ZGlmZiAtLWdpdCBhL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIgYi9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCmRpZmYgLS1naXQgYS9OT1RJQ0UgYi9OT1RJQ0UKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjY3YTZhYQotLS0gL2Rldi9udWxsCisrKyBiL05PVElDRQpAQCAtMCwwICsxLDIyMiBAQAorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAgPT0gIE5PVElDRSBmaWxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNlY3Rpb24gNCBkIG9mICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIGluIHRoaXMgY2FzZSBmb3IgdGhlIEFuZHJvaWQtc3BlY2lmaWMgY29kZS4gICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitBbmRyb2lkIENvZGUKK0NvcHlyaWdodCAyMDA1LTIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorCitUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGFzIHBhcnQgb2YKK1RoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QgKGh0dHA6Ly9zb3VyY2UuYW5kcm9pZC5jb20pLgorCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICA9PSAgTk9USUNFIGZpbGUgY29ycmVzcG9uZGluZyB0byB0aGUgc2VjdGlvbiA0IGQgb2YgICAgICAgICAgICAgICAgICAgID09CisgICA9PSAgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PSAgaW4gdGhpcyBjYXNlIGZvciBBcGFjaGUgQ29tbW9ucyBjb2RlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0FwYWNoZSBDb21tb25zCitDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorCitUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGF0CitUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLgorCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICA9PSAgTk9USUNFIGZpbGUgY29ycmVzcG9uZGluZyB0byB0aGUgc2VjdGlvbiA0IGQgb2YgICAgICAgICAgICAgICAgICAgID09CisgICA9PSAgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PSAgaW4gdGhpcyBjYXNlIGZvciBKYWthcnRhIENvbW1vbnMgTG9nZ2luZy4gICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0pha2FydGEgQ29tbW9ucyBMb2dnaW5nIChKQ0wpCitDb3B5cmlnaHQgMjAwNSwyMDA2IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KKworVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBhdAorVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4KKworICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAgPT0gIE5PVElDRSBmaWxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNlY3Rpb24gNCBkIG9mICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIGluIHRoaXMgY2FzZSBmb3IgdGhlIE51YW5jZSBjb2RlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitUaGVzZSBmaWxlcyBhcmUgQ29weXJpZ2h0IDIwMDcgTnVhbmNlIENvbW11bmljYXRpb25zLCBidXQgcmVsZWFzZWQgdW5kZXIKK3RoZSBBcGFjaGUyIExpY2Vuc2UuCisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKwpkaWZmIC0tZ2l0IGEvYXd0L0FuZHJvaWQubWsgYi9hd3QvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzQ4MGY1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L0FuZHJvaWQubWsKQEAgLTAsMCArMSwzMSBAQAorIworIyBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMKKworTE9DQUxfUEFUSDo9ICQoY2FsbCBteS1kaXIpCisKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVMgOj0gJChjYWxsIGFsbC1zdWJkaXItamF2YS1maWxlcykKKworTE9DQUxfSkFWQV9SRVNPVVJDRV9ESVJTIDo9IHJlc291cmNlcworCitMT0NBTF9KQVZBX0xJQlJBUklFUyA6PSBjb3JlIGZyYW1ld29yaworCitMT0NBTF9NT0RVTEU6PSBhbmRyb2lkLmF3dAorCitMT0NBTF9EWF9GTEFHUyA6PSAtLWNvcmUtbGlicmFyeQorCitpbmNsdWRlICQoQlVJTERfSkFWQV9MSUJSQVJZKQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3MyRC5qYXZhIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3MyRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhOGFlMDIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0FuZHJvaWRHcmFwaGljczJELmphdmEKQEAgLTAsMCArMSwxMzU0IEBACisvKgorICogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgY29tLmFuZHJvaWQuaW50ZXJuYWwuYXd0OworCitpbXBvcnQgY29tLmFuZHJvaWQuaW50ZXJuYWwuYXd0LkFuZHJvaWRHcmFwaGljc0NvbmZpZ3VyYXRpb247CitpbXBvcnQgY29tLmFuZHJvaWQuaW50ZXJuYWwuZ3JhcGhpY3MuTmF0aXZlVXRpbHM7CisKK2ltcG9ydCBqYXZhLmF3dC5BbHBoYUNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5CYXNpY1N0cm9rZTsKK2ltcG9ydCBqYXZhLmF3dC5Db2xvcjsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGU7CitpbXBvcnQgamF2YS5hd3QuRm9udDsKK2ltcG9ydCBqYXZhLmF3dC5Gb250TWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5Qb2x5Z29uOworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5SZW5kZXJpbmdIaW50czsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5TdHJva2U7CitpbXBvcnQgamF2YS5hd3QuZm9udC5Gb250UmVuZGVyQ29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkdseXBoVmVjdG9yOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQXJlYTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkdlbmVyYWxQYXRoOworaW1wb3J0IGphdmEuYXd0Lmdlb20uTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5BZmZpbmVUcmFuc2Zvcm1PcDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2VPcDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRpcmVjdENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SYXN0ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmVuZGVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5TaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLnJlbmRlcmFibGUuUmVuZGVyYWJsZUltYWdlOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuSW1hZ2VTdXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuTXVsdGlSZWN0QXJlYTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkFuZHJvaWRHbHlwaFZlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuRm9udE1ldHJpY3NJbXBsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuT2Zmc2NyZWVuSW1hZ2U7CisKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkJpdG1hcDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkNhbnZhczsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLk1hdHJpeDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLlBhaW50OworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUGF0aDsKKworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUmVjdDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLlJlY3RGOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUmVnaW9uOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuVHlwZWZhY2U7CitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5QaXhlbFhvclhmZXJtb2RlOworaW1wb3J0IGFuZHJvaWQudmlldy5EaXNwbGF5OworaW1wb3J0IGFuZHJvaWQudmlldy5XaW5kb3dNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworCitwdWJsaWMgY2xhc3MgQW5kcm9pZEdyYXBoaWNzMkQgZXh0ZW5kcyBHcmFwaGljczJEIHsKKyAgICAKKyAgICBwcml2YXRlIGludCBkaXNwbGF5V2lkdGgsIGRpc3BsYXlIZWlnaHQ7CisKKyAgICBwcm90ZWN0ZWQgU3VyZmFjZSBkc3RTdXJmID0gbnVsbDsKKyAgICBwcm90ZWN0ZWQgTXVsdGlSZWN0QXJlYSBjbGlwID0gbnVsbDsKKworICAgIHByb3RlY3RlZCBDb21wb3NpdGUgY29tcG9zaXRlID0gQWxwaGFDb21wb3NpdGUuU3JjT3ZlcjsKKyAgICBwcm90ZWN0ZWQgQWZmaW5lVHJhbnNmb3JtIHRyYW5zZm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKworICAgIHByaXZhdGUgc3RhdGljIEFuZHJvaWRHcmFwaGljczJEIG1BZzsKKyAgICBwcml2YXRlIHN0YXRpYyBDYW52YXMgbUM7CisKKyAgICAvLyBBbmRyb2lkIFBhaW50CisgICAgcHVibGljIHN0YXRpYyBQYWludCBtUDsKKworICAgIHByaXZhdGUgc3RhdGljIGphdmEuYXd0LkZvbnQgbUZudDsKKworICAgIC8vIENhY2hlZCBNYXRyaXgKKyAgICBwdWJsaWMgc3RhdGljIE1hdHJpeCBtTTsKKyAgICBwcml2YXRlIHN0YXRpYyBGb250TWV0cmljcyBtRm07CisgICAgcHJpdmF0ZSBzdGF0aWMgUmVuZGVyaW5nSGludHMgbVJoOworICAgIHByaXZhdGUgc3RhdGljIENvbG9yIG1CYzsKKworICAgIHByaXZhdGUgQXJlYSBtQ3VyckNsaXA7CisgICAgCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBkb3VibGUgUkFEXzM2MCA9IE1hdGguUEkgLyAxODAgKiAzNjA7CisgICAgCisgICAgLy8gSW1hZ2UgZHJhd2luZworICAgIHByaXZhdGUgQW5kcm9pZEphdmFCbGl0dGVyIGJsaXR0ZXI7CisgICAgcHJpdmF0ZSBEaXJlY3RDb2xvck1vZGVsIGNtOworICAgIHByaXZhdGUgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzbTsKKyAgICBwcml2YXRlIFdyaXRhYmxlUmFzdGVyIHdyOworCisKKyAgICBwdWJsaWMgc3RhdGljIEFuZHJvaWRHcmFwaGljczJEIGdldEluc3RhbmNlKCkgeworICAgICAgICBpZiAobUFnID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJBbmRyb2lkR3JhcGhpY3MyRCBub3QgaW5zdGFudGlhdGVkISIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtQWc7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBBbmRyb2lkR3JhcGhpY3MyRCBnZXRJbnN0YW5jZShDb250ZXh0IGN0eCwgQ2FudmFzIGMsIFBhaW50IHApIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCB8fCBjdHggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJJbGxlZ2FsIGFyZ3VtZW50LCBDYW52YXMgY2Fubm90IGJlIG51bGwhIik7CisgICAgICAgIH0KKyAgICAgICAgbUFnID0gbmV3IEFuZHJvaWRHcmFwaGljczJEKGN0eCwgYywgcCk7CisgICAgICAgIHJldHVybiBtQWc7CisgICAgfQorCisgICAgcHJpdmF0ZSBBbmRyb2lkR3JhcGhpY3MyRChDb250ZXh0IGN0eCwgQ2FudmFzIGMsIFBhaW50IHApIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgbUMgPSBjOworICAgICAgICBtUCA9IHA7CisgICAgICAgIG1NID0gbmV3IE1hdHJpeCgpOworICAgICAgICBtTS5yZXNldCgpOworICAgICAgICBtTSA9IG1DLmdldE1hdHJpeCgpOworICAgICAgICBSZWN0IHIgPSBtQy5nZXRDbGlwQm91bmRzKCk7CisgICAgICAgIGludCBjbFtdID0gey0xLCByLnRvcCwgci5sZWZ0LCAtMiwgci50b3AsIHIucmlnaHQsIC0yLCByLmJvdHRvbSwgci5yaWdodCwgLTIsIHIuYm90dG9tLCByLmxlZnR9OworICAgICAgICBtQ3VyckNsaXAgPSBuZXcgQXJlYShjcmVhdGVTaGFwZShjbCkpOworICAgICAgICBpZihjdHggIT0gbnVsbCkgeworICAgICAgICAgICAgV2luZG93TWFuYWdlciB3bSA9IChXaW5kb3dNYW5hZ2VyKWN0eC5nZXRTeXN0ZW1TZXJ2aWNlKENvbnRleHQuV0lORE9XX1NFUlZJQ0UpOworICAgICAgICAgICAgRGlzcGxheSBkID0gd20uZ2V0RGVmYXVsdERpc3BsYXkoKTsKKyAgICAgICAgICAgIGRpc3BsYXlXaWR0aCA9IGQuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGRpc3BsYXlIZWlnaHQgPSBkLmdldEhlaWdodCgpOworICAgICAgICB9CisgICAgICAgIGJsaXR0ZXIgPSBuZXcgQW5kcm9pZEphdmFCbGl0dGVyKGMpOworICAgICAgICBjbSA9IG5ldyBEaXJlY3RDb2xvck1vZGVsKDMyLCAweGZmMDAwMCwgMHhmZjAwLCAweGZmLCAweGZmMDAwMDAwKTsKKyAgICAgICAgc20gPSBuZXcgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCgKKyAgICAgICAgICAgICAgICBEYXRhQnVmZmVyLlRZUEVfSU5ULCBkaXNwbGF5V2lkdGgsIGRpc3BsYXlIZWlnaHQsIGNtLmdldE1hc2tzKCkpOworICAgICAgICB3ciA9IFJhc3Rlci5jcmVhdGVXcml0YWJsZVJhc3RlcihzbSwgbnVsbCk7CisgICAgICAgIGRzdFN1cmYgPSBuZXcgSW1hZ2VTdXJmYWNlKGNtLCB3cik7ICAgICAgIAorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZFJlbmRlcmluZ0hpbnRzKE1hcDw/LCA/PiBoaW50cykgeworICAgICAgICBpZiAobVJoID09IG51bGwpIHsKKyAgICAgICAgICAgIG1SaCA9IChSZW5kZXJpbmdIaW50cykgaGludHM7CisgICAgICAgIH0KKyAgICAgICAgbVJoLmFkZCgoUmVuZGVyaW5nSGludHMpIGhpbnRzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRNYXRyaXgoKSB7CisgICAgICAgIGZsb2F0W10gZiA9IG5ldyBmbG9hdFs5XTsKKyAgICAgICAgbUMuZ2V0TWF0cml4KCkuZ2V0VmFsdWVzKGYpOworICAgICAgICByZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgTWF0cml4IGluIEFuZHJvaWQgZm9ybWF0CisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0SW52ZXJzZU1hdHJpeCgpIHsKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGFmID0gbmV3IEFmZmluZVRyYW5zZm9ybShjcmVhdGVBV1RNYXRyaXgoZ2V0TWF0cml4KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFmID0gYWYuY3JlYXRlSW52ZXJzZSgpOworICAgICAgICB9IGNhdGNoIChOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3JlYXRlTWF0cml4KGFmKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFBhdGggZ2V0UGF0aChTaGFwZSBzKSB7CisgICAgICAgIFBhdGggcGF0aCA9IG5ldyBQYXRoKCk7CisgICAgICAgIFBhdGhJdGVyYXRvciBwaSA9IHMuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpOworICAgICAgICB3aGlsZSAocGkuaXNEb25lKCkgPT0gZmFsc2UpIHsKKyAgICAgICAgICAgIGdldEN1cnJlbnRTZWdtZW50KHBpLCBwYXRoKTsKKyAgICAgICAgICAgIHBpLm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGF0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZ2V0Q3VycmVudFNlZ21lbnQoUGF0aEl0ZXJhdG9yIHBpLCBQYXRoIHBhdGgpIHsKKyAgICAgICAgZmxvYXRbXSBjb29yZGluYXRlcyA9IG5ldyBmbG9hdFs2XTsKKyAgICAgICAgaW50IHR5cGUgPSBwaS5jdXJyZW50U2VnbWVudChjb29yZGluYXRlcyk7CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTU9WRVRPOgorICAgICAgICAgICAgcGF0aC5tb3ZlVG8oY29vcmRpbmF0ZXNbMF0sIGNvb3JkaW5hdGVzWzFdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTElORVRPOgorICAgICAgICAgICAgcGF0aC5saW5lVG8oY29vcmRpbmF0ZXNbMF0sIGNvb3JkaW5hdGVzWzFdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfUVVBRFRPOgorICAgICAgICAgICAgcGF0aC5xdWFkVG8oY29vcmRpbmF0ZXNbMF0sIGNvb3JkaW5hdGVzWzFdLCBjb29yZGluYXRlc1syXSwKKyAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXNbM10pOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOgorICAgICAgICAgICAgcGF0aC5jdWJpY1RvKGNvb3JkaW5hdGVzWzBdLCBjb29yZGluYXRlc1sxXSwgY29vcmRpbmF0ZXNbMl0sCisgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzWzNdLCBjb29yZGluYXRlc1s0XSwgY29vcmRpbmF0ZXNbNV0pOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DTE9TRToKKyAgICAgICAgICAgIHBhdGguY2xvc2UoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBTaGFwZSBjcmVhdGVTaGFwZShpbnRbXSBhcnIpIHsKKyAgICAgICAgU2hhcGUgcyA9IG5ldyBHZW5lcmFsUGF0aCgpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgdHlwZSA9IGFycltpXTsgICAgCisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgLTE6CisgICAgICAgICAgICAgICAgLy9NT1ZFVE8KKyAgICAgICAgICAgICAgICAoKEdlbmVyYWxQYXRoKXMpLm1vdmVUbyhhcnJbKytpXSwgYXJyWysraV0pOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAtMjoKKyAgICAgICAgICAgICAgICAvL0xJTkVUTworICAgICAgICAgICAgICAgICgoR2VuZXJhbFBhdGgpcykubGluZVRvKGFyclsrK2ldLCBhcnJbKytpXSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIC0zOgorICAgICAgICAgICAgICAgIC8vUVVBRFRPCisgICAgICAgICAgICAgICAgKChHZW5lcmFsUGF0aClzKS5xdWFkVG8oYXJyWysraV0sIGFyclsrK2ldLCBhcnJbKytpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGFyclsrK2ldKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgLTQ6CisgICAgICAgICAgICAgICAgLy9DVUJJQ1RPCisgICAgICAgICAgICAgICAgKChHZW5lcmFsUGF0aClzKS5jdXJ2ZVRvKGFyclsrK2ldLCBhcnJbKytpXSwgYXJyWysraV0sCisgICAgICAgICAgICAgICAgICAgICAgICBhcnJbKytpXSwgYXJyWysraV0sIGFyclsrK2ldKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgLTU6CisgICAgICAgICAgICAgICAgLy9DTE9TRQorICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gczsKKyAgICB9CisgICAgLyoKKyAgICBwdWJsaWMgaW50W10gZ2V0UGl4ZWxzKCkgeworICAgICAgICByZXR1cm4gbUMuZ2V0UGl4ZWxzKCk7CisgICAgfSovCisKKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IGdldFJhZGlhbihmbG9hdCBkZWdyZWUpIHsKKyAgICAgICAgcmV0dXJuIChmbG9hdCkgKChNYXRoLlBJIC8gMTgwKSAqIGRlZ3JlZSk7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgU2hhcGUgZ2V0U2hhcGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgZ2V0RGVncmVlKGZsb2F0IHJhZGlhbikgeworICAgICAgICByZXR1cm4gKGZsb2F0KSAoKDE4MCAvIE1hdGguUEkpICogcmFkaWFuKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIERlZ3JlZSBpbiByYWRpYW4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IGdldEVsbGlwc2lzWChmbG9hdCBkZWdyZWUsIGZsb2F0IHByaW5jQXhpcykgeworICAgICAgICByZXR1cm4gKGZsb2F0KSBNYXRoLmNvcyhkZWdyZWUpICogcHJpbmNBeGlzOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgZ2V0RWxsaXBzaXNZKGZsb2F0IGRlZ3JlZSwgZmxvYXQgY29uQXhpcykgeworICAgICAgICByZXR1cm4gKGZsb2F0KSBNYXRoLnNpbihkZWdyZWUpICogY29uQXhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGlwKFNoYXBlIHMpIHsKKyAgICAgICAgbUMuY2xpcFBhdGgoZ2V0UGF0aChzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q2FudmFzKENhbnZhcyBjKSB7CisgICAgICAgIG1DID0gYzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3KFNoYXBlIHMpIHsKKyAgICAgICAgaWYgKG1QID09IG51bGwpIHsKKyAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgIH0KKyAgICAgICAgUGFpbnQuU3R5bGUgdG1wID0gbVAuZ2V0U3R5bGUoKTsKKyAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuU1RST0tFKTsKKyAgICAgICAgbUMuZHJhd1BhdGgoZ2V0UGF0aChzKSwgbVApOworICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKy8qCisgICAgcHJpdmF0ZSBBcnJheUxpc3QgZ2V0U2VnbWVudHMoU2hhcGUgcykgeworICAgICAgICBBcnJheUxpc3QgYXJyID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBQYXRoSXRlcmF0b3IgcGkgPSBzLmdldFBhdGhJdGVyYXRvcihudWxsKTsKKyAgICAgICAgd2hpbGUgKHBpLmlzRG9uZSgpID09IGZhbHNlKSB7CisgICAgICAgICAgICBnZXRDdXJyZW50U2VnbWVudChwaSwgYXJyKTsKKyAgICAgICAgICAgIHBpLm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXJyOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBnZXRDdXJyZW50U2VnbWVudChQYXRoSXRlcmF0b3IgcGksIEFycmF5TGlzdCBhcnIpIHsKKyAgICAgICAgZmxvYXRbXSBjb29yZGluYXRlcyA9IG5ldyBmbG9hdFs2XTsKKyAgICAgICAgaW50IHR5cGUgPSBwaS5jdXJyZW50U2VnbWVudChjb29yZGluYXRlcyk7CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTU9WRVRPOgorICAgICAgICAgICAgYXJyLmFkZChuZXcgSW50ZWdlcigtMSkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19MSU5FVE86CisgICAgICAgICAgICBhcnIuYWRkKG5ldyBJbnRlZ2VyKC0yKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX1FVQURUTzoKKyAgICAgICAgICAgIGFyci5hZGQobmV3IEludGVnZXIoLTMpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ1VCSUNUTzoKKyAgICAgICAgICAgIGFyci5hZGQobmV3IEludGVnZXIoLTQpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ0xPU0U6CisgICAgICAgICAgICBhcnIuYWRkKG5ldyBJbnRlZ2VyKC01KSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorKi8KKyAgICAvKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCwgbm90IHN0YW5kYXJkIEFXVAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRyYXcoUGF0aCBzKSB7CisgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICBtUCA9IG5ldyBQYWludCgpOworICAgICAgICB9CisgICAgICAgIFBhaW50LlN0eWxlIHRtcCA9IG1QLmdldFN0eWxlKCk7CisgICAgICAgIG1QLnNldFN0eWxlKFBhaW50LlN0eWxlLlNUUk9LRSk7CisgICAgICAgIHMudHJhbnNmb3JtKG1NKTsKKyAgICAgICAgbUMuZHJhd1BhdGgocywgbVApOworICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdHbHlwaFZlY3RvcihHbHlwaFZlY3RvciBnLCBmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIC8vIFRPRE8gZHJhdyBhdCB4LCB5CisgICAgICAgIC8vIGRyYXcoZy5nZXRPdXRsaW5lKCkpOworICAgICAgICAvKgorICAgICAgICBNYXRyaXggbWF0cml4ID0gbmV3IE1hdHJpeCgpOworICAgICAgICBtYXRyaXguc2V0VHJhbnNsYXRlKHgsIHkpOworICAgICAgICBQYXRoIHB0aCA9IGdldFBhdGgoZy5nZXRPdXRsaW5lKCkpOworICAgICAgICBwdGgudHJhbnNmb3JtKG1hdHJpeCk7CisgICAgICAgIGRyYXcocHRoKTsKKyAgICAgICAgKi8KKyAgICAgICAgUGF0aCBwYXRoID0gbmV3IFBhdGgoKTsKKyAgICAgICAgY2hhcltdIGMgPSAoKEFuZHJvaWRHbHlwaFZlY3RvcilnKS5nZXRHbHlwaHMoKTsKKyAgICAgICAgbVAuZ2V0VGV4dFBhdGgoYywgMCwgYy5sZW5ndGgsIHgsIHksIHBhdGgpOworICAgICAgICBtQy5kcmF3UGF0aChwYXRoLCBtUCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1JlbmRlcmFibGVJbWFnZShSZW5kZXJhYmxlSW1hZ2UgaW1nLCBBZmZpbmVUcmFuc2Zvcm0geGZvcm0pIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3UmVuZGVyZWRJbWFnZShSZW5kZXJlZEltYWdlIGltZywgQWZmaW5lVHJhbnNmb3JtIHhmb3JtKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1N0cmluZyhBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGZsb2F0IHgsCisgICAgICAgICAgICBmbG9hdCB5KSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3Igbm90IHN1cHBvcnRlZCEiKTsKKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdTdHJpbmcoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBub3Qgc3VwcG9ydGVkISIpOworCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1N0cmluZyhTdHJpbmcgcywgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICAgICAgaWYgKG1QID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtUCA9IG5ldyBQYWludCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUGFpbnQuU3R5bGUgdG1wID0gbVAuZ2V0U3R5bGUoKTsKKworICAgICAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuRklMTCk7CisgICAgICAgICAgICBQYXRoIHB0aCA9IG5ldyBQYXRoKCk7CisgICAgICAgICAgICBtUC5nZXRUZXh0UGF0aChzLCAwLCBzLmxlbmd0aCgpLCB4LCB5LCBwdGgpOworICAgICAgICAgICAgbUMuZHJhd1BhdGgocHRoLCBtUCk7CisgICAgICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdTdHJpbmcoU3RyaW5nIHN0ciwgaW50IHgsIGludCB5KSB7CisgICAgICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQYWludC5TdHlsZSB0bXAgPSBtUC5nZXRTdHlsZSgpOworICAgICAgICAgICAgbVAuc2V0U3Ryb2tlV2lkdGgoMCk7CisKKyAgICAgICAgICAgIG1DLmRyYXdUZXh0KHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIudG9DaGFyQXJyYXkoKS5sZW5ndGgsIHgsIHksCisgICAgICAgICAgICAgICAgICAgIG1QKTsKKyAgICAgICAgICAgIG1QLnNldFN0eWxlKHRtcCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbChTaGFwZSBzKSB7CisgICAgICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQYWludC5TdHlsZSB0bXAgPSBtUC5nZXRTdHlsZSgpOworICAgICAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuRklMTCk7CisgICAgICAgICAgICBtQy5kcmF3UGF0aChnZXRQYXRoKHMpLCBtUCk7CisgICAgICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb2xvciBnZXRCYWNrZ3JvdW5kKCkgeworICAgICAgICByZXR1cm4gbUJjOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb21wb3NpdGUgZ2V0Q29tcG9zaXRlKCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQ29tcG9zaXRlIG5vdCBpbXBsZW1lbnRlZCEiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3NDb25maWd1cmF0aW9uIGdldERldmljZUNvbmZpZ3VyYXRpb24oKSB7CisgICAgICAgIHJldHVybiBuZXcgQW5kcm9pZEdyYXBoaWNzQ29uZmlndXJhdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250UmVuZGVyQ29udGV4dCBnZXRGb250UmVuZGVyQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGb250UmVuZGVyQ29udGV4dChnZXRUcmFuc2Zvcm0oKSwgbVAuaXNBbnRpQWxpYXMoKSwgdHJ1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGphdmEuYXd0LlBhaW50IGdldFBhaW50KCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQVdUIFBhaW50IG5vdCBpbXBsZW1lbnRlZCBpbiBBbmRyb2lkISIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQ2FudmFzIGdldEFuZHJvaWRDYW52YXMoKSB7CisgICAgICAgIHJldHVybiBtQzsKKyAgICB9CisgICAgCisgICAgcHVibGljIHN0YXRpYyBQYWludCBnZXRBbmRyb2lkUGFpbnQoKSB7CisgICAgICAgIHJldHVybiBtUDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUmVuZGVyaW5nSGludHMgZ2V0UmVuZGVyaW5nSGludHMoKSB7CisgICAgICAgIHJldHVybiBtUmg7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cm9rZSBnZXRTdHJva2UoKSB7CisgICAgICAgIGlmIChtUCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEJhc2ljU3Ryb2tlKG1QLmdldFN0cm9rZVdpZHRoKCksIG1QLmdldFN0cm9rZUNhcCgpCisgICAgICAgICAgICAgICAgICAgIC5vcmRpbmFsKCksIG1QLmdldFN0cm9rZUpvaW4oKS5vcmRpbmFsKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBZmZpbmVUcmFuc2Zvcm0gZ2V0VHJhbnNmb3JtKCkgeworICAgICAgICByZXR1cm4gbmV3IEFmZmluZVRyYW5zZm9ybShjcmVhdGVBV1RNYXRyaXgoZ2V0TWF0cml4KCkpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoaXQoUmVjdGFuZ2xlIHJlY3QsIFNoYXBlIHMsIGJvb2xlYW4gb25TdHJva2UpIHsKKyAgICAgICAgLy8gPz8/QVdUIFRPRE8gY2hlY2sgaWYgb24gc3Ryb2tlCisgICAgICAgIHJldHVybiBzLmludGVyc2VjdHMocmVjdC5nZXRYKCksIHJlY3QuZ2V0WSgpLCByZWN0LmdldFdpZHRoKCksIHJlY3QKKyAgICAgICAgICAgICAgICAuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJvdGF0ZShkb3VibGUgdGhldGEpIHsKKyAgICAgICAgbU0ucHJlUm90YXRlKChmbG9hdCkgQW5kcm9pZEdyYXBoaWNzMkQKKyAgICAgICAgICAgICAgICAuZ2V0RGVncmVlKChmbG9hdCkgKFJBRF8zNjAgLSB0aGV0YSkpKTsKKyAgICAgICAgbUMuY29uY2F0KG1NKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByb3RhdGUoZG91YmxlIHRoZXRhLCBkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgbU0ucHJlUm90YXRlKChmbG9hdCkgQW5kcm9pZEdyYXBoaWNzMkQuZ2V0RGVncmVlKChmbG9hdCkgdGhldGEpLAorICAgICAgICAgICAgICAgIChmbG9hdCkgeCwgKGZsb2F0KSB5KTsKKyAgICAgICAgbUMuY29uY2F0KG1NKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzY2FsZShkb3VibGUgc3gsIGRvdWJsZSBzeSkgeworICAgICAgICBtTS5zZXRTY2FsZSgoZmxvYXQpIHN4LCAoZmxvYXQpIHN5KTsKKyAgICAgICAgbUMuY29uY2F0KG1NKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kKENvbG9yIGNvbG9yKSB7CisgICAgICAgIG1CYyA9IGNvbG9yOworICAgICAgICBtQy5jbGlwUmVjdChuZXcgUmVjdCgwLCAwLCBtQy5nZXRXaWR0aCgpLCBtQy5nZXRIZWlnaHQoKSkpOworICAgICAgICAvLyBUT0RPIGRvbid0IGxpbWl0IHRvIGN1cnJlbnQgY2xpcAorICAgICAgICBtQy5kcmF3QVJHQihjb2xvci5nZXRBbHBoYSgpLCBjb2xvci5nZXRSZWQoKSwgY29sb3IuZ2V0R3JlZW4oKSwgY29sb3IKKyAgICAgICAgICAgICAgICAuZ2V0Qmx1ZSgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb21wb3NpdGUoQ29tcG9zaXRlIGNvbXApIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkNvbXBvc2l0ZSBub3QgaW1wbGVtZW50ZWQhIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3BhaW50KFBhaW50IHBhaW50KSB7CisgICAgICAgIG1QID0gcGFpbnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGFpbnQoamF2YS5hd3QuUGFpbnQgcGFpbnQpIHsKKyAgICAgICAgc2V0Q29sb3IoKENvbG9yKXBhaW50KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlbmRlcmluZ0hpbnQoUmVuZGVyaW5nSGludHMuS2V5IGtleSkgeworICAgICAgICBpZiAobVJoID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtUmguZ2V0KGtleSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVuZGVyaW5nSGludChSZW5kZXJpbmdIaW50cy5LZXkgaGludEtleSwgT2JqZWN0IGhpbnRWYWx1ZSkgeworICAgICAgICBpZiAobVJoID09IG51bGwpIHsKKyAgICAgICAgICAgIG1SaCA9IG5ldyBSZW5kZXJpbmdIaW50cyhoaW50S2V5LCBoaW50VmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbVJoLnB1dChoaW50S2V5LCBoaW50VmFsdWUpOworICAgICAgICB9CisgICAgICAgIGFwcGx5SGludHMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSZW5kZXJpbmdIaW50cyhNYXA8PywgPz4gaGludHMpIHsKKyAgICAgICAgbVJoID0gKFJlbmRlcmluZ0hpbnRzKSBoaW50czsKKyAgICAgICAgYXBwbHlIaW50cygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBseUhpbnRzKCkgeworICAgICAgICBPYmplY3QgbzsKKworICAgICAgICAvLyBUT0RPIGRvIHNvbWV0aGluZyBsaWtlIHRoaXM6CisgICAgICAgIC8qCisgICAgICAgICAqIFNldCBzID0gbVJoLmtleVNldCgpOyBJdGVyYXRvciBpdCA9IHMuaXRlcmF0b3IoKTsgd2hpbGUoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAqIG8gPSBpdC5uZXh0KCk7IH0KKyAgICAgICAgICovCisKKyAgICAgICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gc2tpYQorICAgICAgICAvKgorICAgICAgICAgKiBvID0gbVJoLmdldChSZW5kZXJpbmdIaW50cy5LRVlfQUxQSEFfSU5URVJQT0xBVElPTik7IGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9BTFBIQV9JTlRFUlBPTEFUSU9OX0RFRkFVTFQpKSB7IH0gZWxzZQorICAgICAgICAgKiBpZiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQUxQSEFfSU5URVJQT0xBVElPTl9RVUFMSVRZKSkgeyB9CisgICAgICAgICAqIGVsc2UgaWYgKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0FMUEhBX0lOVEVSUE9MQVRJT05fU1BFRUQpKSB7IH0KKyAgICAgICAgICogCisgICAgICAgICAqIG8gPSBtUmguZ2V0KFJlbmRlcmluZ0hpbnRzLktFWV9DT0xPUl9SRU5ERVJJTkcpOyBpZgorICAgICAgICAgKiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQ09MT1JfUkVOREVSX0RFRkFVTFQpKSB7IH0gZWxzZSBpZgorICAgICAgICAgKiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQ09MT1JfUkVOREVSX1FVQUxJVFkpKSB7IH0gZWxzZSBpZgorICAgICAgICAgKiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQ09MT1JfUkVOREVSX1NQRUVEKSkgeyB9CisgICAgICAgICAqIAorICAgICAgICAgKiBvID0gbVJoLmdldChSZW5kZXJpbmdIaW50cy5LRVlfRElUSEVSSU5HKTsgaWYKKyAgICAgICAgICogKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0RJVEhFUl9ERUZBVUxUKSkgeyB9IGVsc2UgaWYKKyAgICAgICAgICogKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0RJVEhFUl9ESVNBQkxFKSkgeyB9IGVsc2UgaWYKKyAgICAgICAgICogKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0RJVEhFUl9FTkFCTEUpKSB7IH0KKyAgICAgICAgICogCisgICAgICAgICAqIG8gPSBtUmguZ2V0KFJlbmRlcmluZ0hpbnRzLktFWV9GUkFDVElPTkFMTUVUUklDUyk7IGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9GUkFDVElPTkFMTUVUUklDU19ERUZBVUxUKSkgeyB9IGVsc2UKKyAgICAgICAgICogaWYgKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0ZSQUNUSU9OQUxNRVRSSUNTX09GRikpIHsgfSBlbHNlIGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9GUkFDVElPTkFMTUVUUklDU19PTikpIHsgfQorICAgICAgICAgKiAKKyAgICAgICAgICogbyA9IG1SaC5nZXQoUmVuZGVyaW5nSGludHMuS0VZX0lOVEVSUE9MQVRJT04pOyBpZgorICAgICAgICAgKiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfSU5URVJQT0xBVElPTl9CSUNVQklDKSkgeyB9IGVsc2UgaWYKKyAgICAgICAgICogKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0lOVEVSUE9MQVRJT05fQklMSU5FQVIpKSB7IH0gZWxzZSBpZgorICAgICAgICAgKiAobyAuZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX0lOVEVSUE9MQVRJT05fTkVBUkVTVF9ORUlHSEJPUikpIHsgfQorICAgICAgICAgKiAKKyAgICAgICAgICogbyA9IG1SaC5nZXQoUmVuZGVyaW5nSGludHMuS0VZX1JFTkRFUklORyk7IGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9SRU5ERVJfREVGQVVMVCkpIHsgfSBlbHNlIGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9SRU5ERVJfUVVBTElUWSkpIHsgfSBlbHNlIGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9SRU5ERVJfU1BFRUQpKSB7IH0KKyAgICAgICAgICogCisgICAgICAgICAqIG8gPSBtUmguZ2V0KFJlbmRlcmluZ0hpbnRzLktFWV9TVFJPS0VfQ09OVFJPTCk7IGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9TVFJPS0VfREVGQVVMVCkpIHsgfSBlbHNlIGlmCisgICAgICAgICAqIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9TVFJPS0VfTk9STUFMSVpFKSkgeyB9IGVsc2UgaWYKKyAgICAgICAgICogKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX1NUUk9LRV9QVVJFKSkgeyB9CisgICAgICAgICAqLworCisgICAgICAgIG8gPSBtUmguZ2V0KFJlbmRlcmluZ0hpbnRzLktFWV9BTlRJQUxJQVNJTkcpOworICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQU5USUFMSUFTX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgbVAuc2V0QW50aUFsaWFzKGZhbHNlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfQU5USUFMSUFTX09GRikpIHsKKyAgICAgICAgICAgICAgICBtUC5zZXRBbnRpQWxpYXMoZmFsc2UpOworICAgICAgICAgICAgfSBlbHNlIGlmIChvLmVxdWFscyhSZW5kZXJpbmdIaW50cy5WQUxVRV9BTlRJQUxJQVNfT04pKSB7CisgICAgICAgICAgICAgICAgbVAuc2V0QW50aUFsaWFzKHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbyA9IG1SaC5nZXQoUmVuZGVyaW5nSGludHMuS0VZX1RFWFRfQU5USUFMSUFTSU5HKTsKKyAgICAgICAgaWYgKG8gIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX1RFWFRfQU5USUFMSUFTX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgbVAuc2V0QW50aUFsaWFzKGZhbHNlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoby5lcXVhbHMoUmVuZGVyaW5nSGludHMuVkFMVUVfVEVYVF9BTlRJQUxJQVNfT0ZGKSkgeworICAgICAgICAgICAgICAgIG1QLnNldEFudGlBbGlhcyhmYWxzZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG8uZXF1YWxzKFJlbmRlcmluZ0hpbnRzLlZBTFVFX1RFWFRfQU5USUFMSUFTX09OKSkgeworICAgICAgICAgICAgICAgIG1QLnNldEFudGlBbGlhcyh0cnVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFN0cm9rZShTdHJva2UgcykgeworICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgfQorICAgICAgICBCYXNpY1N0cm9rZSBicyA9IChCYXNpY1N0cm9rZSkgczsKKyAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuU1RST0tFKTsKKyAgICAgICAgbVAuc2V0U3Ryb2tlV2lkdGgoYnMuZ2V0TGluZVdpZHRoKCkpOworCisgICAgICAgIGludCBjYXAgPSBicy5nZXRFbmRDYXAoKTsKKyAgICAgICAgaWYgKGNhcCA9PSAwKSB7CisgICAgICAgICAgICBtUC5zZXRTdHJva2VDYXAoUGFpbnQuQ2FwLkJVVFQpOworICAgICAgICB9IGVsc2UgaWYgKGNhcCA9PSAxKSB7CisgICAgICAgICAgICBtUC5zZXRTdHJva2VDYXAoUGFpbnQuQ2FwLlJPVU5EKTsKKyAgICAgICAgfSBlbHNlIGlmIChjYXAgPT0gMikgeworICAgICAgICAgICAgbVAuc2V0U3Ryb2tlQ2FwKFBhaW50LkNhcC5TUVVBUkUpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGpvaW4gPSBicy5nZXRMaW5lSm9pbigpOworICAgICAgICBpZiAoam9pbiA9PSAwKSB7CisgICAgICAgICAgICBtUC5zZXRTdHJva2VKb2luKFBhaW50LkpvaW4uTUlURVIpOworICAgICAgICB9IGVsc2UgaWYgKGpvaW4gPT0gMSkgeworICAgICAgICAgICAgbVAuc2V0U3Ryb2tlSm9pbihQYWludC5Kb2luLlJPVU5EKTsKKyAgICAgICAgfSBlbHNlIGlmIChqb2luID09IDIpIHsKKyAgICAgICAgICAgIG1QLnNldFN0cm9rZUpvaW4oUGFpbnQuSm9pbi5CRVZFTCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0W10gY3JlYXRlTWF0cml4KEFmZmluZVRyYW5zZm9ybSBUeCkgeworICAgICAgICBkb3VibGVbXSBhdCA9IG5ldyBkb3VibGVbOV07CisgICAgICAgIFR4LmdldE1hdHJpeChhdCk7CisgICAgICAgIGZsb2F0W10gZiA9IG5ldyBmbG9hdFthdC5sZW5ndGhdOworICAgICAgICBmWzBdID0gKGZsb2F0KSBhdFswXTsKKyAgICAgICAgZlsxXSA9IChmbG9hdCkgYXRbMl07CisgICAgICAgIGZbMl0gPSAoZmxvYXQpIGF0WzRdOworICAgICAgICBmWzNdID0gKGZsb2F0KSBhdFsxXTsKKyAgICAgICAgZls0XSA9IChmbG9hdCkgYXRbM107CisgICAgICAgIGZbNV0gPSAoZmxvYXQpIGF0WzVdOworICAgICAgICBmWzZdID0gMDsKKyAgICAgICAgZls3XSA9IDA7CisgICAgICAgIGZbOF0gPSAxOworICAgICAgICByZXR1cm4gZjsKKyAgICB9CisKKyAgICBwcml2YXRlIGZsb2F0W10gY3JlYXRlQVdUTWF0cml4KGZsb2F0W10gbWF0cml4KSB7CisgICAgICAgIGZsb2F0W10gYXQgPSBuZXcgZmxvYXRbOV07CisgICAgICAgIGF0WzBdID0gbWF0cml4WzBdOworICAgICAgICBhdFsxXSA9IG1hdHJpeFszXTsKKyAgICAgICAgYXRbMl0gPSBtYXRyaXhbMV07CisgICAgICAgIGF0WzNdID0gbWF0cml4WzRdOworICAgICAgICBhdFs0XSA9IG1hdHJpeFsyXTsKKyAgICAgICAgYXRbNV0gPSBtYXRyaXhbNV07CisgICAgICAgIGF0WzZdID0gMDsKKyAgICAgICAgYXRbN10gPSAwOworICAgICAgICBhdFs4XSA9IDE7CisgICAgICAgIHJldHVybiBhdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE1hdHJpeCBjcmVhdGVNYXRyaXhPYmooQWZmaW5lVHJhbnNmb3JtIFR4KSB7CisgICAgICAgIE1hdHJpeCBtID0gbmV3IE1hdHJpeCgpOworICAgICAgICBtLnJlc2V0KCk7CisgICAgICAgIG0uc2V0VmFsdWVzKGNyZWF0ZU1hdHJpeChUeCkpOworICAgICAgICByZXR1cm4gbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtIFR4KSB7CisgICAgICAgIG1NLnJlc2V0KCk7CisgICAgICAgIC8qCisgICAgICAgICAqIGlmKFR4LmlzSWRlbnRpdHkoKSkgeyBtTSA9IG5ldyBNYXRyaXgoKTsgfQorICAgICAgICAgKi8KKyAgICAgICAgbU0uc2V0VmFsdWVzKGNyZWF0ZU1hdHJpeChUeCkpOworICAgICAgICBNYXRyaXggbSA9IG5ldyBNYXRyaXgoKTsKKyAgICAgICAgbS5zZXRWYWx1ZXMoZ2V0SW52ZXJzZU1hdHJpeCgpKTsKKyAgICAgICAgbUMuY29uY2F0KG0pOworICAgICAgICBtQy5jb25jYXQobU0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNoZWFyKGRvdWJsZSBzaHgsIGRvdWJsZSBzaHkpIHsKKyAgICAgICAgbU0uc2V0U2tldygoZmxvYXQpIHNoeCwgKGZsb2F0KSBzaHkpOworICAgICAgICBtQy5jb25jYXQobU0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0gVHgpIHsKKyAgICAgICAgTWF0cml4IG0gPSBuZXcgTWF0cml4KCk7CisgICAgICAgIG0uc2V0VmFsdWVzKGNyZWF0ZU1hdHJpeChUeCkpOworICAgICAgICBtQy5jb25jYXQobSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKGRvdWJsZSB0eCwgZG91YmxlIHR5KSB7CisgICAgICAgIG1NLnNldFRyYW5zbGF0ZSgoZmxvYXQpIHR4LCAoZmxvYXQpIHR5KTsKKyAgICAgICAgbUMuY29uY2F0KG1NKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoaW50IHgsIGludCB5KSB7CisgICAgICAgIG1NLnNldFRyYW5zbGF0ZSgoZmxvYXQpIHgsIChmbG9hdCkgeSk7CisgICAgICAgIG1DLmNvbmNhdChtTSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xlYXJSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIG1DLmNsaXBSZWN0KHgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCk7CisgICAgICAgIGlmIChtQmMgIT0gbnVsbCkgeworICAgICAgICAgICAgbUMuZHJhd0FSR0IobUJjLmdldEFscGhhKCksIG1CYy5nZXRCbHVlKCksIG1CYy5nZXRHcmVlbigpLCBtQmMKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlZCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1DLmRyYXdBUkdCKDB4ZmYsIDB4ZmYsIDB4ZmYsIDB4ZmYpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xpcFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgaW50IGNsW10gPSB7LTEsIHgsIHksIC0yLCB4LCB5ICsgd2lkdGgsIC0yLCB4ICsgaGVpZ2h0LCB5ICsgd2lkdGgsIC0yLCB4ICsgaGVpZ2h0LCB5fTsKKyAgICAgICAgU2hhcGUgc2hwID0gY3JlYXRlU2hhcGUoY2wpOworICAgICAgICBtQ3VyckNsaXAuaW50ZXJzZWN0KG5ldyBBcmVhKHNocCkpOworICAgICAgICBtQy5jbGlwUmVjdChuZXcgUmVjdCh4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCBSZWdpb24uT3AuSU5URVJTRUNUKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb3B5QXJlYShpbnQgc3gsIGludCBzeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgZHgsIGludCBkeSkgeworICAgICAgICBjb3B5QXJlYShtQywgc3gsIHN5LCB3aWR0aCArIGR4LCBoZWlnaHQgKyBkeSwgZHgsIGR5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3MgY3JlYXRlKCkgeworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICAgICAgbUMgPSBudWxsOworICAgICAgICAgICAgbVAgPSBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdBcmMoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBzYSwgaW50IGVhKSB7CisgICAgICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtUC5zZXRTdHJva2VXaWR0aCgwKTsKKyAgICAgICAgICAgIG1DLmRyYXdBcmMobmV3IFJlY3RGKHgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCksIDM2MCAtIChlYSArIHNhKSwKKyAgICAgICAgICAgICAgICAgICAgICAgZWEsIHRydWUsIG1QKTsKKyAgICB9CisKKyAgICAKKyAgICAvLyA/Pz9BV1Q6IG9ubHkgdXNlZCBmb3IgZGVidWdpbmcsIGRlbGV0ZSBpbiBmaW5hbCB2ZXJzaW9uCisgICAgcHVibGljIHZvaWQgZHJhd0JpdG1hcChCaXRtYXAgYm0sIGZsb2F0IHgsIGZsb2F0IHksIFBhaW50IHApIHsKKyAgICAgICAgbUMuZHJhd0JpdG1hcChibSwgeCwgeSwgbnVsbCk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgaW50IHgsIGludCB5LCBDb2xvciBiZ2NvbG9yLAorICAgICAgICAgICAgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisKKyAgICAgICAgaWYoaW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBzb21lYml0cyA9IGZhbHNlOworICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBudWxsOworICAgICAgICBpZihpbWFnZSBpbnN0YW5jZW9mIE9mZnNjcmVlbkltYWdlKXsKKyAgICAgICAgICAgIE9mZnNjcmVlbkltYWdlIG9pID0gKE9mZnNjcmVlbkltYWdlKSBpbWFnZTsKKyAgICAgICAgICAgIGlmKChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5FUlJPUikgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRvbmUgPSBvaS5wcmVwYXJlSW1hZ2UoaW1hZ2VPYnNlcnZlcik7CisgICAgICAgICAgICBzb21lYml0cyA9IChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5TT01FQklUUykgIT0gMDsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBvaS5nZXRJbWFnZVN1cmZhY2UoKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShpbWFnZSk7CisgICAgICAgIH0KKworICAgICAgICBpZihkb25lIHx8IHNvbWViaXRzKSB7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgYmxpdHRlci5ibGl0KDAsIDAsIHNyY1N1cmYsIHgsIHksIGRzdFN1cmYsIHcsIGgsIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGUsIGJnY29sb3IsIGNsaXApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkb25lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgaW50IHgsIGludCB5LCBJbWFnZU9ic2VydmVyIGltYWdlT2JzZXJ2ZXIpIHsKKyAgICAgICAgcmV0dXJuIGRyYXdJbWFnZShpbWFnZSwgeCwgeSwgbnVsbCwgaW1hZ2VPYnNlcnZlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltYWdlLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgIENvbG9yIGJnY29sb3IsIEltYWdlT2JzZXJ2ZXIgaW1hZ2VPYnNlcnZlcikgeworCisgICAgICAgIGlmKGltYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gc29tZWJpdHMgPSBmYWxzZTsKKyAgICAgICAgU3VyZmFjZSBzcmNTdXJmID0gbnVsbDsKKworICAgICAgICBpZihpbWFnZSBpbnN0YW5jZW9mIE9mZnNjcmVlbkltYWdlKXsKKyAgICAgICAgICAgIE9mZnNjcmVlbkltYWdlIG9pID0gKE9mZnNjcmVlbkltYWdlKSBpbWFnZTsKKyAgICAgICAgICAgIGlmKChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5FUlJPUikgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRvbmUgPSBvaS5wcmVwYXJlSW1hZ2UoaW1hZ2VPYnNlcnZlcik7CisgICAgICAgICAgICBzb21lYml0cyA9IChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5TT01FQklUUykgIT0gMDsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBvaS5nZXRJbWFnZVN1cmZhY2UoKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShpbWFnZSk7CisgICAgICAgIH0KKworICAgICAgICBpZihkb25lIHx8IHNvbWViaXRzKSB7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGlmKHcgPT0gd2lkdGggJiYgaCA9PSBoZWlnaHQpeworICAgICAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgKEFmZmluZVRyYW5zZm9ybSkgdHJhbnNmb3JtLmNsb25lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGUsIGJnY29sb3IsIGNsaXApOworICAgICAgICAgICAgfWVsc2V7CisgICAgICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICAgICAgICAgIHhmb3JtLnNldFRvU2NhbGUoKGZsb2F0KXdpZHRoIC8gdywgKGZsb2F0KWhlaWdodCAvIGgpOworICAgICAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgKEFmZmluZVRyYW5zZm9ybSkgdHJhbnNmb3JtLmNsb25lKCksCisgICAgICAgICAgICAgICAgICAgICAgICB4Zm9ybSwgY29tcG9zaXRlLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZG9uZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBkcmF3SW1hZ2UoSW1hZ2UgaW1hZ2UsIGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisgICAgICAgIHJldHVybiBkcmF3SW1hZ2UoaW1hZ2UsIHgsIHksIHdpZHRoLCBoZWlnaHQsIG51bGwsIGltYWdlT2JzZXJ2ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgaW50IGR4MSwgaW50IGR5MSwgaW50IGR4MiwgaW50IGR5MiwKKyAgICAgICAgICAgIGludCBzeDEsIGludCBzeTEsIGludCBzeDIsIGludCBzeTIsIENvbG9yIGJnY29sb3IsCisgICAgICAgICAgICBJbWFnZU9ic2VydmVyIGltYWdlT2JzZXJ2ZXIpIHsKKworICAgICAgICBpZihpbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZihkeDEgPT0gZHgyIHx8IGR5MSA9PSBkeTIgfHwgc3gxID09IHN4MiB8fCBzeTEgPT0gc3kyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworICAgICAgICBib29sZWFuIHNvbWViaXRzID0gZmFsc2U7CisgICAgICAgIFN1cmZhY2Ugc3JjU3VyZiA9IG51bGw7CisgICAgICAgIGlmKGltYWdlIGluc3RhbmNlb2YgT2Zmc2NyZWVuSW1hZ2UpeworICAgICAgICAgICAgT2Zmc2NyZWVuSW1hZ2Ugb2kgPSAoT2Zmc2NyZWVuSW1hZ2UpIGltYWdlOworICAgICAgICAgICAgaWYoKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLkVSUk9SKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZG9uZSA9IG9pLnByZXBhcmVJbWFnZShpbWFnZU9ic2VydmVyKTsKKyAgICAgICAgICAgIHNvbWViaXRzID0gKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLlNPTUVCSVRTKSAhPSAwOworICAgICAgICAgICAgc3JjU3VyZiA9IG9pLmdldEltYWdlU3VyZmFjZSgpOworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgc3JjU3VyZiA9IFN1cmZhY2UuZ2V0SW1hZ2VTdXJmYWNlKGltYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKGRvbmUgfHwgc29tZWJpdHMpIHsKKworICAgICAgICAgICAgaW50IGRzdFggPSBkeDE7CisgICAgICAgICAgICBpbnQgZHN0WSA9IGR5MTsKKyAgICAgICAgICAgIGludCBzcmNYID0gc3gxOworICAgICAgICAgICAgaW50IHNyY1kgPSBzeTE7CisKKyAgICAgICAgICAgIGludCBkc3RXID0gZHgyIC0gZHgxOworICAgICAgICAgICAgaW50IGRzdEggPSBkeTIgLSBkeTE7CisgICAgICAgICAgICBpbnQgc3JjVyA9IHN4MiAtIHN4MTsKKyAgICAgICAgICAgIGludCBzcmNIID0gc3kyIC0gc3kxOworCisgICAgICAgICAgICBpZihzcmNXID09IGRzdFcgJiYgc3JjSCA9PSBkc3RIKXsKKyAgICAgICAgICAgICAgICBibGl0dGVyLmJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwgc3JjVywgc3JjSCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRlLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICAgICAgICAgICAgICB4Zm9ybS5zZXRUb1NjYWxlKChmbG9hdClkc3RXIC8gc3JjVywgKGZsb2F0KWRzdEggLyBzcmNIKTsKKyAgICAgICAgICAgICAgICBibGl0dGVyLmJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwgc3JjVywgc3JjSCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgeGZvcm0sIGNvbXBvc2l0ZSwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRvbmU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltYWdlLCBpbnQgZHgxLCBpbnQgZHkxLCBpbnQgZHgyLCBpbnQgZHkyLAorICAgICAgICAgICAgaW50IHN4MSwgaW50IHN5MSwgaW50IHN4MiwgaW50IHN5MiwgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisKKyAgICAgICAgcmV0dXJuIGRyYXdJbWFnZShpbWFnZSwgZHgxLCBkeTEsIGR4MiwgZHkyLCBzeDEsIHN5MSwgc3gyLCBzeTIsIG51bGwsCisgICAgICAgICAgICAgICAgaW1hZ2VPYnNlcnZlcik7CisgICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdJbWFnZShCdWZmZXJlZEltYWdlIGJ1ZkltYWdlLCBCdWZmZXJlZEltYWdlT3Agb3AsCisgICAgICAgICAgICBpbnQgeCwgaW50IHkpIHsKKworICAgICAgICBpZihidWZJbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZihvcCA9PSBudWxsKSB7CisgICAgICAgICAgICBkcmF3SW1hZ2UoYnVmSW1hZ2UsIHgsIHksIG51bGwpOworICAgICAgICB9IGVsc2UgaWYob3AgaW5zdGFuY2VvZiBBZmZpbmVUcmFuc2Zvcm1PcCl7CisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm1PcCBhdG9wID0gKEFmZmluZVRyYW5zZm9ybU9wKSBvcDsKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSA9IGF0b3AuZ2V0VHJhbnNmb3JtKCk7CisgICAgICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShidWZJbWFnZSk7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKSwgeGZvcm0sCisgICAgICAgICAgICAgICAgICAgIGNvbXBvc2l0ZSwgbnVsbCwgY2xpcCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWZJbWFnZSA9IG9wLmZpbHRlcihidWZJbWFnZSwgbnVsbCk7CisgICAgICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShidWZJbWFnZSk7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKSwKKyAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRlLCBudWxsLCBjbGlwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgQWZmaW5lVHJhbnNmb3JtIHRyYW5zLAorICAgICAgICAgICAgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisKKyAgICAgICAgaWYoaW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYodHJhbnMgPT0gbnVsbCB8fCB0cmFucy5pc0lkZW50aXR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBkcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIGltYWdlT2JzZXJ2ZXIpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gc29tZWJpdHMgPSBmYWxzZTsKKyAgICAgICAgU3VyZmFjZSBzcmNTdXJmID0gbnVsbDsKKyAgICAgICAgaWYoaW1hZ2UgaW5zdGFuY2VvZiBPZmZzY3JlZW5JbWFnZSl7CisgICAgICAgICAgICBPZmZzY3JlZW5JbWFnZSBvaSA9IChPZmZzY3JlZW5JbWFnZSkgaW1hZ2U7CisgICAgICAgICAgICBpZigob2kuZ2V0U3RhdGUoKSAmIEltYWdlT2JzZXJ2ZXIuRVJST1IpICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkb25lID0gb2kucHJlcGFyZUltYWdlKGltYWdlT2JzZXJ2ZXIpOworICAgICAgICAgICAgc29tZWJpdHMgPSAob2kuZ2V0U3RhdGUoKSAmIEltYWdlT2JzZXJ2ZXIuU09NRUJJVFMpICE9IDA7CisgICAgICAgICAgICBzcmNTdXJmID0gb2kuZ2V0SW1hZ2VTdXJmYWNlKCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICBzcmNTdXJmID0gU3VyZmFjZS5nZXRJbWFnZVN1cmZhY2UoaW1hZ2UpOworICAgICAgICB9CisKKyAgICAgICAgaWYoZG9uZSB8fCBzb21lYml0cykgeworICAgICAgICAgICAgaW50IHcgPSBzcmNTdXJmLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQgaCA9IHNyY1N1cmYuZ2V0SGVpZ2h0KCk7CisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0geGZvcm0gPSAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKTsKKyAgICAgICAgICAgIHhmb3JtLmNvbmNhdGVuYXRlKHRyYW5zKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCAwLCAwLCBkc3RTdXJmLCB3LCBoLCB4Zm9ybSwgY29tcG9zaXRlLAorICAgICAgICAgICAgICAgICAgICBudWxsLCBjbGlwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZG9uZTsKKyAgICB9CisgICAgICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdMaW5lKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MikgeworICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgfQorICAgICAgICAgICAgbUMuZHJhd0xpbmUoeDEsIHkxLCB4MiwgeTIsIG1QKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3T3ZhbChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICAgICAgaWYgKG1QID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtUCA9IG5ldyBQYWludCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuU1RST0tFKTsKKyAgICAgICAgICAgIG1DLmRyYXdPdmFsKG5ldyBSZWN0Rih4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCBtUCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1BvbHlnb24oaW50W10geHBvaW50cywgaW50W10geXBvaW50cywgaW50IG5wb2ludHMpIHsKKyAgICAgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1DLmRyYXdMaW5lKHhwb2ludHNbbnBvaW50cyAtIDFdLCB5cG9pbnRzW25wb2ludHMgLSAxXSwgeHBvaW50c1swXSwKKyAgICAgICAgICAgICAgICAgICAgeXBvaW50c1swXSwgbVApOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBucG9pbnRzIC0gMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgbUMuZHJhd0xpbmUoeHBvaW50c1tpXSwgeXBvaW50c1tpXSwgeHBvaW50c1tpICsgMV0sCisgICAgICAgICAgICAgICAgICAgICAgICB5cG9pbnRzW2kgKyAxXSwgbVApOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdQb2x5bGluZShpbnRbXSB4cG9pbnRzLCBpbnRbXSB5cG9pbnRzLCBpbnQgbnBvaW50cykgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5wb2ludHMgLSAxOyBpKyspIHsKKyAgICAgICAgICAgIGRyYXdMaW5lKHhwb2ludHNbaV0sIHlwb2ludHNbaV0sIHhwb2ludHNbaSArIDFdLCB5cG9pbnRzW2kgKyAxXSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdSb3VuZFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsCisgICAgICAgICAgICBpbnQgYXJjV2lkdGgsIGludCBhcmNIZWlnaHQpIHsKKyAgICAgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1DLmRyYXdSb3VuZFJlY3QobmV3IFJlY3RGKHgsIHksIHdpZHRoLCBoZWlnaHQpLCBhcmNXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgYXJjSGVpZ2h0LCBtUCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbEFyYyhpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IHNhLCBpbnQgZWEpIHsKKyAgICAgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgUGFpbnQuU3R5bGUgdG1wID0gbVAuZ2V0U3R5bGUoKTsKKyAgICAgICAgICAgIG1QLnNldFN0eWxlKFBhaW50LlN0eWxlLkZJTExfQU5EX1NUUk9LRSk7CisgICAgICAgICAgICBtQy5kcmF3QXJjKG5ldyBSZWN0Rih4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCAzNjAgLSAoc2EgKyBlYSksCisgICAgICAgICAgICAgICAgICAgIGVhLCB0cnVlLCBtUCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIG1QLnNldFN0eWxlKHRtcCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbE92YWwoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFBhaW50LlN0eWxlIHRtcCA9IG1QLmdldFN0eWxlKCk7CisgICAgICAgICAgICBtUC5zZXRTdHlsZShQYWludC5TdHlsZS5GSUxMKTsKKyAgICAgICAgICAgIG1DLmRyYXdPdmFsKG5ldyBSZWN0Rih4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCBtUCk7CisgICAgICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGxQb2x5Z29uKGludFtdIHhwb2ludHMsIGludFtdIHlwb2ludHMsIGludCBucG9pbnRzKSB7CisgICAgICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQYWludC5TdHlsZSB0bXAgPSBtUC5nZXRTdHlsZSgpOworICAgICAgICAgICAgbUMuc2F2ZShDYW52YXMuQ0xJUF9TQVZFX0ZMQUcpOworCisgICAgICAgICAgICBtUC5zZXRTdHlsZShQYWludC5TdHlsZS5GSUxMKTsKKworICAgICAgICAgICAgR2VuZXJhbFBhdGggZmlsbGVkUG9seWdvbiA9IG5ldyBHZW5lcmFsUGF0aCgKKyAgICAgICAgICAgICAgICAgICAgR2VuZXJhbFBhdGguV0lORF9FVkVOX09ERCwgbnBvaW50cyk7CisgICAgICAgICAgICBmaWxsZWRQb2x5Z29uLm1vdmVUbyh4cG9pbnRzWzBdLCB5cG9pbnRzWzBdKTsKKyAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gMTsgaW5kZXggPCB4cG9pbnRzLmxlbmd0aDsgaW5kZXgrKykgeworICAgICAgICAgICAgICAgIGZpbGxlZFBvbHlnb24ubGluZVRvKHhwb2ludHNbaW5kZXhdLCB5cG9pbnRzW2luZGV4XSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaWxsZWRQb2x5Z29uLmNsb3NlUGF0aCgpOworICAgICAgICAgICAgUGF0aCBwYXRoID0gZ2V0UGF0aChmaWxsZWRQb2x5Z29uKTsKKyAgICAgICAgICAgIG1DLmNsaXBQYXRoKHBhdGgpOworICAgICAgICAgICAgbUMuZHJhd1BhdGgocGF0aCwgbVApOworCisgICAgICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgICAgICAgICAgbUMucmVzdG9yZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGxSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQYWludC5TdHlsZSB0bXAgPSBtUC5nZXRTdHlsZSgpOworICAgICAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuRklMTCk7CisgICAgICAgICAgICBtQy5kcmF3UmVjdChuZXcgUmVjdCh4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCBtUCk7CisgICAgICAgICAgICBtUC5zZXRTdHlsZSh0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGludFtdIHhwb2ludHMgPSB7IHgsIHgsIHggKyB3aWR0aCwgeCArIHdpZHRoIH07CisgICAgICAgIGludFtdIHlwb2ludHMgPSB7IHksIHkgKyBoZWlnaHQsIHkgKyBoZWlnaHQsIHkgfTsKKyAgICAgICAgZHJhd1BvbHlnb24oeHBvaW50cywgeXBvaW50cywgNCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbFJvdW5kUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgIGludCBhcmNXaWR0aCwgaW50IGFyY0hlaWdodCkgeworICAgICAgICAgICAgaWYgKG1QID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtUCA9IG5ldyBQYWludCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbVAuc2V0U3R5bGUoUGFpbnQuU3R5bGUuRklMTCk7CisgICAgICAgICAgICBtQy5kcmF3Um91bmRSZWN0KG5ldyBSZWN0Rih4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpLCBhcmNXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgYXJjSGVpZ2h0LCBtUCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNoYXBlIGdldENsaXAoKSB7CisgICAgICAgIHJldHVybiBtQ3VyckNsaXA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRDbGlwQm91bmRzKCkgeworICAgICAgICAgICAgUmVjdCByID0gbUMuZ2V0Q2xpcEJvdW5kcygpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUoci5sZWZ0LCByLnRvcCwgci53aWR0aCgpLCByLmhlaWdodCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sb3IgZ2V0Q29sb3IoKSB7CisgICAgICAgIGlmIChtUCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENvbG9yKG1QLmdldENvbG9yKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250IGdldEZvbnQoKSB7CisgICAgICAgIHJldHVybiBtRm50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250TWV0cmljcyBnZXRGb250TWV0cmljcyhGb250IGZvbnQpIHsKKyAgICAgICAgbUZtID0gbmV3IEZvbnRNZXRyaWNzSW1wbChmb250KTsKKyAgICAgICAgcmV0dXJuIG1GbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDbGlwKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGludCBjbFtdID0gey0xLCB4LCB5LCAtMiwgeCwgeSArIHdpZHRoLCAtMiwgeCArIGhlaWdodCwgeSArIHdpZHRoLCAtMiwgeCArIGhlaWdodCwgeX07CisgICAgICAgIG1DdXJyQ2xpcCA9IG5ldyBBcmVhKGNyZWF0ZVNoYXBlKGNsKSk7CisgICAgICAgIG1DLmNsaXBSZWN0KHgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCwgUmVnaW9uLk9wLlJFUExBQ0UpOworCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2xpcChTaGFwZSBjbGlwKSB7CisgICAgICAgIG1DdXJyQ2xpcCA9IG5ldyBBcmVhKGNsaXApOworICAgICAgICBtQy5jbGlwUGF0aChnZXRQYXRoKGNsaXApLCBSZWdpb24uT3AuUkVQTEFDRSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q29sb3IoQ29sb3IgYykgeworICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgfQorICAgICAgICBtUC5zZXRDb2xvcihjLmdldFJHQigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb250IG1hcHBpbmc6CisgICAgICogCisgICAgICogRmFtaWx5OgorICAgICAqIAorICAgICAqIEFuZHJvaWQgICAgICAgICBBV1QKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogc2VyaWYgICAgICAgICAgIFNlcmlmIC8gVGltZXNSb21hbgorICAgICAqIHNhbnMtc2VyaWYgICAgICBTYW5zU2VyaWYgLyBIZWx2ZXRpY2EKKyAgICAgKiBtb25vc3BhY2UgICAgICAgTW9ub3NwYWNlZCAvIENvdXJpZXIKKyAgICAgKiAKKyAgICAgKiBTdHlsZToKKyAgICAgKiAKKyAgICAgKiBBbmRyb2lkICAgICAgICAgICAgQVdUCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIG5vcm1hbCAgICAgICAgICBQbGFpbgorICAgICAqIGJvbGQgICAgICAgICAgICBib2xkCisgICAgICogaXRhbGljICAgICAgICAgIGl0YWxpYworICAgICAqIAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZvbnQoRm9udCBmb250KSB7CisgICAgICAgIGlmIChmb250ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAobVAgPT0gbnVsbCkgeworICAgICAgICAgICAgbVAgPSBuZXcgUGFpbnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIG1GbnQgPSBmb250OworICAgICAgICBUeXBlZmFjZSB0ZiA9IG51bGw7CisgICAgICAgIGludCBzdHkgPSBmb250LmdldFN0eWxlKCk7CisgICAgICAgIFN0cmluZyBuYW0gPSBmb250LmdldE5hbWUoKTsKKyAgICAgICAgU3RyaW5nIGFGID0gIiI7CisgICAgICAgIGlmIChuYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG5hbS5lcXVhbHNJZ25vcmVDYXNlKCJTZXJpZiIpCisgICAgICAgICAgICAgICAgICAgIHx8IG5hbS5lcXVhbHNJZ25vcmVDYXNlKCJUaW1lc1JvbWFuIikpIHsKKyAgICAgICAgICAgICAgICBhRiA9ICJzZXJpZiI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbS5lcXVhbHNJZ25vcmVDYXNlKCJTYW5zU2VyaWYiKQorICAgICAgICAgICAgICAgICAgICB8fCBuYW0uZXF1YWxzSWdub3JlQ2FzZSgiSGVsdmV0aWNhIikpIHsKKyAgICAgICAgICAgICAgICBhRiA9ICJzYW5zLXNlcmlmIjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtLmVxdWFsc0lnbm9yZUNhc2UoIk1vbm9zcGFjZWQiKQorICAgICAgICAgICAgICAgICAgICB8fCBuYW0uZXF1YWxzSWdub3JlQ2FzZSgiQ291cmllciIpKSB7CisgICAgICAgICAgICAgICAgYUYgPSAibW9ub3NwYWNlIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAoc3R5KSB7CisgICAgICAgIGNhc2UgRm9udC5QTEFJTjoKKyAgICAgICAgICAgIHRmID0gVHlwZWZhY2UuY3JlYXRlKGFGLCBUeXBlZmFjZS5OT1JNQUwpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRm9udC5CT0xEOgorICAgICAgICAgICAgdGYgPSBUeXBlZmFjZS5jcmVhdGUoYUYsIFR5cGVmYWNlLkJPTEQpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRm9udC5JVEFMSUM6CisgICAgICAgICAgICB0ZiA9IFR5cGVmYWNlLmNyZWF0ZShhRiwgVHlwZWZhY2UuSVRBTElDKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZvbnQuQk9MRCB8IEZvbnQuSVRBTElDOgorICAgICAgICAgICAgdGYgPSBUeXBlZmFjZS5jcmVhdGUoYUYsIFR5cGVmYWNlLkJPTERfSVRBTElDKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGYgPSBUeXBlZmFjZS5ERUZBVUxUOworICAgICAgICB9CisKKyAgICAgICAgbVAuc2V0VGV4dFNpemUoZm9udC5nZXRTaXplKCkpOworICAgICAgICBtUC5zZXRUeXBlZmFjZSh0Zik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd0J5dGVzKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLCBpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgZHJhd1N0cmluZyhuZXcgU3RyaW5nKGRhdGEsIG9mZnNldCwgbGVuZ3RoKSwgeCwgeSk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdQb2x5Z29uKFBvbHlnb24gcCkgeworICAgICAgICBkcmF3UG9seWdvbihwLnhwb2ludHMsIHAueXBvaW50cywgcC5ucG9pbnRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaWxsUG9seWdvbihQb2x5Z29uIHApIHsKKyAgICAgICAgZmlsbFBvbHlnb24ocC54cG9pbnRzLCBwLnlwb2ludHMsIHAubnBvaW50cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpcEJvdW5kcyhSZWN0YW5nbGUgcikgeworICAgICAgICBTaGFwZSBjbGlwID0gZ2V0Q2xpcCgpOworICAgICAgICBpZiAoY2xpcCAhPSBudWxsKSB7CisgICAgICAgICAgICBSZWN0YW5nbGUgYiA9IGNsaXAuZ2V0Qm91bmRzKCk7CisgICAgICAgICAgICByLnggPSBiLng7CisgICAgICAgICAgICByLnkgPSBiLnk7CisgICAgICAgICAgICByLndpZHRoID0gYi53aWR0aDsKKyAgICAgICAgICAgIHIuaGVpZ2h0ID0gYi5oZWlnaHQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhpdENsaXAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgcmV0dXJuIGdldENsaXBCb3VuZHMoKS5pbnRlcnNlY3RzKG5ldyBSZWN0YW5nbGUoeCwgeSwgd2lkdGgsIGhlaWdodCkpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3Q2hhcnMoY2hhcltdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW5ndGgsIGludCB4LCBpbnQgeSkgeworICAgICAgICBtQy5kcmF3VGV4dChkYXRhLCBvZmZzZXQsIGxlbmd0aCwgeCwgeSwgbVApOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQYWludE1vZGUoKSB7CisgICAgICAgIGlmIChtUCA9PSBudWxsKSB7CisgICAgICAgICAgICBtUCA9IG5ldyBQYWludCgpOworICAgICAgICB9CisgICAgICAgIG1QLnNldFhmZXJtb2RlKG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFhPUk1vZGUoQ29sb3IgY29sb3IpIHsKKyAgICAgICAgaWYgKG1QID09IG51bGwpIHsKKyAgICAgICAgICAgIG1QID0gbmV3IFBhaW50KCk7CisgICAgICAgIH0KKyAgICAgICAgbVAuc2V0WGZlcm1vZGUobmV3IFBpeGVsWG9yWGZlcm1vZGUoY29sb3IuZ2V0UkdCKCkpKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbDNEUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgYm9vbGVhbiByYWlzZWQpIHsKKyAgICAgICAgQ29sb3IgY29sb3IgPSBnZXRDb2xvcigpOworICAgICAgICBDb2xvciBjb2xvclVwLCBjb2xvckRvd247CisgICAgICAgIGlmIChyYWlzZWQpIHsKKyAgICAgICAgICAgIGNvbG9yVXAgPSBjb2xvci5icmlnaHRlcigpOworICAgICAgICAgICAgY29sb3JEb3duID0gY29sb3IuZGFya2VyKCk7CisgICAgICAgICAgICBzZXRDb2xvcihjb2xvcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb2xvclVwID0gY29sb3IuZGFya2VyKCk7CisgICAgICAgICAgICBjb2xvckRvd24gPSBjb2xvci5icmlnaHRlcigpOworICAgICAgICAgICAgc2V0Q29sb3IoY29sb3JVcCk7CisgICAgICAgIH0KKworICAgICAgICB3aWR0aC0tOworICAgICAgICBoZWlnaHQtLTsKKyAgICAgICAgZmlsbFJlY3QoeCsxLCB5KzEsIHdpZHRoLTEsIGhlaWdodC0xKTsKKworICAgICAgICBzZXRDb2xvcihjb2xvclVwKTsKKyAgICAgICAgZmlsbFJlY3QoeCwgeSwgd2lkdGgsIDEpOworICAgICAgICBmaWxsUmVjdCh4LCB5KzEsIDEsIGhlaWdodCk7CisKKyAgICAgICAgc2V0Q29sb3IoY29sb3JEb3duKTsKKyAgICAgICAgZmlsbFJlY3QoeCt3aWR0aCwgeSwgMSwgaGVpZ2h0KTsKKyAgICAgICAgZmlsbFJlY3QoeCsxLCB5K2hlaWdodCwgd2lkdGgsIDEpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3M0RSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIHJhaXNlZCkgeworICAgICAgICBDb2xvciBjb2xvciA9IGdldENvbG9yKCk7CisgICAgICAgIENvbG9yIGNvbG9yVXAsIGNvbG9yRG93bjsKKyAgICAgICAgaWYgKHJhaXNlZCkgeworICAgICAgICAgICAgY29sb3JVcCA9IGNvbG9yLmJyaWdodGVyKCk7CisgICAgICAgICAgICBjb2xvckRvd24gPSBjb2xvci5kYXJrZXIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbG9yVXAgPSBjb2xvci5kYXJrZXIoKTsKKyAgICAgICAgICAgIGNvbG9yRG93biA9IGNvbG9yLmJyaWdodGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBzZXRDb2xvcihjb2xvclVwKTsKKyAgICAgICAgZmlsbFJlY3QoeCwgeSwgd2lkdGgsIDEpOworICAgICAgICBmaWxsUmVjdCh4LCB5KzEsIDEsIGhlaWdodCk7CisKKyAgICAgICAgc2V0Q29sb3IoY29sb3JEb3duKTsKKyAgICAgICAgZmlsbFJlY3QoeCt3aWR0aCwgeSwgMSwgaGVpZ2h0KTsKKyAgICAgICAgZmlsbFJlY3QoeCsxLCB5K2hlaWdodCwgd2lkdGgsIDEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNvcHlBcmVhKENhbnZhcyBjYW52YXMsIGludCBzeCwgaW50IHN5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBkeCwgaW50IGR5KSB7CisgICAgICAgIHN4ICs9IGdldFRyYW5zZm9ybSgpLmdldFRyYW5zbGF0ZVgoKTsKKyAgICAgICAgc3kgKz0gZ2V0VHJhbnNmb3JtKCkuZ2V0VHJhbnNsYXRlWSgpOworCisgICAgICAgIE5hdGl2ZVV0aWxzLm5hdGl2ZVNjcm9sbFJlY3QoY2FudmFzLAorICAgICAgICAgICAgICAgIG5ldyBSZWN0KHN4LCBzeSwgc3ggKyB3aWR0aCwgc3kgKyBoZWlnaHQpLAorICAgICAgICAgICAgICAgIGR4LCBkeSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3NDb25maWd1cmF0aW9uLmphdmEgYi9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0FuZHJvaWRHcmFwaGljc0NvbmZpZ3VyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzg4OGNkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3NDb25maWd1cmF0aW9uLmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGNvbS5hbmRyb2lkLmludGVybmFsLmF3dDsKKworaW1wb3J0IGNvbS5hbmRyb2lkLmludGVybmFsLmF3dC5BbmRyb2lkR3JhcGhpY3MyRDsKKworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljc0RldmljZTsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlZvbGF0aWxlSW1hZ2U7CisKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkNhbnZhczsKKworcHVibGljIGNsYXNzIEFuZHJvaWRHcmFwaGljc0NvbmZpZ3VyYXRpb24gZXh0ZW5kcyBHcmFwaGljc0NvbmZpZ3VyYXRpb24geworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZUltYWdlKGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVJbWFnZShpbnQgd2lkdGgsIGludCBoZWlnaHQsCisgICAgICAgICAgICBpbnQgdHJhbnNwYXJlbmN5KSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFZvbGF0aWxlSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFZvbGF0aWxlSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgaW50IHRyYW5zcGFyZW5jeSkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICBDYW52YXMgYyA9IEFuZHJvaWRHcmFwaGljczJELmdldEFuZHJvaWRDYW52YXMoKTsKKyAgICAgICAgaWYoYyAhPSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUoMCwgMCwgYy5nZXRXaWR0aCgpLCBjLmdldEhlaWdodCgpKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbG9yTW9kZWwgZ2V0Q29sb3JNb2RlbCgpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKGludCB0cmFuc3BhcmVuY3kpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldERlZmF1bHRUcmFuc2Zvcm0oKSB7CisgICAgICAgIHJldHVybiBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEdyYXBoaWNzRGV2aWNlIGdldERldmljZSgpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldE5vcm1hbGl6aW5nVHJhbnNmb3JtKCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3NGYWN0b3J5LmphdmEgYi9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0FuZHJvaWRHcmFwaGljc0ZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTI1NWI1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkR3JhcGhpY3NGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGNvbS5hbmRyb2lkLmludGVybmFsLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuRm9udE1ldHJpY3M7CitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3MyRDsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljc0Vudmlyb25tZW50OworaW1wb3J0IGphdmEuYXd0LnBlZXIuRm9udFBlZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLk11bHRpUmVjdEFyZWE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkFuZHJvaWRGb250OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250TWFuYWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuRm9udE1ldHJpY3NJbXBsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5BbmRyb2lkRm9udE1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlV2luZG93OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLldpbmRvd0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Db21tb25HcmFwaGljczJERmFjdG9yeTsKKworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuQ2FudmFzOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUGFpbnQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CisKK3B1YmxpYyBjbGFzcyBBbmRyb2lkR3JhcGhpY3NGYWN0b3J5IGV4dGVuZHMgQ29tbW9uR3JhcGhpY3MyREZhY3RvcnkgeworICAgIAorICAgIHB1YmxpYyBHcmFwaGljc0Vudmlyb25tZW50IGNyZWF0ZUdyYXBoaWNzRW52aXJvbm1lbnQoV2luZG93RmFjdG9yeSB3ZikgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBGb250IGVtYmVkRm9udChTdHJpbmcgZm9udEZpbGVQYXRoKSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEZvbnRNYW5hZ2VyIGdldEZvbnRNYW5hZ2VyKCkgeworICAgICAgICByZXR1cm4gQW5kcm9pZEZvbnRNYW5hZ2VyLmluc3Q7CisgICAgfQorCisgICAgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQgZm9udCkgeworICAgICAgICByZXR1cm4gbmV3IEZvbnRNZXRyaWNzSW1wbChmb250KTsKKyAgICB9CisKKyAgICBwdWJsaWMgRm9udFBlZXIgZ2V0Rm9udFBlZXIoRm9udCBmb250KSB7CisgICAgICAgIC8vcmV0dXJuIGdldEZvbnRNYW5hZ2VyKCkuZ2V0Rm9udFBlZXIoZm9udC5nZXROYW1lKCksIGZvbnQuZ2V0U3R5bGUoKSwgZm9udC5nZXRTaXplKCkpOworICAgICAgICByZXR1cm4gbmV3IEFuZHJvaWRGb250KGZvbnQuZ2V0TmFtZSgpLCBmb250LmdldFN0eWxlKCksIGZvbnQuZ2V0U2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgR3JhcGhpY3MyRCBnZXRHcmFwaGljczJEKE5hdGl2ZVdpbmRvdyB3aW4sIGludCB0cmFuc2xhdGVYLAorICAgICAgICAgICAgaW50IHRyYW5zbGF0ZVksIE11bHRpUmVjdEFyZWEgY2xpcCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBHcmFwaGljczJEIGdldEdyYXBoaWNzMkQoTmF0aXZlV2luZG93IHdpbiwgaW50IHRyYW5zbGF0ZVgsCisgICAgICAgICAgICBpbnQgdHJhbnNsYXRlWSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEdyYXBoaWNzMkQgZ2V0R3JhcGhpY3MyRChDb250ZXh0IGN0eCwgQ2FudmFzIGMsIFBhaW50IHApIHsKKyAgICAgICAgcmV0dXJuIEFuZHJvaWRHcmFwaGljczJELmdldEluc3RhbmNlKGN0eCwgYywgcCk7CisgICAgfQorCisgICAgcHVibGljIEdyYXBoaWNzMkQgZ2V0R3JhcGhpY3MyRChDYW52YXMgYywgUGFpbnQgcCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgR3JhcGhpY3MyRCBnZXRHcmFwaGljczJEKCkgeworICAgICAgICByZXR1cm4gQW5kcm9pZEdyYXBoaWNzMkQuZ2V0SW5zdGFuY2UoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZEltYWdlRGVjb2Rlci5qYXZhIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkSW1hZ2VEZWNvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODFiMmUxYQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZEltYWdlRGVjb2Rlci5qYXZhCkBAIC0wLDAgKzEsMjc0IEBACisvKgorICogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5hbmRyb2lkLmludGVybmFsLmF3dDsKKworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuQml0bWFwOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuQml0bWFwRmFjdG9yeTsKKworaW1wb3J0IGphdmEuYXd0LlRyYW5zcGFyZW5jeTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworLy9pbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbXBvbmVudENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EaXJlY3RDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlQ29uc3VtZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW5kZXhDb2xvck1vZGVsOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5EZWNvZGluZ0ltYWdlU291cmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuSW1hZ2VEZWNvZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitwdWJsaWMgY2xhc3MgQW5kcm9pZEltYWdlRGVjb2RlciBleHRlbmRzIEltYWdlRGVjb2RlciB7CisgICAgCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGhpbnRmbGFncyA9CisgICAgICAgIEltYWdlQ29uc3VtZXIuU0lOR0xFRlJBTUUgfCAvLyBQTkcgaXMgYSBzdGF0aWMgaW1hZ2UKKyAgICAgICAgSW1hZ2VDb25zdW1lci5UT1BET1dOTEVGVFJJR0hUIHwgLy8gVGhpcyBvcmRlciBpcyBvbmx5IG9uZSBwb3NzaWJsZQorICAgICAgICBJbWFnZUNvbnN1bWVyLkNPTVBMRVRFU0NBTkxJTkVTOyAvLyBEb24ndCBkZWxpdmVyIGluY29tcGxldGUgc2NhbmxpbmVzCisgICAgCisgICAgLy8gRWFjaCBwaXhlbCBpcyBhIGdyYXlzY2FsZSBzYW1wbGUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX0dSQVkgPSAwOworICAgIC8vIEVhY2ggcGl4ZWwgaXMgYW4gUixHLEIgdHJpcGxlLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQTkdfQ09MT1JfVFlQRV9SR0IgPSAyOworICAgIC8vIEVhY2ggcGl4ZWwgaXMgYSBwYWxldHRlIGluZGV4LCBhIFBMVEUgY2h1bmsgbXVzdCBhcHBlYXIuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX1BMVEUgPSAzOworICAgIC8vIEVhY2ggcGl4ZWwgaXMgYSBncmF5c2NhbGUgc2FtcGxlLCBmb2xsb3dlZCBieSBhbiBhbHBoYSBzYW1wbGUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX0dSQVlfQUxQSEEgPSA0OworICAgIC8vIEVhY2ggcGl4ZWwgaXMgYW4gUixHLEIgdHJpcGxlLCBmb2xsb3dlZCBieSBhbiBhbHBoYSBzYW1wbGUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX1JHQkEgPSA2OworICAgIAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOQl9PRl9MSU5FU19QRVJfQ0hVTksgPSAxOyAgLy8gMCA9IGZ1bGwgaW1hZ2UKKyAgICAKKyAgICBCaXRtYXAgYm07ICAvLyBUaGUgaW1hZ2UgYXMgZGVjb2RlZCBieSBBbmRyb2lkCisgICAgCisgICAgLy8gSGVhZGVyIGluZm9ybWF0aW9uCisgICAgaW50IGltYWdlV2lkdGg7IC8vIEltYWdlIHNpemUKKyAgICBpbnQgaW1hZ2VIZWlnaHQ7ICAKKyAgICBpbnQgY29sb3JUeXBlOyAgLy8gT25lIG9mIHRoZSBQTkdfIGNvbnN0YW50cyBmcm9tIGFib3ZlCisgICAgaW50IGJpdERlcHRoOyAgIC8vIE51bWJlciBvZiBiaXRzIHBlciBjb2xvcgorICAgIGJ5dGUgY21hcFtdOyAgICAvLyBUaGUgY29sb3IgcGFsZXR0ZSBmb3IgaW5kZXggY29sb3IgbW9kZWxzCisgICAgQ29sb3JNb2RlbCBtb2RlbDsgIC8vIFRoZSBjb3JyZXNwb25kaW5nIEFXVCBjb2xvciBtb2RlbAorICAgIAorICAgIGJvb2xlYW4gdHJhbnNmZXJJbnRzOyAvLyBJcyB0cmFuc2ZlciBvZiB0eXBlIGludCBvciBieXRlPworICAgIGludCBkYXRhRWxlbWVudHNQZXJQaXhlbDsKKworICAgIC8vIEJ1ZmZlcnMgZm9yIGRlY29kZWQgaW1hZ2UgZGF0YQorICAgIGJ5dGUgYnl0ZU91dFtdOworICAgIGludCBpbnRPdXRbXTsKKworICAgIAorICAgIHB1YmxpYyBBbmRyb2lkSW1hZ2VEZWNvZGVyKERlY29kaW5nSW1hZ2VTb3VyY2Ugc3JjLCBJbnB1dFN0cmVhbSBpcykgeworICAgICAgICBzdXBlcihzcmMsIGlzKTsKKyAgICAgICAgZGF0YUVsZW1lbnRzUGVyUGl4ZWwgPSAxOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIC8qKgorICAgICAqIEFsbCB0aGUgZGVjb2RpbmcgaXMgZG9uZSBpbiBBbmRyb2lkCisgICAgICogCisgICAgICogQVdUPz8/OiBNZXRob2QgcmV0dXJucyBvbmx5IG9uY2UgdGhlIGltYWdlIGlzIGNvbXBsZXRseSAKKyAgICAgKiBkZWNvZGVkOyBkZWNvZGluZyBpcyBub3QgZG9uZSBhc3luY2hyb25vdXNseQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlY29kZUltYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJtID0gQml0bWFwRmFjdG9yeS5kZWNvZGVTdHJlYW0oaW5wdXRTdHJlYW0pOworICAgICAgICAgICAgaWYgKGJtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIklucHV0IHN0cmVhbSBlbXB0eSBhbmQgbm8gaW1hZ2UgY2FjaGVkIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIENoZWNrIHNpemUKKyAgICAgICAgICAgIGltYWdlV2lkdGggPSBibS5nZXRXaWR0aCgpOworICAgICAgICAgICAgaW1hZ2VIZWlnaHQgPSBibS5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGlmIChpbWFnZVdpZHRoIDwgMCB8fCBpbWFnZUhlaWdodCA8IDAgKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklsbGVnYWwgaW1hZ2Ugc2l6ZTogIiAKKyAgICAgICAgICAgICAgICAgICAgICAgICsgaW1hZ2VXaWR0aCArICIsICIgKyBpbWFnZUhlaWdodCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIFdlIGdvdCB0aGUgaW1hZ2UgZnVsbHkgZGVjb2RlZDsgbm93IHNlbmQgYWxsIGltYWdlIGRhdGEgdG8gQVdUCisgICAgICAgICAgICBzZXREaW1lbnNpb25zKGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0KTsKKyAgICAgICAgICAgIG1vZGVsID0gY3JlYXRlQ29sb3JNb2RlbCgpOworICAgICAgICAgICAgc2V0Q29sb3JNb2RlbChtb2RlbCk7CisgICAgICAgICAgICBzZXRIaW50cyhoaW50ZmxhZ3MpOworICAgICAgICAgICAgc2V0UHJvcGVydGllcyhuZXcgSGFzaHRhYmxlPE9iamVjdCwgT2JqZWN0PigpKTsgLy8gRW1wdHkKKyAgICAgICAgICAgIHNlbmRQaXhlbHMoTkJfT0ZfTElORVNfUEVSX0NIVU5LICE9IDAgPyBOQl9PRl9MSU5FU19QRVJfQ0hVTksgOiBpbWFnZUhlaWdodCk7CisgICAgICAgICAgICBpbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuU1RBVElDSU1BR0VET05FKTsgICAgICAgIAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5JTUFHRUVSUk9SKTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjbG9zZVN0cmVhbSgpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIENyZWF0ZSB0aGUgQVdUIGNvbG9yIG1vZGVsCisgICAgICoKKyAgICAgKiA/Pz9BV1Q6IEFuZHJvaWQgQml0bWFwcyBhcmUgYWx3YXlzIG9mIHR5cGU6IEFSR0ItODg4OC1EaXJlY3QgY29sb3IgbW9kZWwKKyAgICAgKiAKKyAgICAgKiBIb3dldmVyLCB3ZSBsZWF2ZSB0aGUgY29kZSBoZXJlIGZvciBhIG1vcmUgcG93ZXJmdWxsIGRlY29kZXIgCisgICAgICogdGhhdCByZXR1cm5zIGEgbmF0aXZlIG1vZGVsLCBhbmQgdGhlIGNvbnZlcnNpb24gaXMgdGhlbiBoYW5kbGVkCisgICAgICogaW4gQVdULiBXaXRoIHN1Y2ggYSBkZWNvZGVyLCB3ZSB3b3VsZCBuZWVkIHRvIGdldCB0aGUgY29sb3JUeXBlLCAKKyAgICAgKiB0aGUgYml0RGVwdGgsIChhbmQgdGhlIGNvbG9yIHBhbGV0dGUgZm9yIGFuIGluZGV4IGNvbG9yIG1vZGVsKQorICAgICAqIGZyb20gdGhlIGltYWdlIGFuZCBjb25zdHJ1Y3QgdGhlIGNvcnJlY3QgY29sb3IgbW9kZWwgaGVyZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbG9yTW9kZWwgY3JlYXRlQ29sb3JNb2RlbCgpIHsKKyAgICAgICAgQ29sb3JNb2RlbCBjbSA9IG51bGw7CisgICAgICAgIGludCBibU1vZGVsID0gNTsgLy8gVE9ETyBUaGlzIGRvZXNuJ3QgZXhpc3Q6IGJtLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgY21hcCA9IG51bGw7CisgICAgICAgICAgIAorICAgICAgICBzd2l0Y2ggKGJtTW9kZWwpIHsKKyAgICAgICAgLy8gQTFfTU9ERUwKKyAgICAgICAgY2FzZSAxOiAKKyAgICAgICAgICAgIGNvbG9yVHlwZSA9IFBOR19DT0xPUl9UWVBFX0dSQVk7CisgICAgICAgICAgICBiaXREZXB0aCA9IDE7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIAorICAgICAgICAvLyBBOF9NT0RFTAorICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBjb2xvclR5cGUgPSBQTkdfQ09MT1JfVFlQRV9HUkFZX0FMUEhBOworICAgICAgICAgICAgYml0RGVwdGggPSA4OworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAKKyAgICAgICAgLy8gSU5ERVg4X01PREVMCisgICAgICAgIC8vIFJHQl81NjVfTU9ERUwKKyAgICAgICAgLy8gQVJHQl84ODg4X01PREVMCisgICAgICAgIGNhc2UgMzoKKyAgICAgICAgY2FzZSA0OiAKKyAgICAgICAgY2FzZSA1OiAKKyAgICAgICAgICAgIGNvbG9yVHlwZSA9IGJtLmhhc0FscGhhKCkgPyBQTkdfQ09MT1JfVFlQRV9SR0JBIDogUE5HX0NPTE9SX1RZUEVfUkdCOworICAgICAgICAgICAgYml0RGVwdGggPSA4OworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIHN3aXRjaCAoY29sb3JUeXBlKSB7CisgICAgICAgIAorICAgICAgICAgICAgY2FzZSBQTkdfQ09MT1JfVFlQRV9HUkFZOiB7CisgICAgICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gNCAmJiBiaXREZXB0aCAhPSAyICYmICBiaXREZXB0aCAhPSAxKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBDcmVhdGUgZ3JheSBjb2xvciBtb2RlbAorICAgICAgICAgICAgICAgIGludCBudW1FbnRyaWVzID0gMSA8PCBiaXREZXB0aDsKKyAgICAgICAgICAgICAgICBpbnQgc2NhbGVGYWN0b3IgPSAyNTUgLyAobnVtRW50cmllcy0xKTsKKyAgICAgICAgICAgICAgICBieXRlIGNvbXBzW10gPSBuZXcgYnl0ZVtudW1FbnRyaWVzXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUVudHJpZXM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBjb21wc1tpXSA9IChieXRlKSAoaSAqIHNjYWxlRmFjdG9yKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY20gPSBuZXcgSW5kZXhDb2xvck1vZGVsKGJpdERlcHRoLCBudW1FbnRyaWVzLCBjb21wcywgY29tcHMsIGNvbXBzKTsKKworICAgICAgICAgICAgICAgIHRyYW5zZmVySW50cyA9IGZhbHNlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIFBOR19DT0xPUl9UWVBFX1JHQjogeworICAgICAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgY20gPSBuZXcgRGlyZWN0Q29sb3JNb2RlbCgyNCwgMHhmZjAwMDAsIDB4RkYwMCwgMHhGRik7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgdHJhbnNmZXJJbnRzID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBQTkdfQ09MT1JfVFlQRV9QTFRFOiB7CisgICAgICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gNCAmJiBiaXREZXB0aCAhPSAyICYmIGJpdERlcHRoICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjNDPVVua25vd24gUE5HIGNvbG9yIHR5cGUKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChjbWFwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiUGFsZXR0ZSBjb2xvciB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBJbmRleENvbG9yTW9kZWwoYml0RGVwdGgsIGNtYXAubGVuZ3RoIC8gMywgY21hcCwgMCwgZmFsc2UpOworCisgICAgICAgICAgICAgICAgdHJhbnNmZXJJbnRzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgUE5HX0NPTE9SX1RZUEVfR1JBWV9BTFBIQTogeworICAgICAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBDb21wb25lbnRDb2xvck1vZGVsKENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19HUkFZKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5ULAorICAgICAgICAgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlci5UWVBFX0JZVEUpOworCisgICAgICAgICAgICAgICAgdHJhbnNmZXJJbnRzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZGF0YUVsZW1lbnRzUGVyUGl4ZWwgPSAyOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIFBOR19DT0xPUl9UWVBFX1JHQkE6IHsKKyAgICAgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0M9VW5rbm93biBQTkcgY29sb3IgdHlwZQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY20gPSBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKTsKKworICAgICAgICAgICAgICAgIHRyYW5zZmVySW50cyA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIAorICAgICAgICByZXR1cm4gY207CisgICAgfQorICAgIAorICAgIHByaXZhdGUgdm9pZCBzZW5kUGl4ZWxzKGludCBuYk9mTGluZXNQZXJDaHVuaykgeworICAgICAgICBpbnQgdyA9IGltYWdlV2lkdGg7CisgICAgICAgIGludCBoID0gaW1hZ2VIZWlnaHQ7CisgICAgICAgIGludCBuID0gMTsKKyAgICAgICAgaWYgKG5iT2ZMaW5lc1BlckNodW5rID4gMCAmJiBuYk9mTGluZXNQZXJDaHVuayA8PSBoKSB7CisgICAgICAgICAgICBuID0gbmJPZkxpbmVzUGVyQ2h1bms7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmICh0cmFuc2ZlckludHMpIHsKKyAgICAgICAgICAgIC8vIENyZWF0ZSBvdXRwdXQgYnVmZmVyCisgICAgICAgICAgICBpbnRPdXQgPSBuZXcgaW50W3cgKiBuXTsKKyAgICAgICAgICAgIGZvciAoaW50IHlpID0gMDsgeWkgPCBoOyB5aSArPSBuKSB7CisgICAgICAgICAgICAgICAgLy8gTGFzdCBjaHVuayBtaWdodCBjb250YWluIGxlc3MgbGluZXNzCisgICAgICAgICAgICAgICAgaWYgKG4gPiAxICYmIGggLSB5aSA8IG4gKSB7CisgICAgICAgICAgICAgICAgICAgIG4gPSBoIC0geWk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJtLmdldFBpeGVscyhpbnRPdXQsIDAsIHcsIDAsIHlpLCB3LCBuKTsKKyAgICAgICAgICAgICAgICBzZXRQaXhlbHMoMCwgeWksIHcsIG4sIG1vZGVsLCBpbnRPdXQsIDAsIHcpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gQW5kcm9pZCBiaXRtYXBzIGFsd2F5cyBzdG9yZSBpbnRzIChBUkdCLTg4ODggZGlyZWN0IG1vZGVsKQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkJ5dGUgdHJhbnNmZXIgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9CisgICAgfQorICAgIAorfQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkSmF2YUJsaXR0ZXIuamF2YSBiL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZEphdmFCbGl0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDIzYjUzNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZEphdmFCbGl0dGVyLmphdmEKQEAgLTAsMCArMSw1MzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3Q7CisKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkJpdG1hcDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkNhbnZhczsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLk1hdHJpeDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLlBhaW50OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuTXVsdGlSZWN0QXJlYTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5YT1JDb21wb3NpdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXIuQmxpdHRlcjsKKworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckludDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SYXN0ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuV3JpdGFibGVSYXN0ZXI7CisKK3B1YmxpYyBjbGFzcyBBbmRyb2lkSmF2YUJsaXR0ZXIgaW1wbGVtZW50cyBCbGl0dGVyIHsKKworICAgIHByaXZhdGUgQ2FudmFzIGNhbnZhczsKKyAgICBwcml2YXRlIFBhaW50IHBhaW50OworICAgIHByaXZhdGUgaW50IGNvbG9yQ2FjaGU7CisgICAgICAgIAorICAgIHB1YmxpYyBBbmRyb2lkSmF2YUJsaXR0ZXIoQ2FudmFzIGMpIHsKKyAgICAgICAgdGhpcy5jYW52YXMgPSBjOworICAgICAgICB0aGlzLnBhaW50ID0gbmV3IFBhaW50KCk7CisgICAgICAgIHRoaXMucGFpbnQuc2V0U3Ryb2tlV2lkdGgoMSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEluc3RlYWQgb2YgbXVsdGlwbGljYXRpb24gYW5kIGRpdmlzaW9uIHdlIGFyZSB1c2luZyB2YWx1ZXMgZnJvbQorICAgICAqIExvb2t1cCB0YWJsZXMuCisgICAgICovCisgICAgc3RhdGljIGJ5dGUgbXVsTFVUW11bXTsgLy8gTG9va3VwIHRhYmxlIGZvciBtdWx0aXBsaWNhdGlvbgorICAgIHN0YXRpYyBieXRlIGRpdkxVVFtdW107IC8vIExvb2t1cCB0YWJsZSBmb3IgZGl2aXNpb24KKworICAgIHN0YXRpY3sKKyAgICAgICAgbXVsTFVUID0gbmV3IGJ5dGVbMjU2XVsyNTZdOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspeworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IDI1NjsgaisrKXsKKyAgICAgICAgICAgICAgICBtdWxMVVRbaV1bal0gPSAoYnl0ZSkoKGZsb2F0KShpICogaikvMjU1ICsgMC41Zik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZGl2TFVUID0gbmV3IGJ5dGVbMjU2XVsyNTZdOworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgMjU2OyBpKyspeworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IGk7IGorKyl7CisgICAgICAgICAgICAgICAgZGl2TFVUW2ldW2pdID0gKGJ5dGUpKCgoZmxvYXQpaiAvIDI1NSkgLyAoKGZsb2F0KWkvIDI1NSkgKiAyNTUgKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvcihpbnQgaiA9IGk7IGogPCAyNTY7IGorKyl7CisgICAgICAgICAgICAgICAgZGl2TFVUW2ldW2pdID0gKGJ5dGUpMjU1OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgc3RhdGljIGludCBBbHBoYUNvbXBvc2l0ZU1vZGUgPSAxOworICAgIGZpbmFsIHN0YXRpYyBpbnQgWE9STW9kZSA9IDI7CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQWZmaW5lVHJhbnNmb3JtIHN5c3hmb3JtLAorICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtLCBDb21wb3NpdGUgY29tcCwgQ29sb3IgYmdjb2xvciwKKyAgICAgICAgICAgIE11bHRpUmVjdEFyZWEgY2xpcCkgeworICAgICAgICAKKyAgICAgICAgaWYoeGZvcm0gPT0gbnVsbCl7CisgICAgICAgICAgICBibGl0KHNyY1gsIHNyY1ksIHNyY1N1cmYsIGRzdFgsIGRzdFksIGRzdFN1cmYsIHdpZHRoLCBoZWlnaHQsCisgICAgICAgICAgICAgICAgICAgIHN5c3hmb3JtLCBjb21wLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBkb3VibGUgc2NhbGVYID0geGZvcm0uZ2V0U2NhbGVYKCk7CisgICAgICAgICAgICBkb3VibGUgc2NhbGVZID0geGZvcm0uZ2V0U2NhbGVZKCk7CisgICAgICAgICAgICBkb3VibGUgc2NhbGVkWCA9IGRzdFggLyBzY2FsZVg7CisgICAgICAgICAgICBkb3VibGUgc2NhbGVkWSA9IGRzdFkgLyBzY2FsZVk7CisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gYXQgPSBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgICAgICAgICBhdC5zZXRUb1RyYW5zbGF0aW9uKHNjYWxlZFgsIHNjYWxlZFkpOworICAgICAgICAgICAgeGZvcm0uY29uY2F0ZW5hdGUoYXQpOworICAgICAgICAgICAgc3lzeGZvcm0uY29uY2F0ZW5hdGUoeGZvcm0pOworICAgICAgICAgICAgYmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCAwLCAwLCBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICBzeXN4Zm9ybSwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGJsaXQoaW50IHNyY1gsIGludCBzcmNZLCBTdXJmYWNlIHNyY1N1cmYsIGludCBkc3RYLCBpbnQgZHN0WSwKKyAgICAgICAgICAgIFN1cmZhY2UgZHN0U3VyZiwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBBZmZpbmVUcmFuc2Zvcm0gc3lzeGZvcm0sCisgICAgICAgICAgICBDb21wb3NpdGUgY29tcCwgQ29sb3IgYmdjb2xvciwgTXVsdGlSZWN0QXJlYSBjbGlwKSB7CisgICAgICAgIAorICAgICAgICBpZihzeXN4Zm9ybSA9PSBudWxsKSB7CisgICAgICAgICAgICBzeXN4Zm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgdHlwZSA9IHN5c3hmb3JtLmdldFR5cGUoKTsKKyAgICAgICAgc3dpdGNoKHR5cGUpeworICAgICAgICAgICAgY2FzZSBBZmZpbmVUcmFuc2Zvcm0uVFlQRV9UUkFOU0xBVElPTjoKKyAgICAgICAgICAgICAgICBkc3RYICs9IHN5c3hmb3JtLmdldFRyYW5zbGF0ZVgoKTsKKyAgICAgICAgICAgICAgICBkc3RZICs9IHN5c3hmb3JtLmdldFRyYW5zbGF0ZVkoKTsKKyAgICAgICAgICAgIGNhc2UgQWZmaW5lVHJhbnNmb3JtLlRZUEVfSURFTlRJVFk6CisgICAgICAgICAgICAgICAgc2ltcGxlQmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCBkc3RYLCBkc3RZLCBkc3RTdXJmLAorICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGludCBzcmNXID0gc3JjU3VyZi5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGludCBzcmNIID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKworICAgICAgICAgICAgICAgIGludCB3ID0gc3JjWCArIHdpZHRoIDwgc3JjVyA/IHdpZHRoIDogc3JjVyAtIHNyY1g7CisgICAgICAgICAgICAgICAgaW50IGggPSBzcmNZICsgaGVpZ2h0IDwgc3JjSCA/IGhlaWdodCA6IHNyY0ggLSBzcmNZOworCisgICAgICAgICAgICAgICAgQ29sb3JNb2RlbCBzcmNDTSA9IHNyY1N1cmYuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgICAgIFJhc3RlciBzcmNSID0gc3JjU3VyZi5nZXRSYXN0ZXIoKS5jcmVhdGVDaGlsZChzcmNYLCBzcmNZLAorICAgICAgICAgICAgICAgICAgICAgICAgdywgaCwgMCwgMCwgbnVsbCk7CisKKyAgICAgICAgICAgICAgICBDb2xvck1vZGVsIGRzdENNID0gZHN0U3VyZi5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgICAgICAgICAgV3JpdGFibGVSYXN0ZXIgZHN0UiA9IGRzdFN1cmYuZ2V0UmFzdGVyKCk7CisKKyAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZEJsaXQoc3JjQ00sIHNyY1IsIDAsIDAsIGRzdENNLCBkc3RSLCBkc3RYLCBkc3RZLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgc3lzeGZvcm0sIGNvbXAsIGJnY29sb3IsIGNsaXApOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzaW1wbGVCbGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKworICAgICAgICAvLyBUT0RPIEl0J3MgcG9zc2libGUsIHRob3VnaCB1bmxpa2VseSB0aGF0IHdlIG1pZ2h0IGVuY291bnRlciBub24taW50W10KKyAgICAgICAgLy8gZGF0YSBidWZmZXJzLiBJbiB0aGlzIGNhc2UgdGhlIGZvbGxvd2luZyBjb2RlIG5lZWRzIHRvIGhhdmUgc2V2ZXJhbAorICAgICAgICAvLyBicmFuY2hlcyB0aGF0IHRha2UgdGhpcyBpbnRvIGFjY291bnQuCisgICAgICAgIGRhdGEgPSAoRGF0YUJ1ZmZlckludClzcmNTdXJmLmdldFJhc3RlcigpLmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgaW50W10gcGl4ZWxzID0gZGF0YS5nZXREYXRhKCk7CisgICAgICAgIGlmICghc3JjU3VyZi5nZXRDb2xvck1vZGVsKCkuaGFzQWxwaGEoKSkgeworICAgICAgICAgICAgLy8gVGhpcyB3b3VsZG4ndCBiZSBuZWNlc3NhcnkgaWYgQW5kcm9pZCBzdXBwb3J0ZWQgUkdCXzg4OC4KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGl4ZWxzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gcGl4ZWxzW2ldIHwgMHhmZjAwMDAwMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBibWFwID0gQml0bWFwLmNyZWF0ZUJpdG1hcChwaXhlbHMsIHdpZHRoLCBoZWlnaHQsIEJpdG1hcC5Db25maWcuQVJHQl84ODg4KTsKKyAgICAgICAgY2FudmFzLmRyYXdCaXRtYXAoYm1hcCwgZHN0WCwgZHN0WSwgcGFpbnQpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKworICAgICAgICBqYXZhQmx0KHNyY1gsIHNyY1ksIHNyY1N1cmYuZ2V0V2lkdGgoKSwgc3JjU3VyZi5nZXRIZWlnaHQoKSwKKyAgICAgICAgICAgICAgICBzcmNTdXJmLmdldENvbG9yTW9kZWwoKSwgc3JjU3VyZi5nZXRSYXN0ZXIoKSwgZHN0WCwgZHN0WSwKKyAgICAgICAgICAgICAgICBkc3RTdXJmLmdldFdpZHRoKCksIGRzdFN1cmYuZ2V0SGVpZ2h0KCksCisgICAgICAgICAgICAgICAgZHN0U3VyZi5nZXRDb2xvck1vZGVsKCksIGRzdFN1cmYuZ2V0UmFzdGVyKCksCisgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgamF2YUJsdChpbnQgc3JjWCwgaW50IHNyY1ksIGludCBzcmNXLCBpbnQgc3JjSCwKKyAgICAgICAgICAgIENvbG9yTW9kZWwgc3JjQ00sIFJhc3RlciBzcmNSYXN0LCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBpbnQgZHN0VywgaW50IGRzdEgsIENvbG9yTW9kZWwgZHN0Q00sIFdyaXRhYmxlUmFzdGVyIGRzdFJhc3QsCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIENvbXBvc2l0ZSBjb21wLCBDb2xvciBiZ2NvbG9yLAorICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBjbGlwKXsKKyAgICAgICAgCisgICAgICAgIGludCBzcmNYMiA9IHNyY1cgLSAxOworICAgICAgICBpbnQgc3JjWTIgPSBzcmNIIC0gMTsKKyAgICAgICAgaW50IGRzdFgyID0gZHN0VyAtIDE7CisgICAgICAgIGludCBkc3RZMiA9IGRzdEggLSAxOworCisgICAgICAgIGlmKHNyY1ggPCAwKXsKKyAgICAgICAgICAgIHdpZHRoICs9IHNyY1g7CisgICAgICAgICAgICBzcmNYID0gMDsKKyAgICAgICAgfQorICAgICAgICBpZihzcmNZIDwgMCl7CisgICAgICAgICAgICBoZWlnaHQgKz0gc3JjWTsKKyAgICAgICAgICAgIHNyY1kgPSAwOworICAgICAgICB9CisKKyAgICAgICAgaWYoZHN0WCA8IDApeworICAgICAgICAgICAgd2lkdGggKz0gZHN0WDsKKyAgICAgICAgICAgIHNyY1ggLT0gZHN0WDsKKyAgICAgICAgICAgIGRzdFggPSAwOworICAgICAgICB9CisgICAgICAgIGlmKGRzdFkgPCAwKXsKKyAgICAgICAgICAgIGhlaWdodCArPSBkc3RZOworICAgICAgICAgICAgc3JjWSAtPSBkc3RZOworICAgICAgICAgICAgZHN0WSA9IDA7CisgICAgICAgIH0KKworICAgICAgICBpZihzcmNYID4gc3JjWDIgfHwgc3JjWSA+IHNyY1kyKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYoZHN0WCA+IGRzdFgyIHx8IGRzdFkgPiBkc3RZMikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYoc3JjWCArIHdpZHRoID4gc3JjWDIpIHsKKyAgICAgICAgICAgIHdpZHRoID0gc3JjWDIgLSBzcmNYICsgMTsKKyAgICAgICAgfQorICAgICAgICBpZihzcmNZICsgaGVpZ2h0ID4gc3JjWTIpIHsKKyAgICAgICAgICAgIGhlaWdodCA9IHNyY1kyIC0gc3JjWSArIDE7CisgICAgICAgIH0KKyAgICAgICAgaWYoZHN0WCArIHdpZHRoID4gZHN0WDIpIHsKKyAgICAgICAgICAgIHdpZHRoID0gZHN0WDIgLSBkc3RYICsgMTsKKyAgICAgICAgfQorICAgICAgICBpZihkc3RZICsgaGVpZ2h0ID4gZHN0WTIpIHsKKyAgICAgICAgICAgIGhlaWdodCA9IGRzdFkyIC0gZHN0WSArIDE7CisgICAgICAgIH0KKworICAgICAgICBpZih3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgY2xpcFJlY3RzW107CisgICAgICAgIGlmKGNsaXAgIT0gbnVsbCkgeworICAgICAgICAgICAgY2xpcFJlY3RzID0gY2xpcC5yZWN0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2xpcFJlY3RzID0gbmV3IGludFtdezUsIDAsIDAsIGRzdFcgLSAxLCBkc3RIIC0gMX07CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGlzQWxwaGFDb21wID0gZmFsc2U7CisgICAgICAgIGludCBydWxlID0gMDsKKyAgICAgICAgZmxvYXQgYWxwaGEgPSAwOworICAgICAgICBib29sZWFuIGlzWE9SQ29tcCA9IGZhbHNlOworICAgICAgICBDb2xvciB4b3Jjb2xvciA9IG51bGw7CisgICAgICAgIENvbXBvc2l0ZUNvbnRleHQgY29udCA9IG51bGw7CisKKyAgICAgICAgaWYoY29tcCBpbnN0YW5jZW9mIEFscGhhQ29tcG9zaXRlKXsKKyAgICAgICAgICAgIGlzQWxwaGFDb21wID0gdHJ1ZTsKKyAgICAgICAgICAgIEFscGhhQ29tcG9zaXRlIGFjID0gKEFscGhhQ29tcG9zaXRlKSBjb21wOworICAgICAgICAgICAgcnVsZSA9IGFjLmdldFJ1bGUoKTsKKyAgICAgICAgICAgIGFscGhhID0gYWMuZ2V0QWxwaGEoKTsKKyAgICAgICAgfWVsc2UgaWYoY29tcCBpbnN0YW5jZW9mIFhPUkNvbXBvc2l0ZSl7CisgICAgICAgICAgICBpc1hPUkNvbXAgPSB0cnVlOworICAgICAgICAgICAgWE9SQ29tcG9zaXRlIHhjb21wID0gKFhPUkNvbXBvc2l0ZSkgY29tcDsKKyAgICAgICAgICAgIHhvcmNvbG9yID0geGNvbXAuZ2V0WE9SQ29sb3IoKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBjb250ID0gY29tcC5jcmVhdGVDb250ZXh0KHNyY0NNLCBkc3RDTSwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgY2xpcFJlY3RzWzBdOyBpICs9IDQpeworICAgICAgICAgICAgaW50IF9zeCA9IHNyY1g7CisgICAgICAgICAgICBpbnQgX3N5ID0gc3JjWTsKKworICAgICAgICAgICAgaW50IF9keCA9IGRzdFg7CisgICAgICAgICAgICBpbnQgX2R5ID0gZHN0WTsKKworICAgICAgICAgICAgaW50IF93ID0gd2lkdGg7CisgICAgICAgICAgICBpbnQgX2ggPSBoZWlnaHQ7CisKKyAgICAgICAgICAgIGludCBjeCA9IGNsaXBSZWN0c1tpXTsgICAgICAgICAgLy8gQ2xpcHBpbmcgbGVmdCB0b3AgWAorICAgICAgICAgICAgaW50IGN5ID0gY2xpcFJlY3RzW2kgKyAxXTsgICAgICAvLyBDbGlwcGluZyBsZWZ0IHRvcCBZCisgICAgICAgICAgICBpbnQgY3gyID0gY2xpcFJlY3RzW2kgKyAyXTsgICAgIC8vIENsaXBwaW5nIHJpZ2h0IGJvdHRvbSBYCisgICAgICAgICAgICBpbnQgY3kyID0gY2xpcFJlY3RzW2kgKyAzXTsgICAgIC8vIENsaXBwaW5nIHJpZ2h0IGJvdHRvbSBZCisKKyAgICAgICAgICAgIGlmKF9keCA+IGN4MiB8fCBfZHkgPiBjeTIgfHwgZHN0WDIgPCBjeCB8fCBkc3RZMiA8IGN5KSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKGN4ID4gX2R4KXsKKyAgICAgICAgICAgICAgICBpbnQgc2h4ID0gY3ggLSBfZHg7CisgICAgICAgICAgICAgICAgX3cgLT0gc2h4OworICAgICAgICAgICAgICAgIF9keCA9IGN4OworICAgICAgICAgICAgICAgIF9zeCArPSBzaHg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKGN5ID4gX2R5KXsKKyAgICAgICAgICAgICAgICBpbnQgc2h5ID0gY3kgLSBfZHk7CisgICAgICAgICAgICAgICAgX2ggLT0gc2h5OworICAgICAgICAgICAgICAgIF9keSA9IGN5OworICAgICAgICAgICAgICAgIF9zeSArPSBzaHk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKF9keCArIF93ID4gY3gyICsgMSl7CisgICAgICAgICAgICAgICAgX3cgPSBjeDIgLSBfZHggKyAxOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZihfZHkgKyBfaCA+IGN5MiArIDEpeworICAgICAgICAgICAgICAgIF9oID0gY3kyIC0gX2R5ICsgMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYoX3N4ID4gc3JjWDIgfHwgX3N5ID4gc3JjWTIpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYoaXNBbHBoYUNvbXApeworICAgICAgICAgICAgICAgIGFscGhhQ29tcG9zZShfc3gsIF9zeSwgc3JjQ00sIHNyY1Jhc3QsIF9keCwgX2R5LAorICAgICAgICAgICAgICAgICAgICAgICAgZHN0Q00sIGRzdFJhc3QsIF93LCBfaCwgcnVsZSwgYWxwaGEsIGJnY29sb3IpOworICAgICAgICAgICAgfWVsc2UgaWYoaXNYT1JDb21wKXsKKyAgICAgICAgICAgICAgICB4b3JDb21wb3NlKF9zeCwgX3N5LCBzcmNDTSwgc3JjUmFzdCwgX2R4LCBfZHksCisgICAgICAgICAgICAgICAgICAgICAgICBkc3RDTSwgZHN0UmFzdCwgX3csIF9oLCB4b3Jjb2xvcik7CisgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICBSYXN0ZXIgc3IgPSBzcmNSYXN0LmNyZWF0ZUNoaWxkKF9zeCwgX3N5LCBfdywgX2gsIDAsIDAsIG51bGwpOworICAgICAgICAgICAgICAgIFdyaXRhYmxlUmFzdGVyIGRyID0gZHN0UmFzdC5jcmVhdGVXcml0YWJsZUNoaWxkKF9keCwgX2R5LAorICAgICAgICAgICAgICAgICAgICAgICAgX3csIF9oLCAwLCAwLCBudWxsKTsKKyAgICAgICAgICAgICAgICBjb250LmNvbXBvc2Uoc3IsIGRyLCBkcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorCisgICAgRGF0YUJ1ZmZlckludCBkYXRhOworICAgIEJpdG1hcCBibWFwLCBibXA7CisgICAgCisgICAgdm9pZCBhbHBoYUNvbXBvc2UoaW50IHNyY1gsIGludCBzcmNZLCBDb2xvck1vZGVsIHNyY0NNLCBSYXN0ZXIgc3JjUmFzdCwKKyAgICAgICAgICAgIGludCBkc3RYLCBpbnQgZHN0WSwgQ29sb3JNb2RlbCBkc3RDTSwgV3JpdGFibGVSYXN0ZXIgZHN0UmFzdCwKKyAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IHJ1bGUsIGZsb2F0IGFscGhhLCBDb2xvciBiZ2NvbG9yKXsKKyAgICAgICAgCisgICAgICAgIE9iamVjdCBzcmNQaXhlbCA9IGdldFRyYW5zZmVyQXJyYXkoc3JjUmFzdCwgMSk7CisgICAgICAgIGRhdGEgPSAoRGF0YUJ1ZmZlckludClzcmNSYXN0LmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgaW50IHBpeFtdID0gZGF0YS5nZXREYXRhKCk7CisgICAgICAgIGJtYXAgPSBCaXRtYXAuY3JlYXRlQml0bWFwKHBpeCwgd2lkdGgsIGhlaWdodCwgQml0bWFwLkNvbmZpZy5SR0JfNTY1KTsKKyAgICAgICAgY2FudmFzLmRyYXdCaXRtYXAoYm1hcCwgZHN0WCwgZHN0WSwgcGFpbnQpOworICAgIH0KKyAgICAKKyAgICB2b2lkIHJlbmRlcihpbnRbXSBpbWcsIGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGNhbnZhcy5kcmF3Qml0bWFwKEJpdG1hcC5jcmVhdGVCaXRtYXAoaW1nLCB3aWR0aCwgaGVpZ2h0LCBCaXRtYXAuQ29uZmlnLkFSR0JfODg4OCksIHgsIHksIHBhaW50KTsKKyAgICB9CisKKyAgICB2b2lkIHhvckNvbXBvc2UoaW50IHNyY1gsIGludCBzcmNZLCBDb2xvck1vZGVsIHNyY0NNLCBSYXN0ZXIgc3JjUmFzdCwKKyAgICAgICAgICAgIGludCBkc3RYLCBpbnQgZHN0WSwgQ29sb3JNb2RlbCBkc3RDTSwgV3JpdGFibGVSYXN0ZXIgZHN0UmFzdCwKKyAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29sb3IgeG9yY29sb3IpeworCisgICAgICAgIGRhdGEgPSAoRGF0YUJ1ZmZlckludClzcmNSYXN0LmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgaW50IHBpeFtdID0gZGF0YS5nZXREYXRhKCk7CisgICAgICAgIGJtYXAgPSBCaXRtYXAuY3JlYXRlQml0bWFwKHBpeCwgd2lkdGgsIGhlaWdodCwgQml0bWFwLkNvbmZpZy5SR0JfNTY1KTsKKyAgICAgICAgY2FudmFzLmRyYXdCaXRtYXAoYm1hcCwgZHN0WCwgZHN0WSwgcGFpbnQpOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmb3JtZWRCbGl0KENvbG9yTW9kZWwgc3JjQ00sIFJhc3RlciBzcmNSLCBpbnQgc3JjWCwgaW50IHNyY1ksCisgICAgICAgICAgICBDb2xvck1vZGVsIGRzdENNLCBXcml0YWJsZVJhc3RlciBkc3RSLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEFmZmluZVRyYW5zZm9ybSBhdCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKyAgICAgICAgCisgICAgICAgIGRhdGEgPSAoRGF0YUJ1ZmZlckludClzcmNSLmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgaW50W10gcGl4ZWxzID0gZGF0YS5nZXREYXRhKCk7CisgICAgICAgIGlmICghc3JjQ00uaGFzQWxwaGEoKSkgeworICAgICAgICAgICAgLy8gVGhpcyB3b3VsZG4ndCBiZSBuZWNlc3NhcnkgaWYgQW5kcm9pZCBzdXBwb3J0ZWQgUkdCXzg4OC4KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGl4ZWxzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gcGl4ZWxzW2ldIHwgMHhmZjAwMDAwMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBibWFwID0gQml0bWFwLmNyZWF0ZUJpdG1hcChwaXhlbHMsIHdpZHRoLCBoZWlnaHQsIEJpdG1hcC5Db25maWcuQVJHQl84ODg4KTsKKyAgICAgICAgCisgICAgICAgIE1hdHJpeCB0bSA9IG5ldyBNYXRyaXgoKTsKKyAgICAgICAgdG0uc2V0Q29uY2F0KGNhbnZhcy5nZXRNYXRyaXgoKSwgQW5kcm9pZEdyYXBoaWNzMkQuY3JlYXRlTWF0cml4T2JqKGF0KSk7CisgICAgICAgIGlmKGF0LmdldFR5cGUoKSA+IDEpIHsKKyAgICAgICAgICAgIGJtcCA9IEJpdG1hcC5jcmVhdGVCaXRtYXAoYm1hcCwgMCwgMCwgd2lkdGgsIGhlaWdodCwgdG0sIHRydWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYm1wID0gQml0bWFwLmNyZWF0ZUJpdG1hcChibWFwLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCB0bSwgZmFsc2UpOworICAgICAgICB9CisgICAgICAgIGNhbnZhcy5kcmF3Qml0bWFwKGJtcCwgZHN0WCArIChmbG9hdClhdC5nZXRUcmFuc2xhdGVYKCksIGRzdFkgKyAoZmxvYXQpYXQuZ2V0VHJhbnNsYXRlWSgpLCBwYWludCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRChBZmZpbmVUcmFuc2Zvcm0gYXQsIFJlY3RhbmdsZSByKSB7CisgICAgICAgIGludCB4ID0gci54OworICAgICAgICBpbnQgeSA9IHIueTsKKyAgICAgICAgaW50IHdpZHRoID0gci53aWR0aDsKKyAgICAgICAgaW50IGhlaWdodCA9IHIuaGVpZ2h0OworCisgICAgICAgIGZsb2F0W10gY29ybmVycyA9IHsKKyAgICAgICAgICAgIHgsIHksCisgICAgICAgICAgICB4ICsgd2lkdGgsIHksCisgICAgICAgICAgICB4ICsgd2lkdGgsIHkgKyBoZWlnaHQsCisgICAgICAgICAgICB4LCB5ICsgaGVpZ2h0CisgICAgICAgIH07CisKKyAgICAgICAgYXQudHJhbnNmb3JtKGNvcm5lcnMsIDAsIGNvcm5lcnMsIDAsIDQpOworCisgICAgICAgIFJlY3RhbmdsZTJELkZsb2F0IGJvdW5kcyA9IG5ldyBSZWN0YW5nbGUyRC5GbG9hdChjb3JuZXJzWzBdLCBjb3JuZXJzWzFdLCAwICwgMCk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1syXSwgY29ybmVyc1szXSk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1s0XSwgY29ybmVyc1s1XSk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1s2XSwgY29ybmVyc1s3XSk7CisKKyAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjb21wb3NlKGludCBzcmNSR0IsIGJvb2xlYW4gaXNTcmNBbHBoYVByZSwKKyAgICAgICAgICAgIGludCBkc3RSR0IsIGJvb2xlYW4gZHN0SGFzQWxwaGEsIGJvb2xlYW4gaXNEc3RBbHBoYVByZSwKKyAgICAgICAgICAgIGludCBydWxlLCBpbnQgc3JjQ29uc3RBbHBoYSl7CisKKyAgICAgICAgaW50IHNhLCBzciwgc2csIHNiLCBkYSwgZHIsIGRnLCBkYjsKKworICAgICAgICBzYSA9IChzcmNSR0IgPj4gMjQpICYgMHhmZjsKKyAgICAgICAgc3IgPSAoc3JjUkdCID4+IDE2KSAmIDB4ZmY7CisgICAgICAgIHNnID0gKHNyY1JHQiA+PiA4KSAmIDB4ZmY7CisgICAgICAgIHNiID0gc3JjUkdCICYgMHhmZjsKKworICAgICAgICBpZihpc1NyY0FscGhhUHJlKXsKKyAgICAgICAgICAgIHNhID0gbXVsTFVUW3NyY0NvbnN0QWxwaGFdW3NhXSAmIDB4ZmY7CisgICAgICAgICAgICBzciA9IG11bExVVFtzcmNDb25zdEFscGhhXVtzcl0gJiAweGZmOworICAgICAgICAgICAgc2cgPSBtdWxMVVRbc3JjQ29uc3RBbHBoYV1bc2ddICYgMHhmZjsKKyAgICAgICAgICAgIHNiID0gbXVsTFVUW3NyY0NvbnN0QWxwaGFdW3NiXSAmIDB4ZmY7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgc2EgPSBtdWxMVVRbc3JjQ29uc3RBbHBoYV1bc2FdICYgMHhmZjsKKyAgICAgICAgICAgIHNyID0gbXVsTFVUW3NhXVtzcl0gJiAweGZmOworICAgICAgICAgICAgc2cgPSBtdWxMVVRbc2FdW3NnXSAmIDB4ZmY7CisgICAgICAgICAgICBzYiA9IG11bExVVFtzYV1bc2JdICYgMHhmZjsKKyAgICAgICAgfQorCisgICAgICAgIGRhID0gKGRzdFJHQiA+PiAyNCkgJiAweGZmOworICAgICAgICBkciA9IChkc3RSR0IgPj4gMTYpICYgMHhmZjsKKyAgICAgICAgZGcgPSAoZHN0UkdCID4+IDgpICYgMHhmZjsKKyAgICAgICAgZGIgPSBkc3RSR0IgJiAweGZmOworCisgICAgICAgIGlmKCFpc0RzdEFscGhhUHJlKXsKKyAgICAgICAgICAgIGRyID0gbXVsTFVUW2RhXVtkcl0gJiAweGZmOworICAgICAgICAgICAgZGcgPSBtdWxMVVRbZGFdW2RnXSAmIDB4ZmY7CisgICAgICAgICAgICBkYiA9IG11bExVVFtkYV1bZGJdICYgMHhmZjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBGcyA9IDA7CisgICAgICAgIGludCBGZCA9IDA7CisgICAgICAgIHN3aXRjaChydWxlKXsKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5DTEVBUjoKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuRFNUOgorICAgICAgICAgICAgRmQgPSAyNTU7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLkRTVF9BVE9QOgorICAgICAgICAgICAgRnMgPSAyNTUgLSBkYTsKKyAgICAgICAgICAgIEZkID0gc2E7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLkRTVF9JTjoKKyAgICAgICAgICAgIEZkID0gc2E7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLkRTVF9PVVQ6CisgICAgICAgICAgICBGZCA9IDI1NSAtIHNhOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5EU1RfT1ZFUjoKKyAgICAgICAgICAgIEZzID0gMjU1IC0gZGE7CisgICAgICAgICAgICBGZCA9IDI1NTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuU1JDOgorICAgICAgICAgICAgRnMgPSAyNTU7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLlNSQ19BVE9QOgorICAgICAgICAgICAgRnMgPSBkYTsKKyAgICAgICAgICAgIEZkID0gMjU1IC0gc2E7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLlNSQ19JTjoKKyAgICAgICAgICAgIEZzID0gZGE7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLlNSQ19PVVQ6CisgICAgICAgICAgICBGcyA9IDI1NSAtIGRhOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5TUkNfT1ZFUjoKKyAgICAgICAgICAgIEZzID0gMjU1OworICAgICAgICAgICAgRmQgPSAyNTUgLSBzYTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuWE9SOgorICAgICAgICAgICAgRnMgPSAyNTUgLSBkYTsKKyAgICAgICAgICAgIEZkID0gMjU1IC0gc2E7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBkciA9IChtdWxMVVRbc3JdW0ZzXSAmIDB4ZmYpICsgKG11bExVVFtkcl1bRmRdICYgMHhmZik7CisgICAgICAgIGRnID0gKG11bExVVFtzZ11bRnNdICYgMHhmZikgKyAobXVsTFVUW2RnXVtGZF0gJiAweGZmKTsKKyAgICAgICAgZGIgPSAobXVsTFVUW3NiXVtGc10gJiAweGZmKSArIChtdWxMVVRbZGJdW0ZkXSAmIDB4ZmYpOworCisgICAgICAgIGRhID0gKG11bExVVFtzYV1bRnNdICYgMHhmZikgKyAobXVsTFVUW2RhXVtGZF0gJiAweGZmKTsKKworICAgICAgICBpZighaXNEc3RBbHBoYVByZSl7CisgICAgICAgICAgICBpZihkYSAhPSAyNTUpeworICAgICAgICAgICAgICAgIGRyID0gZGl2TFVUW2RhXVtkcl0gJiAweGZmOworICAgICAgICAgICAgICAgIGRnID0gZGl2TFVUW2RhXVtkZ10gJiAweGZmOworICAgICAgICAgICAgICAgIGRiID0gZGl2TFVUW2RhXVtkYl0gJiAweGZmOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmKCFkc3RIYXNBbHBoYSkgeworICAgICAgICAgICAgZGEgPSAweGZmOworICAgICAgICB9CisgICAgICAgIGRzdFJHQiA9IChkYSA8PCAyNCkgfCAoZHIgPDwgMTYpIHwgKGRnIDw8IDgpIHwgZGI7CisKKyAgICAgICAgcmV0dXJuIGRzdFJHQjsKKworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBBbGxvY2F0ZSBhbiBhcnJheSB0aGF0IGNhbiBiZSB1c2UgdG8gc3RvcmUgdGhlIHJlc3VsdCBmb3IgYSAKKyAgICAgKiBSYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzIGNhbGwuCisgICAgICogQHBhcmFtIHJhc3RlciAgUmFzdGVyICh0eXBlKSB3aGVyZSB0aGUgZ2V0RGF0YUVsZW1lbnRzIGNhbGwgd2lsbCBiZSBtYWRlLiAKKyAgICAgKiBAcGFyYW0gbmJQaXhlbHMgIEhvdyBtYW55IHBpeGVscyB0byBzdG9yZSBpbiB0aGUgYXJyYXkgYXQgbW9zdAorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBhcnJheSBvciBudWxsCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgZ2V0VHJhbnNmZXJBcnJheShSYXN0ZXIgcmFzdGVyLCBpbnQgbmJQaXhlbHMpIHsKKyAgICAgICAgaW50IHRyYW5zZmVyVHlwZSA9IHJhc3Rlci5nZXRUcmFuc2ZlclR5cGUoKTsKKyAgICAgICAgaW50IG5iRGF0YUVsZW1lbnRzID0gcmFzdGVyLmdldFNhbXBsZU1vZGVsKCkuZ2V0TnVtRGF0YUVsZW1lbnRzKCk7CisgICAgICAgIGludCBuID0gbmJEYXRhRWxlbWVudHMgKiBuYlBpeGVsczsKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtuXTsKKyAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgIHJldHVybiBuZXcgc2hvcnRbbl07CisgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgIHJldHVybiBuZXcgaW50W25dOworICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDoKKyAgICAgICAgICAgIHJldHVybiBuZXcgZmxvYXRbbl07CisgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgIHJldHVybiBuZXcgZG91YmxlW25dOworICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VTkRFRklORUQ6CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBEcmF3IGEgcGl4ZWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZG90KGludCB4LCBpbnQgeSwgaW50IGNscikgeworICAgICAgICBpZiAoY29sb3JDYWNoZSAhPSBjbHIpIHsKKyAgICAgICAgICAgIHBhaW50LnNldENvbG9yKGNscik7ICAKKyAgICAgICAgICAgIGNvbG9yQ2FjaGUgPSBjbHI7CisgICAgICAgIH0KKyAgICAgICAgY2FudmFzLmRyYXdMaW5lKHgsIHksIHggKyAxLCB5ICsgMSwgcGFpbnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZE5hdGl2ZUV2ZW50UXVldWUuamF2YSBiL2F3dC9jb20vYW5kcm9pZC9pbnRlcm5hbC9hd3QvQW5kcm9pZE5hdGl2ZUV2ZW50UXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzMwNjE0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkTmF0aXZlRXZlbnRRdWV1ZS5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVFdmVudFF1ZXVlOworCitwdWJsaWMgY2xhc3MgQW5kcm9pZE5hdGl2ZUV2ZW50UXVldWUgZXh0ZW5kcyBOYXRpdmVFdmVudFF1ZXVlIHsKKyAgICAKKyAgICBwcml2YXRlIE9iamVjdCBldmVudE1vbml0b3I7CisgICAgCisgICAgcHVibGljIEFuZHJvaWROYXRpdmVFdmVudFF1ZXVlKCkgeworICAgICAgICBzdXBlcigpOworICAgICAgICBldmVudE1vbml0b3IgPSBnZXRFdmVudE1vbml0b3IoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhd2FrZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChldmVudE1vbml0b3IpIHsKKyAgICAgICAgICAgIGV2ZW50TW9uaXRvci5ub3RpZnkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoRXZlbnQoKSB7CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihnZXRDbGFzcygpKyI6IGVtcHR5IG1ldGhvZCBjYWxsZWQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRKYXZhV2luZG93KCkgeworICAgICAgICAvLz8/P0FXVAorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZ2V0Q2xhc3MoKSsiOiBlbXB0eSBtZXRob2QgY2FsbGVkIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBlcmZvcm1MYXRlcihUYXNrIHRhc2spIHsKKyAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGdldENsYXNzKCkrIjogZW1wdHkgbWV0aG9kIGNhbGxlZCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBlcmZvcm1UYXNrKFRhc2sgdGFzaykgeworICAgICAgICAvLz8/P0FXVAorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZ2V0Q2xhc3MoKSsiOiBlbXB0eSBtZXRob2QgY2FsbGVkIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gd2FpdEV2ZW50KCkgeworICAgICAgICB3aGlsZSAoaXNFbXB0eSgpICkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChldmVudE1vbml0b3IpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBldmVudE1vbml0b3Iud2FpdCgxMDAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkV1RLLmphdmEgYi9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0FuZHJvaWRXVEsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjA5ZDExCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9BbmRyb2lkV1RLLmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGNvbS5hbmRyb2lkLmludGVybmFsLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzRGV2aWNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuQ3Vyc29yRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5HcmFwaGljc0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlRXZlbnRRdWV1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVJTTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVNb3VzZUluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlUm9ib3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuU3lzdGVtUHJvcGVydGllczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5XVEs7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuV2luZG93RmFjdG9yeTsKKworcHVibGljIGNsYXNzIEFuZHJvaWRXVEsgZXh0ZW5kcyBXVEsgeworCisgICAgcHJpdmF0ZSBBbmRyb2lkR3JhcGhpY3NGYWN0b3J5IG1BZ2Y7CisgICAgcHJpdmF0ZSBBbmRyb2lkTmF0aXZlRXZlbnRRdWV1ZSBtQW5lcTsKKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ3Vyc29yRmFjdG9yeSBnZXRDdXJzb3JGYWN0b3J5KCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBHcmFwaGljc0ZhY3RvcnkgZ2V0R3JhcGhpY3NGYWN0b3J5KCkgeworICAgICAgICBpZihtQWdmID09IG51bGwpIHsKKyAgICAgICAgICAgIG1BZ2YgPSBuZXcgQW5kcm9pZEdyYXBoaWNzRmFjdG9yeSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtQWdmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBOYXRpdmVFdmVudFF1ZXVlIGdldE5hdGl2ZUV2ZW50UXVldWUoKSB7CisgICAgICAgIGlmKG1BbmVxID09IG51bGwpIHsKKyAgICAgICAgICAgIG1BbmVxID0gbmV3IEFuZHJvaWROYXRpdmVFdmVudFF1ZXVlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1BbmVxOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBOYXRpdmVJTSBnZXROYXRpdmVJTSgpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTmF0aXZlTW91c2VJbmZvIGdldE5hdGl2ZU1vdXNlSW5mbygpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTmF0aXZlUm9ib3QgZ2V0TmF0aXZlUm9ib3QoR3JhcGhpY3NEZXZpY2Ugc2NyZWVuKSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN5c3RlbVByb3BlcnRpZXMgZ2V0U3lzdGVtUHJvcGVydGllcygpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgV2luZG93RmFjdG9yeSBnZXRXaW5kb3dGYWN0b3J5KCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9Bd3RGYWN0b3J5LmphdmEgYi9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0F3dEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTY2N2IyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9Bd3RGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGNvbS5hbmRyb2lkLmludGVybmFsLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzMkQ7CitpbXBvcnQgamF2YS5hd3QuVG9vbGtpdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLkdyYXBoaWNzRmFjdG9yeTsKKworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuQ2FudmFzOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUGFpbnQ7CisKK3B1YmxpYyBjbGFzcyBBd3RGYWN0b3J5IHsKKyAgICAKKyAgICBwcml2YXRlIHN0YXRpYyBHcmFwaGljc0ZhY3RvcnkgZ2Y7CisgICAgCisgICAgLyoqCisgICAgICogVXNlIHRoaXMgbWV0aG9kIHRvIGdldCBhY2NlcyB0byBBV1QgZHJhd2luZyBwcmltaXRpdmVzIGFuZCB0bworICAgICAqIHJlbmRlciBpbnRvIHRoZSBzdXJmYWNlIGFyZWEgb2YgYSBBbmRyb2lkIHdpZGdldC4gT3JpZ2luIGFuZCAKKyAgICAgKiBjbGlwIG9mIHRoZSByZXR1cm5lZCBncmFwaGljcyBvYmplY3QgYXJlIHRoZSBzYW1lIGFzIGluIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgQW5kcm9pZCB3aWRnZXQuIAorICAgICAqIAorICAgICAqIEBwYXJhbSBjIENhbnZhcyBvZiB0aGUgYW5kcm9pZCB3aWRnZXQgdG8gZHJhdyBpbnRvCisgICAgICogQHBhcmFtIHAgVGhlIGRlZmF1bHQgZHJhd2luZyBwYXJhbWV0ZXJzIHN1Y2ggYXMgZm9udCwgCisgICAgICogc3Ryb2tlLCBmb3JlZ3JvdW5kIGFuZCBiYWNrZ3JvdW5kIGNvbG9ycywgZXRjLgorICAgICAqIEByZXR1cm4gVGhlIEFXVCBHcmFwaGljcyBvYmplY3QgdGhhdCBtYWtlcyBhbGwgQVdUIAorICAgICAqIGRyYXdpbmcgcHJpbWl0aXZlcyBhdmFpbGFibGUgaW4gdGhlIGFuZHJvaW5kIHdvcmxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgR3JhcGhpY3MyRCBnZXRBd3RHcmFwaGljcyhDYW52YXMgYywgUGFpbnQgcCkgeworICAgICAgICAvLyBBV1Q/PyBUT0RPOiB0ZXN0IGl0IQorICAgICAgICBpZiAobnVsbCA9PSBnZikgeworICAgICAgICAgICAgVG9vbGtpdCB0ayA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICAgICAgICAgIGdmID0gdGsuZ2V0R3JhcGhpY3NGYWN0b3J5KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdmLmdldEdyYXBoaWNzMkQoYywgcCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvY29tL2FuZHJvaWQvaW50ZXJuYWwvYXd0L0ltYWdlT3V0cHV0U3RyZWFtV3JhcHBlci5qYXZhIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9JbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MjE4NWZkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2NvbS9hbmRyb2lkL2ludGVybmFsL2F3dC9JbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgY29tLmFuZHJvaWQuaW50ZXJuYWwuYXd0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgSW1hZ2VPdXRwdXRTdHJlYW1XcmFwcGVyIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKwkKKwlwcm90ZWN0ZWQgSW1hZ2VPdXRwdXRTdHJlYW0gbUlvczsKKwkKKwlwcml2YXRlIGJ5dGVbXSBtQnVmZjsKKwkKKwlwdWJsaWMgSW1hZ2VPdXRwdXRTdHJlYW1XcmFwcGVyKEltYWdlT3V0cHV0U3RyZWFtIGlvcykgeworCQlpZiAobnVsbCA9PSBpb3MpIHsKKwkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkltYWdlT3V0cHV0U3RyZWFtIG11c3Qgbm90IGJlIG51bGwiKTsKKwkJfQorCQl0aGlzLm1Jb3MgPSBpb3M7CisJCXRoaXMubUJ1ZmYgPSBuZXcgYnl0ZVsxXTsKKwl9CisKKwlwdWJsaWMgSW1hZ2VPdXRwdXRTdHJlYW0gZ2V0SW1hZ2VPdXRwdXRTdHJlYW0oKSB7CisJCXJldHVybiBtSW9zOworCX0KKwkKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJbUJ1ZmZbMF0gPSAoYnl0ZSlvbmVCeXRlOworCQltSW9zLndyaXRlKG1CdWZmLCAwLCAxKTsKKwl9CisKKwlwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJbUlvcy53cml0ZShiLCAwLCBiLmxlbmd0aCk7CisJfQorCQorCXB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQltSW9zLndyaXRlKGIsIG9mZiwgbGVuKTsKKwl9CisJCisJcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQltSW9zLmZsdXNoKCk7CisJfQorCQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAJaWYgKG1Jb3MgPT0gbnVsbCkgeworICAgIAkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gYWxyZWFkeSBjbG9zZWQiKTsKKyAgICAJfQorICAgICAgICBtSW9zID0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQVdURXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9BV1RFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4ZGM4M2EKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQVdURXZlbnQuamF2YQpAQCAtMCwwICsxLDY4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2LCBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50T2JqZWN0OworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC4qOworCisvKioKKyAqIFRoZSBhYnN0cmFjdCBjbGFzcyBBV1RFdmVudCBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIEFXVCBldmVudHMuIFRoaXMgY2xhc3MKKyAqIGFuZCBpdHMgc3ViY2xhc3NlcyBzdXBlcnNlZGUgdGhlIG9yaWdpbmFsIGphdmEuYXd0LkV2ZW50IGNsYXNzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFXVEV2ZW50IGV4dGVuZHMgRXZlbnRPYmplY3QgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE4MjUzMTQ3NzkxNjA0MDk0MDVMOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENPTVBPTkVOVF9FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhCisgICAgICogY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBDT01QT05FTlRfRVZFTlRfTUFTSyA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ09OVEFJTkVSX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIGEKKyAgICAgKiBjb250YWluZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIENPTlRBSU5FUl9FVkVOVF9NQVNLID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGT0NVU19FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byB0aGUgZm9jdXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEZPQ1VTX0VWRU5UX01BU0sgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgS0VZX0VWRU5UX01BU0sgPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIHRoZSBtb3VzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgTU9VU0VfRVZFTlRfTUFTSyA9IDE2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX01PVElPTl9FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhCisgICAgICogbW91c2UgbW90aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBNT1VTRV9NT1RJT05fRVZFTlRfTUFTSyA9IDMyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRPV19FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhIHdpbmRvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgV0lORE9XX0VWRU5UX01BU0sgPSA2NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBBQ1RJT05fRVZFTlRfTUFTSyBpbmRpY2F0ZXMgdGhlIGV2ZW50IHJlbGF0ZXMgdG8gYW4gYWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBBQ1RJT05fRVZFTlRfTUFTSyA9IDEyODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBBREpVU1RNRU5UX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIGFuCisgICAgICogYWRqdXN0bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgQURKVVNUTUVOVF9FVkVOVF9NQVNLID0gMjU2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IElURU1fRVZFTlRfTUFTSyBpbmRpY2F0ZXMgdGhlIGV2ZW50IHJlbGF0ZXMgdG8gYW4gaXRlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgSVRFTV9FVkVOVF9NQVNLID0gNTEyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRFWFRfRVZFTlRfTUFTSyBpbmRpY2F0ZXMgdGhlIGV2ZW50IHJlbGF0ZXMgdG8gdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgVEVYVF9FVkVOVF9NQVNLID0gMTAyNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJTlBVVF9NRVRIT0RfRVZFTlRfTUFTSyBpbmRpY2F0ZXMgdGhlIGV2ZW50IHJlbGF0ZXMgdG8gYW4KKyAgICAgKiBpbnB1dCBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIElOUFVUX01FVEhPRF9FVkVOVF9NQVNLID0gMjA0ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBQQUlOVF9FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhIHBhaW50CisgICAgICogbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBQQUlOVF9FVkVOVF9NQVNLID0gODE5MjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJTlZPQ0FUSU9OX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIGEKKyAgICAgKiBtZXRob2QgaW52b2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgSU5WT0NBVElPTl9FVkVOVF9NQVNLID0gMTYzODQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSElFUkFSQ0hZX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIGEKKyAgICAgKiBoaWVyYXJjaHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEhJRVJBUkNIWV9FVkVOVF9NQVNLID0gMzI3Njg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSElFUkFSQ0hZX0JPVU5EU19FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0bworICAgICAqIGhpZXJhcmNoeSBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEhJRVJBUkNIWV9CT1VORFNfRVZFTlRfTUFTSyA9IDY1NTM2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX1dIRUVMX0VWRU5UX01BU0sgaW5kaWNhdGVzIHRoZSBldmVudCByZWxhdGVzIHRvIHRoZQorICAgICAqIG1vdXNlIHdoZWVsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBNT1VTRV9XSEVFTF9FVkVOVF9NQVNLID0gMTMxMDcyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRPV19TVEFURV9FVkVOVF9NQVNLIGluZGljYXRlcyB0aGUgZXZlbnQgcmVsYXRlcyB0byBhCisgICAgICogd2luZG93IHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBXSU5ET1dfU1RBVEVfRVZFTlRfTUFTSyA9IDI2MjE0NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXSU5ET1dfRk9DVVNfRVZFTlRfTUFTSyBpbmRpY2F0ZXMgdGhlIGV2ZW50IHJlbGF0ZXMgdG8gYQorICAgICAqIHdpbmRvdyBmb2N1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgV0lORE9XX0ZPQ1VTX0VWRU5UX01BU0sgPSA1MjQyODg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVTRVJWRURfSURfTUFYIGluZGljYXRlcyB0aGUgbWF4aW11bSB2YWx1ZSBmb3IgcmVzZXJ2ZWQgQVdUCisgICAgICogZXZlbnQgSURzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFU0VSVkVEX0lEX01BWCA9IDE5OTk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgZXZlbnRzTWFwLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2h0YWJsZTxJbnRlZ2VyLCBFdmVudERlc2NyaXB0b3I+IGV2ZW50c01hcCA9IG5ldyBIYXNodGFibGU8SW50ZWdlciwgRXZlbnREZXNjcmlwdG9yPigpOworCisgICAgLyoqCisgICAgICogVGhlIGNvbnZlcnRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBFdmVudENvbnZlcnRlciBjb252ZXJ0ZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSUQgb2YgdGhlIGV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgaWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3VtZWQgaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBldmVudCBpcyBzZW50IGJhY2sgZG93biB0byB0aGUKKyAgICAgKiBwZWVyIG9uY2UgdGhlIHNvdXJjZSBoYXMgcHJvY2Vzc2VkIGl0IChmYWxzZSBtZWFucyBpdCdzIHNlbnQgdG8gdGhlIHBlZXIsCisgICAgICogdHJ1ZSBtZWFucyBpdCdzIG5vdCkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gY29uc3VtZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGlzcGF0Y2hlZCBieSBrZm0uCisgICAgICovCisgICAgYm9vbGVhbiBkaXNwYXRjaGVkQnlLRk07CisKKyAgICAvKioKKyAgICAgKiBUaGUgaXMgcG9zdGVkLgorICAgICAqLworICAgIHRyYW5zaWVudCBib29sZWFuIGlzUG9zdGVkOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihLZXlFdmVudC5LRVlfVFlQRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKEtFWV9FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgIEtleUxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoS2V5RXZlbnQuS0VZX1BSRVNTRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKEtFWV9FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgIEtleUxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoS2V5RXZlbnQuS0VZX1JFTEVBU0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcihLRVlfRVZFTlRfTUFTSywKKyAgICAgICAgICAgICAgICBLZXlMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKE1vdXNlRXZlbnQuTU9VU0VfQ0xJQ0tFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoTU9VU0VfRVZFTlRfTUFTSywKKyAgICAgICAgICAgICAgICBNb3VzZUxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoTW91c2VFdmVudC5NT1VTRV9QUkVTU0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcihNT1VTRV9FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgIE1vdXNlTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihNb3VzZUV2ZW50Lk1PVVNFX1JFTEVBU0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcihNT1VTRV9FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgIE1vdXNlTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihNb3VzZUV2ZW50Lk1PVVNFX01PVkVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBNT1VTRV9NT1RJT05fRVZFTlRfTUFTSywgTW91c2VNb3Rpb25MaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKE1vdXNlRXZlbnQuTU9VU0VfRU5URVJFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoTU9VU0VfRVZFTlRfTUFTSywKKyAgICAgICAgICAgICAgICBNb3VzZUxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoTW91c2VFdmVudC5NT1VTRV9FWElURUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKE1PVVNFX0VWRU5UX01BU0ssCisgICAgICAgICAgICAgICAgTW91c2VMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKE1vdXNlRXZlbnQuTU9VU0VfRFJBR0dFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgTU9VU0VfTU9USU9OX0VWRU5UX01BU0ssIE1vdXNlTW90aW9uTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihNb3VzZUV2ZW50Lk1PVVNFX1dIRUVMKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBNT1VTRV9XSEVFTF9FVkVOVF9NQVNLLCBNb3VzZVdoZWVsTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihDb21wb25lbnRFdmVudC5DT01QT05FTlRfTU9WRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIENPTVBPTkVOVF9FVkVOVF9NQVNLLCBDb21wb25lbnRMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9SRVNJWkVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBDT01QT05FTlRfRVZFTlRfTUFTSywgQ29tcG9uZW50TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihDb21wb25lbnRFdmVudC5DT01QT05FTlRfU0hPV04pLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIENPTVBPTkVOVF9FVkVOVF9NQVNLLCBDb21wb25lbnRMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9ISURERU4pLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIENPTVBPTkVOVF9FVkVOVF9NQVNLLCBDb21wb25lbnRMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKEZvY3VzRXZlbnQuRk9DVVNfR0FJTkVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcihGT0NVU19FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgIEZvY3VzTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihGb2N1c0V2ZW50LkZPQ1VTX0xPU1QpLCBuZXcgRXZlbnREZXNjcmlwdG9yKEZPQ1VTX0VWRU5UX01BU0ssCisgICAgICAgICAgICAgICAgRm9jdXNMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFBhaW50RXZlbnQuUEFJTlQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKFBBSU5UX0VWRU5UX01BU0ssIG51bGwpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihQYWludEV2ZW50LlVQREFURSksIG5ldyBFdmVudERlc2NyaXB0b3IoUEFJTlRfRVZFTlRfTUFTSywgbnVsbCkpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19PUEVORUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIFdJTkRPV19FVkVOVF9NQVNLLCBXaW5kb3dMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19DTE9TSU5HKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfRVZFTlRfTUFTSywgV2luZG93TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihXaW5kb3dFdmVudC5XSU5ET1dfQ0xPU0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfRVZFTlRfTUFTSywgV2luZG93TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihXaW5kb3dFdmVudC5XSU5ET1dfREVJQ09OSUZJRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIFdJTkRPV19FVkVOVF9NQVNLLCBXaW5kb3dMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19JQ09OSUZJRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIFdJTkRPV19FVkVOVF9NQVNLLCBXaW5kb3dMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19TVEFURV9DSEFOR0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfU1RBVEVfRVZFTlRfTUFTSywgV2luZG93U3RhdGVMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19MT1NUX0ZPQ1VTKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfRk9DVVNfRVZFTlRfTUFTSywgV2luZG93Rm9jdXNMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFdpbmRvd0V2ZW50LldJTkRPV19HQUlORURfRk9DVVMpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIFdJTkRPV19GT0NVU19FVkVOVF9NQVNLLCBXaW5kb3dGb2N1c0xpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoV2luZG93RXZlbnQuV0lORE9XX0RFQUNUSVZBVEVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfRVZFTlRfTUFTSywgV2luZG93TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihXaW5kb3dFdmVudC5XSU5ET1dfQUNUSVZBVEVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBXSU5ET1dfRVZFTlRfTUFTSywgV2luZG93TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihIaWVyYXJjaHlFdmVudC5ISUVSQVJDSFlfQ0hBTkdFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgSElFUkFSQ0hZX0VWRU5UX01BU0ssIEhpZXJhcmNoeUxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoSGllcmFyY2h5RXZlbnQuQU5DRVNUT1JfTU9WRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIEhJRVJBUkNIWV9CT1VORFNfRVZFTlRfTUFTSywgSGllcmFyY2h5Qm91bmRzTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihIaWVyYXJjaHlFdmVudC5BTkNFU1RPUl9SRVNJWkVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBISUVSQVJDSFlfQk9VTkRTX0VWRU5UX01BU0ssIEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoQ29udGFpbmVyRXZlbnQuQ09NUE9ORU5UX0FEREVEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBDT05UQUlORVJfRVZFTlRfTUFTSywgQ29udGFpbmVyTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihDb250YWluZXJFdmVudC5DT01QT05FTlRfUkVNT1ZFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgQ09OVEFJTkVSX0VWRU5UX01BU0ssIENvbnRhaW5lckxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoSW5wdXRNZXRob2RFdmVudC5JTlBVVF9NRVRIT0RfVEVYVF9DSEFOR0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBJTlBVVF9NRVRIT0RfRVZFTlRfTUFTSywgSW5wdXRNZXRob2RMaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKElucHV0TWV0aG9kRXZlbnQuQ0FSRVRfUE9TSVRJT05fQ0hBTkdFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgSU5QVVRfTUVUSE9EX0VWRU5UX01BU0ssIElucHV0TWV0aG9kTGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihJbnZvY2F0aW9uRXZlbnQuSU5WT0NBVElPTl9ERUZBVUxUKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBJTlZPQ0FUSU9OX0VWRU5UX01BU0ssIG51bGwpKTsKKyAgICAgICAgZXZlbnRzTWFwLnB1dChuZXcgSW50ZWdlcihJdGVtRXZlbnQuSVRFTV9TVEFURV9DSEFOR0VEKSwgbmV3IEV2ZW50RGVzY3JpcHRvcigKKyAgICAgICAgICAgICAgICBJVEVNX0VWRU5UX01BU0ssIEl0ZW1MaXN0ZW5lci5jbGFzcykpOworICAgICAgICBldmVudHNNYXAucHV0KG5ldyBJbnRlZ2VyKFRleHRFdmVudC5URVhUX1ZBTFVFX0NIQU5HRUQpLCBuZXcgRXZlbnREZXNjcmlwdG9yKAorICAgICAgICAgICAgICAgIFRFWFRfRVZFTlRfTUFTSywgVGV4dExpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoQWN0aW9uRXZlbnQuQUNUSU9OX1BFUkZPUk1FRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgQUNUSU9OX0VWRU5UX01BU0ssIEFjdGlvbkxpc3RlbmVyLmNsYXNzKSk7CisgICAgICAgIGV2ZW50c01hcC5wdXQobmV3IEludGVnZXIoQWRqdXN0bWVudEV2ZW50LkFESlVTVE1FTlRfVkFMVUVfQ0hBTkdFRCksIG5ldyBFdmVudERlc2NyaXB0b3IoCisgICAgICAgICAgICAgICAgQURKVVNUTUVOVF9FVkVOVF9NQVNLLCBBZGp1c3RtZW50TGlzdGVuZXIuY2xhc3MpKTsKKyAgICAgICAgY29udmVydGVyID0gbmV3IEV2ZW50Q29udmVydGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFXVCBldmVudCBmcm9tIHRoZSBzcGVjaWZpZWQgRXZlbnQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgdGhlIEV2ZW50IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVdURXZlbnQoRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgdGhpcyhldmVudC50YXJnZXQsIGV2ZW50LmlkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQVdUIGV2ZW50IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBPYmplY3QuCisgICAgICogQHBhcmFtIGlkCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQncyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBBV1RFdmVudChPYmplY3Qgc291cmNlLCBpbnQgaWQpIHsKKyAgICAgICAgc3VwZXIoc291cmNlKTsKKyAgICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgICBjb25zdW1lZCA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGV2ZW50J3MgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBldmVudCB0eXBlIElELgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SUQoKSB7CisgICAgICAgIHJldHVybiBpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbmV3IHNvdXJjZSBmb3IgdGhlIEFXVEV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBuZXdTb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgc291cmNlIE9iamVjdCBmb3IgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZShPYmplY3QgbmV3U291cmNlKSB7CisgICAgICAgIHNvdXJjZSA9IG5ld1NvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBBV1RFdmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3Igd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5CisgICAgICAgICAqIHRoZSBmb2xsb3dpbmcgY29kZTogQVdURXZlbnQgZXZlbnQgPSBuZXcgQVdURXZlbnQobmV3IENvbXBvbmVudCgpe30sCisgICAgICAgICAqIDEpe307IFN5c3RlbS5vdXQucHJpbnRsbihldmVudCk7CisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgbmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIENvbXBvbmVudCAmJiAoc291cmNlICE9IG51bGwpKSB7CisgICAgICAgICAgICBDb21wb25lbnQgY29tcCA9IChDb21wb25lbnQpZ2V0U291cmNlKCk7CisgICAgICAgICAgICBuYW1lID0gY29tcC5nZXROYW1lKCk7CisgICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlsiICsgcGFyYW1TdHJpbmcoKSArICJdIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICArICIgb24gIiArIChuYW1lLmxlbmd0aCgpID4gMCA/IG5hbWUgOiBzb3VyY2UpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFXVEV2ZW50IHN0YXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFXVEV2ZW50IHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8vIG5vdGhpbmcgdG8gaW1wbGVtZW50OiBhbGwgZXZlbnQgdHlwZXMgbXVzdCBvdmVycmlkZSB0aGlzIG1ldGhvZAorICAgICAgICByZXR1cm4gIiI7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhpcyBBV1RFdmVudCBoYXMgYmVlbiBjb25zdW1lZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgQVdURXZlbnQgaGFzIGJlZW4gY29uc3VtZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0NvbnN1bWVkKCkgeworICAgICAgICByZXR1cm4gY29uc3VtZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3VtZXMgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGNvbnN1bWUoKSB7CisgICAgICAgIGNvbnN1bWVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IEFXVEV2ZW50IG9iamVjdCB0byBhIGNvcnJlc3BvbmRpbmcgKGRlcHJlY2F0ZWQpIEV2ZW50IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIG5ldyBFdmVudCBvYmplY3Qgd2hpY2ggaXMgYSBjb252ZXJ0ZWQgQVdURXZlbnQgb2JqZWN0IG9yIG51bGwgaWYKKyAgICAgKiAgICAgICAgIHRoZSBjb252ZXJzaW9uIGlzIG5vdCBwb3NzaWJsZQorICAgICAqLworICAgIEV2ZW50IGdldEV2ZW50KCkgeworCisgICAgICAgIGlmIChpZCA9PSBBY3Rpb25FdmVudC5BQ1RJT05fUEVSRk9STUVEKSB7CisgICAgICAgICAgICBBY3Rpb25FdmVudCBhZSA9IChBY3Rpb25FdmVudCl0aGlzOworICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0QWN0aW9uRXZlbnQoYWUpOworCisgICAgICAgIH0gZWxzZSBpZiAoaWQgPT0gQWRqdXN0bWVudEV2ZW50LkFESlVTVE1FTlRfVkFMVUVfQ0hBTkdFRCkgeworICAgICAgICAgICAgQWRqdXN0bWVudEV2ZW50IGFlID0gKEFkanVzdG1lbnRFdmVudCl0aGlzOworICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0QWRqdXN0bWVudEV2ZW50KGFlKTsKKworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvLyB9IGVsc2UgaWYgKGlkID09IENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9NT1ZFRAorICAgICAgICAgICAgLy8gJiYgc291cmNlIGluc3RhbmNlb2YgV2luZG93KSB7CisgICAgICAgICAgICAvLyAvL3RoZSBvbmx5IHR5cGUgb2YgQ29tcG9uZW50IGV2ZW50cyBpcyBDT01QT05FTlRfTU9WRUQgb24gd2luZG93CisgICAgICAgICAgICAvLyBDb21wb25lbnRFdmVudCBjZSA9IChDb21wb25lbnRFdmVudCkgdGhpczsKKyAgICAgICAgICAgIC8vIHJldHVybiBjb252ZXJ0ZXIuY29udmVydENvbXBvbmVudEV2ZW50KGNlKTsKKworICAgICAgICB9IGVsc2UgaWYgKGlkID49IEZvY3VzRXZlbnQuRk9DVVNfRklSU1QgJiYgaWQgPD0gRm9jdXNFdmVudC5GT0NVU19MQVNUKSB7CisgICAgICAgICAgICAvLyBub3RoaW5nIHRvIGNvbnZlcnQKKworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvLyB9IGVsc2UgaWYgKGlkID09IEl0ZW1FdmVudC5JVEVNX1NUQVRFX0NIQU5HRUQpIHsKKyAgICAgICAgICAgIC8vIEl0ZW1FdmVudCBpZSA9IChJdGVtRXZlbnQpIHRoaXM7CisgICAgICAgICAgICAvLyByZXR1cm4gY29udmVydGVyLmNvbnZlcnRJdGVtRXZlbnQoaWUpOworCisgICAgICAgIH0gZWxzZSBpZiAoaWQgPT0gS2V5RXZlbnQuS0VZX1BSRVNTRUQgfHwgaWQgPT0gS2V5RXZlbnQuS0VZX1JFTEVBU0VEKSB7CisgICAgICAgICAgICBLZXlFdmVudCBrZSA9IChLZXlFdmVudCl0aGlzOworICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0S2V5RXZlbnQoa2UpOworICAgICAgICB9IGVsc2UgaWYgKGlkID49IE1vdXNlRXZlbnQuTU9VU0VfRklSU1QgJiYgaWQgPD0gTW91c2VFdmVudC5NT1VTRV9MQVNUKSB7CisgICAgICAgICAgICBNb3VzZUV2ZW50IG1lID0gKE1vdXNlRXZlbnQpdGhpczsKKyAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydE1vdXNlRXZlbnQobWUpOworICAgICAgICB9IGVsc2UgaWYgKGlkID09IFdpbmRvd0V2ZW50LldJTkRPV19DTE9TSU5HIHx8IGlkID09IFdpbmRvd0V2ZW50LldJTkRPV19JQ09OSUZJRUQKKyAgICAgICAgICAgICAgICB8fCBpZCA9PSBXaW5kb3dFdmVudC5XSU5ET1dfREVJQ09OSUZJRUQpIHsKKyAgICAgICAgICAgIC8vIG5vdGhpbmcgdG8gY29udmVydAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBFdmVudChzb3VyY2UsIGlkLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgRXZlbnREZXNjcmlwdG9yLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBFdmVudERlc2NyaXB0b3IgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZXZlbnQgbWFzay4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGxvbmcgZXZlbnRNYXNrOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbGlzdGVuZXIgdHlwZS4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiBsaXN0ZW5lclR5cGU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCBkZXNjcmlwdG9yLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGV2ZW50TWFzaworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBldmVudCBtYXNrLgorICAgICAgICAgKiBAcGFyYW0gbGlzdGVuZXJUeXBlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyIHR5cGUuCisgICAgICAgICAqLworICAgICAgICBFdmVudERlc2NyaXB0b3IobG9uZyBldmVudE1hc2ssIENsYXNzPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiBsaXN0ZW5lclR5cGUpIHsKKyAgICAgICAgICAgIHRoaXMuZXZlbnRNYXNrID0gZXZlbnRNYXNrOworICAgICAgICAgICAgdGhpcy5saXN0ZW5lclR5cGUgPSBsaXN0ZW5lclR5cGU7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjbGFzcyBFdmVudFR5cGVMb29rdXAuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEV2ZW50VHlwZUxvb2t1cCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBsYXN0IGV2ZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBBV1RFdmVudCBsYXN0RXZlbnQgPSBudWxsOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbGFzdCBldmVudCBkZXNjcmlwdG9yLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBFdmVudERlc2NyaXB0b3IgbGFzdEV2ZW50RGVzY3JpcHRvciA9IG51bGw7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIGV2ZW50IGRlc2NyaXB0b3IuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZXZlbnQuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGV2ZW50IGRlc2NyaXB0b3IuCisgICAgICAgICAqLworICAgICAgICBFdmVudERlc2NyaXB0b3IgZ2V0RXZlbnREZXNjcmlwdG9yKEFXVEV2ZW50IGV2ZW50KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZXZlbnQgIT0gbGFzdEV2ZW50KSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3RFdmVudCA9IGV2ZW50OworICAgICAgICAgICAgICAgICAgICBsYXN0RXZlbnREZXNjcmlwdG9yID0gZXZlbnRzTWFwLmdldChuZXcgSW50ZWdlcihldmVudC5pZCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldHVybiBsYXN0RXZlbnREZXNjcmlwdG9yOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIGV2ZW50IG1hc2suCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZXZlbnQuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGV2ZW50IG1hc2suCisgICAgICAgICAqLworICAgICAgICBsb25nIGdldEV2ZW50TWFzayhBV1RFdmVudCBldmVudCkgeworICAgICAgICAgICAgZmluYWwgRXZlbnREZXNjcmlwdG9yIGVkID0gZ2V0RXZlbnREZXNjcmlwdG9yKGV2ZW50KTsKKyAgICAgICAgICAgIHJldHVybiBlZCA9PSBudWxsID8gLTEgOiBlZC5ldmVudE1hc2s7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgRXZlbnRDb252ZXJ0ZXIuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEV2ZW50Q29udmVydGVyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNvbnN0YW50IE9MRF9NT0RfTUFTSy4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgT0xEX01PRF9NQVNLID0gRXZlbnQuQUxUX01BU0sgfCBFdmVudC5DVFJMX01BU0sgfCBFdmVudC5NRVRBX01BU0sKKyAgICAgICAgICAgICAgICB8IEV2ZW50LlNISUZUX01BU0s7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnZlcnQgYWN0aW9uIGV2ZW50LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGFlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGFlLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBldmVudC4KKyAgICAgICAgICovCisgICAgICAgIEV2ZW50IGNvbnZlcnRBY3Rpb25FdmVudChBY3Rpb25FdmVudCBhZSkgeworICAgICAgICAgICAgRXZlbnQgZXZ0ID0gbmV3IEV2ZW50KGFlLmdldFNvdXJjZSgpLCBhZS5nZXRJRCgpLCBhZS5nZXRBY3Rpb25Db21tYW5kKCkpOworICAgICAgICAgICAgZXZ0LndoZW4gPSBhZS5nZXRXaGVuKCk7CisgICAgICAgICAgICBldnQubW9kaWZpZXJzID0gYWUuZ2V0TW9kaWZpZXJzKCkgJiBPTERfTU9EX01BU0s7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBpZiAoc291cmNlIGluc3RhbmNlb2YgQnV0dG9uKSB7IGFyZyA9ICgoQnV0dG9uKQorICAgICAgICAgICAgICogc291cmNlKS5nZXRMYWJlbCgpOyB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIENoZWNrYm94KSB7IGFyZworICAgICAgICAgICAgICogPSBuZXcgQm9vbGVhbigoKENoZWNrYm94KSBzb3VyY2UpLmdldFN0YXRlKCkpOyB9IGVsc2UgaWYgKHNvdXJjZQorICAgICAgICAgICAgICogaW5zdGFuY2VvZiBDaGVja2JveE1lbnVJdGVtKSB7IGFyZyA9ICgoQ2hlY2tib3hNZW51SXRlbSkKKyAgICAgICAgICAgICAqIHNvdXJjZSkuZ2V0TGFiZWwoKTsgfSBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBDaG9pY2UpIHsgYXJnID0KKyAgICAgICAgICAgICAqICgoQ2hvaWNlKSBzb3VyY2UpLmdldFNlbGVjdGVkSXRlbSgpOyB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mCisgICAgICAgICAgICAgKiBMaXN0KSB7IGFyZyA9ICgoTGlzdCkgc291cmNlKS5nZXRTZWxlY3RlZEl0ZW0oKTsgfSBlbHNlIGlmCisgICAgICAgICAgICAgKiAoc291cmNlIGluc3RhbmNlb2YgTWVudUl0ZW0pIHsgYXJnID0gKChNZW51SXRlbSkKKyAgICAgICAgICAgICAqIHNvdXJjZSkuZ2V0TGFiZWwoKTsgfSBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBUZXh0RmllbGQpIHsgYXJnCisgICAgICAgICAgICAgKiA9ICgoVGV4dEZpZWxkKSBzb3VyY2UpLmdldFRleHQoKTsgfQorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gZXZ0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnZlcnQgYWRqdXN0bWVudCBldmVudC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBhZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBhZS4KKyAgICAgICAgICogQHJldHVybiB0aGUgZXZlbnQuCisgICAgICAgICAqLworICAgICAgICBFdmVudCBjb252ZXJ0QWRqdXN0bWVudEV2ZW50KEFkanVzdG1lbnRFdmVudCBhZSkgeworICAgICAgICAgICAgLy8gVE9ETzogRXZlbnQuU0NST0xMX0JFR0lOL1NDUk9MTF9FTkQKKyAgICAgICAgICAgIHJldHVybiBuZXcgRXZlbnQoYWUuc291cmNlLCBhZS5pZCArIGFlLmdldEFkanVzdG1lbnRUeXBlKCkgLSAxLCBuZXcgSW50ZWdlcihhZQorICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsdWUoKSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnZlcnQgY29tcG9uZW50IGV2ZW50LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGNlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGNlLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBldmVudC4KKyAgICAgICAgICovCisgICAgICAgIEV2ZW50IGNvbnZlcnRDb21wb25lbnRFdmVudChDb21wb25lbnRFdmVudCBjZSkgeworICAgICAgICAgICAgQ29tcG9uZW50IGNvbXAgPSBjZS5nZXRDb21wb25lbnQoKTsKKyAgICAgICAgICAgIEV2ZW50IGV2dCA9IG5ldyBFdmVudChjb21wLCBFdmVudC5XSU5ET1dfTU9WRUQsIG51bGwpOworICAgICAgICAgICAgZXZ0LnggPSBjb21wLmdldFgoKTsKKyAgICAgICAgICAgIGV2dC55ID0gY29tcC5nZXRZKCk7CisgICAgICAgICAgICByZXR1cm4gZXZ0OworICAgICAgICB9CisKKyAgICAgICAgLy8gPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgICAqIEV2ZW50IGNvbnZlcnRJdGVtRXZlbnQoSXRlbUV2ZW50IGllKSB7IGludCBvbGRJZCA9IGllLmlkICsKKyAgICAgICAgICogaWUuZ2V0U3RhdGVDaGFuZ2UoKSAtIDE7IE9iamVjdCBzb3VyY2UgPSBpZS5zb3VyY2U7IGludCBpZHggPSAtMTsgaWYKKyAgICAgICAgICogKHNvdXJjZSBpbnN0YW5jZW9mIExpc3QpIHsgTGlzdCBsaXN0ID0gKExpc3QpIHNvdXJjZTsgaWR4ID0KKyAgICAgICAgICogbGlzdC5nZXRTZWxlY3RlZEluZGV4KCk7IH0gZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgQ2hvaWNlKSB7CisgICAgICAgICAqIENob2ljZSBjaG9pY2UgPSAoQ2hvaWNlKSBzb3VyY2U7IGlkeCA9IGNob2ljZS5nZXRTZWxlY3RlZEluZGV4KCk7IH0KKyAgICAgICAgICogT2JqZWN0IGFyZyA9IGlkeCA+PSAwID8gbmV3IEludGVnZXIoaWR4KSA6IG51bGw7IHJldHVybiBuZXcKKyAgICAgICAgICogRXZlbnQoc291cmNlLCBvbGRJZCwgYXJnKTsgfQorICAgICAgICAgKi8KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29udmVydCBrZXkgZXZlbnQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0ga2UKKyAgICAgICAgICogICAgICAgICAgICB0aGUga2UuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGV2ZW50LgorICAgICAgICAgKi8KKyAgICAgICAgRXZlbnQgY29udmVydEtleUV2ZW50KEtleUV2ZW50IGtlKSB7CisgICAgICAgICAgICBpbnQgb2xkSWQgPSBrZS5pZDsKKyAgICAgICAgICAgIC8vIGxlYXZlIG9ubHkgb2xkIEV2ZW50J3MgbW9kaWZpZXJzCisKKyAgICAgICAgICAgIGludCBtb2QgPSBrZS5nZXRNb2RpZmllcnMoKSAmIE9MRF9NT0RfTUFTSzsKKyAgICAgICAgICAgIENvbXBvbmVudCBjb21wID0ga2UuZ2V0Q29tcG9uZW50KCk7CisgICAgICAgICAgICBjaGFyIGtleUNoYXIgPSBrZS5nZXRLZXlDaGFyKCk7CisgICAgICAgICAgICBpbnQga2V5Q29kZSA9IGtlLmdldEtleUNvZGUoKTsKKyAgICAgICAgICAgIGludCBrZXkgPSBjb252ZXJ0S2V5KGtleUNoYXIsIGtleUNvZGUpOworICAgICAgICAgICAgaWYgKGtleSA+PSBFdmVudC5IT01FICYmIGtleSA8PSBFdmVudC5JTlNFUlQpIHsKKyAgICAgICAgICAgICAgICBvbGRJZCArPSAyOyAvLyBub24tQVNDSUkga2V5IC0+IGFjdGlvbiBrZXkKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgRXZlbnQoY29tcCwga2UuZ2V0V2hlbigpLCBvbGRJZCwgMCwgMCwga2V5LCBtb2QpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnZlcnQgbW91c2UgZXZlbnQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbWUuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGV2ZW50LgorICAgICAgICAgKi8KKyAgICAgICAgRXZlbnQgY29udmVydE1vdXNlRXZlbnQoTW91c2VFdmVudCBtZSkgeworICAgICAgICAgICAgaW50IGlkID0gbWUuaWQ7CisgICAgICAgICAgICBpZiAoaWQgIT0gTW91c2VFdmVudC5NT1VTRV9DTElDS0VEKSB7CisgICAgICAgICAgICAgICAgRXZlbnQgZXZ0ID0gbmV3IEV2ZW50KG1lLnNvdXJjZSwgaWQsIG51bGwpOworICAgICAgICAgICAgICAgIGV2dC54ID0gbWUuZ2V0WCgpOworICAgICAgICAgICAgICAgIGV2dC55ID0gbWUuZ2V0WSgpOworICAgICAgICAgICAgICAgIGludCBtb2QgPSBtZS5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgICAgICAgICAvLyBpbiBFdmVudCBtb2RpZmllcnMgbWVhbiBidXR0b24gbnVtYmVyIGZvciBtb3VzZSBldmVudHM6CisgICAgICAgICAgICAgICAgZXZ0Lm1vZGlmaWVycyA9IG1vZCAmIChFdmVudC5BTFRfTUFTSyB8IEV2ZW50Lk1FVEFfTUFTSyk7CisgICAgICAgICAgICAgICAgaWYgKGlkID09IE1vdXNlRXZlbnQuTU9VU0VfUFJFU1NFRCkgeworICAgICAgICAgICAgICAgICAgICBldnQuY2xpY2tDb3VudCA9IG1lLmdldENsaWNrQ291bnQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGV2dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnZlcnQga2V5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGtleUNoYXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUga2V5IGNoYXIuCisgICAgICAgICAqIEBwYXJhbSBrZXlDb2RlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGtleSBjb2RlLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICAgICAqLworICAgICAgICBpbnQgY29udmVydEtleShjaGFyIGtleUNoYXIsIGludCBrZXlDb2RlKSB7CisgICAgICAgICAgICBpbnQga2V5OworICAgICAgICAgICAgLy8gRjEgLSBGMTIKKyAgICAgICAgICAgIGlmIChrZXlDb2RlID49IEtleUV2ZW50LlZLX0YxICYmIGtleUNvZGUgPD0gS2V5RXZlbnQuVktfRjEyKSB7CisgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuRjEgKyBrZXlDb2RlIC0gS2V5RXZlbnQuVktfRjE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN3aXRjaCAoa2V5Q29kZSkgeworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiAvLyBub24tYWN0aW9uIGtleQorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5Q2hhcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAvLyBhY3Rpb24ga2V5czoKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXlFdmVudC5WS19IT01FOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuSE9NRTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX0VORDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IEV2ZW50LkVORDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX1BBR0VfVVA6CisgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBFdmVudC5QR1VQOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5RXZlbnQuVktfUEFHRV9ET1dOOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuUEdETjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX1VQOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuVVA7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXlFdmVudC5WS19ET1dOOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuRE9XTjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX0xFRlQ6CisgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBFdmVudC5MRUZUOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5RXZlbnQuVktfUklHSFQ6CisgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBFdmVudC5SSUdIVDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX1BSSU5UU0NSRUVOOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuUFJJTlRfU0NSRUVOOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5RXZlbnQuVktfU0NST0xMX0xPQ0s6CisgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBFdmVudC5TQ1JPTExfTE9DSzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX0NBUFNfTE9DSzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IEV2ZW50LkNBUFNfTE9DSzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LlZLX05VTV9MT0NLOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuTlVNX0xPQ0s7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBLZXlFdmVudC5WS19QQVVTRToKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IEV2ZW50LlBBVVNFOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5RXZlbnQuVktfSU5TRVJUOgorICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gRXZlbnQuSU5TRVJUOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGtleTsKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQVdURXhjZXB0aW9uLmphdmEgYi9hd3QvamF2YS9hd3QvQVdURXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjU5MGI3MwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9BV1RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8qKgorICogVGhlIEFXVEV4Y2VwdGlvbiBjbGFzcyBpcyB1c2VkIHRvIHByb3ZpZGUgbm90aWZpY2F0aW9uIGFuZCBpbmZvcm1hdGlvbiBhYm91dAorICogQVdUIGVycm9ycy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBBV1RFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE5MDA0MTQyMzExNTEzMjM4NzlMOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFXVCBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmljIG1lc3NhZ2UgZm9yIGN1cnJlbnQgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBBV1RFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0FXVEtleVN0cm9rZS5qYXZhIGIvYXd0L2phdmEvYXd0L0FXVEtleVN0cm9rZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMWY2ZjAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQVdUS2V5U3Ryb2tlLmphdmEKQEAgLTAsMCArMSw3MTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRG1pdHJ5IEEuIER1cm5ldgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUV2ZW50OworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBBV1RLZXlTdHJva2UgaG9sZHMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGNvbXBsZXRlIGFjdCBvZiAKKyAqIHR5cGluZyBhIGNoYXJhY3Rlci4gVGhpcyBpbmNsdWRlcyB0aGUgZXZlbnRzIHRoYXQgYXJlIGdlbmVyYXRlZCB3aGVuIAorICogdGhlIGtleSBpcyBwcmVzc2VkLCByZWxlYXNlZCwgb3IgdHlwZWQgKHByZXNzZWQgYW5kIHJlbGVhc2VkIGdlbmVyYXRpbmcKKyAqIGEgVW5pY29kZSBjaGFyYWN0ZXIgcmVzdWx0KSB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBldmVudAorICogb2JqZWN0cyBLZXlFdmVudC5LRVlfUFJFU1NFRCwgS2V5RXZlbnQuS0VZX1JFTEVBU0VELCBvciBLZXlFdmVudC5LRVlfVFlQRUQuCisgKiBJdCBhbHNvIGhvbGRzIGluZm9ybWF0aW9uIGFib3V0IHdoaWNoIG1vZGlmaWVycyAoc3VjaCBhcyBjb250cm9sIG9yIAorICogc2hpZnQpIHdlcmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBrZXlzdHJva2UuIFRoZSBmb2xsb3dpbmcgbWFza3MgCisgKiBhcmUgYXZhaWxhYmxlIHRvIGlkZW50aWZ5IHRoZSBtb2RpZmllcnM6CisgKiA8dWw+CisgKiA8bGk+amF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfR1JBUEhfRE9XTl9NQVNLPC9saT4KKyAqIDxsaT5qYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9ET1dOX01BU0s8L2xpPgorICogPGxpPmphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQ1RSTF9ET1dOX01BU0s8L2xpPgorICogPGxpPmphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuTUVUQV9ET1dOX01BU0s8L2xpPgorICogPGxpPmphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuU0hJRlRfRE9XTl9NQVNLPC9saT4KKyAqIDxsaT5qYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9HUkFQSF9NQVNLPC9saT4KKyAqIDxsaT5qYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9NQVNLPC9saT4KKyAqIDxsaT5qYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkNUUkxfTUFTSzwvbGk+CisgKiA8bGk+amF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5NRVRBX01BU0s8L2xpPiAgCisgKiA8bGk+amF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5TSElGVF9NQVNLPC9saT4KKyAqIDwvdWw+ICAKKyAqIDxicj4KKyAqICBUaGUgQVdUS2V5U3Ryb2tlIGlzIHVuaXF1ZSwgYW5kIGFwcGxpY2F0aW9ucyBzaG91bGQgbm90IGNyZWF0ZSB0aGVpciBvd24gCisgKiAgaW5zdGFuY2VzIG9mIEFXVEtleVN0cm9rZS4gQWxsIGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlIGdldEFXVEtleVN0cm9rZSAKKyAqICBtZXRob2RzIGZvciBvYnRhaW5pbmcgaW5zdGFuY2VzIG9mIEFXVEtleVN0cm9rZS4KKyAqICAKKyAqICBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEFXVEtleVN0cm9rZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjQzMDUzOTY5MTE1NTE2MTg3MUw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgY2FjaGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPEFXVEtleVN0cm9rZSwgQVdUS2V5U3Ryb2tlPiBjYWNoZSA9IG5ldyBIYXNoTWFwPEFXVEtleVN0cm9rZSwgQVdUS2V5U3Ryb2tlPigpOyAvLyBNYXAKKworICAgIC8vIDwKKyAgICAvLyBBV1RLZXlTdHJva2UKKyAgICAvLyAsCisgICAgLy8gPworICAgIC8vIGV4dGVuZHMKKyAgICAvLyBBV1RLZXlTdHJva2UKKyAgICAvLyA+CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQga2V5RXZlbnRUeXBlc01hcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgU3RyaW5nPiBrZXlFdmVudFR5cGVzTWFwID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU3RyaW5nPigpOyAvLyBNYXAKKworICAgIC8vIDwKKyAgICAvLyBpbnQKKyAgICAvLyAsCisgICAgLy8gU3RyaW5nCisgICAgLy8gPgorCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29uc3RydWN0b3I8Pz4gc3ViQ29uc3RydWN0b3I7CisKKyAgICBzdGF0aWMgeworICAgICAgICBrZXlFdmVudFR5cGVzTWFwLnB1dChuZXcgSW50ZWdlcihLZXlFdmVudC5LRVlfUFJFU1NFRCksICJwcmVzc2VkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAga2V5RXZlbnRUeXBlc01hcC5wdXQobmV3IEludGVnZXIoS2V5RXZlbnQuS0VZX1JFTEVBU0VEKSwgInJlbGVhc2VkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAga2V5RXZlbnRUeXBlc01hcC5wdXQobmV3IEludGVnZXIoS2V5RXZlbnQuS0VZX1RZUEVEKSwgInR5cGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUga2V5IGNoYXIuCisgICAgICovCisgICAgcHJpdmF0ZSBjaGFyIGtleUNoYXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUga2V5IGNvZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQga2V5Q29kZTsKKworICAgIC8qKgorICAgICAqIFRoZSBtb2RpZmllcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbW9kaWZpZXJzOworCisgICAgLyoqCisgICAgICogVGhlIG9uIGtleSByZWxlYXNlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBvbktleVJlbGVhc2U7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQVdUS2V5U3Ryb2tlLiBnZXRBV1RLZXlTdHJva2UgbWV0aG9kIHNob3VsZCBiZSB1c2VkIGJ5CisgICAgICogYXBwbGljYXRpb25zIGNvZGUuCisgICAgICogCisgICAgICogQHBhcmFtIGtleUNoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY2hhci4KKyAgICAgKiBAcGFyYW0ga2V5Q29kZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBjb2RlLgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMuCisgICAgICogQHBhcmFtIG9uS2V5UmVsZWFzZQorICAgICAqICAgICAgICAgICAgdHJ1ZSBpZiBBV1RLZXlTdHJva2UgaXMgZm9yIGEga2V5IHJlbGVhc2UsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQVdUS2V5U3Ryb2tlKGNoYXIga2V5Q2hhciwgaW50IGtleUNvZGUsIGludCBtb2RpZmllcnMsIGJvb2xlYW4gb25LZXlSZWxlYXNlKSB7CisgICAgICAgIHNldEFXVEtleVN0cm9rZShrZXlDaGFyLCBrZXlDb2RlLCBtb2RpZmllcnMsIG9uS2V5UmVsZWFzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgQVdUIGtleSBzdHJva2UuCisgICAgICogCisgICAgICogQHBhcmFtIGtleUNoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY2hhci4KKyAgICAgKiBAcGFyYW0ga2V5Q29kZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBjb2RlLgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMuCisgICAgICogQHBhcmFtIG9uS2V5UmVsZWFzZQorICAgICAqICAgICAgICAgICAgdGhlIG9uIGtleSByZWxlYXNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRBV1RLZXlTdHJva2UoY2hhciBrZXlDaGFyLCBpbnQga2V5Q29kZSwgaW50IG1vZGlmaWVycywgYm9vbGVhbiBvbktleVJlbGVhc2UpIHsKKyAgICAgICAgdGhpcy5rZXlDaGFyID0ga2V5Q2hhcjsKKyAgICAgICAgdGhpcy5rZXlDb2RlID0ga2V5Q29kZTsKKyAgICAgICAgdGhpcy5tb2RpZmllcnMgPSBtb2RpZmllcnM7CisgICAgICAgIHRoaXMub25LZXlSZWxlYXNlID0gb25LZXlSZWxlYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBBV1RLZXlTdHJva2Ugd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnM6CisgICAgICogS2V5RXZlbnQuQ0hBUl9VTkRFRklORUQga2V5IGNoYXIsIEtleUV2ZW50LlZLX1VOREVGSU5FRCBrZXkgY29kZSwgd2l0aG91dAorICAgICAqIG1vZGlmaWVycyBhbmQgZmFsc2Uga2V5IHJlYWxpemVkIHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBBV1RLZXlTdHJva2UoKSB7CisgICAgICAgIHRoaXMoS2V5RXZlbnQuQ0hBUl9VTkRFRklORUQsIEtleUV2ZW50LlZLX1VOREVGSU5FRCwgMCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHVuaXF1ZSBudW1iZXIgdmFsdWUgZm9yIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciB1bmlxdWUgdmFsdWUgb2YgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG1vZGlmaWVycyArIChrZXlDb2RlICE9IEtleUV2ZW50LlZLX1VOREVGSU5FRCA/IGtleUNvZGUgOiBrZXlDaGFyKQorICAgICAgICAgICAgICAgICsgKG9uS2V5UmVsZWFzZSA/IC0xIDogMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2V0IG9mIG1vZGlmaWVycyBmb3IgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciB2YWx1ZSB3aGljaCBjb250YWlucyBtb2RpZmllcnMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRNb2RpZmllcnMoKSB7CisgICAgICAgIHJldHVybiBtb2RpZmllcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBBV1RLZXlTdHJva2Ugb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbk9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBBV1RLZXlTdHJva2Ugb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzCisgICAgICogICAgICAgICAgICBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgb2JqZWN0cyBhcmUgaWRlbnRpY2FsLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBhbk9iamVjdCkgeworICAgICAgICBpZiAoYW5PYmplY3QgaW5zdGFuY2VvZiBBV1RLZXlTdHJva2UpIHsKKyAgICAgICAgICAgIEFXVEtleVN0cm9rZSBrZXkgPSAoQVdUS2V5U3Ryb2tlKWFuT2JqZWN0OworICAgICAgICAgICAgcmV0dXJuICgoa2V5LmtleUNvZGUgPT0ga2V5Q29kZSkgJiYgKGtleS5rZXlDaGFyID09IGtleUNoYXIpCisgICAgICAgICAgICAgICAgICAgICYmIChrZXkubW9kaWZpZXJzID09IG1vZGlmaWVycykgJiYgKGtleS5vbktleVJlbGVhc2UgPT0gb25LZXlSZWxlYXNlKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQVdUS2V5U3Ryb2tlLiBUaGlzIHN0cmluZyBzaG91bGQKKyAgICAgKiBjb250YWluIGtleSBzdHJva2UgcHJvcGVydGllcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFXVEtleVN0cm9rZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpbnQgdHlwZSA9IGdldEtleUV2ZW50VHlwZSgpOworICAgICAgICByZXR1cm4gSW5wdXRFdmVudC5nZXRNb2RpZmllcnNFeFRleHQoZ2V0TW9kaWZpZXJzKCkpICsgIiAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIGtleUV2ZW50VHlwZXNNYXAuZ2V0KG5ldyBJbnRlZ2VyKHR5cGUpKSArICIgIiArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAodHlwZSA9PSBLZXlFdmVudC5LRVlfVFlQRUQgPyBuZXcgU3RyaW5nKG5ldyBjaGFyW10geworICAgICAgICAgICAgICAgICAgICBrZXlDaGFyCisgICAgICAgICAgICAgICAgfSkgOiBLZXlFdmVudC5nZXRLZXlUZXh0KGtleUNvZGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBrZXkgY29kZSBmb3IgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUga2V5IGNvZGUgZm9yIHRoZSBBV1RLZXlTdHJva2Ugb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0S2V5Q29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGtleUNvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUga2V5IGNoYXJhY3RlciBmb3IgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUga2V5IGNoYXJhY3RlciBmb3IgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGNoYXIgZ2V0S2V5Q2hhcigpIHsKKyAgICAgICAgcmV0dXJuIGtleUNoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQVdUIGtleSBzdHJva2UuCisgICAgICogCisgICAgICogQHBhcmFtIGtleUNoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY2hhci4KKyAgICAgKiBAcGFyYW0ga2V5Q29kZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBjb2RlLgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMuCisgICAgICogQHBhcmFtIG9uS2V5UmVsZWFzZQorICAgICAqICAgICAgICAgICAgdGhlIG9uIGtleSByZWxlYXNlLgorICAgICAqIEByZXR1cm4gdGhlIEFXVCBrZXkgc3Ryb2tlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEFXVEtleVN0cm9rZSBnZXRBV1RLZXlTdHJva2UoY2hhciBrZXlDaGFyLCBpbnQga2V5Q29kZSwgaW50IG1vZGlmaWVycywKKyAgICAgICAgICAgIGJvb2xlYW4gb25LZXlSZWxlYXNlKSB7CisgICAgICAgIEFXVEtleVN0cm9rZSBrZXkgPSBuZXdJbnN0YW5jZShrZXlDaGFyLCBrZXlDb2RlLCBtb2RpZmllcnMsIG9uS2V5UmVsZWFzZSk7CisKKyAgICAgICAgQVdUS2V5U3Ryb2tlIHZhbHVlID0gY2FjaGUuZ2V0KGtleSk7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB2YWx1ZSA9IGtleTsKKyAgICAgICAgICAgIGNhY2hlLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogTmV3IGluc3RhbmNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXlDaGFyCisgICAgICogICAgICAgICAgICB0aGUga2V5IGNoYXIuCisgICAgICogQHBhcmFtIGtleUNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY29kZS4KKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpZXJzLgorICAgICAqIEBwYXJhbSBvbktleVJlbGVhc2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbiBrZXkgcmVsZWFzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBBV1Qga2V5IHN0cm9rZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBBV1RLZXlTdHJva2UgbmV3SW5zdGFuY2UoY2hhciBrZXlDaGFyLCBpbnQga2V5Q29kZSwgaW50IG1vZGlmaWVycywKKyAgICAgICAgICAgIGJvb2xlYW4gb25LZXlSZWxlYXNlKSB7CisgICAgICAgIEFXVEtleVN0cm9rZSBrZXk7CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvLyBpZiAoc3ViQ29uc3RydWN0b3IgPT0gbnVsbCkgeworICAgICAgICBrZXkgPSBuZXcgQVdUS2V5U3Ryb2tlKCk7CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvLyB9IGVsc2UgeworICAgICAgICAvLyB0cnkgeworICAgICAgICAvLyBrZXkgPSAoQVdUS2V5U3Ryb2tlKSBzdWJDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZSgpOworICAgICAgICAvLyB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAvLyB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgLy8gfQorICAgICAgICAvLyB9CisgICAgICAgIGludCBhbGxNb2RpZmllcnMgPSBnZXRBbGxNb2RpZmllcnMobW9kaWZpZXJzKTsKKyAgICAgICAga2V5LnNldEFXVEtleVN0cm9rZShrZXlDaGFyLCBrZXlDb2RlLCBhbGxNb2RpZmllcnMsIG9uS2V5UmVsZWFzZSk7CisgICAgICAgIHJldHVybiBrZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgbWFzay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kCisgICAgICogICAgICAgICAgICB0aGUgbW9kLgorICAgICAqIEBwYXJhbSBtYXNrCisgICAgICogICAgICAgICAgICB0aGUgbWFzay4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGFkZE1hc2soaW50IG1vZCwgaW50IG1hc2spIHsKKyAgICAgICAgcmV0dXJuICgobW9kICYgbWFzaykgIT0gMCkgPyAobW9kIHwgbWFzaykgOiBtb2Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCAob2xkICYgbmV3KSBtb2RpZmllcnMgY29ycmVzcG9uZGluZyB0by4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kCisgICAgICogICAgICAgICAgICBvbGQgb3IgbmV3IG1vZGlmaWVycy4KKyAgICAgKiBAcmV0dXJuIG9sZCBhbmQgbmV3IG1vZGlmaWVycyB0b2dldGhlci4KKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGdldEFsbE1vZGlmaWVycyhpbnQgbW9kKSB7CisgICAgICAgIGludCBhbGxNb2QgPSBtb2Q7CisgICAgICAgIGludCBzaGlmdCA9IChJbnB1dEV2ZW50LlNISUZUX01BU0sgfCBJbnB1dEV2ZW50LlNISUZUX0RPV05fTUFTSyk7CisgICAgICAgIGludCBjdHJsID0gKElucHV0RXZlbnQuQ1RSTF9NQVNLIHwgSW5wdXRFdmVudC5DVFJMX0RPV05fTUFTSyk7CisgICAgICAgIGludCBtZXRhID0gKElucHV0RXZlbnQuTUVUQV9NQVNLIHwgSW5wdXRFdmVudC5NRVRBX0RPV05fTUFTSyk7CisgICAgICAgIGludCBhbHQgPSAoSW5wdXRFdmVudC5BTFRfTUFTSyB8IElucHV0RXZlbnQuQUxUX0RPV05fTUFTSyk7CisgICAgICAgIGludCBhbHRHciA9IChJbnB1dEV2ZW50LkFMVF9HUkFQSF9NQVNLIHwgSW5wdXRFdmVudC5BTFRfR1JBUEhfRE9XTl9NQVNLKTsKKyAgICAgICAgLy8gYnV0dG9uIG1vZGlmaWVycyBhcmUgbm90IGNvbnZlcnRlZCBiZXR3ZWVuIG9sZCAmIG5ldworCisgICAgICAgIGFsbE1vZCA9IGFkZE1hc2soYWxsTW9kLCBzaGlmdCk7CisgICAgICAgIGFsbE1vZCA9IGFkZE1hc2soYWxsTW9kLCBjdHJsKTsKKyAgICAgICAgYWxsTW9kID0gYWRkTWFzayhhbGxNb2QsIG1ldGEpOworICAgICAgICBhbGxNb2QgPSBhZGRNYXNrKGFsbE1vZCwgYWx0KTsKKyAgICAgICAgYWxsTW9kID0gYWRkTWFzayhhbGxNb2QsIGFsdEdyKTsKKworICAgICAgICByZXR1cm4gYWxsTW9kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgQVdUS2V5U3Ryb2tlIGZvciBwYXJzZWQgc3RyaW5nLiBUaGUgc3RyaW5nIG11c3QKKyAgICAgKiBoYXZlIHRoZSBmb2xsb3dpbmcgc3ludGF4OgorICAgICAqPHA+CisgICAgICogJmx0O21vZGlmaWVycyZndDsqICgmbHQ7dHlwZWRJRCZndDsgfCAmbHQ7cHJlc3NlZFJlbGVhc2VkSUQmZ3Q7KQorICAgICAqPHA+CisgICAgICogbW9kaWZpZXJzIDo9IHNoaWZ0IHwgY29udHJvbCB8IGN0cmwgfCBtZXRhIHwgYWx0IHwgYWx0R3JhcGggPGJyPgorICAgICAqIHR5cGVkSUQgOj0gdHlwZWQgPHR5cGVkS2V5PiA8YnI+CisgICAgICogdHlwZWRLZXkgOj0gc3RyaW5nIG9mIGxlbmd0aCAxIGdpdmluZyB0aGUgVW5pY29kZSBjaGFyYWN0ZXIuIDxicj4KKyAgICAgKiBwcmVzc2VkUmVsZWFzZWRJRCA6PSAocHJlc3NlZCB8IHJlbGVhc2VkKSA8a2V5PiA8YnI+CisgICAgICoga2V5IDo9IEtleUV2ZW50IGtleSBjb2RlIG5hbWUsIGkuZS4gdGhlIG5hbWUgZm9sbG93aW5nICJWS18iLgorICAgICAqIDxwPgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHdoaWNoIGNvbnRhaW5zIGtleSBzdHJva2UgcGFyYW1ldGVycy4KKyAgICAgKiBAcmV0dXJuIHRoZSBBV1RLZXlTdHJva2UgZm9yIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHN0cmluZyBoYXMgaW5jb3JyZWN0IGZvcm1hdCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVdUS2V5U3Ryb2tlIGdldEFXVEtleVN0cm9rZShTdHJpbmcgcykgeworICAgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuNjU9bnVsbCBhcmd1bWVudAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocyk7CisKKyAgICAgICAgQm9vbGVhbiByZWxlYXNlID0gbnVsbDsKKyAgICAgICAgaW50IG1vZGlmaWVycyA9IDA7CisgICAgICAgIGludCBrZXlDb2RlID0gS2V5RXZlbnQuVktfVU5ERUZJTkVEOworICAgICAgICBjaGFyIGtleUNoYXIgPSBLZXlFdmVudC5DSEFSX1VOREVGSU5FRDsKKyAgICAgICAgYm9vbGVhbiB0eXBlZCA9IGZhbHNlOworICAgICAgICBsb25nIG1vZGlmaWVyID0gMDsKKyAgICAgICAgU3RyaW5nIHRva2VuID0gbnVsbDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgdG9rZW4gPSBnZXROZXh0VG9rZW4odG9rZW5pemVyKTsKKyAgICAgICAgICAgIG1vZGlmaWVyID0gcGFyc2VNb2RpZmllcih0b2tlbik7CisgICAgICAgICAgICBtb2RpZmllcnMgfD0gbW9kaWZpZXI7CisgICAgICAgIH0gd2hpbGUgKG1vZGlmaWVyID4gMCk7CisKKyAgICAgICAgdHlwZWQgPSBwYXJzZVR5cGVkSUQodG9rZW4pOworCisgICAgICAgIGlmICh0eXBlZCkgeworICAgICAgICAgICAgdG9rZW4gPSBnZXROZXh0VG9rZW4odG9rZW5pemVyKTsKKyAgICAgICAgICAgIGtleUNoYXIgPSBwYXJzZVR5cGVkS2V5KHRva2VuKTsKKworICAgICAgICB9CisgICAgICAgIGlmIChrZXlDaGFyID09IEtleUV2ZW50LkNIQVJfVU5ERUZJTkVEKSB7CisgICAgICAgICAgICByZWxlYXNlID0gcGFyc2VQcmVzc2VkUmVsZWFzZWRJRCh0b2tlbik7CisgICAgICAgICAgICBpZiAocmVsZWFzZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG9rZW4gPSBnZXROZXh0VG9rZW4odG9rZW5pemVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleUNvZGUgPSBwYXJzZUtleSh0b2tlbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Nj1JbnZhbGlkIGZvcm1hdAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGdldEFXVEtleVN0cm9rZShrZXlDaGFyLCBrZXlDb2RlLCBtb2RpZmllcnMsIHJlbGVhc2UgPT0gQm9vbGVhbi5UUlVFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuZXh0IHRva2VuLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0b2tlbml6ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB0b2tlbml6ZXIuCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TmV4dFRva2VuKFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICAgICAgICAvLyBhd3QuNjY9SW52YWxpZCBmb3JtYXQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGtleSBjb2RlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBrZXkgY29kZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGdldEtleUNvZGUoU3RyaW5nIHMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZpZWxkIHZrID0gS2V5RXZlbnQuY2xhc3MuZ2V0RmllbGQoIlZLXyIgKyBzKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgcmV0dXJuIHZrLmdldEludChudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChzLmxlbmd0aCgpICE9IDEpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNjY9SW52YWxpZCBmb3JtYXQKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjY2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gS2V5RXZlbnQuVktfVU5ERUZJTkVEOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBpbnN0YW5jZSBvZiB0aGUgQVdUS2V5U3Ryb2tlIGZvciBzcGVjaWZpZWQgY2hhcmFjdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXlDaGFyCisgICAgICogICAgICAgICAgICB0aGUga2V5Ym9hcmQgY2hhcmFjdGVyIHZhbHVlLgorICAgICAqIEByZXR1cm4gYSBBV1RLZXlTdHJva2UgZm9yIHNwZWNpZmllZCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBV1RLZXlTdHJva2UgZ2V0QVdUS2V5U3Ryb2tlKGNoYXIga2V5Q2hhcikgeworICAgICAgICByZXR1cm4gZ2V0QVdUS2V5U3Ryb2tlKGtleUNoYXIsIEtleUV2ZW50LlZLX1VOREVGSU5FRCwgMCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgQVdUS2V5U3Ryb2tlIGZvciBhIGdpdmVuIGtleSBjb2RlLCBzZXQgb2YKKyAgICAgKiBtb2RpZmllcnMsIGFuZCBzcGVjaWZpZWQga2V5IHJlbGVhc2VkIGZsYWcgdmFsdWUuIFRoZSBrZXkgY29kZXMgYXJlCisgICAgICogZGVmaW5lZCBpbiBqYXZhLmF3dC5ldmVudC5LZXlFdmVudCBjbGFzcy4gVGhlIHNldCBvZiBtb2RpZmllcnMgaXMgZ2l2ZW4KKyAgICAgKiBhcyBhIGJpdHdpc2UgY29tYmluYXRpb24gb2YgbWFza3MgdGFrZW4gZnJvbSB0aGUgZm9sbG93aW5nIGxpc3Q6CisgICAgICogPHVsPgorICAgICAqIDxsaT5qYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9HUkFQSF9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfRE9XTl9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQ1RSTF9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5NRVRBX0RPV05fTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LlNISUZUX0RPV05fTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9HUkFQSF9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQUxUX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5DVFJMX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5NRVRBX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5TSElGVF9NQVNLPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDxicj4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5Q29kZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBrZXkgY29kZSBvZiBrZXlib2FyZC4KKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgYml0IHNldCBvZiBtb2RpZmllcnMuCisgICAgICogQHBhcmFtIG9uS2V5UmVsZWFzZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdoaWNoIHJlcHJlc2VudHMgd2hldGhlciB0aGlzIEFXVEtleVN0cm9rZSBzaGFsbAorICAgICAqICAgICAgICAgICAgcmVwcmVzZW50cyBhIGtleSByZWxlYXNlLgorICAgICAqIEByZXR1cm4gdGhlIEFXVEtleVN0cm9rZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFXVEtleVN0cm9rZSBnZXRBV1RLZXlTdHJva2UoaW50IGtleUNvZGUsIGludCBtb2RpZmllcnMsIGJvb2xlYW4gb25LZXlSZWxlYXNlKSB7CisgICAgICAgIHJldHVybiBnZXRBV1RLZXlTdHJva2UoS2V5RXZlbnQuQ0hBUl9VTkRFRklORUQsIGtleUNvZGUsIG1vZGlmaWVycywgb25LZXlSZWxlYXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFXVEtleVN0cm9rZSBmb3IgYSBzcGVjaWZpZWQgY2hhcmFjdGVyIGFuZCBzZXQgb2YgbW9kaWZpZXJzLiBUaGUKKyAgICAgKiBzZXQgb2YgbW9kaWZpZXJzIGlzIGdpdmVuIGFzIGEgYml0d2lzZSBjb21iaW5hdGlvbiBvZiBtYXNrcyB0YWtlbiBmcm9tCisgICAgICogdGhlIGZvbGxvd2luZyBsaXN0OgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+amF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfR1JBUEhfRE9XTl9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQUxUX0RPV05fTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkNUUkxfRE9XTl9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuTUVUQV9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5TSElGVF9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfR1JBUEhfTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQ1RSTF9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuTUVUQV9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuU0hJRlRfTUFTSzwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5Q2hhcgorICAgICAqICAgICAgICAgICAgdGhlIENoYXJhY3RlciBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyBrZXlib2FyZCBjaGFyYWN0ZXIKKyAgICAgKiAgICAgICAgICAgIHZhbHVlLgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXQgc2V0IG9mIG1vZGlmaWVycy4KKyAgICAgKiBAcmV0dXJuIHRoZSBBV1RLZXlTdHJva2Ugb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYga2V5Q2hhciB2YWx1ZSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVdUS2V5U3Ryb2tlIGdldEFXVEtleVN0cm9rZShDaGFyYWN0ZXIga2V5Q2hhciwgaW50IG1vZGlmaWVycykgeworICAgICAgICBpZiAoa2V5Q2hhciA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMDE9J3swfScgcGFyYW1ldGVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDEiLCAia2V5Q2hhciIpKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEFXVEtleVN0cm9rZShrZXlDaGFyLmNoYXJWYWx1ZSgpLCBLZXlFdmVudC5WS19VTkRFRklORUQsIG1vZGlmaWVycywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgQVdUS2V5U3Ryb2tlIGZvciBhIHNwZWNpZmllZCBrZXkgY29kZSBhbmQgc2V0IG9mCisgICAgICogbW9kaWZpZXJzLiBUaGUga2V5IGNvZGVzIGFyZSBkZWZpbmVkIGluIGphdmEuYXd0LmV2ZW50LktleUV2ZW50IGNsYXNzLgorICAgICAqIFRoZSBzZXQgb2YgbW9kaWZpZXJzIGlzIGdpdmVuIGFzIGEgYml0d2lzZSBjb21iaW5hdGlvbiBvZiBtYXNrcyB0YWtlbgorICAgICAqIGZyb20gdGhlIGZvbGxvd2luZyBsaXN0OgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+amF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfR1JBUEhfRE9XTl9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQUxUX0RPV05fTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkNUUkxfRE9XTl9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuTUVUQV9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5TSElGVF9ET1dOX01BU0s8L2xpPiA8bGk+CisgICAgICogamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudC5BTFRfR1JBUEhfTUFTSzwvbGk+IDxsaT4KKyAgICAgKiBqYXZhLmF3dC5ldmVudC5JbnB1dEV2ZW50LkFMVF9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuQ1RSTF9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuTUVUQV9NQVNLPC9saT4gPGxpPgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQuU0hJRlRfTUFTSzwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5Q29kZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBrZXkgY29kZSBvZiBrZXlib2FyZC4KKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgYml0IHNldCBvZiBtb2RpZmllcnMuCisgICAgICogQHJldHVybiB0aGUgQVdUS2V5U3Ryb2tlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVdUS2V5U3Ryb2tlIGdldEFXVEtleVN0cm9rZShpbnQga2V5Q29kZSwgaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gZ2V0QVdUS2V5U3Ryb2tlKGtleUNvZGUsIG1vZGlmaWVycywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEFXVEtleVN0cm9rZSBmb3IgYSBrZXkgZXZlbnQuIFRoaXMgbWV0aG9kIG9idGFpbnMgdGhlIGtleSBjaGFyCisgICAgICogYW5kIGtleSBjb2RlIGZyb20gdGhlIHNwZWNpZmllZCBrZXkgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGFuRXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZXZlbnQgd2hpY2ggaWRlbnRpZmllcyB0aGUgZGVzaXJlZCBBV1RLZXlTdHJva2UuCisgICAgICogQHJldHVybiB0aGUgQVdUS2V5U3Ryb2tlIGZvciB0aGUga2V5IGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVdUS2V5U3Ryb2tlIGdldEFXVEtleVN0cm9rZUZvckV2ZW50KEtleUV2ZW50IGFuRXZlbnQpIHsKKyAgICAgICAgaW50IGlkID0gYW5FdmVudC5nZXRJRCgpOworICAgICAgICBjaGFyIHVuZGVmID0gS2V5RXZlbnQuQ0hBUl9VTkRFRklORUQ7CisgICAgICAgIGNoYXIga2V5Q2hhciA9IChpZCA9PSBLZXlFdmVudC5LRVlfVFlQRUQgPyBhbkV2ZW50LmdldEtleUNoYXIoKSA6IHVuZGVmKTsKKyAgICAgICAgaW50IGtleUNvZGUgPSAoa2V5Q2hhciA9PSB1bmRlZiA/IGFuRXZlbnQuZ2V0S2V5Q29kZSgpIDogS2V5RXZlbnQuVktfVU5ERUZJTkVEKTsKKyAgICAgICAgcmV0dXJuIGdldEFXVEtleVN0cm9rZShrZXlDaGFyLCBrZXlDb2RlLCBhbkV2ZW50LmdldE1vZGlmaWVyc0V4KCksCisgICAgICAgICAgICAgICAgaWQgPT0gS2V5RXZlbnQuS0VZX1JFTEVBU0VEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBrZXkgZXZlbnQgdHlwZSBmb3IgdGhlIEFXVEtleVN0cm9rZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUga2V5IGV2ZW50IHR5cGU6IEtleUV2ZW50LktFWV9QUkVTU0VELCBLZXlFdmVudC5LRVlfVFlQRUQsIG9yCisgICAgICogICAgICAgICBLZXlFdmVudC5LRVlfUkVMRUFTRUQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRLZXlFdmVudFR5cGUoKSB7CisgICAgICAgIGlmIChrZXlDb2RlID09IEtleUV2ZW50LlZLX1VOREVGSU5FRCkgeworICAgICAgICAgICAgcmV0dXJuIEtleUV2ZW50LktFWV9UWVBFRDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKG9uS2V5UmVsZWFzZSA/IEtleUV2ZW50LktFWV9SRUxFQVNFRCA6IEtleUV2ZW50LktFWV9QUkVTU0VEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGtleSBldmVudCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIEFXVEtleVN0cm9rZSBpcworICAgICAqIEtFWV9SRUxFQVNFRCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaWYgdGhlIGtleSBldmVudCBhc3NvY2lhdGVkIHdpdGggdGhlIEFXVEtleVN0cm9rZSBpcworICAgICAqICAgICAgICAgS0VZX1JFTEVBU0VELCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNPbktleVJlbGVhc2UoKSB7CisgICAgICAgIHJldHVybiBvbktleVJlbGVhc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCByZXNvbHZlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBvYmplY3Qgc3RyZWFtIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRBV1RLZXlTdHJva2UodGhpcy5rZXlDaGFyLCB0aGlzLmtleUNvZGUsIHRoaXMubW9kaWZpZXJzLCB0aGlzLm9uS2V5UmVsZWFzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgc3ViY2xhc3MuCisgICAgICogCisgICAgICogQHBhcmFtIHN1YmNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgc3ViY2xhc3MuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIHJlZ2lzdGVyU3ViY2xhc3MoQ2xhc3M8Pz4gc3ViY2xhc3MpIHsKKyAgICAgICAgLy8gPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgICAqIGlmIChzdWJjbGFzcyA9PSBudWxsKSB7IC8vIGF3dC4wMT0nezB9JyBwYXJhbWV0ZXIgaXMgbnVsbCB0aHJvdyBuZXcKKyAgICAgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjAxIiwgInN1YmNsYXNzIikpOworICAgICAgICAgKiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgfSBpZiAoIQorICAgICAgICAgKiBBV1RLZXlTdHJva2UuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShzdWJjbGFzcykpIHsgLy8gYXd0LjY3PXN1YmNsYXNzCisgICAgICAgICAqIGlzIG5vdCBkZXJpdmVkIGZyb20gQVdUS2V5U3Ryb2tlIHRocm93IG5ldworICAgICAgICAgKiBDbGFzc0Nhc3RFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjciKSk7IC8vJE5PTi1OTFMtMSQgfSB0cnkKKyAgICAgICAgICogeyBzdWJDb25zdHJ1Y3RvciA9IHN1YmNsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3IoKTsKKyAgICAgICAgICogc3ViQ29uc3RydWN0b3Iuc2V0QWNjZXNzaWJsZSh0cnVlKTsgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgKiB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsgLy8KKyAgICAgICAgICogYXd0LjY4PXN1YmNsYXNzIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgdGhyb3cgbmV3CisgICAgICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgKiB9IGNhY2hlLmNsZWFyKCk7IC8vZmx1c2ggdGhlIGNhY2hlCisgICAgICAgICAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbW9kaWZpZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHN0ck1vZAorICAgICAqICAgICAgICAgICAgdGhlIHN0ciBtb2QuCisgICAgICogQHJldHVybiB0aGUgbG9uZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIHBhcnNlTW9kaWZpZXIoU3RyaW5nIHN0ck1vZCkgeworICAgICAgICBsb25nIG1vZGlmaWVycyA9IDBsOworICAgICAgICBpZiAoc3RyTW9kLmVxdWFscygic2hpZnQiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBtb2RpZmllcnMgfD0gSW5wdXRFdmVudC5TSElGVF9ET1dOX01BU0s7CisgICAgICAgIH0gZWxzZSBpZiAoc3RyTW9kLmVxdWFscygiY29udHJvbCIpIHx8IHN0ck1vZC5lcXVhbHMoImN0cmwiKSkgeyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgIG1vZGlmaWVycyB8PSBJbnB1dEV2ZW50LkNUUkxfRE9XTl9NQVNLOworICAgICAgICB9IGVsc2UgaWYgKHN0ck1vZC5lcXVhbHMoIm1ldGEiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBtb2RpZmllcnMgfD0gSW5wdXRFdmVudC5NRVRBX0RPV05fTUFTSzsKKyAgICAgICAgfSBlbHNlIGlmIChzdHJNb2QuZXF1YWxzKCJhbHQiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBtb2RpZmllcnMgfD0gSW5wdXRFdmVudC5BTFRfRE9XTl9NQVNLOworICAgICAgICB9IGVsc2UgaWYgKHN0ck1vZC5lcXVhbHMoImFsdEdyYXBoIikpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgbW9kaWZpZXJzIHw9IElucHV0RXZlbnQuQUxUX0dSQVBIX0RPV05fTUFTSzsKKyAgICAgICAgfSBlbHNlIGlmIChzdHJNb2QuZXF1YWxzKCJidXR0b24xIikpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgbW9kaWZpZXJzIHw9IElucHV0RXZlbnQuQlVUVE9OMV9ET1dOX01BU0s7CisgICAgICAgIH0gZWxzZSBpZiAoc3RyTW9kLmVxdWFscygiYnV0dG9uMiIpKSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIG1vZGlmaWVycyB8PSBJbnB1dEV2ZW50LkJVVFRPTjJfRE9XTl9NQVNLOworICAgICAgICB9IGVsc2UgaWYgKHN0ck1vZC5lcXVhbHMoImJ1dHRvbjMiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBtb2RpZmllcnMgfD0gSW5wdXRFdmVudC5CVVRUT04zX0RPV05fTUFTSzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbW9kaWZpZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgdHlwZWQgaWQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0clR5cGVkCisgICAgICogICAgICAgICAgICB0aGUgc3RyIHR5cGVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHBhcnNlVHlwZWRJRChTdHJpbmcgc3RyVHlwZWQpIHsKKyAgICAgICAgaWYgKHN0clR5cGVkLmVxdWFscygidHlwZWQiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHR5cGVkIGtleS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIHN0ciBjaGFyLgorICAgICAqIEByZXR1cm4gdGhlIGNoYXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhciBwYXJzZVR5cGVkS2V5KFN0cmluZyBzdHJDaGFyKSB7CisgICAgICAgIGNoYXIga2V5Q2hhciA9IEtleUV2ZW50LkNIQVJfVU5ERUZJTkVEOworCisgICAgICAgIGlmIChzdHJDaGFyLmxlbmd0aCgpICE9IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Nj1JbnZhbGlkIGZvcm1hdAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGtleUNoYXIgPSBzdHJDaGFyLmNoYXJBdCgwKTsKKyAgICAgICAgcmV0dXJuIGtleUNoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBwcmVzc2VkIHJlbGVhc2VkIGlkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHIuCisgICAgICogQHJldHVybiB0aGUgYm9vbGVhbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBCb29sZWFuIHBhcnNlUHJlc3NlZFJlbGVhc2VkSUQoU3RyaW5nIHN0cikgeworCisgICAgICAgIGlmIChzdHIuZXF1YWxzKCJwcmVzc2VkIikpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uRkFMU0U7CisgICAgICAgIH0gZWxzZSBpZiAoc3RyLmVxdWFscygicmVsZWFzZWQiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUga2V5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJDb2RlCisgICAgICogICAgICAgICAgICB0aGUgc3RyIGNvZGUuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBwYXJzZUtleShTdHJpbmcgc3RyQ29kZSkgeworICAgICAgICBpbnQga2V5Q29kZSA9IEtleUV2ZW50LlZLX1VOREVGSU5FRDsKKworICAgICAgICBrZXlDb2RlID0gZ2V0S2V5Q29kZShzdHJDb2RlKTsKKworICAgICAgICBpZiAoa2V5Q29kZSA9PSBLZXlFdmVudC5WS19VTkRFRklORUQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Nj1JbnZhbGlkIGZvcm1hdAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBrZXlDb2RlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9BV1RMaXN0ZW5lckxpc3QuamF2YSBiL2F3dC9qYXZhL2F3dC9BV1RMaXN0ZW5lckxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzI3ZDYzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0FXVExpc3RlbmVyTGlzdC5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuTGlzdGVuZXJMaXN0OworCitmaW5hbCBjbGFzcyBBV1RMaXN0ZW5lckxpc3Q8VCBleHRlbmRzIEV2ZW50TGlzdGVuZXI+IGV4dGVuZHMgTGlzdGVuZXJMaXN0PFQ+IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjYyMjA3NzE3MTUzMjg0MDk1M0w7CisKKyAgICBwcml2YXRlIGZpbmFsIENvbXBvbmVudCBvd25lcjsKKyAgICAKKyAgICBBV1RMaXN0ZW5lckxpc3QoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgICAgIHRoaXMub3duZXIgPSBudWxsOworICAgIH0KKworICAgIEFXVExpc3RlbmVyTGlzdChDb21wb25lbnQgb3duZXIpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgdGhpcy5vd25lciA9IG93bmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZFVzZXJMaXN0ZW5lcihUIGxpc3RlbmVyKSB7CisgICAgICAgIHN1cGVyLmFkZFVzZXJMaXN0ZW5lcihsaXN0ZW5lcik7CisKKyAgICAgICAgaWYgKG93bmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIG93bmVyLmRlcHJlY2F0ZWRFdmVudEhhbmRsZXIgPSBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9BV1RQZXJtaXNzaW9uLmphdmEgYi9hd3QvamF2YS9hd3QvQVdUUGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiZDgzNTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQVdUUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQmFzaWNQZXJtaXNzaW9uOworCisvKioKKyAqIFRoZSBBV1RQZXJtaXNzaW9uIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgcGVybWlzc2lvbiBhbmQgdGhlIGNvcnJlc3BvbmRpbmcKKyAqIGFjdGlvbiBsaXN0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFXVFBlcm1pc3Npb24gZXh0ZW5kcyBCYXNpY1Blcm1pc3Npb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODg5MDM5MjQwMjU4ODgxNDQ2NUw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQVdUUGVybWlzc2lvbiB3aXRoIGRlZmluZWQgbmFtZSBhbmQgYWN0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBuZXcgQVdUUGVybWlzc2lvbi4KKyAgICAgKiBAcGFyYW0gYWN0aW9ucworICAgICAqICAgICAgICAgICAgdGhlIGFjdGlvbnMgb2YgYSBuZXcgQVdUUGVybWlzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVdUUGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsKKyAgICAgICAgc3VwZXIobmFtZSwgYWN0aW9ucyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFXVCBwZXJtaXNzaW9uIHdpdGggdGhlIGRlZmluZWQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBuZXcgQVdUUGVybWlzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVdUUGVybWlzc2lvbihTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9BY3RpdmVFdmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L0FjdGl2ZUV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzA0NDYyMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9BY3RpdmVFdmVudC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSBkZWZpbmVzIGV2ZW50cyB0aGF0IGtub3cgaG93IHRvIGRpc3BhdGNoIHRoZW1zZWx2ZXMuIFN1Y2gKKyAqIGV2ZW50IGNhbiBiZSBwbGFjZWQgdXBvbiB0aGUgZXZlbnQgcXVldWUgYW5kIGl0cyBkaXNwYXRjaCBtZXRob2Qgd2lsbCBiZQorICogY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGRpc3BhdGNoZWQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEFjdGl2ZUV2ZW50IHsKKworICAgIC8qKgorICAgICAqIERpc3BhdGNoZXMgdGhlIGV2ZW50IHRvIHRoZSBsaXN0ZW5lcnMgb2YgdGhlIGV2ZW50J3Mgc291cmNlLCBvciBkb2VzCisgICAgICogd2hhdGV2ZXIgaXQgaXMgdGhpcyBldmVudCBpcyBzdXBwb3NlZCB0byBkby4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaCgpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQWRqdXN0YWJsZS5qYXZhIGIvYXd0L2phdmEvYXd0L0FkanVzdGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYWY4MGY3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0FkanVzdGFibGUuamF2YQpAQCAtMCwwICsxLDE2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZXZlbnQuQWRqdXN0bWVudExpc3RlbmVyOworCisvKioKKyAqIFRoZSBBZGp1c3RhYmxlIGludGVyZmFjZSByZXByZXNlbnRzIGFuIGFkanVzdGFibGUgbnVtZXJpYyB2YWx1ZSBjb250YWluZWQKKyAqIHdpdGhpbiBhIGJvdW5kZWQgcmFuZ2Ugb2YgdmFsdWVzLCBzdWNoIGFzIHRoZSBjdXJyZW50IGxvY2F0aW9uIGluIHNjcm9sbGFibGUKKyAqIHJlZ2lvbiBvciB0aGUgdmFsdWUgb2YgYSBnYXVnZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQWRqdXN0YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSE9SSVpPTlRBTCBpbmRpY2F0ZXMgdGhhdCB0aGUgQWRqdXN0YWJsZSdzIG9yaWVudGF0aW9uIGlzCisgICAgICogaG9yaXpvbnRhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIT1JJWk9OVEFMID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWRVJUSUNBTCBpbmRpY2F0ZXMgdGhhdCB0aGUgQWRqdXN0YWJsZSdzIG9yaWVudGF0aW9uIGlzCisgICAgICogdmVydGljYWwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkVSVElDQUwgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE5PX09SSUVOVEFUSU9OIGluZGljYXRlcyB0aGF0IHRoZSBBZGp1c3RhYmxlIGhhcyBubworICAgICAqIG9yaWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PX09SSUVOVEFUSU9OID0gMjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRWYWx1ZSgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgdG8gdGhlIEFkanVzdGFibGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBvZiB0aGUgQWRqdXN0YWJsZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VmFsdWUoaW50IGEwKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIEFkanVzdG1lbnRMaXN0ZW5lciB0byBjdXJyZW50IEFkanVzdG1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgQWRqdXN0bWVudExpc3RlbmVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRBZGp1c3RtZW50TGlzdGVuZXIoQWRqdXN0bWVudExpc3RlbmVyIGEwKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJsb2NrIGluY3JlbWVudCBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBibG9jayBpbmNyZW1lbnQgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRCbG9ja0luY3JlbWVudCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4aW11bSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWluaW11bSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb3JpZW50YXRpb24gb2YgdGhlIEFkanVzdGFibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgb3JpZW50YXRpb24gb2YgdGhlIEFkanVzdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPcmllbnRhdGlvbigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdW5pdCBpbmNyZW1lbnQgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdW5pdCBpbmNyZW1lbnQgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRVbml0SW5jcmVtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2aXNpYmxlIGFtb3VudCBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB2aXNpYmxlIGFtb3VudCBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZpc2libGVBbW91bnQoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGFkanVzdG1lbnQgbGlzdGVuZXIgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEFkanVzdG1lbnRMaXN0ZW5lciB0byBiZSByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFkanVzdG1lbnRMaXN0ZW5lcihBZGp1c3RtZW50TGlzdGVuZXIgYTApOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYmxvY2sgaW5jcmVtZW50IGZvciB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYmxvY2sgaW5jcmVtZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2NrSW5jcmVtZW50KGludCBhMCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBtYXhpbXVtIG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1heGltdW0oaW50IGEwKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG1pbmltdW0gb2YgdGhlIEFkanVzdGFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWluaW11bShpbnQgYTApOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdW5pdCBpbmNyZW1lbnQgb2YgdGhlIEFkanVzdGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHVuaXQgaW5jcmVtZW50IG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVuaXRJbmNyZW1lbnQoaW50IGEwKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZpc2libGUgYW1vdW50IG9mIHRoZSBBZGp1c3RhYmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2aXNpYmxlIGFtb3VudCBvZiB0aGUgQWRqdXN0YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRWaXNpYmxlQW1vdW50KGludCBhMCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9BbHBoYUNvbXBvc2l0ZS5qYXZhIGIvYXd0L2phdmEvYXd0L0FscGhhQ29tcG9zaXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM4OWViNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9BbHBoYUNvbXBvc2l0ZS5qYXZhCkBAIC0wLDAgKzEsMzUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGVDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLklDb21wb3NpdGVDb250ZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBBbHBoYUNvbXBvc2l0ZSBjbGFzcyBkZWZpbmVzIGEgYmFzaWMgYWxwaGEgY29tcG9zaXRpbmcgcnVsZXMgZm9yCisgKiBjb21iaW5pbmcgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBjb2xvcnMgdG8gYWNoaWV2ZSBibGVuZGluZyBhbmQgdHJhbnNwYXJlbmN5CisgKiBlZmZlY3RzIHdpdGggZ3JhcGhpY3MgYW5kIGltYWdlcy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBbHBoYUNvbXBvc2l0ZSBpbXBsZW1lbnRzIENvbXBvc2l0ZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xFQVIgaW5kaWNhdGVzIHRoYXQgYm90aCB0aGUgY29sb3IgYW5kIHRoZSBhbHBoYSBvZiB0aGUKKyAgICAgKiBkZXN0aW5hdGlvbiBhcmUgY2xlYXJlZCAoUG9ydGVyLUR1ZmYgQ2xlYXIgcnVsZSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xFQVIgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNSQyBpbmRpY2F0ZXMgdGhhdCB0aGUgc291cmNlIGlzIGNvcGllZCB0byB0aGUgZGVzdGluYXRpb24KKyAgICAgKiAoUG9ydGVyLUR1ZmYgU291cmNlIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNSQyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRFNUIGluZGljYXRlcyB0aGF0IHRoZSBkZXN0aW5hdGlvbiBpcyBsZWZ0IHVudG91Y2hlZAorICAgICAqIChQb3J0ZXItRHVmZiBEZXN0aW5hdGlvbiBydWxlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEU1QgPSA5OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNSQ19PVkVSIGluZGljYXRlcyB0aGF0IHRoZSBzb3VyY2UgaXMgY29tcG9zaXRlZCBvdmVyIHRoZQorICAgICAqIGRlc3RpbmF0aW9uIChQb3J0ZXItRHVmZiBTb3VyY2UgT3ZlciBEZXN0aW5hdGlvbiBydWxlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUkNfT1ZFUiA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRFNUX09WRVIgaW5kaWNhdGVzIHRoYXQgVGhlIGRlc3RpbmF0aW9uIGlzIGNvbXBvc2l0ZWQgb3ZlcgorICAgICAqIHRoZSBzb3VyY2UgYW5kIHRoZSByZXN1bHQgcmVwbGFjZXMgdGhlIGRlc3RpbmF0aW9uIChQb3J0ZXItRHVmZgorICAgICAqIERlc3RpbmF0aW9uIE92ZXIgU291cmNlIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERTVF9PVkVSID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBTUkNfSU4gaW5kaWNhdGVzIHRoYXQgdGhlIHBhcnQgb2YgdGhlIHNvdXJjZSBseWluZyBpbnNpZGUgb2YKKyAgICAgKiB0aGUgZGVzdGluYXRpb24gcmVwbGFjZXMgdGhlIGRlc3RpbmF0aW9uIChQb3J0ZXItRHVmZiBTb3VyY2UgSW4KKyAgICAgKiBEZXN0aW5hdGlvbiBydWxlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUkNfSU4gPSA1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IERTVF9JTiBpbmRpY2F0ZXMgdGhhdCB0aGUgcGFydCBvZiB0aGUgZGVzdGluYXRpb24gbHlpbmcKKyAgICAgKiBpbnNpZGUgb2YgdGhlIHNvdXJjZSByZXBsYWNlcyB0aGUgZGVzdGluYXRpb24gKFBvcnRlci1EdWZmIERlc3RpbmF0aW9uIEluCisgICAgICogU291cmNlIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERTVF9JTiA9IDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU1JDX09VVCBpbmRpY2F0ZXMgdGhhdCB0aGUgcGFydCBvZiB0aGUgc291cmNlIGx5aW5nIG91dHNpZGUKKyAgICAgKiBvZiB0aGUgZGVzdGluYXRpb24gcmVwbGFjZXMgdGhlIGRlc3RpbmF0aW9uIChQb3J0ZXItRHVmZiBTb3VyY2UgSGVsZCBPdXQKKyAgICAgKiBCeSBEZXN0aW5hdGlvbiBydWxlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUkNfT1VUID0gNzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBEU1RfT1VUIGluZGljYXRlcyB0aGF0IHRoZSBwYXJ0IG9mIHRoZSBkZXN0aW5hdGlvbiBseWluZworICAgICAqIG91dHNpZGUgb2YgdGhlIHNvdXJjZSByZXBsYWNlcyB0aGUgZGVzdGluYXRpb24gKFBvcnRlci1EdWZmIERlc3RpbmF0aW9uCisgICAgICogSGVsZCBPdXQgQnkgU291cmNlIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERTVF9PVVQgPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNSQ19BVE9QIGluZGljYXRlcyB0aGF0IHRoZSBwYXJ0IG9mIHRoZSBzb3VyY2UgbHlpbmcgaW5zaWRlCisgICAgICogb2YgdGhlIGRlc3RpbmF0aW9uIGlzIGNvbXBvc2l0ZWQgb250byB0aGUgZGVzdGluYXRpb24gKFBvcnRlci1EdWZmIFNvdXJjZQorICAgICAqIEF0b3AgRGVzdGluYXRpb24gcnVsZSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1JDX0FUT1AgPSAxMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBEU1RfQVRPUCBpbmRpY2F0ZXMgdGhhdCB0aGUgcGFydCBvZiB0aGUgZGVzdGluYXRpb24gbHlpbmcKKyAgICAgKiBpbnNpZGUgb2YgdGhlIHNvdXJjZSBpcyBjb21wb3NpdGVkIG92ZXIgdGhlIHNvdXJjZSBhbmQgcmVwbGFjZXMgdGhlCisgICAgICogZGVzdGluYXRpb24gKFBvcnRlci1EdWZmIERlc3RpbmF0aW9uIEF0b3AgU291cmNlIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERTVF9BVE9QID0gMTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgWE9SIGluZGljYXRlcyB0aGF0IHRoZSBwYXJ0IG9mIHRoZSBzb3VyY2UgdGhhdCBsaWVzIG91dHNpZGUKKyAgICAgKiBvZiB0aGUgZGVzdGluYXRpb24gaXMgY29tYmluZWQgd2l0aCB0aGUgcGFydCBvZiB0aGUgZGVzdGluYXRpb24gdGhhdCBsaWVzCisgICAgICogb3V0c2lkZSBvZiB0aGUgc291cmNlIChQb3J0ZXItRHVmZiBTb3VyY2UgWG9yIERlc3RpbmF0aW9uIHJ1bGUpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFhPUiA9IDEyOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBDTEVBUiBydWxlIGFuZCBhbiBhbHBoYSBvZiAxLjBmLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQWxwaGFDb21wb3NpdGUgQ2xlYXIgPSBuZXcgQWxwaGFDb21wb3NpdGUoQ0xFQVIpOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBTUkMgcnVsZSBhbmQgYW4gYWxwaGEgb2YgMS4wZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFscGhhQ29tcG9zaXRlIFNyYyA9IG5ldyBBbHBoYUNvbXBvc2l0ZShTUkMpOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBEU1QgcnVsZSBhbmQgYW4gYWxwaGEgb2YgMS4wZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFscGhhQ29tcG9zaXRlIERzdCA9IG5ldyBBbHBoYUNvbXBvc2l0ZShEU1QpOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBTUkNfT1ZFUiBydWxlIGFuZCBhbiBhbHBoYSBvZiAxLjBmLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQWxwaGFDb21wb3NpdGUgU3JjT3ZlciA9IG5ldyBBbHBoYUNvbXBvc2l0ZShTUkNfT1ZFUik7CisKKyAgICAvKioKKyAgICAgKiBBbHBoYUNvbXBvc2l0ZSBvYmplY3Qgd2l0aCB0aGUgb3BhcXVlIERTVF9PVkVSIHJ1bGUgYW5kIGFuIGFscGhhIG9mIDEuMGYuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBbHBoYUNvbXBvc2l0ZSBEc3RPdmVyID0gbmV3IEFscGhhQ29tcG9zaXRlKERTVF9PVkVSKTsKKworICAgIC8qKgorICAgICAqIEFscGhhQ29tcG9zaXRlIG9iamVjdCB3aXRoIHRoZSBvcGFxdWUgU1JDX0lOIHJ1bGUgYW5kIGFuIGFscGhhIG9mIDEuMGYuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBbHBoYUNvbXBvc2l0ZSBTcmNJbiA9IG5ldyBBbHBoYUNvbXBvc2l0ZShTUkNfSU4pOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBEU1RfSU4gcnVsZSBhbmQgYW4gYWxwaGEgb2YgMS4wZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFscGhhQ29tcG9zaXRlIERzdEluID0gbmV3IEFscGhhQ29tcG9zaXRlKERTVF9JTik7CisKKyAgICAvKioKKyAgICAgKiBBbHBoYUNvbXBvc2l0ZSBvYmplY3Qgd2l0aCB0aGUgb3BhcXVlIFNSQ19PVVQgcnVsZSBhbmQgYW4gYWxwaGEgb2YgMS4wZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFscGhhQ29tcG9zaXRlIFNyY091dCA9IG5ldyBBbHBoYUNvbXBvc2l0ZShTUkNfT1VUKTsKKworICAgIC8qKgorICAgICAqIEFscGhhQ29tcG9zaXRlIG9iamVjdCB3aXRoIHRoZSBvcGFxdWUgRFNUX09VVCBydWxlIGFuZCBhbiBhbHBoYSBvZiAxLjBmLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQWxwaGFDb21wb3NpdGUgRHN0T3V0ID0gbmV3IEFscGhhQ29tcG9zaXRlKERTVF9PVVQpOworCisgICAgLyoqCisgICAgICogQWxwaGFDb21wb3NpdGUgb2JqZWN0IHdpdGggdGhlIG9wYXF1ZSBTUkNfQVRPUCBydWxlIGFuZCBhbiBhbHBoYSBvZiAxLjBmLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQWxwaGFDb21wb3NpdGUgU3JjQXRvcCA9IG5ldyBBbHBoYUNvbXBvc2l0ZShTUkNfQVRPUCk7CisKKyAgICAvKioKKyAgICAgKiBBbHBoYUNvbXBvc2l0ZSBvYmplY3Qgd2l0aCB0aGUgb3BhcXVlIERTVF9BVE9QIHJ1bGUgYW5kIGFuIGFscGhhIG9mIDEuMGYuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBbHBoYUNvbXBvc2l0ZSBEc3RBdG9wID0gbmV3IEFscGhhQ29tcG9zaXRlKERTVF9BVE9QKTsKKworICAgIC8qKgorICAgICAqIEFscGhhQ29tcG9zaXRlIG9iamVjdCB3aXRoIHRoZSBvcGFxdWUgWE9SIHJ1bGUgYW5kIGFuIGFscGhhIG9mIDEuMGYuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBbHBoYUNvbXBvc2l0ZSBYb3IgPSBuZXcgQWxwaGFDb21wb3NpdGUoWE9SKTsKKworICAgIC8qKgorICAgICAqIFRoZSBydWxlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJ1bGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWxwaGEuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBhbHBoYTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBhbHBoYSBjb21wb3NpdGUuIENyZWF0ZXMgYSBjb250ZXh0IGZvciB0aGUgY29tcG9zaXRpbmcKKyAgICAgKiBvcGVyYXRpb24uIFRoZSBjb250ZXh0IGNvbnRhaW5zIHN0YXRlIHRoYXQgaXMgdXNlZCBpbiBwZXJmb3JtaW5nIHRoZQorICAgICAqIGNvbXBvc2l0aW5nIG9wZXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcnVsZQorICAgICAqICAgICAgICAgICAgdGhlIHJ1bGUuCisgICAgICogQHBhcmFtIGFscGhhCisgICAgICogICAgICAgICAgICB0aGUgYWxwaGEuCisgICAgICovCisgICAgcHJpdmF0ZSBBbHBoYUNvbXBvc2l0ZShpbnQgcnVsZSwgZmxvYXQgYWxwaGEpIHsKKyAgICAgICAgaWYgKHJ1bGUgPCBDTEVBUiB8fCBydWxlID4gWE9SKSB7CisgICAgICAgICAgICAvLyBhd3QuMTFEPVVua25vd24gcnVsZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMUQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxwaGEgPCAwLjBmIHx8IGFscGhhID4gMS4wZikgeworICAgICAgICAgICAgLy8gYXd0LjExRT1Xcm9uZyBhbHBoYSB2YWx1ZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMUUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMucnVsZSA9IHJ1bGU7CisgICAgICAgIHRoaXMuYWxwaGEgPSBhbHBoYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgYWxwaGEgY29tcG9zaXRlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBydWxlCisgICAgICogICAgICAgICAgICB0aGUgcnVsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFscGhhQ29tcG9zaXRlKGludCBydWxlKSB7CisgICAgICAgIHRoaXMocnVsZSwgMS4wZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIENvbXBvc2l0ZUNvbnRleHQgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBzb3VyY2UgQ29sb3JNb2RlbCwKKyAgICAgKiBkZXN0aW5hdGlvbiBDb2xvck1vZGVsIGFuZCBSZW5kZXJpbmdIaW50cyBwYXJhbWV0ZXJzIGZvciBhIGNvbXBvc2luZworICAgICAqIG9wZXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjQ29sb3JNb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSdzIENvbG9yTW9kZWwuCisgICAgICogQHBhcmFtIGRzdENvbG9yTW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbidzIENvbG9yTW9kZWwuCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgUmVuZGVyaW5nSGludHMgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIENvbXBvc2l0ZUNvbnRleHQgb2JqZWN0LgorICAgICAqIEBzZWUgamF2YS5hd3QuQ29tcG9zaXRlI2NyZWF0ZUNvbnRleHQoamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbCwKKyAgICAgKiAgICAgIGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWwsIGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzKQorICAgICAqLworICAgIHB1YmxpYyBDb21wb3NpdGVDb250ZXh0IGNyZWF0ZUNvbnRleHQoQ29sb3JNb2RlbCBzcmNDb2xvck1vZGVsLCBDb2xvck1vZGVsIGRzdENvbG9yTW9kZWwsCisgICAgICAgICAgICBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICByZXR1cm4gbmV3IElDb21wb3NpdGVDb250ZXh0KHRoaXMsIHNyY0NvbG9yTW9kZWwsIGRzdENvbG9yTW9kZWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBBbHBoYUNvbXBvc2l0ZSBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIEFscGhhQ29tcG9zaXRlIG9iamVjdCBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgQWxwaGFDb21wb3NpdGUpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgQWxwaGFDb21wb3NpdGUgb3RoZXIgPSAoQWxwaGFDb21wb3NpdGUpb2JqOworICAgICAgICByZXR1cm4gKHRoaXMucnVsZSA9PSBvdGhlci5nZXRSdWxlKCkgJiYgdGhpcy5hbHBoYSA9PSBvdGhlci5nZXRBbHBoYSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhlIEFscGhhQ29tcG9zaXRlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgb2YgdGhlIEFscGhhQ29tcG9zaXRlIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IEZsb2F0LmZsb2F0VG9JbnRCaXRzKGFscGhhKTsKKyAgICAgICAgaW50IHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBydWxlOworICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb21wb3NpdGluZyBydWxlIG9mIHRoaXMgQWxwaGFDb21wb3NpdGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNvbXBvc2l0aW5nIHJ1bGUgb2YgdGhpcyBBbHBoYUNvbXBvc2l0ZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSdWxlKCkgeworICAgICAgICByZXR1cm4gcnVsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhbHBoYSB2YWx1ZSBvZiB0aGlzIEFscGhhQ29tcG9zaXRlIG9iamVjdDsgcmV0dXJucyAxLjAgaWYgdGhpcworICAgICAqIEFscGhhQ29tcG9zaXRlIG9iamVjdCBkb2Vzbid0IGhhdmUgYWxwaGEgdmFsdWUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYWxwaGEgdmFsdWUgb2YgdGhpcyBBbHBoYUNvbXBvc2l0ZSBvYmplY3Qgb3IgMS4wIGlmIHRoaXMKKyAgICAgKiAgICAgICAgIEFscGhhQ29tcG9zaXRlIG9iamVjdCBkb2Vzbid0IGhhdmUgYWxwaGEgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEFscGhhKCkgeworICAgICAgICByZXR1cm4gYWxwaGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQWxwaGFDb21wb3NpdGUgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHJ1bGUgYW5kIGFscGhhIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBydWxlCisgICAgICogICAgICAgICAgICB0aGUgY29tcG9zaXRpbmcgcnVsZS4KKyAgICAgKiBAcGFyYW0gYWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbHBoYSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBBbHBoYUNvbXBvc2l0ZSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFscGhhQ29tcG9zaXRlIGdldEluc3RhbmNlKGludCBydWxlLCBmbG9hdCBhbHBoYSkgeworICAgICAgICBpZiAoYWxwaGEgPT0gMS4wZikgeworICAgICAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKHJ1bGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQWxwaGFDb21wb3NpdGUocnVsZSwgYWxwaGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEFscGhhQ29tcG9zaXRlIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBydWxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBydWxlCisgICAgICogICAgICAgICAgICB0aGUgY29tcG9zaXRpbmcgcnVsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBBbHBoYUNvbXBvc2l0ZSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFscGhhQ29tcG9zaXRlIGdldEluc3RhbmNlKGludCBydWxlKSB7CisgICAgICAgIHN3aXRjaCAocnVsZSkgeworICAgICAgICAgICAgY2FzZSBDTEVBUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ2xlYXI7CisgICAgICAgICAgICBjYXNlIFNSQzoKKyAgICAgICAgICAgICAgICByZXR1cm4gU3JjOworICAgICAgICAgICAgY2FzZSBEU1Q6CisgICAgICAgICAgICAgICAgcmV0dXJuIERzdDsKKyAgICAgICAgICAgIGNhc2UgU1JDX09WRVI6CisgICAgICAgICAgICAgICAgcmV0dXJuIFNyY092ZXI7CisgICAgICAgICAgICBjYXNlIERTVF9PVkVSOgorICAgICAgICAgICAgICAgIHJldHVybiBEc3RPdmVyOworICAgICAgICAgICAgY2FzZSBTUkNfSU46CisgICAgICAgICAgICAgICAgcmV0dXJuIFNyY0luOworICAgICAgICAgICAgY2FzZSBEU1RfSU46CisgICAgICAgICAgICAgICAgcmV0dXJuIERzdEluOworICAgICAgICAgICAgY2FzZSBTUkNfT1VUOgorICAgICAgICAgICAgICAgIHJldHVybiBTcmNPdXQ7CisgICAgICAgICAgICBjYXNlIERTVF9PVVQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIERzdE91dDsKKyAgICAgICAgICAgIGNhc2UgU1JDX0FUT1A6CisgICAgICAgICAgICAgICAgcmV0dXJuIFNyY0F0b3A7CisgICAgICAgICAgICBjYXNlIERTVF9BVE9QOgorICAgICAgICAgICAgICAgIHJldHVybiBEc3RBdG9wOworICAgICAgICAgICAgY2FzZSBYT1I6CisgICAgICAgICAgICAgICAgcmV0dXJuIFhvcjsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjExRD1Vbmtub3duIHJ1bGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjExRCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQmFzaWNTdHJva2UuamF2YSBiL2F3dC9qYXZhL2F3dC9CYXNpY1N0cm9rZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0NTc4MTUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQmFzaWNTdHJva2UuamF2YQpAQCAtMCwwICsxLDI0NDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5HZW5lcmFsUGF0aDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5taXNjLkhhc2hDb2RlOworCisvKioKKyAqIFRoZSBCYXNpY1N0cm9rZSBjbGFzcyBzcGVjaWZpZXMgYSBzZXQgb2YgcmVuZGVyaW5nIGF0dHJpYnV0ZXMgZm9yIHRoZQorICogb3V0bGluZXMgb2YgZ3JhcGhpY3MgcHJpbWl0aXZlcy4gVGhlIEJhc2ljU3Ryb2tlIGF0dHJpYnV0ZXMgZGVzY3JpYmUgdGhlCisgKiBzaGFwZSBvZiB0aGUgcGVuIHdoaWNoIGRyYXdzIHRoZSBvdXRsaW5lIG9mIGEgU2hhcGUgYW5kIHRoZSBkZWNvcmF0aW9ucworICogYXBwbGllZCBhdCB0aGUgZW5kcyBhbmQgam9pbnMgb2YgcGF0aCBzZWdtZW50cyBvZiB0aGUgU2hhcGUuIFRoZSBCYXNpY1N0cm9rZQorICogaGFzIHRoZSBmb2xsb3dpbmcgcmVuZGVyaW5nIGF0dHJpYnV0ZXM6CisgKiA8cD4KKyAqIDx1bD4KKyAqIDxsaT5saW5lIHdpZHRoIC10aGUgcGVuIHdpZHRoIHdoaWNoIGRyYXdzIHRoZSBvdXRsaW5lcy48L2xpPgorICogPGxpPmVuZCBjYXBzIC0gaW5kaWNhdGVzIHRoZSBkZWNvcmF0aW9uIGFwcGxpZWQgdG8gdGhlIGVuZHMgb2YgdW5jbG9zZWQKKyAqIHN1YnBhdGhzIGFuZCBkYXNoIHNlZ21lbnRzLiBUaGUgQmFzaWNTdHJva2UgZGVmaW5lcyB0aHJlZSBkaWZmZXJlbnQKKyAqIGRlY29yYXRpb25zOiBDQVBfQlVUVCwgQ0FQX1JPVU5ELCBhbmQgQ0FQX1NRVUFSRS48L2xpPgorICogPGxpPmxpbmUgam9pbnMgLSBpbmRpY2F0ZXMgdGhlIGRlY29yYXRpb24gYXBwbGllZCBhdCB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3bworICogcGF0aCBzZWdtZW50cyBhbmQgYXQgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgZW5kcG9pbnRzIG9mIGEgc3VicGF0aC4gVGhlCisgKiBCYXNpY1N0cm9rZSBkZWZpbmVzIHRocmVlIGRlY29yYXRpb25zOiBKT0lOX0JFVkVMLCBKT0lOX01JVEVSLCBhbmQKKyAqIEpPSU5fUk9VTkQuPC9saT4KKyAqIDxsaT5taXRlciBsaW1pdCAtIHRoZSBsaW1pdCB0byB0cmltIGEgbGluZSBqb2luIHRoYXQgaGFzIGEgSk9JTl9NSVRFUgorICogZGVjb3JhdGlvbi48L2xpPgorICogPGxpPmRhc2ggYXR0cmlidXRlcyAtIHRoZSBkZWZpbml0aW9uIG9mIGhvdyB0byBtYWtlIGEgZGFzaCBwYXR0ZXJuIGJ5CisgKiBhbHRlcm5hdGluZyBiZXR3ZWVuIG9wYXF1ZSBhbmQgdHJhbnNwYXJlbnQgc2VjdGlvbnM8L2xpPgorICogPC91bD4KKyAqIDwvcD4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBCYXNpY1N0cm9rZSBpbXBsZW1lbnRzIFN0cm9rZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0FQX0JVVFQgaW5kaWNhdGVzIHRoZSBlbmRzIG9mIHVuY2xvc2VkIHN1YnBhdGhzIGFuZCBkYXNoCisgICAgICogc2VnbWVudHMgaGF2ZSBubyBhZGRlZCBkZWNvcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENBUF9CVVRUID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDQVBfUk9VTkQgaW5kaWNhdGVzIHRoZSBlbmRzIG9mIHVuY2xvc2VkIHN1YnBhdGhzIGFuZCBkYXNoCisgICAgICogc2VnbWVudHMgaGF2ZSBhIHJvdW5kIGRlY29yYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FQX1JPVU5EID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDQVBfU1FVQVJFIGluZGljYXRlcyB0aGUgZW5kcyBvZiB1bmNsb3NlZCBzdWJwYXRocyBhbmQgZGFzaAorICAgICAqIHNlZ21lbnRzIGhhdmUgYSBzcXVhcmUgcHJvamVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQVBfU1FVQVJFID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBKT0lOX01JVEVSIGluZGljYXRlcyB0aGF0IHBhdGggc2VnbWVudHMgYXJlIGpvaW5lZCBieQorICAgICAqIGV4dGVuZGluZyB0aGVpciBvdXRzaWRlIGVkZ2VzIHVudGlsIHRoZXkgbWVldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKT0lOX01JVEVSID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBKT0lOX1JPVU5EIGluZGljYXRlcyB0aGF0IHBhdGggc2VnbWVudHMgYXJlIGpvaW5lZCBieQorICAgICAqIHJvdW5kaW5nIG9mZiB0aGUgY29ybmVyIGF0IGEgcmFkaXVzIG9mIGhhbGYgdGhlIGxpbmUgd2lkdGguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSk9JTl9ST1VORCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSk9JTl9CRVZFTCBpbmRpY2F0ZXMgdGhhdCBwYXRoIHNlZ21lbnRzIGFyZSBqb2luZWQgYnkKKyAgICAgKiBjb25uZWN0aW5nIHRoZSBvdXRlciBjb3JuZXJzIG9mIHRoZWlyIHdpZGUgb3V0bGluZXMgd2l0aCBhIHN0cmFpZ2h0CisgICAgICogc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKT0lOX0JFVkVMID0gMjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50cyBmb3IgY2FsY3VsYXRpbmcuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBNQVhfTEVWRUwgPSAyMDsgLy8gTWF4aW1hbCBkZWVwbmVzcyBvZiBjdXJ2ZSBzdWJkaXZpc2lvbgorCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENVUlZFX0RFTFRBLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBkb3VibGUgQ1VSVkVfREVMVEEgPSAyLjA7IC8vIFdpZHRoIHRvbGVyYW5jZQorCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENPUk5FUl9BTkdMRS4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIENPUk5FUl9BTkdMRSA9IDQuMDsgLy8gTWluaW11bSBjb3JuZXIgYW5nbGUKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDT1JORVJfWkVSTy4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIENPUk5FUl9aRVJPID0gMC4wMTsgLy8gWmVybyBhbmdsZQorCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENVQklDX0FSQy4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIENVQklDX0FSQyA9IDQuMCAvIDMuMCAqIChNYXRoLnNxcnQoMi4wKSAtIDEpOworCisgICAgLyoqCisgICAgICogU3Ryb2tlIHdpZHRoLgorICAgICAqLworICAgIGZsb2F0IHdpZHRoOworCisgICAgLyoqCisgICAgICogU3Ryb2tlIGNhcCB0eXBlLgorICAgICAqLworICAgIGludCBjYXA7CisKKyAgICAvKioKKyAgICAgKiBTdHJva2Ugam9pbiB0eXBlLgorICAgICAqLworICAgIGludCBqb2luOworCisgICAgLyoqCisgICAgICogU3Ryb2tlIG1pdGVyIGxpbWl0LgorICAgICAqLworICAgIGZsb2F0IG1pdGVyTGltaXQ7CisKKyAgICAvKioKKyAgICAgKiBTdHJva2UgZGFzaGVzIGFycmF5LgorICAgICAqLworICAgIGZsb2F0IGRhc2hbXTsKKworICAgIC8qKgorICAgICAqIFN0cm9rZSBkYXNoIHBoYXNlLgorICAgICAqLworICAgIGZsb2F0IGRhc2hQaGFzZTsKKworICAgIC8qKgorICAgICAqIFRoZSB0ZW1wb3JhcnkgcHJlLWNhbGN1bGF0ZWQgdmFsdWVzLgorICAgICAqLworICAgIGRvdWJsZSBjdXJ2ZURlbHRhOworCisgICAgLyoqCisgICAgICogVGhlIGNvcm5lciBkZWx0YS4KKyAgICAgKi8KKyAgICBkb3VibGUgY29ybmVyRGVsdGE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgemVybyBkZWx0YS4KKyAgICAgKi8KKyAgICBkb3VibGUgemVyb0RlbHRhOworCisgICAgLyoqCisgICAgICogVGhlIHcyLgorICAgICAqLworICAgIGRvdWJsZSB3MjsKKworICAgIC8qKgorICAgICAqIFRoZSBmbXkuCisgICAgICovCisgICAgZG91YmxlIGZteCwgZm15OworCisgICAgLyoqCisgICAgICogVGhlIHNteS4KKyAgICAgKi8KKyAgICBkb3VibGUgc2N4LCBzY3ksIHNteCwgc215OworCisgICAgLyoqCisgICAgICogVGhlIGN5LgorICAgICAqLworICAgIGRvdWJsZSBteCwgbXksIGN4LCBjeTsKKworICAgIC8qKgorICAgICAqIFRoZSB0ZW1wb3JhcnkgaW5kaWNhdG9ycy4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzTW92ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBpcyBmaXJzdC4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzRmlyc3Q7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2hlY2sgbW92ZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGNoZWNrTW92ZTsKKworICAgIC8qKgorICAgICAqIFRoZSB0ZW1wb3JhcnkgYW5kIGRlc3RpbmF0aW9uIHdvcmsgcGF0aHMuCisgICAgICovCisgICAgQnVmZmVyZWRQYXRoIGRzdCwgbHAsIHJwLCBzcDsKKworICAgIC8qKgorICAgICAqIFN0cm9rZSBkYXNoZXIgY2xhc3MuCisgICAgICovCisgICAgRGFzaGVyIGRhc2hlcjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCYXNpY1N0cm9rZSB3aXRoIGRlZmF1bHQgd2lkdGgsIGNhcCwgam9pbiwgbGltaXQsIGRhc2gKKyAgICAgKiBhdHRyaWJ1dGVzIHBhcmFtZXRlcnMuIFRoZSBkZWZhdWx0IHBhcmFtZXRlcnMgYXJlIGEgc29saWQgbGluZSBvZiB3aWR0aAorICAgICAqIDEuMCwgQ0FQX1NRVUFSRSwgSk9JTl9NSVRFUiwgYSBtaXRlciBsaW1pdCBvZiAxMC4wLCBudWxsIGRhc2ggYXR0cmlidXRlcywKKyAgICAgKiBhbmQgYSBkYXNoIHBoYXNlIG9mIDAuMGYuCisgICAgICovCisgICAgcHVibGljIEJhc2ljU3Ryb2tlKCkgeworICAgICAgICB0aGlzKDEuMGYsIENBUF9TUVVBUkUsIEpPSU5fTUlURVIsIDEwLjBmLCBudWxsLCAwLjBmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQmFzaWNTdHJva2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHdpZHRoLCBjYXBzLCBqb2lucywKKyAgICAgKiBsaW1pdCwgZGFzaCBhdHRyaWJ1dGVzLCBkYXNoIHBoYXNlIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgQmFzaWtTdHJva2UuCisgICAgICogQHBhcmFtIGNhcAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBkZWNvcmF0aW9uIG9mIEJhc2lrU3Ryb2tlLgorICAgICAqIEBwYXJhbSBqb2luCisgICAgICogICAgICAgICAgICB0aGUgam9pbiBzZWdtZW50cyBkZWNvcmF0aW9uLgorICAgICAqIEBwYXJhbSBtaXRlckxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbGltaXQgdG8gdHJpbSB0aGUgbWl0ZXIgam9pbi4KKyAgICAgKiBAcGFyYW0gZGFzaAorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdpdGggdGhlIGRhc2hpbmcgcGF0dGVybi4KKyAgICAgKiBAcGFyYW0gZGFzaFBoYXNlCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHRoZSBkYXNoaW5nIHBhdHRlcm4uCisgICAgICovCisgICAgcHVibGljIEJhc2ljU3Ryb2tlKGZsb2F0IHdpZHRoLCBpbnQgY2FwLCBpbnQgam9pbiwgZmxvYXQgbWl0ZXJMaW1pdCwgZmxvYXRbXSBkYXNoLAorICAgICAgICAgICAgZmxvYXQgZGFzaFBoYXNlKSB7CisgICAgICAgIGlmICh3aWR0aCA8IDAuMGYpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xMzM9TmVnYXRpdmUgd2lkdGgKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTMzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhcCAhPSBDQVBfQlVUVCAmJiBjYXAgIT0gQ0FQX1JPVU5EICYmIGNhcCAhPSBDQVBfU1FVQVJFKSB7CisgICAgICAgICAgICAvLyBhd3QuMTM0PUlsbGVnYWwgY2FwCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmIChqb2luICE9IEpPSU5fTUlURVIgJiYgam9pbiAhPSBKT0lOX1JPVU5EICYmIGpvaW4gIT0gSk9JTl9CRVZFTCkgeworICAgICAgICAgICAgLy8gYXd0LjEzNT1JbGxlZ2FsIGpvaW4KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTM1IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKGpvaW4gPT0gSk9JTl9NSVRFUiAmJiBtaXRlckxpbWl0IDwgMS4wZikgeworICAgICAgICAgICAgLy8gYXd0LjEzNj1taXRlckxpbWl0IGxlc3MgdGhhbiAxLjBmCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmIChkYXNoICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChkYXNoUGhhc2UgPCAwLjBmKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjEzNz1OZWdhdGl2ZSBkYXNoUGhhc2UKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzNyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGRhc2gubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTM4PVplcm8gZGFzaCBsZW5ndGgKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzOCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgWkVSTzogeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGFzaC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZGFzaFtpXSA8IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjEzOT1OZWdhdGl2ZSBkYXNoW3swfV0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTM5IiwgaSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGRhc2hbaV0gPiAwLjApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIFpFUk87CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gYXd0LjEzQT1BbGwgZGFzaCBsZW5ndGhzIHplcm8KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzQSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5jYXAgPSBjYXA7CisgICAgICAgIHRoaXMuam9pbiA9IGpvaW47CisgICAgICAgIHRoaXMubWl0ZXJMaW1pdCA9IG1pdGVyTGltaXQ7CisgICAgICAgIHRoaXMuZGFzaCA9IGRhc2g7CisgICAgICAgIHRoaXMuZGFzaFBoYXNlID0gZGFzaFBoYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCYXNpY1N0cm9rZSB3aXRoIHNwZWNpZmllZCB3aWR0aCwgY2FwLCBqb2luLCBsaW1pdCBhbmQKKyAgICAgKiBkZWZhdWx0IGRhc2ggYXR0cmlidXRlcyBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIEJhc2lrU3Ryb2tlLgorICAgICAqIEBwYXJhbSBjYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgZGVjb3JhdGlvbiBvZiBCYXNpa1N0cm9rZS4KKyAgICAgKiBAcGFyYW0gam9pbgorICAgICAqICAgICAgICAgICAgdGhlIGpvaW4gc2VnbWVudHMgZGVjb3JhdGlvbi4KKyAgICAgKiBAcGFyYW0gbWl0ZXJMaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGxpbWl0IHRvIHRyaW0gdGhlIG1pdGVyIGpvaW4uCisgICAgICovCisgICAgcHVibGljIEJhc2ljU3Ryb2tlKGZsb2F0IHdpZHRoLCBpbnQgY2FwLCBpbnQgam9pbiwgZmxvYXQgbWl0ZXJMaW1pdCkgeworICAgICAgICB0aGlzKHdpZHRoLCBjYXAsIGpvaW4sIG1pdGVyTGltaXQsIG51bGwsIDAuMGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCYXNpY1N0cm9rZSB3aXRoIHNwZWNpZmllZCB3aWR0aCwgY2FwLCBqb2luIGFuZAorICAgICAqIGRlZmF1bHQgbGltaXQgYW5kIGRhc2ggYXR0cmlidXRlcyBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIEJhc2lrU3Ryb2tlLgorICAgICAqIEBwYXJhbSBjYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgZGVjb3JhdGlvbiBvZiBCYXNpa1N0cm9rZS4KKyAgICAgKiBAcGFyYW0gam9pbgorICAgICAqICAgICAgICAgICAgdGhlIGpvaW4gc2VnbWVudHMgZGVjb3JhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmFzaWNTdHJva2UoZmxvYXQgd2lkdGgsIGludCBjYXAsIGludCBqb2luKSB7CisgICAgICAgIHRoaXMod2lkdGgsIGNhcCwgam9pbiwgMTAuMGYsIG51bGwsIDAuMGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCYXNpY1N0cm9rZSB3aXRoIHNwZWNpZmllZCB3aWR0aCBhbmQgZGVmYXVsdCBjYXAsCisgICAgICogam9pbiwgbGltaXQsIGRhc2ggYXR0cmlidXRlcyBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIEJhc2ljU3Ryb2tlLgorICAgICAqLworICAgIHB1YmxpYyBCYXNpY1N0cm9rZShmbG9hdCB3aWR0aCkgeworICAgICAgICB0aGlzKHdpZHRoLCBDQVBfU1FVQVJFLCBKT0lOX01JVEVSLCAxMC4wZiwgbnVsbCwgMC4wZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbGluZSB3aWR0aCBvZiB0aGUgQmFzaWNTdHJva2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbGluZSB3aWR0aCBvZiB0aGUgQmFzaWNTdHJva2UuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldExpbmVXaWR0aCgpIHsKKyAgICAgICAgcmV0dXJuIHdpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuZCBjYXAgc3R5bGUgb2YgdGhlIEJhc2ljU3Ryb2tlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGVuZCBjYXAgc3R5bGUgb2YgdGhlIEJhc2ljU3Ryb2tlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RW5kQ2FwKCkgeworICAgICAgICByZXR1cm4gY2FwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxpbmUgam9pbiBzdHlsZSBvZiB0aGUgQmFzaWNTdHJva2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbGluZSBqb2luIHN0eWxlIG9mIHRoZSBCYXNpY1N0cm9rZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVKb2luKCkgeworICAgICAgICByZXR1cm4gam9pbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaXRlciBsaW1pdCBvZiB0aGUgQmFzaWNTdHJva2UgKHRoZSBsaW1pdCB0byB0cmltIHRoZSBtaXRlcgorICAgICAqIGpvaW4pLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1pdGVyIGxpbWl0IG9mIHRoZSBCYXNpY1N0cm9rZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWl0ZXJMaW1pdCgpIHsKKyAgICAgICAgcmV0dXJuIG1pdGVyTGltaXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGFzaCBhdHRyaWJ1dGVzIGFycmF5IG9mIHRoZSBCYXNpY1N0cm9rZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkYXNoIGF0dHJpYnV0ZXMgYXJyYXkgb2YgdGhlIEJhc2ljU3Ryb2tlLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldERhc2hBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGRhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGFzaCBwaGFzZSBvZiB0aGUgQmFzaWNTdHJva2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGFzaCBwaGFzZSBvZiB0aGUgQmFzaWNTdHJva2UuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldERhc2hQaGFzZSgpIHsKKyAgICAgICAgcmV0dXJuIGRhc2hQaGFzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhhc2ggY29kZSBvZiB0aGlzIEJhc2ljU3Ryb2tlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBvZiB0aGlzIEJhc2ljU3Ryb2tlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIEhhc2hDb2RlIGhhc2ggPSBuZXcgSGFzaENvZGUoKTsKKyAgICAgICAgaGFzaC5hcHBlbmQod2lkdGgpOworICAgICAgICBoYXNoLmFwcGVuZChjYXApOworICAgICAgICBoYXNoLmFwcGVuZChqb2luKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobWl0ZXJMaW1pdCk7CisgICAgICAgIGlmIChkYXNoICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhhc2guYXBwZW5kKGRhc2hQaGFzZSk7CisgICAgICAgICAgICBmb3IgKGZsb2F0IGVsZW1lbnQgOiBkYXNoKSB7CisgICAgICAgICAgICAgICAgaGFzaC5hcHBlbmQoZWxlbWVudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2guaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIEJhc2ljU3Ryb2tlIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgT2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgT2JqZWN0IGlzIGEgQmFzaWNTdHJva2Ugd2l0aCB0aGUgc2FtZSBkYXRhIHZhbHVlcyBhcworICAgICAqICAgICAgICAgdGhpcyBCYXNpY1N0cm9rZTsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEJhc2ljU3Ryb2tlKSB7CisgICAgICAgICAgICBCYXNpY1N0cm9rZSBicyA9IChCYXNpY1N0cm9rZSlvYmo7CisgICAgICAgICAgICByZXR1cm4gYnMud2lkdGggPT0gd2lkdGggJiYgYnMuY2FwID09IGNhcCAmJiBicy5qb2luID09IGpvaW4KKyAgICAgICAgICAgICAgICAgICAgJiYgYnMubWl0ZXJMaW1pdCA9PSBtaXRlckxpbWl0ICYmIGJzLmRhc2hQaGFzZSA9PSBkYXNoUGhhc2UKKyAgICAgICAgICAgICAgICAgICAgJiYgamF2YS51dGlsLkFycmF5cy5lcXVhbHMoYnMuZGFzaCwgZGFzaCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgYWxsb3dhYmxlIGN1cnZlIGRlcml2YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGguCisgICAgICogQHJldHVybiB0aGUgY3VydmUgZGVsdGEuCisgICAgICovCisgICAgZG91YmxlIGdldEN1cnZlRGVsdGEoZG91YmxlIHdpZHRoKSB7CisgICAgICAgIGRvdWJsZSBhID0gd2lkdGggKyBDVVJWRV9ERUxUQTsKKyAgICAgICAgZG91YmxlIGNvcyA9IDEuMCAtIDIuMCAqIHdpZHRoICogd2lkdGggLyAoYSAqIGEpOworICAgICAgICBkb3VibGUgc2luID0gTWF0aC5zcXJ0KDEuMCAtIGNvcyAqIGNvcyk7CisgICAgICAgIHJldHVybiBNYXRoLmFicyhzaW4gLyBjb3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgdGhlIHZhbHVlIHRvIGRldGVjdCBhIHNtYWxsIGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoLgorICAgICAqIEByZXR1cm4gdGhlIGNvcm5lciBkZWx0YS4KKyAgICAgKi8KKyAgICBkb3VibGUgZ2V0Q29ybmVyRGVsdGEoZG91YmxlIHdpZHRoKSB7CisgICAgICAgIHJldHVybiB3aWR0aCAqIHdpZHRoICogTWF0aC5zaW4oTWF0aC5QSSAqIENPUk5FUl9BTkdMRSAvIDE4MC4wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHZhbHVlIHRvIGRldGVjdCBhIHplcm8gYW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGguCisgICAgICogQHJldHVybiB0aGUgemVybyBkZWx0YS4KKyAgICAgKi8KKyAgICBkb3VibGUgZ2V0WmVyb0RlbHRhKGRvdWJsZSB3aWR0aCkgeworICAgICAgICByZXR1cm4gd2lkdGggKiB3aWR0aCAqIE1hdGguc2luKE1hdGguUEkgKiBDT1JORVJfWkVSTyAvIDE4MC4wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgU2hhcGUgZnJvbSB0aGUgb3V0bGluZSBvZiB0aGUgc3BlY2lmaWVkIHNoYXBlIGRyYXduIHdpdGggdGhpcworICAgICAqIEJhc2ljU3Ryb2tlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFNoYXBlIHRvIGJlIHN0cm9rZWQuCisgICAgICogQHJldHVybiB0aGUgU2hhcGUgb2YgdGhlIHN0cm9rZWQgb3V0bGluZS4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlN0cm9rZSNjcmVhdGVTdHJva2VkU2hhcGUoamF2YS5hd3QuU2hhcGUpCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGNyZWF0ZVN0cm9rZWRTaGFwZShTaGFwZSBzKSB7CisgICAgICAgIHcyID0gd2lkdGggLyAyLjA7CisgICAgICAgIGN1cnZlRGVsdGEgPSBnZXRDdXJ2ZURlbHRhKHcyKTsKKyAgICAgICAgY29ybmVyRGVsdGEgPSBnZXRDb3JuZXJEZWx0YSh3Mik7CisgICAgICAgIHplcm9EZWx0YSA9IGdldFplcm9EZWx0YSh3Mik7CisKKyAgICAgICAgZHN0ID0gbmV3IEJ1ZmZlcmVkUGF0aCgpOworICAgICAgICBscCA9IG5ldyBCdWZmZXJlZFBhdGgoKTsKKyAgICAgICAgcnAgPSBuZXcgQnVmZmVyZWRQYXRoKCk7CisKKyAgICAgICAgaWYgKGRhc2ggPT0gbnVsbCkgeworICAgICAgICAgICAgY3JlYXRlU29saWRTaGFwZShzLmdldFBhdGhJdGVyYXRvcihudWxsKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjcmVhdGVEYXNoZWRTaGFwZShzLmdldFBhdGhJdGVyYXRvcihudWxsKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZHN0LmNyZWF0ZUdlbmVyYWxQYXRoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEgc2hhcGUgd2l0aCBhIHNvbGlkIChub3QgZGFzaGVkKSBvdXRsaW5lLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgUGF0aEl0ZXJhdG9yIG9mIHNvdXJjZSBzaGFwZS4KKyAgICAgKi8KKyAgICB2b2lkIGNyZWF0ZVNvbGlkU2hhcGUoUGF0aEl0ZXJhdG9yIHApIHsKKyAgICAgICAgZG91YmxlIGNvb3Jkc1tdID0gbmV3IGRvdWJsZVs2XTsKKyAgICAgICAgbXggPSBteSA9IGN4ID0gY3kgPSAwLjA7CisgICAgICAgIGlzTW92ZSA9IGZhbHNlOworICAgICAgICBpc0ZpcnN0ID0gZmFsc2U7CisgICAgICAgIGNoZWNrTW92ZSA9IHRydWU7CisgICAgICAgIGJvb2xlYW4gaXNDbG9zZWQgPSB0cnVlOworCisgICAgICAgIHdoaWxlICghcC5pc0RvbmUoKSkgeworICAgICAgICAgICAgc3dpdGNoIChwLmN1cnJlbnRTZWdtZW50KGNvb3JkcykpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTU9WRVRPOgorICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ2xvc2VkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZVNvbGlkU2hhcGUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBycC5jbGVhbigpOworICAgICAgICAgICAgICAgICAgICBteCA9IGN4ID0gY29vcmRzWzBdOworICAgICAgICAgICAgICAgICAgICBteSA9IGN5ID0gY29vcmRzWzFdOworICAgICAgICAgICAgICAgICAgICBpc01vdmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBpc0Nsb3NlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTElORVRPOgorICAgICAgICAgICAgICAgICAgICBhZGRMaW5lKGN4LCBjeSwgY3ggPSBjb29yZHNbMF0sIGN5ID0gY29vcmRzWzFdLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX1FVQURUTzoKKyAgICAgICAgICAgICAgICAgICAgYWRkUXVhZChjeCwgY3ksIGNvb3Jkc1swXSwgY29vcmRzWzFdLCBjeCA9IGNvb3Jkc1syXSwgY3kgPSBjb29yZHNbM10pOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ1VCSUNUTzoKKyAgICAgICAgICAgICAgICAgICAgYWRkQ3ViaWMoY3gsIGN5LCBjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10sIGN4ID0gY29vcmRzWzRdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5ID0gY29vcmRzWzVdKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0NMT1NFOgorICAgICAgICAgICAgICAgICAgICBhZGRMaW5lKGN4LCBjeSwgbXgsIG15LCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIGFkZEpvaW4obHAsIG14LCBteSwgbHAueE1vdmUsIGxwLnlNb3ZlLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgYWRkSm9pbihycCwgbXgsIG15LCBycC54TW92ZSwgcnAueU1vdmUsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgbHAuY2xvc2VQYXRoKCk7CisgICAgICAgICAgICAgICAgICAgIHJwLmNsb3NlUGF0aCgpOworICAgICAgICAgICAgICAgICAgICBscC5hcHBlbmRSZXZlcnNlKHJwKTsKKyAgICAgICAgICAgICAgICAgICAgaXNDbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHAubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGlmICghaXNDbG9zZWQpIHsKKyAgICAgICAgICAgIGNsb3NlU29saWRTaGFwZSgpOworICAgICAgICB9CisKKyAgICAgICAgZHN0ID0gbHA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHNvbGlkIHNoYXBlIHBhdGguCisgICAgICovCisgICAgdm9pZCBjbG9zZVNvbGlkU2hhcGUoKSB7CisgICAgICAgIGFkZENhcChscCwgY3gsIGN5LCBycC54TGFzdCwgcnAueUxhc3QpOworICAgICAgICBscC5jb21iaW5lKHJwKTsKKyAgICAgICAgYWRkQ2FwKGxwLCBteCwgbXksIGxwLnhNb3ZlLCBscC55TW92ZSk7CisgICAgICAgIGxwLmNsb3NlUGF0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBkYXNoZWQgc3Ryb2tlZCBzaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBhdGhJdGVyYXRvciBvZiBzb3VyY2Ugc2hhcGUuCisgICAgICovCisgICAgdm9pZCBjcmVhdGVEYXNoZWRTaGFwZShQYXRoSXRlcmF0b3IgcCkgeworICAgICAgICBkb3VibGUgY29vcmRzW10gPSBuZXcgZG91YmxlWzZdOworICAgICAgICBteCA9IG15ID0gY3ggPSBjeSA9IDAuMDsKKyAgICAgICAgc214ID0gc215ID0gc2N4ID0gc2N5ID0gMC4wOworICAgICAgICBpc01vdmUgPSBmYWxzZTsKKyAgICAgICAgY2hlY2tNb3ZlID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gaXNDbG9zZWQgPSB0cnVlOworCisgICAgICAgIHdoaWxlICghcC5pc0RvbmUoKSkgeworICAgICAgICAgICAgc3dpdGNoIChwLmN1cnJlbnRTZWdtZW50KGNvb3JkcykpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTU9WRVRPOgorCisgICAgICAgICAgICAgICAgICAgIGlmICghaXNDbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlRGFzaGVkU2hhcGUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGRhc2hlciA9IG5ldyBEYXNoZXIoZGFzaCwgZGFzaFBoYXNlKTsKKyAgICAgICAgICAgICAgICAgICAgbHAuY2xlYW4oKTsKKyAgICAgICAgICAgICAgICAgICAgcnAuY2xlYW4oKTsKKyAgICAgICAgICAgICAgICAgICAgc3AgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaXNNb3ZlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaXNDbG9zZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgbXggPSBjeCA9IGNvb3Jkc1swXTsKKyAgICAgICAgICAgICAgICAgICAgbXkgPSBjeSA9IGNvb3Jkc1sxXTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0xJTkVUTzoKKyAgICAgICAgICAgICAgICAgICAgYWRkRGFzaExpbmUoY3gsIGN5LCBjeCA9IGNvb3Jkc1swXSwgY3kgPSBjb29yZHNbMV0pOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfUVVBRFRPOgorICAgICAgICAgICAgICAgICAgICBhZGREYXNoUXVhZChjeCwgY3ksIGNvb3Jkc1swXSwgY29vcmRzWzFdLCBjeCA9IGNvb3Jkc1syXSwgY3kgPSBjb29yZHNbM10pOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ1VCSUNUTzoKKyAgICAgICAgICAgICAgICAgICAgYWRkRGFzaEN1YmljKGN4LCBjeSwgY29vcmRzWzBdLCBjb29yZHNbMV0sIGNvb3Jkc1syXSwgY29vcmRzWzNdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN4ID0gY29vcmRzWzRdLCBjeSA9IGNvb3Jkc1s1XSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DTE9TRToKKyAgICAgICAgICAgICAgICAgICAgYWRkRGFzaExpbmUoY3gsIGN5LCBjeCA9IG14LCBjeSA9IG15KTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoZGFzaGVyLmlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbm5lY3QgY3VycmVudCBhbmQgaGVhZCBzZWdtZW50cworICAgICAgICAgICAgICAgICAgICAgICAgYWRkSm9pbihscCwgZm14LCBmbXksIHNwLnhNb3ZlLCBzcC55TW92ZSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBscC5qb2luKHNwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZEpvaW4obHAsIGZteCwgZm15LCBycC54TGFzdCwgcnAueUxhc3QsIHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgbHAuY29tYmluZShycCk7CisgICAgICAgICAgICAgICAgICAgICAgICBhZGRDYXAobHAsIHNteCwgc215LCBscC54TW92ZSwgbHAueU1vdmUpOworICAgICAgICAgICAgICAgICAgICAgICAgbHAuY2xvc2VQYXRoKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYXBwZW5kKGxwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNwID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlRGFzaGVkU2hhcGUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwLm5leHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghaXNDbG9zZWQpIHsKKyAgICAgICAgICAgIGNsb3NlRGFzaGVkU2hhcGUoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIGRhc2hlZCBzaGFwZSBwYXRoLgorICAgICAqLworICAgIHZvaWQgY2xvc2VEYXNoZWRTaGFwZSgpIHsKKyAgICAgICAgLy8gQWRkIGhlYWQgc2VnbWVudAorICAgICAgICBpZiAoc3AgIT0gbnVsbCkgeworICAgICAgICAgICAgYWRkQ2FwKHNwLCBmbXgsIGZteSwgc3AueE1vdmUsIHNwLnlNb3ZlKTsKKyAgICAgICAgICAgIHNwLmNsb3NlUGF0aCgpOworICAgICAgICAgICAgZHN0LmFwcGVuZChzcCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxwLnR5cGVTaXplID4gMCkgeworICAgICAgICAgICAgLy8gQ2xvc2UgY3VycmVudCBzZWdtZW50CisgICAgICAgICAgICBpZiAoIWRhc2hlci5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgYWRkQ2FwKGxwLCBzY3gsIHNjeSwgcnAueExhc3QsIHJwLnlMYXN0KTsKKyAgICAgICAgICAgICAgICBscC5jb21iaW5lKHJwKTsKKyAgICAgICAgICAgICAgICBhZGRDYXAobHAsIHNteCwgc215LCBscC54TW92ZSwgbHAueU1vdmUpOworICAgICAgICAgICAgICAgIGxwLmNsb3NlUGF0aCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZHN0LmFwcGVuZChscCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGNhcCB0byB0aGUgd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgQnVmZmVyZWRQYXRoIG9iamVjdCBvZiB3b3JrIHBhdGguCisgICAgICogQHBhcmFtIHgwCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzb3VyY2UgcGF0aC4KKyAgICAgKiBAcGFyYW0geTAKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb24gdGhlIHNvdXJjZSBwYXRoLgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCBvbiB0aGUgd29yayBwYXRoLgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCBvbiB0aGUgd29yayBwYXRoLgorICAgICAqLworICAgIHZvaWQgYWRkQ2FwKEJ1ZmZlcmVkUGF0aCBwLCBkb3VibGUgeDAsIGRvdWJsZSB5MCwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgZG91YmxlIHgxID0gcC54TGFzdDsKKyAgICAgICAgZG91YmxlIHkxID0gcC55TGFzdDsKKyAgICAgICAgZG91YmxlIHgxMCA9IHgxIC0geDA7CisgICAgICAgIGRvdWJsZSB5MTAgPSB5MSAtIHkwOworICAgICAgICBkb3VibGUgeDIwID0geDIgLSB4MDsKKyAgICAgICAgZG91YmxlIHkyMCA9IHkyIC0geTA7CisKKyAgICAgICAgc3dpdGNoIChjYXApIHsKKyAgICAgICAgICAgIGNhc2UgQ0FQX0JVVFQ6CisgICAgICAgICAgICAgICAgcC5saW5lVG8oeDIsIHkyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQ0FQX1JPVU5EOgorICAgICAgICAgICAgICAgIGRvdWJsZSBteCA9IHgxMCAqIENVQklDX0FSQzsKKyAgICAgICAgICAgICAgICBkb3VibGUgbXkgPSB5MTAgKiBDVUJJQ19BUkM7CisKKyAgICAgICAgICAgICAgICBkb3VibGUgeDMgPSB4MCArIHkxMDsKKyAgICAgICAgICAgICAgICBkb3VibGUgeTMgPSB5MCAtIHgxMDsKKworICAgICAgICAgICAgICAgIHgxMCAqPSBDVUJJQ19BUkM7CisgICAgICAgICAgICAgICAgeTEwICo9IENVQklDX0FSQzsKKyAgICAgICAgICAgICAgICB4MjAgKj0gQ1VCSUNfQVJDOworICAgICAgICAgICAgICAgIHkyMCAqPSBDVUJJQ19BUkM7CisKKyAgICAgICAgICAgICAgICBwLmN1YmljVG8oeDEgKyB5MTAsIHkxIC0geDEwLCB4MyArIG14LCB5MyArIG15LCB4MywgeTMpOworICAgICAgICAgICAgICAgIHAuY3ViaWNUbyh4MyAtIG14LCB5MyAtIG15LCB4MiAtIHkyMCwgeTIgKyB4MjAsIHgyLCB5Mik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENBUF9TUVVBUkU6CisgICAgICAgICAgICAgICAgcC5saW5lVG8oeDEgKyB5MTAsIHkxIC0geDEwKTsKKyAgICAgICAgICAgICAgICBwLmxpbmVUbyh4MiAtIHkyMCwgeTIgKyB4MjApOworICAgICAgICAgICAgICAgIHAubGluZVRvKHgyLCB5Mik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGJldmVsIGFuZCBtaXRlciBqb2luIHRvIHRoZSB3b3JrIHBhdGguCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBCdWZmZXJlZFBhdGggb2JqZWN0IG9mIHdvcmsgcGF0aC4KKyAgICAgKiBAcGFyYW0geDAKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNvdXJjZSBwYXRoLgorICAgICAqIEBwYXJhbSB5MAorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvbiB0aGUgc291cmNlIHBhdGguCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBuZXh0IHBvaW50IG9uIHRoZSB3b3JrIHBhdGguCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBuZXh0IHBvaW50IG9uIHRoZSB3b3JrIHBhdGguCisgICAgICogQHBhcmFtIGlzTGVmdAorICAgICAqICAgICAgICAgICAgdGhlIG9yaWVudGF0aW9uIG9mIHdvcmsgcGF0aCwgdHJ1ZSBpZiB3b3JrIHBhdGggbGllcyB0byB0aGUKKyAgICAgKiAgICAgICAgICAgIGxlZnQgZnJvbSBzb3VyY2UgcGF0aCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHZvaWQgYWRkSm9pbihCdWZmZXJlZFBhdGggcCwgZG91YmxlIHgwLCBkb3VibGUgeTAsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBib29sZWFuIGlzTGVmdCkgeworICAgICAgICBkb3VibGUgeDEgPSBwLnhMYXN0OworICAgICAgICBkb3VibGUgeTEgPSBwLnlMYXN0OworICAgICAgICBkb3VibGUgeDEwID0geDEgLSB4MDsKKyAgICAgICAgZG91YmxlIHkxMCA9IHkxIC0geTA7CisgICAgICAgIGRvdWJsZSB4MjAgPSB4MiAtIHgwOworICAgICAgICBkb3VibGUgeTIwID0geTIgLSB5MDsKKyAgICAgICAgZG91YmxlIHNpbjAgPSB4MTAgKiB5MjAgLSB5MTAgKiB4MjA7CisKKyAgICAgICAgLy8gU21hbGwgY29ybmVyCisgICAgICAgIGlmICgtY29ybmVyRGVsdGEgPCBzaW4wICYmIHNpbjAgPCBjb3JuZXJEZWx0YSkgeworICAgICAgICAgICAgZG91YmxlIGNvczAgPSB4MTAgKiB4MjAgKyB5MTAgKiB5MjA7CisgICAgICAgICAgICBpZiAoY29zMCA+IDAuMCkgeworICAgICAgICAgICAgICAgIC8vIGlmIHplcm8gY29ybmVyIGRvIG5vdGhpbmcKKyAgICAgICAgICAgICAgICBpZiAoLXplcm9EZWx0YSA+IHNpbjAgfHwgc2luMCA+IHplcm9EZWx0YSkgeworICAgICAgICAgICAgICAgICAgICBkb3VibGUgeDMgPSB4MCArIHcyICogdzIgKiAoeTIwIC0geTEwKSAvIHNpbjA7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB5MyA9IHkwICsgdzIgKiB3MiAqICh4MTAgLSB4MjApIC8gc2luMDsKKyAgICAgICAgICAgICAgICAgICAgcC5zZXRMYXN0KHgzLCB5Myk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFplcm8gY29ybmVyCisgICAgICAgICAgICBpZiAoLXplcm9EZWx0YSA8IHNpbjAgJiYgc2luMCA8IHplcm9EZWx0YSkgeworICAgICAgICAgICAgICAgIHAubGluZVRvKHgyLCB5Mik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoaXNMZWZ0IF4gKHNpbjAgPCAwLjApKSB7CisgICAgICAgICAgICAvLyBUd2lzdGVkIGNvcm5lcgorICAgICAgICAgICAgcC5saW5lVG8oeDAsIHkwKTsKKyAgICAgICAgICAgIHAubGluZVRvKHgyLCB5Mik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzd2l0Y2ggKGpvaW4pIHsKKyAgICAgICAgICAgICAgICBjYXNlIEpPSU5fQkVWRUw6CisgICAgICAgICAgICAgICAgICAgIHAubGluZVRvKHgyLCB5Mik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgSk9JTl9NSVRFUjoKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHMxID0geDEgKiB4MTAgKyB5MSAqIHkxMDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHMyID0geDIgKiB4MjAgKyB5MiAqIHkyMDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHgzID0gKHMxICogeTIwIC0gczIgKiB5MTApIC8gc2luMDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHkzID0gKHMyICogeDEwIC0gczEgKiB4MjApIC8gc2luMDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHgzMCA9IHgzIC0geDA7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB5MzAgPSB5MyAtIHkwOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgbWl0ZXJMZW5ndGggPSBNYXRoLnNxcnQoeDMwICogeDMwICsgeTMwICogeTMwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1pdGVyTGVuZ3RoIDwgbWl0ZXJMaW1pdCAqIHcyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwLmxpbmVUbyh4MywgeTMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHAubGluZVRvKHgyLCB5Mik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgSk9JTl9ST1VORDoKKyAgICAgICAgICAgICAgICAgICAgYWRkUm91bmRKb2luKHAsIHgwLCB5MCwgeDIsIHkyLCBpc0xlZnQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgcm91bmQgam9pbiB0byB0aGUgd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgQnVmZmVyZWRQYXRoIG9iamVjdCBvZiB3b3JrIHBhdGguCisgICAgICogQHBhcmFtIHgwCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzb3VyY2UgcGF0aC4KKyAgICAgKiBAcGFyYW0geTAKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb24gdGhlIHNvdXJjZSBwYXRoLgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCBvbiB0aGUgd29yayBwYXRoLgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCBvbiB0aGUgd29yayBwYXRoLgorICAgICAqIEBwYXJhbSBpc0xlZnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcmllbnRhdGlvbiBvZiB3b3JrIHBhdGgsIHRydWUgaWYgd29yayBwYXRoIGxpZXMgdG8gdGhlCisgICAgICogICAgICAgICAgICBsZWZ0IGZyb20gc291cmNlIHBhdGgsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICB2b2lkIGFkZFJvdW5kSm9pbihCdWZmZXJlZFBhdGggcCwgZG91YmxlIHgwLCBkb3VibGUgeTAsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBib29sZWFuIGlzTGVmdCkgeworICAgICAgICBkb3VibGUgeDEgPSBwLnhMYXN0OworICAgICAgICBkb3VibGUgeTEgPSBwLnlMYXN0OworICAgICAgICBkb3VibGUgeDEwID0geDEgLSB4MDsKKyAgICAgICAgZG91YmxlIHkxMCA9IHkxIC0geTA7CisgICAgICAgIGRvdWJsZSB4MjAgPSB4MiAtIHgwOworICAgICAgICBkb3VibGUgeTIwID0geTIgLSB5MDsKKworICAgICAgICBkb3VibGUgeDMwID0geDEwICsgeDIwOworICAgICAgICBkb3VibGUgeTMwID0geTEwICsgeTIwOworCisgICAgICAgIGRvdWJsZSBsMzAgPSBNYXRoLnNxcnQoeDMwICogeDMwICsgeTMwICogeTMwKTsKKworICAgICAgICBpZiAobDMwIDwgMUUtNSkgeworICAgICAgICAgICAgcC5saW5lVG8oeDIsIHkyKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSB3ID0gdzIgLyBsMzA7CisKKyAgICAgICAgeDMwICo9IHc7CisgICAgICAgIHkzMCAqPSB3OworCisgICAgICAgIGRvdWJsZSB4MyA9IHgwICsgeDMwOworICAgICAgICBkb3VibGUgeTMgPSB5MCArIHkzMDsKKworICAgICAgICBkb3VibGUgY29zID0geDEwICogeDIwICsgeTEwICogeTIwOworICAgICAgICBkb3VibGUgYSA9IE1hdGguYWNvcyhjb3MgLyAodzIgKiB3MikpOworICAgICAgICBpZiAoY29zID49IDAuMCkgeworICAgICAgICAgICAgZG91YmxlIGsgPSA0LjAgLyAzLjAgKiBNYXRoLnRhbihhIC8gNC4wKTsKKyAgICAgICAgICAgIGlmIChpc0xlZnQpIHsKKyAgICAgICAgICAgICAgICBrID0gLWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHgxMCAqPSBrOworICAgICAgICAgICAgeTEwICo9IGs7CisgICAgICAgICAgICB4MjAgKj0gazsKKyAgICAgICAgICAgIHkyMCAqPSBrOworCisgICAgICAgICAgICBwLmN1YmljVG8oeDEgLSB5MTAsIHkxICsgeDEwLCB4MiArIHkyMCwgeTIgLSB4MjAsIHgyLCB5Mik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkb3VibGUgayA9IDQuMCAvIDMuMCAqIE1hdGgudGFuKGEgLyA4LjApOworICAgICAgICAgICAgaWYgKGlzTGVmdCkgeworICAgICAgICAgICAgICAgIGsgPSAtazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgeDEwICo9IGs7CisgICAgICAgICAgICB5MTAgKj0gazsKKyAgICAgICAgICAgIHgyMCAqPSBrOworICAgICAgICAgICAgeTIwICo9IGs7CisgICAgICAgICAgICB4MzAgKj0gazsKKyAgICAgICAgICAgIHkzMCAqPSBrOworCisgICAgICAgICAgICBwLmN1YmljVG8oeDEgLSB5MTAsIHkxICsgeDEwLCB4MyArIHkzMCwgeTMgLSB4MzAsIHgzLCB5Myk7CisgICAgICAgICAgICBwLmN1YmljVG8oeDMgLSB5MzAsIHkzICsgeDMwLCB4MiArIHkyMCwgeTIgLSB4MjAsIHgyLCB5Mik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgc29saWQgbGluZSBzZWdtZW50IHRvIHRoZSB3b3JrIHBhdGguCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydCBsaW5lIHBvaW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnQgbGluZSBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBsaW5lIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIGxpbmUgcG9pbnQuCisgICAgICogQHBhcmFtIHplcm8KKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUgaXQncyBhbGxvd2FibGUgdG8gYWRkIHplcm8gbGVuZ3RoIGxpbmUgc2VnbWVudC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZExpbmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBib29sZWFuIHplcm8pIHsKKyAgICAgICAgZG91YmxlIGR4ID0geDIgLSB4MTsKKyAgICAgICAgZG91YmxlIGR5ID0geTIgLSB5MTsKKworICAgICAgICBpZiAoZHggPT0gMC4wICYmIGR5ID09IDAuMCkgeworICAgICAgICAgICAgaWYgKCF6ZXJvKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZHggPSB3MjsKKyAgICAgICAgICAgIGR5ID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRvdWJsZSB3ID0gdzIgLyBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpOworICAgICAgICAgICAgZHggKj0gdzsKKyAgICAgICAgICAgIGR5ICo9IHc7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgbHgxID0geDEgLSBkeTsKKyAgICAgICAgZG91YmxlIGx5MSA9IHkxICsgZHg7CisgICAgICAgIGRvdWJsZSByeDEgPSB4MSArIGR5OworICAgICAgICBkb3VibGUgcnkxID0geTEgLSBkeDsKKworICAgICAgICBpZiAoY2hlY2tNb3ZlKSB7CisgICAgICAgICAgICBpZiAoaXNNb3ZlKSB7CisgICAgICAgICAgICAgICAgaXNNb3ZlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgbHAubW92ZVRvKGx4MSwgbHkxKTsKKyAgICAgICAgICAgICAgICBycC5tb3ZlVG8ocngxLCByeTEpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhZGRKb2luKGxwLCB4MSwgeTEsIGx4MSwgbHkxLCB0cnVlKTsKKyAgICAgICAgICAgICAgICBhZGRKb2luKHJwLCB4MSwgeTEsIHJ4MSwgcnkxLCBmYWxzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBscC5saW5lVG8oeDIgLSBkeSwgeTIgKyBkeCk7CisgICAgICAgIHJwLmxpbmVUbyh4MiArIGR5LCB5MiAtIGR4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHNvbGlkIHF1YWQgc2VnbWVudCB0byB0aGUgd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTMKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIGNvbnRyb2wgcG9pbnQuCisgICAgICovCisgICAgdm9pZCBhZGRRdWFkKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHgzLCBkb3VibGUgeTMpIHsKKyAgICAgICAgZG91YmxlIHgyMSA9IHgyIC0geDE7CisgICAgICAgIGRvdWJsZSB5MjEgPSB5MiAtIHkxOworICAgICAgICBkb3VibGUgeDIzID0geDIgLSB4MzsKKyAgICAgICAgZG91YmxlIHkyMyA9IHkyIC0geTM7CisKKyAgICAgICAgZG91YmxlIGwyMSA9IE1hdGguc3FydCh4MjEgKiB4MjEgKyB5MjEgKiB5MjEpOworICAgICAgICBkb3VibGUgbDIzID0gTWF0aC5zcXJ0KHgyMyAqIHgyMyArIHkyMyAqIHkyMyk7CisKKyAgICAgICAgaWYgKGwyMSA9PSAwLjAgJiYgbDIzID09IDAuMCkgeworICAgICAgICAgICAgYWRkTGluZSh4MSwgeTEsIHgzLCB5MywgZmFsc2UpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGwyMSA9PSAwLjApIHsKKyAgICAgICAgICAgIGFkZExpbmUoeDIsIHkyLCB4MywgeTMsIGZhbHNlKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsMjMgPT0gMC4wKSB7CisgICAgICAgICAgICBhZGRMaW5lKHgxLCB5MSwgeDIsIHkyLCBmYWxzZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgdzsKKyAgICAgICAgdyA9IHcyIC8gbDIxOworICAgICAgICBkb3VibGUgbXgxID0gLXkyMSAqIHc7CisgICAgICAgIGRvdWJsZSBteTEgPSB4MjEgKiB3OworICAgICAgICB3ID0gdzIgLyBsMjM7CisgICAgICAgIGRvdWJsZSBteDMgPSB5MjMgKiB3OworICAgICAgICBkb3VibGUgbXkzID0gLXgyMyAqIHc7CisKKyAgICAgICAgZG91YmxlIGx4MSA9IHgxICsgbXgxOworICAgICAgICBkb3VibGUgbHkxID0geTEgKyBteTE7CisgICAgICAgIGRvdWJsZSByeDEgPSB4MSAtIG14MTsKKyAgICAgICAgZG91YmxlIHJ5MSA9IHkxIC0gbXkxOworCisgICAgICAgIGlmIChjaGVja01vdmUpIHsKKyAgICAgICAgICAgIGlmIChpc01vdmUpIHsKKyAgICAgICAgICAgICAgICBpc01vdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBscC5tb3ZlVG8obHgxLCBseTEpOworICAgICAgICAgICAgICAgIHJwLm1vdmVUbyhyeDEsIHJ5MSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFkZEpvaW4obHAsIHgxLCB5MSwgbHgxLCBseTEsIHRydWUpOworICAgICAgICAgICAgICAgIGFkZEpvaW4ocnAsIHgxLCB5MSwgcngxLCByeTEsIGZhbHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh4MjEgKiB5MjMgLSB5MjEgKiB4MjMgPT0gMC4wKSB7CisgICAgICAgICAgICAvLyBPbiBsaW5lIGN1cnZlCisgICAgICAgICAgICBpZiAoeDIxICogeDIzICsgeTIxICogeTIzID4gMC4wKSB7CisgICAgICAgICAgICAgICAgLy8gVHdpc3RlZCBjdXJ2ZQorICAgICAgICAgICAgICAgIGlmIChsMjEgPT0gbDIzKSB7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBweCA9IHgxICsgKHgyMSArIHgyMykgLyA0LjA7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBweSA9IHkxICsgKHkyMSArIHkyMykgLyA0LjA7CisgICAgICAgICAgICAgICAgICAgIGxwLmxpbmVUbyhweCArIG14MSwgcHkgKyBteTEpOworICAgICAgICAgICAgICAgICAgICBycC5saW5lVG8ocHggLSBteDEsIHB5IC0gbXkxKTsKKyAgICAgICAgICAgICAgICAgICAgbHAubGluZVRvKHB4IC0gbXgxLCBweSAtIG15MSk7CisgICAgICAgICAgICAgICAgICAgIHJwLmxpbmVUbyhweCArIG14MSwgcHkgKyBteTEpOworICAgICAgICAgICAgICAgICAgICBscC5saW5lVG8oeDMgLSBteDEsIHkzIC0gbXkxKTsKKyAgICAgICAgICAgICAgICAgICAgcnAubGluZVRvKHgzICsgbXgxLCB5MyArIG15MSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHB4MSwgcHkxOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgayA9IGwyMSAvIChsMjEgKyBsMjMpOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgcHggPSB4MSArICh4MjEgKyB4MjMpICogayAqIGs7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBweSA9IHkxICsgKHkyMSArIHkyMykgKiBrICogazsKKyAgICAgICAgICAgICAgICAgICAgcHgxID0gKHgxICsgcHgpIC8gMi4wOworICAgICAgICAgICAgICAgICAgICBweTEgPSAoeTEgKyBweSkgLyAyLjA7CisgICAgICAgICAgICAgICAgICAgIGxwLnF1YWRUbyhweDEgKyBteDEsIHB5MSArIG15MSwgcHggKyBteDEsIHB5ICsgbXkxKTsKKyAgICAgICAgICAgICAgICAgICAgcnAucXVhZFRvKHB4MSAtIG14MSwgcHkxIC0gbXkxLCBweCAtIG14MSwgcHkgLSBteTEpOworICAgICAgICAgICAgICAgICAgICBscC5saW5lVG8ocHggLSBteDEsIHB5IC0gbXkxKTsKKyAgICAgICAgICAgICAgICAgICAgcnAubGluZVRvKHB4ICsgbXgxLCBweSArIG15MSk7CisgICAgICAgICAgICAgICAgICAgIHB4MSA9ICh4MyArIHB4KSAvIDIuMDsKKyAgICAgICAgICAgICAgICAgICAgcHkxID0gKHkzICsgcHkpIC8gMi4wOworICAgICAgICAgICAgICAgICAgICBscC5xdWFkVG8ocHgxIC0gbXgxLCBweTEgLSBteTEsIHgzIC0gbXgxLCB5MyAtIG15MSk7CisgICAgICAgICAgICAgICAgICAgIHJwLnF1YWRUbyhweDEgKyBteDEsIHB5MSArIG15MSwgeDMgKyBteDEsIHkzICsgbXkxKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBjdXJ2ZQorICAgICAgICAgICAgICAgIGxwLnF1YWRUbyh4MiArIG14MSwgeTIgKyBteTEsIHgzICsgbXgzLCB5MyArIG15Myk7CisgICAgICAgICAgICAgICAgcnAucXVhZFRvKHgyIC0gbXgxLCB5MiAtIG15MSwgeDMgLSBteDMsIHkzIC0gbXkzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFkZFN1YlF1YWQoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdWJkaXZpZGVzIHNvbGlkIHF1YWQgY3VydmUgdG8gbWFrZSBvdXRsaW5lIGZvciBzb3VyY2UgcXVhZCBzZWdtZW50IGFuZAorICAgICAqIGFkZHMgaXQgdG8gd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTMKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIGxldmVsCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBsZXZlbCBvZiBzdWJkaXZpc2lvbiBkZWVwbmVzcy4KKyAgICAgKi8KKyAgICB2b2lkIGFkZFN1YlF1YWQoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgeDMsIGRvdWJsZSB5MywgaW50IGxldmVsKSB7CisgICAgICAgIGRvdWJsZSB4MjEgPSB4MiAtIHgxOworICAgICAgICBkb3VibGUgeTIxID0geTIgLSB5MTsKKyAgICAgICAgZG91YmxlIHgyMyA9IHgyIC0geDM7CisgICAgICAgIGRvdWJsZSB5MjMgPSB5MiAtIHkzOworCisgICAgICAgIGRvdWJsZSBjb3MgPSB4MjEgKiB4MjMgKyB5MjEgKiB5MjM7CisgICAgICAgIGRvdWJsZSBzaW4gPSB4MjEgKiB5MjMgLSB5MjEgKiB4MjM7CisKKyAgICAgICAgaWYgKGxldmVsIDwgTUFYX0xFVkVMICYmIChjb3MgPj0gMC4wIHx8IChNYXRoLmFicyhzaW4gLyBjb3MpID4gY3VydmVEZWx0YSkpKSB7CisgICAgICAgICAgICBkb3VibGUgYzF4ID0gKHgyICsgeDEpIC8gMi4wOworICAgICAgICAgICAgZG91YmxlIGMxeSA9ICh5MiArIHkxKSAvIDIuMDsKKyAgICAgICAgICAgIGRvdWJsZSBjMnggPSAoeDIgKyB4MykgLyAyLjA7CisgICAgICAgICAgICBkb3VibGUgYzJ5ID0gKHkyICsgeTMpIC8gMi4wOworICAgICAgICAgICAgZG91YmxlIGMzeCA9IChjMXggKyBjMngpIC8gMi4wOworICAgICAgICAgICAgZG91YmxlIGMzeSA9IChjMXkgKyBjMnkpIC8gMi4wOworICAgICAgICAgICAgYWRkU3ViUXVhZCh4MSwgeTEsIGMxeCwgYzF5LCBjM3gsIGMzeSwgbGV2ZWwgKyAxKTsKKyAgICAgICAgICAgIGFkZFN1YlF1YWQoYzN4LCBjM3ksIGMyeCwgYzJ5LCB4MywgeTMsIGxldmVsICsgMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkb3VibGUgdzsKKyAgICAgICAgICAgIGRvdWJsZSBsMjEgPSBNYXRoLnNxcnQoeDIxICogeDIxICsgeTIxICogeTIxKTsKKyAgICAgICAgICAgIGRvdWJsZSBsMjMgPSBNYXRoLnNxcnQoeDIzICogeDIzICsgeTIzICogeTIzKTsKKyAgICAgICAgICAgIHcgPSB3MiAvIHNpbjsKKyAgICAgICAgICAgIGRvdWJsZSBteDIgPSAoeDIxICogbDIzICsgeDIzICogbDIxKSAqIHc7CisgICAgICAgICAgICBkb3VibGUgbXkyID0gKHkyMSAqIGwyMyArIHkyMyAqIGwyMSkgKiB3OworICAgICAgICAgICAgdyA9IHcyIC8gbDIzOworICAgICAgICAgICAgZG91YmxlIG14MyA9IHkyMyAqIHc7CisgICAgICAgICAgICBkb3VibGUgbXkzID0gLXgyMyAqIHc7CisgICAgICAgICAgICBscC5xdWFkVG8oeDIgKyBteDIsIHkyICsgbXkyLCB4MyArIG14MywgeTMgKyBteTMpOworICAgICAgICAgICAgcnAucXVhZFRvKHgyIC0gbXgyLCB5MiAtIG15MiwgeDMgLSBteDMsIHkzIC0gbXkzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgc29saWQgY3ViaWMgc2VnbWVudCB0byB0aGUgd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTMKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHg0CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmb3VycyBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB5NAorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZm91cnMgY29udHJvbCBwb2ludC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZEN1YmljKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHgzLCBkb3VibGUgeTMsIGRvdWJsZSB4NCwKKyAgICAgICAgICAgIGRvdWJsZSB5NCkgeworICAgICAgICBkb3VibGUgeDEyID0geDEgLSB4MjsKKyAgICAgICAgZG91YmxlIHkxMiA9IHkxIC0geTI7CisgICAgICAgIGRvdWJsZSB4MjMgPSB4MiAtIHgzOworICAgICAgICBkb3VibGUgeTIzID0geTIgLSB5MzsKKyAgICAgICAgZG91YmxlIHgzNCA9IHgzIC0geDQ7CisgICAgICAgIGRvdWJsZSB5MzQgPSB5MyAtIHk0OworCisgICAgICAgIGRvdWJsZSBsMTIgPSBNYXRoLnNxcnQoeDEyICogeDEyICsgeTEyICogeTEyKTsKKyAgICAgICAgZG91YmxlIGwyMyA9IE1hdGguc3FydCh4MjMgKiB4MjMgKyB5MjMgKiB5MjMpOworICAgICAgICBkb3VibGUgbDM0ID0gTWF0aC5zcXJ0KHgzNCAqIHgzNCArIHkzNCAqIHkzNCk7CisKKyAgICAgICAgLy8gQWxsIGVkZ2VzIGFyZSB6ZXJvCisgICAgICAgIGlmIChsMTIgPT0gMC4wICYmIGwyMyA9PSAwLjAgJiYgbDM0ID09IDAuMCkgeworICAgICAgICAgICAgYWRkTGluZSh4MSwgeTEsIHg0LCB5NCwgZmFsc2UpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gT25lIHplcm8gZWRnZQorICAgICAgICBpZiAobDEyID09IDAuMCAmJiBsMjMgPT0gMC4wKSB7CisgICAgICAgICAgICBhZGRMaW5lKHgzLCB5MywgeDQsIHk0LCBmYWxzZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAobDIzID09IDAuMCAmJiBsMzQgPT0gMC4wKSB7CisgICAgICAgICAgICBhZGRMaW5lKHgxLCB5MSwgeDIsIHkyLCBmYWxzZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAobDEyID09IDAuMCAmJiBsMzQgPT0gMC4wKSB7CisgICAgICAgICAgICBhZGRMaW5lKHgyLCB5MiwgeDMsIHkzLCBmYWxzZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgdywgbXgxLCBteTEsIG14NCwgbXk0OworICAgICAgICBib29sZWFuIG9uTGluZTsKKworICAgICAgICBpZiAobDEyID09IDAuMCkgeworICAgICAgICAgICAgdyA9IHcyIC8gbDIzOworICAgICAgICAgICAgbXgxID0geTIzICogdzsKKyAgICAgICAgICAgIG15MSA9IC14MjMgKiB3OworICAgICAgICAgICAgdyA9IHcyIC8gbDM0OworICAgICAgICAgICAgbXg0ID0geTM0ICogdzsKKyAgICAgICAgICAgIG15NCA9IC14MzQgKiB3OworICAgICAgICAgICAgb25MaW5lID0gLXgyMyAqIHkzNCArIHkyMyAqIHgzNCA9PSAwLjA7IC8vIHNpbjMKKyAgICAgICAgfSBlbHNlIGlmIChsMzQgPT0gMC4wKSB7CisgICAgICAgICAgICB3ID0gdzIgLyBsMTI7CisgICAgICAgICAgICBteDEgPSB5MTIgKiB3OworICAgICAgICAgICAgbXkxID0gLXgxMiAqIHc7CisgICAgICAgICAgICB3ID0gdzIgLyBsMjM7CisgICAgICAgICAgICBteDQgPSB5MjMgKiB3OworICAgICAgICAgICAgbXk0ID0gLXgyMyAqIHc7CisgICAgICAgICAgICBvbkxpbmUgPSAteDEyICogeTIzICsgeTEyICogeDIzID09IDAuMDsgLy8gc2luMgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdyA9IHcyIC8gbDEyOworICAgICAgICAgICAgbXgxID0geTEyICogdzsKKyAgICAgICAgICAgIG15MSA9IC14MTIgKiB3OworICAgICAgICAgICAgdyA9IHcyIC8gbDM0OworICAgICAgICAgICAgbXg0ID0geTM0ICogdzsKKyAgICAgICAgICAgIG15NCA9IC14MzQgKiB3OworICAgICAgICAgICAgaWYgKGwyMyA9PSAwLjApIHsKKyAgICAgICAgICAgICAgICBvbkxpbmUgPSAteDEyICogeTM0ICsgeTEyICogeDM0ID09IDAuMDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb25MaW5lID0gLXgxMiAqIHkzNCArIHkxMiAqIHgzNCA9PSAwLjAgJiYgLXgxMiAqIHkyMyArIHkxMiAqIHgyMyA9PSAwLjAgJiYgLy8gc2luMgorICAgICAgICAgICAgICAgICAgICAgICAgLXgyMyAqIHkzNCArIHkyMyAqIHgzNCA9PSAwLjA7IC8vIHNpbjMKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBseDEgPSB4MSArIG14MTsKKyAgICAgICAgZG91YmxlIGx5MSA9IHkxICsgbXkxOworICAgICAgICBkb3VibGUgcngxID0geDEgLSBteDE7CisgICAgICAgIGRvdWJsZSByeTEgPSB5MSAtIG15MTsKKworICAgICAgICBpZiAoY2hlY2tNb3ZlKSB7CisgICAgICAgICAgICBpZiAoaXNNb3ZlKSB7CisgICAgICAgICAgICAgICAgaXNNb3ZlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgbHAubW92ZVRvKGx4MSwgbHkxKTsKKyAgICAgICAgICAgICAgICBycC5tb3ZlVG8ocngxLCByeTEpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhZGRKb2luKGxwLCB4MSwgeTEsIGx4MSwgbHkxLCB0cnVlKTsKKyAgICAgICAgICAgICAgICBhZGRKb2luKHJwLCB4MSwgeTEsIHJ4MSwgcnkxLCBmYWxzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAob25MaW5lKSB7CisgICAgICAgICAgICBpZiAoKHgxID09IHgyICYmIHkxIDwgeTIpIHx8IHgxIDwgeDIpIHsKKyAgICAgICAgICAgICAgICBsMTIgPSAtbDEyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCh4MiA9PSB4MyAmJiB5MiA8IHkzKSB8fCB4MiA8IHgzKSB7CisgICAgICAgICAgICAgICAgbDIzID0gLWwyMzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoeDMgPT0geDQgJiYgeTMgPCB5NCkgfHwgeDMgPCB4NCkgeworICAgICAgICAgICAgICAgIGwzNCA9IC1sMzQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkb3VibGUgZCA9IGwyMyAqIGwyMyAtIGwxMiAqIGwzNDsKKyAgICAgICAgICAgIGRvdWJsZSByb290c1tdID0gbmV3IGRvdWJsZVszXTsKKyAgICAgICAgICAgIGludCByYyA9IDA7CisgICAgICAgICAgICBpZiAoZCA9PSAwLjApIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgdCA9IChsMTIgLSBsMjMpIC8gKGwxMiArIGwzNCAtIGwyMyAtIGwyMyk7CisgICAgICAgICAgICAgICAgaWYgKDAuMCA8IHQgJiYgdCA8IDEuMCkgeworICAgICAgICAgICAgICAgICAgICByb290c1tyYysrXSA9IHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChkID4gMC4wKSB7CisgICAgICAgICAgICAgICAgZCA9IE1hdGguc3FydChkKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgeiA9IGwxMiArIGwzNCAtIGwyMyAtIGwyMzsKKyAgICAgICAgICAgICAgICBkb3VibGUgdDsKKyAgICAgICAgICAgICAgICB0ID0gKGwxMiAtIGwyMyArIGQpIC8gejsKKyAgICAgICAgICAgICAgICBpZiAoMC4wIDwgdCAmJiB0IDwgMS4wKSB7CisgICAgICAgICAgICAgICAgICAgIHJvb3RzW3JjKytdID0gdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdCA9IChsMTIgLSBsMjMgLSBkKSAvIHo7CisgICAgICAgICAgICAgICAgaWYgKDAuMCA8IHQgJiYgdCA8IDEuMCkgeworICAgICAgICAgICAgICAgICAgICByb290c1tyYysrXSA9IHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocmMgPiAwKSB7CisgICAgICAgICAgICAgICAgLy8gU29ydCByb290cworICAgICAgICAgICAgICAgIGlmIChyYyA9PSAyICYmIHJvb3RzWzBdID4gcm9vdHNbMV0pIHsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHRtcCA9IHJvb3RzWzBdOworICAgICAgICAgICAgICAgICAgICByb290c1swXSA9IHJvb3RzWzFdOworICAgICAgICAgICAgICAgICAgICByb290c1sxXSA9IHRtcDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcm9vdHNbcmMrK10gPSAxLjA7CisKKyAgICAgICAgICAgICAgICBkb3VibGUgYXggPSAteDM0IC0geDEyICsgeDIzICsgeDIzOworICAgICAgICAgICAgICAgIGRvdWJsZSBheSA9IC15MzQgLSB5MTIgKyB5MjMgKyB5MjM7CisgICAgICAgICAgICAgICAgZG91YmxlIGJ4ID0gMy4wICogKC14MjMgKyB4MTIpOworICAgICAgICAgICAgICAgIGRvdWJsZSBieSA9IDMuMCAqICgteTIzICsgeTEyKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgY3ggPSAzLjAgKiAoLXgxMik7CisgICAgICAgICAgICAgICAgZG91YmxlIGN5ID0gMy4wICogKC15MTIpOworICAgICAgICAgICAgICAgIGRvdWJsZSB4UHJldiA9IHgxOworICAgICAgICAgICAgICAgIGRvdWJsZSB5UHJldiA9IHkxOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBkb3VibGUgdCA9IHJvb3RzW2ldOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgcHggPSB0ICogKHQgKiAodCAqIGF4ICsgYngpICsgY3gpICsgeDE7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBweSA9IHQgKiAodCAqICh0ICogYXkgKyBieSkgKyBjeSkgKyB5MTsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHB4MSA9ICh4UHJldiArIHB4KSAvIDIuMDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIHB5MSA9ICh5UHJldiArIHB5KSAvIDIuMDsKKyAgICAgICAgICAgICAgICAgICAgbHAuY3ViaWNUbyhweDEgKyBteDEsIHB5MSArIG15MSwgcHgxICsgbXgxLCBweTEgKyBteTEsIHB4ICsgbXgxLCBweSArIG15MSk7CisgICAgICAgICAgICAgICAgICAgIHJwLmN1YmljVG8ocHgxIC0gbXgxLCBweTEgLSBteTEsIHB4MSAtIG14MSwgcHkxIC0gbXkxLCBweCAtIG14MSwgcHkgLSBteTEpOworICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IHJjIC0gMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbHAubGluZVRvKHB4IC0gbXgxLCBweSAtIG15MSk7CisgICAgICAgICAgICAgICAgICAgICAgICBycC5saW5lVG8ocHggKyBteDEsIHB5ICsgbXkxKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB4UHJldiA9IHB4OworICAgICAgICAgICAgICAgICAgICB5UHJldiA9IHB5OworICAgICAgICAgICAgICAgICAgICBteDEgPSAtbXgxOworICAgICAgICAgICAgICAgICAgICBteTEgPSAtbXkxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbHAuY3ViaWNUbyh4MiArIG14MSwgeTIgKyBteTEsIHgzICsgbXg0LCB5MyArIG15NCwgeDQgKyBteDQsIHk0ICsgbXk0KTsKKyAgICAgICAgICAgICAgICBycC5jdWJpY1RvKHgyIC0gbXgxLCB5MiAtIG15MSwgeDMgLSBteDQsIHkzIC0gbXk0LCB4NCAtIG14NCwgeTQgLSBteTQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYWRkU3ViQ3ViaWMoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YmRpdmlkZXMgc29saWQgY3ViaWMgY3VydmUgdG8gbWFrZSBvdXRsaW5lIGZvciBzb3VyY2UgcXVhZCBzZWdtZW50IGFuZAorICAgICAqIGFkZHMgaXQgdG8gd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTMKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHg0CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmb3VycyBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB5NAorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZm91cnMgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0gbGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIGxldmVsIG9mIHN1YmRpdmlzaW9uIGRlZXBuZXNzLgorICAgICAqLworICAgIHZvaWQgYWRkU3ViQ3ViaWMoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgeDMsIGRvdWJsZSB5MywgZG91YmxlIHg0LAorICAgICAgICAgICAgZG91YmxlIHk0LCBpbnQgbGV2ZWwpIHsKKyAgICAgICAgZG91YmxlIHgxMiA9IHgxIC0geDI7CisgICAgICAgIGRvdWJsZSB5MTIgPSB5MSAtIHkyOworICAgICAgICBkb3VibGUgeDIzID0geDIgLSB4MzsKKyAgICAgICAgZG91YmxlIHkyMyA9IHkyIC0geTM7CisgICAgICAgIGRvdWJsZSB4MzQgPSB4MyAtIHg0OworICAgICAgICBkb3VibGUgeTM0ID0geTMgLSB5NDsKKworICAgICAgICBkb3VibGUgY29zMiA9IC14MTIgKiB4MjMgLSB5MTIgKiB5MjM7CisgICAgICAgIGRvdWJsZSBjb3MzID0gLXgyMyAqIHgzNCAtIHkyMyAqIHkzNDsKKyAgICAgICAgZG91YmxlIHNpbjIgPSAteDEyICogeTIzICsgeTEyICogeDIzOworICAgICAgICBkb3VibGUgc2luMyA9IC14MjMgKiB5MzQgKyB5MjMgKiB4MzQ7CisgICAgICAgIGRvdWJsZSBzaW4wID0gLXgxMiAqIHkzNCArIHkxMiAqIHgzNDsKKyAgICAgICAgZG91YmxlIGNvczAgPSAteDEyICogeDM0IC0geTEyICogeTM0OworCisgICAgICAgIGlmIChsZXZlbCA8IE1BWF9MRVZFTAorICAgICAgICAgICAgICAgICYmIChzaW4yICE9IDAuMCB8fCBzaW4zICE9IDAuMCB8fCBzaW4wICE9IDAuMCkKKyAgICAgICAgICAgICAgICAmJiAoY29zMiA+PSAwLjAgfHwgY29zMyA+PSAwLjAgfHwgY29zMCA+PSAwLjAKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IChNYXRoLmFicyhzaW4yIC8gY29zMikgPiBjdXJ2ZURlbHRhKQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgKE1hdGguYWJzKHNpbjMgLyBjb3MzKSA+IGN1cnZlRGVsdGEpIHx8IChNYXRoLmFicyhzaW4wIC8gY29zMCkgPiBjdXJ2ZURlbHRhKSkpIHsKKyAgICAgICAgICAgIGRvdWJsZSBjeCA9ICh4MiArIHgzKSAvIDIuMDsKKyAgICAgICAgICAgIGRvdWJsZSBjeSA9ICh5MiArIHkzKSAvIDIuMDsKKyAgICAgICAgICAgIGRvdWJsZSBseDIgPSAoeDIgKyB4MSkgLyAyLjA7CisgICAgICAgICAgICBkb3VibGUgbHkyID0gKHkyICsgeTEpIC8gMi4wOworICAgICAgICAgICAgZG91YmxlIHJ4MyA9ICh4MyArIHg0KSAvIDIuMDsKKyAgICAgICAgICAgIGRvdWJsZSByeTMgPSAoeTMgKyB5NCkgLyAyLjA7CisgICAgICAgICAgICBkb3VibGUgbHgzID0gKGN4ICsgbHgyKSAvIDIuMDsKKyAgICAgICAgICAgIGRvdWJsZSBseTMgPSAoY3kgKyBseTIpIC8gMi4wOworICAgICAgICAgICAgZG91YmxlIHJ4MiA9IChjeCArIHJ4MykgLyAyLjA7CisgICAgICAgICAgICBkb3VibGUgcnkyID0gKGN5ICsgcnkzKSAvIDIuMDsKKyAgICAgICAgICAgIGN4ID0gKGx4MyArIHJ4MikgLyAyLjA7CisgICAgICAgICAgICBjeSA9IChseTMgKyByeTIpIC8gMi4wOworICAgICAgICAgICAgYWRkU3ViQ3ViaWMoeDEsIHkxLCBseDIsIGx5MiwgbHgzLCBseTMsIGN4LCBjeSwgbGV2ZWwgKyAxKTsKKyAgICAgICAgICAgIGFkZFN1YkN1YmljKGN4LCBjeSwgcngyLCByeTIsIHJ4MywgcnkzLCB4NCwgeTQsIGxldmVsICsgMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkb3VibGUgdywgbXgxLCBteTEsIG14MiwgbXkyLCBteDMsIG15MywgbXg0LCBteTQ7CisgICAgICAgICAgICBkb3VibGUgbDEyID0gTWF0aC5zcXJ0KHgxMiAqIHgxMiArIHkxMiAqIHkxMik7CisgICAgICAgICAgICBkb3VibGUgbDIzID0gTWF0aC5zcXJ0KHgyMyAqIHgyMyArIHkyMyAqIHkyMyk7CisgICAgICAgICAgICBkb3VibGUgbDM0ID0gTWF0aC5zcXJ0KHgzNCAqIHgzNCArIHkzNCAqIHkzNCk7CisKKyAgICAgICAgICAgIGlmIChsMTIgPT0gMC4wKSB7CisgICAgICAgICAgICAgICAgdyA9IHcyIC8gbDIzOworICAgICAgICAgICAgICAgIG14MSA9IHkyMyAqIHc7CisgICAgICAgICAgICAgICAgbXkxID0gLXgyMyAqIHc7CisgICAgICAgICAgICAgICAgdyA9IHcyIC8gbDM0OworICAgICAgICAgICAgICAgIG14NCA9IHkzNCAqIHc7CisgICAgICAgICAgICAgICAgbXk0ID0gLXgzNCAqIHc7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGwzNCA9PSAwLjApIHsKKyAgICAgICAgICAgICAgICB3ID0gdzIgLyBsMTI7CisgICAgICAgICAgICAgICAgbXgxID0geTEyICogdzsKKyAgICAgICAgICAgICAgICBteTEgPSAteDEyICogdzsKKyAgICAgICAgICAgICAgICB3ID0gdzIgLyBsMjM7CisgICAgICAgICAgICAgICAgbXg0ID0geTIzICogdzsKKyAgICAgICAgICAgICAgICBteTQgPSAteDIzICogdzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gQ29tbW9uIGNhc2UKKyAgICAgICAgICAgICAgICB3ID0gdzIgLyBsMTI7CisgICAgICAgICAgICAgICAgbXgxID0geTEyICogdzsKKyAgICAgICAgICAgICAgICBteTEgPSAteDEyICogdzsKKyAgICAgICAgICAgICAgICB3ID0gdzIgLyBsMzQ7CisgICAgICAgICAgICAgICAgbXg0ID0geTM0ICogdzsKKyAgICAgICAgICAgICAgICBteTQgPSAteDM0ICogdzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNpbjIgPT0gMC4wKSB7CisgICAgICAgICAgICAgICAgbXgyID0gbXgxOworICAgICAgICAgICAgICAgIG15MiA9IG15MTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdyA9IHcyIC8gc2luMjsKKyAgICAgICAgICAgICAgICBteDIgPSAtKHgxMiAqIGwyMyAtIHgyMyAqIGwxMikgKiB3OworICAgICAgICAgICAgICAgIG15MiA9IC0oeTEyICogbDIzIC0geTIzICogbDEyKSAqIHc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2luMyA9PSAwLjApIHsKKyAgICAgICAgICAgICAgICBteDMgPSBteDQ7CisgICAgICAgICAgICAgICAgbXkzID0gbXk0OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB3ID0gdzIgLyBzaW4zOworICAgICAgICAgICAgICAgIG14MyA9IC0oeDIzICogbDM0IC0geDM0ICogbDIzKSAqIHc7CisgICAgICAgICAgICAgICAgbXkzID0gLSh5MjMgKiBsMzQgLSB5MzQgKiBsMjMpICogdzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbHAuY3ViaWNUbyh4MiArIG14MiwgeTIgKyBteTIsIHgzICsgbXgzLCB5MyArIG15MywgeDQgKyBteDQsIHk0ICsgbXk0KTsKKyAgICAgICAgICAgIHJwLmN1YmljVG8oeDIgLSBteDIsIHkyIC0gbXkyLCB4MyAtIG14MywgeTMgLSBteTMsIHg0IC0gbXg0LCB5NCAtIG15NCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGRhc2hlZCBsaW5lIHNlZ21lbnQgdG8gdGhlIHdvcmsgcGF0aC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0IGxpbmUgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydCBsaW5lIHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIGxpbmUgcG9pbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgbGluZSBwb2ludC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZERhc2hMaW5lKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICBkb3VibGUgeDIxID0geDIgLSB4MTsKKyAgICAgICAgZG91YmxlIHkyMSA9IHkyIC0geTE7CisKKyAgICAgICAgZG91YmxlIGwyMSA9IE1hdGguc3FydCh4MjEgKiB4MjEgKyB5MjEgKiB5MjEpOworCisgICAgICAgIGlmIChsMjEgPT0gMC4wKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgcHgxLCBweTE7CisgICAgICAgIHB4MSA9IHB5MSA9IDAuMDsKKyAgICAgICAgZG91YmxlIHcgPSB3MiAvIGwyMTsKKyAgICAgICAgZG91YmxlIG14ID0gLXkyMSAqIHc7CisgICAgICAgIGRvdWJsZSBteSA9IHgyMSAqIHc7CisKKyAgICAgICAgZGFzaGVyLmluaXQobmV3IERhc2hJdGVyYXRvci5MaW5lKGwyMSkpOworCisgICAgICAgIHdoaWxlICghZGFzaGVyLmVvZigpKSB7CisgICAgICAgICAgICBkb3VibGUgdCA9IGRhc2hlci5nZXRWYWx1ZSgpOworICAgICAgICAgICAgc2N4ID0geDEgKyB0ICogeDIxOworICAgICAgICAgICAgc2N5ID0geTEgKyB0ICogeTIxOworCisgICAgICAgICAgICBpZiAoZGFzaGVyLmlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgcHgxID0gc2N4OworICAgICAgICAgICAgICAgIHB5MSA9IHNjeTsKKyAgICAgICAgICAgICAgICBkb3VibGUgbHgxID0gcHgxICsgbXg7CisgICAgICAgICAgICAgICAgZG91YmxlIGx5MSA9IHB5MSArIG15OworICAgICAgICAgICAgICAgIGRvdWJsZSByeDEgPSBweDEgLSBteDsKKyAgICAgICAgICAgICAgICBkb3VibGUgcnkxID0gcHkxIC0gbXk7CisgICAgICAgICAgICAgICAgaWYgKGlzTW92ZSkgeworICAgICAgICAgICAgICAgICAgICBpc01vdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgc214ID0gcHgxOworICAgICAgICAgICAgICAgICAgICBzbXkgPSBweTE7CisgICAgICAgICAgICAgICAgICAgIHJwLmNsZWFuKCk7CisgICAgICAgICAgICAgICAgICAgIGxwLm1vdmVUbyhseDEsIGx5MSk7CisgICAgICAgICAgICAgICAgICAgIHJwLm1vdmVUbyhyeDEsIHJ5MSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYWRkSm9pbihscCwgeDEsIHkxLCBseDEsIGx5MSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIGFkZEpvaW4ocnAsIHgxLCB5MSwgcngxLCByeTEsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGRhc2hlci5pc0NvbnRpbnVlKCkpIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgcHgyID0gc2N4OworICAgICAgICAgICAgICAgIGRvdWJsZSBweTIgPSBzY3k7CisgICAgICAgICAgICAgICAgbHAubGluZVRvKHB4MiArIG14LCBweTIgKyBteSk7CisgICAgICAgICAgICAgICAgcnAubGluZVRvKHB4MiAtIG14LCBweTIgLSBteSk7CisgICAgICAgICAgICAgICAgaWYgKGRhc2hlci5jbG9zZSkgeworICAgICAgICAgICAgICAgICAgICBhZGRDYXAobHAsIHB4MiwgcHkyLCBycC54TGFzdCwgcnAueUxhc3QpOworICAgICAgICAgICAgICAgICAgICBscC5jb21iaW5lKHJwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmlyc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZteCA9IHNteDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZteSA9IHNteTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNwID0gbHA7CisgICAgICAgICAgICAgICAgICAgICAgICBscCA9IG5ldyBCdWZmZXJlZFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZENhcChscCwgc214LCBzbXksIGxwLnhNb3ZlLCBscC55TW92ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBscC5jbG9zZVBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpc01vdmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZGFzaGVyLm5leHQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgZGFzaGVkIHF1YWQgc2VnbWVudCB0byB0aGUgd29yayBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTMKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIGNvbnRyb2wgcG9pbnQuCisgICAgICovCisgICAgdm9pZCBhZGREYXNoUXVhZChkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSB4MywgZG91YmxlIHkzKSB7CisKKyAgICAgICAgZG91YmxlIHgyMSA9IHgyIC0geDE7CisgICAgICAgIGRvdWJsZSB5MjEgPSB5MiAtIHkxOworICAgICAgICBkb3VibGUgeDIzID0geDIgLSB4MzsKKyAgICAgICAgZG91YmxlIHkyMyA9IHkyIC0geTM7CisKKyAgICAgICAgZG91YmxlIGwyMSA9IE1hdGguc3FydCh4MjEgKiB4MjEgKyB5MjEgKiB5MjEpOworICAgICAgICBkb3VibGUgbDIzID0gTWF0aC5zcXJ0KHgyMyAqIHgyMyArIHkyMyAqIHkyMyk7CisKKyAgICAgICAgaWYgKGwyMSA9PSAwLjAgJiYgbDIzID09IDAuMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGwyMSA9PSAwLjApIHsKKyAgICAgICAgICAgIGFkZERhc2hMaW5lKHgyLCB5MiwgeDMsIHkzKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsMjMgPT0gMC4wKSB7CisgICAgICAgICAgICBhZGREYXNoTGluZSh4MSwgeTEsIHgyLCB5Mik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgYXggPSB4MSArIHgzIC0geDIgLSB4MjsKKyAgICAgICAgZG91YmxlIGF5ID0geTEgKyB5MyAtIHkyIC0geTI7CisgICAgICAgIGRvdWJsZSBieCA9IHgyIC0geDE7CisgICAgICAgIGRvdWJsZSBieSA9IHkyIC0geTE7CisgICAgICAgIGRvdWJsZSBjeCA9IHgxOworICAgICAgICBkb3VibGUgY3kgPSB5MTsKKworICAgICAgICBkb3VibGUgcHgxLCBweTEsIGR4MSwgZHkxOworICAgICAgICBweDEgPSBweTEgPSBkeDEgPSBkeTEgPSAwLjA7CisgICAgICAgIGRvdWJsZSBwcmV2ID0gMC4wOworCisgICAgICAgIGRhc2hlci5pbml0KG5ldyBEYXNoSXRlcmF0b3IuUXVhZCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSk7CisKKyAgICAgICAgd2hpbGUgKCFkYXNoZXIuZW9mKCkpIHsKKyAgICAgICAgICAgIGRvdWJsZSB0ID0gZGFzaGVyLmdldFZhbHVlKCk7CisgICAgICAgICAgICBkb3VibGUgZHggPSB0ICogYXggKyBieDsKKyAgICAgICAgICAgIGRvdWJsZSBkeSA9IHQgKiBheSArIGJ5OworICAgICAgICAgICAgc2N4ID0gdCAqIChkeCArIGJ4KSArIGN4OyAvLyB0XjIgKiBheCArIDIuMCAqIHQgKiBieCArIGN4CisgICAgICAgICAgICBzY3kgPSB0ICogKGR5ICsgYnkpICsgY3k7IC8vIHReMiAqIGF5ICsgMi4wICogdCAqIGJ5ICsgY3kKKyAgICAgICAgICAgIGlmIChkYXNoZXIuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICBweDEgPSBzY3g7CisgICAgICAgICAgICAgICAgcHkxID0gc2N5OworICAgICAgICAgICAgICAgIGR4MSA9IGR4OworICAgICAgICAgICAgICAgIGR5MSA9IGR5OworICAgICAgICAgICAgICAgIGRvdWJsZSB3ID0gdzIgLyBNYXRoLnNxcnQoZHgxICogZHgxICsgZHkxICogZHkxKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgbXgxID0gLWR5MSAqIHc7CisgICAgICAgICAgICAgICAgZG91YmxlIG15MSA9IGR4MSAqIHc7CisgICAgICAgICAgICAgICAgZG91YmxlIGx4MSA9IHB4MSArIG14MTsKKyAgICAgICAgICAgICAgICBkb3VibGUgbHkxID0gcHkxICsgbXkxOworICAgICAgICAgICAgICAgIGRvdWJsZSByeDEgPSBweDEgLSBteDE7CisgICAgICAgICAgICAgICAgZG91YmxlIHJ5MSA9IHB5MSAtIG15MTsKKyAgICAgICAgICAgICAgICBpZiAoaXNNb3ZlKSB7CisgICAgICAgICAgICAgICAgICAgIGlzTW92ZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBzbXggPSBweDE7CisgICAgICAgICAgICAgICAgICAgIHNteSA9IHB5MTsKKyAgICAgICAgICAgICAgICAgICAgcnAuY2xlYW4oKTsKKyAgICAgICAgICAgICAgICAgICAgbHAubW92ZVRvKGx4MSwgbHkxKTsKKyAgICAgICAgICAgICAgICAgICAgcnAubW92ZVRvKHJ4MSwgcnkxKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhZGRKb2luKGxwLCB4MSwgeTEsIGx4MSwgbHkxLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgYWRkSm9pbihycCwgeDEsIHkxLCByeDEsIHJ5MSwgZmFsc2UpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZGFzaGVyLmlzQ29udGludWUoKSkgeworICAgICAgICAgICAgICAgIGRvdWJsZSBweDMgPSBzY3g7CisgICAgICAgICAgICAgICAgZG91YmxlIHB5MyA9IHNjeTsKKyAgICAgICAgICAgICAgICBkb3VibGUgc3ggPSB4MiAtIHgyMyAqIHByZXY7CisgICAgICAgICAgICAgICAgZG91YmxlIHN5ID0geTIgLSB5MjMgKiBwcmV2OworICAgICAgICAgICAgICAgIGRvdWJsZSB0MiA9ICh0IC0gcHJldikgLyAoMSAtIHByZXYpOworICAgICAgICAgICAgICAgIGRvdWJsZSBweDIgPSBweDEgKyAoc3ggLSBweDEpICogdDI7CisgICAgICAgICAgICAgICAgZG91YmxlIHB5MiA9IHB5MSArIChzeSAtIHB5MSkgKiB0MjsKKworICAgICAgICAgICAgICAgIGFkZFF1YWQocHgxLCBweTEsIHB4MiwgcHkyLCBweDMsIHB5Myk7CisgICAgICAgICAgICAgICAgaWYgKGRhc2hlci5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGFkZENhcChscCwgcHgzLCBweTMsIHJwLnhMYXN0LCBycC55TGFzdCk7CisgICAgICAgICAgICAgICAgICAgIGxwLmNvbWJpbmUocnApOworICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgZm14ID0gc214OworICAgICAgICAgICAgICAgICAgICAgICAgZm15ID0gc215OworICAgICAgICAgICAgICAgICAgICAgICAgc3AgPSBscDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxwID0gbmV3IEJ1ZmZlcmVkUGF0aCgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2FwKGxwLCBzbXgsIHNteSwgbHAueE1vdmUsIGxwLnlNb3ZlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxwLmNsb3NlUGF0aCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlzTW92ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcmV2ID0gdDsKKyAgICAgICAgICAgIGRhc2hlci5uZXh0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGRhc2hlZCBjdWJpYyBzZWdtZW50IHRvIHRoZSB3b3JrIHBhdGguCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgzCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0aGlyZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB5MworICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDQKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGZvdXJzIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHk0CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBmb3VycyBjb250cm9sIHBvaW50LgorICAgICAqLworICAgIHZvaWQgYWRkRGFzaEN1YmljKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHgzLCBkb3VibGUgeTMsIGRvdWJsZSB4NCwKKyAgICAgICAgICAgIGRvdWJsZSB5NCkgeworCisgICAgICAgIGRvdWJsZSB4MTIgPSB4MSAtIHgyOworICAgICAgICBkb3VibGUgeTEyID0geTEgLSB5MjsKKyAgICAgICAgZG91YmxlIHgyMyA9IHgyIC0geDM7CisgICAgICAgIGRvdWJsZSB5MjMgPSB5MiAtIHkzOworICAgICAgICBkb3VibGUgeDM0ID0geDMgLSB4NDsKKyAgICAgICAgZG91YmxlIHkzNCA9IHkzIC0geTQ7CisKKyAgICAgICAgZG91YmxlIGwxMiA9IE1hdGguc3FydCh4MTIgKiB4MTIgKyB5MTIgKiB5MTIpOworICAgICAgICBkb3VibGUgbDIzID0gTWF0aC5zcXJ0KHgyMyAqIHgyMyArIHkyMyAqIHkyMyk7CisgICAgICAgIGRvdWJsZSBsMzQgPSBNYXRoLnNxcnQoeDM0ICogeDM0ICsgeTM0ICogeTM0KTsKKworICAgICAgICAvLyBBbGwgZWRnZXMgYXJlIHplcm8KKyAgICAgICAgaWYgKGwxMiA9PSAwLjAgJiYgbDIzID09IDAuMCAmJiBsMzQgPT0gMC4wKSB7CisgICAgICAgICAgICAvLyBOT1RISU5HCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBPbmUgemVybyBlZGdlCisgICAgICAgIGlmIChsMTIgPT0gMC4wICYmIGwyMyA9PSAwLjApIHsKKyAgICAgICAgICAgIGFkZERhc2hMaW5lKHgzLCB5MywgeDQsIHk0KTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsMjMgPT0gMC4wICYmIGwzNCA9PSAwLjApIHsKKyAgICAgICAgICAgIGFkZERhc2hMaW5lKHgxLCB5MSwgeDIsIHkyKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsMTIgPT0gMC4wICYmIGwzNCA9PSAwLjApIHsKKyAgICAgICAgICAgIGFkZERhc2hMaW5lKHgyLCB5MiwgeDMsIHkzKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBheCA9IHg0IC0geDEgKyAzLjAgKiAoeDIgLSB4Myk7CisgICAgICAgIGRvdWJsZSBheSA9IHk0IC0geTEgKyAzLjAgKiAoeTIgLSB5Myk7CisgICAgICAgIGRvdWJsZSBieCA9IDMuMCAqICh4MSArIHgzIC0geDIgLSB4Mik7CisgICAgICAgIGRvdWJsZSBieSA9IDMuMCAqICh5MSArIHkzIC0geTIgLSB5Mik7CisgICAgICAgIGRvdWJsZSBjeCA9IDMuMCAqICh4MiAtIHgxKTsKKyAgICAgICAgZG91YmxlIGN5ID0gMy4wICogKHkyIC0geTEpOworICAgICAgICBkb3VibGUgZHggPSB4MTsKKyAgICAgICAgZG91YmxlIGR5ID0geTE7CisKKyAgICAgICAgZG91YmxlIHB4MSA9IDAuMDsKKyAgICAgICAgZG91YmxlIHB5MSA9IDAuMDsKKyAgICAgICAgZG91YmxlIHByZXYgPSAwLjA7CisKKyAgICAgICAgZGFzaGVyLmluaXQobmV3IERhc2hJdGVyYXRvci5DdWJpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpKTsKKworICAgICAgICB3aGlsZSAoIWRhc2hlci5lb2YoKSkgeworCisgICAgICAgICAgICBkb3VibGUgdCA9IGRhc2hlci5nZXRWYWx1ZSgpOworICAgICAgICAgICAgc2N4ID0gdCAqICh0ICogKHQgKiBheCArIGJ4KSArIGN4KSArIGR4OworICAgICAgICAgICAgc2N5ID0gdCAqICh0ICogKHQgKiBheSArIGJ5KSArIGN5KSArIGR5OworICAgICAgICAgICAgaWYgKGRhc2hlci5pc09wZW4oKSkgeworICAgICAgICAgICAgICAgIHB4MSA9IHNjeDsKKyAgICAgICAgICAgICAgICBweTEgPSBzY3k7CisgICAgICAgICAgICAgICAgZG91YmxlIGR4MSA9IHQgKiAodCAqIChheCArIGF4ICsgYXgpICsgYnggKyBieCkgKyBjeDsKKyAgICAgICAgICAgICAgICBkb3VibGUgZHkxID0gdCAqICh0ICogKGF5ICsgYXkgKyBheSkgKyBieSArIGJ5KSArIGN5OworICAgICAgICAgICAgICAgIGRvdWJsZSB3ID0gdzIgLyBNYXRoLnNxcnQoZHgxICogZHgxICsgZHkxICogZHkxKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgbXgxID0gLWR5MSAqIHc7CisgICAgICAgICAgICAgICAgZG91YmxlIG15MSA9IGR4MSAqIHc7CisgICAgICAgICAgICAgICAgZG91YmxlIGx4MSA9IHB4MSArIG14MTsKKyAgICAgICAgICAgICAgICBkb3VibGUgbHkxID0gcHkxICsgbXkxOworICAgICAgICAgICAgICAgIGRvdWJsZSByeDEgPSBweDEgLSBteDE7CisgICAgICAgICAgICAgICAgZG91YmxlIHJ5MSA9IHB5MSAtIG15MTsKKyAgICAgICAgICAgICAgICBpZiAoaXNNb3ZlKSB7CisgICAgICAgICAgICAgICAgICAgIGlzTW92ZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBzbXggPSBweDE7CisgICAgICAgICAgICAgICAgICAgIHNteSA9IHB5MTsKKyAgICAgICAgICAgICAgICAgICAgcnAuY2xlYW4oKTsKKyAgICAgICAgICAgICAgICAgICAgbHAubW92ZVRvKGx4MSwgbHkxKTsKKyAgICAgICAgICAgICAgICAgICAgcnAubW92ZVRvKHJ4MSwgcnkxKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhZGRKb2luKGxwLCB4MSwgeTEsIGx4MSwgbHkxLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgYWRkSm9pbihycCwgeDEsIHkxLCByeDEsIHJ5MSwgZmFsc2UpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZGFzaGVyLmlzQ29udGludWUoKSkgeworICAgICAgICAgICAgICAgIGRvdWJsZSBzeDEgPSB4MiAtIHgyMyAqIHByZXY7CisgICAgICAgICAgICAgICAgZG91YmxlIHN5MSA9IHkyIC0geTIzICogcHJldjsKKyAgICAgICAgICAgICAgICBkb3VibGUgc3gyID0geDMgLSB4MzQgKiBwcmV2OworICAgICAgICAgICAgICAgIGRvdWJsZSBzeTIgPSB5MyAtIHkzNCAqIHByZXY7CisgICAgICAgICAgICAgICAgZG91YmxlIHN4MyA9IHN4MSArIChzeDIgLSBzeDEpICogcHJldjsKKyAgICAgICAgICAgICAgICBkb3VibGUgc3kzID0gc3kxICsgKHN5MiAtIHN5MSkgKiBwcmV2OworICAgICAgICAgICAgICAgIGRvdWJsZSB0MiA9ICh0IC0gcHJldikgLyAoMSAtIHByZXYpOworICAgICAgICAgICAgICAgIGRvdWJsZSBzeDQgPSBzeDMgKyAoc3gyIC0gc3gzKSAqIHQyOworICAgICAgICAgICAgICAgIGRvdWJsZSBzeTQgPSBzeTMgKyAoc3kyIC0gc3kzKSAqIHQyOworCisgICAgICAgICAgICAgICAgZG91YmxlIHB4NCA9IHNjeDsKKyAgICAgICAgICAgICAgICBkb3VibGUgcHk0ID0gc2N5OworICAgICAgICAgICAgICAgIGRvdWJsZSBweDIgPSBweDEgKyAoc3gzIC0gcHgxKSAqIHQyOworICAgICAgICAgICAgICAgIGRvdWJsZSBweTIgPSBweTEgKyAoc3kzIC0gcHkxKSAqIHQyOworICAgICAgICAgICAgICAgIGRvdWJsZSBweDMgPSBweDIgKyAoc3g0IC0gcHgyKSAqIHQyOworICAgICAgICAgICAgICAgIGRvdWJsZSBweTMgPSBweTIgKyAoc3k0IC0gcHkyKSAqIHQyOworCisgICAgICAgICAgICAgICAgYWRkQ3ViaWMocHgxLCBweTEsIHB4MiwgcHkyLCBweDMsIHB5MywgcHg0LCBweTQpOworICAgICAgICAgICAgICAgIGlmIChkYXNoZXIuaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgICAgICAgICBhZGRDYXAobHAsIHB4NCwgcHk0LCBycC54TGFzdCwgcnAueUxhc3QpOworICAgICAgICAgICAgICAgICAgICBscC5jb21iaW5lKHJwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmlyc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZteCA9IHNteDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZteSA9IHNteTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNwID0gbHA7CisgICAgICAgICAgICAgICAgICAgICAgICBscCA9IG5ldyBCdWZmZXJlZFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZENhcChscCwgc214LCBzbXksIGxwLnhNb3ZlLCBscC55TW92ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBscC5jbG9zZVBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpc01vdmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHJldiA9IHQ7CisgICAgICAgICAgICBkYXNoZXIubmV4dCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGFzaGVyIGNsYXNzIHByb3ZpZGVzIGRhc2hpbmcgZm9yIHBhcnRpY3VsYXIgZGFzaCBzdHlsZS4KKyAgICAgKi8KKyAgICBjbGFzcyBEYXNoZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcG9zLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHBvczsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGZpcnN0LgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBjbG9zZSwgdmlzaWJsZSwgZmlyc3Q7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBkYXNoLgorICAgICAgICAgKi8KKyAgICAgICAgZmxvYXQgZGFzaFtdOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcGhhc2UuCisgICAgICAgICAqLworICAgICAgICBmbG9hdCBwaGFzZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGluZGV4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgaXRlci4KKyAgICAgICAgICovCisgICAgICAgIERhc2hJdGVyYXRvciBpdGVyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGFzaGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGRhc2gKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZGFzaC4KKyAgICAgICAgICogQHBhcmFtIHBoYXNlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHBoYXNlLgorICAgICAgICAgKi8KKyAgICAgICAgRGFzaGVyKGZsb2F0IGRhc2hbXSwgZmxvYXQgcGhhc2UpIHsKKyAgICAgICAgICAgIHRoaXMuZGFzaCA9IGRhc2g7CisgICAgICAgICAgICB0aGlzLnBoYXNlID0gcGhhc2U7CisgICAgICAgICAgICBpbmRleCA9IDA7CisgICAgICAgICAgICBwb3MgPSBwaGFzZTsKKyAgICAgICAgICAgIHZpc2libGUgPSB0cnVlOworICAgICAgICAgICAgd2hpbGUgKHBvcyA+PSBkYXNoW2luZGV4XSkgeworICAgICAgICAgICAgICAgIHZpc2libGUgPSAhdmlzaWJsZTsKKyAgICAgICAgICAgICAgICBwb3MgLT0gZGFzaFtpbmRleF07CisgICAgICAgICAgICAgICAgaW5kZXggPSAoaW5kZXggKyAxKSAlIGRhc2gubGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcG9zID0gLXBvczsKKyAgICAgICAgICAgIGZpcnN0ID0gdmlzaWJsZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbml0cyB0aGUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gaXRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBpdGVyLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBpbml0KERhc2hJdGVyYXRvciBpdGVyKSB7CisgICAgICAgICAgICB0aGlzLml0ZXIgPSBpdGVyOworICAgICAgICAgICAgY2xvc2UgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBpZiBpcyBvcGVuLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBvcGVuLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBpc09wZW4oKSB7CisgICAgICAgICAgICByZXR1cm4gdmlzaWJsZSAmJiBwb3MgPCBpdGVyLmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGVja3MgaWYgaXMgY29udGludWUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGlzIGNvbnRpbnVlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBpc0NvbnRpbnVlKCkgeworICAgICAgICAgICAgcmV0dXJuICF2aXNpYmxlICYmIHBvcyA+IDA7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGlmIGlzIGNsb3NlZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaXMgY2xvc2VkLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBpc0Nsb3NlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjbG9zZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGVja3MgaWYgaXMgY29ubmVjdGVkLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBjb25uZWN0ZWQuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGZpcnN0ICYmICFjbG9zZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBFb2YuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGVvZigpIHsKKyAgICAgICAgICAgIGlmICghY2xvc2UpIHsKKyAgICAgICAgICAgICAgICBwb3MgLT0gaXRlci5sZW5ndGg7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocG9zID49IGl0ZXIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgaWYgKHZpc2libGUpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zIC09IGl0ZXIubGVuZ3RoOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2xvc2UgPSBwb3MgPT0gaXRlci5sZW5ndGg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTmV4dC4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChjbG9zZSkgeworICAgICAgICAgICAgICAgIHBvcyArPSBkYXNoW2luZGV4XTsKKyAgICAgICAgICAgICAgICBpbmRleCA9IChpbmRleCArIDEpICUgZGFzaC5sZW5ndGg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEdvIGJhY2sKKyAgICAgICAgICAgICAgICBpbmRleCA9IChpbmRleCArIGRhc2gubGVuZ3RoIC0gMSkgJSBkYXNoLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBwb3MgLT0gZGFzaFtpbmRleF07CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2aXNpYmxlID0gIXZpc2libGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgdmFsdWUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZS4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIGRvdWJsZSB0ID0gaXRlci5nZXROZXh0KHBvcyk7CisgICAgICAgICAgICByZXR1cm4gdCA8IDAgPyAwIDogKHQgPiAxID8gMSA6IHQpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEYXNoSXRlcmF0b3IgY2xhc3MgcHJvdmlkZXMgZGFzaGluZyBmb3IgcGFydGljdWxhciBzZWdtZW50IHR5cGUuCisgICAgICovCisgICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIERhc2hJdGVyYXRvciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBDb25zdGFudCBGTEFUTkVTUy4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBkb3VibGUgRkxBVE5FU1MgPSAxLjA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBDbGFzcyBMaW5lLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGNsYXNzIExpbmUgZXh0ZW5kcyBEYXNoSXRlcmF0b3IgeworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBsaW5lLgorICAgICAgICAgICAgICogCisgICAgICAgICAgICAgKiBAcGFyYW0gbGVuCisgICAgICAgICAgICAgKiAgICAgICAgICAgIHRoZSBsZW4uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIExpbmUoZG91YmxlIGxlbikgeworICAgICAgICAgICAgICAgIGxlbmd0aCA9IGxlbjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBkb3VibGUgZ2V0TmV4dChkb3VibGUgZGFzaFBvcykgeworICAgICAgICAgICAgICAgIHJldHVybiBkYXNoUG9zIC8gbGVuZ3RoOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIENsYXNzIFF1YWQuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgY2xhc3MgUXVhZCBleHRlbmRzIERhc2hJdGVyYXRvciB7CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogVGhlIHZhbCBzaXplLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpbnQgdmFsU2l6ZTsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgdmFsIHBvcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHZhbFBvczsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgY3VyIGxlbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlIGN1ckxlbjsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgcHJldiBsZW4uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGRvdWJsZSBwcmV2TGVuOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBsYXN0IGxlbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlIGxhc3RMZW47CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogVGhlIHZhbHVlcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlW10gdmFsdWVzOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBzdGVwLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBkb3VibGUgc3RlcDsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcXVhZC4KKyAgICAgICAgICAgICAqIAorICAgICAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4MS4KKyAgICAgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgICAgICogICAgICAgICAgICB0aGUgeTEuCisgICAgICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHgyLgorICAgICAgICAgICAgICogQHBhcmFtIHkyCisgICAgICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5Mi4KKyAgICAgICAgICAgICAqIEBwYXJhbSB4MworICAgICAgICAgICAgICogICAgICAgICAgICB0aGUgeDMuCisgICAgICAgICAgICAgKiBAcGFyYW0geTMKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHkzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBRdWFkKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHgzLCBkb3VibGUgeTMpIHsKKworICAgICAgICAgICAgICAgIGRvdWJsZSBueCA9IHgxICsgeDMgLSB4MiAtIHgyOworICAgICAgICAgICAgICAgIGRvdWJsZSBueSA9IHkxICsgeTMgLSB5MiAtIHkyOworCisgICAgICAgICAgICAgICAgaW50IG4gPSAoaW50KSgxICsgTWF0aC5zcXJ0KDAuNzUgKiAoTWF0aC5hYnMobngpICsgTWF0aC5hYnMobnkpKSAqIEZMQVRORVNTKSk7CisgICAgICAgICAgICAgICAgc3RlcCA9IDEuMCAvIG47CisKKyAgICAgICAgICAgICAgICBkb3VibGUgYXggPSB4MSArIHgzIC0geDIgLSB4MjsKKyAgICAgICAgICAgICAgICBkb3VibGUgYXkgPSB5MSArIHkzIC0geTIgLSB5MjsKKyAgICAgICAgICAgICAgICBkb3VibGUgYnggPSAyLjAgKiAoeDIgLSB4MSk7CisgICAgICAgICAgICAgICAgZG91YmxlIGJ5ID0gMi4wICogKHkyIC0geTEpOworCisgICAgICAgICAgICAgICAgZG91YmxlIGR4MSA9IHN0ZXAgKiAoc3RlcCAqIGF4ICsgYngpOworICAgICAgICAgICAgICAgIGRvdWJsZSBkeTEgPSBzdGVwICogKHN0ZXAgKiBheSArIGJ5KTsKKyAgICAgICAgICAgICAgICBkb3VibGUgZHgyID0gc3RlcCAqIChzdGVwICogYXggKiAyLjApOworICAgICAgICAgICAgICAgIGRvdWJsZSBkeTIgPSBzdGVwICogKHN0ZXAgKiBheSAqIDIuMCk7CisgICAgICAgICAgICAgICAgZG91YmxlIHZ4ID0geDE7CisgICAgICAgICAgICAgICAgZG91YmxlIHZ5ID0geTE7CisKKyAgICAgICAgICAgICAgICB2YWxTaXplID0gbjsKKyAgICAgICAgICAgICAgICB2YWx1ZXMgPSBuZXcgZG91YmxlW3ZhbFNpemVdOworICAgICAgICAgICAgICAgIGRvdWJsZSBwdnggPSB2eDsKKyAgICAgICAgICAgICAgICBkb3VibGUgcHZ5ID0gdnk7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gMC4wOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHZ4ICs9IGR4MTsKKyAgICAgICAgICAgICAgICAgICAgdnkgKz0gZHkxOworICAgICAgICAgICAgICAgICAgICBkeDEgKz0gZHgyOworICAgICAgICAgICAgICAgICAgICBkeTEgKz0gZHkyOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgbHggPSB2eCAtIHB2eDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGx5ID0gdnkgLSBwdnk7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tpXSA9IE1hdGguc3FydChseCAqIGx4ICsgbHkgKiBseSk7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCArPSB2YWx1ZXNbaV07CisgICAgICAgICAgICAgICAgICAgIHB2eCA9IHZ4OworICAgICAgICAgICAgICAgICAgICBwdnkgPSB2eTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB2YWxQb3MgPSAwOworICAgICAgICAgICAgICAgIGN1ckxlbiA9IDAuMDsKKyAgICAgICAgICAgICAgICBwcmV2TGVuID0gMC4wOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIGRvdWJsZSBnZXROZXh0KGRvdWJsZSBkYXNoUG9zKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIHQgPSAyLjA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGN1ckxlbiA8PSBkYXNoUG9zICYmIHZhbFBvcyA8IHZhbFNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJldkxlbiA9IGN1ckxlbjsKKyAgICAgICAgICAgICAgICAgICAgY3VyTGVuICs9IGxhc3RMZW4gPSB2YWx1ZXNbdmFsUG9zKytdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY3VyTGVuID4gZGFzaFBvcykgeworICAgICAgICAgICAgICAgICAgICB0ID0gKHZhbFBvcyAtIDEgKyAoZGFzaFBvcyAtIHByZXZMZW4pIC8gbGFzdExlbikgKiBzdGVwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBDbGFzcyBDdWJpYy4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBjbGFzcyBDdWJpYyBleHRlbmRzIERhc2hJdGVyYXRvciB7CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogVGhlIHZhbCBzaXplLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpbnQgdmFsU2l6ZTsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgdmFsIHBvcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHZhbFBvczsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgY3VyIGxlbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlIGN1ckxlbjsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgcHJldiBsZW4uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGRvdWJsZSBwcmV2TGVuOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBsYXN0IGxlbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlIGxhc3RMZW47CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogVGhlIHZhbHVlcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG91YmxlW10gdmFsdWVzOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBzdGVwLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBkb3VibGUgc3RlcDsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgY3ViaWMuCisgICAgICAgICAgICAgKiAKKyAgICAgICAgICAgICAqIEBwYXJhbSB4MQorICAgICAgICAgICAgICogICAgICAgICAgICB0aGUgeDEuCisgICAgICAgICAgICAgKiBAcGFyYW0geTEKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHkxLgorICAgICAgICAgICAgICogQHBhcmFtIHgyCisgICAgICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4Mi4KKyAgICAgICAgICAgICAqIEBwYXJhbSB5MgorICAgICAgICAgICAgICogICAgICAgICAgICB0aGUgeTIuCisgICAgICAgICAgICAgKiBAcGFyYW0geDMKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHgzLgorICAgICAgICAgICAgICogQHBhcmFtIHkzCisgICAgICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5My4KKyAgICAgICAgICAgICAqIEBwYXJhbSB4NAorICAgICAgICAgICAgICogICAgICAgICAgICB0aGUgeDQuCisgICAgICAgICAgICAgKiBAcGFyYW0geTQKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHk0LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBDdWJpYyhkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSB4MywgZG91YmxlIHkzLCBkb3VibGUgeDQsCisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB5NCkgeworCisgICAgICAgICAgICAgICAgZG91YmxlIG54MSA9IHgxICsgeDMgLSB4MiAtIHgyOworICAgICAgICAgICAgICAgIGRvdWJsZSBueTEgPSB5MSArIHkzIC0geTIgLSB5MjsKKyAgICAgICAgICAgICAgICBkb3VibGUgbngyID0geDIgKyB4NCAtIHgzIC0geDM7CisgICAgICAgICAgICAgICAgZG91YmxlIG55MiA9IHkyICsgeTQgLSB5MyAtIHkzOworCisgICAgICAgICAgICAgICAgZG91YmxlIG1heCA9IE1hdGgubWF4KE1hdGguYWJzKG54MSkgKyBNYXRoLmFicyhueTEpLCBNYXRoLmFicyhueDIpICsgTWF0aC5hYnMobnkyKSk7CisgICAgICAgICAgICAgICAgaW50IG4gPSAoaW50KSgxICsgTWF0aC5zcXJ0KDAuNzUgKiBtYXgpICogRkxBVE5FU1MpOworICAgICAgICAgICAgICAgIHN0ZXAgPSAxLjAgLyBuOworCisgICAgICAgICAgICAgICAgZG91YmxlIGF4ID0geDQgLSB4MSArIDMuMCAqICh4MiAtIHgzKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgYXkgPSB5NCAtIHkxICsgMy4wICogKHkyIC0geTMpOworICAgICAgICAgICAgICAgIGRvdWJsZSBieCA9IDMuMCAqICh4MSArIHgzIC0geDIgLSB4Mik7CisgICAgICAgICAgICAgICAgZG91YmxlIGJ5ID0gMy4wICogKHkxICsgeTMgLSB5MiAtIHkyKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgY3ggPSAzLjAgKiAoeDIgLSB4MSk7CisgICAgICAgICAgICAgICAgZG91YmxlIGN5ID0gMy4wICogKHkyIC0geTEpOworCisgICAgICAgICAgICAgICAgZG91YmxlIGR4MSA9IHN0ZXAgKiAoc3RlcCAqIChzdGVwICogYXggKyBieCkgKyBjeCk7CisgICAgICAgICAgICAgICAgZG91YmxlIGR5MSA9IHN0ZXAgKiAoc3RlcCAqIChzdGVwICogYXkgKyBieSkgKyBjeSk7CisgICAgICAgICAgICAgICAgZG91YmxlIGR4MiA9IHN0ZXAgKiAoc3RlcCAqIChzdGVwICogYXggKiA2LjAgKyBieCAqIDIuMCkpOworICAgICAgICAgICAgICAgIGRvdWJsZSBkeTIgPSBzdGVwICogKHN0ZXAgKiAoc3RlcCAqIGF5ICogNi4wICsgYnkgKiAyLjApKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgZHgzID0gc3RlcCAqIChzdGVwICogKHN0ZXAgKiBheCAqIDYuMCkpOworICAgICAgICAgICAgICAgIGRvdWJsZSBkeTMgPSBzdGVwICogKHN0ZXAgKiAoc3RlcCAqIGF5ICogNi4wKSk7CisgICAgICAgICAgICAgICAgZG91YmxlIHZ4ID0geDE7CisgICAgICAgICAgICAgICAgZG91YmxlIHZ5ID0geTE7CisKKyAgICAgICAgICAgICAgICB2YWxTaXplID0gbjsKKyAgICAgICAgICAgICAgICB2YWx1ZXMgPSBuZXcgZG91YmxlW3ZhbFNpemVdOworICAgICAgICAgICAgICAgIGRvdWJsZSBwdnggPSB2eDsKKyAgICAgICAgICAgICAgICBkb3VibGUgcHZ5ID0gdnk7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gMC4wOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHZ4ICs9IGR4MTsKKyAgICAgICAgICAgICAgICAgICAgdnkgKz0gZHkxOworICAgICAgICAgICAgICAgICAgICBkeDEgKz0gZHgyOworICAgICAgICAgICAgICAgICAgICBkeTEgKz0gZHkyOworICAgICAgICAgICAgICAgICAgICBkeDIgKz0gZHgzOworICAgICAgICAgICAgICAgICAgICBkeTIgKz0gZHkzOworICAgICAgICAgICAgICAgICAgICBkb3VibGUgbHggPSB2eCAtIHB2eDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGx5ID0gdnkgLSBwdnk7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tpXSA9IE1hdGguc3FydChseCAqIGx4ICsgbHkgKiBseSk7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCArPSB2YWx1ZXNbaV07CisgICAgICAgICAgICAgICAgICAgIHB2eCA9IHZ4OworICAgICAgICAgICAgICAgICAgICBwdnkgPSB2eTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB2YWxQb3MgPSAwOworICAgICAgICAgICAgICAgIGN1ckxlbiA9IDAuMDsKKyAgICAgICAgICAgICAgICBwcmV2TGVuID0gMC4wOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIGRvdWJsZSBnZXROZXh0KGRvdWJsZSBkYXNoUG9zKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIHQgPSAyLjA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGN1ckxlbiA8PSBkYXNoUG9zICYmIHZhbFBvcyA8IHZhbFNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJldkxlbiA9IGN1ckxlbjsKKyAgICAgICAgICAgICAgICAgICAgY3VyTGVuICs9IGxhc3RMZW4gPSB2YWx1ZXNbdmFsUG9zKytdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY3VyTGVuID4gZGFzaFBvcykgeworICAgICAgICAgICAgICAgICAgICB0ID0gKHZhbFBvcyAtIDEgKyAoZGFzaFBvcyAtIHByZXZMZW4pIC8gbGFzdExlbikgKiBzdGVwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBsZW5ndGguCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgbGVuZ3RoOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSBuZXh0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGRhc2hQb3MKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZGFzaCBwb3MuCisgICAgICAgICAqIEByZXR1cm4gdGhlIG5leHQuCisgICAgICAgICAqLworICAgICAgICBhYnN0cmFjdCBkb3VibGUgZ2V0TmV4dChkb3VibGUgZGFzaFBvcyk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWZmZXJlZFBhdGggY2xhc3MgcHJvdmlkZXMgd29yayBwYXRoIHN0b3JpbmcgYW5kIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIEJ1ZmZlcmVkUGF0aCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBDb25zdGFudCBidWZDYXBhY2l0eS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBidWZDYXBhY2l0eSA9IDEwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcG9pbnQgc2hpZnQuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgaW50IHBvaW50U2hpZnRbXSA9IHsKKyAgICAgICAgICAgICAgICAyLCAvLyBNT1ZFVE8KKyAgICAgICAgICAgICAgICAyLCAvLyBMSU5FVE8KKyAgICAgICAgICAgICAgICA0LCAvLyBRVUFEVE8KKyAgICAgICAgICAgICAgICA2LCAvLyBDVUJJQ1RPCisgICAgICAgICAgICAgICAgMAorICAgICAgICB9OyAvLyBDTE9TRQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdHlwZXMuCisgICAgICAgICAqLworICAgICAgICBieXRlW10gdHlwZXM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBwb2ludHMuCisgICAgICAgICAqLworICAgICAgICBmbG9hdFtdIHBvaW50czsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHR5cGUgc2l6ZS4KKyAgICAgICAgICovCisgICAgICAgIGludCB0eXBlU2l6ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBvaW50IHNpemUuCisgICAgICAgICAqLworICAgICAgICBpbnQgcG9pbnRTaXplOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBsYXN0LgorICAgICAgICAgKi8KKyAgICAgICAgZmxvYXQgeExhc3Q7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGxhc3QuCisgICAgICAgICAqLworICAgICAgICBmbG9hdCB5TGFzdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggbW92ZS4KKyAgICAgICAgICovCisgICAgICAgIGZsb2F0IHhNb3ZlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBtb3ZlLgorICAgICAgICAgKi8KKyAgICAgICAgZmxvYXQgeU1vdmU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBidWZmZXJlZCBwYXRoLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJ1ZmZlcmVkUGF0aCgpIHsKKyAgICAgICAgICAgIHR5cGVzID0gbmV3IGJ5dGVbYnVmQ2FwYWNpdHldOworICAgICAgICAgICAgcG9pbnRzID0gbmV3IGZsb2F0W2J1ZkNhcGFjaXR5ICogMl07CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2sgYnVmLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHR5cGVDb3VudAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIGNvdW50LgorICAgICAgICAgKiBAcGFyYW0gcG9pbnRDb3VudAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBjb3VudC4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgY2hlY2tCdWYoaW50IHR5cGVDb3VudCwgaW50IHBvaW50Q291bnQpIHsKKyAgICAgICAgICAgIGlmICh0eXBlU2l6ZSArIHR5cGVDb3VudCA+IHR5cGVzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGJ5dGUgdG1wW10gPSBuZXcgYnl0ZVt0eXBlU2l6ZSArIE1hdGgubWF4KGJ1ZkNhcGFjaXR5LCB0eXBlQ291bnQpXTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHR5cGVzLCAwLCB0bXAsIDAsIHR5cGVTaXplKTsKKyAgICAgICAgICAgICAgICB0eXBlcyA9IHRtcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwb2ludFNpemUgKyBwb2ludENvdW50ID4gcG9pbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGZsb2F0IHRtcFtdID0gbmV3IGZsb2F0W3BvaW50U2l6ZSArIE1hdGgubWF4KGJ1ZkNhcGFjaXR5ICogMiwgcG9pbnRDb3VudCldOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocG9pbnRzLCAwLCB0bXAsIDAsIHBvaW50U2l6ZSk7CisgICAgICAgICAgICAgICAgcG9pbnRzID0gdG1wOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBpZiBpcyBlbXB0eS4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaXMgZW1wdHkuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gdHlwZVNpemUgPT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDbGVhbi4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgY2xlYW4oKSB7CisgICAgICAgICAgICB0eXBlU2l6ZSA9IDA7CisgICAgICAgICAgICBwb2ludFNpemUgPSAwOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1vdmUgdG8uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4LgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBtb3ZlVG8oZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgICAgICBjaGVja0J1ZigxLCAyKTsKKyAgICAgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE87CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geE1vdmUgPSAoZmxvYXQpeDsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB5TW92ZSA9IChmbG9hdCl5OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExpbmUgdG8uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4LgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBsaW5lVG8oZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgICAgICBjaGVja0J1ZigxLCAyKTsKKyAgICAgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19MSU5FVE87CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geExhc3QgPSAoZmxvYXQpeDsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB5TGFzdCA9IChmbG9hdCl5OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFF1YWQgdG8uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeDEuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5MS4KKyAgICAgICAgICogQHBhcmFtIHgyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHgyLgorICAgICAgICAgKiBAcGFyYW0geTIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeTIuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHF1YWRUbyhkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgICAgIGNoZWNrQnVmKDEsIDQpOworICAgICAgICAgICAgdHlwZXNbdHlwZVNpemUrK10gPSBQYXRoSXRlcmF0b3IuU0VHX1FVQURUTzsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSAoZmxvYXQpeDE7CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0gKGZsb2F0KXkxOworICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHhMYXN0ID0gKGZsb2F0KXgyOworICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHlMYXN0ID0gKGZsb2F0KXkyOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEN1YmljIHRvLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHgxLgorICAgICAgICAgKiBAcGFyYW0geTEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeTEuCisgICAgICAgICAqIEBwYXJhbSB4MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4Mi4KKyAgICAgICAgICogQHBhcmFtIHkyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkyLgorICAgICAgICAgKiBAcGFyYW0geDMKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeDMuCisgICAgICAgICAqIEBwYXJhbSB5MworICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5My4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgY3ViaWNUbyhkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSB4MywgZG91YmxlIHkzKSB7CisgICAgICAgICAgICBjaGVja0J1ZigxLCA2KTsKKyAgICAgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOworICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IChmbG9hdCl4MTsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSAoZmxvYXQpeTE7CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0gKGZsb2F0KXgyOworICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IChmbG9hdCl5MjsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB4TGFzdCA9IChmbG9hdCl4MzsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB5TGFzdCA9IChmbG9hdCl5MzsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDbG9zZSBwYXRoLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBjbG9zZVBhdGgoKSB7CisgICAgICAgICAgICBjaGVja0J1ZigxLCAwKTsKKyAgICAgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19DTE9TRTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZSBsYXN0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeC4KKyAgICAgICAgICogQHBhcmFtIHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeS4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgc2V0TGFzdChkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUgLSAyXSA9IHhMYXN0ID0gKGZsb2F0KXg7CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplIC0gMV0gPSB5TGFzdCA9IChmbG9hdCl5OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFwcGVuZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBwCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHAuCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFwcGVuZChCdWZmZXJlZFBhdGggcCkgeworICAgICAgICAgICAgY2hlY2tCdWYocC50eXBlU2l6ZSwgcC5wb2ludFNpemUpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwLnBvaW50cywgMCwgcG9pbnRzLCBwb2ludFNpemUsIHAucG9pbnRTaXplKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocC50eXBlcywgMCwgdHlwZXMsIHR5cGVTaXplLCBwLnR5cGVTaXplKTsKKyAgICAgICAgICAgIHBvaW50U2l6ZSArPSBwLnBvaW50U2l6ZTsKKyAgICAgICAgICAgIHR5cGVTaXplICs9IHAudHlwZVNpemU7CisgICAgICAgICAgICB4TGFzdCA9IHBvaW50c1twb2ludFNpemUgLSAyXTsKKyAgICAgICAgICAgIHlMYXN0ID0gcG9pbnRzW3BvaW50U2l6ZSAtIDFdOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFwcGVuZCByZXZlcnNlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHAKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcC4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgYXBwZW5kUmV2ZXJzZShCdWZmZXJlZFBhdGggcCkgeworICAgICAgICAgICAgY2hlY2tCdWYocC50eXBlU2l6ZSwgcC5wb2ludFNpemUpOworICAgICAgICAgICAgLy8gU2tpcCBsYXN0IHBvaW50LCBiZWFjYXVzZSBpdCdzIHRoZSBmaXJzdCBwb2ludCBvZiB0aGUgc2Vjb25kIHBhdGgKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBwLnBvaW50U2l6ZSAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7CisgICAgICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHAucG9pbnRzW2kgKyAwXTsKKyAgICAgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0gcC5wb2ludHNbaSArIDFdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gU2tpcCBmaXJzdCB0eXBlLCBiZWFjdXNlIGl0J3MgYWx3YXlzIE1PVkVUTworICAgICAgICAgICAgaW50IGNsb3NlSW5kZXggPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHAudHlwZVNpemUgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgICAgIGJ5dGUgdHlwZSA9IHAudHlwZXNbaV07CisgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE8pIHsKKyAgICAgICAgICAgICAgICAgICAgdHlwZXNbY2xvc2VJbmRleF0gPSBQYXRoSXRlcmF0b3IuU0VHX01PVkVUTzsKKyAgICAgICAgICAgICAgICAgICAgdHlwZXNbdHlwZVNpemUrK10gPSBQYXRoSXRlcmF0b3IuU0VHX0NMT1NFOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFBhdGhJdGVyYXRvci5TRUdfQ0xPU0UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlSW5kZXggPSB0eXBlU2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB0eXBlc1t0eXBlU2l6ZSsrXSA9IHR5cGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgeExhc3QgPSBwb2ludHNbcG9pbnRTaXplIC0gMl07CisgICAgICAgICAgICB5TGFzdCA9IHBvaW50c1twb2ludFNpemUgLSAxXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBKb2luLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHAKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcC4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgam9pbihCdWZmZXJlZFBhdGggcCkgeworICAgICAgICAgICAgLy8gU2tpcCBNT1ZFVE8KKyAgICAgICAgICAgIGNoZWNrQnVmKHAudHlwZVNpemUgLSAxLCBwLnBvaW50U2l6ZSAtIDIpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwLnBvaW50cywgMiwgcG9pbnRzLCBwb2ludFNpemUsIHAucG9pbnRTaXplIC0gMik7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHAudHlwZXMsIDEsIHR5cGVzLCB0eXBlU2l6ZSwgcC50eXBlU2l6ZSAtIDEpOworICAgICAgICAgICAgcG9pbnRTaXplICs9IHAucG9pbnRTaXplIC0gMjsKKyAgICAgICAgICAgIHR5cGVTaXplICs9IHAudHlwZVNpemUgLSAxOworICAgICAgICAgICAgeExhc3QgPSBwb2ludHNbcG9pbnRTaXplIC0gMl07CisgICAgICAgICAgICB5TGFzdCA9IHBvaW50c1twb2ludFNpemUgLSAxXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb21iaW5lLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHAKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcC4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgY29tYmluZShCdWZmZXJlZFBhdGggcCkgeworICAgICAgICAgICAgY2hlY2tCdWYocC50eXBlU2l6ZSAtIDEsIHAucG9pbnRTaXplIC0gMik7CisgICAgICAgICAgICAvLyBTa2lwIGxhc3QgcG9pbnQsIGJlYWNhdXNlIGl0J3MgdGhlIGZpcnN0IHBvaW50IG9mIHRoZSBzZWNvbmQgcGF0aAorICAgICAgICAgICAgZm9yIChpbnQgaSA9IHAucG9pbnRTaXplIC0gNDsgaSA+PSAwOyBpIC09IDIpIHsKKyAgICAgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0gcC5wb2ludHNbaSArIDBdOworICAgICAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSBwLnBvaW50c1tpICsgMV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBTa2lwIGZpcnN0IHR5cGUsIGJlYWN1c2UgaXQncyBhbHdheXMgTU9WRVRPCisgICAgICAgICAgICBmb3IgKGludCBpID0gcC50eXBlU2l6ZSAtIDE7IGkgPj0gMTsgaS0tKSB7CisgICAgICAgICAgICAgICAgdHlwZXNbdHlwZVNpemUrK10gPSBwLnR5cGVzW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeExhc3QgPSBwb2ludHNbcG9pbnRTaXplIC0gMl07CisgICAgICAgICAgICB5TGFzdCA9IHBvaW50c1twb2ludFNpemUgLSAxXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIHRoZSBnZW5lcmFsIHBhdGguCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmFsIHBhdGguCisgICAgICAgICAqLworICAgICAgICBHZW5lcmFsUGF0aCBjcmVhdGVHZW5lcmFsUGF0aCgpIHsKKyAgICAgICAgICAgIEdlbmVyYWxQYXRoIHAgPSBuZXcgR2VuZXJhbFBhdGgoKTsKKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZVNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGludCB0eXBlID0gdHlwZXNbaV07CisgICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE86CisgICAgICAgICAgICAgICAgICAgICAgICBwLm1vdmVUbyhwb2ludHNbal0sIHBvaW50c1tqICsgMV0pOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19MSU5FVE86CisgICAgICAgICAgICAgICAgICAgICAgICBwLmxpbmVUbyhwb2ludHNbal0sIHBvaW50c1tqICsgMV0pOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19RVUFEVE86CisgICAgICAgICAgICAgICAgICAgICAgICBwLnF1YWRUbyhwb2ludHNbal0sIHBvaW50c1tqICsgMV0sIHBvaW50c1tqICsgMl0sIHBvaW50c1tqICsgM10pOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOgorICAgICAgICAgICAgICAgICAgICAgICAgcC5jdXJ2ZVRvKHBvaW50c1tqXSwgcG9pbnRzW2ogKyAxXSwgcG9pbnRzW2ogKyAyXSwgcG9pbnRzW2ogKyAzXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzW2ogKyA0XSwgcG9pbnRzW2ogKyA1XSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0NMT1NFOgorICAgICAgICAgICAgICAgICAgICAgICAgcC5jbG9zZVBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBqICs9IHBvaW50U2hpZnRbdHlwZV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQnVmZmVyQ2FwYWJpbGl0aWVzLmphdmEgYi9hd3QvamF2YS9hd3QvQnVmZmVyQ2FwYWJpbGl0aWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Q1ZmU3YgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9CdWZmZXJDYXBhYmlsaXRpZXMuamF2YQpAQCAtMCwwICsxLDE5NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCisvKioKKyAqIFRoZSBCdWZmZXJDYXBhYmlsaXRpZXMgY2xhc3MgcmVwcmVzZW50cyB0aGUgY2FwYWJpbGl0aWVzIGFuZCBvdGhlciBwcm9wZXJ0aWVzCisgKiBvZiB0aGUgaW1hZ2UgYnVmZmVycy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJDYXBhYmlsaXRpZXMgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIGZyb250IGJ1ZmZlciBjYXBhYmlsaXRpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbWFnZUNhcGFiaWxpdGllcyBmcm9udEJ1ZmZlckNhcGFiaWxpdGllczsKKworICAgIC8qKgorICAgICAqIFRoZSBiYWNrIGJ1ZmZlciBjYXBhYmlsaXRpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbWFnZUNhcGFiaWxpdGllcyBiYWNrQnVmZmVyQ2FwYWJpbGl0aWVzOworCisgICAgLyoqCisgICAgICogVGhlIGZsaXAgY29udGVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBGbGlwQ29udGVudHMgZmxpcENvbnRlbnRzOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEJ1ZmZlckNhcGFiaWxpdGllcyBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGZyb250QnVmZmVyQ2FwYWJpbGl0aWVzCisgICAgICogICAgICAgICAgICB0aGUgZnJvbnQgYnVmZmVyIGNhcGFiaWxpdGllcywgY2FuIG5vdCBiZSBudWxsLgorICAgICAqIEBwYXJhbSBiYWNrQnVmZmVyQ2FwYWJpbGl0aWVzCisgICAgICogICAgICAgICAgICB0aGUgdGhlIGJhY2sgYW5kIGludGVybWVkaWF0ZSBidWZmZXJzIGNhcGFiaWxpdGllcywgY2FuIG5vdCBiZQorICAgICAqICAgICAgICAgICAgbnVsbC4KKyAgICAgKiBAcGFyYW0gZmxpcENvbnRlbnRzCisgICAgICogICAgICAgICAgICB0aGUgYmFjayBidWZmZXIgY29udGVudHMgYWZ0ZXIgcGFnZSBmbGlwcGluZywgbnVsbCBpZiBwYWdlCisgICAgICogICAgICAgICAgICBmbGlwcGluZyBpcyBub3QgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyQ2FwYWJpbGl0aWVzKEltYWdlQ2FwYWJpbGl0aWVzIGZyb250QnVmZmVyQ2FwYWJpbGl0aWVzLAorICAgICAgICAgICAgSW1hZ2VDYXBhYmlsaXRpZXMgYmFja0J1ZmZlckNhcGFiaWxpdGllcywgRmxpcENvbnRlbnRzIGZsaXBDb250ZW50cykgeworICAgICAgICBpZiAoZnJvbnRCdWZmZXJDYXBhYmlsaXRpZXMgPT0gbnVsbCB8fCBiYWNrQnVmZmVyQ2FwYWJpbGl0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuZnJvbnRCdWZmZXJDYXBhYmlsaXRpZXMgPSBmcm9udEJ1ZmZlckNhcGFiaWxpdGllczsKKyAgICAgICAgdGhpcy5iYWNrQnVmZmVyQ2FwYWJpbGl0aWVzID0gYmFja0J1ZmZlckNhcGFiaWxpdGllczsKKyAgICAgICAgdGhpcy5mbGlwQ29udGVudHMgPSBmbGlwQ29udGVudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIEJ1ZmZlckNhcGFiaWxpdGllcyBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIEJ1ZmZlckNhcGFiaWxpdGllcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJDYXBhYmlsaXRpZXMoZnJvbnRCdWZmZXJDYXBhYmlsaXRpZXMsIGJhY2tCdWZmZXJDYXBhYmlsaXRpZXMsIGZsaXBDb250ZW50cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW1hZ2UgY2FwYWJpbGl0aWVzIG9mIHRoZSBmcm9udCBidWZmZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VDYXBhYmlsaXRpZXMgb2JqZWN0IHJlcHJlc2VudGVkIGNhcGFiaWxpdGllcyBvZiB0aGUKKyAgICAgKiAgICAgICAgIGZyb250IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VDYXBhYmlsaXRpZXMgZ2V0RnJvbnRCdWZmZXJDYXBhYmlsaXRpZXMoKSB7CisgICAgICAgIHJldHVybiBmcm9udEJ1ZmZlckNhcGFiaWxpdGllczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbWFnZSBjYXBhYmlsaXRpZXMgb2YgdGhlIGJhY2sgYnVmZmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEltYWdlQ2FwYWJpbGl0aWVzIG9iamVjdCByZXByZXNlbnRlZCBjYXBhYmlsaXRpZXMgb2YgdGhlIGJhY2sKKyAgICAgKiAgICAgICAgIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VDYXBhYmlsaXRpZXMgZ2V0QmFja0J1ZmZlckNhcGFiaWxpdGllcygpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tCdWZmZXJDYXBhYmlsaXRpZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmxpcCBjb250ZW50cyBvZiB0aGUgYmFjayBidWZmZXIgYWZ0ZXIgcGFnZS1mbGlwcGluZy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBGbGlwQ29udGVudHMgb2YgdGhlIGJhY2sgYnVmZmVyIGFmdGVyIHBhZ2UtZmxpcHBpbmcuCisgICAgICovCisgICAgcHVibGljIEZsaXBDb250ZW50cyBnZXRGbGlwQ29udGVudHMoKSB7CisgICAgICAgIHJldHVybiBmbGlwQ29udGVudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBidWZmZXIgc3RyYXRlZ3kgdXNlcyBwYWdlIGZsaXBwaW5nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGJ1ZmZlciBzdHJhdGVneSB1c2VzIHBhZ2UgZmxpcHBpbmcsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1BhZ2VGbGlwcGluZygpIHsKKyAgICAgICAgcmV0dXJuIGZsaXBDb250ZW50cyAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBwYWdlIGZsaXBwaW5nIGlzIG9ubHkgYXZhaWxhYmxlIGluIGZ1bGwtc2NyZWVuIG1vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBwYWdlIGZsaXBwaW5nIGlzIG9ubHkgYXZhaWxhYmxlIGluIGZ1bGwtc2NyZWVuIG1vZGUsCisgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGdWxsU2NyZWVuUmVxdWlyZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgcGFnZSBmbGlwcGluZyBjYW4gYmUgcGVyZm9ybWVkIHVzaW5nIG1vcmUgdGhhbiB0d28gYnVmZmVycy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHBhZ2UgZmxpcHBpbmcgY2FuIGJlIHBlcmZvcm1lZCB1c2luZyBtb3JlIHRoYW4gdHdvCisgICAgICogICAgICAgICBidWZmZXJzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNNdWx0aUJ1ZmZlckF2YWlsYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBGbGlwQ29udGVudHMgY2xhc3MgcmVwcmVzZW50cyBhIHNldCBvZiBwb3NzaWJsZSBiYWNrIGJ1ZmZlciBjb250ZW50cworICAgICAqIGFmdGVyIHBhZ2UtZmxpcHBpbmcuCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGbGlwQ29udGVudHMgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYmFjayBidWZmZXJlZCBjb250ZW50cyBhcmUgY2xlYXJlZCB3aXRoIHRoZSBiYWNrZ3JvdW5kIGNvbG9yCisgICAgICAgICAqIGFmdGVyIGZsaXBwaW5nLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbGlwQ29udGVudHMgQkFDS0dST1VORCA9IG5ldyBGbGlwQ29udGVudHMoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGJhY2sgYnVmZmVyZWQgY29udGVudHMgYXJlIGNvcGllZCB0byB0aGUgZnJvbnQgYnVmZmVyIGJlZm9yZQorICAgICAgICAgKiBmbGlwcGluZy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxpcENvbnRlbnRzIENPUElFRCA9IG5ldyBGbGlwQ29udGVudHMoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGJhY2sgYnVmZmVyIGNvbnRlbnRzIGFyZSB0aGUgcHJpb3IgY29udGVudHMgb2YgdGhlIGZyb250IGJ1ZmZlci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxpcENvbnRlbnRzIFBSSU9SID0gbmV3IEZsaXBDb250ZW50cygpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYmFjayBidWZmZXIgY29udGVudHMgYXJlIHVuZGVmaW5lZCBhZnRlciBmbGlwcGluZworICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbGlwQ29udGVudHMgVU5ERUZJTkVEID0gbmV3IEZsaXBDb250ZW50cygpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZmxpcCBjb250ZW50cy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgRmxpcENvbnRlbnRzKCkgeworCisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoZSBGbGlwQ29udGVudHMgb2JqZWN0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoZSBGbGlwQ29udGVudHMgb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIEZsaXBDb250ZW50cyBvYmplY3QuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQ29sb3IuamF2YSBiL2F3dC9qYXZhL2F3dC9Db2xvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzYzUzMmQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQ29sb3IuamF2YQpAQCAtMCwwICsxLDk5MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXJJbnQ7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQ29sb3IgY2xhc3MgZGVmaW5lcyBjb2xvcnMgaW4gdGhlIGRlZmF1bHQgc1JHQiBjb2xvciBzcGFjZSBvciBpbiB0aGUKKyAqIHNwZWNpZmllZCBDb2xvclNwYWNlLiBFdmVyeSBDb2xvciBjb250YWlucyBhbHBoYSB2YWx1ZS4gVGhlIGFscGhhIHZhbHVlCisgKiBkZWZpbmVzIHRoZSB0cmFuc3BhcmVuY3kgb2YgYSBjb2xvciBhbmQgY2FuIGJlIHJlcHJlc2VudGVkIGJ5IGEgZmxvYXQgdmFsdWUKKyAqIGluIHRoZSByYW5nZSAwLjAgLSAxLjAgb3IgMCAtIDI1NS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBDb2xvciBpbXBsZW1lbnRzIFBhaW50LCBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTE4NTI2ODE2ODgxMTYxMDc3TDsKKworICAgIC8qCisgICAgICogVGhlIHZhbHVlcyBvZiB0aGUgZm9sbG93aW5nIGNvbG9ycyBhcmUgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IKKyAgICAgKiB3aGljaCBjYW4gYmUgcmV2ZWFsZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBvciBzaW1pbGFyIGNvZGU6IENvbG9yIGMgPQorICAgICAqIENvbG9yLndoaXRlOyBTeXN0ZW0ub3V0LnByaW50bG4oYyk7CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3Igd2hpdGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciB3aGl0ZSA9IG5ldyBDb2xvcigyNTUsIDI1NSwgMjU1KTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciB3aGl0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIFdISVRFID0gd2hpdGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgbGlnaHQgZ3JheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIGxpZ2h0R3JheSA9IG5ldyBDb2xvcigxOTIsIDE5MiwgMTkyKTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBsaWdodCBncmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgTElHSFRfR1JBWSA9IGxpZ2h0R3JheTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBncmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgZ3JheSA9IG5ldyBDb2xvcigxMjgsIDEyOCwgMTI4KTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBncmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgR1JBWSA9IGdyYXk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgZGFyayBncmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgZGFya0dyYXkgPSBuZXcgQ29sb3IoNjQsIDY0LCA2NCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgZGFyayBncmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgREFSS19HUkFZID0gZGFya0dyYXk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgYmxhY2suCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBibGFjayA9IG5ldyBDb2xvcigwLCAwLCAwKTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBibGFjay4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIEJMQUNLID0gYmxhY2s7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgcmVkID0gbmV3IENvbG9yKDI1NSwgMCwgMCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgUkVEID0gcmVkOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIHBpbmsuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBwaW5rID0gbmV3IENvbG9yKDI1NSwgMTc1LCAxNzUpOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIHBpbmsuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBQSU5LID0gcGluazsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBvcmFuZ2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBvcmFuZ2UgPSBuZXcgQ29sb3IoMjU1LCAyMDAsIDApOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIG9yYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIE9SQU5HRSA9IG9yYW5nZTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciB5ZWxsb3cuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciB5ZWxsb3cgPSBuZXcgQ29sb3IoMjU1LCAyNTUsIDApOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIHllbGxvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIFlFTExPVyA9IHllbGxvdzsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBncmVlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIGdyZWVuID0gbmV3IENvbG9yKDAsIDI1NSwgMCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgZ3JlZW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBHUkVFTiA9IGdyZWVuOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIG1hZ2VudGEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBtYWdlbnRhID0gbmV3IENvbG9yKDI1NSwgMCwgMjU1KTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBtYWdlbnRhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgTUFHRU5UQSA9IG1hZ2VudGE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgY3lhbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yIGN5YW4gPSBuZXcgQ29sb3IoMCwgMjU1LCAyNTUpOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIGN5YW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBDWUFOID0gY3lhbjsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBibHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3IgYmx1ZSA9IG5ldyBDb2xvcigwLCAwLCAyNTUpOworCisgICAgLyoqCisgICAgICogVGhlIGNvbG9yIGJsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvciBCTFVFID0gYmx1ZTsKKworICAgIC8qKgorICAgICAqIGludGVnZXIgUkdCIHZhbHVlLgorICAgICAqLworICAgIGludCB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIEZsb2F0IHNSR0IgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdFtdIGZyZ2J2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbG9yIGluIGFuIGFyYml0cmFyeSBjb2xvciBzcGFjZSB3aXRoIDxjb2RlPmZsb2F0PC9jb2RlPiBjb21wb25lbnRzLiBJZgorICAgICAqIG51bGwsIG90aGVyIHZhbHVlIHNob3VsZCBiZSB1c2VkLgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgZnZhbHVlW107CisKKyAgICAvKioKKyAgICAgKiBGbG9hdCBhbHBoYSB2YWx1ZS4gSWYgZnJnYnZhbHVlIGlzIG51bGwsIHRoaXMgaXMgbm90IHZhbGlkIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBmYWxwaGE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IncyBjb2xvciBzcGFjZSBpZiBhcHBsaWNhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgQ29sb3JTcGFjZSBjczsKKworICAgIC8qCisgICAgICogVGhlIHZhbHVlIG9mIHRoZSBTQ0FMRV9GQUNUT1IgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3Igd2hpY2ggY2FuCisgICAgICogYmUgcmV2ZWFsZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlOiBDb2xvciBjID0gbmV3IENvbG9yKDEwMCwgMTAwLCAxMDApOworICAgICAqIENvbG9yIGJjID0gYy5icmlnaHRlcigpOyBTeXN0ZW0ub3V0LnByaW50bG4oIkJyaWdodGVyIGZhY3RvcjogIiArCisgICAgICogKChmbG9hdCljLmdldFJlZCgpKS8oKGZsb2F0KWJjLmdldFJlZCgpKSk7IENvbG9yIGRjID0gYy5kYXJrZXIoKTsKKyAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkRhcmtlciBmYWN0b3I6ICIgKworICAgICAqICgoZmxvYXQpZGMuZ2V0UmVkKCkpLygoZmxvYXQpYy5nZXRSZWQoKSkpOyBUaGUgcmVzdWx0IGlzIHRoZSBzYW1lIGZvcgorICAgICAqIGJyaWdodGVyIGFuZCBkYXJrZXIgbWV0aG9kcywgc28gd2UgbmVlZCBvbmx5IG9uZSBzY2FsZSBmYWN0b3IgZm9yIGJvdGguCisgICAgICovCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDQUxFX0ZBQ1RPUi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgU0NBTEVfRkFDVE9SID0gMC43OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1JTl9TQ0FMQUJMRS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOX1NDQUxBQkxFID0gMzsgLy8gc2hvdWxkIGluY3JlYXNlIHdoZW4KKworICAgIC8vIG11bHRpcGxpZWQgYnkgU0NBTEVfRkFDVE9SCisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBwYWludCBjb250ZXh0LgorICAgICAqLworICAgIHRyYW5zaWVudCBwcml2YXRlIFBhaW50Q29udGV4dCBjdXJyZW50UGFpbnRDb250ZXh0OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbG9yIGluIHRoZSBzcGVjaWZpZWQgQ29sb3JTcGFjZSwgdGhlIHNwZWNpZmllZCBjb2xvcgorICAgICAqIGNvbXBvbmVudHMgYW5kIHRoZSBzcGVjaWZpZWQgYWxwaGEuCisgICAgICogCisgICAgICogQHBhcmFtIGNzcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIENvbG9yU3BhY2UgdG8gYmUgdXNlZCB0byBkZWZpbmUgdGhlIGNvbXBvbmVudHMuCisgICAgICogQHBhcmFtIGNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnRzLgorICAgICAqIEBwYXJhbSBhbHBoYQorICAgICAqICAgICAgICAgICAgdGhlIGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvcihDb2xvclNwYWNlIGNzcGFjZSwgZmxvYXRbXSBjb21wb25lbnRzLCBmbG9hdCBhbHBoYSkgeworICAgICAgICBpbnQgbkNvbXBzID0gY3NwYWNlLmdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgZmxvYXQgY29tcDsKKyAgICAgICAgZnZhbHVlID0gbmV3IGZsb2F0W25Db21wc107CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQ29tcHM7IGkrKykgeworICAgICAgICAgICAgY29tcCA9IGNvbXBvbmVudHNbaV07CisgICAgICAgICAgICBpZiAoY29tcCA8IDAuMGYgfHwgY29tcCA+IDEuMGYpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTA3PUNvbG9yIHBhcmFtZXRlciBvdXRzaWRlIG9mIGV4cGVjdGVkIHJhbmdlOiBjb21wb25lbnQKKyAgICAgICAgICAgICAgICAvLyB7MH0uCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMDciLCBpKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZ2YWx1ZVtpXSA9IGNvbXBvbmVudHNbaV07CisgICAgICAgIH0KKworICAgICAgICBpZiAoYWxwaGEgPCAwLjBmIHx8IGFscGhhID4gMS4wZikgeworICAgICAgICAgICAgLy8gYXd0LjEwOD1BbHBoYSB2YWx1ZSBvdXRzaWRlIG9mIGV4cGVjdGVkIHJhbmdlLgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMDgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBmYWxwaGEgPSBhbHBoYTsKKworICAgICAgICBjcyA9IGNzcGFjZTsKKworICAgICAgICBmcmdidmFsdWUgPSBjcy50b1JHQihmdmFsdWUpOworCisgICAgICAgIHZhbHVlID0gKChpbnQpKGZyZ2J2YWx1ZVsyXSAqIDI1NSArIDAuNSkpIHwgKCgoaW50KShmcmdidmFsdWVbMV0gKiAyNTUgKyAwLjUpKSA8PCA4KQorICAgICAgICAgICAgICAgIHwgKCgoaW50KShmcmdidmFsdWVbMF0gKiAyNTUgKyAwLjUpKSA8PCAxNikgfCAoKChpbnQpKGZhbHBoYSAqIDI1NSArIDAuNSkpIDw8IDI0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgc1JHQiBjb2xvciB3aXRoIHRoZSBzcGVjaWZpZWQgY29tYmluZWQgUkdCQSB2YWx1ZQorICAgICAqIGNvbnNpc3Rpbmcgb2YgdGhlIGFscGhhIGNvbXBvbmVudCBpbiBiaXRzIDI0LTMxLCB0aGUgcmVkIGNvbXBvbmVudCBpbgorICAgICAqIGJpdHMgMTYtMjMsIHRoZSBncmVlbiBjb21wb25lbnQgaW4gYml0cyA4LTE1LCBhbmQgdGhlIGJsdWUgY29tcG9uZW50IGluCisgICAgICogYml0cyAwLTcuIElmIHRoZSBoYXNhbHBoYSBhcmd1bWVudCBpcyBmYWxzZSwgdGhlIGFscGhhIGhhcyBkZWZhdWx0IHZhbHVlCisgICAgICogLSAyNTUuCisgICAgICogCisgICAgICogQHBhcmFtIHJnYmEKKyAgICAgKiAgICAgICAgICAgIHRoZSBSR0JBIGNvbXBvbmVudHMuCisgICAgICogQHBhcmFtIGhhc0FscGhhCisgICAgICogICAgICAgICAgICB0aGUgYWxwaGEgcGFyYW1ldGVyIGlzIHRydWUgaWYgYWxwaGEgYml0cyBhcmUgdmFsaWQsIGZhbHNlCisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIENvbG9yKGludCByZ2JhLCBib29sZWFuIGhhc0FscGhhKSB7CisgICAgICAgIGlmICghaGFzQWxwaGEpIHsKKyAgICAgICAgICAgIHZhbHVlID0gcmdiYSB8IDB4RkYwMDAwMDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB2YWx1ZSA9IHJnYmE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgY29sb3Igd2l0aCB0aGUgc3BlY2lmaWVkIHJlZCwgZ3JlZW4sIGJsdWUgYW5kIGFscGhhCisgICAgICogY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHJlZCBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBncmVlbiBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBibHVlIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgdGhlIGFscGhhIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3IoaW50IHIsIGludCBnLCBpbnQgYiwgaW50IGEpIHsKKyAgICAgICAgaWYgKChyICYgMHhGRikgIT0gciB8fCAoZyAmIDB4RkYpICE9IGcgfHwgKGIgJiAweEZGKSAhPSBiIHx8IChhICYgMHhGRikgIT0gYSkgeworICAgICAgICAgICAgLy8gYXd0LjEwOT1Db2xvciBwYXJhbWV0ZXIgb3V0c2lkZSBvZiBleHBlY3RlZCByYW5nZS4KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTA5IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdmFsdWUgPSBiIHwgKGcgPDwgOCkgfCAociA8PCAxNikgfCAoYSA8PCAyNCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IG9wYXF1ZSBzUkdCIGNvbG9yIHdpdGggdGhlIHNwZWNpZmllZCByZWQsIGdyZWVuLCBhbmQKKyAgICAgKiBibHVlIHZhbHVlcy4gVGhlIEFscGhhIGNvbXBvbmVudCBpcyBzZXQgdG8gdGhlIGRlZmF1bHQgLSAxLjAuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWQgY29tcG9uZW50LgorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgZ3JlZW4gY29tcG9uZW50LgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYmx1ZSBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIENvbG9yKGludCByLCBpbnQgZywgaW50IGIpIHsKKyAgICAgICAgaWYgKChyICYgMHhGRikgIT0gciB8fCAoZyAmIDB4RkYpICE9IGcgfHwgKGIgJiAweEZGKSAhPSBiKSB7CisgICAgICAgICAgICAvLyBhd3QuMTA5PUNvbG9yIHBhcmFtZXRlciBvdXRzaWRlIG9mIGV4cGVjdGVkIHJhbmdlLgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMDkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICAvLyAweEZGIGZvciBhbHBoYSBjaGFubmVsCisgICAgICAgIHZhbHVlID0gYiB8IChnIDw8IDgpIHwgKHIgPDwgMTYpIHwgMHhGRjAwMDAwMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgc1JHQiBjb2xvciB3aXRoIHRoZSBzcGVjaWZpZWQgUkdCIHZhbHVlIGNvbnNpc3Rpbmcgb2YKKyAgICAgKiB0aGUgcmVkIGNvbXBvbmVudCBpbiBiaXRzIDE2LTIzLCB0aGUgZ3JlZW4gY29tcG9uZW50IGluIGJpdHMgOC0xNSwgYW5kCisgICAgICogdGhlIGJsdWUgY29tcG9uZW50IGluIGJpdHMgMC03LiBBbHBoYSBoYXMgZGVmYXVsdCB2YWx1ZSAtIDI1NS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmdiCisgICAgICogICAgICAgICAgICB0aGUgUkdCIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIENvbG9yKGludCByZ2IpIHsKKyAgICAgICAgdmFsdWUgPSByZ2IgfCAweEZGMDAwMDAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBjb2xvciB3aXRoIHRoZSBzcGVjaWZpZWQgcmVkLCBncmVlbiwgYmx1ZSBhbmQgYWxwaGEKKyAgICAgKiBjb21wb25lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgcmVkIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGdyZWVuIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJsdWUgY29tcG9uZW50LgorICAgICAqIEBwYXJhbSBhCisgICAgICogICAgICAgICAgICB0aGUgYWxwaGEgY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBDb2xvcihmbG9hdCByLCBmbG9hdCBnLCBmbG9hdCBiLCBmbG9hdCBhKSB7CisgICAgICAgIHRoaXMoKGludCkociAqIDI1NSArIDAuNSksIChpbnQpKGcgKiAyNTUgKyAwLjUpLCAoaW50KShiICogMjU1ICsgMC41KSwgKGludCkoYSAqIDI1NSArIDAuNSkpOworICAgICAgICBmYWxwaGEgPSBhOworICAgICAgICBmdmFsdWUgPSBuZXcgZmxvYXRbM107CisgICAgICAgIGZ2YWx1ZVswXSA9IHI7CisgICAgICAgIGZ2YWx1ZVsxXSA9IGc7CisgICAgICAgIGZ2YWx1ZVsyXSA9IGI7CisgICAgICAgIGZyZ2J2YWx1ZSA9IGZ2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgY29sb3Igd2l0aCB0aGUgc3BlY2lmaWVkIHJlZCwgZ3JlZW4sIGFuZCBibHVlCisgICAgICogY29tcG9uZW50cyBhbmQgZGVmYXVsdCBhbHBoYSB2YWx1ZSAtIDEuMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHJlZCBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBncmVlbiBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBibHVlIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3IoZmxvYXQgciwgZmxvYXQgZywgZmxvYXQgYikgeworICAgICAgICB0aGlzKHIsIGcsIGIsIDEuMGYpOworICAgIH0KKworICAgIHB1YmxpYyBQYWludENvbnRleHQgY3JlYXRlQ29udGV4dChDb2xvck1vZGVsIGNtLCBSZWN0YW5nbGUgciwgUmVjdGFuZ2xlMkQgcjJkLAorICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtLCBSZW5kZXJpbmdIaW50cyByaHMpIHsKKyAgICAgICAgaWYgKGN1cnJlbnRQYWludENvbnRleHQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRQYWludENvbnRleHQ7CisgICAgICAgIH0KKyAgICAgICAgY3VycmVudFBhaW50Q29udGV4dCA9IG5ldyBDb2xvci5Db2xvclBhaW50Q29udGV4dCh2YWx1ZSk7CisgICAgICAgIHJldHVybiBjdXJyZW50UGFpbnRDb250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIENvbG9yIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIENvbG9yIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgZm9ybWF0IG9mIHRoZSBzdHJpbmcgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3Igd2hpY2ggY2FuCisgICAgICAgICAqIGJlIHJldmVhbGVkIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZTogQ29sb3IgYyA9IG5ldyBDb2xvcigxLCAyLCAzKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGMpOworICAgICAgICAgKi8KKworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW3I9IiArIGdldFJlZCgpICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsZz0iICsgZ2V0R3JlZW4oKSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiLGI9IiArIGdldEJsdWUoKSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiXSI7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIE9iamVjdCB0byB0aGUgQ29sb3IuCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGlzIGEgQ29sb3Igd2hvc2UgdmFsdWUgaXMgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgIHRoaXMgQ29sb3IsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ29sb3IpIHsKKyAgICAgICAgICAgIHJldHVybiAoKENvbG9yKW9iaikudmFsdWUgPT0gdGhpcy52YWx1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGZsb2F0IGFycmF5IGNvbnRhaW5pbmcgdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzIG9mIHRoZQorICAgICAqIENvbG9yIGluIHRoZSBzcGVjaWZpZWQgQ29sb3JTcGFjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3JTcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBDb2xvclNwYWNlLgorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhpcyBmbG9hdAorICAgICAqICAgICAgICAgICAgYXJyYXkuIElmIG51bGwsIGEgZmxvYXQgYXJyYXkgd2lsbCBiZSBjcmVhdGVkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzIGluIGEgZmxvYXQgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0Q29tcG9uZW50cyhDb2xvclNwYWNlIGNvbG9yU3BhY2UsIGZsb2F0W10gY29tcG9uZW50cykgeworICAgICAgICBpbnQgbkNvbXBzID0gY29sb3JTcGFjZS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgZmxvYXRbbkNvbXBzICsgMV07CisgICAgICAgIH0KKworICAgICAgICBnZXRDb2xvckNvbXBvbmVudHMoY29sb3JTcGFjZSwgY29tcG9uZW50cyk7CisKKyAgICAgICAgaWYgKGZyZ2J2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzW25Db21wc10gPSBmYWxwaGE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb21wb25lbnRzW25Db21wc10gPSBnZXRBbHBoYSgpIC8gMjU1ZjsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBmbG9hdCBhcnJheSBjb250YWluaW5nIHRoZSBjb2xvciBjb21wb25lbnRzIG9mIHRoZSBDb2xvciBpbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgQ29sb3JTcGFjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3JTcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBDb2xvclNwYWNlLgorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhpcyBmbG9hdAorICAgICAqICAgICAgICAgICAgYXJyYXkuIElmIG51bGwsIGEgZmxvYXQgYXJyYXkgd2lsbCBiZSBjcmVhdGVkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbG9yIGNvbXBvbmVudHMgaW4gYSBmbG9hdCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRDb2xvckNvbXBvbmVudHMoQ29sb3JTcGFjZSBjb2xvclNwYWNlLCBmbG9hdFtdIGNvbXBvbmVudHMpIHsKKyAgICAgICAgZmxvYXRbXSBjaWVYWVpDb21wb25lbnRzID0gZ2V0Q29sb3JTcGFjZSgpLnRvQ0lFWFlaKGdldENvbG9yQ29tcG9uZW50cyhudWxsKSk7CisgICAgICAgIGZsb2F0W10gY3NDb21wb25lbnRzID0gY29sb3JTcGFjZS5mcm9tQ0lFWFlaKGNpZVhZWkNvbXBvbmVudHMpOworCisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjc0NvbXBvbmVudHM7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNzQ29tcG9uZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY29tcG9uZW50c1tpXSA9IGNzQ29tcG9uZW50c1tpXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbG9yU3BhY2Ugb2YgdGhpcyBDb2xvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBDb2xvclNwYWNlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3JTcGFjZSBnZXRDb2xvclNwYWNlKCkgeworICAgICAgICBpZiAoY3MgPT0gbnVsbCkgeworICAgICAgICAgICAgY3MgPSBDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBDb2xvciB3aGljaCBpcyBhIGRhcmtlciB0aGFuIHRoaXMgQ29sb3IgYWNjb3JkaW5nIHRvIGEKKyAgICAgKiBmaXhlZCBzY2FsZSBmYWN0b3IuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGFya2VyIENvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvciBkYXJrZXIoKSB7CisgICAgICAgIHJldHVybiBuZXcgQ29sb3IoKGludCkoZ2V0UmVkKCkgKiBTQ0FMRV9GQUNUT1IpLCAoaW50KShnZXRHcmVlbigpICogU0NBTEVfRkFDVE9SKSwKKyAgICAgICAgICAgICAgICAoaW50KShnZXRCbHVlKCkgKiBTQ0FMRV9GQUNUT1IpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IENvbG9yIHdoaWNoIGlzIGEgYnJpZ2h0ZXIgdGhhbiB0aGlzIENvbG9yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJyaWdodGVyIENvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvciBicmlnaHRlcigpIHsKKworICAgICAgICBpbnQgciA9IGdldFJlZCgpOworICAgICAgICBpbnQgYiA9IGdldEJsdWUoKTsKKyAgICAgICAgaW50IGcgPSBnZXRHcmVlbigpOworCisgICAgICAgIGlmIChyID09IDAgJiYgYiA9PSAwICYmIGcgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihNSU5fU0NBTEFCTEUsIE1JTl9TQ0FMQUJMRSwgTUlOX1NDQUxBQkxFKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyIDwgTUlOX1NDQUxBQkxFICYmIHIgIT0gMCkgeworICAgICAgICAgICAgciA9IE1JTl9TQ0FMQUJMRTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHIgPSAoaW50KShyIC8gU0NBTEVfRkFDVE9SKTsKKyAgICAgICAgICAgIHIgPSAociA+IDI1NSkgPyAyNTUgOiByOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGIgPCBNSU5fU0NBTEFCTEUgJiYgYiAhPSAwKSB7CisgICAgICAgICAgICBiID0gTUlOX1NDQUxBQkxFOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYiA9IChpbnQpKGIgLyBTQ0FMRV9GQUNUT1IpOworICAgICAgICAgICAgYiA9IChiID4gMjU1KSA/IDI1NSA6IGI7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZyA8IE1JTl9TQ0FMQUJMRSAmJiBnICE9IDApIHsKKyAgICAgICAgICAgIGcgPSBNSU5fU0NBTEFCTEU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnID0gKGludCkoZyAvIFNDQUxFX0ZBQ1RPUik7CisgICAgICAgICAgICBnID0gKGcgPiAyNTUpID8gMjU1IDogZzsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQ29sb3IociwgZywgYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGZsb2F0IGFycmF5IGNvbnRhaW5pbmcgdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzIG9mIHRoZQorICAgICAqIENvbG9yIGluIHRoZSBkZWZhdWx0IHNSR0IgY29sb3Igc3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRzIG9mIHRoaXMgbWV0aG9kIHdpbGwgYmUgd3JpdHRlbiB0byB0aGlzIGZsb2F0CisgICAgICogICAgICAgICAgICBhcnJheS4gQSBuZXcgZmxvYXQgYXJyYXkgd2lsbCBiZSBjcmVhdGVkIGlmIHRoaXMgYXJndW1lbnQgaXMKKyAgICAgKiAgICAgICAgICAgIG51bGwuCisgICAgICogQHJldHVybiB0aGUgUkdCIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzIGluIGEgZmxvYXQgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0UkdCQ29tcG9uZW50cyhmbG9hdFtdIGNvbXBvbmVudHMpIHsKKyAgICAgICAgaWYgKGNvbXBvbmVudHMgPT0gbnVsbCkgeworICAgICAgICAgICAgY29tcG9uZW50cyA9IG5ldyBmbG9hdFs0XTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmcmdidmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgY29tcG9uZW50c1szXSA9IGZhbHBoYTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHNbM10gPSBnZXRBbHBoYSgpIC8gMjU1ZjsKKyAgICAgICAgfQorCisgICAgICAgIGdldFJHQkNvbG9yQ29tcG9uZW50cyhjb21wb25lbnRzKTsKKworICAgICAgICByZXR1cm4gY29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZmxvYXQgYXJyYXkgY29udGFpbmluZyB0aGUgY29sb3IgY29tcG9uZW50cyBvZiB0aGUgQ29sb3IgaW4gdGhlCisgICAgICogZGVmYXVsdCBzUkdCIGNvbG9yIHNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhpcyBmbG9hdAorICAgICAqICAgICAgICAgICAgYXJyYXkuIEEgbmV3IGZsb2F0IGFycmF5IHdpbGwgYmUgY3JlYXRlZCBpZiB0aGlzIGFyZ3VtZW50IGlzCisgICAgICogICAgICAgICAgICBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIFJHQiBjb2xvciBjb21wb25lbnRzIGluIGEgZmxvYXQgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0UkdCQ29sb3JDb21wb25lbnRzKGZsb2F0W10gY29tcG9uZW50cykgeworICAgICAgICBpZiAoY29tcG9uZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzID0gbmV3IGZsb2F0WzNdOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZyZ2J2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzWzJdID0gZnJnYnZhbHVlWzJdOworICAgICAgICAgICAgY29tcG9uZW50c1sxXSA9IGZyZ2J2YWx1ZVsxXTsKKyAgICAgICAgICAgIGNvbXBvbmVudHNbMF0gPSBmcmdidmFsdWVbMF07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb21wb25lbnRzWzJdID0gZ2V0Qmx1ZSgpIC8gMjU1ZjsKKyAgICAgICAgICAgIGNvbXBvbmVudHNbMV0gPSBnZXRHcmVlbigpIC8gMjU1ZjsKKyAgICAgICAgICAgIGNvbXBvbmVudHNbMF0gPSBnZXRSZWQoKSAvIDI1NWY7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZmxvYXQgYXJyYXkgd2hpY2ggY29udGFpbnMgdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzIG9mCisgICAgICogdGhlIENvbG9yIGluIHRoZSBDb2xvclNwYWNlIG9mIHRoZSBDb2xvci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIHJlc3VsdHMgb2YgdGhpcyBtZXRob2Qgd2lsbCBiZSB3cml0dGVuIHRvIHRoaXMgZmxvYXQKKyAgICAgKiAgICAgICAgICAgIGFycmF5LiBBIG5ldyBmbG9hdCBhcnJheSB3aWxsIGJlIGNyZWF0ZWQgaWYgdGhpcyBhcmd1bWVudCBpcworICAgICAqICAgICAgICAgICAgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xvciBhbmQgYWxwaGEgY29tcG9uZW50cyBpbiBhIGZsb2F0IGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldENvbXBvbmVudHMoZmxvYXRbXSBjb21wb25lbnRzKSB7CisgICAgICAgIGlmIChmdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFJHQkNvbXBvbmVudHMoY29tcG9uZW50cyk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbkNvbG9yQ29tcHMgPSBmdmFsdWUubGVuZ3RoOworCisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgZmxvYXRbbkNvbG9yQ29tcHMgKyAxXTsKKyAgICAgICAgfQorCisgICAgICAgIGdldENvbG9yQ29tcG9uZW50cyhjb21wb25lbnRzKTsKKworICAgICAgICBjb21wb25lbnRzW25Db2xvckNvbXBzXSA9IGZhbHBoYTsKKworICAgICAgICByZXR1cm4gY29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZmxvYXQgYXJyYXkgd2hpY2ggY29udGFpbnMgdGhlIGNvbG9yIGNvbXBvbmVudHMgb2YgdGhlIENvbG9yIGluCisgICAgICogdGhlIENvbG9yU3BhY2Ugb2YgdGhlIENvbG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhpcyBmbG9hdAorICAgICAqICAgICAgICAgICAgYXJyYXkuIEEgbmV3IGZsb2F0IGFycmF5IHdpbGwgYmUgY3JlYXRlZCBpZiB0aGlzIGFyZ3VtZW50IGlzCisgICAgICogICAgICAgICAgICBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIGNvbG9yIGNvbXBvbmVudHMgaW4gYSBmbG9hdCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRDb2xvckNvbXBvbmVudHMoZmxvYXRbXSBjb21wb25lbnRzKSB7CisgICAgICAgIGlmIChmdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFJHQkNvbG9yQ29tcG9uZW50cyhjb21wb25lbnRzKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgZmxvYXRbZnZhbHVlLmxlbmd0aF07CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZ2YWx1ZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY29tcG9uZW50c1tpXSA9IGZ2YWx1ZVtpXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBoYXNoIGNvZGUgb2YgdGhpcyBDb2xvciBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiBhIGhhc2ggY29kZSBvZiB0aGlzIENvbG9yIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRUcmFuc3BhcmVuY3koKSB7CisgICAgICAgIHN3aXRjaCAoZ2V0QWxwaGEoKSkgeworICAgICAgICAgICAgY2FzZSAweGZmOgorICAgICAgICAgICAgICAgIHJldHVybiBUcmFuc3BhcmVuY3kuT1BBUVVFOworICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgIHJldHVybiBUcmFuc3BhcmVuY3kuQklUTUFTSzsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIFRyYW5zcGFyZW5jeS5UUkFOU0xVQ0VOVDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHJlZCBjb21wb25lbnQgb2YgdGhlIENvbG9yIGluIHRoZSByYW5nZSAwLTI1NS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSByZWQgY29tcG9uZW50IG9mIHRoZSBDb2xvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlZCgpIHsKKyAgICAgICAgcmV0dXJuICh2YWx1ZSA+PiAxNikgJiAweEZGOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFJHQiB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbG9yIGluIHRoZSBkZWZhdWx0IHNSR0IKKyAgICAgKiBDb2xvck1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFJHQiBjb2xvciB2YWx1ZSBpbiB0aGUgZGVmYXVsdCBzUkdCIENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSR0IoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBncmVlbiBjb21wb25lbnQgb2YgdGhlIENvbG9yIGluIHRoZSByYW5nZSAwLTI1NS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBncmVlbiBjb21wb25lbnQgb2YgdGhlIENvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0R3JlZW4oKSB7CisgICAgICAgIHJldHVybiAodmFsdWUgPj4gOCkgJiAweEZGOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBDb2xvciBpbiB0aGUgcmFuZ2UgMC0yNTUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmx1ZSBjb21wb25lbnQgb2YgdGhlIENvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Qmx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlICYgMHhGRjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhbHBoYSBjb21wb25lbnQgb2YgdGhlIENvbG9yIGluIHRoZSByYW5nZSAwLTI1NS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhbHBoYSBjb21wb25lbnQgb2YgdGhlIENvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QWxwaGEoKSB7CisgICAgICAgIHJldHVybiAodmFsdWUgPj4gMjQpICYgMHhGRjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBDb2xvciBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nLCBvciByZXR1cm5zIHRoZSBDb2xvciBzcGVjaWZpZWQKKyAgICAgKiBieSB0aGUgc2Vjb25kIHBhcmFtZXRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbm0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICAgICAqIEBwYXJhbSBkZWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IENvbG9yLgorICAgICAqIEByZXR1cm4gdGhlIGNvbG9yIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcsIG9yIHRoZSBDb2xvciBzcGVjaWZpZWQgYnkKKyAgICAgKiAgICAgICAgIHRoZSBzZWNvbmQgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3IgZ2V0Q29sb3IoU3RyaW5nIG5tLCBDb2xvciBkZWYpIHsKKyAgICAgICAgSW50ZWdlciBpbnRlZ2VyID0gSW50ZWdlci5nZXRJbnRlZ2VyKG5tKTsKKworICAgICAgICBpZiAoaW50ZWdlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihpbnRlZ2VyLmludFZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbG9yIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcsIG9yIHJldHVybnMgdGhlIENvbG9yIGNvbnZlcnRlZAorICAgICAqIGZyb20gdGhlIHNlY29uZCBwYXJhbWV0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG5tCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gZGVmCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCBDb2xvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xvciBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nLCBvciB0aGUgQ29sb3IgY29udmVydGVkIGZyb20KKyAgICAgKiAgICAgICAgIHRoZSBzZWNvbmQgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3IgZ2V0Q29sb3IoU3RyaW5nIG5tLCBpbnQgZGVmKSB7CisgICAgICAgIEludGVnZXIgaW50ZWdlciA9IEludGVnZXIuZ2V0SW50ZWdlcihubSk7CisKKyAgICAgICAgaWYgKGludGVnZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihkZWYpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihpbnRlZ2VyLmludFZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbG9yIGZyb20gdGhlIHNwZWNpZmllZCBTdHJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIG5tCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAcmV0dXJuIHRoZSBDb2xvciBvYmplY3QsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb2xvciBnZXRDb2xvcihTdHJpbmcgbm0pIHsKKyAgICAgICAgSW50ZWdlciBpbnRlZ2VyID0gSW50ZWdlci5nZXRJbnRlZ2VyKG5tKTsKKworICAgICAgICBpZiAoaW50ZWdlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQ29sb3IoaW50ZWdlci5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIGEgU3RyaW5nIHRvIGFuIGludGVnZXIgYW5kIHJldHVybnMgdGhlIHNwZWNpZmllZCBvcGFxdWUgQ29sb3IuCisgICAgICogCisgICAgICogQHBhcmFtIG5tCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHdoaWNoIHJlcHJlc2VudHMgYW4gb3BhcXVlIGNvbG9yIGFzIGEgMjQtYml0CisgICAgICogICAgICAgICAgICBpbnRlZ2VyLgorICAgICAqIEByZXR1cm4gdGhlIENvbG9yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBTdHJpbmcuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBjYW4gbm90IGJlIGNvbnZlcnRlZCB0byBhbiBpbnRlZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3IgZGVjb2RlKFN0cmluZyBubSkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIEludGVnZXIgaW50ZWdlciA9IEludGVnZXIuZGVjb2RlKG5tKTsKKyAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihpbnRlZ2VyLmludFZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBDb2xvciBvYmplY3QgdXNpbmcgdGhlIHNwZWNpZmllZCB2YWx1ZXMgb2YgdGhlIEhTQiBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGh1ZSBjb21wb25lbnQgb2YgdGhlIENvbG9yLgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2F0dXJhdGlvbiBvZiB0aGUgQ29sb3IuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBicmlnaHRuZXNzIG9mIHRoZSBDb2xvci4KKyAgICAgKiBAcmV0dXJuIGEgY29sb3Igb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBodWUsIHNhdHVyYXRpb24gYW5kIGJyaWdodG5lc3MKKyAgICAgKiAgICAgICAgIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENvbG9yIGdldEhTQkNvbG9yKGZsb2F0IGgsIGZsb2F0IHMsIGZsb2F0IGIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihIU0J0b1JHQihoLCBzLCBiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIENvbG9yIHNwZWNpZmllZCBieSB0aGUgUkdCIG1vZGVsIHRvIGFuIGVxdWl2YWxlbnQgY29sb3IgaW4KKyAgICAgKiB0aGUgSFNCIG1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgcmVkIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGdyZWVuIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJsdWUgY29tcG9uZW50LgorICAgICAqIEBwYXJhbSBoc2J2YWxzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgcmVzdWx0IGh1ZSwgc2F0dXJhdGlvbiwgYnJpZ2h0bmVzcyB2YWx1ZXMgb3IKKyAgICAgKiAgICAgICAgICAgIG51bGwuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgb2YgaHVlLCBzYXR1cmF0aW9uLCBicmlnaHRuZXNzIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0W10gUkdCdG9IU0IoaW50IHIsIGludCBnLCBpbnQgYiwgZmxvYXRbXSBoc2J2YWxzKSB7CisgICAgICAgIGlmIChoc2J2YWxzID09IG51bGwpIHsKKyAgICAgICAgICAgIGhzYnZhbHMgPSBuZXcgZmxvYXRbM107CisgICAgICAgIH0KKworICAgICAgICBpbnQgViA9IE1hdGgubWF4KGIsIE1hdGgubWF4KHIsIGcpKTsKKyAgICAgICAgaW50IHRlbXAgPSBNYXRoLm1pbihiLCBNYXRoLm1pbihyLCBnKSk7CisKKyAgICAgICAgZmxvYXQgSCwgUywgQjsKKworICAgICAgICBCID0gViAvIDI1NS5mOworCisgICAgICAgIGlmIChWID09IHRlbXApIHsKKyAgICAgICAgICAgIEggPSBTID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFMgPSAoViAtIHRlbXApIC8gKChmbG9hdClWKTsKKworICAgICAgICAgICAgZmxvYXQgQ3IgPSAoViAtIHIpIC8gKGZsb2F0KShWIC0gdGVtcCk7CisgICAgICAgICAgICBmbG9hdCBDZyA9IChWIC0gZykgLyAoZmxvYXQpKFYgLSB0ZW1wKTsKKyAgICAgICAgICAgIGZsb2F0IENiID0gKFYgLSBiKSAvIChmbG9hdCkoViAtIHRlbXApOworCisgICAgICAgICAgICBpZiAociA9PSBWKSB7CisgICAgICAgICAgICAgICAgSCA9IENiIC0gQ2c7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGcgPT0gVikgeworICAgICAgICAgICAgICAgIEggPSAyICsgQ3IgLSBDYjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgSCA9IDQgKyBDZyAtIENyOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBIIC89IDYuZjsKKyAgICAgICAgICAgIGlmIChIIDwgMCkgeworICAgICAgICAgICAgICAgIEgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGhzYnZhbHNbMF0gPSBIOworICAgICAgICBoc2J2YWxzWzFdID0gUzsKKyAgICAgICAgaHNidmFsc1syXSA9IEI7CisKKyAgICAgICAgcmV0dXJuIGhzYnZhbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIENvbG9yIHNwZWNpZmllZCBieSB0aGUgSFNCIG1vZGVsIHRvIGFuIGVxdWl2YWxlbnQgY29sb3IgaW4KKyAgICAgKiB0aGUgZGVmYXVsdCBSR0IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGh1ZQorICAgICAqICAgICAgICAgICAgdGhlIGh1ZSBjb21wb25lbnQgb2YgdGhlIENvbG9yLgorICAgICAqIEBwYXJhbSBzYXR1cmF0aW9uCisgICAgICogICAgICAgICAgICB0aGUgc2F0dXJhdGlvbiBvZiB0aGUgQ29sb3IuCisgICAgICogQHBhcmFtIGJyaWdodG5lc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBicmlnaHRuZXNzIG9mIHRoZSBDb2xvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBSR0IgdmFsdWUgb2YgdGhlIGNvbG9yIHdpdGggdGhlIHNwZWNpZmllZCBodWUsIHNhdHVyYXRpb24gYW5kCisgICAgICogICAgICAgICBicmlnaHRuZXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IEhTQnRvUkdCKGZsb2F0IGh1ZSwgZmxvYXQgc2F0dXJhdGlvbiwgZmxvYXQgYnJpZ2h0bmVzcykgeworICAgICAgICBmbG9hdCBmciwgZmcsIGZiOworCisgICAgICAgIGlmIChzYXR1cmF0aW9uID09IDApIHsKKyAgICAgICAgICAgIGZyID0gZmcgPSBmYiA9IGJyaWdodG5lc3M7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmbG9hdCBIID0gKGh1ZSAtIChmbG9hdClNYXRoLmZsb29yKGh1ZSkpICogNjsKKyAgICAgICAgICAgIGludCBJID0gKGludClNYXRoLmZsb29yKEgpOworICAgICAgICAgICAgZmxvYXQgRiA9IEggLSBJOworICAgICAgICAgICAgZmxvYXQgTSA9IGJyaWdodG5lc3MgKiAoMSAtIHNhdHVyYXRpb24pOworICAgICAgICAgICAgZmxvYXQgTiA9IGJyaWdodG5lc3MgKiAoMSAtIHNhdHVyYXRpb24gKiBGKTsKKyAgICAgICAgICAgIGZsb2F0IEsgPSBicmlnaHRuZXNzICogKDEgLSBzYXR1cmF0aW9uICogKDEgLSBGKSk7CisKKyAgICAgICAgICAgIHN3aXRjaCAoSSkgeworICAgICAgICAgICAgICAgIGNhc2UgMDoKKyAgICAgICAgICAgICAgICAgICAgZnIgPSBicmlnaHRuZXNzOworICAgICAgICAgICAgICAgICAgICBmZyA9IEs7CisgICAgICAgICAgICAgICAgICAgIGZiID0gTTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgICAgICAgICBmciA9IE47CisgICAgICAgICAgICAgICAgICAgIGZnID0gYnJpZ2h0bmVzczsKKyAgICAgICAgICAgICAgICAgICAgZmIgPSBNOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICAgICAgICAgIGZyID0gTTsKKyAgICAgICAgICAgICAgICAgICAgZmcgPSBicmlnaHRuZXNzOworICAgICAgICAgICAgICAgICAgICBmYiA9IEs7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICAgICAgZnIgPSBNOworICAgICAgICAgICAgICAgICAgICBmZyA9IE47CisgICAgICAgICAgICAgICAgICAgIGZiID0gYnJpZ2h0bmVzczsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgICAgICAgICBmciA9IEs7CisgICAgICAgICAgICAgICAgICAgIGZnID0gTTsKKyAgICAgICAgICAgICAgICAgICAgZmIgPSBicmlnaHRuZXNzOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDU6CisgICAgICAgICAgICAgICAgICAgIGZyID0gYnJpZ2h0bmVzczsKKyAgICAgICAgICAgICAgICAgICAgZmcgPSBNOworICAgICAgICAgICAgICAgICAgICBmYiA9IE47CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIGZyID0gZmIgPSBmZyA9IDA7IC8vIGltcG9zc2libGUsIHRvIHN1cHJlc3MgY29tcGlsZXIgZXJyb3IKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCByID0gKGludCkoZnIgKiAyNTUuICsgMC41KTsKKyAgICAgICAgaW50IGcgPSAoaW50KShmZyAqIDI1NS4gKyAwLjUpOworICAgICAgICBpbnQgYiA9IChpbnQpKGZiICogMjU1LiArIDAuNSk7CisKKyAgICAgICAgcmV0dXJuIChyIDw8IDE2KSB8IChnIDw8IDgpIHwgYiB8IDB4RkYwMDAwMDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIENvbG9yUGFpbnRDb250ZXh0LgorICAgICAqLworICAgIGNsYXNzIENvbG9yUGFpbnRDb250ZXh0IGltcGxlbWVudHMgUGFpbnRDb250ZXh0IHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIFJHQiB2YWx1ZS4KKyAgICAgICAgICovCisgICAgICAgIGludCByZ2JWYWx1ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHNhdmVkIHJhc3Rlci4KKyAgICAgICAgICovCisgICAgICAgIFdyaXRhYmxlUmFzdGVyIHNhdmVkUmFzdGVyID0gbnVsbDsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGNvbG9yIHBhaW50IGNvbnRleHQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gcmdiCisgICAgICAgICAqICAgICAgICAgICAgdGhlIFJHQiB2YWx1ZS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBDb2xvclBhaW50Q29udGV4dChpbnQgcmdiKSB7CisgICAgICAgICAgICByZ2JWYWx1ZSA9IHJnYjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CisgICAgICAgICAgICBzYXZlZFJhc3RlciA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICAgICAgcmV0dXJuIENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJhc3RlciBnZXRSYXN0ZXIoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpIHsKKyAgICAgICAgICAgIGlmIChzYXZlZFJhc3RlciA9PSBudWxsIHx8IHcgIT0gc2F2ZWRSYXN0ZXIuZ2V0V2lkdGgoKSB8fCBoICE9IHNhdmVkUmFzdGVyLmdldEhlaWdodCgpKSB7CisgICAgICAgICAgICAgICAgc2F2ZWRSYXN0ZXIgPSBnZXRDb2xvck1vZGVsKCkuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHcsIGgpOworCisgICAgICAgICAgICAgICAgLy8gU3VwcG9zZSB3ZSBoYXZlIGhlcmUgc2ltcGxlIElOVC9SR0IgY29sb3Ivc2FtcGxlIG1vZGVsCisgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlckludCBpbnRCdWZmZXIgPSAoRGF0YUJ1ZmZlckludClzYXZlZFJhc3Rlci5nZXREYXRhQnVmZmVyKCk7CisgICAgICAgICAgICAgICAgaW50IHJnYlZhbHVlc1tdID0gaW50QnVmZmVyLmdldERhdGEoKTsKKyAgICAgICAgICAgICAgICBpbnQgcmdiRmlsbFZhbHVlID0gcmdiVmFsdWU7CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwocmdiVmFsdWVzLCByZ2JGaWxsVmFsdWUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gc2F2ZWRSYXN0ZXI7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQ29tcG9uZW50LmphdmEgYi9hd3QvamF2YS9hd3QvQ29tcG9uZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUyYTlmNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9Db21wb25lbnQuamF2YQpAQCAtMCwwICsxLDYwMjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8vaW1wb3J0IGphdmEuYXd0LmRuZC5Ecm9wVGFyZ2V0OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkNvbXBvbmVudEV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkNvbXBvbmVudExpc3RlbmVyOworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkZvY3VzRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuRm9jdXNMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5IaWVyYXJjaHlCb3VuZHNMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5IaWVyYXJjaHlFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5IaWVyYXJjaHlMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5JbnB1dE1ldGhvZEV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LklucHV0TWV0aG9kTGlzdGVuZXI7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSW52b2NhdGlvbkV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUxpc3RlbmVyOworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lk1vdXNlRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuTW91c2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZU1vdGlvbkxpc3RlbmVyOworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lk1vdXNlV2hlZWxFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZVdoZWVsTGlzdGVuZXI7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuUGFpbnRFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5XaW5kb3dFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5pbS5JbnB1dENvbnRleHQ7CitpbXBvcnQgamF2YS5hd3QuaW0uSW5wdXRNZXRob2RSZXF1ZXN0czsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJTdHJhdGVneTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlZvbGF0aWxlSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuV3JpdGFibGVSYXN0ZXI7CitpbXBvcnQgamF2YS5hd3QucGVlci5Db21wb25lbnRQZWVyOworaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlU3VwcG9ydDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8vPz8/QVdUCisvL2ltcG9ydCBqYXZheC5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2libGU7CisvL2ltcG9ydCBqYXZheC5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2libGVDb21wb25lbnQ7CisvL2ltcG9ydCBqYXZheC5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2libGVDb250ZXh0OworLy9pbXBvcnQgamF2YXguYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlUm9sZTsKKy8vaW1wb3J0IGphdmF4LmFjY2Vzc2liaWxpdHkuQWNjZXNzaWJsZVN0YXRlOworLy9pbXBvcnQgamF2YXguYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlU3RhdGVTZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LkNsaXBSZWdpb247IC8vaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuRmllbGRzQWNjZXNzb3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Quc3RhdGUuU3RhdGU7IC8vaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QudGV4dC5UZXh0RmllbGRLaXQ7CisvL2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LnRleHQuVGV4dEtpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVXaW5kb3c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgYWJzdHJhY3QgQ29tcG9uZW50IGNsYXNzIHNwZWNpZmllcyBhbiBvYmplY3Qgd2l0aCBhIGdyYXBoaWNhbAorICogcmVwcmVzZW50YXRpb24gdGhhdCBjYW4gYmUgZGlzcGxheWVkIG9uIHRoZSBzY3JlZW4gYW5kIHRoYXQgY2FuIGludGVyYWN0IHdpdGgKKyAqIHRoZSB1c2VyIChmb3IgZXhhbXBsZTogc2Nyb2xsYmFycywgYnV0dG9ucywgY2hlY2tib3hlcykuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29tcG9uZW50IGltcGxlbWVudHMgSW1hZ2VPYnNlcnZlciwgTWVudUNvbnRhaW5lciwgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NjQ0MTE0NTEyNzE0NjE5NzUwTDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUT1BfQUxJR05NRU5UIGluZGljYXRlcyB0aGUgdG9wIGFsaWdubWVudCBvZiB0aGUgY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgVE9QX0FMSUdOTUVOVCA9IDAuMGY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0VOVEVSX0FMSUdOTUVOVCBpbmRpY2F0ZXMgdGhlIGNlbnRlciBhbGlnbm1lbnQgb2YgdGhlCisgICAgICogY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgQ0VOVEVSX0FMSUdOTUVOVCA9IDAuNWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQk9UVE9NX0FMSUdOTUVOVCBpbmRpY2F0ZXMgdGhlIGJvdHRvbSBhbGlnbm1lbnQgb2YgdGhlCisgICAgICogY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgQk9UVE9NX0FMSUdOTUVOVCA9IDEuMGY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTEVGVF9BTElHTk1FTlQgaW5kaWNhdGVzIHRoZSBsZWZ0IGFsaWdubWVudCBvZiB0aGUKKyAgICAgKiBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBMRUZUX0FMSUdOTUVOVCA9IDAuMGY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUklHSFRfQUxJR05NRU5UIGluZGljYXRlcyB0aGUgcmlnaHQgYWxpZ25tZW50IG9mIHRoZQorICAgICAqIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGZsb2F0IFJJR0hUX0FMSUdOTUVOVCA9IDEuMGY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgY2hpbGRDbGFzc2VzRmxhZ3MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaHRhYmxlPENsYXNzPD8+LCBCb29sZWFuPiBjaGlsZENsYXNzZXNGbGFncyA9IG5ldyBIYXNodGFibGU8Q2xhc3M8Pz4sIEJvb2xlYW4+KCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcGVlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb21wb25lbnRQZWVyIHBlZXIgPSBuZXcgQ29tcG9uZW50UGVlcigpIHsKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGluY3JlbWVudGFsSW1hZ2VVcGRhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBpbmNyZW1lbnRhbEltYWdlVXBkYXRlOworCisgICAgLyoqCisgICAgICogVGhlIHRvb2xraXQuCisgICAgICovCisgICAgZmluYWwgdHJhbnNpZW50IFRvb2xraXQgdG9vbGtpdCA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHJvdGVjdGVkIGFic3RyYWN0IGNsYXNzIEFjY2Vzc2libGVBV1RDb21wb25lbnQgZXh0ZW5kcyBBY2Nlc3NpYmxlQ29udGV4dAorICAgICAqIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBBY2Nlc3NpYmxlQ29tcG9uZW50IHsgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZworICAgICAqIHNlcmlhbFZlcnNpb25VSUQgPSA2NDIzMjE2NTU3NTc4MDAxOTFMOyBwcm90ZWN0ZWQgY2xhc3MKKyAgICAgKiBBY2Nlc3NpYmxlQVdUQ29tcG9uZW50SGFuZGxlciBpbXBsZW1lbnRzIENvbXBvbmVudExpc3RlbmVyIHsgcHJvdGVjdGVkCisgICAgICogQWNjZXNzaWJsZUFXVENvbXBvbmVudEhhbmRsZXIoKSB7IH0gcHVibGljIHZvaWQKKyAgICAgKiBjb21wb25lbnRIaWRkZW4oQ29tcG9uZW50RXZlbnQgZSkgeyBpZiAoYmVoYXZpb3VyLmlzTGlnaHR3ZWlnaHQoKSkgeworICAgICAqIHJldHVybjsgfSBmaXJlUHJvcGVydHlDaGFuZ2UoQWNjZXNzaWJsZUNvbnRleHQuQUNDRVNTSUJMRV9TVEFURV9QUk9QRVJUWSwKKyAgICAgKiBBY2Nlc3NpYmxlU3RhdGUuVklTSUJMRSwgbnVsbCk7IH0gcHVibGljIHZvaWQKKyAgICAgKiBjb21wb25lbnRNb3ZlZChDb21wb25lbnRFdmVudCBlKSB7IH0gcHVibGljIHZvaWQKKyAgICAgKiBjb21wb25lbnRSZXNpemVkKENvbXBvbmVudEV2ZW50IGUpIHsgfSBwdWJsaWMgdm9pZAorICAgICAqIGNvbXBvbmVudFNob3duKENvbXBvbmVudEV2ZW50IGUpIHsgaWYgKGJlaGF2aW91ci5pc0xpZ2h0d2VpZ2h0KCkpIHsKKyAgICAgKiByZXR1cm47IH0gZmlyZVByb3BlcnR5Q2hhbmdlKEFjY2Vzc2libGVDb250ZXh0LkFDQ0VTU0lCTEVfU1RBVEVfUFJPUEVSVFksCisgICAgICogbnVsbCwgQWNjZXNzaWJsZVN0YXRlLlZJU0lCTEUpOyB9IH0gcHJvdGVjdGVkIGNsYXNzCisgICAgICogQWNjZXNzaWJsZUFXVEZvY3VzSGFuZGxlciBpbXBsZW1lbnRzIEZvY3VzTGlzdGVuZXIgeyBwdWJsaWMgdm9pZAorICAgICAqIGZvY3VzR2FpbmVkKEZvY3VzRXZlbnQgZSkgeyBpZiAoYmVoYXZpb3VyLmlzTGlnaHR3ZWlnaHQoKSkgeyByZXR1cm47IH0KKyAgICAgKiBmaXJlUHJvcGVydHlDaGFuZ2UoQWNjZXNzaWJsZUNvbnRleHQuQUNDRVNTSUJMRV9TVEFURV9QUk9QRVJUWSwgbnVsbCwKKyAgICAgKiBBY2Nlc3NpYmxlU3RhdGUuRk9DVVNFRCk7IH0gcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgeyBpZgorICAgICAqIChiZWhhdmlvdXIuaXNMaWdodHdlaWdodCgpKSB7IHJldHVybjsgfQorICAgICAqIGZpcmVQcm9wZXJ0eUNoYW5nZShBY2Nlc3NpYmxlQ29udGV4dC5BQ0NFU1NJQkxFX1NUQVRFX1BST1BFUlRZLAorICAgICAqIEFjY2Vzc2libGVTdGF0ZS5GT0NVU0VELCBudWxsKTsgfSB9IHByb3RlY3RlZCBDb21wb25lbnRMaXN0ZW5lcgorICAgICAqIGFjY2Vzc2libGVBV1RDb21wb25lbnRIYW5kbGVyOyBwcm90ZWN0ZWQgRm9jdXNMaXN0ZW5lcgorICAgICAqIGFjY2Vzc2libGVBV1RGb2N1c0hhbmRsZXI7CisgICAgICovCisgICAgLyoKKyAgICAgKiBOdW1iZXIgb2YgcmVnaXN0ZXJlZCBwcm9wZXJ0eSBjaGFuZ2UgbGlzdGVuZXJzLgorICAgICAqLworICAgIC8qCisgICAgICogaW50IGxpc3RlbmVyc0NvdW50OyBwdWJsaWMgdm9pZCBhZGRGb2N1c0xpc3RlbmVyKEZvY3VzTGlzdGVuZXIgbCkgeworICAgICAqIENvbXBvbmVudC50aGlzLmFkZEZvY3VzTGlzdGVuZXIobCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIHZvaWQgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyCisgICAgICogbGlzdGVuZXIpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7CisgICAgICogc3VwZXIuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7IGxpc3RlbmVyc0NvdW50Kys7IGlmCisgICAgICogKGFjY2Vzc2libGVBV1RDb21wb25lbnRIYW5kbGVyID09IG51bGwpIHsgYWNjZXNzaWJsZUFXVENvbXBvbmVudEhhbmRsZXIgPQorICAgICAqIG5ldyBBY2Nlc3NpYmxlQVdUQ29tcG9uZW50SGFuZGxlcigpOworICAgICAqIENvbXBvbmVudC50aGlzLmFkZENvbXBvbmVudExpc3RlbmVyKGFjY2Vzc2libGVBV1RDb21wb25lbnRIYW5kbGVyKTsgfSBpZgorICAgICAqIChhY2Nlc3NpYmxlQVdURm9jdXNIYW5kbGVyID09IG51bGwpIHsgYWNjZXNzaWJsZUFXVEZvY3VzSGFuZGxlciA9IG5ldworICAgICAqIEFjY2Vzc2libGVBV1RGb2N1c0hhbmRsZXIoKTsKKyAgICAgKiBDb21wb25lbnQudGhpcy5hZGRGb2N1c0xpc3RlbmVyKGFjY2Vzc2libGVBV1RGb2N1c0hhbmRsZXIpOyB9IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFBvaW50IHApIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuIENvbXBvbmVudC50aGlzLmNvbnRhaW5zKHApOyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlQXQoUG9pbnQgYXJnMCkgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4gbnVsbDsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfQorICAgICAqIH0gcHVibGljIENvbG9yIGdldEJhY2tncm91bmQoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBDb21wb25lbnQudGhpcy5nZXRCYWNrZ3JvdW5kKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuCisgICAgICogQ29tcG9uZW50LnRoaXMuZ2V0Qm91bmRzKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiBDdXJzb3IgZ2V0Q3Vyc29yKCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuCisgICAgICogQ29tcG9uZW50LnRoaXMuZ2V0Q3Vyc29yKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiBGb250IGdldEZvbnQoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBDb21wb25lbnQudGhpcy5nZXRGb250KCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiBGb250TWV0cmljcyBnZXRGb250TWV0cmljcyhGb250IGYpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IHJldHVybgorICAgICAqIENvbXBvbmVudC50aGlzLmdldEZvbnRNZXRyaWNzKGYpOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBwdWJsaWMgQ29sb3IgZ2V0Rm9yZWdyb3VuZCgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IHJldHVybgorICAgICAqIENvbXBvbmVudC50aGlzLmdldEZvcmVncm91bmQoKTsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICogcHVibGljIFBvaW50IGdldExvY2F0aW9uKCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuCisgICAgICogQ29tcG9uZW50LnRoaXMuZ2V0TG9jYXRpb24oKTsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYworICAgICAqIFBvaW50IGdldExvY2F0aW9uT25TY3JlZW4oKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBDb21wb25lbnQudGhpcy5nZXRMb2NhdGlvbk9uU2NyZWVuKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0KKyAgICAgKiB9IHB1YmxpYyBEaW1lbnNpb24gZ2V0U2l6ZSgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IHJldHVybgorICAgICAqIENvbXBvbmVudC50aGlzLmdldFNpemUoKTsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYworICAgICAqIGJvb2xlYW4gaXNFbmFibGVkKCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuCisgICAgICogQ29tcG9uZW50LnRoaXMuaXNFbmFibGVkKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiBib29sZWFuIGlzRm9jdXNUcmF2ZXJzYWJsZSgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IHJldHVybgorICAgICAqIENvbXBvbmVudC50aGlzLmlzRm9jdXNUcmF2ZXJzYWJsZSgpOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBwdWJsaWMgYm9vbGVhbiBpc1Nob3dpbmcoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBDb21wb25lbnQudGhpcy5pc1Nob3dpbmcoKTsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYworICAgICAqIGJvb2xlYW4gaXNWaXNpYmxlKCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuCisgICAgICogQ29tcG9uZW50LnRoaXMuaXNWaXNpYmxlKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiB2b2lkIHJlbW92ZUZvY3VzTGlzdGVuZXIoRm9jdXNMaXN0ZW5lciBsKSB7CisgICAgICogQ29tcG9uZW50LnRoaXMucmVtb3ZlRm9jdXNMaXN0ZW5lcihsKTsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgdm9pZCByZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKKyAgICAgKiBsaXN0ZW5lcikgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsKKyAgICAgKiBzdXBlci5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGxpc3RlbmVyKTsgbGlzdGVuZXJzQ291bnQtLTsgaWYKKyAgICAgKiAobGlzdGVuZXJzQ291bnQgPiAwKSB7IHJldHVybjsgfSAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBsaXN0ZW5lcnMsCisgICAgICogcmVtb3ZlIGhhbmRsZXJzOgorICAgICAqIENvbXBvbmVudC50aGlzLnJlbW92ZUZvY3VzTGlzdGVuZXIoYWNjZXNzaWJsZUFXVEZvY3VzSGFuZGxlcik7CisgICAgICogQ29tcG9uZW50LnRoaXMucmVtb3ZlQ29tcG9uZW50TGlzdGVuZXIoYWNjZXNzaWJsZUFXVENvbXBvbmVudEhhbmRsZXIpOworICAgICAqIGFjY2Vzc2libGVBV1RDb21wb25lbnRIYW5kbGVyID0gbnVsbDsgYWNjZXNzaWJsZUFXVEZvY3VzSGFuZGxlciA9IG51bGw7IH0KKyAgICAgKiBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyB2b2lkIHJlcXVlc3RGb2N1cygpIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgQ29tcG9uZW50LnRoaXMucmVxdWVzdEZvY3VzKCk7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyB2b2lkIHNldEJhY2tncm91bmQoQ29sb3IgY29sb3IpIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgQ29tcG9uZW50LnRoaXMuc2V0QmFja2dyb3VuZChjb2xvcik7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyB2b2lkIHNldEJvdW5kcyhSZWN0YW5nbGUgcikgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBDb21wb25lbnQudGhpcy5zZXRCb3VuZHMocik7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyB2b2lkIHNldEN1cnNvcihDdXJzb3IgY3Vyc29yKSB7CisgICAgICogdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IENvbXBvbmVudC50aGlzLnNldEN1cnNvcihjdXJzb3IpOyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMgdm9pZCBzZXRFbmFibGVkKGJvb2xlYW4gZW5hYmxlZCkgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBDb21wb25lbnQudGhpcy5zZXRFbmFibGVkKGVuYWJsZWQpOyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMgdm9pZCBzZXRGb250KEZvbnQgZikgeyB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgKiB0cnkgeyBDb21wb25lbnQudGhpcy5zZXRGb250KGYpOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBwdWJsaWMgdm9pZCBzZXRGb3JlZ3JvdW5kKENvbG9yIGNvbG9yKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeworICAgICAqIENvbXBvbmVudC50aGlzLnNldEZvcmVncm91bmQoY29sb3IpOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihQb2ludCBwKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeworICAgICAqIENvbXBvbmVudC50aGlzLnNldExvY2F0aW9uKHApOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBwdWJsaWMgdm9pZCBzZXRTaXplKERpbWVuc2lvbiBzaXplKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeworICAgICAqIENvbXBvbmVudC50aGlzLnNldFNpemUoc2l6ZSk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfSBwdWJsaWMKKyAgICAgKiB2b2lkIHNldFZpc2libGUoYm9vbGVhbiB2aXNpYmxlKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeworICAgICAqIENvbXBvbmVudC50aGlzLnNldFZpc2libGUodmlzaWJsZSk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlUGFyZW50KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgKiB0cnkgeyBBY2Nlc3NpYmxlIGFQYXJlbnQgPSBzdXBlci5nZXRBY2Nlc3NpYmxlUGFyZW50KCk7IGlmIChhUGFyZW50ICE9CisgICAgICogbnVsbCkgeyByZXR1cm4gYVBhcmVudDsgfSBDb250YWluZXIgcGFyZW50ID0gZ2V0UGFyZW50KCk7IHJldHVybiAocGFyZW50CisgICAgICogaW5zdGFuY2VvZiBBY2Nlc3NpYmxlID8gKEFjY2Vzc2libGUpIHBhcmVudCA6IG51bGwpOyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlQ2hpbGQoaW50IGkpIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuIG51bGw7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0KKyAgICAgKiB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0QWNjZXNzaWJsZUNoaWxkcmVuQ291bnQoKSB7IHRvb2xraXQubG9ja0FXVCgpOworICAgICAqIHRyeSB7IHJldHVybiAwOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIEFjY2Vzc2libGVDb21wb25lbnQgZ2V0QWNjZXNzaWJsZUNvbXBvbmVudCgpIHsgcmV0dXJuCisgICAgICogdGhpczsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldEFjY2Vzc2libGVEZXNjcmlwdGlvbigpIHsgcmV0dXJuCisgICAgICogc3VwZXIuZ2V0QWNjZXNzaWJsZURlc2NyaXB0aW9uKCk7IC8vIHdoeSBvdmVycmlkZT8gfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgaW50IGdldEFjY2Vzc2libGVJbmRleEluUGFyZW50KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgKiB0cnkgeyBpZiAoZ2V0QWNjZXNzaWJsZVBhcmVudCgpID09IG51bGwpIHsgcmV0dXJuIC0xOyB9IGludCBjb3VudCA9IDA7CisgICAgICogQ29udGFpbmVyIHBhcmVudCA9IGdldFBhcmVudCgpOyBmb3IgKGludCBpID0gMDsgaSA8CisgICAgICogcGFyZW50LmdldENvbXBvbmVudENvdW50KCk7IGkrKykgeyBDb21wb25lbnQgYUNvbXAgPQorICAgICAqIHBhcmVudC5nZXRDb21wb25lbnQoaSk7IGlmIChhQ29tcCBpbnN0YW5jZW9mIEFjY2Vzc2libGUpIHsgaWYgKGFDb21wID09CisgICAgICogQ29tcG9uZW50LnRoaXMpIHsgcmV0dXJuIGNvdW50OyB9ICsrY291bnQ7IH0gfSByZXR1cm4gLTE7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBBY2Nlc3NpYmxlUm9sZSBnZXRBY2Nlc3NpYmxlUm9sZSgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICogdHJ5IHsgcmV0dXJuIEFjY2Vzc2libGVSb2xlLkFXVF9DT01QT05FTlQ7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBBY2Nlc3NpYmxlU3RhdGVTZXQgZ2V0QWNjZXNzaWJsZVN0YXRlU2V0KCkgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBBY2Nlc3NpYmxlU3RhdGVTZXQgc2V0ID0gbmV3CisgICAgICogQWNjZXNzaWJsZVN0YXRlU2V0KCk7IGlmIChpc0VuYWJsZWQoKSkgeworICAgICAqIHNldC5hZGQoQWNjZXNzaWJsZVN0YXRlLkVOQUJMRUQpOyB9IGlmIChpc0ZvY3VzYWJsZSgpKSB7CisgICAgICogc2V0LmFkZChBY2Nlc3NpYmxlU3RhdGUuRk9DVVNBQkxFKTsgfSBpZiAoaGFzRm9jdXMoKSkgeworICAgICAqIHNldC5hZGQoQWNjZXNzaWJsZVN0YXRlLkZPQ1VTRUQpOyB9IGlmIChpc09wYXF1ZSgpKSB7CisgICAgICogc2V0LmFkZChBY2Nlc3NpYmxlU3RhdGUuT1BBUVVFKTsgfSBpZiAoaXNTaG93aW5nKCkpIHsKKyAgICAgKiBzZXQuYWRkKEFjY2Vzc2libGVTdGF0ZS5TSE9XSU5HKTsgfSBpZiAoaXNWaXNpYmxlKCkpIHsKKyAgICAgKiBzZXQuYWRkKEFjY2Vzc2libGVTdGF0ZS5WSVNJQkxFKTsgfSByZXR1cm4gc2V0OyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHRocm93cyBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24KKyAgICAgKiB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4gQ29tcG9uZW50LnRoaXMuZ2V0TG9jYWxlKCk7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IH0KKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgQmx0QnVmZmVyU3RyYXRlZ3kgY2xhc3MgcHJvdmlkZXMgb3Bwb3J0dW5pdHkgb2YgYmxpdHRpbmcgb2Zmc2NyZWVuCisgICAgICogc3VyZmFjZXMgdG8gYSBjb21wb25lbnQuIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGJsaXR0aW5nLCBzZWUgPGEKKyAgICAgKiBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JpdF9ibGl0Ij5CaXQgYmxpdDwvYT4uCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHJvdGVjdGVkIGNsYXNzIEJsdEJ1ZmZlclN0cmF0ZWd5IGV4dGVuZHMgQnVmZmVyU3RyYXRlZ3kgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYmFjayBidWZmZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIFZvbGF0aWxlSW1hZ2VbXSBiYWNrQnVmZmVyczsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNhcHMuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgQnVmZmVyQ2FwYWJpbGl0aWVzIGNhcHM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aC4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBpbnQgd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBoZWlnaHQuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgaW50IGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHZhbGlkYXRlZCBjb250ZW50cy4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIHZhbGlkYXRlZENvbnRlbnRzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQmx0QnVmZmVyU3RyYXRlZ3kgYnVmZmVyIHN0cmF0ZWd5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIG51bUJ1ZmZlcnMKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ1ZmZlcnMuCisgICAgICAgICAqIEBwYXJhbSBjYXBzCisgICAgICAgICAqICAgICAgICAgICAgdGhlIEJ1ZmZlckNhcGFiaWxpdGllcy4KKyAgICAgICAgICogQHRocm93cyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICB0aGUgbm90IGltcGxlbWVudGVkIGV4Y2VwdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBCbHRCdWZmZXJTdHJhdGVneShpbnQgbnVtQnVmZmVycywgQnVmZmVyQ2FwYWJpbGl0aWVzIGNhcHMpCisgICAgICAgICAgICAgICAgdGhyb3dzIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBkcmF3aW5nIGJ1ZmZlciBoYXMgYmVlbiBsb3N0IHNpbmNlIHRoZSBsYXN0IGNhbGwKKyAgICAgICAgICogdG8gZ2V0RHJhd0dyYXBoaWNzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBkcmF3aW5nIGJ1ZmZlciBoYXMgYmVlbiBsb3N0IHNpbmNlIHRoZSBsYXN0IGNhbGwKKyAgICAgICAgICogICAgICAgICB0byBnZXREcmF3R3JhcGhpY3MsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgICAgICogQHNlZSBqYXZhLmF3dC5pbWFnZS5CdWZmZXJTdHJhdGVneSNjb250ZW50c0xvc3QoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRlbnRzTG9zdCgpIHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZHJhd2luZyBidWZmZXIgaGFzIGJlZW4gcmVzdG9yZWQgZnJvbSBhIGxvc3QKKyAgICAgICAgICogc3RhdGUgYW5kIHJlaW5pdGlhbGl6ZWQgdG8gdGhlIGRlZmF1bHQgYmFja2dyb3VuZCBjb2xvci4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZHJhd2luZyBidWZmZXIgaGFzIGJlZW4gcmVzdG9yZWQgZnJvbSBhIGxvc3QKKyAgICAgICAgICogICAgICAgICBzdGF0ZSBhbmQgcmVpbml0aWFsaXplZCB0byB0aGUgZGVmYXVsdCBiYWNrZ3JvdW5kIGNvbG9yLAorICAgICAgICAgKiAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgICAgICogQHNlZSBqYXZhLmF3dC5pbWFnZS5CdWZmZXJTdHJhdGVneSNjb250ZW50c1Jlc3RvcmVkKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250ZW50c1Jlc3RvcmVkKCkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyB0aGUgYmFjayBidWZmZXJzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIG51bUJ1ZmZlcnMKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ1ZmZlcnMuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVCYWNrQnVmZmVycyhpbnQgbnVtQnVmZmVycykgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgQnVmZmVyQ2FwYWJpbGl0aWVzIG9mIHRoZSBidWZmZXIgc3RyYXRlZ3kuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJDYXBhYmlsaXRpZXMuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjZ2V0Q2FwYWJpbGl0aWVzKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQnVmZmVyQ2FwYWJpbGl0aWVzIGdldENhcGFiaWxpdGllcygpIHsKKyAgICAgICAgICAgIHJldHVybiAoQnVmZmVyQ2FwYWJpbGl0aWVzKWNhcHMuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIEdyYXBoaWNzIG9mIGN1cnJlbnQgYnVmZmVyIHN0cmF0ZWd5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgR3JhcGhpY3Mgb2YgY3VycmVudCBidWZmZXIgc3RyYXRlZ3kuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjZ2V0RHJhd0dyYXBoaWNzKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgR3JhcGhpY3MgZ2V0RHJhd0dyYXBoaWNzKCkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXZhbGlkYXRlcyB0aGUgbG9zdCBkcmF3aW5nIGJ1ZmZlci4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHJldmFsaWRhdGUoKSB7CisgICAgICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNZXRob2QgaXMgbm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTaG93cyB0aGUgbmV4dCBhdmFpbGFibGUgYnVmZmVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHNlZSBqYXZhLmF3dC5pbWFnZS5CdWZmZXJTdHJhdGVneSNzaG93KCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzaG93KCkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgRmxpcEJ1ZmZlclN0cmF0ZWd5IGNsYXNzIGlzIGZvciBmbGlwcGluZyBidWZmZXJzIG9uIGEgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHByb3RlY3RlZCBjbGFzcyBGbGlwQnVmZmVyU3RyYXRlZ3kgZXh0ZW5kcyBCdWZmZXJTdHJhdGVneSB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBCdWZmZXIgQ2FwYWJpbGl0aWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIEJ1ZmZlckNhcGFiaWxpdGllcyBjYXBzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZHJhd2luZyBidWZmZXIuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgSW1hZ2UgZHJhd0J1ZmZlcjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGRyYXdpbmcgVm9sYXRpbGVJbWFnZSBidWZmZXIuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgVm9sYXRpbGVJbWFnZSBkcmF3VkJ1ZmZlcjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG51bWJlciBvZiBidWZmZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIGludCBudW1CdWZmZXJzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdmFsaWRhdGVkIGNvbnRlbnRzIGluZGljYXRlcyBpZiB0aGUgZHJhd2luZyBidWZmZXIgaXMgcmVzdG9yZWQKKyAgICAgICAgICogZnJvbSBsb3N0IHN0YXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gdmFsaWRhdGVkQ29udGVudHM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbGlwIGJ1ZmZlciBzdHJhdGVneS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBudW1CdWZmZXJzCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBidWZmZXJzLgorICAgICAgICAgKiBAcGFyYW0gY2FwcworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBCdWZmZXJDYXBhYmlsaXRpZXMuCisgICAgICAgICAqIEB0aHJvd3MgQVdURXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjYXBhYmlsaXRpZXMgc3VwcGxpZWQgY291bGQgbm90IGJlIHN1cHBvcnRlZCBvcgorICAgICAgICAgKiAgICAgICAgICAgICBtZXQuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgRmxpcEJ1ZmZlclN0cmF0ZWd5KGludCBudW1CdWZmZXJzLCBCdWZmZXJDYXBhYmlsaXRpZXMgY2FwcykgdGhyb3dzIEFXVEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBpZiAoIShDb21wb25lbnQudGhpcyBpbnN0YW5jZW9mIFdpbmRvdykgJiYgIShDb21wb25lbnQudGhpcworICAgICAgICAgICAgICogaW5zdGFuY2VvZiBDYW52YXMpKSB7IC8vIGF3dC4xNEI9T25seSBDYW52YXMgb3IgV2luZG93IGlzIGFsbG93ZWQKKyAgICAgICAgICAgICAqIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTRCIikpOworICAgICAgICAgICAgICogLy8kTk9OLU5MUy0xJCB9CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIC8vIFRPRE86IHRocm93IG5ldyBBV1RFeGNlcHRpb24oIkNhcGFiaWxpdGllcyBhcmUgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgdGhpcy5udW1CdWZmZXJzID0gbnVtQnVmZmVyczsKKyAgICAgICAgICAgIHRoaXMuY2FwcyA9IChCdWZmZXJDYXBhYmlsaXRpZXMpY2Fwcy5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZHJhd2luZyBidWZmZXIgaGFzIGJlZW4gbG9zdCBzaW5jZSB0aGUgbGFzdCBjYWxsCisgICAgICAgICAqIHRvIGdldERyYXdHcmFwaGljcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZHJhd2luZyBidWZmZXIgaGFzIGJlZW4gbG9zdCBzaW5jZSB0aGUgbGFzdCBjYWxsCisgICAgICAgICAqICAgICAgICAgdG8gZ2V0RHJhd0dyYXBoaWNzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjY29udGVudHNMb3N0KCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250ZW50c0xvc3QoKSB7CisgICAgICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNZXRob2QgaXMgbm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGRyYXdpbmcgYnVmZmVyIGhhcyBiZWVuIHJlc3RvcmVkIGZyb20gYSBsb3N0CisgICAgICAgICAqIHN0YXRlIGFuZCByZWluaXRpYWxpemVkIHRvIHRoZSBkZWZhdWx0IGJhY2tncm91bmQgY29sb3IuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGRyYXdpbmcgYnVmZmVyIGhhcyBiZWVuIHJlc3RvcmVkIGZyb20gYSBsb3N0CisgICAgICAgICAqICAgICAgICAgc3RhdGUgYW5kIHJlaW5pdGlhbGl6ZWQgdG8gdGhlIGRlZmF1bHQgYmFja2dyb3VuZCBjb2xvciwKKyAgICAgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjY29udGVudHNSZXN0b3JlZCgpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGVudHNSZXN0b3JlZCgpIHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgZmxpcHBpbmcgYnVmZmVycyB3aXRoIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGNhcGFiaWxpdGllcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBudW1CdWZmZXJzCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBidWZmZXJzLgorICAgICAgICAgKiBAcGFyYW0gY2FwcworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBCdWZmZXJDYXBhYmlsaXRpZXMuCisgICAgICAgICAqIEB0aHJvd3MgQVdURXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjYXBhYmlsaXRpZXMgY291bGQgbm90IGJlIHN1cHBvcnRlZCBvciBtZXQuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVCdWZmZXJzKGludCBudW1CdWZmZXJzLCBCdWZmZXJDYXBhYmlsaXRpZXMgY2FwcykgdGhyb3dzIEFXVEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAobnVtQnVmZmVycyA8IDIpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTRDPU51bWJlciBvZiBidWZmZXJzIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9uZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTRDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWNhcHMuaXNQYWdlRmxpcHBpbmcoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4xNEQ9QnVmZmVyIGNhcGFiaWxpdGllcyBzaG91bGQgc3VwcG9ydCBmbGlwcGluZworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTREIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIUNvbXBvbmVudC50aGlzLmJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTRFPUNvbXBvbmVudCBzaG91bGQgYmUgZGlzcGxheWFibGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE0RSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gVE9ETzogdGhyb3cgbmV3IEFXVEV4Y2VwdGlvbigiQ2FwYWJpbGl0aWVzIGFyZSBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNZXRob2QgaXMgbm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBEZXN0cm95IGJ1ZmZlcnMuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBkZXN0cm95QnVmZmVycygpIHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEZsaXBzIHRoZSBjb250ZW50cyBvZiB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250IGJ1ZmZlci4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBmbGlwQWN0aW9uCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGZsaXAgYWN0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZmxpcChCdWZmZXJDYXBhYmlsaXRpZXMuRmxpcENvbnRlbnRzIGZsaXBBY3Rpb24pIHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIGJhY2sgYnVmZmVyIGFzIEltYWdlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgYmFjayBidWZmZXIgYXMgSW1hZ2UuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgSW1hZ2UgZ2V0QmFja0J1ZmZlcigpIHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgQnVmZmVyQ2FwYWJpbGl0aWVzIG9mIHRoZSBidWZmZXIgc3RyYXRlZ3kuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJDYXBhYmlsaXRpZXMuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjZ2V0Q2FwYWJpbGl0aWVzKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQnVmZmVyQ2FwYWJpbGl0aWVzIGdldENhcGFiaWxpdGllcygpIHsKKyAgICAgICAgICAgIHJldHVybiAoQnVmZmVyQ2FwYWJpbGl0aWVzKWNhcHMuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIEdyYXBoaWNzIG9mIGN1cnJlbnQgYnVmZmVyIHN0cmF0ZWd5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgR3JhcGhpY3Mgb2YgY3VycmVudCBidWZmZXIgc3RyYXRlZ3kuCisgICAgICAgICAqIEBzZWUgamF2YS5hd3QuaW1hZ2UuQnVmZmVyU3RyYXRlZ3kjZ2V0RHJhd0dyYXBoaWNzKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgR3JhcGhpY3MgZ2V0RHJhd0dyYXBoaWNzKCkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXZhbGlkYXRlcyB0aGUgbG9zdCBkcmF3aW5nIGJ1ZmZlci4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHJldmFsaWRhdGUoKSB7CisgICAgICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNZXRob2QgaXMgbm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTaG93cyB0aGUgbmV4dCBhdmFpbGFibGUgYnVmZmVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHNlZSBqYXZhLmF3dC5pbWFnZS5CdWZmZXJTdHJhdGVneSNzaG93KCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzaG93KCkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZXJuYWwgY29tcG9uZW50J3Mgc3RhdGUgdXRpbGl6ZWQgYnkgdGhlIHZpc3VhbCB0aGVtZS4KKyAgICAgKi8KKyAgICBjbGFzcyBDb21wb25lbnRTdGF0ZSBpbXBsZW1lbnRzIFN0YXRlIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGRlZmF1bHQgbWluaW11bSBzaXplLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBEaW1lbnNpb24gZGVmYXVsdE1pbmltdW1TaXplID0gbmV3IERpbWVuc2lvbigpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGVja3MgaWYgdGhlIGNvbXBvbmVudCBpcyBlbmFibGVkLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgY29tcG9uZW50IGlzIGVuYWJsZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5hYmxlZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGVja3MgaWYgdGhlIGNvbXBvbmVudCBpcyB2aXNpYmxlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgY29tcG9uZW50IGlzIHZpc2libGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1Zpc2libGUoKSB7CisgICAgICAgICAgICByZXR1cm4gdmlzaWJsZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGVja3MgaWYgaXMgZm9jdXNlZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaXMgZm9jdXNlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRm9jdXNlZCgpIHsKKyAgICAgICAgICAgIC8vID8/P0FXVDogcmV0dXJuIGlzRm9jdXNPd25lcigpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIGZvbnQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBmb250LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZvbnQgZ2V0Rm9udCgpIHsKKyAgICAgICAgICAgIHJldHVybiBDb21wb25lbnQudGhpcy5nZXRGb250KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGlmIHRoZSBmb250IGhhcyBiZWVuIHNldC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGZvbnQgaGFzIGJlZW4gc2V0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNGb250U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZvbnQgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgYmFja2dyb3VuZCBjb2xvci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDb2xvciBnZXRCYWNrZ3JvdW5kKCkgeworICAgICAgICAgICAgQ29sb3IgYyA9IENvbXBvbmVudC50aGlzLmdldEJhY2tncm91bmQoKTsKKyAgICAgICAgICAgIHJldHVybiAoYyAhPSBudWxsKSA/IGMgOiBnZXREZWZhdWx0QmFja2dyb3VuZCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBpZiB0aGUgYmFja2dyb3VuZCBpcyBzZXQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBiYWNrZ3JvdW5kIGlzIHNldC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQmFja2dyb3VuZFNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBiYWNrQ29sb3IgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSB0ZXh0IGNvbG9yLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgdGV4dCBjb2xvci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDb2xvciBnZXRUZXh0Q29sb3IoKSB7CisgICAgICAgICAgICBDb2xvciBjID0gZ2V0Rm9yZWdyb3VuZCgpOworICAgICAgICAgICAgcmV0dXJuIChjICE9IG51bGwpID8gYyA6IGdldERlZmF1bHRGb3JlZ3JvdW5kKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGlmIHRoZSB0ZXh0IGNvbG9yIGlzIHNldC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHRleHQgY29sb3IgaXMgc2V0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUZXh0Q29sb3JTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gZm9yZUNvbG9yICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgZm9udCBtZXRyaWNzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgZm9udCBtZXRyaWNzLgorICAgICAgICAgKi8KKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICAgICAgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKCkgeworICAgICAgICAgICAgcmV0dXJuIHRvb2xraXQuZ2V0Rm9udE1ldHJpY3MoQ29tcG9uZW50LnRoaXMuZ2V0Rm9udCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcygpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlKHgsIHksIHcsIGgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHNpemUgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEaW1lbnNpb24gZ2V0U2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKHcsIGgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHdpbmRvdyBpZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdGhlIHdpbmRvdyBpZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBsb25nIGdldFdpbmRvd0lkKCkgeworICAgICAgICAgICAgTmF0aXZlV2luZG93IHdpbiA9IGdldE5hdGl2ZVdpbmRvdygpOworICAgICAgICAgICAgcmV0dXJuICh3aW4gIT0gbnVsbCkgPyB3aW4uZ2V0SWQoKSA6IDA7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCBtaW5pbXVtIHNpemUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IG1pbmltdW0gc2l6ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEaW1lbnNpb24gZ2V0RGVmYXVsdE1pbmltdW1TaXplKCkgeworICAgICAgICAgICAgaWYgKGRlZmF1bHRNaW5pbXVtU2l6ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2FsY3VsYXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdE1pbmltdW1TaXplOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIGRlZmF1bHQgbWluaW11bSBzaXplLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHNpemUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmV3IGRlZmF1bHQgbWluaW11bSBzaXplLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgc2V0RGVmYXVsdE1pbmltdW1TaXplKERpbWVuc2lvbiBzaXplKSB7CisgICAgICAgICAgICBkZWZhdWx0TWluaW11bVNpemUgPSBzaXplOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlc2V0IHRoZSBkZWZhdWx0IG1pbmltdW0gc2l6ZSB0byBudWxsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgICAgICBkZWZhdWx0TWluaW11bVNpemUgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGN1bGF0ZSB0aGUgZGVmYXVsdCBtaW5pbXVtIHNpemU6IHRvIGJlIG92ZXJyaWRkZW4uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBjYWxjdWxhdGUoKSB7CisgICAgICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyA/Pz9BV1Q6IHByaXZhdGUgdHJhbnNpZW50IEFjY2Vzc2libGVDb250ZXh0IGFjY2Vzc2libGVDb250ZXh0OworCisgICAgLyoqCisgICAgICogVGhlIGJlaGF2aW91ci4KKyAgICAgKi8KKyAgICBmaW5hbCB0cmFuc2llbnQgQ29tcG9uZW50QmVoYXZpb3IgYmVoYXZpb3VyOworCisgICAgLy8gPz8/QVdUOiBDb250YWluZXIgcGFyZW50OworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBhdXRvIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGF1dG9OYW1lID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb250LgorICAgICAqLworICAgIHByaXZhdGUgRm9udCBmb250OworCisgICAgLyoqCisgICAgICogVGhlIGJhY2sgY29sb3IuCisgICAgICovCisgICAgcHJpdmF0ZSBDb2xvciBiYWNrQ29sb3I7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZm9yZSBjb2xvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbG9yIGZvcmVDb2xvcjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZXByZWNhdGVkIGV2ZW50IGhhbmRsZXIuCisgICAgICovCisgICAgYm9vbGVhbiBkZXByZWNhdGVkRXZlbnRIYW5kbGVyID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmFibGVkIGV2ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgZW5hYmxlZEV2ZW50czsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmFibGVkIEFXVCBldmVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIGVuYWJsZWRBV1RFdmVudHM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcG9uZW50IGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFXVExpc3RlbmVyTGlzdDxDb21wb25lbnRMaXN0ZW5lcj4gY29tcG9uZW50TGlzdGVuZXJzID0gbmV3IEFXVExpc3RlbmVyTGlzdDxDb21wb25lbnRMaXN0ZW5lcj4oCisgICAgICAgICAgICB0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb2N1cyBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBBV1RMaXN0ZW5lckxpc3Q8Rm9jdXNMaXN0ZW5lcj4gZm9jdXNMaXN0ZW5lcnMgPSBuZXcgQVdUTGlzdGVuZXJMaXN0PEZvY3VzTGlzdGVuZXI+KAorICAgICAgICAgICAgdGhpcyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGllcmFyY2h5IGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFXVExpc3RlbmVyTGlzdDxIaWVyYXJjaHlMaXN0ZW5lcj4gaGllcmFyY2h5TGlzdGVuZXJzID0gbmV3IEFXVExpc3RlbmVyTGlzdDxIaWVyYXJjaHlMaXN0ZW5lcj4oCisgICAgICAgICAgICB0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBoaWVyYXJjaHkgYm91bmRzIGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFXVExpc3RlbmVyTGlzdDxIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lcj4gaGllcmFyY2h5Qm91bmRzTGlzdGVuZXJzID0gbmV3IEFXVExpc3RlbmVyTGlzdDxIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lcj4oCisgICAgICAgICAgICB0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBrZXkgbGlzdGVuZXJzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgQVdUTGlzdGVuZXJMaXN0PEtleUxpc3RlbmVyPiBrZXlMaXN0ZW5lcnMgPSBuZXcgQVdUTGlzdGVuZXJMaXN0PEtleUxpc3RlbmVyPih0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBtb3VzZSBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBBV1RMaXN0ZW5lckxpc3Q8TW91c2VMaXN0ZW5lcj4gbW91c2VMaXN0ZW5lcnMgPSBuZXcgQVdUTGlzdGVuZXJMaXN0PE1vdXNlTGlzdGVuZXI+KAorICAgICAgICAgICAgdGhpcyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbW91c2UgbW90aW9uIGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFXVExpc3RlbmVyTGlzdDxNb3VzZU1vdGlvbkxpc3RlbmVyPiBtb3VzZU1vdGlvbkxpc3RlbmVycyA9IG5ldyBBV1RMaXN0ZW5lckxpc3Q8TW91c2VNb3Rpb25MaXN0ZW5lcj4oCisgICAgICAgICAgICB0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBtb3VzZSB3aGVlbCBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBBV1RMaXN0ZW5lckxpc3Q8TW91c2VXaGVlbExpc3RlbmVyPiBtb3VzZVdoZWVsTGlzdGVuZXJzID0gbmV3IEFXVExpc3RlbmVyTGlzdDxNb3VzZVdoZWVsTGlzdGVuZXI+KAorICAgICAgICAgICAgdGhpcyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5wdXQgbWV0aG9kIGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFXVExpc3RlbmVyTGlzdDxJbnB1dE1ldGhvZExpc3RlbmVyPiBpbnB1dE1ldGhvZExpc3RlbmVycyA9IG5ldyBBV1RMaXN0ZW5lckxpc3Q8SW5wdXRNZXRob2RMaXN0ZW5lcj4oCisgICAgICAgICAgICB0aGlzKTsKKworICAgIC8qKgorICAgICAqIFRoZSB4LgorICAgICAqLworICAgIGludCB4OworCisgICAgLyoqCisgICAgICogVGhlIHkuCisgICAgICovCisgICAgaW50IHk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdy4KKyAgICAgKi8KKyAgICBpbnQgdzsKKworICAgIC8qKgorICAgICAqIFRoZSBoLgorICAgICAqLworICAgIGludCBoOworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIERpbWVuc2lvbiBtYXhpbXVtU2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIHNpemUuCisgICAgICovCisgICAgcHJpdmF0ZSBEaW1lbnNpb24gbWluaW11bVNpemU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJlZmVycmVkIHNpemUuCisgICAgICovCisgICAgcHJpdmF0ZSBEaW1lbnNpb24gcHJlZmVycmVkU2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBib3VuZHMgbWFzayBwYXJhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBib3VuZHNNYXNrUGFyYW07CisKKyAgICAvKioKKyAgICAgKiBUaGUgaWdub3JlIHJlcGFpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlnbm9yZVJlcGFpbnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5hYmxlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZW5hYmxlZCA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5wdXQgbWV0aG9kcyBlbmFibGVkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpbnB1dE1ldGhvZHNFbmFibGVkID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBkaXNwYXRjaCB0byBpbS4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgYm9vbGVhbiBkaXNwYXRjaFRvSU0gPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIGZvY3VzYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZm9jdXNhYmxlID0gdHJ1ZTsgLy8gQnkgZGVmYXVsdCwgYWxsIENvbXBvbmVudHMgcmV0dXJuCisKKyAgICAvLyB0cnVlIGZyb20gaXNGb2N1c2FibGUoKSBtZXRob2QKKyAgICAvKioKKyAgICAgKiBUaGUgdmlzaWJsZS4KKyAgICAgKi8KKyAgICBib29sZWFuIHZpc2libGUgPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIGNhbGxlZCBzZXQgZm9jdXNhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjYWxsZWRTZXRGb2N1c2FibGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3ZlcnJpZGRlbiBpcyBmb2N1c2FibGUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIG92ZXJyaWRlbklzRm9jdXNhYmxlID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb2N1cyB0cmF2ZXJzYWwga2V5cyBlbmFibGVkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmb2N1c1RyYXZlcnNhbEtleXNFbmFibGVkID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFBvc3NpYmxlIGtleXMgYXJlOiBGT1JXQVJEX1RSQVZFUlNBTF9LRVlTLCBCQUNLV0FSRF9UUkFWRVJTQUxfS0VZUywKKyAgICAgKiBVUF9DWUNMRV9UUkFWRVJTQUxfS0VZUy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBTZXQ8PyBleHRlbmRzIEFXVEtleVN0cm9rZT4+IHRyYXZlcnNhbEtleXMgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTZXQ8PyBleHRlbmRzIEFXVEtleVN0cm9rZT4+KCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHJhdmVyc2FsIGkgZHMuCisgICAgICovCisgICAgaW50W10gdHJhdmVyc2FsSURzOworCisgICAgLyoqCisgICAgICogVGhlIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIExvY2FsZSBsb2NhbGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3JpZW50YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBDb21wb25lbnRPcmllbnRhdGlvbiBvcmllbnRhdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBwcm9wZXJ0eSBjaGFuZ2Ugc3VwcG9ydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFByb3BlcnR5Q2hhbmdlU3VwcG9ydCBwcm9wZXJ0eUNoYW5nZVN1cHBvcnQ7CisKKyAgICAvLyA/Pz9BV1Q6IHByaXZhdGUgQXJyYXlMaXN0PFBvcHVwTWVudT4gcG9wdXBzOworCisgICAgLyoqCisgICAgICogVGhlIGNvYWxlc2Nlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY29hbGVzY2VyOworCisgICAgLyoqCisgICAgICogVGhlIGV2ZW50cyB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEhhc2h0YWJsZTxJbnRlZ2VyLCBMaW5rZWRMaXN0PEFXVEV2ZW50Pj4gZXZlbnRzVGFibGU7CisKKyAgICAvKioKKyAgICAgKiBDYXNoZWQgcmVmZXJlbmNlIHVzZWQgZHVyaW5nIEV2ZW50UXVldWUucG9zdEV2ZW50KCkKKyAgICAgKi8KKyAgICBwcml2YXRlIExpbmtlZExpc3Q8QVdURXZlbnQ+IGV2ZW50c0xpc3Q7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGllcmFyY2h5IGNoYW5naW5nIGNvdW50ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgaGllcmFyY2h5Q2hhbmdpbmdDb3VudGVyOworCisgICAgLyoqCisgICAgICogVGhlIHdhcyBzaG93aW5nLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiB3YXNTaG93aW5nOworCisgICAgLyoqCisgICAgICogVGhlIHdhcyBkaXNwbGF5YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gd2FzRGlzcGxheWFibGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3Vyc29yLgorICAgICAqLworICAgIEN1cnNvciBjdXJzb3I7CisKKyAgICAvLyA/Pz9BV1Q6IERyb3BUYXJnZXQgZHJvcFRhcmdldDsKKworICAgIC8qKgorICAgICAqIFRoZSBtb3VzZSBleGl0ZWQgZXhwZWN0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIG1vdXNlRXhpdGVkRXhwZWN0ZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVwYWludCByZWdpb24uCisgICAgICovCisgICAgdHJhbnNpZW50IE11bHRpUmVjdEFyZWEgcmVwYWludFJlZ2lvbjsKKworICAgIC8vID8/P0FXVDogdHJhbnNpZW50IFJlZHJhd01hbmFnZXIgcmVkcmF3TWFuYWdlcjsKKyAgICAvKioKKyAgICAgKiBUaGUgcmVkcmF3IG1hbmFnZXIuCisgICAgICovCisgICAgdHJhbnNpZW50IE9iamVjdCByZWRyYXdNYW5hZ2VyOworCisgICAgLyoqCisgICAgICogVGhlIHZhbGlkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiB2YWxpZDsKKworICAgIC8qKgorICAgICAqIFRoZSB1cGRhdGVkIGltYWdlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEhhc2hNYXA8SW1hZ2UsIEltYWdlUGFyYW1ldGVycz4gdXBkYXRlZEltYWdlczsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2NrIG9iamVjdCBmb3IgcHJpdmF0ZSBjb21wb25lbnQncyBkYXRhIHdoaWNoIGRvbid0IGFmZmVjdCB0aGUKKyAgICAgKiBjb21wb25lbnQgaGllcmFyY2h5LgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQ29tcG9uZW50TG9jayB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNvbXBvbmVudCBsb2NrLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgdHJhbnNpZW50IE9iamVjdCBjb21wb25lbnRMb2NrID0gbmV3IENvbXBvbmVudExvY2soKTsKKyAgICBzdGF0aWMgeworICAgICAgICBQcml2aWxlZ2VkQWN0aW9uPFN0cmluZ1tdPiBhY3Rpb24gPSBuZXcgUHJpdmlsZWdlZEFjdGlvbjxTdHJpbmdbXT4oKSB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nW10gcnVuKCkgeworICAgICAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0aWVzW10gPSBuZXcgU3RyaW5nWzJdOworICAgICAgICAgICAgICAgIHByb3BlcnRpZXNbMF0gPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImF3dC5pbWFnZS5yZWRyYXdyYXRlIiwgIjEwMCIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzWzFdID0gU3lzdGVtLmdldFByb3BlcnR5KCJhd3QuaW1hZ2UuaW5jcmVtZW50YWxkcmF3IiwgInRydWUiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIFN0cmluZyBwcm9wZXJ0aWVzW10gPSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChhY3Rpb24pOworICAgICAgICAvLyBGSVhNRTogcmF0ZSBpcyBuZXZlciB1c2VkLCBjYW4gdGhpcyBjb2RlIGFuZCB0aGUgZ2V0IHByb3BlcnR5IGFib3ZlCisgICAgICAgIC8vIGJlIHJlbW92ZWQ/CisgICAgICAgIC8vIGludCByYXRlOworICAgICAgICAvLworICAgICAgICAvLyB0cnkgeworICAgICAgICAvLyByYXRlID0gSW50ZWdlci5kZWNvZGUocHJvcGVydGllc1swXSkuaW50VmFsdWUoKTsKKyAgICAgICAgLy8gfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gcmF0ZSA9IDEwMDsKKyAgICAgICAgLy8gfQorICAgICAgICBpbmNyZW1lbnRhbEltYWdlVXBkYXRlID0gcHJvcGVydGllc1sxXS5lcXVhbHMoInRydWUiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBjb21wb25lbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbXBvbmVudCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcmllbnRhdGlvbiA9IENvbXBvbmVudE9yaWVudGF0aW9uLlVOS05PV047CisgICAgICAgICAgICByZWRyYXdNYW5hZ2VyID0gbnVsbDsKKyAgICAgICAgICAgIC8vID8/P0FXVAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIHRyYXZlcnNhbElEcyA9IHRoaXMgaW5zdGFuY2VvZiBDb250YWluZXIgPworICAgICAgICAgICAgICogS2V5Ym9hcmRGb2N1c01hbmFnZXIuY29udFRyYXZlcnNhbElEcyA6CisgICAgICAgICAgICAgKiBLZXlib2FyZEZvY3VzTWFuYWdlci5jb21wVHJhdmVyc2FsSURzOyBmb3IgKGludCBlbGVtZW50IDoKKyAgICAgICAgICAgICAqIHRyYXZlcnNhbElEcykgeyB0cmF2ZXJzYWxLZXlzLnB1dChuZXcgSW50ZWdlcihlbGVtZW50KSwgbnVsbCk7IH0KKyAgICAgICAgICAgICAqIGJlaGF2aW91ciA9IGNyZWF0ZUJlaGF2aW9yKCk7CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGJlaGF2aW91ciA9IG51bGw7CisKKyAgICAgICAgICAgIGRlcml2ZUNvYWxlc2NlckZsYWcoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgdGhhdCB0aGUgY2xhc3MgaW5oZXJpdGVkIGZyb20gQ29tcG9uZW50IGRlY2xhcmVzIHRoZSBtZXRob2QKKyAgICAgKiBjb2FsZXNjZUV2ZW50cygpLCBhbmQgcHV0IHRoZSByZXN1bHRzIHRvIHRoZSBjaGlsZENsYXNzZXNGbGFncyBtYXAuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRlcml2ZUNvYWxlc2NlckZsYWcoKSB7CisgICAgICAgIENsYXNzPD8+IHRoaXNDbGFzcyA9IGdldENsYXNzKCk7CisgICAgICAgIGJvb2xlYW4gZmxhZyA9IHRydWU7CisgICAgICAgIHN5bmNocm9uaXplZCAoY2hpbGRDbGFzc2VzRmxhZ3MpIHsKKyAgICAgICAgICAgIEJvb2xlYW4gZmxhZ1dyYXBwZXIgPSBjaGlsZENsYXNzZXNGbGFncy5nZXQodGhpc0NsYXNzKTsKKyAgICAgICAgICAgIGlmIChmbGFnV3JhcHBlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgTWV0aG9kIGNvYWxlc2NlTWV0aG9kID0gbnVsbDsKKyAgICAgICAgICAgICAgICBmb3IgKENsYXNzPD8+IGMgPSB0aGlzQ2xhc3M7IGMgIT0gQ29tcG9uZW50LmNsYXNzOyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvYWxlc2NlTWV0aG9kID0gYy5nZXREZWNsYXJlZE1ldGhvZCgiY29hbGVzY2VFdmVudHMiLCBuZXcgQ2xhc3NbXSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJqYXZhLmF3dC5BV1RFdmVudCIpLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiamF2YS5hd3QuQVdURXZlbnQiKX0pOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvYWxlc2NlTWV0aG9kICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZsYWcgPSAoY29hbGVzY2VNZXRob2QgIT0gbnVsbCk7CisgICAgICAgICAgICAgICAgY2hpbGRDbGFzc2VzRmxhZ3MucHV0KHRoaXNDbGFzcywgQm9vbGVhbi52YWx1ZU9mKGZsYWcpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmxhZyA9IGZsYWdXcmFwcGVyLmJvb2xlYW5WYWx1ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNvYWxlc2NlciA9IGZsYWc7CisgICAgICAgIGlmIChmbGFnKSB7CisgICAgICAgICAgICBldmVudHNUYWJsZSA9IG5ldyBIYXNodGFibGU8SW50ZWdlciwgTGlua2VkTGlzdDxBV1RFdmVudD4+KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBldmVudHNUYWJsZSA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbmFtZSBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgU3RyaW5nIG9sZE5hbWU7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXV0b05hbWUgPSBmYWxzZTsKKyAgICAgICAgICAgIG9sZE5hbWUgPSB0aGlzLm5hbWU7CisgICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2UoIm5hbWUiLCBvbGROYW1lLCBuYW1lKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhpcyBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKChuYW1lID09IG51bGwpICYmIGF1dG9OYW1lKSB7CisgICAgICAgICAgICAgICAgbmFtZSA9IGF1dG9OYW1lKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdXRvIG5hbWUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nLgorICAgICAqLworICAgIFN0cmluZyBhdXRvTmFtZSgpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBnZXRDbGFzcygpLmdldE5hbWUoKTsKKyAgICAgICAgaWYgKG5hbWUuaW5kZXhPZigiJCIpICE9IC0xKSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvLyBpbnQgbnVtYmVyID0gdG9vbGtpdC5hdXRvTnVtYmVyLm5leHRDb21wb25lbnQrKzsKKyAgICAgICAgaW50IG51bWJlciA9IDA7CisgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZyhuYW1lLmxhc3RJbmRleE9mKCIuIikgKyAxKSArIEludGVnZXIudG9TdHJpbmcobnVtYmVyKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgZm9ybWF0IGlzIGJhc2VkIG9uIDEuNSByZWxlYXNlIGJlaGF2aW9yIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieQorICAgICAgICAgKiB0aGUgZm9sbG93aW5nIGNvZGU6IENvbXBvbmVudCBjID0gbmV3IENvbXBvbmVudCgpe307CisgICAgICAgICAqIGMuc2V0VmlzaWJsZShmYWxzZSk7IFN5c3RlbS5vdXQucHJpbnRsbihjKTsKKyAgICAgICAgICovCisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlsiICsgcGFyYW1TdHJpbmcoKSArICJdIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwdWJsaWMgdm9pZCBhZGQoUG9wdXBNZW51IHBvcHVwKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBpZgorICAgICAqIChwb3B1cC5nZXRQYXJlbnQoKSA9PSB0aGlzKSB7IHJldHVybjsgfSBpZiAocG9wdXBzID09IG51bGwpIHsgcG9wdXBzID0KKyAgICAgKiBuZXcgQXJyYXlMaXN0PFBvcHVwTWVudT4oKTsgfSBwb3B1cC5zZXRQYXJlbnQodGhpcyk7IHBvcHVwcy5hZGQocG9wdXApOyB9CisgICAgICogZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlLCBpZiB0aGUgY29tcG9uZW50IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgUG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBjb21wb25lbnQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBQb2ludCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludCBwKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHAueCwgcC55KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUsIGlmIHRoZSBjb21wb25lbnQgY29udGFpbnMgdGhlIHBvaW50IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGNvbXBvbmVudCBjb250YWlucyB0aGUgcG9pbnQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBjb29yZGluYXRlcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCB4LCBpbnQgeSkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBpbnNpZGUoeCwgeSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVwcmVjYXRlZDogcmVwbGFjZWQgYnkgcmVwbGFjZWQgYnkgZ2V0U2l6ZSgpIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkaW1lbnNpb24uCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgZ2V0U2l6ZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEaW1lbnNpb24gc2l6ZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbih3LCBoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHB1YmxpYyBDb250YWluZXIgZ2V0UGFyZW50KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuIHBhcmVudDsgfQorICAgICAqIGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIExpc3QuCisgICAgICogCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIG91dC4KKyAgICAgKiBAcGFyYW0gaW5kZW50CisgICAgICogICAgICAgICAgICB0aGUgaW5kZW50CisgICAgICogQHJldHVybiB0aGUgbmVhcmVzdCBoZWF2eXdlaWdodCBhbmNlc3RvciBpbiBoaWVyYXJjaHkgb3IKKyAgICAgKiAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIENvbXBvbmVudCBnZXRIV0FuY2VzdG9yKCkgeyByZXR1cm4gKHBhcmVudCAhPSBudWxsID8KKyAgICAgKiBwYXJlbnQuZ2V0SFdTdXJmYWNlKCkgOiBudWxsKTsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogQHJldHVybiBoZWF2eXdlaWdodCBjb21wb25lbnQgdGhhdCBpcyBlcXVhbCB0byBvciBpcyBhIG5lYXJlc3QKKyAgICAgKiAgICAgICAgIGhlYXZ5d2VpZ2h0IGNvbnRhaW5lciBvZiB0aGUgY3VycmVudCBjb21wb25lbnQsIG9yCisgICAgICogICAgICAgICA8Y29kZT5udWxsPC9jb2RlPiBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBDb21wb25lbnQgZ2V0SFdTdXJmYWNlKCkgeyBDb21wb25lbnQgcGFyZW50OyBmb3IgKHBhcmVudCA9IHRoaXM7IChwYXJlbnQKKyAgICAgKiAhPSBudWxsKSAmJiAocGFyZW50LmlzTGlnaHR3ZWlnaHQoKSk7IHBhcmVudCA9IHBhcmVudCAuZ2V0UGFyZW50KCkpIHsgOyB9CisgICAgICogcmV0dXJuIHBhcmVudDsgfSBXaW5kb3cgZ2V0V2luZG93QW5jZXN0b3IoKSB7IENvbXBvbmVudCBwYXI7IGZvciAocGFyID0KKyAgICAgKiB0aGlzOyBwYXIgIT0gbnVsbCAmJiAhKHBhciBpbnN0YW5jZW9mIFdpbmRvdyk7IHBhciA9IHBhci5nZXRQYXJlbnQoKSkgeyA7CisgICAgICogfSByZXR1cm4gKFdpbmRvdykgcGFyOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBUbyBiZSBjYWxsZWQgYnkgY29udGFpbmVyCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiB2b2lkIHNldFBhcmVudChDb250YWluZXIgcGFyZW50KSB7IHRoaXMucGFyZW50ID0gcGFyZW50OworICAgICAqIHNldFJlZHJhd01hbmFnZXIoKTsgfSB2b2lkIHNldFJlZHJhd01hbmFnZXIoKSB7IHJlZHJhd01hbmFnZXIgPQorICAgICAqIGdldFJlZHJhd01hbmFnZXIoKTsgfSBwdWJsaWMgdm9pZCByZW1vdmUoTWVudUNvbXBvbmVudCBtZW51KSB7CisgICAgICogdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IGlmIChtZW51LmdldFBhcmVudCgpID09IHRoaXMpIHsKKyAgICAgKiBtZW51LnNldFBhcmVudChudWxsKTsgcG9wdXBzLnJlbW92ZShtZW51KTsgfSB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqLworICAgIC8qKgorICAgICAqIFByaW50cyBhIGxpc3Qgb2YgdGhpcyBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBsZWFkaW5nCisgICAgICogd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHRvIHRoZSBzcGVjaWZpZWQgUHJpbnRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBQcmludFN0cmVhbSBvYmplY3QuCisgICAgICogQHBhcmFtIGluZGVudAorICAgICAqICAgICAgICAgICAgaG93IG1hbnkgbGVhZGluZyB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgdG8gcHJlcGVuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsaXN0KFByaW50U3RyZWFtIG91dCwgaW50IGluZGVudCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGdldEluZGVudFN0cihpbmRlbnQpICsgdGhpcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIGEgbGlzdCBvZiB0aGlzIGNvbXBvbmVudCB0byB0aGUgc3BlY2lmaWVkIFByaW50V3JpdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgUHJpbnRXcml0ZXIgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxpc3QoUHJpbnRXcml0ZXIgb3V0KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGlzdChvdXQsIDEpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBhIGxpc3Qgb2YgdGhpcyBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBsZWFkaW5nCisgICAgICogd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHRvIHRoZSBzcGVjaWZpZWQgUHJpbnRXcml0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBQcmludFdyaXRlciBvYmplY3QuCisgICAgICogQHBhcmFtIGluZGVudAorICAgICAqICAgICAgICAgICAgaG93IG1hbnkgbGVhZGluZyB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgdG8gcHJlcGVuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsaXN0KFByaW50V3JpdGVyIG91dCwgaW50IGluZGVudCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGdldEluZGVudFN0cihpbmRlbnQpICsgdGhpcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIHN0cmluZyBjb21wb3NlZCBvZiB0aGUgZGVzaXJlZCBudW1iZXIgb2Ygd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIFN0cmluZyB0byByZXR1cm4uCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGNvbXBvc2VkIG9mIHRoZSBkZXNpcmVkIG51bWJlciBvZiB3aGl0ZXNwYWNlCisgICAgICogICAgICAgICBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIFN0cmluZyBnZXRJbmRlbnRTdHIoaW50IGluZGVudCkgeworICAgICAgICBjaGFyW10gaW5kID0gbmV3IGNoYXJbaW5kZW50XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbmRlbnQ7IGluZFtpKytdID0gJyAnKSB7CisgICAgICAgICAgICA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoaW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBsaXN0IG9mIHRoaXMgY29tcG9uZW50IHRvIHRoZSBzcGVjaWZpZWQgUHJpbnRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBQcmludFN0cmVhbSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbGlzdChQcmludFN0cmVhbSBvdXQpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBkZWZhdWx0IGluZGVudCA9IDEKKyAgICAgICAgICAgIGxpc3Qob3V0LCAxKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBsaXN0IG9mIHRoaXMgY29tcG9uZW50IHRvIHRoZSBzdGFuZGFyZCBzeXN0ZW0gb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsaXN0KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxpc3QoU3lzdGVtLm91dCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MgdG8gYmUgdXNlZCBmb3IgcGFpbnRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoR3JhcGhpY3MgZykgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhaW50KGcpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgY29tcG9uZW50IGFuZCBhbGwgb2YgaXRzIHN1YmNvbXBvbmVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljcyB0byBiZSB1c2VkIGZvciBwYWludGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludEFsbChHcmFwaGljcyBnKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFpbnRBbGwoZyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2l6ZSBvZiB0aGUgQ29tcG9uZW50IHNwZWNpZmllZCBieSB3aWR0aCBhbmQgaGVpZ2h0IHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXNpemUod2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2l6ZSBvZiB0aGUgQ29tcG9uZW50IHNwZWNpZmllZCBieSBEaW1lbnNpb24gb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHNpemUgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaXplKERpbWVuc2lvbiBkKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzaXplKGQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQ6IHJlcGxhY2VkIGJ5IHNldFNpemUoaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aC4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0LgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHNldFNpemUoaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHJlc2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3VuZHNNYXNrUGFyYW0gPSBOYXRpdmVXaW5kb3cuQk9VTkRTX05PTU9WRTsKKyAgICAgICAgICAgIHNldEJvdW5kcyh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBzZXRTaXplKGludCwgaW50KSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHNldFNpemUoaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHJlc2l6ZShEaW1lbnNpb24gc2l6ZSkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldFNpemUoc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIGNvbXBvbmVudCBpcyBjb21wbGV0ZWx5IG9wYXF1ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgY29tcG9uZW50IGlzIGNvbXBsZXRlbHkgb3BhcXVlLCBmYWxzZSBieSBkZWZhdWx0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzT3BhcXVlKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBiZWhhdmlvdXIuaXNPcGFxdWUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcy4KKyAgICAgKiAKKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBzZXRFbmFibGVkKGJvb2xlYW4pIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIGRpc2FibGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0RW5hYmxlZEltcGwoZmFsc2UpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICAvLyA/Pz9BV1Q6IGZpcmVBY2Nlc3NpYmxlU3RhdGVDaGFuZ2UoQWNjZXNzaWJsZVN0YXRlLkVOQUJMRUQsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmFibGVzIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHNldEVuYWJsZWQoYm9vbGVhbikgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgZW5hYmxlKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldEVuYWJsZWRJbXBsKHRydWUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICAvLyA/Pz9BV1Q6IGZpcmVBY2Nlc3NpYmxlU3RhdGVDaGFuZ2UoQWNjZXNzaWJsZVN0YXRlLkVOQUJMRUQsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZSB0aGlzIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJvb2xlYW4gcGFyYW1ldGVyLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHNldEVuYWJsZWQoYm9vbGVhbikgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgZW5hYmxlKGJvb2xlYW4gYikgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChiKSB7CisgICAgICAgICAgICAgICAgZW5hYmxlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRpc2FibGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgdGhlIGxvY2F0aW9uIG9mIHRoaXMgY29tcG9uZW50IHRvIHRoZSBzcGVjaWZpZWQgUG9pbnQgb2JqZWN0OworICAgICAqIHJldHVybnMgdGhlIHBvaW50IG9mIHRoZSBjb21wb25lbnQncyB0b3AtbGVmdCBjb3JuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHJ2CisgICAgICogICAgICAgICAgICB0aGUgUG9pbnQgb2JqZWN0IHdoZXJlIHRoZSBjb21wb25lbnQncyB0b3AtbGVmdCBjb3JuZXIKKyAgICAgKiAgICAgICAgICAgIHBvc2l0aW9uIHdpbGwgYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIFBvaW50IHdoaWNoIHNwZWNpZmllcyB0aGUgY29tcG9uZW50J3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbihQb2ludCBydikgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChydiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcnYgPSBuZXcgUG9pbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJ2LnNldExvY2F0aW9uKGdldFgoKSwgZ2V0WSgpKTsKKyAgICAgICAgICAgIHJldHVybiBydjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhdGlvbiBvZiB0aGlzIGNvbXBvbmVudCBvbiB0aGUgZm9ybTsgcmV0dXJucyB0aGUgcG9pbnQgb2YgdGhlCisgICAgICogY29tcG9uZW50J3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFBvaW50IHdoaWNoIHNwZWNpZmllcyB0aGUgY29tcG9uZW50J3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbigpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYXRpb24oKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzaXplIG9mIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdGhpcyBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRTaXplKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzaXplKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcmVzIHRoZSBzaXplIG9mIHRoaXMgQ29tcG9uZW50IHRvIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcnYKKyAgICAgKiAgICAgICAgICAgIHRoZSBEaW1lbnNpb24gb2JqZWN0IHdoZXJlIHRoZSBzaXplIG9mIHRoZSBDb21wb25lbnQgd2lsbCBiZQorICAgICAqICAgICAgICAgICAgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIERpbWVuc2lvbiBvZiB0aGlzIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGltZW5zaW9uIGdldFNpemUoRGltZW5zaW9uIHJ2KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHJ2ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBydiA9IG5ldyBEaW1lbnNpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJ2LnNldFNpemUoZ2V0V2lkdGgoKSwgZ2V0SGVpZ2h0KCkpOworICAgICAgICAgICAgcmV0dXJuIHJ2OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIENvbXBvbmVudCBpcyB2YWxpZC4gQSBjb21wb25lbnQgaXMgdmFsaWQgaWYgaXQKKyAgICAgKiBpcyBjb3JyZWN0bHkgc2l6ZWQgYW5kIHBvc2l0aW9uZWQgd2l0aGluIGl0cyBwYXJlbnQgY29udGFpbmVyIGFuZCBhbGwgaXRzCisgICAgICogY2hpbGRyZW4gYXJlIGFsc28gdmFsaWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgQ29tcG9uZW50IGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdmFsaWQgJiYgYmVoYXZpb3VyLmlzRGlzcGxheWFibGUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBnZXRDb21wb25lbnRBdChpbnQsIGludCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFBvaW50LgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGdldENvbXBvbmVudEF0KGludCwgaW50KSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgUG9pbnQgbG9jYXRpb24oKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludCh4LCB5KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIENvbXBvbmVudCB0byBhIG5hdGl2ZSBzY3JlZW4gcmVzb3VyY2UgYW5kIG1ha2VzIGl0CisgICAgICogZGlzcGxheWFibGUuIFRoaXMgbWV0aG9kIG5vdCBiZSBjYWxsZWQgZGlyZWN0bHkgYnkgdXNlciBhcHBsaWNhdGlvbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkTm90aWZ5KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZXBhcmU0SGllcmFyY2h5Q2hhbmdlKCk7CisgICAgICAgICAgICBiZWhhdmlvdXIuYWRkTm90aWZ5KCk7CisgICAgICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgICAgIC8vIGZpbmlzaEhpZXJhcmNoeUNoYW5nZSh0aGlzLCBwYXJlbnQsIDApOworICAgICAgICAgICAgLy8gaWYgKGRyb3BUYXJnZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gZHJvcFRhcmdldC5hZGROb3RpZnkocGVlcik7CisgICAgICAgICAgICAvLyB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwIHRvIGRpc3BsYXkuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBiLgorICAgICAqLworICAgIHZvaWQgbWFwVG9EaXNwbGF5KGJvb2xlYW4gYikgeworICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgICogaWYgKGIgJiYgIWlzRGlzcGxheWFibGUoKSkgeyBpZiAoKHRoaXMgaW5zdGFuY2VvZiBXaW5kb3cpIHx8ICgocGFyZW50CisgICAgICAgICAqICE9IG51bGwpICYmIHBhcmVudC5pc0Rpc3BsYXlhYmxlKCkpKSB7IGFkZE5vdGlmeSgpOyB9IH0gZWxzZSBpZiAoIWIKKyAgICAgICAgICogJiYgaXNEaXNwbGF5YWJsZSgpKSB7IHJlbW92ZU5vdGlmeSgpOyB9CisgICAgICAgICAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRvb2xraXQuCisgICAgICogCisgICAgICogQHJldHVybiBhY2Nlc3NpYmxlIGNvbnRleHQgc3BlY2lmaWMgZm9yIHBhcnRpY3VsYXIgY29tcG9uZW50LgorICAgICAqLworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogQWNjZXNzaWJsZUNvbnRleHQgY3JlYXRlQWNjZXNzaWJsZUNvbnRleHQoKSB7IHJldHVybiBudWxsOyB9IHB1YmxpYworICAgICAqIEFjY2Vzc2libGVDb250ZXh0IGdldEFjY2Vzc2libGVDb250ZXh0KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgaWYKKyAgICAgKiAoYWNjZXNzaWJsZUNvbnRleHQgPT0gbnVsbCkgeyBhY2Nlc3NpYmxlQ29udGV4dCA9CisgICAgICogY3JlYXRlQWNjZXNzaWJsZUNvbnRleHQoKTsgfSByZXR1cm4gYWNjZXNzaWJsZUNvbnRleHQ7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBHZXRzIFRvb2xraXQgZm9yIHRoZSBjdXJyZW50IENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBUb29sa2l0IG9mIHRoaXMgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBUb29sa2l0IGdldFRvb2xraXQoKSB7CisgICAgICAgIHJldHVybiB0b29sa2l0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhpcyBjb21wb25lbnQncyBsb2NraW5nIG9iamVjdCBmb3IgQVdUIGNvbXBvbmVudCB0cmVlIGFuZCBsYXlvdXQKKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRyZWUgbG9ja2luZyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRUcmVlTG9jaygpIHsKKyAgICAgICAgcmV0dXJuIHRvb2xraXQuYXd0VHJlZUxvY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFuZGxlcyB0aGUgZXZlbnQuIFVzZSBBY3Rpb25MaXN0ZW5lciBpbnN0ZWFkIG9mIHRoaXMuCisgICAgICogCisgICAgICogQHBhcmFtIGV2dAorICAgICAqICAgICAgICAgICAgdGhlIEV2ZW50LgorICAgICAqIEBwYXJhbSB3aGF0CisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQncyBrZXkuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqIEBkZXByZWNhdGVkIFVzZSBBY3Rpb25MaXN0ZW5lciBjbGFzcyBmb3IgcmVnaXN0ZXJpbmcgZXZlbnQgbGlzdGVuZXIuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBhY3Rpb24oRXZlbnQgZXZ0LCBPYmplY3Qgd2hhdCkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuOiBkbyBub3RoaW5nLAorICAgICAgICAvLyBqdXN0IHJldHVybiBmYWxzZSB0byBwcm9wYWdhdGUgZXZlbnQgdXAgdG8gdGhlIHBhcmVudCBjb250YWluZXIKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByb3BlcnR5IGNoYW5nZSBzdXBwb3J0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnR5IGNoYW5nZSBzdXBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IGdldFByb3BlcnR5Q2hhbmdlU3VwcG9ydCgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChjb21wb25lbnRMb2NrKSB7CisgICAgICAgICAgICBpZiAocHJvcGVydHlDaGFuZ2VTdXBwb3J0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwcm9wZXJ0eUNoYW5nZVN1cHBvcnQgPSBuZXcgUHJvcGVydHlDaGFuZ2VTdXBwb3J0KHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5Q2hhbmdlU3VwcG9ydDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHVibGljIHZvaWQgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICogZ2V0UHJvcGVydHlDaGFuZ2VTdXBwb3J0KCkuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7IH0gcHVibGljCisgICAgICogdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFN0cmluZyBwcm9wZXJ0eU5hbWUsCisgICAgICogUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAqIGdldFByb3BlcnR5Q2hhbmdlU3VwcG9ydCgpLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIocHJvcGVydHlOYW1lLAorICAgICAqIGxpc3RlbmVyKTsgfSBwdWJsaWMgdm9pZCBhcHBseUNvbXBvbmVudE9yaWVudGF0aW9uKENvbXBvbmVudE9yaWVudGF0aW9uCisgICAgICogb3JpZW50YXRpb24pIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7CisgICAgICogc2V0Q29tcG9uZW50T3JpZW50YXRpb24ob3JpZW50YXRpb24pOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9CisgICAgICogfQorICAgICAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZXQgb2YgZm9jdXMgdHJhdmVyc2FsIGtleXMgZm9yIHRoZSBnaXZlbiBmb2N1cworICAgICAqIHRyYXZlcnNhbCBvcGVyYXRpb24gaGFzIGJlZW4gZXhwbGljaXRseSBkZWZpbmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBJRCBvZiB0cmF2ZXJzYWwga2V5LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNldCBvZiBmb2N1cyB0cmF2ZXJzYWwga2V5cyBmb3IgdGhlIGdpdmVuIGZvY3VzLgorICAgICAqICAgICAgICAgdHJhdmVyc2FsIG9wZXJhdGlvbiBoYXMgYmVlbiBleHBsaWNpdGx5IGRlZmluZWQgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgIENvbXBvbmVudCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFyZUZvY3VzVHJhdmVyc2FsS2V5c1NldChpbnQgaWQpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnRlZ2VyIElkID0gbmV3IEludGVnZXIoaWQpOworICAgICAgICAgICAgaWYgKHRyYXZlcnNhbEtleXMuY29udGFpbnNLZXkoSWQpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbEtleXMuZ2V0KElkKSAhPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gYXd0LjE0Rj1pbnZhbGlkIGZvY3VzIHRyYXZlcnNhbCBrZXkgaWRlbnRpZmllcgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xNEYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSByZWN0YW5nbGUgYm91bmRzIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIGdldEJvdW5kcygpIG1ldGhvb2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgUmVjdGFuZ2xlIGJvdW5kcygpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZSh4LCB5LCB3LCBoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb25zdHJ1Y3Rpb24gc3RhdHVzIG9mIGEgc3BlY2lmaWVkIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHdpZHRoIGFuZCBoZWlnaHQgdGhhdCBpcyBiZWluZyBjcmVhdGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHRvIGJlIGNoZWNrZWQuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2Ygc2NhbGVkIGltYWdlIHdoaWNoIHN0YXR1cyBpcyBiZWluZyBjaGVja2VkLCBvcgorICAgICAqICAgICAgICAgICAgLTEuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBzY2FsZWQgaW1hZ2Ugd2hpY2ggc3RhdHVzIGlzIGJlaW5nIGNoZWNrZWQsIG9yCisgICAgICogICAgICAgICAgICAtMS4KKyAgICAgKiBAcGFyYW0gb2JzZXJ2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZU9ic2VydmVyIG9iamVjdCB0byBiZSBub3RpZmllZCB3aGlsZSB0aGUgaW1hZ2UgaXMKKyAgICAgKiAgICAgICAgICAgIGJlaW5nIHByZXBhcmVkLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlT2JzZXJ2ZXIgZmxhZ3Mgb2YgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGludCBjaGVja0ltYWdlKEltYWdlIGltYWdlLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdG9vbGtpdC5jaGVja0ltYWdlKGltYWdlLCB3aWR0aCwgaGVpZ2h0LCBvYnNlcnZlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29uc3RydWN0aW9uIHN0YXR1cyBvZiBhIHNwZWNpZmllZCBpbWFnZSB0aGF0IGlzIGJlaW5nCisgICAgICogY3JlYXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0byBiZSBjaGVja2VkLgorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHRvIGJlIG5vdGlmaWVkIHdoaWxlIHRoZSBpbWFnZSBpcworICAgICAqICAgICAgICAgICAgYmVpbmcgcHJlcGFyZWQuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VPYnNlcnZlciBmbGFncyBvZiB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNoZWNrSW1hZ2UoSW1hZ2UgaW1hZ2UsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdG9vbGtpdC5jaGVja0ltYWdlKGltYWdlLCAtMSwgLTEsIG9ic2VydmVyKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb2FsZXNjZXMgdGhlIGV4aXN0ZWQgZXZlbnQgd2l0aCBuZXcgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGV4aXN0aW5nRXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGlzdGluZyBldmVudCBpbiB0aGUgRXZlbnRRdWV1ZS4KKyAgICAgKiBAcGFyYW0gbmV3RXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZXZlbnQgdG8gYmUgcG9zdGVkIHRvIHRoZSBFdmVudFF1ZXVlLgorICAgICAqIEByZXR1cm4gdGhlIGNvYWxlc2NlZCBBV1RFdmVudCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBjb2FsZXNjaW5nIGRvbmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIEFXVEV2ZW50IGNvYWxlc2NlRXZlbnRzKEFXVEV2ZW50IGV4aXN0aW5nRXZlbnQsIEFXVEV2ZW50IG5ld0V2ZW50KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbzoKKyAgICAgICAgICAgIC8vIDEuIE1vdXNlIGV2ZW50cyBjb2FsZXNjZWQgYXQgV1RLIGxldmVsCisgICAgICAgICAgICAvLyAyLiBQYWludCBldmVudHMgaGFuZGxlZCBieSBSZWRyYXdNYW5hZ2VyCisgICAgICAgICAgICAvLyBUaGlzIG1ldGhvZCBpcyBmb3Igb3ZlcnJpZGluZyBvbmx5CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBDb21wb25lbnQgaXMgYSBjb2FsZXNjZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBjb2FsZXNjZXIuCisgICAgICovCisgICAgYm9vbGVhbiBpc0NvYWxlc2NlcigpIHsKKyAgICAgICAgcmV0dXJuIGNvYWxlc2NlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZWxhdGl2ZSBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWxhdGl2ZSBldmVudC4KKyAgICAgKi8KKyAgICBBV1RFdmVudCBnZXRSZWxhdGl2ZUV2ZW50KGludCBpZCkgeworICAgICAgICBJbnRlZ2VyIGlkV3JhcHBlciA9IG5ldyBJbnRlZ2VyKGlkKTsKKyAgICAgICAgZXZlbnRzTGlzdCA9IGV2ZW50c1RhYmxlLmdldChpZFdyYXBwZXIpOworICAgICAgICBpZiAoZXZlbnRzTGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBldmVudHNMaXN0ID0gbmV3IExpbmtlZExpc3Q8QVdURXZlbnQ+KCk7CisgICAgICAgICAgICBldmVudHNUYWJsZS5wdXQoaWRXcmFwcGVyLCBldmVudHNMaXN0KTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChldmVudHNMaXN0LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV2ZW50c0xpc3QuZ2V0TGFzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIG5ldyBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBldmVudC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZE5ld0V2ZW50KEFXVEV2ZW50IGV2ZW50KSB7CisgICAgICAgIGV2ZW50c0xpc3QuYWRkTGFzdChldmVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgcmVsYXRpdmUgZXZlbnQuCisgICAgICovCisgICAgdm9pZCByZW1vdmVSZWxhdGl2ZUV2ZW50KCkgeworICAgICAgICBldmVudHNMaXN0LnJlbW92ZUxhc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBuZXh0IGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZAorICAgICAqICAgICAgICAgICAgdGhlIGlkLgorICAgICAqLworICAgIHZvaWQgcmVtb3ZlTmV4dEV2ZW50KGludCBpZCkgeworICAgICAgICBldmVudHNUYWJsZS5nZXQobmV3IEludGVnZXIoaWQpKS5yZW1vdmVGaXJzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBJbWFnZVByb2R1Y2VyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9kdWNlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUHJvZHVjZXIgdG8gYmUgdXNlZCBmb3IgaW1hZ2UgY3JlYXRpb24uCisgICAgICogQHJldHVybiB0aGUgaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIEltYWdlUHJvZHVjZXIuCisgICAgICovCisgICAgcHVibGljIEltYWdlIGNyZWF0ZUltYWdlKEltYWdlUHJvZHVjZXIgcHJvZHVjZXIpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdG9vbGtpdC5jcmVhdGVJbWFnZShwcm9kdWNlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBvZmYtc2NyZWVuIGRyYXdhYmxlIGltYWdlIHRvIGJlIHVzZWQgZm9yIGRvdWJsZSBidWZmZXJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlLgorICAgICAqIEByZXR1cm4gdGhlIG9mZi1zY3JlZW4gZHJhd2FibGUgaW1hZ2Ugb3IgbnVsbCBpZiB0aGUgY29tcG9uZW50IGlzIG5vdAorICAgICAqICAgICAgICAgZGlzcGxheWFibGUgb3IgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMKKyAgICAgKiAgICAgICAgIHRydWUuCisgICAgICovCisgICAgcHVibGljIEltYWdlIGNyZWF0ZUltYWdlKGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghaXNEaXNwbGF5YWJsZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBHcmFwaGljc0NvbmZpZ3VyYXRpb24gZ2MgPSBnZXRHcmFwaGljc0NvbmZpZ3VyYXRpb24oKTsKKyAgICAgICAgICAgIGlmIChnYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBDb2xvck1vZGVsIGNtID0gZ2MuZ2V0Q29sb3JNb2RlbChUcmFuc3BhcmVuY3kuT1BBUVVFKTsKKyAgICAgICAgICAgIFdyaXRhYmxlUmFzdGVyIHdyID0gY20uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHdpZHRoLCBoZWlnaHQpOworICAgICAgICAgICAgSW1hZ2UgaW1hZ2UgPSBuZXcgQnVmZmVyZWRJbWFnZShjbSwgd3IsIGNtLmlzQWxwaGFQcmVtdWx0aXBsaWVkKCksIG51bGwpOworICAgICAgICAgICAgZmlsbEltYWdlQmFja2dyb3VuZChpbWFnZSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICByZXR1cm4gaW1hZ2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBvZmYtc2NyZWVuIGRyYXdhYmxlIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCwgaGVpZ2h0IGFuZAorICAgICAqIEltYWdlQ2FwYWJpbGl0aWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQuCisgICAgICogQHBhcmFtIGNhcHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZUNhcGFiaWxpdGllcy4KKyAgICAgKiBAcmV0dXJuIHRoZSB2b2xhdGlsZSBpbWFnZS4KKyAgICAgKiBAdGhyb3dzIEFXVEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBjYXBhYmlsaXRpZXMgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVm9sYXRpbGVJbWFnZSBjcmVhdGVWb2xhdGlsZUltYWdlKGludCB3aWR0aCwgaW50IGhlaWdodCwgSW1hZ2VDYXBhYmlsaXRpZXMgY2FwcykKKyAgICAgICAgICAgIHRocm93cyBBV1RFeGNlcHRpb24geworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghaXNEaXNwbGF5YWJsZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBHcmFwaGljc0NvbmZpZ3VyYXRpb24gZ2MgPSBnZXRHcmFwaGljc0NvbmZpZ3VyYXRpb24oKTsKKyAgICAgICAgICAgIGlmIChnYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBWb2xhdGlsZUltYWdlIGltYWdlID0gZ2MuY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2Uod2lkdGgsIGhlaWdodCwgY2Fwcyk7CisgICAgICAgICAgICBmaWxsSW1hZ2VCYWNrZ3JvdW5kKGltYWdlLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgIHJldHVybiBpbWFnZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdm9sYXRpbGUgb2ZmLXNjcmVlbiBkcmF3YWJsZSBpbWFnZSB3aGljaCBpcyB1c2VkIGZvciBkb3VibGUKKyAgICAgKiBidWZmZXJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBpbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2b2xhdGlsZSBpbWFnZSBhIHZvbGF0aWxlIG9mZi1zY3JlZW4gZHJhd2FibGUgaW1hZ2Ugd2hpY2ggaXMKKyAgICAgKiAgICAgICAgIHVzZWQgZm9yIGRvdWJsZSBidWZmZXJpbmcgb3IgbnVsbCBpZiB0aGUgY29tcG9uZW50IGlzIG5vdAorICAgICAqICAgICAgICAgZGlzcGxheWFibGUsIG9yIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zCisgICAgICogICAgICAgICB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBWb2xhdGlsZUltYWdlIGNyZWF0ZVZvbGF0aWxlSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFpc0Rpc3BsYXlhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBnYyA9IGdldEdyYXBoaWNzQ29uZmlndXJhdGlvbigpOworICAgICAgICAgICAgaWYgKGdjID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFZvbGF0aWxlSW1hZ2UgaW1hZ2UgPSBnYy5jcmVhdGVDb21wYXRpYmxlVm9sYXRpbGVJbWFnZSh3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgIGZpbGxJbWFnZUJhY2tncm91bmQoaW1hZ2UsIHdpZHRoLCBoZWlnaHQpOworICAgICAgICAgICAgcmV0dXJuIGltYWdlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGwgdGhlIGltYWdlIGJlaW5nIGNyZWF0ZWQgYnkgY3JlYXRlSW1hZ2UoKSBvciBjcmVhdGVWb2xhdGlsZUltYWdlKCkKKyAgICAgKiB3aXRoIHRoZSBjb21wb25lbnQncyBiYWNrZ3JvdW5kIGNvbG9yIHRvIHByZXBhcmUgaXQgZm9yIGRvdWJsZS1idWZmZXJlZAorICAgICAqIHBhaW50aW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZpbGxJbWFnZUJhY2tncm91bmQoSW1hZ2UgaW1hZ2UsIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBHcmFwaGljcyBnciA9IGltYWdlLmdldEdyYXBoaWNzKCk7CisgICAgICAgIGdyLnNldENvbG9yKGdldEJhY2tncm91bmQoKSk7CisgICAgICAgIGdyLmZpbGxSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOworICAgICAgICBnci5kaXNwb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsaXZlcnMgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGV2dAorICAgICAqICAgICAgICAgICAgdGhlIGV2ZW50LgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZSkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgZGVsaXZlckV2ZW50KEV2ZW50IGV2dCkgeworICAgICAgICBwb3N0RXZlbnQoZXZ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9tcHRzIHRoZSBsYXlvdXQgbWFuYWdlciB0byBsYXkgb3V0IHRoaXMgY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRvTGF5b3V0KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxheW91dCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICAvLyBJbXBsZW1lbnRlZCBpbiBDb250YWluZXIKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaXJlIHByb3BlcnR5IGNoYW5nZSBpbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBwYXJhbSBvbGRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG9sZCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZUltcGwoU3RyaW5nIHByb3BlcnR5TmFtZSwgT2JqZWN0IG9sZFZhbHVlLCBPYmplY3QgbmV3VmFsdWUpIHsKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IHBjczsKKyAgICAgICAgc3luY2hyb25pemVkIChjb21wb25lbnRMb2NrKSB7CisgICAgICAgICAgICBpZiAocHJvcGVydHlDaGFuZ2VTdXBwb3J0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwY3MgPSBwcm9wZXJ0eUNoYW5nZVN1cHBvcnQ7CisgICAgICAgIH0KKyAgICAgICAgcGNzLmZpcmVQcm9wZXJ0eUNoYW5nZShwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZXMgZm9yIGludCBwcm9wZXJ0aWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBwYXJhbSBvbGRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG9sZCBwcm9wZXJ0eSdzIHZhbHVlLgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwcm9wZXJ0eSdzIHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBpbnQgb2xkVmFsdWUsIGludCBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgbmV3IEludGVnZXIob2xkVmFsdWUpLCBuZXcgSW50ZWdlcihuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYSBib29sZWFuLXZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG9sZCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG5ldyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2UoU3RyaW5nIHByb3BlcnR5TmFtZSwgYm9vbGVhbiBvbGRWYWx1ZSwgYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgQm9vbGVhbi52YWx1ZU9mKG9sZFZhbHVlKSwgQm9vbGVhbi52YWx1ZU9mKG5ld1ZhbHVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYW4gT2JqZWN0LXZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG9sZCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG5ldyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2UoZmluYWwgU3RyaW5nIHByb3BlcnR5TmFtZSwgZmluYWwgT2JqZWN0IG9sZFZhbHVlLAorICAgICAgICAgICAgZmluYWwgT2JqZWN0IG5ld1ZhbHVlKSB7CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZUltcGwocHJvcGVydHlOYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYSBieXRlLXZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG9sZCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG5ldyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2UoU3RyaW5nIHByb3BlcnR5TmFtZSwgYnl0ZSBvbGRWYWx1ZSwgYnl0ZSBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgbmV3IEJ5dGUob2xkVmFsdWUpLCBuZXcgQnl0ZShuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYSBjaGFyLXZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbGQgcHJvcGVydHkncyB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcHJvcGVydHkncyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2UoU3RyaW5nIHByb3BlcnR5TmFtZSwgY2hhciBvbGRWYWx1ZSwgY2hhciBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgbmV3IENoYXJhY3RlcihvbGRWYWx1ZSksIG5ldyBDaGFyYWN0ZXIobmV3VmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYSBib3VuZCBwcm9wZXJ0eSBjaGFuZ2UgZm9yIGEgc2hvcnQtdmFsdWVkIHByb3BlcnR5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBwYXJhbSBvbGRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG9sZCBwcm9wZXJ0eSdzIHZhbHVlLgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwcm9wZXJ0eSdzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBzaG9ydCBvbGRWYWx1ZSwgc2hvcnQgbmV3VmFsdWUpIHsKKyAgICAgICAgZmlyZVByb3BlcnR5Q2hhbmdlSW1wbChwcm9wZXJ0eU5hbWUsIG5ldyBTaG9ydChvbGRWYWx1ZSksIG5ldyBTaG9ydChuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYSBsb25nLXZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbGQgcHJvcGVydHkncyB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcHJvcGVydHkncyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2UoU3RyaW5nIHByb3BlcnR5TmFtZSwgbG9uZyBvbGRWYWx1ZSwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgbmV3IExvbmcob2xkVmFsdWUpLCBuZXcgTG9uZyhuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJvdW5kIHByb3BlcnR5IGNoYW5nZSBmb3IgYSBmbG9hdC12YWx1ZWQgcHJvcGVydHkuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3BlcnR5TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHBhcmFtIG9sZFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2xkIHByb3BlcnR5J3MgdmFsdWUuCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHByb3BlcnR5J3MgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmlyZVByb3BlcnR5Q2hhbmdlKFN0cmluZyBwcm9wZXJ0eU5hbWUsIGZsb2F0IG9sZFZhbHVlLCBmbG9hdCBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2VJbXBsKHByb3BlcnR5TmFtZSwgbmV3IEZsb2F0KG9sZFZhbHVlKSwgbmV3IEZsb2F0KG5ld1ZhbHVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0IGEgYm91bmQgcHJvcGVydHkgY2hhbmdlIGZvciBhIGRvdWJsZS12YWx1ZWQgcHJvcGVydHkuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3BlcnR5TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHBhcmFtIG9sZFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2xkIHByb3BlcnR5J3MgdmFsdWUuCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHByb3BlcnR5J3MgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmlyZVByb3BlcnR5Q2hhbmdlKFN0cmluZyBwcm9wZXJ0eU5hbWUsIGRvdWJsZSBvbGRWYWx1ZSwgZG91YmxlIG5ld1ZhbHVlKSB7CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZUltcGwocHJvcGVydHlOYW1lLCBuZXcgRG91YmxlKG9sZFZhbHVlKSwgbmV3IERvdWJsZShuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFsaWdubWVudCBhbG9uZyB0aGUgeCBheGlzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFsaWdubWVudCBhbG9uZyB0aGUgeCBheGlzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRBbGlnbm1lbnRYKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBDRU5URVJfQUxJR05NRU5UOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFsaWdubWVudCBhbG9uZyB0aGUgeSBheGlzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFsaWdubWVudCBhbG9uZyB5IGF4aXMuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEFsaWdubWVudFkoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIENFTlRFUl9BTElHTk1FTlQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvciBmb3IgdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmFja2dyb3VuZCBjb2xvciBmb3IgdGhpcyBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIENvbG9yIGdldEJhY2tncm91bmQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgKChiYWNrQ29sb3IgPT0gbnVsbCkgJiYgKHBhcmVudCAhPSBudWxsKSkgeyByZXR1cm4KKyAgICAgICAgICAgICAqIHBhcmVudC5nZXRCYWNrZ3JvdW5kKCk7IH0KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuIGJhY2tDb2xvcjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIG9mIHRoaXMgY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBib3VuZHMoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGRhdGEgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSB0byB0aGUgc3BlY2lmaWVkIFJlY3RhbmdsZQorICAgICAqIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcnYKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgb2JqZWN0IHdoZXJlIHRoZSBib3VuZGluZyByZWN0YW5nbGUncyBkYXRhIGlzCisgICAgICogICAgICAgICAgICBzdG9yZWQuCisgICAgICogQHJldHVybiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKFJlY3RhbmdsZSBydikgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChydiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcnYgPSBuZXcgUmVjdGFuZ2xlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBydi5zZXRCb3VuZHMoeCwgeSwgdywgaCk7CisgICAgICAgICAgICByZXR1cm4gcnY7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29sb3IgbW9kZWwgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xvciBtb2RlbCBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBDb2xvck1vZGVsIGdldENvbG9yTW9kZWwoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldFRvb2xraXQoKS5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQ29tcG9uZW50IHdoaWNoIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgUG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBDb21wb25lbnQgd2hpY2ggY29udGFpbnMgdGhlIHNwZWNpZmllZCBQb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcG9uZW50IGdldENvbXBvbmVudEF0KFBvaW50IHApIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50QXQocC54LCBwLnkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbXBvbmVudCB3aGljaCBjb250YWlucyB0aGUgcG9pbnQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50LgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBDb21wb25lbnQgd2hpY2ggY29udGFpbnMgdGhlIHBvaW50IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgY29vcmRpbmF0ZXMuCisgICAgICovCisgICAgcHVibGljIENvbXBvbmVudCBnZXRDb21wb25lbnRBdChpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYXRlKHgsIHkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXBvbmVudCdzIG9yaWVudGF0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNvbXBvbmVudCdzIG9yaWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDb21wb25lbnRPcmllbnRhdGlvbiBnZXRDb21wb25lbnRPcmllbnRhdGlvbigpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb247CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3Vyc29yIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQ3Vyc29yLgorICAgICAqLworICAgIHB1YmxpYyBDdXJzb3IgZ2V0Q3Vyc29yKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjdXJzb3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiB9IGVsc2UgaWYgKHBhcmVudCAhPSBudWxsKSB7IHJldHVybiBwYXJlbnQuZ2V0Q3Vyc29yKCk7CisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gQ3Vyc29yLmdldERlZmF1bHRDdXJzb3IoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHB1YmxpYyBEcm9wVGFyZ2V0IGdldERyb3BUYXJnZXQoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBkcm9wVGFyZ2V0OyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0gcHVibGljIENvbnRhaW5lcgorICAgICAqIGdldEZvY3VzQ3ljbGVSb290QW5jZXN0b3IoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBmb3IgKENvbnRhaW5lciBjID0KKyAgICAgKiBwYXJlbnQ7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0UGFyZW50KCkpIHsgaWYgKGMuaXNGb2N1c0N5Y2xlUm9vdCgpKSB7CisgICAgICogcmV0dXJuIGM7IH0gfSByZXR1cm4gbnVsbDsgfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICogQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIHB1YmxpYyBTZXQ8QVdUS2V5U3Ryb2tlPgorICAgICAqIGdldEZvY3VzVHJhdmVyc2FsS2V5cyhpbnQgaWQpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IEludGVnZXIga0lkID0KKyAgICAgKiBuZXcgSW50ZWdlcihpZCk7IEtleWJvYXJkRm9jdXNNYW5hZ2VyLmNoZWNrVHJhdmVyc2FsS2V5c0lEKHRyYXZlcnNhbEtleXMsCisgICAgICoga0lkKTsgU2V0PD8gZXh0ZW5kcyBBV1RLZXlTdHJva2U+IGtleXMgPSB0cmF2ZXJzYWxLZXlzLmdldChrSWQpOyBpZiAoa2V5cworICAgICAqID09IG51bGwgJiYgcGFyZW50ICE9IG51bGwpIHsga2V5cyA9IHBhcmVudC5nZXRGb2N1c1RyYXZlcnNhbEtleXMoaWQpOyB9CisgICAgICogaWYgKGtleXMgPT0gbnVsbCkgeyBrZXlzID0KKyAgICAgKiBLZXlib2FyZEZvY3VzTWFuYWdlci5nZXRDdXJyZW50S2V5Ym9hcmRGb2N1c01hbmFnZXIoKQorICAgICAqIC5nZXREZWZhdWx0Rm9jdXNUcmF2ZXJzYWxLZXlzKGlkKTsgfSByZXR1cm4gKFNldDxBV1RLZXlTdHJva2U+KSBrZXlzOyB9CisgICAgICogZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSB0aGUgZm9jdXMgdHJhdmVyc2FsIGtleXMgYXJlIGVuYWJsZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHRoZSBmb2N1cyB0cmF2ZXJzYWwga2V5cyBhcmUgZW5hYmxlZCBmb3IgdGhpcworICAgICAqICAgICAgICAgY29tcG9uZW50LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Rm9jdXNUcmF2ZXJzYWxLZXlzRW5hYmxlZCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZm9jdXNUcmF2ZXJzYWxLZXlzRW5hYmxlZDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmb250IG1ldHJpY3Mgb2YgdGhlIHNwZWNpZmllZCBGb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgRm9udC4KKyAgICAgKiBAcmV0dXJuIHRoZSBGb250TWV0cmljcyBvZiB0aGUgc3BlY2lmaWVkIEZvbnQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgRm9udE1ldHJpY3MgZ2V0Rm9udE1ldHJpY3MoRm9udCBmKSB7CisgICAgICAgIHJldHVybiB0b29sa2l0LmdldEZvbnRNZXRyaWNzKGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvcmVncm91bmQgY29sb3Igb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JlZ3JvdW5kIGNvbG9yIG9mIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIENvbG9yIGdldEZvcmVncm91bmQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgKGZvcmVDb2xvciA9PSBudWxsICYmIHBhcmVudCAhPSBudWxsKSB7IHJldHVybgorICAgICAgICAgICAgICogcGFyZW50LmdldEZvcmVncm91bmQoKTsgfQorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gZm9yZUNvbG9yOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEdyYXBoaWNzIG9mIHRoZSBDb21wb25lbnQgb3IgbnVsbCBpZiB0aGlzIENvbXBvbmVudCBpcyBub3QKKyAgICAgKiBkaXNwbGF5YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBHcmFwaGljcyBvZiB0aGUgQ29tcG9uZW50IG9yIG51bGwgaWYgdGhpcyBDb21wb25lbnQgaXMgbm90CisgICAgICogICAgICAgICBkaXNwbGF5YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhcGhpY3MgZ2V0R3JhcGhpY3MoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFpc0Rpc3BsYXlhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEdyYXBoaWNzIGcgPSBiZWhhdmlvdXIuZ2V0R3JhcGhpY3MoMCwgMCwgdywgaCk7CisgICAgICAgICAgICBnLnNldENvbG9yKGZvcmVDb2xvcik7CisgICAgICAgICAgICBnLnNldEZvbnQoZm9udCk7CisgICAgICAgICAgICByZXR1cm4gZzsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBnZXRHcmFwaGljc0NvbmZpZ3VyYXRpb24oKSB7CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvKgorICAgICAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgV2luZG93IHdpbiA9IGdldFdpbmRvd0FuY2VzdG9yKCk7IGlmICh3aW4gPT0KKyAgICAgICAgICogbnVsbCkgeyByZXR1cm4gbnVsbDsgfSByZXR1cm4gd2luLmdldEdyYXBoaWNzQ29uZmlndXJhdGlvbigpOyB9CisgICAgICAgICAqIGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9CisgICAgICAgICAqLworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlaWdodCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gaDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcGFpbnQgbWVzc2FnZXMgcmVjZWl2ZWQgZnJvbSB0aGUgb3BlcmF0aW5nIHN5c3RlbSBzaG91bGQKKyAgICAgKiBiZSBpZ25vcmVkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBwYWludCBtZXNzYWdlcyByZWNlaXZlZCBmcm9tIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHNob3VsZAorICAgICAqICAgICAgICAgYmUgaWdub3JlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldElnbm9yZVJlcGFpbnQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGlnbm9yZVJlcGFpbnQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW5wdXQgY29udGV4dCBvZiB0aGlzIGNvbXBvbmVudCBmb3IgaGFuZGxpbmcgdGhlIGNvbW11bmljYXRpb24KKyAgICAgKiB3aXRoIGlucHV0IG1ldGhvZHMgd2hlbiB0ZXh0IGlzIGVudGVyZWQgaW4gdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgSW5wdXRDb250ZXh0IHVzZWQgYnkgdGhpcyBDb21wb25lbnQgb3IgbnVsbCBpZiBubyBjb250ZXh0IGlzCisgICAgICogICAgICAgICBzcGVjaWZpbmVkLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dENvbnRleHQgZ2V0SW5wdXRDb250ZXh0KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vID8/P0FXVAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIENvbnRhaW5lciBwYXJlbnQgPSBnZXRQYXJlbnQoKTsgaWYgKHBhcmVudCAhPSBudWxsKSB7IHJldHVybgorICAgICAgICAgICAgICogcGFyZW50LmdldElucHV0Q29udGV4dCgpOyB9CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGlucHV0IG1ldGhvZCByZXF1ZXN0IGhhbmRsZXIgd2hpY2ggc3VwcG9ydHMgcmVxdWVzdHMgZnJvbSBpbnB1dAorICAgICAqIG1ldGhvZHMgZm9yIHRoaXMgY29tcG9uZW50LCBvciBudWxsIGZvciBkZWZhdWx0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IG1ldGhvZCByZXF1ZXN0IGhhbmRsZXIgd2hpY2ggc3VwcG9ydHMgcmVxdWVzdHMgZnJvbQorICAgICAqICAgICAgICAgaW5wdXQgbWV0aG9kcyBmb3IgdGhpcyBjb21wb25lbnQsIG9yIG51bGwgZm9yIGRlZmF1bHQuCisgICAgICovCisgICAgcHVibGljIElucHV0TWV0aG9kUmVxdWVzdHMgZ2V0SW5wdXRNZXRob2RSZXF1ZXN0cygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWxlIG9mIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsZSBvZiB0aGlzIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBpZiAobG9jYWxlID09IG51bGwpIHsgaWYgKHBhcmVudCA9PSBudWxsKSB7IGlmICh0aGlzIGluc3RhbmNlb2YKKyAgICAgICAgICAgICAqIFdpbmRvdykgeyByZXR1cm4gTG9jYWxlLmdldERlZmF1bHQoKTsgfSAvLyBhd3QuMTUwPW5vIHBhcmVudAorICAgICAgICAgICAgICogdGhyb3cgbmV3CisgICAgICAgICAgICAgKiBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTUwIikpOworICAgICAgICAgICAgICogLy8kTk9OLU5MUy0xJCB9IHJldHVybiBnZXRQYXJlbnQoKS5nZXRMb2NhbGUoKTsgfQorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gbG9jYWxlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2F0aW9uIG9mIHRoaXMgY29tcG9uZW50IGluIHRoZSBmb3JtIG9mIGEgcG9pbnQgc3BlY2lmeWluZyB0aGUKKyAgICAgKiBjb21wb25lbnQncyB0b3AtbGVmdCBjb3JuZXIgaW4gdGhlIHNjcmVlbidzIGNvb3JkaW5hdGUgc3BhY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUG9pbnQgZ2l2aW5nIHRoZSBjb21wb25lbnQncyBsb2NhdGlvbiBpbiB0aGUgc2NyZWVuJ3MKKyAgICAgKiAgICAgICAgIGNvb3JkaW5hdGUgc3BhY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29tcG9uZW50IGlzIG5vdCBzaG93biBvbiB0aGUgc2NyZWVuLgorICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbk9uU2NyZWVuKCkgdGhyb3dzIElsbGVnYWxDb21wb25lbnRTdGF0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUG9pbnQgcCA9IG5ldyBQb2ludCgpOworICAgICAgICAgICAgaWYgKGlzU2hvd2luZygpKSB7CisgICAgICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBDb21wb25lbnQgY29tcDsgZm9yIChjb21wID0gdGhpczsgY29tcCAhPSBudWxsICYmICEoY29tcAorICAgICAgICAgICAgICAgICAqIGluc3RhbmNlb2YgV2luZG93KTsgY29tcCA9IGNvbXAgLmdldFBhcmVudCgpKSB7CisgICAgICAgICAgICAgICAgICogcC50cmFuc2xhdGUoY29tcC5nZXRYKCksIGNvbXAuZ2V0WSgpKTsgfSBpZiAoY29tcCBpbnN0YW5jZW9mCisgICAgICAgICAgICAgICAgICogV2luZG93KSB7IHAudHJhbnNsYXRlKGNvbXAuZ2V0WCgpLCBjb21wLmdldFkoKSk7IH0KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGF3dC4xNTE9Y29tcG9uZW50IG11c3QgYmUgc2hvd2luZyBvbiB0aGUgc2NyZWVuIHRvIGRldGVybWluZSBpdHMKKyAgICAgICAgICAgIC8vIGxvY2F0aW9uCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbENvbXBvbmVudFN0YXRlRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE1MSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBlZXIuIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJ5IHVzZXIKKyAgICAgKiBhcHBsaWNhdGlvbnMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQ29tcG9uZW50UGVlci4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBpc0Rpc3BsYXlhYmxlKCkuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgQ29tcG9uZW50UGVlciBnZXRQZWVyKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChiZWhhdmlvdXIuaXNEaXNwbGF5YWJsZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBlZXI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHRoZSBwcm9wZXJ0eSBjaGFuZ2UgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgdG8gdGhpcworICAgICAqIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcltdIGdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkgeworICAgICAgICByZXR1cm4gZ2V0UHJvcGVydHlDaGFuZ2VTdXBwb3J0KCkuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgb2JqZWN0cyByZWdpc3RlcmVkIHRvIHRoaXMKKyAgICAgKiBDb21wb25lbnQgZm9yIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3BlcnR5TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIG9iamVjdHMgcmVnaXN0ZXJlZCB0byB0aGlzCisgICAgICogICAgICAgICBDb21wb25lbnQgZm9yIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJbXSBnZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycyhTdHJpbmcgcHJvcGVydHlOYW1lKSB7CisgICAgICAgIHJldHVybiBnZXRQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoKS5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycyhwcm9wZXJ0eU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd2lkdGggb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdpZHRoKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiB3OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgY29tcG9uZW50J3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgY29tcG9uZW50J3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0WCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNvbXBvbmVudCdzIHRvcC1sZWZ0IGNvcm5lci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNvbXBvbmVudCdzIHRvcC1sZWZ0IGNvcm5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFkoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR290IHRoZSBmb2N1cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZ0CisgICAgICogICAgICAgICAgICB0aGUgRXZlbnQuCisgICAgICogQHBhcmFtIHdoYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHByb2Nlc3NGb2N1c0V2ZW50KEZvY3VzRXZlbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIGdvdEZvY3VzKEV2ZW50IGV2dCwgT2JqZWN0IHdoYXQpIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbjogZG8gbm90aGluZywKKyAgICAgICAgLy8ganVzdCByZXR1cm4gZmFsc2UgdG8gcHJvcGFnYXRlIGV2ZW50IHVwIHRvIHRoZSBwYXJlbnQgY29udGFpbmVyCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGVzIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgcHJvY2Vzc0V2ZW50KEFXVEV2ZW50KSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVFdmVudChFdmVudCBldnQpIHsKKyAgICAgICAgc3dpdGNoIChldnQuaWQpIHsKKyAgICAgICAgICAgIGNhc2UgRXZlbnQuQUNUSU9OX0VWRU5UOgorICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb24oZXZ0LCBldnQuYXJnKTsKKyAgICAgICAgICAgIGNhc2UgRXZlbnQuR09UX0ZPQ1VTOgorICAgICAgICAgICAgICAgIHJldHVybiBnb3RGb2N1cyhldnQsIG51bGwpOworICAgICAgICAgICAgY2FzZSBFdmVudC5MT1NUX0ZPQ1VTOgorICAgICAgICAgICAgICAgIHJldHVybiBsb3N0Rm9jdXMoZXZ0LCBudWxsKTsKKyAgICAgICAgICAgIGNhc2UgRXZlbnQuTU9VU0VfRE9XTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gbW91c2VEb3duKGV2dCwgZXZ0LngsIGV2dC55KTsKKyAgICAgICAgICAgIGNhc2UgRXZlbnQuTU9VU0VfRFJBRzoKKyAgICAgICAgICAgICAgICByZXR1cm4gbW91c2VEcmFnKGV2dCwgZXZ0LngsIGV2dC55KTsKKyAgICAgICAgICAgIGNhc2UgRXZlbnQuTU9VU0VfRU5URVI6CisgICAgICAgICAgICAgICAgcmV0dXJuIG1vdXNlRW50ZXIoZXZ0LCBldnQueCwgZXZ0LnkpOworICAgICAgICAgICAgY2FzZSBFdmVudC5NT1VTRV9FWElUOgorICAgICAgICAgICAgICAgIHJldHVybiBtb3VzZUV4aXQoZXZ0LCBldnQueCwgZXZ0LnkpOworICAgICAgICAgICAgY2FzZSBFdmVudC5NT1VTRV9NT1ZFOgorICAgICAgICAgICAgICAgIHJldHVybiBtb3VzZU1vdmUoZXZ0LCBldnQueCwgZXZ0LnkpOworICAgICAgICAgICAgY2FzZSBFdmVudC5NT1VTRV9VUDoKKyAgICAgICAgICAgICAgICByZXR1cm4gbW91c2VVcChldnQsIGV2dC54LCBldnQueSk7CisgICAgICAgICAgICBjYXNlIEV2ZW50LktFWV9BQ1RJT046CisgICAgICAgICAgICBjYXNlIEV2ZW50LktFWV9QUkVTUzoKKyAgICAgICAgICAgICAgICByZXR1cm4ga2V5RG93bihldnQsIGV2dC5rZXkpOworICAgICAgICAgICAgY2FzZSBFdmVudC5LRVlfQUNUSU9OX1JFTEVBU0U6CisgICAgICAgICAgICBjYXNlIEV2ZW50LktFWV9SRUxFQVNFOgorICAgICAgICAgICAgICAgIHJldHVybiBrZXlVcChldnQsIGV2dC5rZXkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsvLyBldmVudCBub3QgaGFuZGxlZAorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBDb21wb25lbnQgaXMgdGhlIGZvY3VzIG93bmVyIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBDb21wb25lbnQgaXMgdGhlIGZvY3VzIG93bmVyLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzRm9jdXMoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gPz8/QVdUOiByZXR1cm4gaXNGb2N1c093bmVyKCk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSGlkZXMgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBzZXRWaXNpYmxlKGJvb2xlYW4pIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIGhpZGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCF2aXNpYmxlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJlcGFyZTRIaWVyYXJjaHlDaGFuZ2UoKTsKKyAgICAgICAgICAgIHZpc2libGUgPSBmYWxzZTsKKyAgICAgICAgICAgIG1vdmVGb2N1c09uSGlkZSgpOworICAgICAgICAgICAgYmVoYXZpb3VyLnNldFZpc2libGUoZmFsc2UpOworICAgICAgICAgICAgcG9zdEV2ZW50KG5ldyBDb21wb25lbnRFdmVudCh0aGlzLCBDb21wb25lbnRFdmVudC5DT01QT05FTlRfSElEREVOKSk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGZpbmlzaEhpZXJhcmNoeUNoYW5nZSh0aGlzLCBwYXJlbnQsIDApOworICAgICAgICAgICAgbm90aWZ5SW5wdXRNZXRob2QobnVsbCk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGludmFsaWRhdGVSZWFsUGFyZW50KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBwb2ludCB3aXRoIHRoZSBzcGVjaWZpZWQgY29vcmRpbmF0ZXMgYmVsb25ncyB0bworICAgICAqIHRoZSBDb21tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBQb2ludC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgUG9pbnQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgcG9pbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGNvb3JkaW5hdGVzIGJlbG9uZ3MgdG8gdGhlCisgICAgICogICAgICAgICBDb21tcG9uZW50LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgY29udGFpbnMoaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIGluc2lkZShpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4geCA+PSAwICYmIHggPCBnZXRXaWR0aCgpICYmIHkgPj0gMCAmJiB5IDwgZ2V0SGVpZ2h0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52YWxpZGF0ZXMgdGhlIGNvbXBvbmVudCwgdGhpcyBjb21wb25lbnQgYW5kIGFsbCBwYXJlbnRzIGFib3ZlIGl0IGFyZQorICAgICAqIG1hcmtlZCBhcyBuZWVkaW5nIHRvIGJlIGxhaWQgb3V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHJlc2V0RGVmYXVsdFNpemUoKTsKKyAgICAgICAgICAgIC8vID8/P0FXVDogaW52YWxpZGF0ZVJlYWxQYXJlbnQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIGJhY2tncm91bmQgY29sb3IgaXMgc2V0IHRvIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGJhY2tncm91bmQgY29sb3IgaXMgc2V0IHRvIHRoaXMgQ29tcG9uZW50LCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQmFja2dyb3VuZFNldCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gYmFja0NvbG9yICE9IG51bGw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IGEgY3Vyc29yIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGEgY3Vyc29yIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ3Vyc29yU2V0KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBjdXJzb3IgIT0gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhpcyBDb21wb25lbnQgaXMgZGlzcGxheWFibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIENvbXBvbmVudCBpcyBkaXNwbGF5YWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRGlzcGxheWFibGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoaXMgY29tcG9uZW50IGlzIHBhaW50ZWQgdG8gYW4gYnVmZmVyIHdoaWNoIGlzCisgICAgICogY29waWVkIHRvIHRoZSBzY3JlZW4gbGF0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIGNvbXBvbmVudCBpcyBwYWludGVkIHRvIGFuIGJ1ZmZlciB3aGljaCBpcyBjb3BpZWQKKyAgICAgKiAgICAgICAgIHRvIHRoZSBzY3JlZW4gbGF0ZXIsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RvdWJsZUJ1ZmZlcmVkKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGZhbHNlIGJ5IGRlZmF1bHQKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhpcyBDb21wb25lbnQgaXMgZW5hYmxlZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgQ29tcG9uZW50IGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGVuYWJsZWQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogIlJlY3Vyc2l2ZSIgaXNFbmFibGVkKCkuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlIGlmIG5vdCBvbmx5IGNvbXBvbmVudCBpdHNlbGYgaXMgZW5hYmxlZCBidXQgaXRzIGhlYXZ5d2VpZ2h0CisgICAgICogICAgICAgICBwYXJlbnQgaXMgYWxzbyAiaW5kaXJlY3RseSIgZW5hYmxlZC4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzSW5kaXJlY3RseUVuYWJsZWQoKSB7CisgICAgICAgIENvbXBvbmVudCBjb21wID0gdGhpczsKKyAgICAgICAgd2hpbGUgKGNvbXAgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCFjb21wLmlzTGlnaHR3ZWlnaHQoKSAmJiAhY29tcC5pc0VuYWJsZWQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vID8/P0FXVDogY29tcCA9IGNvbXAuZ2V0UmVhbFBhcmVudCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgY29tcG9uZW50IGlzIGtleSBlbmFibGVkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGNvbXBvbmVudCBpcyBlbmFibGVkIGFuZCBpbmRpcmVjdGx5IGVuYWJsZWQuCisgICAgICovCisgICAgYm9vbGVhbiBpc0tleUVuYWJsZWQoKSB7CisgICAgICAgIGlmICghaXNFbmFibGVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNJbmRpcmVjdGx5RW5hYmxlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgb25seSBwYXJlbnQgb2YgYSBjaGlsZCBjb21wb25lbnQsIGJ1dCBub3Qgb3duZXIgb2YgYSB3aW5kb3cuCisgICAgICogCisgICAgICogQHJldHVybiBwYXJlbnQgb2YgY2hpbGQgY29tcG9uZW50LCBudWxsIGlmIGNvbXBvbmVudCBpcyBhIHRvcC1sZXZlbAorICAgICAqICAgICAgICAgKFdpbmRvdyBpbnN0YW5jZSkuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBDb250YWluZXIgZ2V0UmVhbFBhcmVudCgpIHsgcmV0dXJuICghKHRoaXMgaW5zdGFuY2VvZiBXaW5kb3cpID8KKyAgICAgKiBnZXRQYXJlbnQoKSA6IG51bGwpOyB9IHB1YmxpYyBib29sZWFuIGlzRm9jdXNDeWNsZVJvb3QoQ29udGFpbmVyCisgICAgICogY29udGFpbmVyKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4gZ2V0Rm9jdXNDeWNsZVJvb3RBbmNlc3RvcigpCisgICAgICogPT0gY29udGFpbmVyOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0gcHVibGljIGJvb2xlYW4KKyAgICAgKiBpc0ZvY3VzT3duZXIoKSB7IHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4KKyAgICAgKiBLZXlib2FyZEZvY3VzTWFuYWdlci5nZXRDdXJyZW50S2V5Ym9hcmRGb2N1c01hbmFnZXIoKS5nZXRGb2N1c093bmVyKCkgPT0KKyAgICAgKiB0aGlzOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIENvbXBvbmVudCBjYW4gYmUgZm9jdXNhYmxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBDb21wb25lbnQgY2FuIGJlIGZvY3VzYWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGlzRm9jdXNhYmxlKCkuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZvY3VzVHJhdmVyc2FibGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3ZlcnJpZGVuSXNGb2N1c2FibGUgPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiBmb2N1c2FibGU7IC8vIGEgQ29tcG9uZW50IG11c3QgZWl0aGVyIGJlIGJvdGggZm9jdXNhYmxlIGFuZAorICAgICAgICAgICAgLy8gZm9jdXMgdHJhdmVyc2FibGUsIG9yIG5laXRoZXIKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBDb21wb25lbnQgY2FuIGJlIGZvY3VzYWJsZSBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIENvbXBvbmVudCBjYW4gYmUgZm9jdXNhYmxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGb2N1c2FibGUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGlzRm9jdXNUcmF2ZXJzYWJsZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgRm9udCBpcyBzZXQgZm9yIHRoaXMgQ29tcG9uZW50IG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBGb250IGlzIHNldCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRm9udFNldCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZm9udCAhPSBudWxsOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBmb3JlZ3JvdW5kIGNvbG9yIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudCBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBmb3JlZ3JvdW5kIGNvbG9yIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZvcmVncm91bmRTZXQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGZvcmVDb2xvciAhPSBudWxsOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbXBvbmVudCBoYXMgYSBsaWdodHdlaWdodCBwZWVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBjb21wb25lbnQgaGFzIGEgbGlnaHR3ZWlnaHQgcGVlciwgZmFsc2UgaWYgaXQgaGFzIGEKKyAgICAgKiAgICAgICAgIG5hdGl2ZSBwZWVyIG9yIG5vIHBlZXIuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMaWdodHdlaWdodCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gYmVoYXZpb3VyLmlzTGlnaHR3ZWlnaHQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhpcyBDb21wb25lbnQgaXMgc2hvd24uCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIENvbXBvbmVudCBpcyBzaG93biwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2hvd2luZygpIHsKKyAgICAgICAgLy8gPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4gKGlzVmlzaWJsZSgpICYmIGlzRGlzcGxheWFibGUoKSAmJgorICAgICAgICAgKiAocGFyZW50ICE9IG51bGwpICYmIHBhcmVudC5pc1Nob3dpbmcoKSk7IH0gZmluYWxseSB7CisgICAgICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0KKyAgICAgICAgICovCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhpcyBDb21wb25lbnQgaXMgdmlzaWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBDb21wb25lbnQgaXMgdmlzaWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVmlzaWJsZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdmlzaWJsZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBwcm9jZXNzS2V5RXZlbnQoS2V5RXZlbnQpIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZ0CisgICAgICogICAgICAgICAgICB0aGUgRXZlbnQuCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBjb2RlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSByZXBsYWNlZCBieSBwcm9jZXNzS2V5RXZlbnQoS2V5RXZlbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIGtleURvd24oRXZlbnQgZXZ0LCBpbnQga2V5KSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW46IGRvIG5vdGhpbmcsCisgICAgICAgIC8vIGp1c3QgcmV0dXJuIGZhbHNlIHRvIHByb3BhZ2F0ZSBldmVudCB1cCB0byB0aGUgcGFyZW50IGNvbnRhaW5lcgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVwcmVjYXRlZDogcmVwbGFjZWQgYnkgcHJvY2Vzc0tleUV2ZW50KEtleUV2ZW50KSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIGV2dAorICAgICAqICAgICAgICAgICAgdGhlIEV2ZW50LgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY29kZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgcHJvY2Vzc0tleUV2ZW50KEtleUV2ZW50KSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBrZXlVcChFdmVudCBldnQsIGludCBrZXkpIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbjogZG8gbm90aGluZywKKyAgICAgICAgLy8ganVzdCByZXR1cm4gZmFsc2UgdG8gcHJvcGFnYXRlIGV2ZW50IHVwIHRvIHRoZSBwYXJlbnQgY29udGFpbmVyCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiBSZXBsYWNlZCBieSBkb0xheW91dCgpIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBkb0xheW91dCgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIGxheW91dCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBJbXBsZW1lbnRlZCBpbiBDb250YWluZXIKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBnZXRDb21wb25lbnRBdChpbnQsIGludCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAqIEByZXR1cm4gVGhlIGNvbXBvbmVudC4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBnZXRDb21wb25lbnRBdChpbnQsIGludCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIENvbXBvbmVudCBsb2NhdGUoaW50IHgsIGludCB5KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNvbnRhaW5zKHgsIHkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBwcm9jZXNzRm9jdXNFdmVudChGb2N1c0V2ZW50KS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZ0CisgICAgICogICAgICAgICAgICB0aGUgRXZlbnQuCisgICAgICogQHBhcmFtIHdoYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHByb2Nlc3NGb2N1c0V2ZW50KEZvY3VzRXZlbnQpLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gbG9zdEZvY3VzKEV2ZW50IGV2dCwgT2JqZWN0IHdoYXQpIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbjogZG8gbm90aGluZywKKyAgICAgICAgLy8ganVzdCByZXR1cm4gZmFsc2UgdG8gcHJvcGFnYXRlIGV2ZW50IHVwIHRvIHRoZSBwYXJlbnQgY29udGFpbmVyCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXByZWNhdGVkOiByZXBsYWNlZCBieSBwcm9jZXNzTW91c2VFdmVudChNb3VzZUV2ZW50KSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIGV2dAorICAgICAqICAgICAgICAgICAgdGhlIE1vdXNlRXZlbnQuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHByb2Nlc3NNb3VzZUV2ZW50KE1vdXNlRXZlbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIG1vdXNlRG93bihFdmVudCBldnQsIGludCB4LCBpbnQgeSkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuOiBkbyBub3RoaW5nLAorICAgICAgICAvLyBqdXN0IHJldHVybiBmYWxzZSB0byBwcm9wYWdhdGUgZXZlbnQgdXAgdG8gdGhlIHBhcmVudCBjb250YWluZXIKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQ6IHJlcGxhY2VkIGJ5IGdldE1pbmltdW1TaXplKCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBldnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgZ2V0TWluaW11bVNpemUoKSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBtb3VzZURyYWcoRXZlbnQgZXZ0LCBpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbjogZG8gbm90aGluZywKKyAgICAgICAgLy8ganVzdCByZXR1cm4gZmFsc2UgdG8gcHJvcGFnYXRlIGV2ZW50IHVwIHRvIHRoZSBwYXJlbnQgY29udGFpbmVyCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlZCBieSBwcm9jZXNzTW91c2VFdmVudChNb3VzZUV2ZW50KSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIGV2dAorICAgICAqICAgICAgICAgICAgdGhlIEV2ZW50LgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKiBAZGVwcmVjYXRlZCByZXBsYWNlZCBieSBwcm9jZXNzTW91c2VFdmVudChNb3VzZUV2ZW50KSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgYm9vbGVhbiBtb3VzZUVudGVyKEV2ZW50IGV2dCwgaW50IHgsIGludCB5KSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW46IGRvIG5vdGhpbmcsCisgICAgICAgIC8vIGp1c3QgcmV0dXJuIGZhbHNlIHRvIHByb3BhZ2F0ZSBldmVudCB1cCB0byB0aGUgcGFyZW50IGNvbnRhaW5lcgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZWQgYnkgcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBldnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gbW91c2VFeGl0KEV2ZW50IGV2dCwgaW50IHgsIGludCB5KSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW46IGRvIG5vdGhpbmcsCisgICAgICAgIC8vIGp1c3QgcmV0dXJuIGZhbHNlIHRvIHByb3BhZ2F0ZSBldmVudCB1cCB0byB0aGUgcGFyZW50IGNvbnRhaW5lcgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZWQgYnkgcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBldnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBwcm9jZXNzTW91c2VFdmVudChNb3VzZUV2ZW50KSBtZXRob2QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gbW91c2VNb3ZlKEV2ZW50IGV2dCwgaW50IHgsIGludCB5KSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW46IGRvIG5vdGhpbmcsCisgICAgICAgIC8vIGp1c3QgcmV0dXJuIGZhbHNlIHRvIHByb3BhZ2F0ZSBldmVudCB1cCB0byB0aGUgcGFyZW50IGNvbnRhaW5lcgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZWQgYnkgcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBldnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gbW91c2VVcChFdmVudCBldnQsIGludCB4LCBpbnQgeSkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuOiBkbyBub3RoaW5nLAorICAgICAgICAvLyBqdXN0IHJldHVybiBmYWxzZSB0byBwcm9wYWdhdGUgZXZlbnQgdXAgdG8gdGhlIHBhcmVudCBjb250YWluZXIKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQ6IHJlcGxhY2VkIGJ5IHNldExvY2F0aW9uKGludCwgaW50KSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGVzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlcy4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBzZXRMb2NhdGlvbihpbnQsIGludCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgbW92ZShpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3VuZHNNYXNrUGFyYW0gPSBOYXRpdmVXaW5kb3cuQk9VTkRTX05PU0laRTsKKyAgICAgICAgICAgIHNldEJvdW5kcyh4LCB5LCB3LCBoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIEBEZXByZWNhdGVkIHB1YmxpYyB2b2lkIG5leHRGb2N1cygpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7CisgICAgICogdHJhbnNmZXJGb2N1cyhLZXlib2FyZEZvY3VzTWFuYWdlci5GT1JXQVJEX1RSQVZFUlNBTF9LRVlTKTsgfSBmaW5hbGx5IHsKKyAgICAgKiB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbXBvbmVudCdzIHN0YXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29tcG9uZW50J3Mgc3RhdGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciB3aGljaCBjYW4gYmUgcmV2ZWFsZWQgYnkKKyAgICAgICAgICogdGhlIGZvbGxvd2luZyBjb2RlOiBDb21wb25lbnQgYyA9IG5ldyBDb21wb25lbnQoKXt9OworICAgICAgICAgKiBjLnNldFZpc2libGUoZmFsc2UpOyBTeXN0ZW0ub3V0LnByaW50bG4oYyk7CisgICAgICAgICAqLworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXROYW1lKCkgKyAiLCIgKyBnZXRYKCkgKyAiLCIgKyBnZXRZKCkgKyAiLCIgKyBnZXRXaWR0aCgpICsgIngiIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQKKyAgICAgICAgICAgICAgICAgICAgKyBnZXRIZWlnaHQoKSArICghaXNWaXNpYmxlKCkgPyAiLGhpZGRlbiIgOiAiIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBEZXByZWNhdGVkCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgYm9vbGVhbiBwb3N0RXZlbnQoRXZlbnQgZXZ0KSB7CisgICAgICAgIGJvb2xlYW4gaGFuZGxlZCA9IGhhbmRsZUV2ZW50KGV2dCk7CisgICAgICAgIGlmIChoYW5kbGVkKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgICogLy8gcHJvcGFnYXRlIG5vbi1oYW5kbGVkIGV2ZW50cyB1cCB0byBwYXJlbnQgQ29tcG9uZW50IHBhciA9IHBhcmVudDsKKyAgICAgICAgICogLy8gdHJ5IHRvIGNhbGwgcG9zdEV2ZW50IG9ubHkgb24gY29tcG9uZW50cyB3aGljaCAvLyBvdmVycmlkZSBhbnkgb2YKKyAgICAgICAgICogZGVwcmVjYXRlZCBtZXRob2QgaGFuZGxlcnMgLy8gd2hpbGUgKHBhciAhPSBudWxsICYmCisgICAgICAgICAqICFwYXIuZGVwcmVjYXRlZEV2ZW50SGFuZGxlcikgeyAvLyBwYXIgPSBwYXIucGFyZW50OyAvLyB9IC8vIHRyYW5zbGF0ZQorICAgICAgICAgKiBldmVudCBjb29yZGluYXRlcyBiZWZvcmUgcG9zdGluZyBpdCB0byBwYXJlbnQgaWYgKHBhciAhPSBudWxsKSB7CisgICAgICAgICAqIGV2dC50cmFuc2xhdGUoeCwgeSk7IHBhci5wb3N0RXZlbnQoZXZ0KTsgfQorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXBhcmVzIGFuIGltYWdlIGZvciByZW5kZXJpbmcgb24gdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZSB0byBiZSBwcmVwYXJlZC4KKyAgICAgKiBAcGFyYW0gb2JzZXJ2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZU9ic2VydmVyIG9iamVjdCB0byBiZSBub3RpZmllZCBhcyBzb29uIGFzIHRoZSBpbWFnZQorICAgICAqICAgICAgICAgICAgaXMgcHJlcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbWFnZSBoYXMgYmVlbiBmdWxseSBwcmVwYXJlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHByZXBhcmVJbWFnZShJbWFnZSBpbWFnZSwgSW1hZ2VPYnNlcnZlciBvYnNlcnZlcikgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiB0b29sa2l0LnByZXBhcmVJbWFnZShpbWFnZSwgLTEsIC0xLCBvYnNlcnZlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZXMgYW4gaW1hZ2UgZm9yIHJlbmRlcmluZyBvbiB0aGUgQ29tcG9uZW50IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHdpZHRoLCBoZWlnaHQsIGFuZCBJbWFnZU9ic2VydmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlIHRvIGJlIHByZXBhcmVkLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHNjYWxlZCBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHNjYWxlZCBoZWlnaHQuCisgICAgICogQHBhcmFtIG9ic2VydmVyCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VPYnNlcnZlciBvYmplY3QgdG8gYmUgbm90aWZpZWQgYXMgc29vbiBhcyB0aGUgaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIGlzIHByZXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgaW1hZ2UgaXMgYmVlbiBmdWxseSBwcmVwYXJlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHByZXBhcmVJbWFnZShJbWFnZSBpbWFnZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBJbWFnZU9ic2VydmVyIG9ic2VydmVyKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHRvb2xraXQucHJlcGFyZUltYWdlKGltYWdlLCB3aWR0aCwgaGVpZ2h0LCBvYnNlcnZlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFrZXMgdGhpcyBDb21wb25lbnQgdW5kaXNwbGF5YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVOb3RpZnkoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgKGRyb3BUYXJnZXQgIT0gbnVsbCkgeyBkcm9wVGFyZ2V0LnJlbW92ZU5vdGlmeShwZWVyKTsgfQorICAgICAgICAgICAgICovCisgICAgICAgICAgICBwcmVwYXJlNEhpZXJhcmNoeUNoYW5nZSgpOworICAgICAgICAgICAgLy8gLz8/P0FXVDogbW92ZUZvY3VzKCk7CisgICAgICAgICAgICBiZWhhdmlvdXIucmVtb3ZlTm90aWZ5KCk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGZpbmlzaEhpZXJhcmNoeUNoYW5nZSh0aGlzLCBwYXJlbnQsIDApOworICAgICAgICAgICAgcmVtb3ZlTm90aWZ5SW5wdXRDb250ZXh0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgSW5wdXRDb250ZXh0LnJlbW92ZU5vdGlmeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVtb3ZlTm90aWZ5SW5wdXRDb250ZXh0KCkgeworICAgICAgICBpZiAoIWlucHV0TWV0aG9kc0VuYWJsZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBJbnB1dENvbnRleHQgaWMgPSBnZXRJbnB1dENvbnRleHQoKTsKKyAgICAgICAgaWYgKGljICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vID8/P0FXVDogaWMucmVtb3ZlTm90aWZ5KHRoaXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gc29tZSBwcm9wZXJ0eSBvZiBhIGNvbXBvbmVudCBjaGFuZ2VzLCBtYWtpbmcKKyAgICAgKiBpdCB1bmZvY3VzYWJsZSwgZS4gZy4gaGlkZSgpLCByZW1vdmVOb3RpZnkoKSwgc2V0RW5hYmxlZChmYWxzZSksCisgICAgICogc2V0Rm9jdXNhYmxlKGZhbHNlKSBpcyBjYWxsZWQsIGFuZCB0aGVyZWZvcmUgYXV0b21hdGljIGZvcndhcmQgZm9jdXMKKyAgICAgKiB0cmF2ZXJzYWwgaXMgbmVjZXNzYXJ5CisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiB2b2lkIG1vdmVGb2N1cygpIHsgLy8gZG9uJ3QgdXNlIHRyYW5zZmVyRm9jdXMoKSwgYnV0IHF1ZXJ5IGZvY3VzCisgICAgICogdHJhdmVyc2FsIHBvbGljeSBkaXJlY3RseSAvLyBhbmQgaWYgaXQgcmV0dXJucyBudWxsLCB0cmFuc2ZlciBmb2N1cyB1cAorICAgICAqIGN5Y2xlIC8vIGFuZCBmaW5kIG5leHQgZm9jdXNhYmxlIGNvbXBvbmVudCB0aGVyZSBLZXlib2FyZEZvY3VzTWFuYWdlciBrZm0KKyAgICAgKiA9IEtleWJvYXJkRm9jdXNNYW5hZ2VyLmdldEN1cnJlbnRLZXlib2FyZEZvY3VzTWFuYWdlcigpOyBDb250YWluZXIgcm9vdCA9CisgICAgICoga2ZtLmdldEN1cnJlbnRGb2N1c0N5Y2xlUm9vdCgpOyBDb21wb25lbnQgbmV4dENvbXAgPSB0aGlzOyBib29sZWFuCisgICAgICogc3VjY2VzcyA9ICFpc0ZvY3VzT3duZXIoKTsgd2hpbGUgKCFzdWNjZXNzKSB7IGlmIChyb290ICE9CisgICAgICogbmV4dENvbXAuZ2V0Rm9jdXNDeWNsZVJvb3RBbmNlc3RvcigpKSB7IC8vIGNvbXBvbmVudCB3YXMgcHJvYmFibHkgcmVtb3ZlZAorICAgICAqIGZyb20gY29udGFpbmVyIC8vIHNvIGZvY3VzIHdpbGwgYmUgbG9zdCBpbiBzb21lIHRpbWUgcmV0dXJuOyB9IG5leHRDb21wID0KKyAgICAgKiByb290LmdldEZvY3VzVHJhdmVyc2FsUG9saWN5KCkuZ2V0Q29tcG9uZW50QWZ0ZXIocm9vdCwgbmV4dENvbXApOyBpZgorICAgICAqIChuZXh0Q29tcCA9PSB0aGlzKSB7IG5leHRDb21wID0gbnVsbDsgLy8gYXZvaWQgbG9vcGluZyB9IGlmIChuZXh0Q29tcCAhPQorICAgICAqIG51bGwpIHsgc3VjY2VzcyA9IG5leHRDb21wLnJlcXVlc3RGb2N1c0luV2luZG93KCk7IH0gZWxzZSB7IG5leHRDb21wID0KKyAgICAgKiByb290OyByb290ID0gcm9vdC5nZXRGb2N1c0N5Y2xlUm9vdEFuY2VzdG9yKCk7IC8vIGlmIG5vIGFjY2VwdGFibGUKKyAgICAgKiBjb21wb25lbnQgaXMgZm91bmQgYXQgYWxsIC0gY2xlYXIgZ2xvYmFsIC8vIGZvY3VzIG93bmVyIGlmIChyb290ID09IG51bGwpCisgICAgICogeyBpZiAobmV4dENvbXAgaW5zdGFuY2VvZiBXaW5kb3cpIHsgV2luZG93IHduZCA9IChXaW5kb3cpIG5leHRDb21wOworICAgICAqIHduZC5zZXRGb2N1c093bmVyKG51bGwpOyB3bmQuc2V0UmVxdWVzdGVkRm9jdXMobnVsbCk7IH0KKyAgICAgKiBrZm0uY2xlYXJHbG9iYWxGb2N1c093bmVyKCk7IHJldHVybjsgfSB9IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogRm9yIENvbnRhaW5lciB0aGVyZSdzIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIG1vdmluZyBmb2N1cyB3aGVuIGJlaW5nIG1hZGUKKyAgICAgKiBpbnZpc2libGUgb3IgbWFkZSB1bmZvY3VzYWJsZSBpbiBzb21lIG90aGVyIHdheSwgYmVjYXVzZSB3aGVuIGNvbnRhaW5lcgorICAgICAqIGlzIG1hZGUgaW52aXNpYmxlLCBjb21wb25lbnQgc3RpbGwgcmVtYWlucyB2aXNpYmxlLCBpLiBlLiBpdHMgaGlkZSgpIG9yCisgICAgICogc2V0VmlzaWJsZSgpIGlzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgdm9pZCBtb3ZlRm9jdXNPbkhpZGUoKSB7CisgICAgICAgIC8vID8/P0FXVDogbW92ZUZvY3VzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgcHJvcGVydHkgY2hhbmdlIGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGdldFByb3BlcnR5Q2hhbmdlU3VwcG9ydCgpLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHByb3BlcnR5IGNoYW5nZSBsaXN0ZW5lciByZWdpc3RlcmVkIGZvdCB0aGlzIGNvbXBvbmVudCBmb3IKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoU3RyaW5nIHByb3BlcnR5TmFtZSwgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICBnZXRQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoKS5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKHByb3BlcnR5TmFtZSwgbGlzdGVuZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGFpbnRzIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIG9mIHRoaXMgY29tcG9uZW50IHdpdGhpbiB0bQorICAgICAqIG1pbGxpc2Vjb25kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdG0KKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdXBkYXRpbmcuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgUmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIFJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBSZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBSZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVwYWludChsb25nIHRtLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgICogdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7IGlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwIHx8CisgICAgICAgICAqIChyZWRyYXdNYW5hZ2VyID09IG51bGwpIHx8ICFpc1Nob3dpbmcoKSkgeyByZXR1cm47IH0gaWYgKGJlaGF2aW91cgorICAgICAgICAgKiBpbnN0YW5jZW9mIExXQmVoYXZpb3IpIHsgaWYgKHBhcmVudCA9PSBudWxsIHx8ICFwYXJlbnQudmlzaWJsZSB8fAorICAgICAgICAgKiAhcGFyZW50LmJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCkpIHsgcmV0dXJuOyB9IGlmIChyZXBhaW50UmVnaW9uID09CisgICAgICAgICAqIG51bGwpIHsgcmVwYWludFJlZ2lvbiA9IG5ldyBNdWx0aVJlY3RBcmVhKG5ldyBSZWN0YW5nbGUoeCwgeSwgd2lkdGgsCisgICAgICAgICAqIGhlaWdodCkpOyB9IHJlcGFpbnRSZWdpb24uaW50ZXJzZWN0KG5ldyBSZWN0YW5nbGUoMCwgMCwgdGhpcy53LAorICAgICAgICAgKiB0aGlzLmgpKTsgcmVwYWludFJlZ2lvbi50cmFuc2xhdGUodGhpcy54LCB0aGlzLnkpOworICAgICAgICAgKiBwYXJlbnQucmVwYWludFJlZ2lvbiA9IHJlcGFpbnRSZWdpb247IHJlcGFpbnRSZWdpb24gPSBudWxsOworICAgICAgICAgKiBwYXJlbnQucmVwYWludCh0bSwgeCArIHRoaXMueCwgeSArIHRoaXMueSwgd2lkdGgsIGhlaWdodCk7IH0gZWxzZSB7CisgICAgICAgICAqIGlmIChyZXBhaW50UmVnaW9uICE9IG51bGwpIHsgcmVkcmF3TWFuYWdlci5hZGRVcGRhdGVSZWdpb24odGhpcywKKyAgICAgICAgICogcmVwYWludFJlZ2lvbik7IHJlcGFpbnRSZWdpb24gPSBudWxsOyB9IGVsc2UgeworICAgICAgICAgKiByZWRyYXdNYW5hZ2VyLmFkZFVwZGF0ZVJlZ2lvbih0aGlzLCBuZXcgUmVjdGFuZ2xlKHgsIHksIHdpZHRoLAorICAgICAgICAgKiBoZWlnaHQpKTsgfQorICAgICAgICAgKiB0b29sa2l0LmdldFN5c3RlbUV2ZW50UXVldWVDb3JlKCkubm90aWZ5RXZlbnRNb25pdG9yKHRvb2xraXQpOyB9IH0KKyAgICAgICAgICogZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0KKyAgICAgICAgICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUG9zdCBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUuCisgICAgICovCisgICAgdm9pZCBwb3N0RXZlbnQoQVdURXZlbnQgZSkgeworICAgICAgICBnZXRUb29sa2l0KCkuZ2V0U3lzdGVtRXZlbnRRdWV1ZUltcGwoKS5wb3N0RXZlbnQoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwYWludHMgdGhlIHNwZWNpZmllZCBSZWN0YW5nbGUgb2YgdGhpcyBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgUmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIFJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBSZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBSZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVwYWludChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcGFpbnQoMCwgeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwYWludHMgdGhpcyBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVwYWludCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAodyA+IDAgJiYgaCA+IDApIHsKKyAgICAgICAgICAgICAgICByZXBhaW50KDAsIDAsIDAsIHcsIGgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGFpbnRzIHRoZSBjb21wb25lbnQgd2l0aGluIHRtIG1pbGxpc2Vjb25kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdG0KKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdXBkYXRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVwYWludChsb25nIHRtKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVwYWludCh0bSwgMCwgMCwgdywgaCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVxdWVzdHMgdGhhdCB0aGlzIENvbXBvbmVudCBnZXQgdGhlIGlucHV0IGZvY3VzIHRlbXBvcmFyaWx5LiBUaGlzCisgICAgICogY29tcG9uZW50IG11c3QgYmUgZGlzcGxheWFibGUsIHZpc2libGUsIGFuZCBmb2N1c2FibGUuCisgICAgICogCisgICAgICogQHBhcmFtIHRlbXBvcmFyeQorICAgICAqICAgICAgICAgICAgdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSBpZiB0aGUgZm9jdXMgY2hhbmdlIGlzIHRlbXBvcmFyeSwgd2hlbgorICAgICAqICAgICAgICAgICAgdGhlIHdpbmRvdyBsb3NlcyB0aGUgZm9jdXMuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmb2N1cyBjaGFuZ2UgcmVxdWVzdCBpcyBzdWNjZWVkZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiByZXF1ZXN0Rm9jdXMoYm9vbGVhbiB0ZW1wb3JhcnkpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IHJldHVybiByZXF1ZXN0Rm9jdXNJbXBsKHRlbXBvcmFyeSwgdHJ1ZSwgZmFsc2UpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICAvLyA/Pz9BV1QKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcXVlc3RzIHRoYXQgdGhpcyBDb21wb25lbnQgZ2V0IHRoZSBpbnB1dCBmb2N1cy4gVGhpcyBjb21wb25lbnQgbXVzdCBiZQorICAgICAqIGRpc3BsYXlhYmxlLCB2aXNpYmxlLCBhbmQgZm9jdXNhYmxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlcXVlc3RGb2N1cygpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXF1ZXN0Rm9jdXMoZmFsc2UpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHJvdGVjdGVkIGJvb2xlYW4gcmVxdWVzdEZvY3VzSW5XaW5kb3coYm9vbGVhbiB0ZW1wb3JhcnkpIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgV2luZG93IHduZCA9IGdldFdpbmRvd0FuY2VzdG9yKCk7IGlmICgod25kID09CisgICAgICogbnVsbCkgfHwgIXduZC5pc0ZvY3VzZWQoKSkgeyByZXR1cm4gZmFsc2U7IH0gcmV0dXJuCisgICAgICogcmVxdWVzdEZvY3VzSW1wbCh0ZW1wb3JhcnksIGZhbHNlLCBmYWxzZSk7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IGJvb2xlYW4gcmVxdWVzdEZvY3VzSW1wbChib29sZWFuIHRlbXBvcmFyeSwKKyAgICAgKiBib29sZWFuIGNyb3NzV2luZG93LCBib29sZWFuIHJlamVjdGlvblJlY292ZXJ5KSB7IGlmICghcmVqZWN0aW9uUmVjb3ZlcnkKKyAgICAgKiAmJiBpc0ZvY3VzT3duZXIoKSkgeyByZXR1cm4gdHJ1ZTsgfSBXaW5kb3cgd25kID0gZ2V0V2luZG93QW5jZXN0b3IoKTsKKyAgICAgKiBDb250YWluZXIgcGFyID0gZ2V0UmVhbFBhcmVudCgpOyBpZiAoKHBhciAhPSBudWxsKSAmJiBwYXIuaXNSZW1vdmVkKSB7CisgICAgICogcmV0dXJuIGZhbHNlOyB9IGlmICghaXNTaG93aW5nKCkgfHwgIWlzRm9jdXNhYmxlKCkgfHwKKyAgICAgKiAhd25kLmlzRm9jdXNhYmxlV2luZG93KCkpIHsgcmV0dXJuIGZhbHNlOyB9IHJldHVybgorICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLmdldEN1cnJlbnRLZXlib2FyZEZvY3VzTWFuYWdlcigpLnJlcXVlc3RGb2N1cyh0aGlzLAorICAgICAqIHRlbXBvcmFyeSwgY3Jvc3NXaW5kb3csIHRydWUpOyB9IHB1YmxpYyBib29sZWFuIHJlcXVlc3RGb2N1c0luV2luZG93KCkgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyByZXR1cm4gcmVxdWVzdEZvY3VzSW5XaW5kb3coZmFsc2UpOyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogRGVwcmVjYXRlZDogcmVwbGFjZWQgYnkgc2V0Qm91bmRzKGludCwgaW50LCBpbnQsIGludCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGguCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgc2V0Qm91bmRzKGludCwgaW50LCBpbnQsIGludCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgcmVzaGFwZShpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldEJvdW5kcyh4LCB5LCB3LCBoLCBib3VuZHNNYXNrUGFyYW0sIHRydWUpOworICAgICAgICAgICAgYm91bmRzTWFza1BhcmFtID0gMDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHJlY3RhbmdsZSBmb3IgdGhpcyBDb21wb25lbnQgdG8gYmUgdGhlIHJlY3RhbmdsZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB4LHkgY29vcmRpbmF0ZXMgb2YgdGhlIHRvcC1sZWZ0IGNvcm5lciBhbmQgdGhlIHdpZHRoIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHRvcC1sZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wLWxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCb3VuZHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXNoYXBlKHgsIHksIHcsIGgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgcmVjdGFuZ2xlIGZvciB0aGlzIENvbXBvbmVudCB0byBiZSB0aGUgcmVjdGFuZ2xlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHgseSBjb29yZGluYXRlcyBvZiB0aGUgdG9wLWxlZnQgY29ybmVyIGFuZCB0aGUgd2lkdGggYW5kIGhlaWdodCBhbmQgcG9zdHMKKyAgICAgKiB0aGUgYXBwcm9wcmlhdGUgZXZlbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AtbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHRvcC1sZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGJNYXNrCisgICAgICogICAgICAgICAgICB0aGUgYml0bWFzayBvZiBib3VuZHMgb3B0aW9ucy4KKyAgICAgKiBAcGFyYW0gdXBkYXRlQmVoYXZpb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aGV0aGVyIHRvIHVwZGF0ZSB0aGUgYmVoYXZvaXIncyBib3VuZHMgYXMgd2VsbC4KKyAgICAgKi8KKyAgICB2b2lkIHNldEJvdW5kcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGJNYXNrLCBib29sZWFuIHVwZGF0ZUJlaGF2aW9yKSB7CisgICAgICAgIGludCBvbGRYID0gdGhpcy54OworICAgICAgICBpbnQgb2xkWSA9IHRoaXMueTsKKyAgICAgICAgaW50IG9sZFcgPSB0aGlzLnc7CisgICAgICAgIGludCBvbGRIID0gdGhpcy5oOworICAgICAgICBzZXRCb3VuZHNGaWVsZHMoeCwgeSwgdywgaCwgYk1hc2spOworICAgICAgICAvLyBNb3ZlZAorICAgICAgICBpZiAoKG9sZFggIT0gdGhpcy54KSB8fCAob2xkWSAhPSB0aGlzLnkpKSB7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGludmFsaWRhdGVSZWFsUGFyZW50KCk7CisgICAgICAgICAgICBwb3N0RXZlbnQobmV3IENvbXBvbmVudEV2ZW50KHRoaXMsIENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9NT1ZFRCkpOworICAgICAgICAgICAgc3ByZWFkSGllcmFyY2h5Qm91bmRzRXZlbnRzKHRoaXMsIEhpZXJhcmNoeUV2ZW50LkFOQ0VTVE9SX01PVkVEKTsKKyAgICAgICAgfQorICAgICAgICAvLyBSZXNpemVkCisgICAgICAgIGlmICgob2xkVyAhPSB0aGlzLncpIHx8IChvbGRIICE9IHRoaXMuaCkpIHsKKyAgICAgICAgICAgIGludmFsaWRhdGUoKTsKKyAgICAgICAgICAgIHBvc3RFdmVudChuZXcgQ29tcG9uZW50RXZlbnQodGhpcywgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX1JFU0laRUQpKTsKKyAgICAgICAgICAgIHNwcmVhZEhpZXJhcmNoeUJvdW5kc0V2ZW50cyh0aGlzLCBIaWVyYXJjaHlFdmVudC5BTkNFU1RPUl9SRVNJWkVEKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodXBkYXRlQmVoYXZpb3IpIHsKKyAgICAgICAgICAgIGJlaGF2aW91ci5zZXRCb3VuZHModGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oLCBiTWFzayk7CisgICAgICAgIH0KKyAgICAgICAgbm90aWZ5SW5wdXRNZXRob2QobmV3IFJlY3RhbmdsZSh4LCB5LCB3LCBoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgSW5wdXRDb250ZXh0SW1wbC5ub3RpZnlDbGllbnRXaW5kb3dDaGFuZ2VkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBib3VuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBib3VuZHMuCisgICAgICovCisgICAgdm9pZCBub3RpZnlJbnB1dE1ldGhvZChSZWN0YW5nbGUgYm91bmRzKSB7CisgICAgICAgIC8vIG9ubHkgV2luZG93IGFjdHVhbGx5IG5vdGlmaWVzIElNIG9mIGJvdW5kcyBjaGFuZ2UKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBib3VuZHMgZmllbGRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3LgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaC4KKyAgICAgKiBAcGFyYW0gYk1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiIG1hc2suCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEJvdW5kc0ZpZWxkcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGJNYXNrKSB7CisgICAgICAgIGlmICgoYk1hc2sgJiBOYXRpdmVXaW5kb3cuQk9VTkRTX05PU0laRSkgPT0gMCkgeworICAgICAgICAgICAgdGhpcy53ID0gdzsKKyAgICAgICAgICAgIHRoaXMuaCA9IGg7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChiTWFzayAmIE5hdGl2ZVdpbmRvdy5CT1VORFNfTk9NT1ZFKSA9PSAwKSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hdGl2ZSBpbnNldHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbmF0aXZlIGluc2V0cy4KKyAgICAgKi8KKyAgICBJbnNldHMgZ2V0TmF0aXZlSW5zZXRzKCkgeworICAgICAgICByZXR1cm4gbmV3IEluc2V0cygwLCAwLCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbnNldHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW5zZXRzLgorICAgICAqLworICAgIEluc2V0cyBnZXRJbnNldHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgSW5zZXRzKDAsIDAsIDAsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBpcyBtb3VzZSBleGl0ZWQgZXhwZWN0ZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBtb3VzZSBleGl0ZWQgZXhwZWN0ZWQuCisgICAgICovCisgICAgYm9vbGVhbiBpc01vdXNlRXhpdGVkRXhwZWN0ZWQoKSB7CisgICAgICAgIHJldHVybiBtb3VzZUV4aXRlZEV4cGVjdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1vdXNlIGV4aXRlZCBleHBlY3RlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbW91c2UgZXhpdGVkIGV4cGVjdGVkLgorICAgICAqLworICAgIHZvaWQgc2V0TW91c2VFeGl0ZWRFeHBlY3RlZChib29sZWFuIGV4cGVjdGVkKSB7CisgICAgICAgIG1vdXNlRXhpdGVkRXhwZWN0ZWQgPSBleHBlY3RlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuZXcgYm91bmRpbmcgcmVjdGFuZ2xlIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Qm91bmRzKFJlY3RhbmdsZSByKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0Qm91bmRzKHIueCwgci55LCByLndpZHRoLCByLmhlaWdodCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcG9uZW50IG9yaWVudGF0aW9uIHdoaWNoIGFmZmVjdHMgdGhlIGNvbXBvbmVudCdzIGVsZW1lbnRzIGFuZAorICAgICAqIHRleHQgd2l0aGluIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgQ29tcG9uZW50T3JpZW50YXRpb24gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbXBvbmVudE9yaWVudGF0aW9uKENvbXBvbmVudE9yaWVudGF0aW9uIG8pIHsKKyAgICAgICAgQ29tcG9uZW50T3JpZW50YXRpb24gb2xkT3JpZW50YXRpb247CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkT3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjsKKyAgICAgICAgICAgIG9yaWVudGF0aW9uID0gbzsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICAgICAgZmlyZVByb3BlcnR5Q2hhbmdlKCJjb21wb25lbnRPcmllbnRhdGlvbiIsIG9sZE9yaWVudGF0aW9uLCBvcmllbnRhdGlvbik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaW52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCBjdXJzb3IgZm9yIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjdXJzb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgQ3Vyc29yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEN1cnNvcihDdXJzb3IgY3Vyc29yKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhpcy5jdXJzb3IgPSBjdXJzb3I7CisgICAgICAgICAgICBzZXRDdXJzb3IoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgY3VycmVudCBjdXJzb3Igc2hhcGUgdG8gQ29tcG9uZW50J3MgQ3Vyc29yLgorICAgICAqLworICAgIHZvaWQgc2V0Q3Vyc29yKCkgeworICAgICAgICBpZiAoaXNEaXNwbGF5YWJsZSgpICYmIGlzU2hvd2luZygpKSB7CisgICAgICAgICAgICBSZWN0YW5nbGUgYWJzUmVjdCA9IG5ldyBSZWN0YW5nbGUoZ2V0TG9jYXRpb25PblNjcmVlbigpLCBnZXRTaXplKCkpOworICAgICAgICAgICAgUG9pbnQgYWJzUG9pbnRlclBvcyA9IHRvb2xraXQuZGlzcGF0Y2hlci5tb3VzZURpc3BhdGNoZXIuZ2V0UG9pbnRlclBvcygpOworICAgICAgICAgICAgLy8gPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgKGFic1JlY3QuY29udGFpbnMoYWJzUG9pbnRlclBvcykpIHsgLy8gc2V0IEN1cnNvciBvbmx5IG9uCisgICAgICAgICAgICAgKiB0b3AtbGV2ZWwgV2luZG93cyhvbiBYMTEpIFdpbmRvdyB0b3BMZXZlbFduZCA9CisgICAgICAgICAgICAgKiBnZXRXaW5kb3dBbmNlc3RvcigpOyBpZiAodG9wTGV2ZWxXbmQgIT0gbnVsbCkgeyBQb2ludCBwb2ludGVyUG9zCisgICAgICAgICAgICAgKiA9IE1vdXNlRGlzcGF0Y2hlci5jb252ZXJ0UG9pbnQobnVsbCwgYWJzUG9pbnRlclBvcywgdG9wTGV2ZWxXbmQpOworICAgICAgICAgICAgICogQ29tcG9uZW50IGNvbXBVbmRlckN1cnNvciA9CisgICAgICAgICAgICAgKiB0b3BMZXZlbFduZC5maW5kQ29tcG9uZW50QXQocG9pbnRlclBvcyk7IC8vIGlmIChjb21wVW5kZXJDdXJzb3IKKyAgICAgICAgICAgICAqID09IHRoaXMgfHwgLy8gY29tcFVuZGVyQ3Vyc29yLmdldEN1cnNvckFuY2VzdG9yKCkgPT0gdGhpcykgeworICAgICAgICAgICAgICogTmF0aXZlV2luZG93IHduZCA9IHRvcExldmVsV25kLmdldE5hdGl2ZVdpbmRvdygpOyBpZgorICAgICAgICAgICAgICogKGNvbXBVbmRlckN1cnNvciAhPSBudWxsICYmIHduZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgKiBjb21wVW5kZXJDdXJzb3IuZ2V0UmVhbEN1cnNvcigpLmdldE5hdGl2ZUN1cnNvcigpCisgICAgICAgICAgICAgKiAuc2V0Q3Vyc29yKHduZC5nZXRJZCgpKTsgfSAvLyB9IH0gfQorICAgICAgICAgICAgICovCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhbmNlc3RvciBDdXJzb3IgaWYgQ29tcG9uZW50IGlzIGRpc2FibGVkIChkaXJlY3RseSBvciB2aWEgYW4KKyAgICAgKiBhbmNlc3RvcikgZXZlbiBpZiBDdXJzb3IgaXMgZXhwbGljaXRseSBzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgYWN0dWFsIEN1cnNvciB0byBiZSBkaXNwbGF5ZWQuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBDdXJzb3IgZ2V0UmVhbEN1cnNvcigpIHsgQ29tcG9uZW50IGN1cnNvckFuY2VzdG9yID0gZ2V0Q3Vyc29yQW5jZXN0b3IoKTsKKyAgICAgKiByZXR1cm4gY3Vyc29yQW5jZXN0b3IgIT0gbnVsbCA/IGN1cnNvckFuY2VzdG9yLmdldEN1cnNvcigpIDoKKyAgICAgKiBDdXJzb3IuZ2V0RGVmYXVsdEN1cnNvcigpOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhbmNlc3RvcihvciBjb21wb25lbnQgaXRzZWxmKSB3aG9zZSBjdXJzb3IgaXMgc2V0IHdoZW4gcG9pbnRlcgorICAgICAqIGlzIGluc2lkZSBjb21wb25lbnQKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgQ3Vyc29yIHRvIGJlIGRpc3BsYXllZC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIENvbXBvbmVudCBnZXRDdXJzb3JBbmNlc3RvcigpIHsgQ29tcG9uZW50IGNvbXA7IGZvciAoY29tcCA9IHRoaXM7IGNvbXAgIT0KKyAgICAgKiBudWxsOyBjb21wID0gY29tcC5nZXRQYXJlbnQoKSkgeyBpZiAoY29tcCBpbnN0YW5jZW9mIFdpbmRvdyB8fAorICAgICAqIGNvbXAuaXNDdXJzb3JTZXQoKSAmJiBjb21wLmlzS2V5RW5hYmxlZCgpKSB7IHJldHVybiBjb21wOyB9IH0gcmV0dXJuCisgICAgICogbnVsbDsgfSBwdWJsaWMgdm9pZCBzZXREcm9wVGFyZ2V0KERyb3BUYXJnZXQgZHQpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeQorICAgICAqIHsgaWYgKGRyb3BUYXJnZXQgPT0gZHQpIHsgcmV0dXJuOyB9IERyb3BUYXJnZXQgb2xkRHJvcFRhcmdldCA9CisgICAgICogZHJvcFRhcmdldDsgZHJvcFRhcmdldCA9IGR0OyBpZiAob2xkRHJvcFRhcmdldCAhPSBudWxsKSB7IGlmCisgICAgICogKGJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCkpIHsgb2xkRHJvcFRhcmdldC5yZW1vdmVOb3RpZnkocGVlcik7IH0KKyAgICAgKiBvbGREcm9wVGFyZ2V0LnNldENvbXBvbmVudChudWxsKTsgfSBpZiAoZHQgIT0gbnVsbCkgeworICAgICAqIGR0LnNldENvbXBvbmVudCh0aGlzKTsgaWYgKGJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCkpIHsKKyAgICAgKiBkdC5hZGROb3RpZnkocGVlcik7IH0gfSB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBjb21wb25lbnQgdG8gdGhlICJlbmFibGVkIiBvciAiZGlzYWJsZWQiIHN0YXRlIGRlcGVuZGluZyBvbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYm9vbGVhbiBwYXJhbWV0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0cnVlIGlmIHRoaXMgY29tcG9uZW50IHNob3VsZCBiZSBlbmFibGVkOyBmYWxzZSBpZiB0aGlzCisgICAgICogICAgICAgICAgICBjb21wb25lbnQgc2hvdWxkIGJlIGRpc2FibGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVuYWJsZSh2YWx1ZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZW5hYmxlZCBpbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBlbmFibGVkIGltcGwuCisgICAgICovCisgICAgdm9pZCBzZXRFbmFibGVkSW1wbChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGlmIChlbmFibGVkICE9IHZhbHVlKSB7CisgICAgICAgICAgICBlbmFibGVkID0gdmFsdWU7CisgICAgICAgICAgICBzZXRDdXJzb3IoKTsKKyAgICAgICAgICAgIGlmICghZW5hYmxlZCkgeworICAgICAgICAgICAgICAgIG1vdmVGb2N1c09uSGlkZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYmVoYXZpb3VyLnNldEVuYWJsZWQodmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwcml2YXRlIHZvaWQgZmlyZUFjY2Vzc2libGVTdGF0ZUNoYW5nZShBY2Nlc3NpYmxlU3RhdGUgc3RhdGUsIGJvb2xlYW4KKyAgICAgKiB2YWx1ZSkgeyBpZiAoYmVoYXZpb3VyLmlzTGlnaHR3ZWlnaHQoKSkgeyByZXR1cm47IH0gQWNjZXNzaWJsZUNvbnRleHQgYWMKKyAgICAgKiA9IGdldEFjY2Vzc2libGVDb250ZXh0KCk7IGlmIChhYyAhPSBudWxsKSB7IEFjY2Vzc2libGVTdGF0ZSBvbGRWYWx1ZSA9CisgICAgICogbnVsbDsgQWNjZXNzaWJsZVN0YXRlIG5ld1ZhbHVlID0gbnVsbDsgaWYgKHZhbHVlKSB7IG5ld1ZhbHVlID0gc3RhdGU7IH0KKyAgICAgKiBlbHNlIHsgb2xkVmFsdWUgPSBzdGF0ZTsgfQorICAgICAqIGFjLmZpcmVQcm9wZXJ0eUNoYW5nZShBY2Nlc3NpYmxlQ29udGV4dC5BQ0NFU1NJQkxFX1NUQVRFX1BST1BFUlRZLAorICAgICAqIG9sZFZhbHVlLCBuZXdWYWx1ZSk7IH0gfQorICAgICAqLworCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwdWJsaWMgdm9pZCBzZXRGb2N1c1RyYXZlcnNhbEtleXMoaW50IGlkLCBTZXQ8PyBleHRlbmRzIEFXVEtleVN0cm9rZT4KKyAgICAgKiBrZXlzdHJva2VzKSB7IFNldDw/IGV4dGVuZHMgQVdUS2V5U3Ryb2tlPiBvbGRUcmF2ZXJzYWxLZXlzOyBTdHJpbmcKKyAgICAgKiBwcm9wTmFtZSA9ICJGb2N1c1RyYXZlcnNhbEtleXMiOyAvLyROT04tTkxTLTEkIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeworICAgICAqIEludGVnZXIga0lkID0gbmV3IEludGVnZXIoaWQpOworICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLmNoZWNrVHJhdmVyc2FsS2V5c0lEKHRyYXZlcnNhbEtleXMsIGtJZCk7CisgICAgICogTWFwPEludGVnZXIsIFNldDw/IGV4dGVuZHMgQVdUS2V5U3Ryb2tlPj4ga2V5cyA9IG5ldyBIYXNoTWFwPEludGVnZXIsCisgICAgICogU2V0PD8gZXh0ZW5kcyBBV1RLZXlTdHJva2U+PigpOyBmb3IgKGludCBraWQgOiB0cmF2ZXJzYWxJRHMpIHsgSW50ZWdlcgorICAgICAqIGtleSA9IG5ldyBJbnRlZ2VyKGtpZCk7IGtleXMucHV0KGtleSwgZ2V0Rm9jdXNUcmF2ZXJzYWxLZXlzKGtpZCkpOyB9CisgICAgICogS2V5Ym9hcmRGb2N1c01hbmFnZXIuY2hlY2tLZXlTdHJva2VzKHRyYXZlcnNhbElEcywga2V5cywga0lkLAorICAgICAqIGtleXN0cm9rZXMpOyBvbGRUcmF2ZXJzYWxLZXlzID0gdHJhdmVyc2FsS2V5cy5nZXQobmV3IEludGVnZXIoaWQpKTsgLy8KKyAgICAgKiBwdXQgYSBjb3B5IG9mIGtleXN0cm9rZXMgb2JqZWN0IGludG8gbWFwOiBTZXQ8PyBleHRlbmRzIEFXVEtleVN0cm9rZT4KKyAgICAgKiBuZXdLZXlzID0ga2V5c3Ryb2tlczsgaWYgKGtleXN0cm9rZXMgIT0gbnVsbCkgeyBuZXdLZXlzID0gbmV3CisgICAgICogSGFzaFNldDxBV1RLZXlTdHJva2U+KGtleXN0cm9rZXMpOyB9IHRyYXZlcnNhbEtleXMucHV0KGtJZCwgbmV3S2V5cyk7CisgICAgICogU3RyaW5nIGRpcmVjdGlvbiA9ICIiOyAvLyROT04tTkxTLTEkIHN3aXRjaCAoaWQpIHsgY2FzZQorICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLkZPUldBUkRfVFJBVkVSU0FMX0tFWVM6IGRpcmVjdGlvbiA9ICJmb3J3YXJkIjsKKyAgICAgKiAvLyROT04tTkxTLTEkIGJyZWFrOyBjYXNlIEtleWJvYXJkRm9jdXNNYW5hZ2VyLkJBQ0tXQVJEX1RSQVZFUlNBTF9LRVlTOgorICAgICAqIGRpcmVjdGlvbiA9ICJiYWNrd2FyZCI7IC8vJE5PTi1OTFMtMSQgYnJlYWs7IGNhc2UKKyAgICAgKiBLZXlib2FyZEZvY3VzTWFuYWdlci5VUF9DWUNMRV9UUkFWRVJTQUxfS0VZUzogZGlyZWN0aW9uID0gInVwQ3ljbGUiOworICAgICAqIC8vJE5PTi1OTFMtMSQgYnJlYWs7IGNhc2UgS2V5Ym9hcmRGb2N1c01hbmFnZXIuRE9XTl9DWUNMRV9UUkFWRVJTQUxfS0VZUzoKKyAgICAgKiBkaXJlY3Rpb24gPSAiZG93bkN5Y2xlIjsgLy8kTk9OLU5MUy0xJCBicmVhazsgfSBwcm9wTmFtZSA9IGRpcmVjdGlvbiArCisgICAgICogcHJvcE5hbWU7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gZmlyZVByb3BlcnR5Q2hhbmdlKHByb3BOYW1lLAorICAgICAqIG9sZFRyYXZlcnNhbEtleXMsIGtleXN0cm9rZXMpOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmb2N1cyB0cmF2ZXJzYWwga2V5cyBzdGF0ZSBmb3IgdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0cnVlIGlmIHRoZSBmb2N1cyB0cmF2ZXJzYWwga2V5cyBzdGF0ZSBpcyBlbmFibGVkLCBmYWxzZSBpZgorICAgICAqICAgICAgICAgICAgdGhlIGZvY3VzIHRyYXZlcnNhbCBrZXlzIHN0YXRlIGlzIGRpc2FibGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvY3VzVHJhdmVyc2FsS2V5c0VuYWJsZWQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBib29sZWFuIG9sZEZvY3VzVHJhdmVyc2FsS2V5c0VuYWJsZWQ7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkRm9jdXNUcmF2ZXJzYWxLZXlzRW5hYmxlZCA9IGZvY3VzVHJhdmVyc2FsS2V5c0VuYWJsZWQ7CisgICAgICAgICAgICBmb2N1c1RyYXZlcnNhbEtleXNFbmFibGVkID0gdmFsdWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZSgiZm9jdXNUcmF2ZXJzYWxLZXlzRW5hYmxlZCIsIG9sZEZvY3VzVHJhdmVyc2FsS2V5c0VuYWJsZWQsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICBmb2N1c1RyYXZlcnNhbEtleXNFbmFibGVkKTsKKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHB1YmxpYyB2b2lkIHNldEZvY3VzYWJsZShib29sZWFuIGZvY3VzYWJsZSkgeyBib29sZWFuIG9sZEZvY3VzYWJsZTsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgY2FsbGVkU2V0Rm9jdXNhYmxlID0gdHJ1ZTsgb2xkRm9jdXNhYmxlID0KKyAgICAgKiB0aGlzLmZvY3VzYWJsZTsgdGhpcy5mb2N1c2FibGUgPSBmb2N1c2FibGU7IGlmICghZm9jdXNhYmxlKSB7CisgICAgICogbW92ZUZvY3VzKCk7IH0gfSBmaW5hbGx5IHsgdG9vbGtpdC51bmxvY2tBV1QoKTsgfQorICAgICAqIGZpcmVQcm9wZXJ0eUNoYW5nZSgiZm9jdXNhYmxlIiwgb2xkRm9jdXNhYmxlLCBmb2N1c2FibGUpOyAvLyROT04tTkxTLTEkIH0KKyAgICAgKiBwdWJsaWMgRm9udCBnZXRGb250KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgcmV0dXJuIChmb250ID09IG51bGwpICYmCisgICAgICogKHBhcmVudCAhPSBudWxsKSA/IHBhcmVudC5nZXRGb250KCkgOiBmb250OyB9IGZpbmFsbHkgeworICAgICAqIHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZm9udCBmb3IgdGhpcyBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZm9udCBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbnQoRm9udCBmKSB7CisgICAgICAgIEZvbnQgb2xkRm9udDsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvbGRGb250ID0gZm9udDsKKyAgICAgICAgICAgIHNldEZvbnRJbXBsKGYpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2UoImZvbnQiLCBvbGRGb250LCBmb250KTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZvbnQgaW1wbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBmb250IGltcGwuCisgICAgICovCisgICAgdm9pZCBzZXRGb250SW1wbChGb250IGYpIHsKKyAgICAgICAgZm9udCA9IGY7CisgICAgICAgIGludmFsaWRhdGUoKTsKKyAgICAgICAgaWYgKGlzU2hvd2luZygpKSB7CisgICAgICAgICAgICByZXBhaW50KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZhbGlkYXRlIHRoZSBjb21wb25lbnQgaWYgaXQgaW5oZXJpdHMgdGhlIGZvbnQgZnJvbSB0aGUgcGFyZW50LiBUaGlzCisgICAgICogbWV0aG9kIGlzIG92ZXJyaWRkZW4gaW4gQ29udGFpbmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY29tcG9uZW50IHdhcyBpbnZhbGlkYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIGJvb2xlYW4gcHJvcGFnYXRlRm9udCgpIHsKKyAgICAgICAgaWYgKGZvbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZvcmVncm91bmQgY29sb3IgZm9yIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGZvcmVncm91bmQgY29sb3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rm9yZWdyb3VuZChDb2xvciBjKSB7CisgICAgICAgIENvbG9yIG9sZEZnQ29sb3I7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkRmdDb2xvciA9IGZvcmVDb2xvcjsKKyAgICAgICAgICAgIGZvcmVDb2xvciA9IGM7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZSgiZm9yZWdyb3VuZCIsIG9sZEZnQ29sb3IsIGZvcmVDb2xvcik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgcmVwYWludCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJhY2tncm91bmQgY29sb3IgZm9yIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYmFja2dyb3VuZCBjb2xvciBmb3IgdGhpcyBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZChDb2xvciBjKSB7CisgICAgICAgIENvbG9yIG9sZEJrQ29sb3I7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkQmtDb2xvciA9IGJhY2tDb2xvcjsKKyAgICAgICAgICAgIGJhY2tDb2xvciA9IGM7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZSgiYmFja2dyb3VuZCIsIG9sZEJrQ29sb3IsIGJhY2tDb2xvcik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgcmVwYWludCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgZm9yIHdoZXRoZXIgcGFpbnQgbWVzc2FnZXMgcmVjZWl2ZWQgZnJvbSB0aGUgb3BlcmF0aW5nCisgICAgICogc3lzdGVtIHNob3VsZCBiZSBpZ25vcmVkIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRydWUgaWYgcGFpbnQgbWVzc2FnZXMgcmVjZWl2ZWQgZnJvbSB0aGUgb3BlcmF0aW5nIHN5c3RlbQorICAgICAqICAgICAgICAgICAgc2hvdWxkIGJlIGlnbm9yZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJZ25vcmVSZXBhaW50KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZ25vcmVSZXBhaW50ID0gdmFsdWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbG9jYWxlIG9mIHRoZSBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBMb2NhbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgTG9jYWxlIG9sZExvY2FsZTsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvbGRMb2NhbGUgPSB0aGlzLmxvY2FsZTsKKyAgICAgICAgICAgIHRoaXMubG9jYWxlID0gbG9jYWxlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2UoImxvY2FsZSIsIG9sZExvY2FsZSwgbG9jYWxlKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBDb21wb25lbnQgdG8gdGhlIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBsb2NhdGlvbiBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKFBvaW50IHApIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRMb2NhdGlvbihwLngsIHAueSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbG9jYXRpb24gb2YgdGhlIENvbXBvbmVudCB0byB0aGUgc3BlY2lmaWVkIHgsIHkgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9jYXRpb24oaW50IHgsIGludCB5KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbW92ZSh4LCB5KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2aXNpYmlsaXR5IHN0YXRlIG9mIHRoZSBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRydWUgaWYgdGhlIGNvbXBvbmVudCBpcyB2aXNpYmxlLCBmYWxzZSBpZiB0aGUgY29tcG9uZW50IGlzCisgICAgICogICAgICAgICAgICBub3Qgc2hvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VmlzaWJsZShib29sZWFuIGIpIHsKKyAgICAgICAgLy8gc2hvdygpICYgaGlkZSgpIGFyZSBub3QgZGVwcmVjYXRlZCBmb3IgV2luZG93LAorICAgICAgICAvLyBzbyBoYXZlIHRvIGNhbGwgdGhlbSBmcm9tIHNldFZpc2libGUoKQorICAgICAgICBzaG93KGIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQ6IHJlcGxhY2VkIGJ5IHNldFZpc2libGUoYm9vbGVhbikgbWV0aG9kLgorICAgICAqIAorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHNldFZpc2libGUoYm9vbGVhbikgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgc2hvdygpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAodmlzaWJsZSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZXBhcmU0SGllcmFyY2h5Q2hhbmdlKCk7CisgICAgICAgICAgICBtYXBUb0Rpc3BsYXkodHJ1ZSk7CisgICAgICAgICAgICB2YWxpZGF0ZSgpOworICAgICAgICAgICAgdmlzaWJsZSA9IHRydWU7CisgICAgICAgICAgICBiZWhhdmlvdXIuc2V0VmlzaWJsZSh0cnVlKTsKKyAgICAgICAgICAgIHBvc3RFdmVudChuZXcgQ29tcG9uZW50RXZlbnQodGhpcywgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX1NIT1dOKSk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGZpbmlzaEhpZXJhcmNoeUNoYW5nZSh0aGlzLCBwYXJlbnQsIDApOworICAgICAgICAgICAgbm90aWZ5SW5wdXRNZXRob2QobmV3IFJlY3RhbmdsZSh4LCB5LCB3LCBoKSk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGludmFsaWRhdGVSZWFsUGFyZW50KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVwcmVjYXRlZDogcmVwbGFjZWQgYnkgc2V0VmlzaWJsZShib29sZWFuKSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSB2aXNpYmlsaXR5J3Mgc3RhdGUuCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgc2V0VmlzaWJsZShib29sZWFuKSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzaG93KGJvb2xlYW4gYikgeworICAgICAgICBpZiAoYikgeworICAgICAgICAgICAgc2hvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaGlkZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiB2b2lkIHRyYW5zZmVyRm9jdXMoaW50IGRpcikgeyBDb250YWluZXIgcm9vdCA9IG51bGw7IGlmICh0aGlzIGluc3RhbmNlb2YKKyAgICAgKiBDb250YWluZXIpIHsgQ29udGFpbmVyIGNvbnQgPSAoQ29udGFpbmVyKSB0aGlzOyBpZgorICAgICAqIChjb250LmlzRm9jdXNDeWNsZVJvb3QoKSkgeyByb290ID0gY29udC5nZXRGb2N1c1RyYXZlcnNhbFJvb3QoKTsgfSB9IGlmCisgICAgICogKHJvb3QgPT0gbnVsbCkgeyByb290ID0gZ2V0Rm9jdXNDeWNsZVJvb3RBbmNlc3RvcigpOyB9IC8vIHRyYW5zZmVyIGZvY3VzCisgICAgICogdXAgY3ljbGUgaWYgcm9vdCBpcyB1bnJlYWNoYWJsZSBDb21wb25lbnQgY29tcCA9IHRoaXM7IHdoaWxlICgocm9vdCAhPQorICAgICAqIG51bGwpICYmICEocm9vdC5pc0ZvY3VzQ3ljbGVSb290KCkgJiYgcm9vdC5pc1Nob3dpbmcoKSAmJgorICAgICAqIHJvb3QuaXNFbmFibGVkKCkgJiYgcm9vdCAuaXNGb2N1c2FibGUoKSkpIHsgY29tcCA9IHJvb3Q7IHJvb3QgPQorICAgICAqIHJvb3QuZ2V0Rm9jdXNDeWNsZVJvb3RBbmNlc3RvcigpOyB9IGlmIChyb290ID09IG51bGwpIHsgcmV0dXJuOyB9CisgICAgICogRm9jdXNUcmF2ZXJzYWxQb2xpY3kgcG9saWN5ID0gcm9vdC5nZXRGb2N1c1RyYXZlcnNhbFBvbGljeSgpOyBDb21wb25lbnQKKyAgICAgKiBuZXh0Q29tcCA9IG51bGw7IHN3aXRjaCAoZGlyKSB7IGNhc2UKKyAgICAgKiBLZXlib2FyZEZvY3VzTWFuYWdlci5GT1JXQVJEX1RSQVZFUlNBTF9LRVlTOiBuZXh0Q29tcCA9CisgICAgICogcG9saWN5LmdldENvbXBvbmVudEFmdGVyKHJvb3QsIGNvbXApOyBicmVhazsgY2FzZQorICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLkJBQ0tXQVJEX1RSQVZFUlNBTF9LRVlTOiBuZXh0Q29tcCA9CisgICAgICogcG9saWN5LmdldENvbXBvbmVudEJlZm9yZShyb290LCBjb21wKTsgYnJlYWs7IH0gaWYgKG5leHRDb21wICE9IG51bGwpIHsKKyAgICAgKiBuZXh0Q29tcC5yZXF1ZXN0Rm9jdXMoZmFsc2UpOyB9IH0gcHVibGljIHZvaWQgdHJhbnNmZXJGb2N1cygpIHsKKyAgICAgKiB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5IHsgbmV4dEZvY3VzKCk7IH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0KKyAgICAgKiB9IHB1YmxpYyB2b2lkIHRyYW5zZmVyRm9jdXNCYWNrd2FyZCgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7IHRyeSB7CisgICAgICogdHJhbnNmZXJGb2N1cyhLZXlib2FyZEZvY3VzTWFuYWdlci5CQUNLV0FSRF9UUkFWRVJTQUxfS0VZUyk7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9IHB1YmxpYyB2b2lkIHRyYW5zZmVyRm9jdXNVcEN5Y2xlKCkgeworICAgICAqIHRvb2xraXQubG9ja0FXVCgpOyB0cnkgeyBLZXlib2FyZEZvY3VzTWFuYWdlciBrZm0gPQorICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLmdldEN1cnJlbnRLZXlib2FyZEZvY3VzTWFuYWdlcigpOyBDb250YWluZXIgcm9vdCA9CisgICAgICoga2ZtLmdldEN1cnJlbnRGb2N1c0N5Y2xlUm9vdCgpOyBpZihyb290ID09IG51bGwpIHsgcmV0dXJuOyB9IGJvb2xlYW4KKyAgICAgKiBzdWNjZXNzID0gZmFsc2U7IENvbXBvbmVudCBuZXh0Q29tcCA9IG51bGw7IENvbnRhaW5lciBuZXdSb290ID0gcm9vdDsgZG8KKyAgICAgKiB7IG5leHRDb21wID0gbmV3Um9vdCBpbnN0YW5jZW9mIFdpbmRvdyA/CisgICAgICogbmV3Um9vdC5nZXRGb2N1c1RyYXZlcnNhbFBvbGljeSgpIC5nZXREZWZhdWx0Q29tcG9uZW50KG5ld1Jvb3QpIDoKKyAgICAgKiBuZXdSb290OyBuZXdSb290ID0gbmV3Um9vdC5nZXRGb2N1c0N5Y2xlUm9vdEFuY2VzdG9yKCk7IGlmIChuZXh0Q29tcCA9PQorICAgICAqIG51bGwpIHsgYnJlYWs7IH0gc3VjY2VzcyA9IG5leHRDb21wLnJlcXVlc3RGb2N1c0luV2luZG93KCk7IGlmIChuZXdSb290CisgICAgICogPT0gbnVsbCkgeyBicmVhazsgfSBrZm0uc2V0R2xvYmFsQ3VycmVudEZvY3VzQ3ljbGVSb290KG5ld1Jvb3QpOyB9IHdoaWxlCisgICAgICogKCFzdWNjZXNzKTsgaWYgKCFzdWNjZXNzICYmIHJvb3QgIT0gbmV3Um9vdCkgeworICAgICAqIGtmbS5zZXRHbG9iYWxDdXJyZW50Rm9jdXNDeWNsZVJvb3Qocm9vdCk7IH0gfSBmaW5hbGx5IHsKKyAgICAgKiB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlcyB0aGF0IHRoaXMgY29tcG9uZW50IGhhcyBhIHZhbGlkIGxheW91dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWJlaGF2aW91ci5pc0Rpc3BsYXlhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2YWxpZGF0ZUltcGwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZSBpbXBsLgorICAgICAqLworICAgIHZvaWQgdmFsaWRhdGVJbXBsKCkgeworICAgICAgICB2YWxpZCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmF0aXZlIHdpbmRvdy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuYXRpdmUgd2luZG93LgorICAgICAqLworICAgIE5hdGl2ZVdpbmRvdyBnZXROYXRpdmVXaW5kb3coKSB7CisgICAgICAgIHJldHVybiBiZWhhdmlvdXIuZ2V0TmF0aXZlV2luZG93KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IGEgbWF4aW11bSBzaXplIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBtYXhpbXVtIHNpemUgaXMgc2V0IGZvciB0aGUgQ29tcG9uZW50LCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTWF4aW11bVNpemVTZXQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG1heGltdW1TaXplICE9IG51bGw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBtaW5pbXVtIHNpemUgaXMgc2V0IGZvciB0aGUgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIG1pbmltdW0gc2l6ZSBpcyBzZXQgZm9yIHRoZSBjb21wb25lbnQsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNNaW5pbXVtU2l6ZVNldCgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbWluaW11bVNpemUgIT0gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHByZWZlcnJlZCBzaXplIGlzIHNldCBmb3IgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBwcmVmZXJyZWQgc2l6ZSBpcyBzZXQgZm9yIHRoZSBDb21wb25lbnQsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQcmVmZXJyZWRTaXplU2V0KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBwcmVmZXJyZWRTaXplICE9IG51bGw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWF4aW11bSBzaXplIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBzaXplIG9mIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRNYXhpbXVtU2l6ZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gaXNNYXhpbXVtU2l6ZVNldCgpID8gbmV3IERpbWVuc2lvbihtYXhpbXVtU2l6ZSkgOiBuZXcgRGltZW5zaW9uKFNob3J0Lk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGltZW5zaW9uIGdldE1pbmltdW1TaXplKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBtaW5pbXVtU2l6ZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQ6IHJlcGxhY2VkIGJ5IGdldE1pbmltdW1TaXplKCkgbWV0aG9kLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIERpbWVuc2lvbi4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBnZXRNaW5pbXVtU2l6ZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEaW1lbnNpb24gbWluaW11bVNpemUoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGlzTWluaW11bVNpemVTZXQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiAoRGltZW5zaW9uKW1pbmltdW1TaXplLmNsb25lKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBEaW1lbnNpb24gZGVmU2l6ZSA9IGdldERlZmF1bHRNaW5pbXVtU2l6ZSgpOworICAgICAgICAgICAgaWYgKGRlZlNpemUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAoRGltZW5zaW9uKWRlZlNpemUuY2xvbmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpc0Rpc3BsYXlhYmxlKCkgPyBuZXcgRGltZW5zaW9uKDEsIDEpIDogbmV3IERpbWVuc2lvbih3LCBoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcmVmZXJyZWQgc2l6ZSBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHByZWZlcnJlZCBzaXplIG9mIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRQcmVmZXJyZWRTaXplKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBwcmVmZXJyZWRTaXplKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVwcmVjYXRlZDogcmVwbGFjZWQgYnkgZ2V0UHJlZmVycmVkU2l6ZSgpIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBEaW1lbnNpb24uCisgICAgICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgZ2V0UHJlZmVycmVkU2l6ZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEaW1lbnNpb24gcHJlZmVycmVkU2l6ZSgpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoaXNQcmVmZXJyZWRTaXplU2V0KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihwcmVmZXJyZWRTaXplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIERpbWVuc2lvbiBkZWZTaXplID0gZ2V0RGVmYXVsdFByZWZlcnJlZFNpemUoKTsKKyAgICAgICAgICAgIGlmIChkZWZTaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihkZWZTaXplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGdldE1pbmltdW1TaXplKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBtYXhpbXVtU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBtYXhpbXVtIHNpemUgb2YgdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNYXhpbXVtU2l6ZShEaW1lbnNpb24gbWF4aW11bVNpemUpIHsKKyAgICAgICAgRGltZW5zaW9uIG9sZE1heGltdW1TaXplOworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9sZE1heGltdW1TaXplID0gdGhpcy5tYXhpbXVtU2l6ZTsKKyAgICAgICAgICAgIGlmIChvbGRNYXhpbXVtU2l6ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb2xkTWF4aW11bVNpemUgPSBvbGRNYXhpbXVtU2l6ZS5nZXRTaXplKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodGhpcy5tYXhpbXVtU2l6ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKG1heGltdW1TaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXhpbXVtU2l6ZSA9IG5ldyBEaW1lbnNpb24obWF4aW11bVNpemUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKG1heGltdW1TaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXhpbXVtU2l6ZS5zZXRTaXplKG1heGltdW1TaXplKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aGlzLm1heGltdW1TaXplID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZSgibWF4aW11bVNpemUiLCBvbGRNYXhpbXVtU2l6ZSwgdGhpcy5tYXhpbXVtU2l6ZSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGludmFsaWRhdGVSZWFsUGFyZW50KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbWluaW11bSBzaXplIG9mIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG1pbmltdW1TaXplCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG1pbmltdW0gc2l6ZSBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1pbmltdW1TaXplKERpbWVuc2lvbiBtaW5pbXVtU2l6ZSkgeworICAgICAgICBEaW1lbnNpb24gb2xkTWluaW11bVNpemU7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkTWluaW11bVNpemUgPSB0aGlzLm1pbmltdW1TaXplOworICAgICAgICAgICAgaWYgKG9sZE1pbmltdW1TaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvbGRNaW5pbXVtU2l6ZSA9IG9sZE1pbmltdW1TaXplLmdldFNpemUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0aGlzLm1pbmltdW1TaXplID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAobWluaW11bVNpemUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbmltdW1TaXplID0gbmV3IERpbWVuc2lvbihtaW5pbXVtU2l6ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAobWluaW11bVNpemUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbmltdW1TaXplLnNldFNpemUobWluaW11bVNpemUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMubWluaW11bVNpemUgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICAgICAgZmlyZVByb3BlcnR5Q2hhbmdlKCJtaW5pbXVtU2l6ZSIsIG9sZE1pbmltdW1TaXplLCB0aGlzLm1pbmltdW1TaXplKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vID8/P0FXVDogaW52YWxpZGF0ZVJlYWxQYXJlbnQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcmVmZXJyZWQgc2l6ZSBvZiB0aGUgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcmVmZXJyZWRTaXplCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHByZWZlcnJlZCBzaXplIG9mIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJlZmVycmVkU2l6ZShEaW1lbnNpb24gcHJlZmVycmVkU2l6ZSkgeworICAgICAgICBEaW1lbnNpb24gb2xkUHJlZmVycmVkU2l6ZTsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvbGRQcmVmZXJyZWRTaXplID0gdGhpcy5wcmVmZXJyZWRTaXplOworICAgICAgICAgICAgaWYgKG9sZFByZWZlcnJlZFNpemUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG9sZFByZWZlcnJlZFNpemUgPSBvbGRQcmVmZXJyZWRTaXplLmdldFNpemUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0aGlzLnByZWZlcnJlZFNpemUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChwcmVmZXJyZWRTaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmZXJyZWRTaXplID0gbmV3IERpbWVuc2lvbihwcmVmZXJyZWRTaXplKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChwcmVmZXJyZWRTaXplICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmZXJyZWRTaXplLnNldFNpemUocHJlZmVycmVkU2l6ZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmZXJyZWRTaXplID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZSgicHJlZmVycmVkU2l6ZSIsIG9sZFByZWZlcnJlZFNpemUsIHRoaXMucHJlZmVycmVkU2l6ZSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGludmFsaWRhdGVSZWFsUGFyZW50KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBSZWRyYXdNYW5hZ2VyIGdldFJlZHJhd01hbmFnZXIoKSB7IGlmIChwYXJlbnQgPT0gbnVsbCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAqIHJldHVybiBwYXJlbnQuZ2V0UmVkcmF3TWFuYWdlcigpOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgaXMgZm9jdXNhYmlsaXR5IGV4cGxpY2l0bHkgc2V0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjb21wb25lbnQgaGFzIGEgZm9jdXNhYmxlIHBlZXIuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBib29sZWFuIGlzUGVlckZvY3VzYWJsZSgpIHsgLy8gVGhlIHJlY29tbWVuZGF0aW9ucyBmb3IgV2luZG93cyBhbmQgVW5peAorICAgICAqIGFyZSB0aGF0IC8vIENhbnZhc2VzLCBMYWJlbHMsIFBhbmVscywgU2Nyb2xsYmFycywgU2Nyb2xsUGFuZXMsIFdpbmRvd3MsCisgICAgICogLy8gYW5kIGxpZ2h0d2VpZ2h0IENvbXBvbmVudHMgaGF2ZSBub24tZm9jdXNhYmxlIHBlZXJzLCAvLyBhbmQgYWxsIG90aGVyCisgICAgICogQ29tcG9uZW50cyBoYXZlIGZvY3VzYWJsZSBwZWVycy4gaWYgKHRoaXMgaW5zdGFuY2VvZiBDYW52YXMgfHwgdGhpcworICAgICAqIGluc3RhbmNlb2YgTGFiZWwgfHwgdGhpcyBpbnN0YW5jZW9mIFBhbmVsIHx8IHRoaXMgaW5zdGFuY2VvZiBTY3JvbGxiYXIgfHwKKyAgICAgKiB0aGlzIGluc3RhbmNlb2YgU2Nyb2xsUGFuZSB8fCB0aGlzIGluc3RhbmNlb2YgV2luZG93IHx8IGlzTGlnaHR3ZWlnaHQoKSkKKyAgICAgKiB7IHJldHVybiBmYWxzZTsgfSByZXR1cm4gdHJ1ZTsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogQHJldHVybiB0cnVlIGlmIGZvY3VzYWJpbGl0eSB3YXMgZXhwbGljaXRseSBzZXQgdmlhIGEgY2FsbCB0bworICAgICAqICAgICAgICAgc2V0Rm9jdXNhYmxlKCkgb3IgdmlhIG92ZXJyaWRpbmcgaXNGb2N1c2FibGUoKSBvcgorICAgICAqICAgICAgICAgaXNGb2N1c1RyYXZlcnNhYmxlKCkuCisgICAgICovCisgICAgYm9vbGVhbiBpc0ZvY3VzYWJpbGl0eUV4cGxpY2l0bHlTZXQoKSB7CisgICAgICAgIHJldHVybiBjYWxsZWRTZXRGb2N1c2FibGUgfHwgb3ZlcnJpZGVuSXNGb2N1c2FibGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFpbnRzIHRoZSBjb21wb25lbnQgYW5kIGFsbCBvZiBpdHMgc3ViY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzIHRvIGJlIHVzZWQgZm9yIHBhaW50aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhaW50QWxsKEdyYXBoaWNzIGcpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYWludChnKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MgdG8gYmUgdXNlZCBmb3IgdXBkYXRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKEdyYXBoaWNzIGcpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWlzTGlnaHR3ZWlnaHQoKSAmJiAhaXNQcmVwYWludGVyKCkpIHsKKyAgICAgICAgICAgICAgICBnLnNldENvbG9yKGdldEJhY2tncm91bmQoKSk7CisgICAgICAgICAgICAgICAgZy5maWxsUmVjdCgwLCAwLCB3LCBoKTsKKyAgICAgICAgICAgICAgICBnLnNldENvbG9yKGdldEZvcmVncm91bmQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYWludChnKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYWludHMgdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljcyB0byBiZSB1c2VkIGZvciBwYWludGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYWludChHcmFwaGljcyBnKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gSnVzdCB0byBub3RoaW5nCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZXMgdGhlIGNvbXBvbmVudCB0byBiZSBwYWludGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MgdG8gYmUgdXNlZCBmb3IgcGFpbnRpbmcuCisgICAgICovCisgICAgdm9pZCBwcmVwYWludChHcmFwaGljcyBnKSB7CisgICAgICAgIC8vIEp1c3QgdG8gbm90aGluZy4gRm9yIG92ZXJyaWRpbmcuCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGlzIHByZXBhaW50ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBwcmVwYWludGVyLgorICAgICAqLworICAgIGJvb2xlYW4gaXNQcmVwYWludGVyKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZTQgaGllcmFyY2h5IGNoYW5nZS4KKyAgICAgKi8KKyAgICB2b2lkIHByZXBhcmU0SGllcmFyY2h5Q2hhbmdlKCkgeworICAgICAgICBpZiAoaGllcmFyY2h5Q2hhbmdpbmdDb3VudGVyKysgPT0gMCkgeworICAgICAgICAgICAgd2FzU2hvd2luZyA9IGlzU2hvd2luZygpOworICAgICAgICAgICAgd2FzRGlzcGxheWFibGUgPSBpc0Rpc3BsYXlhYmxlKCk7CisgICAgICAgICAgICBwcmVwYXJlQ2hpbGRyZW40SGllcmFyY2h5Q2hhbmdlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwYXJlIGNoaWxkcmVuNCBoaWVyYXJjaHkgY2hhbmdlLgorICAgICAqLworICAgIHZvaWQgcHJlcGFyZUNoaWxkcmVuNEhpZXJhcmNoeUNoYW5nZSgpIHsKKyAgICAgICAgLy8gVG8gYmUgaW5oZXJpdGVkIGJ5IENvbnRhaW5lcgorICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogdm9pZCBmaW5pc2hIaWVyYXJjaHlDaGFuZ2UoQ29tcG9uZW50IGNoYW5nZWQsIENvbnRhaW5lciBjaGFuZ2VkUGFyZW50LAorICAgICAqIGludCBhbmNlc3RvckZsYWdzKSB7IGlmICgtLWhpZXJhcmNoeUNoYW5naW5nQ291bnRlciA9PSAwKSB7IGludAorICAgICAqIGNoYW5nZUZsYWdzID0gYW5jZXN0b3JGbGFnczsgaWYgKHdhc1Nob3dpbmcgIT0gaXNTaG93aW5nKCkpIHsgY2hhbmdlRmxhZ3MKKyAgICAgKiB8PSBIaWVyYXJjaHlFdmVudC5TSE9XSU5HX0NIQU5HRUQ7IH0gaWYgKHdhc0Rpc3BsYXlhYmxlICE9CisgICAgICogaXNEaXNwbGF5YWJsZSgpKSB7IGNoYW5nZUZsYWdzIHw9IEhpZXJhcmNoeUV2ZW50LkRJU1BMQVlBQklMSVRZX0NIQU5HRUQ7CisgICAgICogfSBpZiAoY2hhbmdlRmxhZ3MgPiAwKSB7IHBvc3RFdmVudChuZXcgSGllcmFyY2h5RXZlbnQodGhpcywKKyAgICAgKiBIaWVyYXJjaHlFdmVudC5ISUVSQVJDSFlfQ0hBTkdFRCwgY2hhbmdlZCwgY2hhbmdlZFBhcmVudCwgY2hhbmdlRmxhZ3MpKTsKKyAgICAgKiB9IGZpbmlzaENoaWxkcmVuSGllcmFyY2h5Q2hhbmdlKGNoYW5nZWQsIGNoYW5nZWRQYXJlbnQsIGFuY2VzdG9yRmxhZ3MpOyB9CisgICAgICogfSB2b2lkIGZpbmlzaENoaWxkcmVuSGllcmFyY2h5Q2hhbmdlKENvbXBvbmVudCBjaGFuZ2VkLCBDb250YWluZXIKKyAgICAgKiBjaGFuZ2VkUGFyZW50LCBpbnQgYW5jZXN0b3JGbGFncykgeyAvLyBUbyBiZSBpbmhlcml0ZWQgYnkgQ29udGFpbmVyIH0KKyAgICAgKiB2b2lkIHBvc3RIaWVyYXJjaHlCb3VuZHNFdmVudHMoQ29tcG9uZW50IGNoYW5nZWQsIGludCBpZCkgeyBwb3N0RXZlbnQobmV3CisgICAgICogSGllcmFyY2h5RXZlbnQodGhpcywgaWQsIGNoYW5nZWQsIG51bGwsIDApKTsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogU3ByZWFkIGhpZXJhcmNoeSBib3VuZHMgZXZlbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFuZ2VkCisgICAgICogICAgICAgICAgICB0aGUgY2hhbmdlZC4KKyAgICAgKiBAcGFyYW0gaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpZC4KKyAgICAgKi8KKyAgICB2b2lkIHNwcmVhZEhpZXJhcmNoeUJvdW5kc0V2ZW50cyhDb21wb25lbnQgY2hhbmdlZCwgaW50IGlkKSB7CisgICAgICAgIC8vIFRvIGJlIGluaGVyaXRlZCBieSBDb250YWluZXIKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNwYXRjaGVzIGFuIGV2ZW50IHRvIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgRXZlbnQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgZGlzcGF0Y2hFdmVudChBV1RFdmVudCBlKSB7CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvKgorICAgICAgICAgKiBpZiAoZS5pc0NvbnN1bWVkKCkpIHsgcmV0dXJuOyB9IGlmIChlIGluc3RhbmNlb2YgUGFpbnRFdmVudCkgeworICAgICAgICAgKiB0b29sa2l0LmRpc3BhdGNoQVdURXZlbnQoZSk7IHByb2Nlc3NQYWludEV2ZW50KChQYWludEV2ZW50KSBlKTsKKyAgICAgICAgICogcmV0dXJuOyB9IEtleWJvYXJkRm9jdXNNYW5hZ2VyIGtmbSA9CisgICAgICAgICAqIEtleWJvYXJkRm9jdXNNYW5hZ2VyLmdldEN1cnJlbnRLZXlib2FyZEZvY3VzTWFuYWdlcigpOyBpZgorICAgICAgICAgKiAoIWUuZGlzcGF0Y2hlZEJ5S0ZNICYmIGtmbS5kaXNwYXRjaEV2ZW50KGUpKSB7IHJldHVybjsgfSBpZiAoZQorICAgICAgICAgKiBpbnN0YW5jZW9mIEtleUV2ZW50KSB7IEtleUV2ZW50IGtlID0gKEtleUV2ZW50KSBlOyAvLyBjb25zdW1lcworICAgICAgICAgKiBLZXlFdmVudCB3aGljaCByZXByZXNlbnRzIGEgZm9jdXMgdHJhdmVyc2FsIGtleSBpZgorICAgICAgICAgKiAoZ2V0Rm9jdXNUcmF2ZXJzYWxLZXlzRW5hYmxlZCgpKSB7IGtmbS5wcm9jZXNzS2V5RXZlbnQodGhpcywga2UpOyBpZgorICAgICAgICAgKiAoa2UuaXNDb25zdW1lZCgpKSB7IHJldHVybjsgfSB9IH0gaWYgKGlucHV0TWV0aG9kc0VuYWJsZWQgJiYKKyAgICAgICAgICogZGlzcGF0Y2hUb0lNICYmIGUuaXNQb3N0ZWQgJiYgZGlzcGF0Y2hFdmVudFRvSU0oZSkpIHsgcmV0dXJuOyB9IGlmCisgICAgICAgICAqIChlLmdldElEKCkgPT0gV2luZG93RXZlbnQuV0lORE9XX0lDT05JRklFRCkgeworICAgICAgICAgKiBub3RpZnlJbnB1dE1ldGhvZChudWxsKTsgfSBBV1RFdmVudC5FdmVudERlc2NyaXB0b3IgZGVzY3JpcHRvciA9CisgICAgICAgICAqIHRvb2xraXQuZXZlbnRUeXBlTG9va3VwLmdldEV2ZW50RGVzY3JpcHRvcihlKTsKKyAgICAgICAgICogdG9vbGtpdC5kaXNwYXRjaEFXVEV2ZW50KGUpOyBpZiAoZGVzY3JpcHRvciAhPSBudWxsKSB7IGlmCisgICAgICAgICAqIChpc0V2ZW50RW5hYmxlZChkZXNjcmlwdG9yLmV2ZW50TWFzaykgfHwKKyAgICAgICAgICogKGdldExpc3RlbmVycyhkZXNjcmlwdG9yLmxpc3RlbmVyVHlwZSkubGVuZ3RoID4gMCkpIHsKKyAgICAgICAgICogcHJvY2Vzc0V2ZW50KGUpOyB9IC8vIGlucHV0IGV2ZW50cyBjYW4gYmUgY29uc3VtZWQgYnkgdXNlciBsaXN0ZW5lcnM6CisgICAgICAgICAqIGlmICghZS5pc0NvbnN1bWVkKCkgJiYgKChlbmFibGVkQVdURXZlbnRzICYgZGVzY3JpcHRvci5ldmVudE1hc2spICE9CisgICAgICAgICAqIDApKSB7IHBvc3Rwcm9jZXNzRXZlbnQoZSwgZGVzY3JpcHRvci5ldmVudE1hc2spOyB9IH0KKyAgICAgICAgICogcG9zdERlcHJlY2F0ZWRFdmVudChlKTsKKyAgICAgICAgICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUG9zdCBkZXByZWNhdGVkIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcG9zdERlcHJlY2F0ZWRFdmVudChBV1RFdmVudCBlKSB7CisgICAgICAgIGlmIChkZXByZWNhdGVkRXZlbnRIYW5kbGVyKSB7CisgICAgICAgICAgICBFdmVudCBldnQgPSBlLmdldEV2ZW50KCk7CisgICAgICAgICAgICBpZiAoZXZ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwb3N0RXZlbnQoZXZ0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBvc3Rwcm9jZXNzIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKiBAcGFyYW0gZXZlbnRNYXNrCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgbWFzay4KKyAgICAgKi8KKyAgICB2b2lkIHBvc3Rwcm9jZXNzRXZlbnQoQVdURXZlbnQgZSwgbG9uZyBldmVudE1hc2spIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjYWxsIHN5c3RlbSBsaXN0ZW5lcnMgdW5kZXIgQVdUIGxvY2sKKyAgICAgICAgICAgIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuRk9DVVNfRVZFTlRfTUFTSykgeworICAgICAgICAgICAgICAgIHByZXByb2Nlc3NGb2N1c0V2ZW50KChGb2N1c0V2ZW50KWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuS0VZX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgICAgICBwcmVwcm9jZXNzS2V5RXZlbnQoKEtleUV2ZW50KWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuTU9VU0VfRVZFTlRfTUFTSykgeworICAgICAgICAgICAgICAgIHByZXByb2Nlc3NNb3VzZUV2ZW50KChNb3VzZUV2ZW50KWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuTU9VU0VfTU9USU9OX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgICAgICBwcmVwcm9jZXNzTW91c2VNb3Rpb25FdmVudCgoTW91c2VFdmVudCllKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50LkNPTVBPTkVOVF9FVkVOVF9NQVNLKSB7CisgICAgICAgICAgICAgICAgcHJlcHJvY2Vzc0NvbXBvbmVudEV2ZW50KChDb21wb25lbnRFdmVudCllKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50Lk1PVVNFX1dIRUVMX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgICAgICBwcmVwcm9jZXNzTW91c2VXaGVlbEV2ZW50KChNb3VzZVdoZWVsRXZlbnQpZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50TWFzayA9PSBBV1RFdmVudC5JTlBVVF9NRVRIT0RfRVZFTlRfTUFTSykgeworICAgICAgICAgICAgICAgIHByZXByb2Nlc3NJbnB1dE1ldGhvZEV2ZW50KChJbnB1dE1ldGhvZEV2ZW50KWUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXByb2Nlc3MgaW5wdXQgbWV0aG9kIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJlcHJvY2Vzc0lucHV0TWV0aG9kRXZlbnQoSW5wdXRNZXRob2RFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NJbnB1dE1ldGhvZEV2ZW50SW1wbChlLCBpbnB1dE1ldGhvZExpc3RlbmVycy5nZXRTeXN0ZW1MaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcHJvY2VzcyBtb3VzZSB3aGVlbCBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByZXByb2Nlc3NNb3VzZVdoZWVsRXZlbnQoTW91c2VXaGVlbEV2ZW50IGUpIHsKKyAgICAgICAgcHJvY2Vzc01vdXNlV2hlZWxFdmVudEltcGwoZSwgbW91c2VXaGVlbExpc3RlbmVycy5nZXRTeXN0ZW1MaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBtb3VzZSB3aGVlbCBldmVudCBpbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NNb3VzZVdoZWVsRXZlbnRJbXBsKE1vdXNlV2hlZWxFdmVudCBlLCBDb2xsZWN0aW9uPE1vdXNlV2hlZWxMaXN0ZW5lcj4gYykgeworICAgICAgICBmb3IgKE1vdXNlV2hlZWxMaXN0ZW5lciBsaXN0ZW5lciA6IGMpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRJRCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBNb3VzZUV2ZW50Lk1PVVNFX1dIRUVMOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5tb3VzZVdoZWVsTW92ZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcHJvY2VzcyBjb21wb25lbnQgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcmVwcm9jZXNzQ29tcG9uZW50RXZlbnQoQ29tcG9uZW50RXZlbnQgZSkgeworICAgICAgICBwcm9jZXNzQ29tcG9uZW50RXZlbnRJbXBsKGUsIGNvbXBvbmVudExpc3RlbmVycy5nZXRTeXN0ZW1MaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcHJvY2VzcyBtb3VzZSBtb3Rpb24gZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqLworICAgIHZvaWQgcHJlcHJvY2Vzc01vdXNlTW90aW9uRXZlbnQoTW91c2VFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NNb3VzZU1vdGlvbkV2ZW50SW1wbChlLCBtb3VzZU1vdGlvbkxpc3RlbmVycy5nZXRTeXN0ZW1MaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcHJvY2VzcyBtb3VzZSBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUKKyAgICAgKi8KKyAgICB2b2lkIHByZXByb2Nlc3NNb3VzZUV2ZW50KE1vdXNlRXZlbnQgZSkgeworICAgICAgICBwcm9jZXNzTW91c2VFdmVudEltcGwoZSwgbW91c2VMaXN0ZW5lcnMuZ2V0U3lzdGVtTGlzdGVuZXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXByb2Nlc3Mga2V5IGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKi8KKyAgICB2b2lkIHByZXByb2Nlc3NLZXlFdmVudChLZXlFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NLZXlFdmVudEltcGwoZSwga2V5TGlzdGVuZXJzLmdldFN5c3RlbUxpc3RlbmVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwcm9jZXNzIGZvY3VzIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKi8KKyAgICB2b2lkIHByZXByb2Nlc3NGb2N1c0V2ZW50KEZvY3VzRXZlbnQgZSkgeworICAgICAgICBwcm9jZXNzRm9jdXNFdmVudEltcGwoZSwgZm9jdXNMaXN0ZW5lcnMuZ2V0U3lzdGVtTGlzdGVuZXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBBV1RFdmVudCBvY2N1cnJlZCBvbiB0aGlzIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NFdmVudChBV1RFdmVudCBlKSB7CisgICAgICAgIGxvbmcgZXZlbnRNYXNrID0gdG9vbGtpdC5ldmVudFR5cGVMb29rdXAuZ2V0RXZlbnRNYXNrKGUpOworICAgICAgICBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50LkNPTVBPTkVOVF9FVkVOVF9NQVNLKSB7CisgICAgICAgICAgICBwcm9jZXNzQ29tcG9uZW50RXZlbnQoKENvbXBvbmVudEV2ZW50KWUpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50TWFzayA9PSBBV1RFdmVudC5GT0NVU19FVkVOVF9NQVNLKSB7CisgICAgICAgICAgICBwcm9jZXNzRm9jdXNFdmVudCgoRm9jdXNFdmVudCllKTsKKyAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuS0VZX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgIHByb2Nlc3NLZXlFdmVudCgoS2V5RXZlbnQpZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50Lk1PVVNFX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgIHByb2Nlc3NNb3VzZUV2ZW50KChNb3VzZUV2ZW50KWUpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50TWFzayA9PSBBV1RFdmVudC5NT1VTRV9XSEVFTF9FVkVOVF9NQVNLKSB7CisgICAgICAgICAgICBwcm9jZXNzTW91c2VXaGVlbEV2ZW50KChNb3VzZVdoZWVsRXZlbnQpZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50Lk1PVVNFX01PVElPTl9FVkVOVF9NQVNLKSB7CisgICAgICAgICAgICBwcm9jZXNzTW91c2VNb3Rpb25FdmVudCgoTW91c2VFdmVudCllKTsKKyAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuSElFUkFSQ0hZX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgIHByb2Nlc3NIaWVyYXJjaHlFdmVudCgoSGllcmFyY2h5RXZlbnQpZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRNYXNrID09IEFXVEV2ZW50LkhJRVJBUkNIWV9CT1VORFNfRVZFTlRfTUFTSykgeworICAgICAgICAgICAgcHJvY2Vzc0hpZXJhcmNoeUJvdW5kc0V2ZW50KChIaWVyYXJjaHlFdmVudCllKTsKKyAgICAgICAgfSBlbHNlIGlmIChldmVudE1hc2sgPT0gQVdURXZlbnQuSU5QVVRfTUVUSE9EX0VWRU5UX01BU0spIHsKKyAgICAgICAgICAgIHByb2Nlc3NJbnB1dE1ldGhvZEV2ZW50KChJbnB1dE1ldGhvZEV2ZW50KWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBhbGwgbGlzdGVuZXIncyBvYmplY3RzIGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIKKyAgICAgKiB0eXBlIGFuZCByZWdpc3RlcmVkIHRvIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0ZW5lciB0eXBlLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgYWxsIGxpc3RlbmVyJ3Mgb2JqZWN0cyBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBsaXN0ZW5lciB0eXBlIGFuZCByZWdpc3RlcmVkIHRvIHRoaXMgQ29tcG9uZW50LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8VCBleHRlbmRzIEV2ZW50TGlzdGVuZXI+IFRbXSBnZXRMaXN0ZW5lcnMoQ2xhc3M8VD4gbGlzdGVuZXJUeXBlKSB7CisgICAgICAgIGlmIChDb21wb25lbnRMaXN0ZW5lci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGxpc3RlbmVyVHlwZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAoVFtdKWdldENvbXBvbmVudExpc3RlbmVycygpOworICAgICAgICB9IGVsc2UgaWYgKEZvY3VzTGlzdGVuZXIuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShsaXN0ZW5lclR5cGUpKSB7CisgICAgICAgICAgICByZXR1cm4gKFRbXSlnZXRGb2N1c0xpc3RlbmVycygpOworICAgICAgICB9IGVsc2UgaWYgKEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20obGlzdGVuZXJUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pZ2V0SGllcmFyY2h5Qm91bmRzTGlzdGVuZXJzKCk7CisgICAgICAgIH0gZWxzZSBpZiAoSGllcmFyY2h5TGlzdGVuZXIuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShsaXN0ZW5lclR5cGUpKSB7CisgICAgICAgICAgICByZXR1cm4gKFRbXSlnZXRIaWVyYXJjaHlMaXN0ZW5lcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmIChJbnB1dE1ldGhvZExpc3RlbmVyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20obGlzdGVuZXJUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pZ2V0SW5wdXRNZXRob2RMaXN0ZW5lcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmIChLZXlMaXN0ZW5lci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGxpc3RlbmVyVHlwZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAoVFtdKWdldEtleUxpc3RlbmVycygpOworICAgICAgICB9IGVsc2UgaWYgKE1vdXNlV2hlZWxMaXN0ZW5lci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGxpc3RlbmVyVHlwZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAoVFtdKWdldE1vdXNlV2hlZWxMaXN0ZW5lcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmIChNb3VzZU1vdGlvbkxpc3RlbmVyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20obGlzdGVuZXJUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pZ2V0TW91c2VNb3Rpb25MaXN0ZW5lcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmIChNb3VzZUxpc3RlbmVyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20obGlzdGVuZXJUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pZ2V0TW91c2VMaXN0ZW5lcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmIChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20obGlzdGVuZXJUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKFRbXSlBcnJheS5uZXdJbnN0YW5jZShsaXN0ZW5lclR5cGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgcGFpbnQgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NQYWludEV2ZW50KFBhaW50RXZlbnQgZXZlbnQpIHsKKyAgICAgICAgaWYgKHJlZHJhd01hbmFnZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFJlY3RhbmdsZSBjbGlwUmVjdCA9IGV2ZW50LmdldFVwZGF0ZVJlY3QoKTsKKyAgICAgICAgaWYgKChjbGlwUmVjdC53aWR0aCA8PSAwKSB8fCAoY2xpcFJlY3QuaGVpZ2h0IDw9IDApKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgR3JhcGhpY3MgZyA9IGdldEdyYXBoaWNzKCk7CisgICAgICAgIGlmIChnID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbml0R3JhcGhpY3MoZywgZXZlbnQpOworICAgICAgICBpZiAoIWdldElnbm9yZVJlcGFpbnQoKSkgeworICAgICAgICAgICAgaWYgKGV2ZW50LmdldElEKCkgPT0gUGFpbnRFdmVudC5QQUlOVCkgeworICAgICAgICAgICAgICAgIHBhaW50KGcpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB1cGRhdGUoZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZy5kaXNwb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdHMgdGhlIGdyYXBoaWNzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgZy4KKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUuCisgICAgICovCisgICAgdm9pZCBpbml0R3JhcGhpY3MoR3JhcGhpY3MgZywgUGFpbnRFdmVudCBlKSB7CisgICAgICAgIFJlY3RhbmdsZSBjbGlwID0gZS5nZXRVcGRhdGVSZWN0KCk7CisgICAgICAgIGlmIChjbGlwIGluc3RhbmNlb2YgQ2xpcFJlZ2lvbikgeworICAgICAgICAgICAgZy5zZXRDbGlwKCgoQ2xpcFJlZ2lvbiljbGlwKS5nZXRDbGlwKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZy5zZXRDbGlwKGNsaXApOworICAgICAgICB9CisgICAgICAgIGlmIChpc1ByZXBhaW50ZXIoKSkgeworICAgICAgICAgICAgcHJlcGFpbnQoZyk7CisgICAgICAgIH0gZWxzZSBpZiAoIWlzTGlnaHR3ZWlnaHQoKSAmJiAoZS5nZXRJRCgpID09IFBhaW50RXZlbnQuUEFJTlQpKSB7CisgICAgICAgICAgICBnLnNldENvbG9yKGdldEJhY2tncm91bmQoKSk7CisgICAgICAgICAgICBnLmZpbGxSZWN0KDAsIDAsIHcsIGgpOworICAgICAgICB9CisgICAgICAgIGcuc2V0Rm9udChnZXRGb250KCkpOworICAgICAgICBnLnNldENvbG9yKGdldEZvcmVncm91bmQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5hYmxlcyB0aGUgZXZlbnRzIHdpdGggdGhlIHNwZWNpZmllZCBldmVudCBtYXNrIHRvIGJlIGRlbGl2ZXJlZCB0byB0aGlzCisgICAgICogY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudHNUb0VuYWJsZQorICAgICAqICAgICAgICAgICAgdGhlIGV2ZW50cyBtYXNrIHdoaWNoIHNwZWNpZmllcyB0aGUgdHlwZXMgb2YgZXZlbnRzIHRvIGVuYWJsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmFibGVFdmVudHMobG9uZyBldmVudHNUb0VuYWJsZSkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVuYWJsZWRFdmVudHMgfD0gZXZlbnRzVG9FbmFibGU7CisgICAgICAgICAgICBkZXByZWNhdGVkRXZlbnRIYW5kbGVyID0gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5hYmxlIGF3dCBldmVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50c1RvRW5hYmxlCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnRzIHRvIGVuYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5hYmxlQVdURXZlbnRzKGxvbmcgZXZlbnRzVG9FbmFibGUpIHsKKyAgICAgICAgZW5hYmxlZEFXVEV2ZW50cyB8PSBldmVudHNUb0VuYWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcyB0aGUgZXZlbnRzIHdpdGggdHlwZXMgc3BlY2lmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgZXZlbnQgbWFzayBmcm9tCisgICAgICogYmVpbmcgZGVsaXZlcmVkIHRvIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudHNUb0Rpc2FibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBldmVudCBtYXNrIHNwZWNpZnlpbmcgdGhlIGV2ZW50IHR5cGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGRpc2FibGVFdmVudHMobG9uZyBldmVudHNUb0Rpc2FibGUpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbmFibGVkRXZlbnRzICY9IH5ldmVudHNUb0Rpc2FibGU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGb3IgdXNlIGluIE1vdXNlRGlzcGF0Y2hlciBvbmx5LiBSZWFsbHkgaXQgY2hlY2tzIG5vdCBvbmx5IG1vdXNlIGV2ZW50cy4KKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgaXMgbW91c2UgZXZlbnQgZW5hYmxlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZlbnRNYXNrCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgbWFzay4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGlzIG1vdXNlIGV2ZW50IGVuYWJsZWQuCisgICAgICovCisgICAgYm9vbGVhbiBpc01vdXNlRXZlbnRFbmFibGVkKGxvbmcgZXZlbnRNYXNrKSB7CisgICAgICAgIHJldHVybiAoaXNFdmVudEVuYWJsZWQoZXZlbnRNYXNrKSB8fCAoZW5hYmxlZEFXVEV2ZW50cyAmIGV2ZW50TWFzaykgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGlzIGV2ZW50IGVuYWJsZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50TWFzaworICAgICAqICAgICAgICAgICAgdGhlIGV2ZW50IG1hc2suCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBldmVudCBlbmFibGVkLgorICAgICAqLworICAgIGJvb2xlYW4gaXNFdmVudEVuYWJsZWQobG9uZyBldmVudE1hc2spIHsKKyAgICAgICAgcmV0dXJuICgoZW5hYmxlZEV2ZW50cyAmIGV2ZW50TWFzaykgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyBpbnB1dCBtZXRob2Qgc3VwcG9ydCBmb3IgdGhpcyBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVuYWJsZQorICAgICAqICAgICAgICAgICAgdHJ1ZSB0byBlbmFibGUgaW5wdXQgbWV0aG9kIHN1cHBvcnQsIGZhbHNlIHRvIGRpc2FibGUgaXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5hYmxlSW5wdXRNZXRob2RzKGJvb2xlYW4gZW5hYmxlKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFlbmFibGUpIHsKKyAgICAgICAgICAgICAgICByZW1vdmVOb3RpZnlJbnB1dENvbnRleHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlucHV0TWV0aG9kc0VuYWJsZWQgPSBlbmFibGU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBhbGwgY29tcG9uZW50J3MgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgYWxsIGNvbXBvbmVudCdzIGxpc3RlbmVycyByZWdpc3RlcmVkIGZvciB0aGlzCisgICAgICogICAgICAgICBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIENvbXBvbmVudExpc3RlbmVyW10gZ2V0Q29tcG9uZW50TGlzdGVuZXJzKCkgeworICAgICAgICByZXR1cm4gY29tcG9uZW50TGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMobmV3IENvbXBvbmVudExpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgY29tcG9uZW50IGxpc3RlbmVyIHRvIHRoZSBDb21wb25lbnQgZm9yIHJlY2VpdmluZworICAgICAqIGNvbXBvbmVudCdzIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgQ29tcG9uZW50TGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQ29tcG9uZW50TGlzdGVuZXIoQ29tcG9uZW50TGlzdGVuZXIgbCkgeworICAgICAgICBjb21wb25lbnRMaXN0ZW5lcnMuYWRkVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGNvbXBvbmVudCBsaXN0ZW5lciByZWdpc3RlcmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIENvbXBvbmVudExpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUNvbXBvbmVudExpc3RlbmVyKENvbXBvbmVudExpc3RlbmVyIGwpIHsKKyAgICAgICAgY29tcG9uZW50TGlzdGVuZXJzLnJlbW92ZVVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSBjb21wb25lbnQgZXZlbnQgdGhhdCBoYXMgb2NjdXJyZWQgb24gdGhpcyBjb21wb25lbnQgYnkKKyAgICAgKiBkaXNwYXRjaGluZyB0aGVtIHRvIGFueSByZWdpc3RlcmVkIENvbXBvbmVudExpc3RlbmVyIG9iamVjdHMuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb21wb25lbnRFdmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzQ29tcG9uZW50RXZlbnQoQ29tcG9uZW50RXZlbnQgZSkgeworICAgICAgICBwcm9jZXNzQ29tcG9uZW50RXZlbnRJbXBsKGUsIGNvbXBvbmVudExpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgY29tcG9uZW50IGV2ZW50IGltcGwuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgYy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0NvbXBvbmVudEV2ZW50SW1wbChDb21wb25lbnRFdmVudCBlLCBDb2xsZWN0aW9uPENvbXBvbmVudExpc3RlbmVyPiBjKSB7CisgICAgICAgIGZvciAoQ29tcG9uZW50TGlzdGVuZXIgbGlzdGVuZXIgOiBjKSB7CisgICAgICAgICAgICBzd2l0Y2ggKGUuZ2V0SUQoKSkgeworICAgICAgICAgICAgICAgIGNhc2UgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX0hJRERFTjoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuY29tcG9uZW50SGlkZGVuKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9NT1ZFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuY29tcG9uZW50TW92ZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX1JFU0laRUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNvbXBvbmVudFJlc2l6ZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX1NIT1dOOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5jb21wb25lbnRTaG93bihlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIGZvY3VzIGxpc3RlbmVycyByZWdpc3RlcmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBmb2N1cyBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCBmb3IgdGhpcyBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIEZvY3VzTGlzdGVuZXJbXSBnZXRGb2N1c0xpc3RlbmVycygpIHsKKyAgICAgICAgcmV0dXJuIGZvY3VzTGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMobmV3IEZvY3VzTGlzdGVuZXJbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBmb2N1cyBsaXN0ZW5lciB0byB0aGUgQ29tcG9uZW50IGZvciByZWNlaXZpbmcgZm9jdXMKKyAgICAgKiBldmVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb2N1c0xpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEZvY3VzTGlzdGVuZXIoRm9jdXNMaXN0ZW5lciBsKSB7CisgICAgICAgIGZvY3VzTGlzdGVuZXJzLmFkZFVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBhd3QgZm9jdXMgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsLgorICAgICAqLworICAgIHZvaWQgYWRkQVdURm9jdXNMaXN0ZW5lcihGb2N1c0xpc3RlbmVyIGwpIHsKKyAgICAgICAgZW5hYmxlQVdURXZlbnRzKEFXVEV2ZW50LkZPQ1VTX0VWRU5UX01BU0spOworICAgICAgICBmb2N1c0xpc3RlbmVycy5hZGRTeXN0ZW1MaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBmb2N1cyBsaXN0ZW5lciByZWdpc3RlcmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIEZvY3VzTGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlRm9jdXNMaXN0ZW5lcihGb2N1c0xpc3RlbmVyIGwpIHsKKyAgICAgICAgZm9jdXNMaXN0ZW5lcnMucmVtb3ZlVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBhIEZvY3VzRXZlbnQgdGhhdCBoYXMgb2NjdXJyZWQgb24gdGhpcyBjb21wb25lbnQgYnkgZGlzcGF0Y2hpbmcKKyAgICAgKiBpdCB0byB0aGUgcmVnaXN0ZXJlZCBsaXN0ZW5lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb2N1c0V2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NGb2N1c0V2ZW50KEZvY3VzRXZlbnQgZSkgeworICAgICAgICBwcm9jZXNzRm9jdXNFdmVudEltcGwoZSwgZm9jdXNMaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzIGZvY3VzIGV2ZW50IGltcGwuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgYy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0ZvY3VzRXZlbnRJbXBsKEZvY3VzRXZlbnQgZSwgQ29sbGVjdGlvbjxGb2N1c0xpc3RlbmVyPiBjKSB7CisgICAgICAgIGZvciAoRm9jdXNMaXN0ZW5lciBsaXN0ZW5lciA6IGMpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRJRCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBGb2N1c0V2ZW50LkZPQ1VTX0dBSU5FRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuZm9jdXNHYWluZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRm9jdXNFdmVudC5GT0NVU19MT1NUOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5mb2N1c0xvc3QoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiByZWdpc3RlcmVkIEhpZXJhcmNoeUxpc3RlbmVycyBmb3IgdGhpcyBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiByZWdpc3RlcmVkIEhpZXJhcmNoeUxpc3RlbmVycyBmb3IgdGhpcyBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIEhpZXJhcmNoeUxpc3RlbmVyW10gZ2V0SGllcmFyY2h5TGlzdGVuZXJzKCkgeworICAgICAgICByZXR1cm4gaGllcmFyY2h5TGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMobmV3IEhpZXJhcmNoeUxpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgaGllcmFyY2h5IGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgSGllcmFyY2h5TGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkSGllcmFyY2h5TGlzdGVuZXIoSGllcmFyY2h5TGlzdGVuZXIgbCkgeworICAgICAgICBoaWVyYXJjaHlMaXN0ZW5lcnMuYWRkVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGhpZXJhcmNoeSBsaXN0ZW5lciByZWdpc3RlcmVkIGZvciB0aGlzIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIEhpZXJhcmNoeUxpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUhpZXJhcmNoeUxpc3RlbmVyKEhpZXJhcmNoeUxpc3RlbmVyIGwpIHsKKyAgICAgICAgaGllcmFyY2h5TGlzdGVuZXJzLnJlbW92ZVVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSBoaWVyYXJjaHkgZXZlbnQgdGhhdCBoYXMgb2NjdXJyZWQgb24gdGhpcyBjb21wb25lbnQgYnkKKyAgICAgKiBkaXNwYXRjaGluZyBpdCB0byB0aGUgcmVnaXN0ZXJlZCBsaXN0ZW5lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBIaWVyYXJjaHlFdmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzSGllcmFyY2h5RXZlbnQoSGllcmFyY2h5RXZlbnQgZSkgeworICAgICAgICBmb3IgKEhpZXJhcmNoeUxpc3RlbmVyIGxpc3RlbmVyIDogaGllcmFyY2h5TGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMoKSkgeworICAgICAgICAgICAgc3dpdGNoIChlLmdldElEKCkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIEhpZXJhcmNoeUV2ZW50LkhJRVJBUkNIWV9DSEFOR0VEOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5oaWVyYXJjaHlDaGFuZ2VkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgSGllcmFyY2h5Qm91bmRzTGlzdGVuZXIgb2JqZWN0cyByZWdpc3RlcmVkIHRvIHRoaXMKKyAgICAgKiBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lciBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyBIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lcltdIGdldEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVycygpIHsKKyAgICAgICAgcmV0dXJuIGhpZXJhcmNoeUJvdW5kc0xpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKG5ldyBIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lclswXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGhpZXJhcmNoeSBib3VuZHMgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lcihIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lciBsKSB7CisgICAgICAgIGhpZXJhcmNoeUJvdW5kc0xpc3RlbmVycy5hZGRVc2VyTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgaGllcmFyY2h5IGJvdW5kcyBsaXN0ZW5lciByZWdpc3RlcmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyKEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyIGwpIHsKKyAgICAgICAgaGllcmFyY2h5Qm91bmRzTGlzdGVuZXJzLnJlbW92ZVVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSBoaWVyYXJjaHkgYm91bmRzIGV2ZW50IHRoYXQgaGFzIG9jY3VycmVkIG9uIHRoaXMgY29tcG9uZW50IGJ5CisgICAgICogZGlzcGF0Y2hpbmcgaXQgdG8gdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgSGllcmFyY2h5Qm91bmRzRXZlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0hpZXJhcmNoeUJvdW5kc0V2ZW50KEhpZXJhcmNoeUV2ZW50IGUpIHsKKyAgICAgICAgZm9yIChIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lciBsaXN0ZW5lciA6IGhpZXJhcmNoeUJvdW5kc0xpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKCkpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRJRCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBIaWVyYXJjaHlFdmVudC5BTkNFU1RPUl9NT1ZFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuYW5jZXN0b3JNb3ZlZChlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBIaWVyYXJjaHlFdmVudC5BTkNFU1RPUl9SRVNJWkVEOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5hbmNlc3RvclJlc2l6ZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUga2V5IGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUga2V5IGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZSBDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIEtleUxpc3RlbmVyW10gZ2V0S2V5TGlzdGVuZXJzKCkgeworICAgICAgICByZXR1cm4ga2V5TGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMobmV3IEtleUxpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQga2V5IGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgS2V5TGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkS2V5TGlzdGVuZXIoS2V5TGlzdGVuZXIgbCkgeworICAgICAgICBrZXlMaXN0ZW5lcnMuYWRkVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIGF3dCBrZXkgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsLgorICAgICAqLworICAgIHZvaWQgYWRkQVdUS2V5TGlzdGVuZXIoS2V5TGlzdGVuZXIgbCkgeworICAgICAgICBlbmFibGVBV1RFdmVudHMoQVdURXZlbnQuS0VZX0VWRU5UX01BU0spOworICAgICAgICBrZXlMaXN0ZW5lcnMuYWRkU3lzdGVtTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUga2V5IGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoaXMgQ29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgS2V5TGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlS2V5TGlzdGVuZXIoS2V5TGlzdGVuZXIgbCkgeworICAgICAgICBrZXlMaXN0ZW5lcnMucmVtb3ZlVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBhIGtleSBldmVudCB0aGF0IGhhcyBvY2N1cnJlZCBvbiB0aGlzIGNvbXBvbmVudCBieSBkaXNwYXRjaGluZworICAgICAqIGl0IHRvIHRoZSByZWdpc3RlcmVkIGxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIEtleUV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NLZXlFdmVudChLZXlFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NLZXlFdmVudEltcGwoZSwga2V5TGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBrZXkgZXZlbnQgaW1wbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUuCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzS2V5RXZlbnRJbXBsKEtleUV2ZW50IGUsIENvbGxlY3Rpb248S2V5TGlzdGVuZXI+IGMpIHsKKyAgICAgICAgZm9yIChLZXlMaXN0ZW5lciBsaXN0ZW5lciA6IGMpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRJRCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBLZXlFdmVudC5LRVlfUFJFU1NFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIua2V5UHJlc3NlZChlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBLZXlFdmVudC5LRVlfUkVMRUFTRUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmtleVJlbGVhc2VkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIEtleUV2ZW50LktFWV9UWVBFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIua2V5VHlwZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgbW91c2UgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgdG8gdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBtb3VzZSBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCB0byB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBNb3VzZUxpc3RlbmVyW10gZ2V0TW91c2VMaXN0ZW5lcnMoKSB7CisgICAgICAgIHJldHVybiBtb3VzZUxpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKG5ldyBNb3VzZUxpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgbW91c2UgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBNb3VzZUxpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZE1vdXNlTGlzdGVuZXIoTW91c2VMaXN0ZW5lciBsKSB7CisgICAgICAgIG1vdXNlTGlzdGVuZXJzLmFkZFVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBhd3QgbW91c2UgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsLgorICAgICAqLworICAgIHZvaWQgYWRkQVdUTW91c2VMaXN0ZW5lcihNb3VzZUxpc3RlbmVyIGwpIHsKKyAgICAgICAgZW5hYmxlQVdURXZlbnRzKEFXVEV2ZW50Lk1PVVNFX0VWRU5UX01BU0spOworICAgICAgICBtb3VzZUxpc3RlbmVycy5hZGRTeXN0ZW1MaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBhd3QgbW91c2UgbW90aW9uIGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgbC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZEFXVE1vdXNlTW90aW9uTGlzdGVuZXIoTW91c2VNb3Rpb25MaXN0ZW5lciBsKSB7CisgICAgICAgIGVuYWJsZUFXVEV2ZW50cyhBV1RFdmVudC5NT1VTRV9NT1RJT05fRVZFTlRfTUFTSyk7CisgICAgICAgIG1vdXNlTW90aW9uTGlzdGVuZXJzLmFkZFN5c3RlbUxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIGF3dCBjb21wb25lbnQgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsLgorICAgICAqLworICAgIHZvaWQgYWRkQVdUQ29tcG9uZW50TGlzdGVuZXIoQ29tcG9uZW50TGlzdGVuZXIgbCkgeworICAgICAgICBlbmFibGVBV1RFdmVudHMoQVdURXZlbnQuQ09NUE9ORU5UX0VWRU5UX01BU0spOworICAgICAgICBjb21wb25lbnRMaXN0ZW5lcnMuYWRkU3lzdGVtTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgYXd0IGlucHV0IG1ldGhvZCBsaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGwuCisgICAgICovCisgICAgdm9pZCBhZGRBV1RJbnB1dE1ldGhvZExpc3RlbmVyKElucHV0TWV0aG9kTGlzdGVuZXIgbCkgeworICAgICAgICBlbmFibGVBV1RFdmVudHMoQVdURXZlbnQuSU5QVVRfTUVUSE9EX0VWRU5UX01BU0spOworICAgICAgICBpbnB1dE1ldGhvZExpc3RlbmVycy5hZGRTeXN0ZW1MaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBhd3QgbW91c2Ugd2hlZWwgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsLgorICAgICAqLworICAgIHZvaWQgYWRkQVdUTW91c2VXaGVlbExpc3RlbmVyKE1vdXNlV2hlZWxMaXN0ZW5lciBsKSB7CisgICAgICAgIGVuYWJsZUFXVEV2ZW50cyhBV1RFdmVudC5NT1VTRV9XSEVFTF9FVkVOVF9NQVNLKTsKKyAgICAgICAgbW91c2VXaGVlbExpc3RlbmVycy5hZGRTeXN0ZW1MaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtb3VzZSBsaXN0ZW5lciByZWdpc3RlcmVkIGZvciB0aGlzIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIE1vdXNlTGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlTW91c2VMaXN0ZW5lcihNb3VzZUxpc3RlbmVyIGwpIHsKKyAgICAgICAgbW91c2VMaXN0ZW5lcnMucmVtb3ZlVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBhIG1vdXNlIGV2ZW50IHRoYXQgaGFzIG9jY3VycmVkIG9uIHRoaXMgY29tcG9uZW50IGJ5CisgICAgICogZGlzcGF0Y2hpbmcgaXQgdG8gdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgTW91c2VFdmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTW91c2VFdmVudChNb3VzZUV2ZW50IGUpIHsKKyAgICAgICAgcHJvY2Vzc01vdXNlRXZlbnRJbXBsKGUsIG1vdXNlTGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBtb3VzZSBldmVudCBpbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZS4KKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NNb3VzZUV2ZW50SW1wbChNb3VzZUV2ZW50IGUsIENvbGxlY3Rpb248TW91c2VMaXN0ZW5lcj4gYykgeworICAgICAgICBmb3IgKE1vdXNlTGlzdGVuZXIgbGlzdGVuZXIgOiBjKSB7CisgICAgICAgICAgICBzd2l0Y2ggKGUuZ2V0SUQoKSkgeworICAgICAgICAgICAgICAgIGNhc2UgTW91c2VFdmVudC5NT1VTRV9DTElDS0VEOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5tb3VzZUNsaWNrZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgTW91c2VFdmVudC5NT1VTRV9FTlRFUkVEOgorICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5tb3VzZUVudGVyZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgTW91c2VFdmVudC5NT1VTRV9FWElURUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLm1vdXNlRXhpdGVkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIE1vdXNlRXZlbnQuTU9VU0VfUFJFU1NFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubW91c2VQcmVzc2VkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIE1vdXNlRXZlbnQuTU9VU0VfUkVMRUFTRUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLm1vdXNlUmVsZWFzZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBtb3VzZSBtb3Rpb24gZXZlbnQgaW1wbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGUuCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzTW91c2VNb3Rpb25FdmVudEltcGwoTW91c2VFdmVudCBlLCBDb2xsZWN0aW9uPE1vdXNlTW90aW9uTGlzdGVuZXI+IGMpIHsKKyAgICAgICAgZm9yIChNb3VzZU1vdGlvbkxpc3RlbmVyIGxpc3RlbmVyIDogYykgeworICAgICAgICAgICAgc3dpdGNoIChlLmdldElEKCkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIE1vdXNlRXZlbnQuTU9VU0VfRFJBR0dFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubW91c2VEcmFnZ2VkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIE1vdXNlRXZlbnQuTU9VU0VfTU9WRUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLm1vdXNlTW92ZWQoZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgbW91c2UgbW90aW9uIGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZSBDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgTW91c2VNb3Rpb25MaXN0ZW5lcnMgcmVnaXN0ZXJlZCB0byB0aGUgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBNb3VzZU1vdGlvbkxpc3RlbmVyW10gZ2V0TW91c2VNb3Rpb25MaXN0ZW5lcnMoKSB7CisgICAgICAgIHJldHVybiBtb3VzZU1vdGlvbkxpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKG5ldyBNb3VzZU1vdGlvbkxpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgbW91c2UgbW90aW9uIGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgTW91c2VNb3Rpb25MaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRNb3VzZU1vdGlvbkxpc3RlbmVyKE1vdXNlTW90aW9uTGlzdGVuZXIgbCkgeworICAgICAgICBtb3VzZU1vdGlvbkxpc3RlbmVycy5hZGRVc2VyTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgbW91c2UgbW90aW9uIGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgTW91c2VNb3Rpb25MaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVNb3VzZU1vdGlvbkxpc3RlbmVyKE1vdXNlTW90aW9uTGlzdGVuZXIgbCkgeworICAgICAgICBtb3VzZU1vdGlvbkxpc3RlbmVycy5yZW1vdmVVc2VyTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIGEgbW91c2UgbW90aW9uIGV2ZW50IHRoYXQgaGFzIG9jY3VycmVkIG9uIHRoaXMgY29tcG9uZW50IGJ5CisgICAgICogZGlzcGF0Y2hpbmcgaXQgdG8gdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgTW91c2VFdmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTW91c2VNb3Rpb25FdmVudChNb3VzZUV2ZW50IGUpIHsKKyAgICAgICAgcHJvY2Vzc01vdXNlTW90aW9uRXZlbnRJbXBsKGUsIG1vdXNlTW90aW9uTGlzdGVuZXJzLmdldFVzZXJMaXN0ZW5lcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgbW91c2Ugd2hlZWwgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgdG8gdGhlIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBNb3VzZVdoZWVsTGlzdGVuZXJzIHJlZ2lzdGVyZWQgdG8gdGhlIENvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTW91c2VXaGVlbExpc3RlbmVyW10gZ2V0TW91c2VXaGVlbExpc3RlbmVycygpIHsKKyAgICAgICAgcmV0dXJuIG1vdXNlV2hlZWxMaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycyhuZXcgTW91c2VXaGVlbExpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgbW91c2Ugd2hlZWwgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBNb3VzZVdoZWVsTGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkTW91c2VXaGVlbExpc3RlbmVyKE1vdXNlV2hlZWxMaXN0ZW5lciBsKSB7CisgICAgICAgIG1vdXNlV2hlZWxMaXN0ZW5lcnMuYWRkVXNlckxpc3RlbmVyKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG1vdXNlIHdoZWVsIGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgTW91c2VXaGVlbExpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZU1vdXNlV2hlZWxMaXN0ZW5lcihNb3VzZVdoZWVsTGlzdGVuZXIgbCkgeworICAgICAgICBtb3VzZVdoZWVsTGlzdGVuZXJzLnJlbW92ZVVzZXJMaXN0ZW5lcihsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSBtb3VzZSB3aGVlbCBldmVudCB0aGF0IGhhcyBvY2N1cnJlZCBvbiB0aGlzIGNvbXBvbmVudCBieQorICAgICAqIGRpc3BhdGNoaW5nIGl0IHRvIHRoZSByZWdpc3RlcmVkIGxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIE1vdXNlV2hlZWxFdmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTW91c2VXaGVlbEV2ZW50KE1vdXNlV2hlZWxFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NNb3VzZVdoZWVsRXZlbnRJbXBsKGUsIG1vdXNlV2hlZWxMaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHRoZSBJbnB1dE1ldGhvZExpc3RlbmVyIGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZQorICAgICAqIENvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBJbnB1dE1ldGhvZExpc3RlbmVyIGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZQorICAgICAqICAgICAgICAgQ29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dE1ldGhvZExpc3RlbmVyW10gZ2V0SW5wdXRNZXRob2RMaXN0ZW5lcnMoKSB7CisgICAgICAgIHJldHVybiBpbnB1dE1ldGhvZExpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKG5ldyBJbnB1dE1ldGhvZExpc3RlbmVyWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgaW5wdXQgbWV0aG9kIGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgSW5wdXRNZXRob2RMaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRJbnB1dE1ldGhvZExpc3RlbmVyKElucHV0TWV0aG9kTGlzdGVuZXIgbCkgeworICAgICAgICBpbnB1dE1ldGhvZExpc3RlbmVycy5hZGRVc2VyTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgaW5wdXQgbWV0aG9kIGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoaXMgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgSW5wdXRNZXRob2RMaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJbnB1dE1ldGhvZExpc3RlbmVyKElucHV0TWV0aG9kTGlzdGVuZXIgbCkgeworICAgICAgICBpbnB1dE1ldGhvZExpc3RlbmVycy5yZW1vdmVVc2VyTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIGFuIGlucHV0IG1ldGhvZCBldmVudCB0aGF0IGhhcyBvY2N1cnJlZCBvbiB0aGlzIGNvbXBvbmVudCBieQorICAgICAqIGRpc3BhdGNoaW5nIGl0IHRvIHRoZSByZWdpc3RlcmVkIGxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIElucHV0TWV0aG9kRXZlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0lucHV0TWV0aG9kRXZlbnQoSW5wdXRNZXRob2RFdmVudCBlKSB7CisgICAgICAgIHByb2Nlc3NJbnB1dE1ldGhvZEV2ZW50SW1wbChlLCBpbnB1dE1ldGhvZExpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgaW5wdXQgbWV0aG9kIGV2ZW50IGltcGwuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgYy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0lucHV0TWV0aG9kRXZlbnRJbXBsKElucHV0TWV0aG9kRXZlbnQgZSwgQ29sbGVjdGlvbjxJbnB1dE1ldGhvZExpc3RlbmVyPiBjKSB7CisgICAgICAgIGZvciAoSW5wdXRNZXRob2RMaXN0ZW5lciBsaXN0ZW5lciA6IGMpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRJRCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBJbnB1dE1ldGhvZEV2ZW50LkNBUkVUX1BPU0lUSU9OX0NIQU5HRUQ6CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhcmV0UG9zaXRpb25DaGFuZ2VkKGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIElucHV0TWV0aG9kRXZlbnQuSU5QVVRfTUVUSE9EX1RFWFRfQ0hBTkdFRDoKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuaW5wdXRNZXRob2RUZXh0Q2hhbmdlZChlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHB1YmxpYyBQb2ludCBnZXRNb3VzZVBvc2l0aW9uKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsgUG9pbnQKKyAgICAgKiBhYnNQb2ludGVyUG9zID0gTW91c2VJbmZvLmdldFBvaW50ZXJJbmZvKCkuZ2V0TG9jYXRpb24oKTsgV2luZG93CisgICAgICogd2luVW5kZXJQdHIgPQorICAgICAqIHRvb2xraXQuZGlzcGF0Y2hlci5tb3VzZURpc3BhdGNoZXIuZmluZFdpbmRvd0F0KGFic1BvaW50ZXJQb3MpOyBQb2ludAorICAgICAqIHBvaW50ZXJQb3MgPSBNb3VzZURpc3BhdGNoZXIuY29udmVydFBvaW50KG51bGwsIGFic1BvaW50ZXJQb3MsCisgICAgICogd2luVW5kZXJQdHIpOyBib29sZWFuIGlzVW5kZXJQb2ludGVyID0gZmFsc2U7IGlmICh3aW5VbmRlclB0ciA9PSBudWxsKSB7CisgICAgICogcmV0dXJuIG51bGw7IH0gaXNVbmRlclBvaW50ZXIgPSB3aW5VbmRlclB0ci5pc0NvbXBvbmVudEF0KHRoaXMsCisgICAgICogcG9pbnRlclBvcyk7IGlmIChpc1VuZGVyUG9pbnRlcikgeyByZXR1cm4KKyAgICAgKiBNb3VzZURpc3BhdGNoZXIuY29udmVydFBvaW50KG51bGwsIGFic1BvaW50ZXJQb3MsIHRoaXMpOyB9IHJldHVybiBudWxsOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBTZXQgbmF0aXZlIGNhcmV0IGF0IHRoZSBnaXZlbiBwb3NpdGlvbiA8YnI+CisgICAgICogTm90ZTogdGhpcyBtZXRob2QgdGFrZXMgQVdUIGxvY2sgaW5zaWRlIGJlY2F1c2UgaXQgd2Fsa3MgdGhyb3VnaCB0aGUKKyAgICAgKiBjb21wb25lbnQgaGllcmFyY2h5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkuCisgICAgICovCisgICAgdm9pZCBzZXRDYXJldFBvcyhmaW5hbCBpbnQgeCwgZmluYWwgaW50IHkpIHsKKyAgICAgICAgUnVubmFibGUgciA9IG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXRDYXJldFBvc0ltcGwoeCwgeSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIGlmIChUaHJlYWQuY3VycmVudFRocmVhZCgpIGluc3RhbmNlb2YgRXZlbnREaXNwYXRjaFRocmVhZCkgeworICAgICAgICAgICAgci5ydW4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRvb2xraXQuZ2V0U3lzdGVtRXZlbnRRdWV1ZUltcGwoKS5wb3N0RXZlbnQobmV3IEludm9jYXRpb25FdmVudCh0aGlzLCByKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgYXQgZXZlbnQgZGlzcGF0Y2ggdGhyZWFkLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkuCisgICAgICovCisgICAgdm9pZCBzZXRDYXJldFBvc0ltcGwoaW50IHgsIGludCB5KSB7CisgICAgICAgIENvbXBvbmVudCBjID0gdGhpczsKKyAgICAgICAgd2hpbGUgKChjICE9IG51bGwpICYmIGMuYmVoYXZpb3VyLmlzTGlnaHR3ZWlnaHQoKSkgeworICAgICAgICAgICAgeCArPSBjLng7CisgICAgICAgICAgICB5ICs9IGMueTsKKyAgICAgICAgICAgIC8vID8/P0FXVDogYyA9IGMuZ2V0UGFyZW50KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIC8vID8/P0FXVAorICAgICAgICAvKgorICAgICAgICAgKiBpZiAoYyBpbnN0YW5jZW9mIFdpbmRvdykgeyBJbnNldHMgaW5zZXRzID0gYy5nZXROYXRpdmVJbnNldHMoKTsgeCAtPQorICAgICAgICAgKiBpbnNldHMubGVmdDsgeSAtPSBpbnNldHMudG9wOyB9CisgICAgICAgICAqIHRvb2xraXQuZ2V0V2luZG93RmFjdG9yeSgpLnNldENhcmV0UG9zaXRpb24oeCwgeSk7CisgICAgICAgICAqLworICAgIH0KKworICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3RhbmRhcmQgY29tcG9uZW50cyBzdWNoIGFzIEJ1dHRvbiBhbmQgTGlzdAorICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgbWluaW11bSBzaXplLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgbWluaW11bSBzaXplLgorICAgICAqLworICAgIERpbWVuc2lvbiBnZXREZWZhdWx0TWluaW11bVNpemUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3RhbmRhcmQgY29tcG9uZW50cyBzdWNoIGFzIEJ1dHRvbiBhbmQgTGlzdAorICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgcHJlZmVycmVkIHNpemUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBwcmVmZXJyZWQgc2l6ZS4KKyAgICAgKi8KKyAgICBEaW1lbnNpb24gZ2V0RGVmYXVsdFByZWZlcnJlZFNpemUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3RhbmRhcmQgY29tcG9uZW50cyBzdWNoIGFzIEJ1dHRvbiBhbmQgTGlzdAorICAgIC8qKgorICAgICAqIFJlc2V0IGRlZmF1bHQgc2l6ZS4KKyAgICAgKi8KKyAgICB2b2lkIHJlc2V0RGVmYXVsdFNpemUoKSB7CisgICAgfQorCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBDb21wb25lbnRCZWhhdmlvciBjcmVhdGVCZWhhdmlvcigpIHsgcmV0dXJuIG5ldyBMV0JlaGF2aW9yKHRoaXMpOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IGJhY2tncm91bmQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBiYWNrZ3JvdW5kLgorICAgICAqLworICAgIENvbG9yIGdldERlZmF1bHRCYWNrZ3JvdW5kKCkgeworICAgICAgICAvLyA/Pz9BV1Q6IHJldHVybiBnZXRXaW5kb3dBbmNlc3RvcigpLmdldERlZmF1bHRCYWNrZ3JvdW5kKCk7CisgICAgICAgIHJldHVybiBnZXRCYWNrZ3JvdW5kKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBmb3JlZ3JvdW5kLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgZm9yZWdyb3VuZC4KKyAgICAgKi8KKyAgICBDb2xvciBnZXREZWZhdWx0Rm9yZWdyb3VuZCgpIHsKKyAgICAgICAgLy8gPz8/QVdUIHJldHVybiBnZXRXaW5kb3dBbmNlc3RvcigpLmdldERlZmF1bHRGb3JlZ3JvdW5kKCk7CisgICAgICAgIHJldHVybiBnZXRGb3JlZ3JvdW5kKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIHdoZW4gbmF0aXZlIHJlc291cmNlIGZvciB0aGlzIGNvbXBvbmVudCBpcyBjcmVhdGVkIChmb3IKKyAgICAgKiBoZWF2eXdlaWdodHMgb25seSkuCisgICAgICogCisgICAgICogQHBhcmFtIHdpbgorICAgICAqICAgICAgICAgICAgdGhlIHdpbi4KKyAgICAgKi8KKyAgICB2b2lkIG5hdGl2ZVdpbmRvd0NyZWF0ZWQoTmF0aXZlV2luZG93IHdpbikgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lIHRoZSBjb21wb25lbnQncyBhcmVhIGhpZGRlbiBiZWhpbmQgdGhlIHdpbmRvd3MgdGhhdCBoYXZlIGhpZ2hlcgorICAgICAqIFotb3JkZXIsIGluY2x1ZGluZyB3aW5kb3dzIG9mIG90aGVyIGFwcGxpY2F0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gZGVzdExvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgZGVzdCBsb2NhdGlvbi4KKyAgICAgKiBAcGFyYW0gZGVzdFNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0IHNpemUuCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjYWxjdWxhdGVkIHJlZ2lvbiwgb3IgbnVsbCBpZiBpdCBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIE11bHRpUmVjdEFyZWEgZ2V0T2JzY3VyZWRSZWdpb24oUmVjdGFuZ2xlIHBhcnQpIHsgaWYgKCF2aXNpYmxlIHx8IHBhcmVudAorICAgICAqID09IG51bGwgfHwgIXBhcmVudC52aXNpYmxlKSB7IHJldHVybiBudWxsOyB9IFJlY3RhbmdsZSByID0gbmV3CisgICAgICogUmVjdGFuZ2xlKDAsIDAsIHcsIGgpOyBpZiAocGFydCAhPSBudWxsKSB7IHIgPSByLmludGVyc2VjdGlvbihwYXJ0KTsgfSBpZgorICAgICAqIChyLmlzRW1wdHkoKSkgeyByZXR1cm4gbnVsbDsgfSByLnRyYW5zbGF0ZSh4LCB5KTsgTXVsdGlSZWN0QXJlYSByZXQgPQorICAgICAqIHBhcmVudC5nZXRPYnNjdXJlZFJlZ2lvbihyKTsgaWYgKHJldCAhPSBudWxsKSB7CisgICAgICogcGFyZW50LmFkZE9ic2N1cmVkUmVnaW9ucyhyZXQsIHRoaXMpOyByZXQudHJhbnNsYXRlKC14LCAteSk7CisgICAgICogcmV0LmludGVyc2VjdChuZXcgUmVjdGFuZ2xlKDAsIDAsIHcsIGgpKTsgfSByZXR1cm4gcmV0OyB9CisgICAgICovCisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAqIENsYXNzTm90Rm91bmRFeGNlcHRpb24geyBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsgRmllbGRzQWNjZXNzb3IKKyAgICAgKiBhY2Nlc3NvciA9IG5ldyBGaWVsZHNBY2Nlc3NvcihDb21wb25lbnQuY2xhc3MsIHRoaXMpOworICAgICAqIGFjY2Vzc29yLnNldCgidG9vbGtpdCIsIFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgKiBhY2Nlc3Nvci5zZXQoImJlaGF2aW91ciIsIGNyZWF0ZUJlaGF2aW9yKCkpOyAvLyROT04tTkxTLTEkCisgICAgICogYWNjZXNzb3Iuc2V0KCJjb21wb25lbnRMb2NrIiwgbmV3IE9iamVjdCgpKTsgLy8gJE5PTi1MT0NLLTEkCisgICAgICogLy8kTk9OLU5MUy0xJCB9CisgICAgICovCisKKyAgICBmaW5hbCB2b2lkIG9uRHJhd0ltYWdlKEltYWdlIGltYWdlLCBQb2ludCBkZXN0TG9jYXRpb24sIERpbWVuc2lvbiBkZXN0U2l6ZSwgUmVjdGFuZ2xlIHNvdXJjZSkgeworICAgICAgICBJbWFnZVBhcmFtZXRlcnMgaW1hZ2VQYXJhbXM7CisgICAgICAgIGlmICh1cGRhdGVkSW1hZ2VzID09IG51bGwpIHsKKyAgICAgICAgICAgIHVwZGF0ZWRJbWFnZXMgPSBuZXcgSGFzaE1hcDxJbWFnZSwgSW1hZ2VQYXJhbWV0ZXJzPigpOworICAgICAgICB9CisgICAgICAgIGltYWdlUGFyYW1zID0gdXBkYXRlZEltYWdlcy5nZXQoaW1hZ2UpOworICAgICAgICBpZiAoaW1hZ2VQYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaW1hZ2VQYXJhbXMgPSBuZXcgSW1hZ2VQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICB1cGRhdGVkSW1hZ2VzLnB1dChpbWFnZSwgaW1hZ2VQYXJhbXMpOworICAgICAgICB9CisgICAgICAgIGltYWdlUGFyYW1zLmFkZERyYXdpbmcoZGVzdExvY2F0aW9uLCBkZXN0U2l6ZSwgc291cmNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbWFnZVVwZGF0ZShJbWFnZSBpbWcsIGludCBpbmZvZmxhZ3MsIGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgICAgICBpZiAoKGluZm9mbGFncyAmIChBTExCSVRTIHwgRlJBTUVCSVRTKSkgIT0gMCkgeworICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmICgoaW5mb2ZsYWdzICYgU09NRUJJVFMpICE9IDAgJiYgaW5jcmVtZW50YWxJbWFnZVVwZGF0ZSkgeworICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGRvbmUpIHsKKyAgICAgICAgICAgICAgICByZXBhaW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gKGluZm9mbGFncyAmIChBQk9SVCB8IEFMTEJJVFMpKSA9PSAwOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHJpdmF0ZSB2b2lkIGludmFsaWRhdGVSZWFsUGFyZW50KCkgeyBDb250YWluZXIgcmVhbFBhcmVudCA9CisgICAgICogZ2V0UmVhbFBhcmVudCgpOyBpZiAoKHJlYWxQYXJlbnQgIT0gbnVsbCkgJiYgcmVhbFBhcmVudC5pc1ZhbGlkKCkpIHsKKyAgICAgKiByZWFsUGFyZW50LmludmFsaWRhdGUoKTsgfSB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgSW1hZ2VQYXJhbWV0ZXJzLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgSW1hZ2VQYXJhbWV0ZXJzIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGRyYXdpbmcgcGFyYW1zLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaW5rZWRMaXN0PERyYXdpbmdQYXJhbWV0ZXJzPiBkcmF3aW5nUGFyYW1zID0gbmV3IExpbmtlZExpc3Q8RHJhd2luZ1BhcmFtZXRlcnM+KCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzaXplLgorICAgICAgICAgKi8KKyAgICAgICAgRGltZW5zaW9uIHNpemUgPSBuZXcgRGltZW5zaW9uKENvbXBvbmVudC50aGlzLncsIENvbXBvbmVudC50aGlzLmgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBBZGRzIHRoZSBkcmF3aW5nLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGRlc3RMb2NhdGlvbgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0IGxvY2F0aW9uLgorICAgICAgICAgKiBAcGFyYW0gZGVzdFNpemUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZGVzdCBzaXplLgorICAgICAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZS4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgYWRkRHJhd2luZyhQb2ludCBkZXN0TG9jYXRpb24sIERpbWVuc2lvbiBkZXN0U2l6ZSwgUmVjdGFuZ2xlIHNvdXJjZSkgeworICAgICAgICAgICAgZHJhd2luZ1BhcmFtcy5hZGQobmV3IERyYXdpbmdQYXJhbWV0ZXJzKGRlc3RMb2NhdGlvbiwgZGVzdFNpemUsIHNvdXJjZSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIERyYXdpbmcgcGFyYW1ldGVycyBpdGVyYXRvci4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdGhlIGl0ZXJhdG9yPCBkcmF3aW5nIHBhcmFtZXRlcnM+LgorICAgICAgICAgKi8KKyAgICAgICAgSXRlcmF0b3I8RHJhd2luZ1BhcmFtZXRlcnM+IGRyYXdpbmdQYXJhbWV0ZXJzSXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gZHJhd2luZ1BhcmFtcy5pdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBDbGFzcyBEcmF3aW5nUGFyYW1ldGVycy4KKyAgICAgICAgICovCisgICAgICAgIGNsYXNzIERyYXdpbmdQYXJhbWV0ZXJzIHsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgZGVzdCBsb2NhdGlvbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgUG9pbnQgZGVzdExvY2F0aW9uOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBkZXN0IHNpemUuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIERpbWVuc2lvbiBkZXN0U2l6ZTsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUaGUgc291cmNlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBSZWN0YW5nbGUgc291cmNlOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkcmF3aW5nIHBhcmFtZXRlcnMuCisgICAgICAgICAgICAgKiAKKyAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0TG9jYXRpb24KKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIGRlc3QgbG9jYXRpb24uCisgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdFNpemUKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIGRlc3Qgc2l6ZS4KKyAgICAgICAgICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgICAgICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgRHJhd2luZ1BhcmFtZXRlcnMoUG9pbnQgZGVzdExvY2F0aW9uLCBEaW1lbnNpb24gZGVzdFNpemUsIFJlY3RhbmdsZSBzb3VyY2UpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmRlc3RMb2NhdGlvbiA9IG5ldyBQb2ludChkZXN0TG9jYXRpb24pOworICAgICAgICAgICAgICAgIGlmIChkZXN0U2l6ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdFNpemUgPSBuZXcgRGltZW5zaW9uKGRlc3RTaXplKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc3RTaXplID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHNvdXJjZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlID0gbmV3IFJlY3RhbmdsZShzb3VyY2UpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXh0Q29tcG9uZW50IHN1cHBvcnQuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgZGlzcGF0Y2ggZXZlbnQgdG8gaW0uCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwcml2YXRlIFRleHRLaXQgdGV4dEtpdCA9IG51bGw7IFRleHRLaXQgZ2V0VGV4dEtpdCgpIHsgcmV0dXJuIHRleHRLaXQ7IH0KKyAgICAgKiB2b2lkIHNldFRleHRLaXQoVGV4dEtpdCBraXQpIHsgdGV4dEtpdCA9IGtpdDsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogVGV4dEZpZWxkIHN1cHBvcnQuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwcml2YXRlIFRleHRGaWVsZEtpdCB0ZXh0RmllbGRLaXQgPSBudWxsOyBUZXh0RmllbGRLaXQgZ2V0VGV4dEZpZWxkS2l0KCkKKyAgICAgKiB7IHJldHVybiB0ZXh0RmllbGRLaXQ7IH0gdm9pZCBzZXRUZXh0RmllbGRLaXQoVGV4dEZpZWxkS2l0IGtpdCkgeworICAgICAqIHRleHRGaWVsZEtpdCA9IGtpdDsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogRGlzcGF0Y2hlcyBpbnB1dCAmIGZvY3VzIGV2ZW50cyB0byBpbnB1dCBtZXRob2QgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgZXZlbnQgdG8gcGFzcyB0byBJbnB1dENvbnRleHQuZGlzcGF0Y2hFdmVudCgpLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBldmVudCB3YXMgY29uc3VtZWQgYnkgSU0sIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZGlzcGF0Y2hFdmVudFRvSU0oQVdURXZlbnQgZSkgeworICAgICAgICBJbnB1dENvbnRleHQgaWMgPSBnZXRJbnB1dENvbnRleHQoKTsKKyAgICAgICAgaWYgKGljID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaWQgPSBlLmdldElEKCk7CisgICAgICAgIGJvb2xlYW4gaXNJbnB1dEV2ZW50ID0gKChpZCA+PSBLZXlFdmVudC5LRVlfRklSU1QpICYmIChpZCA8PSBLZXlFdmVudC5LRVlfTEFTVCkpCisgICAgICAgICAgICAgICAgfHwgKChpZCA+PSBNb3VzZUV2ZW50Lk1PVVNFX0ZJUlNUKSAmJiAoaWQgPD0gTW91c2VFdmVudC5NT1VTRV9MQVNUKSk7CisgICAgICAgIGlmICgoKGlkID49IEZvY3VzRXZlbnQuRk9DVVNfRklSU1QpICYmIChpZCA8PSBGb2N1c0V2ZW50LkZPQ1VTX0xBU1QpKSB8fCBpc0lucHV0RXZlbnQpIHsKKyAgICAgICAgICAgIGljLmRpc3BhdGNoRXZlbnQoZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGUuaXNDb25zdW1lZCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9Db21wb25lbnRCZWhhdmlvci5qYXZhIGIvYXd0L2phdmEvYXd0L0NvbXBvbmVudEJlaGF2aW9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjRlOGZmYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9Db21wb25lbnRCZWhhdmlvci5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRG1pdHJ5IEEuIER1cm5ldgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlV2luZG93OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2Ugb2YgdGhlIGhlbHBlciBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGRpZmZlcmVuY2UKKyAqIGJldHdlZW4gbGlnaHR3ZWlnaHQgYW5kIGhlYXZ5d2VpZ2h0IGNvbXBvbmVudHMuCisgKi8KK2ludGVyZmFjZSBDb21wb25lbnRCZWhhdmlvciB7CisKKyAgICB2b2lkIGFkZE5vdGlmeSgpOworCisgICAgdm9pZCBzZXRCb3VuZHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiTWFzayk7CisKKyAgICB2b2lkIHNldFZpc2libGUoYm9vbGVhbiBiKTsKKworICAgIEdyYXBoaWNzIGdldEdyYXBoaWNzKGludCB0cmFuc2xhdGlvblgsIGludCB0cmFuc2xhdGlvblksIGludCB3aWR0aCwgaW50IGhlaWdodCk7CisKKyAgICBOYXRpdmVXaW5kb3cgZ2V0TmF0aXZlV2luZG93KCk7CisKKyAgICBib29sZWFuIGlzTGlnaHR3ZWlnaHQoKTsKKworICAgIHZvaWQgb25Nb3ZlKGludCB4LCBpbnQgeSk7CisKKyAgICBib29sZWFuIGlzT3BhcXVlKCk7CisKKyAgICBib29sZWFuIGlzRGlzcGxheWFibGUoKTsKKworICAgIHZvaWQgc2V0RW5hYmxlZChib29sZWFuIHZhbHVlKTsKKworICAgIHZvaWQgcmVtb3ZlTm90aWZ5KCk7CisKKyAgICB2b2lkIHNldFpPcmRlcihpbnQgbmV3SW5kZXgsIGludCBvbGRJbmRleCk7CisKKyAgICBib29sZWFuIHNldEZvY3VzKGJvb2xlYW4gZm9jdXMsIENvbXBvbmVudCBvcHBvc2l0ZSk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQ29tcG9uZW50T3JpZW50YXRpb24uamF2YSBiL2F3dC9qYXZhL2F3dC9Db21wb25lbnRPcmllbnRhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhY2MxMWEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvQ29tcG9uZW50T3JpZW50YXRpb24uamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YsIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhlIENvbXBvbmVudE9yaWVudGF0aW9uIGNsYXNzIHNwZWNpZmllcyB0aGUgbGFuZ3VhZ2Utc2Vuc2l0aXZlIG9yaWVudGF0aW9uCisgKiBvZiBjb21wb25lbnQncyBlbGVtZW50cyBvciB0ZXh0LiBJdCBpcyB1c2VkIHRvIHJlZmxlY3QgdGhlIGRpZmZlcmVuY2VzIGluCisgKiB0aGlzIG9yZGVyaW5nIGJldHdlZW4gZGlmZmVyZW50IHdyaXRpbmcgc3lzdGVtcy4gVGhlIENvbXBvbmVudE9yaWVudGF0aW9uCisgKiBjbGFzcyBpbmRpY2F0ZXMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBlbGVtZW50cy90ZXh0IGluIHRoZSBob3Jpem9udGFsCisgKiBkaXJlY3Rpb24gKCJsZWZ0IHRvIHJpZ2h0IiBvciAicmlnaHQgdG8gbGVmdCIpIGFuZCBpbiB0aGUgdmVydGljYWwgZGlyZWN0aW9uCisgKiAoInRvcCB0byBib3R0b20iIG9yICJib3R0b20gdG8gdG9wIikuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29tcG9uZW50T3JpZW50YXRpb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQxMTMyOTEzOTIxNDM1NjM4MjhMOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IExFRlRfVE9fUklHSFQgaW5kaWNhdGVzIHRoYXQgaXRlbXMgcnVuIGxlZnQgdG8gcmlnaHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb21wb25lbnRPcmllbnRhdGlvbiBMRUZUX1RPX1JJR0hUID0gbmV3IENvbXBvbmVudE9yaWVudGF0aW9uKHRydWUsIHRydWUpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFJJR0hUX1RPX0xFRlQgaW5kaWNhdGVzIHRoYXQgaXRlbXMgcnVuIHJpZ2h0IHRvIGxlZnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb21wb25lbnRPcmllbnRhdGlvbiBSSUdIVF9UT19MRUZUID0gbmV3IENvbXBvbmVudE9yaWVudGF0aW9uKHRydWUsIGZhbHNlKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBVTktOT1dOIGluZGljYXRlcyB0aGF0IGEgY29tcG9uZW50J3Mgb3JpZW50YXRpb24gaXMgbm90IHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbXBvbmVudE9yaWVudGF0aW9uIFVOS05PV04gPSBuZXcgQ29tcG9uZW50T3JpZW50YXRpb24odHJ1ZSwgdHJ1ZSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcmxMYW5ncy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBybExhbmdzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOyAvLyBSSUdIVF9UT19MRUZUCisKKyAgICAvLyBsYW5ndWFnZXMKKworICAgIC8qKgorICAgICAqIFRoZSBob3Jpem9udGFsLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBob3Jpem9udGFsOworCisgICAgLyoqCisgICAgICogVGhlIGxlZnQycmlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxlZnQycmlnaHQ7CisKKyAgICBzdGF0aWMgeworICAgICAgICBybExhbmdzLmFkZCgiYXIiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBybExhbmdzLmFkZCgiZmEiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBybExhbmdzLmFkZCgiaXciKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBybExhbmdzLmFkZCgidXIiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9yaWVudGF0aW9uIGZvciB0aGUgZ2l2ZW4gUmVzb3VyY2VCdW5kbGUncyBsb2NhbGl6YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGJkbAorICAgICAqICAgICAgICAgICAgdGhlIFJlc291cmNlQnVuZGxlLgorICAgICAqIEByZXR1cm4gdGhlIENvbXBvbmVudE9yaWVudGF0aW9uLgorICAgICAqIEBkZXByZWNhdGVkIFVzZSBnZXRPcmllbnRhdGlvbihqYXZhLnV0aWwuTG9jYWxlKSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIENvbXBvbmVudE9yaWVudGF0aW9uIGdldE9yaWVudGF0aW9uKFJlc291cmNlQnVuZGxlIGJkbCkgeworICAgICAgICBPYmplY3Qgb2JqID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iaiA9IGJkbC5nZXRPYmplY3QoIk9yaWVudGF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIG1yZSkgeworICAgICAgICAgICAgb2JqID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ29tcG9uZW50T3JpZW50YXRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiAoQ29tcG9uZW50T3JpZW50YXRpb24pb2JqOworICAgICAgICB9CisgICAgICAgIExvY2FsZSBsb2NhbGUgPSBiZGwuZ2V0TG9jYWxlKCk7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0T3JpZW50YXRpb24obG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvcmllbnRhdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCisgICAgICogCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBMb2NhbGUuCisgICAgICogQHJldHVybiB0aGUgQ29tcG9uZW50T3JpZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb21wb25lbnRPcmllbnRhdGlvbiBnZXRPcmllbnRhdGlvbihMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIFN0cmluZyBsYW5nID0gbG9jYWxlLmdldExhbmd1YWdlKCk7CisgICAgICAgIHJldHVybiBybExhbmdzLmNvbnRhaW5zKGxhbmcpID8gUklHSFRfVE9fTEVGVCA6IExFRlRfVE9fUklHSFQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGNvbXBvbmVudCBvcmllbnRhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaG9yCisgICAgICogICAgICAgICAgICB3aGV0aGVyIHRoZSBpdGVtcyBzaG91bGQgYmUgYXJyYW5nZWQgaG9yaXpvbnRhbGx5LgorICAgICAqIEBwYXJhbSBsMnIKKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdGhpcyBvcmllbnRhdGlvbiBzcGVjaWZpZXMgYSBsZWZ0LXRvLXJpZ2h0IGZsb3cuCisgICAgICovCisgICAgcHJpdmF0ZSBDb21wb25lbnRPcmllbnRhdGlvbihib29sZWFuIGhvciwgYm9vbGVhbiBsMnIpIHsKKyAgICAgICAgaG9yaXpvbnRhbCA9IGhvcjsKKyAgICAgICAgbGVmdDJyaWdodCA9IGwycjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHRleHQgb2YgdGhlIG9mIHdyaXRpbmcgc3lzdGVtcyBhcnJhbmdlZCBob3Jpem9udGFsbHkuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgdGV4dCBpcyB3cml0dGVuIGhvcml6b250YWxseSwgZmFsc2UgZm9yIGEgdmVydGljYWwKKyAgICAgKiAgICAgICAgIGFycmFuZ2VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSG9yaXpvbnRhbCgpIHsKKyAgICAgICAgcmV0dXJuIGhvcml6b250YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB0ZXh0IGlzIGFycmFuZ2VkIGZyb20gbGVmdCB0byByaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGZvciB3cml0aW5nIHN5c3RlbXMgd3JpdHRlbiBmcm9tIGxlZnQgdG8gcmlnaHQ7IGZhbHNlIGZvcgorICAgICAqICAgICAgICAgcmlnaHQtdG8tbGVmdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xlZnRUb1JpZ2h0KCkgeworICAgICAgICByZXR1cm4gbGVmdDJyaWdodDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9Db21wb3NpdGUuamF2YSBiL2F3dC9qYXZhL2F3dC9Db21wb3NpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTczMGZlCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0NvbXBvc2l0ZS5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbDsKKworLyoqCisgKiBUaGUgQ29tcG9zaXRlIGludGVyZmFjZSBhbGxvd3MgdGhlIG1ldGhvZHMgdG8gY29tcG9zZSBhIGRyYXcgcHJpbWl0aXZlIG9uIHRoZQorICogZ3JhcGhpY3MgYXJlYS4gVGhlIGNsYXNzZXMgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBydWxlcyBhbmQKKyAqIGEgbWV0aG9kIHRvIGNyZWF0ZSB0aGUgY29udGV4dCBmb3IgYSBwYXJ0aWN1bGFyIG9wZXJhdGlvbi4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29tcG9zaXRlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBDb21wb3NpdGVDb250ZXh0IHdoaWNoIGRlZmluZXMgdGhlIGVuY2Fwc3VsYXRlZCBhbmQgb3B0aW1pemVkCisgICAgICogZW52aXJvbm1lbnQgZm9yIGEgY29tcG9zaXRpbmcgb3BlcmF0aW9uLiBTZXZlcmFsIGNvbnRleHRzIGNhbiBleGlzdCBmb3IgYQorICAgICAqIHNpbmdsZSBDb21wb3NpdGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmNDb2xvck1vZGVsCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlJ3MgQ29sb3JNb2RlbC4KKyAgICAgKiBAcGFyYW0gZHN0Q29sb3JNb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uJ3MgQ29sb3JNb2RlbC4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cy4KKyAgICAgKiBAcmV0dXJuIHRoZSBDb21wb3NpdGVDb250ZXh0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcG9zaXRlQ29udGV4dCBjcmVhdGVDb250ZXh0KENvbG9yTW9kZWwgc3JjQ29sb3JNb2RlbCwgQ29sb3JNb2RlbCBkc3RDb2xvck1vZGVsLAorICAgICAgICAgICAgUmVuZGVyaW5nSGludHMgaGludHMpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvQ29tcG9zaXRlQ29udGV4dC5qYXZhIGIvYXd0L2phdmEvYXd0L0NvbXBvc2l0ZUNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTU2NDBkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0NvbXBvc2l0ZUNvbnRleHQuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKKworLyoqCisgKiBUaGUgQ29tcG9zaXRlQ29udGV4dCBpbnRlcmZhY2Ugc3BlY2lmaWVzIHRoZSBlbmNhcHN1bGF0ZWQgYW5kIG9wdGltaXplZAorICogZW52aXJvbm1lbnQgZm9yIGEgY29tcG9zaXRpbmcgb3BlcmF0aW9uLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBDb21wb3NpdGVDb250ZXh0IHsKKworICAgIC8qKgorICAgICAqIENvbXBvc2VzIHRoZSB0d28gc291cmNlIFJhc3RlciBvYmplY3RzIGFuZCBwbGFjZXMgdGhlIHJlc3VsdCBpbiB0aGUKKyAgICAgKiBkZXN0aW5hdGlvbiBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFJhc3Rlci4KKyAgICAgKiBAcGFyYW0gZHN0SW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBSYXN0ZXIuCisgICAgICogQHBhcmFtIGRzdE91dAorICAgICAqICAgICAgICAgICAgdGhlIFdyaXRhYmxlUmFzdGVyIG9iamVjdCB3aGVyZSB0aGUgcmVzdWx0IG9mIGNvbXBvc2luZworICAgICAqICAgICAgICAgICAgb3BlcmF0aW9uIGlzIHN0b3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb21wb3NlKFJhc3RlciBzcmMsIFJhc3RlciBkc3RJbiwgV3JpdGFibGVSYXN0ZXIgZHN0T3V0KTsKKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIHJlc291cmNlcyBhbGxvY2F0ZWQgZm9yIGEgY29udGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9DdXJzb3IuamF2YSBiL2F3dC9qYXZhL2F3dC9DdXJzb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTBjYzg0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0N1cnNvci5qYXZhCkBAIC0wLDAgKzEsNDI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlQ3Vyc29yOworCisvKioKKyAqIFRoZSBDdXJzb3IgY2xhc3MgcmVwcmVzZW50cyB0aGUgYml0bWFwIG9mIHRoZSBtb3VzZSBjdXJzb3IuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQ3Vyc29yIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDgwMjgyMzc0OTc1Njg5ODU1MDRMOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IERFRkFVTFRfQ1VSU09SIGluZGljYXRlcyB0aGUgZGVmYXVsdCBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0NVUlNPUiA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ1JPU1NIQUlSX0NVUlNPUiBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUk9TU0hBSVJfQ1VSU09SID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBURVhUX0NVUlNPUiBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUX0NVUlNPUiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0FJVF9DVVJTT1IgY3Vyc29yIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0FJVF9DVVJTT1IgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNXX1JFU0laRV9DVVJTT1IgY3Vyc29yIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1dfUkVTSVpFX0NVUlNPUiA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0VfUkVTSVpFX0NVUlNPUiBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRV9SRVNJWkVfQ1VSU09SID0gNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBOV19SRVNJWkVfQ1VSU09SIGN1cnNvciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5XX1JFU0laRV9DVVJTT1IgPSA2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE5FX1JFU0laRV9DVVJTT1IgY3Vyc29yIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVfUkVTSVpFX0NVUlNPUiA9IDc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTl9SRVNJWkVfQ1VSU09SIGN1cnNvciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5fUkVTSVpFX0NVUlNPUiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU19SRVNJWkVfQ1VSU09SIGN1cnNvciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNfUkVTSVpFX0NVUlNPUiA9IDk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV19SRVNJWkVfQ1VSU09SIGN1cnNvciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdfUkVTSVpFX0NVUlNPUiA9IDEwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEVfUkVTSVpFX0NVUlNPUiBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFX1JFU0laRV9DVVJTT1IgPSAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBIQU5EX0NVUlNPUiBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIQU5EX0NVUlNPUiA9IDEyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVkVfQ1VSU09SIGN1cnNvciB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PVkVfQ1VSU09SID0gMTM7CisKKyAgICAvKioKKyAgICAgKiBBIG1hcHBpbmcgZnJvbSBuYW1lcyB0byBzeXN0ZW0gY3VzdG9tIGN1cnNvcnMuCisgICAgICovCisgICAgc3RhdGljIE1hcDxTdHJpbmcsIEN1cnNvcj4gc3lzdGVtQ3VzdG9tQ3Vyc29yczsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJzb3IgcHJvcHMuCisgICAgICovCisgICAgc3RhdGljIFByb3BlcnRpZXMgY3Vyc29yUHJvcHM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcHJlZGVmaW5lZE5hbWVzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBwcmVkZWZpbmVkTmFtZXMgPSB7CisgICAgICAgICAgICAiRGVmYXVsdCIsICJDcm9zc2hhaXIiLCAiVGV4dCIsICJXYWl0IiwgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JAorICAgICAgICAgICAgIlNvdXRod2VzdCBSZXNpemUiLCAiU291dGhlYXN0IFJlc2l6ZSIsIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgIk5vcnRod2VzdCBSZXNpemUiLCAiTm9ydGhlYXN0IFJlc2l6ZSIsIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgIk5vcnRoIFJlc2l6ZSIsICJTb3V0aCBSZXNpemUiLCAiV2VzdCBSZXNpemUiLCAiRWFzdCBSZXNpemUiLCAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkCisgICAgICAgICAgICAiSGFuZCIsICJNb3ZlIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJlZGVmaW5lZCBzZXQgb2YgY3Vyc29ycy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIEN1cnNvcltdIHByZWRlZmluZWQgPSB7CisgICAgICAgICAgICBuZXcgQ3Vyc29yKERFRkFVTFRfQ1VSU09SKSwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENVU1RPTV9DVVJTT1IgaXMgYXNzb2NpYXRlZCB3aXRoIGFsbCBjdXN0b20gY3Vyc29yIHR5cGVzLgorICAgICAqIChUaG9zZSB3aGljaCBhcmUgbm90IHByZWRlZmluZWQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1VTVE9NX0NVUlNPUiA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIGN1cnNvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBvZiB0aGUgY3Vyc29yLCBjaG9zZW4gZnJvbSB0aGUgbGlzdCBvZiBjdXJzb3IgdHlwZSBjb25zdGFudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdHlwZTsKKworICAgIC8qKgorICAgICAqIFRoZSBuYXRpdmUgY3Vyc29yLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IE5hdGl2ZUN1cnNvciBuYXRpdmVDdXJzb3I7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXhhY3QgcG9pbnQgb24gdGhlIGN1cnNvciBpbWFnZSB0aGF0IGluZGljYXRlcyB3aGljaCBwb2ludCB0aGUgY3Vyc29yCisgICAgICogaXMgc2VsZWN0aW5nIChwb2ludGluZyB0bykuIFRoZSBjb29yZGluYXRlcyBhcmUgZ2l2ZW4gd2l0aCByZXNwZWN0IHRoZQorICAgICAqIG9yaWdpbiBvZiB0aGUgSW1hZ2UgKGl0cyB1cHBlciBsZWZ0IGNvcm5lcikuCisgICAgICovCisgICAgcHJpdmF0ZSBQb2ludCBob3RTcG90OworCisgICAgLyoqCisgICAgICogVGhlIGltYWdlIHRvIGRyYXcgb24gdGhlIHNjcmVlbiByZXByZXNlbnRpbmcgdGhlIGN1cnNvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIEltYWdlIGltYWdlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGN1cnNvciB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgY3Vyc29yLgorICAgICAqLworICAgIHByb3RlY3RlZCBDdXJzb3IoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcyhuYW1lLCBudWxsLCBuZXcgUG9pbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGN1cnNvciBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIGN1cnNvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ3Vyc29yKGludCB0eXBlKSB7CisgICAgICAgIGNoZWNrVHlwZSh0eXBlKTsKKyAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgaWYgKCh0eXBlID49IDApICYmICh0eXBlIDwgcHJlZGVmaW5lZE5hbWVzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIG5hbWUgPSBwcmVkZWZpbmVkTmFtZXNbdHlwZV0gKyAiIEN1cnNvciI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBjdXJzb3IuCisgICAgICogCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lLgorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWcuCisgICAgICogQHBhcmFtIGhvdFNwb3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Qgc3BvdC4KKyAgICAgKi8KKyAgICBDdXJzb3IoU3RyaW5nIG5hbWUsIEltYWdlIGltZywgUG9pbnQgaG90U3BvdCkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0eXBlID0gQ1VTVE9NX0NVUlNPUjsKKyAgICAgICAgdGhpcy5ob3RTcG90ID0gaG90U3BvdDsKKyAgICAgICAgaW1hZ2UgPSBpbWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluYWxpemUgbWV0aG9kIG92ZXJyaWRlcyB0aGUgZmluYWxpemUgbWV0aG9kIGZyb20gT2JqZWN0IGNsYXNzLgorICAgICAqIAorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5hdGl2ZSBjdXJzb3IgaXMgbm90IG51bGwgYW5kIHRocm93cyBhIFRocm93YWJsZSB3aGVuCisgICAgICogICAgICAgICAgICAgZGVzdHJveWVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGlmIChuYXRpdmVDdXJzb3IgIT0gbnVsbCkgeworICAgICAgICAgICAgbmF0aXZlQ3Vyc29yLmRlc3Ryb3lDdXJzb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGN1cnNvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjdXJzb3IuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnNvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnNvci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiWyIgKyBuYW1lICsgIl0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJzb3IgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJzb3IgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByZWRlZmluZWQgY3Vyc29yIHdpdGggdGhlIHNwZWNpZmllZCB0eXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiBjdXJzb3IuCisgICAgICogQHJldHVybiB0aGUgcHJlZGVmaW5lZCBjdXJzb3Igd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDdXJzb3IgZ2V0UHJlZGVmaW5lZEN1cnNvcihpbnQgdHlwZSkgeworICAgICAgICBjaGVja1R5cGUodHlwZSk7CisgICAgICAgIEN1cnNvciBjdXJzb3IgPSBwcmVkZWZpbmVkW3R5cGVdOworICAgICAgICBpZiAoY3Vyc29yID09IG51bGwpIHsKKyAgICAgICAgICAgIGN1cnNvciA9IG5ldyBDdXJzb3IodHlwZSk7CisgICAgICAgICAgICBwcmVkZWZpbmVkW3R5cGVdID0gY3Vyc29yOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBjdXJzb3IuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBjdXJzb3IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDdXJzb3IgZ2V0RGVmYXVsdEN1cnNvcigpIHsKKyAgICAgICAgcmV0dXJuIGdldFByZWRlZmluZWRDdXJzb3IoREVGQVVMVF9DVVJTT1IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNwZWNpZmllZCBzeXN0ZW0gY3VzdG9tIGN1cnNvci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgc3lzdGVtIGN1cnNvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcGVjaWZpYyBzeXN0ZW0gY3Vyc29yIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqIEB0aHJvd3MgQVdURXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGRlc2lyZWQgY3Vyc29yIGhhcyBtYWxmb3JtZWQgZGF0YSBzdWNoIGFzIGFuCisgICAgICogICAgICAgICAgICAgaW5jb3JyZWN0bHkgZGVmaW5lZCBob3Qgc3BvdC4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlzSGVhZGxlc3MgbWV0aG9kIG9mIHRoZSBHcmFwaGljc0Vudmlyb25tZW50IHJldHVybnMKKyAgICAgKiAgICAgICAgICAgICB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ3Vyc29yIGdldFN5c3RlbUN1c3RvbUN1cnNvcihTdHJpbmcgbmFtZSkgdGhyb3dzIEFXVEV4Y2VwdGlvbiwgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBUb29sa2l0LmNoZWNrSGVhZGxlc3MoKTsKKyAgICAgICAgcmV0dXJuIGdldFN5c3RlbUN1c3RvbUN1cnNvckZyb21NYXAobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3BlY2lmaWVkIHN5c3RlbSBjdXN0b20gY3Vyc29yIGZyb20gdGhlIG1hcCBvZiBzeXN0ZW0gY3VzdG9tCisgICAgICogY3Vyc29ycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgY3Vyc29yLgorICAgICAqIEByZXR1cm4gdGhlIGRlc2lyZWQgc3lzdGVtIGN1c3RvbSBjdXJzb3IgZnJvbSB0aGUgbWFwIG9mIHN5c3RlbSBjdXN0b20KKyAgICAgKiAgICAgICAgIGN1cnNvcnMuCisgICAgICogQHRocm93cyBBV1RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgQVdUIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBDdXJzb3IgZ2V0U3lzdGVtQ3VzdG9tQ3Vyc29yRnJvbU1hcChTdHJpbmcgbmFtZSkgdGhyb3dzIEFXVEV4Y2VwdGlvbiB7CisgICAgICAgIGxvYWRDdXJzb3JQcm9wcygpOworICAgICAgICBpZiAoc3lzdGVtQ3VzdG9tQ3Vyc29ycyA9PSBudWxsKSB7CisgICAgICAgICAgICBzeXN0ZW1DdXN0b21DdXJzb3JzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDdXJzb3I+KCk7CisgICAgICAgIH0KKyAgICAgICAgQ3Vyc29yIGN1cnNvciA9IHN5c3RlbUN1c3RvbUN1cnNvcnMuZ2V0KG5hbWUpOworICAgICAgICBpZiAoY3Vyc29yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXd0LjE0MT1mYWlsZWQgdG8gcGFyc2UgaG90c3BvdCBwcm9wZXJ0eSBmb3IgY3Vyc29yOgorICAgICAgICBTdHJpbmcgZXhNc2cgPSBNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xNDEiKSArIG5hbWU7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIG5tID0gIkN1cnNvci4iICsgbmFtZTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBTdHJpbmcgbmFtZVN0ciA9IGN1cnNvclByb3BzLmdldFByb3BlcnR5KG5tICsgIi5OYW1lIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIGhvdFNwb3RTdHIgPSBjdXJzb3JQcm9wcy5nZXRQcm9wZXJ0eShubSArICIuSG90U3BvdCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIFN0cmluZyBmaWxlU3RyID0gY3Vyc29yUHJvcHMuZ2V0UHJvcGVydHkobm0gKyAiLkZpbGUiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBpbnQgaWR4ID0gaG90U3BvdFN0ci5pbmRleE9mKCcsJyk7CisgICAgICAgIGlmIChpZHggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVdURXhjZXB0aW9uKGV4TXNnKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgeCwgeTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHggPSBuZXcgSW50ZWdlcihob3RTcG90U3RyLnN1YnN0cmluZygwLCBpZHgpKS5pbnRWYWx1ZSgpOworICAgICAgICAgICAgeSA9IG5ldyBJbnRlZ2VyKGhvdFNwb3RTdHIuc3Vic3RyaW5nKGlkeCArIDEsIGhvdFNwb3RTdHIubGVuZ3RoKCkpKS5pbnRWYWx1ZSgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVdURXhjZXB0aW9uKGV4TXNnKTsKKyAgICAgICAgfQorICAgICAgICBJbWFnZSBpbWcgPSBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCkuY3JlYXRlSW1hZ2UoZmlsZVN0cik7CisgICAgICAgIGN1cnNvciA9IG5ldyBDdXJzb3IobmFtZVN0ciwgaW1nLCBuZXcgUG9pbnQoeCwgeSkpOworICAgICAgICBzeXN0ZW1DdXN0b21DdXJzb3JzLnB1dChuYW1lLCBjdXJzb3IpOworCisgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBjdXJzb3IgcHJvcHMuCisgICAgICogCisgICAgICogQHRocm93cyBBV1RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgQVdUIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRDdXJzb3JQcm9wcygpIHRocm93cyBBV1RFeGNlcHRpb24geworICAgICAgICBpZiAoY3Vyc29yUHJvcHMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBzZXAgPSBGaWxlLnNlcGFyYXRvcjsKKyAgICAgICAgU3RyaW5nIGN1cnNvcnNEaXIgPSAibGliIiArIHNlcCArICJpbWFnZXMiICsgc2VwICsgImN1cnNvcnMiOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICBTdHJpbmcgY3Vyc29yc0Fic0RpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIikgKyBzZXAgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgY3Vyc29yc0RpcjsKKyAgICAgICAgU3RyaW5nIGN1cnNvclByb3BzRmlsZU5hbWUgPSAiY3Vyc29ycy5wcm9wZXJ0aWVzIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICBTdHJpbmcgY3Vyc29yUHJvcHNGdWxsRmlsZU5hbWUgPSAoY3Vyc29yc0Fic0RpciArIHNlcCArIGN1cnNvclByb3BzRmlsZU5hbWUpOworICAgICAgICBjdXJzb3JQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjdXJzb3JQcm9wcy5sb2FkKG5ldyBGaWxlSW5wdXRTdHJlYW0obmV3IEZpbGUoY3Vyc29yUHJvcHNGdWxsRmlsZU5hbWUpKSk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBhd3QuMTQyPUV4Y2VwdGlvbjogY2xhc3MgezB9IHsxfSBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nOiB7Mn0KKyAgICAgICAgICAgIHRocm93IG5ldyBBV1RFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTQyIiwvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRDbGFzcygpLCBlLmdldE1lc3NhZ2UoKSwgY3Vyc29yUHJvcHNGdWxsRmlsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgfSkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVdURXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUuCisgICAgICovCisgICAgc3RhdGljIHZvaWQgY2hlY2tUeXBlKGludCB0eXBlKSB7CisgICAgICAgIC8vIGNhbid0IHVzZSBwcmVkZWZpbmVkIGFycmF5IGhlcmUgYmVjYXVzZSBpdCBtYXkgbm90IGhhdmUgYmVlbgorICAgICAgICAvLyBpbml0aWFsaXplZCB5ZXQKKyAgICAgICAgaWYgKCh0eXBlIDwgMCkgfHwgKHR5cGUgPj0gcHJlZGVmaW5lZE5hbWVzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xNDM9aWxsZWdhbCBjdXJzb3IgdHlwZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xNDMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vICJsYXppbHkiIGNyZWF0ZSBuYXRpdmUgY3Vyc29yczoKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYXRpdmUgY3Vyc29yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG5hdGl2ZSBjdXJzb3IuCisgICAgICovCisgICAgTmF0aXZlQ3Vyc29yIGdldE5hdGl2ZUN1cnNvcigpIHsKKyAgICAgICAgaWYgKG5hdGl2ZUN1cnNvciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ3Vyc29yOworICAgICAgICB9CisgICAgICAgIFRvb2xraXQgdG9vbGtpdCA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICAgICAgaWYgKHR5cGUgIT0gQ1VTVE9NX0NVUlNPUikgeworICAgICAgICAgICAgbmF0aXZlQ3Vyc29yID0gdG9vbGtpdC5jcmVhdGVOYXRpdmVDdXJzb3IodHlwZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuYXRpdmVDdXJzb3IgPSB0b29sa2l0LmNyZWF0ZUN1c3RvbU5hdGl2ZUN1cnNvcihpbWFnZSwgaG90U3BvdCwgbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5hdGl2ZUN1cnNvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYXRpdmUgY3Vyc29yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYXRpdmVDdXJzb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbmF0aXZlIGN1cnNvci4KKyAgICAgKi8KKyAgICB2b2lkIHNldE5hdGl2ZUN1cnNvcihOYXRpdmVDdXJzb3IgbmF0aXZlQ3Vyc29yKSB7CisgICAgICAgIHRoaXMubmF0aXZlQ3Vyc29yID0gbmF0aXZlQ3Vyc29yOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9EaW1lbnNpb24uamF2YSBiL2F3dC9qYXZhL2F3dC9EaW1lbnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Nzc3OTYyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0RpbWVuc2lvbi5qYXZhCkBAIC0wLDAgKzEsMjAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0Lmdlb20uRGltZW5zaW9uMkQ7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubWlzYy5IYXNoQ29kZTsKKworLyoqCisgKiBUaGUgRGltZW5zaW9uIHJlcHJlc2VudHMgdGhlIHNpemUgKHdpZHRoIGFuZCBoZWlnaHQpIG9mIGEgY29tcG9uZW50LiBUaGUKKyAqIHdpZHRoIGFuZCBoZWlnaHQgdmFsdWVzIGNhbiBiZSBuZWdhdGl2ZSwgYnV0IGluIHRoYXQgY2FzZSB0aGUgYmVoYXZpb3Igb2YKKyAqIHNvbWUgbWV0aG9kcyBpcyB1bmV4cGVjdGVkLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIERpbWVuc2lvbiBleHRlbmRzIERpbWVuc2lvbjJEIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ3MjM5NTI1Nzk0OTEzNDk1MjRMOworCisgICAgLyoqCisgICAgICogVGhlIHdpZHRoIGRpbWVuc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHdpZHRoOworCisgICAgLyoqCisgICAgICogVGhlIGhlaWdodCBkaW1lbnNpb24uCisgICAgICovCisgICAgcHVibGljIGludCBoZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgRGltZW5zaW9uIHdpdGggdGhlIHNhbWUgZGF0YSBhcyB0aGUgc3BlY2lmaWVkCisgICAgICogRGltZW5zaW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgRGltZW5zaW9uIHRvIGNvcHkgdGhlIGRhdGEgZnJvbSB3aGVuIGNyZWF0aW5nIHRoZSBuZXcKKyAgICAgKiAgICAgICAgICAgIERpbWVuc2lvbiBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbihEaW1lbnNpb24gZCkgeworICAgICAgICB0aGlzKGQud2lkdGgsIGQuaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgRGltZW5zaW9uIHdpdGggemVybyB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqLworICAgIHB1YmxpYyBEaW1lbnNpb24oKSB7CisgICAgICAgIHRoaXMoMCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IERpbWVuc2lvbiB3aXRoIHRoZSBzcGVjaWZpZWQgd2lkdGggYW5kIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgbmV3IERpbWVuc2lvbi4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBuZXcgRGltZW5zaW9uLgorICAgICAqLworICAgIHB1YmxpYyBEaW1lbnNpb24oaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHNldFNpemUod2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoZSBEaW1lbnNpb24uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoZSBEaW1lbnNpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgSGFzaENvZGUgaGFzaCA9IG5ldyBIYXNoQ29kZSgpOworICAgICAgICBoYXNoLmFwcGVuZCh3aWR0aCk7CisgICAgICAgIGhhc2guYXBwZW5kKGhlaWdodCk7CisgICAgICAgIHJldHVybiBoYXNoLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBEaW1lbnNpb24gb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGlzIGEgRGltZW5zaW9uIHdpdGggdGhlIHNhbWUgd2lkdGgKKyAgICAgKiAgICAgICAgIGFuZCBoZWlnaHQgZGF0YSBhcyB0aGlzIERpbWVuc2lvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEaW1lbnNpb24pIHsKKyAgICAgICAgICAgIERpbWVuc2lvbiBkID0gKERpbWVuc2lvbilvYmo7CisgICAgICAgICAgICByZXR1cm4gKGQud2lkdGggPT0gd2lkdGggJiYgZC5oZWlnaHQgPT0gaGVpZ2h0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIGFzc29jaWF0ZWQgdG8gdGhpcyBEaW1lbnNpb24gb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyBhc3NvY2lhdGVkIHRvIHRoaXMgRGltZW5zaW9uIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBUaGUgb3V0cHV0IGZvcm1hdCBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvdXIuIEl0IGNvdWxkIGJlCisgICAgICAgIC8vIG9idGFpbmVkIGluIHRoZSBmb2xsb3dpbmcgd2F5CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgRGltZW5zaW9uKCkudG9TdHJpbmcoKSkKKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlt3aWR0aD0iICsgd2lkdGggKyAiLGhlaWdodD0iICsgaGVpZ2h0ICsgIl0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNpemUgb2YgdGhpcyBEaW1lbnNpb24gb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQKKyAgICAgKiBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIERpbWVuc2lvbi4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBEaW1lbnNpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzaXplIG9mIHRoaXMgRGltZW5zaW9uIG9iamVjdCBieSBjb3B5aW5nIHRoZSBkYXRhIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIERpbWVuc2lvbiBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBEaW1lbnNpb24gdGhhdCBnaXZlcyB0aGUgbmV3IHNpemUgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpemUoRGltZW5zaW9uIGQpIHsKKyAgICAgICAgc2V0U2l6ZShkLndpZHRoLCBkLmhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2l6ZSBvZiB0aGlzIERpbWVuc2lvbiBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIGRvdWJsZSB3aWR0aAorICAgICAqIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIERpbWVuc2lvbi4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBEaW1lbnNpb24uCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLkRpbWVuc2lvbjJEI3NldFNpemUoZG91YmxlLCBkb3VibGUpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgc2V0U2l6ZSgoaW50KU1hdGguY2VpbCh3aWR0aCksIChpbnQpTWF0aC5jZWlsKGhlaWdodCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNpemUgb2YgdGhlIERpbWVuc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSBEaW1lbnNpb24uCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbih3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIERpbWVuc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhlIERpbWVuc2lvbi4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uRGltZW5zaW9uMkQjZ2V0SGVpZ2h0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aCBvZiB0aGUgRGltZW5zaW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpZHRoIG9mIHRoZSBEaW1lbnNpb24uCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLkRpbWVuc2lvbjJEI2dldFdpZHRoKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldFdpZHRoKCkgeworICAgICAgICByZXR1cm4gd2lkdGg7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvRGlzcGF0Y2hlci5qYXZhIGIvYXd0L2phdmEvYXd0L0Rpc3BhdGNoZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDU3YWY0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0Rpc3BhdGNoZXIuamF2YQpAQCAtMCwwICsxLDcyMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YsIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkNvbXBvbmVudEV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkZvY3VzRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5LZXlFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LlBhaW50RXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuV2luZG93RXZlbnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVFdmVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVXaW5kb3c7CisKKworLyoqCisgKiBIZWxwZXIgcGFja2FnZS1wcml2YXRlIGNsYXNzIGZvciBtYW5hZ2luZyBsaWdodHdlaWdodCBjb21wb25lbnRzICYKKyAqIGRpc3BhdGNoaW5nIGV2ZW50cyBmcm9tIGhlYXZ5d2VpZ2h0IHNvdXJjZQorICovCitjbGFzcyBEaXNwYXRjaGVyIHsKKworICAgIC8vPz8/QVdUOiBmaW5hbCBQb3B1cERpc3BhdGNoZXIgcG9wdXBEaXNwYXRjaGVyID0gbmV3IFBvcHVwRGlzcGF0Y2hlcigpOworCisgICAgLy8/Pz9BV1Q6IGZpbmFsIEZvY3VzRGlzcGF0Y2hlciBmb2N1c0Rpc3BhdGNoZXI7CisKKyAgICBmaW5hbCBNb3VzZUdyYWJNYW5hZ2VyIG1vdXNlR3JhYk1hbmFnZXIgPSBuZXcgTW91c2VHcmFiTWFuYWdlcigpOworCisgICAgZmluYWwgTW91c2VEaXNwYXRjaGVyIG1vdXNlRGlzcGF0Y2hlcjsKKworICAgIHByaXZhdGUgZmluYWwgQ29tcG9uZW50RGlzcGF0Y2hlciBjb21wb25lbnREaXNwYXRjaGVyID0gbmV3IENvbXBvbmVudERpc3BhdGNoZXIoKTsKKworICAgIHByaXZhdGUgZmluYWwgS2V5RGlzcGF0Y2hlciBrZXlEaXNwYXRjaGVyID0gbmV3IEtleURpc3BhdGNoZXIoKTsKKworICAgIHByaXZhdGUgZmluYWwgVG9vbGtpdCB0b29sa2l0OworCisgICAgaW50IGNsaWNrSW50ZXJ2YWwgPSAyNTA7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdG9vbGtpdCAtIEFXVCB0b29sa2l0CisgICAgICovCisgICAgRGlzcGF0Y2hlcihUb29sa2l0IHRvb2xraXQpIHsKKyAgICAgICAgdGhpcy50b29sa2l0ID0gdG9vbGtpdDsKKworICAgICAgICAvLz8/P0FXVDogZm9jdXNEaXNwYXRjaGVyID0gbmV3IEZvY3VzRGlzcGF0Y2hlcih0b29sa2l0KTsKKyAgICAgICAgbW91c2VEaXNwYXRjaGVyID0gbmV3IE1vdXNlRGlzcGF0Y2hlcihtb3VzZUdyYWJNYW5hZ2VyLCB0b29sa2l0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNwYXRjaCBuYXRpdmUgZXZlbnQ6IHByb2R1Y2UgYXBwcm9wcmlhdGUgQVdUIGV2ZW50cywgCisgICAgICogdXBkYXRlIGNvbXBvbmVudCdzIGZpZWxkcyB3aGVuIG5lZWRlZAorICAgICAqIEBwYXJhbSBldmVudCAtIG5hdGl2ZSBldmVudCB0byBkaXNwYXRjaAorICAgICAqIEByZXR1cm4gLSB0cnVlIG1lYW5zIGRlZmF1bHQgcHJvY2Vzc2luZyBieSBPUyBpcyBub3QgbmVlZGVkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb25FdmVudChOYXRpdmVFdmVudCBldmVudCkgeworICAgICAgICBpbnQgZXZlbnRJZCA9IGV2ZW50LmdldEV2ZW50SWQoKTsKKworICAgICAgICBpZiAoZXZlbnRJZCA9PSBOYXRpdmVFdmVudC5JRF9DUkVBVEVEKSB7CisgICAgICAgICAgICByZXR1cm4gdG9vbGtpdC5vbldpbmRvd0NyZWF0ZWQoZXZlbnQuZ2V0V2luZG93SWQoKSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRJZCA9PSBOYXRpdmVFdmVudC5JRF9NT1VTRV9HUkFCX0NBTkNFTEVEKSB7CisgICAgICAgICAgICByZXR1cm4gbW91c2VHcmFiTWFuYWdlci5vbkdyYWJDYW5jZWxlZCgpOworICAgICAgICAvLz8/P0FXVAorLy8gICAgICAgIH0gZWxzZSBpZiAocG9wdXBEaXNwYXRjaGVyLm9uRXZlbnQoZXZlbnQpKSB7CisvLyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIENvbXBvbmVudCBzcmMgPSB0b29sa2l0LmdldENvbXBvbmVudEJ5SWQoZXZlbnQuZ2V0V2luZG93SWQoKSk7CisKKyAgICAgICAgICAgIGlmIChzcmMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICgoKGV2ZW50SWQgPj0gQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX0ZJUlNUKSAmJiAoZXZlbnRJZCA8PSBDb21wb25lbnRFdmVudC5DT01QT05FTlRfTEFTVCkpCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAoKGV2ZW50SWQgPj0gV2luZG93RXZlbnQuV0lORE9XX0ZJUlNUKSAmJiAoZXZlbnRJZCA8PSBXaW5kb3dFdmVudC5XSU5ET1dfTEFTVCkpCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAoZXZlbnRJZCA9PSBOYXRpdmVFdmVudC5JRF9JTlNFVFNfQ0hBTkdFRCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IChldmVudElkID09IE5hdGl2ZUV2ZW50LklEX0JPVU5EU19DSEFOR0VEKQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGV2ZW50SWQgPT0gTmF0aXZlRXZlbnQuSURfVEhFTUVfQ0hBTkdFRCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudERpc3BhdGNoZXIuZGlzcGF0Y2goc3JjLCBldmVudCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoZXZlbnRJZCA+PSBNb3VzZUV2ZW50Lk1PVVNFX0ZJUlNUKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGV2ZW50SWQgPD0gTW91c2VFdmVudC5NT1VTRV9MQVNUKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbW91c2VEaXNwYXRjaGVyLmRpc3BhdGNoKHNyYywgZXZlbnQpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRJZCA9PSBQYWludEV2ZW50LlBBSU5UKSB7CisgICAgICAgICAgICAgICAgICAgIC8vPz8/QVdUOiBzcmMucmVkcmF3TWFuYWdlci5hZGRQYWludFJlZ2lvbihzcmMsIGV2ZW50LmdldENsaXBSZWN0cygpKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChldmVudElkID49IEZvY3VzRXZlbnQuRk9DVVNfRklSU1QpCisgICAgICAgICAgICAgICAgICAgICYmIChldmVudElkIDw9IEZvY3VzRXZlbnQuRk9DVVNfTEFTVCkpIHsKKworICAgICAgICAgICAgICAgIC8vPz8/QVdUOiByZXR1cm4gZm9jdXNEaXNwYXRjaGVyLmRpc3BhdGNoKHNyYywgZXZlbnQpOworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKGV2ZW50SWQgPj0gS2V5RXZlbnQuS0VZX0ZJUlNUKQorICAgICAgICAgICAgICAgICAgICAmJiAoZXZlbnRJZCA8PSBLZXlFdmVudC5LRVlfTEFTVCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4ga2V5RGlzcGF0Y2hlci5kaXNwYXRjaChzcmMsIGV2ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGlzcGF0Y2hlciBvZiBuYXRpdmUgZXZlbnRzIHRoYXQgYWZmZWN0IAorICAgICAqIGNvbXBvbmVudCdzIHN0YXRlIG9yIGJvdW5kcworICAgICAqLworICAgIGZpbmFsIGNsYXNzIENvbXBvbmVudERpc3BhdGNoZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBIYW5kbGUgbmF0aXZlIGV2ZW50IHRoYXQgYWZmZWN0cyBjb21wb25lbnQncyBzdGF0ZSBvciBib3VuZHMKKyAgICAgICAgICogQHBhcmFtIHNyYyAtIHRoZSBjb21wb25lbnQgdXBkYXRlZCBieSB0aGUgZXZlbnQKKyAgICAgICAgICogQHBhcmFtIGV2ZW50IC0gdGhlIG5hdGl2ZSBldmVudAorICAgICAgICAgKiBAcmV0dXJuIC0gYXMgaW4gRGlzcGF0Y2hlci5vbkV2ZW50KCkKKyAgICAgICAgICogQHNlZSBEaXNwYXRjaGVyI29uRXZlbnQoTmF0aXZlRXZlbnQpCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGRpc3BhdGNoKENvbXBvbmVudCBzcmMsIE5hdGl2ZUV2ZW50IGV2ZW50KSB7CisgICAgICAgICAgICBpbnQgaWQgPSBldmVudC5nZXRFdmVudElkKCk7CisKKyAgICAgICAgICAgIGlmICgoaWQgPT0gTmF0aXZlRXZlbnQuSURfSU5TRVRTX0NIQU5HRUQpCisgICAgICAgICAgICAgICAgICAgIHx8IChpZCA9PSBOYXRpdmVFdmVudC5JRF9USEVNRV9DSEFOR0VEKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBkaXNwYXRjaEluc2V0cyhldmVudCwgc3JjKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKGlkID49IFdpbmRvd0V2ZW50LldJTkRPV19GSVJTVCkKKyAgICAgICAgICAgICAgICAgICAgJiYgKGlkIDw9IFdpbmRvd0V2ZW50LldJTkRPV19MQVNUKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBkaXNwYXRjaFdpbmRvdyhldmVudCwgc3JjKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGRpc3BhdGNoUHVyZUNvbXBvbmVudChldmVudCwgc3JjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0b3AtbGV2ZWwgd2luZG93J3MgbmF0aXZlIGRlY29yYXRpb25zIAorICAgICAgICAgKiBAcGFyYW0gZXZlbnQgLSB0aGUgbmF0aXZlIGV2ZW50CisgICAgICAgICAqIEBwYXJhbSBzcmMgLSB0aGUgY29tcG9uZW50IHVwZGF0ZWQgYnkgdGhlIGV2ZW50CisgICAgICAgICAqIEByZXR1cm4gLSBhcyBpbiBEaXNwYXRjaGVyLm9uRXZlbnQoKQorICAgICAgICAgKiBAc2VlIERpc3BhdGNoZXIjb25FdmVudChOYXRpdmVFdmVudCkKKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gZGlzcGF0Y2hJbnNldHMoTmF0aXZlRXZlbnQgZXZlbnQsIENvbXBvbmVudCBzcmMpIHsKKyAgICAgICAgICAgIC8vPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgaWYgKHNyYyBpbnN0YW5jZW9mIFdpbmRvdykgeworICAgICAgICAgICAgICAgICgoV2luZG93KSBzcmMpLnNldE5hdGl2ZUluc2V0cyhldmVudC5nZXRJbnNldHMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRvcC1sZXZlbCB3aW5kb3cncyBzdGF0ZQorICAgICAgICAgKiBAcGFyYW0gZXZlbnQgLSB0aGUgbmF0aXZlIGV2ZW50CisgICAgICAgICAqIEBwYXJhbSBzcmMgLSB0aGUgY29tcG9uZW50IHVwZGF0ZWQgYnkgdGhlIGV2ZW50CisgICAgICAgICAqIEByZXR1cm4gLSBhcyBpbiBEaXNwYXRjaGVyLm9uRXZlbnQoKQorICAgICAgICAgKiBAc2VlIERpc3BhdGNoZXIjb25FdmVudChOYXRpdmVFdmVudCkKKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gZGlzcGF0Y2hXaW5kb3coTmF0aXZlRXZlbnQgZXZlbnQsIENvbXBvbmVudCBzcmMpIHsKKyAgICAgICAgICAgIC8vPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgV2luZG93IHdpbmRvdyA9IChXaW5kb3cpIHNyYzsKKyAgICAgICAgICAgIGludCBpZCA9IGV2ZW50LmdldEV2ZW50SWQoKTsKKworICAgICAgICAgICAgaWYgKGlkID09IFdpbmRvd0V2ZW50LldJTkRPV19DTE9TSU5HKSB7CisgICAgICAgICAgICAgICAgdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpLnBvc3RFdmVudCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFdpbmRvd0V2ZW50KHdpbmRvdywgV2luZG93RXZlbnQuV0lORE9XX0NMT1NJTkcpKTsKKworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChpZCA9PSBXaW5kb3dFdmVudC5XSU5ET1dfU1RBVEVfQ0hBTkdFRCkgeworICAgICAgICAgICAgICAgIGlmICh3aW5kb3cgaW5zdGFuY2VvZiBGcmFtZSkgeworICAgICAgICAgICAgICAgICAgICAoKEZyYW1lKSB3aW5kb3cpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnVwZGF0ZUV4dGVuZGVkU3RhdGUoZXZlbnQuZ2V0V2luZG93U3RhdGUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEhhbmRsZSB0aGUgY2hhbmdlIG9mIGNvbXBvbmVudCdzIHNpemUgYW5kL29yIHBvc2l0aW9uCisgICAgICAgICAqIEBwYXJhbSBldmVudCAtIHRoZSBuYXRpdmUgZXZlbnQKKyAgICAgICAgICogQHBhcmFtIHNyYyAtIHRoZSBjb21wb25lbnQgdXBkYXRlZCBieSB0aGUgZXZlbnQKKyAgICAgICAgICogQHJldHVybiAtIGFzIGluIERpc3BhdGNoZXIub25FdmVudCgpCisgICAgICAgICAqIEBzZWUgRGlzcGF0Y2hlciNvbkV2ZW50KE5hdGl2ZUV2ZW50KQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGRpc3BhdGNoUHVyZUNvbXBvbmVudChOYXRpdmVFdmVudCBldmVudCwgQ29tcG9uZW50IHNyYykgeworICAgICAgICAgICAgUmVjdGFuZ2xlIHJlY3QgPSBldmVudC5nZXRXaW5kb3dSZWN0KCk7CisgICAgICAgICAgICBQb2ludCBsb2MgPSByZWN0LmdldExvY2F0aW9uKCk7CisgICAgICAgICAgICBpbnQgbWFzazsKKworICAgICAgICAgICAgc3dpdGNoIChldmVudC5nZXRFdmVudElkKCkpIHsKKyAgICAgICAgICAgIGNhc2UgTmF0aXZlRXZlbnQuSURfQk9VTkRTX0NIQU5HRUQ6CisgICAgICAgICAgICAgICAgbWFzayA9IDA7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9NT1ZFRDoKKyAgICAgICAgICAgICAgICBtYXNrID0gTmF0aXZlV2luZG93LkJPVU5EU19OT1NJWkU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENvbXBvbmVudEV2ZW50LkNPTVBPTkVOVF9SRVNJWkVEOgorICAgICAgICAgICAgICAgIG1hc2sgPSBOYXRpdmVXaW5kb3cuQk9VTkRTX05PTU9WRTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjEyRT1Vbmtub3duIGNvbXBvbmVudCBldmVudCBpZC4KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMkUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICBpZiAoIShzcmMgaW5zdGFuY2VvZiBXaW5kb3cpKSB7CisgICAgICAgICAgICAgICAgQ29tcG9uZW50IGNvbXBUbyA9IHNyYy5nZXRQYXJlbnQoKTsKKyAgICAgICAgICAgICAgICBDb21wb25lbnQgY29tcEZyb20gPSBzcmMuZ2V0SFdBbmNlc3RvcigpOworCisgICAgICAgICAgICAgICAgaWYgKChjb21wVG8gIT0gbnVsbCkgJiYgKGNvbXBGcm9tICE9IG51bGwpKSB7CisgICAgICAgICAgICAgICAgICAgIGxvYyA9IE1vdXNlRGlzcGF0Y2hlci5jb252ZXJ0UG9pbnQoY29tcEZyb20sIGxvYywgY29tcFRvKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCB3aW5kb3dTdGF0ZSA9IGV2ZW50LmdldFdpbmRvd1N0YXRlKCk7CisKKyAgICAgICAgICAgICAgICBpZiAoKHdpbmRvd1N0YXRlID49IDApICYmIChzcmMgaW5zdGFuY2VvZiBGcmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgKChGcmFtZSkgc3JjKS51cGRhdGVFeHRlbmRlZFN0YXRlKHdpbmRvd1N0YXRlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzcmMuc2V0Qm91bmRzKGxvYy54LCBsb2MueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQsIG1hc2ssIGZhbHNlKTsKKyAgICAgICAgICAgICovCisgICAgICAgICAgICAKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGRpc3BhdGNoZXIgb2YgdGhlIGtleWJvYXJkIGV2ZW50cworICAgICAqLworICAgIGZpbmFsIGNsYXNzIEtleURpc3BhdGNoZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBIYW5kbGUgdGhlIGtleWJvYXJkIGV2ZW50IHVzaW5nIHRoZSBLZXlib2FyZEZvY3VzTWFuYWdlcgorICAgICAgICAgKiBAcGFyYW0gc3JjIC0gdGhlIGNvbXBvbmVudCByZWNlaXZpbmcgdGhlIGV2ZW50CisgICAgICAgICAqIEBwYXJhbSBldmVudCAtIHRoZSBuYXRpdmUgZXZlbnQKKyAgICAgICAgICogQHJldHVybiAtIGFzIGluIERpc3BhdGNoZXIub25FdmVudCgpCisgICAgICAgICAqIEBzZWUgRGlzcGF0Y2hlciNvbkV2ZW50KE5hdGl2ZUV2ZW50KQorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBkaXNwYXRjaChDb21wb25lbnQgc3JjLCBOYXRpdmVFdmVudCBldmVudCkgeworICAgICAgICAgICAgaW50IGlkID0gZXZlbnQuZ2V0RXZlbnRJZCgpOworICAgICAgICAgICAgaW50IG1vZGlmaWVycyA9IGV2ZW50LmdldElucHV0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBpbnQgbG9jYXRpb24gPSBldmVudC5nZXRLZXlMb2NhdGlvbigpOworICAgICAgICAgICAgaW50IGNvZGUgPSBldmVudC5nZXRWS2V5KCk7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgY2hhcnMgPSBldmVudC5nZXRLZXlDaGFycygpOworICAgICAgICAgICAgaW50IGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoKCk7CisgICAgICAgICAgICBsb25nIHRpbWUgPSBldmVudC5nZXRUaW1lKCk7CisgICAgICAgICAgICBjaGFyIGtleUNoYXIgPSBldmVudC5nZXRMYXN0Q2hhcigpOworCisgICAgICAgICAgICAvLz8/P0FXVAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgIGlmIChzcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vcmV0YXJnZXQgZm9jdXMgcHJveHkga2V5IGV2ZW50cyB0byBmb2N1c093bmVyOgorICAgICAgICAgICAgICAgIFdpbmRvdyBmb2N1c1Byb3h5T3duZXIgPSB0b29sa2l0LmdldEZvY3VzUHJveHlPd25lckJ5SWQoZXZlbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRXaW5kb3dJZCgpKTsKKyAgICAgICAgICAgICAgICBpZiAoZm9jdXNQcm94eU93bmVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzcmMgPSBLZXlib2FyZEZvY3VzTWFuYWdlci5hY3R1YWxGb2N1c093bmVyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgRXZlbnRRdWV1ZSBldmVudFF1ZXVlID0gdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpOworICAgICAgICAgICAgCisgICAgICAgICAgICBpZiAoc3JjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBldmVudFF1ZXVlLnBvc3RFdmVudChuZXcgS2V5RXZlbnQoc3JjLCBpZCwgdGltZSwgbW9kaWZpZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgY29kZSwga2V5Q2hhciwgbG9jYXRpb24pKTsKKyAgICAgICAgICAgICAgICAvLyBLRVlfVFlQRUQgZ29lcyBhZnRlciBLRVlfUFJFU1NFRAorICAgICAgICAgICAgICAgIGlmIChpZCA9PSBLZXlFdmVudC5LRVlfUFJFU1NFRCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJzTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleUNoYXIgPSBjaGFycy5jaGFyQXQoaSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q2hhciAhPSBLZXlFdmVudC5DSEFSX1VOREVGSU5FRCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50UXVldWUucG9zdEV2ZW50KG5ldyBLZXlFdmVudChzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXlFdmVudC5LRVlfVFlQRUQsIHRpbWUsIG1vZGlmaWVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleUV2ZW50LlZLX1VOREVGSU5FRCwga2V5Q2hhciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleUV2ZW50LktFWV9MT0NBVElPTl9VTktOT1dOKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0YXJnZXRzIHRoZSBtb3VzZSBldmVudHMgdG8gdGhlIGdyYWIgb3duZXIgd2hlbiBtb3VzZSBpcyBncmFiYmVkLAorICAgICAqIGdyYWIgYW5kIHVuZ3JhYiBtb3VzZSB3aGVuIG1vdXNlIGJ1dHRvbnMgYXJlIHByZXNzZWQgYW5kIHJlbGVhc2VkCisgICAgICovCisKKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgTW91c2VHcmFiTWFuYWdlciB7CisKKyAgICAgICAgLyoqIAorICAgICAgICAgKiBUaGUgdG9wLWxldmVsIHdpbmRvdyBob2xkaW5nIHRoZSBtb3VzZSBncmFiIAorICAgICAgICAgKiB0aGF0IHdhcyBleHBsaWNpdGx5IHN0YXJ0ZWQgYnkgc3RhcnRHcmFiKCkgbWV0aG9kCisgICAgICAgICAqLworICAgICAgICAvLz8/P0FXVDogcHJpdmF0ZSBXaW5kb3cgbmF0aXZlR3JhYk93bmVyID0gbnVsbDsKKyAgICAgICAgLyoqIAorICAgICAgICAgKiBUaGUgY29tcG9uZW50IHRoYXQgb3ducyB0aGUgc3ludGhldGljIAorICAgICAgICAgKiBtb3VzZSBncmFiIHdoaWxlIGF0IGxlYXN0IG9uZSBvZiB0aGUKKyAgICAgICAgICogbW91c2UgYnV0dG9ucyBpcyBwcmVzc2VkCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIENvbXBvbmVudCBzeW50aGV0aWNHcmFiT3duZXIgPSBudWxsOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQcmV2aW91cyB2YWx1ZSBvZiBzeW50aGV0aWNHcmFiT3duZXIKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgQ29tcG9uZW50IGxhc3RTeW50aGV0aWNHcmFiT3duZXIgPSBudWxsOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBOdW1iZXIgb2YgbW91c2UgYnV0dG9ucyBjdXJyZW50bHkgcHJlc3NlZAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgc3ludGhldGljR3JhYkRlcHRoID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBleHBsaWNpdCBtb3VzZSBncmFiIGVuZHMKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgUnVubmFibGUgd2hlbkNhbmNlbGVkOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBFeHBsaWNpdGx5IHN0YXJ0IHRoZSBtb3VzZSBncmFiCisgICAgICAgICAqIEBwYXJhbSBncmFiV2luZG93IC0gdGhlIHdpbmRvdyB0aGF0IHdpbGwgb3duIHRoZSBncmFiCisgICAgICAgICAqIEBwYXJhbSB3aGVuQ2FuY2VsZWQgLSB0aGUgY2FsbGJhY2sgdG8gY2FsbCB3aGVuIHRoZSBncmFiIGVuZHMuIAorICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbAorICAgICAgICAgKi8KKyAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgdm9pZCBzdGFydEdyYWIoV2luZG93IGdyYWJXaW5kb3csIFJ1bm5hYmxlIHdoZW5DYW5jZWxlZCkgeworCisgICAgICAgICAgICBpZiAobmF0aXZlR3JhYk93bmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTJGPUF0dGVtcHQgdG8gc3RhcnQgbmVzdGVkIG1vdXNlIGdyYWIKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMkYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTmF0aXZlV2luZG93IHdpbiA9IGdyYWJXaW5kb3cuZ2V0TmF0aXZlV2luZG93KCk7CisgICAgICAgICAgICBpZiAod2luID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTMwPUF0dGVtcHQgdG8gZ3JhYiBtb3VzZSBpbiBub3QgZGlzcGxheWFibGUgd2luZG93CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTMwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG5hdGl2ZUdyYWJPd25lciA9IGdyYWJXaW5kb3c7CisgICAgICAgICAgICB0aGlzLndoZW5DYW5jZWxlZCA9IHdoZW5DYW5jZWxlZDsKKyAgICAgICAgICAgIHdpbi5ncmFiTW91c2UoKTsKKyAgICAgICAgfQorICAgICAgICAqLworCisgICAgICAgIC8qKgorICAgICAgICAgKiBFbmRzIHRoZSBleHBsaWNpdCBtb3VzZSBncmFiLiBJZiB0aGUgbm9uLW51bGwgY2FsbGJhY2sgd2FzIHByb3ZpZGVkCisgICAgICAgICAqIGluIHRoZSBzdGFydEdyYWIoKSBtZXRob2QsIHRoaXMgY2FsbGJhY2sgaXMgY2FsbGVkIAorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBlbmRHcmFiKCkgeworICAgICAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICBpZiAobmF0aXZlR3JhYk93bmVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFdpbmRvdyBncmFiV2luZG93ID0gbmF0aXZlR3JhYk93bmVyOworICAgICAgICAgICAgbmF0aXZlR3JhYk93bmVyID0gbnVsbDsKKyAgICAgICAgICAgIE5hdGl2ZVdpbmRvdyB3aW4gPSBncmFiV2luZG93LmdldE5hdGl2ZVdpbmRvdygpOworCisgICAgICAgICAgICBpZiAod2luICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB3aW4udW5ncmFiTW91c2UoKTsKKyAgICAgICAgICAgICAgICBpZiAod2hlbkNhbmNlbGVkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgd2hlbkNhbmNlbGVkLnJ1bigpOworICAgICAgICAgICAgICAgICAgICB3aGVuQ2FuY2VsZWQgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICovCisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRW5kcyBib3RoIGV4cGxpY2l0IGFuZCBzeW50aGV0aWMgZ3JhbnMgCisgICAgICAgICAqIEByZXR1cm4gLSBhbHdheXMgcmV0dXJucyBmYWxzZQorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBvbkdyYWJDYW5jZWxlZCgpIHsKKyAgICAgICAgICAgIGVuZEdyYWIoKTsKKyAgICAgICAgICAgIHJlc2V0U3ludGhldGljR3JhYigpOworCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU3RhcnRzIHRoZSBzeW50aGV0aWMgbW91c2UgZ3JhYiwgaW5jcmVhc2VzIHRoZSBjb3VudGVyIAorICAgICAgICAgKiBvZiBjdXJyZW50bHkgcHJlc3NlZCBtb3VzZSBidXR0b25zCisgICAgICAgICAqIEBwYXJhbSBzb3VyY2UgLSB0aGUgY29tcG9uZW50IHdoZXJlIG1vdXNlIHByZXNzIGV2ZW50IG9jY3VyZWQKKyAgICAgICAgICogQHJldHVybiAtIHRoZSBjb21wb25lbnQgdGhhdCBvd25zIHRoZSBzeW50aGV0aWMgZ3JhYgorICAgICAgICAgKi8KKyAgICAgICAgQ29tcG9uZW50IG9uTW91c2VQcmVzc2VkKENvbXBvbmVudCBzb3VyY2UpIHsKKyAgICAgICAgICAgIGlmIChzeW50aGV0aWNHcmFiRGVwdGggPT0gMCkgeworICAgICAgICAgICAgICAgIHN5bnRoZXRpY0dyYWJPd25lciA9IHNvdXJjZTsKKyAgICAgICAgICAgICAgICBsYXN0U3ludGhldGljR3JhYk93bmVyID0gc291cmNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3ludGhldGljR3JhYkRlcHRoKys7CisKKyAgICAgICAgICAgIHJldHVybiBzeW50aGV0aWNHcmFiT3duZXI7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRGVjcmVhc2VzIHRoZSBjb3VudGVyIG9mIGN1cnJlbnRseSBwcmVzc2VkIG1vdXNlIGJ1dHRvbnMsCisgICAgICAgICAqIGVuZHMgdGhlIHN5bnRoZXRpYyBtb3VzZSBncmFiLCB3aGVuIHRoaXMgY291bnRlciBiZWNvbWVzIHplcm8KKyAgICAgICAgICogQHBhcmFtIHNvdXJjZSAtIHRoZSBjb21wb25lbnQgd2hlcmUgbW91c2UgcHJlc3MgZXZlbnQgb2NjdXJlZAorICAgICAgICAgKiBAcmV0dXJuIC0gdGhlIGNvbXBvbmVudCB0aGF0IG93bnMgdGhlIHN5bnRoZXRpYyBncmFiLCAKKyAgICAgICAgICogb3Igc291cmNlIHBhcmFtZXRlciBpZiBtb3VzZSBncmFiIHdhcyByZWxlYXNlZAorICAgICAgICAgKi8KKyAgICAgICAgQ29tcG9uZW50IG9uTW91c2VSZWxlYXNlZChDb21wb25lbnQgc291cmNlKSB7CisgICAgICAgICAgICBDb21wb25lbnQgcmV0ID0gc291cmNlOworCisgICAgICAgICAgICAvLz8/P0FXVAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgIGlmIChzeW50aGV0aWNHcmFiT3duZXIgIT0gbnVsbCAmJiBuYXRpdmVHcmFiT3duZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldCA9IHN5bnRoZXRpY0dyYWJPd25lcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICovCisgICAgICAgICAgICBzeW50aGV0aWNHcmFiRGVwdGgtLTsKKyAgICAgICAgICAgIGlmIChzeW50aGV0aWNHcmFiRGVwdGggPD0gMCkgeworICAgICAgICAgICAgICAgIHJlc2V0U3ludGhldGljR3JhYigpOworICAgICAgICAgICAgICAgIGxhc3RTeW50aGV0aWNHcmFiT3duZXIgPSBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVwZGF0ZSB0aGUgc3RhdGUgb2Ygc3ludGhldGljIG91c2UgZ3JhbSAKKyAgICAgICAgICogd2hlbiB0aGUgbW91c2UgaXMgbW92ZWQvZHJhZ2dlZAorICAgICAgICAgKiBAcGFyYW0gZXZlbnQgLSB0aGUgbmF0aXZlIGV2ZW50CisgICAgICAgICAqLworICAgICAgICB2b2lkIHByZXByb2Nlc3NFdmVudChOYXRpdmVFdmVudCBldmVudCkgeworICAgICAgICAgICAgaW50IGlkID0gZXZlbnQuZ2V0RXZlbnRJZCgpOworICAgICAgICAgICAgc3dpdGNoIChpZCkgeworICAgICAgICAgICAgY2FzZSBNb3VzZUV2ZW50Lk1PVVNFX01PVkVEOgorICAgICAgICAgICAgICAgIGlmIChzeW50aGV0aWNHcmFiT3duZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzeW50aGV0aWNHcmFiT3duZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBzeW50aGV0aWNHcmFiRGVwdGggPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobGFzdFN5bnRoZXRpY0dyYWJPd25lciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3RTeW50aGV0aWNHcmFiT3duZXIgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgTW91c2VFdmVudC5NT1VTRV9EUkFHR0VEOgorICAgICAgICAgICAgICAgIGlmIChzeW50aGV0aWNHcmFiT3duZXIgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgbGFzdFN5bnRoZXRpY0dyYWJPd25lciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY0dyYWJPd25lciA9IGxhc3RTeW50aGV0aWNHcmFiT3duZXI7CisgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY0dyYWJEZXB0aCA9IDA7CisgICAgICAgICAgICAgICAgICAgIGludCBtYXNrID0gZXZlbnQuZ2V0SW5wdXRNb2RpZmllcnMoKTsKKyAgICAgICAgICAgICAgICAgICAgc3ludGhldGljR3JhYkRlcHRoICs9IChtYXNrICYgSW5wdXRFdmVudC5CVVRUT04xX0RPV05fTUFTSykgIT0gMCA/IDEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IDA7CisgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY0dyYWJEZXB0aCArPSAobWFzayAmIElucHV0RXZlbnQuQlVUVE9OMl9ET1dOX01BU0spICE9IDAgPyAxCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwOworICAgICAgICAgICAgICAgICAgICBzeW50aGV0aWNHcmFiRGVwdGggKz0gKG1hc2sgJiBJbnB1dEV2ZW50LkJVVFRPTjNfRE9XTl9NQVNLKSAhPSAwID8gMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHJldHVybiB0aGUgY29tcG9uZW50IHRoYXQgY3VycmVudGx5IG93bnMgdGhlIHN5bnRoZXRpYyBncmFiIAorICAgICAgICAgKi8KKyAgICAgICAgQ29tcG9uZW50IGdldFN5bnRoZXRpY0dyYWJPd25lcigpIHsKKyAgICAgICAgICAgIHJldHVybiBzeW50aGV0aWNHcmFiT3duZXI7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogZW5kcyBzeW50aGV0aWMgZ3JhYgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHJlc2V0U3ludGhldGljR3JhYigpIHsKKyAgICAgICAgICAgIHN5bnRoZXRpY0dyYWJPd25lciA9IG51bGw7CisgICAgICAgICAgICBzeW50aGV0aWNHcmFiRGVwdGggPSAwOworICAgICAgICB9CisKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogRGlzcGF0Y2hlcyBuYXRpdmUgZXZlbnRzIHJlbGF0ZWQgdG8gdGhlIHBvcC11cCBib3hlcyAKKyAgICAgKiAodGhlIG5vbi1jb21wb25lbnQgd2luZG93cyBzdWNoIGFzIG1lbnVzIGFuZCBkcm9wIGxpc3RzKQorICAgICAqLworLy8gICAgZmluYWwgY2xhc3MgUG9wdXBEaXNwYXRjaGVyIHsKKy8vCisvLyAgICAgICAgcHJpdmF0ZSBQb3B1cEJveCBhY3RpdmVQb3B1cDsKKy8vCisvLyAgICAgICAgcHJpdmF0ZSBQb3B1cEJveCB1bmRlckN1cnNvcjsKKy8vCisvLyAgICAgICAgcHJpdmF0ZSBmaW5hbCBNb3VzZUdyYWIgZ3JhYiA9IG5ldyBNb3VzZUdyYWIoKTsKKy8vCisvLyAgICAgICAgLyoqCisvLyAgICAgICAgICogSGFuZGxlcyB0aGUgbW91c2UgZ3JhYiBmb3IgcG9wLXVwIGJveGVzCisvLyAgICAgICAgICovCisvLyAgICAgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBNb3VzZUdyYWIgeworLy8gICAgICAgICAgICBwcml2YXRlIGludCBkZXB0aDsKKy8vCisvLyAgICAgICAgICAgIHByaXZhdGUgUG9wdXBCb3ggb3duZXI7CisvLworLy8gICAgICAgICAgICBwcml2YXRlIGZpbmFsIFBvaW50IHN0YXJ0ID0gbmV3IFBvaW50KCk7CisvLworLy8gICAgICAgICAgICAvKioKKy8vICAgICAgICAgICAgICogU3RhcnRzIHRoZSBncmFiIHdoZW4gbW91c2UgaXMgcHJlc3NlZAorLy8gICAgICAgICAgICAgKiBAcGFyYW0gc3JjIC0gdGhlIHBvcC11cCBib3ggd2hlcmUgbW91c2UgZXZlbnQgaGFzIG9jY3VyZWQKKy8vICAgICAgICAgICAgICogQHBhcmFtIHdoZXJlIC0gdGhlIG1vdXNlIHBvaW50ZXIgbG9jYXRpb24KKy8vICAgICAgICAgICAgICogQHJldHVybiAtIHRoZSBncmFiIG93bmVyCisvLyAgICAgICAgICAgICAqLworLy8gICAgICAgICAgICBQb3B1cEJveCBtb3VzZVByZXNzZWQoUG9wdXBCb3ggc3JjLCBQb2ludCB3aGVyZSkgeworLy8gICAgICAgICAgICAgICAgaWYgKGRlcHRoID09IDApIHsKKy8vICAgICAgICAgICAgICAgICAgICBvd25lciA9IHNyYzsKKy8vICAgICAgICAgICAgICAgICAgICBzdGFydC5zZXRMb2NhdGlvbih3aGVyZSk7CisvLyAgICAgICAgICAgICAgICB9CisvLyAgICAgICAgICAgICAgICBkZXB0aCsrOworLy8gICAgICAgICAgICAgICAgcmV0dXJuIG93bmVyOworLy8gICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICAvKioKKy8vICAgICAgICAgICAgICogRW5kcyB0aGUgZ3JhYiB3aGVuIGFsbCBtb3VzZWJ1dHRvbnMgYXJlIHJlbGVhc2VkCisvLyAgICAgICAgICAgICAqIEBwYXJhbSBzcmMgLSB0aGUgcG9wLXVwIGJveCB3aGVyZSBtb3VzZSBldmVudCBoYXMgb2NjdXJlZAorLy8gICAgICAgICAgICAgKiBAcGFyYW0gd2hlcmUgLSB0aGUgbW91c2UgcG9pbnRlciBsb2NhdGlvbgorLy8gICAgICAgICAgICAgKiBAcmV0dXJuIC0gdGhlIGdyYWIgb3duZXIsIG9yIHNyYyBwYXJhbWV0ZXIgaWYgdGhlIGdyYWIgaGFzIGVuZGVkCisvLyAgICAgICAgICAgICAqLworLy8gICAgICAgICAgICBQb3B1cEJveCBtb3VzZVJlbGVhc2VkKFBvcHVwQm94IHNyYywgUG9pbnQgd2hlcmUpIHsKKy8vICAgICAgICAgICAgICAgIFBvcHVwQm94IHJldCA9IChvd25lciAhPSBudWxsKSA/IG93bmVyIDogc3JjOworLy8gICAgICAgICAgICAgICAgaWYgKGRlcHRoID09IDApIHsKKy8vICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworLy8gICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgICAgZGVwdGgtLTsKKy8vICAgICAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CisvLyAgICAgICAgICAgICAgICAgICAgUG9wdXBCb3ggdGd0ID0gb3duZXI7CisvLyAgICAgICAgICAgICAgICAgICAgb3duZXIgPSBudWxsOworLy8gICAgICAgICAgICAgICAgICAgIGlmICh0Z3QgIT0gbnVsbCAmJiBzcmMgPT0gbnVsbCkgeworLy8gICAgICAgICAgICAgICAgICAgICAgICBQb2ludCBhID0gbmV3IFBvaW50KHN0YXJ0KTsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgUG9pbnQgYiA9IG5ldyBQb2ludCh3aGVyZSk7CisvLyAgICAgICAgICAgICAgICAgICAgICAgIFBvaW50IHBvcyA9IHRndC5nZXRTY3JlZW5Mb2NhdGlvbigpOworLy8gICAgICAgICAgICAgICAgICAgICAgICBhLnRyYW5zbGF0ZSgtcG9zLngsIC1wb3MueSk7CisvLyAgICAgICAgICAgICAgICAgICAgICAgIGIudHJhbnNsYXRlKC1wb3MueCwgLXBvcy55KTsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRndC5jbG9zZU9uVW5ncmFiKGEsIGIpKSB7CisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CisvLyAgICAgICAgICAgIH0KKy8vCisvLyAgICAgICAgICAgIC8qKgorLy8gICAgICAgICAgICAgKiBTZXQgdGhlIGdyYWIgb3duZXIgdG8gbnVsbAorLy8gICAgICAgICAgICAgKi8KKy8vICAgICAgICAgICAgdm9pZCByZXNldCgpIHsKKy8vICAgICAgICAgICAgICAgIGRlcHRoID0gMDsKKy8vICAgICAgICAgICAgICAgIG93bmVyID0gbnVsbDsKKy8vICAgICAgICAgICAgICAgIHN0YXJ0LnNldExvY2F0aW9uKDAsIDApOworLy8gICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICAvKioKKy8vICAgICAgICAgICAgICogQHJldHVybiAtIHRoZSBwb3AtdXAgYm94IGN1cnJlbnRseSBvd25pbmcgdGhlIGdyYWIKKy8vICAgICAgICAgICAgICovCisvLyAgICAgICAgICAgIHB1YmxpYyBQb3B1cEJveCBnZXRPd25lcigpIHsKKy8vICAgICAgICAgICAgICAgIHJldHVybiBvd25lcjsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgLyoqCisvLyAgICAgICAgICogQ2FsbCB0aGUgbW91c2UgZXZlbnQgaGFuZGxlciBvZiB0aGUgcG9wLXVwIGJveAorLy8gICAgICAgICAqIEBwYXJhbSBzcmMgLSB0aGUgcG9wLXVwIGJveCB3aGVyZSB0aGUgbW91c2UgZXZlbnQgb2NjdXJlZAorLy8gICAgICAgICAqIEBwYXJhbSBldmVudElkIC0gdGhlIGV2ZW50IElELCBvbmUgb2YgTW91c2VFdmVudC5NT1VTRV8qIGNvbnN0YW50cworLy8gICAgICAgICAqIEBwYXJhbSB3aGVyZSAtIHRoZSBtb3VzZSBwb2ludGVyIGxvY2F0aW9uCisvLyAgICAgICAgICogQHBhcmFtIGV2ZW50IC0gbmF0aXZlIGV2ZW50CisvLyAgICAgICAgICovCisvLyAgICAgICAgcHJpdmF0ZSB2b2lkIG1vdXNlRXZlbnQoUG9wdXBCb3ggc3JjLCBpbnQgZXZlbnRJZCwgUG9pbnQgd2hlcmUsCisvLyAgICAgICAgICAgICAgICBOYXRpdmVFdmVudCBldmVudCkgeworLy8gICAgICAgICAgICBQb2ludCBwb3MgPSBzcmMuZ2V0U2NyZWVuTG9jYXRpb24oKTsKKy8vICAgICAgICAgICAgcG9zLnNldExvY2F0aW9uKHdoZXJlLnggLSBwb3MueCwgd2hlcmUueSAtIHBvcy55KTsKKy8vCisvLyAgICAgICAgICAgIHNyYy5vbk1vdXNlRXZlbnQoZXZlbnRJZCwgcG9zLCBldmVudC5nZXRNb3VzZUJ1dHRvbigpLCBldmVudAorLy8gICAgICAgICAgICAgICAgICAgIC5nZXRUaW1lKCksIGV2ZW50LmdldElucHV0TW9kaWZpZXJzKCksIGV2ZW50CisvLyAgICAgICAgICAgICAgICAgICAgLmdldFdoZWVsUm90YXRpb24oKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICAvKioKKy8vICAgICAgICAgKiBIYW5kbGUgdGhlIG5hdGl2ZSBldmVudCB0YXJnZXRlZCBieSBhIHBvcC11cCBib3guIFRoaXMgY291bGQgYmUgCisvLyAgICAgICAgICogcGFpbnQgZXZlbnQsIG1vdXNlIG9yIGtleWJvYXJkIGV2ZW50LgorLy8gICAgICAgICAqIEBwYXJhbSBldmVudCAtIHRoZSBuYXRpdmUgZXZlbnQKKy8vICAgICAgICAgKiBAcmV0dXJuIC0gZmFsc2UgaWYgdGhlIGV2ZW50IHdhcyBoYW5kbGVkIGFuZCBkb2Vzbid0IAorLy8gICAgICAgICAqIG5lZWQgdGhlIGZ1cnRoZXIgcHJvY2Vzc2luZzsgdHJ1ZSB3aGVuIHRoZSBmdXJ0aGVyIAorLy8gICAgICAgICAqIHByb2Nlc3NpbmcgaXMgbmVlZGVkCisvLyAgICAgICAgICovCisvLyAgICAgICAgYm9vbGVhbiBvbkV2ZW50KE5hdGl2ZUV2ZW50IGV2ZW50KSB7CisvLyAgICAgICAgICAgIFBvcHVwQm94IHNyYyA9IHRvb2xraXQuZ2V0UG9wdXBCb3hCeUlkKGV2ZW50LmdldFdpbmRvd0lkKCkpOworLy8gICAgICAgICAgICBpbnQgaWQgPSBldmVudC5nZXRFdmVudElkKCk7CisvLworLy8gICAgICAgICAgICBpZiAoKGlkID09IFBhaW50RXZlbnQuUEFJTlQpKSB7CisvLyAgICAgICAgICAgICAgICBpZiAoc3JjICE9IG51bGwpIHsKKy8vICAgICAgICAgICAgICAgICAgICBzcmMucGFpbnQoZXZlbnQuZ2V0Q2xpcFJlY3RzKCkpOworLy8gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworLy8gICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgICAgQ29tcG9uZW50IGMgPSB0b29sa2l0LmdldENvbXBvbmVudEJ5SWQoZXZlbnQuZ2V0V2luZG93SWQoKSk7CisvLyAgICAgICAgICAgICAgICBpZiAoKGMgIT0gbnVsbCkgJiYgKGMgaW5zdGFuY2VvZiBGcmFtZSkpIHsKKy8vICAgICAgICAgICAgICAgICAgICAoKEZyYW1lKSBjKS5wYWludE1lbnVCYXIoZXZlbnQuZ2V0Q2xpcFJlY3RzKCkpOworLy8gICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworLy8gICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICBpZiAoKGlkID49IE1vdXNlRXZlbnQuTU9VU0VfRklSU1QpICYmIChpZCA8PSBNb3VzZUV2ZW50Lk1PVVNFX0xBU1QpKSB7CisvLyAgICAgICAgICAgICAgICBQb2ludCB3aGVyZSA9IGV2ZW50LmdldFNjcmVlblBvcygpOworLy8KKy8vICAgICAgICAgICAgICAgIGlmIChzcmMgIT0gdW5kZXJDdXJzb3IpIHsKKy8vICAgICAgICAgICAgICAgICAgICBpZiAodW5kZXJDdXJzb3IgIT0gbnVsbCkgeworLy8gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZUV2ZW50KHVuZGVyQ3Vyc29yLCBNb3VzZUV2ZW50Lk1PVVNFX0VYSVRFRCwgd2hlcmUsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQpOworLy8gICAgICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgICAgICB1bmRlckN1cnNvciA9IHNyYzsKKy8vICAgICAgICAgICAgICAgICAgICBpZiAodW5kZXJDdXJzb3IgIT0gbnVsbCkgeworLy8gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZUV2ZW50KHVuZGVyQ3Vyc29yLCBNb3VzZUV2ZW50Lk1PVVNFX0VOVEVSRUQsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlcmUsIGV2ZW50KTsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgdW5kZXJDdXJzb3Iuc2V0RGVmYXVsdEN1cnNvcigpOworLy8gICAgICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIGlmIChpZCA9PSBNb3VzZUV2ZW50Lk1PVVNFX0VYSVRFRCkgeworLy8gICAgICAgICAgICAgICAgICAgIHVuZGVyQ3Vyc29yID0gbnVsbDsKKy8vICAgICAgICAgICAgICAgIH0KKy8vCisvLyAgICAgICAgICAgICAgICBpZiAoKGFjdGl2ZVBvcHVwID09IG51bGwpICYmIChzcmMgPT0gbnVsbCB8fCAhc3JjLmlzTWVudUJhcigpKSkgeworLy8gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKy8vICAgICAgICAgICAgICAgIH0KKy8vCisvLyAgICAgICAgICAgICAgICBpZiAoaWQgPT0gTW91c2VFdmVudC5NT1VTRV9QUkVTU0VEKSB7CisvLyAgICAgICAgICAgICAgICAgICAgc3JjID0gZ3JhYi5tb3VzZVByZXNzZWQoc3JjLCB3aGVyZSk7CisvLyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlkID09IE1vdXNlRXZlbnQuTU9VU0VfUkVMRUFTRUQpIHsKKy8vICAgICAgICAgICAgICAgICAgICBzcmMgPSBncmFiLm1vdXNlUmVsZWFzZWQoc3JjLCB3aGVyZSk7CisvLyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNyYyA9PSBudWxsKSB7CisvLyAgICAgICAgICAgICAgICAgICAgc3JjID0gZ3JhYi5nZXRPd25lcigpOworLy8gICAgICAgICAgICAgICAgfQorLy8KKy8vICAgICAgICAgICAgICAgIFBvcHVwQm94IHdhc0FjdGl2ZSA9IGFjdGl2ZVBvcHVwOworLy8KKy8vICAgICAgICAgICAgICAgIGlmIChzcmMgIT0gbnVsbCkgeworLy8gICAgICAgICAgICAgICAgICAgIG1vdXNlRXZlbnQoc3JjLCBpZCwgd2hlcmUsIGV2ZW50KTsKKy8vICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3JjLmlzTWVudSgpIHx8IHNyYy5jb250YWlucyh3aGVyZSk7CisvLyAgICAgICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICAgICAgaWYgKHdhc0FjdGl2ZSAhPSBudWxsICYmIGFjdGl2ZVBvcHVwID09IG51bGwpIHsKKy8vICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2FzQWN0aXZlLmlzTWVudSgpOworLy8gICAgICAgICAgICAgICAgfQorLy8KKy8vICAgICAgICAgICAgICAgIGlmICgoaWQgPT0gTW91c2VFdmVudC5NT1VTRV9QUkVTU0VEKQorLy8gICAgICAgICAgICAgICAgICAgICAgICB8fCAoaWQgPT0gTW91c2VFdmVudC5NT1VTRV9SRUxFQVNFRCkpIHsKKy8vICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzTWVudSA9IGFjdGl2ZVBvcHVwLmlzTWVudSgpOworLy8gICAgICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBbGwoKTsKKy8vICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWlzTWVudTsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworLy8gICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICBpZiAoYWN0aXZlUG9wdXAgPT0gbnVsbCkgeworLy8gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworLy8gICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICBpZiAoKGlkID49IEtleUV2ZW50LktFWV9GSVJTVCkgJiYgKGlkIDw9IEtleUV2ZW50LktFWV9MQVNUKSkgeworLy8gICAgICAgICAgICAgICAgYm9vbGVhbiBpc01lbnUgPSBhY3RpdmVQb3B1cC5pc01lbnUoKTsKKy8vICAgICAgICAgICAgICAgIGFjdGl2ZVBvcHVwLmRpc3BhdGNoS2V5RXZlbnQoaWQsIGV2ZW50LmdldFZLZXkoKSwgZXZlbnQKKy8vICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRpbWUoKSwgZXZlbnQuZ2V0SW5wdXRNb2RpZmllcnMoKSk7CisvLworLy8gICAgICAgICAgICAgICAgcmV0dXJuIGlzTWVudTsKKy8vICAgICAgICAgICAgfQorLy8KKy8vICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgLyoqCisvLyAgICAgICAgICogUmVtZW1iZXIgdGhlIHBvcC11cCBhcyBhY3RpdmUgYW5kIGdyYWIgdGhlIG1vdXNlIG9uIGl0CisvLyAgICAgICAgICogQHBhcmFtIHBvcHVwIC0gdGhlIHBvcC11cCBib3ggdG8gYWN0aXZhdGUKKy8vICAgICAgICAgKi8KKy8vICAgICAgICB2b2lkIGFjdGl2YXRlKGZpbmFsIFBvcHVwQm94IHBvcHVwKSB7CisvLyAgICAgICAgICAgIGlmIChhY3RpdmVQb3B1cCA9PSBudWxsKSB7CisvLworLy8gICAgICAgICAgICAgICAgYWN0aXZlUG9wdXAgPSBwb3B1cDsKKy8vICAgICAgICAgICAgICAgIG1vdXNlR3JhYk1hbmFnZXIuc3RhcnRHcmFiKHBvcHVwLmdldE93bmVyKCksIG5ldyBSdW5uYWJsZSgpIHsKKy8vICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisvLyAgICAgICAgICAgICAgICAgICAgICAgIGRlYWN0aXZhdGUocG9wdXApOworLy8gICAgICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIH0pOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICAvKioKKy8vICAgICAgICAgKiBEZWFjdGl2YXRlIHRoZSBjdXJyZW50bHkgYWN0aXZlIHBvcC11cCBib3gKKy8vICAgICAgICAgKi8KKy8vICAgICAgICB2b2lkIGRlYWN0aXZhdGVBbGwoKSB7CisvLyAgICAgICAgICAgIGRlYWN0aXZhdGUoYWN0aXZlUG9wdXApOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgLyoqCisvLyAgICAgICAgICogRGVhY3RpdmF0ZSB0aGUgcG9wLXVwIGJveCwgZW5kIHRoZSBtb3VzZSBncmFiCisvLyAgICAgICAgICovCisvLyAgICAgICAgdm9pZCBkZWFjdGl2YXRlKFBvcHVwQm94IHBvcHVwKSB7CisvLyAgICAgICAgICAgIGdyYWIucmVzZXQoKTsKKy8vCisvLyAgICAgICAgICAgIGlmIChhY3RpdmVQb3B1cCAhPSBudWxsICYmIGFjdGl2ZVBvcHVwID09IHBvcHVwKSB7CisvLyAgICAgICAgICAgICAgICBhY3RpdmVQb3B1cCA9IG51bGw7CisvLyAgICAgICAgICAgICAgICBtb3VzZUdyYWJNYW5hZ2VyLmVuZEdyYWIoKTsKKy8vICAgICAgICAgICAgICAgIHBvcHVwLmhpZGUoKTsKKy8vICAgICAgICAgICAgICAgIHVuZGVyQ3Vyc29yID0gbnVsbDsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgLyoqCisvLyAgICAgICAgICogQ2hlY2sgdGhhdCB0aGUgcG9wLXVwIGJveCBpcyBjdXJyZW50bHkgYWN0aXZlCisvLyAgICAgICAgICogQHBhcmFtIHBvcHVwIC0gdGhlIHBvcC11cCBib3ggdG8gY2hlY2sKKy8vICAgICAgICAgKiBAcmV0dXJuIC0gdHJ1ZSBpZiBhY3RpdmUKKy8vICAgICAgICAgKi8KKy8vICAgICAgICBib29sZWFuIGlzQWN0aXZlKFBvcHVwQm94IHBvcHVwKSB7CisvLyAgICAgICAgICAgIHJldHVybiAocG9wdXAgPT0gYWN0aXZlUG9wdXApICYmIChwb3B1cCAhPSBudWxsKTsKKy8vICAgICAgICB9CisvLyAgICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvRGlzcGxheU1vZGUuamF2YSBiL2F3dC9qYXZhL2F3dC9EaXNwbGF5TW9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwMjEwMTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvRGlzcGxheU1vZGUuamF2YQpAQCAtMCwwICsxLDE2NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCisvKioKKyAqIFRoZSBEaXNwbGF5TW9kZSBjbGFzcyBjb250YWlucyB0aGUgYml0IGRlcHRoLCBoZWlnaHQsIHdpZHRoIGFuZCByZWZyZXNoIHJhdGUKKyAqIG9mIGEgR3JhcGhpY3NEZXZpY2UuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRGlzcGxheU1vZGUgeworCisgICAgLyoqCisgICAgICogVGhlIHdpZHRoLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IHdpZHRoOworCisgICAgLyoqCisgICAgICogVGhlIGhlaWdodC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBoZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYml0IGRlcHRoLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IGJpdERlcHRoOworCisgICAgLyoqCisgICAgICogVGhlIHJlZnJlc2ggcmF0ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCByZWZyZXNoUmF0ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWYWx1ZSBCSVRfREVQVEhfTVVMVEkgaW5kaWNhdGVzIHRoZSBiaXQgZGVwdGgKKyAgICAgKi8KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9ERVBUSF9NVUxUSSA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFJFRlJFU0hfUkFURV9VTktOT1dOIGluZGljYXRlcyB0aGUgcmVmcmVzaCByYXRlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFRlJFU0hfUkFURV9VTktOT1dOID0gMDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgRGlzcGxheU1vZGUgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBkaXNwbGF5LgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGRpc3BsYXkuCisgICAgICogQHBhcmFtIGJpdERlcHRoCisgICAgICogICAgICAgICAgICB0aGUgYml0IGRlcHRoIG9mIHRoZSBkaXNwbGF5LgorICAgICAqIEBwYXJhbSByZWZyZXNoUmF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHJlZnJlc2ggcmF0ZSBvZiB0aGUgZGlzcGxheS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBEaXNwbGF5TW9kZShpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBiaXREZXB0aCwgaW50IHJlZnJlc2hSYXRlKSB7CisgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgIHRoaXMuYml0RGVwdGggPSBiaXREZXB0aDsKKyAgICAgICAgdGhpcy5yZWZyZXNoUmF0ZSA9IHJlZnJlc2hSYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIGlmIHRoaXMgRGlzcGxheU1vZGUgaXMgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCBvYmplY3Qgb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSBkbQorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGEgRGlzcGxheU1vZGUgd2l0aCB0aGUgc2FtZSBkYXRhCisgICAgICogICAgICAgICB2YWx1ZXMgYXMgdGhpcyBEaXNwbGF5TW9kZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBkbSkgeworICAgICAgICBpZiAoZG0gaW5zdGFuY2VvZiBEaXNwbGF5TW9kZSkgeworICAgICAgICAgICAgcmV0dXJuIGVxdWFscygoRGlzcGxheU1vZGUpZG0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyBpZiB0aGlzIERpc3BsYXlNb2RlIGlzIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgRGlzcGxheU1vZGUgb2JqZWN0CisgICAgICogb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSBkbQorICAgICAqICAgICAgICAgICAgdGhlIERpc3BsYXlNb2RlIHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgYWxsIG9mIHRoZSBkYXRhIHZhbHVlcyBvZiB0aGlzIERpc3BsYXlNb2RlIGFyZSBlcXVhbCB0bworICAgICAqICAgICAgICAgdGhlIHZhbHVlcyBvZiB0aGUgc3BlY2lmaWVkIERpc3BsYXlNb2RlIG9iamVjdCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhEaXNwbGF5TW9kZSBkbSkgeworICAgICAgICBpZiAoZG0gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChkbS5iaXREZXB0aCAhPSBiaXREZXB0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChkbS5yZWZyZXNoUmF0ZSAhPSByZWZyZXNoUmF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChkbS53aWR0aCAhPSB3aWR0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChkbS5oZWlnaHQgIT0gaGVpZ2h0KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYml0IGRlcHRoIG9mIHRoZSBEaXNwbGF5TW9kZSwgcmV0dXJucyBCSVRfREVQVEhfTVVMVEkgdmFsdWUgaWYKKyAgICAgKiBtdWx0aXBsZSBiaXQgZGVwdGhzIGFyZSBzdXBwb3J0ZWQgaW4gdGhpcyBkaXNwbGF5IG1vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYml0IGRlcHRoIG9mIHRoZSBEaXNwbGF5TW9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEJpdERlcHRoKCkgeworICAgICAgICByZXR1cm4gYml0RGVwdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBEaXNwbGF5TW9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhlIERpc3BsYXlNb2RlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SGVpZ2h0KCkgeworICAgICAgICByZXR1cm4gaGVpZ2h0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHJlZnJlc2ggcmF0ZSBvZiB0aGUgRGlzcGxheU1vZGUsIHJldHVybnMgUkVGUkVTSF9SQVRFX1VOS05PV04KKyAgICAgKiB2YWx1ZSBpZiB0aGUgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSByZWZyZXNoIHJhdGUgb2YgdGhlIERpc3BsYXlNb2RlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmVmcmVzaFJhdGUoKSB7CisgICAgICAgIHJldHVybiByZWZyZXNoUmF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aCBvZiB0aGUgRGlzcGxheU1vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd2lkdGggb2YgdGhlIERpc3BsYXlNb2RlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2lkdGgoKSB7CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvRXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9FdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNmE2MWYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvRXZlbnQuamF2YQpAQCAtMCwwICsxLDU5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIFRoZSBFdmVudCBjbGFzcyBpcyBvYnNvbGV0ZSBhbmQgaGFzIGJlZW4gcmVwbGFjZWQgYnkgQVdURXZlbnQgY2xhc3MuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgRXZlbnQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTQ4ODkyMjUwOTQwMDUwNDcwM0w7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0hJRlRfTUFTSyBpbmRpY2F0ZXMgdGhhdCB0aGUgU2hpZnQga2V5IGlzIGRvd24gd2hlbiB0aGUKKyAgICAgKiBldmVudCBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSElGVF9NQVNLID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDVFJMX01BU0sgaW5kaWNhdGVzIHRoYXQgdGhlIENvbnRyb2wga2V5IGlzIGRvd24gd2hlbiB0aGUKKyAgICAgKiBldmVudCBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDVFJMX01BU0sgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1FVEFfTUFTSyBpbmRpY2F0ZXMgdGhhdCB0aGUgTWV0YSBrZXkgaXMgZG93biB3aGVuIHQgaGUKKyAgICAgKiBldmVudCBvY2N1cnJlZCAob3IgdGhlIHJpZ2h0IG1vdXNlIGJ1dHRvbikuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVUQV9NQVNLID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBBTFRfTUFTSyBpbmRpY2F0ZXMgdGhhdCB0aGUgQWx0IGtleSBpcyBkb3duIHdoZW4gdGhlIGV2ZW50CisgICAgICogb2NjdXJyZWQgKG9yIHRoZSBtaWRkbGUgbW91c2UgYnV0dG9uKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTFRfTUFTSyA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSE9NRSBpbmRpY2F0ZXMgSG9tZSBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSE9NRSA9IDEwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRU5EIGluZGljYXRlcyBFbmQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORCA9IDEwMDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUEdVUCBpbmRpY2F0ZXMgUGFnZSBVcCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEdVUCA9IDEwMDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUEdETiBpbmRpY2F0ZXMgUGFnZSBEb3duIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQR0ROID0gMTAwMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBVUCBpbmRpY2F0ZXMgVXAga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVQID0gMTAwNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBET1dOIGluZGljYXRlcyBEb3duIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET1dOID0gMTAwNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBMRUZUIGluZGljYXRlcyBMZWZ0IGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMRUZUID0gMTAwNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBSSUdIVCBpbmRpY2F0ZXMgUmlnaHQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJJR0hUID0gMTAwNzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMSBpbmRpY2F0ZXMgRjEga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEYxID0gMTAwODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMiBpbmRpY2F0ZXMgRjIga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEYyID0gMTAwOTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMyBpbmRpY2F0ZXMgRjMga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEYzID0gMTAxMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGNCBpbmRpY2F0ZXMgRjQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY0ID0gMTAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGNSBpbmRpY2F0ZXMgRjUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY1ID0gMTAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGNiBpbmRpY2F0ZXMgRjYga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY2ID0gMTAxMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGNyBpbmRpY2F0ZXMgRjcga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY3ID0gMTAxNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGOCBpbmRpY2F0ZXMgRjgga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY4ID0gMTAxNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGOSBpbmRpY2F0ZXMgRjkga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEY5ID0gMTAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMTAgaW5kaWNhdGVzIEYxMCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRjEwID0gMTAxNzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMTEgaW5kaWNhdGVzIEYxMSBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRjExID0gMTAxODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGMTIgaW5kaWNhdGVzIEYxMiBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRjEyID0gMTAxOTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBQUklOVF9TQ1JFRU4gaW5kaWNhdGVzIFByaW50IFNjcmVlbiBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJTlRfU0NSRUVOID0gMTAyMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBTQ1JPTExfTE9DSyBpbmRpY2F0ZXMgU2Nyb2xsIExvY2sga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDUk9MTF9MT0NLID0gMTAyMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDQVBTX0xPQ0sgaW5kaWNhdGVzIENhcHMgTG9jayBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FQU19MT0NLID0gMTAyMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBOVU1fTE9DSyBpbmRpY2F0ZXMgTnVtIExvY2sga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTV9MT0NLID0gMTAyMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBQQVVTRSBpbmRpY2F0ZXMgUGF1c2Uga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBVVNFID0gMTAyNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJTlNFUlQgaW5kaWNhdGVzIEluc2VydCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5TRVJUID0gMTAyNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBFTlRFUiBpbmRpY2F0ZXMgRW50ZXIga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVEVSID0gMTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQkFDS19TUEFDRSBpbmRpY2F0ZXMgQmFjayBTcGFjZSBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFDS19TUEFDRSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFCIGluZGljYXRlcyBUQWIga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQiA9IDk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRVNDQVBFIGluZGljYXRlcyBFc2NhcGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVTQ0FQRSA9IDI3OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IERFTEVURSBpbmRpY2F0ZXMgRGVsZXRlIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUxFVEUgPSAxMjc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0lORE9XX0RFU1RST1kgaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgaGFzIGFza2VkCisgICAgICogdGhlIHdpbmRvdyBtYW5hZ2VyIHRvIGtpbGwgdGhlIHdpbmRvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfREVTVFJPWSA9IDIwMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXSU5ET1dfRVhQT1NFIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcyBhc2tlZCB0aGUKKyAgICAgKiB3aW5kb3cgbWFuYWdlciB0byBleHBvc2UgdGhlIHdpbmRvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfRVhQT1NFID0gMjAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRPV19JQ09OSUZZIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcyBhc2tlZAorICAgICAqIHRoZSB3aW5kb3cgbWFuYWdlciB0byBpY29uaWZ5IHRoZSB3aW5kb3cuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORE9XX0lDT05JRlkgPSAyMDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0lORE9XX0RFSUNPTklGWSBpbmRpY2F0ZXMgYW4gZXZlbnQgd2hlbiB0aGUgdXNlciBoYXMgYXNrZWQKKyAgICAgKiB0aGUgd2luZG93IG1hbmFnZXIgdG8gZGVpY29uaWZ5IHRoZSB3aW5kb3cuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORE9XX0RFSUNPTklGWSA9IDIwNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXSU5ET1dfTU9WRUQgaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgaGFzIGFza2VkIHRoZQorICAgICAqIHdpbmRvdyBtYW5hZ2VyIHRvIG1vdmUgdGhlIHdpbmRvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfTU9WRUQgPSAyMDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX1BSRVNTIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIHByZXNzZXMgYSBub3JtYWwKKyAgICAgKiBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VZX1BSRVNTID0gNDAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9SRUxFQVNFIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIHJlbGVhc2VzIGEKKyAgICAgKiBub3JtYWwga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9SRUxFQVNFID0gNDAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9BQ1RJT04gaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgcHJlc3NlZCBhCisgICAgICogbm9uLUFTQ0lJIGFjdGlvbiBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0FDVElPTiA9IDQwMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBLRVlfQUNUSU9OX1JFTEVBU0UgaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgcmVsZWFzZWQKKyAgICAgKiBhIG5vbi1BU0NJSSBhY3Rpb24ga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9BQ1RJT05fUkVMRUFTRSA9IDQwNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNT1VTRV9ET1dOIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcyBwcmVzc2VkIHRoZQorICAgICAqIG1vdXNlIGJ1dHRvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9ET1dOID0gNTAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX1VQIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcyByZWxlYXNlZCB0aGUKKyAgICAgKiBtb3VzZSBidXR0b24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9VU0VfVVAgPSA1MDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTU9VU0VfTU9WRSBpbmRpY2F0ZXMgYW4gZXZlbnQgd2hlbiB0aGUgdXNlciBoYXMgbW92ZWQgdGhlCisgICAgICogbW91c2Ugd2l0aCBubyBidXR0b24gcHJlc3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9NT1ZFID0gNTAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX0VOVEVSIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSBtb3VzZSBoYXMgZW50ZXJlZCBhCisgICAgICogY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PVVNFX0VOVEVSID0gNTA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX0VYSVQgaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIG1vdXNlIGhhcyBleGl0ZWQgYQorICAgICAqIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9FWElUID0gNTA1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PVVNFX0RSQUcgaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgaGFzIG1vdmVkIGEKKyAgICAgKiBtb3VzZSB3aXRoIHRoZSBwcmVzc2VkIGJ1dHRvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9EUkFHID0gNTA2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDUk9MTF9MSU5FX1VQIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcworICAgICAqIGFjdGl2YXRlZCBsaW5lLXVwIGFyZWEgb2Ygc2Nyb2xsYmFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDUk9MTF9MSU5FX1VQID0gNjAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDUk9MTF9MSU5FX0RPV04gaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgaGFzCisgICAgICogYWN0aXZhdGVkIGxpbmUtZG93biBhcmVhIG9mIHNjcm9sbGJhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQ1JPTExfTElORV9ET1dOID0gNjAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDUk9MTF9QQUdFX1VQIGluZGljYXRlcyBhbiBldmVudCB3aGVuIHRoZSB1c2VyIGhhcworICAgICAqIGFjdGl2YXRlZCBwYWdlIHVwIGFyZWEgb2Ygc2Nyb2xsYmFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDUk9MTF9QQUdFX1VQID0gNjAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDUk9MTF9QQUdFX0RPV04gaW5kaWNhdGVzIGFuIGV2ZW50IHdoZW4gdGhlIHVzZXIgaGFzCisgICAgICogYWN0aXZhdGVkIHBhZ2UgZG93biBhcmVhIG9mIHNjcm9sbGJhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQ1JPTExfUEFHRV9ET1dOID0gNjA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDUk9MTF9BQlNPTFVURSBpbmRpY2F0ZXMgYW4gZXZlbnQgd2hlbiB0aGUgdXNlciBoYXMgbW92ZWQKKyAgICAgKiB0aGUgYnViYmxlIGluIGEgc2Nyb2xsIGJhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQ1JPTExfQUJTT0xVVEUgPSA2MDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NST0xMX0JFR0lOIGluZGljYXRlcyBhIHNjcm9sbCBiZWdpbiBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQ1JPTExfQkVHSU4gPSA2MDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NST0xMX0VORCBpbmRpY2F0ZXMgYSBzY3JvbGwgZW5kIGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDUk9MTF9FTkQgPSA2MDc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTElTVF9TRUxFQ1QgaW5kaWNhdGVzIHRoYXQgYW4gaXRlbSBpbiBhIGxpc3QgaGFzIGJlZW4KKyAgICAgKiBzZWxlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMSVNUX1NFTEVDVCA9IDcwMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBMSVNUX0RFU0VMRUNUIGluZGljYXRlcyB0aGF0IGFuIGl0ZW0gaW4gYSBsaXN0IGhhcyBiZWVuCisgICAgICogdW5zZWxlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMSVNUX0RFU0VMRUNUID0gNzAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEFDVElPTl9FVkVOVCBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciB3YW50cyBzb21lIGFjdGlvbiB0bworICAgICAqIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDVElPTl9FVkVOVCA9IDEwMDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTE9BRF9GSUxFIGluZGljYXRlcyBhIGZpbGUgbG9hZGluZyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT0FEX0ZJTEUgPSAxMDAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNBVkVfRklMRSBpbmRpY2F0ZXMgYSBmaWxlIHNhdmluZyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQVZFX0ZJTEUgPSAxMDAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEdPVF9GT0NVUyBpbmRpY2F0ZXMgdGhhdCBhIGNvbXBvbmVudCBnb3QgdGhlIGZvY3VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdPVF9GT0NVUyA9IDEwMDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTE9TVF9GT0NVUyBpbmRpY2F0ZXMgdGhhdCB0aGUgY29tcG9uZW50IGxvc3QgdGhlIGZvY3VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPU1RfRk9DVVMgPSAxMDA1OworCisgICAgLyoqCisgICAgICogVGhlIHRhcmdldCBpcyB0aGUgY29tcG9uZW50IHdpdGggd2hpY2ggdGhlIGV2ZW50IGlzIGFzc29jaWF0ZWQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCB0YXJnZXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd2hlbiBpcyB0aW1lc3RhbXAgd2hlbiBldmVudCBoYXMgb2NjdXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyB3aGVuOworCisgICAgLyoqCisgICAgICogVGhlIGlkIGluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIGludCBpZDsKKworICAgIC8qKgorICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIGludCB4OworCisgICAgLyoqCisgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHk7CisKKyAgICAvKioKKyAgICAgKiBUaGUga2V5IGNvZGUgb2Yga2V5IGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQga2V5OworCisgICAgLyoqCisgICAgICogVGhlIHN0YXRlIG9mIHRoZSBtb2RpZmllciBrZXlzIChnaXZlbiBieSBhIGJpdG1hc2spLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbW9kaWZpZXJzOworCisgICAgLyoqCisgICAgICogVGhlIGNsaWNrIGNvdW50IGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIGNvbnNlY3V0aXZlIGNsaWNrcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNsaWNrQ291bnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXJndW1lbnQgb2YgdGhlIGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgYXJnOworCisgICAgLyoqCisgICAgICogVGhlIG5leHQgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIEV2ZW50IGV2dDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGNvbXBvbmVudCwgZXZlbnQgdHlwZSwKKyAgICAgKiBhbmQgYXJndW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGlkCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgdHlwZS4KKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIEV2ZW50KE9iamVjdCB0YXJnZXQsIGludCBpZCwgT2JqZWN0IGFyZykgeworICAgICAgICB0aGlzKHRhcmdldCwgMGwsIGlkLCAwLCAwLCAwLCAwLCBhcmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGNvbXBvbmVudCwgdGltZSBzdGFtcCwKKyAgICAgKiBldmVudCB0eXBlLCB4IGFuZCB5IGNvb3JkaW5hdGVzLCBrZXlib2FyZCBrZXksIHN0YXRlIG9mIHRoZSBtb2RpZmllcgorICAgICAqIGtleXMsIGFuZCBhbiBhcmd1bWVudCBzZXQgdG8gbnVsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gd2hlbgorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgc3RhbXAuCisgICAgICogQHBhcmFtIGlkCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgdHlwZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5LgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllciBrZXlzIHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBFdmVudChPYmplY3QgdGFyZ2V0LCBsb25nIHdoZW4sIGludCBpZCwgaW50IHgsIGludCB5LCBpbnQga2V5LCBpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHRoaXModGFyZ2V0LCB3aGVuLCBpZCwgeCwgeSwga2V5LCBtb2RpZmllcnMsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGNvbXBvbmVudCwgdGltZSBzdGFtcCwKKyAgICAgKiBldmVudCB0eXBlLCB4IGFuZCB5IGNvb3JkaW5hdGVzLCBrZXlib2FyZCBrZXksIHN0YXRlIG9mIHRoZSBtb2RpZmllcgorICAgICAqIGtleXMsIGFuZCBhbiBhcmd1bWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gd2hlbgorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgc3RhbXAuCisgICAgICogQHBhcmFtIGlkCisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgdHlwZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5LgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllciBrZXlzIHN0YXRlLgorICAgICAqIEBwYXJhbSBhcmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIEV2ZW50KE9iamVjdCB0YXJnZXQsIGxvbmcgd2hlbiwgaW50IGlkLCBpbnQgeCwgaW50IHksIGludCBrZXksIGludCBtb2RpZmllcnMsIE9iamVjdCBhcmcpIHsKKyAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CisgICAgICAgIHRoaXMud2hlbiA9IHdoZW47CisgICAgICAgIHRoaXMuaWQgPSBpZDsKKyAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICAgIHRoaXMubW9kaWZpZXJzID0gbW9kaWZpZXJzOworICAgICAgICB0aGlzLmFyZyA9IGFyZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRXZlbnQuCisgICAgICogCisgICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEV2ZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3Igd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5CisgICAgICAgICAqIHRoZSBmb2xsb3dpbmcgY29kZTogRXZlbnQgZSA9IG5ldyBFdmVudChuZXcgQnV0dG9uKCksIDBsLAorICAgICAgICAgKiBFdmVudC5LRVlfUFJFU1MsIDAsIDAsIEV2ZW50LlRBQiwgRXZlbnQuU0hJRlRfTUFTSywgImFyZyIpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworCisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbIiArIHBhcmFtU3RyaW5nKCkgKyAiXSI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzdGF0ZSBvZiB0aGlzIEV2ZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzdGF0ZSBvZiB0aGlzIEV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiaWQ9IiArIGlkICsgIix4PSIgKyB4ICsgIix5PSIgKyB5ICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgICAgICAgICAoa2V5ICE9IDAgPyAiLGtleT0iICsga2V5ICsgZ2V0TW9kaWZpZXJzU3RyaW5nKCkgOiAiIikgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAiLHRhcmdldD0iICsgdGFyZ2V0ICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIChhcmcgIT0gbnVsbCA/ICIsYXJnPSIgKyBhcmcgOiAiIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGlmaWVycy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RpZmllcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0TW9kaWZpZXJzU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgc3RyTW9kID0gIiI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaWYgKHNoaWZ0RG93bigpKSB7CisgICAgICAgICAgICBzdHJNb2QgKz0gIixzaGlmdCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoY29udHJvbERvd24oKSkgeworICAgICAgICAgICAgc3RyTW9kICs9ICIsY29udHJvbCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAobWV0YURvd24oKSkgeworICAgICAgICAgICAgc3RyTW9kICs9ICIsbWV0YSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RyTW9kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZXMgeCBhbmQgeSBjb29yZGluYXRlcyBvZiBoaXMgZXZlbnQgdG8gdGhlIHgrZHggYW5kIHgrZHkKKyAgICAgKiBjb29yZGluYXRlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBieSB3aGljaCB0aGUgZXZlbnQncyB4IGNvb3JkaW5hdGUgaXMgaW5jcmVhc2VkLgorICAgICAqIEBwYXJhbSBkeQorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIGJ5IHdoaWNoIHRoZSBldmVudCdzIHkgY29vcmRpbmF0ZSBpcyBpbmNyZWFzZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKGludCBkeCwgaW50IGR5KSB7CisgICAgICAgIHggKz0gZHg7CisgICAgICAgIHkgKz0gZHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIENvbnRyb2wga2V5IGlzIGRvd24gb3Igbm90LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgQ29udHJvbCBrZXkgaXMgZG93bjsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRyb2xEb3duKCkgeworICAgICAgICByZXR1cm4gKG1vZGlmaWVycyAmIENUUkxfTUFTSykgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgTWV0YSBrZXkgaXMgZG93biBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBNZXRhIGtleSBpcyBkb3duOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWV0YURvd24oKSB7CisgICAgICAgIHJldHVybiAobW9kaWZpZXJzICYgTUVUQV9NQVNLKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBTaGlmdCBrZXkgaXMgZG93biBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBTaGlmdCBrZXkgaXMgZG93bjsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNoaWZ0RG93bigpIHsKKyAgICAgICAgcmV0dXJuIChtb2RpZmllcnMgJiBTSElGVF9NQVNLKSAhPSAwOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0V2ZW50RGlzcGF0Y2hUaHJlYWQuamF2YSBiL2F3dC9qYXZhL2F3dC9FdmVudERpc3BhdGNoVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQyYzhhMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9FdmVudERpc3BhdGNoVGhyZWFkLmphdmEKQEAgLTAsMCArMSwxMTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92LCBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUV2ZW50OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUV2ZW50UXVldWU7CisKK2NsYXNzIEV2ZW50RGlzcGF0Y2hUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgIHsKKyAgICAKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXJrZXJFdmVudCBleHRlbmRzIEFXVEV2ZW50IHsKKyAgICAgICAgTWFya2VyRXZlbnQoT2JqZWN0IHNvdXJjZSwgaW50IGlkKSB7CisgICAgICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZpbmFsIERpc3BhdGNoZXIgZGlzcGF0Y2hlcjsKKyAgICBmaW5hbCBUb29sa2l0IHRvb2xraXQ7CisgICAgcHJpdmF0ZSBOYXRpdmVFdmVudFF1ZXVlIG5hdGl2ZVF1ZXVlOworCisgICAgcHJvdGVjdGVkIHZvbGF0aWxlIGJvb2xlYW4gc2h1dGRvd25QZW5kaW5nID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXNlIGFuZCBydW4gdGhlIG1haW4gZXZlbnQgbG9vcAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgbmF0aXZlUXVldWUgPSB0b29sa2l0LmdldE5hdGl2ZUV2ZW50UXVldWUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnVuTW9kYWxMb29wKG51bGwpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC5zaHV0ZG93bldhdGNoZG9nLmZvcmNlU2h1dGRvd24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgcnVuTW9kYWxMb29wKE1vZGFsQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIGxvbmcgbGFzdFBhaW50VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICB3aGlsZSAoIXNodXRkb3duUGVuZGluZyAmJiAoY29udGV4dCA9PSBudWxsIHx8IGNvbnRleHQuaXNNb2RhbExvb3BSdW5uaW5nKCkpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgRXZlbnRRdWV1ZSBldmVudFF1ZXVlID0gdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpOworCisgICAgICAgICAgICBOYXRpdmVFdmVudCBuZSA9IG5hdGl2ZVF1ZXVlLmdldE5leHRFdmVudCgpOworICAgICAgICAgICAgaWYgKG5lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBkaXNwYXRjaGVyLm9uRXZlbnQobmUpOworICAgICAgICAgICAgICAgIE1hcmtlckV2ZW50IG1hcmtlciA9IG5ldyBNYXJrZXJFdmVudCh0aGlzLCAwKTsKKyAgICAgICAgICAgICAgICBldmVudFF1ZXVlLnBvc3RFdmVudChtYXJrZXIpOworICAgICAgICAgICAgICAgIGZvciAoQVdURXZlbnQgYWUgPSBldmVudFF1ZXVlLmdldE5leHRFdmVudE5vV2FpdCgpOyAKKyAgICAgICAgICAgICAgICAgICAgICAgIChhZSAhPSBudWxsKSAmJiAoYWUgIT0gbWFya2VyKTsgCisgICAgICAgICAgICAgICAgICAgICAgICBhZSA9IGV2ZW50UXVldWUuZ2V0TmV4dEV2ZW50Tm9XYWl0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZXZlbnRRdWV1ZS5kaXNwYXRjaEV2ZW50KGFlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRvb2xraXQuc2h1dGRvd25XYXRjaGRvZy5zZXROYXRpdmVRdWV1ZUVtcHR5KHRydWUpOworICAgICAgICAgICAgICAgIEFXVEV2ZW50IGFlID0gZXZlbnRRdWV1ZS5nZXROZXh0RXZlbnROb1dhaXQoKTsKKyAgICAgICAgICAgICAgICBpZiAoYWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBldmVudFF1ZXVlLmRpc3BhdGNoRXZlbnQoYWUpOworICAgICAgICAgICAgICAgICAgICBsb25nIGN1clRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1clRpbWUgLSBsYXN0UGFpbnRUaW1lID4gMTApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xraXQub25RdWV1ZUVtcHR5KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFpbnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0b29sa2l0LnNodXRkb3duV2F0Y2hkb2cuc2V0QXd0UXVldWVFbXB0eSh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgdG9vbGtpdC5vblF1ZXVlRW1wdHkoKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFBhaW50VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAgICAgICB3YWl0Rm9yQW55RXZlbnQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgIC8vIFRPRE86IEV4Y2VwdGlvbiBoYW5kbGVyIHNob3VsZCBiZSBpbXBsZW1lbnRlZAorICAgICAgICAgICAgICAgIC8vIHQucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSB2b2lkIHdhaXRGb3JBbnlFdmVudCgpIHsKKyAgICAgICAgRXZlbnRRdWV1ZSBldmVudFF1ZXVlID0gdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpOworICAgICAgICBpZiAoIWV2ZW50UXVldWUuaXNFbXB0eSgpIHx8ICFuYXRpdmVRdWV1ZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBPYmplY3QgZXZlbnRNb25pdG9yID0gbmF0aXZlUXVldWUuZ2V0RXZlbnRNb25pdG9yKCk7CisgICAgICAgIHN5bmNocm9uaXplZChldmVudE1vbml0b3IpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZXZlbnRNb25pdG9yLndhaXQoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHNodXRkb3duKCkgeworICAgICAgICBzaHV0ZG93blBlbmRpbmcgPSB0cnVlOworICAgIH0KKworICAgIEV2ZW50RGlzcGF0Y2hUaHJlYWQoVG9vbGtpdCB0b29sa2l0LCBEaXNwYXRjaGVyIGRpc3BhdGNoZXIgKSB7CisgICAgICAgIHRoaXMudG9vbGtpdCA9IHRvb2xraXQ7CisgICAgICAgIHRoaXMuZGlzcGF0Y2hlciA9IGRpc3BhdGNoZXI7CisgICAgICAgIHNldE5hbWUoIkFXVC1FdmVudERpc3BhdGNoVGhyZWFkIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgc2V0RGFlbW9uKHRydWUpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0V2ZW50UXVldWUuamF2YSBiL2F3dC9qYXZhL2F3dC9FdmVudFF1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI2YTU5MwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9FdmVudFF1ZXVlLmphdmEKQEAgLTAsMCArMSwzMjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92LCBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSW52b2NhdGlvbkV2ZW50OworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkVtcHR5U3RhY2tFeGNlcHRpb247CisKKy8qKgorICogVGhlIEV2ZW50UXVldWUgY2xhc3MgbWFuYWdlcyBldmVudHMuIEl0IGlzIGEgcGxhdGZvcm0taW5kZXBlbmRlbnQgY2xhc3MgdGhhdAorICogcXVldWVzIGV2ZW50cyBib3RoIGZyb20gdGhlIHVuZGVybHlpbmcgcGVlciBjbGFzc2VzIGFuZCBmcm9tIHRydXN0ZWQKKyAqIGFwcGxpY2F0aW9uIGNsYXNzZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgRXZlbnRRdWV1ZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29yZSByZWYuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBFdmVudFF1ZXVlQ29yZUF0b21pY1JlZmVyZW5jZSBjb3JlUmVmID0gbmV3IEV2ZW50UXVldWVDb3JlQXRvbWljUmVmZXJlbmNlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRXZlbnRRdWV1ZUNvcmVBdG9taWNSZWZlcmVuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRXZlbnRRdWV1ZUNvcmVBdG9taWNSZWZlcmVuY2UgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY29yZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgRXZlbnRRdWV1ZUNvcmUgY29yZTsKKworICAgICAgICAvKiBzeW5jaHJvbml6ZWQgKi8KKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgZXZlbnQgcXVldWUgY29yZS4KKyAgICAgICAgICovCisgICAgICAgIEV2ZW50UXVldWVDb3JlIGdldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb3JlOworICAgICAgICB9CisKKyAgICAgICAgLyogc3luY2hyb25pemVkICovCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBuZXdDb3JlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5ldyBjb3JlLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBzZXQoRXZlbnRRdWV1ZUNvcmUgbmV3Q29yZSkgeworICAgICAgICAgICAgY29yZSA9IG5ld0NvcmU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNhbGxpbmcgdGhyZWFkIGlzIHRoZSBjdXJyZW50IEFXVCBFdmVudFF1ZXVlJ3MKKyAgICAgKiBkaXNwYXRjaCB0aHJlYWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgY2FsbGluZyB0aHJlYWQgaXMgdGhlIGN1cnJlbnQgQVdUIEV2ZW50UXVldWUncworICAgICAqICAgICAgICAgZGlzcGF0Y2ggdGhyZWFkOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRGlzcGF0Y2hUaHJlYWQoKSB7CisgICAgICAgIHJldHVybiBUaHJlYWQuY3VycmVudFRocmVhZCgpIGluc3RhbmNlb2YgRXZlbnREaXNwYXRjaFRocmVhZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3N0cyBhbiBJbnZvY2F0aW9uRXZlbnQgd2hpY2ggZXhlY3V0ZXMgdGhlIHJ1bigpIG1ldGhvZCBvbiBhIFJ1bm5hYmxlCisgICAgICogd2hlbiBkaXNwYXRjaGVkIGJ5IHRoZSBBV1QgZXZlbnQgZGlzcGF0Y2hlciB0aHJlYWQuCisgICAgICogCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICB0aGUgUnVubmFibGUgd2hvc2UgcnVuIG1ldGhvZCBzaG91bGQgYmUgZXhlY3V0ZWQgc3luY2hyb25vdXNseQorICAgICAqICAgICAgICAgICAgb24gdGhlIEV2ZW50UXVldWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGludm9rZUxhdGVyKFJ1bm5hYmxlIHJ1bm5hYmxlKSB7CisgICAgICAgIFRvb2xraXQgdG9vbGtpdCA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICAgICAgSW52b2NhdGlvbkV2ZW50IGV2ZW50ID0gbmV3IEludm9jYXRpb25FdmVudCh0b29sa2l0LCBydW5uYWJsZSk7CisgICAgICAgIHRvb2xraXQuZ2V0U3lzdGVtRXZlbnRRdWV1ZUltcGwoKS5wb3N0RXZlbnQoZXZlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvc3RzIGFuIEludm9jYXRpb25FdmVudCB3aGljaCBleGVjdXRlcyB0aGUgcnVuKCkgbWV0aG9kIG9uIGEgUnVubmFibGUKKyAgICAgKiB3aGVuIGRpc3BhdGNoZWQgYnkgdGhlIEFXVCBldmVudCBkaXNwYXRjaGVyIHRocmVhZCBhbmQgdGhlIG5vdGlmeUFsbAorICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgb24gaXQgaW1tZWRpYXRlbHkgYWZ0ZXIgcnVuIHJldHVybnMuCisgICAgICogCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICB0aGUgUnVubmFibGUgd2hvc2UgcnVuIG1ldGhvZCBzaG91bGQgYmUgZXhlY3V0ZWQgc3luY2hyb25vdXNseQorICAgICAqICAgICAgICAgICAgb24gdGhlIEV2ZW50UXVldWUuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGhhcyBpbnRlcnJ1cHRlZCB0aGlzIHRocmVhZC4KKyAgICAgKiBAdGhyb3dzIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBydW5uaW5nIHRoZSBydW5uYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW52b2tlQW5kV2FpdChSdW5uYWJsZSBydW5uYWJsZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKGlzRGlzcGF0Y2hUaHJlYWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBUb29sa2l0IHRvb2xraXQgPSBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCk7CisgICAgICAgIGZpbmFsIE9iamVjdCBub3RpZmllciA9IG5ldyBPYmplY3QoKTsgLy8gJE5PTi1MT0NLLTEkCisgICAgICAgIEludm9jYXRpb25FdmVudCBldmVudCA9IG5ldyBJbnZvY2F0aW9uRXZlbnQodG9vbGtpdCwgcnVubmFibGUsIG5vdGlmaWVyLCB0cnVlKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKG5vdGlmaWVyKSB7CisgICAgICAgICAgICB0b29sa2l0LmdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCkucG9zdEV2ZW50KGV2ZW50KTsKKyAgICAgICAgICAgIG5vdGlmaWVyLndhaXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEV4Y2VwdGlvbiBleGNlcHRpb24gPSBldmVudC5nZXRFeGNlcHRpb24oKTsKKworICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKGV4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzeXN0ZW0gZXZlbnQgcXVldWUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIGV2ZW50IHF1ZXVlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEV2ZW50UXVldWUgZ2V0U3lzdGVtRXZlbnRRdWV1ZSgpIHsKKyAgICAgICAgVGhyZWFkIHRoID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgaWYgKHRoIGluc3RhbmNlb2YgRXZlbnREaXNwYXRjaFRocmVhZCkgeworICAgICAgICAgICAgcmV0dXJuICgoRXZlbnREaXNwYXRjaFRocmVhZCl0aCkudG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1vc3QgcmVjZW50IGV2ZW50J3MgdGltZXN0YW1wLiBUaGlzIGV2ZW50IHdhcyBkaXNwYXRjaGVkIGZyb20KKyAgICAgKiB0aGUgRXZlbnRRdWV1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGNhbGxpbmcgdGhyZWFkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRpbWVzdGFtcCBvZiB0aGUgbGFzdCBFdmVudCB0byBiZSBkaXNwYXRjaGVkLCBvcgorICAgICAqICAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgaWYgdGhpcyBtZXRob2QgaXMgaW52b2tlZCBmcm9tIGEKKyAgICAgKiAgICAgICAgIHRocmVhZCBvdGhlciB0aGFuIGFuIGV2ZW50LWRpc3BhdGNoaW5nIHRocmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgZ2V0TW9zdFJlY2VudEV2ZW50VGltZSgpIHsKKyAgICAgICAgRXZlbnRRdWV1ZSBlcSA9IGdldFN5c3RlbUV2ZW50UXVldWUoKTsKKyAgICAgICAgcmV0dXJuIChlcSAhPSBudWxsKSA/IGVxLmdldE1vc3RSZWNlbnRFdmVudFRpbWVJbXBsKCkgOiBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtb3N0IHJlY2VudCBldmVudCB0aW1lIGltcGwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbW9zdCByZWNlbnQgZXZlbnQgdGltZSBpbXBsLgorICAgICAqLworICAgIHByaXZhdGUgbG9uZyBnZXRNb3N0UmVjZW50RXZlbnRUaW1lSW1wbCgpIHsKKyAgICAgICAgcmV0dXJuIGdldENvcmUoKS5nZXRNb3N0UmVjZW50RXZlbnRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGhlIGN1cnJlbnRseSBkaXNwYXRjaGVkIGV2ZW50IGJ5IHRoZSBFdmVudFF1ZXVlIGFzc29jaWF0ZWQKKyAgICAgKiB3aXRoIHRoZSBjYWxsaW5nIHRocmVhZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50bHkgZGlzcGF0Y2hlZCBldmVudCBvciBudWxsIGlmIHRoaXMgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgKiAgICAgICAgIGZyb20gYSB0aHJlYWQgb3RoZXIgdGhhbiBhbiBldmVudC1kaXNwYXRjaGluZyB0aHJlYWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBV1RFdmVudCBnZXRDdXJyZW50RXZlbnQoKSB7CisgICAgICAgIEV2ZW50UXVldWUgZXEgPSBnZXRTeXN0ZW1FdmVudFF1ZXVlKCk7CisgICAgICAgIHJldHVybiAoZXEgIT0gbnVsbCkgPyBlcS5nZXRDdXJyZW50RXZlbnRJbXBsKCkgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgZXZlbnQgaW1wbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGV2ZW50IGltcGwuCisgICAgICovCisgICAgcHJpdmF0ZSBBV1RFdmVudCBnZXRDdXJyZW50RXZlbnRJbXBsKCkgeworICAgICAgICByZXR1cm4gZ2V0Q29yZSgpLmdldEN1cnJlbnRFdmVudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCBxdWV1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXZlbnRRdWV1ZSgpIHsKKyAgICAgICAgc2V0Q29yZShuZXcgRXZlbnRRdWV1ZUNvcmUodGhpcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBldmVudCBxdWV1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgICAgICAgdGhlIHQuCisgICAgICovCisgICAgRXZlbnRRdWV1ZShUb29sa2l0IHQpIHsKKyAgICAgICAgc2V0Q29yZShuZXcgRXZlbnRRdWV1ZUNvcmUodGhpcywgdCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvc3RzIGEgZXZlbnQgdG8gdGhlIEV2ZW50UXVldWUuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICBBV1RFdmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwb3N0RXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgZXZlbnQuaXNQb3N0ZWQgPSB0cnVlOworICAgICAgICBnZXRDb3JlKCkucG9zdEV2ZW50KGV2ZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGV2ZW50IGZyb20gdGhlIEV2ZW50UXVldWUgYW5kIHJlbW92ZXMgaXQgZnJvbSB0aGlzIHF1ZXVlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG5leHQgQVdURXZlbnQuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlzIHRocm93biBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoaXMgdGhyZWFkLgorICAgICAqLworICAgIHB1YmxpYyBBV1RFdmVudCBnZXROZXh0RXZlbnQoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0Q29yZSgpLmdldE5leHRFdmVudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5leHQgZXZlbnQgbm8gd2FpdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGV2ZW50IG5vIHdhaXQuCisgICAgICovCisgICAgQVdURXZlbnQgZ2V0TmV4dEV2ZW50Tm9XYWl0KCkgeworICAgICAgICByZXR1cm4gZ2V0Q29yZSgpLmdldE5leHRFdmVudE5vV2FpdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpcnN0IGV2ZW50IG9mIHRoZSBFdmVudFF1ZXVlICh3aXRob3V0IHJlbW92aW5nIGl0IGZyb20gdGhlCisgICAgICogcXVldWUpLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRoZSBmaXJzdCBBV1QgZXZlbnQgb2YgdGhlIEV2ZW50UXVldWUuCisgICAgICovCisgICAgcHVibGljIEFXVEV2ZW50IHBlZWtFdmVudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldENvcmUoKS5wZWVrRXZlbnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBldmVudCBvZiB0aGUgRXZlbnRRdWV1ZSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgKHdpdGhvdXQKKyAgICAgKiByZW1vdmluZyBpdCBmcm9tIHRoZSBxdWV1ZSkuCisgICAgICogCisgICAgICogQHBhcmFtIGlkCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBJRCBvZiBldmVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBldmVudCBvZiB0aGUgRXZlbnRRdWV1ZSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuCisgICAgICovCisgICAgcHVibGljIEFXVEV2ZW50IHBlZWtFdmVudChpbnQgaWQpIHsKKyAgICAgICAgcmV0dXJuIGdldENvcmUoKS5wZWVrRXZlbnQoaWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBleGlzdGluZyBFdmVudFF1ZXVlIHdpdGggdGhlIHNwZWNpZmllZCBFdmVudFF1ZXVlLiBBbnkKKyAgICAgKiBwZW5kaW5nIGV2ZW50cyBhcmUgdHJhbnNmZXJyZWQgdG8gdGhlIG5ldyBFdmVudFF1ZXVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuZXdFdmVudFF1ZXVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGV2ZW50IHF1ZXVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1c2goRXZlbnRRdWV1ZSBuZXdFdmVudFF1ZXVlKSB7CisgICAgICAgIGdldENvcmUoKS5wdXNoKG5ld0V2ZW50UXVldWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3BzIGRpc3BhdGNoaW5nIGV2ZW50cyB1c2luZyB0aGlzIEV2ZW50UXVldWUuIEFueSBwZW5kaW5nIGV2ZW50cyBhcmUKKyAgICAgKiB0cmFuc2ZlcnJlZCB0byB0aGUgcHJldmlvdXMgRXZlbnRRdWV1ZS4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIEVtcHR5U3RhY2tFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpcyB0aHJvd24gaWYgbm8gcHJldmlvdXMgcHVzaCB3YXMgbWFkZSBvbiB0aGlzIEV2ZW50UXVldWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcG9wKCkgdGhyb3dzIEVtcHR5U3RhY2tFeGNlcHRpb24geworICAgICAgICBnZXRDb3JlKCkucG9wKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGlzcGF0Y2hlcyB0aGUgc3BlY2lmaWVkIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgZ2V0Q29yZSgpLmRpc3BhdGNoRXZlbnRJbXBsKGV2ZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaXMgZW1wdHkuCisgICAgICovCisgICAgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gZ2V0Q29yZSgpLmlzRW1wdHkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb3JlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNvcmUuCisgICAgICovCisgICAgRXZlbnRRdWV1ZUNvcmUgZ2V0Q29yZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcmVSZWYuZ2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29yZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3Q29yZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBjb3JlLgorICAgICAqLworICAgIHZvaWQgc2V0Q29yZShFdmVudFF1ZXVlQ29yZSBuZXdDb3JlKSB7CisgICAgICAgIGNvcmVSZWYuc2V0KChuZXdDb3JlICE9IG51bGwpID8gbmV3Q29yZSA6IG5ldyBFdmVudFF1ZXVlQ29yZSh0aGlzKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0V2ZW50UXVldWVDb3JlLmphdmEgYi9hd3QvamF2YS9hd3QvRXZlbnRRdWV1ZUNvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmM3YzQ2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0V2ZW50UXVldWVDb3JlLmphdmEKQEAgLTAsMCArMSwyNTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKiogCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZXZlbnQuQWN0aW9uRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5JbnB1dE1ldGhvZEV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lkludm9jYXRpb25FdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50OworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIGV2ZW50cyBzdG9yYWdlIGZvciBFdmVudFF1ZXVlCisgKi8KK2ZpbmFsIGNsYXNzIEV2ZW50UXVldWVDb3JlIHsKKyAgICAKKyAgICBwcml2YXRlIGZpbmFsIExpbmtlZExpc3Q8RXZlbnRRdWV1ZT4gcXVldWVTdGFjayA9IG5ldyBMaW5rZWRMaXN0PEV2ZW50UXVldWU+KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBMaW5rZWRMaXN0PEFXVEV2ZW50PiBldmVudHMgPSBuZXcgTGlua2VkTGlzdDxBV1RFdmVudD4oKTsKKyAgICAKKyAgICBwcml2YXRlIFRvb2xraXQgdG9vbGtpdDsKKyAgICBwcml2YXRlIEV2ZW50UXVldWUgYWN0aXZlUXVldWU7CisgICAgcHJpdmF0ZSBUaHJlYWQgZGlzcGF0Y2hUaHJlYWQ7CisgICAgCisgICAgQVdURXZlbnQgY3VycmVudEV2ZW50OworICAgIGxvbmcgbW9zdFJlY2VudEV2ZW50VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIAorICAgIEV2ZW50UXVldWVDb3JlKEV2ZW50UXVldWUgZXEpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBxdWV1ZVN0YWNrLmFkZExhc3QoZXEpOworICAgICAgICAgICAgYWN0aXZlUXVldWUgPSBlcTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEV2ZW50UXVldWVDb3JlKEV2ZW50UXVldWUgZXEsIFRvb2xraXQgdCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHF1ZXVlU3RhY2suYWRkTGFzdChlcSk7CisgICAgICAgICAgICBhY3RpdmVRdWV1ZSA9IGVxOworICAgICAgICAgICAgc2V0VG9vbGtpdCh0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN5bmNocm9uaXplZCBsb25nIGdldE1vc3RSZWNlbnRFdmVudFRpbWUoKSB7CisgICAgICAgIHJldHVybiBtb3N0UmVjZW50RXZlbnRUaW1lOworICAgIH0KKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgQVdURXZlbnQgZ2V0Q3VycmVudEV2ZW50KCkgeworICAgICAgICByZXR1cm4gY3VycmVudEV2ZW50OworICAgIH0KKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc1N5c3RlbUV2ZW50UXVldWUoKSB7CisgICAgICAgIHJldHVybiB0b29sa2l0ICE9IG51bGw7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgdm9pZCBzZXRUb29sa2l0KFRvb2xraXQgdCkgeworICAgICAgICB0b29sa2l0ID0gdDsKKyAgICAgICAgaWYgKHRvb2xraXQgIT0gbnVsbCkgeworICAgICAgICAgICAgdG9vbGtpdC5zZXRTeXN0ZW1FdmVudFF1ZXVlQ29yZSh0aGlzKTsKKyAgICAgICAgICAgIGRpc3BhdGNoVGhyZWFkID0gdG9vbGtpdC5kaXNwYXRjaFRocmVhZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIHBvc3RFdmVudChBV1RFdmVudCBldmVudCkgeworICAgICAgICAvLz8/P0FXVAorICAgICAgICAvKgorICAgICAgICBldmVudHMuYWRkTGFzdChldmVudCk7CisgICAgICAgIGlmICgodG9vbGtpdCA9PSBudWxsKSAmJiAoZGlzcGF0Y2hUaHJlYWQgPT0gbnVsbCkpIHsKKyAgICAgICAgICAgIGRpc3BhdGNoVGhyZWFkID0gbmV3IEV2ZW50UXVldWVUaHJlYWQodGhpcyk7CisgICAgICAgICAgICBkaXNwYXRjaFRocmVhZC5zdGFydCgpOworICAgICAgICB9CisgICAgICAgIC8vIFRPRE86IGFkZCBldmVudCBjb2FsZXNjaW5nCisgICAgICAgIGlmICh0b29sa2l0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRvb2xraXQuc2h1dGRvd25XYXRjaGRvZy5zZXRBd3RRdWV1ZUVtcHR5KGZhbHNlKTsKKyAgICAgICAgICAgIGlmICghR3JhcGhpY3NFbnZpcm9ubWVudC5nZXRMb2NhbEdyYXBoaWNzRW52aXJvbm1lbnQoKS5pc0hlYWRsZXNzSW5zdGFuY2UoKSkgeworICAgICAgICAgICAgICAgIG5vdGlmeUV2ZW50TW9uaXRvcih0b29sa2l0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgKi8KKyAgICB9CisgICAgCisgICAgdm9pZCBub3RpZnlFdmVudE1vbml0b3IoVG9vbGtpdCB0KSB7CisgICAgICAgIE9iamVjdCBlbSA9IHQuZ2V0TmF0aXZlRXZlbnRRdWV1ZSgpLmdldEV2ZW50TW9uaXRvcigpOworICAgICAgICBzeW5jaHJvbml6ZWQgKGVtKSB7CisgICAgICAgICAgICBlbS5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgQVdURXZlbnQgZ2V0TmV4dEV2ZW50KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKGV2ZW50cy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHdhaXQoKTsKKyAgICAgICAgfQorICAgICAgICBBV1RFdmVudCBldmVudCA9IGV2ZW50cy5yZW1vdmVGaXJzdCgpOworICAgICAgICAvLyBUT0RPOiBhZGQgZXZlbnQgY29hbGVzY2luZworICAgICAgICByZXR1cm4gZXZlbnQ7CisgICAgfSAgICAKKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgQVdURXZlbnQgcGVla0V2ZW50KCkgeworICAgICAgICByZXR1cm4gZXZlbnRzLmlzRW1wdHkoKSA/IG51bGwgOiBldmVudHMuZ2V0Rmlyc3QoKTsKKyAgICB9CisgICAgCisgICAgc3luY2hyb25pemVkIEFXVEV2ZW50IHBlZWtFdmVudChpbnQgaWQpIHsKKyAgICAgICAgZm9yIChBV1RFdmVudCBldmVudCA6IGV2ZW50cykgeworICAgICAgICAgICAgaWYgKGV2ZW50LmdldElEKCkgPT0gaWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCB2b2lkIGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgdXBkYXRlQ3VycmVudEV2ZW50QW5kVGltZShldmVudCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhY3RpdmVRdWV1ZS5kaXNwYXRjaEV2ZW50KGV2ZW50KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGN1cnJlbnRFdmVudCA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgdm9pZCBkaXNwYXRjaEV2ZW50SW1wbChBV1RFdmVudCBldmVudCkgeworICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBBY3RpdmVFdmVudCkgeworICAgICAgICAgICAgdXBkYXRlQ3VycmVudEV2ZW50QW5kVGltZShldmVudCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICgoQWN0aXZlRXZlbnQpIGV2ZW50KS5kaXNwYXRjaCgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjdXJyZW50RXZlbnQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IHNyYyA9IGV2ZW50LmdldFNvdXJjZSgpOworCisgICAgICAgIGlmIChzcmMgaW5zdGFuY2VvZiBDb21wb25lbnQpIHsKKyAgICAgICAgICAgIGlmIChwcmVwcm9jZXNzQ29tcG9uZW50RXZlbnQoZXZlbnQpKSB7CisgICAgICAgICAgICAgICAgKChDb21wb25lbnQpIHNyYykuZGlzcGF0Y2hFdmVudChldmVudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAodG9vbGtpdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG9vbGtpdC5kaXNwYXRjaEFXVEV2ZW50KGV2ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzcmMgaW5zdGFuY2VvZiBNZW51Q29tcG9uZW50KSB7CisgICAgICAgICAgICAgICAgKChNZW51Q29tcG9uZW50KSBzcmMpLmRpc3BhdGNoRXZlbnQoZXZlbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHByZXByb2Nlc3NDb21wb25lbnRFdmVudChBV1RFdmVudCBldmVudCkgeworICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkgeworICAgICAgICAgIHJldHVybiBwcmVwcm9jZXNzTW91c2VFdmVudCgoTW91c2VFdmVudClldmVudCk7CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcHJlcHJvY2Vzc01vdXNlRXZlbnQoTW91c2VFdmVudCBldmVudCkgeworICAgICAgICAvLz8/P0FXVAorICAgICAgICAvKgorICAgICAgaWYgKHRvb2xraXQgIT0gbnVsbCAmJiB0b29sa2l0Lm1vdXNlRXZlbnRQcmVwcm9jZXNzb3IgIT0gbnVsbCkgeworICAgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgIHJldHVybiB0b29sa2l0Lm1vdXNlRXZlbnRQcmVwcm9jZXNzb3IucHJlcHJvY2VzcyhldmVudCk7CisgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgdm9pZCB1cGRhdGVDdXJyZW50RXZlbnRBbmRUaW1lKEFXVEV2ZW50IGV2ZW50KSB7CisgICAgICAgIGN1cnJlbnRFdmVudCA9IGV2ZW50OworICAgICAgICBsb25nIHdoZW4gPSAwOworICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBBY3Rpb25FdmVudCkgeworICAgICAgICAgICAgd2hlbiA9ICgoQWN0aW9uRXZlbnQpIGV2ZW50KS5nZXRXaGVuKCk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgaW5zdGFuY2VvZiBJbnB1dEV2ZW50KSB7CisgICAgICAgICAgICB3aGVuID0gKChJbnB1dEV2ZW50KSBldmVudCkuZ2V0V2hlbigpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50IGluc3RhbmNlb2YgSW5wdXRNZXRob2RFdmVudCkgeworICAgICAgICAgICAgd2hlbiA9ICgoSW5wdXRNZXRob2RFdmVudCkgZXZlbnQpLmdldFdoZW4oKTsKKyAgICAgICAgfSBlbHNlIGlmIChldmVudCBpbnN0YW5jZW9mIEludm9jYXRpb25FdmVudCkgeworICAgICAgICAgICAgd2hlbiA9ICgoSW52b2NhdGlvbkV2ZW50KSBldmVudCkuZ2V0V2hlbigpOworICAgICAgICB9CisgICAgICAgIGlmICh3aGVuICE9IDApIHsKKyAgICAgICAgICAgIG1vc3RSZWNlbnRFdmVudFRpbWUgPSB3aGVuOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCB2b2lkIHB1c2goRXZlbnRRdWV1ZSBuZXdFdmVudFF1ZXVlKSB7CisgICAgICAgIC8vIFRPRE86IGhhbmRsZSBpbmNvcnJlY3Qgc2l0dWF0aW9ucworICAgICAgICBpZiAocXVldWVTdGFjay5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Qj1RdWV1ZSBzdGFjayBpcyBlbXB0eQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBxdWV1ZVN0YWNrLmFkZExhc3QobmV3RXZlbnRRdWV1ZSk7CisgICAgICAgIGFjdGl2ZVF1ZXVlID0gbmV3RXZlbnRRdWV1ZTsKKyAgICAgICAgYWN0aXZlUXVldWUuc2V0Q29yZSh0aGlzKTsKKyAgICB9CisgICAgCisgICAgc3luY2hyb25pemVkIHZvaWQgcG9wKCkgeworICAgICAgICBFdmVudFF1ZXVlIHJlbW92ZWQgPSBxdWV1ZVN0YWNrLnJlbW92ZUxhc3QoKTsKKyAgICAgICAgaWYgKHJlbW92ZWQgIT0gYWN0aXZlUXVldWUpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Qz1FdmVudCBxdWV1ZSBzdGFjayBpcyBicm9rZW4KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNkMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBhY3RpdmVRdWV1ZSA9IHF1ZXVlU3RhY2suZ2V0TGFzdCgpOworICAgICAgICByZW1vdmVkLnNldENvcmUobnVsbCk7CisgICAgfQorCisgICAgc3luY2hyb25pemVkIEFXVEV2ZW50IGdldE5leHRFdmVudE5vV2FpdCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBldmVudHMuaXNFbXB0eSgpID8gbnVsbCA6IGFjdGl2ZVF1ZXVlLmdldE5leHRFdmVudCgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN5bmNocm9uaXplZCBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiAoY3VycmVudEV2ZW50ID09IG51bGwpICYmIGV2ZW50cy5pc0VtcHR5KCk7CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCBib29sZWFuIGlzRW1wdHkobG9uZyB0aW1lb3V0KSB7CisgICAgICAgIGlmICghaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdhaXQodGltZW91dCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisgICAgICAgIHJldHVybiBpc0VtcHR5KCk7CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCBFdmVudFF1ZXVlIGdldEFjdGl2ZUV2ZW50UXVldWUoKSB7CisgICAgICAgIHJldHVybiBhY3RpdmVRdWV1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvRm9udC5qYXZhIGIvYXd0L2phdmEvYXd0L0ZvbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWQ5MzQzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0ZvbnQuamF2YQpAQCAtMCwwICsxLDE1NDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3QuQW5kcm9pZEdyYXBoaWNzMkQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LkZvbnRSZW5kZXJDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhWZWN0b3I7CitpbXBvcnQgamF2YS5hd3QuZm9udC5MaW5lTWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5mb250LlRleHRBdHRyaWJ1dGU7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UcmFuc2Zvcm1BdHRyaWJ1dGU7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS50ZXh0LkNoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuQW5kcm9pZEdseXBoVmVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Db21tb25HbHlwaFZlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuRm9udFBlZXJJbXBsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250TWV0cmljc0ltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkxpbmVNZXRyaWNzSW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5taXNjLkhhc2hDb2RlOworCisvKioKKyAqIFRoZSBGb250IGNsYXNzIHJlcHJlc2VudHMgZm9udHMgZm9yIHJlbmRlcmluZyB0ZXh0LiBUaGlzIGNsYXNzIGFsbG93IHRvIG1hcAorICogY2hhcmFjdGVycyB0byBnbHlwaHMuCisgKiA8cD4KKyAqIEEgZ2x5cGggaXMgYSBzaGFwZSB1c2VkIHRvIHJlbmRlciBhIGNoYXJhY3RlciBvciBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMuCisgKiBGb3IgZXhhbXBsZSBvbmUgY2hhcmFjdGVyIG9mIExhdGluIHdyaXRpbmcgc3lzdGVtIHJlcHJlc2VudGVkIGJ5IG9uZSBnbHlwaCwKKyAqIGJ1dCBpbiBjb21wbGV4IHdyaXRpbmcgc3lzdGVtIHN1Y2ggYXMgU291dGggYW5kIFNvdXRoLUVhc3QgQXNpYW4gdGhlcmUgaXMKKyAqIG1vcmUgY29tcGxpY2F0ZWQgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBjaGFyYWN0ZXJzIGFuZCBnbHlwaHMuCisgKiA8cD4KKyAqIFRoZSBGb250IG9iamVjdCBpcyBpZGVudGlmaWVkIGJ5IHR3byB0eXBlcyBvZiBuYW1lcy4gVGhlIGxvZ2ljYWwgZm9udCBuYW1lIGlzCisgKiB0aGUgbmFtZSB0aGF0IGlzIHVzZWQgdG8gY29uc3RydWN0IHRoZSBmb250LiBUaGUgZm9udCBuYW1lIGlzIHRoZSBuYW1lIG9mIGEKKyAqIHBhcnRpY3VsYXIgZm9udCBmYWNlIChmb3IgZXhhbXBsZSwgQXJpYWwgQm9sZCkuIFRoZSBmYW1pbHkgbmFtZSBpcyB0aGUgZm9udCdzCisgKiBmYW1pbHkgbmFtZSB0aGF0IHNwZWNpZmllcyB0aGUgdHlwb2dyYXBoaWMgZGVzaWduIGFjcm9zcyBzZXZlcmFsIGZhY2VzIChmb3IKKyAqIGV4YW1wbGUsIEFyaWFsKS4gSW4gYWxsIHRoZSBGb250IGlzIGlkZW50aWZpZWQgYnkgdGhyZWUgYXR0cmlidXRlczogdGhlCisgKiBmYW1pbHkgbmFtZSwgdGhlIHN0eWxlIChzdWNoIGFzIGJvbGQgb3IgaXRhbGljKSwgYW5kIHRoZSBzaXplLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZvbnQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQyMDYwMjEzMTE1OTE0NTkyMTNMOworCisgICAgLy8gSWRlbnRpdHkgVHJhbnNmb3JtIGF0dHJpYnV0ZQorICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJREVOVElUWV9UUkFOU0ZPUk0uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVHJhbnNmb3JtQXR0cmlidXRlIElERU5USVRZX1RSQU5TRk9STSA9IG5ldyBUcmFuc2Zvcm1BdHRyaWJ1dGUoCisgICAgICAgICAgICBuZXcgQWZmaW5lVHJhbnNmb3JtKCkpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFBMQUlOIGluZGljYXRlcyBmb250J3MgcGxhaW4gc3R5bGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUExBSU4gPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEJPTEQgaW5kaWNhdGVzIGZvbnQncyBib2xkIHN0eWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJPTEQgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IElUQUxJQyBpbmRpY2F0ZXMgZm9udCdzIGl0YWxpYyBzdHlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJVEFMSUMgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFJPTUFOX0JBU0VMSU5FIGluZGljYXRlZCByb21hbiBiYXNlbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST01BTl9CQVNFTElORSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0VOVEVSX0JBU0VMSU5FIGluZGljYXRlcyBjZW50ZXIgYmFzZWxpbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0VOVEVSX0JBU0VMSU5FID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBIQU5HSU5HX0JBU0VMSU5FIGluZGljYXRlcyBoYW5naW5nIGJhc2VsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhBTkdJTkdfQkFTRUxJTkUgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRSVUVUWVBFX0ZPTlQgaW5kaWNhdGVzIGEgZm9udCByZXNvdXJjZSBvZiB0eXBlIFRSVUVUWVBFLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSVUVUWVBFX0ZPTlQgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEUxX0ZPTlQgaW5kaWNhdGVzIGEgZm9udCByZXNvdXJjZSBvZiB0eXBlIFRZUEUxLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEUxX0ZPTlQgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IExBWU9VVF9MRUZUX1RPX1JJR0hUIGluZGljYXRlcyB0aGF0IHRleHQgaXMgbGVmdCB0byByaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMQVlPVVRfTEVGVF9UT19SSUdIVCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTEFZT1VUX1JJR0hUX1RPX0xFRlQgaW5kaWNhdGVzIHRoYXQgdGV4dCBpcyByaWdodCB0byBsZWZ0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBWU9VVF9SSUdIVF9UT19MRUZUID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBMQVlPVVRfTk9fU1RBUlRfQ09OVEVYVCBpbmRpY2F0ZXMgdGhhdCB0aGUgdGV4dCBpbiB0aGUgY2hhcgorICAgICAqIGFycmF5IGJlZm9yZSB0aGUgaW5kaWNhdGVkIHN0YXJ0IHNob3VsZCBub3QgYmUgZXhhbWluZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFZT1VUX05PX1NUQVJUX0NPTlRFWFQgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IExBWU9VVF9OT19MSU1JVF9DT05URVhUIGluZGljYXRlcyB0aGF0IHRleHQgaW4gdGhlIGNoYXIKKyAgICAgKiBhcnJheSBhZnRlciB0aGUgaW5kaWNhdGVkIGxpbWl0IHNob3VsZCBub3QgYmUgZXhhbWluZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFZT1VUX05PX0xJTUlUX0NPTlRFWFQgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IERFRkFVTFRfRk9OVC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgRm9udCBERUZBVUxUX0ZPTlQgPSBuZXcgRm9udCgiRGlhbG9nIiwgRm9udC5QTEFJTiwgMTIpOyAvLyROT04tTkxTLTEkCisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZSBvZiB0aGUgRm9udC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3R5bGUgb2YgdGhlIEZvbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzdHlsZTsKKworICAgIC8qKgorICAgICAqIFRoZSBzaXplIG9mIHRoZSBGb250LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgc2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBwb2ludCBzaXplIG9mIHRoZSBGb250LgorICAgICAqLworICAgIHByb3RlY3RlZCBmbG9hdCBwb2ludFNpemU7CisKKyAgICAvLyBGbGFnIGlmIHRoZSBGb250IG9iamVjdCB0cmFuc2Zvcm1lZAorICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2Zvcm1lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gdHJhbnNmb3JtZWQ7CisKKyAgICAvLyBTZXQgb2YgZm9udCBhdHRyaWJ1dGVzCisgICAgLyoqCisgICAgICogVGhlIHJlcXVlc3RlZCBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHByaXZhdGUgSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PiBmUmVxdWVzdGVkQXR0cmlidXRlczsKKworICAgIC8vIGZvbnQgcGVlciBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGlzIEZvbnQKKyAgICAvKioKKyAgICAgKiBUaGUgZm9udCBwZWVyLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IEZvbnRQZWVySW1wbCBmb250UGVlcjsKKworICAgIC8vIG51bWJlciBvZiBnbHlwaHMgaW4gdGhpcyBGb250CisgICAgLyoqCisgICAgICogVGhlIG51bSBnbHlwaHMuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IG51bUdseXBocyA9IC0xOworCisgICAgLy8gY29kZSBmb3IgbWlzc2luZyBnbHlwaCBmb3IgdGhpcyBGb250CisgICAgLyoqCisgICAgICogVGhlIG1pc3NpbmcgZ2x5cGggY29kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgbWlzc2luZ0dseXBoQ29kZSA9IC0xOworCisgICAgLyoqCisgICAgICogV3JpdGVzIG9iamVjdCB0byBPYmplY3RPdXRwdXRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBTaWduYWxzIHRoYXQgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIG9iamVjdCBmcm9tIE9iamVjdElucHV0U3RyZWFtIG9iamVjdCBhbmQgc2V0IG5hdGl2ZSBwbGF0Zm9ybQorICAgICAqIGRlcGVuZGVudCBmaWVsZHMgdG8gZGVmYXVsdCB2YWx1ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBvYmplY3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIFNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgY2xhc3Mgbm90IGZvdW5kIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKworICAgICAgICBudW1HbHlwaHMgPSAtMTsKKyAgICAgICAgbWlzc2luZ0dseXBoQ29kZSA9IC0xOworCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEZvbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZXMuIFRoZSBGb250IHdpbGwgYmUKKyAgICAgKiBjcmVhdGVkIHdpdGggZGVmYXVsdCBhdHRyaWJ1dGVzIGlmIHRoZSBhdHRyaWJ1dGUncyBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZXMgdG8gYmUgYXNzaWduZWQgdG8gdGhlIG5ldyBGb250LCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBGb250KE1hcDw/IGV4dGVuZHMgQXR0cmlidXRlLCA/PiBhdHRyaWJ1dGVzKSB7CisgICAgICAgIE9iamVjdCBjdXJyQXR0cjsKKworICAgICAgICAvLyBEZWZhdWx0IHZhbHVlcyBhcmUgdGFrZW4gZnJvbSB0aGUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgRm9udCBjbGFzcy4KKyAgICAgICAgLy8gU2VlIEZvbnQgY29uc3RydWN0b3IsIGRlY29kZSBhbmQgZ2V0Rm9udCBzZWN0aW9ucy4KKworICAgICAgICB0aGlzLm5hbWUgPSAiZGVmYXVsdCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgdGhpcy5zaXplID0gMTI7CisgICAgICAgIHRoaXMucG9pbnRTaXplID0gMTI7CisgICAgICAgIHRoaXMuc3R5bGUgPSBGb250LlBMQUlOOworCisgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKKworICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMgPSBuZXcgSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PihhdHRyaWJ1dGVzKTsKKworICAgICAgICAgICAgY3VyckF0dHIgPSBhdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLlNJWkUpOworICAgICAgICAgICAgaWYgKGN1cnJBdHRyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnBvaW50U2l6ZSA9ICgoRmxvYXQpY3VyckF0dHIpLmZsb2F0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICB0aGlzLnNpemUgPSAoaW50KU1hdGguY2VpbCh0aGlzLnBvaW50U2l6ZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGN1cnJBdHRyID0gYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFKTsKKyAgICAgICAgICAgIGlmIChjdXJyQXR0ciAhPSBudWxsICYmIGN1cnJBdHRyLmVxdWFscyhUZXh0QXR0cmlidXRlLlBPU1RVUkVfT0JMSVFVRSkpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnN0eWxlIHw9IEZvbnQuSVRBTElDOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjdXJyQXR0ciA9IGF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuV0VJR0hUKTsKKyAgICAgICAgICAgIGlmICgoY3VyckF0dHIgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgJiYgKCgoRmxvYXQpY3VyckF0dHIpLmZsb2F0VmFsdWUoKSA+PSAoVGV4dEF0dHJpYnV0ZS5XRUlHSFRfQk9MRCkuZmxvYXRWYWx1ZSgpKSkgeworICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUgfD0gRm9udC5CT0xEOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjdXJyQXR0ciA9IGF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuRkFNSUxZKTsKKyAgICAgICAgICAgIGlmIChjdXJyQXR0ciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gKFN0cmluZyljdXJyQXR0cjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY3VyckF0dHIgPSBhdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLlRSQU5TRk9STSk7CisgICAgICAgICAgICBpZiAoY3VyckF0dHIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChjdXJyQXR0ciBpbnN0YW5jZW9mIFRyYW5zZm9ybUF0dHJpYnV0ZSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybWVkID0gISgoVHJhbnNmb3JtQXR0cmlidXRlKWN1cnJBdHRyKS5nZXRUcmFuc2Zvcm0oKS5pc0lkZW50aXR5KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyQXR0ciBpbnN0YW5jZW9mIEFmZmluZVRyYW5zZm9ybSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybWVkID0gISgoQWZmaW5lVHJhbnNmb3JtKWN1cnJBdHRyKS5pc0lkZW50aXR5KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmUmVxdWVzdGVkQXR0cmlidXRlcyA9IG5ldyBIYXNodGFibGU8QXR0cmlidXRlLCBPYmplY3Q+KDUpOworICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuVFJBTlNGT1JNLCBJREVOVElUWV9UUkFOU0ZPUk0pOworCisgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybWVkID0gZmFsc2U7CisKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLkZBTUlMWSwgbmFtZSk7CisKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLlNJWkUsIG5ldyBGbG9hdCh0aGlzLnNpemUpKTsKKworICAgICAgICAgICAgaWYgKCh0aGlzLnN0eWxlICYgRm9udC5CT0xEKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuV0VJR0hULCBUZXh0QXR0cmlidXRlLldFSUdIVF9CT0xEKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuV0VJR0hULCBUZXh0QXR0cmlidXRlLldFSUdIVF9SRUdVTEFSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgodGhpcy5zdHlsZSAmIEZvbnQuSVRBTElDKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuUE9TVFVSRSwgVGV4dEF0dHJpYnV0ZS5QT1NUVVJFX09CTElRVUUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFLCBUZXh0QXR0cmlidXRlLlBPU1RVUkVfUkVHVUxBUik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGb250IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBzdHlsZSBhbmQgc2l6ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgZm9udC4KKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHlsZSBvZiBmb250LgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiBmb250LgorICAgICAqLworICAgIHB1YmxpYyBGb250KFN0cmluZyBuYW1lLCBpbnQgc3R5bGUsIGludCBzaXplKSB7CisKKyAgICAgICAgdGhpcy5uYW1lID0gKG5hbWUgIT0gbnVsbCkgPyBuYW1lIDogIkRlZmF1bHQiOyAvLyROT04tTkxTLTEkCisgICAgICAgIHRoaXMuc2l6ZSA9IChzaXplID49IDApID8gc2l6ZSA6IDA7CisgICAgICAgIHRoaXMuc3R5bGUgPSAoc3R5bGUgJiB+MHgwMykgPT0gMCA/IHN0eWxlIDogRm9udC5QTEFJTjsKKyAgICAgICAgdGhpcy5wb2ludFNpemUgPSB0aGlzLnNpemU7CisKKyAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMgPSBuZXcgSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0Pig1KTsKKworICAgICAgICBmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5UUkFOU0ZPUk0sIElERU5USVRZX1RSQU5TRk9STSk7CisKKyAgICAgICAgdGhpcy50cmFuc2Zvcm1lZCA9IGZhbHNlOworCisgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLkZBTUlMWSwgdGhpcy5uYW1lKTsKKyAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuU0laRSwgbmV3IEZsb2F0KHRoaXMuc2l6ZSkpOworCisgICAgICAgIGlmICgodGhpcy5zdHlsZSAmIEZvbnQuQk9MRCkgIT0gMCkgeworICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuV0VJR0hULCBUZXh0QXR0cmlidXRlLldFSUdIVF9CT0xEKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLldFSUdIVCwgVGV4dEF0dHJpYnV0ZS5XRUlHSFRfUkVHVUxBUik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCh0aGlzLnN0eWxlICYgRm9udC5JVEFMSUMpICE9IDApIHsKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLlBPU1RVUkUsIFRleHRBdHRyaWJ1dGUuUE9TVFVSRV9PQkxJUVVFKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLlBPU1RVUkUsIFRleHRBdHRyaWJ1dGUuUE9TVFVSRV9SRUdVTEFSKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIEZvbnQgaGFzIGEgZ2x5cGggZm9yIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIEZvbnQgaGFzIGEgZ2x5cGggZm9yIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbkRpc3BsYXkoY2hhciBjKSB7CisgICAgICAgIEZvbnRQZWVySW1wbCBwZWVyID0gKEZvbnRQZWVySW1wbCl0aGlzLmdldFBlZXIoKTsKKyAgICAgICAgcmV0dXJuIHBlZXIuY2FuRGlzcGxheShjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIEZvbnQgY2FuIGRpc3BsYXkgdGhlIGNoYXJhY3RlcnMgb2YgdGhlIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB0ZXh0IGZyb20gdGhlIHNwZWNpZmllZCBzdGFydCBwb3NpdGlvbiB0byB0aGUgc3BlY2lmaWVkIGxpbWl0IHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0ZXh0CisgICAgICogICAgICAgICAgICB0aGUgdGV4dC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQgKGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkpLgorICAgICAqIEBwYXJhbSBsaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGxpbWl0IG9mZnNldCAoaW4gdGhlIGNoYXJhY3RlciBhcnJheSkuCisgICAgICogQHJldHVybiB0aGUgYSBjaGFyYWN0ZXIncyBwb3NpdGlvbiBpbiB0aGUgdGV4dCB0aGF0IHRoaXMgRm9udCBjYW4gbm90CisgICAgICogICAgICAgICBkaXNwbGF5LCBvciAtMSBpZiB0aGlzIEZvbnQgY2FuIGRpc3BsYXkgYWxsIGNoYXJhY3RlcnMgaW4gdGhpcworICAgICAqICAgICAgICAgdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNhbkRpc3BsYXlVcFRvKGNoYXJbXSB0ZXh0LCBpbnQgc3RhcnQsIGludCBsaW1pdCkgeworICAgICAgICBpbnQgc3QgPSBzdGFydDsKKyAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgd2hpbGUgKChzdCA8IGxpbWl0KSAmJiBjYW5EaXNwbGF5KHRleHRbc3RdKSkgeworICAgICAgICAgICAgc3QrKzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdCA9PSBsaW1pdCkgeworICAgICAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQgPSBzdDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBGb250IGNhbiBkaXNwbGF5IHRoZSBjaGFyYWN0ZXJzIG9mIHRoZSB0aGUgc3BlY2lmaWVkCisgICAgICogQ2hhcmFjdGVySXRlcmF0b3IgZnJvbSB0aGUgc3BlY2lmaWVkIHN0YXJ0IHBvc2l0aW9uIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogbGltaXQgcG9zaXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGl0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBDaGFyYWN0ZXJJdGVyYXRvci4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbGltaXQgb2Zmc2V0LgorICAgICAqIEByZXR1cm4gdGhlIGEgY2hhcmFjdGVyJ3MgcG9zaXRpb24gaW4gdGhlIENoYXJhY3Rlckl0ZXJhdG9yIHRoYXQgdGhpcworICAgICAqICAgICAgICAgRm9udCBjYW4gbm90IGRpc3BsYXksIG9yIC0xIGlmIHRoaXMgRm9udCBjYW4gZGlzcGxheSBhbGwKKyAgICAgKiAgICAgICAgIGNoYXJhY3RlcnMgaW4gdGhpcyB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2FuRGlzcGxheVVwVG8oQ2hhcmFjdGVySXRlcmF0b3IgaXRlciwgaW50IHN0YXJ0LCBpbnQgbGltaXQpIHsKKyAgICAgICAgaW50IHN0ID0gc3RhcnQ7CisgICAgICAgIGNoYXIgYyA9IGl0ZXIuc2V0SW5kZXgoc3RhcnQpOworICAgICAgICBpbnQgcmVzdWx0OworCisgICAgICAgIHdoaWxlICgoc3QgPCBsaW1pdCkgJiYgKGNhbkRpc3BsYXkoYykpKSB7CisgICAgICAgICAgICBzdCsrOworICAgICAgICAgICAgYyA9IGl0ZXIubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGlmIChzdCA9PSBsaW1pdCkgeworICAgICAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQgPSBzdDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgRm9udCBjYW4gZGlzcGxheSBhIHNwZWNpZmllZCBTdHJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZy4KKyAgICAgKiBAcmV0dXJuIHRoZSBhIGNoYXJhY3RlcidzIHBvc2l0aW9uIGluIHRoZSBTdHJpbmcgdGhhdCB0aGlzIEZvbnQgY2FuIG5vdAorICAgICAqICAgICAgICAgZGlzcGxheSwgb3IgLTEgaWYgdGhpcyBGb250IGNhbiBkaXNwbGF5IGFsbCBjaGFyYWN0ZXJzIGluIHRoaXMKKyAgICAgKiAgICAgICAgIHRleHQuCisgICAgICovCisgICAgcHVibGljIGludCBjYW5EaXNwbGF5VXBUbyhTdHJpbmcgc3RyKSB7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IHN0ci50b0NoYXJBcnJheSgpOworICAgICAgICByZXR1cm4gY2FuRGlzcGxheVVwVG8oY2hhcnMsIDAsIGNoYXJzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEdseXBoVmVjdG9yIG9mIGFzc29jaWF0aW5nIGNoYXJhY3RlcnMgdG8gZ2x5cGhzIGJhc2VkIG9uIHRoZQorICAgICAqIFVuaWNvZGUgbWFwIG9mIHRoaXMgRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHBhcmFtIGNoYXJzCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVycyBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBHbHlwaFZlY3RvciBvZiBhc3NvY2lhdGluZyBjaGFyYWN0ZXJzIHRvIGdseXBocyBiYXNlZCBvbiB0aGUKKyAgICAgKiAgICAgICAgIFVuaWNvZGUgbWFwIG9mIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2x5cGhWZWN0b3IgY3JlYXRlR2x5cGhWZWN0b3IoRm9udFJlbmRlckNvbnRleHQgZnJjLCBjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBbmRyb2lkR2x5cGhWZWN0b3IoY2hhcnMsIGZyYywgdGhpcywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEdseXBoVmVjdG9yIG9mIGFzc29jaWF0aW5nIGNoYXJhY3RlcnMgY29udGFpbmVkIGluIHRoZQorICAgICAqIHNwZWNpZmllZCBDaGFyYWN0ZXJJdGVyYXRvciB0byBnbHlwaHMgYmFzZWQgb24gdGhlIFVuaWNvZGUgbWFwIG9mIHRoaXMKKyAgICAgKiBGb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiBAcGFyYW0gaXRlcgorICAgICAqICAgICAgICAgICAgdGhlIENoYXJhY3Rlckl0ZXJhdG9yLgorICAgICAqIEByZXR1cm4gdGhlIEdseXBoVmVjdG9yIG9mIGFzc29jaWF0aW5nIGNoYXJhY3RlcnMgY29udGFpbmVkIGluIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIENoYXJhY3Rlckl0ZXJhdG9yIHRvIGdseXBocyBiYXNlZCBvbiB0aGUgVW5pY29kZSBtYXAgb2YKKyAgICAgKiAgICAgICAgIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2x5cGhWZWN0b3IgY3JlYXRlR2x5cGhWZWN0b3IoRm9udFJlbmRlckNvbnRleHQgZnJjLCBDaGFyYWN0ZXJJdGVyYXRvciBpdGVyKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7IC8vJE5PTi1OTFMtMSQgICAgCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEdseXBoVmVjdG9yIG9mIGFzc29jaWF0aW5nIGNoYXJhY3RlcnMgdG8gZ2x5cGhzIGJhc2VkIG9uIHRoZQorICAgICAqIFVuaWNvZGUgbWFwIG9mIHRoaXMgRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHBhcmFtIGdseXBoQ29kZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW50ZWdlciBhcnJheSBvZiBnbHlwaCBjb2Rlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBHbHlwaFZlY3RvciBvZiBhc3NvY2lhdGluZyBjaGFyYWN0ZXJzIHRvIGdseXBocyBiYXNlZCBvbiB0aGUKKyAgICAgKiAgICAgICAgIFVuaWNvZGUgbWFwIG9mIHRoaXMgRm9udC4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGJ5IGEgc3ViY2xhc3MuCisgICAgICovCisgICAgcHVibGljIEdseXBoVmVjdG9yIGNyZWF0ZUdseXBoVmVjdG9yKEZvbnRSZW5kZXJDb250ZXh0IGZyYywgaW50W10gZ2x5cGhDb2RlcykKKyAgICAgICAgICAgIHRocm93cyBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBHbHlwaFZlY3RvciBvZiBhc3NvY2lhdGluZyBjaGFyYWN0ZXJzIHRvIGdseXBocyBiYXNlZCBvbiB0aGUKKyAgICAgKiBVbmljb2RlIG1hcCBvZiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIEdseXBoVmVjdG9yIG9mIGFzc29jaWF0aW5nIGNoYXJhY3RlcnMgdG8gZ2x5cGhzIGJhc2VkIG9uIHRoZQorICAgICAqICAgICAgICAgVW5pY29kZSBtYXAgb2YgdGhpcyBGb250LgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaFZlY3RvciBjcmVhdGVHbHlwaFZlY3RvcihGb250UmVuZGVyQ29udGV4dCBmcmMsIFN0cmluZyBzdHIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBbmRyb2lkR2x5cGhWZWN0b3Ioc3RyLnRvQ2hhckFycmF5KCksIGZyYywgdGhpcywgMCk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmb250IHN0eWxlIGNvbnN0YW50IHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gb25lIG9mIHRoZSBmb250CisgICAgICogc3R5bGUgbmFtZXMgKCJCT0xEIiwgIklUQUxJQyIsICJCT0xESVRBTElDIikuIFRoaXMgbWV0aG9kIHJldHVybnMKKyAgICAgKiBGb250LlBMQUlOIGlmIHRoZSBhcmd1bWVudCBpcyBub3Qgb25lIG9mIHRoZSBwcmVkZWZpbmVkIHN0eWxlIG5hbWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250U3R5bGVOYW1lCisgICAgICogICAgICAgICAgICBmb250IHN0eWxlIG5hbWUuCisgICAgICogQHJldHVybiBmb250IHN0eWxlIGNvbnN0YW50IHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZvbnQgc3R5bGUgbmFtZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBnZXRGb250U3R5bGUoU3RyaW5nIGZvbnRTdHlsZU5hbWUpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IEZvbnQuUExBSU47CisKKyAgICAgICAgaWYgKGZvbnRTdHlsZU5hbWUudG9VcHBlckNhc2UoKS5lcXVhbHMoIkJPTERJVEFMSUMiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICByZXN1bHQgPSBGb250LkJPTEQgfCBGb250LklUQUxJQzsKKyAgICAgICAgfSBlbHNlIGlmIChmb250U3R5bGVOYW1lLnRvVXBwZXJDYXNlKCkuZXF1YWxzKCJCT0xEIikpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgcmVzdWx0ID0gRm9udC5CT0xEOworICAgICAgICB9IGVsc2UgaWYgKGZvbnRTdHlsZU5hbWUudG9VcHBlckNhc2UoKS5lcXVhbHMoIklUQUxJQyIpKSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIHJlc3VsdCA9IEZvbnQuSVRBTElDOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHdoaWNoIGRlc2NyaWJlZCB0aGUgRm9udC4gVGhlIHN0cmluZyBzaG91bGQKKyAgICAgKiBoYXZlIHRoZSBmb2xsb3dpbmcgZm9ybWF0OiBmb250bmFtZS1zdHlsZS1wb2ludHNpemUuIFRoZSBzdHlsZSBjYW4gYmUKKyAgICAgKiBQTEFJTiwgQk9MRCwgQk9MRElUQUxJQywgb3IgSVRBTElDLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgd2hpY2ggZGVzY3JpYmVzIHRoZSBmb250LgorICAgICAqIEByZXR1cm4gdGhlIEZvbnQgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZvbnQgZGVjb2RlKFN0cmluZyBzdHIpIHsKKyAgICAgICAgLy8gWFhYOiBEb2N1bWVudGF0aW9uIGRvZXNuJ3QgZGVzY3JpYmUgYWxsIGNhc2VzLCBlLmcuIGZvbnRzIGZhY2UgbmFtZXMKKyAgICAgICAgLy8gd2l0aAorICAgICAgICAvLyBzeW1ib2xzIHRoYXQgYXJlIHN1Z2dlc3RlZCBhcyBkZWxpbWl0ZXJzIGluIHRoZSBkb2N1bWVudGF0aW9uLgorICAgICAgICAvLyBJbiB0aGlzIGRlY29kZSBpbXBsZW1lbnRhdGlvbiBvbmx5ICoqKi0qKiotKioqIGZvcm1hdCBpcyB1c2VkIHdpdGgKKyAgICAgICAgLy8gJy0nCisgICAgICAgIC8vIGFzIHRoZSBkZWxpbWl0ZXIgdG8gYXZvaWQgdW5leHBlY3RlZCBwYXJzZSByZXN1bHRzIG9mIGZvbnQgZmFjZSBuYW1lcworICAgICAgICAvLyB3aXRoIHNwYWNlcy4KKworICAgICAgICBpZiAoc3RyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBERUZBVUxUX0ZPTlQ7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdUb2tlbml6ZXIgc3RyVG9rZW5zOworICAgICAgICBTdHJpbmcgZGVsaW0gPSAiLSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIHN1YnN0cjsKKworICAgICAgICBpbnQgZm9udFNpemUgPSBERUZBVUxUX0ZPTlQuc2l6ZTsKKyAgICAgICAgaW50IGZvbnRTdHlsZSA9IERFRkFVTFRfRk9OVC5zdHlsZTsKKyAgICAgICAgU3RyaW5nIGZvbnROYW1lID0gREVGQVVMVF9GT05ULm5hbWU7CisKKyAgICAgICAgc3RyVG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihzdHIudHJpbSgpLCBkZWxpbSk7CisKKyAgICAgICAgLy8gRm9udCBOYW1lCisgICAgICAgIGlmIChzdHJUb2tlbnMuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBmb250TmFtZSA9IHN0clRva2Vucy5uZXh0VG9rZW4oKTsgLy8gZmlyc3QgdG9rZW4gaXMgdGhlIGZvbnQgbmFtZQorICAgICAgICB9CisKKyAgICAgICAgLy8gRm9udCBTdHlsZSBvciBTaXplIChpZiB0aGUgc3R5bGUgaXMgdW5kZWZpbmVkKQorICAgICAgICBpZiAoc3RyVG9rZW5zLmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgc3Vic3RyID0gc3RyVG9rZW5zLm5leHRUb2tlbigpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIGlmIHNlY29uZCB0b2tlbiBpcyB0aGUgZm9udCBzaXplCisgICAgICAgICAgICAgICAgZm9udFNpemUgPSBJbnRlZ2VyLnBhcnNlSW50KHN1YnN0cik7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHRoZW4gc2Vjb25kIHRva2VuIGlzIHRoZSBmb250IHN0eWxlCisgICAgICAgICAgICAgICAgZm9udFN0eWxlID0gZ2V0Rm9udFN0eWxlKHN1YnN0cik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZvbnQgU2l6ZQorICAgICAgICBpZiAoc3RyVG9rZW5zLmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmb250U2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc3RyVG9rZW5zLm5leHRUb2tlbigpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEZvbnQoZm9udE5hbWUsIGZvbnRTdHlsZSwgZm9udFNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSBzcGVjaWZpZWQgYWZmaW5lIHRyYW5zZm9ybSB0byB0aGUgRm9udCBhbmQgcmV0dXJucyBhIG5ldworICAgICAqIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHRyYW5zCisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqIEByZXR1cm4gdGhlIEZvbnQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYWZmaW5lIHRyYW5zZm9ybSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgRm9udCBkZXJpdmVGb250KEFmZmluZVRyYW5zZm9ybSB0cmFucykgeworCisgICAgICAgIGlmICh0cmFucyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuOTQ9dHJhbnNmb3JtIGNhbiBub3QgYmUgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PiBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcyA9IChIYXNodGFibGU8QXR0cmlidXRlLCBPYmplY3Q+KWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgLmNsb25lKCk7CisKKyAgICAgICAgZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuVFJBTlNGT1JNLCBuZXcgVHJhbnNmb3JtQXR0cmlidXRlKHRyYW5zKSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBGb250KGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgRm9udCB0aGF0IGlzIGEgY29weSBvZiB0aGUgY3VycmVudCBGb250IG1vZGlmaWVkIHNvIHRoYXQKKyAgICAgKiB0aGUgc2l6ZSBpcyB0aGUgc3BlY2lmaWVkIHNpemUuCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIGZvbnQuCisgICAgICogQHJldHVybiB0aGUgRm9udCBvYmplY3QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEZvbnQgZGVyaXZlRm9udChmbG9hdCBzaXplKSB7CisgICAgICAgIEhhc2h0YWJsZTxBdHRyaWJ1dGUsIE9iamVjdD4gZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMgPSAoSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PilmUmVxdWVzdGVkQXR0cmlidXRlcworICAgICAgICAgICAgICAgIC5jbG9uZSgpOworICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5TSVpFLCBuZXcgRmxvYXQoc2l6ZSkpOworICAgICAgICByZXR1cm4gbmV3IEZvbnQoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgRm9udCB0aGF0IGlzIGEgY29weSBvZiB0aGUgY3VycmVudCBGb250IG1vZGlmaWVkIHNvIHRoYXQKKyAgICAgKiB0aGUgc3R5bGUgaXMgdGhlIHNwZWNpZmllZCBzdHlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHlsZSBvZiBmb250LgorICAgICAqIEByZXR1cm4gdGhlIEZvbnQgb2JqZWN0LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBGb250IGRlcml2ZUZvbnQoaW50IHN0eWxlKSB7CisgICAgICAgIEhhc2h0YWJsZTxBdHRyaWJ1dGUsIE9iamVjdD4gZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMgPSAoSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PilmUmVxdWVzdGVkQXR0cmlidXRlcworICAgICAgICAgICAgICAgIC5jbG9uZSgpOworCisgICAgICAgIGlmICgoc3R5bGUgJiBGb250LkJPTEQpICE9IDApIHsKKyAgICAgICAgICAgIGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLldFSUdIVCwgVGV4dEF0dHJpYnV0ZS5XRUlHSFRfQk9MRCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuV0VJR0hUKSAhPSBudWxsKSB7CisgICAgICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5yZW1vdmUoVGV4dEF0dHJpYnV0ZS5XRUlHSFQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChzdHlsZSAmIEZvbnQuSVRBTElDKSAhPSAwKSB7CisgICAgICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFLCBUZXh0QXR0cmlidXRlLlBPU1RVUkVfT0JMSVFVRSk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuUE9TVFVSRSkgIT0gbnVsbCkgeworICAgICAgICAgICAgZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMucmVtb3ZlKFRleHRBdHRyaWJ1dGUuUE9TVFVSRSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEZvbnQoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgRm9udCB0aGF0IGlzIGEgY29weSBvZiB0aGUgY3VycmVudCBGb250IG1vZGlmaWVkIHRvIG1hdGNoCisgICAgICogdGhlIHNwZWNpZmllZCBzdHlsZSBhbmQgd2l0aCB0aGUgc3BlY2lmaWVkIGFmZmluZSB0cmFuc2Zvcm0gYXBwbGllZCB0bworICAgICAqIGl0cyBnbHlwaHMuCisgICAgICogCisgICAgICogQHBhcmFtIHN0eWxlCisgICAgICogICAgICAgICAgICB0aGUgc3R5bGUgb2YgZm9udC4KKyAgICAgKiBAcGFyYW0gdHJhbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogQHJldHVybiB0aGUgRm9udCBvYmplY3QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEZvbnQgZGVyaXZlRm9udChpbnQgc3R5bGUsIEFmZmluZVRyYW5zZm9ybSB0cmFucykgeworCisgICAgICAgIGlmICh0cmFucyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuOTQ9dHJhbnNmb3JtIGNhbiBub3QgYmUgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIEhhc2h0YWJsZTxBdHRyaWJ1dGUsIE9iamVjdD4gZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMgPSAoSGFzaHRhYmxlPEF0dHJpYnV0ZSwgT2JqZWN0PilmUmVxdWVzdGVkQXR0cmlidXRlcworICAgICAgICAgICAgICAgIC5jbG9uZSgpOworCisgICAgICAgIGlmICgoc3R5bGUgJiBCT0xEKSAhPSAwKSB7CisgICAgICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5XRUlHSFQsIFRleHRBdHRyaWJ1dGUuV0VJR0hUX0JPTEQpOworICAgICAgICB9IGVsc2UgaWYgKGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLldFSUdIVCkgIT0gbnVsbCkgeworICAgICAgICAgICAgZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMucmVtb3ZlKFRleHRBdHRyaWJ1dGUuV0VJR0hUKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoc3R5bGUgJiBJVEFMSUMpICE9IDApIHsKKyAgICAgICAgICAgIGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChUZXh0QXR0cmlidXRlLlBPU1RVUkUsIFRleHRBdHRyaWJ1dGUuUE9TVFVSRV9PQkxJUVVFKTsKKyAgICAgICAgfSBlbHNlIGlmIChkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFKSAhPSBudWxsKSB7CisgICAgICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5yZW1vdmUoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFKTsKKyAgICAgICAgfQorICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5UUkFOU0ZPUk0sIG5ldyBUcmFuc2Zvcm1BdHRyaWJ1dGUodHJhbnMpKTsKKworICAgICAgICByZXR1cm4gbmV3IEZvbnQoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgRm9udCB0aGF0IGlzIGEgY29weSBvZiB0aGUgY3VycmVudCBGb250IG1vZGlmaWVkIHNvIHRoYXQKKyAgICAgKiB0aGUgc2l6ZSBhbmQgc3R5bGUgYXJlIHRoZSBzcGVjaWZpZWQgc2l6ZSBhbmQgc3R5bGUuCisgICAgICogCisgICAgICogQHBhcmFtIHN0eWxlCisgICAgICogICAgICAgICAgICB0aGUgc3R5bGUgb2YgZm9udC4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgZm9udC4KKyAgICAgKiBAcmV0dXJuIHRoZSBGb250IG9iamVjdC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgRm9udCBkZXJpdmVGb250KGludCBzdHlsZSwgZmxvYXQgc2l6ZSkgeworICAgICAgICBIYXNodGFibGU8QXR0cmlidXRlLCBPYmplY3Q+IGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzID0gKEhhc2h0YWJsZTxBdHRyaWJ1dGUsIE9iamVjdD4pZlJlcXVlc3RlZEF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKworICAgICAgICBpZiAoKHN0eWxlICYgQk9MRCkgIT0gMCkgeworICAgICAgICAgICAgZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMucHV0KFRleHRBdHRyaWJ1dGUuV0VJR0hULCBUZXh0QXR0cmlidXRlLldFSUdIVF9CT0xEKTsKKyAgICAgICAgfSBlbHNlIGlmIChkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5XRUlHSFQpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnJlbW92ZShUZXh0QXR0cmlidXRlLldFSUdIVCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKHN0eWxlICYgSVRBTElDKSAhPSAwKSB7CisgICAgICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5QT1NUVVJFLCBUZXh0QXR0cmlidXRlLlBPU1RVUkVfT0JMSVFVRSk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuUE9TVFVSRSkgIT0gbnVsbCkgeworICAgICAgICAgICAgZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMucmVtb3ZlKFRleHRBdHRyaWJ1dGUuUE9TVFVSRSk7CisgICAgICAgIH0KKworICAgICAgICBkZXJpdmVmUmVxdWVzdGVkQXR0cmlidXRlcy5wdXQoVGV4dEF0dHJpYnV0ZS5TSVpFLCBuZXcgRmxvYXQoc2l6ZSkpOworICAgICAgICByZXR1cm4gbmV3IEZvbnQoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBGb250IG9iamVjdCB3aXRoIGEgbmV3IHNldCBvZiBmb250IGF0dHJpYnV0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXAgb2YgYXR0cmlidXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBGb250LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBGb250IGRlcml2ZUZvbnQoTWFwPD8gZXh0ZW5kcyBBdHRyaWJ1dGUsID8+IGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgQXR0cmlidXRlW10gYXZhbEF0dHJpYnV0ZXMgPSB0aGlzLmdldEF2YWlsYWJsZUF0dHJpYnV0ZXMoKTsKKworICAgICAgICBIYXNodGFibGU8QXR0cmlidXRlLCBPYmplY3Q+IGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzID0gKEhhc2h0YWJsZTxBdHRyaWJ1dGUsIE9iamVjdD4pZlJlcXVlc3RlZEF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICAgICAgT2JqZWN0IGN1cnJBdHRyaWJ1dGU7CisgICAgICAgIGZvciAoQXR0cmlidXRlIGVsZW1lbnQgOiBhdmFsQXR0cmlidXRlcykgeworICAgICAgICAgICAgY3VyckF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXMuZ2V0KGVsZW1lbnQpOworICAgICAgICAgICAgaWYgKGN1cnJBdHRyaWJ1dGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGRlcml2ZWZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLnB1dChlbGVtZW50LCBjdXJyQXR0cmlidXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEZvbnQoZGVyaXZlZlJlcXVlc3RlZEF0dHJpYnV0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgT2JqZWN0IHdpdGggdGhlIGN1cnJlbnQgRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBPYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgRm9udCB3aXRoIHRoZQorICAgICAqICAgICAgICAgc2FtZSBmYW1pbHksIHNpemUsIGFuZCBzdHlsZSBhcyB0aGlzIEZvbnQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG9iaiAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEZvbnQgZm9udCA9IChGb250KW9iajsKKworICAgICAgICAgICAgICAgIHJldHVybiAoKHRoaXMuc3R5bGUgPT0gZm9udC5zdHlsZSkgJiYgKHRoaXMuc2l6ZSA9PSBmb250LnNpemUpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLm5hbWUuZXF1YWxzKGZvbnQubmFtZSkgJiYgKHRoaXMucG9pbnRTaXplID09IGZvbnQucG9pbnRTaXplKSAmJiAodGhpcworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRyYW5zZm9ybSgpKS5lcXVhbHMoZm9udC5nZXRUcmFuc2Zvcm0oKSkpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXAgb2YgZm9udCdzIGF0dHJpYnV0ZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWFwIG9mIGZvbnQncyBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBNYXA8VGV4dEF0dHJpYnV0ZSwgPz4gZ2V0QXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIChNYXA8VGV4dEF0dHJpYnV0ZSwgPz4pZlJlcXVlc3RlZEF0dHJpYnV0ZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBrZXlzIG9mIGFsbCBhdmFpbGFibGUgYXR0cmlidXRlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBrZXlzIGFycmF5IG9mIGFsbCBhdmFpbGFibGUgYXR0cmlidXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlW10gZ2V0QXZhaWxhYmxlQXR0cmlidXRlcygpIHsKKyAgICAgICAgQXR0cmlidXRlW10gYXR0cnMgPSB7CisgICAgICAgICAgICAgICAgVGV4dEF0dHJpYnV0ZS5GQU1JTFksIFRleHRBdHRyaWJ1dGUuUE9TVFVSRSwgVGV4dEF0dHJpYnV0ZS5TSVpFLAorICAgICAgICAgICAgICAgIFRleHRBdHRyaWJ1dGUuVFJBTlNGT1JNLCBUZXh0QXR0cmlidXRlLldFSUdIVCwgVGV4dEF0dHJpYnV0ZS5TVVBFUlNDUklQVCwKKyAgICAgICAgICAgICAgICBUZXh0QXR0cmlidXRlLldJRFRICisgICAgICAgIH07CisgICAgICAgIHJldHVybiBhdHRyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBiYXNlbGluZSBmb3IgdGhpcyBjaGFyYWN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiB0aGUgYmFzZWxpbmUgZm9yIHRoaXMgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBieXRlIGdldEJhc2VsaW5lRm9yKGNoYXIgYykgeworICAgICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgdXNpbmcgVFQgQkFTRSB0YWJsZSBkYXRhCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZhbWlseSBuYW1lIG9mIHRoZSBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZhbWlseSBuYW1lIG9mIHRoZSBGb250LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmFtaWx5KCkgeworICAgICAgICBpZiAoZlJlcXVlc3RlZEF0dHJpYnV0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZlJlcXVlc3RlZEF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuRkFNSUxZKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmYW1pbHkgbmFtZSBvZiB0aGlzIEZvbnQgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBsb2NhbGUuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUuCisgICAgICogQHJldHVybiB0aGUgZmFtaWx5IG5hbWUgb2YgdGhpcyBGb250IGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBsb2NhbGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGYW1pbHkoTG9jYWxlIGwpIHsKKyAgICAgICAgaWYgKGwgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjAxPSd7MH0nIHBhcmFtZXRlciBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDEiLCAiTG9jYWxlIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEZhbWlseSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBGb250IHdpdGggdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgc2V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlcyB0byBiZSBhc3NpZ25lZCB0byB0aGUgbmV3IEZvbnQuCisgICAgICogQHJldHVybiB0aGUgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZvbnQgZ2V0Rm9udChNYXA8PyBleHRlbmRzIEF0dHJpYnV0ZSwgPz4gYXR0cmlidXRlcykgeworICAgICAgICBGb250IGZudCA9IChGb250KWF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuRk9OVCk7CisgICAgICAgIGlmIChmbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZudDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEZvbnQoYXR0cmlidXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIEZvbnQgb2JqZWN0IGZyb20gdGhlIHN5c3RlbSBwcm9wZXJ0aWVzIGxpc3Qgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbmFtZSBvciByZXR1cm5zIHRoZSBzcGVjaWZpZWQgRm9udCBpZiB0aGVyZSBpcyBubyBzdWNoIHByb3BlcnR5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgRm9udC4KKyAgICAgKiBAcmV0dXJuIHRoZSBGb250IG9iamVjdCBmcm9tIHRoZSBzeXN0ZW0gcHJvcGVydGllcyBsaXN0IHdpdGggdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgbmFtZSBvciB0aGUgc3BlY2lmaWVkIEZvbnQgaWYgdGhlcmUgaXMgbm8gc3VjaAorICAgICAqICAgICAgICAgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGb250IGdldEZvbnQoU3RyaW5nIHNwLCBGb250IGYpIHsKKyAgICAgICAgU3RyaW5nIHByID0gU3lzdGVtLmdldFByb3BlcnR5KHNwKTsKKyAgICAgICAgaWYgKHByID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZWNvZGUocHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBGb250IG9iamVjdCBmcm9tIHRoZSBzeXN0ZW0gcHJvcGVydGllcyBsaXN0IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG5hbWUuCisgICAgICogCisgICAgICogQHBhcmFtIHNwCisgICAgICogICAgICAgICAgICB0aGUgc3lzdGVtIHByb3BlcnR5IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgRm9udCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBzdWNoIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZvbnQgZ2V0Rm9udChTdHJpbmcgc3ApIHsKKyAgICAgICAgcmV0dXJuIGdldEZvbnQoc3AsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvbnQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmb250IG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGb250TmFtZSgpIHsKKyAgICAgICAgaWYgKGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZSZXF1ZXN0ZWRBdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLkZBTUlMWSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZm9udCBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGxvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb250IG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udE5hbWUoTG9jYWxlIGwpIHsKKyAgICAgICAgcmV0dXJuIGdldEZhbWlseSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBMaW5lTWV0cmljcyBvYmplY3QgY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2hhcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFycyBhcnJheS4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZmZzZXQuCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIExpbmVNZXRyaWNzIGZvciB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHVibGljIExpbmVNZXRyaWNzIGdldExpbmVNZXRyaWNzKGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgZW5kLCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgaWYgKGZyYyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMDA9Rm9udFJlbmRlckNvbnRleHQgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjAwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICAvLyBGb250TWV0cmljcyBmbSA9IEFuZHJvaWRHcmFwaGljczJELmdldEluc3RhbmNlKCkuZ2V0Rm9udE1ldHJpY3MoKTsKKyAgICAgICAgRm9udE1ldHJpY3MgZm0gPSBuZXcgRm9udE1ldHJpY3NJbXBsKHRoaXMpOworICAgICAgICBmbG9hdFtdIGZtZXQgPSB7CisgICAgICAgICAgICAgICAgZm0uZ2V0QXNjZW50KCksIGZtLmdldERlc2NlbnQoKSwgZm0uZ2V0TGVhZGluZygpCisgICAgICAgIH07CisgICAgICAgIHJldHVybiBuZXcgTGluZU1ldHJpY3NJbXBsKGNoYXJzLmxlbmd0aCwgZm1ldCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIExpbmVNZXRyaWNzIG9iamVjdCBjcmVhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpdGVyCisgICAgICogICAgICAgICAgICB0aGUgQ2hhcmFjdGVySXRlcmF0b3IuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBMaW5lTWV0cmljcyBmb3IgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTWV0cmljcyBnZXRMaW5lTWV0cmljcyhDaGFyYWN0ZXJJdGVyYXRvciBpdGVyLCBpbnQgc3RhcnQsIGludCBlbmQsCisgICAgICAgICAgICBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKworICAgICAgICBpZiAoZnJjID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4wMD1Gb250UmVuZGVyQ29udGV4dCBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyByZXN1bHRTdHJpbmc7CisgICAgICAgIGludCBpdGVyQ291bnQ7CisKKyAgICAgICAgaXRlckNvdW50ID0gZW5kIC0gc3RhcnQ7CisgICAgICAgIGlmIChpdGVyQ291bnQgPCAwKSB7CisgICAgICAgICAgICByZXN1bHRTdHJpbmcgPSAiIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbaXRlckNvdW50XTsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIGZvciAoY2hhciBjID0gaXRlci5zZXRJbmRleChzdGFydCk7IGMgIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSAmJiAoaSA8IGl0ZXJDb3VudCk7IGMgPSBpdGVyCisgICAgICAgICAgICAgICAgICAgIC5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBjaGFyc1tpXSA9IGM7CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0U3RyaW5nID0gbmV3IFN0cmluZyhjaGFycyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZU1ldHJpY3MocmVzdWx0U3RyaW5nLCBmcmMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBMaW5lTWV0cmljcyBvYmplY3QgY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nLgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBMaW5lTWV0cmljcyBmb3IgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTWV0cmljcyBnZXRMaW5lTWV0cmljcyhTdHJpbmcgc3RyLCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgLy8gRm9udE1ldHJpY3MgZm0gPSBBbmRyb2lkR3JhcGhpY3MyRC5nZXRJbnN0YW5jZSgpLmdldEZvbnRNZXRyaWNzKCk7CisgICAgICAgIEZvbnRNZXRyaWNzIGZtID0gbmV3IEZvbnRNZXRyaWNzSW1wbCh0aGlzKTsKKyAgICAgICAgZmxvYXRbXSBmbWV0ID0geworICAgICAgICAgICAgICAgIGZtLmdldEFzY2VudCgpLCBmbS5nZXREZXNjZW50KCksIGZtLmdldExlYWRpbmcoKQorICAgICAgICB9OworICAgICAgICAvLyBMb2cuaSgiRk9OVCBGTUVUIiwgZm1ldC50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBMaW5lTWV0cmljc0ltcGwoc3RyLmxlbmd0aCgpLCBmbWV0LCBudWxsKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBMaW5lTWV0cmljcyBvYmplY3QgY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZW5kIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHJldHVybiB0aGUgTGluZU1ldHJpY3MgZm9yIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZU1ldHJpY3MgZ2V0TGluZU1ldHJpY3MoU3RyaW5nIHN0ciwgaW50IHN0YXJ0LCBpbnQgZW5kLCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZU1ldHJpY3Moc3RyLnN1YnN0cmluZyhzdGFydCwgZW5kKSwgZnJjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIFN0cmluZyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogRm9udFJlbmRlckNvbnRleHQuIFRoZSBsb2dpY2FsIGJvdW5kcyBjb250YWlucyB0aGUgb3JpZ2luLCBhc2NlbnQsCisgICAgICogYWR2YW5jZSwgYW5kIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2kKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgQ2hhcmFjdGVySXRlcmF0b3IuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiBAcmV0dXJuIGEgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRTdHJpbmdCb3VuZHMoQ2hhcmFjdGVySXRlcmF0b3IgY2ksIGludCBzdGFydCwgaW50IGVuZCwKKyAgICAgICAgICAgIEZvbnRSZW5kZXJDb250ZXh0IGZyYykgeworICAgICAgICBpbnQgZmlyc3QgPSBjaS5nZXRCZWdpbkluZGV4KCk7CisgICAgICAgIGludCBmaW5pc2ggPSBjaS5nZXRFbmRJbmRleCgpOworICAgICAgICBjaGFyW10gY2hhcnM7CisKKyAgICAgICAgaWYgKHN0YXJ0IDwgZmlyc3QpIHsKKyAgICAgICAgICAgIC8vIGF3dC45NT1Xcm9uZyBzdGFydCBpbmRleDogezB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45NSIsIHN0YXJ0KSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kID4gZmluaXNoKSB7CisgICAgICAgICAgICAvLyBhd3QuOTY9V3JvbmcgZmluaXNoIGluZGV4OiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0Ljk2IiwgZW5kKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIC8vIGF3dC45Nz1Xcm9uZyByYW5nZSBsZW5ndGg6IHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuOTciLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIChlbmQgLSBzdGFydCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjAwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBjaGFycyA9IG5ldyBjaGFyW2VuZCAtIHN0YXJ0XTsKKworICAgICAgICBjaS5zZXRJbmRleChzdGFydCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXJzW2ldID0gY2kuY3VycmVudCgpOworICAgICAgICAgICAgY2kubmV4dCgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RyaW5nQm91bmRzKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgsIGZyYyk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIFN0cmluZyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogRm9udFJlbmRlckNvbnRleHQuIFRoZSBsb2dpY2FsIGJvdW5kcyBjb250YWlucyB0aGUgb3JpZ2luLCBhc2NlbnQsCisgICAgICogYWR2YW5jZSwgYW5kIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFN0cmluZy4KKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHJldHVybiBhIFJlY3RhbmdsZTJEIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0U3RyaW5nQm91bmRzKFN0cmluZyBzdHIsIEZvbnRSZW5kZXJDb250ZXh0IGZyYykgeworICAgICAgICBjaGFyW10gY2hhcnMgPSBzdHIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RyaW5nQm91bmRzKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgsIGZyYyk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIFN0cmluZyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogRm9udFJlbmRlckNvbnRleHQuIFRoZSBsb2dpY2FsIGJvdW5kcyBjb250YWlucyB0aGUgb3JpZ2luLCBhc2NlbnQsCisgICAgICogYWR2YW5jZSwgYW5kIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFN0cmluZy4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZmZzZXQuCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUyRCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldFN0cmluZ0JvdW5kcyhTdHJpbmcgc3RyLCBpbnQgc3RhcnQsIGludCBlbmQsIEZvbnRSZW5kZXJDb250ZXh0IGZyYykgeworCisgICAgICAgIHJldHVybiB0aGlzLmdldFN0cmluZ0JvdW5kcygoc3RyLnN1YnN0cmluZyhzdGFydCwgZW5kKSksIGZyYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9naWNhbCBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIEZvbnRSZW5kZXJDb250ZXh0LiBUaGUgbG9naWNhbCBib3VuZHMgY29udGFpbnMgdGhlIG9yaWdpbiwgYXNjZW50LAorICAgICAqIGFkdmFuY2UsIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIGNoYXJzCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZmZzZXQuCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUyRCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldFN0cmluZ0JvdW5kcyhjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGVuZCwgRm9udFJlbmRlckNvbnRleHQgZnJjKSB7CisgICAgICAgIGlmIChzdGFydCA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC45NT1Xcm9uZyBzdGFydCBpbmRleDogezB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45NSIsIHN0YXJ0KSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kID4gY2hhcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAvLyBhd3QuOTY9V3JvbmcgZmluaXNoIGluZGV4OiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0Ljk2IiwgZW5kKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIC8vIGF3dC45Nz1Xcm9uZyByYW5nZSBsZW5ndGg6IHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuOTciLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIChlbmQgLSBzdGFydCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjAwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBGb250UGVlckltcGwgcGVlciA9IChGb250UGVlckltcGwpdGhpcy5nZXRQZWVyKCk7CisKKyAgICAgICAgZmluYWwgaW50IFRSQU5TRk9STV9NQVNLID0gQWZmaW5lVHJhbnNmb3JtLlRZUEVfR0VORVJBTF9ST1RBVElPTgorICAgICAgICAgICAgICAgIHwgQWZmaW5lVHJhbnNmb3JtLlRZUEVfR0VORVJBTF9UUkFOU0ZPUk07CisgICAgICAgIFJlY3RhbmdsZTJEIGJvdW5kczsKKworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdHJhbnNmb3JtID0gZ2V0VHJhbnNmb3JtKCk7CisKKyAgICAgICAgLy8gWFhYOiBmb3IgdHJhbnNmb3JtcyB3aGVyZSBhbiBhbmdsZSBiZXR3ZWVuIGJhc2lzIHZlY3RvcnMgaXMgbm90IDkwCisgICAgICAgIC8vIGRlZ3JlZXMgUmVjdGFubGdlMkQgY2xhc3MgZG9lc24ndCBmaXQgYXMgTG9naWNhbCBib3VuZHMuCisgICAgICAgIGlmICgodHJhbnNmb3JtLmdldFR5cGUoKSAmIFRSQU5TRk9STV9NQVNLKSA9PSAwKSB7CisgICAgICAgICAgICBpbnQgd2lkdGggPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgICAgICB3aWR0aCArPSBwZWVyLmNoYXJXaWR0aChjaGFyc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBMaW5lTWV0cmljcyBubG0gPSBwZWVyLmdldExpbmVNZXRyaWNzKCk7CisKKyAgICAgICAgICAgIExpbmVNZXRyaWNzIG5sbSA9IGdldExpbmVNZXRyaWNzKGNoYXJzLCBzdGFydCwgZW5kLCBmcmMpOworCisgICAgICAgICAgICBib3VuZHMgPSB0cmFuc2Zvcm0uY3JlYXRlVHJhbnNmb3JtZWRTaGFwZSgKKyAgICAgICAgICAgICAgICAgICAgbmV3IFJlY3RhbmdsZTJELkZsb2F0KDAsIC1ubG0uZ2V0QXNjZW50KCksIHdpZHRoLCBubG0uZ2V0SGVpZ2h0KCkpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0Qm91bmRzMkQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBsZW4gPSBlbmQgLSBzdGFydDsKKyAgICAgICAgICAgIGNoYXJbXSBzdWJDaGFycyA9IG5ldyBjaGFyW2xlbl07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoYXJzLCBzdGFydCwgc3ViQ2hhcnMsIDAsIGxlbik7CisgICAgICAgICAgICBib3VuZHMgPSBjcmVhdGVHbHlwaFZlY3RvcihmcmMsIHN1YkNoYXJzKS5nZXRMb2dpY2FsQm91bmRzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjaGFyYWN0ZXIncyBtYXhpbXVtIGJvdW5kcyBhcyBkZWZpbmVkIGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyJ3MgbWF4aW11bSBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldE1heENoYXJCb3VuZHMoRm9udFJlbmRlckNvbnRleHQgZnJjKSB7CisgICAgICAgIGlmIChmcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjAwPUZvbnRSZW5kZXJDb250ZXh0IGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wMCIpKTsgLy8kTk9OLU5MUy0xJCAKKyAgICAgICAgfQorCisgICAgICAgIEZvbnRQZWVySW1wbCBwZWVyID0gKEZvbnRQZWVySW1wbCl0aGlzLmdldFBlZXIoKTsKKworICAgICAgICBSZWN0YW5nbGUyRCBib3VuZHMgPSBwZWVyLmdldE1heENoYXJCb3VuZHMoZnJjKTsKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHRyYW5zZm9ybSA9IGdldFRyYW5zZm9ybSgpOworICAgICAgICAvLyAhISBEb2N1bWVudGF0aW9uIGRvZXNuJ3QgZGVzY3JpYmUgbWVhbmluZyBvZiBtYXggY2hhciBib3VuZHMKKyAgICAgICAgLy8gZm9yIHRoZSBmb250cyB0aGF0IGhhdmUgcm90YXRlIHRyYW5zZm9ybXMuIEZvciBhbGwgdHJhbnNmb3JtcworICAgICAgICAvLyByZXR1cm5lZCBib3VuZHMgYXJlIHRoZSBib3VuZHMgb2YgdHJhbnNmb3JtZWQgbWF4Q2hhckJvdW5kcworICAgICAgICAvLyBSZWN0YW5nbGUyRCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBmb250IHdpdGggaWRlbnRpdHkgdHJhbnNmb3JtLgorICAgICAgICAvLyBUT0RPOiByZXNvbHZlIHRoaXMgaXNzdWUgdG8gcmV0dXJuIGNvcnJlY3QgYm91bmRzCisgICAgICAgIGJvdW5kcyA9IHRyYW5zZm9ybS5jcmVhdGVUcmFuc2Zvcm1lZFNoYXBlKGJvdW5kcykuZ2V0Qm91bmRzMkQoKTsKKworICAgICAgICByZXR1cm4gYm91bmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgR2x5cGhWZWN0b3Igb2JqZWN0IHBlcmZvcm1pbmcgZnVsbCBsYXlvdXQgb2YgdGhlIHRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEBwYXJhbSBjaGFycworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBiZSBsYXlvdXQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSB0ZXh0IHRvIHVzZSBmb3IgdGhlIEdseXBoVmVjdG9yLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIGNvdW50IG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZvciB0aGUgR2x5cGhWZWN0b3IuCisgICAgICogQHBhcmFtIGZsYWdzCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyBpbmRpY2F0aW5nIHRleHQgZGlyZWN0aW9uOiBMQVlPVVRfUklHSFRfVE9fTEVGVCwKKyAgICAgKiAgICAgICAgICAgIExBWU9VVF9MRUZUX1RPX1JJR0hULgorICAgICAqIEByZXR1cm4gdGhlIEdseXBoVmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaFZlY3RvciBsYXlvdXRHbHlwaFZlY3RvcihGb250UmVuZGVyQ29udGV4dCBmcmMsIGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgY291bnQsCisgICAgICAgICAgICBpbnQgZmxhZ3MpIHsKKyAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IG1ldGhvZCBmb3IgYmlkaXJlY3Rpb25hbCB0ZXh0LgorICAgICAgICAvLyBBdCB0aGUgbW9tZW50IG9ubHkgTFRSIGFuZCBSVEwgdGV4dHMgc3VwcG9ydGVkLgorICAgICAgICBpZiAoc3RhcnQgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuOTU9V3Jvbmcgc3RhcnQgaW5kZXg6IHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45NSIsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgc3RhcnQpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb3VudCA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC45OD1Xcm9uZyBjb3VudCB2YWx1ZSwgY2FuIG5vdCBiZSBuZWdhdGl2ZTogezB9CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0Ljk4IiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICBjb3VudCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN0YXJ0ICsgY291bnQgPiBjaGFycy5sZW5ndGgpIHsKKyAgICAgICAgICAgIC8vIGF3dC45OT1Xcm9uZyBbc3RhcnQgKyBjb3VudF0gaXMgb3V0IG9mIHJhbmdlOiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuOTkiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIChzdGFydCArIGNvdW50KSkpOworICAgICAgICB9CisKKyAgICAgICAgY2hhcltdIG91dCA9IG5ldyBjaGFyW2NvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFycywgc3RhcnQsIG91dCwgMCwgY291bnQpOworCisgICAgICAgIHJldHVybiBuZXcgQ29tbW9uR2x5cGhWZWN0b3Iob3V0LCBmcmMsIHRoaXMsIGZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEZvbnQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nIHN0bCA9ICJwbGFpbiI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIHJlc3VsdDsKKworICAgICAgICBpZiAodGhpcy5pc0JvbGQoKSAmJiB0aGlzLmlzSXRhbGljKCkpIHsKKyAgICAgICAgICAgIHN0bCA9ICJib2xkaXRhbGljIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmlzQm9sZCgpICYmICF0aGlzLmlzSXRhbGljKCkpIHsKKyAgICAgICAgICAgIHN0bCA9ICJib2xkIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKCF0aGlzLmlzQm9sZCgpICYmIHRoaXMuaXNJdGFsaWMoKSkgeworICAgICAgICAgICAgc3RsID0gIml0YWxpYyI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJlc3VsdCA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW2ZhbWlseT0iICsgdGhpcy5nZXRGYW1pbHkoKSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiLG5hbWU9IiArIHRoaXMubmFtZSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiLHN0eWxlPSIgKyBzdGwgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixzaXplPSIgKyB0aGlzLnNpemUgKyAiXSI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBvc3RzY3JpcHQgbmFtZSBvZiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcG9zdHNjcmlwdCBuYW1lIG9mIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBTTmFtZSgpIHsKKyAgICAgICAgRm9udFBlZXJJbXBsIHBlZXIgPSAoRm9udFBlZXJJbXBsKXRoaXMuZ2V0UGVlcigpOworICAgICAgICByZXR1cm4gcGVlci5nZXRQU05hbWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2dpY2FsIG5hbWUgb2YgdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxvZ2ljYWwgbmFtZSBvZiB0aGlzIEZvbnQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gKHRoaXMubmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGVlciBvZiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcGVlciBvZiB0aGlzIEZvbnQuCisgICAgICogQGRlcHJlY2F0ZWQgRm9udCByZW5kZXJpbmcgaXMgcGxhdGZvcm0gaW5kZXBlbmRlbnQgbm93LgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGphdmEuYXd0LnBlZXIuRm9udFBlZXIgZ2V0UGVlcigpIHsKKyAgICAgICAgaWYgKGZvbnRQZWVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGZvbnRQZWVyID0gKEZvbnRQZWVySW1wbClUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCkuZ2V0R3JhcGhpY3NGYWN0b3J5KCkuZ2V0Rm9udFBlZXIoCisgICAgICAgICAgICAgICAgICAgIHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmb250UGVlcjsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRyYW5zZm9ybSBhY3Rpbmcgb24gdGhpcyBGb250IChmcm9tIHRoZSBGb250J3MgYXR0cmlidXRlcykuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtYXRpb24gb2YgdGhpcyBGb250LgorICAgICAqLworICAgIHB1YmxpYyBBZmZpbmVUcmFuc2Zvcm0gZ2V0VHJhbnNmb3JtKCkgeworICAgICAgICBPYmplY3QgdHJhbnNmb3JtID0gZlJlcXVlc3RlZEF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuVFJBTlNGT1JNKTsKKworICAgICAgICBpZiAodHJhbnNmb3JtICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICh0cmFuc2Zvcm0gaW5zdGFuY2VvZiBUcmFuc2Zvcm1BdHRyaWJ1dGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKChUcmFuc2Zvcm1BdHRyaWJ1dGUpdHJhbnNmb3JtKS5nZXRUcmFuc2Zvcm0oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0cmFuc2Zvcm0gaW5zdGFuY2VvZiBBZmZpbmVUcmFuc2Zvcm0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFmZmluZVRyYW5zZm9ybSgoQWZmaW5lVHJhbnNmb3JtKXRyYW5zZm9ybSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cmFuc2Zvcm0gPSBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChBZmZpbmVUcmFuc2Zvcm0pdHJhbnNmb3JtOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgZm9udCBpcyB0cmFuc2Zvcm1lZCBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIGZvbnQgaXMgdHJhbnNmb3JtZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1RyYW5zZm9ybWVkKCkgeworICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1lZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBmb250IGhhcyBwbGFpbiBzdHlsZSBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIGZvbnQgaGFzIHBsYWluIHN0eWxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQbGFpbigpIHsKKyAgICAgICAgcmV0dXJuICh0aGlzLnN0eWxlID09IFBMQUlOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBmb250IGhhcyBpdGFsaWMgc3R5bGUgb3Igbm90LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBmb250IGhhcyBpdGFsaWMgc3R5bGUsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0l0YWxpYygpIHsKKyAgICAgICAgcmV0dXJuICh0aGlzLnN0eWxlICYgSVRBTElDKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGlzIGZvbnQgaGFzIGJvbGQgc3R5bGUgb3Igbm90LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBmb250IGhhcyBib2xkIHN0eWxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNCb2xkKCkgeworICAgICAgICByZXR1cm4gKHRoaXMuc3R5bGUgJiBCT0xEKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIEZvbnQgaGFzIHVuaWZvcm0gbGluZSBtZXRyaWNzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIEZvbnQgaGFzIHVuaWZvcm0gbGluZSBtZXRyaWNzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzVW5pZm9ybUxpbmVNZXRyaWNzKCkgeworICAgICAgICBGb250UGVlckltcGwgcGVlciA9IChGb250UGVlckltcGwpdGhpcy5nZXRQZWVyKCk7CisgICAgICAgIHJldHVybiBwZWVyLmhhc1VuaWZvcm1MaW5lTWV0cmljcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaGFzaCBjb2RlIG9mIHRoaXMgRm9udCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgRm9udCBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgSGFzaENvZGUgaGFzaCA9IG5ldyBIYXNoQ29kZSgpOworCisgICAgICAgIGhhc2guYXBwZW5kKHRoaXMubmFtZSk7CisgICAgICAgIGhhc2guYXBwZW5kKHRoaXMuc3R5bGUpOworICAgICAgICBoYXNoLmFwcGVuZCh0aGlzLnNpemUpOworCisgICAgICAgIHJldHVybiBoYXNoLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3R5bGUgb2YgdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0eWxlIG9mIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN0eWxlKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zdHlsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzaXplIG9mIHRoaXMgRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGdseXBocyBmb3IgdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBnbHlwaHMgZm9yIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bUdseXBocygpIHsKKyAgICAgICAgaWYgKG51bUdseXBocyA9PSAtMSkgeworICAgICAgICAgICAgRm9udFBlZXJJbXBsIHBlZXIgPSAoRm9udFBlZXJJbXBsKXRoaXMuZ2V0UGVlcigpOworICAgICAgICAgICAgdGhpcy5udW1HbHlwaHMgPSBwZWVyLmdldE51bUdseXBocygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzLm51bUdseXBoczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBnbHlwaENvZGUgd2hpY2ggaXMgdXNlZCBhcyBkZWZhdWx0IGdseXBoIHdoZW4gdGhpcyBGb250IGRvZXMgbm90CisgICAgICogaGF2ZSBhIGdseXBoIGZvciBhIHNwZWNpZmllZCBVbmljb2RlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1pc3NpbmcgZ2x5cGggY29kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1pc3NpbmdHbHlwaENvZGUoKSB7CisgICAgICAgIGlmIChtaXNzaW5nR2x5cGhDb2RlID09IC0xKSB7CisgICAgICAgICAgICBGb250UGVlckltcGwgcGVlciA9IChGb250UGVlckltcGwpdGhpcy5nZXRQZWVyKCk7CisgICAgICAgICAgICB0aGlzLm1pc3NpbmdHbHlwaENvZGUgPSBwZWVyLmdldE1pc3NpbmdHbHlwaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy5taXNzaW5nR2x5cGhDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZsb2F0IHZhbHVlIG9mIGZvbnQncyBzaXplLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IHZhbHVlIG9mIGZvbnQncyBzaXplLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRTaXplMkQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnBvaW50U2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpdGFsaWMgYW5nbGUgb2YgdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGl0YWxpYyBhbmdsZSBvZiB0aGlzIEZvbnQuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEl0YWxpY0FuZ2xlKCkgeworICAgICAgICBGb250UGVlckltcGwgcGVlciA9IChGb250UGVlckltcGwpdGhpcy5nZXRQZWVyKCk7CisgICAgICAgIHJldHVybiBwZWVyLmdldEl0YWxpY0FuZ2xlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZm9udCB3aXRoIHRoZSBzcGVjaWZpZWQgZm9udCBmb3JtYXQgYW5kIGZvbnQgZmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9udEZvcm1hdAorICAgICAqICAgICAgICAgICAgdGhlIGZvbnQgZm9ybWF0LgorICAgICAqIEBwYXJhbSBmb250RmlsZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgb2JqZWN0IHJlcHJlc2VudGVkIHRoZSBpbnB1dCBkYXRhIGZvciB0aGUgZm9udC4KKyAgICAgKiBAcmV0dXJuIHRoZSBGb250LgorICAgICAqIEB0aHJvd3MgRm9udEZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlzIHRocm93biBpZiBmb250RmlsZSBkb2VzIG5vdCBjb250YWluIHRoZSByZXF1aXJlZCBmb250CisgICAgICogICAgICAgICAgICAgdGFibGVzIGZvciB0aGUgc3BlY2lmaWVkIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc2lnbmFscyB0aGF0IGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRm9udCBjcmVhdGVGb250KGludCBmb250Rm9ybWF0LCBGaWxlIGZvbnRGaWxlKSB0aHJvd3MgRm9udEZvcm1hdEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gPz8/QVdUIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZvbnRGaWxlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVGb250KGZvbnRGb3JtYXQsIGlzKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBmb250IHdpdGggdGhlIHNwZWNpZmllZCBmb250IGZvcm1hdCBhbmQgaW5wdXQgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250Rm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUgZm9udCBmb3JtYXQuCisgICAgICogQHBhcmFtIGZvbnRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gcmVwcmVzZW50ZWQgaW5wdXQgZGF0YSBmb3IgdGhlIGZvbnQuCisgICAgICogQHJldHVybiB0aGUgRm9udC4KKyAgICAgKiBAdGhyb3dzIEZvbnRGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpcyB0aHJvd24gaWYgZm9udEZpbGUgZG9lcyBub3QgY29udGFpbiB0aGUgcmVxdWlyZWQgZm9udAorICAgICAqICAgICAgICAgICAgIHRhYmxlcyBmb3IgdGhlIHNwZWNpZmllZCBmb3JtYXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZvbnQgY3JlYXRlRm9udChpbnQgZm9udEZvcm1hdCwgSW5wdXRTdHJlYW0gZm9udFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBGb250Rm9ybWF0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gPz8/QVdUIG5vdCBzdXBwb3J0ZWQKKworICAgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJ1ZmZTdHJlYW07CisgICAgICAgIGludCBiUmVhZCA9IDA7CisgICAgICAgIGludCBzaXplID0gODE5MjsKKyAgICAgICAgLy8gbWVtb3J5IHBhZ2Ugc2l6ZSwgZm9yIHRoZSBmYXN0ZXIgcmVhZGluZworICAgICAgICBieXRlIGJ1ZltdID0gbmV3IGJ5dGVbc2l6ZV07CisKKyAgICAgICAgaWYgKGZvbnRGb3JtYXQgIT0gVFJVRVRZUEVfRk9OVCkgeyAvLyBhd3QuOUE9VW5zdXBwb3J0ZWQgZm9udCBmb3JtYXQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuOUEiKSk7IC8vJE5PTi1OTFMtMSQgCisgICAgICAgIH0KKworICAgICAgICAvKiBHZXQgZm9udCBmaWxlIGluIHN5c3RlbS1zcGVjaWZpYyBkaXJlY3RvcnkgKi8KKworICAgICAgICBGaWxlIGZvbnRGaWxlID0gVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpLmdldEdyYXBoaWNzRmFjdG9yeSgpLmdldEZvbnRNYW5hZ2VyKCkKKyAgICAgICAgICAgICAgICAuZ2V0VGVtcEZvbnRGaWxlKCk7CisKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1tb2RpZmllZAorICAgICAgICBidWZmU3RyZWFtID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZm9udFN0cmVhbSwgODE5Mik7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLW1vZGlmaWVkCisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZk91dFN0cmVhbSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZvbnRGaWxlKTsKKworICAgICAgICBiUmVhZCA9IGJ1ZmZTdHJlYW0ucmVhZChidWYsIDAsIHNpemUpOworCisgICAgICAgIHdoaWxlIChiUmVhZCAhPSAtMSkgeworICAgICAgICAgICAgZk91dFN0cmVhbS53cml0ZShidWYsIDAsIGJSZWFkKTsKKyAgICAgICAgICAgIGJSZWFkID0gYnVmZlN0cmVhbS5yZWFkKGJ1ZiwgMCwgc2l6ZSk7CisgICAgICAgIH0KKworICAgICAgICBidWZmU3RyZWFtLmNsb3NlKCk7CisgICAgICAgIGZPdXRTdHJlYW0uY2xvc2UoKTsKKworICAgICAgICBGb250IGZvbnQgPSBudWxsOworCisgICAgICAgIGZvbnQgPSBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCkuZ2V0R3JhcGhpY3NGYWN0b3J5KCkuZW1iZWRGb250KAorICAgICAgICAgICAgICAgIGZvbnRGaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICAgICAgaWYgKGZvbnQgPT0gbnVsbCkgeyAvLyBhd3QuOUI9Q2FuJ3QgY3JlYXRlIGZvbnQgLSBiYWQgZm9udCBkYXRhCisgICAgICAgICAgICB0aHJvdyBuZXcgRm9udEZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC45QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBmb250OworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0ZvbnRGb3JtYXRFeGNlcHRpb24uamF2YSBiL2F3dC9qYXZhL2F3dC9Gb250Rm9ybWF0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODA2NzExYQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9Gb250Rm9ybWF0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8qKgorICogVGhlIEZvbnRGb3JtYXRFeGNlcHRpb24gY2xhc3MgaXMgdXNlZCB0byBwcm92aWRlIG5vdGlmaWNhdGlvbiBhbmQgaW5mb3JtYXRpb24KKyAqIHRoYXQgZm9udCBjYW4ndCBiZSBjcmVhdGVkLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZvbnRGb3JtYXRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ0ODEyOTAxNDc4MTEzNjEyNzJMOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZvbnQgZm9ybWF0IGV4Y2VwdGlvbiB3aXRoIGRldGFpbGVkIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbGVkIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEZvbnRGb3JtYXRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24pOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0ZvbnRNZXRyaWNzLmphdmEgYi9hd3QvamF2YS9hd3QvRm9udE1ldHJpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDgyNjI2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0ZvbnRNZXRyaWNzLmphdmEKQEAgLTAsMCArMSw0NjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZm9udC5Gb250UmVuZGVyQ29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkxpbmVNZXRyaWNzOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS50ZXh0LkNoYXJhY3Rlckl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIEZvbnRNZXRyaWNzIGNsYXNzIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZW5kZXJpbmcgb2YgYQorICogcGFydGljdWxhciBmb250IG9uIGEgcGFydGljdWxhciBzY3JlZW4uCisgKiA8cD4KKyAqIEVhY2ggY2hhcmFjdGVyIGluIHRoZSBGb250IGhhcyB0aHJlZSB2YWx1ZXMgdGhhdCBoZWxwIGRlZmluZSB3aGVyZSB0byBwbGFjZQorICogaXQ6IGFuIGFzY2VudCwgYSBkZXNjZW50LCBhbmQgYW4gYWR2YW5jZS4gVGhlIGFzY2VudCBpcyB0aGUgZGlzdGFuY2UgdGhlCisgKiBjaGFyYWN0ZXIgZXh0ZW5kcyBhYm92ZSB0aGUgYmFzZWxpbmUuIFRoZSBkZXNjZW50IGlzIHRoZSBkaXN0YW5jZSB0aGUKKyAqIGNoYXJhY3RlciBleHRlbmRzIGJlbG93IHRoZSBiYXNlbGluZS4gVGhlIGFkdmFuY2Ugd2lkdGggZGVmaW5lcyB0aGUgcG9zaXRpb24KKyAqIGF0IHdoaWNoIHRoZSBuZXh0IGNoYXJhY3RlciBzaG91bGQgYmUgcGxhY2VkLgorICogPHA+CisgKiBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzIG9yIGEgc3RyaW5nIGhhcyBhbiBhc2NlbnQsIGEgZGVzY2VudCwgYW5kIGFuIGFkdmFuY2UKKyAqIHdpZHRoIHRvby4gVGhlIGFzY2VudCBvciBkZXNjZW50IG9mIHRoZSBhcnJheSBpcyBzcGVjaWZpZWQgYnkgdGhlIG1heGltdW0KKyAqIGFzY2VudCBvciBkZXNjZW50IG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheS4gVGhlIGFkdmFuY2Ugd2lkdGggaXMgdGhlCisgKiBzdW0gb2YgdGhlIGFkdmFuY2Ugd2lkdGhzIG9mIGVhY2ggb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KKyAqIDwvcD4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb250TWV0cmljcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNjgxMTI2MjI1MjA1MDUwMTQ3TDsKKworICAgIC8qKgorICAgICAqIFRoZSBmb250IGZyb20gd2hpY2ggdGhlIEZvbnRNZXRyaWNzIGlzIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEZvbnQgZm9udDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmb250IG1ldHJpY3MgZnJvbSB0aGUgc3BlY2lmaWVkIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGZudAorICAgICAqICAgICAgICAgICAgdGhlIEZvbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEZvbnRNZXRyaWNzKEZvbnQgZm50KSB7CisgICAgICAgIHRoaXMuZm9udCA9IGZudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBGb250TWV0cmljcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW2ZvbnQ9IiArIHRoaXMuZ2V0Rm9udCgpICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICJhc2NlbnQ9IiArIHRoaXMuZ2V0QXNjZW50KCkgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIiwgZGVzY2VudD0iICsgdGhpcy5nZXREZXNjZW50KCkgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIiwgaGVpZ2h0PSIgKyB0aGlzLmdldEhlaWdodCgpICsgIl0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmb250IGFzc29jaWF0ZWQgd2l0aCB0aGlzIEZvbnRNZXRyaWNzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZvbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRm9udE1ldHJpY3MuCisgICAgICovCisgICAgcHVibGljIEZvbnQgZ2V0Rm9udCgpIHsKKyAgICAgICAgcmV0dXJuIGZvbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSB0ZXh0IGxpbmUgaW4gdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhlaWdodCBvZiB0aGUgdGV4dCBsaW5lIGluIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXNjZW50KCkgKyB0aGlzLmdldERlc2NlbnQoKSArIHRoaXMuZ2V0TGVhZGluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvbnQgYXNjZW50IG9mIHRoZSBGb250IGFzc29jaWF0ZWQgd2l0aCB0aGlzIEZvbnRNZXRyaWNzLiBUaGUKKyAgICAgKiBmb250IGFzY2VudCBpcyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgZm9udCdzIGJhc2VsaW5lIHRvIHRoZSB0b3Agb2YgbW9zdAorICAgICAqIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFzY2VudCBvZiB0aGUgRm9udCBhc3NvY2lhdGVkIHdpdGggdGhpcyBGb250TWV0cmljcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZm9udCBkZXNjZW50IG9mIHRoZSBGb250IGFzc29jaWF0ZWQgd2l0aCB0aGlzIEZvbnRNZXRyaWNzLiBUaGUKKyAgICAgKiBmb250IGRlc2NlbnQgaXMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGZvbnQncyBiYXNlbGluZSB0byB0aGUgYm90dG9tIG9mCisgICAgICogbW9zdCBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIGRlc2NlbmRlcnMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVzY2VudCBvZiB0aGUgRm9udCBhc3NvY2lhdGVkIHdpdGggdGhpcyBGb250TWV0cmljcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERlc2NlbnQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxlYWRpbmcgb2YgdGhlIEZvbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRm9udE1ldHJpY3MuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbGVhZGluZyBvZiB0aGUgRm9udCBhc3NvY2lhdGVkIHdpdGggdGhpcyBGb250TWV0cmljcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlYWRpbmcoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBDaGFyYWN0ZXJJdGVyYXRvciBpbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgR3JhcGhpY3MuCisgICAgICogCisgICAgICogQHBhcmFtIGNpCisgICAgICogICAgICAgICAgICB0aGUgQ2hhcmFjdGVySXRlcmF0b3IuCisgICAgICogQHBhcmFtIGJlZ2luSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZC4KKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzLgorICAgICAqIEByZXR1cm4gdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBDaGFyYWN0ZXJJdGVyYXRvciBpbiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBHcmFwaGljcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZU1ldHJpY3MgZ2V0TGluZU1ldHJpY3MoQ2hhcmFjdGVySXRlcmF0b3IgY2ksIGludCBiZWdpbkluZGV4LCBpbnQgbGltaXQsCisgICAgICAgICAgICBHcmFwaGljcyBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBmb250LmdldExpbmVNZXRyaWNzKGNpLCBiZWdpbkluZGV4LCBsaW1pdCwgdGhpcy5nZXRGUkNGcm9tR3JhcGhpY3MoY29udGV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIEdyYXBoaWNzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBTdHJpbmcuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBMaW5lTWV0cmljcyBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQgU3RyaW5nIGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIEdyYXBoaWNzLgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTWV0cmljcyBnZXRMaW5lTWV0cmljcyhTdHJpbmcgc3RyLCBHcmFwaGljcyBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBmb250LmdldExpbmVNZXRyaWNzKHN0ciwgdGhpcy5nZXRGUkNGcm9tR3JhcGhpY3MoY29udGV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgYXJyYXkgaW4gdGhlCisgICAgICogc3BlY2lmaWVkIEdyYXBoaWNzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFycworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAcGFyYW0gYmVnaW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBiZSB1c2VkLgorICAgICAqIEBwYXJhbSBjb250ZXh0CisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MuCisgICAgICogQHJldHVybiB0aGUgTGluZU1ldHJpY3Mgb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBhcnJheSBpbiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBHcmFwaGljcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZU1ldHJpY3MgZ2V0TGluZU1ldHJpY3MoY2hhcltdIGNoYXJzLCBpbnQgYmVnaW5JbmRleCwgaW50IGxpbWl0LCBHcmFwaGljcyBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBmb250LmdldExpbmVNZXRyaWNzKGNoYXJzLCBiZWdpbkluZGV4LCBsaW1pdCwgdGhpcy5nZXRGUkNGcm9tR3JhcGhpY3MoY29udGV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIEdyYXBoaWNzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBTdHJpbmcuCisgICAgICogQHBhcmFtIGJlZ2luSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZC4KKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzLgorICAgICAqIEByZXR1cm4gdGhlIExpbmVNZXRyaWNzIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgR3JhcGhpY3MuCisgICAgICovCisgICAgcHVibGljIExpbmVNZXRyaWNzIGdldExpbmVNZXRyaWNzKFN0cmluZyBzdHIsIGludCBiZWdpbkluZGV4LCBpbnQgbGltaXQsIEdyYXBoaWNzIGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIGZvbnQuZ2V0TGluZU1ldHJpY3Moc3RyLCBiZWdpbkluZGV4LCBsaW1pdCwgdGhpcy5nZXRGUkNGcm9tR3JhcGhpY3MoY29udGV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlcidzIG1heGltdW0gYm91bmRzIGluIHRoZSBzcGVjaWZpZWQgR3JhcGhpY3MgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzIGNvbnRleHQuCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyJ3MgbWF4aW11bSBib3VuZHMgaW4gdGhlIHNwZWNpZmllZCBHcmFwaGljcyBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRNYXhDaGFyQm91bmRzKEdyYXBoaWNzIGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZm9udC5nZXRNYXhDaGFyQm91bmRzKHRoaXMuZ2V0RlJDRnJvbUdyYXBoaWNzKGNvbnRleHQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBDaGFyYWN0ZXJJdGVyYXRvciBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogR3JhcGhpY3MgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2kKKyAgICAgKiAgICAgICAgICAgIHRoZSBDaGFyYWN0ZXJJdGVyYXRvci4KKyAgICAgKiBAcGFyYW0gYmVnaW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGJlZ2luIG9mZnNldCBvZiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBDaGFyYWN0ZXJJdGVyYXRvciBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBHcmFwaGljcyBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRTdHJpbmdCb3VuZHMoQ2hhcmFjdGVySXRlcmF0b3IgY2ksIGludCBiZWdpbkluZGV4LCBpbnQgbGltaXQsCisgICAgICAgICAgICBHcmFwaGljcyBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBmb250LmdldFN0cmluZ0JvdW5kcyhjaSwgYmVnaW5JbmRleCwgbGltaXQsIHRoaXMuZ2V0RlJDRnJvbUdyYXBoaWNzKGNvbnRleHQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZCBHcmFwaGljcworICAgICAqIGNvbnRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZy4KKyAgICAgKiBAcGFyYW0gYmVnaW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGJlZ2luIG9mZnNldCBvZiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZCBHcmFwaGljcworICAgICAqICAgICAgICAgY29udGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0U3RyaW5nQm91bmRzKFN0cmluZyBzdHIsIGludCBiZWdpbkluZGV4LCBpbnQgbGltaXQsIEdyYXBoaWNzIGNvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuIGZvbnQuZ2V0U3RyaW5nQm91bmRzKHN0ciwgYmVnaW5JbmRleCwgbGltaXQsIHRoaXMuZ2V0RlJDRnJvbUdyYXBoaWNzKGNvbnRleHQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGFycmF5IGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBHcmFwaGljcyBjb250ZXh0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFycworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlcnMgYXJyYXkuCisgICAgICogQHBhcmFtIGJlZ2luSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBiZWdpbiBvZmZzZXQgb2YgdGhlIGFycmF5LgorICAgICAqIEBwYXJhbSBsaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBjb250ZXh0CisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MuCisgICAgICogQHJldHVybiB0aGUgYm91bmRzIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVycyBhcnJheSBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBHcmFwaGljcyBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRTdHJpbmdCb3VuZHMoY2hhcltdIGNoYXJzLCBpbnQgYmVnaW5JbmRleCwgaW50IGxpbWl0LCBHcmFwaGljcyBjb250ZXh0KSB7CisgICAgICAgIHJldHVybiBmb250LmdldFN0cmluZ0JvdW5kcyhjaGFycywgYmVnaW5JbmRleCwgbGltaXQsIHRoaXMuZ2V0RlJDRnJvbUdyYXBoaWNzKGNvbnRleHQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmcgaW4gdGhlIHNwZWNpZmllZCBHcmFwaGljcworICAgICAqIGNvbnRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZy4KKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzLgorICAgICAqIEByZXR1cm4gdGhlIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIFN0cmluZyBpbiB0aGUgc3BlY2lmaWVkIEdyYXBoaWNzCisgICAgICogICAgICAgICBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRTdHJpbmdCb3VuZHMoU3RyaW5nIHN0ciwgR3JhcGhpY3MgY29udGV4dCkgeworICAgICAgICByZXR1cm4gZm9udC5nZXRTdHJpbmdCb3VuZHMoc3RyLCB0aGlzLmdldEZSQ0Zyb21HcmFwaGljcyhjb250ZXh0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBGb250IGhhcyB1bmlmb3JtIGxpbmUgbWV0cmljcyBvciBub3QuIFRoZSBGb250IGNhbiBjb250YWluCisgICAgICogY2hhcmFjdGVycyBvZiBvdGhlciBmb250cyBmb3IgY292ZXJpbmcgY2hhcmFjdGVyIHNldC4gSW4gdGhpcyBjYXNlIHRoZQorICAgICAqIEZvbnQgaXNuJ3QgdW5pZm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBGb250IGhhcyB1bmlmb3JtIGxpbmUgbWV0cmljcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1VuaWZvcm1MaW5lTWV0cmljcygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZm9udC5oYXNVbmlmb3JtTGluZU1ldHJpY3MoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBsZWZ0bW9zdCBwb2ludCB0byB0aGUgcmlnaHRtb3N0IHBvaW50IG9uCisgICAgICogdGhlIHN0cmluZydzIGJhc2VsaW5lIHNob3dpbmcgdGhlIHNwZWNpZmllZCBhcnJheSBvZiBieXRlcyBpbiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBieXRlcyB0byBiZSBtZWFzdXJlZC4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYmUgbWVhc3VyZWQuCisgICAgICogQHJldHVybiB0aGUgYWR2YW5jZSB3aWR0aCBvZiB0aGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGludCBieXRlc1dpZHRoKGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgIGludCB3aWR0aCA9IDA7CisgICAgICAgIGlmICgob2ZmID49IGRhdGEubGVuZ3RoKSB8fCAob2ZmIDwgMCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xM0I9b2Zmc2V0IG9mZiBpcyBvdXQgb2YgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTNCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoKG9mZiArIGxlbiA+IGRhdGEubGVuZ3RoKSkgeworICAgICAgICAgICAgLy8gYXd0LjEzQz1udW1iZXIgb2YgZWxlbWV0cyBsZW4gaXMgb3V0IG9mIHJhbmdlCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZjsgaSA8IG9mZiArIGxlbjsgaSsrKSB7CisgICAgICAgICAgICB3aWR0aCArPSBjaGFyV2lkdGgoZGF0YVtpXSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gd2lkdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgbGVmdG1vc3QgcG9pbnQgdG8gdGhlIHJpZ2h0bW9zdCBwb2ludCBvbgorICAgICAqIHRoZSBzdHJpbmcncyBiYXNlbGluZSBzaG93aW5nIHRoZSBzcGVjaWZpZWQgYXJyYXkgb2YgY2hhcmFjdGVycyBpbiB0aGlzCisgICAgICogRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNoYXJhY3RlcnMgdG8gYmUgbWVhc3VyZWQuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIG1lYXN1cmVkLgorICAgICAqIEByZXR1cm4gdGhlIGFkdmFuY2Ugd2lkdGggb2YgdGhlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2hhcnNXaWR0aChjaGFyW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICBpbnQgd2lkdGggPSAwOworICAgICAgICBpZiAoKG9mZiA+PSBkYXRhLmxlbmd0aCkgfHwgKG9mZiA8IDApKSB7CisgICAgICAgICAgICAvLyBhd3QuMTNCPW9mZnNldCBvZmYgaXMgb3V0IG9mIHJhbmdlCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjEzQiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKChvZmYgKyBsZW4gPiBkYXRhLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xM0M9bnVtYmVyIG9mIGVsZW1ldHMgbGVuIGlzIG91dCBvZiByYW5nZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xM0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSBvZmY7IGkgPCBvZmYgKyBsZW47IGkrKykgeworICAgICAgICAgICAgd2lkdGggKz0gY2hhcldpZHRoKGRhdGFbaV0pOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHdpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGxlZnRtb3N0IHBvaW50IHRvIHRoZSByaWdodG1vc3QgcG9pbnQgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpbiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGNoCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFVuaWNvZGUgcG9pbnQgY29kZSBvZiBjaGFyYWN0ZXIgdG8gYmUgbWVhc3VyZWQuCisgICAgICogQHJldHVybiB0aGUgYWR2YW5jZSB3aWR0aCBvZiB0aGUgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2hhcldpZHRoKGludCBjaCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBsZWZ0bW9zdCBwb2ludCB0byB0aGUgcmlnaHRtb3N0IHBvaW50IG9mCisgICAgICogdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaW4gdGhpcyBGb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgdG8gYmUgbWVhc3VyZWQuCisgICAgICogQHJldHVybiB0aGUgYWR2YW5jZSB3aWR0aCBvZiB0aGUgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2hhcldpZHRoKGNoYXIgY2gpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWF4aW11bSBhZHZhbmNlIHdpZHRoIG9mIGNoYXJhY3RlciBpbiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBhZHZhbmNlIHdpZHRoIG9mIGNoYXJhY3RlciBpbiB0aGlzIEZvbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhBZHZhbmNlKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIGZvbnQgYXNjZW50IG9mIHRoZSBGb250IGFzc29jaWF0ZWQgd2l0aCB0aGlzCisgICAgICogRm9udE1ldHJpY3MuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBmb250IGFzY2VudCBvZiB0aGUgRm9udCBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqICAgICAgICAgRm9udE1ldHJpY3MuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhBc2NlbnQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gZm9udCBkZXNjZW50IG9mIGNoYXJhY3RlciBpbiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBmb250IGRlc2NlbnQgb2YgY2hhcmFjdGVyIGluIHRoaXMgRm9udC4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBnZXRNYXhEZXNjZW50KCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGludCBnZXRNYXhEZWNlbnQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gZm9udCBkZXNjZW50IG9mIGNoYXJhY3RlciBpbiB0aGlzIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBmb250IGRlc2NlbnQgb2YgY2hhcmFjdGVyIGluIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heERlc2NlbnQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFkdmFuY2Ugd2lkdGhzIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFkdmFuY2Ugd2lkdGhzIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBGb250LgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRXaWR0aHMoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFkdmFuY2Ugd2lkdGggZm9yIHRoZSBzcGVjaWZpZWQgU3RyaW5nIGluIHRoaXMgRm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICBTdHJpbmcgdG8gYmUgbWVhc3VyZWQuCisgICAgICogQHJldHVybiB0aGUgdGhlIGFkdmFuY2Ugd2lkdGggZm9yIHRoZSBzcGVjaWZpZWQgU3RyaW5nIGluIHRoaXMgRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHN0cmluZ1dpZHRoKFN0cmluZyBzdHIpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIEZvbnRSZW5kZXJDb250ZXh0IGluc3RhbmNlIG9mIHRoZSBHcmFwaGljcyBjb250ZXh0IHNwZWNpZmllZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBHcmFwaGljcyBjb250ZXh0LgorICAgICAqIEByZXR1cm4gYSBGb250UmVuZGVyQ29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIEdyYXBoaWNzIGNvbnRleHQuCisgICAgICovCisgICAgcHJpdmF0ZSBGb250UmVuZGVyQ29udGV4dCBnZXRGUkNGcm9tR3JhcGhpY3MoR3JhcGhpY3MgY29udGV4dCkgeworICAgICAgICBGb250UmVuZGVyQ29udGV4dCBmcmM7CisgICAgICAgIGlmIChjb250ZXh0IGluc3RhbmNlb2YgR3JhcGhpY3MyRCkgeworICAgICAgICAgICAgZnJjID0gKChHcmFwaGljczJEKWNvbnRleHQpLmdldEZvbnRSZW5kZXJDb250ZXh0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmcmMgPSBuZXcgRm9udFJlbmRlckNvbnRleHQobnVsbCwgZmFsc2UsIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmcmM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0dyYWRpZW50UGFpbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9HcmFkaWVudFBhaW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IzMmVmNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9HcmFkaWVudFBhaW50LmphdmEKQEAgLTAsMCArMSwyNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIEdyYWRpZW50UGFpbnQgY2xhc3MgZGVmaW5lcyBhIHdheSB0byBmaWxsIGEgU2hhcGUgd2l0aCBhIGxpbmVhciBjb2xvcgorICogZ3JhZGllbnQgcGF0dGVybi4KKyAqIDxwPgorICogVGhlIEdyYWRpZW50UGFpbnQncyBmaWxsIHBhdHRlcm4gaXMgZGV0ZXJtaW5lZCBieSB0d28gcG9pbnRzIGFuZCB0d28gY29sb3JzLAorICogcGx1cyB0aGUgY3ljbGljIG1vZGUgb3B0aW9uLiBFYWNoIG9mIHRoZSB0d28gcG9pbnRzIGlzIHBhaW50ZWQgd2l0aCBpdHMKKyAqIGNvcnJlc3BvbmRpbmcgY29sb3IsIGFuZCBvbiB0aGUgbGluZSBzZWdtZW50IGNvbm5lY3RpbmcgdGhlIHR3byBwb2ludHMsIHRoZQorICogY29sb3IgaXMgcHJvcG9ydGlvbmFsbHkgY2hhbmdlZCBiZXR3ZWVuIHRoZSB0d28gY29sb3JzLiBGb3IgcG9pbnRzIG9uIHRoZQorICogc2FtZSBsaW5lIHdoaWNoIGFyZSBub3QgYmV0d2VlbiB0aGUgdHdvIHNwZWNpZmllZCBwb2ludHMgKG91dHNpZGUgb2YgdGhlCisgKiBjb25uZWN0aW5nIHNlZ21lbnQpIHRoZWlyIGNvbG9yIGlzIGRldGVybWluZWQgYnkgdGhlIGN5Y2xpYyBtb2RlIG9wdGlvbi4gSWYKKyAqIHRoZSBtb2RlIGlzIGN5Y2xpYywgdGhlbiB0aGUgcmVzdCBvZiB0aGUgbGluZSByZXBlYXRzIHRoZSBjb2xvciBwYXR0ZXJuIG9mCisgKiB0aGUgY29ubmVjdGluZyBzZWdtZW50LCBjeWNsaW5nIGJhY2sgYW5kIGZvcnRoIGJldHdlZW4gdGhlIHR3byBjb2xvcnMuIElmCisgKiBub3QsIHRoZSBtb2RlIGlzIGFjeWNsaWMgd2hpY2ggbWVhbnMgdGhhdCBhbGwgcG9pbnRzIG9uIHRoZSBsaW5lIG91dHNpZGUgdGhlCisgKiBjb25uZWN0aW5nIGxpbmUgc2VnbWVudCBhcmUgZ2l2ZW4gdGhlIHNhbWUgY29sb3IgYXMgdGhlIGNsb3Nlc3Qgb2YgdGhlIHR3bworICogc3BlY2lmaWVkIHBvaW50cy4KKyAqIDxwPgorICogVGhlIGNvbG9yIG9mIHBvaW50cyB0aGF0IGFyZSBub3Qgb24gdGhlIGxpbmUgY29ubmVjdGluZyB0aGUgdHdvIHNwZWNpZmllZAorICogcG9pbnRzIGFyZSBnaXZlbiBieSBwZXJwZW5kaWN1bGFyIHByb2plY3Rpb246IGJ5IHRha2luZyB0aGUgc2V0IG9mIGxpbmVzCisgKiBwZXJwZW5kaWN1bGFyIHRvIHRoZSBjb25uZWN0aW5nIGxpbmUgYW5kIGZvciBlYWNoIG9uZSwgdGhlIHdob2xlIGxpbmUgaXMKKyAqIGNvbG9yZWQgd2l0aCB0aGUgc2FtZSBjb2xvci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBHcmFkaWVudFBhaW50IGltcGxlbWVudHMgUGFpbnQgeworCisgICAgLyoqCisgICAgICogVGhlIHN0YXJ0IHBvaW50IGNvbG9yLgorICAgICAqLworICAgIENvbG9yIGNvbG9yMTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmQgY29sb3IgcG9pbnQuCisgICAgICovCisgICAgQ29sb3IgY29sb3IyOworCisgICAgLyoqCisgICAgICogVGhlIGxvY2F0aW9uIG9mIHRoZSBzdGFydCBwb2ludC4KKyAgICAgKi8KKyAgICBQb2ludDJEIHBvaW50MTsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2NhdGlvbiBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIFBvaW50MkQgcG9pbnQyOworCisgICAgLyoqCisgICAgICogVGhlIGluZGljYXRvciBvZiBjeWNsZSBmaWxsaW5nLiBJZiBUUlVFIGZpbGxpbmcgcmVwZWF0ZWQgb3V0c2lkZSBwb2ludHMKKyAgICAgKiBzdHJpcGUsIGlmIEZBTFNFIHNvbGlkIGNvbG9yIGZpbGxpbmcgb3V0c2lkZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGN5Y2xpYzsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBHcmFkaWVudFBhaW50IHdpdGggY3ljbGljIG9yIGFjeWNsaWMgbW9kZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjEKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvciBvZiB0aGUgZmlyc3Qgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBwb2ludDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjIKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvciBvZiB0aGUgc2Vjb25kIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKiBAcGFyYW0gY3ljbGljCisgICAgICogICAgICAgICAgICB0aGUgY3ljbGljIG1vZGUgLSB0cnVlIGlmIHRoZSBncmFkaWVudCBwYXR0ZXJuIHNob3VsZCBjeWNsZQorICAgICAqICAgICAgICAgICAgcmVwZWF0ZWRseSBiZXR3ZWVuIHRoZSB0d28gY29sb3JzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIEdyYWRpZW50UGFpbnQoUG9pbnQyRCBwb2ludDEsIENvbG9yIGNvbG9yMSwgUG9pbnQyRCBwb2ludDIsIENvbG9yIGNvbG9yMiwgYm9vbGVhbiBjeWNsaWMpIHsKKyAgICAgICAgaWYgKHBvaW50MSA9PSBudWxsIHx8IHBvaW50MiA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuNkQ9UG9pbnQgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjZEIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbG9yMSA9PSBudWxsIHx8IGNvbG9yMiA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuNkU9Q29sb3IgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjZFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICB0aGlzLnBvaW50MSA9IHBvaW50MTsKKyAgICAgICAgdGhpcy5wb2ludDIgPSBwb2ludDI7CisgICAgICAgIHRoaXMuY29sb3IxID0gY29sb3IxOworICAgICAgICB0aGlzLmNvbG9yMiA9IGNvbG9yMjsKKyAgICAgICAgdGhpcy5jeWNsaWMgPSBjeWNsaWM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEdyYWRpZW50UGFpbnQgd2l0aCBjeWNsaWMgb3IgYWN5Y2xpYyBtb2RlOyBwb2ludHMgYXJlCisgICAgICogc3BlY2lmaWVkIGJ5IGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0gY29sb3IxCisgICAgICogICAgICAgICAgICB0aGUgY29sb3Igb2YgdGhlIGZpcnN0IHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqIEBwYXJhbSBjeWNsaWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjeWNsaWMgbW9kZSAtIHRydWUgaWYgdGhlIGdyYWRpZW50IHBhdHRlcm4gc2hvdWxkIGN5Y2xlCisgICAgICogICAgICAgICAgICByZXBlYXRlZGx5IGJldHdlZW4gdGhlIHR3byBjb2xvcnM7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhZGllbnRQYWludChmbG9hdCB4MSwgZmxvYXQgeTEsIENvbG9yIGNvbG9yMSwgZmxvYXQgeDIsIGZsb2F0IHkyLCBDb2xvciBjb2xvcjIsCisgICAgICAgICAgICBib29sZWFuIGN5Y2xpYykgeworICAgICAgICB0aGlzKG5ldyBQb2ludDJELkZsb2F0KHgxLCB5MSksIGNvbG9yMSwgbmV3IFBvaW50MkQuRmxvYXQoeDIsIHkyKSwgY29sb3IyLCBjeWNsaWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBhY3ljbGljIEdyYWRpZW50UGFpbnQ7IHBvaW50cyBhcmUgc3BlY2lmaWVkIGJ5CisgICAgICogY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjEKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBvZiB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICogQHBhcmFtIGNvbG9yMgorICAgICAqICAgICAgICAgICAgdGhlIGNvbG9yIG9mIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIEdyYWRpZW50UGFpbnQoZmxvYXQgeDEsIGZsb2F0IHkxLCBDb2xvciBjb2xvcjEsIGZsb2F0IHgyLCBmbG9hdCB5MiwgQ29sb3IgY29sb3IyKSB7CisgICAgICAgIHRoaXMoeDEsIHkxLCBjb2xvcjEsIHgyLCB5MiwgY29sb3IyLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGFjeWNsaWMgR3JhZGllbnRQYWludC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjEKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvciBvZiB0aGUgZmlyc3Qgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBwb2ludDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIEBwYXJhbSBjb2xvcjIKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvciBvZiB0aGUgc2Vjb25kIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhZGllbnRQYWludChQb2ludDJEIHBvaW50MSwgQ29sb3IgY29sb3IxLCBQb2ludDJEIHBvaW50MiwgQ29sb3IgY29sb3IyKSB7CisgICAgICAgIHRoaXMocG9pbnQxLCBjb2xvcjEsIHBvaW50MiwgY29sb3IyLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBQYWludENvbnRleHQgZm9yIGEgY29sb3IgcGF0dGVybiBnZW5lcmF0aW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjbQorICAgICAqICAgICAgICAgICAgdGhlIENvbG9yTW9kZWwgb2YgdGhlIFBhaW50IGRhdGEuCisgICAgICogQHBhcmFtIGRldmljZUJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIGJvdW5kaW5nIFJlY3RhbmdsZSBvZiBncmFwaGljcyBwcmltaXRpdmVzIGJlaW5nIHJlbmRlcmVkCisgICAgICogICAgICAgICAgICBpbiB0aGUgZGV2aWNlIHNwYWNlLgorICAgICAqIEBwYXJhbSB1c2VyQm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgYm91bmRpbmcgUmVjdGFuZ2xlIG9mIGdyYXBoaWNzIHByaW1pdGl2ZXMgYmVpbmcgcmVuZGVyZWQKKyAgICAgKiAgICAgICAgICAgIGluIHRoZSB1c2VyIHNwYWNlLgorICAgICAqIEBwYXJhbSB0CisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtIGZyb20gdXNlciBzcGFjZSBpbnRvIGRldmljZSBzcGFjZS4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBScmVuZGVyaW5nSGludHMgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIFBhaW50Q29udGV4dCBmb3IgY29sb3IgcGF0dGVybiBnZW5lcmF0aW5nLgorICAgICAqIEBzZWUgamF2YS5hd3QuUGFpbnQjY3JlYXRlQ29udGV4dChqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsLAorICAgICAqICAgICAgamF2YS5hd3QuUmVjdGFuZ2xlLCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJELAorICAgICAqICAgICAgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm0sIGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzKQorICAgICAqLworICAgIHB1YmxpYyBQYWludENvbnRleHQgY3JlYXRlQ29udGV4dChDb2xvck1vZGVsIGNtLCBSZWN0YW5nbGUgZGV2aWNlQm91bmRzLAorICAgICAgICAgICAgUmVjdGFuZ2xlMkQgdXNlckJvdW5kcywgQWZmaW5lVHJhbnNmb3JtIHQsIFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JhZGllbnRQYWludENvbnRleHQoY20sIHQsIHBvaW50MSwgY29sb3IxLCBwb2ludDIsIGNvbG9yMiwgY3ljbGljKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb2xvciBvZiB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY29sb3Igb2YgdGhlIGZpcnN0IHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBDb2xvciBnZXRDb2xvcjEoKSB7CisgICAgICAgIHJldHVybiBjb2xvcjE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29sb3Igb2YgdGhlIHNlY29uZCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xvciBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBDb2xvciBnZXRDb2xvcjIoKSB7CisgICAgICAgIHJldHVybiBjb2xvcjI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUG9pbnQgb2JqZWN0IC0gdGhlIGZpcnN0IHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBQb2ludDJEIGdldFBvaW50MSgpIHsKKyAgICAgICAgcmV0dXJuIHBvaW50MTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUG9pbnQgb2JqZWN0IC0gdGhlIHNlY29uZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnQyRCBnZXRQb2ludDIoKSB7CisgICAgICAgIHJldHVybiBwb2ludDI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHJhbnNwYXJlbmN5IG1vZGUgZm9yIHRoZSBHcmFkaWVudFBhaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zcGFyZW5jeSBtb2RlIGZvciB0aGUgR3JhZGllbnRQYWludC4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlRyYW5zcGFyZW5jeSNnZXRUcmFuc3BhcmVuY3koKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHJhbnNwYXJlbmN5KCkgeworICAgICAgICBpbnQgYTEgPSBjb2xvcjEuZ2V0QWxwaGEoKTsKKyAgICAgICAgaW50IGEyID0gY29sb3IyLmdldEFscGhhKCk7CisgICAgICAgIHJldHVybiAoYTEgPT0gMHhGRiAmJiBhMiA9PSAweEZGKSA/IE9QQVFVRSA6IFRSQU5TTFVDRU5UOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEdyYWRpZW50UGFpbnQgbW9kZTogdHJ1ZSBmb3IgY3ljbGljIG1vZGUsIGZhbHNlIGZvciBhY3ljbGljCisgICAgICogbW9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdyYWRpZW50IGN5Y2xlcyByZXBlYXRlZGx5IGJldHdlZW4gdGhlIHR3byBjb2xvcnM7CisgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDeWNsaWMoKSB7CisgICAgICAgIHJldHVybiBjeWNsaWM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0dyYWRpZW50UGFpbnRDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvR3JhZGllbnRQYWludENvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDU3NWY1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0dyYWRpZW50UGFpbnRDb250ZXh0LmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUG9pbnQyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXJJbnQ7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworCitjbGFzcyBHcmFkaWVudFBhaW50Q29udGV4dCBpbXBsZW1lbnRzIFBhaW50Q29udGV4dCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2l6ZSBvZiBub25jeWNsaWMgcGFydCBvZiBjb2xvciBsb29rdXAgdGFibGUKKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IExPT0tVUF9TSVpFID0gMjU2OworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBpbmRleCBtYXNrIHRvIGxvb2t1cCBjb2xvciBpbiB0aGUgdGFibGUKKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IExPT0tVUF9NQVNLID0gMHgxRkY7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIG1pbiB2YWx1ZSBlcXVpdmFsZW50IHRvIHplcm8uIElmIGFic29sdXRlIHZhbHVlIGxlc3MgdGhlbiBaRVJPIGl0IGNvbnNpZGVyZWQgYXMgemVyby4gIAorICAgICAqLworICAgIHN0YXRpYyBkb3VibGUgWkVSTyA9IDFFLTEwOworCisgICAgLyoqCisgICAgICogVGhlIENvbG9yTW9kZWwgdXNlciBkZWZpbmVkIGZvciBQYWludENvbnRleHQKKyAgICAgKi8KKyAgICBDb2xvck1vZGVsIGNtOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBpbmRpY2F0b3Igb2YgY3ljbGUgZmlsbGluZy4KKyAgICAgKi8KKyAgICBib29sZWFuIGN5Y2xpYzsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZWdlciBjb2xvciB2YWx1ZSBvZiB0aGUgc3RhcnQgcG9pbnQKKyAgICAgKi8KKyAgICBpbnQgYzE7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIGludGVnZXIgY29sb3IgdmFsdWUgb2YgdGhlIGVuZCBwb2ludAorICAgICAqLworICAgIGludCBjMjsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgbG9va3VwIGdyYWRpZW50IGNvbG9yIHRhYmxlIAorICAgICAqLworICAgIGludFtdIHRhYmxlOworCisgICAgLyoqCisgICAgICogVGhlIHRlbXBvcGFyeSBwcmUtY2FsY3VsYXRlZCB2YWx1ZSB0byBldmFsdXRhZSBjb2xvciBpbmRleCAKKyAgICAgKi8KKyAgICBpbnQgZHg7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIHRlbXBvcGFyeSBwcmUtY2FsY3VsYXRlZCB2YWx1ZSB0byBldmFsdXRhZSBjb2xvciBpbmRleCAKKyAgICAgKi8KKyAgICBpbnQgZHk7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIHRlbXBvcGFyeSBwcmUtY2FsY3VsYXRlZCB2YWx1ZSB0byBldmFsdXRhZSBjb2xvciBpbmRleCAKKyAgICAgKi8KKyAgICBpbnQgZGVsdGE7CisgICAgCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBHcmFkaWVudFBhaW50Y29udGV4dAorICAgICAqIEBwYXJhbSBjbSAtIG5vdCB1c2VkCisgICAgICogQHBhcmFtIHQgLSB0aGUgZmlsbCB0cmFuc2Zvcm1hdGlvbgorICAgICAqIEBwYXJhbSBwb2ludDEgLSB0aGUgc3RhcnQgZmlsbCBwb2ludAorICAgICAqIEBwYXJhbSBjb2xvcjEgLSBjb2xvciBvZiB0aGUgc3RhcnQgcG9pbnQgCisgICAgICogQHBhcmFtIHBvaW50MiAtIHRoZSBlbmQgZmlsbCBwb2ludAorICAgICAqIEBwYXJhbSBjb2xvcjIgLSBjb2xvciBvZiB0aGUgZW5kIHBvaW50CisgICAgICogQHBhcmFtIGN5Y2xpYyAtIHRoZSBpbmRpY2F0b3Igb2YgY3ljbGUgZmlsbGluZworICAgICAqLworICAgIEdyYWRpZW50UGFpbnRDb250ZXh0KENvbG9yTW9kZWwgY20sIEFmZmluZVRyYW5zZm9ybSB0LCBQb2ludDJEIHBvaW50MSwgQ29sb3IgY29sb3IxLCBQb2ludDJEIHBvaW50MiwgQ29sb3IgY29sb3IyLCBib29sZWFuIGN5Y2xpYykgeworICAgICAgICB0aGlzLmN5Y2xpYyA9IGN5Y2xpYzsKKyAgICAgICAgdGhpcy5jbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworCisgICAgICAgIGMxID0gY29sb3IxLmdldFJHQigpOworICAgICAgICBjMiA9IGNvbG9yMi5nZXRSR0IoKTsKKworICAgICAgICBkb3VibGUgcHggPSBwb2ludDIuZ2V0WCgpIC0gcG9pbnQxLmdldFgoKTsKKyAgICAgICAgZG91YmxlIHB5ID0gcG9pbnQyLmdldFkoKSAtIHBvaW50MS5nZXRZKCk7CisKKyAgICAgICAgUG9pbnQyRCBwID0gdC50cmFuc2Zvcm0ocG9pbnQxLCBudWxsKTsKKyAgICAgICAgUG9pbnQyRCBieCA9IG5ldyBQb2ludDJELkRvdWJsZShweCwgcHkpOworICAgICAgICBQb2ludDJEIGJ5ID0gbmV3IFBvaW50MkQuRG91YmxlKHB5LCAtcHgpOworCisgICAgICAgIHQuZGVsdGFUcmFuc2Zvcm0oYngsIGJ4KTsKKyAgICAgICAgdC5kZWx0YVRyYW5zZm9ybShieSwgYnkpOworCisgICAgICAgIGRvdWJsZSB2ZWMgPSBieC5nZXRYKCkgKiBieS5nZXRZKCkgLSBieC5nZXRZKCkgKiBieS5nZXRYKCk7CisKKyAgICAgICAgaWYgKE1hdGguYWJzKHZlYykgPCBaRVJPKSB7CisgICAgICAgICAgICBkeCA9IGR5ID0gZGVsdGEgPSAwOworICAgICAgICAgICAgdGFibGUgPSBuZXcgaW50WzFdOworICAgICAgICAgICAgdGFibGVbMF0gPSBjMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRvdWJsZSBtdWx0ID0gTE9PS1VQX1NJWkUgKiAyNTYgLyB2ZWM7CisgICAgICAgICAgICBkeCA9IChpbnQpKGJ5LmdldFgoKSAqIG11bHQpOworICAgICAgICAgICAgZHkgPSAoaW50KShieS5nZXRZKCkgKiBtdWx0KTsKKyAgICAgICAgICAgIGRlbHRhID0gKGludCkoKHAuZ2V0WCgpICogYnkuZ2V0WSgpIC0gcC5nZXRZKCkgKiBieS5nZXRYKCkpICogbXVsdCk7CisgICAgICAgICAgICBjcmVhdGVUYWJsZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGNvbG9yIGluZGV4IGxvb2t1cCB0YWJsZS4gQ2FsY3VsYXRlIDI1NiBzdGVwIHRyYXNmb3JtYXRpb24gZnJvbSAKKyAgICAgKiB0aGUgc3RhcnQgcG9pbnQgY29sb3IgdG8gdGhlIGVuZCBwb2ludCBjb2xvci4gQ29sb3JzIG11bHRpcGxpZWQgYnkgMjU2IHRvIGRvIGludGVnZXIgY2FsY3VsYXRpb25zLiAKKyAgICAgKi8KKyAgICB2b2lkIGNyZWF0ZVRhYmxlKCkgeworICAgICAgICBkb3VibGUgY2EgPSAoYzEgPj4gMjQpICYgMHhGRjsKKyAgICAgICAgZG91YmxlIGNyID0gKGMxID4+IDE2KSAmIDB4RkY7CisgICAgICAgIGRvdWJsZSBjZyA9IChjMSA+PiA4KSAmIDB4RkY7CisgICAgICAgIGRvdWJsZSBjYiA9IGMxICYgMHhGRjsKKworICAgICAgICBkb3VibGUgayA9IDEuMCAvIExPT0tVUF9TSVpFOworICAgICAgICBkb3VibGUgZGEgPSAoKChjMiA+PiAyNCkgJiAweEZGKSAtIGNhKSAqIGs7CisgICAgICAgIGRvdWJsZSBkciA9ICgoKGMyID4+IDE2KSAmIDB4RkYpIC0gY3IpICogazsKKyAgICAgICAgZG91YmxlIGRnID0gKCgoYzIgPj4gOCkgJiAweEZGKSAtIGNnKSAqIGs7CisgICAgICAgIGRvdWJsZSBkYiA9ICgoYzIgJiAweEZGKSAtIGNiKSAqIGs7CisKKyAgICAgICAgdGFibGUgPSBuZXcgaW50W2N5Y2xpYyA/IExPT0tVUF9TSVpFICsgTE9PS1VQX1NJWkUgOiBMT09LVVBfU0laRV07CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBMT09LVVBfU0laRTsgaSsrKSB7CisgICAgICAgICAgICB0YWJsZVtpXSA9CisgICAgICAgICAgICAgICAgKGludCljYSA8PCAyNCB8CisgICAgICAgICAgICAgICAgKGludCljciA8PCAxNiB8CisgICAgICAgICAgICAgICAgKGludCljZyA8PCA4IHwKKyAgICAgICAgICAgICAgICAoaW50KWNiOworICAgICAgICAgICAgY2EgKz0gZGE7CisgICAgICAgICAgICBjciArPSBkcjsKKyAgICAgICAgICAgIGNnICs9IGRnOworICAgICAgICAgICAgY2IgKz0gZGI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN5Y2xpYykgeworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IExPT0tVUF9TSVpFOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0YWJsZVtMT09LVVBfU0laRSArIExPT0tVUF9TSVpFIC0gMSAtIGldID0gdGFibGVbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICByZXR1cm4gY207CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgUmFzdGVyIGdldFJhc3RlcihpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCkgeworICAgICAgICBXcml0YWJsZVJhc3RlciByYXN0ID0gY20uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHcsIGgpOworCisgICAgICAgIGludFtdIGJ1ZiA9ICgoRGF0YUJ1ZmZlckludClyYXN0LmdldERhdGFCdWZmZXIoKSkuZ2V0RGF0YSgpOworCisgICAgICAgIGludCBjID0geCAqIGR5IC0geSAqIGR4IC0gZGVsdGE7CisgICAgICAgIGludCBjeCA9IGR5OworICAgICAgICBpbnQgY3kgPSAtIHcgKiBkeSAtIGR4OworICAgICAgICBpbnQgayA9IDA7CisKKyAgICAgICAgaWYgKGN5Y2xpYykgeworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IGg7IGorKykgeworICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCB3OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmW2srK10gPSB0YWJsZVsoYyA+PiA4KSAmIExPT0tVUF9NQVNLXTsKKyAgICAgICAgICAgICAgICAgICAgYyArPSBjeDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYyArPSBjeTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvcihpbnQgaiA9IDA7IGogPCBoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgdzsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGMgPj4gODsKKyAgICAgICAgICAgICAgICAgICAgYnVmW2srK10gPSBpbmRleCA8IDAgPyBjMSA6IGluZGV4ID49IExPT0tVUF9TSVpFID8gYzIgOiB0YWJsZVtpbmRleF07CisgICAgICAgICAgICAgICAgICAgIGMgKz0gY3g7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGMgKz0gY3k7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmFzdDsKKyAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0dyYXBoaWNzLmphdmEgYi9hd3QvamF2YS9hd3QvR3JhcGhpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDZlNzlmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0dyYXBoaWNzLmphdmEKQEAgLTAsMCArMSw5MjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgQWxleGV5IEEuIFBldHJlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlT2JzZXJ2ZXI7CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcjsKKworLyoqCisgKiBUaGUgYWJzdHJhY3QgR3JhcGhpY3MgY2xhc3MgYWxsb3dzIGFwcGxpY2F0aW9ucyB0byBkcmF3IG9uIGEgc2NyZWVuIG9yIG90aGVyCisgKiByZW5kZXJpbmcgdGFyZ2V0LiBUaGVyZSBhcmUgc2V2ZXJhbCBwcm9wZXJ0aWVzIHdoaWNoIGRlZmluZSByZW5kZXJpbmcKKyAqIG9wdGlvbnM6IG9yaWdpbiBwb2ludCwgY2xpcHBpbmcgYXJlYSwgY29sb3IsIGZvbnQuIDxicj4KKyAqIDxicj4KKyAqIFRoZSBvcmlnaW4gcG9pbnQgc3BlY2lmaWVzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNsaXBwaW5nIGFyZWEgY29vcmRpbmF0ZQorICogc3lzdGVtLiBBbGwgY29vcmRpbmF0ZXMgdXNlZCBpbiByZW5kZXJpbmcgb3BlcmF0aW9ucyBhcmUgY29tcHV0ZWQgd2l0aAorICogcmVzcGVjdCB0byB0aGlzIHBvaW50LiBUaGUgY2xpcHBpbmcgYXJlYSBkZWZpbmVzIHRoZSBib3VuZGFyaWVzIHdoZXJlCisgKiByZW5kZXJpbmcgb3BlcmF0aW9ucyBjYW4gYmUgcGVyZm9ybWVkLiBSZW5kZXJpbmcgb3BlcmF0aW9ucyBjYW4ndCBtb2RpZnkKKyAqIHBpeGVscyBvdXRzaWRlIG9mIHRoZSBjbGlwcGluZyBhcmVhLiA8YnI+CisgKiA8YnI+CisgKiBUaGUgZHJhdyBhbmQgZmlsbCBtZXRob2RzIGFsbG93IGFwcGxpY2F0aW9ucyB0byBkcmF3aW5nIHNoYXBlcywgdGV4dCwgaW1hZ2VzCisgKiB3aXRoIHNwZWNpZmllZCBmb250IGFuZCBjb2xvciBvcHRpb25zIGluIHRoZSBzcGVjaWZpZWQgcGFydCBvZiB0aGUgc2NyZWVuLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEdyYXBoaWNzIHsKKworICAgIC8vIENvbnN0cnVjdG9ycworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEdyYXBoaWNzLiBUaGlzIGNvbnN0cnVjdG9yIGlzIGRlZmF1bHQgZm9yIEdyYXBoaWNzIGFuZAorICAgICAqIGNhbiBub3QgYmUgY2FsbGVkIGRpcmVjdGx5LgorICAgICAqLworICAgIHByb3RlY3RlZCBHcmFwaGljcygpIHsKKyAgICB9CisKKyAgICAvLyBQdWJsaWMgbWV0aG9kcworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhlIEdyYXBoaWNzIG9iamVjdCB3aXRoIGEgbmV3IG9yaWdpbiBhbmQgYSBuZXcKKyAgICAgKiBzcGVjaWZpZWQgY2xpcCBhcmVhLiBUaGUgbmV3IGNsaXAgYXJlYSBpcyB0aGUgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdGhlCisgICAgICogb3JpZ2luIHBvaW50IHdpdGggY29vcmRpbmF0ZXMgWCxZIGFuZCB0aGUgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodC4gVGhlCisgICAgICogY29vcmRpbmF0ZXMgb2YgYWxsIHN1YnNlcXVlbnQgcmVuZGVyaW5nIG9wZXJhdGlvbnMgd2lsbCBiZSBjb21wdXRlZCB3aXRoCisgICAgICogcmVzcGVjdCB0byB0aGUgbmV3IG9yaWdpbiBhbmQgY2FuIGJlIHBlcmZvcm1lZCBvbmx5IHdpdGhpbiB0aGUgcmFuZ2Ugb2YKKyAgICAgKiB0aGUgY2xpcHBpbmcgYXJlYSBkaW1lbnNpb25zLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBvcmlnaW5hbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgb3JpZ2luYWwgcG9pbnQuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgY2xpcHBpbmcgYXJlYS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIGNsaXBwaW5nIGFyZWEuCisgICAgICogQHJldHVybiB0aGUgR3JhcGhpY3Mgb2JqZWN0IHdpdGggbmV3IG9yaWdpbiBwb2ludCBhbmQgY2xpcHBpbmcgYXJlYS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhcGhpY3MgY3JlYXRlKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIEdyYXBoaWNzIHJlcyA9IGNyZWF0ZSgpOworICAgICAgICByZXMudHJhbnNsYXRlKHgsIHkpOworICAgICAgICByZXMuY2xpcFJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRHJhd3MgdGhlIGhpZ2hsaWdodGVkIG91dGxpbmUgb2YgYSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gcmFpc2VkCisgICAgICogICAgICAgICAgICBhIGJvb2xlYW4gdmFsdWUgdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHJlY3RhbmdsZSBpcyBkcmF3bgorICAgICAqICAgICAgICAgICAgYXMgcmFpc2VkIG9yIGluZGVudGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRyYXczRFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gcmFpc2VkKSB7CisgICAgICAgIC8vIE5vdGU6IGxpZ2h0ZXIvZGFya2VyIGNvbG9ycyBzaG91bGQgYmUgdXNlZCB0byBkcmF3IDNkIHJlY3QuCisgICAgICAgIC8vIFRoZSByZXN1bHRpbmcgcmVjdCBpcyAod2lkdGgrMSl4KGhlaWdodCsxKS4gU3Ryb2tlIGFuZCBwYWludAorICAgICAgICAvLyBhdHRyaWJ1dGVzIG9mCisgICAgICAgIC8vIHRoZSBHcmFwaGljczJEIHNob3VsZCBiZSByZXNldCB0byB0aGUgZGVmYXVsdCB2YWx1ZXMuCisgICAgICAgIC8vIGZpbGxSZWN0IGlzIHVzZWQgaW5zdGVhZCBvZiBkcmF3TGluZSB0byBieXBhc3Mgc3Ryb2tlCisgICAgICAgIC8vIHJlc2V0L3NldCBhbmQgcmFzdGVyaXphdGlvbi4KKworICAgICAgICBDb2xvciBjb2xvciA9IGdldENvbG9yKCk7CisgICAgICAgIENvbG9yIGNvbG9yVXAsIGNvbG9yRG93bjsKKyAgICAgICAgaWYgKHJhaXNlZCkgeworICAgICAgICAgICAgY29sb3JVcCA9IGNvbG9yLmJyaWdodGVyKCk7CisgICAgICAgICAgICBjb2xvckRvd24gPSBjb2xvci5kYXJrZXIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbG9yVXAgPSBjb2xvci5kYXJrZXIoKTsKKyAgICAgICAgICAgIGNvbG9yRG93biA9IGNvbG9yLmJyaWdodGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBzZXRDb2xvcihjb2xvclVwKTsKKyAgICAgICAgZmlsbFJlY3QoeCwgeSwgd2lkdGgsIDEpOworICAgICAgICBmaWxsUmVjdCh4LCB5ICsgMSwgMSwgaGVpZ2h0KTsKKworICAgICAgICBzZXRDb2xvcihjb2xvckRvd24pOworICAgICAgICBmaWxsUmVjdCh4ICsgd2lkdGgsIHksIDEsIGhlaWdodCk7CisgICAgICAgIGZpbGxSZWN0KHggKyAxLCB5ICsgaGVpZ2h0LCB3aWR0aCwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRHJhd3MgdGhlIHRleHQgcmVwcmVzZW50ZWQgYnkgYnl0ZSBhcnJheS4gVGhpcyBtZXRob2QgdXNlcyB0aGUgY3VycmVudAorICAgICAqIGZvbnQgYW5kIGNvbG9yIGZvciByZW5kZXJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB3aGljaCBjb250YWlucyB0aGUgdGV4dCB0byBiZSBkcmF3bi4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHdpdGhpbiB0aGUgYnl0ZSBhcnJheSBvZiB0aGUgdGV4dCB0byBiZSBkcmF3bi4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHRleHQgdG8gZHJhdy4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSB3aGVyZSB0aGUgdGV4dCBpcyB0byBiZSBkcmF3bi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSB3aGVyZSB0aGUgdGV4dCBpcyB0byBiZSBkcmF3bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkcmF3Qnl0ZXMoYnl0ZVtdIGJ5dGVzLCBpbnQgb2ZmLCBpbnQgbGVuLCBpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgZHJhd1N0cmluZyhuZXcgU3RyaW5nKGJ5dGVzLCBvZmYsIGxlbiksIHgsIHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSB0ZXh0IHJlcHJlc2VudGVkIGJ5IGNoYXJhY3RlciBhcnJheS4gVGhpcyBtZXRob2QgdXNlcyB0aGUKKyAgICAgKiBjdXJyZW50IGZvbnQgYW5kIGNvbG9yIGZvciByZW5kZXJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIGNoYXJzCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgd2l0aGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkgb2YgdGhlIHRleHQgdG8gYmUgZHJhd24uCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdoaWNoIHdpbGwgYmUgZHJhd24uCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgd2hlcmUgdGhlIHRleHQgaXMgdG8gYmUgZHJhd24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgd2hlcmUgdGhlIHRleHQgaXMgdG8gYmUgZHJhd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZHJhd0NoYXJzKGNoYXJbXSBjaGFycywgaW50IG9mZiwgaW50IGxlbiwgaW50IHgsIGludCB5KSB7CisgICAgICAgIGRyYXdTdHJpbmcobmV3IFN0cmluZyhjaGFycywgb2ZmLCBsZW4pLCB4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiBhIHBvbHlnb24gd2hpY2ggaXMgZGVmaW5lZCBieSBQb2x5Z29uIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBvbHlnb24gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRyYXdQb2x5Z29uKFBvbHlnb24gcCkgeworICAgICAgICBkcmF3UG9seWdvbihwLnhwb2ludHMsIHAueXBvaW50cywgcC5ucG9pbnRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgcmVjdGFuZ2xlIHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgbGVuZ3RoIGFuZCB0b3AgbGVmdAorICAgICAqIGNvcm5lciBjb29yZGluYXRlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZHJhd1JlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgaW50W10geHBvaW50cyA9IHsKKyAgICAgICAgICAgICAgICB4LCB4LCB4ICsgd2lkdGgsIHggKyB3aWR0aAorICAgICAgICB9OworICAgICAgICBpbnRbXSB5cG9pbnRzID0geworICAgICAgICAgICAgICAgIHksIHkgKyBoZWlnaHQsIHkgKyBoZWlnaHQsIHkKKyAgICAgICAgfTsKKworICAgICAgICBkcmF3UG9seWdvbih4cG9pbnRzLCB5cG9pbnRzLCA0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgaGlnaGxpZ2h0ZWQgb3V0bGluZSBvZiBhIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHJhaXNlZAorICAgICAqICAgICAgICAgICAgYSBib29sZWFuIHZhbHVlIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSByZWN0YW5nbGUgaXMgZHJhd24KKyAgICAgKiAgICAgICAgICAgIGFzIHJhaXNlZCBvciBpbmRlbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaWxsM0RSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIHJhaXNlZCkgeworICAgICAgICAvLyBOb3RlOiBsaWdodGVyL2RhcmtlciBjb2xvcnMgc2hvdWxkIGJlIHVzZWQgdG8gZHJhdyAzZCByZWN0LgorICAgICAgICAvLyBUaGUgcmVzdWx0aW5nIHJlY3QgaXMgKHdpZHRoKXgoaGVpZ2h0KSwgc2FtZSBhcyBmaWxsUmVjdC4KKyAgICAgICAgLy8gU3Ryb2tlIGFuZCBwYWludCBhdHRyaWJ1dGVzIG9mIHRoZSBHcmFwaGljczJEIHNob3VsZCBiZSByZXNldAorICAgICAgICAvLyB0byB0aGUgZGVmYXVsdCB2YWx1ZXMuIGZpbGxSZWN0IGlzIHVzZWQgaW5zdGVhZCBvZiBkcmF3TGluZSB0bworICAgICAgICAvLyBieXBhc3Mgc3Ryb2tlIHJlc2V0L3NldCBhbmQgbGluZSByYXN0ZXJpemF0aW9uLgorCisgICAgICAgIENvbG9yIGNvbG9yID0gZ2V0Q29sb3IoKTsKKyAgICAgICAgQ29sb3IgY29sb3JVcCwgY29sb3JEb3duOworICAgICAgICBpZiAocmFpc2VkKSB7CisgICAgICAgICAgICBjb2xvclVwID0gY29sb3IuYnJpZ2h0ZXIoKTsKKyAgICAgICAgICAgIGNvbG9yRG93biA9IGNvbG9yLmRhcmtlcigpOworICAgICAgICAgICAgc2V0Q29sb3IoY29sb3IpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29sb3JVcCA9IGNvbG9yLmRhcmtlcigpOworICAgICAgICAgICAgY29sb3JEb3duID0gY29sb3IuYnJpZ2h0ZXIoKTsKKyAgICAgICAgICAgIHNldENvbG9yKGNvbG9yVXApOworICAgICAgICB9CisKKyAgICAgICAgd2lkdGgtLTsKKyAgICAgICAgaGVpZ2h0LS07CisgICAgICAgIGZpbGxSZWN0KHggKyAxLCB5ICsgMSwgd2lkdGggLSAxLCBoZWlnaHQgLSAxKTsKKworICAgICAgICBzZXRDb2xvcihjb2xvclVwKTsKKyAgICAgICAgZmlsbFJlY3QoeCwgeSwgd2lkdGgsIDEpOworICAgICAgICBmaWxsUmVjdCh4LCB5ICsgMSwgMSwgaGVpZ2h0KTsKKworICAgICAgICBzZXRDb2xvcihjb2xvckRvd24pOworICAgICAgICBmaWxsUmVjdCh4ICsgd2lkdGgsIHksIDEsIGhlaWdodCk7CisgICAgICAgIGZpbGxSZWN0KHggKyAxLCB5ICsgaGVpZ2h0LCB3aWR0aCwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHBvbHlnb24gd2l0aCB0aGUgY3VycmVudCBjb2xvci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBvbHlnb24gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbGxQb2x5Z29uKFBvbHlnb24gcCkgeworICAgICAgICBmaWxsUG9seWdvbihwLnhwb2ludHMsIHAueXBvaW50cywgcC5ucG9pbnRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNwb3NlcyBvZiB0aGUgR3JhcGhpY3MuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmluYWxpemUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYm91bmRzIG9mIHRoZSBjdXJyZW50IGNsaXBwaW5nIGFyZWEgYXMgYSByZWN0YW5nbGUgYW5kIGNvcGllcyBpdAorICAgICAqIHRvIGFuIGV4aXN0aW5nIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgYSBSZWN0YW5nbGUgb2JqZWN0IHdoZXJlIHRoZSBjdXJyZW50IGNsaXBwaW5nIGFyZWEgYm91bmRzIGFyZQorICAgICAqICAgICAgICAgICAgdG8gYmUgY29waWVkLgorICAgICAqIEByZXR1cm4gdGhlIGJvdW5kcyBvZiB0aGUgY3VycmVudCBjbGlwcGluZyBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpcEJvdW5kcyhSZWN0YW5nbGUgcikgeworICAgICAgICBTaGFwZSBjbGlwID0gZ2V0Q2xpcCgpOworCisgICAgICAgIGlmIChjbGlwICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRPRE86IENhbiB3ZSBnZXQgc2hhcGUgYm91bmRzIHdpdGhvdXQgY3JlYXRpbmcgUmVjdGFuZ2xlIG9iamVjdD8KKyAgICAgICAgICAgIFJlY3RhbmdsZSBiID0gY2xpcC5nZXRCb3VuZHMoKTsKKyAgICAgICAgICAgIHIueCA9IGIueDsKKyAgICAgICAgICAgIHIueSA9IGIueTsKKyAgICAgICAgICAgIHIud2lkdGggPSBiLndpZHRoOworICAgICAgICAgICAgci5oZWlnaHQgPSBiLmhlaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJvdW5kcyBvZiB0aGUgY3VycmVudCBjbGlwcGluZyBhcmVhIGFzIGEgcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUgb2JqZWN0LgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2dldENsaXBCb3VuZHMoKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpcFJlY3QoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGlwQm91bmRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZm9udCBtZXRyaWNzIG9mIHRoZSBjdXJyZW50IGZvbnQuIFRoZSBmb250IG1ldHJpY3Mgb2JqZWN0CisgICAgICogY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlbmRlcmluZyBvZiBhIHBhcnRpY3VsYXIgZm9udC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmb250IG1ldHJpY3Mgb2YgY3VycmVudCBmb250LgorICAgICAqLworICAgIHB1YmxpYyBGb250TWV0cmljcyBnZXRGb250TWV0cmljcygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZvbnRNZXRyaWNzKGdldEZvbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZSBpbnRlcnNlY3RzIHRoZSBjdXJyZW50CisgICAgICogY2xpcHBpbmcgYXJlYS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZSBpbnRlcnNlY3RzIHRoZSBjdXJyZW50IGNsaXBwaW5nCisgICAgICogICAgICAgICBhcmVhLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGl0Q2xpcChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICAvLyBUT0RPOiBDcmVhdGUgcGFja2FnZSBwcml2YXRlIG1ldGhvZCBSZWN0YW5nbGUuaW50ZXJzZWN0cyhpbnQsIGludCwKKyAgICAgICAgLy8gaW50LCBpbnQpOworICAgICAgICByZXR1cm4gZ2V0Q2xpcEJvdW5kcygpLmludGVyc2VjdHMobmV3IFJlY3RhbmdsZSh4LCB5LCB3aWR0aCwgaGVpZ2h0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyB0aGlzIEdyYXBoaWNzIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyB0aGlzIEdyYXBoaWNzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBUT0RPOiBUaGluayBhYm91dCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgR3JhcGhpY3MuCisgICAgICAgIHJldHVybiAiR3JhcGhpY3MiOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLy8gQWJzdHJhY3QgbWV0aG9kcworCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlLiBUaGlzIG1ldGhvZCBmaWxscyBzcGVjaWZpZWQgcmVjdGFuZ2xlCisgICAgICogd2l0aCBiYWNrZ3JvdW5kIGNvbG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbGVhclJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogSW50ZXJzZWN0cyB0aGUgY3VycmVudCBjbGlwcGluZyBhcmVhIHdpdGggYSBuZXcgcmVjdGFuZ2xlLiBJZiB0aGUgY3VycmVudAorICAgICAqIGNsaXBwaW5nIGFyZWEgaXMgbm90IGRlZmluZWQsIHRoZSByZWN0YW5nbGUgYmVjb21lcyBhIG5ldyBjbGlwcGluZyBhcmVhLgorICAgICAqIFJlbmRlcmluZyBvcGVyYXRpb25zIGFyZSBvbmx5IGFsbG93ZWQgd2l0aGluIHRoZSBuZXcgdGhlIGNsaXBwaW5nIGFyZWEuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBmb3IgaW50ZXJzZWN0aW9uLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgZm9yIGludGVyc2VjdGlvbi4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIGZvciBpbnRlcnNlY3Rpb24uCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIGZvciBpbnRlcnNlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xpcFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogQ29waWVzIHRoZSByZWN0YW5nbGUgYXJlYSB0byBhbm90aGVyIGFyZWEgc3BlY2lmaWVkIGJ5IGEgZGlzdGFuY2UgKGR4LAorICAgICAqIGR5KSBmcm9tIHRoZSBvcmlnaW5hbCByZWN0YW5nbGUncyBsb2NhdGlvbi4gUG9zaXRpdmUgZHggYW5kIGR5IHZhbHVlcworICAgICAqIGdpdmUgYSBuZXcgbG9jYXRpb24gZGVmaW5lZCBieSB0cmFuc2xhdGlvbiB0byB0aGUgcmlnaHQgYW5kIGRvd24gZnJvbSB0aGUKKyAgICAgKiBvcmlnaW5hbCBsb2NhdGlvbiwgbmVnYXRpdmUgZHggYW5kIGR5IHZhbHVlcyAtIHRvIHRoZSBsZWZ0IGFuZCB1cC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3gKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCB3aWxsIGJlIGNvcGllZC4KKyAgICAgKiBAcGFyYW0gc3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCB3aWxsIGJlIGNvcGllZC4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHdoaWNoIHdpbGwgYmUgY29waWVkLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCB3aWxsIGJlIGNvcGllZC4KKyAgICAgKiBAcGFyYW0gZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Jpem9udGFsIGRpc3RhbmNlIGZyb20gdGhlIHNvdXJjZSByZWN0YW5nbGUncyBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdG8gdGhlIGNvcHkncyBsb2NhdGlvbi4KKyAgICAgKiBAcGFyYW0gZHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJ0aWNhbCBkaXN0YW5jZSBmcm9tIHRoZSBzb3VyY2UgcmVjdGFuZ2xlJ3MgbG9jYXRpb24gdG8KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb3B5J3MgbG9jYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY29weUFyZWEoaW50IHN4LCBpbnQgc3ksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGR4LCBpbnQgZHkpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBjb3B5IG9mIHRoaXMgR3JhcGhpY3MuCisgICAgICogCisgICAgICogQHJldHVybiBhIG5ldyBHcmFwaGljcyBjb250ZXh0IHdoaWNoIGlzIGEgY29weSBvZiB0aGlzIEdyYXBoaWNzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljcyBjcmVhdGUoKTsKKworICAgIC8qKgorICAgICAqIERpc3Bvc2VzIG9mIHRoZSBHcmFwaGljcy4gVGhpcyBHcmFwaGljcyBvYmplY3QgY2FuIG5vdCBiZSB1c2VkIGFmdGVyCisgICAgICogY2FsbGluZyB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwb3NlKCk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgYXJjIGNvdmVyaW5nIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGFuZCB1c2luZyB0aGUgY3VycmVudAorICAgICAqIGNvbG9yLiBUaGUgcmVjdGFuZ2xlIGlzIGRlZmluZWQgYnkgdGhlIG9yaWdpbiBwb2ludCAoWCwgWSkgYW5kIGRpbWVuc2lvbnMKKyAgICAgKiAod2lkdGggYW5kIGhlaWdodCkuIFRoZSBhcmMgY2VudGVyIGlzIHRoZSB0aGUgY2VudGVyIG9mIHNwZWNpZmllZAorICAgICAqIHJlY3RhbmdsZS4gVGhlIGFuZ2xlIG9yaWdpbiBpcyAzIG8nY2xvY2sgcG9zaXRpb24sIHRoZSBwb3NpdGl2ZSBhbmdsZSBpcworICAgICAqIGNvdW50ZWQgYXMgYSBjb3VudGVyLWNsb2Nrd2lzZSByb3RhdGlvbiwgdGhlIG5lZ2F0aXZlIGFuZ2xlIGlzIGNvdW50ZWQgYXMKKyAgICAgKiBjbG9ja3dpc2Ugcm90YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIG9yaWdpbiBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgd2hpY2ggc2NhbGVzIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIG9yaWdpbiBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgd2hpY2ggc2NhbGVzIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB3aGljaCBzY2FsZXMgdGhlIGFyYy4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgd2hpY2ggc2NhbGVzIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHNhCisgICAgICogICAgICAgICAgICBzdGFydCBhbmdsZSAtIHRoZSBvcmlnaW4gYW5nbGUgb2YgYXJjLgorICAgICAqIEBwYXJhbSBlYQorICAgICAqICAgICAgICAgICAgYXJjIGFuZ2xlIC0gdGhlIGFuZ3VsYXIgYXJjIHZhbHVlIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3QXJjKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgc2EsIGludCBlYSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgc3BlY2lmaWVkIGltYWdlIHdpdGggdGhlIGRlZmluZWQgYmFja2dyb3VuZCBjb2xvci4gVGhlIHRvcCBsZWZ0CisgICAgICogY29ybmVyIG9mIGltYWdlIHdpbGwgYmUgZHJhd24gYXQgcG9pbnQgKHgsIHkpIGluIGN1cnJlbnQgY29vcmRpbmF0ZQorICAgICAqIHN5c3RlbS4gVGhlIGltYWdlIGxvYWRpbmcgcHJvY2VzcyBub3RpZmllcyB0aGUgc3BlY2lmaWVkIEltYWdlIE9ic2VydmVyLgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUgaW1hZ2UgaGFzIGxvYWRlZCwgb3RoZXJ3aXNlIGl0IHJldHVybnMKKyAgICAgKiBmYWxzZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1nCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2Ugd2hpY2ggd2lsbCBiZSBkcmF3bi4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgaW1hZ2UgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBpbWFnZSB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIGJnY29sb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLgorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBub3RpZmllZCBhYm91dCBpbWFnZQorICAgICAqICAgICAgICAgICAgbG9hZGluZyBwcm9jZXNzLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgbG9hZGluZyBpbWFnZSBpcyBzdWNjZXNzZnVsIG9yIGltYWdlIGlzIG51bGwsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltZywgaW50IHgsIGludCB5LCBDb2xvciBiZ2NvbG9yLCBJbWFnZU9ic2VydmVyIG9ic2VydmVyKTsKKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSBzcGVjaWZpZWQgaW1hZ2UuIFRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgaW1hZ2Ugd2lsbCBiZSBkcmF3biBhdAorICAgICAqIHBvaW50ICh4LCB5KSBpbiBjdXJyZW50IGNvb3JkaW5hdGUgc3lzdGVtLiBUaGUgaW1hZ2UgbG9hZGluZyBwcm9jZXNzCisgICAgICogbm90aWZpZXMgdGhlIHNwZWNpZmllZCBJbWFnZSBPYnNlcnZlci4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZQorICAgICAqIGltYWdlIGhhcyBsb2FkZWQsIG90aGVyd2lzZSBpdCByZXR1cm5zIGZhbHNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB3aGljaCB3aWxsIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBpbWFnZSB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGltYWdlIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0gb2JzZXJ2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZU9ic2VydmVyIG9iamVjdCB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQgYWJvdXQgaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIGxvYWRpbmcgcHJvY2Vzcy4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGxvYWRpbmcgaW1hZ2UgaXMgc3VjY2Vzc2Z1bCBvciBpbWFnZSBpcyBudWxsLCBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWcsIGludCB4LCBpbnQgeSwgSW1hZ2VPYnNlcnZlciBvYnNlcnZlcik7CisKKyAgICAvKioKKyAgICAgKiBTY2FsZXMgdGhlIHNwZWNpZmllZCBpbWFnZSB0byBmaXQgaW4gdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgYW5kIGRyYXdzIGl0CisgICAgICogd2l0aCB0aGUgZGVmaW5lZCBiYWNrZ3JvdW5kIGNvbG9yLiBUaGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBpbWFnZSB3aWxsCisgICAgICogYmUgZHJhd24gYXQgdGhlIHBvaW50ICh4LCB5KSBpbiBjdXJyZW50IGNvb3JkaW5hdGUgc3lzdGVtLiBUaGUgbm9uLW9wYXF1ZQorICAgICAqIHBpeGVscyB3aWxsIGJlIGRyYXduIGluIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLiBUaGUgaW1hZ2UgbG9hZGluZyBwcm9jZXNzCisgICAgICogbm90aWZpZXMgdGhlIHNwZWNpZmllZCBJbWFnZSBPYnNlcnZlci4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZQorICAgICAqIGltYWdlIGhhcyBsb2FkZWQsIG90aGVyd2lzZSBpdCByZXR1cm5zIGZhbHNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB3aGljaCB3aWxsIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBpbWFnZSdzIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgaW1hZ2UncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlIHdoaWNoIHNjYWxlcyB0aGUgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5nbGUgd2hpY2ggc2NhbGVzIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gYmdjb2xvcgorICAgICAqICAgICAgICAgICAgdGhlIGJhY2tncm91bmQgY29sb3IuCisgICAgICogQHBhcmFtIG9ic2VydmVyCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VPYnNlcnZlciBvYmplY3Qgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkIGFib3V0IGltYWdlCisgICAgICogICAgICAgICAgICBsb2FkaW5nIHByb2Nlc3MuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBsb2FkaW5nIGltYWdlIGlzIHN1Y2Nlc3NmdWwgb3IgaW1hZ2UgaXMgbnVsbCwgb3RoZXJ3aXNlCisgICAgICogICAgICAgICBmYWxzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBkcmF3SW1hZ2UoSW1hZ2UgaW1nLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgIENvbG9yIGJnY29sb3IsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpOworCisgICAgLyoqCisgICAgICogU2NhbGVzIHRoZSBzcGVjaWZpZWQgaW1hZ2UgdG8gZml0IGluIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGFuZCBkcmF3cworICAgICAqIGl0LiBUaGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBpbWFnZSB3aWxsIGJlIGRyYXduIGF0IHRoZSBwb2ludCAoeCwgeSkgaW4KKyAgICAgKiBjdXJyZW50IGNvb3JkaW5hdGUgc3lzdGVtLiBUaGUgaW1hZ2UgbG9hZGluZyBwcm9jZXNzIG5vdGlmaWVzIHRoZQorICAgICAqIHNwZWNpZmllZCBJbWFnZSBPYnNlcnZlci4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZSBpbWFnZSBoYXMKKyAgICAgKiBsb2FkZWQsIG90aGVyd2lzZSBpdCByZXR1cm5zIGZhbHNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB3aGljaCB3aWxsIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBpbWFnZSB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGltYWdlIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5nbGUgd2hpY2ggc2NhbGVzIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZSB3aGljaCBzY2FsZXMgdGhlIGltYWdlLgorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBub3RpZmllZCBhYm91dCBpbWFnZQorICAgICAqICAgICAgICAgICAgbG9hZGluZyBwcm9jZXNzLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgbG9hZGluZyBpbWFnZSBpcyBzdWNjZXNzZnVsIG9yIGltYWdlIGlzIG51bGwsIG90aGVyd2lzZQorICAgICAqICAgICAgICAgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltZywgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsCisgICAgICAgICAgICBJbWFnZU9ic2VydmVyIG9ic2VydmVyKTsKKworICAgIC8qKgorICAgICAqIFNjYWxlcyB0aGUgc3BlY2lmaWVkIGFyZWEgb2YgdGhlIHNwZWNpZmllZCBpbWFnZSB0byBmaXQgaW4gdGhlIHJlY3RhbmdsZQorICAgICAqIGFyZWEgZGVmaW5lZCBieSBpdHMgY29ybmVycyBjb29yZGluYXRlcyBhbmQgZHJhd3MgdGhlIHN1Yi1pbWFnZSB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBiYWNrZ3JvdW5kIGNvbG9yLiBUaGUgc3ViLWltYWdlIHRvIGJlIGRyYXduIGlzIGRlZmluZWQgYnkgaXRzCisgICAgICogdG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzIChzeDEsIHN5MSkgYW5kIGJvdHRvbSByaWdodCBjb3JuZXIKKyAgICAgKiBjb29yZGluYXRlcyAoc3gyLCBzeTIpIGNvbXB1dGVkIHdpdGggcmVzcGVjdCB0byB0aGUgb3JpZ2luICh0b3AgbGVmdAorICAgICAqIGNvcm5lcikgb2YgdGhlIHNvdXJjZSBpbWFnZS4gVGhlIG5vbiBvcGFxdWUgcGl4ZWxzIHdpbGwgYmUgZHJhd24gaW4gdGhlCisgICAgICogYmFja2dyb3VuZCBjb2xvci4gVGhlIGltYWdlIGxvYWRpbmcgcHJvY2VzcyBub3RpZmllcyBzcGVjaWZpZWQgSW1hZ2UKKyAgICAgKiBPYnNlcnZlci4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZSBpbWFnZSBoYXMgbG9hZGVkLCBvdGhlcndpc2UgaXQKKyAgICAgKiByZXR1cm5zIGZhbHNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB3aGljaCB3aWxsIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSBkeDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIHRvcCBsZWZ0IGNvcm5lciBjb29yZGluYXRlIG9mIHRoZSBkZXN0aW5hdGlvbiByZWN0YW5nbGUKKyAgICAgKiAgICAgICAgICAgIGFyZWEuCisgICAgICogQHBhcmFtIGR5MQorICAgICAqICAgICAgICAgICAgdGhlIFkgdG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGRlc3RpbmF0aW9uIHJlY3RhbmdsZQorICAgICAqICAgICAgICAgICAgYXJlYS4KKyAgICAgKiBAcGFyYW0gZHgyCisgICAgICogICAgICAgICAgICB0aGUgWCBib3R0b20gcmlnaHQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGRlc3RpbmF0aW9uCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUgYXJlYS4KKyAgICAgKiBAcGFyYW0gZHkyCisgICAgICogICAgICAgICAgICB0aGUgWSBib3R0b20gcmlnaHQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGRlc3RpbmF0aW9uCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUgYXJlYS4KKyAgICAgKiBAcGFyYW0gc3gxCisgICAgICogICAgICAgICAgICB0aGUgWCB0b3AgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSB0byBiZSBkcmF3bgorICAgICAqICAgICAgICAgICAgd2l0aGluIHRoZSBzb3VyY2UgaW1hZ2UuCisgICAgICogQHBhcmFtIHN5MQorICAgICAqICAgICAgICAgICAgdGhlIFkgdG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgdG8gYmUgZHJhd24KKyAgICAgKiAgICAgICAgICAgIHdpdGhpbiB0aGUgc291cmNlIGltYWdlLgorICAgICAqIEBwYXJhbSBzeDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGJvdHRvbSByaWdodCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSB0byBiZSBkcmF3bgorICAgICAqICAgICAgICAgICAgd2l0aGluIHRoZSBzb3VyY2UgaW1hZ2UuCisgICAgICogQHBhcmFtIHN5MgorICAgICAqICAgICAgICAgICAgdGhlIFkgYm90dG9tIHJpZ2h0IGNvcm5lciBjb29yZGluYXRlIG9mIHRoZSBhcmVhIHRvIGJlIGRyYXduCisgICAgICogICAgICAgICAgICB3aXRoaW4gdGhlIHNvdXJjZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gYmdjb2xvcgorICAgICAqICAgICAgICAgICAgdGhlIGJhY2tncm91bmQgY29sb3IuCisgICAgICogQHBhcmFtIG9ic2VydmVyCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VPYnNlcnZlciBvYmplY3Qgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkIGFib3V0IGltYWdlCisgICAgICogICAgICAgICAgICBsb2FkaW5nIHByb2Nlc3MuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBsb2FkaW5nIGltYWdlIGlzIHN1Y2Nlc3NmdWwgb3IgaW1hZ2UgaXMgbnVsbCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBkcmF3SW1hZ2UoSW1hZ2UgaW1nLCBpbnQgZHgxLCBpbnQgZHkxLCBpbnQgZHgyLCBpbnQgZHkyLCBpbnQgc3gxLAorICAgICAgICAgICAgaW50IHN5MSwgaW50IHN4MiwgaW50IHN5MiwgQ29sb3IgYmdjb2xvciwgSW1hZ2VPYnNlcnZlciBvYnNlcnZlcik7CisKKyAgICAvKioKKyAgICAgKiBTY2FsZXMgdGhlIHNwZWNpZmllZCBhcmVhIG9mIHRoZSBzcGVjaWZpZWQgaW1hZ2UgdG8gZml0IGluIHRoZSByZWN0YW5nbGUKKyAgICAgKiBhcmVhIGRlZmluZWQgYnkgaXRzIGNvcm5lcnMgY29vcmRpbmF0ZXMgYW5kIGRyYXdzIHRoZSBzdWItaW1hZ2UuIFRoZQorICAgICAqIHN1Yi1pbWFnZSB0byBiZSBkcmF3biBpcyBkZWZpbmVkIGJ5IGl0cyB0b3AgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZXMgKHN4MSwKKyAgICAgKiBzeTEpIGFuZCBib3R0b20gcmlnaHQgY29ybmVyIGNvb3JkaW5hdGVzIChzeDIsIHN5MikgY29tcHV0ZWQgd2l0aCByZXNwZWN0CisgICAgICogdG8gdGhlIG9yaWdpbiAodG9wIGxlZnQgY29ybmVyKSBvZiB0aGUgc291cmNlIGltYWdlLiBUaGUgaW1hZ2UgbG9hZGluZworICAgICAqIHByb2Nlc3Mgbm90aWZpZXMgc3BlY2lmaWVkIEltYWdlIE9ic2VydmVyLiBUaGlzIG1ldGhvZCByZXR1cm5zIHRydWUgaWYKKyAgICAgKiB0aGUgaW1hZ2UgaGFzIGxvYWRlZCwgb3RoZXJ3aXNlIGl0IHJldHVybnMgZmFsc2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltZworICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHdoaWNoIHdpbGwgYmUgZHJhd24uCisgICAgICogQHBhcmFtIGR4MQorICAgICAqICAgICAgICAgICAgdGhlIFggdG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGRlc3RpbmF0aW9uIHJlY3RhbmdsZQorICAgICAqICAgICAgICAgICAgYXJlYS4KKyAgICAgKiBAcGFyYW0gZHkxCisgICAgICogICAgICAgICAgICB0aGUgWSB0b3AgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlCisgICAgICogICAgICAgICAgICBhcmVhLgorICAgICAqIEBwYXJhbSBkeDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGJvdHRvbSByaWdodCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgZGVzdGluYXRpb24KKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZSBhcmVhLgorICAgICAqIEBwYXJhbSBkeTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGJvdHRvbSByaWdodCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgZGVzdGluYXRpb24KKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZSBhcmVhLgorICAgICAqIEBwYXJhbSBzeDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIHRvcCBsZWZ0IGNvcm5lciBjb29yZGluYXRlIG9mIHRoZSBhcmVhIHRvIGJlIGRyYXduCisgICAgICogICAgICAgICAgICB3aXRoaW4gdGhlIHNvdXJjZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gc3kxCisgICAgICogICAgICAgICAgICB0aGUgWSB0b3AgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSB0byBiZSBkcmF3bgorICAgICAqICAgICAgICAgICAgd2l0aGluIHRoZSBzb3VyY2UgaW1hZ2UuCisgICAgICogQHBhcmFtIHN4MgorICAgICAqICAgICAgICAgICAgdGhlIFggYm90dG9tIHJpZ2h0IGNvcm5lciBjb29yZGluYXRlIG9mIHRoZSBhcmVhIHRvIGJlIGRyYXduCisgICAgICogICAgICAgICAgICB3aXRoaW4gdGhlIHNvdXJjZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gc3kyCisgICAgICogICAgICAgICAgICB0aGUgWSBib3R0b20gcmlnaHQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgdG8gYmUgZHJhd24KKyAgICAgKiAgICAgICAgICAgIHdpdGhpbiB0aGUgc291cmNlIGltYWdlLgorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBub3RpZmllZCBhYm91dCBpbWFnZQorICAgICAqICAgICAgICAgICAgbG9hZGluZyBwcm9jZXNzLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgbG9hZGluZyBpbWFnZSBpcyBzdWNjZXNzZnVsIG9yIGltYWdlIGlzIG51bGwsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltZywgaW50IGR4MSwgaW50IGR5MSwgaW50IGR4MiwgaW50IGR5MiwgaW50IHN4MSwKKyAgICAgICAgICAgIGludCBzeTEsIGludCBzeDIsIGludCBzeTIsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpOworCisgICAgLyoqCisgICAgICogRHJhd3MgYSBsaW5lIGZyb20gdGhlIHBvaW50ICh4MSwgeTEpIHRvIHRoZSBwb2ludCAoeDIsIHkyKS4gVGhpcyBtZXRob2QKKyAgICAgKiBkcmF3cyB0aGUgbGluZSB3aXRoIGN1cnJlbnQgY29sb3Igd2hpY2ggY2FuIGJlIGNoYW5nZWQgYnkgc2V0Q29sb3IoQ29sb3IKKyAgICAgKiBjKSBtZXRob2QuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRyYXdMaW5lKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5Mik7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiBhbiBvdmFsIHRvIGZpdCBpbiB0aGUgcmVjdGFuZ2xlIGRlZmluZWQgYnkgdGhlIGdpdmVuCisgICAgICogd2lkdGgsIGhlaWdodCwgYW5kIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggdG9wIGxlZnQgY29ybmVyIG92YWwgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgdG9wIGxlZnQgY29ybmVyIG92YWwgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdmFsIHdpZHRoLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdmFsIGhlaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3T3ZhbChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiBhIHBvbHlnb24uIFRoZSBwb2x5Z29uIHZlcnRpY2VzIGFyZSBkZWZpbmVkIGJ5CisgICAgICogcG9pbnRzIHdpdGggeHBvaW50c1tpXSwgeXBvaW50c1tpXSBhcyBjb29yZGluYXRlcy4gVGhlIHBvbHlnb24gZWRnZXMgYXJlCisgICAgICogdGhlIGxpbmVzIGZyb20gdGhlIHBvaW50cyB3aXRoICh4cG9pbnRzW2ktMV0sIHlwb2ludHNbaS0xXSkgY29vcmRpbmF0ZXMKKyAgICAgKiB0byB0aGUgcG9pbnRzIHdpdGggKHhwb2ludHNbaV0sIHlwb2ludHNbaV0pIGNvb3JkaW5hdGVzLCBmb3IgMCA8IGkgPAorICAgICAqIG5wb2ludHMgKzEuCisgICAgICogCisgICAgICogQHBhcmFtIHhwb2ludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBYIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2x5Z29uIHZlcnRpY2VzLgorICAgICAqIEBwYXJhbSB5cG9pbnRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgWSBjb29yZGluYXRlcyBvZiB0aGUgcG9seWdvbiB2ZXJ0aWNlcy4KKyAgICAgKiBAcGFyYW0gbnBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBwb2x5Z29uIHZlcnRpY2VzL3BvaW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3UG9seWdvbihpbnRbXSB4cG9pbnRzLCBpbnRbXSB5cG9pbnRzLCBpbnQgbnBvaW50cyk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyBhIHNldCBvZiBjb25uZWN0ZWQgbGluZXMgd2hpY2ggYXJlIGRlZmluZWQgYnkgdGhlIHggYW5kIHkKKyAgICAgKiBjb29yZGluYXRlIGFycmF5cy4gVGhlIHBvbHlsaW5lIGlzIGNsb3NlZCBpZiBjb29yZGluYXRlcyBvZiB0aGUgZmlyc3QKKyAgICAgKiBwb2ludCBhcmUgdGhlIHNhbWUgYXMgY29vcmRpbmF0ZXMgb2YgdGhlIGxhc3QgcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHhwb2ludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBYIHBvaW50IGNvb3JkaW5hdGVzLgorICAgICAqIEBwYXJhbSB5cG9pbnRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgWSBwb2ludCBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gbnBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBwb2ludHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1BvbHlsaW5lKGludFtdIHhwb2ludHMsIGludFtdIHlwb2ludHMsIGludCBucG9pbnRzKTsKKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSBvdXRsaW5lIG9mIGEgcmVjdGFuZ2xlIHdpdGggcm91bmQgY29ybmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGFyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgYXJjIHdpZHRoIGZvciB0aGUgY29ybmVycy4KKyAgICAgKiBAcGFyYW0gYXJjSGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgYXJjIGhlaWdodCBmb3IgdGhlIGNvcm5lcnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1JvdW5kUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGFyY1dpZHRoLAorICAgICAgICAgICAgaW50IGFyY0hlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyBhIHRleHQgZGVmaW5lZCBieSBhbiBpdGVyYXRvci4gVGhlIGl0ZXJhdG9yIHNob3VsZCBzcGVjaWZ5IHRoZSBmb250CisgICAgICogZm9yIGV2ZXJ5IGNoYXJhY3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaXRlcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBpdGVyYXRvci4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1N0cmluZyhBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGludCB4LCBpbnQgeSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyBhIHRleHQgZGVmaW5lZCBieSBhIHN0cmluZy4gVGhpcyBtZXRob2QgZHJhd3MgdGhlIHRleHQgd2l0aCBjdXJyZW50CisgICAgICogZm9udCBhbmQgY29sb3IuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZy4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1N0cmluZyhTdHJpbmcgc3RyLCBpbnQgeCwgaW50IHkpOworCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIGFyYyBjb3ZlcmluZyB0aGUgcmVjdGFuZ2xlIGFuZCB1c2luZyB0aGUgY3VycmVudCBjb2xvci4gVGhlCisgICAgICogcmVjdGFuZ2xlIGlzIGRlZmluZWQgYnkgdGhlIG9yaWdpbiBwb2ludCAoWCwgWSkgYW5kIGRpbWVuc2lvbnMgKHdpZHRoIGFuZAorICAgICAqIGhlaWdodCkuIFRoZSBhcmMgY2VudGVyIGlzIHRoZSB0aGUgY2VudGVyIG9mIHNwZWNpZmllZCByZWN0YW5nbGUuIFRoZQorICAgICAqIGFuZ2xlIG9yaWdpbiBpcyBhdCB0aGUgMyBvJ2Nsb2NrIHBvc2l0aW9uLCBhbmQgYSBwb3NpdGl2ZSBhbmdsZSBnaXZlcworICAgICAqIGNvdW50ZXItY2xvY2t3aXNlIHJvdGF0aW9uLCBhIG5lZ2F0aXZlIGFuZ2xlIGdpdmVzIGNsb2Nrd2lzZSByb3RhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggb3JpZ2luIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCBzY2FsZXMgdGhlIGFyYy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgb3JpZ2luIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCBzY2FsZXMgdGhlIGFyYy4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHdoaWNoIHNjYWxlcyB0aGUgYXJjLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSB3aGljaCBzY2FsZXMgdGhlIGFyYy4KKyAgICAgKiBAcGFyYW0gc2EKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0IGFuZ2xlIC0gdGhlIG9yaWdpbiBhbmdsZSBvZiBhcmMuCisgICAgICogQHBhcmFtIGVhCisgICAgICogICAgICAgICAgICBhcmMgYW5nbGUgLSB0aGUgYW5ndWxhciBhcmMgdmFsdWUgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZpbGxBcmMoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBzYSwgaW50IGVhKTsKKworICAgIC8qKgorICAgICAqIEZpbGxzIGFuIG92YWwgd2l0aCB0aGUgY3VycmVudCBjb2xvciB3aGVyZSB0aGUgb3ZhbCBpcyBkZWZpbmVkIGJ5IHRoZQorICAgICAqIGJvdW5kaW5nIHJlY3RhbmdsZSB3aXRoIHRoZSBnaXZlbiB3aWR0aCwgaGVpZ2h0LCBhbmQgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCB0b3AgbGVmdCBjb3JuZXIgb3ZhbCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSB0b3AgbGVmdCBjb3JuZXIgb3ZhbCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIG92YWwgd2lkdGguCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIG92YWwgaGVpZ2h0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZpbGxPdmFsKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTsKKworICAgIC8qKgorICAgICAqIEZpbGxzIGEgcG9seWdvbiB3aXRoIHRoZSBjdXJyZW50IGNvbG9yLiBUaGUgcG9seWdvbiB2ZXJ0aWNlcyBhcmUgZGVmaW5lZAorICAgICAqIGJ5IHRoZSBwb2ludHMgd2l0aCB4cG9pbnRzW2ldLCB5cG9pbnRzW2ldIGFzIGNvb3JkaW5hdGVzLiBUaGUgcG9seWdvbgorICAgICAqIGVkZ2VzIGFyZSB0aGUgbGluZXMgZnJvbSB0aGUgcG9pbnRzIHdpdGggKHhwb2ludHNbaS0xXSwgeXBvaW50c1tpLTFdKQorICAgICAqIGNvb3JkaW5hdGVzIHRvIHRoZSBwb2ludHMgd2l0aCAoeHBvaW50c1tpXSwgeXBvaW50c1tpXSkgY29vcmRpbmF0ZXMsIGZvcgorICAgICAqIDAgPCBpIDwgbnBvaW50cyArMS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geHBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIFggY29vcmRpbmF0ZXMgb2YgdGhlIHBvbHlnb24gdmVydGljZXMuCisgICAgICogQHBhcmFtIHlwb2ludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBZIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2x5Z29uIHZlcnRpY2VzLgorICAgICAqIEBwYXJhbSBucG9pbnRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvbHlnb24gdmVydGljZXMvcG9pbnRzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZpbGxQb2x5Z29uKGludFtdIHhwb2ludHMsIGludFtdIHlwb2ludHMsIGludCBucG9pbnRzKTsKKworICAgIC8qKgorICAgICAqIEZpbGxzIGEgcmVjdGFuZ2xlIHdpdGggdGhlIGN1cnJlbnQgY29sb3IuIFRoZSByZWN0YW5nbGUgaXMgZGVmaW5lZCBieSBpdHMKKyAgICAgKiB3aWR0aCBhbmQgbGVuZ3RoIGFuZCB0b3AgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmaWxsUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBGaWxscyBhIHJvdW5kIGNvcm5lcmVkIHJlY3RhbmdsZSB3aXRoIHRoZSBjdXJyZW50IGNvbG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gYXJjV2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmMgd2lkdGggYXQgdGhlIGNvcm5lcnMuCisgICAgICogQHBhcmFtIGFyY0hlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGFyYyBoZWlnaHQgYXQgdGhlIGNvcm5lcnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZmlsbFJvdW5kUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGFyY1dpZHRoLAorICAgICAgICAgICAgaW50IGFyY0hlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjbGlwcGluZyBhcmVhLiA8YnI+CisgICAgICogPGJyPgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBTaGFwZSBvYmplY3Qgb2YgdGhlIGNsaXBwaW5nIGFyZWEgb3IgbnVsbCBpZiBpdCBpcyBub3Qgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTaGFwZSBnZXRDbGlwKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIGN1cnJlbnQgY2xpcHBpbmcgYXJlYSBhcyBhIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgUmVjdGFuZ2xlIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBib3VuZHMgb2YgdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgIGNsaXBwaW5nIGFyZWEuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFJlY3RhbmdsZSBnZXRDbGlwQm91bmRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGNvbG9yIG9mIEdyYXBoaWNzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29sb3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENvbG9yIGdldENvbG9yKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGZvbnQgb2YgR3JhcGhpY3MuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBmb250LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb250IGdldEZvbnQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvbnQgbWV0cmljcyBvZiB0aGUgc3BlY2lmaWVkIGZvbnQuIFRoZSBmb250IG1ldHJpY3Mgb2JqZWN0CisgICAgICogY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlbmRlcmluZyBvZiBhIHBhcnRpY3VsYXIgZm9udC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9udAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBmb250LgorICAgICAqIEByZXR1cm4gdGhlIGZvbnQgbWV0cmljcyBmb3IgdGhlIHNwZWNpZmllZCBmb250LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb250TWV0cmljcyBnZXRGb250TWV0cmljcyhGb250IGZvbnQpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmV3IGNsaXBwaW5nIGFyZWEgc3BlY2lmaWVkIGJ5IHJlY3RhbmdsZS4gVGhlIG5ldyBjbGlwcGluZyBhcmVhCisgICAgICogZG9lc24ndCBkZXBlbmQgb24gdGhlIHdpbmRvdydzIHZpc2liaWxpdHkuIFJlbmRlcmluZyBvcGVyYXRpb25zIGNhbid0IGJlCisgICAgICogcGVyZm9ybWVkIG91dHNpZGUgbmV3IGNsaXBwaW5nIGFyZWEuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBjbGlwcGluZyByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBjbGlwcGluZyByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIG5ldyBjbGlwcGluZyByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgbmV3IGNsaXBwaW5nIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRDbGlwKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5ldyBjbGlwcGluZyBhcmVhIHRvIGJlIHRoZSBhcmVhIHNwZWNpZmllZCBieSBTaGFwZSBvYmplY3QuIFRoZQorICAgICAqIG5ldyBjbGlwcGluZyBhcmVhIGRvZXNuJ3QgZGVwZW5kIG9uIHRoZSB3aW5kb3cncyB2aXNpYmlsaXR5LiBSZW5kZXJpbmcKKyAgICAgKiBvcGVyYXRpb25zIGNhbid0IGJlIHBlcmZvcm1lZCBvdXRzaWRlIG5ldyBjbGlwcGluZyBhcmVhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjbGlwCisgICAgICogICAgICAgICAgICB0aGUgU2hhcGUgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgbmV3IGNsaXBwaW5nIGFyZWEuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q2xpcChTaGFwZSBjbGlwKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbnQgR3JhcGhpY3MgY29sb3IuIEFsbCByZW5kZXJpbmcgb3BlcmF0aW9ucyB3aXRoIHRoaXMKKyAgICAgKiBHcmFwaGljcyB3aWxsIHVzZSB0aGlzIGNvbG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGNvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldENvbG9yKENvbG9yIGMpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBHcmFwaGljcyBmb250LiBBbGwgcmVuZGVyaW5nIG9wZXJhdGlvbnMgd2l0aCB0aGlzCisgICAgICogR3JhcGhpY3Mgd2lsbCB1c2UgdGhpcyBmb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250CisgICAgICogICAgICAgICAgICB0aGUgbmV3IGZvbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Rm9udChGb250IGZvbnQpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGFpbnQgbW9kZSBmb3IgdGhlIEdyYXBoaWNzIHdoaWNoIG92ZXJ3cml0ZXMgYWxsIHJlbmRlcmluZworICAgICAqIG9wZXJhdGlvbnMgd2l0aCB0aGUgY3VycmVudCBjb2xvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRQYWludE1vZGUoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFhPUiBtb2RlIGZvciB0aGUgR3JhcGhpY3Mgd2hpY2ggY2hhbmdlcyBhIHBpeGVsIGZyb20gdGhlIGN1cnJlbnQKKyAgICAgKiBjb2xvciB0byB0aGUgc3BlY2lmaWVkIFhPUiBjb2xvci4gPGJyPgorICAgICAqIDxicj4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgWE9SIG1vZGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WE9STW9kZShDb2xvciBjb2xvcik7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdGVzIHRoZSBvcmlnaW4gb2YgR3JhcGhpY3MgY3VycmVudCBjb29yZGluYXRlIHN5c3RlbSB0byB0aGUgcG9pbnQKKyAgICAgKiB3aXRoIFgsIFkgY29vcmRpbmF0ZXMgaW4gdGhlIGN1cnJlbnQgY29vcmRpbmF0ZSBzeXN0ZW0uIEFsbCByZW5kZXJpbmcKKyAgICAgKiBvcGVyYXRpb24gaW4gdGhpcyBHcmFwaGljcyB3aWxsIGJlIHJlbGF0ZWQgdG8gdGhlIG5ldyBvcmlnaW4uCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIG9yaWdpbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgb3JpZ2luLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRyYW5zbGF0ZShpbnQgeCwgaW50IHkpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0dyYXBoaWNzMkQuamF2YSBiL2F3dC9qYXZhL2F3dC9HcmFwaGljczJELmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRhNzMxOQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9HcmFwaGljczJELmphdmEKQEAgLTAsMCArMSw1MTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LkdseXBoVmVjdG9yOworaW1wb3J0IGphdmEuYXd0LmZvbnQuRm9udFJlbmRlckNvbnRleHQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlT3A7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLnJlbmRlcmFibGUuUmVuZGVyYWJsZUltYWdlOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBUaGUgR3JhcGhpY3MyRCBjbGFzcyBleHRlbmRzIEdyYXBoaWNzIGNsYXNzIGFuZCBwcm92aWRlcyBtb3JlIGNhcGFiaWxpdGllcworICogZm9yIHJlbmRlcmluZyB0ZXh0LCBpbWFnZXMsIHNoYXBlcy4gVGhpcyBwcm92aWRlcyBtZXRob2RzIHRvIHBlcmZvcm0KKyAqIHRyYW5zZm9ybWF0aW9uIG9mIGNvb3JkaW5hdGUgc3lzdGVtLCBjb2xvciBtYW5hZ2VtZW50LCBhbmQgdGV4dCBsYXlvdXQuIFRoZQorICogZm9sbG93aW5nIGF0dHJpYnV0ZXMgZXhpc3QgZm9yIHJlbmRlcmluZzoKKyAqIDx1bD4KKyAqIDxsaT5Db2xvciAtIGN1cnJlbnQgR3JhcGhpY3MyRCBjb2xvcjs8L2xpPgorICogPGxpPkZvbnQgLSBjdXJyZW50IEdyYXBoaWNzMkQgZm9udDs8L2xpPgorICogPGxpPlN0cm9rZSAtIHBlbiB3aXRoIGEgd2lkdGggb2YgMSBwaXhlbDs8L2xpPgorICogPGxpPlRyYW5zZm9ybSAtIGN1cnJlbnQgR3JhcGhpY3MyRCBUcmFuc2Zvcm1hdGlvbjs8L2xpPgorICogPGxpPkNvbXBvc2l0ZSAtIGFscGhhIGNvbXBvc2l0aW5nIHJ1bGVzIGZvciBjb21iaW5pbmcgc291cmNlIGFuZCBkZXN0aW5hdGlvbgorICogY29sb3JzLjwvbGk+CisgKiA8L3VsPgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEdyYXBoaWNzMkQgZXh0ZW5kcyBHcmFwaGljcyB7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgR3JhcGhpY3MyRCBvYmplY3QuIFRoaXMgY29uc3RydWN0b3Igc2hvdWxkIG5ldmVyIGJlCisgICAgICogY2FsbGVkIGRpcmVjdGx5LgorICAgICAqLworICAgIHByb3RlY3RlZCBHcmFwaGljczJEKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgcHJlZmVyZW5jZXMgZm9yIHRoZSByZW5kZXJpbmcgYWxnb3JpdGhtcy4gVGhlIHByZWZlcmVuY2VzIGFyZQorICAgICAqIGFyYml0cmFyeSBhbmQgc3BlY2lmaWVkIGJ5IE1hcCBvYmplY3RzLiBBbGwgc3BlY2lmaWVkIGJ5IE1hcCBvYmplY3QKKyAgICAgKiBwcmVmZXJlbmNlcyBjYW4gYmUgbW9kaWZpZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZFJlbmRlcmluZ0hpbnRzKE1hcDw/LCA/PiBoaW50cyk7CisKKyAgICAvKioKKyAgICAgKiBJbnRlcnNlY3RzIHRoZSBjdXJyZW50IGNsaXBwaW5nIGFyZWEgd2l0aCB0aGUgc3BlY2lmaWVkIFNoYXBlIGFuZCB0aGUKKyAgICAgKiByZXN1bHQgYmVjb21lcyBhIG5ldyBjbGlwcGluZyBhcmVhLiBJZiBjdXJyZW50IGNsaXBwaW5nIGFyZWEgaXMgbm90CisgICAgICogZGVmaW5lZCwgdGhlIFNoYXBlIGJlY29tZXMgdGhlIG5ldyBjbGlwcGluZyBhcmVhLiBObyByZW5kZXJpbmcgb3BlcmF0aW9ucworICAgICAqIGFyZSBhbGxvd2VkIG91dHNpZGUgdGhlIGNsaXBwaW5nIGFyZWEuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU2hhcGUgb2JqZWN0IHdoaWNoIHdpbGwgYmUgaW50ZXJzZWN0ZWQgd2l0aAorICAgICAqICAgICAgICAgICAgY3VycmVudCBjbGlwcGluZyBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNsaXAoU2hhcGUgcyk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiB0aGUgc3BlY2lmaWVkIFNoYXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgU2hhcGUgd2hpY2ggb3V0bGluZSBpcyBkcmF3bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3KFNoYXBlIHMpOworCisgICAgLyoqCisgICAgICogRHJhd3MgdGhlIHNwZWNpZmllZCBHbHlwaFZlY3RvciBvYmplY3QncyB0ZXh0IGF0IHRoZSBwb2ludCB4LCB5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgR2x5cGhWZWN0b3Igb2JqZWN0IHRvIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBwb3NpdGlvbiB3aGVyZSB0aGUgR2x5cGhWZWN0b3IncyB0ZXh0IHNob3VsZCBiZQorICAgICAqICAgICAgICAgICAgcmVuZGVyZWQuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIHBvc2l0aW9uIHdoZXJlIHRoZSBHbHlwaFZlY3RvcidzIHRleHQgc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICByZW5kZXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3R2x5cGhWZWN0b3IoR2x5cGhWZWN0b3IgZywgZmxvYXQgeCwgZmxvYXQgeSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgQnVmZmVyZWRJbWFnZSAtLSBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIG9wZXJhdGlvbgorICAgICAqIEJ1ZmZlcmVkSW1hZ2VPcCAtLSBhdCB0aGUgcG9pbnQgeCwgeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1nCisgICAgICogICAgICAgICAgICB0aGUgQnVmZmVyZWRJbWFnZSB0byBiZSByZW5kZXJlZC4KKyAgICAgKiBAcGFyYW0gb3AKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWx0ZXIgdG8gYmUgYXBwbGllZCB0byB0aGUgaW1hZ2UgYmVmb3JlIHJlbmRlcmluZy4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgd2hlcmUgdGhlIGltYWdlJ3MgdXBwZXIgbGVmdAorICAgICAqICAgICAgICAgICAgY29ybmVyIHdpbGwgYmUgcGxhY2VkLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB3aGVyZSB0aGUgaW1hZ2UncyB1cHBlciBsZWZ0CisgICAgICogICAgICAgICAgICBjb3JuZXIgd2lsbCBiZSBwbGFjZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd0ltYWdlKEJ1ZmZlcmVkSW1hZ2UgaW1nLCBCdWZmZXJlZEltYWdlT3Agb3AsIGludCB4LCBpbnQgeSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyBCdWZmZXJlZEltYWdlIHRyYW5zZm9ybWVkIGZyb20gaW1hZ2Ugc3BhY2UgaW50byB1c2VyIHNwYWNlCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBBZmZpbmVUcmFuc2Zvcm0geGZvcm0gYW5kIG5vdGlmaWVzIHRoZSBJbWFnZU9ic2VydmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBCdWZmZXJlZEltYWdlIHRvIGJlIHJlbmRlcmVkLgorICAgICAqIEBwYXJhbSB4Zm9ybQorICAgICAqICAgICAgICAgICAgdGhlIGFmZmluZSB0cmFuc2Zvcm1hdGlvbiBmcm9tIHRoZSBpbWFnZSB0byB0aGUgdXNlciBzcGFjZS4KKyAgICAgKiBAcGFyYW0gb2JzCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VPYnNlcnZlciB0byBiZSBub3RpZmllZCBhYm91dCB0aGUgaW1hZ2UgY29udmVyc2lvbi4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBpbWFnZSBpcyBzdWNjZXNzZnVsbHkgbG9hZGVkIGFuZCByZW5kZXJlZCwgb3IgaXQncworICAgICAqICAgICAgICAgbnVsbCwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWcsIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSwgSW1hZ2VPYnNlcnZlciBvYnMpOworCisgICAgLyoqCisgICAgICogRHJhd3MgYSBSZW5kZXJhYmxlSW1hZ2Ugd2hpY2ggaXMgdHJhbnNmb3JtZWQgZnJvbSBpbWFnZSBzcGFjZSBpbnRvIHVzZXIKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIEFmZmluZVRyYW5zZm9ybSB4Zm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1nCisgICAgICogICAgICAgICAgICB0aGUgUmVuZGVyYWJsZUltYWdlIHRvIGJlIHJlbmRlcmVkLgorICAgICAqIEBwYXJhbSB4Zm9ybQorICAgICAqICAgICAgICAgICAgdGhlIGFmZmluZSB0cmFuc2Zvcm1hdGlvbiBmcm9tIGltYWdlIHRvIHVzZXIgc3BhY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1JlbmRlcmFibGVJbWFnZShSZW5kZXJhYmxlSW1hZ2UgaW1nLCBBZmZpbmVUcmFuc2Zvcm0geGZvcm0pOworCisgICAgLyoqCisgICAgICogRHJhd3MgYSBSZW5kZXJlZEltYWdlIHdoaWNoIGlzIHRyYW5zZm9ybWVkIGZyb20gaW1hZ2Ugc3BhY2UgaW50byB1c2VyCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBBZmZpbmVUcmFuc2Zvcm0geGZvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIGltZworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmVkSW1hZ2UgdG8gYmUgcmVuZGVyZWQuCisgICAgICogQHBhcmFtIHhmb3JtCisgICAgICogICAgICAgICAgICB0aGUgYWZmaW5lIHRyYW5zZm9ybWF0aW9uIGZyb20gaW1hZ2UgdG8gdXNlciBzcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3UmVuZGVyZWRJbWFnZShSZW5kZXJlZEltYWdlIGltZywgQWZmaW5lVHJhbnNmb3JtIHhmb3JtKTsKKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGJ5IHRoZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuIFRoZSBmaXJzdAorICAgICAqIGNoYXJhY3RlcidzIHBvc2l0aW9uIGlzIHNwZWNpZmllZCBieSB0aGUgWCwgWSBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpdGVyYXRvcgorICAgICAqICAgICAgICAgICAgd2hvc2UgdGV4dCBpcyBkcmF3bi4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggcG9zaXRpb24gd2hlcmUgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBkcmF3bi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgcG9zaXRpb24gd2hlcmUgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBkcmF3bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3U3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvciwgZmxvYXQgeCwgZmxvYXQgeSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgc3RyaW5nIHNwZWNpZmllZCBieSB0aGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLiBUaGUgZmlyc3QKKyAgICAgKiBjaGFyYWN0ZXIncyBwb3NpdGlvbiBpcyBzcGVjaWZpZWQgYnkgdGhlIFgsIFkgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaXRlcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHdob3NlIHRleHQgaXMgZHJhd24uCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIHBvc2l0aW9uIHdoZXJlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgZHJhd24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIHBvc2l0aW9uIHdoZXJlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgZHJhd24uCisgICAgICogQHNlZSBqYXZhLmF3dC5HcmFwaGljcyNkcmF3U3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd1N0cmluZyhBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGludCB4LCBpbnQgeSk7CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgU3RyaW5nIHdob3NlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgcG9zaXRpb24gaXMgc3BlY2lmaWVkIGJ5IHRoZQorICAgICAqIHBhcmFtZXRlcnMgWCwgWS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB0byBiZSBkcmF3bi4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3Rlci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3U3RyaW5nKFN0cmluZyBzLCBmbG9hdCB4LCBmbG9hdCB5KTsKKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSBTdHJpbmcgd2hvc2UgdGhlIGZpcnN0IGNoYXJhY3RlciBjb29yZGluYXRlcyBhcmUgc3BlY2lmaWVkIGJ5CisgICAgICogdGhlIHBhcmFtZXRlcnMgWCwgWS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHRvIGJlIGRyYXduLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNoYXJhY3Rlci4KKyAgICAgKiBAc2VlIGphdmEuYXd0LkdyYXBoaWNzI2RyYXdTdHJpbmcoU3RyaW5nLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkcmF3U3RyaW5nKFN0cmluZyBzdHIsIGludCB4LCBpbnQgeSk7CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgaW50ZXJpb3Igb2YgdGhlIHNwZWNpZmllZCBTaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIFNoYXBlIHRvIGJlIGZpbGxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmaWxsKFNoYXBlIHMpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGJhY2tncm91bmQgY29sb3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENvbG9yIGdldEJhY2tncm91bmQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgY29tcG9zaXRlIG9mIHRoZSBHcmFwaGljczJELgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcG9zaXRlIHdoaWNoIHNwZWNpZmllcyB0aGUgY29tcG9zaXRpbmcgc3R5bGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENvbXBvc2l0ZSBnZXRDb21wb3NpdGUoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRldmljZSBjb25maWd1cmF0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRldmljZSBjb25maWd1cmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljc0NvbmZpZ3VyYXRpb24gZ2V0RGV2aWNlQ29uZmlndXJhdGlvbigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVuZGVyaW5nIGNvbnRleHQgb2YgdGhlIEZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZvbnRSZW5kZXJDb250ZXh0IGdldEZvbnRSZW5kZXJDb250ZXh0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IFBhaW50IG9mIEdyYXBoaWNzMkQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBQYWludCBvZiBHcmFwaGljczJELgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQYWludCBnZXRQYWludCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2Ygc2luZ2xlIHByZWZlcmVuY2UgZm9yIHNwZWNpZmllZCBrZXkuCisgICAgICogCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBrZXkgb2YgdGhlIHJlbmRlcmluZyBoaW50LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHJlbmRlcmluZyBoaW50IGZvciBzcGVjaWZpZWQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZ2V0UmVuZGVyaW5nSGludChSZW5kZXJpbmdIaW50cy5LZXkga2V5KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNldCBvZiB0aGUgcmVuZGVyaW5nIHByZWZlcmVuY2VzIGFzIGEgY29sbGVjdGlvbiBvZiBrZXkvdmFsdWUKKyAgICAgKiBwYWlycy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBSZW5kZXJpbmdIaW50cyB3aGljaCBjb250YWlucyB0aGUgcmVuZGVyaW5nIHByZWZlcmVuY2VzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBSZW5kZXJpbmdIaW50cyBnZXRSZW5kZXJpbmdIaW50cygpOworCisgICAgLyoqCisgICAgICogR2V0cyBjdXJyZW50IHN0cm9rZSBvZiB0aGUgR3JhcGhpY3MyRC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGN1cnJlbnQgc3Ryb2tlIG9mIHRoZSBHcmFwaGljczJELgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJva2UgZ2V0U3Ryb2tlKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGN1cnJlbnQgYWZmaW5lIHRyYW5zZm9ybSBvZiB0aGUgR3JhcGhpY3MyRC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGN1cnJlbnQgQWZmaW5lVHJhbnNmb3JtIG9mIHRoZSBHcmFwaGljczJELgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBBZmZpbmVUcmFuc2Zvcm0gZ2V0VHJhbnNmb3JtKCk7CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgU2hhcGUgaW50ZXJzZWN0cyB0aGUgc3BlY2lmaWVkCisgICAgICogUmVjdGFuZ2xlLiBJZiB0aGUgb25TdHJva2UgcGFyYW1ldGVyIGlzIHRydWUsIHRoaXMgbWV0aG9kIGNoZWNrcyB3aGV0aGVyCisgICAgICogb3Igbm90IHRoZSBzcGVjaWZpZWQgU2hhcGUgb3V0bGluZSBpbnRlcnNlY3RzIHRoZSBzcGVjaWZpZWQgUmVjdGFuZ2xlLAorICAgICAqIG90aGVyd2lzZSB0aGlzIG1ldGhvZCBjaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBTaGFwZSdzCisgICAgICogaW50ZXJpb3IgaW50ZXJzZWN0cyB0aGUgc3BlY2lmaWVkIFJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVjdAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBSZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBTaGFwZSB0byBjaGVjayBmb3IgaW50ZXJzZWN0aW9uLgorICAgICAqIEBwYXJhbSBvblN0cm9rZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRoaXMgbWV0aG9kIGNoZWNrcyBmb3IKKyAgICAgKiAgICAgICAgICAgIGludGVyc2VjdGlvbiBvZiB0aGUgU2hhcGUgb3V0bGluZSBvciBvZiB0aGUgU2hhcGUgaW50ZXJpb3IKKyAgICAgKiAgICAgICAgICAgIHdpdGggdGhlIFJlY3RhbmdsZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZXJlIGlzIGEgaGl0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaGl0KFJlY3RhbmdsZSByZWN0LCBTaGFwZSBzLCBib29sZWFuIG9uU3Ryb2tlKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgcm90YXRpb24gdHJhbnNmb3JtIHJlbGF0aXZlIHRvIGN1cnJlbnQgR3JhcGhpY3MyRCBUcmFuc2Zvcm0uCisgICAgICogVGhlIGNvb3JkaW5hdGUgc3lzdGVtIGlzIHJvdGF0ZWQgYnkgdGhlIHNwZWNpZmllZCBhbmdsZSBpbiByYWRpYW5zCisgICAgICogcmVsYXRpdmUgdG8gY3VycmVudCBvcmlnaW4uCisgICAgICogCisgICAgICogQHBhcmFtIHRoZXRhCisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByb3RhdGUoZG91YmxlIHRoZXRhKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgdHJhbnNsYXRlZCByb3RhdGlvbiB0cmFuc2Zvcm0gcmVsYXRpdmUgdG8gY3VycmVudCBHcmFwaGljczJECisgICAgICogVHJhbnNmb3JtLiBUaGUgY29vcmRpbmF0ZSBzeXN0ZW0gaXMgcm90YXRlZCBieSB0aGUgc3BlY2lmaWVkIGFuZ2xlIGluCisgICAgICogcmFkaWFucyByZWxhdGl2ZSB0byBjdXJyZW50IG9yaWdpbiBhbmQgdGhlbiBtb3ZlZCB0byBwb2ludCAoeCwgeSkuIElzCisgICAgICogdGhpcyByaWdodD8KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGhldGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJvdGF0ZShkb3VibGUgdGhldGEsIGRvdWJsZSB4LCBkb3VibGUgeSk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGxpbmVhciBzY2FsZSB0cmFuc2Zvcm0gcmVsYXRpdmUgdG8gY3VycmVudCBHcmFwaGljczJECisgICAgICogVHJhbnNmb3JtLiBUaGUgY29vcmRpbmF0ZSBzeXN0ZW0gaXMgcmVzY2FsZWQgdmVydGljYWxseSBhbmQgaG9yaXpvbnRhbGx5CisgICAgICogYnkgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzeAorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxpbmcgZmFjdG9yIGJ5IHdoaWNoIHRoZSBYIGNvb3JkaW5hdGUgaXMgbXVsdGlwbGllZC4KKyAgICAgKiBAcGFyYW0gc3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsaW5nIGZhY3RvciBieSB3aGljaCB0aGUgWSBjb29yZGluYXRlIGlzIG11bHRpcGxpZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2NhbGUoZG91YmxlIHN4LCBkb3VibGUgc3kpOworCisgICAgLyoqCisgICAgICogU2V0cyBhIG5ldyBiYWNrZ3JvdW5kIGNvbG9yIGZvciBjbGVhcmluZyByZWN0YW5ndWxhciBhcmVhcy4gVGhlIGNsZWFyUmVjdAorICAgICAqIG1ldGhvZCB1c2VzIHRoZSBjdXJyZW50IGJhY2tncm91bmQgY29sb3IuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9yCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGJhY2tncm91bmQgY29sb3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0QmFja2dyb3VuZChDb2xvciBjb2xvcik7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IGNvbXBvc2l0ZSBmb3IgR3JhcGhpY3MyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcAorICAgICAqICAgICAgICAgICAgdGhlIENvbXBvc2l0ZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q29tcG9zaXRlKENvbXBvc2l0ZSBjb21wKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBhaW50IGZvciBHcmFwaGljczJELgorICAgICAqIAorICAgICAqIEBwYXJhbSBwYWludAorICAgICAqICAgICAgICAgICAgdGhlIFBhaW50IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRQYWludChQYWludCBwYWludCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEga2V5LXZhbHVlIHBhaXIgaW4gdGhlIGN1cnJlbnQgUmVuZGVyaW5nSGludHMgbWFwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgb2YgdGhlIHJlbmRlcmluZyBoaW50IHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBzZXQgZm9yIHRoZSByZW5kZXJpbmcgaGludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRSZW5kZXJpbmdIaW50KFJlbmRlcmluZ0hpbnRzLktleSBrZXksIE9iamVjdCB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgY3VycmVudCByZW5kZXJpbmcgaGludHMgd2l0aCB0aGUgc3BlY2lmaWVkIHJlbmRlcmluZworICAgICAqIHByZWZlcmVuY2VzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaW50cworICAgICAqICAgICAgICAgICAgdGhlIG5ldyBNYXAgb2YgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlbmRlcmluZ0hpbnRzKE1hcDw/LCA/PiBoaW50cyk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzdHJva2UgZm9yIHRoZSBHcmFwaGljczJELgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgU3Ryb2tlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRTdHJva2UoU3Ryb2tlIHMpOworCisgICAgLyoqCisgICAgICogT3ZlcndyaXRlIHRoZSBjdXJyZW50IFRyYW5zZm9ybSBvZiB0aGUgR3JhcGhpY3MyRC4gVGhlIHNwZWNpZmllZAorICAgICAqIFRyYW5zZm9ybSBzaG91bGQgYmUgcmVjZWl2ZWQgZnJvbSB0aGUgZ2V0VHJhbnNmb3JtKCkgbWV0aG9kIGFuZCBzaG91bGQgYmUKKyAgICAgKiB1c2VkIG9ubHkgZm9yIHJlc3RvcmluZyB0aGUgb3JpZ2luYWwgR3JhcGhpY3MyRCB0cmFuc2Zvcm0gYWZ0ZXIgY2FsbGluZworICAgICAqIGRyYXcgb3IgZmlsbCBtZXRob2RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBUeAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSBUeCk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIHNoZWFyIHRyYW5zZm9ybSByZWxhdGl2ZSB0byBjdXJyZW50IEdyYXBoaWNzMkQgVHJhbnNmb3JtLiBUaGUKKyAgICAgKiBjb29yZGluYXRlIHN5c3RlbSBpcyBzaGlmdGVkIGJ5IHRoZSBzcGVjaWZpZWQgbXVsdGlwbGllcnMgcmVsYXRpdmUgdG8KKyAgICAgKiBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzaHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtdWx0aXBsaWVyIGJ5IHdoaWNoIHRoZSBYIGNvb3JkaW5hdGVzIHNoaWZ0IHBvc2l0aW9uIGFsb25nCisgICAgICogICAgICAgICAgICBYIGF4aXMgYXMgYSBmdW5jdGlvbiBvZiBZIGNvb3JkaW5hdGVzLgorICAgICAqIEBwYXJhbSBzaHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBtdWx0aXBsaWVyIGJ5IHdoaWNoIHRoZSBZIGNvb3JkaW5hdGVzIHNoaWZ0IHBvc2l0aW9uIGFsb25nCisgICAgICogICAgICAgICAgICBZIGF4aXMgYXMgYSBmdW5jdGlvbiBvZiBYIGNvb3JkaW5hdGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNoZWFyKGRvdWJsZSBzaHgsIGRvdWJsZSBzaHkpOworCisgICAgLyoqCisgICAgICogQ29uY2F0ZW5hdGVzIHRoZSBBZmZpbmVUcmFuc2Zvcm0gb2JqZWN0IHdpdGggY3VycmVudCBUcmFuc2Zvcm0gb2YgdGhpcworICAgICAqIEdyYXBoaWNzMkQuIFRoZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIGluIHJldmVyc2Ugb3JkZXIgd2l0aCB0aGUgbGFzdAorICAgICAqIHNwZWNpZmllZCB0cmFuc2Zvcm0gYXBwbGllZCBmaXJzdCBhbmQgdGhlIG5leHQgdHJhbnNmb3JtYXRpb24gYXBwbGllZCB0bworICAgICAqIHRoZSByZXN1bHQgb2YgcHJldmlvdXMgdHJhbnNmb3JtYXRpb24uIE1vcmUgcHJlY2lzZWx5LCBpZiBDeCBpcyB0aGUKKyAgICAgKiBjdXJyZW50IEdyYXBoaWNzMkQgdHJhbnNmb3JtLCB0aGUgdHJhbnNmb3JtIG1ldGhvZCdzIHJlc3VsdCB3aXRoIFR4IGFzCisgICAgICogdGhlIHBhcmFtZXRlciBpcyB0aGUgdHJhbnNmb3JtYXRpb24gUngsIHdoZXJlIFJ4KHApID0gQ3goVHgocCkpLCBmb3IgcCAtCisgICAgICogYSBwb2ludCBpbiBjdXJyZW50IGNvb3JkaW5hdGUgc3lzdGVtLiBSeCBiZWNvbWVzIHRoZSBjdXJyZW50IFRyYW5zZm9ybQorICAgICAqIGZvciB0aGlzIEdyYXBoaWNzMkQuCisgICAgICogCisgICAgICogQHBhcmFtIFR4CisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtIG9iamVjdCB0byBiZSBjb25jYXRlbmF0ZWQgd2l0aCBjdXJyZW50CisgICAgICogICAgICAgICAgICBUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSBUeCk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIHRyYW5zbGF0ZSB0cmFuc2Zvcm0gcmVsYXRpdmUgdG8gY3VycmVudCBHcmFwaGljczJEIFRyYW5zZm9ybS4KKyAgICAgKiBUaGUgY29vcmRpbmF0ZSBzeXN0ZW0gaXMgbW92ZWQgYnkgdGhlIHNwZWNpZmllZCBkaXN0YW5jZSByZWxhdGl2ZSB0bworICAgICAqIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHR4CisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNsYXRpb24gZGlzdGFuY2UgYWxvbmcgdGhlIFggYXhpcy4KKyAgICAgKiBAcGFyYW0gdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2xhdGlvbiBkaXN0YW5jZSBhbG9uZyB0aGUgWSBheGlzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRyYW5zbGF0ZShkb3VibGUgdHgsIGRvdWJsZSB0eSk7CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0aGUgb3JpZ2luIEdyYXBoaWNzMkQgVHJhbnNmb3JtIHRvIHRoZSBwb2ludCB3aXRoIHgsIHkgY29vcmRpbmF0ZXMKKyAgICAgKiBpbiBjdXJyZW50IGNvb3JkaW5hdGUgc3lzdGVtLiBUaGUgbmV3IG9yaWdpbiBvZiBjb29yZGluYXRlIHN5c3RlbSBpcworICAgICAqIG1vdmVkIHRvIHRoZSAoeCwgeSkgcG9pbnQgYWNjb3JkaW5nbHkuIEFsbCByZW5kZXJpbmcgYW5kIHRyYW5zZm9ybQorICAgICAqIG9wZXJhdGlvbnMgYXJlIHBlcmZvcm1lZCByZWxhdGl2ZSB0byB0aGlzIG5ldyBvcmlnaW4uCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUuCisgICAgICogQHNlZSBqYXZhLmF3dC5HcmFwaGljcyN0cmFuc2xhdGUoaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdHJhbnNsYXRlKGludCB4LCBpbnQgeSk7CisKKyAgICAvKioKKyAgICAgKiBGaWxscyBhIDNEIHJlY3RhbmdsZSB3aXRoIHRoZSBjdXJyZW50IGNvbG9yLiBUaGUgcmVjdGFuZ2xlIGlzIHNwZWNpZmllZAorICAgICAqIGJ5IGl0cyB3aWR0aCwgaGVpZ2h0LCBhbmQgdG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHRvcCBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHJhaXNlZAorICAgICAqICAgICAgICAgICAgYSBib29sZWFuIHZhbHVlIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSByZWN0YW5nbGUgaXMgZHJhd24KKyAgICAgKiAgICAgICAgICAgIGFzIHJhaXNlZCBvciBpbmRlbnRlZC4KKyAgICAgKiBAc2VlIGphdmEuYXd0LkdyYXBoaWNzI2ZpbGwzRFJlY3QoaW50LCBpbnQsIGludCwgaW50LCBib29sZWFuKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGwzRFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gcmFpc2VkKSB7CisgICAgICAgIC8vIEFjY29yZGluZyB0byB0aGUgc3BlYywgY29sb3Igc2hvdWxkIGJlIHVzZWQgaW5zdGVhZCBvZiBwYWludCwKKyAgICAgICAgLy8gc28gR3JhcGhpY3MuZmlsbDNEUmVjdCByZXNldHMgcGFpbnQgYW5kCisgICAgICAgIC8vIGl0IHNob3VsZCBiZSByZXN0b3JlZCBhZnRlciB0aGUgY2FsbAorICAgICAgICBQYWludCBzYXZlZFBhaW50ID0gZ2V0UGFpbnQoKTsKKyAgICAgICAgc3VwZXIuZmlsbDNEUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCByYWlzZWQpOworICAgICAgICBzZXRQYWludChzYXZlZFBhaW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEcmF3cyB0aGUgaGlnaGxpZ2h0ZWQgb3V0bGluZSBvZiBhIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdG9wIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB0b3AgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSByYWlzZWQKKyAgICAgKiAgICAgICAgICAgIGEgYm9vbGVhbiB2YWx1ZSB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgcmVjdGFuZ2xlIGlzIGRyYXduCisgICAgICogICAgICAgICAgICBhcyByYWlzZWQgb3IgaW5kZW50ZWQuCisgICAgICogQHNlZSBqYXZhLmF3dC5HcmFwaGljcyNkcmF3M0RSZWN0KGludCwgaW50LCBpbnQsIGludCwgYm9vbGVhbikKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3M0RSZWN0KGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIHJhaXNlZCkgeworICAgICAgICAvLyBBY2NvcmRpbmcgdG8gdGhlIHNwZWMsIGNvbG9yIHNob3VsZCBiZSB1c2VkIGluc3RlYWQgb2YgcGFpbnQsCisgICAgICAgIC8vIHNvIEdyYXBoaWNzLmRyYXczRFJlY3QgcmVzZXRzIHBhaW50IGFuZAorICAgICAgICAvLyBpdCBzaG91bGQgYmUgcmVzdG9yZWQgYWZ0ZXIgdGhlIGNhbGwKKyAgICAgICAgUGFpbnQgc2F2ZWRQYWludCA9IGdldFBhaW50KCk7CisgICAgICAgIHN1cGVyLmRyYXczRFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCwgcmFpc2VkKTsKKyAgICAgICAgc2V0UGFpbnQoc2F2ZWRQYWludCk7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9HcmFwaGljc0NvbmZpZ3VyYXRpb24uamF2YSBiL2F3dC9qYXZhL2F3dC9HcmFwaGljc0NvbmZpZ3VyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTllODk2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0dyYXBoaWNzQ29uZmlndXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjI2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuVm9sYXRpbGVJbWFnZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24gY2xhc3MgY29udGFpbnMgdGhlIGNoYXJhY3RlcmlzdGljcyBvZiBncmFwaGljcworICogZGV2aWNlcyBzdWNoIGFzIGEgcHJpbnRlciBvciBtb25pdG9yLCBhbmQgcmVwcmVzZW50cyBkZXZpY2UncyBjYXBhYmlsaXRpZXMKKyAqIGFuZCBtb2Rlcy4gTWFueSBHcmFwaGljc0NvbmZpZ3VyYXRpb24gb2JqZWN0cyBjYW4gYmUgYXNzb2NpYXRlZCB3aXRoIHNpbmdsZQorICogZ3JhcGhpY3MgZGV2aWNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEdyYXBoaWNzQ29uZmlndXJhdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBjb3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseSBhbmQgc2hvdWxkIGJlIG9idGFpbmVkIGluIGV4dGVuZGVkCisgICAgICogY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgR3JhcGhpY3NDb25maWd1cmF0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgQnVmZmVyZWRJbWFnZSBpbWFnZSBvYmplY3Qgd2l0aCBhIGRhdGEgbGF5b3V0IGFuZCBjb2xvciBtb2RlbAorICAgICAqIGNvbXBhdGlibGUgd2l0aCB0aGlzIEdyYXBoaWNzQ29uZmlndXJhdGlvbiB3aXRoIHNwZWNpZmllZCB3aWR0aCBhbmQKKyAgICAgKiBoZWlnaHQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBCdWZmZXJlZEltYWdlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgQnVmZmVyZWRJbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlIG9iamVjdCB3aXRoIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0CisgICAgICogICAgICAgICBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVJbWFnZShpbnQgd2lkdGgsIGludCBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEJ1ZmZlcmVkSW1hZ2UgdGhhdCBoYXMgdGhlIHNwZWNpZmllZCB3aWR0aCwgaGVpZ2h0LAorICAgICAqIHRyYW5zcGFyZW5jeSBhbmQgaGFzIGEgZGF0YSBsYXlvdXQgYW5kIGNvbG9yIG1vZGVsIGNvbXBhdGlibGUgd2l0aCB0aGlzCisgICAgICogR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIGltYWdlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgaW1hZ2UuCisgICAgICogQHBhcmFtIHRyYW5zcGFyZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zcGFyZW5jeSBtb2RlLgorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVJbWFnZShpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCB0cmFuc3BhcmVuY3kpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFZvbGF0aWxlSW1hZ2UgdGhhdCBoYXMgdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0IGFuZCBoYXMgYQorICAgICAqIGRhdGEgbGF5b3V0IGFuZCBjb2xvciBtb2RlbCBjb21wYXRpYmxlIHdpdGggdGhpcyBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBpbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBWb2xhdGlsZUltYWdlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgVm9sYXRpbGVJbWFnZSBjcmVhdGVDb21wYXRpYmxlVm9sYXRpbGVJbWFnZShpbnQgd2lkdGgsIGludCBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFZvbGF0aWxlSW1hZ2UgdGhhdCBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkIHdpZHRoLCBoZWlnaHQsCisgICAgICogdHJhbnNwYXJlbmN5IGFuZCBoYXMgYSBkYXRhIGxheW91dCBhbmQgY29sb3IgbW9kZWwgY29tcGF0aWJsZSB3aXRoIHRoaXMKKyAgICAgKiBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBpbWFnZS4KKyAgICAgKiBAcGFyYW0gdHJhbnNwYXJlbmN5CisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNwYXJlbmN5IG1vZGUuCisgICAgICogQHJldHVybiB0aGUgVm9sYXRpbGVJbWFnZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFZvbGF0aWxlSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgaW50IHRyYW5zcGFyZW5jeSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgYXJlYSBjb3ZlcmVkIGJ5IHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24gaW4gdGhlCisgICAgICogZGV2aWNlIGNvb3JkaW5hdGVzIHNwYWNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFJlY3RhbmdsZSBvZiBHcmFwaGljc0NvbmZpZ3VyYXRpb24ncyBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFJlY3RhbmdsZSBnZXRCb3VuZHMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbG9yTW9kZWwgb2YgdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBDb2xvck1vZGVsIG9iamVjdCBvZiB0aGUgR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDb2xvck1vZGVsIGdldENvbG9yTW9kZWwoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIENvbG9yTW9kZWwgb2YgdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbiB3aGljaCBzdXBwb3J0cyBzcGVjaWZpZWQKKyAgICAgKiBUcmFuc3BhcmVuY3kuCisgICAgICogCisgICAgICogQHBhcmFtIHRyYW5zcGFyZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIFRyYW5zcGFyZW5jeSBtb2RlOiBPUEFRVUUsIEJJVE1BU0ssIG9yIFRSQU5TTFVDRU5ULgorICAgICAqIEByZXR1cm4gdGhlIENvbG9yTW9kZWwgb2YgdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbiB3aGljaCBzdXBwb3J0cworICAgICAqICAgICAgICAgc3BlY2lmaWVkIFRyYW5zcGFyZW5jeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKGludCB0cmFuc3BhcmVuY3kpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBBZmZpbmVUcmFuc2Zvcm0gb2YgdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCB0cmFuc2xhdGVzIHVzZXIgY29vcmRpbmF0ZXMgdG8gZGV2aWNlIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgQWZmaW5lVHJhbnNmb3JtIG9mIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEFmZmluZVRyYW5zZm9ybSBnZXREZWZhdWx0VHJhbnNmb3JtKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBHcmFwaGljc0RldmljZSBvZiB0aGUgR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNzRGV2aWNlIG9mIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEdyYXBoaWNzRGV2aWNlIGdldERldmljZSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbm9ybWFsaXppbmcgQWZmaW5lVHJhbnNmb3JtIG9mIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbm9ybWFsaXppbmcgQWZmaW5lVHJhbnNmb3JtIG9mIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEFmZmluZVRyYW5zZm9ybSBnZXROb3JtYWxpemluZ1RyYW5zZm9ybSgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBWb2xhdGlsZUltYWdlIHdpdGggc3BlY2lmaWVkIHdpZHRoLCBoZWlnaHQsIEltYWdlQ2FwYWJpbGl0aWVzOyBhCisgICAgICogZGF0YSBsYXlvdXQgYW5kIGNvbG9yIG1vZGVsIGNvbXBhdGlibGUgd2l0aCB0aGlzIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIGltYWdlLgorICAgICAqIEBwYXJhbSBjYXBzCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VDYXBhYmlsaXRpZXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIFZvbGF0aWxlSW1hZ2Ugd2hpY2ggZGF0YSBsYXlvdXQgYW5kIGNvbG9yIG1vZGVsIGNvbXBhdGlibGUKKyAgICAgKiAgICAgICAgIHdpdGggdGhpcyBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICogQHRocm93cyBBV1RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBJbWFnZUNhcGFiaWxpdGllcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZQorICAgICAqICAgICAgICAgICAgIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVm9sYXRpbGVJbWFnZSBjcmVhdGVDb21wYXRpYmxlVm9sYXRpbGVJbWFnZShpbnQgd2lkdGgsIGludCBoZWlnaHQsIEltYWdlQ2FwYWJpbGl0aWVzIGNhcHMpCisgICAgICAgICAgICB0aHJvd3MgQVdURXhjZXB0aW9uIHsKKyAgICAgICAgVm9sYXRpbGVJbWFnZSByZXMgPSBjcmVhdGVDb21wYXRpYmxlVm9sYXRpbGVJbWFnZSh3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgaWYgKCFyZXMuZ2V0Q2FwYWJpbGl0aWVzKCkuZXF1YWxzKGNhcHMpKSB7CisgICAgICAgICAgICAvLyBhd3QuMTRBPUNhbiBub3QgY3JlYXRlIFZvbGF0aWxlSW1hZ2Ugd2l0aCBzcGVjaWZpZWQgY2FwYWJpbGl0aWVzCisgICAgICAgICAgICB0aHJvdyBuZXcgQVdURXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE0QSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFZvbGF0aWxlSW1hZ2Ugd2l0aCBzcGVjaWZpZWQgd2lkdGgsIGhlaWdodCwgdHJhbnNwYXJlbmN5IGFuZAorICAgICAqIEltYWdlQ2FwYWJpbGl0aWVzOyBhIGRhdGEgbGF5b3V0IGFuZCBjb2xvciBtb2RlbCBjb21wYXRpYmxlIHdpdGggdGhpcworICAgICAqIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIGltYWdlLgorICAgICAqIEBwYXJhbSBjYXBzCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VDYXBhYmlsaXRpZXMgb2JqZWN0LgorICAgICAqIEBwYXJhbSB0cmFuc3BhcmVuY3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBUcmFuc3BhcmVuY3kgbW9kZTogT1BBUVVFLCBCSVRNQVNLLCBvciBUUkFOU0xVQ0VOVC4KKyAgICAgKiBAcmV0dXJuIHRoZSBWb2xhdGlsZUltYWdlIHdoaWNoIGRhdGEgbGF5b3V0IGFuZCBjb2xvciBtb2RlbCBjb21wYXRpYmxlCisgICAgICogICAgICAgICB3aXRoIHRoaXMgR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqIEB0aHJvd3MgQVdURXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgSW1hZ2VDYXBhYmlsaXRpZXMgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgICBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIFZvbGF0aWxlSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgSW1hZ2VDYXBhYmlsaXRpZXMgY2FwcywgaW50IHRyYW5zcGFyZW5jeSkgdGhyb3dzIEFXVEV4Y2VwdGlvbiB7CisgICAgICAgIFZvbGF0aWxlSW1hZ2UgcmVzID0gY3JlYXRlQ29tcGF0aWJsZVZvbGF0aWxlSW1hZ2Uod2lkdGgsIGhlaWdodCwgdHJhbnNwYXJlbmN5KTsKKyAgICAgICAgaWYgKCFyZXMuZ2V0Q2FwYWJpbGl0aWVzKCkuZXF1YWxzKGNhcHMpKSB7CisgICAgICAgICAgICAvLyBhd3QuMTRBPUNhbiBub3QgY3JlYXRlIFZvbGF0aWxlSW1hZ2Ugd2l0aCBzcGVjaWZpZWQgY2FwYWJpbGl0aWVzCisgICAgICAgICAgICB0aHJvdyBuZXcgQVdURXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE0QSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYnVmZmVyaW5nIGNhcGFiaWxpdGllcyBvZiB0aGUgR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlckNhcGFiaWxpdGllcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlckNhcGFiaWxpdGllcyBnZXRCdWZmZXJDYXBhYmlsaXRpZXMoKSB7CisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyQ2FwYWJpbGl0aWVzKG5ldyBJbWFnZUNhcGFiaWxpdGllcyhmYWxzZSksIG5ldyBJbWFnZUNhcGFiaWxpdGllcyhmYWxzZSksCisgICAgICAgICAgICAgICAgQnVmZmVyQ2FwYWJpbGl0aWVzLkZsaXBDb250ZW50cy5VTkRFRklORUQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGltYWdlIGNhcGFiaWxpdGllcyBvZiB0aGUgR3JhcGhpY3NDb25maWd1cmF0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEltYWdlQ2FwYWJpbGl0aWVzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VDYXBhYmlsaXRpZXMgZ2V0SW1hZ2VDYXBhYmlsaXRpZXMoKSB7CisgICAgICAgIHJldHVybiBuZXcgSW1hZ2VDYXBhYmlsaXRpZXMoZmFsc2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9HcmFwaGljc0RldmljZS5qYXZhIGIvYXd0L2phdmEvYXd0L0dyYXBoaWNzRGV2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWVkYTRlMAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9HcmFwaGljc0RldmljZS5qYXZhCkBAIC0wLDAgKzEsMTk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgR3JhcGhpY3NEZXZpY2UgY2xhc3MgZGVzY3JpYmVzIHRoZSBncmFwaGljcyBkZXZpY2VzIChzdWNoIGFzIHNjcmVlbnMgb3IKKyAqIHByaW50ZXJzKSB3aGljaCBhcmUgYXZhaWxhYmxlIGluIGEgcGFydGljdWxhciBncmFwaGljcyBlbnZpcm9ubWVudC4gTWFueQorICogR3JhcGhpY3NEZXZpY2UgaW5zdGFuY2VzIGNhbiBiZSBhc3NvY2lhdGVkIHdpdGggYSBzaW5nbGUgR3JhcGhpY3NFbnZpcm9ubWVudC4KKyAqIEVhY2ggR3JhcGhpY3NEZXZpY2UgaGFzIG9uZSBvciBtb3JlIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBvYmplY3RzIHdoaWNoCisgKiBzcGVjaWZ5IHRoZSBkaWZmZXJlbnQgY29uZmlndXJhdGlvbnMgYW5kIG1vZGVzIG9mIEdyYXBoaWNzRGV2aWNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEdyYXBoaWNzRGV2aWNlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkaXNwbGF5IG1vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBEaXNwbGF5TW9kZSBkaXNwbGF5TW9kZTsKKworICAgIC8vID8/P0FXVAorICAgIC8vIHByaXZhdGUgV2luZG93IGZ1bGxTY3JlZW5XaW5kb3cgPSBudWxsOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfSU1BR0VfQlVGRkVSIGluZGljYXRlcyBhIGltYWdlIGJ1ZmZlciBkZXZpY2UuCisgICAgICovCisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0lNQUdFX0JVRkZFUiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9QUklOVEVSIGluZGljYXRlcyBhIHByaW50ZXIgZGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfUFJJTlRFUiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9SQVNURVJfU0NSRUVOIGluZGljYXRlcyBhIHJhc3RlciBzY3JlZW4gZGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfUkFTVEVSX1NDUkVFTiA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBpcyBub3QgdG8gYmUgdXNlZCBkaXJlY3RseSBhcyB0aGlzIGNsYXNzIGlzIGFic3RyYWN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBHcmFwaGljc0RldmljZSgpIHsKKyAgICAgICAgZGlzcGxheU1vZGUgPSBuZXcgRGlzcGxheU1vZGUoMCwgMCwgRGlzcGxheU1vZGUuQklUX0RFUFRIX01VTFRJLAorICAgICAgICAgICAgICAgIERpc3BsYXlNb2RlLlJFRlJFU0hfUkFURV9VTktOT1dOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUKKyAgICAgKiBHcmFwaGljc0RldmljZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgIEdyYXBoaWNzRGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljc0NvbmZpZ3VyYXRpb25bXSBnZXRDb25maWd1cmF0aW9ucygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciB0aGUgR3JhcGhpY3NEZXZpY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBHcmFwaGljc0NvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciB0aGUgR3JhcGhpY3NEZXZpY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEdyYXBoaWNzQ29uZmlndXJhdGlvbiBnZXREZWZhdWx0Q29uZmlndXJhdGlvbigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgU3RyaW5nIGlkZW50aWZpZXIgd2hpY2ggYXNzb2NpYXRlZCB3aXRoIHRoZSBHcmFwaGljc0RldmljZSBpbgorICAgICAqIHRoZSBHcmFwaGljc0Vudmlyb25tZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyBpZGVudGlmaWVyIG9mIHRoZSBHcmFwaGljc0RldmljZSBpbiB0aGUKKyAgICAgKiAgICAgICAgIEdyYXBoaWNzRW52aXJvbm1lbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRJRHN0cmluZygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHlwZSBvZiB0aGlzIEdyYXBoaWNzRGV2aWNlOiBUWVBFX0lNQUdFX0JVRkZFUiwgVFlQRV9QUklOVEVSIG9yCisgICAgICogVFlQRV9SQVNURVJfU0NSRUVOLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgb2YgdGhpcyBHcmFwaGljc0RldmljZTogVFlQRV9JTUFHRV9CVUZGRVIsIFRZUEVfUFJJTlRFUgorICAgICAqICAgICAgICAgb3IgVFlQRV9SQVNURVJfU0NSRUVOLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0VHlwZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBpbiBhY2NlbGVyYXRlZCBtZW1vcnkgb24gdGhpcworICAgICAqIGRldmljZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlIGFjY2VsZXJhdGVkIG1lbW9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEF2YWlsYWJsZUFjY2VsZXJhdGVkTWVtb3J5KCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKgorICAgICAqID8/P0FXVCBwdWJsaWMgR3JhcGhpY3NDb25maWd1cmF0aW9uCisgICAgICogZ2V0QmVzdENvbmZpZ3VyYXRpb24oR3JhcGhpY3NDb25maWdUZW1wbGF0ZSBnY3QpIHsgcmV0dXJuCisgICAgICogZ2N0LmdldEJlc3RDb25maWd1cmF0aW9uKGdldENvbmZpZ3VyYXRpb25zKCkpOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGRpc3BsYXkgbW9kZSBvZiB0aGUgR3JhcGhpY3NEZXZpY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBkaXNwbGF5IG1vZGUgb2YgdGhlIEdyYXBoaWNzRGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBEaXNwbGF5TW9kZSBnZXREaXNwbGF5TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIGRpc3BsYXlNb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgZGlzcGxheSBtb2RlcyBhdmFpbGFibGUgaW4gdGhpcyBHcmFwaGljc0RldmljZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGRpc3BsYXkgbW9kZXMgYXZhaWxhYmxlIGluIHRoaXMgR3JhcGhpY3NEZXZpY2UuCisgICAgICovCisgICAgcHVibGljIERpc3BsYXlNb2RlW10gZ2V0RGlzcGxheU1vZGVzKCkgeworICAgICAgICBEaXNwbGF5TW9kZVtdIGRtcyA9IHsKKyAgICAgICAgICAgIGRpc3BsYXlNb2RlCisgICAgICAgIH07CisgICAgICAgIHJldHVybiBkbXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiA/Pz9BV1QgcHVibGljIFdpbmRvdyBnZXRGdWxsU2NyZWVuV2luZG93KCkgeyByZXR1cm4gZnVsbFNjcmVlbldpbmRvdzsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgR3JhcGhpY3NEZXZpY2Ugc3VwcG9ydHMgbG93LWxldmVsIGRpc3BsYXkgY2hhbmdlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgR3JhcGhpY3NEZXZpY2Ugc3VwcG9ydHMgbG93LWxldmVsIGRpc3BsYXkgY2hhbmdlczsKKyAgICAgKiAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Rpc3BsYXlDaGFuZ2VTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBHcmFwaGljc0RldmljZSBzdXBwb3J0cyBmdWxsIHNjcmVlbiBtb2RlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBHcmFwaGljc0RldmljZSBzdXBwb3J0cyBmdWxsIHNjcmVlbiBtb2RlLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRnVsbFNjcmVlblN1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vIGFuIGFycmF5IG9mIGRpc3BsYXkgbW9kZXMgYXZhaWxhYmxlIGluIHRoaXMgR3JhcGhpY3NEZXZpY2UuCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkaXNwbGF5IG1vZGUgb2YgdGhpcyBHcmFwaGljc0RldmljZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZGlzcGxheSBtb2RlIG9mIHRoaXMgR3JhcGhpY3NEZXZpY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGlzcGxheU1vZGUoRGlzcGxheU1vZGUgZG0pIHsKKyAgICAgICAgaWYgKCFpc0Rpc3BsYXlDaGFuZ2VTdXBwb3J0ZWQoKSkgeworICAgICAgICAgICAgLy8gYXd0LjEyMj1Eb2VzIG5vdCBzdXBwb3J0IGRpc3BsYXkgbW9kZSBjaGFuZ2VzCisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTIyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBEaXNwbGF5TW9kZVtdIGRtcyA9IGdldERpc3BsYXlNb2RlcygpOworICAgICAgICBmb3IgKERpc3BsYXlNb2RlIGVsZW1lbnQgOiBkbXMpIHsKKyAgICAgICAgICAgIGlmIChlbGVtZW50LmVxdWFscyhkbSkpIHsKKyAgICAgICAgICAgICAgICBkaXNwbGF5TW9kZSA9IGRtOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBhd3QuMTIzPVVuc3VwcG9ydGVkIGRpc3BsYXkgbW9kZTogezB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTIzIiwgZG0pKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qCisgICAgICogPz8/QVdUIHB1YmxpYyB2b2lkIHNldEZ1bGxTY3JlZW5XaW5kb3coV2luZG93IHcpIHsgaWYgKHcgPT0gbnVsbCkgeworICAgICAqIGZ1bGxTY3JlZW5XaW5kb3cgPSBudWxsOyByZXR1cm47IH0gZnVsbFNjcmVlbldpbmRvdyA9IHc7IGlmCisgICAgICogKGlzRnVsbFNjcmVlblN1cHBvcnRlZCgpKSB7IHcuZW5hYmxlSW5wdXRNZXRob2RzKGZhbHNlKTsgfSBlbHNlIHsKKyAgICAgKiB3LnNldFNpemUoZGlzcGxheU1vZGUuZ2V0V2lkdGgoKSwgZGlzcGxheU1vZGUuZ2V0SGVpZ2h0KCkpOworICAgICAqIHcuc2V0TG9jYXRpb24oMCwgMCk7IH0gdy5zZXRWaXNpYmxlKHRydWUpOyB3LnNldEFsd2F5c09uVG9wKHRydWUpOyB9CisgICAgICovCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvR3JhcGhpY3NFbnZpcm9ubWVudC5qYXZhIGIvYXd0L2phdmEvYXd0L0dyYXBoaWNzRW52aXJvbm1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTI3NDE3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0dyYXBoaWNzRW52aXJvbm1lbnQuamF2YQpAQCAtMCwwICsxLDIxMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuQ29udGV4dFN0b3JhZ2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Db21tb25HcmFwaGljczJERmFjdG9yeTsKKworLyoqCisgKiBUaGUgR3JhcGhpY3NFbnZpcm9ubWVudCBjbGFzcyBkZWZpbmVzIGEgY29sbGVjdGlvbiBvZiBHcmFwaGljc0RldmljZSBvYmplY3RzCisgKiBhbmQgRm9udCBvYmplY3RzIHdoaWNoIGFyZSBhdmFpbGFibGUgZm9yIEphdmEgYXBwbGljYXRpb24gb24gY3VycmVudAorICogcGxhdGZvcm0uCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgR3JhcGhpY3NFbnZpcm9ubWVudCB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBjb3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseSBhbmQgc2hvdWxkIGJlIG9idGFpbmVkIGluIGV4dGVuZGVkCisgICAgICogY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgR3JhcGhpY3NFbnZpcm9ubWVudCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhbCBHcmFwaGljc0Vudmlyb25tZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIEdyYXBoaWNzRW52aXJvbm1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBHcmFwaGljc0Vudmlyb25tZW50IGdldExvY2FsR3JhcGhpY3NFbnZpcm9ubWVudCgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChDb250ZXh0U3RvcmFnZS5nZXRDb250ZXh0TG9jaygpKSB7CisgICAgICAgICAgICBpZiAoQ29udGV4dFN0b3JhZ2UuZ2V0R3JhcGhpY3NFbnZpcm9ubWVudCgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNIZWFkbGVzcygpKSB7CisgICAgICAgICAgICAgICAgICAgIENvbnRleHRTdG9yYWdlLnNldEdyYXBoaWNzRW52aXJvbm1lbnQobmV3IEhlYWRsZXNzR3JhcGhpY3NFbnZpcm9ubWVudCgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBDb21tb25HcmFwaGljczJERmFjdG9yeSBnMmRmID0gKENvbW1vbkdyYXBoaWNzMkRGYWN0b3J5KVRvb2xraXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RGVmYXVsdFRvb2xraXQoKS5nZXRHcmFwaGljc0ZhY3RvcnkoKTsKKworICAgICAgICAgICAgICAgICAgICBDb250ZXh0U3RvcmFnZS5zZXRHcmFwaGljc0Vudmlyb25tZW50KGcyZGYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3JlYXRlR3JhcGhpY3NFbnZpcm9ubWVudChDb250ZXh0U3RvcmFnZS5nZXRXaW5kb3dGYWN0b3J5KCkpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBDb250ZXh0U3RvcmFnZS5nZXRHcmFwaGljc0Vudmlyb25tZW50KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IGEgZGlzcGxheSwga2V5Ym9hcmQsIGFuZCBtb3VzZSBhcmUgc3VwcG9ydGVkIGluCisgICAgICogdGhpcyBncmFwaGljcyBlbnZpcm9ubWVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIEhlYWRsZXNzRXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGZyb20gYXJlYXMgb2YgdGhlCisgICAgICogICAgICAgICBncmFwaGljcyBlbnZpcm9ubWVudCB0aGF0IGFyZSBkZXBlbmRlbnQgb24gYSBkaXNwbGF5LCBrZXlib2FyZCwKKyAgICAgKiAgICAgICAgIG9yIG1vdXNlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNIZWFkbGVzc0luc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IGEgZGlzcGxheSwga2V5Ym9hcmQsIGFuZCBtb3VzZSBhcmUgc3VwcG9ydGVkIGluCisgICAgICogdGhpcyBlbnZpcm9ubWVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGEgSGVhZGxlc3NFeGNlcHRpb24gaXMgdGhyb3duIGZyb20gYXJlYXMgb2YgdGhlIFRvb2xraXQKKyAgICAgKiAgICAgICAgIGFuZCBHcmFwaGljc0Vudmlyb25tZW50IHRoYXQgYXJlIGRlcGVuZGVudCBvbiBhIGRpc3BsYXksCisgICAgICogICAgICAgICBrZXlib2FyZCwgb3IgbW91c2UsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNIZWFkbGVzcygpIHsKKyAgICAgICAgcmV0dXJuICJ0cnVlIi5lcXVhbHMoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmF3dC5oZWFkbGVzcyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIGJvdW5kcyBvZiBzeXN0ZW0gY2VudGVyZWQgd2luZG93cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGJvdW5kcyBvZiBzeXN0ZW0gY2VudGVyZWQgd2luZG93cy4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRNYXhpbXVtV2luZG93Qm91bmRzKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldERlZmF1bHRTY3JlZW5EZXZpY2UoKS5nZXREZWZhdWx0Q29uZmlndXJhdGlvbigpLmdldEJvdW5kcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFBvaW50IHdoaWNoIHNob3VsZCBkZWZpbmVzIHRoZSBjZW50ZXIgb2Ygc3lzdGVtIHdpbmRvdy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBQb2ludCB3aGVyZSB0aGUgc3lzdGVtIHdpbmRvdyBzaG91bGQgYmUgY2VudGVyZWQuCisgICAgICogQHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlzSGVhZGxlc3MoKSBtZXRob2QgcmV0dXJucyB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRDZW50ZXJQb2ludCgpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIFJlY3RhbmdsZSBtd2IgPSBnZXRNYXhpbXVtV2luZG93Qm91bmRzKCk7CisgICAgICAgIHJldHVybiBuZXcgUG9pbnQobXdiLndpZHRoID4+IDEsIG13Yi5oZWlnaHQgPj4gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHByaW1hcnkgZm9udCBzaG91bGQgYmUgdXNlZC4gUHJpbWFyeSBmb250IGlzIHNwZWNpZmllZAorICAgICAqIGJ5IGluaXRpYWwgc3lzdGVtIGxvY2FsZSBvciBkZWZhdWx0IGVuY29kaW5nKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmVmZXJMb2NhbGVGb250cygpIHsKKyAgICAgICAgLy8gTm90ZTogQVBJIHNwZWNpZmljYXRpb24gc2F5cyBmb2xsb3dpbmc6CisgICAgICAgIC8vICJUaGUgYWN0dWFsIGNoYW5nZSBpbiBmb250IHJlbmRlcmluZyBiZWhhdmlvciByZXN1bHRpbmcKKyAgICAgICAgLy8gZnJvbSBhIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50OworICAgICAgICAvLyBpdCBtYXkgaGF2ZSBubyBlZmZlY3QgYXQgYWxsLiIgU28sIGRvaW5nIG5vdGhpbmcgaXMgYW4KKyAgICAgICAgLy8gYWNjZXB0YWJsZSBiZWhhdmlvciBmb3IgdGhpcyBtZXRob2QuCisKKyAgICAgICAgLy8gRm9yIG5vdyBGb250TWFuYWdlciB1c2VzIDEuNCBmb250LnByb3BlcnRpZXMgc2NoZW1lIGZvciBmb250IG1hcHBpbmcsCisgICAgICAgIC8vIHNvCisgICAgICAgIC8vIHRoaXMgbWV0aG9kIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZAorICAgICAgICAvLyB3aGljaCB3aWxsIGluZmx1ZW5jZSBmb250IG1hcHBpbmcgaXMgcG9zdHBvbmVkIHVudGlsCisgICAgICAgIC8vIDEuNSBtYXBwaW5nIHNjaGVtZSBub3QgaW1wbGVtZW50ZWQuCisKKyAgICAgICAgLy8gdG9kbyAtIEltcGxlbWVudCBub24tZGVmYXVsdCBiZWhhdmlvciB3aXRoIDEuNSBmb250IG1hcHBpbmcgc2NoZW1lCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSBwcm9wb3J0aW9uYWwgcHJlZmVyZW5jZSBvZiB0aGUgZm9udCBzaG91bGQgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmVmZXJQcm9wb3J0aW9uYWxGb250cygpIHsKKyAgICAgICAgLy8gTm90ZTogQVBJIHNwZWNpZmljYXRpb24gc2F5cyBmb2xsb3dpbmc6CisgICAgICAgIC8vICJUaGUgYWN0dWFsIGNoYW5nZSBpbiBmb250IHJlbmRlcmluZyBiZWhhdmlvciByZXN1bHRpbmcKKyAgICAgICAgLy8gZnJvbSBhIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50OworICAgICAgICAvLyBpdCBtYXkgaGF2ZSBubyBlZmZlY3QgYXQgYWxsLiIgU28sIGRvaW5nIG5vdGhpbmcgaXMgYW4KKyAgICAgICAgLy8gYWNjZXB0YWJsZSBiZWhhdmlvciBmb3IgdGhpcyBtZXRob2QuCisKKyAgICAgICAgLy8gRm9yIG5vdyBGb250TWFuYWdlciB1c2VzIDEuNCBmb250LnByb3BlcnRpZXMgc2NoZW1lIGZvciBmb250IG1hcHBpbmcsCisgICAgICAgIC8vIHNvCisgICAgICAgIC8vIHRoaXMgbWV0aG9kIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZAorICAgICAgICAvLyB3aGljaCB3aWxsIGluZmx1ZW5jZSBmb250IG1hcHBpbmcgaXMgcG9zdHBvbmVkIHVudGlsCisgICAgICAgIC8vIDEuNSBtYXBwaW5nIHNjaGVtZSBub3QgaW1wbGVtZW50ZWQuCisKKyAgICAgICAgLy8gdG9kbyAtIEltcGxlbWVudCBub24tZGVmYXVsdCBiZWhhdmlvciB3aXRoIDEuNSBmb250IG1hcHBpbmcgc2NoZW1lCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgR3JhcGhpY3MyRCBvYmplY3QgZm9yIHJlbmRlcmluZyB0byB0aGUgc3BlY2lmaWVkCisgICAgICogQnVmZmVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYnVmZmVyZWRJbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNzMkQgb2JqZWN0IHdoaWNoIGFsbG93cyB0byByZW5kZXIgdG8gdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgQnVmZmVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR3JhcGhpY3MyRCBjcmVhdGVHcmFwaGljcyhCdWZmZXJlZEltYWdlIGJ1ZmZlcmVkSW1hZ2UpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXJyYXkgb2YgYWxsIGF2YWlsYWJsZSBmb250cyBpbnN0YW5jZXMgaW4gdGhpcworICAgICAqIEdyYXBoaWNzRW52aXJvbWVudHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgYWxsIGF2YWlsYWJsZSBmb250cyBpbnN0YW5jZXMgaW4gdGhpcworICAgICAqICAgICAgICAgR3JhcGhpY3NFbnZpcm9tZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRm9udFtdIGdldEFsbEZvbnRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBhbGwgYXZhaWxhYmxlIGZvbnQgZmFtaWx5IG5hbWVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIGFsbCBhdmFpbGFibGUgZm9udCBmYW1pbHkgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldEF2YWlsYWJsZUZvbnRGYW1pbHlOYW1lcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXJyYXkgb2YgYWxsIGF2YWlsYWJsZSBmb250IGZhbWlseSBuYW1lcyBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGxvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgTG9jYWxlIG9iamVjdCB3aGljaCByZXByZXNlbnRzIGdlb2dyYXBoaWNhbCByZWdpb24uIFRoZQorICAgICAqICAgICAgICAgICAgZGVmYXVsdCBsb2NhbGUgaXMgdXNlZCBpZiBsb2NhbGUgaXMgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBhdmFpbGFibGUgZm9udCBmYW1pbHkgbmFtZXMgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0QXZhaWxhYmxlRm9udEZhbWlseU5hbWVzKExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBzY3JlZW4gZGV2aWNlIGFzIEdyYXBoaWNEZXZpY2Ugb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNEZXZpY2Ugb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgZGVmYXVsdCBzY3JlZW4gZGV2aWNlLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpc0hlYWRsZXNzKCkgcmV0dXJucyB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljc0RldmljZSBnZXREZWZhdWx0U2NyZWVuRGV2aWNlKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBhbGwgYXZhaWxhYmxlIHNjcmVlbiBkZXZpY2VzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIEdyYXBoaWNzRGV2aWNlIG9iamVjdHMgd2hpY2ggcmVwcmVzZW50cyBhbGwKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZSBzY3JlZW4gZGV2aWNlcy4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaXNIZWFkbGVzcygpIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR3JhcGhpY3NEZXZpY2VbXSBnZXRTY3JlZW5EZXZpY2VzKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0hlYWRsZXNzRXhjZXB0aW9uLmphdmEgYi9hd3QvamF2YS9hd3QvSGVhZGxlc3NFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzExMWYxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0hlYWRsZXNzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCisvKioKKyAqIFRoZSBIZWFkbGVzc0V4Y2VwdGlvbiBjbGFzcyBwcm92aWRlcyBub3RpZmljYXRpb25zIGFuZCBlcnJvciBtZXNzYWdlcyB3aGVuCisgKiBjb2RlIHRoYXQgaXMgZGVwZW5kZW50IG9uIGEga2V5Ym9hcmQsIGRpc3BsYXksIG9yIG1vdXNlIGlzIGNhbGxlZCBpbiBhbgorICogZW52aXJvbm1lbnQgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IGEga2V5Ym9hcmQsIGRpc3BsYXksIG9yIG1vdXNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEhlYWRsZXNzRXhjZXB0aW9uIGV4dGVuZHMgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTY3MTgzNjQ0OTQ0MzU4NTYzTDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBoZWFkbGVzcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEhlYWRsZXNzRXhjZXB0aW9uKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBoZWFkbGVzcyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB3aGljaCByZXByZXNlbnRzIGVycm9yIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEhlYWRsZXNzRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvSGVhZGxlc3NHcmFwaGljc0Vudmlyb25tZW50LmphdmEgYi9hd3QvamF2YS9hd3QvSGVhZGxlc3NHcmFwaGljc0Vudmlyb25tZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzA2MzkzZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9IZWFkbGVzc0dyYXBoaWNzRW52aXJvbm1lbnQuamF2YQpAQCAtMCwwICsxLDcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3NEZXZpY2U7CitpbXBvcnQgamF2YS5hd3QuSGVhZGxlc3NFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkNvbW1vbkdyYXBoaWNzRW52aXJvbm1lbnQ7CisKKy8qKgorICogVGhlIEhlYWRsZXNzR3JhcGhpY3NFbnZpcm9ubWVudCBjbGFzcyBpcyB0aGUgQ29tbW9uR3JhcGhpY3NFbnZpcm9ubWVudAorICogaW1wbGVtZW50YXRpb24gdG8gdXNlIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBlbnZpcm9ubWVudCBsYWNrcyBkaXNwbGF5LAorICoga2V5Ym9hcmQsIGFuZCBtb3VzZSBzdXBwb3J0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEhlYWRsZXNzR3JhcGhpY3NFbnZpcm9ubWVudCBleHRlbmRzIENvbW1vbkdyYXBoaWNzRW52aXJvbm1lbnQgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCBhIGRpc3BsYXksIGtleWJvYXJkLCBhbmQgbW91c2UgYXJlIHN1cHBvcnRlZCBpbgorICAgICAqIHRoaXMgZ3JhcGhpY3MgZW52aXJvbm1lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBIZWFkbGVzc0V4Y2VwdGlvbiB3aWxsIGJlIHRocm93biBmcm9tIGFyZWFzIG9mIHRoZQorICAgICAqICAgICAgICAgZ3JhcGhpY3MgZW52aXJvbm1lbnQgdGhhdCBhcmUgZGVwZW5kZW50IG9uIGEgZGlzcGxheSwga2V5Ym9hcmQsCisgICAgICogICAgICAgICBvciBtb3VzZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzSGVhZGxlc3NJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBzY3JlZW4gZGV2aWNlIGFzIEdyYXBoaWNEZXZpY2Ugb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNEZXZpY2Ugb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgZGVmYXVsdCBzY3JlZW4gZGV2aWNlLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpc0hlYWRsZXNzKCkgcmV0dXJucyB0cnVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBHcmFwaGljc0RldmljZSBnZXREZWZhdWx0U2NyZWVuRGV2aWNlKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBhbGwgYXZhaWxhYmxlIHNjcmVlbiBkZXZpY2VzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIEdyYXBoaWNzRGV2aWNlIG9iamVjdHMgd2hpY2ggcmVwcmVzZW50cyBhbGwKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZSBzY3JlZW4gZGV2aWNlcy4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaXNIZWFkbGVzcygpIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3NEZXZpY2VbXSBnZXRTY3JlZW5EZXZpY2VzKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvSGVhZGxlc3NUb29sa2l0LmphdmEgYi9hd3QvamF2YS9hd3QvSGVhZGxlc3NUb29sa2l0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzY0YTg1YQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9IZWFkbGVzc1Rvb2xraXQuamF2YQpAQCAtMCwwICsxLDIyNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworLy8/Pz9BV1QKKy8vaW1wb3J0IGphdmEuYXd0LmRhdGF0cmFuc2Zlci5DbGlwYm9hcmQ7CisvL2ltcG9ydCBqYXZhLmF3dC5kbmQuRHJhZ0dlc3R1cmVFdmVudDsKKy8vaW1wb3J0IGphdmEuYXd0LmRuZC5EcmFnR2VzdHVyZUxpc3RlbmVyOworLy9pbXBvcnQgamF2YS5hd3QuZG5kLkRyYWdHZXN0dXJlUmVjb2duaXplcjsKKy8vaW1wb3J0IGphdmEuYXd0LmRuZC5EcmFnU291cmNlOworLy9pbXBvcnQgamF2YS5hd3QuZG5kLkludmFsaWREbkRPcGVyYXRpb25FeGNlcHRpb247CisvL2ltcG9ydCBqYXZhLmF3dC5kbmQucGVlci5EcmFnU291cmNlQ29udGV4dFBlZXI7CitpbXBvcnQgamF2YS5hd3QuaW0uSW5wdXRNZXRob2RIaWdobGlnaHQ7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbDsgLy9pbXBvcnQgamF2YS5hd3QucGVlci4qOworLy9pbXBvcnQgamF2YS5iZWFucy5Qcm9wZXJ0eUNoYW5nZVN1cHBvcnQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuQ29tcG9uZW50SW50ZXJuYWxzOyAvL2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmRhdGF0cmFuc2Zlci5EVEs7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuR3JhcGhpY3NGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUV2ZW50UXVldWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuV2luZG93RmFjdG9yeTsKKworLyoqCisgKiBUaGUgSGVhZGxlc3NUb29sa2l0IGNsYXNzIGlzIGEgc3ViY2xhc3Mgb2YgVG9vbGtpdEltcGwgdG8gYmUgdXNlZCBmb3IKKyAqIGdyYXBoaWNhbCBlbnZpcm9ubWVudHMgdGhhdCBsYWNrIGtleWJvYXJkIGFuZCBtb3VzZSBjYXBhYmlsaXRpZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSGVhZGxlc3NUb29sa2l0IGV4dGVuZHMgVG9vbGtpdEltcGwgeworCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIEJ1dHRvblBlZXIgY3JlYXRlQnV0dG9uKEJ1dHRvbiBhMCkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgQ2hlY2tib3hQZWVyIGNyZWF0ZUNoZWNrYm94KENoZWNrYm94IGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHByb3RlY3RlZCBDaGVja2JveE1lbnVJdGVtUGVlcgorICAgICAqIGNyZWF0ZUNoZWNrYm94TWVudUl0ZW0oQ2hlY2tib3hNZW51SXRlbSBhMCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgKiB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgQ2hvaWNlUGVlciBjcmVhdGVDaG9pY2UoQ2hvaWNlIGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9IHB1YmxpYyBDdXJzb3IKKyAgICAgKiBjcmVhdGVDdXN0b21DdXJzb3IoSW1hZ2UgaW1nLCBQb2ludCBob3RTcG90LCBTdHJpbmcgbmFtZSkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgRGlhbG9nUGVlciBjcmVhdGVEaWFsb2coRGlhbG9nIGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyA8VCBleHRlbmRzIERyYWdHZXN0dXJlUmVjb2duaXplcj4gVAorICAgICAqIGNyZWF0ZURyYWdHZXN0dXJlUmVjb2duaXplciggQ2xhc3M8VD4gcmVjb2duaXplckFic3RyYWN0Q2xhc3MsIERyYWdTb3VyY2UKKyAgICAgKiBkcywgQ29tcG9uZW50IGMsIGludCBzcmNBY3Rpb25zLCBEcmFnR2VzdHVyZUxpc3RlbmVyIGRnbCkgeyByZXR1cm4gbnVsbDsKKyAgICAgKiB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBEcmFnU291cmNlQ29udGV4dFBlZXIKKyAgICAgKiBjcmVhdGVEcmFnU291cmNlQ29udGV4dFBlZXIoRHJhZ0dlc3R1cmVFdmVudCBkZ2UpIHRocm93cworICAgICAqIEludmFsaWREbkRPcGVyYXRpb25FeGNlcHRpb24geyB0aHJvdyBuZXcgSW52YWxpZERuRE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAqIH0KKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIEZpbGVEaWFsb2dQZWVyIGNyZWF0ZUZpbGVEaWFsb2coRmlsZURpYWxvZyBhMCkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgRnJhbWVQZWVyIGNyZWF0ZUZyYW1lKEZyYW1lIGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHByb3RlY3RlZCBMYWJlbFBlZXIgY3JlYXRlTGFiZWwoTGFiZWwgYTApIHRocm93cworICAgICAqIEhlYWRsZXNzRXhjZXB0aW9uIHsgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIExpc3RQZWVyIGNyZWF0ZUxpc3QoTGlzdCBhMCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogeyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgTWVudVBlZXIgY3JlYXRlTWVudShNZW51IGEwKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHByb3RlY3RlZCBNZW51QmFyUGVlciBjcmVhdGVNZW51QmFyKE1lbnVCYXIgYTApIHRocm93cworICAgICAqIEhlYWRsZXNzRXhjZXB0aW9uIHsgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIE1lbnVJdGVtUGVlciBjcmVhdGVNZW51SXRlbShNZW51SXRlbSBhMCkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgUG9wdXBNZW51UGVlciBjcmVhdGVQb3B1cE1lbnUoUG9wdXBNZW51IGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHByb3RlY3RlZCBTY3JvbGxiYXJQZWVyIGNyZWF0ZVNjcm9sbGJhcihTY3JvbGxiYXIgYTApIHRocm93cworICAgICAqIEhlYWRsZXNzRXhjZXB0aW9uIHsgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIFNjcm9sbFBhbmVQZWVyIGNyZWF0ZVNjcm9sbFBhbmUoU2Nyb2xsUGFuZSBhMCkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwcm90ZWN0ZWQgVGV4dEFyZWFQZWVyIGNyZWF0ZVRleHRBcmVhKFRleHRBcmVhIGEwKSB0aHJvd3MKKyAgICAgKiBIZWFkbGVzc0V4Y2VwdGlvbiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHByb3RlY3RlZCBUZXh0RmllbGRQZWVyIGNyZWF0ZVRleHRGaWVsZChUZXh0RmllbGQgYTApIHRocm93cworICAgICAqIEhlYWRsZXNzRXhjZXB0aW9uIHsgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHJvdGVjdGVkIFdpbmRvd1BlZXIgY3JlYXRlV2luZG93KFdpbmRvdyBhMCkgdGhyb3dzCisgICAgICogSGVhZGxlc3NFeGNlcHRpb24geyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRCZXN0Q3Vyc29yU2l6ZShpbnQgcHJlZldpZHRoLCBpbnQgcHJlZkhlaWdodCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbG9yTW9kZWwgZ2V0Q29sb3JNb2RlbCgpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBHcmFwaGljc0ZhY3RvcnkgZ2V0R3JhcGhpY3NGYWN0b3J5KCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TG9ja2luZ0tleVN0YXRlKGludCBrZXlDb2RlKSB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE1heGltdW1DdXJzb3JDb2xvcnMoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE1lbnVTaG9ydGN1dEtleU1hc2soKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIEBPdmVycmlkZSBOYXRpdmVFdmVudFF1ZXVlIGdldE5hdGl2ZUV2ZW50UXVldWUoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiB7IHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOyB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBQcmludEpvYiBnZXRQcmludEpvYihGcmFtZSBmcmFtZSwgU3RyaW5nIGpvYnRpdGxlLAorICAgICAqIEpvYkF0dHJpYnV0ZXMgam9iQXR0cmlidXRlcywgUGFnZUF0dHJpYnV0ZXMgcGFnZUF0dHJpYnV0ZXMpIHRocm93cworICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7IHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgUHJpbnRKb2IgZ2V0UHJpbnRKb2IoRnJhbWUgZnJhbWUsIFN0cmluZyBqb2J0aXRsZSwKKyAgICAgKiBQcm9wZXJ0aWVzIHByb3BzKSB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24geyB0aHJvdyBuZXcKKyAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CisgICAgICovCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5zZXRzIGdldFNjcmVlbkluc2V0cyhHcmFwaGljc0NvbmZpZ3VyYXRpb24gZ2MpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2NyZWVuUmVzb2x1dGlvbigpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEaW1lbnNpb24gZ2V0U2NyZWVuU2l6ZSgpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBDbGlwYm9hcmQgZ2V0U3lzdGVtQ2xpcGJvYXJkKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogeyB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQ2xpcGJvYXJkIGdldFN5c3RlbVNlbGVjdGlvbigpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbgorICAgICAqIHsgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgV2luZG93RmFjdG9yeSBnZXRXaW5kb3dGYWN0b3J5KCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgKiB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsgfQorICAgICAqLworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29tcG9uZW50SW50ZXJuYWxzLnNldENvbXBvbmVudEludGVybmFscyhuZXcgQ29tcG9uZW50SW50ZXJuYWxzSW1wbCgpKTsKKyAgICAgICAgICAgIC8vID8/P0FXVDogbmV3IEV2ZW50UXVldWUodGhpcyk7IC8vIGNyZWF0ZSB0aGUgc3lzdGVtIEV2ZW50UXVldWUKKyAgICAgICAgICAgIC8vID8/P0FXVDogZGlzcGF0Y2hlciA9IG5ldyBEaXNwYXRjaGVyKHRoaXMpOworICAgICAgICAgICAgZGVza3RvcFByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgICAgIC8vID8/P0FXVDogZGVza3RvcFByb3BzU3VwcG9ydCA9IG5ldyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQodGhpcyk7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IGF3dEV2ZW50c01hbmFnZXIgPSBuZXcgQVdURXZlbnRzTWFuYWdlcigpOworICAgICAgICAgICAgLy8gPz8/QVdUOiBkaXNwYXRjaFRocmVhZCA9IG5ldyBIZWFkbGVzc0V2ZW50RGlzcGF0Y2hUaHJlYWQodGhpcywKKyAgICAgICAgICAgIC8vIGRpc3BhdGNoZXIpOworICAgICAgICAgICAgLy8gPz8/QVdUOiBkdGsgPSBEVEsuZ2V0RFRLKCk7CisgICAgICAgICAgICBkaXNwYXRjaFRocmVhZC5zdGFydCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0R5bmFtaWNMYXlvdXRBY3RpdmUoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0R5bmFtaWNMYXlvdXRTZXQoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyYW1lU3RhdGVTdXBwb3J0ZWQoaW50IHN0YXRlKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBsb2FkU3lzdGVtQ29sb3JzKGludFtdIHN5c3RlbUNvbG9ycykgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxqYXZhLmF3dC5mb250LlRleHRBdHRyaWJ1dGUsID8+IG1hcElucHV0TWV0aG9kSGlnaGxpZ2h0KAorICAgICAgICAgICAgSW5wdXRNZXRob2RIaWdobGlnaHQgaGlnaGxpZ2h0KSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSGVhZGxlc3NFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBNYXA8amF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlLCA/PiBtYXBJbnB1dE1ldGhvZEhpZ2hsaWdodEltcGwoSW5wdXRNZXRob2RIaWdobGlnaHQgaGlnaGxpZ2h0KQorICAgICAgICAgICAgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RHluYW1pY0xheW91dChib29sZWFuIGR5bmFtaWMpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldExvY2tpbmdLZXlTdGF0ZShpbnQga2V5Q29kZSwgYm9vbGVhbiBvbikgdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEhlYWRsZXNzRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0lsbGVnYWxDb21wb25lbnRTdGF0ZUV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYXd0L0lsbGVnYWxDb21wb25lbnRTdGF0ZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlZDE3MjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvSWxsZWdhbENvbXBvbmVudFN0YXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCisvKioKKyAqIFRoZSBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24gY2xhc3MgaXMgdXNlZCB0byBwcm92aWRlIG5vdGlmaWNhdGlvbiB0aGF0CisgKiBBV1QgY29tcG9uZW50IGlzIG5vdCBpbiBhbiBhcHByb3ByaWF0ZSBzdGF0ZSBmb3IgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24uCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbENvbXBvbmVudFN0YXRlRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODg5MzM5NTg3MjA4MTQ0MjM4TDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyBtZXNzYWdlIHdoaWNoIGRlc2NyaWJlcyB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsQ29tcG9uZW50U3RhdGVFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICAgICAgc3VwZXIocyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElsbGVnYWxDb21wb25lbnRTdGF0ZUV4Y2VwdGlvbiB3aXRob3V0IGRldGFpbGVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbENvbXBvbmVudFN0YXRlRXhjZXB0aW9uKCkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0ltYWdlLmphdmEgYi9hd3QvamF2YS9hd3QvSW1hZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YWUzZWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0ltYWdlLmphdmEKQEAgLTAsMCArMSwyMDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQXJlYUF2ZXJhZ2luZ1NjYWxlRmlsdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkZpbHRlcmVkSW1hZ2VTb3VyY2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VGaWx0ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlcGxpY2F0ZVNjYWxlRmlsdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIEltYWdlIGFic3RyYWN0IGNsYXNzIHJlcHJlc2VudHMgdGhlIGdyYXBoaWMgaW1hZ2VzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBVbmRlZmluZWRQcm9wZXJ0eSBvYmplY3Qgc2hvdWxkIGJlIHJldHVybmVkIGlmIHByb3BlcnR5IGlzIG5vdAorICAgICAqIGRlZmluZWQgZm9yIGEgcGFydGljdWxhciBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBVbmRlZmluZWRQcm9wZXJ0eSA9IG5ldyBPYmplY3QoKTsgLy8gJE5PTi1MT0NLLTEkCisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NBTEVfREVGQVVMVCBpbmRpY2F0ZXMgdGhlIGRlZmF1bHQgaW1hZ2Ugc2NhbGluZyBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0NBTEVfREVGQVVMVCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NBTEVfRkFTVCBpbmRpY2F0ZXMgYW4gaW1hZ2Ugc2NhbGluZyBhbGdvcml0aG0gd2hpY2ggcGxhY2VzCisgICAgICogYSBoaWdoZXIgcHJpb3JpdHkgb24gc2NhbGluZyBzcGVlZCB0aGFuIG9uIHRoZSBpbWFnZSdzIHNtb290aG5lc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0NBTEVfRkFTVCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NBTEVfU01PT1RIIGluZGljYXRlcyBhbiBpbWFnZSBzY2FsaW5nIGFsZ29yaXRobSB3aGljaAorICAgICAqIHBsYWNlcyBhIGhpZ2hlciBwcmlvcml0eSBvbiBpbWFnZSBzbW9vdGhuZXNzIHRoYW4gb24gc2NhbGluZyBzcGVlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTQ0FMRV9TTU9PVEggPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNDQUxFX1JFUExJQ0FURSBpbmRpY2F0ZXMgdGhlIGltYWdlIHNjYWxpbmcgYWxnb3JpdGhtIGluIHRoZQorICAgICAqIFJlcGxpY2F0ZVNjYWxlRmlsdGVyIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDQUxFX1JFUExJQ0FURSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0NBTEVfQVJFQV9BVkVSQUdJTkcgaW5kaWNhdGVzIHRoZSBhcmVhIGF2ZXJhZ2luZyBpbWFnZQorICAgICAqIHNjYWxpbmcgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDQUxFX0FSRUFfQVZFUkFHSU5HID0gMTY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWNjZWxlcmF0aW9uIHByaW9yaXR5IGluZGljYXRlcyBpbWFnZSBhY2NlbGVyYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZsb2F0IGFjY2VsZXJhdGlvblByaW9yaXR5ID0gMC41ZjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBjYXBhYmlsaXRpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW1hZ2VDYXBhYmlsaXRpZXMgY2FwYWJpbGl0aWVzID0gbmV3IEltYWdlQ2FwYWJpbGl0aWVzKGZhbHNlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGltYWdlIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiBUaGUgVW5kZWZpbmVkUHJvcGVydHkKKyAgICAgKiBvYmplY3Qgc2hvdWxkIGJlIHJldHVybiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCBmb3IgdGhpcyBpbWFnZS4KKyAgICAgKiBUaGUgcmV0dXJuIHZhbHVlIHNob3VsZCBiZSBudWxsIGlmIHRoZSBwcm9wZXJ0eSBpcyBjdXJyZW50bHkgdW5rbm93biB5ZXQKKyAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBJbWFnZU9ic2VydmVyIGlzIHRvIGJlIG5vdGlmaWVkIGxhdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBpbWFnZSdzIHByb3BlcnR5LgorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIuCisgICAgICogQHJldHVybiB0aGUgT2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lLCBJbWFnZU9ic2VydmVyIG9ic2VydmVyKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEltYWdlUHJvZHVjZXIgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgZGF0YSBvZiB0aGlzIEltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEltYWdlUHJvZHVjZXIgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgZGF0YSBvZiB0aGlzIEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbWFnZVByb2R1Y2VyIGdldFNvdXJjZSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2lkdGggb2YgdGhpcyBpbWFnZS4gVGhlIHNwZWNpZmllZCBJbWFnZU9ic2VydmVyIG9iamVjdCBpcworICAgICAqIG5vdGlmaWVkIHdoZW4gdGhlIHdpZHRoIG9mIHRoaXMgaW1hZ2UgaXMgYXZhaWxhYmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHdoaWNoIGlzIGlzIG5vdGlmaWVkIHdoZW4gdGhlIHdpZHRoCisgICAgICogICAgICAgICAgICBvZiB0aGlzIGltYWdlIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aCBvZiBpbWFnZSwgb3IgLTEgaWYgdGhlIHdpZHRoIG9mIHRoaXMgaW1hZ2UgaXMgbm90CisgICAgICogICAgICAgICBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRXaWR0aChJbWFnZU9ic2VydmVyIG9ic2VydmVyKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGhlaWdodCBvZiB0aGlzIGltYWdlLiBUaGUgc3BlY2lmaWVkIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IGlzCisgICAgICogbm90aWZpZWQgd2hlbiB0aGUgaGVpZ2h0IG9mIHRoaXMgaW1hZ2UgaXMgYXZhaWxhYmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYnNlcnZlcgorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHdoaWNoIGlzIGlzIG5vdGlmaWVkIHdoZW4gdGhlIGhlaWdodAorICAgICAqICAgICAgICAgICAgb2YgdGhpcyBpbWFnZSBpcyBhdmFpbGFibGUuCisgICAgICogQHJldHVybiB0aGUgaGVpZ2h0IG9mIGltYWdlLCBvciAtMSBpZiB0aGUgaGVpZ2h0IG9mIHRoaXMgaW1hZ2UgaXMgbm90CisgICAgICogICAgICAgICBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRIZWlnaHQoSW1hZ2VPYnNlcnZlciBvYnNlcnZlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzY2FsZWQgaW5zdGFuY2Ugb2YgdGhpcyBJbWFnZS4gVGhpcyBtZXRob2QgcmV0dXJucyBhbiBJbWFnZQorICAgICAqIG9iamVjdCBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBzb3VyY2Ugb2YgdGhpcyBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB3aWR0aCwgaGVpZ2h0LCBhbmQgYXBwbGllZCBzY2FsaW5nIGFsZ29yaXRobS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBzY2FsZWQgSW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBzY2FsZWQgSW1hZ2UuCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgY29uc3RhbnQgd2hpY2ggaW5kaWNhdGVzIHNjYWxpbmcgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIHNjYWxlZCBJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2UgZ2V0U2NhbGVkSW5zdGFuY2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgaGludHMpIHsKKyAgICAgICAgSW1hZ2VGaWx0ZXIgZmlsdGVyOworICAgICAgICBpZiAoKGhpbnRzICYgKFNDQUxFX1NNT09USCB8IFNDQUxFX0FSRUFfQVZFUkFHSU5HKSkgIT0gMCkgeworICAgICAgICAgICAgZmlsdGVyID0gbmV3IEFyZWFBdmVyYWdpbmdTY2FsZUZpbHRlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbHRlciA9IG5ldyBSZXBsaWNhdGVTY2FsZUZpbHRlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgfQorICAgICAgICBJbWFnZVByb2R1Y2VyIHByb2R1Y2VyID0gbmV3IEZpbHRlcmVkSW1hZ2VTb3VyY2UoZ2V0U291cmNlKCksIGZpbHRlcik7CisgICAgICAgIHJldHVybiBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCkuY3JlYXRlSW1hZ2UocHJvZHVjZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBHcmFwaGljcyBvYmplY3QgZm9yIHJlbmRlcmluZyB0aGlzIGltYWdlLiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZAorICAgICAqIGZvciBvZmYtc2NyZWVuIGltYWdlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgR3JhcGhpY3Mgb2JqZWN0IGZvciByZW5kZXJpbmcgdG8gdGhpcyBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR3JhcGhpY3MgZ2V0R3JhcGhpY3MoKTsKKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgcmVzb3VyY2VzIHdoaWNoIGFyZSB1c2VkIGJ5IHRoaXMgSW1hZ2Ugb2JqZWN0LiBUaGlzIG1ldGhvZCByZXNldHMKKyAgICAgKiB0aGUgaW1hZ2UgdG8gdGhlIHJlY29uc3RydWN0ZWQgc3RhdGUgZnJvbSB0aGUgaW1hZ2UncyBzb3VyY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZmx1c2goKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFjY2VsZXJhdGlvbiBwcmlvcml0eSBvZiB0aGlzIGltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFjY2VsZXJhdGlvbiBwcmlvcml0eSBvZiB0aGlzIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRBY2NlbGVyYXRpb25Qcmlvcml0eSgpIHsKKyAgICAgICAgcmV0dXJuIGFjY2VsZXJhdGlvblByaW9yaXR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFjY2VsZXJhdGlvbiBwcmlvcml0eSBmb3IgdGhpcyBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJpb3JpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYWNjZWxlcmF0aW9uIHByaW9yaXR5ICh2YWx1ZSBpbiB0aGUgcmFuZ2UgMC0xKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBY2NlbGVyYXRpb25Qcmlvcml0eShmbG9hdCBwcmlvcml0eSkgeworICAgICAgICBpZiAocHJpb3JpdHkgPCAwIHx8IHByaW9yaXR5ID4gMSkgeworICAgICAgICAgICAgLy8gYXd0LjEwQT1Qcmlvcml0eSBtdXN0IGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxLCBpbmNsdXNpdmUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTBBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgYWNjZWxlcmF0aW9uUHJpb3JpdHkgPSBwcmlvcml0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIEltYWdlQ2FwYWJpbGl0aWVzIG9iamVjdCBvZiB0aGlzIEltYWdlIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgR3JhcGhpY3NDb25maWd1cmF0aW9uIG9iamVjdCAobnVsbCB2YWx1ZSBtZWFucworICAgICAqICAgICAgICAgICAgZGVmYXVsdCBHcmFwaGljc0NvbmZpZ3VyYXRpb24pLgorICAgICAqIEByZXR1cm4gYW4gSW1hZ2VDYXBhYmlsaXRpZXMgb2JqZWN0IG9mIHRoaXMgSW1hZ2Ugb2JqZWN0IGZvciB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIEltYWdlQ2FwYWJpbGl0aWVzIGdldENhcGFiaWxpdGllcyhHcmFwaGljc0NvbmZpZ3VyYXRpb24gZ2MpIHsKKyAgICAgICAgLy8gTm90ZTogY29tbW9uIGltYWdlIGlzIG5vdCBhY2NlbGVyYXRlZC4KKyAgICAgICAgcmV0dXJuIGNhcGFiaWxpdGllczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvSW1hZ2VDYXBhYmlsaXRpZXMuamF2YSBiL2F3dC9qYXZhL2F3dC9JbWFnZUNhcGFiaWxpdGllcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ZDU5NDYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvSW1hZ2VDYXBhYmlsaXRpZXMuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8qKgorICogVGhlIEltYWdlQ2FwYWJpbGl0aWVzIGNsYXNzIGdpdmVzIGluZm9ybWF0aW9uIGFib3V0IGFuIGltYWdlJ3MgY2FwYWJpbGl0aWVzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEltYWdlQ2FwYWJpbGl0aWVzIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBhY2NlbGVyYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYWNjZWxlcmF0ZWQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VDYXBhYmlsaXRpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIGFjY2VsZXJhdGlvbiBmbGFnCisgICAgICogd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgYWNjZWxlcmF0aW9uIGlzIGRlc2lyZWQgb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhY2NlbGVyYXRlZAorICAgICAqICAgICAgICAgICAgdGhlIGFjY2VsZXJhdGVkIGZsYWcuCisgICAgICovCisgICAgcHVibGljIEltYWdlQ2FwYWJpbGl0aWVzKGJvb2xlYW4gYWNjZWxlcmF0ZWQpIHsKKyAgICAgICAgdGhpcy5hY2NlbGVyYXRlZCA9IGFjY2VsZXJhdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMgSW1hZ2VDYXBhYmlsaXRpZXMgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNvcHkgb2YgdGhpcyBJbWFnZUNhcGFiaWxpdGllcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJbWFnZUNhcGFiaWxpdGllcyhhY2NlbGVyYXRlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBJbWFnZSBvZiB0aGlzIEltYWdlQ2FwYWJpbGl0aWVzIGlzIG9yIGNhbiBiZQorICAgICAqIGFjY2VsZXJhdGVkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIEltYWdlIG9mIHRoaXMgSW1hZ2VDYXBhYmlsaXRpZXMgaXMgb3IgY2FuIGJlCisgICAgICogICAgICAgICBhY2NlbGVyYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQWNjZWxlcmF0ZWQoKSB7CisgICAgICAgIHJldHVybiBhY2NlbGVyYXRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBJbWFnZUNhcGFiaWxpdGllcyBhcHBsaWVzIHRvIHRoZSBWb2xhdGlsZUltYWdlIHdoaWNoCisgICAgICogY2FuIGxvc2UgaXRzIHN1cmZhY2VzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIEltYWdlQ2FwYWJpbGl0aWVzIGFwcGxpZXMgdG8gdGhlIFZvbGF0aWxlSW1hZ2Ugd2hpY2gKKyAgICAgKiAgICAgICAgIGNhbiBsb3NlIGl0cyBzdXJmYWNlcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVHJ1ZVZvbGF0aWxlKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvSW5zZXRzLmphdmEgYi9hd3QvamF2YS9hd3QvSW5zZXRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRmMTk4YwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9JbnNldHMuamF2YQpAQCAtMCwwICsxLDE3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lm1pc2MuSGFzaENvZGU7CisKKy8qKgorICogVGhlIEluc2V0cyBjbGFzcyByZXByZXNlbnRzIHRoZSBib3JkZXJzIG9mIGEgY29udGFpbmVyLiBUaGlzIGNsYXNzIGRlc2NyaWJlcworICogdGhlIHNwYWNlIHRoYXQgYSBjb250YWluZXIgc2hvdWxkIGxlYXZlIGF0IGVhY2ggZWRnZTogdGhlIHRvcCwgdGhlIGJvdHRvbSwKKyAqIHRoZSByaWdodCBzaWRlLCBhbmQgdGhlIGxlZnQgc2lkZS4gVGhlIHNwYWNlIGNhbiBiZSBmaWxsZWQgd2l0aCBhIGJvcmRlciwgYQorICogYmxhbmsgc3BhY2UsIG9yIGEgdGl0bGUuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSW5zZXRzIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTIyNzI1NzI2Mzc2OTU0NjY3NDlMOworCisgICAgLyoqCisgICAgICogVGhlIHRvcCBpbnNldCBpbmRpY2F0ZXMgdGhlIHNpemUgb2YgdGhlIHNwYWNlIGFkZGVkIHRvIHRoZSB0b3Agb2YgdGhlCisgICAgICogcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgdG9wOworCisgICAgLyoqCisgICAgICogVGhlIGxlZnQgaW5zZXQgaW5kaWNhdGVzIHRoZSBzaXplIG9mIHRoZSBzcGFjZSBhZGRlZCB0byB0aGUgbGVmdCBzaWRlIG9mCisgICAgICogdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxlZnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYm90dG9tIGluc2V0IGluZGljYXRlcyB0aGUgc2l6ZSBvZiB0aGUgc3BhY2Ugc3VidHJhY3RlZCBmcm9tIHRoZQorICAgICAqIGJvdHRvbSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgYm90dG9tOworCisgICAgLyoqCisgICAgICogVGhlIHJpZ2h0IGluc2V0IGluZGljYXRlcyB0aGUgc2l6ZSBvZiB0aGUgc3BhY2Ugc3VidHJhY3RlZCBmcm9tIHRoZSByaWdodAorICAgICAqIHNpZGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJpZ2h0OworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEluc2V0IG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgdG9wLCBsZWZ0LCBib3R0b20sCisgICAgICogcmlnaHQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdG9wCisgICAgICogICAgICAgICAgICB0aGUgdG9wIGluc2V0LgorICAgICAqIEBwYXJhbSBsZWZ0CisgICAgICogICAgICAgICAgICB0aGUgbGVmdCBpbnNldC4KKyAgICAgKiBAcGFyYW0gYm90dG9tCisgICAgICogICAgICAgICAgICB0aGUgYm90dG9tIGluc2V0LgorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHJpZ2h0IGluc2V0LgorICAgICAqLworICAgIHB1YmxpYyBJbnNldHMoaW50IHRvcCwgaW50IGxlZnQsIGludCBib3R0b20sIGludCByaWdodCkgeworICAgICAgICBzZXRWYWx1ZXModG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIG9mIHRoZSBJbnNldHMgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBoYXNoIGNvZGUgb2YgdGhlIEluc2V0cyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gSGFzaENvZGUuRU1QVFlfSEFTSF9DT0RFOworICAgICAgICBoYXNoQ29kZSA9IEhhc2hDb2RlLmNvbWJpbmUoaGFzaENvZGUsIHRvcCk7CisgICAgICAgIGhhc2hDb2RlID0gSGFzaENvZGUuY29tYmluZShoYXNoQ29kZSwgbGVmdCk7CisgICAgICAgIGhhc2hDb2RlID0gSGFzaENvZGUuY29tYmluZShoYXNoQ29kZSwgYm90dG9tKTsKKyAgICAgICAgaGFzaENvZGUgPSBIYXNoQ29kZS5jb21iaW5lKGhhc2hDb2RlLCByaWdodCk7CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGlzIEluc2V0cyBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhpcyBJbnNldHMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHJldHVybiBuZXcgSW5zZXRzKHRvcCwgbGVmdCwgYm90dG9tLCByaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgSW5zZXRzIG9iamVjdCBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBvYmplY3QgaXMgYW4gSW5zZXRzIG9iamVjdCB3aG9zZSBkYXRhIHZhbHVlcyBhcmUKKyAgICAgKiAgICAgICAgIGVxdWFsIHRvIHRob3NlIG9mIHRoaXMgb2JqZWN0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvIGluc3RhbmNlb2YgSW5zZXRzKSB7CisgICAgICAgICAgICBJbnNldHMgaSA9IChJbnNldHMpbzsKKyAgICAgICAgICAgIHJldHVybiAoKGkubGVmdCA9PSBsZWZ0KSAmJiAoaS5ib3R0b20gPT0gYm90dG9tKSAmJiAoaS5yaWdodCA9PSByaWdodCkgJiYgKGkudG9wID09IHRvcCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgSW5zZXRzIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgSW5zZXRzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgZm9ybWF0IGlzIGJhc2VkIG9uIDEuNSByZWxlYXNlIGJlaGF2aW9yIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieQorICAgICAgICAgKiB0aGUgZm9sbG93aW5nIGNvZGU6IFN5c3RlbS5vdXQucHJpbnRsbihuZXcgSW5zZXRzKDEsIDIsIDMsIDQpKTsKKyAgICAgICAgICovCisKKyAgICAgICAgcmV0dXJuIChnZXRDbGFzcygpLmdldE5hbWUoKSArICJbbGVmdD0iICsgbGVmdCArICIsdG9wPSIgKyB0b3AgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAiLHJpZ2h0PSIgKyByaWdodCArICIsYm90dG9tPSIgKyBib3R0b20gKyAiXSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdG9wLCBsZWZ0LCBib3R0b20sIGFuZCByaWdodCBpbnNldHMgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHRvcAorICAgICAqICAgICAgICAgICAgdGhlIHRvcCBpbnNldC4KKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqICAgICAgICAgICAgdGhlIGxlZnQgaW5zZXQuCisgICAgICogQHBhcmFtIGJvdHRvbQorICAgICAqICAgICAgICAgICAgdGhlIGJvdHRvbSBpbnNldC4KKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSByaWdodCBpbnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoaW50IHRvcCwgaW50IGxlZnQsIGludCBib3R0b20sIGludCByaWdodCkgeworICAgICAgICBzZXRWYWx1ZXModG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHRvcAorICAgICAqICAgICAgICAgICAgdGhlIHRvcC4KKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqICAgICAgICAgICAgdGhlIGxlZnQuCisgICAgICogQHBhcmFtIGJvdHRvbQorICAgICAqICAgICAgICAgICAgdGhlIGJvdHRvbS4KKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSByaWdodC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0VmFsdWVzKGludCB0b3AsIGludCBsZWZ0LCBpbnQgYm90dG9tLCBpbnQgcmlnaHQpIHsKKyAgICAgICAgdGhpcy50b3AgPSB0b3A7CisgICAgICAgIHRoaXMubGVmdCA9IGxlZnQ7CisgICAgICAgIHRoaXMuYm90dG9tID0gYm90dG9tOworICAgICAgICB0aGlzLnJpZ2h0ID0gcmlnaHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L0l0ZW1TZWxlY3RhYmxlLmphdmEgYi9hd3QvamF2YS9hd3QvSXRlbVNlbGVjdGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTJjZjcwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L0l0ZW1TZWxlY3RhYmxlLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSXRlbUxpc3RlbmVyOworCisvKioKKyAqIFRoZSBJdGVtU2VsZWN0YWJsZSBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHNldCBvZiBpdGVtcyB3aGljaCBjYW4gYmUgc2VsZWN0ZWQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEl0ZW1TZWxlY3RhYmxlIHsKKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gSXRlbUxpc3RlbmVyIGZvciByZWNlaXZpbmcgaXRlbSBldmVudHMgd2hlbiB0aGUgc3RhdGUgb2YgYW4gaXRlbQorICAgICAqIGlzIGNoYW5nZWQgYnkgdGhlIHVzZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBJdGVtTGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkSXRlbUxpc3RlbmVyKEl0ZW1MaXN0ZW5lciBsKTsKKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgdGhlIHNlbGVjdGVkIG9iamVjdHMgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBzZWxlY3RlZAorICAgICAqIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBzZWxlY3RlZCBvYmplY3RzIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gc2VsZWN0ZWQKKyAgICAgKiAgICAgICAgIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gZ2V0U2VsZWN0ZWRPYmplY3RzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgSXRlbUxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgSXRlbUxpc3RlbmVyIHdoaWNoIHdpbGwgYmUgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJdGVtTGlzdGVuZXIoSXRlbUxpc3RlbmVyIGwpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvTWVudUNvbXBvbmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L01lbnVDb21wb25lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzFiMTIwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L01lbnVDb21wb25lbnQuamF2YQpAQCAtMCwwICsxLDc4MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LmV2ZW50LkZvY3VzTGlzdGVuZXI7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuTW91c2VFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5wZWVyLk1lbnVDb21wb25lbnRQZWVyOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7IC8vaW1wb3J0IGphdmF4LmFjY2Vzc2liaWxpdHkuQWNjZXNzaWJsZTsKKy8vaW1wb3J0IGphdmF4LmFjY2Vzc2liaWxpdHkuQWNjZXNzaWJsZUNvbXBvbmVudDsKKy8vaW1wb3J0IGphdmF4LmFjY2Vzc2liaWxpdHkuQWNjZXNzaWJsZUNvbnRleHQ7CisvL2ltcG9ydCBqYXZheC5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2libGVSb2xlOworLy9pbXBvcnQgamF2YXguYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlU2VsZWN0aW9uOworLy9pbXBvcnQgamF2YXguYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlU3RhdGVTZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Quc3RhdGUuTWVudUl0ZW1TdGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LnN0YXRlLk1lbnVTdGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBNZW51Q29tcG9uZW50IGFic3RyYWN0IGNsYXNzIGlzIHRoZSBzdXBlcmNsYXNzIGZvciBtZW51IGNvbXBvbmVudHMuIE1lbnUKKyAqIGNvbXBvbmVudHMgcmVjZWl2ZSBhbmQgcHJvY2VzcyBBV1QgZXZlbnRzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lbnVDb21wb25lbnQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ1MzY5MDIzNTYyMjM4OTQzNzlMOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb250LgorICAgICAqLworICAgIHByaXZhdGUgRm9udCBmb250OworCisgICAgLyoqCisgICAgICogVGhlIHBhcmVudC4KKyAgICAgKi8KKyAgICBNZW51Q29udGFpbmVyIHBhcmVudDsKKworICAgIC8qKgorICAgICAqIFRoZSBkZXByZWNhdGVkIGV2ZW50IGhhbmRsZXIuCisgICAgICovCisgICAgYm9vbGVhbiBkZXByZWNhdGVkRXZlbnRIYW5kbGVyID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBzZWxlY3RlZCBpdGVtIGluZGV4LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNlbGVjdGVkSXRlbUluZGV4OworCisgICAgLy8gPz8/QVdUOiBwcml2YXRlIEFjY2Vzc2libGVDb250ZXh0IGFjY2Vzc2libGVDb250ZXh0OworCisgICAgLyoqCisgICAgICogVGhlIHRvb2xraXQuCisgICAgICovCisgICAgZmluYWwgVG9vbGtpdCB0b29sa2l0ID0gVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpOworCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBwcm90ZWN0ZWQgYWJzdHJhY3QgY2xhc3MgQWNjZXNzaWJsZUFXVE1lbnVDb21wb25lbnQgZXh0ZW5kcworICAgICAqIEFjY2Vzc2libGVDb250ZXh0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBBY2Nlc3NpYmxlQ29tcG9uZW50LAorICAgICAqIEFjY2Vzc2libGVTZWxlY3Rpb24geyBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPQorICAgICAqIC00MjY5NTMzNDE2MjIzNzk4Njk4TDsgcHVibGljIHZvaWQgYWRkRm9jdXNMaXN0ZW5lcihGb2N1c0xpc3RlbmVyCisgICAgICogbGlzdGVuZXIpIHsgfSBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludCBwdCkgeyByZXR1cm4gZmFsc2U7IH0gcHVibGljCisgICAgICogQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlQXQoUG9pbnQgcHQpIHsgcmV0dXJuIG51bGw7IH0gcHVibGljIENvbG9yCisgICAgICogZ2V0QmFja2dyb3VuZCgpIHsgcmV0dXJuIG51bGw7IH0gcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKSB7IHJldHVybgorICAgICAqIG51bGw7IH0gcHVibGljIEN1cnNvciBnZXRDdXJzb3IoKSB7IHJldHVybiBudWxsOyB9IHB1YmxpYyBGb250IGdldEZvbnQoKQorICAgICAqIHsgcmV0dXJuIE1lbnVDb21wb25lbnQudGhpcy5nZXRGb250KCk7IH0gcHVibGljIEZvbnRNZXRyaWNzCisgICAgICogZ2V0Rm9udE1ldHJpY3MoRm9udCBmb250KSB7IHJldHVybiBudWxsOyB9IHB1YmxpYyBDb2xvciBnZXRGb3JlZ3JvdW5kKCkgeworICAgICAqIHJldHVybiBudWxsOyB9IHB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbigpIHsgcmV0dXJuIG51bGw7IH0gcHVibGljIFBvaW50CisgICAgICogZ2V0TG9jYXRpb25PblNjcmVlbigpIHsgcmV0dXJuIG51bGw7IH0gcHVibGljIERpbWVuc2lvbiBnZXRTaXplKCkgeworICAgICAqIHJldHVybiBudWxsOyB9IHB1YmxpYyBib29sZWFuIGlzRW5hYmxlZCgpIHsgcmV0dXJuIHRydWU7IC8vIGFsd2F5cworICAgICAqIGVuYWJsZWQgfSBwdWJsaWMgYm9vbGVhbiBpc0ZvY3VzVHJhdmVyc2FibGUoKSB7IHJldHVybiB0cnVlOyAvLyBhbHdheXMKKyAgICAgKiBmb2N1cyB0cmF2ZXJzYWJsZSB9IHB1YmxpYyBib29sZWFuIGlzU2hvd2luZygpIHsgcmV0dXJuIHRydWU7Ly8gYWx3YXlzCisgICAgICogc2hvd2luZyB9IHB1YmxpYyBib29sZWFuIGlzVmlzaWJsZSgpIHsgcmV0dXJuIHRydWU7IC8vIGFsd2F5cyB2aXNpYmxlIH0KKyAgICAgKiBwdWJsaWMgdm9pZCByZW1vdmVGb2N1c0xpc3RlbmVyKEZvY3VzTGlzdGVuZXIgbGlzdGVuZXIpIHsgfSBwdWJsaWMgdm9pZAorICAgICAqIHJlcXVlc3RGb2N1cygpIHsgfSBwdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kKENvbG9yIGNvbG9yKSB7IH0gcHVibGljIHZvaWQKKyAgICAgKiBzZXRCb3VuZHMoUmVjdGFuZ2xlIHJlY3QpIHsgfSBwdWJsaWMgdm9pZCBzZXRDdXJzb3IoQ3Vyc29yIGN1cnNvcikgeyB9CisgICAgICogcHVibGljIHZvaWQgc2V0RW5hYmxlZChib29sZWFuIGVuYWJsZWQpIHsgfSBwdWJsaWMgdm9pZCBzZXRGb250KEZvbnQKKyAgICAgKiBmb250KSB7IE1lbnVDb21wb25lbnQudGhpcy5zZXRGb250KGZvbnQpOyB9IHB1YmxpYyB2b2lkCisgICAgICogc2V0Rm9yZWdyb3VuZChDb2xvciBjb2xvcikgeyB9IHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKFBvaW50IHB0KSB7IH0KKyAgICAgKiBwdWJsaWMgdm9pZCBzZXRTaXplKERpbWVuc2lvbiBwdCkgeyB9IHB1YmxpYyB2b2lkIHNldFZpc2libGUoYm9vbGVhbgorICAgICAqIHZpc2libGUpIHsgfSBwdWJsaWMgdm9pZCBhZGRBY2Nlc3NpYmxlU2VsZWN0aW9uKGludCBpbmRleCkgeyB9IHB1YmxpYworICAgICAqIHZvaWQgY2xlYXJBY2Nlc3NpYmxlU2VsZWN0aW9uKCkgeyB9IHB1YmxpYyBBY2Nlc3NpYmxlCisgICAgICogZ2V0QWNjZXNzaWJsZVNlbGVjdGlvbihpbnQgaW5kZXgpIHsgcmV0dXJuIG51bGw7IH0gcHVibGljIGludAorICAgICAqIGdldEFjY2Vzc2libGVTZWxlY3Rpb25Db3VudCgpIHsgcmV0dXJuIDA7IH0gcHVibGljIGJvb2xlYW4KKyAgICAgKiBpc0FjY2Vzc2libGVDaGlsZFNlbGVjdGVkKGludCBpbmRleCkgeyByZXR1cm4gZmFsc2U7IH0gcHVibGljIHZvaWQKKyAgICAgKiByZW1vdmVBY2Nlc3NpYmxlU2VsZWN0aW9uKGludCBpbmRleCkgeyB9IHB1YmxpYyB2b2lkCisgICAgICogc2VsZWN0QWxsQWNjZXNzaWJsZVNlbGVjdGlvbigpIHsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlQ2hpbGQoaW50IGluZGV4KSB7IHJldHVybiBudWxsOworICAgICAqIH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIGludCBnZXRBY2Nlc3NpYmxlQ2hpbGRyZW5Db3VudCgpIHsgcmV0dXJuIDA7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIEFjY2Vzc2libGVDb21wb25lbnQgZ2V0QWNjZXNzaWJsZUNvbXBvbmVudCgpIHsgcmV0dXJuCisgICAgICogdGhpczsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldEFjY2Vzc2libGVEZXNjcmlwdGlvbigpIHsgcmV0dXJuCisgICAgICogc3VwZXIuZ2V0QWNjZXNzaWJsZURlc2NyaXB0aW9uKCk7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIGludCBnZXRBY2Nlc3NpYmxlSW5kZXhJblBhcmVudCgpIHsgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICogdHJ5IHsgQWNjZXNzaWJsZSBhUGFyZW50ID0gZ2V0QWNjZXNzaWJsZVBhcmVudCgpOyBpbnQgYUluZGV4ID0gLTE7IGlmCisgICAgICogKGFQYXJlbnQgaW5zdGFuY2VvZiBNZW51Q29tcG9uZW50KSB7IE1lbnVDb21wb25lbnQgcGFyZW50ID0KKyAgICAgKiAoTWVudUNvbXBvbmVudCkgYVBhcmVudDsgaW50IGNvdW50ID0gcGFyZW50LmdldEl0ZW1Db3VudCgpOyBmb3IgKGludCBpID0KKyAgICAgKiAwOyBpIDwgY291bnQ7IGkrKykgeyBNZW51Q29tcG9uZW50IGNvbXAgPSBwYXJlbnQuZ2V0SXRlbShpKTsgaWYgKGNvbXAKKyAgICAgKiBpbnN0YW5jZW9mIEFjY2Vzc2libGUpIHsgYUluZGV4Kys7IGlmIChjb21wID09IE1lbnVDb21wb25lbnQudGhpcykgeworICAgICAqIHJldHVybiBhSW5kZXg7IH0gfSB9IH0gcmV0dXJuIC0xOyB9IGZpbmFsbHkgeyB0b29sa2l0LnVubG9ja0FXVCgpOyB9IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY2Nlc3NpYmxlTmFtZSgpIHsgcmV0dXJuCisgICAgICogc3VwZXIuZ2V0QWNjZXNzaWJsZU5hbWUoKTsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlUGFyZW50KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgKiB0cnkgeyBBY2Nlc3NpYmxlIGFQYXJlbnQgPSBzdXBlci5nZXRBY2Nlc3NpYmxlUGFyZW50KCk7IGlmIChhUGFyZW50ICE9CisgICAgICogbnVsbCkgeyByZXR1cm4gYVBhcmVudDsgfSBNZW51Q29udGFpbmVyIHBhcmVudCA9IGdldFBhcmVudCgpOyBpZiAocGFyZW50CisgICAgICogaW5zdGFuY2VvZiBBY2Nlc3NpYmxlKSB7IGFQYXJlbnQgPSAoQWNjZXNzaWJsZSkgcGFyZW50OyB9IHJldHVybiBhUGFyZW50OworICAgICAqIH0gZmluYWxseSB7IHRvb2xraXQudW5sb2NrQVdUKCk7IH0gfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZVJvbGUgZ2V0QWNjZXNzaWJsZVJvbGUoKSB7IHJldHVybgorICAgICAqIEFjY2Vzc2libGVSb2xlLkFXVF9DT01QT05FTlQ7IH0KKyAgICAgKiBAT3ZlcnJpZGUgcHVibGljIEFjY2Vzc2libGVTZWxlY3Rpb24gZ2V0QWNjZXNzaWJsZVNlbGVjdGlvbigpIHsgcmV0dXJuCisgICAgICogdGhpczsgfQorICAgICAqIEBPdmVycmlkZSBwdWJsaWMgQWNjZXNzaWJsZVN0YXRlU2V0IGdldEFjY2Vzc2libGVTdGF0ZVNldCgpIHsgcmV0dXJuIG5ldworICAgICAqIEFjY2Vzc2libGVTdGF0ZVNldCgpOyB9CisgICAgICogQE92ZXJyaWRlIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgeyByZXR1cm4gTG9jYWxlLmdldERlZmF1bHQoKTsgfSB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBUaGUgYWNjZXNzb3IgdG8gTWVudUNvbXBvbmVudCBpbnRlcm5hbCBzdGF0ZSwgdXRpbGl6ZWQgYnkgdGhlIHZpc3VhbAorICAgICAqIHRoZW1lLgorICAgICAqIAorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgaGVhZGxlc3MgZXhjZXB0aW9uLgorICAgICAqLworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogY2xhc3MgU3RhdGUgaW1wbGVtZW50cyBNZW51U3RhdGUgeyBEaW1lbnNpb24gc2l6ZTsgRGltZW5zaW9uIGdldFNpemUoKSB7CisgICAgICogaWYgKHNpemUgPT0gbnVsbCkgeyBjYWxjdWxhdGUoKTsgfSByZXR1cm4gc2l6ZTsgfSBwdWJsaWMgaW50IGdldFdpZHRoKCkgeworICAgICAqIHJldHVybiBnZXRTaXplKCkud2lkdGg7IH0gcHVibGljIGludCBnZXRIZWlnaHQoKSB7IHJldHVybgorICAgICAqIGdldFNpemUoKS5oZWlnaHQ7IH0gcHVibGljIEZvbnQgZ2V0Rm9udCgpIHsgcmV0dXJuCisgICAgICogTWVudUNvbXBvbmVudC50aGlzLmdldEZvbnQoKTsgfSBwdWJsaWMgaW50IGdldEl0ZW1Db3VudCgpIHsgcmV0dXJuCisgICAgICogTWVudUNvbXBvbmVudC50aGlzLmdldEl0ZW1Db3VudCgpOyB9IHB1YmxpYyBpbnQgZ2V0U2VsZWN0ZWRJdGVtSW5kZXgoKSB7CisgICAgICogcmV0dXJuIE1lbnVDb21wb25lbnQudGhpcy5nZXRTZWxlY3RlZEl0ZW1JbmRleCgpOyB9IHB1YmxpYyBib29sZWFuCisgICAgICogaXNGb250U2V0KCkgeyByZXR1cm4gTWVudUNvbXBvbmVudC50aGlzLmlzRm9udFNldCgpOyB9CisgICAgICogQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQKKyAgICAgKiBmKSB7IHJldHVybiBNZW51Q29tcG9uZW50LnRoaXMudG9vbGtpdC5nZXRGb250TWV0cmljcyhmKTsgfSBwdWJsaWMgUG9pbnQKKyAgICAgKiBnZXRMb2NhdGlvbigpIHsgcmV0dXJuIE1lbnVDb21wb25lbnQudGhpcy5nZXRMb2NhdGlvbigpOyB9IHB1YmxpYworICAgICAqIE1lbnVJdGVtU3RhdGUgZ2V0SXRlbShpbnQgaW5kZXgpIHsgTWVudUl0ZW0gaXRlbSA9CisgICAgICogTWVudUNvbXBvbmVudC50aGlzLmdldEl0ZW0oaW5kZXgpOyByZXR1cm4gaXRlbS5pdGVtU3RhdGU7IH0gcHVibGljIHZvaWQKKyAgICAgKiBzZXRTaXplKGludCB3LCBpbnQgaCkgeyB0aGlzLnNpemUgPSBuZXcgRGltZW5zaW9uKHcsIGgpOyB9IHZvaWQKKyAgICAgKiBjYWxjdWxhdGUoKSB7IHNpemUgPSBuZXcgRGltZW5zaW9uKCk7CisgICAgICogc2l6ZS5zZXRTaXplKHRvb2xraXQudGhlbWUuY2FsY3VsYXRlTWVudVNpemUodGhpcykpOyB9IHZvaWQgcmVzZXQoKSB7IGZvcgorICAgICAqIChpbnQgaSA9IDA7IGkgPCBnZXRJdGVtQ291bnQoKTsgaSsrKSB7ICgoTWVudUl0ZW0uU3RhdGUpCisgICAgICogZ2V0SXRlbShpKSkucmVzZXQoKTsgfSB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFBvcC11cCBib3ggZm9yIG1lbnUuIEl0IHRyYW5zZmVycyB0aGUgcGFpbnQgZXZlbnRzLCBrZXlib2FyZCBhbmQgbW91c2UKKyAgICAgKiBldmVudHMgdG8gdGhlIG1lbnUgY29tcG9uZW50IGl0c2VsZi4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIGNsYXNzIE1lbnVQb3B1cEJveCBleHRlbmRzIFBvcHVwQm94IHsgcHJpdmF0ZSBmaW5hbCBQb2ludCBsYXN0TW91c2VQb3MgPQorICAgICAqIG5ldyBQb2ludCgpOworICAgICAqIEBPdmVycmlkZSBib29sZWFuIGlzTWVudSgpIHsgcmV0dXJuIHRydWU7IH0KKyAgICAgKiBAT3ZlcnJpZGUgdm9pZCBwYWludChHcmFwaGljcyBncikgeyBNZW51Q29tcG9uZW50LnRoaXMucGFpbnQoZ3IpOyB9CisgICAgICogQE92ZXJyaWRlIHZvaWQgb25LZXlFdmVudChpbnQgZXZlbnRJZCwgaW50IHZLZXksIGxvbmcgd2hlbiwgaW50CisgICAgICogbW9kaWZpZXJzKSB7IE1lbnVDb21wb25lbnQudGhpcy5vbktleUV2ZW50KGV2ZW50SWQsIHZLZXksIHdoZW4sCisgICAgICogbW9kaWZpZXJzKTsgfQorICAgICAqIEBPdmVycmlkZSB2b2lkIG9uTW91c2VFdmVudChpbnQgZXZlbnRJZCwgUG9pbnQgd2hlcmUsIGludCBtb3VzZUJ1dHRvbiwKKyAgICAgKiBsb25nIHdoZW4sIGludCBtb2RpZmllcnMsIGludCB3aGVlbFJvdGF0aW9uKSB7IC8vIHByZXZlbnQgY29uZmxpY3Qgb2YKKyAgICAgKiBtb3VzZSBhbmQga2V5Ym9hcmQgLy8gd2hlbiBzdWItbWVudSBkcm9wcyBkb3duIGR1ZSB0byBrZXlib2FyZCBuYXZpZ2F0aW9uCisgICAgICogaWYgKGxhc3RNb3VzZVBvcy5lcXVhbHMod2hlcmUpICYmIChldmVudElkID09IE1vdXNlRXZlbnQuTU9VU0VfTU9WRUQgfHwKKyAgICAgKiBldmVudElkID09IE1vdXNlRXZlbnQuTU9VU0VfRU5URVJFRCkpIHsgcmV0dXJuOyB9CisgICAgICogbGFzdE1vdXNlUG9zLnNldExvY2F0aW9uKHdoZXJlKTsgTWVudUNvbXBvbmVudC50aGlzLm9uTW91c2VFdmVudChldmVudElkLAorICAgICAqIHdoZXJlLCBtb3VzZUJ1dHRvbiwgd2hlbiwgbW9kaWZpZXJzKTsgfSB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTWVudUNvbXBvbmVudCBvYmplY3QuCisgICAgICogCisgICAgICogQHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBncmFwaGljYWwgaW50ZXJmYWNlIGVudmlyb25tZW50IGNhbid0IHN1cHBvcnQKKyAgICAgKiAgICAgICAgICAgICBNZW51Q29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVudUNvbXBvbmVudCgpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVG9vbGtpdC5jaGVja0hlYWRsZXNzKCk7CisgICAgICAgICAgICBuYW1lID0gYXV0b05hbWUoKTsKKyAgICAgICAgICAgIHNlbGVjdGVkSXRlbUluZGV4ID0gLTE7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgTWVudUNvbXBvbmVudCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgTWVudUNvbXBvbmVudCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE1lbnVDb21wb25lbnQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE1lbnVDb21wb25lbnQgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlsiICsgcGFyYW1TdHJpbmcoKSArICJdIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0b29sa2l0LnVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGFyZW50IG1lbnUgY29udGFpbmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHBhcmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVudUNvbnRhaW5lciBnZXRQYXJlbnQoKSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHBhcmVudDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBNZW51Q29tcG9uZW50IHRvIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG5hbWUgb2YgdGhlIE1lbnVDb21wb25lbnQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERpc3BhdGNoZXMgQVdUIGV2ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgdGhlIEFXVEV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcm9jZXNzRXZlbnQoZXZlbnQpOworICAgICAgICAgICAgaWYgKGRlcHJlY2F0ZWRFdmVudEhhbmRsZXIpIHsKKyAgICAgICAgICAgICAgICBwb3N0RGVwcmVjYXRlZEV2ZW50KGV2ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3N0IGRlcHJlY2F0ZWQgZXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQuCisgICAgICovCisgICAgdm9pZCBwb3N0RGVwcmVjYXRlZEV2ZW50KEFXVEV2ZW50IGV2ZW50KSB7CisgICAgICAgIEV2ZW50IGV2dCA9IGV2ZW50LmdldEV2ZW50KCk7CisgICAgICAgIGlmIChldnQgIT0gbnVsbCkgeworICAgICAgICAgICAgcG9zdEV2ZW50KGV2dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwZWVyIG9mIHRoZSBNZW51Q29tcG9uZW50OyBhbiBhcHBsaWNhdGlvbiBtdXN0IG5vdCB1c2UgdGhpcworICAgICAqIG1ldGhvZCBkaXJlY3RseS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBNZW51Q29tcG9uZW50UGVlciBvYmplY3QuCisgICAgICogQHRocm93cyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBieSBhIHN1YmNsYXNzLgorICAgICAqIEBkZXByZWNhdGVkIGFuIGFwcGxpY2F0aW9uIG11c3Qgbm90IHVzZSB0aGlzIG1ldGhvZCBkaXJlY3RseS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBNZW51Q29tcG9uZW50UGVlciBnZXRQZWVyKCkgdGhyb3dzIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNZXRob2QgaXMgbm90IGltcGxlbWVudGVkIik7IC8vVE9ETzogaW1wbGVtZW50IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NraW5nIG9iamVjdCBvZiB0aGlzIE1lbnVDb21wb25lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9ja2luZyBvYmplY3Qgb2YgdGhpcyBNZW51Q29tcG9uZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBPYmplY3QgZ2V0VHJlZUxvY2soKSB7CisgICAgICAgIHJldHVybiB0b29sa2l0LmF3dFRyZWVMb2NrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvc3RzIHRoZSBFdmVudCB0byB0aGUgTWVudUNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIEV2ZW50LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGV2ZW50IGlzIHBvc3RlZCBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBkaXNwYXRjaEV2ZW50IG1ldGhvZC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gcG9zdEV2ZW50KEV2ZW50IGUpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LnBvc3RFdmVudChlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE1lbnVDb21wb25lbnQgc3RhdGUuCisgICAgICogCisgICAgICogQHJldHVybiByZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE1lbnVDb21wb25lbnQgc3RhdGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgdG9vbGtpdC5sb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHVibGljIEFjY2Vzc2libGVDb250ZXh0IGdldEFjY2Vzc2libGVDb250ZXh0KCkgeyB0b29sa2l0LmxvY2tBV1QoKTsgdHJ5CisgICAgICogeyBpZiAoYWNjZXNzaWJsZUNvbnRleHQgPT0gbnVsbCkgeyBhY2Nlc3NpYmxlQ29udGV4dCA9CisgICAgICogY3JlYXRlQWNjZXNzaWJsZUNvbnRleHQoKTsgfSByZXR1cm4gYWNjZXNzaWJsZUNvbnRleHQ7IH0gZmluYWxseSB7CisgICAgICogdG9vbGtpdC51bmxvY2tBV1QoKTsgfSB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmb250IG9mIHRoZSBNZW51Q29tcG9uZW50IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBGb250IG9mIHRoZSBNZW51Q29tcG9uZW50IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9udCBnZXRGb250KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChmb250ID09IG51bGwgJiYgaGFzRGVmYXVsdEZvbnQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0b29sa2l0LmdldERlZmF1bHRGb250KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZm9udCA9PSBudWxsICYmIHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5nZXRGb250KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZm9udDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgaXMgZm9udCBzZXQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBmb250IHNldAorICAgICAqLworICAgIGJvb2xlYW4gaXNGb250U2V0KCkgeworICAgICAgICByZXR1cm4gZm9udCAhPSBudWxsCisgICAgICAgICAgICAgICAgfHwgKChwYXJlbnQgaW5zdGFuY2VvZiBNZW51Q29tcG9uZW50KSAmJiAoKE1lbnVDb21wb25lbnQpcGFyZW50KS5pc0ZvbnRTZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGZvciBkZWZhdWx0IGZvbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIGJvb2xlYW4gaGFzRGVmYXVsdEZvbnQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYW4gQVdURWV2ZW50IG9uIHRoaXMgbWVudSBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICB0aGUgQVdURXZlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0V2ZW50KEFXVEV2ZW50IGV2ZW50KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdG9vbGtpdC51bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHBlZXIgb2YgdGhlIE1lbnVDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlTm90aWZ5KCkgeworICAgICAgICB0b29sa2l0LmxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBGb250IGZvciB0aGlzIE1lbnVDb21wb25lbnQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250CisgICAgICogICAgICAgICAgICB0aGUgbmV3IEZvbnQgdG8gYmUgdXNlZCBmb3IgdGhpcyBNZW51Q29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbnQoRm9udCBmb250KSB7CisgICAgICAgIHRvb2xraXQubG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhpcy5mb250ID0gZm9udDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRvb2xraXQudW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwYXJlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHBhcmVudAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwYXJlbnQuCisgICAgICovCisgICAgdm9pZCBzZXRQYXJlbnQoTWVudUNvbnRhaW5lciBwYXJlbnQpIHsKKyAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYXRpb24uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9jYXRpb24uCisgICAgICovCisgICAgUG9pbnQgZ2V0TG9jYXRpb24oKSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4KKyAgICAgICAgcmV0dXJuIG5ldyBQb2ludCgwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBpbnQgZ2V0V2lkdGgoKSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4KKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhlaWdodC4KKyAgICAgKi8KKyAgICBpbnQgZ2V0SGVpZ2h0KCkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY3Vyc2l2ZWx5IGZpbmQgdGhlIG1lbnUgaXRlbSBmb3IgYSBtZW51IHNob3J0Y3V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBncgorICAgICAqICAgICAgICAgICAgdGhlIGdyLgorICAgICAqIEByZXR1cm4gdGhlIG1lbnUgaXRlbTsgb3IgbnVsbCBpZiB0aGUgaXRlbSBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGlzCisgICAgICogICAgICAgICBzaG9ydGN1dC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIE1lbnVJdGVtIGdldFNob3J0Y3V0TWVudUl0ZW1JbXBsKE1lbnVTaG9ydGN1dCBtcykgeyBpZiAobXMgPT0gbnVsbCkgeworICAgICAqIHJldHVybiBudWxsOyB9IGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0SXRlbUNvdW50KCk7IGkrKykgeyBNZW51SXRlbSBtaSA9CisgICAgICogZ2V0SXRlbShpKTsgaWYgKG1pIGluc3RhbmNlb2YgTWVudSkgeyBtaSA9ICgoTWVudSkKKyAgICAgKiBtaSkuZ2V0U2hvcnRjdXRNZW51SXRlbUltcGwobXMpOyBpZiAobWkgIT0gbnVsbCkgeyByZXR1cm4gbWk7IH0gfSBlbHNlIGlmCisgICAgICogKG1zLmVxdWFscyhtaS5nZXRTaG9ydGN1dCgpKSkgeyByZXR1cm4gbWk7IH0gfSByZXR1cm4gbnVsbDsgfQorICAgICAqLworCisgICAgdm9pZCBwYWludChHcmFwaGljcyBncikgeworICAgICAgICBnci5zZXRDb2xvcihDb2xvci5MSUdIVF9HUkFZKTsKKyAgICAgICAgZ3IuZmlsbFJlY3QoMCwgMCwgZ2V0V2lkdGgoKSwgZ2V0SGVpZ2h0KCkpOworICAgICAgICBnci5zZXRDb2xvcihDb2xvci5CTEFDSyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW91c2UgZXZlbnRzIGhhbmRsZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50SWQKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgTW91c2VFdmVudC5NT1VTRV8qIGNvbnN0YW50cy4KKyAgICAgKiBAcGFyYW0gd2hlcmUKKyAgICAgKiAgICAgICAgICAgIG1vdXNlIGxvY2F0aW9uLgorICAgICAqIEBwYXJhbSBtb3VzZUJ1dHRvbgorICAgICAqICAgICAgICAgICAgbW91c2UgYnV0dG9uIHRoYXQgd2FzIHByZXNzZWQgb3IgcmVsZWFzZWQuCisgICAgICogQHBhcmFtIHdoZW4KKyAgICAgKiAgICAgICAgICAgIGV2ZW50IHRpbWUuCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgaW5wdXQgZXZlbnQgbW9kaWZpZXJzLgorICAgICAqLworICAgIHZvaWQgb25Nb3VzZUV2ZW50KGludCBldmVudElkLCBQb2ludCB3aGVyZSwgaW50IG1vdXNlQnV0dG9uLCBsb25nIHdoZW4sIGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbgorICAgIH0KKworICAgIC8qKgorICAgICAqIEtleWJvYXJkIGV2ZW50IGhhbmRsZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGV2ZW50SWQKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgS2V5RXZlbnQuS0VZXyogY29uc3RhbnRzLgorICAgICAqIEBwYXJhbSB2S2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IGNvZGUuCisgICAgICogQHBhcmFtIHdoZW4KKyAgICAgKiAgICAgICAgICAgIGV2ZW50IHRpbWUuCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgaW5wdXQgZXZlbnQgbW9kaWZpZXJzLgorICAgICAqLworICAgIHZvaWQgb25LZXlFdmVudChpbnQgZXZlbnRJZCwgaW50IHZLZXksIGxvbmcgd2hlbiwgaW50IG1vZGlmaWVycykgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgfQorCisgICAgLyoqCisgICAgICogUG9zdCB0aGUgQWN0aW9uRXZlbnQgb3IgSXRlbUV2ZW50LCBkZXBlbmRpbmcgb24gdHlwZSBvZiB0aGUgbWVudSBpdGVtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGl0ZW0gcmVjdC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHZvaWQgZmlyZUl0ZW1BY3Rpb24oaW50IGl0ZW0sIGxvbmcgd2hlbiwgaW50IG1vZGlmaWVycykgeyBNZW51SXRlbSBtaSA9CisgICAgICogZ2V0SXRlbShpdGVtKTsgbWkuaXRlbVNlbGVjdGVkKHdoZW4sIG1vZGlmaWVycyk7IH0gTWVudUl0ZW0gZ2V0SXRlbShpbnQKKyAgICAgKiBpbmRleCkgeyAvLyB0byBiZSBvdmVycmlkZGVuIHJldHVybiBudWxsOyB9IGludCBnZXRJdGVtQ291bnQoKSB7IHJldHVybgorICAgICAqIDA7IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gVGhlIHN1Yi1tZW51IG9mIGN1cnJlbnRseSBzZWxlY2V0ZCBpdGVtLCBvciBudWxsIGlmIHN1Y2ggYQorICAgICAqICAgICAgICAgc3ViLW1lbnUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIE1lbnUgZ2V0U2VsZWN0ZWRTdWJtZW51KCkgeyBpZiAoc2VsZWN0ZWRJdGVtSW5kZXggPCAwKSB7IHJldHVybiBudWxsOyB9CisgICAgICogTWVudUl0ZW0gaXRlbSA9IGdldEl0ZW0oc2VsZWN0ZWRJdGVtSW5kZXgpOyByZXR1cm4gKGl0ZW0gaW5zdGFuY2VvZiBNZW51KQorICAgICAqID8gKE1lbnUpIGl0ZW0gOiBudWxsOyB9CisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIHNlbGVjdEl0ZW0oaW5kZXgsIHRydWUpLgorICAgICAqLworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogdm9pZCBzZWxlY3RJdGVtKGludCBpbmRleCkgeyBzZWxlY3RJdGVtKGluZGV4LCB0cnVlKTsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogQ2hhbmdlIHRoZSBzZWxlY3Rpb24gaW4gdGhlIG1lbnUuCisgICAgICogCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICBuZXcgc2VsZWNldGQgaXRlbSdzIGluZGV4LgorICAgICAqIEBwYXJhbSBzaG93U3ViTWVudQorICAgICAqICAgICAgICAgICAgaWYgbmV3IHNlbGVjdGVkIGl0ZW0gaGFzIGEgc3ViLW1lbnUsIHNob3VsZCB0aGF0IHN1Yi1tZW51IGJlCisgICAgICogICAgICAgICAgICBkaXNwbGF5ZWQuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiB2b2lkIHNlbGVjdEl0ZW0oaW50IGluZGV4LCBib29sZWFuIHNob3dTdWJNZW51KSB7IGlmIChzZWxlY3RlZEl0ZW1JbmRleAorICAgICAqID09IGluZGV4KSB7IHJldHVybjsgfSBpZiAoc2VsZWN0ZWRJdGVtSW5kZXggPj0gMCAmJgorICAgICAqIGdldEl0ZW0oc2VsZWN0ZWRJdGVtSW5kZXgpIGluc3RhbmNlb2YgTWVudSkgeyAoKE1lbnUpCisgICAgICogZ2V0SXRlbShzZWxlY3RlZEl0ZW1JbmRleCkpLmhpZGUoKTsgfSBNdWx0aVJlY3RBcmVhIGNsaXAgPQorICAgICAqIGdldFVwZGF0ZUNsaXAoaW5kZXgsIHNlbGVjdGVkSXRlbUluZGV4KTsgc2VsZWN0ZWRJdGVtSW5kZXggPSBpbmRleDsKKyAgICAgKiBHcmFwaGljcyBnciA9IGdldEdyYXBoaWNzKGNsaXApOyBpZiAoZ3IgIT0gbnVsbCkgeyBwYWludChncik7IH0gaWYKKyAgICAgKiAoc2hvd1N1Yk1lbnUpIHsgc2hvd1N1Yk1lbnUoc2VsZWN0ZWRJdGVtSW5kZXgpOyB9IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIENoYW5nZSB0aGUgc2VsZWN0ZWQgaXRlbSB0byB0aGUgbmV4dCBvbmUgaW4gdGhlIHJlcXVlc3RlZCBkaXJlY3Rpb24KKyAgICAgKiBtb3ZpbmcgY3ljbGljYWxseSwgc2tpcHBpbmcgc2VwYXJhdG9ycworICAgICAqIAorICAgICAqIEBwYXJhbSBmb3J3YXJkCisgICAgICogICAgICAgICAgICB0aGUgZGlyZWN0aW9uIHRvIG1vdmUgdGhlIHNlbGVjdGlvbi4KKyAgICAgKiBAcGFyYW0gc2hvd1N1Yk1lbnUKKyAgICAgKiAgICAgICAgICAgIGlmIG5ldyBzZWxlY3RlZCBpdGVtIGhhcyBhIHN1Yi1tZW51LCBzaG91bGQgdGhhdCBzdWItbWVudSBiZQorICAgICAqICAgICAgICAgICAgZGlzcGxheWVkLgorICAgICAqLworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogdm9pZCBzZWxlY3ROZXh0SXRlbShib29sZWFuIGZvcndhcmQsIGJvb2xlYW4gc2hvd1N1Yk1lbnUpIHsgaW50IHNlbGVjdGVkCisgICAgICogPSBnZXRTZWxlY3RlZEl0ZW1JbmRleCgpOyBpbnQgY291bnQgPSBnZXRJdGVtQ291bnQoKTsgaWYgKGNvdW50ID09IDApIHsKKyAgICAgKiByZXR1cm47IH0gaWYgKHNlbGVjdGVkIDwgMCkgeyBzZWxlY3RlZCA9IChmb3J3YXJkID8gY291bnQgLSAxIDogMCk7IH0gaW50CisgICAgICogaSA9IHNlbGVjdGVkOyBkbyB7IGkgPSAoZm9yd2FyZCA/IChpICsgMSkgOiAoaSArIGNvdW50IC0gMSkpICUgY291bnQ7IGkKKyAgICAgKiAlPSBjb3VudDsgTWVudUl0ZW0gaXRlbSA9IGdldEl0ZW0oaSk7IGlmICghIi0iLmVxdWFscyhpdGVtLmdldExhYmVsKCkpKSB7CisgICAgICogLy8kTk9OLU5MUy0xJCBzZWxlY3RJdGVtKGksIHNob3dTdWJNZW51KTsgcmV0dXJuOyB9IH0gd2hpbGUgKGkgIT0KKyAgICAgKiBzZWxlY3RlZCk7IH0gdm9pZCBzaG93U3ViTWVudShpbnQgaW5kZXgpIHsgaWYgKChpbmRleCA8IDApIHx8CisgICAgICogIWlzQWN0aXZlKCkpIHsgcmV0dXJuOyB9IE1lbnVJdGVtIGl0ZW0gPSBnZXRJdGVtKGluZGV4KTsgaWYgKGl0ZW0KKyAgICAgKiBpbnN0YW5jZW9mIE1lbnUpIHsgTWVudSBtZW51ID0gKChNZW51KSBnZXRJdGVtKGluZGV4KSk7IGlmCisgICAgICogKG1lbnUuZ2V0SXRlbUNvdW50KCkgPT0gMCkgeyByZXR1cm47IH0gUG9pbnQgbG9jYXRpb24gPQorICAgICAqIGdldFN1Ym1lbnVMb2NhdGlvbihpbmRleCk7IG1lbnUuc2hvdyhsb2NhdGlvbi54LCBsb2NhdGlvbi55LCBmYWxzZSk7IH0gfQorICAgICAqLworCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgbWVudSBiYXIgd2hpY2ggaXMgdGhlIHJvb3Qgb2YgY3VycmVudCBtZW51J3MgaGllcmFyY2h5OyBvcgorICAgICAqICAgICAgICAgbnVsbCBpZiB0aGUgaGllcmFyY2h5IHJvb3QgaXMgbm90IGEgbWVudSBiYXIuCisgICAgICovCisgICAgLy8gPz8/QVdUCisgICAgLyoKKyAgICAgKiBNZW51QmFyIGdldE1lbnVCYXIoKSB7IGlmIChwYXJlbnQgaW5zdGFuY2VvZiBNZW51QmFyKSB7IHJldHVybiAoTWVudUJhcikKKyAgICAgKiBwYXJlbnQ7IH0gaWYgKHBhcmVudCBpbnN0YW5jZW9mIE1lbnVDb21wb25lbnQpIHsgcmV0dXJuICgoTWVudUNvbXBvbmVudCkKKyAgICAgKiBwYXJlbnQpLmdldE1lbnVCYXIoKTsgfSByZXR1cm4gbnVsbDsgfSBQb3B1cEJveCBnZXRQb3B1cEJveCgpIHsgcmV0dXJuCisgICAgICogbnVsbDsgfQorICAgICAqLworCisgICAgUmVjdGFuZ2xlIGdldEl0ZW1SZWN0KGludCBpbmRleCkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZSB0aGUgY2xpcCByZWdpb24gd2hlbiBtZW51IHNlbGVjdGlvbiBpcyBjaGFuZ2VkIGZyb20gaW5kZXgxIHRvCisgICAgICogaW5kZXgyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleDEKKyAgICAgKiAgICAgICAgICAgIG9sZCBzZWxlY3RlZCBpdGVtLgorICAgICAqIEBwYXJhbSBpbmRleDIKKyAgICAgKiAgICAgICAgICAgIG5ldyBzZWxlY3RlZCBpdGVtLgorICAgICAqIEByZXR1cm4gdGhlIHJlZ2lvbiB0byByZXBhaW50LgorICAgICAqLworICAgIGZpbmFsIE11bHRpUmVjdEFyZWEgZ2V0VXBkYXRlQ2xpcChpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSB7CisgICAgICAgIE11bHRpUmVjdEFyZWEgY2xpcCA9IG5ldyBNdWx0aVJlY3RBcmVhKCk7CisgICAgICAgIGlmIChpbmRleDEgPj0gMCkgeworICAgICAgICAgICAgY2xpcC5hZGQoZ2V0SXRlbVJlY3QoaW5kZXgxKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluZGV4MiA+PSAwKSB7CisgICAgICAgICAgICBjbGlwLmFkZChnZXRJdGVtUmVjdChpbmRleDIpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2xpcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdWJtZW51IGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIHN1Ym1lbnUgbG9jYXRpb24uCisgICAgICovCisgICAgUG9pbnQgZ2V0U3VibWVudUxvY2F0aW9uKGludCBpbmRleCkgeworICAgICAgICAvLyB0byBiZSBvdmVycmlkZGVuCisgICAgICAgIHJldHVybiBuZXcgUG9pbnQoMCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2VsZWN0ZWQgaXRlbSBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzZWxlY3RlZCBpdGVtIGluZGV4LgorICAgICAqLworICAgIGludCBnZXRTZWxlY3RlZEl0ZW1JbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIHNlbGVjdGVkSXRlbUluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEhpZGUuCisgICAgICovCisgICAgdm9pZCBoaWRlKCkgeworICAgICAgICBzZWxlY3RlZEl0ZW1JbmRleCA9IC0xOworICAgICAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgTWVudUNvbXBvbmVudCkgeworICAgICAgICAgICAgKChNZW51Q29tcG9uZW50KXBhcmVudCkuaXRlbUhpZGRlbih0aGlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEl0ZW0gaGlkZGVuLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgdGhlIG1jLgorICAgICAqLworICAgIHZvaWQgaXRlbUhpZGRlbihNZW51Q29tcG9uZW50IG1jKSB7CisgICAgICAgIC8vIHRvIGJlIG92ZXJyaWRkZW4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgaXMgdmlzaWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGlzIHZpc2libGUuCisgICAgICovCisgICAgYm9vbGVhbiBpc1Zpc2libGUoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBpcyBhY3RpdmUuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBhY3RpdmUuCisgICAgICovCisgICAgYm9vbGVhbiBpc0FjdGl2ZSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGlkZSBhbGwgbWVudSBoaWVyYXJjaHkuCisgICAgICovCisgICAgdm9pZCBlbmRNZW51KCkgeworICAgICAgICAvLyA/Pz9BV1Q6IHRvb2xraXQuZGlzcGF0Y2hlci5wb3B1cERpc3BhdGNoZXIuZGVhY3RpdmF0ZUFsbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZSB0aGUgbW91c2UgY2xpY2sgb3IgRW50ZXIga2V5IGV2ZW50IG9uIGEgbWVudSdzIGl0ZW0uCisgICAgICogCisgICAgICogQHBhcmFtIHdoZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBldmVudCB0aW1lLgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIGlucHV0IGV2ZW50IG1vZGlmaWVycy4KKyAgICAgKi8KKyAgICB2b2lkIGl0ZW1TZWxlY3RlZChsb25nIHdoZW4sIGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgZW5kTWVudSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF1dG8gbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcuCisgICAgICovCisgICAgU3RyaW5nIGF1dG9OYW1lKCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9IGdldENsYXNzKCkuZ2V0TmFtZSgpOworICAgICAgICBpZiAobmFtZS5pbmRleE9mKCIkIikgIT0gLTEpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gPz8/QVdUOiBpbnQgbnVtYmVyID0gdG9vbGtpdC5hdXRvTnVtYmVyLm5leHRNZW51Q29tcG9uZW50Kys7CisgICAgICAgIGludCBudW1iZXIgPSAwOworICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcobmFtZS5sYXN0SW5kZXhPZigiLiIpICsgMSkgKyBJbnRlZ2VyLnRvU3RyaW5nKG51bWJlcik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgR3JhcGhpY3Mgb2JqZWN0IGZvciB0aGUgcG9wLXVwIGJveCBvZiB0aGlzIG1lbnUgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjbGlwCisgICAgICogICAgICAgICAgICB0aGUgY2xpcCB0byBzZXQgb24gdGhpcyBHcmFwaGljcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIEdyYXBoaWNzIG9iamVjdCwgb3IgbnVsbCBpZiBzdWNoIG9iamVjdCBpcyBub3QKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBHcmFwaGljcyBnZXRHcmFwaGljcyhNdWx0aVJlY3RBcmVhIGNsaXApIHsKKyAgICAgICAgLy8gdG8gYmUgb3ZlcnJpZGRlbgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIGFjY2Vzc2libGUgY29udGV4dCBzcGVjaWZpYyBmb3IgcGFydGljdWxhciBtZW51IGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIEFjY2Vzc2libGVDb250ZXh0IGNyZWF0ZUFjY2Vzc2libGVDb250ZXh0KCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAqLworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L01lbnVDb250YWluZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9NZW51Q29udGFpbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTUwOWExYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9NZW51Q29udGFpbmVyLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCisvKioKKyAqIFRoZSBNZW51Q29udGFpbmVyIGludGVyZmFjZSByZXByZXNlbnRzIGFsbCBtZW51IGNvbnRhaW5lcnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIE1lbnVDb250YWluZXIgeworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIE1lbnVDb21wb25lbnQgZnJvbSB0aGUgTWVudUNvbnRhaW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIE1lbnVDb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKE1lbnVDb21wb25lbnQgYyk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBGb250IG9mIHRoZSBNZW51Q29udGFpbmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZvbnQgb2YgdGhlIE1lbnVDb250YWluZXIuCisgICAgICovCisgICAgcHVibGljIEZvbnQgZ2V0Rm9udCgpOworCisgICAgLyoqCisgICAgICogUG9zdHMgYW4gRXZlbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBFdmVudC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGV2ZW50IGlzIHBvc3RlZCBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBAZGVwcmVjYXRlZCBSZXBsYWNlZCBieSBkaXNwYXRjaEV2ZW50IG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIHBvc3RFdmVudChFdmVudCBlKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L01vZGFsQ29udGV4dC5qYXZhIGIvYXd0L2phdmEvYXd0L01vZGFsQ29udGV4dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyYTU5MTIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvTW9kYWxDb250ZXh0LmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dDsKKworLyoqCisgKgorICogVGhlIGNvbnRleHQgZm9yIG5lc3RlZCBldmVudCBsb29wLiBJdCBjYW4gYmUgZGlhbG9nLCBwb3B1cCBtZW51IGV0Yy4KKyAqLworY2xhc3MgTW9kYWxDb250ZXh0IHsKKworICAgIHByaXZhdGUgYm9vbGVhbiBydW5uaW5nID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGZpbmFsIFRvb2xraXQgdG9vbGtpdDsKKworICAgIE1vZGFsQ29udGV4dCgpIHsKKyAgICAgICAgdG9vbGtpdCA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdXAgYW5kIHJ1biBtb2RhbCBsb29wIGluIHRoaXMgY29udGV4dAorICAgICAqCisgICAgICovCisgICAgdm9pZCBydW5Nb2RhbExvb3AoKSB7CisgICAgICAgIHJ1bm5pbmcgPSB0cnVlOworICAgICAgICB0b29sa2l0LmRpc3BhdGNoVGhyZWFkLnJ1bk1vZGFsTG9vcCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZWF2ZSB0aGUgbW9kYWwgbG9vcCBydW5uaW5nIGluIHRoaXMgY29udGV4dAorICAgICAqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc3RvcHMgdGhlIGxvb3AgaW1tZWRpYXRlbHksCisgICAgICogaXQganVzdCBzZXRzIHRoZSBmbGFnIHRoYXQgc2F5cyB0aGUgbW9kYWwgbG9vcCB0byBzdG9wCisgICAgICoKKyAgICAgKi8KKyAgICB2b2lkIGVuZE1vZGFsTG9vcCgpIHsKKyAgICAgICAgcnVubmluZyA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICogQHJldHVybiBtb2RhbCBsb29wIGlzIGN1cnJlbnRseSBydW5uaW5nIGluIHRoaXMgY29udGV4dAorICAgICAqLworICAgIGJvb2xlYW4gaXNNb2RhbExvb3BSdW5uaW5nKCkgeworICAgICAgICByZXR1cm4gcnVubmluZzsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9Nb3VzZURpc3BhdGNoZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9Nb3VzZURpc3BhdGNoZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjQ4ZjlkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L01vdXNlRGlzcGF0Y2hlci5qYXZhCkBAIC0wLDAgKzEsNDE4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYsIE1pY2hhZWwgRGFuaWxvdiwgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lk1vdXNlTGlzdGVuZXI7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuTW91c2VNb3Rpb25MaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Nb3VzZVdoZWVsRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuTW91c2VXaGVlbExpc3RlbmVyOworaW1wb3J0IGphdmEuYXd0LkRpc3BhdGNoZXIuTW91c2VHcmFiTWFuYWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUV2ZW50OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZVdpbmRvdzsKKworCitjbGFzcyBNb3VzZURpc3BhdGNoZXIgeworCisgICAgLy8gRmllbGRzIGZvciBzeW50aGV0aWMgbW91c2UgY2xpY2sgZXZlbnRzIGdlbmVyYXRpb24KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgY2xpY2tEZWx0YSA9IDU7CisgICAgcHJpdmF0ZSBmaW5hbCBsb25nW10gbGFzdFByZXNzVGltZSA9IG5ldyBsb25nW10gezBsLCAwbCwgMGx9OworICAgIHByaXZhdGUgZmluYWwgUG9pbnRbXSBsYXN0UHJlc3NQb3MgPSBuZXcgUG9pbnRbXSB7bnVsbCwgbnVsbCwgbnVsbH07CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuW10gYnV0dG9uUHJlc3NlZCA9IG5ldyBib29sZWFuW10ge2ZhbHNlLCBmYWxzZSwgZmFsc2V9OworICAgIHByaXZhdGUgZmluYWwgaW50W10gY2xpY2tDb3VudCA9IG5ldyBpbnRbXSB7MCwgMCwgMH07CisKKyAgICAvLyBGaWVsZHMgZm9yIG1vdXNlIGVudGVyZWQvZXhpdGVkIHN1cHBvcnQKKyAgICBwcml2YXRlIENvbXBvbmVudCBsYXN0VW5kZXJQb2ludGVyID0gbnVsbDsKKyAgICBwcml2YXRlIGZpbmFsIFBvaW50IGxhc3RTY3JlZW5Qb3MgPSBuZXcgUG9pbnQoLTEsIC0xKTsKKworICAgIC8vIEZpZWxkcyBmb3IgcmVkdW5kYW50IG1vdXNlIG1vdmVkL2RyYWdnZWQgZmlsdGVyaW5nCisgICAgcHJpdmF0ZSBDb21wb25lbnQgbGFzdFVuZGVyTW90aW9uID0gbnVsbDsKKyAgICBwcml2YXRlIFBvaW50IGxhc3RMb2NhbFBvcyA9IG5ldyBQb2ludCgtMSwgLTEpOworCisgICAgcHJpdmF0ZSBmaW5hbCBNb3VzZUdyYWJNYW5hZ2VyIG1vdXNlR3JhYk1hbmFnZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBUb29sa2l0IHRvb2xraXQ7CisKKyAgICBzdGF0aWMgUG9pbnQgY29udmVydFBvaW50KENvbXBvbmVudCBzcmMsIGludCB4LCBpbnQgeSwgQ29tcG9uZW50IGRlc3QpIHsKKyAgICAgICAgUG9pbnQgc3JjUG9pbnQgPSBnZXRBYnNMb2NhdGlvbihzcmMpOworICAgICAgICBQb2ludCBkZXN0UG9pbnQgPSBnZXRBYnNMb2NhdGlvbihkZXN0KTsKKworICAgICAgICByZXR1cm4gbmV3IFBvaW50KHggKyAoc3JjUG9pbnQueCAtIGRlc3RQb2ludC54KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB5ICsgKHNyY1BvaW50LnkgLSBkZXN0UG9pbnQueSkpOworICAgIH0KKworICAgIHN0YXRpYyBQb2ludCBjb252ZXJ0UG9pbnQoQ29tcG9uZW50IHNyYywgUG9pbnQgcCwgQ29tcG9uZW50IGRzdCkgeworICAgICAgICByZXR1cm4gY29udmVydFBvaW50KHNyYywgcC54LCBwLnksIGRzdCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgUG9pbnQgZ2V0QWJzTG9jYXRpb24oQ29tcG9uZW50IGNvbXApIHsKKyAgICAgICAgUG9pbnQgbG9jYXRpb24gPSBuZXcgUG9pbnQoMCwgMCk7CisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQ6IEFXVCBjb21wb25lbnRzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICBmb3IgKENvbXBvbmVudCBwYXJlbnQgPSBjb21wOyBwYXJlbnQgIT0gbnVsbDsgcGFyZW50ID0gcGFyZW50LnBhcmVudCkgeworLy8gICAgICAgICAgICBQb2ludCBwYXJlbnRQb3MgPSAocGFyZW50IGluc3RhbmNlb2YgRW1iZWRkZWRXaW5kb3cgPworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LmdldE5hdGl2ZVdpbmRvdygpLmdldFNjcmVlblBvcygpIDoKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5nZXRMb2NhdGlvbigpKTsKKy8vCisvLyAgICAgICAgICAgIGxvY2F0aW9uLnRyYW5zbGF0ZShwYXJlbnRQb3MueCwgcGFyZW50UG9zLnkpOworLy8KKy8vICAgICAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFdpbmRvdykgeworLy8gICAgICAgICAgICAgICAgYnJlYWs7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisKKyAgICAgICAgcmV0dXJuIGxvY2F0aW9uOworICAgIH0KKworICAgIE1vdXNlRGlzcGF0Y2hlcihNb3VzZUdyYWJNYW5hZ2VyIG1vdXNlR3JhYk1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgIFRvb2xraXQgdG9vbGtpdCkgeworICAgICAgICB0aGlzLm1vdXNlR3JhYk1hbmFnZXIgPSBtb3VzZUdyYWJNYW5hZ2VyOworICAgICAgICB0aGlzLnRvb2xraXQgPSB0b29sa2l0OworICAgIH0KKworICAgIFBvaW50IGdldFBvaW50ZXJQb3MoKSB7CisgICAgICAgIHJldHVybiBsYXN0U2NyZWVuUG9zOworICAgIH0KKworICAgIGJvb2xlYW4gZGlzcGF0Y2goQ29tcG9uZW50IHNyYywgTmF0aXZlRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgaW50IGlkID0gZXZlbnQuZ2V0RXZlbnRJZCgpOworCisgICAgICAgIGxhc3RTY3JlZW5Qb3Muc2V0TG9jYXRpb24oZXZlbnQuZ2V0U2NyZWVuUG9zKCkpOworICAgICAgICBjaGVja01vdXNlRW50ZXJFeGl0KGV2ZW50LmdldElucHV0TW9kaWZpZXJzKCksIGV2ZW50LmdldFRpbWUoKSk7CisKKyAgICAgICAgaWYgKGlkID09IE1vdXNlRXZlbnQuTU9VU0VfV0hFRUwpIHsKKy8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogQVdUIGNvbXBvbmVudHMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICBkaXNwYXRjaFdoZWVsRXZlbnQoc3JjLCBldmVudCk7CisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIH0gZWxzZSBpZiAoKGlkICE9IE1vdXNlRXZlbnQuTU9VU0VfRU5URVJFRCkgJiYKKyAgICAgICAgICAgICAgICAgICAoaWQgIT0gTW91c2VFdmVudC5NT1VTRV9FWElURUQpKSB7CisgICAgICAgICAgICBQb2ludGVySW5mbyBpbmZvID0gbmV3IFBvaW50ZXJJbmZvKHNyYywgZXZlbnQuZ2V0TG9jYWxQb3MoKSk7CisKKyAgICAgICAgICAgIG1vdXNlR3JhYk1hbmFnZXIucHJlcHJvY2Vzc0V2ZW50KGV2ZW50KTsKKyAgICAgICAgICAgIGZpbmRFdmVudFNvdXJjZShpbmZvKTsKKyAgICAgICAgICAgIGlmICgoaWQgPT0gTW91c2VFdmVudC5NT1VTRV9QUkVTU0VEKSB8fAorICAgICAgICAgICAgICAgIChpZCA9PSBNb3VzZUV2ZW50Lk1PVVNFX1JFTEVBU0VEKSkgeworCisgICAgICAgICAgICAgICAgZGlzcGF0Y2hCdXR0b25FdmVudChpbmZvLCBldmVudCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChpZCA9PSBNb3VzZUV2ZW50Lk1PVVNFX01PVkVEKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAoaWQgPT0gTW91c2VFdmVudC5NT1VTRV9EUkFHR0VEKSkgeworCisgICAgICAgICAgICAgICAgZGlzcGF0Y2hNb3Rpb25FdmVudChpbmZvLCBldmVudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTW91c2VFbnRlckV4aXQoaW50IG1vZGlmaWVycywgbG9uZyB3aGVuKSB7CisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQ6IEFXVCBjb21wb25lbnRzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICBQb2ludGVySW5mbyBpbmZvID0gZmluZENvbXBvbmVudFVuZGVyUG9pbnRlcigpOworLy8gICAgICAgIENvbXBvbmVudCBjdXJVbmRlclBvaW50ZXIgPQorLy8gICAgICAgICAgICAgICAgcHJvcGFnYXRlRXZlbnQoaW5mbywgQVdURXZlbnQuTU9VU0VfRVZFTlRfTUFTSywKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1vdXNlTGlzdGVuZXIuY2xhc3MsIGZhbHNlKS5zcmM7CisvLworLy8gICAgICAgIGlmIChjdXJVbmRlclBvaW50ZXIgIT0gbGFzdFVuZGVyUG9pbnRlcikgeworLy8gICAgICAgICAgICBQb2ludCBwb3MgPSBpbmZvLnBvc2l0aW9uOworLy8gICAgICAgICAgICBpZiAoKGxhc3RVbmRlclBvaW50ZXIgIT0gbnVsbCkgJiYKKy8vICAgICAgICAgICAgICAgICBsYXN0VW5kZXJQb2ludGVyLmlzTW91c2VFeGl0ZWRFeHBlY3RlZCgpKSB7CisvLworLy8gICAgICAgICAgICAgICAgUG9pbnQgZXhpdFBvcyA9IGNvbnZlcnRQb2ludChudWxsLCBsYXN0U2NyZWVuUG9zLngsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RTY3JlZW5Qb3MueSwgbGFzdFVuZGVyUG9pbnRlcik7CisvLworLy8gICAgICAgICAgICAgICAgcG9zdE1vdXNlRW50ZXJFeGl0KE1vdXNlRXZlbnQuTU9VU0VfRVhJVEVELCBtb2RpZmllcnMsIHdoZW4sCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpdFBvcy54LCBleGl0UG9zLnksIGxhc3RVbmRlclBvaW50ZXIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgICAgIHNldEN1cnNvcihjdXJVbmRlclBvaW50ZXIpOworLy8gICAgICAgICAgICBpZiAoY3VyVW5kZXJQb2ludGVyICE9IG51bGwpIHsKKy8vICAgICAgICAgICAgICAgIHBvc3RNb3VzZUVudGVyRXhpdChNb3VzZUV2ZW50Lk1PVVNFX0VOVEVSRUQsIG1vZGlmaWVycywgd2hlbiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MueCwgcG9zLnksIGN1clVuZGVyUG9pbnRlcik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgbGFzdFVuZGVyUG9pbnRlciA9IGN1clVuZGVyUG9pbnRlcjsKKy8vICAgICAgICB9CisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldEN1cnNvcihDb21wb25lbnQgY29tcCkgeworICAgICAgICBpZiAoY29tcCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ29tcG9uZW50IGdyYWJPd25lciA9IG1vdXNlR3JhYk1hbmFnZXIuZ2V0U3ludGhldGljR3JhYk93bmVyKCk7CisgICAgICAgIENvbXBvbmVudCBjdXJzb3JDb21wID0gKChncmFiT3duZXIgIT0gbnVsbCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYWJPd25lci5pc1Nob3dpbmcoKSA/IGdyYWJPd25lciA6IGNvbXApOworICAgICAgICBjdXJzb3JDb21wLnNldEN1cnNvcigpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwb3N0TW91c2VFbnRlckV4aXQoaW50IGlkLCBpbnQgbW9kLCBsb25nIHdoZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgeCwgaW50IHksIENvbXBvbmVudCBjb21wKSB7CisgICAgICAgIGlmIChjb21wLmlzSW5kaXJlY3RseUVuYWJsZWQoKSkgeworICAgICAgICAgICAgdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpLnBvc3RFdmVudCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoY29tcCwgaWQsIHdoZW4sIG1vZCwgeCwgeSwgMCwgZmFsc2UpKTsKKyAgICAgICAgICAgIGNvbXAuc2V0TW91c2VFeGl0ZWRFeHBlY3RlZChpZCA9PSBNb3VzZUV2ZW50Lk1PVVNFX0VOVEVSRUQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29tcC5zZXRNb3VzZUV4aXRlZEV4cGVjdGVkKGZhbHNlKTsKKyAgICAgICAgfQorICAgIH0KKworIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogQVdUIGNvbXBvbmVudHMgbm90IHN1cHBvcnRlZAorLy8gICAgcHJpdmF0ZSBQb2ludGVySW5mbyBmaW5kQ29tcG9uZW50VW5kZXJQb2ludGVyKCkgeworLy8gICAgICAgIE5hdGl2ZVdpbmRvdyBuYXRpdmVXaW5kb3cgPSB0b29sa2l0LmdldFdpbmRvd0ZhY3RvcnkoKS4KKy8vICAgICAgICBnZXRXaW5kb3dGcm9tUG9pbnQobGFzdFNjcmVlblBvcyk7CisvLworLy8gICAgICAgIGlmIChuYXRpdmVXaW5kb3cgIT0gbnVsbCkgeworLy8gICAgICAgICAgICBDb21wb25lbnQgY29tcCA9IHRvb2xraXQuZ2V0Q29tcG9uZW50QnlJZChuYXRpdmVXaW5kb3cuZ2V0SWQoKSk7CisvLworLy8gICAgICAgICAgICBpZiAoY29tcCAhPSBudWxsKSB7CisvLyAgICAgICAgICAgICAgICBXaW5kb3cgd2luZG93ID0gY29tcC5nZXRXaW5kb3dBbmNlc3RvcigpOworLy8gICAgICAgICAgICAgICAgUG9pbnQgcG9pbnRlclBvcyA9IGNvbnZlcnRQb2ludChudWxsLCBsYXN0U2NyZWVuUG9zLngsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RTY3JlZW5Qb3MueSwgd2luZG93KTsKKy8vCisvLyAgICAgICAgICAgICAgICBpZiAod2luZG93LmdldENsaWVudCgpLmNvbnRhaW5zKHBvaW50ZXJQb3MpKSB7CisvLyAgICAgICAgICAgICAgICAgICAgUG9pbnRlckluZm8gaW5mbyA9IG5ldyBQb2ludGVySW5mbyh3aW5kb3csIHBvaW50ZXJQb3MpOworLy8KKy8vICAgICAgICAgICAgICAgICAgICBmYWxsMkNoaWxkKGluZm8pOworLy8KKy8vICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5mbzsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgcmV0dXJuIG5ldyBQb2ludGVySW5mbyhudWxsLCBudWxsKTsKKy8vICAgIH0KKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAKKyAgICBwcml2YXRlIHZvaWQgZmluZEV2ZW50U291cmNlKFBvaW50ZXJJbmZvIGluZm8pIHsKKyAgICAgICAgQ29tcG9uZW50IGdyYWJPd25lciA9IG1vdXNlR3JhYk1hbmFnZXIuZ2V0U3ludGhldGljR3JhYk93bmVyKCk7CisKKyAgICAgICAgaWYgKGdyYWJPd25lciAhPSBudWxsICYmIGdyYWJPd25lci5pc1Nob3dpbmcoKSkgeworICAgICAgICAgICAgaW5mby5wb3NpdGlvbiA9IGNvbnZlcnRQb2ludChpbmZvLnNyYywgaW5mby5wb3NpdGlvbiwgZ3JhYk93bmVyKTsKKyAgICAgICAgICAgIGluZm8uc3JjID0gZ3JhYk93bmVyOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8/Pz9BV1Q6IHJpc2UyVG9wTGV2ZWwoaW5mbyk7CisgICAgICAgICAgICAvLz8/P0FXVDogZmFsbDJDaGlsZChpbmZvKTsKKyAgICAgICAgfQorICAgIH0KKworIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogQVdUIGNvbXBvbmVudHMgbm90IHN1cHBvcnRlZAorLy8gICAgcHJpdmF0ZSB2b2lkIHJpc2UyVG9wTGV2ZWwoUG9pbnRlckluZm8gaW5mbykgeworLy8gICAgICAgIHdoaWxlICghKGluZm8uc3JjIGluc3RhbmNlb2YgV2luZG93KSkgeworLy8gICAgICAgICAgICBpbmZvLnBvc2l0aW9uLnRyYW5zbGF0ZShpbmZvLnNyYy54LCBpbmZvLnNyYy55KTsKKy8vICAgICAgICAgICAgaW5mby5zcmMgPSBpbmZvLnNyYy5wYXJlbnQ7CisvLyAgICAgICAgfQorLy8gICAgfQorLy8KKy8vICAgIHByaXZhdGUgdm9pZCBmYWxsMkNoaWxkKFBvaW50ZXJJbmZvIGluZm8pIHsKKy8vICAgICAgICBJbnNldHMgaW5zZXRzID0gaW5mby5zcmMuZ2V0SW5zZXRzKCk7CisvLworLy8gICAgICAgIGZpbmFsIFBvaW50IHBvcyA9IGluZm8ucG9zaXRpb247CisvLyAgICAgICAgZmluYWwgaW50IHggPSBwb3MueDsKKy8vICAgICAgICBmaW5hbCBpbnQgeSA9IHBvcy55OworLy8gICAgICAgIGlmICgoeCA+PSBpbnNldHMubGVmdCkgJiYgKHkgPj0gaW5zZXRzLnRvcCkgJiYKKy8vICAgICAgICAgICAgICAgICh4IDwgKGluZm8uc3JjLncgLSBpbnNldHMucmlnaHQpKSAmJgorLy8gICAgICAgICAgICAgICAgKHkgPCAoaW5mby5zcmMuaCAtIGluc2V0cy5ib3R0b20pKSkKKy8vICAgICAgICB7CisvLyAgICAgICAgICAgIENvbXBvbmVudFtdIGNoaWxkcmVuID0gKChDb250YWluZXIpIGluZm8uc3JjKS5nZXRDb21wb25lbnRzKCk7CisvLworLy8gICAgICAgICAgICBmb3IgKENvbXBvbmVudCBjaGlsZCA6IGNoaWxkcmVuKSB7CisvLyAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNTaG93aW5nKCkpIHsKKy8vICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQuY29udGFpbnMoeCAtIGNoaWxkLmdldFgoKSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgLSBjaGlsZC5nZXRZKCkpKQorLy8gICAgICAgICAgICAgICAgICAgIHsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgaW5mby5zcmMgPSBjaGlsZDsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgcG9zLnRyYW5zbGF0ZSgtY2hpbGQueCwgLWNoaWxkLnkpOworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgQ29udGFpbmVyKSB7CisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxsMkNoaWxkKGluZm8pOworLy8gICAgICAgICAgICAgICAgICAgICAgICB9CisvLworLy8gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisvLyAgICAgICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgICAgfQorLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfQorLy8gICAgfQorLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgcHJpdmF0ZSB2b2lkIGRpc3BhdGNoQnV0dG9uRXZlbnQoUG9pbnRlckluZm8gaW5mbywgTmF0aXZlRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgaW50IGJ1dHRvbiA9IGV2ZW50LmdldE1vdXNlQnV0dG9uKCk7CisgICAgICAgIGxvbmcgdGltZSA9IGV2ZW50LmdldFRpbWUoKTsKKyAgICAgICAgaW50IGlkID0gZXZlbnQuZ2V0RXZlbnRJZCgpOworICAgICAgICBpbnQgaW5kZXggPSBidXR0b24gLSAxOworICAgICAgICBib29sZWFuIGNsaWNrUmVxdWlyZWQgPSBmYWxzZTsKKworICAgICAgICBwcm9wYWdhdGVFdmVudChpbmZvLCBBV1RFdmVudC5NT1VTRV9FVkVOVF9NQVNLLAorICAgICAgICAgICAgICAgICAgICAgICBNb3VzZUxpc3RlbmVyLmNsYXNzLCBmYWxzZSk7CisgICAgICAgIGlmIChpZCA9PSBNb3VzZUV2ZW50Lk1PVVNFX1BSRVNTRUQpIHsKKyAgICAgICAgICAgIGludCBjbGlja0ludGVydmFsID0gdG9vbGtpdC5kaXNwYXRjaGVyLmNsaWNrSW50ZXJ2YWw7CisgICAgICAgICAgICBtb3VzZUdyYWJNYW5hZ2VyLm9uTW91c2VQcmVzc2VkKGluZm8uc3JjKTsKKyAgICAgICAgICAgIGJ1dHRvblByZXNzZWRbaW5kZXhdID0gdHJ1ZTsKKyAgICAgICAgICAgIGNsaWNrQ291bnRbaW5kZXhdID0gKCFkZWx0YUV4Y2VlZGVkKGluZGV4LCBpbmZvKSAmJgorICAgICAgICAgICAgICAgICAgICAoKHRpbWUgLSBsYXN0UHJlc3NUaW1lW2luZGV4XSkgPD0gY2xpY2tJbnRlcnZhbCkpID8KKyAgICAgICAgICAgICAgICAgICAgY2xpY2tDb3VudFtpbmRleF0gKyAxIDogMTsKKyAgICAgICAgICAgIGxhc3RQcmVzc1RpbWVbaW5kZXhdID0gdGltZTsKKyAgICAgICAgICAgIGxhc3RQcmVzc1Bvc1tpbmRleF0gPSBpbmZvLnBvc2l0aW9uOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbW91c2VHcmFiTWFuYWdlci5vbk1vdXNlUmVsZWFzZWQoaW5mby5zcmMpOworICAgICAgICAgICAgLy8gc2V0IGN1cnNvciBiYWNrIG9uIHN5bnRoZXRpYyBtb3VzZSBncmFiIGVuZDoKKy8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogQVdUIGNvbXBvbmVudHMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICBzZXRDdXJzb3IoZmluZENvbXBvbmVudFVuZGVyUG9pbnRlcigpLnNyYyk7CisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICBpZiAoYnV0dG9uUHJlc3NlZFtpbmRleF0pIHsKKyAgICAgICAgICAgICAgICBidXR0b25QcmVzc2VkW2luZGV4XSA9IGZhbHNlOworICAgICAgICAgICAgICAgIGNsaWNrUmVxdWlyZWQgPSAhZGVsdGFFeGNlZWRlZChpbmRleCwgaW5mbyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNsaWNrQ291bnRbaW5kZXhdID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaW5mby5zcmMuaXNJbmRpcmVjdGx5RW5hYmxlZCgpKSB7CisgICAgICAgICAgICBmaW5hbCBQb2ludCBwb3MgPSBpbmZvLnBvc2l0aW9uOworICAgICAgICAgICAgZmluYWwgaW50IG1vZCA9IGV2ZW50LmdldElucHV0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICB0b29sa2l0LmdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCkucG9zdEV2ZW50KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNb3VzZUV2ZW50KGluZm8uc3JjLCBpZCwgdGltZSwgbW9kLCBwb3MueCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MueSwgY2xpY2tDb3VudFtpbmRleF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuZ2V0VHJpZ2dlcigpLCBidXR0b24pKTsKKyAgICAgICAgICAgIGlmIChjbGlja1JlcXVpcmVkKSB7CisgICAgICAgICAgICAgICAgdG9vbGtpdC5nZXRTeXN0ZW1FdmVudFF1ZXVlSW1wbCgpLnBvc3RFdmVudCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTW91c2VFdmVudChpbmZvLnNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb3VzZUV2ZW50Lk1PVVNFX0NMSUNLRUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZSwgbW9kLCBwb3MueCwgcG9zLnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2tDb3VudFtpbmRleF0sIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGRlbHRhRXhjZWVkZWQoaW50IGluZGV4LCBQb2ludGVySW5mbyBpbmZvKSB7CisgICAgICAgIGZpbmFsIFBvaW50IGxhc3RQb3MgPSBsYXN0UHJlc3NQb3NbaW5kZXhdOworICAgICAgICBpZiAobGFzdFBvcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChNYXRoLmFicyhsYXN0UG9zLnggLSBpbmZvLnBvc2l0aW9uLngpID4gY2xpY2tEZWx0YSkgfHwKKyAgICAgICAgICAgICAgICAoTWF0aC5hYnMobGFzdFBvcy55IC0gaW5mby5wb3NpdGlvbi55KSA+IGNsaWNrRGVsdGEpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGlzcGF0Y2hNb3Rpb25FdmVudChQb2ludGVySW5mbyBpbmZvLCBOYXRpdmVFdmVudCBldmVudCkgeworICAgICAgICBwcm9wYWdhdGVFdmVudChpbmZvLCBBV1RFdmVudC5NT1VTRV9NT1RJT05fRVZFTlRfTUFTSywKKyAgICAgICAgICAgICAgICAgICAgICAgTW91c2VNb3Rpb25MaXN0ZW5lci5jbGFzcywgZmFsc2UpOworICAgICAgICBmaW5hbCBQb2ludCBwb3MgPSBpbmZvLnBvc2l0aW9uOworICAgICAgICBpZiAoKGxhc3RVbmRlck1vdGlvbiAhPSBpbmZvLnNyYykgfHwKKyAgICAgICAgICAgICFsYXN0TG9jYWxQb3MuZXF1YWxzKHBvcykpIHsKKworICAgICAgICAgICAgbGFzdFVuZGVyTW90aW9uID0gaW5mby5zcmM7CisgICAgICAgICAgICBsYXN0TG9jYWxQb3MgPSBwb3M7CisKKyAgICAgICAgICAgIGlmIChpbmZvLnNyYy5pc0luZGlyZWN0bHlFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgICB0b29sa2l0LmdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCkucG9zdEV2ZW50KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNb3VzZUV2ZW50KGluZm8uc3JjLCBldmVudC5nZXRFdmVudElkKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuZ2V0VGltZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LmdldElucHV0TW9kaWZpZXJzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLngsIHBvcy55LCAwLCBmYWxzZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgTW91c2VXaGVlbEV2ZW50IGNyZWF0ZVdoZWVsRXZlbnQoQ29tcG9uZW50IHNyYywgTmF0aXZlRXZlbnQgZXZlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9pbnQgd2hlcmUpIHsKKworICAgICAgICBJbnRlZ2VyIHNjcm9sbEFtb3VudFByb3BlcnR5ID0KKyAgICAgICAgICAgIChJbnRlZ2VyKXRvb2xraXQuZ2V0RGVza3RvcFByb3BlcnR5KCJhd3Qud2hlZWxTY3JvbGxpbmdTaXplIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaW50IGFtb3VudCA9IDE7CisgICAgICAgIGludCB0eXBlID0gTW91c2VXaGVlbEV2ZW50LldIRUVMX1VOSVRfU0NST0xMOworCisgICAgICAgIGlmIChzY3JvbGxBbW91bnRQcm9wZXJ0eSAhPSBudWxsKSB7CisgICAgICAgICAgICBhbW91bnQgPSBzY3JvbGxBbW91bnRQcm9wZXJ0eS5pbnRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKGFtb3VudCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBNb3VzZVdoZWVsRXZlbnQuV0hFRUxfQkxPQ0tfU0NST0xMOworICAgICAgICAgICAgICAgIGFtb3VudCA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBNb3VzZVdoZWVsRXZlbnQoc3JjLCBldmVudC5nZXRFdmVudElkKCksCisgICAgICAgICAgICAgICAgZXZlbnQuZ2V0VGltZSgpLCBldmVudC5nZXRJbnB1dE1vZGlmaWVycygpLAorICAgICAgICAgICAgICAgIHdoZXJlLngsIHdoZXJlLnksIDAsIGZhbHNlLCB0eXBlLCBhbW91bnQsCisgICAgICAgICAgICAgICAgZXZlbnQuZ2V0V2hlZWxSb3RhdGlvbigpKTsKKyAgICB9CisKKy8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogQVdUIGNvbXBvbmVudHMgbm90IHN1cHBvcnRlZAorLy8gICAgcHJpdmF0ZSB2b2lkIGRpc3BhdGNoV2hlZWxFdmVudChDb21wb25lbnQgc3JjLCBOYXRpdmVFdmVudCBldmVudCkgeworLy8gICAgICAgIFBvaW50ZXJJbmZvIGluZm8gPSBmaW5kQ29tcG9uZW50VW5kZXJQb2ludGVyKCk7CisvLworLy8gICAgICAgIGlmIChpbmZvLnNyYyA9PSBudWxsKSB7CisvLyAgICAgICAgICAgIGluZm8uc3JjID0gc3JjOworLy8gICAgICAgICAgICBpbmZvLnBvc2l0aW9uID0gZXZlbnQuZ2V0TG9jYWxQb3MoKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIHByb3BhZ2F0ZUV2ZW50KGluZm8sIEFXVEV2ZW50Lk1PVVNFX1dIRUVMX0VWRU5UX01BU0ssCisvLyAgICAgICAgICAgICAgICAgICAgICAgTW91c2VXaGVlbExpc3RlbmVyLmNsYXNzLCB0cnVlKTsKKy8vICAgICAgICBpZiAoKGluZm8uc3JjICE9IG51bGwpICYmIGluZm8uc3JjLmlzSW5kaXJlY3RseUVuYWJsZWQoKSkgeworLy8gICAgICAgICAgICB0b29sa2l0LmdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCkucG9zdEV2ZW50KAorLy8gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVdoZWVsRXZlbnQoaW5mby5zcmMsIGV2ZW50LCBpbmZvLnBvc2l0aW9uKSk7CisvLyAgICAgICAgfQorLy8gICAgfQorLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgcHJpdmF0ZSBQb2ludGVySW5mbyBwcm9wYWdhdGVFdmVudChQb2ludGVySW5mbyBpbmZvLCBsb25nIG1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgRXZlbnRMaXN0ZW5lcj4gdHlwZSwgYm9vbGVhbiBwaWVyY2VIVykgeworICAgICAgICBDb21wb25lbnQgc3JjID0gaW5mby5zcmM7CisgICAgICAgIHdoaWxlICgoc3JjICE9IG51bGwpICYmCisgICAgICAgICAgICAgICAoc3JjLmlzTGlnaHR3ZWlnaHQoKSB8fCBwaWVyY2VIVykgJiYKKyAgICAgICAgICAgICAgIShzcmMuaXNNb3VzZUV2ZW50RW5hYmxlZChtYXNrKSB8fAorICAgICAgICAgICAgICAgKHNyYy5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoID4gMCkpKSB7CisKKyAgICAgICAgICAgIGluZm8ucG9zaXRpb24udHJhbnNsYXRlKHNyYy54LCBzcmMueSk7CisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQ6IEFXVCBjb21wb25lbnRzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICAgICAgc3JjID0gc3JjLnBhcmVudDsKKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgIGluZm8uc3JjID0gc3JjOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGluZm87CisgICAgfQorCisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQ6IEFXVCBjb21wb25lbnRzIG5vdCBzdXBwb3J0ZWQKKy8vICAgIFdpbmRvdyBmaW5kV2luZG93QXQoUG9pbnQgcCkgeworLy8gICAgICAgIE5hdGl2ZVdpbmRvdyBuYXRpdmVXaW5kb3cgPQorLy8gICAgICAgICAgICB0b29sa2l0LmdldFdpbmRvd0ZhY3RvcnkoKS5nZXRXaW5kb3dGcm9tUG9pbnQocCk7CisvLworLy8gICAgICAgIFdpbmRvdyB3aW5kb3cgPSBudWxsOworLy8gICAgICAgIGlmIChuYXRpdmVXaW5kb3cgIT0gbnVsbCkgeworLy8gICAgICAgICAgICBDb21wb25lbnQgY29tcCA9IHRvb2xraXQuZ2V0Q29tcG9uZW50QnlJZChuYXRpdmVXaW5kb3cuZ2V0SWQoKSk7CisvLworLy8gICAgICAgICAgICBpZiAoY29tcCAhPSBudWxsKSB7CisvLyAgICAgICAgICAgICAgICB3aW5kb3cgPSBjb21wLmdldFdpbmRvd0FuY2VzdG9yKCk7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLyAgICAgICAgcmV0dXJuIHdpbmRvdzsKKy8vICAgIH0KKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKworICAgIHByaXZhdGUgY2xhc3MgUG9pbnRlckluZm8geworCisgICAgICAgIENvbXBvbmVudCBzcmM7CisgICAgICAgIFBvaW50IHBvc2l0aW9uOworCisgICAgICAgIFBvaW50ZXJJbmZvKENvbXBvbmVudCBzcmMsIFBvaW50IHBvc2l0aW9uKSB7CisgICAgICAgICAgICB0aGlzLnNyYyA9IHNyYzsKKyAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvUGFpbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9QYWludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmZWEzYTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvUGFpbnQuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CisKKy8qKgorICogVGhlIFBhaW50IGludGVyZmFjZSBwcm92aWRlcyBwb3NzaWJpbGl0eSBvZiBnZW5lcmF0aW5nIGNvbG9yIHBhdHRlcm5zIGluCisgKiBkZXZpY2Ugc3BhY2UgZm9yIGZpbGwsIGRyYXcsIG9yIHN0cm9rZSBvcGVyYXRpb25zIGluIGEgR3JhcGhpY3MyRC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUGFpbnQgZXh0ZW5kcyBUcmFuc3BhcmVuY3kgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgUGFpbnRDb250ZXh0IHdoaWNoIGlzIHVzZWQgdG8gZ2VuZXJhdGUgY29sb3IgcGF0dGVybnMgZm9yCisgICAgICogcmVuZGVyaW5nIG9wZXJhdGlvbnMgb2YgR3JhcGhpY3MyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY20KKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvck1vZGVsIG9iamVjdCwgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gZGV2aWNlQm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlIHJlcHJlc2VudHMgdGhlIGJvdW5kaW5nIGJveCBvZiBkZXZpY2Ugc3BhY2UgZm9yCisgICAgICogICAgICAgICAgICB0aGUgZ3JhcGhpY3MgcmVuZGVyaW5nIG9wZXJhdGlvbnMuCisgICAgICogQHBhcmFtIHVzZXJCb3VuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgcmVwcmVzZW50cyBib3VuZGluZyBib3ggb2YgdXNlciBzcGFjZSBmb3IgdGhlCisgICAgICogICAgICAgICAgICBncmFwaGljcyByZW5kZXJpbmcgb3BlcmF0aW9ucy4KKyAgICAgKiBAcGFyYW0geGZvcm0KKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gZm9yIHRyYW5zbGF0aW9uIGZyb20gdXNlciBzcGFjZSB0byBkZXZpY2UKKyAgICAgKiAgICAgICAgICAgIHNwYWNlLgorICAgICAqIEBwYXJhbSBoaW50cworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmluZ0hpbnRzIHByZWZlcmVuY2VzLgorICAgICAqIEByZXR1cm4gdGhlIFBhaW50Q29udGV4dCBmb3IgZ2VuZXJhdGluZyBjb2xvciBwYXR0ZXJucy4KKyAgICAgKi8KKyAgICBQYWludENvbnRleHQgY3JlYXRlQ29udGV4dChDb2xvck1vZGVsIGNtLCBSZWN0YW5nbGUgZGV2aWNlQm91bmRzLCBSZWN0YW5nbGUyRCB1c2VyQm91bmRzLAorICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtLCBSZW5kZXJpbmdIaW50cyBoaW50cyk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvUGFpbnRDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvUGFpbnRDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY2YjZjYQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9QYWludENvbnRleHQuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKKworLyoqCisgKiBUaGUgUGFpbnRDb250ZXh0IGludGVyZmFjZSBkZXRlcm1pbmVzIHRoZSBzcGVjaWZpYyBlbnZpcm9ubWVudCBmb3IgZ2VuZXJhdGluZworICogY29sb3IgcGF0dGVybnMgaW4gZGV2aWNlIHNwYWNlIGZvciBmaWxsLCBkcmF3LCBvciBzdHJva2UgcmVuZGVyaW5nIG9wZXJhdGlvbnMKKyAqIHVzaW5nIEdyYXBoaWNzMkQuIFRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIGNvbG9ycyB0aHJvdWdoIHRoZSBSYXN0ZXIgb2JqZWN0CisgKiBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmljIENvbG9yTW9kZWwgZm9yIEdyYXBoaWNzMkQgcmVuZGVyaW5nIG9wZXJhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFBhaW50Q29udGV4dCB7CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyB0aGUgcmVzb3VyY2VzIGFsbG9jYXRlZCBmb3IgdGhlIG9wZXJhdGlvbi4KKyAgICAgKi8KKyAgICB2b2lkIGRpc3Bvc2UoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIENvbG9yTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIENvbG9yTW9kZWwgZ2V0Q29sb3JNb2RlbCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgUmFzdGVyIHdoaWNoIGRlZmluZXMgdGhlIGNvbG9ycyBvZiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyCisgICAgICogYXJlYSBmb3IgR3JhcGhpY3MyRCByZW5kZXJpbmcgb3BlcmF0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZGV2aWNlIHNwYWNlIGFyZWEgZm9yIHdoaWNoIGNvbG9ycyBhcmUKKyAgICAgKiAgICAgICAgICAgIGdlbmVyYXRlZC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgZGV2aWNlIHNwYWNlIGFyZWEgZm9yIHdoaWNoIGNvbG9ycyBhcmUKKyAgICAgKiAgICAgICAgICAgIGdlbmVyYXRlZC4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBkZXZpY2Ugc3BhY2UgYXJlYSBmb3Igd2hpY2ggY29sb3JzIGFyZQorICAgICAqICAgICAgICAgICAgZ2VuZXJhdGVkLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBkZXZpY2Ugc3BhY2UgYXJlYSBmb3Igd2hpY2ggY29sb3JzIGFyZQorICAgICAqICAgICAgICAgICAgZ2VuZXJhdGVkLgorICAgICAqIEByZXR1cm4gdGhlIFJhc3RlciBvYmplY3Qgd2hpY2ggY29udGFpbnMgdGhlIGNvbG9ycyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICByZWN0YW5ndWxhciBhcmVhIGZvciBHcmFwaGljczJEIHJlbmRlcmluZyBvcGVyYXRpb25zLgorICAgICAqLworICAgIFJhc3RlciBnZXRSYXN0ZXIoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L1BvaW50LmphdmEgYi9hd3QvamF2YS9hd3QvUG9pbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZWM0MjQxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L1BvaW50LmphdmEKQEAgLTAsMCArMSwyMTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIFRoZSBQb2ludCBjbGFzcyByZXByZXNlbnRzIGEgcG9pbnQgbG9jYXRpb24gd2l0aCBjb29yZGluYXRlcyBYLCBZIGluIGN1cnJlbnQKKyAqIGNvb3JkaW5hdGUgc3lzdGVtLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFBvaW50IGV4dGVuZHMgUG9pbnQyRCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTI3Njk0MDY0MDI1OTc0OTg1MEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgWCBjb29yZGluYXRlIG9mIFBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgeDsKKworICAgIC8qKgorICAgICAqIFRoZSBZIGNvb3JkaW5hdGUgb2YgUG9pbnQuCisgICAgICovCisgICAgcHVibGljIGludCB5OworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHBvaW50IHdpdGggKDAsIE8pIGNvb3JkaW5hdGVzLCB0aGUgb3JpZ2luIG9mCisgICAgICogY29vcmRpbmF0ZSBzeXN0ZW0uCisgICAgICovCisgICAgcHVibGljIFBvaW50KCkgeworICAgICAgICBzZXRMb2NhdGlvbigwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcG9pbnQgd2l0aCAoeCwgeSkgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgUG9pbnQuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgUG9pbnQuCisgICAgICovCisgICAgcHVibGljIFBvaW50KGludCB4LCBpbnQgeSkgeworICAgICAgICBzZXRMb2NhdGlvbih4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcG9pbnQsIGdpdmluZyBpdCB0aGUgc2FtZSBsb2NhdGlvbiBhcyB0aGUgcGFyYW1ldGVyIHAuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludCBvYmplY3QgZ2l2aW5nIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbmV3IHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBQb2ludChQb2ludCBwKSB7CisgICAgICAgIHNldExvY2F0aW9uKHAueCwgcC55KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyBjdXJyZW50IFBvaW50IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBPYmplY3QgYmVpbmcgY29tcGFyZWQgaXMgYSBQb2ludCB3aG9zZSBjb29yZGluYXRlcworICAgICAqICAgICAgICAgYXJlIGVxdWFsIHRvIHRoZSBjb29yZGluYXRlcyBvZiB0aGlzIFBvaW50LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlBvaW50MkQjZXF1YWxzKE9iamVjdCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBQb2ludCkgeworICAgICAgICAgICAgUG9pbnQgcCA9IChQb2ludClvYmo7CisgICAgICAgICAgICByZXR1cm4geCA9PSBwLnggJiYgeSA9PSBwLnk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IFBvaW50IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IFBvaW50IG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW3g9IiArIHggKyAiLHk9IiArIHkgKyAiXSI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBYIGNvb3JkaW5hdGUgb2YgUG9pbnQgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHJldHVybiBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IGFzIGEgZG91YmxlLgorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5Qb2ludDJEI2dldFgoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0WCgpIHsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBZIGNvb3JkaW5hdGUgb2YgUG9pbnQgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHJldHVybiBZIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IGFzIGEgZG91YmxlLgorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5Qb2ludDJEI2dldFkoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0WSgpIHsKKyAgICAgICAgcmV0dXJuIHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYXRpb24gb2YgdGhlIFBvaW50IGFzIGEgbmV3IFBvaW50IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgUG9pbnQuCisgICAgICovCisgICAgcHVibGljIFBvaW50IGdldExvY2F0aW9uKCkgeworICAgICAgICByZXR1cm4gbmV3IFBvaW50KHgsIHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBQb2ludCB0byB0aGUgc2FtZSBjb29yZGluYXRlcyBhcyBwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgUG9pbnQgdGhhdCBnaXZlcyB0aGUgbmV3IGxvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKFBvaW50IHApIHsKKyAgICAgICAgc2V0TG9jYXRpb24ocC54LCBwLnkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBQb2ludCB0byB0aGUgY29vcmRpbmF0ZXMgWCwgWS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgUG9pbnQncyBuZXcgbG9jYXRpb24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIFBvaW50J3MgbmV3IGxvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKGludCB4LCBpbnQgeSkgeworICAgICAgICB0aGlzLnggPSB4OworICAgICAgICB0aGlzLnkgPSB5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIFBvaW50IHRvIHRoZSBzcGVjaWZpZWQgZG91YmxlIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCB0aGUgUG9pbnQncyBuZXcgbG9jYXRpb24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIHRoZSBQb2ludCdzIG5ldyBsb2NhdGlvbi4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uUG9pbnQyRCNzZXRMb2NhdGlvbihkb3VibGUsIGRvdWJsZSkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgeCA9IHggPCBJbnRlZ2VyLk1JTl9WQUxVRSA/IEludGVnZXIuTUlOX1ZBTFVFIDogeCA+IEludGVnZXIuTUFYX1ZBTFVFID8gSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgICAgICAgICAgICA6IHg7CisgICAgICAgIHkgPSB5IDwgSW50ZWdlci5NSU5fVkFMVUUgPyBJbnRlZ2VyLk1JTl9WQUxVRSA6IHkgPiBJbnRlZ2VyLk1BWF9WQUxVRSA/IEludGVnZXIuTUFYX1ZBTFVFCisgICAgICAgICAgICAgICAgOiB5OworICAgICAgICBzZXRMb2NhdGlvbigoaW50KU1hdGgucm91bmQoeCksIChpbnQpTWF0aC5yb3VuZCh5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW92ZXMgdGhlIFBvaW50IHRvIHRoZSBzcGVjaWZpZWQgKHgsIHkpIGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBuZXcgbG9jYXRpb24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBsb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtb3ZlKGludCB4LCBpbnQgeSkgeworICAgICAgICBzZXRMb2NhdGlvbih4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdGVzIGN1cnJlbnQgUG9pbnQgbW92aW5nIGl0IGZyb20gdGhlIHBvc2l0aW9uICh4LCB5KSB0byB0aGUgbmV3CisgICAgICogcG9zaXRpb24gZ2l2ZW4gYnkgKHgrZHgsIHgrZHkpIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkeAorICAgICAqICAgICAgICAgICAgdGhlIGhvcml6b250YWwgZGVsdGEgLSB0aGUgUG9pbnQgaXMgbW92ZWQgdG8gdGhpcyBkaXN0YW5jZQorICAgICAqICAgICAgICAgICAgYWxvbmcgWCBheGlzLgorICAgICAqIEBwYXJhbSBkeQorICAgICAqICAgICAgICAgICAgdGhlIHZlcnRpY2FsIGRlbHRhIC0gdGhlIFBvaW50IGlzIG1vdmVkIHRvIHRoaXMgZGlzdGFuY2UgYWxvbmcKKyAgICAgKiAgICAgICAgICAgIFkgYXhpcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoaW50IGR4LCBpbnQgZHkpIHsKKyAgICAgICAgeCArPSBkeDsKKyAgICAgICAgeSArPSBkeTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9Qb2x5Z29uLmphdmEgYi9hd3QvamF2YS9hd3QvUG9seWdvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlMzFlYjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvUG9seWdvbi5qYXZhCkBAIC0wLDAgKzEsNTE1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgUG9seWdvbiBjbGFzcyBkZWZpbmVzIGFuIGNsb3NlZCBhcmVhIHNwZWNpZmllZCBieSBuIHZlcnRpY2VzIGFuZCBuIGVkZ2VzLgorICogVGhlIGNvb3JkaW5hdGVzIG9mIHRoZSB2ZXJ0aWNlcyBhcmUgc3BlY2lmaWVkIGJ5IHgsIHkgYXJyYXlzLiBUaGUgZWRnZXMgYXJlCisgKiB0aGUgbGluZSBzZWdtZW50cyBmcm9tIHRoZSBwb2ludCAoeFtpXSwgeVtpXSkgdG8gdGhlIHBvaW50ICh4W2krMV0sIHlbaSsxXSksCisgKiBmb3IgLTEgPCBpIDwgKG4tMSkgcGx1cyB0aGUgbGluZSBzZWdtZW50IGZyb20gdGhlIHBvaW50ICh4W24tMV0sIHlbbi0xXSkgdG8KKyAqIHRoZSBwb2ludCAoeFswXSwgeVswXSkgcG9pbnQuIFRoZSBQb2x5Z29uIGlzIGVtcHR5IGlmIHRoZSBudW1iZXIgb2YgdmVydGljZXMKKyAqIGlzIHplcm8uCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUG9seWdvbiBpbXBsZW1lbnRzIFNoYXBlLCBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY0NjAwNjE0Mzc5MDAwNjk5NjlMOworCisgICAgLyoqCisgICAgICogVGhlIHBvaW50cyBidWZmZXIgY2FwYWNpdHkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9DQVBBQ0lUWSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIFBvbHlnb24gdmVydGljZXMuCisgICAgICovCisgICAgcHVibGljIGludCBucG9pbnRzOworCisgICAgLyoqCisgICAgICogVGhlIGFycmF5IG9mIFggY29vcmRpbmF0ZXMgb2YgdGhlIHZlcnRpY2VzLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSB4cG9pbnRzOworCisgICAgLyoqCisgICAgICogVGhlIGFycmF5IG9mIFkgY29vcmRpbmF0ZXMgb2YgdGhlIHZlcnRpY2VzLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSB5cG9pbnRzOworCisgICAgLyoqCisgICAgICogVGhlIHNtYWxsZXN0IFJlY3RhbmdsZSB0aGF0IGNvbXBsZXRlbHkgY29udGFpbnMgdGhpcyBQb2x5Z29uLgorICAgICAqLworICAgIHByb3RlY3RlZCBSZWN0YW5nbGUgYm91bmRzOworCisgICAgLyoKKyAgICAgKiBQb2x5Z29uIHBhdGggaXRlcmF0b3IKKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZXJuYWwgQ2xhc3MgSXRlcmF0b3IuCisgICAgICovCisgICAgY2xhc3MgSXRlcmF0b3IgaW1wbGVtZW50cyBQYXRoSXRlcmF0b3IgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgc291cmNlIFBvbHlnb24gb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBvbHlnb24gcDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBhdGggaXRlcmF0b3IgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjdXJyZW50IHNlZ21lbnQgaW5kZXguCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFBvbHlnb24uSXRlcmF0b3IgZm9yIHRoZSBnaXZlbiBwb2x5Z29uIGFuZAorICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGF0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybSBvYmplY3QgdG8gYXBwbHkgcmVjdGFuZ2xlIHBhdGguCisgICAgICAgICAqIEBwYXJhbSBwCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHAuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIGF0LCBQb2x5Z29uIHApIHsKKyAgICAgICAgICAgIHRoaXMucCA9IHA7CisgICAgICAgICAgICB0aGlzLnQgPSBhdDsKKyAgICAgICAgICAgIGlmIChwLm5wb2ludHMgPT0gMCkgeworICAgICAgICAgICAgICAgIGluZGV4ID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9FVkVOX09ERDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IHAubnBvaW50czsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIG5leHQoKSB7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjdXJyZW50U2VnbWVudChkb3VibGVbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4xMTA9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjExMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ID09IHAubnBvaW50cykgeworICAgICAgICAgICAgICAgIHJldHVybiBTRUdfQ0xPU0U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb29yZHNbMF0gPSBwLnhwb2ludHNbaW5kZXhdOworICAgICAgICAgICAgY29vcmRzWzFdID0gcC55cG9pbnRzW2luZGV4XTsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW5kZXggPT0gMCA/IFNFR19NT1ZFVE8gOiBTRUdfTElORVRPOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjdXJyZW50U2VnbWVudChmbG9hdFtdIGNvb3JkcykgeworICAgICAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjExMD1JdGVyYXRvciBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTEwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gcC5ucG9pbnRzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFNFR19DTE9TRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvb3Jkc1swXSA9IHAueHBvaW50c1tpbmRleF07CisgICAgICAgICAgICBjb29yZHNbMV0gPSBwLnlwb2ludHNbaW5kZXhdOworICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpbmRleCA9PSAwID8gU0VHX01PVkVUTyA6IFNFR19MSU5FVE87CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZW1wdHkgcG9seWdvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9seWdvbigpIHsKKyAgICAgICAgeHBvaW50cyA9IG5ldyBpbnRbQlVGRkVSX0NBUEFDSVRZXTsKKyAgICAgICAgeXBvaW50cyA9IG5ldyBpbnRbQlVGRkVSX0NBUEFDSVRZXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcG9seWdvbiB3aXRoIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHZlcnRpY2VzLCBhbmQgdGhlCisgICAgICogZ2l2ZW4gYXJyYXlzIG9mIHgsIHkgdmVydGV4IGNvb3JkaW5hdGVzLiBUaGUgbGVuZ3RoIG9mIGVhY2ggY29vcmRpbmF0ZQorICAgICAqIGFycmF5IG1heSBub3QgYmUgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHZlcnRpY2VzIGJ1dCBtYXkgYmUKKyAgICAgKiBncmVhdGVyLiBPbmx5IHRoZSBmaXJzdCBuIGVsZW1lbnRzIGFyZSB1c2VkIGZyb20gZWFjaCBjb29yZGluYXRlIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4cG9pbnRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgWCB2ZXJ0ZXggY29vcmRpbmF0ZXMuCisgICAgICogQHBhcmFtIHlwb2ludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBZIHZlcnRleCBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gbnBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciB2ZXJ0aWNlcyBvZiB0aGUgcG9seWdvbi4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbGVuZ3RoIG9mIHhwb2ludHMgb3IgeXBvaW50cyBpcyBsZXNzIHRoYW4gbi4KKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbiBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9seWdvbihpbnRbXSB4cG9pbnRzLCBpbnRbXSB5cG9pbnRzLCBpbnQgbnBvaW50cykgeworICAgICAgICBpZiAobnBvaW50cyA+IHhwb2ludHMubGVuZ3RoIHx8IG5wb2ludHMgPiB5cG9pbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgLy8gYXd0LjExMT1QYXJhbWV0ZXIgbnBvaW50cyBpcyBncmVhdGVyIHRoYW4gYXJyYXkgbGVuZ3RoCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xMTEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAobnBvaW50cyA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4xMTI9TmVnYXRpdmUgbnVtYmVyIG9mIHBvaW50cworICAgICAgICAgICAgdGhyb3cgbmV3IE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjExMiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHRoaXMubnBvaW50cyA9IG5wb2ludHM7CisgICAgICAgIHRoaXMueHBvaW50cyA9IG5ldyBpbnRbbnBvaW50c107CisgICAgICAgIHRoaXMueXBvaW50cyA9IG5ldyBpbnRbbnBvaW50c107CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoeHBvaW50cywgMCwgdGhpcy54cG9pbnRzLCAwLCBucG9pbnRzKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh5cG9pbnRzLCAwLCB0aGlzLnlwb2ludHMsIDAsIG5wb2ludHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgY3VycmVudCBQb2x5Z29uIHRvIGFuIGVtcHR5IFBvbHlnb24uIE1vcmUgcHJlY2lzZWx5LCB0aGUKKyAgICAgKiBudW1iZXIgb2YgUG9seWdvbiB2ZXJ0aWNlcyBpcyBzZXQgdG8gemVybywgYnV0IHgsIHkgY29vcmRpbmF0ZXMgYXJyYXlzCisgICAgICogYXJlIG5vdCBhZmZlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgbnBvaW50cyA9IDA7CisgICAgICAgIGJvdW5kcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52YWxpZGF0ZXMgdGhlIGRhdGEgdGhhdCBkZXBlbmRzIG9uIHRoZSB2ZXJ0ZXggY29vcmRpbmF0ZXMuIFRoaXMgbWV0aG9kCisgICAgICogc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBkaXJlY3QgbWFuaXB1bGF0aW9ucyBvZiB0aGUgeCwgeSB2ZXJ0ZXgKKyAgICAgKiBjb29yZGluYXRlcyBhcnJheXMgdG8gYXZvaWQgdW5wcmVkaWN0YWJsZSByZXN1bHRzIG9mIG1ldGhvZHMgd2hpY2ggcmVseQorICAgICAqIG9uIHRoZSBib3VuZGluZyBib3guCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW52YWxpZGF0ZSgpIHsKKyAgICAgICAgYm91bmRzID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBwb2ludCB0byB0aGUgUG9seWdvbiBhbmQgdXBkYXRlcyB0aGUgYm91bmRpbmcgYm94IGFjY29yZGluZ2x5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgYWRkZWQgdmVydGV4LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgYWRkZWQgdmVydGV4LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFBvaW50KGludCBweCwgaW50IHB5KSB7CisgICAgICAgIGlmIChucG9pbnRzID09IHhwb2ludHMubGVuZ3RoKSB7CisgICAgICAgICAgICBpbnRbXSB0bXA7CisKKyAgICAgICAgICAgIHRtcCA9IG5ldyBpbnRbeHBvaW50cy5sZW5ndGggKyBCVUZGRVJfQ0FQQUNJVFldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh4cG9pbnRzLCAwLCB0bXAsIDAsIHhwb2ludHMubGVuZ3RoKTsKKyAgICAgICAgICAgIHhwb2ludHMgPSB0bXA7CisKKyAgICAgICAgICAgIHRtcCA9IG5ldyBpbnRbeXBvaW50cy5sZW5ndGggKyBCVUZGRVJfQ0FQQUNJVFldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh5cG9pbnRzLCAwLCB0bXAsIDAsIHlwb2ludHMubGVuZ3RoKTsKKyAgICAgICAgICAgIHlwb2ludHMgPSB0bXA7CisgICAgICAgIH0KKworICAgICAgICB4cG9pbnRzW25wb2ludHNdID0gcHg7CisgICAgICAgIHlwb2ludHNbbnBvaW50c10gPSBweTsKKyAgICAgICAgbnBvaW50cysrOworCisgICAgICAgIGlmIChib3VuZHMgIT0gbnVsbCkgeworICAgICAgICAgICAgYm91bmRzLnNldEZyYW1lRnJvbURpYWdvbmFsKE1hdGgubWluKGJvdW5kcy5nZXRNaW5YKCksIHB4KSwgTWF0aC5taW4oYm91bmRzLmdldE1pblkoKSwKKyAgICAgICAgICAgICAgICAgICAgcHkpLCBNYXRoLm1heChib3VuZHMuZ2V0TWF4WCgpLCBweCksIE1hdGgubWF4KGJvdW5kcy5nZXRNYXhZKCksIHB5KSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhlIFBvbHlnb24uIFRoZSBib3VuZGluZyByZWN0YW5nbGUgaXMgdGhlCisgICAgICogc21hbGxlc3QgcmVjdGFuZ2xlIHdoaWNoIGNvbnRhaW5zIHRoZSBQb2x5Z29uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSBvZiB0aGUgUG9seWdvbi4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlNoYXBlI2dldEJvdW5kcygpCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKSB7CisgICAgICAgIGlmIChib3VuZHMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICAgICAgfQorICAgICAgICBpZiAobnBvaW50cyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZSgpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGJ4MSA9IHhwb2ludHNbMF07CisgICAgICAgIGludCBieTEgPSB5cG9pbnRzWzBdOworICAgICAgICBpbnQgYngyID0gYngxOworICAgICAgICBpbnQgYnkyID0gYnkxOworCisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbnBvaW50czsgaSsrKSB7CisgICAgICAgICAgICBpbnQgeCA9IHhwb2ludHNbaV07CisgICAgICAgICAgICBpbnQgeSA9IHlwb2ludHNbaV07CisgICAgICAgICAgICBpZiAoeCA8IGJ4MSkgeworICAgICAgICAgICAgICAgIGJ4MSA9IHg7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHggPiBieDIpIHsKKyAgICAgICAgICAgICAgICBieDIgPSB4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHkgPCBieTEpIHsKKyAgICAgICAgICAgICAgICBieTEgPSB5OworICAgICAgICAgICAgfSBlbHNlIGlmICh5ID4gYnkyKSB7CisgICAgICAgICAgICAgICAgYnkyID0geTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBib3VuZHMgPSBuZXcgUmVjdGFuZ2xlKGJ4MSwgYnkxLCBieDIgLSBieDEsIGJ5MiAtIGJ5MSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIG9mIHRoZSBQb2x5Z29uLiBUaGUgYm91bmRpbmcgcmVjdGFuZ2xlIGlzIHRoZQorICAgICAqIHNtYWxsZXN0IHJlY3RhbmdsZSB3aGljaCBjb250YWlucyB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhlIFBvbHlnb24uCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIGdldEJvdW5kcygpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRpbmdCb3goKSB7CisgICAgICAgIHJldHVybiBnZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBSZWN0YW5nbGUyRCB3aGljaCByZXByZXNlbnRzIFBvbHlnb24gYm91bmRzLiBUaGUgYm91bmRpbmcKKyAgICAgKiByZWN0YW5nbGUgaXMgdGhlIHNtYWxsZXN0IHJlY3RhbmdsZSB3aGljaCBjb250YWlucyB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhlIFBvbHlnb24uCisgICAgICogQHNlZSBqYXZhLmF3dC5TaGFwZSNnZXRCb3VuZHMyRCgpCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICByZXR1cm4gZ2V0Qm91bmRzKCkuZ2V0Qm91bmRzMkQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdGVzIGFsbCB2ZXJ0aWNlcyBvZiBQb2x5Z29uIHRoZSBzcGVjaWZpZWQgZGlzdGFuY2VzIGFsb25nIFgsIFkKKyAgICAgKiBheGlzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBteAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBob3Jpem9udGFsbHkuCisgICAgICogQHBhcmFtIG15CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIHZlcnRpY2FsbHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKGludCBteCwgaW50IG15KSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnBvaW50czsgaSsrKSB7CisgICAgICAgICAgICB4cG9pbnRzW2ldICs9IG14OworICAgICAgICAgICAgeXBvaW50c1tpXSArPSBteTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYm91bmRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJvdW5kcy50cmFuc2xhdGUobXgsIG15KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGUgcG9pbnQgZ2l2ZW4gYnkgdGhlIGNvb3JkaW5hdGVzIHgsIHkgbGllcyBpbnNpZGUKKyAgICAgKiB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBwb2ludCBsaWVzIGluc2lkZSB0aGUgUG9seWdvbiwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2UgY29udGFpbnMoaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIGluc2lkZShpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKChkb3VibGUpeCwgKGRvdWJsZSl5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHBvaW50IGdpdmVuIGJ5IHRoZSBjb29yZGluYXRlcyB4LCB5IGxpZXMgaW5zaWRlCisgICAgICogdGhlIFBvbHlnb24uCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcG9pbnQgbGllcyBpbnNpZGUgdGhlIFBvbHlnb24sIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoaW50IHgsIGludCB5KSB7CisgICAgICAgIHJldHVybiBjb250YWlucygoZG91YmxlKXgsIChkb3VibGUpeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBwb2ludCB3aXRoIHNwZWNpZmllZCBkb3VibGUgY29vcmRpbmF0ZXMgbGllcworICAgICAqIGluc2lkZSB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHBvaW50IGdpdmVuIGJ5IHRoZSBkb3VibGUgY29vcmRpbmF0ZXMgbGllcyBpbnNpZGUKKyAgICAgKiAgICAgICAgIHRoZSBQb2x5Z29uLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQHNlZSBqYXZhLmF3dC5TaGFwZSNjb250YWlucyhkb3VibGUsIGRvdWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgcmV0dXJuIENyb3NzaW5nLmlzSW5zaWRlRXZlbk9kZChDcm9zc2luZy5jcm9zc1NoYXBlKHRoaXMsIHgsIHkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHJlY3RhbmdsZSBkZXRlcm1pbmVkIGJ5IHRoZSBwYXJhbWV0ZXJzIFt4LCB5LAorICAgICAqIHdpZHRoLCBoZWlnaHRdIGxpZXMgaW5zaWRlIHRoZSBQb2x5Z29uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGVzJ3MgbGVmdCB1cHBlciBjb3JuZXIgYXMgYQorICAgICAqICAgICAgICAgICAgZG91YmxlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGVzJ3MgbGVmdCB1cHBlciBjb3JuZXIgYXMgYQorICAgICAqICAgICAgICAgICAgZG91YmxlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZSBhcyBhIGRvdWJsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZSBhcyBhIGRvdWJsZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGxpZXMgaW5zaWRlIHRoZSBQb2x5Z29uLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgamF2YS5hd3QuU2hhcGUjY29udGFpbnMoZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgIGludCBjcm9zcyA9IENyb3NzaW5nLmludGVyc2VjdFNoYXBlKHRoaXMsIHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICByZXR1cm4gY3Jvc3MgIT0gQ3Jvc3NpbmcuQ1JPU1NJTkcgJiYgQ3Jvc3NpbmcuaXNJbnNpZGVFdmVuT2RkKGNyb3NzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHJlY3RhbmdsZSBkZXRlcm1pbmVkIGJ5IHRoZSBwYXJhbWV0ZXJzIFt4LCB5LAorICAgICAqIHdpZHRoLCBoZWlnaHRdIGludGVyc2VjdHMgdGhlIGludGVyaW9yIG9mIHRoZSBQb2x5Z29uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGVzJ3MgbGVmdCB1cHBlciBjb3JuZXIgYXMgYQorICAgICAqICAgICAgICAgICAgZG91YmxlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGVzJ3MgbGVmdCB1cHBlciBjb3JuZXIgYXMgYQorICAgICAqICAgICAgICAgICAgZG91YmxlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZSBhcyBhIGRvdWJsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZSBhcyBhIGRvdWJsZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGludGVyc2VjdHMgdGhlIGludGVyaW9yIG9mIHRoZQorICAgICAqICAgICAgICAgUG9seWdvbiwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgamF2YS5hd3QuU2hhcGUjaW50ZXJzZWN0cyhkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCkgeworICAgICAgICBpbnQgY3Jvc3MgPSBDcm9zc2luZy5pbnRlcnNlY3RTaGFwZSh0aGlzLCB4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgcmV0dXJuIGNyb3NzID09IENyb3NzaW5nLkNST1NTSU5HIHx8IENyb3NzaW5nLmlzSW5zaWRlRXZlbk9kZChjcm9zcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGxpZXMgaW5zaWRlIHRoZSBQb2x5Z29uLgorICAgICAqIAorICAgICAqIEBwYXJhbSByZWN0CisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgbGllcyBpbnNpZGUgdGhlIFBvbHlnb24sIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSBqYXZhLmF3dC5TaGFwZSNjb250YWlucyhqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZTJEIHJlY3QpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHJlY3QuZ2V0WCgpLCByZWN0LmdldFkoKSwgcmVjdC5nZXRXaWR0aCgpLCByZWN0LmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBQb2ludCBsaWVzIGluc2lkZSB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludCBvYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIFBvaW50IGxpZXMgaW5zaWRlIHRoZSBQb2x5Z29uLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFBvaW50IHBvaW50KSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhwb2ludC5nZXRYKCksIHBvaW50LmdldFkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgUG9pbnQyRCBsaWVzIGluc2lkZSB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludDJEIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgUG9pbnQyRCBsaWVzIGluc2lkZSB0aGUgUG9seWdvbiwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlNoYXBlI2NvbnRhaW5zKGphdmEuYXd0Lmdlb20uUG9pbnQyRCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludDJEIHBvaW50KSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhwb2ludC5nZXRYKCksIHBvaW50LmdldFkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBpbnRlcmlvciBvZiByZWN0YW5nbGUgc3BlY2lmaWVkIGJ5IHRoZQorICAgICAqIFJlY3RhbmdsZTJEIG9iamVjdCBpbnRlcnNlY3RzIHRoZSBpbnRlcmlvciBvZiB0aGUgUG9seWdvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVjdAorICAgICAqICAgICAgICAgICAgdGhlIFJlY3RhbmdsZTJEIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBSZWN0YW5nbGUyRCBpbnRlcnNlY3RzIHRoZSBpbnRlcmlvciBvZiB0aGUgUG9seWdvbiwKKyAgICAgKiAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlNoYXBlI2ludGVyc2VjdHMoamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHJlY3QpIHsKKyAgICAgICAgcmV0dXJuIGludGVyc2VjdHMocmVjdC5nZXRYKCksIHJlY3QuZ2V0WSgpLCByZWN0LmdldFdpZHRoKCksIHJlY3QuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFBhdGhJdGVyYXRvciBvYmplY3Qgd2hpY2ggZ2l2ZXMgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2x5Z29uLAorICAgICAqIHRyYW5zZm9ybWVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBBZmZpbmVUcmFuc2Zvcm0gb2JqZWN0IG9yIG51bGwuCisgICAgICogQHJldHVybiBQYXRoSXRlcmF0b3Igb2JqZWN0IGZvciB0aGUgUG9seWdvbi4KKyAgICAgKiBAc2VlIGphdmEuYXd0LlNoYXBlI2dldFBhdGhJdGVyYXRvcihqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybSkKKyAgICAgKi8KKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKHQsIHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFBhdGhJdGVyYXRvciBvYmplY3Qgd2hpY2ggZ2l2ZXMgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2x5Z29uLAorICAgICAqIHRyYW5zZm9ybWVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybS4gVGhlIGZsYXRuZXNzCisgICAgICogcGFyYW1ldGVyIGlzIGlnbm9yZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgQWZmaW5lVHJhbnNmb3JtIG9iamVjdCBvciBudWxsLgorICAgICAqIEBwYXJhbSBmbGF0bmVzcworICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIHRoZSBjb250cm9sIHBvaW50cyBmb3IgYSBnaXZlbiBjdXJ2ZQorICAgICAqICAgICAgICAgICAgd2hpY2ggdmFyaWVzIGZyb20gY29saW5lYXIgYmVmb3JlIGEgc3ViZGl2aWRlZCBjdXJ2ZSBpcworICAgICAqICAgICAgICAgICAgcmVwbGFjZWQgYnkgYSBzdHJhaWdodCBsaW5lIGNvbm5lY3RpbmcgdGhlIGVuZHBvaW50cy4gVGhpcworICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIGlzIGlnbm9yZWQgZm9yIHRoZSBQb2x5Z29uIGNsYXNzLgorICAgICAqIEByZXR1cm4gUGF0aEl0ZXJhdG9yIG9iamVjdCBmb3IgdGhlIFBvbHlnb24uCisgICAgICogQHNlZSBqYXZhLmF3dC5TaGFwZSNnZXRQYXRoSXRlcmF0b3IoamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm0sCisgICAgICogICAgICBkb3VibGUpCisgICAgICovCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIHQsIGRvdWJsZSBmbGF0bmVzcykgeworICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKHQsIHRoaXMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L1JlY3RhbmdsZS5qYXZhIGIvYXd0L2phdmEvYXd0L1JlY3RhbmdsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4ZWJiM2EKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvUmVjdGFuZ2xlLmphdmEKQEAgLTAsMCArMSw3MjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBUaGUgUmVjdGFuZ2xlIGNsYXNzIGRlZmluZXMgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgaW4gdGVybXMgb2YgaXRzIHVwcGVyIGxlZnQKKyAqIGNvcm5lciBjb29yZGluYXRlcyBbeCx5XSwgaXRzIHdpZHRoLCBhbmQgaXRzIGhlaWdodC4gQSBSZWN0YW5nbGUgc3BlY2lmaWVkIGJ5CisgKiBbeCwgeSwgd2lkdGgsIGhlaWdodF0gcGFyYW1ldGVycyBoYXMgYW4gb3V0bGluZSBwYXRoIHdpdGggY29ybmVycyBhdCBbeCwgeV0sCisgKiBbeCArIHdpZHRoLHldLCBbeCArIHdpZHRoLHkgKyBoZWlnaHRdLCBhbmQgW3gsIHkgKyBoZWlnaHRdLiA8YnI+CisgKiA8YnI+CisgKiBUaGUgcmVjdGFuZ2xlIGlzIGVtcHR5IGlmIHRoZSB3aWR0aCBvciBoZWlnaHQgaXMgbmVnYXRpdmUgb3IgemVyby4gSW4gdGhpcworICogY2FzZSB0aGUgaXNFbXB0eSBtZXRob2QgcmV0dXJucyB0cnVlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFJlY3RhbmdsZSBleHRlbmRzIFJlY3RhbmdsZTJEIGltcGxlbWVudHMgU2hhcGUsIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDM0NTg1NzA3MDI1NTY3NDc2NEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyBsZWZ0IHVwcGVyIGNvcm5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyBsZWZ0IHVwcGVyIGNvcm5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgd2lkdGg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhlaWdodDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyByZWN0YW5nbGUgd2l0aCBbMCwgMF0gdXBwZXIgbGVmdCBjb3JuZXIgY29vcmRpbmF0ZXMsCisgICAgICogdGhlIHdpZHRoIGFuZCB0aGUgaGVpZ2h0IGFyZSB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUoKSB7CisgICAgICAgIHNldEJvdW5kcygwLCAwLCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVjdGFuZ2xlIHdob3NlIHVwcGVyIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzIGFyZQorICAgICAqIGdpdmVuIGJ5IHRoZSBQb2ludCBvYmplY3QgKHAuWCBhbmQgcC5ZKSwgYW5kIHRoZSB3aWR0aCBhbmQgdGhlIGhlaWdodCBhcmUKKyAgICAgKiB6ZXJvLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgUG9pbnQgc3BlY2lmaWVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBjb29yZGluYXRlcyBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlKFBvaW50IHApIHsKKyAgICAgICAgc2V0Qm91bmRzKHAueCwgcC55LCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVjdGFuZ2xlIHdob3NlIHVwcGVyIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzIGFyZQorICAgICAqIGdpdmVuIGJ5IHRoZSBQb2ludCBvYmplY3QgKHAuWCBhbmQgcC5ZKSwgYW5kIHRoZSB3aWR0aCBhbmQgdGhlIGhlaWdodCBhcmUKKyAgICAgKiBnaXZlbiBieSBEaW1lbnNpb24gb2JqZWN0IChkLndpZHRoIGFuZCBkLmhlaWdodCkuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBzcGVjaWZpZXMgdGhlIHVwcGVyIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzIG9mIHRoZQorICAgICAqICAgICAgICAgICAgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgZGltZW5zaW9uIHNwZWNpZmllcyB0aGUgd2lkdGggYW5kIHRoZSBoZWlnaHQgb2YgdGhlCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZShQb2ludCBwLCBEaW1lbnNpb24gZCkgeworICAgICAgICBzZXRCb3VuZHMocC54LCBwLnksIGQud2lkdGgsIGQuaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVjdGFuZ2xlIGRldGVybWluZWQgYnkgdGhlIHVwcGVyIGxlZnQgY29ybmVyCisgICAgICogY29vcmRpbmF0ZXMgKHgsIHkpLCB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCB1cHBlciBsZWZ0IGNvcm5lciBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIHVwcGVyIGxlZnQgY29ybmVyIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZShpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBzZXRCb3VuZHMoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHJlY3RhbmdsZSB3aXRoIFswLCAwXSBhcyBpdHMgdXBwZXIgbGVmdCBjb3JuZXIKKyAgICAgKiBjb29yZGluYXRlcyBhbmQgdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlKGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBzZXRCb3VuZHMoMCwgMCwgd2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHJlY3RhbmdsZSB3aXRoIHRoZSBzYW1lIGNvb3JkaW5hdGVzIGFzIHRoZSBnaXZlbgorICAgICAqIHNvdXJjZSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgb2JqZWN0IHdoaWNoIHBhcmFtZXRlcnMgd2lsbCBiZSB1c2VkIGZvcgorICAgICAqICAgICAgICAgICAgaW5zdGFudGlhdGluZyBhIG5ldyBSZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZShSZWN0YW5nbGUgcikgeworICAgICAgICBzZXRCb3VuZHMoci54LCByLnksIHIud2lkdGgsIHIuaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHB1YmxpYyBSZWN0YW5nbGUoRGltZW5zaW9uIGQpIHsgc2V0Qm91bmRzKDAsIDAsIGQud2lkdGgsIGQuaGVpZ2h0KTsgfQorICAgICAqLworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFggY29vcmRpbmF0ZSBvZiBib3VuZCBhcyBhIGRvdWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBYIGNvb3JkaW5hdGUgb2YgYm91bmQgYXMgYSBkb3VibGUuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlJlY3Rhbmd1bGFyU2hhcGUjZ2V0WCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBnZXRYKCkgeworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBZIGNvb3JkaW5hdGUgb2YgYm91bmQgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgWSBjb29yZGluYXRlIG9mIGJvdW5kIGFzIGEgZG91YmxlLgorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5SZWN0YW5ndWxhclNoYXBlI2dldFkoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0WSgpIHsKKyAgICAgICAgcmV0dXJuIHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgYXMgYSBkb3VibGUuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlJlY3Rhbmd1bGFyU2hhcGUjZ2V0SGVpZ2h0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIGFzIGEgZG91YmxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgYXMgYSBkb3VibGUuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlJlY3Rhbmd1bGFyU2hhcGUjZ2V0V2lkdGgoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0V2lkdGgoKSB7CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRoZSByZWN0YW5nbGUgaXMgZW1wdHkuIFRoZSByZWN0YW5nbGUgaXMgZW1wdHkKKyAgICAgKiBpZiBpdHMgd2lkdGggb3IgaGVpZ2h0IGlzIG5lZ2F0aXZlIG9yIHplcm8uCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgcmVjdGFuZ2xlIGlzIGVtcHR5LCBvdGhlcndpc2UgZmFsc2UuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlJlY3Rhbmd1bGFyU2hhcGUjaXNFbXB0eSgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBvZiBhIFJlY3RhbmdsZSBhcyBEaW1lbnNpb24gb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBEaW1lbnNpb24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgc2l6ZSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBEaW1lbnNpb24gZ2V0U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24od2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2l6ZSBvZiB0aGUgUmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzaXplIG9mIGEgUmVjdGFuZ2xlIHNwZWNpZmllZCBhcyBEaW1lbnNpb24gb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICBhIERpbWVuc2lvbiBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyBuZXcgc2l6ZSBvZiBhIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaXplKERpbWVuc2lvbiBkKSB7CisgICAgICAgIHNldFNpemUoZC53aWR0aCwgZC5oZWlnaHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2F0aW9uIG9mIGEgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIgYXMgYSBQb2ludCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUG9pbnQgb2JqZWN0IHdpdGggY29vcmRpbmF0ZXMgZXF1YWwgdG8gdGhlIHVwcGVyIGxlZnQgY29ybmVyCisgICAgICogICAgICAgICBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQb2ludCh4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVjdGFuZ2xlIGluIHRlcm1zIG9mIGl0cyB1cHBlciBsZWZ0IGNvcm5lcgorICAgICAqIGNvb3JkaW5hdGVzIFggYW5kIFkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgdGhpcy55ID0geTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2NhdGlvbiBvZiBhIHJlY3RhbmdsZSB1c2luZyBhIFBvaW50IG9iamVjdCB0byBnaXZlIHRoZQorICAgICAqIGNvb3JkaW5hdGVzIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBvaW50IG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBuZXcgdXBwZXIgbGVmdCBjb3JuZXIKKyAgICAgKiAgICAgICAgICAgIGNvb3JkaW5hdGVzIG9mIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihQb2ludCBwKSB7CisgICAgICAgIHNldExvY2F0aW9uKHAueCwgcC55KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyBhIHJlY3RhbmdsZSB0byB0aGUgbmV3IGxvY2F0aW9uIGJ5IG1vdmluZyBpdHMgdXBwZXIgbGVmdCBjb3JuZXIgdG8KKyAgICAgKiB0aGUgcG9pbnQgd2l0aCBjb29yZGluYXRlcyBYIGFuZCBZLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Ugc2V0TG9jYXRpb24oaW50LCBpbnQpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIG1vdmUoaW50IHgsIGludCB5KSB7CisgICAgICAgIHNldExvY2F0aW9uKHgsIHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJlY3RhbmdsZSB0byBiZSB0aGUgbmVhcmVzdCByZWN0YW5nbGUgd2l0aCBpbnRlZ2VyIGNvb3JkaW5hdGVzCisgICAgICogYm91bmRpbmcgdGhlIHJlY3RhbmdsZSBkZWZpbmVkIGJ5IHRoZSBkb3VibGUtdmFsdWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBkb3VibGUtdmFsdWVkCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUgdG8gYmUgYm91bmRlZC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIGRvdWJsZS12YWx1ZWQKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZSB0byBiZSBib3VuZGVkLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgdG8gYmUgYm91bmRlZC4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgdG8gYmUgYm91bmRlZC4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQjc2V0UmVjdChkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVjdChkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCkgeworICAgICAgICBpbnQgeDEgPSAoaW50KU1hdGguZmxvb3IoeCk7CisgICAgICAgIGludCB5MSA9IChpbnQpTWF0aC5mbG9vcih5KTsKKyAgICAgICAgaW50IHgyID0gKGludClNYXRoLmNlaWwoeCArIHdpZHRoKTsKKyAgICAgICAgaW50IHkyID0gKGludClNYXRoLmNlaWwoeSArIGhlaWdodCk7CisgICAgICAgIHNldEJvdW5kcyh4MSwgeTEsIHgyIC0geDEsIHkyIC0geTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBuZXcgc2l6ZSBmb3IgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWN0YW5nbGUncyBuZXcgd2lkdGguCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHJlY3RhbmdsZSdzIG5ldyBoZWlnaHQuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHRoZSBzZXRTaXplKGludCwgaW50KSBtZXRob2QuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCByZXNpemUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHNldEJvdW5kcyh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIGJvdW5kcyBvZiBhIHJlY3RhbmdsZSB0byB0aGUgc3BlY2lmaWVkIHgsIHksIHdpZHRoIGFuZCBoZWlnaHQKKyAgICAgKiBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Ugc2V0Qm91bmRzKGludCwgaW50LCBpbnQsIGludCkgbWV0aG9kCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCByZXNoYXBlKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHNldEJvdW5kcyh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGJvdW5kcyBvZiB0aGUgcmVjdGFuZ2xlIGFzIGEgbmV3IFJlY3RhbmdsZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUmVjdGFuZ2xlIG9iamVjdCB3aXRoIHRoZSBzYW1lIGJvdW5kcyBhcyB0aGUgb3JpZ2luYWwKKyAgICAgKiAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uUmVjdGFuZ3VsYXJTaGFwZSNnZXRCb3VuZHMoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZSh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSBhcyBhIFJlY3RhbmdsZTJEIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBSZWN0YW5nbGUyRCBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgYm91bmRzIG9mIHRoZQorICAgICAqICAgICAgICAgb3JpZ2luYWwgcmVjdGFuZ2xlLgorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRCNnZXRCb3VuZHMyRCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICByZXR1cm4gZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYm91bmRzIG9mIGEgcmVjdGFuZ2xlIHRvIHRoZSBzcGVjaWZpZWQgeCwgeSwgd2lkdGgsIGFuZCBoZWlnaHQKKyAgICAgKiBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJvdW5kcyhpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICB0aGlzLnggPSB4OworICAgICAgICB0aGlzLnkgPSB5OworICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJvdW5kcyBvZiB0aGUgcmVjdGFuZ2xlIHRvIG1hdGNoIHRoZSBib3VuZHMgb2YgdGhlIFJlY3RhbmdsZQorICAgICAqIG9iamVjdCBzZW50IGFzIGEgcGFyYW1ldGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlIG9iamVjdCB3aGljaCBzcGVjaWZpZXMgdGhlIG5ldyBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Qm91bmRzKFJlY3RhbmdsZSByKSB7CisgICAgICAgIHNldEJvdW5kcyhyLngsIHIueSwgci53aWR0aCwgci5oZWlnaHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVubGFyZ2VzIHRoZSByZWN0YW5nbGUgYnkgbW92aW5nIGVhY2ggY29ybmVyIG91dHdhcmQgZnJvbSB0aGUgY2VudGVyIGJ5IGEKKyAgICAgKiBkaXN0YW5jZSBvZiBkeCBob3Jpem9uYWxseSBhbmQgYSBkaXN0YW5jZSBvZiBkeSB2ZXJ0aWNhbGx5LiBTcGVjaWZpY2FsbHksCisgICAgICogY2hhbmdlcyBhIHJlY3RhbmdsZSB3aXRoIFt4LCB5LCB3aWR0aCwgaGVpZ2h0XSBwYXJhbWV0ZXJzIHRvIGEgcmVjdGFuZ2xlCisgICAgICogd2l0aCBbeC1keCwgeS1keSwgd2lkdGgrMipkeCwgaGVpZ2h0KzIqZHldIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGR4CisgICAgICogICAgICAgICAgICB0aGUgaG9yaXpvbnRhbCBkaXN0YW5jZSB0byBtb3ZlIGVhY2ggY29ybmVyIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGR5CisgICAgICogICAgICAgICAgICB0aGUgdmVydGljYWwgZGlzdGFuY2UgdG8gbW92ZSBlYWNoIGNvcm5lciBjb29yZGluYXRlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGdyb3coaW50IGR4LCBpbnQgZHkpIHsKKyAgICAgICAgeCAtPSBkeDsKKyAgICAgICAgeSAtPSBkeTsKKyAgICAgICAgd2lkdGggKz0gZHggKyBkeDsKKyAgICAgICAgaGVpZ2h0ICs9IGR5ICsgZHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW92ZXMgYSByZWN0YW5nbGUgYSBkaXN0YW5jZSBvZiBteCBhbG9uZyB0aGUgeCBjb29yZGluYXRlIGF4aXMgYW5kIGEKKyAgICAgKiBkaXN0YW5jZSBvZiBteSBhbG9uZyB5IGNvb3JkaW5hdGUgYXhpcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Jpem9udGFsIHRyYW5zbGF0aW9uIGluY3JlbWVudC4KKyAgICAgKiBAcGFyYW0gbXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJ0aWNhbCB0cmFuc2xhdGlvbiBpbmNyZW1lbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKGludCBteCwgaW50IG15KSB7CisgICAgICAgIHggKz0gbXg7CisgICAgICAgIHkgKz0gbXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5sYXJnZXMgdGhlIHJlY3RhbmdsZSB0byBjb3ZlciB0aGUgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgbmV3IHBvaW50IHRvIGJlIGNvdmVyZWQgYnkgdGhlCisgICAgICogICAgICAgICAgICByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBuZXcgcG9pbnQgdG8gYmUgY292ZXJlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IHB4LCBpbnQgcHkpIHsKKyAgICAgICAgaW50IHgxID0gTWF0aC5taW4oeCwgcHgpOworICAgICAgICBpbnQgeDIgPSBNYXRoLm1heCh4ICsgd2lkdGgsIHB4KTsKKyAgICAgICAgaW50IHkxID0gTWF0aC5taW4oeSwgcHkpOworICAgICAgICBpbnQgeTIgPSBNYXRoLm1heCh5ICsgaGVpZ2h0LCBweSk7CisgICAgICAgIHNldEJvdW5kcyh4MSwgeTEsIHgyIC0geDEsIHkyIC0geTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVubGFyZ2VzIHRoZSByZWN0YW5nbGUgdG8gY292ZXIgdGhlIHNwZWNpZmllZCBwb2ludCB3aXRoIHRoZSBuZXcgcG9pbnQKKyAgICAgKiBnaXZlbiBhcyBhIFBvaW50IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBvaW50IG9iamVjdCB0aGF0IHNwZWNpZmllcyB0aGUgbmV3IHBvaW50IHRvIGJlIGNvdmVyZWQgYnkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKFBvaW50IHApIHsKKyAgICAgICAgYWRkKHAueCwgcC55KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IHJlY3RhbmdsZSB0byB0aGUgb3JpZ2luYWwgcmVjdGFuZ2xlLCB0aGUgcmVzdWx0IGlzIGFuIHVuaW9uIG9mCisgICAgICogdGhlIHNwZWNpZmllZCBzcGVjaWZpZWQgcmVjdGFuZ2xlIGFuZCBvcmlnaW5hbCByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgd2hpY2ggaXMgYWRkZWQgdG8gdGhlIG9yaWdpbmFsIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoUmVjdGFuZ2xlIHIpIHsKKyAgICAgICAgaW50IHgxID0gTWF0aC5taW4oeCwgci54KTsKKyAgICAgICAgaW50IHgyID0gTWF0aC5tYXgoeCArIHdpZHRoLCByLnggKyByLndpZHRoKTsKKyAgICAgICAgaW50IHkxID0gTWF0aC5taW4oeSwgci55KTsKKyAgICAgICAgaW50IHkyID0gTWF0aC5tYXgoeSArIGhlaWdodCwgci55ICsgci5oZWlnaHQpOworICAgICAgICBzZXRCb3VuZHMoeDEsIHkxLCB4MiAtIHgxLCB5MiAtIHkxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRoZSBwb2ludCB3aXRoIHNwZWNpZmllZCBjb29yZGluYXRlcyBbcHgsIHB5XQorICAgICAqIGlzIHdpdGhpbiB0aGUgYm91bmRzIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBwb2ludCB3aXRoIHNwZWNpZmllZCBjb29yZGluYXRlcyBbcHgsIHB5XSBpcyB3aXRoaW4KKyAgICAgKiAgICAgICAgIHRoZSBib3VuZHMgb2YgdGhlIHJlY3RhbmdsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCBweCwgaW50IHB5KSB7CisgICAgICAgIGlmIChpc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHggPCB4IHx8IHB5IDwgeSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHB4IC09IHg7CisgICAgICAgIHB5IC09IHk7CisgICAgICAgIHJldHVybiBweCA8IHdpZHRoICYmIHB5IDwgaGVpZ2h0OworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBvciBub3QgdGhlIHBvaW50IGdpdmVuIGFzIGEgUG9pbnQgb2JqZWN0IGlzIHdpdGhpbiB0aGUKKyAgICAgKiBib3VuZHMgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIFBvaW50IG9iamVjdAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHBvaW50IHAgaXMgd2l0aGluIHRoZSBib3VuZHMgb2YgdGhlIHJlY3RhbmdsZSwKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSBmYWxzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludCBwKSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhwLngsIHAueSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIG9yIG5vdCB0aGUgcmVjdGFuZ2xlIHNwZWNpZmllZCBieSBbcngsIHJ5LCBydywgcmhdCisgICAgICogcGFyYW1ldGVycyBpcyBsb2NhdGVkIGluc2lkZSB0aGUgb3JpZ2luYWwgcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByeAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlIHRvIGNvbXBhcmUuCisgICAgICogQHBhcmFtIHJ5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgdG8gY29tcGFyZS4KKyAgICAgKiBAcGFyYW0gcncKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHRvIGNvbXBhcmUuCisgICAgICogQHBhcmFtIHJoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGEgcmVjdGFuZ2xlIHdpdGggW3J4LCByeSwgcncsIHJoXSBwYXJhbWV0ZXJzIGlzIGVudGlyZWx5CisgICAgICogICAgICAgICBjb250YWluZWQgaW4gdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCByeCwgaW50IHJ5LCBpbnQgcncsIGludCByaCkgeworICAgICAgICByZXR1cm4gY29udGFpbnMocngsIHJ5KSAmJiBjb250YWlucyhyeCArIHJ3IC0gMSwgcnkgKyByaCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHdoZXRoZXIgb3Igbm90IHRoZSByZWN0YW5nbGUgc3BlY2lmaWVkIGJ5IHRoZSBSZWN0YW5nbGUgb2JqZWN0CisgICAgICogaXMgbG9jYXRlZCBpbnNpZGUgdGhlIG9yaWdpbmFsIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIFJlY3RhbmdsZSBvYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgcmVjdGFuZ2xlIHNwZWNpZmllZCBieSBSZWN0YW5nbGUgb2JqZWN0IGlzIGVudGlyZWx5CisgICAgICogICAgICAgICBjb250YWluZWQgaW4gdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZSByKSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhyLngsIHIueSwgci53aWR0aCwgci5oZWlnaHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHdoZXRoZXIgb3Igbm90IGEgcG9pbnQgd2l0aCBzcGVjaWZpZWQgY29vcmRpbmF0ZXMgW3B4LCBweV0KKyAgICAgKiBiZWxvbmdzIHRvIGEgcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiBhIHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiBhIHBvaW50LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgYSBwb2ludCB3aXRoIHNwZWNpZmllZCBjb29yZGluYXRlcyBbcHgsIHB5XSBiZWxvbmdzIHRvIGEKKyAgICAgKiAgICAgICAgIHJlY3RhbmdsZSwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqIEBkZXByZWNhdGVkIHVzZSBjb250YWlucyhpbnQsIGludCkgbWV0aG9kLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gaW5zaWRlKGludCBweCwgaW50IHB5KSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhweCwgcHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgb3JpZ2luYWwgcmVjdGFuZ2xlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIFJlY3RhbmdsZTJELgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIFJlY3RhbmdsZTJEIG9iamVjdCB0aGF0IGlzIHRoZSByZXN1bHQgb2YgaW50ZXJzZWN0aW5nIHRoZQorICAgICAqICAgICAgICAgb3JpZ2luYWwgcmVjdGFuZ2xlIHdpdGggdGhlIHNwZWNpZmllZCBSZWN0YW5nbGUyRC4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQjY3JlYXRlSW50ZXJzZWN0aW9uKGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGNyZWF0ZUludGVyc2VjdGlvbihSZWN0YW5nbGUyRCByKSB7CisgICAgICAgIGlmIChyIGluc3RhbmNlb2YgUmVjdGFuZ2xlKSB7CisgICAgICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uKChSZWN0YW5nbGUpcik7CisgICAgICAgIH0KKyAgICAgICAgUmVjdGFuZ2xlMkQgZHN0ID0gbmV3IFJlY3RhbmdsZTJELkRvdWJsZSgpOworICAgICAgICBSZWN0YW5nbGUyRC5pbnRlcnNlY3QodGhpcywgciwgZHN0KTsKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByZWN0YW5nbGUuIEFuIGVtcHR5IHJlY3RhbmdsZSBpcyByZXR1cm5lZCBpZiB0aGVyZSBpcyBubyBpbnRlcnNlY3Rpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIFJlY3RhbmdsZSBvYmplY3QgaXMgcmVzdWx0IG9mIHRoZSBvcmlnaW5hbCByZWN0YW5nbGUgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZSBpbnRlcnNlY3Rpb24oUmVjdGFuZ2xlIHIpIHsKKyAgICAgICAgaW50IHgxID0gTWF0aC5tYXgoeCwgci54KTsKKyAgICAgICAgaW50IHkxID0gTWF0aC5tYXgoeSwgci55KTsKKyAgICAgICAgaW50IHgyID0gTWF0aC5taW4oeCArIHdpZHRoLCByLnggKyByLndpZHRoKTsKKyAgICAgICAgaW50IHkyID0gTWF0aC5taW4oeSArIGhlaWdodCwgci55ICsgci5oZWlnaHQpOworICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZSh4MSwgeTEsIHgyIC0geDEsIHkyIC0geTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBvciBub3QgdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSBpbnRlcnNlY3RzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHR3byByZWN0YW5nbGVzIG92ZXJsYXAsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZSByKSB7CisgICAgICAgIHJldHVybiAhaW50ZXJzZWN0aW9uKHIpLmlzRW1wdHkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXJlIHRoZSBzcGVjaWZpZWQgUG9pbnQgaXMgbG9jYXRlZCB3aXRoIHJlc3BlY3QgdG8gdGhlCisgICAgICogcmVjdGFuZ2xlLiBUaGlzIG1ldGhvZCBjb21wdXRlcyB3aGV0aGVyIHRoZSBwb2ludCBpcyB0byB0aGUgcmlnaHQgb3IgdG8KKyAgICAgKiB0aGUgbGVmdCBvZiB0aGUgcmVjdGFuZ2xlIGFuZCB3aGV0aGVyIGl0IGlzIGFib3ZlIG9yIGJlbG93IHRoZSByZWN0YW5nbGUsCisgICAgICogYW5kIHBhY2tzIHRoZSByZXN1bHQgaW50byBhbiBpbnRlZ2VyIGJ5IHVzaW5nIGEgYmluYXJ5IE9SIG9wZXJhdGlvbiB3aXRoCisgICAgICogdGhlIGZvbGxvd2luZyBtYXNrczoKKyAgICAgKiA8dWw+CisgICAgICo8bGk+UmVjdGFuZ2xlMkQuT1VUX0xFRlQ8L2xpPgorICAgICAqPGxpPlJlY3RhbmdsZTJELk9VVF9UT1A8L2xpPgorICAgICAqPGxpPlJlY3RhbmdsZTJELk9VVF9SSUdIVDwvbGk+CisgICAgICo8bGk+UmVjdGFuZ2xlMkQuT1VUX0JPVFRPTTwvbGk+CisgICAgICo8L3VsPgorICAgICAqIElmIHRoZSByZWN0YW5nbGUgaXMgZW1wdHksIGFsbCBtYXNrcyBhcmUgc2V0LCBhbmQgaWYgdGhlIHBvaW50IGlzIGluc2lkZQorICAgICAqIHRoZSByZWN0YW5nbGUsIG5vbmUgYXJlIHNldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKiBAcGFyYW0gcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsb2NhdGlvbiBvZiB0aGUgUG9pbnQgcmVsYXRpdmUgdG8gdGhlIHJlY3RhbmdsZSBhcyB0aGUgcmVzdWx0CisgICAgICogICAgICAgICBvZiBsb2dpY2FsIE9SIG9wZXJhdGlvbiB3aXRoIGFsbCBvdXQgbWFza3MuCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEI291dGNvZGUoZG91YmxlLCBkb3VibGUpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBvdXRjb2RlKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIGludCBjb2RlID0gMDsKKworICAgICAgICBpZiAod2lkdGggPD0gMCkgeworICAgICAgICAgICAgY29kZSB8PSBPVVRfTEVGVCB8IE9VVF9SSUdIVDsKKyAgICAgICAgfSBlbHNlIGlmIChweCA8IHgpIHsKKyAgICAgICAgICAgIGNvZGUgfD0gT1VUX0xFRlQ7CisgICAgICAgIH0gZWxzZSBpZiAocHggPiB4ICsgd2lkdGgpIHsKKyAgICAgICAgICAgIGNvZGUgfD0gT1VUX1JJR0hUOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGhlaWdodCA8PSAwKSB7CisgICAgICAgICAgICBjb2RlIHw9IE9VVF9UT1AgfCBPVVRfQk9UVE9NOworICAgICAgICB9IGVsc2UgaWYgKHB5IDwgeSkgeworICAgICAgICAgICAgY29kZSB8PSBPVVRfVE9QOworICAgICAgICB9IGVsc2UgaWYgKHB5ID4geSArIGhlaWdodCkgeworICAgICAgICAgICAgY29kZSB8PSBPVVRfQk9UVE9NOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5sYXJnZXMgdGhlIHJlY3RhbmdsZSB0byBjb3ZlciB0aGUgc3BlY2lmaWVkIFJlY3RhbmdsZTJELgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIHVuaW9uIG9mIHRoZSBvcmlnaW5hbCBhbmQgdGhlIHNwZWNpZmllZCBSZWN0YW5nbGUyRC4KKyAgICAgKiBAc2VlIGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQjY3JlYXRlVW5pb24oamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgY3JlYXRlVW5pb24oUmVjdGFuZ2xlMkQgcikgeworICAgICAgICBpZiAociBpbnN0YW5jZW9mIFJlY3RhbmdsZSkgeworICAgICAgICAgICAgcmV0dXJuIHVuaW9uKChSZWN0YW5nbGUpcik7CisgICAgICAgIH0KKyAgICAgICAgUmVjdGFuZ2xlMkQgZHN0ID0gbmV3IFJlY3RhbmdsZTJELkRvdWJsZSgpOworICAgICAgICBSZWN0YW5nbGUyRC51bmlvbih0aGlzLCByLCBkc3QpOworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVubGFyZ2VzIHRoZSByZWN0YW5nbGUgdG8gY292ZXIgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUuCisgICAgICogQHJldHVybiB0aGUgdW5pb24gb2YgdGhlIG9yaWdpbmFsIGFuZCB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlIHVuaW9uKFJlY3RhbmdsZSByKSB7CisgICAgICAgIFJlY3RhbmdsZSBkc3QgPSBuZXcgUmVjdGFuZ2xlKHRoaXMpOworICAgICAgICBkc3QuYWRkKHIpOworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBvcmlnaW5hbCBSZWN0YW5nbGUgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIE9iamVjdCBmb3IgY29tcGFyaXNvbi4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGlzIGEgcmVjdGFuZ2xlIHdpdGggdGhlIHNhbWUKKyAgICAgKiAgICAgICAgIGRpbWVuc2lvbnMgYXMgdGhlIG9yaWdpbmFsIHJlY3RhbmdsZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRCNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkgeworICAgICAgICAgICAgUmVjdGFuZ2xlIHIgPSAoUmVjdGFuZ2xlKW9iajsKKyAgICAgICAgICAgIHJldHVybiByLnggPT0geCAmJiByLnkgPT0geSAmJiByLndpZHRoID09IHdpZHRoICYmIHIuaGVpZ2h0ID09IGhlaWdodDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVjdGFuZ2xlOyB0aGUgc3RyaW5nIGNvbnRhaW5zIFt4LAorICAgICAqIHksIHdpZHRoLCBoZWlnaHRdIHBhcmFtZXRlcnMgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBUaGUgb3V0cHV0IGZvcm1hdCBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvdXIuIEl0IGNvdWxkIGJlCisgICAgICAgIC8vIG9idGFpbmVkIGluIHRoZSBmb2xsb3dpbmcgd2F5CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgUmVjdGFuZ2xlKCkudG9TdHJpbmcoKSkKKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlt4PSIgKyB4ICsgIix5PSIgKyB5ICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgIix3aWR0aD0iICsgd2lkdGggKyAiLGhlaWdodD0iICsgaGVpZ2h0ICsgIl0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L1JlbmRlcmluZ0hpbnRzLmphdmEgYi9hd3QvamF2YS9hd3QvUmVuZGVyaW5nSGludHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2Y2ZmExCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L1JlbmRlcmluZ0hpbnRzLmphdmEKQEAgLTAsMCArMSw2MDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgQWxleGV5IEEuIFBldHJlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogVGhlIFJlbmRlcmluZ0hpbnRzIGNsYXNzIHJlcHJlc2VudHMgcHJlZmVyZW5jZXMgZm9yIHRoZSByZW5kZXJpbmcgYWxnb3JpdGhtcy4KKyAqIFRoZSBwcmVmZXJlbmNlcyBhcmUgYXJiaXRyYXJ5IGFuZCBjYW4gYmUgc3BlY2lmaWVkIGJ5IE1hcCBvYmplY3RzIG9yIGJ5CisgKiBrZXktdmFsdWUgcGFpcnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmVuZGVyaW5nSGludHMgaW1wbGVtZW50cyBNYXA8T2JqZWN0LCBPYmplY3Q+LCBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9BTFBIQV9JTlRFUlBPTEFUSU9OIC0gYWxwaGEgaW50ZXJwb2xhdGlvbiByZW5kZXJpbmcgaGludAorICAgICAqIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleSBLRVlfQUxQSEFfSU5URVJQT0xBVElPTiA9IG5ldyBLZXlJbXBsKDEpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0FMUEhBX0lOVEVSUE9MQVRJT05fREVGQVVMVCAtIGFscGhhIGludGVycG9sYXRpb24KKyAgICAgKiByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9BTFBIQV9JTlRFUlBPTEFUSU9OX0RFRkFVTFQgPSBuZXcgS2V5VmFsdWUoCisgICAgICAgICAgICBLRVlfQUxQSEFfSU5URVJQT0xBVElPTik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfQUxQSEFfSU5URVJQT0xBVElPTl9TUEVFRCAtIGFscGhhIGludGVycG9sYXRpb24KKyAgICAgKiByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9BTFBIQV9JTlRFUlBPTEFUSU9OX1NQRUVEID0gbmV3IEtleVZhbHVlKAorICAgICAgICAgICAgS0VZX0FMUEhBX0lOVEVSUE9MQVRJT04pOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0FMUEhBX0lOVEVSUE9MQVRJT05fUVVBTElUWSAtIGFscGhhIGludGVycG9sYXRpb24KKyAgICAgKiByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9BTFBIQV9JTlRFUlBPTEFUSU9OX1FVQUxJVFkgPSBuZXcgS2V5VmFsdWUoCisgICAgICAgICAgICBLRVlfQUxQSEFfSU5URVJQT0xBVElPTik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX0FOVElBTElBU0lORyAtIGFudGlhbGlhc2luZyByZW5kZXJpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXkgS0VZX0FOVElBTElBU0lORyA9IG5ldyBLZXlJbXBsKDIpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0FOVElBTElBU19ERUZBVUxUIC0gYW50aWFsaWFzaW5nIHJlbmRlcmluZyBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0FOVElBTElBU19ERUZBVUxUID0gbmV3IEtleVZhbHVlKEtFWV9BTlRJQUxJQVNJTkcpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0FOVElBTElBU19PTiAtIGFudGlhbGlhc2luZyByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9BTlRJQUxJQVNfT04gPSBuZXcgS2V5VmFsdWUoS0VZX0FOVElBTElBU0lORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfQU5USUFMSUFTX09GRiAtIGFudGlhbGlhc2luZyByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9BTlRJQUxJQVNfT0ZGID0gbmV3IEtleVZhbHVlKEtFWV9BTlRJQUxJQVNJTkcpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9DT0xPUl9SRU5ERVJJTkcgLSBjb2xvciByZW5kZXJpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXkgS0VZX0NPTE9SX1JFTkRFUklORyA9IG5ldyBLZXlJbXBsKDMpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0NPTE9SX1JFTkRFUl9ERUZBVUxUIC0gY29sb3IgcmVuZGVyaW5nIGhpbnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgVkFMVUVfQ09MT1JfUkVOREVSX0RFRkFVTFQgPSBuZXcgS2V5VmFsdWUoS0VZX0NPTE9SX1JFTkRFUklORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfQ09MT1JfUkVOREVSX1NQRUVEIC0gY29sb3IgcmVuZGVyaW5nIGhpbnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgVkFMVUVfQ09MT1JfUkVOREVSX1NQRUVEID0gbmV3IEtleVZhbHVlKEtFWV9DT0xPUl9SRU5ERVJJTkcpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0NPTE9SX1JFTkRFUl9RVUFMSVRZIC0gY29sb3IgcmVuZGVyaW5nIGhpbnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgVkFMVUVfQ09MT1JfUkVOREVSX1FVQUxJVFkgPSBuZXcgS2V5VmFsdWUoS0VZX0NPTE9SX1JFTkRFUklORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX0RJVEhFUklORyAtIGRpdGhlcmluZyByZW5kZXJpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXkgS0VZX0RJVEhFUklORyA9IG5ldyBLZXlJbXBsKDQpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0RJVEhFUl9ERUZBVUxUIC0gZGl0aGVyaW5nIHJlbmRlcmluZyBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0RJVEhFUl9ERUZBVUxUID0gbmV3IEtleVZhbHVlKEtFWV9ESVRIRVJJTkcpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0RJVEhFUl9ESVNBQkxFIC0gZGl0aGVyaW5nIHJlbmRlcmluZyBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0RJVEhFUl9ESVNBQkxFID0gbmV3IEtleVZhbHVlKEtFWV9ESVRIRVJJTkcpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0RJVEhFUl9ESVNBQkxFIC0gZGl0aGVyaW5nIHJlbmRlcmluZyBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0RJVEhFUl9FTkFCTEUgPSBuZXcgS2V5VmFsdWUoS0VZX0RJVEhFUklORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX0ZSQUNUSU9OQUxNRVRSSUNTIC0gZnJhY3Rpb25hbCBtZXRyaWNzIHJlbmRlcmluZyBoaW50CisgICAgICoga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2V5IEtFWV9GUkFDVElPTkFMTUVUUklDUyA9IG5ldyBLZXlJbXBsKDUpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0ZSQUNUSU9OQUxNRVRSSUNTX0RFRkFVTFQgLSBmcmFjdGlvbmFsIG1ldHJpY3MKKyAgICAgKiByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9GUkFDVElPTkFMTUVUUklDU19ERUZBVUxUID0gbmV3IEtleVZhbHVlKEtFWV9GUkFDVElPTkFMTUVUUklDUyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfRlJBQ1RJT05BTE1FVFJJQ1NfT04gLSBmcmFjdGlvbmFsIG1ldHJpY3MgcmVuZGVyaW5nCisgICAgICogaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9GUkFDVElPTkFMTUVUUklDU19PTiA9IG5ldyBLZXlWYWx1ZShLRVlfRlJBQ1RJT05BTE1FVFJJQ1MpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0ZSQUNUSU9OQUxNRVRSSUNTX09GRiAtIGZyYWN0aW9uYWwgbWV0cmljcyByZW5kZXJpbmcKKyAgICAgKiBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0ZSQUNUSU9OQUxNRVRSSUNTX09GRiA9IG5ldyBLZXlWYWx1ZShLRVlfRlJBQ1RJT05BTE1FVFJJQ1MpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEtFWV9JTlRFUlBPTEFUSU9OIC0gaW50ZXJwb2xhdGlvbiByZW5kZXJpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXkgS0VZX0lOVEVSUE9MQVRJT04gPSBuZXcgS2V5SW1wbCg2KTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9JTlRFUlBPTEFUSU9OX0JJQ1VCSUMgLSBpbnRlcnBvbGF0aW9uIHJlbmRlcmluZyBoaW50CisgICAgICogdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgVkFMVUVfSU5URVJQT0xBVElPTl9CSUNVQklDID0gbmV3IEtleVZhbHVlKEtFWV9JTlRFUlBPTEFUSU9OKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9JTlRFUlBPTEFUSU9OX0JJTElORUFSIC0gaW50ZXJwb2xhdGlvbiByZW5kZXJpbmcgaGludAorICAgICAqIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX0lOVEVSUE9MQVRJT05fQklMSU5FQVIgPSBuZXcgS2V5VmFsdWUoS0VZX0lOVEVSUE9MQVRJT04pOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFZBTFVFX0lOVEVSUE9MQVRJT05fTkVBUkVTVF9ORUlHSEJPUiAtIGludGVycG9sYXRpb24KKyAgICAgKiByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9JTlRFUlBPTEFUSU9OX05FQVJFU1RfTkVJR0hCT1IgPSBuZXcgS2V5VmFsdWUoCisgICAgICAgICAgICBLRVlfSU5URVJQT0xBVElPTik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX1JFTkRFUklORyAtIHJlbmRlcmluZyBoaW50IGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleSBLRVlfUkVOREVSSU5HID0gbmV3IEtleUltcGwoNyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfUkVOREVSX0RFRkFVTFQgLSByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9SRU5ERVJfREVGQVVMVCA9IG5ldyBLZXlWYWx1ZShLRVlfUkVOREVSSU5HKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9SRU5ERVJfU1BFRUQgLSByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9SRU5ERVJfU1BFRUQgPSBuZXcgS2V5VmFsdWUoS0VZX1JFTkRFUklORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfUkVOREVSX1FVQUxJVFkgLSByZW5kZXJpbmcgaGludCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBWQUxVRV9SRU5ERVJfUVVBTElUWSA9IG5ldyBLZXlWYWx1ZShLRVlfUkVOREVSSU5HKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBLRVlfU1RST0tFX0NPTlRST0wgLSBzdHJva2UgY29udHJvbCBoaW50IGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleSBLRVlfU1RST0tFX0NPTlRST0wgPSBuZXcgS2V5SW1wbCg4KTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9TVFJPS0VfREVGQVVMVCAtIHN0cm9rZSBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX1NUUk9LRV9ERUZBVUxUID0gbmV3IEtleVZhbHVlKEtFWV9TVFJPS0VfQ09OVFJPTCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfU1RST0tFX05PUk1BTElaRSAtIHN0cm9rZSBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX1NUUk9LRV9OT1JNQUxJWkUgPSBuZXcgS2V5VmFsdWUoS0VZX1NUUk9LRV9DT05UUk9MKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9TVFJPS0VfUFVSRSAtIHN0cm9rZSBoaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX1NUUk9LRV9QVVJFID0gbmV3IEtleVZhbHVlKEtFWV9TVFJPS0VfQ09OVFJPTCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgS0VZX1RFWFRfQU5USUFMSUFTSU5HIC0gdGV4dCBhbnRpYWxpYXNpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXkgS0VZX1RFWFRfQU5USUFMSUFTSU5HID0gbmV3IEtleUltcGwoOSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfVEVYVF9BTlRJQUxJQVNfREVGQVVMVCAtIHRleHQgYW50aWFsaWFzaW5nIGhpbnQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX1RFWFRfQU5USUFMSUFTX0RFRkFVTFQgPSBuZXcgS2V5VmFsdWUoS0VZX1RFWFRfQU5USUFMSUFTSU5HKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBWQUxVRV9URVhUX0FOVElBTElBU19PTiAtIHRleHQgYW50aWFsaWFzaW5nIGhpbnQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0IFZBTFVFX1RFWFRfQU5USUFMSUFTX09OID0gbmV3IEtleVZhbHVlKEtFWV9URVhUX0FOVElBTElBU0lORyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVkFMVUVfVEVYVF9BTlRJQUxJQVNfT0ZGIC0gdGV4dCBhbnRpYWxpYXNpbmcgaGludCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgVkFMVUVfVEVYVF9BTlRJQUxJQVNfT0ZGID0gbmV3IEtleVZhbHVlKEtFWV9URVhUX0FOVElBTElBU0lORyk7CisKKyAgICAvKiogVGhlIG1hcC4gKi8KKyAgICBwcml2YXRlIEhhc2hNYXA8T2JqZWN0LCBPYmplY3Q+IG1hcCA9IG5ldyBIYXNoTWFwPE9iamVjdCwgT2JqZWN0PigpOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHJlbmRlcmluZyBoaW50cyBvYmplY3QgZnJvbSBzcGVjaWZpZWQgTWFwIG9iamVjdCB3aXRoCisgICAgICogZGVmaW5lZCBrZXkvdmFsdWUgcGFpcnMgb3IgbnVsbCBmb3IgZW1wdHkgUmVuZGVyaW5nSGludHMuCisgICAgICogCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIE1hcCBvYmplY3Qgd2l0aCBkZWZpbmVkIGtleS92YWx1ZSBwYWlycyBvciBudWxsIGZvciBlbXB0eQorICAgICAqICAgICAgICAgICAgUmVuZGVyaW5nSGludHMuCisgICAgICovCisgICAgcHVibGljIFJlbmRlcmluZ0hpbnRzKE1hcDxLZXksID8+IG1hcCkgeworICAgICAgICBzdXBlcigpOworICAgICAgICBpZiAobWFwICE9IG51bGwpIHsKKyAgICAgICAgICAgIHB1dEFsbChtYXApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHJlbmRlcmluZyBoaW50cyBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS92YWx1ZQorICAgICAqIHBhaXIuCisgICAgICogCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiBoaW50IHByb3BlcnR5LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIG9mIGhpbnQgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIFJlbmRlcmluZ0hpbnRzKEtleSBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBzdXBlcigpOworICAgICAgICBwdXQoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgcHJvcGVydGllcyByZXByZXNlbnRlZCBieSBrZXkvdmFsdWUgcGFpcnMgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogUmVuZGVyaW5nSGludHMgb2JqZWN0IHRvIGN1cnJlbnQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaW50cworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmluZ0hpbnRzIHRvIGJlIGFkZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZChSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBtYXAucHV0QWxsKGhpbnRzLm1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHV0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIHRoZSBzcGVjaWZpZWQga2V5LiBOZWl0aGVyIHRoZSBrZXkgbm9yIHRoZQorICAgICAqIHZhbHVlIGNhbiBiZSBudWxsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZW5kZXJpbmcgaGludCBrZXkuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcmVuZGVyaW5nIGhpbnQgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgcmVuZGVyaW5nIGhpbnQgdmFsdWUgYXNzaWduZWQgdG8gdGhlIGtleSBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAoISgoS2V5KWtleSkuaXNDb21wYXRpYmxlVmFsdWUodmFsdWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbWFwLnB1dChrZXksIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQga2V5IGFuZCBjb3JyZXNwb25kaW5nIHZhbHVlIGZyb20gdGhlIFJlbmRlcmluZ0hpbnRzCisgICAgICogb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaGludCBrZXkgdG8gYmUgcmVtb3ZlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3Qgb2YgcHJldmlvdXMgcmVuZGVyaW5nIGhpbnQgdmFsdWUgd2hpY2ggaXMgYXNzaWduZWQgdG8KKyAgICAgKiAgICAgICAgIHRoZSBzcGVjaWZpZWQga2V5LCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5yZW1vdmUoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhc3NpZ25lZCB0byB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcmVuZGVyaW5nIGhpbnQga2V5LgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCBhc3NpZ25lZCB0byB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldChPYmplY3Qga2V5KSB7CisgICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNldCBvZiByZW5kZXJpbmcgaGludHMga2V5cyBmb3IgY3VycmVudCBSZW5kZXJpbmdIaW50cyBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc2V0IG9mIHJlbmRlcmluZyBoaW50cyBrZXlzLgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8T2JqZWN0PiBrZXlTZXQoKSB7CisgICAgICAgIHJldHVybiBtYXAua2V5U2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNldCBvZiBNYXAuRW50cnkgb2JqZWN0cyB3aGljaCBjb250YWluIGN1cnJlbnQgUmVuZGVyaW5nSGludAorICAgICAqIGtleS92YWx1ZSBwYWlycy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhIHNldCBvZiBtYXBwZWQgUmVuZGVyaW5nSGludCBrZXkvdmFsdWUgcGFpcnMuCisgICAgICovCisgICAgcHVibGljIFNldDxNYXAuRW50cnk8T2JqZWN0LCBPYmplY3Q+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5lbnRyeVNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1dHMgYWxsIG9mIHRoZSBwcmVmZXJlbmNlcyBmcm9tIHRoZSBzcGVjaWZpZWQgTWFwIGludG8gdGhlIGN1cnJlbnQKKyAgICAgKiBSZW5kZXJpbmdIaW50cyBvYmplY3QuIFRoZXNlIG1hcHBpbmdzIHJlcGxhY2UgYWxsIGV4aXN0aW5nIHByZWZlcmVuY2VzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIE1hcCBvZiBwcmVmZXJlbmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8sID8+IG0pIHsKKyAgICAgICAgaWYgKG0gaW5zdGFuY2VvZiBSZW5kZXJpbmdIaW50cykgeworICAgICAgICAgICAgbWFwLnB1dEFsbCgoKFJlbmRlcmluZ0hpbnRzKW0pLm1hcCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTZXQ8Pz4gZW50cmllcyA9IG0uZW50cnlTZXQoKTsKKworICAgICAgICAgICAgaWYgKGVudHJpZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gZW50cmllcy5pdGVyYXRvcigpOworICAgICAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgTWFwLkVudHJ5PD8sID8+IGVudHJ5ID0gKE1hcC5FbnRyeTw/LCA/PilpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIEtleSBrZXkgPSAoS2V5KWVudHJ5LmdldEtleSgpOworICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgcHV0KGtleSwgdmFsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgQ29sbGVjdGlvbiBvZiB2YWx1ZXMgY29udGFpbmVkIGluIGN1cnJlbnQgUmVuZGVyaW5nSGludHMKKyAgICAgKiBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQ29sbGVjdGlvbiBvZiBSZW5kZXJpbmdIaW50cydzIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxPYmplY3Q+IHZhbHVlcygpIHsKKyAgICAgICAgcmV0dXJuIG1hcC52YWx1ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgY3VycmVudCBSZW5kZXJpbmdIaW50cyBvYmplY3QgY29udGFpbnMgYXQgbGVhc3Qgb25lCisgICAgICogdGhlIHZhbHVlIHdoaWNoIGlzIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgT2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBPYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhc3NpZ25lZCB0byBhdCBsZWFzdCBvbmUKKyAgICAgKiAgICAgICAgIFJlbmRlcmluZ0hpbnQncyBrZXksIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zVmFsdWUodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCBjdXJyZW50IFJlbmRlcmluZ0hpbnRzIG9iamVjdCBjb250YWlucyB0aGUga2V5CisgICAgICogd2hpY2ggaXMgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCBPYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBPYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgUmVuZGVyaW5nSGludHMgb2JqZWN0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgT2JqZWN0CisgICAgICogICAgICAgICBhcyBhIGtleSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIFJlbmRlcmluZ0hpbnRzIG9iamVjdCBjb250YWlucyBhbnkga2V5L3ZhbHVlCisgICAgICogcGFpcnMuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgUmVuZGVyaW5nSGludHMgb2JqZWN0IGlzIGVtcHR5LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5pc0VtcHR5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBSZW5kZXJpbmdIaW50cyBvZiBhbGwga2V5L3ZhbHVlIHBhaXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBtYXAuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzIGluIHRoZSBSZW5kZXJpbmdIaW50cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIFJlbmRlcmluZ0hpbnRzIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBPYmplY3QgaXMgYSBNYXAgd2hvc2Uga2V5L3ZhbHVlIHBhaXJzIG1hdGNoIHRoaXMKKyAgICAgKiAgICAgICAgIFJlbmRlcmluZ0hpbnRzJyBrZXkvdmFsdWUgcGFpcnMsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIE1hcCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIE1hcDw/LCA/PiBtID0gKE1hcDw/LCA/PilvOworICAgICAgICBTZXQ8Pz4ga2V5cyA9IGtleVNldCgpOworICAgICAgICBpZiAoIWtleXMuZXF1YWxzKG0ua2V5U2V0KCkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGtleXMuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgS2V5IGtleSA9IChLZXkpaXQubmV4dCgpOworICAgICAgICAgICAgT2JqZWN0IHYxID0gZ2V0KGtleSk7CisgICAgICAgICAgICBPYmplY3QgdjIgPSBtLmdldChrZXkpOworICAgICAgICAgICAgaWYgKCEodjEgPT0gbnVsbCA/IHYyID09IG51bGwgOiB2MS5lcXVhbHModjIpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgZm9yIHRoaXMgUmVuZGVyaW5nSGludHMgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBmb3IgdGhpcyBSZW5kZXJpbmdIaW50cyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb25lIG9mIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3Qgd2l0aCB0aGUgc2FtZSBjb250ZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZSBvZiB0aGUgUmVuZGVyaW5nSGludHMgaW5zdGFuY2UuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgUmVuZGVyaW5nSGludHMgY2xvbmUgPSBuZXcgUmVuZGVyaW5nSGludHMobnVsbCk7CisgICAgICAgIGNsb25lLm1hcCA9IChIYXNoTWFwPE9iamVjdCwgT2JqZWN0Pil0aGlzLm1hcC5jbG9uZSgpOworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgU3RyaW5nIG9iamVjdCB3aGljaCByZXByZXNlbnRzIFJlbmRlcmluZ0hpbnRzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIlJlbmRlcmluZ0hpbnRzWyIgKyBtYXAudG9TdHJpbmcoKSArICJdIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIFJlbmRlcmluZ0hpbnRzLktleSBjbGFzcyBpcyBhYnN0cmFjdCBhbmQgZGVmaW5lcyBhIGJhc2UgdHlwZSBmb3IgYWxsCisgICAgICogUmVuZGVyaW5nSGludHMga2V5cy4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEtleSB7CisKKyAgICAgICAgLyoqIFRoZSBrZXkuICovCisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IGtleTsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGtleSB3aXRoIHVuaXF1ZSBpbnRlZ2VyIGlkZW50aWZpZXIuIE5vIHR3byBvYmplY3RzCisgICAgICAgICAqIG9mIHRoZSBzYW1lIHN1YmNsYXNzIHdpdGggdGhlIHNhbWUgaW50ZWdlciBrZXkgY2FuIGJlIGluc3RhbnRpYXRlZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBrZXkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdW5pcXVlIGtleS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBLZXkoaW50IGtleSkgeworICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29tcGFyZXMgdGhlIEtleSBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBvCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBPYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIEtleSBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIG9iamVjdCwgZmFsc2UKKyAgICAgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcyA9PSBvOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBmb3IgdGhpcyBLZXkgb2JqZWN0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIEtleSBvYmplY3QuCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGludGVnZXIgdW5pcXVlIGtleSB3aXRoIHdoaWNoIHRoaXMgS2V5IG9iamVjdCBoYXMgYmVlbgorICAgICAgICAgKiBpbnN0YW50aWF0ZWQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBpbnRlZ2VyIHVuaXF1ZSBrZXkgd2l0aCB3aGljaCB0aGlzIEtleSBvYmplY3QgaGFzIGJlZW4KKyAgICAgICAgICogICAgICAgICBpbnN0YW50aWF0ZWQuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgaW50IGludEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHNwZWNpZmllZCB2YWx1ZSBpcyBjb21wYXRpYmxlIHdpdGggdGhlIEtleS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB2YWwKKyAgICAgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0LgorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBLZXksCisgICAgICAgICAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNDb21wYXRpYmxlVmFsdWUoT2JqZWN0IHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpdmF0ZSBpbXBsZW1lbnRhdGlvbiBvZiBLZXkgY2xhc3MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgS2V5SW1wbCBleHRlbmRzIEtleSB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBrZXkgaW1wbGVtZW50YXRpb24uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0ga2V5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBLZXlJbXBsKGludCBrZXkpIHsKKyAgICAgICAgICAgIHN1cGVyKGtleSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDb21wYXRpYmxlVmFsdWUoT2JqZWN0IHZhbCkgeworICAgICAgICAgICAgaWYgKCEodmFsIGluc3RhbmNlb2YgS2V5VmFsdWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gKChLZXlWYWx1ZSl2YWwpLmtleSA9PSB0aGlzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpdmF0ZSBjbGFzcyBLZXlWYWx1ZSBpcyB1c2VkIGFzIHZhbHVlIGZvciBLZXkgY2xhc3MgaW5zdGFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgS2V5VmFsdWUgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUga2V5LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBLZXkga2V5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcga2V5IHZhbHVlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGtleQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgS2V5VmFsdWUoS2V5IGtleSkgeworICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvU2hhcGUuamF2YSBiL2F3dC9qYXZhL2F3dC9TaGFwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5YmM2MjMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvU2hhcGUuamF2YQpAQCAtMCwwICsxLDE2MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5QYXRoSXRlcmF0b3I7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CisKKy8qKgorICogVGhlIFNoYXBlIGludGVyZmFjZSBkZWZpbmVzIGEgZ2VvbWV0cmljIHNoYXBlIGRlZmluZWQgYnkgYSBib3VuZGFyeSAob3V0bGluZSkKKyAqIHBhdGguIFRoZSBwYXRoIG91dGxpbmUgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggYSBQYXRoSXRlcmF0b3Igb2JqZWN0LiBUaGUKKyAqIFNoYXBlIGludGVyZmFjZSBwcm92aWRlcyBtZXRob2RzIGZvciBvYnRhaW5pbmcgdGhlIGJvdW5kaW5nIGJveCAod2hpY2ggaXMgdGhlCisgKiBzbWFsbGVzdCByZWN0YW5nbGUgY29udGFpbmluZyB0aGUgc2hhcGUgYW5kIGZvciBvYnRhaW5pbmcgYSBQYXRoSXRlcmF0b3IKKyAqIG9iamVjdCBmb3IgY3VycmVudCBTaGFwZSwgYXMgd2VsbCBhcyB1dGlsaXR5IG1ldGhvZHMgd2hpY2ggZGV0ZXJtaW5lIGlmIHRoZQorICogU2hhcGUgY29udGFpbnMgb3IgaW50ZXJzZWN0cyBhIFJlY3RhbmdsZSBvciBjb250YWlucyBhIFBvaW50LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBTaGFwZSB7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHBvaW50IHdpdGggc3BlY2lmaWVkIGNvb3JkaW5hdGVzIGxpZXMgaW5zaWRlCisgICAgICogdGhlIFNoYXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBjb29yZGluYXRlcyBsaWUgaW5zaWRlIHRoZSBTaGFwZSwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHkpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSByZWN0YW5nbGUgd2l0aCBzcGVjaWZpZWQgW3gsIHksIHdpZHRoLCBoZWlnaHRdCisgICAgICogcGFyYW1ldGVycyBsaWVzIGluc2lkZSB0aGUgU2hhcGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGRvdWJsZSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgZG91YmxlIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlIGxpZXMgaW5zaWRlIHRoZSBTaGFwZSwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3LCBkb3VibGUgaCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBQb2ludDJEIGxpZXMgaW5zaWRlIHRoZSBTaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBQb2ludDJEIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgUG9pbnQyRCBsaWVzIGluc2lkZSB0aGUgU2hhcGUsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUG9pbnQyRCBwb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgbGllcyBpbnNpZGUgdGhlIFNoYXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgbGllcyBpbnNpZGUgdGhlIFNoYXBlLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZTJEIHIpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIG9mIHRoZSBTaGFwZS4gVGhlIGJvdW5kaW5nIHJlY3RhbmdsZSBpcyB0aGUKKyAgICAgKiBzbWFsbGVzdCByZWN0YW5nbGUgd2hpY2ggY29udGFpbnMgdGhlIFNoYXBlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSBvZiB0aGUgU2hhcGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFJlY3RhbmdsZTJEIHdoaWNoIHJlcHJlc2VudHMgU2hhcGUgYm91bmRzLiBUaGUgYm91bmRpbmcKKyAgICAgKiByZWN0YW5nbGUgaXMgdGhlIHNtYWxsZXN0IHJlY3RhbmdsZSB3aGljaCBjb250YWlucyB0aGUgU2hhcGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIG9mIHRoZSBTaGFwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFBhdGhJdGVyYXRvciBvYmplY3Qgb2YgdGhlIFNoYXBlIHdoaWNoIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUKKyAgICAgKiBzaGFwZSdzIGJvdW5kYXJ5IG1vZGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhdAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBBZmZpbmVUcmFuc2Zvcm0gb2JqZWN0IG9yIG51bGwuCisgICAgICogQHJldHVybiBQYXRoSXRlcmF0b3Igb2JqZWN0IGZvciB0aGUgU2hhcGUuCisgICAgICovCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIGF0KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFBhdGhJdGVyYXRvciBvYmplY3Qgb2YgdGhlIFNoYXBlIHdoaWNoIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUKKyAgICAgKiBjb29yZGluYXRlcyBvZiB0aGUgc2hhcGVzIGJvdW5kYXJ5IG1vZGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm0uIFRoZSBmbGF0bmVzcyBwYXJhbWV0ZXIgZGVmaW5lcyB0aGUgYW1vdW50IG9mIHN1YmRpdmlzaW9uCisgICAgICogb2YgdGhlIGN1cnZlZCBzZWdtZW50cyBhbmQgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIGRpc3RhbmNlIHdoaWNoIGV2ZXJ5CisgICAgICogcG9pbnQgb24gdGhlIHVuZmxhdHRlbmVkIHRyYW5zZm9ybWVkIGN1cnZlIGNhbiBkZXZpYXRlIGZyb20gdGhlIHJldHVybmVkCisgICAgICogZmxhdHRlbmVkIHBhdGggc2VnbWVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIGF0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybSBvYmplY3Qgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gZmxhdG5lc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aGUgY29udHJvbCBwb2ludHMgZm9yIGEgZ2l2ZW4gY3VydmUKKyAgICAgKiAgICAgICAgICAgIHdoaWNoIHZhcmllcyBmcm9tIGNvbGluZWFyIGJlZm9yZSBhIHN1YmRpdmlkZWQgY3VydmUgaXMKKyAgICAgKiAgICAgICAgICAgIHJlcGxhY2VkIGJ5IGEgc3RyYWlnaHQgbGluZSBjb25uZWN0aW5nIHRoZSBlbmRwb2ludHMuCisgICAgICogQHJldHVybiBQYXRoSXRlcmF0b3Igb2JqZWN0IGZvciB0aGUgU2hhcGUuCisgICAgICovCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIGF0LCBkb3VibGUgZmxhdG5lc3MpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBpbnRlcmlvciBvZiByZWN0YW5ndWxhciBzcGVjaWZpZWQgYnkgW3gsIHksCisgICAgICogd2lkdGgsIGhlaWdodF0gcGFyYW1ldGVycyBpbnRlcnNlY3RzIHRoZSBpbnRlcmlvciBvZiB0aGUgU2hhcGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGRvdWJsZSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgZG91YmxlIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3RhbmdsZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSByZWN0YW5nbGUgc3BlY2lmaWVkIGJ5IFt4LCB5LCB3aWR0aCwgaGVpZ2h0XQorICAgICAqICAgICAgICAgcGFyYW1ldGVycyBpbnRlcnNlY3RzIHRoZSBpbnRlcmlvciBvZiB0aGUgU2hhcGUsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHcsIGRvdWJsZSBoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGUgaW50ZXJpb3Igb2YgcmVjdGFuZ2xlIHNwZWNpZmllZCBieSBSZWN0YW5nbGUyRAorICAgICAqIG9iamVjdCBpbnRlcnNlY3RzIHRoZSBpbnRlcmlvciBvZiB0aGUgU2hhcGUuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWN0YW5nbGUyRCBvYmplY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgUmVjdGFuZ2xlMkQgaW50ZXJzZWN0cyB0aGUgaW50ZXJpb3Igb2YgdGhlIFNoYXBlLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGludGVyc2VjdHMoUmVjdGFuZ2xlMkQgcik7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvU3Ryb2tlLmphdmEgYi9hd3QvamF2YS9hd3QvU3Ryb2tlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmQxN2EyMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9TdHJva2UuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8qKgorICogVGhlIFN0cm9rZSBpbnRlcmZhY2UgZ2l2ZXMgYSBwZW4gc3R5bGUgdG8gYmUgdXNlZCBieSB0aGUgR3JhcGhpY3MyRAorICogaW50ZXJmYWNlLiBJdCBwcm92aWRlcyBhIG1lYW5zIGZvciBnZXR0aW5nIGEgc3Ryb2tlZCB2ZXJzaW9uIG9mIGEgc2hhcGUsCisgKiB3aGljaCBpcyB0aGUgdmVyc2lvbiB0aGF0IGlzIHN1aXRhYmxlIGZvciBkcmF3aW5nIHZpYSB0aGUgR3JhcGhpY3MyRAorICogaW50ZXJmYWNlLiBTdHJva2luZyBhIHNoYXBlIGdpdmVzIHRoZSBzaGFwZSdzIG91dGxpbmUgYSB3aWR0aCBvciBkcmF3aW5nCisgKiBzdHlsZS4KKyAqIDxwPgorICogVGhlIERyYXcgbWV0aG9kcyBmcm9tIEdyYXBoaWNzMkQgaW50ZXJmYWNlIHNob3VsZCB1c2UgdGhlIFN0cm9rZSBvYmplY3QgZm9yCisgKiByZW5kZXJpbmcgdGhlIHNoYXBlJ3Mgb3V0bGluZS4gVGhlIHN0cm9rZSBzaG91bGQgYmUgc2V0IGJ5CisgKiBzZXRTdHJva2UoamF2YS5hd3QuU3Ryb2tlKSBtZXRob2Qgb2YgdGhlIEdyYXBoaWNzMkQgaW50ZXJmYWNlLgorICogCisgKiBAc2VlIGphdmEuYXd0LkdyYXBoaWNzMkQjc2V0U3Ryb2tlKGphdmEuYXd0LlN0cm9rZSkKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFN0cm9rZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBzdHJva2VkIHNoYXBlLCB3aGljaCBpcyB0aGUgdmVyc2lvbiB0aGF0IGlzIHN1aXRhYmxlIGZvcgorICAgICAqIGRyYXdpbmcgdmlhIHRoZSBHcmFwaGljczJEIGludGVyZmFjZS4gU3Ryb2tpbmcgYSBzaGFwZSBnaXZlcyB0aGUgc2hhcGUncworICAgICAqIG91dGxpbmUgYSB3aWR0aCBvciBkcmF3aW5nIHN0eWxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luYWwgc2hhcGUuCisgICAgICogQHJldHVybiB0aGUgc3Ryb2tlZCBzaGFwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgY3JlYXRlU3Ryb2tlZFNoYXBlKFNoYXBlIHApOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L1Rvb2xraXQuamF2YSBiL2F3dC9qYXZhL2F3dC9Ub29sa2l0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTM4ZDUyNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9Ub29sa2l0LmphdmEKQEAgLTAsMCArMSwxNDQ0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuYXd0OworCitpbXBvcnQgamF2YS5hd3QuZXZlbnQuQVdURXZlbnRMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5BV1RFdmVudExpc3RlbmVyUHJveHk7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuSW5wdXRFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5pbS5JbnB1dE1ldGhvZEhpZ2hsaWdodDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlT2JzZXJ2ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VQcm9kdWNlcjsKK2ltcG9ydCBqYXZhLmF3dC5wZWVyLkZvbnRQZWVyOworaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlU3VwcG9ydDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5DaG9pY2VTdHlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LkNvbXBvbmVudEludGVybmFsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LkNvbnRleHRTdG9yYWdlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuUmVhZE9ubHlJdGVyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5DcmVhdGlvblBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5HcmFwaGljc0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlQ3Vyc29yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlRXZlbnRRdWV1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVFdmVudFRocmVhZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5TaHV0ZG93bldhdGNoZG9nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLlN5bmNocm9uaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5XVEs7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgVG9vbGtpdCBjbGFzcyBpcyB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBsYXRmb3JtLXNwZWNpZmljIEFic3RyYWN0CisgKiBXaW5kb3cgVG9vbGtpdCBpbXBsZW1lbnRhdGlvbi4gVG9vbGtpdCdzIHN1YmNsYXNzZXMgYXJlIHVzZWQgdG8gYmluZCB0aGUKKyAqIHZhcmlvdXMgY29tcG9uZW50cyB0byBwYXJ0aWN1bGFyIG5hdGl2ZSB0b29sa2l0IGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUb29sa2l0IHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBSRUNPVVJDRV9QQVRILgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRUNPVVJDRV9QQVRIID0gIm9yZy5hcGFjaGUuaGFybW9ueS5hd3QucmVzb3VyY2VzLkFXVFByb3BlcnRpZXMiOyAvLyROT04tTkxTLTEkCisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZXNvdXJjZUJ1bmRsZSBwcm9wZXJ0aWVzID0gbG9hZFJlc291cmNlcyhSRUNPVVJDRV9QQVRIKTsKKworICAgIC8qKgorICAgICAqIFRoZSBkaXNwYXRjaGVyLgorICAgICAqLworICAgIERpc3BhdGNoZXIgZGlzcGF0Y2hlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBzeXN0ZW0gZXZlbnQgcXVldWUgY29yZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEV2ZW50UXVldWVDb3JlIHN5c3RlbUV2ZW50UXVldWVDb3JlOworCisgICAgLyoqCisgICAgICogVGhlIGRpc3BhdGNoIHRocmVhZC4KKyAgICAgKi8KKyAgICBFdmVudERpc3BhdGNoVGhyZWFkIGRpc3BhdGNoVGhyZWFkOworCisgICAgLyoqCisgICAgICogVGhlIG5hdGl2ZSB0aHJlYWQuCisgICAgICovCisgICAgTmF0aXZlRXZlbnRUaHJlYWQgbmF0aXZlVGhyZWFkOworCisgICAgLyoqCisgICAgICogVGhlIEFXVCBldmVudHMgbWFuYWdlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQVdURXZlbnRzTWFuYWdlciBhd3RFdmVudHNNYW5hZ2VyOworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEFXVFRyZWVMb2NrLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQVdUVHJlZUxvY2sgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBBV1QgdHJlZSBsb2NrLgorICAgICAqLworICAgIGZpbmFsIE9iamVjdCBhd3RUcmVlTG9jayA9IG5ldyBBV1RUcmVlTG9jaygpOworCisgICAgLyoqCisgICAgICogVGhlIHN5bmNocm9uaXplci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN5bmNocm9uaXplciBzeW5jaHJvbml6ZXIgPSBDb250ZXh0U3RvcmFnZS5nZXRTeW5jaHJvbml6ZXIoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzaHV0ZG93biB3YXRjaGRvZy4KKyAgICAgKi8KKyAgICBmaW5hbCBTaHV0ZG93bldhdGNoZG9nIHNodXRkb3duV2F0Y2hkb2cgPSBuZXcgU2h1dGRvd25XYXRjaGRvZygpOworCisgICAgLyoqCisgICAgICogVGhlIGF1dG8gbnVtYmVyLgorICAgICAqLworICAgIGZpbmFsIEF1dG9OdW1iZXIgYXV0b051bWJlciA9IG5ldyBBdXRvTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXZlbnQgdHlwZSBsb29rdXAuCisgICAgICovCisgICAgZmluYWwgQVdURXZlbnQuRXZlbnRUeXBlTG9va3VwIGV2ZW50VHlwZUxvb2t1cCA9IG5ldyBBV1RFdmVudC5FdmVudFR5cGVMb29rdXAoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBiIGR5bmFtaWMgbGF5b3V0IHNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYkR5bmFtaWNMYXlvdXRTZXQgPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIHNldCBvZiBkZXNrdG9wIHByb3BlcnRpZXMgdGhhdCB1c2VyIHNldCBkaXJlY3RseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEhhc2hTZXQ8U3RyaW5nPiB1c2VyUHJvcFNldCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKworICAgIC8qKgorICAgICAqIFRoZSBkZXNrdG9wIHByb3BlcnRpZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIE1hcDxTdHJpbmcsIE9iamVjdD4gZGVza3RvcFByb3BlcnRpZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVza3RvcCBwcm9wcyBzdXBwb3J0LgorICAgICAqLworICAgIHByb3RlY3RlZCBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgZGVza3RvcFByb3BzU3VwcG9ydDsKKworICAgIC8qKgorICAgICAqIEZvciB0aGlzIGNvbXBvbmVudCB0aGUgbmF0aXZlIHdpbmRvdyBpcyBiZWluZyBjcmVhdGVkIEl0IGlzIHVzZWQgaW4gdGhlCisgICAgICogY2FsbGJhY2stZHJpdmVuIHdpbmRvdyBjcmVhdGlvbiAoZS5nLiBvbiBXaW5kb3dzIGluIHRoZSBoYW5kbGVyIG9mCisgICAgICogV01fQ1JFQVRFIGV2ZW50KSB0byBlc3RhYmxpc2ggdGhlIGNvbm5lY3Rpb24gYmV0d2VlbiB0aGlzIGNvbXBvbmVudCBhbmQKKyAgICAgKiBpdHMgbmF0aXZlIHdpbmRvdy4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCByZWNlbnROYXRpdmVXaW5kb3dDb21wb25lbnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd3RrLgorICAgICAqLworICAgIHByaXZhdGUgV1RLIHd0azsKKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBDb21wb25lbnRJbnRlcm5hbHNJbXBsLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBjbGFzcyBDb21wb25lbnRJbnRlcm5hbHNJbXBsIGV4dGVuZHMgQ29tcG9uZW50SW50ZXJuYWxzIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogU2h1dGRvd24uCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB7CisgICAgICAgICAgICBkaXNwYXRjaFRocmVhZC5zaHV0ZG93bigpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIGRlc2t0b3AgcHJvcGVydHkgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZSBhbmQgZmlyZXMgYSBwcm9wZXJ0eQorICAgICAgICAgKiBjaGFuZ2UgZXZlbnQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHByb3BlcnR5LgorICAgICAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHByb3BlcnR5LgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldERlc2t0b3BQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICBUb29sa2l0LnRoaXMuc2V0RGVza3RvcFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgbG90IG9mIG1ldGhvZHMgbXVzdCB0aHJvdyBIZWFkbGVzc0V4Y2VwdGlvbiBpZgorICAgICAqIDxjb2RlPkdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpPC9jb2RlPiByZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+LgorICAgICAqIAorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgaGVhZGxlc3MgZXhjZXB0aW9uLgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIGNoZWNrSGVhZGxlc3MoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBpZiAoR3JhcGhpY3NFbnZpcm9ubWVudC5nZXRMb2NhbEdyYXBoaWNzRW52aXJvbm1lbnQoKS5pc0hlYWRsZXNzSW5zdGFuY2UoKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBIZWFkbGVzc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvY2sgQVdULgorICAgICAqLworICAgIGZpbmFsIHZvaWQgbG9ja0FXVCgpIHsKKyAgICAgICAgc3luY2hyb25pemVyLmxvY2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGF0aWMgbG9jayBBV1QuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIHZvaWQgc3RhdGljTG9ja0FXVCgpIHsKKyAgICAgICAgQ29udGV4dFN0b3JhZ2UuZ2V0U3luY2hyb25pemVyKCkubG9jaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVubG9jayBBV1QuCisgICAgICovCisgICAgZmluYWwgdm9pZCB1bmxvY2tBV1QoKSB7CisgICAgICAgIHN5bmNocm9uaXplci51bmxvY2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGF0aWMgdW5sb2NrIEFXVC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgdm9pZCBzdGF0aWNVbmxvY2tBV1QoKSB7CisgICAgICAgIENvbnRleHRTdG9yYWdlLmdldFN5bmNocm9uaXplcigpLnVubG9jaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludm9rZUFuZFdhaXQgdW5kZXIgQVdUIGxvY2suIFcvbyB0aGlzIG1ldGhvZCBzeXN0ZW0gY2FuIGhhbmcgdXAuIEFkZGVkCisgICAgICogdG8gc3VwcG9ydCBtb2RhbGl0eSAoRGlhbG9nLnNob3coKSAmIFBvcHVwTWVudS5zaG93KCkpIGZyb20gbm90IGV2ZW50CisgICAgICogZGlzcGF0Y2ggdGhyZWFkLiBVc2UgaW4gb3RoZXIgY2FzZXMgaXMgbm90IHJlY29tbWVuZGVkLiBTdGlsbCBjYW4gYmUKKyAgICAgKiBjYWxsZWQgb25seSBmb3Igd2hvbGUgQVBJIG1ldGhvZHMgdGhhdCBjYW5ub3QgYmUgY2FsbGVkIGZyb20gb3RoZXIKKyAgICAgKiBjbGFzc2VzIEFQSSBtZXRob2RzLiBFeGFtcGxlczogc2hvdygpIGZvciBtb2RhbCBkaWFsb2dzIC0gY29ycmVjdCwgb25seQorICAgICAqIHVzZXIgY2FuIGNhbGwgaXQsIGRpcmVjdGx5IG9yIHRocm91Z2ggc2V0VmlzaWJsZSh0cnVlKSBzZXRCb3VuZHMoKSBmb3IKKyAgICAgKiBjb21wb25lbnRzIC0gaW5jb3JyZWN0LCBzZXRCb3VuZHMoKSBjYW4gYmUgY2FsbGVkIGZyb20gbGF5b3V0Q29udGFpbmVyKCkKKyAgICAgKiBmb3IgbGF5b3V0IG1hbmFnZXJzCisgICAgICogCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICB0aGUgcnVubmFibGUuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBpbnRlcnJ1cHRlZCBleGNlcHRpb24uCisgICAgICogQHRocm93cyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdGhlIGludm9jYXRpb24gdGFyZ2V0IGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBmaW5hbCB2b2lkIHVuc2FmZUludm9rZUFuZFdhaXQoUnVubmFibGUgcnVubmFibGUpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZXIuc3RvcmVTdGF0ZUFuZEZyZWUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEV2ZW50UXVldWUuaW52b2tlQW5kV2FpdChydW5uYWJsZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZXIubG9ja0FuZFJlc3RvcmVTdGF0ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3luY2hyb25pemVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN5bmNocm9uaXplci4KKyAgICAgKi8KKyAgICBmaW5hbCBTeW5jaHJvbml6ZXIgZ2V0U3luY2hyb25pemVyKCkgeworICAgICAgICByZXR1cm4gc3luY2hyb25pemVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdUSy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB3VEsuCisgICAgICovCisgICAgZmluYWwgV1RLIGdldFdUSygpIHsKKyAgICAgICAgcmV0dXJuIHd0azsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGFuZCBkZWZhdWx0IHZhbHVlLiBUaGlzIG1ldGhvZAorICAgICAqIHJldHVybnMgdGhlIGRlZlZhbHVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3BOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBwcm9wZXJ0eS4KKyAgICAgKiBAcGFyYW0gZGVmVmFsCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcm9wZXJ0eSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcE5hbWUsIFN0cmluZyBkZWZWYWwpIHsKKyAgICAgICAgaWYgKHByb3BOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC43RD1Qcm9wZXJ0eSBuYW1lIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC43RCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHN0YXRpY0xvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyByZXRWYWwgPSBudWxsOworICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJldFZhbCA9IHByb3BlcnRpZXMuZ2V0U3RyaW5nKHByb3BOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIChyZXRWYWwgPT0gbnVsbCkgPyBkZWZWYWwgOiByZXRWYWw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdGF0aWNVbmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgVG9vbGtpdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IFRvb2xraXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUb29sa2l0IGdldERlZmF1bHRUb29sa2l0KCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKENvbnRleHRTdG9yYWdlLmdldENvbnRleHRMb2NrKCkpIHsKKyAgICAgICAgICAgIGlmIChDb250ZXh0U3RvcmFnZS5zaHV0ZG93blBlbmRpbmcoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgVG9vbGtpdCBkZWZUb29sa2l0ID0gQ29udGV4dFN0b3JhZ2UuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICAgICAgICAgIGlmIChkZWZUb29sa2l0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZGVmVG9vbGtpdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN0YXRpY0xvY2tBV1QoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGVmVG9vbGtpdCA9IEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpID8gbmV3IEhlYWRsZXNzVG9vbGtpdCgpCisgICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBUb29sa2l0SW1wbCgpOworICAgICAgICAgICAgICAgIENvbnRleHRTdG9yYWdlLnNldERlZmF1bHRUb29sa2l0KGRlZlRvb2xraXQpOworICAgICAgICAgICAgICAgIHJldHVybiBkZWZUb29sa2l0OworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdGF0aWNVbmxvY2tBV1QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRPRE86IHJlYWQgc3lzdGVtIHByb3BlcnR5IG5hbWVkIGF3dC50b29sa2l0CisgICAgICAgICAgICAvLyBhbmQgY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgY2xhc3MsCisgICAgICAgICAgICAvLyBieSBkZWZhdWx0IHVzZSBUb29sa2l0SW1wbAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBGb250LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgRm9udCBmb3IgVG9vbGtpdC4KKyAgICAgKi8KKyAgICBGb250IGdldERlZmF1bHRGb250KCkgeworICAgICAgICByZXR1cm4gd3RrLmdldFN5c3RlbVByb3BlcnRpZXMoKS5nZXREZWZhdWx0Rm9udCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgcmVzb3VyY2VzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwYXRoCisgICAgICogICAgICAgICAgICB0aGUgcGF0aC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBidW5kbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgbG9hZFJlc291cmNlcyhTdHJpbmcgcGF0aCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShwYXRoKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd1RLIGNsYXNzIG5hbWUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd1RLIGNsYXNzIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldFdUS0NsYXNzTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuICJjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3QuQW5kcm9pZFdUSyI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29tcG9uZW50IGJ5IGlkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZAorICAgICAqICAgICAgICAgICAgdGhlIGlkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbXBvbmVudCBieSBpZC4KKyAgICAgKi8KKyAgICBDb21wb25lbnQgZ2V0Q29tcG9uZW50QnlJZChsb25nIGlkKSB7CisgICAgICAgIGlmIChpZCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBHcmFwaGljc0ZhY3RvcnkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgR3JhcGhpY3NGYWN0b3J5IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhcGhpY3NGYWN0b3J5IGdldEdyYXBoaWNzRmFjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIHd0ay5nZXRHcmFwaGljc0ZhY3RvcnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgdG9vbGtpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVG9vbGtpdCgpIHsKKyAgICAgICAgaW5pdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYXRlcyBBV1QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29tcG9uZW50SW50ZXJuYWxzLnNldENvbXBvbmVudEludGVybmFscyhuZXcgQ29tcG9uZW50SW50ZXJuYWxzSW1wbCgpKTsKKyAgICAgICAgICAgIG5ldyBFdmVudFF1ZXVlKHRoaXMpOyAvLyBjcmVhdGUgdGhlIHN5c3RlbSBFdmVudFF1ZXVlCisgICAgICAgICAgICBkaXNwYXRjaGVyID0gbmV3IERpc3BhdGNoZXIodGhpcyk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gZ2V0V1RLQ2xhc3NOYW1lKCk7CisgICAgICAgICAgICBkZXNrdG9wUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgT2JqZWN0PigpOworICAgICAgICAgICAgZGVza3RvcFByb3BzU3VwcG9ydCA9IG5ldyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQodGhpcyk7CisgICAgICAgICAgICBhd3RFdmVudHNNYW5hZ2VyID0gbmV3IEFXVEV2ZW50c01hbmFnZXIoKTsKKyAgICAgICAgICAgIGRpc3BhdGNoVGhyZWFkID0gbmV3IEV2ZW50RGlzcGF0Y2hUaHJlYWQodGhpcywgZGlzcGF0Y2hlcik7CisgICAgICAgICAgICBuYXRpdmVUaHJlYWQgPSBuZXcgTmF0aXZlRXZlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIE5hdGl2ZUV2ZW50VGhyZWFkLkluaXQgaW5pdCA9IG5ldyBOYXRpdmVFdmVudFRocmVhZC5Jbml0KCkgeworICAgICAgICAgICAgICAgIHB1YmxpYyBXVEsgaW5pdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgd3RrID0gY3JlYXRlV1RLKGNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIHd0ay5nZXROYXRpdmVFdmVudFF1ZXVlKCkuc2V0U2h1dGRvd25XYXRjaGRvZyhzaHV0ZG93bldhdGNoZG9nKTsKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVyLnNldEVudmlyb25tZW50KHd0aywgZGlzcGF0Y2hUaHJlYWQpOworICAgICAgICAgICAgICAgICAgICBDb250ZXh0U3RvcmFnZS5zZXRXVEsod3RrKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHd0azsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICAgICAgbmF0aXZlVGhyZWFkLnN0YXJ0KGluaXQpOworICAgICAgICAgICAgZGlzcGF0Y2hUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgICAgIHd0ay5nZXROYXRpdmVFdmVudFF1ZXVlKCkuYXdha2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3luY2hyb25pemVzIHRoaXMgdG9vbGtpdCdzIGdyYXBoaWNzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN5bmMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnN0cnVjdGlvbiBzdGF0dXMgb2YgYSBzcGVjaWZpZWQgaW1hZ2UgdGhhdCBpcyBiZWluZworICAgICAqIGNyZWF0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgdG8gYmUgY2hlY2tlZC4KKyAgICAgKiBAcGFyYW0gYTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBzY2FsZWQgaW1hZ2UgZm9yIHdoaWNoIHRoZSBzdGF0dXMgaXMgYmVpbmcKKyAgICAgKiAgICAgICAgICAgIGNoZWNrZWQgb3IgLTEuCisgICAgICogQHBhcmFtIGEyCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHNjYWxlZCBpbWFnZSBmb3Igd2hpY2ggdGhlIHN0YXR1cyBpcyBiZWluZworICAgICAqICAgICAgICAgICAgY2hlY2tlZCBvciAtMS4KKyAgICAgKiBAcGFyYW0gYTMKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZU9ic2VydmVyIG9iamVjdCB0byBiZSBub3RpZmllZCB3aGlsZSB0aGUgaW1hZ2UgaXMKKyAgICAgKiAgICAgICAgICAgIGJlaW5nIHByZXBhcmVkLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlT2JzZXJ2ZXIgZmxhZ3Mgd2hpY2ggZ2l2ZSB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgaW1hZ2UKKyAgICAgKiAgICAgICAgIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBjaGVja0ltYWdlKEltYWdlIGEwLCBpbnQgYTEsIGludCBhMiwgSW1hZ2VPYnNlcnZlciBhMyk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgSW1hZ2VQcm9kdWNlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVByb2R1Y2VyIHRvIGJlIHVzZWQgZm9yIGltYWdlIGNyZWF0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBJbWFnZVByb2R1Y2VyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbWFnZSBjcmVhdGVJbWFnZShJbWFnZVByb2R1Y2VyIGEwKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGltYWdlIGZyb20gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5LCBvZmZzZXQgYW5kIGxlbmd0aC4gVGhlCisgICAgICogYnl0ZSBhcnJheSBzaG91bGQgY29udGFpbiBkYXRhIHdpdGggaW1hZ2UgZm9ybWF0IHN1cHBvcnRlZCBieSBUb29sa2l0CisgICAgICogc3VjaCBhcyBKUEVHLCBHSUYsIG9yIFBORy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IHdpdGggdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGExCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBiZWdpbm5pbmcgdGhlIGltYWdlIGRhdGEgaW4gdGhlIGJ5dGUgYXJyYXkuCisgICAgICogQHBhcmFtIGEyCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbWFnZSBkYXRhIGluIHRoZSBieXRlIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlIGNyZWF0ZUltYWdlKGJ5dGVbXSBhMCwgaW50IGExLCBpbnQgYTIpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgaW1hZ2UgdXNpbmcgaW1hZ2UgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQgVVJMLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCBmb3IgZXh0cmFjdGluZyBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbWFnZSBjcmVhdGVJbWFnZShVUkwgYTApOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgaW1hZ2UgdXNpbmcgaW1hZ2UgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQgZmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlIG5hbWUgd2hpY2ggY29udGFpbnMgaW1hZ2UgZGF0YSBvZiBzdXBwb3J0ZWQgZm9ybWF0LgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbWFnZSBjcmVhdGVJbWFnZShTdHJpbmcgYTApOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQ29sb3JNb2RlbCBvZiBUb29sa2l0J3Mgc2NyZWVuLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NyZWVuIGRldmljZSBtZXRyaWNzIGZvciB0aGUgc3BlY2lmaWVkIGZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGZvbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250LgorICAgICAqIEByZXR1cm4gdGhlIEZvbnRNZXRyaWNzIGZvciB0aGUgc3BlY2lmaWVkIEZvbnQuCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIGdldExpbmVNZXRyaWNzIG1ldGhvZCBmcm9tIEZvbnQgY2xhc3MuCisgICAgICovCisKKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBhYnN0cmFjdCBGb250TWV0cmljcyBnZXRGb250TWV0cmljcyhGb250IGZvbnQpOworCisgICAgLyoqCisgICAgICogUHJlcGFyZXMgdGhlIHNwZWNpZmllZCBpbWFnZSBmb3IgcmVuZGVyaW5nIG9uIHRoZSBzY3JlZW4gd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgc2l6ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZSB0byBiZSBwcmVwYXJlZC4KKyAgICAgKiBAcGFyYW0gYTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgc2NyZWVuIHJlcHJlc2VudGF0aW9uIG9yIC0xIGZvciB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgc2NyZWVuLgorICAgICAqIEBwYXJhbSBhMgorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgc2NyZWVuIHJlcHJlc2VudGF0aW9uIG9yIC0xIGZvciB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgc2NyZWVuLgorICAgICAqIEBwYXJhbSBhMworICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT2JzZXJ2ZXIgb2JqZWN0IHRvIGJlIG5vdGlmaWVkIGFzIHNvb24gYXMgdGhlIGltYWdlCisgICAgICogICAgICAgICAgICBpcyBwcmVwYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGltYWdlIGlzIGZ1bGx5IHByZXBhcmVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gcHJlcGFyZUltYWdlKEltYWdlIGEwLCBpbnQgYTEsIGludCBhMiwgSW1hZ2VPYnNlcnZlciBhMyk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGF1ZGlvIGJlZXAuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYmVlcCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgZm9udCBuYW1lcyB3aGljaCBhcmUgYXZhaWxhYmxlIGluIHRoaXMgVG9vbGtpdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBmb250IG5hbWVzIHdoaWNoIGFyZSBhdmFpbGFibGUgaW4gdGhpcyBUb29sa2l0LgorICAgICAqIEBkZXByZWNhdGVkIHVzZSBHcmFwaGljc0Vudmlyb25tZW50LmdldEF2YWlsYWJsZUZvbnRGYW1pbHlOYW1lcygpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRGb250TGlzdCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGhlIEZvbnQgaW1wbGVtZW50YXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBwZWVyIGludGVyZmFjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250IG5hbWUgdG8gYmUgaW1wbGVtZW50ZWQuCisgICAgICogQHBhcmFtIGExCisgICAgICogICAgICAgICAgICB0aGUgdGhlIGZvbnQgc3R5bGU6IFBMQUlOLCBCT0xELCBJVEFMSUMuCisgICAgICogQHJldHVybiB0aGUgRm9udFBlZXIgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBGb250LgorICAgICAqIEBkZXByZWNhdGVkIHVzZSBqYXZhLmF3dC5HcmFwaGljc0Vudmlyb25tZW50LmdldEFsbEZvbnRzIG1ldGhvZC4KKyAgICAgKi8KKworICAgIEBEZXByZWNhdGVkCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IEZvbnRQZWVyIGdldEZvbnRQZWVyKFN0cmluZyBhMCwgaW50IGExKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGltYWdlIGZyb20gdGhlIHNwZWNpZmllZCBmaWxlIHdoaWNoIGNvbnRhaW5zIGltYWdlIGRhdGEgaW4gYQorICAgICAqIHN1cHBvcnRlZCBpbWFnZSBmb3JtYXQgKHN1Y2ggYXMgSlBFRywgR0lGLCBvciBQTkcpOyB0aGlzIG1ldGhvZCBzaG91bGQKKyAgICAgKiByZXR1cm4gdGhlIHNhbWUgSW1hZ2UgZm9yIG11bHRpcGxlIGNhbGxzIG9mIHRoaXMgbWV0aG9kIHdpdGggdGhlIHNhbWUKKyAgICAgKiBpbWFnZSBmaWxlIG5hbWUuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSBuYW1lIHdoaWNoIGNvbnRhaW5zIGltYWdlIGRhdGEgaW4gYSBzdXBwb3J0ZWQgaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIGZvcm1hdCAoc3VjaCBhcyBKUEVHLCBHSUYsIG9yIFBORykuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlIGdldEltYWdlKFN0cmluZyBhMCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbWFnZSBmcm9tIHRoZSBzcGVjaWZpZWQgVVJMIHdoaWNoIGNvbnRhaW5zIGltYWdlIGRhdGEgaW4gYQorICAgICAqIHN1cHBvcnRlZCBpbWFnZSBmb3JtYXQgKHN1Y2ggYXMgSlBFRywgR0lGLCBvciBQTkcpOyB0aGlzIG1ldGhvZCBzaG91bGQKKyAgICAgKiByZXR1cm4gdGhlIHNhbWUgSW1hZ2UgZm9yIG11bHRpcGxlIGNhbGxzIG9mIHRoaXMgbWV0aG9kIHdpdGggdGhlIHNhbWUKKyAgICAgKiBpbWFnZSBVUkwuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgVVJMIHdoaWNoIGNvbnRhaW5zIGltYWdlIGRhdGEgaW4gYSBzdXBwb3J0ZWQgaW1hZ2UgZm9ybWF0CisgICAgICogICAgICAgICAgICAoc3VjaCBhcyBKUEVHLCBHSUYsIG9yIFBORykuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlIGdldEltYWdlKFVSTCBhMCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzY3JlZW4gcmVzb2x1dGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzY3JlZW4gcmVzb2x1dGlvbi4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRTY3JlZW5SZXNvbHV0aW9uKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NyZWVuIHNpemUuCisgICAgICogCisgICAgICogQHJldHVybiBhIERpbWVuc2lvbiBvYmplY3QgY29udGFpbmluZyB0aGUgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgc2NyZWVuLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGltZW5zaW9uIGdldFNjcmVlblNpemUoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBFdmVudFF1ZXVlIGluc3RhbmNlIHdpdGhvdXQgY2hlY2tpbmcgYWNjZXNzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBFdmVudFF1ZXVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBFdmVudFF1ZXVlIGdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbWFwIG9mIHRleHQgYXR0cmlidXRlcyBmb3IgdGhlIGFic3RyYWN0IGxldmVsIGRlc2NyaXB0aW9uIG9mCisgICAgICogdGhlIHNwZWNpZmllZCBpbnB1dCBtZXRob2QgaGlnaGxpZ2h0LCBvciBudWxsIGlmIG5vIG1hcHBpbmcgaXMgZm91bmQuCisgICAgICogCisgICAgICogQHBhcmFtIGhpZ2hsaWdodAorICAgICAqICAgICAgICAgICAgdGhlIElucHV0TWV0aG9kSGlnaGxpZ2h0LgorICAgICAqIEByZXR1cm4gdGhlIE1hcDxqYXZhLmF3dC5mb250LiB0ZXh0IGF0dHJpYnV0ZSw/Pi4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE1hcDxqYXZhLmF3dC5mb250LlRleHRBdHRyaWJ1dGUsID8+IG1hcElucHV0TWV0aG9kSGlnaGxpZ2h0KAorICAgICAgICAgICAgSW5wdXRNZXRob2RIaWdobGlnaHQgaGlnaGxpZ2h0KSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNYXAgaW5wdXQgbWV0aG9kIGhpZ2hsaWdodCBpbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaWdobGlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoaWdobGlnaHQuCisgICAgICogQHJldHVybiB0aGUgbWFwPGphdmEuYXd0LmZvbnQuIHRleHQgYXR0cmlidXRlLD8+LgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgaGVhZGxlc3MgZXhjZXB0aW9uLgorICAgICAqLworICAgIE1hcDxqYXZhLmF3dC5mb250LlRleHRBdHRyaWJ1dGUsID8+IG1hcElucHV0TWV0aG9kSGlnaGxpZ2h0SW1wbChJbnB1dE1ldGhvZEhpZ2hsaWdodCBoaWdobGlnaHQpCisgICAgICAgICAgICB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBIYXNoTWFwPGphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZSwgPz4gbWFwID0gbmV3IEhhc2hNYXA8amF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlLCBPYmplY3Q+KCk7CisgICAgICAgIHd0ay5nZXRTeXN0ZW1Qcm9wZXJ0aWVzKCkubWFwSW5wdXRNZXRob2RIaWdobGlnaHQoaGlnaGxpZ2h0LCBtYXApOworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuPGphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZSwgT2JqZWN0PiB1bm1vZGlmaWFibGVNYXAobWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIHByb3BlcnR5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUgZm9yIHdoaWNoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgd2lsbCBiZSBhZGRlZC4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoU3RyaW5nIHByb3BOYW1lLCBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGwpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGRlc2t0b3BQcm9wZXJ0aWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIGluaXRpYWxpemVEZXNrdG9wUHJvcGVydGllcygpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGwgIT0gbnVsbCkgeyAvLyB0aGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCBudWxsIGxpc3RlbmVyIHdpbGwgbm90IGJlCisgICAgICAgICAgICAvLyBhZGRlZAorICAgICAgICAgICAgZGVza3RvcFByb3BzU3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKHByb3BOYW1lLCBsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHByb3BlcnR5IGNoYW5nZSBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCB3aXRoIHRoaXMKKyAgICAgKiBUb29sa2l0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIHByb3BlcnR5IGNoYW5nZSBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCB3aXRoIHRoaXMKKyAgICAgKiAgICAgICAgIFRvb2xraXQuCisgICAgICovCisgICAgcHVibGljIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJbXSBnZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpIHsKKyAgICAgICAgcmV0dXJuIGRlc2t0b3BQcm9wc1N1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRoZSBwcm9wZXJ0eSBjaGFuZ2UgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGlzCisgICAgICogVG9vbGtpdCBmb3Igbm90aWZpY2F0aW9uIHJlZ2FyZGluZyB0aGUgc3BlY2lmaWVkIHByb3BlcnR5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUgZm9yIHdoaWNoIHRoZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHdhcworICAgICAqICAgICAgICAgICAgcmVnaXN0ZXJlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycyByZWdpc3RlcmVkIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBwcm9wZXJ0eSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyW10gZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoU3RyaW5nIHByb3BOYW1lKSB7CisgICAgICAgIHJldHVybiBkZXNrdG9wUHJvcHNTdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKHByb3BOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkgY2hhbmdlIGxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoZQorICAgICAqIHNwZWNpZmllZCBwcm9wZXJ0eSBuYW1lLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHJlZ2lzdGVyZWQgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IG5hbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihTdHJpbmcgcHJvcE5hbWUsIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbCkgeworICAgICAgICBkZXNrdG9wUHJvcHNTdXBwb3J0LnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIocHJvcE5hbWUsIGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBjdXN0b20gY3Vyc29yIHdpdGggdGhlIHNwZWNpZmllZCBJbWFnZSwgaG90IHNwb3QsIGFuZCBjdXJzb3IKKyAgICAgKiBkZXNjcmlwdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1nCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2Ugb2YgYWN0aXZhdGVkIGN1cnNvci4KKyAgICAgKiBAcGFyYW0gaG90U3BvdAorICAgICAqICAgICAgICAgICAgdGhlIFBvaW50IGdpdmluZyB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGN1cnNvcidzIGhvdCBzcG90LgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgY3Vyc29yIGRlc2NyaXB0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIGN1cnNvciB3aXRoIHRoZSBzcGVjaWZpZWQgSW1hZ2UsIGhvdCBzcG90LCBhbmQgY3Vyc29yCisgICAgICogICAgICAgICBkZXNjcmlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG90IHNwb3QgdmFsdWVzIGFyZSBvdXRzaWRlIHRoZSBib3VuZHMgb2YgdGhlIGN1cnNvci4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaXNIZWFkbGVzcygpIG1ldGhvZCBvZiBHcmFwaGljc0Vudmlyb25tZW50IGNsYXNzIHJldHVybnMKKyAgICAgKiAgICAgICAgICAgICB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBDdXJzb3IgY3JlYXRlQ3VzdG9tQ3Vyc29yKEltYWdlIGltZywgUG9pbnQgaG90U3BvdCwgU3RyaW5nIG5hbWUpCisgICAgICAgICAgICB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiwgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgdyA9IGltZy5nZXRXaWR0aChudWxsKSwgeCA9IGhvdFNwb3QueDsKKyAgICAgICAgICAgIGludCBoID0gaW1nLmdldEhlaWdodChudWxsKSwgeSA9IGhvdFNwb3QueTsKKyAgICAgICAgICAgIGlmICh4IDwgMCB8fCB4ID49IHcgfHwgeSA8IDAgfHwgeSA+PSBoKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjdFPWludmFsaWQgaG90U3BvdAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjdFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEN1cnNvcihuYW1lLCBpbWcsIGhvdFNwb3QpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdXBwb3J0ZWQgY3Vyc29yIGRpbWVuc2lvbiB3aGljaCBpcyBjbG9zZXN0IHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB3aWR0aCBhbmQgaGVpZ2h0LiBJZiB0aGUgVG9vbGtpdCBvbmx5IHN1cHBvcnRzIGEgc2luZ2xlIGN1cnNvciBzaXplLCB0aGlzCisgICAgICogbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIHN1cHBvcnRlZCBjdXJzb3Igc2l6ZS4gSWYgY3VzdG9tIGN1cnNvciBpcyBub3QKKyAgICAgKiBzdXBwb3J0ZWQsIGEgZGltZW5zaW9uIG9mIDAsIDAgc2hvdWxkIGJlIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcmVmV2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJyZWQgY3Vyc29yIHdpZHRoLgorICAgICAqIEBwYXJhbSBwcmVmSGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVycmVkIGN1cnNvciBoZWlnaHQuCisgICAgICogQHJldHVybiB0aGUgc3VwcG9ydGVkIGN1cnNvciBkaW1lbnNpb24gd2hpY2ggaXMgY2xvc2VzdCB0byB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBHcmFwaGljc0Vudmlyb25tZW50LmlzSGVhZGxlc3MoKSByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRCZXN0Q3Vyc29yU2l6ZShpbnQgcHJlZldpZHRoLCBpbnQgcHJlZkhlaWdodCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHd0ay5nZXRDdXJzb3JGYWN0b3J5KCkuZ2V0QmVzdEN1cnNvclNpemUocHJlZldpZHRoLCBwcmVmSGVpZ2h0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgZGVza3RvcCBwcm9wZXJ0eS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIE9iamVjdCB0aGF0IGlzIHRoZSBwcm9wZXJ0eSdzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0RGVza3RvcFByb3BlcnR5KFN0cmluZyBwcm9wTmFtZSkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZGVza3RvcFByb3BlcnRpZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgaW5pdGlhbGl6ZURlc2t0b3BQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocHJvcE5hbWUuZXF1YWxzKCJhd3QuZHluYW1pY0xheW91dFN1cHBvcnRlZCIpKSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAvLyBkeW5hbWljTGF5b3V0U3VwcG9ydGVkIGlzIHNwZWNpYWwgY2FzZQorICAgICAgICAgICAgICAgIHJldHVybiBCb29sZWFuLnZhbHVlT2YoaXNEeW5hbWljTGF5b3V0QWN0aXZlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT2JqZWN0IHZhbCA9IGRlc2t0b3BQcm9wZXJ0aWVzLmdldChwcm9wTmFtZSk7CisgICAgICAgICAgICBpZiAodmFsID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyB0cnkgdG8gbGF6aWx5IGxvYWQgcHJvcCB2YWx1ZQorICAgICAgICAgICAgICAgIC8vIGp1c3QgZm9yIGNvbXBhdGliaWxpdHksIG91ciBsYXppbHlMb2FkIGlzIGVtcHR5CisgICAgICAgICAgICAgICAgdmFsID0gbGF6aWx5TG9hZERlc2t0b3BQcm9wZXJ0eShwcm9wTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NraW5nIGtleSBzdGF0ZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUga2V5IGNvZGU6IFZLX0NBUFNfTE9DSywgVktfTlVNX0xPQ0ssIFZLX1NDUk9MTF9MT0NLLCBvcgorICAgICAqICAgICAgICAgICAgVktfS0FOQV9MT0NLLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGtleSBjb2RlIGlzIGluIHRoZSBsb2NrZWQgc3RhdGUsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdGF0ZSBvZiB0aGlzIGtleSBjYW4ndCBiZSByZXRyaWV2ZWQsIG9yIGlmIHRoZQorICAgICAqICAgICAgICAgICAgIGtleWJvYXJkIGRvZXNuJ3QgaGF2ZSB0aGlzIGtleS4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldExvY2tpbmdLZXlTdGF0ZShpbnQgYTApIHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiwKKyAgICAgICAgICAgIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy9UT0RPOiBpbXBsZW1lbnQgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbG9ycyB3aGljaCB0aGUgVG9vbGtpdCBzdXBwb3J0cyBmb3IKKyAgICAgKiBjdXN0b20gY3Vyc29yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gY3Vyc29yIGNvbG9ycy4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhpbXVtQ3Vyc29yQ29sb3JzKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHd0ay5nZXRDdXJzb3JGYWN0b3J5KCkuZ2V0TWF4aW11bUN1cnNvckNvbG9ycygpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZW51IHNob3J0Y3V0IGtleSBtYXNrLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1lbnUgc2hvcnRjdXQga2V5IG1hc2suCisgICAgICogQHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBHcmFwaGljc0Vudmlyb25tZW50LmlzSGVhZGxlc3MoKSBtZXRob2QgcmV0dXJucyB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWVudVNob3J0Y3V0S2V5TWFzaygpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBJbnB1dEV2ZW50LkNUUkxfTUFTSzsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NyZWVuIGluc2V0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2MKKyAgICAgKiAgICAgICAgICAgIHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24uCisgICAgICogQHJldHVybiB0aGUgaW5zZXRzIG9mIHRoaXMgdG9vbGtpdC4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIEluc2V0cyBnZXRTY3JlZW5JbnNldHMoR3JhcGhpY3NDb25maWd1cmF0aW9uIGdjKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBpZiAoZ2MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnNldHMoMCwgMCwgMCwgMCk7IC8vIFRPRE86IGdldCByZWFsIHNjcmVlbiBpbnNldHMKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3lzdGVtIEV2ZW50UXVldWUgaW5zdGFuY2UuIElmIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mCisgICAgICogY2hlY2tBd3RFdmVudFF1ZXVlQWNjZXNzIGlzIHVzZWQsIHRoZW4gdGhpcyByZXN1bHRzIG9mIGEgY2FsbCB0byB0aGUKKyAgICAgKiBzZWN1cml0eSBtYW5hZ2VyJ3MgY2hlY2tQZXJtaXNzaW9uIG1ldGhvZCB3aXRoIGFuCisgICAgICogQVdUUGVybWlzc2lvbigiYWNjZXNzRXZlbnRRdWV1ZSIpIHBlcm1pc3Npb24uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIEV2ZW50UXVldWUgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEV2ZW50UXVldWUgZ2V0U3lzdGVtRXZlbnRRdWV1ZSgpIHsKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgc20uY2hlY2tBd3RFdmVudFF1ZXVlQWNjZXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldFN5c3RlbUV2ZW50UXVldWVJbXBsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3lzdGVtIGV2ZW50IHF1ZXVlIGNvcmUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIGV2ZW50IHF1ZXVlIGNvcmUuCisgICAgICovCisgICAgRXZlbnRRdWV1ZUNvcmUgZ2V0U3lzdGVtRXZlbnRRdWV1ZUNvcmUoKSB7CisgICAgICAgIHJldHVybiBzeXN0ZW1FdmVudFF1ZXVlQ29yZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzeXN0ZW0gZXZlbnQgcXVldWUgY29yZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29yZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBzeXN0ZW0gZXZlbnQgcXVldWUgY29yZS4KKyAgICAgKi8KKyAgICB2b2lkIHNldFN5c3RlbUV2ZW50UXVldWVDb3JlKEV2ZW50UXVldWVDb3JlIGNvcmUpIHsKKyAgICAgICAgc3lzdGVtRXZlbnRRdWV1ZUNvcmUgPSBjb3JlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgdGhlIGRlc2t0b3AgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbml0aWFsaXplRGVza3RvcFByb3BlcnRpZXMoKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHd0ay5nZXRTeXN0ZW1Qcm9wZXJ0aWVzKCkuaW5pdChkZXNrdG9wUHJvcGVydGllcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBkeW5hbWljIGxheW91dCBvZiBDb250YWluZXJzIGlzIGFjdGl2ZSBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBkeW5hbWljIGxheW91dCBvZiBDb250YWluZXJzIGlzIGFjdGl2ZSwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEdyYXBoaWNzRW52aXJvbm1lbnQuaXNIZWFkbGVzcygpIG1ldGhvZCByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEeW5hbWljTGF5b3V0QWN0aXZlKCkgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gYWx3YXlzIHJldHVybiB0cnVlCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBpZiB0aGUgbGF5b3V0IG9mIENvbnRhaW5lcnMgaXMgY2hlY2tlZCBkeW5hbWljYWxseSBkdXJpbmcKKyAgICAgKiByZXNpemluZywgb3Igc3RhdGljYWxseSBhZnRlciByZXNpemluZyBpcyBjb21wbGV0ZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBpZiB0aGUgbGF5b3V0IG9mIENvbnRhaW5lcnMgaXMgY2hlY2tlZCBkeW5hbWljYWxseQorICAgICAqICAgICAgICAgZHVyaW5nIHJlc2l6aW5nOyBmYWxzZSwgaWYgdGhlIGxheW91dCBvZiBDb250YWluZXJzIGlzIGNoZWNrZWQKKyAgICAgKiAgICAgICAgIHN0YXRpY2FsbHkgYWZ0ZXIgcmVzaXppbmcgaXMgY29tcGxldGVkLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0R5bmFtaWNMYXlvdXRTZXQoKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gYkR5bmFtaWNMYXlvdXRTZXQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIGZyYW1lIHN0YXRlIGlzIHN1cHBvcnRlZCBieSBUb29sa2l0IG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmcmFtZSBzdGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGZyYW1lIHN0YXRlIGlzIHN1cHBvcnRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyYW1lU3RhdGVTdXBwb3J0ZWQoaW50IHN0YXRlKSB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24geworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gd3RrLmdldFdpbmRvd0ZhY3RvcnkoKS5pc1dpbmRvd1N0YXRlU3VwcG9ydGVkKHN0YXRlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgdGhlIHZhbHVlIG9mIHRoZSBkZXNrdG9wIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBuYW1lLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgZGVza3RvcCBwcm9wZXJ0eSB2YWx1ZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCBsYXppbHlMb2FkRGVza3RvcFByb3BlcnR5KFN0cmluZyBwcm9wTmFtZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyB0aGUgY3VycmVudCBzeXN0ZW0gY29sb3IgdmFsdWVzIHRvIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9ycworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdoZXJlIHRoZSBjdXJyZW50IHN5c3RlbSBjb2xvciB2YWx1ZXMgYXJlIHdyaXR0ZW4gYnkKKyAgICAgKiAgICAgICAgICAgIHRoaXMgbWV0aG9kLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBsb2FkU3lzdGVtQ29sb3JzKGludFtdIGNvbG9ycykgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZGVza3RvcCBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvcE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSdzIG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkncyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXREZXNrdG9wUHJvcGVydHkoU3RyaW5nIHByb3BOYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgT2JqZWN0IG9sZFZhbDsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2xkVmFsID0gZ2V0RGVza3RvcFByb3BlcnR5KHByb3BOYW1lKTsKKyAgICAgICAgICAgIHVzZXJQcm9wU2V0LmFkZChwcm9wTmFtZSk7CisgICAgICAgICAgICBkZXNrdG9wUHJvcGVydGllcy5wdXQocHJvcE5hbWUsIHZhbHVlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGRlc2t0b3BQcm9wc1N1cHBvcnQuZmlyZVByb3BlcnR5Q2hhbmdlKHByb3BOYW1lLCBvbGRWYWwsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsYXlvdXQgc3RhdGUsIHdoZXRoZXIgdGhlIENvbnRhaW5lciBsYXlvdXQgaXMgY2hlY2tlZAorICAgICAqIGR5bmFtaWNhbGx5IGR1cmluZyByZXNpemluZywgb3Igc3RhdGljYWxseSBhZnRlciByZXNpemluZyBpcyBjb21wbGV0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGR5bmFtaWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZHluYW1pYyBsYXlvdXQgc3RhdGUgLSBpZiB0cnVlIHRoZSBsYXlvdXQgb2YKKyAgICAgKiAgICAgICAgICAgIENvbnRhaW5lcnMgaXMgY2hlY2tlZCBkeW5hbWljYWxseSBkdXJpbmcgcmVzaXppbmcsIGlmIGZhbHNlIC0KKyAgICAgKiAgICAgICAgICAgIHN0YXRpY2FsbHkgYWZ0ZXIgcmVzaXppbmcgaXMgY29tcGxldGVkLgorICAgICAqIEB0aHJvd3MgSGVhZGxlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgR3JhcGhpY3NFbnZpcm9ubWVudC5pc0hlYWRsZXNzKCkgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREeW5hbWljTGF5b3V0KGJvb2xlYW4gZHluYW1pYykgdGhyb3dzIEhlYWRsZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYkR5bmFtaWNMYXlvdXRTZXQgPSBkeW5hbWljOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2NraW5nIGtleSBzdGF0ZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkgY29kZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgY29kZTogVktfQ0FQU19MT0NLLCBWS19OVU1fTE9DSywgVktfU0NST0xMX0xPQ0ssIG9yCisgICAgICogICAgICAgICAgICBWS19LQU5BX0xPQ0suCisgICAgICogQHBhcmFtIGExCisgICAgICogICAgICAgICAgICB0aGUgc3RhdGUgLSB0cnVlIHRvIHNldCB0aGUgc3BlY2lmaWVkIGtleSBjb2RlIHRvIHRoZSBsb2NrZWQKKyAgICAgKiAgICAgICAgICAgIHN0YXRlLCBmYWxzZSAtIHRvIHVubG9jayBpdC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0YXRlIG9mIHRoaXMga2V5IGNhbid0IGJlIHNldCwgb3IgaWYgdGhlIGtleWJvYXJkCisgICAgICogICAgICAgICAgICAgZG9lc24ndCBoYXZlIHRoaXMga2V5LgorICAgICAqIEB0aHJvd3MgTm90SW1wbGVtZW50ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9ja2luZ0tleVN0YXRlKGludCBhMCwgYm9vbGVhbiBhMSkgdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLAorICAgICAgICAgICAgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCIpOyAvL1RPRE86IGltcGxlbWVudCAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9uIHF1ZXVlIGVtcHR5LgorICAgICAqLworICAgIHZvaWQgb25RdWV1ZUVtcHR5KCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHd0ay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2xzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGNscyBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIHdUSy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFdUSyBjcmVhdGVXVEsoU3RyaW5nIGNsc05hbWUpIHsKKyAgICAgICAgV1RLIG5ld1dUSyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdXVEsgPSAoV1RLKUNsYXNzLmZvck5hbWUoY2xzTmFtZSkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdXVEs7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29ubmVjdCB0aGUgY29tcG9uZW50IHRvIGl0cyBuYXRpdmUgd2luZG93CisgICAgICogCisgICAgICogQHBhcmFtIHdpbklkCisgICAgICogICAgICAgICAgICB0aGUgaWQgb2YgbmF0aXZlIHdpbmRvdyBqdXN0IGNyZWF0ZWQuCisgICAgICovCisgICAgYm9vbGVhbiBvbldpbmRvd0NyZWF0ZWQobG9uZyB3aW5JZCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmF0aXZlIGV2ZW50IHF1ZXVlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG5hdGl2ZSBldmVudCBxdWV1ZS4KKyAgICAgKi8KKyAgICBOYXRpdmVFdmVudFF1ZXVlIGdldE5hdGl2ZUV2ZW50UXVldWUoKSB7CisgICAgICAgIHJldHVybiB3dGsuZ2V0TmF0aXZlRXZlbnRRdWV1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzaGFyZWQgaW5zdGFuY2Ugb2YgaW1wbGVtZW50YXRpb24gb2YKKyAgICAgKiBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5OYXRpdmVDdXJzb3IgZm9yIGN1cnJlbnQgcGxhdGZvcm0gZm9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgSmF2YSBDdXJzb3IgdHlwZS4KKyAgICAgKiBAcmV0dXJuIG5ldyBpbnN0YW5jZSBvZiBpbXBsZW1lbnRhdGlvbiBvZiBOYXRpdmVDdXJzb3IuCisgICAgICovCisgICAgTmF0aXZlQ3Vyc29yIGNyZWF0ZU5hdGl2ZUN1cnNvcihpbnQgdHlwZSkgeworICAgICAgICByZXR1cm4gd3RrLmdldEN1cnNvckZhY3RvcnkoKS5nZXRDdXJzb3IodHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNoYXJlZCBpbnN0YW5jZSBvZiBpbXBsZW1lbnRhdGlvbiBvZgorICAgICAqIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUN1cnNvciBmb3IgY3VycmVudCBwbGF0Zm9ybSBmb3IgY3VzdG9tCisgICAgICogY3Vyc29yCisgICAgICogCisgICAgICogQHBhcmFtIGltZworICAgICAqICAgICAgICAgICAgdGhlIGltZy4KKyAgICAgKiBAcGFyYW0gaG90U3BvdAorICAgICAqICAgICAgICAgICAgdGhlIGhvdCBzcG90LgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZS4KKyAgICAgKiBAcmV0dXJuIG5ldyBpbnN0YW5jZSBvZiBpbXBsZW1lbnRhdGlvbiBvZiBOYXRpdmVDdXJzb3IuCisgICAgICovCisgICAgTmF0aXZlQ3Vyc29yIGNyZWF0ZUN1c3RvbU5hdGl2ZUN1cnNvcihJbWFnZSBpbWcsIFBvaW50IGhvdFNwb3QsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiB3dGsuZ2V0Q3Vyc29yRmFjdG9yeSgpLmNyZWF0ZUN1c3RvbUN1cnNvcihpbWcsIGhvdFNwb3QueCwgaG90U3BvdC55KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFuIEFXVEV2ZW50TGlzdGVuZXIgdG8gdGhlIFRvb2xraXQgdG8gbGlzdGVuIGZvciBldmVudHMgb2YgdHlwZXMKKyAgICAgKiBjb3JyZXNwb25kaW5nIHRvIGJpdHMgaW4gdGhlIHNwZWNpZmllZCBldmVudCBtYXNrLiBFdmVudCBtYXNrcyBhcmUKKyAgICAgKiBkZWZpbmVkIGluIEFXVEV2ZW50IGNsYXNzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIEFXVEV2ZW50TGlzdGVuZXIuCisgICAgICogQHBhcmFtIGV2ZW50TWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgb2YgZXZlbnQgdHlwZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQVdURXZlbnRMaXN0ZW5lcihBV1RFdmVudExpc3RlbmVyIGxpc3RlbmVyLCBsb25nIGV2ZW50TWFzaykgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgICAgICBpZiAoc2VjdXJpdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlY3VyaXR5LmNoZWNrUGVybWlzc2lvbihhd3RFdmVudHNNYW5hZ2VyLnBlcm1pc3Npb24pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXd0RXZlbnRzTWFuYWdlci5hZGRBV1RFdmVudExpc3RlbmVyKGxpc3RlbmVyLCBldmVudE1hc2spOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgQVdUIGV2ZW50IGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIEFXVEV2ZW50TGlzdGVuZXIgdG8gYmUgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBV1RFdmVudExpc3RlbmVyKEFXVEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZWN1cml0eS5jaGVja1Blcm1pc3Npb24oYXd0RXZlbnRzTWFuYWdlci5wZXJtaXNzaW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGF3dEV2ZW50c01hbmFnZXIucmVtb3ZlQVdURXZlbnRMaXN0ZW5lcihsaXN0ZW5lcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFycmF5IG9mIGFsbCBBV1QgZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGlzIFRvb2xraXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgYWxsIEFXVCBldmVudCBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCB3aXRoIHRoaXMKKyAgICAgKiAgICAgICAgIFRvb2xraXQuCisgICAgICovCisgICAgcHVibGljIEFXVEV2ZW50TGlzdGVuZXJbXSBnZXRBV1RFdmVudExpc3RlbmVycygpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZWN1cml0eS5jaGVja1Blcm1pc3Npb24oYXd0RXZlbnRzTWFuYWdlci5wZXJtaXNzaW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBhd3RFdmVudHNNYW5hZ2VyLmdldEFXVEV2ZW50TGlzdGVuZXJzKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHRoZSBBV1QgZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGlzIFRvb2xraXQKKyAgICAgKiBmb3IgdGhlIGV2ZW50IHR5cGVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBldmVudCBtYXNrLgorICAgICAqIAorICAgICAqIEBwYXJhbSBldmVudE1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXQgbWFzayBvZiBldmVudCB0eXBlLgorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHRoZSBBV1QgZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgaW4gdGhpcyBUb29sa2l0CisgICAgICogICAgICAgICBmb3IgdGhlIGV2ZW50IHR5cGVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBldmVudCBtYXNrLgorICAgICAqLworICAgIHB1YmxpYyBBV1RFdmVudExpc3RlbmVyW10gZ2V0QVdURXZlbnRMaXN0ZW5lcnMobG9uZyBldmVudE1hc2spIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZWN1cml0eS5jaGVja1Blcm1pc3Npb24oYXd0RXZlbnRzTWFuYWdlci5wZXJtaXNzaW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBhd3RFdmVudHNNYW5hZ2VyLmdldEFXVEV2ZW50TGlzdGVuZXJzKGV2ZW50TWFzayk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERpc3BhdGNoIEFXVCBldmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBldmVudC4KKyAgICAgKi8KKyAgICB2b2lkIGRpc3BhdGNoQVdURXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgYXd0RXZlbnRzTWFuYWdlci5kaXNwYXRjaEFXVEV2ZW50KGV2ZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgQVdURXZlbnRzTWFuYWdlci4KKyAgICAgKi8KKyAgICBmaW5hbCBjbGFzcyBBV1RFdmVudHNNYW5hZ2VyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBlcm1pc3Npb24uCisgICAgICAgICAqLworICAgICAgICBBV1RQZXJtaXNzaW9uIHBlcm1pc3Npb24gPSBuZXcgQVdUUGVybWlzc2lvbigibGlzdGVuVG9BbGxBV1RFdmVudHMiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbGlzdGVuZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBBV1RMaXN0ZW5lckxpc3Q8QVdURXZlbnRMaXN0ZW5lclByb3h5PiBsaXN0ZW5lcnMgPSBuZXcgQVdUTGlzdGVuZXJMaXN0PEFXVEV2ZW50TGlzdGVuZXJQcm94eT4oKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQWRkcyB0aGUgQVdUIGV2ZW50IGxpc3RlbmVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyLgorICAgICAgICAgKiBAcGFyYW0gZXZlbnRNYXNrCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGV2ZW50IG1hc2suCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFkZEFXVEV2ZW50TGlzdGVuZXIoQVdURXZlbnRMaXN0ZW5lciBsaXN0ZW5lciwgbG9uZyBldmVudE1hc2spIHsKKyAgICAgICAgICAgIGlmIChsaXN0ZW5lciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXJzLmFkZFVzZXJMaXN0ZW5lcihuZXcgQVdURXZlbnRMaXN0ZW5lclByb3h5KGV2ZW50TWFzaywgbGlzdGVuZXIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZW1vdmVzIHRoZSBBV1QgZXZlbnQgbGlzdGVuZXIuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbGlzdGVuZXIuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHJlbW92ZUFXVEV2ZW50TGlzdGVuZXIoQVdURXZlbnRMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKEFXVEV2ZW50TGlzdGVuZXJQcm94eSBwcm94eSA6IGxpc3RlbmVycy5nZXRVc2VyTGlzdGVuZXJzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyID09IHByb3h5LmdldExpc3RlbmVyKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5yZW1vdmVVc2VyTGlzdGVuZXIocHJveHkpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIEFXVCBldmVudCBsaXN0ZW5lcnMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBBV1QgZXZlbnQgbGlzdGVuZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgQVdURXZlbnRMaXN0ZW5lcltdIGdldEFXVEV2ZW50TGlzdGVuZXJzKCkgeworICAgICAgICAgICAgSGFzaFNldDxFdmVudExpc3RlbmVyPiBsaXN0ZW5lcnNTZXQgPSBuZXcgSGFzaFNldDxFdmVudExpc3RlbmVyPigpOworICAgICAgICAgICAgZm9yIChBV1RFdmVudExpc3RlbmVyUHJveHkgcHJveHkgOiBsaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycygpKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXJzU2V0LmFkZChwcm94eS5nZXRMaXN0ZW5lcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsaXN0ZW5lcnNTZXQudG9BcnJheShuZXcgQVdURXZlbnRMaXN0ZW5lcltsaXN0ZW5lcnNTZXQuc2l6ZSgpXSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgQVdUIGV2ZW50IGxpc3RlbmVycy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBldmVudE1hc2sKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgbWFzay4KKyAgICAgICAgICogQHJldHVybiB0aGUgQVdUIGV2ZW50IGxpc3RlbmVycy4KKyAgICAgICAgICovCisgICAgICAgIEFXVEV2ZW50TGlzdGVuZXJbXSBnZXRBV1RFdmVudExpc3RlbmVycyhsb25nIGV2ZW50TWFzaykgeworICAgICAgICAgICAgSGFzaFNldDxFdmVudExpc3RlbmVyPiBsaXN0ZW5lcnNTZXQgPSBuZXcgSGFzaFNldDxFdmVudExpc3RlbmVyPigpOworICAgICAgICAgICAgZm9yIChBV1RFdmVudExpc3RlbmVyUHJveHkgcHJveHkgOiBsaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycygpKSB7CisgICAgICAgICAgICAgICAgaWYgKChwcm94eS5nZXRFdmVudE1hc2soKSAmIGV2ZW50TWFzaykgPT0gZXZlbnRNYXNrKSB7CisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1NldC5hZGQocHJveHkuZ2V0TGlzdGVuZXIoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxpc3RlbmVyc1NldC50b0FycmF5KG5ldyBBV1RFdmVudExpc3RlbmVyW2xpc3RlbmVyc1NldC5zaXplKCldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBEaXNwYXRjaCBBV1QgZXZlbnQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZXZlbnQuCisgICAgICAgICAqLworICAgICAgICB2b2lkIGRpc3BhdGNoQVdURXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKyAgICAgICAgICAgIEFXVEV2ZW50LkV2ZW50RGVzY3JpcHRvciBkZXNjcmlwdG9yID0gZXZlbnRUeXBlTG9va3VwLmdldEV2ZW50RGVzY3JpcHRvcihldmVudCk7CisgICAgICAgICAgICBpZiAoZGVzY3JpcHRvciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChBV1RFdmVudExpc3RlbmVyUHJveHkgcHJveHkgOiBsaXN0ZW5lcnMuZ2V0VXNlckxpc3RlbmVycygpKSB7CisgICAgICAgICAgICAgICAgaWYgKChwcm94eS5nZXRFdmVudE1hc2soKSAmIGRlc2NyaXB0b3IuZXZlbnRNYXNrKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHByb3h5LmV2ZW50RGlzcGF0Y2hlZChldmVudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEF1dG9OdW1iZXIuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEF1dG9OdW1iZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBjb21wb25lbnQuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dENvbXBvbmVudCA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuZXh0IGNhbnZhcy4KKyAgICAgICAgICovCisgICAgICAgIGludCBuZXh0Q2FudmFzID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgcGFuZWwuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dFBhbmVsID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgd2luZG93LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG5leHRXaW5kb3cgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBmcmFtZS4KKyAgICAgICAgICovCisgICAgICAgIGludCBuZXh0RnJhbWUgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBkaWFsb2cuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dERpYWxvZyA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuZXh0IGJ1dHRvbi4KKyAgICAgICAgICovCisgICAgICAgIGludCBuZXh0QnV0dG9uID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgbWVudSBjb21wb25lbnQuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dE1lbnVDb21wb25lbnQgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBsYWJlbC4KKyAgICAgICAgICovCisgICAgICAgIGludCBuZXh0TGFiZWwgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBjaGVjayBib3guCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dENoZWNrQm94ID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgc2Nyb2xsYmFyLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG5leHRTY3JvbGxiYXIgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBzY3JvbGwgcGFuZS4KKyAgICAgICAgICovCisgICAgICAgIGludCBuZXh0U2Nyb2xsUGFuZSA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuZXh0IGxpc3QuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dExpc3QgPSAwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBjaG9pY2UuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dENob2ljZSA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuZXh0IGZpbGUgZGlhbG9nLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG5leHRGaWxlRGlhbG9nID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgdGV4dCBhcmVhLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG5leHRUZXh0QXJlYSA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuZXh0IHRleHQgZmllbGQuCisgICAgICAgICAqLworICAgICAgICBpbnQgbmV4dFRleHRGaWVsZCA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBMb2NrIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IExvY2soKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L1Rvb2xraXRJbXBsLmphdmEgYi9hd3QvamF2YS9hd3QvVG9vbGtpdEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDE1YWVmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L1Rvb2xraXRJbXBsLmphdmEKQEAgLTAsMCArMSwyNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC5pbS5JbnB1dE1ldGhvZEhpZ2hsaWdodDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlT2JzZXJ2ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VQcm9kdWNlcjsKK2ltcG9ydCBqYXZhLmF3dC5wZWVyLio7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlLio7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuR3JhcGhpY3NGYWN0b3J5OworCitjbGFzcyBUb29sa2l0SW1wbCBleHRlbmRzIFRvb2xraXQgeworCQorICAgIHN0YXRpYyBmaW5hbCBIYXNodGFibGU8U2VyaWFsaXphYmxlLCBJbWFnZT4gaW1hZ2VDYWNoZSA9IG5ldyBIYXNodGFibGU8U2VyaWFsaXphYmxlLCBJbWFnZT4oKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHN5bmMoKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjaGVja0ltYWdlKEltYWdlIGltYWdlLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gSW1hZ2VPYnNlcnZlci5BTExCSVRTOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCEoaW1hZ2UgaW5zdGFuY2VvZiBPZmZzY3JlZW5JbWFnZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gSW1hZ2VPYnNlcnZlci5BTExCSVRTOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT2Zmc2NyZWVuSW1hZ2Ugb2kgPSAoT2Zmc2NyZWVuSW1hZ2UpIGltYWdlOworICAgICAgICAgICAgcmV0dXJuIG9pLmNoZWNrSW1hZ2Uob2JzZXJ2ZXIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2UgY3JlYXRlSW1hZ2UoSW1hZ2VQcm9kdWNlciBwcm9kdWNlcikgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE9mZnNjcmVlbkltYWdlKHByb2R1Y2VyKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlIGNyZWF0ZUltYWdlKGJ5dGVbXSBpbWFnZWRhdGEsIGludCBpbWFnZW9mZnNldCwgaW50IGltYWdlbGVuZ3RoKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgT2Zmc2NyZWVuSW1hZ2UobmV3IEJ5dGVBcnJheURlY29kaW5nSW1hZ2VTb3VyY2UoaW1hZ2VkYXRhLCBpbWFnZW9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgaW1hZ2VsZW5ndGgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlIGNyZWF0ZUltYWdlKFVSTCB1cmwpIHsKKyAgICAgICAgbG9ja0FXVCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5JbWFnZShuZXcgVVJMRGVjb2RpbmdJbWFnZVNvdXJjZSh1cmwpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlIGNyZWF0ZUltYWdlKFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE9mZnNjcmVlbkltYWdlKG5ldyBGaWxlRGVjb2RpbmdJbWFnZVNvdXJjZShmaWxlbmFtZSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gR3JhcGhpY3NFbnZpcm9ubWVudC5nZXRMb2NhbEdyYXBoaWNzRW52aXJvbm1lbnQoKS5nZXREZWZhdWx0U2NyZWVuRGV2aWNlKCkKKyAgICAgICAgICAgICAgICAgICAgLmdldERlZmF1bHRDb25maWd1cmF0aW9uKCkuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBPdmVycmlkZQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQgZm9udCkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgIAlHcmFwaGljc0ZhY3RvcnkgZ2YgPSBnZXRHcmFwaGljc0ZhY3RvcnkoKTsKKyAgICAgICAgICAgIHJldHVybiBnZi5nZXRGb250TWV0cmljcyhmb250KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHByZXBhcmVJbWFnZShJbWFnZSBpbWFnZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBJbWFnZU9ic2VydmVyIG9ic2VydmVyKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh3aWR0aCA9PSAwIHx8IGhlaWdodCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIShpbWFnZSBpbnN0YW5jZW9mIE9mZnNjcmVlbkltYWdlKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT2Zmc2NyZWVuSW1hZ2Ugb2kgPSAoT2Zmc2NyZWVuSW1hZ2UpIGltYWdlOworICAgICAgICAgICAgcmV0dXJuIG9pLnByZXBhcmVJbWFnZShvYnNlcnZlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGJlZXAoKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgCS8vID8/P0FXVDogaXMgdGhlcmUgbm90aGluZyB0byBiZSBpbXBsZW1lbnRlZCBoZXJlPworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBPdmVycmlkZQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFN0cmluZ1tdIGdldEZvbnRMaXN0KCkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1bmxvY2tBV1QoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBPdmVycmlkZQorICAgIEBEZXByZWNhdGVkCisgICAgcHJvdGVjdGVkIEZvbnRQZWVyIGdldEZvbnRQZWVyKFN0cmluZyBhMCwgaW50IGExKSB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2UgZ2V0SW1hZ2UoU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIHJldHVybiBnZXRJbWFnZShmaWxlbmFtZSwgdGhpcyk7CisgICAgfQorCisgICAgc3RhdGljIEltYWdlIGdldEltYWdlKFN0cmluZyBmaWxlbmFtZSwgVG9vbGtpdCB0b29sa2l0KSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoaW1hZ2VDYWNoZSkgeworICAgICAgICAgICAgSW1hZ2UgaW0gPSAoZmlsZW5hbWUgPT0gbnVsbCA/IG51bGwgOiBpbWFnZUNhY2hlLmdldChmaWxlbmFtZSkpOworCisgICAgICAgICAgICBpZiAoaW0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGltID0gdG9vbGtpdC5jcmVhdGVJbWFnZShmaWxlbmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGltYWdlQ2FjaGUucHV0KGZpbGVuYW1lLCBpbSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBpbTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZSBnZXRJbWFnZShVUkwgdXJsKSB7CisgICAgICAgIHJldHVybiBnZXRJbWFnZSh1cmwsIHRoaXMpOworICAgIH0KKworICAgIHN0YXRpYyBJbWFnZSBnZXRJbWFnZShVUkwgdXJsLCBUb29sa2l0IHRvb2xraXQpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChpbWFnZUNhY2hlKSB7CisgICAgICAgICAgICBJbWFnZSBpbSA9IGltYWdlQ2FjaGUuZ2V0KHVybCk7CisgICAgICAgICAgICBpZiAoaW0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGltID0gdG9vbGtpdC5jcmVhdGVJbWFnZSh1cmwpOworICAgICAgICAgICAgICAgICAgICBpbWFnZUNhY2hlLnB1dCh1cmwsIGltKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpbTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2NyZWVuUmVzb2x1dGlvbigpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgCXJldHVybiA2MjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRTY3JlZW5TaXplKCkgeworICAgICAgICBsb2NrQVdUKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEaXNwbGF5TW9kZSBkbSA9IEdyYXBoaWNzRW52aXJvbm1lbnQuZ2V0TG9jYWxHcmFwaGljc0Vudmlyb25tZW50KCkKKyAgICAgICAgICAgICAgICAgICAgLmdldERlZmF1bHRTY3JlZW5EZXZpY2UoKS5nZXREaXNwbGF5TW9kZSgpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oZG0uZ2V0V2lkdGgoKSwgZG0uZ2V0SGVpZ2h0KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdW5sb2NrQVdUKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWFwPGphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZSwgPz4gbWFwSW5wdXRNZXRob2RIaWdobGlnaHQoCisgICAgICAgICAgICBJbnB1dE1ldGhvZEhpZ2hsaWdodCBoaWdobGlnaHQpIHRocm93cyBIZWFkbGVzc0V4Y2VwdGlvbiB7CisgICAgICAgIGxvY2tBV1QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBtYXBJbnB1dE1ldGhvZEhpZ2hsaWdodEltcGwoaGlnaGxpZ2h0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHVubG9ja0FXVCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEV2ZW50UXVldWUgZ2V0U3lzdGVtRXZlbnRRdWV1ZUltcGwoKSB7CisgICAgICAgIHJldHVybiBnZXRTeXN0ZW1FdmVudFF1ZXVlQ29yZSgpLmdldEFjdGl2ZUV2ZW50UXVldWUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvVHJhbnNwYXJlbmN5LmphdmEgYi9hd3QvamF2YS9hd3QvVHJhbnNwYXJlbmN5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRhMWU3ZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9UcmFuc3BhcmVuY3kuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3Q7CisKKy8qKgorICogVGhlIFRyYW5zcGFyZW5jeSBpbnRlcmZhY2UgZGVmaW5lcyB0cmFuc3BhcmVuY3kncyBnZW5lcmFsIG1vZGVzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBUcmFuc3BhcmVuY3kgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE9QQVFVRSByZXByZXNlbnRzIGNvbXBsZXRlbHkgb3BhcXVlIGRhdGEsIGFsbCBwaXhlbHMgaGF2ZSBhbgorICAgICAqIGFscGhhIHZhbHVlIG9mIDEuMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUEFRVUUgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEJJVE1BU0sgcmVwcmVzZW50cyBkYXRhIHdoaWNoIGNhbiBiZSBlaXRoZXIgY29tcGxldGVseQorICAgICAqIG9wYXF1ZSwgd2l0aCBhbiBhbHBoYSB2YWx1ZSBvZiAxLjAsIG9yIGNvbXBsZXRlbHkgdHJhbnNwYXJlbnQsIHdpdGggYW4KKyAgICAgKiBhbHBoYSB2YWx1ZSBvZiAwLjAuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUTUFTSyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFJBTlNMVUNFTlQgcmVwcmVzZW50cyBkYXRhIHdoaWNoIGFscGhhIHZhbHVlIGNhbiB2YXJ5CisgICAgICogYmV0d2VlbiBhbmQgaW5jbHVkaW5nIDAuMCBhbmQgMS4wLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQU5TTFVDRU5UID0gMzsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRyYW5zcGFyZW5jeSBtb2RlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zcGFyZW5jeSBtb2RlOiBPUEFRVUUsIEJJVE1BU0sgb3IgVFJBTlNMVUNFTlQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUcmFuc3BhcmVuY3koKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2NvbG9yL0NNTUV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYXd0L2NvbG9yL0NNTUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4YjlhN2UKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvY29sb3IvQ01NRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuY29sb3I7CisKKy8qKgorICogVGhlIENNTUV4Y2VwdGlvbiBpcyB0aHJvd24gYXMgc29vbiBhcyBhIG5hdGl2ZSBDTU0gZXJyb3Igb2NjdXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIENNTUV4Y2VwdGlvbiBleHRlbmRzIGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uIHsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1Nzc1NTU4MDQ0MTQyOTk0OTY1TDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBDTU0gZXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBvZiB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDTU1FeGNlcHRpb24gKFN0cmluZyBzKSB7CisgICAgICAgIHN1cGVyIChzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvY29sb3IvQ29sb3JTcGFjZS5qYXZhIGIvYXd0L2phdmEvYXd0L2NvbG9yL0NvbG9yU3BhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NGM0OTFiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2NvbG9yL0NvbG9yU3BhY2UuamF2YQpAQCAtMCwwICsxLDQxNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuY29sb3I7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuTFVUQ29sb3JDb252ZXJ0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENvbG9yU3BhY2UgY2xhc3MgZGVmaW5lcyBhIGNvbG9yIHNwYWNlIHR5cGUgZm9yIGEgQ29sb3IgYW5kIHByb3ZpZGVzCisgKiBtZXRob2RzIGZvciBhcnJheXMgb2YgY29sb3IgY29tcG9uZW50IG9wZXJhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29sb3JTcGFjZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKiogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQwOTQ1MjcwNDMwODY4OTcyNEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9YWVogaW5kaWNhdGVzIFhZWiBjb2xvciBzcGFjZSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfWFlaID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0xhYiBpbmRpY2F0ZXMgTGFiIGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9MYWIgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfTHV2IGluZGljYXRlcyBMdXYgY29sb3Igc3BhY2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0x1diA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9ZQ2JDciBpbmRpY2F0ZXMgWUNiQ3IgY29sb3Igc3BhY2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1lDYkNyID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX1l4eSBpbmRpY2F0ZXMgWXh5IGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9ZeHkgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfUkdCIGluZGljYXRlcyBSR0IgY29sb3Igc3BhY2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1JHQiA9IDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9HUkFZIGluZGljYXRlcyBHcmF5IGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9HUkFZID0gNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0hTViBpbmRpY2F0ZXMgSFNWIGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9IU1YgPSA3OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfSExTIGluZGljYXRlcyBITFMgY29sb3Igc3BhY2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0hMUyA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9DTVlLIGluZGljYXRlcyBDTVlLIGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9DTVlLID0gOTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0NNWSBpbmRpY2F0ZXMgQ01ZIGNvbG9yIHNwYWNlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9DTVkgPSAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzJDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDIgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzJDTFIgPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzNDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDMgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzNDTFIgPSAxMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzRDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDQgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzRDTFIgPSAxNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzVDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDUgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzVDTFIgPSAxNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzZDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDYgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzZDTFIgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzdDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDcgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzdDTFIgPSAxNzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzhDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDggY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzhDTFIgPSAxODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFXzlDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDkgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzlDTFIgPSAxOTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0FDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDEwIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9BQ0xSID0gMjA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9CQ0xSIGluZGljYXRlcyBjb2xvciBzcGFjZXMgd2l0aCAxMSBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQkNMUiA9IDIxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfQ0NMUiBpbmRpY2F0ZXMgY29sb3Igc3BhY2VzIHdpdGggMTIgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0NDTFIgPSAyMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0RDTFIgaW5kaWNhdGVzIGNvbG9yIHNwYWNlcyB3aXRoIDEzIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9EQ0xSID0gMjM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9FQ0xSIGluZGljYXRlcyBjb2xvciBzcGFjZXMgd2l0aCAxNCBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRUNMUiA9IDI0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfRkNMUiBpbmRpY2F0ZXMgY29sb3Igc3BhY2VzIHdpdGggMTUgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZDTFIgPSAyNTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDU19zUkdCIGluZGljYXRlcyBzdGFuZGFyZCBSR0IgY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1Nfc1JHQiA9IDEwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ1NfTElORUFSX1JHQiBpbmRpY2F0ZXMgbGluZWFyIFJHQiBjb2xvciBzcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDU19MSU5FQVJfUkdCID0gMTAwNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDU19DSUVYWVogaW5kaWNhdGVzIENJRVhZWiBjb252ZXJzaW9uIGNvbG9yIHNwYWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENTX0NJRVhZWiA9IDEwMDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ1NfUFlDQyBpbmRpY2F0ZXMgUGhvdG8gWUNDIGNvbnZlcnNpb24gY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1NfUFlDQyA9IDEwMDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ1NfR1JBWSBpbmRpY2F0ZXMgbGluZWFyIGdyYXkgc2NhbGUgY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1NfR1JBWSA9IDEwMDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3NfIGdyYXkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29sb3JTcGFjZSBjc19HcmF5ID0gbnVsbDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgY3NfIHB5Y2MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29sb3JTcGFjZSBjc19QWUNDID0gbnVsbDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgY3NfIGNpZXh5ei4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBDb2xvclNwYWNlIGNzX0NJRVhZWiA9IG51bGw7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIGNzXyBscmdiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENvbG9yU3BhY2UgY3NfTFJHQiA9IG51bGw7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIGNzX3MgcmdiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENvbG9yU3BhY2UgY3Nfc1JHQiA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB0eXBlOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBudW0gY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBudW1Db21wb25lbnRzOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgQ29sb3JTcGFjZSB3aXRoIHRoZSBzcGVjaWZpZWQgQ29sb3JTcGFjZSB0eXBlIGFuZCBudW1iZXIKKyAgICAgKiBvZiBjb21wb25lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiBjb2xvciBzcGFjZS4KKyAgICAgKiBAcGFyYW0gbnVtY29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjb21wb25lbnRzLgorICAgICAqLworICAgIHByb3RlY3RlZCBDb2xvclNwYWNlKGludCB0eXBlLCBpbnQgbnVtY29tcG9uZW50cykgeworICAgICAgICB0aGlzLm51bUNvbXBvbmVudHMgPSBudW1jb21wb25lbnRzOworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGNvbXBvbmVudCBmb3IgdGhlIHNwZWNpZmllZCBjb21wb25lbnQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGlkeAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb21wb25lbnQuCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaWR4KSB7CisgICAgICAgIGlmIChpZHggPCAwIHx8IGlkeCA+IG51bUNvbXBvbmVudHMgLSAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMTZBPUludmFsaWQgY29tcG9uZW50IGluZGV4OiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTZBIiwgaWR4KSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICByZXR1cm4gIlVubmFtZWQgY29sb3IgY29tcG9uZW50ICMiICsgaWR4OyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgdGhlIHRyYW5zZm9ybWF0aW9uIG9mIGEgY29sb3IgZnJvbSB0aGlzIENvbG9yU3BhY2UgaW50byB0aGUgUkdCCisgICAgICogY29sb3Igc3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9ydmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciB2YWx1ZSBpbiB0aGlzIENvbG9yU3BhY2UuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgd2l0aCBjb2xvciBjb21wb25lbnRzIGluIHRoZSBSR0IgY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0W10gdG9SR0IoZmxvYXRbXSBjb2xvcnZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBhIGNvbG9yIGZyb20gdGhpcyBDb2xvclNwYWNlIGludG8gdGhlCisgICAgICogQ1NfQ0lFWFlaIGNvbG9yIHNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvcnZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgY29sb3IgdmFsdWUgaW4gdGhpcyBDb2xvclNwYWNlLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGFycmF5IHdpdGggY29sb3IgY29tcG9uZW50cyBpbiB0aGUgQ1NfQ0lFWFlaIGNvbG9yCisgICAgICogICAgICAgICBzcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXRbXSB0b0NJRVhZWihmbG9hdFtdIGNvbG9ydmFsdWUpOworCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgdGhlIHRyYW5zZm9ybWF0aW9uIG9mIGEgY29sb3IgZnJvbSB0aGUgUkdCIGNvbG9yIHNwYWNlIGludG8gdGhpcworICAgICAqIENvbG9yU3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIHJnYnZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgYXJyYXkgcmVwcmVzZW50aW5nIGEgY29sb3IgaW4gdGhlIFJHQiBjb2xvciBzcGFjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmbG9hdCBhcnJheSB3aXRoIHRoZSB0cmFuc2Zvcm1lZCBjb2xvciBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdFtdIGZyb21SR0IoZmxvYXRbXSByZ2J2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyB0aGUgdHJhbnNmb3JtYXRpb24gb2YgYSBjb2xvciBmcm9tIHRoZSBDU19DSUVYWVogY29sb3Igc3BhY2UKKyAgICAgKiBpbnRvIHRoaXMgQ29sb3JTcGFjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3J2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHJlcHJlc2VudGluZyBhIGNvbG9yIGluIHRoZSBDU19DSUVYWVogY29sb3IKKyAgICAgKiAgICAgICAgICAgIHNwYWNlLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGFycmF5IHdpdGggdGhlIHRyYW5zZm9ybWVkIGNvbG9yIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0W10gZnJvbUNJRVhZWihmbG9hdFtdIGNvbG9ydmFsdWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSBub3JtYWxpemVkIGNvbG9yIGNvbXBvbmVudCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50CisgICAgICogICAgICAgICAgICB0aGUgY29tcG9uZW50IHRvIGRldGVybWluZSB0aGUgbWluaW11bSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIG5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWluVmFsdWUoaW50IGNvbXBvbmVudCkgeworICAgICAgICBpZiAoY29tcG9uZW50IDwgMCB8fCBjb21wb25lbnQgPiBudW1Db21wb25lbnRzIC0gMSkgeworICAgICAgICAgICAgLy8gYXd0LjE2QT1JbnZhbGlkIGNvbXBvbmVudCBpbmRleDogezB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2QSIsIGNvbXBvbmVudCkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWF4aW11bSBub3JtYWxpemVkIGNvbG9yIGNvbXBvbmVudCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50CisgICAgICogICAgICAgICAgICB0aGUgY29tcG9uZW50IHRvIGRldGVybWluZSB0aGUgbWF4aW11bSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWF4VmFsdWUoaW50IGNvbXBvbmVudCkgeworICAgICAgICBpZiAoY29tcG9uZW50IDwgMCB8fCBjb21wb25lbnQgPiBudW1Db21wb25lbnRzIC0gMSkgeworICAgICAgICAgICAgLy8gYXd0LjE2QT1JbnZhbGlkIGNvbXBvbmVudCBpbmRleDogezB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2QSIsIGNvbXBvbmVudCkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgQ29sb3JTcGFjZSBoYXMgQ1Nfc1JHQiB0eXBlIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgQ29sb3JTcGFjZSBoYXMgQ1Nfc1JHQiB0eXBlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDU19zUkdCKCkgeworICAgICAgICAvLyBJZiBvdXIgY29sb3Igc3BhY2UgaXMgc1JHQiwgdGhlbiBjc19zUkdCCisgICAgICAgIC8vIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQKKyAgICAgICAgcmV0dXJuICh0aGlzID09IGNzX3NSR0IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHR5cGUgb2YgdGhlIENvbG9yU3BhY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGUgQ29sb3JTcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBjb21wb25lbnRzIGZvciB0aGlzIENvbG9yU3BhY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1Db21wb25lbnRzKCkgeworICAgICAgICByZXR1cm4gbnVtQ29tcG9uZW50czsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNpbmdsZSBpbnN0YW5jZSBvZiBDb2xvclNwYWNlIHdpdGggdGhlIHNwZWNpZmllZCBDb2xvclNwYWNlOgorICAgICAqIENTX3NSR0IsIENTX0xJTkVBUl9SR0IsIENTX0NJRVhZWiwgQ1NfR1JBWSwgb3IgQ1NfUFlDQy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3JzcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIGlkZW50aWZpZXIgb2YgdGhlIHNwZWNpZmllZCBDb2xvcnNwYWNlLgorICAgICAqIEByZXR1cm4gdGhlIHNpbmdsZSBpbnN0YW5jZSBvZiB0aGUgZGVzaXJlZCBDb2xvclNwYWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JTcGFjZSBnZXRJbnN0YW5jZShpbnQgY29sb3JzcGFjZSkgeworICAgICAgICBzd2l0Y2ggKGNvbG9yc3BhY2UpIHsKKyAgICAgICAgICAgIGNhc2UgQ1Nfc1JHQjoKKyAgICAgICAgICAgICAgICBpZiAoY3Nfc1JHQiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNzX3NSR0IgPSBuZXcgSUNDX0NvbG9yU3BhY2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElDQ19Qcm9maWxlU3R1YihDU19zUkdCKSk7CisgICAgICAgICAgICAgICAgICAgIExVVENvbG9yQ29udmVydGVyLnNSR0JfQ1MgPSBjc19zUkdCOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSUNDX1Byb2ZpbGUuZ2V0SW5zdGFuY2UgKENTX3NSR0IpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNzX3NSR0I7CisgICAgICAgICAgICBjYXNlIENTX0NJRVhZWjoKKyAgICAgICAgICAgICAgICBpZiAoY3NfQ0lFWFlaID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY3NfQ0lFWFlaID0gbmV3IElDQ19Db2xvclNwYWNlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJQ0NfUHJvZmlsZVN0dWIoQ1NfQ0lFWFlaKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZSAoQ1NfQ0lFWFlaKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBjc19DSUVYWVo7CisgICAgICAgICAgICBjYXNlIENTX0dSQVk6CisgICAgICAgICAgICAgICAgaWYgKGNzX0dyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjc19HcmF5ID0gbmV3IElDQ19Db2xvclNwYWNlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJQ0NfUHJvZmlsZVN0dWIoQ1NfR1JBWSkpOworICAgICAgICAgICAgICAgICAgICBMVVRDb2xvckNvbnZlcnRlci5MSU5FQVJfR1JBWV9DUyA9IGNzX0dyYXk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZSAoQ1NfR1JBWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gY3NfR3JheTsKKyAgICAgICAgICAgIGNhc2UgQ1NfUFlDQzoKKyAgICAgICAgICAgICAgICBpZiAoY3NfUFlDQyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNzX1BZQ0MgPSBuZXcgSUNDX0NvbG9yU3BhY2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElDQ19Qcm9maWxlU3R1YihDU19QWUNDKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZSAoQ1NfUFlDQykpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gY3NfUFlDQzsKKyAgICAgICAgICAgIGNhc2UgQ1NfTElORUFSX1JHQjoKKyAgICAgICAgICAgICAgICBpZiAoY3NfTFJHQiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNzX0xSR0IgPSBuZXcgSUNDX0NvbG9yU3BhY2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElDQ19Qcm9maWxlU3R1YihDU19MSU5FQVJfUkdCKSk7CisgICAgICAgICAgICAgICAgICAgIExVVENvbG9yQ29udmVydGVyLkxJTkVBUl9HUkFZX0NTID0gY3NfR3JheTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0lDQ19Qcm9maWxlLmdldEluc3RhbmNlIChDU19MSU5FQVJfUkdCKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBjc19MUkdCOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVua25vd24gYXJndW1lbnQgcGFzc2VkCisgICAgICAgIC8vIGF3dC4xNkI9Tm90IGEgcHJlZGVmaW5lZCBjb2xvcnNwYWNlCisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJOb3QgYSBwcmVkZWZpbmVkIGNvbG9yc3BhY2UiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvY29sb3IvSUNDX0NvbG9yU3BhY2UuamF2YSBiL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfQ29sb3JTcGFjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViNGQ3ZTkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvY29sb3IvSUNDX0NvbG9yU3BhY2UuamF2YQpAQCAtMCwwICsxLDQ2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuY29sb3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLkNvbG9yQ29udmVydGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuQ29sb3JTY2FsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5jb2xvci5JQ0NfVHJhbnNmb3JtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgYWJzdHJhY3QgY2xhc3MgQ29sb3JTcGFjZSBhbmQgcmVwcmVzZW50cyBkZXZpY2UKKyAqIGluZGVwZW5kZW50IGFuZCBkZXZpY2UgZGVwZW5kZW50IGNvbG9yIHNwYWNlcy4gVGhpcyBjb2xvciBzcGFjZSBpcyBiYXNlZCBvbgorICogdGhlIEludGVybmF0aW9uYWwgQ29sb3IgQ29uc29ydGl1bSBTcGVjaWZpY2F0aW9uIChJQ0MpIEZpbGUgRm9ybWF0IGZvciBDb2xvcgorICogUHJvZmlsZXM6IDxhIGhyZWY9Imh0dHA6Ly93d3cuY29sb3Iub3JnIj5odHRwOi8vd3d3LmNvbG9yLm9yZzwvYT4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJQ0NfQ29sb3JTcGFjZSBleHRlbmRzIENvbG9yU3BhY2UgeworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM0NTU4ODkxMTQwNzA0MzE0ODNMOworCisgICAgLy8gTmVlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgd2l0aCBzZXJpYWxpemVkIGZvcm0KKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsUGVyc2lzdGVudEZpZWxkcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RTdHJlYW1GaWVsZFtdCisgICAgICBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInRoaXNQcm9maWxlIiwgSUNDX1Byb2ZpbGUuY2xhc3MpLCAvLyROT04tTkxTLTEkCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWluVmFsIiwgZmxvYXRbXS5jbGFzcyksIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtYXhWYWwiLCBmbG9hdFtdLmNsYXNzKSwgLy8kTk9OLU5MUy0xJAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImRpZmZNaW5NYXgiLCBmbG9hdFtdLmNsYXNzKSwgLy8kTk9OLU5MUy0xJAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImludkRpZmZNaW5NYXgiLCBmbG9hdFtdLmNsYXNzKSwgLy8kTk9OLU5MUy0xJAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm5lZWRTY2FsZUluaXQiLCBCb29sZWFuLlRZUEUpIC8vJE5PTi1OTFMtMSQKKyAgICB9OworCisKKyAgIC8qKgorICAgICAqIEFjY29yZGluZyB0byBJQ0Mgc3BlY2lmaWNhdGlvbiAoZnJvbSBodHRwOi8vd3d3LmNvbG9yLm9yZykgIkZvciB0aGUKKyAgICAgKiBDSUVYWVogZW5jb2RpbmcsIGVhY2ggY29tcG9uZW50IChYLCBZLCBhbmQgWikgaXMgZW5jb2RlZCBhcyBhCisgICAgICogdTFGaXhlZDE1TnVtYmVyIi4gVGhpcyBtZWFucyB0aGF0IG1heCB2YWx1ZSBmb3IgdGhpcyBlbmNvZGluZyBpcyAxICsKKyAgICAgKiAoMzI3NjcvMzI3NjgpCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXQgTUFYX1hZWiA9IDFmICsgKDMyNzY3Zi8zMjc2OGYpOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNQVhfU0hPUlQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXQgTUFYX1NIT1JUID0gNjU1MzVmOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJTlZfTUFYX1NIT1JULgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IElOVl9NQVhfU0hPUlQgPSAxZi9NQVhfU0hPUlQ7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNIT1JUMlhZWl9GQUNUT1IuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXQgU0hPUlQyWFlaX0ZBQ1RPUiA9IE1BWF9YWVovTUFYX1NIT1JUOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBYWVoyU0hPUlRfRkFDVE9SLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IFhZWjJTSE9SVF9GQUNUT1IgPSBNQVhfU0hPUlQvTUFYX1hZWjsKKworICAgIC8qKgorICAgICAqIFRoZSBwcm9maWxlLgorICAgICAqLworICAgIHByaXZhdGUgSUNDX1Byb2ZpbGUgcHJvZmlsZSA9IG51bGw7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIG1pbiB2YWx1ZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBtaW5WYWx1ZXNbXSA9IG51bGw7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIG1heCB2YWx1ZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBtYXhWYWx1ZXNbXSA9IG51bGw7CisKKyAgICAvLyBjYWNoZSB0cmFuc2Zvcm1zIGhlcmUgLSBwZXJmb3JtYW5jZSBnYWluCisgICAgLyoqCisgICAgICogVGhlIHRvIHJnYiB0cmFuc2Zvcm0uCisgICAgICovCisgICAgcHJpdmF0ZSBJQ0NfVHJhbnNmb3JtIHRvUkdCVHJhbnNmb3JtID0gbnVsbDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgZnJvbSByZ2IgdHJhbnNmb3JtLgorICAgICAqLworICAgIHByaXZhdGUgSUNDX1RyYW5zZm9ybSBmcm9tUkdCVHJhbnNmb3JtID0gbnVsbDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgdG8geHl6IHRyYW5zZm9ybS4KKyAgICAgKi8KKyAgICBwcml2YXRlIElDQ19UcmFuc2Zvcm0gdG9YWVpUcmFuc2Zvcm0gPSBudWxsOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBmcm9tIHh5eiB0cmFuc2Zvcm0uCisgICAgICovCisgICAgcHJpdmF0ZSBJQ0NfVHJhbnNmb3JtIGZyb21YWVpUcmFuc2Zvcm0gPSBudWxsOworCisgICAgLyoqCisgICAgICogVGhlIGNvbnZlcnRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIENvbG9yQ29udmVydGVyIGNvbnZlcnRlciA9IG5ldyBDb2xvckNvbnZlcnRlcigpOworICAgIAorICAgIC8qKgorICAgICAqIFRoZSBzY2FsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb2xvclNjYWxlciBzY2FsZXIgPSBuZXcgQ29sb3JTY2FsZXIoKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgc2NhbGluZyBkYXRhIGxvYWRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2NhbGluZ0RhdGFMb2FkZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSByZXNvbHZlZCBkZXNlcmlhbGl6ZWQgaW5zdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIElDQ19Db2xvclNwYWNlIHJlc29sdmVkRGVzZXJpYWxpemVkSW5zdDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJQ0MgY29sb3Igc3BhY2UgZnJvbSBhbiBJQ0NfUHJvZmlsZSBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIHBmCisgICAgICogICAgICAgICAgICB0aGUgSUNDX1Byb2ZpbGUgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBJQ0NfQ29sb3JTcGFjZShJQ0NfUHJvZmlsZSBwZikgeworICAgICAgICBzdXBlcihwZi5nZXRDb2xvclNwYWNlVHlwZSgpLCBwZi5nZXROdW1Db21wb25lbnRzKCkpOworCisgICAgICAgIGludCBwZkNsYXNzID0gcGYuZ2V0UHJvZmlsZUNsYXNzKCk7CisKKyAgICAgICAgc3dpdGNoIChwZkNsYXNzKSB7CisgICAgICAgICAgICBjYXNlIElDQ19Qcm9maWxlLkNMQVNTX0NPTE9SU1BBQ0VDT05WRVJTSU9OOgorICAgICAgICAgICAgY2FzZSBJQ0NfUHJvZmlsZS5DTEFTU19ESVNQTEFZOgorICAgICAgICAgICAgY2FzZSBJQ0NfUHJvZmlsZS5DTEFTU19PVVRQVVQ6CisgICAgICAgICAgICBjYXNlIElDQ19Qcm9maWxlLkNMQVNTX0lOUFVUOgorICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBPSywgaXQgaXMgY29sb3IgY29udmVyc2lvbiBwcm9maWxlCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4xNjg9SW52YWxpZCBwcm9maWxlIGNsYXNzLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTY4IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBwcm9maWxlID0gcGY7CisgICAgICAgIGZpbGxNaW5NYXhWYWx1ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJQ0NfUHJvZmlsZSBmb3IgdGhpcyBJQ0NfQ29sb3JTcGFjZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJQ0NfUHJvZmlsZSBmb3IgdGhpcyBJQ0NfQ29sb3JTcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUNDX1Byb2ZpbGUgZ2V0UHJvZmlsZSgpIHsKKyAgICAgICAgaWYgKHByb2ZpbGUgaW5zdGFuY2VvZiBJQ0NfUHJvZmlsZVN0dWIpIHsKKyAgICAgICAgICAgIHByb2ZpbGUgPSAoKElDQ19Qcm9maWxlU3R1YikgcHJvZmlsZSkubG9hZFByb2ZpbGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwcm9maWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBhIGNvbG9yIGZyb20gdGhpcyBDb2xvclNwYWNlIGludG8gdGhlIFJHQgorICAgICAqIGNvbG9yIHNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvcnZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgY29sb3IgdmFsdWUgaW4gdGhpcyBDb2xvclNwYWNlLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGFycmF5IHdpdGggY29sb3IgY29tcG9uZW50cyBpbiB0aGUgUkdCIGNvbG9yIHNwYWNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIHRvUkdCKGZsb2F0W10gY29sb3J2YWx1ZSkgeworICAgICAgICBpZiAodG9SR0JUcmFuc2Zvcm0gPT0gbnVsbCkgeworICAgICAgICAgICAgSUNDX1Byb2ZpbGUgc1JHQlByb2ZpbGUgPQorICAgICAgICAgICAgICAgICgoSUNDX0NvbG9yU3BhY2UpIENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ1Nfc1JHQikpLmdldFByb2ZpbGUoKTsKKyAgICAgICAgICAgIElDQ19Qcm9maWxlW10gcHJvZmlsZXMgPSB7Z2V0UHJvZmlsZSgpLCBzUkdCUHJvZmlsZX07CisgICAgICAgICAgICB0b1JHQlRyYW5zZm9ybSA9IG5ldyBJQ0NfVHJhbnNmb3JtKHByb2ZpbGVzKTsKKyAgICAgICAgICAgIGlmICghc2NhbGluZ0RhdGFMb2FkZWQpIHsKKyAgICAgICAgICAgICAgICBzY2FsZXIubG9hZFNjYWxpbmdEYXRhKHRoaXMpOworICAgICAgICAgICAgICAgIHNjYWxpbmdEYXRhTG9hZGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHNob3J0W10gZGF0YSA9IG5ldyBzaG9ydFtnZXROdW1Db21wb25lbnRzKCldOworCisgICAgICAgIHNjYWxlci5zY2FsZShjb2xvcnZhbHVlLCBkYXRhLCAwKTsKKworICAgICAgICBzaG9ydFtdIGNvbnZlcnRlZCA9CisgICAgICAgICAgICBjb252ZXJ0ZXIudHJhbnNsYXRlQ29sb3IodG9SR0JUcmFuc2Zvcm0sIGRhdGEsIG51bGwpOworCisgICAgICAgIC8vIHVuc2NhbGUgdG8gc1JHQgorICAgICAgICBmbG9hdFtdIHJlcyA9IG5ldyBmbG9hdFszXTsKKworICAgICAgICByZXNbMF0gPSAoKGNvbnZlcnRlZFswXSAmIDB4RkZGRikpICogSU5WX01BWF9TSE9SVDsKKyAgICAgICAgcmVzWzFdID0gKChjb252ZXJ0ZWRbMV0gJiAweEZGRkYpKSAqIElOVl9NQVhfU0hPUlQ7CisgICAgICAgIHJlc1syXSA9ICgoY29udmVydGVkWzJdICYgMHhGRkZGKSkgKiBJTlZfTUFYX1NIT1JUOworCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgdGhlIHRyYW5zZm9ybWF0aW9uIG9mIGEgY29sb3IgZnJvbSB0aGlzIENvbG9yU3BhY2UgaW50byB0aGUKKyAgICAgKiBDU19DSUVYWVogY29sb3Igc3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9ydmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciB2YWx1ZSBpbiB0aGlzIENvbG9yU3BhY2UuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgd2l0aCBjb2xvciBjb21wb25lbnRzIGluIHRoZSBDU19DSUVYWVogY29sb3IKKyAgICAgKiAgICAgICAgIHNwYWNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIHRvQ0lFWFlaKGZsb2F0W10gY29sb3J2YWx1ZSkgeworICAgICAgICBpZiAodG9YWVpUcmFuc2Zvcm0gPT0gbnVsbCkgeworICAgICAgICAgICAgSUNDX1Byb2ZpbGUgeHl6UHJvZmlsZSA9CisgICAgICAgICAgICAgICAgKChJQ0NfQ29sb3JTcGFjZSkgQ29sb3JTcGFjZS5nZXRJbnN0YW5jZShDU19DSUVYWVopKS5nZXRQcm9maWxlKCk7CisgICAgICAgICAgICBJQ0NfUHJvZmlsZVtdIHByb2ZpbGVzID0ge2dldFByb2ZpbGUoKSwgeHl6UHJvZmlsZX07CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludFtdIGludGVudHMgPSB7CisgICAgICAgICAgICAgICAgICAgICAgICBJQ0NfUHJvZmlsZS5pY1JlbGF0aXZlQ29sb3JpbWV0cmljLAorICAgICAgICAgICAgICAgICAgICAgICAgSUNDX1Byb2ZpbGUuaWNQZXJjZXB0dWFsfTsKKyAgICAgICAgICAgICAgICB0b1hZWlRyYW5zZm9ybSA9IG5ldyBJQ0NfVHJhbnNmb3JtKHByb2ZpbGVzLCBpbnRlbnRzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENNTUV4Y2VwdGlvbiBlKSB7IC8vIE5vIHN1Y2ggdGFnLCB1c2Ugd2hhdCB3ZSBjYW4KKyAgICAgICAgICAgICAgICB0b1hZWlRyYW5zZm9ybSA9IG5ldyBJQ0NfVHJhbnNmb3JtKHByb2ZpbGVzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCFzY2FsaW5nRGF0YUxvYWRlZCkgeworICAgICAgICAgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEodGhpcyk7CisgICAgICAgICAgICAgICAgc2NhbGluZ0RhdGFMb2FkZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc2hvcnRbXSBkYXRhID0gbmV3IHNob3J0W2dldE51bUNvbXBvbmVudHMoKV07CisKKyAgICAgICAgc2NhbGVyLnNjYWxlKGNvbG9ydmFsdWUsIGRhdGEsIDApOworCisgICAgICAgIHNob3J0W10gY29udmVydGVkID0KKyAgICAgICAgICAgIGNvbnZlcnRlci50cmFuc2xhdGVDb2xvcih0b1hZWlRyYW5zZm9ybSwgZGF0YSwgbnVsbCk7CisKKyAgICAgICAgLy8gdW5zY2FsZSB0byBYWVoKKyAgICAgICAgZmxvYXRbXSByZXMgPSBuZXcgZmxvYXRbM107CisKKyAgICAgICAgcmVzWzBdID0gKChjb252ZXJ0ZWRbMF0gJiAweEZGRkYpKSAqIFNIT1JUMlhZWl9GQUNUT1I7CisgICAgICAgIHJlc1sxXSA9ICgoY29udmVydGVkWzFdICYgMHhGRkZGKSkgKiBTSE9SVDJYWVpfRkFDVE9SOworICAgICAgICByZXNbMl0gPSAoKGNvbnZlcnRlZFsyXSAmIDB4RkZGRikpICogU0hPUlQyWFlaX0ZBQ1RPUjsKKworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBhIGNvbG9yIGZyb20gdGhlIFJHQiBjb2xvciBzcGFjZSBpbnRvIHRoaXMKKyAgICAgKiBDb2xvclNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByZ2J2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHJlcHJlc2VudGluZyBhIGNvbG9yIGluIHRoZSBSR0IgY29sb3Igc3BhY2UuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgd2l0aCB0aGUgdHJhbnNmb3JtZWQgY29sb3IgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXRbXSBmcm9tUkdCKGZsb2F0W10gcmdidmFsdWUpIHsKKyAgICAgICAgaWYgKGZyb21SR0JUcmFuc2Zvcm0gPT0gbnVsbCkgeworICAgICAgICAgICAgSUNDX1Byb2ZpbGUgc1JHQlByb2ZpbGUgPQorICAgICAgICAgICAgICAgICgoSUNDX0NvbG9yU3BhY2UpIENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ1Nfc1JHQikpLmdldFByb2ZpbGUoKTsKKyAgICAgICAgICAgIElDQ19Qcm9maWxlW10gcHJvZmlsZXMgPSB7c1JHQlByb2ZpbGUsIGdldFByb2ZpbGUoKX07CisgICAgICAgICAgICBmcm9tUkdCVHJhbnNmb3JtID0gbmV3IElDQ19UcmFuc2Zvcm0ocHJvZmlsZXMpOworICAgICAgICAgICAgaWYgKCFzY2FsaW5nRGF0YUxvYWRlZCkgeworICAgICAgICAgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEodGhpcyk7CisgICAgICAgICAgICAgICAgc2NhbGluZ0RhdGFMb2FkZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc2NhbGUgcmdiIHZhbHVlIHRvIHNob3J0CisgICAgICAgIHNob3J0W10gc2NhbGVkUkdCVmFsdWUgPSBuZXcgc2hvcnRbM107CisgICAgICAgIHNjYWxlZFJHQlZhbHVlWzBdID0gKHNob3J0KShyZ2J2YWx1ZVswXSAqIE1BWF9TSE9SVCArIDAuNWYpOworICAgICAgICBzY2FsZWRSR0JWYWx1ZVsxXSA9IChzaG9ydCkocmdidmFsdWVbMV0gKiBNQVhfU0hPUlQgKyAwLjVmKTsKKyAgICAgICAgc2NhbGVkUkdCVmFsdWVbMl0gPSAoc2hvcnQpKHJnYnZhbHVlWzJdICogTUFYX1NIT1JUICsgMC41Zik7CisKKyAgICAgICAgc2hvcnRbXSBjb252ZXJ0ZWQgPQorICAgICAgICAgICAgY29udmVydGVyLnRyYW5zbGF0ZUNvbG9yKGZyb21SR0JUcmFuc2Zvcm0sIHNjYWxlZFJHQlZhbHVlLCBudWxsKTsKKworICAgICAgICBmbG9hdFtdIHJlcyA9IG5ldyBmbG9hdFtnZXROdW1Db21wb25lbnRzKCldOworCisgICAgICAgIHNjYWxlci51bnNjYWxlKHJlcywgY29udmVydGVkLCAwKTsKKworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBhIGNvbG9yIGZyb20gdGhlIENTX0NJRVhZWiBjb2xvciBzcGFjZQorICAgICAqIGludG8gdGhpcyBDb2xvclNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4eXp2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHJlcHJlc2VudGluZyBhIGNvbG9yIGluIHRoZSBDU19DSUVYWVogY29sb3IKKyAgICAgKiAgICAgICAgICAgIHNwYWNlLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGFycmF5IHdpdGggdGhlIHRyYW5zZm9ybWVkIGNvbG9yIGNvbXBvbmVudHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0W10gZnJvbUNJRVhZWihmbG9hdFtdIHh5enZhbHVlKSB7CisgICAgICAgIGlmIChmcm9tWFlaVHJhbnNmb3JtID09IG51bGwpIHsKKyAgICAgICAgICAgIElDQ19Qcm9maWxlIHh5elByb2ZpbGUgPQorICAgICAgICAgICAgICAgICgoSUNDX0NvbG9yU3BhY2UpIENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ1NfQ0lFWFlaKSkuZ2V0UHJvZmlsZSgpOworICAgICAgICAgICAgSUNDX1Byb2ZpbGVbXSBwcm9maWxlcyA9IHt4eXpQcm9maWxlLCBnZXRQcm9maWxlKCl9OworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnRbXSBpbnRlbnRzID0geworICAgICAgICAgICAgICAgICAgICAgICAgSUNDX1Byb2ZpbGUuaWNQZXJjZXB0dWFsLAorICAgICAgICAgICAgICAgICAgICAgICAgSUNDX1Byb2ZpbGUuaWNSZWxhdGl2ZUNvbG9yaW1ldHJpY307CisgICAgICAgICAgICAgICAgZnJvbVhZWlRyYW5zZm9ybSA9IG5ldyBJQ0NfVHJhbnNmb3JtKHByb2ZpbGVzLCBpbnRlbnRzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENNTUV4Y2VwdGlvbiBlKSB7IC8vIE5vIHN1Y2ggdGFnLCB1c2Ugd2hhdCB3ZSBjYW4KKyAgICAgICAgICAgICAgICBmcm9tWFlaVHJhbnNmb3JtID0gbmV3IElDQ19UcmFuc2Zvcm0ocHJvZmlsZXMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIXNjYWxpbmdEYXRhTG9hZGVkKSB7CisgICAgICAgICAgICAgICAgc2NhbGVyLmxvYWRTY2FsaW5nRGF0YSh0aGlzKTsKKyAgICAgICAgICAgICAgICBzY2FsaW5nRGF0YUxvYWRlZCA9IHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNjYWxlIHh5eiB2YWx1ZSB0byBzaG9ydAorICAgICAgICBzaG9ydFtdIHNjYWxlZFhZWlZhbHVlID0gbmV3IHNob3J0WzNdOworICAgICAgICBzY2FsZWRYWVpWYWx1ZVswXSA9IChzaG9ydCkoeHl6dmFsdWVbMF0gKiBYWVoyU0hPUlRfRkFDVE9SICsgMC41Zik7CisgICAgICAgIHNjYWxlZFhZWlZhbHVlWzFdID0gKHNob3J0KSh4eXp2YWx1ZVsxXSAqIFhZWjJTSE9SVF9GQUNUT1IgKyAwLjVmKTsKKyAgICAgICAgc2NhbGVkWFlaVmFsdWVbMl0gPSAoc2hvcnQpKHh5enZhbHVlWzJdICogWFlaMlNIT1JUX0ZBQ1RPUiArIDAuNWYpOworCisgICAgICAgIHNob3J0W10gY29udmVydGVkID0KKyAgICAgICAgICAgIGNvbnZlcnRlci50cmFuc2xhdGVDb2xvcihmcm9tWFlaVHJhbnNmb3JtLCBzY2FsZWRYWVpWYWx1ZSwgbnVsbCk7CisKKyAgICAgICAgZmxvYXRbXSByZXMgPSBuZXcgZmxvYXRbZ2V0TnVtQ29tcG9uZW50cygpXTsKKworICAgICAgICBzY2FsZXIudW5zY2FsZShyZXMsIGNvbnZlcnRlZCwgMCk7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIG5vcm1hbGl6ZWQgY29sb3IgY29tcG9uZW50IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnQgdG8gZGV0ZXJtaW5lIHRoZSBtaW5pbXVtIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgY29tcG9uZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRNaW5WYWx1ZShpbnQgY29tcG9uZW50KSB7CisgICAgICAgIGlmICgoY29tcG9uZW50IDwgMCkgfHwgKGNvbXBvbmVudCA+IHRoaXMuZ2V0TnVtQ29tcG9uZW50cygpIC0gMSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xNjk9Q29tcG9uZW50IGluZGV4IG91dCBvZiByYW5nZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xNjkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtaW5WYWx1ZXNbY29tcG9uZW50XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG5vcm1hbGl6ZWQgY29sb3IgY29tcG9uZW50IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnQgdG8gZGV0ZXJtaW5lIHRoZSBtYXhpbXVtIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgY29tcG9uZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRNYXhWYWx1ZShpbnQgY29tcG9uZW50KSB7CisgICAgICAgIGlmICgoY29tcG9uZW50IDwgMCkgfHwgKGNvbXBvbmVudCA+IHRoaXMuZ2V0TnVtQ29tcG9uZW50cygpIC0gMSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xNjk9Q29tcG9uZW50IGluZGV4IG91dCBvZiByYW5nZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xNjkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtYXhWYWx1ZXNbY29tcG9uZW50XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxsIG1pbiBtYXggdmFsdWVzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmaWxsTWluTWF4VmFsdWVzKCkgeworICAgICAgICBpbnQgbiA9IGdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgbWF4VmFsdWVzID0gbmV3IGZsb2F0W25dOworICAgICAgICBtaW5WYWx1ZXMgPSBuZXcgZmxvYXRbbl07CisgICAgICAgIHN3aXRjaCAoZ2V0VHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuVFlQRV9YWVo6CisgICAgICAgICAgICAgICAgbWluVmFsdWVzWzBdID0gMDsKKyAgICAgICAgICAgICAgICBtaW5WYWx1ZXNbMV0gPSAwOworICAgICAgICAgICAgICAgIG1pblZhbHVlc1syXSA9IDA7CisgICAgICAgICAgICAgICAgbWF4VmFsdWVzWzBdID0gTUFYX1hZWjsKKyAgICAgICAgICAgICAgICBtYXhWYWx1ZXNbMV0gPSBNQVhfWFlaOworICAgICAgICAgICAgICAgIG1heFZhbHVlc1syXSA9IE1BWF9YWVo7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuVFlQRV9MYWI6CisgICAgICAgICAgICAgICAgbWluVmFsdWVzWzBdID0gMDsKKyAgICAgICAgICAgICAgICBtaW5WYWx1ZXNbMV0gPSAtMTI4OworICAgICAgICAgICAgICAgIG1pblZhbHVlc1syXSA9IC0xMjg7CisgICAgICAgICAgICAgICAgbWF4VmFsdWVzWzBdID0gMTAwOworICAgICAgICAgICAgICAgIG1heFZhbHVlc1sxXSA9IDEyNzsKKyAgICAgICAgICAgICAgICBtYXhWYWx1ZXNbMl0gPSAxMjc7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPG47IGkrKykgeworICAgICAgICAgICAgICAgICAgICBtaW5WYWx1ZXNbaV0gPSAwOworICAgICAgICAgICAgICAgICAgICBtYXhWYWx1ZXNbaV0gPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgb3V0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIFNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IG91dC5wdXRGaWVsZHMoKTsKKworICAgICAgICBmaWVsZHMucHV0KCJ0aGlzUHJvZmlsZSIsIHByb2ZpbGUpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGZpZWxkcy5wdXQoIm1pblZhbCIsIG51bGwpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGZpZWxkcy5wdXQoIm1heFZhbCIsIG51bGwpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGZpZWxkcy5wdXQoImRpZmZNaW5NYXgiLCBudWxsKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBmaWVsZHMucHV0KCJpbnZEaWZmTWluTWF4IiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgZmllbGRzLnB1dCgibmVlZFNjYWxlSW5pdCIsIHRydWUpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgb3V0LndyaXRlRmllbGRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgaW4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgU2lnbmFscyB0aGF0IGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBjbGFzcyBub3QgZm91bmQgZXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IGluLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgcmVzb2x2ZWREZXNlcmlhbGl6ZWRJbnN0ID0KKyAgICAgICAgICAgICAgICBuZXcgSUNDX0NvbG9yU3BhY2UoKElDQ19Qcm9maWxlKSBmaWVsZHMuZ2V0KCJ0aGlzUHJvZmlsZSIsIG51bGwpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgcmVzb2x2ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3QKKyAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBvYmplY3Qgc3RyZWFtIGV4Y2VwdGlvbgorICAgICAqLworICAgIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVzb2x2ZWREZXNlcmlhbGl6ZWRJbnN0OworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2NvbG9yL0lDQ19Qcm9maWxlLmphdmEgYi9hd3QvamF2YS9hd3QvY29sb3IvSUNDX1Byb2ZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmZlZTZjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2NvbG9yL0lDQ19Qcm9maWxlLmphdmEKQEAgLTAsMCArMSwxNDc3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmNvbG9yOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLklDQ19Qcm9maWxlSGVscGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuTmF0aXZlQ01NOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBJQ0NfUHJvZmlsZSBjbGFzcyByZXByZXNlbnRzIGEgY29sb3IgcHJvZmlsZSBkYXRhIGZvciBjb2xvciBzcGFjZXMgYmFzZWQKKyAqIG9uIHRoZSBJbnRlcm5hdGlvbmFsIENvbG9yIENvbnNvcnRpdW0gU3BlY2lmaWNhdGlvbiBJQ0MuMToyMDAxLTEyLCBGaWxlCisgKiBGb3JtYXQgZm9yIENvbG9yIFByb2ZpbGVzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIElDQ19Qcm9maWxlIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zOTM4NTE1ODYxOTkwOTM2NzY2TDsKKworICAgIC8vIE5PVEU6IENvbnN0YW50IGZpZWxkIHZhbHVlcyBhcmUgbm90ZWQgaW4gMS41IHNwZWNpZmljYXRpb24uCisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xBU1NfSU5QVVQgaW5kaWNhdGVzIHRoYXQgcHJvZmlsZSBjbGFzcyBpcyBpbnB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19JTlBVVCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xBU1NfRElTUExBWSBpbmRpY2F0ZXMgdGhhdCBwcm9maWxlIGNsYXNzIGlzIGRpc3BsYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRElTUExBWSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xBU1NfT1VUUFVUIGluZGljYXRlcyB0aGF0IHByb2ZpbGUgY2xhc3MgaXMgb3V0cHV0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX09VVFBVVCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xBU1NfREVWSUNFTElOSyBpbmRpY2F0ZXMgdGhhdCBwcm9maWxlIGNsYXNzIGlzIGRldmljZQorICAgICAqIGxpbmsuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfREVWSUNFTElOSyA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ0xBU1NfQ09MT1JTUEFDRUNPTlZFUlNJT04gaW5kaWNhdGVzIHRoYXQgcHJvZmlsZSBjbGFzcyBpcworICAgICAqIGNvbG9yIHNwYWNlIGNvbnZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfQ09MT1JTUEFDRUNPTlZFUlNJT04gPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENMQVNTX0FCU1RSQUNUIGluZGljYXRlcyB0aGF0IHByb2ZpbGUgY2xhc3MgaXMgYWJzdHJhY3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfQUJTVFJBQ1QgPSA1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENMQVNTX05BTUVEQ09MT1IgaW5kaWNhdGVzIHRoYXQgcHJvZmlsZSBjbGFzcyBpcyBuYW1lZAorICAgICAqIGNvbG9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX05BTUVEQ09MT1IgPSA2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnWFlaRGF0YSAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnWFlaRGF0YSA9IDE0ODIyNTA3ODQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdMYWJEYXRhIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdMYWJEYXRhID0gMTI4MTQ1MDUyODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0x1dkRhdGEgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0x1dkRhdGEgPSAxMjgyNzY2MzY4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnWUNiQ3JEYXRhIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdZQ2JDckRhdGEgPSAxNDk3NTg4MzM4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnWXh5RGF0YSAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnWXh5RGF0YSA9IDE1MDEwNjc1NTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdSZ2JEYXRhIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdSZ2JEYXRhID0gMTM4MDQwMTY5NjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0dyYXlEYXRhIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdHcmF5RGF0YSA9IDExOTY1NzMwMTc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdIc3ZEYXRhIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdIc3ZEYXRhID0gMTIxMzQyMTA4ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0hsc0RhdGEgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0hsc0RhdGEgPSAxMjEyOTYxNTY4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQ215a0RhdGEgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0NteWtEYXRhID0gMTEyOTE0MjYwMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0NteURhdGEgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0NteURhdGEgPSAxMTI5MTQyNTYwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnU3BhY2UyQ0xSIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdTcGFjZTJDTFIgPSA4NDMyNzEyNTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdTcGFjZTNDTFIgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1NwYWNlM0NMUiA9IDg2MDA0ODQ2NjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlNENMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2U0Q0xSID0gODc2ODI1NjgyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnU3BhY2U1Q0xSIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdTcGFjZTVDTFIgPSA4OTM2MDI4OTg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdTcGFjZTZDTFIgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1NwYWNlNkNMUiA9IDkxMDM4MDExNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlN0NMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2U3Q0xSID0gOTI3MTU3MzMwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnU3BhY2U4Q0xSIC0gSUNDIFByb2ZpbGUgQ29sb3IgU3BhY2UgVHlwZSBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdTcGFjZThDTFIgPSA5NDM5MzQ1NDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdTcGFjZTlDTFIgLSBJQ0MgUHJvZmlsZSBDb2xvciBTcGFjZSBUeXBlIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1NwYWNlOUNMUiA9IDk2MDcxMTc2MjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlQUNMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VBQ0xSID0gMTA5NDkyOTQ5MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlQkNMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VCQ0xSID0gMTExMTcwNjcwNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlQ0NMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VDQ0xSID0gMTEyODQ4MzkyMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlRENMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VEQ0xSID0gMTE0NTI2MTEzODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlRUNMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VFQ0xSID0gMTE2MjAzODM1NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NwYWNlRkNMUiAtIElDQyBQcm9maWxlIENvbG9yIFNwYWNlIFR5cGUgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU3BhY2VGQ0xSID0gMTE3ODgxNTU3MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0lucHV0Q2xhc3MgLSBJQ0MgUHJvZmlsZSBDbGFzcyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdJbnB1dENsYXNzID0gMTkzNTg5NjE3ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0Rpc3BsYXlDbGFzcyAtIElDQyBQcm9maWxlIENsYXNzIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0Rpc3BsYXlDbGFzcyA9IDE4MzU5NTUzMTQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdPdXRwdXRDbGFzcyAtIElDQyBQcm9maWxlIENsYXNzIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ091dHB1dENsYXNzID0gMTg4NjU0OTEwNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0xpbmtDbGFzcyAtIElDQyBQcm9maWxlIENsYXNzIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0xpbmtDbGFzcyA9IDE4MTg4NDg4NzU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdBYnN0cmFjdENsYXNzIC0gSUNDIFByb2ZpbGUgQ2xhc3MgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQWJzdHJhY3RDbGFzcyA9IDE2MzM4NDIwMzY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdDb2xvcmFudE9yZGVyVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0NvbG9yYW50T3JkZXJUYWcgPSAxNjY4MDUxNTY3OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQ29sb3JhbnRUYWJsZVRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdDb2xvcmFudFRhYmxlVGFnID0gMTY2ODA1MTU3MjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0NvbG9yU3BhY2VDbGFzcyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdDb2xvclNwYWNlQ2xhc3MgPSAxOTM2NzQ0ODAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnTmFtZWRDb2xvckNsYXNzIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ05hbWVkQ29sb3JDbGFzcyA9IDE4NTI2NjI2MzY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNQZXJjZXB0dWFsIC0gSUNDIFByb2ZpbGUgUmVuZGVyaW5nIEludGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1BlcmNlcHR1YWwgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljUmVsYXRpdmVDb2xvcmltZXRyaWMgLSBJQ0MgUHJvZmlsZSBSZW5kZXJpbmcgSW50ZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljUmVsYXRpdmVDb2xvcmltZXRyaWMgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2F0dXJhdGlvbiAtIElDQyBQcm9maWxlIFJlbmRlcmluZyBJbnRlbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTYXR1cmF0aW9uID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0Fic29sdXRlQ29sb3JpbWV0cmljIC0gSUNDIFByb2ZpbGUgUmVuZGVyaW5nIEludGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0Fic29sdXRlQ29sb3JpbWV0cmljID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0hlYWQgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnSGVhZCA9IDE3NTE0NzQ1MzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdBVG9CMFRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdBVG9CMFRhZyA9IDEwOTM4MTI3ODQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdBVG9CMVRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdBVG9CMVRhZyA9IDEwOTM4MTI3ODU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdBVG9CMlRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdBVG9CMlRhZyA9IDEwOTM4MTI3ODY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdCbHVlQ29sb3JhbnRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQmx1ZUNvbG9yYW50VGFnID0gMTY0OTk1NzIxMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0JsdWVNYXRyaXhDb2x1bW5UYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQmx1ZU1hdHJpeENvbHVtblRhZyA9IDE2NDk5NTcyMTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdCbHVlVFJDVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0JsdWVUUkNUYWcgPSAxNjQ5NjkzMjUxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQlRvQTBUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQlRvQTBUYWcgPSAxMTEwNTg5NzQ0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQlRvQTFUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQlRvQTFUYWcgPSAxMTEwNTg5NzQ1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQlRvQTJUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQlRvQTJUYWcgPSAxMTEwNTg5NzQ2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnQ2FsaWJyYXRpb25EYXRlVGltZVRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdDYWxpYnJhdGlvbkRhdGVUaW1lVGFnID0gMTY2NzMyOTE0MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0NoYXJUYXJnZXRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQ2hhclRhcmdldFRhZyA9IDE5NTI1NDMzMzU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdDb3B5cmlnaHRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQ29weXJpZ2h0VGFnID0gMTY2ODMxMzcxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0NyZEluZm9UYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQ3JkSW5mb1RhZyA9IDE2Njg0NDExOTM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdEZXZpY2VNZmdEZXNjVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcgPSAxNjg0ODkzMjg0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnRGV2aWNlTW9kZWxEZXNjVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZyA9IDE2ODQ4OTA3MjQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdEZXZpY2VTZXR0aW5nc1RhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdEZXZpY2VTZXR0aW5nc1RhZyA9IDE2ODQzNzEwNTk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdHYW11dFRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdHYW11dFRhZyA9IDE3MzQ0MzgyNjA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdHcmF5VFJDVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0dyYXlUUkNUYWcgPSAxODAwNjg4MTk1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnR3JlZW5Db2xvcmFudFRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdHcmVlbkNvbG9yYW50VGFnID0gMTczMzg0MzI5MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0dyZWVuTWF0cml4Q29sdW1uVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0dyZWVuTWF0cml4Q29sdW1uVGFnID0gMTczMzg0MzI5MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0dyZWVuVFJDVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ0dyZWVuVFJDVGFnID0gMTczMzU3OTMzMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0x1bWluYW5jZVRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdMdW1pbmFuY2VUYWcgPSAxODE5NjM1MDQ5OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnTWVhc3VyZW1lbnRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnTWVhc3VyZW1lbnRUYWcgPSAxODM1MzYwNjI3OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnTWVkaWFCbGFja1BvaW50VGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ01lZGlhQmxhY2tQb2ludFRhZyA9IDE2NTEyMDgzMDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnID0gMjAwNDExOTY2ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ05hbWVkQ29sb3IyVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ05hbWVkQ29sb3IyVGFnID0gMTg1MjAwOTUyMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ091dHB1dFJlc3BvbnNlVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ091dHB1dFJlc3BvbnNlVGFnID0gMTkxOTI1MTMxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1ByZXZpZXcwVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1ByZXZpZXcwVGFnID0gMTg4NjU0NTIwMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1ByZXZpZXcxVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1ByZXZpZXcxVGFnID0gMTg4NjU0NTIwMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1ByZXZpZXcyVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1ByZXZpZXcyVGFnID0gMTg4NjU0NTIwMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcgPSAxNjg0MzcwMjc1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnUHJvZmlsZVNlcXVlbmNlRGVzY1RhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdQcm9maWxlU2VxdWVuY2VEZXNjVGFnID0gMTg4NjYxMDgwMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1BzMkNSRDBUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnUHMyQ1JEMFRhZyA9IDE4ODY2MTA0ODA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdQczJDUkQxVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1BzMkNSRDFUYWcgPSAxODg2NjEwNDgxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnUHMyQ1JEMlRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdQczJDUkQyVGFnID0gMTg4NjYxMDQ4MjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1BzMkNSRDNUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnUHMyQ1JEM1RhZyA9IDE4ODY2MTA0ODM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdQczJDU0FUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnUHMyQ1NBVGFnID0gMTg4NjU5Nzc0NzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1BzMlJlbmRlcmluZ0ludGVudFRhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdQczJSZW5kZXJpbmdJbnRlbnRUYWcgPSAxODg2NTk3NzM3OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnUmVkQ29sb3JhbnRUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnUmVkQ29sb3JhbnRUYWcgPSAxOTE4MzkyNjY2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljU2lnUmVkTWF0cml4Q29sdW1uVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1JlZE1hdHJpeENvbHVtblRhZyA9IDE5MTgzOTI2NjY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdSZWRUUkNUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnUmVkVFJDVGFnID0gMTkxODEyODcwNzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1NjcmVlbmluZ0Rlc2NUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU2NyZWVuaW5nRGVzY1RhZyA9IDE5MzU4OTcxODg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdTY3JlZW5pbmdUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnU2NyZWVuaW5nVGFnID0gMTkzNTg5NzE5ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1RlY2hub2xvZ3lUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnVGVjaG5vbG9neVRhZyA9IDE5NTI4MDE2NDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdVY3JCZ1RhZyAtIElDQyBQcm9maWxlIFRhZyBTaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNTaWdVY3JCZ1RhZyA9IDE2NTA4Nzc0NzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdWaWV3aW5nQ29uZERlc2NUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnVmlld2luZ0NvbmREZXNjVGFnID0gMTk4NzQwNTE1NjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ1ZpZXdpbmdDb25kaXRpb25zVGFnIC0gSUNDIFByb2ZpbGUgVGFnIFNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY1NpZ1ZpZXdpbmdDb25kaXRpb25zVGFnID0gMTk4NjYxODc0MzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1NpZ0Nocm9tYXRpY0FkYXB0YXRpb25UYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQ2hyb21hdGljQWRhcHRhdGlvblRhZyA9IDE2Njc3ODUwNjA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNTaWdDaHJvbWF0aWNpdHlUYWcgLSBJQ0MgUHJvZmlsZSBUYWcgU2lnbmF0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljU2lnQ2hyb21hdGljaXR5VGFnID0gMTY2Nzc4OTQyMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkclNpemUgLSBJQ0MgUHJvZmlsZSBIZWFkZXIgTG9jYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNIZHJTaXplID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkckNtbUlkIC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyQ21tSWQgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyVmVyc2lvbiAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkclZlcnNpb24gPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyRGV2aWNlQ2xhc3MgLSBJQ0MgUHJvZmlsZSBIZWFkZXIgTG9jYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNIZHJEZXZpY2VDbGFzcyA9IDEyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyQ29sb3JTcGFjZSAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkckNvbG9yU3BhY2UgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkclBjcyAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkclBjcyA9IDIwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyRGF0ZSAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkckRhdGUgPSAyNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkck1hZ2ljIC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyTWFnaWMgPSAzNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkclBsYXRmb3JtIC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyUGxhdGZvcm0gPSA0MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0hkclByb2ZpbGVJRCAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkclByb2ZpbGVJRCA9IDg0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyRmxhZ3MgLSBJQ0MgUHJvZmlsZSBIZWFkZXIgTG9jYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNIZHJGbGFncyA9IDQ0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyTWFudWZhY3R1cmVyIC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyTWFudWZhY3R1cmVyID0gNDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNIZHJNb2RlbCAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkck1vZGVsID0gNTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNIZHJBdHRyaWJ1dGVzIC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyQXR0cmlidXRlcyA9IDU2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyUmVuZGVyaW5nSW50ZW50IC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRyUmVuZGVyaW5nSW50ZW50ID0gNjQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNIZHJJbGx1bWluYW50IC0gSUNDIFByb2ZpbGUgSGVhZGVyIExvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljSGRySWxsdW1pbmFudCA9IDY4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGljSGRyQ3JlYXRvciAtIElDQyBQcm9maWxlIEhlYWRlciBMb2NhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0hkckNyZWF0b3IgPSA4MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0lDQ0Fic29sdXRlQ29sb3JpbWV0cmljIC0gSUNDIFByb2ZpbGUgUmVuZGVyaW5nIEludGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpY0lDQ0Fic29sdXRlQ29sb3JpbWV0cmljID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY01lZGlhUmVsYXRpdmVDb2xvcmltZXRyaWMgLSBJQ0MgUHJvZmlsZSBSZW5kZXJpbmcgSW50ZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljTWVkaWFSZWxhdGl2ZUNvbG9yaW1ldHJpYyA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNUYWdUeXBlIC0gSUNDIFByb2ZpbGUgQ29uc3RhbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNUYWdUeXBlID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY1RhZ1Jlc2VydmVkIC0gSUNDIFByb2ZpbGUgQ29uc3RhbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNUYWdSZXNlcnZlZCA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNDdXJ2ZUNvdW50IC0gSUNDIFByb2ZpbGUgQ29uc3RhbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNDdXJ2ZUNvdW50ID0gODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBpY0N1cnZlRGF0YSAtIElDQyBQcm9maWxlIENvbnN0YW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGljQ3VydmVEYXRhID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgaWNYWVpOdW1iZXJYIC0gSUNDIFByb2ZpbGUgQ29uc3RhbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaWNYWVpOdW1iZXJYID0gODsKKworICAgIC8qKgorICAgICAqIFNpemUgb2YgYSBwcm9maWxlIGhlYWRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgaGVhZGVyU2l6ZSA9IDEyODsKKworICAgIC8qKgorICAgICAqIGhlYWRlciBtYWdpYyBudW1iZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGhlYWRlck1hZ2ljTnVtYmVyID0gMHg2MTYzNzM3MDsKKworICAgIC8vIENhY2hlIG9mIHByZWRlZmluZWQgcHJvZmlsZXMKKyAgICAvKioKKyAgICAgKiBUaGUgcyByZ2IgcHJvZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJQ0NfUHJvZmlsZSBzUkdCUHJvZmlsZTsKKworICAgIC8qKgorICAgICAqIFRoZSB4eXogcHJvZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJQ0NfUHJvZmlsZSB4eXpQcm9maWxlOworCisgICAgLyoqCisgICAgICogVGhlIGdyYXkgcHJvZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJQ0NfUHJvZmlsZSBncmF5UHJvZmlsZTsKKworICAgIC8qKgorICAgICAqIFRoZSBweWNjIHByb2ZpbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgSUNDX1Byb2ZpbGUgcHljY1Byb2ZpbGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGluZWFyIHJnYiBwcm9maWxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIElDQ19Qcm9maWxlIGxpbmVhclJHQlByb2ZpbGU7CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGUgdG8gdGhlIGN1cnJlbnQgcHJvZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBsb25nIHByb2ZpbGVIYW5kbGUgPSAwOworCisgICAgLyoqCisgICAgICogSWYgaGFuZGxlIGlzIHVzZWQgYnkgYW5vdGhlciBjbGFzcyB0aGlzIG9iamVjdCBpcyBub3QgcmVzcG9uc2libGUgZm9yCisgICAgICogY2xvc2luZyBwcm9maWxlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGJvb2xlYW4gaGFuZGxlU3RvbGVuID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBDYWNoZWQgaGVhZGVyIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYnl0ZVtdIGhlYWRlckRhdGEgPSBudWxsOworCisgICAgLyoqCisgICAgICogU2VyaWFsaXphdGlvbiBzdXBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IElDQ19Qcm9maWxlIG9wZW5lZFByb2ZpbGVPYmplY3Q7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUNDIHByb2ZpbGUgd2l0aCB0aGUgZ2l2ZW4gZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBJQ0NfUHJvZmlsZShieXRlW10gZGF0YSkgeworICAgICAgICBwcm9maWxlSGFuZGxlID0gTmF0aXZlQ01NLmNtbU9wZW5Qcm9maWxlKGRhdGEpOworICAgICAgICBOYXRpdmVDTU0uYWRkSGFuZGxlKHRoaXMsIHByb2ZpbGVIYW5kbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gaW5zdGFudGlhdGUgZHVtbXkgSUNDX1Byb2ZpbGVTdHViIG9iamVjdHMuCisgICAgICovCisgICAgSUNDX1Byb2ZpbGUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBpbnN0YW50aWF0ZSBzdWJjbGFzc2VzIChJQ0NfUHJvZmlsZUdyZXkgYW5kIElDQ19Qcm9maWxlUkdCKS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvZmlsZUhhbmRsZQorICAgICAqICAgICAgICAgICAgLSBzaG91bGQgYmUgdmFsaWQgaGFuZGxlIHRvIG9wZW5lZCBjb2xvciBwcm9maWxlCisgICAgICovCisgICAgSUNDX1Byb2ZpbGUobG9uZyBwcm9maWxlSGFuZGxlKSB7CisgICAgICAgIHRoaXMucHJvZmlsZUhhbmRsZSA9IHByb2ZpbGVIYW5kbGU7CisgICAgICAgIC8vIEEgbmV3IG9iamVjdCByZWZlcmVuY2UsIG5lZWQgdG8gYWRkIGl0LgorICAgICAgICBOYXRpdmVDTU0uYWRkSGFuZGxlKHRoaXMsIHByb2ZpbGVIYW5kbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgSUNDX1Byb2ZpbGUgdG8gYSBmaWxlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgbmFtZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQgZHVyaW5nIHdyaXRpbmcgb3Igb3BlbmluZworICAgICAqICAgICAgICAgICAgIHRoZSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvU3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZU5hbWUpOworICAgICAgICBvU3RyZWFtLndyaXRlKGdldERhdGEoKSk7CisgICAgICAgIG9TdHJlYW0uY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemFibGUgaW1wbGVtZW50YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIFNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgICAgIHMud3JpdGVPYmplY3QobnVsbCk7CisgICAgICAgIHMud3JpdGVPYmplY3QoZ2V0RGF0YSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemFibGUgaW1wbGVtZW50YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIFNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgY2xhc3Mgbm90IGZvdW5kIGV4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgU3RyaW5nIGNvbG9yU3BhY2VTdHIgPSAoU3RyaW5nKXMucmVhZE9iamVjdCgpOworICAgICAgICBieXRlW10gZGF0YSA9IChieXRlW10pcy5yZWFkT2JqZWN0KCk7CisKKyAgICAgICAgaWYgKGNvbG9yU3BhY2VTdHIgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGNvbG9yU3BhY2VTdHIuZXF1YWxzKCJDU19zUkdCIikpIHsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIG9wZW5lZFByb2ZpbGVPYmplY3QgPSBnZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjb2xvclNwYWNlU3RyLmVxdWFscygiQ1NfR1JBWSIpKSB7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICBvcGVuZWRQcm9maWxlT2JqZWN0ID0gZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19HUkFZKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29sb3JTcGFjZVN0ci5lcXVhbHMoIkNTX0xJTkVBUl9SR0IiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgb3BlbmVkUHJvZmlsZU9iamVjdCA9IGdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1NfTElORUFSX1JHQik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbG9yU3BhY2VTdHIuZXF1YWxzKCJDU19DSUVYWVoiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgb3BlbmVkUHJvZmlsZU9iamVjdCA9IGdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1NfQ0lFWFlaKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29sb3JTcGFjZVN0ci5lcXVhbHMoIkNTX1BZQ0MiKSkgeyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgb3BlbmVkUHJvZmlsZU9iamVjdCA9IGdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1NfUFlDQyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG9wZW5lZFByb2ZpbGVPYmplY3QgPSBJQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZShkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG9wZW5lZFByb2ZpbGVPYmplY3QgPSBJQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZShkYXRhKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc29sdmVzIGluc3RhbmNlcyBiZWluZyBkZXNlcmlhbGl6ZWQgaW50byBpbnN0YW5jZXMgcmVnaXN0ZXJlZCB3aXRoIENNTS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIElDQ19Qcm9maWxlIG9iamVjdCBmb3IgcHJvZmlsZSByZWdpc3RlcmVkIHdpdGggQ01NLgorICAgICAqIEB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIHNlcmlhbGl6ZWQgZmlsZXMgb3IgZHVyaW5nIHRoZQorICAgICAqICAgICAgICAgICAgIHByb2Nlc3Mgb2YgcmVhZGluZyB0aGVtLgorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgcmVhZFJlc29sdmUoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW5lZFByb2ZpbGVPYmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBJQ0NfUHJvZmlsZSB0byBhbiBPdXRwdXRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBPdXRwdXRTdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZCBkdXJpbmcgd3JpdGluZyBvcgorICAgICAqICAgICAgICAgICAgIG9wZW5pbmcgT3V0cHV0U3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKE91dHB1dFN0cmVhbSBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzLndyaXRlKGdldERhdGEoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIHRhZ2dlZCBkYXRhIGVsZW1lbnQgaW4gdGhlIHByb2ZpbGUgZnJvbSBhIGJ5dGUgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHRhZ1NpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIElDQyB0YWcgc2lnbmF0dXJlIGZvciB0aGUgZGF0YSBlbGVtZW50IHRvIGJlIHNldC4KKyAgICAgKiBAcGFyYW0gdGFnRGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdG8gYmUgc2V0IGZvciB0aGUgc3BlY2lmaWVkIHRhZyBzaWduYXR1cmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0YShpbnQgdGFnU2lnbmF0dXJlLCBieXRlW10gdGFnRGF0YSkgeworICAgICAgICBOYXRpdmVDTU0uY21tU2V0UHJvZmlsZUVsZW1lbnQocHJvZmlsZUhhbmRsZSwgdGFnU2lnbmF0dXJlLCB0YWdEYXRhKTsKKyAgICAgICAgLy8gUmVtb3ZlIGNhY2hlZCBoZWFkZXIgZGF0YSBpZiBoZWFkZXIgaXMgbW9kaWZpZWQKKyAgICAgICAgaWYgKHRhZ1NpZ25hdHVyZSA9PSBpY1NpZ0hlYWQpIHsKKyAgICAgICAgICAgIGhlYWRlckRhdGEgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIHRhZ2dlZCBkYXRhIGVsZW1lbnQgZnJvbSB0aGUgcHJvZmlsZSBhcyBhIGJ5dGUgYXJyYXkuIEVsZW1lbnRzIGFyZQorICAgICAqIGlkZW50aWZpZWQgYnkgdGFnIHNpZ25hdHVyZXMgYXMgZGVmaW5lZCBpbiB0aGUgSUNDIHNwZWNpZmljYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHRhZ1NpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIElDQyB0YWcgc2lnbmF0dXJlIGZvciB0aGUgZGF0YSBlbGVtZW50IHRvIGdldC4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSB0YWdnZWQgZGF0YSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RGF0YShpbnQgdGFnU2lnbmF0dXJlKSB7CisgICAgICAgIGludCB0YWdTaXplID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhZ1NpemUgPSBOYXRpdmVDTU0uY21tR2V0UHJvZmlsZUVsZW1lbnRTaXplKHByb2ZpbGVIYW5kbGUsIHRhZ1NpZ25hdHVyZSk7CisgICAgICAgIH0gY2F0Y2ggKENNTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBXZSdsbCBnZXQgdGhpcyBleGNlcHRpb24gaWYgdGhlcmUncyBubyBlbGVtZW50IHdpdGgKKyAgICAgICAgICAgIC8vIHRoZSBzcGVjaWZpZWQgdGFnIHNpZ25hdHVyZQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW3RhZ1NpemVdOworICAgICAgICBOYXRpdmVDTU0uY21tR2V0UHJvZmlsZUVsZW1lbnQocHJvZmlsZUhhbmRsZSwgdGFnU2lnbmF0dXJlLCBkYXRhKTsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGRhdGEgYnl0ZSBhcnJheSBvZiB0aGlzIElDQ19Qcm9maWxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIElDQyBQcm9maWxlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKCkgeworICAgICAgICBpbnQgcHJvZmlsZVNpemUgPSBOYXRpdmVDTU0uY21tR2V0UHJvZmlsZVNpemUocHJvZmlsZUhhbmRsZSk7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbcHJvZmlsZVNpemVdOworICAgICAgICBOYXRpdmVDTU0uY21tR2V0UHJvZmlsZShwcm9maWxlSGFuZGxlLCBkYXRhKTsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogRnJlZXMgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggYW4gSUNDX1Byb2ZpbGUgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgeworICAgICAgICBpZiAocHJvZmlsZUhhbmRsZSAhPSAwICYmICFoYW5kbGVTdG9sZW4pIHsKKyAgICAgICAgICAgIE5hdGl2ZUNNTS5jbW1DbG9zZVByb2ZpbGUocHJvZmlsZUhhbmRsZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBBbHdheXMgcmVtb3ZlIGJlY2F1c2Uga2V5IG5vIG1vcmUgZXhpc3QKKyAgICAgICAgLy8gd2hlbiBvYmplY3QgaXMgZGVzdHJveWVkCisgICAgICAgIE5hdGl2ZUNNTS5yZW1vdmVIYW5kbGUodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJvZmlsZSBjbGFzcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm9maWxlIGNsYXNzIGNvbnN0YW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UHJvZmlsZUNsYXNzKCkgeworICAgICAgICBpbnQgZGV2aWNlQ2xhc3NTaWduYXR1cmUgPSBnZXRJbnRGcm9tSGVhZGVyKGljSGRyRGV2aWNlQ2xhc3MpOworCisgICAgICAgIHN3aXRjaCAoZGV2aWNlQ2xhc3NTaWduYXR1cmUpIHsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdDb2xvclNwYWNlQ2xhc3M6CisgICAgICAgICAgICAgICAgcmV0dXJuIENMQVNTX0NPTE9SU1BBQ0VDT05WRVJTSU9OOworICAgICAgICAgICAgY2FzZSBpY1NpZ0Rpc3BsYXlDbGFzczoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ0xBU1NfRElTUExBWTsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdPdXRwdXRDbGFzczoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ0xBU1NfT1VUUFVUOworICAgICAgICAgICAgY2FzZSBpY1NpZ0lucHV0Q2xhc3M6CisgICAgICAgICAgICAgICAgcmV0dXJuIENMQVNTX0lOUFVUOworICAgICAgICAgICAgY2FzZSBpY1NpZ0xpbmtDbGFzczoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ0xBU1NfREVWSUNFTElOSzsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdBYnN0cmFjdENsYXNzOgorICAgICAgICAgICAgICAgIHJldHVybiBDTEFTU19BQlNUUkFDVDsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdOYW1lZENvbG9yQ2xhc3M6CisgICAgICAgICAgICAgICAgcmV0dXJuIENMQVNTX05BTUVEQ09MT1I7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICB9CisKKyAgICAgICAgLy8gTm90IGFuIElDQyBwcm9maWxlIGNsYXNzCisgICAgICAgIC8vIGF3dC4xNUY9UHJvZmlsZSBjbGFzcyBkb2VzIG5vdCBjb21wbHkgd2l0aCBJQ0Mgc3BlY2lmaWNhdGlvbgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE1RiIpKTsgLy8kTk9OLU5MUy0xJAorCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29sb3Igc3BhY2UgdHlwZSBvZiB0aGUgUHJvZmlsZSBDb25uZWN0aW9uIFNwYWNlIChQQ1MpLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFBDUyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UENTVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGNzRnJvbVNpZ25hdHVyZShnZXRJbnRGcm9tSGVhZGVyKGljSGRyUGNzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhpcyBJQ0MgUHJvZmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiB0aGlzIElDQyBQcm9maWxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtQ29tcG9uZW50cygpIHsKKyAgICAgICAgc3dpdGNoIChnZXRJbnRGcm9tSGVhZGVyKGljSGRyQ29sb3JTcGFjZSkpIHsKKyAgICAgICAgICAgIC8vIFRoZSBtb3N0IGNvbW1vbiBjYXNlcyBnbyBmaXJzdCB0byBpbmNyZWFzZSBzcGVlZAorICAgICAgICAgICAgY2FzZSBpY1NpZ1JnYkRhdGE6CisgICAgICAgICAgICBjYXNlIGljU2lnWFlaRGF0YToKKyAgICAgICAgICAgIGNhc2UgaWNTaWdMYWJEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiAzOworICAgICAgICAgICAgY2FzZSBpY1NpZ0NteWtEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiA0OworICAgICAgICAgICAgICAgIC8vIFRoZW4gYWxsIG90aGVyCisgICAgICAgICAgICBjYXNlIGljU2lnR3JheURhdGE6CisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2UyQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiAyOworICAgICAgICAgICAgY2FzZSBpY1NpZ1lDYkNyRGF0YToKKyAgICAgICAgICAgIGNhc2UgaWNTaWdMdXZEYXRhOgorICAgICAgICAgICAgY2FzZSBpY1NpZ1l4eURhdGE6CisgICAgICAgICAgICBjYXNlIGljU2lnSGxzRGF0YToKKyAgICAgICAgICAgIGNhc2UgaWNTaWdIc3ZEYXRhOgorICAgICAgICAgICAgY2FzZSBpY1NpZ0NteURhdGE6CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2UzQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiAzOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlNENMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gNDsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZTVDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIDU7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2U2Q0xSOgorICAgICAgICAgICAgICAgIHJldHVybiA2OworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlN0NMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gNzsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZThDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIDg7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2U5Q0xSOgorICAgICAgICAgICAgICAgIHJldHVybiA5OworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlQUNMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gMTA7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2VCQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiAxMTsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZUNDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIDEyOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlRENMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gMTM7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2VFQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiAxNDsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZUZDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIDE1OworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgfQorCisgICAgICAgIC8vIGF3dC4xNjA9Q29sb3Igc3BhY2UgZG9lc24ndCBjb21wbHkgd2l0aCBJQ0Mgc3BlY2lmaWNhdGlvbgorICAgICAgICB0aHJvdyBuZXcgUHJvZmlsZURhdGFFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTYwIikgLy8kTk9OLU5MUy0xJAorICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbm9yIHZlcnNpb24gb2YgdGhpcyBJQ0MgcHJvZmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoaXMgSUNDIHByb2ZpbGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNaW5vclZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiBnZXRCeXRlRnJvbUhlYWRlcihpY0hkclZlcnNpb24gKyAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYWpvciB2ZXJzaW9uIG9mIHRoaXMgSUNDIHByb2ZpbGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWFqb3IgdmVyc2lvbiBvZiB0aGlzIElDQyBwcm9maWxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWFqb3JWZXJzaW9uKCkgeworICAgICAgICByZXR1cm4gZ2V0Qnl0ZUZyb21IZWFkZXIoaWNIZHJWZXJzaW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb2xvciBzcGFjZSB0eXBlIG9mIHRoaXMgSUNDX1Byb2ZpbGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY29sb3Igc3BhY2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvbG9yU3BhY2VUeXBlKCkgeworICAgICAgICByZXR1cm4gY3NGcm9tU2lnbmF0dXJlKGdldEludEZyb21IZWFkZXIoaWNIZHJDb2xvclNwYWNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gb3BlbiB0aGUgZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGguIFBhdGggZW50cmllcyBjYW4gYmUgZGl2aWRlZAorICAgICAqIGJ5IGEgc2VwYXJhdG9yIGNoYXJhY3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHBhdGggdG8gdGhlIGZpbGUuCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIHRoZSBmaWxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEZpbGVJbnB1dFN0cmVhbSB0cnlQYXRoKFN0cmluZyBwYXRoLCBTdHJpbmcgZmlsZU5hbWUpIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpU3RyZWFtID0gbnVsbDsKKworICAgICAgICBpZiAocGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocGF0aCwgRmlsZS5wYXRoU2VwYXJhdG9yKTsKKworICAgICAgICB3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBTdHJpbmcgcGF0aEVudHJ5ID0gc3QubmV4dFRva2VuKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpU3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShwYXRoRW50cnkgKyBGaWxlLnNlcGFyYXRvckNoYXIgKyBmaWxlTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKGZpU3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpU3RyZWFtOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmlTdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2luZ2xlIGluc3RhbmNlIG9mIElDQ19Qcm9maWxlIGZyb20gZGF0YSBpbiB0aGUgc3BlY2lmaWVkIGZpbGUuCisgICAgICogCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIG5hbWUgb2YgZmlsZSB3aXRoIElDQyBwcm9maWxlIGRhdGEuCisgICAgICogQHJldHVybiBzaW5nbGUgaW5zdGFuY2Ugb2YgSUNDX1Byb2ZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHNpZ25hbHMgdGhhdCBhbiBJL08gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyB0aGUgZmlsZSBvcgorICAgICAqICAgICAgICAgICAgIHRoZSBmaWxlIGRvZXMgbm90IGV4aXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSUNDX1Byb2ZpbGUgZ2V0SW5zdGFuY2UoU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgZk5hbWUgPSBmaWxlTmFtZTsgLy8gdG8gdXNlIGluIHRoZSBwcml2aWxlZ2VkIGJsb2NrCisKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpU3RyZWFtID0gKEZpbGVJbnB1dFN0cmVhbSlBY2Nlc3NDb250cm9sbGVyCisgICAgICAgICAgICAgICAgLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxGaWxlSW5wdXRTdHJlYW0+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgRmlsZUlucHV0U3RyZWFtIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaVN0cmVhbSA9IG51bGw7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZW4gYWJzb2x1dGUgcGF0aAorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaVN0cmVhbSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZk5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaVN0cmVhbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaVN0cmVhbTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBqYXZhLmljY3Byb2ZpbGUucGF0aCBlbnRyaWVzCisgICAgICAgICAgICAgICAgICAgICAgICBmaVN0cmVhbSA9IHRyeVBhdGgoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmljY3Byb2ZpbGUucGF0aCIpLCBmTmFtZSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaVN0cmVhbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpU3RyZWFtOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBqYXZhLmNsYXNzLnBhdGggZW50cmllcworICAgICAgICAgICAgICAgICAgICAgICAgZmlTdHJlYW0gPSB0cnlQYXRoKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5jbGFzcy5wYXRoIiksIGZOYW1lKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpU3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlTdHJlYW07CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGRpcmVjdG9yeSB3aXRoIGphdmEgc2FtcGxlIHByb2ZpbGVzCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob21lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaVN0cmVhbSA9IHRyeVBhdGgoaG9tZSArIEZpbGUuc2VwYXJhdG9yQ2hhcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAibGliIiArIEZpbGUuc2VwYXJhdG9yQ2hhciArICJjbW0iLCBmTmFtZSAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlTdHJlYW07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9KTsKKworICAgICAgICBpZiAoZmlTdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjE2MT1VbmFibGUgdG8gb3BlbiBmaWxlIHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2MSIsIGZpbGVOYW1lKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIElDQ19Qcm9maWxlIHBmID0gZ2V0SW5zdGFuY2UoZmlTdHJlYW0pOworICAgICAgICBmaVN0cmVhbS5jbG9zZSgpOworICAgICAgICByZXR1cm4gcGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2luZ2xlIGluc3RhbmNlIG9mIElDQ19Qcm9maWxlIHdpdGggZGF0YSBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogSW5wdXRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbnB1dFN0cmVhbSB3aXRoIElDQyBwcm9maWxlIGRhdGEuCisgICAgICogQHJldHVybiBzaW5nbGUgaW5zdGFuY2Ugb2YgSUNDX1Byb2ZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkIGR1cmluZyByZWFkaW5nIGZyb20KKyAgICAgKiAgICAgICAgICAgICBJbnB1dFN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdmFsaWQgSUNDIFByb2ZpbGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElDQ19Qcm9maWxlIGdldEluc3RhbmNlKElucHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBoZWFkZXIgPSBuZXcgYnl0ZVtoZWFkZXJTaXplXTsKKyAgICAgICAgLy8gYXd0LjE2Mj1JbnZhbGlkIElDQyBQcm9maWxlIERhdGEKKyAgICAgICAgU3RyaW5nIGludmFsaWREYXRhTWVzc2FnZSA9IE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2MiIpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgLy8gR2V0IGhlYWRlciBmcm9tIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgICAgaWYgKHMucmVhZChoZWFkZXIpICE9IGhlYWRlclNpemUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oaW52YWxpZERhdGFNZXNzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIHRoZSBwcm9maWxlIGRhdGEgZm9yIGNvbnNpc3RlbmN5CisgICAgICAgIGlmIChJQ0NfUHJvZmlsZUhlbHBlci5nZXRCaWdFbmRpYW5Gcm9tQnl0ZUFycmF5KGhlYWRlciwgaWNIZHJNYWdpYykgIT0gaGVhZGVyTWFnaWNOdW1iZXIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oaW52YWxpZERhdGFNZXNzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdldCBwcm9maWxlIHNpemUgZnJvbSBoZWFkZXIsIGNyZWF0ZSBhbiBhcnJheSBmb3IgcHJvZmlsZSBkYXRhCisgICAgICAgIGludCBwcm9maWxlU2l6ZSA9IElDQ19Qcm9maWxlSGVscGVyLmdldEJpZ0VuZGlhbkZyb21CeXRlQXJyYXkoaGVhZGVyLCBpY0hkclNpemUpOworICAgICAgICBieXRlW10gcHJvZmlsZURhdGEgPSBuZXcgYnl0ZVtwcm9maWxlU2l6ZV07CisKKyAgICAgICAgLy8gQ29weSBoZWFkZXIgaW50byBpdAorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGhlYWRlciwgMCwgcHJvZmlsZURhdGEsIDAsIGhlYWRlclNpemUpOworCisgICAgICAgIC8vIFJlYWQgdGhlIHByb2ZpbGUgaXRzZWxmCisgICAgICAgIGlmIChzLnJlYWQocHJvZmlsZURhdGEsIGhlYWRlclNpemUsIHByb2ZpbGVTaXplIC0gaGVhZGVyU2l6ZSkgIT0gcHJvZmlsZVNpemUgLSBoZWFkZXJTaXplKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGludmFsaWREYXRhTWVzc2FnZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UocHJvZmlsZURhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNpbmdsZSBpbnN0YW5jZSBvZiBJQ0NfUHJvZmlsZSBmcm9tIHRoZSBzcGVjaWZpZWQgZGF0YSBpbiBhIGJ5dGUKKyAgICAgKiBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgb2YgSUNDIHByb2ZpbGUuCisgICAgICogQHJldHVybiBzaW5nbGUgaW5zdGFuY2Ugb2YgSUNDX1Byb2ZpbGUgZnJvbSB0aGUgc3BlY2lmaWVkIGRhdGEgaW4gYSBieXRlCisgICAgICogICAgICAgICBhcnJheS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdmFsaWQgSUNDIFByb2ZpbGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElDQ19Qcm9maWxlIGdldEluc3RhbmNlKGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIElDQ19Qcm9maWxlIHJlcyA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcyA9IG5ldyBJQ0NfUHJvZmlsZShkYXRhKTsKKyAgICAgICAgfSBjYXRjaCAoQ01NRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xNjI9SW52YWxpZCBJQ0MgUHJvZmlsZSBEYXRhCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2MiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MubmFtZSIpLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigid2luZG93cyIpID49IDApIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChyZXMuZ2V0Q29sb3JTcGFjZVR5cGUoKSA9PSBDb2xvclNwYWNlLlRZUEVfUkdCCisgICAgICAgICAgICAgICAgICAgICAgICAmJiByZXMuZ2V0RGF0YVNpemUoaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcpID4gMAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmVzLmdldERhdGFTaXplKGljU2lnUmVkQ29sb3JhbnRUYWcpID4gMAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmVzLmdldERhdGFTaXplKGljU2lnR3JlZW5Db2xvcmFudFRhZykgPiAwCisgICAgICAgICAgICAgICAgICAgICAgICAmJiByZXMuZ2V0RGF0YVNpemUoaWNTaWdCbHVlQ29sb3JhbnRUYWcpID4gMAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmVzLmdldERhdGFTaXplKGljU2lnUmVkVFJDVGFnKSA+IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHJlcy5nZXREYXRhU2l6ZShpY1NpZ0dyZWVuVFJDVGFnKSA+IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHJlcy5nZXREYXRhU2l6ZShpY1NpZ0JsdWVUUkNUYWcpID4gMCkgeworICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgSUNDX1Byb2ZpbGVSR0IocmVzLmdldFByb2ZpbGVIYW5kbGUoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXMuZ2V0Q29sb3JTcGFjZVR5cGUoKSA9PSBDb2xvclNwYWNlLlRZUEVfR1JBWQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmVzLmdldERhdGFTaXplKGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnKSA+IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHJlcy5nZXREYXRhU2l6ZShpY1NpZ0dyYXlUUkNUYWcpID4gMCkgeworICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgSUNDX1Byb2ZpbGVHcmF5KHJlcy5nZXRQcm9maWxlSGFuZGxlKCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSBjYXRjaCAoQ01NRXhjZXB0aW9uIGUpIHsgLyogcmV0dXJuIHJlcyBpbiB0aGlzIGNhc2UgKi8KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2luZ2xlIGluc3RhbmNlIG9mIElDQ19Qcm9maWxlIHdpdGggdGhlIHNwZWNpZmljIGNvbG9yIHNwYWNlCisgICAgICogZGVmaW5lZCBieSB0aGUgQ29sb3JTcGFjZSBjbGFzczogQ1Nfc1JHQiwgQ1NfTElORUFSX1JHQiwgQ1NfQ0lFWFlaLAorICAgICAqIENTX1BZQ0MsIENTX0dSQVkuCisgICAgICogCisgICAgICogQHBhcmFtIGNzcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgY29sb3Igc3BhY2UgZGVmaW5lZCBpbiB0aGUgQ29sb3JTcGFjZSBjbGFzcy4KKyAgICAgKiBAcmV0dXJuIHNpbmdsZSBpbnN0YW5jZSBvZiBJQ0NfUHJvZmlsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlzIG5vdCBvbmUgb2YgdGhlIGRlZmluZWQgY29sb3Igc3BhY2UgdHlwZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJQ0NfUHJvZmlsZSBnZXRJbnN0YW5jZShpbnQgY3NwYWNlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzd2l0Y2ggKGNzcGFjZSkgeworCisgICAgICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX3NSR0I6CisgICAgICAgICAgICAgICAgICAgIGlmIChzUkdCUHJvZmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzUkdCUHJvZmlsZSA9IGdldEluc3RhbmNlKCJzUkdCLnBmIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gc1JHQlByb2ZpbGU7CisKKyAgICAgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfQ0lFWFlaOgorICAgICAgICAgICAgICAgICAgICBpZiAoeHl6UHJvZmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4eXpQcm9maWxlID0gZ2V0SW5zdGFuY2UoIkNJRVhZWi5wZiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHh5elByb2ZpbGU7CisKKyAgICAgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfR1JBWToKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdyYXlQcm9maWxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyYXlQcm9maWxlID0gZ2V0SW5zdGFuY2UoIkdSQVkucGYiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBncmF5UHJvZmlsZTsKKworICAgICAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19QWUNDOgorICAgICAgICAgICAgICAgICAgICBpZiAocHljY1Byb2ZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHljY1Byb2ZpbGUgPSBnZXRJbnN0YW5jZSgiUFlDQy5wZiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHB5Y2NQcm9maWxlOworCisgICAgICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX0xJTkVBUl9SR0I6CisgICAgICAgICAgICAgICAgICAgIGlmIChsaW5lYXJSR0JQcm9maWxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVhclJHQlByb2ZpbGUgPSBnZXRJbnN0YW5jZSgiTElORUFSX1JHQi5wZiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmVhclJHQlByb2ZpbGU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gYXd0LjE2Mz1DYW4ndCBvcGVuIGNvbG9yIHByb2ZpbGUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJDYW4ndCBvcGVuIGNvbG9yIHByb2ZpbGUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vIGF3dC4xNjQ9Tm90IGEgcHJlZGVmaW5lZCBjb2xvciBzcGFjZQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiTm90IGEgcHJlZGVmaW5lZCBjb2xvciBzcGFjZSIpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuIGludGVnZXIgZnJvbSB0aGUgcHJvZmlsZSBoZWFkZXIgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaWR4CisgICAgICogICAgICAgICAgICAtIG9mZnNldCBpbiBieXRlcyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGhlYWRlcgorICAgICAqIEByZXR1cm4gdGhlIGludGVnZXIgdmFsdWUgZnJvbSBoZWFkZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRJbnRGcm9tSGVhZGVyKGludCBpZHgpIHsKKyAgICAgICAgaWYgKGhlYWRlckRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgaGVhZGVyRGF0YSA9IGdldERhdGEoaWNTaWdIZWFkKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoKGhlYWRlckRhdGFbaWR4XSAmIDB4RkYpIDw8IDI0KSB8ICgoaGVhZGVyRGF0YVtpZHggKyAxXSAmIDB4RkYpIDw8IDE2KQorICAgICAgICAgICAgICAgIHwgKChoZWFkZXJEYXRhW2lkeCArIDJdICYgMHhGRikgPDwgOCkgfCAoKGhlYWRlckRhdGFbaWR4ICsgM10gJiAweEZGKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZSBmcm9tIHRoZSBwcm9maWxlIGhlYWRlciBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIC0gb2Zmc2V0IGluIGJ5dGVzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgaGVhZGVyCisgICAgICogQHJldHVybiB0aGUgYnl0ZSBmcm9tIGhlYWRlcgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZSBnZXRCeXRlRnJvbUhlYWRlcihpbnQgaWR4KSB7CisgICAgICAgIGlmIChoZWFkZXJEYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIGhlYWRlckRhdGEgPSBnZXREYXRhKGljU2lnSGVhZCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaGVhZGVyRGF0YVtpZHhdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIElDQyBjb2xvciBzcGFjZSBzaWduYXR1cmUgdG8gdGhlIGphdmEgcHJlZGVmaW5lZCBjb2xvciBzcGFjZQorICAgICAqIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHNpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIHNpZ25hdHVyZQorICAgICAqIEByZXR1cm4gdGhlIGludAorICAgICAqLworICAgIHByaXZhdGUgaW50IGNzRnJvbVNpZ25hdHVyZShpbnQgc2lnbmF0dXJlKSB7CisgICAgICAgIHN3aXRjaCAoc2lnbmF0dXJlKSB7CisgICAgICAgICAgICBjYXNlIGljU2lnUmdiRGF0YToKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFX1JHQjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdYWVpEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfWFlaOworICAgICAgICAgICAgY2FzZSBpY1NpZ0NteWtEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfQ01ZSzsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdMYWJEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfTGFiOworICAgICAgICAgICAgY2FzZSBpY1NpZ0dyYXlEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfR1JBWTsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdIbHNEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfSExTOworICAgICAgICAgICAgY2FzZSBpY1NpZ0x1dkRhdGE6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV9MdXY7CisgICAgICAgICAgICBjYXNlIGljU2lnWUNiQ3JEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfWUNiQ3I7CisgICAgICAgICAgICBjYXNlIGljU2lnWXh5RGF0YToKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFX1l4eTsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdIc3ZEYXRhOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfSFNWOworICAgICAgICAgICAgY2FzZSBpY1NpZ0NteURhdGE6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV9DTVk7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2UyQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfMkNMUjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZTNDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV8zQ0xSOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlNENMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFXzRDTFI7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2U1Q0xSOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfNUNMUjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZTZDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV82Q0xSOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlN0NMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFXzdDTFI7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2U4Q0xSOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfOENMUjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZTlDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV85Q0xSOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlQUNMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFX0FDTFI7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2VCQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfQkNMUjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZUNDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV9DQ0xSOworICAgICAgICAgICAgY2FzZSBpY1NpZ1NwYWNlRENMUjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFX0RDTFI7CisgICAgICAgICAgICBjYXNlIGljU2lnU3BhY2VFQ0xSOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfRUNMUjsKKyAgICAgICAgICAgIGNhc2UgaWNTaWdTcGFjZUZDTFI6CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yU3BhY2UuVFlQRV9GQ0xSOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgfQorCisgICAgICAgIC8vIGF3dC4xNjU9Q29sb3Igc3BhY2UgZG9lc24ndCBjb21wbHkgd2l0aCBJQ0Mgc3BlY2lmaWNhdGlvbgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByb2ZpbGUgaGFuZGxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHByb2ZpbGUgaGFuZGxlCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIGdldFByb2ZpbGVIYW5kbGUoKSB7CisgICAgICAgIGhhbmRsZVN0b2xlbiA9IHRydWU7CisgICAgICAgIHJldHVybiBwcm9maWxlSGFuZGxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgc2l6ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFnU2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgdGFnIHNpZ25hdHVyZQorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgc2l6ZQorICAgICAqLworICAgIHByaXZhdGUgaW50IGdldERhdGFTaXplKGludCB0YWdTaWduYXR1cmUpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNNTS5jbW1HZXRQcm9maWxlRWxlbWVudFNpemUocHJvZmlsZUhhbmRsZSwgdGFnU2lnbmF0dXJlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBYWVogdmFsdWUgZnJvbSB0aGUgdGFnIGRhdGEuCisgICAgICogCisgICAgICogQHBhcmFtIHRhZ1NpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIHRhZyBzaWduYXR1cmUKKyAgICAgKiBAcmV0dXJuIHRoZSBYWVogdmFsdWUKKyAgICAgKi8KKyAgICBmbG9hdFtdIGdldFhZWlZhbHVlKGludCB0YWdTaWduYXR1cmUpIHsKKyAgICAgICAgZmxvYXRbXSByZXMgPSBuZXcgZmxvYXRbM107CisgICAgICAgIGJ5dGVbXSBkYXRhID0gZ2V0RGF0YSh0YWdTaWduYXR1cmUpOworCisgICAgICAgIC8vIENvbnZlcnQgZnJvbSBJQ0MgczE1Rml4ZWQxNk51bWJlciB0eXBlCisgICAgICAgIC8vIDEgKGZsb2F0KSA9IDB4MTAwMDAgKHMxNUZpeGVkMTZOdW1iZXIpLAorICAgICAgICAvLyBoZW5jZSBkaXZpZGluZyBieSAweDEwMDAwCisgICAgICAgIHJlc1swXSA9IElDQ19Qcm9maWxlSGVscGVyLmdldEludEZyb21CeXRlQXJyYXkoZGF0YSwgMCkgLyA2NTUzNi5mOworICAgICAgICByZXNbMV0gPSBJQ0NfUHJvZmlsZUhlbHBlci5nZXRJbnRGcm9tQnl0ZUFycmF5KGRhdGEsIDQpIC8gNjU1MzYuZjsKKyAgICAgICAgcmVzWzJdID0gSUNDX1Byb2ZpbGVIZWxwZXIuZ2V0SW50RnJvbUJ5dGVBcnJheShkYXRhLCA4KSAvIDY1NTM2LmY7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZWRpYSB3aGl0ZSBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtZWRpYSB3aGl0ZSBwb2ludC4KKyAgICAgKi8KKyAgICBmbG9hdFtdIGdldE1lZGlhV2hpdGVQb2ludCgpIHsKKyAgICAgICAgcmV0dXJuIGdldFhZWlZhbHVlKGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBUUkMgaXMgbm90IGEgdGFibGUgcmV0dXJucyBnYW1tYSB2aWEgcmV0dXJuIHZhbHVlIGFuZCBzZXRzIGRhdGFUUkMgdG8KKyAgICAgKiBudWxsLiBJZiBUUkMgaXMgYSB0YWJsZSByZXR1cm5zIDAgYW5kIGZpbGxzIGRhdGFUUkMgd2l0aCB2YWx1ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHRhZ1NpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIHRhZyBzaWduYXR1cmUKKyAgICAgKiBAcGFyYW0gZGF0YVRSQworICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHJjCisgICAgICogQHJldHVybiAtIGdhbW1hIG9yIHplcm8gaWYgVFJDIGlzIGEgdGFibGUKKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGdldEdhbW1hT3JUUkMoaW50IHRhZ1NpZ25hdHVyZSwgc2hvcnRbXSBkYXRhVFJDKSB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gZ2V0RGF0YSh0YWdTaWduYXR1cmUpOworICAgICAgICBpbnQgdHJjU2l6ZSA9IElDQ19Qcm9maWxlSGVscGVyLmdldEludEZyb21CeXRlQXJyYXkoZGF0YSwgaWNDdXJ2ZUNvdW50KTsKKworICAgICAgICBkYXRhVFJDID0gbnVsbDsKKworICAgICAgICBpZiAodHJjU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMS4wZjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0cmNTaXplID09IDEpIHsKKyAgICAgICAgICAgIC8vIENhc3QgZnJvbSBJQ0MgdThGaXhlZDhOdW1iZXIgdG8gZmxvYXQKKyAgICAgICAgICAgIHJldHVybiBJQ0NfUHJvZmlsZUhlbHBlci5nZXRTaG9ydEZyb21CeXRlQXJyYXkoZGF0YSwgaWNDdXJ2ZURhdGEpIC8gMjU2LmY7CisgICAgICAgIH0KKworICAgICAgICAvLyBUUkMgaXMgYSB0YWJsZQorICAgICAgICBkYXRhVFJDID0gbmV3IHNob3J0W3RyY1NpemVdOworICAgICAgICBmb3IgKGludCBpID0gMCwgcG9zID0gaWNDdXJ2ZURhdGE7IGkgPCB0cmNTaXplOyBpKyssIHBvcyArPSAyKSB7CisgICAgICAgICAgICBkYXRhVFJDW2ldID0gSUNDX1Byb2ZpbGVIZWxwZXIuZ2V0U2hvcnRGcm9tQnl0ZUFycmF5KGRhdGEsIHBvcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZ2FtbWEuCisgICAgICogCisgICAgICogQHBhcmFtIHRhZ1NpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIHRhZyBzaWduYXR1cmUKKyAgICAgKiBAcmV0dXJuIHRoZSBnYW1tYQorICAgICAqLworICAgIGZsb2F0IGdldEdhbW1hKGludCB0YWdTaWduYXR1cmUpIHsKKyAgICAgICAgc2hvcnRbXSBkYXRhVFJDID0gbnVsbDsKKyAgICAgICAgZmxvYXQgZ2FtbWEgPSBnZXRHYW1tYU9yVFJDKHRhZ1NpZ25hdHVyZSwgZGF0YVRSQyk7CisKKyAgICAgICAgaWYgKGRhdGFUUkMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGdhbW1hOworICAgICAgICB9CisgICAgICAgIC8vIGF3dC4xNjY9VFJDIGlzIG5vdCBhIHNpbXBsZSBnYW1tYSB2YWx1ZS4KKyAgICAgICAgdGhyb3cgbmV3IFByb2ZpbGVEYXRhRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFRSQy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFnU2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgdGFnIHNpZ25hdHVyZQorICAgICAqIEByZXR1cm4gdGhlIHRSQworICAgICAqLworICAgIHNob3J0W10gZ2V0VFJDKGludCB0YWdTaWduYXR1cmUpIHsKKyAgICAgICAgc2hvcnRbXSBkYXRhVFJDID0gbnVsbDsKKyAgICAgICAgZ2V0R2FtbWFPclRSQyh0YWdTaWduYXR1cmUsIGRhdGFUUkMpOworCisgICAgICAgIGlmIChkYXRhVFJDID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xNjc9VFJDIGlzIGEgZ2FtbWEgdmFsdWUsIG5vdCBhIHRhYmxlLgorICAgICAgICAgICAgdGhyb3cgbmV3IFByb2ZpbGVEYXRhRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE2NyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBkYXRhVFJDOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZUdyYXkuamF2YSBiL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZUdyYXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzQ4MTAxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2NvbG9yL0lDQ19Qcm9maWxlR3JheS5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmNvbG9yOworCisvKioKKyAqIFRoZSBJQ0NfUHJvZmlsZUdyYXkgY2xhc3MgcmVwcmVzZW50IHByb2ZpbGVzIHdpdGggVFlQRV9HUkFZIGNvbG9yIHNwYWNlIHR5cGUsCisgKiBhbmQgaW5jbHVkZXMgdGhlIGdyYXlUUkNUYWcgYW5kIG1lZGlhV2hpdGVQb2ludFRhZyB0YWdzLiBUaGUgZ3JheSBjb21wb25lbnQKKyAqIGNhbiBiZSB0cmFuc2Zvcm1lZCBmcm9tIGEgR1JBWSBkZXZpY2UgcHJvZmlsZSBjb2xvciBzcGFjZSB0byB0aGUgQ0lFWFlaCisgKiBQcm9maWxlIHRocm91Z2ggdGhlIHRvbmUgcmVwcm9kdWN0aW9uIGN1cnZlIChUUkMpOgorICogPHA+CisgKiBQQ1NZID0gZ3JheVRSQ1tkZXZpY2VHcmF5XQorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIElDQ19Qcm9maWxlR3JheSBleHRlbmRzIElDQ19Qcm9maWxlIHsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTEyNDcyMTI5MDczMjAwMjY0OUw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgaUMgY18gcHJvZmlsZSBncmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9maWxlSGFuZGxlCisgICAgICogICAgICAgICAgICB0aGUgcHJvZmlsZSBoYW5kbGUKKyAgICAgKi8KKyAgICBJQ0NfUHJvZmlsZUdyYXkobG9uZyBwcm9maWxlSGFuZGxlKSB7CisgICAgICAgIHN1cGVyKHByb2ZpbGVIYW5kbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFRSQyBhcyBhbiBhcnJheSBvZiBzaG9ydHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc2hvcnQgYXJyYXkgb2YgdGhlIFRSQy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnRbXSBnZXRUUkMoKSB7CisgICAgICAgIHJldHVybiBzdXBlci5nZXRUUkMoaWNTaWdHcmF5VFJDVGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZWRpYSB3aGl0ZSBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtZWRpYSB3aGl0ZSBwb2ludAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIGdldE1lZGlhV2hpdGVQb2ludCgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldE1lZGlhV2hpdGVQb2ludCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBnYW1tYSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIHRvbmUgcmVwcm9kdWN0aW9uIGN1cnZlIChUUkMpLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGdhbW1hIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgdG9uZSByZXByb2R1Y3Rpb24gY3VydmUgKFRSQykuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEdhbW1hKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0R2FtbWEoaWNTaWdHcmF5VFJDVGFnKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZVJHQi5qYXZhIGIvYXd0L2phdmEvYXd0L2NvbG9yL0lDQ19Qcm9maWxlUkdCLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWM2MDEwZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZVJHQi5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5jb2xvcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBJQ0NfUHJvZmlsZVJHQiBjbGFzcyByZXByZXNlbnRzIHByb2ZpbGVzIHdpdGggUkdCIGNvbG9yIHNwYWNlIHR5cGUgYW5kCisgKiBjb250YWlucyB0aGUgcmVkQ29sb3JhbnRUYWcsIGdyZWVuQ29sb3JhbnRUYWcsIGJsdWVDb2xvcmFudFRhZywgcmVkVFJDVGFnLAorICogZ3JlZW5UUkNUYWcsIGJsdWVUUkNUYWcsIGFuZCBtZWRpYVdoaXRlUG9pbnRUYWcgdGFncy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJQ0NfUHJvZmlsZVJHQiBleHRlbmRzIElDQ19Qcm9maWxlIHsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4NTA1MDY3Mzg1MTUyNTc5MzM0TDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBSR0IgSUNDX1Byb2ZpbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHByb2ZpbGVIYW5kbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9maWxlIGhhbmRsZQorICAgICAqLworICAgIElDQ19Qcm9maWxlUkdCKGxvbmcgcHJvZmlsZUhhbmRsZSkgeworICAgICAgICBzdXBlcihwcm9maWxlSGFuZGxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVEQ09NUE9ORU5UIGluZGljYXRlcyB0aGUgcmVkIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRURDT01QT05FTlQgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEdSRUVOQ09NUE9ORU5UIGluZGljYXRlcyB0aGUgZ3JlZW4gY29tcG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdSRUVOQ09NUE9ORU5UID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBCTFVFQ09NUE9ORU5UIGluZGljYXRlcyB0aGUgYmx1ZSBjb21wb25lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkxVRUNPTVBPTkVOVCA9IDI7CisKKyAgICAvLyBhd3QuMTVFPVVua25vd24gY29tcG9uZW50LiBNdXN0IGJlIFJFRENPTVBPTkVOVCwgR1JFRU5DT01QT05FTlQgb3IgQkxVRUNPTVBPTkVOVC4KKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVU5LTk9XTl9DT01QT05FTlRfTVNHLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVTktOT1dOX0NPTVBPTkVOVF9NU0cgPSBNZXNzYWdlcworICAgICAgICAgICAgLmdldFN0cmluZygiYXd0LjE1RSIpOyAvLyROT04tTkxTLTEkCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBUUkMuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbXBvbmVudAorICAgICAqICAgICAgICAgICAgdGhlIHRhZyBzaWduYXR1cmUuCisgICAgICogQHJldHVybiB0aGUgVFJDIHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydFtdIGdldFRSQyhpbnQgY29tcG9uZW50KSB7CisgICAgICAgIHN3aXRjaCAoY29tcG9uZW50KSB7CisgICAgICAgICAgICBjYXNlIFJFRENPTVBPTkVOVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VFJDKGljU2lnUmVkVFJDVGFnKTsKKyAgICAgICAgICAgIGNhc2UgR1JFRU5DT01QT05FTlQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFRSQyhpY1NpZ0dyZWVuVFJDVGFnKTsKKyAgICAgICAgICAgIGNhc2UgQkxVRUNPTVBPTkVOVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VFJDKGljU2lnQmx1ZVRSQ1RhZyk7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihVTktOT1dOX0NPTVBPTkVOVF9NU0cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdhbW1hLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YWcgc2lnbmF0dXJlLgorICAgICAqIEByZXR1cm4gdGhlIGdhbW1hIHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRHYW1tYShpbnQgY29tcG9uZW50KSB7CisgICAgICAgIHN3aXRjaCAoY29tcG9uZW50KSB7CisgICAgICAgICAgICBjYXNlIFJFRENPTVBPTkVOVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0R2FtbWEoaWNTaWdSZWRUUkNUYWcpOworICAgICAgICAgICAgY2FzZSBHUkVFTkNPTVBPTkVOVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0R2FtbWEoaWNTaWdHcmVlblRSQ1RhZyk7CisgICAgICAgICAgICBjYXNlIEJMVUVDT01QT05FTlQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEdhbW1hKGljU2lnQmx1ZVRSQ1RhZyk7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihVTktOT1dOX0NPTVBPTkVOVF9NU0cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBmbG9hdCBtYXRyaXggd2hpY2ggY29udGFpbnMgdGhlIFgsIFksIGFuZCBaIGNvbXBvbmVudHMgb2YgdGhlCisgICAgICogcHJvZmlsZSdzIHJlZENvbG9yYW50VGFnLCBncmVlbkNvbG9yYW50VGFnLCBhbmQgYmx1ZUNvbG9yYW50VGFnLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IG1hdHJpeCB3aGljaCBjb250YWlucyB0aGUgWCwgWSwgYW5kIFogY29tcG9uZW50cyBvZiB0aGUKKyAgICAgKiAgICAgICAgIHByb2ZpbGUncyByZWRDb2xvcmFudFRhZywgZ3JlZW5Db2xvcmFudFRhZywgYW5kIGJsdWVDb2xvcmFudFRhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXVtdIGdldE1hdHJpeCgpIHsKKyAgICAgICAgZmxvYXQgW11bXSBtID0gbmV3IGZsb2F0WzNdWzNdOyAvLyBUaGUgbWF0cml4CisKKyAgICAgICAgZmxvYXRbXSByZWRYWVogPSBnZXRYWVpWYWx1ZShpY1NpZ1JlZENvbG9yYW50VGFnKTsKKyAgICAgICAgZmxvYXRbXSBncmVlblhZWiA9IGdldFhZWlZhbHVlKGljU2lnR3JlZW5Db2xvcmFudFRhZyk7CisgICAgICAgIGZsb2F0W10gYmx1ZVhZWiA9IGdldFhZWlZhbHVlKGljU2lnQmx1ZUNvbG9yYW50VGFnKTsKKworICAgICAgICBtWzBdWzBdID0gcmVkWFlaWzBdOworICAgICAgICBtWzFdWzBdID0gcmVkWFlaWzFdOworICAgICAgICBtWzJdWzBdID0gcmVkWFlaWzJdOworCisgICAgICAgIG1bMF1bMV0gPSBncmVlblhZWlswXTsKKyAgICAgICAgbVsxXVsxXSA9IGdyZWVuWFlaWzFdOworICAgICAgICBtWzJdWzFdID0gZ3JlZW5YWVpbMl07CisKKyAgICAgICAgbVswXVsyXSA9IGJsdWVYWVpbMF07CisgICAgICAgIG1bMV1bMl0gPSBibHVlWFlaWzFdOworICAgICAgICBtWzJdWzJdID0gYmx1ZVhZWlsyXTsKKworICAgICAgICByZXR1cm4gbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZWRpYSB3aGl0ZSBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtZWRpYSB3aGl0ZSBwb2ludC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRNZWRpYVdoaXRlUG9pbnQoKSB7CisgICAgICAgIHJldHVybiBzdXBlci5nZXRNZWRpYVdoaXRlUG9pbnQoKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZVN0dWIuamF2YSBiL2F3dC9qYXZhL2F3dC9jb2xvci9JQ0NfUHJvZmlsZVN0dWIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzA0YzhhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2NvbG9yL0lDQ19Qcm9maWxlU3R1Yi5qYXZhCkBAIC0wLDAgKzEsMTczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmNvbG9yOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKK2ZpbmFsIGNsYXNzIElDQ19Qcm9maWxlU3R1YiBleHRlbmRzIElDQ19Qcm9maWxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MDEzODk3NjA4NzUyNTM1MDdMOworCisgICAgdHJhbnNpZW50IGludCBjb2xvcnNwYWNlOworCisgICAgcHVibGljIElDQ19Qcm9maWxlU3R1YihpbnQgY3NTcGVjaWZpZXIpIHsKKyAgICAgICAgc3dpdGNoIChjc1NwZWNpZmllcikgeworICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX3NSR0I6CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfQ0lFWFlaOgorICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX0xJTkVBUl9SR0I6CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfUFlDQzoKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19HUkFZOgorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTVEPUludmFsaWQgY29sb3JzcGFjZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTVEIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgY29sb3JzcGFjZSA9IGNzU3BlY2lmaWVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemFibGUgaW1wbGVtZW50YXRpb24KKyAgICAgKgorICAgICAqIEB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBsb2FkUHJvZmlsZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKE91dHB1dFN0cmVhbSBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlN0dWIgY2Fubm90IHBlcmZvcm0gdGhpcyBvcGVyYXRpb24iKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERhdGEoaW50IHRhZ1NpZ25hdHVyZSwgYnl0ZVtdIHRhZ0RhdGEpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoaW50IHRhZ1NpZ25hdHVyZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlN0dWIgY2Fubm90IHBlcmZvcm0gdGhpcyBvcGVyYXRpb24iKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0RGF0YSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFByb2ZpbGVDbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIENMQVNTX0NPTE9SU1BBQ0VDT05WRVJTSU9OOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0UENTVHlwZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE51bUNvbXBvbmVudHMoKSB7CisgICAgICAgIHN3aXRjaCAoY29sb3JzcGFjZSkgeworICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX3NSR0I6CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfQ0lFWFlaOgorICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX0xJTkVBUl9SR0I6CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfUFlDQzoKKyAgICAgICAgICAgICAgICByZXR1cm4gMzsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19HUkFZOgorICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlN0dWIgY2Fubm90IHBlcmZvcm0gdGhpcyBvcGVyYXRpb24iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRNaW5vclZlcnNpb24oKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiU3R1YiBjYW5ub3QgcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRNYWpvclZlcnNpb24oKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiU3R1YiBjYW5ub3QgcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRDb2xvclNwYWNlVHlwZSgpIHsKKyAgICAgICAgc3dpdGNoIChjb2xvcnNwYWNlKSB7CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1Nfc1JHQjoKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19MSU5FQVJfUkdCOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfUkdCOworICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX0NJRVhZWjoKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3JTcGFjZS5UWVBFX1hZWjsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19QWUNDOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfM0NMUjsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19HUkFZOgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xvclNwYWNlLlRZUEVfR1JBWTsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSUNDX1Byb2ZpbGUgZ2V0SW5zdGFuY2UoU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlN0dWIgY2Fubm90IHBlcmZvcm0gdGhpcyBvcGVyYXRpb24iKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSUNDX1Byb2ZpbGUgZ2V0SW5zdGFuY2UoSW5wdXRTdHJlYW0gcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJTdHViIGNhbm5vdCBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIElDQ19Qcm9maWxlIGdldEluc3RhbmNlKGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiU3R1YiBjYW5ub3QgcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBJQ0NfUHJvZmlsZSBnZXRJbnN0YW5jZShpbnQgY3NwYWNlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiU3R1YiBjYW5ub3QgcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgcHVibGljIElDQ19Qcm9maWxlIGxvYWRQcm9maWxlKCkgeworICAgICAgICBzd2l0Y2ggKGNvbG9yc3BhY2UpIHsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19zUkdCOgorICAgICAgICAgICAgICAgIHJldHVybiBJQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpOworICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLkNTX0dSQVk6CisgICAgICAgICAgICAgICAgcmV0dXJuIElDQ19Qcm9maWxlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1NfR1JBWSk7CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfQ0lFWFlaOgorICAgICAgICAgICAgICAgIHJldHVybiBJQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX0NJRVhZWik7CisgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuQ1NfTElORUFSX1JHQjoKKyAgICAgICAgICAgICAgICByZXR1cm4gSUNDX1Byb2ZpbGUuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19MSU5FQVJfUkdCKTsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5DU19QWUNDOgorICAgICAgICAgICAgICAgIHJldHVybiBJQ0NfUHJvZmlsZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX1BZQ0MpOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlN0dWIgY2Fubm90IHBlcmZvcm0gdGhpcyBvcGVyYXRpb24iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9jb2xvci9Qcm9maWxlRGF0YUV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYXd0L2NvbG9yL1Byb2ZpbGVEYXRhRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM1ZjMxNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9jb2xvci9Qcm9maWxlRGF0YUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmNvbG9yOworCisvKioKKyAqIFRoZSBQcm9maWxlRGF0YUV4Y2VwdGlvbiBjbGFzcyByZXByZXNlbnRzIGFuIGVycm9yIHdoaWNoIG9jY3VycyB3aGlsZQorICogYWNjZXNzaW5nIG9yIHByb2Nlc3NpbmcgYW4gSUNDX1Byb2ZpbGUgb2JqZWN0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFByb2ZpbGVEYXRhRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisgICAgCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzI4NjE0MDg4ODI0MDMyMjQ5OEw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcHJvZmlsZSBkYXRhIGV4Y2VwdGlvbiB3aXRoIGRldGFpbGVkIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWxlZCBtZXNzYWdlIG9mIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFByb2ZpbGVEYXRhRXhjZXB0aW9uKFN0cmluZyBzKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvY29sb3IvcGFja2FnZS5odG1sIGIvYXd0L2phdmEvYXd0L2NvbG9yL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MDlkOTYzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2NvbG9yL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBjb250YWlucyBjbGFzc2VzIHJlcHJlc2VudGluZyBjb2xvciBzcGFjZXMgYW5kIHByb2ZpbGVzIGJhc2VkIG9uIHRoZSBJbnRlcm5hdGlvbmFsIENvbG9yIENvbnNvcnRpdW0gKElDQykgUHJvZmlsZSBGb3JtYXQgU3BlY2lmaWNhdGlvbi4gCisgICAgPC9wPgorICAgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvQVdURXZlbnRMaXN0ZW5lci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FXVEV2ZW50TGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjI5M2IzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FXVEV2ZW50TGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS5hd3QuQVdURXZlbnQ7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQVdURXZlbnRMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgcHVibGljIHZvaWQgZXZlbnREaXNwYXRjaGVkKEFXVEV2ZW50IGV2ZW50KTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0FXVEV2ZW50TGlzdGVuZXJQcm94eS5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FXVEV2ZW50TGlzdGVuZXJQcm94eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlZGM0MWYzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FXVEV2ZW50TGlzdGVuZXJQcm94eS5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5BV1RFdmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyUHJveHk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEFXVEV2ZW50TGlzdGVuZXJQcm94eSBleHRlbmRzIEV2ZW50TGlzdGVuZXJQcm94eSBpbXBsZW1lbnRzIEFXVEV2ZW50TGlzdGVuZXIgeworCisgICAgcHJpdmF0ZSBBV1RFdmVudExpc3RlbmVyIGxpc3RlbmVyOworICAgIHByaXZhdGUgbG9uZyBldmVudE1hc2s7CisKKyAgICBwdWJsaWMgQVdURXZlbnRMaXN0ZW5lclByb3h5KGxvbmcgZXZlbnRNYXNrLCBBV1RFdmVudExpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHN1cGVyKGxpc3RlbmVyKTsKKworICAgICAgICAvLyBhd3QuMTkzPUxpc3RlbmVyIGNhbid0IGJlIHplcm8KKyAgICAgICAgYXNzZXJ0IGxpc3RlbmVyICE9IG51bGwgOiBNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOTMiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIHRoaXMubGlzdGVuZXIgPSBsaXN0ZW5lcjsKKyAgICAgICAgdGhpcy5ldmVudE1hc2sgPSBldmVudE1hc2s7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZXZlbnREaXNwYXRjaGVkKEFXVEV2ZW50IGV2dCkgeworICAgICAgICBsaXN0ZW5lci5ldmVudERpc3BhdGNoZWQoZXZ0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRFdmVudE1hc2soKSB7CisgICAgICAgIHJldHVybiBldmVudE1hc2s7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvQWN0aW9uRXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9BY3Rpb25FdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4ODJlMGQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQWN0aW9uRXZlbnQuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQWN0aW9uRXZlbnQgZXh0ZW5kcyBBV1RFdmVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzY3MTA3ODc5NjI3MzgzMjE0OUw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSElGVF9NQVNLID0gMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENUUkxfTUFTSyA9IDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVRBX01BU0sgPSA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxUX01BU0sgPSA4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNUSU9OX0ZJUlNUID0gMTAwMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDVElPTl9MQVNUID0gMTAwMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDVElPTl9QRVJGT1JNRUQgPSAxMDAxOworCisgICAgcHJpdmF0ZSBsb25nIHdoZW47CisgICAgcHJpdmF0ZSBpbnQgbW9kaWZpZXJzOworICAgIHByaXZhdGUgU3RyaW5nIGNvbW1hbmQ7CisKKyAgICBwdWJsaWMgQWN0aW9uRXZlbnQoT2JqZWN0IHNvdXJjZSwgaW50IGlkLCBTdHJpbmcgY29tbWFuZCkgeworICAgICAgICB0aGlzKHNvdXJjZSwgaWQsIGNvbW1hbmQsIDApOworICAgIH0KKworICAgIHB1YmxpYyBBY3Rpb25FdmVudChPYmplY3Qgc291cmNlLCBpbnQgaWQsIFN0cmluZyBjb21tYW5kLCBpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHRoaXMoc291cmNlLCBpZCwgY29tbWFuZCwgMGwsIG1vZGlmaWVycyk7CisgICAgfQorCisgICAgcHVibGljIEFjdGlvbkV2ZW50KE9iamVjdCBzb3VyY2UsIGludCBpZCwgU3RyaW5nIGNvbW1hbmQsIGxvbmcgd2hlbiwgaW50IG1vZGlmaWVycykgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKworICAgICAgICB0aGlzLmNvbW1hbmQgPSBjb21tYW5kOworICAgICAgICB0aGlzLndoZW4gPSB3aGVuOworICAgICAgICB0aGlzLm1vZGlmaWVycyA9IG1vZGlmaWVyczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1vZGlmaWVycygpIHsKKyAgICAgICAgcmV0dXJuIG1vZGlmaWVyczsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEFjdGlvbkNvbW1hbmQoKSB7CisgICAgICAgIHJldHVybiBjb21tYW5kOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFdoZW4oKSB7CisgICAgICAgIHJldHVybiB3aGVuOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBBY3Rpb25FdmVudCBlID0gbmV3IEFjdGlvbkV2ZW50KG5ldyBDb21wb25lbnQoKXt9LAorICAgICAgICAgKiAgICAgICBBY3Rpb25FdmVudC5BQ1RJT05fUEVSRk9STUVELCAiQ29tbWFuZCIsCisgICAgICAgICAqICAgICAgIEFjdGlvbkV2ZW50LlNISUZUX01BU0t8QWN0aW9uRXZlbnQuQ1RSTF9NQVNLfAorICAgICAgICAgKiAgICAgICBBY3Rpb25FdmVudC5NRVRBX01BU0t8QWN0aW9uRXZlbnQuQUxUX01BU0spOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyBpZFN0cmluZyA9IChpZCA9PSBBQ1RJT05fUEVSRk9STUVEKSA/IAorICAgICAgICAgICAgICAgICAgICAgICAgICAiQUNUSU9OX1BFUkZPUk1FRCIgOiAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIFN0cmluZyBtb2RpZmllcnNTdHJpbmcgPSAiIjsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGlmICgobW9kaWZpZXJzICYgU0hJRlRfTUFTSykgPiAwKSB7CisgICAgICAgICAgICBtb2RpZmllcnNTdHJpbmcgKz0gIlNoaWZ0IjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQ1RSTF9NQVNLKSA+IDApIHsKKyAgICAgICAgICAgIG1vZGlmaWVyc1N0cmluZyArPSBtb2RpZmllcnNTdHJpbmcubGVuZ3RoKCkgPT0gMCA/ICJDdHJsIiA6ICIrQ3RybCI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgTUVUQV9NQVNLKSA+IDApIHsKKyAgICAgICAgICAgIG1vZGlmaWVyc1N0cmluZyArPSBtb2RpZmllcnNTdHJpbmcubGVuZ3RoKCkgPT0gMCA/ICJNZXRhIiA6ICIrTWV0YSI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQUxUX01BU0spID4gMCkgeworICAgICAgICAgICAgbW9kaWZpZXJzU3RyaW5nICs9IG1vZGlmaWVyc1N0cmluZy5sZW5ndGgoKSA9PSAwID8gIkFsdCIgOiAiK0FsdCI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIChpZFN0cmluZyArICIsY21kPSIgKyBjb21tYW5kICsgIix3aGVuPSIgKyB3aGVuICsgIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIsbW9kaWZpZXJzPSIgKyBtb2RpZmllcnNTdHJpbmcpOyAvLyROT04tTkxTLTEkCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvQWN0aW9uTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9BY3Rpb25MaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2ZWVlN2EKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQWN0aW9uTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQWN0aW9uTGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0FkanVzdG1lbnRFdmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FkanVzdG1lbnRFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlMmQ2YzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQWRqdXN0bWVudEV2ZW50LmphdmEKQEAgLTAsMCArMSwxMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5BV1RFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5BZGp1c3RhYmxlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQWRqdXN0bWVudEV2ZW50IGV4dGVuZHMgQVdURXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTcwMDI5MDY0NTIwNTI3OTkyMUw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBREpVU1RNRU5UX0ZJUlNUID0gNjAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQURKVVNUTUVOVF9MQVNUID0gNjAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQURKVVNUTUVOVF9WQUxVRV9DSEFOR0VEID0gNjAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5JVF9JTkNSRU1FTlQgPSAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5JVF9ERUNSRU1FTlQgPSAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tfREVDUkVNRU5UID0gMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJMT0NLX0lOQ1JFTUVOVCA9IDQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFDSyA9IDU7CisKKyAgICBwcml2YXRlIGludCB0eXBlOworICAgIHByaXZhdGUgaW50IHZhbHVlOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0FkanVzdGluZzsKKworICAgIHB1YmxpYyBBZGp1c3RtZW50RXZlbnQoQWRqdXN0YWJsZSBzb3VyY2UsIGludCBpZCwgaW50IHR5cGUsIGludCB2YWx1ZSkgeworICAgICAgICB0aGlzKHNvdXJjZSwgaWQsIHR5cGUsIHZhbHVlLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIEFkanVzdG1lbnRFdmVudChBZGp1c3RhYmxlIHNvdXJjZSwgaW50IGlkLCBpbnQgdHlwZSwgaW50IHZhbHVlLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBZGp1c3RpbmcpIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCk7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgdGhpcy5pc0FkanVzdGluZyA9IGlzQWRqdXN0aW5nOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEFkanVzdG1lbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRWYWx1ZUlzQWRqdXN0aW5nKCkgeworICAgICAgICByZXR1cm4gaXNBZGp1c3Rpbmc7CisgICAgfQorCisgICAgcHVibGljIEFkanVzdGFibGUgZ2V0QWRqdXN0YWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIChBZGp1c3RhYmxlKSBzb3VyY2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciAKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICogCisgICAgICAgICAqIEFkanVzdG1lbnRFdmVudCBlID0gbmV3IEFkanVzdG1lbnRFdmVudChuZXcgU2Nyb2xsYmFyKCksIAorICAgICAgICAgKiAgICAgICBBZGp1c3RtZW50RXZlbnQuQURKVVNUTUVOVF9WQUxVRV9DSEFOR0VELCAKKyAgICAgICAgICogICAgICAgQWRqdXN0bWVudEV2ZW50LlVOSVRfSU5DUkVNRU5ULCAxKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICBTdHJpbmcgaWRTdHJpbmcgPSAoaWQgPT0gQURKVVNUTUVOVF9WQUxVRV9DSEFOR0VEID8KKyAgICAgICAgICAgICAgICAiQURKVVNUTUVOVF9WQUxVRV9DSEFOR0VEIiA6ICJ1bmtub3duIHR5cGUiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIFN0cmluZyBhZGpUeXBlID0gbnVsbDsKKworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgY2FzZSBVTklUX0lOQ1JFTUVOVDoKKyAgICAgICAgICAgIGFkalR5cGUgPSAiVU5JVF9JTkNSRU1FTlQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBVTklUX0RFQ1JFTUVOVDoKKyAgICAgICAgICAgIGFkalR5cGUgPSAiVU5JVF9ERUNSRU1FTlQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBCTE9DS19JTkNSRU1FTlQ6CisgICAgICAgICAgICBhZGpUeXBlID0gIkJMT0NLX0lOQ1JFTUVOVCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEJMT0NLX0RFQ1JFTUVOVDoKKyAgICAgICAgICAgIGFkalR5cGUgPSAiQkxPQ0tfREVDUkVNRU5UIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVFJBQ0s6CisgICAgICAgICAgICBhZGpUeXBlID0gIlRSQUNLIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBhZGpUeXBlID0gInVua25vd24gdHlwZSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoaWRTdHJpbmcgKyAiLGFkalR5cGU9IiArIGFkalR5cGUgKyAiLHZhbHVlPSIgKyB2YWx1ZSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIsaXNBZGp1c3Rpbmc9IiArIGlzQWRqdXN0aW5nKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0FkanVzdG1lbnRMaXN0ZW5lci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0FkanVzdG1lbnRMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmNmE3MjQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQWRqdXN0bWVudExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEFkanVzdG1lbnRMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgcHVibGljIHZvaWQgYWRqdXN0bWVudFZhbHVlQ2hhbmdlZChBZGp1c3RtZW50RXZlbnQgZSk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9Db21wb25lbnRBZGFwdGVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvQ29tcG9uZW50QWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0MjIzNWYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQ29tcG9uZW50QWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb21wb25lbnRBZGFwdGVyIGltcGxlbWVudHMgQ29tcG9uZW50TGlzdGVuZXIgeworCisgICAgcHVibGljIENvbXBvbmVudEFkYXB0ZXIoKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tcG9uZW50SGlkZGVuKENvbXBvbmVudEV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjb21wb25lbnRNb3ZlZChDb21wb25lbnRFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tcG9uZW50UmVzaXplZChDb21wb25lbnRFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tcG9uZW50U2hvd24oQ29tcG9uZW50RXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0NvbXBvbmVudEV2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvQ29tcG9uZW50RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjBkM2FiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0NvbXBvbmVudEV2ZW50LmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIENvbXBvbmVudEV2ZW50IGV4dGVuZHMgQVdURXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODEwMTQwNjgyMzkwMjk5Mjk2NUw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QT05FTlRfRklSU1QgPSAxMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QT05FTlRfTEFTVCA9IDEwMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTVBPTkVOVF9NT1ZFRCA9IDEwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTVBPTkVOVF9SRVNJWkVEID0gMTAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUE9ORU5UX1NIT1dOID0gMTAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUE9ORU5UX0hJRERFTiA9IDEwMzsKKworICAgIHB1YmxpYyBDb21wb25lbnRFdmVudChDb21wb25lbnQgc291cmNlLCBpbnQgaWQpIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCk7CisgICAgfQorCisgICAgcHVibGljIENvbXBvbmVudCBnZXRDb21wb25lbnQoKSB7CisgICAgICAgIHJldHVybiAoQ29tcG9uZW50KSBzb3VyY2U7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBDb21wb25lbnRFdmVudCBlID0gbmV3IENvbXBvbmVudEV2ZW50KG5ldyBCdXR0b24oIkJ1dHRvbiIpLCAKKyAgICAgICAgICogICAgICAgICAgQ29tcG9uZW50RXZlbnQuQ09NUE9ORU5UX1NIT1dOKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICBTdHJpbmcgaWRTdHJpbmcgPSBudWxsOworICAgICAgICBDb21wb25lbnQgYyA9IGdldENvbXBvbmVudCgpOworCisgICAgICAgIHN3aXRjaCAoaWQpIHsKKyAgICAgICAgY2FzZSBDT01QT05FTlRfTU9WRUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJDT01QT05FTlRfTU9WRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBDT01QT05FTlRfUkVTSVpFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIkNPTVBPTkVOVF9SRVNJWkVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQ09NUE9ORU5UX1NIT1dOOgorICAgICAgICAgICAgcmV0dXJuICJDT01QT05FTlRfU0hPV04iOyAvLyROT04tTkxTLTEkCisgICAgICAgIGNhc2UgQ09NUE9ORU5UX0hJRERFTjoKKyAgICAgICAgICAgIHJldHVybiAiQ09NUE9ORU5UX0hJRERFTiI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIChpZFN0cmluZyArICIgKCIgKyBjLmdldFgoKSArICIsIiArIGMuZ2V0WSgpICsgIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIgIiArIGMuZ2V0V2lkdGgoKSsgIngiICsgYy5nZXRIZWlnaHQoKSArICIpIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvQ29tcG9uZW50TGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Db21wb25lbnRMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1YWRiYTIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvQ29tcG9uZW50TGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29tcG9uZW50TGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIGNvbXBvbmVudEhpZGRlbihDb21wb25lbnRFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIGNvbXBvbmVudE1vdmVkKENvbXBvbmVudEV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgY29tcG9uZW50UmVzaXplZChDb21wb25lbnRFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIGNvbXBvbmVudFNob3duKENvbXBvbmVudEV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvQ29udGFpbmVyQWRhcHRlci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0NvbnRhaW5lckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NDk4M2M3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0NvbnRhaW5lckFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29udGFpbmVyQWRhcHRlciBpbXBsZW1lbnRzIENvbnRhaW5lckxpc3RlbmVyIHsKKworICAgIHB1YmxpYyBDb250YWluZXJBZGFwdGVyKCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNvbXBvbmVudEFkZGVkKENvbnRhaW5lckV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjb21wb25lbnRSZW1vdmVkKENvbnRhaW5lckV2ZW50IGUpIHsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9Db250YWluZXJFdmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0NvbnRhaW5lckV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcyYzllNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Db250YWluZXJFdmVudC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CisvLz8/P0FXVDogaW1wb3J0IGphdmEuYXd0LkNvbnRhaW5lcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIENvbnRhaW5lckV2ZW50IGV4dGVuZHMgQ29tcG9uZW50RXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQxMTQ5NDIyNTA1Mzk3NzIwNDFMOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OVEFJTkVSX0ZJUlNUID0gMzAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OVEFJTkVSX0xBU1QgPSAzMDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QT05FTlRfQURERUQgPSAzMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QT05FTlRfUkVNT1ZFRCA9IDMwMTsKKworICAgIHByaXZhdGUgQ29tcG9uZW50IGNoaWxkOworCisgICAgcHVibGljIENvbnRhaW5lckV2ZW50KENvbXBvbmVudCBzcmMsIGludCBpZCwgQ29tcG9uZW50IGNoaWxkKSB7CisgICAgICAgIHN1cGVyKHNyYywgaWQpOworICAgICAgICB0aGlzLmNoaWxkID0gY2hpbGQ7CisgICAgfQorCisgICAgcHVibGljIENvbXBvbmVudCBnZXRDaGlsZCgpIHsKKyAgICAgICAgcmV0dXJuIGNoaWxkOworICAgIH0KKworICAgIC8vPz8/QVdUCisgICAgLyoKKyAgICBwdWJsaWMgQ29udGFpbmVyIGdldENvbnRhaW5lcigpIHsKKyAgICAgICAgcmV0dXJuIChDb250YWluZXIpIHNvdXJjZTsKKyAgICB9CisgICAgKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBDb250YWluZXJFdmVudCBlID0gbmV3IENvbnRhaW5lckV2ZW50KG5ldyBQYW5lbCgpLAorICAgICAgICAgKiAgICAgICAgICBDb250YWluZXJFdmVudC5DT01QT05FTlRfQURERUQsCisgICAgICAgICAqICAgICAgICAgIG5ldyBCdXR0b24oIkJ1dHRvbiIpKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICBTdHJpbmcgaWRTdHJpbmcgPSBudWxsOworCisgICAgICAgIHN3aXRjaCAoaWQpIHsKKyAgICAgICAgY2FzZSBDT01QT05FTlRfQURERUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJDT01QT05FTlRfQURERUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBDT01QT05FTlRfUkVNT1ZFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIkNPTVBPTkVOVF9SRU1PVkVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJ1bmtub3duIHR5cGUiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKGlkU3RyaW5nICsgIixjaGlsZD0iICsgY2hpbGQuZ2V0TmFtZSgpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0NvbnRhaW5lckxpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvQ29udGFpbmVyTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MTc4NTllCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0NvbnRhaW5lckxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIENvbnRhaW5lckxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBjb21wb25lbnRBZGRlZChDb250YWluZXJFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIGNvbXBvbmVudFJlbW92ZWQoQ29udGFpbmVyRXZlbnQgZSk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0FkYXB0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0FkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTNlMzdmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0ZvY3VzQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb2N1c0FkYXB0ZXIgaW1wbGVtZW50cyBGb2N1c0xpc3RlbmVyIHsKKworICAgIHB1YmxpYyBGb2N1c0FkYXB0ZXIoKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZm9jdXNHYWluZWQoRm9jdXNFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0ZvY3VzRXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0V2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGExODY4OQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0V2ZW50LmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZvY3VzRXZlbnQgZXh0ZW5kcyBDb21wb25lbnRFdmVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MjM3NTM3ODY0NTc0MTYzOTZMOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9DVVNfRklSU1QgPSAxMDA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9DVVNfTEFTVCA9IDEwMDU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT0NVU19HQUlORUQgPSAxMDA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9DVVNfTE9TVCA9IDEwMDU7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gdGVtcG9yYXJ5OworICAgIHByaXZhdGUgQ29tcG9uZW50IG9wcG9zaXRlOworCisgICAgcHVibGljIEZvY3VzRXZlbnQoQ29tcG9uZW50IHNvdXJjZSwgaW50IGlkKSB7CisgICAgICAgIHRoaXMoc291cmNlLCBpZCwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyBGb2N1c0V2ZW50KENvbXBvbmVudCBzb3VyY2UsIGludCBpZCwgYm9vbGVhbiB0ZW1wb3JhcnkpIHsKKyAgICAgICAgdGhpcyhzb3VyY2UsIGlkLCB0ZW1wb3JhcnksIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBGb2N1c0V2ZW50KENvbXBvbmVudCBzb3VyY2UsIGludCBpZCwgYm9vbGVhbiB0ZW1wb3JhcnksIENvbXBvbmVudCBvcHBvc2l0ZSkgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKyAgICAgICAgdGhpcy50ZW1wb3JhcnkgPSB0ZW1wb3Jhcnk7CisgICAgICAgIHRoaXMub3Bwb3NpdGUgPSBvcHBvc2l0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29tcG9uZW50IGdldE9wcG9zaXRlQ29tcG9uZW50KCkgeworICAgICAgICByZXR1cm4gb3Bwb3NpdGU7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNUZW1wb3JhcnkoKSB7CisgICAgICAgIHJldHVybiB0ZW1wb3Jhcnk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciAKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICogCisgICAgICAgICAqIEZvY3VzRXZlbnQgZSA9IG5ldyBGb2N1c0V2ZW50KG5ldyBCdXR0b24oIkJ1dHRvbjAiKSwKKyAgICAgICAgICogICAgICAgRm9jdXNFdmVudC5GT0NVU19HQUlORUQsIGZhbHNlLCBuZXcgQnV0dG9uKCJCdXR0b24xIikpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyBpZFN0cmluZyA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChpZCkgeworICAgICAgICBjYXNlIEZPQ1VTX0dBSU5FRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIkZPQ1VTX0dBSU5FRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZPQ1VTX0xPU1Q6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJGT0NVU19MT1NUIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJ1bmtub3duIHR5cGUiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKGlkU3RyaW5nICsKKyAgICAgICAgICAgICAgICAodGVtcG9yYXJ5ID8gIix0ZW1wb3JhcnkiIDogIixwZXJtYW5lbnQiKSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIsb3Bwb3NpdGU9IiArIG9wcG9zaXRlKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0ZvY3VzTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0xpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmJiYmQwMAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Gb2N1c0xpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEZvY3VzTGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIGZvY3VzR2FpbmVkKEZvY3VzRXZlbnQgZSk7CisKKyAgICBwdWJsaWMgdm9pZCBmb2N1c0xvc3QoRm9jdXNFdmVudCBlKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0hpZXJhcmNoeUJvdW5kc0FkYXB0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9IaWVyYXJjaHlCb3VuZHNBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJmZThmZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9IaWVyYXJjaHlCb3VuZHNBZGFwdGVyLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEhpZXJhcmNoeUJvdW5kc0FkYXB0ZXIgaW1wbGVtZW50cyBIaWVyYXJjaHlCb3VuZHNMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgSGllcmFyY2h5Qm91bmRzQWRhcHRlcigpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhbmNlc3Rvck1vdmVkKEhpZXJhcmNoeUV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhbmNlc3RvclJlc2l6ZWQoSGllcmFyY2h5RXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0hpZXJhcmNoeUJvdW5kc0xpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvSGllcmFyY2h5Qm91bmRzTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZThmMmU3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0hpZXJhcmNoeUJvdW5kc0xpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEhpZXJhcmNoeUJvdW5kc0xpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBhbmNlc3Rvck1vdmVkKEhpZXJhcmNoeUV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgYW5jZXN0b3JSZXNpemVkKEhpZXJhcmNoeUV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvSGllcmFyY2h5RXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9IaWVyYXJjaHlFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxZDIyZjQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvSGllcmFyY2h5RXZlbnQuamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKy8vPz8/QVdUOiBpbXBvcnQgamF2YS5hd3QuQ29udGFpbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSGllcmFyY2h5RXZlbnQgZXh0ZW5kcyBBV1RFdmVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTMzNzU3Njk3MDAzODA0Mzk5MEw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBISUVSQVJDSFlfRklSU1QgPSAxNDAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSElFUkFSQ0hZX0NIQU5HRUQgPSAxNDAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1JfTU9WRUQgPSAxNDAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1JfUkVTSVpFRCA9IDE0MDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBISUVSQVJDSFlfTEFTVCA9IDE0MDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVJFTlRfQ0hBTkdFRCA9IDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVNQTEFZQUJJTElUWV9DSEFOR0VEID0gMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dJTkdfQ0hBTkdFRCA9IDQ7CisKKyAgICAvLz8/P0FXVDogcHJpdmF0ZSBDb250YWluZXIgY2hhbmdlZFBhcmVudDsKKyAgICBwcml2YXRlIENvbXBvbmVudCBjaGFuZ2VkOworICAgIHByaXZhdGUgbG9uZyBjaGFuZ2VGbGFnOworCisgICAgLy8/Pz9BV1QKKyAgICAvKgorICAgIHB1YmxpYyBIaWVyYXJjaHlFdmVudChDb21wb25lbnQgc291cmNlLCBpbnQgaWQsIENvbXBvbmVudCBjaGFuZ2VkLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGFpbmVyIGNoYW5nZWRQYXJlbnQpIHsKKyAgICAgICAgdGhpcyhzb3VyY2UsIGlkLCBjaGFuZ2VkLCBjaGFuZ2VkUGFyZW50LCAwbCk7CisgICAgfQorICAgICovCisKKyAgICAvLz8/P0FXVAorICAgIC8qCisgICAgcHVibGljIEhpZXJhcmNoeUV2ZW50KENvbXBvbmVudCBzb3VyY2UsIGludCBpZCwgQ29tcG9uZW50IGNoYW5nZWQsCisgICAgICAgICAgICBDb250YWluZXIgY2hhbmdlZFBhcmVudCwgbG9uZyBjaGFuZ2VGbGFncykgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKworICAgICAgICB0aGlzLmNoYW5nZWQgPSBjaGFuZ2VkOworICAgICAgICB0aGlzLmNoYW5nZWRQYXJlbnQgPSBjaGFuZ2VkUGFyZW50OworICAgICAgICB0aGlzLmNoYW5nZUZsYWcgPSBjaGFuZ2VGbGFnczsKKyAgICB9CisgICAgKi8KKyAgICAvLz8/P0FXVDogRmFrZSBjb25zdHJ1Y3Rvciwgc2hvdWxkIGJlIGFzIGFib3ZlLgorICAgIHB1YmxpYyBIaWVyYXJjaHlFdmVudChDb21wb25lbnQgc291cmNlLCBpbnQgaWQsIENvbXBvbmVudCBjaGFuZ2VkLAorICAgICAgICAgICAgT2JqZWN0IGNoYW5nZWRQYXJlbnQsIGxvbmcgY2hhbmdlRmxhZ3MpIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCk7CisKKy8vICAgICAgICB0aGlzLmNoYW5nZWQgPSBjaGFuZ2VkOworLy8gICAgICAgIHRoaXMuY2hhbmdlZFBhcmVudCA9IGNoYW5nZWRQYXJlbnQ7CisvLyAgICAgICAgdGhpcy5jaGFuZ2VGbGFnID0gY2hhbmdlRmxhZ3M7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBDb21wb25lbnQgZ2V0Q29tcG9uZW50KCkgeworICAgICAgICByZXR1cm4gKENvbXBvbmVudCkgc291cmNlOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldENoYW5nZUZsYWdzKCkgeworICAgICAgICByZXR1cm4gY2hhbmdlRmxhZzsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29tcG9uZW50IGdldENoYW5nZWQoKSB7CisgICAgICAgIHJldHVybiBjaGFuZ2VkOworICAgIH0KKworICAgIC8vPz8/QVdUCisgICAgLyoKKyAgICBwdWJsaWMgQ29udGFpbmVyIGdldENoYW5nZWRQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiBjaGFuZ2VkUGFyZW50OworCisgICAgfQorICAgICovCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHBhcmFtU3RyaW5nKCkgeworICAgICAgICAvKiBUaGUgZm9ybWF0IGlzIGJhc2VkIG9uIDEuNSByZWxlYXNlIGJlaGF2aW9yIAorICAgICAgICAgKiB3aGljaCBjYW4gYmUgcmV2ZWFsZWQgYnkgdGhlIGZvbGxvd2luZyBjb2RlOgorICAgICAgICAgKiAKKyAgICAgICAgICogSGllcmFyY2h5RXZlbnQgZSA9IG5ldyBIaWVyYXJjaHlFdmVudChuZXcgQnV0dG9uKCJCdXR0b24iKSwKKyAgICAgICAgICogICAgICAgICAgSGllcmFyY2h5RXZlbnQuSElFUkFSQ0hZX0NIQU5HRUQsCisgICAgICAgICAqICAgICAgICAgIG5ldyBQYW5lbCgpLCBuZXcgQ29udGFpbmVyKCkpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgcGFyYW1TdHJpbmcgPSBudWxsOworCisgICAgICAgIHN3aXRjaCAoaWQpIHsKKyAgICAgICAgY2FzZSBISUVSQVJDSFlfQ0hBTkdFRDoKKyAgICAgICAgICAgIHBhcmFtU3RyaW5nID0gIkhJRVJBUkNIWV9DSEFOR0VEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQU5DRVNUT1JfTU9WRUQ6CisgICAgICAgICAgICBwYXJhbVN0cmluZyA9ICJBTkNFU1RPUl9NT1ZFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEFOQ0VTVE9SX1JFU0laRUQ6CisgICAgICAgICAgICBwYXJhbVN0cmluZyA9ICJBTkNFU1RPUl9SRVNJWkVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBwYXJhbVN0cmluZyA9ICJ1bmtub3duIHR5cGUiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBwYXJhbVN0cmluZyArPSAiICgiOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgaWYgKGlkID09IEhJRVJBUkNIWV9DSEFOR0VEKSB7CisgICAgICAgICAgICBpZiAoKGNoYW5nZUZsYWcgJiBQQVJFTlRfQ0hBTkdFRCkgPiAwKSB7CisgICAgICAgICAgICAgICAgcGFyYW1TdHJpbmcgKz0gIlBBUkVOVF9DSEFOR0VELCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoY2hhbmdlRmxhZyAmIERJU1BMQVlBQklMSVRZX0NIQU5HRUQpID4gMCkgeworICAgICAgICAgICAgICAgIHBhcmFtU3RyaW5nICs9ICJESVNQTEFZQUJJTElUWV9DSEFOR0VELCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoY2hhbmdlRmxhZyAmIFNIT1dJTkdfQ0hBTkdFRCkgPiAwKSB7CisgICAgICAgICAgICAgICAgcGFyYW1TdHJpbmcgKz0gIlNIT1dJTkdfQ0hBTkdFRCwiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLz8/P0FXVAorICAgICAgICAvKgorICAgICAgICByZXR1cm4gcGFyYW1TdHJpbmcgKyAiY2hhbmdlZD0iICsgY2hhbmdlZCArICAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixjaGFuZ2VkUGFyZW50PSIgKyBjaGFuZ2VkUGFyZW50ICsgIikiOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIHBhcmFtU3RyaW5nOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0hpZXJhcmNoeUxpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvSGllcmFyY2h5TGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjNkOWJjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0hpZXJhcmNoeUxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEhpZXJhcmNoeUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBoaWVyYXJjaHlDaGFuZ2VkKEhpZXJhcmNoeUV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvSW5wdXRFdmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0lucHV0RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDNiN2EzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0lucHV0RXZlbnQuamF2YQpAQCAtMCwwICsxLDE5MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIElucHV0RXZlbnQgZXh0ZW5kcyBDb21wb25lbnRFdmVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjQ4MjUyNTk4MTY5ODMwOTc4Nkw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSElGVF9NQVNLID0gMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENUUkxfTUFTSyA9IDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVRBX01BU0sgPSA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxUX01BU0sgPSA4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxUX0dSQVBIX01BU0sgPSAzMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJVVFRPTjFfTUFTSyA9IDE2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUVE9OMl9NQVNLID0gODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJVVFRPTjNfTUFTSyA9IDQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSElGVF9ET1dOX01BU0sgPSA2NDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENUUkxfRE9XTl9NQVNLID0gMTI4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVUQV9ET1dOX01BU0sgPSAyNTY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTFRfRE9XTl9NQVNLID0gNTEyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUVE9OMV9ET1dOX01BU0sgPSAxMDI0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUVE9OMl9ET1dOX01BU0sgPSAyMDQ4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUVE9OM19ET1dOX01BU0sgPSA0MDk2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxUX0dSQVBIX0RPV05fTUFTSyA9IDgxOTI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRE9XTl9NQVNLUyA9IFNISUZUX0RPV05fTUFTSyB8IENUUkxfRE9XTl9NQVNLIHwKKyAgICAgICAgICAgIE1FVEFfRE9XTl9NQVNLIHwgQUxUX0RPV05fTUFTSyB8IEJVVFRPTjFfRE9XTl9NQVNLIHwKKyAgICAgICAgICAgIEJVVFRPTjJfRE9XTl9NQVNLIHwgQlVUVE9OM19ET1dOX01BU0sgfCBBTFRfR1JBUEhfRE9XTl9NQVNLOworCisgICAgcHJpdmF0ZSBsb25nIHdoZW47CisgICAgcHJpdmF0ZSBpbnQgbW9kaWZpZXJzRXg7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRNb2RpZmllcnNFeFRleHQoaW50IG1vZGlmaWVycy8qRXgqLykgeworICAgICAgICByZXR1cm4gTW91c2VFdmVudC5hZGRNb3VzZU1vZGlmaWVyc0V4VGV4dCgKKyAgICAgICAgICAgICAgICBLZXlFdmVudC5nZXRLZXlNb2RpZmllcnNFeFRleHQobW9kaWZpZXJzKSwgbW9kaWZpZXJzKTsKKyAgICB9CisKKyAgICBzdGF0aWMgaW50IGV4dHJhY3RFeEZsYWdzKGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgaW50IGV4RmxhZ3MgPSBtb2RpZmllcnMgJiBET1dOX01BU0tTOworCisgICAgICAgIGlmICgobW9kaWZpZXJzICYgU0hJRlRfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgZXhGbGFncyB8PSBTSElGVF9ET1dOX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnMgJiBDVFJMX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIGV4RmxhZ3MgfD0gQ1RSTF9ET1dOX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnMgJiBNRVRBX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIGV4RmxhZ3MgfD0gTUVUQV9ET1dOX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnMgJiBBTFRfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgZXhGbGFncyB8PSBBTFRfRE9XTl9NQVNLOworICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQUxUX0dSQVBIX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIGV4RmxhZ3MgfD0gQUxUX0dSQVBIX0RPV05fTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIEJVVFRPTjFfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgZXhGbGFncyB8PSBCVVRUT04xX0RPV05fTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIEJVVFRPTjJfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgZXhGbGFncyB8PSBCVVRUT04yX0RPV05fTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIEJVVFRPTjNfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgZXhGbGFncyB8PSBCVVRUT04zX0RPV05fTUFTSzsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBleEZsYWdzOworICAgIH0KKworICAgIElucHV0RXZlbnQoQ29tcG9uZW50IHNvdXJjZSwgaW50IGlkLCBsb25nIHdoZW4sIGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCk7CisKKyAgICAgICAgdGhpcy53aGVuID0gd2hlbjsKKyAgICAgICAgbW9kaWZpZXJzRXggPSBleHRyYWN0RXhGbGFncyhtb2RpZmllcnMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TW9kaWZpZXJzKCkgeworICAgICAgICBpbnQgbW9kaWZpZXJzID0gMDsKKworICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgU0hJRlRfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICBtb2RpZmllcnMgfD0gU0hJRlRfTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgQ1RSTF9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIG1vZGlmaWVycyB8PSBDVFJMX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnNFeCAmIE1FVEFfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICBtb2RpZmllcnMgfD0gTUVUQV9NQVNLOworICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzRXggJiBBTFRfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICBtb2RpZmllcnMgfD0gQUxUX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnNFeCAmIEFMVF9HUkFQSF9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIG1vZGlmaWVycyB8PSBBTFRfR1JBUEhfTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgQlVUVE9OMV9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIG1vZGlmaWVycyB8PSBCVVRUT04xX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnNFeCAmIEJVVFRPTjJfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICBtb2RpZmllcnMgfD0gQlVUVE9OMl9NQVNLOworICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzRXggJiBCVVRUT04zX0RPV05fTUFTSykgIT0gMCkgeworICAgICAgICAgICAgbW9kaWZpZXJzIHw9IEJVVFRPTjNfTUFTSzsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtb2RpZmllcnM7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNb2RpZmllcnNFeCgpIHsKKyAgICAgICAgcmV0dXJuIG1vZGlmaWVyc0V4OworICAgIH0KKworICAgIHZvaWQgc2V0TW9kaWZpZXJzKGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgbW9kaWZpZXJzRXggPSBleHRyYWN0RXhGbGFncyhtb2RpZmllcnMpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQWx0RG93bigpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzRXggJiBBTFRfRE9XTl9NQVNLKSAhPSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0FsdEdyYXBoRG93bigpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzRXggJiBBTFRfR1JBUEhfRE9XTl9NQVNLKSAhPSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnRyb2xEb3duKCkgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnNFeCAmIENUUkxfRE9XTl9NQVNLKSAhPSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc01ldGFEb3duKCkgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnNFeCAmIE1FVEFfRE9XTl9NQVNLKSAhPSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NoaWZ0RG93bigpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzRXggJiBTSElGVF9ET1dOX01BU0spICE9IDApOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFdoZW4oKSB7CisgICAgICAgIHJldHVybiB3aGVuOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNvbnN1bWUoKSB7CisgICAgICAgIHN1cGVyLmNvbnN1bWUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnN1bWVkKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuaXNDb25zdW1lZCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0lucHV0TWV0aG9kRXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9JbnB1dE1ldGhvZEV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmUwMDFhNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9JbnB1dE1ldGhvZEV2ZW50LmphdmEKQEAgLTAsMCArMSwxNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5BV1RFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0SGl0SW5mbzsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbnB1dE1ldGhvZEV2ZW50IGV4dGVuZHMgQVdURXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDcyNzE5MDg3NDc3ODkyMjY2MUw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlBVVF9NRVRIT0RfRklSU1QgPSAxMTAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5QVVRfTUVUSE9EX1RFWFRfQ0hBTkdFRCA9IDExMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQVJFVF9QT1NJVElPTl9DSEFOR0VEID0gMTEwMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOUFVUX01FVEhPRF9MQVNUID0gMTEwMTsKKworICAgIHByaXZhdGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIHRleHQ7CisgICAgcHJpdmF0ZSBUZXh0SGl0SW5mbyB2aXNpYmxlUG9zaXRpb247CisgICAgcHJpdmF0ZSBUZXh0SGl0SW5mbyBjYXJldDsKKyAgICBwcml2YXRlIGludCBjb21taXR0ZWRDaGFyYWN0ZXJDb3VudDsKKyAgICBwcml2YXRlIGxvbmcgd2hlbjsKKworICAgIHB1YmxpYyBJbnB1dE1ldGhvZEV2ZW50KENvbXBvbmVudCBzcmMsIGludCBpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mbyBjYXJldCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8gdmlzaWJsZVBvcykgeworICAgICAgICB0aGlzKHNyYywgaWQsIG51bGwsIDAsIGNhcmV0LCB2aXNpYmxlUG9zKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSW5wdXRNZXRob2RFdmVudChDb21wb25lbnQgc3JjLCBpbnQgaWQsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb21taXRlZENoYXJDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mbyBjYXJldCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8gdmlzaWJsZVBvcykgeworICAgICAgICB0aGlzKHNyYywgaWQsIDBsLCB0ZXh0LCBjb21taXRlZENoYXJDb3VudCwgY2FyZXQsIHZpc2libGVQb3MpOworICAgIH0KKworICAgIHB1YmxpYyBJbnB1dE1ldGhvZEV2ZW50KENvbXBvbmVudCBzcmMsIGludCBpZCwgbG9uZyB3aGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29tbWl0dGVkQ2hhcmFjdGVyQ291bnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8gY2FyZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8gdmlzaWJsZVBvcykgeworICAgICAgICBzdXBlcihzcmMsIGlkKTsKKworICAgICAgICBpZiAoKGlkIDwgSU5QVVRfTUVUSE9EX0ZJUlNUKSB8fCAoaWQgPiBJTlBVVF9NRVRIT0RfTEFTVCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xOEU9V3JvbmcgZXZlbnQgaWQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMThFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKChpZCA9PSBDQVJFVF9QT1NJVElPTl9DSEFOR0VEKSAmJiAodGV4dCAhPSBudWxsKSkgeworICAgICAgICAgICAgLy8gYXd0LjE4Rj1UZXh0IG11c3QgYmUgbnVsbCBmb3IgQ0FSRVRfUE9TSVRJT05fQ0hBTkdFRAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOEYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoKHRleHQgIT0gbnVsbCkgJiYKKyAgICAgICAgICAgICAgICAoKGNvbW1pdHRlZENoYXJhY3RlckNvdW50IDwgMCkgfHwKKyAgICAgICAgICAgICAgICAgKGNvbW1pdHRlZENoYXJhY3RlckNvdW50ID4gCisgICAgICAgICAgICAgICAgICAgICAgICAodGV4dC5nZXRFbmRJbmRleCgpIC0gdGV4dC5nZXRCZWdpbkluZGV4KCkpKSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xOTA9V3JvbmcgY29tbWl0dGVkQ2hhcmFjdGVyQ291bnQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTkwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICB0aGlzLndoZW4gPSB3aGVuOworICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OworICAgICAgICB0aGlzLmNhcmV0ID0gY2FyZXQ7CisgICAgICAgIHRoaXMudmlzaWJsZVBvc2l0aW9uID0gdmlzaWJsZVBvczsKKyAgICAgICAgdGhpcy5jb21taXR0ZWRDaGFyYWN0ZXJDb3VudCA9IGNvbW1pdHRlZENoYXJhY3RlckNvdW50OworICAgIH0KKworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXRDYXJldCgpIHsKKyAgICAgICAgcmV0dXJuIGNhcmV0OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Q29tbWl0dGVkQ2hhcmFjdGVyQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjb21taXR0ZWRDaGFyYWN0ZXJDb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGdldFRleHQoKSB7CisgICAgICAgIHJldHVybiB0ZXh0OworICAgIH0KKworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXRWaXNpYmxlUG9zaXRpb24oKSB7CisgICAgICAgIHJldHVybiB2aXNpYmxlUG9zaXRpb247CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0V2hlbigpIHsKKyAgICAgICAgcmV0dXJuIHdoZW47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY29uc3VtZSgpIHsKKyAgICAgICAgc3VwZXIuY29uc3VtZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29uc3VtZWQoKSB7CisgICAgICAgIHJldHVybiBzdXBlci5pc0NvbnN1bWVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciAKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICogCisgICAgICAgICAqIElucHV0TWV0aG9kRXZlbnQgZSA9IG5ldyBJbnB1dE1ldGhvZEV2ZW50KG5ldyBDb21wb25lbnQoKXt9LAorICAgICAgICAgKiAgICAgICAgICBJbnB1dE1ldGhvZEV2ZW50LklOUFVUX01FVEhPRF9URVhUX0NIQU5HRUQsCisgICAgICAgICAqICAgICAgICAgIFRleHRIaXRJbmZvLmxlYWRpbmcoMSksIFRleHRIaXRJbmZvLnRyYWlsaW5nKDIpKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nIHR5cGVTdHJpbmcgPSBudWxsOworCisgICAgICAgIHN3aXRjaCAoaWQpIHsKKyAgICAgICAgY2FzZSBJTlBVVF9NRVRIT0RfVEVYVF9DSEFOR0VEOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJJTlBVVF9NRVRIT0RfVEVYVF9DSEFOR0VEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQ0FSRVRfUE9TSVRJT05fQ0hBTkdFRDoKKyAgICAgICAgICAgIHR5cGVTdHJpbmcgPSAiQ0FSRVRfUE9TSVRJT05fQ0hBTkdFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJ1bmtub3duIHR5cGUiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHlwZVN0cmluZyArICIsdGV4dD0iICsgdGV4dCArICAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixjb21taXRlZENoYXJDb3VudD0iICsgY29tbWl0dGVkQ2hhcmFjdGVyQ291bnQgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixjYXJldD0iICsgY2FyZXQgKyAiLHZpc2libGVQb3NpdGlvbj0iICsgdmlzaWJsZVBvc2l0aW9uOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9JbnB1dE1ldGhvZExpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvSW5wdXRNZXRob2RMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1ZWFhN2UKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvSW5wdXRNZXRob2RMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJbnB1dE1ldGhvZExpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBjYXJldFBvc2l0aW9uQ2hhbmdlZChJbnB1dE1ldGhvZEV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgaW5wdXRNZXRob2RUZXh0Q2hhbmdlZChJbnB1dE1ldGhvZEV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvSW52b2NhdGlvbkV2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvSW52b2NhdGlvbkV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNThlM2I3MgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9JbnZvY2F0aW9uRXZlbnQuamF2YQpAQCAtMCwwICsxLDEzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0LkFjdGl2ZUV2ZW50OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZvY2F0aW9uRXZlbnQgZXh0ZW5kcyBBV1RFdmVudCBpbXBsZW1lbnRzIEFjdGl2ZUV2ZW50IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQzNjA1NjM0NDkwOTQ1OTQ1MEw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlZPQ0FUSU9OX0ZJUlNUID0gMTIwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVk9DQVRJT05fREVGQVVMVCA9IDEyMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlZPQ0FUSU9OX0xBU1QgPSAxMjAwOworCisgICAgcHJvdGVjdGVkIFJ1bm5hYmxlIHJ1bm5hYmxlOworCisgICAgcHJvdGVjdGVkIE9iamVjdCBub3RpZmllcjsKKworICAgIHByb3RlY3RlZCBib29sZWFuIGNhdGNoRXhjZXB0aW9uczsKKworICAgIHByaXZhdGUgbG9uZyB3aGVuOworICAgIHByaXZhdGUgVGhyb3dhYmxlIHRocm93YWJsZTsKKworICAgIHB1YmxpYyBJbnZvY2F0aW9uRXZlbnQoT2JqZWN0IHNvdXJjZSwgUnVubmFibGUgcnVubmFibGUpIHsKKyAgICAgICAgdGhpcyhzb3VyY2UsIHJ1bm5hYmxlLCBudWxsLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIEludm9jYXRpb25FdmVudChPYmplY3Qgc291cmNlLCBSdW5uYWJsZSBydW5uYWJsZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qgbm90aWZpZXIsIGJvb2xlYW4gY2F0Y2hFeGNlcHRpb25zKSB7CisgICAgICAgIHRoaXMoc291cmNlLCBJTlZPQ0FUSU9OX0RFRkFVTFQsIHJ1bm5hYmxlLCBub3RpZmllciwgY2F0Y2hFeGNlcHRpb25zKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSW52b2NhdGlvbkV2ZW50KE9iamVjdCBzb3VyY2UsIGludCBpZCwgUnVubmFibGUgcnVubmFibGUsCisgICAgICAgICAgICBPYmplY3Qgbm90aWZpZXIsIGJvb2xlYW4gY2F0Y2hFeGNlcHRpb25zKQorICAgIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCk7CisKKyAgICAgICAgLy8gYXd0LjE4Qz1DYW5ub3QgaW52b2tlIG51bGwgcnVubmFibGUKKyAgICAgICAgYXNzZXJ0IHJ1bm5hYmxlICE9IG51bGwgOiBNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOEMiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjE4RD1Tb3VyY2UgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOEQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnJ1bm5hYmxlID0gcnVubmFibGU7CisgICAgICAgIHRoaXMubm90aWZpZXIgPSBub3RpZmllcjsKKyAgICAgICAgdGhpcy5jYXRjaEV4Y2VwdGlvbnMgPSBjYXRjaEV4Y2VwdGlvbnM7CisKKyAgICAgICAgdGhyb3dhYmxlID0gbnVsbDsKKyAgICAgICAgd2hlbiA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoKCkgeworICAgICAgICBpZiAoIWNhdGNoRXhjZXB0aW9ucykgeworICAgICAgICAgICAgcnVuQW5kTm90aWZ5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJ1bkFuZE5vdGlmeSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvd2FibGUgPSB0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJ1bkFuZE5vdGlmeSgpIHsKKyAgICAgICAgaWYgKG5vdGlmaWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZChub3RpZmllcikgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJ1bm5hYmxlLnJ1bigpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIG5vdGlmaWVyLm5vdGlmeUFsbCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJ1bm5hYmxlLnJ1bigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiAodGhyb3dhYmxlICE9IG51bGwgJiYgdGhyb3dhYmxlIGluc3RhbmNlb2YgRXhjZXB0aW9uKSA/CisgICAgICAgICAgICAgICAgKEV4Y2VwdGlvbil0aHJvd2FibGUgOiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0VGhyb3dhYmxlKCkgeworICAgICAgICByZXR1cm4gdGhyb3dhYmxlOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFdoZW4oKSB7CisgICAgICAgIHJldHVybiB3aGVuOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBJbnZvY2F0aW9uRXZlbnQgZSA9IG5ldyBJbnZvY2F0aW9uRXZlbnQobmV3IENvbXBvbmVudCgpe30sCisgICAgICAgICAqICAgICAgIG5ldyBSdW5uYWJsZSgpIHsgcHVibGljIHZvaWQgcnVuKCl7fSB9KTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICByZXR1cm4gKChpZCA9PSBJTlZPQ0FUSU9OX0RFRkFVTFQgPyAiSU5WT0NBVElPTl9ERUZBVUxUIiA6ICJ1bmtub3duIHR5cGUiKSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIscnVubmFibGU9IiArIHJ1bm5hYmxlICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsbm90aWZpZXI9IiArIG5vdGlmaWVyICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsY2F0Y2hFeGNlcHRpb25zPSIgKyBjYXRjaEV4Y2VwdGlvbnMgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIix3aGVuPSIgKyB3aGVuKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0l0ZW1FdmVudC5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L0l0ZW1FdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5OTA4ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvSXRlbUV2ZW50LmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0Lkl0ZW1TZWxlY3RhYmxlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSXRlbUV2ZW50IGV4dGVuZHMgQVdURXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTYwODcwODEzMjQ0NzIwNjkzM0w7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJVEVNX0ZJUlNUID0gNzAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVRFTV9MQVNUID0gNzAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVRFTV9TVEFURV9DSEFOR0VEID0gNzAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VMRUNURUQgPSAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTRUxFQ1RFRCA9IDI7CisKKyAgICBwcml2YXRlIE9iamVjdCBpdGVtOworICAgIHByaXZhdGUgaW50IHN0YXRlQ2hhbmdlOworCisgICAgcHVibGljIEl0ZW1FdmVudChJdGVtU2VsZWN0YWJsZSBzb3VyY2UsIGludCBpZCwgT2JqZWN0IGl0ZW0sIGludCBzdGF0ZUNoYW5nZSkgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKworICAgICAgICB0aGlzLml0ZW0gPSBpdGVtOworICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlID0gc3RhdGVDaGFuZ2U7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRJdGVtKCkgeworICAgICAgICByZXR1cm4gaXRlbTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN0YXRlQ2hhbmdlKCkgeworICAgICAgICByZXR1cm4gc3RhdGVDaGFuZ2U7CisgICAgfQorCisgICAgcHVibGljIEl0ZW1TZWxlY3RhYmxlIGdldEl0ZW1TZWxlY3RhYmxlKCkgeworICAgICAgICByZXR1cm4gKEl0ZW1TZWxlY3RhYmxlKSBzb3VyY2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciAKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICogCisgICAgICAgICAqIENoZWNrYm94IGMgPSBuZXcgQ2hlY2tib3goIkNoZWNrYm94IiwgdHJ1ZSk7CisgICAgICAgICAqIEl0ZW1FdmVudCBlID0gbmV3IEl0ZW1FdmVudChjLCBJdGVtRXZlbnQuSVRFTV9TVEFURV9DSEFOR0VELCAKKyAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMsIEl0ZW1FdmVudC5TRUxFQ1RFRCk7CisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKKyAgICAgICAgICovCisKKyAgICAgICAgU3RyaW5nIHN0YXRlU3RyaW5nID0gbnVsbDsKKworICAgICAgICBzd2l0Y2ggKHN0YXRlQ2hhbmdlKSB7CisgICAgICAgIGNhc2UgU0VMRUNURUQ6CisgICAgICAgICAgICBzdGF0ZVN0cmluZyA9ICJTRUxFQ1RFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIERFU0VMRUNURUQ6CisgICAgICAgICAgICBzdGF0ZVN0cmluZyA9ICJERVNFTEVDVEVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBzdGF0ZVN0cmluZyA9ICJ1bmtub3duIHR5cGUiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKChpZCA9PSBJVEVNX1NUQVRFX0NIQU5HRUQgPyAiSVRFTV9TVEFURV9DSEFOR0VEIiA6ICJ1bmtub3duIHR5cGUiKSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICIsaXRlbT0iICsgaXRlbSArICIsc3RhdGVDaGFuZ2U9IiArIHN0YXRlU3RyaW5nKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvSXRlbUxpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvSXRlbUxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGRlYzY3MwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9JdGVtTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSXRlbUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBpdGVtU3RhdGVDaGFuZ2VkKEl0ZW1FdmVudCBlKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0tleUFkYXB0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9LZXlBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk2Y2NhOAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9LZXlBZGFwdGVyLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEtleUFkYXB0ZXIgaW1wbGVtZW50cyBLZXlMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgS2V5QWRhcHRlcigpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBrZXlSZWxlYXNlZChLZXlFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQga2V5VHlwZWQoS2V5RXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0tleUV2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvS2V5RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjI3ZjcwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0tleUV2ZW50LmphdmEKQEAgLTAsMCArMSw2ODcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CitpbXBvcnQgamF2YS5hd3QuVG9vbGtpdDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgS2V5RXZlbnQgZXh0ZW5kcyBJbnB1dEV2ZW50IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMzUyMTMwOTUzMDI4MTI2OTU0TDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9GSVJTVCA9IDQwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9MQVNUID0gNDAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VZX1RZUEVEID0gNDAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VZX1BSRVNTRUQgPSA0MDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLRVlfUkVMRUFTRUQgPSA0MDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19FTlRFUiA9IDEwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQkFDS19TUEFDRSA9IDg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19UQUIgPSA5OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQ0FOQ0VMID0gMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NMRUFSID0gMTI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19TSElGVCA9IDE2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQ09OVFJPTCA9IDE3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQUxUID0gMTg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19QQVVTRSA9IDE5OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQ0FQU19MT0NLID0gMjA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19FU0NBUEUgPSAyNzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1NQQUNFID0gMzI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19QQUdFX1VQID0gMzM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19QQUdFX0RPV04gPSAzNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0VORCA9IDM1OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSE9NRSA9IDM2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTEVGVCA9IDM3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfVVAgPSAzODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1JJR0hUID0gMzk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ET1dOID0gNDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19DT01NQSA9IDQ0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTUlOVVMgPSA0NTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1BFUklPRCA9IDQ2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfU0xBU0ggPSA0NzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzAgPSA0ODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzEgPSA0OTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzIgPSA1MDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzMgPSA1MTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzQgPSA1MjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzUgPSA1MzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzYgPSA1NDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzcgPSA1NTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzggPSA1NjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLXzkgPSA1NzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1NFTUlDT0xPTiA9IDU5OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRVFVQUxTID0gNjE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19BID0gNjU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19CID0gNjY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19DID0gNjc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19EID0gNjg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19FID0gNjk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GID0gNzA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19HID0gNzE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19IID0gNzI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19JID0gNzM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19KID0gNzQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19LID0gNzU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19MID0gNzY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19NID0gNzc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19OID0gNzg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19PID0gNzk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19QID0gODA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19RID0gODE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19SID0gODI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19TID0gODM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19UID0gODQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19VID0gODU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19WID0gODY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19XID0gODc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19YID0gODg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ZID0gODk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19aID0gOTA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19PUEVOX0JSQUNLRVQgPSA5MTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0JBQ0tfU0xBU0ggPSA5MjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NMT1NFX0JSQUNLRVQgPSA5MzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDAgPSA5NjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDEgPSA5NzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDIgPSA5ODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDMgPSA5OTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDQgPSAxMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19OVU1QQUQ1ID0gMTAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTlVNUEFENiA9IDEwMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTVBBRDcgPSAxMDM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19OVU1QQUQ4ID0gMTA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTlVNUEFEOSA9IDEwNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX01VTFRJUExZID0gMTA2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQUREID0gMTA3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfU0VQQVJBVEVSID0gMTA4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfU0VQQVJBVE9SID0gMTA4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfU1VCVFJBQ1QgPSAxMDk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUNJTUFMID0gMTEwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRElWSURFID0gMTExOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfREVMRVRFID0gMTI3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTlVNX0xPQ0sgPSAxNDQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19TQ1JPTExfTE9DSyA9IDE0NTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxID0gMTEyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjIgPSAxMTM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GMyA9IDExNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0Y0ID0gMTE1OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjUgPSAxMTY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GNiA9IDExNzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0Y3ID0gMTE4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjggPSAxMTk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GOSA9IDEyMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxMCA9IDEyMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxMSA9IDEyMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxMiA9IDEyMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxMyA9IDYxNDQwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjE0ID0gNjE0NDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GMTUgPSA2MTQ0MjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxNiA9IDYxNDQzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjE3ID0gNjE0NDQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GMTggPSA2MTQ0NTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YxOSA9IDYxNDQ2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjIwID0gNjE0NDc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GMjEgPSA2MTQ0ODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0YyMiA9IDYxNDQ5OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfRjIzID0gNjE0NTA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GMjQgPSA2MTQ1MTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1BSSU5UU0NSRUVOID0gMTU0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSU5TRVJUID0gMTU1OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSEVMUCA9IDE1NjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX01FVEEgPSAxNTc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19CQUNLX1FVT1RFID0gMTkyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfUVVPVEUgPSAyMjI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19LUF9VUCA9IDIyNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0tQX0RPV04gPSAyMjU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19LUF9MRUZUID0gMjI2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfS1BfUklHSFQgPSAyMjc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX0dSQVZFID0gMTI4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfREVBRF9BQ1VURSA9IDEyOTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RFQURfQ0lSQ1VNRkxFWCA9IDEzMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RFQURfVElMREUgPSAxMzE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX01BQ1JPTiA9IDEzMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RFQURfQlJFVkUgPSAxMzM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX0FCT1ZFRE9UID0gMTM0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfREVBRF9ESUFFUkVTSVMgPSAxMzU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX0FCT1ZFUklORyA9IDEzNjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RFQURfRE9VQkxFQUNVVEUgPSAxMzc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX0NBUk9OID0gMTM4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfREVBRF9DRURJTExBID0gMTM5OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfREVBRF9PR09ORUsgPSAxNDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX0lPVEEgPSAxNDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19ERUFEX1ZPSUNFRF9TT1VORCA9IDE0MjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RFQURfU0VNSVZPSUNFRF9TT1VORCA9IDE0MzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0FNUEVSU0FORCA9IDE1MDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0FTVEVSSVNLID0gMTUxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfUVVPVEVEQkwgPSAxNTI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19MRVNTID0gMTUzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfR1JFQVRFUiA9IDE2MDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0JSQUNFTEVGVCA9IDE2MTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0JSQUNFUklHSFQgPSAxNjI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19BVCA9IDUxMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NPTE9OID0gNTEzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQ0lSQ1VNRkxFWCA9IDUxNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0RPTExBUiA9IDUxNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0VVUk9fU0lHTiA9IDUxNjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0VYQ0xBTUFUSU9OX01BUksgPSA1MTc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19JTlZFUlRFRF9FWENMQU1BVElPTl9NQVJLID0gNTE4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTEVGVF9QQVJFTlRIRVNJUyA9IDUxOTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05VTUJFUl9TSUdOID0gNTIwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfUExVUyA9IDUyMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1JJR0hUX1BBUkVOVEhFU0lTID0gNTIyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfVU5ERVJTQ09SRSA9IDUyMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0ZJTkFMID0gMjQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19XSU5ET1dTID0gNTI0OyAKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NPTlRFWFRfTUVOVSA9IDUyNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NPTlZFUlQgPSAyODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX05PTkNPTlZFUlQgPSAyOTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0FDQ0VQVCA9IDMwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfTU9ERUNIQU5HRSA9IDMxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfS0FOQSA9IDIxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfS0FOSkkgPSAyNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0FMUEhBTlVNRVJJQyA9IDI0MDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0tBVEFLQU5BID0gMjQxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSElSQUdBTkEgPSAyNDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19GVUxMX1dJRFRIID0gMjQzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSEFMRl9XSURUSCA9IDI0NDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1JPTUFOX0NIQVJBQ1RFUlMgPSAyNDU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19BTExfQ0FORElEQVRFUyA9IDI1NjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1BSRVZJT1VTX0NBTkRJREFURSA9IDI1NzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0NPREVfSU5QVVQgPSAyNTg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19KQVBBTkVTRV9LQVRBS0FOQSA9IDI1OTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0pBUEFORVNFX0hJUkFHQU5BID0gMjYwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfSkFQQU5FU0VfUk9NQU4gPSAyNjE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19LQU5BX0xPQ0sgPSAyNjI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19JTlBVVF9NRVRIT0RfT05fT0ZGID0gMjYzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQ1VUID0gNjU0ODk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19DT1BZID0gNjU0ODU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19QQVNURSA9IDY1NDg3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfVU5ETyA9IDY1NDgzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVktfQUdBSU4gPSA2NTQ4MTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0ZJTkQgPSA2NTQ4ODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX1BST1BTID0gNjU0ODI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19TVE9QID0gNjU0ODA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19DT01QT1NFID0gNjUzMTI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19BTFRfR1JBUEggPSA2NTQwNjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZLX0JFR0lOID0gNjUzNjg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWS19VTkRFRklORUQgPSAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIENIQVJfVU5ERUZJTkVEID0gKGNoYXIpKC0xKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9MT0NBVElPTl9VTktOT1dOID0gMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWV9MT0NBVElPTl9TVEFOREFSRCA9IDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLRVlfTE9DQVRJT05fTEVGVCA9IDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLRVlfTE9DQVRJT05fUklHSFQgPSAzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0xPQ0FUSU9OX05VTVBBRCA9IDQ7CisKKyAgICBwcml2YXRlIGludCBrZXlDb2RlOworICAgIHByaXZhdGUgY2hhciBrZXlDaGFyOworICAgIHByaXZhdGUgaW50IGtleUxvY2F0aW9uOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0S2V5TW9kaWZpZXJzVGV4dChpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHJldHVybiBnZXRLZXlNb2RpZmllcnNFeFRleHQoZXh0cmFjdEV4RmxhZ3MobW9kaWZpZXJzKSk7CisgICAgfQorCisgICAgc3RhdGljIFN0cmluZyBnZXRLZXlNb2RpZmllcnNFeFRleHQoaW50IG1vZGlmaWVyc0V4KSB7CisgICAgICAgIFN0cmluZyB0ZXh0ID0gIiI7IC8vJE5PTi1OTFMtMSQKKworICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgSW5wdXRFdmVudC5NRVRBX0RPV05fTUFTSykgIT0gMCkgeworICAgICAgICAgICAgdGV4dCArPSBUb29sa2l0LmdldFByb3BlcnR5KCJBV1QubWV0YSIsICJNZXRhIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzRXggJiBJbnB1dEV2ZW50LkNUUkxfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0ICs9ICgodGV4dC5sZW5ndGgoKSA+IDApID8gIisiIDogIiIpICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgICAgIFRvb2xraXQuZ2V0UHJvcGVydHkoIkFXVC5jb250cm9sIiwgIkN0cmwiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0KKyAgICAgICAgaWYgKChtb2RpZmllcnNFeCAmIElucHV0RXZlbnQuQUxUX0RPV05fTUFTSykgIT0gMCkgeworICAgICAgICAgICAgdGV4dCArPSAoKHRleHQubGVuZ3RoKCkgPiAwKSA/ICIrIiA6ICIiKSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICAgICBUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYWx0IiwgIkFsdCIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgSW5wdXRFdmVudC5TSElGVF9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIHRleHQgKz0gKCh0ZXh0Lmxlbmd0aCgpID4gMCkgPyAiKyIgOiAiIikgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAgICAgVG9vbGtpdC5nZXRQcm9wZXJ0eSgiQVdULnNoaWZ0IiwgIlNoaWZ0Iik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzRXggJiBJbnB1dEV2ZW50LkFMVF9HUkFQSF9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIHRleHQgKz0gKCh0ZXh0Lmxlbmd0aCgpID4gMCkgPyAiKyIgOiAiIikgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAgICAgVG9vbGtpdC5nZXRQcm9wZXJ0eSgiQVdULmFsdEdyYXBoIiwgIkFsdCBHcmFwaCIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0ZXh0OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEtleVRleHQoaW50IGtleUNvZGUpIHsKKyAgICAgICAgU3RyaW5nW10gcmF3TmFtZSA9IGdldFB1YmxpY1N0YXRpY0ZpbmFsSW50RmllbGROYW1lKGtleUNvZGUpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgaWYgKChyYXdOYW1lID09IG51bGwpIHx8IChyYXdOYW1lLmxlbmd0aCA9PSAwKSkgeworICAgICAgICAgICAgcmV0dXJuICgiVW5rbm93biBrZXlDb2RlOiAiICsgKGtleUNvZGUgPj0gMCA/ICIweCIgOiAiLTB4IikgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvSGV4U3RyaW5nKE1hdGguYWJzKGtleUNvZGUpKSk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcHJvcGVydHlOYW1lID0gZ2V0UHJvcGVydHlOYW1lKHJhd05hbWUpOworICAgICAgICBTdHJpbmcgZGVmYXVsdE5hbWUgPSBnZXREZWZhdWx0TmFtZShyYXdOYW1lKTsKKworICAgICAgICByZXR1cm4gVG9vbGtpdC5nZXRQcm9wZXJ0eShwcm9wZXJ0eU5hbWUsIGRlZmF1bHROYW1lKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0RGVmYXVsdE5hbWUoU3RyaW5nW10gcmF3TmFtZSkgeworICAgICAgICBTdHJpbmcgbmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IHRydWU7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHBhcnQgPSByYXdOYW1lW2ldOworCisgICAgICAgICAgICBuYW1lICs9IG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7cGFydC5jaGFyQXQoMCl9KS50b1VwcGVyQ2FzZSgpICsKKyAgICAgICAgICAgICAgICAgICAgcGFydC5zdWJzdHJpbmcoMSkudG9Mb3dlckNhc2UoKTsKKworICAgICAgICAgICAgaWYgKGkgPT0gKHJhd05hbWUubGVuZ3RoIC0gMSkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5hbWUgKz0gIiAiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0UHJvcGVydHlOYW1lKFN0cmluZ1tdIHJhd05hbWUpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSByYXdOYW1lWzBdLnRvTG93ZXJDYXNlKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCByYXdOYW1lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgcGFydCA9IHJhd05hbWVbaV07CisKKyAgICAgICAgICAgIG5hbWUgKz0gbmV3IFN0cmluZyhuZXcgY2hhcltdIHtwYXJ0LmNoYXJBdCgwKX0pLnRvVXBwZXJDYXNlKCkgKworICAgICAgICAgICAgICAgICAgICBwYXJ0LnN1YnN0cmluZygxKS50b0xvd2VyQ2FzZSgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuICgiQVdULiIgKyBuYW1lKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldFB1YmxpY1N0YXRpY0ZpbmFsSW50RmllbGROYW1lKGludCB2YWx1ZSkgeworICAgICAgICBGaWVsZFtdIGFsbEZpZWxkcyA9IEtleUV2ZW50LmNsYXNzLmdldERlY2xhcmVkRmllbGRzKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBhbGxGaWVsZHMpIHsKKyAgICAgICAgICAgICAgICBDbGFzczw/PiBzc2FsYyA9IGZpZWxkLmdldFR5cGUoKTsKKyAgICAgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gZmllbGQuZ2V0TW9kaWZpZXJzKCk7CisKKyAgICAgICAgICAgICAgICBpZiAoc3NhbGMuaXNQcmltaXRpdmUoKSAmJiBzc2FsYy5nZXROYW1lKCkuZXF1YWxzKCJpbnQiKSAmJiAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllci5pc0ZpbmFsKG1vZGlmaWVycykgJiYgTW9kaWZpZXIuaXNQdWJsaWMobW9kaWZpZXJzKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZXIuaXNTdGF0aWMobW9kaWZpZXJzKSkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZC5nZXRJbnQobnVsbCkgPT0gdmFsdWUpeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBmaWVsZC5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcHJlZml4TGVuZ3RoID0gbmFtZS5pbmRleE9mKCJfIikgKyAxOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKHByZWZpeExlbmd0aCkuc3BsaXQoIl8iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBLZXlFdmVudChDb21wb25lbnQgc3JjLCBpbnQgaWQsCisgICAgICAgICAgICAgICAgICAgIGxvbmcgd2hlbiwgaW50IG1vZGlmaWVycywKKyAgICAgICAgICAgICAgICAgICAgaW50IGtleUNvZGUpIHsKKyAgICAgICAgdGhpcyhzcmMsIGlkLCB3aGVuLCBtb2RpZmllcnMsIGtleUNvZGUsCisgICAgICAgICAgICAgICAgKGtleUNvZGUgPiAoMiA8PCA3KSAtIDEpID8gQ0hBUl9VTkRFRklORUQgOiAoY2hhcikga2V5Q29kZSk7CisgICAgfQorCisgICAgcHVibGljIEtleUV2ZW50KENvbXBvbmVudCBzcmMsIGludCBpZCwKKyAgICAgICAgICAgICAgICAgICAgbG9uZyB3aGVuLCBpbnQgbW9kaWZpZXJzLAorICAgICAgICAgICAgICAgICAgICBpbnQga2V5Q29kZSwgY2hhciBrZXlDaGFyKSB7CisgICAgICAgIHRoaXMoc3JjLCBpZCwgd2hlbiwgbW9kaWZpZXJzLCBrZXlDb2RlLCBrZXlDaGFyLCBLRVlfTE9DQVRJT05fVU5LTk9XTik7CisgICAgfQorCisgICAgcHVibGljIEtleUV2ZW50KENvbXBvbmVudCBzcmMsIGludCBpZCwKKyAgICAgICAgICAgICAgICAgICAgbG9uZyB3aGVuLCBpbnQgbW9kaWZpZXJzLAorICAgICAgICAgICAgICAgICAgICBpbnQga2V5Q29kZSwgY2hhciBrZXlDaGFyLAorICAgICAgICAgICAgICAgICAgICBpbnQga2V5TG9jYXRpb24pIHsKKyAgICAgICAgc3VwZXIoc3JjLCBpZCwgd2hlbiwgbW9kaWZpZXJzKTsKKworICAgICAgICBpZiAoaWQgPT0gS0VZX1RZUEVEKSB7CisgICAgICAgICAgICBpZiAoa2V5Q29kZSAhPSBWS19VTkRFRklORUQpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTkxPUludmFsaWQga2V5Q29kZSBmb3IgS0VZX1RZUEVEIGV2ZW50LCBtdXN0IGJlIFZLX1VOREVGSU5FRAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTkxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoa2V5Q2hhciA9PSBDSEFSX1VOREVGSU5FRCkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4xOTI9SW52YWxpZCBrZXlDaGFyIGZvciBLRVlfVFlQRUQgZXZlbnQsIGNhbid0IGJlIENIQVJfVU5ERUZJTkVECisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaWYgKChrZXlMb2NhdGlvbiA8IEtFWV9MT0NBVElPTl9VTktOT1dOKQorICAgICAgICAgICAgICAgIHx8IChrZXlMb2NhdGlvbiA+IEtFWV9MT0NBVElPTl9OVU1QQUQpKSB7CisgICAgICAgICAgICAvLyBhd3QuMjk3PUludmFsaWQga2V5TG9jYXRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjk3IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICB0aGlzLmtleUNoYXIgPSBrZXlDaGFyOworICAgICAgICB0aGlzLmtleUxvY2F0aW9uID0ga2V5TG9jYXRpb247CisgICAgICAgIHRoaXMua2V5Q29kZSA9IGtleUNvZGU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRLZXlDb2RlKCkgeworICAgICAgICByZXR1cm4ga2V5Q29kZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRLZXlDb2RlKGludCBrZXlDb2RlKSB7CisgICAgICAgIHRoaXMua2V5Q29kZSA9IGtleUNvZGU7CisgICAgfQorCisgICAgcHVibGljIGNoYXIgZ2V0S2V5Q2hhcigpIHsKKyAgICAgICAgcmV0dXJuIGtleUNoYXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0S2V5Q2hhcihjaGFyIGtleUNoYXIpIHsKKyAgICAgICAgdGhpcy5rZXlDaGFyID0ga2V5Q2hhcjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEtleUxvY2F0aW9uKCkgeworICAgICAgICByZXR1cm4ga2V5TG9jYXRpb247CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRNb2RpZmllcnMoaW50IG1vZGlmaWVycykgeworICAgICAgICBzdXBlci5zZXRNb2RpZmllcnMobW9kaWZpZXJzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0FjdGlvbktleSgpIHsKKyAgICAgICAgcmV0dXJuICgoa2V5Q2hhciA9PSBDSEFSX1VOREVGSU5FRCkgJiYgKGtleUNvZGUgIT0gVktfVU5ERUZJTkVEKSAmJgorICAgICAgICAgICAgICAgICEoKGtleUNvZGUgPT0gVktfQUxUKSB8fCAoa2V5Q29kZSA9PSBWS19BTFRfR1JBUEgpIHx8CisgICAgICAgICAgICAgICAgICAgIChrZXlDb2RlID09IFZLX0NPTlRST0wpIHx8IChrZXlDb2RlID09IFZLX01FVEEpIHx8IChrZXlDb2RlID09IFZLX1NISUZUKSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICoKKyAgICAgICAgICogS2V5RXZlbnQgZSA9IG5ldyBLZXlFdmVudChuZXcgQ29tcG9uZW50KCkge30sIAorICAgICAgICAgKiAgICAgICBLZXlFdmVudC5LRVlfUFJFU1NFRCwgMCwgCisgICAgICAgICAqICAgICAgIEtleUV2ZW50LkNUUkxfRE9XTl9NQVNLfEtleUV2ZW50LlNISUZUX0RPV05fTUFTSywgCisgICAgICAgICAqICAgICAgIEtleUV2ZW50LlZLX0EsICdBJywgS2V5RXZlbnQuS0VZX0xPQ0FUSU9OX1NUQU5EQVJEKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICBTdHJpbmcgaWRTdHJpbmcgPSBudWxsOworICAgICAgICBTdHJpbmcgbG9jU3RyaW5nID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIHBhcmFtU3RyaW5nID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIGtleUNoYXJTdHJpbmcgPSAoa2V5Q2hhciA9PSAnXG4nKSA/CisgICAgICAgICAgICAgICAga2V5Q2hhclN0cmluZyA9IGdldEtleVRleHQoVktfRU5URVIpIDogIiciICsga2V5Q2hhciArICInIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisKKyAgICAgICAgc3dpdGNoIChpZCkgeworICAgICAgICBjYXNlIEtFWV9QUkVTU0VEOgorICAgICAgICAgICAgaWRTdHJpbmcgPSAiS0VZX1BSRVNTRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBLRVlfUkVMRUFTRUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJLRVlfUkVMRUFTRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBLRVlfVFlQRUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJLRVlfVFlQRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gInVua25vd24gdHlwZSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaChrZXlMb2NhdGlvbil7CisgICAgICAgIGNhc2UgS0VZX0xPQ0FUSU9OX1NUQU5EQVJEOgorICAgICAgICAgICAgbG9jU3RyaW5nID0gIktFWV9MT0NBVElPTl9TVEFOREFSRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEtFWV9MT0NBVElPTl9MRUZUOgorICAgICAgICAgICAgbG9jU3RyaW5nID0gIktFWV9MT0NBVElPTl9MRUZUIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgS0VZX0xPQ0FUSU9OX1JJR0hUOgorICAgICAgICAgICAgbG9jU3RyaW5nID0gIktFWV9MT0NBVElPTl9SSUdIVCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEtFWV9MT0NBVElPTl9OVU1QQUQ6CisgICAgICAgICAgICBsb2NTdHJpbmcgPSAiS0VZX0xPQ0FUSU9OX05VTVBBRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEtFWV9MT0NBVElPTl9VTktOT1dOOgorICAgICAgICAgICAgbG9jU3RyaW5nID0gIktFWV9MT0NBVElPTl9VTktOT1dOIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBsb2NTdHJpbmcgPSAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcGFyYW1TdHJpbmcgPSBpZFN0cmluZyArICIsa2V5Q29kZT0iICsga2V5Q29kZTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBpZiAoaXNBY3Rpb25LZXkoKSkgeworICAgICAgICAgICAgcGFyYW1TdHJpbmcgKz0gIiwiICsgZ2V0S2V5VGV4dChrZXlDb2RlKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcGFyYW1TdHJpbmcgKz0gIixrZXlDaGFyPSIgKyBrZXlDaGFyU3RyaW5nOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKGdldE1vZGlmaWVyc0V4KCkgPiAwKSB7CisgICAgICAgICAgICBwYXJhbVN0cmluZyArPSAiLG1vZGlmaWVycz0iICsgZ2V0TW9kaWZpZXJzRXhUZXh0KGdldE1vZGlmaWVyc0V4KCkpICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAiLGV4dE1vZGlmaWVycz0iICsgZ2V0TW9kaWZpZXJzRXhUZXh0KGdldE1vZGlmaWVyc0V4KCkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcGFyYW1TdHJpbmcgKz0gIixrZXlMb2NhdGlvbj0iICsgbG9jU3RyaW5nOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgcmV0dXJuIHBhcmFtU3RyaW5nOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L0tleUxpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvS2V5TGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzE0NGRmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L0tleUxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEtleUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQga2V5UmVsZWFzZWQoS2V5RXZlbnQgZSk7CisKKyAgICBwdWJsaWMgdm9pZCBrZXlUeXBlZChLZXlFdmVudCBlKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L01vdXNlQWRhcHRlci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L01vdXNlQWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjMTkxNzMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VBZGFwdGVyLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1vdXNlQWRhcHRlciBpbXBsZW1lbnRzIE1vdXNlTGlzdGVuZXIgeworCisgICAgcHVibGljIE1vdXNlQWRhcHRlcigpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtb3VzZUNsaWNrZWQoTW91c2VFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbW91c2VFbnRlcmVkKE1vdXNlRXZlbnQgZSkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG1vdXNlRXhpdGVkKE1vdXNlRXZlbnQgZSkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG1vdXNlUHJlc3NlZChNb3VzZUV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtb3VzZVJlbGVhc2VkKE1vdXNlRXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L01vdXNlRXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZUV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmIxZmE4YgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZUV2ZW50LmphdmEKQEAgLTAsMCArMSwyMzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CitpbXBvcnQgamF2YS5hd3QuUG9pbnQ7CitpbXBvcnQgamF2YS5hd3QuVG9vbGtpdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgTW91c2VFdmVudCBleHRlbmRzIElucHV0RXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTk5MTIxNDE1MzQ5NDg0Mjg0OEw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9GSVJTVCA9IDUwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PVVNFX0xBU1QgPSA1MDc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9DTElDS0VEID0gNTAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9VU0VfUFJFU1NFRCA9IDUwMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PVVNFX1JFTEVBU0VEID0gNTAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9VU0VfTU9WRUQgPSA1MDM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT1VTRV9FTlRFUkVEID0gNTA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9VU0VfRVhJVEVEID0gNTA1OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9VU0VfRFJBR0dFRCA9IDUwNjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PVVNFX1dIRUVMID0gNTA3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9CVVRUT04gPSAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUVE9OMSA9IDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCVVRUT04yID0gMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJVVFRPTjMgPSAzOworCisgICAgcHJpdmF0ZSBib29sZWFuIHBvcHVwVHJpZ2dlcjsKKyAgICBwcml2YXRlIGludCBjbGlja0NvdW50OworICAgIHByaXZhdGUgaW50IGJ1dHRvbjsKKyAgICBwcml2YXRlIGludCB4OworICAgIHByaXZhdGUgaW50IHk7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRNb3VzZU1vZGlmaWVyc1RleHQoaW50IG1vZGlmaWVycykgeworICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgdGV4dCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBpZiAoKG1vZGlmaWVycyAmIE1FVEFfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgdGV4dC5hcHBlbmQoVG9vbGtpdC5nZXRQcm9wZXJ0eSgiQVdULm1ldGEiLCAiTWV0YSIpKS5hcHBlbmQoIisiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIFNISUZUX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIHRleHQuYXBwZW5kKFRvb2xraXQuZ2V0UHJvcGVydHkoIkFXVC5zaGlmdCIsICJTaGlmdCIpKS5hcHBlbmQoIisiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIENUUkxfTUFTSykgIT0gMCkgeworICAgICAgICAgICAgdGV4dC5hcHBlbmQoVG9vbGtpdC5nZXRQcm9wZXJ0eSgiQVdULmNvbnRyb2wiLCAiQ3RybCIpKS5hcHBlbmQoIisiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIEFMVF9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYWx0IiwgIkFsdCIpKS5hcHBlbmQoIisiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVycyAmIEFMVF9HUkFQSF9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYWx0R3JhcGgiLCAiQWx0IEdyYXBoIikpLmFwcGVuZCgiKyIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQlVUVE9OMV9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYnV0dG9uMSIsICJCdXR0b24xIikpLmFwcGVuZCgiKyIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQlVUVE9OMl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYnV0dG9uMiIsICJCdXR0b24yIikpLmFwcGVuZCgiKyIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzICYgQlVUVE9OM19NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYnV0dG9uMyIsICJCdXR0b24zIikpLmFwcGVuZCgiKyIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRleHQubGVuZ3RoKCkgPT0gMCA/IHRleHQudG9TdHJpbmcoKSA6IHRleHQuc3Vic3RyaW5nKDAsIHRleHQKKyAgICAgICAgICAgICAgICAubGVuZ3RoKCkgLSAxKTsKKyAgICB9CisKKyAgICBzdGF0aWMgU3RyaW5nIGFkZE1vdXNlTW9kaWZpZXJzRXhUZXh0KFN0cmluZyB0ZXh0LCBpbnQgbW9kaWZpZXJzRXgpIHsKKyAgICAgICAgaWYgKChtb2RpZmllcnNFeCAmIElucHV0RXZlbnQuQlVUVE9OMV9ET1dOX01BU0spICE9IDApIHsKKyAgICAgICAgICAgIHRleHQgKz0gKCh0ZXh0Lmxlbmd0aCgpID4gMCkgPyAiKyIgOiAiIikgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICAgICAgVG9vbGtpdC5nZXRQcm9wZXJ0eSgiQVdULmJ1dHRvbjEiLCAiQnV0dG9uMSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1vZGlmaWVyc0V4ICYgSW5wdXRFdmVudC5CVVRUT04yX0RPV05fTUFTSykgIT0gMCkgeworICAgICAgICAgICAgdGV4dCArPSAoKHRleHQubGVuZ3RoKCkgPiAwKSA/ICIrIiA6ICIiKSArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICAgICBUb29sa2l0LmdldFByb3BlcnR5KCJBV1QuYnV0dG9uMiIsICJCdXR0b24yIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGlmICgobW9kaWZpZXJzRXggJiBJbnB1dEV2ZW50LkJVVFRPTjNfRE9XTl9NQVNLKSAhPSAwKSB7CisgICAgICAgICAgICB0ZXh0ICs9ICgodGV4dC5sZW5ndGgoKSA+IDApID8gIisiIDogIiIpICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgICAgIFRvb2xraXQuZ2V0UHJvcGVydHkoIkFXVC5idXR0b24zIiwgIkJ1dHRvbjMiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdGV4dDsKKyAgICB9CisKKyAgICBwdWJsaWMgTW91c2VFdmVudChDb21wb25lbnQgc291cmNlLCBpbnQgaWQsIGxvbmcgd2hlbiwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgbW9kaWZpZXJzLCBpbnQgeCwgaW50IHksCisgICAgICAgICAgICAgICAgICAgICAgaW50IGNsaWNrQ291bnQsIGJvb2xlYW4gcG9wdXBUcmlnZ2VyKSB7CisgICAgICAgIHRoaXMoc291cmNlLCBpZCwgd2hlbiwgbW9kaWZpZXJzLCB4LCB5LAorICAgICAgICAgICAgIGNsaWNrQ291bnQsIHBvcHVwVHJpZ2dlciwgTk9CVVRUT04pOworICAgIH0KKworICAgIHB1YmxpYyBNb3VzZUV2ZW50KENvbXBvbmVudCBzb3VyY2UsIGludCBpZCwgbG9uZyB3aGVuLAorICAgICAgICAgICAgICAgICAgICAgIGludCBtb2RpZmllcnMsIGludCB4LCBpbnQgeSwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgY2xpY2tDb3VudCwgYm9vbGVhbiBwb3B1cFRyaWdnZXIsIGludCBidXR0b24pIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCwgd2hlbiwgbW9kaWZpZXJzKTsKKworICAgICAgICBpZiAoKGJ1dHRvbiAhPSBOT0JVVFRPTikgJiYgKGJ1dHRvbiAhPSBCVVRUT04xKSAmJgorICAgICAgICAgICAgICAgIChidXR0b24gIT0gQlVUVE9OMikgJiYgKGJ1dHRvbiAhPSBCVVRUT04zKSkgeworICAgICAgICAgICAgLy8gYXd0LjE4Qj1JbnZhbGlkIGJ1dHRvbiB2YWx1ZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMucG9wdXBUcmlnZ2VyID0gcG9wdXBUcmlnZ2VyOworICAgICAgICB0aGlzLmNsaWNrQ291bnQgPSBjbGlja0NvdW50OworICAgICAgICB0aGlzLmJ1dHRvbiA9IGJ1dHRvbjsKKyAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgdGhpcy55ID0geTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEJ1dHRvbigpIHsKKyAgICAgICAgcmV0dXJuIGJ1dHRvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENsaWNrQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjbGlja0NvdW50OworICAgIH0KKworICAgIHB1YmxpYyBQb2ludCBnZXRQb2ludCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQb2ludCh4LCB5KTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFgoKSB7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0WSgpIHsKKyAgICAgICAgcmV0dXJuIHk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQb3B1cFRyaWdnZXIoKSB7CisgICAgICAgIHJldHVybiBwb3B1cFRyaWdnZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlUG9pbnQoaW50IHgsIGludCB5KSB7CisgICAgICAgIHRoaXMueCArPSB4OworICAgICAgICB0aGlzLnkgKz0geTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHBhcmFtU3RyaW5nKCkgeworICAgICAgICAvKiBUaGUgZm9ybWF0IGlzIGJhc2VkIG9uIDEuNSByZWxlYXNlIGJlaGF2aW9yIAorICAgICAgICAgKiB3aGljaCBjYW4gYmUgcmV2ZWFsZWQgYnkgdGhlIGZvbGxvd2luZyBjb2RlOgorICAgICAgICAgKiAKKyAgICAgICAgICogTW91c2VFdmVudCBlID0gbmV3IE1vdXNlRXZlbnQobmV3IENvbXBvbmVudCgpe30sIAorICAgICAgICAgKiAgICAgICAgICBNb3VzZUV2ZW50Lk1PVVNFX1BSRVNTRUQsIDAsIAorICAgICAgICAgKiAgICAgICAgICBNb3VzZUV2ZW50LkJVVFRPTjFfRE9XTl9NQVNLfE1vdXNlRXZlbnQuQ1RSTF9ET1dOX01BU0ssCisgICAgICAgICAqICAgICAgICAgIDEwLCAyMCwgMSwgZmFsc2UsIE1vdXNlRXZlbnQuQlVUVE9OMSk7CisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKKyAgICAgICAgICovCisKKyAgICAgICAgU3RyaW5nIGlkU3RyaW5nID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIHBhcmFtU3RyaW5nID0gbnVsbDsKKworICAgICAgICBzd2l0Y2ggKGlkKSB7CisgICAgICAgIGNhc2UgTU9VU0VfTU9WRUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJNT1VTRV9NT1ZFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE1PVVNFX0NMSUNLRUQ6CisgICAgICAgICAgICBpZFN0cmluZyA9ICJNT1VTRV9DTElDS0VEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTU9VU0VfUFJFU1NFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIk1PVVNFX1BSRVNTRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBNT1VTRV9SRUxFQVNFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIk1PVVNFX1JFTEVBU0VEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTU9VU0VfRFJBR0dFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIk1PVVNFX0RSQUdHRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBNT1VTRV9FTlRFUkVEOgorICAgICAgICAgICAgaWRTdHJpbmcgPSAiTU9VU0VfRU5URVJFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE1PVVNFX0VYSVRFRDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gIk1PVVNFX0VYSVRFRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE1PVVNFX1dIRUVMOgorICAgICAgICAgICAgaWRTdHJpbmcgPSAiTU9VU0VfV0hFRUwiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGlkU3RyaW5nID0gInVua25vd24gdHlwZSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtU3RyaW5nID0gaWRTdHJpbmcgKyAiLCgiICsgZ2V0WCgpICsgIiwiICsgZ2V0WSgpICsgIikiICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgICAgICAgICAiLGJ1dHRvbj0iICsgYnV0dG9uOyAvLyROT04tTkxTLTEkCisgICAgICAgIGlmIChnZXRNb2RpZmllcnNFeCgpID4gMCkgeworICAgICAgICAgICAgcGFyYW1TdHJpbmcgKz0gCisgICAgICAgICAgICAgICAgICAgICIsbW9kaWZpZXJzPSIgKyBnZXRNb2RpZmllcnNFeFRleHQoZ2V0TW9kaWZpZXJzRXgoKSkgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICIsZXh0TW9kaWZpZXJzPSIgKyBnZXRNb2RpZmllcnNFeFRleHQoZ2V0TW9kaWZpZXJzRXgoKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBwYXJhbVN0cmluZyArPSAiLGNsaWNrQ291bnQ9IiArIGdldENsaWNrQ291bnQoKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIHJldHVybiBwYXJhbVN0cmluZzsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZUxpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1ODc5YjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBNb3VzZUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCBtb3VzZUNsaWNrZWQoTW91c2VFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIG1vdXNlRW50ZXJlZChNb3VzZUV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgbW91c2VFeGl0ZWQoTW91c2VFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIG1vdXNlUHJlc3NlZChNb3VzZUV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgbW91c2VSZWxlYXNlZChNb3VzZUV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VNb3Rpb25BZGFwdGVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VNb3Rpb25BZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWVjZDBkNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZU1vdGlvbkFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTW91c2VNb3Rpb25BZGFwdGVyIGltcGxlbWVudHMgTW91c2VNb3Rpb25MaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgTW91c2VNb3Rpb25BZGFwdGVyKCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG1vdXNlRHJhZ2dlZChNb3VzZUV2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtb3VzZU1vdmVkKE1vdXNlRXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L01vdXNlTW90aW9uTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZU1vdGlvbkxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTEzMTNjMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZU1vdGlvbkxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIE1vdXNlTW90aW9uTGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIG1vdXNlRHJhZ2dlZChNb3VzZUV2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgbW91c2VNb3ZlZChNb3VzZUV2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VXaGVlbEV2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvTW91c2VXaGVlbEV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTNlZDQyNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZVdoZWVsRXZlbnQuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIE1vdXNlV2hlZWxFdmVudCBleHRlbmRzIE1vdXNlRXZlbnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTkxODc0MTM1ODE5OTM1NjM5MjlMOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0hFRUxfVU5JVF9TQ1JPTEwgPSAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0hFRUxfQkxPQ0tfU0NST0xMID0gMTsKKworICAgIHByaXZhdGUgaW50IHdoZWVsUm90YXRpb247CisgICAgcHJpdmF0ZSBpbnQgc2Nyb2xsQW1vdW50OworICAgIHByaXZhdGUgaW50IHNjcm9sbFR5cGU7CisKKyAgICBwdWJsaWMgTW91c2VXaGVlbEV2ZW50KENvbXBvbmVudCBzb3VyY2UsIGludCBpZCwgbG9uZyB3aGVuLCBpbnQgbW9kaWZpZXJzLAorICAgICAgICAgICAgaW50IHgsIGludCB5LCBpbnQgY2xpY2tDb3VudCwgYm9vbGVhbiBwb3B1cFRyaWdnZXIsIGludCBzY3JvbGxUeXBlLAorICAgICAgICAgICAgaW50IHNjcm9sbEFtb3VudCwgaW50IHdoZWVsUm90YXRpb24pIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBpZCwgd2hlbiwgbW9kaWZpZXJzLCB4LCB5LCBjbGlja0NvdW50LCBwb3B1cFRyaWdnZXIpOworCisgICAgICAgIHRoaXMuc2Nyb2xsVHlwZSA9IHNjcm9sbFR5cGU7CisgICAgICAgIHRoaXMuc2Nyb2xsQW1vdW50ID0gc2Nyb2xsQW1vdW50OworICAgICAgICB0aGlzLndoZWVsUm90YXRpb24gPSB3aGVlbFJvdGF0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U2Nyb2xsQW1vdW50KCkgeworICAgICAgICByZXR1cm4gc2Nyb2xsQW1vdW50OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U2Nyb2xsVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHNjcm9sbFR5cGU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRXaGVlbFJvdGF0aW9uKCkgeworICAgICAgICByZXR1cm4gd2hlZWxSb3RhdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFVuaXRzVG9TY3JvbGwoKSB7CisgICAgICAgIHJldHVybiAoc2Nyb2xsQW1vdW50ICogd2hlZWxSb3RhdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBwYXJhbVN0cmluZygpIHsKKyAgICAgICAgLyogVGhlIGZvcm1hdCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciAKKyAgICAgICAgICogd2hpY2ggY2FuIGJlIHJldmVhbGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZToKKyAgICAgICAgICogCisgICAgICAgICAqIE1vdXNlV2hlZWxFdmVudCBlID0gbmV3IE1vdXNlV2hlZWxFdmVudChuZXcgQ29tcG9uZW50KCl7fSwgCisgICAgICAgICAqICAgICAgICAgIE1vdXNlV2hlZWxFdmVudC5NT1VTRV9XSEVFTCwgMCwgCisgICAgICAgICAqICAgICAgICAgIE1vdXNlRXZlbnQuQlVUVE9OMV9ET1dOX01BU0t8TW91c2VFdmVudC5DVFJMX0RPV05fTUFTSywKKyAgICAgICAgICogICAgICAgICAgMTAsIDIwLCAxLCBmYWxzZSwgTW91c2VXaGVlbEV2ZW50LldIRUVMX1VOSVRfU0NST0xMLAorICAgICAgICAgKiAgICAgICAgICAxLCAzKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgKi8KKworICAgICAgICBTdHJpbmcgcGFyYW1TdHJpbmcgPSBzdXBlci5wYXJhbVN0cmluZygpOworICAgICAgICBTdHJpbmcgdHlwZVN0cmluZyA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChzY3JvbGxUeXBlKSB7CisgICAgICAgIGNhc2UgV0hFRUxfVU5JVF9TQ1JPTEw6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gIldIRUVMX1VOSVRfU0NST0xMIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0hFRUxfQkxPQ0tfU0NST0xMOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSEVFTF9CTE9DS19TQ1JPTEwiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHR5cGVTdHJpbmcgPSAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcGFyYW1TdHJpbmcgKz0gIixzY3JvbGxUeXBlPSIgKyB0eXBlU3RyaW5nICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsc2Nyb2xsQW1vdW50PSIgKyBzY3JvbGxBbW91bnQgKyAgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsd2hlZWxSb3RhdGlvbj0iICsgd2hlZWxSb3RhdGlvbjsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIHJldHVybiBwYXJhbVN0cmluZzsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZVdoZWVsTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9Nb3VzZVdoZWVsTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDZhOTgyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L01vdXNlV2hlZWxMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBNb3VzZVdoZWVsTGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIG1vdXNlV2hlZWxNb3ZlZChNb3VzZVdoZWVsRXZlbnQgZSk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9QYWludEV2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvUGFpbnRFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyYWMwOTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvUGFpbnRFdmVudC5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUGFpbnRFdmVudCBleHRlbmRzIENvbXBvbmVudEV2ZW50IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDEyNjc0OTIwMjY0MzMzMzc1OTNMOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFJTlRfRklSU1QgPSA4MDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUlOVF9MQVNUID0gODAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFJTlQgPSA4MDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVUERBVEUgPSA4MDE7CisKKyAgICBwcml2YXRlIFJlY3RhbmdsZSB1cGRhdGVSZWN0OworCisgICAgcHVibGljIFBhaW50RXZlbnQoQ29tcG9uZW50IHNvdXJjZSwgaW50IGlkLCBSZWN0YW5nbGUgdXBkYXRlUmVjdCkgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKworICAgICAgICB0aGlzLnVwZGF0ZVJlY3QgPSB1cGRhdGVSZWN0OworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0VXBkYXRlUmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIHVwZGF0ZVJlY3Q7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VXBkYXRlUmVjdChSZWN0YW5nbGUgdXBkYXRlUmVjdCkgeworICAgICAgICB0aGlzLnVwZGF0ZVJlY3QgPSB1cGRhdGVSZWN0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBQYWludEV2ZW50IGUgPSBuZXcgUGFpbnRFdmVudChuZXcgQ29tcG9uZW50KCl7fSwgCisgICAgICAgICAqICAgICAgICAgIFBhaW50RXZlbnQuUEFJTlQsIG5ldyBSZWN0YW5nbGUoMCwgMCwgMTAsIDIwKSk7IAorICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyB0eXBlU3RyaW5nID0gbnVsbDsKKworICAgICAgICBzd2l0Y2ggKGlkKSB7CisgICAgICAgIGNhc2UgUEFJTlQ6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gIlBBSU5UIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVVBEQVRFOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJVUERBVEUiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHR5cGVTdHJpbmcgPSAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHR5cGVTdHJpbmcgKyAiLHVwZGF0ZVJlY3Q9IiArIHVwZGF0ZVJlY3Q7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9ldmVudC9UZXh0RXZlbnQuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9UZXh0RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTY5MGFkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L1RleHRFdmVudC5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5BV1RFdmVudDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFRleHRFdmVudCBleHRlbmRzIEFXVEV2ZW50IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYyNjk5MDIyOTEyNTA5NDExNzlMOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVYVF9GSVJTVCA9IDkwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFWFRfTEFTVCA9IDkwMDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFWFRfVkFMVUVfQ0hBTkdFRCA9IDkwMDsKKworICAgIHB1YmxpYyBUZXh0RXZlbnQoT2JqZWN0IHNyYywgaW50IGlkKSB7CisgICAgICAgIHN1cGVyKHNyYywgaWQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBUZXh0RXZlbnQgZSA9IG5ldyBUZXh0RXZlbnQobmV3IENvbXBvbmVudCgpe30sIAorICAgICAgICAgKiAgICAgICAgICBUZXh0RXZlbnQuVEVYVF9WQUxVRV9DSEFOR0VEKTsgCisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKKyAgICAgICAgICovCisKKyAgICAgICAgcmV0dXJuIChpZCA9PSBURVhUX1ZBTFVFX0NIQU5HRUQpID8gCisgICAgICAgICAgICAgICAgIlRFWFRfVkFMVUVfQ0hBTkdFRCIgOiAidW5rbm93biB0eXBlIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvVGV4dExpc3RlbmVyLmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvVGV4dExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDU3NTdjNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9UZXh0TGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgVGV4dExpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXh0VmFsdWVDaGFuZ2VkKFRleHRFdmVudCBlKTsKKworfQorCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvV2luZG93QWRhcHRlci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd0FkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NzBhYThkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd0FkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgV2luZG93QWRhcHRlciBpbXBsZW1lbnRzIFdpbmRvd0xpc3RlbmVyLCBXaW5kb3dTdGF0ZUxpc3RlbmVyLCBXaW5kb3dGb2N1c0xpc3RlbmVyIHsKKworICAgIHB1YmxpYyBXaW5kb3dBZGFwdGVyKCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0FjdGl2YXRlZChXaW5kb3dFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd2luZG93Q2xvc2VkKFdpbmRvd0V2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3aW5kb3dDbG9zaW5nKFdpbmRvd0V2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3aW5kb3dEZWFjdGl2YXRlZChXaW5kb3dFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd2luZG93RGVpY29uaWZpZWQoV2luZG93RXZlbnQgZSkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0dhaW5lZEZvY3VzKFdpbmRvd0V2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3aW5kb3dJY29uaWZpZWQoV2luZG93RXZlbnQgZSkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0xvc3RGb2N1cyhXaW5kb3dFdmVudCBlKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd2luZG93T3BlbmVkKFdpbmRvd0V2ZW50IGUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3aW5kb3dTdGF0ZUNoYW5nZWQoV2luZG93RXZlbnQgZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd0V2ZW50LmphdmEgYi9hd3QvamF2YS9hd3QvZXZlbnQvV2luZG93RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzRkMmFjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd0V2ZW50LmphdmEKQEAgLTAsMCArMSwxNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWljaGFlbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZXZlbnQ7CisKKworLy8/Pz9BV1QKKy8vaW1wb3J0IGphdmEuYXd0LldpbmRvdzsKKy8vaW1wb3J0IGphdmEuYXd0LkZyYW1lOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgV2luZG93RXZlbnQgZXh0ZW5kcyBDb21wb25lbnRFdmVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTU2Nzk1OTEzMzE0NzkxMjEyN0w7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfRklSU1QgPSAyMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfT1BFTkVEID0gMjAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORE9XX0NMT1NJTkcgPSAyMDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfQ0xPU0VEID0gMjAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORE9XX0lDT05JRklFRCA9IDIwMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdJTkRPV19ERUlDT05JRklFRCA9IDIwNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdJTkRPV19BQ1RJVkFURUQgPSAyMDU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfREVBQ1RJVkFURUQgPSAyMDY7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfR0FJTkVEX0ZPQ1VTID0gMjA3OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORE9XX0xPU1RfRk9DVVMgPSAyMDg7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5ET1dfU1RBVEVfQ0hBTkdFRCA9IDIwOTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdJTkRPV19MQVNUID0gMjA5OworCisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgV2luZG93IG9wcG9zaXRlV2luZG93OworICAgIHByaXZhdGUgaW50IG9sZFN0YXRlOworICAgIHByaXZhdGUgaW50IG5ld1N0YXRlOworCisgICAgLy8/Pz9BV1QKKyAgICAvKgorICAgIHB1YmxpYyBXaW5kb3dFdmVudChXaW5kb3cgc291cmNlLCBpbnQgaWQpIHsKKyAgICAgICAgdGhpcyhzb3VyY2UsIGlkLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgV2luZG93RXZlbnQoV2luZG93IHNvdXJjZSwgaW50IGlkLCBXaW5kb3cgb3Bwb3NpdGUpIHsKKyAgICAgICAgdGhpcyhzb3VyY2UsIGlkLCBvcHBvc2l0ZSwgRnJhbWUuTk9STUFMLCBGcmFtZS5OT1JNQUwpOworICAgIH0KKworICAgIHB1YmxpYyBXaW5kb3dFdmVudChXaW5kb3cgc291cmNlLCBpbnQgaWQsIGludCBvbGRTdGF0ZSwgaW50IG5ld1N0YXRlKSB7CisgICAgICAgIHRoaXMoc291cmNlLCBpZCwgbnVsbCwgb2xkU3RhdGUsIG5ld1N0YXRlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgV2luZG93RXZlbnQoV2luZG93IHNvdXJjZSwgaW50IGlkLCBXaW5kb3cgb3Bwb3NpdGUsIAorICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2xkU3RhdGUsIGludCBuZXdTdGF0ZSkgeworICAgICAgICBzdXBlcihzb3VyY2UsIGlkKTsKKworICAgICAgICBvcHBvc2l0ZVdpbmRvdyA9IG9wcG9zaXRlOworICAgICAgICB0aGlzLm9sZFN0YXRlID0gb2xkU3RhdGU7CisgICAgICAgIHRoaXMubmV3U3RhdGUgPSBuZXdTdGF0ZTsKKyAgICB9CisgICAgKi8KKyAgICAvLz8/P0FXVDogRmFrZSBjb25zdHJ1Y3RvcgorICAgIHB1YmxpYyBXaW5kb3dFdmVudCgpIHsKKyAgICAgICAgc3VwZXIobnVsbCwgMCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBpbnQgZ2V0TmV3U3RhdGUoKSB7CisgICAgICAgIHJldHVybiBuZXdTdGF0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE9sZFN0YXRlKCkgeworICAgICAgICByZXR1cm4gb2xkU3RhdGU7CisgICAgfQorCisgICAgLy8/Pz9BV1QKKyAgICAvKgorICAgIHB1YmxpYyBXaW5kb3cgZ2V0T3Bwb3NpdGVXaW5kb3coKSB7CisgICAgICAgIHJldHVybiBvcHBvc2l0ZVdpbmRvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgV2luZG93IGdldFdpbmRvdygpIHsKKyAgICAgICAgcmV0dXJuIChXaW5kb3cpIHNvdXJjZTsKKyAgICB9CisgICAgKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcGFyYW1TdHJpbmcoKSB7CisgICAgICAgIC8qIFRoZSBmb3JtYXQgaXMgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IgCisgICAgICAgICAqIHdoaWNoIGNhbiBiZSByZXZlYWxlZCBieSB0aGUgZm9sbG93aW5nIGNvZGU6CisgICAgICAgICAqIAorICAgICAgICAgKiBXaW5kb3dFdmVudCBlID0gbmV3IFdpbmRvd0V2ZW50KG5ldyBGcmFtZSgpLCAKKyAgICAgICAgICogICAgICAgICAgV2luZG93RXZlbnQuV0lORE9XX09QRU5FRCk7IAorICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyB0eXBlU3RyaW5nID0gbnVsbDsKKworICAgICAgICBzd2l0Y2ggKGlkKSB7CisgICAgICAgIGNhc2UgV0lORE9XX09QRU5FRDoKKyAgICAgICAgICAgIHR5cGVTdHJpbmcgPSAiV0lORE9XX09QRU5FRCI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFdJTkRPV19DTE9TSU5HOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfQ0xPU0lORyI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFdJTkRPV19DTE9TRUQ6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gIldJTkRPV19DTE9TRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBXSU5ET1dfSUNPTklGSUVEOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfSUNPTklGSUVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0lORE9XX0RFSUNPTklGSUVEOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfREVJQ09OSUZJRUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBXSU5ET1dfQUNUSVZBVEVEOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfQUNUSVZBVEVEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0lORE9XX0RFQUNUSVZBVEVEOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfREVBQ1RJVkFURUQiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBXSU5ET1dfR0FJTkVEX0ZPQ1VTOgorICAgICAgICAgICAgdHlwZVN0cmluZyA9ICJXSU5ET1dfR0FJTkVEX0ZPQ1VTIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0lORE9XX0xPU1RfRk9DVVM6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gIldJTkRPV19MT1NUX0ZPQ1VTIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0lORE9XX1NUQVRFX0NIQU5HRUQ6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gIldJTkRPV19TVEFURV9DSEFOR0VEIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gInVua25vd24gdHlwZSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIHJldHVybiB0eXBlU3RyaW5nICsgIixvcHBvc2l0ZT0iICsgb3Bwb3NpdGVXaW5kb3cgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixvbGRTdGF0ZT0iICsgb2xkU3RhdGUgKyAiLG5ld1N0YXRlPSIgKyBuZXdTdGF0ZTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICovCisgICAgICAgIHJldHVybiB0eXBlU3RyaW5nOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd0ZvY3VzTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9XaW5kb3dGb2N1c0xpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTI4NDU5ZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9ldmVudC9XaW5kb3dGb2N1c0xpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWNoYWVsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFdpbmRvd0ZvY3VzTGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0dhaW5lZEZvY3VzKFdpbmRvd0V2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgd2luZG93TG9zdEZvY3VzKFdpbmRvd0V2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvV2luZG93TGlzdGVuZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9ldmVudC9XaW5kb3dMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxYmQ1NDcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZXZlbnQvV2luZG93TGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgV2luZG93TGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0FjdGl2YXRlZChXaW5kb3dFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NlZChXaW5kb3dFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NpbmcoV2luZG93RXZlbnQgZSk7CisKKyAgICBwdWJsaWMgdm9pZCB3aW5kb3dEZWFjdGl2YXRlZChXaW5kb3dFdmVudCBlKTsKKworICAgIHB1YmxpYyB2b2lkIHdpbmRvd0RlaWNvbmlmaWVkKFdpbmRvd0V2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgd2luZG93SWNvbmlmaWVkKFdpbmRvd0V2ZW50IGUpOworCisgICAgcHVibGljIHZvaWQgd2luZG93T3BlbmVkKFdpbmRvd0V2ZW50IGUpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZXZlbnQvV2luZG93U3RhdGVMaXN0ZW5lci5qYXZhIGIvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd1N0YXRlTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTE0ZDllCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2V2ZW50L1dpbmRvd1N0YXRlTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgV2luZG93U3RhdGVMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgcHVibGljIHZvaWQgd2luZG93U3RhdGVDaGFuZ2VkKFdpbmRvd0V2ZW50IGUpOworCit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L0ZvbnRSZW5kZXJDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvZm9udC9Gb250UmVuZGVyQ29udGV4dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3ZGUwMGYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZm9udC9Gb250UmVuZGVyQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsMTc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworCisvKioKKyAqIFRoZSBGb250UmVuZGVyQ29udGV4dCBjbGFzcyBjb250YWlucyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGV4dCBtZWFzdXJlbWVudC4KKyAqIEFudGktYWxpYXNpbmcgYW5kIGZyYWN0aW9uYWwtbWV0cmljcyBtb2RlcyBhcmUgZGVmaW5lZCBieSBhbiBhcHBsaWNhdGlvbiBhbmQKKyAqIGFmZmVjdCB0aGUgc2l6ZSBvZiBhIGNoYXJhY3Rlci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBGb250UmVuZGVyQ29udGV4dCB7CisKKyAgICAvLyBBZmZpbmUgdHJhbnNmb3JtIG9mIHRoaXMgbW9kZQorICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2Zvcm0uCisgICAgICovCisgICAgcHJpdmF0ZSBBZmZpbmVUcmFuc2Zvcm0gdHJhbnNmb3JtOworCisgICAgLy8gSXMgdGhlIGFudGktYWxpYXNlZCBtb2RlIHVzZWQKKyAgICAvKioKKyAgICAgKiBUaGUgYW50aSBhbGlhc2VkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmQW50aUFsaWFzZWQ7CisKKyAgICAvLyBJcyB0aGUgZnJhY3Rpb25hbCBtZXRyaWNzIHVzZWQKKyAgICAvKioKKyAgICAgKiBUaGUgZnJhY3Rpb25hbCBtZXRyaWNzLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmRnJhY3Rpb25hbE1ldHJpY3M7CisKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGb250UmVuZGVyQ29udGV4dCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogQWZmaW5lVHJhbnNmb3JtLCBhbnRpLWFsaWFzaW5nIGFuZCBmcmFjdGlvbmFsIG1ldHJpY3MgZmxhZ3MuCisgICAgICogCisgICAgICogQHBhcmFtIHRyYW5zCisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBhbnRpQWxpYXNlZAorICAgICAqICAgICAgICAgICAgdGhlIGFudGktYWxpYXNpbmcgZmxhZy4KKyAgICAgKiBAcGFyYW0gdXNlc0ZyYWN0aW9uYWxNZXRyaWNzCisgICAgICogICAgICAgICAgICB0aGUgZnJhY3Rpb25hbCBtZXRyaWNzIGZsYWcuCisgICAgICovCisgICAgcHVibGljIEZvbnRSZW5kZXJDb250ZXh0KEFmZmluZVRyYW5zZm9ybSB0cmFucywgYm9vbGVhbiBhbnRpQWxpYXNlZCwgCisgICAgICAgICAgICBib29sZWFuIHVzZXNGcmFjdGlvbmFsTWV0cmljcykgeworICAgICAgICBpZiAodHJhbnMgIT0gbnVsbCl7CisgICAgICAgICAgICB0cmFuc2Zvcm0gPSBuZXcgQWZmaW5lVHJhbnNmb3JtKHRyYW5zKTsKKyAgICAgICAgfQorICAgICAgICBmQW50aUFsaWFzZWQgPSBhbnRpQWxpYXNlZDsKKyAgICAgICAgZkZyYWN0aW9uYWxNZXRyaWNzID0gdXNlc0ZyYWN0aW9uYWxNZXRyaWNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGb250UmVuZGVyQ29udGV4dCBvYmplY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIEZvbnRSZW5kZXJDb250ZXh0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgT2JqZWN0IHdpdGggY3VycmVudCBGb250UmVuZGVyQ29udGV4dCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGlzIGVxdWFsIHRvIGN1cnJlbnQKKyAgICAgKiAgICAgICAgIEZvbnRSZW5kZXJDb250ZXh0IG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG9iaiAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKEZvbnRSZW5kZXJDb250ZXh0KSBvYmopOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHJhbnNmb3JtIHdoaWNoIGlzIHVzZWQgZm9yIHNjYWxpbmcgdHlwb2dyYXBoaWNhbCBwb2ludHMgdG8KKyAgICAgKiBwaXhlbHMgaW4gdGhpcyBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBBZmZpbmVUcmFuc2Zvcm0gd2hpY2ggaXMgdXNlZCBmb3Igc2NhbGluZyB0eXBvZ3JhcGhpY2FsCisgICAgICogICAgICAgICBwb2ludHMgdG8gcGl4ZWxzIGluIHRoaXMgRm9udFJlbmRlckNvbnRleHQuCisgICAgICovCisgICAgcHVibGljIEFmZmluZVRyYW5zZm9ybSBnZXRUcmFuc2Zvcm0oKSB7CisgICAgICAgIGlmICh0cmFuc2Zvcm0gIT0gbnVsbCl7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFmZmluZVRyYW5zZm9ybSh0cmFuc2Zvcm0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBGb250UmVuZGVyQ29udGV4dCBvYmplY3Qgd2l0aCBjdXJyZW50CisgICAgICogRm9udFJlbmRlckNvbnRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0IG9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgRm9udFJlbmRlckNvbnRleHQgb2JqZWN0IGlzIGVxdWFsIHRvCisgICAgICogICAgICAgICBjdXJyZW50IEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gZnJjKXsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZyYyA9PSBudWxsKXsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghZnJjLmdldFRyYW5zZm9ybSgpLmVxdWFscyh0aGlzLmdldFRyYW5zZm9ybSgpKSAmJgorICAgICAgICAgICAgIWZyYy5pc0FudGlBbGlhc2VkKCkgPT0gdGhpcy5mQW50aUFsaWFzZWQgJiYKKyAgICAgICAgICAgICFmcmMudXNlc0ZyYWN0aW9uYWxNZXRyaWNzKCkgPT0gdGhpcy5mRnJhY3Rpb25hbE1ldHJpY3MpeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGV4dCBmcmFjdGlvbmFsIG1ldHJpY3MgYXJlIHVzZWQgaW4gdGhpcworICAgICAqIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHRleHQgZnJhY3Rpb25hbCBtZXRyaWNzIGFyZSB1c2VkIGluIHRoaXMKKyAgICAgKiAgICAgICAgIEZvbnRSZW5kZXJDb250ZXh0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdXNlc0ZyYWN0aW9uYWxNZXRyaWNzKCkgeworICAgICAgICByZXR1cm4gdGhpcy5mRnJhY3Rpb25hbE1ldHJpY3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGFudGktYWxpYXNpbmcgaXMgdXNlZCBpbiB0aGlzIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgaXMgYW50aS1hbGlhc2luZyBpcyB1c2VkIGluIHRoaXMgRm9udFJlbmRlckNvbnRleHQsCisgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBbnRpQWxpYXNlZCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZkFudGlBbGlhc2VkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaGFzaCBjb2RlIG9mIHRoZSBGb250UmVuZGVyQ29udGV4dCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoZSBGb250UmVuZGVyQ29udGV4dCBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJhbnNmb3JtKCkuaGFzaENvZGUoKSBeCisgICAgICAgICAgICAgICAgbmV3IEJvb2xlYW4odGhpcy5mRnJhY3Rpb25hbE1ldHJpY3MpLmhhc2hDb2RlKCkgXgorICAgICAgICAgICAgICAgIG5ldyBCb29sZWFuKHRoaXMuZkFudGlBbGlhc2VkKS5oYXNoQ29kZSgpOworICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9HbHlwaEp1c3RpZmljYXRpb25JbmZvLmphdmEgYi9hd3QvamF2YS9hd3QvZm9udC9HbHlwaEp1c3RpZmljYXRpb25JbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjAzZGUwYQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9mb250L0dseXBoSnVzdGlmaWNhdGlvbkluZm8uamF2YQpAQCAtMCwwICsxLDE5NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGNsYXNzIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBnbHlwaCdzCisgKiBqdXN0aWZpY2F0aW9uIHByb3BlcnRpZXMuIFRoZXJlIGFyZSBmb3VyIGp1c3RpZmljYXRpb24gcHJvcGVydGllczogd2VpZ2h0LAorICogcHJpb3JpdHksIGFic29yYiwgYW5kIGxpbWl0LgorICogPHA+CisgKiBUaGVyZSBhcmUgdHdvIHNldHMgb2YgbWV0cmljczogZ3Jvd2luZyBhbmQgc2hyaW5raW5nLiBHcm93aW5nIG1ldHJpY3MgYXJlCisgKiB1c2VkIHdoZW4gdGhlIGdseXBocyBhcmUgdG8gYmUgc3ByZWFkIGFwYXJ0IHRvIGZpdCBhIGxhcmdlciB3aWR0aC4gU2hyaW5raW5nCisgKiBtZXRyaWNzIGFyZSB1c2VkIHdoZW4gdGhlIGdseXBocyBhcmUgdG8gYmUgbW92ZWQgdG9nZXRoZXIgdG8gZml0IGEgc21hbGxlcgorICogd2lkdGguCisgKiA8L3A+CisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUFJJT1JJVFlfS0FTSElEQSBpbmRpY2F0ZXMgdGhlIGhpZ2hlc3QganVzdGlmaWNhdGlvbgorICAgICAqIHByaW9yaXR5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSU9SSVRZX0tBU0hJREEgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFBSSU9SSVRZX1dISVRFU1BBQ0UgaW5kaWNhdGVzIHRoZSBzZWNvbmQgaGlnaGVzdAorICAgICAqIGp1c3RpZmljYXRpb24gcHJpb3JpdHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJT1JJVFlfV0hJVEVTUEFDRSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUFJJT1JJVFlfSU5URVJDSEFSIGluZGljYXRlcyB0aGUgc2Vjb25kIGxvd2VzdCBqdXN0aWZpY2F0aW9uCisgICAgICogcHJpb3JpdHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJT1JJVFlfSU5URVJDSEFSID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBQUklPUklUWV9OT05FIGluZGljYXRlcyB0aGUgbG93ZXN0IGp1c3RpZmljYXRpb24gcHJpb3JpdHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJT1JJVFlfTk9ORSA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZ3JvdyBhYnNvcmIgZmxhZyBpbmRpY2F0ZXMgaWYgdGhpcyBnbHlwaCBhYnNvcmJzIGFsbCBleHRyYSBzcGFjZSBhdAorICAgICAqIHRoaXMgYW5kIGxvd2VyIHByaW9yaXR5IGxldmVscyB3aGVuIGl0IGdyb3dzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGdyb3dBYnNvcmI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZ3JvdyBsZWZ0IGxpbWl0IHZhbHVlIHJlcHJlc2VudHMgdGhlIG1heGltdW0gdmFsdWUgYnkgd2hpY2ggdGhlIGxlZnQKKyAgICAgKiBzaWRlIG9mIHRoaXMgZ2x5cGggZ3Jvd3MuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGdyb3dMZWZ0TGltaXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZ3JvdyByaWdodCBsaW1pdCB2YWx1ZSByZXBlc2VudHMgdGhlIG1heGltdW0gdmFsdWUgYnkgd2hpY2ggdGhlIHJpZ2h0CisgICAgICogc2lkZSBvZiB0aGlzIGdseXBoIGdyb3dzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBmbG9hdCBncm93UmlnaHRMaW1pdDsKKworICAgIC8qKgorICAgICAqIFRoZSBncm93IHByaW9yaXR5IHZhbHVlIHJlcHJlc2VudHMgdGhlIHByaW9yaXR5IGxldmVsIG9mIHRoaXMgZ2x5cGggYXMgaXQKKyAgICAgKiBpcyBncm93aW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ3Jvd1ByaW9yaXR5OworCisgICAgLyoqCisgICAgICogVGhlIHNocmluayBhYnNvcmIgZmxlZyBpbmRpY2F0ZXMgdGhpcyBnbHlwaCBhYnNvcmJzIGFsbCByZW1haW5pbmcKKyAgICAgKiBzaHJpbmthZ2UgYXQgdGhpcyBhbmQgbG93ZXIgcHJpb3JpdHkgbGV2ZWxzIGFzIGl0IHNocmlua3MuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gc2hyaW5rQWJzb3JiOworCisgICAgLyoqCisgICAgICogVGhlIHNocmluayBsZWZ0IGxpbWl0IHZhbHVlIHJlcHJlc2VudHMgdGhlIG1heGltdW0gdmFsdWUgYnkgd2hpY2ggdGhlCisgICAgICogbGVmdCBzaWRlIG9mIHRoaXMgZ2x5cGggc2hyaW5rcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgZmxvYXQgc2hyaW5rTGVmdExpbWl0OworCisgICAgLyoqCisgICAgICogVGhlIHNocmluayByaWdodCBsaW1pdCB2YWx1ZSByZXByZXNlbnRzIHRoZSBtYXhpbXVtIHZhbHVlIGJ5IHdoaWNoIHRoZQorICAgICAqIHJpZ2h0IHNpZGUgb2YgdGhpcyBnbHlwaCBzaHJpbmtzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBmbG9hdCBzaHJpbmtSaWdodExpbWl0OworCisgICAgLyoqCisgICAgICogVGhlIHNocmluayBwcmlvcml0eSByZXByZXNlbnRzIHRoZSBnbHl0aCdzIHByaW9yaXR5IGxldmVsIGFzIGl0IGlzCisgICAgICogc2hyaW5raW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgc2hyaW5rUHJpb3JpdHk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd2VpZ2h0IG9mIHRoZSBnbHlwaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgZmxvYXQgd2VpZ2h0OworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEdseXBoSnVzdGlmaWNhdGlvbkluZm8gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGdseXBoJ3MKKyAgICAgKiBqdXN0aWZpY2F0aW9uIHByb3BlcnRpZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHdlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHdlaWdodCBvZiBnbHlwaC4KKyAgICAgKiBAcGFyYW0gZ3Jvd0Fic29yYgorICAgICAqICAgICAgICAgICAgaW5kaWNhdGVzIGlmIHRoaXMgZ2x5cGggY29udGFpcyBhbGwgc3BhY2UgYXQgdGhpcyBwcmlvcml0eSBhbmQKKyAgICAgKiAgICAgICAgICAgIGxvd2VyIHByaW9yaXR5IGxldmVscyB3aGVuIGl0IGdyb3dzLgorICAgICAqIEBwYXJhbSBncm93UHJpb3JpdHkKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB0aGUgcHJpb3JpdHkgbGV2ZWwgb2YgdGhpcyBnbHlwaCB3aGVuIGl0IGdyb3dzLgorICAgICAqIEBwYXJhbSBncm93TGVmdExpbWl0CisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2Ygd2hpY2ggdGhlIGxlZnQgc2lkZSBvZiB0aGlzCisgICAgICogICAgICAgICAgICBnbHlwaCBjYW4gZ3Jvdy4KKyAgICAgKiBAcGFyYW0gZ3Jvd1JpZ2h0TGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIHZhbHVlIG9mIHdoaWNoIHRoZSByaWdodCBzaWRlIG9mIHRoaXMgZ2x5cGggY2FuCisgICAgICogICAgICAgICAgICBncm93LgorICAgICAqIEBwYXJhbSBzaHJpbmtBYnNvcmIKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyBpZiB0aGlzIGdseXBoIGNvbnRhaW5zIGFsbCByZW1haW5pbmcgc2hyaW5rYWdlIGF0CisgICAgICogICAgICAgICAgICB0aGlzIGFuZCBsb3dlciBwcmlvcml0eSBsZXZlbHMgd2hlbiBpdCBzaHJpbmtzLgorICAgICAqIEBwYXJhbSBzaHJpbmtQcmlvcml0eQorICAgICAqICAgICAgICAgICAgaW5kaWNhdGVzIHRoZSBnbHlwaCdzIHByaW9yaXR5IGxldmVsIHdoZW4gaXQgc2hyaW5rcy4KKyAgICAgKiBAcGFyYW0gc2hyaW5rTGVmdExpbWl0CisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2Ygd2hpY2ggdGhlIGxlZnQgc2lkZSBvZiB0aGlzCisgICAgICogICAgICAgICAgICBnbHlwaCBjYW4gc2hyaW5rLgorICAgICAqIEBwYXJhbSBzaHJpbmtSaWdodExpbWl0CisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgdGhlIG1heGltdW0gYW1vdW50IGJ5IHdoaWNoIHRoZSByaWdodCBzaWRlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgICAgIGdseXBoIGNhbiBzaHJpbmsuCisgICAgICovCisgICAgcHVibGljIEdseXBoSnVzdGlmaWNhdGlvbkluZm8oZmxvYXQgd2VpZ2h0LCBib29sZWFuIGdyb3dBYnNvcmIsIGludCBncm93UHJpb3JpdHksCisgICAgICAgICAgICBmbG9hdCBncm93TGVmdExpbWl0LCBmbG9hdCBncm93UmlnaHRMaW1pdCwgYm9vbGVhbiBzaHJpbmtBYnNvcmIsIGludCBzaHJpbmtQcmlvcml0eSwKKyAgICAgICAgICAgIGZsb2F0IHNocmlua0xlZnRMaW1pdCwgZmxvYXQgc2hyaW5rUmlnaHRMaW1pdCkgeworCisgICAgICAgIGlmICh3ZWlnaHQgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMTlDPXdlaWdodCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE5QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHRoaXMud2VpZ2h0ID0gd2VpZ2h0OworCisgICAgICAgIGlmIChncm93TGVmdExpbWl0IDwgMCkgeworICAgICAgICAgICAgLy8gYXd0LjE5RD1ncm93TGVmdExpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTlEIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ncm93TGVmdExpbWl0ID0gZ3Jvd0xlZnRMaW1pdDsKKworICAgICAgICBpZiAoZ3Jvd1JpZ2h0TGltaXQgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMTlFPWdyb3dSaWdodExpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTlFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ncm93UmlnaHRMaW1pdCA9IGdyb3dSaWdodExpbWl0OworCisgICAgICAgIGlmICgoc2hyaW5rUHJpb3JpdHkgPCAwKSB8fCAoc2hyaW5rUHJpb3JpdHkgPiBQUklPUklUWV9OT05FKSkgeworICAgICAgICAgICAgLy8gYXd0LjE5Rj1pbmNvcnJlY3QgdmFsdWUgZm9yIHNocmlua1ByaW9yaXR5LCBtb3JlIHRoYW4KKyAgICAgICAgICAgIC8vIFBSSU9SSVRZX05PTkUgb3IgbGVzcyB0aGFuIFBSSU9SSVRZX0tBU0hJREEgdmFsdWUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTlGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zaHJpbmtQcmlvcml0eSA9IHNocmlua1ByaW9yaXR5OworCisgICAgICAgIGlmICgoZ3Jvd1ByaW9yaXR5IDwgMCkgfHwgKGdyb3dQcmlvcml0eSA+IFBSSU9SSVRZX05PTkUpKSB7CisgICAgICAgICAgICAvLyBhd3QuMjAwPWluY29ycmVjdCB2YWx1ZSBmb3IgZ3Jvd1ByaW9yaXR5LCBtb3JlIHRoYW4gUFJJT1JJVFlfTk9ORQorICAgICAgICAgICAgLy8gb3IgbGVzcyB0aGFuIFBSSU9SSVRZX0tBU0hJREEgdmFsdWUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjAwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ncm93UHJpb3JpdHkgPSBncm93UHJpb3JpdHk7CisKKyAgICAgICAgaWYgKHNocmlua0xlZnRMaW1pdCA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMDE9c2hyaW5rTGVmdExpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjAxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zaHJpbmtMZWZ0TGltaXQgPSBzaHJpbmtMZWZ0TGltaXQ7CisKKyAgICAgICAgaWYgKHNocmlua1JpZ2h0TGltaXQgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjAyPXNocmlua1JpZ2h0TGltaXQgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNocmlua1JpZ2h0TGltaXQgPSBzaHJpbmtSaWdodExpbWl0OworCisgICAgICAgIHRoaXMuc2hyaW5rQWJzb3JiID0gc2hyaW5rQWJzb3JiOworICAgICAgICB0aGlzLmdyb3dBYnNvcmIgPSBncm93QWJzb3JiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L0dseXBoTWV0cmljcy5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvR2x5cGhNZXRyaWNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg3MTcyMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9mb250L0dseXBoTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsMjY2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5mb250OworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKKworLyoqCisgKiBUaGUgR2x5cGhNZXRyaWNzIGNsYXNzIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzaXplIGFuZCBzaGFwZSBvZiBhCisgKiBzaW5nbGUgZ2x5cGguIEVhY2ggZ2x5cGggaGFzIGluZm9ybWF0aW9uIHRvIHNwZWNpZnkgd2hldGhlciBpdHMgYmFzZWxpbmUgaXMKKyAqIGhvcml6b250YWwgb3IgdmVydGljYWwgYXMgd2VsbCBhcyBpbmZvcm1hdGlvbiBvbiBob3cgaXQgaW50ZXJhY3RzIHdpdGggb3RoZXIKKyAqIGNoYXJhY3RlcnMgaW4gYSB0ZXh0LCBnaXZlbiBhcyBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlczogU1RBTkRBUkQsCisgKiBMSUdBVFVSRSwgQ09NQklOSU5HLCBvciBDT01QT05FTlQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2x5cGhNZXRyaWNzIHsKKworICAgIC8vIGFkdmFuY2Ugd2lkdGggb2YgdGhlIGdseXBoIGNoYXJhY3RlciBjZWxsCisgICAgLyoqCisgICAgICogVGhlIGFkdmFuY2UgeC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGFkdmFuY2VYOworCisgICAgLy8gYWR2YW5jZSBoZWlnaHQgb2YgdGhlIGdseXBoIGNoYXJhY3RlciBjZWxsCisgICAgLyoqCisgICAgICogVGhlIGFkdmFuY2UgeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGFkdmFuY2VZOworCisgICAgLy8gZmxhZyBpZiB0aGUgZ2x5cGggaG9yaXpvbnRhbAorICAgIC8qKgorICAgICAqIFRoZSBob3Jpem9udGFsLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBob3Jpem9udGFsOworCisgICAgLy8gZ2x5cGggdHlwZSBjb2RlCisgICAgLyoqCisgICAgICogVGhlIGdseXBoIHR5cGUuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIGdseXBoVHlwZTsKKworICAgIC8vIGJvdW5kaW5nIGJveCBmb3Igb3V0bGluZSBvZiB0aGUgZ2x5cGgKKyAgICAvKioKKyAgICAgKiBUaGUgYm91bmRzLgorICAgICAqLworICAgIHByaXZhdGUgUmVjdGFuZ2xlMkQuRmxvYXQgYm91bmRzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNUQU5EQVJEIGluZGljYXRlcyBhIGdseXBoIHRoYXQgcmVwcmVzZW50cyBhIHNpbmdsZQorICAgICAqIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU1RBTkRBUkQgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IExJR0FUVVJFIGluZGljYXRlcyBhIGdseXBoIHRoYXQgcmVwcmVzZW50cyBtdWx0aXBsZQorICAgICAqIGNoYXJhY3RlcnMgYXMgYSBsaWdhdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgTElHQVRVUkUgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENPTUJJTklORyBpbmRpY2F0ZXMgYSBnbHlwaCB3aGljaCBoYXMgbm8gY2FyZXQgcG9zaXRpb24KKyAgICAgKiBiZXR3ZWVuIGdseXBocyAoZm9yIGV4YW1wbGUgdW1sYXV0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ09NQklOSU5HID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDT01QT05FTlQgaW5kaWNhdGVzIGEgZ2x5cGggd2l0aCBubyBjb3JyZXNwb25kaW5nIGNoYXJhY3RlcgorICAgICAqIGluIHRoZSBiYWNraW5nIHN0b3JlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDT01QT05FTlQgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdISVRFU1BBQ0UgaW5kaWNhdGVzIGEgZ2x5cGggd2l0aG91dCB2aXN1YWwgcmVwcmVzZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFdISVRFU1BBQ0UgPSA0OworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEdseXBoTWV0cmljcyBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGhvcml6b250YWwKKyAgICAgKiAgICAgICAgICAgIHNwZWNpZmllcyBpZiBtZXRyaWNzIGFyZSBmb3IgYSBob3Jpem9udGFsIGJhc2VsaW5lICh0cnVlCisgICAgICogICAgICAgICAgICB2YWx1ZSksIG9yIGEgdmVydGljYWwgYmFzZWxpbmUgKGZhbHNlIHZhbHVlKS4KKyAgICAgKiBAcGFyYW0gYWR2YW5jZVgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvbXBvbmVudCBvZiB0aGUgZ2x5cGgncyBhZHZhbmNlLgorICAgICAqIEBwYXJhbSBhZHZhbmNlWQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29tcG9uZW50IG9mIHRoZSBnbHlwaCdzIGFkdmFuY2UuCisgICAgICogQHBhcmFtIGJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIGdseXBoJ3MgYm91bmRzLgorICAgICAqIEBwYXJhbSBnbHlwaFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCdzIHR5cGUuCisgICAgICovCisgICAgcHVibGljIEdseXBoTWV0cmljcyhib29sZWFuIGhvcml6b250YWwsIGZsb2F0IGFkdmFuY2VYLCBmbG9hdCBhZHZhbmNlWSwgUmVjdGFuZ2xlMkQgYm91bmRzLAorICAgICAgICAgICAgYnl0ZSBnbHlwaFR5cGUpIHsKKyAgICAgICAgdGhpcy5ob3Jpem9udGFsID0gaG9yaXpvbnRhbDsKKyAgICAgICAgdGhpcy5hZHZhbmNlWCA9IGFkdmFuY2VYOworICAgICAgICB0aGlzLmFkdmFuY2VZID0gYWR2YW5jZVk7CisKKyAgICAgICAgdGhpcy5ib3VuZHMgPSBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoKTsKKyAgICAgICAgdGhpcy5ib3VuZHMuc2V0UmVjdChib3VuZHMpOworCisgICAgICAgIHRoaXMuZ2x5cGhUeXBlID0gZ2x5cGhUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBob3Jpem9udGFsIEdseXBoTWV0cmljcyB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYWR2YW5jZVgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvbXBvbmVudCBvZiB0aGUgZ2x5cGgncyBhZHZhbmNlLgorICAgICAqIEBwYXJhbSBib3VuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCdzIGJvdW5kcy4KKyAgICAgKiBAcGFyYW0gZ2x5cGhUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZ2x5cGgncyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaE1ldHJpY3MoZmxvYXQgYWR2YW5jZVgsIFJlY3RhbmdsZTJEIGJvdW5kcywgYnl0ZSBnbHlwaFR5cGUpIHsKKyAgICAgICAgdGhpcy5hZHZhbmNlWCA9IGFkdmFuY2VYOworICAgICAgICB0aGlzLmFkdmFuY2VZID0gMDsKKworICAgICAgICB0aGlzLmhvcml6b250YWwgPSB0cnVlOworCisgICAgICAgIHRoaXMuYm91bmRzID0gbmV3IFJlY3RhbmdsZTJELkZsb2F0KCk7CisgICAgICAgIHRoaXMuYm91bmRzLnNldFJlY3QoYm91bmRzKTsKKworICAgICAgICB0aGlzLmdseXBoVHlwZSA9IGdseXBoVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBnbHlwaCdzIGJvdW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGdseXBoJ3MgYm91bmRzLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgcmV0dXJuIChSZWN0YW5nbGUyRC5GbG9hdCl0aGlzLmJvdW5kcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGlzIGdseXBoIGlzIHdoaXRlc3BhY2Ugb3Igbm90LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBnbHlwaCBpcyB3aGl0ZXNwYWNlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlKCkgeworICAgICAgICByZXR1cm4gKCh0aGlzLmdseXBoVHlwZSAmIDQpID09IFdISVRFU1BBQ0UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGlzIGdseXBoIGlzIHN0YW5kYXJkIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgZ2x5cGggaXMgc3RhbmRhcmQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYXJkKCkgeworICAgICAgICByZXR1cm4gKCh0aGlzLmdseXBoVHlwZSAmIDMpID09IFNUQU5EQVJEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBnbHlwaCBpcyBsaWdhdHVyZSBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIGdseXBoIGlzIGxpZ2F0dXJlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMaWdhdHVyZSgpIHsKKyAgICAgICAgcmV0dXJuICgodGhpcy5nbHlwaFR5cGUgJiAzKSA9PSBMSUdBVFVSRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgZ2x5cGggaXMgY29tcG9uZW50IG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgZ2x5cGggaXMgY29tcG9uZW50LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDb21wb25lbnQoKSB7CisgICAgICAgIHJldHVybiAoKHRoaXMuZ2x5cGhUeXBlICYgMykgPT0gQ09NUE9ORU5UKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBnbHlwaCBpcyBjb21iaW5pbmcgb3Igbm90LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBnbHlwaCBpcyBjb21iaW5pbmcsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbWJpbmluZygpIHsKKyAgICAgICAgcmV0dXJuICgodGhpcy5nbHlwaFR5cGUgJiAzKSA9PSBDT01CSU5JTkcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdseXBoJ3MgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBnbHlwaCdzIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gdGhpcy5nbHlwaFR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgcmlnaHQgKGZvciBob3Jpem9udGFsKSBvciBib3R0b20gKGZvcgorICAgICAqIHZlcnRpY2FsKSBvZiB0aGUgZ2x5cGggYm91bmRzIHRvIHRoZSBhZHZhbmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRpc3RhbmNlIGZyb20gdGhlIHJpZ2h0IChmb3IgaG9yaXpvbnRhbCkgb3IgYm90dG9tIChmb3IKKyAgICAgKiAgICAgICAgIHZlcnRpY2FsKSBvZiB0aGUgZ2x5cGggYm91bmRzIHRvIHRoZSBhZHZhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRSU0IoKSB7CisgICAgICAgIGlmICh0aGlzLmhvcml6b250YWwpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2VYIC0gdGhpcy5ib3VuZHMueCAtIChmbG9hdCl0aGlzLmJvdW5kcy5nZXRXaWR0aCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2VZIC0gdGhpcy5ib3VuZHMueSAtIChmbG9hdCl0aGlzLmJvdW5kcy5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkaXN0YW5jZSBmcm9tIDAsIDAgdG8gdGhlIGxlZnQgKGZvciBob3Jpem9udGFsKSBvciB0b3AgKGZvcgorICAgICAqIHZlcnRpY2FsKSBvZiB0aGUgZ2x5cGggYm91bmRzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRpc3RhbmNlIGZyb20gMCwgMCB0byB0aGUgbGVmdCAoZm9yIGhvcml6b250YWwpIG9yIHRvcCAoZm9yCisgICAgICogICAgICAgICB2ZXJ0aWNhbCkgb2YgdGhlIGdseXBoIGJvdW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TFNCKCkgeworICAgICAgICBpZiAodGhpcy5ob3Jpem9udGFsKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5ib3VuZHMueDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy5ib3VuZHMueTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBZIGNvbXBvbmVudCBvZiB0aGUgZ2x5cGgncyBhZHZhbmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFkgY29tcG9uZW50IG9mIHRoZSBnbHlwaCdzIGFkdmFuY2UuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEFkdmFuY2VZKCkgeworICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBYIGNvbXBvbmVudCBvZiB0aGUgZ2x5cGgncyBhZHZhbmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFggY29tcG9uZW50IG9mIHRoZSBnbHlwaCdzIGFkdmFuY2UuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEFkdmFuY2VYKCkgeworICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlWDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBnbHlwaCdzIGFkdmFuY2UgYWxvbmcgdGhlIGJhc2VsaW5lLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGdseXBoJ3MgYWR2YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0QWR2YW5jZSgpIHsKKyAgICAgICAgaWYgKHRoaXMuaG9yaXpvbnRhbCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWR2YW5jZVg7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuYWR2YW5jZVk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9HbHlwaFZlY3Rvci5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvR2x5cGhWZWN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNzJiNzc0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvR2x5cGhWZWN0b3IuamF2YQpAQCAtMCwwICsxLDQwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC5Gb250UmVuZGVyQ29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkdseXBoSnVzdGlmaWNhdGlvbkluZm87CitpbXBvcnQgamF2YS5hd3QuZm9udC5HbHlwaE1ldHJpY3M7CisKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS5hd3QuU2hhcGU7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CisKKy8qKgorICogVGhlIEdseXBoVmVjdG9yIGNsYXNzIGNvbnRhaW5zIGEgY29sbGVjdGlvbiBvZiBnbHlwaHMgd2l0aCBnZW9tZXRyaWMKKyAqIGluZm9ybWF0aW9uIGFuZCBlYWNoIGdseXBoJ3MgbG9jYXRpb24uIEVhY2ggR2x5cGhWZWN0b3IgY2FuIGJlIGFzc29jaWF0ZWQKKyAqIHdpdGggb25seSBvbmUgRm9udC4gR2x5cGhWZWN0b3IgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZvciBlYWNoCisgKiBnbHlwaDoKKyAqIDx1bD4KKyAqIDxsaT50aGUgZ2x5cGggcG9zaXRpb247PC9saT4KKyAqIDxsaT50aGUgdHJhbnNmb3JtIG9mIHRoZSBnbHlwaDs8L2xpPgorICogPGxpPnRoZSBtZXRyaWNzIG9mIHRoZSBnbHlwaCBpbiB0aGUgY29udGV4dCBvZiB0aGUgR2x5cGhWZWN0b3IuPC9saT4KKyAqIDwvdWw+CisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgR2x5cGhWZWN0b3IgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEZMQUdfSEFTX1RSQU5TRk9STVMgaW5kaWNhdGVzIHRoYXQgdGhpcyBHbHlwaFZlY3RvciBoYXMKKyAgICAgKiBwZXItZ2x5cGggdHJhbnNmb3Jtcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTEFHX0hBU19UUkFOU0ZPUk1TID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGTEFHX0hBU19QT1NJVElPTl9BREpVU1RNRU5UUyBpbmRpY2F0ZXMgdGhhdCB0aGUgR2x5cGhWZWN0b3IKKyAgICAgKiBoYXMgcGVyLWdseXBoIHBvc2l0aW9uIGFkanVzdG1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMQUdfSEFTX1BPU0lUSU9OX0FESlVTVE1FTlRTID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGTEFHX1JVTl9SVEwgaW5kaWNhdGVzIHRoYXQgdGhpcyBHbHlwaFZlY3RvciBoYXMgYSByaWdodCB0bworICAgICAqIGxlZnQgcnVuIGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTEFHX1JVTl9SVEwgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEZMQUdfQ09NUExFWF9HTFlQSFMgaW5kaWNhdGVzIHRoYXQgdGhpcyBHbHlwaFZlY3RvciBoYXMgYQorICAgICAqIGNvbXBsZXggZ2x5cGggdG8gY2hhciBtYXBwaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMQUdfQ09NUExFWF9HTFlQSFMgPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEZMQUdfTUFTSyBpbmRpY2F0ZXMgYSBtYXNrIGZvciBzdXBwb3J0ZWQgZmxhZ3MgZnJvbQorICAgICAqIGdldExheW91dEZsYWdzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMQUdfTUFTSyA9IDE1OyAvLyAofCkgbWFzayBvZiBvdGhlciBmbGFncworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEdseXBoVmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaFZlY3RvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwaXhlbCBib3VuZHMgb2YgdGhlIEdseXBoVmVjdG9yIHdoZW4gcmVuZGVyZWQgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIGxvY2F0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIEdseXBoVmVjdG9yJ3MgbG9jYXRpb24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIEdseXBoVmVjdG9yJ3MgbG9jYXRpb24uCisgICAgICogQHJldHVybiB0aGUgcGl4ZWwgYm91bmRzCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRQaXhlbEJvdW5kcyhGb250UmVuZGVyQ29udGV4dCBmcmMsIGZsb2F0IHgsIGZsb2F0IHkpIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiAtIGludGVnZXIgUmVjdGFuZ2xlLCB0aGF0IGVuY2xvc2VzIHZpc3VhbAorICAgICAgICAvLyBib3VuZHMgcmVjdGFuZ2xlCisgICAgICAgIFJlY3RhbmdsZTJEIHZpc3VhbFJlY3QgPSBnZXRWaXN1YWxCb3VuZHMoKTsKKworICAgICAgICBpbnQgbWluWCA9IChpbnQpTWF0aC5mbG9vcih2aXN1YWxSZWN0LmdldE1pblgoKSArIHgpOworICAgICAgICBpbnQgbWluWSA9IChpbnQpTWF0aC5mbG9vcih2aXN1YWxSZWN0LmdldE1pblkoKSArIHkpOworICAgICAgICBpbnQgd2lkdGggPSAoaW50KU1hdGguY2VpbCh2aXN1YWxSZWN0LmdldE1heFgoKSArIHgpIC0gbWluWDsKKyAgICAgICAgaW50IGhlaWdodCA9IChpbnQpTWF0aC5jZWlsKHZpc3VhbFJlY3QuZ2V0TWF4WSgpICsgeSkgLSBtaW5ZOworCisgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlKG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBpeGVsIGJvdW5kcyBvZiB0aGUgZ2x5cGggd2l0aCB0aGUgc3BlY2lmaWVkIGluZGV4IGluIHRoaXMKKyAgICAgKiBHbHlwaFZlY3RvciB3aGljaCBpcyByZW5kZXJlZCB3aXRoIHRoZSBzcGVjaWZpZWQgRm9udFJlbmRlckNvbnRleHQgYXQgdGhlCisgICAgICogc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGdseXBoIGluZGV4IGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBHbHlwaFZlY3RvcidzIGxvY2F0aW9uLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBHbHlwaFZlY3RvcidzIGxvY2F0aW9uLgorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUgYm91bmRzLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0R2x5cGhQaXhlbEJvdW5kcyhpbnQgaW5kZXgsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICBSZWN0YW5nbGUyRCB2aXN1YWxSZWN0ID0gZ2V0R2x5cGhWaXN1YWxCb3VuZHMoaW5kZXgpLmdldEJvdW5kczJEKCk7CisKKyAgICAgICAgaW50IG1pblggPSAoaW50KU1hdGguZmxvb3IodmlzdWFsUmVjdC5nZXRNaW5YKCkgKyB4KTsKKyAgICAgICAgaW50IG1pblkgPSAoaW50KU1hdGguZmxvb3IodmlzdWFsUmVjdC5nZXRNaW5ZKCkgKyB5KTsKKyAgICAgICAgaW50IHdpZHRoID0gKGludClNYXRoLmNlaWwodmlzdWFsUmVjdC5nZXRNYXhYKCkgKyB4KSAtIG1pblg7CisgICAgICAgIGludCBoZWlnaHQgPSAoaW50KU1hdGguY2VpbCh2aXN1YWxSZWN0LmdldE1heFkoKSArIHkpIC0gbWluWTsKKworICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZShtaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoZSBHbHlwaFZlY3Rvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoZSBHbHlwaFZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUmVjdGFuZ2xlMkQgZ2V0VmlzdWFsQm91bmRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9naWNhbCBib3VuZHMgb2YgdGhlIEdseXBoVmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBSZWN0YW5nbGUyRCBnZXRMb2dpY2FsQm91bmRzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEBwYXJhbSBuZXdQb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcG9zaXRpb24gb2YgdGhlIGdseXBoIGF0IHRoZSBzcGVjaWZpZWQgZ2x5cGhJbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRHbHlwaFBvc2l0aW9uKGludCBnbHlwaEluZGV4LCBQb2ludDJEIG5ld1Bvcyk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGggaW4gdGhpcyBHbHlwaFZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUG9pbnQyRCBnZXRHbHlwaFBvc2l0aW9uKGludCBnbHlwaEluZGV4KTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFmZmluZSB0cmFuc2Zvcm0gdG8gYSBnbHlwaCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gdGhpcworICAgICAqIEdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgZ2x5dGggaW5kZXggaW4gdGhpcyBHbHlwaFZlY3Rvci4KKyAgICAgKiBAcGFyYW0gdHJhbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gdG8gYmUgYXNzaWduZWQgdG8gdGhlIHNwZWNpZmllZCBnbHlwaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRHbHlwaFRyYW5zZm9ybShpbnQgZ2x5cGhJbmRleCwgQWZmaW5lVHJhbnNmb3JtIHRyYW5zKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRyYW5zZm9ybSBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB0cmFuc2Zvcm0gb2YgdGhlIGdseXBoLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBBZmZpbmVUcmFuc2Zvcm0gZ2V0R2x5cGhUcmFuc2Zvcm0oaW50IGdseXBoSW5kZXgpOworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBHbHlwaFZlY3RvciB3aXRoIHRoZSBzcGVjaWZpZWQgR2x5cGhWZWN0b3Igb2JqZWN0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhWZWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBHbHlwaFZlY3RvciBvYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIEdseXBoVmVjdG9yIGlzIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgR2x5cGhWZWN0b3IKKyAgICAgKiAgICAgICAgIG9iamVjdCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGVxdWFscyhHbHlwaFZlY3RvciBnbHlwaFZlY3Rvcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZXRyaWNzIG9mIHRoZSBnbHlwaCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gdGhpcworICAgICAqIEdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIG1ldHJpY3Mgb2YgdGhlIGdseXBoIHdpdGggdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGlzCisgICAgICogICAgICAgICBHbHlwaFZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR2x5cGhNZXRyaWNzIGdldEdseXBoTWV0cmljcyhpbnQgZ2x5cGhJbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBqdXN0aWZpY2F0aW9uIGluZm9ybWF0aW9uIG9mIHRoZSBnbHlwaCB3aG9zZSBpbmRleCBpcyBzcGVjaWZpZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHlwaCBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGZvciB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGdldEdseXBoSnVzdGlmaWNhdGlvbkluZm8oaW50IGdseXBoSW5kZXgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgRm9udFJlbmRlckNvbnRleHQgb2YgdGhpcyBHbHlwaFZlY3Rvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBGb250UmVuZGVyQ29udGV4dCBvZiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb250UmVuZGVyQ29udGV4dCBnZXRGb250UmVuZGVyQ29udGV4dCgpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIFNoYXBlIG9iamVjdCB3aGljaCBkZWZpbmVzIHRoZSB2aXN1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IsIHRyYW5zbGF0ZWQgYSBkaXN0YW5jZSBvZiB4IGluIHRoZSBYCisgICAgICogZGlyZWN0aW9uIGFuZCB5IGluIHRoZSBZIGRpcmVjdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGdseXRoIGluZGV4IGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBpbiB0aGUgWCBkaXJlY3Rpb24gdG8gdHJhbnNsYXRlIHRoZSBzaGFwZSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIGJlZm9yZSByZXR1cm5pbmcgaXQuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBpbiB0aGUgWSBkaXJlY3Rpb24gdG8gdHJhbnNsYXRlIHRoZSBzaGFwZSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIGJlZm9yZSByZXR1cm5pbmcgaXQuCisgICAgICogQHJldHVybiBhIFNoYXBlIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSB2aXN1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgZ2x5cGggaW4gdGhpcyBHbHlwaFZlY3RvciAtIGdseXBoIG91dGxpbmUuCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGdldEdseXBoT3V0bGluZShpbnQgZ2x5cGhJbmRleCwgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICBTaGFwZSBpbml0aWFsU2hhcGUgPSBnZXRHbHlwaE91dGxpbmUoZ2x5cGhJbmRleCk7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0cmFucyA9IEFmZmluZVRyYW5zZm9ybS5nZXRUcmFuc2xhdGVJbnN0YW5jZSh4LCB5KTsKKyAgICAgICAgcmV0dXJuIHRyYW5zLmNyZWF0ZVRyYW5zZm9ybWVkU2hhcGUoaW5pdGlhbFNoYXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGggaW4gdGhlIEdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgZ2x5cGggaW5kZXggaW4gdGhpcyBHbHlwaFZlY3Rvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBnbHlwaCB2aXN1YWwgYm91bmRzIG9mIHRoZSBnbHlwaCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4KKyAgICAgKiAgICAgICAgIHRoZSBHbHlwaFZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hhcGUgZ2V0R2x5cGhWaXN1YWxCb3VuZHMoaW50IGdseXBoSW5kZXgpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIFNoYXBlIG9iamVjdCB3aGljaCBkZWZpbmVzIHRoZSB2aXN1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBnbHl0aCBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gYSBTaGFwZSBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IgLSBnbHlwaCBvdXRsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTaGFwZSBnZXRHbHlwaE91dGxpbmUoaW50IGdseXBoSW5kZXgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9naWNhbCBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaCBpbiB0aGUgR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBpbiB0aGlzIEdseXBoVmVjdG9yIG9mIHRoZSBnbHlwaCBmcm9tIHdoaWNoIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSBpdHMgbG9naWNhbCBib3VuZHMKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIGluIHRoZSBHbHlwaFZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hhcGUgZ2V0R2x5cGhMb2dpY2FsQm91bmRzKGludCBnbHlwaEluZGV4KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZpc3VhbCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEdseXBoVmVjdG9yIHJlbmRlcmVkIGluIHgsIHkKKyAgICAgKiBsb2NhdGlvbiBhcyBhIFNoYXBlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgR2x5cGhWZWN0b3IuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIHZpc3VhbCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEdseXBoVmVjdG9yIGFzIGEgU2hhcGUgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTaGFwZSBnZXRPdXRsaW5lKGZsb2F0IHgsIGZsb2F0IHkpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgR2x5cGhWZWN0b3IgYXMgYSBTaGFwZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgR2x5cGhWZWN0b3IgYXMgYSBTaGFwZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNoYXBlIGdldE91dGxpbmUoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvbnQgb2YgdGhpcyBHbHlwaFZlY3Rvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmb250IG9mIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZvbnQgZ2V0Rm9udCgpOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgZ2x5cGggY29kZXMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaHMuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZ2luR2x5cGhJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGludG8gdGhpcyBHbHlwaFZlY3RvciBhdCB3aGljaCB0byBzdGFydCByZXRyaWV2aW5nCisgICAgICogICAgICAgICAgICBnbHlwaCBjb2Rlcy4KKyAgICAgKiBAcGFyYW0gbnVtRW50cmllcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBnbHlwaCBjb2Rlcy4KKyAgICAgKiBAcGFyYW0gY29kZVJldHVybgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGludG8gd2hpY2ggdGhlIHJlc3VsdGluZyBnbHlwaGNvZGVzIHdpbGwgYmUgd3JpdHRlbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiB0aGUgZ2x5cGggY29kZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludFtdIGdldEdseXBoQ29kZXMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsIGludFtdIGNvZGVSZXR1cm4pOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgY2hhcmFjdGVyIGluZGljZXMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaHMuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZ2luR2x5cGhJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBnbHlwaCB0byByZXR1cm4gaW5mb3JtYXRpb24gZm9yLgorICAgICAqIEBwYXJhbSBudW1FbnRyaWVzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGdseXBoIGluZGljZXMgdG8gcmV0dXJuLgorICAgICAqIEBwYXJhbSBjb2RlUmV0dXJuCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgaW50byB3aGljaCB0aGUgcmVzdWx0aW5nIGNoYXJhY3RlciBpbmRpY2VzIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIHdyaXR0ZW4uCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBjaGFyYWN0ZXIgaW5kaWNlcyBmb3IgdGhlIHNwZWNpZmllcyBnbHlwaHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldEdseXBoQ2hhckluZGljZXMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsIGludFtdIGNvZGVSZXR1cm4pIHsKKyAgICAgICAgaWYgKGNvZGVSZXR1cm4gPT0gbnVsbCkgeworICAgICAgICAgICAgY29kZVJldHVybiA9IG5ldyBpbnRbbnVtRW50cmllc107CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUVudHJpZXM7IGkrKykgeworICAgICAgICAgICAgY29kZVJldHVybltpXSA9IGdldEdseXBoQ2hhckluZGV4KGkgKyBiZWdpbkdseXBoSW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb2RlUmV0dXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgdGhlIHBvc2l0aW9ucyBvZiB0aGUgc3BlY2lmaWVkIGdseXBocyBpbiB0aGlzCisgICAgICogR2x5cGhWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZ2luR2x5cGhJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBnbHlwaCB0byByZXR1cm4gaW5mb3JtYXRpb24gZm9yLgorICAgICAqIEBwYXJhbSBudW1FbnRyaWVzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGdseXBocyB0byByZXR1cm4gaW5mb3JtYXRpb24gZm9yLgorICAgICAqIEBwYXJhbSBwb3NpdGlvblJldHVybgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdoZXJlIHRoZSByZXN1bHQgd2lsbCBiZSBzdG9yZWQuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBnbHlwaCBwb3NpdGlvbnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0W10gZ2V0R2x5cGhQb3NpdGlvbnMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsCisgICAgICAgICAgICBmbG9hdFtdIHBvc2l0aW9uUmV0dXJuKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdseXBoIGNvZGUgb2YgdGhlIHNwZWNpZmllZCBnbHlwaC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGluIHRoaXMgR2x5cGhWZWN0b3Igd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIGdseXBoCisgICAgICogICAgICAgICAgICBmcm9tIHdoaWNoIHRvIHJldHJpZXZlIHRoZSBnbHlwaGNvZGUuCisgICAgICogQHJldHVybiB0aGUgZ2x5cGhjb2RlIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGguCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRHbHlwaENvZGUoaW50IGdseXBoSW5kZXgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmlyc3QgbG9naWNhbCBjaGFyYWN0ZXIncyBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgZ2x5cGggaW5kZXguCisgICAgICogQHJldHVybiB0aGUgdGhlIGZpcnN0IGxvZ2ljYWwgY2hhcmFjdGVyJ3MgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGludCBnZXRHbHlwaENoYXJJbmRleChpbnQgZ2x5cGhJbmRleCkgeworICAgICAgICAvLyBkZWZhdWx0IGltcGxlbWV0YXRpb24gb25lLXRvLW9uZQorICAgICAgICByZXR1cm4gZ2x5cGhJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGRlZmF1bHQgbGF5b3V0IHRvIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcGVyZm9ybURlZmF1bHRMYXlvdXQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBnbHlwaHMgaW4gdGhlIEdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBnbHlwaHMgaW4gdGhlIEdseXBoVmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TnVtR2x5cGhzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGZsYWdzIHdoaWNoIGRlc2NyaWJlIHRoZSBnbG9iYWwgc3RhdGUgb2YgdGhlIEdseXBoVmVjdG9yLiBUaGUKKyAgICAgKiBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHJldHVybnMgMC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBsYXlvdXQgZmxhZ3MKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExheW91dEZsYWdzKCkgeworICAgICAgICAvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9uIC0gcmV0dXJuZWQgdmFsdWUgaXMgMAorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L0dyYXBoaWNBdHRyaWJ1dGUuamF2YSBiL2F3dC9qYXZhL2F3dC9mb250L0dyYXBoaWNBdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NDgwZTBmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvR3JhcGhpY0F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsMTc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5mb250OworCitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3MyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIEdyYXBoaWNBdHRyaWJ1dGUgYWJzdHJhY3QgY2xhc3MgcHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gaW5zZXJ0CisgKiBncmFwaGljYWwgZWxlbWVudHMgaW4gcHJpbnRlZCB0ZXh0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEdyYXBoaWNBdHRyaWJ1dGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRPUF9BTElHTk1FTlQgaW5kaWNhdGVzIHVzaW5nIHRoZSB0b3AgbGluZSB0byBjYWxjdWxhdGUKKyAgICAgKiBwbGFjZW1lbnQgb2YgZ3JhcGhpY3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVE9QX0FMSUdOTUVOVCA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEJPVFRPTV9BTElHTk1FTlQgaW5kaWNhdGVzIHVzaW5nIHRoZSBib3R0b20gbGluZSB0bworICAgICAqIGNhbGN1bGF0ZSBwbGFjZW1lbnQgb2YgZ3JhcGhpY3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQk9UVE9NX0FMSUdOTUVOVCA9IC0yOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFJPTUFOX0JBU0VMSU5FIGluZGljYXRlcyB0aGUgcGxhY2VtZW50IG9mIHRoZSByb21hbiBiYXNlbGluZQorICAgICAqIHdpdGggcmVzcGVjdCB0byB0aGUgZ3JhcGhpY3Mgb3JpZ2luLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPTUFOX0JBU0VMSU5FID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDRU5URVJfQkFTRUxJTkUgaW5kaWNhdGVzIHRoZSBwbGFjZW1lbnQgb2YgdGhlIGNlbnRlcgorICAgICAqIGJhc2VsaW5lIHdpdGggcmVzcGVjdCB0byB0aGUgZ3JhcGhpY3Mgb3JpZ2luLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENFTlRFUl9CQVNFTElORSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSEFOR0lOR19CQVNFTElORSBpbmRpY2F0ZXMgdGhlIHBsYWNlbWVudCBvZiB0aGUgaGFuZ2luZworICAgICAqIGJhc2VsaW5lIHdpdGggcmVzcGVjdCB0byB0aGUgZ3JhcGhpY3Mgb3JpZ2luLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhBTkdJTkdfQkFTRUxJTkUgPSAyOworCisgICAgLy8gdGhlIGFsaWdubWVudCBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUKKyAgICAvKioKKyAgICAgKiBUaGUgYWxpZ25tZW50LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGFsaWdubWVudDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBncmFwaGljIGF0dHJpYnV0ZSB3aXRoIHRoZSBzcGVjaWZpZWQgYWxpZ25tZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbGlnbgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBhbGlnbm1lbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEdyYXBoaWNBdHRyaWJ1dGUoaW50IGFsaWduKSB7CisgICAgICAgIGlmICgoYWxpZ24gPCBCT1RUT01fQUxJR05NRU5UKSB8fCAoYWxpZ24gPiBIQU5HSU5HX0JBU0VMSU5FKSkgeworICAgICAgICAgICAgLy8gYXd0LjE5OD1JbGxlZ2FsIGFsaWdubWVudCBhcmd1bWVudAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOTgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLmFsaWdubWVudCA9IGFsaWduOworICAgIH0KKworICAgIC8qKgorICAgICAqIERyYXdzIHRoZSBHcmFwaGljQXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGdyYXBoaWNzCisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgR3JhcGhpY0F0dHJpYnV0ZSBsb2NhdGlvbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiBHcmFwaGljQXR0cmlidXRlIGxvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRyYXcoR3JhcGhpY3MyRCBncmFwaGljcywgZmxvYXQgeCwgZmxvYXQgeSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBHcmFwaGljQXR0cmlidXRlJ3MgYWR2YW5jZS4gSXQncyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgcG9pbnQgYXQKKyAgICAgKiB3aGljaCB0aGUgZ3JhcGhpYyBpcyByZW5kZXJlZCBhbmQgdGhlIHBvaW50IHdoZXJlIHRoZSBuZXh0IGNoYXJhY3RlciBvcgorICAgICAqIGdyYXBoaWMgaXMgcmVuZGVyZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgR3JhcGhpY0F0dHJpYnV0ZSdzIGFkdmFuY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0IGdldEFkdmFuY2UoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFsaWdubWVudCBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYWxpZ25tZW50IG9mIHRoaXMgR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEFsaWdubWVudCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuYWxpZ25tZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFzY2VudCBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXNjZW50IG9mIHRoaXMgR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0QXNjZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhpcyBHcmFwaGljQXR0cmlidXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJvdW5kcyBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kcygpIHsKKyAgICAgICAgZmxvYXQgYXNjZW50ID0gZ2V0QXNjZW50KCk7CisgICAgICAgIGZsb2F0IGFkdmFuY2UgPSBnZXRBZHZhbmNlKCk7CisgICAgICAgIGZsb2F0IGRlc2NlbnQgPSBnZXREZXNjZW50KCk7CisKKyAgICAgICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiAtIHNlZSBBUEkgZG9jdW1lbnRhdGlvbi4KKyAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5GbG9hdCgwLCAtYXNjZW50LCBhZHZhbmNlLCBhc2NlbnQgKyBkZXNjZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZXNjZW50IG9mIHRoaXMgR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjZW50IG9mIHRoaXMgR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0RGVzY2VudCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBvZiB0aGlzIEdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2V0SnVzdGlmaWNhdGlvbkluZm8oKSB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbi4gU2luY2UgZG9jdW1lbnRhdGlvbiBkb2Vzbid0IGRlc2NyaWJlIGRlZmF1bHQKKyAgICAgICAgICogdmFsdWVzLCB0aGV5IHdlcmUgY2FsY3VsYXRlZCBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvciBhbmQgY2FuIGJlCisgICAgICAgICAqIG9idGFpbmVkIHVzaW5nIG5leHQgdGVzdCBzYW1wbGU6IC8vIENyZWF0ZSBHcmFwaGljQXR0cmlidXRlIGNsYXNzCisgICAgICAgICAqIGltcGxlbWVudGF0aW9uIHB1YmxpYyBjbGFzcyBNeUdyYXBoaWNBdHRyaWJ1dGUgZXh0ZW5kcworICAgICAgICAgKiBHcmFwaGljQXR0cmlidXRlIHsgcHJvdGVjdGVkIE15R3JhcGhpY0F0dHJpYnV0ZShpbnQgYWxpZ24pIHsKKyAgICAgICAgICogc3VwZXIoYWxpZ24pOyB9IHB1YmxpYyBmbG9hdCBnZXREZXNjZW50KCkgeyByZXR1cm4gMDsgfSBwdWJsaWMgZmxvYXQKKyAgICAgICAgICogZ2V0QWR2YW5jZSgpIHsgcmV0dXJuIDE7IH0gcHVibGljIHZvaWQgZHJhdyhHcmFwaGljczJEIGcyLCBmbG9hdCB4LAorICAgICAgICAgKiBmbG9hdCB5KSB7IH0gcHVibGljIGZsb2F0IGdldEFzY2VudCgpIHsgcmV0dXJuIDA7IH0gfQorICAgICAgICAgKiBNeUdyYXBoaWNBdHRyaWJ1dGUgbXlHQSA9IGdhdC5uZXcgTXlHcmFwaGljQXR0cmlidXRlKDApOyAvLyBwcmludAorICAgICAgICAgKiBqdXN0aWZpY2F0aW9uIHBhcmFtZXRlcnMKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKG15R0EuZ2V0SnVzdGlmaWNhdGlvbkluZm8oKS5ncm93QWJzb3JiKTsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKG15R0EuZ2V0SnVzdGlmaWNhdGlvbkluZm8oKS5zaHJpbmtBYnNvcmIpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4obXlHQS5nZXRKdXN0aWZpY2F0aW9uSW5mbygpLmdyb3dMZWZ0TGltaXQpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4obXlHQS5nZXRKdXN0aWZpY2F0aW9uSW5mbygpLmdyb3dQcmlvcml0eSk7CisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihteUdBLmdldEp1c3RpZmljYXRpb25JbmZvKCkuZ3Jvd1JpZ2h0TGltaXQpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4obXlHQS5nZXRKdXN0aWZpY2F0aW9uSW5mbygpLnNocmlua0xlZnRMaW1pdCk7CisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihteUdBLmdldEp1c3RpZmljYXRpb25JbmZvKCkuc2hyaW5rUHJpb3JpdHkpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4obXlHQS5nZXRKdXN0aWZpY2F0aW9uSW5mbygpLnNocmlua1JpZ2h0TGltaXQpOworICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4obXlHQS5nZXRKdXN0aWZpY2F0aW9uSW5mbygpLndlaWdodCk7CisgICAgICAgICAqLworICAgICAgICBmbG9hdCBhZHZhbmNlID0gZ2V0QWR2YW5jZSgpOworICAgICAgICByZXR1cm4gbmV3IEdseXBoSnVzdGlmaWNhdGlvbkluZm8oYWR2YW5jZSwgZmFsc2UsCisgICAgICAgICAgICAgICAgR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9JTlRFUkNIQVIsIGFkdmFuY2UgLyAzLCBhZHZhbmNlIC8gMywgZmFsc2UsCisgICAgICAgICAgICAgICAgR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9XSElURVNQQUNFLCAwLCAwKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L0ltYWdlR3JhcGhpY0F0dHJpYnV0ZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvSW1hZ2VHcmFwaGljQXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZkNDc1OAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9mb250L0ltYWdlR3JhcGhpY0F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5mb250OworCitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3MyRDsKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lm1pc2MuSGFzaENvZGU7CisKKy8qKgorICogVGhlIEltYWdlR3JhcGhpY0F0dHJpYnV0ZSBjbGFzcyBwcm92aWRlcyBhbiBvcHBvcnR1bml0eSB0byBpbnNlcnQgaW1hZ2VzIHRvIGEKKyAqIHRleHQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW1hZ2VHcmFwaGljQXR0cmlidXRlIGV4dGVuZHMgR3JhcGhpY0F0dHJpYnV0ZSB7CisKKyAgICAvLyBJbWFnZSBvYmplY3QgcmVuZGVyZWQgYnkgdGhpcyBJbWFnZUdyYXBoaWNBdHRyaWJ1dGUKKyAgICAvKioKKyAgICAgKiBUaGUgaW1hZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBJbWFnZSBmSW1hZ2U7CisKKyAgICAvLyBYIGNvb3JkaW5hdGUgb2YgdGhlIG9yaWdpbiBwb2ludAorICAgIC8qKgorICAgICAqIFRoZSBvcmlnaW4geC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGZPcmlnaW5YOworCisgICAgLy8gWSBjb29yZGluYXRlIG9mIHRoZSBvcmlnaW4gcG9pbnQKKyAgICAvKioKKyAgICAgKiBUaGUgb3JpZ2luIHkuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBmT3JpZ2luWTsKKworICAgIC8vIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2Ugb2JqZWN0CisgICAgLyoqCisgICAgICogVGhlIGltZyB3aWR0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGZJbWdXaWR0aDsKKworICAgIC8vIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIG9iamVjdAorICAgIC8qKgorICAgICAqIFRoZSBpbWcgaGVpZ2h0LgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgZkltZ0hlaWdodDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZUdyYXBoaWNBdHRyaWJ1dGUgd2l0aCB0aGUgc3BlY2lmaWVkIGltYWdlLAorICAgICAqIGFsaWdubWVudCBhbmQgb3JpZ2lucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZSB0byBiZSByZW5kZXJlZCBieSBJbWFnZUdyYXBoaWNBdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIGFsaWdubWVudAorICAgICAqICAgICAgICAgICAgdGhlIGFsaWdubWVudCBvZiB0aGUgSW1hZ2VHcmFwaGljQXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBvcmlnaW5YCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luIFggY29vcmRpbmF0ZSBpbiB0aGUgaW1hZ2Ugb2YgSW1hZ2VHcmFwaGljQXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBvcmlnaW5ZCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luIFkgY29vcmRpbmF0ZSBpbiB0aGUgaW1hZ2Ugb2YgSW1hZ2VHcmFwaGljQXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZUdyYXBoaWNBdHRyaWJ1dGUoSW1hZ2UgaW1hZ2UsIGludCBhbGlnbm1lbnQsIGZsb2F0IG9yaWdpblgsIGZsb2F0IG9yaWdpblkpIHsKKyAgICAgICAgc3VwZXIoYWxpZ25tZW50KTsKKworICAgICAgICB0aGlzLmZJbWFnZSA9IGltYWdlOworICAgICAgICB0aGlzLmZPcmlnaW5YID0gb3JpZ2luWDsKKyAgICAgICAgdGhpcy5mT3JpZ2luWSA9IG9yaWdpblk7CisKKyAgICAgICAgdGhpcy5mSW1nV2lkdGggPSBmSW1hZ2UuZ2V0V2lkdGgobnVsbCk7CisgICAgICAgIHRoaXMuZkltZ0hlaWdodCA9IGZJbWFnZS5nZXRIZWlnaHQobnVsbCk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VHcmFwaGljQXR0cmlidXRlIHdpdGggdGhlIHNwZWNpZmllZCBpbWFnZSBhbmQKKyAgICAgKiBhbGlnbm1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2UgdG8gYmUgcmVuZGVyZWQgYnkgSW1hZ2VHcmFwaGljQXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBhbGlnbm1lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlnbm1lbnQgb2YgdGhlIEltYWdlR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VHcmFwaGljQXR0cmlidXRlKEltYWdlIGltYWdlLCBpbnQgYWxpZ25tZW50KSB7CisgICAgICAgIHRoaXMoaW1hZ2UsIGFsaWdubWVudCwgMCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBvZiB0aGlzIEltYWdlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgSW1hZ2VHcmFwaGljQXR0cmlidXRlIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBIYXNoQ29kZSBoYXNoID0gbmV3IEhhc2hDb2RlKCk7CisKKyAgICAgICAgaGFzaC5hcHBlbmQoZkltYWdlLmhhc2hDb2RlKCkpOworICAgICAgICBoYXNoLmFwcGVuZChnZXRBbGlnbm1lbnQoKSk7CisgICAgICAgIHJldHVybiBoYXNoLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBJbWFnZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0IHdpdGggdGhpcworICAgICAqIEltYWdlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGlnYQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIEltYWdlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QgaXMgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgIHRoaXMgSW1hZ2VHcmFwaGljQXR0cmlidXRlIG9iamVjdCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhJbWFnZUdyYXBoaWNBdHRyaWJ1dGUgaWdhKSB7CisgICAgICAgIGlmIChpZ2EgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlnYSA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoZk9yaWdpblggPT0gaWdhLmZPcmlnaW5YICYmIGZPcmlnaW5ZID09IGlnYS5mT3JpZ2luWQorICAgICAgICAgICAgICAgICYmIGdldEFsaWdubWVudCgpID09IGlnYS5nZXRBbGlnbm1lbnQoKSAmJiBmSW1hZ2UuZXF1YWxzKGlnYS5mSW1hZ2UpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIE9iamVjdCB3aXRoIHRoaXMgSW1hZ2VHcmFwaGljQXR0cmlidXRlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBPYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAgSW1hZ2VHcmFwaGljQXR0cmlidXRlIG9iamVjdCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZXF1YWxzKChJbWFnZUdyYXBoaWNBdHRyaWJ1dGUpb2JqKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhdyhHcmFwaGljczJEIGcyLCBmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIGcyLmRyYXdJbWFnZShmSW1hZ2UsIChpbnQpKHggLSBmT3JpZ2luWCksIChpbnQpKHkgLSBmT3JpZ2luWSksIG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRBZHZhbmNlKCkgeworICAgICAgICByZXR1cm4gTWF0aC5tYXgoMCwgZkltZ1dpZHRoIC0gZk9yaWdpblgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRBc2NlbnQoKSB7CisgICAgICAgIHJldHVybiBNYXRoLm1heCgwLCBmT3JpZ2luWSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5GbG9hdCgtZk9yaWdpblgsIC1mT3JpZ2luWSwgZkltZ1dpZHRoLCBmSW1nSGVpZ2h0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RGVzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIGZJbWdIZWlnaHQgLSBmT3JpZ2luWSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9MaW5lQnJlYWtNZWFzdXJlci5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvTGluZUJyZWFrTWVhc3VyZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODAwMDkzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvTGluZUJyZWFrTWVhc3VyZXIuamF2YQpAQCAtMCwwICsxLDIzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmZvbnQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOyAvLz8/P0FXVDogaW1wb3J0IGphdmEudGV4dC5CcmVha0l0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIGNsYXNzIExpbmVCcmVha01lYXN1cmVyIHByb3ZpZGVzIG1ldGhvZHMgdG8gbWVhc3VyZSB0aGUgZ3JhcGhpY2FsCisgKiByZXByZXNlbnRhdGlvbiBvZiBhIHRleHQgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIHdoZXJlIHRvIGFkZCBsaW5lIGJyZWFrcyBzbworICogdGhlIHJlc3VsdGluZyBsaW5lIG9mIHRleHQgZml0cyBpdHMgd3JhcHBpbmcgd2lkdGguIFRoZSB3cmFwcGluZyB3aWR0aAorICogZGVmaW5lcyB0aGUgdmlzdWFsIHdpZHRoIG9mIHRoZSBwYXJhZ3JhcGguCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTGluZUJyZWFrTWVhc3VyZXIgeworCisgICAgLyoqCisgICAgICogVGhlIHRtLgorICAgICAqLworICAgIHByaXZhdGUgVGV4dE1lYXN1cmVyIHRtID0gbnVsbDsKKworICAgIC8vID8/P0FXVCBwcml2YXRlIEJyZWFrSXRlcmF0b3IgYmkgPSBudWxsOworICAgIC8qKgorICAgICAqIFRoZSBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBwb3NpdGlvbiA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4cG9zLgorICAgICAqLworICAgIGludCBtYXhwb3MgPSAwOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IExpbmVCcmVha01lYXN1cmVyIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCB0ZXh0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0ZXh0CisgICAgICogICAgICAgICAgICB0aGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIG9iamVjdCB3aGljaCBjb250YWlucyB0ZXh0CisgICAgICogICAgICAgICAgICB3aXRoIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIuCisgICAgICogQHBhcmFtIGZyYworICAgICAqICAgICAgICAgICAgdGhlIEZvbnRSZW5kZXJDb250ZXh0IHJlcHJlc2VudGVkIGluZm9ybWF0aW9uIGFib3V0IGdyYXBoaWMKKyAgICAgKiAgICAgICAgICAgIGRldmljZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZUJyZWFrTWVhc3VyZXIoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIHRleHQsIEZvbnRSZW5kZXJDb250ZXh0IGZyYykgeworICAgICAgICAvLyA/Pz9BV1Q6IHRoaXModGV4dCwgQnJlYWtJdGVyYXRvci5nZXRMaW5lSW5zdGFuY2UoKSwgZnJjKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqID8/P0FXVCBwdWJsaWMgTGluZUJyZWFrTWVhc3VyZXIoIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LAorICAgICAqIEJyZWFrSXRlcmF0b3IgYmksIEZvbnRSZW5kZXJDb250ZXh0IGZyYyApIHsgdG0gPSBuZXcgVGV4dE1lYXN1cmVyKHRleHQsCisgICAgICogZnJjKTsgdGhpcy5iaSA9IGJpOyB0aGlzLmJpLnNldFRleHQodGV4dCk7IHBvc2l0aW9uID0KKyAgICAgKiB0ZXh0LmdldEJlZ2luSW5kZXgoKTsgbWF4cG9zID0gdG0uYWNpLmdldEVuZEluZGV4KCk7IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgYSBjaGFyYWN0ZXIgZnJvbSB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIG9mIHRoZSB0ZXh0LCB1cGRhdGVzIHRoaXMKKyAgICAgKiBMaW5lQnJlYWtNZWFzdXJlciBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG5ld1RleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdGV4dC4KKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciB3aGljaCBpcyBkZWxldGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUNoYXIoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIG5ld1RleHQsIGludCBwb3MpIHsKKyAgICAgICAgdG0uZGVsZXRlQ2hhcihuZXdUZXh0LCBwb3MpOworICAgICAgICAvLyA/Pz9BV1Q6IGJpLnNldFRleHQobmV3VGV4dCk7CisKKyAgICAgICAgcG9zaXRpb24gPSBuZXdUZXh0LmdldEJlZ2luSW5kZXgoKTsKKworICAgICAgICBtYXhwb3MtLTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhpcyBMaW5lQnJlYWtNZWFzdXJlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoaXMgTGluZUJyZWFrTWVhc3VyZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgeworICAgICAgICByZXR1cm4gcG9zaXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyBhIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoZSB0ZXh0LCB1cGRhdGVzIHRoaXMKKyAgICAgKiBMaW5lQnJlYWtNZWFzdXJlciBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG5ld1RleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdGV4dC4KKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciB3aGljaCBpcyBpbnNlcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbnNlcnRDaGFyKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBuZXdUZXh0LCBpbnQgcG9zKSB7CisgICAgICAgIHRtLmluc2VydENoYXIobmV3VGV4dCwgcG9zKTsKKyAgICAgICAgLy8gPz8/QVdUOiBiaS5zZXRUZXh0KG5ld1RleHQpOworCisgICAgICAgIHBvc2l0aW9uID0gbmV3VGV4dC5nZXRCZWdpbkluZGV4KCk7CisKKyAgICAgICAgbWF4cG9zKys7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBsaW5lIG9mIHRleHQsIHVwZGF0ZXMgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzCisgICAgICogTGluZUJyZWFrTWVhc3VyZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHdyYXBwaW5nV2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIHZpc2libGUgbGluZSB3aWR0aC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0TGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaW1pdCBwb2ludCB3aXRoaW4gdGhlIHRleHQgaW5kaWNhdGluZyB0aGF0IG5vIGZ1cnRoZXIKKyAgICAgKiAgICAgICAgICAgIHRleHQgc2hvdWxkIGJlIGluY2x1ZGVkIG9uIHRoZSBsaW5lOyB0aGUgcGFyYWdyYXBoIGJyZWFrLgorICAgICAqIEBwYXJhbSByZXF1aXJlTmV4dFdvcmQKKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUsIG51bGwgaXMgcmV0dXJuZWQgKHRoZSBlbnRpcmUgd29yZCBhdCB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgcG9zaXRpb24gZG9lcyBub3QgZml0IHdpdGhpbiB0aGUgd3JhcHBpbmcgd2lkdGgpOyBpZiBmYWxzZSwgYQorICAgICAqICAgICAgICAgICAgdmFsaWQgbGF5b3V0IGlzIHJldHVybmVkIHRoYXQgaW5jbHVkZXMgYXQgbGVhc3QgdGhlIGNoYXJhY3RlcgorICAgICAqICAgICAgICAgICAgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQHJldHVybiB0aGUgbmV4dCBUZXh0TGF5b3V0IHdoaWNoIGJlZ2lucyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudHMgdGhlIG5leHQgbGluZSBvZiB0ZXh0IHdpdGggd2lkdGggd3JhcHBpbmdXaWR0aCwgbnVsbAorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIGVudGlyZSB3b3JkIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGRvZXMgbm90CisgICAgICogICAgICAgICBmaXQgd2l0aGluIHRoZSB3cmFwcGluZyB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dExheW91dCBuZXh0TGF5b3V0KGZsb2F0IHdyYXBwaW5nV2lkdGgsIGludCBvZmZzZXRMaW1pdCwgYm9vbGVhbiByZXF1aXJlTmV4dFdvcmQpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IG1heHBvcykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbmV4dFBvc2l0aW9uID0gbmV4dE9mZnNldCh3cmFwcGluZ1dpZHRoLCBvZmZzZXRMaW1pdCwgcmVxdWlyZU5leHRXb3JkKTsKKworICAgICAgICBpZiAobmV4dFBvc2l0aW9uID09IHBvc2l0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBUZXh0TGF5b3V0IGxheW91dCA9IHRtLmdldExheW91dChwb3NpdGlvbiwgbmV4dFBvc2l0aW9uKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXh0UG9zaXRpb247CisgICAgICAgIHJldHVybiBsYXlvdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBsaW5lIG9mIHRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIHdyYXBwaW5nV2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIHZpc2libGUgbGluZSB3aWR0aC4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGxpbmUgb2YgdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dExheW91dCBuZXh0TGF5b3V0KGZsb2F0IHdyYXBwaW5nV2lkdGgpIHsKKyAgICAgICAgcmV0dXJuIG5leHRMYXlvdXQod3JhcHBpbmdXaWR0aCwgbWF4cG9zLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5kIHBvc2l0aW9uIG9mIHRoZSBuZXh0IGxpbmUgb2YgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd3JhcHBpbmdXaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gdmlzaWJsZSBsaW5lIHdpZHRoLgorICAgICAqIEByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsaW5lIG9mIHRleHQuCisgICAgICovCisgICAgcHVibGljIGludCBuZXh0T2Zmc2V0KGZsb2F0IHdyYXBwaW5nV2lkdGgpIHsKKyAgICAgICAgcmV0dXJuIG5leHRPZmZzZXQod3JhcHBpbmdXaWR0aCwgbWF4cG9zLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5kIHBvc2l0aW9uIG9mIHRoZSBuZXh0IGxpbmUgb2YgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd3JhcHBpbmdXaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gdmlzaWJsZSBsaW5lIHdpZHRoLgorICAgICAqIEBwYXJhbSBvZmZzZXRMaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGxpbWl0IHBvaW50IHdpdGhpbmcgdGhlIHRleHQgaW5kaWNhdGluZyB0aGF0IG5vIGZ1cnRoZXIKKyAgICAgKiAgICAgICAgICAgIHRleHQgc2hvdWxkIGJlIGluY2x1ZGVkIG9uIHRoZSBsaW5lOyB0aGUgcGFyYWdyYXBoIGJyZWFrLgorICAgICAqIEBwYXJhbSByZXF1aXJlTmV4dFdvcmQKKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUsIHRoZSBjdXJyZW50IHBvc2l0aW9uIGlzIHJldHVybmVkIGlmIHRoZSBlbnRpcmUgbmV4dAorICAgICAqICAgICAgICAgICAgd29yZCBkb2VzIG5vdCBmaXQgd2l0aGluIHdyYXBwaW5nV2lkdGg7IGlmIGZhbHNlLCB0aGUgb2Zmc2V0CisgICAgICogICAgICAgICAgICByZXR1cm5lZCBpcyBhdCBsZWFzdCBvbmUgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsaW5lIG9mIHRleHQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2Zmc2V0TGltaXQgaXMgbGVzcyB0aGFuIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbmV4dE9mZnNldChmbG9hdCB3cmFwcGluZ1dpZHRoLCBpbnQgb2Zmc2V0TGltaXQsIGJvb2xlYW4gcmVxdWlyZU5leHRXb3JkKSB7CisgICAgICAgIGlmIChvZmZzZXRMaW1pdCA8PSBwb3NpdGlvbikgeworICAgICAgICAgICAgLy8gYXd0LjIwMz1PZmZzZXQgbGltaXQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBjdXJyZW50IHBvc2l0aW9uLgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBtYXhwb3MpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBicmVha1BvcyA9IHRtLmdldExpbmVCcmVha0luZGV4KHBvc2l0aW9uLCB3cmFwcGluZ1dpZHRoKTsKKyAgICAgICAgaW50IGNvcnJlY3RlZFBvcyA9IGJyZWFrUG9zOworCisgICAgICAgIC8vIFRoaXMgY2hlY2sgaXMgcmVxdWlyZWQgYmVjYXVzZSBiaS5wcmVjZWRpbmcobWF4cG9zKSB0aHJvd3MgYW4KKyAgICAgICAgLy8gZXhjZXB0aW9uCisgICAgICAgIC8qCisgICAgICAgICAqID8/P0FXVCBpZiAoYnJlYWtQb3MgPT0gbWF4cG9zKSB7IGNvcnJlY3RlZFBvcyA9IG1heHBvczsgfSBlbHNlIGlmCisgICAgICAgICAqIChDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKGJpLmdldFRleHQoKS5zZXRJbmRleChicmVha1BvcykpKSB7CisgICAgICAgICAqIGNvcnJlY3RlZFBvcyA9IGJpLmZvbGxvd2luZyhicmVha1Bvcyk7IH0gZWxzZSB7IGNvcnJlY3RlZFBvcyA9CisgICAgICAgICAqIGJpLnByZWNlZGluZyhicmVha1Bvcyk7IH0KKyAgICAgICAgICovCisKKyAgICAgICAgaWYgKHBvc2l0aW9uID49IGNvcnJlY3RlZFBvcykgeworICAgICAgICAgICAgaWYgKHJlcXVpcmVOZXh0V29yZCkgeworICAgICAgICAgICAgICAgIGNvcnJlY3RlZFBvcyA9IHBvc2l0aW9uOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjb3JyZWN0ZWRQb3MgPSBNYXRoLm1heChwb3NpdGlvbiArIDEsIGJyZWFrUG9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBNYXRoLm1pbihjb3JyZWN0ZWRQb3MsIG9mZnNldExpbWl0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuZXcgcG9zaXRpb24gb2YgdGhpcyBMaW5lQnJlYWtNZWFzdXJlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHBvc2l0aW9uIG9mIHRoaXMgTGluZUJyZWFrTWVhc3VyZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UG9zaXRpb24oaW50IHBvcykgeworICAgICAgICBpZiAodG0uYWNpLmdldEJlZ2luSW5kZXgoKSA+IHBvcyB8fCBtYXhwb3MgPCBwb3MpIHsKKyAgICAgICAgICAgIC8vIGF3dC4zMz1pbmRleCBpcyBvdXQgb2YgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMzMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbiA9IHBvczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9MaW5lTWV0cmljcy5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvTGluZU1ldHJpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YjAzZTVkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvTGluZU1ldHJpY3MuamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworLyoqCisgKiBUaGUgTGluZU1ldHJpY3MgY2xhc3MgcHJvdmlkZXMgaW5mb3JtYXRpb24gc3VjaCBhcyBjb25jZXJuaW5nIGhvdyB0aGUgdGV4dCBpcworICogcG9zaXRpb25lZCB3aXRoIHJlc3BlY3QgdG8gdGhlIGJhc2UgbGluZSwgc3VjaCBhcyBhc2NlbnQsIGRlc2NlbnQsIGFuZAorICogbGVhZGluZy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBMaW5lTWV0cmljcyB7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBiYXNlbGluZSBvZmZzZXRzIG9mIHRoZSB0ZXh0IGFjY29yZGluZyB0byB0aGUgdGhlIGJhc2VsaW5lIG9mCisgICAgICogdGhpcyB0ZXh0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJhc2VsaW5lIG9mZnNldHMgb2YgdGhlIHRleHQgYWNjb3JkaW5nIHRvIHRoZSB0aGUgYmFzZWxpbmUgb2YKKyAgICAgKiAgICAgICAgIHRoaXMgdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXRbXSBnZXRCYXNlbGluZU9mZnNldHMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRoZSB0ZXh0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRoZSB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TnVtQ2hhcnMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJhc2VsaW5lIGluZGV4LCByZXR1cm5zIG9uZSBvZiB0aGUgZm9sbG93aW5nIGluZGV4OgorICAgICAqIFJPTUFOX0JBU0VMSU5FLCBDRU5URVJfQkFTRUxJTkUsIEhBTkdJTkdfQkFTRUxJTkUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmFzZWxpbmUgaW5kZXg6IFJPTUFOX0JBU0VMSU5FLCBDRU5URVJfQkFTRUxJTkUgb3IKKyAgICAgKiAgICAgICAgIEhBTkdJTkdfQkFTRUxJTkUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRCYXNlbGluZUluZGV4KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aGlja25lc3Mgb2YgdGhlIHVuZGVybGluZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0aGlja25lc3Mgb2YgdGhlIHVuZGVybGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0VW5kZXJsaW5lVGhpY2tuZXNzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvZmZzZXQgb2YgdGhlIHVuZGVybGluZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIHVuZGVybGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0VW5kZXJsaW5lT2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aGlja25lc3Mgb2Ygc3RyaWtlIHRocm91Z2ggbGluZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0aGlja25lc3Mgb2Ygc3RyaWtlIHRocm91Z2ggbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0U3RyaWtldGhyb3VnaFRoaWNrbmVzcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBzdHJpa2UgdGhyb3VnaCBsaW5lLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgc3RyaWtlIHRocm91Z2ggbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZmxvYXQgZ2V0U3RyaWtldGhyb3VnaE9mZnNldCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbGVhZGluZyBvZiB0aGUgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBsZWFkaW5nIG9mIHRoZSB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXRMZWFkaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIHRleHQgYXMgYSBzdW0gb2YgdGhlIGFzY2VudCwgdGhlIGRlc2NlbnQgYW5kIHRoZQorICAgICAqIGxlYWRpbmcuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGVpZ2h0IG9mIHRoZSB0ZXh0IGFzIGEgc3VtIG9mIHRoZSBhc2NlbnQsIHRoZSBkZXNjZW50IGFuZAorICAgICAqICAgICAgICAgdGhlIGxlYWRpbmcuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0IGdldEhlaWdodCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVzY2VudCBvZiB0aGUgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjZW50IG9mIHRoZSB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXREZXNjZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhc2NlbnQgb2YgdGhlIHRleHQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXNjZW50IG9mIHRoZSB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXRBc2NlbnQoKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ZvbnQvTXVsdGlwbGVNYXN0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9mb250L011bHRpcGxlTWFzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI2NGYyNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9mb250L011bHRpcGxlTWFzdGVyLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CisKKy8qKgorICogVGhlIE11bHRpcGxlTWFzdGVyIGludGVyZmFjZSBwcm92aWRlcyBtZXRob2RzIHRvIG1hbmlwdWxhdGUgTXVsdGlwbGVNYXN0ZXIKKyAqIHR5cGUgZm9udHMgYW5kIHJldHJpZXZlIGdyYXBoaWNhbCBhbmQgZGVzaWduIGRhdGEgZnJvbSB0aGVtLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBNdWx0aXBsZU1hc3RlciB7CisKKyAgICAvKioKKyAgICAgKiBEZXJpdmVzIGEgbmV3IG11bHRpcGxlIG1hc3RlciBmb250IGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhXaWR0aHMKKyAgICAgKiAgICAgICAgICAgIGZsb2F0IGFycmF5IHdoaWNoIHJlcHJlc2VudHMgd2lkdGggb2YgZWFjaCBnbHlwaCBpbiBmb250CisgICAgICogICAgICAgICAgICBzcGFjZS4KKyAgICAgKiBAcGFyYW0gYXZnU3RlbVdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgYXZlcmFnZSBzdGVtIHdpZHRoIGluIGZvbnQgc3BhY2UuCisgICAgICogQHBhcmFtIHR5cGljYWxDYXBIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBpY2FsIHVwcGVyIGNhc2UgY2hhciBoZWlnaHQuCisgICAgICogQHBhcmFtIHR5cGljYWxYSGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgdHlwaWNhbCBsb3dlciBjYXNlIGNoYXIgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBpdGFsaWNBbmdsZQorICAgICAqICAgICAgICAgICAgdGhlIHNsb3BlIGFuZ2xlIGZvciBpdGFsaWNzLgorICAgICAqIEByZXR1cm4gYSBNdWx0aXBsZU1hc3RlciBmb250LgorICAgICAqLworICAgIHB1YmxpYyBGb250IGRlcml2ZU1NRm9udChmbG9hdFtdIGdseXBoV2lkdGhzLCBmbG9hdCBhdmdTdGVtV2lkdGgsIGZsb2F0IHR5cGljYWxDYXBIZWlnaHQsCisgICAgICAgICAgICBmbG9hdCB0eXBpY2FsWEhlaWdodCwgZmxvYXQgaXRhbGljQW5nbGUpOworCisgICAgLyoqCisgICAgICogRGVyaXZlcyBhIG5ldyBtdWx0aXBsZSBtYXN0ZXIgZm9udCBiYXNlZCBvbiB0aGUgZGVzaWduIGF4aXMgdmFsdWVzCisgICAgICogY29udGFpbmVkIGluIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIGF4ZXMKKyAgICAgKiAgICAgICAgICAgIGFuIGZsb2F0IGFycmF5IHdoaWNoIGNvbnRhaW5zIGF4aXMgdmFsdWVzLgorICAgICAqIEByZXR1cm4gYSBNdWx0aXBsZU1hc3RlciBmb250LgorICAgICAqLworICAgIHB1YmxpYyBGb250IGRlcml2ZU1NRm9udChmbG9hdFtdIGF4ZXMpOworCisgICAgLyoqCisgICAgICogR2V0cyBkZWZhdWx0IGRlc2lnbiB2YWx1ZXMgZm9yIHRoZSBheGVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgZGVzaWduIHZhbHVlcyBmb3IgdGhlIGF4ZXMuCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0RGVzaWduQXhpc0RlZmF1bHRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBkZXNpZ24gYXhpcyBuYW1lcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBkZXNpZ24gYXhpcyBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVzaWduQXhpc05hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBkZXNpZ24gYXhpcyByYW5nZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZGVzaWduIGF4aXMgcmFuZ2VzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldERlc2lnbkF4aXNSYW5nZXMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBtdWx0aXBsZSBtYXN0ZXIgZGVzaWduIGNvbnRyb2xzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtdWx0aXBsZSBtYXN0ZXIgZGVzaWduIGNvbnRyb2xzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtRGVzaWduQXhlcygpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9PcGVuVHlwZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvT3BlblR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjY2OTExCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvT3BlblR5cGUuamF2YQpAQCAtMCwwICsxLDQxOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworLyoqCisgKiBUaGUgT3BlblR5cGUgaW50ZXJmYWNlIHByb3ZpZGVzIGNvbnN0YW50cyBhbmQgbWV0aG9kcyBmb3IgZ2V0dGluZyBpbnN0YW5jZQorICogZGF0YSBmb3IgZm9udHMgb2YgdHlwZSBPcGVuVHlwZSBhbmQgVHJ1ZVR5cGUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlCisgKiA8YQorICogaHJlZj0iaHR0cDovL3BhcnRuZXJzLmFkb2JlLmNvbS9wdWJsaWMvZGV2ZWxvcGVyL29wZW50eXBlL2luZGV4X3NwZWMuaHRtbCI+CisgKiBPcGVuVHlwZSBzcGVjaWZpY2F0aW9uPC9hPi4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgT3BlblR5cGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19BQ05UIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfQUNOVCA9IDE2MzM5MDYyOTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0FWQVIgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19BVkFSID0gMTYzNTE0ODE0NjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfQkFTRSBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0JBU0UgPSAxMTExNTc3NDEzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19CREFUIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfQkRBVCA9IDE2NTA3NDU3MTY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0JMT0MgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19CTE9DID0gMTY1MTI3MzU3MTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfQlNMTiBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0JTTE4gPSAxNjUxNzMxNTY2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19DRkYgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19DRkYgPSAxMTI4Njc4OTQ0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19DTUFQIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfQ01BUCA9IDE2NjgxMTI3NTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0NWQVIgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19DVkFSID0gMTY2ODcwMjU3ODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfQ1ZUIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfQ1ZUID0gMTY2ODcwNzM2MDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfRFNJRyBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0RTSUcgPSAxMTQ2MzA4OTM1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19FQkRUIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfRUJEVCA9IDExNjE5NzA3NzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0VCTEMgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19FQkxDID0gMTE2MTk3MjgwMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfRUJTQyBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0VCU0MgPSAxMTYxOTc0NTk1OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19GRFNDIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfRkRTQyA9IDE3MTc4NTkxNzE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0ZFQVQgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19GRUFUID0gMTcxNzkyMDExNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfRk1UWCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0ZNVFggPSAxNzE4NDQ5MjcyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19GUEdNIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfRlBHTSA9IDE3MTg2NDI1NDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0ZWQVIgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19GVkFSID0gMTcxOTAzNDIyNjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfR0FTUCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0dBU1AgPSAxNzM0NDM5NzkyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19HREVGIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfR0RFRiA9IDExOTU2NTY1MTg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0dMWUYgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19HTFlGID0gMTczNTE2MjIxNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfR1BPUyBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0dQT1MgPSAxMTk2NDQ1NTIzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19HU1VCIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfR1NVQiA9IDExOTY2NDM2NTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0dWQVIgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19HVkFSID0gMTczNTgxMTQ0MjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfSERNWCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0hETVggPSAxNzUxNDEyMDg4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19IRUFEIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfSEVBRCA9IDE3NTE0NzQ1MzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0hIRUEgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19ISEVBID0gMTc1MTY3MjE2MTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfSE1UWCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0hNVFggPSAxNzUyMDAzNzA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19KU1RGIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfSlNURiA9IDEyNDY5NzUwNDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0pVU1QgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19KVVNUID0gMTc4NjA4MjE2NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfS0VSTiBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0tFUk4gPSAxODAxODEwNTQyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19MQ0FSIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfTENBUiA9IDE4MTg0NTIzMzg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX0xPQ0EgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19MT0NBID0gMTgxOTIzOTI2NTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfTFRTSCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX0xUU0ggPSAxMjgwNTk0NzYwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19NQVhQIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfTUFYUCA9IDE4MzUxMDQzNjg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX01NRlggaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19NTUZYID0gMTI5NjkwOTkxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfTU1TRCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX01NU0QgPSAxMjk2OTEzMjIwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19NT1JUIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfTU9SVCA9IDE4MzYwMjAzNDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX05BTUUgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19OQU1FID0gMTg1MTg3ODc1NzsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfT1BCRCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX09QQkQgPSAxODM2MDIwMzQwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19PUzIgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19PUzIgPSAxMzMwODUxNjM0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19QQ0xUIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfUENMVCA9IDEzNDY1ODc3MzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX1BPU1QgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19QT1NUID0gMTg4NjM1MjI0NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfUFJFUCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX1BSRVAgPSAxODg2NTQ1MjY0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19QUk9QIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfUFJPUCA9IDE4ODY1NDc4MjQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX1RSQUsgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19UUkFLID0gMTk1MzY1MzA5OTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfVFlQMSBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX1RZUDEgPSAxOTU0MTE1NjMzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRBR19WRE1YIGluZGljYXRlcyBjb3JyZXNwb25kaW5nIHRhYmxlIHRhZyBpbiB0aGUgT3BlbiBUeXBlCisgICAgICogU3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUdfVkRNWCA9IDE0NDczMTY4MjQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVEFHX1ZIRUEgaW5kaWNhdGVzIGNvcnJlc3BvbmRpbmcgdGFibGUgdGFnIGluIHRoZSBPcGVuIFR5cGUKKyAgICAgKiBTcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBR19WSEVBID0gMTk4NjU1MzE4NTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUQUdfVk1UWCBpbmRpY2F0ZXMgY29ycmVzcG9uZGluZyB0YWJsZSB0YWcgaW4gdGhlIE9wZW4gVHlwZQorICAgICAqIFNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFHX1ZNVFggPSAxOTg2ODg0NzI4OworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgT3BlblR5cGUgZm9udCB2ZXJzaW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRoZSBPcGVuVHlwZSBmb250IHZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0YWJsZSBmb3IgYSBzcGVjaWZpZWQgdGFnLiBTZm50IHRhYmxlcyBpbmNsdWRlIGNtYXAsIG5hbWUgYW5kCisgICAgICogaGVhZCBpdGVtcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2ZudFRhZworICAgICAqICAgICAgICAgICAgdGhlIHNmbnQgdGFnLgorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IGNvbnRhaW5zIHRoZSBmb250IGRhdGEgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCB0YWcuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRGb250VGFibGUoaW50IHNmbnRUYWcpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGFibGUgZm9yIGEgc3BlY2lmaWVkIHRhZy4gU2ZudCB0YWJsZXMgaW5jbHVkZSBjbWFwLCBuYW1lIGFuZAorICAgICAqIGhlYWQgaXRlbXMuCisgICAgICogCisgICAgICogQHBhcmFtIHNmbnRUYWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZm50IHRhZy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSByZXR1cm5lZCB0YWJsZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgcmV0dXJuZWQgdGFibGUuCisgICAgICogQHJldHVybiB0aGUgdGFibGUgY29ycmVzcG9uZGluZyB0byBzZm50VGFnIGFuZCBjb250YWluaW5nIHRoZSBieXRlcworICAgICAqICAgICAgICAgc3RhcnRpbmcgYXQgb2Zmc2V0IGJ5dGUgYW5kIGluY2x1ZGluZyBjb3VudCBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEZvbnRUYWJsZShpbnQgc2ZudFRhZywgaW50IG9mZnNldCwgaW50IGNvdW50KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRhYmxlIGZvciBhIHNwZWNpZmllZCB0YWcuIFNmbnQgdGFibGVzIGluY2x1ZGUgY21hcCwgbmFtZSBhbmQKKyAgICAgKiBoZWFkIGl0ZW1zLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJTZm50VGFnCisgICAgICogICAgICAgICAgICB0aGUgc3RyIHNmbnQgdGFnIGFzIGEgU3RyaW5nLgorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IGNvbnRhaW5zIHRoZSBmb250IGRhdGEgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCB0YWcuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRGb250VGFibGUoU3RyaW5nIHN0clNmbnRUYWcpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGFibGUgZm9yIGEgc3BlY2lmaWVkIHRhZy4gU2ZudCB0YWJsZXMgaW5jbHVkZSBjbWFwLCBuYW1lIGFuZAorICAgICAqIGhlYWQgaXRlbXMuCisgICAgICogCisgICAgICogQHBhcmFtIHN0clNmbnRUYWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZm50IHRhZyBhcyBhIFN0cmluZy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSByZXR1cm5lZCB0YWJsZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgcmV0dXJuZWQgdGFibGUuCisgICAgICogQHJldHVybiB0aGUgdGFibGUgY29ycmVzcG9uZGluZyB0byBzZm50VGFnIGFuZCBjb250YWluaW5nIHRoZSBieXRlcworICAgICAqICAgICAgICAgc3RhcnRpbmcgYXQgb2Zmc2V0IGJ5dGUgYW5kIGluY2x1ZGluZyBjb3VudCBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEZvbnRUYWJsZShTdHJpbmcgc3RyU2ZudFRhZywgaW50IG9mZnNldCwgaW50IGNvdW50KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRhYmxlIHNpemUgZm9yIGEgc3BlY2lmaWVkIHRhZy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyU2ZudFRhZworICAgICAqICAgICAgICAgICAgdGhlIHNmbnQgdGFnIGFzIGEgU3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIHRhYmxlIHNpemUgZm9yIGEgc3BlY2lmaWVkIHRhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEZvbnRUYWJsZVNpemUoU3RyaW5nIHN0clNmbnRUYWcpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGFibGUgc2l6ZSBmb3IgYSBzcGVjaWZpZWQgdGFnLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzZm50VGFnCisgICAgICogICAgICAgICAgICB0aGUgc2ZudCB0YWcuCisgICAgICogQHJldHVybiB0aGUgdGFibGUgc2l6ZSBmb3IgYSBzcGVjaWZpZWQgdGFnLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Rm9udFRhYmxlU2l6ZShpbnQgc2ZudFRhZyk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L1NoYXBlR3JhcGhpY0F0dHJpYnV0ZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvU2hhcGVHcmFwaGljQXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTgyYmZmZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9mb250L1NoYXBlR3JhcGhpY0F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsMjA2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5mb250OworCitpbXBvcnQgamF2YS5hd3QuQmFzaWNTdHJva2U7CitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3MyRDsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5TdHJva2U7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5taXNjLkhhc2hDb2RlOworCisvKioKKyAqIFRoZSBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgY2xhc3MgcHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gaW5zZXJ0IHNoYXBlcyB0byBhCisgKiB0ZXh0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNoYXBlR3JhcGhpY0F0dHJpYnV0ZSBleHRlbmRzIEdyYXBoaWNBdHRyaWJ1dGUgeworCisgICAgLy8gc2hhcGUgdG8gcmVuZGVyCisgICAgLyoqCisgICAgICogVGhlIHNoYXBlLgorICAgICAqLworICAgIHByaXZhdGUgU2hhcGUgZlNoYXBlOworCisgICAgLy8gZmxhZywgaWYgdGhlIHNoYXBlIHNob3VsZCBiZSBzdHJva2VkICh0cnVlKSBvciBmaWxsZWQgKGZhbHNlKQorICAgIC8qKgorICAgICAqIFRoZSBzdHJva2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGZTdHJva2U7CisKKyAgICAvLyBib3VuZHMgb2YgdGhlIHNoYXBlCisgICAgLyoqCisgICAgICogVGhlIGJvdW5kcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlY3RhbmdsZTJEIGZCb3VuZHM7CisKKyAgICAvLyBYIGNvb3JkaW5hdGUgb2YgdGhlIG9yaWdpbiBwb2ludAorICAgIC8qKgorICAgICAqIFRoZSBvcmlnaW4geC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGZPcmlnaW5YOworCisgICAgLy8gWSBjb29yZGluYXRlIG9mIHRoZSBvcmlnaW4gcG9pbnQKKyAgICAvKioKKyAgICAgKiBUaGUgb3JpZ2luIHkuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBmT3JpZ2luWTsKKworICAgIC8vIHdpZHRoIG9mIHRoZSBzaGFwZQorICAgIC8qKgorICAgICAqIFRoZSBzaGFwZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGZTaGFwZVdpZHRoOworCisgICAgLy8gaGVpZ2h0IG9mIHRoZSBzaGFwZQorICAgIC8qKgorICAgICAqIFRoZSBzaGFwZSBoZWlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBmU2hhcGVIZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU1RST0tFIGluZGljYXRlcyB3aGV0aGVyIHRoZSBTaGFwZSBpcyBzdHJva2VkIG9yIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gU1RST0tFID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBGSUxMIGluZGljYXRlcyB3aGV0aGVyIHRoZSBTaGFwZSBpcyBmaWxsZWQgb3Igbm90LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBGSUxMID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgU2hhcGVHcmFwaGljQXR0cmlidXRlIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBTaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2hhcGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGFwZSB0byBiZSByZW5kZXJlZCBieSB0aGlzIFNoYXBlR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gYWxpZ25tZW50CisgICAgICogICAgICAgICAgICB0aGUgYWxpZ25tZW50IG9mIHRoaXMgU2hhcGVHcmFwaGljQXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBzdHJva2UKKyAgICAgKiAgICAgICAgICAgIHRydWUgaWYgdGhlIFNoYXBlIGlzIHN0cm9rZWQsIGZhbHNlIGlmIHRoZSBTaGFwZSBpcyBmaWxsZWQuCisgICAgICovCisgICAgcHVibGljIFNoYXBlR3JhcGhpY0F0dHJpYnV0ZShTaGFwZSBzaGFwZSwgaW50IGFsaWdubWVudCwgYm9vbGVhbiBzdHJva2UpIHsKKyAgICAgICAgc3VwZXIoYWxpZ25tZW50KTsKKworICAgICAgICB0aGlzLmZTaGFwZSA9IHNoYXBlOworICAgICAgICB0aGlzLmZTdHJva2UgPSBzdHJva2U7CisKKyAgICAgICAgdGhpcy5mQm91bmRzID0gZlNoYXBlLmdldEJvdW5kczJEKCk7CisKKyAgICAgICAgdGhpcy5mT3JpZ2luWCA9IChmbG9hdClmQm91bmRzLmdldE1pblgoKTsKKyAgICAgICAgdGhpcy5mT3JpZ2luWSA9IChmbG9hdClmQm91bmRzLmdldE1pblkoKTsKKworICAgICAgICB0aGlzLmZTaGFwZVdpZHRoID0gKGZsb2F0KWZCb3VuZHMuZ2V0V2lkdGgoKTsKKyAgICAgICAgdGhpcy5mU2hhcGVIZWlnaHQgPSAoZmxvYXQpZkJvdW5kcy5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIG9mIHRoaXMgU2hhcGVHcmFwaGljQXR0cmlidXRlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgaGFzaCBjb2RlIG9mIHRoaXMgU2hhcGVHcmFwaGljQXR0cmlidXRlIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBIYXNoQ29kZSBoYXNoID0gbmV3IEhhc2hDb2RlKCk7CisKKyAgICAgICAgaGFzaC5hcHBlbmQoZlNoYXBlLmhhc2hDb2RlKCkpOworICAgICAgICBoYXNoLmFwcGVuZChnZXRBbGlnbm1lbnQoKSk7CisgICAgICAgIHJldHVybiBoYXNoLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzZ2EKKyAgICAgKiAgICAgICAgICAgIHRoZSBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0IGlzIGVxdWFsIHRvIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIFNoYXBlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoU2hhcGVHcmFwaGljQXR0cmlidXRlIHNnYSkgeworICAgICAgICBpZiAoc2dhID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZ2EgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKGZTdHJva2UgPT0gc2dhLmZTdHJva2UgJiYgZ2V0QWxpZ25tZW50KCkgPT0gc2dhLmdldEFsaWdubWVudCgpICYmIGZTaGFwZQorICAgICAgICAgICAgICAgIC5lcXVhbHMoc2dhLmZTaGFwZSkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBTaGFwZUdyYXBoaWNBdHRyaWJ1dGUgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgT2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIFNoYXBlR3JhcGhpY0F0dHJpYnV0ZSBvYmplY3QgaXMgZXF1YWwgdG8gdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgT2JqZWN0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKFNoYXBlR3JhcGhpY0F0dHJpYnV0ZSlvYmopOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhdyhHcmFwaGljczJEIGcyLCBmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBhdCA9IEFmZmluZVRyYW5zZm9ybS5nZXRUcmFuc2xhdGVJbnN0YW5jZSh4LCB5KTsKKyAgICAgICAgaWYgKGZTdHJva2UgPT0gU1RST0tFKSB7CisgICAgICAgICAgICBTdHJva2Ugb2xkU3Ryb2tlID0gZzIuZ2V0U3Ryb2tlKCk7CisgICAgICAgICAgICBnMi5zZXRTdHJva2UobmV3IEJhc2ljU3Ryb2tlKCkpOworICAgICAgICAgICAgZzIuZHJhdyhhdC5jcmVhdGVUcmFuc2Zvcm1lZFNoYXBlKGZTaGFwZSkpOworICAgICAgICAgICAgZzIuc2V0U3Ryb2tlKG9sZFN0cm9rZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnMi5maWxsKGF0LmNyZWF0ZVRyYW5zZm9ybWVkU2hhcGUoZlNoYXBlKSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRBZHZhbmNlKCkgeworICAgICAgICByZXR1cm4gTWF0aC5tYXgoMCwgZlNoYXBlV2lkdGggKyBmT3JpZ2luWCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldEFzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIC1mT3JpZ2luWSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIChSZWN0YW5nbGUyRClmQm91bmRzLmNsb25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldERlc2NlbnQoKSB7CisgICAgICAgIHJldHVybiBNYXRoLm1heCgwLCBmU2hhcGVIZWlnaHQgKyBmT3JpZ2luWSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9UZXh0SGl0SW5mby5qYXZhIGIvYXd0L2phdmEvYXd0L2ZvbnQvVGV4dEhpdEluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NDYwZWJhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvVGV4dEhpdEluZm8uamF2YQpAQCAtMCwwICsxLDIxNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmZvbnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubWlzYy5IYXNoQ29kZTsKKworLyoqCisgKiBUaGUgVGV4dEhpdEluZm8gY2xhc3MgcHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgYSBjYXJldCBwb3NpdGlvbiBpbiBhIHRleHQKKyAqIG1vZGVsIGZvciBpbnNlcnRpb24gb3IgZGVsZXRpb24gb2YgYSBjaGFyYWN0ZXIgaW4gYSB0ZXh0LiBUaGUgVGV4dEhpdEluZm8KKyAqIGRlZmluZXMgdHdvIGJpYXNlcyBvZiB0aGUgY2hhcmFjdGVyOiBsZWFkaW5nIG9yIHRyYWlsaW5nLiBMZWFkaW5nIHBvc2l0aW9uCisgKiBtZWFucyB0aGUgbGVmdCBlZGdlIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIChUZXh0SGl0SW5mby5sZWFkaW5nKDIpIG1ldGhvZAorICogZm9yICJ0ZXh0IiByZXR1cm5zIHRoZSBsZWZ0IHNpZGUgb2YgIngiKS4gVHJhaWxpbmcgcG9zaXRpb24gbWVhbnMgdGhlIHJpZ2h0CisgKiBlZGdlIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIChUZXh0SGl0SW5mby50cmFpbGluZygyKSBtZXRob2QgZm9yICJ0ZXh0IgorICogcmV0dXJucyB0aGUgcmlnaHQgc2lkZSBvZiAieCIpLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRleHRIaXRJbmZvIHsKKworICAgIC8qKgorICAgICAqIFRoZSBjaGFyIGlkeC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjaGFySWR4OyAvLyBSZXByZXNlbnRzIGNoYXJhY3RlciBpbmRleCBpbiB0aGUgbGluZQorCisgICAgLyoqCisgICAgICogVGhlIGlzIHRyYWlsaW5nLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1RyYWlsaW5nOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHRleHQgaGl0IGluZm8uCisgICAgICogCisgICAgICogQHBhcmFtIGlkeAorICAgICAqICAgICAgICAgICAgdGhlIGlkeC4KKyAgICAgKiBAcGFyYW0gaXNUcmFpbGluZworICAgICAqICAgICAgICAgICAgdGhlIGlzIHRyYWlsaW5nLgorICAgICAqLworICAgIHByaXZhdGUgVGV4dEhpdEluZm8oaW50IGlkeCwgYm9vbGVhbiBpc1RyYWlsaW5nKSB7CisgICAgICAgIGNoYXJJZHggPSBpZHg7CisgICAgICAgIHRoaXMuaXNUcmFpbGluZyA9IGlzVHJhaWxpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGV4dHVhbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBUZXh0SGl0SW5mbyBpbnN0YW5jZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoIlRleHRIaXRJbmZvWyIgKyBjaGFySWR4ICsgIiwgIiArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgIChpc1RyYWlsaW5nID8gIlRyYWlsaW5nIiA6ICJMZWFkaW5nIikgKyAiXSIgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIFRleHRIaXRJbmZvIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIFRleHRIaXRJbmZvIG9iamVjdCB3aXRoIHRoZQorICAgICAqICAgICAgICAgc2FtZSBkYXRhIHZhbHVlcyBhcyB0aGlzIFRleHRIaXRJbmZvLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFRleHRIaXRJbmZvKSB7CisgICAgICAgICAgICByZXR1cm4gZXF1YWxzKChUZXh0SGl0SW5mbylvYmopOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIFRleHRIaXRJbmZvIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgVGV4dEhpdEluZm8gb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBUZXh0SGl0SW5mbyBvYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIFRleHRIaXRJbmZvIG9iamVjdCBoYXMgdGhlIHNhbWUgZGF0YSB2YWx1ZXMgYXMgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgVGV4dEhpdEluZm8gb2JqZWN0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFRleHRIaXRJbmZvIHRoaSkgeworICAgICAgICByZXR1cm4gdGhpICE9IG51bGwgJiYgdGhpLmNoYXJJZHggPT0gY2hhcklkeCAmJiB0aGkuaXNUcmFpbGluZyA9PSBpc1RyYWlsaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBUZXh0SGl0SW5mbyBvYmplY3Qgd2l0aCBpdHMgY2hhcmFjdGVyIGluZGV4IGF0IHRoZSBzcGVjaWZpZWQKKyAgICAgKiBvZmZzZXQgZnJvbSB0aGUgY2hhcmFjdGVyIGluZGV4IG9mIHRoaXMgVGV4dEhpdEluZm8uCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mby4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gZ2V0T2Zmc2V0SGl0KGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXh0SGl0SW5mbyhjaGFySWR4ICsgb2Zmc2V0LCBpc1RyYWlsaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgVGV4dEhpdEluZm8gYXNzb2NpYXRlZCB3aXRoIHRoZSBvdGhlciBzaWRlIG9mIHRoZSBpbnNlcnRpb24gcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgb3RoZXIgaGl0LgorICAgICAqLworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXRPdGhlckhpdCgpIHsKKyAgICAgICAgcmV0dXJuIGlzVHJhaWxpbmcgPyBuZXcgVGV4dEhpdEluZm8oY2hhcklkeCArIDEsIGZhbHNlKQorICAgICAgICAgICAgICAgIDogbmV3IFRleHRIaXRJbmZvKGNoYXJJZHggLSAxLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgY2hhcmFjdGVyIGlzIGhpdCwgZmFsc2UgaWYgdGhlCisgICAgICogdHJhaWxpbmcgZWRnZSBvZiB0aGUgY2hhcmFjdGVyIGlzIGhpdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgY2hhcmFjdGVyIGlzIGhpdCwgZmFsc2UgaWYgdGhlCisgICAgICogICAgICAgICB0cmFpbGluZyBlZGdlIG9mIHRoZSBjaGFyYWN0ZXIgaXMgaGl0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTGVhZGluZ0VkZ2UoKSB7CisgICAgICAgIHJldHVybiAhaXNUcmFpbGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgdmFsdWUgb2YgdGhpcyBUZXh0SGl0SW5mbyBpbnN0YW5jZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIEhhc2hDb2RlLmNvbWJpbmUoY2hhcklkeCwgaXNUcmFpbGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW5zZXJ0aW9uIGluZGV4LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGluc2VydGlvbiBpbmRleDogY2hhcmFjdGVyIGluZGV4IGlmIHRoZSBsZWFkaW5nIGVkZ2UgaXMgaGl0LAorICAgICAqICAgICAgICAgb3IgY2hhcmFjdGVyIGluZGV4ICsgMSBpZiB0aGUgdHJhaWxpbmcgZWRnZSBpcyBoaXQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbnNlcnRpb25JbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGlzVHJhaWxpbmcgPyBjaGFySWR4ICsgMSA6IGNoYXJJZHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3RlciBoaXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGhpdCdzIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q2hhckluZGV4KCkgeworICAgICAgICByZXR1cm4gY2hhcklkeDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVGV4dEhpdEluZm8gYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBhdCB0aGUgc3BlY2lmaWVkIGNoYXIgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGNoYXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgaW5kZXguCisgICAgICogQHJldHVybiB0aGUgVGV4dEhpdEluZm8gYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZQorICAgICAqICAgICAgICAgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgY2hhciBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRleHRIaXRJbmZvIHRyYWlsaW5nKGludCBjaGFySW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXh0SGl0SW5mbyhjaGFySW5kZXgsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBUZXh0SGl0SW5mbyBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlCisgICAgICogY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgY2hhciBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2hhckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgY2hhciBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mbyBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlCisgICAgICogICAgICAgICBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBjaGFyIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGV4dEhpdEluZm8gbGVhZGluZyhpbnQgY2hhckluZGV4KSB7CisgICAgICAgIHJldHVybiBuZXcgVGV4dEhpdEluZm8oY2hhckluZGV4LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhICh0cmFpbGluZykgVGV4dEhpdEluZm8gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgY2hhcmFjdGVyCisgICAgICogYmVmb3JlIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHJldHVybiB0aGUgVGV4dEhpdEluZm8gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgY2hhcmFjdGVyIGJlZm9yZSB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUZXh0SGl0SW5mbyBiZWZvcmVPZmZzZXQoaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gbmV3IFRleHRIaXRJbmZvKG9mZnNldCAtIDEsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSAobGVhZGluZykgVGV4dEhpdEluZm8gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgY2hhcmFjdGVyCisgICAgICogYWZ0ZXIgdGhlIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mbyBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGV4dEhpdEluZm8gYWZ0ZXJPZmZzZXQoaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gbmV3IFRleHRIaXRJbmZvKG9mZnNldCwgZmFsc2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L1RleHRMYXlvdXQuamF2YSBiL2F3dC9qYXZhL2F3dC9mb250L1RleHRMYXlvdXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzZmMGJhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvVGV4dExheW91dC5qYXZhCkBAIC0wLDAgKzEsOTI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzMkQ7CitpbXBvcnQgamF2YS5hd3QuU2hhcGU7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkdlbmVyYWxQYXRoOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmc7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5CYXNpY01ldHJpY3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkNhcmV0TWFuYWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuVGV4dE1ldHJpY3NDYWxjdWxhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5UZXh0UnVuQnJlYWtlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgVGV4dExheW91dCBjbGFzcyBkZWZpbmVzIHRoZSBncmFwaGljYWwgcmVwcmVzZW50YXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIG1ldGhvZCBmb3Igb2J0YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IGN1cnNvciBwb3NpdGlvbmluZworICogYW5kIG1vdmVtZW50LCBzcGxpdCBjdXJzb3JzIGZvciB0ZXh0IHdpdGggZGlmZmVyZW50IGRpcmVjdGlvbnMsIGxvZ2ljYWwgYW5kCisgKiB2aXN1YWwgaGlnaGxpZ2h0aW5nLCBtdWx0aXBsZSBiYXNlbGluZXMsIGhpdHMsIGp1c3RpZmljYXRpb24sIGFzY2VudCwKKyAqIGRlc2NlbnQsIGFuZCBhZHZhbmNlLCBhbmQgcmVuZGVyaW5nLiBBIFRleHRMYXlvdXQgb2JqZWN0IGNhbiBiZSByZW5kZXJlZAorICogdXNpbmcgR3JhcGhpY3MgY29udGV4dC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXh0TGF5b3V0IGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDYXJldFBvbGljeSBjbGFzcyBwcm92aWRlcyBhIHBvbGljeSBmb3Igb2J0YWluaW5nIHRoZSBjYXJldCBsb2NhdGlvbi4KKyAgICAgKiBUaGUgc2luZ2xlIGdldFN0cm9uZ0NhcmV0IG1ldGhvZCBzcGVjaWZpZXMgdGhlIHBvbGljeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENhcmV0UG9saWN5IHsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IENhcmV0UG9saWN5LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENhcmV0UG9saWN5KCkgeworICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgd2hpY2hldmVyIG9mIHRoZSB0d28gc3BlY2lmaWVkIFRleHRIaXRJbmZvIG9iamVjdHMgaGFzIHRoZQorICAgICAgICAgKiBzdHJvbmdlciBjYXJldCAoaGlnaGVyIGNoYXJhY3RlciBsZXZlbCkgaW4gdGhlIHNwZWNpZmllZCBUZXh0TGF5b3V0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGhpdDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgVGV4dEhpdEluZm8gb2YgdGhlIHNwZWNpZmllZCBUZXh0TGF5b3V0LgorICAgICAgICAgKiBAcGFyYW0gaGl0MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgVGV4dEhpdEluZm8gb2YgdGhlIHNwZWNpZmllZCBUZXh0TGF5b3V0LgorICAgICAgICAgKiBAcGFyYW0gbGF5b3V0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIFRleHRMYXlvdXQuCisgICAgICAgICAqIEByZXR1cm4gdGhlIFRleHRIaXRJbmZvIHdpdGggdGhlIHN0cm9uZ2VyIGNhcmV0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFRleHRIaXRJbmZvIGdldFN0cm9uZ0NhcmV0KFRleHRIaXRJbmZvIGhpdDEsIFRleHRIaXRJbmZvIGhpdDIsIFRleHRMYXlvdXQgbGF5b3V0KSB7CisgICAgICAgICAgICAvLyBTdHJvbmdlciBoaXQgaXMgdGhlIG9uZSB3aXRoIGdyZWF0ZXIgbGV2ZWwuCisgICAgICAgICAgICAvLyBJZiB0aGUgbGV2ZWwgaXMgc2FtZSwgbGVhZGluZyBlZGdlIGlzIHN0cm9uZ2VyLgorCisgICAgICAgICAgICBpbnQgbGV2ZWwxID0gbGF5b3V0LmdldENoYXJhY3RlckxldmVsKGhpdDEuZ2V0Q2hhckluZGV4KCkpOworICAgICAgICAgICAgaW50IGxldmVsMiA9IGxheW91dC5nZXRDaGFyYWN0ZXJMZXZlbChoaXQyLmdldENoYXJJbmRleCgpKTsKKworICAgICAgICAgICAgaWYgKGxldmVsMSA9PSBsZXZlbDIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGhpdDIuaXNMZWFkaW5nRWRnZSgpICYmICghaGl0MS5pc0xlYWRpbmdFZGdlKCkpKSA/IGhpdDIgOiBoaXQxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxldmVsMSA+IGxldmVsMiA/IGhpdDEgOiBoaXQyOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgREVGQVVMVF9DQVJFVF9QT0xJQ1kgaW5kaWNhdGVzIHRoZSBkZWZhdWx0IGNhcmV0IHBvbGljeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRMYXlvdXQuQ2FyZXRQb2xpY3kgREVGQVVMVF9DQVJFVF9QT0xJQ1kgPSBuZXcgQ2FyZXRQb2xpY3koKTsKKworICAgIC8qKgorICAgICAqIFRoZSBicmVha2VyLgorICAgICAqLworICAgIHByaXZhdGUgVGV4dFJ1bkJyZWFrZXIgYnJlYWtlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBtZXRyaWNzIHZhbGlkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBtZXRyaWNzVmFsaWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSB0bWMuCisgICAgICovCisgICAgcHJpdmF0ZSBUZXh0TWV0cmljc0NhbGN1bGF0b3IgdG1jOworCisgICAgLyoqCisgICAgICogVGhlIG1ldHJpY3MuCisgICAgICovCisgICAgcHJpdmF0ZSBCYXNpY01ldHJpY3MgbWV0cmljczsKKworICAgIC8qKgorICAgICAqIFRoZSBjYXJldCBtYW5hZ2VyLgorICAgICAqLworICAgIHByaXZhdGUgQ2FyZXRNYW5hZ2VyIGNhcmV0TWFuYWdlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBqdXN0aWZpY2F0aW9uIHdpZHRoLgorICAgICAqLworICAgIGZsb2F0IGp1c3RpZmljYXRpb25XaWR0aCA9IC0xOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFRleHRMYXlvdXQgb2JqZWN0IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcgYW5kIEZvbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBiZSBkaXNwbGF5ZWQuCisgICAgICogQHBhcmFtIGZvbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb250IG9mIHRoZSB0ZXh0LgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dCBvYmplY3QgZm9yIG9idGFpbmluZyBpbmZvcm1hdGlvbiBhYm91dCBhCisgICAgICogICAgICAgICAgICBncmFwaGljcyBkZXZpY2UuCisgICAgICovCisgICAgcHVibGljIFRleHRMYXlvdXQoU3RyaW5nIHN0cmluZywgRm9udCBmb250LCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMDE9J3swfScgcGFyYW1ldGVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDEiLCAic3RyaW5nIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmb250ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4wMT0nezB9JyBwYXJhbWV0ZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wMSIsICJmb250IikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdHJpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjAyPSd7MH0nIHBhcmFtZXRlciBoYXMgemVybyBsZW5ndGgKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDIiLCAic3RyaW5nIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhzdHJpbmcpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoVGV4dEF0dHJpYnV0ZS5GT05ULCBmb250KTsKKyAgICAgICAgdGhpcy5icmVha2VyID0gbmV3IFRleHRSdW5CcmVha2VyKGFzLmdldEl0ZXJhdG9yKCksIGZyYyk7CisgICAgICAgIGNhcmV0TWFuYWdlciA9IG5ldyBDYXJldE1hbmFnZXIoYnJlYWtlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFRleHRMYXlvdXQgZnJvbSB0aGUgc3BlY2lmaWVkIHRleHQgYW5kIGEgbWFwIG9mCisgICAgICogYXR0cmlidXRlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGJlIGRpc3BsYXllZC4KKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZXMgdG8gYmUgdXNlZCBmb3Igb2J0YWluaW5nIHRoZSB0ZXh0IHN0eWxlLgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dCBvYmplY3QgZm9yIG9idGFpbmluZyBpbmZvcm1hdGlvbiBhYm91dCBhCisgICAgICogICAgICAgICAgICBncmFwaGljcyBkZXZpY2UuCisgICAgICovCisgICAgcHVibGljIFRleHRMYXlvdXQoU3RyaW5nIHN0cmluZywKKyAgICAgICAgICAgIE1hcDw/IGV4dGVuZHMgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsID8+IGF0dHJpYnV0ZXMsCisgICAgICAgICAgICBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMDE9J3swfScgcGFyYW1ldGVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDEiLCAic3RyaW5nIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4wMT0nezB9JyBwYXJhbWV0ZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wMSIsICJhdHRyaWJ1dGVzIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdHJpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjAyPSd7MH0nIHBhcmFtZXRlciBoYXMgemVybyBsZW5ndGgKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDIiLCAic3RyaW5nIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhzdHJpbmcpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIDAsIHN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgIHRoaXMuYnJlYWtlciA9IG5ldyBUZXh0UnVuQnJlYWtlcihhcy5nZXRJdGVyYXRvcigpLCBmcmMpOworICAgICAgICBjYXJldE1hbmFnZXIgPSBuZXcgQ2FyZXRNYW5hZ2VyKGJyZWFrZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBUZXh0TGF5b3V0IGZyb20gdGhlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGV4dAorICAgICAqICAgICAgICAgICAgdGhlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci4KKyAgICAgKiBAcGFyYW0gZnJjCisgICAgICogICAgICAgICAgICB0aGUgRm9udFJlbmRlckNvbnRleHQgb2JqZWN0IGZvciBvYnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgYQorICAgICAqICAgICAgICAgICAgZ3JhcGhpY3MgZGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBUZXh0TGF5b3V0KEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgaWYgKHRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjAzPSd7MH0nIGl0ZXJhdG9yIHBhcmFtZXRlciBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjAzIiwgInRleHQiKSk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHRleHQuZ2V0QmVnaW5JbmRleCgpID09IHRleHQuZ2V0RW5kSW5kZXgoKSkgeworICAgICAgICAgICAgLy8gYXd0LjA0PSd7MH0nIGl0ZXJhdG9yIHBhcmFtZXRlciBoYXMgemVybyBsZW5ndGgKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDQiLCAidGV4dCIpKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0KKworICAgICAgICB0aGlzLmJyZWFrZXIgPSBuZXcgVGV4dFJ1bkJyZWFrZXIodGV4dCwgZnJjKTsKKyAgICAgICAgY2FyZXRNYW5hZ2VyID0gbmV3IENhcmV0TWFuYWdlcihicmVha2VyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgdGV4dCBsYXlvdXQuCisgICAgICogCisgICAgICogQHBhcmFtIGJyZWFrZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBicmVha2VyLgorICAgICAqLworICAgIFRleHRMYXlvdXQoVGV4dFJ1bkJyZWFrZXIgYnJlYWtlcikgeworICAgICAgICB0aGlzLmJyZWFrZXIgPSBicmVha2VyOworICAgICAgICBjYXJldE1hbmFnZXIgPSBuZXcgQ2FyZXRNYW5hZ2VyKHRoaXMuYnJlYWtlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBvZiB0aGlzIFRleHRMYXlvdXQgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBoYXNoIGNvZGUgb2YgdGhpcyBUZXh0TGF5b3V0IG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gYnJlYWtlci5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIFRleHRMYXlvdXQgcmVzID0gbmV3IFRleHRMYXlvdXQoKFRleHRSdW5CcmVha2VyKWJyZWFrZXIuY2xvbmUoKSk7CisKKyAgICAgICAgaWYgKGp1c3RpZmljYXRpb25XaWR0aCA+PSAwKSB7CisgICAgICAgICAgICByZXMuaGFuZGxlSnVzdGlmeShqdXN0aWZpY2F0aW9uV2lkdGgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIFRleHRMYXlvdXQgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgVGV4dExheW91dCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGxheW91dAorICAgICAqICAgICAgICAgICAgdGhlIFRleHRMYXlvdXQgb2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBUZXh0TGF5b3V0IG9iamVjdCBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBUZXh0TGF5b3V0IG9iamVjdCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhUZXh0TGF5b3V0IGxheW91dCkgeworICAgICAgICBpZiAobGF5b3V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy5icmVha2VyLmVxdWFscyhsYXlvdXQuYnJlYWtlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBUZXh0TGF5b3V0IG9iamVjdCB0byB0aGUgc3BlY2lmaWVkIE9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBUZXh0TGF5b3V0IG9iamVjdCBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIE9iamVjdCwKKyAgICAgKiAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgVGV4dExheW91dCA/IGVxdWFscygoVGV4dExheW91dClvYmopIDogZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIFRleHRMYXlvdXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIFRleHRMYXlvdXQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgLy8gd2hhdCBmb3I/CisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERyYXdzIHRoaXMgVGV4dExheW91dCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIEdyYXBoaWNzMkQgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZzJkCisgICAgICogICAgICAgICAgICB0aGUgR3JhcGhpY3MyRCBvYmplY3Qgd2hpY2ggcmVuZGVycyB0aGlzIFRleHRMYXlvdXQuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIFRleHRMYXlvdXQgb3JpZ2luLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBUZXh0TGF5b3V0IG9yaWdpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkcmF3KEdyYXBoaWNzMkQgZzJkLCBmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIHVwZGF0ZU1ldHJpY3MoKTsKKyAgICAgICAgYnJlYWtlci5kcmF3U2VnbWVudHMoZzJkLCB4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgbWV0cmljcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdXBkYXRlTWV0cmljcygpIHsKKyAgICAgICAgaWYgKCFtZXRyaWNzVmFsaWQpIHsKKyAgICAgICAgICAgIGJyZWFrZXIuY3JlYXRlQWxsU2VnbWVudHMoKTsKKyAgICAgICAgICAgIHRtYyA9IG5ldyBUZXh0TWV0cmljc0NhbGN1bGF0b3IoYnJlYWtlcik7CisgICAgICAgICAgICBtZXRyaWNzID0gdG1jLmNyZWF0ZU1ldHJpY3MoKTsKKyAgICAgICAgICAgIG1ldHJpY3NWYWxpZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhZHZhbmNlIG9mIHRoaXMgVGV4dExheW91dCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYWR2YW5jZSBvZiB0aGlzIFRleHRMYXlvdXQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRBZHZhbmNlKCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiBtZXRyaWNzLmdldEFkdmFuY2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhc2NlbnQgb2YgdGhpcyBUZXh0TGF5b3V0IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhc2NlbnQgb2YgdGhpcyBUZXh0TGF5b3V0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0QXNjZW50KCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiBtZXRyaWNzLmdldEFzY2VudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJhc2VsaW5lIG9mIHRoaXMgVGV4dExheW91dCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmFzZWxpbmUgb2YgdGhpcyBUZXh0TGF5b3V0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXRCYXNlbGluZSgpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gKGJ5dGUpbWV0cmljcy5nZXRCYXNlTGluZUluZGV4KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmxvYXQgYXJyYXkgb2Ygb2Zmc2V0cyBmb3IgdGhlIGJhc2VsaW5lcyB3aGljaCBhcmUgdXNlZCBpbiB0aGlzCisgICAgICogVGV4dExheW91dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmbG9hdCBhcnJheSBvZiBvZmZzZXRzIGZvciB0aGUgYmFzZWxpbmVzIHdoaWNoIGFyZSB1c2VkIGluCisgICAgICogICAgICAgICB0aGlzIFRleHRMYXlvdXQuCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0QmFzZWxpbmVPZmZzZXRzKCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiB0bWMuZ2V0QmFzZWxpbmVPZmZzZXRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmxhY2sgYm94IGJvdW5kcyBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgc3BlY2lmaWVkIGFyZWEuIFRoZQorICAgICAqIGJsYWNrIGJveCBib3VuZHMgaXMgYW4gU2hhcGUgd2hpY2ggY29udGFpbnMgYWxsIGJvdW5kaW5nIGJveGVzIG9mIGFsbCB0aGUKKyAgICAgKiBnbHlwaHMgb2YgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiBmaXJzdEVuZHBvaW50IGFuZCBzZWNvbmRFbmRwb2ludAorICAgICAqIHBhcmFtZXRlcnMgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmaXJzdEVuZHBvaW50CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgcG9pbnQgb2YgdGhlIGFyZWEuCisgICAgICogQHBhcmFtIHNlY29uZEVuZHBvaW50CisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIHBvaW50IG9mIHRoZSBhcmVhLgorICAgICAqIEByZXR1cm4gdGhlIFNoYXBlIHdoaWNoIGNvbnRhaW5zIGJsYWNrIGJveCBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGdldEJsYWNrQm94Qm91bmRzKGludCBmaXJzdEVuZHBvaW50LCBpbnQgc2Vjb25kRW5kcG9pbnQpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICBpZiAoZmlyc3RFbmRwb2ludCA8IHNlY29uZEVuZHBvaW50KSB7CisgICAgICAgICAgICByZXR1cm4gYnJlYWtlci5nZXRCbGFja0JveEJvdW5kcyhmaXJzdEVuZHBvaW50LCBzZWNvbmRFbmRwb2ludCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJyZWFrZXIuZ2V0QmxhY2tCb3hCb3VuZHMoc2Vjb25kRW5kcG9pbnQsIGZpcnN0RW5kcG9pbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJvdW5kcyBvZiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYm91bmRzIG9mIHRoaXMgVGV4dExheW91dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzKCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiBicmVha2VyLmdldFZpc3VhbEJvdW5kcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNhcmV0IG9mIHRoZSBzcGVjaWZpZWQgVGV4dEhpdEluZm8uCisgICAgICogCisgICAgICogQHBhcmFtIGhpdEluZm8KKyAgICAgKiAgICAgICAgICAgIHRoZSBUZXh0SGl0SW5mby4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY2FyZXQgb2YgdGhlIHNwZWNpZmllZCBUZXh0SGl0SW5mby4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRDYXJldEluZm8oVGV4dEhpdEluZm8gaGl0SW5mbykgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiBjYXJldE1hbmFnZXIuZ2V0Q2FyZXRJbmZvKGhpdEluZm8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNhcmV0IG9mIHRoZSBzcGVjaWZpZWQgVGV4dEhpdEluZm8gb2YgYQorICAgICAqIGNoYXJhY3RlciBpbiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogCisgICAgICogQHBhcmFtIGhpdEluZm8KKyAgICAgKiAgICAgICAgICAgIHRoZSBUZXh0SGl0SW5mbyBvZiBhIGNoYXJhY3RlciBpbiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogQHBhcmFtIGJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIGJvdW5kcyB0byB3aGljaCB0aGUgY2FyZXQgaW5mbyBpcyBjb25zdHJ1Y3RlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjYXJldCBvZiB0aGUgc3BlY2lmaWVkIFRleHRIaXRJbmZvLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldENhcmV0SW5mbyhUZXh0SGl0SW5mbyBoaXRJbmZvLCBSZWN0YW5nbGUyRCBib3VuZHMpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gY2FyZXRNYW5hZ2VyLmdldENhcmV0SW5mbyhoaXRJbmZvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgU2hhcGUgd2hpY2ggcmVwcmVzZW50cyB0aGUgY2FyZXQgb2YgdGhlIHNwZWNpZmllZCBUZXh0SGl0SW5mbyBpbgorICAgICAqIHRoZSBib3VuZHMgb2YgdGhpcyBUZXh0TGF5b3V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaXRJbmZvCisgICAgICogICAgICAgICAgICB0aGUgVGV4dEhpdEluZm8uCisgICAgICogQHBhcmFtIGJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIGJvdW5kcyB0byB3aGljaCB0aGUgY2FyZXQgaW5mbyBpcyBjb25zdHJ1Y3RlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBTaGFwZSB3aGljaCByZXByZXNlbnRzIHRoZSBjYXJldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgZ2V0Q2FyZXRTaGFwZShUZXh0SGl0SW5mbyBoaXRJbmZvLCBSZWN0YW5nbGUyRCBib3VuZHMpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gY2FyZXRNYW5hZ2VyLmdldENhcmV0U2hhcGUoaGl0SW5mbywgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIFNoYXBlIHdoaWNoIHJlcHJlc2VudHMgdGhlIGNhcmV0IG9mIHRoZSBzcGVjaWZpZWQgVGV4dEhpdEluZm8gaW4KKyAgICAgKiB0aGUgYm91bmRzIG9mIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaGl0SW5mbworICAgICAqICAgICAgICAgICAgdGhlIFRleHRIaXRJbmZvLgorICAgICAqIEByZXR1cm4gdGhlIFNoYXBlIHdoaWNoIHJlcHJlc2VudHMgdGhlIGNhcmV0LgorICAgICAqLworICAgIHB1YmxpYyBTaGFwZSBnZXRDYXJldFNoYXBlKFRleHRIaXRJbmZvIGhpdEluZm8pIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gY2FyZXRNYW5hZ2VyLmdldENhcmV0U2hhcGUoaGl0SW5mbywgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0d28gU2hhcGVzIGZvciB0aGUgc3Ryb25nIGFuZCB3ZWFrIGNhcmV0cyB3aXRoIGRlZmF1bHQgY2FyZXQgcG9saWN5CisgICAgICogYW5kIG51bGwgYm91bmRzOiB0aGUgZmlyc3QgZWxlbWVudCBpcyB0aGUgc3Ryb25nIGNhcmV0LCB0aGUgc2Vjb25kIGlzIHRoZQorICAgICAqIHdlYWsgY2FyZXQgb3IgbnVsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICBhbiBvZmZzZXQgaW4gdGhlIFRleHRMYXlvdXQuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0d28gU2hhcGVzIGNvcnJlc3BvbmRlZCB0byB0aGUgc3Ryb25nIGFuZCB3ZWFrCisgICAgICogICAgICAgICBjYXJldHMuCisgICAgICovCisgICAgcHVibGljIFNoYXBlW10gZ2V0Q2FyZXRTaGFwZXMoaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gZ2V0Q2FyZXRTaGFwZXMob2Zmc2V0LCBudWxsLCBUZXh0TGF5b3V0LkRFRkFVTFRfQ0FSRVRfUE9MSUNZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHR3byBTaGFwZXMgZm9yIHRoZSBzdHJvbmcgYW5kIHdlYWsgY2FyZXRzIHdpdGggdGhlIGRlZmF1bHQgY2FyZXQKKyAgICAgKiBwb2xpY3k6IHRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZSBzdHJvbmcgY2FyZXQsIHRoZSBzZWNvbmQgaXMgdGhlIHdlYWsKKyAgICAgKiBjYXJldCBvciBudWxsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIGFuIG9mZnNldCBpbiB0aGUgVGV4dExheW91dC4KKyAgICAgKiBAcGFyYW0gYm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgYm91bmRzIHRvIHdoaWNoIHRvIGV4dGVuZCB0aGUgY2FyZXRzLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdHdvIFNoYXBlcyBjb3JyZXNwb25kZWQgdG8gdGhlIHN0cm9uZyBhbmQgd2VhaworICAgICAqICAgICAgICAgY2FyZXRzLgorICAgICAqLworICAgIHB1YmxpYyBTaGFwZVtdIGdldENhcmV0U2hhcGVzKGludCBvZmZzZXQsIFJlY3RhbmdsZTJEIGJvdW5kcykgeworICAgICAgICByZXR1cm4gZ2V0Q2FyZXRTaGFwZXMob2Zmc2V0LCBib3VuZHMsIFRleHRMYXlvdXQuREVGQVVMVF9DQVJFVF9QT0xJQ1kpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdHdvIFNoYXBlcyBmb3IgdGhlIHN0cm9uZyBhbmQgd2VhayBjYXJldHM6IHRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZQorICAgICAqIHN0cm9uZyBjYXJldCwgdGhlIHNlY29uZCBpcyB0aGUgd2VhayBjYXJldCBvciBudWxsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIGFuIG9mZnNldCBpbiB0aGUgVGV4dExheW91dC4KKyAgICAgKiBAcGFyYW0gYm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgYm91bmRzIHRvIHdoaWNoIHRvIGV4dGVuZCB0aGUgY2FyZXRzLgorICAgICAqIEBwYXJhbSBwb2xpY3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgQ2FyZXRQb2xpY3kuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0d28gU2hhcGVzIGNvcnJlc3BvbmRlZCB0byB0aGUgc3Ryb25nIGFuZCB3ZWFrCisgICAgICogICAgICAgICBjYXJldHMuCisgICAgICovCisgICAgcHVibGljIFNoYXBlW10gZ2V0Q2FyZXRTaGFwZXMoaW50IG9mZnNldCwgUmVjdGFuZ2xlMkQgYm91bmRzLCBUZXh0TGF5b3V0LkNhcmV0UG9saWN5IHBvbGljeSkgeworICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBicmVha2VyLmdldENoYXJDb3VudCgpKSB7CisgICAgICAgICAgICAvLyBhd3QuMTk1PU9mZnNldCBpcyBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE5NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gY2FyZXRNYW5hZ2VyLmdldENhcmV0U2hhcGVzKG9mZnNldCwgYm91bmRzLCBwb2xpY3ksIHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGlzIFRleHRMYXlvdXQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDaGFyYWN0ZXJDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIGJyZWFrZXIuZ2V0Q2hhckNvdW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbGV2ZWwgb2YgdGhlIGNoYXJhY3RlciB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiB0aGUgbGV2ZWwgb2YgdGhlIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXRDaGFyYWN0ZXJMZXZlbChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xIHx8IGluZGV4ID09IGdldENoYXJhY3RlckNvdW50KCkpIHsKKyAgICAgICAgICAgIHJldHVybiAoYnl0ZSlicmVha2VyLmdldEJhc2VMZXZlbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBicmVha2VyLmdldExldmVsKGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZXNjZW50IG9mIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjZW50IG9mIHRoaXMgVGV4dExheW91dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0RGVzY2VudCgpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gbWV0cmljcy5nZXREZXNjZW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgVGV4dExheW91dCB3aWNoIGlzIGp1c3RpZmllZCB3aXRoIHRoZSBzcGVjaWZpZWQgd2lkdGggcmVsYXRlZCB0bworICAgICAqIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ganVzdGlmaWNhdGlvbldpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggd2hpY2ggaXMgdXNlZCBmb3IganVzdGlmaWNhdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgVGV4dExheW91dCBqdXN0aWZpZWQgdG8gdGhlIHNwZWNpZmllZCB3aWR0aC4KKyAgICAgKiBAdGhyb3dzIEVycm9yCisgICAgICogICAgICAgICAgICAgdGhlIGVycm9yIG9jY3VyZXMgaWYgdGhpcyBUZXh0TGF5b3V0IGhhcyBiZWVuIGFscmVhZHkKKyAgICAgKiAgICAgICAgICAgICBqdXN0aWZpZWQuCisgICAgICovCisgICAgcHVibGljIFRleHRMYXlvdXQgZ2V0SnVzdGlmaWVkTGF5b3V0KGZsb2F0IGp1c3RpZmljYXRpb25XaWR0aCkgdGhyb3dzIEVycm9yIHsKKyAgICAgICAgZmxvYXQganVzdGlmaWNhdGlvbiA9IGJyZWFrZXIuZ2V0SnVzdGlmaWNhdGlvbigpOworCisgICAgICAgIGlmIChqdXN0aWZpY2F0aW9uIDwgMCkgeworICAgICAgICAgICAgLy8gYXd0LjE5Nj1KdXN0aWZpY2F0aW9uIGltcG9zc2libGUsIGxheW91dCBhbHJlYWR5IGp1c3RpZmllZAorICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE5NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGVsc2UgaWYgKGp1c3RpZmljYXRpb24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBUZXh0TGF5b3V0IGp1c3RpZmllZExheW91dCA9IG5ldyBUZXh0TGF5b3V0KChUZXh0UnVuQnJlYWtlcilicmVha2VyLmNsb25lKCkpOworICAgICAgICBqdXN0aWZpZWRMYXlvdXQuaGFuZGxlSnVzdGlmeShqdXN0aWZpY2F0aW9uV2lkdGgpOworICAgICAgICByZXR1cm4ganVzdGlmaWVkTGF5b3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxlYWRpbmcgb2YgdGhpcyBUZXh0TGF5b3V0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxlYWRpbmcgb2YgdGhpcyBUZXh0TGF5b3V0LgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRMZWFkaW5nKCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisgICAgICAgIHJldHVybiBtZXRyaWNzLmdldExlYWRpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgU2hhcGUgcmVwcmVzZW50aW5nIHRoZSBsb2dpY2FsIHNlbGVjdGlvbiBiZXR3ZWVlbiB0aGUgc3BlY2lmaWVkCisgICAgICogZW5kcG9pbnRzIGFuZCBleHRlbmRlZCB0byB0aGUgbmF0dXJhbCBib3VuZHMgb2YgdGhpcyBUZXh0TGF5b3V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmaXJzdEVuZHBvaW50CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc2VsZWN0ZWQgZW5kcG9pbnQgd2l0aGluIHRoZSBhcmVhIG9mIGNoYXJhY3RlcnMKKyAgICAgKiBAcGFyYW0gc2Vjb25kRW5kcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc2VsZWN0ZWQgZW5kcG9pbnQgd2l0aGluIHRoZSBhcmVhIG9mIGNoYXJhY3RlcnMKKyAgICAgKiBAcmV0dXJuIGEgU2hhcGUgcmVwcmVzZW50ZWQgdGhlIGxvZ2ljYWwgc2VsZWN0aW9uIGJldHdlZWVuIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGVuZHBvaW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgZ2V0TG9naWNhbEhpZ2hsaWdodFNoYXBlKGludCBmaXJzdEVuZHBvaW50LCBpbnQgc2Vjb25kRW5kcG9pbnQpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworICAgICAgICByZXR1cm4gZ2V0TG9naWNhbEhpZ2hsaWdodFNoYXBlKGZpcnN0RW5kcG9pbnQsIHNlY29uZEVuZHBvaW50LCBicmVha2VyLmdldExvZ2ljYWxCb3VuZHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIFNoYXBlIHJlcHJlc2VudGluZyB0aGUgbG9naWNhbCBzZWxlY3Rpb24gYmV0d2VlZW4gdGhlIHNwZWNpZmllZAorICAgICAqIGVuZHBvaW50cyBhbmQgZXh0ZW5kZWQgdG8gdGhlIHNwZWNpZmllZCBib3VuZHMgb2YgdGhpcyBUZXh0TGF5b3V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmaXJzdEVuZHBvaW50CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc2VsZWN0ZWQgZW5kcG9pbnQgd2l0aGluIHRoZSBhcmVhIG9mIGNoYXJhY3RlcnMKKyAgICAgKiBAcGFyYW0gc2Vjb25kRW5kcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc2VsZWN0ZWQgZW5kcG9pbnQgd2l0aGluIHRoZSBhcmVhIG9mIGNoYXJhY3RlcnMKKyAgICAgKiBAcGFyYW0gYm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJvdW5kcyBvZiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogQHJldHVybiBhIFNoYXBlIHJlcHJlc2VudGVkIHRoZSBsb2dpY2FsIHNlbGVjdGlvbiBiZXR3ZWVlbiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbmRwb2ludHMuCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGdldExvZ2ljYWxIaWdobGlnaHRTaGFwZShpbnQgZmlyc3RFbmRwb2ludCwgaW50IHNlY29uZEVuZHBvaW50LCBSZWN0YW5nbGUyRCBib3VuZHMpIHsKKyAgICAgICAgdXBkYXRlTWV0cmljcygpOworCisgICAgICAgIGlmIChmaXJzdEVuZHBvaW50ID4gc2Vjb25kRW5kcG9pbnQpIHsKKyAgICAgICAgICAgIGlmIChzZWNvbmRFbmRwb2ludCA8IDAgfHwgZmlyc3RFbmRwb2ludCA+IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMTk3PUVuZHBvaW50cyBhcmUgb3V0IG9mIHJhbmdlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4xOTciKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjYXJldE1hbmFnZXIuZ2V0TG9naWNhbEhpZ2hsaWdodFNoYXBlKHNlY29uZEVuZHBvaW50LCBmaXJzdEVuZHBvaW50LCBib3VuZHMsCisgICAgICAgICAgICAgICAgICAgIHRoaXMpOworICAgICAgICB9CisgICAgICAgIGlmIChmaXJzdEVuZHBvaW50IDwgMCB8fCBzZWNvbmRFbmRwb2ludCA+IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4xOTc9RW5kcG9pbnRzIGFyZSBvdXQgb2YgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTk3IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNhcmV0TWFuYWdlci5nZXRMb2dpY2FsSGlnaGxpZ2h0U2hhcGUoZmlyc3RFbmRwb2ludCwgc2Vjb25kRW5kcG9pbnQsIGJvdW5kcywgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9naWNhbCByYW5nZXMgb2YgdGV4dCB3aGljaCBjb3JyZXNwb25kcyB0byBhIHZpc3VhbCBzZWxlY3Rpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGhpdDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBlbmRwb2ludCBvZiB0aGUgdmlzdWFsIHJhbmdlLgorICAgICAqIEBwYXJhbSBoaXQyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIGVuZHBvaW50IG9mIHRoZSB2aXN1YWwgcmFuZ2UuCisgICAgICogQHJldHVybiB0aGUgbG9naWNhbCByYW5nZXMgb2YgdGV4dCB3aGljaCBjb3JyZXNwb25kcyB0byBhIHZpc3VhbAorICAgICAqICAgICAgICAgc2VsZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRMb2dpY2FsUmFuZ2VzRm9yVmlzdWFsU2VsZWN0aW9uKFRleHRIaXRJbmZvIGhpdDEsIFRleHRIaXRJbmZvIGhpdDIpIHsKKyAgICAgICAgcmV0dXJuIGNhcmV0TWFuYWdlci5nZXRMb2dpY2FsUmFuZ2VzRm9yVmlzdWFsU2VsZWN0aW9uKGhpdDEsIGhpdDIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFRleHRIaXRJbmZvIGZvciB0aGUgbmV4dCBjYXJldCB0byB0aGUgbGVmdCAob3IgdXAgYXQgdGhlIGVuZCBvZgorICAgICAqIHRoZSBsaW5lKSBvZiB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mbyBmb3IgdGhlIG5leHQgY2FyZXQgdG8gdGhlIGxlZnQgKG9yIHVwIGF0IHRoZSBlbmQKKyAgICAgKiAgICAgICAgIG9mIHRoZSBsaW5lKSBvZiB0aGUgc3BlY2lmaWVkIGhpdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBoaXQuCisgICAgICovCisgICAgcHVibGljIFRleHRIaXRJbmZvIGdldE5leHRMZWZ0SGl0KGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGdldE5leHRMZWZ0SGl0KG9mZnNldCwgREVGQVVMVF9DQVJFVF9QT0xJQ1kpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFRleHRIaXRJbmZvIGZvciB0aGUgbmV4dCBjYXJldCB0byB0aGUgbGVmdCAob3IgdXAgYXQgdGhlIGVuZCBvZgorICAgICAqIHRoZSBsaW5lKSBvZiB0aGUgc3BlY2lmaWVkIGhpdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaGl0SW5mbworICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgaGl0LgorICAgICAqIEByZXR1cm4gdGhlIFRleHRIaXRJbmZvIGZvciB0aGUgbmV4dCBjYXJldCB0byB0aGUgbGVmdCAob3IgdXAgYXQgdGhlIGVuZAorICAgICAqICAgICAgICAgb2YgdGhlIGxpbmUpIG9mIHRoZSBzcGVjaWZpZWQgaGl0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vIGhpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gZ2V0TmV4dExlZnRIaXQoVGV4dEhpdEluZm8gaGl0SW5mbykgeworICAgICAgICBicmVha2VyLmNyZWF0ZUFsbFNlZ21lbnRzKCk7CisgICAgICAgIHJldHVybiBjYXJldE1hbmFnZXIuZ2V0TmV4dExlZnRIaXQoaGl0SW5mbyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgVGV4dEhpdEluZm8gZm9yIHRoZSBuZXh0IGNhcmV0IHRvIHRoZSBsZWZ0IChvciB1cCBhdCB0aGUgZW5kIG9mCisgICAgICogdGhlIGxpbmUpIG9mIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LCBnaXZlbiB0aGUgc3BlY2lmaWVkIGNhcmV0IHBvbGljeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiBAcGFyYW0gcG9saWN5CisgICAgICogICAgICAgICAgICB0aGUgcG9saWN5IHRvIGJlIHVzZWQgZm9yIG9idGFpbmluZyB0aGUgc3Ryb25nIGNhcmV0LgorICAgICAqIEByZXR1cm4gdGhlIFRleHRIaXRJbmZvIGZvciB0aGUgbmV4dCBjYXJldCB0byB0aGUgbGVmdCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBvZmZzZXQsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gaGl0LgorICAgICAqLworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXROZXh0TGVmdEhpdChpbnQgb2Zmc2V0LCBUZXh0TGF5b3V0LkNhcmV0UG9saWN5IHBvbGljeSkgeworICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBicmVha2VyLmdldENoYXJDb3VudCgpKSB7CisgICAgICAgICAgICAvLyBhd3QuMTk1PU9mZnNldCBpcyBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE5NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgVGV4dEhpdEluZm8gaGl0ID0gVGV4dEhpdEluZm8uYWZ0ZXJPZmZzZXQob2Zmc2V0KTsKKyAgICAgICAgVGV4dEhpdEluZm8gc3Ryb25nSGl0ID0gcG9saWN5LmdldFN0cm9uZ0NhcmV0KGhpdCwgaGl0LmdldE90aGVySGl0KCksIHRoaXMpOworICAgICAgICBUZXh0SGl0SW5mbyBuZXh0TGVmdEhpdCA9IGdldE5leHRMZWZ0SGl0KHN0cm9uZ0hpdCk7CisKKyAgICAgICAgaWYgKG5leHRMZWZ0SGl0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBwb2xpY3kuZ2V0U3Ryb25nQ2FyZXQoZ2V0VmlzdWFsT3RoZXJIaXQobmV4dExlZnRIaXQpLCBuZXh0TGVmdEhpdCwgdGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgVGV4dEhpdEluZm8gZm9yIHRoZSBuZXh0IGNhcmV0IHRvIHRoZSByaWdodCAob3IgZG93biBhdCB0aGUgZW5kCisgICAgICogb2YgdGhlIGxpbmUpIG9mIHRoZSBzcGVjaWZpZWQgaGl0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaXRJbmZvCisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBoaXQuCisgICAgICogQHJldHVybiB0aGUgVGV4dEhpdEluZm8gZm9yIHRoZSBuZXh0IGNhcmV0IHRvIHRoZSByaWdodCAob3IgZG93biBhdCB0aGUKKyAgICAgKiAgICAgICAgIGVuZCBvZiB0aGUgbGluZSkgb2YgdGhlIHNwZWNpZmllZCBoaXQsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiAgICAgICAgIGhpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gZ2V0TmV4dFJpZ2h0SGl0KFRleHRIaXRJbmZvIGhpdEluZm8pIHsKKyAgICAgICAgYnJlYWtlci5jcmVhdGVBbGxTZWdtZW50cygpOworICAgICAgICByZXR1cm4gY2FyZXRNYW5hZ2VyLmdldE5leHRSaWdodEhpdChoaXRJbmZvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBUZXh0SGl0SW5mbyBmb3IgdGhlIG5leHQgY2FyZXQgdG8gdGhlIHJpZ2h0IChvciBkb3duIGF0IHRoZSBlbmQKKyAgICAgKiBvZiB0aGUgbGluZSkgb2YgdGhlIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogQHJldHVybiB0aGUgVGV4dEhpdEluZm8gZm9yIHRoZSBuZXh0IGNhcmV0IHRvIHRoZSByaWdodCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBvZmZzZXQsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gaGl0LgorICAgICAqLworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXROZXh0UmlnaHRIaXQoaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gZ2V0TmV4dFJpZ2h0SGl0KG9mZnNldCwgREVGQVVMVF9DQVJFVF9QT0xJQ1kpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFRleHRIaXRJbmZvIGZvciB0aGUgbmV4dCBjYXJldCB0byB0aGUgcmlnaHQgKG9yIGRvd24gYXQgdGhlIGVuZAorICAgICAqIG9mIHRoZSBsaW5lKSBvZiB0aGUgc3BlY2lmaWVkIG9mZnNldCwgZ2l2ZW4gdGhlIHNwZWNpZmllZCBjYXJldCBwb2xpY3kuCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGlzIFRleHRMYXlvdXQuCisgICAgICogQHBhcmFtIHBvbGljeQorICAgICAqICAgICAgICAgICAgdGhlIHBvbGljeSB0byBiZSB1c2VkIGZvciBvYnRhaW5pbmcgdGhlIHN0cm9uZyBjYXJldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mbyBmb3IgdGhlIG5leHQgY2FyZXQgdG8gdGhlIHJpZ2h0IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIG9mZnNldCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBoaXQuCisgICAgICovCisgICAgcHVibGljIFRleHRIaXRJbmZvIGdldE5leHRSaWdodEhpdChpbnQgb2Zmc2V0LCBUZXh0TGF5b3V0LkNhcmV0UG9saWN5IHBvbGljeSkgeworICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBicmVha2VyLmdldENoYXJDb3VudCgpKSB7CisgICAgICAgICAgICAvLyBhd3QuMTk1PU9mZnNldCBpcyBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjE5NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgVGV4dEhpdEluZm8gaGl0ID0gVGV4dEhpdEluZm8uYWZ0ZXJPZmZzZXQob2Zmc2V0KTsKKyAgICAgICAgVGV4dEhpdEluZm8gc3Ryb25nSGl0ID0gcG9saWN5LmdldFN0cm9uZ0NhcmV0KGhpdCwgaGl0LmdldE90aGVySGl0KCksIHRoaXMpOworICAgICAgICBUZXh0SGl0SW5mbyBuZXh0UmlnaHRIaXQgPSBnZXROZXh0UmlnaHRIaXQoc3Ryb25nSGl0KTsKKworICAgICAgICBpZiAobmV4dFJpZ2h0SGl0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBwb2xpY3kuZ2V0U3Ryb25nQ2FyZXQoZ2V0VmlzdWFsT3RoZXJIaXQobmV4dFJpZ2h0SGl0KSwgbmV4dFJpZ2h0SGl0LCB0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvdXRsaW5lIG9mIHRoaXMgVGV4dExheW91dCBhcyBhIFNoYXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4Zm9ybQorICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybSB0byBiZSB1c2VkIHRvIHRyYW5zZm9ybSB0aGUgb3V0bGluZSBiZWZvcmUKKyAgICAgKiAgICAgICAgICAgIHJldHVybmluZyBpdCwgb3IgbnVsbCBpZiBubyB0cmFuc2Zvcm1hdGlvbiBpcyBkZXNpcmVkLgorICAgICAqIEByZXR1cm4gdGhlIG91dGxpbmUgb2YgdGhpcyBUZXh0TGF5b3V0IGFzIGEgU2hhcGUuCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGdldE91dGxpbmUoQWZmaW5lVHJhbnNmb3JtIHhmb3JtKSB7CisgICAgICAgIGJyZWFrZXIuY3JlYXRlQWxsU2VnbWVudHMoKTsKKworICAgICAgICBHZW5lcmFsUGF0aCBvdXRsaW5lID0gYnJlYWtlci5nZXRPdXRsaW5lKCk7CisKKyAgICAgICAgaWYgKG91dGxpbmUgIT0gbnVsbCAmJiB4Zm9ybSAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXRsaW5lLnRyYW5zZm9ybSh4Zm9ybSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb3V0bGluZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2aXNpYmxlIGFkdmFuY2Ugb2YgdGhpcyBUZXh0TGF5b3V0IHdoaWNoIGlzIGRlZmluZWQgYXMgZGlmZmVuY2UKKyAgICAgKiBiZXR3ZWVuIGxlYWRpbmcgKGFkdmFuY2UpIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHZpc2libGUgYWR2YW5jZSBvZiB0aGlzIFRleHRMYXlvdXQuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldFZpc2libGVBZHZhbmNlKCkgeworICAgICAgICB1cGRhdGVNZXRyaWNzKCk7CisKKyAgICAgICAgLy8gVHJhaWxpbmcgd2hpdGVzcGFjZSBfU0hPVUxEXyBiZSByZW9yZGVyZWQgKFVuaWNvZGUgc3BlYykgdG8KKyAgICAgICAgLy8gYmFzZSBkaXJlY3Rpb24sIHNvIGl0IGlzIGFsc28gdHJhaWxpbmcKKyAgICAgICAgLy8gaW4gbG9naWNhbCByZXByZXNlbnRhdGlvbi4gV2UgdXNlIHRoaXMgZmFjdC4KKyAgICAgICAgaW50IGxhc3ROb25XaGl0ZXNwYWNlID0gYnJlYWtlci5nZXRMYXN0Tm9uV2hpdGVzcGFjZSgpOworCisgICAgICAgIGlmIChsYXN0Tm9uV2hpdGVzcGFjZSA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9IGVsc2UgaWYgKGxhc3ROb25XaGl0ZXNwYWNlID09IGdldENoYXJhY3RlckNvdW50KCkgLSAxKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0QWR2YW5jZSgpOworICAgICAgICB9IGVsc2UgaWYgKGp1c3RpZmljYXRpb25XaWR0aCA+PSAwKSB7IC8vIExheW91dCBpcyBqdXN0aWZpZWQKKyAgICAgICAgICAgIHJldHVybiBqdXN0aWZpY2F0aW9uV2lkdGg7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBicmVha2VyLnB1c2hTZWdtZW50cyhicmVha2VyLmdldEFDSSgpLmdldEJlZ2luSW5kZXgoKSwgbGFzdE5vbldoaXRlc3BhY2UKKyAgICAgICAgICAgICAgICAgICAgKyBicmVha2VyLmdldEFDSSgpLmdldEJlZ2luSW5kZXgoKSArIDEpOworCisgICAgICAgICAgICBicmVha2VyLmNyZWF0ZUFsbFNlZ21lbnRzKCk7CisKKyAgICAgICAgICAgIGZsb2F0IHZpc0FkdmFuY2UgPSB0bWMuY3JlYXRlTWV0cmljcygpLmdldEFkdmFuY2UoKTsKKworICAgICAgICAgICAgYnJlYWtlci5wb3BTZWdtZW50cygpOworICAgICAgICAgICAgcmV0dXJuIHZpc0FkdmFuY2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgU2hhcGUgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIGhpZ2hsaWdodGVkIChzZWxlY3RlZCkgYXJlYSBiYXNlZAorICAgICAqIG9uIHR3byBoaXQgbG9jYXRpb25zIHdpdGhpbiB0aGUgdGV4dCBhbmQgZXh0ZW5kcyB0byB0aGUgYm91bmRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaXQxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgdGV4dCBoaXQgbG9jYXRpb24uCisgICAgICogQHBhcmFtIGhpdDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgdGV4dCBoaXQgbG9jYXRpb24uCisgICAgICogQHBhcmFtIGJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIHJlY3RhbmdsZSB0aGF0IHRoZSBoaWdobGlnaHRlZCBhcmVhIHNob3VsZCBiZSBleHRlbmRlZCBvcgorICAgICAqICAgICAgICAgICAgcmVzdHJpY3RlZCB0by4KKyAgICAgKiBAcmV0dXJuIGEgU2hhcGUgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIGhpZ2hsaWdodGVkIChzZWxlY3RlZCkgYXJlYS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgZ2V0VmlzdWFsSGlnaGxpZ2h0U2hhcGUoVGV4dEhpdEluZm8gaGl0MSwgVGV4dEhpdEluZm8gaGl0MiwgUmVjdGFuZ2xlMkQgYm91bmRzKSB7CisgICAgICAgIHJldHVybiBjYXJldE1hbmFnZXIuZ2V0VmlzdWFsSGlnaGxpZ2h0U2hhcGUoaGl0MSwgaGl0MiwgYm91bmRzLCB0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgU2hhcGUgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIGhpZ2hsaWdodGVkIChzZWxlY3RlZCkgYXJlYSBiYXNlZAorICAgICAqIG9uIHR3byBoaXQgbG9jYXRpb25zIHdpdGhpbiB0aGUgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaGl0MQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IHRleHQgaGl0IGxvY2F0aW9uLgorICAgICAqIEBwYXJhbSBoaXQyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIHRleHQgaGl0IGxvY2F0aW9uLgorICAgICAqIEByZXR1cm4gYSBTaGFwZSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgaGlnaGxpZ2h0ZWQgKHNlbGVjdGVkKSBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyBTaGFwZSBnZXRWaXN1YWxIaWdobGlnaHRTaGFwZShUZXh0SGl0SW5mbyBoaXQxLCBUZXh0SGl0SW5mbyBoaXQyKSB7CisgICAgICAgIGJyZWFrZXIuY3JlYXRlQWxsU2VnbWVudHMoKTsKKyAgICAgICAgcmV0dXJuIGNhcmV0TWFuYWdlci5nZXRWaXN1YWxIaWdobGlnaHRTaGFwZShoaXQxLCBoaXQyLCBicmVha2VyLmdldExvZ2ljYWxCb3VuZHMoKSwgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgVGV4dEhpdEluZm8gZm9yIGEgaGl0IG9uIHRoZSBvcHBvc2l0ZSBzaWRlIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBoaXQncyBjYXJldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaGl0SW5mbworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBUZXh0SGl0SW5mby4KKyAgICAgKiBAcmV0dXJuIHRoZSBUZXh0SGl0SW5mbyBmb3IgYSBoaXQgb24gdGhlIG9wcG9zaXRlIHNpZGUgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgaGl0J3MgY2FyZXQuCisgICAgICovCisgICAgcHVibGljIFRleHRIaXRJbmZvIGdldFZpc3VhbE90aGVySGl0KFRleHRIaXRJbmZvIGhpdEluZm8pIHsKKyAgICAgICAgcmV0dXJuIGNhcmV0TWFuYWdlci5nZXRWaXN1YWxPdGhlckhpdChoaXRJbmZvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBKdXN0aWZpZXMgdGhlIHRleHQ7IHRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMuCisgICAgICogCisgICAgICogQHBhcmFtIGp1c3RpZmljYXRpb25XaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIGZvciBqdXN0aWZpY2F0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGhhbmRsZUp1c3RpZnkoZmxvYXQganVzdGlmaWNhdGlvbldpZHRoKSB7CisgICAgICAgIGZsb2F0IGp1c3RpZmljYXRpb24gPSBicmVha2VyLmdldEp1c3RpZmljYXRpb24oKTsKKworICAgICAgICBpZiAoanVzdGlmaWNhdGlvbiA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4xOTY9SnVzdGlmaWNhdGlvbiBpbXBvc3NpYmxlLCBsYXlvdXQgYWxyZWFkeSBqdXN0aWZpZWQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMTk2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0gZWxzZSBpZiAoanVzdGlmaWNhdGlvbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmbG9hdCBnYXAgPSAoanVzdGlmaWNhdGlvbldpZHRoIC0gZ2V0VmlzaWJsZUFkdmFuY2UoKSkgKiBqdXN0aWZpY2F0aW9uOworICAgICAgICBicmVha2VyLmp1c3RpZnkoZ2FwKTsKKyAgICAgICAgdGhpcy5qdXN0aWZpY2F0aW9uV2lkdGggPSBqdXN0aWZpY2F0aW9uV2lkdGg7CisKKyAgICAgICAgLy8gQ29ycmVjdCBtZXRyaWNzCisgICAgICAgIHRtYyA9IG5ldyBUZXh0TWV0cmljc0NhbGN1bGF0b3IoYnJlYWtlcik7CisgICAgICAgIHRtYy5jb3JyZWN0QWR2YW5jZShtZXRyaWNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVGV4dEhpdEluZm8gb2JqZWN0IHRoYXQgZ2l2ZXMgaW5mb3JtYXRpb24gb24gd2hpY2ggZGl2aXNpb24KKyAgICAgKiBwb2ludCAoYmV0d2VlbiB0d28gY2hhcmFjdGVycykgaXMgY29ycmVzcG9uZHMgdG8gYSBoaXQgKHN1Y2ggYXMgYSBtb3VzZQorICAgICAqIGNsaWNrKSBhdCB0aGUgc3BlY2lmaWVkIGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIGluIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBpbiB0aGlzIFRleHRMYXlvdXQuIFRleHRIaXRJbmZvIG9iamVjdAorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMgd2l0aGluIHRoZSB0ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gaGl0VGVzdENoYXIoZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICByZXR1cm4gaGl0VGVzdENoYXIoeCwgeSwgZ2V0Qm91bmRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBUZXh0SGl0SW5mbyBvYmplY3QgdGhhdCBnaXZlcyBpbmZvcm1hdGlvbiBvbiB3aGljaCBkaXZpc2lvbgorICAgICAqIHBvaW50IChiZXR3ZWVuIHR3byBjaGFyYWN0ZXJzKSBpcyBjb3JyZXNwb25kcyB0byBhIGhpdCAoc3VjaCBhcyBhIG1vdXNlCisgICAgICogY2xpY2spIGF0IHRoZSBzcGVjaWZpZWQgY29vcmRpbmF0ZXMgd2l0aGluIHRoZSBzcGVjaWZpZWQgdGV4dCByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgaW4gdGhpcyBUZXh0TGF5b3V0LgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIGluIHRoaXMgVGV4dExheW91dC4KKyAgICAgKiBAcGFyYW0gYm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgYm91bmRzIG9mIHRoZSB0ZXh0IGFyZWEuIFRleHRIaXRJbmZvIG9iamVjdCBjb3JyZXNwb25kaW5nCisgICAgICogICAgICAgICAgICB0byB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMgd2l0aGluIHRoZSB0ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gaGl0VGVzdENoYXIoZmxvYXQgeCwgZmxvYXQgeSwgUmVjdGFuZ2xlMkQgYm91bmRzKSB7CisgICAgICAgIGlmICh4ID4gYm91bmRzLmdldE1heFgoKSkgeworICAgICAgICAgICAgcmV0dXJuIGJyZWFrZXIuaXNMVFIoKSA/IFRleHRIaXRJbmZvLnRyYWlsaW5nKGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkgLSAxKSA6IFRleHRIaXRJbmZvCisgICAgICAgICAgICAgICAgICAgIC5sZWFkaW5nKDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHggPCBib3VuZHMuZ2V0TWluWCgpKSB7CisgICAgICAgICAgICByZXR1cm4gYnJlYWtlci5pc0xUUigpID8gVGV4dEhpdEluZm8ubGVhZGluZygwKSA6IFRleHRIaXRJbmZvLnRyYWlsaW5nKGJyZWFrZXIKKyAgICAgICAgICAgICAgICAgICAgLmdldENoYXJDb3VudCgpIC0gMSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnJlYWtlci5oaXRUZXN0KHgsIHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFRleHRMYXlvdXQgaGFzIGEgImxlZnQgdG8gcmlnaHQiIGRpcmVjdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBUZXh0TGF5b3V0IGhhcyBhICJsZWZ0IHRvIHJpZ2h0IiBkaXJlY3Rpb24sIGZhbHNlIGlmCisgICAgICogICAgICAgICB0aGlzIFRleHRMYXlvdXQgaGFzIGEgInJpZ2h0IHRvIGxlZnQiIGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xlZnRUb1JpZ2h0KCkgeworICAgICAgICByZXR1cm4gYnJlYWtlci5pc0xUUigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFRleHRMYXlvdXQgaXMgdmVydGljYWwsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBUZXh0TGF5b3V0IGlzIHZlcnRpY2FsLCBmYWxzZSBpZiBob3Jpem9udGFsLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVmVydGljYWwoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZm9udC9UZXh0TWVhc3VyZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9mb250L1RleHRNZWFzdXJlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3NDFmNTkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZm9udC9UZXh0TWVhc3VyZXIuamF2YQpAQCAtMCwwICsxLDE4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmZvbnQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LlRleHRNZXRyaWNzQ2FsY3VsYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuVGV4dFJ1bkJyZWFrZXI7CisKKy8qKgorICogVGhlIFRleHRNZWFzdXJlciBjbGFzcyBwcm92aWRlcyB1dGlsaXRpZXMgZm9yIGxpbmUgYnJlYWsgb3BlcmF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXh0TWVhc3VyZXIgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIGFjaS4KKyAgICAgKi8KKyAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgYWNpOworCisgICAgLyoqCisgICAgICogVGhlIGZyYy4KKyAgICAgKi8KKyAgICBGb250UmVuZGVyQ29udGV4dCBmcmM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYnJlYWtlci4KKyAgICAgKi8KKyAgICBUZXh0UnVuQnJlYWtlciBicmVha2VyID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIFRoZSB0bWMuCisgICAgICovCisgICAgVGV4dE1ldHJpY3NDYWxjdWxhdG9yIHRtYyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgdGV4dCBtZWFzdXJlciBmcm9tIHRoZSBzcGVjaWZpZWQgdGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGV4dAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSB0ZXh0LgorICAgICAqIEBwYXJhbSBmcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBGb250UmVuZGVyQ29udGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dE1lYXN1cmVyKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgdGhpcy5hY2kgPSB0ZXh0OworICAgICAgICB0aGlzLmZyYyA9IGZyYzsKKyAgICAgICAgYnJlYWtlciA9IG5ldyBUZXh0UnVuQnJlYWtlcihhY2ksIHRoaXMuZnJjKTsKKyAgICAgICAgdG1jID0gbmV3IFRleHRNZXRyaWNzQ2FsY3VsYXRvcihicmVha2VyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgY3VycmVudCB0ZXh0IHdpdGggdGhlIG5ldyB0ZXh0LCBpbnNlcnRpbmcgYSBicmVhayBjaGFyYWN0ZXIKKyAgICAgKiBhdCB0aGUgc3BlY2lmaWVkIGluc2VydCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3UGFyYWdyYXBoCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHBhcmFncmFwaCB0ZXh0LgorICAgICAqIEBwYXJhbSBpbnNlcnRQb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBpbiB0aGUgdGV4dCB3aGVyZSB0aGUgY2hhcmFjdGVyIGlzIGluc2VydGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGluc2VydENoYXIoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIG5ld1BhcmFncmFwaCwgaW50IGluc2VydFBvcykgeworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3Igb2xkQWNpID0gYWNpOworICAgICAgICBhY2kgPSBuZXdQYXJhZ3JhcGg7CisgICAgICAgIGlmICgob2xkQWNpLmdldEVuZEluZGV4KCkgLSBvbGRBY2kuZ2V0QmVnaW5JbmRleCgpKQorICAgICAgICAgICAgICAgIC0gKGFjaS5nZXRFbmRJbmRleCgpIC0gYWNpLmdldEJlZ2luSW5kZXgoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgIGJyZWFrZXIgPSBuZXcgVGV4dFJ1bkJyZWFrZXIoYWNpLCB0aGlzLmZyYyk7CisgICAgICAgICAgICB0bWMgPSBuZXcgVGV4dE1ldHJpY3NDYWxjdWxhdG9yKGJyZWFrZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnJlYWtlci5pbnNlcnRDaGFyKG5ld1BhcmFncmFwaCwgaW5zZXJ0UG9zKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBjdXJyZW50IHRleHQgd2l0aCB0aGUgbmV3IHRleHQgYW5kIGRlbGV0ZXMgYSBjaGFyYWN0ZXIgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuZXdQYXJhZ3JhcGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhZ3JhcGggdGV4dCBhZnRlciBkZWxldGlvbi4KKyAgICAgKiBAcGFyYW0gZGVsZXRlUG9zCisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gaW4gdGhlIHRleHQgd2hlcmUgdGhlIGNoYXJhY3RlciBpcyByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUNoYXIoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIG5ld1BhcmFncmFwaCwgaW50IGRlbGV0ZVBvcykgeworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3Igb2xkQWNpID0gYWNpOworICAgICAgICBhY2kgPSBuZXdQYXJhZ3JhcGg7CisgICAgICAgIGlmICgob2xkQWNpLmdldEVuZEluZGV4KCkgLSBvbGRBY2kuZ2V0QmVnaW5JbmRleCgpKQorICAgICAgICAgICAgICAgIC0gKGFjaS5nZXRFbmRJbmRleCgpIC0gYWNpLmdldEJlZ2luSW5kZXgoKSkgIT0gMSkgeworICAgICAgICAgICAgYnJlYWtlciA9IG5ldyBUZXh0UnVuQnJlYWtlcihhY2ksIHRoaXMuZnJjKTsKKyAgICAgICAgICAgIHRtYyA9IG5ldyBUZXh0TWV0cmljc0NhbGN1bGF0b3IoYnJlYWtlcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBicmVha2VyLmRlbGV0ZUNoYXIobmV3UGFyYWdyYXBoLCBkZWxldGVQb3MpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXh0TWVhc3VyZXIoKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcilhY2kuY2xvbmUoKSwgZnJjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVGV4dExheW91dCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciByYW5nZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyLgorICAgICAqIEBwYXJhbSBsaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3Rlci4KKyAgICAgKiBAcmV0dXJuIGEgVGV4dExheW91dCBmb3IgdGhlIGNoYXJhY3RlcnMgYmVnaW5uaW5nIGF0ICJzdGFydCIgdXAgdG8gImVuZCIuCisgICAgICovCisgICAgcHVibGljIFRleHRMYXlvdXQgZ2V0TGF5b3V0KGludCBzdGFydCwgaW50IGxpbWl0KSB7CisgICAgICAgIGJyZWFrZXIucHVzaFNlZ21lbnRzKHN0YXJ0IC0gYWNpLmdldEJlZ2luSW5kZXgoKSwgbGltaXQgLSBhY2kuZ2V0QmVnaW5JbmRleCgpKTsKKworICAgICAgICBicmVha2VyLmNyZWF0ZUFsbFNlZ21lbnRzKCk7CisgICAgICAgIFRleHRMYXlvdXQgbGF5b3V0ID0gbmV3IFRleHRMYXlvdXQoKFRleHRSdW5CcmVha2VyKWJyZWFrZXIuY2xvbmUoKSk7CisKKyAgICAgICAgYnJlYWtlci5wb3BTZWdtZW50cygpOworICAgICAgICByZXR1cm4gbGF5b3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyYXBoaWNhbCB3aWR0aCBvZiBhIGxpbmUgYmVnaW5uaW5nIGF0ICJzdGFydCIgcGFyYW1ldGVyIGFuZAorICAgICAqIGluY2x1ZGluZyBjaGFyYWN0ZXJzIHVwIHRvICJlbmQiIHBhcmFtZXRlci4gInN0YXJ0IiBhbmQgImVuZCIgYXJlCisgICAgICogYWJzb2x1dGUgaW5kaWNlcywgbm90IHJlbGF0aXZlIHRvIHRoZSAic3RhcnQiIG9mIHRoZSBwYXJhZ3JhcGguCisgICAgICogCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IG1lYXN1cmluZy4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGluZGV4IGF0IHdoaWNoIHRvIHN0b3AgbWVhc3VyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIGdyYXBoaWNhbCB3aWR0aCBvZiBhIGxpbmUgYmVnaW5uaW5nIGF0ICJzdGFydCIgYW5kIGluY2x1ZGluZworICAgICAqICAgICAgICAgY2hhcmFjdGVycyB1cCB0byAiZW5kIi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0QWR2YW5jZUJldHdlZW4oaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGJyZWFrZXIucHVzaFNlZ21lbnRzKHN0YXJ0IC0gYWNpLmdldEJlZ2luSW5kZXgoKSwgZW5kIC0gYWNpLmdldEJlZ2luSW5kZXgoKSk7CisKKyAgICAgICAgYnJlYWtlci5jcmVhdGVBbGxTZWdtZW50cygpOworICAgICAgICBmbG9hdCByZXR2YWwgPSB0bWMuY3JlYXRlTWV0cmljcygpLmdldEFkdmFuY2UoKTsKKworICAgICAgICBicmVha2VyLnBvcFNlZ21lbnRzKCk7CisgICAgICAgIHJldHVybiByZXR2YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciB3aGljaCBpcyBub3QgZml0IG9uIGEgbGluZQorICAgICAqIGJlZ2lubmluZyBhdCBzdGFydCBhbmQgcG9zc2libGUgbWVhc3VyaW5nIHVwIHRvIG1heEFkdmFuY2UgaW4gZ3JhcGhpY2FsCisgICAgICogd2lkdGguCisgICAgICogCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICBoZSBjaGFyYWN0ZXIgaW5kZXggYXQgd2hpY2ggdG8gc3RhcnQgbWVhc3VyaW5nLgorICAgICAqIEBwYXJhbSBtYXhBZHZhbmNlCisgICAgICogICAgICAgICAgICB0aGUgZ3JhcGhpY2FsIHdpZHRoIGluIHdoaWNoIHRoZSBsaW5lIG11c3QgZml0LgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciB0aGF0IGlzIGZpdCBvbiBhIGxpbmUKKyAgICAgKiAgICAgICAgIGJlZ2lubmluZyBhdCBzdGFydCwgd2hpY2ggaXMgbm90IGxvbmdlciB0aGFuIG1heEFkdmFuY2UgaW4KKyAgICAgKiAgICAgICAgIGdyYXBoaWNhbCB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVCcmVha0luZGV4KGludCBzdGFydCwgZmxvYXQgbWF4QWR2YW5jZSkgeworICAgICAgICBicmVha2VyLmNyZWF0ZUFsbFNlZ21lbnRzKCk7CisgICAgICAgIHJldHVybiBicmVha2VyLmdldExpbmVCcmVha0luZGV4KHN0YXJ0IC0gYWNpLmdldEJlZ2luSW5kZXgoKSwgbWF4QWR2YW5jZSkKKyAgICAgICAgICAgICAgICArIGFjaS5nZXRCZWdpbkluZGV4KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ZvbnQvVHJhbnNmb3JtQXR0cmlidXRlLmphdmEgYi9hd3QvamF2YS9hd3QvZm9udC9UcmFuc2Zvcm1BdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjJjYWEyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvVHJhbnNmb3JtQXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIFRyYW5zZm9ybUF0dHJpYnV0ZSBjbGFzcyBpcyBhIHdyYXBwZXIgZm9yIHRoZSBBZmZpbmVUcmFuc2Zvcm0gY2xhc3MgaW4KKyAqIG9yZGVyIHRvIHVzZSBpdCBhcyBhdHRyaWJ1dGUuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVHJhbnNmb3JtQXR0cmlidXRlIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMzNTYyNDczNTc4Mjc3MDk1MzBMOworCisgICAgLy8gYWZmaW5lIHRyYW5zZm9ybSBvZiB0aGlzIFRyYW5zZm9ybUF0dHJpYnV0ZSBpbnN0YW5jZQorICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2Zvcm0uCisgICAgICovCisgICAgcHJpdmF0ZSBBZmZpbmVUcmFuc2Zvcm0gZlRyYW5zZm9ybTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBUcmFuc2Zvcm1BdHRyaWJ1dGUgZnJvbSB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHJhbnNmb3JtCisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtIHRvIGJlIHdyYXBwZWQuCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybUF0dHJpYnV0ZShBZmZpbmVUcmFuc2Zvcm0gdHJhbnNmb3JtKSB7CisgICAgICAgIGlmICh0cmFuc2Zvcm0gPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0Ljk0PXRyYW5zZm9ybSBjYW4gbm90IGJlIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuOTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRyYW5zZm9ybS5pc0lkZW50aXR5KCkpIHsKKyAgICAgICAgICAgIHRoaXMuZlRyYW5zZm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0odHJhbnNmb3JtKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGluaXRpYWwgQWZmaW5lVHJhbnNmb3JtIHdoaWNoIGlzIHdyYXBwZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW5pdGlhbCBBZmZpbmVUcmFuc2Zvcm0gd2hpY2ggaXMgd3JhcHBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldFRyYW5zZm9ybSgpIHsKKyAgICAgICAgaWYgKGZUcmFuc2Zvcm0gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBBZmZpbmVUcmFuc2Zvcm0oZlRyYW5zZm9ybSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyB0cmFuc2Zvcm0gaXMgYW4gaWRlbnRpdHkgdHJhbnNmb3JtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyB0cmFuc2Zvcm0gaXMgYW4gaWRlbnRpdHkgdHJhbnNmb3JtLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpdHkoKSB7CisgICAgICAgIHJldHVybiAoZlRyYW5zZm9ybSA9PSBudWxsKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9mb250L3BhY2thZ2UuaHRtbCBiL2F3dC9qYXZhL2F3dC9mb250L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODhkY2MwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ZvbnQvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsOCBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNsYXNzZXMgdG8gc3VwcG9ydCB0aGUgcmVwcmVzZW50YXRpb24gb2YgZGlmZmVyZW50IHR5cGVzIG9mIGZvbnRzIGZvciBleGFtcGxlIFRydWVUeXBlIGZvbnRzLgorICAgIDwvcD4KKyAgICBAc2luY2UgQW5kcm9pZCAxLjAKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vQWZmaW5lVHJhbnNmb3JtLmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9BZmZpbmVUcmFuc2Zvcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTY5MzhjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vQWZmaW5lVHJhbnNmb3JtLmphdmEKQEAgLTAsMCArMSwxMjY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCitpbXBvcnQgamF2YS5hd3QuU2hhcGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5taXNjLkhhc2hDb2RlOworCisvKioKKyAqIFRoZSBDbGFzcyBBZmZpbmVUcmFuc2Zvcm0gcmVwcmVzZW50cyBhIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiAocm90YXRpb24sCisgKiBzY2FsaW5nLCBvciBzaGVhcikgZm9sbG93ZWQgYnkgYSB0cmFuc2xhdGlvbiB0aGF0IGFjdHMgb24gYSBjb29yZGluYXRlIHNwYWNlLgorICogSXQgcHJlc2VydmVzIGNvbGxpbmVhcml0eSBvZiBwb2ludHMgYW5kIHJhdGlvcyBvZiBkaXN0YW5jZXMgYmV0d2VlbiBjb2xsaW5lYXIKKyAqIHBvaW50czogc28gaWYgQSwgQiwgYW5kIEMgYXJlIG9uIGEgbGluZSwgdGhlbiBhZnRlciB0aGUgc3BhY2UgaGFzIGJlZW4KKyAqIHRyYW5zZm9ybWVkIHZpYSB0aGUgYWZmaW5lIHRyYW5zZm9ybSwgdGhlIGltYWdlcyBvZiB0aGUgdGhyZWUgcG9pbnRzIHdpbGwKKyAqIHN0aWxsIGJlIG9uIGEgbGluZSwgYW5kIHRoZSByYXRpbyBvZiB0aGUgZGlzdGFuY2UgZnJvbSBBIHRvIEIgd2l0aCB0aGUKKyAqIGRpc3RhbmNlIGZyb20gQiB0byBDIHdpbGwgYmUgdGhlIHNhbWUgYXMgdGhlIGNvcnJlc3BvbmRpbmcgcmF0aW8gaW4gdGhlIGltYWdlCisgKiBzcGFjZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBBZmZpbmVUcmFuc2Zvcm0gaW1wbGVtZW50cyBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMzMwOTczMjEwNTIzODYwODM0TDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0lERU5USVRZLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSURFTlRJVFkgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfVFJBTlNMQVRJT04uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9UUkFOU0xBVElPTiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9VTklGT1JNX1NDQUxFLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfVU5JRk9STV9TQ0FMRSA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9HRU5FUkFMX1NDQUxFLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfR0VORVJBTF9TQ0FMRSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9RVUFEUkFOVF9ST1RBVElPTi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1FVQURSQU5UX1JPVEFUSU9OID0gODsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0dFTkVSQUxfUk9UQVRJT04uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9HRU5FUkFMX1JPVEFUSU9OID0gMTY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9HRU5FUkFMX1RSQU5TRk9STS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0dFTkVSQUxfVFJBTlNGT1JNID0gMzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9GTElQLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRkxJUCA9IDY0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfTUFTS19TQ0FMRS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX01BU0tfU0NBTEUgPSBUWVBFX1VOSUZPUk1fU0NBTEUgfCBUWVBFX0dFTkVSQUxfU0NBTEU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9NQVNLX1JPVEFUSU9OLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfTUFTS19ST1RBVElPTiA9IFRZUEVfUVVBRFJBTlRfUk9UQVRJT04gfCBUWVBFX0dFTkVSQUxfUk9UQVRJT047CisKKyAgICAvKioKKyAgICAgKiBUaGUgPGNvZGU+VFlQRV9VTktOT1dOPC9jb2RlPiBpcyBhbiBpbml0aWFsIHR5cGUgdmFsdWUuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBUWVBFX1VOS05PV04gPSAtMTsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW4gdmFsdWUgZXF1aXZhbGVudCB0byB6ZXJvLiBJZiBhYnNvbHV0ZSB2YWx1ZSBsZXNzIHRoZW4gWkVSTyBpdAorICAgICAqIGNvbnNpZGVyZWQgYXMgemVyby4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIFpFUk8gPSAxRS0xMDsKKworICAgIC8qKgorICAgICAqIFRoZSB2YWx1ZXMgb2YgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqLworICAgIGRvdWJsZSBtMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbTEwLgorICAgICAqLworICAgIGRvdWJsZSBtMTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbTAxLgorICAgICAqLworICAgIGRvdWJsZSBtMDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbTExLgorICAgICAqLworICAgIGRvdWJsZSBtMTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbTAyLgorICAgICAqLworICAgIGRvdWJsZSBtMDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbTEyLgorICAgICAqLworICAgIGRvdWJsZSBtMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHJhbnNmb3JtYXRpb24gPGNvZGU+dHlwZTwvY29kZT4uCisgICAgICovCisgICAgdHJhbnNpZW50IGludCB0eXBlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGFmZmluZSB0cmFuc2Zvcm0gb2YgdHlwZSA8Y29kZT5UWVBFX0lERU5USVRZPC9jb2RlPgorICAgICAqICh3aGljaCBsZWF2ZXMgY29vcmRpbmF0ZXMgdW5jaGFuZ2VkKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtKCkgeworICAgICAgICB0eXBlID0gVFlQRV9JREVOVElUWTsKKyAgICAgICAgbTAwID0gbTExID0gMS4wOworICAgICAgICBtMTAgPSBtMDEgPSBtMDIgPSBtMTIgPSAwLjA7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGFmZmluZSB0cmFuc2Zvcm0gdGhhdCBoYXMgdGhlIHNhbWUgZGF0YSBhcyB0aGUgZ2l2ZW4KKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2Zvcm0gdG8gY29weS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSB0KSB7CisgICAgICAgIHRoaXMudHlwZSA9IHQudHlwZTsKKyAgICAgICAgdGhpcy5tMDAgPSB0Lm0wMDsKKyAgICAgICAgdGhpcy5tMTAgPSB0Lm0xMDsKKyAgICAgICAgdGhpcy5tMDEgPSB0Lm0wMTsKKyAgICAgICAgdGhpcy5tMTEgPSB0Lm0xMTsKKyAgICAgICAgdGhpcy5tMDIgPSB0Lm0wMjsKKyAgICAgICAgdGhpcy5tMTIgPSB0Lm0xMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgYWZmaW5lIHRyYW5zZm9ybSBieSBzcGVjaWZ5aW5nIHRoZSB2YWx1ZXMgb2YgdGhlIDJ4MworICAgICAqIHRyYW5zZm9ybWF0aW9uIG1hdHJpeCBhcyBmbG9hdHMuIFRoZSB0eXBlIGlzIHNldCB0byB0aGUgZGVmYXVsdCB0eXBlOgorICAgICAqIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbTAwCisgICAgICogICAgICAgICAgICB0aGUgbTAwIGVudHJ5IGluIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguCisgICAgICogQHBhcmFtIG0xMAorICAgICAqICAgICAgICAgICAgdGhlIG0xMCBlbnRyeSBpbiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDEgZW50cnkgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIG1hdHJpeC4KKyAgICAgKiBAcGFyYW0gbTExCisgICAgICogICAgICAgICAgICB0aGUgbTExIGVudHJ5IGluIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguCisgICAgICogQHBhcmFtIG0wMgorICAgICAqICAgICAgICAgICAgdGhlIG0wMiBlbnRyeSBpbiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTIgZW50cnkgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIG1hdHJpeC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtKGZsb2F0IG0wMCwgZmxvYXQgbTEwLCBmbG9hdCBtMDEsIGZsb2F0IG0xMSwgZmxvYXQgbTAyLCBmbG9hdCBtMTIpIHsKKyAgICAgICAgdGhpcy50eXBlID0gVFlQRV9VTktOT1dOOworICAgICAgICB0aGlzLm0wMCA9IG0wMDsKKyAgICAgICAgdGhpcy5tMTAgPSBtMTA7CisgICAgICAgIHRoaXMubTAxID0gbTAxOworICAgICAgICB0aGlzLm0xMSA9IG0xMTsKKyAgICAgICAgdGhpcy5tMDIgPSBtMDI7CisgICAgICAgIHRoaXMubTEyID0gbTEyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBhZmZpbmUgdHJhbnNmb3JtIGJ5IHNwZWNpZnlpbmcgdGhlIHZhbHVlcyBvZiB0aGUgMngzCisgICAgICogdHJhbnNmb3JtYXRpb24gbWF0cml4IGFzIGRvdWJsZXMuIFRoZSB0eXBlIGlzIHNldCB0byB0aGUgZGVmYXVsdCB0eXBlOgorICAgICAqIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbTAwCisgICAgICogICAgICAgICAgICB0aGUgbTAwIGVudHJ5IGluIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguCisgICAgICogQHBhcmFtIG0xMAorICAgICAqICAgICAgICAgICAgdGhlIG0xMCBlbnRyeSBpbiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDEgZW50cnkgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIG1hdHJpeC4KKyAgICAgKiBAcGFyYW0gbTExCisgICAgICogICAgICAgICAgICB0aGUgbTExIGVudHJ5IGluIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguCisgICAgICogQHBhcmFtIG0wMgorICAgICAqICAgICAgICAgICAgdGhlIG0wMiBlbnRyeSBpbiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTIgZW50cnkgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIG1hdHJpeC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtKGRvdWJsZSBtMDAsIGRvdWJsZSBtMTAsIGRvdWJsZSBtMDEsIGRvdWJsZSBtMTEsIGRvdWJsZSBtMDIsIGRvdWJsZSBtMTIpIHsKKyAgICAgICAgdGhpcy50eXBlID0gVFlQRV9VTktOT1dOOworICAgICAgICB0aGlzLm0wMCA9IG0wMDsKKyAgICAgICAgdGhpcy5tMTAgPSBtMTA7CisgICAgICAgIHRoaXMubTAxID0gbTAxOworICAgICAgICB0aGlzLm0xMSA9IG0xMTsKKyAgICAgICAgdGhpcy5tMDIgPSBtMDI7CisgICAgICAgIHRoaXMubTEyID0gbTEyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBhZmZpbmUgdHJhbnNmb3JtIGJ5IHJlYWRpbmcgdGhlIHZhbHVlcyBvZiB0aGUKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbiBtYXRyaXggZnJvbSBhbiBhcnJheSBvZiBmbG9hdHMuIFRoZSBtYXBwaW5nIGZyb20gdGhlIGFycmF5CisgICAgICogdG8gdGhlIG1hdHJpeCBzdGFydHMgd2l0aCA8Y29kZT5tYXRyaXhbMF08L2NvZGU+IGdpdmluZyB0aGUgdG9wLWxlZnQKKyAgICAgKiBlbnRyeSBvZiB0aGUgbWF0cml4IGFuZCBwcm9jZWVkcyB3aXRoIHRoZSB1c3VhbCBsZWZ0LXRvLXJpZ2h0IGFuZAorICAgICAqIHRvcC1kb3duIG9yZGVyaW5nLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBhcnJheSBoYXMgb25seSBmb3VyIGVudHJpZXMsIHRoZW4gdGhlIHR3byBlbnRyaWVzIG9mIHRoZSBsYXN0IHJvdworICAgICAqIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXggZGVmYXVsdCB0byB6ZXJvLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtYXRyaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBmb3VyIG9yIHNpeCBmbG9hdHMgZ2l2aW5nIHRoZSB2YWx1ZXMgb2YgdGhlCisgICAgICogICAgICAgICAgICBtYXRyaXguCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgaXMgMCwgMSwgMiwgMywgb3IgNS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtKGZsb2F0W10gbWF0cml4KSB7CisgICAgICAgIHRoaXMudHlwZSA9IFRZUEVfVU5LTk9XTjsKKyAgICAgICAgbTAwID0gbWF0cml4WzBdOworICAgICAgICBtMTAgPSBtYXRyaXhbMV07CisgICAgICAgIG0wMSA9IG1hdHJpeFsyXTsKKyAgICAgICAgbTExID0gbWF0cml4WzNdOworICAgICAgICBpZiAobWF0cml4Lmxlbmd0aCA+IDQpIHsKKyAgICAgICAgICAgIG0wMiA9IG1hdHJpeFs0XTsKKyAgICAgICAgICAgIG0xMiA9IG1hdHJpeFs1XTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBhZmZpbmUgdHJhbnNmb3JtIGJ5IHJlYWRpbmcgdGhlIHZhbHVlcyBvZiB0aGUKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbiBtYXRyaXggZnJvbSBhbiBhcnJheSBvZiBkb3VibGVzLiBUaGUgbWFwcGluZyBmcm9tIHRoZQorICAgICAqIGFycmF5IHRvIHRoZSBtYXRyaXggc3RhcnRzIHdpdGggPGNvZGU+bWF0cml4WzBdPC9jb2RlPiBnaXZpbmcgdGhlCisgICAgICogdG9wLWxlZnQgZW50cnkgb2YgdGhlIG1hdHJpeCBhbmQgcHJvY2VlZHMgd2l0aCB0aGUgdXN1YWwgbGVmdC10by1yaWdodAorICAgICAqIGFuZCB0b3AtZG93biBvcmRlcmluZy4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgYXJyYXkgaGFzIG9ubHkgZm91ciBlbnRyaWVzLCB0aGVuIHRoZSB0d28gZW50cmllcyBvZiB0aGUgbGFzdCByb3cKKyAgICAgKiBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4IGRlZmF1bHQgdG8gemVyby4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWF0cml4CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgZm91ciBvciBzaXggZG91YmxlcyBnaXZpbmcgdGhlIHZhbHVlcyBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIG1hdHJpeC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBhcnJheSBpcyAwLCAxLCAyLCAzLCBvciA1LgorICAgICAqLworICAgIHB1YmxpYyBBZmZpbmVUcmFuc2Zvcm0oZG91YmxlW10gbWF0cml4KSB7CisgICAgICAgIHRoaXMudHlwZSA9IFRZUEVfVU5LTk9XTjsKKyAgICAgICAgbTAwID0gbWF0cml4WzBdOworICAgICAgICBtMTAgPSBtYXRyaXhbMV07CisgICAgICAgIG0wMSA9IG1hdHJpeFsyXTsKKyAgICAgICAgbTExID0gbWF0cml4WzNdOworICAgICAgICBpZiAobWF0cml4Lmxlbmd0aCA+IDQpIHsKKyAgICAgICAgICAgIG0wMiA9IG1hdHJpeFs0XTsKKyAgICAgICAgICAgIG0xMiA9IG1hdHJpeFs1XTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHlwZSBvZiB0aGUgYWZmaW5lIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSB0eXBlIGlzIGNvbXB1dGVkIGFzIGZvbGxvd3M6IExhYmVsIHRoZSBlbnRyaWVzIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbgorICAgICAqIG1hdHJpeCBhcyB0aHJlZSByb3dzIChtMDAsIG0wMSksIChtMTAsIG0xMSksIGFuZCAobTAyLCBtMTIpLiBUaGVuIGlmIHRoZQorICAgICAqIG9yaWdpbmFsIGJhc2lzIHZlY3RvcnMgYXJlICgxLCAwKSBhbmQgKDAsIDEpLCB0aGUgbmV3IGJhc2lzIHZlY3RvcnMgYWZ0ZXIKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbiBhcmUgZ2l2ZW4gYnkgKG0wMCwgbTAxKSBhbmQgKG0xMCwgbTExKSwgYW5kIHRoZQorICAgICAqIHRyYW5zbGF0aW9uIHZlY3RvciBpcyAobTAyLCBtMTIpLgorICAgICAqIDxwPgorICAgICAqIFRoZSB0eXBlcyBhcmUgY2xhc3NpZmllZCBhcyBmb2xsb3dzOiA8YnIvPiBUWVBFX0lERU5USVRZIC0gbm8gY2hhbmdlPGJyLz4KKyAgICAgKiBUWVBFX1RSQU5TTEFUSU9OIC0gVGhlIHRyYW5zbGF0aW9uIHZlY3RvciBpc24ndCB6ZXJvPGJyLz4KKyAgICAgKiBUWVBFX1VOSUZPUk1fU0NBTEUgLSBUaGUgbmV3IGJhc2lzIHZlY3RvcnMgaGF2ZSBlcXVhbCBsZW5ndGg8YnIvPgorICAgICAqIFRZUEVfR0VORVJBTF9TQ0FMRSAtIFRoZSBuZXcgYmFzaXMgdmVjdG9ycyBkb250JyBoYXZlIGVxdWFsIGxlbmd0aDxici8+CisgICAgICogVFlQRV9GTElQIC0gVGhlIG5ldyBiYXNpcyB2ZWN0b3Igb3JpZW50YXRpb24gZGlmZmVycyBmcm9tIHRoZSBvcmlnaW5hbAorICAgICAqIG9uZTxici8+IFRZUEVfUVVBRFJBTlRfUk9UQVRJT04gLSBUaGUgbmV3IGJhc2lzIGlzIGEgcm90YXRpb24gb2YgdGhlCisgICAgICogb3JpZ2luYWwgYnkgOTAsIDE4MCwgMjcwLCBvciAzNjAgZGVncmVlczxici8+IFRZUEVfR0VORVJBTF9ST1RBVElPTiAtIFRoZQorICAgICAqIG5ldyBiYXNpcyBpcyBhIHJvdGF0aW9uIG9mIHRoZSBvcmlnaW5hbCBieSBhbiBhcmJpdHJhcnkgYW5nbGU8YnIvPgorICAgICAqIFRZUEVfR0VORVJBTF9UUkFOU0ZPUk0gLSBUaGUgdHJhbnNmb3JtYXRpb24gY2FuJ3QgYmUgaW52ZXJ0ZWQuPGJyLz4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgbXVsdGlwbGUgdHlwZXMgYXJlIHBvc3NpYmxlLCB0aHVzIHRoZSB0eXBlcyBjYW4gYmUgY29tYmluZWQKKyAgICAgKiB1c2luZyBiaXR3aXNlIGNvbWJpbmF0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoZSBBZmZpbmUgVHJhbnNmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgaWYgKHR5cGUgIT0gVFlQRV9VTktOT1dOKSB7CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIGludCB0eXBlID0gMDsKKworICAgICAgICBpZiAobTAwICogbTAxICsgbTEwICogbTExICE9IDAuMCkgeworICAgICAgICAgICAgdHlwZSB8PSBUWVBFX0dFTkVSQUxfVFJBTlNGT1JNOworICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBpZiAobTAyICE9IDAuMCB8fCBtMTIgIT0gMC4wKSB7CisgICAgICAgICAgICB0eXBlIHw9IFRZUEVfVFJBTlNMQVRJT047CisgICAgICAgIH0gZWxzZSBpZiAobTAwID09IDEuMCAmJiBtMTEgPT0gMS4wICYmIG0wMSA9PSAwLjAgJiYgbTEwID09IDAuMCkgeworICAgICAgICAgICAgdHlwZSA9IFRZUEVfSURFTlRJVFk7CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChtMDAgKiBtMTEgLSBtMDEgKiBtMTAgPCAwLjApIHsKKyAgICAgICAgICAgIHR5cGUgfD0gVFlQRV9GTElQOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIGR4ID0gbTAwICogbTAwICsgbTEwICogbTEwOworICAgICAgICBkb3VibGUgZHkgPSBtMDEgKiBtMDEgKyBtMTEgKiBtMTE7CisgICAgICAgIGlmIChkeCAhPSBkeSkgeworICAgICAgICAgICAgdHlwZSB8PSBUWVBFX0dFTkVSQUxfU0NBTEU7CisgICAgICAgIH0gZWxzZSBpZiAoZHggIT0gMS4wKSB7CisgICAgICAgICAgICB0eXBlIHw9IFRZUEVfVU5JRk9STV9TQ0FMRTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobTAwID09IDAuMCAmJiBtMTEgPT0gMC4wKSB8fCAobTEwID09IDAuMCAmJiBtMDEgPT0gMC4wICYmIChtMDAgPCAwLjAgfHwgbTExIDwgMC4wKSkpIHsKKyAgICAgICAgICAgIHR5cGUgfD0gVFlQRV9RVUFEUkFOVF9ST1RBVElPTjsKKyAgICAgICAgfSBlbHNlIGlmIChtMDEgIT0gMC4wIHx8IG0xMCAhPSAwLjApIHsKKyAgICAgICAgICAgIHR5cGUgfD0gVFlQRV9HRU5FUkFMX1JPVEFUSU9OOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NhbGUgeCBlbnRyeSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4ICh0aGUgdXBwZXIgbGVmdAorICAgICAqIG1hdHJpeCBlbnRyeSkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc2NhbGUgeCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldFNjYWxlWCgpIHsKKyAgICAgICAgcmV0dXJuIG0wMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzY2FsZSB5IGVudHJ5IG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXggKHRoZSBsb3dlciByaWdodAorICAgICAqIGVudHJ5IG9mIHRoZSBsaW5lYXIgdHJhbnNmb3JtYXRpb24pLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNjYWxlIHkgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRTY2FsZVkoKSB7CisgICAgICAgIHJldHVybiBtMTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2hlYXIgeCBlbnRyeSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4ICh0aGUgdXBwZXIgcmlnaHQKKyAgICAgKiBlbnRyeSBvZiB0aGUgbGluZWFyIHRyYW5zZm9ybWF0aW9uKS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzaGVhciB4IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0U2hlYXJYKCkgeworICAgICAgICByZXR1cm4gbTAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNoZWFyIHkgZW50cnkgb2YgdGhlIHRyYW5zZm9ybWF0aW9uIG1hdHJpeCAodGhlIGxvd2VyIGxlZnQgZW50cnkKKyAgICAgKiBvZiB0aGUgbGluZWFyIHRyYW5zZm9ybWF0aW9uKS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzaGVhciB5IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0U2hlYXJZKCkgeworICAgICAgICByZXR1cm4gbTEwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNsYXRpb24gdmVjdG9yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNsYXRpb24gdmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0VHJhbnNsYXRlWCgpIHsKKyAgICAgICAgcmV0dXJuIG0wMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRyYW5zbGF0aW9uIHZlY3Rvci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRyYW5zbGF0aW9uIHZlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldFRyYW5zbGF0ZVkoKSB7CisgICAgICAgIHJldHVybiBtMTI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBBZmZpbmVUcmFuc2Zvcm1hdGlvbiBpcyB0aGUgaWRlbnRpdHkuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlIGlkZW50aXR5LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpdHkoKSB7CisgICAgICAgIHJldHVybiBnZXRUeXBlKCkgPT0gVFlQRV9JREVOVElUWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHZhbHVlcyBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4IGludG8gdGhlIGdpdmVuIGFycmF5IG9mCisgICAgICogZG91Ymxlcy4gSWYgdGhlIGFycmF5IGhhcyBsZW5ndGggNCwgb25seSB0aGUgbGluZWFyIHRyYW5zZm9ybWF0aW9uIHBhcnQKKyAgICAgKiB3aWxsIGJlIHdyaXR0ZW4gaW50byBpdC4gSWYgaXQgaGFzIGxlbmd0aCBncmVhdGVyIHRoYW4gNCwgdGhlIHRyYW5zbGF0aW9uCisgICAgICogdmVjdG9yIHdpbGwgYmUgaW5jbHVkZWQgYXMgd2VsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWF0cml4CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgdG8gZmlsbCB3aXRoIHRoZSB2YWx1ZXMgb2YgdGhlIG1hdHJpeC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBhcnJheSBpcyAwLCAxLCAyLCAzLCBvciA1LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGdldE1hdHJpeChkb3VibGVbXSBtYXRyaXgpIHsKKyAgICAgICAgbWF0cml4WzBdID0gbTAwOworICAgICAgICBtYXRyaXhbMV0gPSBtMTA7CisgICAgICAgIG1hdHJpeFsyXSA9IG0wMTsKKyAgICAgICAgbWF0cml4WzNdID0gbTExOworICAgICAgICBpZiAobWF0cml4Lmxlbmd0aCA+IDQpIHsKKyAgICAgICAgICAgIG1hdHJpeFs0XSA9IG0wMjsKKyAgICAgICAgICAgIG1hdHJpeFs1XSA9IG0xMjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRldGVybWluYW50IG9mIHRoZSBsaW5lYXIgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRldGVybWluYW50IG9mIHRoZSBsaW5lYXIgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0RGV0ZXJtaW5hbnQoKSB7CisgICAgICAgIHJldHVybiBtMDAgKiBtMTEgLSBtMDEgKiBtMTA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdHJhbnNmb3JtIGluIHRlcm1zIG9mIGEgbGlzdCBvZiBkb3VibGUgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtMDAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDAgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTAgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDEgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTEgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDIgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqIEBwYXJhbSBtMTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTIgY29vcmRpbmF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gbWF0cml4LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRyYW5zZm9ybShkb3VibGUgbTAwLCBkb3VibGUgbTEwLCBkb3VibGUgbTAxLCBkb3VibGUgbTExLCBkb3VibGUgbTAyLCBkb3VibGUgbTEyKSB7CisgICAgICAgIHRoaXMudHlwZSA9IFRZUEVfVU5LTk9XTjsKKyAgICAgICAgdGhpcy5tMDAgPSBtMDA7CisgICAgICAgIHRoaXMubTEwID0gbTEwOworICAgICAgICB0aGlzLm0wMSA9IG0wMTsKKyAgICAgICAgdGhpcy5tMTEgPSBtMTE7CisgICAgICAgIHRoaXMubTAyID0gbTAyOworICAgICAgICB0aGlzLm0xMiA9IG0xMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0cmFuc2Zvcm0ncyBkYXRhIHRvIG1hdGNoIHRoZSBkYXRhIG9mIHRoZSB0cmFuc2Zvcm0gc2VudCBhcyBhCisgICAgICogcGFyYW1ldGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0CisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmb3JtIHRoYXQgZ2l2ZXMgdGhlIG5ldyB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSB0KSB7CisgICAgICAgIHR5cGUgPSB0LnR5cGU7CisgICAgICAgIHNldFRyYW5zZm9ybSh0Lm0wMCwgdC5tMTAsIHQubTAxLCB0Lm0xMSwgdC5tMDIsIHQubTEyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0cmFuc2Zvcm0gdG8gdGhlIGlkZW50aXR5IHRyYW5zZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUb0lkZW50aXR5KCkgeworICAgICAgICB0eXBlID0gVFlQRV9JREVOVElUWTsKKyAgICAgICAgbTAwID0gbTExID0gMS4wOworICAgICAgICBtMTAgPSBtMDEgPSBtMDIgPSBtMTIgPSAwLjA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdHJhbnNmb3JtYXRpb24gdG8gYSB0cmFuc2xhdGlvbiBhbG9uZS4gU2V0cyB0aGUgbGluZWFyIHBhcnQgb2YKKyAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gdG8gaWRlbnRpdHkgYW5kIHRoZSB0cmFuc2xhdGlvbiB2ZWN0b3IgdG8gdGhlIHZhbHVlcworICAgICAqIHNlbnQgYXMgcGFyYW1ldGVycy4gU2V0cyB0aGUgdHlwZSB0byA8Y29kZT5UWVBFX0lERU5USVRZPC9jb2RlPiBpZiB0aGUKKyAgICAgKiByZXN1bHRpbmcgQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlIGlkZW50aXR5IHRyYW5zZm9ybWF0aW9uLCBvdGhlcndpc2UKKyAgICAgKiBzZXRzIGl0IHRvIDxjb2RlPlRZUEVfVFJBTlNMQVRJT048L2NvZGU+LgorICAgICAqIAorICAgICAqIEBwYXJhbSBteAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIG15CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIGluIHRoZSB5IGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUb1RyYW5zbGF0aW9uKGRvdWJsZSBteCwgZG91YmxlIG15KSB7CisgICAgICAgIG0wMCA9IG0xMSA9IDEuMDsKKyAgICAgICAgbTAxID0gbTEwID0gMC4wOworICAgICAgICBtMDIgPSBteDsKKyAgICAgICAgbTEyID0gbXk7CisgICAgICAgIGlmIChteCA9PSAwLjAgJiYgbXkgPT0gMC4wKSB7CisgICAgICAgICAgICB0eXBlID0gVFlQRV9JREVOVElUWTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHR5cGUgPSBUWVBFX1RSQU5TTEFUSU9OOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdHJhbnNmb3JtYXRpb24gdG8gYmVpbmcgYSBzY2FsZSBhbG9uZSwgZWxpbWluYXRpbmcgcm90YXRpb24sCisgICAgICogc2hlYXIsIGFuZCB0cmFuc2xhdGlvbiBlbGVtZW50cy4gU2V0cyB0aGUgdHlwZSB0bworICAgICAqIDxjb2RlPlRZUEVfSURFTlRJVFk8L2NvZGU+IGlmIHRoZSByZXN1bHRpbmcgQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlCisgICAgICogaWRlbnRpdHkgdHJhbnNmb3JtYXRpb24sIG90aGVyd2lzZSBzZXRzIGl0IHRvIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIHNjeAorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB4IGRpcmVjdGlvbi4KKyAgICAgKiBAcGFyYW0gc2N5CisgICAgICogICAgICAgICAgICB0aGUgc2NhbGluZyBmYWN0b3IgaW4gdGhlIHkgZGlyZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRvU2NhbGUoZG91YmxlIHNjeCwgZG91YmxlIHNjeSkgeworICAgICAgICBtMDAgPSBzY3g7CisgICAgICAgIG0xMSA9IHNjeTsKKyAgICAgICAgbTEwID0gbTAxID0gbTAyID0gbTEyID0gMC4wOworICAgICAgICBpZiAoc2N4ICE9IDEuMCB8fCBzY3kgIT0gMS4wKSB7CisgICAgICAgICAgICB0eXBlID0gVFlQRV9VTktOT1dOOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHlwZSA9IFRZUEVfSURFTlRJVFk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0cmFuc2Zvcm1hdGlvbiB0byBiZWluZyBhIHNoZWFyIGFsb25lLCBlbGltaW5hdGluZyByb3RhdGlvbiwKKyAgICAgKiBzY2FsaW5nLCBhbmQgdHJhbnNsYXRpb24gZWxlbWVudHMuIFNldHMgdGhlIHR5cGUgdG8KKyAgICAgKiA8Y29kZT5UWVBFX0lERU5USVRZPC9jb2RlPiBpZiB0aGUgcmVzdWx0aW5nIEFmZmluZVRyYW5zZm9ybWF0aW9uIGlzIHRoZQorICAgICAqIGlkZW50aXR5IHRyYW5zZm9ybWF0aW9uLCBvdGhlcndpc2Ugc2V0cyBpdCB0byA8Y29kZT5UWVBFX1VOS05PV048L2NvZGU+LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzaHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGVhcmluZyBmYWN0b3IgaW4gdGhlIHggZGlyZWN0aW9uLgorICAgICAqIEBwYXJhbSBzaHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGVhcmluZyBmYWN0b3IgaW4gdGhlIHkgZGlyZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRvU2hlYXIoZG91YmxlIHNoeCwgZG91YmxlIHNoeSkgeworICAgICAgICBtMDAgPSBtMTEgPSAxLjA7CisgICAgICAgIG0wMiA9IG0xMiA9IDAuMDsKKyAgICAgICAgbTAxID0gc2h4OworICAgICAgICBtMTAgPSBzaHk7CisgICAgICAgIGlmIChzaHggIT0gMC4wIHx8IHNoeSAhPSAwLjApIHsKKyAgICAgICAgICAgIHR5cGUgPSBUWVBFX1VOS05PV047CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0eXBlID0gVFlQRV9JREVOVElUWTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRyYW5zZm9ybWF0aW9uIHRvIGJlaW5nIGEgcm90YXRpb24gYWxvbmUsIGVsaW1pbmF0aW5nIHNoZWFyaW5nLAorICAgICAqIHNjYWxpbmcsIGFuZCB0cmFuc2xhdGlvbiBlbGVtZW50cy4gU2V0cyB0aGUgdHlwZSB0bworICAgICAqIDxjb2RlPlRZUEVfSURFTlRJVFk8L2NvZGU+IGlmIHRoZSByZXN1bHRpbmcgQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlCisgICAgICogaWRlbnRpdHkgdHJhbnNmb3JtYXRpb24sIG90aGVyd2lzZSBzZXRzIGl0IHRvIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIGFuZ2xlCisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUb1JvdGF0aW9uKGRvdWJsZSBhbmdsZSkgeworICAgICAgICBkb3VibGUgc2luID0gTWF0aC5zaW4oYW5nbGUpOworICAgICAgICBkb3VibGUgY29zID0gTWF0aC5jb3MoYW5nbGUpOworICAgICAgICBpZiAoTWF0aC5hYnMoY29zKSA8IFpFUk8pIHsKKyAgICAgICAgICAgIGNvcyA9IDAuMDsKKyAgICAgICAgICAgIHNpbiA9IHNpbiA+IDAuMCA/IDEuMCA6IC0xLjA7CisgICAgICAgIH0gZWxzZSBpZiAoTWF0aC5hYnMoc2luKSA8IFpFUk8pIHsKKyAgICAgICAgICAgIHNpbiA9IDAuMDsKKyAgICAgICAgICAgIGNvcyA9IGNvcyA+IDAuMCA/IDEuMCA6IC0xLjA7CisgICAgICAgIH0KKyAgICAgICAgbTAwID0gbTExID0gY29zOworICAgICAgICBtMDEgPSAtc2luOworICAgICAgICBtMTAgPSBzaW47CisgICAgICAgIG0wMiA9IG0xMiA9IDAuMDsKKyAgICAgICAgdHlwZSA9IFRZUEVfVU5LTk9XTjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0cmFuc2Zvcm1hdGlvbiB0byBiZWluZyBhIHJvdGF0aW9uIGZvbGxvd2VkIGJ5IGEgdHJhbnNsYXRpb24uCisgICAgICogU2V0cyB0aGUgdHlwZSB0byA8Y29kZT5UWVBFX1VOS05PV048L2NvZGU+LgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbmdsZQorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnMuCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIGluIHRoZSB4IGRpcmVjdGlvbi4KKyAgICAgKiBAcGFyYW0gcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSB0byB0cmFuc2xhdGUgaW4gdGhlIHkgZGlyZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRvUm90YXRpb24oZG91YmxlIGFuZ2xlLCBkb3VibGUgcHgsIGRvdWJsZSBweSkgeworICAgICAgICBzZXRUb1JvdGF0aW9uKGFuZ2xlKTsKKyAgICAgICAgbTAyID0gcHggKiAoMS4wIC0gbTAwKSArIHB5ICogbTEwOworICAgICAgICBtMTIgPSBweSAqICgxLjAgLSBtMDApIC0gcHggKiBtMTA7CisgICAgICAgIHR5cGUgPSBUWVBFX1VOS05PV047CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBBZmZpbmVUcmFuc2Zvcm1hdGlvbiB0aGF0IGlzIGEgdHJhbnNsYXRpb24gYWxvbmUgd2l0aCB0aGUKKyAgICAgKiB0cmFuc2xhdGlvbiB2ZWN0b3IgZ2l2ZW4gYnkgdGhlIHZhbHVlcyBzZW50IGFzIHBhcmFtZXRlcnMuIFRoZSBuZXcKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbidzIHR5cGUgaXMgPGNvZGU+VFlQRV9JREVOVElUWTwvY29kZT4gaWYgdGhlCisgICAgICogQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlIGlkZW50aXR5IHRyYW5zZm9ybWF0aW9uLCBvdGhlcndpc2UgaXQncworICAgICAqIDxjb2RlPlRZUEVfVFJBTlNMQVRJT048L2NvZGU+LgorICAgICAqIAorICAgICAqIEBwYXJhbSBteAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIG15CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIGluIHRoZSB5IGRpcmVjdGlvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgQWZmaW5lVHJhbnNmb3JtYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBZmZpbmVUcmFuc2Zvcm0gZ2V0VHJhbnNsYXRlSW5zdGFuY2UoZG91YmxlIG14LCBkb3VibGUgbXkpIHsKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHQgPSBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgICAgIHQuc2V0VG9UcmFuc2xhdGlvbihteCwgbXkpOworICAgICAgICByZXR1cm4gdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEFmZmluZVRyYW5zZm9ybWF0aW9uIHRoYXQgaXMgYSBzY2FsZSBhbG9uZS4gVGhlIG5ldworICAgICAqIHRyYW5zZm9ybWF0aW9uJ3MgdHlwZSBpcyA8Y29kZT5UWVBFX0lERU5USVRZPC9jb2RlPiBpZiB0aGUKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm1hdGlvbiBpcyB0aGUgaWRlbnRpdHkgdHJhbnNmb3JtYXRpb24sIG90aGVyd2lzZSBpdCdzCisgICAgICogPGNvZGU+VFlQRV9VTktOT1dOPC9jb2RlPi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2N4CisgICAgICogICAgICAgICAgICB0aGUgc2NhbGluZyBmYWN0b3IgaW4gdGhlIHggZGlyZWN0aW9uLgorICAgICAqIEBwYXJhbSBzY1kKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeSBkaXJlY3Rpb24uCisgICAgICogQHJldHVybiB0aGUgbmV3IEFmZmluZVRyYW5zZm9ybWF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQWZmaW5lVHJhbnNmb3JtIGdldFNjYWxlSW5zdGFuY2UoZG91YmxlIHNjeCwgZG91YmxlIHNjWSkgeworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdCA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICAgICAgdC5zZXRUb1NjYWxlKHNjeCwgc2NZKTsKKyAgICAgICAgcmV0dXJuIHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBBZmZpbmVUcmFuc2Zvcm1hdGlvbiB0aGF0IGlzIGEgc2hlYXIgYWxvbmUuIFRoZSBuZXcKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbidzIHR5cGUgaXMgPGNvZGU+VFlQRV9JREVOVElUWTwvY29kZT4gaWYgdGhlCisgICAgICogQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlIGlkZW50aXR5IHRyYW5zZm9ybWF0aW9uLCBvdGhlcndpc2UgaXQncworICAgICAqIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIHNoeAorICAgICAqICAgICAgICAgICAgdGhlIHNoZWFyaW5nIGZhY3RvciBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIHNoeQorICAgICAqICAgICAgICAgICAgdGhlIHNoZWFyaW5nIGZhY3RvciBpbiB0aGUgeSBkaXJlY3Rpb24uCisgICAgICogQHJldHVybiB0aGUgbmV3IEFmZmluZVRyYW5zZm9ybWF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQWZmaW5lVHJhbnNmb3JtIGdldFNoZWFySW5zdGFuY2UoZG91YmxlIHNoeCwgZG91YmxlIHNoeSkgeworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gbSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICAgICAgbS5zZXRUb1NoZWFyKHNoeCwgc2h5KTsKKyAgICAgICAgcmV0dXJuIG07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBBZmZpbmVUcmFuc2Zvcm1hdGlvbiB0aGF0IGlzIGEgcm90YXRpb24gYWxvbmUuIFRoZSBuZXcKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbidzIHR5cGUgaXMgPGNvZGU+VFlQRV9JREVOVElUWTwvY29kZT4gaWYgdGhlCisgICAgICogQWZmaW5lVHJhbnNmb3JtYXRpb24gaXMgdGhlIGlkZW50aXR5IHRyYW5zZm9ybWF0aW9uLCBvdGhlcndpc2UgaXQncworICAgICAqIDxjb2RlPlRZUEVfVU5LTk9XTjwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIGFuZ2xlCisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFucy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgQWZmaW5lVHJhbnNmb3JtYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBZmZpbmVUcmFuc2Zvcm0gZ2V0Um90YXRlSW5zdGFuY2UoZG91YmxlIGFuZ2xlKSB7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0ID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICB0LnNldFRvUm90YXRpb24oYW5nbGUpOworICAgICAgICByZXR1cm4gdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEFmZmluZVRyYW5zZm9ybWF0aW9uIHRoYXQgaXMgYSByb3RhdGlvbiBmb2xsb3dlZCBieSBhCisgICAgICogdHJhbnNsYXRpb24uIFNldHMgdGhlIHR5cGUgdG8gPGNvZGU+VFlQRV9VTktOT1dOPC9jb2RlPi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYW5nbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIGluIHRoZSB4IGRpcmVjdGlvbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBpbiB0aGUgeSBkaXJlY3Rpb24uCisgICAgICogQHJldHVybiB0aGUgbmV3IEFmZmluZVRyYW5zZm9ybWF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQWZmaW5lVHJhbnNmb3JtIGdldFJvdGF0ZUluc3RhbmNlKGRvdWJsZSBhbmdsZSwgZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0ID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICB0LnNldFRvUm90YXRpb24oYW5nbGUsIHgsIHkpOworICAgICAgICByZXR1cm4gdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIGEgdHJhbnNsYXRpb24gdG8gdGhpcyBBZmZpbmVUcmFuc2Zvcm1hdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSB0byB0cmFuc2xhdGUgaW4gdGhlIHggZGlyZWN0aW9uLgorICAgICAqIEBwYXJhbSBteQorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBpbiB0aGUgeSBkaXJlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKGRvdWJsZSBteCwgZG91YmxlIG15KSB7CisgICAgICAgIGNvbmNhdGVuYXRlKEFmZmluZVRyYW5zZm9ybS5nZXRUcmFuc2xhdGVJbnN0YW5jZShteCwgbXkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIGEgc2NhbGluZyB0cmFuc2Zvcm1hdGlvbiB0byB0aGlzIEFmZmluZVRyYW5zZm9ybWF0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzY3gKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIHNjeQorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB5IGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzY2FsZShkb3VibGUgc2N4LCBkb3VibGUgc2N5KSB7CisgICAgICAgIGNvbmNhdGVuYXRlKEFmZmluZVRyYW5zZm9ybS5nZXRTY2FsZUluc3RhbmNlKHNjeCwgc2N5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbGllcyBhIHNoZWFyaW5nIHRyYW5zZm9ybWF0aW9uIHRvIHRoaXMgQWZmaW5lVHJhbnNmb3JtYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHNoeAorICAgICAqICAgICAgICAgICAgdGhlIHNoZWFyaW5nIGZhY3RvciBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIHNoeQorICAgICAqICAgICAgICAgICAgdGhlIHNoZWFyaW5nIGZhY3RvciBpbiB0aGUgeSBkaXJlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2hlYXIoZG91YmxlIHNoeCwgZG91YmxlIHNoeSkgeworICAgICAgICBjb25jYXRlbmF0ZShBZmZpbmVUcmFuc2Zvcm0uZ2V0U2hlYXJJbnN0YW5jZShzaHgsIHNoeSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgYSByb3RhdGlvbiB0cmFuc2Zvcm1hdGlvbiB0byB0aGlzIEFmZmluZVRyYW5zZm9ybWF0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbmdsZQorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcm90YXRlKGRvdWJsZSBhbmdsZSkgeworICAgICAgICBjb25jYXRlbmF0ZShBZmZpbmVUcmFuc2Zvcm0uZ2V0Um90YXRlSW5zdGFuY2UoYW5nbGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIGEgcm90YXRpb24gYW5kIHRyYW5zbGF0aW9uIHRyYW5zZm9ybWF0aW9uIHRvIHRoaXMKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm1hdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYW5nbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zLgorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRvIHRyYW5zbGF0ZSBpbiB0aGUgeCBkaXJlY3Rpb24uCisgICAgICogQHBhcmFtIHB5CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdG8gdHJhbnNsYXRlIGluIHRoZSB5IGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByb3RhdGUoZG91YmxlIGFuZ2xlLCBkb3VibGUgcHgsIGRvdWJsZSBweSkgeworICAgICAgICBjb25jYXRlbmF0ZShBZmZpbmVUcmFuc2Zvcm0uZ2V0Um90YXRlSW5zdGFuY2UoYW5nbGUsIHB4LCBweSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE11bHRpcGxpZXMgdGhlIG1hdHJpeCByZXByZXNlbnRhdGlvbnMgb2YgdHdvIEFmZmluZVRyYW5zZm9ybSBvYmplY3RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0MQorICAgICAqICAgICAgICAgICAgLSB0aGUgQWZmaW5lVHJhbnNmb3JtIG9iamVjdCBpcyBhIG11bHRpcGxpY2FuZAorICAgICAqIEBwYXJhbSB0MgorICAgICAqICAgICAgICAgICAgLSB0aGUgQWZmaW5lVHJhbnNmb3JtIG9iamVjdCBpcyBhIG11bHRpcGxpZXIKKyAgICAgKiBAcmV0dXJuIGFuIEFmZmluZVRyYW5zZm9ybSBvYmplY3QgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHQxIG11bHRpcGxpZWQgYnkKKyAgICAgKiAgICAgICAgIHRoZSBtYXRyaXggdDIuCisgICAgICovCisgICAgQWZmaW5lVHJhbnNmb3JtIG11bHRpcGx5KEFmZmluZVRyYW5zZm9ybSB0MSwgQWZmaW5lVHJhbnNmb3JtIHQyKSB7CisgICAgICAgIHJldHVybiBuZXcgQWZmaW5lVHJhbnNmb3JtKHQxLm0wMCAqIHQyLm0wMCArIHQxLm0xMCAqIHQyLm0wMSwgLy8gbTAwCisgICAgICAgICAgICAgICAgdDEubTAwICogdDIubTEwICsgdDEubTEwICogdDIubTExLCAvLyBtMDEKKyAgICAgICAgICAgICAgICB0MS5tMDEgKiB0Mi5tMDAgKyB0MS5tMTEgKiB0Mi5tMDEsIC8vIG0xMAorICAgICAgICAgICAgICAgIHQxLm0wMSAqIHQyLm0xMCArIHQxLm0xMSAqIHQyLm0xMSwgLy8gbTExCisgICAgICAgICAgICAgICAgdDEubTAyICogdDIubTAwICsgdDEubTEyICogdDIubTAxICsgdDIubTAyLCAvLyBtMDIKKyAgICAgICAgICAgICAgICB0MS5tMDIgKiB0Mi5tMTAgKyB0MS5tMTIgKiB0Mi5tMTEgKyB0Mi5tMTIpOy8vIG0xMgorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgdGhlIGdpdmVuIEFmZmluZVRyYW5zZm9ybSB0byB0aGlzIEFmZmluZVRyYW5zZm9ybSB2aWEgbWF0cml4CisgICAgICogbXVsdGlwbGljYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gdG8gYXBwbHkgdG8gdGhpcyBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29uY2F0ZW5hdGUoQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgc2V0VHJhbnNmb3JtKG11bHRpcGx5KHQsIHRoaXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2VzIHRoZSBjdXJyZW50IEFmZmluZVRyYW5zZm9ybSB0aGUgb25lIG9idGFpbmVkIGJ5IHRha2luZyB0aGUKKyAgICAgKiB0cmFuc2Zvcm0gdCBhbmQgYXBwbHlpbmcgdGhpcyBBZmZpbmVUcmFuc2Zvcm0gdG8gaXQuCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gdGhhdCB0aGlzIEFmZmluZVRyYW5zZm9ybSBpcyBtdWx0aXBsaWVkCisgICAgICogICAgICAgICAgICBieS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmVDb25jYXRlbmF0ZShBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICBzZXRUcmFuc2Zvcm0obXVsdGlwbHkodGhpcywgdCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gQWZmaW5lVHJhbnNmb3JtIHRoYXQgaXMgdGhlIGludmVyc2Ugb2YgdGhpcyB0cmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYWZmaW5lIHRyYW5zZm9ybSB0aGF0IGlzIHRoZSBpbnZlcnNlIG9mIHRoaXMgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqIEB0aHJvd3MgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgQWZmaW5lVHJhbnNmb3JtIGNhbm5vdCBiZSBpbnZlcnRlZCAodGhlIGRldGVybWluYW50CisgICAgICogICAgICAgICAgICAgb2YgdGhlIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBwYXJ0IGlzIHplcm8pLgorICAgICAqLworICAgIHB1YmxpYyBBZmZpbmVUcmFuc2Zvcm0gY3JlYXRlSW52ZXJzZSgpIHRocm93cyBOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIHsKKyAgICAgICAgZG91YmxlIGRldCA9IGdldERldGVybWluYW50KCk7CisgICAgICAgIGlmIChNYXRoLmFicyhkZXQpIDwgWkVSTykgeworICAgICAgICAgICAgLy8gYXd0LjIwND1EZXRlcm1pbmFudCBpcyB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEFmZmluZVRyYW5zZm9ybShtMTEgLyBkZXQsIC8vIG0wMAorICAgICAgICAgICAgICAgIC1tMTAgLyBkZXQsIC8vIG0xMAorICAgICAgICAgICAgICAgIC1tMDEgLyBkZXQsIC8vIG0wMQorICAgICAgICAgICAgICAgIG0wMCAvIGRldCwgLy8gbTExCisgICAgICAgICAgICAgICAgKG0wMSAqIG0xMiAtIG0xMSAqIG0wMikgLyBkZXQsIC8vIG0wMgorICAgICAgICAgICAgICAgIChtMTAgKiBtMDIgLSBtMDAgKiBtMTIpIC8gZGV0IC8vIG0xMgorICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGx5IHRoZSBjdXJyZW50IEFmZmluZVRyYW5zZm9ybSB0byB0aGUgcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIHBvaW50LgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIFBvaW50MkQgb2JqZWN0IHRvIGJlIGZpbGxlZCB3aXRoIHRoZSBkZXN0aW5hdGlvbiBjb29yZGluYXRlcworICAgICAqICAgICAgICAgICAgKHdoZXJlIHRoZSBvcmlnaW5hbCBwb2ludCBpcyBzZW50IGJ5IHRoaXMgQWZmaW5lVHJhbnNmb3JtKS4KKyAgICAgKiAgICAgICAgICAgIE1heSBiZSBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIHBvaW50IGluIHRoZSBBZmZpbmVUcmFuc2Zvcm0ncyBpbWFnZSBzcGFjZSB3aGVyZSB0aGUgb3JpZ2luYWwKKyAgICAgKiAgICAgICAgIHBvaW50IGlzIHNlbnQuCisgICAgICovCisgICAgcHVibGljIFBvaW50MkQgdHJhbnNmb3JtKFBvaW50MkQgc3JjLCBQb2ludDJEIGRzdCkgeworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChzcmMgaW5zdGFuY2VvZiBQb2ludDJELkRvdWJsZSkgeworICAgICAgICAgICAgICAgIGRzdCA9IG5ldyBQb2ludDJELkRvdWJsZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkc3QgPSBuZXcgUG9pbnQyRC5GbG9hdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIHggPSBzcmMuZ2V0WCgpOworICAgICAgICBkb3VibGUgeSA9IHNyYy5nZXRZKCk7CisKKyAgICAgICAgZHN0LnNldExvY2F0aW9uKHggKiBtMDAgKyB5ICogbTAxICsgbTAyLCB4ICogbTEwICsgeSAqIG0xMSArIG0xMik7CisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbGllcyB0aGlzIEFmZmluZVRyYW5zZm9ybSB0byBhbiBhcnJheSBvZiBwb2ludHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gc3JjT2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzb3VyY2UgcG9pbnQgYXJyYXkgb2YgdGhlIGZpcnN0IHBvaW50IHRvIGJlCisgICAgICogICAgICAgICAgICB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgYXJyYXkgd2hlcmUgdGhlIGltYWdlcyBvZiB0aGUgcG9pbnRzIChhZnRlciBhcHBseWluZworICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybWF0aW9uKSBzaG91bGQgYmUgcGxhY2VkLgorICAgICAqIEBwYXJhbSBkc3RPZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5IHdoZXJlIHRoZSBuZXcgdmFsdWVzCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvaW50cyB0byB0cmFuc2Zvcm0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5zcmNPZmYgKyBsZW5ndGggPiBzcmMubGVuZ3RoPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgICAgIDxjb2RlPmRzdE9mZiArIGxlbmd0aCA+IGRzdC5sZW5ndGg8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShQb2ludDJEW10gc3JjLCBpbnQgc3JjT2ZmLCBQb2ludDJEW10gZHN0LCBpbnQgZHN0T2ZmLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHdoaWxlICgtLWxlbmd0aCA+PSAwKSB7CisgICAgICAgICAgICBQb2ludDJEIHNyY1BvaW50ID0gc3JjW3NyY09mZisrXTsKKyAgICAgICAgICAgIGRvdWJsZSB4ID0gc3JjUG9pbnQuZ2V0WCgpOworICAgICAgICAgICAgZG91YmxlIHkgPSBzcmNQb2ludC5nZXRZKCk7CisgICAgICAgICAgICBQb2ludDJEIGRzdFBvaW50ID0gZHN0W2RzdE9mZl07CisgICAgICAgICAgICBpZiAoZHN0UG9pbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChzcmNQb2ludCBpbnN0YW5jZW9mIFBvaW50MkQuRG91YmxlKSB7CisgICAgICAgICAgICAgICAgICAgIGRzdFBvaW50ID0gbmV3IFBvaW50MkQuRG91YmxlKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZHN0UG9pbnQgPSBuZXcgUG9pbnQyRC5GbG9hdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRzdFBvaW50LnNldExvY2F0aW9uKHggKiBtMDAgKyB5ICogbTAxICsgbTAyLCB4ICogbTEwICsgeSAqIG0xMSArIG0xMik7CisgICAgICAgICAgICBkc3RbZHN0T2ZmKytdID0gZHN0UG9pbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIHRoaXMgQWZmaW5lVHJhbnNmb3JtIHRvIGEgc2V0IG9mIHBvaW50cyBnaXZlbiBhcyBhbiBhcnJheSBvZgorICAgICAqIGRvdWJsZSB2YWx1ZXMgd2hlcmUgZXZlcnkgdHdvIHZhbHVlcyBpbiB0aGUgYXJyYXkgZ2l2ZSB0aGUgY29vcmRpbmF0ZXMgb2YKKyAgICAgKiBhIHBvaW50OyB0aGUgZXZlbi1pbmRleGVkIHZhbHVlcyBnaXZpbmcgdGhlIHggY29vcmRpbmF0ZXMgYW5kIHRoZQorICAgICAqIG9kZC1pbmRleGVkIHZhbHVlcyBnaXZpbmcgdGhlIHkgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gc3JjT2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzb3VyY2UgcG9pbnQgYXJyYXkgb2YgdGhlIGZpcnN0IHBvaW50IHRvIGJlCisgICAgICogICAgICAgICAgICB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgYXJyYXkgd2hlcmUgdGhlIGltYWdlcyBvZiB0aGUgcG9pbnRzIChhZnRlciBhcHBseWluZworICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybWF0aW9uKSBzaG91bGQgYmUgcGxhY2VkLgorICAgICAqIEBwYXJhbSBkc3RPZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5IHdoZXJlIHRoZSBuZXcgdmFsdWVzCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvaW50cyB0byB0cmFuc2Zvcm0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5zcmNPZmYgKyBsZW5ndGgqMiA+IHNyYy5sZW5ndGg8L2NvZGU+IG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+ZHN0T2ZmICsgbGVuZ3RoKjIgPiBkc3QubGVuZ3RoPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oZG91YmxlW10gc3JjLCBpbnQgc3JjT2ZmLCBkb3VibGVbXSBkc3QsIGludCBkc3RPZmYsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaW50IHN0ZXAgPSAyOworICAgICAgICBpZiAoc3JjID09IGRzdCAmJiBzcmNPZmYgPCBkc3RPZmYgJiYgZHN0T2ZmIDwgc3JjT2ZmICsgbGVuZ3RoICogMikgeworICAgICAgICAgICAgc3JjT2ZmID0gc3JjT2ZmICsgbGVuZ3RoICogMiAtIDI7CisgICAgICAgICAgICBkc3RPZmYgPSBkc3RPZmYgKyBsZW5ndGggKiAyIC0gMjsKKyAgICAgICAgICAgIHN0ZXAgPSAtMjsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoLS1sZW5ndGggPj0gMCkgeworICAgICAgICAgICAgZG91YmxlIHggPSBzcmNbc3JjT2ZmICsgMF07CisgICAgICAgICAgICBkb3VibGUgeSA9IHNyY1tzcmNPZmYgKyAxXTsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYgKyAwXSA9IHggKiBtMDAgKyB5ICogbTAxICsgbTAyOworICAgICAgICAgICAgZHN0W2RzdE9mZiArIDFdID0geCAqIG0xMCArIHkgKiBtMTEgKyBtMTI7CisgICAgICAgICAgICBzcmNPZmYgKz0gc3RlcDsKKyAgICAgICAgICAgIGRzdE9mZiArPSBzdGVwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbGllcyB0aGlzIEFmZmluZVRyYW5zZm9ybSB0byBhIHNldCBvZiBwb2ludHMgZ2l2ZW4gYXMgYW4gYXJyYXkgb2YKKyAgICAgKiBmbG9hdCB2YWx1ZXMgd2hlcmUgZXZlcnkgdHdvIHZhbHVlcyBpbiB0aGUgYXJyYXkgZ2l2ZSB0aGUgY29vcmRpbmF0ZXMgb2YKKyAgICAgKiBhIHBvaW50OyB0aGUgZXZlbi1pbmRleGVkIHZhbHVlcyBnaXZpbmcgdGhlIHggY29vcmRpbmF0ZXMgYW5kIHRoZQorICAgICAqIG9kZC1pbmRleGVkIHZhbHVlcyBnaXZpbmcgdGhlIHkgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gc3JjT2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzb3VyY2UgcG9pbnQgYXJyYXkgb2YgdGhlIGZpcnN0IHBvaW50IHRvIGJlCisgICAgICogICAgICAgICAgICB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgYXJyYXkgd2hlcmUgdGhlIGltYWdlcyBvZiB0aGUgcG9pbnRzIChhZnRlciBhcHBseWluZworICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybWF0aW9uKSBzaG91bGQgYmUgcGxhY2VkLgorICAgICAqIEBwYXJhbSBkc3RPZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5IHdoZXJlIHRoZSBuZXcgdmFsdWVzCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvaW50cyB0byB0cmFuc2Zvcm0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5zcmNPZmYgKyBsZW5ndGgqMiA+IHNyYy5sZW5ndGg8L2NvZGU+IG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+ZHN0T2ZmICsgbGVuZ3RoKjIgPiBkc3QubGVuZ3RoPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oZmxvYXRbXSBzcmMsIGludCBzcmNPZmYsIGZsb2F0W10gZHN0LCBpbnQgZHN0T2ZmLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGludCBzdGVwID0gMjsKKyAgICAgICAgaWYgKHNyYyA9PSBkc3QgJiYgc3JjT2ZmIDwgZHN0T2ZmICYmIGRzdE9mZiA8IHNyY09mZiArIGxlbmd0aCAqIDIpIHsKKyAgICAgICAgICAgIHNyY09mZiA9IHNyY09mZiArIGxlbmd0aCAqIDIgLSAyOworICAgICAgICAgICAgZHN0T2ZmID0gZHN0T2ZmICsgbGVuZ3RoICogMiAtIDI7CisgICAgICAgICAgICBzdGVwID0gLTI7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKC0tbGVuZ3RoID49IDApIHsKKyAgICAgICAgICAgIGZsb2F0IHggPSBzcmNbc3JjT2ZmICsgMF07CisgICAgICAgICAgICBmbG9hdCB5ID0gc3JjW3NyY09mZiArIDFdOworICAgICAgICAgICAgZHN0W2RzdE9mZiArIDBdID0gKGZsb2F0KSh4ICogbTAwICsgeSAqIG0wMSArIG0wMik7CisgICAgICAgICAgICBkc3RbZHN0T2ZmICsgMV0gPSAoZmxvYXQpKHggKiBtMTAgKyB5ICogbTExICsgbTEyKTsKKyAgICAgICAgICAgIHNyY09mZiArPSBzdGVwOworICAgICAgICAgICAgZHN0T2ZmICs9IHN0ZXA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIHRoaXMgQWZmaW5lVHJhbnNmb3JtIHRvIGEgc2V0IG9mIHBvaW50cyBnaXZlbiBhcyBhbiBhcnJheSBvZgorICAgICAqIGZsb2F0IHZhbHVlcyB3aGVyZSBldmVyeSB0d28gdmFsdWVzIGluIHRoZSBhcnJheSBnaXZlIHRoZSBjb29yZGluYXRlcyBvZgorICAgICAqIGEgcG9pbnQ7IHRoZSBldmVuLWluZGV4ZWQgdmFsdWVzIGdpdmluZyB0aGUgeCBjb29yZGluYXRlcyBhbmQgdGhlCisgICAgICogb2RkLWluZGV4ZWQgdmFsdWVzIGdpdmluZyB0aGUgeSBjb29yZGluYXRlcy4gVGhlIGRlc3RpbmF0aW9uIGNvb3JkaW5hdGVzCisgICAgICogYXJlIGdpdmVuIGFzIHZhbHVlcyBvZiB0eXBlIDxjb2RlPmRvdWJsZTwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gc3JjT2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzb3VyY2UgcG9pbnQgYXJyYXkgb2YgdGhlIGZpcnN0IHBvaW50IHRvIGJlCisgICAgICogICAgICAgICAgICB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgYXJyYXkgd2hlcmUgdGhlIGltYWdlcyBvZiB0aGUgcG9pbnRzIChhZnRlciBhcHBseWluZworICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybWF0aW9uKSBzaG91bGQgYmUgcGxhY2VkLgorICAgICAqIEBwYXJhbSBkc3RPZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5IHdoZXJlIHRoZSBuZXcgdmFsdWVzCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvaW50cyB0byB0cmFuc2Zvcm0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5zcmNPZmYgKyBsZW5ndGgqMiA+IHNyYy5sZW5ndGg8L2NvZGU+IG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+ZHN0T2ZmICsgbGVuZ3RoKjIgPiBkc3QubGVuZ3RoPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oZmxvYXRbXSBzcmMsIGludCBzcmNPZmYsIGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZiwgaW50IGxlbmd0aCkgeworICAgICAgICB3aGlsZSAoLS1sZW5ndGggPj0gMCkgeworICAgICAgICAgICAgZmxvYXQgeCA9IHNyY1tzcmNPZmYrK107CisgICAgICAgICAgICBmbG9hdCB5ID0gc3JjW3NyY09mZisrXTsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYrK10gPSB4ICogbTAwICsgeSAqIG0wMSArIG0wMjsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYrK10gPSB4ICogbTEwICsgeSAqIG0xMSArIG0xMjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgdGhpcyBBZmZpbmVUcmFuc2Zvcm0gdG8gYSBzZXQgb2YgcG9pbnRzIGdpdmVuIGFzIGFuIGFycmF5IG9mCisgICAgICogZG91YmxlIHZhbHVlcyB3aGVyZSBldmVyeSB0d28gdmFsdWVzIGluIHRoZSBhcnJheSBnaXZlIHRoZSBjb29yZGluYXRlcyBvZgorICAgICAqIGEgcG9pbnQ7IHRoZSBldmVuLWluZGV4ZWQgdmFsdWVzIGdpdmluZyB0aGUgeCBjb29yZGluYXRlcyBhbmQgdGhlCisgICAgICogb2RkLWluZGV4ZWQgdmFsdWVzIGdpdmluZyB0aGUgeSBjb29yZGluYXRlcy4gVGhlIGRlc3RpbmF0aW9uIGNvb3JkaW5hdGVzCisgICAgICogYXJlIGdpdmVuIGFzIHZhbHVlcyBvZiB0eXBlIDxjb2RlPmZsb2F0PC9jb2RlPi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgcG9pbnRzIHRvIGJlIHRyYW5zZm9ybWVkLgorICAgICAqIEBwYXJhbSBzcmNPZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIHNvdXJjZSBwb2ludCBhcnJheSBvZiB0aGUgZmlyc3QgcG9pbnQgdG8gYmUKKyAgICAgKiAgICAgICAgICAgIHRyYW5zZm9ybWVkLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBhcnJheSB3aGVyZSB0aGUgaW1hZ2VzIG9mIHRoZSBwb2ludHMgKGFmdGVyIGFwcGx5aW5nCisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtYXRpb24pIHNob3VsZCBiZSBwbGFjZWQuCisgICAgICogQHBhcmFtIGRzdE9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYXJyYXkgd2hlcmUgdGhlIG5ldyB2YWx1ZXMKKyAgICAgKiAgICAgICAgICAgIHNob3VsZCBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgcG9pbnRzIHRvIHRyYW5zZm9ybS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIDxjb2RlPnNyY09mZiArIGxlbmd0aCoyID4gc3JjLmxlbmd0aDwvY29kZT4gb3IKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5kc3RPZmYgKyBsZW5ndGgqMiA+IGRzdC5sZW5ndGg8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShkb3VibGVbXSBzcmMsIGludCBzcmNPZmYsIGZsb2F0W10gZHN0LCBpbnQgZHN0T2ZmLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHdoaWxlICgtLWxlbmd0aCA+PSAwKSB7CisgICAgICAgICAgICBkb3VibGUgeCA9IHNyY1tzcmNPZmYrK107CisgICAgICAgICAgICBkb3VibGUgeSA9IHNyY1tzcmNPZmYrK107CisgICAgICAgICAgICBkc3RbZHN0T2ZmKytdID0gKGZsb2F0KSh4ICogbTAwICsgeSAqIG0wMSArIG0wMik7CisgICAgICAgICAgICBkc3RbZHN0T2ZmKytdID0gKGZsb2F0KSh4ICogbTEwICsgeSAqIG0xMSArIG0xMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2Zvcm1zIHRoZSBwb2ludCBhY2NvcmRpbmcgdG8gdGhlIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBwYXJ0IG9mIHRoaXMKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm1hdGlvbiAod2l0aG91dCBhcHBseWluZyB0aGUgdHJhbnNsYXRpb24pLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcmlnaW5hbCBwb2ludC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgb2JqZWN0IHdoZXJlIHRoZSByZXN1bHQgb2YgdGhlIGRlbHRhIHRyYW5zZm9ybSBpcworICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlIGRlbHRhIHRyYW5zZm9ybSAobGluZWFyIHBhcnQgb25seSkgdG8KKyAgICAgKiAgICAgICAgIHRoZSBvcmlnaW5hbCBwb2ludC4KKyAgICAgKi8KKyAgICAvLyBUT0RPOiBpcyB0aGlzIHJpZ2h0PyBpZiBkc3QgaXMgbnVsbCwgd2UgY2hlY2sgd2hhdCBpdCdzIGFuCisgICAgLy8gaW5zdGFuY2Ugb2Y/IFNob3VsZG4ndCBpdCBiZSBzcmMgaW5zdGFuY2VvZiBQb2ludDJELkRvdWJsZT8KKyAgICBwdWJsaWMgUG9pbnQyRCBkZWx0YVRyYW5zZm9ybShQb2ludDJEIHNyYywgUG9pbnQyRCBkc3QpIHsKKyAgICAgICAgaWYgKGRzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZHN0IGluc3RhbmNlb2YgUG9pbnQyRC5Eb3VibGUpIHsKKyAgICAgICAgICAgICAgICBkc3QgPSBuZXcgUG9pbnQyRC5Eb3VibGUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZHN0ID0gbmV3IFBvaW50MkQuRmxvYXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSB4ID0gc3JjLmdldFgoKTsKKyAgICAgICAgZG91YmxlIHkgPSBzcmMuZ2V0WSgpOworCisgICAgICAgIGRzdC5zZXRMb2NhdGlvbih4ICogbTAwICsgeSAqIG0wMSwgeCAqIG0xMCArIHkgKiBtMTEpOworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgdGhlIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBwYXJ0IG9mIHRoaXMgQWZmaW5lVHJhbnNmb3JtIChpZ25vcmluZworICAgICAqIHRoZSB0cmFuc2xhdGlvbiBwYXJ0KSB0byBhIHNldCBvZiBwb2ludHMgZ2l2ZW4gYXMgYW4gYXJyYXkgb2YgZG91YmxlCisgICAgICogdmFsdWVzIHdoZXJlIGV2ZXJ5IHR3byB2YWx1ZXMgaW4gdGhlIGFycmF5IGdpdmUgdGhlIGNvb3JkaW5hdGVzIG9mIGEKKyAgICAgKiBwb2ludDsgdGhlIGV2ZW4taW5kZXhlZCB2YWx1ZXMgZ2l2aW5nIHRoZSB4IGNvb3JkaW5hdGVzIGFuZCB0aGUKKyAgICAgKiBvZGQtaW5kZXhlZCB2YWx1ZXMgZ2l2aW5nIHRoZSB5IGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBwb2ludHMgdG8gYmUgdHJhbnNmb3JtZWQuCisgICAgICogQHBhcmFtIHNyY09mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgc291cmNlIHBvaW50IGFycmF5IG9mIHRoZSBmaXJzdCBwb2ludCB0byBiZQorICAgICAqICAgICAgICAgICAgdHJhbnNmb3JtZWQuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHBvaW50IGFycmF5IHdoZXJlIHRoZSBpbWFnZXMgb2YgdGhlIHBvaW50cyAoYWZ0ZXIgYXBwbHlpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWx0YSB0cmFuc2Zvcm1hdGlvbikgc2hvdWxkIGJlIHBsYWNlZC4KKyAgICAgKiBAcGFyYW0gZHN0T2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBhcnJheSB3aGVyZSB0aGUgbmV3IHZhbHVlcworICAgICAqICAgICAgICAgICAgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBwb2ludHMgdG8gdHJhbnNmb3JtLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+c3JjT2ZmICsgbGVuZ3RoKjIgPiBzcmMubGVuZ3RoPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgICAgIDxjb2RlPmRzdE9mZiArIGxlbmd0aCoyID4gZHN0Lmxlbmd0aDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsdGFUcmFuc2Zvcm0oZG91YmxlW10gc3JjLCBpbnQgc3JjT2ZmLCBkb3VibGVbXSBkc3QsIGludCBkc3RPZmYsIGludCBsZW5ndGgpIHsKKyAgICAgICAgd2hpbGUgKC0tbGVuZ3RoID49IDApIHsKKyAgICAgICAgICAgIGRvdWJsZSB4ID0gc3JjW3NyY09mZisrXTsKKyAgICAgICAgICAgIGRvdWJsZSB5ID0gc3JjW3NyY09mZisrXTsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYrK10gPSB4ICogbTAwICsgeSAqIG0wMTsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYrK10gPSB4ICogbTEwICsgeSAqIG0xMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zZm9ybXMgdGhlIHBvaW50IGFjY29yZGluZyB0byB0aGUgaW52ZXJzZSBvZiB0aGlzCisgICAgICogQWZmaW5lVHJhbnNmb3JtYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIHBvaW50LgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBvYmplY3Qgd2hlcmUgdGhlIHJlc3VsdCBvZiB0aGUgaW52ZXJzZSB0cmFuc2Zvcm0gaXMKKyAgICAgKiAgICAgICAgICAgIHdyaXR0ZW4gKG1heSBiZSBudWxsKS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlIGludmVyc2UgdHJhbnNmb3JtLiBJbnZlcnNlIHRyYW5zZm9ybS4KKyAgICAgKiBAdGhyb3dzIE5vbmludmVydGlibGVUcmFuc2Zvcm1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIEFmZmluZVRyYW5zZm9ybSBjYW5ub3QgYmUgaW52ZXJ0ZWQgKHRoZSBkZXRlcm1pbmFudAorICAgICAqICAgICAgICAgICAgIG9mIHRoZSBsaW5lYXIgdHJhbnNmb3JtYXRpb24gcGFydCBpcyB6ZXJvKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnQyRCBpbnZlcnNlVHJhbnNmb3JtKFBvaW50MkQgc3JjLCBQb2ludDJEIGRzdCkKKyAgICAgICAgICAgIHRocm93cyBOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIHsKKyAgICAgICAgZG91YmxlIGRldCA9IGdldERldGVybWluYW50KCk7CisgICAgICAgIGlmIChNYXRoLmFicyhkZXQpIDwgWkVSTykgeworICAgICAgICAgICAgLy8gYXd0LjIwND1EZXRlcm1pbmFudCBpcyB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHNyYyBpbnN0YW5jZW9mIFBvaW50MkQuRG91YmxlKSB7CisgICAgICAgICAgICAgICAgZHN0ID0gbmV3IFBvaW50MkQuRG91YmxlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRzdCA9IG5ldyBQb2ludDJELkZsb2F0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgeCA9IHNyYy5nZXRYKCkgLSBtMDI7CisgICAgICAgIGRvdWJsZSB5ID0gc3JjLmdldFkoKSAtIG0xMjsKKworICAgICAgICBkc3Quc2V0TG9jYXRpb24oKHggKiBtMTEgLSB5ICogbTAxKSAvIGRldCwgKHkgKiBtMDAgLSB4ICogbTEwKSAvIGRldCk7CisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbGllcyB0aGUgaW52ZXJzZSBvZiB0aGlzIEFmZmluZVRyYW5zZm9ybSB0byBhIHNldCBvZiBwb2ludHMgZ2l2ZW4gYXMKKyAgICAgKiBhbiBhcnJheSBvZiBkb3VibGUgdmFsdWVzIHdoZXJlIGV2ZXJ5IHR3byB2YWx1ZXMgaW4gdGhlIGFycmF5IGdpdmUgdGhlCisgICAgICogY29vcmRpbmF0ZXMgb2YgYSBwb2ludDsgdGhlIGV2ZW4taW5kZXhlZCB2YWx1ZXMgZ2l2aW5nIHRoZSB4IGNvb3JkaW5hdGVzCisgICAgICogYW5kIHRoZSBvZGQtaW5kZXhlZCB2YWx1ZXMgZ2l2aW5nIHRoZSB5IGNvb3JkaW5hdGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBwb2ludHMgdG8gYmUgdHJhbnNmb3JtZWQuCisgICAgICogQHBhcmFtIHNyY09mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgc291cmNlIHBvaW50IGFycmF5IG9mIHRoZSBmaXJzdCBwb2ludCB0byBiZQorICAgICAqICAgICAgICAgICAgdHJhbnNmb3JtZWQuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHBvaW50IGFycmF5IHdoZXJlIHRoZSBpbWFnZXMgb2YgdGhlIHBvaW50cyAoYWZ0ZXIgYXBwbHlpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnZlcnNlIG9mIHRoZSBBZmZpbmVUcmFuc2Zvcm1hdGlvbikgc2hvdWxkIGJlIHBsYWNlZC4KKyAgICAgKiBAcGFyYW0gZHN0T2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBhcnJheSB3aGVyZSB0aGUgbmV3IHZhbHVlcworICAgICAqICAgICAgICAgICAgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBwb2ludHMgdG8gdHJhbnNmb3JtLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+c3JjT2ZmICsgbGVuZ3RoKjIgPiBzcmMubGVuZ3RoPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgICAgIDxjb2RlPmRzdE9mZiArIGxlbmd0aCoyID4gZHN0Lmxlbmd0aDwvY29kZT4uCisgICAgICogQHRocm93cyBOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBBZmZpbmVUcmFuc2Zvcm0gY2Fubm90IGJlIGludmVydGVkICh0aGUgZGV0ZXJtaW5hbnQKKyAgICAgKiAgICAgICAgICAgICBvZiB0aGUgbGluZWFyIHRyYW5zZm9ybWF0aW9uIHBhcnQgaXMgemVybykuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW52ZXJzZVRyYW5zZm9ybShkb3VibGVbXSBzcmMsIGludCBzcmNPZmYsIGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZiwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIHsKKyAgICAgICAgZG91YmxlIGRldCA9IGdldERldGVybWluYW50KCk7CisgICAgICAgIGlmIChNYXRoLmFicyhkZXQpIDwgWkVSTykgeworICAgICAgICAgICAgLy8gYXd0LjIwND1EZXRlcm1pbmFudCBpcyB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlICgtLWxlbmd0aCA+PSAwKSB7CisgICAgICAgICAgICBkb3VibGUgeCA9IHNyY1tzcmNPZmYrK10gLSBtMDI7CisgICAgICAgICAgICBkb3VibGUgeSA9IHNyY1tzcmNPZmYrK10gLSBtMTI7CisgICAgICAgICAgICBkc3RbZHN0T2ZmKytdID0gKHggKiBtMTEgLSB5ICogbTAxKSAvIGRldDsKKyAgICAgICAgICAgIGRzdFtkc3RPZmYrK10gPSAoeSAqIG0wMCAtIHggKiBtMTApIC8gZGV0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzaGFwZSB3aG9zZSBkYXRhIGlzIGdpdmVuIGJ5IGFwcGx5aW5nIHRoaXMgQWZmaW5lVHJhbnNmb3JtCisgICAgICogdG8gdGhlIHNwZWNpZmllZCBzaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luYWwgc2hhcGUgd2hvc2UgZGF0YSBpcyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc2hhcGUgZm91bmQgYnkgYXBwbHlpbmcgdGhpcyBBZmZpbmVUcmFuc2Zvcm0gdG8gdGhlCisgICAgICogICAgICAgICBvcmlnaW5hbCBzaGFwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgY3JlYXRlVHJhbnNmb3JtZWRTaGFwZShTaGFwZSBzcmMpIHsKKyAgICAgICAgaWYgKHNyYyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3JjIGluc3RhbmNlb2YgR2VuZXJhbFBhdGgpIHsKKyAgICAgICAgICAgIHJldHVybiAoKEdlbmVyYWxQYXRoKXNyYykuY3JlYXRlVHJhbnNmb3JtZWRTaGFwZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICBQYXRoSXRlcmF0b3IgcGF0aCA9IHNyYy5nZXRQYXRoSXRlcmF0b3IodGhpcyk7CisgICAgICAgIEdlbmVyYWxQYXRoIGRzdCA9IG5ldyBHZW5lcmFsUGF0aChwYXRoLmdldFdpbmRpbmdSdWxlKCkpOworICAgICAgICBkc3QuYXBwZW5kKHBhdGgsIGZhbHNlKTsKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW1siICsgbTAwICsgIiwgIiArIG0wMSArICIsICIgKyBtMDIgKyAiXSwgWyIgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JAorICAgICAgICAgICAgICAgICsgbTEwICsgIiwgIiArIG0xMSArICIsICIgKyBtMTIgKyAiXV0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIEhhc2hDb2RlIGhhc2ggPSBuZXcgSGFzaENvZGUoKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTAwKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTAxKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTAyKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTEwKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTExKTsKKyAgICAgICAgaGFzaC5hcHBlbmQobTEyKTsKKyAgICAgICAgcmV0dXJuIGhhc2guaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBBZmZpbmVUcmFuc2Zvcm0pIHsKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0ID0gKEFmZmluZVRyYW5zZm9ybSlvYmo7CisgICAgICAgICAgICByZXR1cm4gbTAwID09IHQubTAwICYmIG0wMSA9PSB0Lm0wMSAmJiBtMDIgPT0gdC5tMDIgJiYgbTEwID09IHQubTEwICYmIG0xMSA9PSB0Lm0xMQorICAgICAgICAgICAgICAgICAgICAmJiBtMTIgPT0gdC5tMTI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgQWZmaW5lVHJhc3Nmb3JtIG9iamVjdCB0byB0aGUgb3V0cHV0IHN0ZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIC0gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIC0gaWYgdGhlcmUgYXJlIEkvTyBlcnJvcnMgd2hpbGUgd3JpdGluZyB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCB0aGUgQWZmaW5lVHJhbnNmb3JtIG9iamVjdCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgLSB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAtIGlmIHRoZXJlIGFyZSBJL08gZXJyb3JzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgLSBpZiBjbGFzcyBjb3VsZCBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgdHlwZSA9IFRZUEVfVU5LTk9XTjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9nZW9tL0FyYzJELmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9BcmMyRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2ZjVjZDMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9BcmMyRC5qYXZhCkBAIC0wLDAgKzEsMTE1NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIEFyYzJEIHJlcHJlc2VudHMgYSBzZWdtZW50IG9mIGEgY3VydmUgaW5zY3JpYmVkIGluIGEgcmVjdGFuZ2xlLiBUaGUKKyAqIGN1cnZlIGlzIGRlZmluZWQgYnkgYSBzdGFydCBhbmdsZSBhbmQgYW4gZXh0ZW50IGFuZ2xlICh0aGUgZW5kIGFuZ2xlIG1pbnVzCisgKiB0aGUgc3RhcnQgYW5nbGUpIGFzIGEgcGllIHdlZGdlIHdob3NlIHBvaW50IGlzIGluIHRoZSBjZW50ZXIgb2YgdGhlCisgKiByZWN0YW5nbGUuIFRoZSBBcmMyRCBhcyBhIHNoYXBlIG1heSBiZSBlaXRoZXIgT1BFTiAoaW5jbHVkaW5nIG5vdGhpbmcgYnV0IHRoZQorICogY3VydmVkIGFyYyBzZWdtZW50IGl0c2VsZiksIENIT1JEICh0aGUgY3VydmVkIGFyYyBzZWdtZW50IGNsb3NlZCBieSBhCisgKiBjb25uZWN0aW5nIHNlZ21lbnQgZnJvbSB0aGUgZW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFyYywgb3IgUElFICh0aGUKKyAqIHNlZ21lbnRzIGZyb20gdGhlIGVuZCBvZiB0aGUgYXJjIHRvIHRoZSBjZW50ZXIgb2YgdGhlIHJlY3RhbmdsZSBhbmQgZnJvbSB0aGUKKyAqIGNlbnRlciBvZiB0aGUgcmVjdGFuZ2xlIGJhY2sgdG8gdGhlIGFyYydzIHN0YXJ0IHBvaW50IGFyZSBpbmNsdWRlZCkuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQXJjMkQgZXh0ZW5kcyBSZWN0YW5ndWxhclNoYXBlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBhcmMgdHlwZSBPUEVOIGluZGljYXRlcyB0aGF0IHRoZSBzaGFwZSBpbmNsdWRlcyBvbmx5IHRoZSBjdXJ2ZWQgYXJjCisgICAgICogc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBPUEVOID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBhcmMgdHlwZSBDSE9SRCBpbmRpY2F0ZXMgdGhhdCBhcyBhIHNoYXBlIHRoZSBjb25uZWN0aW5nIHNlZ21lbnQgZnJvbQorICAgICAqIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBhcmMgdG8gdGhlIGJlZ2lubmluZyBwb2ludCBpcyBpbmNsdWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDSE9SRCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXJjIHR5cGUgUElFIGluZGljYXRlcyB0aGF0IGFzIGEgc2hhcGUgdGhlIHR3byBzZWdtZW50cyBmcm9tIHRoZQorICAgICAqIGFyYydzIGVuZHBvaW50IHRvIHRoZSBjZW50ZXIgb2YgdGhlIHJlY3RhbmdsZSBhbmQgZnJvbSB0aGUgY2VudGVyIG9mIHRoZQorICAgICAqIHJlY3RhbmdsZSB0byB0aGUgYXJjJ3MgZW5kcG9pbnQgYXJlIGluY2x1ZGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFBJRSA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRmxvYXQgaXMgYSBzdWJjbGFzcyBvZiBBcmMyRCBpbiB3aGljaCBhbGwgb2YgdGhlIGRhdGEgdmFsdWVzCisgICAgICogYXJlIGdpdmVuIGFzIGZsb2F0cy4KKyAgICAgKiAKKyAgICAgKiBAc2VlIEFyYzJELkRvdWJsZQorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRmxvYXQgZXh0ZW5kcyBBcmMyRCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUgdGhhdAorICAgICAgICAgKiBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUgdGhhdAorICAgICAgICAgKiBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHRoYXQgY29udGFpbnMgdGhlIGFyYy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHRoYXQgY29udGFpbnMgdGhlIGFyYy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgc3RhcnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgZXh0ZW50OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQXJjMkQgb2YgdHlwZSBPUEVOIHdpdGggZmxvYXQgdmFsdWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KCkgeworICAgICAgICAgICAgc3VwZXIoT1BFTik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFyYzJEIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aXRoIGZsb2F0IHZhbHVlcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB0eXBlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5ldyBBcmMyRCwgZWl0aGVyIHtAbGluayBBcmMyRCNPUEVOfSwKKyAgICAgICAgICogICAgICAgICAgICB7QGxpbmsgQXJjMkQjQ0hPUkR9LCBvciB7QGxpbmsgQXJjMkQjUElFfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGbG9hdChpbnQgdHlwZSkgeworICAgICAgICAgICAgc3VwZXIodHlwZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgQXJjMkQgd2l0aCB0aGUgc3BlY2lmaWVkIGZsb2F0LXZhbHVlZCBkYXRhLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlCisgICAgICAgICAqICAgICAgICAgICAgdGhhdCBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUKKyAgICAgICAgICogICAgICAgICAgICB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHRoYXQgY29udGFpbnMgdGhlIGFyYy4KKyAgICAgICAgICogQHBhcmFtIGhlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICAgICAqIEBwYXJhbSBzdGFydAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqIEBwYXJhbSBleHRlbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgd2lkdGggYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAgICAgKiBAcGFyYW0gdHlwZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBuZXcgQXJjMkQsIGVpdGhlciB7QGxpbmsgQXJjMkQjT1BFTn0sCisgICAgICAgICAqICAgICAgICAgICAge0BsaW5rIEFyYzJEI0NIT1JEfSwgb3Ige0BsaW5rIEFyYzJEI1BJRX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgd2lkdGgsIGZsb2F0IGhlaWdodCwgZmxvYXQgc3RhcnQsIGZsb2F0IGV4dGVudCwKKyAgICAgICAgICAgICAgICBpbnQgdHlwZSkgeworICAgICAgICAgICAgc3VwZXIodHlwZSk7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0OworICAgICAgICAgICAgdGhpcy5leHRlbnQgPSBleHRlbnQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFuZ2xlMkQgd2l0aCB0aGUgc3BlY2lmaWVkIGZsb2F0LXZhbHVlZCBkYXRhIGFuZAorICAgICAgICAgKiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIGdpdmVuIGJ5IHRoZSBwYXJhbWV0ZXIgYm91bmRzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGJvdW5kcworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhlIEFuZ2xlMkQuCisgICAgICAgICAqIEBwYXJhbSBzdGFydAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqIEBwYXJhbSBleHRlbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgd2lkdGggYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAgICAgKiBAcGFyYW0gdHlwZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBuZXcgQXJjMkQsIGVpdGhlciB7QGxpbmsgQXJjMkQjT1BFTn0sCisgICAgICAgICAqICAgICAgICAgICAge0BsaW5rIEFyYzJEI0NIT1JEfSwgb3Ige0BsaW5rIEFyYzJEI1BJRX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoUmVjdGFuZ2xlMkQgYm91bmRzLCBmbG9hdCBzdGFydCwgZmxvYXQgZXh0ZW50LCBpbnQgdHlwZSkgeworICAgICAgICAgICAgc3VwZXIodHlwZSk7CisgICAgICAgICAgICB0aGlzLnggPSAoZmxvYXQpYm91bmRzLmdldFgoKTsKKyAgICAgICAgICAgIHRoaXMueSA9IChmbG9hdClib3VuZHMuZ2V0WSgpOworICAgICAgICAgICAgdGhpcy53aWR0aCA9IChmbG9hdClib3VuZHMuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gKGZsb2F0KWJvdW5kcy5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKKyAgICAgICAgICAgIHRoaXMuZXh0ZW50ID0gZXh0ZW50OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WCgpIHsKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0V2lkdGgoKSB7CisgICAgICAgICAgICByZXR1cm4gd2lkdGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRIZWlnaHQoKSB7CisgICAgICAgICAgICByZXR1cm4gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0QW5nbGVTdGFydCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzdGFydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEFuZ2xlRXh0ZW50KCkgeworICAgICAgICAgICAgcmV0dXJuIGV4dGVudDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIHdpZHRoIDw9IDAuMGYgfHwgaGVpZ2h0IDw9IDAuMGY7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0QXJjKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0LCBkb3VibGUgc3RhcnQsCisgICAgICAgICAgICAgICAgZG91YmxlIGV4dGVudCwgaW50IHR5cGUpIHsKKyAgICAgICAgICAgIHRoaXMuc2V0QXJjVHlwZSh0eXBlKTsKKyAgICAgICAgICAgIHRoaXMueCA9IChmbG9hdCl4OworICAgICAgICAgICAgdGhpcy55ID0gKGZsb2F0KXk7CisgICAgICAgICAgICB0aGlzLndpZHRoID0gKGZsb2F0KXdpZHRoOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSAoZmxvYXQpaGVpZ2h0OworICAgICAgICAgICAgdGhpcy5zdGFydCA9IChmbG9hdClzdGFydDsKKyAgICAgICAgICAgIHRoaXMuZXh0ZW50ID0gKGZsb2F0KWV4dGVudDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRBbmdsZVN0YXJ0KGRvdWJsZSBzdGFydCkgeworICAgICAgICAgICAgdGhpcy5zdGFydCA9IChmbG9hdClzdGFydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRBbmdsZUV4dGVudChkb3VibGUgZXh0ZW50KSB7CisgICAgICAgICAgICB0aGlzLmV4dGVudCA9IChmbG9hdClleHRlbnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFJlY3RhbmdsZTJEIG1ha2VCb3VuZHMoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoKGZsb2F0KXgsIChmbG9hdCl5LCAoZmxvYXQpd2lkdGgsIChmbG9hdCloZWlnaHQpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRG91YmxlIGlzIGEgc3ViY2xhc3Mgb2YgQXJjMkQgaW4gd2hpY2ggYWxsIG9mIHRoZSBkYXRhIHZhbHVlcworICAgICAqIGFyZSBnaXZlbiBhcyBkb3VibGVzLgorICAgICAqIAorICAgICAqIEBzZWUgQXJjMkQuRmxvYXQKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERvdWJsZSBleHRlbmRzIEFyYzJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZSB0aGF0CisgICAgICAgICAqIGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUgdGhhdAorICAgICAgICAgKiBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSB5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHdpZHRoOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgdGhhdCBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHN0YXJ0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgd2lkdGggYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSBleHRlbnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBBcmMyRCBvZiB0eXBlIE9QRU4gd2l0aCBkb3VibGUgdmFsdWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZSgpIHsKKyAgICAgICAgICAgIHN1cGVyKE9QRU4pOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBBcmMyRCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgd2l0aCBkb3VibGUgdmFsdWVzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgbmV3IEFyYzJELCBlaXRoZXIge0BsaW5rIEFyYzJEI09QRU59LAorICAgICAgICAgKiAgICAgICAgICAgIHtAbGluayBBcmMyRCNDSE9SRH0sIG9yIHtAbGluayBBcmMyRCNQSUV9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShpbnQgdHlwZSkgeworICAgICAgICAgICAgc3VwZXIodHlwZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgQXJjMkQgd2l0aCB0aGUgc3BlY2lmaWVkIGRvdWJsZS12YWx1ZWQgZGF0YS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZQorICAgICAgICAgKiAgICAgICAgICAgIHRoYXQgY29udGFpbnMgdGhlIGFyYy4KKyAgICAgICAgICogQHBhcmFtIHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlCisgICAgICAgICAqICAgICAgICAgICAgdGhhdCBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgdGhhdCBjb250YWlucyB0aGUgYXJjLgorICAgICAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAgICAgKiBAcGFyYW0gZXh0ZW50CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIGFuZ2xlIG9mIHRoZSBhcmMgaW4gZGVncmVlcy4KKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgbmV3IEFyYzJELCBlaXRoZXIge0BsaW5rIEFyYzJEI09QRU59LAorICAgICAgICAgKiAgICAgICAgICAgIHtAbGluayBBcmMyRCNDSE9SRH0sIG9yIHtAbGluayBBcmMyRCNQSUV9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCwgZG91YmxlIHN0YXJ0LCBkb3VibGUgZXh0ZW50LAorICAgICAgICAgICAgICAgIGludCB0eXBlKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlKTsKKyAgICAgICAgICAgIHRoaXMueCA9IHg7CisgICAgICAgICAgICB0aGlzLnkgPSB5OworICAgICAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgICAgICB0aGlzLmV4dGVudCA9IGV4dGVudDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQW5nbGUyRCB3aXRoIHRoZSBzcGVjaWZpZWQgZmxvYXQtdmFsdWVkIGRhdGEgYW5kCisgICAgICAgICAqIHRoZSBib3VuZGluZyByZWN0YW5nbGUgZ2l2ZW4gYnkgdGhlIHBhcmFtZXRlciBib3VuZHMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gYm91bmRzCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSBvZiB0aGUgQW5nbGUyRC4KKyAgICAgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGFuZ2xlIG9mIHRoZSBhcmMgaW4gZGVncmVlcy4KKyAgICAgICAgICogQHBhcmFtIGV4dGVudAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqIEBwYXJhbSB0eXBlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5ldyBBcmMyRCwgZWl0aGVyIHtAbGluayBBcmMyRCNPUEVOfSwKKyAgICAgICAgICogICAgICAgICAgICB7QGxpbmsgQXJjMkQjQ0hPUkR9LCBvciB7QGxpbmsgQXJjMkQjUElFfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoUmVjdGFuZ2xlMkQgYm91bmRzLCBkb3VibGUgc3RhcnQsIGRvdWJsZSBleHRlbnQsIGludCB0eXBlKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlKTsKKyAgICAgICAgICAgIHRoaXMueCA9IGJvdW5kcy5nZXRYKCk7CisgICAgICAgICAgICB0aGlzLnkgPSBib3VuZHMuZ2V0WSgpOworICAgICAgICAgICAgdGhpcy53aWR0aCA9IGJvdW5kcy5nZXRXaWR0aCgpOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBib3VuZHMuZ2V0SGVpZ2h0KCk7CisgICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgICAgICB0aGlzLmV4dGVudCA9IGV4dGVudDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgoKSB7CisgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkoKSB7CisgICAgICAgICAgICByZXR1cm4geTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFdpZHRoKCkgeworICAgICAgICAgICAgcmV0dXJuIHdpZHRoOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0SGVpZ2h0KCkgeworICAgICAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEFuZ2xlU3RhcnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRBbmdsZUV4dGVudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aCA8PSAwLjAgfHwgaGVpZ2h0IDw9IDAuMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRBcmMoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQsIGRvdWJsZSBzdGFydCwKKyAgICAgICAgICAgICAgICBkb3VibGUgZXh0ZW50LCBpbnQgdHlwZSkgeworICAgICAgICAgICAgdGhpcy5zZXRBcmNUeXBlKHR5cGUpOworICAgICAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgICAgIHRoaXMueSA9IHk7CisgICAgICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICAgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKKyAgICAgICAgICAgIHRoaXMuZXh0ZW50ID0gZXh0ZW50OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEFuZ2xlU3RhcnQoZG91YmxlIHN0YXJ0KSB7CisgICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0QW5nbGVFeHRlbnQoZG91YmxlIGV4dGVudCkgeworICAgICAgICAgICAgdGhpcy5leHRlbnQgPSBleHRlbnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFJlY3RhbmdsZTJEIG1ha2VCb3VuZHMoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgSXRlcmF0b3IgaXMgdGhlIHN1YmNsYXNzIG9mIFBhdGhJdGVyYXRvciB0aGF0IGlzIHVzZWQgdG8KKyAgICAgKiB0cmF2ZXJzZSB0aGUgYm91bmRhcnkgb2YgYSBzaGFwZSBvZiB0eXBlIEFyYzJELgorICAgICAqLworICAgIGNsYXNzIEl0ZXJhdG9yIGltcGxlbWVudHMgUGF0aEl0ZXJhdG9yIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBhcmMncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgeDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBhcmMncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgeTsKKworICAgICAgICAvKioKKyAgICAgICAgICogSGFsZiBvZiB0aGUgd2lkdGggb2YgdGhlIGFyYydzIGJvdW5kaW5nIHJlY3RhbmdsZSAodGhlIHJhZGl1cyBpbiB0aGUKKyAgICAgICAgICogY2FzZSBvZiBhIGNpcmN1bGFyIGFyYykuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEhhbGYgb2YgdGhlIGhlaWdodCBvZiB0aGUgYXJjJ3MgYm91bmRpbmcgcmVjdGFuZ2xlICh0aGUgcmFkaXVzIGluIHRoZQorICAgICAgICAgKiBjYXNlIG9mIGEgY2lyY3VsYXIgYXJjKS4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgYW5nbGU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBhbmdsZSBleHRlbnQgaW4gZGVncmVlcy4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBleHRlbnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjbG9zdXJlIHR5cGUgb2YgdGhlIGFyYy4KKyAgICAgICAgICovCisgICAgICAgIGludCB0eXBlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcGF0aCBpdGVyYXRvciB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY3VycmVudCBzZWdtZW50IGluZGV4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIGFyYyBzZWdtZW50cyB0aGUgc291cmNlIGFyYyBzdWJkaXZpZGVkIHRvIGJlCisgICAgICAgICAqIGFwcHJveGltYXRlZCBieSBCZXppZXIgY3VydmVzLiBEZXBlbmRzIG9uIGV4dGVudCB2YWx1ZS4KKyAgICAgICAgICovCisgICAgICAgIGludCBhcmNDb3VudDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG51bWJlciBvZiBsaW5lIHNlZ21lbnRzLiBEZXBlbmRzIG9uIGNsb3N1cmUgdHlwZS4KKyAgICAgICAgICovCisgICAgICAgIGludCBsaW5lQ291bnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzdGVwIHRvIGNhbGN1bGF0ZSBuZXh0IGFyYyBzdWJkaXZpc2lvbiBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBzdGVwOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGVtcG9yYXJ5IHZhbHVlIG9mIGNvc2ludXMgb2YgdGhlIGN1cnJlbnQgYW5nbGUuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgY29zOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGVtcG9yYXJ5IHZhbHVlIG9mIHNpbnVzIG9mIHRoZSBjdXJyZW50IGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHNpbjsKKworICAgICAgICAvKiogVGhlIGNvZWZmaWNpZW50IHRvIGNhbGN1bGF0ZSBjb250cm9sIHBvaW50cyBvZiBCZXppZXIgY3VydmVzLiAqLworICAgICAgICBkb3VibGUgazsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRlbXBvcmFyeSB2YWx1ZSBvZiB4IGNvb3JkaW5hdGUgb2YgdGhlIEJlemllciBjdXJ2ZSBjb250cm9sCisgICAgICAgICAqIHZlY3Rvci4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBreDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRlbXBvcmFyeSB2YWx1ZSBvZiB5IGNvb3JkaW5hdGUgb2YgdGhlIEJlemllciBjdXJ2ZSBjb250cm9sCisgICAgICAgICAqIHZlY3Rvci4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBreTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgcGF0aCBwb2ludCAoTU9WRV9UTykuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgbXg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBhdGggcG9pbnQgKE1PVkVfVE8pLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIG15OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEFyYzJELkl0ZXJhdG9yIGZvciBnaXZlbiBsaW5lIGFuZCB0cmFuc2Zvcm1hdGlvbgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc291cmNlIEFyYzJEIG9iamVjdC4KKyAgICAgICAgICogQHBhcmFtIHQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcihBcmMyRCBhLCBBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICAgICAgaWYgKHdpZHRoIDwgMCB8fCBoZWlnaHQgPCAwKSB7CisgICAgICAgICAgICAgICAgYXJjQ291bnQgPSAwOworICAgICAgICAgICAgICAgIGxpbmVDb3VudCA9IDA7CisgICAgICAgICAgICAgICAgaW5kZXggPSAxOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy53aWR0aCA9IGEuZ2V0V2lkdGgoKSAvIDIuMDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gYS5nZXRIZWlnaHQoKSAvIDIuMDsKKyAgICAgICAgICAgIHRoaXMueCA9IGEuZ2V0WCgpICsgd2lkdGg7CisgICAgICAgICAgICB0aGlzLnkgPSBhLmdldFkoKSArIGhlaWdodDsKKyAgICAgICAgICAgIHRoaXMuYW5nbGUgPSAtTWF0aC50b1JhZGlhbnMoYS5nZXRBbmdsZVN0YXJ0KCkpOworICAgICAgICAgICAgdGhpcy5leHRlbnQgPSAtYS5nZXRBbmdsZUV4dGVudCgpOworICAgICAgICAgICAgdGhpcy50eXBlID0gYS5nZXRBcmNUeXBlKCk7CisgICAgICAgICAgICB0aGlzLnQgPSB0OworCisgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZXh0ZW50KSA+PSAzNjAuMCkgeworICAgICAgICAgICAgICAgIGFyY0NvdW50ID0gNDsKKyAgICAgICAgICAgICAgICBrID0gNC4wIC8gMy4wICogKE1hdGguc3FydCgyLjApIC0gMS4wKTsKKyAgICAgICAgICAgICAgICBzdGVwID0gTWF0aC5QSSAvIDIuMDsKKyAgICAgICAgICAgICAgICBpZiAoZXh0ZW50IDwgMC4wKSB7CisgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAtc3RlcDsKKyAgICAgICAgICAgICAgICAgICAgayA9IC1rOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXJjQ291bnQgPSAoaW50KU1hdGgucmludChNYXRoLmFicyhleHRlbnQpIC8gOTAuMCk7CisgICAgICAgICAgICAgICAgc3RlcCA9IE1hdGgudG9SYWRpYW5zKGV4dGVudCAvIGFyY0NvdW50KTsKKyAgICAgICAgICAgICAgICBrID0gNC4wIC8gMy4wICogKDEuMCAtIE1hdGguY29zKHN0ZXAgLyAyLjApKSAvIE1hdGguc2luKHN0ZXAgLyAyLjApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBsaW5lQ291bnQgPSAwOworICAgICAgICAgICAgaWYgKHR5cGUgPT0gQXJjMkQuQ0hPUkQpIHsKKyAgICAgICAgICAgICAgICBsaW5lQ291bnQrKzsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBBcmMyRC5QSUUpIHsKKyAgICAgICAgICAgICAgICBsaW5lQ291bnQgKz0gMjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IGFyY0NvdW50ICsgbGluZUNvdW50OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbmV4dCgpIHsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGRvdWJsZVtdIGNvb3JkcykgeworICAgICAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjRCPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvdW50ID0gMTsKKyAgICAgICAgICAgICAgICBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7CisgICAgICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpOworICAgICAgICAgICAgICAgIGt4ID0gayAqIHdpZHRoICogc2luOworICAgICAgICAgICAgICAgIGt5ID0gayAqIGhlaWdodCAqIGNvczsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSBteCA9IHggKyBjb3MgKiB3aWR0aDsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSBteSA9IHkgKyBzaW4gKiBoZWlnaHQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4IDw9IGFyY0NvdW50KSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19DVUJJQ1RPOworICAgICAgICAgICAgICAgIGNvdW50ID0gMzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSBteCAtIGt4OworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IG15ICsga3k7CisgICAgICAgICAgICAgICAgYW5nbGUgKz0gc3RlcDsKKyAgICAgICAgICAgICAgICBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7CisgICAgICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpOworICAgICAgICAgICAgICAgIGt4ID0gayAqIHdpZHRoICogc2luOworICAgICAgICAgICAgICAgIGt5ID0gayAqIGhlaWdodCAqIGNvczsKKyAgICAgICAgICAgICAgICBjb29yZHNbNF0gPSBteCA9IHggKyBjb3MgKiB3aWR0aDsKKyAgICAgICAgICAgICAgICBjb29yZHNbNV0gPSBteSA9IHkgKyBzaW4gKiBoZWlnaHQ7CisgICAgICAgICAgICAgICAgY29vcmRzWzJdID0gbXggKyBreDsKKyAgICAgICAgICAgICAgICBjb29yZHNbM10gPSBteSAtIGt5OworICAgICAgICAgICAgfSBlbHNlIGlmIChpbmRleCA9PSBhcmNDb3VudCArIGxpbmVDb3VudCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfQ0xPU0U7CisgICAgICAgICAgICAgICAgY291bnQgPSAwOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDE7CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0geDsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSB5OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZmxvYXRbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC40Qj1JdGVyYXRvciBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCB0eXBlOworICAgICAgICAgICAgaW50IGNvdW50OworICAgICAgICAgICAgaWYgKGluZGV4ID09IDApIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX01PVkVUTzsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDE7CisgICAgICAgICAgICAgICAgY29zID0gTWF0aC5jb3MoYW5nbGUpOworICAgICAgICAgICAgICAgIHNpbiA9IE1hdGguc2luKGFuZ2xlKTsKKyAgICAgICAgICAgICAgICBreCA9IGsgKiB3aWR0aCAqIHNpbjsKKyAgICAgICAgICAgICAgICBreSA9IGsgKiBoZWlnaHQgKiBjb3M7CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gKGZsb2F0KShteCA9IHggKyBjb3MgKiB3aWR0aCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KShteSA9IHkgKyBzaW4gKiBoZWlnaHQpOworICAgICAgICAgICAgfSBlbHNlIGlmIChpbmRleCA8PSBhcmNDb3VudCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfQ1VCSUNUTzsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDM7CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gKGZsb2F0KShteCAtIGt4KTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSAoZmxvYXQpKG15ICsga3kpOworICAgICAgICAgICAgICAgIGFuZ2xlICs9IHN0ZXA7CisgICAgICAgICAgICAgICAgY29zID0gTWF0aC5jb3MoYW5nbGUpOworICAgICAgICAgICAgICAgIHNpbiA9IE1hdGguc2luKGFuZ2xlKTsKKyAgICAgICAgICAgICAgICBreCA9IGsgKiB3aWR0aCAqIHNpbjsKKyAgICAgICAgICAgICAgICBreSA9IGsgKiBoZWlnaHQgKiBjb3M7CisgICAgICAgICAgICAgICAgY29vcmRzWzRdID0gKGZsb2F0KShteCA9IHggKyBjb3MgKiB3aWR0aCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzVdID0gKGZsb2F0KShteSA9IHkgKyBzaW4gKiBoZWlnaHQpOworICAgICAgICAgICAgICAgIGNvb3Jkc1syXSA9IChmbG9hdCkobXggKyBreCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzNdID0gKGZsb2F0KShteSAtIGt5KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPT0gYXJjQ291bnQgKyBsaW5lQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0NMT1NFOworICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19MSU5FVE87CisgICAgICAgICAgICAgICAgY291bnQgPSAxOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCl4OworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IChmbG9hdCl5OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNsb3N1cmUgdHlwZSBvZiB0aGUgYXJjLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgYXJjMkQuCisgICAgICogCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbG9zdXJlIHR5cGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIEFyYzJEKGludCB0eXBlKSB7CisgICAgICAgIHNldEFyY1R5cGUodHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGFrZXMgdGhlIGRvdWJsZS12YWx1ZWQgZGF0YSBhbmQgY3JlYXRlcyB0aGUgY29ycmVzcG9uZGluZyBSZWN0YW5nbGUyRAorICAgICAqIG9iamVjdCB3aXRoIHZhbHVlcyBlaXRoZXIgb2YgdHlwZSBmbG9hdCBvciBvZiB0eXBlIGRvdWJsZSBkZXBlbmRpbmcgb24KKyAgICAgKiB3aGV0aGVyIHRoaXMgQXJjMkQgaW5zdGFuY2UgaXMgb2YgdHlwZSBGbG9hdCBvciBEb3VibGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBib3VuZGluZworICAgICAqICAgICAgICAgICAgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIFJlY3RhbmdsZTJEIG9iamVjdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgUmVjdGFuZ2xlMkQgbWFrZUJvdW5kcyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFydCBhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFydCBhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldEFuZ2xlU3RhcnQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIGFuZ2xlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpZHRoIGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0QW5nbGVFeHRlbnQoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN0YXJ0IGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBzdGFydCBhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRBbmdsZVN0YXJ0KGRvdWJsZSBzdGFydCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB3aWR0aCBhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXh0ZW50CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHdpZHRoIGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEFuZ2xlRXh0ZW50KGRvdWJsZSBleHRlbnQpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSB2YWx1ZXMgdGhhdCBkZWZpbmUgdGhlIGFyYy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZQorICAgICAqICAgICAgICAgICAgdGhhdCBjb250YWlucyB0aGUgYXJjLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlCisgICAgICogICAgICAgICAgICB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB0aGF0IGNvbnRhaW5zIHRoZSBhcmMuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHRoYXQgY29udGFpbnMgdGhlIGFyYy4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBhbmdsZSBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICogQHBhcmFtIGV4dGVudAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIGFuZ2xlIG9mIHRoZSBhcmMgaW4gZGVncmVlcy4KKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5ldyBBcmMyRCwgZWl0aGVyIHtAbGluayBBcmMyRCNPUEVOfSwKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBBcmMyRCNDSE9SRH0sIG9yIHtAbGluayBBcmMyRCNQSUV9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEFyYyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCwgZG91YmxlIHN0YXJ0LAorICAgICAgICAgICAgZG91YmxlIGV4dGVudCwgaW50IHR5cGUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXJjIHR5cGUsIGVpdGhlciB7QGxpbmsgQXJjMkQjT1BFTn0sIHtAbGluayBBcmMyRCNDSE9SRH0sIG9yCisgICAgICoge0BsaW5rIEFyYzJEI1BJRX0uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJjIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRBcmNUeXBlKCkgeworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhcmMgdHlwZSwgZWl0aGVyIHtAbGluayBBcmMyRCNPUEVOfSwge0BsaW5rIEFyYzJEI0NIT1JEfSwgb3IKKyAgICAgKiB7QGxpbmsgQXJjMkQjUElFfS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhcmMgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBcmNUeXBlKGludCB0eXBlKSB7CisgICAgICAgIGlmICh0eXBlICE9IE9QRU4gJiYgdHlwZSAhPSBDSE9SRCAmJiB0eXBlICE9IFBJRSkgeworICAgICAgICAgICAgLy8gYXd0LjIwNT1JbnZhbGlkIHR5cGUgb2YgQXJjOiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjA1IiwgdHlwZSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFydCBwb2ludCBvZiB0aGUgYXJjIGFzIGEgUG9pbnQyRC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFydCBwb2ludCBvZiB0aGUgY3VydmVkIGFyYyBzZWdtZW50LgorICAgICAqLworICAgIHB1YmxpYyBQb2ludDJEIGdldFN0YXJ0UG9pbnQoKSB7CisgICAgICAgIGRvdWJsZSBhID0gTWF0aC50b1JhZGlhbnMoZ2V0QW5nbGVTdGFydCgpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkRvdWJsZShnZXRYKCkgKyAoMS4wICsgTWF0aC5jb3MoYSkpICogZ2V0V2lkdGgoKSAvIDIuMCwgZ2V0WSgpCisgICAgICAgICAgICAgICAgKyAoMS4wIC0gTWF0aC5zaW4oYSkpICogZ2V0SGVpZ2h0KCkgLyAyLjApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuZCBwb2ludCBvZiB0aGUgYXJjIGFzIGEgUG9pbnQyRC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBhcmMgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnQyRCBnZXRFbmRQb2ludCgpIHsKKyAgICAgICAgZG91YmxlIGEgPSBNYXRoLnRvUmFkaWFucyhnZXRBbmdsZVN0YXJ0KCkgKyBnZXRBbmdsZUV4dGVudCgpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkRvdWJsZShnZXRYKCkgKyAoMS4wICsgTWF0aC5jb3MoYSkpICogZ2V0V2lkdGgoKSAvIDIuMCwgZ2V0WSgpCisgICAgICAgICAgICAgICAgKyAoMS4wIC0gTWF0aC5zaW4oYSkpICogZ2V0SGVpZ2h0KCkgLyAyLjApOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG1ha2VCb3VuZHMoZ2V0WCgpLCBnZXRZKCksIGdldFdpZHRoKCksIGdldEhlaWdodCgpKTsKKyAgICAgICAgfQorICAgICAgICBkb3VibGUgcngxID0gZ2V0WCgpOworICAgICAgICBkb3VibGUgcnkxID0gZ2V0WSgpOworICAgICAgICBkb3VibGUgcngyID0gcngxICsgZ2V0V2lkdGgoKTsKKyAgICAgICAgZG91YmxlIHJ5MiA9IHJ5MSArIGdldEhlaWdodCgpOworCisgICAgICAgIFBvaW50MkQgcDEgPSBnZXRTdGFydFBvaW50KCk7CisgICAgICAgIFBvaW50MkQgcDIgPSBnZXRFbmRQb2ludCgpOworCisgICAgICAgIGRvdWJsZSBieDEgPSBjb250YWluc0FuZ2xlKDE4MC4wKSA/IHJ4MSA6IE1hdGgubWluKHAxLmdldFgoKSwgcDIuZ2V0WCgpKTsKKyAgICAgICAgZG91YmxlIGJ5MSA9IGNvbnRhaW5zQW5nbGUoOTAuMCkgPyByeTEgOiBNYXRoLm1pbihwMS5nZXRZKCksIHAyLmdldFkoKSk7CisgICAgICAgIGRvdWJsZSBieDIgPSBjb250YWluc0FuZ2xlKDAuMCkgPyByeDIgOiBNYXRoLm1heChwMS5nZXRYKCksIHAyLmdldFgoKSk7CisgICAgICAgIGRvdWJsZSBieTIgPSBjb250YWluc0FuZ2xlKDI3MC4wKSA/IHJ5MiA6IE1hdGgubWF4KHAxLmdldFkoKSwgcDIuZ2V0WSgpKTsKKworICAgICAgICBpZiAodHlwZSA9PSBQSUUpIHsKKyAgICAgICAgICAgIGRvdWJsZSBjeCA9IGdldENlbnRlclgoKTsKKyAgICAgICAgICAgIGRvdWJsZSBjeSA9IGdldENlbnRlclkoKTsKKyAgICAgICAgICAgIGJ4MSA9IE1hdGgubWluKGJ4MSwgY3gpOworICAgICAgICAgICAgYnkxID0gTWF0aC5taW4oYnkxLCBjeSk7CisgICAgICAgICAgICBieDIgPSBNYXRoLm1heChieDIsIGN4KTsKKyAgICAgICAgICAgIGJ5MiA9IE1hdGgubWF4KGJ5MiwgY3kpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtYWtlQm91bmRzKGJ4MSwgYnkxLCBieDIgLSBieDEsIGJ5MiAtIGJ5MSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RnJhbWUoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgc2V0QXJjKHgsIHksIHdpZHRoLCBoZWlnaHQsIGdldEFuZ2xlU3RhcnQoKSwgZ2V0QW5nbGVFeHRlbnQoKSwgdHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSB0aGF0IGRlZmluZXMgdGhlIGFyYy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGFuZ2xlIG9mIHRoZSBhcmMgaW4gZGVncmVlcy4KKyAgICAgKiBAcGFyYW0gZXh0ZW50CisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgd2lkdGggb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xvc3VyZSB0eXBlLCBlaXRoZXIge0BsaW5rIEFyYzJEI09QRU59LAorICAgICAqICAgICAgICAgICAge0BsaW5rIEFyYzJEI0NIT1JEfSwgb3Ige0BsaW5rIEFyYzJEI1BJRX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXJjKFBvaW50MkQgcG9pbnQsIERpbWVuc2lvbjJEIHNpemUsIGRvdWJsZSBzdGFydCwgZG91YmxlIGV4dGVudCwgaW50IHR5cGUpIHsKKyAgICAgICAgc2V0QXJjKHBvaW50LmdldFgoKSwgcG9pbnQuZ2V0WSgpLCBzaXplLmdldFdpZHRoKCksIHNpemUuZ2V0SGVpZ2h0KCksIHN0YXJ0LCBleHRlbnQsIHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgdGhhdCBkZWZpbmVzIHRoZSBhcmMuCisgICAgICogCisgICAgICogQHBhcmFtIHJlY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmMncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAqIEBwYXJhbSBleHRlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbmdsZSB3aWR0aCBvZiB0aGUgYXJjIGluIGRlZ3JlZXMuCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbG9zdXJlIHR5cGUsIGVpdGhlciB7QGxpbmsgQXJjMkQjT1BFTn0sCisgICAgICogICAgICAgICAgICB7QGxpbmsgQXJjMkQjQ0hPUkR9LCBvciB7QGxpbmsgQXJjMkQjUElFfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBcmMoUmVjdGFuZ2xlMkQgcmVjdCwgZG91YmxlIHN0YXJ0LCBkb3VibGUgZXh0ZW50LCBpbnQgdHlwZSkgeworICAgICAgICBzZXRBcmMocmVjdC5nZXRYKCksIHJlY3QuZ2V0WSgpLCByZWN0LmdldFdpZHRoKCksIHJlY3QuZ2V0SGVpZ2h0KCksIHN0YXJ0LCBleHRlbnQsIHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgdGhhdCBkZWZpbmVzIHRoZSBhcmMgYnkgY29weWluZyBpdCBmcm9tIGFub3RoZXIgQXJjMkQuCisgICAgICogCisgICAgICogQHBhcmFtIGFyYworICAgICAqICAgICAgICAgICAgdGhlIGFyYyB3aG9zZSBkYXRhIGlzIGNvcGllZCBpbnRvIHRoaXMgYXJjLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFyYyhBcmMyRCBhcmMpIHsKKyAgICAgICAgc2V0QXJjKGFyYy5nZXRYKCksIGFyYy5nZXRZKCksIGFyYy5nZXRXaWR0aCgpLCBhcmMuZ2V0SGVpZ2h0KCksIGFyYy5nZXRBbmdsZVN0YXJ0KCksIGFyYworICAgICAgICAgICAgICAgIC5nZXRBbmdsZUV4dGVudCgpLCBhcmMuZ2V0QXJjVHlwZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIGZvciBhIGNpcmN1bGFyIGFyYyBieSBnaXZpbmcgaXRzIGNlbnRlciBhbmQgcmFkaXVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBjaXJjbGUuCisgICAgICogQHBhcmFtIHJhZGl1cworICAgICAqICAgICAgICAgICAgdGhlIHJhZGl1cyBvZiB0aGUgY2lyY2xlLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGFuZ2xlIG9mIHRoZSBhcmMgaW4gZGVncmVlcy4KKyAgICAgKiBAcGFyYW0gZXh0ZW50CisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgd2lkdGggb2YgdGhlIGFyYyBpbiBkZWdyZWVzLgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xvc3VyZSB0eXBlLCBlaXRoZXIge0BsaW5rIEFyYzJEI09QRU59LAorICAgICAqICAgICAgICAgICAge0BsaW5rIEFyYzJEI0NIT1JEfSwgb3Ige0BsaW5rIEFyYzJEI1BJRX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXJjQnlDZW50ZXIoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgcmFkaXVzLCBkb3VibGUgc3RhcnQsIGRvdWJsZSBleHRlbnQsCisgICAgICAgICAgICBpbnQgdHlwZSkgeworICAgICAgICBzZXRBcmMoeCAtIHJhZGl1cywgeSAtIHJhZGl1cywgcmFkaXVzICogMi4wLCByYWRpdXMgKiAyLjAsIHN0YXJ0LCBleHRlbnQsIHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFyYyBkYXRhIGZvciBhIGNpcmN1bGFyIGFyYyBiYXNlZCBvbiB0d28gdGFuZ2VudCBsaW5lcyBhbmQgdGhlCisgICAgICogcmFkaXVzLiBUaGUgdHdvIHRhbmdlbnQgbGluZXMgYXJlIHRoZSBsaW5lcyBmcm9tIHAxIHRvIHAyIGFuZCBmcm9tIHAyIHRvCisgICAgICogcDMsIHdoaWNoIGRldGVybWluZSBhIHVuaXF1ZSBjaXJjbGUgd2l0aCB0aGUgZ2l2ZW4gcmFkaXVzLiBUaGUgc3RhcnQgYW5kCisgICAgICogZW5kIHBvaW50cyBvZiB0aGUgYXJjIGFyZSB0aGUgcG9pbnRzIHdoZXJlIHRoZSBjaXJjbGUgdG91Y2hlcyB0aGUgdHdvCisgICAgICogbGluZXMsIGFuZCB0aGUgYXJjIGl0c2VsZiBpcyB0aGUgc2hvcnRlciBvZiB0aGUgdHdvIGNpcmNsZSBzZWdtZW50cworICAgICAqIGRldGVybWluZWQgYnkgdGhlIHR3byBwb2ludHMgKGluIG90aGVyIHdvcmRzLCBpdCBpcyB0aGUgcGllY2Ugb2YgdGhlCisgICAgICogY2lyY2xlIHRoYXQgaXMgY2xvc2VyIHRvIHRoZSBsaW5lcycgaW50ZXJzZWN0aW9uIHBvaW50IHAyIGFuZCBmb3JtcyBhCisgICAgICogY29uY2F2ZSBzaGFwZSB3aXRoIHRoZSBzZWdtZW50cyBmcm9tIHAxIHRvIHAyIGFuZCBmcm9tIHAyIHRvIHAzKS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcDEKKyAgICAgKiAgICAgICAgICAgIGEgcG9pbnQgd2hpY2ggZGV0ZXJtaW5lcyBvbmUgb2YgdGhlIHR3byB0YW5nZW50IGxpbmVzICh3aXRoCisgICAgICogICAgICAgICAgICBwMikuCisgICAgICogQHBhcmFtIHAyCisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgb2YgaW50ZXJzZWN0aW9uIG9mIHRoZSB0d28gdGFuZ2VudCBsaW5lcy4KKyAgICAgKiBAcGFyYW0gcDMKKyAgICAgKiAgICAgICAgICAgIGEgcG9pbnQgd2hpY2ggZGV0ZXJtaW5lcyBvbmUgb2YgdGhlIHR3byB0YW5nZW50IGxpbmVzICh3aXRoCisgICAgICogICAgICAgICAgICBwMikuCisgICAgICogQHBhcmFtIHJhZGl1cworICAgICAqICAgICAgICAgICAgdGhlIHJhZGl1cyBvZiB0aGUgY2lyY3VsYXIgYXJjLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFyY0J5VGFuZ2VudChQb2ludDJEIHAxLCBQb2ludDJEIHAyLCBQb2ludDJEIHAzLCBkb3VibGUgcmFkaXVzKSB7CisgICAgICAgIC8vIFVzZWQgc2ltcGxlIGdlb21ldHJpYyBjYWxjdWxhdGlvbnMgb2YgYXJjIGNlbnRlciwgcmFkaXVzIGFuZCBhbmdsZXMKKyAgICAgICAgLy8gYnkgdGFuZ2VudHMKKyAgICAgICAgZG91YmxlIGExID0gLU1hdGguYXRhbjIocDEuZ2V0WSgpIC0gcDIuZ2V0WSgpLCBwMS5nZXRYKCkgLSBwMi5nZXRYKCkpOworICAgICAgICBkb3VibGUgYTIgPSAtTWF0aC5hdGFuMihwMy5nZXRZKCkgLSBwMi5nZXRZKCksIHAzLmdldFgoKSAtIHAyLmdldFgoKSk7CisgICAgICAgIGRvdWJsZSBhbSA9IChhMSArIGEyKSAvIDIuMDsKKyAgICAgICAgZG91YmxlIGFoID0gYTEgLSBhbTsKKyAgICAgICAgZG91YmxlIGQgPSByYWRpdXMgLyBNYXRoLmFicyhNYXRoLnNpbihhaCkpOworICAgICAgICBkb3VibGUgeCA9IHAyLmdldFgoKSArIGQgKiBNYXRoLmNvcyhhbSk7CisgICAgICAgIGRvdWJsZSB5ID0gcDIuZ2V0WSgpIC0gZCAqIE1hdGguc2luKGFtKTsKKyAgICAgICAgYWggPSBhaCA+PSAwLjAgPyBNYXRoLlBJICogMS41IC0gYWggOiBNYXRoLlBJICogMC41IC0gYWg7CisgICAgICAgIGExID0gZ2V0Tm9ybUFuZ2xlKE1hdGgudG9EZWdyZWVzKGFtIC0gYWgpKTsKKyAgICAgICAgYTIgPSBnZXROb3JtQW5nbGUoTWF0aC50b0RlZ3JlZXMoYW0gKyBhaCkpOworICAgICAgICBkb3VibGUgZGVsdGEgPSBhMiAtIGExOworICAgICAgICBpZiAoZGVsdGEgPD0gMC4wKSB7CisgICAgICAgICAgICBkZWx0YSArPSAzNjAuMDsKKyAgICAgICAgfQorICAgICAgICBzZXRBcmNCeUNlbnRlcih4LCB5LCByYWRpdXMsIGExLCBkZWx0YSwgdHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG5ldyBzdGFydCBhbmdsZSB0byBiZSB0aGUgYW5nbGUgZ2l2ZW4gYnkgdGhlIHRoZSB2ZWN0b3IgZnJvbSB0aGUKKyAgICAgKiBjdXJyZW50IGNlbnRlciBwb2ludCB0byB0aGUgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwb2ludAorICAgICAqICAgICAgICAgICAgdGhlIHBvaW50IHRoYXQgZGV0ZXJtaW5lcyB0aGUgbmV3IHN0YXJ0IGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFuZ2xlU3RhcnQoUG9pbnQyRCBwb2ludCkgeworICAgICAgICBkb3VibGUgYW5nbGUgPSBNYXRoLmF0YW4yKHBvaW50LmdldFkoKSAtIGdldENlbnRlclkoKSwgcG9pbnQuZ2V0WCgpIC0gZ2V0Q2VudGVyWCgpKTsKKyAgICAgICAgc2V0QW5nbGVTdGFydChnZXROb3JtQW5nbGUoLU1hdGgudG9EZWdyZWVzKGFuZ2xlKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFuZ2xlcyBpbiB0ZXJtcyBvZiB2ZWN0b3JzIGZyb20gdGhlIGN1cnJlbnQgYXJjIGNlbnRlciB0byB0aGUKKyAgICAgKiBwb2ludHMgKHgxLCB5MSkgYW5kICh4MiwgeTIpLiBUaGUgc3RhcnQgYW5nbGUgaXMgZ2l2ZW4gYnkgdGhlIHZlY3RvciBmcm9tCisgICAgICogdGhlIGN1cnJlbnQgY2VudGVyIHRvIHRoZSBwb2ludCAoeDEsIHkxKSBhbmQgdGhlIGVuZCBhbmdsZSBpcyBnaXZlbiBieQorICAgICAqIHRoZSB2ZWN0b3IgZnJvbSB0aGUgY2VudGVyIHRvIHRoZSBwb2ludCAoeDIsIHkyKS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHdob3NlIHZlY3RvciBmcm9tIHRoZSBjZW50ZXIKKyAgICAgKiAgICAgICAgICAgIHBvaW50IGRldGVybWluZXMgdGhlIG5ldyBzdGFydCBhbmdsZSBvZiB0aGUgYXJjLgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgd2hvc2UgdmVjdG9yIGZyb20gdGhlIGNlbnRlcgorICAgICAqICAgICAgICAgICAgcG9pbnQgZGV0ZXJtaW5lcyB0aGUgbmV3IHN0YXJ0IGFuZ2xlIG9mIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB3aG9zZSB2ZWN0b3IgZnJvbSB0aGUgY2VudGVyCisgICAgICogICAgICAgICAgICBwb2ludCBkZXRlcm1pbmVzIHRoZSBuZXcgZW5kIGFuZ2xlIG9mIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB3aG9zZSB2ZWN0b3IgZnJvbSB0aGUgY2VudGVyCisgICAgICogICAgICAgICAgICBwb2ludCBkZXRlcm1pbmVzIHRoZSBuZXcgZW5kIGFuZ2xlIG9mIHRoZSBhcmMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QW5nbGVzKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICBkb3VibGUgY3ggPSBnZXRDZW50ZXJYKCk7CisgICAgICAgIGRvdWJsZSBjeSA9IGdldENlbnRlclkoKTsKKyAgICAgICAgZG91YmxlIGExID0gZ2V0Tm9ybUFuZ2xlKC1NYXRoLnRvRGVncmVlcyhNYXRoLmF0YW4yKHkxIC0gY3ksIHgxIC0gY3gpKSk7CisgICAgICAgIGRvdWJsZSBhMiA9IGdldE5vcm1BbmdsZSgtTWF0aC50b0RlZ3JlZXMoTWF0aC5hdGFuMih5MiAtIGN5LCB4MiAtIGN4KSkpOworICAgICAgICBhMiAtPSBhMTsKKyAgICAgICAgaWYgKGEyIDw9IDAuMCkgeworICAgICAgICAgICAgYTIgKz0gMzYwLjA7CisgICAgICAgIH0KKyAgICAgICAgc2V0QW5nbGVTdGFydChhMSk7CisgICAgICAgIHNldEFuZ2xlRXh0ZW50KGEyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhbmdsZXMgaW4gdGVybXMgb2YgdmVjdG9ycyBmcm9tIHRoZSBjdXJyZW50IGFyYyBjZW50ZXIgdG8gdGhlCisgICAgICogcG9pbnRzIHAxIGFuZCBwMi4gVGhlIHN0YXJ0IGFuZ2xlIGlzIGdpdmVuIGJ5IHRoZSB2ZWN0b3IgZnJvbSB0aGUgY3VycmVudAorICAgICAqIGNlbnRlciB0byB0aGUgcG9pbnQgcDEgYW5kIHRoZSBlbmQgYW5nbGUgaXMgZ2l2ZW4gYnkgdGhlIHZlY3RvciBmcm9tIHRoZQorICAgICAqIGNlbnRlciB0byB0aGUgcG9pbnQgcDIuCisgICAgICogCisgICAgICogQHBhcmFtIHAxCisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgd2hvc2UgdmVjdG9yIGZyb20gdGhlIGNlbnRlciBwb2ludCBkZXRlcm1pbmVzIHRoZQorICAgICAqICAgICAgICAgICAgbmV3IHN0YXJ0IGFuZ2xlIG9mIHRoZSBhcmMuCisgICAgICogQHBhcmFtIHAyCisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgd2hvc2UgdmVjdG9yIGZyb20gdGhlIGNlbnRlciBwb2ludCBkZXRlcm1pbmVzIHRoZQorICAgICAqICAgICAgICAgICAgbmV3IGVuZCBhbmdsZSBvZiB0aGUgYXJjLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFuZ2xlcyhQb2ludDJEIHAxLCBQb2ludDJEIHAyKSB7CisgICAgICAgIHNldEFuZ2xlcyhwMS5nZXRYKCksIHAxLmdldFkoKSwgcDIuZ2V0WCgpLCBwMi5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vcm1hbGl6ZXMgdGhlIGFuZ2xlIGJ5IHJlbW92aW5nIGV4dHJhIHdpbmRpbmcgKHBhc3QgMzYwIGRlZ3JlZXMpIGFuZAorICAgICAqIHBsYWNpbmcgaXQgaW4gdGhlIHBvc2l0aXZlIGRlZ3JlZSByYW5nZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYW5nbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYW5nbGUgaW4gZGVncmVlcy4KKyAgICAgKiBAcmV0dXJuIGFuIGFuZ2xlIGJldHdlZW4gMCBhbmQgMzYwIGRlZ3JlZXMgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIHNhbWUKKyAgICAgKiAgICAgICAgIGRpcmVjdGlvbiB2ZWN0b3IgYXMgdGhlIHNvdXJjZSBhbmdsZS4KKyAgICAgKi8KKyAgICBkb3VibGUgZ2V0Tm9ybUFuZ2xlKGRvdWJsZSBhbmdsZSkgeworICAgICAgICBkb3VibGUgbiA9IE1hdGguZmxvb3IoYW5nbGUgLyAzNjAuMCk7CisgICAgICAgIHJldHVybiBhbmdsZSAtIG4gKiAzNjAuMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGdpdmVuIGFuZ2xlIGlzIGNvbnRhaW5lZCBpbiB0aGUgc3BhbiBvZiB0aGUgYXJjLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbmdsZQorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIHRvIHRlc3QgaW4gZGVncmVlcy4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBnaXZlbiBhbmdsZSBpcyBiZXR3ZWVuIHRoZSBzdGFydCBhbmdsZSBhbmQgdGhlIGVuZAorICAgICAqICAgICAgICAgYW5nbGUgb2YgdGhlIGFyYy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FuZ2xlKGRvdWJsZSBhbmdsZSkgeworICAgICAgICBkb3VibGUgZXh0ZW50ID0gZ2V0QW5nbGVFeHRlbnQoKTsKKyAgICAgICAgaWYgKGV4dGVudCA+PSAzNjAuMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYW5nbGUgPSBnZXROb3JtQW5nbGUoYW5nbGUpOworICAgICAgICBkb3VibGUgYTEgPSBnZXROb3JtQW5nbGUoZ2V0QW5nbGVTdGFydCgpKTsKKyAgICAgICAgZG91YmxlIGEyID0gYTEgKyBleHRlbnQ7CisgICAgICAgIGlmIChhMiA+IDM2MC4wKSB7CisgICAgICAgICAgICByZXR1cm4gYW5nbGUgPj0gYTEgfHwgYW5nbGUgPD0gYTIgLSAzNjAuMDsKKyAgICAgICAgfQorICAgICAgICBpZiAoYTIgPCAwLjApIHsKKyAgICAgICAgICAgIHJldHVybiBhbmdsZSA+PSBhMiArIDM2MC4wIHx8IGFuZ2xlIDw9IGExOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnQgPiAwLjAgPyBhMSA8PSBhbmdsZSAmJiBhbmdsZSA8PSBhMiA6IGEyIDw9IGFuZ2xlICYmIGFuZ2xlIDw9IGExOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIC8vIE5vcm1hbGl6ZSBwb2ludAorICAgICAgICBkb3VibGUgbnggPSAocHggLSBnZXRYKCkpIC8gZ2V0V2lkdGgoKSAtIDAuNTsKKyAgICAgICAgZG91YmxlIG55ID0gKHB5IC0gZ2V0WSgpKSAvIGdldEhlaWdodCgpIC0gMC41OworCisgICAgICAgIGlmICgobnggKiBueCArIG55ICogbnkpID4gMC4yNSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIGV4dGVudCA9IGdldEFuZ2xlRXh0ZW50KCk7CisgICAgICAgIGRvdWJsZSBhYnNFeHRlbnQgPSBNYXRoLmFicyhleHRlbnQpOworICAgICAgICBpZiAoYWJzRXh0ZW50ID49IDM2MC4wKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gY29udGFpbnNBbmdsZSA9IGNvbnRhaW5zQW5nbGUoTWF0aC50b0RlZ3JlZXMoLU1hdGguYXRhbjIobnksIG54KSkpOworICAgICAgICBpZiAodHlwZSA9PSBQSUUpIHsKKyAgICAgICAgICAgIHJldHVybiBjb250YWluc0FuZ2xlOworICAgICAgICB9CisgICAgICAgIGlmIChhYnNFeHRlbnQgPD0gMTgwLjAgJiYgIWNvbnRhaW5zQW5nbGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIExpbmUyRCBsID0gbmV3IExpbmUyRC5Eb3VibGUoZ2V0U3RhcnRQb2ludCgpLCBnZXRFbmRQb2ludCgpKTsKKyAgICAgICAgaW50IGNjdzEgPSBsLnJlbGF0aXZlQ0NXKHB4LCBweSk7CisgICAgICAgIGludCBjY3cyID0gbC5yZWxhdGl2ZUNDVyhnZXRDZW50ZXJYKCksIGdldENlbnRlclkoKSk7CisgICAgICAgIHJldHVybiBjY3cxID09IDAgfHwgY2N3MiA9PSAwIHx8ICgoY2N3MSArIGNjdzIpID09IDAgXiBhYnNFeHRlbnQgPiAxODAuMCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoZG91YmxlIHJ4LCBkb3VibGUgcnksIGRvdWJsZSBydywgZG91YmxlIHJoKSB7CisKKyAgICAgICAgaWYgKCEoY29udGFpbnMocngsIHJ5KSAmJiBjb250YWlucyhyeCArIHJ3LCByeSkgJiYgY29udGFpbnMocnggKyBydywgcnkgKyByaCkgJiYgY29udGFpbnMoCisgICAgICAgICAgICAgICAgcngsIHJ5ICsgcmgpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIGFic0V4dGVudCA9IE1hdGguYWJzKGdldEFuZ2xlRXh0ZW50KCkpOworICAgICAgICBpZiAodHlwZSAhPSBQSUUgfHwgYWJzRXh0ZW50IDw9IDE4MC4wIHx8IGFic0V4dGVudCA+PSAzNjAuMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBSZWN0YW5nbGUyRCByID0gbmV3IFJlY3RhbmdsZTJELkRvdWJsZShyeCwgcnksIHJ3LCByaCk7CisKKyAgICAgICAgZG91YmxlIGN4ID0gZ2V0Q2VudGVyWCgpOworICAgICAgICBkb3VibGUgY3kgPSBnZXRDZW50ZXJZKCk7CisgICAgICAgIGlmIChyLmNvbnRhaW5zKGN4LCBjeSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIFBvaW50MkQgcDEgPSBnZXRTdGFydFBvaW50KCk7CisgICAgICAgIFBvaW50MkQgcDIgPSBnZXRFbmRQb2ludCgpOworCisgICAgICAgIHJldHVybiAhci5pbnRlcnNlY3RzTGluZShjeCwgY3ksIHAxLmdldFgoKSwgcDEuZ2V0WSgpKQorICAgICAgICAgICAgICAgICYmICFyLmludGVyc2VjdHNMaW5lKGN4LCBjeSwgcDIuZ2V0WCgpLCBwMi5nZXRZKCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZTJEIHJlY3QpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHJlY3QuZ2V0WCgpLCByZWN0LmdldFkoKSwgcmVjdC5nZXRXaWR0aCgpLCByZWN0LmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworCisgICAgICAgIGlmIChpc0VtcHR5KCkgfHwgcncgPD0gMC4wIHx8IHJoIDw9IDAuMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2s6IERvZXMgYXJjIGNvbnRhaW4gcmVjdGFuZ2xlJ3MgcG9pbnRzCisgICAgICAgIGlmIChjb250YWlucyhyeCwgcnkpIHx8IGNvbnRhaW5zKHJ4ICsgcncsIHJ5KSB8fCBjb250YWlucyhyeCwgcnkgKyByaCkKKyAgICAgICAgICAgICAgICB8fCBjb250YWlucyhyeCArIHJ3LCByeSArIHJoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgY3ggPSBnZXRDZW50ZXJYKCk7CisgICAgICAgIGRvdWJsZSBjeSA9IGdldENlbnRlclkoKTsKKyAgICAgICAgUG9pbnQyRCBwMSA9IGdldFN0YXJ0UG9pbnQoKTsKKyAgICAgICAgUG9pbnQyRCBwMiA9IGdldEVuZFBvaW50KCk7CisgICAgICAgIFJlY3RhbmdsZTJEIHIgPSBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKHJ4LCByeSwgcncsIHJoKTsKKworICAgICAgICAvLyBDaGVjazogRG9lcyByZWN0YW5nbGUgY29udGFpbiBhcmMncyBwb2ludHMKKyAgICAgICAgaWYgKHIuY29udGFpbnMocDEpIHx8IHIuY29udGFpbnMocDIpIHx8ICh0eXBlID09IFBJRSAmJiByLmNvbnRhaW5zKGN4LCBjeSkpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0eXBlID09IFBJRSkgeworICAgICAgICAgICAgaWYgKHIuaW50ZXJzZWN0c0xpbmUocDEuZ2V0WCgpLCBwMS5nZXRZKCksIGN4LCBjeSkKKyAgICAgICAgICAgICAgICAgICAgfHwgci5pbnRlcnNlY3RzTGluZShwMi5nZXRYKCksIHAyLmdldFkoKSwgY3gsIGN5KSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHIuaW50ZXJzZWN0c0xpbmUocDEuZ2V0WCgpLCBwMS5nZXRZKCksIHAyLmdldFgoKSwgcDIuZ2V0WSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTmVhcmVzdCByZWN0YW5nbGUgcG9pbnQKKyAgICAgICAgZG91YmxlIG54ID0gY3ggPCByeCA/IHJ4IDogKGN4ID4gcnggKyBydyA/IHJ4ICsgcncgOiBjeCk7CisgICAgICAgIGRvdWJsZSBueSA9IGN5IDwgcnkgPyByeSA6IChjeSA+IHJ5ICsgcmggPyByeSArIHJoIDogY3kpOworICAgICAgICByZXR1cm4gY29udGFpbnMobngsIG55KTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gYXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCBhdCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9BcmVhLmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9BcmVhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY2MTllMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9nZW9tL0FyZWEuamF2YQpAQCAtMCwwICsxLDMzMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgQ2xhc3MgQXJlYSBwcm92aWRlcyBhIG1pbmltYWwgaW1wbGVtZW50YXRpb24gZm9yIGEgZ2VuZXJpYyBzaGFwZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBBcmVhIGltcGxlbWVudHMgU2hhcGUsIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc291cmNlIFNoYXBlIG9iamVjdC4KKyAgICAgKi8KKyAgICBTaGFwZSBzOworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIE51bGxJdGVyYXRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOdWxsSXRlcmF0b3IgaW1wbGVtZW50cyBQYXRoSXRlcmF0b3IgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgbnVsbCBpdGVyYXRvci4KKyAgICAgICAgICovCisgICAgICAgIE51bGxJdGVyYXRvcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbmV4dCgpIHsKKyAgICAgICAgICAgIC8vIG5vdGhpbmcKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZmxvYXRbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Qj1JdGVyYXRvciBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgYXJlYSB3aXRoIG5vIGRhdGEuCisgICAgICovCisgICAgcHVibGljIEFyZWEoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGFyZWEgd2l0aCBkYXRhIGdpdmVuIGJ5IHRoZSBzcGVjaWZpZWQgc2hhcGUuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGFwZSB0aGF0IGdpdmVzIHRoZSBkYXRhIGZvciB0aGlzIEFyZWEuCisgICAgICovCisgICAgcHVibGljIEFyZWEoU2hhcGUgcykgeworICAgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnMgPSBzOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSB4LCBkb3VibGUgeSkgeworICAgICAgICByZXR1cm4gcyA9PSBudWxsID8gZmFsc2UgOiBzLmNvbnRhaW5zKHgsIHkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgIHJldHVybiBzID09IG51bGwgPyBmYWxzZSA6IHMuY29udGFpbnMoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUG9pbnQyRCBwKSB7CisgICAgICAgIGlmIChwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzID09IG51bGwgPyBmYWxzZSA6IHMuY29udGFpbnMocCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUmVjdGFuZ2xlMkQgcikgeworICAgICAgICBpZiAociA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcyA9PSBudWxsID8gZmFsc2UgOiBzLmNvbnRhaW5zKHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhlIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIEFyZWEuCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhBcmVhIG9iaikgdGhyb3dzIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgIHJldHVybiBzID09IG51bGwgPyBmYWxzZSA6IHMuaW50ZXJzZWN0cyh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgaWYgKHIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHMgPT0gbnVsbCA/IGZhbHNlIDogcy5pbnRlcnNlY3RzKHIpOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICByZXR1cm4gcyA9PSBudWxsID8gbmV3IFJlY3RhbmdsZSgpIDogcy5nZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgIHJldHVybiBzID09IG51bGwgPyBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKCkgOiBzLmdldEJvdW5kczJEKCk7CisgICAgfQorCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgcmV0dXJuIHMgPT0gbnVsbCA/IG5ldyBOdWxsSXRlcmF0b3IoKSA6IHMuZ2V0UGF0aEl0ZXJhdG9yKHQpOworICAgIH0KKworICAgIHB1YmxpYyBQYXRoSXRlcmF0b3IgZ2V0UGF0aEl0ZXJhdG9yKEFmZmluZVRyYW5zZm9ybSB0LCBkb3VibGUgZmxhdG5lc3MpIHsKKyAgICAgICAgcmV0dXJuIHMgPT0gbnVsbCA/IG5ldyBOdWxsSXRlcmF0b3IoKSA6IHMuZ2V0UGF0aEl0ZXJhdG9yKHQsIGZsYXRuZXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgYXJlYSB0byB0aGlzIGFyZWEuCisgICAgICogCisgICAgICogQHBhcmFtIGFyZWEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmVhIHRvIGFkZCB0byB0aGlzIGFyZWEuCisgICAgICogQHRocm93cyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoQXJlYSBhcmVhKSB0aHJvd3Mgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGFuIGV4Y2x1c2l2ZSBvciBvcGVyYXRpb24gYmV0d2VlbiB0aGlzIHNoYXBlIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogc2hhcGUuCisgICAgICogCisgICAgICogQHBhcmFtIGFyZWEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmVhIHRvIFhPUiBhZ2FpbnN0IHRoaXMgYXJlYS4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4Y2x1c2l2ZU9yKEFyZWEgYXJlYSkgdGhyb3dzIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBhIFJlY3RhbmdsZTJEIGZyb20gdGhlIHNvdXJjZSBzaGFwZSBpZiB0aGUgdW5kZXJseWluZyBzaGFwZSBkYXRhCisgICAgICogZGVzY3JpYmVzIGEgcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUyRCBvYmplY3QgaWYgdGhlIHNvdXJjZSBzaGFwZSBpcyByZWN0YW5nbGUsIG9yIG51bGwgaWYKKyAgICAgKiAgICAgICAgIHNoYXBlIGlzIGVtcHR5IG9yIG5vdCByZWN0YW5nbGUuCisgICAgICovCisgICAgUmVjdGFuZ2xlMkQgZXh0cmFjdFJlY3RhbmdsZSgpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgZmxvYXRbXSBwb2ludHMgPSBuZXcgZmxvYXRbMTJdOworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBQYXRoSXRlcmF0b3IgcCA9IHMuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpOworICAgICAgICBmbG9hdFtdIGNvb3JkcyA9IG5ldyBmbG9hdFs2XTsKKyAgICAgICAgd2hpbGUgKCFwLmlzRG9uZSgpKSB7CisgICAgICAgICAgICBpbnQgdHlwZSA9IHAuY3VycmVudFNlZ21lbnQoY29vcmRzKTsKKyAgICAgICAgICAgIGlmIChjb3VudCA+IDEyIHx8IHR5cGUgPT0gUGF0aEl0ZXJhdG9yLlNFR19RVUFEVE8gfHwgdHlwZSA9PSBQYXRoSXRlcmF0b3IuU0VHX0NVQklDVE8pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvaW50c1tjb3VudCsrXSA9IGNvb3Jkc1swXTsKKyAgICAgICAgICAgIHBvaW50c1tjb3VudCsrXSA9IGNvb3Jkc1sxXTsKKyAgICAgICAgICAgIHAubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGlmIChwb2ludHNbMF0gPT0gcG9pbnRzWzZdICYmIHBvaW50c1s2XSA9PSBwb2ludHNbOF0gJiYgcG9pbnRzWzJdID09IHBvaW50c1s0XQorICAgICAgICAgICAgICAgICYmIHBvaW50c1sxXSA9PSBwb2ludHNbM10gJiYgcG9pbnRzWzNdID09IHBvaW50c1s5XSAmJiBwb2ludHNbNV0gPT0gcG9pbnRzWzddKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZTJELkZsb2F0KHBvaW50c1swXSwgcG9pbnRzWzFdLCBwb2ludHNbMl0gLSBwb2ludHNbMF0sIHBvaW50c1s3XQorICAgICAgICAgICAgICAgICAgICAtIHBvaW50c1sxXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVkdWNlcyB0aGUgc2l6ZSBvZiB0aGlzIEFyZWEgYnkgaW50ZXJzZWN0aW5nIGl0IHdpdGggdGhlIHNwZWNpZmllZCBBcmVhCisgICAgICogaWYgdGhleSBhcmUgYm90aCByZWN0YW5nbGVzLgorICAgICAqIAorICAgICAqIEBzZWUgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRCNpbnRlcnNlY3QoUmVjdGFuZ2xlMkQsIFJlY3RhbmdsZTJELAorICAgICAqICAgICAgUmVjdGFuZ2xlMkQpCisgICAgICogQHBhcmFtIGFyZWEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludGVyc2VjdChBcmVhIGFyZWEpIHsKKyAgICAgICAgUmVjdGFuZ2xlMkQgc3JjMSA9IGV4dHJhY3RSZWN0YW5nbGUoKTsKKyAgICAgICAgUmVjdGFuZ2xlMkQgc3JjMiA9IGFyZWEuZXh0cmFjdFJlY3RhbmdsZSgpOworICAgICAgICBpZiAoc3JjMSAhPSBudWxsICYmIHNyYzIgIT0gbnVsbCkgeworICAgICAgICAgICAgUmVjdGFuZ2xlMkQuaW50ZXJzZWN0KHNyYzEsIHNyYzIsIChSZWN0YW5nbGUyRClzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YnRyYWN0IHRoZSBzcGVjaWZpZWQgYXJlYSBmcm9tIHRoaXMgYXJlYS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYXJlYQorICAgICAqICAgICAgICAgICAgdGhlIGFyZWEgdG8gc3VidHJhY3QuCisgICAgICogQHRocm93cyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdWJ0cmFjdChBcmVhIGFyZWEpIHRocm93cyBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgQXJlYSBpcyBlbXB0eS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgQXJlYSBpcyBlbXB0eS4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB0aHJvd3Mgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGlzIEFyZWEgaXMgcG9seWdvbmFsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBBcmVhIGlzIHBvbHlnb25hbC4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUG9seWdvbmFsKCkgdGhyb3dzIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBBcmVhIGlzIHJlY3Rhbmd1bGFyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBBcmVhIGlzIHJlY3Rhbmd1bGFyLgorICAgICAqIEB0aHJvd3MgTm90SW1wbGVtZW50ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWN0YW5ndWxhcigpIHRocm93cyBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgQXJlYSBpcyBzaW5ndWxhci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgQXJlYSBpcyBzaW5ndWxhci4KKyAgICAgKiBAdGhyb3dzIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2luZ3VsYXIoKSB0aHJvd3Mgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgZGF0YSBvZiB0aGlzIEFyZWEuCisgICAgICogCisgICAgICogQHRocm93cyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNmb3JtcyB0aGUgZGF0YSBvZiB0aGlzIEFyZWEgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2Zvcm0gdG8gdXNlIHRvIHRyYW5zZm9ybSB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgcyA9IHQuY3JlYXRlVHJhbnNmb3JtZWRTaGFwZShzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEFyZWEgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHRyYW5zZm9ybWluZyB0aGUgZGF0YSBvZiB0aGlzCisgICAgICogQXJlYSBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2Zvcm0gdG8gdXNlIHRvIHRyYW5zZm9ybSB0aGUgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgQXJlYSB0aGF0IGlzIHRoZSByZXN1bHQgb2YgdHJhbnNmb3JtaW5nIHRoZSBkYXRhIG9mIHRoaXMKKyAgICAgKiAgICAgICAgIEFyZWEgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBBcmVhIGNyZWF0ZVRyYW5zZm9ybWVkQXJlYShBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICByZXR1cm4gcyA9PSBudWxsID8gbmV3IEFyZWEoKSA6IG5ldyBBcmVhKHQuY3JlYXRlVHJhbnNmb3JtZWRTaGFwZShzKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBcmVhKHRoaXMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vQ3ViaWNDdXJ2ZTJELmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9DdWJpY0N1cnZlMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGRlZGYzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vQ3ViaWNDdXJ2ZTJELmphdmEKQEAgLTAsMCArMSwxMDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Dcm9zc2luZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQ2xhc3MgQ3ViaWNDdXJ2ZTJEIGlzIGEgU2hhcGUgdGhhdCByZXByZXNlbnRzIGEgc2VnbWVudCBvZiBhIHF1YWRyYXRpYworICogKEJlemllcikgY3VydmUuIFRoZSBjdXJ2ZWQgc2VnbWVudCBpcyBkZXRlcm1pbmVkIGJ5IGZvdXIgcG9pbnRzOiBhIHN0YXJ0CisgKiBwb2ludCwgYW4gZW5kIHBvaW50LCBhbmQgdHdvIGNvbnRyb2wgcG9pbnRzLiBUaGUgY29udHJvbCBwb2ludHMgZ2l2ZQorICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRhbmdlbnQgYW5kIG5leHQgZGVyaXZhdGl2ZSBhdCB0aGUgZW5kcG9pbnRzIGFjY29yZGluZworICogdG8gdGhlIHN0YW5kYXJkIHRoZW9yeSBvZiBCZXppZXIgY3VydmVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBCZXppZXIKKyAqIGN1cnZlcywgc2VlIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQiVDMyVBOXppZXJfY3VydmUiPnRoaXMKKyAqIGFydGljbGU8L2E+LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEN1YmljQ3VydmUyRCBpbXBsZW1lbnRzIFNoYXBlLCBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEZsb2F0IGlzIHRoZSBzdWJjbGFzcyBvZiBDdWJpY0N1cnZlMkQgdGhhdCBoYXMgYWxsIG9mIGl0cyBkYXRhCisgICAgICogdmFsdWVzIHN0b3JlZCB3aXRoIGZsb2F0LWxldmVsIHByZWNpc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZsb2F0IGV4dGVuZHMgQ3ViaWNDdXJ2ZTJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgeDE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHkxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IGN0cmx4MTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCBjdHJseTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IGN0cmx4MjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgY3RybHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgeDI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB5MjsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZsb2F0LXZhbHVlZCBDdWJpY0N1cnZlMkQgd2l0aCBhbGwgY29vcmRpbmF0ZQorICAgICAgICAgKiB2YWx1ZXMgc2V0IHRvIHplcm8uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZsb2F0LXZhbHVlZCBDdWJpY0N1cnZlMkQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqIGNvb3JkaW5hdGUgdmFsdWVzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIGN0cmx5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSBjdHJseDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIGN0cmx5MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGbG9hdChmbG9hdCB4MSwgZmxvYXQgeTEsIGZsb2F0IGN0cmx4MSwgZmxvYXQgY3RybHkxLCBmbG9hdCBjdHJseDIsIGZsb2F0IGN0cmx5MiwKKyAgICAgICAgICAgICAgICBmbG9hdCB4MiwgZmxvYXQgeTIpIHsKKyAgICAgICAgICAgIHNldEN1cnZlKHgxLCB5MSwgY3RybHgxLCBjdHJseTEsIGN0cmx4MiwgY3RybHkyLCB4MiwgeTIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WDEoKSB7CisgICAgICAgICAgICByZXR1cm4geDE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZMSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEN0cmxYMSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdHJseDE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRDdHJsWTEoKSB7CisgICAgICAgICAgICByZXR1cm4gY3RybHkxOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0Q3RybFgyKCkgeworICAgICAgICAgICAgcmV0dXJuIGN0cmx4MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEN0cmxZMigpIHsKKyAgICAgICAgICAgIHJldHVybiBjdHJseTI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYMigpIHsKKyAgICAgICAgICAgIHJldHVybiB4MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkyKCkgeworICAgICAgICAgICAgcmV0dXJuIHkyOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQb2ludDJEIGdldFAxKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkZsb2F0KHgxLCB5MSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0Q3RybFAxKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkZsb2F0KGN0cmx4MSwgY3RybHkxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRDdHJsUDIoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRmxvYXQoY3RybHgyLCBjdHJseTIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQb2ludDJEIGdldFAyKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkZsb2F0KHgyLCB5Mik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjdHJseDEsIGRvdWJsZSBjdHJseTEsIGRvdWJsZSBjdHJseDIsCisgICAgICAgICAgICAgICAgZG91YmxlIGN0cmx5MiwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgICAgIHRoaXMueDEgPSAoZmxvYXQpeDE7CisgICAgICAgICAgICB0aGlzLnkxID0gKGZsb2F0KXkxOworICAgICAgICAgICAgdGhpcy5jdHJseDEgPSAoZmxvYXQpY3RybHgxOworICAgICAgICAgICAgdGhpcy5jdHJseTEgPSAoZmxvYXQpY3RybHkxOworICAgICAgICAgICAgdGhpcy5jdHJseDIgPSAoZmxvYXQpY3RybHgyOworICAgICAgICAgICAgdGhpcy5jdHJseTIgPSAoZmxvYXQpY3RybHkyOworICAgICAgICAgICAgdGhpcy54MiA9IChmbG9hdCl4MjsKKyAgICAgICAgICAgIHRoaXMueTIgPSAoZmxvYXQpeTI7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgZGF0YSB2YWx1ZXMgb2YgdGhlIGN1cnZlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIGN0cmx5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSBjdHJseDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIGN0cmx5MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEN1cnZlKGZsb2F0IHgxLCBmbG9hdCB5MSwgZmxvYXQgY3RybHgxLCBmbG9hdCBjdHJseTEsIGZsb2F0IGN0cmx4MiwKKyAgICAgICAgICAgICAgICBmbG9hdCBjdHJseTIsIGZsb2F0IHgyLCBmbG9hdCB5MikgeworICAgICAgICAgICAgdGhpcy54MSA9IHgxOworICAgICAgICAgICAgdGhpcy55MSA9IHkxOworICAgICAgICAgICAgdGhpcy5jdHJseDEgPSBjdHJseDE7CisgICAgICAgICAgICB0aGlzLmN0cmx5MSA9IGN0cmx5MTsKKyAgICAgICAgICAgIHRoaXMuY3RybHgyID0gY3RybHgyOworICAgICAgICAgICAgdGhpcy5jdHJseTIgPSBjdHJseTI7CisgICAgICAgICAgICB0aGlzLngyID0geDI7CisgICAgICAgICAgICB0aGlzLnkyID0geTI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgICAgICBmbG9hdCByeDEgPSBNYXRoLm1pbihNYXRoLm1pbih4MSwgeDIpLCBNYXRoLm1pbihjdHJseDEsIGN0cmx4MikpOworICAgICAgICAgICAgZmxvYXQgcnkxID0gTWF0aC5taW4oTWF0aC5taW4oeTEsIHkyKSwgTWF0aC5taW4oY3RybHkxLCBjdHJseTIpKTsKKyAgICAgICAgICAgIGZsb2F0IHJ4MiA9IE1hdGgubWF4KE1hdGgubWF4KHgxLCB4MiksIE1hdGgubWF4KGN0cmx4MSwgY3RybHgyKSk7CisgICAgICAgICAgICBmbG9hdCByeTIgPSBNYXRoLm1heChNYXRoLm1heCh5MSwgeTIpLCBNYXRoLm1heChjdHJseTEsIGN0cmx5MikpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5GbG9hdChyeDEsIHJ5MSwgcngyIC0gcngxLCByeTIgLSByeTEpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIERvdWJsZSBpcyB0aGUgc3ViY2xhc3Mgb2YgQ3ViaWNDdXJ2ZTJEIHRoYXQgaGFzIGFsbCBvZiBpdHMgZGF0YQorICAgICAqIHZhbHVlcyBzdG9yZWQgd2l0aCBkb3VibGUtbGV2ZWwgcHJlY2lzaW9uLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRG91YmxlIGV4dGVuZHMgQ3ViaWNDdXJ2ZTJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHgxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIGN0cmx4MTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgY3RybHkxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgY3RybHgyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgY3RybHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHgyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZG91YmxlLXZhbHVlZCBDdWJpY0N1cnZlMkQgd2l0aCBhbGwgY29vcmRpbmF0ZQorICAgICAgICAgKiB2YWx1ZXMgc2V0IHRvIHplcm8uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRG91YmxlKCkgeworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkb3VibGUtdmFsdWVkIEN1YmljQ3VydmUyRCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogY29vcmRpbmF0ZSB2YWx1ZXMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIHkxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSBjdHJseDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHkxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIGN0cmx4MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHkyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB4MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIHkyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN0cmx4MSwgZG91YmxlIGN0cmx5MSwgZG91YmxlIGN0cmx4MiwKKyAgICAgICAgICAgICAgICBkb3VibGUgY3RybHkyLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICAgICAgc2V0Q3VydmUoeDEsIHkxLCBjdHJseDEsIGN0cmx5MSwgY3RybHgyLCBjdHJseTIsIHgyLCB5Mik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYMSgpIHsKKyAgICAgICAgICAgIHJldHVybiB4MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkxKCkgeworICAgICAgICAgICAgcmV0dXJuIHkxOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0Q3RybFgxKCkgeworICAgICAgICAgICAgcmV0dXJuIGN0cmx4MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEN0cmxZMSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdHJseTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRDdHJsWDIoKSB7CisgICAgICAgICAgICByZXR1cm4gY3RybHgyOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0Q3RybFkyKCkgeworICAgICAgICAgICAgcmV0dXJuIGN0cmx5MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgyKCkgeworICAgICAgICAgICAgcmV0dXJuIHgyOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WTIoKSB7CisgICAgICAgICAgICByZXR1cm4geTI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0UDEoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKHgxLCB5MSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0Q3RybFAxKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkRvdWJsZShjdHJseDEsIGN0cmx5MSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0Q3RybFAyKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkRvdWJsZShjdHJseDIsIGN0cmx5Mik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0UDIoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKHgyLCB5Mik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjdHJseDEsIGRvdWJsZSBjdHJseTEsIGRvdWJsZSBjdHJseDIsCisgICAgICAgICAgICAgICAgZG91YmxlIGN0cmx5MiwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgICAgIHRoaXMueDEgPSB4MTsKKyAgICAgICAgICAgIHRoaXMueTEgPSB5MTsKKyAgICAgICAgICAgIHRoaXMuY3RybHgxID0gY3RybHgxOworICAgICAgICAgICAgdGhpcy5jdHJseTEgPSBjdHJseTE7CisgICAgICAgICAgICB0aGlzLmN0cmx4MiA9IGN0cmx4MjsKKyAgICAgICAgICAgIHRoaXMuY3RybHkyID0gY3RybHkyOworICAgICAgICAgICAgdGhpcy54MiA9IHgyOworICAgICAgICAgICAgdGhpcy55MiA9IHkyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICAgICAgZG91YmxlIHJ4MSA9IE1hdGgubWluKE1hdGgubWluKHgxLCB4MiksIE1hdGgubWluKGN0cmx4MSwgY3RybHgyKSk7CisgICAgICAgICAgICBkb3VibGUgcnkxID0gTWF0aC5taW4oTWF0aC5taW4oeTEsIHkyKSwgTWF0aC5taW4oY3RybHkxLCBjdHJseTIpKTsKKyAgICAgICAgICAgIGRvdWJsZSByeDIgPSBNYXRoLm1heChNYXRoLm1heCh4MSwgeDIpLCBNYXRoLm1heChjdHJseDEsIGN0cmx4MikpOworICAgICAgICAgICAgZG91YmxlIHJ5MiA9IE1hdGgubWF4KE1hdGgubWF4KHkxLCB5MiksIE1hdGgubWF4KGN0cmx5MSwgY3RybHkyKSk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZTJELkRvdWJsZShyeDEsIHJ5MSwgcngyIC0gcngxLCByeTIgLSByeTEpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDdWJpY0N1cnZlMkQgcGF0aCBpdGVyYXRvcgorICAgICAqLworICAgIC8qKgorICAgICAqIFRoZSBJdGVyYXRvciBjbGFzcyBmb3IgdGhlIFNoYXBlIEN1YmljQ3VydmUyRC4KKyAgICAgKi8KKyAgICBjbGFzcyBJdGVyYXRvciBpbXBsZW1lbnRzIFBhdGhJdGVyYXRvciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzb3VyY2UgQ3ViaWNDdXJ2ZTJEIG9iamVjdC4KKyAgICAgICAgICovCisgICAgICAgIEN1YmljQ3VydmUyRCBjOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcGF0aCBpdGVyYXRvciB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY3VycmVudCBzZWdtZW50IGluZGV4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEN1YmljQ3VydmUyRC5JdGVyYXRvciBmb3IgZ2l2ZW4gbGluZSBhbmQKKyAgICAgICAgICogdHJhbnNmb3JtYXRpb24KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBjCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBDdWJpY0N1cnZlMkQgb2JqZWN0LgorICAgICAgICAgKiBAcGFyYW0gdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBhZmZpbmUgdHJhbnNmb3JtYXRpb24gb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgSXRlcmF0b3IoQ3ViaWNDdXJ2ZTJEIGMsIEFmZmluZVRyYW5zZm9ybSB0KSB7CisgICAgICAgICAgICB0aGlzLmMgPSBjOworICAgICAgICAgICAgdGhpcy50ID0gdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBuZXh0KCkgeworICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IGMuZ2V0WDEoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSBjLmdldFkxKCk7CisgICAgICAgICAgICAgICAgY291bnQgPSAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0NVQklDVE87CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gYy5nZXRDdHJsWDEoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSBjLmdldEN0cmxZMSgpOworICAgICAgICAgICAgICAgIGNvb3Jkc1syXSA9IGMuZ2V0Q3RybFgyKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzNdID0gYy5nZXRDdHJsWTIoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbNF0gPSBjLmdldFgyKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzVdID0gYy5nZXRZMigpOworICAgICAgICAgICAgICAgIGNvdW50ID0gMzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGZsb2F0W10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCljLmdldFgxKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KWMuZ2V0WTEoKTsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfQ1VCSUNUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSAoZmxvYXQpYy5nZXRDdHJsWDEoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSAoZmxvYXQpYy5nZXRDdHJsWTEoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMl0gPSAoZmxvYXQpYy5nZXRDdHJsWDIoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbM10gPSAoZmxvYXQpYy5nZXRDdHJsWTIoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbNF0gPSAoZmxvYXQpYy5nZXRYMigpOworICAgICAgICAgICAgICAgIGNvb3Jkc1s1XSA9IChmbG9hdCljLmdldFkyKCk7CisgICAgICAgICAgICAgICAgY291bnQgPSAzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IDItRCBjdWJpYyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ3ViaWNDdXJ2ZTJEKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFgxKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRZMSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFBvaW50MkQgZ2V0UDEoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRDdHJsWDEoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRDdHJsWTEoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQb2ludDJEIGdldEN0cmxQMSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRDdHJsWDIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0Q3RybFkyKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUG9pbnQyRCBnZXRDdHJsUDIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WDIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WTIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuZCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFBvaW50MkQgZ2V0UDIoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2YgdGhlIGN1cnZlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiBAcGFyYW0gY3RybHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIGN0cmx4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIGN0cmx5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q3VydmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjdHJseDEsIGRvdWJsZSBjdHJseTEsCisgICAgICAgICAgICBkb3VibGUgY3RybHgyLCBkb3VibGUgY3RybHkyLCBkb3VibGUgeDIsIGRvdWJsZSB5Mik7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIG9mIHRoZSBjdXJ2ZSBhcyBwb2ludCBvYmplY3RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwMQorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqIEBwYXJhbSBjcDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjcDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0gcDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgcG9pbnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgcG9pbnRzIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoUG9pbnQyRCBwMSwgUG9pbnQyRCBjcDEsIFBvaW50MkQgY3AyLCBQb2ludDJEIHAyKSB7CisgICAgICAgIHNldEN1cnZlKHAxLmdldFgoKSwgcDEuZ2V0WSgpLCBjcDEuZ2V0WCgpLCBjcDEuZ2V0WSgpLCBjcDIuZ2V0WCgpLCBjcDIuZ2V0WSgpLCBwMi5nZXRYKCksCisgICAgICAgICAgICAgICAgcDIuZ2V0WSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIG9mIHRoZSBjdXJ2ZSBieSByZWFkaW5nIHRoZSBkYXRhIGZyb20gYW4gYXJyYXkgb2YgdmFsdWVzLgorICAgICAqIFRoZSB2YWx1ZXMgYXJlIHJlYWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGFyZ3VtZW50cyBvZiB0aGUgbWV0aG9kCisgICAgICoge0BsaW5rIEN1YmljQ3VydmUyRCNzZXRDdXJ2ZShkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSl9CisgICAgICogLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb29yZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiB2YWx1ZXMgY29udGFpbmluZyB0aGUgbmV3IGNvb3JkaW5hdGVzLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgdGhlIGRhdGEgdG8gcmVhZCB3aXRoaW4gdGhlIGFycmF5LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNvb3Jkcy5sZW5ndGh9IDwgb2Zmc2V0ICsgOC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvb3JkaW5hdGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDdXJ2ZShkb3VibGVbXSBjb29yZHMsIGludCBvZmZzZXQpIHsKKyAgICAgICAgc2V0Q3VydmUoY29vcmRzW29mZnNldCArIDBdLCBjb29yZHNbb2Zmc2V0ICsgMV0sIGNvb3Jkc1tvZmZzZXQgKyAyXSwgY29vcmRzW29mZnNldCArIDNdLAorICAgICAgICAgICAgICAgIGNvb3Jkc1tvZmZzZXQgKyA0XSwgY29vcmRzW29mZnNldCArIDVdLCBjb29yZHNbb2Zmc2V0ICsgNl0sIGNvb3Jkc1tvZmZzZXQgKyA3XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgY3VydmUgYnkgcmVhZGluZyB0aGUgZGF0YSBmcm9tIGFuIGFycmF5IG9mIHBvaW50cy4KKyAgICAgKiBUaGUgdmFsdWVzIGFyZSByZWFkIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBhcmd1bWVudHMgb2YgdGhlIG1ldGhvZAorICAgICAqIHtAbGluayBDdWJpY0N1cnZlMkQjc2V0Q3VydmUoUG9pbnQyRCwgUG9pbnQyRCwgUG9pbnQyRCwgUG9pbnQyRCl9CisgICAgICogCisgICAgICogQHBhcmFtIHBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyBjb250YWluaW5nIHRoZSBuZXcgY29vcmRpbmF0ZXMuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZGF0YSB0byByZWFkIHdpdGhpbiB0aGUgYXJyYXkuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcG9pbnRzLmxlbmd0aH0gPCBvZmZzZXQgKyAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwb2ludCBhcnJheSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEN1cnZlKFBvaW50MkRbXSBwb2ludHMsIGludCBvZmZzZXQpIHsKKyAgICAgICAgc2V0Q3VydmUocG9pbnRzW29mZnNldCArIDBdLmdldFgoKSwgcG9pbnRzW29mZnNldCArIDBdLmdldFkoKSwgcG9pbnRzW29mZnNldCArIDFdLmdldFgoKSwKKyAgICAgICAgICAgICAgICBwb2ludHNbb2Zmc2V0ICsgMV0uZ2V0WSgpLCBwb2ludHNbb2Zmc2V0ICsgMl0uZ2V0WCgpLCBwb2ludHNbb2Zmc2V0ICsgMl0uZ2V0WSgpLAorICAgICAgICAgICAgICAgIHBvaW50c1tvZmZzZXQgKyAzXS5nZXRYKCksIHBvaW50c1tvZmZzZXQgKyAzXS5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2YgdGhlIGN1cnZlIGJ5IGNvcHlpbmcgaXQgZnJvbSBhbm90aGVyIEN1YmljQ3VydmUyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY3VydmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjdXJ2ZSB0byBjb3B5IHRoZSBkYXRhIHBvaW50cyBmcm9tLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY3VydmUgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDdXJ2ZShDdWJpY0N1cnZlMkQgY3VydmUpIHsKKyAgICAgICAgc2V0Q3VydmUoY3VydmUuZ2V0WDEoKSwgY3VydmUuZ2V0WTEoKSwgY3VydmUuZ2V0Q3RybFgxKCksIGN1cnZlLmdldEN0cmxZMSgpLCBjdXJ2ZQorICAgICAgICAgICAgICAgIC5nZXRDdHJsWDIoKSwgY3VydmUuZ2V0Q3RybFkyKCksIGN1cnZlLmdldFgyKCksIGN1cnZlLmdldFkyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNxdWFyZSBvZiB0aGUgZmxhdG5lc3Mgb2YgdGhpcyBjdXJ2ZSwgd2hlcmUgdGhlIGZsYXRuZXNzIGlzIHRoZQorICAgICAqIG1heGltdW0gZGlzdGFuY2UgZnJvbSB0aGUgY3VydmVzIGNvbnRyb2wgcG9pbnRzIHRvIHRoZSBsaW5lIHNlZ21lbnQKKyAgICAgKiBjb25uZWN0aW5nIHRoZSB0d28gcG9pbnRzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSBvZiB0aGUgZmxhdG5lc3MuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRGbGF0bmVzc1NxKCkgeworICAgICAgICByZXR1cm4gZ2V0RmxhdG5lc3NTcShnZXRYMSgpLCBnZXRZMSgpLCBnZXRDdHJsWDEoKSwgZ2V0Q3RybFkxKCksIGdldEN0cmxYMigpLCBnZXRDdHJsWTIoKSwKKyAgICAgICAgICAgICAgICBnZXRYMigpLCBnZXRZMigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzcXVhcmUgb2YgdGhlIGZsYXRuZXNzIG9mIHRoZSBjdWJpYyBjdXJ2ZSBzZWdtZW50IGRlZmluZWQgYnkgdGhlCisgICAgICogc3BlY2lmaWVkIHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogQHBhcmFtIGN0cmx4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0gY3RybHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSBvZiB0aGUgZmxhdG5lc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RmxhdG5lc3NTcShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN0cmx4MSwgZG91YmxlIGN0cmx5MSwKKyAgICAgICAgICAgIGRvdWJsZSBjdHJseDIsIGRvdWJsZSBjdHJseTIsIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgIHJldHVybiBNYXRoLm1heChMaW5lMkQucHRTZWdEaXN0U3EoeDEsIHkxLCB4MiwgeTIsIGN0cmx4MSwgY3RybHkxKSwgTGluZTJELnB0U2VnRGlzdFNxKHgxLAorICAgICAgICAgICAgICAgIHkxLCB4MiwgeTIsIGN0cmx4MiwgY3RybHkyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3F1YXJlIG9mIHRoZSBmbGF0bmVzcyBvZiB0aGUgY3ViaWMgY3VydmUgc2VnbWVudCBkZWZpbmVkIGJ5IHRoZQorICAgICAqIHNwZWNpZmllZCB2YWx1ZXMuIFRoZSB2YWx1ZXMgYXJlIHJlYWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGFyZ3VtZW50cworICAgICAqIG9mIHRoZSBtZXRob2QKKyAgICAgKiB7QGxpbmsgQ3ViaWNDdXJ2ZTJEI2dldEZsYXRuZXNzU3EoZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpfQorICAgICAqIC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29vcmRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgcG9pbnRzIGNvbnRhaW5pbmcgdGhlIG5ldyBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBkYXRhIHRvIHJlYWQgd2l0aGluIHRoZSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGZsYXRuZXNzLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcG9pbnRzLmxlbmd0aCA8IG9mZnNldCArIC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBvaW50IGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RmxhdG5lc3NTcShkb3VibGUgY29vcmRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGdldEZsYXRuZXNzU3EoY29vcmRzW29mZnNldCArIDBdLCBjb29yZHNbb2Zmc2V0ICsgMV0sIGNvb3Jkc1tvZmZzZXQgKyAyXSwKKyAgICAgICAgICAgICAgICBjb29yZHNbb2Zmc2V0ICsgM10sIGNvb3Jkc1tvZmZzZXQgKyA0XSwgY29vcmRzW29mZnNldCArIDVdLCBjb29yZHNbb2Zmc2V0ICsgNl0sCisgICAgICAgICAgICAgICAgY29vcmRzW29mZnNldCArIDddKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmbGF0bmVzcyBvZiB0aGlzIGN1cnZlLCB3aGVyZSB0aGUgZmxhdG5lc3MgaXMgdGhlIG1heGltdW0KKyAgICAgKiBkaXN0YW5jZSBmcm9tIHRoZSBjdXJ2ZXMgY29udHJvbCBwb2ludHMgdG8gdGhlIGxpbmUgc2VnbWVudCBjb25uZWN0aW5nCisgICAgICogdGhlIHR3byBwb2ludHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZmxhdG5lc3Mgb2YgdGhpcyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldEZsYXRuZXNzKCkgeworICAgICAgICByZXR1cm4gZ2V0RmxhdG5lc3MoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0Q3RybFgxKCksIGdldEN0cmxZMSgpLCBnZXRDdHJsWDIoKSwgZ2V0Q3RybFkyKCksCisgICAgICAgICAgICAgICAgZ2V0WDIoKSwgZ2V0WTIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmxhdG5lc3Mgb2YgdGhlIGN1YmljIGN1cnZlIHNlZ21lbnQgZGVmaW5lZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiBAcGFyYW0gY3RybHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIGN0cmx4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIGN0cmx5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgZmxhdG5lc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RmxhdG5lc3MoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjdHJseDEsIGRvdWJsZSBjdHJseTEsCisgICAgICAgICAgICBkb3VibGUgY3RybHgyLCBkb3VibGUgY3RybHkyLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGdldEZsYXRuZXNzU3EoeDEsIHkxLCBjdHJseDEsIGN0cmx5MSwgY3RybHgyLCBjdHJseTIsIHgyLCB5MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZsYXRuZXNzIG9mIHRoZSBjdWJpYyBjdXJ2ZSBzZWdtZW50IGRlZmluZWQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIHZhbHVlcy4gVGhlIHZhbHVlcyBhcmUgcmVhZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgYXJndW1lbnRzIG9mIHRoZQorICAgICAqIG1ldGhvZAorICAgICAqIHtAbGluayBDdWJpY0N1cnZlMkQjZ2V0RmxhdG5lc3MoZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpfQorICAgICAqIC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29vcmRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgcG9pbnRzIGNvbnRhaW5pbmcgdGhlIG5ldyBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBkYXRhIHRvIHJlYWQgd2l0aGluIHRoZSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmbGF0bmVzcy4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHBvaW50cy5sZW5ndGggPCBvZmZzZXQgKyAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwb2ludCBhcnJheSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGdldEZsYXRuZXNzKGRvdWJsZSBjb29yZHNbXSwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gZ2V0RmxhdG5lc3MoY29vcmRzW29mZnNldCArIDBdLCBjb29yZHNbb2Zmc2V0ICsgMV0sIGNvb3Jkc1tvZmZzZXQgKyAyXSwKKyAgICAgICAgICAgICAgICBjb29yZHNbb2Zmc2V0ICsgM10sIGNvb3Jkc1tvZmZzZXQgKyA0XSwgY29vcmRzW29mZnNldCArIDVdLCBjb29yZHNbb2Zmc2V0ICsgNl0sCisgICAgICAgICAgICAgICAgY29vcmRzW29mZnNldCArIDddKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBkYXRhIGZvciB0d28gY3ViaWMgY3VydmVzIGJ5IGRpdmlkaW5nIHRoaXMgY3VydmUgaW4gdHdvLiBUaGUKKyAgICAgKiBkaXZpc2lvbiBwb2ludCBpcyB0aGUgcG9pbnQgb24gdGhlIGN1cnZlIHRoYXQgaXMgY2xvc2VzdCB0byB0aGUgYXZlcmFnZQorICAgICAqIG9mIGN1cnZlJ3MgdHdvIGNvbnRyb2wgcG9pbnRzLiBUaGUgdHdvIG5ldyBjb250cm9sIHBvaW50cyAobmVhcmVzdCB0aGUKKyAgICAgKiBuZXcgZW5kcG9pbnQpIGFyZSBjb21wdXRlZCBieSBhdmVyYWdpbmcgdGhlIG9yaWdpbmFsIGNvbnRyb2wgcG9pbnRzIHdpdGgKKyAgICAgKiB0aGUgbmV3IGVuZHBvaW50LiBUaGUgZGF0YSBvZiB0aGlzIGN1cnZlIGlzIGxlZnQgdW5jaGFuZ2VkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsZWZ0CisgICAgICogICAgICAgICAgICB0aGUgQ3ViaWNDdXJ2ZTJEIHdoZXJlIHRoZSBsZWZ0IChzdGFydCkgc2VnbWVudCdzIGRhdGEgaXMKKyAgICAgKiAgICAgICAgICAgIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHJpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgQ3ViaWNDdXJ2ZTJEIHdoZXJlIHRoZSByaWdodCAoZW5kKSBzZWdtZW50J3MgZGF0YSBpcworICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZWl0aGVyIGN1cnZlIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3ViZGl2aWRlKEN1YmljQ3VydmUyRCBsZWZ0LCBDdWJpY0N1cnZlMkQgcmlnaHQpIHsKKyAgICAgICAgc3ViZGl2aWRlKHRoaXMsIGxlZnQsIHJpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBkYXRhIGZvciB0d28gY3ViaWMgY3VydmVzIGJ5IGRpdmlkaW5nIHRoZSBzcGVjaWZpZWQgY3VydmUgaW4KKyAgICAgKiB0d28uIFRoZSBkaXZpc2lvbiBwb2ludCBpcyB0aGUgcG9pbnQgb24gdGhlIGN1cnZlIHRoYXQgaXMgY2xvc2VzdCB0byB0aGUKKyAgICAgKiBhdmVyYWdlIG9mIGN1cnZlJ3MgdHdvIGNvbnRyb2wgcG9pbnRzLiBUaGUgdHdvIG5ldyBjb250cm9sIHBvaW50cworICAgICAqIChuZWFyZXN0IHRoZSBuZXcgZW5kcG9pbnQpIGFyZSBjb21wdXRlZCBieSBhdmVyYWdpbmcgdGhlIG9yaWdpbmFsIGNvbnRyb2wKKyAgICAgKiBwb2ludHMgd2l0aCB0aGUgbmV3IGVuZHBvaW50LiBUaGUgZGF0YSBvZiB0aGUgc291cmNlIGN1cnZlIGlzIGxlZnQKKyAgICAgKiB1bmNoYW5nZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIGN1cnZlIHRvIGJlIGRpdmlkZWQgaW4gdHdvLgorICAgICAqIEBwYXJhbSBsZWZ0CisgICAgICogICAgICAgICAgICB0aGUgQ3ViaWNDdXJ2ZTJEIHdoZXJlIHRoZSBsZWZ0IChzdGFydCkgc2VnbWVudCdzIGRhdGEgaXMKKyAgICAgKiAgICAgICAgICAgIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHJpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgQ3ViaWNDdXJ2ZTJEIHdoZXJlIHRoZSByaWdodCAoZW5kKSBzZWdtZW50J3MgZGF0YSBpcworICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZWl0aGVyIGN1cnZlIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHN1YmRpdmlkZShDdWJpY0N1cnZlMkQgc3JjLCBDdWJpY0N1cnZlMkQgbGVmdCwgQ3ViaWNDdXJ2ZTJEIHJpZ2h0KSB7CisgICAgICAgIGRvdWJsZSB4MSA9IHNyYy5nZXRYMSgpOworICAgICAgICBkb3VibGUgeTEgPSBzcmMuZ2V0WTEoKTsKKyAgICAgICAgZG91YmxlIGN4MSA9IHNyYy5nZXRDdHJsWDEoKTsKKyAgICAgICAgZG91YmxlIGN5MSA9IHNyYy5nZXRDdHJsWTEoKTsKKyAgICAgICAgZG91YmxlIGN4MiA9IHNyYy5nZXRDdHJsWDIoKTsKKyAgICAgICAgZG91YmxlIGN5MiA9IHNyYy5nZXRDdHJsWTIoKTsKKyAgICAgICAgZG91YmxlIHgyID0gc3JjLmdldFgyKCk7CisgICAgICAgIGRvdWJsZSB5MiA9IHNyYy5nZXRZMigpOworICAgICAgICBkb3VibGUgY3ggPSAoY3gxICsgY3gyKSAvIDIuMDsKKyAgICAgICAgZG91YmxlIGN5ID0gKGN5MSArIGN5MikgLyAyLjA7CisgICAgICAgIGN4MSA9ICh4MSArIGN4MSkgLyAyLjA7CisgICAgICAgIGN5MSA9ICh5MSArIGN5MSkgLyAyLjA7CisgICAgICAgIGN4MiA9ICh4MiArIGN4MikgLyAyLjA7CisgICAgICAgIGN5MiA9ICh5MiArIGN5MikgLyAyLjA7CisgICAgICAgIGRvdWJsZSBheCA9IChjeDEgKyBjeCkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBheSA9IChjeTEgKyBjeSkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBieCA9IChjeDIgKyBjeCkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBieSA9IChjeTIgKyBjeSkgLyAyLjA7CisgICAgICAgIGN4ID0gKGF4ICsgYngpIC8gMi4wOworICAgICAgICBjeSA9IChheSArIGJ5KSAvIDIuMDsKKyAgICAgICAgaWYgKGxlZnQgIT0gbnVsbCkgeworICAgICAgICAgICAgbGVmdC5zZXRDdXJ2ZSh4MSwgeTEsIGN4MSwgY3kxLCBheCwgYXksIGN4LCBjeSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJpZ2h0LnNldEN1cnZlKGN4LCBjeSwgYngsIGJ5LCBjeDIsIGN5MiwgeDIsIHkyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGRhdGEgZm9yIHR3byBjdWJpYyBjdXJ2ZXMgYnkgZGl2aWRpbmcgdGhlIHNwZWNpZmllZCBjdXJ2ZSBpbgorICAgICAqIHR3by4gVGhlIGRpdmlzaW9uIHBvaW50IGlzIHRoZSBwb2ludCBvbiB0aGUgY3VydmUgdGhhdCBpcyBjbG9zZXN0IHRvIHRoZQorICAgICAqIGF2ZXJhZ2Ugb2YgY3VydmUncyB0d28gY29udHJvbCBwb2ludHMuIFRoZSB0d28gbmV3IGNvbnRyb2wgcG9pbnRzCisgICAgICogKG5lYXJlc3QgdGhlIG5ldyBlbmRwb2ludCkgYXJlIGNvbXB1dGVkIGJ5IGF2ZXJhZ2luZyB0aGUgb3JpZ2luYWwgY29udHJvbAorICAgICAqIHBvaW50cyB3aXRoIHRoZSBuZXcgZW5kcG9pbnQuIFRoZSBkYXRhIG9mIHRoZSBzb3VyY2UgY3VydmUgaXMgbGVmdAorICAgICAqIHVuY2hhbmdlZC4gVGhlIGRhdGEgZm9yIHRoZSB0aHJlZSBjdXJ2ZXMgaXMgcmVhZC93cml0dGVuIGluIHRoZSB1c3VhbAorICAgICAqIG9yZGVyOiB7IHgxLCB5MSwgY3RybHgxLCBjdHJseTEsIGN0cmx4MiwgY3J0cnkyLCB4MiwgeTMgfQorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IGdpdmVzIHRoZSBkYXRhIHZhbHVlcyBmb3IgdGhlIHNvdXJjZSBjdXJ2ZS4KKyAgICAgKiBAcGFyYW0gc3JjT2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzcmMgYXJyYXkgdG8gcmVhZCB0aGUgdmFsdWVzIGZyb20uCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aGVyZSB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHN0YXJ0IGN1cnZlIHNob3VsZCBiZQorICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVmdE9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgbGVmdCBhcnJheSB0byBzdGFydCB3cml0aW5nIHRoZSB2YWx1ZXMuCisgICAgICogQHBhcmFtIHJpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgd2hlcmUgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBlbmQgY3VydmUgc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICB3cml0dGVuLgorICAgICAqIEBwYXJhbSByaWdodE9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgcmlnaHQgYXJyYXkgdG8gc3RhcnQgd3JpdGluZyB0aGUgdmFsdWVzLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc3JjLmxlbmd0aCA8IHNyY29mZiArIDggb3IgaWYgbGVmdC5sZW5ndGggPCBsZWZ0T2ZmICsgOCBvcgorICAgICAqICAgICAgICAgICAgIGlmIHJpZ2h0Lmxlbmd0aCA8IHJpZ2h0T2ZmICsgOC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBhcnJheXMgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc3ViZGl2aWRlKGRvdWJsZSBzcmNbXSwgaW50IHNyY09mZiwgZG91YmxlIGxlZnRbXSwgaW50IGxlZnRPZmYsCisgICAgICAgICAgICBkb3VibGUgcmlnaHRbXSwgaW50IHJpZ2h0T2ZmKSB7CisgICAgICAgIGRvdWJsZSB4MSA9IHNyY1tzcmNPZmYgKyAwXTsKKyAgICAgICAgZG91YmxlIHkxID0gc3JjW3NyY09mZiArIDFdOworICAgICAgICBkb3VibGUgY3gxID0gc3JjW3NyY09mZiArIDJdOworICAgICAgICBkb3VibGUgY3kxID0gc3JjW3NyY09mZiArIDNdOworICAgICAgICBkb3VibGUgY3gyID0gc3JjW3NyY09mZiArIDRdOworICAgICAgICBkb3VibGUgY3kyID0gc3JjW3NyY09mZiArIDVdOworICAgICAgICBkb3VibGUgeDIgPSBzcmNbc3JjT2ZmICsgNl07CisgICAgICAgIGRvdWJsZSB5MiA9IHNyY1tzcmNPZmYgKyA3XTsKKyAgICAgICAgZG91YmxlIGN4ID0gKGN4MSArIGN4MikgLyAyLjA7CisgICAgICAgIGRvdWJsZSBjeSA9IChjeTEgKyBjeTIpIC8gMi4wOworICAgICAgICBjeDEgPSAoeDEgKyBjeDEpIC8gMi4wOworICAgICAgICBjeTEgPSAoeTEgKyBjeTEpIC8gMi4wOworICAgICAgICBjeDIgPSAoeDIgKyBjeDIpIC8gMi4wOworICAgICAgICBjeTIgPSAoeTIgKyBjeTIpIC8gMi4wOworICAgICAgICBkb3VibGUgYXggPSAoY3gxICsgY3gpIC8gMi4wOworICAgICAgICBkb3VibGUgYXkgPSAoY3kxICsgY3kpIC8gMi4wOworICAgICAgICBkb3VibGUgYnggPSAoY3gyICsgY3gpIC8gMi4wOworICAgICAgICBkb3VibGUgYnkgPSAoY3kyICsgY3kpIC8gMi4wOworICAgICAgICBjeCA9IChheCArIGJ4KSAvIDIuMDsKKyAgICAgICAgY3kgPSAoYXkgKyBieSkgLyAyLjA7CisgICAgICAgIGlmIChsZWZ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxlZnRbbGVmdE9mZiArIDBdID0geDE7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyAxXSA9IHkxOworICAgICAgICAgICAgbGVmdFtsZWZ0T2ZmICsgMl0gPSBjeDE7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyAzXSA9IGN5MTsKKyAgICAgICAgICAgIGxlZnRbbGVmdE9mZiArIDRdID0gYXg7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyA1XSA9IGF5OworICAgICAgICAgICAgbGVmdFtsZWZ0T2ZmICsgNl0gPSBjeDsKKyAgICAgICAgICAgIGxlZnRbbGVmdE9mZiArIDddID0gY3k7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgMF0gPSBjeDsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgMV0gPSBjeTsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgMl0gPSBieDsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgM10gPSBieTsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgNF0gPSBjeDI7CisgICAgICAgICAgICByaWdodFtyaWdodE9mZiArIDVdID0gY3kyOworICAgICAgICAgICAgcmlnaHRbcmlnaHRPZmYgKyA2XSA9IHgyOworICAgICAgICAgICAgcmlnaHRbcmlnaHRPZmYgKyA3XSA9IHkyOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIHJvb3RzIG9mIHRoZSBjdWJpYyBwb2x5bm9taWFsLiBUaGlzIGlzIGFjY29tcGxpc2hlZCBieSBmaW5kaW5nCisgICAgICogdGhlIChyZWFsKSB2YWx1ZXMgb2YgeCB0aGF0IHNvbHZlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb246IGVxblszXSp4KngqeCArCisgICAgICogZXFuWzJdKngqeCArIGVxblsxXSp4ICsgZXFuWzBdID0gMC4gVGhlIHNvbHV0aW9ucyBhcmUgd3JpdHRlbiBiYWNrIGludG8KKyAgICAgKiB0aGUgYXJyYXkgZXFuIHN0YXJ0aW5nIGZyb20gdGhlIGluZGV4IDAgaW4gdGhlIGFycmF5LiBUaGUgcmV0dXJuIHZhbHVlCisgICAgICogdGVsbHMgaG93IG1hbnkgYXJyYXkgZWxlbWVudHMgaGF2ZSBiZWVuIGNoYW5nZWQgYnkgdGhpcyBtZXRob2QgY2FsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXFuCisgICAgICogICAgICAgICAgICBhbiBhcnJheSBjb250YWluaW5nIHRoZSBjb2VmZmljaWVudHMgb2YgdGhlIGN1YmljIHBvbHlub21pYWwKKyAgICAgKiAgICAgICAgICAgIHRvIHNvbHZlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByb290cyBvZiB0aGUgY3ViaWMgcG9seW5vbWlhbC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVxbi5sZW5ndGggPCA0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBzb2x2ZUN1YmljKGRvdWJsZSBlcW5bXSkgeworICAgICAgICByZXR1cm4gc29sdmVDdWJpYyhlcW4sIGVxbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIHJvb3RzIG9mIHRoZSBjdWJpYyBwb2x5bm9taWFsLiBUaGlzIGlzIGFjY29tcGxpc2hlZCBieSBmaW5kaW5nCisgICAgICogdGhlIChyZWFsKSB2YWx1ZXMgb2YgeCB0aGF0IHNvbHZlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb246IGVxblszXSp4KngqeCArCisgICAgICogZXFuWzJdKngqeCArIGVxblsxXSp4ICsgZXFuWzBdID0gMC4gVGhlIHNvbHV0aW9ucyBhcmUgd3JpdHRlbiBpbnRvIHRoZQorICAgICAqIGFycmF5IHJlcyBzdGFydGluZyBmcm9tIHRoZSBpbmRleCAwIGluIHRoZSBhcnJheS4gVGhlIHJldHVybiB2YWx1ZSB0ZWxscworICAgICAqIGhvdyBtYW55IGFycmF5IGVsZW1lbnRzIGhhdmUgYmVlbiBjaGFuZ2VkIGJ5IHRoaXMgbWV0aG9kIGNhbGwuCisgICAgICogCisgICAgICogQHBhcmFtIGVxbgorICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgY29lZmZpY2llbnRzIG9mIHRoZSBjdWJpYyBwb2x5bm9taWFsCisgICAgICogICAgICAgICAgICB0byBzb2x2ZS4KKyAgICAgKiBAcGFyYW0gcmVzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgdGhhdCB0aGlzIG1ldGhvZCB3cml0ZXMgdGhlIHJlc3VsdHMgaW50by4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygcm9vdHMgb2YgdGhlIGN1YmljIHBvbHlub21pYWwuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcW4ubGVuZ3RoIDwgNCBvciBpZiByZXMubGVuZ3RoIGlzIGxlc3MgdGhhbiB0aGUgbnVtYmVyIG9mCisgICAgICogICAgICAgICAgICAgcm9vdHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciBhcnJheSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNvbHZlQ3ViaWMoZG91YmxlIGVxbltdLCBkb3VibGUgcmVzW10pIHsKKyAgICAgICAgcmV0dXJuIENyb3NzaW5nLnNvbHZlQ3ViaWMoZXFuLCByZXMpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBDcm9zc2luZy5pc0luc2lkZUV2ZW5PZGQoQ3Jvc3NpbmcuY3Jvc3NTaGFwZSh0aGlzLCBweCwgcHkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgcngsIGRvdWJsZSByeSwgZG91YmxlIHJ3LCBkb3VibGUgcmgpIHsKKyAgICAgICAgaW50IGNyb3NzID0gQ3Jvc3NpbmcuaW50ZXJzZWN0U2hhcGUodGhpcywgcngsIHJ5LCBydywgcmgpOworICAgICAgICByZXR1cm4gY3Jvc3MgIT0gQ3Jvc3NpbmcuQ1JPU1NJTkcgJiYgQ3Jvc3NpbmcuaXNJbnNpZGVFdmVuT2RkKGNyb3NzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpbnQgY3Jvc3MgPSBDcm9zc2luZy5pbnRlcnNlY3RTaGFwZSh0aGlzLCByeCwgcnksIHJ3LCByaCk7CisgICAgICAgIHJldHVybiBjcm9zcyA9PSBDcm9zc2luZy5DUk9TU0lORyB8fCBDcm9zc2luZy5pc0luc2lkZUV2ZW5PZGQoY3Jvc3MpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFBvaW50MkQgcCkgeworICAgICAgICByZXR1cm4gY29udGFpbnMocC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgcmV0dXJuIGludGVyc2VjdHMoci5nZXRYKCksIHIuZ2V0WSgpLCByLmdldFdpZHRoKCksIHIuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHIuZ2V0WCgpLCByLmdldFkoKSwgci5nZXRXaWR0aCgpLCByLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIGdldEJvdW5kczJEKCkuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCB0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gYXQsIGRvdWJsZSBmbGF0bmVzcykgeworICAgICAgICByZXR1cm4gbmV3IEZsYXR0ZW5pbmdQYXRoSXRlcmF0b3IoZ2V0UGF0aEl0ZXJhdG9yKGF0KSwgZmxhdG5lc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9EaW1lbnNpb24yRC5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vRGltZW5zaW9uMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYTA4MWM1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vRGltZW5zaW9uMkQuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCisvKioKKyAqIFRoZSBDbGFzcyBEaW1lbnNpb24yRCByZXByZXNlbnRzIGEgc2l6ZSAod2lkdGggYW5kIGhlaWdodCkgb2YgYSBnZW9tZXRyaWMKKyAqIG9iamVjdC4gSXQgc3RvcmVzIGRvdWJsZS12YWx1ZWQgZGF0YSBpbiBvcmRlciB0byBiZSBjb21wYXRpYmxlIHdpdGgKKyAqIGhpZ2gtcHJlY2lzaW9uIGdlb21ldHJpYyBvcGVyYXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERpbWVuc2lvbjJEIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkaW1lbnNpb24gMmQgd2l0aCBubyBkYXRhLgorICAgICAqLworICAgIHByb3RlY3RlZCBEaW1lbnNpb24yRCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFdpZHRoKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGVpZ2h0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0SGVpZ2h0KCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0U2l6ZShkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgd2lkdGggYW5kIGhlaWdodCBiYXNlZCBvbiB0aGUgZGF0YSBvZiBhbm90aGVyIERpbWVuc2lvbjJECisgICAgICogb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgRGltZW5zaW9uMkQgb2JqZWN0IHByb3ZpZGluZyB0aGUgZGF0YSB0byBjb3B5IGludG8gdGhpcworICAgICAqICAgICAgICAgICAgRGltZW5zaW9uMkQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpemUoRGltZW5zaW9uMkQgZCkgeworICAgICAgICBzZXRTaXplKGQuZ2V0V2lkdGgoKSwgZC5nZXRIZWlnaHQoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vRWxsaXBzZTJELmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9FbGxpcHNlMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWZkMGQwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vRWxsaXBzZTJELmphdmEKQEAgLTAsMCArMSw0NTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0Lmdlb207CisKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBDbGFzcyBFbGxpcHNlMkQgZGVzY3JpYmVzIGFuIGVsbGlwc2UgZGVmaW5lZCBieSBhIHJlY3Rhbmd1bGFyIGFyZWEgaW4KKyAqIHdoaWNoIGl0IGlzIGluc2NyaWJlZC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBFbGxpcHNlMkQgZXh0ZW5kcyBSZWN0YW5ndWxhclNoYXBlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBGbG9hdCBpcyB0aGUgc3ViY2xhc3Mgb2YgRWxsaXBzZTJEIHRoYXQgaGFzIGFsbCBvZiBpdHMgZGF0YQorICAgICAqIHZhbHVlcyBzdG9yZWQgd2l0aCBmbG9hdC1sZXZlbCBwcmVjaXNpb24uCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGbG9hdCBleHRlbmRzIEVsbGlwc2UyRCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBlbGxpcHNlJ3MgYm91bmRpbmcKKyAgICAgICAgICogcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBlbGxpcHNlJ3MgYm91bmRpbmcKKyAgICAgICAgICogcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgRWxsaXBzZTJELgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KCkgeworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgRWxsaXBzZTJEIHdpdGggdGhlIHNwZWNpZmllZCBkYXRhLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgZWxsaXBzZSdzCisgICAgICAgICAqICAgICAgICAgICAgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBlbGxpcHNlJ3MKKyAgICAgICAgICogICAgICAgICAgICBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIGhlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGVsbGlwc2UncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgd2lkdGgsIGZsb2F0IGhlaWdodCkgeworICAgICAgICAgICAgc2V0RnJhbWUoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYKCkgeworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZKCkgeworICAgICAgICAgICAgcmV0dXJuIHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aCA8PSAwLjAgfHwgaGVpZ2h0IDw9IDAuMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZSBkYXRhIG9mIHRoZSBlbGxpcHNlJ3MgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgZWxsaXBzZSdzCisgICAgICAgICAqICAgICAgICAgICAgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBlbGxpcHNlJ3MKKyAgICAgICAgICogICAgICAgICAgICBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIGhlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGVsbGlwc2UncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZShmbG9hdCB4LCBmbG9hdCB5LCBmbG9hdCB3aWR0aCwgZmxvYXQgaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEZyYW1lKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSAoZmxvYXQpeDsKKyAgICAgICAgICAgIHRoaXMueSA9IChmbG9hdCl5OworICAgICAgICAgICAgdGhpcy53aWR0aCA9IChmbG9hdCl3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gKGZsb2F0KWhlaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRG91YmxlIGlzIHRoZSBzdWJjbGFzcyBvZiBFbGxpcHNlMkQgdGhhdCBoYXMgYWxsIG9mIGl0cyBkYXRhCisgICAgICogdmFsdWVzIHN0b3JlZCB3aXRoIGRvdWJsZS1sZXZlbCBwcmVjaXNpb24uCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBEb3VibGUgZXh0ZW5kcyBFbGxpcHNlMkQgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nCisgICAgICAgICAqIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIGVsbGlwc2UncyBib3VuZGluZworICAgICAgICAgKiByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBoZWlnaHQgb2YgdGhlIGVsbGlwc2UncyBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgRWxsaXBzZTJELgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZG91YmxlLXZhbHVlZCBFbGxpcHNlMkQgd2l0aCB0aGUgc3BlY2lmaWVkIGRhdGEuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSBlbGxpcHNlJ3MKKyAgICAgICAgICogICAgICAgICAgICBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICAgICAqIEBwYXJhbSB5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIGVsbGlwc2UncworICAgICAgICAgKiAgICAgICAgICAgIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIHdpZHRoCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBlbGxpcHNlJ3MgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgZWxsaXBzZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHNldEZyYW1lKHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WCgpIHsKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0V2lkdGgoKSB7CisgICAgICAgICAgICByZXR1cm4gd2lkdGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRIZWlnaHQoKSB7CisgICAgICAgICAgICByZXR1cm4gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gd2lkdGggPD0gMC4wIHx8IGhlaWdodCA8PSAwLjA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RnJhbWUoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHRoaXMueCA9IHg7CisgICAgICAgICAgICB0aGlzLnkgPSB5OworICAgICAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZTJELkRvdWJsZSh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogRWxsaXBzZTJEIHBhdGggaXRlcmF0b3IKKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgc3ViY2xhc3Mgb2YgUGF0aEl0ZXJhdG9yIHRvIHRyYXZlcnNlIGFuIEVsbGlwc2UyRC4KKyAgICAgKi8KKyAgICBjbGFzcyBJdGVyYXRvciBpbXBsZW1lbnRzIFBhdGhJdGVyYXRvciB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRWxsaXBzZSBpcyBzdWJkaXZpZGVkIGludG8gZm91ciBxdWFydGVycyBieSB4IGFuZCB5IGF4aXMuIEVhY2ggcGFydAorICAgICAgICAgKiBhcHByb3hpbWF0ZWQgYnkgY3ViaWMgQmV6aWVyIGN1cnZlLiBBcmMgaW4gZmlyc3QgcXVhcnRlciBpcyBzdGFydGVkCisgICAgICAgICAqIGluIChhLCAwKSBhbmQgZmluaXNoZWQgaW4gKDAsIGIpIHBvaW50cy4gQ29udHJvbCBwb2ludHMgZm9yIGN1YmljCisgICAgICAgICAqIGN1cnZlIHdpaWwgYmUgKGEsIDApLCAoYSwgbSksIChuLCBiKSBhbmQgKDAsIGIpIHdoZXJlIG4gYW5kIG0gYXJlCisgICAgICAgICAqIGNhbGN1bGF0ZWQgYmFzZWQgb24gcmVxdWlyZW1lbnQgQmV6aWVyIGN1cnZlIGluIHBvaW50IDAuNSBzaG91bGQgbGF5CisgICAgICAgICAqIG9uIHRoZSBhcmMuCisgICAgICAgICAqLworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY29lZmZpY2llbnQgdG8gY2FsY3VsYXRlIGNvbnRyb2wgcG9pbnRzIG9mIEJlemllciBjdXJ2ZXMuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBkb3VibGUgdSA9IDIuMCAvIDMuMCAqIChNYXRoLnNxcnQoMi4wKSAtIDEuMCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBwb2ludHMgY29vcmRpbmF0ZXMgY2FsY3VsYXRpb24gdGFibGUuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBkb3VibGUgcG9pbnRzW11bXSA9IHsKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAxLjAsIDAuNSArIHUsIDAuNSArIHUsIDEuMCwgMC41LCAxLjAKKyAgICAgICAgICAgICAgICB9LCB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLjUgLSB1LCAxLjAsIDAuMCwgMC41ICsgdSwgMC4wLCAwLjUKKyAgICAgICAgICAgICAgICB9LCB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIDAuNSAtIHUsIDAuNSAtIHUsIDAuMCwgMC41LCAwLjAKKyAgICAgICAgICAgICAgICB9LCB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLjUgKyB1LCAwLjAsIDEuMCwgMC41IC0gdSwgMS4wLCAwLjUKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgbGVmdC11cHBlciBjb3JuZXIgb2YgdGhlIGVsbGlwc2UgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgbGVmdC11cHBlciBjb3JuZXIgb2YgdGhlIGVsbGlwc2UgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgZWxsaXBzZSBib3VuZHMuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBoZWlnaHQgb2YgdGhlIGVsbGlwc2UgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBhdGggaXRlcmF0b3IgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGN1cnJlbnQgc2VnbWVudCBpbmRleC4KKyAgICAgICAgICovCisgICAgICAgIGludCBpbmRleDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBFbGxpcHNlMkQuSXRlcmF0b3IgZm9yIGdpdmVuIGVsbGlwc2UgYW5kCisgICAgICAgICAqIHRyYW5zZm9ybWF0aW9uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgRWxsaXBzZTJEIG9iamVjdC4KKyAgICAgICAgICogQHBhcmFtIHQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgYWZmaW5lIHRyYW5zZm9ybWF0aW9uIG9iamVjdC4KKyAgICAgICAgICovCisgICAgICAgIEl0ZXJhdG9yKEVsbGlwc2UyRCBlLCBBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICAgICAgdGhpcy54ID0gZS5nZXRYKCk7CisgICAgICAgICAgICB0aGlzLnkgPSBlLmdldFkoKTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSBlLmdldFdpZHRoKCk7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IGUuZ2V0SGVpZ2h0KCk7CisgICAgICAgICAgICB0aGlzLnQgPSB0OworICAgICAgICAgICAgaWYgKHdpZHRoIDwgMC4wIHx8IGhlaWdodCA8IDAuMCkgeworICAgICAgICAgICAgICAgIGluZGV4ID0gNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IDU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBuZXh0KCkgeworICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gNSkgeworICAgICAgICAgICAgICAgIHJldHVybiBTRUdfQ0xPU0U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgICAgIGlmIChpbmRleCA9PSAwKSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19NT1ZFVE87CisgICAgICAgICAgICAgICAgY291bnQgPSAxOworICAgICAgICAgICAgICAgIGRvdWJsZSBwW10gPSBwb2ludHNbM107CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0geCArIHBbNF0gKiB3aWR0aDsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSB5ICsgcFs1XSAqIGhlaWdodDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19DVUJJQ1RPOworICAgICAgICAgICAgICAgIGNvdW50ID0gMzsKKyAgICAgICAgICAgICAgICBkb3VibGUgcFtdID0gcG9pbnRzW2luZGV4IC0gMV07CisgICAgICAgICAgICAgICAgaW50IGogPSAwOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1tqXSA9IHggKyBwW2orK10gKiB3aWR0aDsKKyAgICAgICAgICAgICAgICAgICAgY29vcmRzW2pdID0geSArIHBbaisrXSAqIGhlaWdodDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdC50cmFuc2Zvcm0oY29vcmRzLCAwLCBjb29yZHMsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjdXJyZW50U2VnbWVudChmbG9hdFtdIGNvb3JkcykgeworICAgICAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjRCPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ID09IDUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gU0VHX0NMT1NFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvdW50ID0gMTsKKyAgICAgICAgICAgICAgICBkb3VibGUgcFtdID0gcG9pbnRzWzNdOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCkoeCArIHBbNF0gKiB3aWR0aCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KSh5ICsgcFs1XSAqIGhlaWdodCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfQ1VCSUNUTzsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDM7CisgICAgICAgICAgICAgICAgaW50IGogPSAwOworICAgICAgICAgICAgICAgIGRvdWJsZSBwW10gPSBwb2ludHNbaW5kZXggLSAxXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBjb29yZHNbal0gPSAoZmxvYXQpKHggKyBwW2orK10gKiB3aWR0aCk7CisgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1tqXSA9IChmbG9hdCkoeSArIHBbaisrXSAqIGhlaWdodCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEVsbGlwc2UyRC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRWxsaXBzZTJEKCkgeworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIGlmIChpc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBhID0gKHB4IC0gZ2V0WCgpKSAvIGdldFdpZHRoKCkgLSAwLjU7CisgICAgICAgIGRvdWJsZSBiID0gKHB5IC0gZ2V0WSgpKSAvIGdldEhlaWdodCgpIC0gMC41OworCisgICAgICAgIHJldHVybiBhICogYSArIGIgKiBiIDwgMC4yNTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHJ3IDw9IDAuMCB8fCByaCA8PSAwLjApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBjeCA9IGdldFgoKSArIGdldFdpZHRoKCkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBjeSA9IGdldFkoKSArIGdldEhlaWdodCgpIC8gMi4wOworCisgICAgICAgIGRvdWJsZSByeDEgPSByeDsKKyAgICAgICAgZG91YmxlIHJ5MSA9IHJ5OworICAgICAgICBkb3VibGUgcngyID0gcnggKyBydzsKKyAgICAgICAgZG91YmxlIHJ5MiA9IHJ5ICsgcmg7CisKKyAgICAgICAgZG91YmxlIG54ID0gY3ggPCByeDEgPyByeDEgOiAoY3ggPiByeDIgPyByeDIgOiBjeCk7CisgICAgICAgIGRvdWJsZSBueSA9IGN5IDwgcnkxID8gcnkxIDogKGN5ID4gcnkyID8gcnkyIDogY3kpOworCisgICAgICAgIHJldHVybiBjb250YWlucyhueCwgbnkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHJ3IDw9IDAuMCB8fCByaCA8PSAwLjApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSByeDEgPSByeDsKKyAgICAgICAgZG91YmxlIHJ5MSA9IHJ5OworICAgICAgICBkb3VibGUgcngyID0gcnggKyBydzsKKyAgICAgICAgZG91YmxlIHJ5MiA9IHJ5ICsgcmg7CisKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHJ4MSwgcnkxKSAmJiBjb250YWlucyhyeDIsIHJ5MSkgJiYgY29udGFpbnMocngyLCByeTIpICYmIGNvbnRhaW5zKHJ4MSwgcnkyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gYXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCBhdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vRmxhdHRlbmluZ1BhdGhJdGVyYXRvci5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vRmxhdHRlbmluZ1BhdGhJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyMDhmMzkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9GbGF0dGVuaW5nUGF0aEl0ZXJhdG9yLmphdmEKQEAgLTAsMCArMSwzNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0Lmdlb207CisKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBDbGFzcyBGbGF0dGVuaW5nUGF0aEl0ZXJhdG9yIHRha2VzIGEgUGF0aEl0ZXJhdG9yIGZvciB0cmF2ZXJzaW5nIGEgY3VydmVkCisgKiBzaGFwZSBhbmQgZmxhdHRlbnMgaXQgYnkgZXN0aW1hdGluZyB0aGUgY3VydmUgYXMgYSBzZXJpZXMgb2YgbGluZSBzZWdtZW50cy4KKyAqIFRoZSBmbGF0dGVuaW5nIGZhY3RvciBpbmRpY2F0ZXMgaG93IGZhciB0aGUgZXN0aW1hdGluZyBsaW5lIHNlZ21lbnRzIGFyZQorICogYWxsb3dlZCB0byBiZSBmcm9tIHRoZSBhY3R1YWwgY3VydmU6IHRoZSBGbGF0dGVuaW5nUGF0aEl0ZXJhdG9yIHdpbGwga2VlcAorICogZGl2aWRpbmcgZWFjaCBjdXJ2ZWQgc2VnbWVudCBpbnRvIHNtYWxsZXIgYW5kIHNtYWxsZXIgZmxhdCBzZWdtZW50cyB1bnRpbAorICogZWl0aGVyIHRoZSBzZWdtZW50cyBhcmUgd2l0aGluIHRoZSBmbGF0dGVuaW5nIGZhY3RvciBvZiB0aGUgY3VydmUgb3IgdW50aWwKKyAqIHRoZSBidWZmZXIgbGltaXQgaXMgcmVhY2hlZC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBGbGF0dGVuaW5nUGF0aEl0ZXJhdG9yIGltcGxlbWVudHMgUGF0aEl0ZXJhdG9yIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IHBvaW50cyBidWZmZXIgc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX1NJWkUgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGN1cnZlIHN1YmRpdmlzaW9uIGxpbWl0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfTElNSVQgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBwb2ludHMgYnVmZmVyIGNhcGFjaXR5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfQ0FQQUNJVFkgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIG9mIGN1cnJlbnQgc2VnbWVudCB0byBiZSBmbGF0LgorICAgICAqLworICAgIGludCBidWZUeXBlOworCisgICAgLyoqCisgICAgICogVGhlIGN1cnZlIHN1YmRpdmlzaW9uIGxpbWl0LgorICAgICAqLworICAgIGludCBidWZMaW1pdDsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50IHBvaW50cyBidWZmZXIgc2l6ZS4KKyAgICAgKi8KKyAgICBpbnQgYnVmU2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBpbm5lciBjdXJzb3IgcG9zaXRpb24gaW4gcG9pbnRzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBpbnQgYnVmSW5kZXg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBzdWJkaXZpc2lvbiBjb3VudC4KKyAgICAgKi8KKyAgICBpbnQgYnVmU3ViZGl2OworCisgICAgLyoqCisgICAgICogVGhlIHBvaW50cyBidWZmZXIuCisgICAgICovCisgICAgZG91YmxlIGJ1ZltdOworCisgICAgLyoqCisgICAgICogVGhlIGluZGljYXRvciBvZiBlbXB0eSBwb2ludHMgYnVmZmVyLgorICAgICAqLworICAgIGJvb2xlYW4gYnVmRW1wdHkgPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIHNvdXJjZSBQYXRoSXRlcmF0b3IuCisgICAgICovCisgICAgUGF0aEl0ZXJhdG9yIHA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZmxhdG5lc3Mgb2YgbmV3IHBhdGguCisgICAgICovCisgICAgZG91YmxlIGZsYXRuZXNzOworCisgICAgLyoqCisgICAgICogVGhlIHNxdWFyZSBvZiBmbGF0bmVzcy4KKyAgICAgKi8KKyAgICBkb3VibGUgZmxhdG5lc3MyOworCisgICAgLyoqCisgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQuCisgICAgICovCisgICAgZG91YmxlIHB4OworCisgICAgLyoqCisgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQuCisgICAgICovCisgICAgZG91YmxlIHB5OworCisgICAgLyoqCisgICAgICogVGhlIHRlbXBvcmFyeSBidWZmZXIgZm9yIGdldHRpbmcgcG9pbnRzIGZyb20gUGF0aEl0ZXJhdG9yLgorICAgICAqLworICAgIGRvdWJsZSBjb29yZHNbXSA9IG5ldyBkb3VibGVbNl07CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZmxhdHRlbmluZyBwYXRoIGl0ZXJhdG9yIGdpdmVuIHRoZSBwYXRoIGl0ZXJhdG9yIGZvciBhCisgICAgICogKHBvc3NpYmx5KSBjdXJ2ZWQgcGF0aCBhbmQgYSBmbGF0dGVuaW5nIGZhY3RvciB3aGljaCBpbmRpY2F0ZXMgaG93IGNsb3NlCisgICAgICogdG9nZXRoZXIgdGhlIHBvaW50cyBvbiB0aGUgY3VydmUgc2hvdWxkIGJlIGNob3Nlbi4gVGhlIGJ1ZmZlciBsaW1pdAorICAgICAqIGRlZmF1bHRzIHRvIDE2IHdoaWNoIG1lYW5zIHRoYXQgZWFjaCBjdXJ2ZSB3aWxsIGJlIGRpdmlkZWQgaW50byBubyBtb3JlCisgICAgICogdGhhbiAxNiBzZWdtZW50cyByZWdhcmRsZXNzIG9mIHRoZSBmbGF0dGVuaW5nIGZhY3Rvci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHBhdGggaXRlcmF0b3Igb2YgdGhlIG9yaWdpbmFsIGN1cnZlLgorICAgICAqIEBwYXJhbSBmbGF0bmVzcworICAgICAqICAgICAgICAgICAgdGhlIGZsYXR0ZW5pbmcgZmFjdG9yIHRoYXQgaW5kaWNhdGVzIGhvdyBmYXIgdGhlIGZsYXQgcGF0aCBpcworICAgICAqICAgICAgICAgICAgYWxsb3dlZCB0byBiZSBmcm9tIHRoZSBhY3R1YWwgY3VydmUgaW4gb3JkZXIgdG8gZGVjaWRlIHdoZW4gdG8KKyAgICAgKiAgICAgICAgICAgIHN0b3AgZGl2aWRpbmcgdGhlIHBhdGggaW50byBzbWFsbGVyIGFuZCBzbWFsbGVyIHNlZ21lbnRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZsYXRuZXNzIGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGF0aCBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBGbGF0dGVuaW5nUGF0aEl0ZXJhdG9yKFBhdGhJdGVyYXRvciBwYXRoLCBkb3VibGUgZmxhdG5lc3MpIHsKKyAgICAgICAgdGhpcyhwYXRoLCBmbGF0bmVzcywgQlVGRkVSX0xJTUlUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZmxhdHRlbmluZyBwYXRoIGl0ZXJhdG9yIGdpdmVuIHRoZSBwYXRoIGl0ZXJhdG9yIGZvciBhCisgICAgICogKHBvc3NpYmx5KSBjdXJ2ZWQgcGF0aCBhbmQgYSBmbGF0dGVuaW5nIGZhY3RvciBhbmQgYSBidWZmZXIgbGltaXQuIFRoZQorICAgICAqIEZsYXR0ZW5pbmdQYXRoSXRlcmF0b3Igd2lsbCBrZWVwIGRpdmlkaW5nIGVhY2ggY3VydmVkIHNlZ21lbnQgaW50bworICAgICAqIHNtYWxsZXIgYW5kIHNtYWxsZXIgZmxhdCBzZWdtZW50cyB1bnRpbCBlaXRoZXIgdGhlIHNlZ21lbnRzIGFyZSB3aXRoaW4KKyAgICAgKiB0aGUgZmxhdHRlbmluZyBmYWN0b3Igb2YgdGhlIGN1cnZlIG9yIHVudGlsIHRoZSBidWZmZXIgbGltaXQgaXMgcmVhY2hlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHBhdGggaXRlcmF0b3Igb2YgdGhlIG9yaWdpbmFsIGN1cnZlLgorICAgICAqIEBwYXJhbSBmbGF0bmVzcworICAgICAqICAgICAgICAgICAgdGhlIGZsYXR0ZW5pbmcgZmFjdG9yIHRoYXQgaW5kaWNhdGVzIGhvdyBmYXIgdGhlIGZsYXQgcGF0aCBpcworICAgICAqICAgICAgICAgICAgYWxsb3dlZCB0byBiZSBmcm9tIHRoZSBhY3R1YWwgY3VydmUgaW4gb3JkZXIgdG8gZGVjaWRlIHdoZW4gdG8KKyAgICAgKiAgICAgICAgICAgIHN0b3AgZGl2aWRpbmcgdGhlIHBhdGggaW50byBzbWFsbGVyIGFuZCBzbWFsbGVyIHNlZ21lbnRzLgorICAgICAqIEBwYXJhbSBsaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGZsYXQgc2VnbWVudHMgdG8gZGl2aWRlIGVhY2ggY3VydmUgaW50by4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmbGF0bmVzcyBvciBsaW1pdCBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhdGggaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmxhdHRlbmluZ1BhdGhJdGVyYXRvcihQYXRoSXRlcmF0b3IgcGF0aCwgZG91YmxlIGZsYXRuZXNzLCBpbnQgbGltaXQpIHsKKyAgICAgICAgaWYgKGZsYXRuZXNzIDwgMC4wKSB7CisgICAgICAgICAgICAvLyBhd3QuMjA2PUZsYXRuZXNzIGlzIGxlc3MgdGhlbiB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIwNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmIChsaW1pdCA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMDc9TGltaXQgaXMgbGVzcyB0aGVuIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjA3IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjIwOD1QYXRoIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMDgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnAgPSBwYXRoOworICAgICAgICB0aGlzLmZsYXRuZXNzID0gZmxhdG5lc3M7CisgICAgICAgIHRoaXMuZmxhdG5lc3MyID0gZmxhdG5lc3MgKiBmbGF0bmVzczsKKyAgICAgICAgdGhpcy5idWZMaW1pdCA9IGxpbWl0OworICAgICAgICB0aGlzLmJ1ZlNpemUgPSBNYXRoLm1pbihidWZMaW1pdCwgQlVGRkVSX1NJWkUpOworICAgICAgICB0aGlzLmJ1ZiA9IG5ldyBkb3VibGVbYnVmU2l6ZV07CisgICAgICAgIHRoaXMuYnVmSW5kZXggPSBidWZTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZsYXR0ZW5pbmcgZmFjdG9yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZsYXR0ZW5pbmcgZmFjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0RmxhdG5lc3MoKSB7CisgICAgICAgIHJldHVybiBmbGF0bmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBzdWJkaXZpc2lvbnMgcGVyIGN1cnZlZCBzZWdtZW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIHN1YmRpdmlzaW9ucyBwZXIgY3VydmVkIHNlZ21lbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZWN1cnNpb25MaW1pdCgpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZkxpbWl0OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgIHJldHVybiBwLmdldFdpbmRpbmdSdWxlKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNEb25lKCkgeworICAgICAgICByZXR1cm4gYnVmRW1wdHkgJiYgcC5pc0RvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIGZsYXQgcGF0aCBwb2ludHMgZm9yIGN1cnJlbnQgc2VnbWVudCBvZiB0aGUgc291cmNlIHNoYXBlLiBMaW5lCisgICAgICogc2VnbWVudCBpcyBmbGF0IGJ5IGl0c2VsZi4gRmxhdG5lc3Mgb2YgcXVhZCBhbmQgY3ViaWMgY3VydmVzIGV2YWx1YXRlZCBieQorICAgICAqIGdldEZsYXRuZXNzU3EoKSBtZXRob2QuIEN1cnZlcyBzdWJkaXZpZGVkIHVudGlsIGN1cnJlbnQgZmxhdG5lc3MgaXMKKyAgICAgKiBiaWdnZXIgdGhhbiB1c2VyIGRlZmluZWQgYW5kIHN1YmRpdmlzaW9uIGxpbWl0IGlzbid0IGV4aGF1c3RlZC4gU2luZ2xlCisgICAgICogc291cmNlIHNlZ21lbnQgdHJhbnNsYXRlZCB0byBzZXJpZXMgb2YgYnVmZmVyIHBvaW50cy4gVGhlIGxlc3MgZmxhdG5lc3MKKyAgICAgKiB0aGUgYmlnZ2VyIHNlcmllcy4gRXZlcnkgY3VycmVudFNlZ21lbnQoKSBjYWxsIGV4dHJhY3Qgb25lIHBvaW50IGZyb20gdGhlCisgICAgICogYnVmZmVyLiBXaGVuIHNlcmllcyBjb21wbGV0ZWQgZXZhbHVhdGUoKSB0YWtlcyBuZXh0IHNvdXJjZSBzaGFwZSBzZWdtZW50LgorICAgICAqLworICAgIHZvaWQgZXZhbHVhdGUoKSB7CisgICAgICAgIGlmIChidWZFbXB0eSkgeworICAgICAgICAgICAgYnVmVHlwZSA9IHAuY3VycmVudFNlZ21lbnQoY29vcmRzKTsKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAoYnVmVHlwZSkgeworICAgICAgICAgICAgY2FzZSBTRUdfTU9WRVRPOgorICAgICAgICAgICAgY2FzZSBTRUdfTElORVRPOgorICAgICAgICAgICAgICAgIHB4ID0gY29vcmRzWzBdOworICAgICAgICAgICAgICAgIHB5ID0gY29vcmRzWzFdOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTRUdfUVVBRFRPOgorICAgICAgICAgICAgICAgIGlmIChidWZFbXB0eSkgeworICAgICAgICAgICAgICAgICAgICBidWZJbmRleCAtPSA2OworICAgICAgICAgICAgICAgICAgICBidWZbYnVmSW5kZXggKyAwXSA9IHB4OworICAgICAgICAgICAgICAgICAgICBidWZbYnVmSW5kZXggKyAxXSA9IHB5OworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvb3JkcywgMCwgYnVmLCBidWZJbmRleCArIDIsIDQpOworICAgICAgICAgICAgICAgICAgICBidWZTdWJkaXYgPSAwOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHdoaWxlIChidWZTdWJkaXYgPCBidWZMaW1pdCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoUXVhZEN1cnZlMkQuZ2V0RmxhdG5lc3NTcShidWYsIGJ1ZkluZGV4KSA8IGZsYXRuZXNzMikgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBSZWFsbG9jIGJ1ZmZlcgorICAgICAgICAgICAgICAgICAgICBpZiAoYnVmSW5kZXggPD0gNCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHRtcFtdID0gbmV3IGRvdWJsZVtidWZTaXplICsgQlVGRkVSX0NBUEFDSVRZXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBidWZJbmRleCwgdG1wLCBidWZJbmRleCArIEJVRkZFUl9DQVBBQ0lUWSwgYnVmU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGJ1ZkluZGV4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiA9IHRtcDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZlNpemUgKz0gQlVGRkVSX0NBUEFDSVRZOworICAgICAgICAgICAgICAgICAgICAgICAgYnVmSW5kZXggKz0gQlVGRkVSX0NBUEFDSVRZOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgUXVhZEN1cnZlMkQuc3ViZGl2aWRlKGJ1ZiwgYnVmSW5kZXgsIGJ1ZiwgYnVmSW5kZXggLSA0LCBidWYsIGJ1ZkluZGV4KTsKKworICAgICAgICAgICAgICAgICAgICBidWZJbmRleCAtPSA0OworICAgICAgICAgICAgICAgICAgICBidWZTdWJkaXYrKzsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBidWZJbmRleCArPSA0OworICAgICAgICAgICAgICAgIHB4ID0gYnVmW2J1ZkluZGV4XTsKKyAgICAgICAgICAgICAgICBweSA9IGJ1ZltidWZJbmRleCArIDFdOworCisgICAgICAgICAgICAgICAgYnVmRW1wdHkgPSAoYnVmSW5kZXggPT0gYnVmU2l6ZSAtIDIpOworICAgICAgICAgICAgICAgIGlmIChidWZFbXB0eSkgeworICAgICAgICAgICAgICAgICAgICBidWZJbmRleCA9IGJ1ZlNpemU7CisgICAgICAgICAgICAgICAgICAgIGJ1ZlR5cGUgPSBTRUdfTElORVRPOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZlN1YmRpdi0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgU0VHX0NVQklDVE86CisgICAgICAgICAgICAgICAgaWYgKGJ1ZkVtcHR5KSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZkluZGV4IC09IDg7CisgICAgICAgICAgICAgICAgICAgIGJ1ZltidWZJbmRleCArIDBdID0gcHg7CisgICAgICAgICAgICAgICAgICAgIGJ1ZltidWZJbmRleCArIDFdID0gcHk7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29vcmRzLCAwLCBidWYsIGJ1ZkluZGV4ICsgMiwgNik7CisgICAgICAgICAgICAgICAgICAgIGJ1ZlN1YmRpdiA9IDA7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgd2hpbGUgKGJ1ZlN1YmRpdiA8IGJ1ZkxpbWl0KSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChDdWJpY0N1cnZlMkQuZ2V0RmxhdG5lc3NTcShidWYsIGJ1ZkluZGV4KSA8IGZsYXRuZXNzMikgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBSZWFsbG9jIGJ1ZmZlcgorICAgICAgICAgICAgICAgICAgICBpZiAoYnVmSW5kZXggPD0gNikgeworICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHRtcFtdID0gbmV3IGRvdWJsZVtidWZTaXplICsgQlVGRkVSX0NBUEFDSVRZXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBidWZJbmRleCwgdG1wLCBidWZJbmRleCArIEJVRkZFUl9DQVBBQ0lUWSwgYnVmU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGJ1ZkluZGV4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiA9IHRtcDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZlNpemUgKz0gQlVGRkVSX0NBUEFDSVRZOworICAgICAgICAgICAgICAgICAgICAgICAgYnVmSW5kZXggKz0gQlVGRkVSX0NBUEFDSVRZOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgQ3ViaWNDdXJ2ZTJELnN1YmRpdmlkZShidWYsIGJ1ZkluZGV4LCBidWYsIGJ1ZkluZGV4IC0gNiwgYnVmLCBidWZJbmRleCk7CisKKyAgICAgICAgICAgICAgICAgICAgYnVmSW5kZXggLT0gNjsKKyAgICAgICAgICAgICAgICAgICAgYnVmU3ViZGl2Kys7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgYnVmSW5kZXggKz0gNjsKKyAgICAgICAgICAgICAgICBweCA9IGJ1ZltidWZJbmRleF07CisgICAgICAgICAgICAgICAgcHkgPSBidWZbYnVmSW5kZXggKyAxXTsKKworICAgICAgICAgICAgICAgIGJ1ZkVtcHR5ID0gKGJ1ZkluZGV4ID09IGJ1ZlNpemUgLSAyKTsKKyAgICAgICAgICAgICAgICBpZiAoYnVmRW1wdHkpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmSW5kZXggPSBidWZTaXplOworICAgICAgICAgICAgICAgICAgICBidWZUeXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBidWZTdWJkaXYtLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG5leHQoKSB7CisgICAgICAgIGlmIChidWZFbXB0eSkgeworICAgICAgICAgICAgcC5uZXh0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGZsb2F0W10gY29vcmRzKSB7CisgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgLy8gYXd0LjRCPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCeCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGV2YWx1YXRlKCk7CisgICAgICAgIGludCB0eXBlID0gYnVmVHlwZTsKKyAgICAgICAgaWYgKHR5cGUgIT0gU0VHX0NMT1NFKSB7CisgICAgICAgICAgICBjb29yZHNbMF0gPSAoZmxvYXQpcHg7CisgICAgICAgICAgICBjb29yZHNbMV0gPSAoZmxvYXQpcHk7CisgICAgICAgICAgICBpZiAodHlwZSAhPSBTRUdfTU9WRVRPKSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19MSU5FVE87CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgcHVibGljIGludCBjdXJyZW50U2VnbWVudChkb3VibGVbXSBjb29yZHMpIHsKKyAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBldmFsdWF0ZSgpOworICAgICAgICBpbnQgdHlwZSA9IGJ1ZlR5cGU7CisgICAgICAgIGlmICh0eXBlICE9IFNFR19DTE9TRSkgeworICAgICAgICAgICAgY29vcmRzWzBdID0gcHg7CisgICAgICAgICAgICBjb29yZHNbMV0gPSBweTsKKyAgICAgICAgICAgIGlmICh0eXBlICE9IFNFR19NT1ZFVE8pIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9HZW5lcmFsUGF0aC5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vR2VuZXJhbFBhdGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNjY5YmM3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vR2VuZXJhbFBhdGguamF2YQpAQCAtMCwwICsxLDYyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQ3Jvc3Npbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIGNsYXNzIEdlbmVyYWxQYXRoIHJlcHJlc2VudHMgYSBzaGFwZSB3aG9zZSBvdXRsaW5lIGlzIGdpdmVuIGJ5IGRpZmZlcmVudAorICogdHlwZXMgb2YgY3VydmVkIGFuZCBzdHJhaWdodCBzZWdtZW50cy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBHZW5lcmFsUGF0aCBpbXBsZW1lbnRzIFNoYXBlLCBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRfRVZFTl9PREQgc2VlIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9FVkVOX09ERH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORF9FVkVOX09ERCA9IFBhdGhJdGVyYXRvci5XSU5EX0VWRU5fT0REOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRfTk9OX1pFUk8gc2VlIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9OT05fWkVST30uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lORF9OT05fWkVSTyA9IFBhdGhJdGVyYXRvci5XSU5EX05PTl9aRVJPOworCisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlcnMgc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX1NJWkUgPSAxMDsKKworICAgIC8qKgorICAgICAqIFRoZSBidWZmZXJzIGNhcGFjaXR5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfQ0FQQUNJVFkgPSAxMDsKKworICAgIC8qKgorICAgICAqIFRoZSBwb2ludCdzIHR5cGVzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBieXRlW10gdHlwZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcG9pbnRzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBmbG9hdFtdIHBvaW50czsKKworICAgIC8qKgorICAgICAqIFRoZSBwb2ludCdzIHR5cGUgYnVmZmVyIHNpemUuCisgICAgICovCisgICAgaW50IHR5cGVTaXplOworCisgICAgLyoqCisgICAgICogVGhlIHBvaW50cyBidWZmZXIgc2l6ZS4KKyAgICAgKi8KKyAgICBpbnQgcG9pbnRTaXplOworCisgICAgLyoqCisgICAgICogVGhlIHBhdGggcnVsZS4KKyAgICAgKi8KKyAgICBpbnQgcnVsZTsKKworICAgIC8qKgorICAgICAqIFRoZSBzcGFjZSBhbW91bnQgaW4gcG9pbnRzIGJ1ZmZlciBmb3IgZGlmZmVyZW50IHNlZ21lbmV0J3MgdHlwZXMuCisgICAgICovCisgICAgc3RhdGljIGludCBwb2ludFNoaWZ0W10gPSB7CisgICAgICAgICAgICAyLCAvLyBNT1ZFVE8KKyAgICAgICAgICAgIDIsIC8vIExJTkVUTworICAgICAgICAgICAgNCwgLy8gUVVBRFRPCisgICAgICAgICAgICA2LCAvLyBDVUJJQ1RPCisgICAgICAgICAgICAwCisgICAgfTsgLy8gQ0xPU0UKKworICAgIC8qCisgICAgICogR2VuZXJhbFBhdGggcGF0aCBpdGVyYXRvcgorICAgICAqLworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBJdGVyYXRvciBpcyB0aGUgc3ViY2xhc3Mgb2YgSXRlcmF0b3IgZm9yIHRyYXZlcnNpbmcgdGhlIG91dGxpbmUKKyAgICAgKiBvZiBhIEdlbmVyYWxQYXRoLgorICAgICAqLworICAgIGNsYXNzIEl0ZXJhdG9yIGltcGxlbWVudHMgUGF0aEl0ZXJhdG9yIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uIGluIHR5cGVzIGJ1ZmZlci4KKyAgICAgICAgICovCisgICAgICAgIGludCB0eXBlSW5kZXg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvbiBpbiBwb2ludHMgYnVmZmVyLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHBvaW50SW5kZXg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzb3VyY2UgR2VuZXJhbFBhdGggb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgR2VuZXJhbFBhdGggcDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBhdGggaXRlcmF0b3IgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBHZW5lcmFsUGF0aC5JdGVyYXRvciBmb3IgZ2l2ZW4gZ2VuZXJhbCBwYXRoLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHBhdGgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc291cmNlIEdlbmVyYWxQYXRoIG9iamVjdC4KKyAgICAgICAgICovCisgICAgICAgIEl0ZXJhdG9yKEdlbmVyYWxQYXRoIHBhdGgpIHsKKyAgICAgICAgICAgIHRoaXMocGF0aCwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBHZW5lcmFsUGF0aC5JdGVyYXRvciBmb3IgZ2l2ZW4gZ2VuZXJhbCBwYXRoIGFuZAorICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBwYXRoCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBHZW5lcmFsUGF0aCBvYmplY3QuCisgICAgICAgICAqIEBwYXJhbSBhdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gb2JqZWN0IHRvIGFwcGx5IHJlY3RhbmdsZSBwYXRoLgorICAgICAgICAgKi8KKyAgICAgICAgSXRlcmF0b3IoR2VuZXJhbFBhdGggcGF0aCwgQWZmaW5lVHJhbnNmb3JtIGF0KSB7CisgICAgICAgICAgICB0aGlzLnAgPSBwYXRoOworICAgICAgICAgICAgdGhpcy50ID0gYXQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFdpbmRpbmdSdWxlKCkgeworICAgICAgICAgICAgcmV0dXJuIHAuZ2V0V2luZGluZ1J1bGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlSW5kZXggPj0gcC50eXBlU2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIG5leHQoKSB7CisgICAgICAgICAgICB0eXBlSW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgdHlwZSA9IHAudHlwZXNbdHlwZUluZGV4XTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IEdlbmVyYWxQYXRoLnBvaW50U2hpZnRbdHlwZV07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBjb29yZHNbaV0gPSBwLnBvaW50c1twb2ludEluZGV4ICsgaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdC50cmFuc2Zvcm0oY29vcmRzLCAwLCBjb29yZHMsIDAsIGNvdW50IC8gMik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb2ludEluZGV4ICs9IGNvdW50OworICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGZsb2F0W10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgdHlwZSA9IHAudHlwZXNbdHlwZUluZGV4XTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IEdlbmVyYWxQYXRoLnBvaW50U2hpZnRbdHlwZV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHAucG9pbnRzLCBwb2ludEluZGV4LCBjb29yZHMsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgY291bnQgLyAyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvaW50SW5kZXggKz0gY291bnQ7CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGdlbmVyYWwgcGF0aCB3aXRoIHRoZSB3aW5kaW5nIHJ1bGUgc2V0IHRvCisgICAgICoge0BsaW5rIFBhdGhJdGVyYXRvciNXSU5EX05PTl9aRVJPfSBhbmQgdGhlIGluaXRpYWwgY2FwYWNpdHkgKG51bWJlciBvZgorICAgICAqIHNlZ21lbnRzKSBzZXQgdG8gdGhlIGRlZmF1bHQgdmFsdWUgMTAuCisgICAgICovCisgICAgcHVibGljIEdlbmVyYWxQYXRoKCkgeworICAgICAgICB0aGlzKFdJTkRfTk9OX1pFUk8sIEJVRkZFUl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZ2VuZXJhbCBwYXRoIHdpdGggdGhlIGdpdmVuIHdpbmRpbmcgcnVsZSBhbmQgdGhlCisgICAgICogaW5pdGlhbCBjYXBhY2l0eSAobnVtYmVyIG9mIHNlZ21lbnRzKSBzZXQgdG8gdGhlIGRlZmF1bHQgdmFsdWUgMTAuCisgICAgICogCisgICAgICogQHBhcmFtIHJ1bGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aW5kaW5nIHJ1bGUsIGVpdGhlciB7QGxpbmsgUGF0aEl0ZXJhdG9yI1dJTkRfRVZFTl9PRER9IG9yCisgICAgICogICAgICAgICAgICB7QGxpbmsgUGF0aEl0ZXJhdG9yI1dJTkRfTk9OX1pFUk99LgorICAgICAqLworICAgIHB1YmxpYyBHZW5lcmFsUGF0aChpbnQgcnVsZSkgeworICAgICAgICB0aGlzKHJ1bGUsIEJVRkZFUl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZ2VuZXJhbCBwYXRoIHdpdGggdGhlIGdpdmVuIHdpbmRpbmcgcnVsZSBhbmQgaW5pdGlhbAorICAgICAqIGNhcGFjaXR5IChudW1iZXIgb2Ygc2VnbWVudHMpLgorICAgICAqIAorICAgICAqIEBwYXJhbSBydWxlCisgICAgICogICAgICAgICAgICB0aGUgd2luZGluZyBydWxlLCBlaXRoZXIge0BsaW5rIFBhdGhJdGVyYXRvciNXSU5EX0VWRU5fT0REfSBvcgorICAgICAqICAgICAgICAgICAge0BsaW5rIFBhdGhJdGVyYXRvciNXSU5EX05PTl9aRVJPfS4KKyAgICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHNlZ21lbnRzIHRoZSBwYXRoIGlzIHNldCB0byBob2xkLgorICAgICAqLworICAgIHB1YmxpYyBHZW5lcmFsUGF0aChpbnQgcnVsZSwgaW50IGluaXRpYWxDYXBhY2l0eSkgeworICAgICAgICBzZXRXaW5kaW5nUnVsZShydWxlKTsKKyAgICAgICAgdHlwZXMgPSBuZXcgYnl0ZVtpbml0aWFsQ2FwYWNpdHldOworICAgICAgICBwb2ludHMgPSBuZXcgZmxvYXRbaW5pdGlhbENhcGFjaXR5ICogMl07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBHZW5lcmFsUGF0aCBmcm9tIHRoZSBvdXRsaW5lIG9mIHRoZSBnaXZlbiBzaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2hhcGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGFwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbFBhdGgoU2hhcGUgc2hhcGUpIHsKKyAgICAgICAgdGhpcyhXSU5EX05PTl9aRVJPLCBCVUZGRVJfU0laRSk7CisgICAgICAgIFBhdGhJdGVyYXRvciBwID0gc2hhcGUuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpOworICAgICAgICBzZXRXaW5kaW5nUnVsZShwLmdldFdpbmRpbmdSdWxlKCkpOworICAgICAgICBhcHBlbmQocCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHdpbmRpbmcgcnVsZSwgd2hpY2ggZGV0ZXJtaW5lcyBob3cgdG8gZGVjaWRlIHdoZXRoZXIgYSBwb2ludAorICAgICAqIHRoYXQgaXNuJ3Qgb24gdGhlIHBhdGggaXRzZWxmIGlzIGluc2lkZSBvciBvdXRzaWRlIG9mIHRoZSBzaGFwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcnVsZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB3aW5kaW5nIHJ1bGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgd2luZGluZyBydWxlIGlzIG5laXRoZXIKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgUGF0aEl0ZXJhdG9yI1dJTkRfRVZFTl9PRER9IG5vcgorICAgICAqICAgICAgICAgICAgIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9OT05fWkVST30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0V2luZGluZ1J1bGUoaW50IHJ1bGUpIHsKKyAgICAgICAgaWYgKHJ1bGUgIT0gV0lORF9FVkVOX09ERCAmJiBydWxlICE9IFdJTkRfTk9OX1pFUk8pIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMDk9SW52YWxpZCB3aW5kaW5nIHJ1bGUgdmFsdWUKKyAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIwOSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHRoaXMucnVsZSA9IHJ1bGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2luZGluZyBydWxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpbmRpbmcgcnVsZSwgZWl0aGVyIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9FVkVOX09ERH0gb3IKKyAgICAgKiAgICAgICAgIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9OT05fWkVST30uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRXaW5kaW5nUnVsZSgpIHsKKyAgICAgICAgcmV0dXJuIHJ1bGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHRoZSBwb2ludCBkYXRhIGJ1ZmZlciBzaXplcyB0byBzZWUgd2hldGhlciBwb2ludENvdW50IGFkZGl0aW9uYWwKKyAgICAgKiBwb2ludC1kYXRhIGVsZW1lbnRzIGNhbiBmaXQuIChOb3RlIHRoYXQgdGhlIG51bWJlciBvZiBwb2ludCBkYXRhIGVsZW1lbnRzCisgICAgICogdG8gYWRkIGlzIG1vcmUgdGhhbiBvbmUgcGVyIHBvaW50IC0tIGl0IGRlcGVuZHMgb24gdGhlIHR5cGUgb2YgcG9pbnQKKyAgICAgKiBiZWluZyBhZGRlZC4pIFJlYWxsb2NhdGVzIHRoZSBidWZmZXJzIHRvIGVubGFyZ2UgdGhlIHNpemUgaWYgbmVjZXNzYXJ5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwb2ludENvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBvaW50IGRhdGEgZWxlbWVudHMgdG8gYmUgYWRkZWQuCisgICAgICogQHBhcmFtIGNoZWNrTW92ZQorICAgICAqICAgICAgICAgICAgd2hldGhlciB0byBjaGVjayBmb3IgZXhpc3RpbmcgcG9pbnRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGNoZWNrTW92ZSBpcyB0cnVlIGFuZCB0aGUgcGF0aCBpcyBjdXJyZW50bHkgZW1wdHkuCisgICAgICovCisgICAgdm9pZCBjaGVja0J1ZihpbnQgcG9pbnRDb3VudCwgYm9vbGVhbiBjaGVja01vdmUpIHsKKyAgICAgICAgaWYgKGNoZWNrTW92ZSAmJiB0eXBlU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjBBPUZpcnN0IHNlZ21lbnQgc2hvdWxkIGJlIFNFR19NT1ZFVE8gdHlwZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxQYXRoU3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjBBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHR5cGVTaXplID09IHR5cGVzLmxlbmd0aCkgeworICAgICAgICAgICAgYnl0ZSB0bXBbXSA9IG5ldyBieXRlW3R5cGVTaXplICsgQlVGRkVSX0NBUEFDSVRZXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodHlwZXMsIDAsIHRtcCwgMCwgdHlwZVNpemUpOworICAgICAgICAgICAgdHlwZXMgPSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvaW50U2l6ZSArIHBvaW50Q291bnQgPiBwb2ludHMubGVuZ3RoKSB7CisgICAgICAgICAgICBmbG9hdCB0bXBbXSA9IG5ldyBmbG9hdFtwb2ludFNpemUgKyBNYXRoLm1heChCVUZGRVJfQ0FQQUNJVFkgKiAyLCBwb2ludENvdW50KV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBvaW50cywgMCwgdG1wLCAwLCBwb2ludFNpemUpOworICAgICAgICAgICAgcG9pbnRzID0gdG1wOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIG5ldyBwb2ludCB0byB0aGUgZW5kIG9mIHRoaXMgZ2VuZXJhbCBwYXRoLCBkaXNjb25uZWN0ZWQgZnJvbQorICAgICAqIHRoZSBleGlzdGluZyBwYXRoLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBuZXh0IHBvaW50IHRvIGFwcGVuZC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCB0byBhcHBlbmQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbW92ZVRvKGZsb2F0IHgsIGZsb2F0IHkpIHsKKyAgICAgICAgaWYgKHR5cGVTaXplID4gMCAmJiB0eXBlc1t0eXBlU2l6ZSAtIDFdID09IFBhdGhJdGVyYXRvci5TRUdfTU9WRVRPKSB7CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplIC0gMl0gPSB4OworICAgICAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSAtIDFdID0geTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNoZWNrQnVmKDIsIGZhbHNlKTsKKyAgICAgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE87CisgICAgICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geDsKKyAgICAgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB5OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIG5ldyBzZWdtZW50IHRvIHRoZSBlbmQgb2YgdGhpcyBnZW5lcmFsIHBhdGggYnkgbWFraW5nIGEKKyAgICAgKiBzdHJhaWdodCBsaW5lIHNlZ21lbnQgZnJvbSB0aGUgY3VycmVudCBlbmRwb2ludCB0byB0aGUgZ2l2ZW4gbmV3IHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBuZXh0IHBvaW50IHRvIGFwcGVuZC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb2ludCB0byBhcHBlbmQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbGluZVRvKGZsb2F0IHgsIGZsb2F0IHkpIHsKKyAgICAgICAgY2hlY2tCdWYoMiwgdHJ1ZSk7CisgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19MSU5FVE87CisgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB4OworICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGEgbmV3IHNlZ21lbnQgdG8gdGhlIGVuZCBvZiB0aGlzIGdlbmVyYWwgcGF0aCBieSBtYWtpbmcgYQorICAgICAqIHF1YWRyYXRpYyBjdXJ2ZSBmcm9tIHRoZSBjdXJyZW50IGVuZHBvaW50IHRvIHRoZSBwb2ludCAoeDIsIHkyKSB1c2luZyB0aGUKKyAgICAgKiBwb2ludCAoeDEsIHkxKSBhcyB0aGUgcXVhZHJhdGljIGN1cnZlJ3MgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHF1YWRyYXRpYyBjdXJ2ZSdzIGNvbnRyb2wgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBxdWFkcmF0aWMgY3VydmUncyBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcXVhZHJhdGljIGN1cnZlJ3MgZW5kIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcXVhZHJhdGljIGN1cnZlJ3MgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHF1YWRUbyhmbG9hdCB4MSwgZmxvYXQgeTEsIGZsb2F0IHgyLCBmbG9hdCB5MikgeworICAgICAgICBjaGVja0J1Zig0LCB0cnVlKTsKKyAgICAgICAgdHlwZXNbdHlwZVNpemUrK10gPSBQYXRoSXRlcmF0b3IuU0VHX1FVQURUTzsKKyAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHgxOworICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geTE7CisgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB4MjsKKyAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHkyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgYSBuZXcgc2VnbWVudCB0byB0aGUgZW5kIG9mIHRoaXMgZ2VuZXJhbCBwYXRoIGJ5IG1ha2luZyBhIGN1YmljCisgICAgICogY3VydmUgZnJvbSB0aGUgY3VycmVudCBlbmRwb2ludCB0byB0aGUgcG9pbnQgKHgzLCB5MykgdXNpbmcgKHgxLCB5MSkgYW5kCisgICAgICogKHgyLCB5MikgYXMgY29udHJvbCBwb2ludHMuCisgICAgICogCisgICAgICogQHNlZSBqYXZhLmF3dC5nZW9tLkN1YmljQ3VydmUyRAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgbmV3IGN1YmljIHNlZ21lbnQncyBmaXJzdCBjb250cm9sCisgICAgICogICAgICAgICAgICBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBjdWJpYyBzZWdtZW50J3MgZmlyc3QgY29udHJvbAorICAgICAqICAgICAgICAgICAgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBuZXcgY3ViaWMgc2VnbWVudCdzIHNlY29uZCBjb250cm9sCisgICAgICogICAgICAgICAgICBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBjdWJpYyBzZWdtZW50J3Mgc2Vjb25kIGNvbnRyb2wKKyAgICAgKiAgICAgICAgICAgIHBvaW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgbmV3IGN1YmljIHNlZ21lbnQncyBlbmQgcG9pbnQuCisgICAgICogQHBhcmFtIHkzCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBuZXcgY3ViaWMgc2VnbWVudCdzIGVuZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjdXJ2ZVRvKGZsb2F0IHgxLCBmbG9hdCB5MSwgZmxvYXQgeDIsIGZsb2F0IHkyLCBmbG9hdCB4MywgZmxvYXQgeTMpIHsKKyAgICAgICAgY2hlY2tCdWYoNiwgdHJ1ZSk7CisgICAgICAgIHR5cGVzW3R5cGVTaXplKytdID0gUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOworICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geDE7CisgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB5MTsKKyAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHgyOworICAgICAgICBwb2ludHNbcG9pbnRTaXplKytdID0geTI7CisgICAgICAgIHBvaW50c1twb2ludFNpemUrK10gPSB4MzsKKyAgICAgICAgcG9pbnRzW3BvaW50U2l6ZSsrXSA9IHkzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHR5cGUgaW5mb3JtYXRpb24gdG8gZGVjbGFyZSB0aGF0IHRoZSBjdXJyZW50IGVuZHBvaW50IGNsb3NlcworICAgICAqIHRoZSBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZVBhdGgoKSB7CisgICAgICAgIGlmICh0eXBlU2l6ZSA9PSAwIHx8IHR5cGVzW3R5cGVTaXplIC0gMV0gIT0gUGF0aEl0ZXJhdG9yLlNFR19DTE9TRSkgeworICAgICAgICAgICAgY2hlY2tCdWYoMCwgdHJ1ZSk7CisgICAgICAgICAgICB0eXBlc1t0eXBlU2l6ZSsrXSA9IFBhdGhJdGVyYXRvci5TRUdfQ0xPU0U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBvdXRsaW5lIG9mIHRoZSBzcGVjaWZpZWQgc2hhcGUgb250byB0aGUgZW5kIG9mIHRoaXMKKyAgICAgKiBHZW5lcmFsUGF0aC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2hhcGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaGFwZSB3aG9zZSBvdXRsaW5lIGlzIHRvIGJlIGFwcGVuZGVkLgorICAgICAqIEBwYXJhbSBjb25uZWN0CisgICAgICogICAgICAgICAgICB0cnVlIHRvIGNvbm5lY3QgdGhpcyBwYXRoJ3MgY3VycmVudCBlbmRwb2ludCB0byB0aGUgZmlyc3QKKyAgICAgKiAgICAgICAgICAgIHBvaW50IG9mIHRoZSBzaGFwZSdzIG91dGxpbmUgb3IgZmFsc2UgdG8gYXBwZW5kIHRoZSBzaGFwZSdzCisgICAgICogICAgICAgICAgICBvdXRsaW5lIHdpdGhvdXQgY29ubmVjdGluZyBpdC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNoYXBlIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZChTaGFwZSBzaGFwZSwgYm9vbGVhbiBjb25uZWN0KSB7CisgICAgICAgIFBhdGhJdGVyYXRvciBwID0gc2hhcGUuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpOworICAgICAgICBhcHBlbmQocCwgY29ubmVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgcGF0aCBkZWZpbmVkIGJ5IHRoZSBzcGVjaWZpZWQgUGF0aEl0ZXJhdG9yIG9udG8gdGhlIGVuZCBvZgorICAgICAqIHRoaXMgR2VuZXJhbFBhdGguCisgICAgICogCisgICAgICogQHBhcmFtIHBhdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBQYXRoSXRlcmF0b3IgdGhhdCBkZWZpbmVzIHRoZSBuZXcgcGF0aCB0byBhcHBlbmQuCisgICAgICogQHBhcmFtIGNvbm5lY3QKKyAgICAgKiAgICAgICAgICAgIHRydWUgdG8gY29ubmVjdCB0aGlzIHBhdGgncyBjdXJyZW50IGVuZHBvaW50IHRvIHRoZSBmaXJzdAorICAgICAqICAgICAgICAgICAgcG9pbnQgb2YgdGhlIHNoYXBlJ3Mgb3V0bGluZSBvciBmYWxzZSB0byBhcHBlbmQgdGhlIHNoYXBlJ3MKKyAgICAgKiAgICAgICAgICAgIG91dGxpbmUgd2l0aG91dCBjb25uZWN0aW5nIGl0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZChQYXRoSXRlcmF0b3IgcGF0aCwgYm9vbGVhbiBjb25uZWN0KSB7CisgICAgICAgIHdoaWxlICghcGF0aC5pc0RvbmUoKSkgeworICAgICAgICAgICAgZmxvYXQgY29vcmRzW10gPSBuZXcgZmxvYXRbNl07CisgICAgICAgICAgICBzd2l0Y2ggKHBhdGguY3VycmVudFNlZ21lbnQoY29vcmRzKSkgeworICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE86CisgICAgICAgICAgICAgICAgICAgIGlmICghY29ubmVjdCB8fCB0eXBlU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtb3ZlVG8oY29vcmRzWzBdLCBjb29yZHNbMV0pOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVzW3R5cGVTaXplIC0gMV0gIT0gUGF0aEl0ZXJhdG9yLlNFR19DTE9TRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHBvaW50c1twb2ludFNpemUgLSAyXSA9PSBjb29yZHNbMF0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBwb2ludHNbcG9pbnRTaXplIC0gMV0gPT0gY29vcmRzWzFdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyBOTyBCUkVBSzsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTElORVRPOgorICAgICAgICAgICAgICAgICAgICBsaW5lVG8oY29vcmRzWzBdLCBjb29yZHNbMV0pOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfUVVBRFRPOgorICAgICAgICAgICAgICAgICAgICBxdWFkVG8oY29vcmRzWzBdLCBjb29yZHNbMV0sIGNvb3Jkc1syXSwgY29vcmRzWzNdKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0NVQklDVE86CisgICAgICAgICAgICAgICAgICAgIGN1cnZlVG8oY29vcmRzWzBdLCBjb29yZHNbMV0sIGNvb3Jkc1syXSwgY29vcmRzWzNdLCBjb29yZHNbNF0sIGNvb3Jkc1s1XSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DTE9TRToKKyAgICAgICAgICAgICAgICAgICAgY2xvc2VQYXRoKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcGF0aC5uZXh0KCk7CisgICAgICAgICAgICBjb25uZWN0ID0gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGVuZCBwb2ludCBvZiB0aGUgcGF0aC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGVuZCBwb2ludCBvZiB0aGUgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnQyRCBnZXRDdXJyZW50UG9pbnQoKSB7CisgICAgICAgIGlmICh0eXBlU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQgaiA9IHBvaW50U2l6ZSAtIDI7CisgICAgICAgIGlmICh0eXBlc1t0eXBlU2l6ZSAtIDFdID09IFBhdGhJdGVyYXRvci5TRUdfQ0xPU0UpIHsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHR5cGVTaXplIC0gMjsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgICAgIGludCB0eXBlID0gdHlwZXNbaV07CisgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE8pIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGogLT0gcG9pbnRTaGlmdFt0eXBlXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRmxvYXQocG9pbnRzW2pdLCBwb2ludHNbaiArIDFdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIEdlbmVyYWxQYXRoIHRvIGJlaW5nIGFuIGVtcHR5IHBhdGguIFRoZSB1bmRlcmx5aW5nIHBvaW50IGFuZAorICAgICAqIHNlZ21lbnQgZGF0YSBpcyBub3QgZGVsZXRlZCBidXQgcmF0aGVyIHRoZSBlbmQgaW5kaWNlcyBvZiB0aGUgZGF0YSBhcnJheXMKKyAgICAgKiBhcmUgc2V0IHRvIHplcm8uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIHR5cGVTaXplID0gMDsKKyAgICAgICAgcG9pbnRTaXplID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2Zvcm0gYWxsIG9mIHRoZSBjb29yZGluYXRlcyBvZiB0aGlzIHBhdGggYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSB0KSB7CisgICAgICAgIHQudHJhbnNmb3JtKHBvaW50cywgMCwgcG9pbnRzLCAwLCBwb2ludFNpemUgLyAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEdlbmVyYWxQYXRoIHdob3NlIGRhdGEgaXMgZ2l2ZW4gYnkgdGhpcyBwYXRoJ3MgZGF0YQorICAgICAqIHRyYW5zZm9ybWVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgR2VuZXJhbFBhdGggd2hvc2UgZGF0YSBpcyBnaXZlbiBieSB0aGlzIHBhdGgncyBkYXRhCisgICAgICogICAgICAgICB0cmFuc2Zvcm1lZCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGNyZWF0ZVRyYW5zZm9ybWVkU2hhcGUoQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgR2VuZXJhbFBhdGggcCA9IChHZW5lcmFsUGF0aCljbG9uZSgpOworICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICBwLnRyYW5zZm9ybSh0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgIGZsb2F0IHJ4MSwgcnkxLCByeDIsIHJ5MjsKKyAgICAgICAgaWYgKHBvaW50U2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByeDEgPSByeTEgPSByeDIgPSByeTIgPSAwLjBmOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGkgPSBwb2ludFNpemUgLSAxOworICAgICAgICAgICAgcnkxID0gcnkyID0gcG9pbnRzW2ktLV07CisgICAgICAgICAgICByeDEgPSByeDIgPSBwb2ludHNbaS0tXTsKKyAgICAgICAgICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICAgICAgICAgIGZsb2F0IHkgPSBwb2ludHNbaS0tXTsKKyAgICAgICAgICAgICAgICBmbG9hdCB4ID0gcG9pbnRzW2ktLV07CisgICAgICAgICAgICAgICAgaWYgKHggPCByeDEpIHsKKyAgICAgICAgICAgICAgICAgICAgcngxID0geDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHggPiByeDIpIHsKKyAgICAgICAgICAgICAgICAgICAgcngyID0geDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHkgPCByeTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcnkxID0geTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHkgPiByeTIpIHsKKyAgICAgICAgICAgICAgICAgICAgcnkyID0geTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5GbG9hdChyeDEsIHJ5MSwgcngyIC0gcngxLCByeTIgLSByeTEpOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICByZXR1cm4gZ2V0Qm91bmRzMkQoKS5nZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhlIGNyb3NzIGNvdW50IChudW1iZXIgb2YgdGltZXMgYSByYXkgZnJvbSB0aGUgcG9pbnQgY3Jvc3NlcyB0aGUKKyAgICAgKiBzaGFwZSdzIGJvdW5kYXJ5KSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbnVtYmVyIG9mIGNyb3NzaW5ncworICAgICAqIGNvcnJlc3BvbmRzIHRvIGEgcG9pbnQgaW5zaWRlIHRoZSBzaGFwZSBvciBub3QgKGFjY29yZGluZyB0byB0aGUgc2hhcGUncworICAgICAqIHBhdGggcnVsZSkuCisgICAgICogCisgICAgICogQHBhcmFtIGNyb3NzCisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQncyBjcm9zcyBjb3VudC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHBvaW50IGlzIGluc2lkZSB0aGUgcGF0aCwgb3IgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIGJvb2xlYW4gaXNJbnNpZGUoaW50IGNyb3NzKSB7CisgICAgICAgIGlmIChydWxlID09IFdJTkRfTk9OX1pFUk8pIHsKKyAgICAgICAgICAgIHJldHVybiBDcm9zc2luZy5pc0luc2lkZU5vblplcm8oY3Jvc3MpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDcm9zc2luZy5pc0luc2lkZUV2ZW5PZGQoY3Jvc3MpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBpc0luc2lkZShDcm9zc2luZy5jcm9zc1NoYXBlKHRoaXMsIHB4LCBweSkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpbnQgY3Jvc3MgPSBDcm9zc2luZy5pbnRlcnNlY3RTaGFwZSh0aGlzLCByeCwgcnksIHJ3LCByaCk7CisgICAgICAgIHJldHVybiBjcm9zcyAhPSBDcm9zc2luZy5DUk9TU0lORyAmJiBpc0luc2lkZShjcm9zcyk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhkb3VibGUgcngsIGRvdWJsZSByeSwgZG91YmxlIHJ3LCBkb3VibGUgcmgpIHsKKyAgICAgICAgaW50IGNyb3NzID0gQ3Jvc3NpbmcuaW50ZXJzZWN0U2hhcGUodGhpcywgcngsIHJ5LCBydywgcmgpOworICAgICAgICByZXR1cm4gY3Jvc3MgPT0gQ3Jvc3NpbmcuQ1JPU1NJTkcgfHwgaXNJbnNpZGUoY3Jvc3MpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFBvaW50MkQgcCkgeworICAgICAgICByZXR1cm4gY29udGFpbnMocC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhSZWN0YW5nbGUyRCByKSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhyLmdldFgoKSwgci5nZXRZKCksIHIuZ2V0V2lkdGgoKSwgci5nZXRIZWlnaHQoKSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhSZWN0YW5nbGUyRCByKSB7CisgICAgICAgIHJldHVybiBpbnRlcnNlY3RzKHIuZ2V0WCgpLCByLmdldFkoKSwgci5nZXRXaWR0aCgpLCByLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKHRoaXMsIHQpOworICAgIH0KKworICAgIHB1YmxpYyBQYXRoSXRlcmF0b3IgZ2V0UGF0aEl0ZXJhdG9yKEFmZmluZVRyYW5zZm9ybSB0LCBkb3VibGUgZmxhdG5lc3MpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGbGF0dGVuaW5nUGF0aEl0ZXJhdG9yKGdldFBhdGhJdGVyYXRvcih0KSwgZmxhdG5lc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBHZW5lcmFsUGF0aCBwID0gKEdlbmVyYWxQYXRoKXN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBwLnR5cGVzID0gdHlwZXMuY2xvbmUoKTsKKyAgICAgICAgICAgIHAucG9pbnRzID0gcG9pbnRzLmNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1MGJhMjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9JbGxlZ2FsUGF0aFN0YXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworLyoqCisgKiBUaGUgQ2xhc3MgSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbiBpbmRpY2F0ZXMgZXJyb3JzIHdoZXJlIHRoZSBjdXJyZW50IHN0YXRlCisgKiBvZiBhIHBhdGggb2JqZWN0IGlzIGluY29tcGF0aWJsZSB3aXRoIHRoZSBkZXNpcmVkIGFjdGlvbiwgc3VjaCBhcyBwZXJmb3JtaW5nCisgKiBub24tdHJpdmlhbCBhY3Rpb25zIG9uIGFuIGVtcHR5IHBhdGguCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUxNTgwODQyMDUyMjA0ODEwOTRMOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGlsbGVnYWwgcGF0aCBzdGF0ZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxQYXRoU3RhdGVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGlsbGVnYWwgcGF0aCBzdGF0ZSBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbAorICAgICAqIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWxzIG9mIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbFBhdGhTdGF0ZUV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgICAgICBzdXBlcihzKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9nZW9tL0xpbmUyRC5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vTGluZTJELmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNkNTFiNgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9nZW9tL0xpbmUyRC5qYXZhCkBAIC0wLDAgKzEsOTQ4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIExpbmUyRCByZXByZXNlbnRzIGEgbGluZSB3aG9zZSBkYXRhIGlzIGdpdmVuIGluIGhpZ2gtcHJlY2lzaW9uCisgKiB2YWx1ZXMgYXBwcm9wcmlhdGUgZm9yIGdyYXBoaWNhbCBvcGVyYXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIExpbmUyRCBpbXBsZW1lbnRzIFNoYXBlLCBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEZsb2F0IGlzIHRoZSBzdWJjbGFzcyBvZiBMaW5lMkQgdGhhdCBoYXMgYWxsIG9mIGl0cyBkYXRhIHZhbHVlcworICAgICAqIHN0b3JlZCB3aXRoIGZsb2F0LWxldmVsIHByZWNpc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZsb2F0IGV4dGVuZHMgTGluZTJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgeDE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHkxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgeDI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB5MjsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZsb2F0LXZhbHVlZCBMaW5lMkQgd2l0aCBpdHMgZGF0YSB2YWx1ZXMgc2V0IHRvCisgICAgICAgICAqIHplcm8uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZsb2F0LXZhbHVlZCBMaW5lMkQgd2l0aCB0aGUgc3BlY2lmaWVkIGVuZHBvaW50cy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geTEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIHgyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geTIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoZmxvYXQgeDEsIGZsb2F0IHkxLCBmbG9hdCB4MiwgZmxvYXQgeTIpIHsKKyAgICAgICAgICAgIHNldExpbmUoeDEsIHkxLCB4MiwgeTIpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgTGluZTJEIHdpdGggdGhlIHNwZWNpZmllZCBlbmRwb2ludHMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gcDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSBwMgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoUG9pbnQyRCBwMSwgUG9pbnQyRCBwMikgeworICAgICAgICAgICAgc2V0TGluZShwMSwgcDIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WDEoKSB7CisgICAgICAgICAgICByZXR1cm4geDE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZMSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgyKCkgeworICAgICAgICAgICAgcmV0dXJuIHgyOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WTIoKSB7CisgICAgICAgICAgICByZXR1cm4geTI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0UDEoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRmxvYXQoeDEsIHkxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRQMigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9pbnQyRC5GbG9hdCh4MiwgeTIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldExpbmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgICAgICB0aGlzLngxID0gKGZsb2F0KXgxOworICAgICAgICAgICAgdGhpcy55MSA9IChmbG9hdCl5MTsKKyAgICAgICAgICAgIHRoaXMueDIgPSAoZmxvYXQpeDI7CisgICAgICAgICAgICB0aGlzLnkyID0gKGZsb2F0KXkyOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIGRhdGEgdmFsdWVzIHRoYXQgZGVmaW5lIHRoZSBsaW5lLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB5MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHNldExpbmUoZmxvYXQgeDEsIGZsb2F0IHkxLCBmbG9hdCB4MiwgZmxvYXQgeTIpIHsKKyAgICAgICAgICAgIHRoaXMueDEgPSB4MTsKKyAgICAgICAgICAgIHRoaXMueTEgPSB5MTsKKyAgICAgICAgICAgIHRoaXMueDIgPSB4MjsKKyAgICAgICAgICAgIHRoaXMueTIgPSB5MjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgICAgIGZsb2F0IHJ4LCByeSwgcncsIHJoOworICAgICAgICAgICAgaWYgKHgxIDwgeDIpIHsKKyAgICAgICAgICAgICAgICByeCA9IHgxOworICAgICAgICAgICAgICAgIHJ3ID0geDIgLSB4MTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcnggPSB4MjsKKyAgICAgICAgICAgICAgICBydyA9IHgxIC0geDI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoeTEgPCB5MikgeworICAgICAgICAgICAgICAgIHJ5ID0geTE7CisgICAgICAgICAgICAgICAgcmggPSB5MiAtIHkxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByeSA9IHkyOworICAgICAgICAgICAgICAgIHJoID0geTEgLSB5MjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQocngsIHJ5LCBydywgcmgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIERvdWJsZSBpcyB0aGUgc3ViY2xhc3Mgb2YgTGluZTJEIHRoYXQgaGFzIGFsbCBvZiBpdHMgZGF0YQorICAgICAqIHZhbHVlcyBzdG9yZWQgd2l0aCBkb3VibGUtbGV2ZWwgcHJlY2lzaW9uLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRG91YmxlIGV4dGVuZHMgTGluZTJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHgxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeTI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkb3VibGUtdmFsdWVkIExpbmUyRCB3aXRoIGl0cyBkYXRhIHZhbHVlcyBzZXQgdG8KKyAgICAgICAgICogemVyby4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgTGluZTJEIHdpdGggdGhlIHNwZWNpZmllZCBlbmRwb2ludHMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geDEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIHkxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICAgICAqIEBwYXJhbSB4MgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgICAgICogQHBhcmFtIHkyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgICAgIHNldExpbmUoeDEsIHkxLCB4MiwgeTIpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkb3VibGUtdmFsdWVkIExpbmUyRCB3aXRoIHRoZSBzcGVjaWZpZWQgZW5kcG9pbnRzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHAxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gcDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZW5kIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShQb2ludDJEIHAxLCBQb2ludDJEIHAyKSB7CisgICAgICAgICAgICBzZXRMaW5lKHAxLCBwMik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYMSgpIHsKKyAgICAgICAgICAgIHJldHVybiB4MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkxKCkgeworICAgICAgICAgICAgcmV0dXJuIHkxOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WDIoKSB7CisgICAgICAgICAgICByZXR1cm4geDI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZMigpIHsKKyAgICAgICAgICAgIHJldHVybiB5MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRQMSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9pbnQyRC5Eb3VibGUoeDEsIHkxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRQMigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9pbnQyRC5Eb3VibGUoeDIsIHkyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRMaW5lKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICAgICAgdGhpcy54MSA9IHgxOworICAgICAgICAgICAgdGhpcy55MSA9IHkxOworICAgICAgICAgICAgdGhpcy54MiA9IHgyOworICAgICAgICAgICAgdGhpcy55MiA9IHkyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICAgICAgZG91YmxlIHJ4LCByeSwgcncsIHJoOworICAgICAgICAgICAgaWYgKHgxIDwgeDIpIHsKKyAgICAgICAgICAgICAgICByeCA9IHgxOworICAgICAgICAgICAgICAgIHJ3ID0geDIgLSB4MTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcnggPSB4MjsKKyAgICAgICAgICAgICAgICBydyA9IHgxIC0geDI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoeTEgPCB5MikgeworICAgICAgICAgICAgICAgIHJ5ID0geTE7CisgICAgICAgICAgICAgICAgcmggPSB5MiAtIHkxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByeSA9IHkyOworICAgICAgICAgICAgICAgIHJoID0geTEgLSB5MjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKHJ4LCByeSwgcncsIHJoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogTGluZTJEIHBhdGggaXRlcmF0b3IKKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgc3ViY2xhc3Mgb2YgUGF0aEl0ZXJhdG9yIHRvIHRyYXZlcnNlIGEgTGluZTJELgorICAgICAqLworICAgIGNsYXNzIEl0ZXJhdG9yIGltcGxlbWVudHMgUGF0aEl0ZXJhdG9yIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnQgbGluZSBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSB4MTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnQgbGluZSBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSB5MTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIGxpbmUgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgeDI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBsaW5lIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcGF0aCBpdGVyYXRvciB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY3VycmVudCBzZWdtZW50IGluZGV4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IExpbmUyRC5JdGVyYXRvciBmb3IgZ2l2ZW4gbGluZSBhbmQgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgTGluZTJEIG9iamVjdC4KKyAgICAgICAgICogQHBhcmFtIGF0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybSBvYmplY3QgdG8gYXBwbHkgcmVjdGFuZ2xlIHBhdGguCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcihMaW5lMkQgbCwgQWZmaW5lVHJhbnNmb3JtIGF0KSB7CisgICAgICAgICAgICB0aGlzLngxID0gbC5nZXRYMSgpOworICAgICAgICAgICAgdGhpcy55MSA9IGwuZ2V0WTEoKTsKKyAgICAgICAgICAgIHRoaXMueDIgPSBsLmdldFgyKCk7CisgICAgICAgICAgICB0aGlzLnkyID0gbC5nZXRZMigpOworICAgICAgICAgICAgdGhpcy50ID0gYXQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFdpbmRpbmdSdWxlKCkgeworICAgICAgICAgICAgcmV0dXJuIFdJTkRfTk9OX1pFUk87CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXggPiAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbmV4dCgpIHsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGRvdWJsZVtdIGNvb3JkcykgeworICAgICAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjRCPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IHgxOworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHkxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSB4MjsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSB5MjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZmxvYXRbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC40Qj1JdGVyYXRvciBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCB0eXBlOworICAgICAgICAgICAgaWYgKGluZGV4ID09IDApIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX01PVkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSAoZmxvYXQpeDE7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KXkxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSAoZmxvYXQpeDI7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KXkyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTGluZTJELgorICAgICAqLworICAgIHByb3RlY3RlZCBMaW5lMkQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WDEoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFkxKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4Mi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFgyKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFkyKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBwIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUG9pbnQyRCBnZXRQMSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcCBlbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcCBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFBvaW50MkQgZ2V0UDIoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxpbmUncyBlbmRwb2ludHMuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldExpbmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxpbmUncyBlbmRwb2ludHMuCisgICAgICogCisgICAgICogQHBhcmFtIHAxCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogQHBhcmFtIHAyCisgICAgICogICAgICAgICAgICB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExpbmUoUG9pbnQyRCBwMSwgUG9pbnQyRCBwMikgeworICAgICAgICBzZXRMaW5lKHAxLmdldFgoKSwgcDEuZ2V0WSgpLCBwMi5nZXRYKCksIHAyLmdldFkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGluZSdzIGVuZHBvaW50cyBieSBjb3B5aW5nIHRoZSBkYXRhIGZyb20gYW5vdGhlciBMaW5lMkQuCisgICAgICogCisgICAgICogQHBhcmFtIGxpbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBMaW5lMkQgdG8gY29weSB0aGUgZW5kcG9pbnQgZGF0YSBmcm9tLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExpbmUoTGluZTJEIGxpbmUpIHsKKyAgICAgICAgc2V0TGluZShsaW5lLmdldFgxKCksIGxpbmUuZ2V0WTEoKSwgbGluZS5nZXRYMigpLCBsaW5lLmdldFkyKCkpOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICByZXR1cm4gZ2V0Qm91bmRzMkQoKS5nZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWxscyB3aGVyZSB0aGUgcG9pbnQgaXMgd2l0aCByZXNwZWN0IHRvIHRoZSBsaW5lIHNlZ21lbnQsIGdpdmVuIHRoZQorICAgICAqIG9yaWVudGF0aW9uIG9mIHRoZSBsaW5lIHNlZ21lbnQuIElmIHRoZSByYXkgZm91bmQgYnkgZXh0ZW5kaW5nIHRoZSBsaW5lCisgICAgICogc2VnbWVudCBmcm9tIGl0cyBzdGFydGluZyBwb2ludCBpcyByb3RhdGVkLCB0aGlzIG1ldGhvZCB0ZWxscyB3aGV0aGVyIHRoZQorICAgICAqIHJheSBzaG91bGQgcm90YXRlIGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbiBvciBhIGNvdW50ZXItY2xvY2t3aXNlCisgICAgICogZGlyZWN0aW9uIHRvIGhpdCB0aGUgcG9pbnQgZmlyc3QuIFRoZSByZXR1cm4gdmFsdWUgaXMgMCBpZiB0aGUgcG9pbnQgaXMKKyAgICAgKiBvbiB0aGUgbGluZSBzZWdtZW50LCBpdCdzIDEgaWYgdGhlIHBvaW50IGlzIG9uIHRoZSByYXkgb3IgaWYgdGhlIHJheQorICAgICAqIHNob3VsZCByb3RhdGUgaW4gYSBjb3VudGVyLWNsb2Nrd2lzZSBkaXJlY3Rpb24gdG8gZ2V0IHRvIHRoZSBwb2ludCwgYW5kCisgICAgICogaXQncyAtMSBpZiB0aGUgcmF5IHNob3VsZCByb3RhdGUgaW4gYSBjbG9ja3dpc2UgZGlyZWN0aW9uIHRvIGdldCB0byB0aGUKKyAgICAgKiBwb2ludCBvciBpZiB0aGUgcG9pbnQgaXMgb24gdGhlIGxpbmUgZGV0ZXJtaW5lZCBieSB0aGUgbGluZSBzZWdtZW50IGJ1dAorICAgICAqIG5vdCBvbiB0aGUgcmF5IGZyb20gdGhlIHNlZ21lbnQncyBzdGFydGluZyBwb2ludCBhbmQgdGhyb3VnaCBpdHMgZW5kCisgICAgICogcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHAgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSB0aGF0IGRlc2NyaWJlcyB3aGVyZSB0aGUgcG9pbnQgaXMgd2l0aCByZXNwZWN0IHRvIHRoZQorICAgICAqICAgICAgICAgbGluZSBzZWdtZW50LCBnaXZlbiB0aGUgb3JpZW50YXRpb24gb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByZWxhdGl2ZUNDVyhkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIC8qCisgICAgICAgICAqIEEgPSAoeDIteDEsIHkyLXkxKSBQID0gKHB4LXgxLCBweS15MSkKKyAgICAgICAgICovCisgICAgICAgIHgyIC09IHgxOworICAgICAgICB5MiAtPSB5MTsKKyAgICAgICAgcHggLT0geDE7CisgICAgICAgIHB5IC09IHkxOworICAgICAgICBkb3VibGUgdCA9IHB4ICogeTIgLSBweSAqIHgyOyAvLyBQeEEKKyAgICAgICAgaWYgKHQgPT0gMC4wKSB7CisgICAgICAgICAgICB0ID0gcHggKiB4MiArIHB5ICogeTI7IC8vIFAqQQorICAgICAgICAgICAgaWYgKHQgPiAwLjApIHsKKyAgICAgICAgICAgICAgICBweCAtPSB4MjsgLy8gQi1BCisgICAgICAgICAgICAgICAgcHkgLT0geTI7CisgICAgICAgICAgICAgICAgdCA9IHB4ICogeDIgKyBweSAqIHkyOyAvLyAoUC1BKSpBCisgICAgICAgICAgICAgICAgaWYgKHQgPCAwLjApIHsKKyAgICAgICAgICAgICAgICAgICAgdCA9IDAuMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdCA8IDAuMCA/IC0xIDogKHQgPiAwLjAgPyAxIDogMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVsbHMgd2hlcmUgdGhlIHBvaW50IGlzIHdpdGggcmVzcGVjdCB0byB0aGlzIGxpbmUgc2VnbWVudCwgZ2l2ZW4gdGhlCisgICAgICogb3JpZW50YXRpb24gb2YgdGhpcyBsaW5lIHNlZ21lbnQuIElmIHRoZSByYXkgZm91bmQgYnkgZXh0ZW5kaW5nIHRoZSBsaW5lCisgICAgICogc2VnbWVudCBmcm9tIGl0cyBzdGFydGluZyBwb2ludCBpcyByb3RhdGVkLCB0aGlzIG1ldGhvZCB0ZWxscyB3aGV0aGVyIHRoZQorICAgICAqIHJheSBzaG91bGQgcm90YXRlIGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbiBvciBhIGNvdW50ZXItY2xvY2t3aXNlCisgICAgICogZGlyZWN0aW9uIHRvIGhpdCB0aGUgcG9pbnQgZmlyc3QuIFRoZSByZXR1cm4gdmFsdWUgaXMgMCBpZiB0aGUgcG9pbnQgaXMKKyAgICAgKiBvbiB0aGUgbGluZSBzZWdtZW50LCBpdCdzIDEgaWYgdGhlIHBvaW50IGlzIG9uIHRoZSByYXkgb3IgaWYgdGhlIHJheQorICAgICAqIHNob3VsZCByb3RhdGUgaW4gYSBjb3VudGVyLWNsb2Nrd2lzZSBkaXJlY3Rpb24gdG8gZ2V0IHRvIHRoZSBwb2ludCwgYW5kCisgICAgICogaXQncyAtMSBpZiB0aGUgcmF5IHNob3VsZCByb3RhdGUgaW4gYSBjbG9ja3dpc2UgZGlyZWN0aW9uIHRvIGdldCB0byB0aGUKKyAgICAgKiBwb2ludCBvciBpZiB0aGUgcG9pbnQgaXMgb24gdGhlIGxpbmUgZGV0ZXJtaW5lZCBieSB0aGUgbGluZSBzZWdtZW50IGJ1dAorICAgICAqIG5vdCBvbiB0aGUgcmF5IGZyb20gdGhlIHNlZ21lbnQncyBzdGFydGluZyBwb2ludCBhbmQgdGhyb3VnaCBpdHMgZW5kCisgICAgICogcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHAgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSB0aGF0IGRlc2NyaWJlcyB3aGVyZSB0aGUgcG9pbnQgaXMgd2l0aCByZXNwZWN0IHRvIHRoaXMKKyAgICAgKiAgICAgICAgIGxpbmUgc2VnbWVudCwgZ2l2ZW4gdGhlIG9yaWVudGF0aW9uIG9mIHRoaXMgbGluZSBzZWdtZW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVsYXRpdmVDQ1coZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgcmV0dXJuIHJlbGF0aXZlQ0NXKGdldFgxKCksIGdldFkxKCksIGdldFgyKCksIGdldFkyKCksIHB4LCBweSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVsbHMgd2hlcmUgdGhlIHBvaW50IGlzIHdpdGggcmVzcGVjdCB0byB0aGlzIGxpbmUgc2VnbWVudCwgZ2l2ZW4gdGhlCisgICAgICogb3JpZW50YXRpb24gb2YgdGhpcyBsaW5lIHNlZ21lbnQuIElmIHRoZSByYXkgZm91bmQgYnkgZXh0ZW5kaW5nIHRoZSBsaW5lCisgICAgICogc2VnbWVudCBmcm9tIGl0cyBzdGFydGluZyBwb2ludCBpcyByb3RhdGVkLCB0aGlzIG1ldGhvZCB0ZWxscyB3aGV0aGVyIHRoZQorICAgICAqIHJheSBzaG91bGQgcm90YXRlIGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbiBvciBhIGNvdW50ZXItY2xvY2t3aXNlCisgICAgICogZGlyZWN0aW9uIHRvIGhpdCB0aGUgcG9pbnQgZmlyc3QuIFRoZSByZXR1cm4gdmFsdWUgaXMgMCBpZiB0aGUgcG9pbnQgaXMKKyAgICAgKiBvbiB0aGUgbGluZSBzZWdtZW50LCBpdCdzIDEgaWYgdGhlIHBvaW50IGlzIG9uIHRoZSByYXkgb3IgaWYgdGhlIHJheQorICAgICAqIHNob3VsZCByb3RhdGUgaW4gYSBjb3VudGVyLWNsb2Nrd2lzZSBkaXJlY3Rpb24gdG8gZ2V0IHRvIHRoZSBwb2ludCwgYW5kCisgICAgICogaXQncyAtMSBpZiB0aGUgcmF5IHNob3VsZCByb3RhdGUgaW4gYSBjbG9ja3dpc2UgZGlyZWN0aW9uIHRvIGdldCB0byB0aGUKKyAgICAgKiBwb2ludCBvciBpZiB0aGUgcG9pbnQgaXMgb24gdGhlIGxpbmUgZGV0ZXJtaW5lZCBieSB0aGUgbGluZSBzZWdtZW50IGJ1dAorICAgICAqIG5vdCBvbiB0aGUgcmF5IGZyb20gdGhlIHNlZ21lbnQncyBzdGFydGluZyBwb2ludCBhbmQgdGhyb3VnaCBpdHMgZW5kCisgICAgICogcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHRoYXQgZGVzY3JpYmVzIHdoZXJlIHRoZSBwb2ludCBpcyB3aXRoIHJlc3BlY3QgdG8gdGhpcworICAgICAqICAgICAgICAgbGluZSBzZWdtZW50LCBnaXZlbiB0aGUgb3JpZW50YXRpb24gb2YgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICovCisgICAgcHVibGljIGludCByZWxhdGl2ZUNDVyhQb2ludDJEIHApIHsKKyAgICAgICAgcmV0dXJuIHJlbGF0aXZlQ0NXKGdldFgxKCksIGdldFkxKCksIGdldFgyKCksIGdldFkyKCksIHAuZ2V0WCgpLCBwLmdldFkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVsbHMgd2hldGhlciB0aGUgdHdvIGxpbmUgc2VnbWVudHMgY3Jvc3MuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgZmlyc3Qgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBmaXJzdCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBmaXJzdCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBmaXJzdCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB4MworICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIHNlY29uZCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MworICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIHNlY29uZCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB4NAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBzZWNvbmQgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geTQKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgc2Vjb25kIHNlZ21lbnQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgdHdvIGxpbmUgc2VnbWVudHMgY3Jvc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGxpbmVzSW50ZXJzZWN0KGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHgzLAorICAgICAgICAgICAgZG91YmxlIHkzLCBkb3VibGUgeDQsIGRvdWJsZSB5NCkgeworICAgICAgICAvKgorICAgICAgICAgKiBBID0gKHgyLXgxLCB5Mi15MSkgQiA9ICh4My14MSwgeTMteTEpIEMgPSAoeDQteDEsIHk0LXkxKSBEID0gKHg0LXgzLAorICAgICAgICAgKiB5NC15MykgPSBDLUIgRSA9ICh4MS14MywgeTEteTMpID0gLUIgRiA9ICh4Mi14MywgeTIteTMpID0gQS1CIFJlc3VsdAorICAgICAgICAgKiBpcyAoKEF4QikgKEF4QykgPD0wKSBhbmQgKChEeEUpIChEeEYpIDw9IDApIER4RSA9IChDLUIpeCgtQikgPQorICAgICAgICAgKiBCeEItQ3hCID0gQnhDIER4RiA9IChDLUIpeChBLUIpID0gQ3hBLUN4Qi1CeEErQnhCID0gQXhCK0J4Qy1BeEMKKyAgICAgICAgICovCisKKyAgICAgICAgeDIgLT0geDE7IC8vIEEKKyAgICAgICAgeTIgLT0geTE7CisgICAgICAgIHgzIC09IHgxOyAvLyBCCisgICAgICAgIHkzIC09IHkxOworICAgICAgICB4NCAtPSB4MTsgLy8gQworICAgICAgICB5NCAtPSB5MTsKKworICAgICAgICBkb3VibGUgQXZCID0geDIgKiB5MyAtIHgzICogeTI7CisgICAgICAgIGRvdWJsZSBBdkMgPSB4MiAqIHk0IC0geDQgKiB5MjsKKworICAgICAgICAvLyBPbmxpbmUKKyAgICAgICAgaWYgKEF2QiA9PSAwLjAgJiYgQXZDID09IDAuMCkgeworICAgICAgICAgICAgaWYgKHgyICE9IDAuMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAoeDQgKiB4MyA8PSAwLjApCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAoKHgzICogeDIgPj0gMC4wKSAmJiAoeDIgPiAwLjAgPyB4MyA8PSB4MiB8fCB4NCA8PSB4MiA6IHgzID49IHgyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHg0ID49IHgyKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoeTIgIT0gMC4wKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICh5NCAqIHkzIDw9IDAuMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8ICgoeTMgKiB5MiA+PSAwLjApICYmICh5MiA+IDAuMCA/IHkzIDw9IHkyIHx8IHk0IDw9IHkyIDogeTMgPj0geTIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgeTQgPj0geTIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBCdkMgPSB4MyAqIHk0IC0geDQgKiB5MzsKKworICAgICAgICByZXR1cm4gKEF2QiAqIEF2QyA8PSAwLjApICYmIChCdkMgKiAoQXZCICsgQnZDIC0gQXZDKSA8PSAwLjApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbGxzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBsaW5lIHNlZ21lbnRzIGNyb3NzZXMgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgdGVzdCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIHRlc3Qgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgdGVzdCBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSB0ZXN0IHNlZ21lbnQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIGxpbmUgc2VnbWVudHMgY3Jvc3NlcyB0aGlzIGxpbmUgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzTGluZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgcmV0dXJuIGxpbmVzSW50ZXJzZWN0KHgxLCB5MSwgeDIsIHkyLCBnZXRYMSgpLCBnZXRZMSgpLCBnZXRYMigpLCBnZXRZMigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWxscyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbGluZSBzZWdtZW50cyBjcm9zc2VzIHRoaXMgbGluZSBzZWdtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgdGVzdCBzZWdtZW50LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBsaW5lIHNlZ21lbnRzIGNyb3NzZXMgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGwgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzTGluZShMaW5lMkQgbCkgeworICAgICAgICByZXR1cm4gbGluZXNJbnRlcnNlY3QobC5nZXRYMSgpLCBsLmdldFkxKCksIGwuZ2V0WDIoKSwgbC5nZXRZMigpLCBnZXRYMSgpLCBnZXRZMSgpLAorICAgICAgICAgICAgICAgIGdldFgyKCksIGdldFkyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0gcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lCisgICAgICogICAgICAgICBzZWdtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHB0U2VnRGlzdFNxKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHB4LAorICAgICAgICAgICAgZG91YmxlIHB5KSB7CisgICAgICAgIC8qCisgICAgICAgICAqIEEgPSAoeDIgLSB4MSwgeTIgLSB5MSkgUCA9IChweCAtIHgxLCBweSAtIHkxKQorICAgICAgICAgKi8KKyAgICAgICAgeDIgLT0geDE7IC8vIEEgPSAoeDIsIHkyKQorICAgICAgICB5MiAtPSB5MTsKKyAgICAgICAgcHggLT0geDE7IC8vIFAgPSAocHgsIHB5KQorICAgICAgICBweSAtPSB5MTsKKyAgICAgICAgZG91YmxlIGRpc3Q7CisgICAgICAgIGlmIChweCAqIHgyICsgcHkgKiB5MiA8PSAwLjApIHsgLy8gUCpBCisgICAgICAgICAgICBkaXN0ID0gcHggKiBweCArIHB5ICogcHk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBweCA9IHgyIC0gcHg7IC8vIFAgPSBBIC0gUCA9ICh4MiAtIHB4LCB5MiAtIHB5KQorICAgICAgICAgICAgcHkgPSB5MiAtIHB5OworICAgICAgICAgICAgaWYgKHB4ICogeDIgKyBweSAqIHkyIDw9IDAuMCkgeyAvLyBQKkEKKyAgICAgICAgICAgICAgICBkaXN0ID0gcHggKiBweCArIHB5ICogcHk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRpc3QgPSBweCAqIHkyIC0gcHkgKiB4MjsKKyAgICAgICAgICAgICAgICBkaXN0ID0gZGlzdCAqIGRpc3QgLyAoeDIgKiB4MiArIHkyICogeTIpOyAvLyBweEEvfEF8CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRpc3QgPCAwKSB7CisgICAgICAgICAgICBkaXN0ID0gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgcHRTZWdEaXN0KGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgcmV0dXJuIE1hdGguc3FydChwdFNlZ0Rpc3RTcSh4MSwgeTEsIHgyLCB5MiwgcHgsIHB5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2l2ZXMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoaXMgbGluZSBzZWdtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0gcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoaXMgbGluZQorICAgICAqICAgICAgICAgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIHB0U2VnRGlzdFNxKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBwdFNlZ0Rpc3RTcShnZXRYMSgpLCBnZXRZMSgpLCBnZXRYMigpLCBnZXRZMigpLCBweCwgcHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGlzIGxpbmUgc2VnbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhpcyBsaW5lCisgICAgICogICAgICAgICBzZWdtZW50LgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgcHRTZWdEaXN0U3EoUG9pbnQyRCBwKSB7CisgICAgICAgIHJldHVybiBwdFNlZ0Rpc3RTcShnZXRYMSgpLCBnZXRZMSgpLCBnZXRYMigpLCBnZXRZMigpLCBwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBwdFNlZ0Rpc3QoZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgcmV0dXJuIHB0U2VnRGlzdChnZXRYMSgpLCBnZXRZMSgpLCBnZXRYMigpLCBnZXRZMigpLCBweCwgcHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhpcyBsaW5lIHNlZ21lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGlzIGxpbmUgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIHB0U2VnRGlzdChQb2ludDJEIHApIHsKKyAgICAgICAgcmV0dXJuIHB0U2VnRGlzdChnZXRYMSgpLCBnZXRZMSgpLCBnZXRYMigpLCBnZXRZMigpLCBwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0gcHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHB0TGluZURpc3RTcShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSBweCwKKyAgICAgICAgICAgIGRvdWJsZSBweSkgeworICAgICAgICB4MiAtPSB4MTsKKyAgICAgICAgeTIgLT0geTE7CisgICAgICAgIHB4IC09IHgxOworICAgICAgICBweSAtPSB5MTsKKyAgICAgICAgZG91YmxlIHMgPSBweCAqIHkyIC0gcHkgKiB4MjsKKyAgICAgICAgcmV0dXJuIHMgKiBzIC8gKHgyICogeDIgKyB5MiAqIHkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlcyB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhlIGxpbmUuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGxpbmUgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgbGluZSBzZWdtZW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBwdExpbmVEaXN0KGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgcmV0dXJuIE1hdGguc3FydChwdExpbmVEaXN0U3EoeDEsIHkxLCB4MiwgeTIsIHB4LCBweSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmVzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZQorICAgICAqIGRldGVybWluZWQgYnkgdGhpcyBMaW5lMkQuCisgICAgICogCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEBwYXJhbSBweQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdGVzdCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZQorICAgICAqICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGlzIExpbmUyRC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIHB0TGluZURpc3RTcShkb3VibGUgcHgsIGRvdWJsZSBweSkgeworICAgICAgICByZXR1cm4gcHRMaW5lRGlzdFNxKGdldFgxKCksIGdldFkxKCksIGdldFgyKCksIGdldFkyKCksIHB4LCBweSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2l2ZXMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lCisgICAgICogZGV0ZXJtaW5lZCBieSB0aGlzIExpbmUyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludCBhbmQgdGhlIGxpbmUKKyAgICAgKiAgICAgICAgIGRldGVybWluZWQgYnkgdGhpcyBMaW5lMkQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBwdExpbmVEaXN0U3EoUG9pbnQyRCBwKSB7CisgICAgICAgIHJldHVybiBwdExpbmVEaXN0U3EoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0WDIoKSwgZ2V0WTIoKSwgcC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lIGRldGVybWluZWQgYnkgdGhpcworICAgICAqIExpbmUyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB0ZXN0IHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50IGFuZCB0aGUgbGluZSBkZXRlcm1pbmVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgIExpbmUyRC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIHB0TGluZURpc3QoZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgcmV0dXJuIHB0TGluZURpc3QoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0WDIoKSwgZ2V0WTIoKSwgcHgsIHB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lIGRldGVybWluZWQgYnkgdGhpcworICAgICAqIExpbmUyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHRlc3QgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgYW5kIHRoZSBsaW5lIGRldGVybWluZWQgYnkgdGhpcworICAgICAqICAgICAgICAgTGluZTJELgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgcHRMaW5lRGlzdChQb2ludDJEIHApIHsKKyAgICAgICAgcmV0dXJuIHB0TGluZURpc3QoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0WDIoKSwgZ2V0WTIoKSwgcC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgcHgsIGRvdWJsZSBweSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUG9pbnQyRCBwKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhSZWN0YW5nbGUyRCByKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgcngsIGRvdWJsZSByeSwgZG91YmxlIHJ3LCBkb3VibGUgcmgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGludGVyc2VjdHMoZG91YmxlIHJ4LCBkb3VibGUgcnksIGRvdWJsZSBydywgZG91YmxlIHJoKSB7CisgICAgICAgIHJldHVybiBpbnRlcnNlY3RzKG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUocngsIHJ5LCBydywgcmgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgcmV0dXJuIHIuaW50ZXJzZWN0c0xpbmUoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0WDIoKSwgZ2V0WTIoKSk7CisgICAgfQorCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIGF0KSB7CisgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IodGhpcywgYXQpOworICAgIH0KKworICAgIHB1YmxpYyBQYXRoSXRlcmF0b3IgZ2V0UGF0aEl0ZXJhdG9yKEFmZmluZVRyYW5zZm9ybSBhdCwgZG91YmxlIGZsYXRuZXNzKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IodGhpcywgYXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0ZTZmMGYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9Ob25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworLyoqCisgKiBUaGUgQ2xhc3MgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbiBpcyB0aGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duCisgKiB3aGVuIGFuIGFjdGlvbiByZXF1aXJlcyBpbnZlcnRpbmcgYW4ge0BsaW5rIEFmZmluZVRyYW5zZm9ybX0gdGhhdCBpcyBub3QKKyAqIGludmVydGlibGUgKGhhcyBkZXRlcm1pbmFudCAwKS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIGV4dGVuZHMgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2MTM3MjI1MjQwNTAzOTkwNDY2TDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBub24taW52ZXJ0aWJsZSB0cmFuc2Zvcm0gZXhjZXB0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgZXJyb3IgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9uaW52ZXJ0aWJsZVRyYW5zZm9ybUV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgICAgICBzdXBlcihzKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9nZW9tL1BhdGhJdGVyYXRvci5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vUGF0aEl0ZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmQxYzBmZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9nZW9tL1BhdGhJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMTQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCisvKioKKyAqIFRoZSBJbnRlcmZhY2UgUGF0aEl0ZXJhdG9yIHJlcHJlc2VudHMgYW4gaXRlcmF0b3Igb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8KKyAqIHRyYXZlcnNlIHRoZSBvdXRsaW5lIG9mIGEge0BsaW5rIGphdmEuYXd0LlNoYXBlfS4gSXQgcmV0dXJucyBwb2ludHMgYWxvbmcgdGhlCisgKiBib3VuZGFyeSBvZiB0aGUgU2hhcGUgd2hpY2ggbWF5IGJlIGFjdHVhbCB2ZXJ0aWNlcyAoaW4gdGhlIGNhc2Ugb2YgYSBzaGFwZQorICogbWFkZSBvZiBsaW5lIHNlZ21lbnRzKSBvciBtYXkgYmUgcG9pbnRzIG9uIGEgY3VydmVkIHNlZ21lbnQgd2l0aCB0aGUgZGlzdGFuY2UKKyAqIGJldHdlZW4gdGhlIHBvaW50cyBkZXRlcm1pbmVkIGJ5IGEgY2hvc2VuIGZsYXR0ZW5pbmcgZmFjdG9yLgorICogPHA+CisgKiBJZiB0aGUgc2hhcGUgaXMgY2xvc2VkLCB0aGUgb3V0bGluZSBpcyB0cmF2ZXJzZWQgaW4gdGhlIGNvdW50ZXItY2xvY2t3aXNlCisgKiBkaXJlY3Rpb24uIFRoYXQgbWVhbnMgdGhhdCBtb3ZpbmcgZm9yd2FyZCBhbG9uZyB0aGUgYm91bmRhcnkgaXMgdG8gdHJhdmVsIGluCisgKiBzdWNoIGEgd2F5IHRoYXQgdGhlIGludGVyaW9yIG9mIHRoZSBzaGFwZSBpcyB0byB0aGUgbGVmdCBvZiB0aGUgb3V0bGluZSBwYXRoCisgKiBhbmQgdGhlIGV4dGVyaW9yIG9mIHRoZSBzaGFwZSBpcyB0byB0aGUgcmlnaHQgb2YgdGhlIG91dGxpbmUgcGF0aC4gVGhlCisgKiBpbnRlcmlvciBhbmQgZXh0ZXJpb3Igb2YgdGhlIHNoYXBlIGFyZSBkZXRlcm1pbmVkIGJ5IGEgd2luZGluZyBydWxlLgorICogPC9wPgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBQYXRoSXRlcmF0b3IgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJTkRfRVZFTl9PREQgaW5kaWNhdGVzIHRoZSB3aW5kaW5nIHJ1bGUgdGhhdCBzYXlzIHRoYXQgYQorICAgICAqIHBvaW50IGlzIG91dHNpZGUgdGhlIHNoYXBlIGlmIGFueSBpbmZpbml0ZSByYXkgZnJvbSB0aGUgcG9pbnQgY3Jvc3NlcyB0aGUKKyAgICAgKiBvdXRsaW5lIG9mIHRoZSBzaGFwZSBhbiBldmVuIG51bWJlciBvZiB0aW1lcywgb3RoZXJ3aXNlIGl0IGlzIGluc2lkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5EX0VWRU5fT0REID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXSU5EX05PTl9aRVJPIGluZGljYXRlcyB0aGUgd2luZGluZyBydWxlIHRoYXQgc2F5cyB0aGF0IGEKKyAgICAgKiBwb2ludCBpcyBpbnNpZGUgdGhlIHNoYXBlIGlmIGV2ZXJ5IGluZmluaXRlIHJheSBzdGFydGluZyBmcm9tIHRoYXQgcG9pbnQKKyAgICAgKiBjcm9zc2VzIHRoZSBvdXRsaW5lIG9mIHRoZSBzaGFwZSBhIG5vbi16ZXJvIG51bWJlciBvZiB0aW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXSU5EX05PTl9aRVJPID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBTRUdfTU9WRVRPIGluZGljYXRlcyB0aGF0IHRvIGZvbGxvdyB0aGUgc2hhcGUncyBvdXRsaW5lIGZyb20KKyAgICAgKiB0aGUgcHJldmlvdXMgcG9pbnQgdG8gdGhlIGN1cnJlbnQgcG9pbnQsIHRoZSBjdXJzb3IgKHRyYXZlcnNhbCBwb2ludCkKKyAgICAgKiBzaG91bGQgYmUgcGxhY2VkIGRpcmVjdGx5IG9uIHRoZSBjdXJyZW50IHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFR19NT1ZFVE8gPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNFR19MSU5FVE8gaW5kaWNhdGVzIHRoYXQgdG8gZm9sbG93IHRoZSBzaGFwZSdzIG91dGxpbmUgZnJvbQorICAgICAqIHRoZSBwcmV2aW91cyBwb2ludCB0byB0aGUgY3VycmVudCBwb2ludCwgdGhlIGN1cnNvciAodHJhdmVyc2FsIHBvaW50KQorICAgICAqIHNob3VsZCBmb2xsb3cgYSBzdHJhaWdodCBsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFR19MSU5FVE8gPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNFR19RVUFEVE8gaW5kaWNhdGVzIHRoYXQgdG8gZm9sbG93IHRoZSBzaGFwZSdzIG91dGxpbmUgZnJvbQorICAgICAqIHRoZSBwcmV2aW91cyBwb2ludCB0byB0aGUgY3VycmVudCBwb2ludCwgdGhlIGN1cnNvciAodHJhdmVyc2FsIHBvaW50KQorICAgICAqIHNob3VsZCBmb2xsb3cgYSBxdWFkcmF0aWMgY3VydmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VHX1FVQURUTyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0VHX0NVQklDVE8gaW5kaWNhdGVzIHRoYXQgdG8gZm9sbG93IHRoZSBzaGFwZSdzIG91dGxpbmUKKyAgICAgKiBmcm9tIHRoZSBwcmV2aW91cyBwb2ludCB0byB0aGUgY3VycmVudCBwb2ludCwgdGhlIGN1cnNvciAodHJhdmVyc2FsCisgICAgICogcG9pbnQpIHNob3VsZCBmb2xsb3cgYSBjdWJpYyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRUdfQ1VCSUNUTyA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0VHX0NMT1NFIGluZGljYXRlcyB0aGF0IHRoZSBwcmV2aW91cyBwb2ludCB3YXMgdGhlIGVuZCBvZgorICAgICAqIHRoZSBzaGFwZSdzIG91dGxpbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VHX0NMT1NFID0gNDsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpbmRpbmcgcnVsZSwgZWl0aGVyIHtAbGluayBQYXRoSXRlcmF0b3IjV0lORF9FVkVOX09ERH0gb3IKKyAgICAgKiB7QGxpbmsgUGF0aEl0ZXJhdG9yI1dJTkRfTk9OX1pFUk99LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpbmRpbmcgcnVsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdpbmRpbmdSdWxlKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBQYXRoSXRlcmF0b3IgaGFzIGJlZW4gY29tcGxldGVseSB0cmF2ZXJzZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIFBhdGhJdGVyYXRvciBoYXMgYmVlbiBjb21wbGV0ZWx5IHRyYXZlcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RvbmUoKTsKKworICAgIC8qKgorICAgICAqIFRlbGxzIHRoaXMgUGF0aEl0ZXJhdG9yIHRvIHNraXAgdG8gdGhlIG5leHQgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBuZXh0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbmV4dCB2ZXJ0ZXggcG9pbnQgYWxvbmcgdGhlIHNoYXBlJ3Mgb3V0bGluZQorICAgICAqIGFuZCBhIGZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hhdCBraW5kIG9mIHNlZ21lbnQgdG8gdXNlIGluIG9yZGVyIHRvIGNvbm5lY3QKKyAgICAgKiB0aGUgcHJldmlvdXMgdmVydGV4IHBvaW50IHRvIHRoZSBjdXJyZW50IHZlcnRleCBwb2ludCB0byBmb3JtIHRoZSBjdXJyZW50CisgICAgICogc2VnbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29vcmRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgdGhhdCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgc2VnbWVudCBhcmUgd3JpdHRlbiBpbnRvLgorICAgICAqIEByZXR1cm4gdGhlIGZsYWcgdGhhdCBpbmRpY2F0ZXMgaG93IHRvIGZvbGxvdyB0aGUgc2hhcGUncyBvdXRsaW5lIGZyb20KKyAgICAgKiAgICAgICAgIHRoZSBwcmV2aW91cyBwb2ludCB0byB0aGUgY3VycmVudCBvbmUsIGNob3NlbiBmcm9tIHRoZSBmb2xsb3dpbmcKKyAgICAgKiAgICAgICAgIGNvbnN0YW50czoge0BsaW5rIFBhdGhJdGVyYXRvciNTRUdfTU9WRVRPfSwKKyAgICAgKiAgICAgICAgIHtAbGluayBQYXRoSXRlcmF0b3IjU0VHX0xJTkVUT30sIHtAbGluayBQYXRoSXRlcmF0b3IjU0VHX1FVQURUT30sCisgICAgICogICAgICAgICB7QGxpbmsgUGF0aEl0ZXJhdG9yI1NFR19DVUJJQ1RPfSwgb3IKKyAgICAgKiAgICAgICAgIHtAbGluayBQYXRoSXRlcmF0b3IjU0VHX0NMT1NFfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGZsb2F0W10gY29vcmRzKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBuZXh0IHZlcnRleCBwb2ludCBhbG9uZyB0aGUgc2hhcGUncyBvdXRsaW5lCisgICAgICogYW5kIGEgZmxhZyB0aGF0IGluZGljYXRlcyB3aGF0IGtpbmQgb2Ygc2VnbWVudCB0byB1c2UgaW4gb3JkZXIgdG8gY29ubmVjdAorICAgICAqIHRoZSBwcmV2aW91cyB2ZXJ0ZXggcG9pbnQgdG8gdGhlIGN1cnJlbnQgdmVydGV4IHBvaW50IHRvIGZvcm0gdGhlIGN1cnJlbnQKKyAgICAgKiBzZWdtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb29yZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IHRoZSBjb29yZGluYXRlcyBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICAgICBzZWdtZW50IGFyZSB3cml0dGVuIGludG8uCisgICAgICogQHJldHVybiB0aGUgZmxhZyB0aGF0IGluZGljYXRlcyBob3cgdG8gZm9sbG93IHRoZSBzaGFwZSdzIG91dGxpbmUgZnJvbQorICAgICAqICAgICAgICAgdGhlIHByZXZpb3VzIHBvaW50IHRvIHRoZSBjdXJyZW50IG9uZSwgY2hvc2VuIGZyb20gdGhlIGZvbGxvd2luZworICAgICAqICAgICAgICAgY29uc3RhbnRzOiB7QGxpbmsgUGF0aEl0ZXJhdG9yI1NFR19NT1ZFVE99LAorICAgICAqICAgICAgICAge0BsaW5rIFBhdGhJdGVyYXRvciNTRUdfTElORVRPfSwge0BsaW5rIFBhdGhJdGVyYXRvciNTRUdfUVVBRFRPfSwKKyAgICAgKiAgICAgICAgIHtAbGluayBQYXRoSXRlcmF0b3IjU0VHX0NVQklDVE99LCBvcgorICAgICAqICAgICAgICAge0BsaW5rIFBhdGhJdGVyYXRvciNTRUdfQ0xPU0V9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2dlb20vUG9pbnQyRC5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vUG9pbnQyRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3MDI2YzgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9Qb2ludDJELmphdmEKQEAgLTAsMCArMSwzMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0Lmdlb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubWlzYy5IYXNoQ29kZTsKKworLyoqCisgKiBUaGUgQ2xhc3MgUG9pbnQyRCByZXByZXNlbnRzIGEgcG9pbnQgd2hvc2UgZGF0YSBpcyBnaXZlbiBpbiBoaWdoLXByZWNpc2lvbgorICogdmFsdWVzIGFwcHJvcHJpYXRlIGZvciBncmFwaGljYWwgb3BlcmF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQb2ludDJEIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBGbG9hdCBpcyB0aGUgc3ViY2xhc3Mgb2YgUG9pbnQyRCB0aGF0IGhhcyBhbGwgb2YgaXRzIGRhdGEKKyAgICAgKiB2YWx1ZXMgc3RvcmVkIHdpdGggZmxvYXQtbGV2ZWwgcHJlY2lzaW9uLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRmxvYXQgZXh0ZW5kcyBQb2ludDJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgUG9pbnQyRCB3aXRoIGl0cyBkYXRhIHNldCB0byB6ZXJvLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KCkgeworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgUG9pbnQyRCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogY29vcmRpbmF0ZXMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUuCisgICAgICAgICAqIEBwYXJhbSB5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGbG9hdChmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgoKSB7CisgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkoKSB7CisgICAgICAgICAgICByZXR1cm4geTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZSBwb2ludCdzIGNvb3JkaW5hdGVzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgICAgIHRoaXMueCA9IChmbG9hdCl4OworICAgICAgICAgICAgdGhpcy55ID0gKGZsb2F0KXk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbeD0iICsgeCArICIseT0iICsgeSArICJdIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBEb3VibGUgaXMgdGhlIHN1YmNsYXNzIG9mIFBvaW50MkQgdGhhdCBoYXMgYWxsIG9mIGl0cyBkYXRhCisgICAgICogdmFsdWVzIHN0b3JlZCB3aXRoIGRvdWJsZS1sZXZlbCBwcmVjaXNpb24uCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBEb3VibGUgZXh0ZW5kcyBQb2ludDJEIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeTsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgUG9pbnQyRCB3aXRoIGl0cyBkYXRhIHNldCB0byB6ZXJvLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZG91YmxlLXZhbHVlZCBQb2ludDJEIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAgICAgKiBjb29yZGluYXRlcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgICAgICogQHBhcmFtIHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgICAgIHRoaXMueCA9IHg7CisgICAgICAgICAgICB0aGlzLnkgPSB5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WCgpIHsKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKGRvdWJsZSB4LCBkb3VibGUgeSkgeworICAgICAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgICAgIHRoaXMueSA9IHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbeD0iICsgeCArICIseT0iICsgeSArICJdIjsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBQb2ludDJELgorICAgICAqLworICAgIHByb3RlY3RlZCBQb2ludDJEKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRYKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WSgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcG9pbnQncyBjb29yZGluYXRlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRMb2NhdGlvbihkb3VibGUgeCwgZG91YmxlIHkpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcG9pbnQncyBjb29yZGluYXRlcyBieSBjb3B5aW5nIHRoZW0gZnJvbSBhbm90aGVyIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgdG8gY29weSB0aGUgZGF0YSBmcm9tLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKFBvaW50MkQgcCkgeworICAgICAgICBzZXRMb2NhdGlvbihwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHR3byBzcGVjaWZpZWQgcG9pbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4MQorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBwb2ludC4KKyAgICAgKiBAcGFyYW0geTIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHR3byBzcGVjaWZpZWQgcG9pbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRpc3RhbmNlU3EoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgIHgyIC09IHgxOworICAgICAgICB5MiAtPSB5MTsKKyAgICAgICAgcmV0dXJuIHgyICogeDIgKyB5MiAqIHkyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhpcyBwb2ludCBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBweAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQuCisgICAgICogQHBhcmFtIHB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhpcyBwb2ludCBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBkaXN0YW5jZVNxKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBQb2ludDJELmRpc3RhbmNlU3EoZ2V0WCgpLCBnZXRZKCksIHB4LCBweSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGlzIHBvaW50IGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdGhlciBwb2ludC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhpcyBwb2ludCBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBkaXN0YW5jZVNxKFBvaW50MkQgcCkgeworICAgICAgICByZXR1cm4gUG9pbnQyRC5kaXN0YW5jZVNxKGdldFgoKSwgZ2V0WSgpLCBwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSB0d28gc3BlY2lmaWVkIHBvaW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBvaW50LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgcG9pbnQuCisgICAgICogQHBhcmFtIHgyCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIHNwZWNpZmllZCBwb2ludHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZGlzdGFuY2UoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgIHJldHVybiBNYXRoLnNxcnQoZGlzdGFuY2VTcSh4MSwgeTEsIHgyLCB5MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoaXMgcG9pbnQgYW5kIHRoZSBzcGVjaWZpZWQgcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludC4KKyAgICAgKiBAcGFyYW0gcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50LgorICAgICAqIEByZXR1cm4gdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhpcyBwb2ludCBhbmQgdGhlIHNwZWNpZmllZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGRpc3RhbmNlKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBNYXRoLnNxcnQoZGlzdGFuY2VTcShweCwgcHkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGlzIHBvaW50IGFuZCB0aGUgc3BlY2lmaWVkIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgb3RoZXIgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGlzIHBvaW50IGFuZCB0aGUgc3BlY2lmaWVkIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZGlzdGFuY2UoUG9pbnQyRCBwKSB7CisgICAgICAgIHJldHVybiBNYXRoLnNxcnQoZGlzdGFuY2VTcShwKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgSGFzaENvZGUgaGFzaCA9IG5ldyBIYXNoQ29kZSgpOworICAgICAgICBoYXNoLmFwcGVuZChnZXRYKCkpOworICAgICAgICBoYXNoLmFwcGVuZChnZXRZKCkpOworICAgICAgICByZXR1cm4gaGFzaC5oYXNoQ29kZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFBvaW50MkQpIHsKKyAgICAgICAgICAgIFBvaW50MkQgcCA9IChQb2ludDJEKW9iajsKKyAgICAgICAgICAgIHJldHVybiBnZXRYKCkgPT0gcC5nZXRYKCkgJiYgZ2V0WSgpID09IHAuZ2V0WSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9RdWFkQ3VydmUyRC5qYXZhIGIvYXd0L2phdmEvYXd0L2dlb20vUXVhZEN1cnZlMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTg2YTQ4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vUXVhZEN1cnZlMkQuamF2YQpAQCAtMCwwICsxLDkxOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQ3Jvc3Npbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIFF1YWRDdXJ2ZTJEIGlzIGEgU2hhcGUgdGhhdCByZXByZXNlbnRzIGEgc2VnbWVudCBvZiBhIHF1YWRyYXRpYworICogKEJlemllcikgY3VydmUuIFRoZSBjdXJ2ZWQgc2VnbWVudCBpcyBkZXRlcm1pbmVkIGJ5IHRocmVlIHBvaW50czogYSBzdGFydAorICogcG9pbnQsIGFuIGVuZCBwb2ludCwgYW5kIGEgY29udHJvbCBwb2ludC4gVGhlIGxpbmUgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0bworICogdGhlIHN0YXJ0aW5nIHBvaW50IGdpdmVzIHRoZSB0YW5nZW50IHRvIHRoZSBjdXJ2ZSBhdCB0aGUgc3RhcnRpbmcgcG9pbnQsIGFuZAorICogdGhlIGxpbmUgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0byB0aGUgZW5kIHBvaW50IGdpdmVzIHRoZSB0YW5nZW50IHRvIHRoZQorICogY3VydmUgYXQgdGhlIGVuZCBwb2ludC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBRdWFkQ3VydmUyRCBpbXBsZW1lbnRzIFNoYXBlLCBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEZsb2F0IGlzIHRoZSBzdWJjbGFzcyBvZiBRdWFkQ3VydmUyRCB0aGF0IGhhcyBhbGwgb2YgaXRzIGRhdGEKKyAgICAgKiB2YWx1ZXMgc3RvcmVkIHdpdGggZmxvYXQtbGV2ZWwgcHJlY2lzaW9uLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRmxvYXQgZXh0ZW5kcyBRdWFkQ3VydmUyRCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQgc2VnbWVudC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB4MTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHkxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IGN0cmx4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IGN0cmx5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHgyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZmxvYXQtdmFsdWVkIFF1YWRDdXJ2ZTJEIHdpdGggYWxsIGNvb3JkaW5hdGUKKyAgICAgICAgICogdmFsdWVzIHNldCB0byB6ZXJvLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KCkgeworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmbG9hdC12YWx1ZWQgUXVhZEN1cnZlMkQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqIGNvb3JkaW5hdGUgdmFsdWVzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGN1cnZlZAorICAgICAgICAgKiAgICAgICAgICAgIHNlZ21lbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQKKyAgICAgICAgICogICAgICAgICAgICBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0geTIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KGZsb2F0IHgxLCBmbG9hdCB5MSwgZmxvYXQgY3RybHgsIGZsb2F0IGN0cmx5LCBmbG9hdCB4MiwgZmxvYXQgeTIpIHsKKyAgICAgICAgICAgIHNldEN1cnZlKHgxLCB5MSwgY3RybHgsIGN0cmx5LCB4MiwgeTIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WDEoKSB7CisgICAgICAgICAgICByZXR1cm4geDE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZMSgpIHsKKyAgICAgICAgICAgIHJldHVybiB5MTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEN0cmxYKCkgeworICAgICAgICAgICAgcmV0dXJuIGN0cmx4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0Q3RybFkoKSB7CisgICAgICAgICAgICByZXR1cm4gY3RybHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYMigpIHsKKyAgICAgICAgICAgIHJldHVybiB4MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkyKCkgeworICAgICAgICAgICAgcmV0dXJuIHkyOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQb2ludDJEIGdldFAxKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkZsb2F0KHgxLCB5MSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0Q3RybFB0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQb2ludDJELkZsb2F0KGN0cmx4LCBjdHJseSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0UDIoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRmxvYXQoeDIsIHkyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRDdXJ2ZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN0cmx4LCBkb3VibGUgY3RybHksIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgICAgICB0aGlzLngxID0gKGZsb2F0KXgxOworICAgICAgICAgICAgdGhpcy55MSA9IChmbG9hdCl5MTsKKyAgICAgICAgICAgIHRoaXMuY3RybHggPSAoZmxvYXQpY3RybHg7CisgICAgICAgICAgICB0aGlzLmN0cmx5ID0gKGZsb2F0KWN0cmx5OworICAgICAgICAgICAgdGhpcy54MiA9IChmbG9hdCl4MjsKKyAgICAgICAgICAgIHRoaXMueTIgPSAoZmxvYXQpeTI7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgZGF0YSB2YWx1ZXMgb2YgdGhlIGN1cnZlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGN1cnZlZAorICAgICAgICAgKiAgICAgICAgICAgIHNlZ21lbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQKKyAgICAgICAgICogICAgICAgICAgICBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0geTIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoZmxvYXQgeDEsIGZsb2F0IHkxLCBmbG9hdCBjdHJseCwgZmxvYXQgY3RybHksIGZsb2F0IHgyLCBmbG9hdCB5MikgeworICAgICAgICAgICAgdGhpcy54MSA9IHgxOworICAgICAgICAgICAgdGhpcy55MSA9IHkxOworICAgICAgICAgICAgdGhpcy5jdHJseCA9IGN0cmx4OworICAgICAgICAgICAgdGhpcy5jdHJseSA9IGN0cmx5OworICAgICAgICAgICAgdGhpcy54MiA9IHgyOworICAgICAgICAgICAgdGhpcy55MiA9IHkyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICAgICAgZmxvYXQgcngwID0gTWF0aC5taW4oTWF0aC5taW4oeDEsIHgyKSwgY3RybHgpOworICAgICAgICAgICAgZmxvYXQgcnkwID0gTWF0aC5taW4oTWF0aC5taW4oeTEsIHkyKSwgY3RybHkpOworICAgICAgICAgICAgZmxvYXQgcngxID0gTWF0aC5tYXgoTWF0aC5tYXgoeDEsIHgyKSwgY3RybHgpOworICAgICAgICAgICAgZmxvYXQgcnkxID0gTWF0aC5tYXgoTWF0aC5tYXgoeTEsIHkyKSwgY3RybHkpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5GbG9hdChyeDAsIHJ5MCwgcngxIC0gcngwLCByeTEgLSByeTApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIERvdWJsZSBpcyB0aGUgc3ViY2xhc3Mgb2YgUXVhZEN1cnZlMkQgdGhhdCBoYXMgYWxsIG9mIGl0cyBkYXRhCisgICAgICogdmFsdWVzIHN0b3JlZCB3aXRoIGRvdWJsZS1sZXZlbCBwcmVjaXNpb24uCisgICAgICogCisgICAgICogQHNpbmNlIEFuZHJvaWQgMS4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBEb3VibGUgZXh0ZW5kcyBRdWFkQ3VydmUyRCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQgc2VnbWVudC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQgc2VnbWVudC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGNvbnRyb2wgcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIGN0cmx4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSBjdHJseTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIHBvaW50IG9mIHRoZSBjdXJ2ZWQgc2VnbWVudC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHkyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZG91YmxlLXZhbHVlZCBRdWFkQ3VydmUyRCB3aXRoIGFsbCBjb29yZGluYXRlCisgICAgICAgICAqIHZhbHVlcyBzZXQgdG8gemVyby4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgUXVhZEN1cnZlMkQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqIGNvb3JkaW5hdGUgdmFsdWVzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgxCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGN1cnZlZAorICAgICAgICAgKiAgICAgICAgICAgIHNlZ21lbnQuCisgICAgICAgICAqIEBwYXJhbSB5MQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQKKyAgICAgICAgICogICAgICAgICAgICBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0gY3RybHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAgICAgKiBAcGFyYW0geDIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKiBAcGFyYW0geTIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN0cmx4LCBkb3VibGUgY3RybHksIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgICAgICBzZXRDdXJ2ZSh4MSwgeTEsIGN0cmx4LCBjdHJseSwgeDIsIHkyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgxKCkgeworICAgICAgICAgICAgcmV0dXJuIHgxOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WTEoKSB7CisgICAgICAgICAgICByZXR1cm4geTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRDdHJsWCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdHJseDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEN0cmxZKCkgeworICAgICAgICAgICAgcmV0dXJuIGN0cmx5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0WDIoKSB7CisgICAgICAgICAgICByZXR1cm4geDI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZMigpIHsKKyAgICAgICAgICAgIHJldHVybiB5MjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRQMSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9pbnQyRC5Eb3VibGUoeDEsIHkxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUG9pbnQyRCBnZXRDdHJsUHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKGN0cmx4LCBjdHJseSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFBvaW50MkQgZ2V0UDIoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKHgyLCB5Mik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjdHJseCwgZG91YmxlIGN0cmx5LCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICAgICAgdGhpcy54MSA9IHgxOworICAgICAgICAgICAgdGhpcy55MSA9IHkxOworICAgICAgICAgICAgdGhpcy5jdHJseCA9IGN0cmx4OworICAgICAgICAgICAgdGhpcy5jdHJseSA9IGN0cmx5OworICAgICAgICAgICAgdGhpcy54MiA9IHgyOworICAgICAgICAgICAgdGhpcy55MiA9IHkyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKCkgeworICAgICAgICAgICAgZG91YmxlIHJ4MCA9IE1hdGgubWluKE1hdGgubWluKHgxLCB4MiksIGN0cmx4KTsKKyAgICAgICAgICAgIGRvdWJsZSByeTAgPSBNYXRoLm1pbihNYXRoLm1pbih5MSwgeTIpLCBjdHJseSk7CisgICAgICAgICAgICBkb3VibGUgcngxID0gTWF0aC5tYXgoTWF0aC5tYXgoeDEsIHgyKSwgY3RybHgpOworICAgICAgICAgICAgZG91YmxlIHJ5MSA9IE1hdGgubWF4KE1hdGgubWF4KHkxLCB5MiksIGN0cmx5KTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKHJ4MCwgcnkwLCByeDEgLSByeDAsIHJ5MSAtIHJ5MCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFF1YWRDdXJ2ZTJEIHBhdGggaXRlcmF0b3IKKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgUGF0aEl0ZXJhdG9yIGZvciBhIFF1YWQyRCBjdXJ2ZS4KKyAgICAgKi8KKyAgICBjbGFzcyBJdGVyYXRvciBpbXBsZW1lbnRzIFBhdGhJdGVyYXRvciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzb3VyY2UgUXVhZEN1cnZlMkQgb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgUXVhZEN1cnZlMkQgYzsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBhdGggaXRlcmF0b3IgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGN1cnJlbnQgc2VnbWVudCBpbmRleC4KKyAgICAgICAgICovCisgICAgICAgIGludCBpbmRleDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBRdWFkQ3VydmUyRC5JdGVyYXRvciBmb3IgZ2l2ZW4gY3VydmUgYW5kCisgICAgICAgICAqIHRyYW5zZm9ybWF0aW9uCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gcQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgUXVhZEN1cnZlMkQgb2JqZWN0LgorICAgICAgICAgKiBAcGFyYW0gdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBBZmZpbmVUcmFuc2Zvcm0gdGhhdCBhY3RzIG9uIHRoZSBjb29yZGluYXRlcyBiZWZvcmUKKyAgICAgICAgICogICAgICAgICAgICByZXR1cm5pbmcgdGhlbSAob3IgbnVsbCkuCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcihRdWFkQ3VydmUyRCBxLCBBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICAgICAgdGhpcy5jID0gcTsKKyAgICAgICAgICAgIHRoaXMudCA9IHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFdpbmRpbmdSdWxlKCkgeworICAgICAgICAgICAgcmV0dXJuIFdJTkRfTk9OX1pFUk87CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gKGluZGV4ID4gMSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBuZXh0KCkgeworICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgICAgIGlmIChpbmRleCA9PSAwKSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19NT1ZFVE87CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gYy5nZXRYMSgpOworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IGMuZ2V0WTEoKTsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfUVVBRFRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IGMuZ2V0Q3RybFgoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSBjLmdldEN0cmxZKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzJdID0gYy5nZXRYMigpOworICAgICAgICAgICAgICAgIGNvb3Jkc1szXSA9IGMuZ2V0WTIoKTsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdC50cmFuc2Zvcm0oY29vcmRzLCAwLCBjb29yZHMsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjdXJyZW50U2VnbWVudChmbG9hdFtdIGNvb3JkcykgeworICAgICAgICAgICAgaWYgKGlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjRCPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCljLmdldFgxKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KWMuZ2V0WTEoKTsKKyAgICAgICAgICAgICAgICBjb3VudCA9IDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfUVVBRFRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCljLmdldEN0cmxYKCk7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KWMuZ2V0Q3RybFkoKTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMl0gPSAoZmxvYXQpYy5nZXRYMigpOworICAgICAgICAgICAgICAgIGNvb3Jkc1szXSA9IChmbG9hdCljLmdldFkyKCk7CisgICAgICAgICAgICAgICAgY291bnQgPSAyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHF1YWRyYXRpYyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUXVhZEN1cnZlMkQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WDEoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc3RhcnRpbmcgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFkxKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUG9pbnQyRCBnZXRQMSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgY29udHJvbCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldEN0cmxYKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNvbnRyb2wgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB5IGNvb3JkaW5hdGUgb2YgdGhlIGNvbnRyb2wgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRDdHJsWSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29udHJvbCBwb2ludC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQb2ludDJEIGdldEN0cmxQdCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRYMigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXRZMigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZW5kIHBvaW50LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGVuZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUG9pbnQyRCBnZXRQMigpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgY3VydmUuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIGN0cmx4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEN1cnZlKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgY3RybHgsIGRvdWJsZSBjdHJseSwgZG91YmxlIHgyLAorICAgICAgICAgICAgZG91YmxlIHkyKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2YgdGhlIGN1cnZlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwMQorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBjdXJ2ZWQgc2VnbWVudC4KKyAgICAgKiBAcGFyYW0gY3AKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBwMgorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgdGhyZWUgcG9pbnRzIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoUG9pbnQyRCBwMSwgUG9pbnQyRCBjcCwgUG9pbnQyRCBwMikgeworICAgICAgICBzZXRDdXJ2ZShwMS5nZXRYKCksIHAxLmdldFkoKSwgY3AuZ2V0WCgpLCBjcC5nZXRZKCksIHAyLmdldFgoKSwgcDIuZ2V0WSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIG9mIHRoZSBjdXJ2ZSBieSByZWFkaW5nIHRoZSBkYXRhIGZyb20gYW4gYXJyYXkgb2YgdmFsdWVzLgorICAgICAqIFRoZSB2YWx1ZXMgYXJlIHJlYWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGFyZ3VtZW50cyBvZiB0aGUgbWV0aG9kCisgICAgICoge0BsaW5rIFF1YWRDdXJ2ZTJEI3NldEN1cnZlKGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpfQorICAgICAqIC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29vcmRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgdmFsdWVzIGNvbnRhaW5pbmcgdGhlIG5ldyBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBkYXRhIHRvIHJlYWQgd2l0aGluIHRoZSBhcnJheS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjb29yZHMubGVuZ3RofSA8IG9mZnNldCArIDYuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb29yZGluYXRlIGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoZG91YmxlW10gY29vcmRzLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHNldEN1cnZlKGNvb3Jkc1tvZmZzZXQgKyAwXSwgY29vcmRzW29mZnNldCArIDFdLCBjb29yZHNbb2Zmc2V0ICsgMl0sIGNvb3Jkc1tvZmZzZXQgKyAzXSwKKyAgICAgICAgICAgICAgICBjb29yZHNbb2Zmc2V0ICsgNF0sIGNvb3Jkc1tvZmZzZXQgKyA1XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgY3VydmUgYnkgcmVhZGluZyB0aGUgZGF0YSBmcm9tIGFuIGFycmF5IG9mIHBvaW50cy4KKyAgICAgKiBUaGUgdmFsdWVzIGFyZSByZWFkIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBhcmd1bWVudHMgb2YgdGhlIG1ldGhvZAorICAgICAqIHtAbGluayBRdWFkQ3VydmUyRCNzZXRDdXJ2ZShQb2ludDJELCBQb2ludDJELCBQb2ludDJEKX0uCisgICAgICogCisgICAgICogQHBhcmFtIHBvaW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyBjb250YWluaW5nIHRoZSBuZXcgY29vcmRpbmF0ZXMuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZGF0YSB0byByZWFkIHdpdGhpbiB0aGUgYXJyYXkuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwb2ludHMubGVuZ3RoIDwgb2Zmc2V0ICsgMy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBvaW50IGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VydmUoUG9pbnQyRFtdIHBvaW50cywgaW50IG9mZnNldCkgeworICAgICAgICBzZXRDdXJ2ZShwb2ludHNbb2Zmc2V0ICsgMF0uZ2V0WCgpLCBwb2ludHNbb2Zmc2V0ICsgMF0uZ2V0WSgpLCBwb2ludHNbb2Zmc2V0ICsgMV0uZ2V0WCgpLAorICAgICAgICAgICAgICAgIHBvaW50c1tvZmZzZXQgKyAxXS5nZXRZKCksIHBvaW50c1tvZmZzZXQgKyAyXS5nZXRYKCksIHBvaW50c1tvZmZzZXQgKyAyXS5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2YgdGhlIGN1cnZlIGJ5IGNvcHlpbmcgaXQgZnJvbSBhbm90aGVyIFF1YWRDdXJ2ZTJELgorICAgICAqIAorICAgICAqIEBwYXJhbSBjdXJ2ZQorICAgICAqICAgICAgICAgICAgdGhlIGN1cnZlIHRvIGNvcHkgdGhlIGRhdGEgcG9pbnRzIGZyb20uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjdXJ2ZSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEN1cnZlKFF1YWRDdXJ2ZTJEIGN1cnZlKSB7CisgICAgICAgIHNldEN1cnZlKGN1cnZlLmdldFgxKCksIGN1cnZlLmdldFkxKCksIGN1cnZlLmdldEN0cmxYKCksIGN1cnZlLmdldEN0cmxZKCksIGN1cnZlLmdldFgyKCksCisgICAgICAgICAgICAgICAgY3VydmUuZ2V0WTIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjb250cm9sIHBvaW50IHRvIHRoZSBzdHJhaWdodAorICAgICAqIGxpbmUgc2VnbWVudCBjb25uZWN0aW5nIHRoZSBzdGFydCBwb2ludCBhbmQgdGhlIGVuZCBwb2ludCBmb3IgdGhpcyBjdXJ2ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzcXVhcmUgb2YgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGNvbnRyb2wgcG9pbnQgdG8gdGhlIHN0cmFpZ2h0CisgICAgICogICAgICAgICBsaW5lIHNlZ21lbnQgY29ubmVjdGluZyB0aGUgc3RhcnQgcG9pbnQgYW5kIHRoZSBlbmQgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRGbGF0bmVzc1NxKCkgeworICAgICAgICByZXR1cm4gTGluZTJELnB0U2VnRGlzdFNxKGdldFgxKCksIGdldFkxKCksIGdldFgyKCksIGdldFkyKCksIGdldEN0cmxYKCksIGdldEN0cmxZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0byB0aGUgc3RyYWlnaHQKKyAgICAgKiBsaW5lIHNlZ21lbnQgY29ubmVjdGluZyB0aGUgc3RhcnQgcG9pbnQgYW5kIHRoZSBlbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIGN0cmx4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0byB0aGUgc3RyYWlnaHQKKyAgICAgKiAgICAgICAgIGxpbmUgc2VnbWVudCBjb25uZWN0aW5nIHRoZSBzdGFydCBwb2ludCBhbmQgdGhlIGVuZCBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBnZXRGbGF0bmVzc1NxKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgY3RybHgsIGRvdWJsZSBjdHJseSwgZG91YmxlIHgyLAorICAgICAgICAgICAgZG91YmxlIHkyKSB7CisgICAgICAgIHJldHVybiBMaW5lMkQucHRTZWdEaXN0U3EoeDEsIHkxLCB4MiwgeTIsIGN0cmx4LCBjdHJseSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjb250cm9sIHBvaW50IHRvIHRoZSBzdHJhaWdodAorICAgICAqIGxpbmUgc2VnbWVudCBjb25uZWN0aW5nIHRoZSBzdGFydCBwb2ludCBhbmQgdGhlIGVuZCBwb2ludCBieSByZWFkaW5nIHRoZQorICAgICAqIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2ludHMgZnJvbSBhbiBhcnJheSBvZiB2YWx1ZXMuIFRoZSB2YWx1ZXMgYXJlIHJlYWQgaW4KKyAgICAgKiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgYXJndW1lbnRzIG9mIHRoZSBtZXRob2QKKyAgICAgKiB7QGxpbmsgUXVhZEN1cnZlMkQjZ2V0RmxhdG5lc3NTcShkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlKX0KKyAgICAgKiAuCisgICAgICogCisgICAgICogQHBhcmFtIGNvb3JkcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyBjb250YWluaW5nIHRoZSBjb29yZGluYXRlcyB0byB1c2UgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgY2FsY3VsYXRpb24KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBkYXRhIHRvIHJlYWQgd2l0aGluIHRoZSBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0byB0aGUgc3RyYWlnaHQKKyAgICAgKiAgICAgICAgIGxpbmUgc2VnbWVudCBjb25uZWN0aW5nIHRoZSBzdGFydCBwb2ludCBhbmQgdGhlIGVuZCBwb2ludC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjb29yZHMubGVuZ3RofSA8IG9mZnNldCArIDYuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb29yZGluYXRlIGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RmxhdG5lc3NTcShkb3VibGUgY29vcmRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIExpbmUyRC5wdFNlZ0Rpc3RTcShjb29yZHNbb2Zmc2V0ICsgMF0sIGNvb3Jkc1tvZmZzZXQgKyAxXSwgY29vcmRzW29mZnNldCArIDRdLAorICAgICAgICAgICAgICAgIGNvb3Jkc1tvZmZzZXQgKyA1XSwgY29vcmRzW29mZnNldCArIDJdLCBjb29yZHNbb2Zmc2V0ICsgM10pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGNvbnRyb2wgcG9pbnQgdG8gdGhlIHN0cmFpZ2h0IGxpbmUgc2VnbWVudAorICAgICAqIGNvbm5lY3RpbmcgdGhlIHN0YXJ0IHBvaW50IGFuZCB0aGUgZW5kIHBvaW50IG9mIHRoaXMgUXVhZEN1cnZlMkQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGNvbnRyb2wgcG9pbnQgdG8gdGhlIHN0cmFpZ2h0IGxpbmUKKyAgICAgKiAgICAgICAgIHNlZ21lbnQgY29ubmVjdGluZyB0aGUgc3RhcnQgcG9pbnQgYW5kIHRoZSBlbmQgcG9pbnQgb2YgdGhpcworICAgICAqICAgICAgICAgUXVhZEN1cnZlMkQuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRGbGF0bmVzcygpIHsKKyAgICAgICAgcmV0dXJuIExpbmUyRC5wdFNlZ0Rpc3QoZ2V0WDEoKSwgZ2V0WTEoKSwgZ2V0WDIoKSwgZ2V0WTIoKSwgZ2V0Q3RybFgoKSwgZ2V0Q3RybFkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY29udHJvbCBwb2ludCB0byB0aGUgc3RyYWlnaHQgbGluZSBzZWdtZW50CisgICAgICogY29ubmVjdGluZyB0aGUgc3RhcnQgcG9pbnQgYW5kIHRoZSBlbmQgcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkxCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIGN0cmx4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjb250cm9sIHBvaW50LgorICAgICAqIEBwYXJhbSBjdHJseQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY29udHJvbCBwb2ludC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGVuZCBwb2ludCBvZiB0aGUgY3VydmVkIHNlZ21lbnQuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgcG9pbnQgb2YgdGhlIGN1cnZlZCBzZWdtZW50LgorICAgICAqIEByZXR1cm4gdGhlIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjb250cm9sIHBvaW50IHRvIHRoZSBzdHJhaWdodCBsaW5lCisgICAgICogICAgICAgICBzZWdtZW50IGNvbm5lY3RpbmcgdGhlIHN0YXJ0IHBvaW50IGFuZCB0aGUgZW5kIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGdldEZsYXRuZXNzKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgY3RybHgsIGRvdWJsZSBjdHJseSwgZG91YmxlIHgyLAorICAgICAgICAgICAgZG91YmxlIHkyKSB7CisgICAgICAgIHJldHVybiBMaW5lMkQucHRTZWdEaXN0KHgxLCB5MSwgeDIsIHkyLCBjdHJseCwgY3RybHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjb250cm9sIHBvaW50IHRvIHRoZSBzdHJhaWdodCBsaW5lIHNlZ21lbnQKKyAgICAgKiBjb25uZWN0aW5nIHRoZSBzdGFydCBwb2ludCBhbmQgdGhlIGVuZCBwb2ludC4gVGhlIHZhbHVlcyBhcmUgcmVhZCBpbiB0aGUKKyAgICAgKiBzYW1lIG9yZGVyIGFzIHRoZSBhcmd1bWVudHMgb2YgdGhlIG1ldGhvZAorICAgICAqIHtAbGluayBRdWFkQ3VydmUyRCNnZXRGbGF0bmVzcyhkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlKX0KKyAgICAgKiAuCisgICAgICogCisgICAgICogQHBhcmFtIGNvb3JkcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHBvaW50cyBjb250YWluaW5nIHRoZSBjb29yZGluYXRlcyB0byB1c2UgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgY2FsY3VsYXRpb24uCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZGF0YSB0byByZWFkIHdpdGhpbiB0aGUgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGNvbnRyb2wgcG9pbnQgdG8gdGhlIHN0cmFpZ2h0IGxpbmUKKyAgICAgKiAgICAgICAgIHNlZ21lbnQgY29ubmVjdGluZyB0aGUgc3RhcnQgcG9pbnQgYW5kIHRoZSBlbmQgcG9pbnQuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7Y29kZSBjb29yZHMubGVuZ3RofSA8IG9mZnNldCArIDYuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb29yZGluYXRlIGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RmxhdG5lc3MoZG91YmxlIGNvb3Jkc1tdLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHJldHVybiBMaW5lMkQucHRTZWdEaXN0KGNvb3Jkc1tvZmZzZXQgKyAwXSwgY29vcmRzW29mZnNldCArIDFdLCBjb29yZHNbb2Zmc2V0ICsgNF0sCisgICAgICAgICAgICAgICAgY29vcmRzW29mZnNldCArIDVdLCBjb29yZHNbb2Zmc2V0ICsgMl0sIGNvb3Jkc1tvZmZzZXQgKyAzXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZGF0YSBmb3IgdHdvIHF1YWRyYXRpYyBjdXJ2ZXMgYnkgZGl2aWRpbmcgdGhpcyBjdXJ2ZSBpbiB0d28uCisgICAgICogVGhlIGRpdmlzaW9uIHBvaW50IGlzIHRoZSBwb2ludCBvbiB0aGUgY3VydmUgdGhhdCBpcyBjbG9zZXN0IHRvIHRoaXMKKyAgICAgKiBjdXJ2ZSdzIGNvbnRyb2wgcG9pbnQuIFRoZSBkYXRhIG9mIHRoaXMgY3VydmUgaXMgbGVmdCB1bmNoYW5nZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBRdWFkQ3VydmUyRCB3aGVyZSB0aGUgbGVmdCAoc3RhcnQpIHNlZ21lbnQncyBkYXRhIGlzCisgICAgICogICAgICAgICAgICB3cml0dGVuLgorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqICAgICAgICAgICAgdGhlIFF1YWRDdXJ2ZTJEIHdoZXJlIHRoZSByaWdodCAoZW5kKSBzZWdtZW50J3MgZGF0YSBpcworICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZWl0aGVyIGN1cnZlIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3ViZGl2aWRlKFF1YWRDdXJ2ZTJEIGxlZnQsIFF1YWRDdXJ2ZTJEIHJpZ2h0KSB7CisgICAgICAgIHN1YmRpdmlkZSh0aGlzLCBsZWZ0LCByaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZGF0YSBmb3IgdHdvIHF1YWRyYXRpYyBjdXJ2ZXMgYnkgZGl2aWRpbmcgYSBzb3VyY2UgY3VydmUgaW4KKyAgICAgKiB0d28uIFRoZSBkaXZpc2lvbiBwb2ludCBpcyB0aGUgcG9pbnQgb24gdGhlIGN1cnZlIHRoYXQgaXMgY2xvc2VzdCB0byB0aGUKKyAgICAgKiBzb3VyY2UgY3VydmUncyBjb250cm9sIHBvaW50LiBUaGUgZGF0YSBvZiB0aGUgc291cmNlIGN1cnZlIGlzIGxlZnQKKyAgICAgKiB1bmNoYW5nZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGN1cnZlIHRoYXQgcHJvdmlkZXMgdGhlIGluaXRpYWwgZGF0YS4KKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqICAgICAgICAgICAgdGhlIFF1YWRDdXJ2ZTJEIHdoZXJlIHRoZSBsZWZ0IChzdGFydCkgc2VnbWVudCdzIGRhdGEgaXMKKyAgICAgKiAgICAgICAgICAgIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHJpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgUXVhZEN1cnZlMkQgd2hlcmUgdGhlIHJpZ2h0IChlbmQpIHNlZ21lbnQncyBkYXRhIGlzCisgICAgICogICAgICAgICAgICB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIGN1cnZlcyBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdWJkaXZpZGUoUXVhZEN1cnZlMkQgc3JjLCBRdWFkQ3VydmUyRCBsZWZ0LCBRdWFkQ3VydmUyRCByaWdodCkgeworICAgICAgICBkb3VibGUgeDEgPSBzcmMuZ2V0WDEoKTsKKyAgICAgICAgZG91YmxlIHkxID0gc3JjLmdldFkxKCk7CisgICAgICAgIGRvdWJsZSBjeCA9IHNyYy5nZXRDdHJsWCgpOworICAgICAgICBkb3VibGUgY3kgPSBzcmMuZ2V0Q3RybFkoKTsKKyAgICAgICAgZG91YmxlIHgyID0gc3JjLmdldFgyKCk7CisgICAgICAgIGRvdWJsZSB5MiA9IHNyYy5nZXRZMigpOworICAgICAgICBkb3VibGUgY3gxID0gKHgxICsgY3gpIC8gMi4wOworICAgICAgICBkb3VibGUgY3kxID0gKHkxICsgY3kpIC8gMi4wOworICAgICAgICBkb3VibGUgY3gyID0gKHgyICsgY3gpIC8gMi4wOworICAgICAgICBkb3VibGUgY3kyID0gKHkyICsgY3kpIC8gMi4wOworICAgICAgICBjeCA9IChjeDEgKyBjeDIpIC8gMi4wOworICAgICAgICBjeSA9IChjeTEgKyBjeTIpIC8gMi4wOworICAgICAgICBpZiAobGVmdCAhPSBudWxsKSB7CisgICAgICAgICAgICBsZWZ0LnNldEN1cnZlKHgxLCB5MSwgY3gxLCBjeTEsIGN4LCBjeSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJpZ2h0LnNldEN1cnZlKGN4LCBjeSwgY3gyLCBjeTIsIHgyLCB5Mik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBkYXRhIGZvciB0d28gcXVhZHJhdGljIGN1cnZlcyBieSBkaXZpZGluZyBhIHNvdXJjZSBjdXJ2ZSBpbgorICAgICAqIHR3by4gVGhlIGRpdmlzaW9uIHBvaW50IGlzIHRoZSBwb2ludCBvbiB0aGUgY3VydmUgdGhhdCBpcyBjbG9zZXN0IHRvIHRoZQorICAgICAqIHNvdXJjZSBjdXJ2ZSdzIGNvbnRyb2wgcG9pbnQuIFRoZSBkYXRhIGZvciB0aGUgdGhyZWUgY3VydmVzIGlzIHJlYWQgYW5kCisgICAgICogd3JpdHRlbiBmcm9tIGFycmF5cyBvZiB2YWx1ZXMgaW4gdGhlIHVzdWFsIG9yZGVyOiB4MSwgeTEsIGN4LCBjeSwgeDIsIHkyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IGdpdmVzIHRoZSBkYXRhIHZhbHVlcyBmb3IgdGhlIHNvdXJjZSBjdXJ2ZS4KKyAgICAgKiBAcGFyYW0gc3Jjb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBzcmMgYXJyYXkgdG8gcmVhZCB0aGUgdmFsdWVzIGZyb20uCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aGVyZSB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHN0YXJ0IGN1cnZlIHNob3VsZCBiZQorICAgICAqICAgICAgICAgICAgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gbGVmdE9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgbGVmdCBhcnJheSB0byBzdGFydCB3cml0aW5nIHRoZSB2YWx1ZXMuCisgICAgICogQHBhcmFtIHJpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgd2hlcmUgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBlbmQgY3VydmUgc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICB3cml0dGVuLgorICAgICAqIEBwYXJhbSByaWdodE9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgcmlnaHQgYXJyYXkgdG8gc3RhcnQgd3JpdGluZyB0aGUgdmFsdWVzLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNyYy5sZW5ndGh9IDwgc3Jjb2ZmICsgNiBvciBpZiB7QGNvZGUgbGVmdC5sZW5ndGh9CisgICAgICogICAgICAgICAgICAgPCBsZWZ0T2ZmICsgNiBvciBpZiB7QGNvZGUgcmlnaHQubGVuZ3RofSA8IHJpZ2h0T2ZmICsgNi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBhcnJheXMgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc3ViZGl2aWRlKGRvdWJsZSBzcmNbXSwgaW50IHNyY29mZiwgZG91YmxlIGxlZnRbXSwgaW50IGxlZnRPZmYsCisgICAgICAgICAgICBkb3VibGUgcmlnaHRbXSwgaW50IHJpZ2h0T2ZmKSB7CisgICAgICAgIGRvdWJsZSB4MSA9IHNyY1tzcmNvZmYgKyAwXTsKKyAgICAgICAgZG91YmxlIHkxID0gc3JjW3NyY29mZiArIDFdOworICAgICAgICBkb3VibGUgY3ggPSBzcmNbc3Jjb2ZmICsgMl07CisgICAgICAgIGRvdWJsZSBjeSA9IHNyY1tzcmNvZmYgKyAzXTsKKyAgICAgICAgZG91YmxlIHgyID0gc3JjW3NyY29mZiArIDRdOworICAgICAgICBkb3VibGUgeTIgPSBzcmNbc3Jjb2ZmICsgNV07CisgICAgICAgIGRvdWJsZSBjeDEgPSAoeDEgKyBjeCkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBjeTEgPSAoeTEgKyBjeSkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBjeDIgPSAoeDIgKyBjeCkgLyAyLjA7CisgICAgICAgIGRvdWJsZSBjeTIgPSAoeTIgKyBjeSkgLyAyLjA7CisgICAgICAgIGN4ID0gKGN4MSArIGN4MikgLyAyLjA7CisgICAgICAgIGN5ID0gKGN5MSArIGN5MikgLyAyLjA7CisgICAgICAgIGlmIChsZWZ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxlZnRbbGVmdE9mZiArIDBdID0geDE7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyAxXSA9IHkxOworICAgICAgICAgICAgbGVmdFtsZWZ0T2ZmICsgMl0gPSBjeDE7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyAzXSA9IGN5MTsKKyAgICAgICAgICAgIGxlZnRbbGVmdE9mZiArIDRdID0gY3g7CisgICAgICAgICAgICBsZWZ0W2xlZnRPZmYgKyA1XSA9IGN5OworICAgICAgICB9CisgICAgICAgIGlmIChyaWdodCAhPSBudWxsKSB7CisgICAgICAgICAgICByaWdodFtyaWdodE9mZiArIDBdID0gY3g7CisgICAgICAgICAgICByaWdodFtyaWdodE9mZiArIDFdID0gY3k7CisgICAgICAgICAgICByaWdodFtyaWdodE9mZiArIDJdID0gY3gyOworICAgICAgICAgICAgcmlnaHRbcmlnaHRPZmYgKyAzXSA9IGN5MjsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgNF0gPSB4MjsKKyAgICAgICAgICAgIHJpZ2h0W3JpZ2h0T2ZmICsgNV0gPSB5MjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSByb290cyBvZiB0aGUgcXVhZHJhdGljIHBvbHlub21pYWwuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5CisgICAgICogZmluZGluZyB0aGUgKHJlYWwpIHZhbHVlcyBvZiB4IHRoYXQgc29sdmUgdGhlIGZvbGxvd2luZyBlcXVhdGlvbjoKKyAgICAgKiBlcW5bMl0qeCp4ICsgZXFuWzFdKnggKyBlcW5bMF0gPSAwLiBUaGUgc29sdXRpb25zIGFyZSB3cml0dGVuIGJhY2sgaW50bworICAgICAqIHRoZSBhcnJheSBlcW4gc3RhcnRpbmcgZnJvbSB0aGUgaW5kZXggMCBpbiB0aGUgYXJyYXkuIFRoZSByZXR1cm4gdmFsdWUKKyAgICAgKiB0ZWxscyBob3cgbWFueSBhcnJheSBlbGVtZW50cyBoYXZlIGJlZW4gY2hhbmdlZCBieSB0aGlzIG1ldGhvZCBjYWxsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlcW4KKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgcXVhZHJhdGljCisgICAgICogICAgICAgICAgICBwb2x5bm9taWFsIHRvIHNvbHZlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByb290cyBvZiB0aGUgcXVhZHJhdGljIHBvbHlub21pYWwuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZXFuLmxlbmd0aH0gPCAzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBzb2x2ZVF1YWRyYXRpYyhkb3VibGUgZXFuW10pIHsKKyAgICAgICAgcmV0dXJuIHNvbHZlUXVhZHJhdGljKGVxbiwgZXFuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyB0aGUgcm9vdHMgb2YgdGhlIHF1YWRyYXRpYyBwb2x5bm9taWFsLiBUaGlzIGlzIGFjY29tcGxpc2hlZCBieQorICAgICAqIGZpbmRpbmcgdGhlIChyZWFsKSB2YWx1ZXMgb2YgeCB0aGF0IHNvbHZlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb246CisgICAgICogZXFuWzJdKngqeCArIGVxblsxXSp4ICsgZXFuWzBdID0gMC4gVGhlIHNvbHV0aW9ucyBhcmUgd3JpdHRlbiBpbnRvIHRoZQorICAgICAqIGFycmF5IHJlcyBzdGFydGluZyBmcm9tIHRoZSBpbmRleCAwIGluIHRoZSBhcnJheS4gVGhlIHJldHVybiB2YWx1ZSB0ZWxscworICAgICAqIGhvdyBtYW55IGFycmF5IGVsZW1lbnRzIGhhdmUgYmVlbiB3cml0dGVuIGJ5IHRoaXMgbWV0aG9kIGNhbGwuCisgICAgICogCisgICAgICogQHBhcmFtIGVxbgorICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgY29lZmZpY2llbnRzIG9mIHRoZSBxdWFkcmF0aWMKKyAgICAgKiAgICAgICAgICAgIHBvbHlub21pYWwgdG8gc29sdmUuCisgICAgICogQHBhcmFtIHJlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRoYXQgdGhpcyBtZXRob2Qgd3JpdGVzIHRoZSByZXN1bHRzIGludG8uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJvb3RzIG9mIHRoZSBxdWFkcmF0aWMgcG9seW5vbWlhbC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBlcW4ubGVuZ3RofSA8IDMgb3IgaWYge0Bjb2RlIHJlcy5sZW5ndGh9IGlzIGxlc3MKKyAgICAgKiAgICAgICAgICAgICB0aGFuIHRoZSBudW1iZXIgb2Ygcm9vdHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciBhcnJheSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNvbHZlUXVhZHJhdGljKGRvdWJsZSBlcW5bXSwgZG91YmxlIHJlc1tdKSB7CisgICAgICAgIHJldHVybiBDcm9zc2luZy5zb2x2ZVF1YWQoZXFuLCByZXMpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgIHJldHVybiBDcm9zc2luZy5pc0luc2lkZUV2ZW5PZGQoQ3Jvc3NpbmcuY3Jvc3NTaGFwZSh0aGlzLCBweCwgcHkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgcngsIGRvdWJsZSByeSwgZG91YmxlIHJ3LCBkb3VibGUgcmgpIHsKKyAgICAgICAgaW50IGNyb3NzID0gQ3Jvc3NpbmcuaW50ZXJzZWN0U2hhcGUodGhpcywgcngsIHJ5LCBydywgcmgpOworICAgICAgICByZXR1cm4gY3Jvc3MgIT0gQ3Jvc3NpbmcuQ1JPU1NJTkcgJiYgQ3Jvc3NpbmcuaXNJbnNpZGVFdmVuT2RkKGNyb3NzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpbnQgY3Jvc3MgPSBDcm9zc2luZy5pbnRlcnNlY3RTaGFwZSh0aGlzLCByeCwgcnksIHJ3LCByaCk7CisgICAgICAgIHJldHVybiBjcm9zcyA9PSBDcm9zc2luZy5DUk9TU0lORyB8fCBDcm9zc2luZy5pc0luc2lkZUV2ZW5PZGQoY3Jvc3MpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFBvaW50MkQgcCkgeworICAgICAgICByZXR1cm4gY29udGFpbnMocC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgcmV0dXJuIGludGVyc2VjdHMoci5nZXRYKCksIHIuZ2V0WSgpLCByLmdldFdpZHRoKCksIHIuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHIuZ2V0WCgpLCByLmdldFkoKSwgci5nZXRXaWR0aCgpLCByLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIGdldEJvdW5kczJEKCkuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIHQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCB0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gdCwgZG91YmxlIGZsYXRuZXNzKSB7CisgICAgICAgIHJldHVybiBuZXcgRmxhdHRlbmluZ1BhdGhJdGVyYXRvcihnZXRQYXRoSXRlcmF0b3IodCksIGZsYXRuZXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9nZW9tL1JlY3RhbmdsZTJELmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9SZWN0YW5nbGUyRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxNjYxMzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvZ2VvbS9SZWN0YW5nbGUyRC5qYXZhCkBAIC0wLDAgKzEsODI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubWlzYy5IYXNoQ29kZTsKKworLyoqCisgKiBUaGUgQ2xhc3MgUmVjdGFuZ2xlMkQgcmVwcmVzZW50cyBhIHJlY3RhbmdsZSB3aG9zZSBjb29yZGluYXRlcyBhcmUgZ2l2ZW4gd2l0aAorICogdGhlIGNvcnJlY3QgcHJlY2lzaW9uIHRvIGJlIHVzZWQgd2l0aCB0aGUgR3JhcGhpY3MyRCBjbGFzc2VzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFJlY3RhbmdsZTJEIGV4dGVuZHMgUmVjdGFuZ3VsYXJTaGFwZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgT1VUX0xFRlQgaXMgYSBtYXNrIHRoYXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IGEgZ2l2ZW4KKyAgICAgKiBwb2ludCBpcyBvdXRzaWRlIHRoZSByZWN0YW5nbGUgYW5kIHRvIGl0cyBsZWZ0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9VVF9MRUZUID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBPVVRfVE9QIGlzIGEgbWFzayB0aGF0IGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCBhIGdpdmVuCisgICAgICogcG9pbnQgaXMgb3V0c2lkZSB0aGUgcmVjdGFuZ2xlIGFuZCBhYm92ZSBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVVRfVE9QID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBPVVRfUklHSFQgaXMgYSBtYXNrIHRoYXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IGEgZ2l2ZW4KKyAgICAgKiBwb2ludCBpcyBvdXRzaWRlIHRoZSByZWN0YW5nbGUgYW5kIHRvIGl0cyByaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVVRfUklHSFQgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE9VVF9CT1RUT00gaXMgYSBtYXNrIHRoYXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IGEgZ2l2ZW4KKyAgICAgKiBwb2ludCBpcyBvdXRzaWRlIHRoZSByZWN0YW5nbGUgYW5kIGFib3ZlIGl0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9VVF9CT1RUT00gPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEZsb2F0IGlzIHRoZSBzdWJjbGFzcyBvZiBSZWN0YW5nbGUyRCB0aGF0IHJlcHJlc2VudHMgYQorICAgICAqIHJlY3RhbmdsZSB3aG9zZSBkYXRhIHZhbHVlcyBhcmUgZ2l2ZW4gYXMgZmxvYXRzICh3aXRoIGZsb2F0LWxldmVsCisgICAgICogcHJlY2lzaW9uKS4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZsb2F0IGV4dGVuZHMgUmVjdGFuZ2xlMkQgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmbG9hdCB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IHJlY3RhbmdsZSB3aXRoIGZsb2F0LXByZWNpc2lvbiBkYXRhIGZpZWxkcy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGbG9hdCgpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVjdGFuZ2xlIHdpdGggdGhlIHNwZWNpZmllZCBmbG9hdC1wcmVjaXNpb24gZGF0YS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KGZsb2F0IHgsIGZsb2F0IHksIGZsb2F0IHdpZHRoLCBmbG9hdCBoZWlnaHQpIHsKKyAgICAgICAgICAgIHNldFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYKCkgeworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZKCkgeworICAgICAgICAgICAgcmV0dXJuIHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aCA8PSAwLjBmIHx8IGhlaWdodCA8PSAwLjBmOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIHJlY3RhbmdsZSdzIGRhdGEgdG8gdGhlIGdpdmVuIHZhbHVlcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgc2V0UmVjdChmbG9hdCB4LCBmbG9hdCB5LCBmbG9hdCB3aWR0aCwgZmxvYXQgaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFJlY3QoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHRoaXMueCA9IChmbG9hdCl4OworICAgICAgICAgICAgdGhpcy55ID0gKGZsb2F0KXk7CisgICAgICAgICAgICB0aGlzLndpZHRoID0gKGZsb2F0KXdpZHRoOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSAoZmxvYXQpaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFJlY3QoUmVjdGFuZ2xlMkQgcikgeworICAgICAgICAgICAgdGhpcy54ID0gKGZsb2F0KXIuZ2V0WCgpOworICAgICAgICAgICAgdGhpcy55ID0gKGZsb2F0KXIuZ2V0WSgpOworICAgICAgICAgICAgdGhpcy53aWR0aCA9IChmbG9hdClyLmdldFdpZHRoKCk7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IChmbG9hdClyLmdldEhlaWdodCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgb3V0Y29kZShkb3VibGUgcHgsIGRvdWJsZSBweSkgeworICAgICAgICAgICAgaW50IGNvZGUgPSAwOworCisgICAgICAgICAgICBpZiAod2lkdGggPD0gMC4wZikgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX0xFRlQgfCBPVVRfUklHSFQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHB4IDwgeCkgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX0xFRlQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHB4ID4geCArIHdpZHRoKSB7CisgICAgICAgICAgICAgICAgY29kZSB8PSBPVVRfUklHSFQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChoZWlnaHQgPD0gMC4wZikgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX1RPUCB8IE9VVF9CT1RUT007CisgICAgICAgICAgICB9IGVsc2UgaWYgKHB5IDwgeSkgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX1RPUDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocHkgPiB5ICsgaGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgY29kZSB8PSBPVVRfQk9UVE9NOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gY29kZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBjcmVhdGVJbnRlcnNlY3Rpb24oUmVjdGFuZ2xlMkQgcikgeworICAgICAgICAgICAgUmVjdGFuZ2xlMkQgZHN0OworICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBEb3VibGUpIHsKKyAgICAgICAgICAgICAgICBkc3QgPSBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRzdCA9IG5ldyBSZWN0YW5nbGUyRC5GbG9hdCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUmVjdGFuZ2xlMkQuaW50ZXJzZWN0KHRoaXMsIHIsIGRzdCk7CisgICAgICAgICAgICByZXR1cm4gZHN0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBjcmVhdGVVbmlvbihSZWN0YW5nbGUyRCByKSB7CisgICAgICAgICAgICBSZWN0YW5nbGUyRCBkc3Q7CisgICAgICAgICAgICBpZiAociBpbnN0YW5jZW9mIERvdWJsZSkgeworICAgICAgICAgICAgICAgIGRzdCA9IG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZHN0ID0gbmV3IFJlY3RhbmdsZTJELkZsb2F0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBSZWN0YW5nbGUyRC51bmlvbih0aGlzLCByLCBkc3QpOworICAgICAgICAgICAgcmV0dXJuIGRzdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgLy8gVGhlIG91dHB1dCBmb3JtYXQgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3VyLiBJdCBjb3VsZCBiZQorICAgICAgICAgICAgLy8gb2J0YWluZWQgaW4gdGhlIGZvbGxvd2luZyB3YXkKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoKS50b1N0cmluZygpKQorICAgICAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICsgIlt4PSIgKyB4ICsgIix5PSIgKyB5ICsgIix3aWR0aD0iICsgd2lkdGggKyAiLGhlaWdodD0iICsgaGVpZ2h0ICsgIl0iOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkIC8vJE5PTi1OTFMtNSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBEb3VibGUgaXMgdGhlIHN1YmNsYXNzIG9mIFJlY3RhbmdsZTJEIHRoYXQgcmVwcmVzZW50cyBhCisgICAgICogcmVjdGFuZ2xlIHdob3NlIGRhdGEgdmFsdWVzIGFyZSBnaXZlbiBhcyBkb3VibGVzICh3aXRoCisgICAgICogZG91YmxlLXByZWNpc2lvbi1sZXZlbCBwcmVjaXNpb24pLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRG91YmxlIGV4dGVuZHMgUmVjdGFuZ2xlMkQgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBlbXB0eSByZWN0YW5nbGUgd2l0aCBkb3VibGUtcHJlY2lzaW9uIGRhdGEgZmllbGRzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERvdWJsZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVjdGFuZ2xlIHdpdGggdGhlIGdpdmVuIGRvdWJsZSB2YWx1ZXMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIGhlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpIHsKKyAgICAgICAgICAgIHNldFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYKCkgeworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZKCkgeworICAgICAgICAgICAgcmV0dXJuIHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aCA8PSAwLjAgfHwgaGVpZ2h0IDw9IDAuMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRSZWN0KGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFJlY3QoUmVjdGFuZ2xlMkQgcikgeworICAgICAgICAgICAgdGhpcy54ID0gci5nZXRYKCk7CisgICAgICAgICAgICB0aGlzLnkgPSByLmdldFkoKTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSByLmdldFdpZHRoKCk7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHIuZ2V0SGVpZ2h0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBvdXRjb2RlKGRvdWJsZSBweCwgZG91YmxlIHB5KSB7CisgICAgICAgICAgICBpbnQgY29kZSA9IDA7CisKKyAgICAgICAgICAgIGlmICh3aWR0aCA8PSAwLjApIHsKKyAgICAgICAgICAgICAgICBjb2RlIHw9IE9VVF9MRUZUIHwgT1VUX1JJR0hUOworICAgICAgICAgICAgfSBlbHNlIGlmIChweCA8IHgpIHsKKyAgICAgICAgICAgICAgICBjb2RlIHw9IE9VVF9MRUZUOworICAgICAgICAgICAgfSBlbHNlIGlmIChweCA+IHggKyB3aWR0aCkgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX1JJR0hUOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGVpZ2h0IDw9IDAuMCkgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX1RPUCB8IE9VVF9CT1RUT007CisgICAgICAgICAgICB9IGVsc2UgaWYgKHB5IDwgeSkgeworICAgICAgICAgICAgICAgIGNvZGUgfD0gT1VUX1RPUDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocHkgPiB5ICsgaGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgY29kZSB8PSBPVVRfQk9UVE9NOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gY29kZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERvdWJsZSh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgY3JlYXRlSW50ZXJzZWN0aW9uKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIGRzdCA9IG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoKTsKKyAgICAgICAgICAgIFJlY3RhbmdsZTJELmludGVyc2VjdCh0aGlzLCByLCBkc3QpOworICAgICAgICAgICAgcmV0dXJuIGRzdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgY3JlYXRlVW5pb24oUmVjdGFuZ2xlMkQgcikgeworICAgICAgICAgICAgUmVjdGFuZ2xlMkQgZGVzdCA9IG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoKTsKKyAgICAgICAgICAgIFJlY3RhbmdsZTJELnVuaW9uKHRoaXMsIHIsIGRlc3QpOworICAgICAgICAgICAgcmV0dXJuIGRlc3Q7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIC8vIFRoZSBvdXRwdXQgZm9ybWF0IGJhc2VkIG9uIDEuNSByZWxlYXNlIGJlaGF2aW91ci4gSXQgY291bGQgYmUKKyAgICAgICAgICAgIC8vIG9idGFpbmVkIGluIHRoZSBmb2xsb3dpbmcgd2F5CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4obmV3IFJlY3RhbmdsZTJELkRvdWJsZSgpLnRvU3RyaW5nKCkpCisgICAgICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiW3g9IiArIHggKyAiLHk9IiArIHkgKyAiLHdpZHRoPSIgKyB3aWR0aCArICIsaGVpZ2h0PSIgKyBoZWlnaHQgKyAiXSI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQgLy8kTk9OLU5MUy01JAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEl0ZXJhdG9yIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlCisgICAgICogUmVjdGFuZ2xlMkQncyBib3VuZGFyeSBtb2RpZmllZCBieSBhbiBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICovCisgICAgY2xhc3MgSXRlcmF0b3IgaW1wbGVtZW50cyBQYXRoSXRlcmF0b3IgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSB4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSB5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIEFmZmluZVRyYW5zZm9ybSB0aGF0IGlzIHVzZWQgdG8gbW9kaWZ5IHRoZSBjb29yZGluYXRlcyB0aGF0IGFyZQorICAgICAgICAgKiByZXR1cm5lZCBieSB0aGUgcGF0aCBpdGVyYXRvci4KKyAgICAgICAgICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY3VycmVudCBzZWdtZW50IGluZGV4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGluZGV4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFJlY3RhbmdsZTJELkl0ZXJhdG9yIGZvciBnaXZlbiByZWN0YW5nbGUgYW5kCisgICAgICAgICAqIHRyYW5zZm9ybWF0aW9uLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFJlY3RhbmdsZTJEIG9iamVjdC4KKyAgICAgICAgICogQHBhcmFtIGF0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybSBvYmplY3QgdG8gYXBwbHkgdG8gdGhlIGNvb3JkaW5hdGVzCisgICAgICAgICAqICAgICAgICAgICAgYmVmb3JlIHJldHVybmluZyB0aGVtLgorICAgICAgICAgKi8KKyAgICAgICAgSXRlcmF0b3IoUmVjdGFuZ2xlMkQgciwgQWZmaW5lVHJhbnNmb3JtIGF0KSB7CisgICAgICAgICAgICB0aGlzLnggPSByLmdldFgoKTsKKyAgICAgICAgICAgIHRoaXMueSA9IHIuZ2V0WSgpOworICAgICAgICAgICAgdGhpcy53aWR0aCA9IHIuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gci5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIHRoaXMudCA9IGF0OworICAgICAgICAgICAgaWYgKHdpZHRoIDwgMC4wIHx8IGhlaWdodCA8IDAuMCkgeworICAgICAgICAgICAgICAgIGluZGV4ID0gNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IDU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBuZXh0KCkgeworICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ID09IDUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gU0VHX0NMT1NFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IHg7CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0geTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19MSU5FVE87CisgICAgICAgICAgICAgICAgc3dpdGNoIChpbmRleCkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSB4ICsgd2lkdGg7CisgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSB5OworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IHggKyB3aWR0aDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHkgKyBoZWlnaHQ7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzWzBdID0geDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHkgKyBoZWlnaHQ7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzWzBdID0geDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdC50cmFuc2Zvcm0oY29vcmRzLCAwLCBjb29yZHMsIDAsIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGN1cnJlbnRTZWdtZW50KGZsb2F0W10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ID09IDUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gU0VHX0NMT1NFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGU7CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCl4OworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IChmbG9hdCl5OworICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTU9WRVRPOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCkoeCArIHdpZHRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IChmbG9hdCl5OworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCkoeCArIHdpZHRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IChmbG9hdCkoeSArIGhlaWdodCk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gKGZsb2F0KXg7CisgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSAoZmxvYXQpKHkgKyBoZWlnaHQpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgNDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IChmbG9hdCl4OworICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gKGZsb2F0KXk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdC50cmFuc2Zvcm0oY29vcmRzLCAwLCBjb29yZHMsIDAsIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBSZWN0YW5nbGUyRC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVjdGFuZ2xlMkQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcmVjdGFuZ2xlJ3MgbG9jYXRpb24gYW5kIGRpbWVuc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlY3QoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYXRpb24gb2YgdGhlIHBvaW50IHdpdGggcmVzcGVjdCB0byB0aGUgcmVjdGFuZ2xlIGFuZCBwYWNrcworICAgICAqIHRoZSBpbmZvcm1hdGlvbiBpbnRvIGEgc2luZ2xlIGludGVnZXIgdXNpbmcgdGhlIGJpdG1hc2tzCisgICAgICoge0BsaW5rIFJlY3RhbmdsZTJEI09VVF9MRUZUfSwge0BsaW5rIFJlY3RhbmdsZTJEI09VVF9SSUdIVH0sCisgICAgICoge0BsaW5rIFJlY3RhbmdsZTJEI09VVF9UT1B9LCBhbmQge0BsaW5rIFJlY3RhbmdsZTJEI09VVF9CT1RUT019LiBJZiB0aGUKKyAgICAgKiByZWN0YW5nbGUgaGFzIHplcm8gb3IgbmVnYXRpdmUgd2lkdGgsIHRoZW4gZXZlcnkgcG9pbnQgaXMgcmVnYXJkZWQgYXMKKyAgICAgKiBiZWluZyBib3RoIHRvIHRoZSBsZWZ0IGFuZCB0byB0aGUgcmlnaHQgb2YgdGhlIHJlY3RhbmdsZS4gU2ltaWxhcmx5LCBpZgorICAgICAqIHRoZSBoZWlnaHQgaXMgemVybyBvciBuZWdhdGl2ZSB0aGVuIGFsbCBwb2ludHMgYXJlIGNvbnNpZGVyZWQgdG8gYmUgYm90aAorICAgICAqIGJvdGggYWJvdmUgYW5kIGJlbG93IGl0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB0aGUgcG9pbnQncyBsb2NhdGlvbiB3aXRoIHJlc3BlY3QgdG8gdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IG91dGNvZGUoZG91YmxlIHgsIGRvdWJsZSB5KTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gbmV3IHJlY3RhbmdsZSB0aGF0IGlzIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhpcyByZWN0YW5nbGUgd2l0aAorICAgICAqIHRoZSBnaXZlbiByZWN0YW5nbGUuIFRoZSByZXN1bHRpbmcgcmVjdGFuZ2xlIG1heSBiZSBlbXB0eS4gVGhlIGRhdGEgb2YKKyAgICAgKiB0aGlzIHJlY3RhbmdsZSBpcyBsZWZ0IHVuY2hhbmdlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHJlY3RhbmdsZSB0byBpbnRlcnNlY3Qgd2l0aCB0aGlzIHJlY3RhbmdsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcmVjdGFuZ2xlIGdpdmVuIGJ5IGludGVyc2VjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUmVjdGFuZ2xlMkQgY3JlYXRlSW50ZXJzZWN0aW9uKFJlY3RhbmdsZTJEIHIpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBuZXcgcmVjdGFuZ2xlIHRoYXQgaXMgdGhlIHVuaW9uIG9mIHRoaXMgcmVjdGFuZ2xlIHdpdGggdGhlCisgICAgICogZ2l2ZW4gcmVjdGFuZ2xlLiBUaGUgbmV3IHJlY3RhbmdsZSBpcyB0aGUgc21hbGxlc3QgcmVjdGFuZ2xlIHdoaWNoCisgICAgICogY29udGFpbnMgYm90aCB0aGlzIHJlY3RhbmdsZSBhbmQgdGhlIHJlY3RhbmdsZSBzcGVjaWZpZWQgYXMgYSBwYXJhbWV0ZXIuCisgICAgICogVGhlIGRhdGEgb2YgdGhpcyByZWN0YW5nbGUgaXMgbGVmdCB1bmNoYW5nZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWN0YW5nbGUgdG8gY29tYmluZSB3aXRoIHRoaXMgcmVjdGFuZ2xlLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyByZWN0YW5nbGUgZ2l2ZW4gYnkgdW5pb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFJlY3RhbmdsZTJEIGNyZWF0ZVVuaW9uKFJlY3RhbmdsZTJEIHIpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGlzIHJlY3RhbmdsZSB0byBtYXRjaCB0aGUgZGF0YSBvZiB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgcmVjdGFuZ2xlIHdob3NlIGRhdGEgaXMgdG8gYmUgY29waWVkIGludG8gdGhpcyByZWN0YW5nbGUncworICAgICAqICAgICAgICAgICAgZmllbGRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlY3QoUmVjdGFuZ2xlMkQgcikgeworICAgICAgICBzZXRSZWN0KHIuZ2V0WCgpLCByLmdldFkoKSwgci5nZXRXaWR0aCgpLCByLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZShkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCkgeworICAgICAgICBzZXRSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgcmV0dXJuIChSZWN0YW5nbGUyRCljbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBhbnkgcGFydCBvZiB0aGUgbGluZSBzZWdtZW50IGJldHdlZW4gKGFuZCBpbmNsdWRpbmcpCisgICAgICogdGhlIHR3byBnaXZlbiBwb2ludHMgdG91Y2hlcyBhbnkgcGFydCBvZiB0aGUgcmVjdGFuZ2xlLCBpbmNsdWRpbmcgaXRzCisgICAgICogYm91bmRhcnkuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIG9uZSBvZiB0aGUgcG9pbnRzIHRoYXQgZGV0ZXJtaW5lcyB0aGUgbGluZQorICAgICAqICAgICAgICAgICAgc2VnbWVudCB0byB0ZXN0LgorICAgICAqIEBwYXJhbSB5MQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiBvbmUgb2YgdGhlIHBvaW50cyB0aGF0IGRldGVybWluZXMgdGhlIGxpbmUKKyAgICAgKiAgICAgICAgICAgIHNlZ21lbnQgdG8gdGVzdC4KKyAgICAgKiBAcGFyYW0geDIKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2Ygb25lIG9mIHRoZSBwb2ludHMgdGhhdCBkZXRlcm1pbmVzIHRoZSBsaW5lCisgICAgICogICAgICAgICAgICBzZWdtZW50IHRvIHRlc3QuCisgICAgICogQHBhcmFtIHkyCisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIG9uZSBvZiB0aGUgcG9pbnRzIHRoYXQgZGV0ZXJtaW5lcyB0aGUgbGluZQorICAgICAqICAgICAgICAgICAgc2VnbWVudCB0byB0ZXN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgYXQgbGVhc3Qgb25lIHBvaW50IG9mIHRoZSBsaW5lIHNlZ21lbnQgYmV0d2VlbiB0aGUgdHdvCisgICAgICogICAgICAgICBwb2ludHMgbWF0Y2hlcyBhbnkgcG9pbnQgb2YgdGhlIGludGVyaW9yIG9mIHRoZSByZWN0YW5nbGUgb3IgdGhlCisgICAgICogICAgICAgICByZWN0YW5nbGUncyBib3VuZGFyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzTGluZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgZG91YmxlIHJ4MSA9IGdldFgoKTsKKyAgICAgICAgZG91YmxlIHJ5MSA9IGdldFkoKTsKKyAgICAgICAgZG91YmxlIHJ4MiA9IHJ4MSArIGdldFdpZHRoKCk7CisgICAgICAgIGRvdWJsZSByeTIgPSByeTEgKyBnZXRIZWlnaHQoKTsKKyAgICAgICAgcmV0dXJuIChyeDEgPD0geDEgJiYgeDEgPD0gcngyICYmIHJ5MSA8PSB5MSAmJiB5MSA8PSByeTIpCisgICAgICAgICAgICAgICAgfHwgKHJ4MSA8PSB4MiAmJiB4MiA8PSByeDIgJiYgcnkxIDw9IHkyICYmIHkyIDw9IHJ5MikKKyAgICAgICAgICAgICAgICB8fCBMaW5lMkQubGluZXNJbnRlcnNlY3QocngxLCByeTEsIHJ4MiwgcnkyLCB4MSwgeTEsIHgyLCB5MikKKyAgICAgICAgICAgICAgICB8fCBMaW5lMkQubGluZXNJbnRlcnNlY3QocngyLCByeTEsIHJ4MSwgcnkyLCB4MSwgeTEsIHgyLCB5Mik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFueSBwYXJ0IG9mIHRoZSBzcGVjaWZpZWQgbGluZSBzZWdtZW50IHRvdWNoZXMgYW55CisgICAgICogcGFydCBvZiB0aGUgcmVjdGFuZ2xlLCBpbmNsdWRpbmcgaXRzIGJvdW5kYXJ5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgbGluZSBzZWdtZW50IHRvIHRlc3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBhdCBsZWFzdCBvbmUgcG9pbnQgb2YgdGhlIGdpdmVuIGxpbmUgc2VnbWVudCBtYXRjaGVzIGFueQorICAgICAqICAgICAgICAgcG9pbnQgb2YgdGhlIGludGVyaW9yIG9mIHRoZSByZWN0YW5nbGUgb3IgdGhlIHJlY3RhbmdsZSdzCisgICAgICogICAgICAgICBib3VuZGFyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzTGluZShMaW5lMkQgbCkgeworICAgICAgICByZXR1cm4gaW50ZXJzZWN0c0xpbmUobC5nZXRYMSgpLCBsLmdldFkxKCksIGwuZ2V0WDIoKSwgbC5nZXRZMigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgcG9pbnQgd2l0aCByZXNwZWN0IHRvIHRoZSByZWN0YW5nbGUgYW5kIHBhY2tzCisgICAgICogdGhlIGluZm9ybWF0aW9uIGludG8gYSBzaW5nbGUgaW50ZWdlciB1c2luZyB0aGUgYml0bWFza3MKKyAgICAgKiB7QGxpbmsgUmVjdGFuZ2xlMkQjT1VUX0xFRlR9LCB7QGxpbmsgUmVjdGFuZ2xlMkQjT1VUX1JJR0hUfSwKKyAgICAgKiB7QGxpbmsgUmVjdGFuZ2xlMkQjT1VUX1RPUH0sIGFuZCB7QGxpbmsgUmVjdGFuZ2xlMkQjT1VUX0JPVFRPTX0uIElmIHRoZQorICAgICAqIHJlY3RhbmdsZSBoYXMgemVybyBvciBuZWdhdGl2ZSB3aWR0aCwgdGhlbiBldmVyeSBwb2ludCBpcyByZWdhcmRlZCBhcworICAgICAqIGJlaW5nIGJvdGggdG8gdGhlIGxlZnQgYW5kIHRvIHRoZSByaWdodCBvZiB0aGUgcmVjdGFuZ2xlLiBTaW1pbGFybHksIGlmCisgICAgICogdGhlIGhlaWdodCBpcyB6ZXJvIG9yIG5lZ2F0aXZlIHRoZW4gYWxsIHBvaW50cyBhcmUgY29uc2lkZXJlZCB0byBiZSBib3RoCisgICAgICogYm90aCBhYm92ZSBhbmQgYmVsb3cgaXQuCisgICAgICogCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHRoZSBwb2ludCdzIGxvY2F0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgb3V0Y29kZShQb2ludDJEIHApIHsKKyAgICAgICAgcmV0dXJuIG91dGNvZGUocC5nZXRYKCksIHAuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIHgxID0gZ2V0WCgpOworICAgICAgICBkb3VibGUgeTEgPSBnZXRZKCk7CisgICAgICAgIGRvdWJsZSB4MiA9IHgxICsgZ2V0V2lkdGgoKTsKKyAgICAgICAgZG91YmxlIHkyID0geTEgKyBnZXRIZWlnaHQoKTsKKworICAgICAgICByZXR1cm4geDEgPD0geCAmJiB4IDwgeDIgJiYgeTEgPD0geSAmJiB5IDwgeTI7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHdpZHRoIDw9IDAuMCB8fCBoZWlnaHQgPD0gMC4wKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgeDEgPSBnZXRYKCk7CisgICAgICAgIGRvdWJsZSB5MSA9IGdldFkoKTsKKyAgICAgICAgZG91YmxlIHgyID0geDEgKyBnZXRXaWR0aCgpOworICAgICAgICBkb3VibGUgeTIgPSB5MSArIGdldEhlaWdodCgpOworCisgICAgICAgIHJldHVybiB4ICsgd2lkdGggPiB4MSAmJiB4IDwgeDIgJiYgeSArIGhlaWdodCA+IHkxICYmIHkgPCB5MjsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHdpZHRoIDw9IDAuMCB8fCBoZWlnaHQgPD0gMC4wKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgeDEgPSBnZXRYKCk7CisgICAgICAgIGRvdWJsZSB5MSA9IGdldFkoKTsKKyAgICAgICAgZG91YmxlIHgyID0geDEgKyBnZXRXaWR0aCgpOworICAgICAgICBkb3VibGUgeTIgPSB5MSArIGdldEhlaWdodCgpOworCisgICAgICAgIHJldHVybiB4MSA8PSB4ICYmIHggKyB3aWR0aCA8PSB4MiAmJiB5MSA8PSB5ICYmIHkgKyBoZWlnaHQgPD0geTI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlcyB0aGUgZGF0YSB2YWx1ZXMgb2YgdGhlIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSB0byBtYXRjaCB0aGUKKyAgICAgKiBpbnRlcnNlY3Rpb24gb2YgdGhlIHR3byBzb3VyY2UgcmVjdGFuZ2xlcywgbGVhdmluZyB0aGUgdHdvIHNvdXJjZQorICAgICAqIHJlY3RhbmdsZXMgdW5jaGFuZ2VkLiBUaGUgcmVzdWx0aW5nIHJlY3RhbmdsZSBtYXkgYmUgZW1wdHkuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYzEKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgdHdvIHNvdXJjZSByZWN0YW5nbGVzIGdpdmluZyB0aGUgZGF0YSB0byBpbnRlcnNlY3QuCisgICAgICogQHBhcmFtIHNyYzIKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgdHdvIHNvdXJjZSByZWN0YW5nbGVzIGdpdmluZyB0aGUgZGF0YSB0byBpbnRlcnNlY3QuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIG9iamVjdCB3aGVyZSB0aGUgZGF0YSBvZiB0aGUgaW50ZXJzZWN0aW9uIGlzCisgICAgICogICAgICAgICAgICB3cml0dGVuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbnRlcnNlY3QoUmVjdGFuZ2xlMkQgc3JjMSwgUmVjdGFuZ2xlMkQgc3JjMiwgUmVjdGFuZ2xlMkQgZHN0KSB7CisgICAgICAgIGRvdWJsZSB4MSA9IE1hdGgubWF4KHNyYzEuZ2V0TWluWCgpLCBzcmMyLmdldE1pblgoKSk7CisgICAgICAgIGRvdWJsZSB5MSA9IE1hdGgubWF4KHNyYzEuZ2V0TWluWSgpLCBzcmMyLmdldE1pblkoKSk7CisgICAgICAgIGRvdWJsZSB4MiA9IE1hdGgubWluKHNyYzEuZ2V0TWF4WCgpLCBzcmMyLmdldE1heFgoKSk7CisgICAgICAgIGRvdWJsZSB5MiA9IE1hdGgubWluKHNyYzEuZ2V0TWF4WSgpLCBzcmMyLmdldE1heFkoKSk7CisgICAgICAgIGRzdC5zZXRGcmFtZSh4MSwgeTEsIHgyIC0geDEsIHkyIC0geTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoYW5nZXMgdGhlIGRhdGEgdmFsdWVzIG9mIHRoZSBkZXN0aW5hdGlvbiByZWN0YW5nbGUgdG8gbWF0Y2ggdGhlIHVuaW9uCisgICAgICogb2YgdGhlIHR3byBzb3VyY2UgcmVjdGFuZ2xlcywgbGVhdmluZyB0aGUgdHdvIHNvdXJjZSByZWN0YW5nbGVzCisgICAgICogdW5jaGFuZ2VkLiBUaGUgdW5pb24gaXMgdGhlIHNtYWxsZXN0IHJlY3RhbmdsZSB0aGF0IGNvbXBsZXRlbHkgY292ZXJzIHRoZQorICAgICAqIHR3byBzb3VyY2UgcmVjdGFuZ2xlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjMQorICAgICAqICAgICAgICAgICAgb25lIG9mIHRoZSB0d28gc291cmNlIHJlY3RhbmdsZXMgZ2l2aW5nIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSBzcmMyCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIHR3byBzb3VyY2UgcmVjdGFuZ2xlcyBnaXZpbmcgdGhlIGRhdGEuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIG9iamVjdCB3aGVyZSB0aGUgZGF0YSBvZiB0aGUgdW5pb24gaXMgd3JpdHRlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdW5pb24oUmVjdGFuZ2xlMkQgc3JjMSwgUmVjdGFuZ2xlMkQgc3JjMiwgUmVjdGFuZ2xlMkQgZHN0KSB7CisgICAgICAgIGRvdWJsZSB4MSA9IE1hdGgubWluKHNyYzEuZ2V0TWluWCgpLCBzcmMyLmdldE1pblgoKSk7CisgICAgICAgIGRvdWJsZSB5MSA9IE1hdGgubWluKHNyYzEuZ2V0TWluWSgpLCBzcmMyLmdldE1pblkoKSk7CisgICAgICAgIGRvdWJsZSB4MiA9IE1hdGgubWF4KHNyYzEuZ2V0TWF4WCgpLCBzcmMyLmdldE1heFgoKSk7CisgICAgICAgIGRvdWJsZSB5MiA9IE1hdGgubWF4KHNyYzEuZ2V0TWF4WSgpLCBzcmMyLmdldE1heFkoKSk7CisgICAgICAgIGRzdC5zZXRGcmFtZSh4MSwgeTEsIHgyIC0geDEsIHkyIC0geTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVubGFyZ2VzIHRoZSByZWN0YW5nbGUgc28gdGhhdCBpdCBpbmNsdWRlcyB0aGUgZ2l2ZW4gcG9pbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBwb2ludCB0byBiZSBjb3ZlcmVkIGJ5IHRoZQorICAgICAqICAgICAgICAgICAgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBuZXcgcG9pbnQgdG8gYmUgY292ZXJlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgIGRvdWJsZSB4MSA9IE1hdGgubWluKGdldE1pblgoKSwgeCk7CisgICAgICAgIGRvdWJsZSB5MSA9IE1hdGgubWluKGdldE1pblkoKSwgeSk7CisgICAgICAgIGRvdWJsZSB4MiA9IE1hdGgubWF4KGdldE1heFgoKSwgeCk7CisgICAgICAgIGRvdWJsZSB5MiA9IE1hdGgubWF4KGdldE1heFkoKSwgeSk7CisgICAgICAgIHNldFJlY3QoeDEsIHkxLCB4MiAtIHgxLCB5MiAtIHkxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmxhcmdlcyB0aGUgcmVjdGFuZ2xlIHNvIHRoYXQgaXQgaW5jbHVkZXMgdGhlIGdpdmVuIHBvaW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHBvaW50IHRvIGJlIGNvdmVyZWQgYnkgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoUG9pbnQyRCBwKSB7CisgICAgICAgIGFkZChwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVubGFyZ2VzIHRoZSByZWN0YW5nbGUgc28gdGhhdCBpdCBjb3ZlcnMgdGhlIGdpdmVuIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyByZWN0YW5nbGUgdG8gYmUgY292ZXJlZCBieSB0aGlzIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoUmVjdGFuZ2xlMkQgcikgeworICAgICAgICB1bmlvbih0aGlzLCByLCB0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKHRoaXMsIHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQYXRoSXRlcmF0b3IgZ2V0UGF0aEl0ZXJhdG9yKEFmZmluZVRyYW5zZm9ybSB0LCBkb3VibGUgZmxhdG5lc3MpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCB0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBIYXNoQ29kZSBoYXNoID0gbmV3IEhhc2hDb2RlKCk7CisgICAgICAgIGhhc2guYXBwZW5kKGdldFgoKSk7CisgICAgICAgIGhhc2guYXBwZW5kKGdldFkoKSk7CisgICAgICAgIGhhc2guYXBwZW5kKGdldFdpZHRoKCkpOworICAgICAgICBoYXNoLmFwcGVuZChnZXRIZWlnaHQoKSk7CisgICAgICAgIHJldHVybiBoYXNoLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgUmVjdGFuZ2xlMkQpIHsKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIHIgPSAoUmVjdGFuZ2xlMkQpb2JqOworICAgICAgICAgICAgcmV0dXJuIGdldFgoKSA9PSByLmdldFgoKSAmJiBnZXRZKCkgPT0gci5nZXRZKCkgJiYgZ2V0V2lkdGgoKSA9PSByLmdldFdpZHRoKCkKKyAgICAgICAgICAgICAgICAgICAgJiYgZ2V0SGVpZ2h0KCkgPT0gci5nZXRIZWlnaHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9SZWN0YW5ndWxhclNoYXBlLmphdmEgYi9hd3QvamF2YS9hd3QvZ2VvbS9SZWN0YW5ndWxhclNoYXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGIwZDA1YwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9nZW9tL1JlY3Rhbmd1bGFyU2hhcGUuamF2YQpAQCAtMCwwICsxLDI5NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuZ2VvbTsKKworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKKworLyoqCisgKiBUaGUgQ2xhc3MgUmVjdGFuZ3VsYXJTaGFwZSByZXByZXNlbnRzIGEgU2hhcGUgd2hvc2UgZGF0YSBpcyAoYXQgbGVhc3QKKyAqIHBhcnRpYWxseSkgZGVzY3JpYmVkIGJ5IGEgcmVjdGFuZ3VsYXIgZnJhbWUuIFRoaXMgaW5jbHVkZXMgc2hhcGVzIHdoaWNoIGFyZQorICogb2J2aW91c2x5IHJlY3Rhbmd1bGFyIChzdWNoIGFzIFJlY3RhbmdsZTJEKSBhcyB3ZWxsIGFzIHNoYXBlcyBsaWtlIEFyYzJECisgKiB3aGljaCBhcmUgbGFyZ2VseSBkZXRlcm1pbmVkIGJ5IHRoZSByZWN0YW5nbGUgdGhleSBmaXQgaW5zaWRlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFJlY3Rhbmd1bGFyU2hhcGUgaW1wbGVtZW50cyBTaGFwZSwgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyByZWN0YW5ndWxhciBzaGFwZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVjdGFuZ3VsYXJTaGFwZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0WCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFkoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFdpZHRoKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldEhlaWdodCgpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgaXMgYW4gZW1wdHkgcmVjdGFuZ2xlOiBvbmUgd2l0aCB6ZXJvIGFzIGl0cyB3aWR0aCBvcgorICAgICAqIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSB3aWR0aCBvciBoZWlnaHQgaXMgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNFbXB0eSgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBmb3IgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSBpbiB0ZXJtcyBvZiBkb3VibGUgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZyYW1lKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHcsIGRvdWJsZSBoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0geCB2YWx1ZSBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlICh0aGUgeCBjb29yZGluYXRlIG9mCisgICAgICogdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSByZWN0YW5nbGUpLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0geCB2YWx1ZSBvZiB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0TWluWCgpIHsKKyAgICAgICAgcmV0dXJuIGdldFgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHkgdmFsdWUgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSAodGhlIHkgY29vcmRpbmF0ZSBvZgorICAgICAqIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlKS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHkgdmFsdWUgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldE1pblkoKSB7CisgICAgICAgIHJldHVybiBnZXRZKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWF4aW11bSB4IHZhbHVlIG9mIHRoZSBib3VuZGluZyByZWN0YW5nbGUgKHRoZSB4IGNvb3JkaW5hdGUgb2YKKyAgICAgKiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZSBwbHVzIHRoZSByZWN0YW5nbGUncyB3aWR0aCkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSB4IHZhbHVlIG9mIHRoZSBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRNYXhYKCkgeworICAgICAgICByZXR1cm4gZ2V0WCgpICsgZ2V0V2lkdGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIHkgdmFsdWUgb2YgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSAodGhlIHkgY29vcmRpbmF0ZSBvZgorICAgICAqIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgcmVjdGFuZ2xlIHBsdXMgdGhlIHJlY3RhbmdsZSdzIGhlaWdodCkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSB5IHZhbHVlIG9mIHRoZSBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRNYXhZKCkgeworICAgICAgICByZXR1cm4gZ2V0WSgpICsgZ2V0SGVpZ2h0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRlciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0Q2VudGVyWCgpIHsKKyAgICAgICAgcmV0dXJuIGdldFgoKSArIGdldFdpZHRoKCkgLyAyLjA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRlciBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0Q2VudGVyWSgpIHsKKyAgICAgICAgcmV0dXJuIGdldFkoKSArIGdldEhlaWdodCgpIC8gMi4wOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBsYWNlcyB0aGUgcmVjdGFuZ2xlJ3Mgc2l6ZSBhbmQgbG9jYXRpb24gZGF0YSBpbiBhIG5ldyBSZWN0YW5nbGUyRCBvYmplY3QKKyAgICAgKiBhbmQgcmV0dXJucyBpdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZGluZyByZWN0YW5nbGUgYXMgYSBuZXcgUmVjdGFuZ2xlMkQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRGcmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoZ2V0WCgpLCBnZXRZKCksIGdldFdpZHRoKCksIGdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBib3VuZGluZyByZWN0YW5nbGUgaW4gdGVybXMgb2YgYSBQb2ludDJEIHdoaWNoIGdpdmVzIGl0cyB1cHBlcgorICAgICAqIGxlZnQgY29ybmVyIGFuZCBhIERpbWVuc2lvbjJEIG9iamVjdCBnaXZpbmcgaXRzIHdpZHRoIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIGxvYworICAgICAqICAgICAgICAgICAgdGhlIG5ldyB1cHBlciBsZWZ0IGNvcm5lciBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHNpemUgZGltZW5zaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZShQb2ludDJEIGxvYywgRGltZW5zaW9uMkQgc2l6ZSkgeworICAgICAgICBzZXRGcmFtZShsb2MuZ2V0WCgpLCBsb2MuZ2V0WSgpLCBzaXplLmdldFdpZHRoKCksIHNpemUuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSB0byBtYXRjaCB0aGUgZGF0YSBjb250YWluZWQgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIFJlY3RhbmdsZTJELgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgcmVjdGFuZ2xlIHRoYXQgZ2l2ZXMgdGhlIG5ldyBmcmFtZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZyYW1lKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgc2V0RnJhbWUoci5nZXRYKCksIHIuZ2V0WSgpLCByLmdldFdpZHRoKCksIHIuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZyYW1pbmcgcmVjdGFuZ2xlIGdpdmVuIHR3byBvcHBvc2l0ZSBjb3JuZXJzLiBBbnkgdHdvIGNvcm5lcnMKKyAgICAgKiBtYXkgYmUgdXNlZCBpbiBhbnkgb3JkZXIgYXMgbG9uZyBhcyB0aGV5IGFyZSBkaWFnb25hbGx5IG9wcG9zaXRlIG9uZQorICAgICAqIGFub3RoZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgxCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIG9uZSBvZiB0aGUgY29ybmVyIHBvaW50cy4KKyAgICAgKiBAcGFyYW0geTEKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2Ygb25lIG9mIHRoZSBjb3JuZXIgcG9pbnRzLgorICAgICAqIEBwYXJhbSB4MgorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgb3RoZXIgY29ybmVyIHBvaW50LgorICAgICAqIEBwYXJhbSB5MgorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgb3RoZXIgY29ybmVyIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZyYW1lRnJvbURpYWdvbmFsKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MikgeworICAgICAgICBkb3VibGUgcngsIHJ5LCBydywgcmg7CisgICAgICAgIGlmICh4MSA8IHgyKSB7CisgICAgICAgICAgICByeCA9IHgxOworICAgICAgICAgICAgcncgPSB4MiAtIHgxOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcnggPSB4MjsKKyAgICAgICAgICAgIHJ3ID0geDEgLSB4MjsKKyAgICAgICAgfQorICAgICAgICBpZiAoeTEgPCB5MikgeworICAgICAgICAgICAgcnkgPSB5MTsKKyAgICAgICAgICAgIHJoID0geTIgLSB5MTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJ5ID0geTI7CisgICAgICAgICAgICByaCA9IHkxIC0geTI7CisgICAgICAgIH0KKyAgICAgICAgc2V0RnJhbWUocngsIHJ5LCBydywgcmgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZyYW1pbmcgcmVjdGFuZ2xlIGdpdmVuIHR3byBvcHBvc2l0ZSBjb3JuZXJzLiBBbnkgdHdvIGNvcm5lcnMKKyAgICAgKiBtYXkgYmUgdXNlZCBpbiBhbnkgb3JkZXIgYXMgbG9uZyBhcyB0aGV5IGFyZSBkaWFnb25hbGx5IG9wcG9zaXRlIG9uZQorICAgICAqIGFub3RoZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHAxCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGNvcm5lciBwb2ludHMuCisgICAgICogQHBhcmFtIHAyCisgICAgICogICAgICAgICAgICB0aGUgb3RoZXIgY29ybmVyIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZyYW1lRnJvbURpYWdvbmFsKFBvaW50MkQgcDEsIFBvaW50MkQgcDIpIHsKKyAgICAgICAgc2V0RnJhbWVGcm9tRGlhZ29uYWwocDEuZ2V0WCgpLCBwMS5nZXRZKCksIHAyLmdldFgoKSwgcDIuZ2V0WSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmcmFtaW5nIHJlY3RhbmdsZSBnaXZlbiB0aGUgY2VudGVyIHBvaW50IGFuZCBvbmUgY29ybmVyLiBBbnkKKyAgICAgKiBjb3JuZXIgbWF5IGJlIHVzZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGNlbnRlclgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRlciBwb2ludC4KKyAgICAgKiBAcGFyYW0gY2VudGVyWQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIHBvaW50LgorICAgICAqIEBwYXJhbSBjb3JuZXJYCisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIG9uZSBvZiB0aGUgY29ybmVyIHBvaW50cy4KKyAgICAgKiBAcGFyYW0gY29ybmVyWQorICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiBvbmUgb2YgdGhlIGNvcm5lciBwb2ludHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RnJhbWVGcm9tQ2VudGVyKGRvdWJsZSBjZW50ZXJYLCBkb3VibGUgY2VudGVyWSwgZG91YmxlIGNvcm5lclgsIGRvdWJsZSBjb3JuZXJZKSB7CisgICAgICAgIGRvdWJsZSB3aWR0aCA9IE1hdGguYWJzKGNvcm5lclggLSBjZW50ZXJYKTsKKyAgICAgICAgZG91YmxlIGhlaWdodCA9IE1hdGguYWJzKGNvcm5lclkgLSBjZW50ZXJZKTsKKyAgICAgICAgc2V0RnJhbWUoY2VudGVyWCAtIHdpZHRoLCBjZW50ZXJZIC0gaGVpZ2h0LCB3aWR0aCAqIDIuMCwgaGVpZ2h0ICogMi4wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmcmFtaW5nIHJlY3RhbmdsZSBnaXZlbiB0aGUgY2VudGVyIHBvaW50IGFuZCBvbmUgY29ybmVyLiBBbnkKKyAgICAgKiBjb3JuZXIgbWF5IGJlIHVzZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGNlbnRlcgorICAgICAqICAgICAgICAgICAgdGhlIGNlbnRlciBwb2ludC4KKyAgICAgKiBAcGFyYW0gY29ybmVyCisgICAgICogICAgICAgICAgICBhIGNvcm5lciBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZUZyb21DZW50ZXIoUG9pbnQyRCBjZW50ZXIsIFBvaW50MkQgY29ybmVyKSB7CisgICAgICAgIHNldEZyYW1lRnJvbUNlbnRlcihjZW50ZXIuZ2V0WCgpLCBjZW50ZXIuZ2V0WSgpLCBjb3JuZXIuZ2V0WCgpLCBjb3JuZXIuZ2V0WSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludDJEIHBvaW50KSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhwb2ludC5nZXRYKCksIHBvaW50LmdldFkoKSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhSZWN0YW5nbGUyRCByZWN0KSB7CisgICAgICAgIHJldHVybiBpbnRlcnNlY3RzKHJlY3QuZ2V0WCgpLCByZWN0LmdldFkoKSwgcmVjdC5nZXRXaWR0aCgpLCByZWN0LmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhSZWN0YW5nbGUyRCByZWN0KSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhyZWN0LmdldFgoKSwgcmVjdC5nZXRZKCksIHJlY3QuZ2V0V2lkdGgoKSwgcmVjdC5nZXRIZWlnaHQoKSk7CisgICAgfQorCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKSB7CisgICAgICAgIGludCB4MSA9IChpbnQpTWF0aC5mbG9vcihnZXRNaW5YKCkpOworICAgICAgICBpbnQgeTEgPSAoaW50KU1hdGguZmxvb3IoZ2V0TWluWSgpKTsKKyAgICAgICAgaW50IHgyID0gKGludClNYXRoLmNlaWwoZ2V0TWF4WCgpKTsKKyAgICAgICAgaW50IHkyID0gKGludClNYXRoLmNlaWwoZ2V0TWF4WSgpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWN0YW5nbGUoeDEsIHkxLCB4MiAtIHgxLCB5MiAtIHkxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gdCwgZG91YmxlIGZsYXRuZXNzKSB7CisgICAgICAgIHJldHVybiBuZXcgRmxhdHRlbmluZ1BhdGhJdGVyYXRvcihnZXRQYXRoSXRlcmF0b3IodCksIGZsYXRuZXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9nZW9tL1JvdW5kUmVjdGFuZ2xlMkQuamF2YSBiL2F3dC9qYXZhL2F3dC9nZW9tL1JvdW5kUmVjdGFuZ2xlMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmJkZGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2dlb20vUm91bmRSZWN0YW5nbGUyRC5qYXZhCkBAIC0wLDAgKzEsNjM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5nZW9tOworCitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQ2xhc3MgUm91bmRSZWN0YW5nbGUyRCBkZXNjcmliZXMgYSByZWN0YW5nbGUgd2l0aCByb3VuZGVkIGNvcm5lcnMgd2l0aAorICogaGlnaC1wcmVjaXNpb24gZGF0YSB0aGF0IGlzIGFwcHJvcHJpYXRlIGZvciBnZW9tZXRyaWMgb3BlcmF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBSb3VuZFJlY3RhbmdsZTJEIGV4dGVuZHMgUmVjdGFuZ3VsYXJTaGFwZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRmxvYXQgaXMgdGhlIHN1YmNsYXNzIG9mIFJvdW5kUmVjdGFuZ2xlMkQgdGhhdCBoYXMgYWxsIG9mIGl0cworICAgICAqIGRhdGEgdmFsdWVzIHN0b3JlZCB3aXRoIGZsb2F0LWxldmVsIHByZWNpc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZsb2F0IGV4dGVuZHMgUm91bmRSZWN0YW5nbGUyRCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZsb2F0IHdpZHRoOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgaGVpZ2h0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYXJjIHdpZHRoIG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgYXJjd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBhcmMgaGVpZ2h0IG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmxvYXQgYXJjaGVpZ2h0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZmxvYXQtdmFsdWVkIFJvdW5kUmVjdGFuZ2xlMkQgd2l0aCBpdHMgZGF0YS12YWx1ZXMKKyAgICAgICAgICogc2V0IHRvIHplcm8uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmxvYXQoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZsb2F0LXZhbHVlZCBSb3VuZFJlY3RhbmdsZTJEIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAgICAgKiBkYXRhIHZhbHVlcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSB4CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKiBAcGFyYW0gYXJjd2lkdGgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgYXJjIHdpZHRoIG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICAgICAqIEBwYXJhbSBhcmNoZWlnaHQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgYXJjIGhlaWdodCBvZiB0aGUgcm91bmRlZCBjb3JuZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEZsb2F0KGZsb2F0IHgsIGZsb2F0IHksIGZsb2F0IHdpZHRoLCBmbG9hdCBoZWlnaHQsIGZsb2F0IGFyY3dpZHRoLCBmbG9hdCBhcmNoZWlnaHQpIHsKKyAgICAgICAgICAgIHNldFJvdW5kUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBhcmN3aWR0aCwgYXJjaGVpZ2h0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFgoKSB7CisgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFkoKSB7CisgICAgICAgICAgICByZXR1cm4geTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldFdpZHRoKCkgeworICAgICAgICAgICAgcmV0dXJuIHdpZHRoOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0SGVpZ2h0KCkgeworICAgICAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEFyY1dpZHRoKCkgeworICAgICAgICAgICAgcmV0dXJuIGFyY3dpZHRoOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0QXJjSGVpZ2h0KCkgeworICAgICAgICAgICAgcmV0dXJuIGFyY2hlaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIHdpZHRoIDw9IDAuMGYgfHwgaGVpZ2h0IDw9IDAuMGY7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgcm91bmQgcmVjdGFuZ2xlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICogQHBhcmFtIHkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICogQHBhcmFtIHdpZHRoCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICAgICAqIEBwYXJhbSBhcmN3aWR0aAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBhcmMgd2lkdGggb2YgdGhlIHJvdW5kZWQgY29ybmVycy4KKyAgICAgICAgICogQHBhcmFtIGFyY2hlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBhcmMgaGVpZ2h0IG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzZXRSb3VuZFJlY3QoZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgd2lkdGgsIGZsb2F0IGhlaWdodCwgZmxvYXQgYXJjd2lkdGgsCisgICAgICAgICAgICAgICAgZmxvYXQgYXJjaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICAgICAgdGhpcy5hcmN3aWR0aCA9IGFyY3dpZHRoOworICAgICAgICAgICAgdGhpcy5hcmNoZWlnaHQgPSBhcmNoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Um91bmRSZWN0KGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0LCBkb3VibGUgYXJjd2lkdGgsCisgICAgICAgICAgICAgICAgZG91YmxlIGFyY2hlaWdodCkgeworICAgICAgICAgICAgdGhpcy54ID0gKGZsb2F0KXg7CisgICAgICAgICAgICB0aGlzLnkgPSAoZmxvYXQpeTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSAoZmxvYXQpd2lkdGg7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IChmbG9hdCloZWlnaHQ7CisgICAgICAgICAgICB0aGlzLmFyY3dpZHRoID0gKGZsb2F0KWFyY3dpZHRoOworICAgICAgICAgICAgdGhpcy5hcmNoZWlnaHQgPSAoZmxvYXQpYXJjaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFJvdW5kUmVjdChSb3VuZFJlY3RhbmdsZTJEIHJyKSB7CisgICAgICAgICAgICB0aGlzLnggPSAoZmxvYXQpcnIuZ2V0WCgpOworICAgICAgICAgICAgdGhpcy55ID0gKGZsb2F0KXJyLmdldFkoKTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSAoZmxvYXQpcnIuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gKGZsb2F0KXJyLmdldEhlaWdodCgpOworICAgICAgICAgICAgdGhpcy5hcmN3aWR0aCA9IChmbG9hdClyci5nZXRBcmNXaWR0aCgpOworICAgICAgICAgICAgdGhpcy5hcmNoZWlnaHQgPSAoZmxvYXQpcnIuZ2V0QXJjSGVpZ2h0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZTJELkZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIERvdWJsZSBpcyB0aGUgc3ViY2xhc3Mgb2YgUm91bmRSZWN0YW5nbGUyRCB0aGF0IGhhcyBhbGwgb2YgaXRzCisgICAgICogZGF0YSB2YWx1ZXMgc3RvcmVkIHdpdGggZG91YmxlLWxldmVsIHByZWNpc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERvdWJsZSBleHRlbmRzIFJvdW5kUmVjdGFuZ2xlMkQgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUncyB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgeDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIHk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSB3aWR0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGRvdWJsZSBoZWlnaHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBhcmMgd2lkdGggb2YgdGhlIHJvdW5kZWQgY29ybmVycy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBkb3VibGUgYXJjd2lkdGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBhcmMgaGVpZ2h0IG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZG91YmxlIGFyY2hlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgUm91bmRSZWN0YW5nbGUyRCB3aXRoIGl0cworICAgICAgICAgKiBkYXRhLXZhbHVlcyBzZXQgdG8gemVyby4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoKSB7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRvdWJsZS12YWx1ZWQgUm91bmRSZWN0YW5nbGUyRCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogZGF0YSB2YWx1ZXMuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0geAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKiBAcGFyYW0geQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIGhlaWdodAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgICAgICogQHBhcmFtIGFyY3dpZHRoCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGFyYyB3aWR0aCBvZiB0aGUgcm91bmRlZCBjb3JuZXJzLgorICAgICAgICAgKiBAcGFyYW0gYXJjaGVpZ2h0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGFyYyBoZWlnaHQgb2YgdGhlIHJvdW5kZWQgY29ybmVycy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBEb3VibGUoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQsIGRvdWJsZSBhcmN3aWR0aCwKKyAgICAgICAgICAgICAgICBkb3VibGUgYXJjaGVpZ2h0KSB7CisgICAgICAgICAgICBzZXRSb3VuZFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCwgYXJjd2lkdGgsIGFyY2hlaWdodCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRYKCkgeworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRZKCkgeworICAgICAgICAgICAgcmV0dXJuIHk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEhlaWdodCgpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGRvdWJsZSBnZXRBcmNXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiBhcmN3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZG91YmxlIGdldEFyY0hlaWdodCgpIHsKKyAgICAgICAgICAgIHJldHVybiBhcmNoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aCA8PSAwLjAgfHwgaGVpZ2h0IDw9IDAuMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRSb3VuZFJlY3QoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQsIGRvdWJsZSBhcmN3aWR0aCwKKyAgICAgICAgICAgICAgICBkb3VibGUgYXJjaGVpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLnggPSB4OworICAgICAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICAgICAgdGhpcy5hcmN3aWR0aCA9IGFyY3dpZHRoOworICAgICAgICAgICAgdGhpcy5hcmNoZWlnaHQgPSBhcmNoZWlnaHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Um91bmRSZWN0KFJvdW5kUmVjdGFuZ2xlMkQgcnIpIHsKKyAgICAgICAgICAgIHRoaXMueCA9IHJyLmdldFgoKTsKKyAgICAgICAgICAgIHRoaXMueSA9IHJyLmdldFkoKTsKKyAgICAgICAgICAgIHRoaXMud2lkdGggPSByci5nZXRXaWR0aCgpOworICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSByci5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIHRoaXMuYXJjd2lkdGggPSByci5nZXRBcmNXaWR0aCgpOworICAgICAgICAgICAgdGhpcy5hcmNoZWlnaHQgPSByci5nZXRBcmNIZWlnaHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRG91YmxlKHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSb3VuZFJlY3RhbmdsZTJEIHBhdGggaXRlcmF0b3IKKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBUaGUgc3ViY2xhc3Mgb2YgUGF0aEl0ZXJhdG9yIHRvIHRyYXZlcnNlIGEgUm91bmRSZWN0YW5nbGUyRC4KKyAgICAgKi8KKyAgICBjbGFzcyBJdGVyYXRvciBpbXBsZW1lbnRzIFBhdGhJdGVyYXRvciB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUGF0aCBmb3Igcm91bmQgY29ybmVycyBnZW5lcmF0ZWQgdGhlIHNhbWUgd2F5IGFzIEVsbGlwc2UyRAorICAgICAgICAgKi8KKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNvZWZmaWNpZW50IHRvIGNhbGN1bGF0ZSBjb250cm9sIHBvaW50cyBvZiBCZXppZXIgY3VydmVzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHUgPSAwLjUgLSAyLjAgLyAzLjAgKiAoTWF0aC5zcXJ0KDIuMCkgLSAxLjApOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcG9pbnRzIGNvb3JkaW5hdGVzIGNhbGN1bGF0aW9uIHRhYmxlLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHBvaW50c1tdW10gPSB7CisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjUsIDAuMCwgMC4wCisgICAgICAgICAgICAgICAgfSwgLy8gTU9WRVRPCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgMS4wLCAtMC41LCAwLjAsIDAuMAorICAgICAgICAgICAgICAgIH0sIC8vIExJTkVUTworICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIDEuMCwgLXUsIDAuMCwgMC4wLCAvLyBDVUJJQ1RPCisgICAgICAgICAgICAgICAgICAgICAgICAxLjAsIDAuMCwgMC4wLCB1LCAxLjAsIDAuMCwgMC4wLCAwLjUKKyAgICAgICAgICAgICAgICB9LCB7CisgICAgICAgICAgICAgICAgICAgICAgICAxLjAsIDAuMCwgMS4wLCAtMC41CisgICAgICAgICAgICAgICAgfSwgLy8gTElORVRPCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgMS4wLCAwLjAsIDEuMCwgLXUsIC8vIENVQklDVE8KKyAgICAgICAgICAgICAgICAgICAgICAgIDEuMCwgLXUsIDEuMCwgMC4wLCAxLjAsIC0wLjUsIDEuMCwgMC4wCisgICAgICAgICAgICAgICAgfSwgeworICAgICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjUsIDEuMCwgMC4wCisgICAgICAgICAgICAgICAgfSwgLy8gTElORVRPCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgMC4wLCB1LCAxLjAsIDAuMCwgLy8gQ1VCSUNUTworICAgICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjAsIDEuMCwgLXUsIDAuMCwgMC4wLCAxLjAsIC0wLjUKKyAgICAgICAgICAgICAgICB9LCB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIDAuMCwgMC4wLCAwLjUKKyAgICAgICAgICAgICAgICB9LCAvLyBMSU5FVE8KKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIDAuMCwgMC4wLCB1LCAvLyBDVUJJQ1RPCisgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIHUsIDAuMCwgMC4wLCAwLjAsIDAuNSwgMC4wLCAwLjAKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzZWdtZW50IHR5cGVzIGNvcnJlc3BvbmQgdG8gcG9pbnRzIGFycmF5LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHR5cGVzW10gPSB7CisgICAgICAgICAgICAgICAgU0VHX01PVkVUTywgU0VHX0xJTkVUTywgU0VHX0NVQklDVE8sIFNFR19MSU5FVE8sIFNFR19DVUJJQ1RPLCBTRUdfTElORVRPLAorICAgICAgICAgICAgICAgIFNFR19DVUJJQ1RPLCBTRUdfTElORVRPLCBTRUdfQ1VCSUNUTworICAgICAgICB9OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgeCBjb29yZGluYXRlIG9mIGxlZnQtdXBwZXIgY29ybmVyIG9mIHRoZSByb3VuZCByZWN0YW5nbGUgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB5IGNvb3JkaW5hdGUgb2YgbGVmdC11cHBlciBjb3JuZXIgb2YgdGhlIHJvdW5kIHJlY3RhbmdsZSBib3VuZHMuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgeTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHdpZHRoIG9mIHRoZSByb3VuZCByZWN0YW5nbGUgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIHdpZHRoOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgaGVpZ2h0IG9mIHRoZSByb3VuZCByZWN0YW5nbGUgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgZG91YmxlIGhlaWdodDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHdpZHRoIG9mIGFyYyBjb3JuZXJzIG9mIHRoZSByb3VuZCByZWN0YW5nbGUuCisgICAgICAgICAqLworICAgICAgICBkb3VibGUgYXc7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBoZWlnaHQgb2YgYXJjIGNvcm5lcnMgb2YgdGhlIHJvdW5kIHJlY3RhbmdsZS4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBhaDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBhdGggaXRlcmF0b3IgdHJhbnNmb3JtYXRpb24uCisgICAgICAgICAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGN1cnJlbnQgc2VnbWVudCBpbmRleC4KKyAgICAgICAgICovCisgICAgICAgIGludCBpbmRleDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBSb3VuZFJlY3RhbmdsZTJELkl0ZXJhdG9yIGZvciBnaXZlbiByb3VuZCByZWN0YW5nbGUKKyAgICAgICAgICogYW5kIHRyYW5zZm9ybWF0aW9uLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHJyCisgICAgICAgICAqICAgICAgICAgICAgLSB0aGUgc291cmNlIFJvdW5kUmVjdGFuZ2xlMkQgb2JqZWN0CisgICAgICAgICAqIEBwYXJhbSBhdAorICAgICAgICAgKiAgICAgICAgICAgIC0gdGhlIEFmZmluZVRyYW5zZm9ybSBvYmplY3QgdG8gYXBwbHkgcmVjdGFuZ2xlIHBhdGgKKyAgICAgICAgICovCisgICAgICAgIEl0ZXJhdG9yKFJvdW5kUmVjdGFuZ2xlMkQgcnIsIEFmZmluZVRyYW5zZm9ybSBhdCkgeworICAgICAgICAgICAgdGhpcy54ID0gcnIuZ2V0WCgpOworICAgICAgICAgICAgdGhpcy55ID0gcnIuZ2V0WSgpOworICAgICAgICAgICAgdGhpcy53aWR0aCA9IHJyLmdldFdpZHRoKCk7CisgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHJyLmdldEhlaWdodCgpOworICAgICAgICAgICAgdGhpcy5hdyA9IE1hdGgubWluKHdpZHRoLCByci5nZXRBcmNXaWR0aCgpKTsKKyAgICAgICAgICAgIHRoaXMuYWggPSBNYXRoLm1pbihoZWlnaHQsIHJyLmdldEFyY0hlaWdodCgpKTsKKyAgICAgICAgICAgIHRoaXMudCA9IGF0OworICAgICAgICAgICAgaWYgKHdpZHRoIDwgMC4wIHx8IGhlaWdodCA8IDAuMCB8fCBhdyA8IDAuMCB8fCBhaCA8IDAuMCkgeworICAgICAgICAgICAgICAgIGluZGV4ID0gcG9pbnRzLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0V2luZGluZ1J1bGUoKSB7CisgICAgICAgICAgICByZXR1cm4gV0lORF9OT05fWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCA+IHBvaW50cy5sZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBuZXh0KCkgeworICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW5kZXggPT0gcG9pbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBTRUdfQ0xPU0U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgaiA9IDA7CisgICAgICAgICAgICBkb3VibGUgcFtdID0gcG9pbnRzW2luZGV4XTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkgKz0gNCkgeworICAgICAgICAgICAgICAgIGNvb3Jkc1tqKytdID0geCArIHBbaSArIDBdICogd2lkdGggKyBwW2kgKyAxXSAqIGF3OworICAgICAgICAgICAgICAgIGNvb3Jkc1tqKytdID0geSArIHBbaSArIDJdICogaGVpZ2h0ICsgcFtpICsgM10gKiBhaDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgaiAvIDIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHR5cGVzW2luZGV4XTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZmxvYXRbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC40Qj1JdGVyYXRvciBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpbmRleCA9PSBwb2ludHMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFNFR19DTE9TRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIGRvdWJsZSBwW10gPSBwb2ludHNbaW5kZXhdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSArPSA0KSB7CisgICAgICAgICAgICAgICAgY29vcmRzW2orK10gPSAoZmxvYXQpKHggKyBwW2kgKyAwXSAqIHdpZHRoICsgcFtpICsgMV0gKiBhdyk7CisgICAgICAgICAgICAgICAgY29vcmRzW2orK10gPSAoZmxvYXQpKHkgKyBwW2kgKyAyXSAqIGhlaWdodCArIHBbaSArIDNdICogYWgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCBqIC8gMik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZXNbaW5kZXhdOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgUm91bmRSZWN0YW5nbGUyRC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUm91bmRSZWN0YW5nbGUyRCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcmMgd2lkdGguCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJjIHdpZHRoLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0QXJjV2lkdGgoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFyYyBoZWlnaHQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJjIGhlaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldEFyY0hlaWdodCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgUm91bmRSZWN0YW5nbGUyRC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlJ3MgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSdzIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBhcmNXaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIGFyYyB3aWR0aCBvZiB0aGUgcm91bmRlZCBjb3JuZXJzLgorICAgICAqIEBwYXJhbSBhcmNIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmMgaGVpZ2h0IG9mIHRoZSByb3VuZGVkIGNvcm5lcnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Um91bmRSZWN0KGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0LAorICAgICAgICAgICAgZG91YmxlIGFyY1dpZHRoLCBkb3VibGUgYXJjSGVpZ2h0KTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2YgdGhlIFJvdW5kUmVjdGFuZ2xlMkQgYnkgY29weWluZyB0aGUgdmFsdWVzIGZyb20gYW4KKyAgICAgKiBleGlzdGluZyBSb3VuZFJlY3RhbmdsZTJELgorICAgICAqIAorICAgICAqIEBwYXJhbSBycgorICAgICAqICAgICAgICAgICAgdGhlIHJvdW5kIHJlY3RhbmdsZSB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Um91bmRSZWN0KFJvdW5kUmVjdGFuZ2xlMkQgcnIpIHsKKyAgICAgICAgc2V0Um91bmRSZWN0KHJyLmdldFgoKSwgcnIuZ2V0WSgpLCByci5nZXRXaWR0aCgpLCByci5nZXRIZWlnaHQoKSwgcnIuZ2V0QXJjV2lkdGgoKSwgcnIKKyAgICAgICAgICAgICAgICAuZ2V0QXJjSGVpZ2h0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZyYW1lKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KSB7CisgICAgICAgIHNldFJvdW5kUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBnZXRBcmNXaWR0aCgpLCBnZXRBcmNIZWlnaHQoKSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoZG91YmxlIHB4LCBkb3VibGUgcHkpIHsKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIHJ4MSA9IGdldFgoKTsKKyAgICAgICAgZG91YmxlIHJ5MSA9IGdldFkoKTsKKyAgICAgICAgZG91YmxlIHJ4MiA9IHJ4MSArIGdldFdpZHRoKCk7CisgICAgICAgIGRvdWJsZSByeTIgPSByeTEgKyBnZXRIZWlnaHQoKTsKKworICAgICAgICBpZiAocHggPCByeDEgfHwgcHggPj0gcngyIHx8IHB5IDwgcnkxIHx8IHB5ID49IHJ5MikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIGF3ID0gZ2V0QXJjV2lkdGgoKSAvIDIuMDsKKyAgICAgICAgZG91YmxlIGFoID0gZ2V0QXJjSGVpZ2h0KCkgLyAyLjA7CisKKyAgICAgICAgZG91YmxlIGN4LCBjeTsKKworICAgICAgICBpZiAocHggPCByeDEgKyBhdykgeworICAgICAgICAgICAgY3ggPSByeDEgKyBhdzsKKyAgICAgICAgfSBlbHNlIGlmIChweCA+IHJ4MiAtIGF3KSB7CisgICAgICAgICAgICBjeCA9IHJ4MiAtIGF3OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAocHkgPCByeTEgKyBhaCkgeworICAgICAgICAgICAgY3kgPSByeTEgKyBhaDsKKyAgICAgICAgfSBlbHNlIGlmIChweSA+IHJ5MiAtIGFoKSB7CisgICAgICAgICAgICBjeSA9IHJ5MiAtIGFoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBweCA9IChweCAtIGN4KSAvIGF3OworICAgICAgICBweSA9IChweSAtIGN5KSAvIGFoOworICAgICAgICByZXR1cm4gcHggKiBweCArIHB5ICogcHkgPD0gMS4wOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGludGVyc2VjdHMoZG91YmxlIHJ4LCBkb3VibGUgcnksIGRvdWJsZSBydywgZG91YmxlIHJoKSB7CisgICAgICAgIGlmIChpc0VtcHR5KCkgfHwgcncgPD0gMC4wIHx8IHJoIDw9IDAuMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIHgxID0gZ2V0WCgpOworICAgICAgICBkb3VibGUgeTEgPSBnZXRZKCk7CisgICAgICAgIGRvdWJsZSB4MiA9IHgxICsgZ2V0V2lkdGgoKTsKKyAgICAgICAgZG91YmxlIHkyID0geTEgKyBnZXRIZWlnaHQoKTsKKworICAgICAgICBkb3VibGUgcngxID0gcng7CisgICAgICAgIGRvdWJsZSByeTEgPSByeTsKKyAgICAgICAgZG91YmxlIHJ4MiA9IHJ4ICsgcnc7CisgICAgICAgIGRvdWJsZSByeTIgPSByeSArIHJoOworCisgICAgICAgIGlmIChyeDIgPCB4MSB8fCB4MiA8IHJ4MSB8fCByeTIgPCB5MSB8fCB5MiA8IHJ5MSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIGN4ID0gKHgxICsgeDIpIC8gMi4wOworICAgICAgICBkb3VibGUgY3kgPSAoeTEgKyB5MikgLyAyLjA7CisKKyAgICAgICAgZG91YmxlIG54ID0gY3ggPCByeDEgPyByeDEgOiAoY3ggPiByeDIgPyByeDIgOiBjeCk7CisgICAgICAgIGRvdWJsZSBueSA9IGN5IDwgcnkxID8gcnkxIDogKGN5ID4gcnkyID8gcnkyIDogY3kpOworCisgICAgICAgIHJldHVybiBjb250YWlucyhueCwgbnkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGRvdWJsZSByeCwgZG91YmxlIHJ5LCBkb3VibGUgcncsIGRvdWJsZSByaCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHJ3IDw9IDAuMCB8fCByaCA8PSAwLjApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSByeDEgPSByeDsKKyAgICAgICAgZG91YmxlIHJ5MSA9IHJ5OworICAgICAgICBkb3VibGUgcngyID0gcnggKyBydzsKKyAgICAgICAgZG91YmxlIHJ5MiA9IHJ5ICsgcmg7CisKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zKHJ4MSwgcnkxKSAmJiBjb250YWlucyhyeDIsIHJ5MSkgJiYgY29udGFpbnMocngyLCByeTIpICYmIGNvbnRhaW5zKHJ4MSwgcnkyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUGF0aEl0ZXJhdG9yIGdldFBhdGhJdGVyYXRvcihBZmZpbmVUcmFuc2Zvcm0gYXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcih0aGlzLCBhdCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvZ2VvbS9wYWNrYWdlLmh0bWwgYi9hd3QvamF2YS9hd3QvZ2VvbS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTNhMjM2ZQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9nZW9tL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBjb250YWlucyBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIHJlbGF0ZWQgdG8gSmF2YTJEIHNoYXBlcyBhbmQgZ2VvbWV0cnkuCisgICAgPC9wPgorICAgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW0vSW5wdXRDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvaW0vSW5wdXRDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NlNTE0OAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbS9JbnB1dENvbnRleHQuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmltOworCitpbXBvcnQgamF2YS5hd3QuQVdURXZlbnQ7CisvLz8/P0FXVDogaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbS5JbnB1dE1ldGhvZENvbnRleHQ7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbnB1dENvbnRleHQgeworICAgIHByb3RlY3RlZCBJbnB1dENvbnRleHQoKSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBJbnB1dENvbnRleHQgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgSW5wdXRNZXRob2RDb250ZXh0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGlzcGF0Y2hFdmVudChBV1RFdmVudCBldmVudCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kQ29tcG9zaXRpb24oKSB7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRJbnB1dE1ldGhvZENvbnRyb2xPYmplY3QoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBvc2l0aW9uRW5hYmxlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlY29udmVydCgpIHsKKyAgICB9CisKKyAgICAvLz8/P0FXVAorICAgIC8qCisgICAgcHVibGljIHZvaWQgcmVtb3ZlTm90aWZ5KENvbXBvbmVudCBjbGllbnQpIHsKKyAgICB9CisgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIHNlbGVjdElucHV0TWV0aG9kKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN1YnNldHMoQ2hhcmFjdGVyLlN1YnNldFtdIHN1YnNldHMpIHsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgc2V0Q29tcG9zaXRpb25FbmFibGVkKGJvb2xlYW4gZW5hYmxlKSB7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW0vSW5wdXRNZXRob2RIaWdobGlnaHQuamF2YSBiL2F3dC9qYXZhL2F3dC9pbS9JbnB1dE1ldGhvZEhpZ2hsaWdodC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2NWQ0N2MKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW0vSW5wdXRNZXRob2RIaWdobGlnaHQuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5pbTsKKworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbnB1dE1ldGhvZEhpZ2hsaWdodCB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSQVdfVEVYVCA9IDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT05WRVJURURfVEVYVCA9IDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIElucHV0TWV0aG9kSGlnaGxpZ2h0CisgICAgICAgIFVOU0VMRUNURURfUkFXX1RFWFRfSElHSExJR0hUID0gbmV3IElucHV0TWV0aG9kSGlnaGxpZ2h0KGZhbHNlLCBSQVdfVEVYVCk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIElucHV0TWV0aG9kSGlnaGxpZ2h0CisgICAgICAgIFNFTEVDVEVEX1JBV19URVhUX0hJR0hMSUdIVCA9IG5ldyBJbnB1dE1ldGhvZEhpZ2hsaWdodCh0cnVlLCBSQVdfVEVYVCk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIElucHV0TWV0aG9kSGlnaGxpZ2h0CisgICAgICAgIFVOU0VMRUNURURfQ09OVkVSVEVEX1RFWFRfSElHSExJR0hUID0gCisgICAgICAgICAgICBuZXcgSW5wdXRNZXRob2RIaWdobGlnaHQoZmFsc2UsIENPTlZFUlRFRF9URVhUKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5wdXRNZXRob2RIaWdobGlnaHQKKyAgICAgICAgU0VMRUNURURfQ09OVkVSVEVEX1RFWFRfSElHSExJR0hUID0gCisgICAgICAgICAgICBuZXcgSW5wdXRNZXRob2RIaWdobGlnaHQodHJ1ZSwgQ09OVkVSVEVEX1RFWFQpOworICAgIAorICAgIHByaXZhdGUgYm9vbGVhbiBzZWxlY3RlZDsKKyAgICBwcml2YXRlIGludCBzdGF0ZTsKKyAgICBwcml2YXRlIGludCB2YXJpYXRpb247CisgICAgcHJpdmF0ZSBNYXA8VGV4dEF0dHJpYnV0ZSw/PiBzdHlsZTsKKworICAgIHB1YmxpYyBJbnB1dE1ldGhvZEhpZ2hsaWdodChib29sZWFuIHNlbGVjdGVkLCBpbnQgc3RhdGUsIGludCB2YXJpYXRpb24pIHsKKyAgICAgICAgdGhpcyhzZWxlY3RlZCwgc3RhdGUsIHZhcmlhdGlvbiwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIElucHV0TWV0aG9kSGlnaGxpZ2h0KGJvb2xlYW4gc2VsZWN0ZWQsIGludCBzdGF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhcmlhdGlvbiwgTWFwPGphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZSwgPz4gc3R5bGUpIHsKKyAgICAgICAgaWYgKChzdGF0ZSAhPSBSQVdfVEVYVCkgJiYgKHN0YXRlICE9IENPTlZFUlRFRF9URVhUKSkgeworICAgICAgICAgICAgLy8gYXd0LjIwQj11bmtub3duIGlucHV0IG1ldGhvZCBoaWdobGlnaHQgc3RhdGUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjBCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zZWxlY3RlZCA9IHNlbGVjdGVkOworICAgICAgICB0aGlzLnN0YXRlID0gc3RhdGU7CisgICAgICAgIHRoaXMudmFyaWF0aW9uID0gdmFyaWF0aW9uOworICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7CisgICAgfQorCisgICAgcHVibGljIElucHV0TWV0aG9kSGlnaGxpZ2h0KGJvb2xlYW4gc2VsZWN0ZWQsIGludCBzdGF0ZSkgeworICAgICAgICB0aGlzKHNlbGVjdGVkLCBzdGF0ZSwgMCwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0YXRlOworICAgIH0KKworICAgIHB1YmxpYyBNYXA8amF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlLCA/PiBnZXRTdHlsZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0eWxlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0VmFyaWF0aW9uKCkgeworICAgICAgICByZXR1cm4gdmFyaWF0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzU2VsZWN0ZWQoKSB7CisgICAgICAgIHJldHVybiBzZWxlY3RlZDsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbS9JbnB1dE1ldGhvZFJlcXVlc3RzLmphdmEgYi9hd3QvamF2YS9hd3QvaW0vSW5wdXRNZXRob2RSZXF1ZXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMmQzOTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW0vSW5wdXRNZXRob2RSZXF1ZXN0cy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuaW07CisKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0SGl0SW5mbzsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIElucHV0TWV0aG9kUmVxdWVzdHMgeworCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBjYW5jZWxMYXRlc3RDb21taXR0ZWRUZXh0KEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzKTsKKworICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZ2V0Q29tbWl0dGVkVGV4dChpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4LCBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlW10gYXR0cmlidXRlcyk7CisKKyAgICBwdWJsaWMgaW50IGdldENvbW1pdHRlZFRleHRMZW5ndGgoKTsKKworICAgIHB1YmxpYyBpbnQgZ2V0SW5zZXJ0UG9zaXRpb25PZmZzZXQoKTsKKworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXRMb2NhdGlvbk9mZnNldChpbnQgeCwgaW50IHkpOworCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBnZXRTZWxlY3RlZFRleHQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMpOworCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRUZXh0TG9jYXRpb24oVGV4dEhpdEluZm8gb2Zmc2V0KTsKK30KKwpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltL0lucHV0U3Vic2V0LmphdmEgYi9hd3QvamF2YS9hd3QvaW0vSW5wdXRTdWJzZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDg4ODFlCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltL0lucHV0U3Vic2V0LmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuaW07CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnB1dFN1YnNldCBleHRlbmRzIENoYXJhY3Rlci5TdWJzZXQgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCBMQVRJTiA9IG5ldyBJbnB1dFN1YnNldCgiTEFUSU4iKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCAKKyAgICAgICAgTEFUSU5fRElHSVRTID0gbmV3IElucHV0U3Vic2V0KCJMQVRJTl9ESUdJVFMiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCAKKyAgICAgICAgVFJBRElUSU9OQUxfSEFOWkkgPSBuZXcgSW5wdXRTdWJzZXQoIlRSQURJVElPTkFMX0hBTlpJIik7IC8vJE5PTi1OTFMtMSQKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5wdXRTdWJzZXQgCisgICAgICAgIFNJTVBMSUZJRURfSEFOWkkgPSBuZXcgSW5wdXRTdWJzZXQoIlNJTVBMSUZJRURfSEFOWkkiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCBLQU5KSSA9IG5ldyBJbnB1dFN1YnNldCgiS0FOSkkiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCBIQU5KQSA9IG5ldyBJbnB1dFN1YnNldCgiSEFOSkEiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCAKKyAgICAgICAgSEFMRldJRFRIX0tBVEFLQU5BID0gbmV3IElucHV0U3Vic2V0KCJIQUxGV0lEVEhfS0FUQUtBTkEiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCAKKyAgICAgICAgRlVMTFdJRFRIX0xBVElOID0gbmV3IElucHV0U3Vic2V0KCJGVUxMV0lEVEhfTEFUSU4iKTsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN1YnNldCAKKyAgICAgICAgRlVMTFdJRFRIX0RJR0lUUyA9IG5ldyBJbnB1dFN1YnNldCgiRlVMTFdJRFRIX0RJR0lUUyIpOyAvLyROT04tTkxTLTEkCisKKyAgICBwcml2YXRlIElucHV0U3Vic2V0KFN0cmluZyBuYW1lKSB7CisgICAgICAgIHN1cGVyKG5hbWUpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltL3NwaS9JbnB1dE1ldGhvZC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltL3NwaS9JbnB1dE1ldGhvZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3YTg4MzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW0vc3BpL0lucHV0TWV0aG9kLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5pbS5zcGk7CisKK2ltcG9ydCBqYXZhLmF3dC5BV1RFdmVudDsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gQW5kcm9pZCAxLjAuIEl0IGlzIG1lcmVseSBwcm92aWRlZCB0byBtYWludGFpbgorICogaW50ZXJmYWNlIGNvbXBhdGliaWxpdHkgd2l0aCBkZXNrdG9wIEphdmEgaW1wbGVtZW50YXRpb25zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJbnB1dE1ldGhvZCB7CisKKyAgICBwdWJsaWMgdm9pZCBhY3RpdmF0ZSgpOworCisgICAgcHVibGljIHZvaWQgZGVhY3RpdmF0ZShib29sZWFuIGlzVGVtcG9yYXJ5KTsKKworICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZXZlbnQpOworCisgICAgcHVibGljIHZvaWQgZGlzcG9zZSgpOworCisgICAgcHVibGljIHZvaWQgZW5kQ29tcG9zaXRpb24oKTsKKworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udHJvbE9iamVjdCgpOworCisgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKTsKKworICAgIHB1YmxpYyB2b2lkIGhpZGVXaW5kb3dzKCk7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBvc2l0aW9uRW5hYmxlZCgpOworCisgICAgcHVibGljIHZvaWQgbm90aWZ5Q2xpZW50V2luZG93Q2hhbmdlKFJlY3RhbmdsZSBib3VuZHMpOworCisgICAgcHVibGljIHZvaWQgcmVjb252ZXJ0KCk7CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVOb3RpZnkoKTsKKworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN1YnNldHMoQ2hhcmFjdGVyLlN1YnNldFtdIHN1YnNldHMpOworCisgICAgcHVibGljIHZvaWQgc2V0Q29tcG9zaXRpb25FbmFibGVkKGJvb2xlYW4gZW5hYmxlKTsKKworICAgIHB1YmxpYyB2b2lkIHNldElucHV0TWV0aG9kQ29udGV4dChJbnB1dE1ldGhvZENvbnRleHQgY29udGV4dCk7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSk7Cit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbS9zcGkvSW5wdXRNZXRob2RDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvaW0vc3BpL0lucHV0TWV0aG9kQ29udGV4dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmYzc3M2MKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW0vc3BpL0lucHV0TWV0aG9kQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuaW0uc3BpOworCisvLz8/P0FXVDogaW1wb3J0IGphdmEuYXd0LldpbmRvdzsKK2ltcG9ydCBqYXZhLmF3dC5mb250LlRleHRIaXRJbmZvOworaW1wb3J0IGphdmEuYXd0LmltLklucHV0TWV0aG9kUmVxdWVzdHM7CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcjsKKy8vPz8/QVdUOiBpbXBvcnQgamF2YXguc3dpbmcuSkZyYW1lOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIDEuMC4gSXQgaXMgbWVyZWx5IHByb3ZpZGVkIHRvIG1haW50YWluCisgKiBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSB3aXRoIGRlc2t0b3AgSmF2YSBpbXBsZW1lbnRhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIElucHV0TWV0aG9kQ29udGV4dCBleHRlbmRzIElucHV0TWV0aG9kUmVxdWVzdHMgeworCisvLyAgICA/Pz9BV1Q6IHB1YmxpYyBKRnJhbWUgY3JlYXRlSW5wdXRNZXRob2RKRnJhbWUoU3RyaW5nIHRpdGxlLCBib29sZWFuIGF0dGFjaFRvSW5wdXRDb250ZXh0KTsKKworLy8gICAgPz8/QVdUOiBwdWJsaWMgV2luZG93IGNyZWF0ZUlucHV0TWV0aG9kV2luZG93KFN0cmluZyB0aXRsZSwgYm9vbGVhbiBhdHRhY2hUb0lucHV0Q29udGV4dCk7CisKKyAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaElucHV0TWV0aG9kRXZlbnQoaW50IGlkLCBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgdGV4dCwgaW50IGNvbW1pdHRlZENoYXJhY3RlckNvdW50LCBUZXh0SGl0SW5mbyBjYXJldCwgVGV4dEhpdEluZm8gdmlzaWJsZVBvc2l0aW9uKTsKKworICAgIHB1YmxpYyB2b2lkIGVuYWJsZUNsaWVudFdpbmRvd05vdGlmaWNhdGlvbihJbnB1dE1ldGhvZCBpbnB1dE1ldGhvZCwgYm9vbGVhbiBlbmFibGUpOworCit9CisKZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbS9zcGkvSW5wdXRNZXRob2REZXNjcmlwdG9yLmphdmEgYi9hd3QvamF2YS9hd3QvaW0vc3BpL0lucHV0TWV0aG9kRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4MDBiYzEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW0vc3BpL0lucHV0TWV0aG9kRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuaW0uc3BpOworCitpbXBvcnQgamF2YS5hd3QuQVdURXhjZXB0aW9uOworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBub3Qgc3VwcG9ydGVkIGluIEFuZHJvaWQgMS4wLiBJdCBpcyBtZXJlbHkgcHJvdmlkZWQgdG8gbWFpbnRhaW4KKyAqIGludGVyZmFjZSBjb21wYXRpYmlsaXR5IHdpdGggZGVza3RvcCBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSW5wdXRNZXRob2REZXNjcmlwdG9yIHsKKworICAgIHB1YmxpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgdGhyb3dzIEFXVEV4Y2VwdGlvbjsKKworICAgIHB1YmxpYyBJbnB1dE1ldGhvZCBjcmVhdGVJbnB1dE1ldGhvZCgpIHRocm93cyBFeGNlcHRpb247CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldElucHV0TWV0aG9kRGlzcGxheU5hbWUoTG9jYWxlIGlucHV0TG9jYWxlLCBMb2NhbGUgZGlzcGxheUxhbmd1YWdlKTsKKworICAgIHB1YmxpYyBJbWFnZSBnZXRJbnB1dE1ldGhvZEljb24oTG9jYWxlIGlucHV0TG9jYWxlKTsKKworICAgIHB1YmxpYyBib29sZWFuIGhhc0R5bmFtaWNMb2NhbGVMaXN0KCk7CisKK30KKwpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0FmZmluZVRyYW5zZm9ybU9wLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQWZmaW5lVHJhbnNmb3JtT3AuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjI1ZTFhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0FmZmluZVRyYW5zZm9ybU9wLmphdmEKQEAgLTAsMCArMSw2MTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreSwgRGVuaXMgTS4gS2lzaGVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Ob25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBBZmZpbmVUcmFuc2Zvcm0gY2xhc3MgdHJhbnNsYXRlcyBjb29yZGluYXRlcyBmcm9tIDJEIGNvb3JkaW5hdGVzIGluIHRoZQorICogc291cmNlIGltYWdlIG9yIFJhc3RlciB0byAyRCBjb29yZGluYXRlcyBpbiB0aGUgZGVzdGluYXRpb24gaW1hZ2Ugb3IgUmFzdGVyCisgKiB1c2luZyBhZmZpbmUgdHJhbnNmb3JtYXRpb24uIFRoZSBudW1iZXIgb2YgYmFuZHMgaW4gdGhlIHNvdXJjZSBSYXN0ZXIgc2hvdWxkCisgKiBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZSBkZXN0aW5hdGlvbiBSYXN0ZXIuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQWZmaW5lVHJhbnNmb3JtT3AgaW1wbGVtZW50cyBCdWZmZXJlZEltYWdlT3AsIFJhc3Rlck9wIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX05FQVJFU1RfTkVJR0hCT1IgaW5kaWNhdGVzIG5lYXJlc3QtbmVpZ2hib3IKKyAgICAgKiBpbnRlcnBvbGF0aW9uIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9ORUFSRVNUX05FSUdIQk9SID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0JJTElORUFSIGluZGljYXRlcyBiaWxpbmVhciBpbnRlcnBvbGF0aW9uIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CSUxJTkVBUiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9CSUNVQklDIGluZGljYXRlcyBiaS1jdWJpYyBpbnRlcnBvbGF0aW9uIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CSUNVQklDID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSBpIHR5cGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgaVR5cGU7IC8vIGludGVycG9sYXRpb24gdHlwZQorCisgICAgLyoqCisgICAgICogVGhlIGF0LgorICAgICAqLworICAgIHByaXZhdGUgQWZmaW5lVHJhbnNmb3JtIGF0OworCisgICAgLyoqCisgICAgICogVGhlIGhpbnRzLgorICAgICAqLworICAgIHByaXZhdGUgUmVuZGVyaW5nSGludHMgaGludHM7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBUT0RPIC0gdW5jb21tZW50CisgICAgICAgIC8vIFN5c3RlbS5sb2FkTGlicmFyeSgiaW1hZ2VvcHMiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQWZmaW5lVHJhbnNmb3JtT3Agd2l0aCB0aGUgc3BlY2lmaWVkIEFmZmluZVRyYW5zZm9ybQorICAgICAqIGFuZCBSZW5kZXJpbmdIaW50cyBvYmplY3Qgd2hpY2ggZGVmaW5lcyB0aGUgaW50ZXJwb2xhdGlvbiB0eXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4Zm9ybQorICAgICAqICAgICAgICAgICAgdGhlIEFmZmluZVRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3Qgd2hpY2ggZGVmaW5lcyB0aGUgaW50ZXJwb2xhdGlvbgorICAgICAqICAgICAgICAgICAgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtT3AoQWZmaW5lVHJhbnNmb3JtIHhmb3JtLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICB0aGlzKHhmb3JtLCBUWVBFX05FQVJFU1RfTkVJR0hCT1IpOworICAgICAgICB0aGlzLmhpbnRzID0gaGludHM7CisKKyAgICAgICAgaWYgKGhpbnRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIE9iamVjdCBoaW50ID0gaGludHMuZ2V0KFJlbmRlcmluZ0hpbnRzLktFWV9JTlRFUlBPTEFUSU9OKTsKKyAgICAgICAgICAgIGlmIChoaW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBOZWFyZXN0IG5laWdoYm9yIGlzIGRlZmF1bHQKKyAgICAgICAgICAgICAgICBpZiAoaGludCA9PSBSZW5kZXJpbmdIaW50cy5WQUxVRV9JTlRFUlBPTEFUSU9OX0JJTElORUFSKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaVR5cGUgPSBUWVBFX0JJTElORUFSOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaGludCA9PSBSZW5kZXJpbmdIaW50cy5WQUxVRV9JTlRFUlBPTEFUSU9OX0JJQ1VCSUMpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5pVHlwZSA9IFRZUEVfQklDVUJJQzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGhpbnQgPSBoaW50cy5nZXQoUmVuZGVyaW5nSGludHMuS0VZX1JFTkRFUklORyk7CisgICAgICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGZyb20gcmVuZGVyaW5nIHF1YWxpdHkKKyAgICAgICAgICAgICAgICBpZiAoaGludCA9PSBSZW5kZXJpbmdIaW50cy5WQUxVRV9SRU5ERVJfUVVBTElUWSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmlUeXBlID0gVFlQRV9CSUxJTkVBUjsKKyAgICAgICAgICAgICAgICAgICAgLy8gRm9yIHNwZWVkIHVzZSBuZWFyZXN0IG5laWdoYm9yCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEFmZmluZVRyYW5zZm9ybU9wIHdpdGggdGhlIHNwZWNpZmllZCBBZmZpbmVUcmFuc2Zvcm0KKyAgICAgKiBhbmQgYSBzcGVjaWZpZWQgaW50ZXJwb2xhdGlvbiB0eXBlIGZyb20gdGhlIGxpc3Qgb2YgcHJlZGVmaW5lZAorICAgICAqIGludGVycG9sYXRpb24gdHlwZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHhmb3JtCisgICAgICogICAgICAgICAgICB0aGUgQWZmaW5lVHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBpbnRlcnAKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbmUgb2YgcHJlZGVmaW5lZCBpbnRlcnBvbGF0aW9uIHR5cGVzOgorICAgICAqICAgICAgICAgICAgVFlQRV9ORUFSRVNUX05FSUdIQk9SLCBUWVBFX0JJTElORUFSLCBvciBUWVBFX0JJQ1VCSUMuCisgICAgICovCisgICAgcHVibGljIEFmZmluZVRyYW5zZm9ybU9wKEFmZmluZVRyYW5zZm9ybSB4Zm9ybSwgaW50IGludGVycCkgeworICAgICAgICBpZiAoTWF0aC5hYnMoeGZvcm0uZ2V0RGV0ZXJtaW5hbnQoKSkgPD0gRG91YmxlLk1JTl9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI0Rj1VbmFibGUgdG8gaW52ZXJ0IHRyYW5zZm9ybSB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbWFnaW5nT3BFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjRGIiwgeGZvcm0pKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5hdCA9IChBZmZpbmVUcmFuc2Zvcm0peGZvcm0uY2xvbmUoKTsKKworICAgICAgICBpZiAoaW50ZXJwICE9IFRZUEVfTkVBUkVTVF9ORUlHSEJPUiAmJiBpbnRlcnAgIT0gVFlQRV9CSUxJTkVBUiAmJiBpbnRlcnAgIT0gVFlQRV9CSUNVQklDKSB7CisgICAgICAgICAgICAvLyBhd3QuMjUwPVVua25vd24gaW50ZXJwb2xhdGlvbiB0eXBlOiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjUwIiwgaW50ZXJwKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuaVR5cGUgPSBpbnRlcnA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW50ZXJwb2xhdGlvbiB0eXBlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGludGVycG9sYXRpb24gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEludGVycG9sYXRpb25UeXBlKCkgeworICAgICAgICByZXR1cm4gaVR5cGU7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlbmRlcmluZ0hpbnRzIGdldFJlbmRlcmluZ0hpbnRzKCkgeworICAgICAgICBpZiAoaGludHMgPT0gbnVsbCkgeworICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gbnVsbDsKKworICAgICAgICAgICAgc3dpdGNoIChpVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9ORUFSRVNUX05FSUdIQk9SOgorICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFJlbmRlcmluZ0hpbnRzLlZBTFVFX0lOVEVSUE9MQVRJT05fTkVBUkVTVF9ORUlHSEJPUjsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBUWVBFX0JJTElORUFSOgorICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFJlbmRlcmluZ0hpbnRzLlZBTFVFX0lOVEVSUE9MQVRJT05fQklMSU5FQVI7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgVFlQRV9CSUNVQklDOgorICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFJlbmRlcmluZ0hpbnRzLlZBTFVFX0lOVEVSUE9MQVRJT05fQklDVUJJQzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBSZW5kZXJpbmdIaW50cy5WQUxVRV9JTlRFUlBPTEFUSU9OX05FQVJFU1RfTkVJR0hCT1I7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGhpbnRzID0gbmV3IFJlbmRlcmluZ0hpbnRzKFJlbmRlcmluZ0hpbnRzLktFWV9JTlRFUlBPTEFUSU9OLCB2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaGludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYWZmaW5lIHRyYW5zZm9ybSBhc3NvY2lhdGVkIHdpdGggdGhpcyBBZmZpbmVUcmFuc2Zvcm1PcC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEFmZmluZVRyYW5zZm9ybSBnZXRUcmFuc2Zvcm0oKSB7CisgICAgICAgIHJldHVybiAoQWZmaW5lVHJhbnNmb3JtKWF0LmNsb25lKCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFBvaW50MkQgZ2V0UG9pbnQyRChQb2ludDJEIHNyY1B0LCBQb2ludDJEIGRzdFB0KSB7CisgICAgICAgIHJldHVybiBhdC50cmFuc2Zvcm0oc3JjUHQsIGRzdFB0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoQnVmZmVyZWRJbWFnZSBzcmMpIHsKKyAgICAgICAgcmV0dXJuIGdldEJvdW5kczJEKHNyYy5nZXRSYXN0ZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKFJhc3RlciBzcmMpIHsKKyAgICAgICAgLy8gV2UgcG9zaXRpb24gc291cmNlIHJhc3RlciB0byAoMCwwKSBldmVuIGlmIGl0IGlzIHRyYW5zbGF0ZWQgY2hpbGQKKyAgICAgICAgLy8gcmFzdGVyLgorICAgICAgICAvLyBUaGlzIG1lYW5zIHRoYXQgd2UgbmVlZCBvbmx5IHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHNyYworICAgICAgICBpbnQgd2lkdGggPSBzcmMuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGhlaWdodCA9IHNyYy5nZXRIZWlnaHQoKTsKKworICAgICAgICBmbG9hdFtdIGNvcm5lcnMgPSB7CisgICAgICAgICAgICAgICAgMCwgMCwgd2lkdGgsIDAsIHdpZHRoLCBoZWlnaHQsIDAsIGhlaWdodAorICAgICAgICB9OworCisgICAgICAgIGF0LnRyYW5zZm9ybShjb3JuZXJzLCAwLCBjb3JuZXJzLCAwLCA0KTsKKworICAgICAgICBSZWN0YW5nbGUyRC5GbG9hdCBib3VuZHMgPSBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoY29ybmVyc1swXSwgY29ybmVyc1sxXSwgMCwgMCk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1syXSwgY29ybmVyc1szXSk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1s0XSwgY29ybmVyc1s1XSk7CisgICAgICAgIGJvdW5kcy5hZGQoY29ybmVyc1s2XSwgY29ybmVyc1s3XSk7CisKKyAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSBjcmVhdGVDb21wYXRpYmxlRGVzdEltYWdlKEJ1ZmZlcmVkSW1hZ2Ugc3JjLCBDb2xvck1vZGVsIGRlc3RDTSkgeworICAgICAgICBSZWN0YW5nbGUyRCBuZXdCb3VuZHMgPSBnZXRCb3VuZHMyRChzcmMpOworCisgICAgICAgIC8vIERlc3RpbmF0aW9uIGltYWdlIHNob3VsZCBpbmNsdWRlICgwLDApICsgcG9zaXRpdmUgcGFydAorICAgICAgICAvLyBvZiB0aGUgYXJlYSBib3VuZGVkIGJ5IG5ld0JvdW5kcyAoaW4gc291cmNlIGNvb3JkaW5hdGUgc3lzdGVtKS4KKyAgICAgICAgZG91YmxlIGRzdFdpZHRoID0gbmV3Qm91bmRzLmdldFgoKSArIG5ld0JvdW5kcy5nZXRXaWR0aCgpOworICAgICAgICBkb3VibGUgZHN0SGVpZ2h0ID0gbmV3Qm91bmRzLmdldFkoKSArIG5ld0JvdW5kcy5nZXRIZWlnaHQoKTsKKworICAgICAgICBpZiAoZHN0V2lkdGggPD0gMCB8fCBkc3RIZWlnaHQgPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjI1MT1UcmFuc2Zvcm1lZCB3aWR0aCAoezB9KSBhbmQgaGVpZ2h0ICh7MX0pIHNob3VsZCBiZQorICAgICAgICAgICAgLy8gZ3JlYXRlciB0aGFuIDAKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjUxIiwgZHN0V2lkdGgsIGRzdEhlaWdodCkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVzdENNICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShkZXN0Q00sIGRlc3RDTS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoKGludClkc3RXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgKGludClkc3RIZWlnaHQpLCBkZXN0Q00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBDb2xvck1vZGVsIGNtID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKworICAgICAgICAvLyBJbnRlcnBvbGF0aW9uIG90aGVyIHRoYW4gTk4gZG9lc24ndCBtYWtlIGFueSBzZW5zZSBmb3IgaW5kZXggY29sb3IKKyAgICAgICAgaWYgKGlUeXBlICE9IFRZUEVfTkVBUkVTVF9ORUlHSEJPUiAmJiBjbSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlKChpbnQpZHN0V2lkdGgsIChpbnQpZHN0SGVpZ2h0LCBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IpOworICAgICAgICB9CisKKyAgICAgICAgLy8gT0ssIHdlIGNhbiBnZXQgc291cmNlIGNvbG9yIG1vZGVsCisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShjbSwgc3JjLmdldFJhc3RlcigpLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcigoaW50KWRzdFdpZHRoLAorICAgICAgICAgICAgICAgIChpbnQpZHN0SGVpZ2h0KSwgY20uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKFJhc3RlciBzcmMpIHsKKyAgICAgICAgLy8gSGVyZSBhcHByb2FjaCBpcyBvdGhlciB0aGVuIGluIGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2UgLQorICAgICAgICAvLyBkZXN0aW5hdGlvbiBzaG91bGQgaW5jbHVkZSBvbmx5CisgICAgICAgIC8vIHRyYW5zZm9ybWVkIGltYWdlLCBidXQgbm90ICgwLDApIGluIHNvdXJjZSBjb29yZGluYXRlIHN5c3RlbQorCisgICAgICAgIFJlY3RhbmdsZTJEIG5ld0JvdW5kcyA9IGdldEJvdW5kczJEKHNyYyk7CisgICAgICAgIHJldHVybiBzcmMuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKChpbnQpbmV3Qm91bmRzLmdldFgoKSwgKGludCluZXdCb3VuZHMuZ2V0WSgpLAorICAgICAgICAgICAgICAgIChpbnQpbmV3Qm91bmRzLmdldFdpZHRoKCksIChpbnQpbmV3Qm91bmRzLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgQnVmZmVyZWRJbWFnZSBmaWx0ZXIoQnVmZmVyZWRJbWFnZSBzcmMsIEJ1ZmZlcmVkSW1hZ2UgZHN0KSB7CisgICAgICAgIGlmIChzcmMgPT0gZHN0KSB7CisgICAgICAgICAgICAvLyBhd3QuMjUyPVNvdXJjZSBjYW4ndCBiZSBzYW1lIGFzIHRoZSBkZXN0aW5hdGlvbgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIENvbG9yTW9kZWwgc3JjQ00gPSBzcmMuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICBCdWZmZXJlZEltYWdlIGZpbmFsRHN0ID0gbnVsbDsKKworICAgICAgICBpZiAoc3JjQ00gaW5zdGFuY2VvZiBJbmRleENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICAmJiAoaVR5cGUgIT0gVFlQRV9ORUFSRVNUX05FSUdIQk9SIHx8IHNyY0NNLmdldFBpeGVsU2l6ZSgpICUgOCAhPSAwKSkgeworICAgICAgICAgICAgc3JjID0gKChJbmRleENvbG9yTW9kZWwpc3JjQ00pLmNvbnZlcnRUb0ludERpc2NyZXRlKHNyYy5nZXRSYXN0ZXIoKSwgdHJ1ZSk7CisgICAgICAgICAgICBzcmNDTSA9IHNyYy5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2Uoc3JjLCBzcmNDTSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoIXNyY0NNLmVxdWFscyhkc3QuZ2V0Q29sb3JNb2RlbCgpKSkgeworICAgICAgICAgICAgICAgIC8vIFRyZWF0IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfUkdCIGFuZAorICAgICAgICAgICAgICAgIC8vIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQiBhcyBzYW1lCisgICAgICAgICAgICAgICAgaWYgKCEoKHNyYy5nZXRUeXBlKCkgPT0gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0IgfHwgc3JjLmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IpICYmIChkc3QKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRUeXBlKCkgPT0gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0IgfHwgZHN0LmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IpKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbERzdCA9IGRzdDsKKyAgICAgICAgICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RJbWFnZShzcmMsIHNyY0NNKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTa2lwIGFscGhhIGNoYW5uZWwgZm9yIFRZUEVfSU5UX1JHQiBpbWFnZXMKKyAgICAgICAgaWYgKHNsb3dGaWx0ZXIoc3JjLmdldFJhc3RlcigpLCBkc3QuZ2V0UmFzdGVyKCkpICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMUY9VW5hYmxlIHRvIHRyYW5zZm9ybSBzb3VyY2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbWFnaW5nT3BFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjFGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAvLyBUT0RPIC0gdW5jb21tZW50CisgICAgICAgICAgICAvLyBpZiAoaXBwRmlsdGVyKHNyYy5nZXRSYXN0ZXIoKSwgZHN0LmdldFJhc3RlcigpLCBzcmMuZ2V0VHlwZSgpKSAhPQorICAgICAgICAgICAgLy8gMCkKKyAgICAgICAgICAgIC8vIHRocm93IG5ldyBJbWFnaW5nT3BFeGNlcHRpb24gKCJVbmFibGUgdG8gdHJhbnNmb3JtIHNvdXJjZSIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpbmFsRHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIEdyYXBoaWNzMkQgZyA9IGZpbmFsRHN0LmNyZWF0ZUdyYXBoaWNzKCk7CisgICAgICAgICAgICBnLnNldENvbXBvc2l0ZShBbHBoYUNvbXBvc2l0ZS5TcmMpOworICAgICAgICAgICAgZy5kcmF3SW1hZ2UoZHN0LCAwLCAwLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbmFsRHN0ID0gZHN0OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZpbmFsRHN0OworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBXcml0YWJsZVJhc3RlciBmaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0KSB7CisgICAgICAgIGlmIChzcmMgPT0gZHN0KSB7CisgICAgICAgICAgICAvLyBhd3QuMjUyPVNvdXJjZSBjYW4ndCBiZSBzYW1lIGFzIHRoZSBkZXN0aW5hdGlvbgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoc3JjKTsKKyAgICAgICAgfSBlbHNlIGlmIChzcmMuZ2V0TnVtQmFuZHMoKSAhPSBkc3QuZ2V0TnVtQmFuZHMoKSkgeworICAgICAgICAgICAgLy8gYXd0LjI1Mz1EaWZmZXJlbnQgbnVtYmVyIG9mIGJhbmRzIGluIHNvdXJjZSBhbmQgZGVzdGluYXRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjUzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoc2xvd0ZpbHRlcihzcmMsIGRzdCkgIT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIxRj1VbmFibGUgdG8gdHJhbnNmb3JtIHNvdXJjZQorICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdpbmdPcEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIC8vIFRPRE8gLSB1bmNvbW1lbnQKKyAgICAgICAgICAgIC8vIGlmIChpcHBGaWx0ZXIoc3JjLCBkc3QsIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9DVVNUT00pICE9IDApCisgICAgICAgICAgICAvLyB0aHJvdyBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uKCJVbmFibGUgdG8gdHJhbnNmb3JtIHNvdXJjZSIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICAvLyBUT0RPIHJlbW92ZSB3aGVuIG1ldGhvZCBpcyB1c2VkCisgICAgLyoqCisgICAgICogSXBwIGZpbHRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc3JjLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHBhcmFtIGltYWdlVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgaW50IGlwcEZpbHRlcihSYXN0ZXIgc3JjLCBXcml0YWJsZVJhc3RlciBkc3QsIGludCBpbWFnZVR5cGUpIHsKKyAgICAgICAgaW50IHNyY1N0cmlkZSwgZHN0U3RyaWRlOworICAgICAgICBib29sZWFuIHNraXBDaGFubmVsID0gZmFsc2U7CisgICAgICAgIGludCBjaGFubmVsczsKKyAgICAgICAgaW50IG9mZnNldHNbXSA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChpbWFnZVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQkdSOiB7CisgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSA0OworICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNyYy5nZXRXaWR0aCgpICogNDsKKyAgICAgICAgICAgICAgICBkc3RTdHJpZGUgPSBkc3QuZ2V0V2lkdGgoKSAqIDQ7CisgICAgICAgICAgICAgICAgc2tpcENoYW5uZWwgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQjoKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCX1BSRToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFXzRCWVRFX0FCR1I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV80QllURV9BQkdSX1BSRTogeworICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcmMuZ2V0V2lkdGgoKSAqIDQ7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0dSQVk6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0lOREVYRUQ6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDE7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCk7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFXzNCWVRFX0JHUjogeworICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gMzsKKyAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcmMuZ2V0V2lkdGgoKSAqIDM7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCkgKiAzOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9VU0hPUlRfR1JBWTogLy8gVE9ETyAtIGNvdWxkIGJlIGRvbmUgaW4KKyAgICAgICAgICAgICAgICAvLyBuYXRpdmUgY29kZT8KKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF81NjVfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUXzU1NV9SR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0JJTkFSWTogeworICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgIFNhbXBsZU1vZGVsIHNyY1NNID0gc3JjLmdldFNhbXBsZU1vZGVsKCk7CisgICAgICAgICAgICAgICAgU2FtcGxlTW9kZWwgZHN0U00gPSBkc3QuZ2V0U2FtcGxlTW9kZWwoKTsKKworICAgICAgICAgICAgICAgIGlmIChzcmNTTSBpbnN0YW5jZW9mIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgZHN0U00gaW5zdGFuY2VvZiBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgIGlmIChzcmNTTS5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZHN0U00uZ2V0RGF0YVR5cGUoKSAhPSBEYXRhQnVmZmVyLlRZUEVfQllURSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSBzcmNTTS5nZXROdW1CYW5kcygpOyAvLyBIYXZlIElQUCBmdW5jdGlvbnMgZm9yIDEsCisgICAgICAgICAgICAgICAgICAgIC8vIDMgYW5kIDQgY2hhbm5lbHMKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNoYW5uZWxzICE9IDEgJiYgY2hhbm5lbHMgIT0gMyAmJiBjaGFubmVscyAhPSA0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpbnQgZGF0YVR5cGVTaXplID0gRGF0YUJ1ZmZlci5nZXREYXRhVHlwZVNpemUoc3JjU00uZ2V0RGF0YVR5cGUoKSkgLyA4OworCisgICAgICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9ICgoQ29tcG9uZW50U2FtcGxlTW9kZWwpc3JjU00pLmdldFNjYW5saW5lU3RyaWRlKCkgKiBkYXRhVHlwZVNpemU7CisgICAgICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9ICgoQ29tcG9uZW50U2FtcGxlTW9kZWwpZHN0U00pLmdldFNjYW5saW5lU3RyaWRlKCkgKiBkYXRhVHlwZVNpemU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzcmNTTSBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGRzdFNNIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgc3Bwc20xID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpc3JjU007CisgICAgICAgICAgICAgICAgICAgIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgc3Bwc20yID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpZHN0U007CisKKyAgICAgICAgICAgICAgICAgICAgLy8gTm8gSVBQIGZ1bmN0aW9uIGZvciB0aGlzIHR5cGUKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNwcHNtMS5nZXREYXRhVHlwZSgpID09IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gc3Bwc20xLmdldE51bUJhbmRzKCk7CisgICAgICAgICAgICAgICAgICAgIC8vIEhhdmUgSVBQIGZ1bmN0aW9ucyBmb3IgMSwgMyBhbmQgNCBjaGFubmVscworICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbHMgIT0gMSAmJiBjaGFubmVscyAhPSAzICYmIGNoYW5uZWxzICE9IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGNvbXBhdGliaWxpdHkgb2Ygc2FtcGxlIG1vZGVscworICAgICAgICAgICAgICAgICAgICBpZiAoc3Bwc20xLmdldERhdGFUeXBlKCkgIT0gc3Bwc20yLmdldERhdGFUeXBlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAhQXJyYXlzLmVxdWFscyhzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpLCBzcHBzbTIuZ2V0Qml0T2Zmc2V0cygpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICFBcnJheXMuZXF1YWxzKHNwcHNtMS5nZXRCaXRNYXNrcygpLCBzcHBzbTIuZ2V0Qml0TWFza3MoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhbm5lbHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwcHNtMS5nZXRTYW1wbGVTaXplKGkpICE9IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbHMgPT0gMykgeworICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSA0OworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaW50IGRhdGFUeXBlU2l6ZSA9IERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKHNwcHNtMS5nZXREYXRhVHlwZSgpKSAvIDg7CisKKyAgICAgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3Bwc20xLmdldFNjYW5saW5lU3RyaWRlKCkgKiBkYXRhVHlwZVNpemU7CisgICAgICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IHNwcHNtMi5nZXRTY2FubGluZVN0cmlkZSgpICogZGF0YVR5cGVTaXplOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBGaWxsIG9mZnNldHMgaWYgdGhlcmUncyBhIGNoaWxkIHJhc3RlcgorICAgICAgICAgICAgICAgIGlmIChzcmMuZ2V0UGFyZW50KCkgIT0gbnVsbCB8fCBkc3QuZ2V0UGFyZW50KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICE9IDAgfHwgc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICE9IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBkc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzID0gbmV3IGludFs0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMF0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICsgc3JjLmdldE1pblgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMV0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgc3JjLmdldE1pblkoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMl0gPSAtZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICsgZHN0LmdldE1pblgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbM10gPSAtZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgZHN0LmdldE1pblkoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZSBtMDAgPSBhdC5nZXRTY2FsZVgoKTsKKyAgICAgICAgZG91YmxlIG0wMSA9IGF0LmdldFNoZWFyWCgpOworICAgICAgICBkb3VibGUgbTAyID0gYXQuZ2V0VHJhbnNsYXRlWCgpOworICAgICAgICBkb3VibGUgbTEwID0gYXQuZ2V0U2hlYXJZKCk7CisgICAgICAgIGRvdWJsZSBtMTEgPSBhdC5nZXRTY2FsZVkoKTsKKyAgICAgICAgZG91YmxlIG0xMiA9IGF0LmdldFRyYW5zbGF0ZVkoKTsKKworICAgICAgICBPYmplY3Qgc3JjRGF0YSwgZHN0RGF0YTsKKyAgICAgICAgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yIGRiQWNjZXNzID0gQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yLmdldEluc3RhbmNlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcmNEYXRhID0gZGJBY2Nlc3MuZ2V0RGF0YShzcmMuZ2V0RGF0YUJ1ZmZlcigpKTsKKyAgICAgICAgICAgIGRzdERhdGEgPSBkYkFjY2Vzcy5nZXREYXRhKGRzdC5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOyAvLyBVbmtub3duIGRhdGEgYnVmZmVyIHR5cGUKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpcHBBZmZpbmVUcmFuc2Zvcm0obTAwLCBtMDEsIG0wMiwgbTEwLCBtMTEsIG0xMiwgc3JjRGF0YSwgc3JjLmdldFdpZHRoKCksIHNyYworICAgICAgICAgICAgICAgIC5nZXRIZWlnaHQoKSwgc3JjU3RyaWRlLCBkc3REYXRhLCBkc3QuZ2V0V2lkdGgoKSwgZHN0LmdldEhlaWdodCgpLCBkc3RTdHJpZGUsCisgICAgICAgICAgICAgICAgaVR5cGUsIGNoYW5uZWxzLCBza2lwQ2hhbm5lbCwgb2Zmc2V0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2xvdyBmaWx0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBzbG93RmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCkgeworICAgICAgICAvLyBUT0RPOiBtYWtlIGNvcnJlY3QgaW50ZXJwb2xhdGlvbgorICAgICAgICAvLyBUT0RPOiB3aGF0IGlmIHRoZXJlIGFyZSBkaWZmZXJlbnQgZGF0YSB0eXBlcz8KKworICAgICAgICBSZWN0YW5nbGUgc3JjQm91bmRzID0gc3JjLmdldEJvdW5kcygpOworICAgICAgICBSZWN0YW5nbGUgZHN0Qm91bmRzID0gZHN0LmdldEJvdW5kcygpOworICAgICAgICBSZWN0YW5nbGUgbm9ybURzdEJvdW5kcyA9IG5ldyBSZWN0YW5nbGUoMCwgMCwgZHN0Qm91bmRzLndpZHRoLCBkc3RCb3VuZHMuaGVpZ2h0KTsKKyAgICAgICAgUmVjdGFuZ2xlIGJvdW5kcyA9IGdldEJvdW5kczJEKHNyYykuZ2V0Qm91bmRzKCkuaW50ZXJzZWN0aW9uKG5vcm1Ec3RCb3VuZHMpOworCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBpbnYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW52ID0gYXQuY3JlYXRlSW52ZXJzZSgpOworICAgICAgICB9IGNhdGNoIChOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZVtdIG0gPSBuZXcgZG91YmxlWzZdOworICAgICAgICBpbnYuZ2V0TWF0cml4KG0pOworCisgICAgICAgIGludCBtaW5TcmNYID0gc3JjQm91bmRzLng7CisgICAgICAgIGludCBtaW5TcmNZID0gc3JjQm91bmRzLnk7CisgICAgICAgIGludCBtYXhTcmNYID0gc3JjQm91bmRzLnggKyBzcmNCb3VuZHMud2lkdGg7CisgICAgICAgIGludCBtYXhTcmNZID0gc3JjQm91bmRzLnkgKyBzcmNCb3VuZHMuaGVpZ2h0OworCisgICAgICAgIGludCBtaW5YID0gYm91bmRzLnggKyBkc3RCb3VuZHMueDsKKyAgICAgICAgaW50IG1pblkgPSBib3VuZHMueSArIGRzdEJvdW5kcy55OworICAgICAgICBpbnQgbWF4WCA9IG1pblggKyBib3VuZHMud2lkdGg7CisgICAgICAgIGludCBtYXhZID0gbWluWSArIGJvdW5kcy5oZWlnaHQ7CisKKyAgICAgICAgaW50IGh4ID0gKGludCkobVswXSAqIDI1Nik7CisgICAgICAgIGludCBoeSA9IChpbnQpKG1bMV0gKiAyNTYpOworICAgICAgICBpbnQgdnggPSAoaW50KShtWzJdICogMjU2KTsKKyAgICAgICAgaW50IHZ5ID0gKGludCkobVszXSAqIDI1Nik7CisgICAgICAgIGludCBzeCA9IChpbnQpKG1bNF0gKiAyNTYpICsgaHggKiBib3VuZHMueCArIHZ4ICogYm91bmRzLnkgKyAoc3JjQm91bmRzLngpICogMjU2OworICAgICAgICBpbnQgc3kgPSAoaW50KShtWzVdICogMjU2KSArIGh5ICogYm91bmRzLnggKyB2eSAqIGJvdW5kcy55ICsgKHNyY0JvdW5kcy55KSAqIDI1NjsKKworICAgICAgICB2eCAtPSBoeCAqIGJvdW5kcy53aWR0aDsKKyAgICAgICAgdnkgLT0gaHkgKiBib3VuZHMud2lkdGg7CisKKyAgICAgICAgaWYgKHNyYy5nZXRUcmFuc2ZlclR5cGUoKSA9PSBkc3QuZ2V0VHJhbnNmZXJUeXBlKCkpIHsKKyAgICAgICAgICAgIGZvciAoaW50IHkgPSBtaW5ZOyB5IDwgbWF4WTsgeSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeCA9IG1pblg7IHggPCBtYXhYOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHB4ID0gc3ggPj4gODsKKyAgICAgICAgICAgICAgICAgICAgaW50IHB5ID0gc3kgPj4gODsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHB4ID49IG1pblNyY1ggJiYgcHkgPj0gbWluU3JjWSAmJiBweCA8IG1heFNyY1ggJiYgcHkgPCBtYXhTcmNZKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsID0gc3JjLmdldERhdGFFbGVtZW50cyhweCwgcHksIG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgZHN0LnNldERhdGFFbGVtZW50cyh4LCB5LCB2YWwpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHN4ICs9IGh4OworICAgICAgICAgICAgICAgICAgICBzeSArPSBoeTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3ggKz0gdng7CisgICAgICAgICAgICAgICAgc3kgKz0gdnk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmbG9hdCBwaXhlbFtdID0gbnVsbDsKKyAgICAgICAgICAgIGZvciAoaW50IHkgPSBtaW5ZOyB5IDwgbWF4WTsgeSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeCA9IG1pblg7IHggPCBtYXhYOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHB4ID0gc3ggPj4gODsKKyAgICAgICAgICAgICAgICAgICAgaW50IHB5ID0gc3kgPj4gODsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHB4ID49IG1pblNyY1ggJiYgcHkgPj0gbWluU3JjWSAmJiBweCA8IG1heFNyY1ggJiYgcHkgPCBtYXhTcmNZKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbCA9IHNyYy5nZXRQaXhlbChweCwgcHksIHBpeGVsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5zZXRQaXhlbCh4LCB5LCBwaXhlbCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc3ggKz0gaHg7CisgICAgICAgICAgICAgICAgICAgIHN5ICs9IGh5OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzeCArPSB2eDsKKyAgICAgICAgICAgICAgICBzeSArPSB2eTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIElwcCBhZmZpbmUgdHJhbnNmb3JtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtMDAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMDAuCisgICAgICogQHBhcmFtIG0wMQorICAgICAqICAgICAgICAgICAgdGhlIG0wMS4KKyAgICAgKiBAcGFyYW0gbTAyCisgICAgICogICAgICAgICAgICB0aGUgbTAyLgorICAgICAqIEBwYXJhbSBtMTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtMTAuCisgICAgICogQHBhcmFtIG0xMQorICAgICAqICAgICAgICAgICAgdGhlIG0xMS4KKyAgICAgKiBAcGFyYW0gbTEyCisgICAgICogICAgICAgICAgICB0aGUgbTEyLgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIHNyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgc3JjIHdpZHRoLgorICAgICAqIEBwYXJhbSBzcmNIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBzcmNTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgc3RyaWRlLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHBhcmFtIGRzdFdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgZHN0IHdpZHRoLgorICAgICAqIEBwYXJhbSBkc3RIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBkc3RTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3Qgc3RyaWRlLgorICAgICAqIEBwYXJhbSBpVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGkgdHlwZS4KKyAgICAgKiBAcGFyYW0gY2hhbm5lbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFubmVscy4KKyAgICAgKiBAcGFyYW0gc2tpcENoYW5uZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBza2lwIGNoYW5uZWwuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXRzLgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgaXBwQWZmaW5lVHJhbnNmb3JtKGRvdWJsZSBtMDAsIGRvdWJsZSBtMDEsIGRvdWJsZSBtMDIsIGRvdWJsZSBtMTAsCisgICAgICAgICAgICBkb3VibGUgbTExLCBkb3VibGUgbTEyLCBPYmplY3Qgc3JjLCBpbnQgc3JjV2lkdGgsIGludCBzcmNIZWlnaHQsIGludCBzcmNTdHJpZGUsCisgICAgICAgICAgICBPYmplY3QgZHN0LCBpbnQgZHN0V2lkdGgsIGludCBkc3RIZWlnaHQsIGludCBkc3RTdHJpZGUsIGludCBpVHlwZSwgaW50IGNoYW5uZWxzLAorICAgICAgICAgICAgYm9vbGVhbiBza2lwQ2hhbm5lbCwgaW50IG9mZnNldHNbXSk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0FyZWFBdmVyYWdpbmdTY2FsZUZpbHRlci5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0FyZWFBdmVyYWdpbmdTY2FsZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmYjEzOGUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQXJlYUF2ZXJhZ2luZ1NjYWxlRmlsdGVyLmphdmEKQEAgLTAsMCArMSwyODggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaGUgQXJlYUF2ZXJhZ2luZ1NjYWxlRmlsdGVyIGNsYXNzIHNjYWxlcyB0aGUgc291cmNlIGltYWdlIHVzaW5nIGFyZWEKKyAqIGF2ZXJhZ2luZyBhbGdvcml0aG0uIFRoaXMgYWxnb3JpdGhtIHByb3ZpZGVzIGEgc291cmNlIGltYWdlIHdpdGggYSBuZXcgaW1hZ2UKKyAqIGNvbnRhaW5pbmcgdGhlIHJlc2FtcGxlZCBpbWFnZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBBcmVhQXZlcmFnaW5nU2NhbGVGaWx0ZXIgZXh0ZW5kcyBSZXBsaWNhdGVTY2FsZUZpbHRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcmdiQ00uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29sb3JNb2RlbCByZ2JDTSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IGF2ZXJhZ2luZ0ZsYWdzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBhdmVyYWdpbmdGbGFncyA9IChJbWFnZUNvbnN1bWVyLlRPUERPV05MRUZUUklHSFQgfCBJbWFnZUNvbnN1bWVyLkNPTVBMRVRFU0NBTkxJTkVTKTsKKworICAgIC8qKgorICAgICAqIFRoZSByZXNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gcmVzZXQgPSB0cnVlOyAvLyBGbGFnIGZvciB1c2VkIHN1cGVyY2xhc3MgZmlsdGVyCisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5pdGVkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpbml0ZWQgPSBmYWxzZTsgLy8gQWxsIGRhdGEgaW5pdGVkCisKKyAgICAvKioKKyAgICAgKiBUaGUgc3VtX3IuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc3VtX3JbXTsgLy8gQXJyYXkgZm9yIGF2ZXJhZ2UgUmVkIHNhbXBsZXMKKworICAgIC8qKgorICAgICAqIFRoZSBzdW1fZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBzdW1fZ1tdOyAvLyBBcnJheSBmb3IgYXZlcmFnZSBHcmVlbiBzYW1wbGVzCisKKyAgICAvKioKKyAgICAgKiBUaGUgc3VtX2IuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc3VtX2JbXTsgLy8gQXJyYXkgZm9yIGF2ZXJhZ2UgQmx1ZSBzYW1wbGVzCisKKyAgICAvKioKKyAgICAgKiBUaGUgc3VtX2EuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc3VtX2FbXTsgLy8gQXJyYXkgZm9yIGF2ZXJhZ2UgQWxwaGEgc2FtcGxlcworCisgICAgLyoqCisgICAgICogVGhlIGJ1ZmYuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYnVmZltdOyAvLyBTdHJpZGUgYnVmZmVyCisKKyAgICAvKioKKyAgICAgKiBUaGUgYXZnIGZhY3Rvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBhdmdGYWN0b3I7IC8vIEdsb2JhbCBhdmVyYWdpbmcgZmFjdG9yCisKKyAgICAvKioKKyAgICAgKiBUaGUgY2FjaGVkIGR5LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNhY2hlZERZOyAvLyBDYWNoZWQgbnVtYmVyIG9mIHRoZSBkZXN0aW5hdGlvbiBzY2FubGluZQorCisgICAgLyoqCisgICAgICogVGhlIGNhY2hlZCBkdiByZXN0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNhY2hlZERWUmVzdDsgLy8gQ2FjaGVkIHZhbHVlIG9mIHJlc3Qgc3JjIHNjYW5saW5lcyBmb3Igc3VtCisKKyAgICAvLyBwaXhlbCBzYW1wbGVzCisgICAgLy8gQmVjYXVzZSBkYXRhIGlmIHRyYW5zZmVycmluZyBieSB3aG9sZSBzY2FubGluZXMKKyAgICAvLyB3ZSBhcmUgY2FjaGluZyBvbmx5IFkgY29vcmRpbmF0ZSB2YWx1ZXMKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBBcmVhQXZlcmFnaW5nU2NhbGVGaWx0ZXIgb2JqZWN0IHdoaWNoIHNjYWxlcyBhIHNvdXJjZQorICAgICAqIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxlZCB3aWR0aCBvZiB0aGUgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxlZCBoZWlnaHQgb2YgdGhlIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBBcmVhQXZlcmFnaW5nU2NhbGVGaWx0ZXIoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHN1cGVyKHdpZHRoLCBoZWlnaHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgaW50W10gcGl4ZWxzLCBpbnQgb2ZmLAorICAgICAgICAgICAgaW50IHNjYW5zaXplKSB7CisgICAgICAgIGlmIChyZXNldCkgeworICAgICAgICAgICAgc3VwZXIuc2V0UGl4ZWxzKHgsIHksIHcsIGgsIG1vZGVsLCBwaXhlbHMsIG9mZiwgc2NhbnNpemUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0RmlsdGVyZWRQaXhlbHMoeCwgeSwgdywgaCwgbW9kZWwsIHBpeGVscywgb2ZmLCBzY2Fuc2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGVbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgaWYgKHJlc2V0KSB7CisgICAgICAgICAgICBzdXBlci5zZXRQaXhlbHMoeCwgeSwgdywgaCwgbW9kZWwsIHBpeGVscywgb2ZmLCBzY2Fuc2l6ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXRGaWx0ZXJlZFBpeGVscyh4LCB5LCB3LCBoLCBtb2RlbCwgcGl4ZWxzLCBvZmYsIHNjYW5zaXplKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEhpbnRzKGludCBoaW50cykgeworICAgICAgICBzdXBlci5zZXRIaW50cyhoaW50cyk7CisgICAgICAgIHJlc2V0ID0gKChoaW50cyAmIGF2ZXJhZ2luZ0ZsYWdzKSAhPSBhdmVyYWdpbmdGbGFncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgQXJlYSBBdmVyYWdpbmcgU2NhbGUgZmlsdGVyLiBUaGUgZGVzY3JpcHRpb24KKyAgICAgKiBvZiBhbGdvcml0aG0gaXMgcHJlc2VudGVkIGluIEphdmEgQVBJIFNwZWNpZmljYXRpb24uIEFycmF5cyBzdW1fciwgc3VtX2csCisgICAgICogc3VtX2IsIHN1bV9hIGhhdmUgbGVuZ3RoIGVxdWFscyB3aWR0aCBvZiBkZXN0aW5hdGlvbiBpbWFnZS4gSW4gZWFjaAorICAgICAqIGFycmF5J3MgZWxlbWVudCBpcyBhY2N1bXVsYXRpbmcgcGl4ZWwncyBjb21wb25lbnQgdmFsdWVzLCBwcm9wb3J0aW9uYWwgdG8KKyAgICAgKiB0aGUgYXJlYSB3aGljaCBzb3VyY2UgcGl4ZWxzIHdpbGwgb2NjdXB5IGluIGRlc3RpbmF0aW9uIGltYWdlLiBUaGVuIHRoYXQKKyAgICAgKiB2YWx1ZXMgd2lsbCBkaXZpZGUgYnkgR2xvYmFsIGF2ZXJhZ2luZyBmYWN0b3IgKGFyZWEgb2YgdGhlIGRlc3RpbmF0aW9uCisgICAgICogaW1hZ2UpIGZvciByZWNlaXZpbmcgYXZlcmFnZSB2YWx1ZXMgb2YgZGVzdGluYXRpb24gcGl4ZWxzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHBpeGVscyBYIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgcGl4ZWxzIFkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBhcmVhIG9mIHRoZSBzb3VyY2UgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBhcmVhIG9mIHRoZSBzb3VyY2UgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBtb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIGNvbG9yIG1vZGVsIG9mIHRoZSBzb3VyY2UgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBwaXhlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBzb3VyY2UgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW50byB0aGUgc291cmNlIHBpeGVscyBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2Ygc2NhbmxpbmUgaW4gdGhlIHBpeGVscyBhcnJheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0RmlsdGVyZWRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIE9iamVjdCBwaXhlbHMsCisgICAgICAgICAgICBpbnQgb2ZmLCBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgaWYgKCFpbml0ZWQpIHsKKyAgICAgICAgICAgIGluaXRpYWxpemUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzcmNYLCBzcmNZLCBkeCwgZHk7CisgICAgICAgIGludCBzdlJlc3QsIGR2UmVzdCwgc2hSZXN0LCBkaFJlc3QsIHZEaWYsIGhEaWY7CisKKyAgICAgICAgaWYgKHkgPT0gMCkgeworICAgICAgICAgICAgZHkgPSAwOworICAgICAgICAgICAgZHZSZXN0ID0gc3JjSGVpZ2h0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZHkgPSBjYWNoZWREWTsKKyAgICAgICAgICAgIGR2UmVzdCA9IGNhY2hlZERWUmVzdDsKKyAgICAgICAgfQorCisgICAgICAgIHNyY1kgPSB5OworICAgICAgICBzdlJlc3QgPSBkZXN0SGVpZ2h0OworCisgICAgICAgIGludCBzcmNPZmYgPSBvZmY7CisgICAgICAgIHdoaWxlIChzcmNZIDwgeSArIGgpIHsKKyAgICAgICAgICAgIGlmIChzdlJlc3QgPCBkdlJlc3QpIHsKKyAgICAgICAgICAgICAgICB2RGlmID0gc3ZSZXN0OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB2RGlmID0gZHZSZXN0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzcmNYID0gMDsKKyAgICAgICAgICAgIGR4ID0gMDsKKyAgICAgICAgICAgIHNoUmVzdCA9IGRlc3RXaWR0aDsKKyAgICAgICAgICAgIGRoUmVzdCA9IHNyY1dpZHRoOworICAgICAgICAgICAgd2hpbGUgKHNyY1ggPCB3KSB7CisgICAgICAgICAgICAgICAgaWYgKHNoUmVzdCA8IGRoUmVzdCkgeworICAgICAgICAgICAgICAgICAgICBoRGlmID0gc2hSZXN0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGhEaWYgPSBkaFJlc3Q7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBhdmcgPSBoRGlmICogdkRpZjsgLy8gY2FsY3VsYXRpb24gb2YgY29udHJpYnV0aW9uIGZhY3RvcgorCisgICAgICAgICAgICAgICAgaW50IHJnYiwgcGl4OworICAgICAgICAgICAgICAgIGlmIChwaXhlbHMgaW5zdGFuY2VvZiBpbnRbXSkgeworICAgICAgICAgICAgICAgICAgICBwaXggPSAoKGludFtdKXBpeGVscylbc3JjT2ZmICsgc3JjWF07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4ID0gKChieXRlW10pcGl4ZWxzKVtzcmNPZmYgKyBzcmNYXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmdiID0gbW9kZWwuZ2V0UkdCKHBpeCk7CisgICAgICAgICAgICAgICAgaW50IGEgPSByZ2IgPj4+IDI0OworICAgICAgICAgICAgICAgIGludCByID0gKHJnYiA+PiAxNikgJiAweGZmOworICAgICAgICAgICAgICAgIGludCBnID0gKHJnYiA+PiA4KSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgaW50IGIgPSByZ2IgJiAweGZmOworCisgICAgICAgICAgICAgICAgLy8gYWNjdW11bGF0aW5nIHBpeGVsJ3MgY29tcG9uZW50IHZhbHVlcworICAgICAgICAgICAgICAgIHN1bV9hW2R4XSArPSBhICogYXZnOworICAgICAgICAgICAgICAgIHN1bV9yW2R4XSArPSByICogYXZnOworICAgICAgICAgICAgICAgIHN1bV9nW2R4XSArPSBnICogYXZnOworICAgICAgICAgICAgICAgIHN1bV9iW2R4XSArPSBiICogYXZnOworCisgICAgICAgICAgICAgICAgc2hSZXN0IC09IGhEaWY7CisgICAgICAgICAgICAgICAgZGhSZXN0IC09IGhEaWY7CisKKyAgICAgICAgICAgICAgICBpZiAoc2hSZXN0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgc3JjWCsrOworICAgICAgICAgICAgICAgICAgICBzaFJlc3QgPSBkZXN0V2lkdGg7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGRoUmVzdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGR4Kys7CisgICAgICAgICAgICAgICAgICAgIGRoUmVzdCA9IHNyY1dpZHRoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3ZSZXN0IC09IHZEaWY7CisgICAgICAgICAgICBkdlJlc3QgLT0gdkRpZjsKKworICAgICAgICAgICAgaWYgKHN2UmVzdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgc3ZSZXN0ID0gZGVzdEhlaWdodDsKKyAgICAgICAgICAgICAgICBzcmNZKys7CisgICAgICAgICAgICAgICAgc3JjT2ZmICs9IHNjYW5zaXplOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZHZSZXN0ID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBhdmVyYWdpbmcgZGVzdGluYXRpb24gcGl4ZWwncyB2YWx1ZXMKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc3RXaWR0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBhID0gKHN1bV9hW2ldIC8gYXZnRmFjdG9yKSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGludCByID0gKHN1bV9yW2ldIC8gYXZnRmFjdG9yKSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGludCBnID0gKHN1bV9nW2ldIC8gYXZnRmFjdG9yKSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGludCBiID0gKHN1bV9iW2ldIC8gYXZnRmFjdG9yKSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGludCBmcmdiID0gKGEgPDwgMjQpIHwgKHIgPDwgMTYpIHwgKGcgPDwgOCkgfCBiOworICAgICAgICAgICAgICAgICAgICBidWZmW2ldID0gZnJnYjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKDAsIGR5LCBkZXN0V2lkdGgsIDEsIHJnYkNNLCBidWZmLCAwLCBkZXN0V2lkdGgpOworICAgICAgICAgICAgICAgIGR5Kys7CisgICAgICAgICAgICAgICAgZHZSZXN0ID0gc3JjSGVpZ2h0OworICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKHN1bV9hLCAwKTsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChzdW1fciwgMCk7CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoc3VtX2csIDApOworICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKHN1bV9iLCAwKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgY2FjaGVkRFkgPSBkeTsKKyAgICAgICAgY2FjaGVkRFZSZXN0ID0gZHZSZXN0OworCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6YXRpb24gb2YgdGhlIGF1eGlsaWFyeSBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKCkgeworCisgICAgICAgIHN1bV9hID0gbmV3IGludFtkZXN0V2lkdGhdOworICAgICAgICBzdW1fciA9IG5ldyBpbnRbZGVzdFdpZHRoXTsKKyAgICAgICAgc3VtX2cgPSBuZXcgaW50W2Rlc3RXaWR0aF07CisgICAgICAgIHN1bV9iID0gbmV3IGludFtkZXN0V2lkdGhdOworCisgICAgICAgIGJ1ZmYgPSBuZXcgaW50W2Rlc3RXaWR0aF07CisgICAgICAgIG91dHBpeGJ1ZiA9IGJ1ZmY7CisgICAgICAgIGF2Z0ZhY3RvciA9IHNyY1dpZHRoICogc3JjSGVpZ2h0OworCisgICAgICAgIGluaXRlZCA9IHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0F3dEltYWdlQmFja2Rvb3JBY2Nlc3NvckltcGwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3JJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRmZmVlOAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3JJbXBsLmphdmEKQEAgLTAsMCArMSwxNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqIENyZWF0ZWQgb24gMjMuMTEuMjAwNQorICoKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyQnl0ZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyRG91YmxlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXJGbG9hdDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVySW50OworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXJTaG9ydDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyVVNob3J0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5HTFZvbGF0aWxlSW1hZ2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5TdXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuRGF0YUJ1ZmZlckxpc3RlbmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgY2xhc3Mgbm90IHBhcnQgb2YgcHVibGljIEFQSS4gSXQgdXNlZnVsIGZvciByZWNlaXZpbmcgcGFja2FnZSBwcml2YXRlCisgKiBkYXRhIGZyb20gb3RoZXIgcGFja2FnZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitjbGFzcyBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3JJbXBsIGV4dGVuZHMgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yIHsKKworICAgIHN0YXRpYyB2b2lkIGluaXQoKSB7CisgICAgICAgIGluc3QgPSBuZXcgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29ySW1wbCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdXJmYWNlIGdldEltYWdlU3VyZmFjZShJbWFnZSBpbWFnZSkgeworICAgICAgICBpZiAoaW1hZ2UgaW5zdGFuY2VvZiBCdWZmZXJlZEltYWdlKSB7CisgICAgICAgICAgICByZXR1cm4gKChCdWZmZXJlZEltYWdlKWltYWdlKS5nZXRJbWFnZVN1cmZhY2UoKTsKKyAgICAgICAgfSBlbHNlIGlmIChpbWFnZSBpbnN0YW5jZW9mIEdMVm9sYXRpbGVJbWFnZSkgeworICAgICAgICAgICAgcmV0dXJuICgoR0xWb2xhdGlsZUltYWdlKWltYWdlKS5nZXRJbWFnZVN1cmZhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dyYXlQYWxsZXRlKEluZGV4Q29sb3JNb2RlbCBpY20pIHsKKyAgICAgICAgcmV0dXJuIGljbS5pc0dyYXlQYWxsZXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXREYXRhKERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgaWYgKGRiIGluc3RhbmNlb2YgRGF0YUJ1ZmZlckJ5dGUpIHsKKyAgICAgICAgICAgIHJldHVybiAoKERhdGFCdWZmZXJCeXRlKWRiKS5nZXREYXRhKCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyVVNob3J0KSB7CisgICAgICAgICAgICByZXR1cm4gKChEYXRhQnVmZmVyVVNob3J0KWRiKS5nZXREYXRhKCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyU2hvcnQpIHsKKyAgICAgICAgICAgIHJldHVybiAoKERhdGFCdWZmZXJTaG9ydClkYikuZ2V0RGF0YSgpOworICAgICAgICB9IGVsc2UgaWYgKGRiIGluc3RhbmNlb2YgRGF0YUJ1ZmZlckludCkgeworICAgICAgICAgICAgcmV0dXJuICgoRGF0YUJ1ZmZlckludClkYikuZ2V0RGF0YSgpOworICAgICAgICB9IGVsc2UgaWYgKGRiIGluc3RhbmNlb2YgRGF0YUJ1ZmZlckZsb2F0KSB7CisgICAgICAgICAgICByZXR1cm4gKChEYXRhQnVmZmVyRmxvYXQpZGIpLmdldERhdGEoKTsKKyAgICAgICAgfSBlbHNlIGlmIChkYiBpbnN0YW5jZW9mIERhdGFCdWZmZXJEb3VibGUpIHsKKyAgICAgICAgICAgIHJldHVybiAoKERhdGFCdWZmZXJEb3VibGUpZGIpLmdldERhdGEoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzU9V3JvbmcgRGF0YSBCdWZmZXIgdHlwZSA6IHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzUiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIGRiLmdldENsYXNzKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXREYXRhSW50KERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgaWYgKGRiIGluc3RhbmNlb2YgRGF0YUJ1ZmZlckludCkgeworICAgICAgICAgICAgcmV0dXJuICgoRGF0YUJ1ZmZlckludClkYikuZ2V0RGF0YSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0RGF0YUJ5dGUoRGF0YUJ1ZmZlciBkYikgeworICAgICAgICBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyQnl0ZSkgeworICAgICAgICAgICAgcmV0dXJuICgoRGF0YUJ1ZmZlckJ5dGUpZGIpLmdldERhdGEoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnRbXSBnZXREYXRhU2hvcnQoRGF0YUJ1ZmZlciBkYikgeworICAgICAgICBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyU2hvcnQpIHsKKyAgICAgICAgICAgIHJldHVybiAoKERhdGFCdWZmZXJTaG9ydClkYikuZ2V0RGF0YSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydFtdIGdldERhdGFVU2hvcnQoRGF0YUJ1ZmZlciBkYikgeworICAgICAgICBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyVVNob3J0KSB7CisgICAgICAgICAgICByZXR1cm4gKChEYXRhQnVmZmVyVVNob3J0KWRiKS5nZXREYXRhKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZVtdIGdldERhdGFEb3VibGUoRGF0YUJ1ZmZlciBkYikgeworICAgICAgICBpZiAoZGIgaW5zdGFuY2VvZiBEYXRhQnVmZmVyRG91YmxlKSB7CisgICAgICAgICAgICByZXR1cm4gKChEYXRhQnVmZmVyRG91YmxlKWRiKS5nZXREYXRhKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0W10gZ2V0RGF0YUZsb2F0KERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgaWYgKGRiIGluc3RhbmNlb2YgRGF0YUJ1ZmZlckZsb2F0KSB7CisgICAgICAgICAgICByZXR1cm4gKChEYXRhQnVmZmVyRmxvYXQpZGIpLmdldERhdGEoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGREYXRhQnVmZmVyTGlzdGVuZXIoRGF0YUJ1ZmZlciBkYiwgRGF0YUJ1ZmZlckxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGRiLmFkZERhdGFCdWZmZXJMaXN0ZW5lcihsaXN0ZW5lcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlRGF0YUJ1ZmZlckxpc3RlbmVyKERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgZGIucmVtb3ZlRGF0YUJ1ZmZlckxpc3RlbmVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoRGF0YUJ1ZmZlciBkYikgeworICAgICAgICBkYi52YWxpZGF0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbGVhc2VEYXRhKERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgZGIucmVsZWFzZURhdGEoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvQmFuZENvbWJpbmVPcC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0JhbmRDb21iaW5lT3AuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTJjYzg5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0JhbmRDb21iaW5lT3AuamF2YQpAQCAtMCwwICsxLDY1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKgorICogQGRhdGU6IFNlcCAyMCwgMjAwNQorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUG9pbnQyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQmFuZENvbWJpbmVPcCBjbGFzcyB0cmFuc2xhdGVzIGNvb3JkaW5hdGVzIGZyb20gY29vcmRpbmF0ZXMgaW4gdGhlIHNvdXJjZQorICogUmFzdGVyIHRvIGNvb3JkaW5hdGVzIGluIHRoZSBkZXN0aW5hdGlvbiBSYXN0ZXIgYnkgYW4gYXJiaXRyYXJ5IGxpbmVhcgorICogY29tYmluYXRpb24gb2YgdGhlIGJhbmRzIGluIGEgc291cmNlIFJhc3RlciwgdXNpbmcgYSBzcGVjaWZpZWQgbWF0cml4LiBUaGUKKyAqIG51bWJlciBvZiBiYW5kcyBpbiB0aGUgbWF0cml4IHNob3VsZCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZQorICogc291cmNlIFJhc3RlciBwbHVzIDEuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQmFuZENvbWJpbmVPcCBpbXBsZW1lbnRzIFJhc3Rlck9wIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBvZmZzZXRzM2MuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBvZmZzZXRzM2NbXSA9IHsKKyAgICAgICAgICAgIDE2LCA4LCAwCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBvZmZzZXRzNGFjLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgb2Zmc2V0czRhY1tdID0geworICAgICAgICAgICAgMTYsIDgsIDAsIDI0CisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBtYXNrczNjLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgbWFza3MzY1tdID0geworICAgICAgICAgICAgMHhGRjAwMDAsIDB4RkYwMCwgMHhGRgorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgbWFza3M0YWMuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBtYXNrczRhY1tdID0geworICAgICAgICAgICAgMHhGRjAwMDAsIDB4RkYwMCwgMHhGRiwgMHhGRjAwMDAwMAorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgcGlPZmZzZXRzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBwaU9mZnNldHNbXSA9IHsKKyAgICAgICAgICAgIDAsIDEsIDIKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHBpSW52T2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgcGlJbnZPZmZzZXRzW10gPSB7CisgICAgICAgICAgICAyLCAxLCAwCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0JZVEUzQy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CWVRFM0MgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfQllURTRBQy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CWVRFNEFDID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX1VTSE9SVDNDLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUWVBFX1VTSE9SVDNDID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX1NIT1JUM0MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRZUEVfU0hPUlQzQyA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbXggd2lkdGguCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbXhXaWR0aDsKKworICAgIC8qKgorICAgICAqIFRoZSBteCBoZWlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbXhIZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0cml4LgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgbWF0cml4W11bXTsKKworICAgIC8qKgorICAgICAqIFRoZSByIGhpbnRzLgorICAgICAqLworICAgIHByaXZhdGUgUmVuZGVyaW5nSGludHMgckhpbnRzOworCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gWFhYIC0gdG9kbworICAgICAgICAvLyBTeXN0ZW0ubG9hZExpYnJhcnkoImltYWdlb3BzIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEJhbmRDb21iaW5lT3Agb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBtYXRyaXguCisgICAgICogCisgICAgICogQHBhcmFtIG1hdHJpeAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBtYXRyaXggZm9yIGJhbmQgY29tYmluaW5nLgorICAgICAqIEBwYXJhbSBoaW50cworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmluZ0hpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBCYW5kQ29tYmluZU9wKGZsb2F0IG1hdHJpeFtdW10sIFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHRoaXMubXhIZWlnaHQgPSBtYXRyaXgubGVuZ3RoOworICAgICAgICB0aGlzLm14V2lkdGggPSBtYXRyaXhbMF0ubGVuZ3RoOworICAgICAgICB0aGlzLm1hdHJpeCA9IG5ldyBmbG9hdFtteEhlaWdodF1bbXhXaWR0aF07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBteEhlaWdodDsgaSsrKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1hdHJpeFtpXSwgMCwgdGhpcy5tYXRyaXhbaV0sIDAsIG14V2lkdGgpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ySGludHMgPSBoaW50czsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUmVuZGVyaW5nSGludHMgZ2V0UmVuZGVyaW5nSGludHMoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnJIaW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXRyaXggYXNzb2NpYXRlZCB3aXRoIHRoaXMgQmFuZENvbWJpbmVPcCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWF0cml4IGFzc29jaWF0ZWQgd2l0aCB0aGlzIEJhbmRDb21iaW5lT3Agb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBmbG9hdFtdW10gZ2V0TWF0cml4KCkgeworICAgICAgICBmbG9hdCByZXNbXVtdID0gbmV3IGZsb2F0W214SGVpZ2h0XVtteFdpZHRoXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG14SGVpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWF0cml4W2ldLCAwLCByZXNbaV0sIDAsIG14V2lkdGgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUG9pbnQyRCBnZXRQb2ludDJEKFBvaW50MkQgc3JjUG9pbnQsIFBvaW50MkQgZHN0UG9pbnQpIHsKKyAgICAgICAgaWYgKGRzdFBvaW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdFBvaW50ID0gbmV3IFBvaW50MkQuRmxvYXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGRzdFBvaW50LnNldExvY2F0aW9uKHNyY1BvaW50KTsKKyAgICAgICAgcmV0dXJuIGRzdFBvaW50OworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRChSYXN0ZXIgc3JjKSB7CisgICAgICAgIHJldHVybiBzcmMuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKFJhc3RlciBzcmMpIHsKKyAgICAgICAgaW50IG51bUJhbmRzID0gc3JjLmdldE51bUJhbmRzKCk7CisgICAgICAgIGlmIChteFdpZHRoICE9IG51bUJhbmRzICYmIG14V2lkdGggIT0gKG51bUJhbmRzICsgMSkgfHwgbnVtQmFuZHMgIT0gbXhIZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNTQ9TnVtYmVyIG9mIGJhbmRzIGluIHRoZSBzb3VyY2UgcmFzdGVyICh7MH0pIGlzCisgICAgICAgICAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgbWF0cml4IFt7MX14ezJ9XQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTQiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQmFuZHMsIG14V2lkdGgsIG14SGVpZ2h0CisgICAgICAgICAgICAgICAgICAgIH0pKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzcmMuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCkpOworICAgIH0KKworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBmaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0KSB7CisgICAgICAgIGludCBudW1CYW5kcyA9IHNyYy5nZXROdW1CYW5kcygpOworCisgICAgICAgIGlmIChteFdpZHRoICE9IG51bUJhbmRzICYmIG14V2lkdGggIT0gKG51bUJhbmRzICsgMSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNTQ9TnVtYmVyIG9mIGJhbmRzIGluIHRoZSBzb3VyY2UgcmFzdGVyICh7MH0pIGlzCisgICAgICAgICAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgbWF0cml4IFt7MX14ezJ9XQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTQiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQmFuZHMsIG14V2lkdGgsIG14SGVpZ2h0CisgICAgICAgICAgICAgICAgICAgIH0pKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoc3JjKTsKKyAgICAgICAgfSBlbHNlIGlmIChkc3QuZ2V0TnVtQmFuZHMoKSAhPSBteEhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjI1NT1OdW1iZXIgb2YgYmFuZHMgaW4gdGhlIGRlc3RpbmF0aW9uIHJhc3RlciAoezB9KSBpcworICAgICAgICAgICAgLy8gaW5jb21wYXRpYmxlIHdpdGggdGhlIG1hdHJpeCBbezF9eHsyfV0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjU1IiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5nZXROdW1CYW5kcygpLCBteFdpZHRoLCBteEhlaWdodAorICAgICAgICAgICAgICAgICAgICB9KSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBYWFggLSB0b2RvCisgICAgICAgIC8vIGlmIChpcHBGaWx0ZXIoc3JjLCBkc3QpICE9IDApCisgICAgICAgIGlmICh2ZXJ5U2xvd0ZpbHRlcihzcmMsIGRzdCkgIT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIxRj1VbmFibGUgdG8gdHJhbnNmb3JtIHNvdXJjZQorICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdpbmdPcEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIFNhbXBsZU1vZGVsSW5mby4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTYW1wbGVNb2RlbEluZm8geworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY2hhbm5lbHMuCisgICAgICAgICAqLworICAgICAgICBpbnQgY2hhbm5lbHM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjaGFubmVscyBvcmRlci4KKyAgICAgICAgICovCisgICAgICAgIGludCBjaGFubmVsc09yZGVyW107CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzdHJpZGUuCisgICAgICAgICAqLworICAgICAgICBpbnQgc3RyaWRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHNhbXBsZSBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzYW1wbGUgbW9kZWwgaW5mby4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFNhbXBsZU1vZGVsSW5mbyBjaGVja1NhbXBsZU1vZGVsKFNhbXBsZU1vZGVsIHNtKSB7CisgICAgICAgIFNhbXBsZU1vZGVsSW5mbyByZXQgPSBuZXcgU2FtcGxlTW9kZWxJbmZvKCk7CisKKyAgICAgICAgaWYgKHNtIGluc3RhbmNlb2YgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsKSB7CisgICAgICAgICAgICAvLyBDaGVjayBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgIGlmIChzbS5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldC5jaGFubmVscyA9IHNtLmdldE51bUJhbmRzKCk7CisgICAgICAgICAgICByZXQuc3RyaWRlID0gKChDb21wb25lbnRTYW1wbGVNb2RlbClzbSkuZ2V0U2NhbmxpbmVTdHJpZGUoKTsKKyAgICAgICAgICAgIHJldC5jaGFubmVsc09yZGVyID0gKChDb21wb25lbnRTYW1wbGVNb2RlbClzbSkuZ2V0QmFuZE9mZnNldHMoKTsKKworICAgICAgICB9IGVsc2UgaWYgKHNtIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgLy8gQ2hlY2sgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbTEgPSAoU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbClzbTsKKworICAgICAgICAgICAgcmV0LmNoYW5uZWxzID0gc3Bwc20xLmdldE51bUJhbmRzKCk7CisgICAgICAgICAgICBpZiAoc3Bwc20xLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDaGVjayBzYW1wbGUgbW9kZWxzCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJldC5jaGFubmVsczsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHNwcHNtMS5nZXRTYW1wbGVTaXplKGkpICE9IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXQuY2hhbm5lbHNPcmRlciA9IG5ldyBpbnRbcmV0LmNoYW5uZWxzXTsKKyAgICAgICAgICAgIGludCBiaXRPZmZzZXRzW10gPSBzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXQuY2hhbm5lbHM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChiaXRPZmZzZXRzW2ldICUgOCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldC5jaGFubmVsc09yZGVyW2ldID0gYml0T2Zmc2V0c1tpXSAvIDg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldC5jaGFubmVscyA9IDQ7CisgICAgICAgICAgICByZXQuc3RyaWRlID0gc3Bwc20xLmdldFNjYW5saW5lU3RyaWRlKCkgKiA0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNsb3cgZmlsdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRzdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2xvd0ZpbHRlcihSYXN0ZXIgc3JjLCBXcml0YWJsZVJhc3RlciBkc3QpIHsKKyAgICAgICAgaW50IHJlcyA9IDA7CisKKyAgICAgICAgU2FtcGxlTW9kZWxJbmZvIHNyY0luZm8sIGRzdEluZm87CisgICAgICAgIGludCBvZmZzZXRzW10gPSBudWxsOworCisgICAgICAgIHNyY0luZm8gPSBjaGVja1NhbXBsZU1vZGVsKHNyYy5nZXRTYW1wbGVNb2RlbCgpKTsKKyAgICAgICAgZHN0SW5mbyA9IGNoZWNrU2FtcGxlTW9kZWwoZHN0LmdldFNhbXBsZU1vZGVsKCkpOworICAgICAgICBpZiAoc3JjSW5mbyA9PSBudWxsIHx8IGRzdEluZm8gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHZlcnlTbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpbGwgb2Zmc2V0cyBpZiB0aGVyZSdzIGEgY2hpbGQgcmFzdGVyCisgICAgICAgIGlmIChzcmMuZ2V0UGFyZW50KCkgIT0gbnVsbCB8fCBkc3QuZ2V0UGFyZW50KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHNyYy5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSAhPSAwIHx8IHNyYy5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKSAhPSAwCisgICAgICAgICAgICAgICAgICAgIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSAhPSAwIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgb2Zmc2V0cyA9IG5ldyBpbnRbNF07CisgICAgICAgICAgICAgICAgb2Zmc2V0c1swXSA9IC1zcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBzcmMuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgIG9mZnNldHNbMV0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgc3JjLmdldE1pblkoKTsKKyAgICAgICAgICAgICAgICBvZmZzZXRzWzJdID0gLWRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSArIGRzdC5nZXRNaW5YKCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0c1szXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgKyBkc3QuZ2V0TWluWSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IHJteFdpZHRoID0gKHNyY0luZm8uY2hhbm5lbHMgKyAxKTsgLy8gd2lkdGggb2YgdGhlIHJlb3JkZXJlZCBtYXRyaXgKKyAgICAgICAgZmxvYXQgcmVvcmRlcmVkTWF0cml4W10gPSBuZXcgZmxvYXRbcm14V2lkdGggKiBkc3RJbmZvLmNoYW5uZWxzXTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkc3RJbmZvLmNoYW5uZWxzOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChqID49IGRzdEluZm8uY2hhbm5lbHNPcmRlci5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmNJbmZvLmNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoaSA+PSBzcmNJbmZvLmNoYW5uZWxzT3JkZXIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJlb3JkZXJlZE1hdHJpeFtkc3RJbmZvLmNoYW5uZWxzT3JkZXJbal0gKiBybXhXaWR0aCArIHNyY0luZm8uY2hhbm5lbHNPcmRlcltpXV0gPSBtYXRyaXhbal1baV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobXhXaWR0aCA9PSBybXhXaWR0aCkgeworICAgICAgICAgICAgICAgIHJlb3JkZXJlZE1hdHJpeFsoZHN0SW5mby5jaGFubmVsc09yZGVyW2pdICsgMSkgKiBybXhXaWR0aCAtIDFdID0gbWF0cml4W2pdW214V2lkdGggLSAxXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIE9iamVjdCBzcmNEYXRhLCBkc3REYXRhOworICAgICAgICBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IgZGJBY2Nlc3MgPSBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyY0RhdGEgPSBkYkFjY2Vzcy5nZXREYXRhKHNyYy5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICAgICAgZHN0RGF0YSA9IGRiQWNjZXNzLmdldERhdGEoZHN0LmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7IC8vIFVua25vd24gZGF0YSBidWZmZXIgdHlwZQorICAgICAgICB9CisKKyAgICAgICAgc2ltcGxlQ29tYmluZUJhbmRzKHNyY0RhdGEsIHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCksIHNyY0luZm8uc3RyaWRlLAorICAgICAgICAgICAgICAgIHNyY0luZm8uY2hhbm5lbHMsIGRzdERhdGEsIGRzdEluZm8uc3RyaWRlLCBkc3RJbmZvLmNoYW5uZWxzLCByZW9yZGVyZWRNYXRyaXgsCisgICAgICAgICAgICAgICAgb2Zmc2V0cyk7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJ5IHNsb3cgZmlsdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRzdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgdmVyeVNsb3dGaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0KSB7CisgICAgICAgIGludCBudW1CYW5kcyA9IHNyYy5nZXROdW1CYW5kcygpOworCisgICAgICAgIGludCBzcmNNaW5YID0gc3JjLmdldE1pblgoKTsKKyAgICAgICAgaW50IHNyY1kgPSBzcmMuZ2V0TWluWSgpOworCisgICAgICAgIGludCBkc3RNaW5YID0gZHN0LmdldE1pblgoKTsKKyAgICAgICAgaW50IGRzdFkgPSBkc3QuZ2V0TWluWSgpOworCisgICAgICAgIGludCBkWCA9IHNyYy5nZXRXaWR0aCgpOy8vIDwgZHN0LmdldFdpZHRoKCkgPyBzcmMuZ2V0V2lkdGgoKSA6CisgICAgICAgIC8vIGRzdC5nZXRXaWR0aCgpOworICAgICAgICBpbnQgZFkgPSBzcmMuZ2V0SGVpZ2h0KCk7Ly8gPCBkc3QuZ2V0SGVpZ2h0KCkgPyBzcmMuZ2V0SGVpZ2h0KCkgOgorICAgICAgICAvLyBkc3QuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgZmxvYXQgc2FtcGxlOworICAgICAgICBpbnQgc3JjUGl4ZWxzW10gPSBuZXcgaW50W251bUJhbmRzICogZFggKiBkWV07CisgICAgICAgIGludCBkc3RQaXhlbHNbXSA9IG5ldyBpbnRbbXhIZWlnaHQgKiBkWCAqIGRZXTsKKworICAgICAgICBzcmNQaXhlbHMgPSBzcmMuZ2V0UGl4ZWxzKHNyY01pblgsIHNyY1ksIGRYLCBkWSwgc3JjUGl4ZWxzKTsKKworICAgICAgICBpZiAobnVtQmFuZHMgPT0gbXhXaWR0aCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGogPSAwOyBpIDwgc3JjUGl4ZWxzLmxlbmd0aDsgaSArPSBudW1CYW5kcykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGRzdEIgPSAwOyBkc3RCIDwgbXhIZWlnaHQ7IGRzdEIrKykgeworICAgICAgICAgICAgICAgICAgICBzYW1wbGUgPSAwZjsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgc3JjQiA9IDA7IHNyY0IgPCBudW1CYW5kczsgc3JjQisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGUgKz0gbWF0cml4W2RzdEJdW3NyY0JdICogc3JjUGl4ZWxzW2kgKyBzcmNCXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBkc3RQaXhlbHNbaisrXSA9IChpbnQpc2FtcGxlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBqID0gMDsgaSA8IHNyY1BpeGVscy5sZW5ndGg7IGkgKz0gbnVtQmFuZHMpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBkc3RCID0gMDsgZHN0QiA8IG14SGVpZ2h0OyBkc3RCKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2FtcGxlID0gMGY7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHNyY0IgPSAwOyBzcmNCIDwgbnVtQmFuZHM7IHNyY0IrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlICs9IG1hdHJpeFtkc3RCXVtzcmNCXSAqIHNyY1BpeGVsc1tpICsgc3JjQl07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZHN0UGl4ZWxzW2orK10gPSAoaW50KShzYW1wbGUgKyBtYXRyaXhbZHN0Ql1bbnVtQmFuZHNdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBkc3Quc2V0UGl4ZWxzKGRzdE1pblgsIGRzdFksIGRYLCBkWSwgZHN0UGl4ZWxzKTsKKworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBUT0RPIHJlbW92ZSB3aGVuIG1ldGhvZCBpcyB1c2VkCisgICAgLyoqCisgICAgICogSXBwIGZpbHRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc3JjLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgaW50IGlwcEZpbHRlcihSYXN0ZXIgc3JjLCBXcml0YWJsZVJhc3RlciBkc3QpIHsKKyAgICAgICAgYm9vbGVhbiBpbnZlcnRDaGFubmVsczsKKyAgICAgICAgYm9vbGVhbiBpblBsYWNlID0gKHNyYyA9PSBkc3QpOworICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgaW50IHNyY1N0cmlkZSwgZHN0U3RyaWRlOworICAgICAgICBpbnQgb2Zmc2V0c1tdID0gbnVsbDsKKworICAgICAgICBpbnQgc3JjQmFuZHMgPSBzcmMuZ2V0TnVtQmFuZHMoKTsKKyAgICAgICAgaW50IGRzdEJhbmRzID0gZHN0LmdldE51bUJhbmRzKCk7CisKKyAgICAgICAgaWYgKGRzdEJhbmRzICE9IDMKKyAgICAgICAgICAgICAgICB8fCAoc3JjQmFuZHMgIT0gMyAmJiAhKHNyY0JhbmRzID09IDQgJiYgbWF0cml4WzBdWzNdID09IDAgJiYgbWF0cml4WzFdWzNdID09IDAgJiYgbWF0cml4WzJdWzNdID09IDApKSkgeworICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICB9CisKKyAgICAgICAgU2FtcGxlTW9kZWwgc3JjU00gPSBzcmMuZ2V0U2FtcGxlTW9kZWwoKTsKKyAgICAgICAgU2FtcGxlTW9kZWwgZHN0U00gPSBkc3QuZ2V0U2FtcGxlTW9kZWwoKTsKKworICAgICAgICBpZiAoc3JjU00gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgJiYgZHN0U00gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSB7CisgICAgICAgICAgICAvLyBDaGVjayBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtMSA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKXNyY1NNOworICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbTIgPSAoU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbClkc3RTTTsKKworICAgICAgICAgICAgaWYgKHNwcHNtMS5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9JTlQKKyAgICAgICAgICAgICAgICAgICAgfHwgc3Bwc20yLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQ2hlY2sgc2FtcGxlIG1vZGVscworICAgICAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHNwcHNtMi5nZXRCaXRPZmZzZXRzKCksIG9mZnNldHMzYykKKyAgICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMoc3Bwc20yLmdldEJpdE1hc2tzKCksIG1hc2tzM2MpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoc3JjQmFuZHMgPT0gMykgeworICAgICAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpLCBvZmZzZXRzM2MpCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAhQXJyYXlzLmVxdWFscyhzcHBzbTEuZ2V0Qml0TWFza3MoKSwgbWFza3MzYykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoc3JjQmFuZHMgPT0gNCkgeworICAgICAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpLCBvZmZzZXRzNGFjKQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMoc3Bwc20xLmdldEJpdE1hc2tzKCksIG1hc2tzNGFjKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0eXBlID0gVFlQRV9CWVRFNEFDOworICAgICAgICAgICAgaW52ZXJ0Q2hhbm5lbHMgPSB0cnVlOworCisgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcHBzbTEuZ2V0U2NhbmxpbmVTdHJpZGUoKSAqIDQ7CisgICAgICAgICAgICBkc3RTdHJpZGUgPSBzcHBzbTIuZ2V0U2NhbmxpbmVTdHJpZGUoKSAqIDQ7CisgICAgICAgIH0gZWxzZSBpZiAoc3JjU00gaW5zdGFuY2VvZiBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAmJiBkc3RTTSBpbnN0YW5jZW9mIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgaWYgKHNyY0JhbmRzICE9IDMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBzcmNEYXRhVHlwZSA9IHNyY1NNLmdldERhdGFUeXBlKCk7CisKKyAgICAgICAgICAgIHN3aXRjaCAoc3JjRGF0YVR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgICAgICB0eXBlID0gVFlQRV9CWVRFM0M7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICAgICAgdHlwZSA9IFRZUEVfVVNIT1JUM0M7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOgorICAgICAgICAgICAgICAgICAgICB0eXBlID0gVFlQRV9TSE9SVDNDOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIENoZWNrIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsIHBpc20xID0gKFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbClzcmNTTTsKKyAgICAgICAgICAgIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCBwaXNtMiA9IChQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwpZHN0U007CisKKyAgICAgICAgICAgIGlmIChzcmNEYXRhVHlwZSAhPSBwaXNtMi5nZXREYXRhVHlwZSgpIHx8IHBpc20xLmdldFBpeGVsU3RyaWRlKCkgIT0gMworICAgICAgICAgICAgICAgICAgICB8fCBwaXNtMi5nZXRQaXhlbFN0cmlkZSgpICE9IDMKKyAgICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMocGlzbTEuZ2V0QmFuZE9mZnNldHMoKSwgcGlzbTIuZ2V0QmFuZE9mZnNldHMoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChBcnJheXMuZXF1YWxzKHBpc20xLmdldEJhbmRPZmZzZXRzKCksIHBpSW52T2Zmc2V0cykpIHsKKyAgICAgICAgICAgICAgICBpbnZlcnRDaGFubmVscyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMocGlzbTEuZ2V0QmFuZE9mZnNldHMoKSwgcGlPZmZzZXRzKSkgeworICAgICAgICAgICAgICAgIGludmVydENoYW5uZWxzID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGRhdGFUeXBlU2l6ZSA9IERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKHNyY0RhdGFUeXBlKSAvIDg7CisKKyAgICAgICAgICAgIHNyY1N0cmlkZSA9IHBpc20xLmdldFNjYW5saW5lU3RyaWRlKCkgKiBkYXRhVHlwZVNpemU7CisgICAgICAgICAgICBkc3RTdHJpZGUgPSBwaXNtMi5nZXRTY2FubGluZVN0cmlkZSgpICogZGF0YVR5cGVTaXplOworICAgICAgICB9IGVsc2UgeyAvLyBYWFggLSB0b2RvIC0gSVBQIGFsbG93cyBzdXBwb3J0IGZvciBwbGFuYXIgZGF0YSBhbHNvCisgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBGaWxsIG9mZnNldHMgaWYgdGhlcmUncyBhIGNoaWxkIHJhc3RlcgorICAgICAgICBpZiAoc3JjLmdldFBhcmVudCgpICE9IG51bGwgfHwgZHN0LmdldFBhcmVudCgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMCB8fCBzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgIT0gMAorICAgICAgICAgICAgICAgICAgICB8fCBkc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMCB8fCBkc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgIT0gMCkgeworICAgICAgICAgICAgICAgIG9mZnNldHMgPSBuZXcgaW50WzRdOworICAgICAgICAgICAgICAgIG9mZnNldHNbMF0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICsgc3JjLmdldE1pblgoKTsKKyAgICAgICAgICAgICAgICBvZmZzZXRzWzFdID0gLXNyYy5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKSArIHNyYy5nZXRNaW5ZKCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0c1syXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBkc3QuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgIG9mZnNldHNbM10gPSAtZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgZHN0LmdldE1pblkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIE9iamVjdCBzcmNEYXRhLCBkc3REYXRhOworICAgICAgICBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IgZGJBY2Nlc3MgPSBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyY0RhdGEgPSBkYkFjY2Vzcy5nZXREYXRhKHNyYy5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICAgICAgZHN0RGF0YSA9IGRiQWNjZXNzLmdldERhdGEoZHN0LmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7IC8vIFVua25vd24gZGF0YSBidWZmZXIgdHlwZQorICAgICAgICB9CisKKyAgICAgICAgZmxvYXQgaXBwTWF0cml4W10gPSBuZXcgZmxvYXRbMTJdOworCisgICAgICAgIGlmIChpbnZlcnRDaGFubmVscykgeworICAgICAgICAgICAgLy8gSVBQIHRyZWF0cyBiaWcgZW5kaWFuIGludGVnZXJzIGxpa2UgQkdSLCBzbyB3ZSBoYXZlIHRvCisgICAgICAgICAgICAvLyBzd2FwIGNvbHVtbnMgMSBhbmQgMyBhbmQgcm93cyAxIGFuZCAzCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG14SGVpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBpcHBNYXRyaXhbaSAqIDRdID0gbWF0cml4WzIgLSBpXVsyXTsKKyAgICAgICAgICAgICAgICBpcHBNYXRyaXhbaSAqIDQgKyAxXSA9IG1hdHJpeFsyIC0gaV1bMV07CisgICAgICAgICAgICAgICAgaXBwTWF0cml4W2kgKiA0ICsgMl0gPSBtYXRyaXhbMiAtIGldWzBdOworCisgICAgICAgICAgICAgICAgaWYgKG14V2lkdGggPT0gNCkgeworICAgICAgICAgICAgICAgICAgICBpcHBNYXRyaXhbaSAqIDQgKyAzXSA9IG1hdHJpeFsyIC0gaV1bM107CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChteFdpZHRoID09IDUpIHsKKyAgICAgICAgICAgICAgICAgICAgaXBwTWF0cml4W2kgKiA0ICsgM10gPSBtYXRyaXhbMiAtIGldWzRdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXhIZWlnaHQ7IGkrKykgeworICAgICAgICAgICAgICAgIGlwcE1hdHJpeFtpICogNF0gPSBtYXRyaXhbaV1bMF07CisgICAgICAgICAgICAgICAgaXBwTWF0cml4W2kgKiA0ICsgMV0gPSBtYXRyaXhbaV1bMV07CisgICAgICAgICAgICAgICAgaXBwTWF0cml4W2kgKiA0ICsgMl0gPSBtYXRyaXhbaV1bMl07CisKKyAgICAgICAgICAgICAgICBpZiAobXhXaWR0aCA9PSA0KSB7CisgICAgICAgICAgICAgICAgICAgIGlwcE1hdHJpeFtpICogNCArIDNdID0gbWF0cml4W2ldWzNdOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobXhXaWR0aCA9PSA1KSB7CisgICAgICAgICAgICAgICAgICAgIGlwcE1hdHJpeFtpICogNCArIDNdID0gbWF0cml4W2ldWzRdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpcHBDb2xvclR3aXN0KHNyY0RhdGEsIHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCksIHNyY1N0cmlkZSwgZHN0RGF0YSwgZHN0CisgICAgICAgICAgICAgICAgLmdldFdpZHRoKCksIGRzdC5nZXRIZWlnaHQoKSwgZHN0U3RyaWRlLCBpcHBNYXRyaXgsIHR5cGUsIG9mZnNldHMsIGluUGxhY2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElwcCBjb2xvciB0d2lzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjRGF0YQorICAgICAqICAgICAgICAgICAgdGhlIHNyYyBkYXRhLgorICAgICAqIEBwYXJhbSBzcmNXaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHNyYyB3aWR0aC4KKyAgICAgKiBAcGFyYW0gc3JjSGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgc3JjIGhlaWdodC4KKyAgICAgKiBAcGFyYW0gc3JjU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgc3JjIHN0cmlkZS4KKyAgICAgKiBAcGFyYW0gZHN0RGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRzdCBkYXRhLgorICAgICAqIEBwYXJhbSBkc3RXaWR0aAorICAgICAqICAgICAgICAgICAgdGhlIGRzdCB3aWR0aC4KKyAgICAgKiBAcGFyYW0gZHN0SGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgZHN0IGhlaWdodC4KKyAgICAgKiBAcGFyYW0gZHN0U3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgZHN0IHN0cmlkZS4KKyAgICAgKiBAcGFyYW0gaXBwTWF0cml4CisgICAgICogICAgICAgICAgICB0aGUgaXBwIG1hdHJpeC4KKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXRzLgorICAgICAqIEBwYXJhbSBpblBsYWNlCisgICAgICogICAgICAgICAgICB0aGUgaW4gcGxhY2UuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgbmF0aXZlIGludCBpcHBDb2xvclR3aXN0KE9iamVjdCBzcmNEYXRhLCBpbnQgc3JjV2lkdGgsIGludCBzcmNIZWlnaHQsCisgICAgICAgICAgICBpbnQgc3JjU3RyaWRlLCBPYmplY3QgZHN0RGF0YSwgaW50IGRzdFdpZHRoLCBpbnQgZHN0SGVpZ2h0LCBpbnQgZHN0U3RyaWRlLAorICAgICAgICAgICAgZmxvYXQgaXBwTWF0cml4W10sIGludCB0eXBlLCBpbnQgb2Zmc2V0c1tdLCBib29sZWFuIGluUGxhY2UpOworCisgICAgLyoqCisgICAgICogU2ltcGxlIGNvbWJpbmUgYmFuZHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNyY0RhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgZGF0YS4KKyAgICAgKiBAcGFyYW0gc3JjV2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgd2lkdGguCisgICAgICogQHBhcmFtIHNyY0hlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHNyYyBoZWlnaHQuCisgICAgICogQHBhcmFtIHNyY1N0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHNyYyBzdHJpZGUuCisgICAgICogQHBhcmFtIHNyY0NoYW5uZWxzCisgICAgICogICAgICAgICAgICB0aGUgc3JjIGNoYW5uZWxzLgorICAgICAqIEBwYXJhbSBkc3REYXRhCisgICAgICogICAgICAgICAgICB0aGUgZHN0IGRhdGEuCisgICAgICogQHBhcmFtIGRzdFN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIGRzdCBzdHJpZGUuCisgICAgICogQHBhcmFtIGRzdENoYW5uZWxzCisgICAgICogICAgICAgICAgICB0aGUgZHN0IGNoYW5uZWxzLgorICAgICAqIEBwYXJhbSBtCisgICAgICogICAgICAgICAgICB0aGUgbS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldHMuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgbmF0aXZlIGludCBzaW1wbGVDb21iaW5lQmFuZHMoT2JqZWN0IHNyY0RhdGEsIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwKKyAgICAgICAgICAgIGludCBzcmNTdHJpZGUsIGludCBzcmNDaGFubmVscywgT2JqZWN0IGRzdERhdGEsIGludCBkc3RTdHJpZGUsIGludCBkc3RDaGFubmVscywKKyAgICAgICAgICAgIGZsb2F0IG1bXSwgaW50IG9mZnNldHNbXSk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvQmFuZGVkU2FtcGxlTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9CYW5kZWRTYW1wbGVNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhYTMwZDcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQmFuZGVkU2FtcGxlTW9kZWwuamF2YQpAQCAtMCwwICsxLDQyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQmFuZGVkU2FtcGxlTW9kZWwgY2xhc3MgcHJvdmlkZXMgc2FtcGxlcyBvZiBwaXhlbHMgaW4gYW4gaW1hZ2Ugd2hpY2ggaXMKKyAqIHN0b3JlZCBpbiBhIGJhbmQgaW50ZXJsZWF2ZWQgbWV0aG9kLiBFYWNoIHBpeGVsJ3Mgc2FtcGxlIHRha2VzIG9uZSBkYXRhCisgKiBlbGVtZW50IG9mIHRoZSBEYXRhQnVmZmVyLiBUaGUgcGl4ZWwgc3RyaWRlIGZvciBhIEJhbmRlZFNhbXBsZU1vZGVsIGlzIG9uZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCYW5kZWRTYW1wbGVNb2RlbCBleHRlbmRzIENvbXBvbmVudFNhbXBsZU1vZGVsIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGluZGljZXMuCisgICAgICogCisgICAgICogQHBhcmFtIG51bUJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtIGJhbmRzLgorICAgICAqIEByZXR1cm4gdGhlIGludFtdLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludFtdIGNyZWF0ZUluZGljZXMoaW50IG51bUJhbmRzKSB7CisgICAgICAgIGludCBpbmRpY2VzW10gPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBpbmRpY2VzW2ldID0gaTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5kaWNlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBvZmZzZXRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBudW1CYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bSBiYW5kcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnRbXS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBjcmVhdGVPZmZzZXRzKGludCBudW1CYW5kcykgeworICAgICAgICBpbnQgb2Zmc2V0c1tdID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgb2Zmc2V0c1tpXSA9IDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG9mZnNldHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEJhbmRlZFNhbXBsZU1vZGVsIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgZGF0YSB0eXBlCisgICAgICogb2Ygc2FtcGxlcywgdGhlIHdpZHRoLCBoZWlnaHQgYW5kIGJhbmRzIG51bWJlciBvZiBpbWFnZSBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiBzYW1wbGVzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBudW1CYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmFuZGVkU2FtcGxlTW9kZWwoaW50IGRhdGFUeXBlLCBpbnQgdywgaW50IGgsIGludCBudW1CYW5kcykgeworICAgICAgICB0aGlzKGRhdGFUeXBlLCB3LCBoLCB3LCBCYW5kZWRTYW1wbGVNb2RlbC5jcmVhdGVJbmRpY2VzKG51bUJhbmRzKSwgQmFuZGVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAuY3JlYXRlT2Zmc2V0cyhudW1CYW5kcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCYW5kZWRTYW1wbGVNb2RlbCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIGRhdGEgdHlwZQorICAgICAqIG9mIHNhbXBsZXMsIHRoZSB3aWR0aCwgaGVpZ2h0IGFuZCBiYW5kcyBudW1iZXIgb2YgaW1hZ2UgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2Ygc2FtcGxlcy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gc2NhbmxpbmVTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUgb2YgdGhlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5rSW5kaWNlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHRoZSBiYW5rIGluZGljZXMuCisgICAgICogQHBhcmFtIGJhbmRPZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgdGhlIGJhbmQgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmFuZGVkU2FtcGxlTW9kZWwoaW50IGRhdGFUeXBlLCBpbnQgdywgaW50IGgsIGludCBzY2FubGluZVN0cmlkZSwgaW50IGJhbmtJbmRpY2VzW10sCisgICAgICAgICAgICBpbnQgYmFuZE9mZnNldHNbXSkgeworICAgICAgICBzdXBlcihkYXRhVHlwZSwgdywgaCwgMSwgc2NhbmxpbmVTdHJpZGUsIGJhbmtJbmRpY2VzLCBiYW5kT2Zmc2V0cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbChpbnQgdywgaW50IGgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCYW5kZWRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwgdywgYmFua0luZGljZXMsIGJhbmRPZmZzZXRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0YUJ1ZmZlciBjcmVhdGVEYXRhQnVmZmVyKCkgeworICAgICAgICBEYXRhQnVmZmVyIGRhdGEgPSBudWxsOworICAgICAgICBpbnQgc2l6ZSA9IHNjYW5saW5lU3RyaWRlICogaGVpZ2h0OworCisgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyQnl0ZShzaXplLCBudW1CYW5rcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJTaG9ydChzaXplLCBudW1CYW5rcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVySW50KHNpemUsIG51bUJhbmtzKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlckZsb2F0KHNpemUsIG51bUJhbmtzKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJEb3VibGUoc2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRhdGE7CisKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgY3JlYXRlU3Vic2V0U2FtcGxlTW9kZWwoaW50W10gYmFuZHMpIHsKKyAgICAgICAgaWYgKGJhbmRzLmxlbmd0aCA+IG51bUJhbmRzKSB7CisgICAgICAgICAgICAvLyBhd3QuNjQ9VGhlIG51bWJlciBvZiB0aGUgYmFuZHMgaW4gdGhlIHN1YnNldCBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICAgICAgICAvLyBudW1iZXIgb2YgYmFuZHMgaW4gdGhlIHNhbXBsZSBtb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGluZGljZXNbXSA9IG5ldyBpbnRbYmFuZHMubGVuZ3RoXTsKKyAgICAgICAgaW50IG9mZnNldHNbXSA9IG5ldyBpbnRbYmFuZHMubGVuZ3RoXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhbmRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbmRpY2VzW2ldID0gYmFua0luZGljZXNbYmFuZHNbaV1dOworICAgICAgICAgICAgb2Zmc2V0c1tpXSA9IGJhbmRPZmZzZXRzW2JhbmRzW2ldXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQmFuZGVkU2FtcGxlTW9kZWwoZGF0YVR5cGUsIHdpZHRoLCBoZWlnaHQsIHNjYW5saW5lU3RyaWRlLCBpbmRpY2VzLCBvZmZzZXRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIE9iamVjdCBvYmosIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOiB7CisgICAgICAgICAgICAgICAgYnl0ZSBiZGF0YVtdOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gbmV3IGJ5dGVbbnVtQmFuZHNdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gKGJ5dGVbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhW2ldID0gKGJ5dGUpZ2V0U2FtcGxlKHgsIHksIGksIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG9iaiA9IGJkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6IHsKKyAgICAgICAgICAgICAgICBzaG9ydCBzZGF0YVtdOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNkYXRhID0gbmV3IHNob3J0W251bUJhbmRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZGF0YSA9IChzaG9ydFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2RhdGFbaV0gPSAoc2hvcnQpZ2V0U2FtcGxlKHgsIHksIGksIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG9iaiA9IHNkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOiB7CisgICAgICAgICAgICAgICAgaW50IGlkYXRhW107CisKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWRhdGEgPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZGF0YSA9IChpbnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlkYXRhW2ldID0gZ2V0U2FtcGxlKHgsIHksIGksIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG9iaiA9IGlkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRkxPQVQ6IHsKKyAgICAgICAgICAgICAgICBmbG9hdCBmZGF0YVtdOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZkYXRhID0gbmV3IGZsb2F0W251bUJhbmRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IChmbG9hdFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmRhdGFbaV0gPSBnZXRTYW1wbGVGbG9hdCh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvYmogPSBmZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRTogeworICAgICAgICAgICAgICAgIGRvdWJsZSBkZGF0YVtdOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGRkYXRhID0gbmV3IGRvdWJsZVtudW1CYW5kc107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZGRhdGEgPSAoZG91YmxlW10pb2JqOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBkZGF0YVtpXSA9IGdldFNhbXBsZURvdWJsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvYmogPSBkZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBvYmo7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaW50IHBpeGVsW107CisgICAgICAgIGlmIChpQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcGl4ZWwgPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBpeGVsID0gaUFycmF5OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBwaXhlbFtpXSA9IGdldFNhbXBsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwaXhlbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkYXRhLmdldEVsZW0oYmFua0luZGljZXNbYl0sIHkgKiBzY2FubGluZVN0cmlkZSArIHggKyBiYW5kT2Zmc2V0c1tiXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBnZXRTYW1wbGVEb3VibGUoaW50IHgsIGludCB5LCBpbnQgYiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGF0YS5nZXRFbGVtRG91YmxlKGJhbmtJbmRpY2VzW2JdLCB5ICogc2NhbmxpbmVTdHJpZGUgKyB4ICsgYmFuZE9mZnNldHNbYl0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRTYW1wbGVGbG9hdChpbnQgeCwgaW50IHksIGludCBiLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkYXRhLmdldEVsZW1GbG9hdChiYW5rSW5kaWNlc1tiXSwgeSAqIHNjYW5saW5lU3RyaWRlICsgeCArIGJhbmRPZmZzZXRzW2JdKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50W10gZ2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBzYW1wbGVzW107CisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIGlmIChpQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgc2FtcGxlcyA9IG5ldyBpbnRbdyAqIGhdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2FtcGxlcyA9IGlBcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgc2FtcGxlc1tpZHgrK10gPSBnZXRTYW1wbGUoaiwgaSwgYiwgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2FtcGxlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIGludCB0bXAgPSBoYXNoID4+PiA4OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKworICAgICAgICByZXR1cm4gaGFzaCBeIDB4NTU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiZGF0YVtdID0gKGJ5dGVbXSlvYmo7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBiZGF0YVtpXSAmIDB4ZmYsIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2RhdGFbXSA9IChzaG9ydFtdKW9iajsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIHNkYXRhW2ldICYgMHhmZmZmLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWRhdGFbXSA9IChpbnRbXSlvYmo7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBpZGF0YVtpXSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDoKKyAgICAgICAgICAgICAgICBmbG9hdCBmZGF0YVtdID0gKGZsb2F0W10pb2JqOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoeCwgeSwgaSwgZmRhdGFbaV0sIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIGRvdWJsZSBkZGF0YVtdID0gKGRvdWJsZVtdKW9iajsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIGRkYXRhW2ldLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIGlBcnJheVtpXSwgZGF0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1CYW5kczsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgIHNldFNhbXBsZShqLCBpLCBuLCBpQXJyYXlbaWR4KytdLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgZG91YmxlIHMsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCA+PSB0aGlzLndpZHRoIHx8IHkgPj0gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgZGF0YS5zZXRFbGVtRG91YmxlKGJhbmtJbmRpY2VzW2JdLCB5ICogc2NhbmxpbmVTdHJpZGUgKyB4ICsgYmFuZE9mZnNldHNbYl0sIHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBmbG9hdCBzLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGRhdGEuc2V0RWxlbUZsb2F0KGJhbmtJbmRpY2VzW2JdLCB5ICogc2NhbmxpbmVTdHJpZGUgKyB4ICsgYmFuZE9mZnNldHNbYl0sIHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBpbnQgcywgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBkYXRhLnNldEVsZW0oYmFua0luZGljZXNbYl0sIHkgKiBzY2FubGluZVN0cmlkZSArIHggKyBiYW5kT2Zmc2V0c1tiXSwgcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgc2V0U2FtcGxlKGosIGksIGIsIGlBcnJheVtpZHgrK10sIGRhdGEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9CdWZmZXJTdHJhdGVneS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0J1ZmZlclN0cmF0ZWd5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M4Nzc5ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9CdWZmZXJTdHJhdGVneS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuQnVmZmVyQ2FwYWJpbGl0aWVzOworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzOworCisvKioKKyAqIFRoZSBCdWZmZXJTdHJhdGVneSBhYnN0cmFjdCBjbGFzcyBwcm92aWRlcyBhbiBvcHBvcnR1bml0eSB0byBvcmdhbml6ZSB0aGUKKyAqIGJ1ZmZlcnMgZm9yIGEgQ2FudmFzIG9yIFdpbmRvdy4gVGhlIEJ1ZmZlclN0cmF0ZWd5IGltcGxlbWVudGF0aW9uIGRlcGVuZHMgb24KKyAqIGhhcmR3YXJlIGFuZCBzb2Z0d2FyZSBsaW1pdGF0aW9ucy4gVGhlc2UgbGltaXRhdGlvbnMgYXJlIGRldGVjdGFibGUgdGhyb3VnaAorICogdGhlIGNhcGFiaWxpdGllcyBvYmplY3Qgd2hpY2ggY2FuIGJlIG9idGFpbmVkIGJ5IHRoZSBHcmFwaGljc0NvbmZpZ3VyYXRpb24gb2YKKyAqIHRoZSBDYW52YXMgb3IgV2luZG93LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEJ1ZmZlclN0cmF0ZWd5IHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZHJhd2luZyBidWZmZXIgd2FzIGxvc3Qgc2luY2UgdGhlIGxhc3QgY2FsbCBvZgorICAgICAqIGdldERyYXdHcmFwaGljcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGRyYXdpbmcgYnVmZmVyIHdhcyBsb3N0IHNpbmNlIHRoZSBsYXN0IGNhbGwgb2YKKyAgICAgKiAgICAgICAgIGdldERyYXdHcmFwaGljcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNvbnRlbnRzTG9zdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBkcmF3aW5nIGJ1ZmZlciBpcyByZXN0b3JlZCBmcm9tIGEgbG9zdCBzdGF0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGRyYXdpbmcgYnVmZmVyIGlzIHJlc3RvcmVkIGZyb20gYSBsb3N0IHN0YXRlLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNvbnRlbnRzUmVzdG9yZWQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEJ1ZmZlckNhcGFiaWxpdGllcyBvZiBCdWZmZXJTdHJhdGVneS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJDYXBhYmlsaXRpZXMgb2YgQnVmZmVyU3RyYXRlZ3kuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1ZmZlckNhcGFiaWxpdGllcyBnZXRDYXBhYmlsaXRpZXMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEdyYXBoaWNzIG9iamVjdCB0byB1c2UgdG8gZHJhdyB0byB0aGUgYnVmZmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEdyYXBoaWNzIG9iamVjdCB0byB1c2UgdG8gZHJhdyB0byB0aGUgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljcyBnZXREcmF3R3JhcGhpY3MoKTsKKworICAgIC8qKgorICAgICAqIFNob3dzIHRoZSBuZXh0IGF2YWlsYWJsZSBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2hvdygpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvQnVmZmVyZWRJbWFnZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0J1ZmZlcmVkSW1hZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOWQ1OGQ5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0J1ZmZlcmVkSW1hZ2UuamF2YQpAQCAtMCwwICsxLDk1MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3QuQW5kcm9pZEdyYXBoaWNzMkQ7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzRW52aXJvbm1lbnQ7CitpbXBvcnQgamF2YS5hd3QuSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuUG9pbnQ7CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LlRyYW5zcGFyZW5jeTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkltYWdlU3VyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5CdWZmZXJlZEltYWdlU291cmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBCdWZmZXJlZEltYWdlIGNsYXNzIGRlc2NyaWJlcyBhbiBJbWFnZSB3aGljaCBjb250YWlucyBhIGJ1ZmZlciBvZiBpbWFnZQorICogZGF0YSBhbmQgaW5jbHVkZXMgYSBDb2xvck1vZGVsIGFuZCBhIFJhc3RlciBmb3IgdGhpcyBkYXRhLiBUaGlzIGNsYXNzCisgKiBwcm92aWRlcyBtZXRob2RzIGZvciBvYnRhaW5pbmcgYW5kIHNldHRpbmcgdGhlIFJhc3RlciBhbmQgZm9yIG1hbmlwdWxhdGluZworICogdGhlIENvbG9yTW9kZWwgcGFyYW1ldGVycy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJlZEltYWdlIGV4dGVuZHMgSW1hZ2UgaW1wbGVtZW50cyBXcml0YWJsZVJlbmRlcmVkSW1hZ2UsIFRyYW5zcGFyZW5jeSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9DVVNUT00gaW5kaWNhdGVzIHRoYXQgSW1hZ2UgdHlwZSBpcyB1bmtub3duLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQ1VTVE9NID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0lOVF9SR0IgaW5kaWNhdGVzIGFuIGltYWdlIHdpdGggOCBiaXQgUkdCIGNvbG9yCisgICAgICogY29tcG9uZW50cywgaXQgaGFzIGEgRGlyZWN0Q29sb3JNb2RlbCB3aXRob3V0IGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSU5UX1JHQiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9JTlRfQVJHQiBpbmRpY2F0ZXMgYW4gaW1hZ2Ugd2l0aCA4IGJpdCBSR0JBIGNvbG9yCisgICAgICogY29tcG9uZW50cywgaXQgaGFzIGEgRGlyZWN0Q29sb3JNb2RlbCB3aXRoIGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSU5UX0FSR0IgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfSU5UX0FSR0JfUFJFIGluZGljYXRlcyBhbiBpbWFnZSB3aXRoIDggYml0IFJHQkEgY29sb3IKKyAgICAgKiBjb21wb25lbnRzLCBpdCBoYXMgYSBEaXJlY3RDb2xvck1vZGVsIHdpdGggYWxwaGEsIGFuZCBpbWFnZSBkYXRhIGlzCisgICAgICogcHJlLW11bHRpcGxpZWQgYnkgYWxwaGEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9JTlRfQVJHQl9QUkUgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfSU5UX0JHUiBpbmRpY2F0ZXMgYW4gaW1hZ2Ugd2l0aCA4IGJpdCBSR0IgY29sb3IKKyAgICAgKiBjb21wb25lbnRzLCBCR1IgY29sb3IgbW9kZWwgKHdpdGggdGhlIGNvbG9ycyBCbHVlLCBHcmVlbiwgYW5kIFJlZCkuIFRoZXJlCisgICAgICogaXMgbm8gYWxwaGEuIFRoZSBpbWFnZSBoYXMgYSBEaXJlY3RDb2xvck1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSU5UX0JHUiA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV8zQllURV9CR1IgaW5kaWNhdGVzIGFuIGltYWdlIHdpdGggOCBiaXQgUkdCIGNvbG9yCisgICAgICogY29tcG9uZW50cywgQkdSIGNvbG9yIG1vZGVsICh3aXRoIHRoZSBjb2xvcnMgQmx1ZSwgR3JlZW4sIGFuZCBSZWQgc3RvcmVkCisgICAgICogaW4gMyBieXRlcykuIFRoZXJlIGlzIG5vIGFscGhhLiBUaGUgaW1hZ2UgaGFzIGEgQ29tcG9uZW50Q29sb3JNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFXzNCWVRFX0JHUiA9IDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV80QllURV9BQkdSIGluZGljYXRlcyBhbiBpbWFnZSB3aXRoIDggYml0IFJHQkEgY29sb3IKKyAgICAgKiBjb21wb25lbnRzIHN0b3JlZCBpbiAzIGJ5dGVzIGFuZCAxIGJ5dGUgb2YgYWxwaGEuIEl0IGhhcyBhCisgICAgICogQ29tcG9uZW50Q29sb3JNb2RlbCB3aXRoIGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfNEJZVEVfQUJHUiA9IDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV80QllURV9BQkdSX1BSRSBpbmRpY2F0ZXMgYW4gaW1hZ2Ugd2l0aCA4IGJpdCBSR0JBIGNvbG9yCisgICAgICogY29tcG9uZW50cyBzdG9yZWQgaW4gMyBieXRlcyBhbmQgMSBieXRlIGZvciBhbHBoYS4gVGhlIGltYWdlIGhhcyBhCisgICAgICogQ29tcG9uZW50Q29sb3JNb2RlbCB3aXRoIGFscGhhLiBUaGUgY29sb3IgZGF0YSBpcyBwcmUtbXVsdGlwbGllZCB3aXRoCisgICAgICogYWxwaGEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV80QllURV9BQkdSX1BSRSA9IDc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9VU0hPUlRfNTY1X1JHQiBpbmRpY2F0ZXMgYW4gaW1hZ2Ugd2l0aCA1NjUgUkdCIGNvbG9yCisgICAgICogY29tcG9uZW50cyAoNS1iaXRzIHJlZCwgNi1iaXRzIGdyZWVuLCA1LWJpdHMgYmx1ZSkgd2l0aCBubyBhbHBoYS4gVGhpcworICAgICAqIGltYWdlIGhhcyBhIERpcmVjdENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9VU0hPUlRfNTY1X1JHQiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9VU0hPUlRfNTU1X1JHQiBpbmRpY2F0ZXMgYW4gaW1hZ2Ugd2l0aCA1NTUgUkdCIGNvbG9yCisgICAgICogY29tcG9uZW50cyAoNS1iaXRzIHJlZCwgNS1iaXRzIGdyZWVuLCA1LWJpdHMgYmx1ZSkgd2l0aCBubyBhbHBoYS4gVGhpcworICAgICAqIGltYWdlIGhhcyBhIERpcmVjdENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9VU0hPUlRfNTU1X1JHQiA9IDk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9CWVRFX0dSQVkgaW5kaWNhdGVzIGEgdW5zaWduZWQgYnl0ZSBpbWFnZS4gVGhpcyBpbWFnZQorICAgICAqIGhhcyBhIENvbXBvbmVudENvbG9yTW9kZWwgd2l0aCBhIENTX0dSQVkgQ29sb3JTcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0JZVEVfR1JBWSA9IDEwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRZUEVfVVNIT1JUX0dSQVkgaW5kaWNhdGVzIGFuIHVuc2lnbmVkIHNob3J0IGltYWdlLiBUaGlzCisgICAgICogaW1hZ2UgaGFzIGEgQ29tcG9uZW50Q29sb3JNb2RlbCB3aXRoIGEgQ1NfR1JBWSBDb2xvclNwYWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfVVNIT1JUX0dSQVkgPSAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0JZVEVfQklOQVJZIGluZGljYXRlcyBhbiBvcGFxdWUgYnl0ZS1wYWNrZWQgMSwgMiBvciA0CisgICAgICogYml0IGltYWdlLiBUaGUgaW1hZ2UgaGFzIGFuIEluZGV4Q29sb3JNb2RlbCB3aXRob3V0IGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQllURV9CSU5BUlkgPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0JZVEVfSU5ERVhFRCBpbmRpY2F0ZXMgYW4gaW5kZXhlZCBieXRlIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQllURV9JTkRFWEVEID0gMTM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQUxQSEFfTUFTSy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUxQSEFfTUFTSyA9IDB4ZmYwMDAwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVEX01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFRF9NQVNLID0gMHgwMGZmMDAwMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBHUkVFTl9NQVNLLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUkVFTl9NQVNLID0gMHgwMDAwZmYwMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBCTFVFX01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMVUVfTUFTSyA9IDB4MDAwMDAwZmY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVEX0JHUl9NQVNLLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRURfQkdSX01BU0sgPSAweDAwMDAwMGZmOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEdSRUVOX0JHUl9NQVNLLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUkVFTl9CR1JfTUFTSyA9IDB4MDAwMGZmMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQkxVRV9CR1JfTUFTSy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxVRV9CR1JfTUFTSyA9IDB4MDBmZjAwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVEXzU2NV9NQVNLLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRURfNTY1X01BU0sgPSAweGY4MDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgR1JFRU5fNTY1X01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSRUVOXzU2NV9NQVNLID0gMHgwN2UwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEJMVUVfNTY1X01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMVUVfNTY1X01BU0sgPSAweDAwMWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUkVEXzU1NV9NQVNLLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRURfNTU1X01BU0sgPSAweDdjMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgR1JFRU5fNTU1X01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSRUVOXzU1NV9NQVNLID0gMHgwM2UwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEJMVUVfNTU1X01BU0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMVUVfNTU1X01BU0sgPSAweDAwMWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY20uCisgICAgICovCisgICAgcHJpdmF0ZSBDb2xvck1vZGVsIGNtOworCisgICAgLyoqCisgICAgICogVGhlIHJhc3Rlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFdyaXRhYmxlUmFzdGVyIHJhc3RlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBpbWFnZSB0eXBlLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IGltYWdlVHlwZTsKKworICAgIC8qKgorICAgICAqIFRoZSBwcm9wZXJ0aWVzLgorICAgICAqLworICAgIHByaXZhdGUgSGFzaHRhYmxlPD8sID8+IHByb3BlcnRpZXM7CisKKyAgICAvLyBTdXJmYWNlIG9mIHRoZSBCdWZmZXJlZCBJbWFnZSAtIHVzZWQgZm9yIGJsaXR0aW5nIG9uZSBCdWZmZXJlZCBJbWFnZQorICAgIC8vIG9uIHRoZSBvdGhlciBvbmUgb3Igb24gdGhlIENvbXBvbmVudAorICAgIC8qKgorICAgICAqIFRoZSBpbWFnZSBzdXJmLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgSW1hZ2VTdXJmYWNlIGltYWdlU3VyZjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCdWZmZXJlZEltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBDb2xvck1vZGVsLCBhbmQKKyAgICAgKiBXcml0YWJsZVJhc3RlciBvYmplY3RzLiBUaGUgUmFzdGVyIGRhdGEgY2FuIGJlIGJlIGRpdmlkZWQgb3IgbXVsdGlwbGllZAorICAgICAqIGJ5IGFscGhhLiBJdCBkZXBlbmRzIG9uIHRoZSBhbHBoYVByZW11bHRpcGxpZWQgc3RhdGUgaW4gdGhlIENvbG9yTW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGNtCisgICAgICogICAgICAgICAgICB0aGUgQ29sb3JNb2RlbCBvZiB0aGUgbmV3IGltYWdlLgorICAgICAqIEBwYXJhbSByYXN0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBXcml0YWJsZVJhc3RlciBvZiB0aGUgbmV3IGltYWdlLgorICAgICAqIEBwYXJhbSBpc1Jhc3RlclByZW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUgdGhlIGRhdGEgb2YgdGhlIHNwZWNpZmllZCBSYXN0ZXIgaXMgcHJlLW11bHRpcGxpZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGFscGhhLgorICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydGllcyBvZiBuZXcgSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2UoQ29sb3JNb2RlbCBjbSwgV3JpdGFibGVSYXN0ZXIgcmFzdGVyLCBib29sZWFuIGlzUmFzdGVyUHJlbXVsdGlwbGllZCwKKyAgICAgICAgICAgIEhhc2h0YWJsZTw/LCA/PiBwcm9wZXJ0aWVzKSB7CisgICAgICAgIGlmICghY20uaXNDb21wYXRpYmxlUmFzdGVyKHJhc3RlcikpIHsKKyAgICAgICAgICAgIC8vIGF3dC40RD1UaGUgcmFzdGVyIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgQ29sb3JNb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40RCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHJhc3Rlci5nZXRNaW5YKCkgIT0gMCB8fCByYXN0ZXIuZ2V0TWluWSgpICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMjg9bWluWCBvciBtaW5ZIG9mIHRoaXMgcmFzdGVyIG5vdCBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyOCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jbSA9IGNtOworICAgICAgICB0aGlzLnJhc3RlciA9IHJhc3RlcjsKKyAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllczsKKworICAgICAgICBjb2VyY2VEYXRhKGlzUmFzdGVyUHJlbXVsdGlwbGllZCk7CisKKyAgICAgICAgaW1hZ2VUeXBlID0gU3VyZmFjZS5nZXRUeXBlKGNtLCByYXN0ZXIpOworCisgICAgICAgIGltYWdlU3VyZiA9IGNyZWF0ZUltYWdlU3VyZmFjZShpbWFnZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCdWZmZXJlZEltYWdlIHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCwgaGVpZ2h0CisgICAgICogcHJlZGVmaW5lZCBpbWFnZSB0eXBlIChUWVBFX0JZVEVfQklOQVJZIG9yIFRZUEVfQllURV9JTkRFWEVEKSBhbmQgdGhlCisgICAgICogc3BlY2lmaWVkIEluZGV4Q29sb3JNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBuZXcgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBuZXcgaW1hZ2UuCisgICAgICogQHBhcmFtIGltYWdlVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHByZWRlZmluZWQgaW1hZ2UgdHlwZS4KKyAgICAgKiBAcGFyYW0gY20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgSW5kZXhDb2xvck1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlKGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGltYWdlVHlwZSwgSW5kZXhDb2xvck1vZGVsIGNtKSB7CisgICAgICAgIHN3aXRjaCAoaW1hZ2VUeXBlKSB7CisgICAgICAgICAgICBjYXNlIFRZUEVfQllURV9CSU5BUlk6CisgICAgICAgICAgICAgICAgaWYgKGNtLmhhc0FscGhhKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjIyNz1UaGlzIGltYWdlIHR5cGUgY2FuJ3QgaGF2ZSBhbHBoYQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyNyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgcGl4ZWxfYml0cyA9IDA7CisgICAgICAgICAgICAgICAgaW50IG1hcFNpemUgPSBjbS5nZXRNYXBTaXplKCk7CisgICAgICAgICAgICAgICAgaWYgKG1hcFNpemUgPD0gMikgeworICAgICAgICAgICAgICAgICAgICBwaXhlbF9iaXRzID0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1hcFNpemUgPD0gNCkgeworICAgICAgICAgICAgICAgICAgICBwaXhlbF9iaXRzID0gMjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1hcFNpemUgPD0gMTYpIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWxfYml0cyA9IDQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjIyMT1UaGUgaW1hZ2VUeXBlIGlzIFRZUEVfQllURV9CSU5BUlkgYW5kIHRoZSBjb2xvcgorICAgICAgICAgICAgICAgICAgICAvLyBtYXAgaGFzIG1vcmUgdGhhbiAxNiBlbnRyaWVzCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjIxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmFzdGVyID0gUmFzdGVyLmNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfQllURSwgd2lkdGgsIGhlaWdodCwgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsX2JpdHMsIG51bGwpOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIFRZUEVfQllURV9JTkRFWEVEOgorICAgICAgICAgICAgICAgIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfQllURSwgd2lkdGgsIGhlaWdodCwgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4yMjI9VGhlIGltYWdlVHlwZSBpcyBub3QgVFlQRV9CWVRFX0JJTkFSWSBvcgorICAgICAgICAgICAgICAgIC8vIFRZUEVfQllURV9JTkRFWEVECisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMjIiKSk7IC8vJE5PTi1OTFMtMSQKKworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFjbS5pc0NvbXBhdGlibGVSYXN0ZXIocmFzdGVyKSkgeworICAgICAgICAgICAgLy8gYXd0LjIyMz1UaGUgaW1hZ2VUeXBlIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggQ29sb3JNb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY20gPSBjbTsKKyAgICAgICAgdGhpcy5pbWFnZVR5cGUgPSBpbWFnZVR5cGU7CisgICAgICAgIGltYWdlU3VyZiA9IGNyZWF0ZUltYWdlU3VyZmFjZShpbWFnZVR5cGUpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEJ1ZmZlcmVkSW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHdpZHRoLCBoZWlnaHQgYW5kCisgICAgICogcHJlZGVmaW5lZCBpbWFnZSB0eXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIG5ldyBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIG5ldyBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaW1hZ2VUeXBlCisgICAgICogICAgICAgICAgICB0aGUgcHJlZGVmaW5lZCBpbWFnZSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlKGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGltYWdlVHlwZSkgeworCisgICAgICAgIHN3aXRjaCAoaW1hZ2VUeXBlKSB7CisgICAgICAgICAgICBjYXNlIFRZUEVfSU5UX1JHQjoKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBEaXJlY3RDb2xvck1vZGVsKDI0LCBSRURfTUFTSywgR1JFRU5fTUFTSywgQkxVRV9NQVNLKTsKKyAgICAgICAgICAgICAgICByYXN0ZXIgPSBjbS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgVFlQRV9JTlRfQVJHQjoKKyAgICAgICAgICAgICAgICBjbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICAgICAgICAgIHJhc3RlciA9IGNtLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3Rlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBUWVBFX0lOVF9BUkdCX1BSRToKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBEaXJlY3RDb2xvck1vZGVsKENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19zUkdCKSwgMzIsIFJFRF9NQVNLLAorICAgICAgICAgICAgICAgICAgICAgICAgR1JFRU5fTUFTSywgQkxVRV9NQVNLLCBBTFBIQV9NQVNLLCB0cnVlLCBEYXRhQnVmZmVyLlRZUEVfSU5UKTsKKworICAgICAgICAgICAgICAgIHJhc3RlciA9IGNtLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3Rlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBUWVBFX0lOVF9CR1I6CisgICAgICAgICAgICAgICAgY20gPSBuZXcgRGlyZWN0Q29sb3JNb2RlbCgyNCwgUkVEX0JHUl9NQVNLLCBHUkVFTl9CR1JfTUFTSywgQkxVRV9CR1JfTUFTSyk7CisKKyAgICAgICAgICAgICAgICByYXN0ZXIgPSBjbS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgVFlQRV8zQllURV9CR1I6IHsKKyAgICAgICAgICAgICAgICBpbnQgYml0c1tdID0geworICAgICAgICAgICAgICAgICAgICAgICAgOCwgOCwgOAorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgaW50IGJhbmRPZmZzZXRzW10gPSB7CisgICAgICAgICAgICAgICAgICAgICAgICAyLCAxLCAwCisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBDb21wb25lbnRDb2xvck1vZGVsKENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19zUkdCKSwgYml0cywKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBmYWxzZSwgVHJhbnNwYXJlbmN5Lk9QQVFVRSwgRGF0YUJ1ZmZlci5UWVBFX0JZVEUpOworCisgICAgICAgICAgICAgICAgcmFzdGVyID0gUmFzdGVyLmNyZWF0ZUludGVybGVhdmVkUmFzdGVyKERhdGFCdWZmZXIuVFlQRV9CWVRFLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggKiAzLCAzLCBiYW5kT2Zmc2V0cywgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgVFlQRV80QllURV9BQkdSOiB7CisgICAgICAgICAgICAgICAgaW50IGJpdHNbXSA9IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIDgsIDgsIDgsIDgKKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIGludCBiYW5kT2Zmc2V0c1tdID0geworICAgICAgICAgICAgICAgICAgICAgICAgMywgMiwgMSwgMAorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgY20gPSBuZXcgQ29tcG9uZW50Q29sb3JNb2RlbChDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQiksIGJpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBmYWxzZSwgVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5ULCBEYXRhQnVmZmVyLlRZUEVfQllURSk7CisKKyAgICAgICAgICAgICAgICByYXN0ZXIgPSBSYXN0ZXIuY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHdpZHRoLCBoZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCAqIDQsIDQsIGJhbmRPZmZzZXRzLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBUWVBFXzRCWVRFX0FCR1JfUFJFOiB7CisgICAgICAgICAgICAgICAgaW50IGJpdHNbXSA9IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIDgsIDgsIDgsIDgKKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIGludCBiYW5kT2Zmc2V0c1tdID0geworICAgICAgICAgICAgICAgICAgICAgICAgMywgMiwgMSwgMAorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgY20gPSBuZXcgQ29tcG9uZW50Q29sb3JNb2RlbChDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQiksIGJpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCB0cnVlLCBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQsIERhdGFCdWZmZXIuVFlQRV9CWVRFKTsKKworICAgICAgICAgICAgICAgIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfQllURSwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoICogNCwgNCwgYmFuZE9mZnNldHMsIG51bGwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIFRZUEVfVVNIT1JUXzU2NV9SR0I6CisgICAgICAgICAgICAgICAgY20gPSBuZXcgRGlyZWN0Q29sb3JNb2RlbChDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQiksIDE2LAorICAgICAgICAgICAgICAgICAgICAgICAgUkVEXzU2NV9NQVNLLCBHUkVFTl81NjVfTUFTSywgQkxVRV81NjVfTUFTSywgMCwgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUKTsKKworICAgICAgICAgICAgICAgIHJhc3RlciA9IGNtLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3Rlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBUWVBFX1VTSE9SVF81NTVfUkdCOgorICAgICAgICAgICAgICAgIGNtID0gbmV3IERpcmVjdENvbG9yTW9kZWwoQ29sb3JTcGFjZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpLCAxNSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFJFRF81NTVfTUFTSywgR1JFRU5fNTU1X01BU0ssIEJMVUVfNTU1X01BU0ssIDAsIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCk7CisKKyAgICAgICAgICAgICAgICByYXN0ZXIgPSBjbS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgVFlQRV9CWVRFX0dSQVk6IHsKKyAgICAgICAgICAgICAgICBpbnQgYml0c1tdID0geworICAgICAgICAgICAgICAgICAgICA4CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBDb21wb25lbnRDb2xvck1vZGVsKENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19HUkFZKSwgYml0cywKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBmYWxzZSwgVHJhbnNwYXJlbmN5Lk9QQVFVRSwgRGF0YUJ1ZmZlci5UWVBFX0JZVEUpOworCisgICAgICAgICAgICAgICAgcmFzdGVyID0gY20uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHdpZHRoLCBoZWlnaHQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIFRZUEVfVVNIT1JUX0dSQVk6IHsKKyAgICAgICAgICAgICAgICBpbnQgYml0c1tdID0geworICAgICAgICAgICAgICAgICAgICAxNgorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgY20gPSBuZXcgQ29tcG9uZW50Q29sb3JNb2RlbChDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1NfR1JBWSksIGJpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UsIFRyYW5zcGFyZW5jeS5PUEFRVUUsIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQpOworICAgICAgICAgICAgICAgIHJhc3RlciA9IGNtLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3Rlcih3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBUWVBFX0JZVEVfQklOQVJZOiB7CisgICAgICAgICAgICAgICAgaW50IGNvbG9yTWFwW10gPSB7CisgICAgICAgICAgICAgICAgICAgICAgICAwLCAweGZmZmZmZgorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgY20gPSBuZXcgSW5kZXhDb2xvck1vZGVsKDEsIDIsIGNvbG9yTWFwLCAwLCBmYWxzZSwgLTEsIERhdGFCdWZmZXIuVFlQRV9CWVRFKTsKKworICAgICAgICAgICAgICAgIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVQYWNrZWRSYXN0ZXIoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHdpZHRoLCBoZWlnaHQsIDEsIDEsIG51bGwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIFRZUEVfQllURV9JTkRFWEVEOiB7CisgICAgICAgICAgICAgICAgaW50IGNvbG9yTWFwW10gPSBuZXcgaW50WzI1Nl07CisgICAgICAgICAgICAgICAgaW50IGkgPSAwOworICAgICAgICAgICAgICAgIGZvciAoaW50IHIgPSAwOyByIDwgMjU2OyByICs9IDUxKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGcgPSAwOyBnIDwgMjU2OyBnICs9IDUxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8IDI1NjsgYiArPSA1MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTWFwW2ldID0gKHIgPDwgMTYpIHwgKGcgPDwgOCkgfCBiOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGludCBncmF5ID0gMHgxMjsKKyAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IDI1NjsgaSsrLCBncmF5ICs9IDYpIHsKKyAgICAgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gPSAoZ3JheSA8PCAxNikgfCAoZ3JheSA8PCA4KSB8IGdyYXk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNtID0gbmV3IEluZGV4Q29sb3JNb2RlbCg4LCAyNTYsIGNvbG9yTWFwLCAwLCBmYWxzZSwgLTEsIERhdGFCdWZmZXIuVFlQRV9CWVRFKTsKKyAgICAgICAgICAgICAgICByYXN0ZXIgPSBSYXN0ZXIuY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHdpZHRoLCBoZWlnaHQsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKworICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjI0PVVua25vd24gaW1hZ2UgdHlwZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjI0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5pbWFnZVR5cGUgPSBpbWFnZVR5cGU7CisgICAgICAgIGltYWdlU3VyZiA9IGNyZWF0ZUltYWdlU3VyZmFjZShpbWFnZVR5cGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgcmV0dXJuIGdldFByb3BlcnR5KG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjIyNT1Qcm9wZXJ0eSBuYW1lIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMjUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAocHJvcGVydGllcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gSW1hZ2UuVW5kZWZpbmVkUHJvcGVydHk7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IHByb3BlcnR5ID0gcHJvcGVydGllcy5nZXQobmFtZSk7CisgICAgICAgIGlmIChwcm9wZXJ0eSA9PSBudWxsKSB7CisgICAgICAgICAgICBwcm9wZXJ0eSA9IEltYWdlLlVuZGVmaW5lZFByb3BlcnR5OworICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm9wZXJ0eTsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY29weURhdGEoV3JpdGFibGVSYXN0ZXIgb3V0UmFzdGVyKSB7CisgICAgICAgIGlmIChvdXRSYXN0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgb3V0UmFzdGVyID0gUmFzdGVyLmNyZWF0ZVdyaXRhYmxlUmFzdGVyKHJhc3Rlci5nZXRTYW1wbGVNb2RlbCgpLCBuZXcgUG9pbnQocmFzdGVyCisgICAgICAgICAgICAgICAgICAgIC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSwgcmFzdGVyLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpKSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgdyA9IG91dFJhc3Rlci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgaCA9IG91dFJhc3Rlci5nZXRIZWlnaHQoKTsKKyAgICAgICAgaW50IG1pblggPSBvdXRSYXN0ZXIuZ2V0TWluWCgpOworICAgICAgICBpbnQgbWluWSA9IG91dFJhc3Rlci5nZXRNaW5ZKCk7CisKKyAgICAgICAgT2JqZWN0IGRhdGEgPSBudWxsOworCisgICAgICAgIGRhdGEgPSByYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKG1pblgsIG1pblksIHcsIGgsIGRhdGEpOworICAgICAgICBvdXRSYXN0ZXIuc2V0RGF0YUVsZW1lbnRzKG1pblgsIG1pblksIHcsIGgsIGRhdGEpOworCisgICAgICAgIHJldHVybiBvdXRSYXN0ZXI7CisgICAgfQorCisgICAgcHVibGljIFJhc3RlciBnZXREYXRhKFJlY3RhbmdsZSByZWN0KSB7CisgICAgICAgIGludCBtaW5YID0gcmVjdC54OworICAgICAgICBpbnQgbWluWSA9IHJlY3QueTsKKyAgICAgICAgaW50IHcgPSByZWN0LndpZHRoOworICAgICAgICBpbnQgaCA9IHJlY3QuaGVpZ2h0OworCisgICAgICAgIFNhbXBsZU1vZGVsIHNtID0gcmFzdGVyLmdldFNhbXBsZU1vZGVsKCk7CisgICAgICAgIFNhbXBsZU1vZGVsIG5zbSA9IHNtLmNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbCh3LCBoKTsKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgb3V0ciA9IFJhc3Rlci5jcmVhdGVXcml0YWJsZVJhc3Rlcihuc20sIHJlY3QuZ2V0TG9jYXRpb24oKSk7CisgICAgICAgIE9iamVjdCBkYXRhID0gbnVsbDsKKworICAgICAgICBkYXRhID0gcmFzdGVyLmdldERhdGFFbGVtZW50cyhtaW5YLCBtaW5ZLCB3LCBoLCBkYXRhKTsKKyAgICAgICAgb3V0ci5zZXREYXRhRWxlbWVudHMobWluWCwgbWluWSwgdywgaCwgZGF0YSk7CisgICAgICAgIHJldHVybiBvdXRyOworICAgIH0KKworICAgIHB1YmxpYyBWZWN0b3I8UmVuZGVyZWRJbWFnZT4gZ2V0U291cmNlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFByb3BlcnR5TmFtZXMoKSB7CisgICAgICAgIGlmIChwcm9wZXJ0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFZlY3RvcjxTdHJpbmc+IHYgPSBuZXcgVmVjdG9yPFN0cmluZz4oKTsKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbjw/PiBlID0gcHJvcGVydGllcy5rZXlzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHYuYWRkKChTdHJpbmcpZS5uZXh0RWxlbWVudCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGludCBzaXplID0gdi5zaXplKCk7CisgICAgICAgIGlmIChzaXplID4gMCkgeworICAgICAgICAgICAgU3RyaW5nIG5hbWVzW10gPSBuZXcgU3RyaW5nW3NpemVdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBuYW1lc1tpXSA9IHYuZWxlbWVudEF0KGkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5hbWVzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiQnVmZmVyZWRJbWFnZUAiICsgSW50ZWdlci50b0hleFN0cmluZyhoYXNoQ29kZSgpKSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiOiB0eXBlID0gIiArIGltYWdlVHlwZSArICIgIiArIGNtICsgIiAiICsgcmFzdGVyOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH0KKworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBnZXRXcml0YWJsZVRpbGUoaW50IHRpbGVYLCBpbnQgdGlsZVkpIHsKKyAgICAgICAgcmV0dXJuIHJhc3RlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBXcml0YWJsZVJhc3RlciBvZiB0aGlzIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIgb2YgdGhpcyBCdWZmZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBnZXRSYXN0ZXIoKSB7CisgICAgICAgIHJldHVybiByYXN0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIFdyaXRhYmxlUmFzdGVyIG9iamVjdCB3aGljaCBjb250YWlucyB0aGUgYWxwaGEgY2hhbm5lbCBvZgorICAgICAqIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0IHdpdGggQ29sb3JNb2RlbCBvYmplY3RzIHRoYXQgc3VwcG9ydHMgYSBzZXBhcmF0ZQorICAgICAqIGFscGhhIGNoYW5uZWwgc3VjaCBhcyBDb21wb25lbnRDb2xvck1vZGVsIG9yIERpcmVjdENvbG9yTW9kZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBhbHBoYSBjaGFubmVsIG9mCisgICAgICogICAgICAgICB0aGlzIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldEFscGhhUmFzdGVyKCkgeworICAgICAgICByZXR1cm4gY20uZ2V0QWxwaGFSYXN0ZXIocmFzdGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVUaWxlT2JzZXJ2ZXIoVGlsZU9ic2VydmVyIHRvKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVGlsZU9ic2VydmVyKFRpbGVPYnNlcnZlciB0bykgeworICAgIH0KKworICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBnZXRTYW1wbGVNb2RlbCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRTYW1wbGVNb2RlbCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERhdGEoUmFzdGVyIHIpIHsKKworICAgICAgICBSZWN0YW5nbGUgZnJvbSA9IHIuZ2V0Qm91bmRzKCk7CisgICAgICAgIFJlY3RhbmdsZSB0byA9IHJhc3Rlci5nZXRCb3VuZHMoKTsKKyAgICAgICAgUmVjdGFuZ2xlIGludGVyc2VjdGlvbiA9IHRvLmludGVyc2VjdGlvbihmcm9tKTsKKworICAgICAgICBpbnQgbWluWCA9IGludGVyc2VjdGlvbi54OworICAgICAgICBpbnQgbWluWSA9IGludGVyc2VjdGlvbi55OworICAgICAgICBpbnQgdyA9IGludGVyc2VjdGlvbi53aWR0aDsKKyAgICAgICAgaW50IGggPSBpbnRlcnNlY3Rpb24uaGVpZ2h0OworCisgICAgICAgIE9iamVjdCBkYXRhID0gbnVsbDsKKworICAgICAgICBkYXRhID0gci5nZXREYXRhRWxlbWVudHMobWluWCwgbWluWSwgdywgaCwgZGF0YSk7CisgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMobWluWCwgbWluWSwgdywgaCwgZGF0YSk7CisgICAgfQorCisgICAgcHVibGljIFJhc3RlciBnZXRUaWxlKGludCB0aWxlWCwgaW50IHRpbGVZKSB7CisgICAgICAgIGlmICh0aWxlWCA9PSAwICYmIHRpbGVZID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiByYXN0ZXI7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXd0LjIyNj1Cb3RoIHRpbGVYIGFuZCB0aWxlWSBhcmUgbm90IGVxdWFsIHRvIDAKKyAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMjYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBwdWJsaWMgUmFzdGVyIGdldERhdGEoKSB7CisgICAgICAgIGludCB3ID0gcmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgIGludCBoID0gcmFzdGVyLmdldEhlaWdodCgpOworICAgICAgICBpbnQgbWluWCA9IHJhc3Rlci5nZXRNaW5YKCk7CisgICAgICAgIGludCBtaW5ZID0gcmFzdGVyLmdldE1pblkoKTsKKworICAgICAgICBXcml0YWJsZVJhc3RlciBvdXRyID0gUmFzdGVyLmNyZWF0ZVdyaXRhYmxlUmFzdGVyKHJhc3Rlci5nZXRTYW1wbGVNb2RlbCgpLCBuZXcgUG9pbnQocmFzdGVyCisgICAgICAgICAgICAgICAgLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpLCByYXN0ZXIuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkpKTsKKworICAgICAgICBPYmplY3QgZGF0YSA9IG51bGw7CisKKyAgICAgICAgZGF0YSA9IHJhc3Rlci5nZXREYXRhRWxlbWVudHMobWluWCwgbWluWSwgdywgaCwgZGF0YSk7CisgICAgICAgIG91dHIuc2V0RGF0YUVsZW1lbnRzKG1pblgsIG1pblksIHcsIGgsIGRhdGEpOworCisgICAgICAgIHJldHVybiBvdXRyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZVByb2R1Y2VyIGdldFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlU291cmNlKHRoaXMsIHByb3BlcnRpZXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0V2lkdGgoSW1hZ2VPYnNlcnZlciBvYnNlcnZlcikgeworICAgICAgICByZXR1cm4gcmFzdGVyLmdldFdpZHRoKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRIZWlnaHQoSW1hZ2VPYnNlcnZlciBvYnNlcnZlcikgeworICAgICAgICByZXR1cm4gcmFzdGVyLmdldEhlaWdodCgpOworICAgIH0KKworICAgIHB1YmxpYyBDb2xvck1vZGVsIGdldENvbG9yTW9kZWwoKSB7CisgICAgICAgIHJldHVybiBjbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHRoaXMgQnVmZmVyZWRJbWFnZSBhcyBhIHN1YmltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgeCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHN1YmltYWdlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBzdWJpbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGdldFN1YmltYWdlKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7CisgICAgICAgIFdyaXRhYmxlUmFzdGVyIHdyID0gcmFzdGVyLmNyZWF0ZVdyaXRhYmxlQ2hpbGQoeCwgeSwgdywgaCwgMCwgMCwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShjbSwgd3IsIGNtLmlzQWxwaGFQcmVtdWx0aXBsaWVkKCksIHByb3BlcnRpZXMpOworICAgIH0KKworICAgIHB1YmxpYyBQb2ludFtdIGdldFdyaXRhYmxlVGlsZUluZGljZXMoKSB7CisgICAgICAgIFBvaW50IHBvaW50c1tdID0gbmV3IFBvaW50WzFdOworICAgICAgICBwb2ludHNbMF0gPSBuZXcgUG9pbnQoMCwgMCk7CisgICAgICAgIHJldHVybiBwb2ludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgR3JhcGhpY3MyRCBvYmplY3Qgd2hpY2ggYWxsb3dzIHRvIGRyYXcgaW50byB0aGlzCisgICAgICogQnVmZmVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBncmFwaGljczJEIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JhcGhpY3MyRCBjcmVhdGVHcmFwaGljcygpIHsKKyAgICAgICAgR3JhcGhpY3NFbnZpcm9ubWVudCBnZSA9IEdyYXBoaWNzRW52aXJvbm1lbnQuZ2V0TG9jYWxHcmFwaGljc0Vudmlyb25tZW50KCk7CisgICAgICAgIC8vIHJldHVybiBnZS5jcmVhdGVHcmFwaGljcyh0aGlzKTsKKyAgICAgICAgLy8gPz8/QVdUIGhhY2ssIEZJWE1FCisgICAgICAgIC8vIHJldHVybiBBbmRyb2lkR3JhcGhpY3MyRC5nZXRJbnN0YW5jZSgpOworICAgICAgICAvLyB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3MgZ2V0R3JhcGhpY3MoKSB7CisgICAgICAgIHJldHVybiBjcmVhdGVHcmFwaGljcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvZXJjZXMgdGhlIGRhdGEgdG8gYWNoaWV2ZSB0aGUgc3RhdGUgd2hpY2ggaXMgc3BlY2lmaWVkIGJ5IHRoZQorICAgICAqIGlzQWxwaGFQcmVtdWx0aXBsaWVkIHZhcmlhYmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpc0FscGhhUHJlbXVsdGlwbGllZAorICAgICAqICAgICAgICAgICAgdGhlIGlzIGFscGhhIHByZS1tdWx0aXBsaWVkIHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvZXJjZURhdGEoYm9vbGVhbiBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICBpZiAoY20uaGFzQWxwaGEoKSAmJiBjbS5pc0FscGhhUHJlbXVsdGlwbGllZCgpICE9IGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgICAgICBjbSA9IGNtLmNvZXJjZURhdGEocmFzdGVyLCBpc0FscGhhUHJlbXVsdGlwbGllZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIGNvbG9ycyBpbiB0aGUgVFlQRV9JTlRfQVJHQiBjb2xvciBtb2RlbCBhbmQgZGVmYXVsdCBzUkdCCisgICAgICogY29sb3Igc3BhY2Ugb2YgdGhlIHNwZWNpZmllZCBhcmVhIG9mIHRoaXMgQnVmZmVyZWRJbWFnZS4gVGhlIHJlc3VsdCBhcnJheQorICAgICAqIGlzIGNvbXBvc2VkIGJ5IHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtOgorICAgICAqIDxwPgorICAgICAqIHBpeGVsID0gcmdiQXJyYXlbb2Zmc2V0ICsgKHktc3RhcnRZKSpzY2Fuc2l6ZSArICh4LXN0YXJ0WCldCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdGFydFgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBYIGFyZWEgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gc3RhcnRZCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgWSBhcmVhIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgYXJlYS4KKyAgICAgKiBAcGFyYW0gcmdiQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHQgYXJyYXkgd2lsbCBiZSBzdG9yZWQgdG8gdGhpcyBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSByZ2JBcnJheSBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUgZm9yIHRoZSByZ2JBcnJheS4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGNvbG9ycyBmb3IgdGhlIHNwZWNpZmllZCBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRSR0IoaW50IHN0YXJ0WCwgaW50IHN0YXJ0WSwgaW50IHcsIGludCBoLCBpbnRbXSByZ2JBcnJheSwgaW50IG9mZnNldCwKKyAgICAgICAgICAgIGludCBzY2Fuc2l6ZSkgeworICAgICAgICBpZiAocmdiQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmdiQXJyYXkgPSBuZXcgaW50W29mZnNldCArIGggKiBzY2Fuc2l6ZV07CisgICAgICAgIH0KKworICAgICAgICBpbnQgb2ZmID0gb2Zmc2V0OworICAgICAgICBmb3IgKGludCB5ID0gc3RhcnRZOyB5IDwgc3RhcnRZICsgaDsgeSsrLCBvZmYgKz0gc2NhbnNpemUpIHsKKyAgICAgICAgICAgIGludCBpID0gb2ZmOworICAgICAgICAgICAgZm9yIChpbnQgeCA9IHN0YXJ0WDsgeCA8IHN0YXJ0WCArIHc7IHgrKywgaSsrKSB7CisgICAgICAgICAgICAgICAgcmdiQXJyYXlbaV0gPSBjbS5nZXRSR0IocmFzdGVyLmdldERhdGFFbGVtZW50cyh4LCB5LCBudWxsKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJnYkFycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgUkdCIHZhbHVlcyBmcm9tIHRoZSBzcGVjaWZpZWQgYXJyYXkgdG8gdGhlIHNwZWNpZmllZCBCdWZmZXJlZEltYWdlCisgICAgICogYXJlYS4gVGhlIHBpeGVscyBhcmUgaW4gdGhlIGRlZmF1bHQgUkdCIGNvbG9yIG1vZGVsIChUWVBFX0lOVF9BUkdCKSBhbmQKKyAgICAgKiBkZWZhdWx0IHNSR0IgY29sb3Igc3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIHN0YXJ0WAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IFggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gc3RhcnRZCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgWSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIEJ1ZmZlcmVkSW1hZ2UgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgQnVmZmVyZWRJbWFnZSBhcmVhLgorICAgICAqIEBwYXJhbSByZ2JBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIFJHQiB2YWx1ZXMuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgcmdiQXJyYXkgYXJyYXkuCisgICAgICogQHBhcmFtIHNjYW5zaXplCisgICAgICogICAgICAgICAgICB0aGUgc2NhbmxpbmUgc3RyaWRlIGZvciB0aGUgcmdiQXJyYXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UkdCKGludCBzdGFydFgsIGludCBzdGFydFksIGludCB3LCBpbnQgaCwgaW50W10gcmdiQXJyYXksIGludCBvZmZzZXQsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgaW50IG9mZiA9IG9mZnNldDsKKyAgICAgICAgZm9yIChpbnQgeSA9IHN0YXJ0WTsgeSA8IHN0YXJ0WSArIGg7IHkrKywgb2ZmICs9IHNjYW5zaXplKSB7CisgICAgICAgICAgICBpbnQgaSA9IG9mZjsKKyAgICAgICAgICAgIGZvciAoaW50IHggPSBzdGFydFg7IHggPCBzdGFydFggKyB3OyB4KyssIGkrKykgeworICAgICAgICAgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMoeCwgeSwgY20uZ2V0RGF0YUVsZW1lbnRzKHJnYkFycmF5W2ldLCBudWxsKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgdGhlIHNwZWNpZmllZCBSR0IgdmFsdWUgdG8gdGhlIHNwZWNpZmllZCBwaXhlbCBvZiB0aGlzCisgICAgICogQnVmZmVyZWRJbWFnZS4gVGhlIHBpeGVsIHNob3VsZCBiZSBpbiB0aGUgZGVmYXVsdCBSR0IgY29sb3IgbW9kZWwKKyAgICAgKiAoVFlQRV9JTlRfQVJHQikgYW5kIGRlZmF1bHQgc1JHQiBjb2xvciBzcGFjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSByZ2IKKyAgICAgKiAgICAgICAgICAgIHRoZSBSR0IgdmFsdWUgdG8gYmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRSR0IoaW50IHgsIGludCB5LCBpbnQgcmdiKSB7CisgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMoeCwgeSwgY20uZ2V0RGF0YUVsZW1lbnRzKHJnYiwgbnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVGlsZVdyaXRhYmxlKGludCB0aWxlWCwgaW50IHRpbGVZKSB7CisgICAgICAgIGlmICh0aWxlWCA9PSAwICYmIHRpbGVZID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIC8vIGF3dC4yMjY9Qm90aCB0aWxlWCBhbmQgdGlsZVkgYXJlIG5vdCBlcXVhbCB0byAwCisgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjI2IikpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVsZWFzZVdyaXRhYmxlVGlsZShpbnQgdGlsZVgsIGludCB0aWxlWSkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBjb2xvciBpbiB0aGUgVFlQRV9JTlRfQVJHQiBjb2xvciBtb2RlbCBhbmQgZGVmYXVsdCBzUkdCIGNvbG9yCisgICAgICogc3BhY2Ugb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEByZXR1cm4gdGhlIGNvbG9yIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaW4gdGhlIFRZUEVfSU5UX0FSR0IgY29sb3IgbW9kZWwKKyAgICAgKiAgICAgICAgIGFuZCBkZWZhdWx0IHNSR0IgY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSR0IoaW50IHgsIGludCB5KSB7CisgICAgICAgIHJldHVybiBjbS5nZXRSR0IocmFzdGVyLmdldERhdGFFbGVtZW50cyh4LCB5LCBudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGFscGhhIGlzIHByZS1tdWx0aXBsaWVkLCBmYWxzZSBpZiBhbHBoYSBpcyBub3QKKyAgICAgKiBwcmUtbXVsdGlwbGllZCBvciB0aGVyZSBpcyBubyBhbHBoYS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYWxwaGEgaXMgcHJlLW11bHRpcGxpZWQsIGZhbHNlIGlmIGFscGhhIGlzIG5vdAorICAgICAqICAgICAgICAgcHJlLW11bHRpcGxpZWQgb3IgdGhlcmUgaXMgbm8gYWxwaGEuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQoKSB7CisgICAgICAgIHJldHVybiBjbS5pc0FscGhhUHJlbXVsdGlwbGllZCgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc1RpbGVXcml0ZXJzKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHsKKyAgICAgICAgaW1hZ2VTdXJmLmRpc3Bvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFdpZHRoKCkgeworICAgICAgICByZXR1cm4gcmFzdGVyLmdldFdpZHRoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW1hZ2UgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBpbWFnZSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGltYWdlVHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRpbGVXaWR0aCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRXaWR0aCgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0VGlsZUhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRpbGVHcmlkWU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRpbGVHcmlkWE9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE51bVlUaWxlcygpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXROdW1YVGlsZXMoKSB7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TWluWSgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRNaW5ZKCk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNaW5YKCkgeworICAgICAgICByZXR1cm4gcmFzdGVyLmdldE1pblgoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1pblRpbGVZKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1pblRpbGVYKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBpbWFnZSBzdXJmYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbWFnZSBzdXJmYWNlLgorICAgICAqLworICAgIHByaXZhdGUgSW1hZ2VTdXJmYWNlIGNyZWF0ZUltYWdlU3VyZmFjZShpbnQgdHlwZSkgeworICAgICAgICByZXR1cm4gbmV3IEltYWdlU3VyZmFjZShnZXRDb2xvck1vZGVsKCksIGdldFJhc3RlcigpLCB0eXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbWFnZSBzdXJmYWNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGltYWdlIHN1cmZhY2UuCisgICAgICovCisgICAgSW1hZ2VTdXJmYWNlIGdldEltYWdlU3VyZmFjZSgpIHsKKyAgICAgICAgcmV0dXJuIGltYWdlU3VyZjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRyYW5zcGFyZW5jeSgpIHsKKyAgICAgICAgcmV0dXJuIGNtLmdldFRyYW5zcGFyZW5jeSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9CdWZmZXJlZEltYWdlRmlsdGVyLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQnVmZmVyZWRJbWFnZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiNmZjZjAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQnVmZmVyZWRJbWFnZUZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMzk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqICBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqICBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqICB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAgIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiAgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiAgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgQnVmZmVyZWRJbWFnZUZpbHRlciBjbGFzcyBwcm92aWRlcyBmaWx0ZXJpbmcgb3BlcmF0aW9ucyB0byB0aGUKKyAqIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0cyB1c2luZyBvcGVyYXRvcnMgd2hpY2ggaW1wbGVtZW50IEJ1ZmZlcmVkSW1hZ2VPcAorICogaW50ZXJmYWNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEJ1ZmZlcmVkSW1hZ2VGaWx0ZXIgZXh0ZW5kcyBJbWFnZUZpbHRlciBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgYWNjZXNzb3IuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yIGFjY2Vzc29yID0gQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yLmdldEluc3RhbmNlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3AuCisgICAgICovCisgICAgcHJpdmF0ZSBCdWZmZXJlZEltYWdlT3Agb3A7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmFzdGVyLgorICAgICAqLworICAgIHByaXZhdGUgV3JpdGFibGVSYXN0ZXIgcmFzdGVyOworCisgICAgLyoqCisgICAgICogVGhlIGkgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBpRGF0YVtdOworCisgICAgLyoqCisgICAgICogVGhlIGIgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGUgYkRhdGFbXTsKKworICAgIC8qKgorICAgICAqIFRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB3aWR0aDsKKworICAgIC8qKgorICAgICAqIFRoZSBoZWlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgaGVpZ2h0OworCisgICAgLyoqCisgICAgICogVGhlIGNtLgorICAgICAqLworICAgIHByaXZhdGUgQ29sb3JNb2RlbCBjbTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb3JjZWQgcmdiLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmb3JjZWRSR0IgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2ZlciB0eXBlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHRyYW5zZmVyVHlwZSA9IERhdGFCdWZmZXIuVFlQRV9VTkRFRklORUQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQnVmZmVyZWRJbWFnZUZpbHRlciB3aXRoIHRoZSBzcGVjaWZpZWQgQnVmZmVyZWRJbWFnZU9wCisgICAgICogb3BlcmF0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIG9wCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEJ1ZmZlcmVkSW1hZ2VPcCBvcGVyYXRvci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgQnVmZmVyZWRJbWFnZU9wIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2VGaWx0ZXIoQnVmZmVyZWRJbWFnZU9wIG9wKSB7CisgICAgICAgIGlmIChvcCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLm9wID0gb3A7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQnVmZmVyZWRJbWFnZU9wIG9wZXJhdG9yIGFzc29jaWF0ZWQgd2l0aCB0aGlzCisgICAgICogQnVmZmVyZWRJbWFnZUZpbHRlciBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQnVmZmVyZWRJbWFnZU9wIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEJ1ZmZlcmVkSW1hZ2VGaWx0ZXIKKyAgICAgKiAgICAgICAgIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZU9wIGdldEJ1ZmZlcmVkSW1hZ2VPcCgpIHsKKyAgICAgICAgcmV0dXJuIG9wOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERpbWVuc2lvbnMoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgIC8vIFN0b3AgaW1hZ2UgY29uc3VtaW5nIGlmIG5vIHBpeGVscyBleHBlY3RlZC4KKyAgICAgICAgaWYgKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApIHsKKyAgICAgICAgICAgIGNvbnN1bWVyLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5TVEFUSUNJTUFHRURPTkUpOworICAgICAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbG9yTW9kZWwoQ29sb3JNb2RlbCBtb2RlbCkgeworICAgICAgICBpZiAodGhpcy5jbSAhPSBudWxsICYmIHRoaXMuY20gIT0gbW9kZWwgJiYgcmFzdGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvcmNlUkdCKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmNtID0gbW9kZWw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGVbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgc2V0UGl4ZWxzKHgsIHksIHcsIGgsIG1vZGVsLCBwaXhlbHMsIG9mZiwgc2NhbnNpemUsIHRydWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgaW50W10gcGl4ZWxzLCBpbnQgb2ZmLAorICAgICAgICAgICAgaW50IHNjYW5zaXplKSB7CisgICAgICAgIHNldFBpeGVscyh4LCB5LCB3LCBoLCBtb2RlbCwgcGl4ZWxzLCBvZmYsIHNjYW5zaXplLCBmYWxzZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgaW1hZ2VDb21wbGV0ZShpbnQgc3RhdHVzKSB7CisgICAgICAgIGlmIChzdGF0dXMgPT0gU1RBVElDSU1BR0VET05FIHx8IHN0YXR1cyA9PSBTSU5HTEVGUkFNRURPTkUpIHsKKyAgICAgICAgICAgIEJ1ZmZlcmVkSW1hZ2UgYmltID0gbmV3IEJ1ZmZlcmVkSW1hZ2UoY20sIHJhc3RlciwgY20uaXNBbHBoYVByZW11bHRpcGxpZWQsIG51bGwpOworICAgICAgICAgICAgYmltID0gb3AuZmlsdGVyKGJpbSwgbnVsbCk7CisgICAgICAgICAgICBEYXRhQnVmZmVyIGRzdERiID0gYmltLmdldFJhc3RlcigpLmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgICAgIENvbG9yTW9kZWwgZHN0Q20gPSBiaW0uZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgaW50IGRzdFcgPSBiaW0uZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBkc3RIID0gYmltLmdldEhlaWdodCgpOworCisgICAgICAgICAgICBjb25zdW1lci5zZXREaW1lbnNpb25zKGRzdFcsIGRzdEgpOworCisgICAgICAgICAgICBpZiAoZHN0RGIuZ2V0RGF0YVR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfSU5UKSB7CisgICAgICAgICAgICAgICAgY29uc3VtZXIuc2V0Q29sb3JNb2RlbChkc3RDbSk7CisgICAgICAgICAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKDAsIDAsIGRzdFcsIGRzdEgsIGRzdENtLCBhY2Nlc3Nvci5nZXREYXRhSW50KGRzdERiKSwgMCwgZHN0Vyk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGRzdERiLmdldERhdGFUeXBlKCkgPT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUpIHsKKyAgICAgICAgICAgICAgICBjb25zdW1lci5zZXRDb2xvck1vZGVsKGRzdENtKTsKKyAgICAgICAgICAgICAgICBjb25zdW1lci5zZXRQaXhlbHMoMCwgMCwgZHN0VywgZHN0SCwgZHN0Q20sIGFjY2Vzc29yLmdldERhdGFCeXRlKGRzdERiKSwgMCwgZHN0Vyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCBkc3REYXRhW10gPSBiaW0uZ2V0UkdCKDAsIDAsIGRzdFcsIGRzdEgsIG51bGwsIDAsIGRzdFcpOworICAgICAgICAgICAgICAgIGRzdENtID0gQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgY29uc3VtZXIuc2V0Q29sb3JNb2RlbChkc3RDbSk7CisgICAgICAgICAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKDAsIDAsIGRzdFcsIGRzdEgsIGRzdENtLCBkc3REYXRhLCAwLCBkc3RXKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChzdGF0dXMgPT0gSU1BR0VFUlJPUiB8fCBzdGF0dXMgPT0gSU1BR0VBQk9SVEVEKSB7CisgICAgICAgICAgICByZXNldCgpOworICAgICAgICB9CisKKyAgICAgICAgY29uc3VtZXIuaW1hZ2VDb21wbGV0ZShzdGF0dXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBpeGVscy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHguCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5LgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgdy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGguCisgICAgICogQHBhcmFtIG1vZGVsCisgICAgICogICAgICAgICAgICB0aGUgbW9kZWwuCisgICAgICogQHBhcmFtIHBpeGVscworICAgICAqICAgICAgICAgICAgdGhlIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2ZmLgorICAgICAqIEBwYXJhbSBzY2Fuc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNjYW5zaXplLgorICAgICAqIEBwYXJhbSBpc0J5dGVEYXRhCisgICAgICogICAgICAgICAgICB0aGUgaXMgYnl0ZSBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIE9iamVjdCBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUsIGJvb2xlYW4gaXNCeXRlRGF0YSkgeworICAgICAgICAvLyBDaGVjayBib3VuZHMKKyAgICAgICAgLy8gTmVlZCB0byBjb3B5IG9ubHkgdGhlIHBpeGVscyB0aGF0IHdpbGwgZml0IGludG8gdGhlIGRlc3RpbmF0aW9uIGFyZWEKKyAgICAgICAgaWYgKHggPCAwKSB7CisgICAgICAgICAgICB3IC09IHg7CisgICAgICAgICAgICBvZmYgKz0geDsKKyAgICAgICAgICAgIHggPSAwOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHkgPCAwKSB7CisgICAgICAgICAgICBoIC09IHk7CisgICAgICAgICAgICBvZmYgKz0geSAqIHNjYW5zaXplOworICAgICAgICAgICAgeSA9IDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoeCArIHcgPiB3aWR0aCkgeworICAgICAgICAgICAgdyA9IHdpZHRoIC0geDsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh5ICsgaCA+IGhlaWdodCkgeworICAgICAgICAgICAgaCA9IGhlaWdodCAtIHk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgbW9kZWwKKyAgICAgICAgaWYgKHRoaXMuY20gPT0gbnVsbCkgeworICAgICAgICAgICAgc2V0Q29sb3JNb2RlbChtb2RlbCk7CisgICAgICAgIH0gZWxzZSBpZiAobW9kZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgbW9kZWwgPSB0aGlzLmNtOworICAgICAgICB9IGVsc2UgaWYgKCFtb2RlbC5lcXVhbHModGhpcy5jbSkpIHsKKyAgICAgICAgICAgIGZvcmNlUkdCKCk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGNhbkFycmF5Y29weTsKKyAgICAgICAgLy8gUHJvY2VzcyBwaXhlbHMKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VOREVGSU5FRDogeworICAgICAgICAgICAgICAgIGlmIChpc0J5dGVEYXRhKSB7CisgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyVHlwZSA9IERhdGFCdWZmZXIuVFlQRV9CWVRFOworICAgICAgICAgICAgICAgICAgICBjcmVhdGVSYXN0ZXIodHJhbnNmZXJUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gYkRhdGEgPSBuZXcgYnl0ZVt3aWR0aCpoZWlnaHRdOworICAgICAgICAgICAgICAgICAgICBjYW5BcnJheWNvcHkgPSAhZm9yY2VkUkdCOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJhbnNmZXJUeXBlID0gRGF0YUJ1ZmZlci5UWVBFX0lOVDsKKyAgICAgICAgICAgICAgICBjcmVhdGVSYXN0ZXIodHJhbnNmZXJUeXBlKTsKKyAgICAgICAgICAgICAgICAvLyBpRGF0YSA9IG5ldyBpbnRbd2lkdGgqaGVpZ2h0XTsKKyAgICAgICAgICAgICAgICBjYW5BcnJheWNvcHkgPSAhZm9yY2VkUkdCIHx8IG1vZGVsLmVxdWFscyhDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9IC8vIEFuZCBwcm9jZWVkIHRvIGNvcHkgdGhlIHBpeGVscworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOiB7CisgICAgICAgICAgICAgICAgaWYgKGlzQnl0ZURhdGEpIHsgLy8gVGhlcmUgYXJlIGludCBkYXRhIGFscmVhZHkgYnV0IHRoZSBuZXcgZGF0YQorICAgICAgICAgICAgICAgICAgICAvLyBhcmUgYnl0ZXMKKyAgICAgICAgICAgICAgICAgICAgZm9yY2VSR0IoKTsKKyAgICAgICAgICAgICAgICAgICAgY2FuQXJyYXljb3B5ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZvcmNlZFJHQiB8fCBtb2RlbC5lcXVhbHMoQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGNhbkFycmF5Y29weSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0gLy8gRWxzZSBmYWxsYmFjayB0byB0aGUgUkdCIGNvbnZlcnNpb24KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6IHsKKyAgICAgICAgICAgICAgICBpZiAoaXNCeXRlRGF0YSAmJiAhZm9yY2VkUkdCKSB7CisgICAgICAgICAgICAgICAgICAgIGNhbkFycmF5Y29weSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFJHQiBjb252ZXJzaW9uCisgICAgICAgICAgICAgICAgY2FuQXJyYXljb3B5ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkZWZhdWx0OiB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgb2ZmICs9IHg7CisgICAgICAgIGludCBtYXhPZmZzZXQgPSBvZmYgKyBoICogc2NhbnNpemU7CisgICAgICAgIGludCBkc3RPZmZzZXQgPSB4ICsgeSAqIHdpZHRoOworCisgICAgICAgIGlmIChjYW5BcnJheWNvcHkpIHsKKyAgICAgICAgICAgIE9iamVjdCBkc3RBcnJheSA9IGlzQnl0ZURhdGEgPyAoT2JqZWN0KWJEYXRhIDogKE9iamVjdClpRGF0YTsKKyAgICAgICAgICAgIGZvciAoOyBvZmYgPCBtYXhPZmZzZXQ7IG9mZiArPSBzY2Fuc2l6ZSwgZHN0T2Zmc2V0ICs9IHdpZHRoKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwaXhlbHMsIG9mZiwgZHN0QXJyYXksIGRzdE9mZnNldCwgdyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBSR0IgY29udmVyc2lvbgorICAgICAgICAgICAgZm9yICg7IG9mZiA8IG1heE9mZnNldDsgb2ZmICs9IHNjYW5zaXplLCBkc3RPZmZzZXQgKz0gd2lkdGgpIHsKKyAgICAgICAgICAgICAgICBpbnQgc3JjUG9zID0gb2ZmOworICAgICAgICAgICAgICAgIGludCBkc3RQb3MgPSBkc3RPZmZzZXQ7CisgICAgICAgICAgICAgICAgaW50IG1heERzdFBvcyA9IGRzdE9mZnNldCArIHc7CisgICAgICAgICAgICAgICAgZm9yICg7IGRzdFBvcyA8IG1heERzdFBvczsgZHN0UG9zKyssIHNyY1BvcysrKSB7CisgICAgICAgICAgICAgICAgICAgIGlEYXRhW2RzdFBvc10gPSBtb2RlbC5nZXRSR0IoaXNCeXRlRGF0YSA/ICgoYnl0ZVtdKXBpeGVscylbc3JjUG9zXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKChpbnRbXSlwaXhlbHMpW3NyY1Bvc10pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcmNlIHJnYi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZm9yY2VSR0IoKSB7CisgICAgICAgIGlmICghZm9yY2VkUkdCKSB7CisgICAgICAgICAgICBmb3JjZWRSR0IgPSB0cnVlOworICAgICAgICAgICAgaW50IHNpemUgPSB3aWR0aCAqIGhlaWdodDsKKyAgICAgICAgICAgIGludCByZ2JEYXRhW10gPSBuZXcgaW50W3NpemVdOworCisgICAgICAgICAgICBpZiAoYkRhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJnYkRhdGFbaV0gPSBjbS5nZXRSR0IoYkRhdGFbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaURhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJnYkRhdGFbaV0gPSBjbS5nZXRSR0IoaURhdGFbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY20gPSBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKTsKKyAgICAgICAgICAgIERhdGFCdWZmZXJJbnQgZGIgPSBuZXcgRGF0YUJ1ZmZlckludChyZ2JEYXRhLCBzaXplKTsKKyAgICAgICAgICAgIGludCBtYXNrc1tdID0gbmV3IGludFtdIHsKKyAgICAgICAgICAgICAgICAgICAgMHgwMGZmMDAwMCwgMHgwMDAwZmYwMCwgMHgwMDAwMDBmZiwgMHhmZjAwMDAwMAorICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVQYWNrZWRSYXN0ZXIoZGIsIHdpZHRoLCBoZWlnaHQsIHdpZHRoLCBtYXNrcywgbnVsbCk7CisgICAgICAgICAgICBpRGF0YSA9IGFjY2Vzc29yLmdldERhdGFJbnQoZGIpOworICAgICAgICAgICAgYkRhdGEgPSBudWxsOworICAgICAgICAgICAgdHJhbnNmZXJUeXBlID0gRGF0YUJ1ZmZlci5UWVBFX0lOVDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldCgpIHsKKyAgICAgICAgd2lkdGggPSAwOworICAgICAgICBoZWlnaHQgPSAwOworICAgICAgICBmb3JjZWRSR0IgPSBmYWxzZTsKKyAgICAgICAgY20gPSBudWxsOworICAgICAgICBpRGF0YSA9IG51bGw7CisgICAgICAgIGJEYXRhID0gbnVsbDsKKyAgICAgICAgdHJhbnNmZXJUeXBlID0gRGF0YUJ1ZmZlci5UWVBFX1VOREVGSU5FRDsKKyAgICAgICAgcmFzdGVyID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSByYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVSYXN0ZXIoaW50IGRhdGFUeXBlKSB7CisgICAgICAgIGJvb2xlYW4gY3JlYXRlZFZhbGlkQnVmZmVyID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYXN0ZXIgPSBjbS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICBpbnQgcmFzdGVyVHlwZSA9IHJhc3Rlci5nZXREYXRhQnVmZmVyKCkuZ2V0RGF0YVR5cGUoKTsKKyAgICAgICAgICAgIGlmIChyYXN0ZXJUeXBlID09IGRhdGFUeXBlKSB7CisgICAgICAgICAgICAgICAgc3dpdGNoIChyYXN0ZXJUeXBlKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDogeworICAgICAgICAgICAgICAgICAgICAgICAgaURhdGEgPSBhY2Nlc3Nvci5nZXREYXRhSW50KHJhc3Rlci5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlEYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkVmFsaWRCdWZmZXIgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURTogeworICAgICAgICAgICAgICAgICAgICAgICAgYkRhdGEgPSBhY2Nlc3Nvci5nZXREYXRhQnl0ZShyYXN0ZXIuZ2V0RGF0YUJ1ZmZlcigpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGF0YSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZFZhbGlkQnVmZmVyID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkVmFsaWRCdWZmZXIgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoY20gPT0gQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yY2VkUkdCID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNyZWF0ZWRWYWxpZEJ1ZmZlciA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgY3JlYXRlZFZhbGlkQnVmZmVyID0gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY3JlYXRlZFZhbGlkQnVmZmVyID09IGZhbHNlKSB7CisgICAgICAgICAgICBjbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICAgICAgcmFzdGVyID0gY20uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHdpZHRoLCBoZWlnaHQpOworICAgICAgICAgICAgaURhdGEgPSBhY2Nlc3Nvci5nZXREYXRhSW50KHJhc3Rlci5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICAgICAgYkRhdGEgPSBudWxsOworICAgICAgICAgICAgZm9yY2VkUkdCID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9CdWZmZXJlZEltYWdlT3AuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9CdWZmZXJlZEltYWdlT3AuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ODNhMzlkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0J1ZmZlcmVkSW1hZ2VPcC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgQWxleGV5IEEuIFBldHJlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUG9pbnQyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworCisvKioKKyAqIFRoZSBCdWZmZXJlZEltYWdlT3AgaW50ZXJmYWNlIHByb3ZpZGVzIG1ldGhvZHMgZm9yIHBlcmZvcm1pbmcgdHJhbnNmb3JtYXRpb25zCisgKiBmcm9tIHNvdXJjZSBkYXRhIHRvIGRlc3RpbmF0aW9uIGRhdGEgZm9yIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0cy4gQW4gb2JqZWN0CisgKiBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIHBhc3NlZCBpbnRvIGEgQnVmZmVyZWRJbWFnZUZpbHRlciB0bworICogb3BlcmF0ZSBvbiBhIEJ1ZmZlcmVkSW1hZ2UuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEJ1ZmZlcmVkSW1hZ2VPcCB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgZGVzdGluYXRpb24gaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIEJ1ZmZlcmVkSW1hZ2UgYW5kCisgICAgICogQ29sb3JNb2RlbDsgdGhpcyBkZXN0aW5hdGlvbiBpbWFnZSBpcyBlbXB0eSBhbmQgaGFzIHRoZSBjb3JyZWN0IHNpemUgYW5kCisgICAgICogbnVtYmVyIG9mIGJhbmRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgQnVmZmVyZWRJbWFnZS4KKyAgICAgKiBAcGFyYW0gZGVzdENNCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gQ29sb3JNb2RlbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2UoQnVmZmVyZWRJbWFnZSBzcmMsIENvbG9yTW9kZWwgZGVzdENNKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZmlsdGVyIG9wZXJhdGlvbiBvbiB0aGUgc291cmNlIEJ1ZmZlcmVkSW1hZ2UgYW5kIHN0b3JlcyB0aGUKKyAgICAgKiByZXN1bHRpbmcgQnVmZmVyZWRJbWFnZSB0byB0aGUgZGVzdGluYXRpb24gQnVmZmVyZWRJbWFnZS4gSWYgdGhlCisgICAgICogZGVzdGluYXRpb24gQnVmZmVyZWRJbWFnZSBpcyBudWxsLCBhIEJ1ZmZlcmVkSW1hZ2Ugd2l0aCBhbiBhcHByb3ByaWF0ZQorICAgICAqIENvbG9yTW9kZWwgaXMgY3JlYXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICogQHBhcmFtIGRlc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBCdWZmZXJlZEltYWdlLCB3aGVyZSB0aGUgcmVzdWx0IGlzIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXJlZCBCdWZmZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGZpbHRlcihCdWZmZXJlZEltYWdlIHNyYywgQnVmZmVyZWRJbWFnZSBkZXN0KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJvdW5kcyBvZiBmaWx0ZXJlZCBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIEJ1ZmZlcmVkSW1hZ2UgdG8gYmUgZmlsdGVyZWQuCisgICAgICogQHJldHVybiB0aGUgcmVjdGFuZ2xlIGJvdW5kcyBvZiBmaWx0ZXJlZCBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoQnVmZmVyZWRJbWFnZSBzcmMpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9pbnQgb2YgdGhlIGRlc3RpbmF0aW9uIGltYWdlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBwb2ludCBpbiB0aGUgc291cmNlIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmNQdAorICAgICAqICAgICAgICAgICAgdGhlIHBvaW50IG9mIHRoZSBzb3VyY2UgaW1hZ2UuCisgICAgICogQHBhcmFtIGRzdFB0CisgICAgICogICAgICAgICAgICB0aGUgcG9pbnQgd2hlcmUgdGhlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZXN0aW5hdGlvbiBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnQyRCBnZXRQb2ludDJEKFBvaW50MkQgc3JjUHQsIFBvaW50MkQgZHN0UHQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgUmVuZGVyaW5nSGludHMgb2YgdGhlIEJ1ZmZlcmVkSW1hZ2VPcC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBSZW5kZXJpbmdIaW50cyBvZiB0aGUgQnVmZmVyZWRJbWFnZU9wLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJpbmdIaW50cyBnZXRSZW5kZXJpbmdIaW50cygpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0J5dGVMb29rdXBUYWJsZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0J5dGVMb29rdXBUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3Y2VlMzAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQnl0ZUxvb2t1cFRhYmxlLmphdmEKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqIEBkYXRlOiBPY3QgMTQsIDIwMDUKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBCeXRlTG9va3VwVGFibGUgY2xhc3MgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3IgbG9va3VwIG9wZXJhdGlvbnMsIGFuZAorICogaXMgZGVmaW5lZCBieSBhbiBpbnB1dCBieXRlIGFycmF5IGZvciBiYW5kcyBvciBjb21wb25lbnRzIG9mIGltYWdlIGFuZCBhbgorICogb2Zmc2V0IHZhbHVlLiBUaGUgb2Zmc2V0IHZhbHVlIHdpbGwgYmUgc3VidHJhY3RlZCBmcm9tIHRoZSBpbnB1dCB2YWx1ZXMKKyAqIGJlZm9yZSBpbmRleGluZyB0aGUgaW5wdXQgYXJyYXlzLiBUaGUgb3V0cHV0IG9mIGEgbG9va3VwIG9wZXJhdGlvbiBpcworICogcmVwcmVzZW50ZWQgYXMgYW4gYXJyYXkgb2YgdW5zaWduZWQgYnl0ZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQnl0ZUxvb2t1cFRhYmxlIGV4dGVuZHMgTG9va3VwVGFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIGRhdGFbXVtdOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEJ5dGVMb29rdXBUYWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHZhbHVlIGFuZAorICAgICAqIHRoZSBzcGVjaWZpZWQgYnl0ZSBhcnJheSB3aGljaCByZXByZXNlbnRzIHRoZSBsb29rdXAgdGFibGUgZm9yIGFsbCBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUxvb2t1cFRhYmxlKGludCBvZmZzZXQsIGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIHN1cGVyKG9mZnNldCwgMSk7CisgICAgICAgIGlmIChkYXRhLmxlbmd0aCA8IDEpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMZW5ndGggb2YgZGF0YSBzaG91bGQgbm90IGJlIGxlc3MgdGhlbiBvbmUiKTsKKyAgICAgICAgdGhpcy5kYXRhID0gbmV3IGJ5dGVbMV1bZGF0YS5sZW5ndGhdOworICAgICAgICAvLyBUaGUgZGF0YSBhcnJheSBzdG9yZWQgYXMgYSByZWZlcmVuY2UKKyAgICAgICAgdGhpcy5kYXRhWzBdID0gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQnl0ZUxvb2t1cFRhYmxlIHdpdGggdGhlIHNwZWNpZmllZCBvZmZzZXQgdmFsdWUgYW5kCisgICAgICogdGhlIHNwZWNpZmllZCBieXRlIGFycmF5IG9mIGFycmF5cyB3aGljaCByZXByZXNlbnRzIHRoZSBsb29rdXAgdGFibGUgZm9yCisgICAgICogZWFjaCBiYW5kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdmFsdWUuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IG9mIGJ5dGVzIGFycmF5IGZvciBlYWNoIGJhbmQuCisgICAgICovCisgICAgcHVibGljIEJ5dGVMb29rdXBUYWJsZShpbnQgb2Zmc2V0LCBieXRlW11bXSBkYXRhKSB7CisgICAgICAgIHN1cGVyKG9mZnNldCwgZGF0YS5sZW5ndGgpOworICAgICAgICB0aGlzLmRhdGEgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aF1bZGF0YVswXS5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8vIFRoZSBkYXRhIGFycmF5IGZvciBlYWNoIGJhbmQgc3RvcmVkIGFzIGEgcmVmZXJlbmNlCisgICAgICAgICAgICB0aGlzLmRhdGFbaV0gPSBkYXRhW2ldOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgQnl0ZUxvb2t1cFRhYmxlIG9iamVjdC4gSWYgdGhpcworICAgICAqIEJ5dGVMb29rdXBUYWJsZSBvYmplY3QgaGFzIG9uZSBieXRlIGFycmF5IGZvciBhbGwgYmFuZHMsIHRoZSByZXR1cm5lZAorICAgICAqIGFycmF5IGxlbmd0aCBpcyBvbmUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgQnl0ZUxvb2t1cFRhYmxlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdW10gZ2V0VGFibGUoKSB7CisgICAgICAgIC8vIFJldHVybnMgZGF0YSBieSByZWZlcmVuY2UKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGxvb2t1cFBpeGVsKGludFtdIHNyYywgaW50W10gZHN0KSB7CisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0ID0gbmV3IGludFtzcmMubGVuZ3RoXTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBvZmZzZXQgPSBnZXRPZmZzZXQoKTsKKyAgICAgICAgaWYgKGdldE51bUNvbXBvbmVudHMoKSA9PSAxKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGRzdFtpXSA9IGRhdGFbMF1bc3JjW2ldIC0gb2Zmc2V0XTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0TnVtQ29tcG9uZW50cygpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkc3RbaV0gPSBkYXRhW2ldW3NyY1tpXSAtIG9mZnNldF07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBieXRlIGFycmF5IHdoaWNoIGNvbnRhaW5zIHNhbXBsZXMgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCB3aGljaAorICAgICAqIGlzIHRyYW5zbGF0ZWQgd2l0aCB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgQnl0ZUxvb2t1cFRhYmxlIG9iamVjdC4gVGhlCisgICAgICogcmVzdWx0ZWQgYXJyYXkgaXMgc3RvcmVkIHRvIHRoZSBkc3QgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkgd2hlcmUgdGhlIHJlc3VsdCBjYW4gYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkgb2YgdHJhbnNsYXRlZCBzYW1wbGVzIG9mIGEgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBsb29rdXBQaXhlbChieXRlW10gc3JjLCBieXRlW10gZHN0KSB7CisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0ID0gbmV3IGJ5dGVbc3JjLmxlbmd0aF07CisgICAgICAgIH0KKworICAgICAgICBpbnQgb2Zmc2V0ID0gZ2V0T2Zmc2V0KCk7CisgICAgICAgIGlmIChnZXROdW1Db21wb25lbnRzKCkgPT0gMSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkc3RbaV0gPSBkYXRhWzBdW3NyY1tpXSAtIG9mZnNldF07CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldE51bUNvbXBvbmVudHMoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZHN0W2ldID0gZGF0YVtpXVtzcmNbaV0gLSBvZmZzZXRdOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvQ29sb3JDb252ZXJ0T3AuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Db2xvckNvbnZlcnRPcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhMTcwMGIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQ29sb3JDb252ZXJ0T3AuamF2YQpAQCAtMCwwICsxLDcxMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKiAKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzOworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CitpbXBvcnQgamF2YS5hd3QuY29sb3IuSUNDX0NvbG9yU3BhY2U7CitpbXBvcnQgamF2YS5hd3QuY29sb3IuSUNDX1Byb2ZpbGU7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuQ29sb3JDb252ZXJ0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5jb2xvci5Db2xvclNjYWxlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLklDQ19UcmFuc2Zvcm07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENvbG9yQ29udmVydE9wIGNsYXNzIGNvbnZlcnRzIHRoZSBwaXhlbHMgb2YgdGhlIGRhdGEgaW4gdGhlIHNvdXJjZSBpbWFnZQorICogd2l0aCB0aGUgc3BlY2lmaWVkIENvbG9yU3BhY2Ugb2JqZWN0cyBvciBhbiBhcnJheSBvZiBJQ0NfUHJvZmlsZSBvYmplY3RzLiBUaGUKKyAqIHJlc3VsdCBwaXhlbHMgYXJlIHNjYWxlZCB0byB0aGUgcHJlY2lzaW9uIG9mIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBDb2xvckNvbnZlcnRPcCBpbXBsZW1lbnRzIEJ1ZmZlcmVkSW1hZ2VPcCwgUmFzdGVyT3AgeworICAgIC8vIFVudXNlZCBidXQgcmVxdWlyZWQgYnkgaW50ZXJmYWNlcworICAgIC8qKgorICAgICAqIFRoZSByZW5kZXJpbmcgaGludHMuCisgICAgICovCisgICAgUmVuZGVyaW5nSGludHMgcmVuZGVyaW5nSGludHM7CisKKyAgICAvLyBTZXF1ZW5jZSBjb25zaXN0aW5nIG9mIENvbG9yU3BhY2UgYW5kIElDQ19Qcm9maWxlIGVsZW1lbnRzCisgICAgLyoqCisgICAgICogVGhlIGNvbnZlcnNpb24gc2VxdWVuY2UuCisgICAgICovCisgICAgT2JqZWN0IGNvbnZlcnNpb25TZXF1ZW5jZVtdID0gbmV3IElDQ19Qcm9maWxlWzBdOyAvLyBUbyBlbGltaW5hdGUgY2hlY2tzIGZvcgorCisgICAgLy8gbnVsbAorCisgICAgLy8gTm90IG51bGwgaWYgQ29sb3JDb252ZXJ0T3AgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgYXJyYXkgb2YgSUNDIHByb2ZpbGVzCisgICAgLyoqCisgICAgICogVGhlIG1pZCBwcm9maWxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIElDQ19Qcm9maWxlIG1pZFByb2ZpbGVzW107CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2MuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb2xvckNvbnZlcnRlciBjYyA9IG5ldyBDb2xvckNvbnZlcnRlcigpOworCisgICAgLyoqCisgICAgICogVGhlIHQgY3JlYXRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIElDQ19UcmFuc2ZvbUNyZWF0b3IgdENyZWF0b3IgPSBuZXcgSUNDX1RyYW5zZm9tQ3JlYXRvcigpOworCisgICAgLyoqCisgICAgICogVGhlIGlzIGljYy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNJQ0MgPSB0cnVlOworCisgICAgLy8gQ2FjaGVkIElDQ19UcmFuc2Zvcm0KKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgSUNDX1RyYW5zZm9tQ3JlYXRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIElDQ19UcmFuc2ZvbUNyZWF0b3IgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdHJhbnNmb3JtLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBJQ0NfVHJhbnNmb3JtIHRyYW5zZm9ybTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG1heCBjb21wb25lbnRzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgbWF4Q29tcG9uZW50czsKKworICAgICAgICAvKioKKyAgICAgICAgICogRm9yIHRoZSBmdWxsIElDQyBjYXNlLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHNyYworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICAgICAqIEBwYXJhbSBkc3QKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAgICAgKiBAcGFyYW0gY29udlNlcQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBjb252IHNlcS4KKyAgICAgICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIElDQ19UcmFuc2Zvcm0gZ2V0VHJhbnNmb3JtKElDQ19Qcm9maWxlIHNyYywgSUNDX1Byb2ZpbGUgZHN0LCBJQ0NfUHJvZmlsZSBjb252U2VxW10pIHsKKyAgICAgICAgICAgIGlmICh0cmFuc2Zvcm0gIT0gbnVsbCAmJiBzcmMgPT0gdHJhbnNmb3JtLmdldFNyYygpICYmIGRzdCA9PSB0cmFuc2Zvcm0uZ2V0RHN0KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gY29udlNlcS5sZW5ndGg7CisgICAgICAgICAgICBpbnQgc3JjRmxnID0gMCwgZHN0RmxnID0gMDsKKworICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwIHx8IHNyYyAhPSBjb252U2VxWzBdKSB7CisgICAgICAgICAgICAgICAgaWYgKHNyYyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNyY0ZsZyA9IDE7IC8vIG5lZWQgc3JjIHByb2ZpbGUKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobGVuZ3RoID09IDAgfHwgZHN0ICE9IGNvbnZTZXFbbGVuZ3RoIC0gMV0pIHsKKyAgICAgICAgICAgICAgICBpZiAoZHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZHN0RmxnID0gMTsgLy8gbmVlZCBkc3QgcHJvZmlsZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgSUNDX1Byb2ZpbGUgcHJvZmlsZXNbXTsKKyAgICAgICAgICAgIGludCBuUHJvZmlsZXMgPSBsZW5ndGggKyBzcmNGbGcgKyBkc3RGbGc7CisgICAgICAgICAgICBpZiAoblByb2ZpbGVzID09IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIHByb2ZpbGVzID0gY29udlNlcTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHJvZmlsZXMgPSBuZXcgSUNDX1Byb2ZpbGVbblByb2ZpbGVzXTsKKyAgICAgICAgICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgICAgICAgICBpZiAoc3JjRmxnICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXNbcG9zKytdID0gc3JjOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHByb2ZpbGVzW3BvcysrXSA9IGNvbnZTZXFbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChkc3RGbGcgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBwcm9maWxlc1twb3MrK10gPSBkc3Q7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtID0gbmV3IElDQ19UcmFuc2Zvcm0ocHJvZmlsZXMpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVzZWQgb25seSB3aGVuIHRoZXJlIGFyZSBub24tSUNDIGNvbG9yIHNwYWNlcy4gUmV0dXJucyBzZXF1ZW5jZSBvZgorICAgICAgICAgKiBub24tSUNDIGNvbG9yIHNwYWNlcyBhbmQgSUNDIHRyYW5zZm9ybXMgbWFkZSBmcm9tIHNyYywgZHN0IGFuZAorICAgICAgICAgKiBjb252ZXJzaW9uU2VxdWVuY2UuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gc3JjCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgICAgICogQHBhcmFtIGRzdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICAgICAqIEByZXR1cm4gdGhlIHNlcXVlbmNlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE9iamVjdFtdIGdldFNlcXVlbmNlKE9iamVjdCBzcmMsIE9iamVjdCBkc3QpIHsKKyAgICAgICAgICAgIEFycmF5TGlzdDxPYmplY3Q+IHByb2ZpbGVzID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KDEwKTsKKyAgICAgICAgICAgIEFycmF5TGlzdDxPYmplY3Q+IHNlcXVlbmNlID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KDEwKTsKKworICAgICAgICAgICAgLy8gV2UgbmVlZCB0aGlzIHByb2ZpbGUgYW55d2F5CisgICAgICAgICAgICBJQ0NfUHJvZmlsZSB4eXpQcm9maWxlID0gSUNDX1Byb2ZpbGUuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19DSUVYWVopOworCisgICAgICAgICAgICBPYmplY3QgY29udmVyc2lvbkZpcnN0ID0gbnVsbCwgY29udmVyc2lvbkxhc3QgPSBudWxsOworICAgICAgICAgICAgaW50IGNvbnZlcnNpb25MZW5ndGggPSBjb252ZXJzaW9uU2VxdWVuY2UubGVuZ3RoOworICAgICAgICAgICAgaWYgKGNvbnZlcnNpb25MZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgY29udmVyc2lvbkZpcnN0ID0gY29udmVyc2lvblNlcXVlbmNlWzBdOworICAgICAgICAgICAgICAgIGNvbnZlcnNpb25MYXN0ID0gY29udmVyc2lvblNlcXVlbmNlW2NvbnZlcnNpb25MZW5ndGggLSAxXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYm9vbGVhbiBpY2NTZXF1ZW5jZVN0YXJ0ZWQgPSBmYWxzZTsKKworICAgICAgICAgICAgaWYgKHNyYyAhPSBjb252ZXJzaW9uRmlyc3QgJiYgc3JjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoc3JjIGluc3RhbmNlb2YgSUNDX1Byb2ZpbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXMuYWRkKHNyYyk7CisgICAgICAgICAgICAgICAgICAgIGljY1NlcXVlbmNlU3RhcnRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXMuYWRkKHh5elByb2ZpbGUpOworICAgICAgICAgICAgICAgICAgICBzZXF1ZW5jZS5hZGQoc3JjKTsgLy8gQWRkIG5vbi1JQ0MgY29sb3Igc3BhY2UgdG8gdGhlCisgICAgICAgICAgICAgICAgICAgIC8vIHNlcXVlbmNlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwcm9maWxlcy5hZGQoeHl6UHJvZmlsZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29udmVyc2lvbkxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbnZlcnNpb25TZXF1ZW5jZVtpXSBpbnN0YW5jZW9mIElDQ19Qcm9maWxlKSB7CisgICAgICAgICAgICAgICAgICAgIHByb2ZpbGVzLmFkZChjb252ZXJzaW9uU2VxdWVuY2VbaV0pOworICAgICAgICAgICAgICAgICAgICBpY2NTZXF1ZW5jZVN0YXJ0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWNjU2VxdWVuY2VTdGFydGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHByb2ZpbGVzLmFkZCh4eXpQcm9maWxlKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBFbGltaW5hdGUgc2FtZSBwcm9maWxlcyBpZiB0aGVyZSBhcmUgYW55CisgICAgICAgICAgICAgICAgICAgIC8vIChlLmcuIHh5elByb2ZpbGUgbWF5IG9jY3VyIHNldmVyYWwgdGltZXMpCisgICAgICAgICAgICAgICAgICAgIE9iamVjdCBwcmV2ID0gcHJvZmlsZXMuZ2V0KDApOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMTsgayA8IHByb2ZpbGVzLnNpemUoKTsgaysrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJldiA9PSBwcm9maWxlcy5nZXQoaykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBrLS07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXMucmVtb3ZlKGspOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IHByb2ZpbGVzLmdldChrKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIElmIG9ubHkgb25lIHByb2ZpbGUgbGVmdCB3ZSBza2lwIHRoZSB0cmFuc2Zvcm0gLQorICAgICAgICAgICAgICAgICAgICAvLyBpdCBjYW4gYmUgb25seSBDSUVYWVoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHByb2ZpbGVzLnNpemUoKSA+IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlLmFkZChuZXcgSUNDX1RyYW5zZm9ybShwcm9maWxlcy50b0FycmF5KG5ldyBJQ0NfUHJvZmlsZVswXSkpKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIG5vbi1JQ0MgY29sb3Igc3BhY2UgdG8gdGhlIHNlcXVlbmNlCisgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW5jZS5hZGQoY29udmVyc2lvblNlcXVlbmNlW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHByb2ZpbGVzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgICAgIHByb2ZpbGVzLmFkZCh4eXpQcm9maWxlKTsKKyAgICAgICAgICAgICAgICAgICAgaWNjU2VxdWVuY2VTdGFydGVkID0gZmFsc2U7IC8vIFNlcXVlbmNlIG9mIElDQyBwcm9maWxlcyBpcworICAgICAgICAgICAgICAgICAgICAvLyBwcm9jZXNzZWQKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBBZGQgbm9uLUlDQyBjb2xvciBzcGFjZSB0byB0aGUgc2VxdWVuY2UKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVuY2UuYWRkKGNvbnZlcnNpb25TZXF1ZW5jZVtpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZHN0ICE9IGNvbnZlcnNpb25MYXN0ICYmIGRzdCAhPSBudWxsKSB7IC8vIEFkZCBsYXN0IHByb2ZpbGUgaWYKKyAgICAgICAgICAgICAgICAvLyBuZWVkZWQKKyAgICAgICAgICAgICAgICBpZiAoZHN0IGluc3RhbmNlb2YgSUNDX1Byb2ZpbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXMuYWRkKGRzdCk7CisgICAgICAgICAgICAgICAgICAgIGljY1NlcXVlbmNlU3RhcnRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpY2NTZXF1ZW5jZVN0YXJ0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvZmlsZXMuYWRkKHh5elByb2ZpbGUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlLmFkZChkc3QpOyAvLyBBZGQgbGFzdCBub24tSUNDIGNvbG9yIHNwYWNlIHRvIHRoZQorICAgICAgICAgICAgICAgICAgICAvLyBzZXF1ZW5jZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGljY1NlcXVlbmNlU3RhcnRlZCkgeyAvLyBNYWtlIGxhc3QgdHJhbnNmb3JtIGlmIG5lZWRlZAorICAgICAgICAgICAgICAgIHNlcXVlbmNlLmFkZChuZXcgSUNDX1RyYW5zZm9ybShwcm9maWxlcy50b0FycmF5KG5ldyBJQ0NfUHJvZmlsZVswXSkpKTsKKyAgICAgICAgICAgICAgICBpZiAoZHN0ICE9IG51bGwgJiYgIShkc3QgaW5zdGFuY2VvZiBJQ0NfUHJvZmlsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVuY2UuYWRkKGRzdCk7IC8vIEFkZCBsYXN0IG5vbi1JQ0MgY29sb3Igc3BhY2UgdG8gdGhlCisgICAgICAgICAgICAgICAgICAgIC8vIHNlcXVlbmNlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDYWxjdWxhdGUgbWF4IG51bWJlciBvZiBjb21wb25lbnRzCisgICAgICAgICAgICAvLyBUaGlzIG51bWJlciB3aWxsIGJlIHVzZWQgZm9yIG1lbW9yeSBhbGxvY2F0aW9uCisgICAgICAgICAgICBtYXhDb21wb25lbnRzID0gMDsKKyAgICAgICAgICAgIE9iamVjdCBvOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIHNpemUgPSBzZXF1ZW5jZS5zaXplKCk7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBvID0gc2VxdWVuY2UuZ2V0KGkpOworICAgICAgICAgICAgICAgIGlmIChvIGluc3RhbmNlb2YgSUNDX1RyYW5zZm9ybSkgeworICAgICAgICAgICAgICAgICAgICBJQ0NfVHJhbnNmb3JtIHQgPSAoSUNDX1RyYW5zZm9ybSlvOworICAgICAgICAgICAgICAgICAgICBtYXhDb21wb25lbnRzID0gKG1heENvbXBvbmVudHMgPiB0LmdldE51bUlucHV0Q2hhbm5lbHMoKSArIDEpID8gbWF4Q29tcG9uZW50cworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdC5nZXROdW1JbnB1dENoYW5uZWxzKCkgKyAxOworICAgICAgICAgICAgICAgICAgICBtYXhDb21wb25lbnRzID0gKG1heENvbXBvbmVudHMgPiB0LmdldE51bU91dHB1dENoYW5uZWxzKCkgKyAxKSA/IG1heENvbXBvbmVudHMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHQuZ2V0TnVtT3V0cHV0Q2hhbm5lbHMoKSArIDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgQ29sb3JTcGFjZSBjcyA9IChDb2xvclNwYWNlKW87CisgICAgICAgICAgICAgICAgICAgIG1heENvbXBvbmVudHMgPSAobWF4Q29tcG9uZW50cyA+IGNzLmdldE51bUNvbXBvbmVudHMoKSArIDEpID8gbWF4Q29tcG9uZW50cworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY3MuZ2V0TnVtQ29tcG9uZW50cygpICsgMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBzZXF1ZW5jZS50b0FycmF5KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQ29sb3JDb252ZXJ0T3Agb2JqZWN0IHVzaW5nIHR3byBzcGVjaWZpZWQgQ29sb3JTcGFjZQorICAgICAqIG9iamVjdHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNyY0NTCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIENvbG9yU3BhY2UuCisgICAgICogQHBhcmFtIGRzdENTCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gQ29sb3JTcGFjZS4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3QgdXNlZCBmb3IgdGhlIGNvbG9yIGNvbnZlcnNpb24sIG9yCisgICAgICogICAgICAgICAgICBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvckNvbnZlcnRPcChDb2xvclNwYWNlIHNyY0NTLCBDb2xvclNwYWNlIGRzdENTLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBpZiAoc3JjQ1MgPT0gbnVsbCB8fCBkc3RDUyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjVCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZW5kZXJpbmdIaW50cyA9IGhpbnRzOworCisgICAgICAgIGJvb2xlYW4gc3JjSUNDID0gc3JjQ1MgaW5zdGFuY2VvZiBJQ0NfQ29sb3JTcGFjZTsKKyAgICAgICAgYm9vbGVhbiBkc3RJQ0MgPSBkc3RDUyBpbnN0YW5jZW9mIElDQ19Db2xvclNwYWNlOworCisgICAgICAgIGlmIChzcmNJQ0MgJiYgZHN0SUNDKSB7CisgICAgICAgICAgICBjb252ZXJzaW9uU2VxdWVuY2UgPSBuZXcgSUNDX1Byb2ZpbGVbMl07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb252ZXJzaW9uU2VxdWVuY2UgPSBuZXcgT2JqZWN0WzJdOworICAgICAgICAgICAgaXNJQ0MgPSBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzcmNJQ0MpIHsKKyAgICAgICAgICAgIGNvbnZlcnNpb25TZXF1ZW5jZVswXSA9ICgoSUNDX0NvbG9yU3BhY2Upc3JjQ1MpLmdldFByb2ZpbGUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbnZlcnNpb25TZXF1ZW5jZVswXSA9IHNyY0NTOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRzdElDQykgeworICAgICAgICAgICAgY29udmVyc2lvblNlcXVlbmNlWzFdID0gKChJQ0NfQ29sb3JTcGFjZSlkc3RDUykuZ2V0UHJvZmlsZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29udmVyc2lvblNlcXVlbmNlWzFdID0gZHN0Q1M7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQ29sb3JDb252ZXJ0T3Agb2JqZWN0IGZyb20gdGhlIHNwZWNpZmllZCBJQ0NfUHJvZmlsZQorICAgICAqIG9iamVjdHMuCisgICAgICogCisgICAgICogQHBhcmFtIHByb2ZpbGVzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgSUNDX1Byb2ZpbGUgb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3QgdXNlZCBmb3IgdGhlIGNvbG9yIGNvbnZlcnNpb24sIG9yCisgICAgICogICAgICAgICAgICBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvckNvbnZlcnRPcChJQ0NfUHJvZmlsZSBwcm9maWxlc1tdLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBpZiAocHJvZmlsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI1QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmVuZGVyaW5nSGludHMgPSBoaW50czsKKworICAgICAgICAvLyBUaGlzIGFycmF5IGlzIG5vdCB1c2VkIGluIHRoZSBwcm9ncmFtIGxvZ2ljLCBzbyBkb24ndCBuZWVkIHRvIGNvcHkgaXQKKyAgICAgICAgLy8gU3RvcmUgaXQgb25seSB0byByZXR1cm4gYmFjaworICAgICAgICBtaWRQcm9maWxlcyA9IHByb2ZpbGVzOworCisgICAgICAgIGNvbnZlcnNpb25TZXF1ZW5jZSA9IG5ldyBJQ0NfUHJvZmlsZVttaWRQcm9maWxlcy5sZW5ndGhdOworCisgICAgICAgIC8vIEFkZCBwcm9maWxlcyB0byB0aGUgY29udmVyc2lvbiBzZXF1ZW5jZQorICAgICAgICBmb3IgKGludCBpID0gMCwgbGVuZ3RoID0gbWlkUHJvZmlsZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvbnZlcnNpb25TZXF1ZW5jZVtpXSA9IG1pZFByb2ZpbGVzW2ldOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IENvbG9yQ29udmVydE9wIG9iamVjdCB1c2luZyB0aGUgc3BlY2lmaWVkIENvbG9yU3BhY2UKKyAgICAgKiBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGNzCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gQ29sb3JTcGFjZSBvciBhbiBpbnRlcm1lZGlhdGUgQ29sb3JTcGFjZS4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3QgdXNlZCBmb3IgdGhlIGNvbG9yIGNvbnZlcnNpb24sIG9yCisgICAgICogICAgICAgICAgICBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBDb2xvckNvbnZlcnRPcChDb2xvclNwYWNlIGNzLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBpZiAoY3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI1QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmVuZGVyaW5nSGludHMgPSBoaW50czsKKworICAgICAgICBpZiAoY3MgaW5zdGFuY2VvZiBJQ0NfQ29sb3JTcGFjZSkgeworICAgICAgICAgICAgY29udmVyc2lvblNlcXVlbmNlID0gbmV3IElDQ19Qcm9maWxlWzFdOworICAgICAgICAgICAgY29udmVyc2lvblNlcXVlbmNlWzBdID0gKChJQ0NfQ29sb3JTcGFjZSljcykuZ2V0UHJvZmlsZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29udmVyc2lvblNlcXVlbmNlID0gbmV3IE9iamVjdFsxXTsKKyAgICAgICAgICAgIGNvbnZlcnNpb25TZXF1ZW5jZVswXSA9IGNzOworICAgICAgICAgICAgaXNJQ0MgPSBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBDb2xvckNvbnZlcnRPcCBvYmplY3Qgd2hpY2ggY29udmVydHMgZnJvbSBhIHNvdXJjZQorICAgICAqIGNvbG9yIHNwYWNlIHRvIGEgZGVzdGluYXRpb24gY29sb3Igc3BhY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgUmVuZGVyaW5nSGludHMgb2JqZWN0IHVzZWQgZm9yIHRoZSBjb2xvciBjb252ZXJzaW9uLCBvcgorICAgICAqICAgICAgICAgICAgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3JDb252ZXJ0T3AoUmVuZGVyaW5nSGludHMgaGludHMpIHsKKyAgICAgICAgcmVuZGVyaW5nSGludHMgPSBoaW50czsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgV3JpdGFibGVSYXN0ZXIgZmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCkgeworICAgICAgICBpZiAoY29udmVyc2lvblNlcXVlbmNlLmxlbmd0aCA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjVEIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBJQ0NfUHJvZmlsZSBzcmNQZiA9IG51bGwsIGRzdFBmID0gbnVsbDsgLy8gdW51c2VkIGlmIGlzSUNDIGlzIGZhbHNlCisgICAgICAgIGludCBuU3JjQ29sb3JDb21wcywgbkRzdENvbG9yQ29tcHM7CisgICAgICAgIE9iamVjdCBmaXJzdCA9IGNvbnZlcnNpb25TZXF1ZW5jZVswXTsKKyAgICAgICAgT2JqZWN0IGxhc3QgPSBjb252ZXJzaW9uU2VxdWVuY2VbY29udmVyc2lvblNlcXVlbmNlLmxlbmd0aCAtIDFdOworCisgICAgICAgIC8vIEdldCB0aGUgbnVtYmVyIG9mIGlucHV0L291dHB1dCBjb2xvciBjb21wb25lbnRzCisgICAgICAgIGlmIChpc0lDQykgeworICAgICAgICAgICAgc3JjUGYgPSAoSUNDX1Byb2ZpbGUpZmlyc3Q7CisgICAgICAgICAgICBkc3RQZiA9IChJQ0NfUHJvZmlsZSlsYXN0OworICAgICAgICAgICAgblNyY0NvbG9yQ29tcHMgPSBzcmNQZi5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgICAgICBuRHN0Q29sb3JDb21wcyA9IGRzdFBmLmdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChmaXJzdCBpbnN0YW5jZW9mIElDQ19Qcm9maWxlKSB7CisgICAgICAgICAgICAgICAgc3JjUGYgPSAoSUNDX1Byb2ZpbGUpZmlyc3Q7CisgICAgICAgICAgICAgICAgblNyY0NvbG9yQ29tcHMgPSBzcmNQZi5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5TcmNDb2xvckNvbXBzID0gKChDb2xvclNwYWNlKWZpcnN0KS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChsYXN0IGluc3RhbmNlb2YgSUNDX1Byb2ZpbGUpIHsKKyAgICAgICAgICAgICAgICBkc3RQZiA9IChJQ0NfUHJvZmlsZSlsYXN0OworICAgICAgICAgICAgICAgIG5Ec3RDb2xvckNvbXBzID0gZHN0UGYuZ2V0TnVtQ29tcG9uZW50cygpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBuRHN0Q29sb3JDb21wcyA9ICgoQ29sb3JTcGFjZSlsYXN0KS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayB0aGF0IHNvdXJjZSBhbmQgZGVzdGluYXRpb24gcmFzdGVycyBhcmUgY29tcGF0aWJsZSB3aXRoCisgICAgICAgIC8vIHRyYW5zZm9ybXMgYW5kIHdpdGggZWFjaCBvdGhlcgorICAgICAgICBpZiAoc3JjLmdldE51bUJhbmRzKCkgIT0gblNyY0NvbG9yQ29tcHMpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNUU9SW5jb3JyZWN0IG51bWJlciBvZiBzb3VyY2UgcmFzdGVyIGJhbmRzLiBTaG91bGQgYmUgZXF1YWwKKyAgICAgICAgICAgIC8vIHRvIHRoZSBudW1iZXIgb2YgY29sb3IgY29tcG9uZW50cyBvZiBzb3VyY2UgY29sb3JzcGFjZS4KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjVFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZHN0ICE9IG51bGwpIHsgLy8gQ2hlY2sgZGVzdGluYXRpb24gcmFzdGVyCisgICAgICAgICAgICBpZiAoZHN0LmdldE51bUJhbmRzKCkgIT0gbkRzdENvbG9yQ29tcHMpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjVGPUluY29ycmVjdCBudW1iZXIgb2YgZGVzdGluYXRpb24gcmFzdGVyIGJhbmRzLiBTaG91bGQKKyAgICAgICAgICAgICAgICAvLyBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGNvbG9yIGNvbXBvbmVudHMgb2YgZGVzdGluYXRpb24KKyAgICAgICAgICAgICAgICAvLyBjb2xvcnNwYWNlLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjVGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzcmMuZ2V0V2lkdGgoKSAhPSBkc3QuZ2V0V2lkdGgoKSB8fCBzcmMuZ2V0SGVpZ2h0KCkgIT0gZHN0LmdldEhlaWdodCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNjAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoc3JjKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc0lDQykgeworICAgICAgICAgICAgLy8gQ3JlYXRlIHRyYW5zZm9ybQorICAgICAgICAgICAgSUNDX1RyYW5zZm9ybSB0ID0gdENyZWF0b3IKKyAgICAgICAgICAgICAgICAgICAgLmdldFRyYW5zZm9ybShzcmNQZiwgZHN0UGYsIChJQ0NfUHJvZmlsZVtdKWNvbnZlcnNpb25TZXF1ZW5jZSk7CisgICAgICAgICAgICBjYy50cmFuc2xhdGVDb2xvcih0LCBzcmMsIGRzdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBPYmplY3RbXSBzZXF1ZW5jZSA9IHRDcmVhdG9yLmdldFNlcXVlbmNlKG51bGwsIG51bGwpOworCisgICAgICAgICAgICAvLyBHZXQgZGF0YSBmcm9tIHRoZSBzb3VyY2UgcmFzdGVyCisgICAgICAgICAgICBDb2xvclNjYWxlciBzY2FsZXIgPSBuZXcgQ29sb3JTY2FsZXIoKTsKKyAgICAgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEoc3JjLCBudWxsKTsKKyAgICAgICAgICAgIGZsb2F0IHRtcERhdGFbXVtdID0gc2NhbGVyLnNjYWxlTm9ybWFsaXplKHNyYyk7CisKKyAgICAgICAgICAgIC8vIEdldCBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGNvbG9yIHNwYWNlcworICAgICAgICAgICAgQ29sb3JTcGFjZSBzcmNDUyA9IChzcmNQZiA9PSBudWxsKSA/IChDb2xvclNwYWNlKWZpcnN0IDogbmV3IElDQ19Db2xvclNwYWNlKHNyY1BmKTsKKyAgICAgICAgICAgIENvbG9yU3BhY2UgZHN0Q1MgPSAoZHN0UGYgPT0gbnVsbCkgPyAoQ29sb3JTcGFjZSlsYXN0IDogbmV3IElDQ19Db2xvclNwYWNlKGRzdFBmKTsKKworICAgICAgICAgICAgYXBwbHlTZXF1ZW5jZShzZXF1ZW5jZSwgdG1wRGF0YSwgc3JjQ1MsIGRzdENTKTsKKworICAgICAgICAgICAgc2NhbGVyLmxvYWRTY2FsaW5nRGF0YShkc3QsIG51bGwpOworICAgICAgICAgICAgc2NhbGVyLnVuc2NhbGVOb3JtYWxpemVkKGRzdCwgdG1wRGF0YSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2UoQnVmZmVyZWRJbWFnZSBzcmMsIENvbG9yTW9kZWwgZGVzdENNKSB7CisgICAgICAgIC8vIElmIGRlc3RpbmF0aW9uIGNvbG9yIG1vZGVsIGlzIHBhc3NlZCBvbmx5IG9uZSBsaW5lIG5lZWRlZAorICAgICAgICBpZiAoZGVzdENNICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShkZXN0Q00sIGRlc3RDTS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoc3JjLmdldFdpZHRoKCksCisgICAgICAgICAgICAgICAgICAgIHNyYy5nZXRIZWlnaHQoKSksIGRlc3RDTS5pc0FscGhhUHJlbXVsdGlwbGllZCgpLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBuU3BhY2VzID0gY29udmVyc2lvblNlcXVlbmNlLmxlbmd0aDsKKworICAgICAgICBpZiAoblNwYWNlcyA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjYxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICAvLyBHZXQgZGVzdGluYXRpb24gY29sb3Igc3BhY2UKKyAgICAgICAgT2JqZWN0IGRlc3RpbmF0aW9uID0gY29udmVyc2lvblNlcXVlbmNlW25TcGFjZXMgLSAxXTsKKyAgICAgICAgQ29sb3JTcGFjZSBkc3RDUyA9IChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIENvbG9yU3BhY2UpID8gKENvbG9yU3BhY2UpZGVzdGluYXRpb24KKyAgICAgICAgICAgICAgICA6IG5ldyBJQ0NfQ29sb3JTcGFjZSgoSUNDX1Byb2ZpbGUpZGVzdGluYXRpb24pOworCisgICAgICAgIENvbG9yTW9kZWwgc3JjQ00gPSBzcmMuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICBDb2xvck1vZGVsIGRzdENNID0gbmV3IENvbXBvbmVudENvbG9yTW9kZWwoZHN0Q1MsIHNyY0NNLmhhc0FscGhhKCksIHNyY0NNCisgICAgICAgICAgICAgICAgLmlzQWxwaGFQcmVtdWx0aXBsaWVkKCksIHNyY0NNLmdldFRyYW5zcGFyZW5jeSgpLCBzcmNDTS5nZXRUcmFuc2ZlclR5cGUoKSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlKGRzdENNLCBkZXN0Q00uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHNyYy5nZXRXaWR0aCgpLCBzcmMKKyAgICAgICAgICAgICAgICAuZ2V0SGVpZ2h0KCkpLCBkZXN0Q00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlcmVkSW1hZ2UgZmlsdGVyKEJ1ZmZlcmVkSW1hZ2Ugc3JjLCBCdWZmZXJlZEltYWdlIGRzdCkgeworICAgICAgICBpZiAoZHN0ID09IG51bGwgJiYgY29udmVyc2lvblNlcXVlbmNlLmxlbmd0aCA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjYyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBDb2xvck1vZGVsIHNyY0NNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgLy8gRmlyc3QgaGFuZGxlIGluZGV4IGNvbG9yIG1vZGVsCisgICAgICAgIGlmIChzcmNDTSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgc3JjID0gKChJbmRleENvbG9yTW9kZWwpc3JjQ00pLmNvbnZlcnRUb0ludERpc2NyZXRlKHNyYy5nZXRSYXN0ZXIoKSwgZmFsc2UpOworICAgICAgICB9CisgICAgICAgIENvbG9yU3BhY2Ugc3JjQ1MgPSBzcmNDTS5nZXRDb2xvclNwYWNlKCk7CisKKyAgICAgICAgQnVmZmVyZWRJbWFnZSByZXM7CisgICAgICAgIGJvb2xlYW4gaXNEc3RJbmRleCA9IGZhbHNlOworICAgICAgICBpZiAoZHN0ICE9IG51bGwpIHsKKworICAgICAgICAgICAgaWYgKHNyYy5nZXRXaWR0aCgpICE9IGRzdC5nZXRXaWR0aCgpIHx8IHNyYy5nZXRIZWlnaHQoKSAhPSBkc3QuZ2V0SGVpZ2h0KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZHN0LmdldENvbG9yTW9kZWwoKSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgICAgIGlzRHN0SW5kZXggPSB0cnVlOworICAgICAgICAgICAgICAgIHJlcyA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2Uoc3JjLCBudWxsKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzID0gZHN0OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzID0gY3JlYXRlQ29tcGF0aWJsZURlc3RJbWFnZShzcmMsIG51bGwpOworICAgICAgICB9CisgICAgICAgIENvbG9yTW9kZWwgZHN0Q00gPSByZXMuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICBDb2xvclNwYWNlIGRzdENTID0gZHN0Q00uZ2V0Q29sb3JTcGFjZSgpOworCisgICAgICAgIElDQ19Qcm9maWxlIHNyY1BmID0gbnVsbCwgZHN0UGYgPSBudWxsOworICAgICAgICBpZiAoc3JjQ1MgaW5zdGFuY2VvZiBJQ0NfQ29sb3JTcGFjZSkgeworICAgICAgICAgICAgc3JjUGYgPSAoKElDQ19Db2xvclNwYWNlKXNyY0NTKS5nZXRQcm9maWxlKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRzdENTIGluc3RhbmNlb2YgSUNDX0NvbG9yU3BhY2UpIHsKKyAgICAgICAgICAgIGRzdFBmID0gKChJQ0NfQ29sb3JTcGFjZSlkc3RDUykuZ2V0UHJvZmlsZSgpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpc0Z1bGxJQ0MgPSBpc0lDQyAmJiBzcmNQZiAhPSBudWxsICYmIGRzdFBmICE9IG51bGw7CisKKyAgICAgICAgaWYgKGlzRnVsbElDQykgeworICAgICAgICAgICAgSUNDX1RyYW5zZm9ybSB0ID0gdENyZWF0b3IKKyAgICAgICAgICAgICAgICAgICAgLmdldFRyYW5zZm9ybShzcmNQZiwgZHN0UGYsIChJQ0NfUHJvZmlsZVtdKWNvbnZlcnNpb25TZXF1ZW5jZSk7CisgICAgICAgICAgICBjYy50cmFuc2xhdGVDb2xvcih0LCBzcmMsIHJlcyk7CisgICAgICAgIH0gZWxzZSB7IC8vIFBlcmZvcm0gbm9uLUlDQyB0cmFuc2Zvcm0KKyAgICAgICAgICAgIE9iamVjdCBzZXF1ZW5jZVtdID0gdENyZWF0b3IuZ2V0U2VxdWVuY2Uoc3JjUGYgPT0gbnVsbCA/IChPYmplY3Qpc3JjQ1MgOiBzcmNQZiwKKyAgICAgICAgICAgICAgICAgICAgZHN0UGYgPT0gbnVsbCA/IChPYmplY3QpZHN0Q1MgOiBkc3RQZik7CisKKyAgICAgICAgICAgIGludCBzcmNXID0gc3JjLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQgc3JjSCA9IHNyYy5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGludCBudW1QaXhlbHMgPSBzcmNXICogc3JjSDsKKworICAgICAgICAgICAgLy8gTG9hZCBhbGwgcGl4ZWwgZGF0YSBpbnRvIGFycmF5IHRtcERhdGEKKyAgICAgICAgICAgIGZsb2F0IHRtcERhdGFbXVtdID0gbmV3IGZsb2F0W251bVBpeGVsc11bdENyZWF0b3IubWF4Q29tcG9uZW50c107CisgICAgICAgICAgICBmb3IgKGludCByb3cgPSAwLCBkYXRhUG9zID0gMDsgcm93IDwgc3JjVzsgcm93KyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBjb2wgPSAwOyBjb2wgPCBzcmNIOyBjb2wrKykgeworICAgICAgICAgICAgICAgICAgICB0bXBEYXRhW2RhdGFQb3NdID0gc3JjQ00uZ2V0Tm9ybWFsaXplZENvbXBvbmVudHMoc3JjLmdldFJhc3RlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldERhdGFFbGVtZW50cyhyb3csIGNvbCwgbnVsbCksIHRtcERhdGFbZGF0YVBvc10sIDApOworICAgICAgICAgICAgICAgICAgICBkYXRhUG9zKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDb3B5IGFscGhhIGNoYW5uZWwgaWYgbmVlZGVkCisgICAgICAgICAgICBmbG9hdCBhbHBoYVtdID0gbnVsbDsKKyAgICAgICAgICAgIGludCBhbHBoYUlkeCA9IHNyY0NNLm51bUNvbXBvbmVudHMgLSAxOworICAgICAgICAgICAgaWYgKHNyY0NNLmhhc0FscGhhKCkgJiYgZHN0Q00uaGFzQWxwaGEoKSkgeworICAgICAgICAgICAgICAgIGFscGhhID0gbmV3IGZsb2F0W251bVBpeGVsc107CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QaXhlbHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhbHBoYVtpXSA9IHRtcERhdGFbaV1bYWxwaGFJZHhdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gVHJhbnNsYXRlIGNvbG9ycworICAgICAgICAgICAgYXBwbHlTZXF1ZW5jZShzZXF1ZW5jZSwgdG1wRGF0YSwgc3JjQ1MsIGRzdENTKTsKKworICAgICAgICAgICAgLy8gQ29weSBhbHBoYSBpZiBuZWVkZWQKKyAgICAgICAgICAgIGlmIChkc3RDTS5oYXNBbHBoYSgpKSB7CisgICAgICAgICAgICAgICAgYWxwaGFJZHggPSBkc3RDTS5udW1Db21wb25lbnRzIC0gMTsKKyAgICAgICAgICAgICAgICBpZiAoYWxwaGEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVBpeGVsczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXBEYXRhW2ldW2FscGhhSWR4XSA9IGFscGhhW2ldOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QaXhlbHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgdG1wRGF0YVtpXVthbHBoYUlkeF0gPSAxZjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gU3RvcmUgZGF0YSBiYWNrIHRvIHRoZSBpbWFnZQorICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gMCwgZGF0YVBvcyA9IDA7IHJvdyA8IHNyY1c7IHJvdysrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gMDsgY29sIDwgc3JjSDsgY29sKyspIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzLmdldFJhc3RlcigpLnNldERhdGFFbGVtZW50cyhyb3csIGNvbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RDTS5nZXREYXRhRWxlbWVudHModG1wRGF0YVtkYXRhUG9zKytdLCAwLCBudWxsKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzRHN0SW5kZXgpIHsgLy8gQ29udmVydCBpbWFnZSBpbnRvIGluZGV4ZWQgY29sb3IKKyAgICAgICAgICAgIEdyYXBoaWNzMkQgZzJkID0gZHN0LmNyZWF0ZUdyYXBoaWNzKCk7CisgICAgICAgICAgICBnMmQuZHJhd0ltYWdlKHJlcywgMCwgMCwgbnVsbCk7CisgICAgICAgICAgICBnMmQuZGlzcG9zZSgpOworICAgICAgICAgICAgcmV0dXJuIGRzdDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbHkgc2VxdWVuY2UuCisgICAgICogCisgICAgICogQHBhcmFtIHNlcXVlbmNlCisgICAgICogICAgICAgICAgICB0aGUgc2VxdWVuY2UuCisgICAgICogQHBhcmFtIHRtcERhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSB0bXAgZGF0YS4KKyAgICAgKiBAcGFyYW0gc3JjQ1MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgY3MuCisgICAgICogQHBhcmFtIGRzdENTCisgICAgICogICAgICAgICAgICB0aGUgZHN0IGNzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhcHBseVNlcXVlbmNlKE9iamVjdCBzZXF1ZW5jZVtdLCBmbG9hdCB0bXBEYXRhW11bXSwgQ29sb3JTcGFjZSBzcmNDUywKKyAgICAgICAgICAgIENvbG9yU3BhY2UgZHN0Q1MpIHsKKyAgICAgICAgQ29sb3JTcGFjZSB4eXpDUyA9IENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19DSUVYWVopOworCisgICAgICAgIGludCBudW1QaXhlbHMgPSB0bXBEYXRhLmxlbmd0aDsKKworICAgICAgICAvLyBGaXJzdCB0cmFuc2Zvcm0uLi4KKyAgICAgICAgaWYgKHNlcXVlbmNlWzBdIGluc3RhbmNlb2YgSUNDX1RyYW5zZm9ybSkgeyAvLyBJQ0MKKyAgICAgICAgICAgIElDQ19UcmFuc2Zvcm0gdCA9IChJQ0NfVHJhbnNmb3JtKXNlcXVlbmNlWzBdOworICAgICAgICAgICAgY2MudHJhbnNsYXRlQ29sb3IodCwgdG1wRGF0YSwgc3JjQ1MsIHh5ekNTLCBudW1QaXhlbHMpOworICAgICAgICB9IGVsc2UgeyAvLyBub24gSUNDCisgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG51bVBpeGVsczsgaysrKSB7CisgICAgICAgICAgICAgICAgdG1wRGF0YVtrXSA9IHNyY0NTLnRvQ0lFWFlaKHRtcERhdGFba10pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2MubG9hZFNjYWxpbmdEYXRhKHh5ekNTKTsgLy8gcHJlcGFyZSBmb3Igc2NhbGluZyBYWVoKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoT2JqZWN0IGVsZW1lbnQgOiBzZXF1ZW5jZSkgeworICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBJQ0NfVHJhbnNmb3JtKSB7CisgICAgICAgICAgICAgICAgSUNDX1RyYW5zZm9ybSB0ID0gKElDQ19UcmFuc2Zvcm0pZWxlbWVudDsKKyAgICAgICAgICAgICAgICBjYy50cmFuc2xhdGVDb2xvcih0LCB0bXBEYXRhLCBudWxsLCBudWxsLCBudW1QaXhlbHMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBDb2xvclNwYWNlIGNzID0gKENvbG9yU3BhY2UpZWxlbWVudDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG51bVBpeGVsczsgaysrKSB7CisgICAgICAgICAgICAgICAgICAgIHRtcERhdGFba10gPSBjcy5mcm9tQ0lFWFlaKHRtcERhdGFba10pOworICAgICAgICAgICAgICAgICAgICB0bXBEYXRhW2tdID0gY3MudG9DSUVYWVoodG1wRGF0YVtrXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTGFzdCB0cmFuc2Zvcm0uLi4KKyAgICAgICAgaWYgKHNlcXVlbmNlW3NlcXVlbmNlLmxlbmd0aCAtIDFdIGluc3RhbmNlb2YgSUNDX1RyYW5zZm9ybSkgeyAvLyBJQ0MKKyAgICAgICAgICAgIElDQ19UcmFuc2Zvcm0gdCA9IChJQ0NfVHJhbnNmb3JtKXNlcXVlbmNlW3NlcXVlbmNlLmxlbmd0aCAtIDFdOworICAgICAgICAgICAgY2MudHJhbnNsYXRlQ29sb3IodCwgdG1wRGF0YSwgeHl6Q1MsIGRzdENTLCBudW1QaXhlbHMpOworICAgICAgICB9IGVsc2UgeyAvLyBub24gSUNDCisgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG51bVBpeGVsczsgaysrKSB7CisgICAgICAgICAgICAgICAgdG1wRGF0YVtrXSA9IGRzdENTLmZyb21DSUVYWVoodG1wRGF0YVtrXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUG9pbnQyRCBnZXRQb2ludDJEKFBvaW50MkQgc3JjUHQsIFBvaW50MkQgZHN0UHQpIHsKKyAgICAgICAgaWYgKGRzdFB0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRzdFB0LnNldExvY2F0aW9uKHNyY1B0KTsKKyAgICAgICAgICAgIHJldHVybiBkc3RQdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFBvaW50MkQuRmxvYXQoKGZsb2F0KXNyY1B0LmdldFgoKSwgKGZsb2F0KXNyY1B0LmdldFkoKSk7CisgICAgfQorCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKFJhc3RlciBzcmMpIHsKKyAgICAgICAgaW50IG5Db21wcyA9IDA7CisgICAgICAgIGludCBuU3BhY2VzID0gY29udmVyc2lvblNlcXVlbmNlLmxlbmd0aDsKKworICAgICAgICBpZiAoblNwYWNlcyA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjYxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBPYmplY3QgbGFzdENTID0gY29udmVyc2lvblNlcXVlbmNlW25TcGFjZXMgLSAxXTsKKyAgICAgICAgaWYgKGxhc3RDUyBpbnN0YW5jZW9mIENvbG9yU3BhY2UpIHsKKyAgICAgICAgICAgIG5Db21wcyA9ICgoQ29sb3JTcGFjZSlsYXN0Q1MpLmdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5Db21wcyA9ICgoSUNDX1Byb2ZpbGUpbGFzdENTKS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDYWxjdWxhdGUgY29ycmVjdCBkYXRhIHR5cGUKKyAgICAgICAgaW50IGRzdERhdGFUeXBlID0gc3JjLmdldERhdGFCdWZmZXIoKS5nZXREYXRhVHlwZSgpOworICAgICAgICBpZiAoZHN0RGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZHN0RGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1NIT1JUKSB7CisgICAgICAgICAgICBkc3REYXRhVHlwZSA9IERhdGFCdWZmZXIuVFlQRV9TSE9SVDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBSYXN0ZXIuY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoZHN0RGF0YVR5cGUsIHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCksIG5Db21wcywKKyAgICAgICAgICAgICAgICBuZXcgUG9pbnQoc3JjLmdldE1pblgoKSwgc3JjLmdldE1pblkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRChSYXN0ZXIgc3JjKSB7CisgICAgICAgIHJldHVybiBzcmMuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKEJ1ZmZlcmVkSW1hZ2Ugc3JjKSB7CisgICAgICAgIHJldHVybiBzcmMuZ2V0UmFzdGVyKCkuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBJQ0NfUHJvZmlsZXMgb2JqZWN0cyB3aGljaCBjb25zdHJ1Y3RzIHRoaXMKKyAgICAgKiBDb2xvckNvbnZlcnRPcCBvYmplY3Qgb3IgcmV0dXJucyBudWxsIGlmIHRoaXMgQ29sb3JDb252ZXJ0T3AgaXMgbm90CisgICAgICogY29uc3RydWN0ZWQgZnJvbSBhcnJheSBvZiBJQ0NfUHJvZmlsZXMuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBJQ0NfUHJvZmlsZXMgb2JqZWN0cyB3aGljaCBjb25zdHJ1Y3RzIHRoaXMKKyAgICAgKiAgICAgICAgIENvbG9yQ29udmVydE9wIG9iamVjdCBvciByZXR1cm5zIG51bGwgaWYgdGhpcyBDb2xvckNvbnZlcnRPcCBpcworICAgICAqICAgICAgICAgbm90IGNvbnN0cnVjdGVkIGZyb20gYXJyYXkgb2YgSUNDX1Byb2ZpbGVzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBJQ0NfUHJvZmlsZVtdIGdldElDQ19Qcm9maWxlcygpIHsKKyAgICAgICAgaWYgKG1pZFByb2ZpbGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBtaWRQcm9maWxlczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUmVuZGVyaW5nSGludHMgZ2V0UmVuZGVyaW5nSGludHMoKSB7CisgICAgICAgIHJldHVybiByZW5kZXJpbmdIaW50czsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvQ29sb3JNb2RlbC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0NvbG9yTW9kZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjA4NGUxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0NvbG9yTW9kZWwuamF2YQpAQCAtMCwwICsxLDk2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5UcmFuc3BhcmVuY3k7CitpbXBvcnQgamF2YS5hd3QuY29sb3IuQ29sb3JTcGFjZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIGNsYXNzIENvbG9yTW9kZWwuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29sb3JNb2RlbCBpbXBsZW1lbnRzIFRyYW5zcGFyZW5jeSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGl4ZWxfYml0cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHBpeGVsX2JpdHM7IC8vIFBpeGVsIGxlbmd0aCBpbiBiaXRzCisKKyAgICAvKioKKyAgICAgKiBUaGUgdHJhbnNmZXIgdHlwZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHRyYW5zZmVyVHlwZTsKKworICAgIC8qKgorICAgICAqIFRoZSBjcy4KKyAgICAgKi8KKyAgICBDb2xvclNwYWNlIGNzOworCisgICAgLyoqCisgICAgICogVGhlIGhhcyBhbHBoYS4KKyAgICAgKi8KKyAgICBib29sZWFuIGhhc0FscGhhOworCisgICAgLyoqCisgICAgICogVGhlIGlzIGFscGhhIHByZW11bHRpcGxpZWQuCisgICAgICovCisgICAgYm9vbGVhbiBpc0FscGhhUHJlbXVsdGlwbGllZDsKKworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc3BhcmVuY3kuCisgICAgICovCisgICAgaW50IHRyYW5zcGFyZW5jeTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW0gY29sb3IgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBpbnQgbnVtQ29sb3JDb21wb25lbnRzOworCisgICAgLyoqCisgICAgICogVGhlIG51bSBjb21wb25lbnRzLgorICAgICAqLworICAgIGludCBudW1Db21wb25lbnRzOworCisgICAgLyoqCisgICAgICogVGhlIGJpdHMuCisgICAgICovCisgICAgaW50W10gYml0czsgLy8gQXJyYXkgb2YgY29tcG9uZW50cyBtYXNrcworCisgICAgLyoqCisgICAgICogVGhlIG1heCB2YWx1ZXMuCisgICAgICovCisgICAgaW50W10gbWF4VmFsdWVzID0gbnVsbDsgLy8gTWF4IHZhbHVlcyB0aGF0IG1heSBiZSByZXByZXNlbnQgYnkgY29sb3IKKworICAgIC8vIGNvbXBvbmVudHMKKworICAgIC8qKgorICAgICAqIFRoZSBtYXggYml0IGxlbmd0aC4KKyAgICAgKi8KKyAgICBpbnQgbWF4Qml0TGVuZ3RoOyAvLyBNYXggbGVuZ3RoIGNvbG9yIGNvbXBvbmVudHMgaW4gYml0cworCisgICAgLyoqCisgICAgICogVGhlIFJHIGJkZWZhdWx0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENvbG9yTW9kZWwgUkdCZGVmYXVsdDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBjb2xvciBtb2RlbCB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbF9iaXRzCisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwgbGVuZ3RoIGluIGJpdHMuCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBjb21wb25lbnQgbWFza3MuCisgICAgICogQHBhcmFtIGNzcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbG9yIHNwYWNlLgorICAgICAqIEBwYXJhbSBoYXNBbHBoYQorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgY29sb3IgbW9kZWwgaGFzIGFscGhhLgorICAgICAqIEBwYXJhbSBpc0FscGhhUHJlbXVsdGlwbGllZAorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgYWxwaGEgaXMgcHJlLW11bHRpcGxpZWQuCisgICAgICogQHBhcmFtIHRyYW5zcGFyZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zcGFyZW5jeSBzdHJhdGVneSwgQHNlZSBqYXZhLmF3dC5UcmFuc3BhcmVuY3kuCisgICAgICogQHBhcmFtIHRyYW5zZmVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zZmVyIHR5cGUgKHByaW1pdGl2ZSBqYXZhIHR5cGUgdG8gdXNlIGZvciB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbXBvbmVudHMpLgorICAgICAqLworICAgIHByb3RlY3RlZCBDb2xvck1vZGVsKGludCBwaXhlbF9iaXRzLCBpbnRbXSBiaXRzLCBDb2xvclNwYWNlIGNzcGFjZSwgYm9vbGVhbiBoYXNBbHBoYSwKKyAgICAgICAgICAgIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQsIGludCB0cmFuc3BhcmVuY3ksIGludCB0cmFuc2ZlclR5cGUpIHsKKworICAgICAgICBpZiAocGl4ZWxfYml0cyA8IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNkI9VGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBwaXhlbCB2YWx1ZXMgaXMgbGVzcyB0aGFuIDEKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjZCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoYml0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjZDPWJpdHMgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IHN1bSA9IDA7CisgICAgICAgIGZvciAoaW50IGVsZW1lbnQgOiBiaXRzKSB7CisgICAgICAgICAgICBpZiAoZWxlbWVudCA8IDApIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjZEPVRoZSBlbGVtZW50cyBpbiBiaXRzIGlzIGxlc3MgdGhhbiAwCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNkQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1bSArPSBlbGVtZW50OworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN1bSA8IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNkU9VGhlIHN1bSBvZiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gYml0cyBpcyBsZXNzIHRoYW4gMQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2RSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGNzcGFjZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjZGPVRoZSBjc3BhY2UgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNkYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0cmFuc3BhcmVuY3kgPCBUcmFuc3BhcmVuY3kuT1BBUVVFIHx8IHRyYW5zcGFyZW5jeSA+IFRyYW5zcGFyZW5jeS5UUkFOU0xVQ0VOVCkgeworICAgICAgICAgICAgLy8gYXd0LjI3MD1UaGUgdHJhbnNwYXJlbmN5IGlzIG5vdCBhIHZhbGlkIHZhbHVlCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3MCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5waXhlbF9iaXRzID0gcGl4ZWxfYml0czsKKyAgICAgICAgdGhpcy5iaXRzID0gYml0cy5jbG9uZSgpOworCisgICAgICAgIG1heFZhbHVlcyA9IG5ldyBpbnRbYml0cy5sZW5ndGhdOworICAgICAgICBtYXhCaXRMZW5ndGggPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWF4VmFsdWVzW2ldID0gKDEgPDwgYml0c1tpXSkgLSAxOworICAgICAgICAgICAgaWYgKGJpdHNbaV0gPiBtYXhCaXRMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBtYXhCaXRMZW5ndGggPSBiaXRzW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY3MgPSBjc3BhY2U7CisgICAgICAgIHRoaXMuaGFzQWxwaGEgPSBoYXNBbHBoYTsKKyAgICAgICAgdGhpcy5pc0FscGhhUHJlbXVsdGlwbGllZCA9IGlzQWxwaGFQcmVtdWx0aXBsaWVkOworICAgICAgICBudW1Db2xvckNvbXBvbmVudHMgPSBjcy5nZXROdW1Db21wb25lbnRzKCk7CisKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICBudW1Db21wb25lbnRzID0gbnVtQ29sb3JDb21wb25lbnRzICsgMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG51bUNvbXBvbmVudHMgPSBudW1Db2xvckNvbXBvbmVudHM7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnRyYW5zcGFyZW5jeSA9IHRyYW5zcGFyZW5jeTsKKyAgICAgICAgdGhpcy50cmFuc2ZlclR5cGUgPSB0cmFuc2ZlclR5cGU7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgY29sb3IgbW9kZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHBpeGVsIGJpdCBkZXB0aC4gVGhlCisgICAgICogdHJhbnNmZXJUeXBlIGlzIGNob3NlbiBiYXNlZCBvbiB0aGUgcGl4ZWwgYml0cywgYW5kIHRoZSBvdGhlciBkYXRhIGZpZWxkcworICAgICAqIGFyZSBnaXZlbiBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3JNb2RlbChpbnQgYml0cykgeworCisgICAgICAgIGlmIChiaXRzIDwgMSkgeworICAgICAgICAgICAgLy8gYXd0LjI3MT1UaGUgbnVtYmVyIG9mIGJpdHMgaW4gYml0cyBpcyBsZXNzIHRoYW4gMQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHBpeGVsX2JpdHMgPSBiaXRzOworICAgICAgICB0cmFuc2ZlclR5cGUgPSBnZXRUcmFuc2ZlclR5cGUoYml0cyk7CisgICAgICAgIGNzID0gQ29sb3JTcGFjZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpOworICAgICAgICBoYXNBbHBoYSA9IHRydWU7CisgICAgICAgIGlzQWxwaGFQcmVtdWx0aXBsaWVkID0gZmFsc2U7CisgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5UUkFOU0xVQ0VOVDsKKworICAgICAgICBudW1Db2xvckNvbXBvbmVudHMgPSAzOworICAgICAgICBudW1Db21wb25lbnRzID0gNDsKKworICAgICAgICB0aGlzLmJpdHMgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgZWxlbWVudHMgZnJvbSB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCBhcnJheSwgdHJhbnNmb3JtaW5nCisgICAgICogdGhlbSBhY2NvcmRpbmcgdG8gcnVsZXMgb2YgdGhlIGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgY29tcG9uZW50cy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBub3JtQ29tcG9uZW50cyBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgdGhhdCB0aGUgcmVzdWx0IGlzIHdyaXR0ZW4gdG86IGFuIGFycmF5IG9mIHZhbHVlcworICAgICAqICAgICAgICAgICAgd2hvc2UgbGVuZ3RoIG11c3QgYmUgdGhlIG51bWJlciBvZiBjb21wb25lbnRzIHVzZWQgYnkgdGhlCisgICAgICogICAgICAgICAgICBjb2xvciBtb2RlbCBhbmQgd2hvc2UgdHlwZSBkZXBlbmRzIG9uIHRoZSB0cmFuc2ZlciB0eXBlIChiYXNlZAorICAgICAqICAgICAgICAgICAgb24gdGhlIHBpeGVsIGJpdCBkZXB0aCksIG9yIG51bGwgdG8gaGF2ZSB0aGUgYXBwcm9wcmlhdGUgYXJyYXkKKyAgICAgKiAgICAgICAgICAgIGNyZWF0ZWQuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZGF0YSBlbGVtZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldERhdGFFbGVtZW50cyhpbnRbXSBjb21wb25lbnRzLCBpbnQgb2Zmc2V0LCBPYmplY3Qgb2JqKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90ICIgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgInN1cHBvcnRlZCBieSB0aGlzIENvbG9yTW9kZWwiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgZWxlbWVudHMgZnJvbSB0aGUgc3BlY2lmaWVkIGFycmF5IG9mIG5vcm1hbGl6ZWQgY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbm9ybUNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBub3JtYWxpemVkIGNvbXBvbmVudHMuCisgICAgICogQHBhcmFtIG5vcm1PZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIG5vcm1Db21wb25lbnRzIGFycmF5LgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IHRoZSByZXN1bHQgaXMgd3JpdHRlbiB0bzogYW4gYXJyYXkgb2YgdmFsdWVzCisgICAgICogICAgICAgICAgICB3aG9zZSBsZW5ndGggbXVzdCBiZSB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgdXNlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1vZGVsIGFuZCB3aG9zZSB0eXBlIGRlcGVuZHMgb24gdGhlIHRyYW5zZmVyIHR5cGUgKGJhc2VkCisgICAgICogICAgICAgICAgICBvbiB0aGUgcGl4ZWwgYml0IGRlcHRoKSwgb3IgbnVsbCB0byBoYXZlIHRoZSBhcHByb3ByaWF0ZSBhcnJheQorICAgICAqICAgICAgICAgICAgY3JlYXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBkYXRhIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGZsb2F0W10gbm9ybUNvbXBvbmVudHMsIGludCBub3JtT2Zmc2V0LCBPYmplY3Qgb2JqKSB7CisgICAgICAgIGludCB1bm5vcm1Db21wb25lbnRzW10gPSBnZXRVbm5vcm1hbGl6ZWRDb21wb25lbnRzKG5vcm1Db21wb25lbnRzLCBub3JtT2Zmc2V0LCBudWxsLCAwKTsKKyAgICAgICAgcmV0dXJuIGdldERhdGFFbGVtZW50cyh1bm5vcm1Db21wb25lbnRzLCAwLCBvYmopOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgZWxlbWVudHMgY29ycmVzcG9uZGluZyB0byB0aGUgcGl4ZWwgZGV0ZXJtaW5lZCBieSB0aGUgUkdCCisgICAgICogZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmdiCisgICAgICogICAgICAgICAgICB0aGUgUkdCIGludGVnZXIgdmFsdWUgdGhhdCBkZWZpbmVzIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0gcGl4ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IHRoZSByZXN1bHQgaXMgd3JpdHRlbiB0bzogYW4gYXJyYXkgb2YgdmFsdWVzCisgICAgICogICAgICAgICAgICB3aG9zZSBsZW5ndGggbXVzdCBiZSB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgdXNlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1vZGVsIGFuZCB3aG9zZSB0eXBlIGRlcGVuZHMgb24gdGhlIHRyYW5zZmVyIHR5cGUgKGJhc2VkCisgICAgICogICAgICAgICAgICBvbiB0aGUgcGl4ZWwgYml0IGRlcHRoKSwgb3IgbnVsbCB0byBoYXZlIHRoZSBhcHByb3ByaWF0ZSBhcnJheQorICAgICAqICAgICAgICAgICAgY3JlYXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBkYXRhIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCByZ2IsIE9iamVjdCBwaXhlbCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICJzdXBwb3J0ZWQgYnkgdGhpcyBDb2xvck1vZGVsIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjaGlsZCByYXN0ZXIgY29ycmVzcG9uZGluZyB0byB0aGUgYWxwaGEgY2hhbm5lbCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogd3JpdGFibGUgcmFzdGVyLCBvciBudWxsIGlmIGFscGhhIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHJhc3RlcgorICAgICAqICAgICAgICAgICAgdGhlIHJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBhbHBoYSByYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldEFscGhhUmFzdGVyKFdyaXRhYmxlUmFzdGVyIHJhc3RlcikgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGNvbG9yIG1vZGVsIGJ5IGNvZXJjaW5nIHRoZSBkYXRhIGluIHRoZSB3cml0YWJsZSByYXN0ZXIgaW4KKyAgICAgKiBhY2NvcmRhbmNlIHdpdGggdGhlIGFscGhhIHN0cmF0ZWd5IG9mIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHJhc3RlcgorICAgICAqICAgICAgICAgICAgdGhlIHJhc3Rlci4KKyAgICAgKiBAcGFyYW0gaXNBbHBoYVByZW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdGhlIGFscGhhIGlzIHByZS1tdWx0aXBsaWVkIGluIHRoaXMgY29sb3IgbW9kZWwKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY29sb3IgbW9kZWwuCisgICAgICovCisgICAgcHVibGljIENvbG9yTW9kZWwgY29lcmNlRGF0YShXcml0YWJsZVJhc3RlciByYXN0ZXIsIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGlzIG1ldGhvZCBpcyBub3QgIiArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAic3VwcG9ydGVkIGJ5IHRoaXMgQ29sb3JNb2RlbCIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGhlIG91dHB1dCBmb3JtYXQgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3IuCisgICAgICAgIC8vIEl0IGNvdWxkIGJlIHJldmVsZWQgc3VjaCB3YXk6CisgICAgICAgIC8vIENvbG9yTW9kZWwgY20gPSBuZXcKKyAgICAgICAgLy8gQ29tcG9uZW50Q29sb3JNb2RlbChDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQiwKKyAgICAgICAgLy8gZmFsc2UsIGZhbHNlLCBUcmFuc3BhcmVuY3kuT1BBUVVFLCBEYXRhQnVmZmVyLlRZUEVfQllURSk7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihjbS50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuICJDb2xvck1vZGVsOiBDb2xvciBTcGFjZSA9ICIgKyBjcy50b1N0cmluZygpICsgIjsgaGFzIGFscGhhID0gIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICArIGhhc0FscGhhICsgIjsgaXMgYWxwaGEgcHJlbXVsdGlwaWVkID0gIiAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgKyBpc0FscGhhUHJlbXVsdGlwbGllZCArICI7IHRyYW5zcGFyZW5jeSA9ICIgKyB0cmFuc3BhcmVuY3kgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICsgIjsgbnVtYmVyIGNvbG9yIGNvbXBvbmVudHMgPSAiICsgbnVtQ29sb3JDb21wb25lbnRzIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICArICI7IHBpeGVsIGJpdHMgPSAiICsgcGl4ZWxfYml0cyArICI7IHRyYW5zZmVyIHR5cGUgPSAiIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgICsgdHJhbnNmZXJUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXBvbmVudHMgb2YgdGhlIHBpeGVsIGRldGVybWluZWQgYnkgdGhlIGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHBpeGVsCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0aGF0IGRlZmluZXMgdGhlIHBpeGVsICh3aG9zZSBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIHBpeGVsIGxlbmd0aCBpbiBiaXRzLgorICAgICAqIEBzZWUgQ29sb3JNb2RlbCNnZXRUcmFuc2ZlclR5cGUoKQorICAgICAqIEBwYXJhbSBjb21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgdGhlIGFycmF5IHdoZXJlIHRoZSByZXN1bHRpbmcgY29tcG9uZW50cyBhcmUgd3JpdHRlbiAob3IKKyAgICAgKiAgICAgICAgICAgIG51bGwgdG8gcHJvbXB0IHRoZSBtZXRob2QgdG8gY3JlYXRlIHRoZSByZXR1cm4gYXJyYXkpLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdGhhdCB0ZWxscyB3aGVyZSB0aGUgcmVzdWx0cyBzaG91bGQgYmUgd3JpdHRlbiBpbgorICAgICAqICAgICAgICAgICAgdGhlIHJldHVybiBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRDb21wb25lbnRzKE9iamVjdCBwaXhlbCwgaW50W10gY29tcG9uZW50cywgaW50IG9mZnNldCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICJzdXBwb3J0ZWQgYnkgdGhpcyBDb2xvck1vZGVsIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBub3JtYWxpemVkIGNvbXBvbmVudHMgb2YgdGhlIHBpeGVsIGRldGVybWluZWQgYnkgdGhlIGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHBpeGVsCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0aGF0IGRlZmluZXMgdGhlIHBpeGVsICh3aG9zZSBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIHBpeGVsIGxlbmd0aCBpbiBiaXRzLgorICAgICAqIEBzZWUgQ29sb3JNb2RlbCNnZXRUcmFuc2ZlclR5cGUoKQorICAgICAqIEBwYXJhbSBub3JtQ29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdoZXJlIHRoZSByZXN1bHRpbmcgbm9ybWFsaXplZCBjb21wb25lbnRzIGFyZQorICAgICAqICAgICAgICAgICAgd3JpdHRlbiAob3IgbnVsbCB0byBwcm9tcHQgdGhlIG1ldGhvZCB0byBjcmVhdGUgdGhlIHJldHVybgorICAgICAqICAgICAgICAgICAgYXJyYXkpLgorICAgICAqIEBwYXJhbSBub3JtT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRoYXQgdGVsbHMgd2hlcmUgdGhlIHJlc3VsdHMgc2hvdWxkIGJlIHdyaXR0ZW4gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2Ygbm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldE5vcm1hbGl6ZWRDb21wb25lbnRzKE9iamVjdCBwaXhlbCwgZmxvYXRbXSBub3JtQ29tcG9uZW50cywgaW50IG5vcm1PZmZzZXQpIHsKKworICAgICAgICBpZiAocGl4ZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI5ND1waXhlbCBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjk0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpbnQgdW5ub3JtQ29tcG9uZW50c1tdID0gZ2V0Q29tcG9uZW50cyhwaXhlbCwgbnVsbCwgMCk7CisgICAgICAgIHJldHVybiBnZXROb3JtYWxpemVkQ29tcG9uZW50cyh1bm5vcm1Db21wb25lbnRzLCAwLCBub3JtQ29tcG9uZW50cywgbm9ybU9mZnNldCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgQ29sb3JNb2RlbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDb2xvck1vZGVsIGNtID0gKENvbG9yTW9kZWwpb2JqOworCisgICAgICAgIHJldHVybiAocGl4ZWxfYml0cyA9PSBjbS5nZXRQaXhlbFNpemUoKSAmJiB0cmFuc2ZlclR5cGUgPT0gY20uZ2V0VHJhbnNmZXJUeXBlKCkKKyAgICAgICAgICAgICAgICAmJiBjcy5nZXRUeXBlKCkgPT0gY20uZ2V0Q29sb3JTcGFjZSgpLmdldFR5cGUoKSAmJiBoYXNBbHBoYSA9PSBjbS5oYXNBbHBoYSgpCisgICAgICAgICAgICAgICAgJiYgaXNBbHBoYVByZW11bHRpcGxpZWQgPT0gY20uaXNBbHBoYVByZW11bHRpcGxpZWQoKQorICAgICAgICAgICAgICAgICYmIHRyYW5zcGFyZW5jeSA9PSBjbS5nZXRUcmFuc3BhcmVuY3koKQorICAgICAgICAgICAgICAgICYmIG51bUNvbG9yQ29tcG9uZW50cyA9PSBjbS5nZXROdW1Db2xvckNvbXBvbmVudHMoKQorICAgICAgICAgICAgICAgICYmIG51bUNvbXBvbmVudHMgPT0gY20uZ2V0TnVtQ29tcG9uZW50cygpICYmIEFycmF5cy5lcXVhbHMoYml0cywgY20KKyAgICAgICAgICAgICAgICAuZ2V0Q29tcG9uZW50U2l6ZSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVkIGNvbXBvbmVudCBvZiB0aGUgcGl4ZWwgZGV0ZXJtaW5lZCBieSB0aGUgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5EYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0aGF0IGRlZmluZXMgdGhlIHBpeGVsICh3aG9zZSBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIHBpeGVsIGxlbmd0aCBpbiBiaXRzLgorICAgICAqIEBzZWUgQ29sb3JNb2RlbCNnZXRUcmFuc2ZlclR5cGUoKQorICAgICAqIEByZXR1cm4gdGhlIHJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlZChPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIHJldHVybiBnZXRSZWQoY29uc3RydWN0UGl4ZWwoaW5EYXRhKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgUkdCIGludGVnZXIgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGUgcGl4ZWwgZGVmaW5lZCBieSB0aGUgZGF0YQorICAgICAqIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbkRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRoYXQgZGVmaW5lcyB0aGUgcGl4ZWwgKHdob3NlIHByaW1pdGl2ZSB0eXBlCisgICAgICogICAgICAgICAgICBjb3JyZXNwb25kcyB0byB0aGUgcGl4ZWwgbGVuZ3RoIGluIGJpdHMuCisgICAgICogQHNlZSBDb2xvck1vZGVsI2dldFRyYW5zZmVyVHlwZSgpCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciB2YWx1ZSB0aGF0IGdpdmVzIHRoZSBwaXhlbCdzIGNvbG9ycyBpbiBSR0IgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UkdCKE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgcmV0dXJuIChnZXRBbHBoYShpbkRhdGEpIDw8IDI0IHwgZ2V0UmVkKGluRGF0YSkgPDwgMTYgfCBnZXRHcmVlbihpbkRhdGEpIDw8IDggfCBnZXRCbHVlKGluRGF0YSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdyZWVuIGNvbXBvbmVudCBvZiB0aGUgcGl4ZWwgZGVmaW5lZCBieSB0aGUgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5EYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0aGF0IGRlZmluZXMgdGhlIHBpeGVsICh3aG9zZSBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIHBpeGVsIGxlbmd0aCBpbiBiaXRzLgorICAgICAqIEBzZWUgQ29sb3JNb2RlbCNnZXRUcmFuc2ZlclR5cGUoKQorICAgICAqIEByZXR1cm4gdGhlIGdyZWVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0R3JlZW4oT2JqZWN0IGluRGF0YSkgeworICAgICAgICByZXR1cm4gZ2V0R3JlZW4oY29uc3RydWN0UGl4ZWwoaW5EYXRhKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmx1ZSBjb21wb25lbnQgb2YgdGhlIHBpeGVsIGRlZmluZWQgYnkgdGhlIGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIGluRGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXkgdGhhdCBkZWZpbmVzIHRoZSBwaXhlbCAod2hvc2UgcHJpbWl0aXZlIHR5cGUKKyAgICAgKiAgICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIHRoZSBwaXhlbCBsZW5ndGggaW4gYml0cy4KKyAgICAgKiBAc2VlIENvbG9yTW9kZWwjZ2V0VHJhbnNmZXJUeXBlKCkKKyAgICAgKiBAcmV0dXJuIHRoZSBibHVlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Qmx1ZShPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIHJldHVybiBnZXRCbHVlKGNvbnN0cnVjdFBpeGVsKGluRGF0YSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFscGhhIGNvbXBvbmVudCBvZiB0aGUgcGl4ZWwgZGVmaW5lZCBieSB0aGUgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5EYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0aGF0IGRlZmluZXMgdGhlIHBpeGVsICh3aG9zZSBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIHBpeGVsIGxlbmd0aCBpbiBiaXRzLgorICAgICAqIEBzZWUgQ29sb3JNb2RlbCNnZXRUcmFuc2ZlclR5cGUoKQorICAgICAqIEByZXR1cm4gdGhlIGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QWxwaGEoT2JqZWN0IGluRGF0YSkgeworICAgICAgICByZXR1cm4gZ2V0QWxwaGEoY29uc3RydWN0UGl4ZWwoaW5EYXRhKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbXBhdGlibGUgd3JpdGFibGUgcmFzdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGRlc2lyZWQgd3JpdGFibGUgcmFzdGVyLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBkZXNpcmVkIHdyaXRhYmxlIHJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSB3cml0YWJsZSByYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcihpbnQgdywgaW50IGgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGlzIG1ldGhvZCBpcyBub3QgIiArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAic3VwcG9ydGVkIGJ5IHRoaXMgQ29sb3JNb2RlbCIpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzYW1wbGUgbW9kZWwgaXMgY29tcGF0aWJsZSB3aXRoIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHNtCisgICAgICogICAgICAgICAgICB0aGUgc2FtcGxlIG1vZGVsLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNhbXBsZSBtb2RlbCBpcyBjb21wYXRpYmxlIHdpdGggdGhpcyBjb2xvciBtb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBhdGlibGVTYW1wbGVNb2RlbChTYW1wbGVNb2RlbCBzbSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICJzdXBwb3J0ZWQgYnkgdGhpcyBDb2xvck1vZGVsIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBjb21wYXRpYmxlIHNhbXBsZSBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBkZXNpcmVkIHNhbXBsZSBtb2RlbC4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgZGVzaXJlZCBzYW1wbGUgbW9kZWwuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlIG1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBjcmVhdGVDb21wYXRpYmxlU2FtcGxlTW9kZWwoaW50IHcsIGludCBoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90ICIgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgInN1cHBvcnRlZCBieSB0aGlzIENvbG9yTW9kZWwiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIHJhc3RlciBpcyBjb21wYXRpYmxlIHdpdGggdGhpcyBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmFzdGVyCisgICAgICogICAgICAgICAgICB0aGUgcmFzdGVyIHRvIGluc3BlY3QuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgcmFzdGVyIGlzIGNvbXBhdGlibGUgd2l0aCB0aGlzIGNvbG9yIG1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcGF0aWJsZVJhc3RlcihSYXN0ZXIgcmFzdGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90ICIgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgInN1cHBvcnRlZCBieSB0aGlzIENvbG9yTW9kZWwiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbG9yIHNwYWNlIG9mIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY29sb3Igc3BhY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvbG9yU3BhY2UgZ2V0Q29sb3JTcGFjZSgpIHsKKyAgICAgICAgcmV0dXJuIGNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5vcm1hbGl6ZWQgY29tcG9uZW50cyBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB1bm5vcm1hbGl6ZWQgY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHVubm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgd2hlcmUgdGhlIGNvbXBvbmVudHMgc2hvdWxkIGJlIHJlYWQgZnJvbSB0aGUgYXJyYXkKKyAgICAgKiAgICAgICAgICAgIG9mIHVubm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqIEBwYXJhbSBub3JtQ29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdoZXJlIHRoZSByZXN1bHRpbmcgbm9ybWFsaXplZCBjb21wb25lbnRzIGFyZQorICAgICAqICAgICAgICAgICAgd3JpdHRlbiAob3IgbnVsbCB0byBwcm9tcHQgdGhlIG1ldGhvZCB0byBjcmVhdGUgdGhlIHJldHVybgorICAgICAqICAgICAgICAgICAgYXJyYXkpLgorICAgICAqIEBwYXJhbSBub3JtT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRoYXQgdGVsbHMgd2hlcmUgdGhlIHJlc3VsdHMgc2hvdWxkIGJlIHdyaXR0ZW4gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgbm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldE5vcm1hbGl6ZWRDb21wb25lbnRzKGludFtdIGNvbXBvbmVudHMsIGludCBvZmZzZXQsIGZsb2F0IG5vcm1Db21wb25lbnRzW10sCisgICAgICAgICAgICBpbnQgbm9ybU9mZnNldCkgeworICAgICAgICBpZiAoYml0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjZDPWJpdHMgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG5vcm1Db21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIG5vcm1Db21wb25lbnRzID0gbmV3IGZsb2F0W251bUNvbXBvbmVudHMgKyBub3JtT2Zmc2V0XTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChoYXNBbHBoYSAmJiBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICAgICAgZmxvYXQgbm9ybUFscGhhID0gKGZsb2F0KWNvbXBvbmVudHNbb2Zmc2V0ICsgbnVtQ29sb3JDb21wb25lbnRzXQorICAgICAgICAgICAgICAgICAgICAvIG1heFZhbHVlc1tudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgaWYgKG5vcm1BbHBoYSAhPSAwLjBmKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgaV0gPSBjb21wb25lbnRzW29mZnNldCArIGldCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyAobm9ybUFscGhhICogbWF4VmFsdWVzW2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbbm9ybU9mZnNldCArIG51bUNvbG9yQ29tcG9uZW50c10gPSBub3JtQWxwaGE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG5vcm1Db21wb25lbnRzW25vcm1PZmZzZXQgKyBpXSA9IDAuMGY7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgaV0gPSAoZmxvYXQpY29tcG9uZW50c1tvZmZzZXQgKyBpXSAvIG1heFZhbHVlc1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBub3JtQ29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIGVsZW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgdW5ub3JtYWxpemVkIGNvbXBvbmVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnRzLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdG8gc3RhcnQgcmVhZGluZyB0aGUgY29tcG9uZW50cyBmcm9tIHRoZSBhcnJheSBvZgorICAgICAqICAgICAgICAgICAgY29tcG9uZW50cy4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRhIGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXREYXRhRWxlbWVudChpbnRbXSBjb21wb25lbnRzLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90ICIgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgInN1cHBvcnRlZCBieSB0aGlzIENvbG9yTW9kZWwiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVubm9ybWFsaXplZCBjb21wb25lbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZAorICAgICAqIG5vcm1hbGl6ZWQgY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbm9ybUNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBub3JtYWxpemVkIGNvbXBvbmVudHMuCisgICAgICogQHBhcmFtIG5vcm1PZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgd2hlcmUgdGhlIGNvbXBvbmVudHMgc2hvdWxkIGJlIHJlYWQgZnJvbSB0aGUgYXJyYXkKKyAgICAgKiAgICAgICAgICAgIG9mIG5vcm1hbGl6ZWQgY29tcG9uZW50cy4KKyAgICAgKiBAcGFyYW0gY29tcG9uZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdoZXJlIHRoZSByZXN1bHRpbmcgdW5ub3JtYWxpemVkIGNvbXBvbmVudHMgYXJlCisgICAgICogICAgICAgICAgICB3cml0dGVuIChvciBudWxsIHRvIHByb21wdCB0aGUgbWV0aG9kIHRvIGNyZWF0ZSB0aGUgcmV0dXJuCisgICAgICogICAgICAgICAgICBhcnJheSkuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCB0aGF0IHRlbGxzIHdoZXJlIHRoZSByZXN1bHRzIHNob3VsZCBiZSB3cml0dGVuIGluCisgICAgICogICAgICAgICAgICB0aGUgcmV0dXJuIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIHVubm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRVbm5vcm1hbGl6ZWRDb21wb25lbnRzKGZsb2F0IG5vcm1Db21wb25lbnRzW10sIGludCBub3JtT2Zmc2V0LAorICAgICAgICAgICAgaW50IGNvbXBvbmVudHNbXSwgaW50IG9mZnNldCkgeworCisgICAgICAgIGlmIChiaXRzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNkM9Yml0cyBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjZDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobm9ybUNvbXBvbmVudHMubGVuZ3RoIC0gbm9ybU9mZnNldCA8IG51bUNvbXBvbmVudHMpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNzM9VGhlIGxlbmd0aCBvZiBub3JtQ29tcG9uZW50cyBtaW51cyBub3JtT2Zmc2V0IGlzIGxlc3MKKyAgICAgICAgICAgIC8vIHRoYW4gbnVtQ29tcG9uZW50cworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgaW50W251bUNvbXBvbmVudHMgKyBvZmZzZXRdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGNvbXBvbmVudHMubGVuZ3RoIC0gb2Zmc2V0IDwgbnVtQ29tcG9uZW50cykgeworICAgICAgICAgICAgICAgIC8vIGF3dC4yNzI9VGhlIGxlbmd0aCBvZiBjb21wb25lbnRzIG1pbnVzIG9mZnNldCBpcyBsZXNzIHRoYW4KKyAgICAgICAgICAgICAgICAvLyBudW1Db21wb25lbnRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChoYXNBbHBoYSAmJiBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjb21wb25lbnRzW29mZnNldCArIGldID0gKGludCkobm9ybUNvbXBvbmVudHNbbm9ybU9mZnNldCArIGldICogbWF4VmFsdWVzW2ldCisgICAgICAgICAgICAgICAgICAgICAgICAqIGFscGhhICsgMC41Zik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb21wb25lbnRzW29mZnNldCArIG51bUNvbG9yQ29tcG9uZW50c10gPSAoaW50KShub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICsgbnVtQ29sb3JDb21wb25lbnRzXQorICAgICAgICAgICAgICAgICAgICAqIG1heFZhbHVlc1tudW1Db2xvckNvbXBvbmVudHNdICsgMC41Zik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgICAgIGNvbXBvbmVudHNbb2Zmc2V0ICsgaV0gPSAoaW50KShub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgaV0gKiBtYXhWYWx1ZXNbaV0gKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSBub3JtYWxpemVkIGNvbXBvbmVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIG5vcm1Db21wb25lbnRzCisgICAgICogICAgICAgICAgICB0aGUgbm9ybWFsaXplZCBjb21wb25lbnRzLgorICAgICAqIEBwYXJhbSBub3JtT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHdoZXJlIHRoZSBub3JtYWxpemVkIGNvbXBvbmVudHMgc2hvdWxkIGJlIHJlYWQgZnJvbQorICAgICAqICAgICAgICAgICAgdGhlIG5vcm1hbGl6ZWQgY29tcG9uZW50IGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERhdGFFbGVtZW50KGZsb2F0IG5vcm1Db21wb25lbnRzW10sIGludCBub3JtT2Zmc2V0KSB7CisgICAgICAgIGludCB1bm5vcm1Db21wb25lbnRzW10gPSBnZXRVbm5vcm1hbGl6ZWRDb21wb25lbnRzKG5vcm1Db21wb25lbnRzLCBub3JtT2Zmc2V0LCBudWxsLCAwKTsKKyAgICAgICAgcmV0dXJuIGdldERhdGFFbGVtZW50KHVubm9ybUNvbXBvbmVudHMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRha2VzIGEgcGl4ZWwgd2hvc2UgZGF0YSBpcyBkZWZpbmVkIGJ5IGFuIGludGVnZXIsIGFuZCB3cml0ZXMgdGhlCisgICAgICogY29ycmVzcG9uZGluZyBjb21wb25lbnRzIGludG8gdGhlIGNvbXBvbmVudHMgYXJyYXksIHN0YXJ0aW5nIGZyb20gdGhlCisgICAgICogaW5kZXggb2Zmc2V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIGRhdGEuCisgICAgICogQHBhcmFtIGNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIHdyaXRlIHRoZSBjb21wb25lbnRzIHRvIChvciBudWxsIHRvIGhhdmUgdGhlCisgICAgICogICAgICAgICAgICBtZXRob2QgY3JlYXRlIHRoZSByZXR1cm4gYXJyYXkpLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdGhhdCBkZXRlcm1pbmVzIHdoZXJlIHRoZSByZXN1bHRzIGFyZSB3cml0dGVuIGluCisgICAgICogICAgICAgICAgICB0aGUgY29tcG9uZW50cyBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBjb21wb25lbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRDb21wb25lbnRzKGludCBwaXhlbCwgaW50IGNvbXBvbmVudHNbXSwgaW50IG9mZnNldCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICJzdXBwb3J0ZWQgYnkgdGhpcyBDb2xvck1vZGVsIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZWQgY29tcG9uZW50IG9mIHRoZSBwaXhlbCBkZXRlcm1pbmVkIGJ5IHRoZSBwaXhlbCBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsLgorICAgICAqIEByZXR1cm4gdGhlIHJlZCBjb21wb25lbnQgb2YgdGhlIGdpdmVuIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0UmVkKGludCBwaXhlbCk7CisKKyAgICAvKioKKyAgICAgKiBUYWtlcyB0aGUgcGl4ZWwgZGF0YSBhbmQgcmV0dXJucyB0aGUgaW50ZWdlciB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIHBpeGVsJ3MgY29sb3IgaW4gUkdCIGZvcm1hdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGl4ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgUkdCIGludGVnZXIgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSR0IoaW50IHBpeGVsKSB7CisgICAgICAgIHJldHVybiAoZ2V0QWxwaGEocGl4ZWwpIDw8IDI0IHwgZ2V0UmVkKHBpeGVsKSA8PCAxNiB8IGdldEdyZWVuKHBpeGVsKSA8PCA4IHwgZ2V0Qmx1ZShwaXhlbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdyZWVuIGNvbXBvbmVudCBvZiB0aGUgcGl4ZWwgZGV0ZXJtaW5lZCBieSB0aGUgcGl4ZWwgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGl4ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBncmVlbiBjb21wb25lbnQgb2YgdGhlIGdpdmVuIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0R3JlZW4oaW50IHBpeGVsKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNpemUgb2YgdGhlIGRlc2lyZWQgY29tcG9uZW50IG9mIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbXBvbmVudElkeAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRoYXQgZGV0ZXJtaW5lcyB3aGljaCBjb21wb25lbnQgc2l6ZSB0byBnZXQuCisgICAgICogQHJldHVybiB0aGUgY29tcG9uZW50IHNpemUgY29ycmVzcG9uZGluZyB0byB0aGUgaW5kZXguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY29sb3IgbW9kZWwgZG9lc24ndCBzdXBwb3J0IGFuIGFycmF5IG9mIHNlcGFyYXRlCisgICAgICogICAgICAgICAgICAgY29tcG9uZW50cy4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlCisgICAgICogICAgICAgICAgICAgbnVtYmVyIG9mIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb21wb25lbnRTaXplKGludCBjb21wb25lbnRJZHgpIHsKKyAgICAgICAgaWYgKGJpdHMgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI2Qz1iaXRzIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNkMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21wb25lbnRJZHggPCAwIHx8IGNvbXBvbmVudElkeCA+PSBiaXRzLmxlbmd0aCkgeworICAgICAgICAgICAgLy8gYXd0LjI3ND1jb21wb25lbnRJZHggaXMgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBvcgorICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjc0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYml0c1tjb21wb25lbnRJZHhdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBwaXhlbCBkZXRlcm1pbmVkIGJ5IHRoZSBwaXhlbCBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsLgorICAgICAqIEByZXR1cm4gdGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBnaXZlbiBwaXhlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEJsdWUoaW50IHBpeGVsKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFscGhhIGNvbXBvbmVudCBvZiB0aGUgcGl4ZWwgZGV0ZXJtaW5lZCBieSB0aGUgcGl4ZWwgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGl4ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhbHBoYSBjb21wb25lbnQgb2YgdGhlIGdpdmVuIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0QWxwaGEoaW50IHBpeGVsKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFycmF5IG9mIHNpemVzIG9mIHRoZSBkaWZmZXJlbnQgY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBzaXplcyBvZiB0aGUgZGlmZmVyZW50IGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldENvbXBvbmVudFNpemUoKSB7CisgICAgICAgIGlmIChiaXRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBiaXRzLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBhbHBoYSBjb21wb25lbnQgaXMgcHJlLW11bHRpcGxpZWQuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgYWxwaGEgY29tcG9uZW50IGlzIHByZS1tdWx0aXBsaWVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkKCkgeworICAgICAgICByZXR1cm4gaXNBbHBoYVByZW11bHRpcGxpZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyBjb2xvciBtb2RlbCBzdXBwb3J0cyBhbHBoYS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgY29sb3IgbW9kZWwgaGFzIGFscGhhLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0FscGhhKCkgeworICAgICAgICByZXR1cm4gaGFzQWxwaGE7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2ggPSAwOworICAgICAgICBpbnQgdG1wOworCisgICAgICAgIGlmIChoYXNBbHBoYSkgeworICAgICAgICAgICAgaGFzaCBePSAxOworICAgICAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgICAgIGhhc2ggXj0gMTsKKyAgICAgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIH0KKworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCBePSBudW1Db2xvckNvbXBvbmVudHM7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworCisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIF49IHRyYW5zcGFyZW5jeTsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggXj0gY3MuZ2V0VHlwZSgpOworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCBePSBwaXhlbF9iaXRzOworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCBePSB0cmFuc2ZlclR5cGU7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworCisgICAgICAgIGlmIChiaXRzICE9IG51bGwpIHsKKworICAgICAgICAgICAgZm9yIChpbnQgZWxlbWVudCA6IGJpdHMpIHsKKyAgICAgICAgICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgICAgICAgICBoYXNoIF49IGVsZW1lbnQ7CisgICAgICAgICAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRUcmFuc3BhcmVuY3koKSB7CisgICAgICAgIHJldHVybiB0cmFuc3BhcmVuY3k7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHJhbnNmZXIgdHlwZSwgd2hpY2ggaXMgdGhlIHR5cGUgb2YgSmF2YSBwcmltaXRpdmUgdmFsdWUgdGhhdAorICAgICAqIGNvcnJlc3BvbmRzIHRvIHRoZSBiaXQgbGVuZ3RoIHBlciBwaXhlbDogZWl0aGVyCisgICAgICoge0BsaW5rIERhdGFCdWZmZXIjVFlQRV9CWVRFfSwge0BsaW5rIERhdGFCdWZmZXIjVFlQRV9VU0hPUlR9LAorICAgICAqIHtAbGluayBEYXRhQnVmZmVyI1RZUEVfSU5UfSwgb3Ige0BsaW5rIERhdGFCdWZmZXIjVFlQRV9VTkRFRklORUR9LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZmVyIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRUcmFuc2ZlclR5cGUoKSB7CisgICAgICAgIHJldHVybiB0cmFuc2ZlclR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGl4ZWwgc2l6ZSBpbiBiaXRzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHBpeGVsIHNpemUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQaXhlbFNpemUoKSB7CisgICAgICAgIHJldHVybiBwaXhlbF9iaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBjb21wb25lbnRzIG9mIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1Db21wb25lbnRzKCkgeworICAgICAgICByZXR1cm4gbnVtQ29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgY29sb3IgY29tcG9uZW50cyBvZiB0aGlzIGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBjb2xvciBjb21wb25lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtQ29sb3JDb21wb25lbnRzKCkgeworICAgICAgICByZXR1cm4gbnVtQ29sb3JDb21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgUkdCIGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgUkdCIGNvbG9yIG1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JNb2RlbCBnZXRSR0JkZWZhdWx0KCkgeworICAgICAgICBpZiAoUkdCZGVmYXVsdCA9PSBudWxsKSB7CisgICAgICAgICAgICBSR0JkZWZhdWx0ID0gbmV3IERpcmVjdENvbG9yTW9kZWwoMzIsIDB4MDBmZjAwMDAsIDB4MDAwMGZmMDAsIDB4MDAwMDAwZmYsIDB4ZmYwMDAwMDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBSR0JkZWZhdWx0OworICAgIH0KKworICAgIC8qCisgICAgICogQ29uc3RydWN0IElOVCBwaXhlbCByZXByZXNlbnRhdGlvbiBmcm9tIE9iamVjdAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IHBpeGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmouCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNvbnN0cnVjdFBpeGVsKE9iamVjdCBvYmopIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKworICAgICAgICBzd2l0Y2ggKGdldFRyYW5zZmVyVHlwZSgpKSB7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJQaXhlbCA9IChieXRlW10pb2JqOworICAgICAgICAgICAgICAgIGlmIChiUGl4ZWwubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuMjc1PVRoaXMgcGl4ZWwgcmVwcmVzZW50YXRpb24gaXMgbm90IHN1dXBvcnRlZCBieSB0aXMKKyAgICAgICAgICAgICAgICAgICAgLy8gQ29sb3IgTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwaXhlbCA9IGJQaXhlbFswXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydFtdIHNQaXhlbCA9IChzaG9ydFtdKW9iajsKKyAgICAgICAgICAgICAgICBpZiAoc1BpeGVsLmxlbmd0aCA+IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjI3NT1UaGlzIHBpeGVsIHJlcHJlc2VudGF0aW9uIGlzIG5vdCBzdXVwb3J0ZWQgYnkgdGlzCisgICAgICAgICAgICAgICAgICAgIC8vIENvbG9yIE1vZGVsCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBzUGl4ZWxbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnRbXSBpUGl4ZWwgPSAoaW50W10pb2JqOworICAgICAgICAgICAgICAgIGlmIChpUGl4ZWwubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuMjc1PVRoaXMgcGl4ZWwgcmVwcmVzZW50YXRpb24gaXMgbm90IHN1dXBvcnRlZCBieSB0aXMKKyAgICAgICAgICAgICAgICAgICAgLy8gQ29sb3IgTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwaXhlbCA9IGlQaXhlbFswXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjJEPVRoaXMgdHJhbnNmZXJUeXBlICggezB9ICkgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzCisgICAgICAgICAgICAgICAgLy8gY29sb3IgbW9kZWwKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJEIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmZXJUeXBlKSk7CisKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGl4ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHJhbnNmZXIgdHlwZSwgd2hpY2ggaXMgdGhlIHR5cGUgb2YgSmF2YSBwcmltaXRpdmUgdmFsdWUgdGhhdAorICAgICAqIGNvcnJlc3BvbmRzIHRvIHRoZSBiaXQgbGVuZ3RoIHBlciBwaXhlbDogZWl0aGVyCisgICAgICoge0BsaW5rIERhdGFCdWZmZXIjVFlQRV9CWVRFfSwge0BsaW5rIERhdGFCdWZmZXIjVFlQRV9VU0hPUlR9LAorICAgICAqIHtAbGluayBEYXRhQnVmZmVyI1RZUEVfSU5UfSwgb3Ige0BsaW5rIERhdGFCdWZmZXIjVFlQRV9VTkRFRklORUR9LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY29tcG9uZW50IG1hc2tzLgorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZmVyIHR5cGUuCisgICAgICovCisgICAgc3RhdGljIGludCBnZXRUcmFuc2ZlclR5cGUoaW50IGJpdHMpIHsKKyAgICAgICAgaWYgKGJpdHMgPD0gOCkgeworICAgICAgICAgICAgcmV0dXJuIERhdGFCdWZmZXIuVFlQRV9CWVRFOworICAgICAgICB9IGVsc2UgaWYgKGJpdHMgPD0gMTYpIHsKKyAgICAgICAgICAgIHJldHVybiBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOworICAgICAgICB9IGVsc2UgaWYgKGJpdHMgPD0gMzIpIHsKKyAgICAgICAgICAgIHJldHVybiBEYXRhQnVmZmVyLlRZUEVfSU5UOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIERhdGFCdWZmZXIuVFlQRV9VTkRFRklORUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaW5hbGl6ZSgpIHsKKyAgICAgICAgLy8gVGhpcyBtZXRob2QgaXMgYWRkZWQgZm9yIHRoZSBBUEkgY29tcGF0aWJpbGl0eQorICAgICAgICAvLyBEb24ndCBuZWVkIHRvIGNhbGwgc3VwZXIgc2luY2UgT2JqZWN0J3MgZmluYWxpemUgaXMgYWx3YXlzIGVtcHR5CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0NvbXBvbmVudENvbG9yTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Db21wb25lbnRDb2xvck1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDMyOGZkMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Db21wb25lbnRDb2xvck1vZGVsLmphdmEKQEAgLTAsMCArMSwxNDgyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLkxVVENvbG9yQ29udmVydGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBDbGFzcyBDb21wb25lbnRDb2xvck1vZGVsIHJlcHJlc2VudHMgYSBjb2xvciBtb2RlbCB0aGF0IGlzIGRlZmluZWQgaW4KKyAqIHRlcm1zIG9mIGl0cyBjb21wb25lbnRzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIENvbXBvbmVudENvbG9yTW9kZWwgZXh0ZW5kcyBDb2xvck1vZGVsIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzaWduZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHNpZ25lZDsgLy8gUGl4ZWwgc2FtcGxlcyBhcmUgc2lnbmVkLgorCisgICAgLy8gU2FtcGxlcyB3aXRoIFRyYW5zZmVyVHlwZSBEYXRhQnVmZmVyLlRZUEVfQllURSwKKyAgICAvLyBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBEYXRhQnVmZmVyLlRZUEVfSU5UIC0KKyAgICAvLyB1bnNpZ25lZC4gU2FtcGxlcyB3aXRoIG90aGVycyBUcmFuc2ZlclR5cGUgLQorICAgIC8vIHNpZ25lZC4KKworICAgIC8qKgorICAgICAqIFRoZSBpbnRlZ3JhbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaW50ZWdyYWw7IC8vIFBpeGVsIHNhbXBsZXMgYXJlIGludGVncmFsLgorCisgICAgLy8gU2FtcGxlcyB3aXRoIFRyYW5zZmVyVHlwZSBEYXRhQnVmZmVyLlRZUEVfQllURSwKKyAgICAvLyBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBEYXRhQnVmZmVyLlNob3J0IGFuZAorICAgIC8vIERhdGFCdWZmZXIuVFlQRV9JTlQgLSBpbnRlZ3JhbC4KKworICAgIC8qKgorICAgICAqIFRoZSBzY2FsZSBmYWN0b3JzLgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgc2NhbGVGYWN0b3JzW107IC8vIEFycmF5IG9mIGZhY3RvcnMgZm9yIHJlZHVjdGlvbiBjb21wb25lbnRzCisKKyAgICAvLyB2YWx1ZXMgaW50byB0aGUgZm9ybSBzY2FsZWQgZnJvbSAwIHRvIDI1NQorCisgICAgLyoqCisgICAgICogVGhlIGRvbm90IHN1cHBvcnQgdW5ub3JtYWxpemVkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkb25vdFN1cHBvcnRVbm5vcm1hbGl6ZWQ7IC8vIFRoaXMgQ29sb3IgTW9kZWwgZG9uJ3Qgc3VwcG9ydAorCisgICAgLy8gdW5ub3Jtb2xpemVkIGZvcm0KKworICAgIC8qKgorICAgICAqIFRoZSBuZWVkIGFscGhhIGRpdmlkZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbmVlZEFscGhhRGl2aWRlOyAvLyBoYXNBbHBoYSAmJiBpc0FscGhhUHJlbXVsdGlwbGllZAorCisgICAgLyoqCisgICAgICogVGhlIGNhbGMgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNhbGNWYWx1ZTsgLy8gVmFsdWUgd2FzIGN1bGN1bGF0ZWQKKworICAgIC8qKgorICAgICAqIFRoZSBuZWVkIHNjYWxlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBuZWVkU2NhbGU7IC8vIE5vcm1hbGl6ZWQgdmFsdWUgbmVlZCB0byBzY2FsZQorCisgICAgLyoqCisgICAgICogVGhlIG1pbiB2YWxzLgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgbWluVmFsc1tdOyAvLyBBcnJheSBvZiBNaW4gbm9ybWFsaXplZCB2YWx1ZXMKKworICAgIC8qKgorICAgICAqIFRoZSByYW5nZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCByYW5nZXNbXTsgLy8gQXJyYXkgb2YgcmFuZ2Ugbm9ybWFsaXplZCB2YWx1ZXMKKworICAgIC8qKgorICAgICAqIFRoZSBhbHBoYSBsdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIGFscGhhTFVUW107IC8vIExvb2t1cCB0YWJsZSBmb3Igc2NhbGUgYWxwaGEgdmFsdWUKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBsdSB0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGUgY29sb3JMVVRzW11bXTsgLy8gTG9va3VwIHRhYmxlcyBmb3Igc2NhbGUgY29sb3IgdmFsdWVzCisKKyAgICAvKioKKyAgICAgKiBUaGUgZnJvbV8gbGluZWEgcl8gcmcgYl8gbHV0LgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZSBmcm9tX0xJTkVBUl9SR0JfTFVUW107IC8vIExvb2t1cCB0YWJsZSBmb3IgY29udmVyc2lvbiBmcm9tCisKKyAgICAvLyBMaW5lYXIgUkdCIENvbG9yIFNwYWNlIGludG8gc1JHQgorCisgICAgLyoqCisgICAgICogVGhlIHRvXyBsaW5lYSByXzggcmcgYl8gbHV0LgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZSB0b19MSU5FQVJfOFJHQl9MVVRbXTsgLy8gTG9va3VwIHRhYmxlIGZvciBjb252ZXJzaW9uIGZyb20KKworICAgIC8vIHNSR0IgQ29sb3IgU3BhY2UgaW50byBMaW5lYXIgUkdCCisgICAgLy8gOCBiaXQKKworICAgIC8qKgorICAgICAqIFRoZSB0b18gbGluZWEgcl8xNiByZyBiXyBsdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzaG9ydCB0b19MSU5FQVJfMTZSR0JfTFVUW107IC8vIExvb2t1cCB0YWJsZSBmb3IgY29udmVyc2lvbiBmcm9tCisKKyAgICAvLyBzUkdCIENvbG9yIFNwYWNlIGludG8gTGluZWFyIFJHQgorICAgIC8vIDE2IGJpdAorCisgICAgLyoqCisgICAgICogVGhlIExJTkVBIHJfIHJnIGJfIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBMSU5FQVJfUkdCX0xlbmd0aDsgLy8gTGluZWFyIFJHQiBiaXQgbGVuZ3RoCisKKyAgICAvKioKKyAgICAgKiBUaGUgZmFjdG9yLgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgZkZhY3RvcjsgLy8gU2NhbGUgZmFjdG9yCisKKyAgICAvKioKKyAgICAgKiBUaGUgaXNfcyByZ2IuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzX3NSR0I7IC8vIENvbG9yTW9kZWwgaGFzIHNSR0IgQ29sb3JTcGFjZQorCisgICAgLyoqCisgICAgICogVGhlIGlzXyBsaW5lYSByXyByZ2IuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzX0xJTkVBUl9SR0I7IC8vIENvbG9yIE1vZGVsIGhhcyBMaW5lYXIgUkdCIENvbG9yCisKKyAgICAvLyBTcGFjZQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGNvbXBvbmVudCBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3JTcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbG9yIHNwYWNlLgorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY29tcG9uZW50IG1hc2tzLgorICAgICAqIEBwYXJhbSBoYXNBbHBoYQorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgY29sb3IgbW9kZWwgaGFzIGFscGhhLgorICAgICAqIEBwYXJhbSBpc0FscGhhUHJlbXVsdGlwbGllZAorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgYWxwaGEgaXMgcHJlLW11bHRpcGxpZWQuCisgICAgICogQHBhcmFtIHRyYW5zcGFyZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zcGFyZW5jeSBzdHJhdGVneSwgQHNlZSBqYXZhLmF3dC5UcmFuc3BhcmVuY3kuCisgICAgICogQHBhcmFtIHRyYW5zZmVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zZmVyIHR5cGUgKHByaW1pdGl2ZSBqYXZhIHR5cGUgdG8gdXNlIGZvciB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbXBvbmVudHMpLgorICAgICAqLworICAgIHB1YmxpYyBDb21wb25lbnRDb2xvck1vZGVsKENvbG9yU3BhY2UgY29sb3JTcGFjZSwgaW50IGJpdHNbXSwgYm9vbGVhbiBoYXNBbHBoYSwKKyAgICAgICAgICAgIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQsIGludCB0cmFuc3BhcmVuY3ksIGludCB0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgc3VwZXIoY3JlYXRlUGl4ZWxCaXRzKGNvbG9yU3BhY2UsIGhhc0FscGhhLCB0cmFuc2ZlclR5cGUpLCB2YWxpZGF0ZUJpdHMoYml0cywgY29sb3JTcGFjZSwKKyAgICAgICAgICAgICAgICBoYXNBbHBoYSwgdHJhbnNmZXJUeXBlKSwgY29sb3JTcGFjZSwgaGFzQWxwaGEsIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCB0cmFuc3BhcmVuY3ksCisgICAgICAgICAgICAgICAgdHJhbnNmZXJUeXBlKTsKKworICAgICAgICBuZWVkU2NhbGUgPSBmYWxzZTsKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgc2lnbmVkID0gZmFsc2U7CisgICAgICAgICAgICAgICAgaW50ZWdyYWwgPSB0cnVlOworICAgICAgICAgICAgICAgIGRvbm90U3VwcG9ydFVubm9ybWFsaXplZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIHNjYWxlRmFjdG9ycyA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNjYWxlRmFjdG9yc1tpXSA9IDEuMGYgLyBtYXhWYWx1ZXNbaV07CisgICAgICAgICAgICAgICAgICAgIGlmIChjcy5nZXRNaW5WYWx1ZShpKSAhPSAwLjBmIHx8IGNzLmdldE1heFZhbHVlKGkpICE9IDEuMGYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRvbm90U3VwcG9ydFVubm9ybWFsaXplZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICAgICAgICAgIG1heFZhbHVlc1tudW1Db2xvckNvbXBvbmVudHNdID0gKDEgPDwgYml0c1tudW1Db2xvckNvbXBvbmVudHNdKSAtIDE7CisgICAgICAgICAgICAgICAgICAgIHNjYWxlRmFjdG9yc1tudW1Db2xvckNvbXBvbmVudHNdID0gMS4wZiAvIG1heFZhbHVlc1tudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOgorICAgICAgICAgICAgICAgIHNpZ25lZCA9IHRydWU7CisgICAgICAgICAgICAgICAgaW50ZWdyYWwgPSB0cnVlOworICAgICAgICAgICAgICAgIGRvbm90U3VwcG9ydFVubm9ybWFsaXplZCA9IHRydWU7CisgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JzID0gbmV3IGZsb2F0W251bUNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG1heFZhbHVlc1tpXSA9IFNob3J0Lk1BWF9WQUxVRTsKKyAgICAgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JzW2ldID0gMS4wZiAvIG1heFZhbHVlc1tpXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNzLmdldE1pblZhbHVlKGkpICE9IDAuMGYgfHwgY3MuZ2V0TWF4VmFsdWUoaSkgIT0gMS4wZikgeworICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFNjYWxlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobmVlZFNjYWxlKSB7CisgICAgICAgICAgICAgICAgICAgIG1pblZhbHMgPSBuZXcgZmxvYXRbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgcmFuZ2VzID0gbmV3IGZsb2F0W251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1pblZhbHNbaV0gPSBjcy5nZXRNaW5WYWx1ZShpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlc1tpXSA9IGNzLmdldE1heFZhbHVlKGkpIC0gbWluVmFsc1tpXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIHNpZ25lZCA9IHRydWU7CisgICAgICAgICAgICAgICAgaW50ZWdyYWwgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBkb25vdFN1cHBvcnRVbm5vcm1hbGl6ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjE1PXRyYW5zZmVyVHlwZSBpcyBub3Qgb25lIG9mIERhdGFCdWZmZXIuVFlQRV9CWVRFLAorICAgICAgICAgICAgICAgIC8vIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQsIERhdGFCdWZmZXIuVFlQRV9JTlQsCisgICAgICAgICAgICAgICAgLy8gRGF0YUJ1ZmZlci5UWVBFX1NIT1JULCBEYXRhQnVmZmVyLlRZUEVfRkxPQVQsIG9yCisgICAgICAgICAgICAgICAgLy8gRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjE1IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBuZWVkQWxwaGFEaXZpZGUgPSBoYXNBbHBoYSAmJiBpc0FscGhhUHJlbXVsdGlwbGllZDsKKyAgICAgICAgaW5pdExVVHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgY29tcG9uZW50IGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvclNwYWNlCisgICAgICogICAgICAgICAgICB0aGUgY29sb3Igc3BhY2UuCisgICAgICogQHBhcmFtIGhhc0FscGhhCisgICAgICogICAgICAgICAgICB3aGV0aGVyIHRoZSBjb2xvciBtb2RlbCBoYXMgYWxwaGEuCisgICAgICogQHBhcmFtIGlzQWxwaGFQcmVtdWx0aXBsaWVkCisgICAgICogICAgICAgICAgICB3aGV0aGVyIHRoZSBhbHBoYSBpcyBwcmUtbXVsdGlwbGllZC4KKyAgICAgKiBAcGFyYW0gdHJhbnNwYXJlbmN5CisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNwYXJlbmN5IHN0cmF0ZWd5LCBAc2VlIGphdmEuYXd0LlRyYW5zcGFyZW5jeS4KKyAgICAgKiBAcGFyYW0gdHJhbnNmZXJUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmZXIgdHlwZSAocHJpbWl0aXZlIGphdmEgdHlwZSB0byB1c2UgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgY29tcG9uZW50cykuCisgICAgICovCisgICAgcHVibGljIENvbXBvbmVudENvbG9yTW9kZWwoQ29sb3JTcGFjZSBjb2xvclNwYWNlLCBib29sZWFuIGhhc0FscGhhLAorICAgICAgICAgICAgYm9vbGVhbiBpc0FscGhhUHJlbXVsdGlwbGllZCwgaW50IHRyYW5zcGFyZW5jeSwgaW50IHRyYW5zZmVyVHlwZSkgeworCisgICAgICAgIHRoaXMoY29sb3JTcGFjZSwgY3JlYXRlUGl4ZWxCaXRzQXJyYXkoY29sb3JTcGFjZSwgaGFzQWxwaGEsIHRyYW5zZmVyVHlwZSksIGhhc0FscGhhLAorICAgICAgICAgICAgICAgIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCB0cmFuc3BhcmVuY3ksIHRyYW5zZmVyVHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmFsaWRhdGUgYml0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGJpdHMuCisgICAgICogQHBhcmFtIGNvbG9yU3BhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBzcGFjZS4KKyAgICAgKiBAcGFyYW0gaGFzQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBoYXMgYWxwaGEuCisgICAgICogQHBhcmFtIHRyYW5zZmVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zZmVyIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgaW50W10uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50W10gdmFsaWRhdGVCaXRzKGludCBiaXRzW10sIENvbG9yU3BhY2UgY29sb3JTcGFjZSwgYm9vbGVhbiBoYXNBbHBoYSwKKyAgICAgICAgICAgIGludCB0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgaWYgKGJpdHMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGJpdHM7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbnVtQ29tcG9uZW50cyA9IGNvbG9yU3BhY2UuZ2V0TnVtQ29tcG9uZW50cygpOworICAgICAgICBpZiAoaGFzQWxwaGEpIHsKKyAgICAgICAgICAgIG51bUNvbXBvbmVudHMrKzsKKyAgICAgICAgfQorICAgICAgICBiaXRzID0gbmV3IGludFtudW1Db21wb25lbnRzXTsKKworICAgICAgICBpbnQgY29tcG9uZW50TGVuZ3RoID0gRGF0YUJ1ZmZlci5nZXREYXRhVHlwZVNpemUodHJhbnNmZXJUeXBlKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgYml0c1tpXSA9IGNvbXBvbmVudExlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBiaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHBpeGVsIGJpdHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9yU3BhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBzcGFjZS4KKyAgICAgKiBAcGFyYW0gaGFzQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBoYXMgYWxwaGEuCisgICAgICogQHBhcmFtIHRyYW5zZmVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zZmVyIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBjcmVhdGVQaXhlbEJpdHMoQ29sb3JTcGFjZSBjb2xvclNwYWNlLCBib29sZWFuIGhhc0FscGhhLCBpbnQgdHJhbnNmZXJUeXBlKSB7CisgICAgICAgIGludCBudW1Db21wb25lbnRzID0gY29sb3JTcGFjZS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIGlmIChoYXNBbHBoYSkgeworICAgICAgICAgICAgbnVtQ29tcG9uZW50cysrOworICAgICAgICB9CisgICAgICAgIGludCBjb21wb25lbnRMZW5ndGggPSBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZSh0cmFuc2ZlclR5cGUpOworICAgICAgICByZXR1cm4gbnVtQ29tcG9uZW50cyAqIGNvbXBvbmVudExlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBwaXhlbCBiaXRzIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvclNwYWNlCisgICAgICogICAgICAgICAgICB0aGUgY29sb3Igc3BhY2UuCisgICAgICogQHBhcmFtIGhhc0FscGhhCisgICAgICogICAgICAgICAgICB0aGUgaGFzIGFscGhhLgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2ZlciB0eXBlLgorICAgICAqIEByZXR1cm4gdGhlIGludFtdLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludFtdIGNyZWF0ZVBpeGVsQml0c0FycmF5KENvbG9yU3BhY2UgY29sb3JTcGFjZSwgYm9vbGVhbiBoYXNBbHBoYSwKKyAgICAgICAgICAgIGludCB0cmFuc2ZlclR5cGUpIHsKKworICAgICAgICBpbnQgbnVtQ29tcG9uZW50cyA9IGNvbG9yU3BhY2UuZ2V0TnVtQ29tcG9uZW50cygpOworICAgICAgICBpZiAoaGFzQWxwaGEpIHsKKyAgICAgICAgICAgIG51bUNvbXBvbmVudHMrKzsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiaXRzW10gPSBuZXcgaW50W251bUNvbXBvbmVudHNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgYml0c1tpXSA9IERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKHRyYW5zZmVyVHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJpdHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXREYXRhRWxlbWVudHMoaW50IGNvbXBvbmVudHNbXSwgaW50IG9mZnNldCwgT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoZG9ub3RTdXBwb3J0VW5ub3JtYWxpemVkKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEzPVRoaXMgQ29tcG9uZW50Q29sb3JNb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAgICAgICAgLy8gdW5ub3JtYWxpemVkIGZvcm0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAob2Zmc2V0ICsgbnVtQ29tcG9uZW50cyA+IGNvbXBvbmVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICAvLyBhd3QuMjE2PVRoZSBjb21wb25lbnRzIGFycmF5IGlzIG5vdCBsYXJnZSBlbm91Z2ggdG8gaG9sZCBhbGwgdGhlCisgICAgICAgICAgICAvLyBjb2xvciBhbmQgYWxwaGEgY29tcG9uZW50cworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYmEgPSBuZXcgYnl0ZVtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBiYSA9IChieXRlW10pb2JqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gb2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBiYVtpXSA9IChieXRlKWNvbXBvbmVudHNbaWR4XTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGJhOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNhID0gbmV3IHNob3J0W251bUNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNhID0gKHNob3J0W10pb2JqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gb2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBzYVtpXSA9IChzaG9ydCljb21wb25lbnRzW2lkeF07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBzYTsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWEgPSBuZXcgaW50W251bUNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlhID0gKGludFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IG9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWFbaV0gPSBjb21wb25lbnRzW2lkeF07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpYTsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxNz1UaGUgdHJhbnNmZXIgdHlwZSBvZiB0aGlzIENvbXBvbmVudENvbG9yTW9kZWwgaXMgbm90CisgICAgICAgICAgICAgICAgLy8gb25lCisgICAgICAgICAgICAgICAgLy8gb2YgdGhlIGZvbGxvd2luZyB0cmFuc2ZlciB0eXBlczogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsCisgICAgICAgICAgICAgICAgLy8gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCwgb3IgRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTciKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGZsb2F0IG5vcm1Db21wb25lbnRzW10sIGludCBub3JtT2Zmc2V0LCBPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChuZWVkU2NhbGUpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbaWR4XSA9IChub3JtQ29tcG9uZW50c1tpZHhdIC0gbWluVmFsc1tpXSkgLyByYW5nZXNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJhID0gbmV3IGJ5dGVbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmEgPSAoYnl0ZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAobmVlZEFscGhhRGl2aWRlKSB7CisgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gbm9ybUNvbXBvbmVudHNbbm9ybU9mZnNldCArIG51bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBiYVtpXSA9IChieXRlKShub3JtQ29tcG9uZW50c1tpZHhdICogYWxwaGEgKiBtYXhWYWx1ZXNbaV0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBiYVtudW1Db2xvckNvbXBvbmVudHNdID0gKGJ5dGUpKG5vcm1Db21wb25lbnRzW25vcm1PZmZzZXQgKyBudW1Db2xvckNvbXBvbmVudHNdCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXSArIDAuNWYpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgYmFbaWR4XSA9IChieXRlKShub3JtQ29tcG9uZW50c1tpZHhdICogbWF4VmFsdWVzW2ldICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGJhOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgdXNhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHVzYSA9IG5ldyBzaG9ydFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB1c2EgPSAoc2hvcnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKG5lZWRBbHBoYURpdmlkZSkgeworICAgICAgICAgICAgICAgICAgICBmbG9hdCBhbHBoYSA9IG5vcm1Db21wb25lbnRzW25vcm1PZmZzZXQgKyBudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgdXNhW2ldID0gKHNob3J0KShub3JtQ29tcG9uZW50c1tpZHhdICogYWxwaGEgKiBtYXhWYWx1ZXNbaV0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB1c2FbbnVtQ29sb3JDb21wb25lbnRzXSA9IChzaG9ydCkoYWxwaGEgKiBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXSArIDAuNWYpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgdXNhW2ldID0gKHNob3J0KShub3JtQ29tcG9uZW50c1tpZHhdICogbWF4VmFsdWVzW2ldICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHVzYTsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGludCBpYVtdOworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpYSA9IG5ldyBpbnRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWEgPSAoaW50W10pb2JqOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChuZWVkQWxwaGFEaXZpZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlhW2ldID0gKGludCkobm9ybUNvbXBvbmVudHNbaWR4XSAqIGFscGhhICogbWF4VmFsdWVzW2ldICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWFbbnVtQ29sb3JDb21wb25lbnRzXSA9IChpbnQpKGFscGhhICogbWF4VmFsdWVzW251bUNvbG9yQ29tcG9uZW50c10gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gbm9ybU9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlhW2ldID0gKGludCkobm9ybUNvbXBvbmVudHNbaWR4XSAqIG1heFZhbHVlc1tpXSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpYTsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc2EgPSBuZXcgc2hvcnRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2EgPSAoc2hvcnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKG5lZWRBbHBoYURpdmlkZSkgeworICAgICAgICAgICAgICAgICAgICBmbG9hdCBhbHBoYSA9IG5vcm1Db21wb25lbnRzW25vcm1PZmZzZXQgKyBudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2FbaV0gPSAoc2hvcnQpKG5vcm1Db21wb25lbnRzW2lkeF0gKiBhbHBoYSAqIG1heFZhbHVlc1tpXSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNhW251bUNvbG9yQ29tcG9uZW50c10gPSAoc2hvcnQpKGFscGhhICogbWF4VmFsdWVzW251bUNvbG9yQ29tcG9uZW50c10gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gbm9ybU9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhW2ldID0gKHNob3J0KShub3JtQ29tcG9uZW50c1tpZHhdICogbWF4VmFsdWVzW2ldICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHNhOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDoKKyAgICAgICAgICAgICAgICBmbG9hdCBmYVtdOworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmYSA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmYSA9IChmbG9hdFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAobmVlZEFscGhhRGl2aWRlKSB7CisgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gbm9ybUNvbXBvbmVudHNbbm9ybU9mZnNldCArIG51bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYVtpXSA9IG5vcm1Db21wb25lbnRzW2lkeF0gKiBhbHBoYTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmYVtudW1Db2xvckNvbXBvbmVudHNdID0gYWxwaGE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IG5vcm1PZmZzZXQ7IGkgPCBudW1Db21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYVtpXSA9IG5vcm1Db21wb25lbnRzW2lkeF07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgZG91YmxlIGRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGRhID0gbmV3IGRvdWJsZVtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBkYSA9IChkb3VibGVbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKG5lZWRBbHBoYURpdmlkZSkgeworICAgICAgICAgICAgICAgICAgICBkb3VibGUgYWxwaGEgPSBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhW2ldID0gbm9ybUNvbXBvbmVudHNbaWR4XSAqIGFscGhhOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGRhW251bUNvbG9yQ29tcG9uZW50c10gPSBhbHBoYTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gbm9ybU9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhW2ldID0gbm9ybUNvbXBvbmVudHNbaWR4XTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZGE7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxMz1UaGlzIENvbXBvbmVudENvbG9yTW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUKKyAgICAgICAgICAgICAgICAvLyB1bm5vcm1hbGl6ZWQgZm9ybQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldERhdGFFbGVtZW50cyhpbnQgcmdiLCBPYmplY3QgcGl4ZWwpIHsKKyAgICAgICAgZmxvYXQgbm9ybUNvbXBbXTsKKyAgICAgICAgZmxvYXQgY29tcFtdOworCisgICAgICAgIGludCByZWQgPSAocmdiID4+IDE2KSAmIDB4ZmY7CisgICAgICAgIGludCBncmVlbiA9IChyZ2IgPj4gOCkgJiAweGZmOworICAgICAgICBpbnQgYmx1ZSA9IHJnYiAmIDB4ZmY7CisgICAgICAgIGludCBhbHBoYSA9IChyZ2IgPj4gMjQpICYgMHhmZjsKKworICAgICAgICBjb21wID0gbmV3IGZsb2F0WzNdOworICAgICAgICBpZiAoaXNfc1JHQiB8fCBpc19MSU5FQVJfUkdCKSB7CisgICAgICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgICAgIGlmIChMSU5FQVJfUkdCX0xlbmd0aCA9PSA4KSB7CisgICAgICAgICAgICAgICAgICAgIHJlZCA9IHRvX0xJTkVBUl84UkdCX0xVVFtyZWRdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgZ3JlZW4gPSB0b19MSU5FQVJfOFJHQl9MVVRbZ3JlZW5dICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgYmx1ZSA9IHRvX0xJTkVBUl84UkdCX0xVVFtibHVlXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVkID0gdG9fTElORUFSXzE2UkdCX0xVVFtyZWRdICYgMHhmZmZmOworICAgICAgICAgICAgICAgICAgICBncmVlbiA9IHRvX0xJTkVBUl8xNlJHQl9MVVRbZ3JlZW5dICYgMHhmZmZmOworICAgICAgICAgICAgICAgICAgICBibHVlID0gdG9fTElORUFSXzE2UkdCX0xVVFtibHVlXSAmIDB4ZmZmZjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb21wWzBdID0gcmVkIC8gZkZhY3RvcjsKKyAgICAgICAgICAgIGNvbXBbMV0gPSBncmVlbiAvIGZGYWN0b3I7CisgICAgICAgICAgICBjb21wWzJdID0gYmx1ZSAvIGZGYWN0b3I7CisgICAgICAgICAgICBpZiAoIWhhc0FscGhhKSB7CisgICAgICAgICAgICAgICAgbm9ybUNvbXAgPSBjb21wOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmbG9hdCBub3JtQWxwaGEgPSBhbHBoYSAvIDI1NS4wZjsKKyAgICAgICAgICAgICAgICBub3JtQ29tcCA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG5vcm1Db21wW2ldID0gY29tcFtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbm9ybUNvbXBbbnVtQ29sb3JDb21wb25lbnRzXSA9IG5vcm1BbHBoYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbXBbMF0gPSByZWQgLyBmRmFjdG9yOworICAgICAgICAgICAgY29tcFsxXSA9IGdyZWVuIC8gZkZhY3RvcjsKKyAgICAgICAgICAgIGNvbXBbMl0gPSBibHVlIC8gZkZhY3RvcjsKKyAgICAgICAgICAgIGZsb2F0W10gZGVmQ29tcCA9IGNzLmZyb21SR0IoY29tcCk7CisgICAgICAgICAgICBpZiAoIWhhc0FscGhhKSB7CisgICAgICAgICAgICAgICAgbm9ybUNvbXAgPSBkZWZDb21wOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmbG9hdCBub3JtQWxwaGEgPSBhbHBoYSAvIDI1NS4wZjsKKyAgICAgICAgICAgICAgICBub3JtQ29tcCA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG5vcm1Db21wW2ldID0gZGVmQ29tcFtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbm9ybUNvbXBbbnVtQ29sb3JDb21wb25lbnRzXSA9IG5vcm1BbHBoYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaGFzQWxwaGEgJiYgaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgICAgIG5vcm1Db21wWzBdICo9IG5vcm1Db21wW251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICBub3JtQ29tcFsxXSAqPSBub3JtQ29tcFtudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgbm9ybUNvbXBbMl0gKj0gbm9ybUNvbXBbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBnZXREYXRhRWxlbWVudHMobm9ybUNvbXAsIDAsIHBpeGVsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgZ2V0QWxwaGFSYXN0ZXIoV3JpdGFibGVSYXN0ZXIgcmFzdGVyKSB7CisgICAgICAgIGlmICghaGFzQWxwaGEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaW50IHggPSByYXN0ZXIuZ2V0TWluWCgpOworICAgICAgICBpbnQgeSA9IHJhc3Rlci5nZXRNaW5ZKCk7CisgICAgICAgIGludCBiYW5kTGlzdFtdID0gbmV3IGludFsxXTsKKyAgICAgICAgYmFuZExpc3RbMF0gPSByYXN0ZXIuZ2V0TnVtQmFuZHMoKSAtIDE7CisKKyAgICAgICAgcmV0dXJuIHJhc3Rlci5jcmVhdGVXcml0YWJsZUNoaWxkKHgsIHksIHJhc3Rlci5nZXRXaWR0aCgpLCByYXN0ZXIuZ2V0SGVpZ2h0KCksIHgsIHksCisgICAgICAgICAgICAgICAgYmFuZExpc3QpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb2xvck1vZGVsIGNvZXJjZURhdGEoV3JpdGFibGVSYXN0ZXIgcmFzdGVyLCBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgIGlmICghaGFzQWxwaGEgfHwgdGhpcy5pc0FscGhhUHJlbXVsdGlwbGllZCA9PSBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbWluWCA9IHJhc3Rlci5nZXRNaW5YKCk7CisgICAgICAgIGludCBtaW5ZID0gcmFzdGVyLmdldE1pblkoKTsKKyAgICAgICAgaW50IHcgPSByYXN0ZXIuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGggPSByYXN0ZXIuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgaWYgKGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGFGYWN0b3IgPSBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGlDb21wb25lbnRzW10gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpbnQgaVRyYW5zcGFyZW50Q29tcG9uZW50c1tdID0gbmV3IGludFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyssIG1pblkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDAsIHggPSBtaW5YOyBqIDwgdzsgaisrLCB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpQ29tcG9uZW50cyA9IHJhc3Rlci5nZXRQaXhlbCh4LCBtaW5ZLCBpQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlDb21wb25lbnRzW251bUNvbG9yQ29tcG9uZW50c10gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgaVRyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBpQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdIC8gYWxwaGFGYWN0b3I7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQ29sb3JDb21wb25lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlDb21wb25lbnRzW25dID0gKGludCkoYWxwaGEgKiBpQ29tcG9uZW50c1tuXSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBpQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgc0FscGhhRmFjdG9yID0gbWF4VmFsdWVzW251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIHNob3J0IHNDb21wb25lbnRzW10gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBzaG9ydCBzVHJhbnNwYXJlbnRDb21wb25lbnRzW10gPSBuZXcgc2hvcnRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrLCBtaW5ZKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwLCB4ID0gbWluWDsgaiA8IHc7IGorKywgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc0NvbXBvbmVudHMgPSAoc2hvcnRbXSlyYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKHgsIG1pblksIHNDb21wb25lbnRzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc0NvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMoeCwgbWluWSwgc1RyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBzQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdIC8gc0FscGhhRmFjdG9yOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IG51bUNvbG9yQ29tcG9uZW50czsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzQ29tcG9uZW50c1tuXSA9IChieXRlKShhbHBoYSAqIHNDb21wb25lbnRzW25dICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFzdGVyLnNldERhdGFFbGVtZW50cyh4LCBtaW5ZLCBzQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgZkNvbXBvbmVudHNbXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGZsb2F0IGZUcmFuc3BhcmVudENvbXBvbmVudHNbXSA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyssIG1pblkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDAsIHggPSBtaW5YOyBqIDwgdzsgaisrLCB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29tcG9uZW50cyA9IHJhc3Rlci5nZXRQaXhlbCh4LCBtaW5ZLCBmQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDb21wb25lbnRzW251bUNvbG9yQ29tcG9uZW50c10gPT0gMC4wZikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0RGF0YUVsZW1lbnRzKHgsIG1pblksIGZUcmFuc3BhcmVudENvbXBvbmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gZkNvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1Db2xvckNvbXBvbmVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbXBvbmVudHNbbl0gPSBmQ29tcG9uZW50c1tuXSAqIGFscGhhOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBmQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBkQ29tcG9uZW50c1tdID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGRUcmFuc3BhcmVudENvbXBvbmVudHNbXSA9IG5ldyBkb3VibGVbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrLCBtaW5ZKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwLCB4ID0gbWluWDsgaiA8IHc7IGorKywgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZENvbXBvbmVudHMgPSByYXN0ZXIuZ2V0UGl4ZWwoeCwgbWluWSwgZENvbXBvbmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdID09IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgZFRyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGFscGhhID0gZENvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1Db2xvckNvbXBvbmVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZENvbXBvbmVudHNbbl0gPSBkQ29tcG9uZW50c1tuXSAqIGFscGhhOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBkQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAvLyBhd3QuMjE5PVRoaXMgdHJhbnNmZXJUeXBlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBjb2xvcgorICAgICAgICAgICAgICAgICAgICAvLyBtb2RlbAorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjE5IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGFGYWN0b3IgPSBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGlDb21wb25lbnRzW10gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpbnQgaVRyYW5zcGFyZW50Q29tcG9uZW50c1tdID0gbmV3IGludFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyssIG1pblkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDAsIHggPSBtaW5YOyBqIDwgdzsgaisrLCB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpQ29tcG9uZW50cyA9IHJhc3Rlci5nZXRQaXhlbCh4LCBtaW5ZLCBpQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlDb21wb25lbnRzW251bUNvbG9yQ29tcG9uZW50c10gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgaVRyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBpQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdIC8gYWxwaGFGYWN0b3I7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQ29sb3JDb21wb25lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlDb21wb25lbnRzW25dID0gKGludCkoaUNvbXBvbmVudHNbbl0gLyBhbHBoYSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBpQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgc0FscGhhRmFjdG9yID0gbWF4VmFsdWVzW251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIHNob3J0IHNDb21wb25lbnRzW10gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBzaG9ydCBzVHJhbnNwYXJlbnRDb21wb25lbnRzW10gPSBuZXcgc2hvcnRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrLCBtaW5ZKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwLCB4ID0gbWluWDsgaiA8IHc7IGorKywgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc0NvbXBvbmVudHMgPSAoc2hvcnRbXSlyYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKHgsIG1pblksIHNDb21wb25lbnRzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc0NvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMoeCwgbWluWSwgc1RyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBzQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdIC8gc0FscGhhRmFjdG9yOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IG51bUNvbG9yQ29tcG9uZW50czsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzQ29tcG9uZW50c1tuXSA9IChieXRlKShzQ29tcG9uZW50c1tuXSAvIGFscGhhICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFzdGVyLnNldERhdGFFbGVtZW50cyh4LCBtaW5ZLCBzQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDoKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgZkNvbXBvbmVudHNbXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGZsb2F0IGZUcmFuc3BhcmVudENvbXBvbmVudHNbXSA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyssIG1pblkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDAsIHggPSBtaW5YOyBqIDwgdzsgaisrLCB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29tcG9uZW50cyA9IHJhc3Rlci5nZXRQaXhlbCh4LCBtaW5ZLCBmQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDb21wb25lbnRzW251bUNvbG9yQ29tcG9uZW50c10gPT0gMC4wZikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0RGF0YUVsZW1lbnRzKHgsIG1pblksIGZUcmFuc3BhcmVudENvbXBvbmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gZkNvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1Db2xvckNvbXBvbmVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbXBvbmVudHNbbl0gPSBmQ29tcG9uZW50c1tuXSAvIGFscGhhOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBmQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBkQ29tcG9uZW50c1tdID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGRUcmFuc3BhcmVudENvbXBvbmVudHNbXSA9IG5ldyBkb3VibGVbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrLCBtaW5ZKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwLCB4ID0gbWluWDsgaiA8IHc7IGorKywgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZENvbXBvbmVudHMgPSByYXN0ZXIuZ2V0UGl4ZWwoeCwgbWluWSwgZENvbXBvbmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkQ29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdID09IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgZFRyYW5zcGFyZW50Q29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGFscGhhID0gZENvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1Db2xvckNvbXBvbmVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZENvbXBvbmVudHNbbl0gPSBkQ29tcG9uZW50c1tuXSAvIGFscGhhOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCBkQ29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjIxOT1UaGlzIHRyYW5zZmVyVHlwZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgY29sb3IKKyAgICAgICAgICAgICAgICAgICAgLy8gbW9kZWwKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxOSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzaWduZWQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcG9uZW50Q29sb3JNb2RlbChjcywgYml0cywgaGFzQWxwaGEsIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCB0cmFuc3BhcmVuY3ksCisgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyVHlwZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IENvbXBvbmVudENvbG9yTW9kZWwoY3MsIG51bGwsIGhhc0FscGhhLCBpc0FscGhhUHJlbXVsdGlwbGllZCwgdHJhbnNwYXJlbmN5LAorICAgICAgICAgICAgICAgIHRyYW5zZmVyVHlwZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldENvbXBvbmVudHMoT2JqZWN0IHBpeGVsLCBpbnRbXSBjb21wb25lbnRzLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIGlmIChkb25vdFN1cHBvcnRVbm5vcm1hbGl6ZWQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMTM9VGhpcyBDb21wb25lbnRDb2xvck1vZGVsIGRvZXMgbm90IHN1cHBvcnQgdGhlCisgICAgICAgICAgICAvLyB1bm5vcm1hbGl6ZWQgZm9ybQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgaW50W29mZnNldCArIG51bUNvbXBvbmVudHNdOworICAgICAgICB9IGVsc2UgaWYgKG9mZnNldCArIG51bUNvbXBvbmVudHMgPiBjb21wb25lbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgLy8gYXd0LjIxOD1UaGUgY29tcG9uZW50cyBhcnJheSBpcyBub3QgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgYWxsIHRoZQorICAgICAgICAgICAgLy8gY29sb3IgYW5kIGFscGhhIGNvbXBvbmVudHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjE4IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW10gPSAoYnl0ZVtdKXBpeGVsOworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IG9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50c1tpZHhdID0gYmFbaV0gJiAweGZmOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcG9uZW50czsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW10gPSAoc2hvcnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gb2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzW2lkeF0gPSBzYVtpXSAmIDB4ZmZmZjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudHM7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gb2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzW2lkeF0gPSBpYVtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudHM7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxNz1UaGUgdHJhbnNmZXIgdHlwZSBvZiB0aGlzIENvbXBvbmVudENvbG9yTW9kZWwgaXMgbm90CisgICAgICAgICAgICAgICAgLy8gb25lCisgICAgICAgICAgICAgICAgLy8gb2YgdGhlIGZvbGxvd2luZyB0cmFuc2ZlciB0eXBlczogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsCisgICAgICAgICAgICAgICAgLy8gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCwgb3IgRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTciKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0W10gZ2V0Tm9ybWFsaXplZENvbXBvbmVudHMoT2JqZWN0IHBpeGVsLCBmbG9hdCBub3JtQ29tcG9uZW50c1tdLCBpbnQgbm9ybU9mZnNldCkgeworCisgICAgICAgIGlmIChub3JtQ29tcG9uZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICBub3JtQ29tcG9uZW50cyA9IG5ldyBmbG9hdFtudW1Db21wb25lbnRzICsgbm9ybU9mZnNldF07CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW10gPSAoYnl0ZVtdKXBpeGVsOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcG9uZW50c1tpZHhdID0gKGJhW2ldICYgMHhmZikgKiBzY2FsZUZhY3RvcnNbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgdXNhW10gPSAoc2hvcnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gbm9ybU9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbaWR4XSA9ICh1c2FbaV0gJiAweGZmZmYpICogc2NhbGVGYWN0b3JzW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGludCBpYVtdID0gKGludFtdKXBpeGVsOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcG9uZW50c1tpZHhdID0gaWFbaV0gKiBzY2FsZUZhY3RvcnNbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10pcGl4ZWw7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGlkeCA9IG5vcm1PZmZzZXQ7IGkgPCBudW1Db21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIG5vcm1Db21wb25lbnRzW2lkeF0gPSBzYVtpXSAqIHNjYWxlRmFjdG9yc1tpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGZsb2F0IGZhW10gPSAoZmxvYXRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgaWR4ID0gbm9ybU9mZnNldDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbaWR4XSA9IGZhW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIGRvdWJsZSBkYVtdID0gKGRvdWJsZVtdKXBpeGVsOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29tcG9uZW50czsgaSsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcG9uZW50c1tpZHhdID0gKGZsb2F0KWRhW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjFBPVRoaXMgQ29tcG9uZW50Q29sb3JNb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoaXMKKyAgICAgICAgICAgICAgICAvLyB0cmFuc2ZlclR5cGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxQSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG5lZWRBbHBoYURpdmlkZSkgeworICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBub3JtQ29tcG9uZW50c1tub3JtT2Zmc2V0ICsgbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbaWR4XSAvPSBhbHBoYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZWVkU2NhbGUpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBpZHggPSBub3JtT2Zmc2V0OyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgbm9ybUNvbXBvbmVudHNbaWR4XSA9IG1pblZhbHNbaV0gKyByYW5nZXNbaV0gKiBub3JtQ29tcG9uZW50c1tpZHhdOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBub3JtQ29tcG9uZW50czsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBDb21wb25lbnRDb2xvck1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJlZChPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIHJldHVybiBnZXRSR0JDb21wb25lbnQoaW5EYXRhLCAwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJHQihPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIGludCBhbHBoYSA9IGdldEFscGhhKGluRGF0YSk7CisgICAgICAgIGlmIChjcy5nZXRUeXBlKCkgPT0gQ29sb3JTcGFjZS5UWVBFX0dSQVkpIHsKKyAgICAgICAgICAgIGludCBncmF5ID0gZ2V0UmVkKGluRGF0YSk7CisgICAgICAgICAgICByZXR1cm4gKGFscGhhIDw8IDI0IHwgZ3JheSA8PCAxNiB8IGdyYXkgPDwgOCB8IGdyYXkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoYWxwaGEgPDwgMjQgfCBnZXRSZWQoaW5EYXRhKSA8PCAxNiB8IGdldEdyZWVuKGluRGF0YSkgPDwgOCB8IGdldEJsdWUoaW5EYXRhKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRHcmVlbihPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIHJldHVybiBnZXRSR0JDb21wb25lbnQoaW5EYXRhLCAxKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEJsdWUoT2JqZWN0IGluRGF0YSkgeworICAgICAgICByZXR1cm4gZ2V0UkdCQ29tcG9uZW50KGluRGF0YSwgMik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRBbHBoYShPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIGlmICghaGFzQWxwaGEpIHsKKyAgICAgICAgICAgIHJldHVybiAyNTU7CisgICAgICAgIH0KKyAgICAgICAgaW50IGFscGhhID0gMDsKKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURTogeworICAgICAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10paW5EYXRhOworICAgICAgICAgICAgICAgIGFscGhhID0gYmFbbnVtQ29sb3JDb21wb25lbnRzXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgaWYgKGJpdHNbbnVtQ29sb3JDb21wb25lbnRzXSAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbHBoYUxVVFthbHBoYV0gJiAweGZmOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYWxwaGE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6IHsKKyAgICAgICAgICAgICAgICBzaG9ydCB1c2FbXSA9IChzaG9ydFtdKWluRGF0YTsKKyAgICAgICAgICAgICAgICBhbHBoYSA9IHVzYVtudW1Db2xvckNvbXBvbmVudHNdICYgMHhmZmZmOworICAgICAgICAgICAgICAgIGlmIChiaXRzW251bUNvbG9yQ29tcG9uZW50c10gIT0gOCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxwaGFMVVRbYWxwaGFdICYgMHhmZjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGFscGhhOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOiB7CisgICAgICAgICAgICAgICAgaW50IGlhW10gPSAoaW50W10paW5EYXRhOworICAgICAgICAgICAgICAgIGFscGhhID0gaWFbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICBpZiAoYml0c1tudW1Db2xvckNvbXBvbmVudHNdICE9IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFscGhhTFVUW2FscGhhXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBhbHBoYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOiB7CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXSA9IChzaG9ydFtdKWluRGF0YTsKKyAgICAgICAgICAgICAgICBhbHBoYSA9IHNhW251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgaWYgKGJpdHNbbnVtQ29sb3JDb21wb25lbnRzXSAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbHBoYUxVVFthbHBoYV0gJiAweGZmOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYWxwaGE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9GTE9BVDogeworICAgICAgICAgICAgICAgIGZsb2F0IGZhW10gPSAoZmxvYXRbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcmV0dXJuIChpbnQpKGZhW251bUNvbG9yQ29tcG9uZW50c10gKiAyNTUuMGYgKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRTogeworICAgICAgICAgICAgICAgIGRvdWJsZSBkYVtdID0gKGRvdWJsZVtdKWluRGF0YTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGludCkoZGFbbnVtQ29sb3JDb21wb25lbnRzXSAqIDI1NS4wICsgMC41KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMgdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcihpbnQgdywgaW50IGgpIHsKKyAgICAgICAgU2FtcGxlTW9kZWwgc20gPSBjcmVhdGVDb21wYXRpYmxlU2FtcGxlTW9kZWwodywgaCk7CisgICAgICAgIERhdGFCdWZmZXIgZGIgPSBzbS5jcmVhdGVEYXRhQnVmZmVyKCk7CisgICAgICAgIHJldHVybiBSYXN0ZXIuY3JlYXRlV3JpdGFibGVSYXN0ZXIoc20sIGRiLCBudWxsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBhdGlibGVTYW1wbGVNb2RlbChTYW1wbGVNb2RlbCBzbSkgeworICAgICAgICBpZiAoIShzbSBpbnN0YW5jZW9mIENvbXBvbmVudFNhbXBsZU1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChudW1Db21wb25lbnRzICE9IHNtLmdldE51bUJhbmRzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHJhbnNmZXJUeXBlICE9IHNtLmdldFRyYW5zZmVyVHlwZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbChpbnQgdywgaW50IGgpIHsKKyAgICAgICAgaW50IGJhbmRPZmZzZXRzW10gPSBuZXcgaW50W251bUNvbXBvbmVudHNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgYmFuZE9mZnNldHNbaV0gPSBpOworICAgICAgICB9CisKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwodHJhbnNmZXJUeXBlLCB3LCBoLCBudW1Db21wb25lbnRzLCB3CisgICAgICAgICAgICAgICAgICAgICAgICAqIG51bUNvbXBvbmVudHMsIGJhbmRPZmZzZXRzKTsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvbmVudFNhbXBsZU1vZGVsKHRyYW5zZmVyVHlwZSwgdywgaCwgbnVtQ29tcG9uZW50cywgdworICAgICAgICAgICAgICAgICAgICAgICAgKiBudW1Db21wb25lbnRzLCBiYW5kT2Zmc2V0cyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBhdGlibGVSYXN0ZXIoUmFzdGVyIHJhc3RlcikgeworICAgICAgICBTYW1wbGVNb2RlbCBzbSA9IHJhc3Rlci5nZXRTYW1wbGVNb2RlbCgpOworICAgICAgICBpZiAoIShzbSBpbnN0YW5jZW9mIENvbXBvbmVudFNhbXBsZU1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNtLmdldE51bUJhbmRzKCkgIT0gbnVtQ29tcG9uZW50cykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChyYXN0ZXIuZ2V0VHJhbnNmZXJUeXBlKCkgIT0gdHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgc2FtcGxlU2l6ZXNbXSA9IHNtLmdldFNhbXBsZVNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChiaXRzW2ldICE9IHNhbXBsZVNpemVzW2ldKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIGdldE5vcm1hbGl6ZWRDb21wb25lbnRzKGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQsIGZsb2F0IG5vcm1Db21wb25lbnRzW10sCisgICAgICAgICAgICBpbnQgbm9ybU9mZnNldCkgeworICAgICAgICBpZiAoZG9ub3RTdXBwb3J0VW5ub3JtYWxpemVkKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEzPVRoaXMgQ29tcG9uZW50Q29sb3JNb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAgICAgICAgLy8gdW5ub3JtYWxpemVkIGZvcm0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Tm9ybWFsaXplZENvbXBvbmVudHMoY29tcG9uZW50cywgb2Zmc2V0LCBub3JtQ29tcG9uZW50cywgbm9ybU9mZnNldCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXREYXRhRWxlbWVudChpbnRbXSBjb21wb25lbnRzLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIGlmIChudW1Db21wb25lbnRzID4gMSkgeworICAgICAgICAgICAgLy8gYXd0LjIxMj1UaGVyZSBpcyBtb3JlIHRoYW4gb25lIGNvbXBvbmVudCBpbiB0aGlzIENvbG9yTW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKGRvbm90U3VwcG9ydFVubm9ybWFsaXplZCkgeworICAgICAgICAgICAgLy8gYXd0LjIxMz1UaGlzIENvbXBvbmVudENvbG9yTW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUKKyAgICAgICAgICAgIC8vIHVubm9ybWFsaXplZCBmb3JtCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxMyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBjb21wb25lbnRzW29mZnNldF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldFVubm9ybWFsaXplZENvbXBvbmVudHMoZmxvYXRbXSBub3JtQ29tcG9uZW50cywgaW50IG5vcm1PZmZzZXQsCisgICAgICAgICAgICBpbnRbXSBjb21wb25lbnRzLCBpbnQgb2Zmc2V0KSB7CisKKyAgICAgICAgaWYgKGRvbm90U3VwcG9ydFVubm9ybWFsaXplZCkgeworICAgICAgICAgICAgLy8gYXd0LjIxMz1UaGlzIENvbXBvbmVudENvbG9yTW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUKKyAgICAgICAgICAgIC8vIHVubm9ybWFsaXplZCBmb3JtCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxMyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG5vcm1Db21wb25lbnRzLmxlbmd0aCAtIG5vcm1PZmZzZXQgPCBudW1Db21wb25lbnRzKSB7CisgICAgICAgICAgICAvLyBhd3QuMjFCPVRoZSBsZW5ndGggb2Ygbm9ybUNvbXBvbmVudHMgbWludXMgbm9ybU9mZnNldCBpcyBsZXNzCisgICAgICAgICAgICAvLyB0aGFuIG51bUNvbXBvbmVudHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjFCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VW5ub3JtYWxpemVkQ29tcG9uZW50cyhub3JtQ29tcG9uZW50cywgbm9ybU9mZnNldCwgY29tcG9uZW50cywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldERhdGFFbGVtZW50KGZsb2F0IG5vcm1Db21wb25lbnRzW10sIGludCBub3JtT2Zmc2V0KSB7CisgICAgICAgIGlmIChudW1Db21wb25lbnRzID4gMSkgeworICAgICAgICAgICAgLy8gYXd0LjIxMj1UaGVyZSBpcyBtb3JlIHRoYW4gb25lIGNvbXBvbmVudCBpbiB0aGlzIENvbG9yTW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25lZCkgeworICAgICAgICAgICAgLy8gYXd0LjIxMD1UaGUgY29tcG9uZW50IHZhbHVlIGZvciB0aGlzIENvbG9yTW9kZWwgaXMgc2lnbmVkCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IHBpeGVsID0gZ2V0RGF0YUVsZW1lbnRzKG5vcm1Db21wb25lbnRzLCBub3JtT2Zmc2V0LCBudWxsKTsKKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW10gPSAoYnl0ZVtdKXBpeGVsOworICAgICAgICAgICAgICAgIHJldHVybiBiYVswXSAmIDB4ZmY7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXSA9IChzaG9ydFtdKXBpeGVsOworICAgICAgICAgICAgICAgIHJldHVybiBzYVswXSAmIDB4ZmZmZjsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICByZXR1cm4gaWFbMF07CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4yMTE9UGl4ZWwgdmFsdWVzIGZvciB0aGlzIENvbG9yTW9kZWwgYXJlIG5vdCBjb252ZW5pZW50bHkKKyAgICAgICAgICAgICAgICAvLyByZXByZXNlbnRhYmxlIGFzIGEgc2luZ2xlIGludAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjExIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50W10gZ2V0Q29tcG9uZW50cyhpbnQgcGl4ZWwsIGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgaWYgKG51bUNvbXBvbmVudHMgPiAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEyPVRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgY29tcG9uZW50IGluIHRoaXMgQ29sb3JNb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoZG9ub3RTdXBwb3J0VW5ub3JtYWxpemVkKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEzPVRoaXMgQ29tcG9uZW50Q29sb3JNb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAgICAgICAgLy8gdW5ub3JtYWxpemVkIGZvcm0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoY29tcG9uZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzID0gbmV3IGludFtvZmZzZXQgKyAxXTsKKyAgICAgICAgfQorCisgICAgICAgIGNvbXBvbmVudHNbb2Zmc2V0XSA9IHBpeGVsICYgbWF4VmFsdWVzWzBdOworICAgICAgICByZXR1cm4gY29tcG9uZW50czsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJlZChpbnQgcGl4ZWwpIHsKKyAgICAgICAgZmxvYXQgcmdiW10gPSB0b1JHQihwaXhlbCk7CisgICAgICAgIHJldHVybiAoaW50KShyZ2JbMF0gKiAyNTUuMGYgKyAwLjVmKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJHQihpbnQgcGl4ZWwpIHsKKyAgICAgICAgcmV0dXJuIChnZXRBbHBoYShwaXhlbCkgPDwgMjQpIHwgKGdldFJlZChwaXhlbCkgPDwgMTYpIHwgKGdldEdyZWVuKHBpeGVsKSA8PCA4KQorICAgICAgICAgICAgICAgIHwgZ2V0Qmx1ZShwaXhlbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRHcmVlbihpbnQgcGl4ZWwpIHsKKyAgICAgICAgZmxvYXQgcmdiW10gPSB0b1JHQihwaXhlbCk7CisgICAgICAgIHJldHVybiAoaW50KShyZ2JbMV0gKiAyNTUuMGYgKyAwLjVmKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEJsdWUoaW50IHBpeGVsKSB7CisgICAgICAgIGZsb2F0IHJnYltdID0gdG9SR0IocGl4ZWwpOworICAgICAgICByZXR1cm4gKGludCkocmdiWzJdICogMjU1LjBmICsgMC41Zik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRBbHBoYShpbnQgcGl4ZWwpIHsKKworICAgICAgICAvLyBUaGlzIG1ldGhvZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gYWNjb3JkaW5nIHRvCisgICAgICAgIC8vIEphdmEgQVBJIFNwYWNpZmljYXRpb24KKyAgICAgICAgaWYgKHNpZ25lZCkgeworICAgICAgICAgICAgLy8gYXd0LjIxMD1UaGUgY29tcG9uZW50IHZhbHVlIGZvciB0aGlzIENvbG9yTW9kZWwgaXMgc2lnbmVkCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG51bUNvbXBvbmVudHMgPiAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEyPVRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgY29tcG9uZW50IGluIHRoaXMgQ29sb3JNb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAyNTU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6YXRpb24gb2YgTG9va3VwIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdExVVHMoKSB7CisgICAgICAgIGlzX3NSR0IgPSBjcy5pc0NTX3NSR0IoKTsKKyAgICAgICAgaXNfTElORUFSX1JHQiA9IChjcyA9PSBMVVRDb2xvckNvbnZlcnRlci5MSU5FQVJfUkdCX0NTKTsKKworICAgICAgICBpZiAoaGFzQWxwaGEgJiYgYml0c1tudW1Db2xvckNvbXBvbmVudHNdICE9IDggJiYgaW50ZWdyYWwpIHsKKyAgICAgICAgICAgIGFscGhhTFVUID0gbmV3IGJ5dGVbbWF4VmFsdWVzW251bUNvbG9yQ29tcG9uZW50c10gKyAxXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1heFZhbHVlc1tudW1Db2xvckNvbXBvbmVudHNdOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhbHBoYUxVVFtpXSA9IChieXRlKShzY2FsZUZhY3RvcnNbbnVtQ29sb3JDb21wb25lbnRzXSAqIGkgKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc19MSU5FQVJfUkdCKSB7CisgICAgICAgICAgICBpZiAobWF4Qml0TGVuZ3RoID4gOCkgeworICAgICAgICAgICAgICAgIExJTkVBUl9SR0JfTGVuZ3RoID0gMTY7CisgICAgICAgICAgICAgICAgZnJvbV9MSU5FQVJfUkdCX0xVVCA9IExVVENvbG9yQ29udmVydGVyLmdldEZyb20xNmxSR0J0b3NSR0JfTFVUKCk7CisgICAgICAgICAgICAgICAgdG9fTElORUFSXzE2UkdCX0xVVCA9IExVVENvbG9yQ29udmVydGVyLmdldEZyb21zUkdCdG8xNmxSR0JfTFVUKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIExJTkVBUl9SR0JfTGVuZ3RoID0gODsKKyAgICAgICAgICAgICAgICBmcm9tX0xJTkVBUl9SR0JfTFVUID0gTFVUQ29sb3JDb252ZXJ0ZXIuZ2V0RnJvbThsUkdCdG9zUkdCX0xVVCgpOworICAgICAgICAgICAgICAgIHRvX0xJTkVBUl84UkdCX0xVVCA9IExVVENvbG9yQ29udmVydGVyLmdldEZyb21zUkdCdG84bFJHQl9MVVQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZGYWN0b3IgPSAoKDEgPDwgTElORUFSX1JHQl9MZW5ndGgpIC0gMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmRmFjdG9yID0gMjU1LjBmOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpc0FscGhhUHJlbXVsdGlwbGllZCAmJiBpbnRlZ3JhbCkgeworICAgICAgICAgICAgY29sb3JMVVRzID0gbmV3IGJ5dGVbM11bXTsKKworICAgICAgICAgICAgaWYgKGlzX3NSR0IpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChiaXRzW2ldICE9IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNbaV0gPT0gYml0c1tqXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvckxVVHNbaV0gPSBjb2xvckxVVHNbal07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTFVUc1tpXSA9IG5ldyBieXRlW21heFZhbHVlc1tpXSArIDFdOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gbWF4VmFsdWVzWzBdOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvckxVVHNbaV1bal0gPSAoYnl0ZSkoc2NhbGVGYWN0b3JzW2ldICogaiArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoYml0c1tpXSAhPSBMSU5FQVJfUkdCX0xlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYml0c1tpXSA9PSBiaXRzW2pdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTFVUc1tpXSA9IGNvbG9yTFVUc1tqXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JMVVRzW2ldID0gbmV3IGJ5dGVbbWF4VmFsdWVzW2ldICsgMV07CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8PSBtYXhWYWx1ZXNbMF07IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpZHg7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKExJTkVBUl9SR0JfTGVuZ3RoID09IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4ID0gKGludCkoc2NhbGVGYWN0b3JzW2ldICogaiArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeCA9IChpbnQpKHNjYWxlRmFjdG9yc1tpXSAqIGogKiAyNTcuMGYgKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JMVVRzW2ldW2pdID0gZnJvbV9MSU5FQVJfUkdCX0xVVFtpZHhdOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUbyByZ2IuCisgICAgICogCisgICAgICogQHBhcmFtIHBpeGVsCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGl4ZWwuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2Ygbm9ybWFsaXplZCBzUkdCIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdFtdIHRvUkdCKGludCBwaXhlbCkgeworCisgICAgICAgIC8vIFRoaXMgbWV0aG9kIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBhY2NvcmRpbmcgdG8KKyAgICAgICAgLy8gSmF2YSBBUEkgU3BhY2lmaWNhdGlvbgorICAgICAgICBpZiAoc2lnbmVkKSB7CisgICAgICAgICAgICAvLyBhd3QuMjEwPVRoZSBjb21wb25lbnQgdmFsdWUgZm9yIHRoaXMgQ29sb3JNb2RlbCBpcyBzaWduZWQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjEwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobnVtQ29tcG9uZW50cyA+IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMTI9VGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBjb21wb25lbnQgaW4gdGhpcyBDb2xvck1vZGVsCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxMiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IG9iaiA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gbmV3IGJ5dGVbMV07CisgICAgICAgICAgICAgICAgYmFbMF0gPSAoYnl0ZSlwaXhlbDsKKyAgICAgICAgICAgICAgICBvYmogPSBiYTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW10gPSBuZXcgc2hvcnRbMV07CisgICAgICAgICAgICAgICAgc2FbMF0gPSAoc2hvcnQpcGl4ZWw7CisgICAgICAgICAgICAgICAgb2JqID0gc2E7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IG5ldyBpbnRbMV07CisgICAgICAgICAgICAgICAgaWFbMF0gPSBwaXhlbDsKKyAgICAgICAgICAgICAgICBvYmogPSBpYTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNzLnRvUkdCKGdldE5vcm1hbGl6ZWRDb21wb25lbnRzKG9iaiwgbnVsbCwgMCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFJHQiBjb21wb25lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIHBpeGVsCisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIGlkeAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIGNvbXBvbmVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBSR0IgdmFsdWUgZnJvbSAwIHRvIDI1NSBwaXhlbCdzIGNvbXBvbmVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRSR0JDb21wb25lbnQoT2JqZWN0IHBpeGVsLCBpbnQgaWR4KSB7CisgICAgICAgIGlmIChpc19zUkdCKSB7CisgICAgICAgICAgICBpbnQgY29tcCA9IGdldERlZkNvbXBvbmVudChwaXhlbCwgaWR4KTsKKyAgICAgICAgICAgIGlmIChjYWxjVmFsdWUgfHwgYml0c1tpZHhdID09IDgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjb2xvckxVVHNbaWR4XVtjb21wXSAmIDB4ZmY7CisgICAgICAgIH0gZWxzZSBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgaW50IGNvbXAgPSBnZXREZWZDb21wb25lbnQocGl4ZWwsIGlkeCk7CisgICAgICAgICAgICBpZiAoY2FsY1ZhbHVlIHx8IGJpdHNbaWR4XSA9PSBMSU5FQVJfUkdCX0xlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmcm9tX0xJTkVBUl9SR0JfTFVUW2NvbXBdICYgMHhmZjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjb2xvckxVVHNbaWR4XVtjb21wXSAmIDB4ZmY7CisgICAgICAgIH0KKworICAgICAgICBmbG9hdCBub3JtQ29tcFtdID0gZ2V0Tm9ybWFsaXplZENvbXBvbmVudHMocGl4ZWwsIG51bGwsIDApOworICAgICAgICBmbG9hdCByZ2JDb21wW10gPSBjcy50b1JHQihub3JtQ29tcCk7CisgICAgICAgIHJldHVybiAoaW50KShyZ2JDb21wW2lkeF0gKiAyNTUuMGYgKyAwLjVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZWYgY29tcG9uZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiBjb21wb25lbnQuCisgICAgICogQHJldHVybiB0aGUgdGVudGF0aXZlIHZhbHVlIG9mIHRoZSBwaXhlbCBjb21wb25lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0RGVmQ29tcG9uZW50KE9iamVjdCBwaXhlbCwgaW50IGlkeCkgeworICAgICAgICBpbnQgY29tcCA9IDA7CisgICAgICAgIGNhbGNWYWx1ZSA9IGZhbHNlOworCisgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10pcGl4ZWw7CisgICAgICAgICAgICAgICAgY29tcCA9IGJhW2lkeF0gJiAweGZmOworICAgICAgICAgICAgICAgIGlmIChuZWVkQWxwaGFEaXZpZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGFscGhhID0gYmFbbnVtQ29sb3JDb21wb25lbnRzXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGlmIChhbHBoYSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gMDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG5vcm1BbHBoYSA9IHNjYWxlRmFjdG9yc1tudW1Db2xvckNvbXBvbmVudHNdICogYWxwaGE7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gKGludCkoY29tcCAqIGZGYWN0b3IgLyBub3JtQWxwaGEgKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjYWxjVmFsdWUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcDsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHVzYVtdID0gKHNob3J0W10pcGl4ZWw7CisgICAgICAgICAgICAgICAgY29tcCA9IHVzYVtpZHhdICYgMHhmZmZmOworICAgICAgICAgICAgICAgIGlmIChuZWVkQWxwaGFEaXZpZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGFscGhhID0gdXNhW251bUNvbG9yQ29tcG9uZW50c10gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgICAgIGlmIChhbHBoYSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gMDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG5vcm1BbHBoYSA9IHNjYWxlRmFjdG9yc1tudW1Db2xvckNvbXBvbmVudHNdICogYWxwaGE7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gKGludCkoY29tcCAqIGZGYWN0b3IgLyBub3JtQWxwaGEgKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjYWxjVmFsdWUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcDsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGludCBpYVtdID0gKGludFtdKXBpeGVsOworICAgICAgICAgICAgICAgIGNvbXAgPSBpYVtpZHhdOworICAgICAgICAgICAgICAgIGlmIChuZWVkQWxwaGFEaXZpZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGFscGhhID0gaWFbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGFscGhhID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPSAwOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgbm9ybUFscGhhID0gc2NhbGVGYWN0b3JzW251bUNvbG9yQ29tcG9uZW50c10gKiBhbHBoYTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPSAoaW50KShjb21wICogZkZhY3RvciAvIG5vcm1BbHBoYSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNhbGNWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBjb21wOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10pcGl4ZWw7CisgICAgICAgICAgICAgICAgY29tcCA9IHNhW2lkeF07CisgICAgICAgICAgICAgICAgaWYgKG5lZWRBbHBoYURpdmlkZSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgYWxwaGEgPSBzYVtudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgICAgICAgICBpZiAoYWxwaGEgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBub3JtQWxwaGEgPSBzY2FsZUZhY3RvcnNbbnVtQ29sb3JDb21wb25lbnRzXSAqIGFscGhhOworICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9IChpbnQpKGNvbXAgKiBmRmFjdG9yIC8gbm9ybUFscGhhICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY2FsY1ZhbHVlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXA7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGZsb2F0IGZhW10gPSAoZmxvYXRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBpZiAobmVlZEFscGhhRGl2aWRlKSB7CisgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gZmFbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZhW251bUNvbG9yQ29tcG9uZW50c10gPT0gMC4wZikgeworICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gKGludCkoZmFbaWR4XSAqIGZGYWN0b3IgLyBhbHBoYSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY29tcCA9IChpbnQpKGZhW2lkeF0gKiBmRmFjdG9yICsgMC41Zik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhbGNWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXA7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgICAgICBkb3VibGUgZGFbXSA9IChkb3VibGVbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBpZiAobmVlZEFscGhhRGl2aWRlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChkYVtudW1Db2xvckNvbXBvbmVudHNdID09IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb21wID0gKGludCkoZGFbaWR4XSAqIGZGYWN0b3IgLyBkYVtudW1Db2xvckNvbXBvbmVudHNdICsgMC41KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGNvbXAgPSAoaW50KShkYVtpZHhdICogZkZhY3RvciArIDAuNSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhbGNWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXA7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxND1UaGlzIENvbG9yIE1vZGVsIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHRyYW5zZmVyVHlwZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0NvbXBvbmVudFNhbXBsZU1vZGVsLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvQ29tcG9uZW50U2FtcGxlTW9kZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjgxNDA5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0NvbXBvbmVudFNhbXBsZU1vZGVsLmphdmEKQEAgLTAsMCArMSw3MDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBDb21wb25lbnRTYW1wbGVNb2RlbCBjbGFzcyByZXByZXNlbnRzIGEgc2V0IG9mIGltYWdlIGRhdGEgd2hvc2UgZWFjaAorICogZWxlbWVudCAtIHRoZSBzYW1wbGUgb2YgYSBwaXhlbCAtIHRha2VzIG9uZSBkYXRhIGVsZW1lbnQgb2YgdGhlIERhdGFCdWZmZXIuCisgKiA8cD4KKyAqIFRoZSBCYW5rIGluZGljZXMgZGVub3RlIHRoZSBjb3JyZXNwb25kZW5jZSBiZXR3ZWVuIHRoZSBiYW5rIG9mIGRhdGEgYnVmZmVycworICogYW5kIGEgYmFuZCBvZiBpbWFnZSBkYXRhLiBUaGUgUGl4ZWwgc3RyaWRlIGlzIHRoZSBudW1iZXIgb2YgZGF0YSBhcnJheQorICogZWxlbWVudHMgYmV0d2VlbiB0d28gc2FtcGxlcyBmb3IgdGhlIHNhbWUgYmFuZCBvbiB0aGUgc2FtZSBzY2FubGluZS4gVGhlCisgKiBwaXhlbCBzdHJpZGUgZm9yIGEgQmFuZGVkU2FtcGxlTW9kZWwgaXMgb25lLiBUaGUgc2NhbmxpbmUgc3RyaWRlIHJlcHJlc2VudHMKKyAqIHRoZSBudW1iZXIgb2YgZGF0YSBhcnJheSBlbGVtZW50cyBiZXR3ZWVuIGEgc3BlY2lmaWVkIHNhbXBsZSBhbmQgdGhlCisgKiBjb3JyZXNwb25kaW5nIHNhbXBsZSBpbiB0aGUgc2FtZSBjb2x1bW4gaW4gdGhlIG5leHQgc2NhbmxpbmUuIFRoZSBhcnJheSBvZgorICogYmFuZCBvZmZzZXRzIGdpdmVzIHRoZSBzdGFydGluZyBvZmZzZXRzIHdpdGhpbiBlYWNoIGRhdGEgYmFua3Mgb2YgdGhlIGluIHRoZQorICogRGF0YUJ1ZmZlci4gVGhlIGJhbmsgaW5kaWNlcyByZXByZXNlbnRzIHRoZSBpbmRpY2VzIHdpdGhpbiBlYWNoIGJhbmsgb2YgdGhlCisgKiBEYXRhQnVmZmVyIGNvcnJlc3BvbmRpbmcgdG8gYSBiYW5kIG9mIGltYWdlIGRhdGEuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQ29tcG9uZW50U2FtcGxlTW9kZWwgZXh0ZW5kcyBTYW1wbGVNb2RlbCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYmFuZCBvZmZzZXRzIGFycmF5IG9mIHRoaXMgQ29tcG9uZW50U2FtcGxlTW9kZWwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBiYW5kT2Zmc2V0c1tdOworCisgICAgLyoqCisgICAgICogVGhlIGJhbmsgaW5kaWNlcyBhcnJheSBvZiB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYmFua0luZGljZXNbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgYmFuZHMgaW4gdGhpcyBDb21wb25lbnRTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG51bUJhbmRzOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBiYW5rcyBvZiB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgbnVtQmFua3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoaXMgQ29tcG9uZW50U2FtcGxlTW9kZWwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzY2FubGluZVN0cmlkZTsKKworICAgIC8qKgorICAgICAqIFRoZSBwaXhlbCBzdHJpZGUgb2YgdGhpcyBDb21wb25lbnRTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHBpeGVsU3RyaWRlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IENvbXBvbmVudFNhbXBsZU1vZGVsIHdpdGggdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiBzYW1wbGVzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIHBpeGVsU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwgc3RyaWRlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBzY2FubGluZVN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gYmFua0luZGljZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiB0aGUgYmFuayBpbmRpY2VzLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHRoZSBiYW5kIG9mZnNldHMuCisgICAgICovCisgICAgcHVibGljIENvbXBvbmVudFNhbXBsZU1vZGVsKGludCBkYXRhVHlwZSwgaW50IHcsIGludCBoLCBpbnQgcGl4ZWxTdHJpZGUsIGludCBzY2FubGluZVN0cmlkZSwKKyAgICAgICAgICAgIGludCBiYW5rSW5kaWNlc1tdLCBpbnQgYmFuZE9mZnNldHNbXSkgeworCisgICAgICAgIHN1cGVyKGRhdGFUeXBlLCB3LCBoLCBiYW5kT2Zmc2V0cy5sZW5ndGgpOworCisgICAgICAgIGlmIChwaXhlbFN0cmlkZSA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNEI9UGl4ZWwgc3RyaWRlIG11c3QgYmUgPj0gMAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNEIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzY2FubGluZVN0cmlkZSA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNEM9U2NhbmxpbmUgc3RyaWRlIG11c3QgYmUgPj0gMAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNEMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChiYW5rSW5kaWNlcy5sZW5ndGggIT0gYmFuZE9mZnNldHMubGVuZ3RoKSB7CisgICAgICAgICAgICAvLyBhd3QuMjREPUJhbmsgSW5kaWNlcyBsZW5ndGggbXVzdCBiZSBlcXVhbCBCYW5rIE9mZnNldHMgbGVuZ3RoCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0RCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5waXhlbFN0cmlkZSA9IHBpeGVsU3RyaWRlOworICAgICAgICB0aGlzLnNjYW5saW5lU3RyaWRlID0gc2NhbmxpbmVTdHJpZGU7CisgICAgICAgIHRoaXMuYmFuZE9mZnNldHMgPSBiYW5kT2Zmc2V0cy5jbG9uZSgpOworICAgICAgICB0aGlzLmJhbmtJbmRpY2VzID0gYmFua0luZGljZXMuY2xvbmUoKTsKKyAgICAgICAgdGhpcy5udW1CYW5kcyA9IGJhbmRPZmZzZXRzLmxlbmd0aDsKKworICAgICAgICBpbnQgbWF4QmFuayA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmFua0luZGljZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChiYW5rSW5kaWNlc1tpXSA8IDApIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjRFPUluZGV4IG9mIHswfSBiYW5rIG11c3QgYmUgPj0gMAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjRFIiwgaSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYmFua0luZGljZXNbaV0gPiBtYXhCYW5rKSB7CisgICAgICAgICAgICAgICAgbWF4QmFuayA9IGJhbmtJbmRpY2VzW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMubnVtQmFua3MgPSBtYXhCYW5rICsgMTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBDb21wb25lbnRTYW1wbGVNb2RlbCB3aXRoIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHNhbXBsZXMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gcGl4ZWxTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCBzdHJpZGUgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIHNjYW5saW5lU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJhbmQgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcG9uZW50U2FtcGxlTW9kZWwoaW50IGRhdGFUeXBlLCBpbnQgdywgaW50IGgsIGludCBwaXhlbFN0cmlkZSwgaW50IHNjYW5saW5lU3RyaWRlLAorICAgICAgICAgICAgaW50IGJhbmRPZmZzZXRzW10pIHsKKworICAgICAgICBzdXBlcihkYXRhVHlwZSwgdywgaCwgYmFuZE9mZnNldHMubGVuZ3RoKTsKKyAgICAgICAgaWYgKHBpeGVsU3RyaWRlIDwgMCkgeworICAgICAgICAgICAgLy8gYXd0LjI0Qj1QaXhlbCBzdHJpZGUgbXVzdCBiZSA+PSAwCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHNjYW5saW5lU3RyaWRlIDwgMCkgeworICAgICAgICAgICAgLy8gYXd0LjI0Qz1TY2FubGluZSBzdHJpZGUgbXVzdCBiZSA+PSAwCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5waXhlbFN0cmlkZSA9IHBpeGVsU3RyaWRlOworICAgICAgICB0aGlzLnNjYW5saW5lU3RyaWRlID0gc2NhbmxpbmVTdHJpZGU7CisgICAgICAgIHRoaXMuYmFuZE9mZnNldHMgPSBiYW5kT2Zmc2V0cy5jbG9uZSgpOworICAgICAgICB0aGlzLm51bUJhbmRzID0gYmFuZE9mZnNldHMubGVuZ3RoOworICAgICAgICB0aGlzLm51bUJhbmtzID0gMTsKKworICAgICAgICB0aGlzLmJhbmtJbmRpY2VzID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgYmFua0luZGljZXNbaV0gPSAwOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBPYmplY3Qgb2JqLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmRhdGFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYmRhdGEgPSBuZXcgYnl0ZVtudW1CYW5kc107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmRhdGEgPSAoYnl0ZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYmRhdGFbaV0gPSAoYnl0ZSlnZXRTYW1wbGUoeCwgeSwgaSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgb2JqID0gYmRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOgorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNkYXRhID0gbmV3IHNob3J0W251bUJhbmRzXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZGF0YSA9IChzaG9ydFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2RhdGFbaV0gPSAoc2hvcnQpZ2V0U2FtcGxlKHgsIHksIGksIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG9iaiA9IHNkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlkYXRhID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWRhdGEgPSAoaW50W10pb2JqOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZGF0YVtpXSA9IGdldFNhbXBsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvYmogPSBpZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgZmxvYXQgZmRhdGFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZmRhdGEgPSBuZXcgZmxvYXRbbnVtQmFuZHNdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZkYXRhID0gKGZsb2F0W10pb2JqOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmZGF0YVtpXSA9IGdldFNhbXBsZUZsb2F0KHgsIHksIGksIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG9iaiA9IGZkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgZG91YmxlIGRkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGRkYXRhID0gbmV3IGRvdWJsZVtudW1CYW5kc107CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZGRhdGEgPSAoZG91YmxlW10pb2JqOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBkZGF0YVtpXSA9IGdldFNhbXBsZURvdWJsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvYmogPSBkZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBvYmo7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhcnJbXSA9IChieXRlW10pb2JqOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoeCwgeSwgaSwgYmFycltpXSAmIDB4ZmYsIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FycltdID0gKHNob3J0W10pb2JqOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoeCwgeSwgaSwgc2FycltpXSAmIDB4ZmZmZiwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlhcnJbXSA9IChpbnRbXSlvYmo7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBpYXJyW2ldLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGZsb2F0IGZhcnJbXSA9IChmbG9hdFtdKW9iajsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIGZhcnJbaV0sIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIGRvdWJsZSBkYXJyW10gPSAoZG91YmxlW10pb2JqOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoeCwgeSwgaSwgZGFycltpXSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBDb21wb25lbnRTYW1wbGVNb2RlbCB3aXRoIHRoZSBzcGVjaWZpZWQgT2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIG9iamVjdCBpcyBhIENvbXBvbmVudFNhbXBsZU1vZGVsIHdpdGggaWRlbnRpY2FsIGRhdGEKKyAgICAgKiAgICAgICAgIHZhbHVlcyB0byB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICgobyA9PSBudWxsKSB8fCAhKG8gaW5zdGFuY2VvZiBDb21wb25lbnRTYW1wbGVNb2RlbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDb21wb25lbnRTYW1wbGVNb2RlbCBtb2RlbCA9IChDb21wb25lbnRTYW1wbGVNb2RlbClvOworICAgICAgICByZXR1cm4gdGhpcy53aWR0aCA9PSBtb2RlbC53aWR0aCAmJiB0aGlzLmhlaWdodCA9PSBtb2RlbC5oZWlnaHQKKyAgICAgICAgICAgICAgICAmJiB0aGlzLm51bUJhbmRzID09IG1vZGVsLm51bUJhbmRzICYmIHRoaXMuZGF0YVR5cGUgPT0gbW9kZWwuZGF0YVR5cGUKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKHRoaXMuYmFuZE9mZnNldHMsIG1vZGVsLmJhbmRPZmZzZXRzKQorICAgICAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHModGhpcy5iYW5rSW5kaWNlcywgbW9kZWwuYmFua0luZGljZXMpCisgICAgICAgICAgICAgICAgJiYgdGhpcy5udW1CYW5kcyA9PSBtb2RlbC5udW1CYW5kcyAmJiB0aGlzLm51bUJhbmtzID09IG1vZGVsLm51bUJhbmtzCisgICAgICAgICAgICAgICAgJiYgdGhpcy5zY2FubGluZVN0cmlkZSA9PSBtb2RlbC5zY2FubGluZVN0cmlkZQorICAgICAgICAgICAgICAgICYmIHRoaXMucGl4ZWxTdHJpZGUgPT0gbW9kZWwucGl4ZWxTdHJpZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLmF3dC5pbWFnZS5TYW1wbGVNb2RlbCNjcmVhdGVTdWJzZXRTYW1wbGVNb2RlbChpbnRbXSkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgY3JlYXRlU3Vic2V0U2FtcGxlTW9kZWwoaW50IGJhbmRzW10pIHsKKyAgICAgICAgaWYgKGJhbmRzLmxlbmd0aCA+IHRoaXMubnVtQmFuZHMpIHsKKyAgICAgICAgICAgIC8vIGF3dC42ND1UaGUgbnVtYmVyIG9mIHRoZSBiYW5kcyBpbiB0aGUgc3Vic2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUKKyAgICAgICAgICAgIC8vIG51bWJlciBvZiBiYW5kcyBpbiB0aGUgc2FtcGxlIG1vZGVsCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjY0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kaWNlc1tdID0gbmV3IGludFtiYW5kcy5sZW5ndGhdOworICAgICAgICBpbnQgb2Zmc2V0c1tdID0gbmV3IGludFtiYW5kcy5sZW5ndGhdOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmFuZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGluZGljZXNbaV0gPSBiYW5rSW5kaWNlc1tiYW5kc1tpXV07CisgICAgICAgICAgICBvZmZzZXRzW2ldID0gYmFuZE9mZnNldHNbYmFuZHNbaV1dOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBDb21wb25lbnRTYW1wbGVNb2RlbChkYXRhVHlwZSwgd2lkdGgsIGhlaWdodCwgcGl4ZWxTdHJpZGUsIHNjYW5saW5lU3RyaWRlLAorICAgICAgICAgICAgICAgIGluZGljZXMsIG9mZnNldHMpOworCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbChpbnQgdywgaW50IGgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDb21wb25lbnRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwgcGl4ZWxTdHJpZGUsIHBpeGVsU3RyaWRlICogdywgYmFua0luZGljZXMsCisgICAgICAgICAgICAgICAgYmFuZE9mZnNldHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBwaXhlbFtdOworCisgICAgICAgIGlmIChpQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcGl4ZWwgPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBpeGVsID0gaUFycmF5OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBwaXhlbFtpXSA9IGdldFNhbXBsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwaXhlbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIGlBcnJheVtpXSwgZGF0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkYXRhLmdldEVsZW0oYmFua0luZGljZXNbYl0sIHkgKiBzY2FubGluZVN0cmlkZSArIHggKiBwaXhlbFN0cmlkZSArIGJhbmRPZmZzZXRzW2JdKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U2FtcGxlRmxvYXQoaW50IHgsIGludCB5LCBpbnQgYiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGF0YS5nZXRFbGVtRmxvYXQoYmFua0luZGljZXNbYl0sIHkgKiBzY2FubGluZVN0cmlkZSArIHggKiBwaXhlbFN0cmlkZQorICAgICAgICAgICAgICAgICsgYmFuZE9mZnNldHNbYl0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0U2FtcGxlRG91YmxlKGludCB4LCBpbnQgeSwgaW50IGIsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCA+PSB0aGlzLndpZHRoIHx8IHkgPj0gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRhdGEuZ2V0RWxlbURvdWJsZShiYW5rSW5kaWNlc1tiXSwgeSAqIHNjYW5saW5lU3RyaWRlICsgeCAqIHBpeGVsU3RyaWRlCisgICAgICAgICAgICAgICAgKyBiYW5kT2Zmc2V0c1tiXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPiB0aGlzLndpZHRoIHx8IHggKyB3ID4gdGhpcy53aWR0aCB8fCB5ID4gdGhpcy5oZWlnaHQKKyAgICAgICAgICAgICAgICB8fCB5ICsgaCA+IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpbnQgcGl4ZWxzW10gPSBudWxsOworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBpZiAoaUFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHBpeGVscyA9IG5ldyBpbnRbdyAqIGggKiBudW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbHMgPSBpQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQmFuZHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaWR4KytdID0gZ2V0U2FtcGxlKGosIGksIG4sIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwaXhlbHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgaUFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCArIHcgPiB0aGlzLndpZHRoIHx8IHkgKyBoID4gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQmFuZHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoaiwgaSwgbiwgaUFycmF5W2lkeCsrXSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIGludCBzLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGRhdGEuc2V0RWxlbShiYW5rSW5kaWNlc1tiXSwgeSAqIHNjYW5saW5lU3RyaWRlICsgeCAqIHBpeGVsU3RyaWRlICsgYmFuZE9mZnNldHNbYl0sIHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRTYW1wbGVzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgYiwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggKyB3ID4gdGhpcy53aWR0aCB8fCB5ICsgaCA+IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpbnQgc2FtcGxlc1tdOworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBpZiAoaUFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBuZXcgaW50W3cgKiBoXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBpQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjk1PWRhdGEgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI5NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICBzYW1wbGVzW2lkeCsrXSA9IGdldFNhbXBsZShqLCBpLCBiLCBkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYW1wbGVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBpbnQgaUFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCArIHcgPiB0aGlzLndpZHRoIHx8IHkgKyBoID4gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNldFNhbXBsZShqLCBpLCBiLCBpQXJyYXlbaWR4KytdLCBkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBmbG9hdCBzLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGRhdGEuc2V0RWxlbUZsb2F0KGJhbmtJbmRpY2VzW2JdLCB5ICogc2NhbmxpbmVTdHJpZGUgKyB4ICogcGl4ZWxTdHJpZGUgKyBiYW5kT2Zmc2V0c1tiXSwgcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIGRvdWJsZSBzLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGRhdGEKKyAgICAgICAgICAgICAgICAuc2V0RWxlbURvdWJsZShiYW5rSW5kaWNlc1tiXSwgeSAqIHNjYW5saW5lU3RyaWRlICsgeCAqIHBpeGVsU3RyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICArIGJhbmRPZmZzZXRzW2JdLCBzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0YUJ1ZmZlciBjcmVhdGVEYXRhQnVmZmVyKCkgeworICAgICAgICBEYXRhQnVmZmVyIGRhdGEgPSBudWxsOworCisgICAgICAgIGludCBtYXhPZmZzZXQgPSBiYW5kT2Zmc2V0c1swXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBiYW5kT2Zmc2V0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGJhbmRPZmZzZXRzW2ldID4gbWF4T2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgbWF4T2Zmc2V0ID0gYmFuZE9mZnNldHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpemUgPSAoaGVpZ2h0IC0gMSkgKiBzY2FubGluZVN0cmlkZSArICh3aWR0aCAtIDEpICogcGl4ZWxTdHJpZGUgKyBtYXhPZmZzZXQgKyAxOworCisgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyQnl0ZShzaXplLCBudW1CYW5rcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJTaG9ydChzaXplLCBudW1CYW5rcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyVVNob3J0KHNpemUsIG51bUJhbmtzKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJJbnQoc2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyRmxvYXQoc2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlckRvdWJsZShzaXplLCBudW1CYW5rcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGF0YTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYmFuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIHNwZWNpZmllZCBiYW5kIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoaW50IHgsIGludCB5LCBpbnQgYikgeworICAgICAgICByZXR1cm4geSAqIHNjYW5saW5lU3RyaWRlICsgeCAqIHBpeGVsU3RyaWRlICsgYmFuZE9mZnNldHNbYl07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBmaXJzdCBiYW5kIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBmaXJzdCBiYW5kIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoaW50IHgsIGludCB5KSB7CisgICAgICAgIHJldHVybiB5ICogc2NhbmxpbmVTdHJpZGUgKyB4ICogcGl4ZWxTdHJpZGUgKyBiYW5kT2Zmc2V0c1swXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFNhbXBsZVNpemUoaW50IGJhbmQpIHsKKyAgICAgICAgcmV0dXJuIERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKGRhdGFUeXBlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50W10gZ2V0U2FtcGxlU2l6ZSgpIHsKKyAgICAgICAgaW50IHNhbXBsZVNpemVzW10gPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgaW50IHNpemUgPSBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShkYXRhVHlwZSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBzYW1wbGVTaXplc1tpXSA9IHNpemU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNhbXBsZVNpemVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgYmFuayBpbmRpY2VzIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBDb21wb25lbnRTYW1wbGVNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBiYW5rIGluZGljZXMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludFtdIGdldEJhbmtJbmRpY2VzKCkgeworICAgICAgICByZXR1cm4gYmFua0luZGljZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHRoZSBiYW5kIG9mZnNldHMgY29ycmVzcG9uZGluZyB0byB0aGlzCisgICAgICogQ29tcG9uZW50U2FtcGxlTW9kZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgYmFuZCBvZmZzZXRzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnRbXSBnZXRCYW5kT2Zmc2V0cygpIHsKKyAgICAgICAgcmV0dXJuIGJhbmRPZmZzZXRzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGhhc2ggY29kZSBvZiB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgaGFzaCBjb2RlIG9mIHRoaXMgQ29tcG9uZW50U2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgaW50IHRtcCA9IDA7CisKKyAgICAgICAgaGFzaCA9IHdpZHRoOworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gaGVpZ2h0OworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gbnVtQmFuZHM7CisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBkYXRhVHlwZTsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBmb3IgKGludCBlbGVtZW50IDogYmFuZE9mZnNldHMpIHsKKyAgICAgICAgICAgIGhhc2ggXj0gZWxlbWVudDsKKyAgICAgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGVsZW1lbnQgOiBiYW5rSW5kaWNlcykgeworICAgICAgICAgICAgaGFzaCBePSBlbGVtZW50OworICAgICAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgaGFzaCBePSBwaXhlbFN0cmlkZTsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworCisgICAgICAgIGhhc2ggXj0gc2NhbmxpbmVTdHJpZGU7CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGlzIENvbXBvbmVudFNhbXBsZU1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0U2NhbmxpbmVTdHJpZGUoKSB7CisgICAgICAgIHJldHVybiBzY2FubGluZVN0cmlkZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwaXhlbCBzdHJpZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcGl4ZWwgc3RyaWRlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UGl4ZWxTdHJpZGUoKSB7CisgICAgICAgIHJldHVybiBwaXhlbFN0cmlkZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bURhdGFFbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIG51bUJhbmRzOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0NvbnZvbHZlT3AuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Db252b2x2ZU9wLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmViODkwOQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Db252b2x2ZU9wLmphdmEKQEAgLTAsMCArMSw1NDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqIEBkYXRlOiBTZXAgMjksIDIwMDUKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENvbnZvbHZlT3AgY2xhc3MgY29udm9sdmVzIGZyb20gdGhlIHNvdXJjZSBkYXRhIHRvIHRoZSBkZXN0aW5hdGlvbiB1c2luZworICogYSBjb252b2x1dGlvbiBrZXJuZWwuIEVhY2ggb3V0cHV0IHBpeGVsIGlzIHJlcHJlc2VudGVkIGFzIHRoZSByZXN1bHQgb2YKKyAqIG11bHRpcGx5aW5nIHRoZSBrZXJuZWwgYW5kIHRoZSBzdXJyb3VuZCBvZiB0aGUgaW5wdXQgcGl4ZWwuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgQ29udm9sdmVPcCBpbXBsZW1lbnRzIEJ1ZmZlcmVkSW1hZ2VPcCwgUmFzdGVyT3AgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEVER0VfWkVST19GSUxMIGluZGljYXRlcyB0aGF0IHBpeGVscyBhdCB0aGUgZWRnZSBvZiB0aGUKKyAgICAgKiBkZXN0aW5hdGlvbiBpbWFnZSBhcmUgc2V0IHRvIHplcm8uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRURHRV9aRVJPX0ZJTEwgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEVER0VfTk9fT1AgaW5kaWNhdGVzIHRoYXQgcGl4ZWxzIGF0IHRoZSBlZGdlIG9mIHRoZSBzb3VyY2UKKyAgICAgKiBpbWFnZSBhcmUgY29udmVydGVkIHRvIHRoZSBlZGdlIHBpeGVscyBpbiB0aGUgZGVzdGluYXRpb24gd2l0aG91dAorICAgICAqIG1vZGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFREdFX05PX09QID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBrZXJuZWwuCisgICAgICovCisgICAgcHJpdmF0ZSBLZXJuZWwga2VybmVsOworCisgICAgLyoqCisgICAgICogVGhlIGVkZ2UgY29uZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBlZGdlQ29uZDsKKworICAgIC8qKgorICAgICAqIFRoZSByaHMuCisgICAgICovCisgICAgcHJpdmF0ZSBSZW5kZXJpbmdIaW50cyByaHMgPSBudWxsOworCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gVE9ETworICAgICAgICAvLyBTeXN0ZW0ubG9hZExpYnJhcnkoImltYWdlb3BzIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IENvbnZvbHZlT3Agb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBLZXJuZWwgYW5kCisgICAgICogc3BlY2lmaWVkIGVkZ2VzIGNvbmRpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2VybmVsCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEtlcm5lbC4KKyAgICAgKiBAcGFyYW0gZWRnZUNvbmRpdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBlZGdlIGNvbmRpdGlvbi4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3QsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIENvbnZvbHZlT3AoS2VybmVsIGtlcm5lbCwgaW50IGVkZ2VDb25kaXRpb24sIFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHRoaXMua2VybmVsID0ga2VybmVsOworICAgICAgICB0aGlzLmVkZ2VDb25kID0gZWRnZUNvbmRpdGlvbjsKKyAgICAgICAgdGhpcy5yaHMgPSBoaW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQ29udm9sdmVPcCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIEtlcm5lbCBhbmQKKyAgICAgKiBFREdFX1pFUk9fRklMTCBlZGdlIGNvbmRpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2VybmVsCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEtlcm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udm9sdmVPcChLZXJuZWwga2VybmVsKSB7CisgICAgICAgIHRoaXMua2VybmVsID0ga2VybmVsOworICAgICAgICB0aGlzLmVkZ2VDb25kID0gRURHRV9aRVJPX0ZJTEw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgS2VybmVsIG9iamVjdCBvZiB0aGlzIENvbnZvbHZlT3AuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgS2VybmVsIG9iamVjdCBvZiB0aGlzIENvbnZvbHZlT3AuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEtlcm5lbCBnZXRLZXJuZWwoKSB7CisgICAgICAgIHJldHVybiAoS2VybmVsKWtlcm5lbC5jbG9uZSgpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBSZW5kZXJpbmdIaW50cyBnZXRSZW5kZXJpbmdIaW50cygpIHsKKyAgICAgICAgcmV0dXJuIHJoczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBlZGdlIGNvbmRpdGlvbiBvZiB0aGlzIENvbnZvbHZlT3AuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZWRnZSBjb25kaXRpb246IEVER0VfTk9fT1Agb3IgRURHRV9aRVJPX0ZJTEwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRFZGdlQ29uZGl0aW9uKCkgeworICAgICAgICByZXR1cm4gZWRnZUNvbmQ7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKFJhc3RlciBzcmMpIHsKKyAgICAgICAgcmV0dXJuIHNyYy5nZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoQnVmZmVyZWRJbWFnZSBzcmMpIHsKKyAgICAgICAgcmV0dXJuIGdldEJvdW5kczJEKHNyYy5nZXRSYXN0ZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFBvaW50MkQgZ2V0UG9pbnQyRChQb2ludDJEIHNyY1B0LCBQb2ludDJEIGRzdFB0KSB7CisgICAgICAgIGlmIChkc3RQdCA9PSBudWxsKSB7CisgICAgICAgICAgICBkc3RQdCA9IG5ldyBQb2ludDJELkZsb2F0KCk7CisgICAgICAgIH0KKworICAgICAgICBkc3RQdC5zZXRMb2NhdGlvbihzcmNQdCk7CisgICAgICAgIHJldHVybiBkc3RQdDsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoUmFzdGVyIHNyYykgeworICAgICAgICByZXR1cm4gc3JjLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcigpOworICAgIH0KKworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2UoQnVmZmVyZWRJbWFnZSBzcmMsIENvbG9yTW9kZWwgZHN0Q00pIHsKKyAgICAgICAgaWYgKGRzdENNID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdENNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3RDTSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgZHN0Q00gPSBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIFdyaXRhYmxlUmFzdGVyIHIgPSBkc3RDTS5pc0NvbXBhdGlibGVTYW1wbGVNb2RlbChzcmMuZ2V0U2FtcGxlTW9kZWwoKSkgPyBzcmMuZ2V0UmFzdGVyKCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCkpIDogZHN0Q00KKyAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHNyYy5nZXRXaWR0aCgpLCBzcmMuZ2V0SGVpZ2h0KCkpOworCisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShkc3RDTSwgciwgZHN0Q00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFdyaXRhYmxlUmFzdGVyIGZpbHRlcihSYXN0ZXIgc3JjLCBXcml0YWJsZVJhc3RlciBkc3QpIHsKKyAgICAgICAgaWYgKHNyYyA9PSBudWxsKSB7IC8vIFNob3VsZCB0aHJvdyBhY2NvcmRpbmcgdG8gc3BlYworICAgICAgICAgICAgLy8gYXd0LjI1Nj1Tb3VyY2UgcmFzdGVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzcmMgPT0gZHN0KSB7CisgICAgICAgICAgICAvLyBhd3QuMjU3PVNvdXJjZSByYXN0ZXIgaXMgZXF1YWwgdG8gZGVzdGluYXRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjU3IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKHNyYyk7CisgICAgICAgIH0gZWxzZSBpZiAoc3JjLmdldE51bUJhbmRzKCkgIT0gZHN0LmdldE51bUJhbmRzKCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNTg9TnVtYmVyIG9mIHNvdXJjZSBiYW5kcyAoezB9KSBpcyBub3QgZXF1YWwgdG8gbnVtYmVyIG9mCisgICAgICAgICAgICAvLyBkZXN0aW5hdGlvbiBiYW5kcyAoezF9KQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICJhd3QuMjU4Iiwgc3JjLmdldE51bUJhbmRzKCksIGRzdC5nZXROdW1CYW5kcygpKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gaWYgKGlwcEZpbHRlcihzcmMsIGRzdCwgQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTSkgIT0gMCkKKyAgICAgICAgaWYgKHNsb3dGaWx0ZXIoc3JjLCBkc3QpICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMUY9VW5hYmxlIHRvIHRyYW5zZm9ybSBzb3VyY2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbWFnaW5nT3BFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjFGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNsb3cgZmlsdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRzdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc2xvd0ZpbHRlcihSYXN0ZXIgc3JjLCBXcml0YWJsZVJhc3RlciBkc3QpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNhbXBsZU1vZGVsIHNtID0gc3JjLmdldFNhbXBsZU1vZGVsKCk7CisKKyAgICAgICAgICAgIGludCBudW1CYW5kcyA9IHNyYy5nZXROdW1CYW5kcygpOworICAgICAgICAgICAgaW50IHNyY0hlaWdodCA9IHNyYy5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGludCBzcmNXaWR0aCA9IHNyYy5nZXRXaWR0aCgpOworCisgICAgICAgICAgICBpbnQgeE9yaWdpbiA9IGtlcm5lbC5nZXRYT3JpZ2luKCk7CisgICAgICAgICAgICBpbnQgeU9yaWdpbiA9IGtlcm5lbC5nZXRZT3JpZ2luKCk7CisgICAgICAgICAgICBpbnQga1dpZHRoID0ga2VybmVsLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQga0hlaWdodCA9IGtlcm5lbC5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGZsb2F0W10gZGF0YSA9IGtlcm5lbC5nZXRLZXJuZWxEYXRhKG51bGwpOworCisgICAgICAgICAgICBpbnQgc3JjTWluWCA9IHNyYy5nZXRNaW5YKCk7CisgICAgICAgICAgICBpbnQgc3JjTWluWSA9IHNyYy5nZXRNaW5ZKCk7CisgICAgICAgICAgICBpbnQgZHN0TWluWCA9IGRzdC5nZXRNaW5YKCk7CisgICAgICAgICAgICBpbnQgZHN0TWluWSA9IGRzdC5nZXRNaW5ZKCk7CisKKyAgICAgICAgICAgIGludCBzcmNDb252TWF4WCA9IHNyY1dpZHRoIC0gKGtXaWR0aCAtIHhPcmlnaW4gLSAxKTsKKyAgICAgICAgICAgIGludCBzcmNDb252TWF4WSA9IHNyY0hlaWdodCAtIChrSGVpZ2h0IC0geU9yaWdpbiAtIDEpOworCisgICAgICAgICAgICBpbnRbXSBtYXhWYWx1ZXMgPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgICAgIGludFtdIG1hc2tzID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgICAgICBpbnRbXSBzYW1wbGVTaXplcyA9IHNtLmdldFNhbXBsZVNpemUoKTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgbWF4VmFsdWVzW2ldID0gKDEgPDwgc2FtcGxlU2l6ZXNbaV0pIC0gMTsKKyAgICAgICAgICAgICAgICBtYXNrc1tpXSA9IH4obWF4VmFsdWVzW2ldKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUHJvY2Vzc2luZyBib3VuZHMKKyAgICAgICAgICAgIGZsb2F0W10gcGl4ZWxzID0gbnVsbDsKKyAgICAgICAgICAgIHBpeGVscyA9IHNyYy5nZXRQaXhlbHMoc3JjTWluWCwgc3JjTWluWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgcGl4ZWxzKTsKKyAgICAgICAgICAgIGZsb2F0W10gbmV3UGl4ZWxzID0gbmV3IGZsb2F0W3BpeGVscy5sZW5ndGhdOworICAgICAgICAgICAgaW50IHJvd0xlbmd0aCA9IHNyY1dpZHRoICogbnVtQmFuZHM7CisgICAgICAgICAgICBpZiAodGhpcy5lZGdlQ29uZCA9PSBDb252b2x2ZU9wLkVER0VfTk9fT1ApIHsKKyAgICAgICAgICAgICAgICAvLyB0b3AKKyAgICAgICAgICAgICAgICBpbnQgc3RhcnQgPSAwOworICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSB5T3JpZ2luICogcm93TGVuZ3RoOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGl4ZWxzLCBzdGFydCwgbmV3UGl4ZWxzLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAvLyBib3R0b20KKyAgICAgICAgICAgICAgICBzdGFydCA9IChzcmNIZWlnaHQgLSAoa0hlaWdodCAtIHlPcmlnaW4gLSAxKSkgKiByb3dMZW5ndGg7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gKGtIZWlnaHQgLSB5T3JpZ2luIC0gMSkgKiByb3dMZW5ndGg7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwaXhlbHMsIHN0YXJ0LCBuZXdQaXhlbHMsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICAgICAgICAgIC8vIG1pZGRsZQorICAgICAgICAgICAgICAgIGxlbmd0aCA9IHhPcmlnaW4gKiBudW1CYW5kczsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoMSA9IChrV2lkdGggLSB4T3JpZ2luIC0gMSkgKiBudW1CYW5kczsKKyAgICAgICAgICAgICAgICBzdGFydCA9IHlPcmlnaW4gKiByb3dMZW5ndGg7CisgICAgICAgICAgICAgICAgaW50IHN0YXJ0MSA9ICh5T3JpZ2luICsgMSkgKiByb3dMZW5ndGggLSBsZW5ndGgxOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSB5T3JpZ2luOyBpIDwgKHNyY0hlaWdodCAtIChrSGVpZ2h0IC0geU9yaWdpbiAtIDEpKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGl4ZWxzLCBzdGFydCwgbmV3UGl4ZWxzLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwaXhlbHMsIHN0YXJ0MSwgbmV3UGl4ZWxzLCBzdGFydDEsIGxlbmd0aDEpOworICAgICAgICAgICAgICAgICAgICBzdGFydCArPSByb3dMZW5ndGg7CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0MSArPSByb3dMZW5ndGg7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEN5Y2xlIG92ZXIgcGl4ZWxzIHRvIGJlIGNhbGN1bGF0ZWQKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSB5T3JpZ2luOyBpIDwgc3JjQ29udk1heFk7IGkrKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4T3JpZ2luOyBqIDwgc3JjQ29udk1heFg7IGorKykgeworCisgICAgICAgICAgICAgICAgICAgIC8vIFRha2Uga2VybmVsIGRhdGEgaW4gYmFja3dhcmQgZGlyZWN0aW9uLCBjb252b2x1dGlvbgorICAgICAgICAgICAgICAgICAgICBpbnQga2VybmVsSWR4ID0gZGF0YS5sZW5ndGggLSAxOworCisgICAgICAgICAgICAgICAgICAgIGludCBwaXhlbEluZGV4ID0gaSAqIHJvd0xlbmd0aCArIGogKiBudW1CYW5kczsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaElkeCA9IDAsIHJhc3RlckhJZHggPSBpIC0geU9yaWdpbjsgaElkeCA8IGtIZWlnaHQ7IGhJZHgrKywgcmFzdGVySElkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCB3SWR4ID0gMCwgcmFzdGVyV0lkeCA9IGogLSB4T3JpZ2luOyB3SWR4IDwga1dpZHRoOyB3SWR4KyssIHJhc3RlcldJZHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjdXJJbmRleCA9IHJhc3RlckhJZHggKiByb3dMZW5ndGggKyByYXN0ZXJXSWR4ICogbnVtQmFuZHM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaWR4ID0gMDsgaWR4IDwgbnVtQmFuZHM7IGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1BpeGVsc1twaXhlbEluZGV4ICsgaWR4XSArPSBkYXRhW2tlcm5lbElkeF0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHBpeGVsc1tjdXJJbmRleCArIGlkeF07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlcm5lbElkeC0tOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93IG5vdworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpZHggPSAwOyBpZHggPCBudW1CYW5kczsgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKGludCluZXdQaXhlbHNbcGl4ZWxJbmRleCArIGlkeF0gJiBtYXNrc1tpZHhdKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1BpeGVsc1twaXhlbEluZGV4ICsgaWR4XSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGl4ZWxzW3BpeGVsSW5kZXggKyBpZHhdID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQaXhlbHNbcGl4ZWxJbmRleCArIGlkeF0gPSBtYXhWYWx1ZXNbaWR4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGRzdC5zZXRQaXhlbHMoZHN0TWluWCwgZHN0TWluWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgbmV3UGl4ZWxzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsgLy8gU29tZXRoaW5nIGdvZXMgd3JvbmcsIHNpZ25hbCBlcnJvcgorICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlcmVkSW1hZ2UgZmlsdGVyKEJ1ZmZlcmVkSW1hZ2Ugc3JjLCBCdWZmZXJlZEltYWdlIGRzdCkgeworICAgICAgICBpZiAoc3JjID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNTk9U291cmNlIGltYWdlIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNTkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzcmMgPT0gZHN0KSB7CisgICAgICAgICAgICAvLyBhd3QuMjVBPVNvdXJjZSBlcXVhbHMgdG8gZGVzdGluYXRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjVBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBDb2xvck1vZGVsIHNyY0NNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgQnVmZmVyZWRJbWFnZSBmaW5hbERzdCA9IG51bGw7CisKKyAgICAgICAgaWYgKHNyY0NNIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKSB7CisgICAgICAgICAgICBzcmMgPSAoKEluZGV4Q29sb3JNb2RlbClzcmNDTSkuY29udmVydFRvSW50RGlzY3JldGUoc3JjLmdldFJhc3RlcigpLCB0cnVlKTsKKyAgICAgICAgICAgIHNyY0NNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RJbWFnZShzcmMsIHNyY0NNKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICghc3JjQ00uZXF1YWxzKGRzdC5nZXRDb2xvck1vZGVsKCkpKSB7CisgICAgICAgICAgICAgICAgLy8gVHJlYXQgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0IgYW5kCisgICAgICAgICAgICAgICAgLy8gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCIGFzIHNhbWUKKyAgICAgICAgICAgICAgICBpZiAoISgoc3JjLmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQiB8fCBzcmMuZ2V0VHlwZSgpID09IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQikgJiYgKGRzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQiB8fCBkc3QuZ2V0VHlwZSgpID09IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQikpKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsRHN0ID0gZHN0OworICAgICAgICAgICAgICAgICAgICBkc3QgPSBjcmVhdGVDb21wYXRpYmxlRGVzdEltYWdlKHNyYywgc3JjQ00pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNraXAgYWxwaGEgY2hhbm5lbCBmb3IgVFlQRV9JTlRfUkdCIGltYWdlcworICAgICAgICAvLyBUT0RPCisgICAgICAgIC8vIGlmIChpcHBGaWx0ZXIoc3JjLmdldFJhc3RlcigpLCBkc3QuZ2V0UmFzdGVyKCksIHNyYy5nZXRUeXBlKCkpICE9IDApCisgICAgICAgIGlmIChzbG93RmlsdGVyKHNyYy5nZXRSYXN0ZXIoKSwgZHN0LmdldFJhc3RlcigpKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjFGPVVuYWJsZSB0byB0cmFuc2Zvcm0gc291cmNlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxRiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpbmFsRHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIEdyYXBoaWNzMkQgZyA9IGZpbmFsRHN0LmNyZWF0ZUdyYXBoaWNzKCk7CisgICAgICAgICAgICBnLnNldENvbXBvc2l0ZShBbHBoYUNvbXBvc2l0ZS5TcmMpOworICAgICAgICAgICAgZy5kcmF3SW1hZ2UoZHN0LCAwLCAwLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbmFsRHN0ID0gZHN0OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZpbmFsRHN0OworICAgIH0KKworICAgIC8vIFRPRE8gcmVtb3ZlIHdoZW4gdGhpcyBtZXRob2QgaXMgdXNlZAorICAgIC8qKgorICAgICAqIElwcCBmaWx0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0eXBlLgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIGludCBpcHBGaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0LCBpbnQgaW1hZ2VUeXBlKSB7CisgICAgICAgIGludCBzcmNTdHJpZGUsIGRzdFN0cmlkZTsKKyAgICAgICAgYm9vbGVhbiBza2lwQ2hhbm5lbCA9IGZhbHNlOworICAgICAgICBpbnQgY2hhbm5lbHM7CisgICAgICAgIGludCBvZmZzZXRzW10gPSBudWxsOworCisgICAgICAgIHN3aXRjaCAoaW1hZ2VUeXBlKSB7CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0JHUjogeworICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcmMuZ2V0V2lkdGgoKSAqIDQ7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIHNraXBDaGFubmVsID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQl9QUkU6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV80QllURV9BQkdSOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfNEJZVEVfQUJHUl9QUkU6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDQ7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogNDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfQllURV9HUkFZOiB7CisgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSAxOworICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNyYy5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV8zQllURV9CR1I6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDM7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiAzOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogMzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUX0dSQVk6IC8vIFRPRE8gLSBjb3VsZCBiZSBkb25lIGluCisgICAgICAgICAgICAgICAgLy8gbmF0aXZlIGNvZGU/CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9VU0hPUlRfNTY1X1JHQjoKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF81NTVfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfQllURV9CSU5BUlk6IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgICAgICBTYW1wbGVNb2RlbCBzcmNTTSA9IHNyYy5nZXRTYW1wbGVNb2RlbCgpOworICAgICAgICAgICAgICAgIFNhbXBsZU1vZGVsIGRzdFNNID0gZHN0LmdldFNhbXBsZU1vZGVsKCk7CisKKyAgICAgICAgICAgICAgICBpZiAoc3JjU00gaW5zdGFuY2VvZiBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGRzdFNNIGluc3RhbmNlb2YgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgICAgICAgICBpZiAoc3JjU00uZ2V0RGF0YVR5cGUoKSAhPSBEYXRhQnVmZmVyLlRZUEVfQllURQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGRzdFNNLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gc3JjU00uZ2V0TnVtQmFuZHMoKTsgLy8gSGF2ZSBJUFAgZnVuY3Rpb25zIGZvciAxLAorICAgICAgICAgICAgICAgICAgICAvLyAzIGFuZCA0IGNoYW5uZWxzCisgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYW5uZWxzID09IDEgfHwgY2hhbm5lbHMgPT0gMyB8fCBjaGFubmVscyA9PSA0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gKChDb21wb25lbnRTYW1wbGVNb2RlbClzcmNTTSkuZ2V0U2NhbmxpbmVTdHJpZGUoKTsKKyAgICAgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gKChDb21wb25lbnRTYW1wbGVNb2RlbClkc3RTTSkuZ2V0U2NhbmxpbmVTdHJpZGUoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNyY1NNIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgZHN0U00gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbTEgPSAoU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbClzcmNTTTsKKyAgICAgICAgICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbTIgPSAoU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbClkc3RTTTsKKworICAgICAgICAgICAgICAgICAgICBjaGFubmVscyA9IHNwcHNtMS5nZXROdW1CYW5kcygpOworCisgICAgICAgICAgICAgICAgICAgIC8vIFRZUEVfSU5UX1JHQiwgVFlQRV9JTlRfQVJHQi4uLgorICAgICAgICAgICAgICAgICAgICBpZiAoc3Bwc20xLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHNwcHNtMi5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9JTlQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAhKGNoYW5uZWxzID09IDMgfHwgY2hhbm5lbHMgPT0gNCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGNvbXBhdGliaWxpdHkgb2Ygc2FtcGxlIG1vZGVscworICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMoc3Bwc20xLmdldEJpdE9mZnNldHMoKSwgc3Bwc20yLmdldEJpdE9mZnNldHMoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAhQXJyYXlzLmVxdWFscyhzcHBzbTEuZ2V0Qml0TWFza3MoKSwgc3Bwc20yLmdldEJpdE1hc2tzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcHBzbTEuZ2V0U2FtcGxlU2l6ZShpKSAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNoYW5uZWxzID09IDMpIHsgLy8gQ2Fubm90IHNraXAgY2hhbm5lbCwgZG9uJ3Qga25vdworICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggaXMgYWxwaGEuLi4KKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNwcHNtMS5nZXRTY2FubGluZVN0cmlkZSgpICogNDsKKyAgICAgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gc3Bwc20yLmdldFNjYW5saW5lU3RyaWRlKCkgKiA0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBGaWxsIG9mZnNldHMgaWYgdGhlcmUncyBhIGNoaWxkIHJhc3RlcgorICAgICAgICAgICAgICAgIGlmIChzcmMuZ2V0UGFyZW50KCkgIT0gbnVsbCB8fCBkc3QuZ2V0UGFyZW50KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICE9IDAgfHwgc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICE9IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBkc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVkoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzID0gbmV3IGludFs0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMF0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICsgc3JjLmdldE1pblgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMV0gPSAtc3JjLmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgc3JjLmdldE1pblkoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbMl0gPSAtZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpICsgZHN0LmdldE1pblgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbM10gPSAtZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICsgZHN0LmdldE1pblkoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIE9iamVjdCBzcmNEYXRhLCBkc3REYXRhOworICAgICAgICBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IgZGJBY2Nlc3MgPSBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyY0RhdGEgPSBkYkFjY2Vzcy5nZXREYXRhKHNyYy5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICAgICAgZHN0RGF0YSA9IGRiQWNjZXNzLmdldERhdGEoZHN0LmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7IC8vIFVua25vd24gZGF0YSBidWZmZXIgdHlwZQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGlwcEZpbHRlcjMyZihrZXJuZWwuZGF0YSwga2VybmVsLmdldFdpZHRoKCksIGtlcm5lbC5nZXRIZWlnaHQoKSwKKyAgICAgICAgICAgICAgICBrZXJuZWwuZ2V0WE9yaWdpbigpLCBrZXJuZWwuZ2V0WU9yaWdpbigpLCBlZGdlQ29uZCwgc3JjRGF0YSwgc3JjLmdldFdpZHRoKCksIHNyYworICAgICAgICAgICAgICAgICAgICAgICAgLmdldEhlaWdodCgpLCBzcmNTdHJpZGUsIGRzdERhdGEsIGRzdC5nZXRXaWR0aCgpLCBkc3QuZ2V0SGVpZ2h0KCksCisgICAgICAgICAgICAgICAgZHN0U3RyaWRlLCBjaGFubmVscywgc2tpcENoYW5uZWwsIG9mZnNldHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElwcCBmaWx0ZXIzMmYuCisgICAgICogCisgICAgICogQHBhcmFtIGtlcm5lbAorICAgICAqICAgICAgICAgICAgdGhlIGtlcm5lbC4KKyAgICAgKiBAcGFyYW0ga1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgayB3aWR0aC4KKyAgICAgKiBAcGFyYW0ga0hlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGsgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBhbmNob3JYCisgICAgICogICAgICAgICAgICB0aGUgYW5jaG9yIHguCisgICAgICogQHBhcmFtIGFuY2hvclkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbmNob3IgeS4KKyAgICAgKiBAcGFyYW0gYm9yZGVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGJvcmRlciB0eXBlLgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIHNyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgc3JjIHdpZHRoLgorICAgICAqIEBwYXJhbSBzcmNIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBzcmNTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgc3RyaWRlLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHBhcmFtIGRzdFdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgZHN0IHdpZHRoLgorICAgICAqIEBwYXJhbSBkc3RIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBkc3RTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3Qgc3RyaWRlLgorICAgICAqIEBwYXJhbSBjaGFubmVscworICAgICAqICAgICAgICAgICAgdGhlIGNoYW5uZWxzLgorICAgICAqIEBwYXJhbSBza2lwQ2hhbm5lbAorICAgICAqICAgICAgICAgICAgdGhlIHNraXAgY2hhbm5lbC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldHMuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgbmF0aXZlIGludCBpcHBGaWx0ZXIzMmYoZmxvYXQga2VybmVsW10sIGludCBrV2lkdGgsIGludCBrSGVpZ2h0LCBpbnQgYW5jaG9yWCwKKyAgICAgICAgICAgIGludCBhbmNob3JZLCBpbnQgYm9yZGVyVHlwZSwgT2JqZWN0IHNyYywgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LCBpbnQgc3JjU3RyaWRlLAorICAgICAgICAgICAgT2JqZWN0IGRzdCwgaW50IGRzdFdpZHRoLCBpbnQgZHN0SGVpZ2h0LCBpbnQgZHN0U3RyaWRlLCBpbnQgY2hhbm5lbHMsCisgICAgICAgICAgICBib29sZWFuIHNraXBDaGFubmVsLCBpbnQgb2Zmc2V0c1tdKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9Dcm9wSW1hZ2VGaWx0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Dcm9wSW1hZ2VGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjRjYTc4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0Nyb3BJbWFnZUZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMTk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKKy8qKgorICogVGhlIENyb3BJbWFnZUZpbHRlciBjbGFzcyBjcm9wcyBhIHJlY3Rhbmd1bGFyIHJlZ2lvbiBvZiBhbiBzb3VyY2UgSW1hZ2UgYW5kCisgKiBwcm92aWRlcyBhIHNvdXJjZSBmb3IgYSBuZXcgaW1hZ2UgY29udGFpbmluZyB0aGUgZXh0cmFjdGVkIHJlZ2lvbi4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBDcm9wSW1hZ2VGaWx0ZXIgZXh0ZW5kcyBJbWFnZUZpbHRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSEVJR0hULgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IFgsIFksIFdJRFRILCBIRUlHSFQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQ3JvcEltYWdlRmlsdGVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIKKyAgICAgKiBhcmVhLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ3JvcEltYWdlRmlsdGVyKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7CisgICAgICAgIFggPSB4OworICAgICAgICBZID0geTsKKyAgICAgICAgV0lEVEggPSB3OworICAgICAgICBIRUlHSFQgPSBoOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnRpZXMoSGFzaHRhYmxlPD8sID8+IHByb3BzKSB7CisgICAgICAgIEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4gZnByb3BzOworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCkgeworICAgICAgICAgICAgZnByb3BzID0gbmV3IEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZwcm9wcyA9IChIYXNodGFibGU8T2JqZWN0LCBPYmplY3Q+KXByb3BzLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gIkNyb3AgRmlsdGVycyI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIHByb3AgPSAieD0iICsgWCArICI7IHk9IiArIFkgKyAiOyB3aWR0aD0iICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgICAgICAgICBXSURUSCArICI7IGhlaWdodD0iICsgSEVJR0hUOyAvLyROT04tTkxTLTEkCisgICAgICAgIE9iamVjdCBvID0gZnByb3BzLmdldChwcm9wTmFtZSk7CisgICAgICAgIGlmIChvICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChvIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICAgICAgcHJvcCA9IChTdHJpbmcpbyArICI7ICIgKyBwcm9wOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHByb3AgPSBvLnRvU3RyaW5nKCkgKyAiOyAiICsgcHJvcDsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZwcm9wcy5wdXQocHJvcE5hbWUsIHByb3ApOworICAgICAgICBjb25zdW1lci5zZXRQcm9wZXJ0aWVzKGZwcm9wcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBDb2xvck1vZGVsIG1vZGVsLCBpbnRbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKworICAgICAgICBpZiAoeCArIHcgPCBYIHx8IFggKyBXSURUSCA8IHggfHwgeSArIGggPCBZIHx8IFkgKyBIRUlHSFQgPCB5KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgZGVzdFgsIGRlc3RZLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGVuZFgsIGVuZFksIHNyY0VuZFgsIHNyY0VuZFk7CisKKyAgICAgICAgaW50IG5ld09mZnNldCA9IG9mZjsKKworICAgICAgICBlbmRYID0gWCArIFdJRFRIOworICAgICAgICBlbmRZID0gWSArIEhFSUdIVDsKKworICAgICAgICBzcmNFbmRYID0geCArIHc7CisgICAgICAgIHNyY0VuZFkgPSB5ICsgaDsKKworICAgICAgICBpZiAoeCA8PSBYKSB7CisgICAgICAgICAgICBkZXN0WCA9IDA7CisgICAgICAgICAgICBuZXdPZmZzZXQgKz0gWDsKKyAgICAgICAgICAgIGlmIChlbmRYID49IHNyY0VuZFgpIHsKKyAgICAgICAgICAgICAgICBkZXN0V2lkdGggPSBzcmNFbmRYIC0gWDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGVzdFdpZHRoID0gV0lEVEg7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkZXN0WCA9IHggLSBYOworICAgICAgICAgICAgaWYgKGVuZFggPj0gc3JjRW5kWCkgeworICAgICAgICAgICAgICAgIGRlc3RXaWR0aCA9IHc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlc3RXaWR0aCA9IGVuZFggLSB4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHkgPD0gWSkgeworICAgICAgICAgICAgbmV3T2Zmc2V0ICs9IHNjYW5zaXplICogKFkgLSB5KTsKKyAgICAgICAgICAgIGRlc3RZID0gMDsKKyAgICAgICAgICAgIGlmIChlbmRZID49IHNyY0VuZFkpIHsKKyAgICAgICAgICAgICAgICBkZXN0SGVpZ2h0ID0gc3JjRW5kWSAtIFk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlc3RIZWlnaHQgPSBIRUlHSFQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkZXN0WSA9IHkgLSBZOworICAgICAgICAgICAgaWYgKGVuZFkgPj0gc3JjRW5kWSkgeworICAgICAgICAgICAgICAgIGRlc3RIZWlnaHQgPSBoOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZXN0SGVpZ2h0ID0gZW5kWSAtIHk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKGRlc3RYLCBkZXN0WSwgZGVzdFdpZHRoLCBkZXN0SGVpZ2h0LCBtb2RlbCwgcGl4ZWxzLCBuZXdPZmZzZXQsIHNjYW5zaXplKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGVbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKworICAgICAgICBpZiAoeCArIHcgPCBYIHx8IFggKyBXSURUSCA8IHggfHwgeSArIGggPCBZIHx8IFkgKyBIRUlHSFQgPCB5KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgZGVzdFgsIGRlc3RZLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGVuZFgsIGVuZFksIHNyY0VuZFgsIHNyY0VuZFk7CisKKyAgICAgICAgaW50IG5ld09mZnNldCA9IG9mZjsKKworICAgICAgICBlbmRYID0gWCArIFdJRFRIOworICAgICAgICBlbmRZID0gWSArIEhFSUdIVDsKKworICAgICAgICBzcmNFbmRYID0geCArIHc7CisgICAgICAgIHNyY0VuZFkgPSB5ICsgaDsKKworICAgICAgICBpZiAoeCA8PSBYKSB7CisgICAgICAgICAgICBkZXN0WCA9IDA7CisgICAgICAgICAgICBuZXdPZmZzZXQgKz0gWDsKKyAgICAgICAgICAgIGlmIChlbmRYID49IHNyY0VuZFgpIHsKKyAgICAgICAgICAgICAgICBkZXN0V2lkdGggPSBzcmNFbmRYIC0gWDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGVzdFdpZHRoID0gV0lEVEg7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkZXN0WCA9IHggLSBYOworICAgICAgICAgICAgaWYgKGVuZFggPj0gc3JjRW5kWCkgeworICAgICAgICAgICAgICAgIGRlc3RXaWR0aCA9IHc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlc3RXaWR0aCA9IGVuZFggLSB4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHkgPD0gWSkgeworICAgICAgICAgICAgbmV3T2Zmc2V0ICs9IHNjYW5zaXplICogKFkgLSB5KTsKKyAgICAgICAgICAgIGRlc3RZID0gMDsKKyAgICAgICAgICAgIGlmIChlbmRZID49IHNyY0VuZFkpIHsKKyAgICAgICAgICAgICAgICBkZXN0SGVpZ2h0ID0gc3JjRW5kWSAtIFk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlc3RIZWlnaHQgPSBIRUlHSFQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkZXN0WSA9IHkgLSBZOworICAgICAgICAgICAgaWYgKGVuZFkgPj0gc3JjRW5kWSkgeworICAgICAgICAgICAgICAgIGRlc3RIZWlnaHQgPSBoOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZXN0SGVpZ2h0ID0gZW5kWSAtIHk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKGRlc3RYLCBkZXN0WSwgZGVzdFdpZHRoLCBkZXN0SGVpZ2h0LCBtb2RlbCwgcGl4ZWxzLCBuZXdPZmZzZXQsIHNjYW5zaXplKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREaW1lbnNpb25zKGludCB3LCBpbnQgaCkgeworICAgICAgICBjb25zdW1lci5zZXREaW1lbnNpb25zKFdJRFRILCBIRUlHSFQpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJmOTAwZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyLmphdmEKQEAgLTAsMCArMSw0ODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5EYXRhQnVmZmVyTGlzdGVuZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIERhdGFCdWZmZXIgaXMgYSB3cmFwcGVyIGNsYXNzIGZvciBhIGRhdGEgYXJyYXkgdG8gYmUgdXNlZCBmb3IgdGhlCisgKiBzaXR1YXRpb24gd2hlcmUgYSBzdWl0ZSBvZiBmdW5jdGlvbmFsaXR5IGFjdHMgb24gYSBzZXQgb2YgZGF0YSBpbiBhCisgKiBjb25zaXN0ZW50IHdheSBldmVuIHRob3VnaCB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGRhdGEgbWF5IHZhcnkgZnJvbSBvbmUKKyAqIHVzZSB0byB0aGUgbmV4dC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEYXRhQnVmZmVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0JZVEUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9CWVRFID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX1VTSE9SVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1VTSE9SVCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9TSE9SVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX1NIT1JUID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0lOVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0lOVCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9GTE9BVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZMT0FUID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBUWVBFX0RPVUJMRS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0RPVUJMRSA9IDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVFlQRV9VTkRFRklORUQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9VTkRFRklORUQgPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhIHR5cGUgaW5kaWNhdGVzIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZGF0YSBpbiB0aGlzCisgICAgICogRGF0YUJ1ZmZlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGRhdGFUeXBlOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBkYXRhIGFycmF5cyBpbiB0aGlzIERhdGFCdWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBiYW5rczsKKworICAgIC8qKgorICAgICAqIFRoZSBzdGFydGluZyBpbmRleCBmb3IgcmVhZGluZyB0aGUgZGF0YSBmcm9tIHRoZSBmaXJzdCAob3Igb25seSkgaW50ZXJuYWwKKyAgICAgKiBkYXRhIGFycmF5LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgb2Zmc2V0OworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSBvZiB0aGUgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzaXplOworCisgICAgLyoqCisgICAgICogVGhlIHN0YXJ0aW5nIGluZGljZXMgZm9yIHJlYWRpbmcgdGhlIGRhdGEgZnJvbSB0aGUgaW50ZXJuYWwgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBvZmZzZXRzW107CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGF0YSBjaGFuZ2VkLgorICAgICAqLworICAgIGJvb2xlYW4gZGF0YUNoYW5nZWQgPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEgdGFrZW4uCisgICAgICovCisgICAgYm9vbGVhbiBkYXRhVGFrZW4gPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSBsaXN0ZW5lci4KKyAgICAgKi8KKyAgICBEYXRhQnVmZmVyTGlzdGVuZXIgbGlzdGVuZXI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3JJbXBsLmluaXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIG9mIHRoZSBkYXRhIGFycmF5cy4KKyAgICAgKiBAcGFyYW0gbnVtQmFua3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGF0YSBhcnJheXMgdG8gY3JlYXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgaW5kaWNlcyBmb3IgcmVhZGluZyB0aGUgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbAorICAgICAqICAgICAgICAgICAgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGFCdWZmZXIoaW50IGRhdGFUeXBlLCBpbnQgc2l6ZSwgaW50IG51bUJhbmtzLCBpbnRbXSBvZmZzZXRzKSB7CisgICAgICAgIHRoaXMuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICAgICAgdGhpcy5iYW5rcyA9IG51bUJhbmtzOworICAgICAgICB0aGlzLm9mZnNldHMgPSBvZmZzZXRzLmNsb25lKCk7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0c1swXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgd2l0aCBhbGwgb2YgdGhlIGRhdGEgYXJyYXlzIHN0YXJ0aW5nIGF0CisgICAgICogdGhlIHNhbWUgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIG9mIHRoZSBkYXRhIGFycmF5cy4KKyAgICAgKiBAcGFyYW0gbnVtQmFua3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGF0YSBhcnJheXMgdG8gY3JlYXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdG8gdXNlIGZvciBhbGwgb2YgdGhlIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHByb3RlY3RlZCBEYXRhQnVmZmVyKGludCBkYXRhVHlwZSwgaW50IHNpemUsIGludCBudW1CYW5rcywgaW50IG9mZnNldCkgeworICAgICAgICB0aGlzLmRhdGFUeXBlID0gZGF0YVR5cGU7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgICAgIHRoaXMuYmFua3MgPSBudW1CYW5rczsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMub2Zmc2V0cyA9IG5ldyBpbnRbbnVtQmFua3NdOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChpIDwgbnVtQmFua3MpIHsKKyAgICAgICAgICAgIG9mZnNldHNbaSsrXSA9IG9mZnNldDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciB3aXRoIGFsbCBvZiB0aGUgZGF0YSBhcnJheXMgcmVhZCBmcm9tIHRoZQorICAgICAqIGJlZ2lubmluZyAoYXQgb2Zmc2V0IHplcm8pLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSBvZiB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG51bUJhbmtzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRhdGEgYXJyYXlzIHRvIGNyZWF0ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGF0YUJ1ZmZlcihpbnQgZGF0YVR5cGUsIGludCBzaXplLCBpbnQgbnVtQmFua3MpIHsKKyAgICAgICAgdGhpcy5kYXRhVHlwZSA9IGRhdGFUeXBlOworICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgICAgICB0aGlzLmJhbmtzID0gbnVtQmFua3M7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgdGhpcy5vZmZzZXRzID0gbmV3IGludFtudW1CYW5rc107CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIHdpdGggb25lIGludGVybmFsIGRhdGEgYXJyYXkgcmVhZCBmcm9tIHRoZQorICAgICAqIGJlZ2lubmluZyAoYXQgb2Zmc2V0IHplcm8pLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSBvZiB0aGUgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGFCdWZmZXIoaW50IGRhdGFUeXBlLCBpbnQgc2l6ZSkgeworICAgICAgICB0aGlzLmRhdGFUeXBlID0gZGF0YVR5cGU7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgICAgIHRoaXMuYmFua3MgPSAxOworICAgICAgICB0aGlzLm9mZnNldCA9IDA7CisgICAgICAgIHRoaXMub2Zmc2V0cyA9IG5ldyBpbnRbMV07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGJhbmsKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlcm5hbCBhcnJheSB0byB0aGUgZGF0YSB0by4KKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJyYXkgd2hlcmUgdGhlIGRhdGEgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHdyaXRlIGludG8gdGhlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVsZW0oaW50IGJhbmssIGludCBpLCBpbnQgdmFsKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsb2F0IGRhdGEgdmFsdWUgaW4gdGhlIHNwZWNpZmllZCBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgaW50ZXJuYWwgYXJyYXkgdG8gdGhlIGRhdGEgdG8uCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3cml0ZSBpbnRvIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtRmxvYXQoaW50IGJhbmssIGludCBpLCBmbG9hdCB2YWwpIHsKKyAgICAgICAgc2V0RWxlbShiYW5rLCBpLCAoaW50KXZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZG91YmxlIGRhdGEgdmFsdWUgaW4gdGhlIHNwZWNpZmllZCBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgaW50ZXJuYWwgYXJyYXkgdG8gdGhlIGRhdGEgdG8uCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3cml0ZSBpbnRvIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtRG91YmxlKGludCBiYW5rLCBpbnQgaSwgZG91YmxlIHZhbCkgeworICAgICAgICBzZXRFbGVtKGJhbmssIGksIChpbnQpdmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIHZhbHVlIGluIHRoZSBmaXJzdCBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggd2l0aGluIHRoZSBhcnJheSB3aGVyZSB0aGUgZGF0YSBzaG91bGQgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gd3JpdGUgaW50byB0aGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RWxlbShpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBzZXRFbGVtKDAsIGksIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGF0YSB2YWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgZGF0YSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0byByZWFkIGZyb20uCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEVsZW0oaW50IGJhbmssIGludCBpKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZsb2F0LXR5cGUgZGF0YSB2YWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgZGF0YSBhcnJheSBhdCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGJhbmsKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIHJlYWQgZnJvbS4KKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJyYXkgd2hlcmUgdGhlIGRhdGEgc2hvdWxkIGJlIHJlYWQuCisgICAgICogQHJldHVybiB0aGUgZGF0YSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRFbGVtRmxvYXQoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiBnZXRFbGVtKGJhbmssIGkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRvdWJsZS10eXBlIGRhdGEgdmFsdWUgZnJvbSB0aGUgc3BlY2lmaWVkIGRhdGEgYXJyYXkgYXQgdGhlCisgICAgICogc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0byByZWFkIGZyb20uCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldEVsZW1Eb3VibGUoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiBnZXRFbGVtKGJhbmssIGkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsb2F0IGRhdGEgdmFsdWUgaW4gdGhlIGZpcnN0IGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3cml0ZSBpbnRvIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtRmxvYXQoaW50IGksIGZsb2F0IHZhbCkgeworICAgICAgICBzZXRFbGVtRmxvYXQoMCwgaSwgdmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkb3VibGUgZGF0YSB2YWx1ZSBpbiB0aGUgZmlyc3QgYXJyYXkgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJyYXkgd2hlcmUgdGhlIGRhdGEgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHdyaXRlIGludG8gdGhlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVsZW1Eb3VibGUoaW50IGksIGRvdWJsZSB2YWwpIHsKKyAgICAgICAgc2V0RWxlbURvdWJsZSgwLCBpLCB2YWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgdmFsdWUgZnJvbSB0aGUgZmlyc3QgZGF0YSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAorICAgICAqIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJyYXkgd2hlcmUgdGhlIGRhdGEgc2hvdWxkIGJlIHJlYWQuCisgICAgICogQHJldHVybiB0aGUgZGF0YSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgaSkgeworICAgICAgICByZXR1cm4gZ2V0RWxlbSgwLCBpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIHZhbHVlIGZyb20gdGhlIGZpcnN0IGRhdGEgYXJyYXkgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBhbmQKKyAgICAgKiByZXR1cm5zIGl0IGFzIGEgZmxvYXQuCisgICAgICogCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0RWxlbUZsb2F0KGludCBpKSB7CisgICAgICAgIHJldHVybiBnZXRFbGVtKDAsIGkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgdmFsdWUgZnJvbSB0aGUgZmlyc3QgZGF0YSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAorICAgICAqIHJldHVybnMgaXQgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFycmF5IHdoZXJlIHRoZSBkYXRhIHNob3VsZCBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldEVsZW1Eb3VibGUoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGdldEVsZW0oaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXJyYXkgZ2l2aW5nIHRoZSBvZmZzZXRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGludGVybmFsIGRhdGEKKyAgICAgKiBhcnJheXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2Ygb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0T2Zmc2V0cygpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBpbiBiaXRzIG9mIHRoZSBwcmltaXRpdmUgZGF0YSB0eXBlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNpemUgaW4gYml0cyBvZiB0aGUgcHJpbWl0aXZlIGRhdGEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaXJzdCBpbnRlcm5hbCBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgZGF0YSBhcnJheXMgaW4gdGhpcyBEYXRhQnVmZmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBkYXRhIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bUJhbmtzKCkgeworICAgICAgICByZXR1cm4gYmFua3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhpcyBidWZmZXIncyBkYXRhLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERhdGFUeXBlKCkgeworICAgICAgICByZXR1cm4gdGhpcy5kYXRhVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzaXplIGluIGJpdHMgb2YgdGhlIHByaW1pdGl2ZSBkYXRhIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltaXRpdmUgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIGluIGJpdHMgb2YgdGhlIHByaW1pdGl2ZSBkYXRhIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RGF0YVR5cGVTaXplKGludCB0eXBlKSB7CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworCisgICAgICAgICAgICBjYXNlIFRZUEVfQllURToKKyAgICAgICAgICAgICAgICByZXR1cm4gODsKKworICAgICAgICAgICAgY2FzZSBUWVBFX1VTSE9SVDoKKyAgICAgICAgICAgIGNhc2UgVFlQRV9TSE9SVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gMTY7CisKKyAgICAgICAgICAgIGNhc2UgVFlQRV9JTlQ6CisgICAgICAgICAgICBjYXNlIFRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIDMyOworCisgICAgICAgICAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIHJldHVybiA2NDsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjJDPVVua25vd24gZGF0YSB0eXBlIHswfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJDIiwgdHlwZSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGUgbGlzdGVuZXIgdGhhdCB0aGUgZGF0YSBoYXMgY2hhbmdlZC4KKyAgICAgKi8KKyAgICB2b2lkIG5vdGlmeUNoYW5nZWQoKSB7CisgICAgICAgIGlmIChsaXN0ZW5lciAhPSBudWxsICYmICFkYXRhQ2hhbmdlZCkgeworICAgICAgICAgICAgZGF0YUNoYW5nZWQgPSB0cnVlOworICAgICAgICAgICAgbGlzdGVuZXIuZGF0YUNoYW5nZWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoZSBsaXN0ZW5lciB0aGF0IHRoZSBkYXRhIGhhcyBiZWVuIHJlbGVhc2VkLgorICAgICAqLworICAgIHZvaWQgbm90aWZ5VGFrZW4oKSB7CisgICAgICAgIGlmIChsaXN0ZW5lciAhPSBudWxsICYmICFkYXRhVGFrZW4pIHsKKyAgICAgICAgICAgIGRhdGFUYWtlbiA9IHRydWU7CisgICAgICAgICAgICBsaXN0ZW5lci5kYXRhVGFrZW4oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbGVhc2UgdGhlIGRhdGEuCisgICAgICovCisgICAgdm9pZCByZWxlYXNlRGF0YSgpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwgJiYgZGF0YVRha2VuKSB7CisgICAgICAgICAgICBkYXRhVGFrZW4gPSBmYWxzZTsKKyAgICAgICAgICAgIGxpc3RlbmVyLmRhdGFSZWxlYXNlZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgZGF0YSBidWZmZXIgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICogICAgICAgICAgICB0aGUgbGlzdGVuZXIuCisgICAgICovCisgICAgdm9pZCBhZGREYXRhQnVmZmVyTGlzdGVuZXIoRGF0YUJ1ZmZlckxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHRoaXMubGlzdGVuZXIgPSBsaXN0ZW5lcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBkYXRhIGJ1ZmZlciBsaXN0ZW5lci4KKyAgICAgKi8KKyAgICB2b2lkIHJlbW92ZURhdGFCdWZmZXJMaXN0ZW5lcigpIHsKKyAgICAgICAgbGlzdGVuZXIgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlLgorICAgICAqLworICAgIHZvaWQgdmFsaWRhdGUoKSB7CisgICAgICAgIGRhdGFDaGFuZ2VkID0gZmFsc2U7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvRGF0YUJ1ZmZlckJ5dGUuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyQnl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MDdkZTgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvRGF0YUJ1ZmZlckJ5dGUuamF2YQpAQCAtMCwwICsxLDE4MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKKy8qKgorICogVGhlIENsYXNzIERhdGFCdWZmZXJCeXRlIGlzIHRoZSBzdWJjbGFzcyBvZiBEYXRhQnVmZmVyIGZvciB0aGUgY2FzZSB3aGVyZSB0aGUKKyAqIHVuZGVybHlpbmcgZGF0YSBpcyBvZiB0eXBlIGJ5dGUuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRGF0YUJ1ZmZlckJ5dGUgZXh0ZW5kcyBEYXRhQnVmZmVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhLgorICAgICAqLworICAgIGJ5dGUgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSB1bnNpZ25lZCBzaG9ydC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5cworICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXlzIHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBpbmRpY2VzIGZvciByZWFkaW5nIHRoZSBkYXRhIGZyb20gdGhlIGludGVybmFsCisgICAgICogICAgICAgICAgICBkYXRhIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlckJ5dGUoYnl0ZSBkYXRhQXJyYXlzW11bXSwgaW50IHNpemUsIGludCBvZmZzZXRzW10pIHsKKyAgICAgICAgc3VwZXIoVFlQRV9CWVRFLCBzaXplLCBkYXRhQXJyYXlzLmxlbmd0aCwgb2Zmc2V0cyk7CisgICAgICAgIGRhdGEgPSBkYXRhQXJyYXlzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyQnl0ZShieXRlIGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX0JZVEUsIHNpemUsIGRhdGFBcnJheXMubGVuZ3RoKTsKKyAgICAgICAgZGF0YSA9IGRhdGFBcnJheXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSB1bnNpZ25lZCBzaG9ydCB3aXRoIGEgc2luZ2xlCisgICAgICogdW5kZXJseWluZyBhcnJheSBvZiBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGV4IHRvIHVzZSB3aGVuIHJlYWRpbmcgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJCeXRlKGJ5dGUgZGF0YUFycmF5W10sIGludCBzaXplLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKFRZUEVfQllURSwgc2l6ZSwgMSwgb2Zmc2V0KTsKKyAgICAgICAgZGF0YSA9IG5ldyBieXRlWzFdW107CisgICAgICAgIGRhdGFbMF0gPSBkYXRhQXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQgd2l0aCBhIHNpbmdsZQorICAgICAqIHVuZGVybHlpbmcgYXJyYXkgb2YgZGF0YSBzdGFydGluZyBhdCBpbmRleCAwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJCeXRlKGJ5dGUgZGF0YUFycmF5W10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfQllURSwgc2l6ZSk7CisgICAgICAgIGRhdGEgPSBuZXcgYnl0ZVsxXVtdOworICAgICAgICBkYXRhWzBdID0gZGF0YUFycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBlbXB0eSBkYXRhIGJ1ZmZlciBvZiB0eXBlIHVuc2lnbmVkIHNob3J0IHdpdGggb2Zmc2V0cworICAgICAqIGVxdWFsIHRvIHplcm8uCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqIEBwYXJhbSBudW1CYW5rcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkYXRhIGFycmF5cyB0byBjcmVhdGUuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJCeXRlKGludCBzaXplLCBpbnQgbnVtQmFua3MpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9CWVRFLCBzaXplLCBudW1CYW5rcyk7CisgICAgICAgIGRhdGEgPSBuZXcgYnl0ZVtudW1CYW5rc11bXTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoaSA8IG51bUJhbmtzKSB7CisgICAgICAgICAgICBkYXRhW2krK10gPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBlbXB0eSBkYXRhIGJ1ZmZlciBvZiB0eXBlIHVuc2lnbmVkIHNob3J0IHdpdGggYSBzaW5nbGUKKyAgICAgKiB1bmRlcmx5aW5nIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJCeXRlKGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfQllURSwgc2l6ZSk7CisgICAgICAgIGRhdGEgPSBuZXcgYnl0ZVsxXVtdOworICAgICAgICBkYXRhWzBdID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbShpbnQgYmFuaywgaW50IGksIGludCB2YWwpIHsKKyAgICAgICAgZGF0YVtiYW5rXVtvZmZzZXRzW2JhbmtdICsgaV0gPSAoYnl0ZSl2YWw7CisgICAgICAgIG5vdGlmeUNoYW5nZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBpLCBpbnQgdmFsKSB7CisgICAgICAgIGRhdGFbMF1bb2Zmc2V0ICsgaV0gPSAoYnl0ZSl2YWw7CisgICAgICAgIG5vdGlmeUNoYW5nZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEVsZW0oaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiAoZGF0YVtiYW5rXVtvZmZzZXRzW2JhbmtdICsgaV0pICYgMHhmZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgaW50ZXJuYWwgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmFuaworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBkZXNpcmVkIGRhdGEgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoaW50IGJhbmspIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbYmFua107CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBpKSB7CisgICAgICAgIHJldHVybiAoZGF0YVswXVtvZmZzZXQgKyBpXSkgJiAweGZmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJhbmsgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBiYW5rIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXVtdIGdldEJhbmtEYXRhKCkgeworICAgICAgICBub3RpZnlUYWtlbigpOworICAgICAgICByZXR1cm4gZGF0YS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIGZpcnN0IGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoKSB7CisgICAgICAgIG5vdGlmeVRha2VuKCk7CisgICAgICAgIHJldHVybiBkYXRhWzBdOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJEb3VibGUuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyRG91YmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQwYTUxNgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyRG91YmxlLmphdmEKQEAgLTAsMCArMSwyMjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBDbGFzcyBEYXRhQnVmZmVyRG91YmxlIGlzIHRoZSBzdWJjbGFzcyBvZiBEYXRhQnVmZmVyIGZvciB0aGUgY2FzZSB3aGVyZQorICogdGhlIHVuZGVybHlpbmcgZGF0YSBpcyBvZiB0eXBlIGRvdWJsZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEYXRhQnVmZmVyRG91YmxlIGV4dGVuZHMgRGF0YUJ1ZmZlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGF0YS4KKyAgICAgKi8KKyAgICBkb3VibGUgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBkb3VibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqIEBwYXJhbSBvZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgaW5kaWNlcyBmb3IgcmVhZGluZyB0aGUgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbAorICAgICAqICAgICAgICAgICAgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoZG91YmxlIGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSwgaW50IG9mZnNldHNbXSkgeworICAgICAgICBzdXBlcihUWVBFX0RPVUJMRSwgc2l6ZSwgZGF0YUFycmF5cy5sZW5ndGgsIG9mZnNldHMpOworICAgICAgICBkYXRhID0gZGF0YUFycmF5cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciBvZiB0eXBlIGRvdWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5cworICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXlzIHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoZG91YmxlIGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX0RPVUJMRSwgc2l6ZSwgZGF0YUFycmF5cy5sZW5ndGgpOworICAgICAgICBkYXRhID0gZGF0YUFycmF5cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciBvZiB0eXBlIGRvdWJsZSB3aXRoIGEgc2luZ2xlIHVuZGVybHlpbmcKKyAgICAgKiBhcnJheSBvZiBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGV4IHRvIHVzZSB3aGVuIHJlYWRpbmcgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoZG91YmxlIGRhdGFBcnJheVtdLCBpbnQgc2l6ZSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihUWVBFX0RPVUJMRSwgc2l6ZSwgMSwgb2Zmc2V0KTsKKyAgICAgICAgZGF0YSA9IG5ldyBkb3VibGVbMV1bXTsKKyAgICAgICAgZGF0YVswXSA9IGRhdGFBcnJheTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBkb3VibGUgd2l0aCBhIHNpbmdsZSB1bmRlcmx5aW5nCisgICAgICogYXJyYXkgb2YgZGF0YSBzdGFydGluZyBhdCBpbmRleCAwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoZG91YmxlIGRhdGFBcnJheVtdLCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX0RPVUJMRSwgc2l6ZSk7CisgICAgICAgIGRhdGEgPSBuZXcgZG91YmxlWzFdW107CisgICAgICAgIGRhdGFbMF0gPSBkYXRhQXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IGRhdGEgYnVmZmVyIG9mIHR5cGUgZG91YmxlIHdpdGggb2Zmc2V0cyBlcXVhbCB0bworICAgICAqIHplcm8uCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqIEBwYXJhbSBudW1CYW5rcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkYXRhIGFycmF5cyB0byBjcmVhdGUuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoaW50IHNpemUsIGludCBudW1CYW5rcykgeworICAgICAgICBzdXBlcihUWVBFX0RPVUJMRSwgc2l6ZSwgbnVtQmFua3MpOworICAgICAgICBkYXRhID0gbmV3IGRvdWJsZVtudW1CYW5rc11bXTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoaSA8IG51bUJhbmtzKSB7CisgICAgICAgICAgICBkYXRhW2krK10gPSBuZXcgZG91YmxlW3NpemVdOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IGRhdGEgYnVmZmVyIG9mIHR5cGUgZG91YmxlIHdpdGggYSBzaW5nbGUKKyAgICAgKiB1bmRlcmx5aW5nIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJEb3VibGUoaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9ET1VCTEUsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IGRvdWJsZVsxXVtdOworICAgICAgICBkYXRhWzBdID0gbmV3IGRvdWJsZVtzaXplXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBiYW5rLCBpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXSA9IHZhbDsKKyAgICAgICAgbm90aWZ5Q2hhbmdlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVsZW1GbG9hdChpbnQgYmFuaywgaW50IGksIGZsb2F0IHZhbCkgeworICAgICAgICBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXSA9IHZhbDsKKyAgICAgICAgbm90aWZ5Q2hhbmdlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVsZW1Eb3VibGUoaW50IGJhbmssIGludCBpLCBkb3VibGUgdmFsKSB7CisgICAgICAgIGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbShpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBiYW5rLCBpbnQgaSkgeworICAgICAgICByZXR1cm4gKGludCkoZGF0YVtiYW5rXVtvZmZzZXRzW2JhbmtdICsgaV0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRFbGVtRmxvYXQoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiAoZmxvYXQpKGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldEVsZW1Eb3VibGUoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtRmxvYXQoaW50IGksIGZsb2F0IHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbURvdWJsZShpbnQgaSwgZG91YmxlIHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGF0YSBvZiB0aGUgc3BlY2lmaWVkIGludGVybmFsIGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIGJhbmsKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZGVzaXJlZCBkYXRhIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZVtdIGdldERhdGEoaW50IGJhbmspIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbYmFua107CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBpKSB7CisgICAgICAgIHJldHVybiAoaW50KShkYXRhWzBdW29mZnNldCArIGldKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RWxlbUZsb2F0KGludCBpKSB7CisgICAgICAgIHJldHVybiAoZmxvYXQpKGRhdGFbMF1bb2Zmc2V0ICsgaV0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0RWxlbURvdWJsZShpbnQgaSkgeworICAgICAgICByZXR1cm4gZGF0YVswXVtvZmZzZXQgKyBpXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBiYW5rIGRhdGEuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmFuayBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGVbXVtdIGdldEJhbmtEYXRhKCkgeworICAgICAgICBub3RpZnlUYWtlbigpOworICAgICAgICByZXR1cm4gZGF0YS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIGZpcnN0IGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlW10gZ2V0RGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbMF07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJGbG9hdC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJGbG9hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhNGE2YmYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvRGF0YUJ1ZmZlckZsb2F0LmphdmEKQEAgLTAsMCArMSwyMjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBDbGFzcyBEYXRhQnVmZmVyRmxvYXQgaXMgdGhlIHN1YmNsYXNzIG9mIERhdGFCdWZmZXIgZm9yIHRoZSBjYXNlIHdoZXJlCisgKiB0aGUgdW5kZXJseWluZyBkYXRhIGlzIGZsb2F0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERhdGFCdWZmZXJGbG9hdCBleHRlbmRzIERhdGFCdWZmZXIgeworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEuCisgICAgICovCisgICAgZmxvYXQgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBmbG9hdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5cworICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXlzIHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBpbmRpY2VzIGZvciByZWFkaW5nIHRoZSBkYXRhIGZyb20gdGhlIGludGVybmFsCisgICAgICogICAgICAgICAgICBkYXRhIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlckZsb2F0KGZsb2F0IGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSwgaW50IG9mZnNldHNbXSkgeworICAgICAgICBzdXBlcihUWVBFX0ZMT0FULCBzaXplLCBkYXRhQXJyYXlzLmxlbmd0aCwgb2Zmc2V0cyk7CisgICAgICAgIGRhdGEgPSBkYXRhQXJyYXlzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgZmxvYXQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyRmxvYXQoZmxvYXQgZGF0YUFycmF5c1tdW10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfRkxPQVQsIHNpemUsIGRhdGFBcnJheXMubGVuZ3RoKTsKKyAgICAgICAgZGF0YSA9IGRhdGFBcnJheXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBmbG9hdCB3aXRoIGEgc2luZ2xlIHVuZGVybHlpbmcKKyAgICAgKiBhcnJheSBvZiBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGV4IHRvIHVzZSB3aGVuIHJlYWRpbmcgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJGbG9hdChmbG9hdCBkYXRhQXJyYXlbXSwgaW50IHNpemUsIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9GTE9BVCwgc2l6ZSwgMSwgb2Zmc2V0KTsKKyAgICAgICAgZGF0YSA9IG5ldyBmbG9hdFsxXVtdOworICAgICAgICBkYXRhWzBdID0gZGF0YUFycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciBvZiB0eXBlIGZsb2F0IHdpdGggYSBzaW5nbGUgdW5kZXJseWluZworICAgICAqIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyRmxvYXQoZmxvYXQgZGF0YUFycmF5W10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfRkxPQVQsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IGZsb2F0WzFdW107CisgICAgICAgIGRhdGFbMF0gPSBkYXRhQXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IGRhdGEgYnVmZmVyIG9mIHR5cGUgZmxvYXQgd2l0aCBvZmZzZXRzIGVxdWFsIHRvCisgICAgICogemVyby4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG51bUJhbmtzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRhdGEgYXJyYXlzIHRvIGNyZWF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlckZsb2F0KGludCBzaXplLCBpbnQgbnVtQmFua3MpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9GTE9BVCwgc2l6ZSwgbnVtQmFua3MpOworICAgICAgICBkYXRhID0gbmV3IGZsb2F0W251bUJhbmtzXVtdOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChpIDwgbnVtQmFua3MpIHsKKyAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5ldyBmbG9hdFtzaXplXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBlbXB0eSBkYXRhIGJ1ZmZlciBvZiB0eXBlIGZsb2F0IHdpdGggYSBzaW5nbGUKKyAgICAgKiB1bmRlcmx5aW5nIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJGbG9hdChpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX0ZMT0FULCBzaXplKTsKKyAgICAgICAgZGF0YSA9IG5ldyBmbG9hdFsxXVtdOworICAgICAgICBkYXRhWzBdID0gbmV3IGZsb2F0W3NpemVdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVsZW0oaW50IGJhbmssIGludCBpLCBpbnQgdmFsKSB7CisgICAgICAgIGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbUZsb2F0KGludCBiYW5rLCBpbnQgaSwgZmxvYXQgdmFsKSB7CisgICAgICAgIGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbURvdWJsZShpbnQgYmFuaywgaW50IGksIGRvdWJsZSB2YWwpIHsKKyAgICAgICAgZGF0YVtiYW5rXVtvZmZzZXRzW2JhbmtdICsgaV0gPSAoZmxvYXQpdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbShpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBiYW5rLCBpbnQgaSkgeworICAgICAgICByZXR1cm4gKGludCkoZGF0YVtiYW5rXVtvZmZzZXRzW2JhbmtdICsgaV0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRFbGVtRmxvYXQoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldEVsZW1Eb3VibGUoaW50IGJhbmssIGludCBpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtRmxvYXQoaW50IGksIGZsb2F0IHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RWxlbURvdWJsZShpbnQgaSwgZG91YmxlIHZhbCkgeworICAgICAgICBkYXRhWzBdW29mZnNldCArIGldID0gKGZsb2F0KXZhbDsKKyAgICAgICAgbm90aWZ5Q2hhbmdlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIHNwZWNpZmllZCBpbnRlcm5hbCBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGRlc2lyZWQgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXREYXRhKGludCBiYW5rKSB7CisgICAgICAgIG5vdGlmeVRha2VuKCk7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgaSkgeworICAgICAgICByZXR1cm4gKGludCkoZGF0YVswXVtvZmZzZXQgKyBpXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldEVsZW1GbG9hdChpbnQgaSkgeworICAgICAgICByZXR1cm4gZGF0YVswXVtvZmZzZXQgKyBpXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldEVsZW1Eb3VibGUoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFbMF1bb2Zmc2V0ICsgaV07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmFuayBkYXRhLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJhbmsgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXVtdIGdldEJhbmtEYXRhKCkgeworICAgICAgICBub3RpZnlUYWtlbigpOworICAgICAgICByZXR1cm4gZGF0YS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIGZpcnN0IGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXREYXRhKCkgeworICAgICAgICBub3RpZnlUYWtlbigpOworICAgICAgICByZXR1cm4gZGF0YVswXTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvRGF0YUJ1ZmZlckludC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJJbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODBhMTI3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJJbnQuamF2YQpAQCAtMCwwICsxLDE4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKKy8qKgorICogVGhlIENsYXNzIERhdGFCdWZmZXJJbnQgaXMgdGhlIHN1YmNsYXNzIG9mIERhdGFCdWZmZXIgZm9yIHRoZSBjYXNlIHdoZXJlIHRoZQorICogdW5kZXJseWluZyBkYXRhIGlzIG9mIHR5cGUgaW50ZWdlci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEYXRhQnVmZmVySW50IGV4dGVuZHMgRGF0YUJ1ZmZlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGF0YS4KKyAgICAgKi8KKyAgICBpbnQgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBpbnRlZ2VyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXlzCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheXMgdG8gY29weSB0aGUgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHVzZSBmcm9tIHRoZSBkYXRhIGFycmF5cy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGljZXMgZm9yIHJlYWRpbmcgdGhlIGRhdGEgZnJvbSB0aGUgaW50ZXJuYWwKKyAgICAgKiAgICAgICAgICAgIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVySW50KGludCBkYXRhQXJyYXlzW11bXSwgaW50IHNpemUsIGludCBvZmZzZXRzW10pIHsKKyAgICAgICAgc3VwZXIoVFlQRV9JTlQsIHNpemUsIGRhdGFBcnJheXMubGVuZ3RoLCBvZmZzZXRzKTsKKyAgICAgICAgZGF0YSA9IGRhdGFBcnJheXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBpbnRlZ2VyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXlzCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheXMgdG8gY29weSB0aGUgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHVzZSBmcm9tIHRoZSBkYXRhIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlckludChpbnQgZGF0YUFycmF5c1tdW10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfSU5ULCBzaXplLCBkYXRhQXJyYXlzLmxlbmd0aCk7CisgICAgICAgIGRhdGEgPSBkYXRhQXJyYXlzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgaW50ZWdlciB3aXRoIGEgc2luZ2xlIHVuZGVybHlpbmcKKyAgICAgKiBhcnJheSBvZiBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGV4IHRvIHVzZSB3aGVuIHJlYWRpbmcgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJJbnQoaW50IGRhdGFBcnJheVtdLCBpbnQgc2l6ZSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihUWVBFX0lOVCwgc2l6ZSwgMSwgb2Zmc2V0KTsKKyAgICAgICAgZGF0YSA9IG5ldyBpbnRbMV1bXTsKKyAgICAgICAgZGF0YVswXSA9IGRhdGFBcnJheTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBpbnRlZ2VyIHdpdGggYSBzaW5nbGUgdW5kZXJseWluZworICAgICAqIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVySW50KGludCBkYXRhQXJyYXlbXSwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9JTlQsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IGludFsxXVtdOworICAgICAgICBkYXRhWzBdID0gZGF0YUFycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBlbXB0eSBkYXRhIGJ1ZmZlciBvZiB0eXBlIGludGVnZXIgd2l0aCBvZmZzZXRzIGVxdWFsCisgICAgICogdG8gemVyby4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG51bUJhbmtzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRhdGEgYXJyYXlzIHRvIGNyZWF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlckludChpbnQgc2l6ZSwgaW50IG51bUJhbmtzKSB7CisgICAgICAgIHN1cGVyKFRZUEVfSU5ULCBzaXplLCBudW1CYW5rcyk7CisgICAgICAgIGRhdGEgPSBuZXcgaW50W251bUJhbmtzXVtdOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChpIDwgbnVtQmFua3MpIHsKKyAgICAgICAgICAgIGRhdGFbaSsrXSA9IG5ldyBpbnRbc2l6ZV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZW1wdHkgZGF0YSBidWZmZXIgb2YgdHlwZSBpbnRlZ2VyIHdpdGggYSBzaW5nbGUKKyAgICAgKiB1bmRlcmx5aW5nIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJJbnQoaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9JTlQsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IGludFsxXVtdOworICAgICAgICBkYXRhWzBdID0gbmV3IGludFtzaXplXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBiYW5rLCBpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXSA9IHZhbDsKKyAgICAgICAgbm90aWZ5Q2hhbmdlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVsZW0oaW50IGksIGludCB2YWwpIHsKKyAgICAgICAgZGF0YVswXVtvZmZzZXQgKyBpXSA9IHZhbDsKKyAgICAgICAgbm90aWZ5Q2hhbmdlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgYmFuaywgaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIHNwZWNpZmllZCBpbnRlcm5hbCBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5rCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGRlc2lyZWQgZGF0YSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXREYXRhKGludCBiYW5rKSB7CisgICAgICAgIG5vdGlmeVRha2VuKCk7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgaSkgeworICAgICAgICByZXR1cm4gZGF0YVswXVtvZmZzZXQgKyBpXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBiYW5rIGRhdGEuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYmFuayBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXVtdIGdldEJhbmtEYXRhKCkgeworICAgICAgICBub3RpZnlUYWtlbigpOworICAgICAgICByZXR1cm4gZGF0YS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhlIGZpcnN0IGRhdGEgYXJyYXkuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0RGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbMF07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJTaG9ydC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJTaG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiMTFiMjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvRGF0YUJ1ZmZlclNob3J0LmphdmEKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBDbGFzcyBEYXRhQnVmZmVyU2hvcnQgaXMgdGhlIHN1YmNsYXNzIG9mIERhdGFCdWZmZXIgZm9yIHRoZSBjYXNlIHdoZXJlCisgKiB0aGUgdW5kZXJseWluZyBkYXRhIGlzIHNob3J0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERhdGFCdWZmZXJTaG9ydCBleHRlbmRzIERhdGFCdWZmZXIgeworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEuCisgICAgICovCisgICAgc2hvcnQgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBzaG9ydC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5cworICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXlzIHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBpbmRpY2VzIGZvciByZWFkaW5nIHRoZSBkYXRhIGZyb20gdGhlIGludGVybmFsCisgICAgICogICAgICAgICAgICBkYXRhIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlclNob3J0KHNob3J0IGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSwgaW50IG9mZnNldHNbXSkgeworICAgICAgICBzdXBlcihUWVBFX1NIT1JULCBzaXplLCBkYXRhQXJyYXlzLmxlbmd0aCwgb2Zmc2V0cyk7CisgICAgICAgIGRhdGEgPSBkYXRhQXJyYXlzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgc2hvcnQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyU2hvcnQoc2hvcnQgZGF0YUFycmF5c1tdW10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfU0hPUlQsIHNpemUsIGRhdGFBcnJheXMubGVuZ3RoKTsKKyAgICAgICAgZGF0YSA9IGRhdGFBcnJheXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSBzaG9ydCB3aXRoIGEgc2luZ2xlIHVuZGVybHlpbmcKKyAgICAgKiBhcnJheSBvZiBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5IHRvIGNvcHkgdGhlIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIGluZGV4IHRvIHVzZSB3aGVuIHJlYWRpbmcgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJTaG9ydChzaG9ydCBkYXRhQXJyYXlbXSwgaW50IHNpemUsIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9TSE9SVCwgc2l6ZSwgMSwgb2Zmc2V0KTsKKyAgICAgICAgZGF0YSA9IG5ldyBzaG9ydFsxXVtdOworICAgICAgICBkYXRhWzBdID0gZGF0YUFycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciBvZiB0eXBlIHNob3J0IHdpdGggYSBzaW5nbGUgdW5kZXJseWluZworICAgICAqIGFycmF5IG9mIGRhdGEgc3RhcnRpbmcgYXQgaW5kZXggMC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheSB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyU2hvcnQoc2hvcnQgZGF0YUFycmF5W10sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKFRZUEVfU0hPUlQsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IHNob3J0WzFdW107CisgICAgICAgIGRhdGFbMF0gPSBkYXRhQXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgc2hvcnQgd2l0aCBvZmZzZXRzIGVxdWFsIHRvIHplcm8uCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqIEBwYXJhbSBudW1CYW5rcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkYXRhIGFycmF5cyB0byBjcmVhdGUuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJTaG9ydChpbnQgc2l6ZSwgaW50IG51bUJhbmtzKSB7CisgICAgICAgIHN1cGVyKFRZUEVfU0hPUlQsIHNpemUsIG51bUJhbmtzKTsKKyAgICAgICAgZGF0YSA9IG5ldyBzaG9ydFtudW1CYW5rc11bXTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoaSA8IG51bUJhbmtzKSB7CisgICAgICAgICAgICBkYXRhW2krK10gPSBuZXcgc2hvcnRbc2l6ZV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZW1wdHkgZGF0YSBidWZmZXIgb2YgdHlwZSBzaG9ydCB3aXRoIGEgc2luZ2xlCisgICAgICogdW5kZXJseWluZyBhcnJheSBvZiBkYXRhIHN0YXJ0aW5nIGF0IGluZGV4IDAuCisgICAgICogCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyU2hvcnQoaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9TSE9SVCwgc2l6ZSk7CisgICAgICAgIGRhdGEgPSBuZXcgc2hvcnRbMV1bXTsKKyAgICAgICAgZGF0YVswXSA9IG5ldyBzaG9ydFtzaXplXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBiYW5rLCBpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXSA9IChzaG9ydCl2YWw7CisgICAgICAgIG5vdGlmeUNoYW5nZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBpLCBpbnQgdmFsKSB7CisgICAgICAgIGRhdGFbMF1bb2Zmc2V0ICsgaV0gPSAoc2hvcnQpdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBiYW5rLCBpbnQgaSkgeworICAgICAgICByZXR1cm4gKGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgaW50ZXJuYWwgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmFuaworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBkZXNpcmVkIGRhdGEgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnRbXSBnZXREYXRhKGludCBiYW5rKSB7CisgICAgICAgIG5vdGlmeVRha2VuKCk7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgaSkgeworICAgICAgICByZXR1cm4gKGRhdGFbMF1bb2Zmc2V0ICsgaV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJhbmsgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBiYW5rIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHNob3J0W11bXSBnZXRCYW5rRGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoZSBmaXJzdCBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHNob3J0W10gZ2V0RGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbMF07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RhdGFCdWZmZXJVU2hvcnQuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyVVNob3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNThkOWQ4MwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EYXRhQnVmZmVyVVNob3J0LmphdmEKQEAgLTAsMCArMSwxOTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIERhdGFCdWZmZXJVU2hvcnQgaXMgdGhlIHN1YmNsYXNzIG9mIERhdGFCdWZmZXIgZm9yIHRoZSBjYXNlIHdoZXJlCisgKiB0aGUgdW5kZXJseWluZyBkYXRhIGlzIHVuc2lnbmVkIHNob3J0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERhdGFCdWZmZXJVU2hvcnQgZXh0ZW5kcyBEYXRhQnVmZmVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhLgorICAgICAqLworICAgIHNob3J0IGRhdGFbXVtdOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqIEBwYXJhbSBvZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgaW5kaWNlcyBmb3IgcmVhZGluZyB0aGUgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbAorICAgICAqICAgICAgICAgICAgZGF0YSBhcnJheXMuCisgICAgICovCisgICAgcHVibGljIERhdGFCdWZmZXJVU2hvcnQoc2hvcnQgZGF0YUFycmF5c1tdW10sIGludCBzaXplLCBpbnQgb2Zmc2V0c1tdKSB7CisgICAgICAgIHN1cGVyKFRZUEVfVVNIT1JULCBzaXplLCBkYXRhQXJyYXlzLmxlbmd0aCwgb2Zmc2V0cyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YUFycmF5cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGRhdGFBcnJheXNbaV0ubGVuZ3RoIDwgb2Zmc2V0c1tpXSArIHNpemUpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjhkPUxlbmd0aCBvZiBkYXRhQXJyYXlbezB9XSBpcyBsZXNzIHRoYW4gc2l6ZSArCisgICAgICAgICAgICAgICAgLy8gb2Zmc2V0W3sxfV0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4RCIsIGksIGkpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGRhdGEgPSBkYXRhQXJyYXlzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIGFycmF5cyB0byBjb3B5IHRoZSBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggKG51bWJlciBvZiBlbGVtZW50cykgdG8gdXNlIGZyb20gdGhlIGRhdGEgYXJyYXlzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhQnVmZmVyVVNob3J0KHNob3J0IGRhdGFBcnJheXNbXVtdLCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX1VTSE9SVCwgc2l6ZSwgZGF0YUFycmF5cy5sZW5ndGgpOworICAgICAgICBkYXRhID0gZGF0YUFycmF5cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBkYXRhIGJ1ZmZlciBvZiB0eXBlIHVuc2lnbmVkIHNob3J0IHdpdGggYSBzaW5nbGUKKyAgICAgKiB1bmRlcmx5aW5nIGFycmF5IG9mIGRhdGEuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXkgdG8gY29weSB0aGUgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHVzZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgaW5kZXggdG8gdXNlIHdoZW4gcmVhZGluZyB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlclVTaG9ydChzaG9ydCBkYXRhQXJyYXlbXSwgaW50IHNpemUsIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9VU0hPUlQsIHNpemUsIDEsIG9mZnNldCk7CisgICAgICAgIGlmIChkYXRhQXJyYXkubGVuZ3RoIDwgc2l6ZSArIG9mZnNldCkgeworICAgICAgICAgICAgLy8gYXd0LjI4RT1MZW5ndGggb2YgZGF0YUFycmF5IGlzIGxlc3MgdGhhbiBzaXplICsgb2Zmc2V0CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4RSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGRhdGEgPSBuZXcgc2hvcnRbMV1bXTsKKyAgICAgICAgZGF0YVswXSA9IGRhdGFBcnJheTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGF0YSBidWZmZXIgb2YgdHlwZSB1bnNpZ25lZCBzaG9ydCB3aXRoIGEgc2luZ2xlCisgICAgICogdW5kZXJseWluZyBhcnJheSBvZiBkYXRhIHN0YXJ0aW5nIGF0IGluZGV4IDAuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXkgdG8gY29weSB0aGUgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlclVTaG9ydChzaG9ydCBkYXRhQXJyYXlbXSwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoVFlQRV9VU0hPUlQsIHNpemUpOworICAgICAgICBkYXRhID0gbmV3IHNob3J0WzFdW107CisgICAgICAgIGRhdGFbMF0gPSBkYXRhQXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQgd2l0aCBvZmZzZXRzCisgICAgICogZXF1YWwgdG8gemVyby4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCAobnVtYmVyIG9mIGVsZW1lbnRzKSB0byB1c2UgZnJvbSB0aGUgZGF0YSBhcnJheXMuCisgICAgICogQHBhcmFtIG51bUJhbmtzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRhdGEgYXJyYXlzIHRvIGNyZWF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlclVTaG9ydChpbnQgc2l6ZSwgaW50IG51bUJhbmtzKSB7CisgICAgICAgIHN1cGVyKFRZUEVfVVNIT1JULCBzaXplLCBudW1CYW5rcyk7CisgICAgICAgIGRhdGEgPSBuZXcgc2hvcnRbbnVtQmFua3NdW107CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGkgPCBudW1CYW5rcykgeworICAgICAgICAgICAgZGF0YVtpKytdID0gbmV3IHNob3J0W3NpemVdOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IGRhdGEgYnVmZmVyIG9mIHR5cGUgdW5zaWduZWQgc2hvcnQgd2l0aCBhIHNpbmdsZQorICAgICAqIHVuZGVybHlpbmcgYXJyYXkgb2YgZGF0YSBzdGFydGluZyBhdCBpbmRleCAwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlclVTaG9ydChpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihUWVBFX1VTSE9SVCwgc2l6ZSk7CisgICAgICAgIGRhdGEgPSBuZXcgc2hvcnRbMV1bXTsKKyAgICAgICAgZGF0YVswXSA9IG5ldyBzaG9ydFtzaXplXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBiYW5rLCBpbnQgaSwgaW50IHZhbCkgeworICAgICAgICBkYXRhW2JhbmtdW29mZnNldHNbYmFua10gKyBpXSA9IChzaG9ydCl2YWw7CisgICAgICAgIG5vdGlmeUNoYW5nZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbGVtKGludCBpLCBpbnQgdmFsKSB7CisgICAgICAgIGRhdGFbMF1bb2Zmc2V0ICsgaV0gPSAoc2hvcnQpdmFsOworICAgICAgICBub3RpZnlDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRFbGVtKGludCBiYW5rLCBpbnQgaSkgeworICAgICAgICByZXR1cm4gKGRhdGFbYmFua11bb2Zmc2V0c1tiYW5rXSArIGldKSAmIDB4ZmZmZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgaW50ZXJuYWwgZGF0YSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmFuaworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBkZXNpcmVkIGRhdGEgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnRbXSBnZXREYXRhKGludCBiYW5rKSB7CisgICAgICAgIG5vdGlmeVRha2VuKCk7CisgICAgICAgIHJldHVybiBkYXRhW2JhbmtdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RWxlbShpbnQgaSkgeworICAgICAgICByZXR1cm4gKGRhdGFbMF1bb2Zmc2V0ICsgaV0pICYgMHhmZmZmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJhbmsgZGF0YS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBiYW5rIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHNob3J0W11bXSBnZXRCYW5rRGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoZSBmaXJzdCBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHNob3J0W10gZ2V0RGF0YSgpIHsKKyAgICAgICAgbm90aWZ5VGFrZW4oKTsKKyAgICAgICAgcmV0dXJuIGRhdGFbMF07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0RpcmVjdENvbG9yTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EaXJlY3RDb2xvck1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzAwZWI3YQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9EaXJlY3RDb2xvck1vZGVsLmphdmEKQEAgLTAsMCArMSw4ODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuY29sb3IuQ29sb3JTcGFjZTsKK2ltcG9ydCBqYXZhLmF3dC5UcmFuc3BhcmVuY3k7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuTFVUQ29sb3JDb252ZXJ0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIERpcmVjdENvbG9yTW9kZWwgcmVwcmVzZW50cyBhIHN0YW5kYXJkIChwYWNrZWQpIFJHQiBjb2xvciBtb2RlbAorICogd2l0aCBhZGRpdGlvbmFsIHN1cHBvcnQgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBzUkdCIGNvbG9yIHNwYWNlIGFuZCA4IG9yIDE2CisgKiBiaXQgbGluZWFyIFJHQiBjb2xvciBzcGFjZSB1c2luZyBsb29rdXAgdGFibGVzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIERpcmVjdENvbG9yTW9kZWwgZXh0ZW5kcyBQYWNrZWRDb2xvck1vZGVsIHsKKworICAgIC8qKgorICAgICAqIFRoZSBmcm9tXyBsaW5lYSByXyByZyBiXyBsdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIGZyb21fTElORUFSX1JHQl9MVVRbXTsgLy8gTG9va3VwIHRhYmxlIGZvciBjb252ZXJzaW9uIGZyb20KKworICAgIC8vIExpbmVhciBSR0IgQ29sb3IgU3BhY2UgaW50byBzUkdCCisKKyAgICAvKioKKyAgICAgKiBUaGUgdG9fIGxpbmVhIHJfOCByZyBiXyBsdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIHRvX0xJTkVBUl84UkdCX0xVVFtdOyAvLyBMb29rdXAgdGFibGUgZm9yIGNvbnZlcnNpb24gZnJvbQorCisgICAgLy8gc1JHQiBDb2xvciBTcGFjZSBpbnRvIExpbmVhciBSR0IKKyAgICAvLyA4IGJpdAorCisgICAgLyoqCisgICAgICogVGhlIHRvXyBsaW5lYSByXzE2IHJnIGJfIGx1dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHNob3J0IHRvX0xJTkVBUl8xNlJHQl9MVVRbXTsgLy8gTG9va3VwIHRhYmxlIGZvciBjb252ZXJzaW9uIGZyb20KKworICAgIC8vIHNSR0IgQ29sb3IgU3BhY2UgaW50byBMaW5lYXIgUkdCCisgICAgLy8gMTYgYml0CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWxwaGEgbHV0LgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZSBhbHBoYUxVVFtdOyAvLyBMb29rdXAgdGFibGUgZm9yIHNjYWxlIGFscGhhIHZhbHVlCisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sb3IgbHUgdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlIGNvbG9yTFVUc1tdW107IC8vIExvb2t1cCB0YWJsZXMgZm9yIHNjYWxlIGNvbG9yIHZhbHVlcworCisgICAgLyoqCisgICAgICogVGhlIGlzX3MgcmdiLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc19zUkdCOyAvLyBDb2xvck1vZGVsIGhhcyBzUkdCIENvbG9yU3BhY2UKKworICAgIC8qKgorICAgICAqIFRoZSBpc18gbGluZWEgcl8gcmdiLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc19MSU5FQVJfUkdCOyAvLyBDb2xvciBNb2RlbCBoYXMgTGluZWFyIFJHQiBDb2xvcgorCisgICAgLy8gU3BhY2UKKworICAgIC8qKgorICAgICAqIFRoZSBMSU5FQSByXyByZyBiXyBsZW5ndGguCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgTElORUFSX1JHQl9MZW5ndGg7IC8vIExpbmVhciBSR0IgYml0IGxlbmd0aAorCisgICAgLyoqCisgICAgICogVGhlIGZhY3Rvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGZGYWN0b3I7IC8vIFNjYWxlIGZhY3RvcgorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRpcmVjdCBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3BhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBzcGFjZS4KKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gcm1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHJlZCBiYW5kLgorICAgICAqIEBwYXJhbSBnbWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgZ3JlZW4gYmFuZC4KKyAgICAgKiBAcGFyYW0gYm1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGJsdWUgYmFuZC4KKyAgICAgKiBAcGFyYW0gYW1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGFscGhhIGJhbmQuCisgICAgICogQHBhcmFtIGlzQWxwaGFQcmVtdWx0aXBsaWVkCisgICAgICogICAgICAgICAgICB3aGV0aGVyIHRoZSBhbHBoYSBpcyBwcmUtbXVsdGlwbGllZCBpbiB0aGlzIGNvbG9yIG1vZGVsLgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2ZlciB0eXBlIChwcmltaXRpdmUgamF2YSB0eXBlIHRvIHVzZSBmb3IgdGhlCisgICAgICogICAgICAgICAgICBjb21wb25lbnRzKS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgY29tYmluZWQgYml0bWFza3MgZm9yIHRoZSBjb2xvcgorICAgICAqICAgICAgICAgICAgIGJhbmRzIGlzIGxlc3MgdGhhbiBvbmUgb3IgZ3JlYXRlciB0aGFuIDMyLgorICAgICAqLworICAgIHB1YmxpYyBEaXJlY3RDb2xvck1vZGVsKENvbG9yU3BhY2Ugc3BhY2UsIGludCBiaXRzLCBpbnQgcm1hc2ssIGludCBnbWFzaywgaW50IGJtYXNrLCBpbnQgYW1hc2ssCisgICAgICAgICAgICBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCBpbnQgdHJhbnNmZXJUeXBlKSB7CisKKyAgICAgICAgc3VwZXIoc3BhY2UsIGJpdHMsIHJtYXNrLCBnbWFzaywgYm1hc2ssIGFtYXNrLCBpc0FscGhhUHJlbXVsdGlwbGllZCwKKyAgICAgICAgICAgICAgICAoYW1hc2sgPT0gMCA/IFRyYW5zcGFyZW5jeS5PUEFRVUUgOiBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQpLCB0cmFuc2ZlclR5cGUpOworCisgICAgICAgIGluaXRMVVRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGRpcmVjdCBjb2xvciBtb2RlbCwgZGV0ZXJtaW5pbmcgdGhlIHRyYW5zZmVyIHR5cGUgZnJvbQorICAgICAqIHRoZSBiaXRzIGFycmF5LCB0aGUgdHJhbnNwYXJlbmN5IGZyb20gdGhlIGFscGhhIG1hc2ssIGFuZCB0aGUgZGVmYXVsdAorICAgICAqIGNvbG9yIHNwYWNlIHtAbGluayBDb2xvclNwYWNlI0NTX3NSR0J9LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY29tcG9uZW50IG1hc2tzLgorICAgICAqIEBwYXJhbSBybWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgcmVkIGJhbmQuCisgICAgICogQHBhcmFtIGdtYXNrCisgICAgICogICAgICAgICAgICB0aGUgYml0bWFzayBjb3JyZXNwb25kaW5nIHRvIHRoZSBncmVlbiBiYW5kLgorICAgICAqIEBwYXJhbSBibWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgYmx1ZSBiYW5kLgorICAgICAqIEBwYXJhbSBhbWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgYWxwaGEgYmFuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGlyZWN0Q29sb3JNb2RlbChpbnQgYml0cywgaW50IHJtYXNrLCBpbnQgZ21hc2ssIGludCBibWFzaywgaW50IGFtYXNrKSB7CisKKyAgICAgICAgc3VwZXIoQ29sb3JTcGFjZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpLCBiaXRzLCBybWFzaywgZ21hc2ssIGJtYXNrLCBhbWFzaywgZmFsc2UsCisgICAgICAgICAgICAgICAgKGFtYXNrID09IDAgPyBUcmFuc3BhcmVuY3kuT1BBUVVFIDogVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5UKSwgQ29sb3JNb2RlbAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRyYW5zZmVyVHlwZShiaXRzKSk7CisKKyAgICAgICAgaW5pdExVVHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZGlyZWN0IGNvbG9yIG1vZGVsIHdpdGggbm8gYWxwaGEgY2hhbm5lbCwgZGV0ZXJtaW5pbmcKKyAgICAgKiB0aGUgdHJhbnNmZXIgdHlwZSBmcm9tIHRoZSBiaXRzIGFycmF5LCB0aGUgZGVmYXVsdCBjb2xvciBzcGFjZQorICAgICAqIHtAbGluayBDb2xvclNwYWNlI0NTX3NSR0J9LCBhbmQgd2l0aCB0aGUgdHJhbnNwYXJlbmN5IHNldCB0bworICAgICAqIHtAbGluayBUcmFuc3BhcmVuY3kjT1BBUVVFfS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gcm1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHJlZCBiYW5kLgorICAgICAqIEBwYXJhbSBnbWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgZ3JlZW4gYmFuZC4KKyAgICAgKiBAcGFyYW0gYm1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGJsdWUgYmFuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGlyZWN0Q29sb3JNb2RlbChpbnQgYml0cywgaW50IHJtYXNrLCBpbnQgZ21hc2ssIGludCBibWFzaykgeworICAgICAgICB0aGlzKGJpdHMsIHJtYXNrLCBnbWFzaywgYm1hc2ssIDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQsIE9iamVjdCBvYmopIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgIHBpeGVsIHw9IChjb21wb25lbnRzW29mZnNldCArIGldIDw8IG9mZnNldHNbaV0pICYgY29tcG9uZW50TWFza3NbaV07CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJhID0gbmV3IGJ5dGVbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmEgPSAoYnl0ZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYmFbMF0gPSAoYnl0ZSlwaXhlbDsKKyAgICAgICAgICAgICAgICBvYmogPSBiYTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNhID0gbmV3IHNob3J0WzFdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNhID0gKHNob3J0W10pb2JqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzYVswXSA9IChzaG9ydClwaXhlbDsKKyAgICAgICAgICAgICAgICBvYmogPSBzYTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGludCBpYVtdOworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpYSA9IG5ldyBpbnRbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWEgPSAoaW50W10pb2JqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpYVswXSA9IHBpeGVsOworICAgICAgICAgICAgICAgIG9iaiA9IGlhOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4yMTQ9VGhpcyBDb2xvciBNb2RlbCBkb2Vzbid0IHN1cHBvcnQgdGhpcyB0cmFuc2ZlclR5cGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjE0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb2JqOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCByZ2IsIE9iamVjdCBwaXhlbCkgeworICAgICAgICBpZiAoZXF1YWxzKENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpKSkgeworICAgICAgICAgICAgaW50IGlhW107CisgICAgICAgICAgICBpZiAocGl4ZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlhID0gbmV3IGludFsxXTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWEgPSAoaW50W10pcGl4ZWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpYVswXSA9IHJnYjsKKyAgICAgICAgICAgIHJldHVybiBpYTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBhbHBoYSA9IChyZ2IgPj4gMjQpICYgMHhmZjsKKyAgICAgICAgaW50IHJlZCA9IChyZ2IgPj4gMTYpICYgMHhmZjsKKyAgICAgICAgaW50IGdyZWVuID0gKHJnYiA+PiA4KSAmIDB4ZmY7CisgICAgICAgIGludCBibHVlID0gcmdiICYgMHhmZjsKKworICAgICAgICBmbG9hdCBjb21wW10gPSBuZXcgZmxvYXRbbnVtQ29sb3JDb21wb25lbnRzXTsKKyAgICAgICAgZmxvYXQgbm9ybUNvbXBbXSA9IG51bGw7CisKKyAgICAgICAgaWYgKGlzX3NSR0IgfHwgaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgaWYgKGlzX0xJTkVBUl9SR0IpIHsKKyAgICAgICAgICAgICAgICBpZiAoTElORUFSX1JHQl9MZW5ndGggPT0gOCkgeworICAgICAgICAgICAgICAgICAgICByZWQgPSB0b19MSU5FQVJfOFJHQl9MVVRbcmVkXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGdyZWVuID0gdG9fTElORUFSXzhSR0JfTFVUW2dyZWVuXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGJsdWUgPSB0b19MSU5FQVJfOFJHQl9MVVRbYmx1ZV0gJiAweGZmOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJlZCA9IHRvX0xJTkVBUl8xNlJHQl9MVVRbcmVkXSAmIDB4ZmZmZjsKKyAgICAgICAgICAgICAgICAgICAgZ3JlZW4gPSB0b19MSU5FQVJfMTZSR0JfTFVUW2dyZWVuXSAmIDB4ZmZmZjsKKyAgICAgICAgICAgICAgICAgICAgYmx1ZSA9IHRvX0xJTkVBUl8xNlJHQl9MVVRbYmx1ZV0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgY29tcFswXSA9IHJlZCAvIGZGYWN0b3I7CisgICAgICAgICAgICBjb21wWzFdID0gZ3JlZW4gLyBmRmFjdG9yOworICAgICAgICAgICAgY29tcFsyXSA9IGJsdWUgLyBmRmFjdG9yOworICAgICAgICAgICAgaWYgKCFoYXNBbHBoYSkgeworICAgICAgICAgICAgICAgIG5vcm1Db21wID0gY29tcDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmxvYXQgbm9ybUFscGhhID0gYWxwaGEgLyAyNTUuMGY7CisgICAgICAgICAgICAgICAgbm9ybUNvbXAgPSBuZXcgZmxvYXRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcFtpXSA9IGNvbXBbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5vcm1Db21wW251bUNvbG9yQ29tcG9uZW50c10gPSBub3JtQWxwaGE7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb21wWzBdID0gcmVkIC8gZkZhY3RvcjsKKyAgICAgICAgICAgIGNvbXBbMV0gPSBncmVlbiAvIGZGYWN0b3I7CisgICAgICAgICAgICBjb21wWzJdID0gYmx1ZSAvIGZGYWN0b3I7CisgICAgICAgICAgICBmbG9hdCByZ2JDb21wW10gPSBjcy5mcm9tUkdCKGNvbXApOworICAgICAgICAgICAgaWYgKCFoYXNBbHBoYSkgeworICAgICAgICAgICAgICAgIG5vcm1Db21wID0gcmdiQ29tcDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmxvYXQgbm9ybUFscGhhID0gYWxwaGEgLyAyNTUuMGY7CisgICAgICAgICAgICAgICAgbm9ybUNvbXAgPSBuZXcgZmxvYXRbbnVtQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db2xvckNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBub3JtQ29tcFtpXSA9IHJnYkNvbXBbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5vcm1Db21wW251bUNvbG9yQ29tcG9uZW50c10gPSBub3JtQWxwaGE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgcHhsID0gMDsKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICBmbG9hdCBub3JtQWxwaGEgPSBub3JtQ29tcFtudW1Db2xvckNvbXBvbmVudHNdOworICAgICAgICAgICAgYWxwaGEgPSAoaW50KShub3JtQWxwaGEgKiBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXSArIDAuNWYpOworICAgICAgICAgICAgaWYgKGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgICAgICAgICAgcmVkID0gKGludCkobm9ybUNvbXBbMF0gKiBub3JtQWxwaGEgKiBtYXhWYWx1ZXNbMF0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICBncmVlbiA9IChpbnQpKG5vcm1Db21wWzFdICogbm9ybUFscGhhICogbWF4VmFsdWVzWzFdICsgMC41Zik7CisgICAgICAgICAgICAgICAgYmx1ZSA9IChpbnQpKG5vcm1Db21wWzJdICogbm9ybUFscGhhICogbWF4VmFsdWVzWzJdICsgMC41Zik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlZCA9IChpbnQpKG5vcm1Db21wWzBdICogbWF4VmFsdWVzWzBdICsgMC41Zik7CisgICAgICAgICAgICAgICAgZ3JlZW4gPSAoaW50KShub3JtQ29tcFsxXSAqIG1heFZhbHVlc1sxXSArIDAuNWYpOworICAgICAgICAgICAgICAgIGJsdWUgPSAoaW50KShub3JtQ29tcFsyXSAqIG1heFZhbHVlc1syXSArIDAuNWYpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHhsID0gKGFscGhhIDw8IG9mZnNldHNbM10pICYgY29tcG9uZW50TWFza3NbM107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZWQgPSAoaW50KShub3JtQ29tcFswXSAqIG1heFZhbHVlc1swXSArIDAuNWYpOworICAgICAgICAgICAgZ3JlZW4gPSAoaW50KShub3JtQ29tcFsxXSAqIG1heFZhbHVlc1sxXSArIDAuNWYpOworICAgICAgICAgICAgYmx1ZSA9IChpbnQpKG5vcm1Db21wWzJdICogbWF4VmFsdWVzWzJdICsgMC41Zik7CisgICAgICAgIH0KKworICAgICAgICBweGwgfD0gKChyZWQgPDwgb2Zmc2V0c1swXSkgJiBjb21wb25lbnRNYXNrc1swXSkKKyAgICAgICAgICAgICAgICB8ICgoZ3JlZW4gPDwgb2Zmc2V0c1sxXSkgJiBjb21wb25lbnRNYXNrc1sxXSkKKyAgICAgICAgICAgICAgICB8ICgoYmx1ZSA8PCBvZmZzZXRzWzJdKSAmIGNvbXBvbmVudE1hc2tzWzJdKTsKKworICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJhW107CisgICAgICAgICAgICAgICAgaWYgKHBpeGVsID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYmEgPSBuZXcgYnl0ZVsxXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBiYSA9IChieXRlW10pcGl4ZWw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJhWzBdID0gKGJ5dGUpcHhsOworICAgICAgICAgICAgICAgIHJldHVybiBiYTsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW107CisgICAgICAgICAgICAgICAgaWYgKHBpeGVsID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc2EgPSBuZXcgc2hvcnRbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2EgPSAoc2hvcnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2FbMF0gPSAoc2hvcnQpcHhsOworICAgICAgICAgICAgICAgIHJldHVybiBzYTsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGludCBpYVtdOworICAgICAgICAgICAgICAgIGlmIChwaXhlbCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlhID0gbmV3IGludFsxXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpYSA9IChpbnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWFbMF0gPSBweGw7CisgICAgICAgICAgICAgICAgcmV0dXJuIGlhOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4yMTQ9VGhpcyBDb2xvciBNb2RlbCBkb2Vzbid0IHN1cHBvcnQgdGhpcyB0cmFuc2ZlclR5cGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjE0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQ29sb3JNb2RlbCBjb2VyY2VEYXRhKFdyaXRhYmxlUmFzdGVyIHJhc3RlciwgYm9vbGVhbiBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworCisgICAgICAgIGlmICghaGFzQWxwaGEgfHwgdGhpcy5pc0FscGhhUHJlbXVsdGlwbGllZCA9PSBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbWluWCA9IHJhc3Rlci5nZXRNaW5YKCk7CisgICAgICAgIGludCBtaW5ZID0gcmFzdGVyLmdldE1pblkoKTsKKyAgICAgICAgaW50IHcgPSByYXN0ZXIuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGggPSByYXN0ZXIuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgaW50IGNvbXBvbmVudHNbXSA9IG51bGw7CisgICAgICAgIGludCB0cmFuc3BhcmVudENvbXBvbmVudHNbXSA9IG5ldyBpbnRbbnVtQ29tcG9uZW50c107CisKKyAgICAgICAgZmxvYXQgYWxwaGFGYWN0b3IgPSBtYXhWYWx1ZXNbbnVtQ29sb3JDb21wb25lbnRzXTsKKworICAgICAgICBpZiAoaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGg7IGkrKywgbWluWSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMCwgeCA9IG1pblg7IGogPCB3OyBqKyssIHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHMgPSByYXN0ZXIuZ2V0UGl4ZWwoeCwgbWluWSwgY29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXRQaXhlbCh4LCBtaW5ZLCB0cmFuc3BhcmVudENvbXBvbmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gY29tcG9uZW50c1tudW1Db2xvckNvbXBvbmVudHNdIC8gYWxwaGFGYWN0b3I7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQ29sb3JDb21wb25lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHNbbl0gPSAoaW50KShhbHBoYSAqIGNvbXBvbmVudHNbbl0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgY29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMKKyAgICAgICAgICAgICAgICAgICAgLy8gdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGg7IGkrKywgbWluWSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMCwgeCA9IG1pblg7IGogPCB3OyBqKyssIHgrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHMgPSByYXN0ZXIuZ2V0UGl4ZWwoeCwgbWluWSwgY29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudHNbbnVtQ29sb3JDb21wb25lbnRzXSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGFscGhhID0gYWxwaGFGYWN0b3IgLyBjb21wb25lbnRzW251bUNvbG9yQ29tcG9uZW50c107CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQ29sb3JDb21wb25lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHNbbl0gPSAoaW50KShhbHBoYSAqIGNvbXBvbmVudHNbbl0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0UGl4ZWwoeCwgbWluWSwgY29tcG9uZW50cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMKKyAgICAgICAgICAgICAgICAgICAgLy8gdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBEaXJlY3RDb2xvck1vZGVsKGNzLCBwaXhlbF9iaXRzLCBjb21wb25lbnRNYXNrc1swXSwgY29tcG9uZW50TWFza3NbMV0sCisgICAgICAgICAgICAgICAgY29tcG9uZW50TWFza3NbMl0sIGNvbXBvbmVudE1hc2tzWzNdLCBpc0FscGhhUHJlbXVsdGlwbGllZCwgdHJhbnNmZXJUeXBlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBUaGUgb3V0cHV0IGZvcm1hdCBiYXNlZCBvbiAxLjUgcmVsZWFzZSBiZWhhdmlvdXIuCisgICAgICAgIC8vIEl0IGNvdWxkIGJlIHJldmVsZWQgc3VjaCB3YXk6CisgICAgICAgIC8vIEJ1ZmZlcmVkSW1hZ2UgYmkgPSBuZXcgQnVmZmVyZWRJbWFnZSgxLCAxLAorICAgICAgICAvLyBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IpOworICAgICAgICAvLyBDb2xvck1vZGVsIGNtID0gYmkuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oY20udG9TdHJpbmcoKSk7CisgICAgICAgIFN0cmluZyBzdHIgPSAiRGlyZWN0Q29sb3JNb2RlbDoiICsgIiBybWFzayA9ICIgKyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNvbXBvbmVudE1hc2tzWzBdKSArICIgZ21hc2sgPSAiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIEludGVnZXIudG9IZXhTdHJpbmcoY29tcG9uZW50TWFza3NbMV0pICsgIiBibWFzayA9ICIgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgSW50ZWdlci50b0hleFN0cmluZyhjb21wb25lbnRNYXNrc1syXSkgKyAiIGFtYXNrID0gIiArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAoIWhhc0FscGhhID8gIjAiIDogSW50ZWdlci50b0hleFN0cmluZyhjb21wb25lbnRNYXNrc1szXSkpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgcmV0dXJuIHN0cjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50W10gZ2V0Q29tcG9uZW50cyhPYmplY3QgcGl4ZWwsIGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQpIHsKKworICAgICAgICBpZiAoY29tcG9uZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzID0gbmV3IGludFtudW1Db21wb25lbnRzICsgb2Zmc2V0XTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpbnRQaXhlbCA9IDA7CisKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBpbnRQaXhlbCA9IGJhWzBdICYgMHhmZjsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNhW10gPSAoc2hvcnRbXSlwaXhlbDsKKyAgICAgICAgICAgICAgICBpbnRQaXhlbCA9IHNhWzBdICYgMHhmZmZmOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlhW10gPSAoaW50W10pcGl4ZWw7CisgICAgICAgICAgICAgICAgaW50UGl4ZWwgPSBpYVswXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjJEPVRoaXMgdHJhbnNmZXJUeXBlICggezB9ICkgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzCisgICAgICAgICAgICAgICAgLy8gY29sb3IgbW9kZWwKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJEIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmZXJUeXBlKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50cyhpbnRQaXhlbCwgY29tcG9uZW50cywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJlZChPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIGludCBwaXhlbCA9IDA7CisgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gYmFbMF0gJiAweGZmOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXSA9IChzaG9ydFtdKWluRGF0YTsKKyAgICAgICAgICAgICAgICBwaXhlbCA9IHNhWzBdICYgMHhmZmZmOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlhW10gPSAoaW50W10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gaWFbMF07CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxND1UaGlzIENvbG9yIE1vZGVsIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHRyYW5zZmVyVHlwZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0UmVkKHBpeGVsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJHQihPYmplY3QgaW5EYXRhKSB7CisgICAgICAgIGludCBwaXhlbCA9IDA7CisgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gYmFbMF0gJiAweGZmOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXSA9IChzaG9ydFtdKWluRGF0YTsKKyAgICAgICAgICAgICAgICBwaXhlbCA9IHNhWzBdICYgMHhmZmZmOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlhW10gPSAoaW50W10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gaWFbMF07CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjIxND1UaGlzIENvbG9yIE1vZGVsIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHRyYW5zZmVyVHlwZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0UkdCKHBpeGVsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEdyZWVuKE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBiYVswXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gc2FbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBpYVswXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMgdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRHcmVlbihwaXhlbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRCbHVlKE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBiYVswXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gc2FbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBpYVswXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMgdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRCbHVlKHBpeGVsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEFscGhhKE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKyAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBiYVswXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10paW5EYXRhOworICAgICAgICAgICAgICAgIHBpeGVsID0gc2FbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlpbkRhdGE7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBpYVswXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjE0PVRoaXMgQ29sb3IgTW9kZWwgZG9lc24ndCBzdXBwb3J0IHRoaXMgdHJhbnNmZXJUeXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRBbHBoYShwaXhlbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcihpbnQgdywgaW50IGgpIHsKKyAgICAgICAgaWYgKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGJhbmRNYXNrc1tdID0gY29tcG9uZW50TWFza3MuY2xvbmUoKTsKKworICAgICAgICBpZiAocGl4ZWxfYml0cyA+IDE2KSB7CisgICAgICAgICAgICByZXR1cm4gUmFzdGVyLmNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfSU5ULCB3LCBoLCBiYW5kTWFza3MsIG51bGwpOworICAgICAgICB9IGVsc2UgaWYgKHBpeGVsX2JpdHMgPiA4KSB7CisgICAgICAgICAgICByZXR1cm4gUmFzdGVyLmNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCB3LCBoLCBiYW5kTWFza3MsIG51bGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIFJhc3Rlci5jcmVhdGVQYWNrZWRSYXN0ZXIoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHcsIGgsIGJhbmRNYXNrcywgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBhdGlibGVSYXN0ZXIoUmFzdGVyIHJhc3RlcikgeworICAgICAgICBTYW1wbGVNb2RlbCBzbSA9IHJhc3Rlci5nZXRTYW1wbGVNb2RlbCgpOworICAgICAgICBpZiAoIShzbSBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpc207CisKKyAgICAgICAgaWYgKHNwcHNtLmdldE51bUJhbmRzKCkgIT0gbnVtQ29tcG9uZW50cykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChyYXN0ZXIuZ2V0VHJhbnNmZXJUeXBlKCkgIT0gdHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbWFza0JhbmRzW10gPSBzcHBzbS5nZXRCaXRNYXNrcygpOworICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhtYXNrQmFuZHMsIGNvbXBvbmVudE1hc2tzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldERhdGFFbGVtZW50KGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgaW50IHBpeGVsID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgIHBpeGVsIHw9IChjb21wb25lbnRzW29mZnNldCArIGldIDw8IG9mZnNldHNbaV0pICYgY29tcG9uZW50TWFza3NbaV07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBpeGVsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnRbXSBnZXRDb21wb25lbnRzKGludCBwaXhlbCwgaW50IGNvbXBvbmVudHNbXSwgaW50IG9mZnNldCkgeworICAgICAgICBpZiAoY29tcG9uZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICBjb21wb25lbnRzID0gbmV3IGludFtudW1Db21wb25lbnRzICsgb2Zmc2V0XTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgY29tcG9uZW50c1tvZmZzZXQgKyBpXSA9IChwaXhlbCAmIGNvbXBvbmVudE1hc2tzW2ldKSA+PiBvZmZzZXRzW2ldOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb21wb25lbnRzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UmVkKGludCBwaXhlbCkgeworICAgICAgICBpZiAoaXNfc1JHQikgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudEZyb21fc1JHQihwaXhlbCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzX0xJTkVBUl9SR0IpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDb21wb25lbnRGcm9tX0xJTkVBUl9SR0IocGl4ZWwsIDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRDb21wb25lbnRGcm9tX1JHQihwaXhlbCwgMCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCBnZXRSR0IoaW50IHBpeGVsKSB7CisgICAgICAgIHJldHVybiAoZ2V0QWxwaGEocGl4ZWwpIDw8IDI0KSB8IChnZXRSZWQocGl4ZWwpIDw8IDE2KSB8IChnZXRHcmVlbihwaXhlbCkgPDwgOCkKKyAgICAgICAgICAgICAgICB8IGdldEJsdWUocGl4ZWwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0R3JlZW4oaW50IHBpeGVsKSB7CisgICAgICAgIGlmIChpc19zUkdCKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50RnJvbV9zUkdCKHBpeGVsLCAxKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudEZyb21fTElORUFSX1JHQihwaXhlbCwgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudEZyb21fUkdCKHBpeGVsLCAxKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEJsdWUoaW50IHBpeGVsKSB7CisgICAgICAgIGlmIChpc19zUkdCKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50RnJvbV9zUkdCKHBpeGVsLCAyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudEZyb21fTElORUFSX1JHQihwaXhlbCwgMik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudEZyb21fUkdCKHBpeGVsLCAyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEFscGhhKGludCBwaXhlbCkgeworICAgICAgICBpZiAoIWhhc0FscGhhKSB7CisgICAgICAgICAgICByZXR1cm4gMjU1OworICAgICAgICB9CisgICAgICAgIGludCBhID0gKHBpeGVsICYgY29tcG9uZW50TWFza3NbM10pID4+PiBvZmZzZXRzWzNdOworICAgICAgICBpZiAoYml0c1szXSA9PSA4KSB7CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWxwaGFMVVRbYV0gJiAweGZmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHJlZCBtYXNrLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHJlZCBtYXNrLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UmVkTWFzaygpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudE1hc2tzWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdyZWVuIG1hc2suCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZ3JlZW4gbWFzay4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEdyZWVuTWFzaygpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudE1hc2tzWzFdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJsdWUgbWFzay4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBibHVlIG1hc2suCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRCbHVlTWFzaygpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudE1hc2tzWzJdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFscGhhIG1hc2suCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYWxwaGEgbWFzay4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEFscGhhTWFzaygpIHsKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICByZXR1cm4gY29tcG9uZW50TWFza3NbM107CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6YXRpb24gb2YgTG9va3VwIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdExVVHMoKSB7CisgICAgICAgIGlzX3NSR0IgPSBjcy5pc0NTX3NSR0IoKTsKKyAgICAgICAgaXNfTElORUFSX1JHQiA9IChjcyA9PSBMVVRDb2xvckNvbnZlcnRlci5MSU5FQVJfUkdCX0NTKTsKKworICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgaWYgKG1heEJpdExlbmd0aCA+IDgpIHsKKyAgICAgICAgICAgICAgICBMSU5FQVJfUkdCX0xlbmd0aCA9IDE2OworICAgICAgICAgICAgICAgIGZyb21fTElORUFSX1JHQl9MVVQgPSBMVVRDb2xvckNvbnZlcnRlci5nZXRGcm9tMTZsUkdCdG9zUkdCX0xVVCgpOworICAgICAgICAgICAgICAgIHRvX0xJTkVBUl8xNlJHQl9MVVQgPSBMVVRDb2xvckNvbnZlcnRlci5nZXRGcm9tc1JHQnRvMTZsUkdCX0xVVCgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMSU5FQVJfUkdCX0xlbmd0aCA9IDg7CisgICAgICAgICAgICAgICAgZnJvbV9MSU5FQVJfUkdCX0xVVCA9IExVVENvbG9yQ29udmVydGVyLmdldEZyb204bFJHQnRvc1JHQl9MVVQoKTsKKyAgICAgICAgICAgICAgICB0b19MSU5FQVJfOFJHQl9MVVQgPSBMVVRDb2xvckNvbnZlcnRlci5nZXRGcm9tc1JHQnRvOGxSR0JfTFVUKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmRmFjdG9yID0gKCgxIDw8IExJTkVBUl9SR0JfTGVuZ3RoKSAtIDEpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZkZhY3RvciA9IDI1NS4wZjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChoYXNBbHBoYSAmJiBiaXRzWzNdICE9IDgpIHsKKyAgICAgICAgICAgIGFscGhhTFVUID0gbmV3IGJ5dGVbbWF4VmFsdWVzWzNdICsgMV07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBtYXhWYWx1ZXNbM107IGkrKykgeworICAgICAgICAgICAgICAgIGFscGhhTFVUW2ldID0gKGJ5dGUpKHNjYWxlc1szXSAqIGkgKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICAgICAgY29sb3JMVVRzID0gbmV3IGJ5dGVbM11bXTsKKworICAgICAgICAgICAgaWYgKGlzX3NSR0IpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChiaXRzW2ldICE9IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNbaV0gPT0gYml0c1tqXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvckxVVHNbaV0gPSBjb2xvckxVVHNbal07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTFVUc1tpXSA9IG5ldyBieXRlW21heFZhbHVlc1tpXSArIDFdOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gbWF4VmFsdWVzW2ldOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvckxVVHNbaV1bal0gPSAoYnl0ZSkoc2NhbGVzW2ldICogaiArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXNfTElORUFSX1JHQikgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNbaV0gIT0gTElORUFSX1JHQl9MZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNbaV0gPT0gYml0c1tqXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvckxVVHNbaV0gPSBjb2xvckxVVHNbal07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTFVUc1tpXSA9IG5ldyBieXRlW21heFZhbHVlc1tpXSArIDFdOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gbWF4VmFsdWVzWzBdOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWR4OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChMSU5FQVJfUkdCX0xlbmd0aCA9PSA4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeCA9IChpbnQpKHNjYWxlc1tpXSAqIGogKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHggPSAoaW50KShzY2FsZXNbaV0gKiBqICogMjU3LjBmICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTFVUc1tpXVtqXSA9IGZyb21fTElORUFSX1JHQl9MVVRbaWR4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJuIFJHQiBjb21wb25lbnQgdmFsdWUgaWYgQ29sb3IgTW9kZWwgaGFzIHNSR0IKKyAgICAgKiBDb2xvclNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGl4ZWwgY29tcG9uZW50LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwaXhlbCBjb21wb25lbnQgc2NhbGVkIGZyb20gMCB0byAyNTUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q29tcG9uZW50RnJvbV9zUkdCKGludCBwaXhlbCwgaW50IGlkeCkgeworICAgICAgICBpbnQgY29tcCA9IChwaXhlbCAmIGNvbXBvbmVudE1hc2tzW2lkeF0pID4+IG9mZnNldHNbaWR4XTsKKyAgICAgICAgaWYgKGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgICAgICBpbnQgYWxwaGEgPSAocGl4ZWwgJiBjb21wb25lbnRNYXNrc1szXSkgPj4+IG9mZnNldHNbM107CisgICAgICAgICAgICBjb21wID0gYWxwaGEgPT0gMCA/IDAgOiAoaW50KShzY2FsZXNbaWR4XSAqIGNvbXAgKiAyNTUuMGYgLyAoc2NhbGVzWzNdICogYWxwaGEpICsgMC41Zik7CisgICAgICAgIH0gZWxzZSBpZiAoYml0c1tpZHhdICE9IDgpIHsKKyAgICAgICAgICAgIGNvbXAgPSBjb2xvckxVVHNbaWR4XVtjb21wXSAmIDB4ZmY7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJuIFJHQiBjb21wb25lbnQgdmFsdWUgaWYgQ29sb3IgTW9kZWwgaGFzIExpbmVhciBSR0IKKyAgICAgKiBDb2xvclNwYWNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGl4ZWwgY29tcG9uZW50LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwaXhlbCBjb21wb25lbnQgc2NhbGVkIGZyb20gMCB0byAyNTUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q29tcG9uZW50RnJvbV9MSU5FQVJfUkdCKGludCBwaXhlbCwgaW50IGlkeCkgeworICAgICAgICBpbnQgY29tcCA9IChwaXhlbCAmIGNvbXBvbmVudE1hc2tzW2lkeF0pID4+IG9mZnNldHNbaWR4XTsKKyAgICAgICAgaWYgKGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgICAgICBmbG9hdCBmYWN0b3IgPSAoKDEgPDwgTElORUFSX1JHQl9MZW5ndGgpIC0gMSk7CisgICAgICAgICAgICBpbnQgYWxwaGEgPSAocGl4ZWwgJiBjb21wb25lbnRNYXNrc1szXSkgPj4gb2Zmc2V0c1szXTsKKyAgICAgICAgICAgIGNvbXAgPSBhbHBoYSA9PSAwID8gMCA6IChpbnQpKHNjYWxlc1tpZHhdICogY29tcCAqIGZhY3RvciAvIChzY2FsZXNbM10gKiBhbHBoYSkgKyAwLjVmKTsKKyAgICAgICAgfSBlbHNlIGlmIChiaXRzW2lkeF0gIT0gTElORUFSX1JHQl9MZW5ndGgpIHsKKyAgICAgICAgICAgIGNvbXAgPSBjb2xvckxVVHNbaWR4XVtjb21wXSAmIDB4ZmY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb21wID0gZnJvbV9MSU5FQVJfUkdCX0xVVFtjb21wXSAmIDB4ZmY7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJuIFJHQiBjb21wb25lbnQgdmFsdWUgaWYgQ29sb3IgTW9kZWwgaGFzIGFyYml0cmFyeSBSR0IKKyAgICAgKiBDb2xvclNhcGNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGl4ZWwgY29tcG9uZW50LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwaXhlbCBjb21wb25lbnQgc2NhbGVkIGZyb20gMCB0byAyNTUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q29tcG9uZW50RnJvbV9SR0IoaW50IHBpeGVsLCBpbnQgaWR4KSB7CisgICAgICAgIGludCBjb21wb25lbnRzW10gPSBnZXRDb21wb25lbnRzKHBpeGVsLCBudWxsLCAwKTsKKyAgICAgICAgZmxvYXRbXSBub3JtQ29tcG9uZW50cyA9IGdldE5vcm1hbGl6ZWRDb21wb25lbnRzKGNvbXBvbmVudHMsIDAsIG51bGwsIDApOworICAgICAgICBmbG9hdFtdIHNSR0Jjb21wb25lbnRzID0gY3MudG9SR0Iobm9ybUNvbXBvbmVudHMpOworICAgICAgICByZXR1cm4gKGludCkoc1JHQmNvbXBvbmVudHNbaWR4XSAqIDI1NS4wZiArIDAuNWYpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0ZpbHRlcmVkSW1hZ2VTb3VyY2UuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9GaWx0ZXJlZEltYWdlU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ4NTU4ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9GaWx0ZXJlZEltYWdlU291cmNlLmphdmEKQEAgLTAsMCArMSw5OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCisvKioKKyAqIFRoZSBGaWx0ZXJlZEltYWdlU291cmNlIGNsYXNzIGlzIHVzZWQgZm9yIHByb2R1Y2luZyBpbWFnZSBkYXRhIGZvciBhIG5ldworICogZmlsdGVyZWQgdmVyc2lvbiBvZiB0aGUgb3JpZ2luYWwgaW1hZ2UgdXNpbmcgdGhlIHNwZWNpZmllZCBmaWx0ZXIgb2JqZWN0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZpbHRlcmVkSW1hZ2VTb3VyY2UgaW1wbGVtZW50cyBJbWFnZVByb2R1Y2VyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzb3VyY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbWFnZVByb2R1Y2VyIHNvdXJjZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmaWx0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbWFnZUZpbHRlciBmaWx0ZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29ucyB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxJbWFnZUNvbnN1bWVyLCBJbWFnZUNvbnN1bWVyPiBjb25zVGFibGUgPSBuZXcgSGFzaHRhYmxlPEltYWdlQ29uc3VtZXIsIEltYWdlQ29uc3VtZXI+KCk7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgRmlsdGVyZWRJbWFnZVNvdXJjZSBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogSW1hZ2VQcm9kdWNlciBhbmQgdGhlIEltYWdlRmlsdGVyIG9iamVjdHMuCisgICAgICogCisgICAgICogQHBhcmFtIG9yaWcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgSW1hZ2VQcm9kdWNlci4KKyAgICAgKiBAcGFyYW0gaW1nZgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBJbWFnZUZpbHRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsdGVyZWRJbWFnZVNvdXJjZShJbWFnZVByb2R1Y2VyIG9yaWcsIEltYWdlRmlsdGVyIGltZ2YpIHsKKyAgICAgICAgc291cmNlID0gb3JpZzsKKyAgICAgICAgZmlsdGVyID0gaW1nZjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNDb25zdW1lcihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGlmIChpYyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY29uc1RhYmxlLmNvbnRhaW5zS2V5KGljKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RhcnRQcm9kdWN0aW9uKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgYWRkQ29uc3VtZXIoaWMpOworICAgICAgICBJbWFnZUNvbnN1bWVyIGZpYyA9IGNvbnNUYWJsZS5nZXQoaWMpOworICAgICAgICBzb3VyY2Uuc3RhcnRQcm9kdWN0aW9uKGZpYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVxdWVzdFRvcERvd25MZWZ0UmlnaHRSZXNlbmQoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBpZiAoaWMgIT0gbnVsbCAmJiBpc0NvbnN1bWVyKGljKSkgeworICAgICAgICAgICAgSW1hZ2VGaWx0ZXIgZmljID0gKEltYWdlRmlsdGVyKWNvbnNUYWJsZS5nZXQoaWMpOworICAgICAgICAgICAgZmljLnJlc2VuZFRvcERvd25MZWZ0UmlnaHQoc291cmNlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVDb25zdW1lcihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGlmIChpYyAhPSBudWxsICYmIGlzQ29uc3VtZXIoaWMpKSB7CisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyIGZpYyA9IGNvbnNUYWJsZS5nZXQoaWMpOworICAgICAgICAgICAgc291cmNlLnJlbW92ZUNvbnN1bWVyKGZpYyk7CisgICAgICAgICAgICBjb25zVGFibGUucmVtb3ZlKGljKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRDb25zdW1lcihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGlmIChpYyAhPSBudWxsICYmICFpc0NvbnN1bWVyKGljKSkgeworICAgICAgICAgICAgSW1hZ2VDb25zdW1lciBmaWMgPSBmaWx0ZXIuZ2V0RmlsdGVySW5zdGFuY2UoaWMpOworICAgICAgICAgICAgc291cmNlLmFkZENvbnN1bWVyKGZpYyk7CisgICAgICAgICAgICBjb25zVGFibGUucHV0KGljLCBmaWMpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0ltYWdlQ29uc3VtZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZUNvbnN1bWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2FmODdkMQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZUNvbnN1bWVyLmphdmEKQEAgLTAsMCArMSwxODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworLyoqCisgKiBUaGUgSW1hZ2VDb25zdW1lciBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIGRhdGEgYWJvdXQgdGhlIGltYWdlIGFuZCBhYm91dCBob3cKKyAqIGl0cyBkYXRhIGlzIGRlbGl2ZXJlZC4gQSBJbWFnZVByb2R1Y2VyIHByb3ZpZGVzIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gYWJvdXQKKyAqIHRoZSBpbWFnZSB1c2luZyB0aGUgbWV0aG9kcyBkZWZpbmVkIGluIHRoaXMgaW50ZXJmYWNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJbWFnZUNvbnN1bWVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBSQU5ET01QSVhFTE9SREVSIGluZGljYXRlcyB0aGF0IHRoZSBwaXhlbHMgYXJlIGRlbGl2ZXJlZCBpbgorICAgICAqIGEgcmFuZG9tIG9yZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJBTkRPTVBJWEVMT1JERVIgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFRPUERPV05MRUZUUklHSFQgaW5kaWNhdGVzIHRoYXQgdGhlIHBpeGVscyBhcmUgZGVsaXZlcmVkIGluCisgICAgICogdG9wLWRvd24sIGxlZnQtdG8tcmlnaHQgb3JkZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVE9QRE9XTkxFRlRSSUdIVCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ09NUExFVEVTQ0FOTElORVMgaW5kaWNhdGVzIHRoYXQgdGhlIHBpeGVscyBhcmUgZGVsaXZlcmVkIGluCisgICAgICogY29tcGxldGUgc2NhbmxpbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUExFVEVTQ0FOTElORVMgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNJTkdMRVBBU1MgaW5kaWNhdGVzIHRoYXQgcGl4ZWxzIGFyZSBkZWxpdmVyZWQgaW4gYSBzaW5nbGUKKyAgICAgKiBwYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJTkdMRVBBU1MgPSA4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNJTkdMRUZSQU1FIGluZGljYXRlcyB0aGF0IGltYWdlIGNvbnNpc3RzIG9mIHNpbmdsZSBmcmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU5HTEVGUkFNRSA9IDE2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IElNQUdFRVJST1IgaW5kaWNhdGVzIGFuIGltYWdlIGVycm9yIGR1cmluZyBpbWFnZSBwcm9kdWNpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU1BR0VFUlJPUiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgU0lOR0xFRlJBTUVET05FIGluZGljYXRlcyB0aGF0IG9ubHkgb25lIG9mIHRoZSBpbWFnZSdzCisgICAgICogZnJhbWVzIGlzIGNvbXBsZXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU5HTEVGUkFNRURPTkUgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNUQVRJQ0lNQUdFRE9ORSBpbmRpY2F0ZXMgdGhhdCB0aGUgaW1hZ2UgaXMgY29tcGxldGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUQVRJQ0lNQUdFRE9ORSA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSU1BR0VBQk9SVEVEIGluZGljYXRlcyB0aGF0IHRoZSBpbWFnZSBwcm9kdWNpbmcgcHJvY2VzcyBpcworICAgICAqIGFib3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU1BR0VBQk9SVEVEID0gNDsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHByb3BlcnRpZXMgZm9yIHRoZSBpbWFnZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBJbWFnZUNvbnN1bWVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm9wcworICAgICAqICAgICAgICAgICAgdGhlIHByb3BlcnRpZXMgZm9yIHRoZSBpbWFnZSBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqICAgICAgICAgICAgSW1hZ2VDb25zdW1lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0aWVzKEhhc2h0YWJsZTw/LCA/PiBwcm9wcyk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBDb2xvck1vZGVsIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgQ29sb3JNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb2xvck1vZGVsKENvbG9yTW9kZWwgbW9kZWwpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGl4ZWxzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YgdGhlIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gbW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgQ29sb3JNb2RlbCB0byBiZSB1c2VkIGZvciBwaXhlbHMgY29udmVydGluZy4KKyAgICAgKiBAcGFyYW0gcGl4ZWxzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgcGl4ZWxzIGFycmF5LgorICAgICAqIEBwYXJhbSBzY2Fuc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIGZyb20gdGhlIG9uZSByb3cgb2YgcGl4ZWxzIHRvIHRoZSBuZXh0IHJvdyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIGludFtdIHBpeGVscywgaW50IG9mZiwKKyAgICAgICAgICAgIGludCBzY2Fuc2l6ZSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwaXhlbHMgZm9yIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZiB0aGUgaW1hZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBtb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBDb2xvck1vZGVsIHRvIGJlIHVzZWQgZm9yIHBpeGVscyBjb252ZXJ0aW5nLgorICAgICAqIEBwYXJhbSBwaXhlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBwaXhlbHMgYXJyYXkuCisgICAgICogQHBhcmFtIHNjYW5zaXplCisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgb25lIHJvdyBvZiBwaXhlbHMgdG8gdGhlIG5leHQgcm93IGluIHRoZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgYnl0ZVtdIHBpeGVscywgaW50IG9mZiwKKyAgICAgICAgICAgIGludCBzY2Fuc2l6ZSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkaW1lbnNpb25zIG9mIGEgc291cmNlIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaW1lbnNpb25zKGludCB3aWR0aCwgaW50IGhlaWdodCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBoaW50IGZsYWdzIG9mIHBpeGVscyBvcmRlciwgd2hpY2ggaXMgdXNlZCBieSB0aGUgSW1hZ2VDb25zdW1lcgorICAgICAqIGZvciBvYnRhaW5pbmcgcGl4ZWxzIGZyb20gdGhlIEltYWdlUHJvZHVjZXIgZm9yIHdoaWNoIHRoaXMgSW1hZ2VDb25zdW1lcgorICAgICAqIGlzIGFkZGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBoaW50ZmxhZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXNrIG9mIGhpbnQgZmxhZ3MuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SGludHMoaW50IGhpbnRmbGFncyk7CisKKyAgICAvKioKKyAgICAgKiBUSGlzIG1ldGhvZCBpcyBjYWxsZWQgaW4gdGhlIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIEltYWdlUHJvZHVjZXIgKGZvciB3aGljaCB0aGlzIEltYWdlQ29uc3VtZXIgaXMgYWRkZWQpIGhhcyBiZWVuCisgICAgICogZGVsaXZlcmVkIGFsbCBwaXhlbHMgb2YgdGhlIHNvdXJjZSBpbWFnZS48L2xpPgorICAgICAqIDxsaT5BIG9uZSBmcmFtZSBvZiBhbiBhbmltYXRpb24gaGFzIGJlZW4gY29tcGxldGVkLjwvbGk+CisgICAgICogPGxpPkFuIGVycm9yIHdoaWxlIGxvYWRpbmcgb3IgcHJvZHVjaW5nIG9mIHRoZSBpbWFnZSBoYXMgb2NjdXJyZWQuCisgICAgICogPC91bD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RhdHVzCisgICAgICogICAgICAgICAgICB0aGUgc3RhdHVzIG9mIGltYWdlIHByb2R1Y2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbWFnZUNvbXBsZXRlKGludCBzdGF0dXMpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2VGaWx0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyYzlmNTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2VGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDEzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCisvKioKKyAqIFRoZSBJbWFnZUZpbHRlciBjbGFzcyBwcm92aWRlcyBhIGZpbHRlciBmb3IgZGVsaXZlcmluZyBpbWFnZSBkYXRhIGZyb20gYW4KKyAqIEltYWdlUHJvZHVjZXIgdG8gYW4gSW1hZ2VDb25zdW1lci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbWFnZUZpbHRlciBpbXBsZW1lbnRzIEltYWdlQ29uc3VtZXIsIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3VtZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIEltYWdlQ29uc3VtZXIgY29uc3VtZXI7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VGaWx0ZXIuCisgICAgICovCisgICAgcHVibGljIEltYWdlRmlsdGVyKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gaW5zdGFuY2Ugb2YgYW4gSW1hZ2VGaWx0ZXIgb2JqZWN0IHdoaWNoIHBlcmZvcm1zIHRoZSBmaWx0ZXJpbmcKKyAgICAgKiBmb3IgdGhlIHNwZWNpZmllZCBJbWFnZUNvbnN1bWVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpYworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBJbWFnZUNvbnN1bWVyLgorICAgICAqIEByZXR1cm4gYW4gSW1hZ2VGaWx0ZXIgdXNlZCB0byBwZXJmb3JtIHRoZSBmaWx0ZXJpbmcgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIEltYWdlQ29uc3VtZXIuCisgICAgICovCisgICAgcHVibGljIEltYWdlRmlsdGVyIGdldEZpbHRlckluc3RhbmNlKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgSW1hZ2VGaWx0ZXIgZmlsdGVyID0gKEltYWdlRmlsdGVyKWNsb25lKCk7CisgICAgICAgIGZpbHRlci5jb25zdW1lciA9IGljOworICAgICAgICByZXR1cm4gZmlsdGVyOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnRpZXMoSGFzaHRhYmxlPD8sID8+IHByb3BzKSB7CisgICAgICAgIEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4gZnByb3BzOworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCkgeworICAgICAgICAgICAgZnByb3BzID0gbmV3IEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZwcm9wcyA9IChIYXNodGFibGU8T2JqZWN0LCBPYmplY3Q+KXByb3BzLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gIkZpbHRlcnMiOyAvLyROT04tTkxTLTEkCisgICAgICAgIFN0cmluZyBwcm9wID0gIk51bGwgZmlsdGVyIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICBPYmplY3QgbyA9IGZwcm9wcy5nZXQocHJvcE5hbWUpOworICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgICAgIHByb3AgPSAoU3RyaW5nKW8gKyAiOyAiICsgcHJvcDsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwcm9wID0gby50b1N0cmluZygpICsgIjsgIiArIHByb3A7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmcHJvcHMucHV0KHByb3BOYW1lLCBwcm9wKTsKKyAgICAgICAgY29uc3VtZXIuc2V0UHJvcGVydGllcyhmcHJvcHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMgSW1hZ2VGaWx0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhpcyBJbWFnZUZpbHRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzcG9uZHMgdG8gYSByZXF1ZXN0IGZvciBhIFRvcC1Eb3duLUxlZnQtUmlnaHQgb3JkZXJlZCByZXNlbmQgb2YgdGhlCisgICAgICogcGl4ZWwgZGF0YSBmcm9tIGFuIEltYWdlQ29uc3VtZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGlwCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VQcm9kdWNlciB0aGF0IHByb3ZpZGVzIHRoaXMgaW5zdGFuY2Ugb2YgdGhlIGZpbHRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNlbmRUb3BEb3duTGVmdFJpZ2h0KEltYWdlUHJvZHVjZXIgaXApIHsKKyAgICAgICAgaXAucmVxdWVzdFRvcERvd25MZWZ0UmlnaHRSZXNlbmQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sb3JNb2RlbChDb2xvck1vZGVsIG1vZGVsKSB7CisgICAgICAgIGNvbnN1bWVyLnNldENvbG9yTW9kZWwobW9kZWwpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgaW50W10gcGl4ZWxzLCBpbnQgb2ZmLAorICAgICAgICAgICAgaW50IHNjYW5zaXplKSB7CisgICAgICAgIGNvbnN1bWVyLnNldFBpeGVscyh4LCB5LCB3LCBoLCBtb2RlbCwgcGl4ZWxzLCBvZmYsIHNjYW5zaXplKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGVbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKHgsIHksIHcsIGgsIG1vZGVsLCBwaXhlbHMsIG9mZiwgc2NhbnNpemUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERpbWVuc2lvbnMoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGNvbnN1bWVyLnNldERpbWVuc2lvbnMod2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SGludHMoaW50IGhpbnRzKSB7CisgICAgICAgIGNvbnN1bWVyLnNldEhpbnRzKGhpbnRzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbWFnZUNvbXBsZXRlKGludCBzdGF0dXMpIHsKKyAgICAgICAgY29uc3VtZXIuaW1hZ2VDb21wbGV0ZShzdGF0dXMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0ltYWdlT2JzZXJ2ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZU9ic2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFlYzQxYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZU9ic2VydmVyLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuSW1hZ2U7CisKKy8qKgorICogdGhlIEltYWdlT2JzZXJ2ZXIgaW50ZXJmYWNlIGlzIGFuIGFzeW5jaHJvbm91cyB1cGRhdGUgaW50ZXJmYWNlIGZvciByZWNlaXZpbmcKKyAqIG5vdGlmaWNhdGlvbnMgYWJvdXQgSW1hZ2UgY29uc3RydWN0aW9uIHN0YXR1cy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSW1hZ2VPYnNlcnZlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0lEVEggaW5kaWNhdGVzIHRoYXQgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBpcyBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lEVEggPSAxOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEhFSUdIVCBpbmRpY2F0ZXMgdGhhdCB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGlzIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIRUlHSFQgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFBST1BFUlRJRVMgaW5kaWNhdGVzIHRoYXQgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGltYWdlIGFyZQorICAgICAqIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9QRVJUSUVTID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBTT01FQklUUyBpbmRpY2F0ZXMgdGhhdCBtb3JlIGJpdHMgbmVlZGVkIGZvciBkcmF3aW5nIGEKKyAgICAgKiBzY2FsZWQgdmFyaWF0aW9uIG9mIHRoZSBpbWFnZSBwaXhlbHMgYXJlIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT01FQklUUyA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRlJBTUVCSVRTIGluZGljYXRlcyB0aGF0IGNvbXBsZXRlIGZyYW1lIG9mIGEgaW1hZ2Ugd2hpY2ggd2FzCisgICAgICogcHJldmlvdXNseSBkcmF3biBpcyBub3cgYXZhaWxhYmxlIGZvciBkcmF3aW5nIGFnYWluLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZSQU1FQklUUyA9IDE2OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEFMTEJJVFMgaW5kaWNhdGVzIHRoYXQgYW4gaW1hZ2Ugd2hpY2ggd2FzIHByZXZpb3VzbHkgZHJhd24KKyAgICAgKiBpcyBub3cgY29tcGxldGUgYW5kIGNhbiBiZSBkcmF3biBhZ2Fpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTExCSVRTID0gMzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgRVJST1IgaW5kaWNhdGVzIHRoYXQgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJST1IgPSA2NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBBQk9SVCBpbmRpY2F0ZXMgdGhhdCB0aGUgaW1hZ2UgcHJvZHVjaW5nIGlzIGFib3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUJPUlQgPSAxMjg7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBpbmZvcm1hdGlvbiBhYm91dCBhbiBJbWFnZSBpbnRlcmZhY2UgYmVjb21lcworICAgICAqIGF2YWlsYWJsZS4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIGZ1cnRoZXIgdXBkYXRlcyBhcmUgbmVlZGVkLCBmYWxzZQorICAgICAqIGlmIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1nCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgdG8gYmUgb2JzZXJ2ZWQuCisgICAgICogQHBhcmFtIGluZm9mbGFncworICAgICAqICAgICAgICAgICAgdGhlIGJpdHdpc2UgT1IgY29tYmluYXRpb24gb2YgaW5mb3JtYXRpb24gZmxhZ3M6IEFCT1JULAorICAgICAqICAgICAgICAgICAgQUxMQklUUywgRVJST1IsIEZSQU1FQklUUywgSEVJR0hULCBQUk9QRVJUSUVTLCBTT01FQklUUywKKyAgICAgKiAgICAgICAgICAgIFdJRFRILgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQuCisgICAgICogQHJldHVybiB0cnVlIGlmIGZ1cnRoZXIgdXBkYXRlcyBhcmUgbmVlZGVkLCBmYWxzZSBpZiBub3QuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaW1hZ2VVcGRhdGUoSW1hZ2UgaW1nLCBpbnQgaW5mb2ZsYWdzLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnZVByb2R1Y2VyLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2VQcm9kdWNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMzhiZTIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2VQcm9kdWNlci5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBJbWFnZVByb2R1Y2VyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3Igb2JqZWN0cyB3aGljaCBwcm9kdWNlIHRoZSBpbWFnZQorICogZGF0YS4gSW1hZ2VQcm9kdWNlciBpcyB1c2VkIGZvciByZWNvbnN0cnVjdGluZyB0aGUgaW1hZ2UuIEVhY2ggaW1hZ2UgY29udGFpbnMKKyAqIGFuIEltYWdlUHJvZHVjZXIuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIEltYWdlUHJvZHVjZXIgeworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgSW1hZ2VDb25zdW1lciBpcyByZWdpc3RlcmVkIHdpdGggdGhpcworICAgICAqIEltYWdlUHJvdmlkZXIgb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpYworICAgICAqICAgICAgICAgICAgdGhlIEltYWdlQ29uc3VtZXIgdG8gYmUgY2hlY2tlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgSW1hZ2VDb25zdW1lciBpcyByZWdpc3RlcmVkIHdpdGggdGhpcworICAgICAqICAgICAgICAgSW1hZ2VQcm92aWRlciwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYyk7CisKKyAgICAvKioKKyAgICAgKiBTdGFydHMgYSByZWNvbnN0cnVjdGlvbiBvZiB0aGUgaW1hZ2UgZGF0YSB3aGljaCB3aWxsIGJlIGRlbGl2ZXJlZCB0byB0aGlzCisgICAgICogY29uc3VtZXIuIFRoaXMgbWV0aG9kIGFkZHMgdGhlIHNwZWNpZmllZCBJbWFnZUNvbnN1bWVyIGJlZm9yZQorICAgICAqIHJlY29uc3RydWN0aW5nIHRoZSBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgSW1hZ2VDb25zdW1lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydFByb2R1Y3Rpb24oSW1hZ2VDb25zdW1lciBpYyk7CisKKyAgICAvKioKKyAgICAgKiBSZXF1ZXN0cyB0aGUgSW1hZ2VQcm9kdWNlciB0byByZXNlbmQgdGhlIGltYWdlIGRhdGEgaW4KKyAgICAgKiBJbWFnZUNvbnN1bWVyLlRPUERPV05MRUZUUklHSFQgb3JkZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGljCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEltYWdlQ29uc3VtZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVxdWVzdFRvcERvd25MZWZ0UmlnaHRSZXNlbmQoSW1hZ2VDb25zdW1lciBpYyk7CisKKyAgICAvKioKKyAgICAgKiBEZXJlZ2lzdGVycyB0aGUgc3BlY2lmaWVkIEltYWdlQ29uc3VtZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGljCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEltYWdlQ29uc3VtZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYyk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgSW1hZ2VDb25zdW1lciBvYmplY3QgdG8gdGhpcyBJbWFnZVByb2R1Y2VyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpYworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBJbWFnZUNvbnN1bWVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZENvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2luZ09wRXhjZXB0aW9uLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvSW1hZ2luZ09wRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTBjMDEyNwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9JbWFnaW5nT3BFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogT2N0IDUsIDIwMDUKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBJbWFnaW5nT3BFeGNlcHRpb24gY2xhc3MgcHJvdmlkZXMgZXJyb3Igbm90aWZpY2F0aW9uIHdoZW4gdGhlCisgKiBCdWZmZXJlZEltYWdlT3Agb3IgUmFzdGVyT3AgZmlsdGVyIG1ldGhvZHMgY2FuIG5vdCBwZXJmb3JtIHRoZSBkZXNpcmVkIGZpbHRlcgorICogb3BlcmF0aW9uLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEltYWdpbmdPcEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODAyNjI4ODQ4MTg0NjI3NjY1OEw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uIHdpdGggYSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnaW5nT3BFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICAgICAgc3VwZXIocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL0luZGV4Q29sb3JNb2RlbC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0luZGV4Q29sb3JNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiMDZhY2QKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvSW5kZXhDb2xvck1vZGVsLmphdmEKQEAgLTAsMCArMSwxMDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LlRyYW5zcGFyZW5jeTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIEluZGV4Q29sb3JNb2RlbCByZXByZXNlbnRzIGEgY29sb3IgbW9kZWwgaW4gd2hpY2ggdGhlIGNvbG9yIHZhbHVlcworICogb2YgdGhlIHBpeGVscyBhcmUgcmVhZCBmcm9tIGEgcGFsZXR0ZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJbmRleENvbG9yTW9kZWwgZXh0ZW5kcyBDb2xvck1vZGVsIHsKKworICAgIC8qKgorICAgICAqIFRoZSBjb2xvciBtYXAuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgY29sb3JNYXBbXTsgLy8gQ29sb3IgTWFwCisKKyAgICAvKioKKyAgICAgKiBUaGUgbWFwIHNpemUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbWFwU2l6ZTsgLy8gQ29sb3IgTWFwIHNpemUKKworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc3BhcmVudCBpbmRleC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB0cmFuc3BhcmVudEluZGV4OyAvLyBJbmRleCBvZiBmdWxseSB0cmFuc3BhcmVudCBwaXhlbAorCisgICAgLyoqCisgICAgICogVGhlIGdyYXkgcGFsZXR0ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZ3JheVBhbGV0dGU7IC8vIENvbG9yIE1vZGVsIGhhcyBDb2xvciBNYXAgd2l0aCBHcmF5IFBhbGxldGUKKworICAgIC8qKgorICAgICAqIFRoZSB2YWxpZCBiaXRzLgorICAgICAqLworICAgIHByaXZhdGUgQmlnSW50ZWdlciB2YWxpZEJpdHM7IC8vIFNwZWNpZnkgdmFsaWQgQ29sb3IgTWFwIHZhbHVlcworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENBQ0hFU0laRS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0FDSEVTSVpFID0gMjA7IC8vIENhY2hlIHNpemUuIENhY2hlIHVzZWQgZm9yCisKKyAgICAvLyBpbXByb3ZpbmcgcGVyZm9ybWFjZSBvZiBzZWxlY3Rpb24KKyAgICAvLyBuZWFyZXN0IGNvbG9yIGluIENvbG9yIE1hcAorCisgICAgLyoqCisgICAgICogVGhlIGNhY2hldGFibGUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgY2FjaGV0YWJsZVtdID0gbmV3IGludFtDQUNIRVNJWkUgKiAyXTsgLy8gQ2FjaGUgdGFibGUgLQorCisgICAgLy8gdXNlZCBmb3IKKworICAgIC8vIHN0b3JpbmcgUkdCIHZhbHVlcyBhbmQgdGhhdCBhcHByb3ByaWF0ZSBpbmRpY2VzCisgICAgLy8gaW4gdGhlIENvbG9yIE1hcAorCisgICAgLyoqCisgICAgICogVGhlIG5leHQgaW5zZXJ0IGlkeC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBuZXh0SW5zZXJ0SWR4ID0gMDsgLy8gTmV4dCBpbmRleCBmb3IgaW5zZXJ0aW9uIGludG8gQ2FjaGUgdGFibGUKKworICAgIC8qKgorICAgICAqIFRoZSB0b3RhbCBpbnNlcnRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB0b3RhbEluc2VydGVkID0gMDsgLy8gTnVtYmVyIG9mIGluc2VydGVkIHZhbHVlcyBpbnRvIENhY2hlIHRhYmxlCisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgaW5kZXggY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBjb21wb25lbnQgbWFza3MuCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAuCisgICAgICogQHBhcmFtIGNtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IGdpdmVzIHRoZSBjb2xvciBtYXBwaW5nLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IG9mIHRoZSBjb2xvciBtYXBwaW5nIGRhdGEgd2l0aGluIHRoZSBjbWFwCisgICAgICogICAgICAgICAgICBhcnJheS4KKyAgICAgKiBAcGFyYW0gdHJhbnNmZXJUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmZXIgdHlwZSAocHJpbWl0aXZlIGphdmEgdHlwZSB0byB1c2UgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgY29tcG9uZW50cykuCisgICAgICogQHBhcmFtIHZhbGlkQml0cworICAgICAqICAgICAgICAgICAgYSBsaXN0IG9mIHdoaWNoIGJpdHMgcmVwcmVzZW50IHZhbGlkIGNvbG9ybWFwIHZhbHVlcywgb3IgbnVsbAorICAgICAqICAgICAgICAgICAgaWYgYWxsIGFyZSB2YWxpZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAgaXMgbGVzcyB0aGFuIG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5kZXhDb2xvck1vZGVsKGludCBiaXRzLCBpbnQgc2l6ZSwgaW50IGNtYXBbXSwgaW50IHN0YXJ0LCBpbnQgdHJhbnNmZXJUeXBlLAorICAgICAgICAgICAgQmlnSW50ZWdlciB2YWxpZEJpdHMpIHsKKworICAgICAgICBzdXBlcihiaXRzLCBJbmRleENvbG9yTW9kZWwuY3JlYXRlQml0cyh0cnVlKSwgQ29sb3JTcGFjZS5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpLAorICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBUcmFuc3BhcmVuY3kuT1BBUVVFLCB2YWxpZGF0ZVRyYW5zZmVyVHlwZSh0cmFuc2ZlclR5cGUpKTsKKworICAgICAgICBpZiAoc2l6ZSA8IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNjQ9U2l6ZSBvZiB0aGUgY29sb3IgbWFwIGlzIGxlc3MgdGhhbiAxCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgbWFwU2l6ZSA9IHNpemU7CisgICAgICAgIGNvbG9yTWFwID0gbmV3IGludFttYXBTaXplXTsKKyAgICAgICAgdHJhbnNwYXJlbnRJbmRleCA9IC0xOworCisgICAgICAgIGlmICh2YWxpZEJpdHMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBTaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIXZhbGlkQml0cy50ZXN0Qml0KGkpKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsaWRCaXRzID0gdmFsaWRCaXRzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5PUEFRVUU7CisgICAgICAgIGludCBhbHBoYU1hc2sgPSAweGZmMDAwMDAwOworICAgICAgICBpbnQgYWxwaGEgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwU2l6ZTsgaSsrLCBzdGFydCsrKSB7CisgICAgICAgICAgICBjb2xvck1hcFtpXSA9IGNtYXBbc3RhcnRdOworICAgICAgICAgICAgYWxwaGEgPSBjbWFwW3N0YXJ0XSAmIGFscGhhTWFzazsKKworICAgICAgICAgICAgaWYgKGFscGhhID09IGFscGhhTWFzaykgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFscGhhID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRJbmRleCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRJbmRleCA9IGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh0cmFuc3BhcmVuY3kgPT0gVHJhbnNwYXJlbmN5Lk9QQVFVRSkgeworICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuQklUTUFTSzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGFscGhhICE9IGFscGhhTWFzayAmJiB0cmFuc3BhcmVuY3kgIT0gVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5UKSB7CisgICAgICAgICAgICAgICAgdHJhbnNwYXJlbmN5ID0gVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5UOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICAgICAgY2hlY2tQYWxldHRlKCk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgaW5kZXggY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBjb21wb25lbnQgbWFza3MuCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAuCisgICAgICogQHBhcmFtIGNtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB0aGF0IGdpdmVzIHRoZSBjb2xvciBtYXBwaW5nLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IG9mIHRoZSBjb2xvciBtYXBwaW5nIGRhdGEgd2l0aGluIHRoZSBjbWFwCisgICAgICogICAgICAgICAgICBhcnJheS4KKyAgICAgKiBAcGFyYW0gaGFzYWxwaGEKKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdGhpcyBjb2xvciBtb2RlbCB1c2VzIGFscGhhLgorICAgICAqIEBwYXJhbSB0cmFucworICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zcGFyZW5jeSBzdXBwb3J0ZWQsIEBzZWUgamF2YS5hd3QuVHJhbnNwYXJlbmN5LgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2ZlciB0eXBlIChwcmltaXRpdmUgamF2YSB0eXBlIHRvIHVzZSBmb3IgdGhlCisgICAgICogICAgICAgICAgICBjb21wb25lbnRzKS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAgaXMgbGVzcyB0aGFuIG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5kZXhDb2xvck1vZGVsKGludCBiaXRzLCBpbnQgc2l6ZSwgaW50IGNtYXBbXSwgaW50IHN0YXJ0LCBib29sZWFuIGhhc2FscGhhLCBpbnQgdHJhbnMsCisgICAgICAgICAgICBpbnQgdHJhbnNmZXJUeXBlKSB7CisKKyAgICAgICAgc3VwZXIoYml0cywgSW5kZXhDb2xvck1vZGVsLmNyZWF0ZUJpdHMoaGFzYWxwaGEgfHwgKHRyYW5zID49IDApKSwgQ29sb3JTcGFjZQorICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShDb2xvclNwYWNlLkNTX3NSR0IpLCAoaGFzYWxwaGEgfHwgKHRyYW5zID49IDApKSwgZmFsc2UsCisgICAgICAgICAgICAgICAgVHJhbnNwYXJlbmN5Lk9QQVFVRSwgdmFsaWRhdGVUcmFuc2ZlclR5cGUodHJhbnNmZXJUeXBlKSk7CisKKyAgICAgICAgaWYgKHNpemUgPCAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjY0PVNpemUgb2YgdGhlIGNvbG9yIG1hcCBpcyBsZXNzIHRoYW4gMQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNjQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIG1hcFNpemUgPSBzaXplOworICAgICAgICBjb2xvck1hcCA9IG5ldyBpbnRbbWFwU2l6ZV07CisgICAgICAgIGlmICh0cmFucyA+PSAwICYmIHRyYW5zIDwgbWFwU2l6ZSkgeworICAgICAgICAgICAgdHJhbnNwYXJlbnRJbmRleCA9IHRyYW5zOworICAgICAgICAgICAgdHJhbnNwYXJlbmN5ID0gVHJhbnNwYXJlbmN5LkJJVE1BU0s7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cmFuc3BhcmVudEluZGV4ID0gLTE7CisgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuT1BBUVVFOworICAgICAgICB9CisKKyAgICAgICAgaW50IGFscGhhTWFzayA9IDB4ZmYwMDAwMDA7CisgICAgICAgIGludCBhbHBoYSA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBTaXplOyBpKyssIHN0YXJ0KyspIHsKKyAgICAgICAgICAgIGlmICh0cmFuc3BhcmVudEluZGV4ID09IGkpIHsKKyAgICAgICAgICAgICAgICBjb2xvck1hcFtpXSA9IGNtYXBbc3RhcnRdICYgMHgwMGZmZmZmZjsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChoYXNhbHBoYSkgeworICAgICAgICAgICAgICAgIGFscGhhID0gY21hcFtzdGFydF0gJiBhbHBoYU1hc2s7CisgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gPSBjbWFwW3N0YXJ0XTsKKworICAgICAgICAgICAgICAgIGlmIChhbHBoYSA9PSBhbHBoYU1hc2spIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChhbHBoYSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh0cmFucyA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zID0gaTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbmN5ID09IFRyYW5zcGFyZW5jeS5PUEFRVUUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5CSVRNQVNLOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhbHBoYSAhPSAwICYmIHRyYW5zcGFyZW5jeSAhPSBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbmN5ID0gVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5UOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gPSBhbHBoYU1hc2sgfCBjbWFwW3N0YXJ0XTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjaGVja1BhbGV0dGUoKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBpbmRleCBjb2xvciBtb2RlbCBieSBidWlsZGluZyB0aGUgY29sb3IgbWFwIGZyb20KKyAgICAgKiBhcnJheXMgb2YgcmVkLCBncmVlbiwgYmx1ZSwgYW5kIGFscGhhIHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGdpdmluZyB0aGUgcmVkIGNvbXBvbmVudHMgb2YgdGhlIGVudHJpZXMgaW4gdGhlCisgICAgICogICAgICAgICAgICBjb2xvciBtYXAuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBnaXZpbmcgdGhlIGdyZWVuIGNvbXBvbmVudHMgb2YgdGhlIGVudHJpZXMgaW4gdGhlCisgICAgICogICAgICAgICAgICBjb2xvciBtYXAuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBnaXZpbmcgdGhlIGJsdWUgY29tcG9uZW50cyBvZiB0aGUgZW50cmllcyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGdpdmluZyB0aGUgYWxwaGEgY29tcG9uZW50cyBvZiB0aGUgZW50cmllcyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1hcC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAgaXMgbGVzcyB0aGFuIG9uZS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIG9uZSBvZiB0aGUgY29tcG9uZW50IGFycmF5cyBpcyBsZXNzIHRoYW4gdGhlCisgICAgICogICAgICAgICAgICAgc2l6ZSBvZiB0aGUgY29sb3IgbWFwLgorICAgICAqLworICAgIHB1YmxpYyBJbmRleENvbG9yTW9kZWwoaW50IGJpdHMsIGludCBzaXplLCBieXRlIHJbXSwgYnl0ZSBnW10sIGJ5dGUgYltdLCBieXRlIGFbXSkgeworCisgICAgICAgIHN1cGVyKGJpdHMsIEluZGV4Q29sb3JNb2RlbC5jcmVhdGVCaXRzKHRydWUpLCBDb2xvclNwYWNlLmdldEluc3RhbmNlKENvbG9yU3BhY2UuQ1Nfc1JHQiksCisgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIFRyYW5zcGFyZW5jeS5PUEFRVUUsIHZhbGlkYXRlVHJhbnNmZXJUeXBlKENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRUcmFuc2ZlclR5cGUoYml0cykpKTsKKworICAgICAgICBjcmVhdGVDb2xvck1hcChzaXplLCByLCBnLCBiLCBhLCAtMSk7CisgICAgICAgIGNoZWNrUGFsZXR0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBpbmRleCBjb2xvciBtb2RlbCBieSBidWlsZGluZyB0aGUgY29sb3IgbWFwIGZyb20KKyAgICAgKiBhcnJheXMgb2YgcmVkLCBncmVlbiwgYW5kIGJsdWUgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY29tcG9uZW50IG1hc2tzLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgY29sb3IgbWFwLgorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgZ2l2aW5nIHRoZSByZWQgY29tcG9uZW50cyBvZiB0aGUgZW50cmllcyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGdpdmluZyB0aGUgZ3JlZW4gY29tcG9uZW50cyBvZiB0aGUgZW50cmllcyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGdpdmluZyB0aGUgYmx1ZSBjb21wb25lbnRzIG9mIHRoZSBlbnRyaWVzIGluIHRoZQorICAgICAqICAgICAgICAgICAgY29sb3IgbWFwLgorICAgICAqIEBwYXJhbSB0cmFucworICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zcGFyZW5jeSBzdXBwb3J0ZWQsIEBzZWUgamF2YS5hd3QuVHJhbnNwYXJlbmN5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIGNvbG9yIG1hcCBpcyBsZXNzIHRoYW4gb25lLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2Ygb25lIG9mIHRoZSBjb21wb25lbnQgYXJyYXlzIGlzIGxlc3MgdGhhbiB0aGUKKyAgICAgKiAgICAgICAgICAgICBzaXplIG9mIHRoZSBjb2xvciBtYXAuCisgICAgICovCisgICAgcHVibGljIEluZGV4Q29sb3JNb2RlbChpbnQgYml0cywgaW50IHNpemUsIGJ5dGUgcltdLCBieXRlIGdbXSwgYnl0ZSBiW10sIGludCB0cmFucykgeworCisgICAgICAgIHN1cGVyKGJpdHMsIEluZGV4Q29sb3JNb2RlbC5jcmVhdGVCaXRzKCh0cmFucyA+PSAwKSksIENvbG9yU3BhY2UKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19zUkdCKSwgKHRyYW5zID49IDApLCBmYWxzZSwgVHJhbnNwYXJlbmN5Lk9QQVFVRSwKKyAgICAgICAgICAgICAgICB2YWxpZGF0ZVRyYW5zZmVyVHlwZShDb2xvck1vZGVsLmdldFRyYW5zZmVyVHlwZShiaXRzKSkpOworCisgICAgICAgIGNyZWF0ZUNvbG9yTWFwKHNpemUsIHIsIGcsIGIsIG51bGwsIHRyYW5zKTsKKyAgICAgICAgY2hlY2tQYWxldHRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGluZGV4IGNvbG9yIG1vZGVsIGJ5IGJ1aWxkaW5nIHRoZSBjb2xvciBtYXAgZnJvbQorICAgICAqIGFycmF5cyBvZiByZWQsIGdyZWVuLCBhbmQgYmx1ZSB2YWx1ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBjb21wb25lbnQgbWFza3MuCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBjb2xvciBtYXAuCisgICAgICogQHBhcmFtIHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBnaXZpbmcgdGhlIHJlZCBjb21wb25lbnRzIG9mIHRoZSBlbnRyaWVzIGluIHRoZQorICAgICAqICAgICAgICAgICAgY29sb3IgbWFwLgorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgZ2l2aW5nIHRoZSBncmVlbiBjb21wb25lbnRzIG9mIHRoZSBlbnRyaWVzIGluIHRoZQorICAgICAqICAgICAgICAgICAgY29sb3IgbWFwLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgZ2l2aW5nIHRoZSBibHVlIGNvbXBvbmVudHMgb2YgdGhlIGVudHJpZXMgaW4gdGhlCisgICAgICogICAgICAgICAgICBjb2xvciBtYXAuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgY29sb3IgbWFwIGlzIGxlc3MgdGhhbiBvbmUuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiBvbmUgb2YgdGhlIGNvbXBvbmVudCBhcnJheXMgaXMgbGVzcyB0aGFuIHRoZQorICAgICAqICAgICAgICAgICAgIHNpemUgb2YgdGhlIGNvbG9yIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5kZXhDb2xvck1vZGVsKGludCBiaXRzLCBpbnQgc2l6ZSwgYnl0ZSByW10sIGJ5dGUgZ1tdLCBieXRlIGJbXSkgeworICAgICAgICBzdXBlcihiaXRzLCBJbmRleENvbG9yTW9kZWwuY3JlYXRlQml0cyhmYWxzZSksIENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19zUkdCKSwKKyAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UsIFRyYW5zcGFyZW5jeS5PUEFRVUUsIHZhbGlkYXRlVHJhbnNmZXJUeXBlKENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRUcmFuc2ZlclR5cGUoYml0cykpKTsKKworICAgICAgICBjcmVhdGVDb2xvck1hcChzaXplLCByLCBnLCBiLCBudWxsLCAtMSk7CisgICAgICAgIGNoZWNrUGFsZXR0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBpbmRleCBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gY21hcAorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRoYXQgZ2l2ZXMgdGhlIGNvbG9yIG1hcHBpbmcuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggb2YgdGhlIGNvbG9yIG1hcHBpbmcgZGF0YSB3aXRoaW4gdGhlIGNtYXAKKyAgICAgKiAgICAgICAgICAgIGFycmF5LgorICAgICAqIEBwYXJhbSBoYXNhbHBoYQorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGlzIGNvbG9yIG1vZGVsIHVzZXMgYWxwaGEuCisgICAgICogQHBhcmFtIHRyYW5zCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNwYXJlbmN5IHN1cHBvcnRlZCwgQHNlZSBqYXZhLmF3dC5UcmFuc3BhcmVuY3kuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgY29sb3IgbWFwIGlzIGxlc3MgdGhhbiBvbmUuCisgICAgICovCisgICAgcHVibGljIEluZGV4Q29sb3JNb2RlbChpbnQgYml0cywgaW50IHNpemUsIGJ5dGUgY21hcFtdLCBpbnQgc3RhcnQsIGJvb2xlYW4gaGFzYWxwaGEsIGludCB0cmFucykgeworCisgICAgICAgIHN1cGVyKGJpdHMsIEluZGV4Q29sb3JNb2RlbC5jcmVhdGVCaXRzKGhhc2FscGhhIHx8ICh0cmFucyA+PSAwKSksIENvbG9yU3BhY2UKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19zUkdCKSwgKGhhc2FscGhhIHx8ICh0cmFucyA+PSAwKSksIGZhbHNlLAorICAgICAgICAgICAgICAgIFRyYW5zcGFyZW5jeS5PUEFRVUUsIHZhbGlkYXRlVHJhbnNmZXJUeXBlKENvbG9yTW9kZWwuZ2V0VHJhbnNmZXJUeXBlKGJpdHMpKSk7CisKKyAgICAgICAgaWYgKHNpemUgPCAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjY0PVNpemUgb2YgdGhlIGNvbG9yIG1hcCBpcyBsZXNzIHRoYW4gMQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNjQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIG1hcFNpemUgPSBzaXplOworICAgICAgICBjb2xvck1hcCA9IG5ldyBpbnRbbWFwU2l6ZV07CisgICAgICAgIHRyYW5zcGFyZW50SW5kZXggPSAtMTsKKworICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuT1BBUVVFOworICAgICAgICBpbnQgYWxwaGEgPSAweGZmMDAwMDAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBjb2xvck1hcFtpXSA9IChjbWFwW3N0YXJ0KytdICYgMHhmZikgPDwgMTYgfCAoY21hcFtzdGFydCsrXSAmIDB4ZmYpIDw8IDgKKyAgICAgICAgICAgICAgICAgICAgfCAoY21hcFtzdGFydCsrXSAmIDB4ZmYpOworICAgICAgICAgICAgaWYgKHRyYW5zID09IGkpIHsKKyAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbmN5ID09IFRyYW5zcGFyZW5jeS5PUEFRVUUpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbmN5ID0gVHJhbnNwYXJlbmN5LkJJVE1BU0s7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChoYXNhbHBoYSkgeworICAgICAgICAgICAgICAgICAgICBzdGFydCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChoYXNhbHBoYSkgeworICAgICAgICAgICAgICAgIGFscGhhID0gY21hcFtzdGFydCsrXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgaWYgKGFscGhhID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW5jeSA9PSBUcmFuc3BhcmVuY3kuT1BBUVVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuQklUTUFTSzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFucyA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFucyA9IGk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAoYWxwaGEgIT0gMHhmZiAmJiB0cmFuc3BhcmVuY3kgIT0gVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5UKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYWxwaGEgPDw9IDI0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29sb3JNYXBbaV0gfD0gYWxwaGE7CisgICAgICAgIH0KKworICAgICAgICBpZiAodHJhbnMgPj0gMCAmJiB0cmFucyA8IG1hcFNpemUpIHsKKyAgICAgICAgICAgIHRyYW5zcGFyZW50SW5kZXggPSB0cmFuczsKKyAgICAgICAgfQorICAgICAgICBjaGVja1BhbGV0dGUoKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBpbmRleCBjb2xvciBtb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNvbXBvbmVudCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGNvbG9yIG1hcC4KKyAgICAgKiBAcGFyYW0gY21hcAorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRoYXQgZ2l2ZXMgdGhlIGNvbG9yIG1hcHBpbmcuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggb2YgdGhlIGNvbG9yIG1hcHBpbmcgZGF0YSB3aXRoaW4gdGhlIGNtYXAKKyAgICAgKiAgICAgICAgICAgIGFycmF5LgorICAgICAqIEBwYXJhbSBoYXNhbHBoYQorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGlzIGNvbG9yIG1vZGVsIHVzZXMgYWxwaGEuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgY29sb3IgbWFwIGlzIGxlc3MgdGhhbiBvbmUuCisgICAgICovCisgICAgcHVibGljIEluZGV4Q29sb3JNb2RlbChpbnQgYml0cywgaW50IHNpemUsIGJ5dGUgY21hcFtdLCBpbnQgc3RhcnQsIGJvb2xlYW4gaGFzYWxwaGEpIHsKKworICAgICAgICB0aGlzKGJpdHMsIHNpemUsIGNtYXAsIHN0YXJ0LCBoYXNhbHBoYSwgLTEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludFtdIGNvbXBvbmVudHMsIGludCBvZmZzZXQsIE9iamVjdCBwaXhlbCkgeworICAgICAgICBpbnQgcmdiID0gKGNvbXBvbmVudHNbb2Zmc2V0XSA8PCAxNikgfCAoY29tcG9uZW50c1tvZmZzZXQgKyAxXSkgPDwgOAorICAgICAgICAgICAgICAgIHwgY29tcG9uZW50c1tvZmZzZXQgKyAyXTsKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICByZ2IgfD0gY29tcG9uZW50c1tvZmZzZXQgKyAzXSA8PCAyNDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJnYiB8PSAweGZmMDAwMDAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREYXRhRWxlbWVudHMocmdiLCBwaXhlbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCByZ2IsIE9iamVjdCBwaXhlbCkgeworICAgICAgICBpbnQgcmVkID0gKHJnYiA+PiAxNikgJiAweGZmOworICAgICAgICBpbnQgZ3JlZW4gPSAocmdiID4+IDgpICYgMHhmZjsKKyAgICAgICAgaW50IGJsdWUgPSByZ2IgJiAweGZmOworICAgICAgICBpbnQgYWxwaGEgPSByZ2IgPj4+IDI0OworICAgICAgICBpbnQgcGl4SWR4ID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsSW5zZXJ0ZWQ7IGkrKykgeworICAgICAgICAgICAgaW50IGlkeCA9IGkgKiAyOworICAgICAgICAgICAgaWYgKHJnYiA9PSBjYWNoZXRhYmxlW2lkeF0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRGF0YU9iamVjdChjYWNoZXRhYmxlW2lkeCArIDFdLCBwaXhlbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWhhc0FscGhhICYmIGdyYXlQYWxldHRlKSB7CisgICAgICAgICAgICBpbnQgZ3JleSA9IChyZWQgKiA3NyArIGdyZWVuICogMTUwICsgYmx1ZSAqIDI5ICsgMTI4KSA+Pj4gODsKKyAgICAgICAgICAgIGludCBtaW5FcnJvciA9IDI1NTsKKyAgICAgICAgICAgIGludCBlcnJvciA9IDA7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZXJyb3IgPSBNYXRoLmFicygoY29sb3JNYXBbaV0gJiAweGZmKSAtIGdyZXkpOworICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IG1pbkVycm9yKSB7CisgICAgICAgICAgICAgICAgICAgIHBpeElkeCA9IGk7CisgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBtaW5FcnJvciA9IGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChhbHBoYSA9PSAwICYmIHRyYW5zcGFyZW50SW5kZXggPiAtMSkgeworICAgICAgICAgICAgcGl4SWR4ID0gdHJhbnNwYXJlbnRJbmRleDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBtaW5BbHBoYUVycm9yID0gMjU1OworICAgICAgICAgICAgaW50IG1pbkVycm9yID0gMTk1MDc1OyAvLyAyNTVeMiArIDI1NV4yICsgMjU1XjIKKyAgICAgICAgICAgIGludCBhbHBoYUVycm9yOworICAgICAgICAgICAgaW50IGVycm9yID0gMDsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBTaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpbnQgcGl4ID0gY29sb3JNYXBbaV07CisgICAgICAgICAgICAgICAgaWYgKHJnYiA9PSBwaXgpIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4SWR4ID0gaTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFscGhhRXJyb3IgPSBNYXRoLmFicyhhbHBoYSAtIChwaXggPj4+IDI0KSk7CisgICAgICAgICAgICAgICAgaWYgKGFscGhhRXJyb3IgPD0gbWluQWxwaGFFcnJvcikgeworICAgICAgICAgICAgICAgICAgICBtaW5BbHBoYUVycm9yID0gYWxwaGFFcnJvcjsKKworICAgICAgICAgICAgICAgICAgICBpbnQgYnVmID0gKChwaXggPj4gMTYpICYgMHhmZikgLSByZWQ7CisgICAgICAgICAgICAgICAgICAgIGVycm9yID0gYnVmICogYnVmOworCisgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IG1pbkVycm9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBidWYgPSAoKHBpeCA+PiA4KSAmIDB4ZmYpIC0gZ3JlZW47CisgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciArPSBidWYgKiBidWY7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IG1pbkVycm9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmID0gKHBpeCAmIDB4ZmYpIC0gYmx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciArPSBidWYgKiBidWY7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBtaW5FcnJvcikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhJZHggPSBpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5FcnJvciA9IGVycm9yOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNhY2hldGFibGVbbmV4dEluc2VydElkeF0gPSByZ2I7CisgICAgICAgIGNhY2hldGFibGVbbmV4dEluc2VydElkeCArIDFdID0gcGl4SWR4OworCisgICAgICAgIG5leHRJbnNlcnRJZHggPSAobmV4dEluc2VydElkeCArIDIpICUgKENBQ0hFU0laRSAqIDIpOworICAgICAgICBpZiAodG90YWxJbnNlcnRlZCA8IENBQ0hFU0laRSkgeworICAgICAgICAgICAgdG90YWxJbnNlcnRlZCsrOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNyZWF0ZURhdGFPYmplY3QocGl4SWR4LCBwaXhlbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYW4gaW1hZ2UgZnJvbSBpbmRleGVkIHRvIFJHQiBmb3JtYXQuCisgICAgICogCisgICAgICogQHBhcmFtIHJhc3RlcgorICAgICAqICAgICAgICAgICAgdGhlIHJhc3RlciBjb250YWluaW5nIHRoZSBzb3VyY2UgaW1hZ2UuCisgICAgICogQHBhcmFtIGZvcmNlQVJHQgorICAgICAqICAgICAgICAgICAgd2hldGhlciB0byB1c2UgdGhlIGRlZmF1bHQgUkdCIGNvbG9yIG1vZGVsLgorICAgICAqIEByZXR1cm4gdGhlIGJ1ZmZlcmVkIGltYWdlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJhc3RlciBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2UgY29udmVydFRvSW50RGlzY3JldGUoUmFzdGVyIHJhc3RlciwgYm9vbGVhbiBmb3JjZUFSR0IpIHsKKworICAgICAgICBpZiAoIWlzQ29tcGF0aWJsZVJhc3RlcihyYXN0ZXIpKSB7CisgICAgICAgICAgICAvLyBhd3QuMjY1PVRoZSByYXN0ZXIgYXJndW1lbnQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzCisgICAgICAgICAgICAvLyBJbmRleENvbG9yTW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjY1IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBDb2xvck1vZGVsIG1vZGVsOworICAgICAgICBpZiAoZm9yY2VBUkdCIHx8IHRyYW5zcGFyZW5jeSA9PSBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQpIHsKKyAgICAgICAgICAgIG1vZGVsID0gQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCk7CisgICAgICAgIH0gZWxzZSBpZiAodHJhbnNwYXJlbmN5ID09IFRyYW5zcGFyZW5jeS5CSVRNQVNLKSB7CisgICAgICAgICAgICBtb2RlbCA9IG5ldyBEaXJlY3RDb2xvck1vZGVsKDI1LCAweDAwZmYwMDAwLCAweDAwMDBmZjAwLCAweDAwMDAwMGZmLCAweDAxMDAwMDAwKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1vZGVsID0gbmV3IERpcmVjdENvbG9yTW9kZWwoMjQsIDB4MDBmZjAwMDAsIDB4MDAwMGZmMDAsIDB4MDAwMDAwZmYpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHcgPSByYXN0ZXIuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGggPSByYXN0ZXIuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgZGlzdFJhc3RlciA9IG1vZGVsLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3Rlcih3LCBoKTsKKworICAgICAgICBpbnQgbWluWCA9IHJhc3Rlci5nZXRNaW5YKCk7CisgICAgICAgIGludCBtaW5ZID0gcmFzdGVyLmdldE1pblkoKTsKKworICAgICAgICBPYmplY3Qgb2JqID0gbnVsbDsKKyAgICAgICAgaW50IHBpeGVsc1tdID0gbnVsbDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGg7IGkrKywgbWluWSsrKSB7CisgICAgICAgICAgICBvYmogPSByYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKG1pblgsIG1pblksIHcsIDEsIG9iaik7CisgICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlvYmo7CisgICAgICAgICAgICAgICAgaWYgKHBpeGVscyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHBpeGVscyA9IG5ldyBpbnRbYmEubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBiYS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgICAgICBwaXhlbHNbal0gPSBjb2xvck1hcFtiYVtqXSAmIDB4ZmZdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2Ygc2hvcnRbXSkgeworICAgICAgICAgICAgICAgIHNob3J0IHNhW10gPSAoc2hvcnRbXSlvYmo7CisgICAgICAgICAgICAgICAgaWYgKHBpeGVscyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHBpeGVscyA9IG5ldyBpbnRbc2EubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzYS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgICAgICBwaXhlbHNbal0gPSBjb2xvck1hcFtzYVtqXSAmIDB4ZmZmZl07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIGludFtdKSB7CisgICAgICAgICAgICAgICAgaW50IGlhW10gPSAoaW50W10pb2JqOworICAgICAgICAgICAgICAgIGlmIChwaXhlbHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwaXhlbHMgPSBuZXcgaW50W2lhLmxlbmd0aF07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaWEubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2pdID0gY29sb3JNYXBbaWFbal1dOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZGlzdFJhc3Rlci5zZXREYXRhRWxlbWVudHMoMCwgaSwgdywgMSwgcGl4ZWxzKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbWFnZShtb2RlbCwgZGlzdFJhc3RlciwgZmFsc2UsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbGlkIHBpeGVscy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWxpZCBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0VmFsaWRQaXhlbHMoKSB7CisgICAgICAgIHJldHVybiB2YWxpZEJpdHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGhlIG91dHB1dCBmb3JtYXQgYmFzZWQgb24gMS41IHJlbGVhc2UgYmVoYXZpb3VyLgorICAgICAgICAvLyBJdCBjb3VsZCBiZSByZXZlbGVkIHN1Y2ggd2F5OgorICAgICAgICAvLyBCdWZmZXJlZEltYWdlIGJpID0gbmV3IEJ1ZmZlcmVkSW1hZ2UoMSwgMSwKKyAgICAgICAgLy8gQnVmZmVyZWRJbWFnZS5UWVBFX0JZVEVfSU5ERVhFRCk7CisgICAgICAgIC8vIENvbG9yTW9kZWwgY20gPSBiaS5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihjbS50b1N0cmluZygpKTsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICJJbmRleENvbG9yTW9kZWw6ICNwaXhlbF9iaXRzID0gIiArIHBpeGVsX2JpdHMgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIiBudW1Db21wb25lbnRzID0gIiArIG51bUNvbXBvbmVudHMgKyAiIGNvbG9yIHNwYWNlID0gIiArIGNzICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgIiB0cmFuc3BhcmVuY3kgPSAiOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgaWYgKHRyYW5zcGFyZW5jeSA9PSBUcmFuc3BhcmVuY3kuT1BBUVVFKSB7CisgICAgICAgICAgICBzdHIgPSBzdHIgKyAiVHJhbnNwYXJlbmN5Lk9QQVFVRSI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfSBlbHNlIGlmICh0cmFuc3BhcmVuY3kgPT0gVHJhbnNwYXJlbmN5LkJJVE1BU0spIHsKKyAgICAgICAgICAgIHN0ciA9IHN0ciArICJUcmFuc3BhcmVuY3kuQklUTUFTSyI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN0ciA9IHN0ciArICJUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQiOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBzdHIgPSBzdHIgKyAiIHRyYW5zSW5kZXggPSAiICsgdHJhbnNwYXJlbnRJbmRleCArICIgaGFzIGFscGhhID0gIiArIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgICAgIGhhc0FscGhhICsgIiBpc0FscGhhUHJlID0gIiArIGlzQWxwaGFQcmVtdWx0aXBsaWVkOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgcmV0dXJuIHN0cjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50W10gZ2V0Q29tcG9uZW50cyhPYmplY3QgcGl4ZWwsIGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgaW50IHBpeElkeCA9IC0xOworICAgICAgICBpZiAocGl4ZWwgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10pcGl4ZWw7CisgICAgICAgICAgICBwaXhJZHggPSBiYVswXSAmIDB4ZmY7CisgICAgICAgIH0gZWxzZSBpZiAocGl4ZWwgaW5zdGFuY2VvZiBzaG9ydFtdKSB7CisgICAgICAgICAgICBzaG9ydCBzYVtdID0gKHNob3J0W10pcGl4ZWw7CisgICAgICAgICAgICBwaXhJZHggPSBzYVswXSAmIDB4ZmZmZjsKKyAgICAgICAgfSBlbHNlIGlmIChwaXhlbCBpbnN0YW5jZW9mIGludFtdKSB7CisgICAgICAgICAgICBpbnQgaWFbXSA9IChpbnRbXSlwaXhlbDsKKyAgICAgICAgICAgIHBpeElkeCA9IGlhWzBdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gYXd0LjIxOT1UaGlzIHRyYW5zZmVyVHlwZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgY29sb3IgbW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMTkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBnZXRDb21wb25lbnRzKHBpeElkeCwgY29tcG9uZW50cywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKGludCB3LCBpbnQgaCkgeworICAgICAgICBXcml0YWJsZVJhc3RlciByYXN0ZXI7CisgICAgICAgIGlmIChwaXhlbF9iaXRzID09IDEgfHwgcGl4ZWxfYml0cyA9PSAyIHx8IHBpeGVsX2JpdHMgPT0gNCkgeworICAgICAgICAgICAgcmFzdGVyID0gUmFzdGVyLmNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfQllURSwgdywgaCwgMSwgcGl4ZWxfYml0cywgbnVsbCk7CisgICAgICAgIH0gZWxzZSBpZiAocGl4ZWxfYml0cyA8PSA4KSB7CisgICAgICAgICAgICByYXN0ZXIgPSBSYXN0ZXIuY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHcsIGgsIDEsIG51bGwpOworICAgICAgICB9IGVsc2UgaWYgKHBpeGVsX2JpdHMgPD0gMTYpIHsKKyAgICAgICAgICAgIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCB3LCBoLCAxLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNjY9VGhlIG51bWJlciBvZiBiaXRzIGluIGEgcGl4ZWwgaXMgZ3JlYXRlciB0aGFuIDE2CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjY2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmFzdGVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcGF0aWJsZVNhbXBsZU1vZGVsKFNhbXBsZU1vZGVsIHNtKSB7CisgICAgICAgIGlmIChzbSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIShzbSBpbnN0YW5jZW9mIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgJiYgIShzbSBpbnN0YW5jZW9mIENvbXBvbmVudFNhbXBsZU1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNtLmdldFRyYW5zZmVyVHlwZSgpICE9IHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChzbS5nZXROdW1CYW5kcygpICE9IDEpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBjcmVhdGVDb21wYXRpYmxlU2FtcGxlTW9kZWwoaW50IHcsIGludCBoKSB7CisgICAgICAgIGlmIChwaXhlbF9iaXRzID09IDEgfHwgcGl4ZWxfYml0cyA9PSAyIHx8IHBpeGVsX2JpdHMgPT0gNCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwoRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIHcsIGgsIHBpeGVsX2JpdHMpOworICAgICAgICB9CisgICAgICAgIGludCBiYW5kT2Zmc2V0c1tdID0gbmV3IGludFsxXTsKKyAgICAgICAgYmFuZE9mZnNldHNbMF0gPSAwOworICAgICAgICByZXR1cm4gbmV3IENvbXBvbmVudFNhbXBsZU1vZGVsKHRyYW5zZmVyVHlwZSwgdywgaCwgMSwgdywgYmFuZE9mZnNldHMpOworCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDb21wYXRpYmxlUmFzdGVyKFJhc3RlciByYXN0ZXIpIHsKKyAgICAgICAgaW50IHNhbXBsZVNpemUgPSByYXN0ZXIuZ2V0U2FtcGxlTW9kZWwoKS5nZXRTYW1wbGVTaXplKDApOworICAgICAgICByZXR1cm4gKHJhc3Rlci5nZXRUcmFuc2ZlclR5cGUoKSA9PSB0cmFuc2ZlclR5cGUgJiYgcmFzdGVyLmdldE51bUJhbmRzKCkgPT0gMSAmJiAoMSA8PCBzYW1wbGVTaXplKSA+PSBtYXBTaXplKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldERhdGFFbGVtZW50KGludCBjb21wb25lbnRzW10sIGludCBvZmZzZXQpIHsKKyAgICAgICAgaW50IHJnYiA9IChjb21wb25lbnRzW29mZnNldF0gPDwgMTYpIHwgKGNvbXBvbmVudHNbb2Zmc2V0ICsgMV0pIDw8IDgKKyAgICAgICAgICAgICAgICB8IGNvbXBvbmVudHNbb2Zmc2V0ICsgMl07CisKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICByZ2IgfD0gY29tcG9uZW50c1tvZmZzZXQgKyAzXSA8PCAyNDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJnYiB8PSAweGZmMDAwMDAwOworICAgICAgICB9CisKKyAgICAgICAgaW50IHBpeGVsOworCisgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGJ5dGUgYmFbXSA9IChieXRlW10pZ2V0RGF0YUVsZW1lbnRzKHJnYiwgbnVsbCk7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSBiYVswXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2FbXSA9IChzaG9ydFtdKWdldERhdGFFbGVtZW50cyhyZ2IsIG51bGwpOworICAgICAgICAgICAgICAgIHBpeGVsID0gc2FbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4yNjc9VGhlIHRyYW5zZmVyVHlwZSBpcyBpbnZhbGlkCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2NyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBpeGVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbG9yIG1hcC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmdiCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkgd2hlcmUgdGhlIGNvbG9yIG1hcCBpcyB3cml0dGVuLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGdldFJHQnMoaW50IHJnYltdKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29sb3JNYXAsIDAsIHJnYiwgMCwgbWFwU2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVkIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgbWFwLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgZ2V0UmVkcyhieXRlIHJbXSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcFNpemU7IGkrKykgeworICAgICAgICAgICAgcltpXSA9IChieXRlKShjb2xvck1hcFtpXSA+PiAxNik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBncmVlbiBjb21wb25lbnQgb2YgdGhlIGNvbG9yIG1hcC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGdldEdyZWVucyhieXRlIGdbXSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcFNpemU7IGkrKykgeworICAgICAgICAgICAgZ1tpXSA9IChieXRlKShjb2xvck1hcFtpXSA+PiA4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBjb2xvciBtYXAuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBnZXRCbHVlcyhieXRlIGJbXSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcFNpemU7IGkrKykgeworICAgICAgICAgICAgYltpXSA9IChieXRlKWNvbG9yTWFwW2ldOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYWxwaGEgY29tcG9uZW50IG9mIHRoZSBjb2xvciBtYXAuCisgICAgICogCisgICAgICogQHBhcmFtIGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBnZXRBbHBoYXMoYnl0ZSBhW10pIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBTaXplOyBpKyspIHsKKyAgICAgICAgICAgIGFbaV0gPSAoYnl0ZSkoY29sb3JNYXBbaV0gPj4gMjQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldENvbXBvbmVudHMoaW50IHBpeGVsLCBpbnQgY29tcG9uZW50c1tdLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIGlmIChjb21wb25lbnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBvbmVudHMgPSBuZXcgaW50W29mZnNldCArIG51bUNvbXBvbmVudHNdOworICAgICAgICB9CisKKyAgICAgICAgY29tcG9uZW50c1tvZmZzZXQgKyAwXSA9IGdldFJlZChwaXhlbCk7CisgICAgICAgIGNvbXBvbmVudHNbb2Zmc2V0ICsgMV0gPSBnZXRHcmVlbihwaXhlbCk7CisgICAgICAgIGNvbXBvbmVudHNbb2Zmc2V0ICsgMl0gPSBnZXRCbHVlKHBpeGVsKTsKKyAgICAgICAgaWYgKGhhc0FscGhhICYmIChjb21wb25lbnRzLmxlbmd0aCAtIG9mZnNldCkgPiAzKSB7CisgICAgICAgICAgICBjb21wb25lbnRzW29mZnNldCArIDNdID0gZ2V0QWxwaGEocGl4ZWwpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaXMgdmFsaWQgZm9yIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHBpeGVsCisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgcGl4ZWwgaXMgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZChpbnQgcGl4ZWwpIHsKKyAgICAgICAgaWYgKHZhbGlkQml0cyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gKHBpeGVsID49IDAgJiYgcGl4ZWwgPCBtYXBTaXplKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKHBpeGVsIDwgbWFwU2l6ZSAmJiB2YWxpZEJpdHMudGVzdEJpdChwaXhlbCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UmVkKGludCBwaXhlbCkgeworICAgICAgICByZXR1cm4gKGNvbG9yTWFwW3BpeGVsXSA+PiAxNikgJiAweGZmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UkdCKGludCBwaXhlbCkgeworICAgICAgICByZXR1cm4gY29sb3JNYXBbcGl4ZWxdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0R3JlZW4oaW50IHBpeGVsKSB7CisgICAgICAgIHJldHVybiAoY29sb3JNYXBbcGl4ZWxdID4+IDgpICYgMHhmZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEJsdWUoaW50IHBpeGVsKSB7CisgICAgICAgIHJldHVybiBjb2xvck1hcFtwaXhlbF0gJiAweGZmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0QWxwaGEoaW50IHBpeGVsKSB7CisgICAgICAgIHJldHVybiAoY29sb3JNYXBbcGl4ZWxdID4+IDI0KSAmIDB4ZmY7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldENvbXBvbmVudFNpemUoKSB7CisgICAgICAgIHJldHVybiBiaXRzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgY29sb3IgbW9kZWwgdmFsaWRhdGVzIHBpeGVscy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGFsbCBwaXhlbHMgYXJlIHZhbGlkLCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgICAgcmV0dXJuICh2YWxpZEJpdHMgPT0gbnVsbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmluYWxpemUoKSB7CisgICAgICAgIC8vIFRPRE86IGltcGxlbWVudAorICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW5kZXggdGhhdCByZXByZXNlbnRzIHRoZSB0cmFuc3BhcmVudCBwaXhlbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCB0aGF0IHJlcHJlc2VudHMgdGhlIHRyYW5zcGFyZW50IHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0VHJhbnNwYXJlbnRQaXhlbCgpIHsKKyAgICAgICAgcmV0dXJuIHRyYW5zcGFyZW50SW5kZXg7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUcmFuc3BhcmVuY3koKSB7CisgICAgICAgIHJldHVybiB0cmFuc3BhcmVuY3k7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgY29sb3IgbWFwLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1hcCBzaXplLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TWFwU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIG1hcFNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgY29sb3IgbWFwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZS4KKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHIuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBnLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYi4KKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgdGhlIGEuCisgICAgICogQHBhcmFtIHRyYW5zCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUNvbG9yTWFwKGludCBzaXplLCBieXRlIHJbXSwgYnl0ZSBnW10sIGJ5dGUgYltdLCBieXRlIGFbXSwgaW50IHRyYW5zKSB7CisgICAgICAgIGlmIChzaXplIDwgMSkgeworICAgICAgICAgICAgLy8gYXd0LjI2ND1TaXplIG9mIHRoZSBjb2xvciBtYXAgaXMgbGVzcyB0aGFuIDEKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjY0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBtYXBTaXplID0gc2l6ZTsKKyAgICAgICAgY29sb3JNYXAgPSBuZXcgaW50W21hcFNpemVdOworICAgICAgICBpZiAodHJhbnMgPj0gMCAmJiB0cmFucyA8IG1hcFNpemUpIHsKKyAgICAgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5CSVRNQVNLOworICAgICAgICAgICAgdHJhbnNwYXJlbnRJbmRleCA9IHRyYW5zOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJhbnNwYXJlbmN5ID0gVHJhbnNwYXJlbmN5Lk9QQVFVRTsKKyAgICAgICAgICAgIHRyYW5zcGFyZW50SW5kZXggPSAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYWxwaGEgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBjb2xvck1hcFtpXSA9ICgocltpXSAmIDB4ZmYpIDw8IDE2KSB8ICgoZ1tpXSAmIDB4ZmYpIDw8IDgpIHwgKGJbaV0gJiAweGZmKTsKKworICAgICAgICAgICAgaWYgKHRyYW5zID09IGkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNvbG9yTWFwW2ldIHw9IDB4ZmYwMDAwMDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFscGhhID0gYVtpXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgaWYgKGFscGhhID09IDB4ZmYpIHsKKyAgICAgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gfD0gMHhmZjAwMDAwMDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFscGhhID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW5jeSA9PSBUcmFuc3BhcmVuY3kuT1BBUVVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuQklUTUFTSzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRJbmRleCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcGFyZW50SW5kZXggPSBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gfD0gKGFbaV0gJiAweGZmKSA8PCAyNDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW5jeSAhPSBUcmFuc3BhcmVuY3kuVFJBTlNMVUNFTlQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5UUkFOU0xVQ0VOVDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjaGVja2luZywgaWYgQ29sb3IgTWFwIGhhcyBHcmF5IHBhbGV0dGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUGFsZXR0ZSgpIHsKKyAgICAgICAgZ3JheVBhbGV0dGUgPSBmYWxzZTsKKyAgICAgICAgaWYgKHRyYW5zcGFyZW5jeSA+IFRyYW5zcGFyZW5jeS5PUEFRVUUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmdiID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcFNpemU7IGkrKykgeworICAgICAgICAgICAgcmdiID0gY29sb3JNYXBbaV07CisgICAgICAgICAgICBpZiAoKChyZ2IgPj4gMTYpICYgMHhmZikgIT0gKChyZ2IgPj4gOCkgJiAweGZmKSB8fCAoKHJnYiA+PiA4KSAmIDB4ZmYpICE9IChyZ2IgJiAweGZmKSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBncmF5UGFsZXR0ZSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0aW9uIGFuIGFycmF5IHBpeGVsIHJlcHJlc2VudGF0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvck1hcElkeAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGludG8gQ29sb3IgTWFwLgorICAgICAqIEBwYXJhbSBwaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsCisgICAgICogQHJldHVybiB0aGUgcGl4ZWwgcmVwcmVzZW50YXRpb24gYXJyYXkuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgY3JlYXRlRGF0YU9iamVjdChpbnQgY29sb3JNYXBJZHgsIE9iamVjdCBwaXhlbCkgeworICAgICAgICBpZiAocGl4ZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgc3dpdGNoICh0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgICAgICBieXRlW10gYmEgPSBuZXcgYnl0ZVsxXTsKKyAgICAgICAgICAgICAgICAgICAgYmFbMF0gPSAoYnl0ZSljb2xvck1hcElkeDsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBiYTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgICAgICBzaG9ydFtdIHNhID0gbmV3IHNob3J0WzFdOworICAgICAgICAgICAgICAgICAgICBzYVswXSA9IChzaG9ydCljb2xvck1hcElkeDsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzYTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjI2Nz1UaGUgdHJhbnNmZXJUeXBlIGlzIGludmFsaWQKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2NyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKHBpeGVsIGluc3RhbmNlb2YgYnl0ZVtdICYmIHRyYW5zZmVyVHlwZSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSkgeworICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSlwaXhlbDsKKyAgICAgICAgICAgIGJhWzBdID0gKGJ5dGUpY29sb3JNYXBJZHg7CisgICAgICAgICAgICBwaXhlbCA9IGJhOworICAgICAgICB9IGVsc2UgaWYgKHBpeGVsIGluc3RhbmNlb2Ygc2hvcnRbXSAmJiB0cmFuc2ZlclR5cGUgPT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCkgeworICAgICAgICAgICAgc2hvcnRbXSBzYSA9IChzaG9ydFtdKXBpeGVsOworICAgICAgICAgICAgc2FbMF0gPSAoc2hvcnQpY29sb3JNYXBJZHg7CisgICAgICAgICAgICBwaXhlbCA9IHNhOworICAgICAgICB9IGVsc2UgaWYgKHBpeGVsIGluc3RhbmNlb2YgaW50W10pIHsKKyAgICAgICAgICAgIGludCBpYVtdID0gKGludFtdKXBpeGVsOworICAgICAgICAgICAgaWFbMF0gPSBjb2xvck1hcElkeDsKKyAgICAgICAgICAgIHBpeGVsID0gaWE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBhd3QuMjY4PVRoZSBwaXhlbCBpcyBub3QgYSBwcmltaXRpdmUgYXJyYXkgb2YgdHlwZSB0cmFuc2ZlclR5cGUKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjY4IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBpeGVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGJpdHMuCisgICAgICogCisgICAgICogQHBhcmFtIGhhc0FscGhhCisgICAgICogICAgICAgICAgICB0aGUgaGFzIGFscGhhLgorICAgICAqIEByZXR1cm4gdGhlIGludFtdLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludFtdIGNyZWF0ZUJpdHMoYm9vbGVhbiBoYXNBbHBoYSkgeworCisgICAgICAgIGludCBudW1DaGFubmVsczsKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICBudW1DaGFubmVscyA9IDQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBudW1DaGFubmVscyA9IDM7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYml0c1tdID0gbmV3IGludFtudW1DaGFubmVsc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ2hhbm5lbHM7IGkrKykgeworICAgICAgICAgICAgYml0c1tpXSA9IDg7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYml0czsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlIHRyYW5zZmVyIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHRyYW5zZmVyVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHRyYW5zZmVyIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCB2YWxpZGF0ZVRyYW5zZmVyVHlwZShpbnQgdHJhbnNmZXJUeXBlKSB7CisgICAgICAgIGlmICh0cmFuc2ZlclR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgdHJhbnNmZXJUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNjk9VGhlIHRyYW5zZmVyVHlwZSBpcyBub3Qgb25lIG9mIERhdGFCdWZmZXIuVFlQRV9CWVRFIG9yCisgICAgICAgICAgICAvLyBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2OSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cmFuc2ZlclR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGlzIGdyYXkgcGFsZXR0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGlzIGdyYXkgcGFsZXR0ZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzR3JheVBhbGxldGUoKSB7CisgICAgICAgIHJldHVybiBncmF5UGFsZXR0ZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9LZXJuZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9LZXJuZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTlkMjdhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL0tlcm5lbC5qYXZhCkBAIC0wLDAgKzEsMTUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogU2VwIDI4LCAyMDA1CisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBLZXJuZWwgY2xhc3MgcHJvdmlkZXMgYSBtYXRyaXguIFRoaXMgbWF0cml4IGlzIHN0b3JlZCBhcyBhIGZsb2F0IGFycmF5CisgKiB3aGljaCBkZXNjcmliZXMgaG93IGEgc3BlY2lmaWVkIHBpeGVsIGFmZmVjdHMgdGhlIHZhbHVlIGNhbGN1bGF0ZWQgZm9yIHRoZQorICogcGl4ZWwncyBwb3NpdGlvbiBpbiB0aGUgb3V0cHV0IGltYWdlIG9mIGEgZmlsdGVyaW5nIG9wZXJhdGlvbi4gVGhlIFgsIFkKKyAqIG9yaWdpbnMgaW5kaWNhdGUgdGhlIGtlcm5lbCBtYXRyaXggZWxlbWVudCB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgcGl4ZWwKKyAqIHBvc2l0aW9uIGZvciB3aGljaCBhbiBvdXRwdXQgdmFsdWUgaXMgYmVpbmcgY2FsY3VsYXRlZC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBLZXJuZWwgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIHggb3JpZ2luLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IHhPcmlnaW47CisKKyAgICAvKioKKyAgICAgKiBUaGUgeSBvcmlnaW4uCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgeU9yaWdpbjsKKworICAgIC8qKgorICAgICAqIFRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB3aWR0aDsKKworICAgIC8qKgorICAgICAqIFRoZSBoZWlnaHQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgaGVpZ2h0OworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEuCisgICAgICovCisgICAgZmxvYXQgZGF0YVtdOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEtlcm5lbCB3aXRoIHRoZSBzcGVjaWZpZWQgZmxvYXQgYXJyYXkuIFRoZQorICAgICAqIHdpZHRoKmhlaWdodCBlbGVtZW50cyBvZiB0aGUgZGF0YSBhcnJheSBhcmUgY29waWVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBLZXJuZWwuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgS2VybmVsLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBvZiBLZXJuZWwuCisgICAgICovCisgICAgcHVibGljIEtlcm5lbChpbnQgd2lkdGgsIGludCBoZWlnaHQsIGZsb2F0W10gZGF0YSkgeworICAgICAgICBpbnQgZGF0YUxlbmd0aCA9IHdpZHRoICogaGVpZ2h0OworICAgICAgICBpZiAoZGF0YS5sZW5ndGggPCBkYXRhTGVuZ3RoKSB7CisgICAgICAgICAgICAvLyBhd3QuMjJCPUxlbmd0aCBvZiBkYXRhIHNob3VsZCBub3QgYmUgbGVzcyB0aGFuIHdpZHRoKmhlaWdodAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMkIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisKKyAgICAgICAgdGhpcy5kYXRhID0gbmV3IGZsb2F0W2RhdGFMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIDAsIHRoaXMuZGF0YSwgMCwgZGF0YUxlbmd0aCk7CisKKyAgICAgICAgeE9yaWdpbiA9ICh3aWR0aCAtIDEpIC8gMjsKKyAgICAgICAgeU9yaWdpbiA9IChoZWlnaHQgLSAxKSAvIDI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2lkdGggb2YgdGhpcyBLZXJuZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd2lkdGggb2YgdGhpcyBLZXJuZWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRXaWR0aCgpIHsKKyAgICAgICAgcmV0dXJuIHdpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGhlaWdodCBvZiB0aGlzIEtlcm5lbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhpcyBLZXJuZWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRIZWlnaHQoKSB7CisgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmxvYXQgZGF0YSBhcnJheSBvZiB0aGlzIEtlcm5lbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHdoZXJlIHRoZSByZXN1bHRlZCBkYXRhIHdpbGwgYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGRhdGEgYXJyYXkgb2YgdGhpcyBLZXJuZWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGZsb2F0W10gZ2V0S2VybmVsRGF0YShmbG9hdFtdIGRhdGEpIHsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgZGF0YSA9IG5ldyBmbG9hdFt0aGlzLmRhdGEubGVuZ3RoXTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuZGF0YSwgMCwgZGF0YSwgMCwgdGhpcy5kYXRhLmxlbmd0aCk7CisKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgWCBvcmlnaW4gb2YgdGhpcyBLZXJuZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgWCBvcmlnaW4gb2YgdGhpcyBLZXJuZWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRYT3JpZ2luKCkgeworICAgICAgICByZXR1cm4geE9yaWdpbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBZIG9yaWdpbiBvZiB0aGlzIEtlcm5lbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBZIG9yaWdpbiBvZiB0aGlzIEtlcm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFlPcmlnaW4oKSB7CisgICAgICAgIHJldHVybiB5T3JpZ2luOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMgS2VybmVsIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3B5IG9mIHRoaXMgS2VybmVsIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICByZXR1cm4gbmV3IEtlcm5lbCh3aWR0aCwgaGVpZ2h0LCBkYXRhKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvTG9va3VwT3AuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Mb29rdXBPcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzNjJjNWMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvTG9va3VwT3AuamF2YQpAQCAtMCwwICsxLDY2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKgorICogQGRhdGU6IE9jdCAxNCwgMjAwNQorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgTG9va3VwT3AgY2xhc3MgcGVyZm9ybXMgYSBsb29rdXAgb3BlcmF0aW9uIHdoaWNoIHRyYW5zZm9ybXMgYSBzb3VyY2UKKyAqIGltYWdlIGJ5IGZpbHRlcmluZyBlYWNoIGJhbmQgdXNpbmcgYSB0YWJsZSBvZiBkYXRhLiBUaGUgdGFibGUgbWF5IGNvbnRhaW4gYQorICogc2luZ2xlIGFycmF5IG9yIGl0IG1heSBjb250YWluIGEgZGlmZmVyZW50IGRhdGEgYXJyYXkgZm9yIGVhY2ggYmFuZCBvZiB0aGUKKyAqIGltYWdlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIExvb2t1cE9wIGltcGxlbWVudHMgQnVmZmVyZWRJbWFnZU9wLCBSYXN0ZXJPcCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbHV0LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgTG9va3VwVGFibGUgbHV0OworCisgICAgLyoqCisgICAgICogVGhlIGhpbnRzLgorICAgICAqLworICAgIHByaXZhdGUgUmVuZGVyaW5nSGludHMgaGludHM7CisKKyAgICAvLyBUT0RPIHJlbW92ZSB3aGVuIHRoaXMgZmllbGQgaXMgdXNlZAorICAgIC8qKgorICAgICAqIFRoZSBjYW4gdXNlIGlwcC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2FuVXNlSXBwOworCisgICAgLy8gV2UgZG9uJ3QgY3JlYXRlIGxldmVscy92YWx1ZXMgd2hlbiBpdCBpcyBwb3NzaWJsZSB0byByZXVzZSBvbGQKKyAgICAvKioKKyAgICAgKiBUaGUgY2FjaGVkIGxldmVscy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjYWNoZWRMZXZlbHNbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBjYWNoZWQgdmFsdWVzLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNhY2hlZFZhbHVlc1tdOworCisgICAgLy8gTnVtYmVyIG9mIGNoYW5uZWxzIGZvciB3aGljaCBjYWNoZSBpcyB2YWxpZC4KKyAgICAvLyBJZiBuZWdhdGl2ZSBudW1iZXIgb2YgY2hhbm5lbHMgaXMgc2FtZSBhcyBwb3NpdGl2ZSBidXQgc2tpcEFscGhhIHdhcworICAgIC8vIHNwZWNpZmllZAorICAgIC8qKgorICAgICAqIFRoZSB2YWxpZCBmb3IgY2hhbm5lbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgdmFsaWRGb3JDaGFubmVsczsKKworICAgIC8qKgorICAgICAqIFRoZSBsZXZlbCBpbml0aWFsaXplci4KKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGxldmVsSW5pdGlhbGl6ZXJbXSA9IG5ldyBpbnRbMHgxMDAwMF07CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBUT0RPCisgICAgICAgIC8vIFN5c3RlbS5sb2FkTGlicmFyeSgiaW1hZ2VvcHMiKTsKKworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSAweDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGxldmVsSW5pdGlhbGl6ZXJbaSAtIDFdID0gaTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBMb29rdXBPcCBvYmplY3QgZnJvbSB0aGUgc3BlY2lmaWVkIExvb2t1cFRhYmxlIG9iamVjdAorICAgICAqIGFuZCBhIFJlbmRlcmluZ0hpbnRzIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9va3VwCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIExvb2t1cFRhYmxlIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJpbmdIaW50cyBvYmplY3Qgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9va3VwT3AoTG9va3VwVGFibGUgbG9va3VwLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBpZiAobG9va3VwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wMSIsICJsb29rdXAiKSk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgICAgIGx1dCA9IGxvb2t1cDsKKyAgICAgICAgdGhpcy5oaW50cyA9IGhpbnRzOworICAgICAgICBjYW5Vc2VJcHAgPSBsdXQgaW5zdGFuY2VvZiBCeXRlTG9va3VwVGFibGUgfHwgbHV0IGluc3RhbmNlb2YgU2hvcnRMb29rdXBUYWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBMb29rdXBUYWJsZSBvZiB0aGUgc3BlY2lmaWVkIE9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBMb29rdXBUYWJsZSBvZiB0aGUgc3BlY2lmaWVkIE9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgTG9va3VwVGFibGUgZ2V0VGFibGUoKSB7CisgICAgICAgIHJldHVybiBsdXQ7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlbmRlcmluZ0hpbnRzIGdldFJlbmRlcmluZ0hpbnRzKCkgeworICAgICAgICByZXR1cm4gaGludHM7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFBvaW50MkQgZ2V0UG9pbnQyRChQb2ludDJEIHNyY1B0LCBQb2ludDJEIGRzdFB0KSB7CisgICAgICAgIGlmIChkc3RQdCA9PSBudWxsKSB7CisgICAgICAgICAgICBkc3RQdCA9IG5ldyBQb2ludDJELkZsb2F0KCk7CisgICAgICAgIH0KKworICAgICAgICBkc3RQdC5zZXRMb2NhdGlvbihzcmNQdCk7CisgICAgICAgIHJldHVybiBkc3RQdDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoUmFzdGVyIHNyYykgeworICAgICAgICByZXR1cm4gc3JjLmdldEJvdW5kcygpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRChCdWZmZXJlZEltYWdlIHNyYykgeworICAgICAgICByZXR1cm4gZ2V0Qm91bmRzMkQoc3JjLmdldFJhc3RlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoUmFzdGVyIHNyYykgeworICAgICAgICByZXR1cm4gc3JjLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcigpOworICAgIH0KKworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2UoQnVmZmVyZWRJbWFnZSBzcmMsIENvbG9yTW9kZWwgZHN0Q00pIHsKKyAgICAgICAgaWYgKGRzdENNID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdENNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKworICAgICAgICAgICAgLy8gU3luYyB0cmFuc2ZlciB0eXBlIHdpdGggTFVUIGZvciBjb21wb25lbnQgY29sb3IgbW9kZWwKKyAgICAgICAgICAgIGlmIChkc3RDTSBpbnN0YW5jZW9mIENvbXBvbmVudENvbG9yTW9kZWwpIHsKKyAgICAgICAgICAgICAgICBpbnQgdHJhbnNmZXJUeXBlID0gZHN0Q00uZ2V0VHJhbnNmZXJUeXBlKCk7CisgICAgICAgICAgICAgICAgaWYgKGx1dCBpbnN0YW5jZW9mIEJ5dGVMb29rdXBUYWJsZSkgeworICAgICAgICAgICAgICAgICAgICB0cmFuc2ZlclR5cGUgPSBEYXRhQnVmZmVyLlRZUEVfQllURTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGx1dCBpbnN0YW5jZW9mIFNob3J0TG9va3VwVGFibGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNmZXJUeXBlID0gRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGRzdENNID0gbmV3IENvbXBvbmVudENvbG9yTW9kZWwoZHN0Q00uY3MsIGRzdENNLmhhc0FscGhhKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkc3RDTS5pc0FscGhhUHJlbXVsdGlwbGllZCwgZHN0Q00udHJhbnNwYXJlbmN5LCB0cmFuc2ZlclR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgciA9IGRzdENNLmlzQ29tcGF0aWJsZVNhbXBsZU1vZGVsKHNyYy5nZXRTYW1wbGVNb2RlbCgpKSA/IHNyYy5nZXRSYXN0ZXIoKQorICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSkgOiBkc3RDTQorICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlKGRzdENNLCByLCBkc3RDTS5pc0FscGhhUHJlbXVsdGlwbGllZCgpLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgV3JpdGFibGVSYXN0ZXIgZmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCkgeworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKHNyYyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoc3JjLmdldE51bUJhbmRzKCkgIT0gZHN0LmdldE51bUJhbmRzKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzNyIpKTsgLy8kTk9OLU5MUy0xJCAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzcmMuZ2V0V2lkdGgoKSAhPSBkc3QuZ2V0V2lkdGgoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjhGIikpOyAvLyROT04tTkxTLTEkICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNyYy5nZXRIZWlnaHQoKSAhPSBkc3QuZ2V0SGVpZ2h0KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI5MCIpKTsgLy8kTk9OLU5MUy0xJCAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChsdXQuZ2V0TnVtQ29tcG9uZW50cygpICE9IDEgJiYgbHV0LmdldE51bUNvbXBvbmVudHMoKSAhPSBzcmMuZ2V0TnVtQmFuZHMoKSkgeworICAgICAgICAgICAgLy8gYXd0LjIzOD1UaGUgbnVtYmVyIG9mIGFycmF5cyBpbiB0aGUgTG9va3VwVGFibGUgZG9lcyBub3QgbWVldCB0aGUKKyAgICAgICAgICAgIC8vIHJlc3RyaWN0aW9ucworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gaWYgKCFjYW5Vc2VJcHAgfHwgaXBwRmlsdGVyKHNyYywgZHN0LCBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NLAorICAgICAgICAvLyBmYWxzZSkgIT0gMCkKKyAgICAgICAgaWYgKHNsb3dGaWx0ZXIoc3JjLCBkc3QsIGZhbHNlKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjFGPVVuYWJsZSB0byB0cmFuc2Zvcm0gc291cmNlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxRiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgQnVmZmVyZWRJbWFnZSBmaWx0ZXIoQnVmZmVyZWRJbWFnZSBzcmMsIEJ1ZmZlcmVkSW1hZ2UgZHN0KSB7CisgICAgICAgIENvbG9yTW9kZWwgc3JjQ00gPSBzcmMuZ2V0Q29sb3JNb2RlbCgpOworCisgICAgICAgIGlmIChzcmNDTSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgLy8gYXd0LjIyMD1Tb3VyY2Ugc2hvdWxkIG5vdCBoYXZlIEluZGV4Q29sb3JNb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMjAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIGlmIHRoZSBudW1iZXIgb2Ygc2NhbGluZyBmYWN0b3JzIG1hdGNoZXMgdGhlIG51bWJlciBvZiBiYW5kcworICAgICAgICBpbnQgbkNvbXBvbmVudHMgPSBzcmNDTS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIGludCBuTFVUQ29tcG9uZW50cyA9IGx1dC5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIGJvb2xlYW4gc2tpcEFscGhhOworICAgICAgICBpZiAoc3JjQ00uaGFzQWxwaGEoKSkgeworICAgICAgICAgICAgaWYgKG5MVVRDb21wb25lbnRzID09IDEgfHwgbkxVVENvbXBvbmVudHMgPT0gbkNvbXBvbmVudHMgLSAxKSB7CisgICAgICAgICAgICAgICAgc2tpcEFscGhhID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobkxVVENvbXBvbmVudHMgPT0gbkNvbXBvbmVudHMpIHsKKyAgICAgICAgICAgICAgICBza2lwQWxwaGEgPSBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjIyOT1OdW1iZXIgb2YgY29tcG9uZW50cyBpbiB0aGUgTFVUIGRvZXMgbm90IG1hdGNoIHRoZQorICAgICAgICAgICAgICAgIC8vIG51bWJlciBvZiBiYW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjI5IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAobkxVVENvbXBvbmVudHMgPT0gMSB8fCBuTFVUQ29tcG9uZW50cyA9PSBuQ29tcG9uZW50cykgeworICAgICAgICAgICAgc2tpcEFscGhhID0gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBhd3QuMjI5PU51bWJlciBvZiBjb21wb25lbnRzIGluIHRoZSBMVVQgZG9lcyBub3QgbWF0Y2ggdGhlIG51bWJlcgorICAgICAgICAgICAgLy8gb2YgYmFuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjI5IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBCdWZmZXJlZEltYWdlIGZpbmFsRHN0ID0gbnVsbDsKKyAgICAgICAgaWYgKGRzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbERzdCA9IGRzdDsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2Uoc3JjLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChzcmMuZ2V0V2lkdGgoKSAhPSBkc3QuZ2V0V2lkdGgoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjkxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzcmMuZ2V0SGVpZ2h0KCkgIT0gZHN0LmdldEhlaWdodCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yOTIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCFzcmNDTS5lcXVhbHMoZHN0LmdldENvbG9yTW9kZWwoKSkpIHsKKyAgICAgICAgICAgICAgICAvLyBUcmVhdCBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQiBhbmQKKyAgICAgICAgICAgICAgICAvLyBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IgYXMgc2FtZQorICAgICAgICAgICAgICAgIGlmICghKChzcmMuZ2V0VHlwZSgpID09IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfUkdCIHx8IHNyYy5nZXRUeXBlKCkgPT0gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCKSAmJiAoZHN0CisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0VHlwZSgpID09IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfUkdCIHx8IGRzdC5nZXRUeXBlKCkgPT0gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWxEc3QgPSBkc3Q7CisgICAgICAgICAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2Uoc3JjLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBUT0RPCisgICAgICAgIC8vIGlmICghY2FuVXNlSXBwIHx8IGlwcEZpbHRlcihzcmMuZ2V0UmFzdGVyKCksIGRzdC5nZXRSYXN0ZXIoKSwKKyAgICAgICAgLy8gc3JjLmdldFR5cGUoKSwgc2tpcEFscGhhKSAhPSAwKQorICAgICAgICBpZiAoc2xvd0ZpbHRlcihzcmMuZ2V0UmFzdGVyKCksIGRzdC5nZXRSYXN0ZXIoKSwgc2tpcEFscGhhKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjFGPVVuYWJsZSB0byB0cmFuc2Zvcm0gc291cmNlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxRiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpbmFsRHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIEdyYXBoaWNzMkQgZyA9IGZpbmFsRHN0LmNyZWF0ZUdyYXBoaWNzKCk7CisgICAgICAgICAgICBnLnNldENvbXBvc2l0ZShBbHBoYUNvbXBvc2l0ZS5TcmMpOworICAgICAgICAgICAgZy5kcmF3SW1hZ2UoZHN0LCAwLCAwLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbmFsRHN0ID0gZHN0OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTbG93IGZpbHRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc3JjLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHBhcmFtIHNraXBBbHBoYQorICAgICAqICAgICAgICAgICAgdGhlIHNraXAgYWxwaGEuCisgICAgICogQHJldHVybiB0aGUgaW50LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IHNsb3dGaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0LCBib29sZWFuIHNraXBBbHBoYSkgeworICAgICAgICBpbnQgbWluU3JjWCA9IHNyYy5nZXRNaW5YKCk7CisgICAgICAgIGludCBtaW5Ec3RYID0gZHN0LmdldE1pblgoKTsKKyAgICAgICAgaW50IG1pblNyY1kgPSBzcmMuZ2V0TWluWSgpOworICAgICAgICBpbnQgbWluRHN0WSA9IGRzdC5nZXRNaW5ZKCk7CisKKyAgICAgICAgaW50IHNraXBwaW5nQ2hhbm5lbHMgPSBza2lwQWxwaGEgPyAxIDogMDsKKyAgICAgICAgaW50IG51bUJhbmRzMlByb2Nlc3MgPSBzcmMuZ2V0TnVtQmFuZHMoKSAtIHNraXBwaW5nQ2hhbm5lbHM7CisKKyAgICAgICAgaW50IG51bUJhbmRzID0gc3JjLmdldE51bUJhbmRzKCk7CisgICAgICAgIGludCBzcmNIZWlnaHQgPSBzcmMuZ2V0SGVpZ2h0KCk7CisgICAgICAgIGludCBzcmNXaWR0aCA9IHNyYy5nZXRXaWR0aCgpOworCisgICAgICAgIGludFtdIHBpeGVscyA9IG51bGw7CisgICAgICAgIGludCBvZmZzZXQgPSBsdXQuZ2V0T2Zmc2V0KCk7CisKKyAgICAgICAgaWYgKGx1dCBpbnN0YW5jZW9mIEJ5dGVMb29rdXBUYWJsZSkgeworICAgICAgICAgICAgYnl0ZVtdW10gYnl0ZURhdGEgPSAoKEJ5dGVMb29rdXBUYWJsZSlsdXQpLmdldFRhYmxlKCk7CisgICAgICAgICAgICBwaXhlbHMgPSBzcmMuZ2V0UGl4ZWxzKG1pblNyY1gsIG1pblNyY1ksIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHBpeGVscyk7CisKKyAgICAgICAgICAgIGlmIChsdXQuZ2V0TnVtQ29tcG9uZW50cygpICE9IDEpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7IGkgKz0gbnVtQmFuZHMpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCBudW1CYW5kczJQcm9jZXNzOyBiKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpICsgYl0gPSBieXRlRGF0YVtiXVtwaXhlbHNbaSArIGJdIC0gb2Zmc2V0XSAmIDB4RkY7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGl4ZWxzLmxlbmd0aDsgaSArPSBudW1CYW5kcykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8IG51bUJhbmRzMlByb2Nlc3M7IGIrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2kgKyBiXSA9IGJ5dGVEYXRhWzBdW3BpeGVsc1tpICsgYl0gLSBvZmZzZXRdICYgMHhGRjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZHN0LnNldFBpeGVscyhtaW5Ec3RYLCBtaW5Ec3RZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBwaXhlbHMpOworICAgICAgICB9IGVsc2UgaWYgKGx1dCBpbnN0YW5jZW9mIFNob3J0TG9va3VwVGFibGUpIHsKKyAgICAgICAgICAgIHNob3J0W11bXSBzaG9ydERhdGEgPSAoKFNob3J0TG9va3VwVGFibGUpbHV0KS5nZXRUYWJsZSgpOworICAgICAgICAgICAgcGl4ZWxzID0gc3JjLmdldFBpeGVscyhtaW5TcmNYLCBtaW5TcmNZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBwaXhlbHMpOworCisgICAgICAgICAgICBpZiAobHV0LmdldE51bUNvbXBvbmVudHMoKSAhPSAxKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwaXhlbHMubGVuZ3RoOyBpICs9IG51bUJhbmRzKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGIgPSAwOyBiIDwgbnVtQmFuZHMyUHJvY2VzczsgYisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaSArIGJdID0gc2hvcnREYXRhW2JdW3BpeGVsc1tpICsgYl0gLSBvZmZzZXRdICYgMHhGRkZGOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7IGkgKz0gbnVtQmFuZHMpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCBudW1CYW5kczJQcm9jZXNzOyBiKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpICsgYl0gPSBzaG9ydERhdGFbMF1bcGl4ZWxzW2kgKyBiXSAtIG9mZnNldF0gJiAweEZGRkY7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGRzdC5zZXRQaXhlbHMobWluRHN0WCwgbWluRHN0WSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgcGl4ZWxzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBwaXhlbFtdID0gbmV3IGludFtzcmMuZ2V0TnVtQmFuZHMoKV07CisgICAgICAgICAgICBpbnQgbWF4WSA9IG1pblNyY1kgKyBzcmNIZWlnaHQ7CisgICAgICAgICAgICBpbnQgbWF4WCA9IG1pblNyY1ggKyBzcmNXaWR0aDsKKyAgICAgICAgICAgIGZvciAoaW50IHNyY1kgPSBtaW5TcmNZLCBkc3RZID0gbWluRHN0WTsgc3JjWSA8IG1heFk7IHNyY1krKywgZHN0WSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgc3JjWCA9IG1pblNyY1gsIGRzdFggPSBtaW5Ec3RYOyBzcmNYIDwgbWF4WDsgc3JjWCsrLCBkc3RYKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc3JjLmdldFBpeGVsKHNyY1gsIHNyY1ksIHBpeGVsKTsKKyAgICAgICAgICAgICAgICAgICAgbHV0Lmxvb2t1cFBpeGVsKHBpeGVsLCBwaXhlbCk7CisgICAgICAgICAgICAgICAgICAgIGRzdC5zZXRQaXhlbChkc3RYLCBkc3RZLCBwaXhlbCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgYnl0ZSBsZXZlbHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNoYW5uZWxzCisgICAgICogICAgICAgICAgICB0aGUgY2hhbm5lbHMuCisgICAgICogQHBhcmFtIHNraXBBbHBoYQorICAgICAqICAgICAgICAgICAgdGhlIHNraXAgYWxwaGEuCisgICAgICogQHBhcmFtIGxldmVscworICAgICAqICAgICAgICAgICAgdGhlIGxldmVscy4KKyAgICAgKiBAcGFyYW0gdmFsdWVzCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWVzLgorICAgICAqIEBwYXJhbSBjaGFubmVsc09yZGVyCisgICAgICogICAgICAgICAgICB0aGUgY2hhbm5lbHMgb3JkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNyZWF0ZUJ5dGVMZXZlbHMoaW50IGNoYW5uZWxzLCBib29sZWFuIHNraXBBbHBoYSwgaW50IGxldmVsc1tdLAorICAgICAgICAgICAgaW50IHZhbHVlc1tdLCBpbnQgY2hhbm5lbHNPcmRlcltdKSB7CisgICAgICAgIGJ5dGUgZGF0YVtdW10gPSAoKEJ5dGVMb29rdXBUYWJsZSlsdXQpLmdldFRhYmxlKCk7CisgICAgICAgIGludCBuTGV2ZWxzID0gZGF0YVswXS5sZW5ndGg7CisgICAgICAgIGludCBvZmZzZXQgPSBsdXQuZ2V0T2Zmc2V0KCk7CisKKyAgICAgICAgLy8gVXNlIG9uZSBkYXRhIGFycmF5IGZvciBhbGwgY2hhbm5lbHMgb3IgdXNlIHNldmVyYWwgZGF0YSBhcnJheXMKKyAgICAgICAgaW50IGRhdGFJbmNyZW1lbnQgPSBkYXRhLmxlbmd0aCA+IDEgPyAxIDogMDsKKworICAgICAgICBmb3IgKGludCBjaCA9IDAsIGRhdGFJZHggPSAwOyBjaCA8IGNoYW5uZWxzOyBkYXRhSWR4ICs9IGRhdGFJbmNyZW1lbnQsIGNoKyspIHsKKyAgICAgICAgICAgIGludCBjaGFubmVsT2Zmc2V0ID0gY2hhbm5lbHNPcmRlciA9PSBudWxsID8gY2ggOiBjaGFubmVsc09yZGVyW2NoXTsKKyAgICAgICAgICAgIGludCBjaGFubmVsQmFzZSA9IG5MZXZlbHMgKiBjaGFubmVsT2Zmc2V0OworCisgICAgICAgICAgICAvLyBTa2lwIGxhc3QgY2hhbm5lbCBpZiBuZWVkZWQsIHplcm8gdmFsdWVzIGFyZSBPSyAtCisgICAgICAgICAgICAvLyBubyBjaGFuZ2VzIHRvIHRoZSBjaGFubmVsIGluZm9ybWF0aW9uIHdpbGwgYmUgZG9uZSBpbiBJUFAKKyAgICAgICAgICAgIGlmICgoY2hhbm5lbE9mZnNldCA9PSBjaGFubmVscyAtIDEgJiYgc2tpcEFscGhhKSB8fCAoZGF0YUlkeCA+PSBkYXRhLmxlbmd0aCkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbEluaXRpYWxpemVyLCBvZmZzZXQsIGxldmVscywgY2hhbm5lbEJhc2UsIG5MZXZlbHMpOworICAgICAgICAgICAgZm9yIChpbnQgZnJvbSA9IDAsIHRvID0gY2hhbm5lbEJhc2U7IGZyb20gPCBuTGV2ZWxzOyBmcm9tKyssIHRvKyspIHsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbdG9dID0gZGF0YVtkYXRhSWR4XVtmcm9tXSAmIDB4RkY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBzaG9ydCBsZXZlbHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNoYW5uZWxzCisgICAgICogICAgICAgICAgICB0aGUgY2hhbm5lbHMuCisgICAgICogQHBhcmFtIHNraXBBbHBoYQorICAgICAqICAgICAgICAgICAgdGhlIHNraXAgYWxwaGEuCisgICAgICogQHBhcmFtIGxldmVscworICAgICAqICAgICAgICAgICAgdGhlIGxldmVscy4KKyAgICAgKiBAcGFyYW0gdmFsdWVzCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWVzLgorICAgICAqIEBwYXJhbSBjaGFubmVsc09yZGVyCisgICAgICogICAgICAgICAgICB0aGUgY2hhbm5lbHMgb3JkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNyZWF0ZVNob3J0TGV2ZWxzKGludCBjaGFubmVscywgYm9vbGVhbiBza2lwQWxwaGEsIGludCBsZXZlbHNbXSwKKyAgICAgICAgICAgIGludCB2YWx1ZXNbXSwgaW50IGNoYW5uZWxzT3JkZXJbXSkgeworICAgICAgICBzaG9ydCBkYXRhW11bXSA9ICgoU2hvcnRMb29rdXBUYWJsZSlsdXQpLmdldFRhYmxlKCk7CisgICAgICAgIGludCBuTGV2ZWxzID0gZGF0YVswXS5sZW5ndGg7CisgICAgICAgIGludCBvZmZzZXQgPSBsdXQuZ2V0T2Zmc2V0KCk7CisKKyAgICAgICAgLy8gVXNlIG9uZSBkYXRhIGFycmF5IGZvciBhbGwgY2hhbm5lbHMgb3IgdXNlIHNldmVyYWwgZGF0YSBhcnJheXMKKyAgICAgICAgaW50IGRhdGFJbmNyZW1lbnQgPSBkYXRhLmxlbmd0aCA+IDEgPyAxIDogMDsKKworICAgICAgICBmb3IgKGludCBjaCA9IDAsIGRhdGFJZHggPSAwOyBjaCA8IGNoYW5uZWxzOyBkYXRhSWR4ICs9IGRhdGFJbmNyZW1lbnQsIGNoKyspIHsKKyAgICAgICAgICAgIGludCBjaGFubmVsT2Zmc2V0ID0gY2hhbm5lbHNPcmRlciA9PSBudWxsID8gY2ggOiBjaGFubmVsc09yZGVyW2NoXTsKKworICAgICAgICAgICAgLy8gU2tpcCBsYXN0IGNoYW5uZWwgaWYgbmVlZGVkLCB6ZXJvIHZhbHVlcyBhcmUgT0sgLQorICAgICAgICAgICAgLy8gbm8gY2hhbmdlcyB0byB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvbiB3aWxsIGJlIGRvbmUgaW4gSVBQCisgICAgICAgICAgICBpZiAoKGNoYW5uZWxPZmZzZXQgPT0gY2hhbm5lbHMgLSAxICYmIHNraXBBbHBoYSkgfHwgKGRhdGFJZHggPj0gZGF0YS5sZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBjaGFubmVsQmFzZSA9IG5MZXZlbHMgKiBjaGFubmVsT2Zmc2V0OworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbEluaXRpYWxpemVyLCBvZmZzZXQsIGxldmVscywgY2hhbm5lbEJhc2UsIG5MZXZlbHMpOworICAgICAgICAgICAgZm9yIChpbnQgZnJvbSA9IDAsIHRvID0gY2hhbm5lbEJhc2U7IGZyb20gPCBuTGV2ZWxzOyBmcm9tKyssIHRvKyspIHsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbdG9dID0gZGF0YVtkYXRhSWR4XVtmcm9tXSAmIDB4RkZGRjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gcmVtb3ZlIHdoZW4gdGhpcyBtZXRob2QgaXMgdXNlZAorICAgIC8qKgorICAgICAqIElwcCBmaWx0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0eXBlLgorICAgICAqIEBwYXJhbSBza2lwQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBza2lwIGFscGhhLgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIGZpbmFsIGludCBpcHBGaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0LCBpbnQgaW1hZ2VUeXBlLCBib29sZWFuIHNraXBBbHBoYSkgeworICAgICAgICBpbnQgcmVzOworCisgICAgICAgIGludCBzcmNTdHJpZGUsIGRzdFN0cmlkZTsKKyAgICAgICAgaW50IGNoYW5uZWxzOworICAgICAgICBpbnQgb2Zmc2V0c1tdID0gbnVsbDsKKyAgICAgICAgaW50IGNoYW5uZWxzT3JkZXJbXSA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChpbWFnZVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0JfUFJFOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQjogeworICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcmMuZ2V0V2lkdGgoKSAqIDQ7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXIgPSBuZXcgaW50W10geworICAgICAgICAgICAgICAgICAgICAgICAgMiwgMSwgMCwgMworICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFXzRCWVRFX0FCR1I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV80QllURV9BQkdSX1BSRToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9CR1I6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDQ7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogNDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfQllURV9HUkFZOiB7CisgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSAxOworICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNyYy5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV8zQllURV9CR1I6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDM7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiAzOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogMzsKKyAgICAgICAgICAgICAgICBjaGFubmVsc09yZGVyID0gbmV3IGludFtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIDIsIDEsIDAKKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9VU0hPUlRfR1JBWToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF81NjVfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUXzU1NV9SR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0JJTkFSWTogeworICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0LCBza2lwQWxwaGEpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBkZWZhdWx0OiB7CisgICAgICAgICAgICAgICAgU2FtcGxlTW9kZWwgc3JjU00gPSBzcmMuZ2V0U2FtcGxlTW9kZWwoKTsKKyAgICAgICAgICAgICAgICBTYW1wbGVNb2RlbCBkc3RTTSA9IGRzdC5nZXRTYW1wbGVNb2RlbCgpOworCisgICAgICAgICAgICAgICAgaWYgKHNyY1NNIGluc3RhbmNlb2YgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBkc3RTTSBpbnN0YW5jZW9mIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNyY1NNLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBkc3RTTS5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCwgc2tpcEFscGhhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIEhhdmUgSVBQIGZ1bmN0aW9ucyBmb3IgMSwgMyBhbmQgNCBjaGFubmVscworICAgICAgICAgICAgICAgICAgICBjaGFubmVscyA9IHNyY1NNLmdldE51bUJhbmRzKCk7CisgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYW5uZWxzID09IDEgfHwgY2hhbm5lbHMgPT0gMyB8fCBjaGFubmVscyA9PSA0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKXNyY1NNKS5nZXRTY2FubGluZVN0cmlkZSgpOworICAgICAgICAgICAgICAgICAgICBkc3RTdHJpZGUgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKWRzdFNNKS5nZXRTY2FubGluZVN0cmlkZSgpOworCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXIgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKXNyY1NNKS5nZXRCYW5kT2Zmc2V0cygpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3JjU00gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBkc3RTTSBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtMSA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKXNyY1NNOworICAgICAgICAgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtMiA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKWRzdFNNOworCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gc3Bwc20xLmdldE51bUJhbmRzKCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gVFlQRV9JTlRfUkdCLCBUWVBFX0lOVF9BUkdCLi4uCisgICAgICAgICAgICAgICAgICAgIGlmIChzcHBzbTEuZ2V0RGF0YVR5cGUoKSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3Bwc20yLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICEoY2hhbm5lbHMgPT0gMyB8fCBjaGFubmVscyA9PSA0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBjb21wYXRpYmlsaXR5IG9mIHNhbXBsZSBtb2RlbHMKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHNwcHNtMS5nZXRCaXRPZmZzZXRzKCksIHNwcHNtMi5nZXRCaXRPZmZzZXRzKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMoc3Bwc20xLmdldEJpdE1hc2tzKCksIHNwcHNtMi5nZXRCaXRNYXNrcygpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcHBzbTEuZ2V0U2FtcGxlU2l6ZShpKSAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBjaGFubmVsc09yZGVyID0gbmV3IGludFtjaGFubmVsc107CisgICAgICAgICAgICAgICAgICAgIGludCBiaXRPZmZzZXRzW10gPSBzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXJbaV0gPSBiaXRPZmZzZXRzW2ldIC8gODsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChjaGFubmVscyA9PSAzKSB7IC8vIERvbid0IHNraXAgY2hhbm5lbCBub3csIGNvdWxkIGJlCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcHRpbWl6ZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNwcHNtMS5nZXRTY2FubGluZVN0cmlkZSgpICogNDsKKyAgICAgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gc3Bwc20yLmdldFNjYW5saW5lU3RyaWRlKCkgKiA0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0LCBza2lwQWxwaGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIEZpbGwgb2Zmc2V0cyBpZiB0aGVyZSdzIGEgY2hpbGQgcmFzdGVyCisgICAgICAgICAgICAgICAgaWYgKHNyYy5nZXRQYXJlbnQoKSAhPSBudWxsIHx8IGRzdC5nZXRQYXJlbnQoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMCB8fCBzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgIT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSAhPSAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHMgPSBuZXcgaW50WzRdOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1swXSA9IC1zcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBzcmMuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1sxXSA9IC1zcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgKyBzcmMuZ2V0TWluWSgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1syXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBkc3QuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1szXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgKyBkc3QuZ2V0TWluWSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IGxldmVsc1tdID0gbnVsbCwgdmFsdWVzW10gPSBudWxsOworICAgICAgICBpbnQgY2hhbm5lbE11bHRpcGxpZXIgPSBza2lwQWxwaGEgPyAtMSA6IDE7CisgICAgICAgIGlmIChjaGFubmVsTXVsdGlwbGllciAqIGNoYW5uZWxzID09IHZhbGlkRm9yQ2hhbm5lbHMpIHsgLy8gdXNlIGV4aXN0aW5nCisgICAgICAgICAgICAvLyBsZXZlbHMvdmFsdWVzCisgICAgICAgICAgICBsZXZlbHMgPSBjYWNoZWRMZXZlbHM7CisgICAgICAgICAgICB2YWx1ZXMgPSBjYWNoZWRWYWx1ZXM7CisgICAgICAgIH0gZWxzZSB7IC8vIGNyZWF0ZSBuZXcgbGV2ZWxzL3ZhbHVlcworICAgICAgICAgICAgaWYgKGx1dCBpbnN0YW5jZW9mIEJ5dGVMb29rdXBUYWJsZSkgeworICAgICAgICAgICAgICAgIGJ5dGUgZGF0YVtdW10gPSAoKEJ5dGVMb29rdXBUYWJsZSlsdXQpLmdldFRhYmxlKCk7CisgICAgICAgICAgICAgICAgbGV2ZWxzID0gbmV3IGludFtjaGFubmVscyAqIGRhdGFbMF0ubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICB2YWx1ZXMgPSBuZXcgaW50W2NoYW5uZWxzICogZGF0YVswXS5sZW5ndGhdOworICAgICAgICAgICAgICAgIGNyZWF0ZUJ5dGVMZXZlbHMoY2hhbm5lbHMsIHNraXBBbHBoYSwgbGV2ZWxzLCB2YWx1ZXMsIGNoYW5uZWxzT3JkZXIpOworICAgICAgICAgICAgfSBlbHNlIGlmIChsdXQgaW5zdGFuY2VvZiBTaG9ydExvb2t1cFRhYmxlKSB7CisgICAgICAgICAgICAgICAgc2hvcnQgZGF0YVtdW10gPSAoKFNob3J0TG9va3VwVGFibGUpbHV0KS5nZXRUYWJsZSgpOworICAgICAgICAgICAgICAgIGxldmVscyA9IG5ldyBpbnRbY2hhbm5lbHMgKiBkYXRhWzBdLmxlbmd0aF07CisgICAgICAgICAgICAgICAgdmFsdWVzID0gbmV3IGludFtjaGFubmVscyAqIGRhdGFbMF0ubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBjcmVhdGVTaG9ydExldmVscyhjaGFubmVscywgc2tpcEFscGhhLCBsZXZlbHMsIHZhbHVlcywgY2hhbm5lbHNPcmRlcik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNhY2hlIGxldmVscy92YWx1ZXMKKyAgICAgICAgICAgIHZhbGlkRm9yQ2hhbm5lbHMgPSBjaGFubmVsTXVsdGlwbGllciAqIGNoYW5uZWxzOworICAgICAgICAgICAgY2FjaGVkTGV2ZWxzID0gbGV2ZWxzOworICAgICAgICAgICAgY2FjaGVkVmFsdWVzID0gdmFsdWVzOworICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IHNyY0RhdGEsIGRzdERhdGE7CisgICAgICAgIEF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvciBkYkFjY2VzcyA9IEF3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5nZXRJbnN0YW5jZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3JjRGF0YSA9IGRiQWNjZXNzLmdldERhdGEoc3JjLmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgICAgICBkc3REYXRhID0gZGJBY2Nlc3MuZ2V0RGF0YShkc3QuZ2V0RGF0YUJ1ZmZlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsgLy8gVW5rbm93biBkYXRhIGJ1ZmZlciB0eXBlCisgICAgICAgIH0KKworICAgICAgICByZXMgPSBpcHBMVVQoc3JjRGF0YSwgc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSwgc3JjU3RyaWRlLCBkc3REYXRhLCBkc3QuZ2V0V2lkdGgoKSwKKyAgICAgICAgICAgICAgICBkc3QuZ2V0SGVpZ2h0KCksIGRzdFN0cmlkZSwgbGV2ZWxzLCB2YWx1ZXMsIGNoYW5uZWxzLCBvZmZzZXRzLCBmYWxzZSk7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcHAgbHV0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMuCisgICAgICogQHBhcmFtIHNyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgc3JjIHdpZHRoLgorICAgICAqIEBwYXJhbSBzcmNIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBzcmNTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcmMgc3RyaWRlLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QuCisgICAgICogQHBhcmFtIGRzdFdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgZHN0IHdpZHRoLgorICAgICAqIEBwYXJhbSBkc3RIZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3QgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBkc3RTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkc3Qgc3RyaWRlLgorICAgICAqIEBwYXJhbSBsZXZlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbHMuCisgICAgICogQHBhcmFtIHZhbHVlcworICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlcy4KKyAgICAgKiBAcGFyYW0gY2hhbm5lbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFubmVscy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldHMuCisgICAgICogQHBhcmFtIGxpbmVhcgorICAgICAqICAgICAgICAgICAgdGhlIGxpbmVhci4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgZmluYWwgc3RhdGljIG5hdGl2ZSBpbnQgaXBwTFVUKE9iamVjdCBzcmMsIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwgaW50IHNyY1N0cmlkZSwKKyAgICAgICAgICAgIE9iamVjdCBkc3QsIGludCBkc3RXaWR0aCwgaW50IGRzdEhlaWdodCwgaW50IGRzdFN0cmlkZSwgaW50IGxldmVsc1tdLCBpbnQgdmFsdWVzW10sCisgICAgICAgICAgICBpbnQgY2hhbm5lbHMsIGludCBvZmZzZXRzW10sIGJvb2xlYW4gbGluZWFyKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9Mb29rdXBUYWJsZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL0xvb2t1cFRhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQ2NWE1NAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Mb29rdXBUYWJsZS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogT2N0IDE0LCAyMDA1CisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgTG9va3VwVGFibGUgY2xhc3MgcmVwcmVzZW50cyBsb29rdXAgdGFibGUgd2hpY2ggaXMgZGVmaW5lZCB3aXRoCisgKiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgYW5kIG9mZnNldCB2YWx1ZS4gQnl0ZUxvb2t1cFRhYmxlIGFuZAorICogU2hvcnRMb29rdXBUYWJsZSBjbGFzc2VzIGFyZSBzdWJjbGFzc2VzIG9mIExvb2t1cFRhYmxlIHdoaWNoIGNvbnRhaW5zIGJ5dGUKKyAqIGFuZCBzaG9ydCBkYXRhIHRhYmxlcyBhcyBhbiBpbnB1dCBhcnJheXMgZm9yIGJhbmRzIG9yIGNvbXBvbmVudHMgb2YgaW1hZ2UuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTG9va3VwVGFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIG9mZnNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBvZmZzZXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbnVtQ29tcG9uZW50czsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBMb29rdXBUYWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHZhbHVlIGFuZCBudW1iZXIKKyAgICAgKiBvZiBjb21wb25lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdmFsdWUuCisgICAgICogQHBhcmFtIG51bUNvbXBvbmVudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTG9va3VwVGFibGUoaW50IG9mZnNldCwgaW50IG51bUNvbXBvbmVudHMpIHsKKyAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzI9T2Zmc2V0IHNob3VsZCBiZSBub3QgbGVzcyB0aGFuIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjMyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bUNvbXBvbmVudHMgPCAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjMzPU51bWJlciBvZiBjb21wb25lbnRzIHNob3VsZCBiZSBwb3NpdGl2ZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICB0aGlzLm51bUNvbXBvbmVudHMgPSBudW1Db21wb25lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCB2YWx1ZSBvZiB0aGlzIExvb2t1cCB0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgdmFsdWUgb2YgdGhpcyBMb29rdXAgdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhpcyBMb29rdXAgdGFibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIGNvbXBvbmVudHMgb2YgdGhpcyBMb29rdXAgdGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1Db21wb25lbnRzKCkgeworICAgICAgICByZXR1cm4gbnVtQ29tcG9uZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgYXJyYXkgd2hpY2ggY29udGFpbnMgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIHdoaWNoCisgICAgICogaXMgdHJhbnNsYXRlZCB3aXRoIHRoZSBsb29rdXAgdGFibGUgb2YgdGhpcyBMb29rdXBUYWJsZS4gVGhlIHJlc3VsdGVkCisgICAgICogYXJyYXkgaXMgc3RvcmVkIHRvIHRoZSBkc3QgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkgd2hlcmUgdGhlIHJlc3VsdCBjYW4gYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGludGVnZXIgYXJyYXkgb2YgdHJhbnNsYXRlZCBzYW1wbGVzIG9mIGEgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludFtdIGxvb2t1cFBpeGVsKGludFtdIHNyYywgaW50W10gZHN0KTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9NZW1vcnlJbWFnZVNvdXJjZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL01lbW9yeUltYWdlU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQ0ZmQ0MGYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvTWVtb3J5SW1hZ2VTb3VyY2UuamF2YQpAQCAtMCwwICsxLDYwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgTWVtb3J5SW1hZ2VTb3VyY2UgY2xhc3MgaXMgdXNlZCB0byBwcm9kdWNlcyBwaXhlbHMgb2YgYW4gaW1hZ2UgZnJvbSBhbgorICogYXJyYXkuIFRoaXMgY2xhc3MgY2FuIG1hbmFnZSBhIG1lbW9yeSBpbWFnZSB3aGljaCBjb250YWlucyBhbiBhbmltYXRpb24gb3IKKyAqIGN1c3RvbSByZW5kZXJpbmcuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgTWVtb3J5SW1hZ2VTb3VyY2UgaW1wbGVtZW50cyBJbWFnZVByb2R1Y2VyIHsKKworICAgIC8qKgorICAgICAqIFRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBpbnQgd2lkdGg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGVpZ2h0LgorICAgICAqLworICAgIGludCBoZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY20uCisgICAgICovCisgICAgQ29sb3JNb2RlbCBjbTsKKworICAgIC8qKgorICAgICAqIFRoZSBiIGRhdGEuCisgICAgICovCisgICAgYnl0ZSBiRGF0YVtdOworCisgICAgLyoqCisgICAgICogVGhlIGkgZGF0YS4KKyAgICAgKi8KKyAgICBpbnQgaURhdGFbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBvZmZzZXQuCisgICAgICovCisgICAgaW50IG9mZnNldDsKKworICAgIC8qKgorICAgICAqIFRoZSBzY2FubGluZS4KKyAgICAgKi8KKyAgICBpbnQgc2NhbmxpbmU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBIYXNodGFibGU8PywgPz4gcHJvcGVydGllczsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdW1lcnMuCisgICAgICovCisgICAgVmVjdG9yPEltYWdlQ29uc3VtZXI+IGNvbnN1bWVyczsKKworICAgIC8qKgorICAgICAqIFRoZSBhbmltYXRlZC4KKyAgICAgKi8KKyAgICBib29sZWFuIGFuaW1hdGVkOworCisgICAgLyoqCisgICAgICogVGhlIGZ1bGxidWZmZXJzLgorICAgICAqLworICAgIGJvb2xlYW4gZnVsbGJ1ZmZlcnM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGF0YSB0eXBlLgorICAgICAqLworICAgIGludCBkYXRhVHlwZTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBEQVRBX1RZUEVfQllURS4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IERBVEFfVFlQRV9CWVRFID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBEQVRBX1RZUEVfSU5ULgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgREFUQV9UWVBFX0lOVCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTWVtb3J5SW1hZ2VTb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBjbQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBDb2xvck1vZGVsLgorICAgICAqIEBwYXJhbSBwaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBwaXhlbCBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbgorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIGZyb20gb25lIHBpeGVsJ3Mgcm93IHRvIHRoZSBuZXh0IGluIHRoZSBwaXhlbAorICAgICAqICAgICAgICAgICAgYXJyYXkuCisgICAgICogQHBhcmFtIHByb3BzCisgICAgICogICAgICAgICAgICB0aGUgc2V0IG9mIHByb3BlcnRpZXMgdG8gYmUgdXNlZCBmb3IgaW1hZ2UgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVtb3J5SW1hZ2VTb3VyY2UoaW50IHcsIGludCBoLCBDb2xvck1vZGVsIGNtLCBpbnQgcGl4W10sIGludCBvZmYsIGludCBzY2FuLAorICAgICAgICAgICAgSGFzaHRhYmxlPD8sID8+IHByb3BzKSB7CisgICAgICAgIGluaXQodywgaCwgY20sIHBpeCwgb2ZmLCBzY2FuLCBwcm9wcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IE1lbW9yeUltYWdlU291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gY20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgQ29sb3JNb2RlbC4KKyAgICAgKiBAcGFyYW0gcGl4CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgcGl4ZWwgYXJyYXkuCisgICAgICogQHBhcmFtIHNjYW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBmcm9tIG9uZSBwaXhlbCdzIHJvdyB0byB0aGUgbmV4dCBpbiB0aGUgcGl4ZWwKKyAgICAgKiAgICAgICAgICAgIGFycmF5LgorICAgICAqIEBwYXJhbSBwcm9wcworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiBwcm9wZXJ0aWVzIHRvIGJlIHVzZWQgZm9yIGltYWdlIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgcHVibGljIE1lbW9yeUltYWdlU291cmNlKGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBjbSwgYnl0ZSBwaXhbXSwgaW50IG9mZiwgaW50IHNjYW4sCisgICAgICAgICAgICBIYXNodGFibGU8PywgPz4gcHJvcHMpIHsKKyAgICAgICAgaW5pdCh3LCBoLCBjbSwgcGl4LCBvZmYsIHNjYW4sIHByb3BzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTWVtb3J5SW1hZ2VTb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYW5kCisgICAgICogZGVmYXVsdCBSR0IgQ29sb3JNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHBpeAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIHBpeGVsIGFycmF5LgorICAgICAqIEBwYXJhbSBzY2FuCisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgZnJvbSBvbmUgcGl4ZWwncyByb3cgdG8gdGhlIG5leHQgaW4gdGhlIHBpeGVsCisgICAgICogICAgICAgICAgICBhcnJheS4KKyAgICAgKiBAcGFyYW0gcHJvcHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXQgb2YgcHJvcGVydGllcyB0byBiZSB1c2VkIGZvciBpbWFnZSBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyBNZW1vcnlJbWFnZVNvdXJjZShpbnQgdywgaW50IGgsIGludCBwaXhbXSwgaW50IG9mZiwgaW50IHNjYW4sIEhhc2h0YWJsZTw/LCA/PiBwcm9wcykgeworICAgICAgICBpbml0KHcsIGgsIENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpLCBwaXgsIG9mZiwgc2NhbiwgcHJvcHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBNZW1vcnlJbWFnZVNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGNtCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIENvbG9yTW9kZWwuCisgICAgICogQHBhcmFtIHBpeAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIHBpeGVsIGFycmF5LgorICAgICAqIEBwYXJhbSBzY2FuCisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgZnJvbSBvbmUgcGl4ZWwncyByb3cgdG8gdGhlIG5leHQgaW4gdGhlIHBpeGVsCisgICAgICogICAgICAgICAgICBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVtb3J5SW1hZ2VTb3VyY2UoaW50IHcsIGludCBoLCBDb2xvck1vZGVsIGNtLCBpbnQgcGl4W10sIGludCBvZmYsIGludCBzY2FuKSB7CisgICAgICAgIGluaXQodywgaCwgY20sIHBpeCwgb2ZmLCBzY2FuLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTWVtb3J5SW1hZ2VTb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBjbQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBDb2xvck1vZGVsLgorICAgICAqIEBwYXJhbSBwaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBwaXhlbCBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbgorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIGZyb20gb25lIHBpeGVsJ3Mgcm93IHRvIHRoZSBuZXh0IGluIHRoZSBwaXhlbAorICAgICAqICAgICAgICAgICAgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIE1lbW9yeUltYWdlU291cmNlKGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBjbSwgYnl0ZSBwaXhbXSwgaW50IG9mZiwgaW50IHNjYW4pIHsKKyAgICAgICAgaW5pdCh3LCBoLCBjbSwgcGl4LCBvZmYsIHNjYW4sIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBNZW1vcnlJbWFnZVNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBhbmQKKyAgICAgKiBkZWZhdWx0IFJHQiBDb2xvck1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gcGl4CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWxzIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIHBpeGVsIGFycmF5LgorICAgICAqIEBwYXJhbSBzY2FuCisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgZnJvbSBvbmUgcGl4ZWwncyByb3cgdG8gdGhlIG5leHQgaW4gdGhlIHBpeGVsCisgICAgICogICAgICAgICAgICBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVtb3J5SW1hZ2VTb3VyY2UoaW50IHcsIGludCBoLCBpbnQgcGl4W10sIGludCBvZmYsIGludCBzY2FuKSB7CisgICAgICAgIGluaXQodywgaCwgQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCksIHBpeCwgb2ZmLCBzY2FuLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNDb25zdW1lcihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIHJldHVybiBjb25zdW1lcnMuY29udGFpbnMoaWMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJvZHVjdGlvbihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGlmICghaXNDb25zdW1lcihpYykgJiYgaWMgIT0gbnVsbCkgeworICAgICAgICAgICAgY29uc3VtZXJzLmFkZEVsZW1lbnQoaWMpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRIZWFkZXIoaWMpOworICAgICAgICAgICAgc2V0UGl4ZWxzKGljLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgICAgIGlmIChhbmltYXRlZCkgeworICAgICAgICAgICAgICAgIGljLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5TSU5HTEVGUkFNRURPTkUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpYy5pbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuU1RBVElDSU1BR0VET05FKTsKKyAgICAgICAgICAgICAgICBpZiAoaXNDb25zdW1lcihpYykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ29uc3VtZXIoaWMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChpc0NvbnN1bWVyKGljKSkgeworICAgICAgICAgICAgICAgIGljLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5JTUFHRUVSUk9SKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0NvbnN1bWVyKGljKSkgeworICAgICAgICAgICAgICAgIHJlbW92ZUNvbnN1bWVyKGljKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlcXVlc3RUb3BEb3duTGVmdFJpZ2h0UmVzZW5kKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBjb25zdW1lcnMucmVtb3ZlRWxlbWVudChpYyk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZENvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgaWYgKGljID09IG51bGwgfHwgY29uc3VtZXJzLmNvbnRhaW5zKGljKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNvbnN1bWVycy5hZGRFbGVtZW50KGljKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgcGl4ZWwgZGF0YSB3aXRoIGEgbmV3IHBpeGVsIGFycmF5IGZvciBob2xkaW5nIHRoZSBwaXhlbHMgZm9yCisgICAgICogdGhpcyBpbWFnZS4gSWYgYW4gYW5pbWF0aW9uIGZsYWcgaXMgc2V0IHRvIHRydWUgdmFsdWUgYnkgdGhlCisgICAgICogc2V0QW5pbWF0ZWQoKSBtZXRob2QsIHRoZSBuZXcgcGl4ZWxzIHdpbGwgYmUgaW1tZWRpYXRlbHkgZGVsaXZlcmVkIHRvIHRoZQorICAgICAqIEltYWdlQ29uc3VtZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuZXdwaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcGl4ZWwgYXJyYXkuCisgICAgICogQHBhcmFtIG5ld21vZGVsCisgICAgICogICAgICAgICAgICB0aGUgbmV3IENvbG9yTW9kZWwuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIHNjYW5zaXplCisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgZnJvbSBvbmUgcm93IG9mIHBpeGVscyB0byB0aGUgbmV4dCByb3cgaW4gdGhlCisgICAgICogICAgICAgICAgICBwaXhlbCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbmV3UGl4ZWxzKGludCBuZXdwaXhbXSwgQ29sb3JNb2RlbCBuZXdtb2RlbCwgaW50IG9mZnNldCwgaW50IHNjYW5zaXplKSB7CisgICAgICAgIHRoaXMuZGF0YVR5cGUgPSBEQVRBX1RZUEVfSU5UOworICAgICAgICB0aGlzLmlEYXRhID0gbmV3cGl4OworICAgICAgICB0aGlzLmNtID0gbmV3bW9kZWw7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICB0aGlzLnNjYW5saW5lID0gc2NhbnNpemU7CisgICAgICAgIG5ld1BpeGVscygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBwaXhlbCBkYXRhIHdpdGggYSBuZXcgcGl4ZWwgYXJyYXkgZm9yIGhvbGRpbmcgdGhlIHBpeGVscyBmb3IKKyAgICAgKiB0aGlzIGltYWdlLiBJZiBhbiBhbmltYXRpb24gZmxhZyBpcyBzZXQgdG8gdHJ1ZSB2YWx1ZSBieSB0aGUKKyAgICAgKiBzZXRBbmltYXRlZCgpIG1ldGhvZCwgdGhlIG5ldyBwaXhlbHMgd2lsbCBiZSBpbW1lZGlhdGVseSBkZWxpdmVyZWQgdG8gdGhlCisgICAgICogSW1hZ2VDb25zdW1lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIG5ld3BpeAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwaXhlbCBhcnJheS4KKyAgICAgKiBAcGFyYW0gbmV3bW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgQ29sb3JNb2RlbC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBmcm9tIG9uZSByb3cgb2YgcGl4ZWxzIHRvIHRoZSBuZXh0IHJvdyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHBpeGVsIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBuZXdQaXhlbHMoYnl0ZSBuZXdwaXhbXSwgQ29sb3JNb2RlbCBuZXdtb2RlbCwgaW50IG9mZnNldCwgaW50IHNjYW5zaXplKSB7CisgICAgICAgIHRoaXMuZGF0YVR5cGUgPSBEQVRBX1RZUEVfQllURTsKKyAgICAgICAgdGhpcy5iRGF0YSA9IG5ld3BpeDsKKyAgICAgICAgdGhpcy5jbSA9IG5ld21vZGVsOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICAgICAgdGhpcy5zY2FubGluZSA9IHNjYW5zaXplOworICAgICAgICBuZXdQaXhlbHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmdWxsIGJ1ZmZlciB1cGRhdGVzIGZsYWcgdG8gdHJ1ZS4gSWYgdGhpcyBpcyBhbiBhbmltYXRlZCBpbWFnZSwKKyAgICAgKiB0aGUgaW1hZ2UgY29uc3VtZXJzIGhpbnRzIGFyZSB1cGRhdGVkIGFjY29yZGluZ2x5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmdWxsYnVmZmVycworICAgICAqICAgICAgICAgICAgdGhlIHRydWUgaWYgdGhlIHBpeGVsIGJ1ZmZlciBzaG91bGQgYmUgc2VudCBhbHdheXMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEZ1bGxCdWZmZXJVcGRhdGVzKGJvb2xlYW4gZnVsbGJ1ZmZlcnMpIHsKKyAgICAgICAgaWYgKHRoaXMuZnVsbGJ1ZmZlcnMgPT0gZnVsbGJ1ZmZlcnMpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmZ1bGxidWZmZXJzID0gZnVsbGJ1ZmZlcnM7CisgICAgICAgIGlmIChhbmltYXRlZCkgeworICAgICAgICAgICAgT2JqZWN0IGNvbnNBcltdID0gY29uc3VtZXJzLnRvQXJyYXkoKTsKKyAgICAgICAgICAgIGZvciAoT2JqZWN0IGVsZW1lbnQgOiBjb25zQXIpIHsKKyAgICAgICAgICAgICAgICBJbWFnZUNvbnN1bWVyIGNvbiA9IChJbWFnZUNvbnN1bWVyKWVsZW1lbnQ7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZ1bGxidWZmZXJzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb24uc2V0SGludHMoSW1hZ2VDb25zdW1lci5UT1BET1dOTEVGVFJJR0hUCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1hZ2VDb25zdW1lci5DT01QTEVURVNDQU5MSU5FUyk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb24uc2V0SGludHMoSW1hZ2VDb25zdW1lci5SQU5ET01QSVhFTE9SREVSKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0NvbnN1bWVyKGNvbikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbi5pbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuSU1BR0VFUlJPUik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29uc3VtZXIoY29uKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ29uc3VtZXIoY29uKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgdGhhdCB0ZWxscyB3aGV0aGVyIHRoaXMgbWVtb3J5IGltYWdlIGhhcyBtb3JlIHRoYW4gb25lCisgICAgICogZnJhbWUgKGZvciBhbmltYXRpb24pOiB0cnVlIGZvciBtdWx0aXBsZSBmcmFtZXMsIGZhbHNlIGlmIHRoaXMgY2xhc3MKKyAgICAgKiByZXByZXNlbnRzIGEgc2luZ2xlIGZyYW1lIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhbmltYXRlZAorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGlzIGltYWdlIHJlcHJlc2VudHMgYW4gYW5pbWF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRBbmltYXRlZChib29sZWFuIGFuaW1hdGVkKSB7CisgICAgICAgIGlmICh0aGlzLmFuaW1hdGVkID09IGFuaW1hdGVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IGNvbnNBcltdID0gY29uc3VtZXJzLnRvQXJyYXkoKTsKKyAgICAgICAgZm9yIChPYmplY3QgZWxlbWVudCA6IGNvbnNBcikgeworICAgICAgICAgICAgSW1hZ2VDb25zdW1lciBjb24gPSAoSW1hZ2VDb25zdW1lcillbGVtZW50OworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb24uaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLlNUQVRJQ0lNQUdFRE9ORSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChpc0NvbnN1bWVyKGNvbikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29uLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5JTUFHRUVSUk9SKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNDb25zdW1lcihjb24pKSB7CisgICAgICAgICAgICAgICAgcmVtb3ZlQ29uc3VtZXIoY29uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLmFuaW1hdGVkID0gYW5pbWF0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mIHRoZSBidWZmZXIgdG8gSW1hZ2VDb25zdW1lcnMgYW5kCisgICAgICogbm90aWZpZXMgdGhlbSB0aGF0IGFuIGFuaW1hdGlvbiBmcmFtZSBpcyBjb21wbGV0ZWQgb25seSBpZiB0aGUge0Bjb2RlCisgICAgICogZnJhbWVub3RpZnl9IHBhcmFtZXRlciBpcyB0cnVlLiBUaGF0IHdvcmtzIG9ubHkgaWYgdGhlIGFuaW1hdGVkIGZsYWcgaGFzCisgICAgICogYmVlbiBzZXQgdG8gdHJ1ZSBieSB0aGUgc2V0QW5pbWF0ZWQoKSBtZXRob2QuIElmIHRoZSBmdWxsIGJ1ZmZlciB1cGRhdGUKKyAgICAgKiBmbGFnIGhhcyBiZWVuIHNldCB0byB0cnVlIGJ5IHRoZSBzZXRGdWxsQnVmZmVyVXBkYXRlcygpIG1ldGhvZCwgdGhlbiB0aGUKKyAgICAgKiBlbnRpcmUgYnVmZmVyIHdpbGwgYWx3YXlzIGJlIHNlbnQgaWdub3JpbmcgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBmcmFtZW5vdGlmeQorICAgICAqICAgICAgICAgICAgdHJ1ZSBpZiBhIFNJTkdMRUZSQU1FRE9ORSBub3RpZmljYXRpb24gc2hvdWxkIGJlIHNlbnQgdG8gdGhlCisgICAgICogICAgICAgICAgICByZWdpc3RlcmVkIGNvbnN1bWVycywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBuZXdQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGJvb2xlYW4gZnJhbWVub3RpZnkpIHsKKyAgICAgICAgaWYgKGFuaW1hdGVkKSB7CisgICAgICAgICAgICBpZiAoZnVsbGJ1ZmZlcnMpIHsKKyAgICAgICAgICAgICAgICB4ID0gMDsKKyAgICAgICAgICAgICAgICB5ID0gMDsKKyAgICAgICAgICAgICAgICB3ID0gd2lkdGg7CisgICAgICAgICAgICAgICAgaCA9IGhlaWdodDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKHggPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIHcgKz0geDsKKyAgICAgICAgICAgICAgICAgICAgeCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh3ID4gd2lkdGgpIHsKKyAgICAgICAgICAgICAgICAgICAgdyA9IHdpZHRoIC0geDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHkgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGggKz0geTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGggPiBoZWlnaHQpIHsKKyAgICAgICAgICAgICAgICBoID0gaGVpZ2h0IC0geTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE9iamVjdCBjb25zQXJbXSA9IGNvbnN1bWVycy50b0FycmF5KCk7CisgICAgICAgICAgICBmb3IgKE9iamVjdCBlbGVtZW50IDogY29uc0FyKSB7CisgICAgICAgICAgICAgICAgSW1hZ2VDb25zdW1lciBjb24gPSAoSW1hZ2VDb25zdW1lcillbGVtZW50OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh3ID4gMCAmJiBoID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2V0UGl4ZWxzKGNvbiwgeCwgeSwgdywgaCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGZyYW1lbm90aWZ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb24uaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLlNJTkdMRUZSQU1FRE9ORSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29uc3VtZXIoY29uKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29uLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5JTUFHRUVSUk9SKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb25zdW1lcihjb24pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDb25zdW1lcihjb24pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mIHRoZSBidWZmZXIgdG8gdGhlIEltYWdlQ29uc3VtZXJzCisgICAgICogYW5kIG5vdGlmaWVzIHRoZW0gdGhhdCBhbiBhbmltYXRpb24gZnJhbWUgaXMgY29tcGxldGVkIGlmIHRoZSBhbmltYXRlZAorICAgICAqIGZsYWcgaGFzIGJlZW4gc2V0IHRvIHRydWUgYnkgdGhlIHNldEFuaW1hdGVkKCkgbWV0aG9kLiBJZiB0aGUgZnVsbCBidWZmZXIKKyAgICAgKiB1cGRhdGUgZmxhZyBoYXMgYmVlbiBzZXQgdG8gdHJ1ZSBieSB0aGUgc2V0RnVsbEJ1ZmZlclVwZGF0ZXMoKSBtZXRob2QsCisgICAgICogdGhlbiB0aGUgZW50aXJlIGJ1ZmZlciB3aWxsIGFsd2F5cyBiZSBzZW50IGlnbm9yaW5nIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbmV3UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7CisgICAgICAgIG5ld1BpeGVscyh4LCB5LCB3LCBoLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBhIG5ldyBidWZmZXIgb2YgcGl4ZWxzIHRvIHRoZSBJbWFnZUNvbnN1bWVycyBhbmQgbm90aWZpZXMgdGhlbSB0aGF0CisgICAgICogYW4gYW5pbWF0aW9uIGZyYW1lIGlzIGNvbXBsZXRlZCBpZiB0aGUgYW5pbWF0ZWQgZmxhZyBoYXMgYmVlbiBzZXQgdG8gdHJ1ZQorICAgICAqIGJ5IHRoZSBzZXRBbmltYXRlZCgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBuZXdQaXhlbHMoKSB7CisgICAgICAgIG5ld1BpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0cyB0aGUuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGguCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodC4KKyAgICAgKiBAcGFyYW0gbW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RlbC4KKyAgICAgKiBAcGFyYW0gcGl4ZWxzCisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmYuCisgICAgICogQHBhcmFtIHNjYW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FuLgorICAgICAqIEBwYXJhbSBwcm9wCisgICAgICogICAgICAgICAgICB0aGUgcHJvcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdChpbnQgd2lkdGgsIGludCBoZWlnaHQsIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGUgcGl4ZWxzW10sIGludCBvZmYsIGludCBzY2FuLAorICAgICAgICAgICAgSGFzaHRhYmxlPD8sID8+IHByb3ApIHsKKworICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7CisgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICB0aGlzLmNtID0gbW9kZWw7CisgICAgICAgIHRoaXMuYkRhdGEgPSBwaXhlbHM7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2ZmOworICAgICAgICB0aGlzLnNjYW5saW5lID0gc2NhbjsKKyAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcDsKKyAgICAgICAgdGhpcy5kYXRhVHlwZSA9IERBVEFfVFlQRV9CWVRFOworICAgICAgICB0aGlzLmNvbnN1bWVycyA9IG5ldyBWZWN0b3I8SW1hZ2VDb25zdW1lcj4oKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRzIHRoZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aC4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0LgorICAgICAqIEBwYXJhbSBtb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIG1vZGVsLgorICAgICAqIEBwYXJhbSBwaXhlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbHMuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZi4KKyAgICAgKiBAcGFyYW0gc2NhbgorICAgICAqICAgICAgICAgICAgdGhlIHNjYW4uCisgICAgICogQHBhcmFtIHByb3AKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0KGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29sb3JNb2RlbCBtb2RlbCwgaW50IHBpeGVsc1tdLCBpbnQgb2ZmLCBpbnQgc2NhbiwKKyAgICAgICAgICAgIEhhc2h0YWJsZTw/LCA/PiBwcm9wKSB7CisKKyAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoOworICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICAgICAgdGhpcy5jbSA9IG1vZGVsOworICAgICAgICB0aGlzLmlEYXRhID0gcGl4ZWxzOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZjsKKyAgICAgICAgdGhpcy5zY2FubGluZSA9IHNjYW47CisgICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3A7CisgICAgICAgIHRoaXMuZGF0YVR5cGUgPSBEQVRBX1RZUEVfSU5UOworICAgICAgICB0aGlzLmNvbnN1bWVycyA9IG5ldyBWZWN0b3I8SW1hZ2VDb25zdW1lcj4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwaXhlbHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbi4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHguCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB5LgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgdy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGguCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFBpeGVscyhJbWFnZUNvbnN1bWVyIGNvbiwgaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpIHsKKyAgICAgICAgaW50IHBpeGVsT2ZmID0gc2NhbmxpbmUgKiB5ICsgb2Zmc2V0ICsgeDsKKworICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CisgICAgICAgICAgICBjYXNlIERBVEFfVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGNvbi5zZXRQaXhlbHMoeCwgeSwgdywgaCwgY20sIGJEYXRhLCBwaXhlbE9mZiwgc2NhbmxpbmUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEQVRBX1RZUEVfSU5UOgorICAgICAgICAgICAgICAgIGNvbi5zZXRQaXhlbHMoeCwgeSwgdywgaCwgY20sIGlEYXRhLCBwaXhlbE9mZiwgc2NhbmxpbmUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjJBPVdyb25nIHR5cGUgb2YgcGl4ZWxzIGFycmF5CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMkEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGhlYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29uCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGhlYWRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHNldEhlYWRlcihJbWFnZUNvbnN1bWVyIGNvbikgeworICAgICAgICBjb24uc2V0RGltZW5zaW9ucyh3aWR0aCwgaGVpZ2h0KTsKKyAgICAgICAgY29uLnNldFByb3BlcnRpZXMocHJvcGVydGllcyk7CisgICAgICAgIGNvbi5zZXRDb2xvck1vZGVsKGNtKTsKKyAgICAgICAgY29uCisgICAgICAgICAgICAgICAgLnNldEhpbnRzKGFuaW1hdGVkID8gKGZ1bGxidWZmZXJzID8gKEltYWdlQ29uc3VtZXIuVE9QRE9XTkxFRlRSSUdIVCB8IEltYWdlQ29uc3VtZXIuQ09NUExFVEVTQ0FOTElORVMpCisgICAgICAgICAgICAgICAgICAgICAgICA6IEltYWdlQ29uc3VtZXIuUkFORE9NUElYRUxPUkRFUikKKyAgICAgICAgICAgICAgICAgICAgICAgIDogKEltYWdlQ29uc3VtZXIuVE9QRE9XTkxFRlRSSUdIVCB8IEltYWdlQ29uc3VtZXIuQ09NUExFVEVTQ0FOTElORVMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJbWFnZUNvbnN1bWVyLlNJTkdMRVBBU1MgfCBJbWFnZUNvbnN1bWVyLlNJTkdMRUZSQU1FKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2RjMTNkOAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9NdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwuamF2YQpAQCAtMCwwICsxLDQ3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIGNsYXNzIHJlcHJlc2VudHMgaW1hZ2UgZGF0YSB3aXRoIG9uZSBiYW5kLgorICogVGhpcyBjbGFzcyBwYWNrcyBtdWx0aXBsZSBwaXhlbHMgd2l0aCBvbmUgc2FtcGxlIGluIG9uZSBkYXRhIGVsZW1lbnQgYW5kCisgKiBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGRhdGEgdHlwZXM6IERhdGFCdWZmZXIuVFlQRV9CWVRFLAorICogRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCwgb3IgRGF0YUJ1ZmZlci5UWVBFX0lOVC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgZXh0ZW5kcyBTYW1wbGVNb2RlbCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGl4ZWwgYml0IHN0cmlkZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBwaXhlbEJpdFN0cmlkZTsKKworICAgIC8qKgorICAgICAqIFRoZSBzY2FubGluZSBzdHJpZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc2NhbmxpbmVTdHJpZGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGF0YSBiaXQgb2Zmc2V0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGRhdGFCaXRPZmZzZXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYml0IG1hc2suCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYml0TWFzazsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhIGVsZW1lbnQgc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBkYXRhRWxlbWVudFNpemU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGl4ZWxzIHBlciBkYXRhIGVsZW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcGl4ZWxzUGVyRGF0YUVsZW1lbnQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHRoZSBzYW1wbGVzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIG51bWJlck9mQml0cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHBlciBwaXhlbC4KKyAgICAgKiBAcGFyYW0gc2NhbmxpbmVTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUgb2YgdGhlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBkYXRhQml0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgdGhlIGJhbmQgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKGludCBkYXRhVHlwZSwgaW50IHcsIGludCBoLCBpbnQgbnVtYmVyT2ZCaXRzLAorICAgICAgICAgICAgaW50IHNjYW5saW5lU3RyaWRlLCBpbnQgZGF0YUJpdE9mZnNldCkgeworCisgICAgICAgIHN1cGVyKGRhdGFUeXBlLCB3LCBoLCAxKTsKKyAgICAgICAgaWYgKGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQKKyAgICAgICAgICAgICAgICAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UKSB7CisgICAgICAgICAgICAvLyBhd3QuNjE9VW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiB7MH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjEiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlKSk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnNjYW5saW5lU3RyaWRlID0gc2NhbmxpbmVTdHJpZGU7CisgICAgICAgIGlmIChudW1iZXJPZkJpdHMgPT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIwQz1OdW1iZXIgb2YgQml0cyBlcXVhbHMgdG8gemVybworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMEMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnBpeGVsQml0U3RyaWRlID0gbnVtYmVyT2ZCaXRzOworICAgICAgICB0aGlzLmRhdGFFbGVtZW50U2l6ZSA9IERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKGRhdGFUeXBlKTsKKyAgICAgICAgaWYgKGRhdGFFbGVtZW50U2l6ZSAlIHBpeGVsQml0U3RyaWRlICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMEQ9VGhlIG51bWJlciBvZiBiaXRzIHBlciBwaXhlbCBpcyBub3QgYSBwb3dlciBvZiAyIG9yCisgICAgICAgICAgICAvLyBwaXhlbHMgc3BhbiBkYXRhIGVsZW1lbnQgYm91bmRhcmllcworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMEQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkYXRhQml0T2Zmc2V0ICUgbnVtYmVyT2ZCaXRzICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMEU9RGF0YSBCaXQgb2Zmc2V0IGlzIG5vdCBhIG11bHRpcGxlIG9mIHBpeGVsIGJpdCBzdHJpZGUKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjBFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5kYXRhQml0T2Zmc2V0ID0gZGF0YUJpdE9mZnNldDsKKworICAgICAgICB0aGlzLnBpeGVsc1BlckRhdGFFbGVtZW50ID0gZGF0YUVsZW1lbnRTaXplIC8gcGl4ZWxCaXRTdHJpZGU7CisgICAgICAgIHRoaXMuYml0TWFzayA9ICgxIDw8IG51bWJlck9mQml0cykgLSAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHNhbXBsZXMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gbnVtYmVyT2ZCaXRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJpdHMgcGVyIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwoaW50IGRhdGFUeXBlLCBpbnQgdywgaW50IGgsIGludCBudW1iZXJPZkJpdHMpIHsKKworICAgICAgICB0aGlzKGRhdGFUeXBlLCB3LCBoLCBudW1iZXJPZkJpdHMsCisgICAgICAgICAgICAgICAgKG51bWJlck9mQml0cyAqIHcgKyBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShkYXRhVHlwZSkgLSAxKQorICAgICAgICAgICAgICAgICAgICAgICAgLyBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShkYXRhVHlwZSksIDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChnZXRUcmFuc2ZlclR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gbmV3IGJ5dGVbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmRhdGEgPSAoYnl0ZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYmRhdGFbMF0gPSAoYnl0ZSlnZXRTYW1wbGUoeCwgeSwgMCwgZGF0YSk7CisgICAgICAgICAgICAgICAgb2JqID0gYmRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2RhdGFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc2RhdGEgPSBuZXcgc2hvcnRbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2RhdGEgPSAoc2hvcnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNkYXRhWzBdID0gKHNob3J0KWdldFNhbXBsZSh4LCB5LCAwLCBkYXRhKTsKKyAgICAgICAgICAgICAgICBvYmogPSBzZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWRhdGFbXTsKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWRhdGEgPSBuZXcgaW50WzFdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlkYXRhID0gKGludFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWRhdGFbMF0gPSBnZXRTYW1wbGUoeCwgeSwgMCwgZGF0YSk7CisgICAgICAgICAgICAgICAgb2JqID0gaWRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb2JqOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIE9iamVjdCBvYmosIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBzZXRTYW1wbGUoeCwgeSwgb2JqLCBkYXRhLCAxLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIG9iamVjdCBpcyBhIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCB3aXRoIHRoZQorICAgICAqICAgICAgICAgc2FtZSBkYXRhIHBhcmFtZXRlciB2YWx1ZXMgYXMgdGhpcyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwsCisgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICgobyA9PSBudWxsKSB8fCAhKG8gaW5zdGFuY2VvZiBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgbW9kZWwgPSAoTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKW87CisgICAgICAgIHJldHVybiB0aGlzLndpZHRoID09IG1vZGVsLndpZHRoICYmIHRoaXMuaGVpZ2h0ID09IG1vZGVsLmhlaWdodAorICAgICAgICAgICAgICAgICYmIHRoaXMubnVtQmFuZHMgPT0gbW9kZWwubnVtQmFuZHMgJiYgdGhpcy5kYXRhVHlwZSA9PSBtb2RlbC5kYXRhVHlwZQorICAgICAgICAgICAgICAgICYmIHRoaXMucGl4ZWxCaXRTdHJpZGUgPT0gbW9kZWwucGl4ZWxCaXRTdHJpZGUgJiYgdGhpcy5iaXRNYXNrID09IG1vZGVsLmJpdE1hc2sKKyAgICAgICAgICAgICAgICAmJiB0aGlzLnBpeGVsc1BlckRhdGFFbGVtZW50ID09IG1vZGVsLnBpeGVsc1BlckRhdGFFbGVtZW50CisgICAgICAgICAgICAgICAgJiYgdGhpcy5kYXRhRWxlbWVudFNpemUgPT0gbW9kZWwuZGF0YUVsZW1lbnRTaXplCisgICAgICAgICAgICAgICAgJiYgdGhpcy5kYXRhQml0T2Zmc2V0ID09IG1vZGVsLmRhdGFCaXRPZmZzZXQKKyAgICAgICAgICAgICAgICAmJiB0aGlzLnNjYW5saW5lU3RyaWRlID09IG1vZGVsLnNjYW5saW5lU3RyaWRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBjcmVhdGVTdWJzZXRTYW1wbGVNb2RlbChpbnQgYmFuZHNbXSkgeworICAgICAgICBpZiAoYmFuZHMgIT0gbnVsbCAmJiBiYW5kcy5sZW5ndGggIT0gMSkgeworICAgICAgICAgICAgLy8gYXd0LjIwRj1OdW1iZXIgb2YgYmFuZHMgbXVzdCBiZSBvbmx5IDEKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjBGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbCh3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgY3JlYXRlQ29tcGF0aWJsZVNhbXBsZU1vZGVsKGludCB3LCBpbnQgaCkgeworICAgICAgICByZXR1cm4gbmV3IE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwgcGl4ZWxCaXRTdHJpZGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW50IHBpeGVsW107CisgICAgICAgIGlmIChpQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcGl4ZWwgPSBuZXcgaW50W251bUJhbmRzXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBpeGVsID0gaUFycmF5OworICAgICAgICB9CisKKyAgICAgICAgcGl4ZWxbMF0gPSBnZXRTYW1wbGUoeCwgeSwgMCwgZGF0YSk7CisgICAgICAgIHJldHVybiBwaXhlbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpQXJyYXksIGRhdGEsIDIsIDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCA+PSB0aGlzLndpZHRoIHx8IHkgPj0gdGhpcy5oZWlnaHQgfHwgYiAhPSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBiaXRudW0gPSBkYXRhQml0T2Zmc2V0ICsgeCAqIHBpeGVsQml0U3RyaWRlOworICAgICAgICBpbnQgZWxlbSA9IGRhdGEuZ2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyBiaXRudW0gLyBkYXRhRWxlbWVudFNpemUpOworICAgICAgICBpbnQgc2hpZnQgPSBkYXRhRWxlbWVudFNpemUgLSAoYml0bnVtICYgKGRhdGFFbGVtZW50U2l6ZSAtIDEpKSAtIHBpeGVsQml0U3RyaWRlOworCisgICAgICAgIHJldHVybiAoZWxlbSA+PiBzaGlmdCkgJiBiaXRNYXNrOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBpbnQgcywgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmIChiICE9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgc2V0U2FtcGxlKHgsIHksIG51bGwsIGRhdGEsIDMsIHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRhQnVmZmVyIGNyZWF0ZURhdGFCdWZmZXIoKSB7CisgICAgICAgIERhdGFCdWZmZXIgZGF0YUJ1ZmZlciA9IG51bGw7CisgICAgICAgIGludCBzaXplID0gc2NhbmxpbmVTdHJpZGUgKiBoZWlnaHQ7CisKKyAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyID0gbmV3IERhdGFCdWZmZXJCeXRlKHNpemUgKyAoZGF0YUJpdE9mZnNldCArIDcpIC8gOCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlciA9IG5ldyBEYXRhQnVmZmVyVVNob3J0KHNpemUgKyAoZGF0YUJpdE9mZnNldCArIDE1KSAvIDE2KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyID0gbmV3IERhdGFCdWZmZXJJbnQoc2l6ZSArIChkYXRhQml0T2Zmc2V0ICsgMzEpIC8gMzIpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkYXRhQnVmZmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE9mZnNldChpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgcmV0dXJuIHkgKiBzY2FubGluZVN0cmlkZSArICh4ICogcGl4ZWxCaXRTdHJpZGUgKyBkYXRhQml0T2Zmc2V0KSAvIGRhdGFFbGVtZW50U2l6ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNhbXBsZVNpemUoaW50IGJhbmQpIHsKKyAgICAgICAgcmV0dXJuIHBpeGVsQml0U3RyaWRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJpdCBvZmZzZXQgaW4gdGhlIGRhdGEgZWxlbWVudCB3aGljaCBpcyBzdG9yZWQgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwaXhlbCBvZiBhIHNjYW5saW5lLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwuCisgICAgICogQHJldHVybiB0aGUgYml0IG9mZnNldCBvZiB0aGUgcGl4ZWwgaW4gdGhlIGRhdGEgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEJpdE9mZnNldChpbnQgeCkgeworICAgICAgICByZXR1cm4gKHggKiBwaXhlbEJpdFN0cmlkZSArIGRhdGFCaXRPZmZzZXQpICUgZGF0YUVsZW1lbnRTaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRTYW1wbGVTaXplKCkgeworICAgICAgICBpbnQgc2FtcGxlU2l6ZXNbXSA9IHsKKyAgICAgICAgICAgIHBpeGVsQml0U3RyaWRlCisgICAgICAgIH07CisgICAgICAgIHJldHVybiBzYW1wbGVTaXplczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIG9mIHRoaXMgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIGNsYXNzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBvZiB0aGlzIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBjbGFzcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IDA7CisgICAgICAgIGludCB0bXAgPSAwOworCisgICAgICAgIGhhc2ggPSB3aWR0aDsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBoYXNoIF49IGhlaWdodDsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBoYXNoIF49IG51bUJhbmRzOworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gZGF0YVR5cGU7CisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBzY2FubGluZVN0cmlkZTsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBoYXNoIF49IHBpeGVsQml0U3RyaWRlOworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gZGF0YUJpdE9mZnNldDsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBoYXNoIF49IGJpdE1hc2s7CisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBkYXRhRWxlbWVudFNpemU7CisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBwaXhlbHNQZXJEYXRhRWxlbWVudDsKKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUcmFuc2ZlclR5cGUoKSB7CisgICAgICAgIGlmIChwaXhlbEJpdFN0cmlkZSA+IDE2KSB7CisgICAgICAgICAgICByZXR1cm4gRGF0YUJ1ZmZlci5UWVBFX0lOVDsKKyAgICAgICAgfSBlbHNlIGlmIChwaXhlbEJpdFN0cmlkZSA+IDgpIHsKKyAgICAgICAgICAgIHJldHVybiBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIERhdGFCdWZmZXIuVFlQRV9CWVRFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoaXMgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGlzIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNjYW5saW5lU3RyaWRlKCkgeworICAgICAgICByZXR1cm4gc2NhbmxpbmVTdHJpZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGl4ZWwgYml0IHN0cmlkZSBvZiB0aGlzIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBwaXhlbCBiaXQgc3RyaWRlIG9mIHRoaXMgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGl4ZWxCaXRTdHJpZGUoKSB7CisgICAgICAgIHJldHVybiBwaXhlbEJpdFN0cmlkZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE51bURhdGFFbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGF0YSBiaXQgb2Zmc2V0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgYml0IG9mZnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERhdGFCaXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBkYXRhQml0T2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgb3RoZXIgbWV0aG9kcyBvZiB0aGlzIGNsYXNzLiBUaGUgYmVoYXZpb3Igb2YgdGhpcworICAgICAqIG1ldGhvZCBkZXBlbmRzIG9uIHRoZSBtZXRob2Qgd2hpY2ggaGFzIGJlZW4gaW52b2tlIHRoaXMgb25lLiBUaGUgYXJndW1lbnQKKyAgICAgKiBtZXRob2RJZCBpcyB1c2VkIHRvIGNob29zZSB2YWxpZCBiZWhhdmlvciBpbiBhIHBhcnRpY3VsYXIgY2FzZS4gSWYKKyAgICAgKiBtZXRob2RJZCBpcyBlcXVhbCB0byAxIGl0IG1lYW5zIHRoYXQgdGhpcyBtZXRob2QgaGFzIGJlZW4gaW52b2tlZCBieSB0aGUKKyAgICAgKiBzZXREYXRhRWxlbWVudHMoKSBtZXRob2QsIDIgLSBtZWFucyBzZXRQaXhlbCgpLCBhbmQgc2V0U2FtcGxlKCkgaW4gYW55CisgICAgICogb3RoZXIgY2FzZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSB4LgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgeS4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gbWV0aG9kSWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXRob2QgaWQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRTYW1wbGUoZmluYWwgaW50IHgsIGZpbmFsIGludCB5LCBmaW5hbCBPYmplY3Qgb2JqLCBmaW5hbCBEYXRhQnVmZmVyIGRhdGEsCisgICAgICAgICAgICBmaW5hbCBpbnQgbWV0aG9kSWQsIGludCBzKSB7CisgICAgICAgIGlmICgoeCA8IDApIHx8ICh5IDwgMCkgfHwgKHggPj0gdGhpcy53aWR0aCkgfHwgKHkgPj0gdGhpcy5oZWlnaHQpKSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBiaXRudW0gPSBkYXRhQml0T2Zmc2V0ICsgeCAqIHBpeGVsQml0U3RyaWRlOworICAgICAgICBmaW5hbCBpbnQgaWR4ID0geSAqIHNjYW5saW5lU3RyaWRlICsgYml0bnVtIC8gZGF0YUVsZW1lbnRTaXplOworICAgICAgICBmaW5hbCBpbnQgc2hpZnQgPSBkYXRhRWxlbWVudFNpemUgLSAoYml0bnVtICYgKGRhdGFFbGVtZW50U2l6ZSAtIDEpKSAtIHBpeGVsQml0U3RyaWRlOworICAgICAgICBmaW5hbCBpbnQgbWFzayA9IH4oYml0TWFzayA8PCBzaGlmdCk7CisgICAgICAgIGludCBlbGVtID0gZGF0YS5nZXRFbGVtKGlkeCk7CisKKyAgICAgICAgc3dpdGNoIChtZXRob2RJZCkgeworICAgICAgICAgICAgY2FzZSAxOiB7IC8vIEludm9rZWQgZnJvbSBzZXREYXRhRWxlbWVudHMoKQorICAgICAgICAgICAgICAgIHN3aXRjaCAoZ2V0VHJhbnNmZXJUeXBlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICAgICAgICAgIHMgPSAoKGJ5dGVbXSlvYmopWzBdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgICAgICAgICBzID0gKChzaG9ydFtdKW9iailbMF0gJiAweGZmZmY7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICgoaW50W10pb2JqKVswXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgMjogeyAvLyBJbnZva2VkIGZyb20gc2V0UGl4ZWwoKQorICAgICAgICAgICAgICAgIHMgPSAoKGludFtdKW9iailbMF07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBlbGVtICY9IG1hc2s7CisgICAgICAgIGVsZW0gfD0gKHMgJiBiaXRNYXNrKSA8PCBzaGlmdDsKKyAgICAgICAgZGF0YS5zZXRFbGVtKGlkeCwgZWxlbSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1BhY2tlZENvbG9yTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9QYWNrZWRDb2xvck1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQxYzJlNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9QYWNrZWRDb2xvck1vZGVsLmphdmEKQEAgLTAsMCArMSw0MDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuVHJhbnNwYXJlbmN5OworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBjbGFzcyBQYWNrZWRDb2xvck1vZGVsIHJlcHJlc2VudHMgYSBjb2xvciBtb2RlbCB3aGVyZSB0aGUgY29tcG9uZW50cyBhcmUKKyAqIGp1c3QgdGhlIHJlZCwgZ3JlZW4sIGFuZCBibHVlIGJhbmRzLCBwbHVzIGFuIGFscGhhIGJhbmQgaWYgYWxwaGEgaXMKKyAqIHN1cHBvcnRlZC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQYWNrZWRDb2xvck1vZGVsIGV4dGVuZHMgQ29sb3JNb2RlbCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcG9uZW50IG1hc2tzLgorICAgICAqLworICAgIGludCBjb21wb25lbnRNYXNrc1tdOworCisgICAgLyoqCisgICAgICogVGhlIG9mZnNldHMuCisgICAgICovCisgICAgaW50IG9mZnNldHNbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBzY2FsZXMuCisgICAgICovCisgICAgZmxvYXQgc2NhbGVzW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcGFja2VkIGNvbG9yIG1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcGFjZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbG9yIHNwYWNlLgorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY29tcG9uZW50IG1hc2tzLgorICAgICAqIEBwYXJhbSBjb2xvck1hc2tBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRoYXQgZ2l2ZXMgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byBlYWNoIGNvbG9yCisgICAgICogICAgICAgICAgICBiYW5kIChyZWQsIGdyZWVuLCBhbmQgYmx1ZSkuCisgICAgICogQHBhcmFtIGFscGhhTWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgYWxwaGEgYmFuZC4KKyAgICAgKiBAcGFyYW0gaXNBbHBoYVByZW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdGhlIGFscGhhIGlzIHByZS1tdWx0aXBsaWVkIGluIHRoaXMgY29sb3IgbW9kZWwuCisgICAgICogQHBhcmFtIHRyYW5zCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNwYXJlbmN5IHN0cmF0ZWd5LCBAc2VlIGphdmEuYXd0LlRyYW5zcGFyZW5jeS4KKyAgICAgKiBAcGFyYW0gdHJhbnNmZXJUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmZXIgdHlwZSAocHJpbWl0aXZlIGphdmEgdHlwZSB0byB1c2UgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgY29tcG9uZW50cykuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGNvbWJpbmVkIGJpdG1hc2tzIGZvciB0aGUgY29sb3IKKyAgICAgKiAgICAgICAgICAgICBiYW5kcyBpcyBsZXNzIHRoYW4gb25lIG9yIGdyZWF0ZXIgdGhhbiAzMi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFja2VkQ29sb3JNb2RlbChDb2xvclNwYWNlIHNwYWNlLCBpbnQgYml0cywgaW50IGNvbG9yTWFza0FycmF5W10sIGludCBhbHBoYU1hc2ssCisgICAgICAgICAgICBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCBpbnQgdHJhbnMsIGludCB0cmFuc2ZlclR5cGUpIHsKKworICAgICAgICBzdXBlcihiaXRzLCBjcmVhdGVCaXRzKGNvbG9yTWFza0FycmF5LCBhbHBoYU1hc2spLCBzcGFjZSwgKGFscGhhTWFzayA9PSAwID8gZmFsc2UgOiB0cnVlKSwKKyAgICAgICAgICAgICAgICBpc0FscGhhUHJlbXVsdGlwbGllZCwgdHJhbnMsIHZhbGlkYXRlVHJhbnNmZXJUeXBlKHRyYW5zZmVyVHlwZSkpOworCisgICAgICAgIGlmIChwaXhlbF9iaXRzIDwgMSB8fCBwaXhlbF9iaXRzID4gMzIpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzY9VGhlIGJpdHMgaXMgbGVzcyB0aGFuIDEgb3IgZ3JlYXRlciB0aGFuIDMyCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgY29tcG9uZW50TWFza3MgPSBuZXcgaW50W251bUNvbXBvbmVudHNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbG9yQ29tcG9uZW50czsgaSsrKSB7CisgICAgICAgICAgICBjb21wb25lbnRNYXNrc1tpXSA9IGNvbG9yTWFza0FycmF5W2ldOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICBjb21wb25lbnRNYXNrc1tudW1Db2xvckNvbXBvbmVudHNdID0gYWxwaGFNYXNrOworICAgICAgICAgICAgaWYgKHRoaXMuYml0c1tudW1Db2xvckNvbXBvbmVudHNdID09IDEpIHsKKyAgICAgICAgICAgICAgICB0cmFuc3BhcmVuY3kgPSBUcmFuc3BhcmVuY3kuQklUTUFTSzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlQ29tcG9uZW50cygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBwYWNrZWQgY29sb3IgbW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHNwYWNlCisgICAgICogICAgICAgICAgICB0aGUgY29sb3Igc3BhY2UuCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBjb21wb25lbnQgbWFza3MuCisgICAgICogQHBhcmFtIHJtYXNrCisgICAgICogICAgICAgICAgICB0aGUgYml0bWFzayBjb3JyZXNwb25kaW5nIHRvIHRoZSByZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gZ21hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRtYXNrIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdyZWVuIGJhbmQuCisgICAgICogQHBhcmFtIGJtYXNrCisgICAgICogICAgICAgICAgICB0aGUgYml0bWFzayBjb3JyZXNwb25kaW5nIHRvIHRoZSBibHVlIGJhbmQuCisgICAgICogQHBhcmFtIGFtYXNrCisgICAgICogICAgICAgICAgICB0aGUgYml0bWFzayBjb3JyZXNwb25kaW5nIHRvIHRoZSBhbHBoYSBiYW5kLgorICAgICAqIEBwYXJhbSBpc0FscGhhUHJlbXVsdGlwbGllZAorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgYWxwaGEgaXMgcHJlLW11bHRpcGxpZWQgaW4gdGhpcyBjb2xvciBtb2RlbC4KKyAgICAgKiBAcGFyYW0gdHJhbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc3BhcmVuY3kgc3RyYXRlZ3ksIEBzZWUgamF2YS5hd3QuVHJhbnNwYXJlbmN5LgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2ZlciB0eXBlIChwcmltaXRpdmUgamF2YSB0eXBlIHRvIHVzZSBmb3IgdGhlCisgICAgICogICAgICAgICAgICBjb21wb25lbnRzKS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgY29tYmluZWQgYml0bWFza3MgZm9yIHRoZSBjb2xvcgorICAgICAqICAgICAgICAgICAgIGJhbmRzIGlzIGxlc3MgdGhhbiBvbmUgb3IgZ3JlYXRlciB0aGFuIDMyLgorICAgICAqLworICAgIHB1YmxpYyBQYWNrZWRDb2xvck1vZGVsKENvbG9yU3BhY2Ugc3BhY2UsIGludCBiaXRzLCBpbnQgcm1hc2ssIGludCBnbWFzaywgaW50IGJtYXNrLCBpbnQgYW1hc2ssCisgICAgICAgICAgICBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkLCBpbnQgdHJhbnMsIGludCB0cmFuc2ZlclR5cGUpIHsKKworICAgICAgICBzdXBlcihiaXRzLCBjcmVhdGVCaXRzKHJtYXNrLCBnbWFzaywgYm1hc2ssIGFtYXNrKSwgc3BhY2UsIChhbWFzayA9PSAwID8gZmFsc2UgOiB0cnVlKSwKKyAgICAgICAgICAgICAgICBpc0FscGhhUHJlbXVsdGlwbGllZCwgdHJhbnMsIHZhbGlkYXRlVHJhbnNmZXJUeXBlKHRyYW5zZmVyVHlwZSkpOworCisgICAgICAgIGlmIChwaXhlbF9iaXRzIDwgMSB8fCBwaXhlbF9iaXRzID4gMzIpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzY9VGhlIGJpdHMgaXMgbGVzcyB0aGFuIDEgb3IgZ3JlYXRlciB0aGFuIDMyCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGNzLmdldFR5cGUoKSAhPSBDb2xvclNwYWNlLlRZUEVfUkdCKSB7CisgICAgICAgICAgICAvLyBhd3QuMjM5PVRoZSBzcGFjZSBpcyBub3QgYSBUWVBFX1JHQiBzcGFjZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29sb3JDb21wb25lbnRzOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChjcy5nZXRNaW5WYWx1ZShpKSAhPSAwLjBmIHx8IGNzLmdldE1heFZhbHVlKGkpICE9IDEuMGYpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjNBPVRoZSBtaW4vbWF4IG5vcm1hbGl6ZWQgY29tcG9uZW50IHZhbHVlcyBhcmUgbm90CisgICAgICAgICAgICAgICAgLy8gMC4wLzEuMAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjNBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY29tcG9uZW50TWFza3MgPSBuZXcgaW50W251bUNvbXBvbmVudHNdOworICAgICAgICBjb21wb25lbnRNYXNrc1swXSA9IHJtYXNrOworICAgICAgICBjb21wb25lbnRNYXNrc1sxXSA9IGdtYXNrOworICAgICAgICBjb21wb25lbnRNYXNrc1syXSA9IGJtYXNrOworCisgICAgICAgIGlmIChoYXNBbHBoYSkgeworICAgICAgICAgICAgY29tcG9uZW50TWFza3NbM10gPSBhbWFzazsKKyAgICAgICAgICAgIGlmICh0aGlzLmJpdHNbM10gPT0gMSkgeworICAgICAgICAgICAgICAgIHRyYW5zcGFyZW5jeSA9IFRyYW5zcGFyZW5jeS5CSVRNQVNLOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcGFyc2VDb21wb25lbnRzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldEFscGhhUmFzdGVyKFdyaXRhYmxlUmFzdGVyIHJhc3RlcikgeworICAgICAgICBpZiAoIWhhc0FscGhhKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGludCB4ID0gcmFzdGVyLmdldE1pblgoKTsKKyAgICAgICAgaW50IHkgPSByYXN0ZXIuZ2V0TWluWSgpOworICAgICAgICBpbnQgdyA9IHJhc3Rlci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgaCA9IHJhc3Rlci5nZXRIZWlnaHQoKTsKKyAgICAgICAgaW50IGJhbmRbXSA9IG5ldyBpbnRbMV07CisgICAgICAgIGJhbmRbMF0gPSByYXN0ZXIuZ2V0TnVtQmFuZHMoKSAtIDE7CisgICAgICAgIHJldHVybiByYXN0ZXIuY3JlYXRlV3JpdGFibGVDaGlsZCh4LCB5LCB3LCBoLCB4LCB5LCBiYW5kKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBQYWNrZWRDb2xvck1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFBhY2tlZENvbG9yTW9kZWwgY20gPSAoUGFja2VkQ29sb3JNb2RlbClvYmo7CisKKyAgICAgICAgcmV0dXJuIChwaXhlbF9iaXRzID09IGNtLmdldFBpeGVsU2l6ZSgpICYmIHRyYW5zZmVyVHlwZSA9PSBjbS5nZXRUcmFuc2ZlclR5cGUoKQorICAgICAgICAgICAgICAgICYmIGNzLmdldFR5cGUoKSA9PSBjbS5nZXRDb2xvclNwYWNlKCkuZ2V0VHlwZSgpICYmIGhhc0FscGhhID09IGNtLmhhc0FscGhhKCkKKyAgICAgICAgICAgICAgICAmJiBpc0FscGhhUHJlbXVsdGlwbGllZCA9PSBjbS5pc0FscGhhUHJlbXVsdGlwbGllZCgpCisgICAgICAgICAgICAgICAgJiYgdHJhbnNwYXJlbmN5ID09IGNtLmdldFRyYW5zcGFyZW5jeSgpCisgICAgICAgICAgICAgICAgJiYgbnVtQ29sb3JDb21wb25lbnRzID09IGNtLmdldE51bUNvbG9yQ29tcG9uZW50cygpCisgICAgICAgICAgICAgICAgJiYgbnVtQ29tcG9uZW50cyA9PSBjbS5nZXROdW1Db21wb25lbnRzKCkKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKGJpdHMsIGNtLmdldENvbXBvbmVudFNpemUoKSkgJiYgQXJyYXlzLmVxdWFscyhjb21wb25lbnRNYXNrcywgY20KKyAgICAgICAgICAgICAgICAuZ2V0TWFza3MoKSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcGF0aWJsZVNhbXBsZU1vZGVsKFNhbXBsZU1vZGVsIHNtKSB7CisgICAgICAgIGlmIChzbSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEoc20gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgZXNtID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpc207CisKKyAgICAgICAgcmV0dXJuICgoZXNtLmdldE51bUJhbmRzKCkgPT0gbnVtQ29tcG9uZW50cykgJiYgKGVzbS5nZXRUcmFuc2ZlclR5cGUoKSA9PSB0cmFuc2ZlclR5cGUpICYmIEFycmF5cworICAgICAgICAgICAgICAgIC5lcXVhbHMoZXNtLmdldEJpdE1hc2tzKCksIGNvbXBvbmVudE1hc2tzKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbChpbnQgdywgaW50IGgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKHRyYW5zZmVyVHlwZSwgdywgaCwgY29tcG9uZW50TWFza3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJpdG1hc2sgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGNvbG9yIGNvbXBvbmVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZGVzaXJlZCBjb2xvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXNrLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TWFzayhpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudE1hc2tzW2luZGV4XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBiaXRtYXNrcyBvZiB0aGUgY29tcG9uZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXNrcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50W10gZ2V0TWFza3MoKSB7CisgICAgICAgIHJldHVybiAoY29tcG9uZW50TWFza3MuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgYml0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sb3JNYXNrQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xvciBtYXNrIGFycmF5LgorICAgICAqIEBwYXJhbSBhbHBoYU1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbHBoYSBtYXNrLgorICAgICAqIEByZXR1cm4gdGhlIGludFtdLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludFtdIGNyZWF0ZUJpdHMoaW50IGNvbG9yTWFza0FycmF5W10sIGludCBhbHBoYU1hc2spIHsKKyAgICAgICAgaW50IGJpdHNbXTsKKyAgICAgICAgaW50IG51bUNvbXA7CisgICAgICAgIGlmIChhbHBoYU1hc2sgPT0gMCkgeworICAgICAgICAgICAgbnVtQ29tcCA9IGNvbG9yTWFza0FycmF5Lmxlbmd0aDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG51bUNvbXAgPSBjb2xvck1hc2tBcnJheS5sZW5ndGggKyAxOworICAgICAgICB9CisKKyAgICAgICAgYml0cyA9IG5ldyBpbnRbbnVtQ29tcF07CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgZm9yICg7IGkgPCBjb2xvck1hc2tBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYml0c1tpXSA9IGNvdW50Q29tcEJpdHMoY29sb3JNYXNrQXJyYXlbaV0pOworICAgICAgICAgICAgaWYgKGJpdHNbaV0gPCAwKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjIzQj1UaGUgbWFzayBvZiB0aGUgezB9IGNvbXBvbmVudCBpcyBub3QgY29udGlndW91cworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjNCIiwgaSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoaSA8IG51bUNvbXApIHsKKyAgICAgICAgICAgIGJpdHNbaV0gPSBjb3VudENvbXBCaXRzKGFscGhhTWFzayk7CisKKyAgICAgICAgICAgIGlmIChiaXRzW2ldIDwgMCkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4yM0M9VGhlIG1hc2sgb2YgdGhlIGFscGhhIGNvbXBvbmVudCBpcyBub3QgY29udGlndW91cworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYml0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBiaXRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBybWFzaworICAgICAqICAgICAgICAgICAgdGhlIHJtYXNrLgorICAgICAqIEBwYXJhbSBnbWFzaworICAgICAqICAgICAgICAgICAgdGhlIGdtYXNrLgorICAgICAqIEBwYXJhbSBibWFzaworICAgICAqICAgICAgICAgICAgdGhlIGJtYXNrLgorICAgICAqIEBwYXJhbSBhbWFzaworICAgICAqICAgICAgICAgICAgdGhlIGFtYXNrLgorICAgICAqIEByZXR1cm4gdGhlIGludFtdLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludFtdIGNyZWF0ZUJpdHMoaW50IHJtYXNrLCBpbnQgZ21hc2ssIGludCBibWFzaywgaW50IGFtYXNrKSB7CisKKyAgICAgICAgaW50IG51bUNvbXA7CisgICAgICAgIGlmIChhbWFzayA9PSAwKSB7CisgICAgICAgICAgICBudW1Db21wID0gMzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG51bUNvbXAgPSA0OworICAgICAgICB9CisgICAgICAgIGludCBiaXRzW10gPSBuZXcgaW50W251bUNvbXBdOworCisgICAgICAgIGJpdHNbMF0gPSBjb3VudENvbXBCaXRzKHJtYXNrKTsKKyAgICAgICAgaWYgKGJpdHNbMF0gPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjNEPVRoZSBtYXNrIG9mIHRoZSByZWQgY29tcG9uZW50IGlzIG5vdCBjb250aWd1b3VzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzRCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgYml0c1sxXSA9IGNvdW50Q29tcEJpdHMoZ21hc2spOworICAgICAgICBpZiAoYml0c1sxXSA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yM0U9VGhlIG1hc2sgb2YgdGhlIGdyZWVuIGNvbXBvbmVudCBpcyBub3QgY29udGlndW91cworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yM0UiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGJpdHNbMl0gPSBjb3VudENvbXBCaXRzKGJtYXNrKTsKKyAgICAgICAgaWYgKGJpdHNbMl0gPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjNGPVRoZSBtYXNrIG9mIHRoZSBibHVlIGNvbXBvbmVudCBpcyBub3QgY29udGlndW91cworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yM0YiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhbWFzayAhPSAwKSB7CisgICAgICAgICAgICBiaXRzWzNdID0gY291bnRDb21wQml0cyhhbWFzayk7CisgICAgICAgICAgICBpZiAoYml0c1szXSA8IDApIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjNDPVRoZSBtYXNrIG9mIHRoZSBhbHBoYSBjb21wb25lbnQgaXMgbm90IGNvbnRpZ3VvdXMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJpdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ291bnQgY29tcCBiaXRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb21wTWFzaworICAgICAqICAgICAgICAgICAgdGhlIGNvbXAgbWFzay4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50Q29tcEJpdHMoaW50IGNvbXBNYXNrKSB7CisgICAgICAgIGludCBiaXRzID0gMDsKKyAgICAgICAgaWYgKGNvbXBNYXNrICE9IDApIHsKKyAgICAgICAgICAgIC8vIERlbGV0aW5nIGZpbmFsIHplcm9zCisgICAgICAgICAgICB3aGlsZSAoKGNvbXBNYXNrICYgMSkgPT0gMCkgeworICAgICAgICAgICAgICAgIGNvbXBNYXNrID4+Pj0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIENvdW50aW5nIGNvbXBvbmVudCBiaXRzCisgICAgICAgICAgICB3aGlsZSAoKGNvbXBNYXNrICYgMSkgPT0gMSkgeworICAgICAgICAgICAgICAgIGNvbXBNYXNrID4+Pj0gMTsKKyAgICAgICAgICAgICAgICBiaXRzKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29tcE1hc2sgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJpdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmFsaWRhdGUgdHJhbnNmZXIgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHJhbnNmZXJUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmZXIgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHZhbGlkYXRlVHJhbnNmZXJUeXBlKGludCB0cmFuc2ZlclR5cGUpIHsKKyAgICAgICAgaWYgKHRyYW5zZmVyVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJiB0cmFuc2ZlclR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVAorICAgICAgICAgICAgICAgICYmIHRyYW5zZmVyVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UKSB7CisgICAgICAgICAgICAvLyBhd3QuMjQwPVRoZSB0cmFuc2ZlclR5cGUgbm90IGlzIG9uZSBvZiBEYXRhQnVmZmVyLlRZUEVfQllURSwKKyAgICAgICAgICAgIC8vIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQgb3IgRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNDAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJhbnNmZXJUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VDb21wb25lbnRzKCkgeworICAgICAgICBvZmZzZXRzID0gbmV3IGludFtudW1Db21wb25lbnRzXTsKKyAgICAgICAgc2NhbGVzID0gbmV3IGZsb2F0W251bUNvbXBvbmVudHNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbXBvbmVudHM7IGkrKykgeworICAgICAgICAgICAgaW50IG9mZiA9IDA7CisgICAgICAgICAgICBpbnQgbWFzayA9IGNvbXBvbmVudE1hc2tzW2ldOworICAgICAgICAgICAgd2hpbGUgKChtYXNrICYgMSkgPT0gMCkgeworICAgICAgICAgICAgICAgIG1hc2sgPj4+PSAxOworICAgICAgICAgICAgICAgIG9mZisrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0c1tpXSA9IG9mZjsKKyAgICAgICAgICAgIGlmIChiaXRzW2ldID09IDApIHsKKyAgICAgICAgICAgICAgICBzY2FsZXNbaV0gPSAyNTYuMGY7IC8vIE1heSBiZSBhbnkgdmFsdWUgZGlmZmVyZW50IGZyb20gemVybywKKyAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHdpbGwgZGl2aWRpbmcgYnkgemVybworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzY2FsZXNbaV0gPSAyNTUuMGYgLyBtYXhWYWx1ZXNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1BpeGVsR3JhYmJlci5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL1BpeGVsR3JhYmJlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlY2Q1YzgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUGl4ZWxHcmFiYmVyLmphdmEKQEAgLTAsMCArMSw0MDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworcHVibGljIGNsYXNzIFBpeGVsR3JhYmJlciBpbXBsZW1lbnRzIEltYWdlQ29uc3VtZXIgeworCisgICAgaW50IHdpZHRoOworICAgIGludCBoZWlnaHQ7CisgICAgaW50IFg7CisgICAgaW50IFk7CisgICAgaW50IG9mZnNldDsKKyAgICBpbnQgc2NhbmxpbmU7CisgICAgSW1hZ2VQcm9kdWNlciBwcm9kdWNlcjsKKworICAgIGJ5dGUgYkRhdGFbXTsKKyAgICBpbnQgaURhdGFbXTsKKyAgICBDb2xvck1vZGVsIGNtOworCisgICAgcHJpdmF0ZSBpbnQgZ3JhYmJlclN0YXR1czsKKyAgICBwcml2YXRlIGludCBkYXRhVHlwZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNHcmFiYmluZzsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNSR0I7CisKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBEQVRBX1RZUEVfQllURSA9IDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERBVEFfVFlQRV9JTlQgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBEQVRBX1RZUEVfVU5ERUZJTkVEID0gMjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBTExfQklUUyA9IChJbWFnZU9ic2VydmVyLkZSQU1FQklUUyB8CisgICAgICAgICAgICBJbWFnZU9ic2VydmVyLkFMTEJJVFMpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSQUJCSU5HX1NUT1AgPSBBTExfQklUUyB8IEltYWdlT2JzZXJ2ZXIuRVJST1I7CisKKworCisgICAgcHVibGljIFBpeGVsR3JhYmJlcihJbWFnZVByb2R1Y2VyIGlwLCBpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50W10gcGl4LAorICAgICAgICAgICAgaW50IG9mZiwgaW50IHNjYW5zaXplKSB7CisgICAgICAgIGluaXRpYWxpemUoaXAsIHgsIHksIHcsIGgsIHBpeCwgb2ZmLCBzY2Fuc2l6ZSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIFBpeGVsR3JhYmJlcihJbWFnZSBpbWcsIGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnRbXSBwaXgsCisgICAgICAgICAgICBpbnQgb2ZmLCBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgaW5pdGlhbGl6ZShpbWcuZ2V0U291cmNlKCksIHgsIHksIHcsIGgsIHBpeCwgb2ZmLCBzY2Fuc2l6ZSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIFBpeGVsR3JhYmJlcihJbWFnZSBpbWcsIGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBib29sZWFuIGZvcmNlUkdCKSB7CisgICAgICAgIGluaXRpYWxpemUoaW1nLmdldFNvdXJjZSgpLCB4LCB5LCB3LCBoLCBudWxsLCAwLCAwLCBmb3JjZVJHQik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydGllcyhIYXNodGFibGU8PywgPz4gcHJvcHMpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGdldFBpeGVscygpIHsKKyAgICAgICAgc3dpdGNoKGRhdGFUeXBlKXsKKyAgICAgICAgY2FzZSBEQVRBX1RZUEVfQllURToKKyAgICAgICAgICAgIHJldHVybiBiRGF0YTsKKyAgICAgICAgY2FzZSBEQVRBX1RZUEVfSU5UOgorICAgICAgICAgICAgcmV0dXJuIGlEYXRhOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2xvck1vZGVsKENvbG9yTW9kZWwgbW9kZWwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgc3JjWCwgaW50IHNyY1ksIGludCBzcmNXLCBpbnQgc3JjSCwKKyAgICAgICAgICAgIENvbG9yTW9kZWwgbW9kZWwsIGJ5dGVbXSBwaXhlbHMsIGludCBzcmNPZmYsIGludCBzcmNTY2FuKSB7CisgICAgICAgIGlmKHNyY1kgPCBZKXsKKyAgICAgICAgICAgIGludCBkZWx0YSA9IFkgLSBzcmNZOworICAgICAgICAgICAgaWYoZGVsdGEgPj0gaGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3JjWSArPSBkZWx0YTsKKyAgICAgICAgICAgIHNyY0ggLT0gZGVsdGE7CisgICAgICAgICAgICBzcmNPZmYgKz0gc3JjU2NhbiAqIGRlbHRhOworICAgICAgICB9CisKKyAgICAgICAgaWYoc3JjWSArIHNyY0ggPiBZICsgaGVpZ2h0KXsKKyAgICAgICAgICAgIHNyY0ggPSBZICsgaGVpZ2h0IC0gc3JjWTsKKyAgICAgICAgICAgIGlmKHNyY0ggPD0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmKHNyY1ggPCBYKXsKKyAgICAgICAgICAgIGludCBkZWx0YSA9IFggLSBzcmNYOworICAgICAgICAgICAgaWYoZGVsdGEgPj0gd2lkdGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzcmNXIC09IGRlbHRhOworICAgICAgICAgICAgc3JjWCArPSBkZWx0YTsKKyAgICAgICAgICAgIHNyY09mZiArPSBkZWx0YTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKHNyY1ggKyBzcmNXID4gWCArIHdpZHRoKXsKKyAgICAgICAgICAgIHNyY1cgPSBYICsgd2lkdGggLSBzcmNYOworICAgICAgICAgICAgaWYoc3JjVyA8PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmKHNjYW5saW5lID09IDApIHsKKyAgICAgICAgICAgIHNjYW5saW5lID0gd2lkdGg7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlYWxPZmYgPSBvZmZzZXQgKyAoc3JjWSAtIFkpICogc2NhbmxpbmUgKyAoc3JjWCAtIFgpOworICAgICAgICBzd2l0Y2goZGF0YVR5cGUpeworICAgICAgICBjYXNlIERBVEFfVFlQRV9VTkRFRklORUQ6CisgICAgICAgICAgICBjbSA9IG1vZGVsOworICAgICAgICAgICAgaWYobW9kZWwgIT0gQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCkpeworICAgICAgICAgICAgICAgIGJEYXRhID0gbmV3IGJ5dGVbd2lkdGggKiBoZWlnaHRdOworICAgICAgICAgICAgICAgIGlzUkdCID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZGF0YVR5cGUgPSBEQVRBX1RZUEVfQllURTsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIGlEYXRhID0gbmV3IGludFt3aWR0aCAqIGhlaWdodF07CisgICAgICAgICAgICAgICAgaXNSR0IgPSB0cnVlOworICAgICAgICAgICAgICAgIGRhdGFUeXBlID0gREFUQV9UWVBFX0lOVDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgY2FzZSBEQVRBX1RZUEVfQllURToKKyAgICAgICAgICAgIGlmKCFpc1JHQiAmJiBjbSA9PSBtb2RlbCl7CisgICAgICAgICAgICAgICAgZm9yKGludCB5ID0gMDsgeSA8IHNyY0g7IHkrKyl7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGl4ZWxzLCBzcmNPZmYsIGJEYXRhLCByZWFsT2ZmLCBzcmNXKTsKKyAgICAgICAgICAgICAgICAgICAgc3JjT2ZmICs9IHNyY1NjYW47CisgICAgICAgICAgICAgICAgICAgIHJlYWxPZmYgKz0gc2NhbmxpbmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yY2VUb1JHQigpOworICAgICAgICBjYXNlIERBVEFfVFlQRV9JTlQ6CisgICAgICAgICAgICBmb3IoaW50IHkgPSAwOyB5IDwgc3JjSDsgeSsrKXsKKyAgICAgICAgICAgICAgICBmb3IoaW50IHggPSAwOyB4IDwgc3JjVzsgeCsrKXsKKyAgICAgICAgICAgICAgICAgICAgaURhdGFbcmVhbE9mZiArIHhdID0gY20uZ2V0UkdCKHBpeGVsc1tzcmNPZmYgKyB4XSAmIDB4ZmYpOyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNyY09mZiArPSBzcmNTY2FuOworICAgICAgICAgICAgICAgIHJlYWxPZmYgKz0gc2NhbmxpbmU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCBzcmNYLCBpbnQgc3JjWSwgaW50IHNyY1csIGludCBzcmNILAorICAgICAgICAgICAgQ29sb3JNb2RlbCBtb2RlbCwgaW50W10gcGl4ZWxzLCBpbnQgc3JjT2ZmLCBpbnQgc3JjU2NhbikgeworCisgICAgICAgIGlmKHNyY1kgPCBZKXsKKyAgICAgICAgICAgIGludCBkZWx0YSA9IFkgLSBzcmNZOworICAgICAgICAgICAgaWYoZGVsdGEgPj0gaGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3JjWSArPSBkZWx0YTsKKyAgICAgICAgICAgIHNyY0ggLT0gZGVsdGE7CisgICAgICAgICAgICBzcmNPZmYgKz0gc3JjU2NhbiAqIGRlbHRhOworICAgICAgICB9CisKKyAgICAgICAgaWYoc3JjWSArIHNyY0ggPiBZICsgaGVpZ2h0KXsKKyAgICAgICAgICAgIHNyY0ggPSBZICsgaGVpZ2h0IC0gc3JjWTsKKyAgICAgICAgICAgIGlmKHNyY0ggPD0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmKHNyY1ggPCBYKXsKKyAgICAgICAgICAgIGludCBkZWx0YSA9IFggLSBzcmNYOworICAgICAgICAgICAgaWYoZGVsdGEgPj0gd2lkdGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzcmNXIC09IGRlbHRhOworICAgICAgICAgICAgc3JjWCArPSBkZWx0YTsKKyAgICAgICAgICAgIHNyY09mZiArPSBkZWx0YTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKHNyY1ggKyBzcmNXID4gWCArIHdpZHRoKXsKKyAgICAgICAgICAgIHNyY1cgPSBYICsgd2lkdGggLSBzcmNYOworICAgICAgICAgICAgaWYoc3JjVyA8PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmKHNjYW5saW5lID09IDApIHsKKyAgICAgICAgICAgIHNjYW5saW5lID0gd2lkdGg7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlYWxPZmYgPSBvZmZzZXQgKyAoc3JjWSAtIFkpICogc2NhbmxpbmUgKyAoc3JjWCAtIFgpOworCisgICAgICAgIGludCBtYXNrID0gMHhGRjsKKworICAgICAgICBzd2l0Y2goZGF0YVR5cGUpeworICAgICAgICBjYXNlIERBVEFfVFlQRV9VTkRFRklORUQ6CisgICAgICAgICAgICBjbSA9IG1vZGVsOworICAgICAgICAgICAgaURhdGEgPSBuZXcgaW50W3dpZHRoICogaGVpZ2h0XTsKKyAgICAgICAgICAgIGRhdGFUeXBlID0gREFUQV9UWVBFX0lOVDsKKyAgICAgICAgICAgIGlzUkdCID0gKGNtID09IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpKTsKKworICAgICAgICBjYXNlIERBVEFfVFlQRV9JTlQ6CisgICAgICAgICAgICBpZihjbSA9PSBtb2RlbCl7CisgICAgICAgICAgICAgICAgZm9yKGludCB5ID0gMDsgeSA8IHNyY0g7IHkrKyl7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGl4ZWxzLCBzcmNPZmYsIGlEYXRhLCByZWFsT2ZmLCBzcmNXKTsKKyAgICAgICAgICAgICAgICAgICAgc3JjT2ZmICs9IHNyY1NjYW47CisgICAgICAgICAgICAgICAgICAgIHJlYWxPZmYgKz0gc2NhbmxpbmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWFzayA9IDB4RkZGRkZGRkY7CisKKyAgICAgICAgY2FzZSBEQVRBX1RZUEVfQllURToKKyAgICAgICAgICAgIGZvcmNlVG9SR0IoKTsKKyAgICAgICAgICAgIGZvcihpbnQgeSA9IDA7IHkgPCBzcmNIOyB5KyspeworICAgICAgICAgICAgICAgIGZvcihpbnQgeCA9IDA7IHggPCBzcmNXOyB4KyspeworICAgICAgICAgICAgICAgICAgICBpRGF0YVtyZWFsT2ZmK3hdID0gY20uZ2V0UkdCKHBpeGVsc1tzcmNPZmYreF0gJiBtYXNrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3JjT2ZmICs9IHNyY1NjYW47CisgICAgICAgICAgICAgICAgcmVhbE9mZiArPSBzY2FubGluZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICByZXR1cm4gY207CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdyYWJQaXhlbHMobG9uZyBtcykgCisgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYoKGdyYWJiZXJTdGF0dXMgJiBHUkFCQklOR19TVE9QKSAhPSAwKXsKKyAgICAgICAgICAgIHJldHVybiAoKGdyYWJiZXJTdGF0dXMgJiBBTExfQklUUykgIT0gMCk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgaWYoIWlzR3JhYmJpbmcpeworICAgICAgICAgICAgaXNHcmFiYmluZyA9IHRydWU7CisgICAgICAgICAgICBncmFiYmVyU3RhdHVzICY9IH5JbWFnZU9ic2VydmVyLkFCT1JUOworICAgICAgICAgICAgcHJvZHVjZXIuc3RhcnRQcm9kdWN0aW9uKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHdoaWxlKChncmFiYmVyU3RhdHVzICYgR1JBQkJJTkdfU1RPUCkgPT0gMCl7CisgICAgICAgICAgICBpZihtcyAhPSAwKXsKKyAgICAgICAgICAgICAgICBtcyA9IHN0YXJ0ICsgbXMgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgICAgICBpZihtcyA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdhaXQobXMpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuICgoZ3JhYmJlclN0YXR1cyAmIEFMTF9CSVRTKSAhPSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREaW1lbnNpb25zKGludCB3LCBpbnQgaCkgeworICAgICAgICBpZih3aWR0aCA8IDApIHsKKyAgICAgICAgICAgIHdpZHRoID0gdyAtIFg7CisgICAgICAgIH0KKyAgICAgICAgaWYoaGVpZ2h0IDwgMCkgeworICAgICAgICAgICAgaGVpZ2h0ID0gaCAtIFk7CisgICAgICAgIH0KKworICAgICAgICBncmFiYmVyU3RhdHVzIHw9IEltYWdlT2JzZXJ2ZXIuV0lEVEggfCBJbWFnZU9ic2VydmVyLkhFSUdIVDsKKworICAgICAgICBpZih3aWR0aCA8PTAgfHwgaGVpZ2h0IDw9MCl7CisgICAgICAgICAgICBpbWFnZUNvbXBsZXRlKFNUQVRJQ0lNQUdFRE9ORSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZihpc1JHQiAmJiBkYXRhVHlwZSA9PSBEQVRBX1RZUEVfVU5ERUZJTkVEKXsKKyAgICAgICAgICAgIGlEYXRhID0gbmV3IGludFt3aWR0aCAqIGhlaWdodF07CisgICAgICAgICAgICBkYXRhVHlwZSA9IERBVEFfVFlQRV9JTlQ7CisgICAgICAgICAgICBzY2FubGluZSA9IHdpZHRoOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SGludHMoaW50IGhpbnRzKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgaW1hZ2VDb21wbGV0ZShpbnQgc3RhdHVzKSB7CisgICAgICAgIHN3aXRjaChzdGF0dXMpeworICAgICAgICBjYXNlIElNQUdFQUJPUlRFRDoKKyAgICAgICAgICAgIGdyYWJiZXJTdGF0dXMgfD0gSW1hZ2VPYnNlcnZlci5BQk9SVDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIElNQUdFRVJST1I6CisgICAgICAgICAgICBncmFiYmVyU3RhdHVzIHw9IEltYWdlT2JzZXJ2ZXIuRVJST1IgfCBJbWFnZU9ic2VydmVyLkFCT1JUOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU0lOR0xFRlJBTUVET05FOgorICAgICAgICAgICAgZ3JhYmJlclN0YXR1cyB8PSBJbWFnZU9ic2VydmVyLkZSQU1FQklUUzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNUQVRJQ0lNQUdFRE9ORToKKyAgICAgICAgICAgIGdyYWJiZXJTdGF0dXMgfD0gSW1hZ2VPYnNlcnZlci5BTExCSVRTOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAvLyBhd3QuMjZBPUluY29ycmVjdCBJbWFnZUNvbnN1bWVyIGNvbXBsZXRpb24gc3RhdHVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2QSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlzR3JhYmJpbmcgPSBmYWxzZTsKKyAgICAgICAgcHJvZHVjZXIucmVtb3ZlQ29uc3VtZXIodGhpcyk7CisgICAgICAgIG5vdGlmeUFsbCgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdyYWJQaXhlbHMoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ3JhYlBpeGVscygwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3RhcnRHcmFiYmluZygpIHsKKyAgICAgICAgaWYoKGdyYWJiZXJTdGF0dXMgJiBHUkFCQklOR19TVE9QKSAhPSAwKXsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZighaXNHcmFiYmluZyl7CisgICAgICAgICAgICBpc0dyYWJiaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIGdyYWJiZXJTdGF0dXMgJj0gfkltYWdlT2JzZXJ2ZXIuQUJPUlQ7CisgICAgICAgICAgICBwcm9kdWNlci5zdGFydFByb2R1Y3Rpb24odGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWJvcnRHcmFiYmluZygpIHsKKyAgICAgICAgaW1hZ2VDb21wbGV0ZShJTUFHRUFCT1JURUQpOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHN0YXR1cygpIHsKKyAgICAgICAgcmV0dXJuIGdyYWJiZXJTdGF0dXM7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0V2lkdGgoKSB7CisgICAgICAgIGlmKHdpZHRoIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRTdGF0dXMoKSB7CisgICAgICAgIHJldHVybiBncmFiYmVyU3RhdHVzOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldEhlaWdodCgpIHsKKyAgICAgICAgaWYoaGVpZ2h0IDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemUoSW1hZ2VQcm9kdWNlciBpcCwgaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsCisgICAgICAgICAgICBpbnQgcGl4ZWxzW10sIGludCBvZmYsIGludCBzY2Fuc2l6ZSwgYm9vbGVhbiBmb3JjZVJHQil7CisKKyAgICAgICAgcHJvZHVjZXIgPSBpcDsKKyAgICAgICAgWCA9IHg7CisgICAgICAgIFkgPSB5OworICAgICAgICB3aWR0aCA9IHc7CisgICAgICAgIGhlaWdodCA9IGg7CisgICAgICAgIGlEYXRhID0gcGl4ZWxzOworICAgICAgICBkYXRhVHlwZSA9IChwaXhlbHMgPT0gbnVsbCkgPyBEQVRBX1RZUEVfVU5ERUZJTkVEIDogREFUQV9UWVBFX0lOVDsKKyAgICAgICAgb2Zmc2V0ID0gb2ZmOworICAgICAgICBzY2FubGluZSA9IHNjYW5zaXplOworICAgICAgICBpZihmb3JjZVJHQil7CisgICAgICAgICAgICBjbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICAgICAgaXNSR0IgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9yY2UgcGl4ZWxzIHRvIElOVCBSR0IgbW9kZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmb3JjZVRvUkdCKCl7CisgICAgICAgIGlmIChpc1JHQikKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAKKyAgICAgICAgc3dpdGNoKGRhdGFUeXBlKXsKKyAgICAgICAgY2FzZSBEQVRBX1RZUEVfQllURToKKyAgICAgICAgICAgIGlEYXRhID0gbmV3IGludFt3aWR0aCAqIGhlaWdodF07CisgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgaURhdGEubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgICAgIGlEYXRhW2ldID0gY20uZ2V0UkdCKGJEYXRhW2ldICYgMHhmZik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkYXRhVHlwZSA9IERBVEFfVFlQRV9JTlQ7CisgICAgICAgICAgICBiRGF0YSA9IG51bGw7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIERBVEFfVFlQRV9JTlQ6CisgICAgICAgICAgICBpbnQgYnVmZltdID0gbmV3IGludFt3aWR0aCAqIGhlaWdodF07CisgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgaURhdGEubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgICAgIGJ1ZmZbaV0gPSBjbS5nZXRSR0IoaURhdGFbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaURhdGEgPSBidWZmOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgc2NhbmxpbmUgPSB3aWR0aDsKKyAgICAgICAgY20gPSBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKTsKKyAgICAgICAgaXNSR0IgPSB0cnVlOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1BpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL1BpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlNjQ2ZjgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCBjbGFzcyByZXByZXNlbnRzIGltYWdlIGRhdGEgYXMgcmVwcmVzZW50ZWQgYXMKKyAqIGludGVybGVhdmVkIHBpeGVscyBhbmQgZm9yIHdoaWNoIGVhY2ggc2FtcGxlIG9mIGEgcGl4ZWwgdGFrZXMgb25lIGRhdGEKKyAqIGVsZW1lbnQgb2YgdGhlIERhdGFCdWZmZXIuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsIGV4dGVuZHMgQ29tcG9uZW50U2FtcGxlTW9kZWwgeworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiB0aGUgc2FtcGxlcy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBwaXhlbFN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIHN0cmlkZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gc2NhbmxpbmVTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUgb2YgdGhlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHRoZSBiYW5kIG9mZnNldHMuCisgICAgICovCisgICAgcHVibGljIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbChpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IHBpeGVsU3RyaWRlLAorICAgICAgICAgICAgaW50IHNjYW5saW5lU3RyaWRlLCBpbnQgYmFuZE9mZnNldHNbXSkgeworCisgICAgICAgIHN1cGVyKGRhdGFUeXBlLCB3LCBoLCBwaXhlbFN0cmlkZSwgc2NhbmxpbmVTdHJpZGUsIGJhbmRPZmZzZXRzKTsKKworICAgICAgICBpbnQgbWF4T2Zmc2V0ID0gYmFuZE9mZnNldHNbMF07CisgICAgICAgIGludCBtaW5PZmZzZXQgPSBiYW5kT2Zmc2V0c1swXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBiYW5kT2Zmc2V0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGJhbmRPZmZzZXRzW2ldID4gbWF4T2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgbWF4T2Zmc2V0ID0gYmFuZE9mZnNldHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYmFuZE9mZnNldHNbaV0gPCBtaW5PZmZzZXQpIHsKKyAgICAgICAgICAgICAgICBtaW5PZmZzZXQgPSBiYW5kT2Zmc2V0c1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIG1heE9mZnNldCAtPSBtaW5PZmZzZXQ7CisKKyAgICAgICAgaWYgKG1heE9mZnNldCA+IHNjYW5saW5lU3RyaWRlKSB7CisgICAgICAgICAgICAvLyBhd3QuMjQxPUFueSBvZmZzZXQgYmV0d2VlbiBiYW5kcyBpcyBncmVhdGVyIHRoYW4gdGhlIFNjYW5saW5lCisgICAgICAgICAgICAvLyBzdHJpZGUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjQxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobWF4T2Zmc2V0ID4gcGl4ZWxTdHJpZGUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNDI9UGl4ZWwgc3RyaWRlIGlzIGxlc3MgdGhhbiBhbnkgb2Zmc2V0IGJldHdlZW4gYmFuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjQyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAocGl4ZWxTdHJpZGUgKiB3ID4gc2NhbmxpbmVTdHJpZGUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNDM9UHJvZHVjdCBvZiBQaXhlbCBzdHJpZGUgYW5kIHcgaXMgZ3JlYXRlciB0aGFuIFNjYW5saW5lCisgICAgICAgICAgICAvLyBzdHJpZGUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBjcmVhdGVTdWJzZXRTYW1wbGVNb2RlbChpbnQgYmFuZHNbXSkgeworICAgICAgICBpbnQgbmV3T2Zmc2V0c1tdID0gbmV3IGludFtiYW5kcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhbmRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBuZXdPZmZzZXRzW2ldID0gYmFuZE9mZnNldHNbYmFuZHNbaV1dOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwoZGF0YVR5cGUsIHdpZHRoLCBoZWlnaHQsIHBpeGVsU3RyaWRlLAorICAgICAgICAgICAgICAgIHNjYW5saW5lU3RyaWRlLCBuZXdPZmZzZXRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgY3JlYXRlQ29tcGF0aWJsZVNhbXBsZU1vZGVsKGludCB3LCBpbnQgaCkgeworICAgICAgICBpbnQgbmV3T2Zmc2V0c1tdOworICAgICAgICBpbnQgbWluT2Zmc2V0ID0gYmFuZE9mZnNldHNbMF07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYmFuZE9mZnNldHNbaV0gPCBtaW5PZmZzZXQpIHsKKyAgICAgICAgICAgICAgICBtaW5PZmZzZXQgPSBiYW5kT2Zmc2V0c1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChtaW5PZmZzZXQgPiAwKSB7CisgICAgICAgICAgICBuZXdPZmZzZXRzID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBuZXdPZmZzZXRzW2ldID0gYmFuZE9mZnNldHNbaV0gLSBtaW5PZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuZXdPZmZzZXRzID0gYmFuZE9mZnNldHM7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwgcGl4ZWxTdHJpZGUsIHBpeGVsU3RyaWRlICogdywKKyAgICAgICAgICAgICAgICBuZXdPZmZzZXRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIGludCB0bXAgPSBoYXNoID4+PiA4OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKworICAgICAgICByZXR1cm4gaGFzaCBeIDB4NjY7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvUkdCSW1hZ2VGaWx0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SR0JJbWFnZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1ZmU1ZDkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUkdCSW1hZ2VGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDE5NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKKy8qKgorICogVGhlIFJHQkltYWdlRmlsdGVyIGNsYXNzIHJlcHJlc2VudHMgYSBmaWx0ZXIgd2hpY2ggbW9kaWZpZXMgcGl4ZWxzIG9mIGFuCisgKiBpbWFnZSBpbiB0aGUgZGVmYXVsdCBSR0IgQ29sb3JNb2RlbC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBSR0JJbWFnZUZpbHRlciBleHRlbmRzIEltYWdlRmlsdGVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBvcmlnaW5hbCBtb2RlbCBpcyB0aGUgQ29sb3JNb2RlbCB0byBiZSByZXBsYWNlZCBieSB0aGUgbmV3IG1vZGVsIHdoZW4KKyAgICAgKiBzdWJzdGl0dXRlQ29sb3JNb2RlbCBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbG9yTW9kZWwgb3JpZ21vZGVsOworCisgICAgLyoqCisgICAgICogVGhlIG5ldyBtb2RlbCBpcyB0aGUgQ29sb3JNb2RlbCB3aXRoIHdoaWNoIHRvIHJlcGxhY2UgdGhlIG9yaWdpbmFsIG1vZGVsCisgICAgICogd2hlbiBzdWJzdGl0dXRlQ29sb3JNb2RlbCBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbG9yTW9kZWwgbmV3bW9kZWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2FuRmlsdGVySW5kZXhDb2xvck1vZGVsIGluZGljYXRlcyBpZiBpdCBpcyBhY2NlcHRhYmxlIHRvIGFwcGx5IHRoZQorICAgICAqIGNvbG9yIGZpbHRlcmluZyBvZiB0aGUgZmlsdGVyUkdCIG1ldGhvZCB0byB0aGUgY29sb3IgdGFibGUgZW50cmllcyBvZiBhbgorICAgICAqIEluZGV4Q29sb3JNb2RlbCBvYmplY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gY2FuRmlsdGVySW5kZXhDb2xvck1vZGVsOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFJHQkltYWdlRmlsdGVyLgorICAgICAqLworICAgIHB1YmxpYyBSR0JJbWFnZUZpbHRlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXJzIGFuIEluZGV4Q29sb3JNb2RlbCBvYmplY3QgYnkgY2FsbGluZyBmaWx0ZXJSR0IgZnVuY3Rpb24gZm9yIGVhY2gKKyAgICAgKiBlbnRyeSBvZiBJbmRleENvbG9yTW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGljbQorICAgICAqICAgICAgICAgICAgdGhlIEluZGV4Q29sb3JNb2RlbCB0byBiZSBmaWx0ZXJlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbmRleENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIEluZGV4Q29sb3JNb2RlbCBmaWx0ZXJJbmRleENvbG9yTW9kZWwoSW5kZXhDb2xvck1vZGVsIGljbSkgeworICAgICAgICBpbnQgdHJhbnNmZXJUeXBlID0gaWNtLmdldFRyYW5zZmVyVHlwZSgpOworICAgICAgICBpbnQgYml0cyA9IGljbS5nZXRQaXhlbFNpemUoKTsKKyAgICAgICAgaW50IG1hcFNpemUgPSBpY20uZ2V0TWFwU2l6ZSgpOworICAgICAgICBpbnQgY29sb3JNYXBbXSA9IG5ldyBpbnRbbWFwU2l6ZV07CisgICAgICAgIGludCBmaWx0ZXJlZENvbG9yTWFwW10gPSBuZXcgaW50W21hcFNpemVdOworICAgICAgICBpY20uZ2V0UkdCcyhjb2xvck1hcCk7CisgICAgICAgIGludCB0cmFucyA9IC0xOworICAgICAgICBib29sZWFuIGhhc0FscGhhID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBmaWx0ZXJlZENvbG9yTWFwW2ldID0gZmlsdGVyUkdCKC0xLCAtMSwgY29sb3JNYXBbaV0pOworICAgICAgICAgICAgaW50IGFscGhhID0gZmlsdGVyZWRDb2xvck1hcFtpXSA+Pj4gMjQ7CisgICAgICAgICAgICBpZiAoYWxwaGEgIT0gMHhmZikgeworICAgICAgICAgICAgICAgIGlmICghaGFzQWxwaGEpIHsKKyAgICAgICAgICAgICAgICAgICAgaGFzQWxwaGEgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYWxwaGEgPT0gMCAmJiB0cmFucyA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgSW5kZXhDb2xvck1vZGVsKGJpdHMsIG1hcFNpemUsIGZpbHRlcmVkQ29sb3JNYXAsIDAsIGhhc0FscGhhLCB0cmFucywKKyAgICAgICAgICAgICAgICB0cmFuc2ZlclR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBvcmlnaW5hbCBjb2xvciBtb2RlbCBhbmQgdGhlIG5ldyBvbmUuCisgICAgICogCisgICAgICogQHBhcmFtIG9sZGNtCisgICAgICogICAgICAgICAgICB0aGUgb2xkIENvbG9yTW9kZWwuCisgICAgICogQHBhcmFtIG5ld2NtCisgICAgICogICAgICAgICAgICB0aGUgbmV3IENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3Vic3RpdHV0ZUNvbG9yTW9kZWwoQ29sb3JNb2RlbCBvbGRjbSwgQ29sb3JNb2RlbCBuZXdjbSkgeworICAgICAgICBvcmlnbW9kZWwgPSBvbGRjbTsKKyAgICAgICAgbmV3bW9kZWwgPSBuZXdjbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2xvck1vZGVsKENvbG9yTW9kZWwgbW9kZWwpIHsKKyAgICAgICAgaWYgKG1vZGVsIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsICYmIGNhbkZpbHRlckluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgSW5kZXhDb2xvck1vZGVsIGljbSA9IChJbmRleENvbG9yTW9kZWwpbW9kZWw7CisgICAgICAgICAgICBDb2xvck1vZGVsIGZpbHRlcmVkTW9kZWwgPSBmaWx0ZXJJbmRleENvbG9yTW9kZWwoaWNtKTsKKyAgICAgICAgICAgIHN1YnN0aXR1dGVDb2xvck1vZGVsKG1vZGVsLCBmaWx0ZXJlZE1vZGVsKTsKKyAgICAgICAgICAgIGNvbnN1bWVyLnNldENvbG9yTW9kZWwoZmlsdGVyZWRNb2RlbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb25zdW1lci5zZXRDb2xvck1vZGVsKENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgaW50W10gcGl4ZWxzLCBpbnQgb2ZmLAorICAgICAgICAgICAgaW50IHNjYW5zaXplKSB7CisKKyAgICAgICAgaWYgKG1vZGVsID09IG51bGwgfHwgbW9kZWwgPT0gb3JpZ21vZGVsKSB7CisgICAgICAgICAgICBjb25zdW1lci5zZXRQaXhlbHMoeCwgeSwgdywgaCwgbmV3bW9kZWwsIHBpeGVscywgb2ZmLCBzY2Fuc2l6ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgcmdiUGl4ZWxzW10gPSBuZXcgaW50W3ddOworICAgICAgICAgICAgZm9yIChpbnQgc3kgPSB5LCBwaXhlbHNPZmYgPSBvZmY7IHN5IDwgeSArIGg7IHN5KyssIHBpeGVsc09mZiArPSBzY2Fuc2l6ZSkgeworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgc3ggPSB4LCBpZHggPSAwOyBzeCA8IHggKyB3OyBzeCsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICByZ2JQaXhlbHNbaWR4XSA9IG1vZGVsLmdldFJHQihwaXhlbHNbcGl4ZWxzT2ZmICsgaWR4XSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbHRlclJHQlBpeGVscyh4LCBzeSwgdywgMSwgcmdiUGl4ZWxzLCAwLCB3KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgQ29sb3JNb2RlbCBtb2RlbCwgYnl0ZVtdIHBpeGVscywgaW50IG9mZiwKKyAgICAgICAgICAgIGludCBzY2Fuc2l6ZSkgeworCisgICAgICAgIGlmIChtb2RlbCA9PSBudWxsIHx8IG1vZGVsID09IG9yaWdtb2RlbCkgeworICAgICAgICAgICAgY29uc3VtZXIuc2V0UGl4ZWxzKHgsIHksIHcsIGgsIG5ld21vZGVsLCBwaXhlbHMsIG9mZiwgc2NhbnNpemUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IHJnYlBpeGVsc1tdID0gbmV3IGludFt3XTsKKyAgICAgICAgICAgIGZvciAoaW50IHN5ID0geSwgcGl4ZWxzT2ZmID0gb2ZmOyBzeSA8IHkgKyBoOyBzeSsrLCBwaXhlbHNPZmYgKz0gc2NhbnNpemUpIHsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHN4ID0geCwgaWR4ID0gMDsgc3ggPCB4ICsgdzsgc3grKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgcmdiUGl4ZWxzW2lkeF0gPSBtb2RlbC5nZXRSR0IocGl4ZWxzW3BpeGVsc09mZiArIGlkeF0gJiAweGZmKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmlsdGVyUkdCUGl4ZWxzKHgsIHN5LCB3LCAxLCByZ2JQaXhlbHMsIDAsIHcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsdGVycyBhIHJlZ2lvbiBvZiBwaXhlbHMgaW4gdGhlIGRlZmF1bHQgUkdCIENvbG9yTW9kZWwgYnkgY2FsbGluZyB0aGUKKyAgICAgKiBmaWx0ZXJSR0IgbWV0aG9kIGZvciB0aGVtLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHJlZ2lvbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiByZWdpb24uCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWdpb24uCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVnaW9uLgorICAgICAqIEBwYXJhbSBwaXhlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbHMgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBhcnJheS4KKyAgICAgKiBAcGFyYW0gc2NhbnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHJvd3Mgb2YgcGl4ZWxzIGluIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaWx0ZXJSR0JQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludFtdIHBpeGVscywgaW50IG9mZiwgaW50IHNjYW5zaXplKSB7CisKKyAgICAgICAgZm9yIChpbnQgc3kgPSB5LCBsaW5lT2ZmID0gb2ZmOyBzeSA8IHkgKyBoOyBzeSsrLCBsaW5lT2ZmICs9IHNjYW5zaXplKSB7CisgICAgICAgICAgICBmb3IgKGludCBzeCA9IHgsIGlkeCA9IDA7IHN4IDwgeCArIHc7IHN4KyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgcGl4ZWxzW2xpbmVPZmYgKyBpZHhdID0gZmlsdGVyUkdCKHN4LCBzeSwgcGl4ZWxzW2xpbmVPZmYgKyBpZHhdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjb25zdW1lci5zZXRQaXhlbHMoeCwgeSwgdywgaCwgQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCksIHBpeGVscywgb2ZmLCBzY2Fuc2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBzaW5nbGUgaW5wdXQgcGl4ZWwgaW4gdGhlIGRlZmF1bHQgUkdCIENvbG9yTW9kZWwgdG8gYSBzaW5nbGUKKyAgICAgKiBvdXRwdXQgcGl4ZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIHBpeGVsJ3MgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgcGl4ZWwncyBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSByZ2IKKyAgICAgKiAgICAgICAgICAgIGEgcGl4ZWwgaW4gdGhlIGRlZmF1bHQgUkdCIGNvbG9yIG1vZGVsLgorICAgICAqIEByZXR1cm4gYSBmaWx0ZXJlZCBwaXhlbCBpbiB0aGUgZGVmYXVsdCBSR0IgY29sb3IgbW9kZWwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBmaWx0ZXJSR0IoaW50IHgsIGludCB5LCBpbnQgcmdiKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1Jhc3Rlci5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL1Jhc3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3NDlmZGUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUmFzdGVyLmphdmEKQEAgLTAsMCArMSwxNTE1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuT3JkaW5hcnlXcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgUmFzdGVyIGNsYXNzIHJlcHJlc2VudHMgYSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4gVGhpcyBjbGFzcyBpcworICogZGVmaW5lZCBieSBEYXRhQnVmZmVyIGFuZCBTYW1wbGVNb2RlbCBvYmplY3RzLiBUaGUgRGF0YUJ1ZmZlciBvYmplY3Qgc3RvcmVzCisgKiBzYW1wbGUgdmFsdWVzIGFuZCBEU2FtcGxlTW9kZWwgZGVmaW5lcyB0aGUgbG9jYXRpb24gb2Ygc2FtcGxlIGluIHRoaXMKKyAqIERhdGFCdWZmZXIuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmFzdGVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBEYXRhQnVmZmVyIG9mIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBEYXRhQnVmZmVyIGRhdGFCdWZmZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGVpZ2h0IG9mIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgaGVpZ2h0OworCisgICAgLyoqCisgICAgICogVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBwaXhlbCBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG1pblg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IHBpeGVsIGluIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgbWluWTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgYmFuZHMgaW4gdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBudW1CYW5kczsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgZGF0YSBlbGVtZW50cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG51bURhdGFFbGVtZW50czsKKworICAgIC8qKgorICAgICAqIFRoZSBwYXJlbnQgb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFJhc3RlciBwYXJlbnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU2FtcGxlTW9kZWwgb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsOworCisgICAgLyoqCisgICAgICogVGhlIFggdHJhbnNsYXRpb24gZnJvbSB0aGUgY29vcmRpbmF0ZSBzcGFjZSBvZiB0aGUgU2FtcGxlTW9kZWwgb2YgdGhpcworICAgICAqIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHNhbXBsZU1vZGVsVHJhbnNsYXRlWDsKKworICAgIC8qKgorICAgICAqIFRoZSBZIHRyYW5zbGF0aW9uIGZyb20gdGhlIGNvb3JkaW5hdGUgc3BhY2Ugb2YgdGhlIFNhbXBsZU1vZGVsIG9mIHRoaXMKKyAgICAgKiBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzYW1wbGVNb2RlbFRyYW5zbGF0ZVk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd2lkdGggb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB3aWR0aDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBSYXN0ZXIgb2JqZWN0IHdpdGggYSBCYW5kZWRTYW1wbGVNb2RlbCBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqIERhdGFCdWZmZXIuIFRoZSBudW1iZXIgb2YgYmFuZHMgaXMgZGVmaW5lZCBieSB0aGUgbGVuZ3RoIG9mIGJhbmRPZmZzZXRzCisgICAgICogb3IgYmFua0luZGljZXMgYXJyYXlzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gc2NhbmxpbmVTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGJhbmtJbmRpY2VzCisgICAgICogICAgICAgICAgICB0aGUgYmFuayBpbmRpY2VzIG9mIGJhbmRzLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJhbmQgb2Zmc2V0cyBvZiBiYW5kcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiBSYXN0ZXIuCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQmFuZGVkUmFzdGVyKERhdGFCdWZmZXIgZGF0YUJ1ZmZlciwgaW50IHcsIGludCBoLAorICAgICAgICAgICAgaW50IHNjYW5saW5lU3RyaWRlLCBpbnQgYmFua0luZGljZXNbXSwgaW50IGJhbmRPZmZzZXRzW10sIFBvaW50IGxvY2F0aW9uKSB7CisKKyAgICAgICAgaWYgKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKWxvY2F0aW9uLnggKyB3ID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgKGxvbmcpbG9jYXRpb24ueSArIGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI3Nj1sb2NhdGlvbi54ICsgdyBvciBsb2NhdGlvbi55ICsgaCByZXN1bHRzIGluIGludGVnZXIKKyAgICAgICAgICAgIC8vIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGJhbmtJbmRpY2VzID09IG51bGwgfHwgYmFuZE9mZnNldHMgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI3Nz1iYW5rSW5kaWNlcyBvciBiYW5kT2Zmc2V0cyBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGRhdGFCdWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI3OD1kYXRhQnVmZmVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBkYXRhVHlwZSA9IGRhdGFCdWZmZXIuZ2V0RGF0YVR5cGUoKTsKKworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVAorICAgICAgICAgICAgICAgICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9JTlQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzA9ZGF0YVR5cGUgaXMgbm90IG9uZSBvZiB0aGUgc3VwcG9ydGVkIGRhdGEgdHlwZXMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjMwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBCYW5kZWRTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCA9IG5ldyBCYW5kZWRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwgc2NhbmxpbmVTdHJpZGUsCisgICAgICAgICAgICAgICAgYmFua0luZGljZXMsIGJhbmRPZmZzZXRzKTsKKworICAgICAgICByZXR1cm4gbmV3IE9yZGluYXJ5V3JpdGFibGVSYXN0ZXIoc2FtcGxlTW9kZWwsIGRhdGFCdWZmZXIsIGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgUmFzdGVyIG9iamVjdCB3aXRoIGEgQmFuZGVkU2FtcGxlTW9kZWwgYW5kIHRoZSBzcGVjaWZpZWQgZGF0YQorICAgICAqIHR5cGUuIFRoZSBEYXRhIHR5cGUgY2FuIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczogVFlQRV9CWVRFLAorICAgICAqIFRZUEVfVVNIT1JULCBvciBUWVBFX0lOVC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHNhbXBsZXM6IFRZUEVfQllURSwgVFlQRV9VU0hPUlQsIG9yCisgICAgICogICAgICAgICAgICBUWVBFX0lOVC4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBzY2FubGluZVN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gYmFua0luZGljZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYW5rIGluZGljZXMgb2YgYmFuZHMuCisgICAgICogQHBhcmFtIGJhbmRPZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgYmFuZCBvZmZzZXRzIG9mIGJhbmRzLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHdoaWNoIGRlZmluZXMgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZQorICAgICAqICAgICAgICAgICAgUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUJhbmRlZFJhc3RlcihpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IHNjYW5saW5lU3RyaWRlLAorICAgICAgICAgICAgaW50IGJhbmtJbmRpY2VzW10sIGludCBiYW5kT2Zmc2V0c1tdLCBQb2ludCBsb2NhdGlvbikgeworCisgICAgICAgIGlmICh3IDw9IDAgfHwgaCA8PSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjJFPXcgb3IgaCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMkUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICBsb2NhdGlvbiA9IG5ldyBQb2ludCgwLCAwKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZylsb2NhdGlvbi54ICsgdyA+IEludGVnZXIuTUFYX1ZBTFVFIHx8IChsb25nKWxvY2F0aW9uLnkgKyBoID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNzY9bG9jYXRpb24ueCArIHcgb3IgbG9jYXRpb24ueSArIGggcmVzdWx0cyBpbiBpbnRlZ2VyCisgICAgICAgICAgICAvLyBvdmVyZmxvdworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChiYW5rSW5kaWNlcyA9PSBudWxsIHx8IGJhbmRPZmZzZXRzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNzc9YmFua0luZGljZXMgb3IgYmFuZE9mZnNldHMgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzciKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUCisgICAgICAgICAgICAgICAgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVCkgeworICAgICAgICAgICAgLy8gYXd0LjIzMD1kYXRhVHlwZSBpcyBub3Qgb25lIG9mIHRoZSBzdXBwb3J0ZWQgZGF0YSB0eXBlcworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBtYXhPZmZzZXQgPSBiYW5kT2Zmc2V0c1swXTsKKyAgICAgICAgaW50IG1heEJhbmsgPSBiYW5rSW5kaWNlc1swXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhbmtJbmRpY2VzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYmFuZE9mZnNldHNbaV0gPiBtYXhPZmZzZXQpIHsKKyAgICAgICAgICAgICAgICBtYXhPZmZzZXQgPSBiYW5kT2Zmc2V0c1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChiYW5rSW5kaWNlc1tpXSA+IG1heEJhbmspIHsKKyAgICAgICAgICAgICAgICBtYXhCYW5rID0gYmFua0luZGljZXNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgbnVtQmFua3MgPSBtYXhCYW5rICsgMTsKKyAgICAgICAgaW50IGRhdGFTaXplID0gc2NhbmxpbmVTdHJpZGUgKiAoaCAtIDEpICsgdyArIG1heE9mZnNldDsKKworICAgICAgICBEYXRhQnVmZmVyIGRhdGEgPSBudWxsOworCisgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyQnl0ZShkYXRhU2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlclVTaG9ydChkYXRhU2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlckludChkYXRhU2l6ZSwgbnVtQmFua3MpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjcmVhdGVCYW5kZWRSYXN0ZXIoZGF0YSwgdywgaCwgc2NhbmxpbmVTdHJpZGUsIGJhbmtJbmRpY2VzLCBiYW5kT2Zmc2V0cywgbG9jYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBSYXN0ZXIgb2JqZWN0IHdpdGggYSBCYW5kZWRTYW1wbGVNb2RlbCBhbmQgdGhlIHNwZWNpZmllZCBkYXRhCisgICAgICogdHlwZS4gVGhlIERhdGEgdHlwZSBjYW4gYmUgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOiBUWVBFX0JZVEUsCisgICAgICogVFlQRV9VU0hPUlQsIG9yIFRZUEVfSU5ULgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiB0aGUgc2FtcGxlczogVFlQRV9CWVRFLCBUWVBFX1VTSE9SVCwgb3IKKyAgICAgKiAgICAgICAgICAgIFRZUEVfSU5ULgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJhbmRzLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHdoaWNoIGRlZmluZXMgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZQorICAgICAqICAgICAgICAgICAgUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUJhbmRlZFJhc3RlcihpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IGJhbmRzLAorICAgICAgICAgICAgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIyRT13IG9yIGggaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYXRpb24gPSBuZXcgUG9pbnQoMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpbG9jYXRpb24ueCArIHcgPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCAobG9uZylsb2NhdGlvbi55ICsgaCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc2PWxvY2F0aW9uLnggKyB3IG9yIGxvY2F0aW9uLnkgKyBoIHJlc3VsdHMgaW4gaW50ZWdlcgorICAgICAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjc2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoYmFuZHMgPCAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc5PWJhbmRzIGlzIGxlc3MgdGhhbiAxCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3OSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGJhbmRPZmZzZXRzW10gPSBuZXcgaW50W2JhbmRzXTsKKyAgICAgICAgaW50IGJhbmtJbmRpY2VzW10gPSBuZXcgaW50W2JhbmRzXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIGJhbmRPZmZzZXRzW2ldID0gMDsKKyAgICAgICAgICAgIGJhbmtJbmRpY2VzW2ldID0gaTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3JlYXRlQmFuZGVkUmFzdGVyKGRhdGFUeXBlLCB3LCBoLCB3LCBiYW5rSW5kaWNlcywgYmFuZE9mZnNldHMsIGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgUmFzdGVyIG9iamVjdCB3aXRoIGEgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgRGF0YUJ1ZmZlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YUJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIERhdGFCdWZmZXIuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIHNjYW5saW5lU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBwaXhlbFN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIHN0cmlkZSBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJhbmQgb2Zmc2V0cyBvZiBiYW5kcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3RlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihEYXRhQnVmZmVyIGRhdGFCdWZmZXIsIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIGludCBzY2FubGluZVN0cmlkZSwgaW50IHBpeGVsU3RyaWRlLCBpbnQgYmFuZE9mZnNldHNbXSwgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIyRT13IG9yIGggaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYXRpb24gPSBuZXcgUG9pbnQoMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpbG9jYXRpb24ueCArIHcgPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCAobG9uZylsb2NhdGlvbi55ICsgaCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc2PWxvY2F0aW9uLnggKyB3IG9yIGxvY2F0aW9uLnkgKyBoIHJlc3VsdHMgaW4gaW50ZWdlcgorICAgICAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjc2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZGF0YUJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc4PWRhdGFCdWZmZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGRhdGFUeXBlID0gZGF0YUJ1ZmZlci5nZXREYXRhVHlwZSgpOworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCkgeworICAgICAgICAgICAgLy8gYXd0LjIzMD1kYXRhVHlwZSBpcyBub3Qgb25lIG9mIHRoZSBzdXBwb3J0ZWQgZGF0YSB0eXBlcworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkYXRhQnVmZmVyLmdldE51bUJhbmtzKCkgPiAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdBPWRhdGFCdWZmZXIgaGFzIG1vcmUgdGhhbiBvbmUgYmFuaworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yN0EiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChiYW5kT2Zmc2V0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdCPWJhbmRPZmZzZXRzIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yN0IiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCA9IG5ldyBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwoZGF0YVR5cGUsIHcsIGgsCisgICAgICAgICAgICAgICAgcGl4ZWxTdHJpZGUsIHNjYW5saW5lU3RyaWRlLCBiYW5kT2Zmc2V0cyk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBPcmRpbmFyeVdyaXRhYmxlUmFzdGVyKHNhbXBsZU1vZGVsLCBkYXRhQnVmZmVyLCBsb2NhdGlvbik7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgUmFzdGVyIG9iamVjdCB3aXRoIGEgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGF0YSB0eXBlLiBUaGUgRGF0YSB0eXBlIGNhbiBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXM6CisgICAgICogVFlQRV9CWVRFLCBUWVBFX1VTSE9SVCwgb3IgVFlQRV9JTlQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHRoZSBzYW1wbGVzOiBUWVBFX0JZVEUsIFRZUEVfVVNIT1JULCBvcgorICAgICAqICAgICAgICAgICAgVFlQRV9JTlQuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIHNjYW5saW5lU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBwaXhlbFN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsIHN0cmlkZSBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJhbmQgb2Zmc2V0cyBvZiBiYW5kcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3RlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIGludCBzY2FubGluZVN0cmlkZSwgaW50IHBpeGVsU3RyaWRlLCBpbnQgYmFuZE9mZnNldHNbXSwgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIyRT13IG9yIGggaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYXRpb24gPSBuZXcgUG9pbnQoMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpbG9jYXRpb24ueCArIHcgPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCAobG9uZylsb2NhdGlvbi55ICsgaCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc2PWxvY2F0aW9uLnggKyB3IG9yIGxvY2F0aW9uLnkgKyBoIHJlc3VsdHMgaW4gaW50ZWdlcgorICAgICAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjc2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCkgeworICAgICAgICAgICAgLy8gYXd0LjIzMD1kYXRhVHlwZSBpcyBub3Qgb25lIG9mIHRoZSBzdXBwb3J0ZWQgZGF0YSB0eXBlcworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzAiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChiYW5kT2Zmc2V0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdCPWJhbmRPZmZzZXRzIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yN0IiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBtaW5PZmZzZXQgPSBiYW5kT2Zmc2V0c1swXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBiYW5kT2Zmc2V0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGJhbmRPZmZzZXRzW2ldIDwgbWluT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgbWluT2Zmc2V0ID0gYmFuZE9mZnNldHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpemUgPSAoaCAtIDEpICogc2NhbmxpbmVTdHJpZGUgKyB3ICogcGl4ZWxTdHJpZGUgKyBtaW5PZmZzZXQ7CisgICAgICAgIERhdGFCdWZmZXIgZGF0YSA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJCeXRlKHNpemUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlclVTaG9ydChzaXplKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihkYXRhLCB3LCBoLCBzY2FubGluZVN0cmlkZSwgcGl4ZWxTdHJpZGUsIGJhbmRPZmZzZXRzLAorICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgUmFzdGVyIG9iamVjdCB3aXRoIGEgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGF0YSB0eXBlLiBUaGUgRGF0YSB0eXBlIGNhbiBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXM6CisgICAgICogVFlQRV9CWVRFLCBUWVBFX1VTSE9SVCwgb3IgVFlQRV9JTlQuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHNhbXBsZXM6IFRZUEVfQllURSwgVFlQRV9VU0hPUlQsIG9yIFRZUEVfSU5ULgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiYW5kcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZUludGVybGVhdmVkUmFzdGVyKGludCBkYXRhVHlwZSwgaW50IHcsIGludCBoLCBpbnQgYmFuZHMsCisgICAgICAgICAgICBQb2ludCBsb2NhdGlvbikgeworCisgICAgICAgIGlmICh3IDw9IDAgfHwgaCA8PSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjJFPXcgb3IgaCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMkUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICBsb2NhdGlvbiA9IG5ldyBQb2ludCgwLCAwKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZylsb2NhdGlvbi54ICsgdyA+IEludGVnZXIuTUFYX1ZBTFVFIHx8IChsb25nKWxvY2F0aW9uLnkgKyBoID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNzY9bG9jYXRpb24ueCArIHcgb3IgbG9jYXRpb24ueSArIGggcmVzdWx0cyBpbiBpbnRlZ2VyCisgICAgICAgICAgICAvLyBvdmVyZmxvdworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUKSB7CisgICAgICAgICAgICAvLyBhd3QuMjMwPWRhdGFUeXBlIGlzIG5vdCBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkYXRhIHR5cGVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGJhbmRPZmZzZXRzW10gPSBuZXcgaW50W2JhbmRzXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYW5kczsgaSsrKSB7CisgICAgICAgICAgICBiYW5kT2Zmc2V0c1tpXSA9IGk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoZGF0YVR5cGUsIHcsIGgsIHcgKiBiYW5kcywgYmFuZHMsIGJhbmRPZmZzZXRzLCBsb2NhdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFJhc3RlciBvYmplY3Qgd2l0aCBhIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgYW5kIHRoZQorICAgICAqIHNwZWNpZmllZCBEYXRhQnVmZmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgRGF0YUJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBzY2FubGluZVN0cmlkZQorICAgICAqICAgICAgICAgICAgdGhlIHNjYW5saW5lIHN0cmlkZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gYmFuZE1hc2tzCisgICAgICogICAgICAgICAgICB0aGUgYmFuZCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyIGRhdGFCdWZmZXIsIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIGludCBzY2FubGluZVN0cmlkZSwgaW50IGJhbmRNYXNrc1tdLCBQb2ludCBsb2NhdGlvbikgeworICAgICAgICBpZiAoZGF0YUJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc4PWRhdGFCdWZmZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKWxvY2F0aW9uLnggKyB3ID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgKGxvbmcpbG9jYXRpb24ueSArIGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI3Nj1sb2NhdGlvbi54ICsgdyBvciBsb2NhdGlvbi55ICsgaCByZXN1bHRzIGluIGludGVnZXIKKyAgICAgICAgICAgIC8vIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGJhbmRNYXNrcyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdDPWJhbmRNYXNrcyBpcyBudWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3QyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGRhdGFCdWZmZXIuZ2V0TnVtQmFua3MoKSA+IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yN0E9ZGF0YUJ1ZmZlciBoYXMgbW9yZSB0aGFuIG9uZSBiYW5rCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3QSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGRhdGFUeXBlID0gZGF0YUJ1ZmZlci5nZXREYXRhVHlwZSgpOworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVAorICAgICAgICAgICAgICAgICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9JTlQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzA9ZGF0YVR5cGUgaXMgbm90IG9uZSBvZiB0aGUgc3VwcG9ydGVkIGRhdGEgdHlwZXMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjMwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsID0gbmV3IFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwoZGF0YVR5cGUsIHcsIGgsCisgICAgICAgICAgICAgICAgc2NhbmxpbmVTdHJpZGUsIGJhbmRNYXNrcyk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBPcmRpbmFyeVdyaXRhYmxlUmFzdGVyKHNhbXBsZU1vZGVsLCBkYXRhQnVmZmVyLCBsb2NhdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFJhc3RlciBvYmplY3Qgd2l0aCBhIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBhbmQgdGhlCisgICAgICogc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFCdWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBEYXRhQnVmZmVyLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGJpdHNQZXJQaXhlbAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHBlciBwaXhlbC4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVBhY2tlZFJhc3RlcihEYXRhQnVmZmVyIGRhdGFCdWZmZXIsIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIGludCBiaXRzUGVyUGl4ZWwsIFBvaW50IGxvY2F0aW9uKSB7CisKKyAgICAgICAgaWYgKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKWxvY2F0aW9uLnggKyB3ID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgKGxvbmcpbG9jYXRpb24ueSArIGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI3Nj1sb2NhdGlvbi54ICsgdyBvciBsb2NhdGlvbi55ICsgaCByZXN1bHRzIGluIGludGVnZXIKKyAgICAgICAgICAgIC8vIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGRhdGFCdWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI3OD1kYXRhQnVmZmVyIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNzgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkYXRhQnVmZmVyLmdldE51bUJhbmtzKCkgPiAxKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdBPWRhdGFCdWZmZXIgaGFzIG1vcmUgdGhhbiBvbmUgYmFuaworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yN0EiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBkYXRhVHlwZSA9IGRhdGFCdWZmZXIuZ2V0RGF0YVR5cGUoKTsKKyAgICAgICAgaWYgKGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQKKyAgICAgICAgICAgICAgICAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UKSB7CisgICAgICAgICAgICAvLyBhd3QuMjMwPWRhdGFUeXBlIGlzIG5vdCBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkYXRhIHR5cGVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsID0gbmV3IE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbChkYXRhVHlwZSwgdywgaCwKKyAgICAgICAgICAgICAgICBiaXRzUGVyUGl4ZWwpOworCisgICAgICAgIHJldHVybiBuZXcgT3JkaW5hcnlXcml0YWJsZVJhc3RlcihzYW1wbGVNb2RlbCwgZGF0YUJ1ZmZlciwgbG9jYXRpb24pOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFJhc3RlciBvYmplY3Qgd2l0aCBhIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBhbmQgdGhlCisgICAgICogc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHNhbXBsZXM6IFRZUEVfQllURSwgVFlQRV9VU0hPUlQsIG9yIFRZUEVfSU5ULgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJhbmRzLgorICAgICAqIEBwYXJhbSBiaXRzUGVyQmFuZAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHBlciBiYW5kLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHdoaWNoIGRlZmluZXMgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZQorICAgICAqICAgICAgICAgICAgUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlUGFja2VkUmFzdGVyKGludCBkYXRhVHlwZSwgaW50IHcsIGludCBoLCBpbnQgYmFuZHMsCisgICAgICAgICAgICBpbnQgYml0c1BlckJhbmQsIFBvaW50IGxvY2F0aW9uKSB7CisKKyAgICAgICAgaWYgKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKWxvY2F0aW9uLnggKyB3ID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgKGxvbmcpbG9jYXRpb24ueSArIGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI3Nj1sb2NhdGlvbi54ICsgdyBvciBsb2NhdGlvbi55ICsgaCByZXN1bHRzIGluIGludGVnZXIKKyAgICAgICAgICAgIC8vIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGJhbmRzIDwgMSB8fCBiaXRzUGVyQmFuZCA8IDEpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yN0Q9Yml0c1BlckJhbmQgb3IgYmFuZHMgaXMgbm90IGdyZWF0ZXIgdGhhbiB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3RCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQKKyAgICAgICAgICAgICAgICAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UKSB7CisgICAgICAgICAgICAvLyBhd3QuMjMwPWRhdGFUeXBlIGlzIG5vdCBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkYXRhIHR5cGVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGJpdHNQZXJCYW5kICogYmFuZHMgPiBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShkYXRhVHlwZSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yN0U9VGhlIHByb2R1Y3Qgb2YgYml0c1BlckJhbmQgYW5kIGJhbmRzIGlzIGdyZWF0ZXIgdGhhbiB0aGUKKyAgICAgICAgICAgIC8vIG51bWJlciBvZiBiaXRzIGhlbGQgYnkgZGF0YVR5cGUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjdFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoYmFuZHMgPiAxKSB7CisKKyAgICAgICAgICAgIGludCBiYW5kTWFza3NbXSA9IG5ldyBpbnRbYmFuZHNdOworICAgICAgICAgICAgaW50IG1hc2sgPSAoMSA8PCBiaXRzUGVyQmFuZCkgLSAxOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBiYW5kTWFza3NbaV0gPSBtYXNrIDw8IChiaXRzUGVyQmFuZCAqIChiYW5kcyAtIDEgLSBpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVQYWNrZWRSYXN0ZXIoZGF0YVR5cGUsIHcsIGgsIGJhbmRNYXNrcywgbG9jYXRpb24pOworICAgICAgICB9CisgICAgICAgIERhdGFCdWZmZXIgZGF0YSA9IG51bGw7CisgICAgICAgIGludCBzaXplID0gKChiaXRzUGVyQmFuZCAqIHcgKyBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShkYXRhVHlwZSkgLSAxKSAvIERhdGFCdWZmZXIKKyAgICAgICAgICAgICAgICAuZ2V0RGF0YVR5cGVTaXplKGRhdGFUeXBlKSkKKyAgICAgICAgICAgICAgICAqIGg7CisKKyAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJCeXRlKHNpemUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlclVTaG9ydChzaXplKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJJbnQoc2l6ZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNyZWF0ZVBhY2tlZFJhc3RlcihkYXRhLCB3LCBoLCBiaXRzUGVyQmFuZCwgbG9jYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBSYXN0ZXIgb2JqZWN0IHdpdGggYSBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgRGF0YUJ1ZmZlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2Ygc2FtcGxlczogVFlQRV9CWVRFLCBUWVBFX1VTSE9SVCwgb3IgVFlQRV9JTlQuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gYmFuZE1hc2tzCisgICAgICogICAgICAgICAgICB0aGUgYmFuZCBtYXNrcy4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhdGlvbiB3aGljaCBkZWZpbmVzIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVBhY2tlZFJhc3RlcihpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IGJhbmRNYXNrc1tdLAorICAgICAgICAgICAgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVAorICAgICAgICAgICAgICAgICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9JTlQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzA9ZGF0YVR5cGUgaXMgbm90IG9uZSBvZiB0aGUgc3VwcG9ydGVkIGRhdGEgdHlwZXMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjMwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIyRT13IG9yIGggaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYXRpb24gPSBuZXcgUG9pbnQoMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpbG9jYXRpb24ueCArIHcgPiBJbnRlZ2VyLk1BWF9WQUxVRSB8fCAobG9uZylsb2NhdGlvbi55ICsgaCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjc2PWxvY2F0aW9uLnggKyB3IG9yIGxvY2F0aW9uLnkgKyBoIHJlc3VsdHMgaW4gaW50ZWdlcgorICAgICAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjc2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoYmFuZE1hc2tzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yN0M9YmFuZE1hc2tzIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yN0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIERhdGFCdWZmZXIgZGF0YSA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJCeXRlKHcgKiBoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJVU2hvcnQodyAqIGgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfSU5UOgorICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgRGF0YUJ1ZmZlckludCh3ICogaCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY3JlYXRlUGFja2VkUmFzdGVyKGRhdGEsIHcsIGgsIHcsIGJhbmRNYXNrcywgbG9jYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBSYXN0ZXIgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBEYXRhQnVmZmVyIGFuZCBTYW1wbGVNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwuCisgICAgICogQHBhcmFtIGRiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbG9jYXRpb24gd2hpY2ggZGVmaW5lcyB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlCisgICAgICogICAgICAgICAgICBSYXN0ZXIuCisgICAgICogQHJldHVybiB0aGUgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmFzdGVyIGNyZWF0ZVJhc3RlcihTYW1wbGVNb2RlbCBzbSwgRGF0YUJ1ZmZlciBkYiwgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAoc20gPT0gbnVsbCB8fCBkYiA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdGPVNhbXBsZU1vZGVsIG9yIERhdGFCdWZmZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3RiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBSYXN0ZXIoc20sIGRiLCBsb2NhdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFdyaXRhYmxlUmFzdGVyIHdpdGggdGhlIHNwZWNpZmllZCBTYW1wbGVNb2RlbCBhbmQgRGF0YUJ1ZmZlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwuCisgICAgICogQHBhcmFtIGRiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbG9jYXRpb24gd2hpY2ggZGVmaW5lcyB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlCisgICAgICogICAgICAgICAgICBSYXN0ZXIuCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVXcml0YWJsZVJhc3RlcihTYW1wbGVNb2RlbCBzbSwgRGF0YUJ1ZmZlciBkYiwgUG9pbnQgbG9jYXRpb24pIHsKKworICAgICAgICBpZiAoc20gPT0gbnVsbCB8fCBkYiA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjdGPVNhbXBsZU1vZGVsIG9yIERhdGFCdWZmZXIgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3RiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBPcmRpbmFyeVdyaXRhYmxlUmFzdGVyKHNtLCBkYiwgbG9jYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBXcml0YWJsZVJhc3RlciB3aXRoIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIHNtCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFNhbXBsZU1vZGVsLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHdoaWNoIGRlZmluZXMgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZQorICAgICAqICAgICAgICAgICAgUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlV3JpdGFibGVSYXN0ZXIoU2FtcGxlTW9kZWwgc20sIFBvaW50IGxvY2F0aW9uKSB7CisKKyAgICAgICAgaWYgKHNtID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yODA9U2FtcGxlTW9kZWwgaXMgbnVsbAorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4MCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gbmV3IFBvaW50KDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNyZWF0ZVdyaXRhYmxlUmFzdGVyKHNtLCBzbS5jcmVhdGVEYXRhQnVmZmVyKCksIGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgUmFzdGVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwgYW5kCisgICAgICogRGF0YUJ1ZmZlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwuCisgICAgICogQHBhcmFtIGRhdGFCdWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgRGF0YUJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb3JpZ2luCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIG9yaWdpbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmFzdGVyKFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsLCBEYXRhQnVmZmVyIGRhdGFCdWZmZXIsIFBvaW50IG9yaWdpbikgeworCisgICAgICAgIHRoaXMoc2FtcGxlTW9kZWwsIGRhdGFCdWZmZXIsIG5ldyBSZWN0YW5nbGUob3JpZ2luLngsIG9yaWdpbi55LCBzYW1wbGVNb2RlbC5nZXRXaWR0aCgpLAorICAgICAgICAgICAgICAgIHNhbXBsZU1vZGVsLmdldEhlaWdodCgpKSwgb3JpZ2luLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgUmFzdGVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwsCisgICAgICogRGF0YUJ1ZmZlciwgcmVjdGFuZ3VsYXIgcmVnaW9uIGFuZCBwYXJlbnQgUmFzdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzYW1wbGVNb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBTYW1wbGVNb2RlbC4KKyAgICAgKiBAcGFyYW0gZGF0YUJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBEYXRhQnVmZmVyLgorICAgICAqIEBwYXJhbSBhUmVnaW9uCisgICAgICogICAgICAgICAgICB0aGUgYSByZWN0YW5ndWxhciByZWdpb24gd2hpY2ggZGVmaW5lcyB0aGUgbmV3IGltYWdlIGJvdW5kcy4KKyAgICAgKiBAcGFyYW0gc2FtcGxlTW9kZWxUcmFuc2xhdGUKKyAgICAgKiAgICAgICAgICAgIHRoaXMgcG9pbnQgZGVmaW5lcyB0aGUgdHJhbnNsYXRpb24gcG9pbnQgZnJvbSB0aGUgU2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgICAgIGNvb3JkaW5hdGVzIHRvIHRoZSBuZXcgUmFzdGVyIGNvb3JkaW5hdGVzLgorICAgICAqIEBwYXJhbSBwYXJlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFJhc3RlcihTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCwgRGF0YUJ1ZmZlciBkYXRhQnVmZmVyLCBSZWN0YW5nbGUgYVJlZ2lvbiwKKyAgICAgICAgICAgIFBvaW50IHNhbXBsZU1vZGVsVHJhbnNsYXRlLCBSYXN0ZXIgcGFyZW50KSB7CisKKyAgICAgICAgaWYgKHNhbXBsZU1vZGVsID09IG51bGwgfHwgZGF0YUJ1ZmZlciA9PSBudWxsIHx8IGFSZWdpb24gPT0gbnVsbAorICAgICAgICAgICAgICAgIHx8IHNhbXBsZU1vZGVsVHJhbnNsYXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yODE9c2FtcGxlTW9kZWwsIGRhdGFCdWZmZXIsIGFSZWdpb24gb3Igc2FtcGxlTW9kZWxUcmFuc2xhdGUKKyAgICAgICAgICAgIC8vIGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yODEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhUmVnaW9uLndpZHRoIDw9IDAgfHwgYVJlZ2lvbi5oZWlnaHQgPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjI4Mj1hUmVnaW9uIGhhcyB3aWR0aCBvciBoZWlnaHQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjgyIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpYVJlZ2lvbi54ICsgKGxvbmcpYVJlZ2lvbi53aWR0aCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjgzPU92ZXJmbG93IFggY29vcmRpbmF0ZSBvZiBSYXN0ZXIKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjgzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxvbmcpYVJlZ2lvbi55ICsgKGxvbmcpYVJlZ2lvbi5oZWlnaHQgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI4ND1PdmVyZmxvdyBZIGNvb3JkaW5hdGUgb2YgUmFzdGVyCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHNhbXBsZU1vZGVsIGluc3RhbmNlb2YgQ29tcG9uZW50U2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgIHZhbGlkYXRlRGF0YUJ1ZmZlcihkYXRhQnVmZmVyLCBhUmVnaW9uLndpZHRoLCBhUmVnaW9uLmhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgKChDb21wb25lbnRTYW1wbGVNb2RlbClzYW1wbGVNb2RlbCkuZ2V0U2NhbmxpbmVTdHJpZGUoKSk7CisgICAgICAgIH0gZWxzZSBpZiAoc2FtcGxlTW9kZWwgaW5zdGFuY2VvZiBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgIHZhbGlkYXRlRGF0YUJ1ZmZlcihkYXRhQnVmZmVyLCBhUmVnaW9uLndpZHRoLCBhUmVnaW9uLmhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgKChNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpc2FtcGxlTW9kZWwpLmdldFNjYW5saW5lU3RyaWRlKCkpOworICAgICAgICB9IGVsc2UgaWYgKHNhbXBsZU1vZGVsIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgdmFsaWRhdGVEYXRhQnVmZmVyKGRhdGFCdWZmZXIsIGFSZWdpb24ud2lkdGgsIGFSZWdpb24uaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAoKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpc2FtcGxlTW9kZWwpLmdldFNjYW5saW5lU3RyaWRlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5zYW1wbGVNb2RlbCA9IHNhbXBsZU1vZGVsOworICAgICAgICB0aGlzLmRhdGFCdWZmZXIgPSBkYXRhQnVmZmVyOworICAgICAgICB0aGlzLm1pblggPSBhUmVnaW9uLng7CisgICAgICAgIHRoaXMubWluWSA9IGFSZWdpb24ueTsKKyAgICAgICAgdGhpcy53aWR0aCA9IGFSZWdpb24ud2lkdGg7CisgICAgICAgIHRoaXMuaGVpZ2h0ID0gYVJlZ2lvbi5oZWlnaHQ7CisgICAgICAgIHRoaXMuc2FtcGxlTW9kZWxUcmFuc2xhdGVYID0gc2FtcGxlTW9kZWxUcmFuc2xhdGUueDsKKyAgICAgICAgdGhpcy5zYW1wbGVNb2RlbFRyYW5zbGF0ZVkgPSBzYW1wbGVNb2RlbFRyYW5zbGF0ZS55OworICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKKyAgICAgICAgdGhpcy5udW1CYW5kcyA9IHNhbXBsZU1vZGVsLmdldE51bUJhbmRzKCk7CisgICAgICAgIHRoaXMubnVtRGF0YUVsZW1lbnRzID0gc2FtcGxlTW9kZWwuZ2V0TnVtRGF0YUVsZW1lbnRzKCk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgUmFzdGVyIHdpdGggdGhlIHNwZWNpZmllZCBTYW1wbGVNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwuCisgICAgICogQHBhcmFtIG9yaWdpbgorICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmFzdGVyKFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsLCBQb2ludCBvcmlnaW4pIHsKKyAgICAgICAgdGhpcyhzYW1wbGVNb2RlbCwgc2FtcGxlTW9kZWwuY3JlYXRlRGF0YUJ1ZmZlcigpLCBuZXcgUmVjdGFuZ2xlKG9yaWdpbi54LCBvcmlnaW4ueSwKKyAgICAgICAgICAgICAgICBzYW1wbGVNb2RlbC5nZXRXaWR0aCgpLCBzYW1wbGVNb2RlbC5nZXRIZWlnaHQoKSksIG9yaWdpbiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgY2hpbGQgb2YgdGhpcyBSYXN0ZXIgYnkgc2hhcmluZyB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyCisgICAgICogYXJlYSBpbiB0aGlzIHJhc3Rlci4gVGhlIHBhcmVudFgsIHBhcmVudFksIHdpZHRoIGFuZCBoZWlnaHQgcGFyYW1ldGVycworICAgICAqIHNwZWNpZnkgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgdG8gYmUgc2hhcmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwYXJlbnRYCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGlzIFJhc3Rlci4KKyAgICAgKiBAcGFyYW0gcGFyZW50WQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhpcyBSYXN0ZXIuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGNoaWxkIGFyZWEuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgY2hpbGQgYXJlYS4KKyAgICAgKiBAcGFyYW0gY2hpbGRNaW5YCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIGNoaWxkIGFyZWEgbWFwcGVkIHRvIHRoZSBwYXJlbnRYCisgICAgICogICAgICAgICAgICBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSBjaGlsZE1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgY2hpbGQgYXJlYSBtYXBwZWQgdG8gdGhlIHBhcmVudFkKKyAgICAgKiAgICAgICAgICAgIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGJhbmRMaXN0CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgYmFuZCBpbmRpY2VzLgorICAgICAqIEByZXR1cm4gdGhlIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFzdGVyIGNyZWF0ZUNoaWxkKGludCBwYXJlbnRYLCBpbnQgcGFyZW50WSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgY2hpbGRNaW5YLAorICAgICAgICAgICAgaW50IGNoaWxkTWluWSwgaW50IGJhbmRMaXN0W10pIHsKKyAgICAgICAgaWYgKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yODU9V2lkdGggb3IgSGVpZ2h0IG9mIGNoaWxkIFJhc3RlciBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8KKyAgICAgICAgICAgIC8vIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjg1IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAocGFyZW50WCA8IHRoaXMubWluWCB8fCBwYXJlbnRYICsgd2lkdGggPiB0aGlzLm1pblggKyB0aGlzLndpZHRoKSB7CisgICAgICAgICAgICAvLyBhd3QuMjg2PXBhcmVudFggZGlzcG9zZXMgb3V0c2lkZSBSYXN0ZXIKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjg2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAocGFyZW50WSA8IHRoaXMubWluWSB8fCBwYXJlbnRZICsgaGVpZ2h0ID4gdGhpcy5taW5ZICsgdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yODc9cGFyZW50WSBkaXNwb3NlcyBvdXRzaWRlIFJhc3RlcgorICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yODciKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZylwYXJlbnRYICsgd2lkdGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI4OD1wYXJlbnRYICsgd2lkdGggcmVzdWx0cyBpbiBpbnRlZ2VyIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKXBhcmVudFkgKyBoZWlnaHQgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI4OT1wYXJlbnRZICsgaGVpZ2h0IHJlc3VsdHMgaW4gaW50ZWdlciBvdmVyZmxvdworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yODkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZyljaGlsZE1pblggKyB3aWR0aCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBhd3QuMjhBPWNoaWxkTWluWCArIHdpZHRoIHJlc3VsdHMgaW4gaW50ZWdlciBvdmVyZmxvdworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yOEEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZyljaGlsZE1pblkgKyBoZWlnaHQgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI4Qj1jaGlsZE1pblkgKyBoZWlnaHQgcmVzdWx0cyBpbiBpbnRlZ2VyIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI4QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgU2FtcGxlTW9kZWwgY2hpbGRNb2RlbDsKKworICAgICAgICBpZiAoYmFuZExpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgY2hpbGRNb2RlbCA9IHNhbXBsZU1vZGVsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2hpbGRNb2RlbCA9IHNhbXBsZU1vZGVsLmNyZWF0ZVN1YnNldFNhbXBsZU1vZGVsKGJhbmRMaXN0KTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjaGlsZFRyYW5zbGF0ZVggPSBjaGlsZE1pblggLSBwYXJlbnRYOworICAgICAgICBpbnQgY2hpbGRUcmFuc2xhdGVZID0gY2hpbGRNaW5ZIC0gcGFyZW50WTsKKworICAgICAgICByZXR1cm4gbmV3IFJhc3RlcihjaGlsZE1vZGVsLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgIG5ldyBSZWN0YW5nbGUoY2hpbGRNaW5YLCBjaGlsZE1pblksIHdpZHRoLCBoZWlnaHQpLCBuZXcgUG9pbnQoY2hpbGRUcmFuc2xhdGVYCisgICAgICAgICAgICAgICAgICAgICAgICArIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgY2hpbGRUcmFuc2xhdGVZICsgc2FtcGxlTW9kZWxUcmFuc2xhdGVZKSwgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgY29tcGF0aWJsZSBXcml0YWJsZVJhc3RlciB3aXRoIHRoZSBzYW1lIHBhcmFtZXRlcnMgYXMgdGhpcworICAgICAqIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKCkgeworICAgICAgICByZXR1cm4gbmV3IE9yZGluYXJ5V3JpdGFibGVSYXN0ZXIoc2FtcGxlTW9kZWwsIG5ldyBQb2ludCgwLCAwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgY29tcGF0aWJsZSBXcml0YWJsZVJhc3RlciB3aXRoIHRoZSBzYW1lIHBhcmFtZXRlcnMgYXMgdGhpcworICAgICAqIFJhc3RlciBhbmQgdGhlIHNwZWNpZmllZCBzaXplLgorICAgICAqIAorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIG5ldyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgbmV3IFdyaXRhYmxlUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoaW50IHcsIGludCBoKSB7CisgICAgICAgIGlmICh3IDw9IDAgfHwgaCA8PSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjJFPXcgb3IgaCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMkUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIFNhbXBsZU1vZGVsIHNtID0gc2FtcGxlTW9kZWwuY3JlYXRlQ29tcGF0aWJsZVNhbXBsZU1vZGVsKHcsIGgpOworCisgICAgICAgIHJldHVybiBuZXcgT3JkaW5hcnlXcml0YWJsZVJhc3RlcihzbSwgbmV3IFBvaW50KDAsIDApKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBjb21wYXRpYmxlIFdyaXRhYmxlUmFzdGVyIHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBhcyB0aGlzCisgICAgICogUmFzdGVyIGFuZCB0aGUgc3BlY2lmaWVkIHNpemUgYW5kIGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBuZXcgV3JpdGFibGVSYXN0ZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBuZXcgV3JpdGFibGVSYXN0ZXIuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIG5ldyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgcmFzdGVyID0gY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHcsIGgpOworCisgICAgICAgIHJldHVybiByYXN0ZXIuY3JlYXRlV3JpdGFibGVDaGlsZCgwLCAwLCB3LCBoLCB4LCB5LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBjb21wYXRpYmxlIFdyaXRhYmxlUmFzdGVyIHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBhcyB0aGlzCisgICAgICogUmFzdGVyIGFuZCB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZSB3aGljaCBkZXRlcm1pbmVzIG5ldyBXcml0YWJsZVJhc3RlcidzCisgICAgICogbG9jYXRpb24gYW5kIHNpemUuCisgICAgICogCisgICAgICogQHBhcmFtIHJlY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgUmVjdGFuZ2xlLgorICAgICAqIEByZXR1cm4gdGhlIFdyaXRhYmxlUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoUmVjdGFuZ2xlIHJlY3QpIHsKKyAgICAgICAgaWYgKHJlY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjI4Qz1SZWN0IGlzIG51bGwKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yOEMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIocmVjdC54LCByZWN0LnksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSB0cmFuc2xhdGVkIGNoaWxkIG9mIHRoaXMgUmFzdGVyLiBUaGUgTmV3IFJhc3RlciBvYmplY3QgaXMgYQorICAgICAqIHJlZmVyZW5jZSB0byB0aGUgdGhpcyBSYXN0ZXIgd2l0aCBhIGRpZmZlcmVudCBsb2NhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2hpbGRNaW5YCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBuZXcgUmFzdGVyLgorICAgICAqIEBwYXJhbSBjaGlsZE1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBSYXN0ZXIuCisgICAgICogQHJldHVybiB0aGUgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBSYXN0ZXIgY3JlYXRlVHJhbnNsYXRlZENoaWxkKGludCBjaGlsZE1pblgsIGludCBjaGlsZE1pblkpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZUNoaWxkKG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIGNoaWxkTWluWCwgY2hpbGRNaW5ZLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhpcyBSYXN0ZXIgYXMgYSByZWN0YW5nbGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYm91bmRzIG9mIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZShtaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBEYXRhQnVmZmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBEYXRhQnVmZmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUJ1ZmZlciBnZXREYXRhQnVmZmVyKCkgeworICAgICAgICByZXR1cm4gZGF0YUJ1ZmZlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIGVsZW1lbnRzIHdoaWNoIHJlcHJlc2VudCB0aGUgcGl4ZWwgZGF0YSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogcmVjdGFuZ2xlIGFyZWEgYXMgYSBwcmltaXRpdmUgYXJyYXkuIFRoZSBmb2xsb3dpbmcgaW1hZ2UgZGF0YSB0eXBlcyBhcmUKKyAgICAgKiBzdXBwb3J0ZWQ6IERhdGFCdWZmZXIuVFlQRV9CWVRFLCBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULAorICAgICAqIERhdGFCdWZmZXIuVFlQRV9JTlQsIERhdGFCdWZmZXIuVFlQRV9TSE9SVCwgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FULCBvcgorICAgICAqIERhdGFCdWZmZXIuVFlQRV9ET1VCTEUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIG91dERhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRpbmcgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZGF0YSBlbGVtZW50cyBvZiB0aGUgc3BlY2lmaWVkIGFyZWEgb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIE9iamVjdCBvdXREYXRhKSB7CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXREYXRhRWxlbWVudHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywKKyAgICAgICAgICAgICAgICBoLCBvdXREYXRhLCBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkYXRhIGVsZW1lbnRzIHdoaWNoIHJlcHJlc2VudCB0aGUgc3BlY2lmaWVkIHBpeGVsIG9mIHRoaXMgUmFzdGVyCisgICAgICogYXMgYSBwcmltaXRpdmUgYXJyYXkuIFRoZSBmb2xsb3dpbmcgaW1hZ2UgZGF0YSB0eXBlcyBhcmUgc3VwcG9ydGVkOgorICAgICAqIERhdGFCdWZmZXIuVFlQRV9CWVRFLCBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBEYXRhQnVmZmVyLlRZUEVfSU5ULAorICAgICAqIERhdGFCdWZmZXIuVFlQRV9TSE9SVCwgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FULCBvciBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIG91dERhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRpbmcgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRhIGVsZW1lbnRzIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwgb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBPYmplY3Qgb3V0RGF0YSkgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWwuZ2V0RGF0YUVsZW1lbnRzKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksCisgICAgICAgICAgICAgICAgb3V0RGF0YSwgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoaXMgUmFzdGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhlaWdodCBvZiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIFggY29vcmRpbmF0ZSBvZiB0aGlzIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIFggY29vcmRpbmF0ZSBvZiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldE1pblgoKSB7CisgICAgICAgIHJldHVybiBtaW5YOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0gWSBjb29yZGluYXRlIG9mIHRoaXMgUmFzdGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gWSBjb29yZGluYXRlIG9mIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TWluWSgpIHsKKyAgICAgICAgcmV0dXJuIG1pblk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoaXMgUmFzdGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBiYW5kcyBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bUJhbmRzKCkgeworICAgICAgICByZXR1cm4gbnVtQmFuZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGRhdGEgZWxlbWVudHMgZm9yIG9uZSBwaXhlbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZGF0YSBlbGVtZW50cyBmb3Igb25lIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtRGF0YUVsZW1lbnRzKCkgeworICAgICAgICByZXR1cm4gbnVtRGF0YUVsZW1lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBhcmVudCBSYXN0ZXIgZm9yIHRoaXMgUmFzdGVyIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgUmFzdGVyIGZvciB0aGlzIFJhc3RlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFJhc3RlciBnZXRQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGRvdWJsZSBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsIGluIHRoaXMgUmFzdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwncyBYIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCdzIFkgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gZEFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIGFycmF5IHdoZXJlIHJlc3VsdCBhcnJheSB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBpbiB0aGlzCisgICAgICogICAgICAgICBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZVtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgZG91YmxlIGRBcnJheVtdKSB7CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRQaXhlbCh4IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVYLCB5IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVZLCBkQXJyYXksCisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaW4gdGhpcyBSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCdzIFggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsJ3MgWSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSBmQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCBhcnJheSB3aGVyZSB0aGUgcmVzdWx0IGFycmF5IHdpbGwgYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaW4gdGhpcworICAgICAqICAgICAgICAgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgZmxvYXQgZkFycmF5W10pIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmdldFBpeGVsKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGZBcnJheSwKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGludGVnZXIgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsJ3MgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwncyBZIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGlBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkgd2hlcmUgdGhlIHJlc3VsdCBhcnJheSB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnRlZ2VyIGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaW4gdGhpcworICAgICAqICAgICAgICAgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSkgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWwuZ2V0UGl4ZWwoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgaUFycmF5LAorICAgICAgICAgICAgICAgIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gZG91YmxlIGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZgorICAgICAqIHBpeGVscyBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gZEFycmF5CisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0aW5nIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIGRvdWJsZSBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiAgICAgICAgIHBpeGVscyBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlW10gZ2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBkb3VibGUgZEFycmF5W10pIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmdldFBpeGVscyh4IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVYLCB5IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVZLCB3LCBoLAorICAgICAgICAgICAgICAgIGRBcnJheSwgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBmbG9hdCBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiBwaXhlbHMgaW4gdGhpcyBSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHJlc3VsdGluZyBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmbG9hdCBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiAgICAgICAgIHBpeGVscyBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGZsb2F0IGZBcnJheVtdKSB7CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRQaXhlbHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwKKyAgICAgICAgICAgICAgICBmQXJyYXksIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gaW50ZWdlciBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiBwaXhlbHMgaW4gdGhpcyByYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHBpeGVsJ3MgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHBpeGVsJ3MgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBpQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRpbmcgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEKKyAgICAgKiAgICAgICAgIG9mIHBpeGVscyBpbiB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgaUFycmF5W10pIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmdldFBpeGVscyh4IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVYLCB5IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVZLCB3LCBoLAorICAgICAgICAgICAgICAgIGlBcnJheSwgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2FtcGxlIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhbgorICAgICAqIGludGVnZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJhbmQuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhbgorICAgICAqICAgICAgICAgaW50ZWdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiKSB7CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRTYW1wbGUoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgYiwKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzYW1wbGUgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIGFzIGEKKyAgICAgKiBkb3VibGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJhbmQuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhCisgICAgICogICAgICAgICBkb3VibGUuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXRTYW1wbGVEb3VibGUoaW50IHgsIGludCB5LCBpbnQgYikgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWwuZ2V0U2FtcGxlRG91YmxlKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGIsCisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2FtcGxlIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhIGZsb2F0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYW5kLgorICAgICAqIEByZXR1cm4gdGhlIHNhbXBsZSBmb3IgdGhlIHNwZWNpZmllZCBiYW5kIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwgYXMgYQorICAgICAqICAgICAgICAgZmxvYXQuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldFNhbXBsZUZsb2F0KGludCB4LCBpbnQgeSwgaW50IGIpIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmdldFNhbXBsZUZsb2F0KHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGIsCisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgU2FtcGxlTW9kZWwgYXNzb2NpYXRlZCB3aXRoIHRoaXMgUmFzdGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFNhbXBsZU1vZGVsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgZ2V0U2FtcGxlTW9kZWwoKSB7CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0cmFuc2xhdGlvbiBvZiB0aGUgWCBjb29yZGluYXRlIGZyb20gdGhlIFNhbXBsZU1vZGVsIGNvb3JkaW5hdGUKKyAgICAgKiBzeXN0ZW0gdG8gdGhlIFJhc3RlcnMncyBjb29yZGluYXRlIHN5c3RlbS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgdHJhbnNsYXRpb24gb2YgdGhlIFggY29vcmRpbmF0ZSBmcm9tIHRoZQorICAgICAqICAgICAgICAgU2FtcGxlTW9kZWwgY29vcmRpbmF0ZSBzeXN0ZW0gdG8gdGhlIFJhc3RlcnMncyBjb29yZGluYXRlIHN5c3RlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWCgpIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsVHJhbnNsYXRlWDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0cmFuc2xhdGlvbiBvZiB0aGUgWSBjb29yZGluYXRlIGZyb20gdGhlIFNhbXBsZU1vZGVsIGNvb3JkaW5hdGUKKyAgICAgKiBzeXN0ZW0gdG8gdGhlIFJhc3RlcnMncyBjb29yZGluYXRlIHN5c3RlbS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgdHJhbnNsYXRpb24gb2YgdGhlIFkgY29vcmRpbmF0ZSBmcm9tIHRoZQorICAgICAqICAgICAgICAgU2FtcGxlTW9kZWwgY29vcmRpbmF0ZSBzeXN0ZW0gdG8gdGhlIFJhc3RlcnMncyBjb29yZGluYXRlIHN5c3RlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsVHJhbnNsYXRlWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCBiYW5kIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscyBpbiB0aGlzIFJhc3RlciBhcyBhIGRvdWJsZSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJhbmQuCisgICAgICogQHBhcmFtIGRBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHJlc3VsdGluZyBkb3VibGUgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZG91YmxlIGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlW10gZ2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGRvdWJsZSBkQXJyYXlbXSkgeworCisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRTYW1wbGVzKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIHcsIGgsCisgICAgICAgICAgICAgICAgYiwgZEFycmF5LCBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmbG9hdCBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzIGluIHRoaXMgUmFzdGVyIGFzIGEgZmxvYXQgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYW5kLgorICAgICAqIEBwYXJhbSBmQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRpbmcgZmxvYXQgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCBiYW5kIG9mIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBmbG9hdCBmQXJyYXlbXSkgeworCisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRTYW1wbGVzKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIHcsIGgsCisgICAgICAgICAgICAgICAgYiwgZkFycmF5LCBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbnRlZ2VyIGFycmF5IG9mIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMgaW4gdGhpcyBSYXN0ZXIgYXMgYSBpbnRlZ2VyIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYmFuZC4KKyAgICAgKiBAcGFyYW0gaUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0aW5nIGludGVnZXIgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQgb2YgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBpbnQgaUFycmF5W10pIHsKKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmdldFNhbXBsZXMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwKKyAgICAgICAgICAgICAgICBiLCBpQXJyYXksIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRyYW5zZmVyIHR5cGUgZm9yIHBpeGVscyBvZiB0aGlzIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAc2VlIFNhbXBsZU1vZGVsI2dldFRyYW5zZmVyVHlwZSgpCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmZXIgdHlwZSBmb3IgcGl4ZWxzIG9mIHRoaXMgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0VHJhbnNmZXJUeXBlKCkgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWwuZ2V0VHJhbnNmZXJUeXBlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2lkdGggb2YgdGhpcyBSYXN0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgd2lkdGggb2YgdGhpcyBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRXaWR0aCgpIHsKKyAgICAgICAgcmV0dXJuIHdpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlIGRhdGEgYnVmZmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhQnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBidWZmZXIuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3LgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaC4KKyAgICAgKiBAcGFyYW0gc2NhbmxpbmVTdHJpZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FubGluZSBzdHJpZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2YWxpZGF0ZURhdGFCdWZmZXIoZmluYWwgRGF0YUJ1ZmZlciBkYXRhQnVmZmVyLCBmaW5hbCBpbnQgdywgZmluYWwgaW50IGgsCisgICAgICAgICAgICBmaW5hbCBpbnQgc2NhbmxpbmVTdHJpZGUpIHsKKyAgICAgICAgaWYgKGRhdGFCdWZmZXIuZ2V0U2l6ZSgpIDwgKHNjYW5saW5lU3RyaWRlICogKGggLSAxKSArIHcgLSAxKSkgeworICAgICAgICAgICAgLy8gYXd0LjI5OD1kYXRhQnVmZmVyIGlzIHRvbyBzbWFsbAorICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yOTgiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9SYXN0ZXJGb3JtYXRFeGNlcHRpb24uamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SYXN0ZXJGb3JtYXRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjY3MTQxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL1Jhc3RlckZvcm1hdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCisvKioKKyAqIFRoZSBSYXN0ZXJGb3JtYXRFeGNlcHRpb24gY2xhc3MgcmVwcmVzZW50cyB0aGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4KKyAqIHRoZXJlJ3MgYW4gaW52YWxpZCBsYXlvdXQgaW4gdGhlIFJhc3Rlci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDk2NTk4OTk2MTE2MTY0MzE1TDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbAorICAgICAqIG1lc3NhZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKFN0cmluZyBzKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1Jhc3Rlck9wLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUmFzdGVyT3AuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOWE4NGM5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL1Jhc3Rlck9wLmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuUmVuZGVyaW5nSGludHM7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CisKKy8qKgorICogVGhlIFJhc3Rlck9wIGludGVyZmFjZSBwcm92aWRlcyBtZXRob2RzIGZvciBwZXJmb3JtaW5nIHRyYW5zZm9ybWF0aW9ucyBmcm9tCisgKiBzb3VyY2UgZGF0YSB0byBkZXN0aW5hdGlvbiBkYXRhIGZvciBSYXN0ZXIgb2JqZWN0cy4gVGhlIHNvdXJjZSBhbmQKKyAqIGRlc3RpbmF0aW9uIG9iamVjdHMgc2hvdWxkIGNvbnRhaW4gdGhlIGFwcHJvcHJpYXRlIG51bWJlciBvZiBiYW5kcyBmb3IgdGhlCisgKiBwYXJ0aWN1bGFyIGNsYXNzZXMgd2hpY2ggaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBSYXN0ZXJPcCB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgZGVzdGluYXRpb24gV3JpdGFibGVSYXN0ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIFJhc3RlcjsgdGhpcworICAgICAqIGRlc3RpbmF0aW9uIGltYWdlIGRhdGEgaXMgZW1wdHkgYW5kIGhhcyB0aGUgY29ycmVjdCBzaXplIGFuZCBudW1iZXIgb2YKKyAgICAgKiBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFJhc3Rlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgY3JlYXRlQ29tcGF0aWJsZURlc3RSYXN0ZXIoUmFzdGVyIHNyYyk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGZpbHRlciBvcGVyYXRpb24gb24gdGhlIHNvdXJjZSBSYXN0ZXIgYW5kIHN0b3JlcyB0aGUgcmVzdWx0aW5nCisgICAgICogaW1hZ2UgZGF0YSB0byB0aGUgZGVzdGluYXRpb24gV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBSYXN0ZXIuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIFdyaXRhYmxlUmFzdGVyLCB3aGVyZSB0aGUgcmVzdWx0IGlzIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXJlZCBXcml0YWJsZVJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgZmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZHMgb2YgdGhlIGZpbHRlcmVkIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFJhc3RlciB0byBiZSBmaWx0ZXJlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWN0YW5nbGUgYm91bmRzIG9mIHRoZSBmaWx0ZXJlZCBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKFJhc3RlciBzcmMpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9pbnQgb2YgdGhlIGRlc3RpbmF0aW9uIGltYWdlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBwb2ludCBpbiB0aGUgc291cmNlIHJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3JjUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBvZiB0aGUgc291cmNlIHJhc3Rlci4KKyAgICAgKiBAcGFyYW0gZHN0UG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCB3aGVyZSB0aGUgcmVzdWx0IHdpbGwgYmUgc3RvcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGRlc3RpbmF0aW9uIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBQb2ludDJEIGdldFBvaW50MkQoUG9pbnQyRCBzcmNQb2ludCwgUG9pbnQyRCBkc3RQb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBSZW5kZXJpbmdIaW50cyBvZiB0aGUgUmFzdGVyT3AuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUmVuZGVyaW5nSGludHMgb2YgdGhlIFJhc3Rlck9wLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJpbmdIaW50cyBnZXRSZW5kZXJpbmdIaW50cygpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1JlbmRlcmVkSW1hZ2UuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SZW5kZXJlZEltYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWVhZmE2NAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SZW5kZXJlZEltYWdlLmphdmEKQEAgLTAsMCArMSwxOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogVGhlIFJlbmRlcmVkSW1hZ2UgaW50ZXJmYWNlIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBieSBhbGwgb2JqZWN0cyB3aGljaAorICogY29udGFpbnMgaW1hZ2UgZGF0YS4gVGhlIGltYWdlIGRhdGEgaXMgcmVwcmVzZW50ZWQgYXMgYSBzaW5nbGUgdGlsZSBvciBhbgorICogYXJyYXkgb2YgdGlsZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFJlbmRlcmVkSW1hZ2UgeworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgZnJvbSB0aGUgcHJvcGVydHkgc2V0IG9mIHRoaXMKKyAgICAgKiBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkncyBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnR5IHZhbHVlIGNvcnJlc3BvbmRlZCB0byB0aGlzIHByb3BlcnR5J3MgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIENvcGllcyB0aGUgcmVnaW9uIG9mIHRoaXMgUmVuZGVyZWRJbWFnZSB0byB0aGUgc3BlY2lmaWVkIFdyaXRhYmxlUmFzdGVyLgorICAgICAqIFRoZSBib3VuZHMgb2YgdGhlIHJlZ2lvbiBhcmUgdGhlIGJvdW5kcyBvZiB0aGUgV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHJhc3RlcgorICAgICAqICAgICAgICAgICAgdGhlIFdyaXRhYmxlUmFzdGVyLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgV3JpdGFibGVSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNvcHlEYXRhKFdyaXRhYmxlUmFzdGVyIHJhc3Rlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbWFnZSBkYXRhIG9mIHRoZSBpbWFnZSdzIHJlZ2lvbiBhcyBvbmUgdGlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVjdAorICAgICAqICAgICAgICAgICAgdGhlIHJlY3Rhbmd1bGFyIHJlZ2lvbiBvZiBSZW5kZXJlZEltYWdlLgorICAgICAqIEByZXR1cm4gdGhlIGltYWdlIGRhdGEgb2YgdGhlIGltYWdlJ3MgcmVnaW9uIGFzIG9uZSB0aWxlLgorICAgICAqLworICAgIHB1YmxpYyBSYXN0ZXIgZ2V0RGF0YShSZWN0YW5nbGUgcmVjdCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCBSZW5kZXJlZEltYWdlIG9iamVjdHMgd2hpY2ggYXJlIHRoZSBzb3VyY2Ugb2YgdGhpcyBSZW5kZXJlZEltYWdlCisgICAgICogb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBWZWN0b3Igb2YgUmVuZGVyZWRJbWFnZSBvYmplY3RzIHdoaWNoIGFyZSB0aGUgc291cmNlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgIFJlbmRlcmVkSW1hZ2Ugb2JqZWN0IG9yIG51bGwsIGlmIHRoZXJlIGlzIG5vIGluZm9ybWF0aW9uIGFib3V0CisgICAgICogICAgICAgICB0aGVtLgorICAgICAqLworICAgIHB1YmxpYyBWZWN0b3I8UmVuZGVyZWRJbWFnZT4gZ2V0U291cmNlcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2V0IG9mIGFsbCBwcm9wZXJ0eSBuYW1lcyBmb3IgdGhpcyBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIGFsbCBwcm9wZXJ0eSBuYW1lcyBmb3IgdGhpcyBSZW5kZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRQcm9wZXJ0eU5hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBTYW1wbGVNb2RlbCBvZiB0aGlzIFJlbmRlcmVkSW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgU2FtcGxlTW9kZWwgb2YgdGhpcyBSZW5kZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTYW1wbGVNb2RlbCBnZXRTYW1wbGVNb2RlbCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGlsZSBjb3JyZXNwb25kZWQgdG8gdGhlIHNwZWNpZmllZCBpbmRpY2VzIGluIHRoZSB0aWxlIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aWxlWAorICAgICAqICAgICAgICAgICAgdGhlIFggaW5kZXggb2YgdGhlIHRpbGUuCisgICAgICogQHBhcmFtIHRpbGVZCisgICAgICogICAgICAgICAgICB0aGUgWSBpbmRleCBvZiB0aGUgdGlsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxlIGNvcnJlc3BvbmRlZCB0byB0aGUgc3BlY2lmaWVkIGluZGljZXMgaW4gdGhlIHRpbGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIFJhc3RlciBnZXRUaWxlKGludCB0aWxlWCwgaW50IHRpbGVZKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGltYWdlIGRhdGEgb2YgdGhpcyBpbWFnZSBhcyBvbmUgdGlsZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBpbWFnZSBkYXRhIG9mIHRoaXMgaW1hZ2UgYXMgb25lIHRpbGUuCisgICAgICovCisgICAgcHVibGljIFJhc3RlciBnZXREYXRhKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBDb2xvck1vZGVsIG9mIHRoaXMgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBDb2xvck1vZGVsIG9mIHRoaXMgUmVuZGVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB3aWR0aCBvZiB0aGUgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aCBvZiB0aGUgUmVuZGVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdpZHRoKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aWxlIHdpZHRoLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRpbGUgd2lkdGggaW4gcGl4ZWxzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VGlsZVdpZHRoKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aWxlIGhlaWdodC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxlIGhlaWdodCBpbiBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaWxlSGVpZ2h0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBZIG9mZnNldCBvZiB0aGUgdGlsZSBncmlkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIFkgb2Zmc2V0IG9mIHRoZSB0aWxlIGdyaWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaWxlR3JpZFlPZmZzZXQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFggb2Zmc2V0IG9mIHRoZSB0aWxlIGdyaWQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgWCBvZmZzZXQgb2YgdGhlIHRpbGUgZ3JpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRpbGVHcmlkWE9mZnNldCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHRpbGVzIGFsb25nIFkgZGlyZWN0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0aWxlcyBhbG9uZyBZIGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bVlUaWxlcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHRpbGVzIGFsb25nIFggZGlyZWN0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0aWxlcyBhbG9uZyBYIGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bVhUaWxlcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSBZIGNvb3JkaW5hdGUgb2YgdGhpcyBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gWSBjb29yZGluYXRlIG9mIHRoaXMgUmVuZGVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1pblkoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0gWCBjb29yZGluYXRlIG9mIHRoaXMgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIFggY29vcmRpbmF0ZSBvZiB0aGlzIFJlbmRlcmVkSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNaW5YKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHRpbGUncyBpbmRleCBhbG9uZyB0aGUgWSBkaXJlY3Rpb24uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSB0aWxlJ3MgaW5kZXggYWxvbmcgdGhlIFkgZGlyZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWluVGlsZVkoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0gdGlsZSdzIGluZGV4IGFsb25nIHRoZSBYIGRpcmVjdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHRpbGUncyBpbmRleCBhbG9uZyB0aGUgWCBkaXJlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNaW5UaWxlWCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhlaWdodCBvZiB0aGUgUmVuZGVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlaWdodCgpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvUmVwbGljYXRlU2NhbGVGaWx0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SZXBsaWNhdGVTY2FsZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxYzBmNDkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUmVwbGljYXRlU2NhbGVGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDIyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIFJlcGxpY2F0ZVNjYWxlRmlsdGVyIGNsYXNzIHNjYWxlcyBhbiBzb3VyY2UgaW1hZ2UgYnkgcmVwbGljYXRpbmcgcm93cyBhbmQKKyAqIGNvbHVtbnMgb2YgcGl4ZWxzIHRvIHNjYWxlIHVwIG9yIG9taXR0aW5nIHJvd3MgYW5kIGNvbHVtbnMgb2YgcGl4ZWxzIHRvIHNjYWxlCisgKiBkb3duLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFJlcGxpY2F0ZVNjYWxlRmlsdGVyIGV4dGVuZHMgSW1hZ2VGaWx0ZXIgeworCisgICAgLyoqCisgICAgICogVGhlIHdpZHRoIG9mIGEgc291cmNlIGltYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgc3JjV2lkdGg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGVpZ2h0IG9mIGEgc291cmNlIGltYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgc3JjSGVpZ2h0OworCisgICAgLyoqCisgICAgICogVGhlIHdpZHRoIG9mIGEgZGVzdGluYXRpb24gaW1hZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBkZXN0V2lkdGg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGVpZ2h0IG9mIGEgZGVzdGluYXRpb24gaW1hZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBkZXN0SGVpZ2h0OworCisgICAgLyoqCisgICAgICogVGhlIGludGVnZXIgYXJyYXkgb2Ygc291cmNlIHJvd3MuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludFtdIHNyY3Jvd3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZWdlciBhcnJheSBvZiBzb3VyY2UgY29sdW1ucy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50W10gc3JjY29sczsKKworICAgIC8qKgorICAgICAqIEFuIE9iamVjdCAoYnl0ZSBhcnJheSB3aXRoIGEgZGVzdGluYXRpb24gd2lkdGgpIHByb3ZpZGVzIGEgcm93IG9mIHBpeGVsCisgICAgICogZGF0YSB0byB0aGUgSW1hZ2VDb25zdW1lci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IG91dHBpeGJ1ZjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBSZXBsaWNhdGVTY2FsZUZpbHRlciB0aGF0IGZpbHRlcnMgdGhlIGltYWdlIHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIHdpZHRoIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2Ygc2NhbGVkIGltYWdlLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2Ygc2NhbGVkIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBSZXBsaWNhdGVTY2FsZUZpbHRlcihpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgaWYgKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMzQ9V2lkdGggb3IgSGVpZ2h0IGVxdWFscyB6ZXJvCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5kZXN0V2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5kZXN0SGVpZ2h0ID0gaGVpZ2h0OworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnRpZXMoSGFzaHRhYmxlPD8sID8+IHByb3BzKSB7CisgICAgICAgIEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4gZnByb3BzOworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCkgeworICAgICAgICAgICAgZnByb3BzID0gbmV3IEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZwcm9wcyA9IChIYXNodGFibGU8T2JqZWN0LCBPYmplY3Q+KXByb3BzLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gIlJlc2NhbGUgRmlsdGVycyI7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIHByb3AgPSAiZGVzdFdpZHRoPSIgKyBkZXN0V2lkdGggKyAiOyAiICsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgImRlc3RIZWlnaHQ9IiArIGRlc3RIZWlnaHQ7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgT2JqZWN0IG8gPSBmcHJvcHMuZ2V0KHByb3BOYW1lKTsKKyAgICAgICAgaWYgKG8gIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgICAgICAgICAgICBwcm9wID0gKFN0cmluZylvICsgIjsgIiArIHByb3A7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHJvcCA9IG8udG9TdHJpbmcoKSArICI7ICIgKyBwcm9wOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZnByb3BzLnB1dChwcm9wTmFtZSwgcHJvcCk7CisgICAgICAgIGNvbnN1bWVyLnNldFByb3BlcnRpZXMoZnByb3BzKTsKKyAgICB9CisKKyAgICAvLyBzZXRQaXhlbHMgbWV0aG9kcyBwcm9kdWNlIHBpeGVscyBhY2NvcmRpbmcgdG8gSmF2YSBBUEkgU3BhY2lmaWNhdGlvbgorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBDb2xvck1vZGVsIG1vZGVsLCBpbnRbXSBwaXhlbHMsIGludCBvZmYsCisgICAgICAgICAgICBpbnQgc2NhbnNpemUpIHsKKworICAgICAgICBpZiAoc3JjY29scyA9PSBudWxsKSB7CisgICAgICAgICAgICBpbml0QXJyYXlzKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ1ZmZbXTsKKyAgICAgICAgaWYgKG91dHBpeGJ1ZiA9PSBudWxsIHx8ICEob3V0cGl4YnVmIGluc3RhbmNlb2YgaW50W10pKSB7CisgICAgICAgICAgICBidWZmID0gbmV3IGludFtkZXN0V2lkdGhdOworICAgICAgICAgICAgb3V0cGl4YnVmID0gYnVmZjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ1ZmYgPSAoaW50W10pb3V0cGl4YnVmOworICAgICAgICB9CisKKyAgICAgICAgaW50IHdhID0gKHNyY1dpZHRoIC0gMSkgPj4+IDE7CisgICAgICAgIGludCBoYSA9IChzcmNIZWlnaHQgLSAxKSA+Pj4gMTsKKyAgICAgICAgaW50IGRzdFggPSAoeCAqIGRlc3RXaWR0aCArIHdhKSAvIHNyY1dpZHRoOworICAgICAgICBpbnQgZHN0WSA9ICh5ICogZGVzdEhlaWdodCArIGhhKSAvIHNyY0hlaWdodDsKKworICAgICAgICBpbnQgc3gsIHN5LCBkeCwgZHk7CisgICAgICAgIGR5ID0gZHN0WTsKKyAgICAgICAgd2hpbGUgKChkeSA8IGRlc3RIZWlnaHQpICYmICgoc3kgPSBzcmNyb3dzW2R5XSkgPCB5ICsgaCkpIHsKKyAgICAgICAgICAgIGR4ID0gZHN0WDsKKyAgICAgICAgICAgIGludCBzcmNPZmYgPSBvZmYgKyAoc3kgLSB5KSAqIHNjYW5zaXplOworICAgICAgICAgICAgd2hpbGUgKChkeCA8IGRlc3RXaWR0aCkgJiYgKChzeCA9IHNyY2NvbHNbZHhdKSA8IHggKyB3KSkgeworICAgICAgICAgICAgICAgIGJ1ZmZbZHhdID0gcGl4ZWxzW3NyY09mZiArIChzeCAtIHgpXTsKKyAgICAgICAgICAgICAgICBkeCsrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjb25zdW1lci5zZXRQaXhlbHMoZHN0WCwgZHksIGR4IC0gZHN0WCwgMSwgbW9kZWwsIGJ1ZmYsIGRzdFgsIGRlc3RXaWR0aCk7CisgICAgICAgICAgICBkeSsrOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBDb2xvck1vZGVsIG1vZGVsLCBieXRlW10gcGl4ZWxzLCBpbnQgb2ZmLAorICAgICAgICAgICAgaW50IHNjYW5zaXplKSB7CisKKyAgICAgICAgaWYgKHNyY2NvbHMgPT0gbnVsbCkgeworICAgICAgICAgICAgaW5pdEFycmF5cygpOworICAgICAgICB9CisgICAgICAgIGJ5dGUgYnVmZltdOworICAgICAgICBpZiAob3V0cGl4YnVmID09IG51bGwgfHwgIShvdXRwaXhidWYgaW5zdGFuY2VvZiBieXRlW10pKSB7CisgICAgICAgICAgICBidWZmID0gbmV3IGJ5dGVbZGVzdFdpZHRoXTsKKyAgICAgICAgICAgIG91dHBpeGJ1ZiA9IGJ1ZmY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWZmID0gKGJ5dGVbXSlvdXRwaXhidWY7CisgICAgICAgIH0KKworICAgICAgICBpbnQgd2EgPSAoc3JjV2lkdGggLSAxKSA+Pj4gMTsKKyAgICAgICAgaW50IGhhID0gKHNyY0hlaWdodCAtIDEpID4+PiAxOworICAgICAgICBpbnQgZHN0WCA9ICh4ICogZGVzdFdpZHRoICsgd2EpIC8gc3JjV2lkdGg7CisgICAgICAgIGludCBkc3RZID0gKHkgKiBkZXN0SGVpZ2h0ICsgaGEpIC8gc3JjSGVpZ2h0OworCisgICAgICAgIGludCBzeCwgc3ksIGR4LCBkeTsKKyAgICAgICAgZHkgPSBkc3RZOworICAgICAgICB3aGlsZSAoKGR5IDwgZGVzdEhlaWdodCkgJiYgKChzeSA9IHNyY3Jvd3NbZHldKSA8IHkgKyBoKSkgeworICAgICAgICAgICAgZHggPSBkc3RYOworICAgICAgICAgICAgaW50IHNyY09mZiA9IG9mZiArIChzeSAtIHkpICogc2NhbnNpemU7CisgICAgICAgICAgICB3aGlsZSAoKGR4IDwgZGVzdFdpZHRoKSAmJiAoKHN4ID0gc3JjY29sc1tkeF0pIDwgeCArIHcpKSB7CisgICAgICAgICAgICAgICAgYnVmZltkeF0gPSBwaXhlbHNbc3JjT2ZmICsgKHN4IC0geCldOworICAgICAgICAgICAgICAgIGR4Kys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNvbnN1bWVyLnNldFBpeGVscyhkc3RYLCBkeSwgZHggLSBkc3RYLCAxLCBtb2RlbCwgYnVmZiwgZHN0WCwgZGVzdFdpZHRoKTsKKyAgICAgICAgICAgIGR5Kys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREaW1lbnNpb25zKGludCB3LCBpbnQgaCkgeworICAgICAgICBzcmNXaWR0aCA9IHc7CisgICAgICAgIHNyY0hlaWdodCA9IGg7CisKKyAgICAgICAgaWYgKGRlc3RXaWR0aCA8IDAgJiYgZGVzdEhlaWdodCA8IDApIHsKKyAgICAgICAgICAgIGRlc3RXaWR0aCA9IHNyY1dpZHRoOworICAgICAgICAgICAgZGVzdEhlaWdodCA9IHNyY0hlaWdodDsKKyAgICAgICAgfSBlbHNlIGlmIChkZXN0V2lkdGggPCAwKSB7CisgICAgICAgICAgICBkZXN0V2lkdGggPSBkZXN0SGVpZ2h0ICogc3JjV2lkdGggLyBzcmNIZWlnaHQ7CisgICAgICAgIH0gZWxzZSBpZiAoZGVzdEhlaWdodCA8IDApIHsKKyAgICAgICAgICAgIGRlc3RIZWlnaHQgPSBkZXN0V2lkdGggKiBzcmNIZWlnaHQgLyBzcmNXaWR0aDsKKyAgICAgICAgfQorICAgICAgICBjb25zdW1lci5zZXREaW1lbnNpb25zKGRlc3RXaWR0aCwgZGVzdEhlaWdodCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6YXRpb24gb2Ygc3JjY29scyBhbmQgc3Jjcm93cyBhcnJheXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluaXRBcnJheXMoKSB7CisgICAgICAgIGlmICgoZGVzdFdpZHRoIDwgMCkgfHwgKGRlc3RIZWlnaHQgPCAwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHNyY2NvbHMgPSBuZXcgaW50W2Rlc3RXaWR0aF07CisgICAgICAgIGludCBjYSA9IHNyY1dpZHRoID4+PiAxOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc3RXaWR0aDsgaSsrKSB7CisgICAgICAgICAgICBzcmNjb2xzW2ldID0gKGkgKiBzcmNXaWR0aCArIGNhKSAvIGRlc3RXaWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIHNyY3Jvd3MgPSBuZXcgaW50W2Rlc3RIZWlnaHRdOworICAgICAgICBpbnQgcmEgPSBzcmNIZWlnaHQgPj4+IDE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzdEhlaWdodDsgaSsrKSB7CisgICAgICAgICAgICBzcmNyb3dzW2ldID0gKGkgKiBzcmNIZWlnaHQgKyByYSkgLyBkZXN0SGVpZ2h0OworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvUmVzY2FsZU9wLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvUmVzY2FsZU9wLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdlMmJkNwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9SZXNjYWxlT3AuamF2YQpAQCAtMCwwICsxLDY1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKgorICogQGRhdGU6IE9jdCA2LCAyMDA1CisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0Lmdlb20uUG9pbnQyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBDbGFzcyBSZXNjYWxlT3AgcGVyZm9ybXMgcmVzY2FsaW5nIG9mIHRoZSBzb3VyY2UgaW1hZ2UgZGF0YSBieQorICogbXVsdGlwbHlpbmcgdGhlIHBpeGVsIHZhbHVlcyB3aXRoIGEgc2NhbGUgZmFjdG9yIGFuZCB0aGVuIGFkZGluZyBhbiBvZmZzZXQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmVzY2FsZU9wIGltcGxlbWVudHMgQnVmZmVyZWRJbWFnZU9wLCBSYXN0ZXJPcCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2NhbGUgZmFjdG9ycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IHNjYWxlRmFjdG9yc1tdOworCisgICAgLyoqCisgICAgICogVGhlIG9mZnNldHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBvZmZzZXRzW107CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGludHMuCisgICAgICovCisgICAgcHJpdmF0ZSBSZW5kZXJpbmdIaW50cyBoaW50czsKKworICAgIHN0YXRpYyB7CisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gU3lzdGVtLmxvYWRMaWJyYXJ5KCJpbWFnZW9wcyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBSZXNjYWxlT3Agb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBzY2FsZSBmYWN0b3JzIGFuZAorICAgICAqIG9mZnNldHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNjYWxlRmFjdG9ycworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHNjYWxlIGZhY3RvciB2YWx1ZXMuCisgICAgICogQHBhcmFtIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBvZmZzZXQgdmFsdWVzLgorICAgICAqIEBwYXJhbSBoaW50cworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmluZ0hpbnRzIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIFJlc2NhbGVPcChmbG9hdFtdIHNjYWxlRmFjdG9ycywgZmxvYXRbXSBvZmZzZXRzLCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICBpbnQgbnVtRmFjdG9ycyA9IE1hdGgubWluKHNjYWxlRmFjdG9ycy5sZW5ndGgsIG9mZnNldHMubGVuZ3RoKTsKKworICAgICAgICB0aGlzLnNjYWxlRmFjdG9ycyA9IG5ldyBmbG9hdFtudW1GYWN0b3JzXTsKKyAgICAgICAgdGhpcy5vZmZzZXRzID0gbmV3IGZsb2F0W251bUZhY3RvcnNdOworCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2NhbGVGYWN0b3JzLCAwLCB0aGlzLnNjYWxlRmFjdG9ycywgMCwgbnVtRmFjdG9ycyk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2Zmc2V0cywgMCwgdGhpcy5vZmZzZXRzLCAwLCBudW1GYWN0b3JzKTsKKworICAgICAgICB0aGlzLmhpbnRzID0gaGludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFJlc2NhbGVPcCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIHNjYWxlIGZhY3RvciBhbmQKKyAgICAgKiBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIHNjYWxlRmFjdG9yCisgICAgICogICAgICAgICAgICB0aGUgc2NhbGUgZmFjdG9yLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgUmVuZGVyaW5nSGludHMgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzY2FsZU9wKGZsb2F0IHNjYWxlRmFjdG9yLCBmbG9hdCBvZmZzZXQsIFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHNjYWxlRmFjdG9ycyA9IG5ldyBmbG9hdFsxXTsKKyAgICAgICAgb2Zmc2V0cyA9IG5ldyBmbG9hdFsxXTsKKworICAgICAgICBzY2FsZUZhY3RvcnNbMF0gPSBzY2FsZUZhY3RvcjsKKyAgICAgICAgb2Zmc2V0c1swXSA9IG9mZnNldDsKKworICAgICAgICB0aGlzLmhpbnRzID0gaGludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHNjYWxpbmcgZmFjdG9ycy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygc2NhbGluZyBmYWN0b3JzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtRmFjdG9ycygpIHsKKyAgICAgICAgcmV0dXJuIHNjYWxlRmFjdG9ycy5sZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlbmRlcmluZ0hpbnRzIGdldFJlbmRlcmluZ0hpbnRzKCkgeworICAgICAgICByZXR1cm4gaGludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2NhbGUgZmFjdG9ycyBvZiB0aGlzIFJlc2NhbGVPcC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2NhbGVGYWN0b3JzCisgICAgICogICAgICAgICAgICB0aGUgZGVzaXJlZCBzY2FsZSBmYWN0b3JzIGFycmF5IHdpbGwgYmUgY29waWVkIHRvIHRoaXMgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgc2NhbGUgZmFjdG9ycyBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgZmxvYXRbXSBnZXRTY2FsZUZhY3RvcnMoZmxvYXRbXSBzY2FsZUZhY3RvcnMpIHsKKyAgICAgICAgaWYgKHNjYWxlRmFjdG9ycyA9PSBudWxsKSB7CisgICAgICAgICAgICBzY2FsZUZhY3RvcnMgPSBuZXcgZmxvYXRbdGhpcy5zY2FsZUZhY3RvcnMubGVuZ3RoXTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBtaW5MZW5ndGggPSBNYXRoLm1pbihzY2FsZUZhY3RvcnMubGVuZ3RoLCB0aGlzLnNjYWxlRmFjdG9ycy5sZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuc2NhbGVGYWN0b3JzLCAwLCBzY2FsZUZhY3RvcnMsIDAsIG1pbkxlbmd0aCk7CisgICAgICAgIHJldHVybiBzY2FsZUZhY3RvcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2Zmc2V0cyBhcnJheSBvZiB0aGlzIFJlc2NhbGVPcC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGRlc2lyZWQgb2Zmc2V0cyBhcnJheSB3aWxsIGJlIGNvcGllZCB0byB0aGlzIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldHMgYXJyYXkgb2YgdGhpcyBSZXNjYWxlT3AuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGZsb2F0W10gZ2V0T2Zmc2V0cyhmbG9hdFtdIG9mZnNldHMpIHsKKyAgICAgICAgaWYgKG9mZnNldHMgPT0gbnVsbCkgeworICAgICAgICAgICAgb2Zmc2V0cyA9IG5ldyBmbG9hdFt0aGlzLm9mZnNldHMubGVuZ3RoXTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBtaW5MZW5ndGggPSBNYXRoLm1pbihvZmZzZXRzLmxlbmd0aCwgdGhpcy5vZmZzZXRzLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5vZmZzZXRzLCAwLCBvZmZzZXRzLCAwLCBtaW5MZW5ndGgpOworICAgICAgICByZXR1cm4gb2Zmc2V0czsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgUG9pbnQyRCBnZXRQb2ludDJEKFBvaW50MkQgc3JjUHQsIFBvaW50MkQgZHN0UHQpIHsKKyAgICAgICAgaWYgKGRzdFB0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdFB0ID0gbmV3IFBvaW50MkQuRmxvYXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGRzdFB0LnNldExvY2F0aW9uKHNyY1B0KTsKKyAgICAgICAgcmV0dXJuIGRzdFB0OworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBSZWN0YW5nbGUyRCBnZXRCb3VuZHMyRChSYXN0ZXIgc3JjKSB7CisgICAgICAgIHJldHVybiBzcmMuZ2V0Qm91bmRzKCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKEJ1ZmZlcmVkSW1hZ2Ugc3JjKSB7CisgICAgICAgIHJldHVybiBnZXRCb3VuZHMyRChzcmMuZ2V0UmFzdGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyBXcml0YWJsZVJhc3RlciBjcmVhdGVDb21wYXRpYmxlRGVzdFJhc3RlcihSYXN0ZXIgc3JjKSB7CisgICAgICAgIHJldHVybiBzcmMuY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKCk7CisgICAgfQorCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2UgY3JlYXRlQ29tcGF0aWJsZURlc3RJbWFnZShCdWZmZXJlZEltYWdlIHNyYywgQ29sb3JNb2RlbCBkc3RDTSkgeworICAgICAgICBpZiAoZHN0Q00gPT0gbnVsbCkgeworICAgICAgICAgICAgZHN0Q00gPSBzcmMuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRzdENNIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKSB7CisgICAgICAgICAgICBkc3RDTSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICB9CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgciA9IGRzdENNLmlzQ29tcGF0aWJsZVNhbXBsZU1vZGVsKHNyYy5nZXRTYW1wbGVNb2RlbCgpKSA/IHNyYy5nZXRSYXN0ZXIoKQorICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSkgOiBkc3RDTQorICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlKGRzdENNLCByLCBkc3RDTS5pc0FscGhhUHJlbXVsdGlwbGllZCgpLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgV3JpdGFibGVSYXN0ZXIgZmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCkgeworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0UmFzdGVyKHNyYyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoc3JjLmdldE51bUJhbmRzKCkgIT0gZHN0LmdldE51bUJhbmRzKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjFEPU51bWJlciBvZiBzcmMgYmFuZHMgKHswfSkgZG9lcyBub3QgbWF0Y2ggbnVtYmVyIG9mCisgICAgICAgICAgICAgICAgLy8gZHN0IGJhbmRzICh7MX0pCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUQiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICBzcmMuZ2V0TnVtQmFuZHMoKSwgZHN0LmdldE51bUJhbmRzKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGlzLnNjYWxlRmFjdG9ycy5sZW5ndGggIT0gMSAmJiB0aGlzLnNjYWxlRmFjdG9ycy5sZW5ndGggIT0gc3JjLmdldE51bUJhbmRzKCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMUU9TnVtYmVyIG9mIHNjYWxpbmcgY29uc3RhbnRzIGlzIG5vdCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mCisgICAgICAgICAgICAvLyBiYW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gaWYgKGlwcEZpbHRlcihzcmMsIGRzdCwgQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTSwgZmFsc2UpICE9IDApCisgICAgICAgIGlmIChzbG93RmlsdGVyKHNyYywgZHN0LCBmYWxzZSkgIT0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIxRj1VbmFibGUgdG8gdHJhbnNmb3JtIHNvdXJjZQorICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdpbmdPcEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2xvdyBmaWx0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAqIEBwYXJhbSBza2lwQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBza2lwIGFscGhhLgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBzbG93RmlsdGVyKFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCwgYm9vbGVhbiBza2lwQWxwaGEpIHsKKyAgICAgICAgU2FtcGxlTW9kZWwgc20gPSBzcmMuZ2V0U2FtcGxlTW9kZWwoKTsKKworICAgICAgICBpbnQgbnVtQmFuZHMgPSBzcmMuZ2V0TnVtQmFuZHMoKTsKKyAgICAgICAgaW50IHNyY0hlaWdodCA9IHNyYy5nZXRIZWlnaHQoKTsKKyAgICAgICAgaW50IHNyY1dpZHRoID0gc3JjLmdldFdpZHRoKCk7CisKKyAgICAgICAgaW50IHNyY01pblggPSBzcmMuZ2V0TWluWCgpOworICAgICAgICBpbnQgc3JjTWluWSA9IHNyYy5nZXRNaW5ZKCk7CisgICAgICAgIGludCBkc3RNaW5YID0gZHN0LmdldE1pblgoKTsKKyAgICAgICAgaW50IGRzdE1pblkgPSBkc3QuZ2V0TWluWSgpOworCisgICAgICAgIGludFtdIG1heFZhbHVlcyA9IG5ldyBpbnRbbnVtQmFuZHNdOworICAgICAgICBpbnRbXSBtYXNrcyA9IG5ldyBpbnRbbnVtQmFuZHNdOworICAgICAgICBpbnRbXSBzYW1wbGVTaXplcyA9IHNtLmdldFNhbXBsZVNpemUoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIG1heFZhbHVlc1tpXSA9ICgxIDw8IHNhbXBsZVNpemVzW2ldKSAtIDE7CisgICAgICAgICAgICBtYXNrc1tpXSA9IH4obWF4VmFsdWVzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFByb2Nlc3NpbmcgYm91bmRzCisgICAgICAgIGZsb2F0W10gcGl4ZWxzID0gbnVsbDsKKyAgICAgICAgcGl4ZWxzID0gc3JjLmdldFBpeGVscyhzcmNNaW5YLCBzcmNNaW5ZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBwaXhlbHMpOworCisgICAgICAgIC8vIEN5Y2xlIG92ZXIgcGl4ZWxzIHRvIGJlIGNhbGN1bGF0ZWQKKyAgICAgICAgaWYgKHNraXBBbHBoYSkgeyAvLyBBbHdheXMgc3VwcG9zZSB0aGF0IGFscGhhIGNoYW5uZWwgaXMgdGhlIGxhc3QgYmFuZAorICAgICAgICAgICAgaWYgKHNjYWxlRmFjdG9ycy5sZW5ndGggPiAxKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwaXhlbHMubGVuZ3RoOykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBiYW5kSWR4ID0gMDsgYmFuZElkeCA8IG51bUJhbmRzIC0gMTsgYmFuZElkeCsrLCBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpXSA9IHBpeGVsc1tpXSAqIHNjYWxlRmFjdG9yc1tiYW5kSWR4XSArIG9mZnNldHNbYmFuZElkeF07CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3Igb3ZlcmZsb3cgbm93CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChpbnQpcGl4ZWxzW2ldICYgbWFza3NbYmFuZElkeF0pICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGl4ZWxzW2ldIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSAwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpXSA9IG1heFZhbHVlc1tiYW5kSWR4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7KSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGJhbmRJZHggPSAwOyBiYW5kSWR4IDwgbnVtQmFuZHMgLSAxOyBiYW5kSWR4KyssIGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gcGl4ZWxzW2ldICogc2NhbGVGYWN0b3JzWzBdICsgb2Zmc2V0c1swXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBvdmVyZmxvdyBub3cKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKGludClwaXhlbHNbaV0gJiBtYXNrc1tiYW5kSWR4XSkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaXhlbHNbaV0gPCAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpXSA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gbWF4VmFsdWVzW2JhbmRJZHhdOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoc2NhbGVGYWN0b3JzLmxlbmd0aCA+IDEpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7KSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGJhbmRJZHggPSAwOyBiYW5kSWR4IDwgbnVtQmFuZHM7IGJhbmRJZHgrKywgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSBwaXhlbHNbaV0gKiBzY2FsZUZhY3RvcnNbYmFuZElkeF0gKyBvZmZzZXRzW2JhbmRJZHhdOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93IG5vdworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoaW50KXBpeGVsc1tpXSAmIG1hc2tzW2JhbmRJZHhdKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpeGVsc1tpXSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSBtYXhWYWx1ZXNbYmFuZElkeF07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7KSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGJhbmRJZHggPSAwOyBiYW5kSWR4IDwgbnVtQmFuZHM7IGJhbmRJZHgrKywgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSBwaXhlbHNbaV0gKiBzY2FsZUZhY3RvcnNbMF0gKyBvZmZzZXRzWzBdOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93IG5vdworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoaW50KXBpeGVsc1tpXSAmIG1hc2tzW2JhbmRJZHhdKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpeGVsc1tpXSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSBtYXhWYWx1ZXNbYmFuZElkeF07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZHN0LnNldFBpeGVscyhkc3RNaW5YLCBkc3RNaW5ZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBwaXhlbHMpOworCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBCdWZmZXJlZEltYWdlIGZpbHRlcihCdWZmZXJlZEltYWdlIHNyYywgQnVmZmVyZWRJbWFnZSBkc3QpIHsKKyAgICAgICAgQ29sb3JNb2RlbCBzcmNDTSA9IHNyYy5nZXRDb2xvck1vZGVsKCk7CisKKyAgICAgICAgaWYgKHNyY0NNIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKSB7CisgICAgICAgICAgICAvLyBhd3QuMjIwPVNvdXJjZSBzaG91bGQgbm90IGhhdmUgSW5kZXhDb2xvck1vZGVsCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIyMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG51bWJlciBvZiBzY2FsaW5nIGZhY3RvcnMgbWF0Y2hlcyB0aGUgbnVtYmVyIG9mIGJhbmRzCisgICAgICAgIGludCBuQ29tcG9uZW50cyA9IHNyY0NNLmdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgYm9vbGVhbiBza2lwQWxwaGE7CisgICAgICAgIGlmIChzcmNDTS5oYXNBbHBoYSgpKSB7CisgICAgICAgICAgICBpZiAoc2NhbGVGYWN0b3JzLmxlbmd0aCA9PSAxIHx8IHNjYWxlRmFjdG9ycy5sZW5ndGggPT0gbkNvbXBvbmVudHMgLSAxKSB7CisgICAgICAgICAgICAgICAgc2tpcEFscGhhID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoc2NhbGVGYWN0b3JzLmxlbmd0aCA9PSBuQ29tcG9uZW50cykgeworICAgICAgICAgICAgICAgIHNraXBBbHBoYSA9IGZhbHNlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjFFPU51bWJlciBvZiBzY2FsaW5nIGNvbnN0YW50cyBpcyBub3QgZXF1YWwgdG8gdGhlCisgICAgICAgICAgICAgICAgLy8gbnVtYmVyIG9mIGJhbmRzCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMUUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChzY2FsZUZhY3RvcnMubGVuZ3RoID09IDEgfHwgc2NhbGVGYWN0b3JzLmxlbmd0aCA9PSBuQ29tcG9uZW50cykgeworICAgICAgICAgICAgc2tpcEFscGhhID0gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBhd3QuMjFFPU51bWJlciBvZiBzY2FsaW5nIGNvbnN0YW50cyBpcyBub3QgZXF1YWwgdG8gdGhlIG51bWJlciBvZgorICAgICAgICAgICAgLy8gYmFuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjFFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBCdWZmZXJlZEltYWdlIGZpbmFsRHN0ID0gbnVsbDsKKyAgICAgICAgaWYgKGRzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbERzdCA9IGRzdDsKKyAgICAgICAgICAgIGRzdCA9IGNyZWF0ZUNvbXBhdGlibGVEZXN0SW1hZ2Uoc3JjLCBzcmNDTSk7CisgICAgICAgIH0gZWxzZSBpZiAoIXNyY0NNLmVxdWFscyhkc3QuZ2V0Q29sb3JNb2RlbCgpKSkgeworICAgICAgICAgICAgLy8gVHJlYXQgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0IgYW5kIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQgorICAgICAgICAgICAgLy8gYXMgc2FtZQorICAgICAgICAgICAgaWYgKCEoKHNyYy5nZXRUeXBlKCkgPT0gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9SR0IgfHwgc3JjLmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0IpICYmIChkc3QKKyAgICAgICAgICAgICAgICAgICAgLmdldFR5cGUoKSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQiB8fCBkc3QuZ2V0VHlwZSgpID09IEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQikpKSB7CisgICAgICAgICAgICAgICAgZmluYWxEc3QgPSBkc3Q7CisgICAgICAgICAgICAgICAgZHN0ID0gY3JlYXRlQ29tcGF0aWJsZURlc3RJbWFnZShzcmMsIHNyY0NNKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gaWYgKGlwcEZpbHRlcihzcmMuZ2V0UmFzdGVyKCksIGRzdC5nZXRSYXN0ZXIoKSwgc3JjLmdldFR5cGUoKSwKKyAgICAgICAgLy8gc2tpcEFscGhhKSAhPSAwKQorICAgICAgICBpZiAoc2xvd0ZpbHRlcihzcmMuZ2V0UmFzdGVyKCksIGRzdC5nZXRSYXN0ZXIoKSwgc2tpcEFscGhhKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMjFGPVVuYWJsZSB0byB0cmFuc2Zvcm0gc291cmNlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2luZ09wRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxRiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKGZpbmFsRHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIEdyYXBoaWNzMkQgZyA9IGZpbmFsRHN0LmNyZWF0ZUdyYXBoaWNzKCk7CisgICAgICAgICAgICBnLnNldENvbXBvc2l0ZShBbHBoYUNvbXBvc2l0ZS5TcmMpOworICAgICAgICAgICAgZy5kcmF3SW1hZ2UoZHN0LCAwLCAwLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpbmFsRHN0ID0gZHN0OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZpbmFsRHN0OworICAgIH0KKworICAgIC8vIERvbid0IGZvcmdldCB0byBwYXNzIGFsbG9jYXRlZCBhcnJheXMgZm9yIGxldmVscyBhbmQgdmFsdWVzLCBzaXplIHNob3VsZAorICAgIC8vIGJlIG51bUJhbmRzKjQKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBsZXZlbHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNtCisgICAgICogICAgICAgICAgICB0aGUgc20uCisgICAgICogQHBhcmFtIG51bUJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtIGJhbmRzLgorICAgICAqIEBwYXJhbSBza2lwQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBza2lwIGFscGhhLgorICAgICAqIEBwYXJhbSBsZXZlbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbHMuCisgICAgICogQHBhcmFtIHZhbHVlcworICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlcy4KKyAgICAgKiBAcGFyYW0gY2hhbm5lbHNPcmRlcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYW5uZWxzIG9yZGVyLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgdm9pZCBjcmVhdGVMZXZlbHMoU2FtcGxlTW9kZWwgc20sIGludCBudW1CYW5kcywgYm9vbGVhbiBza2lwQWxwaGEsIGludCBsZXZlbHNbXSwKKyAgICAgICAgICAgIGludCB2YWx1ZXNbXSwgaW50IGNoYW5uZWxzT3JkZXJbXSkgeworICAgICAgICAvLyBTdXBwb3NlIHNhbWUgc2FtcGxlIHNpemUgZm9yIGFsbCBjaGFubmVscywgb3RoZXJ3aXNlIHVzZSBzbG93IGZpbHRlcgorICAgICAgICBpbnQgbWF4VmFsdWUgPSAoMSA8PCBzbS5nZXRTYW1wbGVTaXplKDApKSAtIDE7CisKKyAgICAgICAgLy8gRm9yIHNpbXBsaWNpdHkgaW50cm9kdWNlIHRoZXNlIGFycmF5cworICAgICAgICBmbG9hdCBleHRTY2FsZUZhY3RvcnNbXSA9IG5ldyBmbG9hdFtudW1CYW5kc107CisgICAgICAgIGZsb2F0IGV4dE9mZnNldHNbXSA9IG5ldyBmbG9hdFtudW1CYW5kc107CisKKyAgICAgICAgaWYgKHNjYWxlRmFjdG9ycy5sZW5ndGggIT0gMSkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzY2FsZUZhY3RvcnMsIDAsIGV4dFNjYWxlRmFjdG9ycywgMCwgc2NhbGVGYWN0b3JzLmxlbmd0aCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9mZnNldHMsIDAsIGV4dE9mZnNldHMsIDAsIHNjYWxlRmFjdG9ycy5sZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICAgICAgZXh0U2NhbGVGYWN0b3JzW2ldID0gc2NhbGVGYWN0b3JzWzBdOworICAgICAgICAgICAgICAgIGV4dE9mZnNldHNbaV0gPSBvZmZzZXRzWzBdOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHNraXBBbHBoYSkgeworICAgICAgICAgICAgZXh0U2NhbGVGYWN0b3JzW251bUJhbmRzIC0gMV0gPSAxOworICAgICAgICAgICAgZXh0T2Zmc2V0c1tudW1CYW5kcyAtIDFdID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENyZWF0ZSBhIGxldmVscworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChleHRTY2FsZUZhY3RvcnNbaV0gPT0gMCkgeworICAgICAgICAgICAgICAgIGxldmVsc1tpICogNF0gPSAwOworICAgICAgICAgICAgICAgIGxldmVsc1tpICogNCArIDFdID0gMDsKKyAgICAgICAgICAgICAgICBsZXZlbHNbaSAqIDQgKyAyXSA9IG1heFZhbHVlICsgMTsKKyAgICAgICAgICAgICAgICBsZXZlbHNbaSAqIDQgKyAzXSA9IG1heFZhbHVlICsgMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmxvYXQgbWluTGV2ZWwgPSAtZXh0T2Zmc2V0c1tpXSAvIGV4dFNjYWxlRmFjdG9yc1tpXTsKKyAgICAgICAgICAgIGZsb2F0IG1heExldmVsID0gKG1heFZhbHVlIC0gZXh0T2Zmc2V0c1tpXSkgLyBleHRTY2FsZUZhY3RvcnNbaV07CisKKyAgICAgICAgICAgIGlmIChtaW5MZXZlbCA8IDApIHsKKyAgICAgICAgICAgICAgICBtaW5MZXZlbCA9IDA7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1pbkxldmVsID4gbWF4VmFsdWUpIHsKKyAgICAgICAgICAgICAgICBtaW5MZXZlbCA9IG1heFZhbHVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWF4TGV2ZWwgPCAwKSB7CisgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChtYXhMZXZlbCA+IG1heFZhbHVlKSB7CisgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBtYXhWYWx1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbGV2ZWxzW2kgKiA0XSA9IDA7CisgICAgICAgICAgICBpZiAobWluTGV2ZWwgPiBtYXhMZXZlbCkgeworICAgICAgICAgICAgICAgIGxldmVsc1tpICogNCArIDFdID0gKGludCltYXhMZXZlbDsKKyAgICAgICAgICAgICAgICBsZXZlbHNbaSAqIDQgKyAyXSA9IChpbnQpbWluTGV2ZWw7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGxldmVsc1tpICogNCArIDFdID0gKGludCltaW5MZXZlbDsKKyAgICAgICAgICAgICAgICBsZXZlbHNbaSAqIDQgKyAyXSA9IChpbnQpbWF4TGV2ZWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsZXZlbHNbaSAqIDQgKyAzXSA9IG1heFZhbHVlICsgMTsKKworICAgICAgICAgICAgLy8gRmlsbCB2YWx1ZXMKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgNDsgaysrKSB7CisgICAgICAgICAgICAgICAgaW50IGlkeCA9IGkgKiA0ICsgazsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbaWR4XSA9IChpbnQpKGV4dFNjYWxlRmFjdG9yc1tpXSAqIGxldmVsc1tpZHhdICsgZXh0T2Zmc2V0c1tpXSk7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlc1tpZHhdIDwgMCkgeworICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbaWR4XSA9IDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZXNbaWR4XSA+IG1heFZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tpZHhdID0gbWF4VmFsdWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVvcmRlciBkYXRhIGlmIGNoYW5uZWxzIGFyZSBzdG9yZWQgaW4gZGlmZmVyZW50IG9yZGVyCisgICAgICAgIGlmIChjaGFubmVsc09yZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBsZW4gPSBudW1CYW5kcyAqIDQ7CisgICAgICAgICAgICBpbnQgc2F2ZWRMZXZlbHNbXSA9IG5ldyBpbnRbbGVuXTsKKyAgICAgICAgICAgIGludCBzYXZlZFZhbHVlc1tdID0gbmV3IGludFtsZW5dOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbHMsIDAsIHNhdmVkTGV2ZWxzLCAwLCBsZW4pOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZXMsIDAsIHNhdmVkVmFsdWVzLCAwLCBsZW4pOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFubmVsc09yZGVyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzYXZlZExldmVscywgaSAqIDQsIGxldmVscywgY2hhbm5lbHNPcmRlcltpXSAqIDQsIDQpOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2F2ZWRWYWx1ZXMsIGkgKiA0LCB2YWx1ZXMsIGNoYW5uZWxzT3JkZXJbaV0gKiA0LCA0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gcmVtb3ZlIHdoZW4gdGhpcyBtZXRob2QgaXMgdXNlZAorICAgIC8qKgorICAgICAqIElwcCBmaWx0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNyYy4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZHN0LgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0eXBlLgorICAgICAqIEBwYXJhbSBza2lwQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBza2lwIGFscGhhLgorICAgICAqIEByZXR1cm4gdGhlIGludC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIGZpbmFsIGludCBpcHBGaWx0ZXIoUmFzdGVyIHNyYywgV3JpdGFibGVSYXN0ZXIgZHN0LCBpbnQgaW1hZ2VUeXBlLCBib29sZWFuIHNraXBBbHBoYSkgeworICAgICAgICBpbnQgcmVzOworCisgICAgICAgIGludCBzcmNTdHJpZGUsIGRzdFN0cmlkZTsKKyAgICAgICAgaW50IGNoYW5uZWxzOworICAgICAgICBpbnQgb2Zmc2V0c1tdID0gbnVsbDsKKyAgICAgICAgaW50IGNoYW5uZWxzT3JkZXJbXSA9IG51bGw7CisKKyAgICAgICAgc3dpdGNoIChpbWFnZVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0FSR0JfUFJFOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQjogeworICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSBzcmMuZ2V0V2lkdGgoKSAqIDQ7CisgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gZHN0LmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXIgPSBuZXcgaW50W10geworICAgICAgICAgICAgICAgICAgICAgICAgMiwgMSwgMCwgMworICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFXzRCWVRFX0FCR1I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV80QllURV9BQkdSX1BSRToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9CR1I6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDQ7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiA0OworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogNDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfQllURV9HUkFZOiB7CisgICAgICAgICAgICAgICAgY2hhbm5lbHMgPSAxOworICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNyYy5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV8zQllURV9CR1I6IHsKKyAgICAgICAgICAgICAgICBjaGFubmVscyA9IDM7CisgICAgICAgICAgICAgICAgc3JjU3RyaWRlID0gc3JjLmdldFdpZHRoKCkgKiAzOworICAgICAgICAgICAgICAgIGRzdFN0cmlkZSA9IGRzdC5nZXRXaWR0aCgpICogMzsKKyAgICAgICAgICAgICAgICBjaGFubmVsc09yZGVyID0gbmV3IGludFtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIDIsIDEsIDAKKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9VU0hPUlRfR1JBWToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF81NjVfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUXzU1NV9SR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0JJTkFSWTogeworICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0LCBza2lwQWxwaGEpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBkZWZhdWx0OiB7CisgICAgICAgICAgICAgICAgU2FtcGxlTW9kZWwgc3JjU00gPSBzcmMuZ2V0U2FtcGxlTW9kZWwoKTsKKyAgICAgICAgICAgICAgICBTYW1wbGVNb2RlbCBkc3RTTSA9IGRzdC5nZXRTYW1wbGVNb2RlbCgpOworCisgICAgICAgICAgICAgICAgaWYgKHNyY1NNIGluc3RhbmNlb2YgUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBkc3RTTSBpbnN0YW5jZW9mIFBpeGVsSW50ZXJsZWF2ZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNyY1NNLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBkc3RTTS5nZXREYXRhVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9CWVRFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvd0ZpbHRlcihzcmMsIGRzdCwgc2tpcEFscGhhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gc3JjU00uZ2V0TnVtQmFuZHMoKTsgLy8gSGF2ZSBJUFAgZnVuY3Rpb25zIGZvciAxLAorICAgICAgICAgICAgICAgICAgICAvLyAzIGFuZCA0IGNoYW5uZWxzCisgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYW5uZWxzID09IDEgfHwgY2hhbm5lbHMgPT0gMyB8fCBjaGFubmVscyA9PSA0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBzcmNTdHJpZGUgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKXNyY1NNKS5nZXRTY2FubGluZVN0cmlkZSgpOworICAgICAgICAgICAgICAgICAgICBkc3RTdHJpZGUgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKWRzdFNNKS5nZXRTY2FubGluZVN0cmlkZSgpOworCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXIgPSAoKENvbXBvbmVudFNhbXBsZU1vZGVsKXNyY1NNKS5nZXRCYW5kT2Zmc2V0cygpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3JjU00gaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBkc3RTTSBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbAorICAgICAgICAgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtMSA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKXNyY1NNOworICAgICAgICAgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtMiA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKWRzdFNNOworCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gc3Bwc20xLmdldE51bUJhbmRzKCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gVFlQRV9JTlRfUkdCLCBUWVBFX0lOVF9BUkdCLi4uCisgICAgICAgICAgICAgICAgICAgIGlmIChzcHBzbTEuZ2V0RGF0YVR5cGUoKSAhPSBEYXRhQnVmZmVyLlRZUEVfSU5UCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3Bwc20yLmdldERhdGFUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0lOVAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICEoY2hhbm5lbHMgPT0gMyB8fCBjaGFubmVscyA9PSA0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBjb21wYXRpYmlsaXR5IG9mIHNhbXBsZSBtb2RlbHMKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHNwcHNtMS5nZXRCaXRPZmZzZXRzKCksIHNwcHNtMi5nZXRCaXRPZmZzZXRzKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMoc3Bwc20xLmdldEJpdE1hc2tzKCksIHNwcHNtMi5nZXRCaXRNYXNrcygpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcHBzbTEuZ2V0U2FtcGxlU2l6ZShpKSAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3dGaWx0ZXIoc3JjLCBkc3QsIHNraXBBbHBoYSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBjaGFubmVsc09yZGVyID0gbmV3IGludFtjaGFubmVsc107CisgICAgICAgICAgICAgICAgICAgIGludCBiaXRPZmZzZXRzW10gPSBzcHBzbTEuZ2V0Qml0T2Zmc2V0cygpOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzT3JkZXJbaV0gPSBiaXRPZmZzZXRzW2ldIC8gODsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChjaGFubmVscyA9PSAzKSB7IC8vIERvbid0IHNraXAgY2hhbm5lbCBub3csIGNvdWxkIGJlCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcHRpbWl6ZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzID0gNDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHNyY1N0cmlkZSA9IHNwcHNtMS5nZXRTY2FubGluZVN0cmlkZSgpICogNDsKKyAgICAgICAgICAgICAgICAgICAgZHN0U3RyaWRlID0gc3Bwc20yLmdldFNjYW5saW5lU3RyaWRlKCkgKiA0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzbG93RmlsdGVyKHNyYywgZHN0LCBza2lwQWxwaGEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIEZpbGwgb2Zmc2V0cyBpZiB0aGVyZSdzIGEgY2hpbGQgcmFzdGVyCisgICAgICAgICAgICAgICAgaWYgKHNyYy5nZXRQYXJlbnQoKSAhPSBudWxsIHx8IGRzdC5nZXRQYXJlbnQoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgIT0gMCB8fCBzcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgIT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGRzdC5nZXRTYW1wbGVNb2RlbFRyYW5zbGF0ZVgoKSAhPSAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZHN0LmdldFNhbXBsZU1vZGVsVHJhbnNsYXRlWSgpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHMgPSBuZXcgaW50WzRdOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1swXSA9IC1zcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBzcmMuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1sxXSA9IC1zcmMuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgKyBzcmMuZ2V0TWluWSgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1syXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVYKCkgKyBkc3QuZ2V0TWluWCgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1szXSA9IC1kc3QuZ2V0U2FtcGxlTW9kZWxUcmFuc2xhdGVZKCkgKyBkc3QuZ2V0TWluWSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IGxldmVsc1tdID0gbmV3IGludFs0ICogY2hhbm5lbHNdOworICAgICAgICBpbnQgdmFsdWVzW10gPSBuZXcgaW50WzQgKiBjaGFubmVsc107CisKKyAgICAgICAgY3JlYXRlTGV2ZWxzKHNyYy5nZXRTYW1wbGVNb2RlbCgpLCBjaGFubmVscywgc2tpcEFscGhhLCBsZXZlbHMsIHZhbHVlcywgY2hhbm5lbHNPcmRlcik7CisKKyAgICAgICAgT2JqZWN0IHNyY0RhdGEsIGRzdERhdGE7CisgICAgICAgIEF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvciBkYkFjY2VzcyA9IEF3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5nZXRJbnN0YW5jZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3JjRGF0YSA9IGRiQWNjZXNzLmdldERhdGEoc3JjLmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgICAgICBkc3REYXRhID0gZGJBY2Nlc3MuZ2V0RGF0YShkc3QuZ2V0RGF0YUJ1ZmZlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsgLy8gVW5rbm93biBkYXRhIGJ1ZmZlciB0eXBlCisgICAgICAgIH0KKworICAgICAgICByZXMgPSBMb29rdXBPcC5pcHBMVVQoc3JjRGF0YSwgc3JjLmdldFdpZHRoKCksIHNyYy5nZXRIZWlnaHQoKSwgc3JjU3RyaWRlLCBkc3REYXRhLCBkc3QKKyAgICAgICAgICAgICAgICAuZ2V0V2lkdGgoKSwgZHN0LmdldEhlaWdodCgpLCBkc3RTdHJpZGUsIGxldmVscywgdmFsdWVzLCBjaGFubmVscywgb2Zmc2V0cywgdHJ1ZSk7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvU2FtcGxlTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9TYW1wbGVNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5NjdmYTYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvU2FtcGxlTW9kZWwuamF2YQpAQCAtMCwwICsxLDExNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIFNhbXBsZU1vZGVsIGNsYXNzIGlzIGFic3RyYWN0IGNsYXNzIGZvciByZXRyaWV2aW5nIHBpeGVsJ3Mgc2FtcGxlcyBpbiB0aGUKKyAqIGRhdGEgb2YgYW4gaW1hZ2UuIEVhY2ggcGl4ZWwgY29udGFpbnMgc2V2ZXJhbCBzYW1wbGVzLiBBIHNhbXBsZSBpcyB0aGUgc2V0IG9mCisgKiB2YWx1ZXMgb2YgdGhlIGJhbmRzIGZvciBzaW5nbGUgcGl4ZWwuIEZvciBleGFtcGxlLCBlYWNoIHBpeGVsIGluIHRoZSBSR0IKKyAqIG1vZGVsIGNvbnRhaW5zIHRocmVlIHNhbXBsZXMgYW5kIHRoZXJlIGFyZSB0aHJlZSBjb3JyZXNwb25kaW5nIGJhbmRzIGluIHRoZQorICogaW1hZ2UgZGF0YSBvZiBzdWNoIHBpeGVscyByZXByZXNlbnRpbmcgcmVkLCBncmVlbiBhbmQgYmx1ZSBjb21wb25lbnRzLgorICogPHA+CisgKiBUaGUgaW1hZ2UgZGF0YSBpcyByZXByZXNlbnRlZCBhcyBhIFJhc3RlciB3aXRoIGEgRGF0YUJ1ZmZlciBhbmQgYQorICogU2FtcGxlTW9kZWwuIFRoZSBTYW1wbGVNb2RlbCBhbGxvd3MgYWNjZXNzIHRvIHRoZSBzYW1wbGVzIGluIHRoZSBEYXRhQnVmZmVyLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNhbXBsZU1vZGVsIHsKKworICAgIC8qKgorICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgZGF0YSB3aGljaCB0aGlzIFNhbXBsZU1vZGVsIGRlc2NyaWJlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHdpZHRoOworCisgICAgLyoqCisgICAgICogVGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UgZGF0YSB3aGljaCB0aGlzIFNhbXBsZU1vZGVsIGRlc2NyaWJlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGhlaWdodDsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgYmFuZHMgb2YgaW1hZ2UgZGF0YSB3aGljaCB0aGlzIFNhbXBsZU1vZGVsIGRlc2NyaWJlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG51bUJhbmRzOworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEgdHlwZSBvZiB0aGUgaW1hZ2UgZGF0YSB3aGljaCB0aGlzIFNhbXBsZU1vZGVsIGRlc2NyaWJlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGRhdGFUeXBlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFNhbXBsZU1vZGVsIHdpdGggdGhlIHNwZWNpZmllZCBkYXRhIHR5cGUsIHdpZHRoLAorICAgICAqIGhlaWdodCBhbmQgbnVtYmVyIG9mIGJhbmRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBudW1CYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiYW5kcyBvZiB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwoaW50IGRhdGFUeXBlLCBpbnQgdywgaW50IGgsIGludCBudW1CYW5kcykgeworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjIyRT13IG9yIGggaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJFIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgc3F1cmUgPSAoKGRvdWJsZSl3KSAqICgoZG91YmxlKWgpOworICAgICAgICBpZiAoc3F1cmUgPj0gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yMkY9VGhlIHByb2R1Y3Qgb2YgdyBhbmQgaCBpcyBncmVhdGVyIHRoYW4gSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjJGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoZGF0YVR5cGUgPCBEYXRhQnVmZmVyLlRZUEVfQllURSB8fCBkYXRhVHlwZSA+IERhdGFCdWZmZXIuVFlQRV9ET1VCTEUKKyAgICAgICAgICAgICAgICAmJiBkYXRhVHlwZSAhPSBEYXRhQnVmZmVyLlRZUEVfVU5ERUZJTkVEKSB7CisgICAgICAgICAgICAvLyBhd3QuMjMwPWRhdGFUeXBlIGlzIG5vdCBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkYXRhIHR5cGVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIzMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG51bUJhbmRzIDwgMSkgeworICAgICAgICAgICAgLy8gYXd0LjIzMT1OdW1iZXIgb2YgYmFuZHMgbXVzdCBiZSBtb3JlIHRoZW4gMAorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yMzEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgdGhpcy53aWR0aCA9IHc7CisgICAgICAgIHRoaXMuaGVpZ2h0ID0gaDsKKyAgICAgICAgdGhpcy5udW1CYW5kcyA9IG51bUJhbmRzOworCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGF0YSBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBvZiB0aGUgc3BlY2lmaWVkIERhdGFCdWZmZXIKKyAgICAgKiB3aXRoIG9uZSBvZiB0aGUgZm9sbG93aW5nIHR5cGVzOiBEYXRhQnVmZmVyLlRZUEVfQllURSwKKyAgICAgKiBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBEYXRhQnVmZmVyLlRZUEVfSU5ULCBEYXRhQnVmZmVyLlRZUEVfU0hPUlQsCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0ZMT0FULCBvciBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgaXMgYSBkYXRhIHdoZXJlIHRoZSByZXN1bHQgd2lsbCBiZSBzdG9yZWQuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgRGF0YUJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIE9iamVjdCBvYmosIERhdGFCdWZmZXIgZGF0YSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBwaXhlbCBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzCisgICAgICogb2YgdGhlIHNwZWNpZmllZCBEYXRhQnVmZmVyIHdpdGggb25lIG9mIHRoZSBmb2xsb3dpbmcgdHlwZXM6CisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQsIERhdGFCdWZmZXIuVFlQRV9JTlQsCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX1NIT1JULCBEYXRhQnVmZmVyLlRZUEVfRkxPQVQsIG9yIERhdGFCdWZmZXIuVFlQRV9ET1VCTEUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIHBpeGVsIGFyZWEuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3Rhbmd1bGFyIHBpeGVsIGFyZWEuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ3VsYXIgcGl4ZWwgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ3VsYXIgcGl4ZWwgYXJlYS4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IGlzIGFuIGFycmF5IHdpdGggdGhlIHByaW1pdGl2ZSB0eXBlLCB3aGVyZSB0aGUKKyAgICAgKiAgICAgICAgICAgIHJlc3VsdCBhcnJheSB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgcGl4ZWwgZGF0YSBmb3IgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mCisgICAgICogICAgICAgICBwaXhlbHMgb2YgdGhlIHNwZWNpZmllZCBEYXRhQnVmZmVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBudW1EYXRhRWxlbWVudHMgPSBnZXROdW1EYXRhRWxlbWVudHMoKTsKKyAgICAgICAgaW50IGlkeCA9IDA7CisKKyAgICAgICAgc3dpdGNoIChnZXRUcmFuc2ZlclR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJkYXRhW107CisgICAgICAgICAgICAgICAgYnl0ZSBiYnVmW10gPSBudWxsOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gbmV3IGJ5dGVbbnVtRGF0YUVsZW1lbnRzICogdyAqIGhdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gKGJ5dGVbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgYmJ1ZiA9IChieXRlW10pZ2V0RGF0YUVsZW1lbnRzKGosIGksIGJidWYsIGRhdGEpOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1EYXRhRWxlbWVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJkYXRhW2lkeCsrXSA9IGJidWZbbl07CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2JqID0gYmRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1NIT1JUOgorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgIHNob3J0IHNkYXRhW107CisgICAgICAgICAgICAgICAgc2hvcnQgc2J1ZltdID0gbnVsbDsKKworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzZGF0YSA9IG5ldyBzaG9ydFtudW1EYXRhRWxlbWVudHMgKiB3ICogaF07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2RhdGEgPSAoc2hvcnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IChzaG9ydFtdKWdldERhdGFFbGVtZW50cyhqLCBpLCBzYnVmLCBkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtRGF0YUVsZW1lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZGF0YVtpZHgrK10gPSBzYnVmW25dOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG9iaiA9IHNkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlkYXRhW107CisgICAgICAgICAgICAgICAgaW50IGlidWZbXSA9IG51bGw7CisKKyAgICAgICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWRhdGEgPSBuZXcgaW50W251bURhdGFFbGVtZW50cyAqIHcgKiBoXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZGF0YSA9IChpbnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWJ1ZiA9IChpbnRbXSlnZXREYXRhRWxlbWVudHMoaiwgaSwgaWJ1ZiwgZGF0YSk7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IG51bURhdGFFbGVtZW50czsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRhdGFbaWR4KytdID0gaWJ1ZltuXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvYmogPSBpZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgZmxvYXQgZmRhdGFbXTsKKyAgICAgICAgICAgICAgICBmbG9hdCBmYnVmW10gPSBudWxsOworCisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZkYXRhID0gbmV3IGZsb2F0W251bURhdGFFbGVtZW50cyAqIHcgKiBoXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IChmbG9hdFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYnVmID0gKGZsb2F0W10pZ2V0RGF0YUVsZW1lbnRzKGosIGksIGZidWYsIGRhdGEpOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1EYXRhRWxlbWVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkYXRhW2lkeCsrXSA9IGZidWZbbl07CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2JqID0gZmRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgICAgICBkb3VibGUgZGRhdGFbXTsKKyAgICAgICAgICAgICAgICBkb3VibGUgZGJ1ZltdID0gbnVsbDsKKworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBkZGF0YSA9IG5ldyBkb3VibGVbbnVtRGF0YUVsZW1lbnRzICogdyAqIGhdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRkYXRhID0gKGRvdWJsZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkYnVmID0gKGRvdWJsZVtdKWdldERhdGFFbGVtZW50cyhqLCBpLCBkYnVmLCBkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtRGF0YUVsZW1lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZGF0YVtpZHgrK10gPSBkYnVmW25dOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG9iaiA9IGRkYXRhOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb2JqOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgZm9yIGEgc2luZ2xlIHBpeGVsIGluIHRoZSBzcGVjaWZpZWQgRGF0YUJ1ZmZlciBmcm9tIGEKKyAgICAgKiBwcmltaXRpdmUgYXJyYXkgd2l0aCBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlczogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCwgRGF0YUJ1ZmZlci5UWVBFX0lOVCwgRGF0YUJ1ZmZlci5UWVBFX1NIT1JULAorICAgICAqIERhdGFCdWZmZXIuVFlQRV9GTE9BVCwgb3IgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiBwaXhlbC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiBwaXhlbC4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IC0gdGhlIGFycmF5IG9mIHByaW1pdGl2ZSBwaXhlbCBkYXRhIHRvIGJlIHNldC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgZWxlbWVudHMgZm9yIGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIERhdGFCdWZmZXIgZnJvbSBhIHByaW1pdGl2ZSBhcnJheSB3aXRoIG9uZSBvZiB0aGUgZm9sbG93aW5nIHR5cGVzOgorICAgICAqIERhdGFCdWZmZXIuVFlQRV9CWVRFLCBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBEYXRhQnVmZmVyLlRZUEVfSU5ULAorICAgICAqIERhdGFCdWZmZXIuVFlQRV9TSE9SVCwgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FULCBvciBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgLSB0aGUgYXJyYXkgb2YgcHJpbWl0aXZlIHBpeGVsIGRhdGEgdG8gYmUgc2V0LgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIE9iamVjdCBvYmosIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpbnQgbnVtRGF0YUVsZW1lbnRzID0gZ2V0TnVtRGF0YUVsZW1lbnRzKCk7CisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIHN3aXRjaCAoZ2V0VHJhbnNmZXJUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgYnl0ZSBiYnVmW10gPSBuZXcgYnl0ZVtudW1EYXRhRWxlbWVudHNdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtRGF0YUVsZW1lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYnVmW25dID0gKChieXRlW10pb2JqKVtpZHgrK107CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzZXREYXRhRWxlbWVudHMoaiwgaSwgYmJ1ZiwgZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgc2hvcnQgc2J1ZltdID0gbmV3IHNob3J0W251bURhdGFFbGVtZW50c107CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1EYXRhRWxlbWVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWZbbl0gPSAoKHNob3J0W10pb2JqKVtpZHgrK107CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzZXREYXRhRWxlbWVudHMoaiwgaSwgc2J1ZiwgZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBpbnQgaWJ1ZltdID0gbmV3IGludFtudW1EYXRhRWxlbWVudHNdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtRGF0YUVsZW1lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpYnVmW25dID0gKChpbnRbXSlvYmopW2lkeCsrXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHNldERhdGFFbGVtZW50cyhqLCBpLCBpYnVmLCBkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRkxPQVQ6CisgICAgICAgICAgICAgICAgZmxvYXQgZmJ1ZltdID0gbmV3IGZsb2F0W251bURhdGFFbGVtZW50c107CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1EYXRhRWxlbWVudHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZidWZbbl0gPSAoKGZsb2F0W10pb2JqKVtpZHgrK107CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzZXREYXRhRWxlbWVudHMoaiwgaSwgZmJ1ZiwgZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgICAgICBkb3VibGUgZGJ1ZltdID0gbmV3IGRvdWJsZVtudW1EYXRhRWxlbWVudHNdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtRGF0YUVsZW1lbnRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmW25dID0gKChkb3VibGVbXSlvYmopW2lkeCsrXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHNldERhdGFFbGVtZW50cyhqLCBpLCBkYnVmLCBkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBTYW1wbGVNb2RlbCB3aXRoIHRoZSBzcGVjaWZpZWQgYmFuZHMgb2YgdGhpcyBTYW1wbGVNb2RlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmFuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBiYW5kcyBmcm9tIHRoaXMgU2FtcGxlTW9kZWwuCisgICAgICogQHJldHVybiB0aGUgU2FtcGxlTW9kZWwgd2l0aCB0aGUgc3BlY2lmaWVkIGJhbmRzIG9mIHRoaXMgU2FtcGxlTW9kZWwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNhbXBsZU1vZGVsIGNyZWF0ZVN1YnNldFNhbXBsZU1vZGVsKGludCBiYW5kc1tdKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIFNhbXBsZU1vZGVsIHdoaWNoIGhhcyB0aGUgc2FtZSBkYXRhIGFzIGluIHRoaXMgU2FtcGxlTW9kZWwKKyAgICAgKiB3aXRoIGEgZGlmZmVyZW50IHdpZHRoIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIGEwCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGExCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIFNhbXBsZU1vZGVsIHdoaWNoIGhhcyB0aGUgc2FtZSBkYXRhIGFzIGluIHRoaXMgU2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgIHdpdGggYSBkaWZmZXJlbnQgd2lkdGggYW5kIGhlaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2FtcGxlTW9kZWwgY3JlYXRlQ29tcGF0aWJsZVNhbXBsZU1vZGVsKGludCBhMCwgaW50IGExKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZXMgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhbiBpbnRlZ2VyIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSBpQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciBhcnJheSB3aXRoIHRoZSBzYW1wbGVzIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpbnQgcGl4ZWxbXTsKKworICAgICAgICBpZiAoaUFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHBpeGVsID0gbmV3IGludFtudW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbCA9IGlBcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgcGl4ZWxbaV0gPSBnZXRTYW1wbGUoeCwgeSwgaSwgZGF0YSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGl4ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIHBpeGVsIG9mIHRoZSBEYXRhQnVmZmVyIGZyb20gYSBpbnRlZ2VyIGFycmF5IG9mIHNhbXBsZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGlBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVsKGludCB4LCBpbnQgeSwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBpQXJyYXlbaV0sIGRhdGEpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIGFzIGEgZmxvYXQgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgd2l0aCB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgZmxvYXQgZkFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCA+PSB0aGlzLndpZHRoIHx8IHkgPj0gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGZsb2F0IHBpeGVsW107CisKKyAgICAgICAgaWYgKGZBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbCA9IG5ldyBmbG9hdFtudW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbCA9IGZBcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgcGl4ZWxbaV0gPSBnZXRTYW1wbGVGbG9hdCh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwaXhlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgcGl4ZWwgb2YgdGhlIERhdGFCdWZmZXIgZnJvbSBhIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5LgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGZsb2F0IGZBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBmQXJyYXlbaV0sIGRhdGEpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIGFzIGEgZG91YmxlIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSBkQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkgd2hlcmUgcmVzdWx0IHdpbGwgYmUgc3RvcmVkLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgYXJyYXkgd2l0aCB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGVbXSBnZXRQaXhlbChpbnQgeCwgaW50IHksIGRvdWJsZSBkQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgZG91YmxlIHBpeGVsW107CisKKyAgICAgICAgaWYgKGRBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbCA9IG5ldyBkb3VibGVbbnVtQmFuZHNdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcGl4ZWwgPSBkQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIHBpeGVsW2ldID0gZ2V0U2FtcGxlRG91YmxlKHgsIHksIGksIGRhdGEpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBpeGVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBwaXhlbCBvZiB0aGUgRGF0YUJ1ZmZlciBmcm9tIGEgZG91YmxlIGFycmF5IG9mIHNhbXBsZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGRBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoaW50IHgsIGludCB5LCBkb3VibGUgZEFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCA+PSB0aGlzLndpZHRoIHx8IHkgPj0gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgeworICAgICAgICAgICAgc2V0U2FtcGxlKHgsIHksIGksIGRBcnJheVtpXSwgZGF0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzYW1wbGUgb2YgYSBzcGVjaWZpZWQgYmFuZCBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBhcyBhbgorICAgICAqIGludGVnZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlIG9mIGEgc3BlY2lmaWVkIGJhbmQgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgRGF0YUJ1ZmZlciBkYXRhKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZSBvZiBhIHNwZWNpZmllZCBiYW5kIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsIGFzIGEgZmxvYXQuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgcGl4ZWwuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlIG9mIGEgc3BlY2lmaWVkIGJhbmQgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldFNhbXBsZUZsb2F0KGludCB4LCBpbnQgeSwgaW50IGIsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICByZXR1cm4gZ2V0U2FtcGxlKHgsIHksIGIsIGRhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZSBvZiBhIHNwZWNpZmllZCBiYW5kIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsIGFzIGEgZG91YmxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHBpeGVsLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIHNhbXBsZSBvZiBhIHNwZWNpZmllZCBiYW5kIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0U2FtcGxlRG91YmxlKGludCB4LCBpbnQgeSwgaW50IGIsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICByZXR1cm4gZ2V0U2FtcGxlKHgsIHksIGIsIGRhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZXMgb2YgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscyBhcyBhbgorICAgICAqIGludGVnZXIgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciBhcnJheSB3aGVyZSByZXN1bHQgd2lsbCBiZSBzdG9yZWQuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIGludGVnZXIgYXJyYXkgd2l0aCB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyCisgICAgICogICAgICAgICBhcmVhIG9mIHBpeGVscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgaUFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCArIHcgPiB0aGlzLndpZHRoIHx8IHkgKyBoID4gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGludCBwaXhlbHNbXTsKKyAgICAgICAgaW50IGlkeCA9IDA7CisKKyAgICAgICAgaWYgKGlBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbHMgPSBuZXcgaW50W3cgKiBoICogbnVtQmFuZHNdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcGl4ZWxzID0gaUFycmF5OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IG51bUJhbmRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2lkeCsrXSA9IGdldFNhbXBsZShqLCBpLCBuLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBpeGVsczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGFsbCBvZiB0aGUgc2FtcGxlcyBmb3IgYSByZWN0YW5ndWxhciBhcmVhIG9mIHBpeGVscyBvZiB0aGUKKyAgICAgKiBEYXRhQnVmZmVyIGZyb20gYW4gaW50ZWdlciBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBpQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIGFycmF5LgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ICsgdyA+IHRoaXMud2lkdGggfHwgeSArIGggPiB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW50IGlkeCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1CYW5kczsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgIHNldFNhbXBsZShqLCBpLCBuLCBpQXJyYXlbaWR4KytdLCBkYXRhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzYW1wbGVzIG9mIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMgYXMgYSBmbG9hdAorICAgICAqIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXJyYXkgd2l0aCB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyCisgICAgICogICAgICAgICBhcmVhIG9mIHBpeGVscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGZsb2F0IGZBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggKyB3ID4gdGhpcy53aWR0aCB8fCB5ICsgaCA+IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBmbG9hdCBwaXhlbHNbXTsKKyAgICAgICAgaW50IGlkeCA9IDA7CisKKyAgICAgICAgaWYgKGZBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbHMgPSBuZXcgZmxvYXRbdyAqIGggKiBudW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbHMgPSBmQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQmFuZHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaWR4KytdID0gZ2V0U2FtcGxlRmxvYXQoaiwgaSwgbiwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBwaXhlbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhbGwgb2YgdGhlIHNhbXBsZXMgZm9yIGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMgb2YgdGhlCisgICAgICogRGF0YUJ1ZmZlciBmcm9tIGEgZmxvYXQgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gZkFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgYXJyYXkuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgZmxvYXQgZkFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCArIHcgPiB0aGlzLndpZHRoIHx8IHkgKyBoID4gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQmFuZHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoaiwgaSwgbiwgZkFycmF5W2lkeCsrXSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2FtcGxlcyBvZiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YgcGl4ZWxzIGFzIGEgZG91YmxlCisgICAgICogYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gZEFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgZG91YmxlIGFycmF5IHdpdGggdGhlIHNhbXBsZXMgb2YgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhcgorICAgICAqICAgICAgICAgYXJlYSBvZiBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZVtdIGdldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgZG91YmxlIGRBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggKyB3ID4gdGhpcy53aWR0aCB8fCB5ICsgaCA+IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBkb3VibGUgcGl4ZWxzW107CisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIGlmIChkQXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcGl4ZWxzID0gbmV3IGRvdWJsZVt3ICogaCAqIG51bUJhbmRzXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBpeGVscyA9IGRBcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBudW1CYW5kczsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpZHgrK10gPSBnZXRTYW1wbGVEb3VibGUoaiwgaSwgbiwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBwaXhlbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhbGwgb2YgdGhlIHNhbXBsZXMgZm9yIGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiBwaXhlbHMgb2YgdGhlCisgICAgICogRGF0YUJ1ZmZlciBmcm9tIGEgZG91YmxlIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGRBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBkb3VibGUgZEFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoeCA8IDAgfHwgeSA8IDAgfHwgeCArIHcgPiB0aGlzLndpZHRoIHx8IHkgKyBoID4gdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgbnVtQmFuZHM7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBzZXRTYW1wbGUoaiwgaSwgbiwgZEFycmF5W2lkeCsrXSwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIHNhbXBsZSBvZiB0aGUgc3BlY2lmaWVkIGJhbmQgZm9yIHRoZSBzcGVjaWZpZWQgcGl4ZWwgaW4gdGhlCisgICAgICogRGF0YUJ1ZmZlciBhcyBpbnRlZ2VyIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNhbXBsZSBhcyBhbiBpbnRlZ2VyIHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgaW50IHMsIERhdGFCdWZmZXIgZGF0YSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzYW1wbGVzIG9mIGEgc3BlY2lmaWVkIGJhbmQgZm9yIGEgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiBwaXhlbHMgYXMgYSBpbnRlZ2VyIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBpQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlcyBvZiBhIHNwZWNpZmllZCBiYW5kIGZvciBhIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhCisgICAgICogICAgICAgICBvZiBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBpbnQgaUFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpbnQgc2FtcGxlc1tdOworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBpZiAoaUFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBuZXcgaW50W3cgKiBoXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBpQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZXNbaWR4KytdID0gZ2V0U2FtcGxlKGosIGksIGIsIGRhdGEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNhbXBsZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2FtcGxlcyBmcm9tIGFuIGludGVnZXIgYXJyYXkgaW4gdGhlIHNwZWNpZmllZCBiYW5kIGZvciB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gaUFycmF5CisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciBhcnJheS4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNldFNhbXBsZShqLCBpLCBiLCBpQXJyYXlbaWR4KytdLCBkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZXMgb2YgYSBzcGVjaWZpZWQgYmFuZCBmb3IgYSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZgorICAgICAqIHBpeGVscyBhcyBhIGZsb2F0IGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBmQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCBhcnJheSB3aGVyZSByZXN1bHQgd2lsbCBiZSBzdG9yZWQuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIHNhbXBsZXMgb2YgYSBzcGVjaWZpZWQgYmFuZCBmb3IgYSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYQorICAgICAqICAgICAgICAgb2YgcGl4ZWxzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBmbG9hdCBmQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGZsb2F0IHNhbXBsZXNbXTsKKyAgICAgICAgaW50IGlkeCA9IDA7CisKKyAgICAgICAgaWYgKGZBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBzYW1wbGVzID0gbmV3IGZsb2F0W3cgKiBoXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBmQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZXNbaWR4KytdID0gZ2V0U2FtcGxlRmxvYXQoaiwgaSwgYiwgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2FtcGxlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzYW1wbGVzIGZyb20gYW4gZmxvYXQgYXJyYXkgaW4gdGhlIHNwZWNpZmllZCBiYW5kIGZvciB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gZkFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgYXJyYXkuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBmbG9hdCBmQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGludCBpZHggPSAwOworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNldFNhbXBsZShqLCBpLCBiLCBmQXJyYXlbaWR4KytdLCBkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNhbXBsZXMgb2YgYSBzcGVjaWZpZWQgYmFuZCBmb3IgYSBzcGVjaWZpZWQgcmVjdGFuZ3VsYXIgYXJlYSBvZgorICAgICAqIHBpeGVscyBhcyBhIGRvdWJsZSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gZEFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIGFycmF5IHdoZXJlIHJlc3VsdCB3aWxsIGJlIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgc2FtcGxlcyBvZiBhIHNwZWNpZmllZCBiYW5kIGZvciBhIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhCisgICAgICogICAgICAgICBvZiBwaXhlbHMuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZVtdIGdldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBkb3VibGUgZEFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBkb3VibGUgc2FtcGxlc1tdOworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBpZiAoZEFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBuZXcgZG91YmxlW3cgKiBoXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBkQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZXNbaWR4KytdID0gZ2V0U2FtcGxlRG91YmxlKGosIGksIGIsIGRhdGEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNhbXBsZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2FtcGxlcyBmcm9tIGFuIGRvdWJsZSBhcnJheSBpbiB0aGUgc3BlY2lmaWVkIGJhbmQgZm9yIHRoZQorICAgICAqIHNwZWNpZmllZCByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBkQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBkb3VibGUgZEFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpbnQgaWR4ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IHk7IGkgPCB5ICsgaDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0geDsgaiA8IHggKyB3OyBqKyspIHsKKyAgICAgICAgICAgICAgICBzZXRTYW1wbGUoaiwgaSwgYiwgZEFycmF5W2lkeCsrXSwgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgc2FtcGxlIG9mIHRoZSBzcGVjaWZpZWQgYmFuZCBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBpbiB0aGUKKyAgICAgKiBEYXRhQnVmZmVyIGFzIGZsb2F0IHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNhbXBsZSBhcyBmbG9hdCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIGZsb2F0IHMsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBzZXRTYW1wbGUoeCwgeSwgYiwgKGludClzLCBkYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgc2FtcGxlIG9mIHRoZSBzcGVjaWZpZWQgYmFuZCBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBpbiB0aGUKKyAgICAgKiBEYXRhQnVmZmVyIGFzIGRvdWJsZSB2YWx1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzYW1wbGUgYXMgZG91YmxlIHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgZG91YmxlIHMsIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBzZXRTYW1wbGUoeCwgeSwgYiwgKGludClzLCBkYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgRGF0YUJ1ZmZlciBvYmplY3Qgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIFNhbXBsZU1vZGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIERhdGFCdWZmZXIgb2JqZWN0IHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0YUJ1ZmZlciBjcmVhdGVEYXRhQnVmZmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzYW1wbGUgc2l6ZSBpbiBiaXRzIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogCisgICAgICogQHBhcmFtIGJhbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYmFuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzYW1wbGUgc2l6ZSBpbiBiaXRzIGZvciB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRTYW1wbGVTaXplKGludCBiYW5kKTsKKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgdGhlIHNhbXBsZSBzaXplIGluIGJpdHMgZm9yIGFsbCBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBzYW1wbGUgc2l6ZSBpbiBiaXRzIGZvciBhbGwgYmFuZHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludFtdIGdldFNhbXBsZVNpemUoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0V2lkdGgoKSB7CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0cmFuc2ZlciB0eXBlIHVzZWQgdG8gdHJhbnNmZXIgcGl4ZWxzIHZpYSB0aGUgZ2V0RGF0YUVsZW1lbnRzCisgICAgICogYW5kIHNldERhdGFFbGVtZW50cyBtZXRob2RzLiBUcmFuc2ZlciB0eXBlIHZhbHVlIGNhbiBiZSBvbmUgb2YgdGhlCisgICAgICogcHJlZGVmaW5lZCB0eXBlIGZyb20gRGF0YUJ1ZmZlciBjbGFzcyBvciBub3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmZXIgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRyYW5zZmVyVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkYXRhIGVsZW1lbnRzIGZvciBwaXhlbCB0cmFuc2ZlcnJpbmcgdmlhIHRoZQorICAgICAqIGdldERhdGFFbGVtZW50cyBhbmQgc2V0RGF0YUVsZW1lbnRzIG1ldGhvZHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGRhdGEgZWxlbWVudHMgZm9yIHBpeGVsIHRyYW5zZmVycmluZyB2aWEgdGhlCisgICAgICogICAgICAgICBnZXREYXRhRWxlbWVudHMgYW5kIHNldERhdGFFbGVtZW50cyBtZXRob2RzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TnVtRGF0YUVsZW1lbnRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYmFuZHMgaW4gdGhlIGltYWdlIGRhdGEgb2YgdGhpcyBTYW1wbGVNb2RlbCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZSBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtQmFuZHMoKSB7CisgICAgICAgIHJldHVybiBudW1CYW5kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEgb2YgdGhpcyBTYW1wbGVNb2RlbCBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SGVpZ2h0KCkgeworICAgICAgICByZXR1cm4gaGVpZ2h0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgdHlwZSBvZiBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRhdGEgdHlwZSBvZiBpbWFnZSBkYXRhIG9mIHRoaXMgU2FtcGxlTW9kZWwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0RGF0YVR5cGUoKSB7CisgICAgICAgIHJldHVybiBkYXRhVHlwZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9TaG9ydExvb2t1cFRhYmxlLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvU2hvcnRMb29rdXBUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzMTlkNTgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvU2hvcnRMb29rdXBUYWJsZS5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogT2N0IDE0LCAyMDA1CisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworLyoqCisgKiBUaGUgU2hvcnRMb29rdXBUYWJsZSBjbGFzcyBwcm92aWRlcyBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvciBsb29rdXAKKyAqIG9wZXJhdGlvbnMsIGFuZCBpcyBkZWZpbmVkIGJ5IGFuIGlucHV0IHNob3J0IGFycmF5IGZvciBiYW5kcyBvciBjb21wb25lbnRzIG9mCisgKiBpbWFnZSBhbmQgYW4gb2Zmc2V0IHZhbHVlLiBUaGUgb2Zmc2V0IHZhbHVlIHdpbGwgYmUgc3VidHJhY3RlZCBmcm9tIHRoZSBpbnB1dAorICogdmFsdWVzIGJlZm9yZSBpbmRleGluZyB0aGUgaW5wdXQgYXJyYXlzLiBUaGUgb3V0cHV0IG9mIGEgbG9va3VwIG9wZXJhdGlvbiBpcworICogcmVwcmVzZW50ZWQgYXMgYW4gdW5zaWduZWQgc2hvcnQgYXJyYXkuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgU2hvcnRMb29rdXBUYWJsZSBleHRlbmRzIExvb2t1cFRhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgc2hvcnQgZGF0YVtdW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgU2hvcnRMb29rdXBUYWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHZhbHVlIGFuZAorICAgICAqIHRoZSBzcGVjaWZpZWQgc2hvcnQgYXJyYXkgd2hpY2ggcmVwcmVzZW50cyBsb29rdXAgdGFibGUgZm9yIGFsbCBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRMb29rdXBUYWJsZShpbnQgb2Zmc2V0LCBzaG9ydFtdIGRhdGEpIHsKKyAgICAgICAgc3VwZXIob2Zmc2V0LCAxKTsKKyAgICAgICAgdGhpcy5kYXRhID0gbmV3IHNob3J0WzFdW2RhdGEubGVuZ3RoXTsKKyAgICAgICAgLy8gVGhlIGRhdGEgYXJyYXkgc3RvcmVkIGFzIGEgcmVmZXJlbmNlCisgICAgICAgIHRoaXMuZGF0YVswXSA9IGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFNob3J0TG9va3VwVGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkIG9mZnNldCB2YWx1ZSBhbmQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHNob3J0IGFycmF5IG9mIGFycmF5cyB3aGljaCByZXByZXNlbnRzIGxvb2t1cCB0YWJsZSBmb3IKKyAgICAgKiBlYWNoIGJhbmQuCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgYXJyYXkgb2YgYXJyYXlzIGZvciBlYWNoIGJhbmQuCisgICAgICovCisgICAgcHVibGljIFNob3J0TG9va3VwVGFibGUoaW50IG9mZnNldCwgc2hvcnRbXVtdIGRhdGEpIHsKKyAgICAgICAgc3VwZXIob2Zmc2V0LCBkYXRhLmxlbmd0aCk7CisgICAgICAgIHRoaXMuZGF0YSA9IG5ldyBzaG9ydFtkYXRhLmxlbmd0aF1bZGF0YVswXS5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8vIFRoZSBkYXRhIGFycmF5IGZvciBlYWNoIGJhbmQgc3RvcmVkIGFzIGEgcmVmZXJlbmNlCisgICAgICAgICAgICB0aGlzLmRhdGFbaV0gPSBkYXRhW2ldOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgU2hvcnRMb29rdXBUYWJsZSBvYmplY3QuIElmIHRoaXMKKyAgICAgKiBTaG9ydExvb2t1cFRhYmxlIG9iamVjdCBoYXMgb25lIHNob3J0IGFycmF5IGZvciBhbGwgYmFuZHMsIHRoZSByZXR1cm5lZAorICAgICAqIGFycmF5IGxlbmd0aCBpcyBvbmUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgU2hvcnRMb29rdXBUYWJsZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHNob3J0W11bXSBnZXRUYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNob3J0IGFycmF5IHdoaWNoIGNvbnRhaW5zIHNhbXBsZXMgb2YgdGhlIHNwZWNpZmllZCBwaXhlbCB3aGljaAorICAgICAqIGlzIHRyYW5zbGF0ZWQgd2l0aCB0aGUgbG9va3VwIHRhYmxlIG9mIHRoaXMgU2hvcnRMb29rdXBUYWJsZSBvYmplY3QuIFRoZQorICAgICAqIHJlc3VsdGVkIGFycmF5IGlzIHN0b3JlZCB0byB0aGUgZHN0IGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYXJyYXkuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5IHdoZXJlIHRoZSByZXN1bHQgY2FuIGJlIHN0b3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaG9ydCBhcnJheSBvZiB0cmFuc2xhdGVkIHNhbXBsZXMgb2YgYSBwaXhlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnRbXSBsb29rdXBQaXhlbChzaG9ydFtdIHNyYywgc2hvcnRbXSBkc3QpIHsKKyAgICAgICAgaWYgKGRzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBkc3QgPSBuZXcgc2hvcnRbc3JjLmxlbmd0aF07CisgICAgICAgIH0KKworICAgICAgICBpbnQgb2Zmc2V0ID0gZ2V0T2Zmc2V0KCk7CisgICAgICAgIGlmIChnZXROdW1Db21wb25lbnRzKCkgPT0gMSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkc3RbaV0gPSBkYXRhWzBdW3NyY1tpXSAtIG9mZnNldF07CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldE51bUNvbXBvbmVudHMoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZHN0W2ldID0gZGF0YVtpXVtzcmNbaV0gLSBvZmZzZXRdOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50W10gbG9va3VwUGl4ZWwoaW50W10gc3JjLCBpbnRbXSBkc3QpIHsKKyAgICAgICAgaWYgKGRzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBkc3QgPSBuZXcgaW50W3NyYy5sZW5ndGhdOworICAgICAgICB9CisKKyAgICAgICAgaW50IG9mZnNldCA9IGdldE9mZnNldCgpOworICAgICAgICBpZiAoZ2V0TnVtQ29tcG9uZW50cygpID09IDEpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZHN0W2ldID0gZGF0YVswXVtzcmNbaV0gLSBvZmZzZXRdOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXROdW1Db21wb25lbnRzKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGRzdFtpXSA9IGRhdGFbaV1bc3JjW2ldIC0gb2Zmc2V0XTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L2ltYWdlL1NpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9TaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjlmMzM1MwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9TaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsLmphdmEKQEAgLTAsMCArMSw1MTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoZSBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIGNsYXNzIHJlcHJlc2VudHMgcGl4ZWwgZGF0YSB3aGVyZSBzZXZlcmFsCisgKiBzYW1wbGVzIGNvbWJpbmUgdG8gY3JlYXRlIGEgc2luZ2xlIHBpeGVsIGFuZCBhcmUgc3RvcmVkIGluIGEgc2luZ2xlIGRhdGEKKyAqIGFycmF5IGVsZW1lbnQuIFRoaXMgY2xhc3Mgc3VwcG9ydHMgVFlQRV9CWVRFLCBUWVBFX1VTSE9SVCwgVFlQRV9JTlQgZGF0YQorICogdHlwZXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBleHRlbmRzIFNhbXBsZU1vZGVsIHsKKworICAgIC8qKgorICAgICAqIFRoZSBiaXQgbWFza3MuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYml0TWFza3NbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBiaXQgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBiaXRPZmZzZXRzW107CisKKyAgICAvKioKKyAgICAgKiBUaGUgYml0IHNpemVzLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGJpdFNpemVzW107CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2NhbmxpbmUgc3RyaWRlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNjYW5saW5lU3RyaWRlOworCisgICAgLyoqCisgICAgICogVGhlIG1heCBiaXQgc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBtYXhCaXRTaXplOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUgb2Ygc2FtcGxlcy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiaXRNYXNrcworICAgICAqICAgICAgICAgICAgdGhlIGJpdCBtYXNrcyBmb3IgYWxsIHRoZSBiYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbChpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IGJpdE1hc2tzW10pIHsKKyAgICAgICAgdGhpcyhkYXRhVHlwZSwgdywgaCwgdywgYml0TWFza3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHRoZSBzYW1wbGVzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGRhdGEuCisgICAgICogQHBhcmFtIHNjYW5saW5lU3RyaWRlCisgICAgICogICAgICAgICAgICB0aGUgc2NhbmxpbmUgc3RyaWRlIG9mIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIEBwYXJhbSBiaXRNYXNrcworICAgICAqICAgICAgICAgICAgdGhlIGJpdCBtYXNrcyBmb3IgYWxsIHRoZSBiYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbChpbnQgZGF0YVR5cGUsIGludCB3LCBpbnQgaCwgaW50IHNjYW5saW5lU3RyaWRlLAorICAgICAgICAgICAgaW50IGJpdE1hc2tzW10pIHsKKworICAgICAgICBzdXBlcihkYXRhVHlwZSwgdywgaCwgYml0TWFza3MubGVuZ3RoKTsKKworICAgICAgICBpZiAoZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgJiYgZGF0YVR5cGUgIT0gRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVAorICAgICAgICAgICAgICAgICYmIGRhdGFUeXBlICE9IERhdGFCdWZmZXIuVFlQRV9JTlQpIHsKKyAgICAgICAgICAgIC8vIGF3dC42MT1VbnN1cHBvcnRlZCBkYXRhIHR5cGU6IHswfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MSIsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGUpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuc2NhbmxpbmVTdHJpZGUgPSBzY2FubGluZVN0cmlkZTsKKyAgICAgICAgdGhpcy5iaXRNYXNrcyA9IGJpdE1hc2tzLmNsb25lKCk7CisgICAgICAgIHRoaXMuYml0T2Zmc2V0cyA9IG5ldyBpbnRbdGhpcy5udW1CYW5kc107CisgICAgICAgIHRoaXMuYml0U2l6ZXMgPSBuZXcgaW50W3RoaXMubnVtQmFuZHNdOworCisgICAgICAgIHRoaXMubWF4Qml0U2l6ZSA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLm51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIGludCBvZmZzZXQgPSAwOworICAgICAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICAgICAgaW50IG1hc2sgPSBiaXRNYXNrc1tpXTsKKworICAgICAgICAgICAgaWYgKG1hc2sgIT0gMCkgeworICAgICAgICAgICAgICAgIHdoaWxlICgobWFzayAmIDEpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbWFzayA+Pj49IDE7CisgICAgICAgICAgICAgICAgICAgIG9mZnNldCsrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHdoaWxlICgobWFzayAmIDEpID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFzayA+Pj49IDE7CisgICAgICAgICAgICAgICAgICAgIHNpemUrKzsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAobWFzayAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF3dC42Mj1Xcm9uZyBtYXNrIDogezB9CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjIiLCBiaXRNYXNrc1tpXSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0aGlzLmJpdE9mZnNldHNbaV0gPSBvZmZzZXQ7CisgICAgICAgICAgICB0aGlzLmJpdFNpemVzW2ldID0gc2l6ZTsKKworICAgICAgICAgICAgaWYgKHRoaXMubWF4Qml0U2l6ZSA8IHNpemUpIHsKKyAgICAgICAgICAgICAgICB0aGlzLm1heEJpdFNpemUgPSBzaXplOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IG9iaiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChnZXRUcmFuc2ZlclR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlIGJkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJkYXRhID0gbmV3IGJ5dGVbMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmRhdGEgPSAoYnl0ZVtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBiZGF0YVswXSA9IChieXRlKWRhdGEuZ2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyB4KTsKKyAgICAgICAgICAgICAgICBvYmogPSBiZGF0YTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBzaG9ydCBzZGF0YVtdOworICAgICAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzZGF0YSA9IG5ldyBzaG9ydFsxXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZGF0YSA9IChzaG9ydFtdKW9iajsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBzZGF0YVswXSA9IChzaG9ydClkYXRhLmdldEVsZW0oeSAqIHNjYW5saW5lU3RyaWRlICsgeCk7CisgICAgICAgICAgICAgICAgb2JqID0gc2RhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlkYXRhW107CisgICAgICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlkYXRhID0gbmV3IGludFsxXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZGF0YSA9IChpbnRbXSlvYmo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWRhdGFbMF0gPSBkYXRhLmdldEVsZW0oeSAqIHNjYW5saW5lU3RyaWRlICsgeCk7CisgICAgICAgICAgICAgICAgb2JqID0gaWRhdGE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG9iajsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBPYmplY3Qgb2JqLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGdldFRyYW5zZmVyVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgICAgIGRhdGEuc2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyB4LCAoKGJ5dGVbXSlvYmopWzBdICYgMHhmZik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgZGF0YS5zZXRFbGVtKHkgKiBzY2FubGluZVN0cmlkZSArIHgsICgoc2hvcnRbXSlvYmopWzBdICYgMHhmZmZmKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBkYXRhLnNldEVsZW0oeSAqIHNjYW5saW5lU3RyaWRlICsgeCwgKChpbnRbXSlvYmopWzBdKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgT2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIG9iamVjdCBpcyBlcXVhbCB0byB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKChvID09IG51bGwpIHx8ICEobyBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIG1vZGVsID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpbzsKKyAgICAgICAgcmV0dXJuIHRoaXMud2lkdGggPT0gbW9kZWwud2lkdGggJiYgdGhpcy5oZWlnaHQgPT0gbW9kZWwuaGVpZ2h0CisgICAgICAgICAgICAgICAgJiYgdGhpcy5udW1CYW5kcyA9PSBtb2RlbC5udW1CYW5kcyAmJiB0aGlzLmRhdGFUeXBlID09IG1vZGVsLmRhdGFUeXBlCisgICAgICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyh0aGlzLmJpdE1hc2tzLCBtb2RlbC5iaXRNYXNrcykKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKHRoaXMuYml0T2Zmc2V0cywgbW9kZWwuYml0T2Zmc2V0cykKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKHRoaXMuYml0U2l6ZXMsIG1vZGVsLmJpdFNpemVzKQorICAgICAgICAgICAgICAgICYmIHRoaXMuc2NhbmxpbmVTdHJpZGUgPT0gbW9kZWwuc2NhbmxpbmVTdHJpZGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGNyZWF0ZVN1YnNldFNhbXBsZU1vZGVsKGludCBiYW5kc1tdKSB7CisgICAgICAgIGlmIChiYW5kcy5sZW5ndGggPiB0aGlzLm51bUJhbmRzKSB7CisgICAgICAgICAgICAvLyBhd3QuNjQ9VGhlIG51bWJlciBvZiB0aGUgYmFuZHMgaW4gdGhlIHN1YnNldCBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICAgICAgICAvLyBudW1iZXIgb2YgYmFuZHMgaW4gdGhlIHNhbXBsZSBtb2RlbAorICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IG1hc2tzW10gPSBuZXcgaW50W2JhbmRzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmFuZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hc2tzW2ldID0gdGhpcy5iaXRNYXNrc1tiYW5kc1tpXV07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKHRoaXMuZGF0YVR5cGUsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0LAorICAgICAgICAgICAgICAgIHRoaXMuc2NhbmxpbmVTdHJpZGUsIG1hc2tzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgY3JlYXRlQ29tcGF0aWJsZVNhbXBsZU1vZGVsKGludCB3LCBpbnQgaCkgeworICAgICAgICByZXR1cm4gbmV3IFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwodGhpcy5kYXRhVHlwZSwgdywgaCwgdGhpcy5iaXRNYXNrcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldFBpeGVsKGludCB4LCBpbnQgeSwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKHggPCAwIHx8IHkgPCAwIHx8IHggPj0gdGhpcy53aWR0aCB8fCB5ID49IHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpbnQgcGl4ZWxbXTsKKyAgICAgICAgaWYgKGlBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbCA9IG5ldyBpbnRbdGhpcy5udW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbCA9IGlBcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5udW1CYW5kczsgaSsrKSB7CisgICAgICAgICAgICBwaXhlbFtpXSA9IGdldFNhbXBsZSh4LCB5LCBpLCBkYXRhKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwaXhlbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLm51bUJhbmRzOyBpKyspIHsKKyAgICAgICAgICAgIHNldFNhbXBsZSh4LCB5LCBpLCBpQXJyYXlbaV0sIGRhdGEpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW50IHNhbXBsZSA9IGRhdGEuZ2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyB4KTsKKyAgICAgICAgcmV0dXJuICgoc2FtcGxlICYgdGhpcy5iaXRNYXNrc1tiXSkgPj4+IHRoaXMuYml0T2Zmc2V0c1tiXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKCh4IDwgMCkgfHwgKHkgPCAwKSB8fCAoKGxvbmcpeCArIChsb25nKXcgPiB0aGlzLndpZHRoKQorICAgICAgICAgICAgICAgIHx8ICgobG9uZyl5ICsgKGxvbmcpaCA+IHRoaXMuaGVpZ2h0KSkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpbnQgcGl4ZWxzW107CisKKyAgICAgICAgaWYgKGlBcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBwaXhlbHMgPSBuZXcgaW50W3cgKiBoICogdGhpcy5udW1CYW5kc107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwaXhlbHMgPSBpQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgdGhpcy5udW1CYW5kczsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpZHgrK10gPSBnZXRTYW1wbGUoaiwgaSwgbiwgZGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBwaXhlbHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgaUFycmF5W10sIERhdGFCdWZmZXIgZGF0YSkgeworICAgICAgICBpZiAoKHggPCAwKSB8fCAoeSA8IDApIHx8ICgobG9uZyl4ICsgKGxvbmcpdyA+IHRoaXMud2lkdGgpCisgICAgICAgICAgICAgICAgfHwgKChsb25nKXkgKyAobG9uZyloID4gdGhpcy5oZWlnaHQpKSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBpZHggPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCB0aGlzLm51bUJhbmRzOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0U2FtcGxlKGosIGksIG4sIGlBcnJheVtpZHgrK10sIGRhdGEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBpbnQgcywgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICh4IDwgMCB8fCB5IDwgMCB8fCB4ID49IHRoaXMud2lkdGggfHwgeSA+PSB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW50IHRtcCA9IGRhdGEuZ2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyB4KTsKKyAgICAgICAgdG1wICY9IH50aGlzLmJpdE1hc2tzW2JdOworICAgICAgICB0bXAgfD0gKHMgPDwgdGhpcy5iaXRPZmZzZXRzW2JdKSAmIHRoaXMuYml0TWFza3NbYl07CisgICAgICAgIGRhdGEuc2V0RWxlbSh5ICogc2NhbmxpbmVTdHJpZGUgKyB4LCB0bXApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRTYW1wbGVzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgYiwgaW50IGlBcnJheVtdLCBEYXRhQnVmZmVyIGRhdGEpIHsKKyAgICAgICAgaWYgKCh4IDwgMCkgfHwgKHkgPCAwKSB8fCAoKGxvbmcpeCArIChsb25nKXcgPiB0aGlzLndpZHRoKQorICAgICAgICAgICAgICAgIHx8ICgobG9uZyl5ICsgKGxvbmcpaCA+IHRoaXMuaGVpZ2h0KSkgeworICAgICAgICAgICAgLy8gYXd0LjYzPUNvb3JkaW5hdGVzIGFyZSBub3QgaW4gYm91bmRzCisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpbnQgc2FtcGxlc1tdOworICAgICAgICBpbnQgaWR4ID0gMDsKKworICAgICAgICBpZiAoaUFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBuZXcgaW50W3cgKiBoXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNhbXBsZXMgPSBpQXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0geTsgaSA8IHkgKyBoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSB4OyBqIDwgeCArIHc7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZXNbaWR4KytdID0gZ2V0U2FtcGxlKGosIGksIGIsIGRhdGEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNhbXBsZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGludCBpQXJyYXlbXSwgRGF0YUJ1ZmZlciBkYXRhKSB7CisgICAgICAgIGlmICgoeCA8IDApIHx8ICh5IDwgMCkgfHwgKChsb25nKXggKyAobG9uZyl3ID4gdGhpcy53aWR0aCkKKyAgICAgICAgICAgICAgICB8fCAoKGxvbmcpeSArIChsb25nKWggPiB0aGlzLmhlaWdodCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC42Mz1Db29yZGluYXRlcyBhcmUgbm90IGluIGJvdW5kcworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC42MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGlkeCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSB5OyBpIDwgeSArIGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IHg7IGogPCB4ICsgdzsgaisrKSB7CisgICAgICAgICAgICAgICAgc2V0U2FtcGxlKHggKyBqLCB5ICsgaSwgYiwgaUFycmF5W2lkeCsrXSwgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0YUJ1ZmZlciBjcmVhdGVEYXRhQnVmZmVyKCkgeworICAgICAgICBEYXRhQnVmZmVyIGRhdGEgPSBudWxsOworICAgICAgICBpbnQgc2l6ZSA9ICh0aGlzLmhlaWdodCAtIDEpICogc2NhbmxpbmVTdHJpZGUgKyB3aWR0aDsKKworICAgICAgICBzd2l0Y2ggKHRoaXMuZGF0YVR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0JZVEU6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVyQnl0ZShzaXplKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVDoKKyAgICAgICAgICAgICAgICBkYXRhID0gbmV3IERhdGFCdWZmZXJVU2hvcnQoc2l6ZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBEYXRhQnVmZmVySW50KHNpemUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgc3BlY2lmaWVkIHBpeGVsIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBzcGVjaWZpZWQgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIHNwZWNpZmllZCBwaXhlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE9mZnNldChpbnQgeCwgaW50IHkpIHsKKyAgICAgICAgcmV0dXJuICh5ICogc2NhbmxpbmVTdHJpZGUgKyB4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNhbXBsZVNpemUoaW50IGJhbmQpIHsKKyAgICAgICAgcmV0dXJuIGJpdFNpemVzW2JhbmRdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnRbXSBnZXRTYW1wbGVTaXplKCkgeworICAgICAgICByZXR1cm4gYml0U2l6ZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHRoZSBiaXQgb2Zmc2V0cyBvZiB0aGUgZGF0YSBhcnJheSBlbGVtZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBiaXQgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0Qml0T2Zmc2V0cygpIHsKKyAgICAgICAgcmV0dXJuIGJpdE9mZnNldHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHRoZSBiaXQgbWFza3MgZm9yIGFsbCBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBiaXQgbWFza3MgZm9yIGFsbCBiYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0Qml0TWFza3MoKSB7CisgICAgICAgIHJldHVybiBiaXRNYXNrcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBoYXNoIGNvZGUgb2YgdGhpcyBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgY2xhc3MuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIGNsYXNzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgaW50IHRtcCA9IDA7CisKKyAgICAgICAgaGFzaCA9IHdpZHRoOworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gaGVpZ2h0OworICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgaGFzaCB8PSB0bXA7CisgICAgICAgIGhhc2ggXj0gbnVtQmFuZHM7CisgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICBoYXNoIDw8PSA4OworICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgaGFzaCBePSBkYXRhVHlwZTsKKyAgICAgICAgdG1wID0gaGFzaCA+Pj4gMjQ7CisgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICBmb3IgKGludCBlbGVtZW50IDogYml0TWFza3MpIHsKKyAgICAgICAgICAgIGhhc2ggXj0gZWxlbWVudDsKKyAgICAgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGVsZW1lbnQgOiBiaXRPZmZzZXRzKSB7CisgICAgICAgICAgICBoYXNoIF49IGVsZW1lbnQ7CisgICAgICAgICAgICB0bXAgPSBoYXNoID4+PiAyNDsKKyAgICAgICAgICAgIGhhc2ggPDw9IDg7CisgICAgICAgICAgICBoYXNoIHw9IHRtcDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBlbGVtZW50IDogYml0U2l6ZXMpIHsKKyAgICAgICAgICAgIGhhc2ggXj0gZWxlbWVudDsKKyAgICAgICAgICAgIHRtcCA9IGhhc2ggPj4+IDI0OworICAgICAgICAgICAgaGFzaCA8PD0gODsKKyAgICAgICAgICAgIGhhc2ggfD0gdG1wOworICAgICAgICB9CisgICAgICAgIGhhc2ggXj0gc2NhbmxpbmVTdHJpZGU7CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNjYW5saW5lIHN0cmlkZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzY2FubGluZSBzdHJpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNjYW5saW5lU3RyaWRlKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zY2FubGluZVN0cmlkZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE51bURhdGFFbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvVGlsZU9ic2VydmVyLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvVGlsZU9ic2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2RkOTdlMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9UaWxlT2JzZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZTsKKworLyoqCisgKiBBbiBhc3luY2hyb25vdXMgdXBkYXRlIGludGVyZmFjZSBmb3IgcmVjZWl2aW5nIG5vdGlmaWNhdGlvbnMgYWJvdXQgdGlsZQorICogaW5mb3JtYXRpb24gd2hlbiB0aWxlcyBvZiBhIFdyaXRhYmxlUmVuZGVyZWRJbWFnZSBiZWNvbWUgbW9kaWZpYWJsZSBvcgorICogdW5tb2RpZmlhYmxlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBUaWxlT2JzZXJ2ZXIgeworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gaW5mb3JtYXRpb24gYWJvdXQgYSB0aWxlIHVwZGF0ZSBpcyBhdmFpbGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gdGlsZVgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGluZGV4IG9mIHRoZSB0aWxlLgorICAgICAqIEBwYXJhbSB0aWxlWQorICAgICAqICAgICAgICAgICAgdGhlIFkgaW5kZXggb2YgdGhlIHRpbGUuCisgICAgICogQHBhcmFtIHdpbGxCZVdyaXRhYmxlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHRpbGUgd2lsbCBiZSBncmFiYmVkIGZvcgorICAgICAqICAgICAgICAgICAgd3JpdGluZyBvciBiZSByZWxlYXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0aWxlVXBkYXRlKFdyaXRhYmxlUmVuZGVyZWRJbWFnZSBzb3VyY2UsIGludCB0aWxlWCwgaW50IHRpbGVZLAorICAgICAgICAgICAgYm9vbGVhbiB3aWxsQmVXcml0YWJsZSk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9Wb2xhdGlsZUltYWdlLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvVm9sYXRpbGVJbWFnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyNGU4NjYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvVm9sYXRpbGVJbWFnZS5qYXZhCkBAIC0wLDAgKzEsMTQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZUNhcGFiaWxpdGllczsKK2ltcG9ydCBqYXZhLmF3dC5UcmFuc3BhcmVuY3k7CisKKy8qKgorICogVGhlIFZvbGF0aWxlSW1hZ2UgYWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50cyBhbiBpbWFnZSB3aGljaCBjYW4gbG9zZSBpdHMKKyAqIGNvbnRlbnRzIGF0IGFueSBwb2ludC4gVm9sYXRpbGVJbWFnZSBvYmplY3RzIGFyZSBkZXZpY2Ugc3BlY2lmaWMuIFRoaXMgY2xhc3MKKyAqIHByb3ZpZGVzIG1ldGhvZHMgZm9yIGNoZWNraW5nIGlmIG9wZXJhdGlvbiBvZiB0aGlzIGltYWdlIGFyZSBjb21wYXRpYmxlIGZvcgorICogdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbi4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBWb2xhdGlsZUltYWdlIGV4dGVuZHMgSW1hZ2UKKy8vIFZvbGF0aWxlIGltYWdlIGltcGxlbWVudHMgVHJhbnNwYXJlbmN5IHNpbmNlIDEuNQorICAgICAgICBpbXBsZW1lbnRzIFRyYW5zcGFyZW5jeSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSU1BR0VfSU5DT01QQVRJQkxFIGluZGljYXRlcyB0aGF0IHRoaXMgVm9sYXRpbGVJbWFnZSBpcyBub3QKKyAgICAgKiBhcHBsaWNhYmxlIGZvciB0aGUgR3JhcGhpY3NDb25maWd1cmF0aW9uIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTUFHRV9JTkNPTVBBVElCTEUgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IElNQUdFX09LIGluZGljYXRlcyB0aGF0IFZvbGF0aWxlSW1hZ2UgaXMgcmVhZHkgZm9yIHVzaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElNQUdFX09LID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJTUFHRV9SRVNUT1JFRCBpbmRpY2F0ZXMgdGhhdCBWb2xhdGlsZUltYWdlIHdpbGwgYmUgcmVhZHkgdG8KKyAgICAgKiB1c2UgYWZ0ZXIgcmVzdG9yaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElNQUdFX1JFU1RPUkVEID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc3BhcmVuY3kgdmFsdWUgb2YgdGhpcyBpbWFnZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHRyYW5zcGFyZW5jeSA9IE9QQVFVRTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBWb2xhdGlsZUltYWdlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVm9sYXRpbGVJbWFnZSgpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcmVuZGVyaW5nIGRhdGEgaXMgbG9zdCBkdXJpbmcgdmFsaWRhdGluZy4gVGhpcyBtZXRob2QKKyAgICAgKiBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIHJlbmRlcmluZyBvcGVyYXRpb24gb2YgaW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBjb250ZW50cyBsb3N0IGR1cmluZyB2YWxpZGF0aW5nLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjb250ZW50c0xvc3QoKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBHcmFwaGljczJEIHVzZWQgdG8gZHJhdyBpbiB0aGlzIFZvbGF0aWxlSW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgR3JhcGhpY3MyRCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEdyYXBoaWNzMkQgY3JlYXRlR3JhcGhpY3MoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEltYWdlQ2FwYWJpbGl0aWVzIG9mIHRoaXMgVm9sYXRpbGVJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZUNhcGFiaWxpdGllcyBvZiB0aGlzIFZvbGF0aWxlSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlQ2FwYWJpbGl0aWVzIGdldENhcGFiaWxpdGllcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoaXMgVm9sYXRpbGVJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2YgdGhpcyBWb2xhdGlsZUltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0SGVpZ2h0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgQnVmZmVyZWRJbWFnZSByZXByZXNlbnRhdGlvbiBvZiBjdXJyZW50IFZvbGF0aWxlSW1hZ2UgdGhhdCB3b24ndAorICAgICAqIGJlIGFmZmVjdGVkIGJ5IGFueSBjaGFuZ2VzIHRvIHRoaXMgVm9sYXRpbGVJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIGEgQnVmZmVyZWRJbWFnZSByZXByZXNlbnRhdGlvbiBvZiBjdXJyZW50IFZvbGF0aWxlSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1ZmZlcmVkSW1hZ2UgZ2V0U25hcHNob3QoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIG9mIHRoaXMgVm9sYXRpbGVJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aCBvZiB0aGlzIFZvbGF0aWxlSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRXaWR0aCgpOworCisgICAgLyoqCisgICAgICogVmFsaWRhdGVzIHRoZSBkcmF3aW5nIHN1cmZhY2Ugb2YgdGhlIGltYWdlIGlmIHRoZSBzdXJmYWNlIGhhZCBiZWVuIGxvc3QKKyAgICAgKiBhbmQgaWYgdGhlIHNwZWNpZmllZCBHcmFwaGljc0NvbmZpZ3VyYXRpb24gb2JqZWN0IGlzIGFwcGxpY2FibGUgdG8gdGhpcworICAgICAqIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnYworICAgICAqICAgICAgICAgICAgdGhlIEdyYXBoaWNzQ29uZmlndXJhdGlvbiBvYmplY3QuCisgICAgICogQHJldHVybiBvbmUgb2YgdGhlIGltYWdlIHN0YXR1cyBjb25zdGFudHM6IElNQUdFX09LLCBJTUFHRV9SRVNUT1JFRCBvcgorICAgICAqICAgICAgICAgSU1BR0VfSU5DT01QQVRJQkxFLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgdmFsaWRhdGUoR3JhcGhpY3NDb25maWd1cmF0aW9uIGdjKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBHcmFwaGljcyBnZXRHcmFwaGljcygpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZUdyYXBoaWNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlUHJvZHVjZXIgZ2V0U291cmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0U25hcHNob3QoKS5nZXRTb3VyY2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRyYW5zcGFyZW5jeSgpIHsKKyAgICAgICAgcmV0dXJuIHRyYW5zcGFyZW5jeTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvV3JpdGFibGVSYXN0ZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Xcml0YWJsZVJhc3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxMzY2ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvV3JpdGFibGVSYXN0ZXIuamF2YQpAQCAtMCwwICsxLDU5MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5Qb2ludDsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBUaGUgV3JpdGFibGVSYXN0ZXIgY2xhc3MgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3Igd3JpdGluZyBzYW1wbGVzIGFuZCBwaXhlbAorICogY2FwYWJpbGl0aWVzIHRvIHRoZSBSYXN0ZXIuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgV3JpdGFibGVSYXN0ZXIgZXh0ZW5kcyBSYXN0ZXIgeworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFdyaXRhYmxlUmFzdGVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgU2FtcGxlTW9kZWwsCisgICAgICogRGF0YUJ1ZmZlciwgcmVjdGFuZ3VsYXIgcmVnaW9uIGFuZCBwYXJlbnQgV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNhbXBsZU1vZGVsCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIFNhbXBsZU1vZGVsLgorICAgICAqIEBwYXJhbSBkYXRhQnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIERhdGFCdWZmZXIuCisgICAgICogQHBhcmFtIGFSZWdpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSByZWN0YW5ndWxhciByZWdpb24gd2hpY2ggZGVmaW5lcyB0aGUgbmV3IGltYWdlIGJvdW5kcy4KKyAgICAgKiBAcGFyYW0gc2FtcGxlTW9kZWxUcmFuc2xhdGUKKyAgICAgKiAgICAgICAgICAgIHRoaXMgcG9pbnQgZGVmaW5lcyB0aGUgdHJhbnNsYXRpb24gcG9pbnQgZnJvbSB0aGUgU2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRvIHRoZSBuZXcgV3JpdGFibGVSYXN0ZXIgY29vcmRpbmF0ZXMuCisgICAgICogQHBhcmFtIHBhcmVudAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmVudCBvZiB0aGlzIFdyaXRhYmxlUmFzdGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBXcml0YWJsZVJhc3RlcihTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCwgRGF0YUJ1ZmZlciBkYXRhQnVmZmVyLCBSZWN0YW5nbGUgYVJlZ2lvbiwKKyAgICAgICAgICAgIFBvaW50IHNhbXBsZU1vZGVsVHJhbnNsYXRlLCBXcml0YWJsZVJhc3RlciBwYXJlbnQpIHsKKyAgICAgICAgc3VwZXIoc2FtcGxlTW9kZWwsIGRhdGFCdWZmZXIsIGFSZWdpb24sIHNhbXBsZU1vZGVsVHJhbnNsYXRlLCBwYXJlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBXcml0YWJsZVJhc3RlciBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIFNhbXBsZU1vZGVsCisgICAgICogd2hpY2ggZGVmaW5lcyBhIGxheW91dCBvZiB0aGlzIFdyaXRhYmxlUmFzdGVyIGFuZCBEYXRhQnVmZmVyIG9iamVjdHMKKyAgICAgKiB3aGljaCBkZWZpbmVzIHRoZSBpbWFnZSBkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzYW1wbGVNb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBTYW1wbGVNb2RlbC4KKyAgICAgKiBAcGFyYW0gZGF0YUJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBEYXRhQnVmZmVyLgorICAgICAqIEBwYXJhbSBvcmlnaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBwb2ludCBvZiBvcmlnaW4uCisgICAgICovCisgICAgcHJvdGVjdGVkIFdyaXRhYmxlUmFzdGVyKFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsLCBEYXRhQnVmZmVyIGRhdGFCdWZmZXIsIFBvaW50IG9yaWdpbikgeworICAgICAgICB0aGlzKHNhbXBsZU1vZGVsLCBkYXRhQnVmZmVyLCBuZXcgUmVjdGFuZ2xlKG9yaWdpbi54LCBvcmlnaW4ueSwgc2FtcGxlTW9kZWwud2lkdGgsCisgICAgICAgICAgICAgICAgc2FtcGxlTW9kZWwuaGVpZ2h0KSwgb3JpZ2luLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgV3JpdGFibGVSYXN0ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIFNhbXBsZU1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzYW1wbGVNb2RlbAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBTYW1wbGVNb2RlbC4KKyAgICAgKiBAcGFyYW0gb3JpZ2luCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luLgorICAgICAqLworICAgIHByb3RlY3RlZCBXcml0YWJsZVJhc3RlcihTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCwgUG9pbnQgb3JpZ2luKSB7CisgICAgICAgIHRoaXMoc2FtcGxlTW9kZWwsIHNhbXBsZU1vZGVsLmNyZWF0ZURhdGFCdWZmZXIoKSwgbmV3IFJlY3RhbmdsZShvcmlnaW4ueCwgb3JpZ2luLnksCisgICAgICAgICAgICAgICAgc2FtcGxlTW9kZWwud2lkdGgsIHNhbXBsZU1vZGVsLmhlaWdodCksIG9yaWdpbiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YSBmb3IgYSBzaW5nbGUgcGl4ZWwgZnJvbSBhbiBpbnB1dCBPYmplY3Qgd2hpY2ggcmVwcmVzZW50cyBhbgorICAgICAqIGFycmF5IG9mIHByaW1pdGl2ZSB0eXBlczogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQsCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0lOVCwgRGF0YUJ1ZmZlci5UWVBFX1NIT1JULCBEYXRhQnVmZmVyLlRZUEVfRkxPQVQsIG9yCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBpbkRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgc2FtcGxlTW9kZWwuc2V0RGF0YUVsZW1lbnRzKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGluRGF0YSwKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXRhIGVsZW1lbnRzIHdoaWNoIHJlcHJlc2VudCBwaXhlbCBkYXRhIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByZWN0YW5nbGUgYXJlYSBhcyBhIHByaW1pdGl2ZSBhcnJheS4gVGhlIGZvbGxvd2luZyBpbWFnZSBkYXRhIHR5cGVzIGFyZQorICAgICAqIHN1cHBvcnRlZDogRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQsCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0lOVCwgRGF0YUJ1ZmZlci5UWVBFX1NIT1JULCBEYXRhQnVmZmVyLlRZUEVfRkxPQVQsIG9yCisgICAgICogRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBpbkRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBwcmltaXRpdmUgdHlwZSBkYXRhIHRvIGJlIHNldCB0byB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICAgICBhcmVhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgT2JqZWN0IGluRGF0YSkgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXREYXRhRWxlbWVudHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwKKyAgICAgICAgICAgICAgICBpbkRhdGEsIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGNoaWxkIG9mIHRoaXMgV3JpdGFibGVSYXN0ZXIgYnkgc2hhcmluZyB0aGUgc3BlY2lmaWVkCisgICAgICogcmVjdGFuZ3VsYXIgYXJlYSBpbiB0aGlzIFdyaXRhYmxlUmFzdGVyLiBUaGUgcGFyZW50WCwgcGFyZW50WSwgd2lkdGggYW5kCisgICAgICogaGVpZ2h0IHBhcmFtZXRlcnMgc3BlY2lmeSByZWN0YW5ndWxhciBhcmVhIHRvIGJlIHNoYXJlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyZW50WAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHNoYXJlZAorICAgICAqICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGggcmVzcGVjdCB0byB0aGlzIFdyaXRhYmxlUmFzdGVyJyBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gcGFyZW50WQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIHNoYXJlZAorICAgICAqICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGggcmVzcGVjdCB0byB0aGlzIFdyaXRhYmxlUmFzdGVyJyBjb29yZGluYXRlcy4KKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBjaGlsZCBhcmVhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBjaGlsZCBhcmVhLgorICAgICAqIEBwYXJhbSBjaGlsZE1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgY2hpbGQgYXJlYSBtYXBwZWQgdG8gdGhlIHBhcmVudFgKKyAgICAgKiAgICAgICAgICAgIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGNoaWxkTWluWQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiBjaGlsZCBhcmVhIG1hcHBlZCB0byB0aGUgcGFyZW50WQorICAgICAqICAgICAgICAgICAgY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0gYmFuZExpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBiYW5kIGluZGljZXMuCisgICAgICogQHJldHVybiB0aGUgY2hpbGQgV3JpdGFibGVSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVdyaXRhYmxlQ2hpbGQoaW50IHBhcmVudFgsIGludCBwYXJlbnRZLCBpbnQgdywgaW50IGgsCisgICAgICAgICAgICBpbnQgY2hpbGRNaW5YLCBpbnQgY2hpbGRNaW5ZLCBpbnQgYmFuZExpc3RbXSkgeworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgLy8gYXd0LjI0ND1XaWR0aCBvciBIZWlnaHQgb2YgY2hpbGQgUmFzdGVyIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0bworICAgICAgICAgICAgLy8gemVybworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwYXJlbnRYIDwgdGhpcy5taW5YIHx8IHBhcmVudFggKyB3ID4gdGhpcy5taW5YICsgdGhpcy53aWR0aCkgeworICAgICAgICAgICAgLy8gYXd0LjI0NT1wYXJlbnRYIGRpc3Bvc2VzIG91dHNpZGUgUmFzdGVyCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhcmVudFkgPCB0aGlzLm1pblkgfHwgcGFyZW50WSArIGggPiB0aGlzLm1pblkgKyB0aGlzLmhlaWdodCkgeworICAgICAgICAgICAgLy8gYXd0LjI0Nj1wYXJlbnRZIGRpc3Bvc2VzIG91dHNpZGUgUmFzdGVyCisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0NiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKXBhcmVudFggKyB3ID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNDc9cGFyZW50WCArIHcgcmVzdWx0cyBpbiBpbnRlZ2VyIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0NyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKXBhcmVudFkgKyBoID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNDg9cGFyZW50WSArIGggcmVzdWx0cyBpbiBpbnRlZ2VyIG92ZXJmbG93CisgICAgICAgICAgICB0aHJvdyBuZXcgUmFzdGVyRm9ybWF0RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI0OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKChsb25nKWNoaWxkTWluWCArIHcgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gYXd0LjI0OT1jaGlsZE1pblggKyB3IHJlc3VsdHMgaW4gaW50ZWdlciBvdmVyZmxvdworICAgICAgICAgICAgdGhyb3cgbmV3IFJhc3RlckZvcm1hdEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNDkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobG9uZyljaGlsZE1pblkgKyBoID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIGF3dC4yNEE9Y2hpbGRNaW5ZICsgaCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKKyAgICAgICAgICAgIHRocm93IG5ldyBSYXN0ZXJGb3JtYXRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjRBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBTYW1wbGVNb2RlbCBjaGlsZE1vZGVsOworCisgICAgICAgIGlmIChiYW5kTGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBjaGlsZE1vZGVsID0gc2FtcGxlTW9kZWw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjaGlsZE1vZGVsID0gc2FtcGxlTW9kZWwuY3JlYXRlU3Vic2V0U2FtcGxlTW9kZWwoYmFuZExpc3QpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNoaWxkVHJhbnNsYXRlWCA9IGNoaWxkTWluWCAtIHBhcmVudFg7CisgICAgICAgIGludCBjaGlsZFRyYW5zbGF0ZVkgPSBjaGlsZE1pblkgLSBwYXJlbnRZOworCisgICAgICAgIHJldHVybiBuZXcgV3JpdGFibGVSYXN0ZXIoY2hpbGRNb2RlbCwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICBuZXcgUmVjdGFuZ2xlKGNoaWxkTWluWCwgY2hpbGRNaW5ZLCB3LCBoKSwgbmV3IFBvaW50KGNoaWxkVHJhbnNsYXRlWAorICAgICAgICAgICAgICAgICAgICAgICAgKyBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIGNoaWxkVHJhbnNsYXRlWSArIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSksIHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHRyYW5zbGF0ZWQgY2hpbGQgb2YgdGhpcyBXcml0YWJsZVJhc3Rlci4gTmV3IFdyaXRhYmxlUmFzdGVyCisgICAgICogb2JqZWN0IGlzIGEgcmVmZXJlbmNlIHRvIHRoZSB0aGlzIFdyaXRhYmxlUmFzdGVyIGFuZCB3aXRoIGRpZmZlcmVudAorICAgICAqIGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGlsZE1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIG5ldyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBAcGFyYW0gY2hpbGRNaW5ZCisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBuZXcgV3JpdGFibGVSYXN0ZXIuCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVdyaXRhYmxlVHJhbnNsYXRlZENoaWxkKGludCBjaGlsZE1pblgsIGludCBjaGlsZE1pblkpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZVdyaXRhYmxlQ2hpbGQobWluWCwgbWluWSwgd2lkdGgsIGhlaWdodCwgY2hpbGRNaW5YLCBjaGlsZE1pblksIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBhcmVudCBXcml0YWJsZVJhc3RlciBmb3IgdGhpcyBXcml0YWJsZVJhc3RlciBvYmplY3QuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcGFyZW50IFdyaXRhYmxlUmFzdGVyIGZvciB0aGlzIFdyaXRhYmxlUmFzdGVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgZ2V0V3JpdGFibGVQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiAoV3JpdGFibGVSYXN0ZXIpcGFyZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgcGl4ZWxzIGZyb20gdGhlIHNwZWNpZmllZCBzb3VyY2UgUmFzdGVyIHNyY1Jhc3RlciB0byB0aGlzCisgICAgICogV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHNyY1Jhc3RlcgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVjdChSYXN0ZXIgc3JjUmFzdGVyKSB7CisgICAgICAgIHNldFJlY3QoMCwgMCwgc3JjUmFzdGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHBpeGVscyBmcm9tIHRoZSBzcGVjaWZpZWQgc291cmNlIFJhc3RlciBzcmNSYXN0ZXIgdG8gdGhpcworICAgICAqIFdyaXRhYmxlUmFzdGVyLiBFYWNoIHBpeGVsIHdpdGggKHgsIHkpIGNvb3JkaW5hdGVzIGZyb20gdGhlIHNvdXJjZSBSYXN0ZXIKKyAgICAgKiBpcyBjb3BpZWQgdG8gcGl4ZWwgd2l0aCAoeCtkeCwgeStkeSkgY29vcmRpbmF0ZXMgaW4gdGhpcyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBUaGUgcGl4ZWxzIHdpdGggKHgrZHgsIHkrZHkpIGNvb3JkaW5hdGVzIHdoaWNoIGFyZSBvdXQgdGhlIGJvdW5kcyBvZiB0aGlzCisgICAgICogcmFzdGVyIGFyZSBpZ25vcmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkeAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3RhbmNlIHRoZSBwaXhlbCdzIFggY29vcmRpbmF0ZSBpbiB0aGUgc291cmNlIFJhc3RlciBpcworICAgICAqICAgICAgICAgICAgdHJhbnNsYXRlZCB3aGVuIHdyaXR0aWVuIHRvIHRoaXMgV3JpdGFibGVSYXN0ZXIuCisgICAgICogQHBhcmFtIGR5CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGFuY2UgdGhlIHBpeGVsJ3MgWSBjb29yZGluYXRlIGluIHRoZSBzb3VyY2UgUmFzdGVyIGlzCisgICAgICogICAgICAgICAgICB0cmFuc2xhdGVkIHdoZW4gd3JpdHRpZW4gdG8gdGhpcyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiBAcGFyYW0gc3JjUmFzdGVyCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFJhc3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWN0KGludCBkeCwgaW50IGR5LCBSYXN0ZXIgc3JjUmFzdGVyKSB7CisgICAgICAgIGludCB3ID0gc3JjUmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgIGludCBoID0gc3JjUmFzdGVyLmdldEhlaWdodCgpOworCisgICAgICAgIGludCBzcmNYID0gc3JjUmFzdGVyLmdldE1pblgoKTsKKyAgICAgICAgaW50IHNyY1kgPSBzcmNSYXN0ZXIuZ2V0TWluWSgpOworCisgICAgICAgIGludCBkc3RYID0gc3JjWCArIGR4OworICAgICAgICBpbnQgZHN0WSA9IHNyY1kgKyBkeTsKKworICAgICAgICBpZiAoZHN0WCA8IHRoaXMubWluWCkgeworICAgICAgICAgICAgaW50IG1pbk9mZlggPSB0aGlzLm1pblggLSBkc3RYOworICAgICAgICAgICAgdyAtPSBtaW5PZmZYOworICAgICAgICAgICAgZHN0WCA9IHRoaXMubWluWDsKKyAgICAgICAgICAgIHNyY1ggKz0gbWluT2ZmWDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkc3RZIDwgdGhpcy5taW5ZKSB7CisgICAgICAgICAgICBpbnQgbWluT2ZmWSA9IHRoaXMubWluWSAtIGRzdFk7CisgICAgICAgICAgICBoIC09IG1pbk9mZlk7CisgICAgICAgICAgICBkc3RZID0gdGhpcy5taW5ZOworICAgICAgICAgICAgc3JjWSArPSBtaW5PZmZZOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRzdFggKyB3ID4gdGhpcy5taW5YICsgdGhpcy53aWR0aCkgeworICAgICAgICAgICAgaW50IG1heE9mZlggPSAoZHN0WCArIHcpIC0gKHRoaXMubWluWCArIHRoaXMud2lkdGgpOworICAgICAgICAgICAgdyAtPSBtYXhPZmZYOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRzdFkgKyBoID4gdGhpcy5taW5ZICsgdGhpcy5oZWlnaHQpIHsKKyAgICAgICAgICAgIGludCBtYXhPZmZZID0gKGRzdFkgKyBoKSAtICh0aGlzLm1pblkgKyB0aGlzLmhlaWdodCk7CisgICAgICAgICAgICBoIC09IG1heE9mZlk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodyA8PSAwIHx8IGggPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgc3dpdGNoIChzYW1wbGVNb2RlbC5nZXREYXRhVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9CWVRFOgorICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9JTlQ6CisgICAgICAgICAgICAgICAgaW50IGlQaXhlbHNMaW5lW10gPSBudWxsOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlQaXhlbHNMaW5lID0gc3JjUmFzdGVyLmdldFBpeGVscyhzcmNYLCBzcmNZICsgaSwgdywgMSwgaVBpeGVsc0xpbmUpOworICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbHMoZHN0WCwgZHN0WSArIGksIHcsIDEsIGlQaXhlbHNMaW5lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGZsb2F0IGZQaXhlbHNMaW5lW10gPSBudWxsOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZQaXhlbHNMaW5lID0gc3JjUmFzdGVyLmdldFBpeGVscyhzcmNYLCBzcmNZICsgaSwgdywgMSwgZlBpeGVsc0xpbmUpOworICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbHMoZHN0WCwgZHN0WSArIGksIHcsIDEsIGZQaXhlbHNMaW5lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0RPVUJMRToKKyAgICAgICAgICAgICAgICBkb3VibGUgZFBpeGVsc0xpbmVbXSA9IG51bGw7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZFBpeGVsc0xpbmUgPSBzcmNSYXN0ZXIuZ2V0UGl4ZWxzKHNyY1gsIHNyY1kgKyBpLCB3LCAxLCBkUGl4ZWxzTGluZSk7CisgICAgICAgICAgICAgICAgICAgIHNldFBpeGVscyhkc3RYLCBkc3RZICsgaSwgdywgMSwgZFBpeGVsc0xpbmUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgZm9yIGEgcmVjdGFuZ2xlIG9mIHBpeGVscyBmcm9tIGFuIGlucHV0IFJhc3RlciB0byB0aGlzCisgICAgICogV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHdoZXJlIHRoZSBkYXRhIG9mIHRoZSBpbnB1dAorICAgICAqICAgICAgICAgICAgUmFzdGVyIGlzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHdoZXJlIHRoZSBkYXRhIG9mIHRoZSBpbnB1dAorICAgICAqICAgICAgICAgICAgUmFzdGVyIGlzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIGluUmFzdGVyCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGFFbGVtZW50cyhpbnQgeCwgaW50IHksIFJhc3RlciBpblJhc3RlcikgeworICAgICAgICBpbnQgZHN0WCA9IHggKyBpblJhc3Rlci5nZXRNaW5YKCk7CisgICAgICAgIGludCBkc3RZID0geSArIGluUmFzdGVyLmdldE1pblkoKTsKKworICAgICAgICBpbnQgdyA9IGluUmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgIGludCBoID0gaW5SYXN0ZXIuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgaWYgKGRzdFggPCB0aGlzLm1pblggfHwgZHN0WCArIHcgPiB0aGlzLm1pblggKyB0aGlzLndpZHRoIHx8IGRzdFkgPCB0aGlzLm1pblkKKyAgICAgICAgICAgICAgICB8fCBkc3RZICsgaCA+IHRoaXMubWluWSArIHRoaXMuaGVpZ2h0KSB7CisgICAgICAgICAgICAvLyBhd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGludCBzcmNYID0gaW5SYXN0ZXIuZ2V0TWluWCgpOworICAgICAgICBpbnQgc3JjWSA9IGluUmFzdGVyLmdldE1pblkoKTsKKyAgICAgICAgT2JqZWN0IGxpbmUgPSBudWxsOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrKSB7CisgICAgICAgICAgICBsaW5lID0gaW5SYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKHNyY1gsIHNyY1kgKyBpLCB3LCAxLCBsaW5lKTsKKyAgICAgICAgICAgIHNldERhdGFFbGVtZW50cyhkc3RYLCBkc3RZICsgaSwgdywgMSwgbGluZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGFuIGludGVnZXIgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCBwaXhlbCBpbiB0aGlzCisgICAgICogV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwaXhlbCdzIFggY29vcmRpbmF0ZS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsJ3MgWSBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSBpQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIGFycmF5IG9mIHNhbXBsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoaW50IHgsIGludCB5LCBpbnQgaUFycmF5W10pIHsKKyAgICAgICAgc2FtcGxlTW9kZWwuc2V0UGl4ZWwoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgaUFycmF5LAorICAgICAgICAgICAgICAgIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBmbG9hdCBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsIGluIHRoaXMKKyAgICAgKiBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsJ3MgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwncyBZIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoaW50IHgsIGludCB5LCBmbG9hdCBmQXJyYXlbXSkgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRQaXhlbCh4IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVYLCB5IC0gc2FtcGxlTW9kZWxUcmFuc2xhdGVZLCBmQXJyYXksCisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIGRvdWJsZSBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHBpeGVsIGluIHRoaXMKKyAgICAgKiBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIHBpeGVsJ3MgWCBjb29yZGluYXRlLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgcGl4ZWwncyBZIGNvb3JkaW5hdGUuCisgICAgICogQHBhcmFtIGRBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSBhcnJheSBvZiBzYW1wbGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBpeGVsKGludCB4LCBpbnQgeSwgZG91YmxlIGRBcnJheVtdKSB7CisgICAgICAgIHNhbXBsZU1vZGVsLnNldFBpeGVsKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGRBcnJheSwKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgaW50ZWdlciBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiBwaXhlbHMgaW4gdGhpcyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIGlBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkgb2Ygc2FtcGxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBpQXJyYXlbXSkgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRQaXhlbHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgaUFycmF5LAorICAgICAgICAgICAgICAgIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBmbG9hdCBhcnJheSBvZiBzYW1wbGVzIGZvciB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEgb2YKKyAgICAgKiBwaXhlbHMgaW4gdGhpcyBXcml0YWJsZVJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHJlY3Rhbmd1bGFyIGFyZWEuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBmbG9hdCBmQXJyYXlbXSkgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRQaXhlbHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgZkFycmF5LAorICAgICAgICAgICAgICAgIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcyBmb3IgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhIG9mCisgICAgICogcGl4ZWxzIGluIHRoaXMgV3JpdGFibGVSYXN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgcmVjdGFuZ3VsYXIgYXJlYS4KKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiByZWN0YW5ndWxhciBhcmVhLgorICAgICAqIEBwYXJhbSBkQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGRvdWJsZSBkQXJyYXlbXSkgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRQaXhlbHMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgZEFycmF5LAorICAgICAgICAgICAgICAgIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBhbmQgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhcgorICAgICAqIGFyZWEgb2YgcGl4ZWxzIHdpdGggYW4gaW50ZWdlciBhcnJheSBvZiBzYW1wbGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogQHBhcmFtIGlBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkgb2Ygc2FtcGxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGVzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgYiwgaW50IGlBcnJheVtdKSB7CisgICAgICAgIHNhbXBsZU1vZGVsLnNldFNhbXBsZXMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgYiwKKyAgICAgICAgICAgICAgICBpQXJyYXksIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBhbmQgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhcgorICAgICAqIGFyZWEgb2YgcGl4ZWxzIHdpdGggYSBmbG9hdCBhcnJheSBvZiBzYW1wbGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHcKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogQHBhcmFtIGZBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IG9mIHNhbXBsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGZsb2F0IGZBcnJheVtdKSB7CisgICAgICAgIHNhbXBsZU1vZGVsLnNldFNhbXBsZXMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgYiwKKyAgICAgICAgICAgICAgICBmQXJyYXksIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNhbXBsZXMgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBhbmQgdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhcgorICAgICAqIGFyZWEgb2YgcGl4ZWxzIHdpdGggYSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgYXJlYSBvZiBwaXhlbHMuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIGFyZWEgb2YgcGl4ZWxzLgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBhcmVhIG9mIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBkQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkgb2Ygc2FtcGxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGVzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgYiwgZG91YmxlIGRBcnJheVtdKSB7CisgICAgICAgIHNhbXBsZU1vZGVsLnNldFNhbXBsZXMoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgdywgaCwgYiwKKyAgICAgICAgICAgICAgICBkQXJyYXksIGRhdGFCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNhbXBsZSBmb3IgdGhlIHNwZWNpZmllZCBiYW5kIGFuZCB0aGUgc3BlY2lmaWVkIHBpeGVsIHdpdGggYW4KKyAgICAgKiBpbnRlZ2VyIHNhbXBsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWwuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGJhbmQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzYW1wbGUgdG8gYmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZShpbnQgeCwgaW50IHksIGludCBiLCBpbnQgcykgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRTYW1wbGUoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgYiwgcywKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzYW1wbGUgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBhbmQgdGhlIHNwZWNpZmllZCBwaXhlbCB3aXRoIGEKKyAgICAgKiBmbG9hdCBzYW1wbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2FtcGxlIHRvIGJlIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgZmxvYXQgcykgeworICAgICAgICBzYW1wbGVNb2RlbC5zZXRTYW1wbGUoeCAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWCwgeSAtIHNhbXBsZU1vZGVsVHJhbnNsYXRlWSwgYiwgcywKKyAgICAgICAgICAgICAgICBkYXRhQnVmZmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzYW1wbGUgZm9yIHRoZSBzcGVjaWZpZWQgYmFuZCBhbmQgdGhlIHNwZWNpZmllZCBwaXhlbCB3aXRoIGFuCisgICAgICogaW50ZWdlciBzYW1wbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVsLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSBwaXhlbC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2FtcGxlIHRvIGJlIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgZG91YmxlIHMpIHsKKyAgICAgICAgc2FtcGxlTW9kZWwuc2V0U2FtcGxlKHggLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVgsIHkgLSBzYW1wbGVNb2RlbFRyYW5zbGF0ZVksIGIsIHMsCisgICAgICAgICAgICAgICAgZGF0YUJ1ZmZlcik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvV3JpdGFibGVSZW5kZXJlZEltYWdlLmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvV3JpdGFibGVSZW5kZXJlZEltYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDUyMzUzYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9Xcml0YWJsZVJlbmRlcmVkSW1hZ2UuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5Qb2ludDsKKworLyoqCisgKiBUaGUgV3JpdGVhYmxlUmVuZGVyZWRJbWFnZSBpbnRlcmZhY2UgaXMgaW50ZXJmYWNlIGZvciBvYmplY3RzIHdoaWNoIGNvbnRhaW5zCisgKiBSYXN0ZXIgZGF0YSBvZiBvbmUgb3Igc2V2ZXJhbCB0aWxlcy4gVGhpcyBpbnRlcmZhY2UgcHJvdmlkZXMgbm90aWZpY2F0aW9uCisgKiBtZWNoYW5pc20gZm9yIG9idGFpbmluZyB0aWxlJ3Mgd3JpdGluZyBzdGF0dXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFdyaXRhYmxlUmVuZGVyZWRJbWFnZSBleHRlbmRzIFJlbmRlcmVkSW1hZ2UgeworCisgICAgLyoqCisgICAgICogR2V0cyBhbmQgY2hlY2tzIG91dCB0aGUgd3JpdGFibGUgdGlsZSBmb3Igd3JpdGluZy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGlsZVgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGluZGV4IG9mIHRoZSB0aWxlLgorICAgICAqIEBwYXJhbSB0aWxlWQorICAgICAqICAgICAgICAgICAgdGhlIFkgaW5kZXggb2YgdGhlIHRpbGUuCisgICAgICogQHJldHVybiB0aGUgV3JpdGFibGVSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldFdyaXRhYmxlVGlsZShpbnQgdGlsZVgsIGludCB0aWxlWSk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSByZWdpc3RlcmVkIFRpbGVPYnNlcnZlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdG8KKyAgICAgKiAgICAgICAgICAgIHRoZSBUaWxlT2JzZXJ2ZXIgd2hpY2ggaXMgcmVnaXN0ZXJlZCBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgV3JpdGFibGVSZW5kZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVRpbGVPYnNlcnZlcihUaWxlT2JzZXJ2ZXIgdG8pOworCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIFRpbGVPYnNlcnZlciB0byB0aGlzIFdyaXRhYmxlUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdG8KKyAgICAgKiAgICAgICAgICAgIHRoZSBUaWxlT2JzZXJ2ZXIgb2JqZWN0IHRvIGJlIGFkZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFRpbGVPYnNlcnZlcihUaWxlT2JzZXJ2ZXIgdG8pOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGltYWdlIHRvIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBSYXN0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0YShSYXN0ZXIgcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBwb2ludHMgd2hpY2ggcmVwcmVzZW50IGluZGljZXMgb2YgdGlsZXMgd2hpY2ggYXJlIGNoZWNrCisgICAgICogb3V0IGZvciB3cml0aW5nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHBvaW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9pbnRbXSBnZXRXcml0YWJsZVRpbGVJbmRpY2VzKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCB0aWxlIGlzIHdyaXRhYmxlIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGlsZVgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGluZGV4IG9mIHRpbGUuCisgICAgICogQHBhcmFtIHRpbGVZCisgICAgICogICAgICAgICAgICB0aGUgWSBpbmRleCBvZiB0aWxlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCB0aWxlIGlzIHdyaXRhYmxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNUaWxlV3JpdGFibGUoaW50IHRpbGVYLCBpbnQgdGlsZVkpOworCisgICAgLyoqCisgICAgICogUmVsZWFzZSB0aGUgc3BlY2lmaWVkIHdyaXRhYmxlIHRpbGUuIFRoaXMgbWV0aG9kIHJlbW92ZXMgdGhlIHdyaXRlciBmcm9tCisgICAgICogdGhlIHRpbGUuCisgICAgICogCisgICAgICogQHBhcmFtIHRpbGVYCisgICAgICogICAgICAgICAgICB0aGUgWCBpbmRleCBvZiB0aGUgdGlsZS4KKyAgICAgKiBAcGFyYW0gdGlsZVkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGluZGV4IG9mIHRoZSB0aWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbGVhc2VXcml0YWJsZVRpbGUoaW50IHRpbGVYLCBpbnQgdGlsZVkpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZXJlIGlzIGEgdGlsZSB3aGljaCBpcyBjaGVja2VkIG91dCBmb3Igd3JpdGluZy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGFueSB0aWxlIGlzIGNoZWNrZWQgb3V0IGZvciB3cml0aW5nLCBmYWxzZSBpZiB0aGVyZSBpcworICAgICAqICAgICAgICAgbm8gc3VjaCB0aWxlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1RpbGVXcml0ZXJzKCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9wYWNrYWdlLmh0bWwgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZDZlZjAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsOCBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgdGhhdCBhbGxvdyB0byBtb2RpZnkgZXhpc3RpbmcgaW1hZ2VzIG9yIHRvIGNyZWF0ZSBhIG5ldyBpbWFnZSByYXRoZXIgdGhhbiBsb2FkaW5nIGl0IGZyb20gYSBmaWxlLgorICAgIDwvcD4KKyAgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9Db250ZXh0dWFsUmVuZGVyZWRJbWFnZUZhY3RvcnkuamF2YSBiL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL0NvbnRleHR1YWxSZW5kZXJlZEltYWdlRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4ODFhMGMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9Db250ZXh0dWFsUmVuZGVyZWRJbWFnZUZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZS5yZW5kZXJhYmxlOworCitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworCisvKioKKyAqIEEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgQ29udGV4dHVhbFJlbmRlcmVkSW1hZ2Ugb2JqZWN0cyB3aXRoIHV0aWxpdGllcyBmb3IKKyAqIG1hbmlwdWxhdGluZyB0aGUgcHJvcGVydGllcyBpbiB0aGUgcGFyYW1ldGVyIGJsb2NrLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBDb250ZXh0dWFsUmVuZGVyZWRJbWFnZUZhY3RvcnkgZXh0ZW5kcyBSZW5kZXJlZEltYWdlRmFjdG9yeSB7CisKKyAgICAvKioKKyAgICAgKiBNYXBzIGEgcmVuZGVyIGNvbnRleHQgdG8gYSBwYXJhbWV0ZXIgYmxvY2sgYW5kIGEgcmVuZGVyYWJsZSBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcGFyYW0gYTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJDb250ZXh0LgorICAgICAqIEBwYXJhbSBhMgorICAgICAqICAgICAgICAgICAgdGhlIFBhcmFtZXRlckJsb2NrLgorICAgICAqIEBwYXJhbSBhMworICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmFibGVJbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZW5kZXIgY29udGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyQ29udGV4dCBtYXBSZW5kZXJDb250ZXh0KGludCBhMCwgUmVuZGVyQ29udGV4dCBhMSwgUGFyYW1ldGVyQmxvY2sgYTIsCisgICAgICAgICAgICBSZW5kZXJhYmxlSW1hZ2UgYTMpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGZyb20gdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgYmxvY2sgdG8gZXhhbWluZSB0byBmaW5kIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAcGFyYW0gYTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShQYXJhbWV0ZXJCbG9jayBhMCwgU3RyaW5nIGExKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHJlbmRlcmVkIGltYWdlIGRldGVybWluZWQgYnkgdGhlIHJlbmRlciBjb250ZXh0IGFuZCBwYXJhbWV0ZXIKKyAgICAgKiBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYTAKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJDb250ZXh0LgorICAgICAqIEBwYXJhbSBhMQorICAgICAqICAgICAgICAgICAgdGhlIFBhcmFtZXRlckJsb2NrLgorICAgICAqIEByZXR1cm4gdGhlIHJlbmRlcmVkIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJlZEltYWdlIGNyZWF0ZShSZW5kZXJDb250ZXh0IGEwLCBQYXJhbWV0ZXJCbG9jayBhMSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBib3VuZGluZyByZWN0YW5nbGUgZnJvbSB0aGUgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBibG9jayB0byByZWFkIHRoZSBib3VuZHMgZnJvbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBib3VuZGluZyByZWN0YW5nbGUuCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKFBhcmFtZXRlckJsb2NrIGEwKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWVzIG9mIGFsbCBvZiB0aGUgc3VwcG9ydGVkIHByb3BlcnRpZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcHJvcGVydHkgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldFByb3BlcnR5TmFtZXMoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGlzIGltYWdlIGZhY3RvcnkgaXMgZHluYW1pYy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgaW1hZ2UgZmFjdG9yeSBpcyBkeW5hbWljLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRHluYW1pYygpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9QYXJhbWV0ZXJCbG9jay5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUGFyYW1ldGVyQmxvY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZGRlNzNhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUGFyYW1ldGVyQmxvY2suamF2YQpAQCAtMCwwICsxLDU2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2UucmVuZGVyYWJsZTsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlbmRlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworLyoqCisgKiBUaGUgY2xhc3MgUGFyYW1ldGVyQmxvY2sgZ3JvdXBzIGFuIGluZGV4ZWQgc2V0IG9mIHBhcmFtZXRlciBkYXRhIHdpdGggYSBzZXQKKyAqIG9mIHJlbmRlcmFibGUgKHNvdXJjZSkgaW1hZ2VzLiBUaGUgbWFwcGluZyBiZXR3ZWVuIHRoZSBpbmRleGVkIHBhcmFtZXRlcnMgYW5kCisgKiB0aGVpciBwcm9wZXJ0eSBuYW1lcyBpcyBwcm92aWRlZCBieSBhIHtAbGluayBDb250ZXh0dWFsUmVuZGVyZWRJbWFnZUZhY3Rvcnl9LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIFBhcmFtZXRlckJsb2NrIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IHNlcmlhbFZlcnNpb25VSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc1NzcxMTU1NTE3ODUyNDA3NTBMOworCisgICAgLyoqCisgICAgICogVGhlIHNvdXJjZXMgKHJlbmRlcmFibGUgaW1hZ2VzKS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVmVjdG9yPE9iamVjdD4gc291cmNlcyA9IG5ldyBWZWN0b3I8T2JqZWN0PigpOworCisgICAgLyoqCisgICAgICogVGhlIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFZlY3RvcjxPYmplY3Q+IHBhcmFtZXRlcnMgPSBuZXcgVmVjdG9yPE9iamVjdD4oKTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZWN0b3Igb2Ygc291cmNlIGltYWdlcy4KKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVycworICAgICAqICAgICAgICAgICAgdGhlIHZlY3RvciBvZiBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayhWZWN0b3I8T2JqZWN0PiBzb3VyY2VzLCBWZWN0b3I8T2JqZWN0PiBwYXJhbWV0ZXJzKSB7CisgICAgICAgIHNldFNvdXJjZXMoc291cmNlcyk7CisgICAgICAgIHNldFBhcmFtZXRlcnMocGFyYW1ldGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHBhcmFtZXRlciBibG9jayB3aXRoIG5vIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZWN0b3Igb2Ygc291cmNlIGltYWdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2soVmVjdG9yPE9iamVjdD4gc291cmNlcykgeworICAgICAgICBzZXRTb3VyY2VzKHNvdXJjZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBwYXJhbWV0ZXIgYmxvY2sgd2l0aCBubyBpbWFnZSBvciBwYXJhbWV0ZXIgdmVjdG9ycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2soKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc291cmNlIGltYWdlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aGVyZSB0aGUgc291cmNlIHdpbGwgYmUgcGxhY2VkLgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIHNldFNvdXJjZShPYmplY3Qgc291cmNlLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKHNvdXJjZXMuc2l6ZSgpIDwgaW5kZXggKyAxKSB7CisgICAgICAgICAgICBzb3VyY2VzLnNldFNpemUoaW5kZXggKyAxKTsKKyAgICAgICAgfQorICAgICAgICBzb3VyY2VzLnNldEVsZW1lbnRBdChzb3VyY2UsIGluZGV4KTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGFyYW1ldGVyIHZhbHVlIG9iamVjdCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgdmFsdWUgdG8gcGxhY2UgYXQgdGhlIGRlc2lyZWQgaW5kZXguCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggd2hlcmUgdGhlIG9iamVjdCBpcyB0byBiZSBwbGFjZWQgaW4gdGhlIHZlY3RvciBvZgorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVycy4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBzZXQoT2JqZWN0IG9iaiwgaW50IGluZGV4KSB7CisgICAgICAgIGlmIChwYXJhbWV0ZXJzLnNpemUoKSA8IGluZGV4ICsgMSkgeworICAgICAgICAgICAgcGFyYW1ldGVycy5zZXRTaXplKGluZGV4ICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgcGFyYW1ldGVycy5zZXRFbGVtZW50QXQob2JqLCBpbmRleCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBzb3VyY2UgdG8gdGhlIHZlY3RvciBvZiBzb3VyY2VzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgdG8gYWRkLgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIGFkZFNvdXJjZShPYmplY3Qgc291cmNlKSB7CisgICAgICAgIHNvdXJjZXMuYWRkRWxlbWVudChzb3VyY2UpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBvYmplY3QgdG8gdGhlIHZlY3RvciBvZiBwYXJhbWV0ZXIgdmFsdWVzCisgICAgICogCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iaiB0byBhZGQuCisgICAgICogQHJldHVybiB0aGlzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgYWRkKE9iamVjdCBvYmopIHsKKyAgICAgICAgcGFyYW1ldGVycy5hZGRFbGVtZW50KG9iaik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZlY3RvciBvZiBzb3VyY2VzLCByZXBsYWNpbmcgdGhlIGV4aXN0aW5nIHZlY3RvciBvZiBzb3VyY2VzLCBpZgorICAgICAqIGFueS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlcworICAgICAqICAgICAgICAgICAgdGhlIG5ldyBzb3VyY2VzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZXMoVmVjdG9yPE9iamVjdD4gc291cmNlcykgeworICAgICAgICB0aGlzLnNvdXJjZXMgPSBzb3VyY2VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZlY3RvciBvZiBwYXJhbWV0ZXJzLCByZXBsYWNpbmcgdGhlIGV4aXN0aW5nIHZlY3RvciBvZgorICAgICAqIHBhcmFtZXRlcnMsIGlmIGFueS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVycworICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcnMoVmVjdG9yPE9iamVjdD4gcGFyYW1ldGVycykgeworICAgICAgICB0aGlzLnBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZlY3RvciBvZiBzb3VyY2VzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZXMuCisgICAgICovCisgICAgcHVibGljIFZlY3RvcjxPYmplY3Q+IGdldFNvdXJjZXMoKSB7CisgICAgICAgIHJldHVybiBzb3VyY2VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZlY3RvciBvZiBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHVibGljIFZlY3RvcjxPYmplY3Q+IGdldFBhcmFtZXRlcnMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSBvYmplY3QgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFNvdXJjZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHNvdXJjZXMuZWxlbWVudEF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvYmplY3QgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXguCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyIG9iamVjdCBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0UGFyYW1ldGVyKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gcGFyYW1ldGVycy5lbGVtZW50QXQoaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNoYWxsb3cgY2xvbmUgKGNsb25lcyB1c2luZyB0aGUgc3VwZXJjbGFzcyBjbG9uZSBtZXRob2QpLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNsb25lIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3Qgc2hhbGxvd0Nsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMgUGFyYW1ldGVyQmxvY2sgaW5zdGFuY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaWRlbnRpY2FsIGNvcHkgb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBQYXJhbWV0ZXJCbG9jayByZXBsaWNhOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVwbGljYSA9IChQYXJhbWV0ZXJCbG9jaylzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNvdXJjZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVwbGljYS5zZXRTb3VyY2VzKChWZWN0b3I8T2JqZWN0Pikoc291cmNlcy5jbG9uZSgpKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtZXRlcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVwbGljYS5zZXRQYXJhbWV0ZXJzKChWZWN0b3I8T2JqZWN0PikocGFyYW1ldGVycy5jbG9uZSgpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcGxpY2E7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBjbGFzc2VzIGNvcnJlc3BvbmRpbmcgdG8gYWxsIG9mIHRoZSBwYXJhbWV0ZXIgdmFsdWVzCisgICAgICogZm91bmQgaW4gdGhlIGFycmF5IG9mIHBhcmFtZXRlcnMsIGluIG9yZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciBjbGFzc2VzLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc1tdIGdldFBhcmFtQ2xhc3NlcygpIHsKKyAgICAgICAgaW50IGNvdW50ID0gcGFyYW1ldGVycy5zaXplKCk7CisgICAgICAgIENsYXNzIHBhcmFtQ2xhc3Nlc1tdID0gbmV3IENsYXNzW2NvdW50XTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgIHBhcmFtQ2xhc3Nlc1tpXSA9IHBhcmFtZXRlcnMuZWxlbWVudEF0KGkpLmdldENsYXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhcmFtQ2xhc3NlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZW5kZXJhYmxlIHNvdXJjZSBpbWFnZSBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGluIHRoZQorICAgICAqIHNvdXJjZSBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZW5kZXJhYmxlIHNvdXJjZSBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyYWJsZUltYWdlIGdldFJlbmRlcmFibGVTb3VyY2UoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoUmVuZGVyYWJsZUltYWdlKXNvdXJjZXMuZWxlbWVudEF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgc2hvcnQgdmFsdWUgaW4gYSBTaG9ydCBhbmQgcGxhY2VzIGl0IGluIHRoZSBwYXJhbWV0ZXIgYmxvY2sgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBzZXQoc2hvcnQgcywgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBzZXQobmV3IFNob3J0KHMpLCBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIHNob3J0IHZhbHVlIGluIGEgU2hvcnQgYW5kIGFkZHMgaXQgdG8gdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNob3J0IHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHJldHVybiB0aGlzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgYWRkKHNob3J0IHMpIHsKKyAgICAgICAgcmV0dXJuIGFkZChuZXcgU2hvcnQocykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBsb25nIHZhbHVlIGluIGEgTG9uZyBhbmQgcGxhY2VzIGl0IGluIHRoZSBwYXJhbWV0ZXIgYmxvY2sgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIHNldChsb25nIGwsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gc2V0KG5ldyBMb25nKGwpLCBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIGxvbmcgdmFsdWUgaW4gYSBMb25nIGFuZCBhZGRzIGl0IHRvIHRoZSBwYXJhbWV0ZXIgYmxvY2suCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHJldHVybiB0aGlzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgYWRkKGxvbmcgbCkgeworICAgICAgICByZXR1cm4gYWRkKG5ldyBMb25nKGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgaW50ZWdlciB2YWx1ZSBpbiBhbiBJbnRlZ2VyIGFuZCBwbGFjZXMgaXQgaW4gdGhlIHBhcmFtZXRlcgorICAgICAqIGJsb2NrIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXguCisgICAgICogQHJldHVybiB0aGlzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgc2V0KGludCBpLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHNldChuZXcgSW50ZWdlcihpKSwgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBpbnRlZ2VyIHZhbHVlIGluIGFuIEludGVnZXIgYW5kIGFkZHMgaXQgdG8gdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBhZGQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGFkZChuZXcgSW50ZWdlcihpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIGZsb2F0IHZhbHVlIGluIGEgRmxvYXQgYW5kIHBsYWNlcyBpdCBpbiB0aGUgcGFyYW1ldGVyIGJsb2NrIGF0CisgICAgICogdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXguCisgICAgICogQHJldHVybiB0aGlzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgc2V0KGZsb2F0IGYsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gc2V0KG5ldyBGbG9hdChmKSwgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBmbG9hdCB2YWx1ZSBpbiBhIEZsb2F0IGFuZCBhZGRzIGl0IHRvIHRoZSBwYXJhbWV0ZXIgYmxvY2suCisgICAgICogCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIGFkZChmbG9hdCBmKSB7CisgICAgICAgIHJldHVybiBhZGQobmV3IEZsb2F0KGYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgZG91YmxlIHZhbHVlIGluIGEgRG91YmxlIGFuZCBwbGFjZXMgaXQgaW4gdGhlIHBhcmFtZXRlciBibG9jaworICAgICAqIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBzZXQoZG91YmxlIGQsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gc2V0KG5ldyBEb3VibGUoZCksIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgZG91YmxlIHZhbHVlIGluIGEgRG91YmxlIGFuZCBhZGRzIGl0IHRvIHRoZSBwYXJhbWV0ZXIgYmxvY2suCisgICAgICogCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBhZGQoZG91YmxlIGQpIHsKKyAgICAgICAgcmV0dXJuIGFkZChuZXcgRG91YmxlKGQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgY2hhciB2YWx1ZSBpbiBhIENoYXJhY3RlciBhbmQgcGxhY2VzIGl0IGluIHRoZSBwYXJhbWV0ZXIgYmxvY2sKKyAgICAgKiBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhciB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIHNldChjaGFyIGMsIGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gc2V0KG5ldyBDaGFyYWN0ZXIoYyksIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgY2hhciB2YWx1ZSBpbiBhIENoYXJhY3RlciBhbmQgYWRkcyBpdCB0byB0aGUgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhciB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gdGhpcyBwYXJhbWV0ZXIgYmxvY2suCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckJsb2NrIGFkZChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGFkZChuZXcgQ2hhcmFjdGVyKGMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB0aGUgYnl0ZSB2YWx1ZSBpbiBhIEJ5dGUgYW5kIHBsYWNlcyBpdCBpbiB0aGUgcGFyYW1ldGVyIGJsb2NrIGF0CisgICAgICogdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBzZXQoYnl0ZSBiLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHNldChuZXcgQnl0ZShiKSwgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBieXRlIHZhbHVlIGluIGEgQnl0ZSBhbmQgYWRkcyBpdCB0byB0aGUgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgYWRkKGJ5dGUgYikgeworICAgICAgICByZXR1cm4gYWRkKG5ldyBCeXRlKGIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBSZW5kZXJlZEltYWdlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggZnJvbSB0aGUgdmVjdG9yIG9mIHNvdXJjZQorICAgICAqIGltYWdlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZW5kZXJlZCBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyZWRJbWFnZSBnZXRSZW5kZXJlZFNvdXJjZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIChSZW5kZXJlZEltYWdlKXNvdXJjZXMuZWxlbWVudEF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzaG9ydC12YWx1ZWQgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZSB2ZWN0b3IKKyAgICAgKiBvZiBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIHNob3J0IHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnRQYXJhbWV0ZXIoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoKFNob3J0KXBhcmFtZXRlcnMuZWxlbWVudEF0KGluZGV4KSkuc2hvcnRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvbmctdmFsdWVkIHBhcmFtZXRlciBmb3VuZCBhdCB0aGUgZGVzaXJlZCBpbmRleCBpbiB0aGUgdmVjdG9yCisgICAgICogb2YgcGFyYW1ldGVyIHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsb25nIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nUGFyYW1ldGVyKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChMb25nKXBhcmFtZXRlcnMuZWxlbWVudEF0KGluZGV4KSkubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW50ZWdlci12YWx1ZWQgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZQorICAgICAqIHZlY3RvciBvZiBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGludGVnZXIgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW50UGFyYW1ldGVyKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChJbnRlZ2VyKXBhcmFtZXRlcnMuZWxlbWVudEF0KGluZGV4KSkuaW50VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmbG9hdC12YWx1ZWQgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZSB2ZWN0b3IKKyAgICAgKiBvZiBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXRQYXJhbWV0ZXIoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoKEZsb2F0KXBhcmFtZXRlcnMuZWxlbWVudEF0KGluZGV4KSkuZmxvYXRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRvdWJsZS12YWx1ZWQgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZSB2ZWN0b3IKKyAgICAgKiBvZiBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGRvdWJsZSBwYXJhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGVQYXJhbWV0ZXIoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoKERvdWJsZSlwYXJhbWV0ZXJzLmVsZW1lbnRBdChpbmRleCkpLmRvdWJsZVZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY2hhci12YWx1ZWQgcGFyYW1ldGVyIGZvdW5kIGF0IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZSB2ZWN0b3IKKyAgICAgKiBvZiBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGNoYXIgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldENoYXJQYXJhbWV0ZXIoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoKENoYXJhY3RlcilwYXJhbWV0ZXJzLmVsZW1lbnRBdChpbmRleCkpLmNoYXJWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJ5dGUtdmFsdWVkIHBhcmFtZXRlciBmb3VuZCBhdCB0aGUgZGVzaXJlZCBpbmRleCBpbiB0aGUgdmVjdG9yCisgICAgICogb2YgcGFyYW1ldGVyIHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlUGFyYW1ldGVyKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChCeXRlKXBhcmFtZXRlcnMuZWxlbWVudEF0KGluZGV4KSkuYnl0ZVZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSB2ZWN0b3Igb2Ygc291cmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVTb3VyY2VzKCkgeworICAgICAgICBzb3VyY2VzLnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSB2ZWN0b3Igb2YgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVQYXJhbWV0ZXJzKCkgeworICAgICAgICBwYXJhbWV0ZXJzLnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3Igb2Ygc291cmNlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHZlY3RvciBvZiBzb3VyY2VzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtU291cmNlcygpIHsKKyAgICAgICAgcmV0dXJuIHNvdXJjZXMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdmVjdG9yIG9mIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3Igb2YgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bVBhcmFtZXRlcnMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLnNpemUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJDb250ZXh0LmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGRiNTEyZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL1JlbmRlckNvbnRleHQuamF2YQpAQCAtMCwwICsxLDIxNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2UucmVuZGVyYWJsZTsKKworaW1wb3J0IGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzOworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworCisvKioKKyAqIFRoZSBDbGFzcyBSZW5kZXJDb250ZXh0IHN0b3JlcyBkYXRhIG9uIGhvdyBhbiBpbWFnZSBpcyB0byBiZSByZW5kZXJlZDogdGhlCisgKiBhZmZpbmUgdHJhbnNmb3JtLCB0aGUgYXJlYSBvZiBpbnRlcmVzdCwgYW5kIHRoZSByZW5kZXJpbmcgaGludHMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmVuZGVyQ29udGV4dCBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWZmaW5lIHRyYW5zZm9ybS4KKyAgICAgKi8KKyAgICBBZmZpbmVUcmFuc2Zvcm0gdHJhbnNmb3JtOworCisgICAgLyoqCisgICAgICogVGhlIGFyZWEgb2YgaW50ZXJlc3QuCisgICAgICovCisgICAgU2hhcGUgYW9pOworCisgICAgLyoqCisgICAgICogVGhlIHJlbmRlcmluZyBoaW50cy4KKyAgICAgKi8KKyAgICBSZW5kZXJpbmdIaW50cyBoaW50czsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyByZW5kZXIgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdXNyMmRldgorICAgICAqICAgICAgICAgICAgdGhlIGFmZmluZSB0cmFuc2Zvcm0uCisgICAgICogQHBhcmFtIGFvaQorICAgICAqICAgICAgICAgICAgdGhlIGFyZWEgb2YgaW50ZXJlc3QuCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJDb250ZXh0KEFmZmluZVRyYW5zZm9ybSB1c3IyZGV2LCBTaGFwZSBhb2ksIFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHRoaXMudHJhbnNmb3JtID0gKEFmZmluZVRyYW5zZm9ybSl1c3IyZGV2LmNsb25lKCk7CisgICAgICAgIHRoaXMuYW9pID0gYW9pOworICAgICAgICB0aGlzLmhpbnRzID0gaGludHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IHJlbmRlciBjb250ZXh0IHdpdGggbm8gc3BlY2lmaWVkIGhpbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB1c3IyZGV2CisgICAgICogICAgICAgICAgICB0aGUgYWZmaW5lIHRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gYW9pCisgICAgICogICAgICAgICAgICB0aGUgYXJlYSBvZiBpbnRlcmVzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyQ29udGV4dChBZmZpbmVUcmFuc2Zvcm0gdXNyMmRldiwgU2hhcGUgYW9pKSB7CisgICAgICAgIHRoaXModXNyMmRldiwgYW9pLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVuZGVyIGNvbnRleHQgd2l0aCBubyBzcGVjaWZpZWQgYXJlYSBvZiBpbnRlcmVzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdXNyMmRldgorICAgICAqICAgICAgICAgICAgdGhlIGFmZmluZSB0cmFuc2Zvcm0uCisgICAgICogQHBhcmFtIGhpbnRzCisgICAgICogICAgICAgICAgICB0aGUgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJDb250ZXh0KEFmZmluZVRyYW5zZm9ybSB1c3IyZGV2LCBSZW5kZXJpbmdIaW50cyBoaW50cykgeworICAgICAgICB0aGlzKHVzcjJkZXYsIG51bGwsIGhpbnRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgcmVuZGVyIGNvbnRleHQgd2l0aCBubyByZW5kZXJpbmcgaGludHMgb3IgYXJlYSBvZgorICAgICAqIGludGVyZXN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB1c3IyZGV2CisgICAgICogICAgICAgICAgICB0aGUgYWZmaW5lIHRyYW5zZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyQ29udGV4dChBZmZpbmVUcmFuc2Zvcm0gdXNyMmRldikgeworICAgICAgICB0aGlzKHVzcjJkZXYsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVuZGVyQ29udGV4dCh0cmFuc2Zvcm0sIGFvaSwgaGludHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFmZmluZSB0cmFuc2Zvcm0gZm9yIHRoaXMgcmVuZGVyIGNvbnRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIG5ld1RyYW5zZm9ybQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhZmZpbmUgdHJhbnNmb3JtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0gbmV3VHJhbnNmb3JtKSB7CisgICAgICAgIHRyYW5zZm9ybSA9IChBZmZpbmVUcmFuc2Zvcm0pbmV3VHJhbnNmb3JtLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uY2F0ZW5hdGVzIHRoZSBjdXJyZW50IHRyYW5zZm9ybSB3aXRoIHRoZSBzcGVjaWZpZWQgdHJhbnNmb3JtIChzbyB0aGV5CisgICAgICogYXJlIGFwcGxpZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHRyYW5zZm9ybSBhY3RpbmcgZmlyc3QpIGFuZCBzZXRzIHRoZQorICAgICAqIHJlc3VsdGluZyB0cmFuc2Zvcm0gYXMgdGhlIGFmZmluZSB0cmFuc2Zvcm0gb2YgdGhpcyByZW5kZXJpbmcgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kVHJhbnNmb3JtCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRyYW5zZm9ybSB3aGljaCBtb2RpZmllcyB0aGUgY3VycmVudCB0cmFuc2Zvcm0uCisgICAgICogQGRlcHJlY2F0ZWQgdXNlCisgICAgICogICAgICAgICAgICAge0BsaW5rIFJlbmRlckNvbnRleHQjcHJlQ29uY2F0ZW5hdGVUcmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtKX0KKyAgICAgKiAgICAgICAgICAgICAuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBwcmVDb25jZXRlbmF0ZVRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0gbW9kVHJhbnNmb3JtKSB7CisgICAgICAgIHByZUNvbmNhdGVuYXRlVHJhbnNmb3JtKG1vZFRyYW5zZm9ybSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uY2F0ZW5hdGVzIHRoZSBjdXJyZW50IHRyYW5zZm9ybSB3aXRoIHRoZSBzcGVjaWZpZWQgdHJhbnNmb3JtIChzbyB0aGV5CisgICAgICogYXJlIGFwcGxpZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHRyYW5zZm9ybSBhY3RpbmcgZmlyc3QpIGFuZCBzZXRzIHRoZQorICAgICAqIHJlc3VsdGluZyB0cmFuc2Zvcm0gYXMgdGhlIGFmZmluZSB0cmFuc2Zvcm0gb2YgdGhpcyByZW5kZXJpbmcgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kVHJhbnNmb3JtCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRyYW5zZm9ybSB3aGljaCBtb2RpZmllcyB0aGUgY3VycmVudCB0cmFuc2Zvcm0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlQ29uY2F0ZW5hdGVUcmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtIG1vZFRyYW5zZm9ybSkgeworICAgICAgICB0cmFuc2Zvcm0ucHJlQ29uY2F0ZW5hdGUobW9kVHJhbnNmb3JtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25jYXRlbmF0ZSB0aGUgc3BlY2lmaWVkIHRyYW5zZm9ybSB3aXRoIHRoZSBjdXJyZW50IHRyYW5zZm9ybS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbW9kVHJhbnNmb3JtCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRyYW5zZm9ybSB3aGljaCBtb2RpZmllcyB0aGUgY3VycmVudCB0cmFuc2Zvcm0uCisgICAgICogQGRlcHJlY2F0ZWQgdXNlCisgICAgICogICAgICAgICAgICAge0BsaW5rIFJlbmRlckNvbnRleHQjY29uY2F0ZW5hdGVUcmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtKX0uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBjb25jZXRlbmF0ZVRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0gbW9kVHJhbnNmb3JtKSB7CisgICAgICAgIGNvbmNhdGVuYXRlVHJhbnNmb3JtKG1vZFRyYW5zZm9ybSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uY2F0ZW5hdGUgdGhlIHNwZWNpZmllZCB0cmFuc2Zvcm0gd2l0aCB0aGUgY3VycmVudCB0cmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIG1vZFRyYW5zZm9ybQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB0cmFuc2Zvcm0gd2hpY2ggbW9kaWZpZXMgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbmNhdGVuYXRlVHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSBtb2RUcmFuc2Zvcm0pIHsKKyAgICAgICAgdHJhbnNmb3JtLmNvbmNhdGVuYXRlKG1vZFRyYW5zZm9ybSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdHJhbnNmb3JtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldFRyYW5zZm9ybSgpIHsKKyAgICAgICAgcmV0dXJuIChBZmZpbmVUcmFuc2Zvcm0pdHJhbnNmb3JtLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYXJlYSBvZiBpbnRlcmVzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3QW9pCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGFyZWEgb2YgaW50ZXJlc3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXJlYU9mSW50ZXJlc3QoU2hhcGUgbmV3QW9pKSB7CisgICAgICAgIGFvaSA9IG5ld0FvaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcmVhIG9mIGludGVyZXN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFyZWEgb2YgaW50ZXJlc3QuCisgICAgICovCisgICAgcHVibGljIFNoYXBlIGdldEFyZWFPZkludGVyZXN0KCkgeworICAgICAgICByZXR1cm4gYW9pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJlbmRlcmluZyBoaW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlbmRlcmluZ0hpbnRzKFJlbmRlcmluZ0hpbnRzIGhpbnRzKSB7CisgICAgICAgIHRoaXMuaGludHMgPSBoaW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZW5kZXJpbmcgaGludHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcmVuZGVyaW5nIGhpbnRzLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJpbmdIaW50cyBnZXRSZW5kZXJpbmdIaW50cygpIHsKKyAgICAgICAgcmV0dXJuIGhpbnRzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL1JlbmRlcmFibGVJbWFnZS5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUmVuZGVyYWJsZUltYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjEzMzJmNwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL1JlbmRlcmFibGVJbWFnZS5qYXZhCkBAIC0wLDAgKzEsMTM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBqYXZhLmF3dC5pbWFnZS5yZW5kZXJhYmxlOworCitpbXBvcnQgamF2YS5hd3QuUmVuZGVyaW5nSGludHM7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmVuZGVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCisvKioKKyAqIFRoZSBJbnRlcmZhY2UgUmVuZGVyYWJsZUltYWdlIGlzIGltcGxlbWVudGVkIGJ5IGFuIG9iamVjdCB0aGF0IGNvbGxlY3RzIGFsbAorICogb2YgdGhlIGltYWdlLXNwZWNpZmljIGRhdGEgdGhhdCBkZWZpbmVzIGEgc2luZ2xlIGltYWdlIHRoYXQgY291bGQgYmUgcmVuZGVyZWQKKyAqIHRvIGRpZmZlcmVudCByZW5kZXJpbmcgdGFyZ2V0cy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVuZGVyYWJsZUltYWdlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBISU5UU19PQlNFUlZFRCBpbmRpY2F0ZXMgdGhhdCB0aGUgcmVuZGVyaW5nIGhpbnRzIGFyZQorICAgICAqIGFwcGxpZWQgcmF0aGVyIHRoYW4gaWdub3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBISU5UU19PQlNFUlZFRCA9ICJISU5UU19PQlNFUlZFRCI7IC8vJE5PTi1OTFMtMSQKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByb3BlcnR5IGZyb20gdGhlIFJlbmRlcmFibGVJbWFnZSdzIHBhcmFtZXRlciBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSByZW5kZXJlZCBpbWFnZSBiYXNlZCBvbiB0aGUgaW5mb3JtYXRpb24gY29udGFpbmVkIGluIHRoZQorICAgICAqIHBhcmFtZXRlcnMgYW5kIHRoZSByZW5kZXIgY29udGV4dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVuZGVyQ29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIHJlbmRlciBjb250ZXh0IGdpdmluZyByZW5kZXJpbmcgc3BlY2lmaWNhdGlvbnMgc3VjaCBhcworICAgICAqICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25zLgorICAgICAqIEByZXR1cm4gdGhlIHJlbmRlcmVkIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJlZEltYWdlIGNyZWF0ZVJlbmRlcmluZyhSZW5kZXJDb250ZXh0IHJlbmRlckNvbnRleHQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgc2NhbGVkIHJlbmRlcmVkIGltYWdlIGJhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4KKyAgICAgKiB0aGUgcGFyYW1ldGVycyBhbmQgdGhlIHJlbmRlciBjb250ZXh0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgZGVzaXJlZCB3aWR0aCBhZnRlciBzY2FsaW5nIG9yIHplcm8gaWYgdGhlIHNjYWxpbmcgc2hvdWxkCisgICAgICogICAgICAgICAgICBiZSBwcm9wb3J0aW9uYWwsIGJhc2VkIG9uIHRoZSBoZWlnaHQuCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIGhlaWdodCBhZnRlciBzY2FsaW5nIG9yIHplcm8gaWYgdGhlIHNjYWxpbmcgc2hvdWxkCisgICAgICogICAgICAgICAgICBiZSBwcm9wb3J0aW9uYWwsIGJhc2VkIG9uIHRoZSB3aWR0aC4KKyAgICAgKiBAcGFyYW0gaGludHMKKyAgICAgKiAgICAgICAgICAgIHRoZSByZW5kZXJpbmcgaGludHMgdG8gdXNlLgorICAgICAqIEByZXR1cm4gdGhlIHJlbmRlcmVkIGltYWdlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYm90aCB0aGUgaGVpZ2h0IGFuZCB3aWR0aCBhcmUgemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyZWRJbWFnZSBjcmVhdGVTY2FsZWRSZW5kZXJpbmcoaW50IHcsIGludCBoLCBSZW5kZXJpbmdIaW50cyBoaW50cyk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2ZWN0b3Igb2Ygc291cmNlcyBmcm9tIHRoZSBwYXJhbWV0ZXIgYmxvY2suCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc291cmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVmVjdG9yPFJlbmRlcmFibGVJbWFnZT4gZ2V0U291cmNlcygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZXMgb2YgYWxsIG9mIHRoZSBzdXBwb3J0ZWQgcHJvcGVydGllcyBpbiB0aGUgY3VycmVudCBjb250ZXh0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnR5IG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRQcm9wZXJ0eU5hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBkZWZhdWx0IHJlbmRlcmluZyAodXNpbmcgdGhlIGlkZW50aXR5IHRyYW5zZm9ybSBhbmQgZGVmYXVsdAorICAgICAqIHJlbmRlciBjb250ZXh0KS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSByZW5kZXJlZCBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVuZGVyZWRJbWFnZSBjcmVhdGVEZWZhdWx0UmVuZGVyaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhpcyBjb250ZXh0IHN1cHBvcnRzIGR5bmFtaWMgcmVuZGVyaW5nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBjb250ZXh0IHN1cHBvcnRzIGR5bmFtaWMgcmVuZGVyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRHluYW1pYygpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2lkdGggb2YgdGhlIGltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHdpZHRoIG9mIHRoZSBpbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0V2lkdGgoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWluWSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRNaW5YKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIGltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEhlaWdodCgpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJhYmxlSW1hZ2VPcC5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUmVuZGVyYWJsZUltYWdlT3AuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzQ1MzcyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUmVuZGVyYWJsZUltYWdlT3AuamF2YQpAQCAtMCwwICsxLDE5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2UucmVuZGVyYWJsZTsKKworaW1wb3J0IGphdmEuYXd0LlJlbmRlcmluZ0hpbnRzOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmVuZGVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogVGhlIENsYXNzIFJlbmRlcmFibGVJbWFnZU9wIGlzIGEgYmFzaWMgaW1wbGVtZW50YXRpb24gb2YgUmVuZGVyYWJsZUltYWdlLAorICogd2l0aCBtZXRob2RzIHRvIGFjY2VzcyB0aGUgcGFyYW1ldGVyIGRhdGEgYW5kIHBlcmZvcm0gcmVuZGVyaW5nIG9wZXJhdGlvbnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmVuZGVyYWJsZUltYWdlT3AgaW1wbGVtZW50cyBSZW5kZXJhYmxlSW1hZ2UgeworCisgICAgLyoqCisgICAgICogVGhlIENSSUYuCisgICAgICovCisgICAgQ29udGV4dHVhbFJlbmRlcmVkSW1hZ2VGYWN0b3J5IENSSUY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGFyYW0gYmxvY2suCisgICAgICovCisgICAgUGFyYW1ldGVyQmxvY2sgcGFyYW1CbG9jazsKKworICAgIC8qKgorICAgICAqIFRoZSBoZWlnaHQuCisgICAgICovCisgICAgZmxvYXQgbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodDsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyByZW5kZXJhYmxlIGltYWdlIG9wLgorICAgICAqIAorICAgICAqIEBwYXJhbSBDUklGCisgICAgICogICAgICAgICAgICB0aGUgY1JJRi4KKyAgICAgKiBAcGFyYW0gcGFyYW1CbG9jaworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtIGJsb2NrLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJhYmxlSW1hZ2VPcChDb250ZXh0dWFsUmVuZGVyZWRJbWFnZUZhY3RvcnkgQ1JJRiwgUGFyYW1ldGVyQmxvY2sgcGFyYW1CbG9jaykgeworICAgICAgICB0aGlzLkNSSUYgPSBDUklGOworICAgICAgICB0aGlzLnBhcmFtQmxvY2sgPSAoUGFyYW1ldGVyQmxvY2spcGFyYW1CbG9jay5jbG9uZSgpOworICAgICAgICBSZWN0YW5nbGUyRCByID0gQ1JJRi5nZXRCb3VuZHMyRChwYXJhbUJsb2NrKTsKKyAgICAgICAgbWluWCA9IChmbG9hdClyLmdldE1pblgoKTsKKyAgICAgICAgbWluWSA9IChmbG9hdClyLmdldE1pblkoKTsKKyAgICAgICAgd2lkdGggPSAoZmxvYXQpci5nZXRXaWR0aCgpOworICAgICAgICBoZWlnaHQgPSAoZmxvYXQpci5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBDUklGLmdldFByb3BlcnR5KHBhcmFtQmxvY2ssIG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW1CbG9jaworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtIGJsb2NrLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyQmxvY2sgc2V0UGFyYW1ldGVyQmxvY2soUGFyYW1ldGVyQmxvY2sgcGFyYW1CbG9jaykgeworICAgICAgICBQYXJhbWV0ZXJCbG9jayBvbGRQYXJhbSA9IHRoaXMucGFyYW1CbG9jazsKKyAgICAgICAgdGhpcy5wYXJhbUJsb2NrID0gKFBhcmFtZXRlckJsb2NrKXBhcmFtQmxvY2suY2xvbmUoKTsKKyAgICAgICAgcmV0dXJuIG9sZFBhcmFtOworICAgIH0KKworICAgIHB1YmxpYyBSZW5kZXJlZEltYWdlIGNyZWF0ZVJlbmRlcmluZyhSZW5kZXJDb250ZXh0IHJlbmRlckNvbnRleHQpIHsKKworICAgICAgICBWZWN0b3I8UmVuZGVyYWJsZUltYWdlPiBzb3VyY2VzID0gZ2V0U291cmNlcygpOworICAgICAgICBQYXJhbWV0ZXJCbG9jayByZFBhcmFtID0gKFBhcmFtZXRlckJsb2NrKXBhcmFtQmxvY2suY2xvbmUoKTsKKworICAgICAgICBpZiAoc291cmNlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBWZWN0b3I8T2JqZWN0PiByZFNvdXJjZXMgPSBuZXcgVmVjdG9yPE9iamVjdD4oKTsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIHdoaWxlIChpIDwgc291cmNlcy5zaXplKCkpIHsKKyAgICAgICAgICAgICAgICBSZW5kZXJDb250ZXh0IG5ld0NvbnRleHQgPSBDUklGCisgICAgICAgICAgICAgICAgICAgICAgICAubWFwUmVuZGVyQ29udGV4dChpLCByZW5kZXJDb250ZXh0LCBwYXJhbUJsb2NrLCB0aGlzKTsKKyAgICAgICAgICAgICAgICBSZW5kZXJlZEltYWdlIHJkaW0gPSBzb3VyY2VzLmVsZW1lbnRBdChpKS5jcmVhdGVSZW5kZXJpbmcobmV3Q29udGV4dCk7CisKKyAgICAgICAgICAgICAgICBpZiAocmRpbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJkU291cmNlcy5hZGRFbGVtZW50KHJkaW0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocmRTb3VyY2VzLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICByZFBhcmFtLnNldFNvdXJjZXMocmRTb3VyY2VzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ1JJRi5jcmVhdGUocmVuZGVyQ29udGV4dCwgcmRQYXJhbSk7CisgICAgfQorCisgICAgcHVibGljIFJlbmRlcmVkSW1hZ2UgY3JlYXRlU2NhbGVkUmVuZGVyaW5nKGludCB3LCBpbnQgaCwgUmVuZGVyaW5nSGludHMgaGludHMpIHsKKyAgICAgICAgaWYgKHcgPT0gMCAmJiBoID09IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC42MD1XaWR0aCBhbmQgSGVpZ2h0IG11c3RuJ3QgYmUgZXF1YWwgemVybyBib3RoCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjYwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHcgPT0gMCkgeworICAgICAgICAgICAgdyA9IE1hdGgucm91bmQoaCAqIChnZXRXaWR0aCgpIC8gZ2V0SGVpZ2h0KCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChoID09IDApIHsKKyAgICAgICAgICAgIGggPSBNYXRoLnJvdW5kKHcgKiAoZ2V0SGVpZ2h0KCkgLyBnZXRXaWR0aCgpKSk7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgc3ggPSAoZG91YmxlKXcgLyBnZXRXaWR0aCgpOworICAgICAgICBkb3VibGUgc3kgPSAoZG91YmxlKWggLyBnZXRIZWlnaHQoKTsKKworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gYXQgPSBBZmZpbmVUcmFuc2Zvcm0uZ2V0U2NhbGVJbnN0YW5jZShzeCwgc3kpOworICAgICAgICBSZW5kZXJDb250ZXh0IGNvbnRleHQgPSBuZXcgUmVuZGVyQ29udGV4dChhdCwgaGludHMpOworICAgICAgICByZXR1cm4gY3JlYXRlUmVuZGVyaW5nKGNvbnRleHQpOworICAgIH0KKworICAgIHB1YmxpYyBWZWN0b3I8UmVuZGVyYWJsZUltYWdlPiBnZXRTb3VyY2VzKCkgeworICAgICAgICBpZiAocGFyYW1CbG9jay5nZXROdW1Tb3VyY2VzKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgVmVjdG9yPFJlbmRlcmFibGVJbWFnZT4gdiA9IG5ldyBWZWN0b3I8UmVuZGVyYWJsZUltYWdlPigpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChpIDwgcGFyYW1CbG9jay5nZXROdW1Tb3VyY2VzKCkpIHsKKyAgICAgICAgICAgIE9iamVjdCBvID0gcGFyYW1CbG9jay5nZXRTb3VyY2UoaSk7CisgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFJlbmRlcmFibGVJbWFnZSkgeworICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudCgoUmVuZGVyYWJsZUltYWdlKW8pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRQcm9wZXJ0eU5hbWVzKCkgeworICAgICAgICByZXR1cm4gQ1JJRi5nZXRQcm9wZXJ0eU5hbWVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGFyYW1ldGVyIGJsb2NrLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciBibG9jaworICAgICAqLworICAgIHB1YmxpYyBQYXJhbWV0ZXJCbG9jayBnZXRQYXJhbWV0ZXJCbG9jaygpIHsKKyAgICAgICAgcmV0dXJuIHBhcmFtQmxvY2s7CisgICAgfQorCisgICAgcHVibGljIFJlbmRlcmVkSW1hZ2UgY3JlYXRlRGVmYXVsdFJlbmRlcmluZygpIHsKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICBSZW5kZXJDb250ZXh0IGNvbnRleHQgPSBuZXcgUmVuZGVyQ29udGV4dChhdCk7CisgICAgICAgIHJldHVybiBjcmVhdGVSZW5kZXJpbmcoY29udGV4dCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNEeW5hbWljKCkgeworICAgICAgICByZXR1cm4gQ1JJRi5pc0R5bmFtaWMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0V2lkdGgoKSB7CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWluWSgpIHsKKyAgICAgICAgcmV0dXJuIG1pblk7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldE1pblgoKSB7CisgICAgICAgIHJldHVybiBtaW5YOworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdCBnZXRIZWlnaHQoKSB7CisgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJhYmxlSW1hZ2VQcm9kdWNlci5qYXZhIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUmVuZGVyYWJsZUltYWdlUHJvZHVjZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODNlYmM3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L2ltYWdlL3JlbmRlcmFibGUvUmVuZGVyYWJsZUltYWdlUHJvZHVjZXIuamF2YQpAQCAtMCwwICsxLDE1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgamF2YS5hd3QuaW1hZ2UucmVuZGVyYWJsZTsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VDb25zdW1lcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogVGhlIENsYXNzIFJlbmRlcmFibGVJbWFnZVByb2R1Y2VyIHByb3ZpZGVzIHRoZSBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIGltYWdlCisgKiByZW5kZXJpbmcuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgUmVuZGVyYWJsZUltYWdlUHJvZHVjZXIgaW1wbGVtZW50cyBJbWFnZVByb2R1Y2VyLCBSdW5uYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmJsLgorICAgICAqLworICAgIFJlbmRlcmFibGVJbWFnZSByYmw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmMuCisgICAgICovCisgICAgUmVuZGVyQ29udGV4dCByYzsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdW1lcnMuCisgICAgICovCisgICAgVmVjdG9yPEltYWdlQ29uc3VtZXI+IGNvbnN1bWVycyA9IG5ldyBWZWN0b3I8SW1hZ2VDb25zdW1lcj4oKTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyByZW5kZXJhYmxlIGltYWdlIHByb2R1Y2VyLgorICAgICAqIAorICAgICAqIEBwYXJhbSByZGJsSW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSByZGJsIGltYWdlLgorICAgICAqIEBwYXJhbSByYworICAgICAqICAgICAgICAgICAgdGhlIHJjLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJhYmxlSW1hZ2VQcm9kdWNlcihSZW5kZXJhYmxlSW1hZ2UgcmRibEltYWdlLCBSZW5kZXJDb250ZXh0IHJjKSB7CisgICAgICAgIHRoaXMucmJsID0gcmRibEltYWdlOworICAgICAgICB0aGlzLnJjID0gcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcmVuZGVyIGNvbnRleHQuCisgICAgICogCisgICAgICogQHBhcmFtIHJjCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHJlbmRlciBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRSZW5kZXJDb250ZXh0KFJlbmRlckNvbnRleHQgcmMpIHsKKyAgICAgICAgdGhpcy5yYyA9IHJjOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc0NvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgcmV0dXJuIGNvbnN1bWVycy5jb250YWlucyhpYyk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN0YXJ0UHJvZHVjdGlvbihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGFkZENvbnN1bWVyKGljKTsKKyAgICAgICAgVGhyZWFkIHQgPSBuZXcgVGhyZWFkKHRoaXMsICJSZW5kZXJhYmxlSW1hZ2VQcm9kdWNlciB0aHJlYWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB0LnN0YXJ0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVxdWVzdFRvcERvd25MZWZ0UmlnaHRSZXNlbmQoSW1hZ2VDb25zdW1lciBpYykgeworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVDb25zdW1lcihJbWFnZUNvbnN1bWVyIGljKSB7CisgICAgICAgIGlmIChpYyAhPSBudWxsKSB7CisgICAgICAgICAgICBjb25zdW1lcnMucmVtb3ZlRWxlbWVudChpYyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBpZiAoaWMgIT0gbnVsbCAmJiAhY29uc3VtZXJzLmNvbnRhaW5zKGljKSkgeworICAgICAgICAgICAgY29uc3VtZXJzLmFkZEVsZW1lbnQoaWMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgcmVuZGVyZWQgaW1hZ2UgaW4gYSBuZXcgdGhyZWFkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgaWYgKHJibCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBSZW5kZXJlZEltYWdlIHJkOworICAgICAgICBpZiAocmMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmQgPSByYmwuY3JlYXRlUmVuZGVyaW5nKHJjKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJkID0gcmJsLmNyZWF0ZURlZmF1bHRSZW5kZXJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIENvbG9yTW9kZWwgY20gPSByZC5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIGlmIChjbSA9PSBudWxsKSB7CisgICAgICAgICAgICBjbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICB9CisKKyAgICAgICAgUmFzdGVyIHIgPSByZC5nZXREYXRhKCk7CisgICAgICAgIGludCB3ID0gci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgaCA9IHIuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgZm9yIChJbWFnZUNvbnN1bWVyIGMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGMuc2V0RGltZW5zaW9ucyh3LCBoKTsKKyAgICAgICAgICAgIGMuc2V0SGludHMoSW1hZ2VDb25zdW1lci5UT1BET1dOTEVGVFJJR0hUIHwgSW1hZ2VDb25zdW1lci5DT01QTEVURVNDQU5MSU5FUworICAgICAgICAgICAgICAgICAgICB8IEltYWdlQ29uc3VtZXIuU0lOR0xFRlJBTUUgfCBJbWFnZUNvbnN1bWVyLlNJTkdMRVBBU1MpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHNjYW5MaW5lW10gPSBuZXcgaW50W3ddOworICAgICAgICBpbnQgcGl4ZWxbXSA9IG51bGw7CisKKyAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoOyB5KyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgdzsgeCsrKSB7CisgICAgICAgICAgICAgICAgcGl4ZWwgPSByLmdldFBpeGVsKHgsIHksIHBpeGVsKTsKKyAgICAgICAgICAgICAgICBzY2FuTGluZVt4XSA9IGNtLmdldERhdGFFbGVtZW50KHBpeGVsLCAwKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChJbWFnZUNvbnN1bWVyIGMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgICAgICBjLnNldFBpeGVscygwLCB5LCB3LCAxLCBjbSwgc2NhbkxpbmUsIDAsIHcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChJbWFnZUNvbnN1bWVyIGMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGMuaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLlNUQVRJQ0lNQUdFRE9ORSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL1JlbmRlcmVkSW1hZ2VGYWN0b3J5LmphdmEgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJlZEltYWdlRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4MWE0MGEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9SZW5kZXJlZEltYWdlRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGphdmEuYXd0LmltYWdlLnJlbmRlcmFibGU7CisKK2ltcG9ydCBqYXZhLmF3dC5SZW5kZXJpbmdIaW50czsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworCisvKioKKyAqIEEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgUmVuZGVyZWRJbWFnZSBvYmplY3RzIGJhc2VkIG9uIHBhcmFtZXRlcnMgYW5kCisgKiByZW5kZXJpbmcgaGludHMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFJlbmRlcmVkSW1hZ2VGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHJlbmRlcmVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBhMAorICAgICAqICAgICAgICAgICAgdGhlIFBhcmFtZXRlckJsb2NrLgorICAgICAqIEBwYXJhbSBhMQorICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmluZ0hpbnRzLgorICAgICAqIEByZXR1cm4gdGhlIHJlbmRlcmVkIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJlZEltYWdlIGNyZWF0ZShQYXJhbWV0ZXJCbG9jayBhMCwgUmVuZGVyaW5nSGludHMgYTEpOworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9wYWNrYWdlLmh0bWwgYi9hd3QvamF2YS9hd3QvaW1hZ2UvcmVuZGVyYWJsZS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDNhYWFiYwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9pbWFnZS9yZW5kZXJhYmxlL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBjb250YWlucyBjbGFzc2VzIHRvIGNyZWF0ZSBpbWFnZXMgd2hpY2ggYXJlIHJlbmRlcmluZy1pbmRlcGVuZGVudC4KKyAgICA8L3A+CisgICAgQHNpbmNlIEFuZHJvaWQgMS4wCisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wYWNrYWdlLmh0bWwgYi9hd3QvamF2YS9hd3QvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhNmY5ZjAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsOCBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgZm9yIGNyZWF0aW5nIChncmFwaGljYWwpIHVzZXIgaW50ZXJmYWNlcyAoR1VJKSwgcGFpbnRpbmcgMkQgZ3JhcGhpY3MgYW5kIGNyZWF0aW5nLCBtYW5pcHVsYXRpbmcgYW5kIGRyYXdpbmcgaW1hZ2VzLiAKKyAgICA8L3A+CisgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9CdXR0b25QZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9CdXR0b25QZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2M0NWI0OQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL0J1dHRvblBlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgQnV0dG9uUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0NhbnZhc1BlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL0NhbnZhc1BlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjc2MzY2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvQ2FudmFzUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBDYW52YXNQZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvQ2hlY2tib3hNZW51SXRlbVBlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL0NoZWNrYm94TWVudUl0ZW1QZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk2ZjQyMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL0NoZWNrYm94TWVudUl0ZW1QZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIENoZWNrYm94TWVudUl0ZW1QZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvQ2hlY2tib3hQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9DaGVja2JveFBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWY4ZGQxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvQ2hlY2tib3hQZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIENoZWNrYm94UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0Nob2ljZVBlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL0Nob2ljZVBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41N2I3NjI5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvQ2hvaWNlUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBDaG9pY2VQZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvQ29tcG9uZW50UGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvQ29tcG9uZW50UGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjMjY3OTEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9Db21wb25lbnRQZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIENvbXBvbmVudFBlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9EaWFsb2dQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9EaWFsb2dQZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFlMzA0OQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL0RpYWxvZ1BlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgRGlhbG9nUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0ZpbGVEaWFsb2dQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9GaWxlRGlhbG9nUGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkMTVlNDgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9GaWxlRGlhbG9nUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBGaWxlRGlhbG9nUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0ZvbnRQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9Gb250UGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkOTgxNWYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9Gb250UGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBGb250UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0ZyYW1lUGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvRnJhbWVQZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWNmYzQwYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL0ZyYW1lUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBGcmFtZVBlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9MYWJlbFBlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL0xhYmVsUGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1MmNhOWQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9MYWJlbFBlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgTGFiZWxQZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvTGlnaHR3ZWlnaHRQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9MaWdodHdlaWdodFBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGVlOTA1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvTGlnaHR3ZWlnaHRQZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIExpZ2h0d2VpZ2h0UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL0xpc3RQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9MaXN0UGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhMjc4ODUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9MaXN0UGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBMaXN0UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL01lbnVCYXJQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9NZW51QmFyUGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhZDJjMTYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9NZW51QmFyUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBNZW51QmFyUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL01lbnVDb21wb25lbnRQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9NZW51Q29tcG9uZW50UGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhYzNiMzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9NZW51Q29tcG9uZW50UGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBNZW51Q29tcG9uZW50UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL01lbnVJdGVtUGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvTWVudUl0ZW1QZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjEzMzg5NwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL01lbnVJdGVtUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBNZW51SXRlbVBlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9NZW51UGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvTWVudVBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjQzY2U3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvTWVudVBlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgTWVudVBlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9Nb3VzZUluZm9QZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9Nb3VzZUluZm9QZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTE3M2E2MgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL01vdXNlSW5mb1BlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgTW91c2VJbmZvUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL1BhbmVsUGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvUGFuZWxQZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWZhYTFmZQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL1BhbmVsUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBQYW5lbFBlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9hd3QvcGVlci9Qb3B1cE1lbnVQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9Qb3B1cE1lbnVQZWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2YxZWY2MQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZhL2F3dC9wZWVyL1BvcHVwTWVudVBlZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LnBlZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgUG9wdXBNZW51UGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL1Njcm9sbFBhbmVQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9TY3JvbGxQYW5lUGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmM2RlODMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9TY3JvbGxQYW5lUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBTY3JvbGxQYW5lUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL1Njcm9sbGJhclBlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL1Njcm9sbGJhclBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWM4OTYxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvU2Nyb2xsYmFyUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBTY3JvbGxiYXJQZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvVGV4dEFyZWFQZWVyLmphdmEgYi9hd3QvamF2YS9hd3QvcGVlci9UZXh0QXJlYVBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzY3MDdmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvVGV4dEFyZWFQZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIFRleHRBcmVhUGVlciB7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2F3dC9wZWVyL1RleHRGaWVsZFBlZXIuamF2YSBiL2F3dC9qYXZhL2F3dC9wZWVyL1RleHRGaWVsZFBlZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjgyMzJhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYXd0L3BlZXIvVGV4dEZpZWxkUGVlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QucGVlcjsKKworcHVibGljIGludGVyZmFjZSBUZXh0RmllbGRQZWVyIHsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYXd0L3BlZXIvV2luZG93UGVlci5qYXZhIGIvYXd0L2phdmEvYXd0L3BlZXIvV2luZG93UGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4NDY0NmYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9hd3QvcGVlci9XaW5kb3dQZWVyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBqYXZhLmF3dC5wZWVyOworCitwdWJsaWMgaW50ZXJmYWNlIFdpbmRvd1BlZXIgeworCit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9iZWFucy9GZWF0dXJlRGVzY3JpcHRvci5qYXZhIGIvYXd0L2phdmEvYmVhbnMvRmVhdHVyZURlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOTQ1YzY1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYmVhbnMvRmVhdHVyZURlc2NyaXB0b3IuamF2YQpAQCAtMCwwICsxLDIzNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuYmVhbnM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQ29tbW9uIGJhc2UgY2xhc3MgZm9yIERlc2NyaXB0b3JzLgorICovCitwdWJsaWMgY2xhc3MgRmVhdHVyZURlc2NyaXB0b3IgeworCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBPYmplY3Q+IHZhbHVlczsKKworICAgIGJvb2xlYW4gcHJlZmVycmVkLCBoaWRkZW4sIGV4cGVydDsKKworICAgIFN0cmluZyBzaG9ydERlc2NyaXB0aW9uOworCisgICAgU3RyaW5nIG5hbWU7CisKKyAgICBTdHJpbmcgZGlzcGxheU5hbWU7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGluc3RhbmNlLgorICAgICAqIDwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmVhdHVyZURlc2NyaXB0b3IoKSB7CisgICAgICAgIHRoaXMudmFsdWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogU2V0cyB0aGUgdmFsdWUgZm9yIHRoZSBuYW1lZCBhdHRyaWJ1dGUuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVOYW1lCisgICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHNldCBhIHZhbHVlIHdpdGguCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBUaGUgdmFsdWUgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKGF0dHJpYnV0ZU5hbWUgPT0gbnVsbCB8fCB2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB2YWx1ZXMucHV0KGF0dHJpYnV0ZU5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIG5hbWVkIGF0dHJpYnV0ZS4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUKKyAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gZ2V0IGEgdmFsdWUgZm9yLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUpIHsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChhdHRyaWJ1dGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlcy5nZXQoYXR0cmlidXRlTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBFbnVtZXJhdGVzIHRoZSBhdHRyaWJ1dGUgbmFtZXMuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2Yge0BsaW5rIEVudW1lcmF0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBhdHRyaWJ1dGVOYW1lcygpIHsKKyAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGxpc3QsIHNvIHRoYXQgdGhlIHJlZmVyZW5jZXMgYXJlIGNvcGllZAorICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24obmV3IExpbmtlZExpc3Q8U3RyaW5nPih2YWx1ZXMua2V5U2V0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBzaG9ydCBkZXNjcmlwdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIHRleHQKKyAgICAgKiAgICAgICAgICAgIFRoZSBkZXNjcmlwdGlvbiB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2hvcnREZXNjcmlwdGlvbihTdHJpbmcgdGV4dCkgeworICAgICAgICB0aGlzLnNob3J0RGVzY3JpcHRpb24gPSB0ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdGhlIG5hbWUuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBUaGUgbmFtZSB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdGhlIGRpc3BsYXkgbmFtZS4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIGRpc3BsYXlOYW1lCisgICAgICogICAgICAgICAgICBUaGUgZGlzcGxheSBuYW1lIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaXNwbGF5TmFtZShTdHJpbmcgZGlzcGxheU5hbWUpIHsKKyAgICAgICAgdGhpcy5kaXNwbGF5TmFtZSA9IGRpc3BsYXlOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIEdldHMgdGhlIHNob3J0IGRlc2NyaXB0aW9uIG9yIHtAbGluayAjZ2V0RGlzcGxheU5hbWUoKX0gaWYgbm90IHNldC4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTaG9ydERlc2NyaXB0aW9uKCkgeworICAgICAgICByZXR1cm4gc2hvcnREZXNjcmlwdGlvbiA9PSBudWxsID8gZ2V0RGlzcGxheU5hbWUoKSA6IHNob3J0RGVzY3JpcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogR2V0cyB0aGUgbmFtZS4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiBUaGUgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIEdldHMgdGhlIGRpc3BsYXkgbmFtZSBvciB7QGxpbmsgI2dldE5hbWUoKX0gaWYgbm90IHNldC4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiBUaGUgZGlzcGxheSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CisgICAgICAgIHJldHVybiBkaXNwbGF5TmFtZSA9PSBudWxsID8gZ2V0TmFtZSgpIDogZGlzcGxheU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogU2V0cyB0aGUgcHJlZmVycmVkIGluZGljYXRvci4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIHByZWZlcnJlZAorICAgICAqICAgICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgcHJlZmVycmVkLCA8Y29kZT5mYWxzZTwvY29kZT4KKyAgICAgKiAgICAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcmVmZXJyZWQoYm9vbGVhbiBwcmVmZXJyZWQpIHsKKyAgICAgICAgdGhpcy5wcmVmZXJyZWQgPSBwcmVmZXJyZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogU2V0cyB0aGUgaGlkZGVuIGluZGljYXRvci4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIGhpZGRlbgorICAgICAqICAgICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgaGlkZGVuLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhpZGRlbihib29sZWFuIGhpZGRlbikgeworICAgICAgICB0aGlzLmhpZGRlbiA9IGhpZGRlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBleHBlcnQgaW5kaWNhdG9yLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXhwZXJ0CisgICAgICogICAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPiBpZiBleHBlcnQsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXhwZXJ0KGJvb2xlYW4gZXhwZXJ0KSB7CisgICAgICAgIHRoaXMuZXhwZXJ0ID0gZXhwZXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIEluZGljYXRlcyBpZiB0aGlzIGZlYXR1cmUgaXMgcHJlZmVycmVkLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHByZWZlcnJlZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ByZWZlcnJlZCgpIHsKKyAgICAgICAgcmV0dXJuIHByZWZlcnJlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhpcyBmZWF0dXJlIGlzIGhpZGRlbi4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBoaWRkZW4sIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNIaWRkZW4oKSB7CisgICAgICAgIHJldHVybiBoaWRkZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogSW5kaWNhdGVzIGlmIHRoaXMgZmVhdHVyZSBpcyBhbiBleHBlcnQgZmVhdHVyZS4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBoaWRkZW4sIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHBlcnQoKSB7CisgICAgICAgIHJldHVybiBleHBlcnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYmVhbnMvSW5kZXhlZFByb3BlcnR5RGVzY3JpcHRvci5qYXZhIGIvYXd0L2phdmEvYmVhbnMvSW5kZXhlZFByb3BlcnR5RGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1NjY3ZDkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9iZWFucy9JbmRleGVkUHJvcGVydHlEZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSwyMjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5iZWFuczsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYmVhbnMuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitwdWJsaWMgY2xhc3MgSW5kZXhlZFByb3BlcnR5RGVzY3JpcHRvciBleHRlbmRzIFByb3BlcnR5RGVzY3JpcHRvciB7CisgICAgcHJpdmF0ZSBNZXRob2QgaW5kZXhlZEdldHRlcjsKKworICAgIHByaXZhdGUgTWV0aG9kIGluZGV4ZWRTZXR0ZXI7CisKKyAgICBwdWJsaWMgSW5kZXhlZFByb3BlcnR5RGVzY3JpcHRvcihTdHJpbmcgcHJvcGVydHlOYW1lLCBDbGFzczw/PiBiZWFuQ2xhc3MsCisgICAgICAgICAgICBTdHJpbmcgZ2V0dGVyTmFtZSwgU3RyaW5nIHNldHRlck5hbWUsIFN0cmluZyBpbmRleGVkR2V0dGVyTmFtZSwKKyAgICAgICAgICAgIFN0cmluZyBpbmRleGVkU2V0dGVyTmFtZSkgdGhyb3dzIEludHJvc3BlY3Rpb25FeGNlcHRpb24geworICAgICAgICBzdXBlcihwcm9wZXJ0eU5hbWUsIGJlYW5DbGFzcywgZ2V0dGVyTmFtZSwgc2V0dGVyTmFtZSk7CisKKyAgICAgICAgLy8gUkkgYmVoYXZlcyBsaWtlIHRoaXMKKyAgICAgICAgaWYgKGluZGV4ZWRHZXR0ZXJOYW1lID09IG51bGwgJiYgaW5kZXhlZFNldHRlck5hbWUgPT0gbnVsbCAmJgorICAgICAgICAgICAgICAgIChnZXR0ZXJOYW1lICE9IG51bGwgfHwgc2V0dGVyTmFtZSAhPSBudWxsKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy41MCIpKTsKKyAgICAgICAgfQorICAgICAgICBzZXRJbmRleGVkUmVhZE1ldGhvZChiZWFuQ2xhc3MsIGluZGV4ZWRHZXR0ZXJOYW1lKTsKKyAgICAgICAgc2V0SW5kZXhlZFdyaXRlTWV0aG9kKGJlYW5DbGFzcywgaW5kZXhlZFNldHRlck5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBJbmRleGVkUHJvcGVydHlEZXNjcmlwdG9yKFN0cmluZyBwcm9wZXJ0eU5hbWUsIE1ldGhvZCBnZXR0ZXIsIE1ldGhvZCBzZXR0ZXIsCisgICAgICAgICAgICBNZXRob2QgaW5kZXhlZEdldHRlciwgTWV0aG9kIGluZGV4ZWRTZXR0ZXIpIHRocm93cyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocHJvcGVydHlOYW1lLCBnZXR0ZXIsIHNldHRlcik7CisgICAgICAgIAorICAgICAgICAvLyB3ZSBuZWVkIHRoaXMgaW4gb3JkZXIgdG8gYmUgY29tcGF0aWJsZSB3aXRoIFJJCisgICAgICAgIGlmIChpbmRleGVkR2V0dGVyID09IG51bGwgJiYgaW5kZXhlZFNldHRlciA9PSBudWxsICYmCisgICAgICAgICAgICAgICAgKGdldHRlciAhPSBudWxsIHx8IHNldHRlciAhPSBudWxsKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy41MCIpKTsKKyAgICAgICAgfQorICAgICAgICBzZXRJbmRleGVkUmVhZE1ldGhvZChpbmRleGVkR2V0dGVyKTsKKyAgICAgICAgc2V0SW5kZXhlZFdyaXRlTWV0aG9kKGluZGV4ZWRTZXR0ZXIpOworICAgIH0KKworICAgIHB1YmxpYyBJbmRleGVkUHJvcGVydHlEZXNjcmlwdG9yKFN0cmluZyBwcm9wZXJ0eU5hbWUsIENsYXNzPD8+IGJlYW5DbGFzcykKKyAgICAgICAgICAgIHRocm93cyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocHJvcGVydHlOYW1lLCBiZWFuQ2xhc3MsIG51bGwsIG51bGwpOworICAgICAgICBTdHJpbmcgZ2V0dGVyTmFtZTsKKyAgICAgICAgU3RyaW5nIHNldHRlck5hbWU7CisgICAgICAgIFN0cmluZyBpbmRleGVkR2V0dGVyTmFtZTsKKyAgICAgICAgU3RyaW5nIGluZGV4ZWRTZXR0ZXJOYW1lOworCisgICAgICAgIC8vIGFycmF5IGdldHRlcgorICAgICAgICBnZXR0ZXJOYW1lID0gY3JlYXRlRGVmYXVsdE1ldGhvZE5hbWUocHJvcGVydHlOYW1lLCAiZ2V0Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaWYgKGhhc01ldGhvZChiZWFuQ2xhc3MsIGdldHRlck5hbWUpKSB7CisgICAgICAgICAgICBzZXRSZWFkTWV0aG9kKGJlYW5DbGFzcywgZ2V0dGVyTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXJyYXkgc2V0dGVyCisgICAgICAgIHNldHRlck5hbWUgPSBjcmVhdGVEZWZhdWx0TWV0aG9kTmFtZShwcm9wZXJ0eU5hbWUsICJzZXQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBpZiAoaGFzTWV0aG9kKGJlYW5DbGFzcywgc2V0dGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHNldFdyaXRlTWV0aG9kKGJlYW5DbGFzcywgc2V0dGVyTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gaW5kZXhlZCBnZXR0ZXIKKyAgICAgICAgaW5kZXhlZEdldHRlck5hbWUgPSBjcmVhdGVEZWZhdWx0TWV0aG9kTmFtZShwcm9wZXJ0eU5hbWUsICJnZXQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBpZiAoaGFzTWV0aG9kKGJlYW5DbGFzcywgaW5kZXhlZEdldHRlck5hbWUpKSB7CisgICAgICAgICAgICBzZXRJbmRleGVkUmVhZE1ldGhvZChiZWFuQ2xhc3MsIGluZGV4ZWRHZXR0ZXJOYW1lKTsKKyAgICAgICAgfQorICAgICAgICAvLyBpbmRleGVkIHNldHRlcgorICAgICAgICBpbmRleGVkU2V0dGVyTmFtZSA9IGNyZWF0ZURlZmF1bHRNZXRob2ROYW1lKHByb3BlcnR5TmFtZSwgInNldCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGlmIChoYXNNZXRob2QoYmVhbkNsYXNzLCBpbmRleGVkU2V0dGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHNldEluZGV4ZWRXcml0ZU1ldGhvZChiZWFuQ2xhc3MsIGluZGV4ZWRTZXR0ZXJOYW1lKTsKKyAgICAgICAgfQorICAgICAgICAvLyBSSSBzZWVtcyB0byBiZWhhdmUgYSBiaXQgZGlmZmVyZW50bHkKKyAgICAgICAgaWYgKGluZGV4ZWRHZXR0ZXIgPT0gbnVsbCAmJiBpbmRleGVkU2V0dGVyID09IG51bGwgJiYKKyAgICAgICAgICAgICAgICBnZXRSZWFkTWV0aG9kKCkgPT0gbnVsbCAmJiBnZXRXcml0ZU1ldGhvZCgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjAxIiwgcHJvcGVydHlOYW1lKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5kZXhlZEdldHRlciA9PSBudWxsICYmIGluZGV4ZWRTZXR0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gbm90IGFuIGluZGV4ZWQgcHJvcGVydHkgaW5kZWVkCisgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjUwIikpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW5kZXhlZFJlYWRNZXRob2QoTWV0aG9kIGluZGV4ZWRHZXR0ZXIpIHRocm93cyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluZGV4ZWRHZXR0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgaW50IG1vZGlmaWVycyA9IGluZGV4ZWRHZXR0ZXIuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzOworICAgICAgICAgICAgQ2xhc3M8Pz4gcmV0dXJuVHlwZTsKKyAgICAgICAgICAgIENsYXNzPD8+IGluZGV4ZWRQcm9wZXJ0eVR5cGU7CisKKyAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNQdWJsaWMobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMjEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBhcmFtZXRlclR5cGVzID0gaW5kZXhlZEdldHRlci5nZXRQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICAgICAgaWYgKHBhcmFtZXRlclR5cGVzLmxlbmd0aCAhPSAxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yMiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFwYXJhbWV0ZXJUeXBlc1swXS5lcXVhbHMoaW50LmNsYXNzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVyblR5cGUgPSBpbmRleGVkR2V0dGVyLmdldFJldHVyblR5cGUoKTsKKyAgICAgICAgICAgIGluZGV4ZWRQcm9wZXJ0eVR5cGUgPSBnZXRJbmRleGVkUHJvcGVydHlUeXBlKCk7CisgICAgICAgICAgICBpZiAoKGluZGV4ZWRQcm9wZXJ0eVR5cGUgIT0gbnVsbCkgJiYgIXJldHVyblR5cGUuZXF1YWxzKGluZGV4ZWRQcm9wZXJ0eVR5cGUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuaW5kZXhlZEdldHRlciA9IGluZGV4ZWRHZXR0ZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW5kZXhlZFdyaXRlTWV0aG9kKE1ldGhvZCBpbmRleGVkU2V0dGVyKSB0aHJvd3MgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbmRleGVkU2V0dGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSBpbmRleGVkU2V0dGVyLmdldE1vZGlmaWVycygpOworICAgICAgICAgICAgQ2xhc3M8Pz5bXSBwYXJhbWV0ZXJUeXBlczsKKyAgICAgICAgICAgIENsYXNzPD8+IGZpcnN0UGFyYW1ldGVyVHlwZTsKKyAgICAgICAgICAgIENsYXNzPD8+IHNlY29uZFBhcmFtZXRlclR5cGU7CisgICAgICAgICAgICBDbGFzczw/PiBwcm9wVHlwZTsKKworICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhtb2RpZmllcnMpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yNSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcGFyYW1ldGVyVHlwZXMgPSBpbmRleGVkU2V0dGVyLmdldFBhcmFtZXRlclR5cGVzKCk7CisgICAgICAgICAgICBpZiAocGFyYW1ldGVyVHlwZXMubGVuZ3RoICE9IDIpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjI2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXJzdFBhcmFtZXRlclR5cGUgPSBwYXJhbWV0ZXJUeXBlc1swXTsKKyAgICAgICAgICAgIGlmICghZmlyc3RQYXJhbWV0ZXJUeXBlLmVxdWFscyhpbnQuY2xhc3MpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yNyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgc2Vjb25kUGFyYW1ldGVyVHlwZSA9IHBhcmFtZXRlclR5cGVzWzFdOworICAgICAgICAgICAgcHJvcFR5cGUgPSBnZXRJbmRleGVkUHJvcGVydHlUeXBlKCk7CisgICAgICAgICAgICBpZiAocHJvcFR5cGUgIT0gbnVsbCAmJiAhc2Vjb25kUGFyYW1ldGVyVHlwZS5lcXVhbHMocHJvcFR5cGUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yOCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuaW5kZXhlZFNldHRlciA9IGluZGV4ZWRTZXR0ZXI7CisgICAgfQorCisgICAgcHVibGljIE1ldGhvZCBnZXRJbmRleGVkV3JpdGVNZXRob2QoKSB7CisgICAgICAgIHJldHVybiBpbmRleGVkU2V0dGVyOworICAgIH0KKworICAgIHB1YmxpYyBNZXRob2QgZ2V0SW5kZXhlZFJlYWRNZXRob2QoKSB7CisgICAgICAgIHJldHVybiBpbmRleGVkR2V0dGVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc3VwZXIuZXF1YWxzKG9iaik7CisgICAgICAgIAorICAgICAgICBpZiAocmVzdWx0KSB7CisgICAgICAgICAgICBJbmRleGVkUHJvcGVydHlEZXNjcmlwdG9yIHBkID0gKEluZGV4ZWRQcm9wZXJ0eURlc2NyaXB0b3IpIG9iajsKKyAgICAKKyAgICAgICAgICAgIGlmIChpbmRleGVkR2V0dGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBpbmRleGVkR2V0dGVyLmVxdWFscyhwZC5nZXRJbmRleGVkUmVhZE1ldGhvZCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0ICYmIGluZGV4ZWRHZXR0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBkLmdldEluZGV4ZWRSZWFkTWV0aG9kKCkgPT0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5kZXhlZFNldHRlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGluZGV4ZWRTZXR0ZXIuZXF1YWxzKHBkLmdldEluZGV4ZWRXcml0ZU1ldGhvZCgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ZWRTZXR0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwZC5nZXRJbmRleGVkV3JpdGVNZXRob2QoKSA9PSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIENsYXNzPD8+IGdldEluZGV4ZWRQcm9wZXJ0eVR5cGUoKSB7CisgICAgICAgIENsYXNzPD8+IHJlc3VsdCA9IG51bGw7CisKKyAgICAgICAgaWYgKGluZGV4ZWRHZXR0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gaW5kZXhlZEdldHRlci5nZXRSZXR1cm5UeXBlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoaW5kZXhlZFNldHRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzID0gaW5kZXhlZFNldHRlci5nZXRQYXJhbWV0ZXJUeXBlcygpOworCisgICAgICAgICAgICByZXN1bHQgPSBwYXJhbWV0ZXJUeXBlc1sxXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRJbmRleGVkUmVhZE1ldGhvZChDbGFzczw/PiBiZWFuQ2xhc3MsIFN0cmluZyBpbmRleGVkR2V0dGVyTmFtZSkgeworICAgICAgICBNZXRob2RbXSBnZXR0ZXJzID0gZmluZE1ldGhvZHMoYmVhbkNsYXNzLCBpbmRleGVkR2V0dGVyTmFtZSk7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisKKyAgICAgICAgZm9yIChNZXRob2QgZWxlbWVudCA6IGdldHRlcnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2V0SW5kZXhlZFJlYWRNZXRob2QoZWxlbWVudCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludHJvc3BlY3Rpb25FeGNlcHRpb24gaWUpIHt9CisKKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRJbmRleGVkV3JpdGVNZXRob2QoQ2xhc3M8Pz4gYmVhbkNsYXNzLCBTdHJpbmcgaW5kZXhlZFNldHRlck5hbWUpIHsKKyAgICAgICAgTWV0aG9kW10gc2V0dGVycyA9IGZpbmRNZXRob2RzKGJlYW5DbGFzcywgaW5kZXhlZFNldHRlck5hbWUpOworICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworCisgICAgICAgIGZvciAoTWV0aG9kIGVsZW1lbnQgOiBzZXR0ZXJzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNldEluZGV4ZWRXcml0ZU1ldGhvZChlbGVtZW50KTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoSW50cm9zcGVjdGlvbkV4Y2VwdGlvbiBpZSkge30KKworICAgICAgICAgICAgaWYgKHJlc3VsdCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYmVhbnMvSW50cm9zcGVjdGlvbkV4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmEvYmVhbnMvSW50cm9zcGVjdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4OTVhZmUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9iZWFucy9JbnRyb3NwZWN0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmJlYW5zOworCitwdWJsaWMgY2xhc3MgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM3MjgxNTA1Mzk5Njk1NDI2MTlMOworCisgICAgcHVibGljIEludHJvc3BlY3Rpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlEZXNjcmlwdG9yLmphdmEgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eURlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Mzg5MTUyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlEZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSwzMDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5iZWFuczsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5iZWFucy5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKK3B1YmxpYyBjbGFzcyBQcm9wZXJ0eURlc2NyaXB0b3IgZXh0ZW5kcyBGZWF0dXJlRGVzY3JpcHRvciB7CisgICAgcHJpdmF0ZSBNZXRob2QgZ2V0dGVyOworCisgICAgcHJpdmF0ZSBNZXRob2Qgc2V0dGVyOworCisgICAgcHJpdmF0ZSBDbGFzczw/PiBwcm9wZXJ0eUVkaXRvckNsYXNzOworCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbnN0cmFpbmVkOworCisgICAgcHJpdmF0ZSBib29sZWFuIGJvdW5kOworCisgICAgcHVibGljIFByb3BlcnR5RGVzY3JpcHRvcihTdHJpbmcgcHJvcGVydHlOYW1lLCBDbGFzczw/PiBiZWFuQ2xhc3MsIFN0cmluZyBnZXR0ZXJOYW1lLAorICAgICAgICAgICAgU3RyaW5nIHNldHRlck5hbWUpIHRocm93cyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgaWYgKGJlYW5DbGFzcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjAzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3BlcnR5TmFtZSA9PSBudWxsIHx8IHByb3BlcnR5TmFtZS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjA0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zZXROYW1lKHByb3BlcnR5TmFtZSk7CisgICAgICAgIHRoaXMuc2V0RGlzcGxheU5hbWUocHJvcGVydHlOYW1lKTsKKyAgICAgICAgaWYgKHNldHRlck5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGhhc01ldGhvZChiZWFuQ2xhc3MsIHNldHRlck5hbWUpKSB7CisgICAgICAgICAgICAgICAgc2V0V3JpdGVNZXRob2QoYmVhbkNsYXNzLCBzZXR0ZXJOYW1lKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4yMCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChnZXR0ZXJOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoYXNNZXRob2QoYmVhbkNsYXNzLCBnZXR0ZXJOYW1lKSkgeworICAgICAgICAgICAgICAgIHNldFJlYWRNZXRob2QoYmVhbkNsYXNzLCBnZXR0ZXJOYW1lKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4xRiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFByb3BlcnR5RGVzY3JpcHRvcihTdHJpbmcgcHJvcGVydHlOYW1lLCBNZXRob2QgZ2V0dGVyLCBNZXRob2Qgc2V0dGVyKQorICAgICAgICAgICAgdGhyb3dzIEludHJvc3BlY3Rpb25FeGNlcHRpb24geworICAgICAgICBzdXBlcigpOworICAgICAgICBpZiAocHJvcGVydHlOYW1lID09IG51bGwgfHwgcHJvcGVydHlOYW1lLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNldE5hbWUocHJvcGVydHlOYW1lKTsKKyAgICAgICAgdGhpcy5zZXREaXNwbGF5TmFtZShwcm9wZXJ0eU5hbWUpOworICAgICAgICBzZXRXcml0ZU1ldGhvZChzZXR0ZXIpOworICAgICAgICBzZXRSZWFkTWV0aG9kKGdldHRlcik7CisgICAgfQorCisgICAgcHVibGljIFByb3BlcnR5RGVzY3JpcHRvcihTdHJpbmcgcHJvcGVydHlOYW1lLCBDbGFzczw/PiBiZWFuQ2xhc3MpCisgICAgICAgICAgICB0aHJvd3MgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBnZXR0ZXJOYW1lOworICAgICAgICBTdHJpbmcgc2V0dGVyTmFtZTsKKyAgICAgICAgaWYgKGJlYW5DbGFzcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjAzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3BlcnR5TmFtZSA9PSBudWxsIHx8IHByb3BlcnR5TmFtZS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjA0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zZXROYW1lKHByb3BlcnR5TmFtZSk7CisgICAgICAgIHRoaXMuc2V0RGlzcGxheU5hbWUocHJvcGVydHlOYW1lKTsKKyAgICAgICAgZ2V0dGVyTmFtZSA9IGNyZWF0ZURlZmF1bHRNZXRob2ROYW1lKHByb3BlcnR5TmFtZSwgImlzIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaWYgKGhhc01ldGhvZChiZWFuQ2xhc3MsIGdldHRlck5hbWUpKSB7CisgICAgICAgICAgICBzZXRSZWFkTWV0aG9kKGJlYW5DbGFzcywgZ2V0dGVyTmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnZXR0ZXJOYW1lID0gY3JlYXRlRGVmYXVsdE1ldGhvZE5hbWUocHJvcGVydHlOYW1lLCAiZ2V0Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIGlmIChoYXNNZXRob2QoYmVhbkNsYXNzLCBnZXR0ZXJOYW1lKSkgeworICAgICAgICAgICAgICAgIHNldFJlYWRNZXRob2QoYmVhbkNsYXNzLCBnZXR0ZXJOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXR0ZXJOYW1lID0gY3JlYXRlRGVmYXVsdE1ldGhvZE5hbWUocHJvcGVydHlOYW1lLCAic2V0Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaWYgKGhhc01ldGhvZChiZWFuQ2xhc3MsIHNldHRlck5hbWUpKSB7CisgICAgICAgICAgICBzZXRXcml0ZU1ldGhvZChiZWFuQ2xhc3MsIHNldHRlck5hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChnZXR0ZXIgPT0gbnVsbCAmJiBzZXR0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4wMSIsIHByb3BlcnR5TmFtZSkpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZU1ldGhvZChNZXRob2Qgc2V0dGVyKSB0aHJvd3MgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzZXR0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgaW50IG1vZGlmaWVycyA9IHNldHRlci5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNQdWJsaWMobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMDUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIENsYXNzPD8+W10gcGFyYW1ldGVyVHlwZXMgPSBzZXR0ZXIuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgICAgIGlmIChwYXJhbWV0ZXJUeXBlcy5sZW5ndGggIT0gMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMDYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIENsYXNzPD8+IHBhcmFtZXRlclR5cGUgPSBwYXJhbWV0ZXJUeXBlc1swXTsKKyAgICAgICAgICAgIENsYXNzPD8+IHByb3BlcnR5VHlwZSA9IGdldFByb3BlcnR5VHlwZSgpOworICAgICAgICAgICAgaWYgKHByb3BlcnR5VHlwZSAhPSBudWxsICYmICFwcm9wZXJ0eVR5cGUuZXF1YWxzKHBhcmFtZXRlclR5cGUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4wNyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuc2V0dGVyID0gc2V0dGVyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJlYWRNZXRob2QoTWV0aG9kIGdldHRlcikgdGhyb3dzIEludHJvc3BlY3Rpb25FeGNlcHRpb24geworICAgICAgICBpZiAoZ2V0dGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSBnZXR0ZXIuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzUHVibGljKG1vZGlmaWVycykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjBBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzID0gZ2V0dGVyLmdldFBhcmFtZXRlclR5cGVzKCk7CisgICAgICAgICAgICBpZiAocGFyYW1ldGVyVHlwZXMubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50cm9zcGVjdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjA4IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBDbGFzczw/PiByZXR1cm5UeXBlID0gZ2V0dGVyLmdldFJldHVyblR5cGUoKTsKKyAgICAgICAgICAgIGlmIChyZXR1cm5UeXBlLmVxdWFscyhWb2lkLlRZUEUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludHJvc3BlY3Rpb25FeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy4zMyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgQ2xhc3M8Pz4gcHJvcGVydHlUeXBlID0gZ2V0UHJvcGVydHlUeXBlKCk7CisgICAgICAgICAgICBpZiAoKHByb3BlcnR5VHlwZSAhPSBudWxsKSAmJiAhcmV0dXJuVHlwZS5lcXVhbHMocHJvcGVydHlUeXBlKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRyb3NwZWN0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMDkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLmdldHRlciA9IGdldHRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgTWV0aG9kIGdldFdyaXRlTWV0aG9kKCkgeworICAgICAgICByZXR1cm4gc2V0dGVyOworICAgIH0KKworICAgIHB1YmxpYyBNZXRob2QgZ2V0UmVhZE1ldGhvZCgpIHsKKyAgICAgICAgcmV0dXJuIGdldHRlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBib29sZWFuIHJlc3VsdCA9IChvYmplY3QgIT0gbnVsbCAmJiBvYmplY3QgaW5zdGFuY2VvZiBQcm9wZXJ0eURlc2NyaXB0b3IpOworICAgICAgICBpZiAocmVzdWx0KSB7CisgICAgICAgICAgICBQcm9wZXJ0eURlc2NyaXB0b3IgcGQgPSAoUHJvcGVydHlEZXNjcmlwdG9yKSBvYmplY3Q7CisgICAgICAgICAgICBib29sZWFuIGdldHRlcnNBcmVFcXVhbCA9ICh0aGlzLmdldHRlciA9PSBudWxsKSAmJiAocGQuZ2V0UmVhZE1ldGhvZCgpID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHx8ICh0aGlzLmdldHRlciAhPSBudWxsKSAmJiAodGhpcy5nZXR0ZXIuZXF1YWxzKHBkLmdldFJlYWRNZXRob2QoKSkpOworICAgICAgICAgICAgYm9vbGVhbiBzZXR0ZXJzQXJlRXF1YWwgPSAodGhpcy5zZXR0ZXIgPT0gbnVsbCkgJiYgKHBkLmdldFdyaXRlTWV0aG9kKCkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgfHwgKHRoaXMuc2V0dGVyICE9IG51bGwpICYmICh0aGlzLnNldHRlci5lcXVhbHMocGQuZ2V0V3JpdGVNZXRob2QoKSkpOworICAgICAgICAgICAgYm9vbGVhbiBwcm9wZXJ0eVR5cGVzQXJlRXF1YWwgPSB0aGlzLmdldFByb3BlcnR5VHlwZSgpID09IHBkLmdldFByb3BlcnR5VHlwZSgpOworICAgICAgICAgICAgYm9vbGVhbiBwcm9wZXJ0eUVkaXRvckNsYXNzZXNBcmVFcXVhbCA9IHRoaXMuZ2V0UHJvcGVydHlFZGl0b3JDbGFzcygpID09IHBkCisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm9wZXJ0eUVkaXRvckNsYXNzKCk7CisgICAgICAgICAgICBib29sZWFuIGJvdW5kUHJvcGVydHlBcmVFcXVhbCA9IHRoaXMuaXNCb3VuZCgpID09IHBkLmlzQm91bmQoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gY29uc3RyYWluZWRQcm9wZXJ0eUFyZUVxdWFsID0gdGhpcy5pc0NvbnN0cmFpbmVkKCkgPT0gcGQuaXNDb25zdHJhaW5lZCgpOworICAgICAgICAgICAgcmVzdWx0ID0gZ2V0dGVyc0FyZUVxdWFsICYmIHNldHRlcnNBcmVFcXVhbCAmJiBwcm9wZXJ0eVR5cGVzQXJlRXF1YWwKKyAgICAgICAgICAgICAgICAgICAgJiYgcHJvcGVydHlFZGl0b3JDbGFzc2VzQXJlRXF1YWwgJiYgYm91bmRQcm9wZXJ0eUFyZUVxdWFsCisgICAgICAgICAgICAgICAgICAgICYmIGNvbnN0cmFpbmVkUHJvcGVydHlBcmVFcXVhbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5RWRpdG9yQ2xhc3MoQ2xhc3M8Pz4gcHJvcGVydHlFZGl0b3JDbGFzcykgeworICAgICAgICB0aGlzLnByb3BlcnR5RWRpdG9yQ2xhc3MgPSBwcm9wZXJ0eUVkaXRvckNsYXNzOworICAgIH0KKworICAgIHB1YmxpYyBDbGFzczw/PiBnZXRQcm9wZXJ0eVR5cGUoKSB7CisgICAgICAgIENsYXNzPD8+IHJlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChnZXR0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gZ2V0dGVyLmdldFJldHVyblR5cGUoKTsKKyAgICAgICAgfSBlbHNlIGlmIChzZXR0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgQ2xhc3M8Pz5bXSBwYXJhbWV0ZXJUeXBlcyA9IHNldHRlci5nZXRQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICAgICAgcmVzdWx0ID0gcGFyYW1ldGVyVHlwZXNbMF07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2xhc3M8Pz4gZ2V0UHJvcGVydHlFZGl0b3JDbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIHByb3BlcnR5RWRpdG9yQ2xhc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29uc3RyYWluZWQoYm9vbGVhbiBjb25zdHJhaW5lZCkgeworICAgICAgICB0aGlzLmNvbnN0cmFpbmVkID0gY29uc3RyYWluZWQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Qm91bmQoYm9vbGVhbiBib3VuZCkgeworICAgICAgICB0aGlzLmJvdW5kID0gYm91bmQ7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNDb25zdHJhaW5lZCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbnN0cmFpbmVkOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgIHJldHVybiBib3VuZDsKKyAgICB9CisKKyAgICBib29sZWFuIGhhc01ldGhvZChDbGFzczw/PiBiZWFuQ2xhc3MsIFN0cmluZyBtZXRob2ROYW1lKSB7CisgICAgICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBmaW5kTWV0aG9kcyhiZWFuQ2xhc3MsIG1ldGhvZE5hbWUpOworICAgICAgICByZXR1cm4gKG1ldGhvZHMubGVuZ3RoID4gMCk7CisgICAgfQorCisgICAgU3RyaW5nIGNyZWF0ZURlZmF1bHRNZXRob2ROYW1lKFN0cmluZyBwcm9wZXJ0eU5hbWUsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChwcm9wZXJ0eU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIGJvcyA9IHByb3BlcnR5TmFtZS5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKTsKKyAgICAgICAgICAgIFN0cmluZyBlb3MgPSBwcm9wZXJ0eU5hbWUuc3Vic3RyaW5nKDEsIHByb3BlcnR5TmFtZS5sZW5ndGgoKSk7CisgICAgICAgICAgICByZXN1bHQgPSBwcmVmaXggKyBib3MgKyBlb3M7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBNZXRob2RbXSBmaW5kTWV0aG9kcyhDbGFzczw/PiBhQ2xhc3MsIFN0cmluZyBtZXRob2ROYW1lKSB7CisgICAgICAgIE1ldGhvZFtdIGFsbE1ldGhvZHMgPSBhQ2xhc3MuZ2V0TWV0aG9kcygpOworICAgICAgICBWZWN0b3I8TWV0aG9kPiBtYXRjaGVkTWV0aG9kcyA9IG5ldyBWZWN0b3I8TWV0aG9kPigpOworICAgICAgICBNZXRob2RbXSByZXN1bHQ7CisgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IGFsbE1ldGhvZHMpIHsKKyAgICAgICAgICAgIGlmIChtZXRob2QuZ2V0TmFtZSgpLmVxdWFscyhtZXRob2ROYW1lKSkgeworICAgICAgICAgICAgICAgIG1hdGNoZWRNZXRob2RzLmFkZChtZXRob2QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IG5ldyBNZXRob2RbbWF0Y2hlZE1ldGhvZHMuc2l6ZSgpXTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBtYXRjaGVkTWV0aG9kcy5zaXplKCk7ICsraikgeworICAgICAgICAgICAgcmVzdWx0W2pdID0gbWF0Y2hlZE1ldGhvZHMuZWxlbWVudEF0KGopOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgdm9pZCBzZXRSZWFkTWV0aG9kKENsYXNzPD8+IGJlYW5DbGFzcywgU3RyaW5nIGdldHRlck5hbWUpIHsKKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgTWV0aG9kW10gZ2V0dGVycyA9IGZpbmRNZXRob2RzKGJlYW5DbGFzcywgZ2V0dGVyTmFtZSk7CisgICAgICAgIGZvciAoTWV0aG9kIGVsZW1lbnQgOiBnZXR0ZXJzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNldFJlYWRNZXRob2QoZWxlbWVudCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludHJvc3BlY3Rpb25FeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgc2V0V3JpdGVNZXRob2QoQ2xhc3M8Pz4gYmVhbkNsYXNzLCBTdHJpbmcgc2V0dGVyTmFtZSkgdGhyb3dzIEludHJvc3BlY3Rpb25FeGNlcHRpb24geworICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworICAgICAgICBNZXRob2RbXSBzZXR0ZXJzID0gZmluZE1ldGhvZHMoYmVhbkNsYXNzLCBzZXR0ZXJOYW1lKTsKKyAgICAgICAgZm9yIChNZXRob2QgZWxlbWVudCA6IHNldHRlcnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2V0V3JpdGVNZXRob2QoZWxlbWVudCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludHJvc3BlY3Rpb25FeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBQcm9wZXJ0eUVkaXRvciBjcmVhdGVQcm9wZXJ0eUVkaXRvcihPYmplY3QgYmVhbikgeworICAgICAgICBQcm9wZXJ0eUVkaXRvciBlZGl0b3I7CisgICAgICAgIGlmIChwcm9wZXJ0eUVkaXRvckNsYXNzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmICghUHJvcGVydHlFZGl0b3IuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShwcm9wZXJ0eUVkaXRvckNsYXNzKSkgeworICAgICAgICAgICAgLy8gYmVhbnMuNDg9UHJvcGVydHkgZWRpdG9yIGlzIG5vdCBhc3NpZ25hYmxlIGZyb20gdGhlCisgICAgICAgICAgICAvLyBQcm9wZXJ0eUVkaXRvciBpbnRlcmZhY2UKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJiZWFucy40OCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/PiBjb25zdHI7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIHRyeSB0byBsb29rIGZvciB0aGUgY29uc3RydWN0b3Igd2l0aCBzaW5nbGUgT2JqZWN0IGFyZ3VtZW50CisgICAgICAgICAgICAgICAgY29uc3RyID0gcHJvcGVydHlFZGl0b3JDbGFzcy5nZXRDb25zdHJ1Y3RvcihPYmplY3QuY2xhc3MpOworICAgICAgICAgICAgICAgIGVkaXRvciA9IChQcm9wZXJ0eUVkaXRvcikgY29uc3RyLm5ld0luc3RhbmNlKGJlYW4pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB0cnkgbm8tYXJndW1lbnQgY29uc3RydWN0b3IKKyAgICAgICAgICAgICAgICBjb25zdHIgPSBwcm9wZXJ0eUVkaXRvckNsYXNzLmdldENvbnN0cnVjdG9yKCk7CisgICAgICAgICAgICAgICAgZWRpdG9yID0gKFByb3BlcnR5RWRpdG9yKSBjb25zdHIubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGJlYW5zLjQ3PVVuYWJsZSB0byBpbnN0YW50aWF0ZSBwcm9wZXJ0eSBlZGl0b3IKKyAgICAgICAgICAgIFJ1bnRpbWVFeGNlcHRpb24gcmUgPSBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImJlYW5zLjQ3IiksIGUpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB0aHJvdyByZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZWRpdG9yOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZhL2JlYW5zL1Byb3BlcnR5RWRpdG9yLmphdmEgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eUVkaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1YmVkZWEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eUVkaXRvci5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5iZWFuczsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKK3B1YmxpYyBpbnRlcmZhY2UgUHJvcGVydHlFZGl0b3IgeworCisgICAgcHVibGljIHZvaWQgcGFpbnRWYWx1ZShHcmFwaGljcyBnZngsIFJlY3RhbmdsZSBib3gpOworCisgICAgcHVibGljIHZvaWQgc2V0QXNUZXh0KFN0cmluZyB0ZXh0KSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOworCisgICAgcHVibGljIFN0cmluZ1tdIGdldFRhZ3MoKTsKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SmF2YUluaXRpYWxpemF0aW9uU3RyaW5nKCk7CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEFzVGV4dCgpOworCisgICAgcHVibGljIHZvaWQgc2V0VmFsdWUoT2JqZWN0IHZhbHVlKTsKKworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKTsKKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcik7CisKKyAgICBwdWJsaWMgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpOworCisgICAgcHVibGljIENvbXBvbmVudCBnZXRDdXN0b21FZGl0b3IoKTsKKworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzQ3VzdG9tRWRpdG9yKCk7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1BhaW50YWJsZSgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlFZGl0b3JNYW5hZ2VyLmphdmEgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eUVkaXRvck1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDU1ODI5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlFZGl0b3JNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5iZWFuczsKKworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK3B1YmxpYyBjbGFzcyBQcm9wZXJ0eUVkaXRvck1hbmFnZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gcGF0aCA9IHsgIm9yZy5hcGFjaGUuaGFybW9ueS5iZWFucy5lZGl0b3JzIiB9OyAvLyROT04tTkxTLTEkCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8Q2xhc3M8Pz4sIENsYXNzPD8+PiByZWdpc3RlcmVkRWRpdG9ycyA9IG5ldyBIYXNoTWFwPENsYXNzPD8+LCBDbGFzczw/Pj4oKTsKKworICAgIHB1YmxpYyBQcm9wZXJ0eUVkaXRvck1hbmFnZXIoKSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyRWRpdG9yKENsYXNzPD8+IHRhcmdldFR5cGUsIENsYXNzPD8+IGVkaXRvckNsYXNzKSB7CisgICAgICAgIGlmICh0YXJnZXRUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgc20uY2hlY2tQcm9wZXJ0aWVzQWNjZXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVkaXRvckNsYXNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRFZGl0b3JzLnB1dCh0YXJnZXRUeXBlLCBlZGl0b3JDbGFzcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZWdpc3RlcmVkRWRpdG9ycy5yZW1vdmUodGFyZ2V0VHlwZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBQcm9wZXJ0eUVkaXRvciBmaW5kRWRpdG9yKENsYXNzPD8+IHRhcmdldFR5cGUpIHsKKyAgICAgICAgaWYgKHRhcmdldFR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBDbGFzczw/PiBlZGl0b3JDbGFzcyA9IG51bGw7CisgICAgICAgIFByb3BlcnR5RWRpdG9yIGVkaXRvciA9IG51bGw7CisKKyAgICAgICAgZWRpdG9yQ2xhc3MgPSByZWdpc3RlcmVkRWRpdG9ycy5nZXQodGFyZ2V0VHlwZSk7CisKKyAgICAgICAgaWYgKGVkaXRvckNsYXNzID09IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyBlZGl0b3JDbGFzc05hbWUgPSB0YXJnZXRUeXBlLmdldE5hbWUoKSArICJFZGl0b3IiOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSB0YXJnZXRUeXBlLmdldENsYXNzTG9hZGVyKCk7CisKKyAgICAgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvYWRlciA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWRpdG9yQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGVkaXRvckNsYXNzTmFtZSwgdHJ1ZSwgbG9hZGVyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBzaG9ydEVkaXRvckNsYXNzTmFtZSA9IGVkaXRvckNsYXNzTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnN0cmluZyhlZGl0b3JDbGFzc05hbWUubGFzdEluZGV4T2YoIi4iKSArIDEpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgICAgICAgICBpZiAodGFyZ2V0VHlwZS5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHNob3J0RWRpdG9yQ2xhc3NOYW1lID0gc2hvcnRFZGl0b3JDbGFzc05hbWUuc3Vic3RyaW5nKDAsIDEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvVXBwZXJDYXNlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNob3J0RWRpdG9yQ2xhc3NOYW1lLnN1YnN0cmluZygxKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBlbGVtZW50IDogcGF0aCkgeworICAgICAgICAgICAgICAgICAgICBlZGl0b3JDbGFzc05hbWUgPSBlbGVtZW50ICsgIi4iICsgc2hvcnRFZGl0b3JDbGFzc05hbWU7IC8vJE5PTi1OTFMtMSQKKworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGVkaXRvckNsYXNzTmFtZSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChlZGl0b3JDbGFzcyAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVkaXRvciA9IChQcm9wZXJ0eUVkaXRvcikgZWRpdG9yQ2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZWRpdG9yOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgc2V0RWRpdG9yU2VhcmNoUGF0aChTdHJpbmdbXSBhcGF0aCkgeworICAgICAgICBTZWN1cml0eU1hbmFnZXIgc20gPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIGlmIChzbSAhPSBudWxsKSB7CisgICAgICAgICAgICBzbS5jaGVja1Byb3BlcnRpZXNBY2Nlc3MoKTsKKyAgICAgICAgfQorCisgICAgICAgIHBhdGggPSBhcGF0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXRFZGl0b3JTZWFyY2hQYXRoKCkgeworICAgICAgICByZXR1cm4gcGF0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eUVkaXRvclN1cHBvcnQuamF2YSBiL2F3dC9qYXZhL2JlYW5zL1Byb3BlcnR5RWRpdG9yU3VwcG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzOTI5YTEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eUVkaXRvclN1cHBvcnQuamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS5iZWFuczsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYmVhbnMuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitwdWJsaWMgY2xhc3MgUHJvcGVydHlFZGl0b3JTdXBwb3J0IGltcGxlbWVudHMgUHJvcGVydHlFZGl0b3IgeworCisgICAgT2JqZWN0IHNvdXJjZSA9IG51bGw7CisKKyAgICBMaXN0PFByb3BlcnR5Q2hhbmdlTGlzdGVuZXI+IGxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3Q8UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcj4oKTsKKworICAgIE9iamVjdCBvbGRWYWx1ZSA9IG51bGw7CisKKyAgICBPYmplY3QgbmV3VmFsdWUgPSBudWxsOworCisgICAgcHVibGljIFByb3BlcnR5RWRpdG9yU3VwcG9ydChPYmplY3Qgc291cmNlKSB7CisgICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMEMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJvcGVydHlFZGl0b3JTdXBwb3J0KCkgeworICAgICAgICBzb3VyY2UgPSB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHBhaW50VmFsdWUoR3JhcGhpY3MgZ2Z4LCBSZWN0YW5nbGUgYm94KSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0QXNUZXh0KFN0cmluZyB0ZXh0KSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5ld1ZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICBzZXRWYWx1ZSh0ZXh0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odGV4dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0VGFncygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRKYXZhSW5pdGlhbGl6YXRpb25TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiPz8/IjsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXNUZXh0KCkgeworICAgICAgICByZXR1cm4gbmV3VmFsdWUgPT0gbnVsbCA/ICJudWxsIiA6IG5ld1ZhbHVlLnRvU3RyaW5nKCk7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IHRoaXMubmV3VmFsdWU7CisgICAgICAgIHRoaXMubmV3VmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgZmlyZVByb3BlcnR5Q2hhbmdlKCk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ld1ZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZShPYmplY3Qgc291cmNlKSB7CisgICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYmVhbnMuMEMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIHNvdXJjZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigKKyAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVycyAhPSBudWxsKSB7CisgICAgICAgICAgICBsaXN0ZW5lcnMucmVtb3ZlKGxpc3RlbmVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKAorICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICBsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29tcG9uZW50IGdldEN1c3RvbUVkaXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDdXN0b21FZGl0b3IoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1BhaW50YWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZSgpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVycy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50ID0gbmV3IFByb3BlcnR5Q2hhbmdlRXZlbnQoc291cmNlLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSwgbmV3VmFsdWUpOworICAgICAgICAgICAgSXRlcmF0b3I8UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcj4gaXRlcmF0b3IgPSBsaXN0ZW5lcnMuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICAgICAgbGlzdGVuZXIucHJvcGVydHlDaGFuZ2UoZXZlbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlWZXRvRXhjZXB0aW9uLmphdmEgYi9hd3QvamF2YS9iZWFucy9Qcm9wZXJ0eVZldG9FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jN2YwOTJhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmEvYmVhbnMvUHJvcGVydHlWZXRvRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmJlYW5zOworCisvKioKKyAqIEluZGljYXRlcyB0aGF0IGEgcHJvcG9zZWQgcHJvcGVydHkgY2hhbmdlIGlzIHVuYWNjZXB0YWJsZS4KKyAqLworcHVibGljIGNsYXNzIFByb3BlcnR5VmV0b0V4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMjk1OTYwNTc2OTQxNjIxNjRMOworCisgICAgcHJpdmF0ZSBmaW5hbCBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2dDsKKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCBhIG1lc3NhZ2UgYW5kIHRoZSBjaGFuZ2UgZXZlbnQuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICBBIGRlc2NyaXB0aW9uIG9mIHRoZSB2ZXRvLgorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgVGhlIGV2ZW50IHRoYXQgd2FzIHZldG9lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvcGVydHlWZXRvRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50KSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgICAgICB0aGlzLmV2dCA9IGV2ZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIEdldHMgdGhlIHByb3BlcnR5IGNoYW5nZSBldmVudC4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiBBbiBpbnN0YW5jZSBvZiB7QGxpbmsgUHJvcGVydHlDaGFuZ2VFdmVudH0KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvcGVydHlDaGFuZ2VFdmVudCBnZXRQcm9wZXJ0eUNoYW5nZUV2ZW50KCkgeworICAgICAgICByZXR1cm4gZXZ0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL0lJT0V4Y2VwdGlvbi5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSUlPRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc3NzE2YwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL0lJT0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBJSU9FeGNlcHRpb24gY2xhc3MgaW5kaWNhdGVzIGVycm9ycyBpbiByZWFkaW5nL3dyaXRpbmcgb3BlcmF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJSU9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzIxNjIxMDcxODYzODk4NTI1MUw7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPRXhjZXB0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsZWQgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJSU9FeGNlcHRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWxlZCBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJSU9FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgaW5pdENhdXNlKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9JSU9JbWFnZS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSUlPSW1hZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWU1MTMwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vSUlPSW1hZ2UuamF2YQpAQCAtMCwwICsxLDIyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2VpbzsKKworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGE7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmVuZGVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SYXN0ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBUaGUgSUlPSW1hZ2UgY2xhc3MgY29tYmluZXMgdGhlIGltYWdlLCBpbWFnZSdzIHRodW1ibmFpbCBhbmQgaW1hZ2UncworICogbWV0YWRhdGEuIFRoZSBpbWFnZSBjYW4gYmUgcHJlc2VudGVkIGFzIFJlbmRlcmVkSW1hZ2Ugb3IgUmFzdGVyIG9iamVjdC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJSU9JbWFnZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW1hZ2Ugb2YgdGhpcyBJSU9JbWFnZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVuZGVyZWRJbWFnZSBpbWFnZTsKKworICAgIC8qKgorICAgICAqIFRoZSByYXN0ZXIgb2YgdGhpcyBJSU9JbWFnZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmFzdGVyIHJhc3RlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBsaXN0IHdpdGggdGh1bWJuYWlscyBhc3NvY2lhdGVkIHdpdGggdGhlIGltYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBMaXN0PD8gZXh0ZW5kcyBCdWZmZXJlZEltYWdlPiB0aHVtYm5haWxzOworCisgICAgLyoqCisgICAgICogVGhlIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgaW1hZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT01ldGFkYXRhIG1ldGFkYXRhOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElJT0ltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBSZW5kZXJlZEltYWdlLCBsaXN0IG9mCisgICAgICogdGh1bWJuYWlscyBhbmQgbWV0YWRhdGEuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2Ugc3BlY2lmaWVkIGJ5IFJlbmRlcmVkSW1hZ2UuCisgICAgICogQHBhcmFtIHRodW1ibmFpbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0cyB3aGljaCByZXByZXNlbnQgdGhlCisgICAgICogICAgICAgICAgICB0aHVtYm5haWxzIG9mIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gbWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXRhZGF0YSBvZiB0aGUgaW1hZ2UuCisgICAgICovCisgICAgcHVibGljIElJT0ltYWdlKFJlbmRlcmVkSW1hZ2UgaW1hZ2UsIExpc3Q8PyBleHRlbmRzIEJ1ZmZlcmVkSW1hZ2U+IHRodW1ibmFpbHMsCisgICAgICAgICAgICBJSU9NZXRhZGF0YSBtZXRhZGF0YSkgeworICAgICAgICBpZiAoaW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW1hZ2Ugc2hvdWxkIG5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5yYXN0ZXIgPSBudWxsOworICAgICAgICB0aGlzLmltYWdlID0gaW1hZ2U7CisgICAgICAgIHRoaXMudGh1bWJuYWlscyA9IHRodW1ibmFpbHM7CisgICAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPSW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIFJhc3RlciwgbGlzdCBvZiB0aHVtYm5haWxzCisgICAgICogYW5kIG1ldGFkYXRhLgorICAgICAqIAorICAgICAqIEBwYXJhbSByYXN0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSYXN0ZXIuCisgICAgICogQHBhcmFtIHRodW1ibmFpbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0cyB3aGljaCByZXByZXNlbnQgdGhlCisgICAgICogICAgICAgICAgICB0aHVtYm5haWxzIG9mIFJhc3RlciBkYXRhLgorICAgICAqIEBwYXJhbSBtZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIG1ldGFkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBJSU9JbWFnZShSYXN0ZXIgcmFzdGVyLCBMaXN0PD8gZXh0ZW5kcyBCdWZmZXJlZEltYWdlPiB0aHVtYm5haWxzLCBJSU9NZXRhZGF0YSBtZXRhZGF0YSkgeworICAgICAgICBpZiAocmFzdGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJhc3RlciBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmltYWdlID0gbnVsbDsKKyAgICAgICAgdGhpcy5yYXN0ZXIgPSByYXN0ZXI7CisgICAgICAgIHRoaXMudGh1bWJuYWlscyA9IHRodW1ibmFpbHM7CisgICAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBSZW5kZXJlZEltYWdlIG9iamVjdCBvciByZXR1cm5zIG51bGwgaWYgdGhpcyBJSU9JbWFnZSBvYmplY3QgaXMKKyAgICAgKiBhc3NvY2lhdGVkIHdpdGggYSBSYXN0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgUmVuZGVyZWRJbWFnZSBvYmplY3Qgb3IgbnVsbCBpZiB0aGlzIElJT0ltYWdlIG9iamVjdCBpcworICAgICAqICAgICAgICAgYXNzb2NpYXRlZCB3aXRoIGEgUmFzdGVyLgorICAgICAqLworICAgIHB1YmxpYyBSZW5kZXJlZEltYWdlIGdldFJlbmRlcmVkSW1hZ2UoKSB7CisgICAgICAgIHJldHVybiBpbWFnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBSZW5kZXJlZEltYWdlIHRvIHRoaXMgSUlPSW1hZ2Ugb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmVkSW1hZ2UgdG8gYmUgc2V0IHRvIHRoaXMgSUlPSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVuZGVyZWRJbWFnZShSZW5kZXJlZEltYWdlIGltYWdlKSB7CisgICAgICAgIGlmIChpbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbWFnZSBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICByYXN0ZXIgPSBudWxsOworICAgICAgICB0aGlzLmltYWdlID0gaW1hZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBJSU9JbWFnZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIGEgUmFzdGVyLCBvciBmYWxzZSBpZgorICAgICAqIGl0J3MgYXNzb2NpYXRlZCB3aXRoIGEgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBJSU9JbWFnZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIGEgUmFzdGVyLCBvciBmYWxzZQorICAgICAqICAgICAgICAgaWYgaXQncyBhc3NvY2lhdGVkIHdpdGggYSBSZW5kZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1Jhc3RlcigpIHsKKyAgICAgICAgcmV0dXJuIHJhc3RlciAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFJhc3RlciBvYmplY3Qgb3IgcmV0dXJucyBudWxsIGlmIHRoaXMgSUlPSW1hZ2Ugb2JqZWN0IGlzCisgICAgICogYXNzb2NpYXRlZCB3aXRoIGEgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBSYXN0ZXIgb3IgbnVsbCBpZiB0aGlzIElJT0ltYWdlIG9iamVjdCBpcyBhc3NvY2lhdGVkIHdpdGggYQorICAgICAqICAgICAgICAgUmVuZGVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFzdGVyIGdldFJhc3RlcigpIHsKKyAgICAgICAgcmV0dXJuIHJhc3RlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBSYXN0ZXIgdG8gdGhlIElJT0ltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByYXN0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgUmFzdGVyIHRvIHRoZSBJSU9JbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSYXN0ZXIoUmFzdGVyIHJhc3RlcikgeworICAgICAgICBpZiAocmFzdGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJhc3RlciBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBpbWFnZSA9IG51bGw7CisgICAgICAgIHRoaXMucmFzdGVyID0gcmFzdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiB0aHVtYm5haWxzIGZvciB0aGlzIElJT0ltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0aHVtYm5haWxzIGZvciB0aGlzIElJT0ltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtVGh1bWJuYWlscygpIHsKKyAgICAgICAgcmV0dXJuIHRodW1ibmFpbHMgIT0gbnVsbCA/IHRodW1ibmFpbHMuc2l6ZSgpIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aHVtYm5haWwgd2l0aCB0aGUgc3BlY2lmaWVkIGluZGV4IGluIHRoZSBsaXN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSB0aHVtYm5haWwgaW4gdGhlIGxpc3QuCisgICAgICogQHJldHVybiB0aGUgdGh1bWJuYWlsIHdpdGggdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSBnZXRUaHVtYm5haWwoaW50IGluZGV4KSB7CisgICAgICAgIGlmICh0aHVtYm5haWxzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0aHVtYm5haWxzLmdldChpbmRleCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm5vIHRodW1ibmFpbHMgd2VyZSBzZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsaXN0IG9mIHRodW1ibmFpbHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiB0aHVtYm5haWxzLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBCdWZmZXJlZEltYWdlPiBnZXRUaHVtYm5haWxzKCkgeworICAgICAgICByZXR1cm4gdGh1bWJuYWlsczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsaXN0IG9mIHRodW1ibmFpbHMgaW1hZ2VzIHRvIHRoaXMgSUlPSW1hZ2Ugb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aHVtYm5haWxzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBCdWZmZXJlZEltYWdlIHdoaWNoIHJlcHJlc2VudCB0aHVtYm5haWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRodW1ibmFpbHMoTGlzdDw/IGV4dGVuZHMgQnVmZmVyZWRJbWFnZT4gdGh1bWJuYWlscykgeworICAgICAgICB0aGlzLnRodW1ibmFpbHMgPSB0aHVtYm5haWxzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIG9mIHRoaXMgSUlPSW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWV0YWRhdGEgb2YgdGhpcyBJSU9JbWFnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0TWV0YWRhdGEoKSB7CisgICAgICAgIHJldHVybiBtZXRhZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtZXRhZGF0YSB0byB0aGlzIElJT0ltYWdlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9NZXRhZGF0YSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNZXRhZGF0YShJSU9NZXRhZGF0YSBtZXRhZGF0YSkgeworICAgICAgICB0aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vSUlPUGFyYW0uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL0lJT1BhcmFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmNjYzk0NQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL0lJT1BhcmFtLmphdmEKQEAgLTAsMCArMSwzNDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZhLmF3dC4qOworCisvKioKKyAqIFRoZSBJSU9QYXJhbSBhYnN0cmFjdCBjbGFzcyBpcyBzdXBlcmNsYXNzIGZvciBJbWFnZVJlYWRQYXJhbSBhbmQKKyAqIEltYWdlV3JpdGVQYXJhbSBjbGFzc2VzIGFuZCBwcm92aWRlcyBtZXRob2RzIGFuZCB2YXJpYWJsZXMgd2hpY2ggdGhleSBzaGFyZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJSU9QYXJhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc291cmNlIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVjdGFuZ2xlIHNvdXJjZVJlZ2lvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBzb3VyY2UgeCBzdWJzYW1wbGluZy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHNvdXJjZVhTdWJzYW1wbGluZyA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc291cmNlIHkgc3Vic2FtcGxpbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzb3VyY2VZU3Vic2FtcGxpbmcgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIHN1YnNhbXBsaW5nIHggb2Zmc2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgc3Vic2FtcGxpbmdYT2Zmc2V0OworCisgICAgLyoqCisgICAgICogVGhlIHN1YnNhbXBsaW5nIHkgb2Zmc2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgc3Vic2FtcGxpbmdZT2Zmc2V0OworCisgICAgLyoqCisgICAgICogVGhlIHNvdXJjZSBiYW5kcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50W10gc291cmNlQmFuZHM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVzdGluYXRpb24gdHlwZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VUeXBlU3BlY2lmaWVyIGRlc3RpbmF0aW9uVHlwZTsKKworICAgIC8qKgorICAgICAqIFRoZSBkZXN0aW5hdGlvbiBvZmZzZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBvaW50IGRlc3RpbmF0aW9uT2Zmc2V0ID0gbmV3IFBvaW50KDAsIDApOworCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQgY29udHJvbGxlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSUlPUGFyYW1Db250cm9sbGVyIGRlZmF1bHRDb250cm9sbGVyOworCisgICAgLyoqCisgICAgICogVGhlIGNvbnRyb2xsZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT1BhcmFtQ29udHJvbGxlciBjb250cm9sbGVyOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElJT1BhcmFtLgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9QYXJhbSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzb3VyY2UgcmVnaW9uIGFzIGEgUmVjdGFuZ2xlIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlUmVnaW9uCisgICAgICogICAgICAgICAgICB0aGUgUmVjdGFuZ2xlIHdoaWNoIHNwZWNpZmllcyB0aGUgc291cmNlIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VSZWdpb24oUmVjdGFuZ2xlIHNvdXJjZVJlZ2lvbikgeworICAgICAgICBpZiAoc291cmNlUmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChzb3VyY2VSZWdpb24ueCA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ4IDwgMCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNvdXJjZVJlZ2lvbi55IDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInkgPCAwIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc291cmNlUmVnaW9uLndpZHRoIDw9IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ3aWR0aCA8PSAwIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc291cmNlUmVnaW9uLmhlaWdodCA8PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaGVpZ2h0IDw9IDAiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNvdXJjZVJlZ2lvbi53aWR0aCA8PSBzdWJzYW1wbGluZ1hPZmZzZXQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ3aWR0aCA8PSBzdWJzYW1wbGluZ1hPZmZzZXQiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNvdXJjZVJlZ2lvbi5oZWlnaHQgPD0gc3Vic2FtcGxpbmdZT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaGVpZ2h0IDw9IHN1YnNhbXBsaW5nWE9mZnNldCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gLS0gY2xvbmUgaXQgdG8gYXZvaWQgdW5leHBlY3RlZCBtb2RpZmljYXRpb25zCisgICAgICAgICAgICB0aGlzLnNvdXJjZVJlZ2lvbiA9IChSZWN0YW5nbGUpc291cmNlUmVnaW9uLmNsb25lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLnNvdXJjZVJlZ2lvbiA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzb3VyY2UgcmVnaW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSByZWdpb24gYXMgUmVjdGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0U291cmNlUmVnaW9uKCkgeworICAgICAgICBpZiAoc291cmNlUmVnaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIC0tIGNsb25lIGl0IHRvIGF2b2lkIHVuZXhwZWN0ZWQgbW9kaWZpY2F0aW9ucworICAgICAgICByZXR1cm4gKFJlY3RhbmdsZSlzb3VyY2VSZWdpb24uY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzb3VyY2Ugc3Vic2FtcGxpbmcuIFRoZSBzb3VyY2VYU3Vic2FtcGxpbmcgYW5kCisgICAgICogc291cmNlWVN1YnNhbXBsaW5nIHBhcmFtZXRlcnMgc3BlY2lmeSB0aGUgbnVtYmVyIG9mIHJvd3MgYW5kIGNvbHVtbnMgdG8KKyAgICAgKiBhZHZhbmNlIGFmdGVyIGV2ZXJ5IHNvdXJjZSBwaXhlbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlWFN1YnNhbXBsaW5nCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIFggc3Vic2FtcGxpbmcuCisgICAgICogQHBhcmFtIHNvdXJjZVlTdWJzYW1wbGluZworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBZIHN1YnNhbXBsaW5nLgorICAgICAqIEBwYXJhbSBzdWJzYW1wbGluZ1hPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWJzYW1wbGluZyBYIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gc3Vic2FtcGxpbmdZT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3Vic2FtcGxpbmcgWSBvZmZzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U291cmNlU3Vic2FtcGxpbmcoaW50IHNvdXJjZVhTdWJzYW1wbGluZywgaW50IHNvdXJjZVlTdWJzYW1wbGluZywKKyAgICAgICAgICAgIGludCBzdWJzYW1wbGluZ1hPZmZzZXQsIGludCBzdWJzYW1wbGluZ1lPZmZzZXQpIHsKKworICAgICAgICBpZiAoc291cmNlWFN1YnNhbXBsaW5nIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNvdXJjZVhTdWJzYW1wbGluZyA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNvdXJjZVlTdWJzYW1wbGluZyA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzb3VyY2VZU3Vic2FtcGxpbmcgPD0gMCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN1YnNhbXBsaW5nWE9mZnNldCA8PSAwIHx8IHN1YnNhbXBsaW5nWE9mZnNldCA+PSBzb3VyY2VYU3Vic2FtcGxpbmcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN1YnNhbXBsaW5nWE9mZnNldCBpcyB3cm9uZyIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN1YnNhbXBsaW5nWU9mZnNldCA8PSAwIHx8IHN1YnNhbXBsaW5nWU9mZnNldCA+PSBzb3VyY2VZU3Vic2FtcGxpbmcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN1YnNhbXBsaW5nWU9mZnNldCBpcyB3cm9uZyIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gLS0gZG9lcyByZWdpb24gY29udGFpbiBwaXhlbHMKKyAgICAgICAgaWYgKHNvdXJjZVJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc291cmNlUmVnaW9uLndpZHRoIDw9IHN1YnNhbXBsaW5nWE9mZnNldAorICAgICAgICAgICAgICAgICAgICB8fCBzb3VyY2VSZWdpb24uaGVpZ2h0IDw9IHN1YnNhbXBsaW5nWU9mZnNldCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRoZXJlIGFyZSBubyBwaXhlbHMgaW4gcmVnaW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnNvdXJjZVhTdWJzYW1wbGluZyA9IHNvdXJjZVhTdWJzYW1wbGluZzsKKyAgICAgICAgdGhpcy5zb3VyY2VZU3Vic2FtcGxpbmcgPSBzb3VyY2VZU3Vic2FtcGxpbmc7CisgICAgICAgIHRoaXMuc3Vic2FtcGxpbmdYT2Zmc2V0ID0gc3Vic2FtcGxpbmdYT2Zmc2V0OworICAgICAgICB0aGlzLnN1YnNhbXBsaW5nWU9mZnNldCA9IHN1YnNhbXBsaW5nWU9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzb3VyY2UgWCBzdWJzYW1wbGluZyAtIHRoZSBudW1iZXIgb2Ygc291cmNlIGNvbHVtbnMgdG8gYWR2YW5jZQorICAgICAqIGZvciBlYWNoIHBpeGVsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSBYIHN1YnNhbXBsaW5nLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U291cmNlWFN1YnNhbXBsaW5nKCkgeworICAgICAgICByZXR1cm4gc291cmNlWFN1YnNhbXBsaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNvdXJjZSBZIHN1YnNhbXBsaW5nIC0gdGhlIG51bWJlciBvZiBzb3VyY2Ugcm93cyB0byBhZHZhbmNlIGZvcgorICAgICAqIGVhY2ggcGl4ZWwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc291cmNlIFkgc3Vic2FtcGxpbmcuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTb3VyY2VZU3Vic2FtcGxpbmcoKSB7CisgICAgICAgIHJldHVybiBzb3VyY2VZU3Vic2FtcGxpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaG9yaXpvbnRhbCBvZmZzZXQgb2YgdGhlIHN1YnNhbXBsaW5nIGdyaWQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaG9yaXpvbnRhbCBvZmZzZXQgb2YgdGhlIHN1YnNhbXBsaW5nIGdyaWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTdWJzYW1wbGluZ1hPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBzdWJzYW1wbGluZ1hPZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmVydGljYWwgb2Zmc2V0IG9mIHRoZSBzdWJzYW1wbGluZyBncmlkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHZlcnRpY2FsIG9mZnNldCBvZiB0aGUgc3Vic2FtcGxpbmcgZ3JpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN1YnNhbXBsaW5nWU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIHN1YnNhbXBsaW5nWU9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbmRpY2VzIG9mIHRoZSBzb3VyY2UgYmFuZHMuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZUJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgaW5kaWNlcyBvZiB0aGUgc291cmNlIGJhbmRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZUJhbmRzKGludFtdIHNvdXJjZUJhbmRzKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFycmF5IG9mIHNvdXJjZSBiYW5kcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBzb3VyY2UgYmFuZHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldFNvdXJjZUJhbmRzKCkgeworICAgICAgICAvLyBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQgSW1hZ2VUeXBlU3BlY2lmaWVyIGZvciB0aGUgZGVzdGluYXRpb24gaW1hZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIGRlc3RpbmF0aW9uVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZXN0aW5hdGlvblR5cGUoSW1hZ2VUeXBlU3BlY2lmaWVyIGRlc3RpbmF0aW9uVHlwZSkgeworICAgICAgICAvLyBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0eXBlIG9mIHRoZSBkZXN0aW5hdGlvbiBpbWFnZSBhcyBhbiBJbWFnZVR5cGVTcGVjaWZpZXIuIC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICovCisgICAgcHVibGljIEltYWdlVHlwZVNwZWNpZmllciBnZXREZXN0aW5hdGlvblR5cGUoKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gaW1hZ2Ugd2hlcmUgdGhlIGRlY29kZWQgcGl4ZWxzIGFyZQorICAgICAqIHBsYWNlZCBhcyBhIHJlc3VsdCBvZiByZWFkaW5nLCBvciBzcGVjaWZpZWQgYW4gYXJlYSB0byBiZSB3cml0dGVuIHdoaWxlCisgICAgICogd3JpdGluZyBvcGVyYXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGRlc3RpbmF0aW9uT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gb2Zmc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlc3RpbmF0aW9uT2Zmc2V0KFBvaW50IGRlc3RpbmF0aW9uT2Zmc2V0KSB7CisgICAgICAgIGlmIChkZXN0aW5hdGlvbk9mZnNldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJkZXN0aW5hdGlvbk9mZnNldCA9PSBudWxsISIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5kZXN0aW5hdGlvbk9mZnNldCA9IChQb2ludClkZXN0aW5hdGlvbk9mZnNldC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gaW1hZ2UgZm9yIHBsYWNpbmcgcGl4ZWxzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gaW1hZ2UuCisgICAgICovCisgICAgcHVibGljIFBvaW50IGdldERlc3RpbmF0aW9uT2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gKFBvaW50KWRlc3RpbmF0aW9uT2Zmc2V0LmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgSUlPUGFyYW1Db250cm9sbGVyIHRvIHRoaXMgSUlPUGFyYW0gb2JqZWN0IGZvciBwcm92aWRpbmcKKyAgICAgKiBzZXR0aW5ncyB0byB0aGlzIElJT1BhcmFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb250cm9sbGVyCisgICAgICogICAgICAgICAgICB0aGUgbmV3IElJT1BhcmFtQ29udHJvbGxlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250cm9sbGVyKElJT1BhcmFtQ29udHJvbGxlciBjb250cm9sbGVyKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgSUlPUGFyYW1Db250cm9sbGVyIGNvbnRyb2xsZXIgZm9yIHRoaXMgSUlPUGFyYW0uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBJSU9QYXJhbUNvbnRyb2xsZXIgY29udHJvbGxlciBmb3IgdGhpcyBJSU9QYXJhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPUGFyYW1Db250cm9sbGVyIGdldENvbnRyb2xsZXIoKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgSUlPUGFyYW1Db250cm9sbGVyIGNvbnRyb2xsZXIgZm9yIHRoaXMgSUlPUGFyYW0uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBJSU9QYXJhbUNvbnRyb2xsZXIgY29udHJvbGxlciBmb3IgdGhpcyBJSU9QYXJhbSwgb3IKKyAgICAgKiAgICAgICAgIG51bGwuCisgICAgICovCisgICAgcHVibGljIElJT1BhcmFtQ29udHJvbGxlciBnZXREZWZhdWx0Q29udHJvbGxlcigpIHsKKyAgICAgICAgLy8gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIElJT1BhcmFtQ29udHJvbGxlciBpcyBpbnN0YWxsZWQgZm9yIHRoaXMgSUlPUGFyYW0uCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBJSU9QYXJhbUNvbnRyb2xsZXIgaXMgaW5zdGFsbGVkIGZvciB0aGlzIElJT1BhcmFtLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0NvbnRyb2xsZXIoKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjdGl2YXRlcyB0aGUgY29udHJvbGxlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhY3RpdmF0ZUNvbnRyb2xsZXIoKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL0lJT1BhcmFtQ29udHJvbGxlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSUlPUGFyYW1Db250cm9sbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM4Y2IyNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL0lJT1BhcmFtQ29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvOworCisvKiAKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworLyoqCisgKiBUaGUgSUlPUGFyYW1Db250cm9sbGVyIHNwZWNpZmllcyBhbiBhY3RpdmF0ZSBtZXRob2QgdGhhdCBpbnZva2VzIHRoZQorICogY29udHJvbGxlci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUlPUGFyYW1Db250cm9sbGVyIHsKKworICAgIC8qKgorICAgICAqIEFjdGl2YXRlcyB0aGUgY29udHJvbGxlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9QYXJhbS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBJSU9QYXJhbSBoYXMgYmVlbiBtb2RpZmllZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIGJvb2xlYW4gYWN0aXZhdGUoSUlPUGFyYW0gcGFyYW0pOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VJTy5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VJTy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwZDdlYzkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZUlPLmphdmEKQEAgLTAsMCArMSw4MDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3BpLio7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlbmRlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5uZXQuVVJMOworCisvKioKKyAqIFRoZSBJbWFnZUlPIGNsYXNzIHByb3ZpZGVzIHN0YXRpYyBtZXRob2RzIHRvIHBlcmZvcm0gcmVhZGluZyBhbmQgd3JpdGluZworICogb3BlcmF0aW9ucyB1c2luZyByZWdpc3RlcmVkIEltYWdlUmVhZGVyIGFuZCBJbWFnZVdyaXRlciBvYmplY3RzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEltYWdlSU8geworCisgICAgLyoqCisgICAgICogVGhlIGNvbnN0YW50IHJlZ2lzdHJ5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIElJT1JlZ2lzdHJ5IHJlZ2lzdHJ5ID0gSUlPUmVnaXN0cnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VJTy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEltYWdlSU8oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2NhbnMgZm9yIHBsdWctaW5zIGluIHRoZSBjbGFzcyBwYXRoLCBsb2FkcyBzcGkgY2xhc3NlcywgYW5kIHJlZ2lzdGVycworICAgICAqIHRoZW0gd2l0aCB0aGUgSUlPUmVnaXN0cnkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNjYW5Gb3JQbHVnaW5zKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBmbGFnIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIGEgY2FjaGUgZmlsZSBpcyB1c2VkIHdoZW4gY3JlYXRpbmcKKyAgICAgKiBJbWFnZUlucHV0U3RyZWFtcyBhbmQgSW1hZ2VPdXRwdXRTdHJlYW1zIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdXNlQ2FjaGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB1c2UgY2FjaGUgZmxhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VXNlQ2FjaGUoYm9vbGVhbiB1c2VDYWNoZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmxhZyB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIGNhY2hlIGZpbGUgaXMgdXNlZCB3aGVuIGNyZWF0aW5nCisgICAgICogSW1hZ2VJbnB1dFN0cmVhbXMgYW5kIEltYWdlT3V0cHV0U3RyZWFtcyBvciBub3QuIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlCisgICAgICogY3VycmVudCB2YWx1ZSB3aGljaCBpcyBzZXQgYnkgc2V0VXNlQ2FjaGUgbWV0aG9kLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHVzZSBjYWNoZSBmbGFnLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBnZXRVc2VDYWNoZSgpIHsKKyAgICAgICAgLy8gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNhY2hlIGRpcmVjdG9yeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2FjaGVEaXJlY3RvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBGaWxlIHdoaWNoIHNwZWNpZmllcyBhIGNhY2hlIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2FjaGVEaXJlY3RvcnkoRmlsZSBjYWNoZURpcmVjdG9yeSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGlyZWN0b3J5IHdoZXJlIGNhY2hlIGZpbGVzIGFyZSBjcmVhdGVkLCByZXR1cm5lZCB0aGUgZmlsZSB3aGljaAorICAgICAqIGlzIHNldCBieSBzZXRDYWNoZURpcmVjdG9yeSBtZXRob2QsIG9yIG51bGwuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgRmlsZSBvYmplY3Qgd2hpY2ggaXMgc2V0IGJ5IHNldENhY2hlRGlyZWN0b3J5IG1ldGhvZCwgb3IKKyAgICAgKiAgICAgICAgIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGaWxlIGdldENhY2hlRGlyZWN0b3J5KCkgeworICAgICAgICAvLyBUT0RPIGltcGxlbWVudAorICAgICAgICAvLyAtLSBudWxsIGluZGljYXRlcyBzeXN0ZW0tZGVwIGRlZmF1bHQgdGVtcG9yYXJ5IGRpcmVjdG9yeQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIEltYWdlSW5wdXRTdHJlYW0gZnJvbSB0aGUgc3BlY2lmaWVkIE9iamVjdC4gVGhlIHNwZWNpZmllZAorICAgICAqIE9iamVjdCBzaG91bGQgb2J0YWluIHRoZSBpbnB1dCBzb3VyY2Ugc3VjaCBhcyBGaWxlLCBvciBJbnB1dFN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBPYmplY3Qgc3VjaCBhcyBGaWxlLCBvciBJbnB1dFN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZUlucHV0U3RyZWFtIG9iamVjdCwgb3IgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbWFnZUlucHV0U3RyZWFtIGNyZWF0ZUltYWdlSW5wdXRTdHJlYW0oT2JqZWN0IGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCBzb3VyY2UgY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorCisgICAgICAgIEl0ZXJhdG9yPEltYWdlSW5wdXRTdHJlYW1TcGk+IGl0ID0gcmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyhJbWFnZUlucHV0U3RyZWFtU3BpLmNsYXNzLAorICAgICAgICAgICAgICAgIHRydWUpOworCisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIEltYWdlSW5wdXRTdHJlYW1TcGkgc3BpID0gaXQubmV4dCgpOworICAgICAgICAgICAgaWYgKHNwaS5nZXRJbnB1dENsYXNzKCkuaXNJbnN0YW5jZShpbnB1dCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3BpLmNyZWF0ZUlucHV0U3RyZWFtSW5zdGFuY2UoaW5wdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gSW1hZ2VPdXRwdXRTdHJlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCBPYmplY3QuIFRoZSBzcGVjaWZpZWQKKyAgICAgKiBPYmplY3Qgc2hvdWxkIG9idGFpbiB0aGUgb3V0cHV0IHNvdXJjZSBzdWNoIGFzIEZpbGUsIG9yIE91dHB1dFN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IE9iamVjdCBzdWNoIGFzIEZpbGUsIG9yIE91dHB1dFN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZU91dHB1dFN0cmVhbSBvYmplY3QsIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VPdXRwdXRTdHJlYW0gY3JlYXRlSW1hZ2VPdXRwdXRTdHJlYW0oT2JqZWN0IG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG91dHB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJvdXRwdXQgZGVzdGluYXRpb24gY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorCisgICAgICAgIEl0ZXJhdG9yPEltYWdlT3V0cHV0U3RyZWFtU3BpPiBpdCA9IHJlZ2lzdHJ5LmdldFNlcnZpY2VQcm92aWRlcnMoCisgICAgICAgICAgICAgICAgSW1hZ2VPdXRwdXRTdHJlYW1TcGkuY2xhc3MsIHRydWUpOworCisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIEltYWdlT3V0cHV0U3RyZWFtU3BpIHNwaSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChzcGkuZ2V0T3V0cHV0Q2xhc3MoKS5pc0luc3RhbmNlKG91dHB1dCkpIHsKKyAgICAgICAgICAgICAgICAvLyB0b2RvIC0gdXNlIGdldFVzZUNhY2hlIGFuZCBnZXRDYWNoZURpciBoZXJlCisgICAgICAgICAgICAgICAgcmV0dXJuIHNwaS5jcmVhdGVPdXRwdXRTdHJlYW1JbnN0YW5jZShvdXRwdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFycmF5IG9mIGZvcm1hdCBuYW1lcyBhcyBTdHJpbmcgd2hpY2ggY2FuIGJlIGRlY29kZWQgYnkKKyAgICAgKiByZWdpc3RlcmVkIEltYWdlUmVhZGVyIG9iamVjdHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0UmVhZGVyRm9ybWF0TmFtZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBNSU1FIHR5cGVzIGFzIFN0cmluZyB3aGljaCBjYW4gYmUgZGVjb2RlZCBieSByZWdpc3RlcmVkCisgICAgICogSW1hZ2VSZWFkZXIgb2JqZWN0cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBNSU1FIHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0UmVhZGVyTUlNRVR5cGVzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgSXRlcmF0b3Igb2YgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlciB3aGljaCBhcmUgYWJsZSB0byBkZWNvZGUgYW4KKyAgICAgKiBpbnB1dCBkYXRhIHNwZWNpZmllZCBieSBpbnB1dCBPYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgT2JqZWN0IHdpdGggZW5jb2RlZCBkYXRhIHN1Y2ggYXMgSW1hZ2VJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VSZWFkZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJdGVyYXRvcjxJbWFnZVJlYWRlcj4gZ2V0SW1hZ2VSZWFkZXJzKE9iamVjdCBpbnB1dCkgeworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJpbnB1dCBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VSZWFkZXJTcGk+IGl0ID0gcmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyhJbWFnZVJlYWRlclNwaS5jbGFzcywKKyAgICAgICAgICAgICAgICBuZXcgQ2FuUmVhZEZpbHRlcihpbnB1dCksIHRydWUpOworCisgICAgICAgIHJldHVybiBuZXcgU3BpSXRlcmF0b3JUb1JlYWRlcnNJdGVyYXRvcldyYXBwZXIoaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VSZWFkZXIgd2hpY2ggYXJlIGFibGUgdG8gZGVjb2RlIHRoZQorICAgICAqIHNwZWNpZmllZCBmb3JtYXQuCisgICAgICogCisgICAgICogQHBhcmFtIGZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXQgbmFtZSBzdWNoIGFzICJqcGVnIiwgb3IgImdpZiIuCisgICAgICogQHJldHVybiB0aGUgSXRlcmF0b3Igb2YgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEl0ZXJhdG9yPEltYWdlUmVhZGVyPiBnZXRJbWFnZVJlYWRlcnNCeUZvcm1hdE5hbWUoU3RyaW5nIGZvcm1hdE5hbWUpIHsKKyAgICAgICAgaWYgKGZvcm1hdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmb3JtYXQgbmFtZSBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VSZWFkZXJTcGk+IGl0ID0gcmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyhJbWFnZVJlYWRlclNwaS5jbGFzcywKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0RmlsdGVyKGZvcm1hdE5hbWUpLCB0cnVlKTsKKworICAgICAgICByZXR1cm4gbmV3IFNwaUl0ZXJhdG9yVG9SZWFkZXJzSXRlcmF0b3JXcmFwcGVyKGl0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJdGVyYXRvciB3aGljaCBsaXN0cyB0aGUgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlciBvYmplY3RzIHRoYXQgYXJlCisgICAgICogYWJsZSB0byBkZWNvZGUgZmlsZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHN1ZmZpeC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZmlsZVN1ZmZpeAorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgc3VmZml4IHN1Y2ggYXMgImpwZyIuCisgICAgICogQHJldHVybiB0aGUgSXRlcmF0b3Igb2YgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJdGVyYXRvcjxJbWFnZVJlYWRlcj4gZ2V0SW1hZ2VSZWFkZXJzQnlTdWZmaXgoU3RyaW5nIGZpbGVTdWZmaXgpIHsKKyAgICAgICAgaWYgKGZpbGVTdWZmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzdWZmaXggY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjxJbWFnZVJlYWRlclNwaT4gaXQgPSByZWdpc3RyeS5nZXRTZXJ2aWNlUHJvdmlkZXJzKEltYWdlUmVhZGVyU3BpLmNsYXNzLAorICAgICAgICAgICAgICAgIG5ldyBTdWZmaXhGaWx0ZXIoZmlsZVN1ZmZpeCksIHRydWUpOworCisgICAgICAgIHJldHVybiBuZXcgU3BpSXRlcmF0b3JUb1JlYWRlcnNJdGVyYXRvcldyYXBwZXIoaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VSZWFkZXIgb2JqZWN0cyB0aGF0IGFyZSBhYmxlIHRvCisgICAgICogZGVjb2RlIGZpbGVzIHdpdGggdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIE1JTUVUeXBlCisgICAgICogICAgICAgICAgICB0aGUgTUlNRSB0eXBlIHN1Y2ggYXMgImltYWdlL2pwZWciLgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VSZWFkZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSXRlcmF0b3I8SW1hZ2VSZWFkZXI+IGdldEltYWdlUmVhZGVyc0J5TUlNRVR5cGUoU3RyaW5nIE1JTUVUeXBlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIFN0cmluZ3MgZ2l2aW5nIHRoZSBuYW1lcyBvZiB0aGUgZm9ybWF0cyBzdXBwb3J0ZWQgYnkKKyAgICAgKiByZWdpc3RlcmVkIEltYWdlV3JpdGVyIG9iamVjdHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0V3JpdGVyRm9ybWF0TmFtZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIFN0cmluZ3MgZ2l2aW5nIHRoZSBNSU1FIHR5cGVzIG9mIHRoZSBmb3JtYXRzIHN1cHBvcnRlZAorICAgICAqIGJ5IHJlZ2lzdGVyZWQgSW1hZ2VXcml0ZXIgb2JqZWN0cy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBNSU1FIHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0V3JpdGVyTUlNRVR5cGVzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgSXRlcmF0b3Igd2hpY2ggbGlzdHMgdGhlIHJlZ2lzdGVyZWQgSW1hZ2VSZWFkZXIgb2JqZWN0cyB0aGF0IGFyZQorICAgICAqIGFibGUgdG8gZW5jb2RlIHRoZSBzcGVjaWZpZWQgaW1hZ2UgZm9ybWF0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgZm9ybWF0IG5hbWUgc3VjaCBhcyAianBlZyIuCisgICAgICogQHJldHVybiB0aGUgSXRlcmF0b3Igb2YgcmVnaXN0ZXJlZCBJbWFnZVdyaXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEl0ZXJhdG9yPEltYWdlV3JpdGVyPiBnZXRJbWFnZVdyaXRlcnNCeUZvcm1hdE5hbWUoU3RyaW5nIGZvcm1hdE5hbWUpIHsKKyAgICAgICAgaWYgKGZvcm1hdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmb3JtYXQgbmFtZSBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VXcml0ZXJTcGk+IGl0ID0gcmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyhJbWFnZVdyaXRlclNwaS5jbGFzcywKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0RmlsdGVyKGZvcm1hdE5hbWUpLCB0cnVlKTsKKworICAgICAgICByZXR1cm4gbmV3IFNwaUl0ZXJhdG9yVG9Xcml0ZXJzSXRlcmF0b3JXcmFwcGVyKGl0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJdGVyYXRvciB3aGljaCBsaXN0cyB0aGUgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlciBvYmplY3RzIHRoYXQgYXJlCisgICAgICogYWJsZSB0byBlbmNvZGUgdGhlIHNwZWNpZmllZCBzdWZmaXguCisgICAgICogCisgICAgICogQHBhcmFtIGZpbGVTdWZmaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlIHN1ZmZpeCBzdWNoIGFzICJqcGciLgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VXcml0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJdGVyYXRvcjxJbWFnZVdyaXRlcj4gZ2V0SW1hZ2VXcml0ZXJzQnlTdWZmaXgoU3RyaW5nIGZpbGVTdWZmaXgpIHsKKyAgICAgICAgaWYgKGZpbGVTdWZmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzdWZmaXggY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjxJbWFnZVdyaXRlclNwaT4gaXQgPSByZWdpc3RyeS5nZXRTZXJ2aWNlUHJvdmlkZXJzKEltYWdlV3JpdGVyU3BpLmNsYXNzLAorICAgICAgICAgICAgICAgIG5ldyBTdWZmaXhGaWx0ZXIoZmlsZVN1ZmZpeCksIHRydWUpOworICAgICAgICByZXR1cm4gbmV3IFNwaUl0ZXJhdG9yVG9Xcml0ZXJzSXRlcmF0b3JXcmFwcGVyKGl0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJdGVyYXRvciB3aGljaCBsaXN0cyB0aGUgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlciBvYmplY3RzIHRoYXQgYXJlCisgICAgICogYWJsZSB0byBlbmNvZGUgdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIE1JTUVUeXBlCisgICAgICogICAgICAgICAgICB0aGUgTUlNRSB0eXBlIHN1Y2ggYXMgImltYWdlL2pwZWciLgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VXcml0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJdGVyYXRvcjxJbWFnZVdyaXRlcj4gZ2V0SW1hZ2VXcml0ZXJzQnlNSU1FVHlwZShTdHJpbmcgTUlNRVR5cGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSW1hZ2VXcml0ZXIgb2JqZWN0IHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBJbWFnZVJlYWRlciwgb3IgcmV0dXJucyBudWxsIGlmIHRoZSBzcGVjaWZpZWQgSW1hZ2VSZWFkZXIgaXMgbm90CisgICAgICogcmVnaXN0ZXJlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEltYWdlUmVhZGVyLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlV3JpdGVyLCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VXcml0ZXIgZ2V0SW1hZ2VXcml0ZXIoSW1hZ2VSZWFkZXIgcmVhZGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgc3BlY2lmaWVkCisgICAgICogSW1hZ2VXcml0ZXIsIG9yIHJldHVybnMgbnVsbCBpZiB0aGUgc3BlY2lmaWVkIEltYWdlV3JpdGVyIGlzIG5vdAorICAgICAqIHJlZ2lzdGVyZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHdyaXRlcgorICAgICAqICAgICAgICAgICAgdGhlIHJlZ2lzdGVyZWQgSW1hZ2VXcml0ZXIgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlUmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VSZWFkZXIgZ2V0SW1hZ2VSZWFkZXIoSW1hZ2VXcml0ZXIgd3JpdGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJdGVyYXRvciBvZiBJbWFnZVdyaXRlciBvYmplY3RzIHdoaWNoIGFyZSBhYmxlIHRvIGVuY29kZSBpbWFnZXMKKyAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgSW1hZ2VUeXBlU3BlY2lmaWVyIGFuZCBmb3JtYXQuCisgICAgICogCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVR5cGVTcGVjaWZpZXIsIHdoaWNoIGRlZmluZXMgbGF5b3V0LgorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgSXRlcmF0b3Igb2YgSW1hZ2VXcml0ZXIgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEl0ZXJhdG9yPEltYWdlV3JpdGVyPiBnZXRJbWFnZVdyaXRlcnMoSW1hZ2VUeXBlU3BlY2lmaWVyIHR5cGUsIFN0cmluZyBmb3JtYXROYW1lKSB7CisgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidHlwZSBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZvcm1hdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmb3JtYXQgbmFtZSBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VXcml0ZXJTcGk+IGl0ID0gcmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyhJbWFnZVdyaXRlclNwaS5jbGFzcywKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0QW5kRW5jb2RlRmlsdGVyKHR5cGUsIGZvcm1hdE5hbWUpLCB0cnVlKTsKKworICAgICAgICByZXR1cm4gbmV3IFNwaUl0ZXJhdG9yVG9Xcml0ZXJzSXRlcmF0b3JXcmFwcGVyKGl0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJdGVyYXRvciBvZiByZWdpc3RlcmVkIEltYWdlVHJhbnNjb2RlcnMgd2hpY2ggYXJlIGFibGUgdG8KKyAgICAgKiB0cmFuc2NvZGUgdGhlIG1ldGFkYXRhIG9mIHRoZSBzcGVjaWZpZWQgSW1hZ2VSZWFkZXIgb2JqZWN0IHRvIGEgc3VpdGFibGUKKyAgICAgKiBvYmplY3QgZm9yIGVuY29kaW5nIGJ5IHRoZSBzcGVjaWZpZWQgSW1hZ2VXcml0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBJbWFnZVJlYWRlci4KKyAgICAgKiBAcGFyYW0gd3JpdGVyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIEltYWdlV3JpdGVyLgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgSW1hZ2VUcmFuc2NvZGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEl0ZXJhdG9yPEltYWdlVHJhbnNjb2Rlcj4gZ2V0SW1hZ2VUcmFuc2NvZGVycyhJbWFnZVJlYWRlciByZWFkZXIsCisgICAgICAgICAgICBJbWFnZVdyaXRlciB3cml0ZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGltYWdlIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIEZpbGUgYW5kIGRlY29kZXMgaXQgdXNpbmcgdGhlCisgICAgICogYXBwcm9wcmlhdGUgcmVnaXN0ZXJlZCBJbWFnZVJlYWRlciBvYmplY3QuIFRoZSBGaWxlIGlzIHdyYXBwZWQgaW4gYW4KKyAgICAgKiBJbWFnZUlucHV0U3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIEZpbGUgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlIGRlY29kZWQgZnJvbSB0aGUgc3BlY2lmaWVkIEZpbGUsIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnVmZmVyZWRJbWFnZSByZWFkKEZpbGUgaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCA9PSBudWxsISIpOworICAgICAgICB9CisKKyAgICAgICAgSW1hZ2VJbnB1dFN0cmVhbSBzdHJlYW0gPSBjcmVhdGVJbWFnZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgcmV0dXJuIHJlYWQoc3RyZWFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBpbWFnZSBkYXRhIGZyb20gdGhlIHNwZWNpZmllZCBJbnB1dFN0cmVhbSBhbmQgZGVjb2RlcyBpdCB1c2luZyBhbgorICAgICAqIGFwcHJvcHJpYXRlIHJlZ2lzdGVyZWQgYW4gSW1hZ2VSZWFkZXIgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIElucHV0U3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2UgZGVjb2RlZCBmcm9tIHRoZSBzcGVjaWZpZWQgSW5wdXRTdHJlYW0sIG9yCisgICAgICogICAgICAgICBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJ1ZmZlcmVkSW1hZ2UgcmVhZChJbnB1dFN0cmVhbSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ID09IG51bGwhIik7CisgICAgICAgIH0KKworICAgICAgICBJbWFnZUlucHV0U3RyZWFtIHN0cmVhbSA9IGNyZWF0ZUltYWdlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICByZXR1cm4gcmVhZChzdHJlYW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGltYWdlIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIFVSTCBhbmQgZGVjb2RlcyBpdCB1c2luZyB0aGUKKyAgICAgKiBhcHByb3ByaWF0ZSByZWdpc3RlcmVkIEltYWdlUmVhZGVyIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlIGRlY29kZWQgZnJvbSB0aGUgc3BlY2lmaWVkIFVSTCwgb3IgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCdWZmZXJlZEltYWdlIHJlYWQoVVJMIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW5wdXQgPT0gbnVsbCEiKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IGlucHV0Lm9wZW5TdHJlYW0oKTsKKyAgICAgICAgQnVmZmVyZWRJbWFnZSByZXMgPSByZWFkKHN0cmVhbSk7CisgICAgICAgIHN0cmVhbS5jbG9zZSgpOworCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgaW1hZ2UgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQgSW1hZ2VJbnB1dFN0cmVhbSBhbmQgZGVjb2RlcyBpdCB1c2luZworICAgICAqIGFwcHJvcHJpYXRlIHJlZ2lzdGVyZWQgYW4gSW1hZ2VSZWFkZXIgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZUlucHV0U3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2UgZGVjb2RlZCBmcm9tIHRoZSBzcGVjaWZpZWQgSW1hZ2VJbnB1dFN0cmVhbSwgb3IKKyAgICAgKiAgICAgICAgIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnVmZmVyZWRJbWFnZSByZWFkKEltYWdlSW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0cmVhbSA9PSBudWxsISIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VSZWFkZXI+IGltYWdlUmVhZGVycyA9IGdldEltYWdlUmVhZGVycyhzdHJlYW0pOworICAgICAgICBpZiAoIWltYWdlUmVhZGVycy5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgSW1hZ2VSZWFkZXIgcmVhZGVyID0gaW1hZ2VSZWFkZXJzLm5leHQoKTsKKyAgICAgICAgcmVhZGVyLnNldElucHV0KHN0cmVhbSwgZmFsc2UsIHRydWUpOworICAgICAgICBCdWZmZXJlZEltYWdlIHJlcyA9IHJlYWRlci5yZWFkKDApOworICAgICAgICByZWFkZXIuZGlzcG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gU3RyZWFtIGNvdWxkIGJlIGFscmVhZHkgY2xvc2VkLCBwcm9jZWVkIHNpbGVudGx5IGluIHRoaXMgY2FzZQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCBpbWFnZSBpbiB0aGUgc3BlY2lmaWVkIGZvcm1hdCAodXNpbmcgYW4gYXBwcm9wcmlhdGUKKyAgICAgKiBJbWFnZVdyaXRlcikgdG8gdGhlIHNwZWNpZmllZCBJbWFnZU91dHB1dFN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJlZEltYWdlLgorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlT3V0cHV0U3RyZWFtIHdoZXJlIEltYWdlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHJldHVybiB0cnVlLCBpZiBJbWFnZSBpcyB3cml0dGVuIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd3JpdGUoUmVuZGVyZWRJbWFnZSBpbSwgU3RyaW5nIGZvcm1hdE5hbWUsIEltYWdlT3V0cHV0U3RyZWFtIG91dHB1dCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKGltID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImltYWdlIGNhbm5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZvcm1hdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZm9ybWF0IG5hbWUgY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm91dHB1dCBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8SW1hZ2VXcml0ZXI+IGl0ID0gZ2V0SW1hZ2VXcml0ZXJzKEltYWdlVHlwZVNwZWNpZmllci5jcmVhdGVGcm9tUmVuZGVyZWRJbWFnZShpbSksCisgICAgICAgICAgICAgICAgZm9ybWF0TmFtZSk7CisgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIEltYWdlV3JpdGVyIHdyaXRlciA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIHdyaXRlci5zZXRPdXRwdXQob3V0cHV0KTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShpbSk7CisgICAgICAgICAgICBvdXRwdXQuZmx1c2goKTsKKyAgICAgICAgICAgIHdyaXRlci5kaXNwb3NlKCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgaW1hZ2UgaW4gdGhlIHNwZWNpZmllZCBmb3JtYXQgKHVzaW5nIGFuIGFwcHJvcHJpYXRlCisgICAgICogSW1hZ2VXcml0ZXIpIHRvIHRoZSBzcGVjaWZpZWQgRmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJlZEltYWdlLgorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBGaWxlIHdoZXJlIEltYWdlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHJldHVybiB0cnVlLCBpZiBJbWFnZSBpcyB3cml0dGVuIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd3JpdGUoUmVuZGVyZWRJbWFnZSBpbSwgU3RyaW5nIGZvcm1hdE5hbWUsIEZpbGUgb3V0cHV0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm91dHB1dCBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG91dHB1dC5leGlzdHMoKSkgeworICAgICAgICAgICAgb3V0cHV0LmRlbGV0ZSgpOworICAgICAgICB9CisKKyAgICAgICAgSW1hZ2VPdXRwdXRTdHJlYW0gaW9zID0gY3JlYXRlSW1hZ2VPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgYm9vbGVhbiBydCA9IHdyaXRlKGltLCBmb3JtYXROYW1lLCBpb3MpOworICAgICAgICBpb3MuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIHJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIGltYWdlIGluIHRoZSBzcGVjaWZpZWQgZm9ybWF0ICh1c2luZyBhbiBhcHByb3ByaWF0ZQorICAgICAqIEltYWdlV3JpdGVyKSB0byB0aGUgc3BlY2lmaWVkIE91dHB1dFN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJlZEltYWdlLgorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIE91dHB1dFN0cmVhbSB3aGVyZSBJbWFnZSBpcyB0byBiZSB3cml0dGVuLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgSW1hZ2UgaXMgd3JpdHRlbiBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHdyaXRlKFJlbmRlcmVkSW1hZ2UgaW0sIFN0cmluZyBmb3JtYXROYW1lLCBPdXRwdXRTdHJlYW0gb3V0cHV0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm91dHB1dCBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisKKyAgICAgICAgSW1hZ2VPdXRwdXRTdHJlYW0gaW9zID0gY3JlYXRlSW1hZ2VPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgYm9vbGVhbiBydCA9IHdyaXRlKGltLCBmb3JtYXROYW1lLCBpb3MpOworICAgICAgICBpb3MuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIHJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbHRlciB0byBtYXRjaCBzcGkgYnkgZm9ybWF0IG5hbWUuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIEZvcm1hdEZpbHRlciBpbXBsZW1lbnRzIFNlcnZpY2VSZWdpc3RyeS5GaWx0ZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBmb3JtYXQgZmlsdGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGb3JtYXRGaWx0ZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXIoT2JqZWN0IHByb3ZpZGVyKSB7CisgICAgICAgICAgICBJbWFnZVJlYWRlcldyaXRlclNwaSBzcGkgPSAoSW1hZ2VSZWFkZXJXcml0ZXJTcGkpcHJvdmlkZXI7CisgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChzcGkuZ2V0Rm9ybWF0TmFtZXMoKSkuY29udGFpbnMobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgdG8gbWF0Y2ggc3BpIGJ5IGZvcm1hdCBuYW1lIGFuZCBlbmNvZGluZyBwb3NzaWJpbGl0eS4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgRm9ybWF0QW5kRW5jb2RlRmlsdGVyIGV4dGVuZHMgRm9ybWF0RmlsdGVyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHR5cGUuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEltYWdlVHlwZVNwZWNpZmllciB0eXBlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZm9ybWF0IGFuZCBlbmNvZGUgZmlsdGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdHlwZS4KKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBGb3JtYXRBbmRFbmNvZGVGaWx0ZXIoSW1hZ2VUeXBlU3BlY2lmaWVyIHR5cGUsIFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZmlsdGVyKE9iamVjdCBwcm92aWRlcikgeworICAgICAgICAgICAgSW1hZ2VXcml0ZXJTcGkgc3BpID0gKEltYWdlV3JpdGVyU3BpKXByb3ZpZGVyOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmZpbHRlcihwcm92aWRlcikgJiYgc3BpLmNhbkVuY29kZUltYWdlKHR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsdGVyIHRvIG1hdGNoIHNwaSBieSBzdWZmaXguCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFN1ZmZpeEZpbHRlciBpbXBsZW1lbnRzIFNlcnZpY2VSZWdpc3RyeS5GaWx0ZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgc3VmLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgc3VmOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgc3VmZml4IGZpbHRlci4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBzdWYKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc3VmLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFN1ZmZpeEZpbHRlcihTdHJpbmcgc3VmKSB7CisgICAgICAgICAgICB0aGlzLnN1ZiA9IHN1ZjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGZpbHRlcihPYmplY3QgcHJvdmlkZXIpIHsKKyAgICAgICAgICAgIEltYWdlUmVhZGVyV3JpdGVyU3BpIHNwaSA9IChJbWFnZVJlYWRlcldyaXRlclNwaSlwcm92aWRlcjsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuYXNMaXN0KHNwaS5nZXRGaWxlU3VmZml4ZXMoKSkuY29udGFpbnMoc3VmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbHRlciB0byBtYXRjaCBzcGkgYnkgZGVjb2RpbmcgcG9zc2liaWxpdHkuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIENhblJlYWRGaWx0ZXIgaW1wbGVtZW50cyBTZXJ2aWNlUmVnaXN0cnkuRmlsdGVyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGlucHV0LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBPYmplY3QgaW5wdXQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBjYW4gcmVhZCBmaWx0ZXIuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgaW5wdXQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ2FuUmVhZEZpbHRlcihPYmplY3QgaW5wdXQpIHsKKyAgICAgICAgICAgIHRoaXMuaW5wdXQgPSBpbnB1dDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGZpbHRlcihPYmplY3QgcHJvdmlkZXIpIHsKKyAgICAgICAgICAgIEltYWdlUmVhZGVyU3BpIHNwaSA9IChJbWFnZVJlYWRlclNwaSlwcm92aWRlcjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNwaS5jYW5EZWNvZGVJbnB1dChpbnB1dCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgU3BpJ3MgaXRlcmF0b3IgdG8gSW1hZ2VXcml0ZXIgaXRlcmF0b3IuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFNwaUl0ZXJhdG9yVG9Xcml0ZXJzSXRlcmF0b3JXcmFwcGVyIGltcGxlbWVudHMgSXRlcmF0b3I8SW1hZ2VXcml0ZXI+IHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGJhY2tlbmQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEl0ZXJhdG9yPEltYWdlV3JpdGVyU3BpPiBiYWNrZW5kOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgc3BpIGl0ZXJhdG9yIHRvIHdyaXRlcnMgaXRlcmF0b3Igd3JhcHBlci4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBiYWNrZW5kCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGJhY2tlbmQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3BpSXRlcmF0b3JUb1dyaXRlcnNJdGVyYXRvcldyYXBwZXIoSXRlcmF0b3I8SW1hZ2VXcml0ZXJTcGk+IGJhY2tlbmQpIHsKKyAgICAgICAgICAgIHRoaXMuYmFja2VuZCA9IGJhY2tlbmQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTmV4dC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdGhlIGltYWdlIHdyaXRlci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBJbWFnZVdyaXRlciBuZXh0KCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYmFja2VuZC5uZXh0KCkuY3JlYXRlV3JpdGVySW5zdGFuY2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBmb3IgbmV4dC4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gYmFja2VuZC5oYXNOZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVtb3ZlcyB0aGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJVc2UgZGVyZWdpc3RlclNlcnZpY2Vwcm92aWRlciBpbnN0ZWFkIG9mIEl0ZXJhdG9yLnJlbW92ZSgpIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyBzcGkncyBpdGVyYXRvciB0byBJbWFnZVJlYWRlciBpdGVyYXRvci4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgU3BpSXRlcmF0b3JUb1JlYWRlcnNJdGVyYXRvcldyYXBwZXIgaW1wbGVtZW50cyBJdGVyYXRvcjxJbWFnZVJlYWRlcj4geworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYmFja2VuZC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgSXRlcmF0b3I8SW1hZ2VSZWFkZXJTcGk+IGJhY2tlbmQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBzcGkgaXRlcmF0b3IgdG8gcmVhZGVycyBpdGVyYXRvciB3cmFwcGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGJhY2tlbmQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgYmFja2VuZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTcGlJdGVyYXRvclRvUmVhZGVyc0l0ZXJhdG9yV3JhcHBlcihJdGVyYXRvcjxJbWFnZVJlYWRlclNwaT4gYmFja2VuZCkgeworICAgICAgICAgICAgdGhpcy5iYWNrZW5kID0gYmFja2VuZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBOZXh0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgaW1hZ2UgcmVhZGVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEltYWdlUmVhZGVyIG5leHQoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBiYWNrZW5kLm5leHQoKS5jcmVhdGVSZWFkZXJJbnN0YW5jZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGZvciBuZXh0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBiYWNrZW5kLmhhc05leHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZW1vdmVzIHRoZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlVzZSBkZXJlZ2lzdGVyU2VydmljZXByb3ZpZGVyIGluc3RlYWQgb2YgSXRlcmF0b3IucmVtb3ZlKCkiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL0ltYWdlUmVhZFBhcmFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVJlYWRQYXJhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljYzVjNWYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVJlYWRQYXJhbS5qYXZhCkBAIC0wLDAgKzEsMjAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFNlcmdleSBJLiBTYWxpc2hldgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2VpbzsKKworaW1wb3J0IGphdmEuYXd0LkRpbWVuc2lvbjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworCisvKgorICogQGF1dGhvciBTZXJnZXkgSS4gU2FsaXNoZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworCisvKioKKyAqIFRoZSBJbWFnZVJlYWRQYXJhbSBjbGFzcyBwcm92aWRlcyBpbmZvcm1hdGlvbiB0byB0aGUgSW1hZ2VSZWFkZXIgYWJvdXQgaG93IGFuCisgKiBpbWFnZSBpcyB0byBiZSBkZWNvZGVkLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEltYWdlUmVhZFBhcmFtIGV4dGVuZHMgSUlPUGFyYW0geworCisgICAgLyoqCisgICAgICogVGhpcyBmbGFnIGluZGljYXRlcyBpZiB0aGlzIEltYWdlUmVhZFBhcmFtIHN1cHBvcnRzIHNldHRpbmcgdGhlIHNvdXJjZQorICAgICAqIHJlbmRlcmluZyBzaXplLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGNhblNldFNvdXJjZVJlbmRlclNpemU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVzdGluYXRpb24gQnVmZmVyZWRJbWFnZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQnVmZmVyZWRJbWFnZSBkZXN0aW5hdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZXN0aW5hdGlvbiBiYW5kcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50W10gZGVzdGluYXRpb25CYW5kczsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIHByb2dyZXNzaXZlIHBhc3MuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBtaW5Qcm9ncmVzc2l2ZVBhc3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIHByb2dyZXNzaXZlIHBhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG51bVByb2dyZXNzaXZlUGFzc2VzOworCisgICAgLyoqCisgICAgICogVGhlIHNvdXJjZSByZW5kZXIgc2l6ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGltZW5zaW9uIHNvdXJjZVJlbmRlclNpemU7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBJbWFnZVJlYWRlclBhcmFtIHN1cHBvcnRzIHJlbmRlcmluZyBhIHNvdXJjZSBpbWFnZQorICAgICAqIGF0IGFuIGFyYml0cmFyeSBzaXplLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBJbWFnZVJlYWRlclBhcmFtIHN1cHBvcnRzIHJlbmRlcmluZyBhIHNvdXJjZSBpbWFnZQorICAgICAqICAgICAgICAgYXQgYW4gYXJiaXRyYXJ5IHNpemUsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXRTb3VyY2VSZW5kZXJTaXplKCkgeworICAgICAgICByZXR1cm4gY2FuU2V0U291cmNlUmVuZGVyU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGRlc3RpbmF0aW9uIGltYWdlIGFzIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQnVmZmVyZWRJbWFnZSB3aGljaCByZXByZXNlbnRzIHRoZSBkZXN0aW5hdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSBnZXREZXN0aW5hdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGluZGljZXMgb2YgZGVzdGluYXRpb24gYmFuZHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZGVzdGluYXRpb24gYmFuZHMuCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldERlc3RpbmF0aW9uQmFuZHMoKSB7CisgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbkJhbmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGluZGV4IG9mIHRoZSBtYXhpbXVtIHBhc3MgdG8gYmUgZGVjb2RlZC4gVGhpcyBtZXRob2QgcmV0dXJucworICAgICAqIEludGVnZXIuTUFYX1ZBTFVFLCBpZiBnZXRTb3VyY2VOdW1Qcm9ncmVzc2l2ZVBhc3NlcygpIG1ldGhvZCByZXR1cm5zCisgICAgICogdmFsdWUgdGhhdCBpcyBlcXVhbCB0byBJbnRlZ2VyLk1BWF9WQUxVRS4gT3RoZXJ3aXNlIHRoaXMgbWV0aG9kIHJldHVybnMKKyAgICAgKiBnZXRTb3VyY2VNaW5Qcm9ncmVzc2l2ZVBhc3MoKSArIGdldFNvdXJjZU51bVByb2dyZXNzaXZlUGFzc2VzKCkgLSAxLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBtYXhpbXVtIHBhc3MgdG8gYmUgZGVjb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNvdXJjZU1heFByb2dyZXNzaXZlUGFzcygpIHsKKyAgICAgICAgaWYgKGdldFNvdXJjZU51bVByb2dyZXNzaXZlUGFzc2VzKCkgPT0gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0U291cmNlTWluUHJvZ3Jlc3NpdmVQYXNzKCkgKyBnZXRTb3VyY2VOdW1Qcm9ncmVzc2l2ZVBhc3NlcygpIC0gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbmRleCBvZiB0aGUgbWluaW11bSBwcm9ncmVzc2l2ZSBwYXNzIHRoYXQgaXMgZGVjb2RlZCwgZGVmYXVsdAorICAgICAqIGlzIDAuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIG1pbmltdW0gcHJvZ3Jlc3NpdmUgcGFzcyB0aGF0IGlzIGRlY29kZWQsCisgICAgICogICAgICAgICBkZWZhdWx0IGlzIDAuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTb3VyY2VNaW5Qcm9ncmVzc2l2ZVBhc3MoKSB7CisgICAgICAgIHJldHVybiBtaW5Qcm9ncmVzc2l2ZVBhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHByb2dyZXNzaXZlIHBhc3Nlcy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMKKyAgICAgKiBJbnRlZ2VyLk1BWF9WQUxVRS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcHJvZ3Jlc3NpdmUgcGFzc2VzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U291cmNlTnVtUHJvZ3Jlc3NpdmVQYXNzZXMoKSB7CisgICAgICAgIHJldHVybiBudW1Qcm9ncmVzc2l2ZVBhc3NlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkaW1lbnNpb24gb2Ygc291cmNlIGltYWdlIHdoaWNoIHdpbGwgYmUgcmVuZGVyZWQgZHVyaW5nIGRlY29kaW5nCisgICAgICogcHJvY2Vzcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzb3VyY2UgcmVuZGVyIHNpemUuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbiBnZXRTb3VyY2VSZW5kZXJTaXplKCkgeworICAgICAgICByZXR1cm4gc291cmNlUmVuZGVyU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQgZGVzdGluYXRpb24gaW1hZ2UuIFRoaXMgaW1hZ2Ugd2lsbCBiZSB1c2VkIGJ5IHJlYWQsCisgICAgICogcmVhZEFsbCwgYW5kIHJlYWRSYXN0ZXIgbWV0aG9kcywgYW5kIGEgcmVmZXJlbmNlIHRvIGl0IHdpbGwgYmUgcmV0dXJuZWQKKyAgICAgKiBieSB0aG9zZSBtZXRob2RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGltYWdlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlc3RpbmF0aW9uKEJ1ZmZlcmVkSW1hZ2UgZGVzdGluYXRpb24pIHsKKyAgICAgICAgdGhpcy5kZXN0aW5hdGlvbiA9IGRlc3RpbmF0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGluZGljZXMgb2YgdGhlIGRlc3RpbmF0aW9uIGJhbmRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgaW5kaWNlcyBvZiB0aGUgZGVzdGluYXRpb24gYmFuZHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVzdGluYXRpb25CYW5kcyhpbnRbXSBkZXN0aW5hdGlvbkJhbmRzKSB7CisgICAgICAgIHRoaXMuZGVzdGluYXRpb25CYW5kcyA9IGRlc3RpbmF0aW9uQmFuZHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGVzdGluYXRpb25UeXBlKEltYWdlVHlwZVNwZWNpZmllciBkZXN0aW5hdGlvblR5cGUpIHsKKyAgICAgICAgdGhpcy5kZXN0aW5hdGlvblR5cGUgPSBkZXN0aW5hdGlvblR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc291cmNlIHByb2dyZXNzaXZlIHBhc3Nlcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWluUGFzcworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBtaW5pbXVtIHBhc3MgdG8gYmUgZGVjb2RlZC4KKyAgICAgKiBAcGFyYW0gbnVtUGFzc2VzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHBhc3NlcyB0byBiZSBkZWNvZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZVByb2dyZXNzaXZlUGFzc2VzKGludCBtaW5QYXNzLCBpbnQgbnVtUGFzc2VzKSB7CisgICAgICAgIG1pblByb2dyZXNzaXZlUGFzcyA9IG1pblBhc3M7CisgICAgICAgIG51bVByb2dyZXNzaXZlUGFzc2VzID0gbnVtUGFzc2VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRpbWVuc2lvbiBzaXplIG9mIHNvdXJjZSBpbWFnZSBpZiBhbiBpbWFnZSBjYW4gYmUgcmVuZGVyZWQgYXQgYW4KKyAgICAgKiBhcmJpdHJhcnkgc2l6ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgcmVuZGVyZWQgaW1hZ2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSB1bnN1cHBvcnRlZCBvcGVyYXRpb24gZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZVJlbmRlclNpemUoRGltZW5zaW9uIHNpemUpIHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2FuU2V0U291cmNlUmVuZGVyU2l6ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJjYW4ndCBzZXQgc291cmNlIHJlbmRlcmVyIHNpemUiKTsKKyAgICAgICAgfQorICAgICAgICBzb3VyY2VSZW5kZXJTaXplID0gc2l6ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVJlYWRlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjI4MmVkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VSZWFkZXIuamF2YQpAQCAtMCwwICsxLDExNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVJlYWRlclNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGE7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5ldmVudC5JSU9SZWFkV2FybmluZ0xpc3RlbmVyOworaW1wb3J0IGphdmF4LmltYWdlaW8uZXZlbnQuSUlPUmVhZFByb2dyZXNzTGlzdGVuZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5ldmVudC5JSU9SZWFkVXBkYXRlTGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlbmRlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuKjsKKworLyoqCisgKiBUaGUgSW1hZ2VSZWFkZXIgY2xhc3MgaXMgYW4gYWJzdHJhY3QgY2xhc3MgZm9yIGRlY29kaW5nIGltYWdlcy4gSW1hZ2VSZWFkZXIKKyAqIG9iamVjdHMgYXJlIGluc3RhbnRpYXRlZCBieSB0aGUgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UsIEltYWdlUmVhZGVyU3BpCisgKiBjbGFzcywgZm9yIHRoZSBzcGVjaWZpYyBmb3JtYXQuIEltYWdlUmVhZGVyU3BpIGNsYXNzIHNob3VsZCBiZSByZWdpc3RlcmVkCisgKiB3aXRoIHRoZSBJSU9SZWdpc3RyeSwgd2hpY2ggdXNlcyB0aGVtIGZvciBmb3JtYXQgcmVjb2duaXRpb24gYW5kIHByZXNlbnRhdGlvbgorICogb2YgYXZhaWxhYmxlIGZvcm1hdCByZWFkZXJzIGFuZCB3cml0ZXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlUmVhZGVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBvcmlnaW5hdGluZyBwcm92aWRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VSZWFkZXJTcGkgb3JpZ2luYXRpbmdQcm92aWRlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnB1dCBvYmplY3Qgc3VjaCBhcyBJbWFnZUlucHV0U3RyZWFtLgorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgaW5wdXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VlayBmb3J3YXJkIG9ubHkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gc2Vla0ZvcndhcmRPbmx5OworCisgICAgLyoqCisgICAgICogVGhlIGlnbm9yZSBtZXRhZGF0YSBmbGFnIGluZGljYXRlcyB3aGV0aGVyIGN1cnJlbnQgaW5wdXQgc291cmNlIGhhcyBiZWVuCisgICAgICogbWFya2VkIGFzIG1ldGFkYXRhIGlzIGFsbG93ZWQgdG8gYmUgaWdub3JlZCBieSBzZXRJbnB1dC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVNZXRhZGF0YTsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIGluZGV4LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgbWluSW5kZXg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXZhaWxhYmxlIGxvY2FsZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIExvY2FsZVtdIGF2YWlsYWJsZUxvY2FsZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jYWxlLgorICAgICAqLworICAgIHByb3RlY3RlZCBMb2NhbGUgbG9jYWxlOworCisgICAgLyoqCisgICAgICogVGhlIGxpc3Qgb2Ygd2FybmluZyBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIExpc3Q8SUlPUmVhZFdhcm5pbmdMaXN0ZW5lcj4gd2FybmluZ0xpc3RlbmVyczsKKworICAgIC8qKgorICAgICAqIFRoZSBsaXN0IG9mIHdhcm5pbmcgbG9jYWxlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTGlzdDxMb2NhbGU+IHdhcm5pbmdMb2NhbGVzOworCisgICAgLyoqCisgICAgICogVGhlIGxpc3Qgb2YgcHJvZ3Jlc3MgbGlzdGVuZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCBMaXN0PElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyPiBwcm9ncmVzc0xpc3RlbmVyczsKKworICAgIC8qKgorICAgICAqIFRoZSBsaXN0IG9mIHVwZGF0ZSBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIExpc3Q8SUlPUmVhZFVwZGF0ZUxpc3RlbmVyPiB1cGRhdGVMaXN0ZW5lcnM7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VSZWFkZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG9yaWdpbmF0aW5nUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRlclNwaSB3aGljaCBpbnN0YW50aWF0ZXMgdGhpcyBJbWFnZVJlYWRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VSZWFkZXIoSW1hZ2VSZWFkZXJTcGkgb3JpZ2luYXRpbmdQcm92aWRlcikgeworICAgICAgICB0aGlzLm9yaWdpbmF0aW5nUHJvdmlkZXIgPSBvcmlnaW5hdGluZ1Byb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZvcm1hdCBuYW1lIG9mIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdCBuYW1lIG9mIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdE5hbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gb3JpZ2luYXRpbmdQcm92aWRlci5nZXRGb3JtYXROYW1lcygpWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEltYWdlUmVhZGVyU3BpIHdoaWNoIGluc3RhbnRpYXRlZCB0aGlzIEltYWdlUmVhZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEltYWdlUmVhZGVyU3BpLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVJlYWRlclNwaSBnZXRPcmlnaW5hdGluZ1Byb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gb3JpZ2luYXRpbmdQcm92aWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGFzIHRoZSBpbnB1dCBzb3VyY2Ugb2YgdGhpcyBJbWFnZVJlYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzb3VyY2UsIGl0IGNhbiBiZSBhbiBJbWFnZUlucHV0U3RyZWFtIG9yIG90aGVyCisgICAgICogICAgICAgICAgICBzdXBwb3J0ZWQgb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gc2Vla0ZvcndhcmRPbmx5CisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciB0aGUgc3RyZWFtIG11c3QgYmUgcmVhZCBzZXF1ZW50aWFsbHkgZnJvbQorICAgICAqICAgICAgICAgICAgaXRzIGN1cnJlbnQgc3RhcnRpbmcgcG9pbnQuCisgICAgICogQHBhcmFtIGlnbm9yZU1ldGFkYXRhCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgd2hpY2ggaW5kaWNhdGVzIGlmIG1ldGFkYXRhIG1heSBiZSBpZ25vcmVkIGR1cmluZworICAgICAqICAgICAgICAgICAgcmVhZHMgb3Igbm90LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElucHV0KE9iamVjdCBpbnB1dCwgYm9vbGVhbiBzZWVrRm9yd2FyZE9ubHksIGJvb2xlYW4gaWdub3JlTWV0YWRhdGEpIHsKKyAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghaXNTdXBwb3J0ZWQoaW5wdXQpICYmICEoaW5wdXQgaW5zdGFuY2VvZiBJbWFnZUlucHV0U3RyZWFtKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ICIgKyBpbnB1dCArICIgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMubWluSW5kZXggPSAwOworICAgICAgICB0aGlzLnNlZWtGb3J3YXJkT25seSA9IHNlZWtGb3J3YXJkT25seTsKKyAgICAgICAgdGhpcy5pZ25vcmVNZXRhZGF0YSA9IGlnbm9yZU1ldGFkYXRhOworICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGlzIHN1cHBvcnRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGlzIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNTdXBwb3J0ZWQoT2JqZWN0IGlucHV0KSB7CisgICAgICAgIEltYWdlUmVhZGVyU3BpIHNwaSA9IGdldE9yaWdpbmF0aW5nUHJvdmlkZXIoKTsKKyAgICAgICAgaWYgKG51bGwgIT0gc3BpKSB7CisgICAgICAgICAgICBDbGFzc1tdIG91dFR5cGVzID0gc3BpLmdldElucHV0VHlwZXMoKTsKKyAgICAgICAgICAgIGZvciAoQ2xhc3M8Pz4gZWxlbWVudCA6IG91dFR5cGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuaXNJbnN0YW5jZShpbnB1dCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGFzIHRoZSBpbnB1dCBzb3VyY2Ugb2YgdGhpcyBJbWFnZVJlYWRlci4KKyAgICAgKiBNZXRhZGF0YSBpcyBub3QgaWdub3JlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzb3VyY2UsIGl0IGNhbiBiZSBhbiBJbWFnZUlucHV0U3RyZWFtIG9yIG90aGVyCisgICAgICogICAgICAgICAgICBzdXBwb3J0ZWQgb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gc2Vla0ZvcndhcmRPbmx5CisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciB0aGUgc3RyZWFtIG11c3QgYmUgcmVhZCBzZXF1ZW50aWFsbHkgZnJvbQorICAgICAqICAgICAgICAgICAgaXRzIGN1cnJlbnQgc3RhcnRpbmcgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5wdXQoT2JqZWN0IGlucHV0LCBib29sZWFuIHNlZWtGb3J3YXJkT25seSkgeworICAgICAgICBzZXRJbnB1dChpbnB1dCwgc2Vla0ZvcndhcmRPbmx5LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3BlY2lmaWVkIE9iamVjdCBhcyB0aGUgaW5wdXQgc291cmNlIG9mIHRoaXMgSW1hZ2VSZWFkZXIuCisgICAgICogTWV0YWRhdGEgaXMgbm90IGlnbm9yZWQgYW5kIGZvcndhcmQgc2Vla2luZyBpcyBub3QgcmVxdWlyZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc291cmNlLCBpdCBjYW4gYmUgSW1hZ2VJbnB1dFN0cmVhbSBvciBvdGhlciBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElucHV0KE9iamVjdCBpbnB1dCkgeworICAgICAgICBzZXRJbnB1dChpbnB1dCwgZmFsc2UsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbnB1dCBzb3VyY2Ugb2JqZWN0IG9mIHRoaXMgSW1hZ2VSZWFkZXIsIG9yIHJldHVybnMgbnVsbC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCBzb3VyY2Ugb2JqZWN0IHN1Y2ggYXMgSW1hZ2VJbnB1dFN0cmVhbSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldElucHV0KCkgeworICAgICAgICByZXR1cm4gaW5wdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBpbnB1dCBzb3VyY2Ugc3VwcG9ydHMgb25seSBmb3J3YXJkIHJlYWRpbmcsIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBpbnB1dCBzb3VyY2Ugc3VwcG9ydHMgb25seSBmb3J3YXJkIHJlYWRpbmcsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTZWVrRm9yd2FyZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBzZWVrRm9yd2FyZE9ubHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IGlucHV0IHNvdXJjZSBhbGxvd3MgdG8gbWV0YWRhdGEgdG8gYmUgaWdub3JlZAorICAgICAqIGJ5IHBhc3NpbmcgdHJ1ZSBhcyB0aGUgaWdub3JlTWV0YWRhdGEgYXJndW1lbnQgdG8gdGhlIHNldElucHV0IG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBjdXJyZW50IGlucHV0IHNvdXJjZSBhbGxvd3MgdG8gbWV0YWRhdGEgdG8gYmUKKyAgICAgKiAgICAgICAgIGlnbm9yZWQgYnkgcGFzc2luZyB0cnVlIGFzIHRoZSBpZ25vcmVNZXRhZGF0YSBhcmd1bWVudCB0byB0aGUKKyAgICAgKiAgICAgICAgIHNldElucHV0IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yaW5nTWV0YWRhdGEoKSB7CisgICAgICAgIHJldHVybiBpZ25vcmVNZXRhZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHZhbGlkIGluZGV4IGZvciByZWFkaW5nIGFuIGltYWdlLCB0aHVtYm5haWwsIG9yIGltYWdlCisgICAgICogbWV0YWRhdGEuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSB2YWxpZCBpbmRleCBmb3IgcmVhZGluZyBhbiBpbWFnZSwgdGh1bWJuYWlsLCBvciBpbWFnZQorICAgICAqICAgICAgICAgbWV0YWRhdGEuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNaW5JbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIG1pbkluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGF2YWlsYWJsZSBsb2NhbGVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGF2YWlsYWJsZSBsb2NhbGVzLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gYXZhaWxhYmxlTG9jYWxlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2NhbGUgdG8gdGhpcyBJbWFnZVJlYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgTG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2FsZSBvZiB0aGlzIEltYWdlUmVhZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsZSBvZiB0aGlzIEltYWdlUmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgeworICAgICAgICByZXR1cm4gbG9jYWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBpbWFnZXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGlucHV0IHNvdXJjZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYWxsb3dTZWFyY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgd2hpY2ggaW5kaWNhdGVzIHdoYXQgYSBzZWFyY2ggaXMgcmVxdWlyZWQ7IGlmCisgICAgICogICAgICAgICAgICBmYWxzZSwgdGhlIHJlYWRlciBtYXkgcmV0dXJuIC0xIHdpdGhvdXQgc2VhcmNoaW5nLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBpbWFnZXMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TnVtSW1hZ2VzKGJvb2xlYW4gYWxsb3dTZWFyY2gpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpZHRoIG9mIHRoZSBzcGVjaWZpZWQgaW1hZ2UgaW4gaW5wdXQgc291cmNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHJldHVybiB0aGUgd2lkdGggaW4gcGl4ZWxzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFdpZHRoKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIHNwZWNpZmllZCBpbWFnZSBpbiBpbnB1dCBzb3VyY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZWlnaHQgaW4gcGl4ZWxzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEhlaWdodChpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzdG9yYWdlIGZvcm1hdCBvZiB0aGUgc3BlY2lmaWVkIGltYWdlIHBsYWNlcyBhbiBpbXBlZGltZW50CisgICAgICogb24gcmFuZG9tIHBpeGVscyBhY2Nlc3Mgb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzdG9yYWdlIGZvcm1hdCBvZiB0aGUgc3BlY2lmaWVkIGltYWdlIHBsYWNlcyBhbgorICAgICAqICAgICAgICAgaW1wZWRpbWVudCBvbiByYW5kb20gcGl4ZWxzIGFjY2VzcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JhbmRvbUFjY2Vzc0Vhc3koaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBmYWxzZTsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXNwZWN0IHJhdGlvICh3aWR0aCBkZXZpZGVkIGJ5IGhlaWdodCkgb2YgdGhlIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHJldHVybiB0aGUgYXNwZWN0IHJhdGlvIG9mIHRoZSBpbWFnZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEFzcGVjdFJhdGlvKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKGZsb2F0KWdldFdpZHRoKGltYWdlSW5kZXgpIC8gZ2V0SGVpZ2h0KGltYWdlSW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSW1hZ2VUeXBlU3BlY2lmaWVyIHdoaWNoIGluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogaW1hZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIEltYWdlVHlwZVNwZWNpZmllciBnZXRSYXdJbWFnZVR5cGUoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSXRlcmF0b3Igb2YgSW1hZ2VUeXBlU3BlY2lmaWVyIG9iamVjdHMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aAorICAgICAqIGltYWdlIHR5cGVzIHRoYXQgbWF5IGJlIHVzZWQgd2hlbiBkZWNvZGluZyBzcGVjaWZpZWQgaW1hZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIGFuIEl0ZXJhdG9yIG9mIEltYWdlVHlwZVNwZWNpZmllciBvYmplY3RzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSXRlcmF0b3I8SW1hZ2VUeXBlU3BlY2lmaWVyPiBnZXRJbWFnZVR5cGVzKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IEltYWdlUmVhZFBhcmFtIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZVJlYWRQYXJhbSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEltYWdlUmVhZFBhcmFtIGdldERlZmF1bHRSZWFkUGFyYW0oKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSUlPTWV0YWRhdGEgb2JqZWN0IGZvciB0aGlzIGlucHV0IHNvdXJjZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJSU9NZXRhZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IElJT01ldGFkYXRhIGdldFN0cmVhbU1ldGFkYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiBJSU9NZXRhZGF0YSBvYmplY3QgZm9yIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZGVzaXJlZCBtZXRhZGF0YSBmb3JtYXQgdG8gYmUgdXNlZCBpbiB0aGUgcmV0dXJuZWQKKyAgICAgKiAgICAgICAgICAgIElJT01ldGFkYXRhIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gbm9kZU5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgbm9kZSBuYW1lcyBvZiB0aGUgZG9jdW1lbnQuCisgICAgICogQHJldHVybiB0aGUgSUlPTWV0YWRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBJSU9NZXRhZGF0YSBnZXRTdHJlYW1NZXRhZGF0YShTdHJpbmcgZm9ybWF0TmFtZSwgU2V0PFN0cmluZz4gbm9kZU5hbWVzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaW1hZ2UgbWV0YWRhdGEgb2YgdGhlIHNwZWNpZmllZCBpbWFnZSBpbiBpbnB1dCBzb3VyY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBJSU9NZXRhZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IElJT01ldGFkYXRhIGdldEltYWdlTWV0YWRhdGEoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGltYWdlIG1ldGFkYXRhIG9mIHRoZSBzcGVjaWZpZWQgaW1hZ2UgaW5wdXQgc291cmNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHBhcmFtIGZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIG1ldGFkYXRhIGZvcm1hdCB0byBiZSB1c2VkIGluIHRoZSByZXR1cm5lZAorICAgICAqICAgICAgICAgICAgSUlPTWV0YWRhdGEgb2JqZWN0LgorICAgICAqIEBwYXJhbSBub2RlTmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBub2RlIG5hbWVzIHdoaWNoIGNhbiBiZSBjb250YWluZWQgaW4gdGhlIGRvY3VtZW50LgorICAgICAqIEByZXR1cm4gdGhlIElJT01ldGFkYXRhLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0SW1hZ2VNZXRhZGF0YShpbnQgaW1hZ2VJbmRleCwgU3RyaW5nIGZvcm1hdE5hbWUsIFNldDxTdHJpbmc+IG5vZGVOYW1lcykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBzcGVjaWZpZWQgaW1hZ2UgYW5kIHJldHVybnMgaXQgYXMgYSBCdWZmZXJlZEltYWdlIHVzaW5nIHRoZQorICAgICAqIGRlZmF1bHQgSW1hZ2VSZWFkUGFyYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSByZWFkKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZChpbWFnZUluZGV4LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgc3BlY2lmaWVkIGltYWdlIGFuZCByZXR1cm5zIGl0IGFzIGEgQnVmZmVyZWRJbWFnZSB1c2luZyB0aGUKKyAgICAgKiBzcGVjaWZpZWQgSW1hZ2VSZWFkUGFyYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRQYXJhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVmZmVyZWRJbWFnZSByZWFkKGludCBpbWFnZUluZGV4LCBJbWFnZVJlYWRQYXJhbSBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBpbWFnZSBhbmQgcmV0dXJucyBhbiBJSU9JbWFnZSB3aXRoIHRoaXMgaW1hZ2UsCisgICAgICogdGh1bWJuYWlscywgYW5kIG1ldGFkYXRhIGZvciB0aGlzIGltYWdlLCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogSW1hZ2VSZWFkUGFyYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRQYXJhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJSU9JbWFnZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIElJT0ltYWdlIHJlYWRBbGwoaW50IGltYWdlSW5kZXgsIEltYWdlUmVhZFBhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIEl0ZXJhdG9yIG9mIElJT0ltYWdlcyBmcm9tIHRoZSBpbnB1dCBzb3VyY2UuCisgICAgICogCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIEl0ZXJhdG9yIG9mIEltYWdlUmVhZFBhcmFtIG9iamVjdHMuCisgICAgICogQHJldHVybiB0aGUgaXRlcmF0b3Igb2YgSUlPSW1hZ2VzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8SUlPSW1hZ2U+IHJlYWRBbGwoSXRlcmF0b3I8PyBleHRlbmRzIEltYWdlUmVhZFBhcmFtPiBwYXJhbXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIHBsdWctaW4gc3VwcG9ydHMgcmVhZGluZyBhIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgcGx1Zy1pbiBzdXBwb3J0cyByZWFkaW5nIGEgUmFzdGVyLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVhZFJhc3RlcigpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIG5ldyBSYXN0ZXIgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSByYXcgcGl4ZWwgZGF0YSBmcm9tIHRoZQorICAgICAqIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkUGFyYW0uCisgICAgICogQHJldHVybiB0aGUgUmFzdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFzdGVyIHJlYWRSYXN0ZXIoaW50IGltYWdlSW5kZXgsIEltYWdlUmVhZFBhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlVuc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgaW1hZ2UgaGFzIHRpbGVzIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlJ3MgaW5kZXguCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIGltYWdlIGhhcyB0aWxlcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ltYWdlVGlsZWQoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBmYWxzZTsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGlsZSB3aWR0aCBpbiB0aGUgc3BlY2lmaWVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxlIHdpZHRoLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRpbGVXaWR0aChpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldFdpZHRoKGltYWdlSW5kZXgpOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aWxlIGhlaWdodCBpbiB0aGUgc3BlY2lmaWVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxlIGhlaWdodC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaWxlSGVpZ2h0KGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0SGVpZ2h0KGltYWdlSW5kZXgpOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSB0aWxlIGdyaWQgaW4gdGhlCisgICAgICogc3BlY2lmaWVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZSB0aWxlIGdyaWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VGlsZUdyaWRYT2Zmc2V0KGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gMDsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgdGlsZSBncmlkIGluIHRoZQorICAgICAqIHNwZWNpZmllZCBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlJ3MgaW5kZXguCisgICAgICogQHJldHVybiB0aGUgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlciBsZWZ0IGNvcm5lciBvZiB0aGUgdGlsZSBncmlkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRpbGVHcmlkWU9mZnNldChpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIDA7IC8vIGRlZgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSB0aWxlIHNwZWNpZmllZCBieSB0aGUgdGlsZVggYW5kIHRpbGVZIHBhcmFtZXRlcnMgb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGltYWdlIGFuZCByZXR1cm5zIGl0IGFzIGEgQnVmZmVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqIEBwYXJhbSB0aWxlWAorICAgICAqICAgICAgICAgICAgdGhlIFggaW5kZXggb2YgdGlsZS4KKyAgICAgKiBAcGFyYW0gdGlsZVkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGluZGV4IG9mIHRpbGUuCisgICAgICogQHJldHVybiB0aGUgQnVmZmVyZWRJbWFnZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2UgcmVhZFRpbGUoaW50IGltYWdlSW5kZXgsIGludCB0aWxlWCwgaW50IHRpbGVZKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgdGlsZSBzcGVjaWZpZWQgYnkgdGhlIHRpbGVYIGFuZCB0aWxlWSBwYXJhbWV0ZXJzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBpbWFnZSBhbmQgcmV0dXJucyBpdCBhcyBhIFJhc3Rlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqIEBwYXJhbSB0aWxlWAorICAgICAqICAgICAgICAgICAgdGhlIFggaW5kZXggb2YgdGlsZS4KKyAgICAgKiBAcGFyYW0gdGlsZVkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGluZGV4IG9mIHRpbGUuCisgICAgICogQHJldHVybiB0aGUgUmFzdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFzdGVyIHJlYWRUaWxlUmFzdGVyKGludCBpbWFnZUluZGV4LCBpbnQgdGlsZVgsIGludCB0aWxlWSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBpbWFnZSB1c2luZyB0aGUgc3BlY2lmaWVkIEltYWdlUmVhZFBhcmFtIGFuZCByZXR1cm5zCisgICAgICogaXQgYXMgYSBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkUGFyYW0uCisgICAgICogQHJldHVybiB0aGUgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFJlbmRlcmVkSW1hZ2UgcmVhZEFzUmVuZGVyZWRJbWFnZShpbnQgaW1hZ2VJbmRleCwgSW1hZ2VSZWFkUGFyYW0gcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZChpbWFnZUluZGV4LCBwYXJhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBpbWFnZSBmb3JtYXQgc3VwcG9ydGVkIGJ5IHRoaXMgcmVhZGVyIHN1cHBvcnRzCisgICAgICogdGh1bWJuYWlsIHByZXZpZXcgaW1hZ2VzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGltYWdlIGZvcm1hdCBzdXBwb3J0ZWQgYnkgdGhpcyByZWFkZXIgc3VwcG9ydHMKKyAgICAgKiAgICAgICAgIHRodW1ibmFpbCBwcmV2aWV3IGltYWdlcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlYWRlclN1cHBvcnRzVGh1bWJuYWlscygpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBpbWFnZSBoYXMgdGh1bWJuYWlscyBvciBub3QuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIGluZGV4LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBpbWFnZSBoYXMgdGh1bWJuYWlscywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNUaHVtYm5haWxzKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0TnVtVGh1bWJuYWlscyhpbWFnZUluZGV4KSA+IDA7IC8vIGRlZgorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiB0aHVtYm5haWxzIGZvciB0aGUgc3BlY2lmaWVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdGh1bWJuYWlscy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1UaHVtYm5haWxzKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gMDsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgd2lkdGggb2YgdGhlIHNwZWNpZmllZCB0aHVtYm5haWwgZm9yIHRoZSBzcGVjaWZpZWQgaW1hZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIGluZGV4LgorICAgICAqIEBwYXJhbSB0aHVtYm5haWxJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHRodW1ibmFpbCdzIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIHRodW1ibmFpbCB3aWR0aC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaHVtYm5haWxXaWR0aChpbnQgaW1hZ2VJbmRleCwgaW50IHRodW1ibmFpbEluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZFRodW1ibmFpbChpbWFnZUluZGV4LCB0aHVtYm5haWxJbmRleCkuZ2V0V2lkdGgoKTsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBzcGVjaWZpZWQgdGh1bWJuYWlsIGZvciB0aGUgc3BlY2lmaWVkIGltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcGFyYW0gdGh1bWJuYWlsSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aHVtYm5haWwncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aHVtYm5haWwgaGVpZ2h0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRodW1ibmFpbEhlaWdodChpbnQgaW1hZ2VJbmRleCwgaW50IHRodW1ibmFpbEluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZFRodW1ibmFpbChpbWFnZUluZGV4LCB0aHVtYm5haWxJbmRleCkuZ2V0SGVpZ2h0KCk7IC8vIGRlZgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSB0aHVtYm5haWwgaW1hZ2UgZm9yIHRoZSBzcGVjaWZpZWQgaW1hZ2UgYXMgYSBCdWZmZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHBhcmFtIHRodW1ibmFpbEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIHJlYWRUaHVtYm5haWwoaW50IGltYWdlSW5kZXgsIGludCB0aHVtYm5haWxJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCIpOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1ZXN0cyBhbiBhYm9ydCBvcGVyYXRpb24gZm9yIGN1cnJlbnQgcmVhZGluZyBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWJvcnQoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCBhIHJlcXVlc3QgdG8gYWJvcnQgdGhlIGN1cnJlbnQgcmVhZCBvcGVyYXRpb24gaGFzCisgICAgICogYmVlbiBtYWRlIHN1Y2Nlc3NmdWxseS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSByZXF1ZXN0IHRvIGFib3J0IHRoZSBjdXJyZW50IHJlYWQgb3BlcmF0aW9uIGhhcyBiZWVuCisgICAgICogICAgICAgICBtYWRlIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGFib3J0UmVxdWVzdGVkKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgYWxsIHByZXZpb3VzIGFib3J0IHJlcXVlc3QsIGFuZCBhYm9ydFJlcXVlc3RlZCByZXR1cm5zIGZhbHNlIGFmdGVyCisgICAgICogY2FsbGluZyB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjbGVhckFib3J0UmVxdWVzdCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgSUlPUmVhZFdhcm5pbmdMaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9SZWFkV2FybmluZ0xpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZElJT1JlYWRXYXJuaW5nTGlzdGVuZXIoSUlPUmVhZFdhcm5pbmdMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgSUlPUmVhZFdhcm5pbmdMaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9SZWFkV2FybmluZ0xpc3RlbmVyIHRvIGJlIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSUlPUmVhZFdhcm5pbmdMaXN0ZW5lcihJSU9SZWFkV2FybmluZ0xpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFdhcm5pbmdMaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsSUlPUmVhZFdhcm5pbmdMaXN0ZW5lcnMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyKElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lciB0byBiZSByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUlJT1JlYWRQcm9ncmVzc0xpc3RlbmVyKElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgcmVnaXN0ZXJlZCBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsSUlPUmVhZFByb2dyZXNzTGlzdGVuZXJzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBJSU9SZWFkVXBkYXRlTGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICogICAgICAgICAgICB0aGUgSUlPUmVhZFVwZGF0ZUxpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZElJT1JlYWRVcGRhdGVMaXN0ZW5lcihJSU9SZWFkVXBkYXRlTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIElJT1JlYWRVcGRhdGVMaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJSU9SZWFkVXBkYXRlTGlzdGVuZXIgdG8gYmUgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJSU9SZWFkVXBkYXRlTGlzdGVuZXIoSUlPUmVhZFVwZGF0ZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgcmVnaXN0ZXJlZCBJSU9SZWFkVXBkYXRlTGlzdGVuZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFsbElJT1JlYWRVcGRhdGVMaXN0ZW5lcnMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgc3RhcnQgb2YgYW4gc2VxdWVuY2Ugb2YgaW1hZ2UgcmVhZHMgYnkgY2FsbGluZyB0aGUKKyAgICAgKiBzZXF1ZW5jZVN0YXJ0ZWQgbWV0aG9kIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWluSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIGluZGV4LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NTZXF1ZW5jZVN0YXJ0ZWQoaW50IG1pbkluZGV4KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgY29tcGxldGlvbiBvZiBhbiBzZXF1ZW5jZSBvZiBpbWFnZSByZWFkcyBieSBjYWxsaW5nCisgICAgICogc2VxdWVuY2VDb21wbGV0ZSBtZXRob2Qgb24gYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFByb2dyZXNzTGlzdGVuZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NTZXF1ZW5jZUNvbXBsZXRlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgdGhlIHN0YXJ0IG9mIGFuIGltYWdlIHJlYWQgYnkgY2FsbGluZyB0aGUgaW1hZ2VTdGFydGVkIG1ldGhvZAorICAgICAqIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NJbWFnZVN0YXJ0ZWQoaW50IGltYWdlSW5kZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSBjdXJyZW50IHBlcmNlbnRhZ2Ugb2YgaW1hZ2UgY29tcGxldGlvbiBieSBjYWxsaW5nIHRoZQorICAgICAqIGltYWdlUHJvZ3Jlc3MgbWV0aG9kIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGVyY2VudGFnZURvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJjZW50YWdlIGRvbmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0ltYWdlUHJvZ3Jlc3MoZmxvYXQgcGVyY2VudGFnZURvbmUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIGltYWdlIGNvbXBsZXRpb24gYnkgY2FsbGluZyB0aGUgaW1hZ2VDb21wbGV0ZSBtZXRob2Qgb24gYWxsCisgICAgICogcmVnaXN0ZXJlZCBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0ltYWdlQ29tcGxldGUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgc3RhcnQgb2YgYSB0aHVtYm5haWwgcmVhZCBieSBjYWxsaW5nIHRoZSB0aHVtYm5haWxTdGFydGVkCisgICAgICogbWV0aG9kIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqIEBwYXJhbSB0aHVtYm5haWxJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHRodW1ibmFpbCBpbmRleC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzVGh1bWJuYWlsU3RhcnRlZChpbnQgaW1hZ2VJbmRleCwgaW50IHRodW1ibmFpbEluZGV4KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgY3VycmVudCBwZXJjZW50YWdlIG9mIHRodW1ibmFpbCBjb21wbGV0aW9uIGJ5IGNhbGxpbmcgdGhlCisgICAgICogdGh1bWJuYWlsUHJvZ3Jlc3MgbWV0aG9kIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGVyY2VudGFnZURvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJjZW50YWdlIGRvbmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1RodW1ibmFpbFByb2dyZXNzKGZsb2F0IHBlcmNlbnRhZ2VEb25lKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgY29tcGxldGlvbiBvZiBhIHRodW1ibmFpbCByZWFkIGJ5IGNhbGxpbmcgdGhlCisgICAgICogdGh1bWJuYWlsQ29tcGxldGUgbWV0aG9kIG9uIGFsbCByZWdpc3RlcmVkIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzVGh1bWJuYWlsQ29tcGxldGUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBhIHJlYWQgYWJvcnRlZCBldmVudCBieSBjYWxsaW5nIHRoZSByZWFkQWJvcnRlZCBtZXRob2Qgb24gYWxsCisgICAgICogcmVnaXN0ZXJlZCBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1JlYWRBYm9ydGVkKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgdGhlIGJlZ2lubmluZyBvZiBhIHByb2dyZXNzaXZlIHBhc3MgYnkgY2FsbGluZyB0aGUgcGFzc1N0YXJ0ZWQKKyAgICAgKiBtZXRob2Qgb24gYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFVwZGF0ZUxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGhlSW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0byBiZSB1cGRhdGVkLgorICAgICAqIEBwYXJhbSBwYXNzCisgICAgICogICAgICAgICAgICB0aGUgY3VycmVudCBwYXNzIGluZGV4LgorICAgICAqIEBwYXJhbSBtaW5QYXNzCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBwYXNzIGluZGV4LgorICAgICAqIEBwYXJhbSBtYXhQYXNzCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBwYXNzIGluZGV4LgorICAgICAqIEBwYXJhbSBtaW5YCisgICAgICogICAgICAgICAgICB0aGUgWCBjb29yZGluYXRlIG9mIG9mIHRoZSB1cHBlciBsZWZ0IHBpeGVsLgorICAgICAqIEBwYXJhbSBtaW5ZCisgICAgICogICAgICAgICAgICB0aGUgWSBjb29yZGluYXRlIG9mIG9mIHRoZSB1cHBlciBsZWZ0IHBpeGVsLgorICAgICAqIEBwYXJhbSBwZXJpb2RYCisgICAgICogICAgICAgICAgICB0aGUgaG9yaXpvbnRhbCBzZXBhcmF0aW9uIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBwZXJpb2RZCisgICAgICogICAgICAgICAgICB0aGUgdmVydGljYWwgc2VwYXJhdGlvbiBiZXR3ZWVuIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYmFuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYWZmZWN0ZWQgYmFuZHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1Bhc3NTdGFydGVkKEJ1ZmZlcmVkSW1hZ2UgdGhlSW1hZ2UsIGludCBwYXNzLCBpbnQgbWluUGFzcywgaW50IG1heFBhc3MsCisgICAgICAgICAgICBpbnQgbWluWCwgaW50IG1pblksIGludCBwZXJpb2RYLCBpbnQgcGVyaW9kWSwgaW50W10gYmFuZHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSB1cGRhdGUgb2YgYSBzZXQgb2Ygc2FtcGxlcyBieSBjYWxsaW5nIHRoZSBpbWFnZVVwZGF0ZQorICAgICAqIG1ldGhvZCBvbiBhbGwgcmVnaXN0ZXJlZCBJSU9SZWFkVXBkYXRlTGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aGVJbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIG1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIG1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBwZXJpb2RYCisgICAgICogICAgICAgICAgICB0aGUgaG9yaXpvbnRhbCBzZXBhcmF0aW9uIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBwZXJpb2RZCisgICAgICogICAgICAgICAgICB0aGUgdmVydGljYWwgc2VwYXJhdGlvbiBiZXR3ZWVuIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYmFuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYWZmZWN0ZWQgYmFuZHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0ltYWdlVXBkYXRlKEJ1ZmZlcmVkSW1hZ2UgdGhlSW1hZ2UsIGludCBtaW5YLCBpbnQgbWluWSwgaW50IHdpZHRoLAorICAgICAgICAgICAgaW50IGhlaWdodCwgaW50IHBlcmlvZFgsIGludCBwZXJpb2RZLCBpbnRbXSBiYW5kcykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgdGhlIGVuZCBvZiBhIHByb2dyZXNzaXZlIHBhc3MgYnkgY2FsbGluZyBwYXNzQ29tcGxldGUgbWV0aG9kIG9mCisgICAgICogcmVnaXN0ZXJlZCBJSU9SZWFkVXBkYXRlTGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aGVJbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHRvIGJlIHVwZGF0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1Bhc3NDb21wbGV0ZShCdWZmZXJlZEltYWdlIHRoZUltYWdlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgYmVnaW5uaW5nIG9mIGEgdGh1bWJuYWlsIHByb2dyZXNzaXZlIHBhc3MgYnkgY2FsbGluZyB0aGUKKyAgICAgKiB0aHVtYm5haWxQYXNzU3RhcnRlZCBtZXRob2Qgb24gYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFVwZGF0ZUxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGhlVGh1bWJuYWlsCisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIHBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBjdXJyZW50IHBhc3MgaW5kZXguCisgICAgICogQHBhcmFtIG1pblBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIHBhc3MgaW5kZXguCisgICAgICogQHBhcmFtIG1heFBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIHBhc3MgaW5kZXguCisgICAgICogQHBhcmFtIG1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIG1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIHBlcmlvZFgKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Jpem9udGFsIHNlcGFyYXRpb24gYmV0d2VlbiBwaXhlbHMuCisgICAgICogQHBhcmFtIHBlcmlvZFkKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJ0aWNhbCBzZXBhcmF0aW9uIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBhZmZlY3RlZCBiYW5kcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzVGh1bWJuYWlsUGFzc1N0YXJ0ZWQoQnVmZmVyZWRJbWFnZSB0aGVUaHVtYm5haWwsIGludCBwYXNzLCBpbnQgbWluUGFzcywKKyAgICAgICAgICAgIGludCBtYXhQYXNzLCBpbnQgbWluWCwgaW50IG1pblksIGludCBwZXJpb2RYLCBpbnQgcGVyaW9kWSwgaW50W10gYmFuZHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSB1cGRhdGUgb2YgYSBzZXQgb2Ygc2FtcGxlcyBpbiBhIHRodW1ibmFpbCBpbWFnZSBieSBjYWxsaW5nCisgICAgICogdGhlIHRodW1ibmFpbFVwZGF0ZSBtZXRob2Qgb24gYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFVwZGF0ZUxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGhlVGh1bWJuYWlsCisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIG1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIG1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyIGxlZnQgcGl4ZWwuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgdG90YWwgd2lkdGggb2YgdGhlIHVwZGF0ZWQgYXJlYS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgdG90YWwgaGVpZ2h0IG9mIHRoZSB1cGRhdGVkIGFyZWEuCisgICAgICogQHBhcmFtIHBlcmlvZFgKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Jpem9udGFsIHNlcGFyYXRpb24gYmV0d2VlbiBwaXhlbHMuCisgICAgICogQHBhcmFtIHBlcmlvZFkKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJ0aWNhbCBzZXBhcmF0aW9uIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiYW5kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBhZmZlY3RlZCBiYW5kcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzVGh1bWJuYWlsVXBkYXRlKEJ1ZmZlcmVkSW1hZ2UgdGhlVGh1bWJuYWlsLCBpbnQgbWluWCwgaW50IG1pblksCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBwZXJpb2RYLCBpbnQgcGVyaW9kWSwgaW50W10gYmFuZHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSBlbmQgb2YgYSB0aHVtYm5haWwgcHJvZ3Jlc3NpdmUgcGFzcyBieSBjYWxsaW5nIHRoZQorICAgICAqIHRodW1ibmFpbFBhc3NDb21wbGV0ZSBtZXRob2Qgb24gYWxsIHJlZ2lzdGVyZWQgSUlPUmVhZFVwZGF0ZUxpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGhlVGh1bWJuYWlsCisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIHRvIGJlIHVwZGF0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1RodW1ibmFpbFBhc3NDb21wbGV0ZShCdWZmZXJlZEltYWdlIHRoZVRodW1ibmFpbCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSB3YXJuaW5nIG1lc3NhZ2UgYnkgY2FsbGluZyB3YXJuaW5nT2NjdXJyZWQgbWV0aG9kIG9mCisgICAgICogcmVnaXN0ZXJlZCBJSU9SZWFkV2FybmluZ0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd2FybmluZworICAgICAqICAgICAgICAgICAgdGhlIHdhcm5pbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1dhcm5pbmdPY2N1cnJlZChTdHJpbmcgd2FybmluZykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSB3YXJuaW5nIGJ5IGNhbGxpbmcgdGhlIHdhcm5pbmdPY2N1cnJlZCBtZXRob2Qgb2Ygb24gYWxsCisgICAgICogcmVnaXN0ZXJlZCBJSU9SZWFkV2FybmluZ0xpc3RlbmVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmFzZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYXNlIG5hbWUgb2YgUmVzb3VyY2VCdW5kbGVzLgorICAgICAqIEBwYXJhbSBrZXl3b3JkCisgICAgICogICAgICAgICAgICB0aGUga2V5d29yZCB0byBpbmRleCB0aGUgd2FybmluZyBhbW9uZyBSZXNvdXJjZUJ1bmRsZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1dhcm5pbmdPY2N1cnJlZChTdHJpbmcgYmFzZU5hbWUsIFN0cmluZyBrZXl3b3JkKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIEltYWdlUmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICAvLyBkZWYKKyAgICAgICAgc2V0SW5wdXQobnVsbCwgZmFsc2UpOworICAgICAgICBzZXRMb2NhbGUobnVsbCk7CisgICAgICAgIHJlbW92ZUFsbElJT1JlYWRVcGRhdGVMaXN0ZW5lcnMoKTsKKyAgICAgICAgcmVtb3ZlQWxsSUlPUmVhZFdhcm5pbmdMaXN0ZW5lcnMoKTsKKyAgICAgICAgcmVtb3ZlQWxsSUlPUmVhZFByb2dyZXNzTGlzdGVuZXJzKCk7CisgICAgICAgIGNsZWFyQWJvcnRSZXF1ZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGlzcG9zZXMgb2YgYW55IHJlc291cmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICAvLyBkbyBub3RoaW5nIGJ5IGRlZgorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHJlZ2lvbiBvZiBzb3VyY2UgaW1hZ2UgdGhhdCBzaG91bGQgYmUgcmVhZCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB3aWR0aCwgaGVpZ2h0IGFuZCBJbWFnZVJlYWRQYXJhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRQYXJhbSBvYmplY3QsIG9yIG51bGwuCisgICAgICogQHBhcmFtIHNyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGltYWdlJ3Mgd2lkdGguCisgICAgICogQHBhcmFtIHNyY0hlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBpbWFnZSdzIGhlaWdodC4KKyAgICAgKiBAcmV0dXJuIHRoZSBSZWN0YW5nbGUgb2Ygc291cmNlIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIFJlY3RhbmdsZSBnZXRTb3VyY2VSZWdpb24oSW1hZ2VSZWFkUGFyYW0gcGFyYW0sIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB0aGUgc3BlY2lmaWVkIHNvdXJjZSByZWdpb24gYW5kIHRoZSBzcGVjaWZpZWQgZGVzdGluYXRpb24gcmVnaW9uCisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSBzb3VyY2UgaW1hZ2UsIGFuIG9wdGlvbmFsCisgICAgICogZGVzdGluYXRpb24gaW1hZ2UsIGFuZCBhbiBJbWFnZVJlYWRQYXJhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBhbiBJbWFnZVJlYWRQYXJhbSBvYmplY3QsIG9yIG51bGwuCisgICAgICogQHBhcmFtIHNyY1dpZHRoCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGltYWdlJ3Mgd2lkdGguCisgICAgICogQHBhcmFtIHNyY0hlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBpbWFnZSdzIGhlaWdodC4KKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyAgICAgKiBAcGFyYW0gc3JjUmVnaW9uCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHJlZ2lvbi4KKyAgICAgKiBAcGFyYW0gZGVzdFJlZ2lvbgorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgY29tcHV0ZVJlZ2lvbnMoSW1hZ2VSZWFkUGFyYW0gcGFyYW0sIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwKKyAgICAgICAgICAgIEJ1ZmZlcmVkSW1hZ2UgaW1hZ2UsIFJlY3RhbmdsZSBzcmNSZWdpb24sIFJlY3RhbmdsZSBkZXN0UmVnaW9uKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB0aGUgdmFsaWRpdHkgb2YgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gYmFuZCBhbmQgaXMgY2FsbGVkIHdoZW4KKyAgICAgKiB0aGUgcmVhZGVyIGtub3dzIHRoZSBudW1iZXIgb2YgYmFuZHMgb2YgdGhlIHNvdXJjZSBpbWFnZSBhbmQgdGhlIG51bWJlcgorICAgICAqIG9mIGJhbmRzIG9mIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRQYXJhbSBmb3IgcmVhZGluZyB0aGUgSW1hZ2UuCisgICAgICogQHBhcmFtIG51bVNyY0JhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZSBzb3VyY2UuCisgICAgICogQHBhcmFtIG51bURzdEJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZSBkZXN0aW5hdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgY2hlY2tSZWFkUGFyYW1CYW5kU2V0dGluZ3MoSW1hZ2VSZWFkUGFyYW0gcGFyYW0sIGludCBudW1TcmNCYW5kcywKKyAgICAgICAgICAgIGludCBudW1Ec3RCYW5kcykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZXN0aW5hdGlvbiBpbWFnZSB3aGVyZSB0aGUgZGVjb2RlZCBkYXRhIGlzIHdyaXR0ZW4uCisgICAgICogCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkUGFyYW0uCisgICAgICogQHBhcmFtIGltYWdlVHlwZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBpdGVyYXRvciBvZiBJbWFnZVR5cGVTcGVjaWZpZXIgb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgYmVpbmcgZGVjb2RlZC4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZSBiZWluZyBkZWNvZGVkLgorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2Ugd2hlcmUgZGVjb2RlZCBwaXhlbHMgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgSUlPRXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZSBpcyBubyBzdWl0YWJsZQorICAgICAqICAgICAgICAgICAgIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIEJ1ZmZlcmVkSW1hZ2UgZ2V0RGVzdGluYXRpb24oSW1hZ2VSZWFkUGFyYW0gcGFyYW0sCisgICAgICAgICAgICBJdGVyYXRvcjxJbWFnZVR5cGVTcGVjaWZpZXI+IGltYWdlVHlwZXMsIGludCB3aWR0aCwgaW50IGhlaWdodCkgdGhyb3dzIElJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL0ltYWdlVHJhbnNjb2Rlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VUcmFuc2NvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjMyZDg5MAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL0ltYWdlVHJhbnNjb2Rlci5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLm1ldGFkYXRhLklJT01ldGFkYXRhOworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VUeXBlU3BlY2lmaWVyOworCisvKioKKyAqIFRoZSBJbWFnZVRyYW5zY29kZXIgaW50ZXJmYWNlIGlzIHRvIGJlIGltcGxlbWVudGVkIGJ5IGNsYXNzZXMgdGhhdCBwZXJmb3JtCisgKiBpbWFnZSB0cmFuc2NvZGluZyBvcGVyYXRpb25zLCB0aGF0IGlzLCB0YWtlIGltYWdlcyB3cml0dGVuIGluIG9uZSBmb3JtYXQgYW5kCisgKiB3cml0ZSB0aGVtIGluIGFub3RoZXIgZm9ybWF0IHVzaW5nIHJlYWQvd3JpdGUgb3BlcmF0aW9ucy4gU29tZSBpbWFnZSBkYXRhIGNhbgorICogYmUgbG9zdCBpbiBzdWNoIHByb2Nlc3Nlcy4gVGhlIEltYWdlVHJhbnNjb2RlciBpbnRlcmZhY2UgY29udmVydHMgbWV0YWRhdGEKKyAqIG9iamVjdHMgKElJT01ldGFkYXRhKSBvZiBJbWFnZVJlYWRlciB0byBhcHByb3ByaWF0ZSBtZXRhZGF0YSBvYmplY3QgZm9yCisgKiBJbWFnZVdyaXRlci4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSW1hZ2VUcmFuc2NvZGVyIHsKKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgSUlPTWV0YWRhdGEgb2JqZWN0IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBJbWFnZVdyaXRlUGFyYW0gZm9yIG9idGFpbmluZyB3cml0ZXIncyBtZXRhZGF0YSBzdHJ1Y3R1cmUuCisgICAgICogCisgICAgICogQHBhcmFtIGluRGF0YQorICAgICAqICAgICAgICAgICAgdGhlIElJT01ldGFkYXRhLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVQYXJhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJSU9NZXRhZGF0YSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBJSU9NZXRhZGF0YSBjb252ZXJ0U3RyZWFtTWV0YWRhdGEoSUlPTWV0YWRhdGEgaW5EYXRhLCBJbWFnZVdyaXRlUGFyYW0gcGFyYW0pOworCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBJSU9NZXRhZGF0YSBvYmplY3QgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIEltYWdlV3JpdGVQYXJhbSBmb3Igb2J0YWluaW5nIHdyaXRlcidzIG1ldGFkYXRhIHN0cnVjdHVyZSBhbmQKKyAgICAgKiBJbWFnZVR5cGVTcGVjaWZpZXIgb2JqZWN0IGZvciBvYnRhaW5pbmcgdGhlIGxheW91dCBhbmQgY29sb3IgaW5mb3JtYXRpb24KKyAgICAgKiBvZiB0aGUgaW1hZ2UgZm9yIHRoaXMgbWV0YWRhdGEuCisgICAgICogCisgICAgICogQHBhcmFtIGluRGF0YQorICAgICAqICAgICAgICAgICAgdGhlIElJT01ldGFkYXRhLgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZVBhcmFtLgorICAgICAqIEByZXR1cm4gdGhlIElJT01ldGFkYXRhLCBvciBudWxsLgorICAgICAqLworICAgIElJT01ldGFkYXRhIGNvbnZlcnRJbWFnZU1ldGFkYXRhKElJT01ldGFkYXRhIGluRGF0YSwgSW1hZ2VUeXBlU3BlY2lmaWVyIGltYWdlVHlwZSwKKyAgICAgICAgICAgIEltYWdlV3JpdGVQYXJhbSBwYXJhbSk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVR5cGVTcGVjaWZpZXIuamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL0ltYWdlVHlwZVNwZWNpZmllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwNWIxYzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVR5cGVTcGVjaWZpZXIuamF2YQpAQCAtMCwwICsxLDM0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2VpbzsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuU2FtcGxlTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CisKKy8qKgorICogVGhlIEltYWdlVHlwZVNwZWNpZmllciBjbGFzcyBwZXJmb3JtcyBjb252ZXJzaW9uIG9wZXJhdGlvbnMgb24gdGhlCisgKiBTYW1wbGVNb2RlbCBhbmQgdGhlIENvbG9yTW9kZWwgb2YgYW4gaW1hZ2UuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSW1hZ2VUeXBlU3BlY2lmaWVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb2xvck1vZGVsIG9mIHRoaXMgSW1hZ2VUeXBlU3BlY2lmaWVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBDb2xvck1vZGVsIGNvbG9yTW9kZWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU2FtcGxlTW9kZWwgb2YgdGhpcyBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlVHlwZVNwZWNpZmllciB3aXRoIHRoZSBzcGVjaWZpZWQgQ29sb3JNb2RlbCBhbmQKKyAgICAgKiBTYW1wbGVNb2RlbCBvYmplY3RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvck1vZGVsCisgICAgICogICAgICAgICAgICB0aGUgQ29sb3JNb2RlbC4KKyAgICAgKiBAcGFyYW0gc2FtcGxlTW9kZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VUeXBlU3BlY2lmaWVyKENvbG9yTW9kZWwgY29sb3JNb2RlbCwgU2FtcGxlTW9kZWwgc2FtcGxlTW9kZWwpIHsKKyAgICAgICAgaWYgKGNvbG9yTW9kZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY29sb3IgbW9kZWwgc2hvdWxkIG5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNhbXBsZU1vZGVsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNhbXBsZSBtb2RlbCBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWNvbG9yTW9kZWwuaXNDb21wYXRpYmxlU2FtcGxlTW9kZWwoc2FtcGxlTW9kZWwpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjb2xvciBhbmQgc2FtcGxlIG1vZGVscyBhcmUgbm90IGNvbXBhdGlibGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY29sb3JNb2RlbCA9IGNvbG9yTW9kZWw7CisgICAgICAgIHRoaXMuc2FtcGxlTW9kZWwgPSBzYW1wbGVNb2RlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VUeXBlU3BlY2lmaWVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVuZGVyZWRJbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmVkSW1hZ2UuCisgICAgICovCisgICAgcHVibGljIEltYWdlVHlwZVNwZWNpZmllcihSZW5kZXJlZEltYWdlIHJlbmRlcmVkSW1hZ2UpIHsKKyAgICAgICAgaWYgKHJlbmRlcmVkSW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW1hZ2Ugc2hvdWxkIG5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb2xvck1vZGVsID0gcmVuZGVyZWRJbWFnZS5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIHRoaXMuc2FtcGxlTW9kZWwgPSByZW5kZXJlZEltYWdlLmdldFNhbXBsZU1vZGVsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBJbWFnZVR5cGVTcGVjaWZpZXIgd2l0aCB0aGUgc3BlY2lmaWVkIERpcmVjdENvbG9yTW9kZWwgYW5kIGEKKyAgICAgKiBwYWNrZWQgU2FtcGxlTW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9yU3BhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvclNwYWNlLgorICAgICAqIEBwYXJhbSByZWRNYXNrCisgICAgICogICAgICAgICAgICB0aGUgcmVkIG1hc2suCisgICAgICogQHBhcmFtIGdyZWVuTWFzaworICAgICAqICAgICAgICAgICAgdGhlIGdyZWVuIG1hc2suCisgICAgICogQHBhcmFtIGJsdWVNYXNrCisgICAgICogICAgICAgICAgICB0aGUgYmx1ZSBtYXNrLgorICAgICAqIEBwYXJhbSBhbHBoYU1hc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbHBoYSBtYXNrLgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2ZlciB0eXBlLgorICAgICAqIEBwYXJhbSBpc0FscGhhUHJlbXVsdGlwbGllZAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBpbmRpY2F0ZXMgaWYgdGhlIGNvbG9yIGNoYW5uZWwgaXMgcHJlLW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIGJ5IGFscGhhLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEltYWdlVHlwZVNwZWNpZmllciBjcmVhdGVQYWNrZWQoQ29sb3JTcGFjZSBjb2xvclNwYWNlLCBpbnQgcmVkTWFzaywKKyAgICAgICAgICAgIGludCBncmVlbk1hc2ssIGludCBibHVlTWFzaywgaW50IGFscGhhTWFzaywgaW50IHRyYW5zZmVyVHlwZSwKKyAgICAgICAgICAgIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gSW1hZ2VUeXBlU3BlY2lmaWVyIHdpdGggc3BlY2lmaWVkIENvbXBvbmVudENvbG9yTW9kZWwgYW5kIGEKKyAgICAgKiBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbG9yU3BhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2xvclNwYWNlLgorICAgICAqIEBwYXJhbSBiYW5kT2Zmc2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJhbmQgb2Zmc2V0cy4KKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUuCisgICAgICogQHBhcmFtIGhhc0FscGhhCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGluZGljYXRlcyBpZiBhbHBoYSBjaGFubmVsIGlzIG5lZWRlZC4KKyAgICAgKiBAcGFyYW0gaXNBbHBoYVByZW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW5kaWNhdGVzIGlmIHRoZSBjb2xvciBjaGFubmVsIGlzIHByZS1tdWx0aXBsaWVkCisgICAgICogICAgICAgICAgICBieSBhbHBoYS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbWFnZVR5cGVTcGVjaWZpZXIgY3JlYXRlSW50ZXJsZWF2ZWQoQ29sb3JTcGFjZSBjb2xvclNwYWNlLCBpbnRbXSBiYW5kT2Zmc2V0cywKKyAgICAgICAgICAgIGludCBkYXRhVHlwZSwgYm9vbGVhbiBoYXNBbHBoYSwgYm9vbGVhbiBpc0FscGhhUHJlbXVsdGlwbGllZCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEltYWdlVHlwZVNwZWNpZmllciBmb3IgYSBpbWFnZSB3aXRoIGEgQmFuZGVkU2FtcGxlTW9kZWwgYW5kIGEKKyAgICAgKiBDb21wb25lbnRDb2xvck1vZGVsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2xvclNwYWNlCisgICAgICogICAgICAgICAgICB0aGUgQ29sb3JTcGFjZS4KKyAgICAgKiBAcGFyYW0gYmFua0luZGljZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYW5rIGluZGljZXMuCisgICAgICogQHBhcmFtIGJhbmRPZmZzZXRzCisgICAgICogICAgICAgICAgICB0aGUgYmFuZCBvZmZzZXRzLgorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZS4KKyAgICAgKiBAcGFyYW0gaGFzQWxwaGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW5kaWNhdGVzIGEgcHJlc2VuY2Ugb2YgYWxwaGEgY2hhbm5lbC4KKyAgICAgKiBAcGFyYW0gaXNBbHBoYVByZW11bHRpcGxpZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IGNvbG9yIGNoYW5uZWwgaXMgYWxwaGEKKyAgICAgKiAgICAgICAgICAgIHByZS1tdWx0aXBsaWVkLgorICAgICAqIEByZXR1cm4gdGhlIGltYWdlIHR5cGUgc3BlY2lmaWVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbWFnZVR5cGVTcGVjaWZpZXIgY3JlYXRlQmFuZGVkKENvbG9yU3BhY2UgY29sb3JTcGFjZSwgaW50W10gYmFua0luZGljZXMsCisgICAgICAgICAgICBpbnRbXSBiYW5kT2Zmc2V0cywgaW50IGRhdGFUeXBlLCBib29sZWFuIGhhc0FscGhhLCBib29sZWFuIGlzQWxwaGFQcmVtdWx0aXBsaWVkKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgSW1hZ2VUeXBlU3BlY2lmaWVyIGZvciBhIGdyYXlzY2FsZSBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHBlciBncmF5IHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZS4KKyAgICAgKiBAcGFyYW0gaXNTaWduZWQKKyAgICAgKiAgICAgICAgICAgIGEgc2lnbmVkIGZsYWcuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VUeXBlU3BlY2lmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VUeXBlU3BlY2lmaWVyIGNyZWF0ZUdyYXlzY2FsZShpbnQgYml0cywgaW50IGRhdGFUeXBlLCBib29sZWFuIGlzU2lnbmVkKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgSW1hZ2VUeXBlU3BlY2lmaWVyIGZvciBhIGdyYXlzY2FsZSBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHBlciBncmF5IHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZS4KKyAgICAgKiBAcGFyYW0gaXNTaWduZWQKKyAgICAgKiAgICAgICAgICAgIGEgc2lnbmVkIGZsYWcuCisgICAgICogQHBhcmFtIGlzQWxwaGFQcmVtdWx0aXBsaWVkCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGluZGljYXRlcyBpZiBjb2xvciBjaGFubmVsIGlzIHByZS1tdWx0aXBsaWVkIGJ5CisgICAgICogICAgICAgICAgICBhbHBoYSwgb3Igbm90LgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEltYWdlVHlwZVNwZWNpZmllciBjcmVhdGVHcmF5c2NhbGUoaW50IGJpdHMsIGludCBkYXRhVHlwZSwgYm9vbGVhbiBpc1NpZ25lZCwKKyAgICAgICAgICAgIGJvb2xlYW4gaXNBbHBoYVByZW11bHRpcGxpZWQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBJbWFnZVR5cGVTcGVjaWZpZXIgd2l0aCB0aGUgaW5kZXhlZCBpbWFnZSBmb3JtYXQuCisgICAgICogCisgICAgICogQHBhcmFtIHJlZExVVAorICAgICAqICAgICAgICAgICAgdGhlIHJlZCB2YWx1ZXMgb2YgaW5kaWNlcy4KKyAgICAgKiBAcGFyYW0gZ3JlZW5MVVQKKyAgICAgKiAgICAgICAgICAgIHRoZSBncmVlbiB2YWx1ZXMgb2YgaW5kaWNlcy4KKyAgICAgKiBAcGFyYW0gYmx1ZUxVVAorICAgICAqICAgICAgICAgICAgdGhlIGJsdWUgdmFsdWVzIG9mIGluZGljZXMuCisgICAgICogQHBhcmFtIGFscGhhTFVUCisgICAgICogICAgICAgICAgICB0aGUgYWxwaGEgdmFsdWVzIG9mIGluZGljZXMuCisgICAgICogQHBhcmFtIGJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaXRzIG51bWJlciBmb3IgZWFjaCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZGF0YVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VUeXBlU3BlY2lmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VUeXBlU3BlY2lmaWVyIGNyZWF0ZUluZGV4ZWQoYnl0ZVtdIHJlZExVVCwgYnl0ZVtdIGdyZWVuTFVULCBieXRlW10gYmx1ZUxVVCwKKyAgICAgICAgICAgIGJ5dGVbXSBhbHBoYUxVVCwgaW50IGJpdHMsIGludCBkYXRhVHlwZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgSW1hZ2VUeXBlU3BlY2lmaWVyIGZyb20gdGhlIHNwZWNpZmllZCBidWZmZXJlZCBpbWFnZSB0eXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBidWZmZXJlZEltYWdlVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlcmVkIGltYWdlIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VUeXBlU3BlY2lmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VUeXBlU3BlY2lmaWVyIGNyZWF0ZUZyb21CdWZmZXJlZEltYWdlVHlwZShpbnQgYnVmZmVyZWRJbWFnZVR5cGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIEltYWdlVHlwZVNwZWNpZmllciBmcm9tIHRoZSBzcGVjaWZpZWQgUmVuZGVyZWRJbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZW5kZXJlZEltYWdlLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEltYWdlVHlwZVNwZWNpZmllciBjcmVhdGVGcm9tUmVuZGVyZWRJbWFnZShSZW5kZXJlZEltYWdlIGltYWdlKSB7CisgICAgICAgIGlmIChudWxsID09IGltYWdlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbWFnZSBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEltYWdlVHlwZVNwZWNpZmllcihpbWFnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQnVmZmVyZWRJbWFnZSB0eXBlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEJ1ZmZlcmVkSW1hZ2UgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEJ1ZmZlcmVkSW1hZ2VUeXBlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1Db21wb25lbnRzKCkgeworICAgICAgICByZXR1cm4gY29sb3JNb2RlbC5nZXROdW1Db21wb25lbnRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJhbmRzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBiYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE51bUJhbmRzKCkgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWwuZ2V0TnVtQmFuZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBwZXIgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiYW5kCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgYmFuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBwZXIgdGhlIHNwZWNpZmllZCBiYW5kLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Qml0c1BlckJhbmQoaW50IGJhbmQpIHsKKyAgICAgICAgaWYgKGJhbmQgPCAwIHx8IGJhbmQgPj0gZ2V0TnVtQmFuZHMoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYW1wbGVNb2RlbC5nZXRTYW1wbGVTaXplKGJhbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFNhbXBsZU1vZGVsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBTYW1wbGVNb2RlbCBhc3NvY2lhdGVkIHdpdGggdGhpcyBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICovCisgICAgcHVibGljIFNhbXBsZU1vZGVsIGdldFNhbXBsZU1vZGVsKCkgeworICAgICAgICByZXR1cm4gc2FtcGxlTW9kZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGNvbXBhdGlibGUgU2FtcGxlTW9kZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHdpZHRoIGFuZCBoZWlnaHQuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGguCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodC4KKyAgICAgKiBAcmV0dXJuIHRoZSBTYW1wbGVNb2RlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2FtcGxlTW9kZWwgZ2V0U2FtcGxlTW9kZWwoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGlmICgobG9uZyl3aWR0aCAqIGhlaWdodCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ3aWR0aCAqIGhlaWdodCA+IEludGVnZXIuTUFYX1ZBTFVFIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNhbXBsZU1vZGVsLmNyZWF0ZUNvbXBhdGlibGVTYW1wbGVNb2RlbCh3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBDb2xvck1vZGVsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBDb2xvck1vZGVsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICByZXR1cm4gY29sb3JNb2RlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBCdWZmZXJlZEltYWdlIHdpdGggdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0IGFuZCB0aGUKKyAgICAgKiBDb2xvck1hZGVsIGFuZCBTYW1wbGVNb2RlbCB3aGljaCBhcmUgc3BlY2lmaWVkIGJ5IHRoaXMKKyAgICAgKiBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdGhlIEJ1ZmZlcmVkSW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgQnVmZmVyZWRJbWFnZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBCdWZmZXJlZEltYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIGNyZWF0ZUJ1ZmZlcmVkSW1hZ2UoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIEltYWdlVHlwZVNwZWNpZmllciBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdCB0byBiZSBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBvYmplY3QgaXMgYW4gSW1hZ2VUeXBlU3BlY2lmaWVyIHdpdGggdGhlIHNhbWUgZGF0YQorICAgICAqICAgICAgICAgYXMgdGhpcyBJbWFnZVR5cGVTcGVjaWZpZXIsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgYm9vbGVhbiBydCA9IGZhbHNlOworICAgICAgICBpZiAobyBpbnN0YW5jZW9mIEltYWdlVHlwZVNwZWNpZmllcikgeworICAgICAgICAgICAgSW1hZ2VUeXBlU3BlY2lmaWVyIHRzID0gKEltYWdlVHlwZVNwZWNpZmllcilvOworICAgICAgICAgICAgcnQgPSBjb2xvck1vZGVsLmVxdWFscyh0cy5jb2xvck1vZGVsKSAmJiBzYW1wbGVNb2RlbC5lcXVhbHModHMuc2FtcGxlTW9kZWwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBydDsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VXcml0ZVBhcmFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVdyaXRlUGFyYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjYxODg5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VXcml0ZVBhcmFtLmphdmEKQEAgLTAsMCArMSw2NjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEuYXd0Lio7CisKKy8qKgorICogVGhlIEltYWdlV3JpdGVQYXJhbSBjbGFzcyBwcm92aWRlcyBpbmZvcm1hdGlvbiB0byBhbiBJbWFnZVdyaXRlciBhYm91dCBob3cgYW4KKyAqIGltYWdlIGlzIHRvIGJlIGVuY29kZWQuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSW1hZ2VXcml0ZVBhcmFtIGV4dGVuZHMgSUlPUGFyYW0geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PREVfRElTQUJMRUQgaW5kaWNhdGVzIHRoYXQgc3RyZWFtIGlzIG5vdCB0aWxlZCwKKyAgICAgKiBwcm9ncmVzc2l2ZSwgb3IgY29tcHJlc3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT0RFX0RJU0FCTEVEID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNT0RFX0RFRkFVTFQgaW5kaWNhdGVzIHRoYXQgdGhlIHN0cmVhbSB3aWxsIGJlIHRpbGVkLAorICAgICAqIHByb2dyZXNzaXZlLCBvciBjb21wcmVzc2VkIGFjY29yZGluZyB0byB0aGUgcGx1Zy1pbidzIGRlZmF1bHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9ERV9ERUZBVUxUID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNT0RFX0VYUExJQ0lUIGluZGljYXRlcyB0aGF0IHRoZSBzdHJlYW0gd2lsbCBiZSB0aWxlZCwKKyAgICAgKiBwcm9ncmVzc2l2ZSwgb3IgY29tcHJlc3NlZCBhY2NvcmRpbmcgdG8gY3VycmVudCBzZXR0aW5ncyB3aGljaCBhcmUKKyAgICAgKiBkZWZpbmVkIGJ5IHNldCBtZXRob2RzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PREVfRVhQTElDSVQgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IE1PREVfQ09QWV9GUk9NX01FVEFEQVRBIGluZGljYXRlcyB0aGF0IHRoZSBzdHJlYW0gd2lsbCBiZQorICAgICAqIHRpbGVkLCBwcm9ncmVzc2l2ZSwgb3IgY29tcHJlc3NlZCBhY2NvcmRpbmcgdG8gc3RyZWFtIG9yIGltYWdlIG1ldGFkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PREVfQ09QWV9GUk9NX01FVEFEQVRBID0gMzsKKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhlIEltYWdlV3JpdGVyIGNhbiB3cml0ZSB0aWxlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjYW5Xcml0ZVRpbGVzID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdGlsaW5nIG1vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB0aWxpbmdNb2RlID0gTU9ERV9DT1BZX0ZST01fTUVUQURBVEE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJlZmVycmVkIHRpbGUgc2l6ZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIERpbWVuc2lvbltdIHByZWZlcnJlZFRpbGVTaXplcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdGlsaW5nIHNldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiB0aWxpbmdTZXQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSB0aWxlIHdpZHRoLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgdGlsZVdpZHRoID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSB0aWxlIGhlaWdodC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHRpbGVIZWlnaHQgPSAwOworCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGUgSW1hZ2VXcml0ZXIgY2FuIG9mZnNldCB0aWxlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjYW5PZmZzZXRUaWxlcyA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogVGhlIHRpbGUgZ3JpZCB4IG9mZnNldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHRpbGVHcmlkWE9mZnNldCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdGlsZSBncmlkIHkgb2Zmc2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgdGlsZUdyaWRZT2Zmc2V0ID0gMDsKKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhlIEltYWdlV3JpdGVyIGNhbiB3cml0ZSBpbiBwcm9ncmVzc2l2ZSBtb2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGNhbldyaXRlUHJvZ3Jlc3NpdmUgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFRoZSBwcm9ncmVzc2l2ZSBtb2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgcHJvZ3Jlc3NpdmVNb2RlID0gTU9ERV9DT1BZX0ZST01fTUVUQURBVEE7CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoZSBJbWFnZVdyaXRlciBjYW4gd3JpdGUgaW4gY29tcHJlc3NlZCBtb2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGNhbldyaXRlQ29tcHJlc3NlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogVGhlIGNvbXByZXNzaW9uIG1vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb21wcmVzc2lvbk1vZGUgPSBNT0RFX0NPUFlfRlJPTV9NRVRBREFUQTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb21wcmVzc2lvbiB0eXBlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nW10gY29tcHJlc3Npb25UeXBlcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcHJlc3Npb24gdHlwZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGNvbXByZXNzaW9uVHlwZSA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcHJlc3Npb24gcXVhbGl0eS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmxvYXQgY29tcHJlc3Npb25RdWFsaXR5ID0gMS4wZjsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2NhbGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIExvY2FsZSBsb2NhbGUgPSBudWxsOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlV3JpdGVQYXJhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VXcml0ZVBhcmFtKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZVdyaXRlUGFyYW0gd2l0aCB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgTG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVdyaXRlUGFyYW0oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1vZGUgZm9yIHdyaXRpbmcgdGhlIHN0cmVhbSBpbiBhIHByb2dyZXNzaXZlIHNlcXVlbmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcHJvZ3Jlc3NpdmUgbW9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFByb2dyZXNzaXZlTW9kZSgpIHsKKyAgICAgICAgaWYgKGNhbldyaXRlUHJvZ3Jlc3NpdmUoKSkgeworICAgICAgICAgICAgcmV0dXJuIHByb2dyZXNzaXZlTW9kZTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oInByb2dyZXNzaXZlIG1vZGUgaXMgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBpbWFnZXMgY2FuIGJlIHdyaXR0ZW4gdXNpbmcgaW5jcmVhc2luZyBxdWFsaXR5IHBhc3NlcyBieQorICAgICAqIHByb2dyZXNzaXZlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBpbWFnZXMgY2FuIGJlIHdyaXR0ZW4gdXNpbmcgaW5jcmVhc2luZyBxdWFsaXR5IHBhc3NlcyBieQorICAgICAqICAgICAgICAgcHJvZ3Jlc3NpdmUsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Xcml0ZVByb2dyZXNzaXZlKCkgeworICAgICAgICByZXR1cm4gY2FuV3JpdGVQcm9ncmVzc2l2ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcm9ncmVzc2l2ZSBtb2RlIHdoaWNoIGRlZmluZXMgd2hldGhlciB0aGUgc3RyZWFtIGNvbnRhaW5zIGEKKyAgICAgKiBwcm9ncmVzc2l2ZSBzZXF1ZW5jZSBvZiBpbmNyZWFzaW5nIHF1YWxpdHkgZHVyaW5nIHdyaXRpbmcuIFRoZQorICAgICAqIHByb2dyZXNzaXZlIG1vZGUgc2hvdWxkIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczogTU9ERV9ESVNBQkxFRCwKKyAgICAgKiBNT0RFX0RFRkFVTFQsIG9yIE1PREVfQ09QWV9GUk9NX01FVEFEQVRBLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHByb2dyZXNzaXZlIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJvZ3Jlc3NpdmVNb2RlKGludCBtb2RlKSB7CisgICAgICAgIGlmIChjYW5Xcml0ZVByb2dyZXNzaXZlKCkpIHsKKyAgICAgICAgICAgIGlmIChtb2RlIDwgTU9ERV9ESVNBQkxFRCB8fCBtb2RlID4gTU9ERV9DT1BZX0ZST01fTUVUQURBVEEgfHwgbW9kZSA9PSBNT0RFX0VYUExJQ0lUKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibW9kZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnByb2dyZXNzaXZlTW9kZSA9IG1vZGU7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJwcm9ncmVzc2l2ZSBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdyaXRlciBjYW4gdXNlIHRpbGVzIHdpdGggbm9uIHplcm8gZ3JpZCBvZmZzZXRzIHdoaWxlCisgICAgICogd3JpdGluZy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSB3cml0ZXIgY2FuIHVzZSB0aWxlcyB3aXRoIG5vbiB6ZXJvIGdyaWQgb2Zmc2V0cworICAgICAqICAgICAgICAgd2hpbGUgd3JpdGluZywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbk9mZnNldFRpbGVzKCkgeworICAgICAgICByZXR1cm4gY2FuT2Zmc2V0VGlsZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgd3JpdGVyIGNhbiB3cml0ZSBpbWFnZXMgd2l0aCBjb21wcmVzc2lvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgd3JpdGVyIGNhbiB3cml0ZSBpbWFnZXMgd2l0aCBjb21wcmVzc2lvbiwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Xcml0ZUNvbXByZXNzZWQoKSB7CisgICAgICAgIHJldHVybiBjYW5Xcml0ZUNvbXByZXNzZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB3cml0ZXIgY2FuIHdyaXRlIHRpbGVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHdyaXRlciBjYW4gd3JpdGUgdGlsZXMsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Xcml0ZVRpbGVzKCkgeworICAgICAgICByZXR1cm4gY2FuV3JpdGVUaWxlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3cml0ZSBjb21wcmVzc2VkLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgdm9pZCBjaGVja1dyaXRlQ29tcHJlc3NlZCgpIHsKKyAgICAgICAgaWYgKCFjYW5Xcml0ZUNvbXByZXNzZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJDb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgY29tcHJlc3Npb24gbW9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgY2hlY2tDb21wcmVzc2lvbk1vZGUoKSB7CisgICAgICAgIGlmIChnZXRDb21wcmVzc2lvbk1vZGUoKSAhPSBNT0RFX0VYUExJQ0lUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDb21wcmVzc2lvbiBtb2RlIG5vdCBNT0RFX0VYUExJQ0lUISIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgY29tcHJlc3Npb24gdHlwZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgY2hlY2tDb21wcmVzc2lvblR5cGUoKSB7CisgICAgICAgIGlmIChnZXRDb21wcmVzc2lvblR5cGVzKCkgIT0gbnVsbCAmJiBnZXRDb21wcmVzc2lvblR5cGUoKSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJObyBjb21wcmVzc2lvbiB0eXBlIHNldCEiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXByZXNzaW9uIG1vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY29tcHJlc3Npb24gbW9kZSBpZiBpdCdzIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvbXByZXNzaW9uTW9kZSgpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzaW9uTW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhbiBhcnJheSBvZiBzdXBwb3J0ZWQgY29tcHJlc3Npb24gdHlwZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYW4gYXJyYXkgb2Ygc3VwcG9ydGVkIGNvbXByZXNzaW9uIHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDb21wcmVzc2lvblR5cGVzKCkgeworICAgICAgICBjaGVja1dyaXRlQ29tcHJlc3NlZCgpOworICAgICAgICBpZiAoY29tcHJlc3Npb25UeXBlcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY29tcHJlc3Npb25UeXBlcy5jbG9uZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgY29tcHJlc3Npb24gdHlwZSwgb3IgcmV0dXJucyBudWxsLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcHJlc3Npb24gdHlwZSwgb3IgcmV0dXJucyBudWxsIGlmIGl0IGlzIG5vdCBzZXQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21wcmVzc2lvblR5cGUoKSB7CisgICAgICAgIGNoZWNrV3JpdGVDb21wcmVzc2VkKCk7CisgICAgICAgIGNoZWNrQ29tcHJlc3Npb25Nb2RlKCk7CisgICAgICAgIHJldHVybiBjb21wcmVzc2lvblR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGJpdCByYXRlIHdoaWNoIHJlcHJlc2VudHMgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBiaXRzIG9mCisgICAgICogb3V0cHV0IGRhdGEgZm9yIGVhY2ggYml0IG9mIGlucHV0IGltYWdlIGRhdGEgd2l0aCB0aGUgc3BlY2lmaWVkIHF1YWxpdHkuCisgICAgICogCisgICAgICogQHBhcmFtIHF1YWxpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBxdWFsaXR5LgorICAgICAqIEByZXR1cm4gYW4gZXN0aW1hdGUgb2YgdGhlIGJpdCByYXRlLCBvciAtMS4wRiBpZiB0aGVyZSBpcyBubyBlc3RpbWF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0Qml0UmF0ZShmbG9hdCBxdWFsaXR5KSB7CisgICAgICAgIGNoZWNrV3JpdGVDb21wcmVzc2VkKCk7CisgICAgICAgIGNoZWNrQ29tcHJlc3Npb25Nb2RlKCk7CisgICAgICAgIGNoZWNrQ29tcHJlc3Npb25UeXBlKCk7CisgICAgICAgIGlmIChxdWFsaXR5IDwgMCB8fCBxdWFsaXR5ID4gMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUXVhbGl0eSBvdXQtb2YtYm91bmRzISIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMS4wZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb21wcmVzc2lvbiBxdWFsaXR5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGNvbXByZXNzaW9uIHF1YWxpdHkuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldENvbXByZXNzaW9uUXVhbGl0eSgpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzaW9uUXVhbGl0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhcnJheSBvZiBjb21wcmVzc2lvbiBxdWFsaXR5IGRlc2NyaXB0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYXJyYXkgb2YgY29tcHJlc3Npb24gcXVhbGl0eSBkZXNjcmlwdGlvbnMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldENvbXByZXNzaW9uUXVhbGl0eURlc2NyaXB0aW9ucygpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBmbG9hdHMgd2hpY2ggZGVzY3JpYmVzIGNvbXByZXNzaW9uIHF1YWxpdHkgbGV2ZWxzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIGNvbXByZXNzaW9uIHF1YWxpdHkgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdIGdldENvbXByZXNzaW9uUXVhbGl0eVZhbHVlcygpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWxlIG9mIHRoaXMgSW1hZ2VXcml0ZVBhcmFtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsZSBvZiB0aGlzIEltYWdlV3JpdGVQYXJhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGNvbXByZXNzaW9uIHR5cGUgdXNpbmcgdGhlIGN1cnJlbnQgTG9jYWxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcHJlc3Npb24gdHlwZSB1c2luZyB0aGUgY3VycmVudCBMb2NhbGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRMb2NhbGl6ZWRDb21wcmVzc2lvblR5cGVOYW1lKCkgeworICAgICAgICBjaGVja1dyaXRlQ29tcHJlc3NlZCgpOworICAgICAgICBjaGVja0NvbXByZXNzaW9uTW9kZSgpOworCisgICAgICAgIFN0cmluZyBjb21wcmVzc2lvblR5cGUgPSBnZXRDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgaWYgKGNvbXByZXNzaW9uVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJObyBjb21wcmVzc2lvbiB0eXBlIHNldCEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29tcHJlc3Npb25UeXBlOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdGlsaW5nLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgdm9pZCBjaGVja1RpbGluZygpIHsKKyAgICAgICAgaWYgKCFjYW5Xcml0ZVRpbGVzKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGlsaW5nIG5vdCBzdXBwb3J0ZWQhIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aWxpbmcgbW9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgY2hlY2tUaWxpbmdNb2RlKCkgeworICAgICAgICBpZiAoZ2V0VGlsaW5nTW9kZSgpICE9IE1PREVfRVhQTElDSVQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlRpbGluZyBtb2RlIG5vdCBNT0RFX0VYUExJQ0lUISIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdGlsaW5nIHBhcmFtcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgY2hlY2tUaWxpbmdQYXJhbXMoKSB7CisgICAgICAgIGlmICghdGlsaW5nU2V0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJUaWxpbmcgcGFyYW1ldGVycyBub3Qgc2V0ISIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGlsaW5nIG1vZGUgaWYgdGlsaW5nIGlzIHN1cHBvcnRlZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxpbmcgbW9kZSBpZiB0aWxpbmcgaXMgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VGlsaW5nTW9kZSgpIHsKKyAgICAgICAgY2hlY2tUaWxpbmcoKTsKKyAgICAgICAgcmV0dXJuIHRpbGluZ01vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBEaW1lbnNpb25zIGdpdmluZyB0aGUgc2l6ZXMgb2YgdGhlIHRpbGVzIGFzIHRoZXkgYXJlCisgICAgICogZW5jb2RlZCBpbiB0aGUgb3V0cHV0IGZpbGUgb3Igc3RyZWFtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHByZWZlcnJlZCB0aWxlIHNpemVzLgorICAgICAqLworICAgIHB1YmxpYyBEaW1lbnNpb25bXSBnZXRQcmVmZXJyZWRUaWxlU2l6ZXMoKSB7CisgICAgICAgIGNoZWNrVGlsaW5nKCk7CisgICAgICAgIGlmIChwcmVmZXJyZWRUaWxlU2l6ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBEaW1lbnNpb25bXSByZXR2YWwgPSBuZXcgRGltZW5zaW9uW3ByZWZlcnJlZFRpbGVTaXplcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByZWZlcnJlZFRpbGVTaXplcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmV0dmFsW2ldID0gbmV3IERpbWVuc2lvbihyZXR2YWxbaV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXR2YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGlsZSBncmlkIFggb2Zmc2V0IGZvciBlbmNvZGluZy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSB0aWxlIGdyaWQgWCBvZmZzZXQgZm9yIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VGlsZUdyaWRYT2Zmc2V0KCkgeworICAgICAgICBjaGVja1RpbGluZygpOworICAgICAgICBjaGVja1RpbGluZ01vZGUoKTsKKyAgICAgICAgY2hlY2tUaWxpbmdQYXJhbXMoKTsKKyAgICAgICAgcmV0dXJuIHRpbGVHcmlkWE9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aWxlIGdyaWQgWSBvZmZzZXQgZm9yIGVuY29kaW5nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRpbGUgZ3JpZCBZIG9mZnNldCBmb3IgZW5jb2RpbmcuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaWxlR3JpZFlPZmZzZXQoKSB7CisgICAgICAgIGNoZWNrVGlsaW5nKCk7CisgICAgICAgIGNoZWNrVGlsaW5nTW9kZSgpOworICAgICAgICBjaGVja1RpbGluZ1BhcmFtcygpOworICAgICAgICByZXR1cm4gdGlsZUdyaWRZT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRpbGUgaGVpZ2h0IGluIGFuIGltYWdlIGFzIGl0IGlzIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdGlsZSBoZWlnaHQgaW4gYW4gaW1hZ2UgYXMgaXQgaXMgd3JpdHRlbiB0byB0aGUgb3V0cHV0CisgICAgICogICAgICAgICBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUaWxlSGVpZ2h0KCkgeworICAgICAgICBjaGVja1RpbGluZygpOworICAgICAgICBjaGVja1RpbGluZ01vZGUoKTsKKyAgICAgICAgY2hlY2tUaWxpbmdQYXJhbXMoKTsKKyAgICAgICAgcmV0dXJuIHRpbGVIZWlnaHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGlsZSB3aWR0aCBpbiBhbiBpbWFnZSBhcyBpdCBpcyB3cml0dGVuIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHRpbGUgd2lkdGggaW4gYW4gaW1hZ2UgYXMgaXQgaXMgd3JpdHRlbiB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRpbGVXaWR0aCgpIHsKKyAgICAgICAgY2hlY2tUaWxpbmcoKTsKKyAgICAgICAgY2hlY2tUaWxpbmdNb2RlKCk7CisgICAgICAgIGNoZWNrVGlsaW5nUGFyYW1zKCk7CisgICAgICAgIHJldHVybiB0aWxlV2lkdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGNvbXByZXNzaW9uIHR5cGUgaGFzIGxvc3NsZXNzIGNvbXByZXNzaW9uIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBjdXJyZW50IGNvbXByZXNzaW9uIHR5cGUgaGFzIGxvc3NsZXNzIGNvbXByZXNzaW9uLAorICAgICAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcHJlc3Npb25Mb3NzbGVzcygpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBjdXJyZW50IGNvbXByZXNzaW9uIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5zZXRDb21wcmVzc2lvbigpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY29tcHJlc3Npb25UeXBlID0gbnVsbDsKKyAgICAgICAgY29tcHJlc3Npb25RdWFsaXR5ID0gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBtb2RlIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUuIFRoZSBzcGVjaWZpZWQgbW9kZSBjYW4KKyAgICAgKiBiZSBvbmUgb2YgdGhlIHByZWRlZmluZWQgY29uc3RhbnRzOiBNT0RFX0RFRkFVTFQsIE1PREVfRElTQUJMRUQsCisgICAgICogTU9ERV9FWFBMSUNJVCwgb3IgTU9ERV9DT1BZX0ZST01fTUVUQURBVEEuCisgICAgICogCisgICAgICogQHBhcmFtIG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgY29tcHJlc3Npb24gbW9kZSB0byBiZSBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29tcHJlc3Npb25Nb2RlKGludCBtb2RlKSB7CisgICAgICAgIGNoZWNrV3JpdGVDb21wcmVzc2VkKCk7CisgICAgICAgIHN3aXRjaCAobW9kZSkgeworICAgICAgICAgICAgY2FzZSBNT0RFX0VYUExJQ0lUOiB7CisgICAgICAgICAgICAgICAgY29tcHJlc3Npb25Nb2RlID0gbW9kZTsKKyAgICAgICAgICAgICAgICB1bnNldENvbXByZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlIE1PREVfQ09QWV9GUk9NX01FVEFEQVRBOgorICAgICAgICAgICAgY2FzZSBNT0RFX0RJU0FCTEVEOgorICAgICAgICAgICAgY2FzZSBNT0RFX0RFRkFVTFQ6IHsKKyAgICAgICAgICAgICAgICBjb21wcmVzc2lvbk1vZGUgPSBtb2RlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgdmFsdWUgZm9yIG1vZGUhIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBxdWFsaXR5LiBUaGUgdmFsdWUgc2hvdWxkIGJlIGJldHdlZW4gMCBhbmQgMS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcXVhbGl0eQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBjb21wcmVzc2lvbiBxdWFsaXR5LCBmbG9hdCB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29tcHJlc3Npb25RdWFsaXR5KGZsb2F0IHF1YWxpdHkpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvblR5cGUoKTsKKyAgICAgICAgaWYgKHF1YWxpdHkgPCAwIHx8IHF1YWxpdHkgPiAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJRdWFsaXR5IG91dC1vZi1ib3VuZHMhIik7CisgICAgICAgIH0KKyAgICAgICAgY29tcHJlc3Npb25RdWFsaXR5ID0gcXVhbGl0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiB0eXBlLiBUaGUgc3BlY2lmaWVkIHN0cmluZyBzaG91bGQgYmUgb25lIG9mIHRoZQorICAgICAqIHZhbHVlcyByZXR1cm5lZCBieSBnZXRDb21wcmVzc2lvblR5cGVzIG1ldGhvZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29tcHJlc3Npb25UeXBlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGNvbXByZXNzaW9uIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29tcHJlc3Npb25UeXBlKFN0cmluZyBjb21wcmVzc2lvblR5cGUpIHsKKyAgICAgICAgY2hlY2tXcml0ZUNvbXByZXNzZWQoKTsKKyAgICAgICAgY2hlY2tDb21wcmVzc2lvbk1vZGUoKTsKKworICAgICAgICBpZiAoY29tcHJlc3Npb25UeXBlID09IG51bGwpIHsgLy8gRG9uJ3QgY2hlY2sgYW55dGhpbmcKKyAgICAgICAgICAgIHRoaXMuY29tcHJlc3Npb25UeXBlID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN0cmluZ1tdIGNvbXByZXNzaW9uVHlwZXMgPSBnZXRDb21wcmVzc2lvblR5cGVzKCk7CisgICAgICAgICAgICBpZiAoY29tcHJlc3Npb25UeXBlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJObyBzZXR0YWJsZSBjb21wcmVzc2lvbiB0eXBlcyIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbXByZXNzaW9uVHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoY29tcHJlc3Npb25UeXBlc1tpXS5lcXVhbHMoY29tcHJlc3Npb25UeXBlKSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uVHlwZSA9IGNvbXByZXNzaW9uVHlwZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQ29tcHJlc3Npb24gdHlwZSBpcyBub3QgaW4gdGhlIGxpc3QuCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIGNvbXByZXNzaW9uIHR5cGUhIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbnN0cnVjdGlvbiB0aGF0IHRpbGluZyBzaG91bGQgYmUgcGVyZm9ybWVkIGZvciB0aGUgaW1hZ2UgaW4gdGhlCisgICAgICogb3V0cHV0IHN0cmVhbSB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGlsZVdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgdGlsZSdzIHdpZHRoLgorICAgICAqIEBwYXJhbSB0aWxlSGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgdGlsZSdzIGhlaWdodC4KKyAgICAgKiBAcGFyYW0gdGlsZUdyaWRYT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgdGlsZSBncmlkJ3MgeCBvZmZzZXQuCisgICAgICogQHBhcmFtIHRpbGVHcmlkWU9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHRpbGUgZ3JpZCdzIHkgb2Zmc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbGluZyhpbnQgdGlsZVdpZHRoLCBpbnQgdGlsZUhlaWdodCwgaW50IHRpbGVHcmlkWE9mZnNldCwgaW50IHRpbGVHcmlkWU9mZnNldCkgeworICAgICAgICBjaGVja1RpbGluZygpOworICAgICAgICBjaGVja1RpbGluZ01vZGUoKTsKKworICAgICAgICBpZiAoIWNhbk9mZnNldFRpbGVzKCkgJiYgKHRpbGVHcmlkWE9mZnNldCAhPSAwIHx8IHRpbGVHcmlkWU9mZnNldCAhPSAwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJDYW4ndCBvZmZzZXQgdGlsZXMhIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAodGlsZVdpZHRoIDw9IDAgfHwgdGlsZUhlaWdodCA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0aWxlIGRpbWVuc2lvbnMgYXJlIG5vbi1wb3NpdGl2ZSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIERpbWVuc2lvbiBwcmVmZXJyZWRUaWxlU2l6ZXNbXSA9IGdldFByZWZlcnJlZFRpbGVTaXplcygpOworICAgICAgICBpZiAocHJlZmVycmVkVGlsZVNpemVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJlZmVycmVkVGlsZVNpemVzLmxlbmd0aDsgaSArPSAyKSB7CisgICAgICAgICAgICAgICAgRGltZW5zaW9uIG1pblNpemUgPSBwcmVmZXJyZWRUaWxlU2l6ZXNbaV07CisgICAgICAgICAgICAgICAgRGltZW5zaW9uIG1heFNpemUgPSBwcmVmZXJyZWRUaWxlU2l6ZXNbaSArIDFdOworICAgICAgICAgICAgICAgIGlmICh0aWxlV2lkdGggPCBtaW5TaXplLndpZHRoIHx8IHRpbGVXaWR0aCA+IG1heFNpemUud2lkdGgKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IHRpbGVIZWlnaHQgPCBtaW5TaXplLmhlaWdodCB8fCB0aWxlSGVpZ2h0ID4gbWF4U2l6ZS5oZWlnaHQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCB0aWxlIHNpemUhIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGlsaW5nU2V0ID0gdHJ1ZTsKKyAgICAgICAgdGhpcy50aWxlV2lkdGggPSB0aWxlV2lkdGg7CisgICAgICAgIHRoaXMudGlsZUhlaWdodCA9IHRpbGVIZWlnaHQ7CisgICAgICAgIHRoaXMudGlsZUdyaWRYT2Zmc2V0ID0gdGlsZUdyaWRYT2Zmc2V0OworICAgICAgICB0aGlzLnRpbGVHcmlkWU9mZnNldCA9IHRpbGVHcmlkWU9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgYWxsIHRpbGluZyBzZXR0aW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnNldFRpbGluZygpIHsKKyAgICAgICAgY2hlY2tUaWxpbmcoKTsKKyAgICAgICAgY2hlY2tUaWxpbmdNb2RlKCk7CisKKyAgICAgICAgdGlsaW5nU2V0ID0gZmFsc2U7CisgICAgICAgIHRpbGVXaWR0aCA9IDA7CisgICAgICAgIHRpbGVIZWlnaHQgPSAwOworICAgICAgICB0aWxlR3JpZFhPZmZzZXQgPSAwOworICAgICAgICB0aWxlR3JpZFlPZmZzZXQgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbGluZyBtb2RlLiBUaGUgc3BlY2lmaWVkIG1vZGUgc2hvdWxkIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nCisgICAgICogdmFsdWVzOiBNT0RFX0RJU0FCTEVELCBNT0RFX0RFRkFVTFQsIE1PREVfRVhQTElDSVQsIG9yCisgICAgICogTU9ERV9DT1BZX0ZST01fTUVUQURBVEEuCisgICAgICogCisgICAgICogQHBhcmFtIG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdGlsaW5nIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGlsaW5nTW9kZShpbnQgbW9kZSkgeworICAgICAgICBjaGVja1RpbGluZygpOworCisgICAgICAgIHN3aXRjaCAobW9kZSkgeworICAgICAgICAgICAgY2FzZSBNT0RFX0VYUExJQ0lUOiB7CisgICAgICAgICAgICAgICAgdGlsaW5nTW9kZSA9IG1vZGU7CisgICAgICAgICAgICAgICAgdW5zZXRUaWxpbmcoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgTU9ERV9DT1BZX0ZST01fTUVUQURBVEE6CisgICAgICAgICAgICBjYXNlIE1PREVfRElTQUJMRUQ6CisgICAgICAgICAgICBjYXNlIE1PREVfREVGQVVMVDogeworICAgICAgICAgICAgICAgIHRpbGluZ01vZGUgPSBtb2RlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgdmFsdWUgZm9yIG1vZGUhIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9JbWFnZVdyaXRlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Njg3OWUwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vSW1hZ2VXcml0ZXIuamF2YQpAQCAtMCwwICsxLDEwMDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW87CisKK2ltcG9ydCBqYXZhLmF3dC5EaW1lbnNpb247CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlbmRlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uZXZlbnQuSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyOworaW1wb3J0IGphdmF4LmltYWdlaW8uZXZlbnQuSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5tZXRhZGF0YS5JSU9NZXRhZGF0YTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVdyaXRlclNwaTsKKworLyoqCisgKiBUaGUgSW1hZ2VXcml0ZXIgY2xhc3MgaXMgYW4gYWJzdHJhY3QgY2xhc3MgZm9yIGVuY29kaW5nIGltYWdlcy4gSW1hZ2VXcml0ZXIKKyAqIG9iamVjdHMgYXJlIGluc3RhbnRpYXRlZCBieSB0aGUgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UsIEltYWdlV3JpdGVyU3BpCisgKiBjbGFzcywgZm9yIHRoZSBzcGVjaWZpYyBmb3JtYXQuIEltYWdlV3JpdGVyU3BpIGNsYXNzIHNob3VsZCBiZSByZWdpc3RlcmVkCisgKiB3aXRoIHRoZSBJSU9SZWdpc3RyeSwgd2hpY2ggdXNlcyB0aGVtIGZvciBmb3JtYXQgcmVjb2duaXRpb24gYW5kIHByZXNlbnRhdGlvbgorICogb2YgYXZhaWxhYmxlIGZvcm1hdCByZWFkZXJzIGFuZCB3cml0ZXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlV3JpdGVyIGltcGxlbWVudHMgSW1hZ2VUcmFuc2NvZGVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBhdmFpbGFibGUgbG9jYWxlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTG9jYWxlW10gYXZhaWxhYmxlTG9jYWxlczsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2NhbGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIExvY2FsZSBsb2NhbGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3JpZ2luYXRpbmcgcHJvdmlkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIEltYWdlV3JpdGVyU3BpIG9yaWdpbmF0aW5nUHJvdmlkZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3V0cHV0LgorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3Qgb3V0cHV0OworCisgICAgLyoqCisgICAgICogVGhlIHByb2dyZXNzIGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTGlzdDxJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXI+IHByb2dyZXNzTGlzdGVuZXJzOworCisgICAgLyoqCisgICAgICogVGhlIHdhcm5pbmcgbGlzdGVuZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCBMaXN0PElJT1dyaXRlV2FybmluZ0xpc3RlbmVyPiB3YXJuaW5nTGlzdGVuZXJzOworCisgICAgLyoqCisgICAgICogVGhlIHdhcm5pbmcgbG9jYWxlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTGlzdDxMb2NhbGU+IHdhcm5pbmdMb2NhbGVzOworCisgICAgLy8gSW5kaWNhdGVzIHRoYXQgYWJvcnQgb3BlcmF0aW9uIGlzIHJlcXVlc3RlZAorICAgIC8vIEFib3J0IG1lY2hhbmlzbSBzaG91bGQgYmUgdGhyZWFkLXNhZmUKKyAgICAvKiogVGhlIGFib3J0ZWQuICovCisgICAgcHJpdmF0ZSBib29sZWFuIGFib3J0ZWQ7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VXcml0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG9yaWdpbmF0aW5nUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlclNwaSB3aGljaCBpbnN0YW50aWF0ZXMgdGhpcyBJbWFnZVdyaXRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VXcml0ZXIoSW1hZ2VXcml0ZXJTcGkgb3JpZ2luYXRpbmdQcm92aWRlcikgeworICAgICAgICB0aGlzLm9yaWdpbmF0aW5nUHJvdmlkZXIgPSBvcmlnaW5hdGluZ1Byb3ZpZGVyOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCBJSU9NZXRhZGF0YSBjb252ZXJ0U3RyZWFtTWV0YWRhdGEoSUlPTWV0YWRhdGEgaWlvTWV0YWRhdGEsCisgICAgICAgICAgICBJbWFnZVdyaXRlUGFyYW0gaW1hZ2VXcml0ZVBhcmFtKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBJSU9NZXRhZGF0YSBjb252ZXJ0SW1hZ2VNZXRhZGF0YShJSU9NZXRhZGF0YSBpaW9NZXRhZGF0YSwKKyAgICAgICAgICAgIEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGVTcGVjaWZpZXIsIEltYWdlV3JpdGVQYXJhbSBpbWFnZVdyaXRlUGFyYW0pOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgSW1hZ2VXcml0ZXJTcGkgd2hpY2ggaW5zdGFudGlhdGVkIHRoaXMgSW1hZ2VXcml0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VXcml0ZXJTcGkuCisgICAgICovCisgICAgcHVibGljIEltYWdlV3JpdGVyU3BpIGdldE9yaWdpbmF0aW5nUHJvdmlkZXIoKSB7CisgICAgICAgIHJldHVybiBvcmlnaW5hdGluZ1Byb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgc3RhcnQgb2YgYW4gaW1hZ2UgcmVhZCBieSBjYWxsaW5nIHRoZWlyIGltYWdlU3RhcnRlZCBtZXRob2QKKyAgICAgKiBvZiByZWdpc3RlcmVkIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzSW1hZ2VTdGFydGVkKGludCBpbWFnZUluZGV4KSB7CisgICAgICAgIGlmIChudWxsICE9IHByb2dyZXNzTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBmb3IgKElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBsaXN0ZW5lciA6IHByb2dyZXNzTGlzdGVuZXJzKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXIuaW1hZ2VTdGFydGVkKHRoaXMsIGltYWdlSW5kZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSBjdXJyZW50IHBlcmNlbnRhZ2Ugb2YgaW1hZ2UgY29tcGxldGlvbiBieSBjYWxsaW5nCisgICAgICogaW1hZ2VQcm9ncmVzcyBtZXRob2Qgb2YgcmVnaXN0ZXJlZCBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHBlcmNlbnRhZ2VEb25lCisgICAgICogICAgICAgICAgICB0aGUgcGVyY2VudGFnZSBkb25lLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NJbWFnZVByb2dyZXNzKGZsb2F0IHBlcmNlbnRhZ2VEb25lKSB7CisgICAgICAgIGlmIChudWxsICE9IHByb2dyZXNzTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBmb3IgKElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBsaXN0ZW5lciA6IHByb2dyZXNzTGlzdGVuZXJzKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXIuaW1hZ2VQcm9ncmVzcyh0aGlzLCBwZXJjZW50YWdlRG9uZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgaW1hZ2UgY29tcGxldGlvbiBieSBjYWxsaW5nIGltYWdlQ29tcGxldGUgbWV0aG9kIG9mIHJlZ2lzdGVyZWQKKyAgICAgKiBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NJbWFnZUNvbXBsZXRlKCkgeworICAgICAgICBpZiAobnVsbCAhPSBwcm9ncmVzc0xpc3RlbmVycykgeworICAgICAgICAgICAgZm9yIChJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIgbGlzdGVuZXIgOiBwcm9ncmVzc0xpc3RlbmVycykgeworICAgICAgICAgICAgICAgIGxpc3RlbmVyLmltYWdlQ29tcGxldGUodGhpcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSB3YXJuaW5nIG1lc3NhZ2UgYnkgY2FsbGluZyB3YXJuaW5nT2NjdXJyZWQgbWV0aG9kIG9mCisgICAgICogcmVnaXN0ZXJlZCBJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBpbmRleC4KKyAgICAgKiBAcGFyYW0gd2FybmluZworICAgICAqICAgICAgICAgICAgdGhlIHdhcm5pbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1dhcm5pbmdPY2N1cnJlZChpbnQgaW1hZ2VJbmRleCwgU3RyaW5nIHdhcm5pbmcpIHsKKyAgICAgICAgaWYgKG51bGwgPT0gd2FybmluZykgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ3YXJuaW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bGwgIT0gd2FybmluZ0xpc3RlbmVycykgeworICAgICAgICAgICAgZm9yIChJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lciBsaXN0ZW5lciA6IHdhcm5pbmdMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICBsaXN0ZW5lci53YXJuaW5nT2NjdXJyZWQodGhpcywgaW1hZ2VJbmRleCwgd2FybmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYSB3YXJuaW5nIG1lc3NhZ2UgYnkgY2FsbGluZyB3YXJuaW5nT2NjdXJyZWQgbWV0aG9kIG9mCisgICAgICogcmVnaXN0ZXJlZCBJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lcnMgd2l0aCBzdHJpbmcgZnJvbSBSZXNvdXJjZUJ1bmRsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqIEBwYXJhbSBidW5kbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIFJlc291cmNlQnVuZGxlLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXl3b3JkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NXYXJuaW5nT2NjdXJyZWQoaW50IGltYWdlSW5kZXgsIFN0cmluZyBidW5kbGUsIFN0cmluZyBrZXkpIHsKKyAgICAgICAgaWYgKHdhcm5pbmdMaXN0ZW5lcnMgIT0gbnVsbCkgeyAvLyBEb24ndCBjaGVjayB0aGUgcGFyYW1ldGVycworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1bmRsZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJiYXNlTmFtZSA9PSBudWxsISIpOworICAgICAgICB9CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigia2V5d29yZCA9PSBudWxsISIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gR2V0IHRoZSBjb250ZXh0IGNsYXNzIGxvYWRlciBhbmQgdHJ5IHRvIGxvY2F0ZSB0aGUgYnVuZGxlIHdpdGggaXQKKyAgICAgICAgLy8gZmlyc3QKKyAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dENsYXNzbG9hZGVyID0gQWNjZXNzQ29udHJvbGxlcgorICAgICAgICAgICAgICAgIC5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248Q2xhc3NMb2FkZXI+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9KTsKKworICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggYm90aCBsaXN0ZW5lcnMgYW5kIGxvY2FsZXMKKyAgICAgICAgaW50IG4gPSB3YXJuaW5nTGlzdGVuZXJzLnNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIElJT1dyaXRlV2FybmluZ0xpc3RlbmVyIGxpc3RlbmVyID0gd2FybmluZ0xpc3RlbmVycy5nZXQoaSk7CisgICAgICAgICAgICBMb2NhbGUgbG9jYWxlID0gd2FybmluZ0xvY2FsZXMuZ2V0KGkpOworCisgICAgICAgICAgICAvLyBOb3cgdHJ5IHRvIGdldCB0aGUgcmVzb3VyY2UgYnVuZGxlCisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSByYjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmIgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoYnVuZGxlLCBsb2NhbGUsIGNvbnRleHRDbGFzc2xvYWRlcik7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJiID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGJ1bmRsZSwgbG9jYWxlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQnVuZGxlIG5vdCBmb3VuZCEiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHdhcm5pbmcgPSByYi5nZXRTdHJpbmcoa2V5KTsKKyAgICAgICAgICAgICAgICBsaXN0ZW5lci53YXJuaW5nT2NjdXJyZWQodGhpcywgaW1hZ2VJbmRleCwgd2FybmluZyk7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlJlc291cmNlIGlzIG1pc3NpbmchIik7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlJlc291cmNlIGlzIG5vdCBhIFN0cmluZyEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCBPYmplY3QgdG8gdGhlIG91dHB1dCBvZiB0aGlzIEltYWdlV3JpdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3Qgd2hpY2ggcmVwcmVzZW50cyBkZXN0aW5hdGlvbiwgaXQgY2FuIGJlCisgICAgICogICAgICAgICAgICBJbWFnZU91dHB1dFN0cmVhbSBvciBvdGhlciBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dChPYmplY3Qgb3V0cHV0KSB7CisgICAgICAgIGlmIChvdXRwdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgSW1hZ2VXcml0ZXJTcGkgc3BpID0gZ2V0T3JpZ2luYXRpbmdQcm92aWRlcigpOworICAgICAgICAgICAgaWYgKG51bGwgIT0gc3BpKSB7CisgICAgICAgICAgICAgICAgQ2xhc3NbXSBvdXRUeXBlcyA9IHNwaS5nZXRPdXRwdXRUeXBlcygpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gc3VwcG9ydGVkID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZm9yIChDbGFzczw/PiBlbGVtZW50IDogb3V0VHlwZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuaXNJbnN0YW5jZShvdXRwdXQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCFzdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigib3V0cHV0ICIgKyBvdXRwdXQgKyAiIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5vdXRwdXQgPSBvdXRwdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgY29tcGxldGVkIGltYWdlIHN0cmVhbSB0aGF0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgaW1hZ2UsCisgICAgICogZGVmYXVsdCBtZXRhZGF0YSwgYW5kIHRodW1ibmFpbHMgdG8gdGhlIG91dHB1dC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW1hZ2UgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQgZHVyaW5nIHdyaXRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGUoSUlPSW1hZ2UgaW1hZ2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG51bGwsIGltYWdlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBjb21wbGV0ZWQgaW1hZ2Ugc3RyZWFtIHRoYXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCByZW5kZXJlZAorICAgICAqIGltYWdlLCBkZWZhdWx0IG1ldGFkYXRhLCBhbmQgdGh1bWJuYWlscyB0byB0aGUgb3V0cHV0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBSZW5kZXJlZEltYWdlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkIGR1cmluZyB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFJlbmRlcmVkSW1hZ2UgaW1hZ2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG51bGwsIG5ldyBJSU9JbWFnZShpbWFnZSwgbnVsbCwgbnVsbCksIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGNvbXBsZXRlZCBpbWFnZSBzdHJlYW0gdGhhdCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGltYWdlLAorICAgICAqIG1ldGFkYXRhIGFuZCB0aHVtYm5haWxzIHRvIHRoZSBvdXRwdXQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmVhbU1ldGFkYXRhCisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIG1ldGFkYXRhLCBvciBudWxsLgorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBpbWFnZSB0byBiZSB3cml0dGVuLCBpZiBjYW5Xcml0ZVJhc3RlcigpIG1ldGhvZAorICAgICAqICAgICAgICAgICAgcmV0dXJucyBmYWxzZSwgdGhlbiBJbWFnZSBtdXN0IGNvbnRhaW4gb25seSBSZW5kZXJlZEltYWdlLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVQYXJhbSwgb3IgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlKElJT01ldGFkYXRhIHN0cmVhbU1ldGFkYXRhLCBJSU9JbWFnZSBpbWFnZSwgSW1hZ2VXcml0ZVBhcmFtIHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGlzcG9zZXMgb2YgYW55IHJlc291cmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICAvLyBkZWYgaW1wbC4gZG9lcyBub3RoaW5nIGFjY29yZGluZyB0byB0aGUgc3BlYy4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1ZXN0cyBhbiBhYm9ydCBvcGVyYXRpb24gZm9yIGN1cnJlbnQgd3JpdGluZyBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFib3J0KCkgeworICAgICAgICBhYm9ydGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciBvciBub3QgYSByZXF1ZXN0IHRvIGFib3J0IHRoZSBjdXJyZW50IHdyaXRlIG9wZXJhdGlvbiBoYXMKKyAgICAgKiBiZWVuIG1hZGUgc3VjY2Vzc2Z1bGx5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHJlcXVlc3QgdG8gYWJvcnQgdGhlIGN1cnJlbnQgd3JpdGUgb3BlcmF0aW9uIGhhcworICAgICAqICAgICAgICAgYmVlbiBtYWRlIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgYm9vbGVhbiBhYm9ydFJlcXVlc3RlZCgpIHsKKyAgICAgICAgcmV0dXJuIGFib3J0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIGFsbCBwcmV2aW91cyBhYm9ydCByZXF1ZXN0LCBhbmQgYWJvcnRSZXF1ZXN0ZWQgcmV0dXJucyBmYWxzZSBhZnRlcgorICAgICAqIGNhbGxpbmcgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGNsZWFyQWJvcnRSZXF1ZXN0KCkgeworICAgICAgICBhYm9ydGVkID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBsaXN0ZW5lci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIoSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAocHJvZ3Jlc3NMaXN0ZW5lcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBuZXcgQXJyYXlMaXN0PElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lcj4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb2dyZXNzTGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICogICAgICAgICAgICB0aGUgSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIgbGlzdGVuZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIoSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh3YXJuaW5nTGlzdGVuZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHdhcm5pbmdMaXN0ZW5lcnMgPSBuZXcgQXJyYXlMaXN0PElJT1dyaXRlV2FybmluZ0xpc3RlbmVyPigpOworICAgICAgICAgICAgd2FybmluZ0xvY2FsZXMgPSBuZXcgQXJyYXlMaXN0PExvY2FsZT4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHdhcm5pbmdMaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKKyAgICAgICAgd2FybmluZ0xvY2FsZXMuYWRkKGdldExvY2FsZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvdXRwdXQgb2JqZWN0IHRoYXQgd2FzIHNldCBieSBzZXRPdXRwdXQgbWV0aG9kLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG91dHB1dCBvYmplY3Qgc3VjaCBhcyBJbWFnZU91dHB1dFN0cmVhbSwgb3IgbnVsbCBpZiBpdCBpcyBub3QKKyAgICAgKiAgICAgICAgIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE91dHB1dCgpIHsKKyAgICAgICAgcmV0dXJuIG91dHB1dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBvdXRwdXQgcmV0dXJuIGZhbHNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tPdXRwdXRSZXR1cm5GYWxzZSgpIHsKKyAgICAgICAgaWYgKGdldE91dHB1dCgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImdldE91dHB1dCgpID09IG51bGwhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuc3VwcG9ydGVkIG9wZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKSB7CisgICAgICAgIGlmIChnZXRPdXRwdXQoKSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJnZXRPdXRwdXQoKSA9PSBudWxsISIpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgd3JpdGUgdmFyaWFudCEiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBuZXcgZW1wdHkgaW1hZ2UgY2FuIGJlIGluc2VydGVkIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgaW1hZ2UuCisgICAgICogQHJldHVybiB0cnVlIGlmIGEgbmV3IGVtcHR5IGltYWdlIGNhbiBiZSBpbnNlcnRlZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LAorICAgICAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBTaWduYWxzIHRoYXQgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuSW5zZXJ0RW1wdHkoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjaGVja091dHB1dFJldHVybkZhbHNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGEgbmV3IGltYWdlIGNhbiBiZSBpbnNlcnRlZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIGltYWdlLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhIG5ldyBpbWFnZSBjYW4gYmUgaW5zZXJ0ZWQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgU2lnbmFscyB0aGF0IGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbkluc2VydEltYWdlKGludCBpbWFnZUluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2hlY2tPdXRwdXRSZXR1cm5GYWxzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGluZGV4IGNhbiBiZSByZW1vdmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIGltYWdlLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGluZGV4IGNhbiBiZSByZW1vdmVkLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBTaWduYWxzIHRoYXQgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVtb3ZlSW1hZ2UoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjaGVja091dHB1dFJldHVybkZhbHNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIG1ldGFkYXRhIG9mIHRoZSBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggY2FuIGJlCisgICAgICogcmVwbGFjZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW1hZ2UgaW5kZXguCisgICAgICogQHJldHVybiB0cnVlIGlmIG1ldGFkYXRhIG9mIHRoZSBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggY2FuIGJlCisgICAgICogICAgICAgICByZXBsYWNlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5SZXBsYWNlSW1hZ2VNZXRhZGF0YShpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrT3V0cHV0UmV0dXJuRmFsc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcGl4ZWxzIG9mIHRoZSBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXggY2FuIGJlCisgICAgICogcmVwbGFjZWQgYnkgdGhlIHJlcGxhY2VQaXhlbHMgbWV0aG9kcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlJ3MgaW5kZXguCisgICAgICogQHJldHVybiB0cnVlIGlmIHBpeGVscyBvZiB0aGUgaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGluZGV4IGNhbiBiZQorICAgICAqICAgICAgICAgcmVwbGFjZWQgYnkgdGhlIHJlcGxhY2VQaXhlbHMgbWV0aG9kcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBTaWduYWxzIHRoYXQgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVwbGFjZVBpeGVscyhpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrT3V0cHV0UmV0dXJuRmFsc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmVhbSBtZXRhZGF0YSBwcmVzZW50ZWQgaW4gdGhlIG91dHB1dCBjYW4gYmUKKyAgICAgKiByZW1vdmVkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyZWFtIG1ldGFkYXRhIHByZXNlbnRlZCBpbiB0aGUgb3V0cHV0IGNhbiBiZQorICAgICAqICAgICAgICAgcmVtb3ZlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5SZXBsYWNlU3RyZWFtTWV0YWRhdGEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2hlY2tPdXRwdXRSZXR1cm5GYWxzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgd3JpdGluZyBvZiBhIGNvbXBsZXRlIGltYWdlIHN0cmVhbSB3aGljaCBjb250YWlucyBhCisgICAgICogc2luZ2xlIGltYWdlIGlzIHN1cHBvcnRlZCB3aXRoIHVuZGVmaW5lZCBwaXhlbCB2YWx1ZXMgYW5kIGFzc29jaWF0ZWQKKyAgICAgKiBtZXRhZGF0YSBhbmQgdGh1bWJuYWlscyB0byB0aGUgb3V0cHV0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgd3JpdGluZyBvZiBhIGNvbXBsZXRlIGltYWdlIHN0cmVhbSB3aGljaCBjb250YWlucyBhCisgICAgICogICAgICAgICBzaW5nbGUgaW1hZ2UgaXMgc3VwcG9ydGVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbldyaXRlRW1wdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2hlY2tPdXRwdXRSZXR1cm5GYWxzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbWV0aG9kcyB3aGljaCB0YWtlbiBhbiBJSU9JbWFnZVBhcmFtZXRlciBjYW4gZGVhbAorICAgICAqIHdpdGggYSBSYXN0ZXIgc291cmNlIGltYWdlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWV0aG9kcyB3aGljaCB0YWtlbiBhbiBJSU9JbWFnZVBhcmFtZXRlciBjYW4gZGVhbAorICAgICAqICAgICAgICAgd2l0aCBhIFJhc3RlciBzb3VyY2UgaW1hZ2UsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Xcml0ZVJhc3RlcnMoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdyaXRlciBjYW4gYWRkIGFuIGltYWdlIHRvIHN0cmVhbSB0aGF0IGFscmVhZHkKKyAgICAgKiBjb250YWlucyBoZWFkZXIgaW5mb3JtYXRpb24uCisgICAgICogCisgICAgICogQHJldHVybiBpZiB0aGUgd3JpdGVyIGNhbiBhZGQgYW4gaW1hZ2UgdG8gc3RyZWFtIHRoYXQgYWxyZWFkeSBjb250YWlucworICAgICAqICAgICAgICAgaGVhZGVyIGluZm9ybWF0aW9uLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuV3JpdGVTZXF1ZW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuZHMgdGhlIGluc2VydGlvbiBvZiBhIG5ldyBpbWFnZS4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kSW5zZXJ0RW1wdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuZHMgdGhlIHJlcGxhY2UgcGl4ZWxzIG9wZXJhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kUmVwbGFjZVBpeGVscygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHVuc3VwcG9ydGVkT3BlcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5kcyBhbiBlbXB0eSB3cml0ZSBvcGVyYXRpb24uCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZFdyaXRlRW1wdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuZHMgdGhlIHNlcXVlbmNlIG9mIHdyaXRlIG9wZXJhdGlvbnMuCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZFdyaXRlU2VxdWVuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgYXZhaWxhYmxlIGxvY2FsZXMuCisgICAgICogCisgICAgICogQHJldHVybiBhbiBvZiBhcnJheSBhdmFpbGFibGUgbG9jYWxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTG9jYWxlcygpIHsKKyAgICAgICAgaWYgKGF2YWlsYWJsZUxvY2FsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYXZhaWxhYmxlTG9jYWxlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSUlPTWV0YWRhdGEgb2JqZWN0IHRoYXQgY29udGFpbnMgZGVmYXVsdCB2YWx1ZXMgZm9yIGVuY29kaW5nIGFuCisgICAgICogaW1hZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlUGFyYW0uCisgICAgICogQHJldHVybiB0aGUgSUlPTWV0YWRhdGEgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJSU9NZXRhZGF0YSBnZXREZWZhdWx0SW1hZ2VNZXRhZGF0YShJbWFnZVR5cGVTcGVjaWZpZXIgaW1hZ2VUeXBlLAorICAgICAgICAgICAgSW1hZ2VXcml0ZVBhcmFtIHBhcmFtKTsKKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSUlPTWV0YWRhdGEgb2JqZWN0IHRoYXQgY29udGFpbnMgZGVmYXVsdCB2YWx1ZXMgZm9yIGVuY29kaW5nIGEKKyAgICAgKiBzdHJlYW0gb2YgaW1hZ2VzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVQYXJhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJSU9NZXRhZGF0YSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IElJT01ldGFkYXRhIGdldERlZmF1bHRTdHJlYW1NZXRhZGF0YShJbWFnZVdyaXRlUGFyYW0gcGFyYW0pOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCBsb2NhbGUgb2YgdGhpcyBJbWFnZVdyaXRlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGxvY2FsZSBvZiB0aGlzIEltYWdlV3JpdGVyLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgeworICAgICAgICByZXR1cm4gbG9jYWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgd3JpdGUgcGFyYW0uIEdldHMgYSBuZXcgSW1hZ2VXcml0ZVBhcmFtIG9iamVjdCBmb3IgdGhpcworICAgICAqIEltYWdlV3JpdGVyIHdpdGggdGhlIGN1cnJlbnQgTG9jYWxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBuZXcgSW1hZ2VXcml0ZVBhcmFtIG9iamVjdCBmb3IgdGhpcyBJbWFnZVdyaXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VXcml0ZVBhcmFtIGdldERlZmF1bHRXcml0ZVBhcmFtKCkgeworICAgICAgICByZXR1cm4gbmV3IEltYWdlV3JpdGVQYXJhbShnZXRMb2NhbGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHRodW1ibmFpbHMgc3VwcG9ydGVkIGJ5IHRoZSBmb3JtYXQgYmVpbmcgd3JpdHRlbiB3aXRoCisgICAgICogc3VwcG9ydGVkIGltYWdlIHR5cGUsIGltYWdlIHdyaXRlIHBhcmFtZXRlcnMsIHN0cmVhbSwgYW5kIGltYWdlIG1ldGFkYXRhCisgICAgICogb2JqZWN0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VUeXBlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VUeXBlU3BlY2lmaWVyLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlJ3MgcGFyYW1ldGVycy4KKyAgICAgKiBAcGFyYW0gc3RyZWFtTWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gbWV0YWRhdGEuCisgICAgICogQHBhcmFtIGltYWdlTWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSBtZXRhZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdGh1bWJuYWlscyBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1UaHVtYm5haWxzU3VwcG9ydGVkKEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGUsIEltYWdlV3JpdGVQYXJhbSBwYXJhbSwKKyAgICAgICAgICAgIElJT01ldGFkYXRhIHN0cmVhbU1ldGFkYXRhLCBJSU9NZXRhZGF0YSBpbWFnZU1ldGFkYXRhKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByZWZlcnJlZCB0aHVtYm5haWwgc2l6ZXMuIEdldHMgYW4gYXJyYXkgb2YgRGltZW5zaW9ucyB3aXRoIHRoZQorICAgICAqIHNpemVzIGZvciB0aHVtYm5haWwgaW1hZ2VzIGFzIHRoZXkgYXJlIGVuY29kZWQgaW4gdGhlIG91dHB1dCBmaWxlIG9yCisgICAgICogc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVR5cGVTcGVjaWZpZXIuCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZVBhcmFtLgorICAgICAqIEBwYXJhbSBzdHJlYW1NZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBtZXRhZGF0YS4KKyAgICAgKiBAcGFyYW0gaW1hZ2VNZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIG1ldGFkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIHByZWZlcnJlZCB0aHVtYm5haWwgc2l6ZXMuCisgICAgICovCisgICAgcHVibGljIERpbWVuc2lvbltdIGdldFByZWZlcnJlZFRodW1ibmFpbFNpemVzKEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGUsCisgICAgICAgICAgICBJbWFnZVdyaXRlUGFyYW0gcGFyYW0sIElJT01ldGFkYXRhIHN0cmVhbU1ldGFkYXRhLCBJSU9NZXRhZGF0YSBpbWFnZU1ldGFkYXRhKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXBhcmVzIGluc2VydGlvbiBvZiBhbiBlbXB0eSBpbWFnZSBieSByZXF1ZXN0aW5nIHRoZSBpbnNlcnRpb24gb2YgYSBuZXcKKyAgICAgKiBpbWFnZSBpbnRvIGFuIGV4aXN0aW5nIGltYWdlIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4LgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0eXBlLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBpbWFnZS4KKyAgICAgKiBAcGFyYW0gaW1hZ2VNZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIG1ldGFkYXRhLCBvciBudWxsLgorICAgICAqIEBwYXJhbSB0aHVtYm5haWxzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgdGh1bWJuYWlscyBmb3IgdGhpcyBpbWFnZSwgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlUGFyYW0sIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByZXBhcmVJbnNlcnRFbXB0eShpbnQgaW1hZ2VJbmRleCwgSW1hZ2VUeXBlU3BlY2lmaWVyIGltYWdlVHlwZSwgaW50IHdpZHRoLAorICAgICAgICAgICAgaW50IGhlaWdodCwgSUlPTWV0YWRhdGEgaW1hZ2VNZXRhZGF0YSwgTGlzdDw/IGV4dGVuZHMgQnVmZmVyZWRJbWFnZT4gdGh1bWJuYWlscywKKyAgICAgICAgICAgIEltYWdlV3JpdGVQYXJhbSBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwYXJlcyB0aGUgd3JpdGVyIHRvIGNhbGwgdGhlIHJlcGxhY2VQaXhlbHMgbWV0aG9kIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogcmVnaW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyBpbmRleC4KKyAgICAgKiBAcGFyYW0gcmVnaW9uCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHJlZ2lvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlcGFyZVJlcGxhY2VQaXhlbHMoaW50IGltYWdlSW5kZXgsIFJlY3RhbmdsZSByZWdpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHVuc3VwcG9ydGVkT3BlcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZXMgdGhlIHdyaXRlciBmb3Igd3JpdGluZyBhbiBlbXB0eSBpbWFnZSBieSBiZWdpbm5pbmcgdGhlIHByb2Nlc3MKKyAgICAgKiBvZiB3cml0aW5nIGEgY29tcGxldGUgaW1hZ2Ugc3RyZWFtIHRoYXQgY29udGFpbnMgYSBzaW5nbGUgaW1hZ2Ugd2l0aAorICAgICAqIHVuZGVmaW5lZCBwaXhlbCB2YWx1ZXMsIG1ldGFkYXRhIGFuZCB0aHVtYm5haWxzLCB0byB0aGUgb3V0cHV0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJlYW1NZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBtZXRhZGF0YS4KKyAgICAgKiBAcGFyYW0gaW1hZ2VUeXBlCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgdHlwZS4KKyAgICAgKiBAcGFyYW0gd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UuCisgICAgICogQHBhcmFtIGhlaWdodAorICAgICAqICAgICAgICAgICAgdGhlIGhlaWdodCBvZiB0aGUgaW1hZ2UuCisgICAgICogQHBhcmFtIGltYWdlTWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIG1ldGFkYXRhLCBvciBudWxsLgorICAgICAqIEBwYXJhbSB0aHVtYm5haWxzCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UncyB0aHVtYm5haWxzLCBvciBudWxsLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlJ3MgcGFyYW1ldGVycywgb3IgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlcGFyZVdyaXRlRW1wdHkoSUlPTWV0YWRhdGEgc3RyZWFtTWV0YWRhdGEsIEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGUsCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIElJT01ldGFkYXRhIGltYWdlTWV0YWRhdGEsCisgICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBCdWZmZXJlZEltYWdlPiB0aHVtYm5haWxzLCBJbWFnZVdyaXRlUGFyYW0gcGFyYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHVuc3VwcG9ydGVkT3BlcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZXMgYSBzdHJlYW0gdG8gYWNjZXB0IGNhbGxzIG9mIHdyaXRlVG9TZXF1ZW5jZSBtZXRob2QgdXNpbmcgdGhlCisgICAgICogbWV0YWRhdGEgb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJlYW1NZXRhZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBtZXRhZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlcGFyZVdyaXRlU2VxdWVuY2UoSUlPTWV0YWRhdGEgc3RyZWFtTWV0YWRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHVuc3VwcG9ydGVkT3BlcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSBjb21wbGV0aW9uIG9mIGEgdGh1bWJuYWlsIHJlYWQgYnkgY2FsbGluZyB0aGVpcgorICAgICAqIHRodW1ibmFpbENvbXBsZXRlIG1ldGhvZCBvZiByZWdpc3RlcmVkIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1RodW1ibmFpbENvbXBsZXRlKCkgeworICAgICAgICBpZiAocHJvZ3Jlc3NMaXN0ZW5lcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIgbGlzdGVuZXIgOiBwcm9ncmVzc0xpc3RlbmVycykgeworICAgICAgICAgICAgICAgIGxpc3RlbmVyLnRodW1ibmFpbENvbXBsZXRlKHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSBjdXJyZW50IHBlcmNlbnRhZ2Ugb2YgdGh1bWJuYWlsIGNvbXBsZXRpb24gYnkgY2FsbGluZyB0aGVpcgorICAgICAqIHRodW1ibmFpbFByb2dyZXNzIG1ldGhvZCBvZiByZWdpc3RlcmVkIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHBlcmNlbnRhZ2VEb25lCisgICAgICogICAgICAgICAgICB0aGUgcGVyY2VudGFnZSBkb25lLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NUaHVtYm5haWxQcm9ncmVzcyhmbG9hdCBwZXJjZW50YWdlRG9uZSkgeworICAgICAgICBpZiAocHJvZ3Jlc3NMaXN0ZW5lcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIgbGlzdGVuZXIgOiBwcm9ncmVzc0xpc3RlbmVycykgeworICAgICAgICAgICAgICAgIGxpc3RlbmVyLnRodW1ibmFpbFByb2dyZXNzKHRoaXMsIHBlcmNlbnRhZ2VEb25lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGUgc3RhcnQgb2YgYSB0aHVtYm5haWwgcmVhZCBieSBjYWxsaW5nIHRodW1ibmFpbFN0YXJ0ZWQKKyAgICAgKiBtZXRob2Qgb2YgcmVnaXN0ZXJlZCBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgaW5kZXguCisgICAgICogQHBhcmFtIHRodW1ibmFpbEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIGluZGV4LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NUaHVtYm5haWxTdGFydGVkKGludCBpbWFnZUluZGV4LCBpbnQgdGh1bWJuYWlsSW5kZXgpIHsKKyAgICAgICAgaWYgKHByb2dyZXNzTGlzdGVuZXJzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyIDogcHJvZ3Jlc3NMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICBsaXN0ZW5lci50aHVtYm5haWxTdGFydGVkKHRoaXMsIGltYWdlSW5kZXgsIHRodW1ibmFpbEluZGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyB0aGF0IHRoZSB3cml0aW5nIGhhcyBiZWVuIGFib3J0ZWQgYnkgY2FsbGluZyB3cml0ZUFib3J0ZWQKKyAgICAgKiBtZXRob2Qgb2YgcmVnaXN0ZXJlZCBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NXcml0ZUFib3J0ZWQoKSB7CisgICAgICAgIGlmIChwcm9ncmVzc0xpc3RlbmVycyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBsaXN0ZW5lciA6IHByb2dyZXNzTGlzdGVuZXJzKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXIud3JpdGVBYm9ydGVkKHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgYWxsIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVycygpIHsKKyAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGFsbCBJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lciBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXJzKCkgeworICAgICAgICB3YXJuaW5nTGlzdGVuZXJzID0gbnVsbDsKKyAgICAgICAgd2FybmluZ0xvY2FsZXMgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIgbGlzdGVuZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICogICAgICAgICAgICB0aGUgcmVnaXN0ZXJlZCBJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIgdG8gYmUgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIoSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGlmIChwcm9ncmVzc0xpc3RlbmVycyAhPSBudWxsICYmIGxpc3RlbmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChwcm9ncmVzc0xpc3RlbmVycy5yZW1vdmUobGlzdGVuZXIpICYmIHByb2dyZXNzTGlzdGVuZXJzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lciBsaXN0ZW5lci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWdpc3RlcmVkIElJT1dyaXRlV2FybmluZ0xpc3RlbmVyIGxpc3RlbmVyIHRvIGJlIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIoSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKHdhcm5pbmdMaXN0ZW5lcnMgPT0gbnVsbCB8fCBsaXN0ZW5lciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgaWR4ID0gd2FybmluZ0xpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKTsKKyAgICAgICAgaWYgKGlkeCA+IC0xKSB7CisgICAgICAgICAgICB3YXJuaW5nTGlzdGVuZXJzLnJlbW92ZShpZHgpOworICAgICAgICAgICAgd2FybmluZ0xvY2FsZXMucmVtb3ZlKGlkeCk7CisKKyAgICAgICAgICAgIGlmICh3YXJuaW5nTGlzdGVuZXJzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHdhcm5pbmdMaXN0ZW5lcnMgPSBudWxsOworICAgICAgICAgICAgICAgIHdhcm5pbmdMb2NhbGVzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCBpbmRleCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIGluZGV4LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJbWFnZShpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyBpbWFnZSBtZXRhZGF0YSBvZiB0aGUgaW1hZ2Ugd2l0aCBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSdzIGluZGV4LgorICAgICAqIEBwYXJhbSBpbWFnZU1ldGFkYXRhCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgbWV0YWRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VJbWFnZU1ldGFkYXRhKGludCBpbWFnZUluZGV4LCBJSU9NZXRhZGF0YSBpbWFnZU1ldGFkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIGEgcGFydCBvZiBhbiBpbWFnZSBwcmVzZW50ZWQgaW4gdGhlIG91dHB1dCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmVkSW1hZ2UuCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZVBhcmFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXBsYWNlUGl4ZWxzKFJlbmRlcmVkSW1hZ2UgaW1hZ2UsIEltYWdlV3JpdGVQYXJhbSBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyBhIHBhcnQgb2YgYW4gaW1hZ2UgcHJlc2VudGVkIGluIHRoZSBvdXRwdXQgd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogUmFzdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSByYXN0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSYXN0ZXIuCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZVBhcmFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXBsYWNlUGl4ZWxzKFJhc3RlciByYXN0ZXIsIEltYWdlV3JpdGVQYXJhbSBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgc3RyZWFtIG1ldGFkYXRhIG9mIHRoZSBvdXRwdXQgd2l0aCBuZXcgSUlPTWV0YWRhdGEuCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmVhbU1ldGFkYXRhCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHN0cmVhbSBtZXRhZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVwbGFjZVN0cmVhbU1ldGFkYXRhKElJT01ldGFkYXRhIHN0cmVhbU1ldGFkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvY2FsZSBvZiB0aGlzIEltYWdlV3JpdGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9jYWxlW10gbG9jYWxlcyA9IGdldEF2YWlsYWJsZUxvY2FsZXMoKTsKKyAgICAgICAgYm9vbGVhbiB2YWxpZExvY2FsZSA9IGZhbHNlOworICAgICAgICBpZiAobG9jYWxlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxvY2FsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAobG9jYWxlLmVxdWFscyhsb2NhbGVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICB2YWxpZExvY2FsZSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh2YWxpZExvY2FsZSkgeworICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGxvY2FsZSEiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIEltYWdlV3JpdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICBzZXRPdXRwdXQobnVsbCk7CisgICAgICAgIHNldExvY2FsZShudWxsKTsKKyAgICAgICAgcmVtb3ZlQWxsSUlPV3JpdGVXYXJuaW5nTGlzdGVuZXJzKCk7CisgICAgICAgIHJlbW92ZUFsbElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lcnMoKTsKKyAgICAgICAgY2xlYXJBYm9ydFJlcXVlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIGltYWdlIGludG8gZXhpc3Rpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIGluZGV4IHdoZXJlIGFuIGltYWdlIHdpbGwgYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW1hZ2UgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlUGFyYW0sIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlSW5zZXJ0KGludCBpbWFnZUluZGV4LCBJSU9JbWFnZSBpbWFnZSwgSW1hZ2VXcml0ZVBhcmFtIHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5zdXBwb3J0ZWRPcGVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCBpbWFnZSB0byB0aGUgc2VxdWVuY2UuCisgICAgICogCisgICAgICogQHBhcmFtIGltYWdlCisgICAgICogICAgICAgICAgICB0aGUgaW1hZ2UgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlUGFyYW0sIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkIGR1cmluZyB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG9TZXF1ZW5jZShJSU9JbWFnZSBpbWFnZSwgSW1hZ2VXcml0ZVBhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnN1cHBvcnRlZE9wZXJhdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL2V2ZW50L0lJT1JlYWRQcm9ncmVzc0xpc3RlbmVyLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5NDQ4OTYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFNlcmdleSBJLiBTYWxpc2hldgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VSZWFkZXI7CisKKy8qKgorICogVGhlIElJT1JlYWRQcm9ncmVzc0xpc3RlbmVyIGludGVyZmFjZSBub3RpZmllcyBjYWxsZXJzIGFib3V0IHRoZSBwcm9ncmVzcyBvZgorICogdGhlIGltYWdlIGFuZCB0aHVtYm5haWwgcmVhZGluZyBtZXRob2RzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJSU9SZWFkUHJvZ3Jlc3NMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IHRoZSBpbWFnZSByZWFkaW5nIGhhcyBiZWVuIGNvbXBsZXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHZvaWQgaW1hZ2VDb21wbGV0ZShJbWFnZVJlYWRlciBzb3VyY2UpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciBhYm91dCB0aGUgZGVncmVlIG9mIGNvbXBsZXRpb24gb2YgdGhlIHJlYWQgY2FsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqIEBwYXJhbSBwZXJjZW50YWdlRG9uZQorICAgICAqICAgICAgICAgICAgdGhlIHBlcmNlbnRhZ2Ugb2YgZGVjb2RpbmcgZG9uZS4KKyAgICAgKi8KKyAgICB2b2lkIGltYWdlUHJvZ3Jlc3MoSW1hZ2VSZWFkZXIgc291cmNlLCBmbG9hdCBwZXJjZW50YWdlRG9uZSk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgYW4gaW1hZ2UgcmVhZCBvcGVyYXRpb24gaGFzIGJlZW4gc3RhcnRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqIEBwYXJhbSBpbWFnZUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGltYWdlIGluIGFuIGlucHV0IGZpbGUgb3Igc3RyZWFtIHRvIGJlIHJlYWQuCisgICAgICovCisgICAgdm9pZCBpbWFnZVN0YXJ0ZWQoSW1hZ2VSZWFkZXIgc291cmNlLCBpbnQgaW1hZ2VJbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgYSByZWFkIG9wZXJhdGlvbiBoYXMgYmVlbiBhYm9ydGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRlciBvYmplY3Qgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgdm9pZCByZWFkQWJvcnRlZChJbWFnZVJlYWRlciBzb3VyY2UpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IGEgc2VxdWVuY2Ugb2YgcmVhZCBvcGVyYXRpb25zIGhhcyBiZWVuCisgICAgICogY29tcGxldGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRlciBvYmplY3Qgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgdm9pZCBzZXF1ZW5jZUNvbXBsZXRlKEltYWdlUmVhZGVyIHNvdXJjZSk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgYSBzZXF1ZW5jZSBvZiByZWFkIG9wZXJhdGlvbiBoYXMgYmVlbgorICAgICAqIHN0YXJ0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gbWluSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgaW1hZ2UgdG8gYmUgcmVhZC4KKyAgICAgKi8KKyAgICB2b2lkIHNlcXVlbmNlU3RhcnRlZChJbWFnZVJlYWRlciBzb3VyY2UsIGludCBtaW5JbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGF0IGEgdGh1bWJuYWlsIHJlYWQgb3BlcmF0aW9uIGhhcyBiZWVuIGNvbXBsZXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHZvaWQgdGh1bWJuYWlsQ29tcGxldGUoSW1hZ2VSZWFkZXIgc291cmNlKTsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoaXMgbGlzdGVuZXIgYWJvdXQgdGhlIGRlZ3JlZSBvZiBjb21wbGV0aW9uIG9mIHRoZSByZWFkIGNhbGwuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gcGVyY2VudGFnZURvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJjZW50YWdlIG9mIGRlY29kaW5nIGRvbmUuCisgICAgICovCisgICAgdm9pZCB0aHVtYm5haWxQcm9ncmVzcyhJbWFnZVJlYWRlciBzb3VyY2UsIGZsb2F0IHBlcmNlbnRhZ2VEb25lKTsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoaXMgbGlzdGVuZXIgdGhhdCBhIHRodW1ibmFpbCByZWFkaW5nIG9wZXJhdGlvbiBoYXMgYmVlbgorICAgICAqIHN0YXJ0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBpbWFnZSBpbiBhbiBpbnB1dCBmaWxlIG9yIHN0cmVhbSB0byBiZSByZWFkLgorICAgICAqIEBwYXJhbSB0aHVtYm5haWxJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSB0aHVtYm5haWwgdG8gYmUgcmVhZC4KKyAgICAgKi8KKyAgICB2b2lkIHRodW1ibmFpbFN0YXJ0ZWQoSW1hZ2VSZWFkZXIgc291cmNlLCBpbnQgaW1hZ2VJbmRleCwgaW50IHRodW1ibmFpbEluZGV4KTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL2V2ZW50L0lJT1JlYWRVcGRhdGVMaXN0ZW5lci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vZXZlbnQvSUlPUmVhZFVwZGF0ZUxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDliZGJjYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL2V2ZW50L0lJT1JlYWRVcGRhdGVMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsMTgyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFNlcmdleSBJLiBTYWxpc2hldgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5ldmVudDsKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVJlYWRlcjsKKworLyoKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworLyoqCisgKiBUaGUgSUlPUmVhZFVwZGF0ZUxpc3RlbmVyIGludGVyZmFjZSBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IHRvIHJlY2VpdmUKKyAqIG5vdGlmaWNhdGlvbiBvZiBwaXhlbCB1cGRhdGVzIGR1cmluZyBpbWFnZSBhbmQgdGh1bWJuYWlsIHJlYWRpbmcgb3BlcmF0aW9ucy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUlPUmVhZFVwZGF0ZUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgdGhlIHNwZWNpZmllZCBhcmVhIG9mIHRoZSBpbWFnZSBoYXMgYmVlbgorICAgICAqIHVwZGF0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdGhlSW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0byBiZSB1cGRhdGVkLgorICAgICAqIEBwYXJhbSBtaW5YCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVscyBpbiB0aGUgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBtaW5ZCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVscyBpbiB0aGUgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSB3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHdpZHRoIG9mIHVwZGF0ZWQgYXJlYS4KKyAgICAgKiBAcGFyYW0gaGVpZ2h0CisgICAgICogICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHVwZGF0ZWQgYXJlYS4KKyAgICAgKiBAcGFyYW0gcGVyaW9kWAorICAgICAqICAgICAgICAgICAgdGhlIGhvcml6b250YWwgc3BhY2luZyBwZXJpb2QgYmV0d2VlbiB1cGRhdGVkIHBpeGVscywgaWYgaXQKKyAgICAgKiAgICAgICAgICAgIGVxdWFscyAxLCB0aGVyZSBpcyBubyBzcGFjZSBiZXR3ZWVuIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gcGVyaW9kWQorICAgICAqICAgICAgICAgICAgdGhlIHZlcnRpY2FsIHNwYWNpbmcgcGVyaW9kIGJldHdlZW4gdXBkYXRlZCBwaXhlbHMsIGlmIGl0CisgICAgICogICAgICAgICAgICBlcXVhbHMgMSwgdGhlcmUgaXMgbm8gc3BhY2UgYmV0d2VlbiBwaXhlbHMuCisgICAgICogQHBhcmFtIGJhbmRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgaW50ZWdlciB2YWx1ZXMgaW5kaWNhdGluZyB0aGUgYmFuZHMgYmVpbmcKKyAgICAgKiAgICAgICAgICAgIHVwZGF0ZWQuCisgICAgICovCisgICAgdm9pZCBpbWFnZVVwZGF0ZShJbWFnZVJlYWRlciBzb3VyY2UsIEJ1ZmZlcmVkSW1hZ2UgdGhlSW1hZ2UsIGludCBtaW5YLCBpbnQgbWluWSwgaW50IHdpZHRoLAorICAgICAgICAgICAgaW50IGhlaWdodCwgaW50IHBlcmlvZFgsIGludCBwZXJpb2RZLCBpbnRbXSBiYW5kcyk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgdGhlIGN1cnJlbnQgcmVhZCBvcGVyYXRpb24gaGFzIGNvbXBsZXRlZCBhCisgICAgICogcHJvZ3Jlc3NpdmUgcGFzcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VSZWFkZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqIEBwYXJhbSB0aGVJbWFnZQorICAgICAqICAgICAgICAgICAgdGhlIGltYWdlIHRvIGJlIHVwZGF0ZWQuCisgICAgICovCisgICAgdm9pZCBwYXNzQ29tcGxldGUoSW1hZ2VSZWFkZXIgc291cmNlLCBCdWZmZXJlZEltYWdlIHRoZUltYWdlKTsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoaXMgbGlzdGVuZXIgdGhhdCB0aGUgY3VycmVudCByZWFkIG9wZXJhdGlvbiBoYXMgYmVndW4gYQorICAgICAqIHByb2dyZXNzaXZlIHBhc3MuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdGhlSW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0byBiZSB1cGRhdGVkLgorICAgICAqIEBwYXJhbSBwYXNzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHRoZSBwYXNzLgorICAgICAqIEBwYXJhbSBtaW5QYXNzCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHBhc3MgdGhhdCB3aWxsIGJlIGRlY29kZWQuCisgICAgICogQHBhcmFtIG1heFBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBwYXNzIHRoYXQgd2lsbCBiZSBkZWNvZGVkLgorICAgICAqIEBwYXJhbSBtaW5YCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBYIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVscyBpbiB0aGUgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBtaW5ZCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBZIGNvb3JkaW5hdGUgb2YgdGhlIHBpeGVscyBpbiB0aGUgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBwZXJpb2RYCisgICAgICogICAgICAgICAgICB0aGUgaG9yaXpvbnRhbCBzcGFjaW5nIHBlcmlvZCBiZXR3ZWVuIHVwZGF0ZWQgcGl4ZWxzLCBpZiBpdAorICAgICAqICAgICAgICAgICAgZXF1YWxzIDEsIHRoZXJlIGlzIG5vIHNwYWNlIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBwZXJpb2RZCisgICAgICogICAgICAgICAgICB0aGUgdmVydGljYWwgc3BhY2luZyBwZXJpb2QgYmV0d2VlbiB1cGRhdGVkIHBpeGVscywgaWYgaXQKKyAgICAgKiAgICAgICAgICAgIGVxdWFscyAxLCB0aGVyZSBpcyBubyBzcGFjZSBiZXR3ZWVuIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYmFuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBpbnRlZ2VyIHZhbHVlcyBpbmRpY2F0aW5nIHRoZSBiYW5kcyBiZWluZworICAgICAqICAgICAgICAgICAgdXBkYXRlZC4KKyAgICAgKi8KKyAgICB2b2lkIHBhc3NTdGFydGVkKEltYWdlUmVhZGVyIHNvdXJjZSwgQnVmZmVyZWRJbWFnZSB0aGVJbWFnZSwgaW50IHBhc3MsIGludCBtaW5QYXNzLAorICAgICAgICAgICAgaW50IG1heFBhc3MsIGludCBtaW5YLCBpbnQgbWluWSwgaW50IHBlcmlvZFgsIGludCBwZXJpb2RZLCBpbnRbXSBiYW5kcyk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgdGhlIGN1cnJlbnQgdGh1bWJuYWlsIHJlYWQgb3BlcmF0aW9uIGhhcworICAgICAqIGNvbXBsZXRlZCBhIHByb2dyZXNzaXZlIHBhc3MuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdGhlSW1hZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aHVtYm5haWwgdG8gYmUgdXBkYXRlZC4KKyAgICAgKi8KKyAgICB2b2lkIHRodW1ibmFpbFBhc3NDb21wbGV0ZShJbWFnZVJlYWRlciBzb3VyY2UsIEJ1ZmZlcmVkSW1hZ2UgdGhlSW1hZ2UpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IHRoZSBjdXJyZW50IHRodW1ibmFpbCByZWFkIG9wZXJhdGlvbiBoYXMKKyAgICAgKiBiZWd1biBhIHByb2dyZXNzaXZlIHBhc3MuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdGhlVGh1bWJuYWlsCisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIHBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgdGhlIHBhc3MuCisgICAgICogQHBhcmFtIG1pblBhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgcGFzcyB0aGF0IHdpbGwgYmUgZGVjb2RlZC4KKyAgICAgKiBAcGFyYW0gbWF4UGFzcworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHBhc3MgdGhhdCB3aWxsIGJlIGRlY29kZWQuCisgICAgICogQHBhcmFtIG1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWxzIGluIHRoZSB1cGRhdGVkIGFyZWEuCisgICAgICogQHBhcmFtIG1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWxzIGluIHRoZSB1cGRhdGVkIGFyZWEuCisgICAgICogQHBhcmFtIHBlcmlvZFgKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3Jpem9udGFsIHNwYWNpbmcgcGVyaW9kIGJldHdlZW4gdXBkYXRlZCBwaXhlbHMsIGlmIGl0CisgICAgICogICAgICAgICAgICBlcXVhbHMgMSwgdGhlcmUgaXMgbm8gc3BhY2UgYmV0d2VlbiBwaXhlbHMuCisgICAgICogQHBhcmFtIHBlcmlvZFkKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJ0aWNhbCBzcGFjaW5nIHBlcmlvZCBiZXR3ZWVuIHVwZGF0ZWQgcGl4ZWxzLCBpZiBpdAorICAgICAqICAgICAgICAgICAgZXF1YWxzIDEsIHRoZXJlIGlzIG5vIHNwYWNlIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBiYW5kcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGludGVnZXIgdmFsdWVzIGluZGljYXRpbmcgdGhlIGJhbmRzIGJlaW5nCisgICAgICogICAgICAgICAgICB1cGRhdGVkLgorICAgICAqLworICAgIHZvaWQgdGh1bWJuYWlsUGFzc1N0YXJ0ZWQoSW1hZ2VSZWFkZXIgc291cmNlLCBCdWZmZXJlZEltYWdlIHRoZVRodW1ibmFpbCwgaW50IHBhc3MsCisgICAgICAgICAgICBpbnQgbWluUGFzcywgaW50IG1heFBhc3MsIGludCBtaW5YLCBpbnQgbWluWSwgaW50IHBlcmlvZFgsIGludCBwZXJpb2RZLCBpbnRbXSBiYW5kcyk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgYSBzcGVjaWZpZWQgYXJlYSBvZiBhIHRodW1ibmFpbCBpbWFnZSBoYXMKKyAgICAgKiBiZWVuIHVwZGF0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlUmVhZGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdGhlVGh1bWJuYWlsCisgICAgICogICAgICAgICAgICB0aGUgdGh1bWJuYWlsIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIG1pblgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIFggY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWxzIGluIHRoZSB1cGRhdGVkIGFyZWEuCisgICAgICogQHBhcmFtIG1pblkKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIFkgY29vcmRpbmF0ZSBvZiB0aGUgcGl4ZWxzIGluIHRoZSB1cGRhdGVkIGFyZWEuCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgd2lkdGggb2YgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBoZWlnaHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWlnaHQgb2YgdXBkYXRlZCBhcmVhLgorICAgICAqIEBwYXJhbSBwZXJpb2RYCisgICAgICogICAgICAgICAgICB0aGUgaG9yaXpvbnRhbCBzcGFjaW5nIHBlcmlvZCBiZXR3ZWVuIHVwZGF0ZWQgcGl4ZWxzLCBpZiBpdAorICAgICAqICAgICAgICAgICAgZXF1YWxzIDEsIHRoZXJlIGlzIG5vIHNwYWNlIGJldHdlZW4gcGl4ZWxzLgorICAgICAqIEBwYXJhbSBwZXJpb2RZCisgICAgICogICAgICAgICAgICB0aGUgdmVydGljYWwgc3BhY2luZyBwZXJpb2QgYmV0d2VlbiB1cGRhdGVkIHBpeGVscywgaWYgaXQKKyAgICAgKiAgICAgICAgICAgIGVxdWFscyAxLCB0aGVyZSBpcyBubyBzcGFjZSBiZXR3ZWVuIHBpeGVscy4KKyAgICAgKiBAcGFyYW0gYmFuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBpbnRlZ2VyIHZhbHVlcyBpbmRpY2F0aW5nIHRoZSBiYW5kcyBiZWluZworICAgICAqICAgICAgICAgICAgdXBkYXRlZC4KKyAgICAgKi8KKyAgICB2b2lkIHRodW1ibmFpbFVwZGF0ZShJbWFnZVJlYWRlciBzb3VyY2UsIEJ1ZmZlcmVkSW1hZ2UgdGhlVGh1bWJuYWlsLCBpbnQgbWluWCwgaW50IG1pblksCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBwZXJpb2RYLCBpbnQgcGVyaW9kWSwgaW50W10gYmFuZHMpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vZXZlbnQvSUlPUmVhZFdhcm5pbmdMaXN0ZW5lci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vZXZlbnQvSUlPUmVhZFdhcm5pbmdMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxOGE1ZGYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9SZWFkV2FybmluZ0xpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBTZXJnZXkgSS4gU2FsaXNoZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlUmVhZGVyOworCisvKiAKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworLyoqCisgKiBUaGUgSUlPUmVhZFdhcm5pbmdMaXN0ZW5lciBwcm92aWRlcyBtZXRob2RzIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9uIG9mCisgKiB3YXJuaW5nIG1lc3NhZ2VzIGdlbmVyYXRlZCBieSBpbWFnZSBhbmQgdGh1bWJuYWlsIHJlYWRpbmcgbWV0aG9kcy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUlPUmVhZFdhcm5pbmdMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciBhYm91dCBhIHdhcm5pbmcgKG5vbi1mYXRhbCBlcnJvcikgZHVyaW5nIGRlY29kaW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRlciBvYmplY3Qgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QuCisgICAgICogQHBhcmFtIHdhcm5pbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgd2FybmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3YXJuaW5nT2NjdXJyZWQoSW1hZ2VSZWFkZXIgc291cmNlLCBTdHJpbmcgd2FybmluZyk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIuamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL2V2ZW50L0lJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhMmM1OTUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9Xcml0ZVByb2dyZXNzTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5ldmVudDsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhlIElJT1dyaXRlUHJvZ3Jlc3NMaXN0ZW5lciBpbnRlcmZhY2UgcHJvdmlkZXMgbWV0aG9kcyB0byByZWNlaXZlCisgKiBub3RpZmljYXRpb24gYWJvdXQgdGhlIHByb2dyZXNzIG9mIHRoZSBpbWFnZSBhbmQgdGh1bWJuYWlsIHdyaXRpbmcgbWV0aG9kcy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUlPV3JpdGVQcm9ncmVzc0xpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIHRoYXQgYW4gaW1hZ2Ugd3JpdGUgb3BlcmF0aW9uIGhhcyBiZWVuIHN0YXJ0ZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBpbWFnZSBiZWluZyB3cml0dGVuLgorICAgICAqLworICAgIHZvaWQgaW1hZ2VTdGFydGVkKEltYWdlV3JpdGVyIHNvdXJjZSwgaW50IGltYWdlSW5kZXgpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciBhYm91dCB0aGUgZGVncmVlIG9mIGNvbXBsZXRpb24gb2YgdGhlIHdyaXRlIGNhbGwuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gcGVyY2VudGFnZURvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJjZW50YWdlIG9mIGVuY29kaW5nIGRvbmUuCisgICAgICovCisgICAgdm9pZCBpbWFnZVByb2dyZXNzKEltYWdlV3JpdGVyIHNvdXJjZSwgZmxvYXQgcGVyY2VudGFnZURvbmUpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IHRoZSBpbWFnZSB3cml0aW5nIGhhcyBiZWVuIGNvbXBsZXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHZvaWQgaW1hZ2VDb21wbGV0ZShJbWFnZVdyaXRlciBzb3VyY2UpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IGEgdGh1bWJuYWlsIHdyaXRlIG9wZXJhdGlvbiBoYXMgYmVlbiBzdGFydGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlciBvYmplY3Qgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QuCisgICAgICogQHBhcmFtIGltYWdlSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgaW1hZ2UgYmVpbmcgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gdGh1bWJuYWlsSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgdGh1bWJuYWlsIGJlaW5nIHdyaXR0ZW4uCisgICAgICovCisgICAgdm9pZCB0aHVtYm5haWxTdGFydGVkKEltYWdlV3JpdGVyIHNvdXJjZSwgaW50IGltYWdlSW5kZXgsIGludCB0aHVtYm5haWxJbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIGFib3V0IHRoZSBkZWdyZWUgb2YgY29tcGxldGlvbiBvZiB0aGUgd3JpdGUgY2FsbC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqIEBwYXJhbSBwZXJjZW50YWdlRG9uZQorICAgICAqICAgICAgICAgICAgdGhlIHBlcmNlbnRhZ2Ugb2YgZW5jb2RpbmcgZG9uZS4KKyAgICAgKi8KKyAgICB2b2lkIHRodW1ibmFpbFByb2dyZXNzKEltYWdlV3JpdGVyIHNvdXJjZSwgZmxvYXQgcGVyY2VudGFnZURvbmUpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB0aGF0IGEgdGh1bWJuYWlsIHdyaXRlIG9wZXJhdGlvbiBoYXMgYmVlbgorICAgICAqIGNvbXBsZXRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZXIgb2JqZWN0IHdoaWNoIGNhbGxzIHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHZvaWQgdGh1bWJuYWlsQ29tcGxldGUoSW1hZ2VXcml0ZXIgc291cmNlKTsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoaXMgbGlzdGVuZXIgdGhhdCB3cml0aW5nIG9wZXJhdGlvbiBoYXMgYmVlbiBhYm9ydGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVdyaXRlciBvYmplY3Qgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgdm9pZCB3cml0ZUFib3J0ZWQoSW1hZ2VXcml0ZXIgc291cmNlKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL2V2ZW50L0lJT1dyaXRlV2FybmluZ0xpc3RlbmVyLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlZTQxY2QKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9JSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uZXZlbnQ7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVyOworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIFRoZSBJSU9Xcml0ZVdhcm5pbmdMaXN0ZW5lciBwcm92aWRlcyBtZXRob2RzIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9uIG9mCisgKiB3YXJuaW5ncyBnZW5lcmF0ZWQgYnkgaW1hZ2UgYW5kIHRodW1ibmFpbCB3cml0aW5nIG1ldGhvZHMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIElJT1dyaXRlV2FybmluZ0xpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGxpc3RlbmVyIGFib3V0IGEgd2FybmluZyAobm9uLWZhdGFsIGVycm9yKSBkdXJpbmcgZW5jb2RpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlV3JpdGVyIG9iamVjdCB3aGljaCBjYWxscyB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gaW1hZ2VJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBpbWFnZSBnZW5lcmF0aW5nIHRoZSB3YXJuaW5nLgorICAgICAqIEBwYXJhbSB3YXJuaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIHdhcm5pbmcuCisgICAgICovCisgICAgdm9pZCB3YXJuaW5nT2NjdXJyZWQoSW1hZ2VXcml0ZXIgc291cmNlLCBpbnQgaW1hZ2VJbmRleCwgU3RyaW5nIHdhcm5pbmcpOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vZXZlbnQvcGFja2FnZS5odG1sIGIvYXd0L2phdmF4L2ltYWdlaW8vZXZlbnQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZmUzOWYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9ldmVudC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw4IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBUaGlzIHBhY2thZ2UgcHJvdmlkZXMgaW50ZXJmYWNlcyB0byBoYW5kbGUgZXZlbnRzIHdoaWNoIGNhbiBiZSBmaXJlZCBkdXJpbmcgdGhlIHJlYWRpbmcgb3Igd3JpdGluZyBvZiBpbWFnZXMuCisgICAgPC9wPgorICBAc2luY2UgQW5kcm9pZCAxLjAKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPSW52YWxpZFRyZWVFeGNlcHRpb24uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT0ludmFsaWRUcmVlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmE5MDY1NwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT0ludmFsaWRUcmVlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLm1ldGFkYXRhOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLklJT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgSUlPSW52YWxpZFRyZWVFeGNlcHRpb24gcHJvdmlkZXMgbm90aWZpY2F0aW9uIGFib3V0IGZhaWxzIG9mCisgKiBJSU9NZXRhZGF0YU5vZGVzIHRyZWUgcGFyc2luZyBieSBJSU9NZXRhZGF0YSBvYmplY3QuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgSUlPSW52YWxpZFRyZWVFeGNlcHRpb24gZXh0ZW5kcyBJSU9FeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIG9mZmVuZGluZyBub2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBOb2RlIG9mZmVuZGluZ05vZGUgPSBudWxsOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGFuIElJT0ludmFsaWRUcmVlRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWxlZAorICAgICAqIG1lc3NhZ2UgYW5kIHNwZWNpZmllZCBvZmZlbmRpbmcgTm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbGVkIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIG9mZmVuZGluZ05vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZlbmRpbmcgbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPSW52YWxpZFRyZWVFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIE5vZGUgb2ZmZW5kaW5nTm9kZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgdGhpcy5vZmZlbmRpbmdOb2RlID0gb2ZmZW5kaW5nTm9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPSW52YWxpZFRyZWVFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbGVkCisgICAgICogbWVzc2FnZSBhbmQgc3BlY2lmaWVkIG9mZmVuZGluZyBOb2RlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsZWQgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gb2ZmZW5kaW5nTm9kZQorICAgICAqICAgICAgICAgICAgdGhlIG9mZmVuZGluZyBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBJSU9JbnZhbGlkVHJlZUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlLCBOb2RlIG9mZmVuZGluZ05vZGUpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgICAgICB0aGlzLm9mZmVuZGluZ05vZGUgPSBvZmZlbmRpbmdOb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZmVuZGluZyBub2RlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG9mZmVuZGluZyBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIGdldE9mZmVuZGluZ05vZGUoKSB7CisgICAgICAgIHJldHVybiBvZmZlbmRpbmdOb2RlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2Y2ViZjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YS5qYXZhCkBAIC0wLDAgKzEsMzkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8ubWV0YWRhdGE7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5tZXRhZGF0YS5JSU9NZXRhZGF0YVV0aWxzOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogVGhlIGNsYXNzIElJT01ldGFkYXRhIHJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIChidW5kbGVkIHdpdGggYW4gaW1hZ2UpIGFzIGEKKyAqIERvbS10eXBlIHRyZWUuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSUlPTWV0YWRhdGEgeworCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGUgc3RhbmRhcmQgbWV0YWRhdGEgZm9ybWF0IGlzIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzdGFuZGFyZEZvcm1hdFN1cHBvcnRlZDsKKworICAgIC8qKgorICAgICAqIFRoZSBuYXRpdmUgbWV0YWRhdGEgZm9ybWF0IG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBuYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmF0aXZlIG1ldGFkYXRhIGZvcm1hdCBjbGFzcyBuYW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgbmF0aXZlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXh0cmEgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXh0cmEgbWV0YWRhdGEgZm9ybWF0IGNsYXNzIG5hbWVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBleHRyYU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lczsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGNvbnRyb2xsZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT01ldGFkYXRhQ29udHJvbGxlciBkZWZhdWx0Q29udHJvbGxlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBjb250cm9sbGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9NZXRhZGF0YUNvbnRyb2xsZXIgY29udHJvbGxlcjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJSU9NZXRhZGF0YSB3aXRoIG5vIGRhdGEgc2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9NZXRhZGF0YSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPTWV0YWRhdGEgd2l0aCB0aGUgc3BlY2lmaWVkIGRhdGEgcGFyYW1ldGVycy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RhbmRhcmRNZXRhZGF0YUZvcm1hdFN1cHBvcnRlZAorICAgICAqICAgICAgICAgICAgd2hldGhlciB0aGUgc3RhbmRhcmQgbWV0YWRhdGEgZm9ybWF0IGlzIHN1cHBvcnRlZC4KKyAgICAgKiBAcGFyYW0gbmF0aXZlTWV0YWRhdGFGb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmF0aXZlIG1ldGFkYXRhIGZvcm1hdCBuYW1lLgorICAgICAqIEBwYXJhbSBuYXRpdmVNZXRhZGF0YUZvcm1hdENsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gZXh0cmFNZXRhZGF0YUZvcm1hdE5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgZXh0cmEgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqIEBwYXJhbSBleHRyYU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGV4dHJhIG1ldGFkYXRhIGZvcm1hdCBjbGFzcyBuYW1lcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSUlPTWV0YWRhdGEoYm9vbGVhbiBzdGFuZGFyZE1ldGFkYXRhRm9ybWF0U3VwcG9ydGVkLCBTdHJpbmcgbmF0aXZlTWV0YWRhdGFGb3JtYXROYW1lLAorICAgICAgICAgICAgU3RyaW5nIG5hdGl2ZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBTdHJpbmdbXSBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICBTdHJpbmdbXSBleHRyYU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcykgeworICAgICAgICBzdGFuZGFyZEZvcm1hdFN1cHBvcnRlZCA9IHN0YW5kYXJkTWV0YWRhdGFGb3JtYXRTdXBwb3J0ZWQ7CisgICAgICAgIHRoaXMubmF0aXZlTWV0YWRhdGFGb3JtYXROYW1lID0gbmF0aXZlTWV0YWRhdGFGb3JtYXROYW1lOworICAgICAgICB0aGlzLm5hdGl2ZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lID0gbmF0aXZlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWU7CisgICAgICAgIGlmIChleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGV4dHJhTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgImV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcyA9PSBudWxsICYmIGV4dHJhTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzICE9IG51bGwhIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiZXh0cmFNZXRhZGF0YUZvcm1hdE5hbWVzICE9IG51bGwgJiYgZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMgPT0gbnVsbCEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMubGVuZ3RoID09IDAhIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMubGVuZ3RoICE9IGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgImV4dHJhTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzLmxlbmd0aCAhPSBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMubGVuZ3RoISIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5leHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMgPSBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMuY2xvbmUoKTsKKyAgICAgICAgICAgIHRoaXMuZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMgPSBleHRyYU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcy5jbG9uZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWV0YWRhdGEgYXMgdHJlZS10eXBlIGRvY3VtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbm9kZSBpbiB0cmVlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTm9kZSBnZXRBc1RyZWUoU3RyaW5nIGZvcm1hdE5hbWUpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBtZXRhZGF0YSBpcyByZWFkIG9ubHkuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgbWV0YWRhdGEgaXMgcmVhZCBvbmx5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzUmVhZE9ubHkoKTsKKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0aGUgc3BlY2lmaWVkIHRyZWUgd2l0aCB0aGlzIG1ldGFkYXRhIHRyZWUuCisgICAgICogCisgICAgICogQHBhcmFtIGZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXQgb2YgdGhlIHNwZWNpZmllZCB0cmVlLgorICAgICAqIEBwYXJhbSByb290CisgICAgICogICAgICAgICAgICB0aGUgcm9vdCBub2RlIG9mIHRoZSBtZXRhZGF0YSB0cmVlLgorICAgICAqIEB0aHJvd3MgSUlPSW52YWxpZFRyZWVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHRyZWUgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhlIHRoaXMgbWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgICB0cmVlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG1lcmdlVHJlZShTdHJpbmcgZm9ybWF0TmFtZSwgTm9kZSByb290KSB0aHJvd3MgSUlPSW52YWxpZFRyZWVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIGNvbnRyb2xsZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVzZXQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbnRyb2xsZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbWV0YWRhdGEgZG9jdW1lbnQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY29udHJvbGxlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPTWV0YWRhdGFDb250cm9sbGVyIGdldENvbnRyb2xsZXIoKSB7CisgICAgICAgIHJldHVybiBjb250cm9sbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgbWV0YWRhdGEgaGFzIGEgY29udHJvbGxlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgbWV0YWRhdGEgaGFzIGEgY29udHJvbGxlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNDb250cm9sbGVyKCkgeworICAgICAgICByZXR1cm4gZ2V0Q29udHJvbGxlcigpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWN0aXZhdGUgdGhlIGNvbnRyb2xsZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFjdGl2YXRlQ29udHJvbGxlcigpIHsKKyAgICAgICAgaWYgKCFoYXNDb250cm9sbGVyKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImhhc0NvbnRyb2xsZXIoKSA9PSBmYWxzZSEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0Q29udHJvbGxlcigpLmFjdGl2YXRlKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgY29udHJvbGxlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IGNvbnRyb2xsZXIuCisgICAgICovCisgICAgcHVibGljIElJT01ldGFkYXRhQ29udHJvbGxlciBnZXREZWZhdWx0Q29udHJvbGxlcigpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRDb250cm9sbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGV4dHJhIG1ldGFkYXRhIGZvcm1hdCBuYW1lcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBleHRyYSBtZXRhZGF0YSBmb3JtYXQgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldEV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcyA9PSBudWxsID8gbnVsbCA6IGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9ybWF0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPTWV0YWRhdGFGb3JtYXQgZ2V0TWV0YWRhdGFGb3JtYXQoU3RyaW5nIGZvcm1hdE5hbWUpIHsKKyAgICAgICAgcmV0dXJuIElJT01ldGFkYXRhVXRpbHMuaW5zdGFudGlhdGVNZXRhZGF0YUZvcm1hdChmb3JtYXROYW1lLCBzdGFuZGFyZEZvcm1hdFN1cHBvcnRlZCwKKyAgICAgICAgICAgICAgICBuYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWUsIG5hdGl2ZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICAgICAgZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hdGl2ZSBtZXRhZGF0YSBmb3JtYXQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuYXRpdmUgbWV0YWRhdGEgZm9ybWF0IG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzdGFuZGFyZCBtZXRhZGF0YSBmb3JtYXQgaXMgc3VwcG9ydGVkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdCBpcyBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZGFyZE1ldGFkYXRhRm9ybWF0U3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gc3RhbmRhcmRGb3JtYXRTdXBwb3J0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIG1ldGFkYXRhIGZvcm1hdCBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TWV0YWRhdGFGb3JtYXROYW1lcygpIHsKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gcmVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgU3RyaW5nIG5hdGl2ZU1ldGFkYXRhRm9ybWF0TmFtZSA9IGdldE5hdGl2ZU1ldGFkYXRhRm9ybWF0TmFtZSgpOworICAgICAgICBib29sZWFuIHN0YW5kYXJkRm9ybWF0U3VwcG9ydGVkID0gaXNTdGFuZGFyZE1ldGFkYXRhRm9ybWF0U3VwcG9ydGVkKCk7CisgICAgICAgIFN0cmluZyBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXNbXSA9IGdldEV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcygpOworCisgICAgICAgIGlmIChzdGFuZGFyZEZvcm1hdFN1cHBvcnRlZCkgeworICAgICAgICAgICAgcmVzLmFkZChJSU9NZXRhZGF0YUZvcm1hdEltcGwuc3RhbmRhcmRNZXRhZGF0YUZvcm1hdE5hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChuYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzLmFkZChuYXRpdmVNZXRhZGF0YUZvcm1hdE5hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChTdHJpbmcgZXh0cmFNZXRhZGF0YUZvcm1hdE5hbWUgOiBleHRyYU1ldGFkYXRhRm9ybWF0TmFtZXMpIHsKKyAgICAgICAgICAgICAgICByZXMuYWRkKGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXMuc2l6ZSgpID4gMCA/IHJlcy50b0FycmF5KG5ldyBTdHJpbmdbMF0pIDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFuZGFyZCBjaHJvbWEgbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBjaHJvbWEgbm9kZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSUlPTWV0YWRhdGFOb2RlIGdldFN0YW5kYXJkQ2hyb21hTm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhbmRhcmQgY29tcHJlc3Npb24gbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBjb21wcmVzc2lvbiBub2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9NZXRhZGF0YU5vZGUgZ2V0U3RhbmRhcmRDb21wcmVzc2lvbk5vZGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHN0YW5kYXJkIGRhdGEgbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBkYXRhIG5vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT01ldGFkYXRhTm9kZSBnZXRTdGFuZGFyZERhdGFOb2RlKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFuZGFyZCBkaW1lbnNpb24gbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBkaW1lbnNpb24gbm9kZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSUlPTWV0YWRhdGFOb2RlIGdldFN0YW5kYXJkRGltZW5zaW9uTm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhbmRhcmQgZG9jdW1lbnQgbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBkb2N1bWVudCBub2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9NZXRhZGF0YU5vZGUgZ2V0U3RhbmRhcmREb2N1bWVudE5vZGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHN0YW5kYXJkIHRleHQgbm9kZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCB0ZXh0IG5vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT01ldGFkYXRhTm9kZSBnZXRTdGFuZGFyZFRleHROb2RlKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFuZGFyZCB0aWxlIG5vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RhbmRhcmQgdGlsZSBub2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBJSU9NZXRhZGF0YU5vZGUgZ2V0U3RhbmRhcmRUaWxlTm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhbmRhcmQgdHJhbnNwYXJlbmN5IG5vZGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RhbmRhcmQgdHJhbnNwYXJlbmN5IG5vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIElJT01ldGFkYXRhTm9kZSBnZXRTdGFuZGFyZFRyYW5zcGFyZW5jeU5vZGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIGFzIGEgdHJlZSBpbiBzdGFuZGFyZCBmb3JtYXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbWV0YWRhdGEgYXMgYSB0cmVlIGluIHN0YW5kYXJkIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgSUlPTWV0YWRhdGFOb2RlIGdldFN0YW5kYXJkVHJlZSgpIHsKKyAgICAgICAgLy8gQ3JlYXRlIHJvb3Qgbm9kZQorICAgICAgICBJSU9NZXRhZGF0YU5vZGUgcm9vdCA9IG5ldyBJSU9NZXRhZGF0YU5vZGUoSUlPTWV0YWRhdGFGb3JtYXRJbXBsLnN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lKTsKKworICAgICAgICBOb2RlIG5vZGU7CisgICAgICAgIGlmICgobm9kZSA9IGdldFN0YW5kYXJkQ2hyb21hTm9kZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByb290LmFwcGVuZENoaWxkKG5vZGUpOworICAgICAgICB9CisgICAgICAgIGlmICgobm9kZSA9IGdldFN0YW5kYXJkQ29tcHJlc3Npb25Ob2RlKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQobm9kZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChub2RlID0gZ2V0U3RhbmRhcmREYXRhTm9kZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByb290LmFwcGVuZENoaWxkKG5vZGUpOworICAgICAgICB9CisgICAgICAgIGlmICgobm9kZSA9IGdldFN0YW5kYXJkRGltZW5zaW9uTm9kZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByb290LmFwcGVuZENoaWxkKG5vZGUpOworICAgICAgICB9CisgICAgICAgIGlmICgobm9kZSA9IGdldFN0YW5kYXJkRG9jdW1lbnROb2RlKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQobm9kZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChub2RlID0gZ2V0U3RhbmRhcmRUZXh0Tm9kZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByb290LmFwcGVuZENoaWxkKG5vZGUpOworICAgICAgICB9CisgICAgICAgIGlmICgobm9kZSA9IGdldFN0YW5kYXJkVGlsZU5vZGUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChub2RlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG5vZGUgPSBnZXRTdGFuZGFyZFRyYW5zcGFyZW5jeU5vZGUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChub2RlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByb290OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbnRyb2xsZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbnRyb2xsZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgY29udHJvbGxlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250cm9sbGVyKElJT01ldGFkYXRhQ29udHJvbGxlciBjb250cm9sbGVyKSB7CisgICAgICAgIHRoaXMuY29udHJvbGxlciA9IGNvbnRyb2xsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZnJvbSB0cmVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbWV0YXRkYXRhIGZvcm1hdCBvZiB0aGUgZnJvbSB0cmVlLgorICAgICAqIEBwYXJhbSByb290CisgICAgICogICAgICAgICAgICB0aGUgcm9vdCBub2RlIG9mIHRoZSBmcm9tIHRyZWUuCisgICAgICogQHRocm93cyBJSU9JbnZhbGlkVHJlZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0cmVlIG9yIGl0cyBmb3JtYXQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzCisgICAgICogICAgICAgICAgICAgbWV0YWRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RnJvbVRyZWUoU3RyaW5nIGZvcm1hdE5hbWUsIE5vZGUgcm9vdCkgdGhyb3dzIElJT0ludmFsaWRUcmVlRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgbWVyZ2VUcmVlKGZvcm1hdE5hbWUsIHJvb3QpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhQ29udHJvbGxlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFDb250cm9sbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQwNTk0OAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhQ29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLm1ldGFkYXRhOworCisvKiAKKyAqIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworLyoqCisgKiBUaGUgSUlPTWV0YWRhdGFDb250cm9sbGVyIGludGVyZmFjZSBwcm92aWRlcyBhIG1ldGhvZCBmb3IgaW1wbGVtZW50aW5nCisgKiBvYmplY3RzIHRvIGFjdGl2YXRlIHRoZSBjb250cm9sbGVyIHdpdGhvdXQgZGVmaW5pbmcgaG93IHRoZSBjb250cm9sbGVyCisgKiBvYnRhaW5zIHZhbHVlcy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUlPTWV0YWRhdGFDb250cm9sbGVyIHsKKworICAgIC8qKgorICAgICAqIEFjdGl2YXRlcyBhIGNvbnRyb2xsZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG1ldGFkYXRhCisgICAgICogICAgICAgICAgICB0aGUgbWV0YWRhdGEgdG8gYmUgbW9kaWZpZWQuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgSUlPTWV0YWRhdGEgaGFzIGJlZW4gbW9kaWZpZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhY3RpdmF0ZShJSU9NZXRhZGF0YSBtZXRhZGF0YSk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YUZvcm1hdC5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTdlNjk3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFGb3JtYXQuamF2YQpAQCAtMCwwICsxLDQwNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLm1ldGFkYXRhOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVR5cGVTcGVjaWZpZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworLyoqCisgKiBUaGUgSW50ZXJmYWNlIElJT01ldGFkYXRhRm9ybWF0IGlzIGltcGxlbWVudGVkIGJ5IGNsYXNzZXMgdGhhdCBkZXNjcmliZSB0aGUKKyAqIHJ1bGVzIGFuZCBhbGxvd2VkIGVsZW1lbnRzIGZvciBhIG1ldGFkYXRhIGRvY3VtZW50IHRyZWUuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgaW50ZXJmYWNlIElJT01ldGFkYXRhRm9ybWF0IHsKKworICAgIC8qKgorICAgICAqIFRoZSBDSElMRF9QT0xJQ1lfRU1QVFkuCisgICAgICovCisgICAgaW50IENISUxEX1BPTElDWV9FTVBUWSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ0hJTERfUE9MSUNZX0FMTC4KKyAgICAgKi8KKyAgICBpbnQgQ0hJTERfUE9MSUNZX0FMTCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ0hJTERfUE9MSUNZX1NPTUUuCisgICAgICovCisgICAgaW50IENISUxEX1BPTElDWV9TT01FID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDSElMRF9QT0xJQ1lfQ0hPSUNFLgorICAgICAqLworICAgIGludCBDSElMRF9QT0xJQ1lfQ0hPSUNFID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSBDSElMRF9QT0xJQ1lfU0VRVUVOQ0UuCisgICAgICovCisgICAgaW50IENISUxEX1BPTElDWV9TRVFVRU5DRSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ0hJTERfUE9MSUNZX1JFUEVBVC4KKyAgICAgKi8KKyAgICBpbnQgQ0hJTERfUE9MSUNZX1JFUEVBVCA9IDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBmb3IgdGhlIGNoaWxkIHBvbGljeS4KKyAgICAgKi8KKyAgICBpbnQgQ0hJTERfUE9MSUNZX01BWCA9IENISUxEX1BPTElDWV9SRVBFQVQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgREFUQVRZUEVfU1RSSU5HLgorICAgICAqLworICAgIGludCBEQVRBVFlQRV9TVFJJTkcgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIERBVEFUWVBFX0JPT0xFQU4uCisgICAgICovCisgICAgaW50IERBVEFUWVBFX0JPT0xFQU4gPSAxOworCisgICAgLyoqCisgICAgICogVGhlIERBVEFUWVBFX0lOVEVHRVIuCisgICAgICovCisgICAgaW50IERBVEFUWVBFX0lOVEVHRVIgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIERBVEFUWVBFX0ZMT0FULgorICAgICAqLworICAgIGludCBEQVRBVFlQRV9GTE9BVCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgREFUQVRZUEVfRE9VQkxFLgorICAgICAqLworICAgIGludCBEQVRBVFlQRV9ET1VCTEUgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIFZBTFVFX05PTkUuCisgICAgICovCisgICAgaW50IFZBTFVFX05PTkUgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIFZBTFVFX0FSQklUUkFSWS4KKyAgICAgKi8KKyAgICBpbnQgVkFMVUVfQVJCSVRSQVJZID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBWQUxVRV9SQU5HRS4KKyAgICAgKi8KKyAgICBpbnQgVkFMVUVfUkFOR0UgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIFZBTFVFX1JBTkdFX01JTl9JTkNMVVNJVkVfTUFTSy4KKyAgICAgKi8KKyAgICBpbnQgVkFMVUVfUkFOR0VfTUlOX0lOQ0xVU0lWRV9NQVNLID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFX01BU0suCisgICAgICovCisgICAgaW50IFZBTFVFX1JBTkdFX01BWF9JTkNMVVNJVkVfTUFTSyA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVkFMVUVfRU5VTUVSQVRJT04uCisgICAgICovCisgICAgaW50IFZBTFVFX0VOVU1FUkFUSU9OID0gMTY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVkFMVUVfTElTVC4KKyAgICAgKi8KKyAgICBpbnQgVkFMVUVfTElTVCA9IDMyOworCisgICAgLyoqCisgICAgICogVGhlIFZBTFVFX1JBTkdFX01JTl9JTkNMVVNJVkUuCisgICAgICovCisgICAgaW50IFZBTFVFX1JBTkdFX01JTl9JTkNMVVNJVkUgPSBWQUxVRV9SQU5HRSB8IFZBTFVFX1JBTkdFX01JTl9JTkNMVVNJVkVfTUFTSzsKKworICAgIC8qKgorICAgICAqIFRoZSBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFLgorICAgICAqLworICAgIGludCBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFID0gVkFMVUVfUkFOR0UgfCBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFX01BU0s7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVkFMVUVfUkFOR0VfTUlOX01BWF9JTkNMVVNJVkUuCisgICAgICovCisgICAgaW50IFZBTFVFX1JBTkdFX01JTl9NQVhfSU5DTFVTSVZFID0gVkFMVUVfUkFOR0UgfCBWQUxVRV9SQU5HRV9NSU5fSU5DTFVTSVZFX01BU0sKKyAgICAgICAgICAgIHwgVkFMVUVfUkFOR0VfTUFYX0lOQ0xVU0lWRV9NQVNLOworCisgICAgLyoqCisgICAgICogVGVsbHMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgYWxsb3dlZCBmb3IgdGhlIHNwZWNpZmllZCBpbWFnZQorICAgICAqIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBpbWFnZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbWFnZSB0eXBlLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIGFsbG93ZWQgZm9yIHRoZSBzcGVjaWZpZWQgaW1hZ2UKKyAgICAgKiAgICAgICAgIHR5cGUuCisgICAgICovCisgICAgYm9vbGVhbiBjYW5Ob2RlQXBwZWFyKFN0cmluZyBlbGVtZW50TmFtZSwgSW1hZ2VUeXBlU3BlY2lmaWVyIGltYWdlVHlwZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGRhdGEgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSdzIGRhdGEgdHlwZS4KKyAgICAgKi8KKyAgICBpbnQgZ2V0QXR0cmlidXRlRGF0YVR5cGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlJ3MgZGVmYXVsdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0QXR0cmlidXRlRGVmYXVsdFZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVzZXItZnJpZW5kbHkgZGVzY3JpcHRpb24gb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSBnaXZpbmcgdGhlIGRlc2lyZWQgbGFuZ3VhZ2UgZm9yIHRoZSBkZXNjcmlwdGlvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUgZGVzY3JpcHRpb24uCisgICAgICovCisgICAgU3RyaW5nIGdldEF0dHJpYnV0ZURlc2NyaXB0aW9uKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lLCBMb2NhbGUgbG9jYWxlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGF0dHJpYnV0ZSBlbnVtZXJhdGlvbnMuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSBlbnVtZXJhdGlvbnMuCisgICAgICovCisgICAgU3RyaW5nW10gZ2V0QXR0cmlidXRlRW51bWVyYXRpb25zKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGUgbGlzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgdGhlIGF0dHJpYnV0ZSBsaXN0LgorICAgICAqLworICAgIGludCBnZXRBdHRyaWJ1dGVMaXN0TWF4TGVuZ3RoKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0gbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGUgbGlzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSBsZW5ndGggb2YgdGhlIGF0dHJpYnV0ZSBsaXN0LgorICAgICAqLworICAgIGludCBnZXRBdHRyaWJ1dGVMaXN0TWluTGVuZ3RoKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gdmFsdWUgYWxsb3dlZCBmb3IgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSB2YWx1ZSBhbGxvd2VkIGZvciB0aGUgYXR0cmlidXRlLgorICAgICAqLworICAgIFN0cmluZyBnZXRBdHRyaWJ1dGVNYXhWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHZhbHVlIGFsbG93ZWQgZm9yIHRoZSBhdHRyaWJ1dGUuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gdmFsdWUgYWxsb3dlZCBmb3IgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0QXR0cmlidXRlTWluVmFsdWUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXR0cmlidXRlIG5hbWVzIGFsbG93ZWQgZm9yIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlIG5hbWVzLgorICAgICAqLworICAgIFN0cmluZ1tdIGdldEF0dHJpYnV0ZU5hbWVzKFN0cmluZyBlbGVtZW50TmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhdHRyaWJ1dGUgdmFsdWUgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlIHZhbHVlIHR5cGUuCisgICAgICovCisgICAgaW50IGdldEF0dHJpYnV0ZVZhbHVlVHlwZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBpcyByZXF1aXJlZCBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgaXMgcmVxdWlyZWQgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGVsZW1lbnQuCisgICAgICovCisgICAgYm9vbGVhbiBpc0F0dHJpYnV0ZVJlcXVpcmVkKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWVzIG9mIHRoZSBwb3NzaWJsZSBjaGlsZCBlbGVtZW50cyBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGNoaWxkIG5hbWVzLgorICAgICAqLworICAgIFN0cmluZ1tdIGdldENoaWxkTmFtZXMoU3RyaW5nIGVsZW1lbnROYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIGVsZW1lbnQncyBjaGlsZCBwb2xpY3kuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGNoaWxkIHBvbGljeS4KKyAgICAgKi8KKyAgICBpbnQgZ2V0Q2hpbGRQb2xpY3koU3RyaW5nIGVsZW1lbnROYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVzZXItZnJpZW5kbHkgZGVzY3JpcHRpb24gb2YgdGhlIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgZ2l2aW5nIHRoZSBkZXNpcmVkIGxhbmd1YWdlIGZvciB0aGUgZGVzY3JpcHRpb24uCisgICAgICogQHJldHVybiB0aGUgZWxlbWVudCBkZXNjcmlwdGlvbi4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0RWxlbWVudERlc2NyaXB0aW9uKFN0cmluZyBlbGVtZW50TmFtZSwgTG9jYWxlIGxvY2FsZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGlsZHJlbiBhbGxvd2VkIGZvciB0aGUgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hpbGRyZW4gYWxsb3dlZCBmb3IgdGhlIGVsZW1lbnQuCisgICAgICovCisgICAgaW50IGdldEVsZW1lbnRNYXhDaGlsZHJlbihTdHJpbmcgZWxlbWVudE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSBudW1iZXIgb2YgY2hpbGRyZW4gYWxsb3dlZCBmb3IgdGhlIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gbnVtYmVyIG9mIGNoaWxkcmVuIGFsbG93ZWQgZm9yIHRoZSBlbGVtZW50LgorICAgICAqLworICAgIGludCBnZXRFbGVtZW50TWluQ2hpbGRyZW4oU3RyaW5nIGVsZW1lbnROYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gb2JqZWN0IGFycmF5IGxlbmd0aCBhbGxvd2VkIGZvciB0aGUgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBvYmplY3QgYXJyYXkgbGVuZ3RoIGFsbG93ZWQgZm9yIHRoZSBlbGVtZW50LgorICAgICAqLworICAgIGludCBnZXRPYmplY3RBcnJheU1heExlbmd0aChTdHJpbmcgZWxlbWVudE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSBvYmplY3QgYXJyYXkgbGVuZ3RoIGFsbG93ZWQgZm9yIHRoZSBlbGVtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIG9iamVjdCBhcnJheSBsZW5ndGggYWxsb3dlZCBmb3IgdGhlIGVsZW1lbnQuCisgICAgICovCisgICAgaW50IGdldE9iamVjdEFycmF5TWluTGVuZ3RoKFN0cmluZyBlbGVtZW50TmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvYmplY3QgY2xhc3MgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKi8KKyAgICBDbGFzczw/PiBnZXRPYmplY3RDbGFzcyhTdHJpbmcgZWxlbWVudE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2JqZWN0IGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBlbGVtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3QgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGVsZW1lbnQuCisgICAgICovCisgICAgT2JqZWN0IGdldE9iamVjdERlZmF1bHRWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2JqZWN0IGVudW1lcmF0aW9ucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IGVudW1lcmF0aW9ucy4KKyAgICAgKi8KKyAgICBPYmplY3RbXSBnZXRPYmplY3RFbnVtZXJhdGlvbnMoU3RyaW5nIGVsZW1lbnROYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gdmFsdWUgYWxsb3dlZCBmb3IgdGhlIGVsZW1lbnQncyBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gdmFsdWUgYWxsb3dlZCBmb3IgdGhlIGVsZW1lbnQncyBvYmplY3QuCisgICAgICovCisgICAgQ29tcGFyYWJsZTw/PiBnZXRPYmplY3RNYXhWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSB2YWx1ZSBhbGxvd2VkIGZvciB0aGUgZWxlbWVudCdzIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSB2YWx1ZSBhbGxvd2VkIGZvciB0aGUgZWxlbWVudCdzIG9iamVjdC4KKyAgICAgKi8KKyAgICBDb21wYXJhYmxlPD8+IGdldE9iamVjdE1pblZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb25zdGFudCB0aGF0IGluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudCdzIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb25zdGFudCB0aGF0IGluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudCdzIHZhbHVlLgorICAgICAqLworICAgIGludCBnZXRPYmplY3RWYWx1ZVR5cGUoU3RyaW5nIGVsZW1lbnROYW1lKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCisgICAgICovCisgICAgU3RyaW5nIGdldFJvb3ROYW1lKCk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YUZvcm1hdEltcGwuamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhRm9ybWF0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhNmU1NjgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YUZvcm1hdEltcGwuamF2YQpAQCAtMCwwICsxLDEwNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5tZXRhZGF0YTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VUeXBlU3BlY2lmaWVyOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CisKKy8qKgorICogVGhlIElJT01ldGFkYXRhRm9ybWF0SW1wbCBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKKyAqIElJT01ldGFkYXRhRm9ybWF0IGludGVyZmFjZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJSU9NZXRhZGF0YUZvcm1hdEltcGwgaW1wbGVtZW50cyBJSU9NZXRhZGF0YUZvcm1hdCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgc3RhbmRhcmRNZXRhZGF0YUZvcm1hdE5hbWUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsKKyAgICAgICAgIkNvbnN0YW50RGVjbGFyZWRJbkFic3RyYWN0Q2xhc3MiCisgICAgfSkKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzdGFuZGFyZE1ldGFkYXRhRm9ybWF0TmFtZSA9ICJqYXZheF9pbWFnZWlvXzEuMCI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RhbmRhcmQgZm9ybWF0LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCB7CisgICAgICAgICJTdGF0aWNOb25GaW5hbEZpZWxkIgorICAgIH0pCisgICAgcHJpdmF0ZSBzdGF0aWMgSUlPTWV0YWRhdGFGb3JtYXRJbXBsIHN0YW5kYXJkRm9ybWF0OworCisgICAgLyoqCisgICAgICogVGhlIHJvb3QgbmFtZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByb290TmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbGVtZW50IGhhc2guCisgICAgICovCisgICAgcHJpdmF0ZSBIYXNoTWFwPFN0cmluZywgRWxlbWVudD4gZWxlbWVudEhhc2ggPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEVsZW1lbnQ+KCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVzb3VyY2UgYmFzZSBuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlc291cmNlQmFzZU5hbWUgPSBnZXRDbGFzcygpLmdldE5hbWUoKSArICJSZXNvdXJjZXMiOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGFuIElJT01ldGFkYXRhRm9ybWF0SW1wbCB3aXRoIHRoZSBzcGVjaWZpZWQgcm9vdCBuYW1lIGFuZAorICAgICAqIGNoaWxkIHBvbGljeSAobm90IENISUxEX1BPTElDWV9SRVBFQVQpLgorICAgICAqIAorICAgICAqIEBwYXJhbSByb290TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2Ygcm9vdCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBjaGlsZFBvbGljeQorICAgICAqICAgICAgICAgICAgdGhlIGNoaWxkIHBvbGljeSBkZWZpbmVkIGJ5IG9uZSBvZiB0aGUgQ0hJTERfUE9MSUNZXyoKKyAgICAgKiAgICAgICAgICAgIGNvbnN0YW50cyAoZXhjZXB0IENISUxEX1BPTElDWV9SRVBFQVQpLgorICAgICAqLworICAgIHB1YmxpYyBJSU9NZXRhZGF0YUZvcm1hdEltcGwoU3RyaW5nIHJvb3ROYW1lLCBpbnQgY2hpbGRQb2xpY3kpIHsKKyAgICAgICAgaWYgKHJvb3ROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJvb3ROYW1lIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hpbGRQb2xpY3kgPCBDSElMRF9QT0xJQ1lfRU1QVFkgfHwgY2hpbGRQb2xpY3kgPiBDSElMRF9QT0xJQ1lfTUFYCisgICAgICAgICAgICAgICAgfHwgY2hpbGRQb2xpY3kgPT0gQ0hJTERfUE9MSUNZX1JFUEVBVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2hpbGRQb2xpY3kgaXMgbm90IG9uZSBvZiB0aGUgcHJlZGVmaW5lZCBjb25zdGFudHMiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMucm9vdE5hbWUgPSByb290TmFtZTsKKyAgICAgICAgRWxlbWVudCByb290ID0gbmV3IEVsZW1lbnQoKTsKKyAgICAgICAgcm9vdC5uYW1lID0gcm9vdE5hbWU7CisgICAgICAgIHJvb3QuY2hpbGRQb2xpY3kgPSBjaGlsZFBvbGljeTsKKyAgICAgICAgZWxlbWVudEhhc2gucHV0KHJvb3ROYW1lLCByb290KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYW4gSUlPTWV0YWRhdGFGb3JtYXRJbXBsIHdpdGggdGhlIHNwZWNpZmllZCByb290IG5hbWUgYW5kCisgICAgICogQ0hJTERfUE9MSUNZX1JFUEVBVCBjaGlsZCBwb2xpY3kuCisgICAgICogCisgICAgICogQHBhcmFtIHJvb3ROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiByb290IGVsZW1lbnQuCisgICAgICogQHBhcmFtIG1pbkNoaWxkcmVuCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBudW1iZXIgb2YgY2hpbGRyZW4uCisgICAgICogQHBhcmFtIG1heENoaWxkcmVuCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hpbGRyZW4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUlPTWV0YWRhdGFGb3JtYXRJbXBsKFN0cmluZyByb290TmFtZSwgaW50IG1pbkNoaWxkcmVuLCBpbnQgbWF4Q2hpbGRyZW4pIHsKKyAgICAgICAgaWYgKHJvb3ROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJvb3ROYW1lIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWluQ2hpbGRyZW4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJtaW5DaGlsZHJlbiA8IDAhIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1pbkNoaWxkcmVuID4gbWF4Q2hpbGRyZW4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1pbkNoaWxkcmVuID4gbWF4Q2hpbGRyZW4hIik7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnJvb3ROYW1lID0gcm9vdE5hbWU7CisgICAgICAgIEVsZW1lbnQgcm9vdCA9IG5ldyBFbGVtZW50KCk7CisgICAgICAgIHJvb3QubmFtZSA9IHJvb3ROYW1lOworICAgICAgICByb290Lm1pbkNoaWxkcmVuID0gbWluQ2hpbGRyZW47CisgICAgICAgIHJvb3QubWF4Q2hpbGRyZW4gPSBtYXhDaGlsZHJlbjsKKyAgICAgICAgcm9vdC5jaGlsZFBvbGljeSA9IENISUxEX1BPTElDWV9SRVBFQVQ7CisgICAgICAgIGVsZW1lbnRIYXNoLnB1dChyb290TmFtZSwgcm9vdCk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsKKyAgICAgICAgIkFic3RyYWN0TWV0aG9kT3ZlcnJpZGVzQWJzdHJhY3RNZXRob2QiCisgICAgfSkKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjYW5Ob2RlQXBwZWFyKFN0cmluZyBlbGVtZW50TmFtZSwgSW1hZ2VUeXBlU3BlY2lmaWVyIGltYWdlVHlwZSk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZSB0byBhbiBleGlzdGluZyBlbGVtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIG5ldyBhdHRyaWJ1dGUgd2lsbCBiZQorICAgICAqICAgICAgICAgICAgYWRkZWQuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHRoZSBuZXcgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSByZXF1aXJlZAorICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBhdHRyaWJ1dGUgbXVzdCBiZQorICAgICAqICAgICAgICAgICAgcHJlc2VudC4KKyAgICAgKiBAcGFyYW0gbGlzdE1pbkxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG1pbmltdW0gbGVnYWwgbnVtYmVyIG9mIGxpc3QgaXRlbXMuCisgICAgICogQHBhcmFtIGxpc3RNYXhMZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aGUgbWF4aW11bSBsZWdhbCBudW1iZXIgb2YgbGlzdCBpdGVtcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUsIGludCBkYXRhVHlwZSwKKyAgICAgICAgICAgIGJvb2xlYW4gcmVxdWlyZWQsIGludCBsaXN0TWluTGVuZ3RoLCBpbnQgbGlzdE1heExlbmd0aCkgeworICAgICAgICBpZiAoYXR0ck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYXR0ck5hbWUgPT0gbnVsbCEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGF0YVR5cGUgPCBEQVRBVFlQRV9TVFJJTkcgfHwgZGF0YVR5cGUgPiBEQVRBVFlQRV9ET1VCTEUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgdmFsdWUgZm9yIGRhdGFUeXBlISIpOworICAgICAgICB9CisgICAgICAgIGlmIChsaXN0TWluTGVuZ3RoIDwgMCB8fCBsaXN0TWluTGVuZ3RoID4gbGlzdE1heExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBsaXN0IGJvdW5kcyEiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgQXR0bGlzdCBhdHRyID0gbmV3IEF0dGxpc3QoKTsKKyAgICAgICAgYXR0ci5uYW1lID0gYXR0ck5hbWU7CisgICAgICAgIGF0dHIuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgYXR0ci5yZXF1aXJlZCA9IHJlcXVpcmVkOworICAgICAgICBhdHRyLmxpc3RNaW5MZW5ndGggPSBsaXN0TWluTGVuZ3RoOworICAgICAgICBhdHRyLmxpc3RNYXhMZW5ndGggPSBsaXN0TWF4TGVuZ3RoOworICAgICAgICBhdHRyLnZhbHVlVHlwZSA9IFZBTFVFX0xJU1Q7CisKKyAgICAgICAgZWxlbWVudC5hdHRyaWJ1dGVzLnB1dChhdHRyTmFtZSwgYXR0cik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBhdHRyaWJ1dGUgdG8gYW4gZXhpc3RpbmcgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSBuZXcgYXR0cmlidXRlIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGFkZGVkLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiB0aGUgbmV3IGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gcmVxdWlyZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIG11c3QgYmUKKyAgICAgKiAgICAgICAgICAgIHByZXNlbnQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUsIGludCBkYXRhVHlwZSwKKyAgICAgICAgICAgIGJvb2xlYW4gcmVxdWlyZWQsIFN0cmluZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgaWYgKGF0dHJOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImF0dHJOYW1lID09IG51bGwhIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRhdGFUeXBlIDwgREFUQVRZUEVfU1RSSU5HIHx8IGRhdGFUeXBlID4gREFUQVRZUEVfRE9VQkxFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHZhbHVlIGZvciBkYXRhVHlwZSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgQXR0bGlzdCBhdHRyID0gbmV3IEF0dGxpc3QoKTsKKyAgICAgICAgYXR0ci5uYW1lID0gYXR0ck5hbWU7CisgICAgICAgIGF0dHIuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgYXR0ci5yZXF1aXJlZCA9IHJlcXVpcmVkOworICAgICAgICBhdHRyLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgYXR0ci52YWx1ZVR5cGUgPSBWQUxVRV9BUkJJVFJBUlk7CisKKyAgICAgICAgZWxlbWVudC5hdHRyaWJ1dGVzLnB1dChhdHRyTmFtZSwgYXR0cik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBhdHRyaWJ1dGUgdG8gYW4gZXhpc3RpbmcgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSBuZXcgYXR0cmlidXRlIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGFkZGVkLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEBwYXJhbSBkYXRhVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgdHlwZSBvZiB0aGUgbmV3IGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gcmVxdWlyZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIG11c3QgYmUKKyAgICAgKiAgICAgICAgICAgIHByZXNlbnQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gZW51bWVyYXRlZFZhbHVlcworICAgICAqICAgICAgICAgICAgdGhlIGxlZ2FsIHZhbHVlcyBmb3IgdGhlIGF0dHJpYnV0ZSBhcyBhIGxpc3Qgb2Ygc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUsIGludCBkYXRhVHlwZSwKKyAgICAgICAgICAgIGJvb2xlYW4gcmVxdWlyZWQsIFN0cmluZyBkZWZhdWx0VmFsdWUsIExpc3Q8U3RyaW5nPiBlbnVtZXJhdGVkVmFsdWVzKSB7CisgICAgICAgIGlmIChhdHRyTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhdHRyTmFtZSA9PSBudWxsISIpOworICAgICAgICB9CisgICAgICAgIGlmIChkYXRhVHlwZSA8IERBVEFUWVBFX1NUUklORyB8fCBkYXRhVHlwZSA+IERBVEFUWVBFX0RPVUJMRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCB2YWx1ZSBmb3IgZGF0YVR5cGUhIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVudW1lcmF0ZWRWYWx1ZXMgPT0gbnVsbCB8fCBlbnVtZXJhdGVkVmFsdWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW51bWVyYXRlZFZhbHVlcyBpcyBlbXB0eSBvciBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChTdHJpbmcgZW51bWVyYXRlZFZhbHVlIDogZW51bWVyYXRlZFZhbHVlcykgeworICAgICAgICAgICAgICAgIGlmIChlbnVtZXJhdGVkVmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJlbnVtZXJhdGVkVmFsdWVzIGNvbnRhaW5zIGEgbnVsbCEiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJlbnVtZXJhdGVkVmFsdWVzIGNvbnRhaW5zIGEgbm9uLVN0cmluZyB2YWx1ZSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgQXR0bGlzdCBhdHRyID0gbmV3IEF0dGxpc3QoKTsKKyAgICAgICAgYXR0ci5uYW1lID0gYXR0ck5hbWU7CisgICAgICAgIGF0dHIuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgYXR0ci5yZXF1aXJlZCA9IHJlcXVpcmVkOworICAgICAgICBhdHRyLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgYXR0ci5lbnVtZXJhdGVkVmFsdWVzID0gZW51bWVyYXRlZFZhbHVlczsKKyAgICAgICAgYXR0ci52YWx1ZVR5cGUgPSBWQUxVRV9FTlVNRVJBVElPTjsKKworICAgICAgICBlbGVtZW50LmF0dHJpYnV0ZXMucHV0KGF0dHJOYW1lLCBhdHRyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZSB0byBhbiBleGlzdGluZyBlbGVtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIG5ldyBhdHRyaWJ1dGUgd2lsbCBiZQorICAgICAqICAgICAgICAgICAgYWRkZWQuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHBhcmFtIGRhdGFUeXBlCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0eXBlIG9mIHRoZSBuZXcgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSByZXF1aXJlZAorICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBhdHRyaWJ1dGUgbXVzdCBiZQorICAgICAqICAgICAgICAgICAgcHJlc2VudC4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIG1pblZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBsZWdhbCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIG1heFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBsZWdhbCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIG1pbkluY2x1c2l2ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlIG1pblZhbHVlIGlzIGluY2x1c2l2ZS4KKyAgICAgKiBAcGFyYW0gbWF4SW5jbHVzaXZlCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgbWF4VmFsdWUgaXMgaW5jbHVzaXZlLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSwgaW50IGRhdGFUeXBlLAorICAgICAgICAgICAgYm9vbGVhbiByZXF1aXJlZCwgU3RyaW5nIGRlZmF1bHRWYWx1ZSwgU3RyaW5nIG1pblZhbHVlLCBTdHJpbmcgbWF4VmFsdWUsCisgICAgICAgICAgICBib29sZWFuIG1pbkluY2x1c2l2ZSwgYm9vbGVhbiBtYXhJbmNsdXNpdmUpIHsKKyAgICAgICAgaWYgKGF0dHJOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImF0dHJOYW1lID09IG51bGwhIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRhdGFUeXBlIDwgREFUQVRZUEVfU1RSSU5HIHx8IGRhdGFUeXBlID4gREFUQVRZUEVfRE9VQkxFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHZhbHVlIGZvciBkYXRhVHlwZSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgQXR0bGlzdCBhdHRyID0gbmV3IEF0dGxpc3QoKTsKKyAgICAgICAgYXR0ci5uYW1lID0gYXR0ck5hbWU7CisgICAgICAgIGF0dHIuZGF0YVR5cGUgPSBkYXRhVHlwZTsKKyAgICAgICAgYXR0ci5yZXF1aXJlZCA9IHJlcXVpcmVkOworICAgICAgICBhdHRyLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgYXR0ci5taW5WYWx1ZSA9IG1pblZhbHVlOworICAgICAgICBhdHRyLm1heFZhbHVlID0gbWF4VmFsdWU7CisgICAgICAgIGF0dHIubWluSW5jbHVzaXZlID0gbWluSW5jbHVzaXZlOworICAgICAgICBhdHRyLm1heEluY2x1c2l2ZSA9IG1heEluY2x1c2l2ZTsKKworICAgICAgICBhdHRyLnZhbHVlVHlwZSA9IFZBTFVFX1JBTkdFOworICAgICAgICBhdHRyLnZhbHVlVHlwZSB8PSBtaW5JbmNsdXNpdmUgPyBWQUxVRV9SQU5HRV9NSU5fSU5DTFVTSVZFX01BU0sgOiAwOworICAgICAgICBhdHRyLnZhbHVlVHlwZSB8PSBtYXhJbmNsdXNpdmUgPyBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFX01BU0sgOiAwOworCisgICAgICAgIGVsZW1lbnQuYXR0cmlidXRlcy5wdXQoYXR0ck5hbWUsIGF0dHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgYXR0cmlidXRlIHdpdGggYm9vbGVhbiBkYXRhIHR5cGUgdG8gYW4gZXhpc3RpbmcgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSBuZXcgYXR0cmlidXRlIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGFkZGVkLgorICAgICAqIEBwYXJhbSBhdHRyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEBwYXJhbSBoYXNEZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIG11c3QgaGF2ZSBhCisgICAgICogICAgICAgICAgICBkZWZhdWx0IHZhbHVlLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZEJvb2xlYW5BdHRyaWJ1dGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUsCisgICAgICAgICAgICBib29sZWFuIGhhc0RlZmF1bHRWYWx1ZSwgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgU3RyaW5nIGRlZmF1bHRWYWwgPSBoYXNEZWZhdWx0VmFsdWUgPyAoZGVmYXVsdFZhbHVlID8gIlRSVUUiIDogIkZBTFNFIikgOiBudWxsOworICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiB2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oMik7CisgICAgICAgIHZhbHVlcy5hZGQoIlRSVUUiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiRkFMU0UiKTsKKworICAgICAgICBhZGRBdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJOYW1lLCBEQVRBVFlQRV9CT09MRUFOLCB0cnVlLCBkZWZhdWx0VmFsLCB2YWx1ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gZXhpc3RpbmcgZWxlbWVudCB0byB0aGUgbGlzdCBvZiBjaGlsZCBlbGVtZW50cyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogcGFyZW50IGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0byBiZSBhZGRlZC4KKyAgICAgKiBAcGFyYW0gcGFyZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmVudCBlbGVtZW50IG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWRkQ2hpbGRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIHBhcmVudE5hbWUpIHsKKyAgICAgICAgRWxlbWVudCBwYXJlbnQgPSBmaW5kRWxlbWVudChwYXJlbnROYW1lKTsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworICAgICAgICBwYXJlbnQuY2hpbGRyZW4uYWRkKGVsZW1lbnQubmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBlbGVtZW50IHR5cGUgdG8gdGhpcyBJSU9NZXRhZGF0YUZvcm1hdCB3aXRoIGEgY2hpbGQgcG9saWN5IChpZgorICAgICAqIHBvbGljeSBpcyBub3QgQ0hJTERfUE9MSUNZX1JFUEVBVCkuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0byBiZSBhZGRlZC4KKyAgICAgKiBAcGFyYW0gcGFyZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmVudCBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGNoaWxkUG9saWN5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIENISUxEX1BPTElDWV8qIGNvbnN0YW50cyBkZWZpbmVkIGJ5CisgICAgICogICAgICAgICAgICBJSU9NZXRhZGF0YUZvcm1hdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIHBhcmVudE5hbWUsIGludCBjaGlsZFBvbGljeSkgeworICAgICAgICBpZiAoY2hpbGRQb2xpY3kgPCBDSElMRF9QT0xJQ1lfRU1QVFkgfHwgY2hpbGRQb2xpY3kgPiBDSElMRF9QT0xJQ1lfTUFYCisgICAgICAgICAgICAgICAgfHwgY2hpbGRQb2xpY3kgPT0gQ0hJTERfUE9MSUNZX1JFUEVBVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2hpbGRQb2xpY3kgaXMgbm90IG9uZSBvZiB0aGUgcHJlZGVmaW5lZCBjb25zdGFudHMiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgcGFyZW50ID0gZmluZEVsZW1lbnQocGFyZW50TmFtZSk7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IG5ldyBFbGVtZW50KCk7CisgICAgICAgIGVsZW1lbnQubmFtZSA9IGVsZW1lbnROYW1lOworICAgICAgICBlbGVtZW50LmNoaWxkUG9saWN5ID0gY2hpbGRQb2xpY3k7CisgICAgICAgIGVsZW1lbnRIYXNoLnB1dChlbGVtZW50TmFtZSwgZWxlbWVudCk7CisgICAgICAgIHBhcmVudC5jaGlsZHJlbi5hZGQoZWxlbWVudE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgZWxlbWVudCB0eXBlIHRvIHRoaXMgSUlPTWV0YWRhdGFGb3JtYXQgd2l0aAorICAgICAqIENISUxEX1BPTElDWV9SRVBFQVQgYW5kIHRoZSBzcGVjaWZpZWQgbWluaW11bSBhbmQgbWF4aW11bSBudW1iZXIgb2YgY2hpbGQKKyAgICAgKiBlbGVtZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUgdG8gYmUgYWRkZWQuCisgICAgICogQHBhcmFtIHBhcmVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBtaW5DaGlsZHJlbgorICAgICAqICAgICAgICAgICAgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGNoaWxkIGVsZW1lbnRzLgorICAgICAqIEBwYXJhbSBtYXhDaGlsZHJlbgorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoaWxkIGVsZW1lbnRzLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgcGFyZW50TmFtZSwgaW50IG1pbkNoaWxkcmVuLAorICAgICAgICAgICAgaW50IG1heENoaWxkcmVuKSB7CisgICAgICAgIGlmIChtaW5DaGlsZHJlbiA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1pbkNoaWxkcmVuIDwgMCEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWluQ2hpbGRyZW4gPiBtYXhDaGlsZHJlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibWluQ2hpbGRyZW4gPiBtYXhDaGlsZHJlbiEiKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgcGFyZW50ID0gZmluZEVsZW1lbnQocGFyZW50TmFtZSk7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IG5ldyBFbGVtZW50KCk7CisgICAgICAgIGVsZW1lbnQubmFtZSA9IGVsZW1lbnROYW1lOworICAgICAgICBlbGVtZW50LmNoaWxkUG9saWN5ID0gQ0hJTERfUE9MSUNZX1JFUEVBVDsKKyAgICAgICAgZWxlbWVudC5taW5DaGlsZHJlbiA9IG1pbkNoaWxkcmVuOworICAgICAgICBlbGVtZW50Lm1heENoaWxkcmVuID0gbWF4Q2hpbGRyZW47CisgICAgICAgIGVsZW1lbnRIYXNoLnB1dChlbGVtZW50TmFtZSwgZWxlbWVudCk7CisgICAgICAgIHBhcmVudC5jaGlsZHJlbi5hZGQoZWxlbWVudE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gT2JqZWN0IHJlZmVyZW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgdHlwZSB0byBiZSBzdG9yZWQgYXMKKyAgICAgKiBlbGVtZW50J3MgdmFsdWUuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEBwYXJhbSBjbGFzc1R5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyBpbmRpY2F0ZXMgdGhlIGxlZ2FsIHR5cGVzIGZvciB0aGUgb2JqZWN0J3MgdmFsdWUuCisgICAgICogQHBhcmFtIGFycmF5TWluTGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBsZWdhbCBsZW5ndGggZm9yIHRoZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gYXJyYXlNYXhMZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIGxlZ2FsIGxlbmd0aCBmb3IgdGhlIGFycmF5LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZE9iamVjdFZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSwgQ2xhc3M8Pz4gY2xhc3NUeXBlLCBpbnQgYXJyYXlNaW5MZW5ndGgsCisgICAgICAgICAgICBpbnQgYXJyYXlNYXhMZW5ndGgpIHsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworCisgICAgICAgIE9iamVjdFZhbHVlIG9ialZhbCA9IG5ldyBPYmplY3RWYWx1ZSgpOworICAgICAgICBvYmpWYWwuY2xhc3NUeXBlID0gY2xhc3NUeXBlOworICAgICAgICBvYmpWYWwuYXJyYXlNYXhMZW5ndGggPSBhcnJheU1heExlbmd0aDsKKyAgICAgICAgb2JqVmFsLmFycmF5TWluTGVuZ3RoID0gYXJyYXlNaW5MZW5ndGg7CisgICAgICAgIG9ialZhbC52YWx1ZVR5cGUgPSBWQUxVRV9MSVNUOworCisgICAgICAgIGVsZW1lbnQub2JqZWN0VmFsdWUgPSBvYmpWYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhbiBPYmplY3QgcmVmZXJlbmNlIHdpdGggdGhlIHNwZWNpZmllZCBjbGFzcyB0eXBlIHRvIGJlIHN0b3JlZCBhcyBhbgorICAgICAqIGVsZW1lbnQncyB2YWx1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGNsYXNzVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGluZGljYXRlcyB0aGUgbGVnYWwgdHlwZXMgZm9yIHRoZSBvYmplY3QncyB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmVxdWlyZWQKKyAgICAgKiAgICAgICAgICAgIGEgZmxhZyBpbmRpY2F0ZWQgdGhhdCB0aGlzIG9iamVjdCB2YWx1ZSBtdXN0IGJlIHByZXNlbnQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUsIG9yIG51bGwuCisgICAgICovCisgICAgcHJvdGVjdGVkIDxUPiB2b2lkIGFkZE9iamVjdFZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSwgQ2xhc3M8VD4gY2xhc3NUeXBlLCBib29sZWFuIHJlcXVpcmVkLAorICAgICAgICAgICAgVCBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgLy8gbm90ZTogcmVxaXJlZCBpcyBhbiB1bnVzZWQgcGFyYW1ldGVyCisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKworICAgICAgICBPYmplY3RWYWx1ZTxUPiBvYmpWYWwgPSBuZXcgT2JqZWN0VmFsdWU8VD4oKTsKKyAgICAgICAgb2JqVmFsLmNsYXNzVHlwZSA9IGNsYXNzVHlwZTsKKyAgICAgICAgb2JqVmFsLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgb2JqVmFsLnZhbHVlVHlwZSA9IFZBTFVFX0FSQklUUkFSWTsKKworICAgICAgICBlbGVtZW50Lm9iamVjdFZhbHVlID0gb2JqVmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gT2JqZWN0IHJlZmVyZW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgdHlwZSB0byBiZSBzdG9yZWQgYXMKKyAgICAgKiB0aGUgZWxlbWVudCdzIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcGFyYW0gY2xhc3NUeXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgaW5kaWNhdGVzIHRoZSBsZWdhbCB0eXBlcyBmb3IgdGhlIG9iamVjdCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmVxdWlyZWQKKyAgICAgKiAgICAgICAgICAgIGEgZmxhZyBpbmRpY2F0ZWQgdGhhdCB0aGlzIG9iamVjdCB2YWx1ZSBtdXN0IGJlIHByZXNlbnQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUsIG9yIG51bGwuCisgICAgICogQHBhcmFtIGVudW1lcmF0ZWRWYWx1ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGxlZ2FsIHZhbHVlcyBmb3IgdGhlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgPFQ+IHZvaWQgYWRkT2JqZWN0VmFsdWUoU3RyaW5nIGVsZW1lbnROYW1lLCBDbGFzczxUPiBjbGFzc1R5cGUsIGJvb2xlYW4gcmVxdWlyZWQsCisgICAgICAgICAgICBUIGRlZmF1bHRWYWx1ZSwgTGlzdDw/IGV4dGVuZHMgVD4gZW51bWVyYXRlZFZhbHVlcykgeworICAgICAgICAvLyBub3RlOiByZXFpcmVkIGlzIGFuIHVudXNlZCBwYXJhbWV0ZXIKKyAgICAgICAgaWYgKGVudW1lcmF0ZWRWYWx1ZXMgPT0gbnVsbCB8fCBlbnVtZXJhdGVkVmFsdWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW51bWVyYXRlZFZhbHVlcyBpcyBlbXB0eSBvciBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChUIGVudW1lcmF0ZWRWYWx1ZSA6IGVudW1lcmF0ZWRWYWx1ZXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZW51bWVyYXRlZFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW51bWVyYXRlZFZhbHVlcyBjb250YWlucyBhIG51bGwhIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgImVudW1lcmF0ZWRWYWx1ZXMgY29udGFpbnMgYSB2YWx1ZSBub3Qgb2YgY2xhc3MgY2xhc3NUeXBlISIpOworICAgICAgICB9CisKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworCisgICAgICAgIE9iamVjdFZhbHVlPFQ+IG9ialZhbCA9IG5ldyBPYmplY3RWYWx1ZTxUPigpOworICAgICAgICBvYmpWYWwuY2xhc3NUeXBlID0gY2xhc3NUeXBlOworICAgICAgICBvYmpWYWwuZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlOworICAgICAgICBvYmpWYWwuZW51bWVyYXRlZFZhbHVlcyA9IGVudW1lcmF0ZWRWYWx1ZXM7CisgICAgICAgIG9ialZhbC52YWx1ZVR5cGUgPSBWQUxVRV9FTlVNRVJBVElPTjsKKworICAgICAgICBlbGVtZW50Lm9iamVjdFZhbHVlID0gb2JqVmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gT2JqZWN0IHJlZmVyZW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgdHlwZSB0byBiZSBzdG9yZWQgYXMKKyAgICAgKiB0aGUgZWxlbWVudCdzIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcGFyYW0gY2xhc3NUeXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgaW5kaWNhdGVzIHRoZSBsZWdhbCB0eXBlcyBmb3IgdGhlIG9iamVjdCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSwgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gbWluVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIGxlZ2FsIHZhbHVlIGZvciB0aGUgb2JqZWN0IHZhbHVlLgorICAgICAqIEBwYXJhbSBtYXhWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbGVnYWwgdmFsdWUgZm9yIHRoZSBvYmplY3QgdmFsdWUuCisgICAgICogQHBhcmFtIG1pbkluY2x1c2l2ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlIG1pblZhbHVlIGlzIGluY2x1c2l2ZS4KKyAgICAgKiBAcGFyYW0gbWF4SW5jbHVzaXZlCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgbWF4VmFsdWUgaXMgaW5jbHVzaXZlLgorICAgICAqLworICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIE9iamVjdCAmIENvbXBhcmFibGU8PyBzdXBlciBUPj4gdm9pZCBhZGRPYmplY3RWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUsCisgICAgICAgICAgICBDbGFzczxUPiBjbGFzc1R5cGUsIFQgZGVmYXVsdFZhbHVlLCBDb21wYXJhYmxlPD8gc3VwZXIgVD4gbWluVmFsdWUsCisgICAgICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgVD4gbWF4VmFsdWUsIGJvb2xlYW4gbWluSW5jbHVzaXZlLCBib29sZWFuIG1heEluY2x1c2l2ZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisKKyAgICAgICAgT2JqZWN0VmFsdWU8VD4gb2JqVmFsID0gbmV3IE9iamVjdFZhbHVlPFQ+KCk7CisgICAgICAgIG9ialZhbC5jbGFzc1R5cGUgPSBjbGFzc1R5cGU7CisgICAgICAgIG9ialZhbC5kZWZhdWx0VmFsdWUgPSBkZWZhdWx0VmFsdWU7CisgICAgICAgIG9ialZhbC5taW5WYWx1ZSA9IG1pblZhbHVlOworICAgICAgICBvYmpWYWwubWF4VmFsdWUgPSBtYXhWYWx1ZTsKKyAgICAgICAgb2JqVmFsLm1pbkluY2x1c2l2ZSA9IG1pbkluY2x1c2l2ZTsKKyAgICAgICAgb2JqVmFsLm1heEluY2x1c2l2ZSA9IG1heEluY2x1c2l2ZTsKKworICAgICAgICBvYmpWYWwudmFsdWVUeXBlID0gVkFMVUVfUkFOR0U7CisgICAgICAgIG9ialZhbC52YWx1ZVR5cGUgfD0gbWluSW5jbHVzaXZlID8gVkFMVUVfUkFOR0VfTUlOX0lOQ0xVU0lWRV9NQVNLIDogMDsKKyAgICAgICAgb2JqVmFsLnZhbHVlVHlwZSB8PSBtYXhJbmNsdXNpdmUgPyBWQUxVRV9SQU5HRV9NQVhfSU5DTFVTSVZFX01BU0sgOiAwOworCisgICAgICAgIGVsZW1lbnQub2JqZWN0VmFsdWUgPSBvYmpWYWw7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVEYXRhVHlwZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSkgeworICAgICAgICBBdHRsaXN0IGF0dHIgPSBmaW5kQXR0cmlidXRlKGVsZW1lbnROYW1lLCBhdHRyTmFtZSk7CisgICAgICAgIHJldHVybiBhdHRyLmRhdGFUeXBlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlRGVmYXVsdFZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKSB7CisgICAgICAgIEF0dGxpc3QgYXR0ciA9IGZpbmRBdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJOYW1lKTsKKyAgICAgICAgcmV0dXJuIGF0dHIuZGVmYXVsdFZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlRGVzY3JpcHRpb24oU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgZmluZEF0dHJpYnV0ZShlbGVtZW50TmFtZSwgYXR0ck5hbWUpOworICAgICAgICByZXR1cm4gZ2V0UmVzb3VyY2VTdHJpbmcoZWxlbWVudE5hbWUgKyAiLyIgKyBhdHRyTmFtZSwgbG9jYWxlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0QXR0cmlidXRlRW51bWVyYXRpb25zKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKSB7CisgICAgICAgIEF0dGxpc3QgYXR0ciA9IGZpbmRBdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJOYW1lKTsKKyAgICAgICAgaWYgKGF0dHIudmFsdWVUeXBlICE9IFZBTFVFX0VOVU1FUkFUSU9OKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBdHRyaWJ1dGUgaXMgbm90IGFuIGVudW1lcmF0aW9uISIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGF0dHIuZW51bWVyYXRlZFZhbHVlcy50b0FycmF5KG5ldyBTdHJpbmdbYXR0ci5lbnVtZXJhdGVkVmFsdWVzLnNpemUoKV0pOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTGlzdE1heExlbmd0aChTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSkgeworICAgICAgICBBdHRsaXN0IGF0dHIgPSBmaW5kQXR0cmlidXRlKGVsZW1lbnROYW1lLCBhdHRyTmFtZSk7CisgICAgICAgIGlmIChhdHRyLnZhbHVlVHlwZSAhPSBWQUxVRV9MSVNUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBdHRyaWJ1dGUgaXMgbm90IGEgbGlzdCEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXR0ci5saXN0TWF4TGVuZ3RoOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTGlzdE1pbkxlbmd0aChTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSkgeworICAgICAgICBBdHRsaXN0IGF0dHIgPSBmaW5kQXR0cmlidXRlKGVsZW1lbnROYW1lLCBhdHRyTmFtZSk7CisgICAgICAgIGlmIChhdHRyLnZhbHVlVHlwZSAhPSBWQUxVRV9MSVNUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBdHRyaWJ1dGUgaXMgbm90IGEgbGlzdCEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXR0ci5saXN0TWluTGVuZ3RoOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlTWF4VmFsdWUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUpIHsKKyAgICAgICAgQXR0bGlzdCBhdHRyID0gZmluZEF0dHJpYnV0ZShlbGVtZW50TmFtZSwgYXR0ck5hbWUpOworICAgICAgICBpZiAoKGF0dHIudmFsdWVUeXBlICYgVkFMVUVfUkFOR0UpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkF0dHJpYnV0ZSBpcyBub3QgYSByYW5nZSEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXR0ci5tYXhWYWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU1pblZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJOYW1lKSB7CisgICAgICAgIEF0dGxpc3QgYXR0ciA9IGZpbmRBdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJOYW1lKTsKKyAgICAgICAgaWYgKChhdHRyLnZhbHVlVHlwZSAmIFZBTFVFX1JBTkdFKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBdHRyaWJ1dGUgaXMgbm90IGEgcmFuZ2UhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF0dHIubWluVmFsdWU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldEF0dHJpYnV0ZU5hbWVzKFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisgICAgICAgIHJldHVybiBlbGVtZW50LmF0dHJpYnV0ZXMua2V5U2V0KCkudG9BcnJheShuZXcgU3RyaW5nW2VsZW1lbnQuYXR0cmlidXRlcy5zaXplKCldKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZVZhbHVlVHlwZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSkgeworICAgICAgICBBdHRsaXN0IGF0dHIgPSBmaW5kQXR0cmlidXRlKGVsZW1lbnROYW1lLCBhdHRyTmFtZSk7CisgICAgICAgIHJldHVybiBhdHRyLnZhbHVlVHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0Q2hpbGROYW1lcyhTdHJpbmcgZWxlbWVudE5hbWUpIHsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworICAgICAgICBpZiAoZWxlbWVudC5jaGlsZFBvbGljeSA9PSBDSElMRF9QT0xJQ1lfRU1QVFkpIHsgLy8gRWxlbWVudCBjYW5ub3QgaGF2ZQorICAgICAgICAgICAgLy8gY2hpbGRyZW4KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuLnRvQXJyYXkobmV3IFN0cmluZ1tlbGVtZW50LmNoaWxkcmVuLnNpemUoKV0pOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Q2hpbGRQb2xpY3koU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgcmV0dXJuIGVsZW1lbnQuY2hpbGRQb2xpY3k7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50RGVzY3JpcHRpb24oU3RyaW5nIGVsZW1lbnROYW1lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsgLy8gQ2hlY2sgaWYgdGhlcmUgaXMgc3VjaCBlbGVtZW50CisgICAgICAgIHJldHVybiBnZXRSZXNvdXJjZVN0cmluZyhlbGVtZW50TmFtZSwgbG9jYWxlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEVsZW1lbnRNYXhDaGlsZHJlbihTdHJpbmcgZWxlbWVudE5hbWUpIHsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworICAgICAgICBpZiAoZWxlbWVudC5jaGlsZFBvbGljeSAhPSBDSElMRF9QT0xJQ1lfUkVQRUFUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDaGlsZCBwb2xpY3kgaXMgbm90IENISUxEX1BPTElDWV9SRVBFQVQhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVsZW1lbnQubWF4Q2hpbGRyZW47CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRFbGVtZW50TWluQ2hpbGRyZW4oU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgaWYgKGVsZW1lbnQuY2hpbGRQb2xpY3kgIT0gQ0hJTERfUE9MSUNZX1JFUEVBVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2hpbGQgcG9saWN5IGlzIG5vdCBDSElMRF9QT0xJQ1lfUkVQRUFUISIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbGVtZW50Lm1pbkNoaWxkcmVuOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0T2JqZWN0QXJyYXlNYXhMZW5ndGgoU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgT2JqZWN0VmFsdWUgdiA9IGVsZW1lbnQub2JqZWN0VmFsdWU7CisgICAgICAgIGlmICh2ID09IG51bGwgfHwgdi52YWx1ZVR5cGUgIT0gVkFMVUVfTElTVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgbGlzdCEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdi5hcnJheU1heExlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE9iamVjdEFycmF5TWluTGVuZ3RoKFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisgICAgICAgIE9iamVjdFZhbHVlIHYgPSBlbGVtZW50Lm9iamVjdFZhbHVlOworICAgICAgICBpZiAodiA9PSBudWxsIHx8IHYudmFsdWVUeXBlICE9IFZBTFVFX0xJU1QpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhIGxpc3QhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHYuYXJyYXlNaW5MZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIENsYXNzPD8+IGdldE9iamVjdENsYXNzKFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBPYmplY3RWYWx1ZSB2ID0gZmluZE9iamVjdFZhbHVlKGVsZW1lbnROYW1lKTsKKyAgICAgICAgcmV0dXJuIHYuY2xhc3NUeXBlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0RGVmYXVsdFZhbHVlKFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBPYmplY3RWYWx1ZSB2ID0gZmluZE9iamVjdFZhbHVlKGVsZW1lbnROYW1lKTsKKyAgICAgICAgcmV0dXJuIHYuZGVmYXVsdFZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3RbXSBnZXRPYmplY3RFbnVtZXJhdGlvbnMoU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgT2JqZWN0VmFsdWUgdiA9IGVsZW1lbnQub2JqZWN0VmFsdWU7CisgICAgICAgIGlmICh2ID09IG51bGwgfHwgdi52YWx1ZVR5cGUgIT0gVkFMVUVfRU5VTUVSQVRJT04pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhbiBlbnVtZXJhdGlvbiEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdi5lbnVtZXJhdGVkVmFsdWVzLnRvQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29tcGFyYWJsZTw/PiBnZXRPYmplY3RNYXhWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUpIHsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworICAgICAgICBPYmplY3RWYWx1ZSB2ID0gZWxlbWVudC5vYmplY3RWYWx1ZTsKKyAgICAgICAgaWYgKHYgPT0gbnVsbCB8fCAodi52YWx1ZVR5cGUgJiBWQUxVRV9SQU5HRSkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgcmFuZ2UhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHYubWF4VmFsdWU7CisgICAgfQorCisgICAgcHVibGljIENvbXBhcmFibGU8Pz4gZ2V0T2JqZWN0TWluVmFsdWUoU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgT2JqZWN0VmFsdWUgdiA9IGVsZW1lbnQub2JqZWN0VmFsdWU7CisgICAgICAgIGlmICh2ID09IG51bGwgfHwgKHYudmFsdWVUeXBlICYgVkFMVUVfUkFOR0UpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhIHJhbmdlISIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2Lm1pblZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0T2JqZWN0VmFsdWVUeXBlKFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisgICAgICAgIGlmIChlbGVtZW50Lm9iamVjdFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBWQUxVRV9OT05FOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbGVtZW50Lm9iamVjdFZhbHVlLnZhbHVlVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZXNvdXJjZSBiYXNlIG5hbWUgZm9yIGxvY2F0aW5nIFJlc291cmNlQnVuZGxlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHJlc291cmNlIGJhc2UgbmFtZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFJlc291cmNlQmFzZU5hbWUoKSB7CisgICAgICAgIHJldHVybiByZXNvdXJjZUJhc2VOYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Um9vdE5hbWUoKSB7CisgICAgICAgIHJldHVybiByb290TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFuZGFyZCBmb3JtYXQgaW5zdGFuY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgSUlPTWV0YWRhdGFGb3JtYXQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJSU9NZXRhZGF0YUZvcm1hdCBnZXRTdGFuZGFyZEZvcm1hdEluc3RhbmNlKCkgeworICAgICAgICBpZiAoc3RhbmRhcmRGb3JtYXQgPT0gbnVsbCkgeworICAgICAgICAgICAgc3RhbmRhcmRGb3JtYXQgPSBuZXcgSUlPU3RhbmRhcmRNZXRhZGF0YUZvcm1hdCgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHN0YW5kYXJkRm9ybWF0OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlUmVxdWlyZWQoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0ck5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZpbmRBdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJOYW1lKS5yZXF1aXJlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGZyb20gdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBlbGVtZW50IG5hbWUuCisgICAgICogQHBhcmFtIGF0dHJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyTmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisgICAgICAgIGVsZW1lbnQuYXR0cmlidXRlcy5yZW1vdmUoYXR0ck5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBmb3JtYXQuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgbmFtZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIGlmICgoZWxlbWVudCA9IGVsZW1lbnRIYXNoLmdldChlbGVtZW50TmFtZSkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGVsZW1lbnRIYXNoLnJlbW92ZShlbGVtZW50TmFtZSk7CisgICAgICAgICAgICBmb3IgKEVsZW1lbnQgZSA6IGVsZW1lbnRIYXNoLnZhbHVlcygpKSB7CisgICAgICAgICAgICAgICAgZS5jaGlsZHJlbi5yZW1vdmUoZWxlbWVudC5uYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG9iamVjdCB2YWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlT2JqZWN0VmFsdWUoU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZpbmRFbGVtZW50KGVsZW1lbnROYW1lKTsKKyAgICAgICAgZWxlbWVudC5vYmplY3RWYWx1ZSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG5ldyBiYXNlIG5hbWUgZm9yIFJlc291cmNlQnVuZGxlcyBjb250YWluaW5nIGRlc2NyaXB0aW9ucyBvZgorICAgICAqIGVsZW1lbnRzIGFuZCBhdHRyaWJ1dGVzIGZvciB0aGlzIGZvcm1hdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVzb3VyY2VCYXNlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyByZXNvdXJjZSBiYXNlIG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0UmVzb3VyY2VCYXNlTmFtZShTdHJpbmcgcmVzb3VyY2VCYXNlTmFtZSkgeworICAgICAgICBpZiAocmVzb3VyY2VCYXNlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJyZXNvdXJjZUJhc2VOYW1lID09IG51bGwhIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5yZXNvdXJjZUJhc2VOYW1lID0gcmVzb3VyY2VCYXNlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgRWxlbWVudC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeworICAgICAgICAiQ2xhc3NXaXRob3V0Q29uc3RydWN0b3IiCisgICAgfSkKKyAgICBwcml2YXRlIGNsYXNzIEVsZW1lbnQgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIFN0cmluZyBuYW1lOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY2hpbGRyZW4uCisgICAgICAgICAqLworICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYXR0cmlidXRlcy4KKyAgICAgICAgICovCisgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBBdHRsaXN0PiBhdHRyaWJ1dGVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBBdHRsaXN0PigpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbWluIGNoaWxkcmVuLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG1pbkNoaWxkcmVuOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbWF4IGNoaWxkcmVuLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG1heENoaWxkcmVuOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY2hpbGQgcG9saWN5LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGNoaWxkUG9saWN5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgb2JqZWN0IHZhbHVlLgorICAgICAgICAgKi8KKyAgICAgICAgT2JqZWN0VmFsdWUgb2JqZWN0VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIEF0dGxpc3QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsKKyAgICAgICAgIkNsYXNzV2l0aG91dENvbnN0cnVjdG9yIgorICAgIH0pCisgICAgcHJpdmF0ZSBjbGFzcyBBdHRsaXN0IHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgbmFtZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGRhdGEgdHlwZS4KKyAgICAgICAgICovCisgICAgICAgIGludCBkYXRhVHlwZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHJlcXVpcmVkLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiByZXF1aXJlZDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGxpc3QgbWluIGxlbmd0aC4KKyAgICAgICAgICovCisgICAgICAgIGludCBsaXN0TWluTGVuZ3RoOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbGlzdCBtYXggbGVuZ3RoLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGxpc3RNYXhMZW5ndGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nIGRlZmF1bHRWYWx1ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGVudW1lcmF0ZWQgdmFsdWVzLgorICAgICAgICAgKi8KKyAgICAgICAgTGlzdDxTdHJpbmc+IGVudW1lcmF0ZWRWYWx1ZXM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtaW4gdmFsdWUuCisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgbWluVmFsdWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtYXggdmFsdWUuCisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgbWF4VmFsdWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtaW4gaW5jbHVzaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBtaW5JbmNsdXNpdmU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtYXggaW5jbHVzaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBtYXhJbmNsdXNpdmU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB2YWx1ZSB0eXBlLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHZhbHVlVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgT2JqZWN0VmFsdWUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsKKyAgICAgICAgIkNsYXNzV2l0aG91dENvbnN0cnVjdG9yIgorICAgIH0pCisgICAgcHJpdmF0ZSBjbGFzcyBPYmplY3RWYWx1ZTxUPiB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjbGFzcyB0eXBlLgorICAgICAgICAgKi8KKyAgICAgICAgQ2xhc3M8VD4gY2xhc3NUeXBlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYXJyYXkgbWluIGxlbmd0aC4KKyAgICAgICAgICovCisgICAgICAgIGludCBhcnJheU1pbkxlbmd0aDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGFycmF5IG1heCBsZW5ndGguCisgICAgICAgICAqLworICAgICAgICBpbnQgYXJyYXlNYXhMZW5ndGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAgICAgKi8KKyAgICAgICAgVCBkZWZhdWx0VmFsdWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBlbnVtZXJhdGVkIHZhbHVlcy4KKyAgICAgICAgICovCisgICAgICAgIExpc3Q8PyBleHRlbmRzIFQ+IGVudW1lcmF0ZWRWYWx1ZXM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtaW4gdmFsdWUuCisgICAgICAgICAqLworICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgVD4gbWluVmFsdWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtYXggdmFsdWUuCisgICAgICAgICAqLworICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgVD4gbWF4VmFsdWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtaW4gaW5jbHVzaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBtaW5JbmNsdXNpdmU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtYXggaW5jbHVzaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBtYXhJbmNsdXNpdmU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB2YWx1ZSB0eXBlLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHZhbHVlVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGVsZW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBFbGVtZW50IGZpbmRFbGVtZW50KFN0cmluZyBuYW1lKSB7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgaWYgKChlbGVtZW50ID0gZWxlbWVudEhhc2guZ2V0KG5hbWUpKSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJlbGVtZW50IG5hbWUgaXMgbnVsbCBvciBubyBzdWNoIGVsZW1lbnQ6ICIgKyBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBlbGVtZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYXR0cmlidXRlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgbmFtZS4KKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGF0dGxpc3QuCisgICAgICovCisgICAgcHJpdmF0ZSBBdHRsaXN0IGZpbmRBdHRyaWJ1dGUoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSkgeworICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBmaW5kRWxlbWVudChlbGVtZW50TmFtZSk7CisgICAgICAgIEF0dGxpc3QgYXR0cmlidXRlOworICAgICAgICBpZiAoKGF0dHJpYnV0ZSA9IGVsZW1lbnQuYXR0cmlidXRlcy5nZXQoYXR0cmlidXRlTmFtZSkpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImF0dHJpYnV0ZSBuYW1lIGlzIG51bGwgb3Igbm8gc3VjaCBhdHRyaWJ1dGU6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBhdHRyaWJ1dGVOYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBhdHRyaWJ1dGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBvYmplY3QgdmFsdWUuCisgICAgICogCisgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdFZhbHVlIGZpbmRPYmplY3RWYWx1ZShTdHJpbmcgZWxlbWVudE5hbWUpIHsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZWxlbWVudE5hbWUpOworICAgICAgICBPYmplY3RWYWx1ZSB2ID0gZWxlbWVudC5vYmplY3RWYWx1ZTsKKyAgICAgICAgaWYgKHYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm8gb2JqZWN0IHdpdGhpbiBlbGVtZW50Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVzb3VyY2Ugc3RyaW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBzdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UmVzb3VyY2VTdHJpbmcoU3RyaW5nIGtleSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAobG9jYWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBHZXQgdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyIGFuZCB0cnkgdG8gbG9jYXRlIHRoZSBidW5kbGUgd2l0aCBpdAorICAgICAgICAvLyBmaXJzdAorICAgICAgICBDbGFzc0xvYWRlciBjb250ZXh0Q2xhc3Nsb2FkZXIgPSBBY2Nlc3NDb250cm9sbGVyCisgICAgICAgICAgICAgICAgLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxDbGFzc0xvYWRlcj4oKSB7CisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlciBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0pOworCisgICAgICAgIC8vIE5vdyB0cnkgdG8gZ2V0IHRoZSByZXNvdXJjZSBidW5kbGUKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYiA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShyZXNvdXJjZUJhc2VOYW1lLCBsb2NhbGUsIGNvbnRleHRDbGFzc2xvYWRlcik7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJiID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKHJlc291cmNlQmFzZU5hbWUsIGxvY2FsZSk7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcmIuZ2V0U3RyaW5nKGtleSk7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBOb3QgYSBzdHJpbmcgcmVzb3VyY2UKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhTm9kZS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFOb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWRjNmQ2NwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL0lJT01ldGFkYXRhTm9kZS5qYXZhCkBAIC0wLDAgKzEsMTA3MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLm1ldGFkYXRhOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKy8vPz8/QVdUCisvL2ltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKKy8vaW1wb3J0IG9yZy53M2MuZG9tLlVzZXJEYXRhSGFuZGxlcjsKKworLyoqCisgKiBUaGUgQ2xhc3MgSUlPTWV0YWRhdGFOb2RlIHJlcHJlc2VudHMgYSBub2RlIG9mIHRoZSAoRE9NLXN0eWxlKSBtZXRhZGF0YSB0cmVlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIElJT01ldGFkYXRhTm9kZSBpbXBsZW1lbnRzIEVsZW1lbnQsIE5vZGVMaXN0IHsKKworICAgIC8qKgorICAgICAqIFRoZSBub2RlIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbm9kZU5hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBub2RlVmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXR0cmlidXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIElJT01ldGFkYXRhTm9kZUxpc3QgYXR0cnMgPSBuZXcgSUlPTWV0YWRhdGFOb2RlTGlzdChuZXcgQXJyYXlMaXN0PElJT01ldGFkYXRhTm9kZT4oKSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGFyZW50IG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBJSU9NZXRhZGF0YU5vZGUgcGFyZW50OworCisgICAgLyoqCisgICAgICogVGhlIGZpcnN0IGNoaWxkIG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBJSU9NZXRhZGF0YU5vZGUgZmlyc3RDaGlsZDsKKworICAgIC8qKgorICAgICAqIFRoZSBsYXN0IGNoaWxkIG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBJSU9NZXRhZGF0YU5vZGUgbGFzdENoaWxkOworCisgICAgLyoqCisgICAgICogVGhlIHByZXZpb3VzIHNpYmxpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBJSU9NZXRhZGF0YU5vZGUgcHJldmlvdXNTaWJsaW5nOworCisgICAgLyoqCisgICAgICogVGhlIG5leHQgc2libGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIElJT01ldGFkYXRhTm9kZSBuZXh0U2libGluZzsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgY2hpbGRyZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbkNoaWxkcmVuOworCisgICAgLyoqCisgICAgICogVGhlIHVzZXIgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgdXNlck9iamVjdDsKKworICAgIC8qKgorICAgICAqIFRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHRleHRDb250ZW50OworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGVtcHR5IG5vZGUuCisgICAgICovCisgICAgcHVibGljIElJT01ldGFkYXRhTm9kZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgZW1wdHkgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbm9kZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBub2RlIG5hbWUuCisgICAgICovCisgICAgcHVibGljIElJT01ldGFkYXRhTm9kZShTdHJpbmcgbm9kZU5hbWUpIHsKKyAgICAgICAgdGhpcy5ub2RlTmFtZSA9IG5vZGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJSU9NZXRhZGF0YU5vZGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgYW5kIHZhbHVlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBub2RlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5vZGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gbm9kZVZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbm9kZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIElJT01ldGFkYXRhTm9kZShTdHJpbmcgbm9kZU5hbWUsIFN0cmluZyBub2RlVmFsdWUpIHsKKyAgICAgICAgdGhpcy5ub2RlTmFtZSA9IG5vZGVOYW1lOworICAgICAgICB0aGlzLm5vZGVWYWx1ZSA9IG5vZGVWYWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7CisgICAgICAgIHJldHVybiBub2RlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICBBdHRyIGF0dHJOb2RlID0gKEF0dHIpYXR0cnMuZ2V0TmFtZWRJdGVtKG5hbWUpOworICAgICAgICByZXR1cm4gKGF0dHJOb2RlID09IG51bGwpID8gIiIgOiBhdHRyTm9kZS5nZXRWYWx1ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgQXR0ciBhdHRyID0gKEF0dHIpYXR0cnMuZ2V0TmFtZWRJdGVtKG5hbWUpOworICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7CisgICAgICAgICAgICBhdHRyLnNldFZhbHVlKHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGF0dHJzLmxpc3QuYWRkKG5ldyBJSU9NZXRhZGF0YUF0dHIobmFtZSwgdmFsdWUsIHRoaXMpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIElJT01ldGFkYXRhQXR0ciBhdHRyID0gKElJT01ldGFkYXRhQXR0cilhdHRycy5nZXROYW1lZEl0ZW0obmFtZSk7CisgICAgICAgIGlmIChhdHRyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGF0dHIuc2V0T3duZXJFbGVtZW50KG51bGwpOworICAgICAgICAgICAgYXR0cnMubGlzdC5yZW1vdmUoYXR0cik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiAoQXR0cilhdHRycy5nZXROYW1lZEl0ZW0obmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEF0dHIgc2V0QXR0cmlidXRlTm9kZShBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBhbHJlYWR5IGluIHVzZS4KKyAgICAgICAgRWxlbWVudCBvd25lciA9IG5ld0F0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIGlmIChvd25lciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAob3duZXIgPT0gdGhpcykgeyAvLyBSZXBsYWNpbmcgYW4gYXR0cmlidXRlIG5vZGUgYnkgaXRzZWxmIGhhcyBubworICAgICAgICAgICAgICAgIC8vIGVmZmVjdAorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlVTRV9BVFRSSUJVVEVfRVJSLAorICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSBpcyBhbHJlYWR5IGluIHVzZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBuZXdBdHRyLmdldE5hbWUoKTsKKyAgICAgICAgQXR0ciBvbGRBdHRyID0gZ2V0QXR0cmlidXRlTm9kZShuYW1lKTsKKyAgICAgICAgaWYgKG9sZEF0dHIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVtb3ZlQXR0cmlidXRlTm9kZShvbGRBdHRyKTsKKyAgICAgICAgfQorCisgICAgICAgIElJT01ldGFkYXRhQXR0ciBpaW9BdHRyOworICAgICAgICBpZiAobmV3QXR0ciBpbnN0YW5jZW9mIElJT01ldGFkYXRhQXR0cikgeworICAgICAgICAgICAgaWlvQXR0ciA9IChJSU9NZXRhZGF0YUF0dHIpbmV3QXR0cjsKKyAgICAgICAgICAgIGlpb0F0dHIuc2V0T3duZXJFbGVtZW50KHRoaXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWlvQXR0ciA9IG5ldyBJSU9NZXRhZGF0YUF0dHIobmFtZSwgbmV3QXR0ci5nZXRWYWx1ZSgpLCB0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIGF0dHJzLmxpc3QuYWRkKGlpb0F0dHIpOworCisgICAgICAgIHJldHVybiBvbGRBdHRyOworICAgIH0KKworICAgIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFhdHRycy5saXN0LnJlbW92ZShvbGRBdHRyKSkgeyAvLyBOb3QgZm91bmQKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsICJObyBzdWNoIGF0dHJpYnV0ZSEiKTsKKyAgICAgICAgfQorCisgICAgICAgICgoSUlPTWV0YWRhdGFBdHRyKW9sZEF0dHIpLnNldE93bmVyRWxlbWVudChudWxsKTsKKworICAgICAgICByZXR1cm4gb2xkQXR0cjsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgQXJyYXlMaXN0PElJT01ldGFkYXRhTm9kZT4gbm9kZXMgPSBuZXcgQXJyYXlMaXN0PElJT01ldGFkYXRhTm9kZT4oKTsKKworICAgICAgICAvLyBOb24tcmVjdXJzaXZlIHRyZWUgd2FsaworICAgICAgICBOb2RlIHBvcyA9IHRoaXM7CisKKyAgICAgICAgd2hpbGUgKHBvcyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAocG9zLmdldE5vZGVOYW1lKCkuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgbm9kZXMuYWRkKChJSU9NZXRhZGF0YU5vZGUpcG9zKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTm9kZSBuZXh0Tm9kZSA9IHBvcy5nZXRGaXJzdENoaWxkKCk7CisKKyAgICAgICAgICAgIHdoaWxlIChuZXh0Tm9kZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHBvcyA9PSB0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG5leHROb2RlID0gcG9zLmdldE5leHRTaWJsaW5nKCk7CisKKyAgICAgICAgICAgICAgICBpZiAobmV4dE5vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwb3MgPSBwb3MuZ2V0UGFyZW50Tm9kZSgpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gbnVsbCB8fCBwb3MgPT0gdGhpcykgeworICAgICAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3MgPSBuZXh0Tm9kZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgSUlPTWV0YWRhdGFOb2RlTGlzdChub2Rlcyk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZShsb2NhbE5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lLCBTdHJpbmcgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0QXR0cmlidXRlKHF1YWxpZmllZE5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgcmVtb3ZlQXR0cmlidXRlKGxvY2FsTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEF0dHIgZ2V0QXR0cmlidXRlTm9kZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlTm9kZShsb2NhbE5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGVOUyhBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQorICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRFbGVtZW50c0J5VGFnTmFtZShsb2NhbE5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gYXR0cnMuZ2V0TmFtZWRJdGVtKG5hbWUpICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBoYXNBdHRyaWJ1dGUobG9jYWxOYW1lKTsKKyAgICB9CisKKyAgICAvLyA/Pz9BV1QKKyAgICAvKgorICAgICAqIHB1YmxpYyBUeXBlSW5mbyBnZXRTY2hlbWFUeXBlSW5mbygpIHsgdGhyb3cgbmV3CisgICAgICogRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7IH0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIDxpPkRlc2NyaXB0aW9uIGNvcGllZCBmcm9tIGludGVyZmFjZTogb3JnLnczYy5kb20uRWxlbWVudCAoRE9NIExldmVsCisgICAgICogMyk8L2k+CisgICAgICogPHA+CisgICAgICogSWYgdGhlIHBhcmFtZXRlciBpc0lkIGlzIHRydWUsIHRoaXMgbWV0aG9kIGRlY2xhcmVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlIC4gVGhpcyBhZmZlY3RzIHRoZSB2YWx1ZQorICAgICAqIG9mIEF0dHIuaXNJZCBhbmQgdGhlIGJlaGF2aW9yIG9mIERvY3VtZW50LmdldEVsZW1lbnRCeUlkLCBidXQgZG9lcyBub3QKKyAgICAgKiBjaGFuZ2UgYW55IHNjaGVtYSB0aGF0IG1heSBiZSBpbiB1c2UsIGluIHBhcnRpY3VsYXIgdGhpcyBkb2VzIG5vdCBhZmZlY3QKKyAgICAgKiB0aGUgQXR0ci5zY2hlbWFUeXBlSW5mbyBvZiB0aGUgc3BlY2lmaWVkIEF0dHIgbm9kZS4gVXNlIHRoZSB2YWx1ZSBmYWxzZQorICAgICAqIGZvciB0aGUgcGFyYW1ldGVyIGlzSWQgdG8gdW5kZWNsYXJlIGFuIGF0dHJpYnV0ZSBmb3IgYmVpbmcgYQorICAgICAqIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUuIFRvIHNwZWNpZnkgYW4gYXR0cmlidXRlIGJ5IGxvY2FsIG5hbWUgYW5kCisgICAgICogbmFtZXNwYWNlIFVSSSwgdXNlIHRoZSBzZXRJZEF0dHJpYnV0ZU5TIG1ldGhvZC4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIGlzSWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIHdoaWNoIGRldGVybWluZXMgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSBpcyBvZiB0eXBlCisgICAgICogICAgICAgICAgICBJRC4KKyAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgRE9NIGVycm9yIG9jY3VycmVkIHdoaWxlIHNldHRpbmcgdGhlIGF0dHJpYnV0ZSB0eXBlLgorICAgICAqICAgICAgICAgICAgIDxwPgorICAgICAqICAgICAgICAgICAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiAgICAgICAgICAgICA8YnI+CisgICAgICogICAgICAgICAgICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBub3QgYW4KKyAgICAgKiAgICAgICAgICAgICBhdHRyaWJ1dGUgb2YgdGhpcyBlbGVtZW50LgorICAgICAqICAgICAgICAgICAgIDwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgYm9vbGVhbiBpc0lkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxpPkRlc2NyaXB0aW9uIGNvcGllZCBmcm9tIGludGVyZmFjZTogb3JnLnczYy5kb20uRWxlbWVudCAoRE9NIExldmVsCisgICAgICogMyk8L2k+CisgICAgICogPHA+CisgICAgICogSWYgdGhlIHBhcmFtZXRlciBpc0lkIGlzIHRydWUsIHRoaXMgbWV0aG9kIGRlY2xhcmVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlIC4gVGhpcyBhZmZlY3RzIHRoZSB2YWx1ZQorICAgICAqIG9mIEF0dHIuaXNJZCBhbmQgdGhlIGJlaGF2aW9yIG9mIERvY3VtZW50LmdldEVsZW1lbnRCeUlkLCBidXQgZG9lcyBub3QKKyAgICAgKiBjaGFuZ2UgYW55IHNjaGVtYSB0aGF0IG1heSBiZSBpbiB1c2UsIGluIHBhcnRpY3VsYXIgdGhpcyBkb2VzIG5vdCBhZmZlY3QKKyAgICAgKiB0aGUgQXR0ci5zY2hlbWFUeXBlSW5mbyBvZiB0aGUgc3BlY2lmaWVkIEF0dHIgbm9kZS4gVXNlIHRoZSB2YWx1ZSBmYWxzZQorICAgICAqIGZvciB0aGUgcGFyYW1ldGVyIGlzSWQgdG8gdW5kZWNsYXJlIGFuIGF0dHJpYnV0ZSBmb3IgYmVpbmcgYQorICAgICAqIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gaXNJZAorICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgd2hpY2ggZGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIGlzIG9mIHR5cGUKKyAgICAgKiAgICAgICAgICAgIElELgorICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBET00gZXJyb3Igb2NjdXJyZWQgd2hpbGUgc2V0dGluZyB0aGUgYXR0cmlidXRlIHR5cGUuCisgICAgICogICAgICAgICAgICAgPHA+CisgICAgICogICAgICAgICAgICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgICAgICAgICAgIDxicj4KKyAgICAgKiAgICAgICAgICAgICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIG5vdCBhbgorICAgICAqICAgICAgICAgICAgIGF0dHJpYnV0ZSBvZiB0aGlzIGVsZW1lbnQuCisgICAgICogICAgICAgICAgICAgPC9wPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwgYm9vbGVhbiBpc0lkKQorICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8aT5EZXNjcmlwdGlvbiBjb3BpZWQgZnJvbSBpbnRlcmZhY2U6IG9yZy53M2MuZG9tLkVsZW1lbnQgKERPTSBMZXZlbAorICAgICAqIDMpPC9pPgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBwYXJhbWV0ZXIgaXNJZCBpcyB0cnVlLCB0aGlzIG1ldGhvZCBkZWNsYXJlcyB0aGUgc3BlY2lmaWVkCisgICAgICogYXR0cmlidXRlIHRvIGJlIGEgdXNlci1kZXRlcm1pbmVkIElEIGF0dHJpYnV0ZSAuIFRoaXMgYWZmZWN0cyB0aGUgdmFsdWUKKyAgICAgKiBvZiBBdHRyLmlzSWQgYW5kIHRoZSBiZWhhdmlvciBvZiBEb2N1bWVudC5nZXRFbGVtZW50QnlJZCwgYnV0IGRvZXMgbm90CisgICAgICogY2hhbmdlIGFueSBzY2hlbWEgdGhhdCBtYXkgYmUgaW4gdXNlLCBpbiBwYXJ0aWN1bGFyIHRoaXMgZG9lcyBub3QgYWZmZWN0CisgICAgICogdGhlIEF0dHIuc2NoZW1hVHlwZUluZm8gb2YgdGhlIHNwZWNpZmllZCBBdHRyIG5vZGUuIFVzZSB0aGUgdmFsdWUgZmFsc2UKKyAgICAgKiBmb3IgdGhlIHBhcmFtZXRlciBpc0lkIHRvIHVuZGVjbGFyZSBhbiBhdHRyaWJ1dGUgZm9yIGJlaW5nIGEKKyAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaWRBdHRyCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIG5vZGUuCisgICAgICogQHBhcmFtIGlzSWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIHdoaWNoIGRldGVybWluZXMgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSBpcyBvZiB0eXBlCisgICAgICogICAgICAgICAgICBJRC4KKyAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgRE9NIGVycm9yIG9jY3VycmVkIHdoaWxlIHNldHRpbmcgdGhlIGF0dHJpYnV0ZSB0eXBlLgorICAgICAqICAgICAgICAgICAgIDxwPgorICAgICAqICAgICAgICAgICAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiAgICAgICAgICAgICA8YnI+CisgICAgICogICAgICAgICAgICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBub3QgYW4KKyAgICAgKiAgICAgICAgICAgICBhdHRyaWJ1dGUgb2YgdGhpcyBlbGVtZW50LgorICAgICAqICAgICAgICAgICAgIDwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZU5vZGUoQXR0ciBpZEF0dHIsIGJvb2xlYW4gaXNJZCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgeworICAgICAgICByZXR1cm4gbm9kZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5vZGVWYWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIG5vZGVWYWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMubm9kZVZhbHVlID0gbm9kZVZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIEVMRU1FTlRfTk9ERTsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCkgeworICAgICAgICByZXR1cm4gcGFyZW50OworICAgIH0KKworICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkgeworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkgeworICAgICAgICByZXR1cm4gZmlyc3RDaGlsZDsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKSB7CisgICAgICAgIHJldHVybiBsYXN0Q2hpbGQ7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkgeworICAgICAgICByZXR1cm4gcHJldmlvdXNTaWJsaW5nOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgeworICAgICAgICByZXR1cm4gbmV4dFNpYmxpbmc7CisgICAgfQorCisgICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gYXR0cnM7CisgICAgfQorCisgICAgcHVibGljIERvY3VtZW50IGdldE93bmVyRG9jdW1lbnQoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5ld0NoaWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5ld0NoaWxkID09IG51bGwhIik7CisgICAgICAgIH0KKworICAgICAgICBJSU9NZXRhZGF0YU5vZGUgbmV3SUlPQ2hpbGQgPSAoSUlPTWV0YWRhdGFOb2RlKW5ld0NoaWxkOworICAgICAgICBJSU9NZXRhZGF0YU5vZGUgcmVmSUlPQ2hpbGQgPSAoSUlPTWV0YWRhdGFOb2RlKXJlZkNoaWxkOworCisgICAgICAgIG5ld0lJT0NoaWxkLnBhcmVudCA9IHRoaXM7CisKKyAgICAgICAgaWYgKHJlZklJT0NoaWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIG5ld0lJT0NoaWxkLm5leHRTaWJsaW5nID0gbnVsbDsKKyAgICAgICAgICAgIG5ld0lJT0NoaWxkLnByZXZpb3VzU2libGluZyA9IGxhc3RDaGlsZDsKKworICAgICAgICAgICAgLy8gRml4IHRoaXMgbm9kZQorICAgICAgICAgICAgbGFzdENoaWxkID0gbmV3SUlPQ2hpbGQ7CisgICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlyc3RDaGlsZCA9IG5ld0lJT0NoaWxkOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmV3SUlPQ2hpbGQubmV4dFNpYmxpbmcgPSByZWZJSU9DaGlsZDsKKyAgICAgICAgICAgIG5ld0lJT0NoaWxkLnByZXZpb3VzU2libGluZyA9IHJlZklJT0NoaWxkLnByZXZpb3VzU2libGluZzsKKworICAgICAgICAgICAgLy8gRml4IHRoaXMgbm9kZQorICAgICAgICAgICAgaWYgKGZpcnN0Q2hpbGQgPT0gcmVmSUlPQ2hpbGQpIHsKKyAgICAgICAgICAgICAgICBmaXJzdENoaWxkID0gbmV3SUlPQ2hpbGQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEZpeCBuZXh0IG5vZGUKKyAgICAgICAgICAgIGlmIChyZWZJSU9DaGlsZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVmSUlPQ2hpbGQucHJldmlvdXNTaWJsaW5nID0gbmV3SUlPQ2hpbGQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBGaXggcHJldiBub2RlCisgICAgICAgIGlmIChuZXdJSU9DaGlsZC5wcmV2aW91c1NpYmxpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgbmV3SUlPQ2hpbGQucHJldmlvdXNTaWJsaW5nLm5leHRTaWJsaW5nID0gbmV3SUlPQ2hpbGQ7CisgICAgICAgIH0KKworICAgICAgICBuQ2hpbGRyZW4rKzsKKworICAgICAgICByZXR1cm4gbmV3SUlPQ2hpbGQ7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgcmVwbGFjZUNoaWxkKE5vZGUgbmV3Q2hpbGQsIE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBpZiAobmV3Q2hpbGQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmV3Q2hpbGQgPT0gbnVsbCEiKTsKKyAgICAgICAgfQorCisgICAgICAgIElJT01ldGFkYXRhTm9kZSBuZXdJSU9DaGlsZCA9IChJSU9NZXRhZGF0YU5vZGUpbmV3Q2hpbGQ7CisgICAgICAgIElJT01ldGFkYXRhTm9kZSBvbGRJSU9DaGlsZCA9IChJSU9NZXRhZGF0YU5vZGUpb2xkQ2hpbGQ7CisKKyAgICAgICAgSUlPTWV0YWRhdGFOb2RlIG5leHQgPSBvbGRJSU9DaGlsZC5uZXh0U2libGluZzsKKyAgICAgICAgSUlPTWV0YWRhdGFOb2RlIHByZXZpb3VzID0gb2xkSUlPQ2hpbGQucHJldmlvdXNTaWJsaW5nOworCisgICAgICAgIC8vIEZpeCBuZXcgbm9kZQorICAgICAgICBuZXdJSU9DaGlsZC5wYXJlbnQgPSB0aGlzOworICAgICAgICBuZXdJSU9DaGlsZC5uZXh0U2libGluZyA9IG5leHQ7CisgICAgICAgIG5ld0lJT0NoaWxkLnByZXZpb3VzU2libGluZyA9IHByZXZpb3VzOworCisgICAgICAgIC8vIEZpeCB0aGlzIG5vZGUKKyAgICAgICAgaWYgKGxhc3RDaGlsZCA9PSBvbGRJSU9DaGlsZCkgeworICAgICAgICAgICAgbGFzdENoaWxkID0gbmV3SUlPQ2hpbGQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpcnN0Q2hpbGQgPT0gb2xkSUlPQ2hpbGQpIHsKKyAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBuZXdJSU9DaGlsZDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpeCBzaWJsaW5ncworICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICBuZXh0LnByZXZpb3VzU2libGluZyA9IG5ld0lJT0NoaWxkOworICAgICAgICB9CisgICAgICAgIGlmIChwcmV2aW91cyAhPSBudWxsKSB7CisgICAgICAgICAgICBwcmV2aW91cy5uZXh0U2libGluZyA9IG5ld0lJT0NoaWxkOworICAgICAgICB9CisKKyAgICAgICAgLy8gRml4IG9sZCBjaGlsZAorICAgICAgICBvbGRJSU9DaGlsZC5wYXJlbnQgPSBudWxsOworICAgICAgICBvbGRJSU9DaGlsZC5uZXh0U2libGluZyA9IG5leHQ7CisgICAgICAgIG9sZElJT0NoaWxkLnByZXZpb3VzU2libGluZyA9IHByZXZpb3VzOworCisgICAgICAgIHJldHVybiBvbGRJSU9DaGlsZDsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG9sZENoaWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm9sZENoaWxkID09IG51bGwhIik7CisgICAgICAgIH0KKworICAgICAgICBJSU9NZXRhZGF0YU5vZGUgb2xkSUlPQ2hpbGQgPSAoSUlPTWV0YWRhdGFOb2RlKW9sZENoaWxkOworCisgICAgICAgIC8vIEZpeCBuZXh0IGFuZCBwcmV2aW91cworICAgICAgICBJSU9NZXRhZGF0YU5vZGUgcHJldmlvdXMgPSBvbGRJSU9DaGlsZC5wcmV2aW91c1NpYmxpbmc7CisgICAgICAgIElJT01ldGFkYXRhTm9kZSBuZXh0ID0gb2xkSUlPQ2hpbGQubmV4dFNpYmxpbmc7CisKKyAgICAgICAgaWYgKHByZXZpb3VzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByZXZpb3VzLm5leHRTaWJsaW5nID0gbmV4dDsKKyAgICAgICAgfQorICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICBuZXh0LnByZXZpb3VzU2libGluZyA9IHByZXZpb3VzOworICAgICAgICB9CisKKyAgICAgICAgLy8gRml4IHRoaXMgbm9kZQorICAgICAgICBpZiAobGFzdENoaWxkID09IG9sZElJT0NoaWxkKSB7CisgICAgICAgICAgICBsYXN0Q2hpbGQgPSBwcmV2aW91czsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmlyc3RDaGlsZCA9PSBvbGRJSU9DaGlsZCkgeworICAgICAgICAgICAgZmlyc3RDaGlsZCA9IG5leHQ7CisgICAgICAgIH0KKyAgICAgICAgbkNoaWxkcmVuLS07CisKKyAgICAgICAgLy8gRml4IG9sZCBjaGlsZAorICAgICAgICBvbGRJSU9DaGlsZC5wYXJlbnQgPSBudWxsOworICAgICAgICBvbGRJSU9DaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBudWxsOworICAgICAgICBvbGRJSU9DaGlsZC5uZXh0U2libGluZyA9IG51bGw7CisKKyAgICAgICAgcmV0dXJuIG9sZElJT0NoaWxkOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgbmV3Q2hpbGQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkgeworICAgICAgICByZXR1cm4gbkNoaWxkcmVuICE9IDA7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkgeworICAgICAgICBJSU9NZXRhZGF0YU5vZGUgY2xvbmVkID0gbmV3IElJT01ldGFkYXRhTm9kZShub2RlTmFtZSk7CisgICAgICAgIGNsb25lZC5zZXRVc2VyT2JqZWN0KGdldFVzZXJPYmplY3QoKSk7CisKKyAgICAgICAgaWYgKGRlZXApIHsgLy8gQ2xvbmUgcmVjdXJzaXZlbHkKKyAgICAgICAgICAgIElJT01ldGFkYXRhTm9kZSBjID0gZmlyc3RDaGlsZDsKKyAgICAgICAgICAgIHdoaWxlIChjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjbG9uZWQuaW5zZXJ0QmVmb3JlKGMuY2xvbmVOb2RlKHRydWUpLCBudWxsKTsKKyAgICAgICAgICAgICAgICBjID0gYy5uZXh0U2libGluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjbG9uZWQ7IC8vIFRvIGNoYW5nZSBib2R5IG9mIGltcGxlbWVudGVkIG1ldGhvZHMgdXNlIEZpbGUgfAorICAgICAgICAvLyBTZXR0aW5ncyB8IEZpbGUgVGVtcGxhdGVzLgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZSgpIHsKKyAgICAgICAgLy8gRG8gbm90aGluZworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvIG5vdGhpbmcKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vZGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKSB7CisgICAgICAgIHJldHVybiBhdHRycy5saXN0LnNpemUoKSA+IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogPGk+RGVzY3JpcHRpb24gY29waWVkIGZyb20gaW50ZXJmYWNlOiBvcmcudzNjLmRvbS5Ob2RlIChET00gTGV2ZWwgMyk8L2k+CisgICAgICogPHA+CisgICAgICogVGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciBudWxsIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiB3YXNuJ3QKKyAgICAgKiBhYmxlIHRvIG9idGFpbiBhbiBhYnNvbHV0ZSBVUkkuIFRoaXMgdmFsdWUgaXMgY29tcHV0ZWQgYXMgZGVzY3JpYmVkIGluLgorICAgICAqIEhvd2V2ZXIsIHdoZW4gdGhlIERvY3VtZW50IHN1cHBvcnRzIHRoZSBmZWF0dXJlICJIVE1MIiBbRE9NIExldmVsIDIKKyAgICAgKiBIVE1MXSwgdGhlIGJhc2UgVVJJIGlzIGNvbXB1dGVkIHVzaW5nIGZpcnN0IHRoZSB2YWx1ZSBvZiB0aGUgaHJlZgorICAgICAqIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFIGVsZW1lbnQgaWYgYW55LCBhbmQgdGhlIHZhbHVlIG9mIHRoZQorICAgICAqIGRvY3VtZW50VVJJIGF0dHJpYnV0ZSBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2Ugb3RoZXJ3aXNlLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFic29sdXRlIGJhc2UgVVJJLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxpPkRlc2NyaXB0aW9uIGNvcGllZCBmcm9tIGludGVyZmFjZTogb3JnLnczYy5kb20uTm9kZSAoRE9NIExldmVsIDMpPC9pPgorICAgICAqIDxwPgorICAgICAqIENvbXBhcmVzIHRoZSByZWZlcmVuY2Ugbm9kZSwgaS5lLiB0aGUgbm9kZSBvbiB3aGljaCB0aGlzIG1ldGhvZCBpcyBiZWluZworICAgICAqIGNhbGxlZCwgd2l0aCBhIG5vZGUsIGkuZS4gdGhlIG9uZSBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIsIHdpdGggcmVnYXJkIHRvCisgICAgICogdGhlaXIgcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50IGFuZCBhY2NvcmRpbmcgdG8gdGhlIGRvY3VtZW50IG9yZGVyLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBub2RlIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGUgcmVmZXJlbmNlIG5vZGUuCisgICAgICogQHJldHVybiBSZXR1cm5zIGhvdyB0aGUgbm9kZSBpcyBwb3NpdGlvbmVkIHJlbGF0aXZlbHkgdG8gdGhlIHJlZmVyZW5jZQorICAgICAqICAgICAgICAgbm9kZS4KKyAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIE5PVF9TVVBQT1JURURfRVJSOiB3aGVuIHRoZSBjb21wYXJlZCBub2RlcyBhcmUgZnJvbSBkaWZmZXJlbnQKKyAgICAgKiAgICAgICAgICAgICBET00gaW1wbGVtZW50YXRpb25zIHRoYXQgZG8gbm90IGNvb3JkaW5hdGUgdG8gcmV0dXJuCisgICAgICogICAgICAgICAgICAgY29uc2lzdGVudCBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyByZXN1bHRzLgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBjb21wYXJlRG9jdW1lbnRQb3NpdGlvbihOb2RlIG90aGVyKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxpPkRlc2NyaXB0aW9uIGNvcGllZCBmcm9tIGludGVyZmFjZTogb3JnLnczYy5kb20uTm9kZSAoRE9NIExldmVsIDMpPC9pPgorICAgICAqIDxwPgorICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cyBkZXNjZW5kYW50cy4KKyAgICAgKiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LiBPbiBzZXR0aW5nLCBhbnkKKyAgICAgKiBwb3NzaWJsZSBjaGlsZHJlbiB0aGlzIG5vZGUgbWF5IGhhdmUgYXJlIHJlbW92ZWQgYW5kLCBpZiBpdCB0aGUgbmV3CisgICAgICogc3RyaW5nIGlzIG5vdCBlbXB0eSBvciBudWxsLCByZXBsYWNlZCBieSBhIHNpbmdsZSBUZXh0IG5vZGUgY29udGFpbmluZworICAgICAqIHRoZSBzdHJpbmcgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzCisgICAgICogcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQorICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkIGFuZCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCisgICAgICogd2hpdGUgc3BhY2VzIGluIGVsZW1lbnQgY29udGVudCAoc2VlIHRoZSBhdHRyaWJ1dGUKKyAgICAgKiBUZXh0LmlzRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKS4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCisgICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4gVGhlCisgICAgICogc3RyaW5nIHJldHVybmVkIGlzIG1hZGUgb2YgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgZGVwZW5kaW5nIG9uIGl0cworICAgICAqIHR5cGUsIGFzIGRlZmluZWQgYmVsb3c6CisgICAgICogPHRhYmxlPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+PHN0cm9uZz5Ob2RlIHR5cGU8L3N0cm9uZz48L3RkPgorICAgICAqIDx0ZD48c3Ryb25nPkNvbnRlbnQ8L3N0cm9uZz48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZD5FTEVNRU5UX05PREUsIEFUVFJJQlVURV9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAorICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgorICAgICAqIDx0ZD5jb25jYXRlbmF0aW9uIG9mIHRoZSB0ZXh0Q29udGVudCBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwKKyAgICAgKiBleGNsdWRpbmcgQ09NTUVOVF9OT0RFIGFuZCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXMuIFRoaXMgaXMgdGhlCisgICAgICogZW1wdHkgc3RyaW5nIGlmIHRoZSBub2RlIGhhcyBubyBjaGlsZHJlbi48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZD5URVhUX05PREUsIENEQVRBX1NFQ1RJT05fTk9ERSwgQ09NTUVOVF9OT0RFLAorICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTwvdGQ+CisgICAgICogPHRkPm5vZGVWYWx1ZTwvdGQ+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkPkRPQ1VNRU5UX05PREUsIERPQ1VNRU5UX1RZUEVfTk9ERSwgTk9UQVRJT05fTk9ERTwvdGQ+CisgICAgICogPHRkPm51bGw8L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPC90YWJsZT4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdGV4dCBjb250ZW50IGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB0aGlzIG5vZGUuCisgICAgICogQHRocm93cyBET01FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCB3aGVuIGl0IHdvdWxkIHJldHVybiBtb3JlCisgICAgICogICAgICAgICAgICAgY2hhcmFjdGVycyB0aGFuIGZpdCBpbiBhIERPTVN0cmluZyB2YXJpYWJsZSBvbiB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiBwbGF0Zm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB0ZXh0Q29udGVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8aT5EZXNjcmlwdGlvbiBjb3BpZWQgZnJvbSBpbnRlcmZhY2U6IG9yZy53M2MuZG9tLk5vZGUgKERPTSBMZXZlbCAzKTwvaT4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGF0dHJpYnV0ZSByZXR1cm5zIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlIGFuZCBpdHMgZGVzY2VuZGFudHMuCisgICAgICogV2hlbiBpdCBpcyBkZWZpbmVkIHRvIGJlIG51bGwsIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdC4gT24gc2V0dGluZywgYW55CisgICAgICogcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZCwgaWYgaXQgdGhlIG5ldworICAgICAqIHN0cmluZyBpcyBub3QgZW1wdHkgb3IgbnVsbCwgcmVwbGFjZWQgYnkgYSBzaW5nbGUgVGV4dCBub2RlIGNvbnRhaW5pbmcKKyAgICAgKiB0aGUgc3RyaW5nIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4gT24gZ2V0dGluZywgbm8gc2VyaWFsaXphdGlvbiBpcworICAgICAqIHBlcmZvcm1lZCwgdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIGFueSBtYXJrdXAuIE5vIHdoaXRlc3BhY2UKKyAgICAgKiBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZCBhbmQgdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIHRoZQorICAgICAqIHdoaXRlIHNwYWNlcyBpbiBlbGVtZW50IGNvbnRlbnQgKHNlZSB0aGUgYXR0cmlidXRlCisgICAgICogVGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSkuIFNpbWlsYXJseSwgb24gc2V0dGluZywgbm8gcGFyc2luZyBpcworICAgICAqIHBlcmZvcm1lZCBlaXRoZXIsIHRoZSBpbnB1dCBzdHJpbmcgaXMgdGFrZW4gYXMgcHVyZSB0ZXh0dWFsIGNvbnRlbnQuIFRoZQorICAgICAqIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlIGRlcGVuZGluZyBvbiBpdHMKKyAgICAgKiB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgorICAgICAqIDx0YWJsZT4KKyAgICAgKiA8dHI+CisgICAgICogPHRkPjxzdHJvbmc+Tm9kZSB0eXBlPC9zdHJvbmc+PC90ZD4KKyAgICAgKiA8dGQ+PHN0cm9uZz5Db250ZW50PC9zdHJvbmc+PC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+RUxFTUVOVF9OT0RFLCBBVFRSSUJVVEVfTk9ERSwgRU5USVRZX05PREUsIEVOVElUWV9SRUZFUkVOQ0VfTk9ERSwKKyAgICAgKiBET0NVTUVOVF9GUkFHTUVOVF9OT0RFPC90ZD4KKyAgICAgKiA8dGQ+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgdGV4dENvbnRlbnQgYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsCisgICAgICogZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzLiBUaGlzIGlzIHRoZQorICAgICAqIGVtcHR5IHN0cmluZyBpZiB0aGUgbm9kZSBoYXMgbm8gY2hpbGRyZW4uPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+VEVYVF9OT0RFLCBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwKKyAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU8L3RkPgorICAgICAqIDx0ZD5ub2RlVmFsdWU8L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZD5ET0NVTUVOVF9OT0RFLCBET0NVTUVOVF9UWVBFX05PREUsIE5PVEFUSU9OX05PREU8L3RkPgorICAgICAqIDx0ZD5udWxsPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDwvdGFibGU+CisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSB0ZXh0Q29udGVudAorICAgICAqICAgICAgICAgICAgdGhlIHRleHQgY29udGVudCBmb3IgdGhpcyBub2RlLgorICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcworICAgICAqICAgICAgICAgICAgIHJlYWRvbmx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRleHRDb250ZW50KFN0cmluZyB0ZXh0Q29udGVudCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMudGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8aT5EZXNjcmlwdGlvbiBjb3BpZWQgZnJvbSBpbnRlcmZhY2U6IG9yZy53M2MuZG9tLk5vZGUgKERPTSBMZXZlbCAzKTwvaT4KKyAgICAgKiA8cD4KKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBzYW1lIG5vZGUgYXMgdGhlIGdpdmVuIG9uZS4gVGhpcyBtZXRob2QKKyAgICAgKiBwcm92aWRlcyBhIHdheSB0byBkZXRlcm1pbmUgd2hldGhlciB0d28gTm9kZSByZWZlcmVuY2VzIHJldHVybmVkIGJ5IHRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIHJlZmVyZW5jZSB0aGUgc2FtZSBvYmplY3QuIFdoZW4gdHdvIE5vZGUgcmVmZXJlbmNlcyBhcmUKKyAgICAgKiByZWZlcmVuY2VzIHRvIHRoZSBzYW1lIG9iamVjdCwgZXZlbiBpZiB0aHJvdWdoIGEgcHJveHksIHRoZSByZWZlcmVuY2VzCisgICAgICogbWF5IGJlIHVzZWQgY29tcGxldGVseSBpbnRlcmNoYW5nZWFibHksIHN1Y2ggdGhhdCBhbGwgYXR0cmlidXRlcyBoYXZlIHRoZQorICAgICAqIHNhbWUgdmFsdWVzIGFuZCBjYWxsaW5nIHRoZSBzYW1lIERPTSBtZXRob2Qgb24gZWl0aGVyIHJlZmVyZW5jZSBhbHdheXMKKyAgICAgKiBoYXMgZXhhY3RseSB0aGUgc2FtZSBlZmZlY3QuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBvdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG5vZGUgdG8gdGVzdCBhZ2FpbnN0LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIG5vZGVzIGFyZSB0aGUgc2FtZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2FtZU5vZGUoTm9kZSBvdGhlcikgeworICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPGk+RGVzY3JpcHRpb24gY29waWVkIGZyb20gaW50ZXJmYWNlOiBvcmcudzNjLmRvbS5Ob2RlIChET00gTGV2ZWwgMyk8L2k+CisgICAgICogPHA+CisgICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20KKyAgICAgKiB0aGlzIG5vZGUuIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIGlnbm9yZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICogU2VlIGZvciBkZXRhaWxzIG9uIHRoZSBhbGdvcml0aG0gdXNlZCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKiA8L3A+CisgICAgICogCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWVzcGFjZSBVUkkgdG8gbG9vayBmb3IuCisgICAgICogQHJldHVybiB0aGUgYXNzb2NpYXRlZCBuYW1lc3BhY2UgcHJlZml4IGlmIGZvdW5kIG9yIG51bGwgaWYgbm9uZSBpcworICAgICAqICAgICAgICAgZm91bmQuIElmIG1vcmUgdGhhbiBvbmUgcHJlZml4IGFyZSBhc3NvY2lhdGVkIHRvIHRoZSBuYW1lc3BhY2UKKyAgICAgKiAgICAgICAgIHByZWZpeCwgdGhlIHJldHVybmVkIG5hbWVzcGFjZSBwcmVmaXggaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgICAgICAgIGRlcGVuZGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKSB7CisgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8aT5EZXNjcmlwdGlvbiBjb3BpZWQgZnJvbSBpbnRlcmZhY2U6IG9yZy53M2MuZG9tLk5vZGUgKERPTSBMZXZlbCAzKTwvaT4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHNwZWNpZmllZCBuYW1lc3BhY2VVUkkgaXMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlCisgICAgICogb3Igbm90LgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCisgICAgICogICAgICAgICAgICB0aGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgbmFtZXNwYWNlVVJJIGlzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSwKKyAgICAgKiAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZVVSSSkgeworICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPGk+RGVzY3JpcHRpb24gY29waWVkIGZyb20gaW50ZXJmYWNlOiBvcmcudzNjLmRvbS5Ob2RlIChET00gTGV2ZWwgMyk8L2k+CisgICAgICogPHA+CisgICAgICogTG9vayB1cCB0aGUgbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBwcmVmaXgsIHN0YXJ0aW5nIGZyb20KKyAgICAgKiB0aGlzIG5vZGUuIFNlZSBmb3IgZGV0YWlscyBvbiB0aGUgYWxnb3JpdGhtIHVzZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICogPC9wPgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcmVmaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmaXggdG8gbG9vayBmb3IuIElmIHRoaXMgcGFyYW1ldGVyIGlzIG51bGwsIHRoZSBtZXRob2QKKyAgICAgKiAgICAgICAgICAgIHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBVUkkgaWYgYW55LgorICAgICAqIEByZXR1cm4gdGhlIGFzc29jaWF0ZWQgbmFtZXNwYWNlIFVSSSBvciBudWxsIGlmIG5vbmUgaXMgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2VVUkkoU3RyaW5nIHByZWZpeCkgeworICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPGk+RGVzY3JpcHRpb24gY29waWVkIGZyb20gaW50ZXJmYWNlOiBvcmcudzNjLmRvbS5Ob2RlIChET00gTGV2ZWwgMyk8L2k+CisgICAgICogPHA+CisgICAgICogVGVzdHMgd2hldGhlciB0d28gbm9kZXMgYXJlIGVxdWFsLiBUaGlzIG1ldGhvZCB0ZXN0cyBmb3IgZXF1YWxpdHkgb2YKKyAgICAgKiBub2Rlcywgbm90IHNhbWVuZXNzIChpLmUuLCB3aGV0aGVyIHRoZSB0d28gbm9kZXMgYXJlIHJlZmVyZW5jZXMgdG8gdGhlCisgICAgICogc2FtZSBvYmplY3QpIHdoaWNoIGNhbiBiZSB0ZXN0ZWQgd2l0aCBOb2RlLmlzU2FtZU5vZGUoKS4gQWxsIG5vZGVzIHRoYXQKKyAgICAgKiBhcmUgdGhlIHNhbWUgd2lsbCBhbHNvIGJlIGVxdWFsLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLiBUd28KKyAgICAgKiBub2RlcyBhcmUgZXF1YWwgaWYgYW5kIG9ubHkgaWYgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQ6CisgICAgICogPHA+CisgICAgICogPGxpPlRoZSB0d28gbm9kZXMgYXJlIG9mIHRoZSBzYW1lIHR5cGUuPC9saT4KKyAgICAgKiA8bGk+VGhlIGZvbGxvd2luZyBzdHJpbmcgYXR0cmlidXRlcyBhcmUgZXF1YWw6IG5vZGVOYW1lLCBsb2NhbE5hbWUsCisgICAgICogbmFtZXNwYWNlVVJJLCBwcmVmaXgsIG5vZGVWYWx1ZSAuIFRoaXMgaXM6IHRoZXkgYXJlIGJvdGggbnVsbCwgb3IgdGhleQorICAgICAqIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIGFuZCBhcmUgY2hhcmFjdGVyIGZvciBjaGFyYWN0ZXIgaWRlbnRpY2FsLjwvbGk+CisgICAgICogPGxpPlRoZSBhdHRyaWJ1dGVzIE5hbWVkTm9kZU1hcHMgYXJlIGVxdWFsLiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIG51bGwsCisgICAgICogb3IgdGhleSBoYXZlIHRoZSBzYW1lIGxlbmd0aCBhbmQgZm9yIGVhY2ggbm9kZSB0aGF0IGV4aXN0cyBpbiBvbmUgbWFwCisgICAgICogdGhlcmUgaXMgYSBub2RlIHRoYXQgZXhpc3RzIGluIHRoZSBvdGhlciBtYXAgYW5kIGlzIGVxdWFsLCBhbHRob3VnaCBub3QKKyAgICAgKiBuZWNlc3NhcmlseSBhdCB0aGUgc2FtZSBpbmRleC48L2xpPgorICAgICAqIDxsaT5UaGUgY2hpbGROb2RlcyBOb2RlTGlzdHMgYXJlIGVxdWFsLiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIG51bGwsIG9yCisgICAgICogdGhleSBoYXZlIHRoZSBzYW1lIGxlbmd0aCBhbmQgY29udGFpbiBlcXVhbCBub2RlcyBhdCB0aGUgc2FtZSBpbmRleC4gTm90ZQorICAgICAqIHRoYXQgbm9ybWFsaXphdGlvbiBjYW4gYWZmZWN0IGVxdWFsaXR5OyB0byBhdm9pZCB0aGlzLCBub2RlcyBzaG91bGQgYmUKKyAgICAgKiBub3JtYWxpemVkIGJlZm9yZSBiZWluZyBjb21wYXJlZC48L2xpPgorICAgICAqIDwvcD4KKyAgICAgKiBGb3IgdHdvIERvY3VtZW50VHlwZSBub2RlcyB0byBiZSBlcXVhbCwgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG11c3QKKyAgICAgKiBhbHNvIGJlIHNhdGlzZmllZDoKKyAgICAgKiA8cD4KKyAgICAgKiA8bGk+VGhlIGZvbGxvd2luZyBzdHJpbmcgYXR0cmlidXRlcyBhcmUgZXF1YWw6IHB1YmxpY0lkLCBzeXN0ZW1JZCwKKyAgICAgKiBpbnRlcm5hbFN1YnNldC48L2xpPgorICAgICAqIDxsaT5UaGUgZW50aXRpZXMgTmFtZWROb2RlTWFwcyBhcmUgZXF1YWwuPC9saT4KKyAgICAgKiA8bGk+VGhlIG5vdGF0aW9ucyBOYW1lZE5vZGVNYXBzIGFyZSBlcXVhbC48L2xpPgorICAgICAqIDwvcD4KKyAgICAgKiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGZvbGxvd2luZyBkbyBub3QgYWZmZWN0IGVxdWFsaXR5OiB0aGUKKyAgICAgKiBvd25lckRvY3VtZW50LCBiYXNlVVJJLCBhbmQgcGFyZW50Tm9kZSBhdHRyaWJ1dGVzLCB0aGUgc3BlY2lmaWVkCisgICAgICogYXR0cmlidXRlIGZvciBBdHRyIG5vZGVzLCB0aGUgc2NoZW1hVHlwZUluZm8gYXR0cmlidXRlIGZvciBBdHRyIGFuZAorICAgICAqIEVsZW1lbnQgbm9kZXMsIHRoZSBUZXh0LmlzRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlIGF0dHJpYnV0ZSBmb3IgVGV4dAorICAgICAqIG5vZGVzLCBhcyB3ZWxsIGFzIGFueSB1c2VyIGRhdGEgb3IgZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgb24gdGhlCisgICAgICogbm9kZXMuIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlOiBBcyBhIGdlbmVyYWwgcnVsZSwgYW55dGhpbmcgbm90IG1lbnRpb25lZCBpbiB0aGUgZGVzY3JpcHRpb24gYWJvdmUKKyAgICAgKiBpcyBub3Qgc2lnbmlmaWNhbnQgaW4gY29uc2lkZXJhdGlvbiBvZiBlcXVhbGl0eSBjaGVja2luZy4gTm90ZSB0aGF0CisgICAgICogZnV0dXJlIHZlcnNpb25zIG9mIHRoaXMgc3BlY2lmaWNhdGlvbiBtYXkgdGFrZSBpbnRvIGFjY291bnQgbW9yZQorICAgICAqIGF0dHJpYnV0ZXMgYW5kIGltcGxlbWVudGF0aW9ucyBjb25mb3JtIHRvIHRoaXMgc3BlY2lmaWNhdGlvbiBhcmUgZXhwZWN0ZWQKKyAgICAgKiB0byBiZSB1cGRhdGVkIGFjY29yZGluZ2x5LgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICB0aGUgbm9kZSB0byBjb21wYXJlIGVxdWFsaXR5IHdpdGguCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgbm9kZXMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxpPkRlc2NyaXB0aW9uIGNvcGllZCBmcm9tIGludGVyZmFjZTogb3JnLnczYy5kb20uTm9kZSAoRE9NIExldmVsIDMpPC9pPgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBzcGVjaWFsaXplZCBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQKKyAgICAgKiBBUElzIG9mIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbiwgYXMgc3BlY2lmaWVkIGluLiBUaGUKKyAgICAgKiBzcGVjaWFsaXplZCBvYmplY3QgbWF5IGFsc28gYmUgb2J0YWluZWQgYnkgdXNpbmcgYmluZGluZy1zcGVjaWZpYyBjYXN0aW5nCisgICAgICogbWV0aG9kcyBidXQgaXMgbm90IG5lY2Vzc2FyaWx5IGV4cGVjdGVkIHRvLCBhcyBkaXNjdXNzZWQgaW4uIFRoaXMgbWV0aG9kCisgICAgICogYWxzbyBhbGxvdyB0aGUgaW1wbGVtZW50YXRpb24gdG8gcHJvdmlkZSBzcGVjaWFsaXplZCBvYmplY3RzIHdoaWNoIGRvIG5vdAorICAgICAqIHN1cHBvcnQgdGhlIE5vZGUgaW50ZXJmYWNlLgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZmVhdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgcmVxdWVzdGVkLiBOb3RlIHRoYXQgYW55IHBsdXMgc2lnbiAiKyIKKyAgICAgKiAgICAgICAgICAgIHByZXBlbmRlZCB0byB0aGUgbmFtZSBvZiB0aGUgZmVhdHVyZSB3aWxsIGJlIGlnbm9yZWQgc2luY2UgaXQKKyAgICAgKiAgICAgICAgICAgIGlzIG5vdCBzaWduaWZpY2FudCBpbiB0aGUgY29udGV4dCBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQgQVBJcyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBpZiBhbnksIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gb2JqZWN0IHdoaWNoCisgICAgICogICAgICAgICBpbXBsZW1lbnRzIGludGVyZmFjZXMgYXNzb2NpYXRlZCB3aXRoIHRoYXQgZmVhdHVyZS4gSWYgdGhlCisgICAgICogICAgICAgICBET01PYmplY3QgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgTm9kZSBpbnRlcmZhY2UsCisgICAgICogICAgICAgICBpdCBtdXN0IGRlbGVnYXRlIHRvIHRoZSBwcmltYXJ5IGNvcmUgTm9kZSBhbmQgbm90IHJldHVybiByZXN1bHRzCisgICAgICogICAgICAgICBpbmNvbnNpc3RlbnQgd2l0aCB0aGUgcHJpbWFyeSBjb3JlIE5vZGUgc3VjaCBhcyBhdHRyaWJ1dGVzLAorICAgICAqICAgICAgICAgY2hpbGROb2RlcywgZXRjLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8vID8/P0FXVAorICAgIC8qCisgICAgICogcHVibGljIE9iamVjdCBzZXRVc2VyRGF0YShTdHJpbmcga2V5LCBPYmplY3QgZGF0YSwgVXNlckRhdGFIYW5kbGVyCisgICAgICogaGFuZGxlcikgeyB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgKiAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsgfQorICAgICAqLworCisgICAgLyoqCisgICAgICogPGk+RGVzY3JpcHRpb24gY29waWVkIGZyb20gaW50ZXJmYWNlOiBvcmcudzNjLmRvbS5Ob2RlIChET00gTGV2ZWwgMyk8L2k+CisgICAgICogPHA+CisgICAgICogUmV0cmlldmVzIHRoZSBvYmplY3QgYXNzb2NpYXRlZCB0byBhIGtleSBvbiBhIHRoaXMgbm9kZS4gVGhlIG9iamVjdCBtdXN0CisgICAgICogZmlyc3QgaGF2ZSBiZWVuIHNldCB0byB0aGlzIG5vZGUgYnkgY2FsbGluZyBzZXRVc2VyRGF0YSB3aXRoIHRoZSBzYW1lCisgICAgICoga2V5LgorICAgICAqIDwvcD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRoZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB0by4KKyAgICAgKiBAcmV0dXJuIHRoZSBET01Vc2VyRGF0YSBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBrZXkgb24gdGhpcyBub2RlLCBvciBudWxsCisgICAgICogICAgICAgICBpZiB0aGVyZSB3YXMgbm9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gbkNoaWxkcmVuKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIE5vZGUgbjsKKyAgICAgICAgZm9yIChuID0gZ2V0Rmlyc3RDaGlsZCgpOyBpbmRleCA+IDA7IGluZGV4LS0pIHsKKyAgICAgICAgICAgIG4gPSBuLmdldE5leHRTaWJsaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG5DaGlsZHJlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB1c2VyIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBub2RlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHVzZXIgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRVc2VyT2JqZWN0KCkgeworICAgICAgICByZXR1cm4gdXNlck9iamVjdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB1c2VyIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBub2RlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB1c2VyT2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHVzZXIgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlck9iamVjdChPYmplY3QgdXNlck9iamVjdCkgeworICAgICAgICB0aGlzLnVzZXJPYmplY3QgPSB1c2VyT2JqZWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBJSU9NZXRhZGF0YUF0dHIuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBJSU9NZXRhZGF0YUF0dHIgZXh0ZW5kcyBJSU9NZXRhZGF0YU5vZGUgaW1wbGVtZW50cyBBdHRyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG93bmVyIGVsZW1lbnQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEVsZW1lbnQgb3duZXJFbGVtZW50OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgaUlPIG1ldGFkYXRhIGF0dHIuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lLgorICAgICAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdmFsdWUuCisgICAgICAgICAqIEBwYXJhbSBvd25lcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBvd25lci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBJSU9NZXRhZGF0YUF0dHIoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSwgRWxlbWVudCBvd25lcikgeworICAgICAgICAgICAgc3VwZXIobmFtZSwgdmFsdWUpOworICAgICAgICAgICAgdGhpcy5vd25lckVsZW1lbnQgPSBvd25lcjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXROb2RlTmFtZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0U3BlY2lmaWVkKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5vZGVWYWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKFN0cmluZyB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBub2RlVmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFbGVtZW50IGdldE93bmVyRWxlbWVudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBvd25lckVsZW1lbnQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgb3duZXIgZWxlbWVudC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBvd25lckVsZW1lbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmV3IG93bmVyIGVsZW1lbnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzZXRPd25lckVsZW1lbnQoRWxlbWVudCBvd25lckVsZW1lbnQpIHsKKyAgICAgICAgICAgIHRoaXMub3duZXJFbGVtZW50ID0gb3duZXJFbGVtZW50OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEByZXR1cm4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzSWQoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIEFUVFJJQlVURV9OT0RFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIElJT01ldGFkYXRhTm9kZUxpc3QuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBJSU9NZXRhZGF0YU5vZGVMaXN0IGltcGxlbWVudHMgTm9kZUxpc3QsIE5hbWVkTm9kZU1hcCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBsaXN0LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBMaXN0PElJT01ldGFkYXRhTm9kZT4gbGlzdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGlJTyBtZXRhZGF0YSBub2RlIGxpc3QuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gbGlzdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0LgorICAgICAgICAgKi8KKyAgICAgICAgSUlPTWV0YWRhdGFOb2RlTGlzdChMaXN0PElJT01ldGFkYXRhTm9kZT4gbGlzdCkgeworICAgICAgICAgICAgdGhpcy5saXN0ID0gbGlzdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBsaXN0LmdldChpbmRleCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICAgICAgcmV0dXJuIGxpc3Quc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBmb3IgKElJT01ldGFkYXRhTm9kZSBub2RlIDogbGlzdCkgeworICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhub2RlLmdldE5vZGVOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5vZGUgc2V0TmFtZWRJdGVtKE5vZGUgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIlRoaXMgTmFtZWROb2RlTWFwIGlzIHJlYWQtb25seSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCisgICAgICAgICAgICAgICAgICAgICJUaGlzIE5hbWVkTm9kZU1hcCBpcyByZWFkLW9ubHkhIik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTm9kZSBnZXROYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBnZXROYW1lZEl0ZW0obG9jYWxOYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIlRoaXMgTmFtZWROb2RlTWFwIGlzIHJlYWQtb25seSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAorICAgICAgICAgICAgICAgICAgICAiVGhpcyBOYW1lZE5vZGVNYXAgaXMgcmVhZC1vbmx5ISIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPU3RhbmRhcmRNZXRhZGF0YUZvcm1hdC5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPU3RhbmRhcmRNZXRhZGF0YUZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwNmNiMmYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9TdGFuZGFyZE1ldGFkYXRhRm9ybWF0LmphdmEKQEAgLTAsMCArMSwyOTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5tZXRhZGF0YTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VUeXBlU3BlY2lmaWVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKKy8qKgorICogVGhlIGNsYXNzIElJT1N0YW5kYXJkTWV0YWRhdGFGb3JtYXQgZGVzY3JpYmVzIHRoZSBydWxlcyBvZiB0aGUgc3RhbmRhcmQKKyAqIG1ldGFkYXRhIGZvcm1hdC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK2NsYXNzIElJT1N0YW5kYXJkTWV0YWRhdGFGb3JtYXQgZXh0ZW5kcyBJSU9NZXRhZGF0YUZvcm1hdEltcGwgeworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElJT1N0YW5kYXJkTWV0YWRhdGFGb3JtYXQuCisgICAgICovCisgICAgcHVibGljIElJT1N0YW5kYXJkTWV0YWRhdGFGb3JtYXQoKSB7CisgICAgICAgIHN1cGVyKHN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lLCBDSElMRF9QT0xJQ1lfU09NRSk7CisgICAgICAgIGJ1aWxkRFREKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuTm9kZUFwcGVhcihTdHJpbmcgZWxlbWVudE5hbWUsIEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGUpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnVpbGRzIHRoZSBEVEQgdGhhdCBkZXNjcmliZXMgdGhlIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYnVpbGREVEQoKSB7CisgICAgICAgIC8vIENIUk9NQQorICAgICAgICBhZGRFbGVtZW50KCJDaHJvbWEiLCBzdGFuZGFyZE1ldGFkYXRhRm9ybWF0TmFtZSwgQ0hJTERfUE9MSUNZX1NPTUUpOworCisgICAgICAgIGFkZEVsZW1lbnQoIkNvbG9yU3BhY2VUeXBlIiwgIkNocm9tYSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gdmFsdWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KDI3KTsKKyAgICAgICAgdmFsdWVzLmFkZCgiWFlaIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkxhYiIpOworICAgICAgICB2YWx1ZXMuYWRkKCJMdXYiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiWUNiQ3IiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiWXh5Iik7CisgICAgICAgIHZhbHVlcy5hZGQoIllDQ0siKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiUGhvdG9ZQ0MiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiUkdCIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkdSQVkiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiSFNWIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkhMUyIpOworICAgICAgICB2YWx1ZXMuYWRkKCJDTVlLIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkNNWSIpOworICAgICAgICB2YWx1ZXMuYWRkKCIyQ0xSIik7CisgICAgICAgIHZhbHVlcy5hZGQoIjNDTFIiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiNENMUiIpOworICAgICAgICB2YWx1ZXMuYWRkKCI1Q0xSIik7CisgICAgICAgIHZhbHVlcy5hZGQoIjZDTFIiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiN0NMUiIpOworICAgICAgICB2YWx1ZXMuYWRkKCI4Q0xSIik7CisgICAgICAgIHZhbHVlcy5hZGQoIjlDTFIiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiQUNMUiIpOworICAgICAgICB2YWx1ZXMuYWRkKCJCQ0xSIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkNDTFIiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiRENMUiIpOworICAgICAgICB2YWx1ZXMuYWRkKCJFQ0xSIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkZDTFIiKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJDb2xvclNwYWNlVHlwZSIsICJuYW1lIiwgREFUQVRZUEVfU1RSSU5HLCB0cnVlLCBudWxsLCB2YWx1ZXMpOworCisgICAgICAgIGFkZEVsZW1lbnQoIk51bUNoYW5uZWxzIiwgIkNocm9tYSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiTnVtQ2hhbm5lbHMiLCAidmFsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSk7IC8vIGxpc3QKKyAgICAgICAgLy8gLQorICAgICAgICAvLyB3aHkKKyAgICAgICAgLy8gPworCisgICAgICAgIGFkZEVsZW1lbnQoIkdhbW1hIiwgIkNocm9tYSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiR2FtbWEiLCAidmFsdWUiLCBEQVRBVFlQRV9GTE9BVCwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiQmxhY2tJc1plcm8iLCAiQ2hyb21hIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQm9vbGVhbkF0dHJpYnV0ZSgiQmxhY2tJc1plcm8iLCAidmFsdWUiLCB0cnVlLCB0cnVlKTsKKworICAgICAgICBhZGRFbGVtZW50KCJQYWxldHRlIiwgIkNocm9tYSIsIDAsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gQ0hJTERfUE9MSUNZX1JFUEVBVAorICAgICAgICBhZGRFbGVtZW50KCJQYWxldHRlRW50cnkiLCAiUGFsZXR0ZSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiUGFsZXR0ZUVudHJ5IiwgImluZGV4IiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiUGFsZXR0ZUVudHJ5IiwgInJlZCIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlBhbGV0dGVFbnRyeSIsICJncmVlbiIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlBhbGV0dGVFbnRyeSIsICJibHVlIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiUGFsZXR0ZUVudHJ5IiwgImFscGhhIiwgREFUQVRZUEVfSU5URUdFUiwgZmFsc2UsICIyNTUiKTsKKworICAgICAgICBhZGRFbGVtZW50KCJCYWNrZ3JvdW5kSW5kZXgiLCAiQ2hyb21hIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJCYWNrZ3JvdW5kSW5kZXgiLCAidmFsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKworICAgICAgICBhZGRFbGVtZW50KCJCYWNrZ3JvdW5kQ29sb3IiLCAiQ2hyb21hIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJCYWNrZ3JvdW5kQ29sb3IiLCAicmVkIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiQmFja2dyb3VuZENvbG9yIiwgImdyZWVuIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiQmFja2dyb3VuZENvbG9yIiwgImJsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKworICAgICAgICAvLyBDT01QUkVTU0lPTgorICAgICAgICBhZGRFbGVtZW50KCJDb21wcmVzc2lvbiIsIHN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lLCBDSElMRF9QT0xJQ1lfU09NRSk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiQ29tcHJlc3Npb25UeXBlTmFtZSIsICJDb21wcmVzc2lvbiIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiQ29tcHJlc3Npb25UeXBlTmFtZSIsICJ2YWx1ZSIsIERBVEFUWVBFX1NUUklORywgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiTG9zc2xlc3MiLCAiQ29tcHJlc3Npb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRCb29sZWFuQXR0cmlidXRlKCJMb3NzbGVzcyIsICJ2YWx1ZSIsIHRydWUsIHRydWUpOworCisgICAgICAgIGFkZEVsZW1lbnQoIk51bVByb2dyZXNzaXZlU2NhbnMiLCAiQ29tcHJlc3Npb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIk51bVByb2dyZXNzaXZlU2NhbnMiLCAidmFsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKworICAgICAgICBhZGRFbGVtZW50KCJCaXRSYXRlIiwgIkNvbXByZXNzaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJCaXRSYXRlIiwgInZhbHVlIiwgREFUQVRZUEVfRkxPQVQsIHRydWUsIG51bGwpOworCisgICAgICAgIC8vIERBVEEKKyAgICAgICAgYWRkRWxlbWVudCgiRGF0YSIsIHN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lLCBDSElMRF9QT0xJQ1lfU09NRSk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiUGxhbmFyQ29uZmlndXJhdGlvbiIsICJEYXRhIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgdmFsdWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KDQpOworICAgICAgICB2YWx1ZXMuYWRkKCJQaXhlbEludGVybGVhdmVkIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlBsYW5lSW50ZXJsZWF2ZWQiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiTGluZUludGVybGVhdmVkIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlRpbGVJbnRlcmxlYXZlZCIpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlBsYW5hckNvbmZpZ3VyYXRpb24iLCAidmFsdWUiLCBEQVRBVFlQRV9TVFJJTkcsIHRydWUsIG51bGwsIHZhbHVlcyk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiU2FtcGxlRm9ybWF0IiwgIkRhdGEiLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICB2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oNCk7CisgICAgICAgIHZhbHVlcy5hZGQoIlNpZ25lZEludGVncmFsIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlVuc2lnbmVkSW50ZWdyYWwiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiUmVhbCIpOworICAgICAgICB2YWx1ZXMuYWRkKCJJbmRleCIpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlNhbXBsZUZvcm1hdCIsICJ2YWx1ZSIsIERBVEFUWVBFX1NUUklORywgdHJ1ZSwgbnVsbCwgdmFsdWVzKTsKKworICAgICAgICBhZGRFbGVtZW50KCJCaXRzUGVyU2FtcGxlIiwgIkRhdGEiLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkJpdHNQZXJTYW1wbGUiLCAidmFsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCAxLCBJbnRlZ2VyLk1BWF9WQUxVRSk7IC8vIGxpc3QKKworICAgICAgICBhZGRFbGVtZW50KCJTaWduaWZpY2FudEJpdHNQZXJTYW1wbGUiLCAiRGF0YSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiU2lnbmlmaWNhbnRCaXRzUGVyU2FtcGxlIiwgInZhbHVlIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgMSwKKyAgICAgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSk7IC8vIGxpc3QKKworICAgICAgICBhZGRFbGVtZW50KCJTYW1wbGVNU0IiLCAiRGF0YSIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiU2FtcGxlTVNCIiwgInZhbHVlIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgMSwgSW50ZWdlci5NQVhfVkFMVUUpOyAvLyBsaXN0CisKKyAgICAgICAgLy8gRElNRU5TSU9OCisgICAgICAgIGFkZEVsZW1lbnQoIkRpbWVuc2lvbiIsIHN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lLCBDSElMRF9QT0xJQ1lfU09NRSk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiUGl4ZWxBc3BlY3RSYXRpbyIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlBpeGVsQXNwZWN0UmF0aW8iLCAidmFsdWUiLCBEQVRBVFlQRV9GTE9BVCwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiSW1hZ2VPcmllbnRhdGlvbiIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICB2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oOCk7CisgICAgICAgIHZhbHVlcy5hZGQoIk5vcm1hbCIpOworICAgICAgICB2YWx1ZXMuYWRkKCJSb3RhdGU5MCIpOworICAgICAgICB2YWx1ZXMuYWRkKCJSb3RhdGUxODAiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiUm90YXRlMjcwIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkZsaXBIIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkZsaXBWIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkZsaXBIUm90YXRlOTAiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiRmxpcFZSb3RhdGU5MCIpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkltYWdlT3JpZW50YXRpb24iLCAidmFsdWUiLCBEQVRBVFlQRV9TVFJJTkcsIHRydWUsIG51bGwsIHZhbHVlcyk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiSG9yaXpvbnRhbFBpeGVsU2l6ZSIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkhvcml6b250YWxQaXhlbFNpemUiLCAidmFsdWUiLCBEQVRBVFlQRV9GTE9BVCwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiVmVydGljYWxQaXhlbFNpemUiLCAiRGltZW5zaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJWZXJ0aWNhbFBpeGVsU2l6ZSIsICJ2YWx1ZSIsIERBVEFUWVBFX0ZMT0FULCB0cnVlLCBudWxsKTsKKworICAgICAgICBhZGRFbGVtZW50KCJIb3Jpem9udGFsUGh5c2ljYWxQaXhlbFNwYWNpbmciLCAiRGltZW5zaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJIb3Jpem9udGFsUGh5c2ljYWxQaXhlbFNwYWNpbmciLCAidmFsdWUiLCBEQVRBVFlQRV9GTE9BVCwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiVmVydGljYWxQaHlzaWNhbFBpeGVsU3BhY2luZyIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlZlcnRpY2FsUGh5c2ljYWxQaXhlbFNwYWNpbmciLCAidmFsdWUiLCBEQVRBVFlQRV9GTE9BVCwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiSG9yaXpvbnRhbFBvc2l0aW9uIiwgIkRpbWVuc2lvbiIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiSG9yaXpvbnRhbFBvc2l0aW9uIiwgInZhbHVlIiwgREFUQVRZUEVfRkxPQVQsIHRydWUsIG51bGwpOworCisgICAgICAgIGFkZEVsZW1lbnQoIlZlcnRpY2FsUG9zaXRpb24iLCAiRGltZW5zaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJWZXJ0aWNhbFBvc2l0aW9uIiwgInZhbHVlIiwgREFUQVRZUEVfRkxPQVQsIHRydWUsIG51bGwpOworCisgICAgICAgIGFkZEVsZW1lbnQoIkhvcml6b250YWxQaXhlbE9mZnNldCIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkhvcml6b250YWxQaXhlbE9mZnNldCIsICJ2YWx1ZSIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwpOworCisgICAgICAgIGFkZEVsZW1lbnQoIlZlcnRpY2FsUGl4ZWxPZmZzZXQiLCAiRGltZW5zaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJWZXJ0aWNhbFBpeGVsT2Zmc2V0IiwgInZhbHVlIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiSG9yaXpvbnRhbFNjcmVlblNpemUiLCAiRGltZW5zaW9uIiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJIb3Jpem9udGFsU2NyZWVuU2l6ZSIsICJ2YWx1ZSIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwpOworCisgICAgICAgIGFkZEVsZW1lbnQoIlZlcnRpY2FsU2NyZWVuU2l6ZSIsICJEaW1lbnNpb24iLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlZlcnRpY2FsU2NyZWVuU2l6ZSIsICJ2YWx1ZSIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwpOworCisgICAgICAgIC8vIERPQ1VNRU5UCisgICAgICAgIGFkZEVsZW1lbnQoIkRvY3VtZW50Iiwgc3RhbmRhcmRNZXRhZGF0YUZvcm1hdE5hbWUsIENISUxEX1BPTElDWV9TT01FKTsKKworICAgICAgICBhZGRFbGVtZW50KCJGb3JtYXRWZXJzaW9uIiwgIkRvY3VtZW50IiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJGb3JtYXRWZXJzaW9uIiwgInZhbHVlIiwgREFUQVRZUEVfU1RSSU5HLCB0cnVlLCBudWxsKTsKKworICAgICAgICBhZGRFbGVtZW50KCJTdWJpbWFnZUludGVycHJldGF0aW9uIiwgIkRvY3VtZW50IiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgdmFsdWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KDE0KTsKKyAgICAgICAgdmFsdWVzLmFkZCgiU3RhbmRhbG9uZSIpOworICAgICAgICB2YWx1ZXMuYWRkKCJTaW5nbGVQYWdlIik7CisgICAgICAgIHZhbHVlcy5hZGQoIkZ1bGxSZXNvbHV0aW9uIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlJlZHVjZWRSZXNvbHV0aW9uIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlB5cmFtaWRMYXllciIpOworICAgICAgICB2YWx1ZXMuYWRkKCJQcmV2aWV3Iik7CisgICAgICAgIHZhbHVlcy5hZGQoIlZvbHVtZVNsaWNlIik7CisgICAgICAgIHZhbHVlcy5hZGQoIk9iamVjdFZpZXciKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiUGFub3JhbWEiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiQW5pbWF0aW9uRnJhbWUiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiVHJhbnNwYXJlbmN5TWFzayIpOworICAgICAgICB2YWx1ZXMuYWRkKCJDb21wb3NpdGluZ0xheWVyIik7CisgICAgICAgIHZhbHVlcy5hZGQoIlNwZWN0cmFsU2xpY2UiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiVW5rbm93biIpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlN1YmltYWdlSW50ZXJwcmV0YXRpb24iLCAidmFsdWUiLCBEQVRBVFlQRV9TVFJJTkcsIHRydWUsIG51bGwsIHZhbHVlcyk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiSW1hZ2VDcmVhdGlvblRpbWUiLCAiRG9jdW1lbnQiLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkltYWdlQ3JlYXRpb25UaW1lIiwgInllYXIiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZUNyZWF0aW9uVGltZSIsICJtb250aCIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwsICIxIiwgIjEyIiwgdHJ1ZSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZUNyZWF0aW9uVGltZSIsICJkYXkiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsLCAiMSIsICIzMSIsIHRydWUsCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiSW1hZ2VDcmVhdGlvblRpbWUiLCAiaG91ciIsIERBVEFUWVBFX0lOVEVHRVIsIGZhbHNlLCAiMCIsICIwIiwgIjIzIiwgdHJ1ZSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZUNyZWF0aW9uVGltZSIsICJtaW51dGUiLCBEQVRBVFlQRV9JTlRFR0VSLCBmYWxzZSwgIjAiLCAiMCIsICI1OSIsIHRydWUsCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiSW1hZ2VDcmVhdGlvblRpbWUiLCAic2Vjb25kIiwgREFUQVRZUEVfSU5URUdFUiwgZmFsc2UsICIwIiwgIjAiLCAiNjAiLCB0cnVlLAorICAgICAgICAgICAgICAgIHRydWUpOworCisgICAgICAgIGFkZEVsZW1lbnQoIkltYWdlTW9kaWZpY2F0aW9uVGltZSIsICJEb2N1bWVudCIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiSW1hZ2VNb2RpZmljYXRpb25UaW1lIiwgInllYXIiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZU1vZGlmaWNhdGlvblRpbWUiLCAibW9udGgiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsLCAiMSIsICIxMiIsCisgICAgICAgICAgICAgICAgdHJ1ZSwgdHJ1ZSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiSW1hZ2VNb2RpZmljYXRpb25UaW1lIiwgImRheSIsIERBVEFUWVBFX0lOVEVHRVIsIHRydWUsIG51bGwsICIxIiwgIjMxIiwgdHJ1ZSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZU1vZGlmaWNhdGlvblRpbWUiLCAiaG91ciIsIERBVEFUWVBFX0lOVEVHRVIsIGZhbHNlLCAiMCIsICIwIiwgIjIzIiwKKyAgICAgICAgICAgICAgICB0cnVlLCB0cnVlKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJJbWFnZU1vZGlmaWNhdGlvblRpbWUiLCAibWludXRlIiwgREFUQVRZUEVfSU5URUdFUiwgZmFsc2UsICIwIiwgIjAiLCAiNTkiLAorICAgICAgICAgICAgICAgIHRydWUsIHRydWUpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkltYWdlTW9kaWZpY2F0aW9uVGltZSIsICJzZWNvbmQiLCBEQVRBVFlQRV9JTlRFR0VSLCBmYWxzZSwgIjAiLCAiMCIsICI2MCIsCisgICAgICAgICAgICAgICAgdHJ1ZSwgdHJ1ZSk7CisKKyAgICAgICAgLy8gVEVYVAorICAgICAgICBhZGRFbGVtZW50KCJUZXh0Iiwgc3RhbmRhcmRNZXRhZGF0YUZvcm1hdE5hbWUsIDAsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gQ0hJTERfUE9MSUNZX1JFUEVBVAorCisgICAgICAgIGFkZEVsZW1lbnQoIlRleHRFbnRyeSIsICJUZXh0IiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJUZXh0RW50cnkiLCAia2V5d29yZCIsIERBVEFUWVBFX1NUUklORywgZmFsc2UsIG51bGwpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlRleHRFbnRyeSIsICJ2YWx1ZSIsIERBVEFUWVBFX1NUUklORywgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiVGV4dEVudHJ5IiwgImxhbmd1YWdlIiwgREFUQVRZUEVfU1RSSU5HLCBmYWxzZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiVGV4dEVudHJ5IiwgImVuY29kaW5nIiwgREFUQVRZUEVfU1RSSU5HLCBmYWxzZSwgbnVsbCk7CisgICAgICAgIHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPig1KTsKKyAgICAgICAgdmFsdWVzLmFkZCgibm9uZSIpOworICAgICAgICB2YWx1ZXMuYWRkKCJsenciKTsKKyAgICAgICAgdmFsdWVzLmFkZCgiemlwIik7CisgICAgICAgIHZhbHVlcy5hZGQoImJ6aXAiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgib3RoZXIiKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJUZXh0RW50cnkiLCAiY29tcHJlc3Npb24iLCBEQVRBVFlQRV9TVFJJTkcsIGZhbHNlLCAibm9uZSIsIHZhbHVlcyk7CisKKyAgICAgICAgLy8gVFJBTlNQQVJFTkNZCisgICAgICAgIGFkZEVsZW1lbnQoIlRyYW5zcGFyZW5jeSIsIHN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lLCBDSElMRF9QT0xJQ1lfU09NRSk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiQWxwaGEiLCAiVHJhbnNwYXJlbmN5IiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgdmFsdWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KDMpOworICAgICAgICB2YWx1ZXMuYWRkKCJub25lIik7CisgICAgICAgIHZhbHVlcy5hZGQoInByZW11bHRpcGxpZWQiKTsKKyAgICAgICAgdmFsdWVzLmFkZCgibm9ucHJlbXVsdGlwbGllZCIpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIkFscGhhIiwgInZhbHVlIiwgREFUQVRZUEVfU1RSSU5HLCBmYWxzZSwgIm5vbmUiLCB2YWx1ZXMpOworCisgICAgICAgIGFkZEVsZW1lbnQoIlRyYW5zcGFyZW50SW5kZXgiLCAiVHJhbnNwYXJlbmN5IiwgQ0hJTERfUE9MSUNZX0VNUFRZKTsKKyAgICAgICAgYWRkQXR0cmlidXRlKCJUcmFuc3BhcmVudEluZGV4IiwgInZhbHVlIiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiVHJhbnNwYXJlbnRDb2xvciIsICJUcmFuc3BhcmVuY3kiLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlRyYW5zcGFyZW50Q29sb3IiLCAidmFsdWUiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisKKyAgICAgICAgYWRkRWxlbWVudCgiVGlsZVRyYW5zcGFyZW5jaWVzIiwgIlRyYW5zcGFyZW5jeSIsIDAsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gQ0hJTERfUE9MSUNZX1JFUEVBVAorCisgICAgICAgIGFkZEVsZW1lbnQoIlRyYW5zcGFyZW50VGlsZSIsICJUaWxlVHJhbnNwYXJlbmNpZXMiLCBDSElMRF9QT0xJQ1lfRU1QVFkpOworICAgICAgICBhZGRBdHRyaWJ1dGUoIlRyYW5zcGFyZW50VGlsZSIsICJ4IiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiVHJhbnNwYXJlbnRUaWxlIiwgInkiLCBEQVRBVFlQRV9JTlRFR0VSLCB0cnVlLCBudWxsKTsKKworICAgICAgICBhZGRFbGVtZW50KCJUaWxlT3BhY2l0aWVzIiwgIlRyYW5zcGFyZW5jeSIsIDAsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gQ0hJTERfUE9MSUNZX1JFUEVBVAorCisgICAgICAgIGFkZEVsZW1lbnQoIk9wYXF1ZVRpbGUiLCAiVGlsZU9wYWNpdGllcyIsIENISUxEX1BPTElDWV9FTVBUWSk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiT3BhcXVlVGlsZSIsICJ4IiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgICAgIGFkZEF0dHJpYnV0ZSgiT3BhcXVlVGlsZSIsICJ5IiwgREFUQVRZUEVfSU5URUdFUiwgdHJ1ZSwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPU3RhbmRhcmRNZXRhZGF0YUZvcm1hdFJlc291cmNlcy5wcm9wZXJ0aWVzIGIvYXd0L2phdmF4L2ltYWdlaW8vbWV0YWRhdGEvSUlPU3RhbmRhcmRNZXRhZGF0YUZvcm1hdFJlc291cmNlcy5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxODU4MDgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9JSU9TdGFuZGFyZE1ldGFkYXRhRm9ybWF0UmVzb3VyY2VzLnByb3BlcnRpZXMKQEAgLTAsMCArMSwxMzMgQEAKKyMgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisjIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisjICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisjIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIyBEZXNjcmlwdGlvbnMgb2YgZWxlbWVudHMgYW5kIGF0dHJpYnV0ZXMgb2YgdGhlIHBsdWdpbiBuZXV0cmFsIG1ldGFkYXRhIGZvcm1hdAorIyAoc2VlIElJT1N0YW5kYXJkTWV0YWRhdGFGb3JtYXQpCisKKyMgTWVzc2FnZXMgZm9yIEVOIGxvY2FsZQorQ2hyb21hPUNocm9tYSAoY29sb3IpIGluZm9ybWF0aW9uCitDb2xvclNwYWNlVHlwZT1UaGUgcmF3IGNvbG9yIHNwYWNlIG9mIHRoZSBpbWFnZQorQ29sb3JTcGFjZVR5cGUvbmFtZT1UaGUgcmF3IGNvbG9yIHNwYWNlIG9mIHRoZSBpbWFnZQorTnVtQ2hhbm5lbHM9VGhlIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgcmF3IGltYWdlLCBpbmNsdWRpbmcgYWxwaGEKK051bUNoYW5uZWxzL3ZhbHVlPVRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHJhdyBpbWFnZSwgaW5jbHVkaW5nIGFscGhhCitHYW1tYT1UaGUgaW1hZ2UgZ2FtbWEKK0dhbW1hL3ZhbHVlPVRoZSBpbWFnZSBnYW1tYQorQmxhY2tJc1plcm89VHJ1ZSBpZiBzbWFsbGVyIHZhbHVlcyByZXByZXNlbnQgZGFya2VyIHNoYWRlcworQmxhY2tJc1plcm8vdmFsdWU9VHJ1ZSBpZiBzbWFsbGVyIHZhbHVlcyByZXByZXNlbnQgZGFya2VyIHNoYWRlcworUGFsZXR0ZT1QYWxldHRlLWNvbG9yIGluZm9ybWF0aW9uCitQYWxldHRlRW50cnk9QSBwYWxldHRlIGVudHJ5CitQYWxldHRlRW50cnkvaW5kZXg9VGhlIGluZGV4IG9mIHRoZSBwYWxldHRlIGVudHJ5CitQYWxldHRlRW50cnkvcmVkPVRoZSByZWQgdmFsdWUgZm9yIHRoZSBwYWxldHRlIGVudHJ5CitQYWxldHRlRW50cnkvZ3JlZW49VGhlIGdyZWVuIHZhbHVlIGZvciB0aGUgcGFsZXR0ZSBlbnRyeQorUGFsZXR0ZUVudHJ5L2JsdWU9VGhlIGJsdWUgdmFsdWUgZm9yIHRoZSBwYWxldHRlIGVudHJ5CitQYWxldHRlRW50cnkvYWxwaGE9VGhlIGFscGhhIHZhbHVlIGZvciB0aGUgcGFsZXR0ZSBlbnRyeQorQmFja2dyb3VuZEluZGV4PUEgcGFsZXR0ZSBpbmRleCB0byBiZSB1c2VkIGFzIGEgYmFja2dyb3VuZAorQmFja2dyb3VuZEluZGV4L3ZhbHVlPUEgcGFsZXR0ZSBpbmRleCB0byBiZSB1c2VkIGFzIGEgYmFja2dyb3VuZAorQmFja2dyb3VuZENvbG9yPUFuIFJHQiB0cmlwbGUgdG8gYmUgdXNlZCBhcyBhIGJhY2tncm91bmQKK0JhY2tncm91bmRDb2xvci9yZWQ9VGhlIHJlZCBiYWNrZ3JvdW5kIHZhbHVlCitCYWNrZ3JvdW5kQ29sb3IvZ3JlZW49VGhlIGdyZWVuIGJhY2tncm91bmQgdmFsdWUKK0JhY2tncm91bmRDb2xvci9ibHVlPVRoZSBibHVlIGJhY2tncm91bmQgdmFsdWUKKworQ29tcHJlc3Npb249Q29tcHJlc3Npb24gaW5mb3JtYXRpb24KK0NvbXByZXNzaW9uVHlwZU5hbWU9VGhlIG5hbWUgb2YgdGhlIGNvbXByZXNzaW9uIHNjaGVtZSBpbiB1c2UKK0NvbXByZXNzaW9uVHlwZU5hbWUvdmFsdWU9VGhlIG5hbWUgb2YgdGhlIGNvbXByZXNzaW9uIHNjaGVtZSBpbiB1c2UKK0xvc3NsZXNzPVRydWUgaWYgdGhlIGNvbXByZXNzaW9uIHNjaGVtZSBpcyBsb3NzbGVzcworTG9zc2xlc3MvdmFsdWU9VHJ1ZSBpZiB0aGUgY29tcHJlc3Npb24gc2NoZW1lIGlzIGxvc3NsZXNzCitOdW1Qcm9ncmVzc2l2ZVNjYW5zPVRoZSBudW1iZXIgb2YgcHJvZ3Jlc3NpdmUgc2NhbnMgdXNlZCBpbiB0aGUgaW1hZ2UgZW5jb2RpbmcKK051bVByb2dyZXNzaXZlU2NhbnMvdmFsdWU9VGhlIG51bWJlciBvZiBwcm9ncmVzc2l2ZSBzY2FucyB1c2VkIGluIHRoZSBpbWFnZSBlbmNvZGluZworQml0UmF0ZT1UaGUgZXN0aW1hdGVkIGJpdCByYXRlIG9mIHRoZSBjb21wcmVzc2lvbiBzY2hlbWUKK0JpdFJhdGUvdmFsdWU9VGhlIGVzdGltYXRlZCBiaXQgcmF0ZSBvZiB0aGUgY29tcHJlc3Npb24gc2NoZW1lCisKK0RhdGE9SW5mb3JtYXRpb24gb24gdGhlIGltYWdlIGxheW91dAorUGxhbmFyQ29uZmlndXJhdGlvbj1UaGUgb3JnYW5pemF0aW9uIG9mIGltYWdlIHNhbXBsZXMgaW4gdGhlIHN0cmVhbQorUGxhbmFyQ29uZmlndXJhdGlvbi92YWx1ZT1UaGUgb3JnYW5pemF0aW9uIG9mIGltYWdlIHNhbXBsZXMgaW4gdGhlIHN0cmVhbQorU2FtcGxlRm9ybWF0PVRoZSBudW1lcmljIGZvcm1hdCBvZiBpbWFnZSBzYW1wbGVzCitTYW1wbGVGb3JtYXQvdmFsdWU9VGhlIG51bWVyaWMgZm9ybWF0IG9mIGltYWdlIHNhbXBsZXMKK0JpdHNQZXJTYW1wbGU9VGhlIG51bWJlciBvZiBiaXRzIHBlciBzYW1wbGUKK0JpdHNQZXJTYW1wbGUvdmFsdWU9QSBsaXN0IG9mIGludGVnZXJzLCBvbmUgcGVyIGNoYW5uZWwKK1NpZ25pZmljYW50Qml0c1BlclNhbXBsZT1UaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJpdHMgcGVyIHNhbXBsZQorU2lnbmlmaWNhbnRCaXRzUGVyU2FtcGxlL3ZhbHVlPUEgbGlzdCBvZiBpbnRlZ2Vycywgb25lIHBlciBjaGFubmVsCitTYW1wbGVNU0I9VGhlIHBvc2l0aW9uIG9mIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBvZiBlYWNoIHNhbXBsZQorU2FtcGxlTVNCL3ZhbHVlPUEgbGlzdCBvZiBpbnRlZ2Vycywgb25lIHBlciBjaGFubmVsCisKK0RpbWVuc2lvbj1EaW1lbnNpb24gaW5mb3JtYXRpb24KK1BpeGVsQXNwZWN0UmF0aW89VGhlIHdpZHRoIG9mIGEgcGl4ZWwgZGl2aWRlZCBieSBpdHMgaGVpZ2h0CitQaXhlbEFzcGVjdFJhdGlvL3ZhbHVlPVRoZSB3aWR0aCBvZiBhIHBpeGVsIGRpdmlkZWQgYnkgaXRzIGhlaWdodAorSW1hZ2VPcmllbnRhdGlvbj1UaGUgZGVzaXJlZCBvcmllbnRhdGlvbiBvZiB0aGUgaW1hZ2UgaW4gdGVybXMgb2YgZmxpcHMgYW5kIGNvdW50ZXItY2xvY2t3aXNlIHJvdGF0aW9ucworSW1hZ2VPcmllbnRhdGlvbi92YWx1ZT1UaGUgZGVzaXJlZCBvcmllbnRhdGlvbiBvZiB0aGUgaW1hZ2UgaW4gdGVybXMgb2YgZmxpcHMgYW5kIGNvdW50ZXItY2xvY2t3aXNlIHJvdGF0aW9ucworSG9yaXpvbnRhbFBpeGVsU2l6ZT1UaGUgd2lkdGggb2YgYSBwaXhlbCwgaW4gbWlsbGltZXRlcnMsIGFzIGl0IHNob3VsZCBiZSByZW5kZXJlZCBvbiBtZWRpYQorSG9yaXpvbnRhbFBpeGVsU2l6ZS92YWx1ZT1UaGUgd2lkdGggb2YgYSBwaXhlbCwgaW4gbWlsbGltZXRlcnMsIGFzIGl0IHNob3VsZCBiZSByZW5kZXJlZCBvbiBtZWRpYQorVmVydGljYWxQaXhlbFNpemU9VGhlIGhlaWdodCBvZiBhIHBpeGVsLCBpbiBtaWxsaW1ldGVycywgYXMgaXQgc2hvdWxkIGJlIHJlbmRlcmVkIG9uIG1lZGlhCitWZXJ0aWNhbFBpeGVsU2l6ZS92YWx1ZT1UaGUgaGVpZ2h0IG9mIGEgcGl4ZWwsIGluIG1pbGxpbWV0ZXJzLCBhcyBpdCBzaG91bGQgYmUgcmVuZGVyZWQgb24gbWVkaWEKK0hvcml6b250YWxQaHlzaWNhbFBpeGVsU3BhY2luZz1UaGUgaG9yaXpvbnRhbCBkaXN0YW5jZSBpbiB0aGUgc3ViamVjdCBvZiB0aGUgaW1hZ2UsIGluIG1pbGxpbWV0ZXJzLCByZXByZXNlbnRlZCBieSBvbmUgcGl4ZWwgYXQgdGhlIGNlbnRlciBvZiB0aGUgaW1hZ2UKK0hvcml6b250YWxQaHlzaWNhbFBpeGVsU3BhY2luZy92YWx1ZT1UaGUgaG9yaXpvbnRhbCBkaXN0YW5jZSBpbiB0aGUgc3ViamVjdCBvZiB0aGUgaW1hZ2UsIGluIG1pbGxpbWV0ZXJzLCByZXByZXNlbnRlZCBieSBvbmUgcGl4ZWwgYXQgdGhlIGNlbnRlciBvZiB0aGUgaW1hZ2UKK1ZlcnRpY2FsUGh5c2ljYWxQaXhlbFNwYWNpbmc9VGhlIHZlcnRpY2FsIGRpc3RhbmNlIGluIHRoZSBzdWJqZWN0IG9mIHRoZSBpbWFnZSwgaW4gbWlsbGltZXRlcnMsIHJlcHJlc2VudGVkIGJ5IG9uZSBwaXhlbCBhdCB0aGUgY2VudGVyIG9mIHRoZSBpbWFnZQorVmVydGljYWxQaHlzaWNhbFBpeGVsU3BhY2luZy92YWx1ZT1UaGUgdmVydGljYWwgZGlzdGFuY2UgaW4gdGhlIHN1YmplY3Qgb2YgdGhlIGltYWdlLCBpbiBtaWxsaW1ldGVycywgcmVwcmVzZW50ZWQgYnkgb25lIHBpeGVsIGF0IHRoZSBjZW50ZXIgb2YgdGhlIGltYWdlCitIb3Jpem9udGFsUG9zaXRpb249VGhlIGhvcml6b250YWwgcG9zaXRpb24sIGluIG1pbGxpbWV0ZXJzLCB3aGVyZSB0aGUgaW1hZ2Ugc2hvdWxkIGJlIHJlbmRlcmVkIG9uIG1lZGlhCitIb3Jpem9udGFsUG9zaXRpb24vdmFsdWU9VGhlIGhvcml6b250YWwgcG9zaXRpb24sIGluIG1pbGxpbWV0ZXJzLCB3aGVyZSB0aGUgaW1hZ2Ugc2hvdWxkIGJlIHJlbmRlcmVkIG9uIG1lZGlhCitWZXJ0aWNhbFBvc2l0aW9uPVRoZSB2ZXJ0aWNhbCBwb3NpdGlvbiwgaW4gbWlsbGltZXRlcnMsIHdoZXJlIHRoZSBpbWFnZSBzaG91bGQgYmUgcmVuZGVyZWQgb24gbWVkaWEKK1ZlcnRpY2FsUG9zaXRpb24vdmFsdWU9VGhlIHZlcnRpY2FsIHBvc2l0aW9uLCBpbiBtaWxsaW1ldGVycywgd2hlcmUgdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZCBvbiBtZWRpYQorSG9yaXpvbnRhbFBpeGVsT2Zmc2V0PVRoZSBob3Jpem9uYWwgcG9zaXRpb24sIGluIHBpeGVscywgd2hlcmUgdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZCBvbnRvIGEgcmFzdGVyIGRpc3BsYXkKK0hvcml6b250YWxQaXhlbE9mZnNldC92YWx1ZT1UaGUgaG9yaXpvbmFsIHBvc2l0aW9uLCBpbiBwaXhlbHMsIHdoZXJlIHRoZSBpbWFnZSBzaG91bGQgYmUgcmVuZGVyZWQgb250byBhIHJhc3RlciBkaXNwbGF5CitWZXJ0aWNhbFBpeGVsT2Zmc2V0PVRoZSB2ZXJ0aWNhbCBwb3NpdGlvbiwgaW4gcGl4ZWxzLCB3aGVyZSB0aGUgaW1hZ2Ugc2hvdWxkIGJlIHJlbmRlcmVkIG9udG8gYSByYXN0ZXIgZGlzcGxheQorVmVydGljYWxQaXhlbE9mZnNldC92YWx1ZT1UaGUgdmVydGljYWwgcG9zaXRpb24sIGluIHBpeGVscywgd2hlcmUgdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZCBvbnRvIGEgcmFzdGVyIGRpc3BsYXkKK0hvcml6b250YWxTY3JlZW5TaXplPVRoZSB3aWR0aCwgaW4gcGl4ZWxzLCBvZiB0aGUgcmFzdGVyIGRpc3BsYXkgaW50byB3aGljaCB0aGUgaW1hZ2Ugc2hvdWxkIGJlIHJlbmRlcmVkCitIb3Jpem9udGFsU2NyZWVuU2l6ZS92YWx1ZT1UaGUgd2lkdGgsIGluIHBpeGVscywgb2YgdGhlIHJhc3RlciBkaXNwbGF5IGludG8gd2hpY2ggdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZAorVmVydGljYWxTY3JlZW5TaXplPVRoZSBoZWlnaHQsIGluIHBpeGVscywgb2YgdGhlIHJhc3RlciBkaXNwbGF5IGludG8gd2hpY2ggdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZAorVmVydGljYWxTY3JlZW5TaXplL3ZhbHVlPVRoZSBoZWlnaHQsIGluIHBpeGVscywgb2YgdGhlIHJhc3RlciBkaXNwbGF5IGludG8gd2hpY2ggdGhlIGltYWdlIHNob3VsZCBiZSByZW5kZXJlZAorCitEb2N1bWVudD1Eb2N1bWVudCBpbmZvcm1hdGlvbgorRm9ybWF0VmVyc2lvbj1UaGUgdmVyc2lvbiBvZiB0aGUgZm9ybWF0IHVzZWQgYnkgdGhlIHN0cmVhbQorRm9ybWF0VmVyc2lvbi92YWx1ZT1UaGUgdmVyc2lvbiBvZiB0aGUgZm9ybWF0IHVzZWQgYnkgdGhlIHN0cmVhbQorU3ViaW1hZ2VJbnRlcnByZXRhdGlvbj1UaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhpcyBpbWFnZSBpbiByZWxhdGlvbiB0byB0aGUgb3RoZXIgaW1hZ2VzIHN0b3JlZCBpbiB0aGUgc2FtZSBzdHJlYW0KK1N1YmltYWdlSW50ZXJwcmV0YXRpb24vdmFsdWU9VGhlIGludGVycHJldGF0aW9uIG9mIHRoaXMgaW1hZ2UgaW4gcmVsYXRpb24gdG8gdGhlIG90aGVyIGltYWdlcyBzdG9yZWQgaW4gdGhlIHNhbWUgc3RyZWFtCitJbWFnZUNyZWF0aW9uVGltZT1UaGUgdGltZSBvZiBpbWFnZSBjcmVhdGlvbgorSW1hZ2VDcmVhdGlvblRpbWUveWVhcj1UaGUgZnVsbCB5ZWFyIChlLmcuLCAxOTY3LCBub3QgNjcpCitJbWFnZUNyZWF0aW9uVGltZS9tb250aD1UaGUgbW9udGgsIHdpdGggSmFudWFyeSA9IDEKK0ltYWdlQ3JlYXRpb25UaW1lL2RheT1UaGUgZGF5IG9mIHRoZSBtb250aAorSW1hZ2VDcmVhdGlvblRpbWUvaG91cj1UaGUgaG91ciBmcm9tIDAgdG8gMjMKK0ltYWdlQ3JlYXRpb25UaW1lL21pbnV0ZT1UaGUgbWludXRlIGZyb20gMCB0byA1OQorSW1hZ2VDcmVhdGlvblRpbWUvc2Vjb25kPVRoZSBzZWNvbmQgZnJvbSAwIHRvIDYwICg2MCA9IGxlYXAgc2Vjb25kKQorSW1hZ2VNb2RpZmljYXRpb25UaW1lPVRoZSB0aW1lIG9mIHRoZSBsYXN0IGltYWdlIG1vZGlmaWNhdGlvbgorSW1hZ2VNb2RpZmljYXRpb25UaW1lL3llYXI9VGhlIGZ1bGwgeWVhciAoZS5nLiwgMTk2Nywgbm90IDY3KQorSW1hZ2VNb2RpZmljYXRpb25UaW1lL21vbnRoPVRoZSBtb250aCwgd2l0aCBKYW51YXJ5ID0gMQorSW1hZ2VNb2RpZmljYXRpb25UaW1lL2RheT1UaGUgZGF5IG9mIHRoZSBtb250aAorSW1hZ2VNb2RpZmljYXRpb25UaW1lL2hvdXI9VGhlIGhvdXIgZnJvbSAwIHRvIDIzCitJbWFnZU1vZGlmaWNhdGlvblRpbWUvbWludXRlPVRoZSBtaW51dGUgZnJvbSAwIHRvIDU5CitJbWFnZU1vZGlmaWNhdGlvblRpbWUvc2Vjb25kPVRoZSBzZWNvbmQgZnJvbSAwIHRvIDYwICg2MCA9IGxlYXAgc2Vjb25kKQorCitUZXh0PVRleHQgaW5mb3JtYXRpb24KK1RleHRFbnRyeT1BIHRleHQgZW50cnkKK1RleHRFbnRyeS9rZXl3b3JkPUEga2V5d29yZCBhc3NvY2lhdGVkIHdpdGggdGhlIHRleHQgZW50cnkKK1RleHRFbnRyeS92YWx1ZT10aGUgdGV4dCBlbnRyeQorVGV4dEVudHJ5L2xhbmd1YWdlPVRoZSBsYW5ndWFnZSBvZiB0aGUgdGV4dAorVGV4dEVudHJ5L2VuY29kaW5nPVRoZSBlbmNvZGluZyBvZiB0aGUgdGV4dAorVGV4dEVudHJ5L2NvbXByZXNzaW9uPVRoZSBtZXRob2QgdXNlZCB0byBjb21wcmVzcyB0aGUgdGV4dAorCitUcmFuc3BhcmVuY3k9VHJhbnNwYXJlbmN5IGluZm9ybWF0aW9uCitBbHBoYT1UaGUgdHlwZSBvZiBhbHBoYSBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4gdGhlIGltYWdlCitBbHBoYS92YWx1ZT1UaGUgdHlwZSBvZiBhbHBoYSBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4gdGhlIGltYWdlCitUcmFuc3BhcmVudEluZGV4PUEgcGFsZXR0ZSBpbmRleCB0byBiZSB0cmVhdGVkIGFzIHRyYW5zcGFyZW50CitUcmFuc3BhcmVudEluZGV4L3ZhbHVlPUEgcGFsZXR0ZSBpbmRleCB0byBiZSB0cmVhdGVkIGFzIHRyYW5zcGFyZW50CitUcmFuc3BhcmVudENvbG9yPUFuIFJHQiBjb2xvciB0byBiZSB0cmVhdGVkIGFzIHRyYW5zcGFyZW50CitUcmFuc3BhcmVudENvbG9yL3ZhbHVlPUFuIFJHQiBjb2xvciB0byBiZSB0cmVhdGVkIGFzIHRyYW5zcGFyZW50CitUaWxlVHJhbnNwYXJlbmNpZXM9QSBsaXN0IG9mIGNvbXBsZXRlbHkgdHJhbnNwYXJlbnQgdGlsZXMKK1RyYW5zcGFyZW50VGlsZT1UaGUgaW5kZXggb2YgYSBjb21wbGV0ZWx5IHRyYW5zcGFyZW50IHRpbGUKK1RyYW5zcGFyZW50VGlsZS94PVRoZSB0aWxlJ3MgWCBpbmRleAorVHJhbnNwYXJlbnRUaWxlL3k9VGhlIHRpbGUncyBZIGluZGV4CitUaWxlT3BhY2l0aWVzPUEgbGlzdCBvZiBjb21wbGV0ZWx5IG9wYXF1ZSB0aWxlcworT3BhcXVlVGlsZT1UaGUgaW5kZXggb2YgYSBjb21wbGV0ZWx5IG9wYXF1ZSB0aWxlCitPcGFxdWVUaWxlL3g9VGhlIHRpbGUncyBYIGluZGV4CitPcGFxdWVUaWxlL3k9VGhlIHRpbGUncyBZIGluZGV4CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9wYWNrYWdlLmh0bWwgYi9hd3QvamF2YXgvaW1hZ2Vpby9tZXRhZGF0YS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjliZDUxYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL21ldGFkYXRhL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBjb250YWlucyBjbGFzc2VzIHdoaWNoIGFsbG93cyB0byByZWFkIGFuZCB3cml0ZSBkZXNjcmliaW5nIG1ldGFkYXRhIG9mIGltYWdlIGZpbGVzLgorICAgIDwvcD4KKyAgQHNpbmNlIEFuZHJvaWQgMS4wCisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3BhY2thZ2UuaHRtbCBiL2F3dC9qYXZheC9pbWFnZWlvL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmQ2MTQ4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsOCBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgd2hpY2ggcHJvdmlkZXMgYW4gSW1hZ2UgSS9PIEFQSS4gVGhlIGNvbnRhaW5lZCBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIGFsbG93IHJlYWRpbmcgYW5kIHdyaXRpbmcgaW1hZ2UgZmlsZXMgb2YgZGlmZmVyZW50IGZvcm1hdHMuCisgICAgPC9wPgorICBAc2luY2UgQW5kcm9pZCAxLjAKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9ibXAvQk1QSW1hZ2VXcml0ZVBhcmFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2JtcC9CTVBJbWFnZVdyaXRlUGFyYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lY2ZiMjBhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9ibXAvQk1QSW1hZ2VXcml0ZVBhcmFtLmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnBsdWdpbnMuYm1wOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVdyaXRlUGFyYW07CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworLyoqCisgKiBUaGUgQk1QSW1hZ2VXcml0ZVBhcmFtIGNsYXNzIGFsbG93cyBlbmNvZGluZyBhbiBpbWFnZSBpbiBCTVAgZm9ybWF0LgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEJNUEltYWdlV3JpdGVQYXJhbSBleHRlbmRzIEltYWdlV3JpdGVQYXJhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdG9wIGRvd24uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHRvcERvd247IC8vIERlZmF1bHQgaXMgYm90dG9tLXVwCisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgQk1QSW1hZ2VXcml0ZVBhcmFtIHdpdGggZGVmYXVsdCB2YWx1ZXMgb2YgYWxsCisgICAgICogcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQk1QSW1hZ2VXcml0ZVBhcmFtKCkgeworICAgICAgICB0aGlzKG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBCTVBJbWFnZVdyaXRlUGFyYW0gd2l0aCB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQk1QSW1hZ2VXcml0ZVBhcmFtKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgc3VwZXIobG9jYWxlKTsKKworICAgICAgICAvLyBTZXQgdGhlIGNvbXByZXNzaW9uCisgICAgICAgIGNhbldyaXRlQ29tcHJlc3NlZCA9IHRydWU7CisgICAgICAgIGNvbXByZXNzaW9uVHlwZXMgPSBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICJCSV9SR0IiLCAiQklfUkxFOCIsICJCSV9STEU0IiwgIkJJX0JJVEZJRUxEUyIKKyAgICAgICAgfTsKKyAgICAgICAgY29tcHJlc3Npb25UeXBlID0gY29tcHJlc3Npb25UeXBlc1swXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRydWUgaWYgdGhlIGRhdGEgd2lsbCBiZSB3cml0dGVuIGluIGEgdG9wLWRvd24gb3JkZXIsIGZhbHNlCisgICAgICogb3RoZXJ3aXNlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0b3BEb3duCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRvcC1kb3duIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRvcERvd24oYm9vbGVhbiB0b3BEb3duKSB7CisgICAgICAgIHRoaXMudG9wRG93biA9IHRvcERvd247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBkYXRhIGlzIHdyaXR0ZW4gaW4gdG9wLWRvd24gb3JkZXIsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGRhdGEgaXMgd3JpdHRlbiBpbiB0b3AtZG93biBvcmRlciwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVG9wRG93bigpIHsKKyAgICAgICAgcmV0dXJuIHRvcERvd247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9ibXAvcGFja2FnZS5odG1sIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9ibXAvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0OTRhMTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2JtcC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw4IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBUaGlzIHBhY2thZ2UgY29udGFpbnMgYXV4aWxpYXJ5IGNsYXNzZXMgZm9yIHRoZSBidWlsdC1pbiBCTVAgaW1hZ2UgcGx1Zy1pbi4KKyAgICA8L3A+CisgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR0h1ZmZtYW5UYWJsZS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdIdWZmbWFuVGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2I1MDRiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdIdWZmbWFuVGFibGUuamF2YQpAQCAtMCwwICsxLDIyNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworLyoqCisgKiBUaGUgSlBFR0h1ZmZtYW5UYWJsZSBjbGFzcyByZXByZXNlbnRzIGEgc2luZ2xlIEpQRUcgSHVmZm1hbiB0YWJsZS4gSXQKKyAqIGNvbnRhaW5zIHRoZSBzdGFuZGFyZCB0YWJsZXMgZnJvbSB0aGUgSlBFRyBzcGVjaWZpY2F0aW9uLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEpQRUdIdWZmbWFuVGFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIHN0YW5kYXJkIERDIGx1bWluYW5jZSBIdWZmbWFuIHRhYmxlIC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEpQRUdIdWZmbWFuVGFibGUgU3RkRENMdW1pbmFuY2UgPSBuZXcgSlBFR0h1ZmZtYW5UYWJsZShuZXcgc2hvcnRbXSB7CisgICAgICAgICAgICAwLCAxLCA1LCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwCisgICAgfSwgbmV3IHNob3J0W10geworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMHgwQSwgMHgwQgorICAgIH0sIGZhbHNlKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzdGFuZGFyZCBEQyBjaHJvbWluYW5jZSBIdWZmbWFuIHRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSlBFR0h1ZmZtYW5UYWJsZSBTdGREQ0Nocm9taW5hbmNlID0gbmV3IEpQRUdIdWZmbWFuVGFibGUobmV3IHNob3J0W10geworICAgICAgICAgICAgMCwgMywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMAorICAgIH0sIG5ldyBzaG9ydFtdIHsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDB4MEEsIDB4MEIKKyAgICB9LCBmYWxzZSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RhbmRhcmQgQUMgbHVtaW5hbmNlIEh1ZmZtYW4gdGFibGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBKUEVHSHVmZm1hblRhYmxlIFN0ZEFDTHVtaW5hbmNlID0gbmV3IEpQRUdIdWZmbWFuVGFibGUobmV3IHNob3J0W10geworICAgICAgICAgICAgMCwgMiwgMSwgMywgMywgMiwgNCwgMywgNSwgNSwgNCwgNCwgMCwgMCwgMSwgMHg3RAorICAgIH0sIG5ldyBzaG9ydFtdIHsKKyAgICAgICAgICAgIDB4MDEsIDB4MDIsIDB4MDMsIDB4MDAsIDB4MDQsIDB4MTEsIDB4MDUsIDB4MTIsIDB4MjEsIDB4MzEsIDB4NDEsIDB4MDYsIDB4MTMsIDB4NTEsCisgICAgICAgICAgICAweDYxLCAweDA3LCAweDIyLCAweDcxLCAweDE0LCAweDMyLCAweDgxLCAweDkxLCAweEExLCAweDA4LCAweDIzLCAweDQyLCAweEIxLCAweEMxLAorICAgICAgICAgICAgMHgxNSwgMHg1MiwgMHhEMSwgMHhGMCwgMHgyNCwgMHgzMywgMHg2MiwgMHg3MiwgMHg4MiwgMHgwOSwgMHgwQSwgMHgxNiwgMHgxNywgMHgxOCwKKyAgICAgICAgICAgIDB4MTksIDB4MUEsIDB4MjUsIDB4MjYsIDB4MjcsIDB4MjgsIDB4MjksIDB4MkEsIDB4MzQsIDB4MzUsIDB4MzYsIDB4MzcsIDB4MzgsIDB4MzksCisgICAgICAgICAgICAweDNBLCAweDQzLCAweDQ0LCAweDQ1LCAweDQ2LCAweDQ3LCAweDQ4LCAweDQ5LCAweDRBLCAweDUzLCAweDU0LCAweDU1LCAweDU2LCAweDU3LAorICAgICAgICAgICAgMHg1OCwgMHg1OSwgMHg1QSwgMHg2MywgMHg2NCwgMHg2NSwgMHg2NiwgMHg2NywgMHg2OCwgMHg2OSwgMHg2QSwgMHg3MywgMHg3NCwgMHg3NSwKKyAgICAgICAgICAgIDB4NzYsIDB4NzcsIDB4NzgsIDB4NzksIDB4N0EsIDB4ODMsIDB4ODQsIDB4ODUsIDB4ODYsIDB4ODcsIDB4ODgsIDB4ODksIDB4OEEsIDB4OTIsCisgICAgICAgICAgICAweDkzLCAweDk0LCAweDk1LCAweDk2LCAweDk3LCAweDk4LCAweDk5LCAweDlBLCAweEEyLCAweEEzLCAweEE0LCAweEE1LCAweEE2LCAweEE3LAorICAgICAgICAgICAgMHhBOCwgMHhBOSwgMHhBQSwgMHhCMiwgMHhCMywgMHhCNCwgMHhCNSwgMHhCNiwgMHhCNywgMHhCOCwgMHhCOSwgMHhCQSwgMHhDMiwgMHhDMywKKyAgICAgICAgICAgIDB4QzQsIDB4QzUsIDB4QzYsIDB4QzcsIDB4QzgsIDB4QzksIDB4Q0EsIDB4RDIsIDB4RDMsIDB4RDQsIDB4RDUsIDB4RDYsIDB4RDcsIDB4RDgsCisgICAgICAgICAgICAweEQ5LCAweERBLCAweEUxLCAweEUyLCAweEUzLCAweEU0LCAweEU1LCAweEU2LCAweEU3LCAweEU4LCAweEU5LCAweEVBLCAweEYxLCAweEYyLAorICAgICAgICAgICAgMHhGMywgMHhGNCwgMHhGNSwgMHhGNiwgMHhGNywgMHhGOCwgMHhGOSwgMHhGQQorICAgIH0sIGZhbHNlKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzdGFuZGFyZCBBQyBjaHJvbWluYW5jZSBIdWZmbWFuIHRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSlBFR0h1ZmZtYW5UYWJsZSBTdGRBQ0Nocm9taW5hbmNlID0gbmV3IEpQRUdIdWZmbWFuVGFibGUobmV3IHNob3J0W10geworICAgICAgICAgICAgMCwgMiwgMSwgMiwgNCwgNCwgMywgNCwgNywgNSwgNCwgNCwgMCwgMSwgMiwgMHg3NworICAgIH0sIG5ldyBzaG9ydFtdIHsKKyAgICAgICAgICAgIDB4MDAsIDB4MDEsIDB4MDIsIDB4MDMsIDB4MTEsIDB4MDQsIDB4MDUsIDB4MjEsIDB4MzEsIDB4MDYsIDB4MTIsIDB4NDEsIDB4NTEsIDB4MDcsCisgICAgICAgICAgICAweDYxLCAweDcxLCAweDEzLCAweDIyLCAweDMyLCAweDgxLCAweDA4LCAweDE0LCAweDQyLCAweDkxLCAweEExLCAweEIxLCAweEMxLCAweDA5LAorICAgICAgICAgICAgMHgyMywgMHgzMywgMHg1MiwgMHhGMCwgMHgxNSwgMHg2MiwgMHg3MiwgMHhEMSwgMHgwQSwgMHgxNiwgMHgyNCwgMHgzNCwgMHhFMSwgMHgyNSwKKyAgICAgICAgICAgIDB4RjEsIDB4MTcsIDB4MTgsIDB4MTksIDB4MUEsIDB4MjYsIDB4MjcsIDB4MjgsIDB4MjksIDB4MkEsIDB4MzUsIDB4MzYsIDB4MzcsIDB4MzgsCisgICAgICAgICAgICAweDM5LCAweDNBLCAweDQzLCAweDQ0LCAweDQ1LCAweDQ2LCAweDQ3LCAweDQ4LCAweDQ5LCAweDRBLCAweDUzLCAweDU0LCAweDU1LCAweDU2LAorICAgICAgICAgICAgMHg1NywgMHg1OCwgMHg1OSwgMHg1QSwgMHg2MywgMHg2NCwgMHg2NSwgMHg2NiwgMHg2NywgMHg2OCwgMHg2OSwgMHg2QSwgMHg3MywgMHg3NCwKKyAgICAgICAgICAgIDB4NzUsIDB4NzYsIDB4NzcsIDB4NzgsIDB4NzksIDB4N0EsIDB4ODIsIDB4ODMsIDB4ODQsIDB4ODUsIDB4ODYsIDB4ODcsIDB4ODgsIDB4ODksCisgICAgICAgICAgICAweDhBLCAweDkyLCAweDkzLCAweDk0LCAweDk1LCAweDk2LCAweDk3LCAweDk4LCAweDk5LCAweDlBLCAweEEyLCAweEEzLCAweEE0LCAweEE1LAorICAgICAgICAgICAgMHhBNiwgMHhBNywgMHhBOCwgMHhBOSwgMHhBQSwgMHhCMiwgMHhCMywgMHhCNCwgMHhCNSwgMHhCNiwgMHhCNywgMHhCOCwgMHhCOSwgMHhCQSwKKyAgICAgICAgICAgIDB4QzIsIDB4QzMsIDB4QzQsIDB4QzUsIDB4QzYsIDB4QzcsIDB4QzgsIDB4QzksIDB4Q0EsIDB4RDIsIDB4RDMsIDB4RDQsIDB4RDUsIDB4RDYsCisgICAgICAgICAgICAweEQ3LCAweEQ4LCAweEQ5LCAweERBLCAweEUyLCAweEUzLCAweEU0LCAweEU1LCAweEU2LCAweEU3LCAweEU4LCAweEU5LCAweEVBLCAweEYyLAorICAgICAgICAgICAgMHhGMywgMHhGNCwgMHhGNSwgMHhGNiwgMHhGNywgMHhGOCwgMHhGOSwgMHhGQQorICAgIH0sIGZhbHNlKTsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGhzLgorICAgICAqLworICAgIHByaXZhdGUgc2hvcnQgbGVuZ3Roc1tdOworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHNob3J0IHZhbHVlc1tdOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGpQRUcgaHVmZm1hbiB0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGVuZ3RocworICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aHMKKyAgICAgKiBAcGFyYW0gdmFsdWVzCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWVzCisgICAgICogQHBhcmFtIGNvcHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb3B5CisgICAgICovCisgICAgSlBFR0h1ZmZtYW5UYWJsZShzaG9ydFtdIGxlbmd0aHMsIHNob3J0W10gdmFsdWVzLCBib29sZWFuIGNvcHkpIHsKKyAgICAgICAgLy8gQ29uc3RydWN0aW9uIG9mIHN0YW5kYXJkIHRhYmxlcyB3aXRob3V0IGNoZWNrcworICAgICAgICAvLyBUaGUgdGhpcmQgcGFyYW0gaXMgZHVtbXkKKyAgICAgICAgLy8gQ291bGQgYmUgYWxzbyB1c2VkIGZvciBjb3B5aW5nIG9mIHRoZSBleGlzdGluZyB0YWJsZXMKKyAgICAgICAgdGhpcy5sZW5ndGhzID0gbGVuZ3RoczsKKyAgICAgICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEpQRUdIdWZmbWFuVGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIGxlbmd0aHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBzaG9ydHMgbGVuZ3Rocy4KKyAgICAgKiBAcGFyYW0gdmFsdWVzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygc2hvcnRzIGNvbnRhaW5pbmcgdGhlIHZhbHVlcyBpbiBvcmRlciBvZgorICAgICAqICAgICAgICAgICAgaW5jcmVhc2luZyBjb2RlIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR0h1ZmZtYW5UYWJsZShzaG9ydFtdIGxlbmd0aHMsIHNob3J0W10gdmFsdWVzKSB7CisgICAgICAgIGlmIChsZW5ndGhzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImxlbmd0aHMgYXJyYXkgaXMgbnVsbCEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInZhbHVlcyBhcnJheSBpcyBudWxsISIpOworICAgICAgICB9CisgICAgICAgIGlmIChsZW5ndGhzLmxlbmd0aCA+IDE2KSB7IC8vIEFjY29yZGluZyB0byB0aGUgc3BlYworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibGVuZ3RocyBhcnJheSBpcyB0b28gbG9uZyEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWVzLmxlbmd0aCA+IDI1NikgeyAvLyBBY2NvcmRpbmcgdG8gdGhlIHNwZWMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInZhbHVlcyBhcnJheSBpcyB0b28gbG9uZyIpOworICAgICAgICB9CisgICAgICAgIGZvciAoc2hvcnQgbGVuZ3RoIDogbGVuZ3RocykgeworICAgICAgICAgICAgaWYgKGxlbmd0aCA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJWYWx1ZXMgaW4gbGVuZ3RocyBhcnJheSBtdXN0IGJlIG5vbi1uZWdhdGl2ZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKHNob3J0IHZhbHVlIDogdmFsdWVzKSB7CisgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVmFsdWVzIGluIHZhbHVlcyBhcnJheSBtdXN0IGJlIG5vbi1uZWdhdGl2ZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNoZWNrSHVmZm1hblRhYmxlKGxlbmd0aHMsIHZhbHVlcyk7CisKKyAgICAgICAgdGhpcy5sZW5ndGhzID0gbmV3IHNob3J0W2xlbmd0aHMubGVuZ3RoXTsKKyAgICAgICAgdGhpcy52YWx1ZXMgPSBuZXcgc2hvcnRbdmFsdWVzLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGVuZ3RocywgMCwgdGhpcy5sZW5ndGhzLCAwLCBsZW5ndGhzLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWVzLCAwLCB0aGlzLnZhbHVlcywgMCwgdmFsdWVzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBsZW5ndGhzIGluIHRoZSBIdWZmbWFuIHRhYmxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHNob3J0IHZhbHVlcyByZXByZXNlbnRpbmcgdGhlIGxlbmd0aCB2YWx1ZXMgaW4gdGhlCisgICAgICogICAgICAgICBIdWZmbWFuIHRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydFtdIGdldExlbmd0aHMoKSB7CisgICAgICAgIHNob3J0IG5ld0xlbmd0aHNbXSA9IG5ldyBzaG9ydFtsZW5ndGhzLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGVuZ3RocywgMCwgbmV3TGVuZ3RocywgMCwgbGVuZ3Rocy5sZW5ndGgpOworICAgICAgICByZXR1cm4gbmV3TGVuZ3RoczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHZhbHVlcyByZXByZXNlbnRlZCBieSBpbmNyZWFzaW5nIGxlbmd0aCBvZiB0aGVpciBjb2Rlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHNob3J0W10gZ2V0VmFsdWVzKCkgeworICAgICAgICBzaG9ydCBuZXdWYWx1ZXNbXSA9IG5ldyBzaG9ydFt2YWx1ZXMubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZXMsIDAsIG5ld1ZhbHVlcywgMCwgdmFsdWVzLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBuZXdWYWx1ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaHVmZm1hbiB0YWJsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbGVuZ3RocworICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aHMuCisgICAgICogQHBhcmFtIHZhbHVlcworICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrSHVmZm1hblRhYmxlKHNob3J0W10gbGVuZ3Rocywgc2hvcnRbXSB2YWx1ZXMpIHsKKyAgICAgICAgaW50IG51bUxlYXZlcyA9IDA7CisgICAgICAgIGludCBwb3NzaWJsZUxlYXZlcyA9IDI7CisgICAgICAgIGZvciAoc2hvcnQgbGVuZ3RoIDogbGVuZ3RocykgeworICAgICAgICAgICAgbnVtTGVhdmVzICs9IGxlbmd0aDsKKyAgICAgICAgICAgIHBvc3NpYmxlTGVhdmVzIC09IGxlbmd0aDsKKyAgICAgICAgICAgIGlmIChwb3NzaWJsZUxlYXZlcyA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgSHVmZm1hbiB0YWJsZSBwcm92aWRlZCwgbGVuZ3RocyBhcmUgaW5jb3JyZWN0LiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcG9zc2libGVMZWF2ZXMgPDw9IDE7CisgICAgICAgIH0KKworICAgICAgICBpZiAodmFsdWVzLmxlbmd0aCAhPSBudW1MZWF2ZXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIEh1ZmZtYW4gdGFibGUgcHJvdmlkZWQsIHN1bSBvZiBsZW5ndGhzICE9IHZhbHVlcy4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEpQRUdIdWZmbWFuVGFibGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEpQRUdIdWZmbWFuVGFibGUgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBzYi5hcHBlbmQoIkpQRUdIdWZmbWFuVGFibGU6XG5sZW5ndGhzOiIpOworICAgICAgICBmb3IgKHNob3J0IGxlbmd0aCA6IGxlbmd0aHMpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnICcpLmFwcGVuZChsZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgc2IuYXBwZW5kKCJcbnZhbHVlczoiKTsKKyAgICAgICAgZm9yIChzaG9ydCB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCcgJykuYXBwZW5kKHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHSW1hZ2VSZWFkUGFyYW0uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHSW1hZ2VSZWFkUGFyYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjNhOWE4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVJlYWRQYXJhbS5qYXZhCkBAIC0wLDAgKzEsMTIzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8ucGx1Z2lucy5qcGVnOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVJlYWRQYXJhbTsKKworLyoqCisgKiBUaGUgSlBFR0ltYWdlUmVhZFBhcmFtIGNsYXNzIHByb3ZpZGVzIGZ1bmN0aW9uYWxpdHkgdG8gc2V0IEh1ZmZtYW4gdGFibGVzIGFuZAorICogcXVhbnRpemF0aW9uIHRhYmxlcyB3aGVuIHVzaW5nIHRoZSBKUEVHIHJlYWRlciBwbHVnLWluLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEpQRUdJbWFnZVJlYWRQYXJhbSBleHRlbmRzIEltYWdlUmVhZFBhcmFtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBxIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEpQRUdRVGFibGUgcVRhYmxlc1tdOworCisgICAgLyoqCisgICAgICogVGhlIGRjIGh1ZmZtYW4gdGFibGVzLgorICAgICAqLworICAgIHByaXZhdGUgSlBFR0h1ZmZtYW5UYWJsZSBkY0h1ZmZtYW5UYWJsZXNbXTsKKworICAgIC8qKgorICAgICAqIFRoZSBhYyBodWZmbWFuIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEpQRUdIdWZmbWFuVGFibGUgYWNIdWZmbWFuVGFibGVzW107CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSlBFR0ltYWdlUmVhZFBhcmFtLgorICAgICAqLworICAgIHB1YmxpYyBKUEVHSW1hZ2VSZWFkUGFyYW0oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRhYmxlcyBhcmUgc2V0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0YWJsZXMgYXJlIHNldCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFyZVRhYmxlc1NldCgpIHsKKyAgICAgICAgcmV0dXJuIHFUYWJsZXMgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBxdWFudGl6YXRpb24gYW5kIEh1ZmZtYW4gdGFibGVzIGZvciB1c2luZyBpbiBkZWNvZGluZyBzdHJlYW1zLgorICAgICAqIAorICAgICAqIEBwYXJhbSBxVGFibGVzCisgICAgICogICAgICAgICAgICB0aGUgcXVhbnRpemF0aW9uIHRhYmxlcy4KKyAgICAgKiBAcGFyYW0gRENIdWZmbWFuVGFibGVzCisgICAgICogICAgICAgICAgICB0aGUgc3RhbmRhcnQgREMgSHVmZm1hbiB0YWJsZXMuCisgICAgICogQHBhcmFtIEFDSHVmZm1hblRhYmxlcworICAgICAqICAgICAgICAgICAgdGhlIHN0YW5kYXJ0IEFDIGh1ZmZtYW4gdGFibGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlY29kZVRhYmxlcyhKUEVHUVRhYmxlW10gcVRhYmxlcywgSlBFR0h1ZmZtYW5UYWJsZVtdIERDSHVmZm1hblRhYmxlcywKKyAgICAgICAgICAgIEpQRUdIdWZmbWFuVGFibGVbXSBBQ0h1ZmZtYW5UYWJsZXMpIHsKKyAgICAgICAgaWYgKHFUYWJsZXMgPT0gbnVsbCB8fCBEQ0h1ZmZtYW5UYWJsZXMgPT0gbnVsbCB8fCBBQ0h1ZmZtYW5UYWJsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBKUEVHIHRhYmxlIGFycmF5cyIpOworICAgICAgICB9CisgICAgICAgIGlmIChEQ0h1ZmZtYW5UYWJsZXMubGVuZ3RoICE9IEFDSHVmZm1hblRhYmxlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgSlBFRyB0YWJsZSBhcnJheXMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocVRhYmxlcy5sZW5ndGggPiA0IHx8IERDSHVmZm1hblRhYmxlcy5sZW5ndGggPiA0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIEpQRUcgdGFibGUgYXJyYXlzIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBEbyB0aGUgc2hhbGxvdyBjb3B5LCBpdCBzaG91bGQgYmUgZW5vdWdoCisgICAgICAgIHRoaXMucVRhYmxlcyA9IHFUYWJsZXMuY2xvbmUoKTsKKyAgICAgICAgZGNIdWZmbWFuVGFibGVzID0gRENIdWZmbWFuVGFibGVzLmNsb25lKCk7CisgICAgICAgIGFjSHVmZm1hblRhYmxlcyA9IEFDSHVmZm1hblRhYmxlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuc2V0IGFsbCBkZWNvZGVkIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnNldERlY29kZVRhYmxlcygpIHsKKyAgICAgICAgcVRhYmxlcyA9IG51bGw7CisgICAgICAgIGRjSHVmZm1hblRhYmxlcyA9IG51bGw7CisgICAgICAgIGFjSHVmZm1hblRhYmxlcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcXVhbnRpemF0aW9uIHRhYmxlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBxdWFudGl6YXRpb24gdGFibGVzLCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBKUEVHUVRhYmxlW10gZ2V0UVRhYmxlcygpIHsKKyAgICAgICAgcmV0dXJuIHFUYWJsZXMgPT0gbnVsbCA/IG51bGwgOiBxVGFibGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgREMgSHVmZm1hbiB0YWJsZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgREMgSHVmZm1hbiB0YWJsZXMgd2hpY2ggYXJlIHNldCwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR0h1ZmZtYW5UYWJsZVtdIGdldERDSHVmZm1hblRhYmxlcygpIHsKKyAgICAgICAgcmV0dXJuIGRjSHVmZm1hblRhYmxlcyA9PSBudWxsID8gbnVsbCA6IGRjSHVmZm1hblRhYmxlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIEFDIEh1ZmZtYW4gdGFibGVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEFDIEh1ZmZtYW4gdGFibGVzIHdoaWNoIGFyZSBzZXQsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIEpQRUdIdWZmbWFuVGFibGVbXSBnZXRBQ0h1ZmZtYW5UYWJsZXMoKSB7CisgICAgICAgIHJldHVybiBhY0h1ZmZtYW5UYWJsZXMgPT0gbnVsbCA/IG51bGwgOiBhY0h1ZmZtYW5UYWJsZXMuY2xvbmUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR0ltYWdlV3JpdGVQYXJhbS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVdyaXRlUGFyYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTc5OTExCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVdyaXRlUGFyYW0uamF2YQpAQCAtMCwwICsxLDIwOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdDb25zdHM7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVQYXJhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIFRoZSBKUEVHSW1hZ2VXcml0ZVBhcmFtIGNsYXNzIGFsbG93cyB0byBzZXQgSlBFRyBIdWZmbWFuIHRhYmxlcyBhbmQKKyAqIHF1YW50aXphdGlvbiB3aGVuIHVzaW5nIHRoZSBKUEVHIHdyaXRlciBwbHVnLWluLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEpQRUdJbWFnZVdyaXRlUGFyYW0gZXh0ZW5kcyBJbWFnZVdyaXRlUGFyYW0geworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IENPTVBfUVVBTElUWV9WQUxVRVMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXRbXSBDT01QX1FVQUxJVFlfVkFMVUVTID0geworICAgICAgICAgICAgMC4wNWYsIDAuNzVmLCAwLjk1ZgorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgQ09NUF9RVUFMSVRZX0RFU0NSSVBUSU9OUy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBDT01QX1FVQUxJVFlfREVTQ1JJUFRJT05TID0geworICAgICAgICAgICAgIk1pbmltdW0gdXNlZnVsIiwgIlZpc3VhbGx5IGxvc3NsZXNzIiwgIk1heGltdW0gdXNlZnVsIgorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgcSB0YWJsZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBKUEVHUVRhYmxlW10gcVRhYmxlczsKKworICAgIC8qKgorICAgICAqIFRoZSBkYyBodWZmbWFuIHRhYmxlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEpQRUdIdWZmbWFuVGFibGVbXSBkY0h1ZmZtYW5UYWJsZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWMgaHVmZm1hbiB0YWJsZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBKUEVHSHVmZm1hblRhYmxlW10gYWNIdWZmbWFuVGFibGVzOworCisgICAgLyoqCisgICAgICogVGhlIG9wdGltaXplIGh1ZmZtYW4gdGFibGVzLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBvcHRpbWl6ZUh1ZmZtYW5UYWJsZXM7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSlBFR0ltYWdlV3JpdGVQYXJhbSBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgTG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBKUEVHSW1hZ2VXcml0ZVBhcmFtKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgc3VwZXIobG9jYWxlKTsKKworICAgICAgICBjYW5Xcml0ZVByb2dyZXNzaXZlID0gdHJ1ZTsKKyAgICAgICAgcHJvZ3Jlc3NpdmVNb2RlID0gSW1hZ2VXcml0ZVBhcmFtLk1PREVfRElTQUJMRUQ7CisKKyAgICAgICAgY2FuV3JpdGVDb21wcmVzc2VkID0gdHJ1ZTsKKyAgICAgICAgY29tcHJlc3Npb25UeXBlcyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAiSlBFRyIKKyAgICAgICAgfTsKKyAgICAgICAgY29tcHJlc3Npb25UeXBlID0gY29tcHJlc3Npb25UeXBlc1swXTsKKyAgICAgICAgY29tcHJlc3Npb25RdWFsaXR5ID0gSlBFR0NvbnN0cy5ERUZBVUxUX0pQRUdfQ09NUFJFU1NJT05fUVVBTElUWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGFibGVzIGFyZSBzZXQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRhYmxlcyBhcmUgc2V0LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYXJlVGFibGVzU2V0KCkgeworICAgICAgICByZXR1cm4gcVRhYmxlcyAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHF1YW50aXphdGlvbiBhbmQgSHVmZm1hbiB0YWJsZXMgZm9yIHVzaW5nIGluIGVuY29kaW5nIHN0cmVhbXMuCisgICAgICogCisgICAgICogQHBhcmFtIHFUYWJsZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBxdWFudGl6YXRpb24gdGFibGVzLgorICAgICAqIEBwYXJhbSBEQ0h1ZmZtYW5UYWJsZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFuZGFydCBEQyBIdWZmbWFuIHRhYmxlcy4KKyAgICAgKiBAcGFyYW0gQUNIdWZmbWFuVGFibGVzCisgICAgICogICAgICAgICAgICB0aGUgc3RhbmRhcnQgQUMgaHVmZm1hbiB0YWJsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RlVGFibGVzKEpQRUdRVGFibGVbXSBxVGFibGVzLCBKUEVHSHVmZm1hblRhYmxlW10gRENIdWZmbWFuVGFibGVzLAorICAgICAgICAgICAgSlBFR0h1ZmZtYW5UYWJsZVtdIEFDSHVmZm1hblRhYmxlcykgeworICAgICAgICBpZiAocVRhYmxlcyA9PSBudWxsIHx8IERDSHVmZm1hblRhYmxlcyA9PSBudWxsIHx8IEFDSHVmZm1hblRhYmxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIEpQRUcgdGFibGUgYXJyYXlzIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKERDSHVmZm1hblRhYmxlcy5sZW5ndGggIT0gQUNIdWZmbWFuVGFibGVzLmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBKUEVHIHRhYmxlIGFycmF5cyIpOworICAgICAgICB9CisgICAgICAgIGlmIChxVGFibGVzLmxlbmd0aCA+IDQgfHwgRENIdWZmbWFuVGFibGVzLmxlbmd0aCA+IDQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgSlBFRyB0YWJsZSBhcnJheXMiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIERvIHRoZSBzaGFsbG93IGNvcHksIGl0IHNob3VsZCBiZSBlbm91Z2gKKyAgICAgICAgdGhpcy5xVGFibGVzID0gcVRhYmxlcy5jbG9uZSgpOworICAgICAgICBkY0h1ZmZtYW5UYWJsZXMgPSBEQ0h1ZmZtYW5UYWJsZXMuY2xvbmUoKTsKKyAgICAgICAgYWNIdWZmbWFuVGFibGVzID0gQUNIdWZmbWFuVGFibGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5zZXQgYWxsIGVuY29kZWQgdGFibGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuc2V0RW5jb2RlVGFibGVzKCkgeworICAgICAgICBxVGFibGVzID0gbnVsbDsKKyAgICAgICAgZGNIdWZmbWFuVGFibGVzID0gbnVsbDsKKyAgICAgICAgYWNIdWZmbWFuVGFibGVzID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBEQyBIdWZmbWFuIHRhYmxlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBEQyBIdWZmbWFuIHRhYmxlcyB3aGljaCBhcmUgc2V0LCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBKUEVHSHVmZm1hblRhYmxlW10gZ2V0RENIdWZmbWFuVGFibGVzKCkgeworICAgICAgICByZXR1cm4gZGNIdWZmbWFuVGFibGVzID09IG51bGwgPyBudWxsIDogZGNIdWZmbWFuVGFibGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQUMgSHVmZm1hbiB0YWJsZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgQUMgSHVmZm1hbiB0YWJsZXMgd2hpY2ggYXJlIHNldCwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR0h1ZmZtYW5UYWJsZVtdIGdldEFDSHVmZm1hblRhYmxlcygpIHsKKyAgICAgICAgcmV0dXJuIGFjSHVmZm1hblRhYmxlcyA9PSBudWxsID8gbnVsbCA6IGFjSHVmZm1hblRhYmxlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHF1YW50aXphdGlvbiB0YWJsZXMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgcXVhbnRpemF0aW9uIHRhYmxlcywgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR1FUYWJsZVtdIGdldFFUYWJsZXMoKSB7CisgICAgICAgIHJldHVybiBxVGFibGVzID09IG51bGwgPyBudWxsIDogcVRhYmxlcy5jbG9uZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDb21wcmVzc2lvblF1YWxpdHlEZXNjcmlwdGlvbnMoKSB7CisgICAgICAgIHN1cGVyLmdldENvbXByZXNzaW9uUXVhbGl0eURlc2NyaXB0aW9ucygpOworICAgICAgICByZXR1cm4gQ09NUF9RVUFMSVRZX0RFU0NSSVBUSU9OUy5jbG9uZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIGdldENvbXByZXNzaW9uUXVhbGl0eVZhbHVlcygpIHsKKyAgICAgICAgc3VwZXIuZ2V0Q29tcHJlc3Npb25RdWFsaXR5VmFsdWVzKCk7CisgICAgICAgIHJldHVybiBDT01QX1FVQUxJVFlfVkFMVUVTLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmxhZyBpbmRpY2F0ZWQgdGhhdCB0aGUgd3JpdGVyIHdpbGwgZ2VuZXJhdGUgb3B0aW1pemVkIEh1ZmZtYW4KKyAgICAgKiB0YWJsZXMgZm9yIHRoZSBpbWFnZSBhcyBwYXJ0IG9mIHRoZSB3cml0aW5nIHByb2Nlc3MuCisgICAgICogCisgICAgICogQHBhcmFtIG9wdGltaXplCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyBvZiBvcHRpbWl6aW5nIGh1ZmZtYW4gdGFibGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9wdGltaXplSHVmZm1hblRhYmxlcyhib29sZWFuIG9wdGltaXplKSB7CisgICAgICAgIG9wdGltaXplSHVmZm1hblRhYmxlcyA9IG9wdGltaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgd3JpdGVyIGdlbmVyYXRlcyBvcHRpbWl6ZWQgSHVmZm1hbiB0YWJsZXMsIGZhbHNlCisgICAgICogb3RoZXJ3aXNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHdyaXRlciBnZW5lcmF0ZXMgb3B0aW1pemVkIEh1ZmZtYW4gdGFibGVzLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGltaXplSHVmZm1hblRhYmxlcygpIHsKKyAgICAgICAgcmV0dXJuIG9wdGltaXplSHVmZm1hblRhYmxlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXByZXNzaW9uTG9zc2xlc3MoKSB7CisgICAgICAgIGlmIChnZXRDb21wcmVzc2lvbk1vZGUoKSAhPSBNT0RFX0VYUExJQ0lUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDb21wcmVzc2lvbiBtb2RlIG5vdCBNT0RFX0VYUExJQ0lUISIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbXByZXNzaW9uKCkgeworICAgICAgICBpZiAoZ2V0Q29tcHJlc3Npb25Nb2RlKCkgIT0gTU9ERV9FWFBMSUNJVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ29tcHJlc3Npb24gbW9kZSBub3QgTU9ERV9FWFBMSUNJVCEiKTsKKyAgICAgICAgfQorICAgICAgICBjb21wcmVzc2lvblF1YWxpdHkgPSBKUEVHQ29uc3RzLkRFRkFVTFRfSlBFR19DT01QUkVTU0lPTl9RVUFMSVRZOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHUVRhYmxlLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR1FUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0NjFkNDYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR1FUYWJsZS5qYXZhCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworLyoqCisgKiBUaGUgSlBFR1FUYWJsZSBjbGFzcyByZXByZXNlbnRzIGEgc2luZ2xlIEpQRUcgcXVhbnRpemF0aW9uIHRhYmxlIGFuZCBwcm92aWRlcworICogZm9yIHRoZSBzdGFuZGFyZCB0YWJsZXMgdGFrZW4gZnJvbSB0aGUgSlBFRyBzcGVjaWZpY2F0aW9uLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEpQRUdRVGFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNJWkUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IFNJWkUgPSA2NDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBCQVNFTElORV9NQVguCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IEJBU0VMSU5FX01BWCA9IDI1NTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNQVguCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IE1BWCA9IDMyNzY3OworCisgICAgLyoqCisgICAgICogVGhlIHRhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgaW50W10gdGhlVGFibGU7CisKKyAgICAvKgorICAgICAqIEsxICYgSzIgdGFibGVzIGNhbiBiZSBmb3VuZCBpbiB0aGUgSlBFRyBmb3JtYXQgc3BlY2lmaWNhdGlvbiBhdAorICAgICAqIGh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL0pQRUcvaXR1LXQ4MS5wZGYKKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBLMUx1bVRhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIEsxTHVtVGFibGUgPSBuZXcgaW50W10geworICAgICAgICAgICAgMTYsIDExLCAxMCwgMTYsIDI0LCA0MCwgNTEsIDYxLCAxMiwgMTIsIDE0LCAxOSwgMjYsIDU4LCA2MCwgNTUsIDE0LCAxMywgMTYsIDI0LCA0MCwgNTcsCisgICAgICAgICAgICA2OSwgNTYsIDE0LCAxNywgMjIsIDI5LCA1MSwgODcsIDgwLCA2MiwgMTgsIDIyLCAzNywgNTYsIDY4LCAxMDksIDEwMywgNzcsIDI0LCAzNSwgNTUsCisgICAgICAgICAgICA2NCwgODEsIDEwNCwgMTEzLCA5MiwgNDksIDY0LCA3OCwgODcsIDEwMywgMTIxLCAxMjAsIDEwMSwgNzIsIDkyLCA5NSwgOTgsIDExMiwgMTAwLAorICAgICAgICAgICAgMTAzLCA5OQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSzJDaHJUYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBLMkNoclRhYmxlID0gbmV3IGludFtdIHsKKyAgICAgICAgICAgIDE3LCAxOCwgMjQsIDQ3LCA5OSwgOTksIDk5LCA5OSwgMTgsIDIxLCAyNiwgNjYsIDk5LCA5OSwgOTksIDk5LCAyNCwgMjYsIDU2LCA5OSwgOTksIDk5LAorICAgICAgICAgICAgOTksIDk5LCA0NywgNjYsIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksCisgICAgICAgICAgICA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTksIDk5LCA5OSwgOTkKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIEsxTHVtaW5hbmNlIGluZGljYXRlcyBzdGFuZGFyZCB0YWJsZSBLLjEgZnJvbSBKUEVHIHNwZWNpZmljYXRpb24gYW5kCisgICAgICogcHJvZHVjZXMgImdvb2QiIHF1YWxpdHkgb3V0cHV0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSlBFR1FUYWJsZSBLMUx1bWluYW5jZSA9IG5ldyBKUEVHUVRhYmxlKEsxTHVtVGFibGUpOworCisgICAgLyoqCisgICAgICogVGhlIEsxRGl2Mkx1bWluYW5jZSBpbmRpY2F0ZXMgSy4xIHRhYmxlIGZyb20gSlBFRyBzcGVjaWZpY2F0aW9uIHdpdGggYWxsCisgICAgICogZWxlbWVudHMgZGl2aWRlZCBieSAyIGFuZCBwcm9kdWNlcyAidmVyeSBnb29kIiBxdWFsaXR5IG91dHB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEpQRUdRVGFibGUgSzFEaXYyTHVtaW5hbmNlID0gSzFMdW1pbmFuY2UuZ2V0U2NhbGVkSW5zdGFuY2UoMC41ZiwgdHJ1ZSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSzJDaHJvbWluYW5jZSBpbmRpY2F0ZXMgSy4yIHRhYmxlIGZyb20gSlBFRyBzcGVjaWZpY2F0aW9uIGFuZAorICAgICAqIHByb2R1Y2VzICJnb29kIiBxdWFsaXR5IG91dHB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEpQRUdRVGFibGUgSzJDaHJvbWluYW5jZSA9IG5ldyBKUEVHUVRhYmxlKEsyQ2hyVGFibGUpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEsyRGl2MkNocm9taW5hbmNlIGluZGljYXRlcyBLLjIgdGFibGUgZnJvbSBKUEVHCisgICAgICogc3BlY2lmaWNhdGlvbiB3aXRoIGFsbCBlbGVtZW50cyBkaXZpZGVkIGJ5IDIgYW5kIHByb2R1Y2VzICJ2ZXJ5IGdvb2QiCisgICAgICogcXVhbGl0eSBvdXRwdXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBKUEVHUVRhYmxlIEsyRGl2MkNocm9taW5hbmNlID0gSzJDaHJvbWluYW5jZS5nZXRTY2FsZWRJbnN0YW5jZSgwLjVmLCB0cnVlKTs7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSlBFR1FUYWJsZSBmcm9tIHRoZSBhcnJheSwgd2hpY2ggc2hvdWxkIGNvbnRhaW4gNjQKKyAgICAgKiBlbGVtZW50cyBpbiBuYXR1cmFsIG9yZGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZQorICAgICAqICAgICAgICAgICAgdGhlIHF1YW50aXphdGlvbiB0YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR1FUYWJsZShpbnRbXSB0YWJsZSkgeworICAgICAgICBpZiAodGFibGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGFibGUgc2hvdWxkIG5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRhYmxlLmxlbmd0aCAhPSBTSVpFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbGxlZ2FsIHRhYmxlIHNpemU6ICIgKyB0YWJsZS5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHRoZVRhYmxlID0gdGFibGUuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHF1YW50aXphdGlvbiB0YWJsZSBhcyBhbiBhcnJheSBvZiBpbnRlZ2VyIHZhbHVlcy4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHF1YW50aXphdGlvbiB0YWJsZSBhcyBhbiBhcnJheSBvZiBpbnRlZ2VyIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0VGFibGUoKSB7CisgICAgICAgIHJldHVybiB0aGVUYWJsZS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNjYWxlZCBpbnN0YW5jZSBhcyBxdWFudGl6YXRpb24gdGFibGUgd2hlcmUgdGhlIHZhbHVlcyBhcmUKKyAgICAgKiBtdWx0aXBsaWVkIGJ5IHRoZSBzY2FsZUZhY3RvciBhbmQgdGhlbiBjbGFtcGVkIGlmIGZvcmNlQmFzZWxpbmUgaXMgdHJ1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc2NhbGVGYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsZSBmYWN0b3Igb2YgdGFibGUuCisgICAgICogQHBhcmFtIGZvcmNlQmFzZWxpbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JjZSBiYXNlbGluZSBmbGFnLCB0aGUgdmFsdWVzIHNob3VsZCBiZSBjbGFtcGVkIGlmIHRydWUuCisgICAgICogQHJldHVybiB0aGUgbmV3IHF1YW50aXphdGlvbiB0YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlBFR1FUYWJsZSBnZXRTY2FsZWRJbnN0YW5jZShmbG9hdCBzY2FsZUZhY3RvciwgYm9vbGVhbiBmb3JjZUJhc2VsaW5lKSB7CisgICAgICAgIGludCB0YWJsZVtdID0gbmV3IGludFtTSVpFXTsKKworICAgICAgICBpbnQgbWF4VmFsdWUgPSBmb3JjZUJhc2VsaW5lID8gQkFTRUxJTkVfTUFYIDogTUFYOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhlVGFibGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCByb3VuZGVkID0gTWF0aC5yb3VuZCh0aGVUYWJsZVtpXSAqIHNjYWxlRmFjdG9yKTsKKyAgICAgICAgICAgIGlmIChyb3VuZGVkIDwgMSkgeworICAgICAgICAgICAgICAgIHJvdW5kZWQgPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJvdW5kZWQgPiBtYXhWYWx1ZSkgeworICAgICAgICAgICAgICAgIHJvdW5kZWQgPSBtYXhWYWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRhYmxlW2ldID0gcm91bmRlZDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEpQRUdRVGFibGUodGFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEpQRUdRVGFibGUgb2JqZWN0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEpQRUdRVGFibGUgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8vIC0tIFRPRE8gbW9yZSBpbmZvcm1hdGl2ZSBpbmZvCisgICAgICAgIHJldHVybiAiSlBFR1FUYWJsZSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vcGx1Z2lucy9qcGVnL3BhY2thZ2UuaHRtbCBiL2F3dC9qYXZheC9pbWFnZWlvL3BsdWdpbnMvanBlZy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ1NzVjNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3BsdWdpbnMvanBlZy9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw4IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBUaGlzIHBhY2thZ2UgY29udGFpbnMgYXV4aWxpYXJ5IGNsYXNzZXMgZm9yIHRoZSBidWlsdC1pbiBKUEVHIGltYWdlIHBsdWctaW4uCisgICAgPC9wPgorICBAc2luY2UgQW5kcm9pZCAxLjAKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0lJT1JlZ2lzdHJ5LmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSUlPUmVnaXN0cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWRkZWFhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0lJT1JlZ2lzdHJ5LmphdmEKQEAgLTAsMCArMSwxMTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdJbWFnZVJlYWRlclNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZy5KUEVHSW1hZ2VXcml0ZXJTcGk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLnBuZy5QTkdJbWFnZVJlYWRlclNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMucG5nLlBOR0ltYWdlV3JpdGVyU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3BpLkZpbGVJSVNTcGk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5zcGkuRmlsZUlPU1NwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnNwaS5JbnB1dFN0cmVhbUlJU1NwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnNwaS5PdXRwdXRTdHJlYW1JT1NTcGk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5zcGkuUkFGSUlTU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3BpLlJBRklPU1NwaTsKKworLyoKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YsIFZpc2tvdiBOaWtvbGF5CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworLyoqCisgKiBUaGUgSUlPUmVnaXN0cnkgY2xhc3MgcmVnaXN0ZXJzIHNlcnZpY2UgcHJvdmlkZXIgaW5zdGFuY2VzIChTUEkpLiBTZXJ2aWNlCisgKiBwcm92aWRlciBpbnN0YW5jZXMgYXJlIHJlY29nbml6ZWQgYnkgc3BlY2lmaWMgbWV0YS1pbmZvcm1hdGlvbiBpbiB0aGUgSkFSCisgKiBmaWxlcyBjb250YWluaW5nIHRoZW0uIFRoZSBKQVIgZmlsZXMgd2l0aCBTUEkgY2xhc3NlcyBhcmUgbG9hZGVkIGZyb20gdGhlCisgKiBhcHBsaWNhdGlvbiBjbGFzcyBwYXRoLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElJT1JlZ2lzdHJ5IGV4dGVuZHMgU2VydmljZVJlZ2lzdHJ5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJSU9SZWdpc3RyeSBpbnN0YW5jZTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBDQVRFR09SSUVTLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzW10gQ0FURUdPUklFUyA9IG5ldyBDbGFzc1tdIHsKKyAgICAgICAgICAgIGphdmF4LmltYWdlaW8uc3BpLkltYWdlV3JpdGVyU3BpLmNsYXNzLCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVJlYWRlclNwaS5jbGFzcywKKyAgICAgICAgICAgIGphdmF4LmltYWdlaW8uc3BpLkltYWdlSW5wdXRTdHJlYW1TcGkuY2xhc3MsCisgICAgICAgICAgICAvLyBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVRyYW5zY29kZXJTcGkuY2xhc3MsCisgICAgICAgICAgICBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZU91dHB1dFN0cmVhbVNwaS5jbGFzcworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPIHJlZ2lzdHJ5LgorICAgICAqLworICAgIHByaXZhdGUgSUlPUmVnaXN0cnkoKSB7CisgICAgICAgIHN1cGVyKEFycmF5cy48Q2xhc3M8Pz4+IGFzTGlzdChDQVRFR09SSUVTKS5pdGVyYXRvcigpKTsKKyAgICAgICAgcmVnaXN0ZXJCdWlsdGluU3BpcygpOworICAgICAgICByZWdpc3RlckFwcGxpY2F0aW9uQ2xhc3NwYXRoU3BpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVyIGJ1aWx0LWluIFNQSXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlZ2lzdGVyQnVpbHRpblNwaXMoKSB7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBKUEVHSW1hZ2VXcml0ZXJTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBKUEVHSW1hZ2VSZWFkZXJTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBQTkdJbWFnZVJlYWRlclNwaSgpKTsKKyAgICAgICAgcmVnaXN0ZXJTZXJ2aWNlUHJvdmlkZXIobmV3IFBOR0ltYWdlV3JpdGVyU3BpKCkpOworICAgICAgICByZWdpc3RlclNlcnZpY2VQcm92aWRlcihuZXcgRmlsZUlPU1NwaSgpKTsKKyAgICAgICAgcmVnaXN0ZXJTZXJ2aWNlUHJvdmlkZXIobmV3IEZpbGVJSVNTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBSQUZJT1NTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBSQUZJSVNTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBPdXRwdXRTdHJlYW1JT1NTcGkoKSk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKG5ldyBJbnB1dFN0cmVhbUlJU1NwaSgpKTsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IElJT1JlZ2lzdHJ5IGluc3RhbmNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgSUlPUmVnaXN0cnkgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJSU9SZWdpc3RyeSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgICAgIC8vIFRPRE8gaW1wbGVtZW50IG93biBpbnN0YW5jZSBmb3IgZWFjaCBUaHJlYWRHcm91cCAoc2VlIGFsc28KKyAgICAgICAgLy8gVGhyZWFkTG9jYWwpCisgICAgICAgIHN5bmNocm9uaXplZCAoSUlPUmVnaXN0cnkuY2xhc3MpIHsKKyAgICAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgSUlPUmVnaXN0cnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVycyBhbGwgc2VydmljZSBwcm92aWRlcnMgZnJvbSB0aGUgYXBwbGljYXRpb24gY2xhc3MgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWdpc3RlckFwcGxpY2F0aW9uQ2xhc3NwYXRoU3BpcygpIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQgZm9yIG5vbi1idWlsdGluIHBsdWdpbnMKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSUlPU2VydmljZVByb3ZpZGVyLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSUlPU2VydmljZVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk0NzY3NwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9JSU9TZXJ2aWNlUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5zcGk7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIFRoZSBJSU9TZXJ2aWNlUHJvdmlkZXIgYWJzdHJhY3QgY2xhc3MgcHJvdmlkZXMgYmFzZSBmdW5jdGlvbmFsaXR5IGZvciBJbWFnZUlPCisgKiBzZXJ2aWNlIHByb3ZpZGVyIGludGVyZmFjZXMgKFNQSXMpLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIElJT1NlcnZpY2VQcm92aWRlciBpbXBsZW1lbnRzIFJlZ2lzdGVyYWJsZVNlcnZpY2UgeworCisgICAgLyoqCisgICAgICogVGhlIHZlbmRvciBuYW1lIG9mIHRoaXMgc2VydmljZSBwcm92aWRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHZlbmRvck5hbWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyB2ZXJzaW9uOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElJT1NlcnZpY2VQcm92aWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmVuZG9yTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHZlbmRvciBuYW1lIG9mIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIHZlcnNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJzaW9uIG9mIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICovCisgICAgcHVibGljIElJT1NlcnZpY2VQcm92aWRlcihTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgaWYgKHZlbmRvck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ2ZW5kb3IgbmFtZSBjYW5ub3QgYmUgTlVMTCIpOworICAgICAgICB9CisgICAgICAgIGlmICh2ZXJzaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidmVyc2lvbiBuYW1lIGNhbm5vdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy52ZW5kb3JOYW1lID0gdmVuZG9yTmFtZTsKKyAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSUlPU2VydmljZVByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyBJSU9TZXJ2aWNlUHJvdmlkZXIoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBvblJlZ2lzdHJhdGlvbihTZXJ2aWNlUmVnaXN0cnkgcmVnaXN0cnksIENsYXNzPD8+IGNhdGVnb3J5KSB7CisgICAgICAgIC8vIHRoZSBkZWZhdWx0IGltcGwuIGRvZXMgbm90aGluZworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG9uRGVyZWdpc3RyYXRpb24oU2VydmljZVJlZ2lzdHJ5IHJlZ2lzdHJ5LCBDbGFzczw/PiBjYXRlZ29yeSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmVuZG9yIG5hbWUgb2YgdGhpcyBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHZlbmRvciBuYW1lIG9mIHRoaXMgc2VydmljZSBwcm92aWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZlbmRvck5hbWUoKSB7CisgICAgICAgIHJldHVybiB2ZW5kb3JOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZlcnNpb24gb2YgdGhpcyBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHZlcnNpb24gb2YgdGhpcyBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGRlc2NyaXB0aW9uIG9mIHRoaXMgc2VydmljZSBwcm92aWRlci4gVGhlIHJlc3VsdCBzdHJpbmcgc2hvdWxkIGJlCisgICAgICogbG9jYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIExvY2FsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXREZXNjcmlwdGlvbihMb2NhbGUgbG9jYWxlKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9JbWFnZUlucHV0U3RyZWFtU3BpLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VJbnB1dFN0cmVhbVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjODU5YTgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VJbnB1dFN0cmVhbVNwaS5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnNwaTsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIEltYWdlSW5wdXRTdHJlYW1TcGkgYWJzdHJhY3QgY2xhc3MgaXMgYSBzZXJ2aWNlIHByb3ZpZGVyIGludGVyZmFjZSAoU1BJKQorICogZm9yIEltYWdlSW5wdXRTdHJlYW1zLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlSW5wdXRTdHJlYW1TcGkgZXh0ZW5kcyBJSU9TZXJ2aWNlUHJvdmlkZXIgaW1wbGVtZW50cyBSZWdpc3RlcmFibGVTZXJ2aWNlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnB1dCBjbGFzcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2xhc3M8Pz4gaW5wdXRDbGFzczsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZUlucHV0U3RyZWFtU3BpLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbWFnZUlucHV0U3RyZWFtU3BpKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlSW5wdXRTdHJlYW1TcGkuCisgICAgICogCisgICAgICogQHBhcmFtIHZlbmRvck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZW5kb3IgbmFtZS4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHZlcnNpb24uCisgICAgICogQHBhcmFtIGlucHV0Q2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VJbnB1dFN0cmVhbVNwaShTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24sIENsYXNzPD8+IGlucHV0Q2xhc3MpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yTmFtZSwgdmVyc2lvbik7CisgICAgICAgIHRoaXMuaW5wdXRDbGFzcyA9IGlucHV0Q2xhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBpbnB1dCBDbGFzcyBvYmplY3QgdGhhdCByZXByZXNlbnRzIGNsYXNzIG9yIGludGVyZmFjZSB0aGF0IG11c3QKKyAgICAgKiBiZSBpbXBsZW1lbnRlZCBieSBhbiBpbnB1dCBzb3VyY2UuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgaW5wdXQgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldElucHV0Q2xhc3MoKSB7CisgICAgICAgIHJldHVybiBpbnB1dENsYXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgSW1hZ2VJbnB1dFN0cmVhbSBjYW4gdXNlIGEgY2FjaGUgZmlsZS4gSWYgdGhpcyBtZXRob2QKKyAgICAgKiByZXR1cm5zIGZhbHNlLCB0aGUgdmFsdWUgb2YgdGhlIHVzZUNhY2hlIHBhcmFtZXRlciBvZgorICAgICAqIGNyZWF0ZUlucHV0U3RyZWFtSW5zdGFuY2Ugd2lsbCBiZSBpZ25vcmVkLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqIHJldHVybnMgZmFsc2UuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgSW1hZ2VJbnB1dFN0cmVhbSBjYW4gdXNlIGEgY2FjaGUgZmlsZSwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Vc2VDYWNoZUZpbGUoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsgLy8gLS0gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBJbWFnZUlucHV0U3RyZWFtIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIHRoZSB1c2Ugb2YgYQorICAgICAqIGNhY2hlIGZpbGUuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHJldHVybnMgZmFsc2UuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgSW1hZ2VJbnB1dFN0cmVhbSBpbXBsZW1lbnRhdGlvbiByZXF1aXJlcyB0aGUgdXNlIG9mCisgICAgICogICAgICAgICBhIGNhY2hlIGZpbGUsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBuZWVkc0NhY2hlRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBJbWFnZUlucHV0U3RyZWFtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuIFRoZQorICAgICAqIGlucHV0IG9iamVjdCBzaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHJldHVybmVkIGJ5IHRoZQorICAgICAqIGdldElucHV0Q2xhc3MgbWV0aG9kLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGZvciB0aGUKKyAgICAgKiBjYWNoZSBmaWxlIGlmIHRoZSB1c2VDYWNoZSBwYXJhbWV0ZXIgaXMgdHJ1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBPYmplY3QuCisgICAgICogQHBhcmFtIHVzZUNhY2hlCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyBpbmRpY2F0aW5nIGlmIGEgY2FjaGUgZmlsZSBpcyBuZWVkZWQgb3Igbm90LgorICAgICAqIEBwYXJhbSBjYWNoZURpcgorICAgICAqICAgICAgICAgICAgdGhlIGNhY2hlIGRpcmVjdG9yeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZUlucHV0U3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW1hZ2VJbnB1dFN0cmVhbSBjcmVhdGVJbnB1dFN0cmVhbUluc3RhbmNlKE9iamVjdCBpbnB1dCwgYm9vbGVhbiB1c2VDYWNoZSwKKyAgICAgICAgICAgIEZpbGUgY2FjaGVEaXIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIEltYWdlSW5wdXRTdHJlYW0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2VydmljZSBwcm92aWRlci4gVGhlCisgICAgICogaW5wdXQgb2JqZWN0IHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZiB0aGUgY2xhc3MgcmV0dXJuZWQgYnkgZ2V0SW5wdXRDbGFzcworICAgICAqIG1ldGhvZC4gVGhpcyBtZXRob2QgdXNlcyB0aGUgZGVmYXVsdCBzeXN0ZW0gZGlyZWN0b3J5IGZvciB0aGUgY2FjaGUgZmlsZSwKKyAgICAgKiBpZiBpdCBpcyBuZWVkZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgT2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlSW5wdXRTdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZUlucHV0U3RyZWFtIGNyZWF0ZUlucHV0U3RyZWFtSW5zdGFuY2UoT2JqZWN0IGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY3JlYXRlSW5wdXRTdHJlYW1JbnN0YW5jZShpbnB1dCwgdHJ1ZSwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlT3V0cHV0U3RyZWFtU3BpLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VPdXRwdXRTdHJlYW1TcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iN2E5YTVjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlT3V0cHV0U3RyZWFtU3BpLmphdmEKQEAgLTAsMCArMSwxMzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CisKKy8qKgorICogVGhlIEltYWdlT3V0cHV0U3RyZWFtU3BpIGFic3RyYWN0IGNsYXNzIGlzIGEgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UgKFNQSSkKKyAqIGZvciBJbWFnZU91dHB1dFN0cmVhbXMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSW1hZ2VPdXRwdXRTdHJlYW1TcGkgZXh0ZW5kcyBJSU9TZXJ2aWNlUHJvdmlkZXIgaW1wbGVtZW50cworICAgICAgICBSZWdpc3RlcmFibGVTZXJ2aWNlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBvdXRwdXQgY2xhc3MuCisgICAgICovCisgICAgcHJvdGVjdGVkIENsYXNzPD8+IG91dHB1dENsYXNzOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlT3V0cHV0U3RyZWFtU3BpLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbWFnZU91dHB1dFN0cmVhbVNwaSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZU91dHB1dFN0cmVhbVNwaS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmVuZG9yTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHZlbmRvciBuYW1lLgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgdmVyc2lvbi4KKyAgICAgKiBAcGFyYW0gb3V0cHV0Q2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIEltYWdlT3V0cHV0U3RyZWFtU3BpKFN0cmluZyB2ZW5kb3JOYW1lLCBTdHJpbmcgdmVyc2lvbiwgQ2xhc3M8Pz4gb3V0cHV0Q2xhc3MpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yTmFtZSwgdmVyc2lvbik7CisgICAgICAgIHRoaXMub3V0cHV0Q2xhc3MgPSBvdXRwdXRDbGFzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIG91dHB1dCBDbGFzcyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgdGhhdAorICAgICAqIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgYW4gb3V0cHV0IHNvdXJjZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBvdXRwdXQgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldE91dHB1dENsYXNzKCkgeworICAgICAgICByZXR1cm4gb3V0cHV0Q2xhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBJbWFnZU91dHB1dFN0cmVhbSBjYW4gdXNlIGEgY2FjaGUgZmlsZS4gSWYgdGhpcworICAgICAqIG1ldGhvZCByZXR1cm5zIGZhbHNlLCB0aGUgdmFsdWUgb2YgdGhlIHVzZUNhY2hlIHBhcmFtZXRlciBvZgorICAgICAqIGNyZWF0ZU91dHB1dFN0cmVhbUluc3RhbmNlIHdpbGwgYmUgaWdub3JlZC4gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKiByZXR1cm5zIGZhbHNlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIEltYWdlT3V0cHV0U3RyZWFtIGNhbiB1c2UgYSBjYWNoZSBmaWxlLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhblVzZUNhY2hlRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBkZWYKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIEltYWdlT3V0cHV0U3RyZWFtIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIHRoZSB1c2Ugb2YKKyAgICAgKiBhIGNhY2hlIGZpbGUuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHJldHVybnMgZmFsc2UuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgSW1hZ2VPdXRwdXRTdHJlYW0gaW1wbGVtZW50YXRpb24gcmVxdWlyZXMgdGhlIHVzZSBvZgorICAgICAqICAgICAgICAgYSBjYWNoZSBmaWxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbmVlZHNDYWNoZUZpbGUoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsgLy8gZGVmCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgSW1hZ2VPdXRwdXRTdHJlYW0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2VydmljZSBwcm92aWRlci4gVGhlCisgICAgICogb3V0cHV0IG9iamVjdCBzaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHJldHVybmVkIGJ5CisgICAgICogZ2V0T3V0cHV0Q2xhc3MgbWV0aG9kLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBkZWZhdWx0IHN5c3RlbSBkaXJlY3RvcnkgZm9yCisgICAgICogdGhlIGNhY2hlIGZpbGUsIGlmIGl0IGlzIG5lZWRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IE9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZU91dHB1dFN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIEltYWdlT3V0cHV0U3RyZWFtIGNyZWF0ZU91dHB1dFN0cmVhbUluc3RhbmNlKE9iamVjdCBvdXRwdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjcmVhdGVPdXRwdXRTdHJlYW1JbnN0YW5jZShvdXRwdXQsIHRydWUsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIEltYWdlT3V0cHV0U3RyZWFtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuIFRoZQorICAgICAqIG91dHB1dCBvYmplY3Qgc2hvdWxkIGJlIGFuIGluc3RhbmNlIG9mIHRoZSBjbGFzcyByZXR1cm5lZCBieQorICAgICAqIGdldElucHV0Q2xhc3MgbWV0aG9kLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGZvciB0aGUKKyAgICAgKiBjYWNoZSBmaWxlLCBpZiB0aGUgdXNlQ2FjaGUgcGFyYW1ldGVyIGlzIHRydWUuCisgICAgICogCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBPYmplY3QuCisgICAgICogQHBhcmFtIHVzZUNhY2hlCisgICAgICogICAgICAgICAgICB0aGUgZmxhZyBpbmRpY2F0aW5nIGlmIGNhY2hlIGZpbGUgaXMgbmVlZGVkIG9yIG5vdC4KKyAgICAgKiBAcGFyYW0gY2FjaGVEaXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYWNoZSBkaXJlY3RvcnkuCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VPdXRwdXRTdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbWFnZU91dHB1dFN0cmVhbSBjcmVhdGVPdXRwdXRTdHJlYW1JbnN0YW5jZShPYmplY3Qgb3V0cHV0LCBib29sZWFuIHVzZUNhY2hlLAorICAgICAgICAgICAgRmlsZSBjYWNoZURpcikgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlUmVhZGVyU3BpLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VSZWFkZXJTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTI4ZDI1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlUmVhZGVyU3BpLmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlUmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhlIEltYWdlUmVhZGVyU3BpIGFic3RyYWN0IGNsYXNzIGlzIGEgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UgKFNQSSkgZm9yCisgKiBJbWFnZVJlYWRlcnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSW1hZ2VSZWFkZXJTcGkgZXh0ZW5kcyBJbWFnZVJlYWRlcldyaXRlclNwaSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU1RBTkRBUkRfSU5QVVRfVFlQRSBjb250YWlucyBJbWFnZUlucHV0U3RyZWFtLmNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3NbXSBTVEFOREFSRF9JTlBVVF9UWVBFID0gbmV3IENsYXNzW10geworICAgICAgICBJbWFnZUlucHV0U3RyZWFtLmNsYXNzCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnB1dCB0eXBlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2xhc3NbXSBpbnB1dFR5cGVzOworCisgICAgLyoqCisgICAgICogVGhlIHdyaXRlciBTUEkgbmFtZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZ1tdIHdyaXRlclNwaU5hbWVzOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlUmVhZGVyU3BpLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbWFnZVJlYWRlclNwaSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZVJlYWRlclNwaS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmVuZG9yTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHZlbmRvciBuYW1lLgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgdmVyc2lvbi4KKyAgICAgKiBAcGFyYW0gbmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXQgbmFtZXMuCisgICAgICogQHBhcmFtIHN1ZmZpeGVzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgdGhlIGZpbGUgc3VmZml4ZXMuCisgICAgICogQHBhcmFtIE1JTUVUeXBlcworICAgICAqICAgICAgICAgICAgdGhlIGFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIE1JTUUgdHlwZXMuCisgICAgICogQHBhcmFtIHBsdWdpbkNsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBsdWctaW4gY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gaW5wdXRUeXBlcworICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHR5cGVzLgorICAgICAqIEBwYXJhbSB3cml0ZXJTcGlOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBjbGFzcyBuYW1lcyBvZiBhbGwgYXNzb2NpYXRlZAorICAgICAqICAgICAgICAgICAgSW1hZ2VXcml0ZXJzLgorICAgICAqIEBwYXJhbSBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIHN0cmVhbSBtZXRhZGF0YSBjYW4gYmUgZGVzY3JpYmVkIGJ5CisgICAgICogICAgICAgICAgICBzdGFuZGFyZCBtZXRhZGF0YSBmb3JtYXQuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmF0aXZlIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0LgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGV4dHJhIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRTdHJlYW1NZXRhZGF0YUZvcm1hdC4KKyAgICAgKiBAcGFyYW0gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIGltYWdlIG1ldGFkYXRhIGNhbiBiZSBkZXNjcmliZWQgYnkKKyAgICAgKiAgICAgICAgICAgIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYXRpdmUgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZS4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXQuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgZXh0cmEgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRJbWFnZU1ldGFkYXRhRm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVJlYWRlclNwaShTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24sIFN0cmluZ1tdIG5hbWVzLCBTdHJpbmdbXSBzdWZmaXhlcywKKyAgICAgICAgICAgIFN0cmluZ1tdIE1JTUVUeXBlcywgU3RyaW5nIHBsdWdpbkNsYXNzTmFtZSwgQ2xhc3NbXSBpbnB1dFR5cGVzLAorICAgICAgICAgICAgU3RyaW5nW10gd3JpdGVyU3BpTmFtZXMsIGJvb2xlYW4gc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0LAorICAgICAgICAgICAgU3RyaW5nIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZSwgU3RyaW5nIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLAorICAgICAgICAgICAgU3RyaW5nW10gZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLCBTdHJpbmdbXSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcywKKyAgICAgICAgICAgIGJvb2xlYW4gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQsIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSwKKyAgICAgICAgICAgIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBTdHJpbmdbXSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcywKKyAgICAgICAgICAgIFN0cmluZ1tdIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yTmFtZSwgdmVyc2lvbiwgbmFtZXMsIHN1ZmZpeGVzLCBNSU1FVHlwZXMsIHBsdWdpbkNsYXNzTmFtZSwKKyAgICAgICAgICAgICAgICBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQsIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZSwKKyAgICAgICAgICAgICAgICBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZSwgZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLAorICAgICAgICAgICAgICAgIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzLCBzdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdCwKKyAgICAgICAgICAgICAgICBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSwgbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZSwKKyAgICAgICAgICAgICAgICBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcywgZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcyk7CisKKyAgICAgICAgaWYgKGlucHV0VHlwZXMgPT0gbnVsbCB8fCBpbnB1dFR5cGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImlucHV0IHR5cGVzIGFycmF5IGNhbm5vdCBiZSBOVUxMIG9yIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5pbnB1dFR5cGVzID0gaW5wdXRUeXBlczsKKyAgICAgICAgdGhpcy53cml0ZXJTcGlOYW1lcyA9IHdyaXRlclNwaU5hbWVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgQ2xhc3Mgb2JqZWN0cyB3aG9zZSB0eXBlcyBjYW4gYmUgdXNlZCBhcyBpbnB1dCBmb3IgdGhpcworICAgICAqIHJlYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCB0eXBlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3NbXSBnZXRJbnB1dFR5cGVzKCkgeworICAgICAgICByZXR1cm4gaW5wdXRUeXBlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvcm1hdCBvZiBzb3VyY2Ugb2JqZWN0IGlzIHN1cHBvcnRlZCBieSB0aGlzIHJlYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9iamVjdCB0byBiZSBkZWNvZGVkIChmb3IgZXhhbXBsZSBhbgorICAgICAqICAgICAgICAgICAgSW1hZ2VJbnB1dFN0cmVhbSkuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgZm9ybWF0IG9mIHNvdXJjZSBvYmplY3QgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgcmVhZGVyLAorICAgICAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjYW5EZWNvZGVJbnB1dChPYmplY3Qgc291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBJbWFnZVJlYWRlciBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBzZXJ2aWNlCisgICAgICogcHJvdmlkZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgSW1hZ2VSZWFkZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVJlYWRlciBjcmVhdGVSZWFkZXJJbnN0YW5jZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjcmVhdGVSZWFkZXJJbnN0YW5jZShudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBJbWFnZVJlYWRlciBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBzZXJ2aWNlCisgICAgICogcHJvdmlkZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGV4dGVuc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIGEgcGx1Zy1pbiBzcGVjaWZpYyBleHRlbnNpb24gb2JqZWN0LCBvciBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIEltYWdlUmVhZGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW1hZ2VSZWFkZXIgY3JlYXRlUmVhZGVySW5zdGFuY2UoT2JqZWN0IGV4dGVuc2lvbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgSW1hZ2VSZWFkZXIgb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mCisgICAgICogdGhlIEltYWdlUmVhZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UgcHJvdmlkZXIgb3Igbm90LgorICAgICAqIAorICAgICAqIEBwYXJhbSByZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbWFnZVJlYWRlci4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgSW1hZ2VSZWFkZXIgb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIHRoZQorICAgICAqICAgICAgICAgSW1hZ2VSZWFkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2VydmljZSBwcm92aWRlciwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc093blJlYWRlcihJbWFnZVJlYWRlciByZWFkZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2Ygc3RyaW5ncyB3aXRoIG5hbWVzIG9mIHRoZSBJbWFnZVdyaXRlclNwaSBjbGFzc2VzIHRoYXQKKyAgICAgKiBzdXBwb3J0IHRoZSBpbnRlcm5hbCBtZXRhZGF0YSByZXByZXNlbnRhdGlvbiB1c2VkIGJ5IHRoZSBJbWFnZVJlYWRlciBvZgorICAgICAqIHRoaXMgc2VydmljZSBwcm92aWRlciwgb3IgbnVsbCBpZiB0aGVyZSBhcmUgbm8gc3VjaCBJbWFnZVdyaXRlcnMuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2Ygc3RyaW5ncyB3aXRoIG5hbWVzIG9mIHRoZSBJbWFnZVdyaXRlclNwaSBjbGFzc2VzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRJbWFnZVdyaXRlclNwaU5hbWVzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlUmVhZGVyV3JpdGVyU3BpLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VSZWFkZXJXcml0ZXJTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Y2EwOGI1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlUmVhZGVyV3JpdGVyU3BpLmphdmEKQEAgLTAsMCArMSwzNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3BpOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5tZXRhZGF0YS5JSU9NZXRhZGF0YVV0aWxzOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5tZXRhZGF0YS5JSU9NZXRhZGF0YUZvcm1hdDsKKworLyoqCisgKiBUaGUgSW1hZ2VSZWFkZXJXcml0ZXJTcGkgY2xhc3MgaXMgYSBzdXBlcmNsYXNzIGZvciB0aGUgSW1hZ2VSZWFkZXJTcGkgYW5kCisgKiBJbWFnZVdyaXRlclNwaSBTUElzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlUmVhZGVyV3JpdGVyU3BpIGV4dGVuZHMgSUlPU2VydmljZVByb3ZpZGVyIGltcGxlbWVudHMKKyAgICAgICAgUmVnaXN0ZXJhYmxlU2VydmljZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZ1tdIG5hbWVzOworCisgICAgLyoqCisgICAgICogVGhlIHN1ZmZpeGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBzdWZmaXhlczsKKworICAgIC8qKgorICAgICAqIFRoZSBNSU1FIHR5cGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBNSU1FVHlwZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGx1Zy1pbiBjbGFzcyBuYW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgcGx1Z2luQ2xhc3NOYW1lOworCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGUgcmVhZGVyL3dyaXRlciBzdXBwb3J0cyBzdGFuZGFyZCBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0LgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHN1cHBvcnRzU3RhbmRhcmRTdHJlYW1NZXRhZGF0YUZvcm1hdDsKKworICAgIC8qKgorICAgICAqIFRoZSBuYXRpdmUgc3RyZWFtIG1ldGFkYXRhIGZvcm1hdCBuYW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgbmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lOworCisgICAgLyoqCisgICAgICogVGhlIG5hdGl2ZSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IGNsYXNzIG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBleHRyYSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXh0cmEgc3RyZWFtIG1ldGFkYXRhIGZvcm1hdCBjbGFzcyBuYW1lcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nW10gZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoZSByZWFkZXIvd3JpdGVyIHN1cHBvcnRzIHN0YW5kYXJkIGltYWdlIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdDsKKworICAgIC8qKgorICAgICAqIFRoZSBuYXRpdmUgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBuYXRpdmUgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IGNsYXNzIG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lOworCisgICAgLyoqCisgICAgICogVGhlIGV4dHJhIGltYWdlIG1ldGFkYXRhIGZvcm1hdCBuYW1lcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nW10gZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXh0cmEgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IGNsYXNzIG5hbWVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlUmVhZGVyV3JpdGVyU3BpLgorICAgICAqIAorICAgICAqIEBwYXJhbSB2ZW5kb3JOYW1lCisgICAgICogICAgICAgICAgICB0aGUgdmVuZG9yIG5hbWUuCisgICAgICogQHBhcmFtIHZlcnNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJzaW9uLgorICAgICAqIEBwYXJhbSBuYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCBuYW1lcy4KKyAgICAgKiBAcGFyYW0gc3VmZml4ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBzdHJpbmdzIHJlcHJlc2VudGluZyB0aGUgZmlsZSBzdWZmaXhlcy4KKyAgICAgKiBAcGFyYW0gTUlNRVR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgYW4gYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgTUlNRSB0eXBlcy4KKyAgICAgKiBAcGFyYW0gcGx1Z2luQ2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGx1Zy1pbiBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIHN0cmVhbSBtZXRhZGF0YSBjYW4gYmUgZGVzY3JpYmVkIGJ5CisgICAgICogICAgICAgICAgICBzdGFuZGFyZCBtZXRhZGF0YSBmb3JtYXQuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmF0aXZlIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0LgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGV4dHJhIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRTdHJlYW1NZXRhZGF0YUZvcm1hdC4KKyAgICAgKiBAcGFyYW0gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIGltYWdlIG1ldGFkYXRhIGNhbiBiZSBkZXNjcmliZWQgYnkKKyAgICAgKiAgICAgICAgICAgIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYXRpdmUgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZS4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXQuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgZXh0cmEgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRJbWFnZU1ldGFkYXRhRm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVJlYWRlcldyaXRlclNwaShTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24sIFN0cmluZ1tdIG5hbWVzLAorICAgICAgICAgICAgU3RyaW5nW10gc3VmZml4ZXMsIFN0cmluZ1tdIE1JTUVUeXBlcywgU3RyaW5nIHBsdWdpbkNsYXNzTmFtZSwKKyAgICAgICAgICAgIGJvb2xlYW4gc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0LCBTdHJpbmcgbmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lLAorICAgICAgICAgICAgU3RyaW5nIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBTdHJpbmdbXSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICBTdHJpbmdbXSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcywKKyAgICAgICAgICAgIGJvb2xlYW4gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQsIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSwKKyAgICAgICAgICAgIFN0cmluZyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBTdHJpbmdbXSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcywKKyAgICAgICAgICAgIFN0cmluZ1tdIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yTmFtZSwgdmVyc2lvbik7CisKKyAgICAgICAgaWYgKG5hbWVzID09IG51bGwgfHwgbmFtZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZm9ybWF0IG5hbWVzIGFycmF5IGNhbm5vdCBiZSBOVUxMIG9yIGVtcHR5Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGx1Z2luQ2xhc3NOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiUGx1Z2luIGNsYXNzIG5hbWUgY2Fubm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlIGNsb25lIGFsbCB0aGUgYXJyYXlzIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZmFjdCB0aGF0CisgICAgICAgIC8vIHNvbWUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIG11c3QgcmV0dXJuIGNsb25lcyBvZiB0aGUgYXJyYXlzCisgICAgICAgIC8vIGFzIGl0IGlzIHN0YXRlZCBpbiB0aGUgc3BlYy4KKyAgICAgICAgdGhpcy5uYW1lcyA9IG5hbWVzLmNsb25lKCk7CisgICAgICAgIHRoaXMuc3VmZml4ZXMgPSBzdWZmaXhlcyA9PSBudWxsID8gbnVsbCA6IHN1ZmZpeGVzLmNsb25lKCk7CisgICAgICAgIHRoaXMuTUlNRVR5cGVzID0gTUlNRVR5cGVzID09IG51bGwgPyBudWxsIDogTUlNRVR5cGVzLmNsb25lKCk7CisgICAgICAgIHRoaXMucGx1Z2luQ2xhc3NOYW1lID0gcGx1Z2luQ2xhc3NOYW1lOworICAgICAgICB0aGlzLnN1cHBvcnRzU3RhbmRhcmRTdHJlYW1NZXRhZGF0YUZvcm1hdCA9IHN1cHBvcnRzU3RhbmRhcmRTdHJlYW1NZXRhZGF0YUZvcm1hdDsKKyAgICAgICAgdGhpcy5uYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUgPSBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWU7CisgICAgICAgIHRoaXMubmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUgPSBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZTsKKworICAgICAgICB0aGlzLmV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcyA9IGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcyA9PSBudWxsID8gbnVsbAorICAgICAgICAgICAgICAgIDogZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLmNsb25lKCk7CisKKyAgICAgICAgdGhpcy5leHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcyA9IGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzID09IG51bGwgPyBudWxsCisgICAgICAgICAgICAgICAgOiBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcy5jbG9uZSgpOworCisgICAgICAgIHRoaXMuc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQgPSBzdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdDsKKyAgICAgICAgdGhpcy5uYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSA9IG5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXROYW1lOworICAgICAgICB0aGlzLm5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUgPSBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lOworCisgICAgICAgIHRoaXMuZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMgPSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcyA9PSBudWxsID8gbnVsbAorICAgICAgICAgICAgICAgIDogZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMuY2xvbmUoKTsKKworICAgICAgICB0aGlzLmV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMgPSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzID09IG51bGwgPyBudWxsCisgICAgICAgICAgICAgICAgOiBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlUmVhZGVyV3JpdGVyU3BpLgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVJlYWRlcldyaXRlclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIG5hbWVzIG9mIHRoZSBmb3JtYXRzIHRoYXQgY2FuIGJlCisgICAgICogdXNlZCBieSB0aGUgSW1hZ2VSZWFkZXIgb3IgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24gYXNzb2NpYXRlZCB3aXRoCisgICAgICogdGhpcyBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHN1cHBvcnRlZCBmb3JtYXQgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldEZvcm1hdE5hbWVzKCkgeworICAgICAgICByZXR1cm4gbmFtZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIGZpbGUgc3VmZml4ZXMgYXNzb2NpYXRlZCB3aXRoIHRoZQorICAgICAqIGZvcm1hdHMgdGhhdCBjYW4gYmUgdXNlZCBieSB0aGUgSW1hZ2VSZWFkZXIgb3IgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24KKyAgICAgKiBvZiB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZmlsZSBzdWZmaXhlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RmlsZVN1ZmZpeGVzKCkgeworICAgICAgICByZXR1cm4gc3VmZml4ZXMgPT0gbnVsbCA/IG51bGwgOiBzdWZmaXhlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2Ygc3RyaW5ncyB3aXRoIHRoZSBuYW1lcyBvZiBhZGRpdGlvbmFsIGZvcm1hdHMgb2YgdGhlCisgICAgICogaW1hZ2UgbWV0YWRhdGEgb2JqZWN0cyBwcm9kdWNlZCBvciBjb25zdW1lZCBieSB0aGlzIHBsdWctaW4uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgZXh0cmEgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFeHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWVzID09IG51bGwgPyBudWxsIDogZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCB0aGUgbmFtZXMgb2YgYWRkaXRpb25hbCBmb3JtYXRzIG9mIHRoZQorICAgICAqIHN0cmVhbSBtZXRhZGF0YSBvYmplY3RzIHByb2R1Y2VkIG9yIGNvbnN1bWVkIGJ5IHRoaXMgcGx1Zy1pbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBleHRyYSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFeHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMoKSB7CisgICAgICAgIHJldHVybiBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMgPT0gbnVsbCA/IG51bGwgOiBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMKKyAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIElJT01ldGFkYXRhRm9ybWF0IG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBpbWFnZSBtZXRhZGF0YSBmb3JtYXQKKyAgICAgKiBuYW1lLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb3JtYXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWUuCisgICAgICogQHJldHVybiB0aGUgSUlPTWV0YWRhdGFGb3JtYXQsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIElJT01ldGFkYXRhRm9ybWF0IGdldEltYWdlTWV0YWRhdGFGb3JtYXQoU3RyaW5nIGZvcm1hdE5hbWUpIHsKKyAgICAgICAgcmV0dXJuIElJT01ldGFkYXRhVXRpbHMuaW5zdGFudGlhdGVNZXRhZGF0YUZvcm1hdChmb3JtYXROYW1lLAorICAgICAgICAgICAgICAgIHN1cHBvcnRzU3RhbmRhcmRJbWFnZU1ldGFkYXRhRm9ybWF0LCBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSwKKyAgICAgICAgICAgICAgICBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLCBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcywKKyAgICAgICAgICAgICAgICBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIElJT01ldGFkYXRhRm9ybWF0IG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0CisgICAgICogbmFtZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9ybWF0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIElJT01ldGFkYXRhRm9ybWF0LCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBJSU9NZXRhZGF0YUZvcm1hdCBnZXRTdHJlYW1NZXRhZGF0YUZvcm1hdChTdHJpbmcgZm9ybWF0TmFtZSkgeworICAgICAgICByZXR1cm4gSUlPTWV0YWRhdGFVdGlscy5pbnN0YW50aWF0ZU1ldGFkYXRhRm9ybWF0KGZvcm1hdE5hbWUsCisgICAgICAgICAgICAgICAgc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0LCBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUsCisgICAgICAgICAgICAgICAgbmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUsIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcywKKyAgICAgICAgICAgICAgICBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBhcnJheSBvZiBzdHJpbmdzIHJlcHJlc2VudGluZyB0aGUgTUlNRSB0eXBlcyBvZiB0aGUgZm9ybWF0cyB0aGF0CisgICAgICogYXJlIHN1cHBvcnRlZCBieSB0aGUgSW1hZ2VSZWFkZXIgb3IgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24gb2YgdGhpcworICAgICAqIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgTUlNRSB0eXBlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TUlNRVR5cGVzKCkgeworICAgICAgICByZXR1cm4gTUlNRVR5cGVzID09IG51bGwgPyBudWxsIDogTUlNRVR5cGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgbmF0aXZlIGltYWdlIG1ldGFkYXRhIGZvcm1hdCBmb3IgdGhpcyByZWFkZXIvd3JpdGVyLAorICAgICAqIHdoaWNoIGFsbG93cyBmb3IgbG9zc2xlc3MgZW5jb2Rpbmcgb3IgZGVjb2Rpbmcgb2YgdGhlIGltYWdlIG1ldGFkYXRhIHdpdGgKKyAgICAgKiB0aGUgZm9ybWF0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyB3aXRoIG5hdGl2ZSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgbmFtZSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgbmF0aXZlIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgZm9yIHRoaXMKKyAgICAgKiByZWFkZXIvd3JpdGVyLCB3aGljaCBhbGxvd3MgZm9yIGxvc3NsZXNzIGVuY29kaW5nIG9yIGRlY29kaW5nIG9mIHRoZQorICAgICAqIHN0cmVhbSBtZXRhZGF0YSB3aXRoIHRoZSBmb3JtYXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHdpdGggbmF0aXZlIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgbmFtZSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBJbWFnZVJlYWRlciBvciBJbWFnZVdyaXRlciBhc3NvY2lhdGVkIHdpdGgKKyAgICAgKiB0aGlzIHNlcnZpY2UgcHJvdmlkZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgY2xhc3MgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBsdWdpbkNsYXNzTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHBsdWdpbkNsYXNzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdCBpcyBzdXBwb3J0ZWQgYnkgdGhlIGdldEFzVHJlZSBhbmQKKyAgICAgKiBzZXRGcm9tVHJlZSBtZXRob2RzIGZvciB0aGUgaW1hZ2UgbWV0YWRhdGEgb2JqZWN0cyBwcm9kdWNlZCBvciBjb25zdW1lZAorICAgICAqIGJ5IHRoaXMgcmVhZGVyIG9yIHdyaXRlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN0YW5kYXJkIGltYWdlIG1ldGFkYXRhIGZvcm1hdCBpcyBzdXBwb3J0ZWQsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXRTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBzdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdCBpcyBzdXBwb3J0ZWQgYnkgdGhlIGdldEFzVHJlZSBhbmQKKyAgICAgKiBzZXRGcm9tVHJlZSBtZXRob2RzIGZvciB0aGUgc3RyZWFtIG1ldGFkYXRhIG9iamVjdHMgcHJvZHVjZWQgb3IgY29uc3VtZWQKKyAgICAgKiBieSB0aGlzIHJlYWRlciBvciB3cml0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBzdGFuZGFyZCBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IGlzIHN1cHBvcnRlZCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXRTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlVHJhbnNjb2RlclNwaS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlVHJhbnNjb2RlclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0MmFmMTkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvSW1hZ2VUcmFuc2NvZGVyU3BpLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5zcGk7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlVHJhbnNjb2RlcjsKKworLyoqCisgKiBUaGUgSW1hZ2VUcmFuc2NvZGVyU3BpIGNsYXNzIGlzIGEgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UgKFNQSSkgZm9yCisgKiBJbWFnZVRyYW5zY29kZXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEltYWdlVHJhbnNjb2RlclNwaSBleHRlbmRzIElJT1NlcnZpY2VQcm92aWRlciBpbXBsZW1lbnRzIFJlZ2lzdGVyYWJsZVNlcnZpY2UgeworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEltYWdlVHJhbnNjb2RlclNwaS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VUcmFuc2NvZGVyU3BpKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZVRyYW5zY29kZXJTcGkgd2l0aCB0aGUgc3BlY2lmaWVkIHZlbmRvciBuYW1lIGFuZAorICAgICAqIHZlcnNpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHZlbmRvck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZW5kb3IgbmFtZS4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIEltYWdlVHJhbnNjb2RlclNwaShTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgc3VwZXIodmVuZG9yTmFtZSwgdmVyc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY2xhc3MgbmFtZSBvZiBhbiBJbWFnZVJlYWRlclNwaSB0aGF0IHByb2R1Y2VzIElJT01ldGFkYXRhCisgICAgICogb2JqZWN0cyB0aGF0IGNhbiBiZSB1c2VkIGFzIGlucHV0IHRvIHRoaXMgdHJhbnNjb2Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjbGFzcyBuYW1lIG9mIGFuIEltYWdlUmVhZGVyU3BpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0UmVhZGVyU2VydmljZVByb3ZpZGVyTmFtZSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY2xhc3MgbmFtZSBvZiBhbiBJbWFnZVdyaXRlclNwaSB0aGF0IHByb2R1Y2VzIElJT01ldGFkYXRhCisgICAgICogb2JqZWN0cyB0aGF0IGNhbiBiZSB1c2VkIGFzIGlucHV0IHRvIHRoaXMgdHJhbnNjb2Rlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBjbGFzcyBuYW1lIG9mIGFuIEltYWdlV3JpdGVyU3BpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0V3JpdGVyU2VydmljZVByb3ZpZGVyTmFtZSgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB0aGUgSW1hZ2VUcmFuc2NvZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UKKyAgICAgKiBwcm92aWRlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZVRyYW5zY29kZXIgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlVHJhbnNjb2RlciBjcmVhdGVUcmFuc2NvZGVySW5zdGFuY2UoKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9JbWFnZVdyaXRlclNwaS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL0ltYWdlV3JpdGVyU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmYyNTQ1NQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9JbWFnZVdyaXRlclNwaS5qYXZhCkBAIC0wLDAgKzEsMjI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnNwaTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVR5cGVTcGVjaWZpZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVdyaXRlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SZW5kZXJlZEltYWdlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhlIEltYWdlV3JpdGVyU3BpIGFic3RyYWN0IGNsYXNzIGlzIGEgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UgKFNQSSkgZm9yCisgKiBJbWFnZVdyaXRlcnMuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSW1hZ2VXcml0ZXJTcGkgZXh0ZW5kcyBJbWFnZVJlYWRlcldyaXRlclNwaSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU1RBTkRBUkRfT1VUUFVUX1RZUEUgY29udGFpbnMgSW1hZ2VJbnB1dFN0cmVhbS5jbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzW10gU1RBTkRBUkRfT1VUUFVUX1RZUEUgPSBuZXcgQ2xhc3NbXSB7CisgICAgICAgIEltYWdlSW5wdXRTdHJlYW0uY2xhc3MKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIG91dHB1dCB0eXBlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2xhc3NbXSBvdXRwdXRUeXBlczsKKworICAgIC8qKgorICAgICAqIFRoZSByZWFkZXIgU1BJIG5hbWVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSByZWFkZXJTcGlOYW1lczsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZVdyaXRlclNwaS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW1hZ2VXcml0ZXJTcGkoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VXcml0ZXJTcGkgd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHZlbmRvck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZW5kb3IgbmFtZS4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHZlcnNpb24uCisgICAgICogQHBhcmFtIG5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG5hbWVzLgorICAgICAqIEBwYXJhbSBzdWZmaXhlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIHRoZSBmaWxlIHN1ZmZpeGVzLgorICAgICAqIEBwYXJhbSBNSU1FVHlwZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbiBhcnJheSBvZiBzdHJpbmdzIHJlcHJlc2VudGluZyBNSU1FIHR5cGVzLgorICAgICAqIEBwYXJhbSBwbHVnaW5DbGFzc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwbHVnLWluIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIG91dHB1dFR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHR5cGVzLgorICAgICAqIEBwYXJhbSByZWFkZXJTcGlOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBjbGFzcyBuYW1lcyBvZiBhbGwgYXNzb2NpYXRlZAorICAgICAqICAgICAgICAgICAgSW1hZ2VSZWFkZXJzLgorICAgICAqIEBwYXJhbSBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIHN0cmVhbSBtZXRhZGF0YSBjYW4gYmUgZGVzY3JpYmVkIGJ5CisgICAgICogICAgICAgICAgICBzdGFuZGFyZCBtZXRhZGF0YSBmb3JtYXQuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUuCisgICAgICogQHBhcmFtIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmF0aXZlIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0LgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBzdHJlYW0gbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWVzLgorICAgICAqIEBwYXJhbSBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGV4dHJhIHN0cmVhbSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRTdHJlYW1NZXRhZGF0YUZvcm1hdC4KKyAgICAgKiBAcGFyYW0gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIGltYWdlIG1ldGFkYXRhIGNhbiBiZSBkZXNjcmliZWQgYnkKKyAgICAgKiAgICAgICAgICAgIHN0YW5kYXJkIG1ldGFkYXRhIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYXRpdmUgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWUsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXROYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZS4KKyAgICAgKiBAcGFyYW0gbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hdGl2ZSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZSwgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIGdldE5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXQuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgZXh0cmEgaW1hZ2UgbWV0YWRhdGEgZm9ybWF0IG5hbWVzLCByZXR1cm5lZCBieQorICAgICAqICAgICAgICAgICAgZ2V0RXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMuCisgICAgICogQHBhcmFtIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHRyYSBpbWFnZSBtZXRhZGF0YSBmb3JtYXQgY2xhc3MgbmFtZXMsIHJldHVybmVkIGJ5CisgICAgICogICAgICAgICAgICBnZXRJbWFnZU1ldGFkYXRhRm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBJbWFnZVdyaXRlclNwaShTdHJpbmcgdmVuZG9yTmFtZSwgU3RyaW5nIHZlcnNpb24sIFN0cmluZ1tdIG5hbWVzLCBTdHJpbmdbXSBzdWZmaXhlcywKKyAgICAgICAgICAgIFN0cmluZ1tdIE1JTUVUeXBlcywgU3RyaW5nIHBsdWdpbkNsYXNzTmFtZSwgQ2xhc3NbXSBvdXRwdXRUeXBlcywKKyAgICAgICAgICAgIFN0cmluZ1tdIHJlYWRlclNwaU5hbWVzLCBib29sZWFuIHN1cHBvcnRzU3RhbmRhcmRTdHJlYW1NZXRhZGF0YUZvcm1hdCwKKyAgICAgICAgICAgIFN0cmluZyBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUsIFN0cmluZyBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZSwKKyAgICAgICAgICAgIFN0cmluZ1tdIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcywgU3RyaW5nW10gZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMsCisgICAgICAgICAgICBib29sZWFuIHN1cHBvcnRzU3RhbmRhcmRJbWFnZU1ldGFkYXRhRm9ybWF0LCBTdHJpbmcgbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUsCisgICAgICAgICAgICBTdHJpbmcgbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZSwgU3RyaW5nW10gZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICBTdHJpbmdbXSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzKSB7CisgICAgICAgIHN1cGVyKHZlbmRvck5hbWUsIHZlcnNpb24sIG5hbWVzLCBzdWZmaXhlcywgTUlNRVR5cGVzLCBwbHVnaW5DbGFzc05hbWUsCisgICAgICAgICAgICAgICAgc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0LCBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUsCisgICAgICAgICAgICAgICAgbmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUsIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcywKKyAgICAgICAgICAgICAgICBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcywgc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQsCisgICAgICAgICAgICAgICAgbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUsIG5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUsCisgICAgICAgICAgICAgICAgZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMsIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMpOworCisgICAgICAgIGlmIChvdXRwdXRUeXBlcyA9PSBudWxsIHx8IG91dHB1dFR5cGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm91dHB1dCB0eXBlcyBhcnJheSBjYW5ub3QgYmUgTlVMTCBvciBlbXB0eSIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5vdXRwdXRUeXBlcyA9IG91dHB1dFR5cGVzOworICAgICAgICB0aGlzLnJlYWRlclNwaU5hbWVzID0gcmVhZGVyU3BpTmFtZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb3JtYXQgb2YgdGhlIHdyaXRlcidzIG91dHB1dCBpcyBsb3NzbGVzcy4gVGhlCisgICAgICogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRydWUuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiBhIGZvcm1hdCBpcyBsb3NzbGVzcywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRm9ybWF0TG9zc2xlc3MoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYXJyYXkgb2YgQ2xhc3Mgb2JqZWN0cyB3aG9zZSB0eXBlcyBjYW4gYmUgdXNlZCBhcyBvdXRwdXQgZm9yIHRoaXMKKyAgICAgKiB3cml0ZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgb3V0cHV0IHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc1tdIGdldE91dHB1dFR5cGVzKCkgeworICAgICAgICByZXR1cm4gb3V0cHV0VHlwZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoZSBJbWFnZVdyaXRlciBpbXBsZW1lbnRhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIHNlcnZpY2UgcHJvdmlkZXIgY2FuIGVuY29kZSBhbiBpbWFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIEltYWdlVHlwZVNwZWNpZmllci4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGFuIGltYWdlIHdpdGggdGhlIHNwZWNpZmllZCB0eXBlIGNhbiBiZSBlbmNvZGVkLCBmYWxzZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNhbkVuY29kZUltYWdlKEltYWdlVHlwZVNwZWNpZmllciB0eXBlKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGUgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiBzZXJ2aWNlIHByb3ZpZGVyIGNhbiBlbmNvZGUgdGhlIHNwZWNpZmllZCBSZW5kZXJlZEltYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbQorICAgICAqICAgICAgICAgICAgdGhlIFJlbmRlcmVkSW1hZ2UuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBSZW5kZXJlZEltYWdlIGNhbiBiZSBlbmNvZGVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlSW1hZ2UoUmVuZGVyZWRJbWFnZSBpbSkgeworICAgICAgICByZXR1cm4gY2FuRW5jb2RlSW1hZ2UoSW1hZ2VUeXBlU3BlY2lmaWVyLmNyZWF0ZUZyb21SZW5kZXJlZEltYWdlKGltKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgc2VydmljZQorICAgICAqIHByb3ZpZGVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEltYWdlV3JpdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW1hZ2VXcml0ZXIgY3JlYXRlV3JpdGVySW5zdGFuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY3JlYXRlV3JpdGVySW5zdGFuY2UobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgSW1hZ2VXcml0ZXIgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgc2VydmljZQorICAgICAqIHByb3ZpZGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBleHRlbnNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBhIHBsdWctaW4gc3BlY2lmaWMgZXh0ZW5zaW9uIG9iamVjdCwgb3IgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBJbWFnZVdyaXRlci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEltYWdlV3JpdGVyIGNyZWF0ZVdyaXRlckluc3RhbmNlKE9iamVjdCBleHRlbnNpb24pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIEltYWdlV3JpdGVyIG9iamVjdCBpcyBhbiBpbnN0YW5jZSBvZgorICAgICAqIHRoZSBJbWFnZVdyaXRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBzZXJ2aWNlIHByb3ZpZGVyIG9yIG5vdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gd3JpdGVyCisgICAgICogICAgICAgICAgICB0aGUgSW1hZ2VXcml0ZXIuCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGUgc3BlY2lmaWVkIEltYWdlV3JpdGVyIG9iamVjdCBpcyBhbiBpbnN0YW5jZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIEltYWdlV3JpdGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UgcHJvdmlkZXIsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNPd25Xcml0ZXIoSW1hZ2VXcml0ZXIgd3JpdGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBuYW1lcyBvZiB0aGUgSW1hZ2VSZWFkZXJTcGkgY2xhc3NlcyB0aGF0CisgICAgICogc3VwcG9ydCB0aGUgaW50ZXJuYWwgbWV0YWRhdGEgcmVwcmVzZW50YXRpb24gdXNlZCBieSB0aGUgSW1hZ2VXcml0ZXIgb2YKKyAgICAgKiB0aGlzIHNlcnZpY2UgcHJvdmlkZXIsIG9yIG51bGwgaWYgdGhlcmUgYXJlIG5vIHN1Y2ggSW1hZ2VSZWFkZXJzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBuYW1lcyBvZiB0aGUgSW1hZ2VXcml0ZXJTcGkgY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0SW1hZ2VSZWFkZXJTcGlOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIHJlYWRlclNwaU5hbWVzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9SZWdpc3RlcmFibGVTZXJ2aWNlLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvUmVnaXN0ZXJhYmxlU2VydmljZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlMmY0ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvUmVnaXN0ZXJhYmxlU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3BpOworCisvKioKKyAqIFRoZSBSZWdpc3RlcmFibGVTZXJ2aWNlIGludGVyZmFjZSBwcm92aWRlcyBzZXJ2aWNlIHByb3ZpZGVyIG9iamVjdHMgdGhhdCBjYW4KKyAqIGJlIHJlZ2lzdGVyZWQgYnkgYSBTZXJ2aWNlUmVnaXN0cnksIGFuZCBub3RpZmljYXRpb25zIHRoYXQgcmVnaXN0cmF0aW9uIGFuZAorICogZGVyZWdpc3RyYXRpb24gaGF2ZSBiZWVuIHBlcmZvcm1lZC4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVnaXN0ZXJhYmxlU2VydmljZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgaXMKKyAgICAgKiByZWdpc3RlcmVkIHRvIHRoZSBzcGVjaWZpZWQgY2F0ZWdvcnkgb2YgdGhlIHNwZWNpZmllZCByZWdpc3RyeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVnaXN0cnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBTZXJ2aWNlUmVnaXN0cnkgdG8gYmUgcmVnaXN0ZXJlZC4KKyAgICAgKiBAcGFyYW0gY2F0ZWdvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyByZXByZXNlbnRpbmcgYSBjYXRlZ29yeS4KKyAgICAgKi8KKyAgICB2b2lkIG9uUmVnaXN0cmF0aW9uKFNlcnZpY2VSZWdpc3RyeSByZWdpc3RyeSwgQ2xhc3M8Pz4gY2F0ZWdvcnkpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGlzCisgICAgICogZGVyZWdpc3RlcmVkIHRvIHRoZSBzcGVjaWZpZWQgY2F0ZWdvcnkgb2YgdGhlIHNwZWNpZmllZCByZWdpc3RyeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmVnaXN0cnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBTZXJ2aWNlUmVnaXN0cnkgdG8gYmUgcmVnaXN0ZXJlZC4KKyAgICAgKiBAcGFyYW0gY2F0ZWdvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyByZXByZXNlbnRpbmcgYSBjYXRlZ29yeS4KKyAgICAgKi8KKyAgICB2b2lkIG9uRGVyZWdpc3RyYXRpb24oU2VydmljZVJlZ2lzdHJ5IHJlZ2lzdHJ5LCBDbGFzczw/PiBjYXRlZ29yeSk7Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvU2VydmljZVJlZ2lzdHJ5LmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvU2VydmljZVJlZ2lzdHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzliMDJhMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3NwaS9TZXJ2aWNlUmVnaXN0cnkuamF2YQpAQCAtMCwwICsxLDU1MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5zcGk7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworCisvKioKKyAqIFRoZSBTZXJ2aWNlUmVnaXN0cnkgY2xhc3MgcHJvdmlkZXMgYWJpbGl0eSB0byByZWdpc3RlciwgZGVyZWdpc3RlciwgbG9vayB1cAorICogYW5kIG9idGFpbiBzZXJ2aWNlIHByb3ZpZGVyIGluc3RhbmNlcyAoU1BJcykuIEEgc2VydmljZSBtZWFucyBhIHNldCBvZgorICogaW50ZXJmYWNlcyBhbmQgY2xhc3NlcywgYW5kIGEgc2VydmljZSBwcm92aWRlciBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBhCisgKiBzZXJ2aWNlLiBTZXJ2aWNlIHByb3ZpZGVycyBjYW4gYmUgYXNzb2NpYXRlZCB3aXRoIG9uZSBvciBtb3JlIGNhdGVnb3JpZXMuCisgKiBFYWNoIGNhdGVnb3J5IGlzIGRlZmluZWQgYnkgYSBjbGFzcyBvciBpbnRlcmZhY2UuIE9ubHkgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgYQorICogZWFjaCBjbGFzcyBpcyBhbGxvd2VkIHRvIGJlIHJlZ2lzdGVyZWQgYXMgYSBjYXRlZ29yeS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBTZXJ2aWNlUmVnaXN0cnkgeworCisgICAgLyoqCisgICAgICogVGhlIGNhdGVnb3JpZXMuCisgICAgICovCisgICAgQ2F0ZWdvcmllc01hcCBjYXRlZ29yaWVzID0gbmV3IENhdGVnb3JpZXNNYXAodGhpcyk7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgU2VydmljZVJlZ2lzdHJ5IHdpdGggdGhlIHNwZWNpZmllZCBjYXRlZ29yaWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjYXRlZ29yaWVzSXRlcmF0b3IKKyAgICAgKiAgICAgICAgICAgIGFuIEl0ZXJhdG9yIG9mIENsYXNzIG9iamVjdHMgZm9yIGRlZmluaW5nIG9mIGNhdGVnb3JpZXMuCisgICAgICovCisgICAgcHVibGljIFNlcnZpY2VSZWdpc3RyeShJdGVyYXRvcjxDbGFzczw/Pj4gY2F0ZWdvcmllc0l0ZXJhdG9yKSB7CisgICAgICAgIGlmIChudWxsID09IGNhdGVnb3JpZXNJdGVyYXRvcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2F0ZWdvcmllcyBpdGVyYXRvciBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoY2F0ZWdvcmllc0l0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gYyA9IGNhdGVnb3JpZXNJdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICBjYXRlZ29yaWVzLmFkZENhdGVnb3J5KGMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9va3MgdXAgYW5kIGluc3RhbnRpYXRlcyB0aGUgYXZhaWxhYmxlIHByb3ZpZGVycyBvZiB0aGlzIHNlcnZpY2UgdXNpbmcKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGNsYXNzIGxvYWRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvdmlkZXJDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIENsYXNzIG9iamVjdCBvZiB0aGUgcHJvdmlkZXIgdG8gYmUgbG9va2VkIHVwLgorICAgICAqIEBwYXJhbSBsb2FkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyBsb2FkZXIgdG8gYmUgdXNlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpdGVyYXRvciBvZiBwcm92aWRlcnMgb2JqZWN0cyBmb3IgdGhpcyBzZXJ2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IEl0ZXJhdG9yPFQ+IGxvb2t1cFByb3ZpZGVycyhDbGFzczxUPiBwcm92aWRlckNsYXNzLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvb2tzIHVwIGFuZCBpbnN0YW50aWF0ZXMgdGhlIGF2YWlsYWJsZSBwcm92aWRlcnMgb2YgdGhpcyBzZXJ2aWNlIHVzaW5nCisgICAgICogdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm92aWRlckNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgQ2xhc3Mgb2JqZWN0IG9mIHRoZSBwcm92aWRlciB0byBiZSBsb29rZWQgdXAuCisgICAgICogQHJldHVybiB0aGUgaXRlcmF0b3Igb2YgcHJvdmlkZXJzIG9iamVjdHMgZm9yIHRoaXMgc2VydmljZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBJdGVyYXRvcjxUPiBsb29rdXBQcm92aWRlcnMoQ2xhc3M8VD4gcHJvdmlkZXJDbGFzcykgeworICAgICAgICByZXR1cm4gbG9va3VwUHJvdmlkZXJzKHByb3ZpZGVyQ2xhc3MsIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVycyB0aGUgc3BlY2lmaWVkIHNlcnZpY2UgcHJvdmlkZXIgb2JqZWN0IGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXRlZ29yaWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBwcm92aWRlciB0byBiZSByZWdpc3RlcmVkLgorICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAqICAgICAgICAgICAgdGhlIGNhdGVnb3J5LgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgbm8gcHJvdmlkZXIgb2YgdGhlIHNhbWUgY2xhc3MgaXMgcmVnaXN0ZXJlZCBpbiB0aGlzCisgICAgICogICAgICAgICBjYXRlZ29yeSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyA8VD4gYm9vbGVhbiByZWdpc3RlclNlcnZpY2VQcm92aWRlcihUIHByb3ZpZGVyLCBDbGFzczxUPiBjYXRlZ29yeSkgeworICAgICAgICByZXR1cm4gY2F0ZWdvcmllcy5hZGRQcm92aWRlcihwcm92aWRlciwgY2F0ZWdvcnkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVycyBhIGxpc3Qgb2Ygc2VydmljZSBwcm92aWRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3ZpZGVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2Ygc2VydmljZSBwcm92aWRlcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVnaXN0ZXJTZXJ2aWNlUHJvdmlkZXJzKEl0ZXJhdG9yPD8+IHByb3ZpZGVycykgeworICAgICAgICBmb3IgKEl0ZXJhdG9yPD8+IGl0ZXJhdG9yID0gcHJvdmlkZXJzOyBpdGVyYXRvci5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICBjYXRlZ29yaWVzLmFkZFByb3ZpZGVyKGl0ZXJhdG9yLm5leHQoKSwgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlcnMgdGhlIHNwZWNpZmllZCBzZXJ2aWNlIHByb3ZpZGVyIG9iamVjdCBpbiBhbGwgY2F0ZWdvcmllcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVyU2VydmljZVByb3ZpZGVyKE9iamVjdCBwcm92aWRlcikgeworICAgICAgICBjYXRlZ29yaWVzLmFkZFByb3ZpZGVyKHByb3ZpZGVyLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXJlZ2lzdGVycyB0aGUgc3BlY2lmaWVzIHNlcnZpY2UgcHJvdmlkZXIgZnJvbSB0aGUgc3BlY2lmaWVkIGNhdGVnb3J5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlcnZpY2UgcHJvdmlkZXIgdG8gYmUgZGVyZWdpc3RlcmVkLgorICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBwcm92aWRlciB3YXMgYWxyZWFkeSByZWdpc3RlcmVkIGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGNhdGVnb3J5LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIDxUPiBib29sZWFuIGRlcmVnaXN0ZXJTZXJ2aWNlUHJvdmlkZXIoVCBwcm92aWRlciwgQ2xhc3M8VD4gY2F0ZWdvcnkpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlcmVnaXN0ZXJzIHRoZSBzcGVjaWZpZWQgc2VydmljZSBwcm92aWRlciBmcm9tIGFsbCBjYXRlZ29yaWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBzZXJ2aWNlIHByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlcmVnaXN0ZXJTZXJ2aWNlUHJvdmlkZXIoT2JqZWN0IHByb3ZpZGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIEl0ZXJhdG9yIG9mIHJlZ2lzdGVyZWQgc2VydmljZSBwcm92aWRlcnMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGNhdGVnb3J5IHdoaWNoIHNhdGlzZnkgdGhlIHNwZWNpZmllZCBGaWx0ZXIuIFRoZSB1c2VPcmRlcmluZyBwYXJhbWV0ZXIKKyAgICAgKiBpbmRpY2F0ZXMgd2hldGhlciB0aGUgaXRlcmF0b3Igd2lsbCByZXR1cm4gYWxsIG9mIHRoZSBzZXJ2ZXIgcHJvdmlkZXIKKyAgICAgKiBvYmplY3RzIGluIGEgc2V0IG9yZGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiBAcGFyYW0gZmlsdGVyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGZpbHRlci4KKyAgICAgKiBAcGFyYW0gdXNlT3JkZXJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIGluZGljYXRpbmcgdGhhdCBwcm92aWRlcnMgYXJlIG9yZGVyZWQgaW4gdGhlIHJldHVybmVkCisgICAgICogICAgICAgICAgICBJdGVyYXRvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBpdGVyYXRvciBvZiByZWdpc3RlcmVkIHNlcnZpY2UgcHJvdmlkZXJzLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8VD4gSXRlcmF0b3I8VD4gZ2V0U2VydmljZVByb3ZpZGVycyhDbGFzczxUPiBjYXRlZ29yeSwgRmlsdGVyIGZpbHRlciwgYm9vbGVhbiB1c2VPcmRlcmluZykgeworICAgICAgICByZXR1cm4gbmV3IEZpbHRlcmVkSXRlcmF0b3I8VD4oZmlsdGVyLCAoSXRlcmF0b3I8VD4pY2F0ZWdvcmllcy5nZXRQcm92aWRlcnMoY2F0ZWdvcnksCisgICAgICAgICAgICAgICAgdXNlT3JkZXJpbmcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIEl0ZXJhdG9yIG9mIGFsbCByZWdpc3RlcmVkIHNlcnZpY2UgcHJvdmlkZXJzIGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXRlZ29yeS4gVGhlIHVzZU9yZGVyaW5nIHBhcmFtZXRlciBpbmRpY2F0ZXMgd2hldGhlciB0aGUgaXRlcmF0b3Igd2lsbAorICAgICAqIHJldHVybiBhbGwgb2YgdGhlIHNlcnZlciBwcm92aWRlciBvYmplY3RzIGluIGEgc2V0IG9yZGVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiBAcGFyYW0gdXNlT3JkZXJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbGFnIGluZGljYXRpbmcgdGhhdCBwcm92aWRlcnMgYXJlIG9yZGVyZWQgaW4gdGhlIHJldHVybmVkCisgICAgICogICAgICAgICAgICBJdGVyYXRvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBJdGVyYXRvciBvZiBzZXJ2aWNlIHByb3ZpZGVycy4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgPFQ+IEl0ZXJhdG9yPFQ+IGdldFNlcnZpY2VQcm92aWRlcnMoQ2xhc3M8VD4gY2F0ZWdvcnksIGJvb2xlYW4gdXNlT3JkZXJpbmcpIHsKKyAgICAgICAgcmV0dXJuIChJdGVyYXRvcjxUPiljYXRlZ29yaWVzLmdldFByb3ZpZGVycyhjYXRlZ29yeSwgdXNlT3JkZXJpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHJlZ2lzdGVyZWQgc2VydmljZSBwcm92aWRlciBvYmplY3QgdGhhdCBoYXMgdGhlIHNwZWNpZmllZCBjbGFzcworICAgICAqIHR5cGUuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3ZpZGVyQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgY2xhc3MuCisgICAgICogQHJldHVybiB0aGUgc2VydmljZSBwcm92aWRlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIDxUPiBUIGdldFNlcnZpY2VQcm92aWRlckJ5Q2xhc3MoQ2xhc3M8VD4gcHJvdmlkZXJDbGFzcykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhbiBvcmRlcmluZyBiZXR3ZWVuIHR3byBzZXJ2aWNlIHByb3ZpZGVyIG9iamVjdHMgd2l0aGluIHRoZQorICAgICAqIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2F0ZWdvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgY2F0ZWdvcnkuCisgICAgICogQHBhcmFtIGZpcnN0UHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBwcm92aWRlci4KKyAgICAgKiBAcGFyYW0gc2Vjb25kUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgcHJvdmlkZXIuCisgICAgICogQHJldHVybiB0cnVlLCBpZiBhIHByZXZpb3VzbHkgdW5zZXQgb3JkZXIgd2FzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IGJvb2xlYW4gc2V0T3JkZXJpbmcoQ2xhc3M8VD4gY2F0ZWdvcnksIFQgZmlyc3RQcm92aWRlciwgVCBzZWNvbmRQcm92aWRlcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5zZXRzIGFuIG9yZGVyaW5nIGJldHdlZW4gdHdvIHNlcnZpY2UgcHJvdmlkZXIgb2JqZWN0cyB3aXRoaW4gdGhlCisgICAgICogc3BlY2lmaWVkIGNhdGVnb3J5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiBAcGFyYW0gZmlyc3RQcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBzZWNvbmRQcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBwcm92aWRlci4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGEgcHJldmlvdXNseSB1bnNldCBvcmRlciB3YXMgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IGJvb2xlYW4gdW5zZXRPcmRlcmluZyhDbGFzczxUPiBjYXRlZ29yeSwgVCBmaXJzdFByb3ZpZGVyLCBUIHNlY29uZFByb3ZpZGVyKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXJlZ2lzdGVycyBhbGwgcHJvdmlkZXJzIGZyb20gdGhlIHNwZWNpZmllZCBjYXRlZ29yeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2F0ZWdvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgY2F0ZWdvcnkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVyZWdpc3RlckFsbChDbGFzczw/PiBjYXRlZ29yeSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVyZWdpc3RlciBhbGwgcHJvdmlkZXJzIGZyb20gYWxsIGNhdGVnb3JpZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVyZWdpc3RlckFsbCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmFsaXplcyB0aGlzIG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgZmluYWxpemF0aW9uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIFRPRE8gdW5jb21tZW50IHdoZW4gZGVyZWdpc3RlckFsbCBpcyBpbXBsZW1lbnRlZAorICAgICAgICAvLyBkZXJlZ2lzdGVyQWxsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBwcm92aWRlciBoYXMgYmVlbiBhbHJlYWR5IHJlZ2lzdGVyZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgdG8gYmUgY2hlY2tlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaGFzIGJlZW4gYWxyZWFkeSByZWdpc3RlcmVkLAorICAgICAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBwcm92aWRlcikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbiBpdGVyYXRvciBvZiBDbGFzcyBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBjYXRlZ29yaWVzLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhdG9yIG9mIENsYXNzIG9iamVjdHMuCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPENsYXNzPD8+PiBnZXRDYXRlZ29yaWVzKCkgeworICAgICAgICByZXR1cm4gY2F0ZWdvcmllcy5saXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIFNlcnZpY2VSZWdpc3RyeS5GaWx0ZXIgaW50ZXJmYWNlIGlzIHVzZWQgYnkKKyAgICAgKiBTZXJ2aWNlUmVnaXN0cnkuZ2V0U2VydmljZVByb3ZpZGVycyB0byBmaWx0ZXIgcHJvdmlkZXJzIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY3JpdGVyaW9uLgorICAgICAqIAorICAgICAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEZpbHRlciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIHNhdGlzZmllcyB0aGUgY3JpdGVyaW9uIG9mCisgICAgICAgICAqIHRoaXMgRmlsdGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgc2F0aXNmaWVzIHRoZSBjcml0ZXJpb24gb2YKKyAgICAgICAgICogICAgICAgICB0aGlzIEZpbHRlciwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBmaWx0ZXIoT2JqZWN0IHByb3ZpZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ2xhc3MgQ2F0ZWdvcmllc01hcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDYXRlZ29yaWVzTWFwIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNhdGVnb3JpZXMuCisgICAgICAgICAqLworICAgICAgICBNYXA8Q2xhc3M8Pz4sIFByb3ZpZGVyc01hcD4gY2F0ZWdvcmllcyA9IG5ldyBIYXNoTWFwPENsYXNzPD8+LCBQcm92aWRlcnNNYXA+KCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSByZWdpc3RyeS4KKyAgICAgICAgICovCisgICAgICAgIFNlcnZpY2VSZWdpc3RyeSByZWdpc3RyeTsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGNhdGVnb3JpZXMgbWFwLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHJlZ2lzdHJ5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIHJlZ2lzdHJ5LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENhdGVnb3JpZXNNYXAoU2VydmljZVJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CisgICAgICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gcmVnaXN0cnk7CisgICAgICAgIH0KKworICAgICAgICAvLyAtLSBUT0RPOiB1c2VPcmRlcmluZworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgcHJvdmlkZXJzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGNhdGVnb3J5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGNhdGVnb3J5LgorICAgICAgICAgKiBAcGFyYW0gdXNlT3JkZXJpbmcKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdXNlIG9yZGVyaW5nLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlcnMuCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcjw/PiBnZXRQcm92aWRlcnMoQ2xhc3M8Pz4gY2F0ZWdvcnksIGJvb2xlYW4gdXNlT3JkZXJpbmcpIHsKKyAgICAgICAgICAgIFByb3ZpZGVyc01hcCBwcm92aWRlcnMgPSBjYXRlZ29yaWVzLmdldChjYXRlZ29yeSk7CisgICAgICAgICAgICBpZiAobnVsbCA9PSBwcm92aWRlcnMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIGNhdGVnb3J5OiAiICsgY2F0ZWdvcnkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVycy5nZXRQcm92aWRlcnModXNlT3JkZXJpbmcpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExpc3QuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBpdGVyYXRvcjwgY2xhc3M8Pz4+LgorICAgICAgICAgKi8KKyAgICAgICAgSXRlcmF0b3I8Q2xhc3M8Pz4+IGxpc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gY2F0ZWdvcmllcy5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkZHMgdGhlIGNhdGVnb3J5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGNhdGVnb3J5CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGNhdGVnb3J5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBhZGRDYXRlZ29yeShDbGFzczw/PiBjYXRlZ29yeSkgeworICAgICAgICAgICAgY2F0ZWdvcmllcy5wdXQoY2F0ZWdvcnksIG5ldyBQcm92aWRlcnNNYXAoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQWRkcyBhIHByb3ZpZGVyIHRvIHRoZSBjYXRlZ29yeS4gSWYgPGNvZGU+Y2F0ZWdvcnk8L2NvZGU+IGlzCisgICAgICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IHRoZW4gdGhlIHByb3ZpZGVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGNhdGVnb3JpZXMKKyAgICAgICAgICogd2hpY2ggdGhlIHByb3ZpZGVyIGlzIGFzc2lnbmFibGUgZnJvbS4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHByb3ZpZGVyIHRvIGFkZC4KKyAgICAgICAgICogQHBhcmFtIGNhdGVnb3J5CisgICAgICAgICAqICAgICAgICAgICAgY2F0ZWdvcnkgdG8gYWRkIHByb3ZpZGVyIHRvLgorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoZXJlIHdlcmUgc3VjaCBwcm92aWRlciBpbiBzb21lIGNhdGVnb3J5LgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBhZGRQcm92aWRlcihPYmplY3QgcHJvdmlkZXIsIENsYXNzPD8+IGNhdGVnb3J5KSB7CisgICAgICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyIHNob3VsZCBiZSAhPSBOVUxMIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2xlYW4gcnQ7CisgICAgICAgICAgICBpZiAoY2F0ZWdvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJ0ID0gZmluZEFuZEFkZChwcm92aWRlcik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJ0ID0gYWRkVG9OYW1lZChwcm92aWRlciwgY2F0ZWdvcnkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocHJvdmlkZXIgaW5zdGFuY2VvZiBSZWdpc3RlcmFibGVTZXJ2aWNlKSB7CisgICAgICAgICAgICAgICAgKChSZWdpc3RlcmFibGVTZXJ2aWNlKXByb3ZpZGVyKS5vblJlZ2lzdHJhdGlvbihyZWdpc3RyeSwgY2F0ZWdvcnkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gcnQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQWRkcyB0aGUgdG8gbmFtZWQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIuCisgICAgICAgICAqIEBwYXJhbSBjYXRlZ29yeQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBjYXRlZ29yeS4KKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGFkZFRvTmFtZWQoT2JqZWN0IHByb3ZpZGVyLCBDbGFzczw/PiBjYXRlZ29yeSkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IGNhdGVnb3JpZXMuZ2V0KGNhdGVnb3J5KTsKKworICAgICAgICAgICAgaWYgKG51bGwgPT0gb2JqKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biBjYXRlZ29yeTogIiArIGNhdGVnb3J5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuICgoUHJvdmlkZXJzTWFwKW9iaikuYWRkUHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEZpbmQgYW5kIGFkZC4KKyAgICAgICAgICogCisgICAgICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlci4KKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGZpbmRBbmRBZGQoT2JqZWN0IHByb3ZpZGVyKSB7CisgICAgICAgICAgICBib29sZWFuIHJ0ID0gZmFsc2U7CisgICAgICAgICAgICBmb3IgKEVudHJ5PENsYXNzPD8+LCBQcm92aWRlcnNNYXA+IGUgOiBjYXRlZ29yaWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRLZXkoKS5pc0Fzc2lnbmFibGVGcm9tKHByb3ZpZGVyLmdldENsYXNzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJ0IHw9IGUuZ2V0VmFsdWUoKS5hZGRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJ0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIENsYXNzIFByb3ZpZGVyc01hcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQcm92aWRlcnNNYXAgeworICAgICAgICAvLyAtLSBUT0RPOiBwcm92aWRlcnMgb3JkZXJpbmcgc3VwcG9ydAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgcHJvdmlkZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgTWFwPENsYXNzPD8+LCBPYmplY3Q+IHByb3ZpZGVycyA9IG5ldyBIYXNoTWFwPENsYXNzPD8+LCBPYmplY3Q+KCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkZHMgdGhlIHByb3ZpZGVyLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHN1Y2Nlc3NmdWwuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGFkZFByb3ZpZGVyKE9iamVjdCBwcm92aWRlcikgeworICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVycy5wdXQocHJvdmlkZXIuZ2V0Q2xhc3MoKSwgcHJvdmlkZXIpICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgcHJvdmlkZXIgY2xhc3Nlcy4KKyAgICAgICAgICogCisgICAgICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIGNsYXNzZXMuCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcjxDbGFzczw/Pj4gZ2V0UHJvdmlkZXJDbGFzc2VzKCkgeworICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVycy5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gLS0gVE9ETyBvcmRlcmluZworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgcHJvdmlkZXJzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIHVzZXJPcmRlcmluZworICAgICAgICAgKiAgICAgICAgICAgIHRoZSB1c2VyIG9yZGVyaW5nLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlcnMuCisgICAgICAgICAqLworICAgICAgICBJdGVyYXRvcjw/PiBnZXRQcm92aWRlcnMoYm9vbGVhbiB1c2VyT3JkZXJpbmcpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm92aWRlcnMudmFsdWVzKCkuaXRlcmF0b3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBGaWx0ZXJlZEl0ZXJhdG9yLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZpbHRlcmVkSXRlcmF0b3I8RT4gaW1wbGVtZW50cyBJdGVyYXRvcjxFPiB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBmaWx0ZXIuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEZpbHRlciBmaWx0ZXI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBiYWNrZW5kLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBJdGVyYXRvcjxFPiBiYWNrZW5kOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmV4dCBvYmouCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEUgbmV4dE9iajsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGZpbHRlcmVkIGl0ZXJhdG9yLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGZpbHRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBmaWx0ZXIuCisgICAgICAgICAqIEBwYXJhbSBiYWNrZW5kCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGJhY2tlbmQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRmlsdGVyZWRJdGVyYXRvcihGaWx0ZXIgZmlsdGVyLCBJdGVyYXRvcjxFPiBiYWNrZW5kKSB7CisgICAgICAgICAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjsKKyAgICAgICAgICAgIHRoaXMuYmFja2VuZCA9IGJhY2tlbmQ7CisgICAgICAgICAgICBmaW5kTmV4dCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5leHQuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChuZXh0T2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgRSB0bXAgPSBuZXh0T2JqOworICAgICAgICAgICAgZmluZE5leHQoKTsKKyAgICAgICAgICAgIHJldHVybiB0bXA7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGZvciBuZXh0LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBzdWNjZXNzZnVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0T2JqICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVtb3ZlcyB0aGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIG5leHRPYmogdG8gYSBuZXh0IHByb3ZpZGVyIG1hdGNoaW5nIHRoZSBjcml0ZXJpb24gZ2l2ZW4gYnkgdGhlCisgICAgICAgICAqIGZpbHRlci4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBmaW5kTmV4dCgpIHsKKyAgICAgICAgICAgIG5leHRPYmogPSBudWxsOworICAgICAgICAgICAgd2hpbGUgKGJhY2tlbmQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgRSBvID0gYmFja2VuZC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKGZpbHRlci5maWx0ZXIobykpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV4dE9iaiA9IG87CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zcGkvcGFja2FnZS5odG1sIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOGNlZmY0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3BpL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICBUaGlzIHBhY2thZ2UgcHJvdmlkZXMgc2V2ZXJhbCBTZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZSAoU1BJKSBjbGFzc2VzIGZvciByZWFkZXJzLCB3cml0ZXJzLCB0cmFuc2NvZGVycyBhbmQgc3RyZWFtcyB0byBoYW5kbGUgaW1hZ2VzLgorICAgIDwvcD4KKyAgQHNpbmNlIEFuZHJvaWQgMS4wCisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9GaWxlQ2FjaGVJbWFnZUlucHV0U3RyZWFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUNhY2hlSW1hZ2VJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxMGFjNjYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUNhY2hlSW1hZ2VJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3RyZWFtOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFRoZSBGaWxlQ2FjaGVJbWFnZUlucHV0U3RyZWFtIGNsYXNzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIEltYWdlSW5wdXRTdHJlYW0KKyAqIHdoaWNoIHJlYWRzIGZyb20gaXRzIElucHV0U3RyZWFtIGFuZCB1c2VzIGEgdGVtcG9yYXJ5IGZpbGUgYXMgYSBjYWNoZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlQ2FjaGVJbWFnZUlucHV0U3RyZWFtIGV4dGVuZHMgSW1hZ2VJbnB1dFN0cmVhbUltcGwgeworCisgICAgLyoqCisgICAgICogVGhlIGlzLgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEZpbGUgZmlsZTsKKworICAgIC8qKgorICAgICAqIFRoZSByYWYuCisgICAgICovCisgICAgcHJpdmF0ZSBSYW5kb21BY2Nlc3NGaWxlIHJhZjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGaWxlQ2FjaGVJbWFnZUlucHV0U3RyZWFtIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIElucHV0U3RyZWFtIGFuZCB1c2luZyB0aGUgc3BlY2lmaWVkIEZpbGUgYXMgaXRzIGNhY2hlIGRpcmVjdG9yeS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUgSW5wdXRTdHJlYW0gZm9yIHJlYWRpbmcuCisgICAgICogQHBhcmFtIGNhY2hlRGlyCisgICAgICogICAgICAgICAgICB0aGUgY2FjaGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBjYWNoZSBmaWxlIHdpbGwgYmUgY3JlYXRlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIEZpbGVDYWNoZUltYWdlSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gc3RyZWFtLCBGaWxlIGNhY2hlRGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0cmVhbSA9PSBudWxsISIpOworICAgICAgICB9CisgICAgICAgIGlzID0gc3RyZWFtOworCisgICAgICAgIGlmIChjYWNoZURpciA9PSBudWxsIHx8IGNhY2hlRGlyLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKEZpbGVDYWNoZUltYWdlT3V0cHV0U3RyZWFtLklJT19URU1QX0ZJTEVfUFJFRklYLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBjYWNoZURpcik7CisgICAgICAgICAgICBmaWxlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgZGlyZWN0b3J5ISIpOworICAgICAgICB9CisKKyAgICAgICAgcmFmID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYml0T2Zmc2V0ID0gMDsKKworICAgICAgICBpZiAoc3RyZWFtUG9zID49IHJhZi5sZW5ndGgoKSkgeworICAgICAgICAgICAgaW50IGIgPSBpcy5yZWFkKCk7CisKKyAgICAgICAgICAgIGlmIChiIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmFmLnNlZWsoc3RyZWFtUG9zKyspOworICAgICAgICAgICAgcmFmLndyaXRlKGIpOworICAgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgIH0KKworICAgICAgICByYWYuc2VlayhzdHJlYW1Qb3MrKyk7CisgICAgICAgIHJldHVybiByYWYucmVhZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYml0T2Zmc2V0ID0gMDsKKworICAgICAgICBpZiAoc3RyZWFtUG9zID49IHJhZi5sZW5ndGgoKSkgeworICAgICAgICAgICAgaW50IG5CeXRlcyA9IGlzLnJlYWQoYiwgb2ZmLCBsZW4pOworCisgICAgICAgICAgICBpZiAobkJ5dGVzIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmFmLnNlZWsoc3RyZWFtUG9zKTsKKyAgICAgICAgICAgIHJhZi53cml0ZShiLCBvZmYsIG5CeXRlcyk7CisgICAgICAgICAgICBzdHJlYW1Qb3MgKz0gbkJ5dGVzOworICAgICAgICAgICAgcmV0dXJuIG5CeXRlczsKKyAgICAgICAgfQorCisgICAgICAgIHJhZi5zZWVrKHN0cmVhbVBvcyk7CisgICAgICAgIGludCBuQnl0ZXMgPSByYWYucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIHN0cmVhbVBvcyArPSBuQnl0ZXM7CisgICAgICAgIHJldHVybiBuQnl0ZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWQoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWRNZW1vcnkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICBmaWxlLmRlbGV0ZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9GaWxlQ2FjaGVJbWFnZU91dHB1dFN0cmVhbS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0ZpbGVDYWNoZUltYWdlT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM1YWZhYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9GaWxlQ2FjaGVJbWFnZU91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3RyZWFtOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworCisvKioKKyAqIFRoZSBGaWxlQ2FjaGVJbWFnZU91dHB1dFN0cmVhbSBjbGFzcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZgorICogSW1hZ2VPdXRwdXRTdHJlYW0gdGhhdCB3cml0ZXMgdG8gaXRzIE91dHB1dFN0cmVhbSB1c2luZyBhIHRlbXBvcmFyeSBmaWxlIGFzIGEKKyAqIGNhY2hlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZpbGVDYWNoZUltYWdlT3V0cHV0U3RyZWFtIGV4dGVuZHMgSW1hZ2VPdXRwdXRTdHJlYW1JbXBsIHsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBJSU9fVEVNUF9GSUxFX1BSRUZJWC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIElJT19URU1QX0ZJTEVfUFJFRklYID0gImlpb0NhY2hlIjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBNQVhfQlVGRkVSX0xFTi4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IE1BWF9CVUZGRVJfTEVOID0gMTA0ODU3NTsgLy8gMSBNQiAtIGlzIGl0IG5vdCB0b28gbXVjaD8KKworICAgIC8qKgorICAgICAqIFRoZSBvcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBvczsKKworICAgIC8qKgorICAgICAqIFRoZSBmaWxlLgorICAgICAqLworICAgIHByaXZhdGUgRmlsZSBmaWxlOworCisgICAgLyoqCisgICAgICogVGhlIHJhZi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgRmlsZUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIE91dHB1dFN0cmVhbSBmb3Igd3JpdGluZy4KKyAgICAgKiBAcGFyYW0gY2FjaGVEaXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYWNoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGNhY2hlIGZpbGUgd2lsbCBiZSBjcmVhdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHN0cmVhbSwgRmlsZSBjYWNoZURpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzdHJlYW0gPT0gbnVsbCEiKTsKKyAgICAgICAgfQorICAgICAgICBvcyA9IHN0cmVhbTsKKworICAgICAgICBpZiAoY2FjaGVEaXIgPT0gbnVsbCB8fCBjYWNoZURpci5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICBmaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZShJSU9fVEVNUF9GSUxFX1BSRUZJWCwgbnVsbCwgY2FjaGVEaXIpOworICAgICAgICAgICAgZmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhIGRpcmVjdG9yeSEiKTsKKyAgICAgICAgfQorCisgICAgICAgIHJhZiA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGZpbGUsICJydyIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmx1c2hCZWZvcmUocmFmLmxlbmd0aCgpKTsKKyAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIGZpbGUuZGVsZXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWQoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWRNZW1vcnkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmx1c2hCaXRzKCk7IC8vIFNlZSB0aGUgZmx1c2hCaXRzIG1ldGhvZCBkZXNjcmlwdGlvbgorCisgICAgICAgIHJhZi53cml0ZShiKTsKKyAgICAgICAgc3RyZWFtUG9zKys7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZsdXNoQml0cygpOyAvLyBTZWUgdGhlIGZsdXNoQml0cyBtZXRob2QgZGVzY3JpcHRpb24KKworICAgICAgICByYWYud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICBzdHJlYW1Qb3MgKz0gbGVuOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJpdE9mZnNldCA9IDA7IC8vIFNob3VsZCByZXNldAorCisgICAgICAgIGludCByZXMgPSByYWYucmVhZCgpOworICAgICAgICBpZiAocmVzID49IDApIHsKKyAgICAgICAgICAgIHN0cmVhbVBvcysrOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJpdE9mZnNldCA9IDA7CisKKyAgICAgICAgaW50IG51bVJlYWQgPSByYWYucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIGlmIChudW1SZWFkID4gMCkgeworICAgICAgICAgICAgc3RyZWFtUG9zICs9IG51bVJlYWQ7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVtUmVhZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaEJlZm9yZShsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyByZWFkRnJvbVBvcyA9IGZsdXNoZWRQb3M7CisgICAgICAgIHN1cGVyLmZsdXNoQmVmb3JlKHBvcyk7CisKKyAgICAgICAgbG9uZyBieXRlc1RvUmVhZCA9IHBvcyAtIHJlYWRGcm9tUG9zOworICAgICAgICByYWYuc2VlayhyZWFkRnJvbVBvcyk7CisKKyAgICAgICAgaWYgKGJ5dGVzVG9SZWFkIDwgTUFYX0JVRkZFUl9MRU4pIHsKKyAgICAgICAgICAgIGJ5dGUgYnVmZmVyW10gPSBuZXcgYnl0ZVsoaW50KWJ5dGVzVG9SZWFkXTsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmZmVyKTsKKyAgICAgICAgICAgIG9zLndyaXRlKGJ1ZmZlcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBieXRlIGJ1ZmZlcltdID0gbmV3IGJ5dGVbTUFYX0JVRkZFUl9MRU5dOworICAgICAgICAgICAgd2hpbGUgKGJ5dGVzVG9SZWFkID4gMCkgeworICAgICAgICAgICAgICAgIGludCBjb3VudCA9IChpbnQpTWF0aC5taW4oTUFYX0JVRkZFUl9MRU4sIGJ5dGVzVG9SZWFkKTsKKyAgICAgICAgICAgICAgICByYWYucmVhZEZ1bGx5KGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICAgICAgICAgIG9zLndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICAgICAgICAgIGJ5dGVzVG9SZWFkIC09IGNvdW50OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgb3MuZmx1c2goKTsKKworICAgICAgICBpZiAocG9zICE9IHN0cmVhbVBvcykgeworICAgICAgICAgICAgcmFmLnNlZWsoc3RyZWFtUG9zKTsgLy8gUmVzZXQgdGhlIHBvc2l0aW9uCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZWVrKGxvbmcgcG9zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocG9zIDwgZmx1c2hlZFBvcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHJhZi5zZWVrKHBvcyk7CisgICAgICAgIHN0cmVhbVBvcyA9IHJhZi5nZXRGaWxlUG9pbnRlcigpOworICAgICAgICBiaXRPZmZzZXQgPSAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGxlbmd0aCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiByYWYubGVuZ3RoKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMUw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUltYWdlSW5wdXRTdHJlYW0uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9GaWxlSW1hZ2VJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5YjYwMDIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUltYWdlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEyMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgRmlsZUltYWdlSW5wdXRTdHJlYW0gY2xhc3MgaW1wbGVtZW50cyBJbWFnZUlucHV0U3RyZWFtIGFuZCBvYnRhaW5zIGl0cworICogaW5wdXQgZGF0YSBmcm9tIGEgRmlsZSBvciBSYW5kb21BY2Nlc3NGaWxlLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIEZpbGVJbWFnZUlucHV0U3RyZWFtIGV4dGVuZHMgSW1hZ2VJbnB1dFN0cmVhbUltcGwgeworCisgICAgLyoqCisgICAgICogVGhlIHJhZi4KKyAgICAgKi8KKyAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZjsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGaWxlSW1hZ2VJbnB1dFN0cmVhbSBmcm9tIHRoZSBzcGVjaWZpZWQgRmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIEZpbGUgb2YgaW5wdXQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgZmlsZSBkb2Vzbid0IGV4aXN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeworICAgICAgICAiRHVwbGljYXRlVGhyb3dzIgorICAgIH0pCisgICAgcHVibGljIEZpbGVJbWFnZUlucHV0U3RyZWFtKEZpbGUgZikgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJmID09IG51bGwhIik7CisgICAgICAgIH0KKworICAgICAgICByYWYgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBGaWxlSW1hZ2VJbnB1dFN0cmVhbSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBSYW5kb21BY2Nlc3NGaWxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByYWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBSYW5kb21BY2Nlc3NGaWxlIG9mIGlucHV0IGRhdGEuCisgICAgICovCisgICAgcHVibGljIEZpbGVJbWFnZUlucHV0U3RyZWFtKFJhbmRvbUFjY2Vzc0ZpbGUgcmFmKSB7CisgICAgICAgIGlmIChyYWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmFmID09IG51bGwhIik7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnJhZiA9IHJhZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiaXRPZmZzZXQgPSAwOworCisgICAgICAgIGludCByZXMgPSByYWYucmVhZCgpOworICAgICAgICBpZiAocmVzICE9IC0xKSB7CisgICAgICAgICAgICBzdHJlYW1Qb3MrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYml0T2Zmc2V0ID0gMDsKKworICAgICAgICBpbnQgbnVtUmVhZCA9IHJhZi5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKG51bVJlYWQgPj0gMCkgeworICAgICAgICAgICAgc3RyZWFtUG9zICs9IG51bVJlYWQ7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVtUmVhZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcmFmLmxlbmd0aCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gLTFMOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2Vlayhsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvcyA8IGdldEZsdXNoZWRQb3NpdGlvbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcmFmLnNlZWsocG9zKTsKKyAgICAgICAgc3RyZWFtUG9zID0gcmFmLmdldEZpbGVQb2ludGVyKCk7CisgICAgICAgIGJpdE9mZnNldCA9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUltYWdlT3V0cHV0U3RyZWFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vRmlsZUltYWdlT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjczMGJhNgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9GaWxlSW1hZ2VPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEyOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5zdHJlYW07CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhlIEZpbGVJbWFnZU91dHB1dFN0cmVhbSBjbGFzcyBpbXBsZW1lbnRzIEltYWdlT3V0cHV0U3RyZWFtIGFuZCB3cml0ZXMgdGhlCisgKiBvdXRwdXQgZGF0YSB0byBhIEZpbGUgb3IgUmFuZG9tQWNjZXNzRmlsZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlSW1hZ2VPdXRwdXRTdHJlYW0gZXh0ZW5kcyBJbWFnZU91dHB1dFN0cmVhbUltcGwgeworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUuCisgICAgICovCisgICAgUmFuZG9tQWNjZXNzRmlsZSBmaWxlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEZpbGVJbWFnZU91dHB1dFN0cmVhbSB3aXRoIHRoZSBzcGVjaWZpZWQgRmlsZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBGaWxlLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbGUgbm90IGZvdW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUltYWdlT3V0cHV0U3RyZWFtKEZpbGUgZikgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGYgIT0gbnVsbCA/IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJydyIpIDogbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IEZpbGVJbWFnZU91dHB1dFN0cmVhbSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBSYW5kb21BY2Nlc3NGaWxlLgorICAgICAqIAorICAgICAqIEBwYXJhbSByYWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgUmFuZG9tQWNjZXNzRmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUltYWdlT3V0cHV0U3RyZWFtKFJhbmRvbUFjY2Vzc0ZpbGUgcmFmKSB7CisgICAgICAgIGlmIChyYWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZmlsZSBzaG91bGQgbm90IGJlIE5VTEwiKTsKKyAgICAgICAgfQorICAgICAgICBmaWxlID0gcmFmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICAvLyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgZm9yIEltYWdlT3V0cHV0U3RyZWFtSW1wbCNmbHVzaEJpdHMoKQorICAgICAgICBmbHVzaEJpdHMoKTsKKyAgICAgICAgZmlsZS53cml0ZShiKTsKKyAgICAgICAgc3RyZWFtUG9zKys7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIC8vIGFjY29yZGluZyB0byB0aGUgc3BlYyBmb3IgSW1hZ2VPdXRwdXRTdHJlYW1JbXBsI2ZsdXNoQml0cygpCisgICAgICAgIGZsdXNoQml0cygpOworICAgICAgICBmaWxlLndyaXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgc3RyZWFtUG9zICs9IGxlbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBpbnQgcnQgPSBmaWxlLnJlYWQoKTsKKyAgICAgICAgaWYgKHJ0ICE9IC0xKSB7CisgICAgICAgICAgICBzdHJlYW1Qb3MrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBpbnQgcnQgPSBmaWxlLnJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICBpZiAocnQgIT0gLTEpIHsKKyAgICAgICAgICAgIHN0cmVhbVBvcyArPSBydDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbGVuZ3RoKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgICAgIHJldHVybiBmaWxlLmxlbmd0aCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIubGVuZ3RoKCk7IC8vIC0xTAorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2Vlayhsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gY2hlY2tDbG9zZWQoKSBpcyBwZXJmb3JtZWQgaW4gc3VwZXIuc2VlaygpCisgICAgICAgIHN1cGVyLnNlZWsocG9zKTsKKyAgICAgICAgZmlsZS5zZWVrKHBvcyk7CisgICAgICAgIHN0cmVhbVBvcyA9IGZpbGUuZ2V0RmlsZVBvaW50ZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgIGZpbGUuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vSUlPQnl0ZUJ1ZmZlci5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0lJT0J5dGVCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjdkODA4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0lJT0J5dGVCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBTZXJnZXkgSS4gU2FsaXNoZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3RyZWFtOworCisvLyAKKy8vIEBhdXRob3IgU2VyZ2V5IEkuIFNhbGlzaGV2CisvLyBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisvLworCisvKioKKyAqIFRoZSBJSU9CeXRlQnVmZmVyIGNsYXNzIHJlcHJlc2VudHMgYSBieXRlIGFycmF5IHdpdGggb2Zmc2V0IGFuZCBsZW5ndGggdGhhdAorICogaXMgdXNlZCBieSBJbWFnZUlucHV0U3RyZWFtIGZvciBvYnRhaW5pbmcgYSBzZXF1ZW5jZSBvZiBieXRlcy4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBjbGFzcyBJSU9CeXRlQnVmZmVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIGRhdGE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgb2Zmc2V0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IG9mZnNldDsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGguCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbGVuZ3RoOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IElJT0J5dGVCdWZmZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIElJT0J5dGVCdWZmZXIoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJ5dGUgYXJyYXkgb2YgdGhpcyBJSU9CeXRlQnVmZmVyLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKCkgeworICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsZW5ndGggaW4gdGhlIGFycmF5IHdoaWNoIHdpbGwgYmUgdXNlZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2Zmc2V0IG9mIHRoaXMgSUlPQnl0ZUJ1ZmZlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhpcyBJSU9CeXRlQnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5ldyBkYXRhIGFycmF5IHRvIHRoaXMgSUlPQnl0ZUJ1ZmZlciBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZGF0YSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhKGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGVuZ3RoIG9mIGRhdGEgd2hpY2ggd2lsbCBiZSB1c2VkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbGVuZ3RoLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExlbmd0aChpbnQgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG9mZnNldCBpbiB0aGUgZGF0YSBhcnJheSBvZiB0aGlzIElJT0J5dGVCdWZmZXIuCisgICAgICogCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBvZmZzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T2Zmc2V0KGludCBvZmZzZXQpIHsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0ltYWdlSW5wdXRTdHJlYW0uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2RlYzVkMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw1MDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworCitwYWNrYWdlIGphdmF4LmltYWdlaW8uc3RyZWFtOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CisKKy8qKgorICogVGhlIEltYWdlSW5wdXRTdHJlYW0gcmVwcmVzZW50cyBpbnB1dCBzdHJlYW0gaW50ZXJmYWNlIHRoYXQgaXMgdXNlZCBieQorICogSW1hZ2VSZWFkZXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJbWFnZUlucHV0U3RyZWFtIGV4dGVuZHMgRGF0YUlucHV0IHsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCBieXRlIG9yZGVyIGZvciByZWFkaW5nIG9mIGRhdGEgdmFsdWVzIGZyb20gdGhpcworICAgICAqIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYnl0ZU9yZGVyCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBvcmRlci4KKyAgICAgKi8KKyAgICB2b2lkIHNldEJ5dGVPcmRlcihCeXRlT3JkZXIgYnl0ZU9yZGVyKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJ5dGUgb3JkZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYnl0ZSBvcmRlci4KKyAgICAgKi8KKyAgICBCeXRlT3JkZXIgZ2V0Qnl0ZU9yZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJ5dGUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb2YgdGhlIHN0cmVhbSwgb3IgLTEgZm9yIEVPRiBpbmRpY2F0aW5nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIG51bWJlciBvZiBieXRlcyB3aGljaCBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIGFycmF5J3MgbGVuZ3RoIGFuZAorICAgICAqIHN0b3JlcyBhIHJlc3VsdCB0byB0aGlzIGFycmF5LgorICAgICAqIAorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcywgb3IgLTEgaW5kaWNhdGVkIEVPRi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgaW50IHJlYWQoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgc3BlY2lmaWVkIGJ5IGxlbiBwYXJhbWV0ZXIgZnJvbSB0aGUgc3RyZWFtIGFuZAorICAgICAqIHN0b3JlcyBhIHJlc3VsdCB0byB0aGUgc3BlY2lmaWVkIGFycmF5IHdpdGggdGhlIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByZWFkIGJ5dGVzLCBvciAtMSBpbmRpY2F0ZWQgRU9GLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG51bWJlciBvZiBieXRlcyBzcGVjaWZpZWQgYnkgbGVuIHBhcmFtZXRlciBmcm9tIHRoZSBzdHJlYW0sIGFuZAorICAgICAqIG1vZGlmaWVzIHRoZSBzcGVjaWZpZWQgSUlPQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlIGFycmF5LCBvZmZzZXQsIGFuZAorICAgICAqIGxlbmd0aC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgSUlPQnl0ZUJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgcmVhZEJ5dGVzKElJT0J5dGVCdWZmZXIgYnVmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJ5dGUgZnJvbSB0aGUgc3RyZWFtIGFuZCByZXR1cm5zIGEgYm9vbGVhbiB0cnVlIHZhbHVlIGlmIGl0IGlzCisgICAgICogbm9uIHplcm8sIGZhbHNlIGlmIGl0IGlzIHplcm8uCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYm9vbGVhbiB2YWx1ZSBmb3IgcmVhZCBieXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBib29sZWFuIHJlYWRCb29sZWFuKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYSBieXRlIGZyb20gdGhlIHN0cmVhbSBhbmQgcmV0dXJucyBpdHMgdmFsdWUgYXMgc2lnbmVkIGJ5dGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc2lnbmVkIGJ5dGUgdmFsdWUgZm9yIHJlYWQgYnl0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgYnl0ZSByZWFkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYnl0ZSBmcm9tIHRoZSBzdHJlYW0gYW5kIHJldHVybnMgaXRzIHZhbHVlIGFzIGFuIGludGVnZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdW5zaWduZWQgYnl0ZSB2YWx1ZSBmb3IgcmVhZCBieXRlIGFzIGFuIGludGVnZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIGludCByZWFkVW5zaWduZWRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgMiBieXRlcyBmcm9tIHRoZSBzdHJlYW0sIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgYXMgYSBzaG9ydC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduZWQgc2hvcnQgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBzaG9ydCByZWFkU2hvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyAyIGJ5dGVzIGZyb20gdGhlIHN0cmVhbSBhbmQgcmV0dXJucyBpdHMgdmFsdWUgYXMgYW4gdW5zaWduZWQgc2hvcnQuCisgICAgICogCisgICAgICogQHJldHVybiBhIHVuc2lnbmVkIHNob3J0IHZhbHVlIGNvZGVkIGluIGFuIGludGVnZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIGludCByZWFkVW5zaWduZWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIDIgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtIGFuZCByZXR1cm5zIHRoZWlyIHVuc2lnbmVkIGNoYXIgdmFsdWUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgdW5zaWduZWQgY2hhciB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgY2hhciByZWFkQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIDQgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLCBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IGFzIGFuIGludGVnZXIuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc2lnbmVkIGludGVnZXIgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBpbnQgcmVhZEludCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIDQgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtIGFuZCByZXR1cm5zIGl0cyB2YWx1ZSBhcyBsb25nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHVuc2lnbmVkIGludGVnZXIgdmFsdWUgYXMgbG9uZy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgbG9uZyByZWFkVW5zaWduZWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyA4IGJ5dGVzIGZyb20gdGhlIHN0cmVhbSwgYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhIGxvbmcuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgbG9uZyB2YWx1ZSBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIGxvbmcgcmVhZExvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyA0IGJ5dGVzIGZyb20gdGhlIHN0cmVhbSwgYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhIGZsb2F0LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IHZhbHVlIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgZmxvYXQgcmVhZEZsb2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgOCBieXRlcyBmcm9tIHRoZSBzdHJlYW0sIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgYXMgYSBkb3VibGUuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgZG91YmxlIHZhbHVlIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgZG91YmxlIHJlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGxpbmUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyBjb250YWluZWQgdGhlIGxpbmUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBieXRlcyBmcm9tIHRoZSBzdHJlYW0gaW4gYSBzdHJpbmcgdGhhdCBoYXMgYmVlbiBlbmNvZGVkIGluIGEKKyAgICAgKiBtb2RpZmllZCBVVEYtOCBmb3JtYXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlYWQgZnJvbSBzdHJlYW0gYW5kIG1vZGlmaWVkIFVURi04IGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgU3RyaW5nIHJlYWRVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0sIGFuZCBzdG9yZXMgdGhlCisgICAgICogcmVzdWx0IGludG8gdGhlIHNwZWNpZmllZCBhcnJheSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mZnNldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtIHdoaWNoIGlzIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhcnJheSdzIGxlbmd0aCwgYW5kIHN0b3JlcyB0aGVtIGludG8gdGhpcyBhcnJheS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzaG9ydHMgZnJvbSB0aGUgc3RyZWFtLCBhbmQgc3RvcmVzIHRoZQorICAgICAqIHJlc3VsdCBpbnRvIHRoZSBzcGVjaWZpZWQgYXJyYXkgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaG9ydCBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2Ygc2hvcnRzIHRvIGJlIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgcmVhZEZ1bGx5KHNob3J0W10gcywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgY2hhcnMgZnJvbSB0aGUgc3RyZWFtLCBhbmQgc3RvcmVzIHRoZQorICAgICAqIHJlc3VsdCBpbnRvIHRoZSBzcGVjaWZpZWQgYXJyYXkgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFycyB0byBiZSByZWFkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHJlYWRGdWxseShjaGFyW10gYywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgaW50ZWdlciBmcm9tIHRoZSBzdHJlYW0sIGFuZCBzdG9yZXMgdGhlCisgICAgICogcmVzdWx0IGludG8gdGhlIHNwZWNpZmllZCBhcnJheSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mZnNldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGludGVnZXIgdG8gYmUgcmVhZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCByZWFkRnVsbHkoaW50W10gaSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbG9uZ3MgZnJvbSB0aGUgc3RyZWFtLCBhbmQgc3RvcmVzIHRoZQorICAgICAqIHJlc3VsdCBpbnRvIHRoZSBzcGVjaWZpZWQgYXJyYXkgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIGFycmF5LgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBsb25ncyB0byBiZSByZWFkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHJlYWRGdWxseShsb25nW10gbCwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZmxvYXRzIGZyb20gdGhlIHN0cmVhbSwgYW5kIHN0b3JlcyB0aGUKKyAgICAgKiByZXN1bHQgaW50byB0aGUgc3BlY2lmaWVkIGFycmF5IHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2Zmc2V0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGZsb2F0cyB0byBiZSByZWFkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHJlYWRGdWxseShmbG9hdFtdIGYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGRvdWJsZXMgZnJvbSB0aGUgc3RyZWFtLCBhbmQgc3RvcmVzIHRoZQorICAgICAqIHJlc3VsdCBpbnRvIHRoZSBzcGVjaWZpZWQgYXJyYXkgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZmZzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRvdWJsZXMgdG8gYmUgcmVhZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCByZWFkRnVsbHkoZG91YmxlW10gZCwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RyZWFtIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHN0cmVhbSBwb3NpdGlvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgbG9uZyBnZXRTdHJlYW1Qb3NpdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGJpdCBvZmZzZXQuCisgICAgICogCisgICAgICogQHJldHVybiB0aGUgYml0IG9mZnNldC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgaW50IGdldEJpdE9mZnNldCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJpdCBvZmZzZXQgdG8gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDcuCisgICAgICogCisgICAgICogQHBhcmFtIGJpdE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGJpdCBvZmZzZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgc2V0Qml0T2Zmc2V0KGludCBiaXRPZmZzZXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYml0IGZyb20gdGhlIHN0cmVhbSBhbmQgcmV0dXJucyB0aGUgdmFsdWUgMCBvciAxLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHNpbmdsZSBiaXQ6IDAgb3IgMS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgaW50IHJlYWRCaXQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJpdHMgYW5kIHJldHVybnMgdGhlaXIgdmFsdWVzIGFzIGxvbmcuCisgICAgICogCisgICAgICogQHBhcmFtIG51bUJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYml0cyB0byBiZSByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGJpdCBzdHJpbmcgYXMgYSBsb25nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBsb25nIHJlYWRCaXRzKGludCBudW1CaXRzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIHN0cmVhbSwgb3IgLTEgaWYgdW5rbm93bi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgbG9uZyBsZW5ndGgoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcyBieSBtb3Zpbmcgc3RyZWFtIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqIEByZXR1cm4gdGhlIGFjdHVhbCBza2lwcGVkIG51bWJlciBvZiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgaW50IHNraXBCeXRlcyhpbnQgbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2tpcHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMgYnkgbW92aW5nIHN0cmVhbSBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgc2tpcHBlZCBudW1iZXIgb2YgYnl0ZXMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIGxvbmcgc2tpcEJ5dGVzKGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBzdHJlYW0gcG9zaXRpb24gdG8gdGhlIHNwZWNpZmllZCBsb2NhdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICBhIGZpbGUgcG9pbnRlciBwb3NpdGlvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCBzZWVrKGxvbmcgcG9zKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNYXJrcyBhIHBvc2l0aW9uIGluIHRoZSBzdHJlYW0gdG8gYmUgcmV0dXJuZWQgdG8gYnkgYSBzdWJzZXF1ZW50IGNhbGwgdG8KKyAgICAgKiByZXNldC4KKyAgICAgKi8KKyAgICB2b2lkIG1hcmsoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpbGUgcG9pbnRlciB0byBpdHMgcHJldmlvdXMgcG9zaXRpb24uCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHRoaXMgc3RyZWFtIHByaW9yIHRvIHRoZSBzcGVjaWZpZWQgc3RyZWFtCisgICAgICogcG9zaXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIHBvcworICAgICAqICAgICAgICAgICAgdGhlIHBvc2l0aW9uLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIGZsdXNoQmVmb3JlKGxvbmcgcG9zKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHRoaXMgc3RyZWFtIHByaW9yIHRvIHRoZSBjdXJyZW50IHN0cmVhbQorICAgICAqIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmx1c2hlZCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBmbHVzaGVkIHBvc2l0aW9uLgorICAgICAqLworICAgIGxvbmcgZ2V0Rmx1c2hlZFBvc2l0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBJbWFnZUlucHV0U3RyZWFtIGNhY2hlcyBkYXRhIGluIG9yZGVyIHRvIGFsbG93CisgICAgICogc2Vla2luZyBiYWNrd2FyZHMuCisgICAgICogCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIEltYWdlSW5wdXRTdHJlYW0gY2FjaGVzIGRhdGEgaW4gb3JkZXIgdG8gYWxsb3cKKyAgICAgKiAgICAgICAgIHNlZWtpbmcgYmFja3dhcmRzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgYm9vbGVhbiBpc0NhY2hlZCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgSW1hZ2VJbnB1dFN0cmVhbSBjYWNoZXMgZGF0YSBpbiBvcmRlciB0byBhbGxvdworICAgICAqIHNlZWtpbmcgYmFja3dhcmRzLCBhbmQga2VlcHMgaXQgaW4gbWVtb3J5LgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBJbWFnZUlucHV0U3RyZWFtIGNhY2hlcyBkYXRhIGluIG9yZGVyIHRvIGFsbG93CisgICAgICogICAgICAgICBzZWVraW5nIGJhY2t3YXJkcywgYW5kIGtlZXBzIGl0IGluIG1lbW9yeS4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzQ2FjaGVkTWVtb3J5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBJbWFnZUlucHV0U3RyZWFtIGNhY2hlcyBkYXRhIGluIG9yZGVyIHRvIGFsbG93CisgICAgICogc2Vla2luZyBiYWNrd2FyZHMsIGFuZCBrZWVwcyBpdCBpbiBhIHRlbXBvcmFyeSBmaWxlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBJbWFnZUlucHV0U3RyZWFtIGNhY2hlcyBkYXRhIGluIG9yZGVyIHRvIGFsbG93CisgICAgICogICAgICAgICBzZWVraW5nIGJhY2t3YXJkcywgYW5kIGtlZXBzIGl0IGluIGEgdGVtcG9yYXJ5IGZpbGUuCisgICAgICovCisgICAgYm9vbGVhbiBpc0NhY2hlZEZpbGUoKTsKKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZUlucHV0U3RyZWFtSW1wbC5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0ltYWdlSW5wdXRTdHJlYW1JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc5ZGE0MQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZUlucHV0U3RyZWFtSW1wbC5qYXZhCkBAIC0wLDAgKzEsNDE4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworCisvKioKKyAqIFRoZSBJbWFnZUlucHV0U3RyZWFtSW1wbCBhYnN0cmFjdCBjbGFzcyBpbXBsZW1lbnRzIHRoZSBJbWFnZUlucHV0U3RyZWFtCisgKiBpbnRlcmZhY2UuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSW1hZ2VJbnB1dFN0cmVhbUltcGwgaW1wbGVtZW50cyBJbWFnZUlucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBieXRlIG9yZGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBCeXRlT3JkZXIgYnl0ZU9yZGVyID0gQnl0ZU9yZGVyLkJJR19FTkRJQU47CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RyZWFtIHBvc2l0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIHN0cmVhbVBvcyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZmx1c2hlZCBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgbG9uZyBmbHVzaGVkUG9zID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBiaXQgb2Zmc2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYml0T2Zmc2V0ID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBjbG9zZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogVGhlIHBvc2l0aW9uIHN0YWNrLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgUG9zaXRpb25TdGFjayBwb3NTdGFjayA9IG5ldyBQb3NpdGlvblN0YWNrKCk7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW50aWF0ZXMgYSBuZXcgSW1hZ2VJbnB1dFN0cmVhbUltcGwuCisgICAgICovCisgICAgcHVibGljIEltYWdlSW5wdXRTdHJlYW1JbXBsKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkIGFuZCBpZiB0cnVlLCB0aHJvd3MgYW4gSU9FeGNlcHRpb24uCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNoZWNrQ2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJzdHJlYW0gaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlT3JkZXIoQnl0ZU9yZGVyIGJ5dGVPcmRlcikgeworICAgICAgICB0aGlzLmJ5dGVPcmRlciA9IGJ5dGVPcmRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZU9yZGVyIGdldEJ5dGVPcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVPcmRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIHB1YmxpYyB2b2lkIHJlYWRCeXRlcyhJSU9CeXRlQnVmZmVyIGJ1ZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImJ1ZmZlciBpcyBOVUxMIik7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlW2xlbl07CisgICAgICAgIGxlbiA9IHJlYWQoYiwgMCwgYi5sZW5ndGgpOworCisgICAgICAgIGJ1Zi5zZXREYXRhKGIpOworICAgICAgICBidWYuc2V0T2Zmc2V0KDApOworICAgICAgICBidWYuc2V0TGVuZ3RoKGxlbik7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gcmVhZEJvb2xlYW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYiA9IHJlYWQoKTsKKyAgICAgICAgaWYgKGIgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCJFT0YgcmVhY2hlZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiICE9IDA7CisgICAgfQorCisgICAgcHVibGljIGJ5dGUgcmVhZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYiA9IHJlYWQoKTsKKyAgICAgICAgaWYgKGIgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCJFT0YgcmVhY2hlZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoYnl0ZSliOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVhZFVuc2lnbmVkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBiID0gcmVhZCgpOworICAgICAgICBpZiAoYiA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oIkVPRiByZWFjaGVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGI7CisgICAgfQorCisgICAgcHVibGljIHNob3J0IHJlYWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBiMSA9IHJlYWQoKTsKKyAgICAgICAgaW50IGIyID0gcmVhZCgpOworCisgICAgICAgIGlmIChiMSA8IDAgfHwgYjIgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCJFT0YgcmVhY2hlZCIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJ5dGVPcmRlciA9PSBCeXRlT3JkZXIuQklHX0VORElBTiA/IChzaG9ydCkoKGIxIDw8IDgpIHwgKGIyICYgMHhmZikpCisgICAgICAgICAgICAgICAgOiAoc2hvcnQpKChiMiA8PCA4KSB8IChiMSAmIDB4ZmYpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHJlYWRVbnNpZ25lZFNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIGNoYXIgcmVhZENoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHJlYWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyByZWFkVW5zaWduZWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyByZWFkTG9uZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdCByZWFkRmxvYXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZG91YmxlIHJlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyByZWFkVVRGKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRnVsbHkoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGdWxseShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KHNob3J0W10gcywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KGNoYXJbXSBjLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRnVsbHkoaW50W10gaSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KGxvbmdbXSBsLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRnVsbHkoZmxvYXRbXSBmLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRnVsbHkoZG91YmxlW10gZCwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0U3RyZWFtUG9zaXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICByZXR1cm4gc3RyZWFtUG9zOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Qml0T2Zmc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgcmV0dXJuIGJpdE9mZnNldDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRCaXRPZmZzZXQoaW50IGJpdE9mZnNldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgdGhpcy5iaXRPZmZzZXQgPSBiaXRPZmZzZXQ7CisgICAgfQorCisgICAgcHVibGljIGludCByZWFkQml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgcmVhZEJpdHMoaW50IG51bUJpdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIC0xTDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNraXBCeXRlcyhpbnQgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgc2tpcEJ5dGVzKGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2Vlayhsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgaWYgKHBvcyA8IGdldEZsdXNoZWRQb3NpdGlvbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0cnlpbmcgdG8gc2VlayBiZWZvcmUgZmx1c2hlZCBwb3MiKTsKKyAgICAgICAgfQorICAgICAgICBiaXRPZmZzZXQgPSAwOworICAgICAgICBzdHJlYW1Qb3MgPSBwb3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbWFyaygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBvc1N0YWNrLnB1c2goZ2V0U3RyZWFtUG9zaXRpb24oKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiU3RyZWFtIG1hcmtpbmcgZXJyb3IiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBiaXQgcG9zCisgICAgICAgIGlmICghcG9zU3RhY2suaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBsb25nIHAgPSBwb3NTdGFjay5wb3AoKTsKKyAgICAgICAgICAgIGlmIChwIDwgZmx1c2hlZFBvcykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibWFya2VkIHBvc2l0aW9uIGxpZXMgaW4gdGhlIGZsdXNoZWQgcG9ydGlvbiBvZiB0aGUgc3RyZWFtIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZWVrKHApOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZmx1c2hCZWZvcmUobG9uZyBwb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwb3MgPiBnZXRTdHJlYW1Qb3NpdGlvbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiVHJ5aW5nIHRvIGZsdXNoIG91dHNpZGUgb2YgY3VycmVudCBwb3NpdGlvbiIpOworICAgICAgICB9CisgICAgICAgIGlmIChwb3MgPCBmbHVzaGVkUG9zKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiVHJ5aW5nIHRvIGZsdXNoIHdpdGhpbiBhbHJlYWR5IGZsdXNoZWQgcG9ydGlvbiIpOworICAgICAgICB9CisgICAgICAgIGZsdXNoZWRQb3MgPSBwb3M7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmbHVzaEJlZm9yZShnZXRTdHJlYW1Qb3NpdGlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRGbHVzaGVkUG9zaXRpb24oKSB7CisgICAgICAgIHJldHVybiBmbHVzaGVkUG9zOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGRlZgorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkTWVtb3J5KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGRlZgorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBkZWYKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIGNsb3NlZCA9IHRydWU7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5hbGl6ZXMgdGhpcyBvYmplY3QuCisgICAgICogCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBDbGFzcyBQb3NpdGlvblN0YWNrLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBvc2l0aW9uU3RhY2sgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgQ29uc3RhbnQgU0laRS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTSVpFID0gMTA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB2YWx1ZXMuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGxvbmdbXSB2YWx1ZXMgPSBuZXcgbG9uZ1tTSVpFXTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBvcy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IHBvcyA9IDA7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFB1c2guCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gdgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBwdXNoKGxvbmcgdikgeworICAgICAgICAgICAgaWYgKHBvcyA+PSB2YWx1ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgZW5zdXJlKHBvcyArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdmFsdWVzW3BvcysrXSA9IHY7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUG9wLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0aGUgbG9uZy4KKyAgICAgICAgICovCisgICAgICAgIGxvbmcgcG9wKCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1stLXBvc107CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2tzIGlmIGlzIGVtcHR5LgorICAgICAgICAgKiAKKyAgICAgICAgICogQHJldHVybiB0cnVlLCBpZiBpcyBlbXB0eS4KKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3MgPT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBFbnN1cmUuCisgICAgICAgICAqIAorICAgICAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzaXplLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZShpbnQgc2l6ZSkgeworICAgICAgICAgICAgbG9uZ1tdIGFyciA9IG5ldyBsb25nW01hdGgubWF4KDIgKiB2YWx1ZXMubGVuZ3RoLCBzaXplKV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlcywgMCwgYXJyLCAwLCB2YWx1ZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIHZhbHVlcyA9IGFycjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZU91dHB1dFN0cmVhbS5qYXZhIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0ltYWdlT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhlYzkzMgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZU91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMzA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBJbWFnZU91dHB1dFN0cmVhbSByZXByZXNlbnRzIG91dHB1dCBzdHJlYW0gaW50ZXJmYWNlIHRoYXQgaXMgdXNlZCBieQorICogSW1hZ2VXcml0ZXJzLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGludGVyZmFjZSBJbWFnZU91dHB1dFN0cmVhbSBleHRlbmRzIERhdGFPdXRwdXQsIEltYWdlSW5wdXRTdHJlYW0geworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc2luZ2xlIGJ5dGUgdG8gdGhlIHN0cmVhbSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUsIG9mIHdoaWNoIHRoZSA4IGxvd2VzdCBiaXRzIHdpbGwgYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBieXRlcyBhcnJheSB0byB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGJ5dGUgYXJyYXkgYmVnaW5uaW5nIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIGJvb2xlYW4gdmFsdWUgdG8gdGhlIHN0cmVhbSwgMSBpZiBpdCBpcyB0cnVlLCAwIGlmCisgICAgICogaXQgaXMgZmFsc2UuCisgICAgICogCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIHZhbHVlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgd3JpdGVCb29sZWFuKGJvb2xlYW4gYikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSA4IGxvd2VzdCBiaXRzIG9mIHRoZSBzcGVjaWZpZWQgaW50ZWdlciB2YWx1ZSB0byB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGludGVnZXIgdmFsdWUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgd3JpdGVCeXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzaG9ydCB2YWx1ZSB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIHNob3J0IHZhbHVlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgd3JpdGVTaG9ydChpbnQgdikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSAxNiBsb3dlc3QgYml0cyBvZiB0aGUgc3BlY2lmaWVkIGludGVnZXIgdmFsdWUgdG8gdGhlIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIHZhbHVlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlQ2hhcihpbnQgdikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIGludGVnZXIgdmFsdWUgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gaGFzIG9jY3VycmVkLgorICAgICAqLworICAgIHZvaWQgd3JpdGVJbnQoaW50IHYpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGxvbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHZhbHVlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlTG9uZyhsb25nIHYpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGZsb2F0IHZhbHVlIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSB2CisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgd2hpY2ggY29udGFpbnMgdmFsdWUgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZUZsb2F0KGZsb2F0IHYpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGRvdWJsZSB2YWx1ZSB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB3aGljaCBjb250YWlucyB2YWx1ZSB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlRG91YmxlKGRvdWJsZSB2KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhlIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlQnl0ZXMoU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIFN0cmluZyB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlQ2hhcnMoU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyAyIGJ5dGVzIHRvIHRoZSBvdXRwdXQgc3RyZWFtIGluIHRoZSBtb2RpZmllZCBVVEYtOCByZXByZXNlbnRhdGlvbgorICAgICAqIG9mIGV2ZXJ5IGNoYXJhY3RlciBvZiB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZVVURihTdHJpbmcgcykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB0aGlzIHN0cmVhbSBwcmlvciB0byB0aGUgc3BlY2lmaWVkIHN0cmVhbQorICAgICAqIHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCBmbHVzaEJlZm9yZShsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbGVuIG51bWJlciBvZiBzaG9ydCB2YWx1ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGFycmF5IHRvIHRoZQorICAgICAqIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNob3J0cyBhcnJheSB0byBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiBjaGFycyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlU2hvcnRzKHNob3J0W10gcywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbGVuIG51bWJlciBvZiBjaGFycyB0byB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhciBhcnJheSB0byBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiBjaGFycyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlQ2hhcnMoY2hhcltdIGMsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGxlbiBudW1iZXIgb2YgaW50ZWdlciB2YWx1ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGFycmF5IHRvIHRoZQorICAgICAqIHN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgYXJyYXkgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBjaGFyIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgY2hhcnMgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZUludHMoaW50W10gaSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbGVuIG51bWJlciBvZiBsb25nIHZhbHVlcyBmcm9tIHRoZSBzcGVjaWZpZWQgYXJyYXkgdG8gdGhlCisgICAgICogc3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyBhcnJheSB0byBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiBjaGFycyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlTG9uZ3MobG9uZ1tdIGwsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGxlbiBudW1iZXIgb2YgZmxvYXQgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBhcnJheSB0byB0aGUKKyAgICAgKiBzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCBhcnJheSB0byBiZSB3cml0dGVuLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiBjaGFycyB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlRmxvYXRzKGZsb2F0W10gZiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbGVuIG51bWJlciBvZiBkb3VibGUgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBhcnJheSB0byB0aGUKKyAgICAgKiBzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgYXJyYXkgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBjaGFyIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgY2hhcnMgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZURvdWJsZXMoZG91YmxlW10gZCwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc2luZ2xlIGJpdCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYml0CisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB3aG9zZSBsZWFzdCBzaWduaWZpY2FudCBiaXQgaXMgdG8gYmUgd3JpdHRlbiB0bworICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgdm9pZCB3cml0ZUJpdChpbnQgYml0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzZXF1ZW5jZSBvZiBiaXRzIGJlZ2lubmluZyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiaXRzCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSBjb250YWluaW5nIHRoZSBiaXRzIHRvIGJlIHdyaXR0ZW4sIHN0YXJ0aW5nCisgICAgICogICAgICAgICAgICB3aXRoIHRoZSBiaXQgaW4gcG9zaXRpb24gbnVtQml0cyAtIDEgZG93biB0byB0aGUgbGVhc3QKKyAgICAgKiAgICAgICAgICAgIHNpZ25pZmljYW50IGJpdC4KKyAgICAgKiBAcGFyYW0gbnVtQml0cworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBiaXQsIGl0IGNhbiBiZSBiZXR3ZWVuIDAgYW5kIDY0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlQml0cyhsb25nIGJpdHMsIGludCBudW1CaXRzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKK30KZGlmZiAtLWdpdCBhL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZU91dHB1dFN0cmVhbUltcGwuamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9JbWFnZU91dHB1dFN0cmVhbUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZmVmNzhmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL0ltYWdlT3V0cHV0U3RyZWFtSW1wbC5qYXZhCkBAIC0wLDAgKzEsMTc0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMyAkCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworCisvKiAKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworCisvKioKKyAqIFRoZSBJbWFnZU91dHB1dFN0cmVhbUltcGwgYWJzdHJhY3QgY2xhc3MgaW1wbGVtZW50cyB0aGUgSW1hZ2VPdXRwdXRTdHJlYW0KKyAqIGludGVyZmFjZS4KKyAqIAorICogQHNpbmNlIEFuZHJvaWQgMS4wCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJbWFnZU91dHB1dFN0cmVhbUltcGwgZXh0ZW5kcyBJbWFnZUlucHV0U3RyZWFtSW1wbCBpbXBsZW1lbnRzCisgICAgICAgIEltYWdlT3V0cHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBJbWFnZU91dHB1dFN0cmVhbUltcGwuCisgICAgICovCisgICAgcHVibGljIEltYWdlT3V0cHV0U3RyZWFtSW1wbCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgcHVibGljIHZvaWQgd3JpdGVCb29sZWFuKGJvb2xlYW4gdikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUodiA/IDEgOiAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJ5dGUoaW50IHYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKHYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlU2hvcnQoaW50IHYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlT3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKworICAgICAgICB9IGVsc2UgeworCisgICAgICAgIH0KKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVDaGFyKGludCB2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZVNob3J0KHYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlSW50KGludCB2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnl0ZU9yZGVyID09IEJ5dGVPcmRlci5CSUdfRU5ESUFOKSB7CisKKyAgICAgICAgfSBlbHNlIHsKKworICAgICAgICB9CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlTG9uZyhsb25nIHYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlT3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKworICAgICAgICB9IGVsc2UgeworCisgICAgICAgIH0KKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVGbG9hdChmbG9hdCB2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZUludChGbG9hdC5mbG9hdFRvSW50Qml0cyh2KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVEb3VibGUoZG91YmxlIHYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlTG9uZyhEb3VibGUuZG91YmxlVG9Mb25nQml0cyh2KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVCeXRlcyhTdHJpbmcgcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUocy5nZXRCeXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUNoYXJzKFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gY2hzID0gcy50b0NoYXJBcnJheSgpOworICAgICAgICB3cml0ZUNoYXJzKGNocywgMCwgY2hzLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVVVEYoU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlU2hvcnRzKHNob3J0W10gcywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVDaGFycyhjaGFyW10gYywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVJbnRzKGludFtdIGksIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlTG9uZ3MobG9uZ1tdIGwsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlRmxvYXRzKGZsb2F0W10gZiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gLS0gVE9ETyBpbXBsZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVEb3VibGVzKGRvdWJsZVtdIGQsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlQml0KGludCBiaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIC0tIFRPRE8gaW1wbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlQml0cyhsb25nIGJpdHMsIGludCBudW1CaXRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSBiaXRzLiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIGluIHRoZSB3cml0ZSBtZXRob2RzIGJ5CisgICAgICogc3ViY2xhc3Nlcy4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZmx1c2hCaXRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJpdE9mZnNldCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyAtLSBUT0RPIGltcGxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vTWVtb3J5Q2FjaGVJbWFnZUlucHV0U3RyZWFtLmphdmEgYi9hd3QvamF2YXgvaW1hZ2Vpby9zdHJlYW0vTWVtb3J5Q2FjaGVJbWFnZUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdmYzc5MQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9NZW1vcnlDYWNoZUltYWdlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3RyZWFtLlJhbmRvbUFjY2Vzc01lbW9yeUNhY2hlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFRoZSBNZW1vcnlDYWNoZUltYWdlSW5wdXRTdHJlYW0gY2xhc3MgaW1wbGVtZW50cyBJbWFnZUlucHV0U3RyZWFtIHVzaW5nIGEKKyAqIG1lbW9yeSBidWZmZXIgZm9yIGNhY2hpbmcgdGhlIGRhdGEuCisgKiAKKyAqIEBzaW5jZSBBbmRyb2lkIDEuMAorICovCitwdWJsaWMgY2xhc3MgTWVtb3J5Q2FjaGVJbWFnZUlucHV0U3RyZWFtIGV4dGVuZHMgSW1hZ2VJbnB1dFN0cmVhbUltcGwgeworCisgICAgLyoqCisgICAgICogVGhlIGlzLgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaXM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmFtYy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJhbmRvbUFjY2Vzc01lbW9yeUNhY2hlIHJhbWMgPSBuZXcgUmFuZG9tQWNjZXNzTWVtb3J5Q2FjaGUoKTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBNZW1vcnlDYWNoZUltYWdlSW5wdXRTdHJlYW0gd2hpY2ggcmVhZHMgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgSW5wdXRTdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIElucHV0U3RyZWFtIHRvIGJlIHJlYWQuCisgICAgICovCisgICAgcHVibGljIE1lbW9yeUNhY2hlSW1hZ2VJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBzdHJlYW0pIHsKKyAgICAgICAgaWYgKHN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzdHJlYW0gPT0gbnVsbCEiKTsKKyAgICAgICAgfQorICAgICAgICBpcyA9IHN0cmVhbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiaXRPZmZzZXQgPSAwOworCisgICAgICAgIGlmIChzdHJlYW1Qb3MgPj0gcmFtYy5sZW5ndGgoKSkgeworICAgICAgICAgICAgaW50IGNvdW50ID0gKGludCkoc3RyZWFtUG9zIC0gcmFtYy5sZW5ndGgoKSArIDEpOworICAgICAgICAgICAgaW50IGJ5dGVzQXBwZW5kZWQgPSByYW1jLmFwcGVuZERhdGEoaXMsIGNvdW50KTsKKworICAgICAgICAgICAgaWYgKGJ5dGVzQXBwZW5kZWQgPCBjb3VudCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCByZXMgPSByYW1jLmdldERhdGEoc3RyZWFtUG9zKTsKKyAgICAgICAgaWYgKHJlcyA+PSAwKSB7CisgICAgICAgICAgICBzdHJlYW1Qb3MrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYml0T2Zmc2V0ID0gMDsKKworICAgICAgICBpZiAoc3RyZWFtUG9zID49IHJhbWMubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIGludCBjb3VudCA9IChpbnQpKHN0cmVhbVBvcyAtIHJhbWMubGVuZ3RoKCkgKyBsZW4pOworICAgICAgICAgICAgcmFtYy5hcHBlbmREYXRhKGlzLCBjb3VudCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmVzID0gcmFtYy5nZXREYXRhKGIsIG9mZiwgbGVuLCBzdHJlYW1Qb3MpOworICAgICAgICBpZiAocmVzID4gMCkgeworICAgICAgICAgICAgc3RyZWFtUG9zICs9IHJlczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NhY2hlZEZpbGUoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NhY2hlZE1lbW9yeSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICByYW1jLmNsb3NlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2hCZWZvcmUobG9uZyBwb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmZsdXNoQmVmb3JlKHBvcyk7CisgICAgICAgIHJhbWMuZnJlZUJlZm9yZShnZXRGbHVzaGVkUG9zaXRpb24oKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL01lbW9yeUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0uamF2YSBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9NZW1vcnlDYWNoZUltYWdlT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWRmNDBhMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9NZW1vcnlDYWNoZUltYWdlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguaW1hZ2Vpby5zdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnN0cmVhbS5SYW5kb21BY2Nlc3NNZW1vcnlDYWNoZTsKKworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhlIE1lbW9yeUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0gY2xhc3MgaW1wbGVtZW50cyBJbWFnZU91dHB1dFN0cmVhbSB1c2luZyBhCisgKiBtZW1vcnkgYnVmZmVyIGZvciBjYWNoaW5nIHRoZSBkYXRhLgorICogCisgKiBAc2luY2UgQW5kcm9pZCAxLjAKKyAqLworcHVibGljIGNsYXNzIE1lbW9yeUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0gZXh0ZW5kcyBJbWFnZU91dHB1dFN0cmVhbUltcGwgeworCisgICAgLyoqCisgICAgICogVGhlIG9zLgorICAgICAqLworICAgIE91dHB1dFN0cmVhbSBvczsKKworICAgIC8qKgorICAgICAqIFRoZSByYW1jLgorICAgICAqLworICAgIFJhbmRvbUFjY2Vzc01lbW9yeUNhY2hlIHJhbWMgPSBuZXcgUmFuZG9tQWNjZXNzTWVtb3J5Q2FjaGUoKTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIG5ldyBNZW1vcnlDYWNoZUltYWdlT3V0cHV0U3RyZWFtIHdoaWNoIHdyaXRlcyB0byB0aGUKKyAgICAgKiBzcGVjaWZpZWQgT3V0cHV0U3RyZWFtLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBPdXRwdXRTdHJlYW0uCisgICAgICovCisgICAgcHVibGljIE1lbW9yeUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHN0cmVhbSkgeworICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0cmVhbSA9PSBudWxsISIpOworICAgICAgICB9CisgICAgICAgIG9zID0gc3RyZWFtOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmbHVzaEJpdHMoKTsgLy8gU2VlIHRoZSBmbHVzaEJpdHMgbWV0aG9kIGRlc2NyaXB0aW9uCisKKyAgICAgICAgcmFtYy5wdXREYXRhKGIsIHN0cmVhbVBvcyk7CisgICAgICAgIHN0cmVhbVBvcysrOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmbHVzaEJpdHMoKTsgLy8gU2VlIHRoZSBmbHVzaEJpdHMgbWV0aG9kIGRlc2NyaXB0aW9uCisKKyAgICAgICAgcmFtYy5wdXREYXRhKGIsIG9mZiwgbGVuLCBzdHJlYW1Qb3MpOworICAgICAgICBzdHJlYW1Qb3MgKz0gbGVuOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJpdE9mZnNldCA9IDA7CisKKyAgICAgICAgaW50IHJlcyA9IHJhbWMuZ2V0RGF0YShzdHJlYW1Qb3MpOworICAgICAgICBpZiAocmVzID49IDApIHsKKyAgICAgICAgICAgIHN0cmVhbVBvcysrOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiaXRPZmZzZXQgPSAwOworCisgICAgICAgIGludCByZXMgPSByYW1jLmdldERhdGEoYiwgb2ZmLCBsZW4sIHN0cmVhbVBvcyk7CisgICAgICAgIGlmIChyZXMgPiAwKSB7CisgICAgICAgICAgICBzdHJlYW1Qb3MgKz0gcmVzOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gcmFtYy5sZW5ndGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NhY2hlZCgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWRNZW1vcnkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ2FjaGVkRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmx1c2hCZWZvcmUobGVuZ3RoKCkpOworICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICByYW1jLmNsb3NlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2hCZWZvcmUobG9uZyBwb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgZmx1c2hlZFBvc2l0aW9uID0gZ2V0Rmx1c2hlZFBvc2l0aW9uKCk7CisgICAgICAgIHN1cGVyLmZsdXNoQmVmb3JlKHBvcyk7CisKKyAgICAgICAgbG9uZyBuZXdGbHVzaGVkUG9zaXRpb24gPSBnZXRGbHVzaGVkUG9zaXRpb24oKTsKKyAgICAgICAgaW50IG5CeXRlcyA9IChpbnQpKG5ld0ZsdXNoZWRQb3NpdGlvbiAtIGZsdXNoZWRQb3NpdGlvbik7CisKKyAgICAgICAgcmFtYy5nZXREYXRhKG9zLCBuQnl0ZXMsIGZsdXNoZWRQb3NpdGlvbik7CisgICAgICAgIHJhbWMuZnJlZUJlZm9yZShuZXdGbHVzaGVkUG9zaXRpb24pOworCisgICAgICAgIG9zLmZsdXNoKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L2phdmF4L2ltYWdlaW8vc3RyZWFtL3BhY2thZ2UuaHRtbCBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNmNTNjMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9qYXZheC9pbWFnZWlvL3N0cmVhbS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw4IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBUaGlzIHBhY2thZ2UgY29udGFpbnMgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyBmb3IgaGFuZGxpbmcgaW1hZ2VzIHdpdGggbG93LWxldmVsIEkvTyBvcGVyYXRpb25zLiAKKyAgICA8L3A+CisgIEBzaW5jZSBBbmRyb2lkIDEuMAorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9DaG9pY2VTdHlsZS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvQ2hvaWNlU3R5bGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2I3YWFkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvQ2hvaWNlU3R5bGUuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0OworCisvKioKKyAqIENob2ljZVN0eWxlLgorICogSXMgdXNlZCB0byBkZWZpbmUgY3VzdG9tIGNob2ljZSBwcm9wZXJ0aWVzOgorICogd2lkdGggYW5kIHggc2NyZWVuIGNvb3JkaW5hdGUgb2YgdGhlIGxpc3QgcG9wdXAgd2luZG93LiAKKyAqLworcHVibGljIGludGVyZmFjZSBDaG9pY2VTdHlsZSB7CisKKyAgICBpbnQgZ2V0UG9wdXBYKGludCB4LCBpbnQgd2lkdGgsIGludCBjaG9pY2VXaWR0aCwgaW50IHNjcmVlbldpZHRoKTsKKyAgICBpbnQgZ2V0UG9wdXBXaWR0aChpbnQgY2hvaWNlV2lkdGgpOworCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9DbGlwUmVnaW9uLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9DbGlwUmVnaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzg5YTgxZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L0NsaXBSZWdpb24uamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdiwgQW50b24gQXZ0YW1vbm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLk11bHRpUmVjdEFyZWE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKK3B1YmxpYyBjbGFzcyBDbGlwUmVnaW9uIGV4dGVuZHMgUmVjdGFuZ2xlIHsKKyAgICBwcml2YXRlIGZpbmFsIE11bHRpUmVjdEFyZWEgY2xpcDsKKworICAgIHB1YmxpYyBDbGlwUmVnaW9uKGZpbmFsIE11bHRpUmVjdEFyZWEgY2xpcCkgeworICAgICAgICB0aGlzLmNsaXAgPSBuZXcgTXVsdGlSZWN0QXJlYShjbGlwKTsKKyAgICAgICAgc2V0Qm91bmRzKGNsaXAuZ2V0Qm91bmRzKCkpOworICAgIH0KKworICAgIHB1YmxpYyBNdWx0aVJlY3RBcmVhIGdldENsaXAoKSB7CisgICAgICAgIHJldHVybiBjbGlwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBzdHIgPSBjbGlwLnRvU3RyaW5nKCk7CisgICAgICAgIGludCBpID0gc3RyLmluZGV4T2YoJ1snKTsKKyAgICAgICAgc3RyID0gc3RyLnN1YnN0cmluZyhpKTsKKyAgICAgICAgaWYgKGNsaXAuZ2V0UmVjdENvdW50KCkgPT0gMSkgeworICAgICAgICAgICAgc3RyID0gc3RyLnN1YnN0cmluZygxLCBzdHIubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyBzdHI7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBjb252ZXJ0UmVnaW9uKGZpbmFsIENvbXBvbmVudCBjaGlsZCwgZmluYWwgQ29tcG9uZW50IHBhcmVudCkgeworICAgICAgICBjb252ZXJ0UmVnaW9uKGNoaWxkLCBjbGlwLCBwYXJlbnQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGludGVyc2VjdChmaW5hbCBSZWN0YW5nbGUgcmVjdCkgeworICAgICAgICBjbGlwLmludGVyc2VjdChyZWN0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gY2xpcC5pc0VtcHR5KCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNvbnZlcnRSZWdpb24oZmluYWwgQ29tcG9uZW50IGNoaWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE11bHRpUmVjdEFyZWEgcmVnaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIENvbXBvbmVudCBwYXJlbnQpIHsKKyAgICAgICAgaW50IHggPSAwLCB5ID0gMDsKKyAgICAgICAgQ29tcG9uZW50IGMgPSBjaGlsZDsKKyAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgZm9yICg7IGMgIT0gbnVsbCAmJiBjICE9IHBhcmVudDsgYyA9IGMuZ2V0UGFyZW50KCkpIHsKKyAgICAgICAgICAgIHggKz0gYy5nZXRYKCk7CisgICAgICAgICAgICB5ICs9IGMuZ2V0WSgpOworICAgICAgICB9CisgICAgICAgICovCisgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGF3dC41MT1Db21wb25lbnQgZXhwZWN0ZWQgdG8gYmUgYSBwYXJlbnQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNTEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZWdpb24udHJhbnNsYXRlKHgsIHkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L0NvbXBvbmVudEludGVybmFscy5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvQ29tcG9uZW50SW50ZXJuYWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzM1OTc4NAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L0NvbXBvbmVudEludGVybmFscy5qYXZhCkBAIC0wLDAgKzEsMjEyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Q7CisKKy8vPz8/QVdUCisvL2ltcG9ydCBqYXZhLmF3dC5Db21wb25lbnQ7CisvL2ltcG9ydCBqYXZhLmF3dC5Db250YWluZXI7CisvL2ltcG9ydCBqYXZhLmF3dC5EaWFsb2c7CitpbXBvcnQgamF2YS5hd3QuRGltZW5zaW9uOworLy9pbXBvcnQgamF2YS5hd3QuSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuSW5zZXRzOworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKKy8vaW1wb3J0IGphdmEuYXd0LldpbmRvdzsKKy8vaW1wb3J0IGphdmEuYXd0LkNob2ljZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworLy9pbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC50ZXh0LlRleHRGaWVsZEtpdDsKKy8vaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QudGV4dC5UZXh0S2l0OworLy9pbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlV2luZG93OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Ob3RJbXBsZW1lbnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiAgVGhlIGFjY2Vzc29yIHRvIEFXVCBwcml2YXRlIEFQSQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29tcG9uZW50SW50ZXJuYWxzIHsKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIENvbXBvbmVudEludGVybmFscyBpbnN0YW5jZSB0byBzZXJ2ZSB0aGUgcmVxdWVzdHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENvbXBvbmVudEludGVybmFscyBnZXRDb21wb25lbnRJbnRlcm5hbHMoKSB7CisgICAgICAgIHJldHVybiBDb250ZXh0U3RvcmFnZS5nZXRDb21wb25lbnRJbnRlcm5hbHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBieSBBV1QgdG8gZXN0YWJsaXNoIHRoZSBjb25uZWN0aW9uCisgICAgICogQHBhcmFtIGludGVybmFscyAtIGltcGxlbWVudGF0aW9uIG9mIENvbXBvbmVudEludGVybmFscyBjcmVhdGVkIGJ5IEFXVAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRDb21wb25lbnRJbnRlcm5hbHMoQ29tcG9uZW50SW50ZXJuYWxzIGludGVybmFscykgeworICAgICAgICBDb250ZXh0U3RvcmFnZS5zZXRDb21wb25lbnRJbnRlcm5hbHMoaW50ZXJuYWxzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWNjZXNzb3IgdG8gbmF0aXZlIHJlc291cmNlIGNvbm5lY3RlZCB0byBhIGNvbXBvbmVudC4KKyAgICAgKiBJdCByZXR1cm5zIG5vbi08Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBvbmx5IGlmIGNvbXBvbmVudAorICAgICAqIGFscmVhZHkgaGFzIHRoZSBuYXRpdmUgcmVzb3VyY2UKKyAgICAgKi8KKyAgICAvL3B1YmxpYyBhYnN0cmFjdCBOYXRpdmVXaW5kb3cgZ2V0TmF0aXZlV2luZG93KENvbXBvbmVudCBjb21wb25lbnQpOworCisgICAgLyoqCisgICAgICogQ29ubmVjdCBXaW5kb3cgb2JqZWN0IHRvIGV4aXN0aW5nIG5hdGl2ZSByZXNvdXJjZQorICAgICAqIEBwYXJhbSBuYXRpdmVXaW5kb3dJZCAtIGlkIG9mIG5hdGl2ZSB3aW5kb3cgdG8gYXR0YWNoCisgICAgICogQHJldHVybiBXaW5kb3cgb2JqZWN0IHdpdGggc3BlY2lhbCBiZWhhdmlvdXIgdGhhdAorICAgICAqIHJlc3RyaWN0cyBtYW51cHVsYXRpb24gd2l0aCB0aGF0IHdpbmRvdworICAgICAqLworICAgIC8vcHVibGljIGFic3RyYWN0IFdpbmRvdyBhdHRhY2hOYXRpdmVXaW5kb3cobG9uZyBuYXRpdmVXaW5kb3dJZCk7CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBtb3VzZSBncmFiIGluICJjbGllbnQiIG1vZGUuCisgICAgICogQWxsIG1vdXNlIGV2ZW50cyBpbiBBV1QgY29tcG9uZW50cyB3aWxsIGJlIHJlcG9ydGVkIGFzIHVzdWFsLAorICAgICAqIG1vdXNlIGV2ZW50cyB0aGF0IG9jY3VyZWQgb3V0c2lkZSBvZiBBV1QgY29tcG9uZW50cyB3aWxsIGJlIHNlbnQgdG8KKyAgICAgKiB0aGUgd2luZG93IHBhc3NlZCBhcyBncmFiV2luZG93IHBhcmFtZXRlci4gV2hlbiBtb3VzZSBncmFiIGlzIGNhbmNlbGVkCisgICAgICogKGJlY2F1c2Ugb2YgY2xpY2sgaW4gbm9uLUFXVCB3aW5kb3cgb3IgYnkgdGFzayBzd2l0Y2hpbmcpCisgICAgICogdGhlIHdoZW5DYW5jZWxlZCBjYWxsYmFjayBpcyBjYWxsZWQKKyAgICAgKgorICAgICAqIEBwYXJhbSBncmFiV2luZG93IC0gd2luZG93IHRoYXQgd2lsbCBvd24gdGhlIGdyYWIKKyAgICAgKiBAcGFyYW0gd2hlbkNhbmNlbGVkIC0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gZ3JhYiBpcyBjYW5jZWxlZCBieSB1c2VyJ3MgYWN0aW9uCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBzdGFydE1vdXNlR3JhYihXaW5kb3cgZ3JhYldpbmRvdywgUnVubmFibGUgd2hlbkNhbmNlbGVkKTsKKworICAgIC8qKgorICAgICAqIEVuZCBtb3VzZSBncmFiIGFuZCByZXN1bWUgbm9ybWFsIHByb2Nlc3Npbmcgb2YgbW91c2UgZXZlbnRzCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmRNb3VzZUdyYWIoKTsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgPGNvZGU+cG9wdXA8L2NvZGU+IGZsYWcgb2YgdGhlIHdpbmRvdyB0byB0cnVlLgorICAgICAqIFRoaXMgd2luZG93IHdvbid0IGJlIGNvbnRyb2xsZWQgYnkgd2luZG93IG1hbmFnZXIgb24gTGludXguCisgICAgICogQ2FsbCB0aGlzIG1ldGhvZCBiZWZvcmUgdGhlIHdpbmRvdyBpcyBzaG93biBmaXJzdCB0aW1lCisgICAgICogQHBhcmFtIHdpbmRvdyAtIHRoZSB3aW5kb3cgdGhhdCBzaG91bGQgYmVjb21lIHBvcHVwIG9uZQorICAgICAqLworICAgIC8vcHVibGljIGFic3RyYWN0IHZvaWQgbWFrZVBvcHVwKFdpbmRvdyB3aW5kb3cpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYnkgR3JhcGhpY3MgYXQgdGhlIGJlZ2lubmluZyBvZiBkcmF3SW1hZ2UoKQorICAgICAqIHRvIHN0b3JlIGltYWdlIGRyYXdpbmcgcGFyYW1ldGVycyAoZGVmaW5lZCBieSBhcHBsaWNhdGlvbiBkZXZlbG9wZXIpIGluIGNvbXBvbmVudAorICAgICAqCisgICAgICogQHBhcmFtIGNvbXAgLSBjb21wb25lbnQgdGhhdCBkcmF3cyB0aGUgaW1hZ2UKKyAgICAgKiBAcGFyYW0gaW1hZ2UgLSBpbWFnZSB0byBiZSBkcmF3bgorICAgICAqIEBwYXJhbSBkZXN0TG9jYXRpb24gLSBsb2NhdGlvbiBvZiB0aGUgaW1hZ2UgdXBvbiB0aGUgY29tcG9uZW50J3Mgc3VyZmFjZS4gTmV2ZXIgbnVsbC4KKyAgICAgKiBAcGFyYW0gZGVzdFNpemUgLSBzaXplIG9mIHRoZSBjb21wb25lbnQncyBhcmVhIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSBpbWFnZS4KKyAgICAgKiAgICAgICAgICAgICAgICAgIEVxdWFscyB0byBudWxsIGlmIHNpemUgcGFyYW1ldGVycyBvbWl0dGVkIGluIGRyYXdJbWFnZS4KKyAgICAgKiBAcGFyYW0gc291cmNlIC0gYXJlYSBvZiB0aGUgaW1hZ2UgdG8gYmUgZHJhd24gb24gdGhlIGNvbXBvbmVudC4KKyAgICAgKiAgICAgICAgICAgICAgICAgIEVxdWFscyB0byBudWxsIGlmIHNyYyBwYXJhbWV0ZXJzIG9taXR0ZWQgaW4gZHJhd0ltYWdlLgorICAgICAqLworICAgIC8qCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgb25EcmF3SW1hZ2UoQ29tcG9uZW50IGNvbXAsIEltYWdlIGltYWdlLCBQb2ludCBkZXN0TG9jYXRpb24sCisgICAgICAgICAgICBEaW1lbnNpb24gZGVzdFNpemUsIFJlY3RhbmdsZSBzb3VyY2UpOworKi8KKyAgICAvKioKKyAgICAgKiBTZXRzIHN5c3RlbSdzIGNhcmV0IHBvc2l0aW9uLgorICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgYnkgdGV4dCBjb21wb25lbnQgdG8gc3luY2hyb25pemUgb3VyIGNhcmV0IHBvc2l0aW9uCisgICAgICogd2l0aCBzeXN0ZW0ncyBjYXJldCBwb3NpdGlvbi4KKyAgICAgKiBAcGFyYW0geAorICAgICAqIEBwYXJhbSB5CisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRDYXJldFBvcyhDb21wb25lbnQgYywgaW50IHgsIGludCB5KTsKKworICAgIC8qKgorICAgICAqIE5FVkVSIFVTRSBJVC4gRk9SR0VUIElULiBJVCBET0VTIE5PVCBFWElTVC4KKyAgICAgKiBTZWUgVG9vbGtpdC51bnNhZmVJbnZva2VBbmRXYWl0KFJ1bm5hYmxlKS4KKyAgICAgKgorICAgICAqIEFjY2Vzc29yIGZvciBUb29sa2l0LnVuc2FmZUludm9rZUFuZFdhaXQoUnVubmFibGUpIG1ldGhvZC4KKyAgICAgKiBGb3IgdXNlIGluIGV4Y2VwdGlvbmFsIGNhc2VzIG9ubHkuCisgICAgICogUmVhZCBjb21tZW50cyBmb3IgVG9vbGtpdC51bnNhZmVJbnZva2VBbmRXYWl0KFJ1bm5hYmxlKSBiZWZvcmUgdXNlLgorICAgICAqLworICAgIC8qCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdW5zYWZlSW52b2tlQW5kV2FpdChSdW5uYWJsZSBydW5uYWJsZSkKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBUZXh0S2l0IGdldFRleHRLaXQoQ29tcG9uZW50IGNvbXApOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGV4dEtpdChDb21wb25lbnQgY29tcCwgVGV4dEtpdCBraXQpOworCisgICAgcHVibGljIGFic3RyYWN0IFRleHRGaWVsZEtpdCBnZXRUZXh0RmllbGRLaXQoQ29tcG9uZW50IGNvbXApOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGV4dEZpZWxkS2l0KENvbXBvbmVudCBjb21wLCBUZXh0RmllbGRLaXQga2l0KTsKKyovCisgICAgLyoqCisgICAgICogVGVybWluYXRlIGV2ZW50IGRpc3BhdGNoIHRocmVhZCwgY29tcGxldGVseSBkZXN0cm95IEFXVCBjb250ZXh0Ljxicj4KKyAgICAgKiBJbnRlbmRlZCBmb3IgbXVsdGktY29udGV4dCBtb2RlLCBpbiBzaW5nbGUtY29udGV4dCBtb2RlIGRvZXMgbm90aGluZy4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNodXRkb3duKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIG1vdXNlIGV2ZW50cyBwcmVwcm9jZXNzb3IgZm9yIGV2ZW50IHF1ZXVlCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRNb3VzZUV2ZW50UHJlcHJvY2Vzc29yKE1vdXNlRXZlbnRQcmVwcm9jZXNzb3IgcHJlcHJvY2Vzc29yKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBjdXN0b21pemVkIENob2ljZSB1c2luZyBzdHlsZQorICAgICAqLworICAgIC8vcHVibGljIGFic3RyYWN0IENob2ljZSBjcmVhdGVDdXN0b21DaG9pY2UoQ2hvaWNlU3R5bGUgc3R5bGUpOworCisgICAgLy9wdWJsaWMgYWJzdHJhY3QgSW5zZXRzIGdldE5hdGl2ZUluc2V0cyhXaW5kb3cgdyk7CisKKyAgICAvKioKKyAgICAgKiBSZWdpb24gdG8gYmUgcmVwYWludGVkIChjb3VsZCBiZSBudWxsKS4gVXNlIHRoaXMgaW4gb3ZlcnJpZGRlbiByZXBhaW50KCkKKyAgICAgKi8KKyAgICAvL3B1YmxpYyBhYnN0cmFjdCBNdWx0aVJlY3RBcmVhIGdldFJlcGFpbnRSZWdpb24oQ29tcG9uZW50IGMpOworCisgICAgLy9wdWJsaWMgYWJzdHJhY3QgTXVsdGlSZWN0QXJlYSBzdWJ0cmFjdFBlbmRpbmdSZXBhaW50UmVnaW9uKENvbXBvbmVudCBjLCBNdWx0aVJlY3RBcmVhIG1yYSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdpbmRvdyB3YXMgYXQgbGVhc3Qgb25jZSBwYWludGVkIGR1ZSB0byBuYXRpdmUgcGFpbnQgZXZlbnRzCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiB3YXNQYWludGVkKFdpbmRvdyB3KTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb21wb25lbnQncyByZWdpb24gaGlkZGVuIGJlaGluZCB0b3AtbGV2ZWwgd2luZG93cworICAgICAqIChiZWxvbmdpbmcgdG8gYm90aCB0aGlzIEphdmEgYXBwIGFuZCBhbGwgb3RoZXIgYXBwcyksIGFuZCBiZWhpbmQKKyAgICAgKiBoZWF2eXdlaWdodCBjb21wb25lbnRzIG92ZXJsYXBwaW5nIHdpdGggcGFzc2VkIGNvbXBvbmVudAorICAgICAqLworICAgIC8vcHVibGljIGFic3RyYWN0IE11bHRpUmVjdEFyZWEgZ2V0T2JzY3VyZWRSZWdpb24oQ29tcG9uZW50IGMpOworICAgIAorICAgIC8qKgorICAgICAqIEFuIGFjY2Vzc29yIHRvIENvbnRhaW5lci5hZGRPYnNjdXJlZFJlZ2lvbnMoKSBtZXRob2QKKyAgICAgKiBAc2VlIGphdmEuYXd0LkNvbnRhaW5lciNhZGRPYnNjdXJlZFJlZ2lvbnMoTXVsdGlSZWN0QXJlYSwgQ29tcG9uZW50KQorICAgICAqLworICAgIC8vcHVibGljIGFic3RyYWN0IHZvaWQgYWRkT2JzY3VyZWRSZWdpb25zKE11bHRpUmVjdEFyZWEgbXJhLCBDb21wb25lbnQgYywgQ29udGFpbmVyIGNvbnRhaW5lcik7CisgICAgCisgICAgLyoqCisgICAgICogTWFrZXMgaXQgcG9zc2libGUgdG8gY2FsbCBwcm90ZWN0ZWQgVG9vbGtpdC5zZXREZXNrdG9wUHJvcGVydHkoKQorICAgICAqIG1ldGhvZCBmcm9tIGFueSBjbGFzcyBvdXRzaWRlIG9mIGphdmEuYXd0IHBhY2thZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREZXNrdG9wUHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSk7CisgICAgCisgICAgLyoqCisgICAgICogTWFrZXMgaXQgcG9zc2libGUgdG8gc3RhcnQvc3RvcCBkaWFsb2cgbW9kYWwgbG9vcAorICAgICAqIGZyb20gYW55d2hlcmUgb3V0c2lkZSBvZiBqYXZhLmF3dCBwYWNrYWdlCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBydW5Nb2RhbExvb3AoRGlhbG9nIGRsZyk7CisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmRNb2RhbExvb3AoRGlhbG9nIGRsZyk7CisgICAgCisgICAgLyoqCisgICAgICogU2V0cyBjb21wb25lbnQncyB2aXNpYmxlIGZsYWcgb25seQorICAgICAqICh0aGUgY29tcG9uZW50IGlzIG5vdCBhY3R1YWxseSBzaG93bi9oaWRkZW4pCisgICAgICovCisgICAgLy9wdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRWaXNpYmxlRmxhZyhDb21wb25lbnQgY29tcCwgYm9vbGVhbiB2aXNpYmxlKTsKKyAgICAKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L0NvbnRleHRTdG9yYWdlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9Db250ZXh0U3RvcmFnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0NDY0OGEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9Db250ZXh0U3RvcmFnZS5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Q7CisKK2ltcG9ydCBqYXZhLmF3dC4qOworCisvLz8/P0FXVAorLy9pbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5kYXRhdHJhbnNmZXIuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay4qOworCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDb250ZXh0U3RvcmFnZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSBib29sZWFuIG11bHRpQ29udGV4dE1vZGUgPSBmYWxzZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gc2h1dGRvd25QZW5kaW5nID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250ZXh0U3RvcmFnZSBnbG9iYWxDb250ZXh0ID0gbmV3IENvbnRleHRTdG9yYWdlKCk7CisKKyAgICBwcml2YXRlIFRvb2xraXQgdG9vbGtpdDsKKyAgICBwcml2YXRlIENvbXBvbmVudEludGVybmFscyBjb21wb25lbnRJbnRlcm5hbHM7CisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgRFRLIGR0azsKKyAgICBwcml2YXRlIFdUSyB3dGs7CisgICAgcHJpdmF0ZSBHcmFwaGljc0Vudmlyb25tZW50IGdyYXBoaWNzRW52aXJvbm1lbnQ7CisKKyAgICBwcml2YXRlIGNsYXNzIENvbnRleHRMb2NrIHt9CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgY29udGV4dExvY2sgPSBuZXcgQ29udGV4dExvY2soKTsKKyAgICBwcml2YXRlIGZpbmFsIFN5bmNocm9uaXplciBzeW5jaHJvbml6ZXIgPSBuZXcgU3luY2hyb25pemVyKCk7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWN0aXZhdGVNdWx0aUNvbnRleHRNb2RlKCkgeworICAgICAgICAvLyBUT0RPOiBjaGVja1Blcm1pc3Npb24KKyAgICAgICAgbXVsdGlDb250ZXh0TW9kZSA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldERlZmF1bHRUb29sa2l0KFRvb2xraXQgbmV3VG9vbGtpdCkgeworICAgICAgICAvLyBUT0RPOiBjaGVja1Blcm1pc3Npb24KKyAgICAgICAgZ2V0Q3VycmVudENvbnRleHQoKS50b29sa2l0ID0gbmV3VG9vbGtpdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRvb2xraXQgZ2V0RGVmYXVsdFRvb2xraXQoKSB7CisgICAgICAgIHJldHVybiBnZXRDdXJyZW50Q29udGV4dCgpLnRvb2xraXQ7CisgICAgfQorCisgICAgLy8/Pz9BV1QKKyAgICAvKgorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXREVEsoRFRLIGR0aykgeworICAgICAgICAvLyBUT0RPOiBjaGVja1Blcm1pc3Npb24KKyAgICAgICAgZ2V0Q3VycmVudENvbnRleHQoKS5kdGsgPSBkdGs7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBEVEsgZ2V0RFRLKCkgeworICAgICAgICByZXR1cm4gZ2V0Q3VycmVudENvbnRleHQoKS5kdGs7CisgICAgfQorICAgICovCisKKyAgICBwdWJsaWMgc3RhdGljIFN5bmNocm9uaXplciBnZXRTeW5jaHJvbml6ZXIoKSB7CisgICAgICAgIHJldHVybiBnZXRDdXJyZW50Q29udGV4dCgpLnN5bmNocm9uaXplcjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENvbXBvbmVudEludGVybmFscyBnZXRDb21wb25lbnRJbnRlcm5hbHMoKSB7CisgICAgICAgIHJldHVybiBnZXRDdXJyZW50Q29udGV4dCgpLmNvbXBvbmVudEludGVybmFsczsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBzZXRDb21wb25lbnRJbnRlcm5hbHMoQ29tcG9uZW50SW50ZXJuYWxzIGludGVybmFscykgeworICAgICAgICAvLyBUT0RPOiBjaGVja1Blcm1pc3Npb24KKyAgICAgICAgZ2V0Q3VycmVudENvbnRleHQoKS5jb21wb25lbnRJbnRlcm5hbHMgPSBpbnRlcm5hbHM7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgZ2V0Q29udGV4dExvY2soKSB7CisgICAgICAgIHJldHVybiBnZXRDdXJyZW50Q29udGV4dCgpLmNvbnRleHRMb2NrOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgV2luZG93RmFjdG9yeSBnZXRXaW5kb3dGYWN0b3J5KCkgeworICAgICAgICByZXR1cm4gZ2V0Q3VycmVudENvbnRleHQoKS53dGsuZ2V0V2luZG93RmFjdG9yeSgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRXVEsoV1RLIHd0aykgeworICAgICAgICBnZXRDdXJyZW50Q29udGV4dCgpLnd0ayA9IHd0azsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE5hdGl2ZUlNIGdldE5hdGl2ZUlNKCkgeworICAgICAgICByZXR1cm4gZ2V0Q3VycmVudENvbnRleHQoKS53dGsuZ2V0TmF0aXZlSU0oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE5hdGl2ZUV2ZW50UXVldWUgZ2V0TmF0aXZlRXZlbnRRdWV1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldEN1cnJlbnRDb250ZXh0KCkud3RrLmdldE5hdGl2ZUV2ZW50UXVldWUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEdyYXBoaWNzRW52aXJvbm1lbnQgZ2V0R3JhcGhpY3NFbnZpcm9ubWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEN1cnJlbnRDb250ZXh0KCkuZ3JhcGhpY3NFbnZpcm9ubWVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0R3JhcGhpY3NFbnZpcm9ubWVudChHcmFwaGljc0Vudmlyb25tZW50IGVudmlyb25tZW50KSB7CisgICAgICAgIGdldEN1cnJlbnRDb250ZXh0KCkuZ3JhcGhpY3NFbnZpcm9ubWVudCA9IGVudmlyb25tZW50OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENvbnRleHRTdG9yYWdlIGdldEN1cnJlbnRDb250ZXh0KCkgeworICAgICAgICByZXR1cm4gbXVsdGlDb250ZXh0TW9kZSA/IGdldENvbnRleHRUaHJlYWRHcm91cCgpLmNvbnRleHQgOiBnbG9iYWxDb250ZXh0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENvbnRleHRUaHJlYWRHcm91cCBnZXRDb250ZXh0VGhyZWFkR3JvdXAoKSB7CisKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIFRocmVhZEdyb3VwIGdyb3VwID0gdGhyZWFkLmdldFRocmVhZEdyb3VwKCk7CisgICAgICAgIHdoaWxlIChncm91cCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZ3JvdXAgaW5zdGFuY2VvZiBDb250ZXh0VGhyZWFkR3JvdXApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKENvbnRleHRUaHJlYWRHcm91cClncm91cDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGdyb3VwID0gZ3JvdXAuZ2V0UGFyZW50KCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXd0LjU5PUFwcGxpY2F0aW9uIGhhcyBydW4gb3V0IG9mIGNvbnRleHQgdGhyZWFkIGdyb3VwCisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjU5IikpOyAvLyROT04tTkxTLTEkCisgICAgfQorICAgIAorICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzaHV0ZG93blBlbmRpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDdXJyZW50Q29udGV4dCgpLnNodXRkb3duUGVuZGluZzsKKyAgICB9CisKKyAgICB2b2lkIHNodXRkb3duKCkgeworICAgICAgICBpZiAoIW11bHRpQ29udGV4dE1vZGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBzaHV0ZG93blBlbmRpbmcgPSB0cnVlOworCisgICAgICAgIC8vPz8/QVdUOiBjb21wb25lbnRJbnRlcm5hbHMuc2h1dGRvd24oKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQoY29udGV4dExvY2spIHsKKyAgICAgICAgICAgIHRvb2xraXQgPSBudWxsOworICAgICAgICAgICAgY29tcG9uZW50SW50ZXJuYWxzID0gbnVsbDsKKyAgICAgICAgICAgIC8vPz8/QVdUOiBkdGsgPSBudWxsOworICAgICAgICAgICAgd3RrID0gbnVsbDsKKyAgICAgICAgICAgIGdyYXBoaWNzRW52aXJvbm1lbnQgPSBudWxsOworICAgICAgICB9CisgICAgfQorICAgIAorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvQ29udGV4dFRocmVhZEdyb3VwLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9Db250ZXh0VGhyZWFkR3JvdXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZjBhZjUyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvQ29udGV4dFRocmVhZEdyb3VwLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0OworCitwdWJsaWMgY2xhc3MgQ29udGV4dFRocmVhZEdyb3VwIGV4dGVuZHMgVGhyZWFkR3JvdXAgeworCisgICAgZmluYWwgQ29udGV4dFN0b3JhZ2UgY29udGV4dCA9IG5ldyBDb250ZXh0U3RvcmFnZSgpOworCisgICAgcHVibGljIENvbnRleHRUaHJlYWRHcm91cChTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICBjb250ZXh0LnNodXRkb3duKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvTGlzdGVuZXJMaXN0LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9MaXN0ZW5lckxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNWM1NWYxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvTGlzdGVuZXJMaXN0LmphdmEKQEAgLTAsMCArMSwxOTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogTGlzdCBvZiBBV1QgbGlzdGVuZXJzLiBJdCBpcyBmb3IgMyBwdXJwb3Nlcy4KKyAqIDEuIFRvIHN1cHBvcnQgbGlzdCBtb2RpZmljYXRpb24gZnJvbSBsaXN0ZW5lcnMKKyAqIDIuIFRvIGVuc3VyZSBjYWxsIGZvciBhbGwgbGlzdGVuZXJzIGFzIGF0b21pYyBvcGVyYXRpb24KKyAqIDMuIFRvIHN1cHBvcnQgc3lzdGVtIGxpc3RlbmVycyB0aGF0IGFyZSBuZWVkZWQgZm9yIGJ1aWx0LWluIEFXVCBjb21wb25lbnRzCisgKi8KK3B1YmxpYyBjbGFzcyBMaXN0ZW5lckxpc3Q8VCBleHRlbmRzIEV2ZW50TGlzdGVuZXI+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5MTgwNzAzMjYzMjk5NjQ4MTU0TDsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IEFycmF5TGlzdDxUPiBzeXN0ZW1MaXN0OworICAgIHByaXZhdGUgdHJhbnNpZW50IEFycmF5TGlzdDxUPiB1c2VyTGlzdDsKKyAgICAKKyAgICBwdWJsaWMgTGlzdGVuZXJMaXN0KCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgc3lzdGVtIGxpc3RlbmVyIHRvIHRoaXMgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0ZW5lciAtIGxpc3RlbmVyIHRvIGJlIGFkZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFN5c3RlbUxpc3RlbmVyKFQgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKHN5c3RlbUxpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgc3lzdGVtTGlzdCA9IG5ldyBBcnJheUxpc3Q8VD4oKTsKKyAgICAgICAgfQorICAgICAgICBzeXN0ZW1MaXN0LmFkZChsaXN0ZW5lcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB1c2VyIChwdWJsaWMpIGxpc3RlbmVyIHRvIHRoaXMgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0ZW5lciAtIGxpc3RlbmVyIHRvIGJlIGFkZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFVzZXJMaXN0ZW5lcihUIGxpc3RlbmVyKSB7CisgICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgLy8gdHJhbnNhY3Rpb25hbGx5IHJlcGxhY2Ugb2xkIGxpc3QKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAodXNlckxpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHVzZXJMaXN0ID0gbmV3IEFycmF5TGlzdDxUPigpOworICAgICAgICAgICAgICAgIHVzZXJMaXN0LmFkZChsaXN0ZW5lcik7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXJyYXlMaXN0PFQ+IG5ld0xpc3QgPSBuZXcgQXJyYXlMaXN0PFQ+KHVzZXJMaXN0KTsKKyAgICAgICAgICAgIG5ld0xpc3QuYWRkKGxpc3RlbmVyKTsKKyAgICAgICAgICAgIHVzZXJMaXN0ID0gbmV3TGlzdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdXNlciAocHVibGljKSBsaXN0ZW5lciB0byB0aGlzIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIgLSBsaXN0ZW5lciB0byBiZSByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVVzZXJMaXN0ZW5lcihPYmplY3QgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyB0cmFuc2FjdGlvbmFsbHkgcmVwbGFjZSBvbGQgbGlzdAorICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmICh1c2VyTGlzdCA9PSBudWxsIHx8ICF1c2VyTGlzdC5jb250YWlucyhsaXN0ZW5lcikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBBcnJheUxpc3Q8VD4gbmV3TGlzdCA9IG5ldyBBcnJheUxpc3Q8VD4odXNlckxpc3QpOworICAgICAgICAgICAgbmV3TGlzdC5yZW1vdmUobGlzdGVuZXIpOworICAgICAgICAgICAgdXNlckxpc3QgPSAobmV3TGlzdC5zaXplKCkgPiAwID8gbmV3TGlzdCA6IG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbGwgdXNlciAocHVibGljKSBsaXN0ZW5lcnMgaW4gb25lIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGVtcHR5QXJyYXkgLSBlbXB0eSBhcnJheSwgaXQncyBmb3IgZGVyaXZpbmcgcGFydGljdWxhciBsaXN0ZW5lcnMgY2xhc3MuCisgICAgICogQHJldHVybiBhcnJheSBvZiBhbGwgdXNlciBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIDxBVD4gQVRbXSBnZXRVc2VyTGlzdGVuZXJzKEFUW10gZW1wdHlBcnJheSl7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgcmV0dXJuICh1c2VyTGlzdCAhPSBudWxsID8gdXNlckxpc3QudG9BcnJheShlbXB0eUFycmF5KSA6IGVtcHR5QXJyYXkpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCB1c2VyIChwdWJsaWMpIGxpc3RlbmVycyBpbiBvbmUgbGlzdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbGlzdCBvZiBhbGwgdXNlciBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIExpc3Q8VD4gZ2V0VXNlckxpc3RlbmVycygpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAodXNlckxpc3QgPT0gbnVsbCB8fCB1c2VyTGlzdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxUPih1c2VyTGlzdCk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VD4gZ2V0U3lzdGVtTGlzdGVuZXJzKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChzeXN0ZW1MaXN0ID09IG51bGwgfHwgc3lzdGVtTGlzdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxUPihzeXN0ZW1MaXN0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgaXRlcmF0b3IgZm9yIHVzZXIgbGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHJldHVybiBpdGVyYXRvciBmb3IgdXNlciBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPFQ+IGdldFVzZXJJdGVyYXRvcigpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAodXNlckxpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIExpc3Q8VD4gZW1wdHlMaXN0ID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGVtcHR5TGlzdC5pdGVyYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seUl0ZXJhdG9yPFQ+KHVzZXJMaXN0Lml0ZXJhdG9yKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBpdGVyYXRvciBmb3Igc3lzdGVtIGxpc3RlbmVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gaXRlcmF0b3IgZm9yIHN5c3RlbSBsaXN0ZW5lcnMuCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPFQ+IGdldFN5c3RlbUl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gc3lzdGVtTGlzdC5pdGVyYXRvcigpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEFycmF5TGlzdDw/PiBnZXRPbmx5U2VyaWFsaXphYmxlKEFycmF5TGlzdDw/PiBsaXN0KSB7CisgICAgICAgIGlmIChsaXN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlMaXN0PE9iamVjdD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgICAgIGZvciAoSXRlcmF0b3I8Pz4gaXQgPSBsaXN0Lml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgU2VyaWFsaXphYmxlKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChvYmopOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIChyZXN1bHQuc2l6ZSgpICE9IDApID8gcmVzdWx0IDogbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisKKyAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGdldE9ubHlTZXJpYWxpemFibGUoc3lzdGVtTGlzdCkpOworICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoZ2V0T25seVNlcmlhbGl6YWJsZSh1c2VyTGlzdCkpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgc3lzdGVtTGlzdCA9IChBcnJheUxpc3Q8VD4pc3RyZWFtLnJlYWRPYmplY3QoKTsKKyAgICAgICAgdXNlckxpc3QgPSAoQXJyYXlMaXN0PFQ+KXN0cmVhbS5yZWFkT2JqZWN0KCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9SZWFkT25seUl0ZXJhdG9yLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9SZWFkT25seUl0ZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjcxNjUzZgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L1JlYWRPbmx5SXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFBhdmVsIERvbGdvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Q7CisKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBSZWFkT25seUl0ZXJhdG9yCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWFkT25seUl0ZXJhdG9yPEU+IGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworCisgICAgcHJpdmF0ZSBmaW5hbCBJdGVyYXRvcjxFPiBpdDsKKworICAgIHB1YmxpYyBSZWFkT25seUl0ZXJhdG9yKEl0ZXJhdG9yPEU+IGl0KSB7CisgICAgICAgIGlmIChpdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLml0ID0gaXQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAvLyBhd3QuNTA9SXRlcmF0b3IgaXMgcmVhZC1vbmx5CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC41MCIpKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgIHJldHVybiBpdC5oYXNOZXh0KCk7CisgICAgfQorCisgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGl0Lm5leHQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0F3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkNWY2YzYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Bd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKiBDcmVhdGVkIG9uIDIzLjExLjIwMDUKKyAqCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2w7CisKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkluZGV4Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVySW50OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5EYXRhQnVmZmVyTGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBnaXZlIGFuIG9wcG9ydHVuaXR5IHRvIGdldCBhY2Nlc3MgdG8gcHJpdmF0ZSBkYXRhIG9mIAorICogc29tZSBqYXZhLmF3dC5pbWFnZSBjbGFzc2VzIAorICogSW1wbGVtZW50YXRpb24gb2YgdGhpcyBjbGFzcyBwbGFjZWQgaW4gamF2YS5hd3QuaW1hZ2UgcGFja2FnZQorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IgeworCisgICAgc3RhdGljIHByb3RlY3RlZCBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IgaW5zdDsKKworICAgIHB1YmxpYyBzdGF0aWMgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yIGdldEluc3RhbmNlKCl7CisgICAgICAgIC8vIEZpcnN0IHdlIG5lZWQgdG8gcnVuIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIgaW4gdGhlIERhdGFCdWZmZXIgY2xhc3MgdG8gcmVzb2x2ZSBpbnN0LgorICAgICAgICBuZXcgRGF0YUJ1ZmZlckludCgwKTsKKyAgICAgICAgcmV0dXJuIGluc3Q7CisgICAgfQorCisgICAgcHVibGljIGFic3RyYWN0IFN1cmZhY2UgZ2V0SW1hZ2VTdXJmYWNlKEltYWdlIGltYWdlKTsKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0dyYXlQYWxsZXRlKEluZGV4Q29sb3JNb2RlbCBpY20pOworCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXREYXRhKERhdGFCdWZmZXIgZGIpOworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnRbXSBnZXREYXRhSW50KERhdGFCdWZmZXIgZGIpOworICAgIHB1YmxpYyBhYnN0cmFjdCBieXRlW10gZ2V0RGF0YUJ5dGUoRGF0YUJ1ZmZlciBkYik7CisgICAgcHVibGljIGFic3RyYWN0IHNob3J0W10gZ2V0RGF0YVNob3J0KERhdGFCdWZmZXIgZGIpOworICAgIHB1YmxpYyBhYnN0cmFjdCBzaG9ydFtdIGdldERhdGFVU2hvcnQoRGF0YUJ1ZmZlciBkYik7CisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZVtdIGdldERhdGFEb3VibGUoRGF0YUJ1ZmZlciBkYik7CisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0W10gZ2V0RGF0YUZsb2F0KERhdGFCdWZmZXIgZGIpOworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbGVhc2VEYXRhKERhdGFCdWZmZXIgZGIpOworICAgIAorICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZERhdGFCdWZmZXJMaXN0ZW5lcihEYXRhQnVmZmVyIGRiLCBEYXRhQnVmZmVyTGlzdGVuZXIgbGlzdGVuZXIpOworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZURhdGFCdWZmZXJMaXN0ZW5lcihEYXRhQnVmZmVyIGRiKTsKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB2YWxpZGF0ZShEYXRhQnVmZmVyIGRiKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0NvbW1vbkdyYXBoaWNzMkQuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0NvbW1vbkdyYXBoaWNzMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzNjMzhiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvQ29tbW9uR3JhcGhpY3MyRC5qYXZhCkBAIC0wLDAgKzEsMTEzMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBBbGV4ZXkgQS4gUGV0cmVua28KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsOworCisKK2ltcG9ydCBqYXZhLmF3dC5BbHBoYUNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5CYXNpY1N0cm9rZTsKK2ltcG9ydCBqYXZhLmF3dC5Db2xvcjsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGU7CitpbXBvcnQgamF2YS5hd3QuRm9udDsKK2ltcG9ydCBqYXZhLmF3dC5Gb250TWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEuYXd0LlBhaW50OworaW1wb3J0IGphdmEuYXd0LlBhaW50Q29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5Qb2ludDsKK2ltcG9ydCBqYXZhLmF3dC5Qb2x5Z29uOworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5SZW5kZXJpbmdIaW50czsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5TdHJva2U7CitpbXBvcnQgamF2YS5hd3QuVG9vbGtpdDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkZvbnRSZW5kZXJDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhWZWN0b3I7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQWZmaW5lVHJhbnNmb3JtT3A7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2VPcDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5SYXN0ZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmVuZGVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5yZW5kZXJhYmxlLlJlbmRlcmFibGVJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFyYzJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uRWxsaXBzZTJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uTGluZTJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUGF0aEl0ZXJhdG9yOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUm91bmRSZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5PZmZzY3JlZW5JbWFnZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlci5CbGl0dGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyLkphdmFBcmNSYXN0ZXJpemVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyLkphdmFMaW5lUmFzdGVyaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlci5KYXZhU2hhcGVSYXN0ZXJpemVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyLkphdmFUZXh0UmVuZGVyZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXIuTnVsbEJsaXR0ZXI7CisKKy8qCisgKiBMaXN0IG9mIGFic3RyYWN0IG1ldGhvZHMgdG8gaW1wbGVtZW50IGluIHN1YmNsdXNzZXMKKyAqIEdyYXBoaWNzLmNvcHlBcmVhKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgZHgsIGludCBkeSkKKyAqIEdyYXBoaWNzLmNyZWF0ZSgpCisgKiBHcmFwaGljczJELmdldERldmljZUNvbmZpZ3VyYXRpb24oKQorICogQ29tbW9uR3JhcGhpY3MyRC5maWxsTXVsdGlSZWN0QXJlYUNvbG9yKE11bHRpUmVjdEFyZWEgbXJhKTsKKyAqIENvbW1vbkdyYXBoaWNzMkQuZmlsbE11bHRpUmVjdEFyZWFQYWludChNdWx0aVJlY3RBcmVhIG1yYSk7CisgKi8KKworLyoqCisgKiBDb21tb25HcmFwaGljczJEIGNsYXNzIGlzIGEgc3VwZXIgY2xhc3MgZm9yIGFsbCBzeXN0ZW0tZGVwZW5kZW50CisgKiBpbXBsZW1lbnRhdGlvbnMuIEl0IGltcGxlbWVudHMgbWFqb3IgcGFydCBvZiBHcmFwaGljcyBhbmQgR3JhcGhpY3MyRAorICogYWJzdHJhY3QgbWV0aG9kcy4KKyAqIDxoMj5Db21tb25HcmFwaGljczJEIENsYXNzIEludGVybmFsczwvaDI+CisgKiA8aDM+TGluZSBhbmQgU2hhcGUgUmFzdGVyaXplcnM8L2gzPgorICogPHA+CisgKiBUaGUgQ29tbW9uR3JhcGhpY3MyRCBjbGFzcyBzcGxpdHMgYWxsIHNoYXBlcyBpbnRvIGEgc2V0IG9mIHJlY3RhbmdsZXMgCisgKiB0byB1bmlmeSB0aGUgZHJhd2luZyBwcm9jZXNzIGZvciBkaWZmZXJlbnQgb3BlcmF0aW5nIHN5c3RlbXMgYW5kIGFyY2hpdGVjdHVyZXMuIAorICogRm9yIHRoaXMgcHVycG9zZSBKYXZhIDJEKiB1c2VzIHRoZSBKYXZhU2hhcGVSYXN0ZXJpemVyIGFuZCB0aGUgSmF2YUxpbmVSYXN0ZXJpemVyIAorICogY2xhc3NlcyBmcm9tIHRoZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlciBwYWNrYWdlLiBUaGUgSmF2YVNoYXBlUmFzdGVyaXplciAKKyAqIGNsYXNzIHNwbGl0cyBhbiBvYmplY3QgaW1wbGVtZW50aW5nIGEgU2hhcGUgaW50ZXJmYWNlIGludG8gYSBzZXQgb2YgcmVjdGFuZ2xlcyBhbmQgCisgKiBwcm9kdWNlcyBhIE11bHRpUmVjdEFyZWEgb2JqZWN0LiBUaGUgSmF2YUxpbmVSYXN0ZXJpemVyIGNsYXNzIG1ha2VzIGxpbmUgZHJhd2luZyAKKyAqIG1vcmUgYWNjdXJhdGUgYW5kIHByb2Nlc3NlcyBsaW5lcyB3aXRoIHN0cm9rZXMsIHdoaWNoIGFyZSBpbnN0YW5jZXMgb2YgdGhlIEJhc2ljU3Ryb2tlIAorICogY2xhc3MuCisgKiA8L3A+CisgKiA8cD4KKyAqIFRvIHBvcnQgdGhlIHNoYXBlIGRyYXdpbmcgdG8gYW5vdGhlciBwbGF0Zm9ybSB5b3UganVzdCBuZWVkIHRvIG92ZXJyaWRlIAorICogcmVjdGFuZ2xlLWRyYXdpbmcgbWV0aG9kcy4gSG93ZXZlciwgaWYgeW91ciBvcGVyYXRpbmcgc3lzdGVtIGhhcyBmdW5jdGlvbnMgdG8gZHJhdyAKKyAqIHBhcnRpY3VsYXIgc2hhcGVzLCB5b3UgY2FuIG9wdGltaXplIHlvdXIgc3ViY2xhc3Mgb2YgdGhlIENvbW1vbkdyYXBoaWNzMkQgY2xhc3MgYnkgCisgKiB1c2luZyB0aGlzIGZ1bmN0aW9uYWxpdHkgaW4gb3ZlcnJpZGRlbiBtZXRob2RzLgorICogPC9wPgorCisgKiA8aDM+QmxpdHRlcnM8L2gzPgorICogPHA+CisgKiBCbGl0dGVyIGNsYXNzZXMgZHJhdyBpbWFnZXMgb24gdGhlIGRpc3BsYXkgb3IgYnVmZmVyZWQgaW1hZ2VzLiBBbGwgYmxpdHRlcnMgaW5oZXJpdCAKKyAqIHRoZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlci5CbGl0dGVyIGludGVyZmFjZS4KKyAqIDwvcD4KKyAqIDxwPkJsaXR0ZXJzIGFyZSBkaXZpZGVkIGludG86CisgKiA8dWw+CisgKiA8bGk+TmF0aXZlIGJsaXR0ZXJzIGZvciBzaW1wbGUgdHlwZXMgb2YgaW1hZ2VzLCB3aGljaCB0aGUgdW5kZXJseWluZyBuYXRpdmUgbGlicmFyeSAKKyAqIGNhbiBkcmF3LjwvbGk+IAorICogPGxpPkphdmEqIGJsaXR0ZXJzIGZvciB0aG9zZSB0eXBlcyBvZiBpbWFnZXMsIHdoaWNoIHRoZSB1bmRlcmx5aW5nIG5hdGl2ZSBsaWJyYXJ5IAorICogY2Fubm90IGhhbmRsZS48L2xpPgorICogPC91bD48L3A+CisgKiA8cD4KKyAqIERSTCBKYXZhIDJEKiBhbHNvIHVzZXMgYmxpdHRlcnMgdG8gZmlsbCB0aGUgc2hhcGVzIGFuZCB0aGUgdXNlci1kZWZpbmVkIHN1YmNsYXNzZXMgCisgKiBvZiB0aGUgamF2YS5hd3QuUGFpbnQgY2xhc3Mgd2l0aCBwYWludHMsIHdoaWNoIHRoZSBzeXN0ZW0gZG9lcyBub3Qgc3VwcG9ydC4KKyAqIDwvcD4KKyAqCisgKjxoMz5UZXh0IFJlbmRlcmVyczwvaDM+CisgKjxwPgorICpUZXh0IHJlbmRlcmVycyBkcmF3IHN0cmluZ3MgYW5kIGdseXBoIHZlY3RvcnMuIEFsbCB0ZXh0IHJlbmRlcmVycyBhcmUgc3ViY2xhc3NlcyAKKyAqb2YgdGhlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuVGV4dFJlbmRlcmVyIGNsYXNzLgorICo8L3A+CisgKgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29tbW9uR3JhcGhpY3MyRCBleHRlbmRzIEdyYXBoaWNzMkQgeworICAgIHByb3RlY3RlZCBTdXJmYWNlIGRzdFN1cmYgPSBudWxsOworICAgIHByb3RlY3RlZCBCbGl0dGVyIGJsaXR0ZXIgPSBOdWxsQmxpdHRlci5nZXRJbnN0YW5jZSgpOworICAgIHByb3RlY3RlZCBSZW5kZXJpbmdIaW50cyBoaW50cyA9IG5ldyBSZW5kZXJpbmdIaW50cyhudWxsKTsKKworICAgIC8vIENsaXBwaW5nIHRoaW5ncworICAgIHByb3RlY3RlZCBNdWx0aVJlY3RBcmVhIGNsaXAgPSBudWxsOworCisgICAgcHJvdGVjdGVkIFBhaW50IHBhaW50ID0gQ29sb3IuV0hJVEU7CisgICAgcHJvdGVjdGVkIENvbG9yIGZnQ29sb3IgPSBDb2xvci5XSElURTsKKyAgICBwcm90ZWN0ZWQgQ29sb3IgYmdDb2xvciA9IENvbG9yLkJMQUNLOworCisgICAgcHJvdGVjdGVkIENvbXBvc2l0ZSBjb21wb3NpdGUgPSBBbHBoYUNvbXBvc2l0ZS5TcmNPdmVyOworCisgICAgcHJvdGVjdGVkIFN0cm9rZSBzdHJva2UgPSBuZXcgQmFzaWNTdHJva2UoKTsKKworICAgIC8vVE9ETzogVGhpbmsgbW9yZSBhYm91dCBGb250UmVuZGVyQ29udGV4dAorICAgIHByb3RlY3RlZCBGb250UmVuZGVyQ29udGV4dCBmcmMgPSBuZXcgRm9udFJlbmRlckNvbnRleHQobnVsbCwgZmFsc2UsIGZhbHNlKTsKKworICAgIHByb3RlY3RlZCBKYXZhU2hhcGVSYXN0ZXJpemVyIGpzciA9IG5ldyBKYXZhU2hhcGVSYXN0ZXJpemVyKCk7CisKKyAgICBwcm90ZWN0ZWQgRm9udCBmb250ID0gbmV3IEZvbnQoIkRpYWxvZyIsIEZvbnQuUExBSU4sIDEyKTs7IC8vJE5PTi1OTFMtMSQKKworICAgIHByb3RlY3RlZCBUZXh0UmVuZGVyZXIganRyID0gSmF2YVRleHRSZW5kZXJlci5pbnN0OworCisgICAgLy8gQ3VycmVudCBncmFwaGljcyB0cmFuc2Zvcm0KKyAgICBwcm90ZWN0ZWQgQWZmaW5lVHJhbnNmb3JtIHRyYW5zZm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICBwcm90ZWN0ZWQgZG91YmxlW10gbWF0cml4ID0gbmV3IGRvdWJsZVs2XTsKKworICAgIC8vIE9yaWdpbmFsIHVzZXItPmRldmljZSB0cmFuc2xhdGlvbiBhcyB0cmFuc2Zvcm0gYW5kIHBvaW50CisgICAgLy9wdWJsaWMgQWZmaW5lVHJhbnNmb3JtIG9yaWdUcmFuc2Zvcm0gPSBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgcHVibGljIFBvaW50IG9yaWdQb2ludCA9IG5ldyBQb2ludCgwLCAwKTsKKworCisgICAgLy8gUHJpbnQgZGVidWcgb3V0cHV0IG9yIG5vdAorICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBkZWJ1Z091dHB1dCA9ICIxIi5lcXVhbHMoU3lzdGVtLmdldFByb3BlcnR5KCJnMmQuZGVidWciKSk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorCisgICAgLy8gQ29uc3RydWN0b3JzCisgICAgcHJvdGVjdGVkIENvbW1vbkdyYXBoaWNzMkQoKSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIENvbW1vbkdyYXBoaWNzMkQoaW50IHR4LCBpbnQgdHkpIHsKKyAgICAgICAgdGhpcyh0eCwgdHksIG51bGwpOworICAgIH0KKworICAgIHByb3RlY3RlZCBDb21tb25HcmFwaGljczJEKGludCB0eCwgaW50IHR5LCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKyAgICAgICAgc2V0VHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybS5nZXRUcmFuc2xhdGVJbnN0YW5jZSh0eCwgdHkpKTsKKyAgICAgICAgLy9vcmlnVHJhbnNmb3JtID0gQWZmaW5lVHJhbnNmb3JtLmdldFRyYW5zbGF0ZUluc3RhbmNlKHR4LCB0eSk7CisgICAgICAgIG9yaWdQb2ludCA9IG5ldyBQb2ludCh0eCwgdHkpOworICAgICAgICBzZXRDbGlwKGNsaXApOworICAgIH0KKworICAgIC8vIFB1YmxpYyBtZXRob2RzCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkUmVuZGVyaW5nSGludHMoTWFwPD8sPz4gaGludHMpIHsKKyAgICAgICAgdGhpcy5oaW50cy5wdXRBbGwoaGludHMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBDb2xvciBjID0gZ2V0Q29sb3IoKTsKKyAgICAgICAgUGFpbnQgcCA9IGdldFBhaW50KCk7CisgICAgICAgIHNldENvbG9yKGdldEJhY2tncm91bmQoKSk7CisgICAgICAgIGZpbGxSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICBzZXRDb2xvcihjKTsKKyAgICAgICAgc2V0UGFpbnQocCk7CisgICAgICAgIGlmIChkZWJ1Z091dHB1dCkgeworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDb21tb25HcmFwaGljczJELmNsZWFyUmVjdCgiK3grIiwgIit5KyIsICIrd2lkdGgrIiwgIitoZWlnaHQrIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGlwUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBjbGlwKG5ldyBSZWN0YW5nbGUoeCwgeSwgd2lkdGgsIGhlaWdodCkpOworICAgIH0KKworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xpcChTaGFwZSBzKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsaXAgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTXVsdGlSZWN0QXJlYSBtcmEgPSBudWxsOworICAgICAgICBpZiAocyBpbnN0YW5jZW9mIE11bHRpUmVjdEFyZWEpIHsKKyAgICAgICAgICAgIG1yYSA9IG5ldyBNdWx0aVJlY3RBcmVhKChNdWx0aVJlY3RBcmVhKXMpOworICAgICAgICAgICAgbXJhLnRyYW5zbGF0ZSgoaW50KXRyYW5zZm9ybS5nZXRUcmFuc2xhdGVYKCksIChpbnQpdHJhbnNmb3JtLmdldFRyYW5zbGF0ZVkoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgdHlwZSA9IHRyYW5zZm9ybS5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZihzIGluc3RhbmNlb2YgUmVjdGFuZ2xlICYmICh0eXBlICYgKEFmZmluZVRyYW5zZm9ybS5UWVBFX0lERU5USVRZIHwKKyAgICAgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0uVFlQRV9UUkFOU0xBVElPTikpICE9IDApeworICAgICAgICAgICAgICAgICAgICBtcmEgPSBuZXcgTXVsdGlSZWN0QXJlYSgoUmVjdGFuZ2xlKXMpOworICAgICAgICAgICAgICAgICAgICBpZih0eXBlID09IEFmZmluZVRyYW5zZm9ybS5UWVBFX1RSQU5TTEFUSU9OKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1yYS50cmFuc2xhdGUoKGludCl0cmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWCgpLCAoaW50KXRyYW5zZm9ybS5nZXRUcmFuc2xhdGVZKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHMgPSB0cmFuc2Zvcm0uY3JlYXRlVHJhbnNmb3JtZWRTaGFwZShzKTsKKyAgICAgICAgICAgICAgICBtcmEgPSBqc3IucmFzdGVyaXplKHMsIDAuNSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoY2xpcCA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRUcmFuc2Zvcm1lZENsaXAobXJhKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNsaXAuaW50ZXJzZWN0KG1yYSk7CisgICAgICAgICAgICBzZXRUcmFuc2Zvcm1lZENsaXAoY2xpcCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICAvLyBEbyBub3RoaW5nIGZvciBKYXZhIG9ubHkgY2xhc3NlcworICAgIH0KKworCisKKworICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAgICAgKgorICAgICAqICBEcmF3IG1ldGhvZHMKKyAgICAgKgorICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3KFNoYXBlIHMpIHsKKyAgICAgICAgaWYgKHN0cm9rZSBpbnN0YW5jZW9mIEJhc2ljU3Ryb2tlICYmICgoQmFzaWNTdHJva2Upc3Ryb2tlKS5nZXRMaW5lV2lkdGgoKSA8PSAxKSB7CisgICAgICAgICAgICAvL1RPRE86IFRoaW5rIGFib3V0IGRyYXdpbmcgdGhlIHNoYXBlIGluIG9uZSBmaWxsTXVsdGlSZWN0QXJlYSBjYWxsCisgICAgICAgICAgICBCYXNpY1N0cm9rZSBic3Ryb2tlID0gKEJhc2ljU3Ryb2tlKXN0cm9rZTsKKyAgICAgICAgICAgIEphdmFMaW5lUmFzdGVyaXplci5MaW5lRGFzaGVyIGxkID0gKGJzdHJva2UuZ2V0RGFzaEFycmF5KCkgPT0gbnVsbCk/bnVsbDpuZXcgSmF2YUxpbmVSYXN0ZXJpemVyLkxpbmVEYXNoZXIoYnN0cm9rZS5nZXREYXNoQXJyYXkoKSwgYnN0cm9rZS5nZXREYXNoUGhhc2UoKSk7CisgICAgICAgICAgICBQYXRoSXRlcmF0b3IgcGkgPSBzLmdldFBhdGhJdGVyYXRvcih0cmFuc2Zvcm0sIDAuNSk7CisgICAgICAgICAgICBmbG9hdCBbXXBvaW50cyA9IG5ldyBmbG9hdFs2XTsKKyAgICAgICAgICAgIGludCB4MSA9IEludGVnZXIuTUlOX1ZBTFVFOworICAgICAgICAgICAgaW50IHkxID0gSW50ZWdlci5NSU5fVkFMVUU7CisgICAgICAgICAgICBpbnQgY3gxID0gSW50ZWdlci5NSU5fVkFMVUU7CisgICAgICAgICAgICBpbnQgY3kxID0gSW50ZWdlci5NSU5fVkFMVUU7CisgICAgICAgICAgICB3aGlsZSAoIXBpLmlzRG9uZSgpKSB7CisgICAgICAgICAgICAgICAgc3dpdGNoIChwaS5jdXJyZW50U2VnbWVudChwb2ludHMpKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE86CisgICAgICAgICAgICAgICAgICAgICAgICB4MSA9IChpbnQpTWF0aC5mbG9vcihwb2ludHNbMF0pOworICAgICAgICAgICAgICAgICAgICAgICAgeTEgPSAoaW50KU1hdGguZmxvb3IocG9pbnRzWzFdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGN4MSA9IHgxOworICAgICAgICAgICAgICAgICAgICAgICAgY3kxID0geTE7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0xJTkVUTzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCB4MiA9IChpbnQpTWF0aC5mbG9vcihwb2ludHNbMF0pOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IHkyID0gKGludClNYXRoLmZsb29yKHBvaW50c1sxXSk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYShKYXZhTGluZVJhc3Rlcml6ZXIucmFzdGVyaXplKHgxLCB5MSwgeDIsIHkyLCBudWxsLCBsZCwgZmFsc2UpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHgxID0geDI7CisgICAgICAgICAgICAgICAgICAgICAgICB5MSA9IHkyOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DTE9TRToKKyAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gY3gxOworICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSBjeTE7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYShKYXZhTGluZVJhc3Rlcml6ZXIucmFzdGVyaXplKHgxLCB5MSwgeDIsIHkyLCBudWxsLCBsZCwgZmFsc2UpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHgxID0geDI7CisgICAgICAgICAgICAgICAgICAgICAgICB5MSA9IHkyOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBpLm5leHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHMgPSBzdHJva2UuY3JlYXRlU3Ryb2tlZFNoYXBlKHMpOworICAgICAgICAgICAgcyA9IHRyYW5zZm9ybS5jcmVhdGVUcmFuc2Zvcm1lZFNoYXBlKHMpOworICAgICAgICAgICAgZmlsbE11bHRpUmVjdEFyZWEoanNyLnJhc3Rlcml6ZShzLCAwLjUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdBcmMoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBzYSwgaW50IGVhKSB7CisgICAgICAgIGlmIChzdHJva2UgaW5zdGFuY2VvZiBCYXNpY1N0cm9rZSAmJiAoKEJhc2ljU3Ryb2tlKXN0cm9rZSkuZ2V0TGluZVdpZHRoKCkgPD0gMSAmJgorICAgICAgICAgICAgICAgICgoQmFzaWNTdHJva2Upc3Ryb2tlKS5nZXREYXNoQXJyYXkoKSA9PSBudWxsICYmIAorICAgICAgICAgICAgICAgICh0cmFuc2Zvcm0uaXNJZGVudGl0eSgpIHx8IHRyYW5zZm9ybS5nZXRUeXBlKCkgPT0gQWZmaW5lVHJhbnNmb3JtLlRZUEVfVFJBTlNMQVRJT04pKSB7CisgICAgICAgICAgICBQb2ludCBwID0gbmV3IFBvaW50KHgsIHkpOworICAgICAgICAgICAgdHJhbnNmb3JtLnRyYW5zZm9ybShwLCBwKTsKKyAgICAgICAgICAgIE11bHRpUmVjdEFyZWEgbXJhID0gSmF2YUFyY1Jhc3Rlcml6ZXIucmFzdGVyaXplKHgsIHksIHdpZHRoLCBoZWlnaHQsIHNhLCBlYSwgY2xpcCk7CisgICAgICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYShtcmEpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGRyYXcobmV3IEFyYzJELkZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQsIHNhLCBlYSwgQXJjMkQuT1BFTikpOworICAgIH0KKworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltYWdlLCBpbnQgeCwgaW50IHksIENvbG9yIGJnY29sb3IsCisgICAgICAgICAgICBJbWFnZU9ic2VydmVyIGltYWdlT2JzZXJ2ZXIpIHsKKworICAgICAgICBpZihpbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworICAgICAgICBib29sZWFuIHNvbWViaXRzID0gZmFsc2U7CisgICAgICAgIFN1cmZhY2Ugc3JjU3VyZiA9IG51bGw7CisgICAgICAgIGlmKGltYWdlIGluc3RhbmNlb2YgT2Zmc2NyZWVuSW1hZ2UpeworICAgICAgICAgICAgT2Zmc2NyZWVuSW1hZ2Ugb2kgPSAoT2Zmc2NyZWVuSW1hZ2UpIGltYWdlOworICAgICAgICAgICAgaWYoKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLkVSUk9SKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZG9uZSA9IG9pLnByZXBhcmVJbWFnZShpbWFnZU9ic2VydmVyKTsKKyAgICAgICAgICAgIHNvbWViaXRzID0gKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLlNPTUVCSVRTKSAhPSAwOworICAgICAgICAgICAgc3JjU3VyZiA9IG9pLmdldEltYWdlU3VyZmFjZSgpOworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgc3JjU3VyZiA9IFN1cmZhY2UuZ2V0SW1hZ2VTdXJmYWNlKGltYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKGRvbmUgfHwgc29tZWJpdHMpIHsKKyAgICAgICAgICAgIGludCB3ID0gc3JjU3VyZi5nZXRXaWR0aCgpOworICAgICAgICAgICAgaW50IGggPSBzcmNTdXJmLmdldEhlaWdodCgpOworICAgICAgICAgICAgYmxpdHRlci5ibGl0KDAsIDAsIHNyY1N1cmYsIHgsIHksIGRzdFN1cmYsIHcsIGgsIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGUsIGJnY29sb3IsIGNsaXApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkb25lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgaW50IHgsIGludCB5LCBJbWFnZU9ic2VydmVyIGltYWdlT2JzZXJ2ZXIpIHsKKyAgICAgICAgcmV0dXJuIGRyYXdJbWFnZShpbWFnZSwgeCwgeSwgbnVsbCwgaW1hZ2VPYnNlcnZlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltYWdlLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgIENvbG9yIGJnY29sb3IsIEltYWdlT2JzZXJ2ZXIgaW1hZ2VPYnNlcnZlcikgeworCisgICAgICAgIGlmKGltYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gc29tZWJpdHMgPSBmYWxzZTsKKyAgICAgICAgU3VyZmFjZSBzcmNTdXJmID0gbnVsbDsKKworICAgICAgICBpZihpbWFnZSBpbnN0YW5jZW9mIE9mZnNjcmVlbkltYWdlKXsKKyAgICAgICAgICAgIE9mZnNjcmVlbkltYWdlIG9pID0gKE9mZnNjcmVlbkltYWdlKSBpbWFnZTsKKyAgICAgICAgICAgIGlmKChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5FUlJPUikgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRvbmUgPSBvaS5wcmVwYXJlSW1hZ2UoaW1hZ2VPYnNlcnZlcik7CisgICAgICAgICAgICBzb21lYml0cyA9IChvaS5nZXRTdGF0ZSgpICYgSW1hZ2VPYnNlcnZlci5TT01FQklUUykgIT0gMDsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBvaS5nZXRJbWFnZVN1cmZhY2UoKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShpbWFnZSk7CisgICAgICAgIH0KKworICAgICAgICBpZihkb25lIHx8IHNvbWViaXRzKSB7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGlmKHcgPT0gd2lkdGggJiYgaCA9PSBoZWlnaHQpeworICAgICAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgKEFmZmluZVRyYW5zZm9ybSkgdHJhbnNmb3JtLmNsb25lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGUsIGJnY29sb3IsIGNsaXApOworICAgICAgICAgICAgfWVsc2V7CisgICAgICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICAgICAgICAgIHhmb3JtLnNldFRvU2NhbGUoKGZsb2F0KXdpZHRoIC8gdywgKGZsb2F0KWhlaWdodCAvIGgpOworICAgICAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgKEFmZmluZVRyYW5zZm9ybSkgdHJhbnNmb3JtLmNsb25lKCksCisgICAgICAgICAgICAgICAgICAgICAgICB4Zm9ybSwgY29tcG9zaXRlLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZG9uZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBkcmF3SW1hZ2UoSW1hZ2UgaW1hZ2UsIGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisgICAgICAgIHJldHVybiBkcmF3SW1hZ2UoaW1hZ2UsIHgsIHksIHdpZHRoLCBoZWlnaHQsIG51bGwsIGltYWdlT2JzZXJ2ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgaW50IGR4MSwgaW50IGR5MSwgaW50IGR4MiwgaW50IGR5MiwKKyAgICAgICAgICAgIGludCBzeDEsIGludCBzeTEsIGludCBzeDIsIGludCBzeTIsIENvbG9yIGJnY29sb3IsCisgICAgICAgICAgICBJbWFnZU9ic2VydmVyIGltYWdlT2JzZXJ2ZXIpIHsKKworICAgICAgICBpZihpbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZihkeDEgPT0gZHgyIHx8IGR5MSA9PSBkeTIgfHwgc3gxID09IHN4MiB8fCBzeTEgPT0gc3kyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworICAgICAgICBib29sZWFuIHNvbWViaXRzID0gZmFsc2U7CisgICAgICAgIFN1cmZhY2Ugc3JjU3VyZiA9IG51bGw7CisgICAgICAgIGlmKGltYWdlIGluc3RhbmNlb2YgT2Zmc2NyZWVuSW1hZ2UpeworICAgICAgICAgICAgT2Zmc2NyZWVuSW1hZ2Ugb2kgPSAoT2Zmc2NyZWVuSW1hZ2UpIGltYWdlOworICAgICAgICAgICAgaWYoKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLkVSUk9SKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZG9uZSA9IG9pLnByZXBhcmVJbWFnZShpbWFnZU9ic2VydmVyKTsKKyAgICAgICAgICAgIHNvbWViaXRzID0gKG9pLmdldFN0YXRlKCkgJiBJbWFnZU9ic2VydmVyLlNPTUVCSVRTKSAhPSAwOworICAgICAgICAgICAgc3JjU3VyZiA9IG9pLmdldEltYWdlU3VyZmFjZSgpOworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgc3JjU3VyZiA9IFN1cmZhY2UuZ2V0SW1hZ2VTdXJmYWNlKGltYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKGRvbmUgfHwgc29tZWJpdHMpIHsKKworICAgICAgICAgICAgaW50IGRzdFggPSBkeDE7CisgICAgICAgICAgICBpbnQgZHN0WSA9IGR5MTsKKyAgICAgICAgICAgIGludCBzcmNYID0gc3gxOworICAgICAgICAgICAgaW50IHNyY1kgPSBzeTE7CisKKyAgICAgICAgICAgIGludCBkc3RXID0gZHgyIC0gZHgxOworICAgICAgICAgICAgaW50IGRzdEggPSBkeTIgLSBkeTE7CisgICAgICAgICAgICBpbnQgc3JjVyA9IHN4MiAtIHN4MTsKKyAgICAgICAgICAgIGludCBzcmNIID0gc3kyIC0gc3kxOworCisgICAgICAgICAgICBpZihzcmNXID09IGRzdFcgJiYgc3JjSCA9PSBkc3RIKXsKKyAgICAgICAgICAgICAgICBibGl0dGVyLmJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwgc3JjVywgc3JjSCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRlLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSA9IG5ldyBBZmZpbmVUcmFuc2Zvcm0oKTsKKyAgICAgICAgICAgICAgICB4Zm9ybS5zZXRUb1NjYWxlKChmbG9hdClkc3RXIC8gc3JjVywgKGZsb2F0KWRzdEggLyBzcmNIKTsKKyAgICAgICAgICAgICAgICBibGl0dGVyLmJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwgc3JjVywgc3JjSCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBZmZpbmVUcmFuc2Zvcm0pIHRyYW5zZm9ybS5jbG9uZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgeGZvcm0sIGNvbXBvc2l0ZSwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRvbmU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZHJhd0ltYWdlKEltYWdlIGltYWdlLCBpbnQgZHgxLCBpbnQgZHkxLCBpbnQgZHgyLCBpbnQgZHkyLAorICAgICAgICAgICAgaW50IHN4MSwgaW50IHN5MSwgaW50IHN4MiwgaW50IHN5MiwgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisKKyAgICAgICAgcmV0dXJuIGRyYXdJbWFnZShpbWFnZSwgZHgxLCBkeTEsIGR4MiwgZHkyLCBzeDEsIHN5MSwgc3gyLCBzeTIsIG51bGwsCisgICAgICAgICAgICAgICAgaW1hZ2VPYnNlcnZlcik7CisgICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdJbWFnZShCdWZmZXJlZEltYWdlIGJ1ZkltYWdlLCBCdWZmZXJlZEltYWdlT3Agb3AsCisgICAgICAgICAgICBpbnQgeCwgaW50IHkpIHsKKworICAgICAgICBpZihidWZJbWFnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZihvcCA9PSBudWxsKSB7CisgICAgICAgICAgICBkcmF3SW1hZ2UoYnVmSW1hZ2UsIHgsIHksIG51bGwpOworICAgICAgICB9IGVsc2UgaWYob3AgaW5zdGFuY2VvZiBBZmZpbmVUcmFuc2Zvcm1PcCl7CisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm1PcCBhdG9wID0gKEFmZmluZVRyYW5zZm9ybU9wKSBvcDsKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSA9IGF0b3AuZ2V0VHJhbnNmb3JtKCk7CisgICAgICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShidWZJbWFnZSk7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKSwgeGZvcm0sCisgICAgICAgICAgICAgICAgICAgIGNvbXBvc2l0ZSwgbnVsbCwgY2xpcCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWZJbWFnZSA9IG9wLmZpbHRlcihidWZJbWFnZSwgbnVsbCk7CisgICAgICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZShidWZJbWFnZSk7CisgICAgICAgICAgICBpbnQgdyA9IHNyY1N1cmYuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCB4LCB5LCBkc3RTdXJmLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKSwKKyAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRlLCBudWxsLCBjbGlwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRyYXdJbWFnZShJbWFnZSBpbWFnZSwgQWZmaW5lVHJhbnNmb3JtIHRyYW5zLAorICAgICAgICAgICAgSW1hZ2VPYnNlcnZlciBpbWFnZU9ic2VydmVyKSB7CisKKyAgICAgICAgaWYoaW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYodHJhbnMgPT0gbnVsbCB8fCB0cmFucy5pc0lkZW50aXR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBkcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIGltYWdlT2JzZXJ2ZXIpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gc29tZWJpdHMgPSBmYWxzZTsKKyAgICAgICAgU3VyZmFjZSBzcmNTdXJmID0gbnVsbDsKKyAgICAgICAgaWYoaW1hZ2UgaW5zdGFuY2VvZiBPZmZzY3JlZW5JbWFnZSl7CisgICAgICAgICAgICBPZmZzY3JlZW5JbWFnZSBvaSA9IChPZmZzY3JlZW5JbWFnZSkgaW1hZ2U7CisgICAgICAgICAgICBpZigob2kuZ2V0U3RhdGUoKSAmIEltYWdlT2JzZXJ2ZXIuRVJST1IpICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkb25lID0gb2kucHJlcGFyZUltYWdlKGltYWdlT2JzZXJ2ZXIpOworICAgICAgICAgICAgc29tZWJpdHMgPSAob2kuZ2V0U3RhdGUoKSAmIEltYWdlT2JzZXJ2ZXIuU09NRUJJVFMpICE9IDA7CisgICAgICAgICAgICBzcmNTdXJmID0gb2kuZ2V0SW1hZ2VTdXJmYWNlKCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICBzcmNTdXJmID0gU3VyZmFjZS5nZXRJbWFnZVN1cmZhY2UoaW1hZ2UpOworICAgICAgICB9CisKKyAgICAgICAgaWYoZG9uZSB8fCBzb21lYml0cykgeworICAgICAgICAgICAgaW50IHcgPSBzcmNTdXJmLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQgaCA9IHNyY1N1cmYuZ2V0SGVpZ2h0KCk7CisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0geGZvcm0gPSAoQWZmaW5lVHJhbnNmb3JtKSB0cmFuc2Zvcm0uY2xvbmUoKTsKKyAgICAgICAgICAgIHhmb3JtLmNvbmNhdGVuYXRlKHRyYW5zKTsKKyAgICAgICAgICAgIGJsaXR0ZXIuYmxpdCgwLCAwLCBzcmNTdXJmLCAwLCAwLCBkc3RTdXJmLCB3LCBoLCB4Zm9ybSwgY29tcG9zaXRlLAorICAgICAgICAgICAgICAgICAgICBudWxsLCBjbGlwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZG9uZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3TGluZShpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIpIHsKKyAgICAgICAgaWYgKGRlYnVnT3V0cHV0KSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbW1vbkdyYXBoaWNzMkQuZHJhd0xpbmUoIit4MSsiLCAiK3kxKyIsICIreDIrIiwgIit5MisiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkIC8vJE5PTi1OTFMtNSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdHJva2UgaW5zdGFuY2VvZiBCYXNpY1N0cm9rZSAmJiAoKEJhc2ljU3Ryb2tlKXN0cm9rZSkuZ2V0TGluZVdpZHRoKCkgPD0gMSkgeworICAgICAgICAgICAgQmFzaWNTdHJva2UgYnN0cm9rZSA9IChCYXNpY1N0cm9rZSlzdHJva2U7CisgICAgICAgICAgICBQb2ludCBwMSA9IG5ldyBQb2ludCh4MSwgeTEpOworICAgICAgICAgICAgUG9pbnQgcDIgPSBuZXcgUG9pbnQoeDIsIHkyKTsKKyAgICAgICAgICAgIHRyYW5zZm9ybS50cmFuc2Zvcm0ocDEsIHAxKTsKKyAgICAgICAgICAgIHRyYW5zZm9ybS50cmFuc2Zvcm0ocDIsIHAyKTsKKyAgICAgICAgICAgIEphdmFMaW5lUmFzdGVyaXplci5MaW5lRGFzaGVyIGxkID0gKGJzdHJva2UuZ2V0RGFzaEFycmF5KCkgPT0gbnVsbCk/bnVsbDpuZXcgSmF2YUxpbmVSYXN0ZXJpemVyLkxpbmVEYXNoZXIoYnN0cm9rZS5nZXREYXNoQXJyYXkoKSwgYnN0cm9rZS5nZXREYXNoUGhhc2UoKSk7CisgICAgICAgICAgICBNdWx0aVJlY3RBcmVhIG1yYSA9IEphdmFMaW5lUmFzdGVyaXplci5yYXN0ZXJpemUocDEueCwgcDEueSwgcDIueCwgcDIueSwgbnVsbCwgbGQsIGZhbHNlKTsKKyAgICAgICAgICAgIGZpbGxNdWx0aVJlY3RBcmVhKG1yYSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZHJhdyhuZXcgTGluZTJELkZsb2F0KHgxLCB5MSwgeDIsIHkyKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd092YWwoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgaWYgKHN0cm9rZSBpbnN0YW5jZW9mIEJhc2ljU3Ryb2tlICYmICgoQmFzaWNTdHJva2Upc3Ryb2tlKS5nZXRMaW5lV2lkdGgoKSA8PSAxICYmCisgICAgICAgICAgICAgICAgKChCYXNpY1N0cm9rZSlzdHJva2UpLmdldERhc2hBcnJheSgpID09IG51bGwgJiYgCisgICAgICAgICAgICAgICAgKHRyYW5zZm9ybS5pc0lkZW50aXR5KCkgfHwgdHJhbnNmb3JtLmdldFR5cGUoKSA9PSBBZmZpbmVUcmFuc2Zvcm0uVFlQRV9UUkFOU0xBVElPTikpIHsKKyAgICAgICAgICAgIFBvaW50IHAgPSBuZXcgUG9pbnQoeCwgeSk7CisgICAgICAgICAgICB0cmFuc2Zvcm0udHJhbnNmb3JtKHAsIHApOworICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBtcmEgPSBKYXZhQXJjUmFzdGVyaXplci5yYXN0ZXJpemUoeCwgeSwgd2lkdGgsIGhlaWdodCwgMCwgMzYwLCBjbGlwKTsKKyAgICAgICAgICAgIGZpbGxNdWx0aVJlY3RBcmVhKG1yYSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZHJhdyhuZXcgRWxsaXBzZTJELkZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3UG9seWdvbihpbnRbXSB4cG9pbnRzLCBpbnRbXSB5cG9pbnRzLCBpbnQgbnBvaW50cykgeworICAgICAgICBkcmF3KG5ldyBQb2x5Z29uKHhwb2ludHMsIHlwb2ludHMsIG5wb2ludHMpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3UG9seWdvbihQb2x5Z29uIHBvbHlnb24pIHsKKyAgICAgICAgZHJhdyhwb2x5Z29uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3UG9seWxpbmUoaW50W10geHBvaW50cywgaW50W10geXBvaW50cywgaW50IG5wb2ludHMpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBucG9pbnRzLTE7IGkrKykgeworICAgICAgICAgICAgZHJhd0xpbmUoeHBvaW50c1tpXSwgeXBvaW50c1tpXSwgeHBvaW50c1tpKzFdLCB5cG9pbnRzW2krMV0pOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1JlbmRlcmFibGVJbWFnZShSZW5kZXJhYmxlSW1hZ2UgaW1nLCBBZmZpbmVUcmFuc2Zvcm0geGZvcm0pIHsKKyAgICAgICAgaWYgKGltZyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgc2NhbGVYID0geGZvcm0uZ2V0U2NhbGVYKCk7CisgICAgICAgIGRvdWJsZSBzY2FsZVkgPSB4Zm9ybS5nZXRTY2FsZVkoKTsKKyAgICAgICAgaWYgKHNjYWxlWCA9PSAxICYmIHNjYWxlWSA9PSAxKSB7CisgICAgICAgICAgICBkcmF3UmVuZGVyZWRJbWFnZShpbWcuY3JlYXRlRGVmYXVsdFJlbmRlcmluZygpLCB4Zm9ybSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgd2lkdGggPSAoaW50KU1hdGgucm91bmQoaW1nLmdldFdpZHRoKCkqc2NhbGVYKTsKKyAgICAgICAgICAgIGludCBoZWlnaHQgPSAoaW50KU1hdGgucm91bmQoaW1nLmdldEhlaWdodCgpKnNjYWxlWSk7CisgICAgICAgICAgICB4Zm9ybSA9IChBZmZpbmVUcmFuc2Zvcm0peGZvcm0uY2xvbmUoKTsKKyAgICAgICAgICAgIHhmb3JtLnNjYWxlKDEsIDEpOworICAgICAgICAgICAgZHJhd1JlbmRlcmVkSW1hZ2UoaW1nLmNyZWF0ZVNjYWxlZFJlbmRlcmluZyh3aWR0aCwgaGVpZ2h0LCBudWxsKSwgeGZvcm0pOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1JlbmRlcmVkSW1hZ2UoUmVuZGVyZWRJbWFnZSByaW1nLCBBZmZpbmVUcmFuc2Zvcm0geGZvcm0pIHsKKyAgICAgICAgaWYgKHJpbWcgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgSW1hZ2UgaW1nID0gbnVsbDsKKworICAgICAgICBpZiAocmltZyBpbnN0YW5jZW9mIEltYWdlKSB7CisgICAgICAgICAgICBpbWcgPSAoSW1hZ2UpcmltZzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vVE9ETzogQ3JlYXRlIG5ldyBjbGFzcyB0byBwcm92aWRlIEltYWdlIGludGVyZmFjZSBmb3IgUmVuZGVyZWRJbWFnZSBvciByZXdyaXRlIHRoaXMgbWV0aG9kCisgICAgICAgICAgICBpbWcgPSBuZXcgQnVmZmVyZWRJbWFnZShyaW1nLmdldENvbG9yTW9kZWwoKSwgcmltZy5jb3B5RGF0YShudWxsKSwgZmFsc2UsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgZHJhd0ltYWdlKGltZywgeGZvcm0sIG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdSb3VuZFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBhcmNXaWR0aCwgaW50IGFyY0hlaWdodCkgeworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5kcmF3Um91bmRSZWN0KCIreCsiLCAiK3krIiwgIit3aWR0aCsiLCAiK2hlaWdodCsiLCIrYXJjV2lkdGgrIiwgIithcmNIZWlnaHQrIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkIC8vJE5PTi1OTFMtNiQgLy8kTk9OLU5MUy03JAorICAgICAgICB9CisKKyAgICAgICAgZHJhdyhuZXcgUm91bmRSZWN0YW5nbGUyRC5GbG9hdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBhcmNXaWR0aCwgYXJjSGVpZ2h0KSk7CisgICAgfQorCisKKworCisKKyAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICoKKyAgICAgKiAgU3RyaW5nIG1ldGhvZHMKKyAgICAgKgorICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkcmF3U3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvciwgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICBHbHlwaFZlY3RvciBndiA9IGZvbnQuY3JlYXRlR2x5cGhWZWN0b3IoZnJjLCBpdGVyYXRvcik7CisgICAgICAgIGRyYXdHbHlwaFZlY3RvcihndiwgeCwgeSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZHJhd1N0cmluZyhBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGludCB4LCBpbnQgeSkgeworICAgICAgICBkcmF3U3RyaW5nKGl0ZXJhdG9yLCAoZmxvYXQpeCwgKGZsb2F0KXkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdTdHJpbmcoU3RyaW5nIHN0ciwgaW50IHgsIGludCB5KSB7CisgICAgICAgIGRyYXdTdHJpbmcoc3RyLCAoZmxvYXQpeCwgKGZsb2F0KXkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdTdHJpbmcoU3RyaW5nIHN0ciwgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5kcmF3U3RyaW5nKCIrc3RyKyIsICIreCsiLCAiK3krIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JAorICAgICAgICB9CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gKEFmZmluZVRyYW5zZm9ybSl0aGlzLmdldFRyYW5zZm9ybSgpLmNsb25lKCk7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBmb250VHJhbnNmb3JtID0gZm9udC5nZXRUcmFuc2Zvcm0oKTsKKyAgICAgICAgYXQuY29uY2F0ZW5hdGUoZm9udFRyYW5zZm9ybSk7CisKKyAgICAgICAgZG91YmxlW10gbWF0cml4ID0gbmV3IGRvdWJsZVs2XTsKKyAgICAgICAgaWYgKCFhdC5pc0lkZW50aXR5KCkpeworCisgICAgICAgICAgICBpbnQgYXRUeXBlID0gYXQuZ2V0VHlwZSgpOworICAgICAgICAgICAgYXQuZ2V0TWF0cml4KG1hdHJpeCk7CisKKyAgICAgICAgICAgIC8vIFRZUEVfVFJBTlNMQVRJT04KKyAgICAgICAgICAgIGlmIChhdFR5cGUgPT0gQWZmaW5lVHJhbnNmb3JtLlRZUEVfVFJBTlNMQVRJT04peworICAgICAgICAgICAgICAgIGp0ci5kcmF3U3RyaW5nKHRoaXMsIHN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgIChmbG9hdCkoeCtmb250VHJhbnNmb3JtLmdldFRyYW5zbGF0ZVgoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAoZmxvYXQpKHkrZm9udFRyYW5zZm9ybS5nZXRUcmFuc2xhdGVZKCkpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBUT0RPOiB3ZSB1c2Ugc2xvdyB0eXBlIG9mIGRyYXdpbmcgc3RyaW5ncyB3aGVuIEZvbnQgb2JqZWN0CisgICAgICAgICAgICAvLyBpbiBHcmFwaGljcyBoYXMgdHJhbnNmb3Jtcywgd2UganVzdCBmaWxsIG91dGxpbmVzLiBOZXcgdGV4dHJlbmRlcmVyCisgICAgICAgICAgICAvLyBpcyB0byBiZSBpbXBsZW1lbnRlZC4KKyAgICAgICAgICAgIFNoYXBlIHNoID0gZm9udC5jcmVhdGVHbHlwaFZlY3Rvcih0aGlzLmdldEZvbnRSZW5kZXJDb250ZXh0KCksIHN0cikuZ2V0T3V0bGluZSh4LCB5KTsKKyAgICAgICAgICAgIHRoaXMuZmlsbChzaCk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGp0ci5kcmF3U3RyaW5nKHRoaXMsIHN0ciwgeCwgeSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdHbHlwaFZlY3RvcihHbHlwaFZlY3RvciBndiwgZmxvYXQgeCwgZmxvYXQgeSkgeworCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBhdCA9IGd2LmdldEZvbnQoKS5nZXRUcmFuc2Zvcm0oKTsKKworICAgICAgICBkb3VibGVbXSBtYXRyaXggPSBuZXcgZG91YmxlWzZdOworICAgICAgICBpZiAoKGF0ICE9IG51bGwpICYmICghYXQuaXNJZGVudGl0eSgpKSl7CisKKyAgICAgICAgICAgIGludCBhdFR5cGUgPSBhdC5nZXRUeXBlKCk7CisgICAgICAgICAgICBhdC5nZXRNYXRyaXgobWF0cml4KTsKKworICAgICAgICAgICAgLy8gVFlQRV9UUkFOU0xBVElPTgorICAgICAgICAgICAgaWYgKChhdFR5cGUgPT0gQWZmaW5lVHJhbnNmb3JtLlRZUEVfVFJBTlNMQVRJT04pICYmCisgICAgICAgICAgICAgICAgKChndi5nZXRMYXlvdXRGbGFncygpICYgR2x5cGhWZWN0b3IuRkxBR19IQVNfVFJBTlNGT1JNUykgPT0gMCkpeworICAgICAgICAgICAgICAgIGp0ci5kcmF3R2x5cGhWZWN0b3IodGhpcywgZ3YsIChpbnQpKHgrbWF0cml4WzRdKSwgKGludCkoeSttYXRyaXhbNV0pKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoKChndi5nZXRMYXlvdXRGbGFncygpICYgR2x5cGhWZWN0b3IuRkxBR19IQVNfVFJBTlNGT1JNUykgPT0gMCkpeworICAgICAgICAgICAgICAgIGp0ci5kcmF3R2x5cGhWZWN0b3IodGhpcywgZ3YsIHgsIHkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE86IHdlIHVzZSBzbG93IHR5cGUgb2YgZHJhd2luZyBzdHJpbmdzIHdoZW4gRm9udCBvYmplY3QKKyAgICAgICAgLy8gaW4gR3JhcGhpY3MgaGFzIHRyYW5zZm9ybXMsIHdlIGp1c3QgZmlsbCBvdXRsaW5lcy4gTmV3IHRleHRyZW5kZXJlcgorICAgICAgICAvLyBpcyB0byBiZSBpbXBsZW1lbnRlZC4KKworICAgICAgICBTaGFwZSBzaCA9IGd2LmdldE91dGxpbmUoeCwgeSk7CisgICAgICAgIHRoaXMuZmlsbChzaCk7CisKKyAgICAgICAgfQorCisKKworCisgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqCisgICAgICogIEZpbGwgbWV0aG9kcworICAgICAqCisgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGwoU2hhcGUgcykgeworICAgICAgICBzID0gdHJhbnNmb3JtLmNyZWF0ZVRyYW5zZm9ybWVkU2hhcGUocyk7CisgICAgICAgIE11bHRpUmVjdEFyZWEgbXJhID0ganNyLnJhc3Rlcml6ZShzLCAwLjUpOworICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYShtcmEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGxBcmMoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBzYSwgaW50IGVhKSB7CisgICAgICAgIGZpbGwobmV3IEFyYzJELkZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQsIHNhLCBlYSwgQXJjMkQuUElFKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmlsbE92YWwoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKKyAgICAgICAgZmlsbChuZXcgRWxsaXBzZTJELkZsb2F0KHgsIHksIHdpZHRoLCBoZWlnaHQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaWxsUG9seWdvbihpbnRbXSB4cG9pbnRzLCBpbnRbXSB5cG9pbnRzLCBpbnQgbnBvaW50cykgeworICAgICAgICBmaWxsKG5ldyBQb2x5Z29uKHhwb2ludHMsIHlwb2ludHMsIG5wb2ludHMpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaWxsUG9seWdvbihQb2x5Z29uIHBvbHlnb24pIHsKKyAgICAgICAgZmlsbChwb2x5Z29uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaWxsUmVjdChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5maWxsUmVjdCgiK3grIiwgIit5KyIsICIrd2lkdGgrIiwgIitoZWlnaHQrIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgIH0KKworICAgICAgICBmaWxsKG5ldyBSZWN0YW5nbGUoeCwgeSwgd2lkdGgsIGhlaWdodCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbGxSb3VuZFJlY3QoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBhcmNXaWR0aCwgaW50IGFyY0hlaWdodCkgeworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5maWxsUm91bmRSZWN0KCIreCsiLCAiK3krIiwgIit3aWR0aCsiLCAiK2hlaWdodCsiLCIrYXJjV2lkdGgrIiwgIithcmNIZWlnaHQrIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkIC8vJE5PTi1OTFMtNiQgLy8kTk9OLU5MUy03JAorICAgICAgICB9CisKKyAgICAgICAgZmlsbChuZXcgUm91bmRSZWN0YW5nbGUyRC5GbG9hdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBhcmNXaWR0aCwgYXJjSGVpZ2h0KSk7CisgICAgfQorCisKKworCisgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqCisgICAgICogIEdldCBtZXRob2RzCisgICAgICoKKyAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbG9yIGdldEJhY2tncm91bmQoKSB7CisgICAgICAgIHJldHVybiBiZ0NvbG9yOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaGFwZSBnZXRDbGlwKCkgeworICAgICAgICBpZiAoY2xpcCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIE11bHRpUmVjdEFyZWEgcmVzID0gbmV3IE11bHRpUmVjdEFyZWEoY2xpcCk7CisgICAgICAgIHJlcy50cmFuc2xhdGUoLU1hdGgucm91bmQoKGZsb2F0KXRyYW5zZm9ybS5nZXRUcmFuc2xhdGVYKCkpLCAtTWF0aC5yb3VuZCgoZmxvYXQpdHJhbnNmb3JtLmdldFRyYW5zbGF0ZVkoKSkpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpcEJvdW5kcygpIHsKKyAgICAgICAgaWYgKGNsaXAgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBSZWN0YW5nbGUgcmVzID0gKFJlY3RhbmdsZSkgY2xpcC5nZXRCb3VuZHMoKS5jbG9uZSgpOworICAgICAgICByZXMudHJhbnNsYXRlKC1NYXRoLnJvdW5kKChmbG9hdCl0cmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWCgpKSwgLU1hdGgucm91bmQoKGZsb2F0KXRyYW5zZm9ybS5nZXRUcmFuc2xhdGVZKCkpKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sb3IgZ2V0Q29sb3IoKSB7CisgICAgICAgIHJldHVybiBmZ0NvbG9yOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb21wb3NpdGUgZ2V0Q29tcG9zaXRlKCkgeworICAgICAgICByZXR1cm4gY29tcG9zaXRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250IGdldEZvbnQoKSB7CisgICAgICAgIHJldHVybiBmb250OworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQgZm9udCkgeworICAgICAgICByZXR1cm4gVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpLmdldEZvbnRNZXRyaWNzKGZvbnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250UmVuZGVyQ29udGV4dCBnZXRGb250UmVuZGVyQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGZyYzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUGFpbnQgZ2V0UGFpbnQoKSB7CisgICAgICAgIHJldHVybiBwYWludDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlbmRlcmluZ0hpbnQoUmVuZGVyaW5nSGludHMuS2V5IGtleSkgeworICAgICAgICByZXR1cm4gaGludHMuZ2V0KGtleSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlbmRlcmluZ0hpbnRzIGdldFJlbmRlcmluZ0hpbnRzKCkgeworICAgICAgICByZXR1cm4gaGludHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cm9rZSBnZXRTdHJva2UoKSB7CisgICAgICAgIHJldHVybiBzdHJva2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEFmZmluZVRyYW5zZm9ybSBnZXRUcmFuc2Zvcm0oKSB7CisgICAgICAgIHJldHVybiAoQWZmaW5lVHJhbnNmb3JtKXRyYW5zZm9ybS5jbG9uZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhpdChSZWN0YW5nbGUgcmVjdCwgU2hhcGUgcywgYm9vbGVhbiBvblN0cm9rZSkgeworICAgICAgICAvL1RPRE86IEltcGxlbWVudCBtZXRob2QuLi4uCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKworCisKKyAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICoKKyAgICAgKiAgVHJhbnNmb3JtYXRpb24gbWV0aG9kcworICAgICAqCisgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJvdGF0ZShkb3VibGUgdGhldGEpIHsKKyAgICAgICAgdHJhbnNmb3JtLnJvdGF0ZSh0aGV0YSk7CisgICAgICAgIHRyYW5zZm9ybS5nZXRNYXRyaXgobWF0cml4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByb3RhdGUoZG91YmxlIHRoZXRhLCBkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgdHJhbnNmb3JtLnJvdGF0ZSh0aGV0YSwgeCwgeSk7CisgICAgICAgIHRyYW5zZm9ybS5nZXRNYXRyaXgobWF0cml4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzY2FsZShkb3VibGUgc3gsIGRvdWJsZSBzeSkgeworICAgICAgICB0cmFuc2Zvcm0uc2NhbGUoc3gsIHN5KTsKKyAgICAgICAgdHJhbnNmb3JtLmdldE1hdHJpeChtYXRyaXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNoZWFyKGRvdWJsZSBzaHgsIGRvdWJsZSBzaHkpIHsKKyAgICAgICAgdHJhbnNmb3JtLnNoZWFyKHNoeCwgc2h5KTsKKyAgICAgICAgdHJhbnNmb3JtLmdldE1hdHJpeChtYXRyaXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0gYXQpIHsKKyAgICAgICAgdHJhbnNmb3JtLmNvbmNhdGVuYXRlKGF0KTsKKyAgICAgICAgdHJhbnNmb3JtLmdldE1hdHJpeChtYXRyaXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShkb3VibGUgdHgsIGRvdWJsZSB0eSkgeworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC50cmFuc2xhdGUoIit0eCsiLCAiK3R5KyIpIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCisgICAgICAgIH0KKworICAgICAgICB0cmFuc2Zvcm0udHJhbnNsYXRlKHR4LCB0eSk7CisgICAgICAgIHRyYW5zZm9ybS5nZXRNYXRyaXgobWF0cml4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoaW50IHR4LCBpbnQgdHkpIHsKKyAgICAgICAgaWYgKGRlYnVnT3V0cHV0KSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbW1vbkdyYXBoaWNzMkQudHJhbnNsYXRlKCIrdHgrIiwgIit0eSsiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgICAgICB9CisKKyAgICAgICAgdHJhbnNmb3JtLnRyYW5zbGF0ZSh0eCwgdHkpOworICAgICAgICB0cmFuc2Zvcm0uZ2V0TWF0cml4KG1hdHJpeCk7CisgICAgfQorCisKKworCisgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqCisgICAgICogIFNldCBtZXRob2RzCisgICAgICoKKyAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZChDb2xvciBjb2xvcikgeworICAgICAgICBiZ0NvbG9yID0gY29sb3I7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2xpcChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworICAgICAgICBzZXRDbGlwKG5ldyBSZWN0YW5nbGUoeCwgeSwgd2lkdGgsIGhlaWdodCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENsaXAoU2hhcGUgcykgeworICAgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRUcmFuc2Zvcm1lZENsaXAobnVsbCk7CisgICAgICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbW1vbkdyYXBoaWNzMkQuc2V0Q2xpcChudWxsKSIpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5zZXRDbGlwKCIrcy5nZXRCb3VuZHMoKSsiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzIGluc3RhbmNlb2YgTXVsdGlSZWN0QXJlYSkgeworICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBuY2xpcCA9IG5ldyBNdWx0aVJlY3RBcmVhKChNdWx0aVJlY3RBcmVhKXMpOworICAgICAgICAgICAgbmNsaXAudHJhbnNsYXRlKE1hdGgucm91bmQoKGZsb2F0KXRyYW5zZm9ybS5nZXRUcmFuc2xhdGVYKCkpLCBNYXRoLnJvdW5kKChmbG9hdCl0cmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWSgpKSk7CisgICAgICAgICAgICBzZXRUcmFuc2Zvcm1lZENsaXAobmNsaXApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IHR5cGUgPSB0cmFuc2Zvcm0uZ2V0VHlwZSgpOworICAgICAgICAgICAgaWYocyBpbnN0YW5jZW9mIFJlY3RhbmdsZSAmJiAodHlwZSAmIChBZmZpbmVUcmFuc2Zvcm0uVFlQRV9JREVOVElUWSB8CisgICAgICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtLlRZUEVfVFJBTlNMQVRJT04pKSAhPSAwKXsKKyAgICAgICAgICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBuY2xpcCA9IG5ldyBNdWx0aVJlY3RBcmVhKChSZWN0YW5nbGUpcyk7CisgICAgICAgICAgICAgICAgICAgIGlmKHR5cGUgPT0gQWZmaW5lVHJhbnNmb3JtLlRZUEVfVFJBTlNMQVRJT04peworICAgICAgICAgICAgICAgICAgICAgICAgbmNsaXAudHJhbnNsYXRlKChpbnQpdHJhbnNmb3JtLmdldFRyYW5zbGF0ZVgoKSwgKGludCl0cmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzZXRUcmFuc2Zvcm1lZENsaXAobmNsaXApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzID0gdHJhbnNmb3JtLmNyZWF0ZVRyYW5zZm9ybWVkU2hhcGUocyk7CisgICAgICAgICAgICAgICAgc2V0VHJhbnNmb3JtZWRDbGlwKGpzci5yYXN0ZXJpemUocywgMC41KSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2xvcihDb2xvciBjb2xvcikgeworICAgICAgICBpZiAoY29sb3IgIT0gbnVsbCkgeworICAgICAgICAgICAgZmdDb2xvciA9IGNvbG9yOworICAgICAgICAgICAgcGFpbnQgPSBjb2xvcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbXBvc2l0ZShDb21wb3NpdGUgY29tcG9zaXRlKSB7CisgICAgICAgIHRoaXMuY29tcG9zaXRlID0gY29tcG9zaXRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZvbnQoRm9udCBmb250KSB7CisgICAgICAgIHRoaXMuZm9udCA9IGZvbnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGFpbnQoUGFpbnQgcGFpbnQpIHsKKyAgICAgICAgaWYgKHBhaW50ID09IG51bGwpCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAKKyAgICAgICAgdGhpcy5wYWludCA9IHBhaW50OworICAgICAgICBpZiAocGFpbnQgaW5zdGFuY2VvZiBDb2xvcikgeworICAgICAgICAgICAgZmdDb2xvciA9IChDb2xvcilwYWludDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBhaW50TW9kZSgpIHsKKyAgICAgICAgY29tcG9zaXRlID0gQWxwaGFDb21wb3NpdGUuU3JjT3ZlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSZW5kZXJpbmdIaW50KFJlbmRlcmluZ0hpbnRzLktleSBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBoaW50cy5wdXQoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVuZGVyaW5nSGludHMoTWFwPD8sPz4gaGludHMpIHsKKyAgICAgICAgdGhpcy5oaW50cy5jbGVhcigpOworICAgICAgICB0aGlzLmhpbnRzLnB1dEFsbChoaW50cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U3Ryb2tlKFN0cm9rZSBzdHJva2UpIHsKKyAgICAgICAgdGhpcy5zdHJva2UgPSBzdHJva2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VHJhbnNmb3JtKEFmZmluZVRyYW5zZm9ybSB0cmFuc2Zvcm0pIHsKKyAgICAgICAgdGhpcy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07CisKKyAgICAgICAgdHJhbnNmb3JtLmdldE1hdHJpeChtYXRyaXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFhPUk1vZGUoQ29sb3IgY29sb3IpIHsKKyAgICAgICAgY29tcG9zaXRlID0gbmV3IFhPUkNvbXBvc2l0ZShjb2xvcik7CisgICAgfQorCisKKyAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcworICAgIHByb3RlY3RlZCB2b2lkIHNldFRyYW5zZm9ybWVkQ2xpcChNdWx0aVJlY3RBcmVhIGNsaXApIHsKKyAgICAgICAgdGhpcy5jbGlwID0gY2xpcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBmaWxscyB0aGUgZ2l2ZW4gTXVsdGlSZWN0QXJlYSB3aXRoIGN1cnJlbnQgcGFpbnQuCisgICAgICogSXQgY2FsbHMgZmlsbE11bHRpUmVjdEFyZWFDb2xvciBhbmQgZmlsbE11bHRpUmVjdEFyZWFQYWludCAKKyAgICAgKiBtZXRob2RzIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBjdXJyZW50IHBhaW50LgorICAgICAqIEBwYXJhbSBtcmEgTXVsdGlSZWN0QXJlYSB0byBmaWxsCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmlsbE11bHRpUmVjdEFyZWEoTXVsdGlSZWN0QXJlYSBtcmEpIHsKKyAgICAgICAgaWYgKGNsaXAgIT0gbnVsbCkgeworICAgICAgICAgICAgbXJhLmludGVyc2VjdChjbGlwKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJldHVybiBpZiBhbGwgc3R1ZmYgaXMgY2xpcHBlZAorICAgICAgICBpZiAobXJhLnJlY3RbMF0gPCA1KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVidWdPdXRwdXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tbW9uR3JhcGhpY3MyRC5maWxsTXVsdGlSZWN0QXJlYSgiK21yYSsiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwYWludCBpbnN0YW5jZW9mIENvbG9yKXsKKyAgICAgICAgICAgIGZpbGxNdWx0aVJlY3RBcmVhQ29sb3IobXJhKTsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYVBhaW50KG1yYSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBmaWxscyB0aGUgZ2l2ZW4gTXVsdGlSZWN0QXJlYSB3aXRoIHNvbGlkIGNvbG9yLgorICAgICAqIEBwYXJhbSBtcmEgTXVsdGlSZWN0QXJlYSB0byBmaWxsCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmlsbE11bHRpUmVjdEFyZWFDb2xvcihNdWx0aVJlY3RBcmVhIG1yYSkgeworICAgICAgICBmaWxsTXVsdGlSZWN0QXJlYVBhaW50KG1yYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZmlsbHMgdGhlIGdpdmVuIE11bHRpUmVjdEFyZWEgd2l0aCBhbnkgcGFpbnQuCisgICAgICogQHBhcmFtIG1yYSBNdWx0aVJlY3RBcmVhIHRvIGZpbGwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmaWxsTXVsdGlSZWN0QXJlYVBhaW50KE11bHRpUmVjdEFyZWEgbXJhKSB7CisgICAgICAgIFJlY3RhbmdsZSByZWMgPSBtcmEuZ2V0Qm91bmRzKCk7CisgICAgICAgIGludCB4ID0gcmVjLng7CisgICAgICAgIGludCB5ID0gcmVjLnk7CisgICAgICAgIGludCB3ID0gcmVjLndpZHRoOworICAgICAgICBpbnQgaCA9IHJlYy5oZWlnaHQ7CisgICAgICAgIGlmKHcgPD0gMCB8fCBoIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQYWludENvbnRleHQgcGMgPSBwYWludC5jcmVhdGVDb250ZXh0KG51bGwsIHJlYywgcmVjLCB0cmFuc2Zvcm0sIGhpbnRzKTsKKyAgICAgICAgUmFzdGVyIHIgPSBwYy5nZXRSYXN0ZXIoeCwgeSwgdywgaCk7CisgICAgICAgIFdyaXRhYmxlUmFzdGVyIHdyOworICAgICAgICBpZihyIGluc3RhbmNlb2YgV3JpdGFibGVSYXN0ZXIpeworICAgICAgICAgICAgd3IgPSAoV3JpdGFibGVSYXN0ZXIpIHI7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgd3IgPSByLmNyZWF0ZUNvbXBhdGlibGVXcml0YWJsZVJhc3RlcigpOworICAgICAgICAgICAgd3Iuc2V0UmVjdChyKTsKKyAgICAgICAgfQorICAgICAgICBTdXJmYWNlIHNyY1N1cmYgPSBuZXcgSW1hZ2VTdXJmYWNlKHBjLmdldENvbG9yTW9kZWwoKSwgd3IpOworICAgICAgICBibGl0dGVyLmJsaXQoMCwgMCwgc3JjU3VyZiwgeCwgeSwgZHN0U3VyZiwgdywgaCwKKyAgICAgICAgICAgICAgICBjb21wb3NpdGUsIG51bGwsIG1yYSk7CisgICAgICAgIHNyY1N1cmYuZGlzcG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBncmFwaGljcyBjbGFzcyBmaWVsZHMuIAorICAgICAqIFVzZWQgaW4gY3JlYXRlIG1ldGhvZAorICAgICAqIAorICAgICAqIEBwYXJhbSBjb3B5IEdyYXBoaWNzIGNsYXNzIHRvIGNvcHkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3B5SW50ZXJuYWxGaWVsZHMoQ29tbW9uR3JhcGhpY3MyRCBjb3B5KSB7CisgICAgICAgIGlmIChjbGlwID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvcHkuc2V0VHJhbnNmb3JtZWRDbGlwKG51bGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29weS5zZXRUcmFuc2Zvcm1lZENsaXAobmV3IE11bHRpUmVjdEFyZWEoY2xpcCkpOworICAgICAgICB9CisgICAgICAgIGNvcHkuc2V0QmFja2dyb3VuZChiZ0NvbG9yKTsKKyAgICAgICAgY29weS5zZXRDb2xvcihmZ0NvbG9yKTsKKyAgICAgICAgY29weS5zZXRQYWludChwYWludCk7CisgICAgICAgIGNvcHkuc2V0Q29tcG9zaXRlKGNvbXBvc2l0ZSk7CisgICAgICAgIGNvcHkuc2V0U3Ryb2tlKHN0cm9rZSk7CisgICAgICAgIGNvcHkuc2V0Rm9udChmb250KTsKKyAgICAgICAgY29weS5zZXRUcmFuc2Zvcm0obmV3IEFmZmluZVRyYW5zZm9ybSh0cmFuc2Zvcm0pKTsKKyAgICAgICAgLy9jb3B5Lm9yaWdUcmFuc2Zvcm0gPSBuZXcgQWZmaW5lVHJhbnNmb3JtKG9yaWdUcmFuc2Zvcm0pOworICAgICAgICBjb3B5Lm9yaWdQb2ludCA9IG5ldyBQb2ludChvcmlnUG9pbnQpOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Db21tb25HcmFwaGljczJERmFjdG9yeS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvQ29tbW9uR3JhcGhpY3MyREZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2UzZWYwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvQ29tbW9uR3JhcGhpY3MyREZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbywgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsOworCitpbXBvcnQgamF2YS5hd3QuRm9udDsKK2ltcG9ydCBqYXZhLmF3dC5Gb250TWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5wZWVyLkZvbnRQZWVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkZvbnRNZXRyaWNzSW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0ay5HcmFwaGljc0ZhY3Rvcnk7CisKKy8qKgorICogQ29tbW9uIEdyYXBoaWNzRmFjdG9yeSBpbXBsZW1lbnRhdGlvbgorICoKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENvbW1vbkdyYXBoaWNzMkRGYWN0b3J5IGltcGxlbWVudHMgR3JhcGhpY3NGYWN0b3J5IHsKKyAgICAKKyAgICAvLyBzdGF0aWMgaW5zdGFuY2Ugb2YgQ29tbW9uR3JhcGhpY3MyREZhY3RvcnkKKyAgICBwdWJsaWMgc3RhdGljIENvbW1vbkdyYXBoaWNzMkRGYWN0b3J5IGluc3Q7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEZvbnRNZXRyaWNzIG9iamVjdCB0aGF0IGtlZXBzIG1ldHJpY3Mgb2YgdGhlIHNwZWNpZmllZCBmb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250IHNwZWNpZmllZCBGb250CisgICAgICogQHJldHVybiBGb250TWV0cmljcyBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIEZvbnQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQgZm9udCkgeworICAgICAgICBGb250TWV0cmljcyBmbTsKKyAgICAgICAgZm9yIChGb250TWV0cmljcyBlbGVtZW50IDogY2FjaGVGTSkgeworICAgICAgICAgICAgZm0gPSBlbGVtZW50OworICAgICAgICAgICAgaWYgKGZtID09IG51bGwpeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZm0uZ2V0Rm9udCgpLmVxdWFscyhmb250KSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZtOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZtID0gbmV3IEZvbnRNZXRyaWNzSW1wbChmb250KTsKKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNhY2hlRk0sIDAsIGNhY2hlRk0sIDEsIGNhY2hlRk0ubGVuZ3RoIC0xKTsKKyAgICAgICAgY2FjaGVGTVswXSA9IGZtOworCisgICAgICAgIHJldHVybiBmbTsKKyAgICB9CisgICAgLy8gRm9udCBtZXRob2RzCisKKyAgICBwdWJsaWMgRm9udFBlZXIgZ2V0Rm9udFBlZXIoRm9udCBmb250KSB7CisgICAgICAgIHJldHVybiBnZXRGb250TWFuYWdlcigpLmdldEZvbnRQZWVyKGZvbnQuZ2V0TmFtZSgpLCBmb250LmdldFN0eWxlKCksIGZvbnQuZ2V0U2l6ZSgpKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogRW1iZWRzIGZvbnQgZnJvbSBnaWxlIHdpdGggc3BlY2lmaWVkIHBhdGggaW50byB0aGUgc3lzdGVtLiAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9udEZpbGVQYXRoIHBhdGggdG8gdGhlIGZvbnQgZmlsZSAKKyAgICAgKiBAcmV0dXJuIEZvbnQgb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgZnJvbSB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRm9udCBlbWJlZEZvbnQoU3RyaW5nIGZvbnRGaWxlUGF0aCk7CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Db21tb25HcmFwaGljc0Vudmlyb25tZW50LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Db21tb25HcmFwaGljc0Vudmlyb25tZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWM3OGU1MAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0NvbW1vbkdyYXBoaWNzRW52aXJvbm1lbnQuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbywgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2w7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzMkQ7CitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3NFbnZpcm9ubWVudDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQ7CisKKy8qKgorICogQ29tbW9uIEdyYXBoaWNzRW52aXJvbm1lbnQgaW1wbGVtZW50YXRpb24KKyAqCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb21tb25HcmFwaGljc0Vudmlyb25tZW50IGV4dGVuZHMgR3JhcGhpY3NFbnZpcm9ubWVudCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3MyRCBjcmVhdGVHcmFwaGljcyhCdWZmZXJlZEltYWdlIGJ1ZmZlcmVkSW1hZ2UpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZEltYWdlR3JhcGhpY3MyRChidWZmZXJlZEltYWdlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0QXZhaWxhYmxlRm9udEZhbWlseU5hbWVzKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgRm9udFtdIGZvbnRzID0gZ2V0QWxsRm9udHMoKTsKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gZmFtaWx5TmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICBmb3IgKEZvbnQgZWxlbWVudCA6IGZvbnRzKSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGVsZW1lbnQuZ2V0RmFtaWx5KGxvY2FsZSk7CisgICAgICAgICAgICBpZiAoIWZhbWlseU5hbWVzLmNvbnRhaW5zKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgZmFtaWx5TmFtZXMuYWRkKG5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbWlseU5hbWVzLnRvQXJyYXkobmV3IFN0cmluZ1tmYW1pbHlOYW1lcy5zaXplKCldKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9udFtdIGdldEFsbEZvbnRzKCkgeworICAgICAgICByZXR1cm4gQ29tbW9uR3JhcGhpY3MyREZhY3RvcnkuaW5zdC5nZXRGb250TWFuYWdlcigpLmdldEFsbEZvbnRzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEF2YWlsYWJsZUZvbnRGYW1pbHlOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIENvbW1vbkdyYXBoaWNzMkRGYWN0b3J5Lmluc3QuZ2V0Rm9udE1hbmFnZXIoKS5nZXRBbGxGYW1pbGllcygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0Nyb3NzaW5nLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Dcm9zc2luZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlN2ZiMGUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9Dcm9zc2luZy5qYXZhCkBAIC0wLDAgKzEsODg5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbDsKKworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUGF0aEl0ZXJhdG9yOworCitwdWJsaWMgY2xhc3MgQ3Jvc3NpbmcgeworCisgICAgLyoqCisgICAgICogQWxsb3dhYmxlIHRvbGVyYW5jZSBmb3IgYm91bmRzIGNvbXBhcmlzb24KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIERFTFRBID0gMUUtNTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBJZiByb290cyBoYXZlIGRpc3RhbmNlIGxlc3MgdGhlbiA8Y29kZT5ST09UX0RFTFRBPC9jb2RlPiB0aGV5IGFyZSBkb3VibGUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZG91YmxlIFJPT1RfREVMVEEgPSAxRS0xMDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZWN0YW5nbGUgY3Jvc3Mgc2VnbWVudAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENST1NTSU5HID0gMjU1OworICAgIAorICAgIC8qKgorICAgICAqIFVua25vd24gY3Jvc3NpbmcgcmVzdWx0CisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBVTktOT1dOID0gMjU0OworCisgICAgLyoqCisgICAgICogU29sdmVzIHF1YWRyYXRpYyBlcXVhdGlvbgorICAgICAqIEBwYXJhbSBlcW4gLSB0aGUgY29lZmZpY2llbnRzIG9mIHRoZSBlcXVhdGlvbgorICAgICAqIEBwYXJhbSByZXMgLSB0aGUgcm9vdHMgb2YgdGhlIGVxdWF0aW9uCisgICAgICogQHJldHVybiBhIG51bWJlciBvZiByb290cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNvbHZlUXVhZChkb3VibGUgZXFuW10sIGRvdWJsZSByZXNbXSkgeworICAgICAgICBkb3VibGUgYSA9IGVxblsyXTsKKyAgICAgICAgZG91YmxlIGIgPSBlcW5bMV07CisgICAgICAgIGRvdWJsZSBjID0gZXFuWzBdOworICAgICAgICBpbnQgcmMgPSAwOworICAgICAgICBpZiAoYSA9PSAwLjApIHsKKyAgICAgICAgICAgIGlmIChiID09IDAuMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc1tyYysrXSA9IC1jIC8gYjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRvdWJsZSBkID0gYiAqIGIgLSA0LjAgKiBhICogYzsKKyAgICAgICAgICAgIC8vIGQgPCAwLjAKKyAgICAgICAgICAgIGlmIChkIDwgMC4wKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkID0gTWF0aC5zcXJ0KGQpOworICAgICAgICAgICAgcmVzW3JjKytdID0gKC0gYiArIGQpIC8gKGEgKiAyLjApOworICAgICAgICAgICAgLy8gZCAhPSAwLjAKKyAgICAgICAgICAgIGlmIChkICE9IDAuMCkgeworICAgICAgICAgICAgICAgIHJlc1tyYysrXSA9ICgtIGIgLSBkKSAvIChhICogMi4wKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZml4Um9vdHMocmVzLCByYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29sdmVzIGN1YmljIGVxdWF0aW9uCisgICAgICogQHBhcmFtIGVxbiAtIHRoZSBjb2VmZmljaWVudHMgb2YgdGhlIGVxdWF0aW9uCisgICAgICogQHBhcmFtIHJlcyAtIHRoZSByb290cyBvZiB0aGUgZXF1YXRpb24KKyAgICAgKiBAcmV0dXJuIGEgbnVtYmVyIG9mIHJvb3RzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgc29sdmVDdWJpYyhkb3VibGUgZXFuW10sIGRvdWJsZSByZXNbXSkgeworICAgICAgICBkb3VibGUgZCA9IGVxblszXTsKKyAgICAgICAgaWYgKGQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHNvbHZlUXVhZChlcW4sIHJlcyk7CisgICAgICAgIH0KKyAgICAgICAgZG91YmxlIGEgPSBlcW5bMl0gLyBkOworICAgICAgICBkb3VibGUgYiA9IGVxblsxXSAvIGQ7CisgICAgICAgIGRvdWJsZSBjID0gZXFuWzBdIC8gZDsKKyAgICAgICAgaW50IHJjID0gMDsKKworICAgICAgICBkb3VibGUgUSA9IChhICogYSAtIDMuMCAqIGIpIC8gOS4wOworICAgICAgICBkb3VibGUgUiA9ICgyLjAgKiBhICogYSAqIGEgLSA5LjAgKiBhICogYiArIDI3LjAgKiBjKSAvIDU0LjA7CisgICAgICAgIGRvdWJsZSBRMyA9IFEgKiBRICogUTsKKyAgICAgICAgZG91YmxlIFIyID0gUiAqIFI7CisgICAgICAgIGRvdWJsZSBuID0gLSBhIC8gMy4wOworCisgICAgICAgIGlmIChSMiA8IFEzKSB7CisgICAgICAgICAgICBkb3VibGUgdCA9IE1hdGguYWNvcyhSIC8gTWF0aC5zcXJ0KFEzKSkgLyAzLjA7CisgICAgICAgICAgICBkb3VibGUgcCA9IDIuMCAqIE1hdGguUEkgLyAzLjA7CisgICAgICAgICAgICBkb3VibGUgbSA9IC0yLjAgKiBNYXRoLnNxcnQoUSk7CisgICAgICAgICAgICByZXNbcmMrK10gPSBtICogTWF0aC5jb3ModCkgKyBuOworICAgICAgICAgICAgcmVzW3JjKytdID0gbSAqIE1hdGguY29zKHQgKyBwKSArIG47CisgICAgICAgICAgICByZXNbcmMrK10gPSBtICogTWF0aC5jb3ModCAtIHApICsgbjsKKyAgICAgICAgfSBlbHNlIHsKKy8vICAgICAgICAgIERlYnVnLnByaW50bG4oIlIyID49IFEzICgiICsgUjIgKyAiLyIgKyBRMyArICIpIik7CisgICAgICAgICAgICBkb3VibGUgQSA9IE1hdGgucG93KE1hdGguYWJzKFIpICsgTWF0aC5zcXJ0KFIyIC0gUTMpLCAxLjAgLyAzLjApOworICAgICAgICAgICAgaWYgKFIgPiAwLjApIHsKKyAgICAgICAgICAgICAgICBBID0gLUE7CisgICAgICAgICAgICB9CisvLyAgICAgICAgICBpZiAoQSA9PSAwLjApIHsKKyAgICAgICAgICAgIGlmICgtUk9PVF9ERUxUQSA8IEEgJiYgQSA8IFJPT1RfREVMVEEpIHsKKyAgICAgICAgICAgICAgICByZXNbcmMrK10gPSBuOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgQiA9IFEgLyBBOworICAgICAgICAgICAgICAgIHJlc1tyYysrXSA9IEEgKyBCICsgbjsKKy8vICAgICAgICAgICAgICBpZiAoUjIgPT0gUTMpIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgZGVsdGEgPSBSMiAtIFEzOworICAgICAgICAgICAgICAgIGlmICgtUk9PVF9ERUxUQSA8IGRlbHRhICYmIGRlbHRhIDwgUk9PVF9ERUxUQSkgeworICAgICAgICAgICAgICAgICAgICByZXNbcmMrK10gPSAtIChBICsgQikgLyAyLjAgKyBuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIHJldHVybiBmaXhSb290cyhyZXMsIHJjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGNsdWRlcyBkb3VibGUgcm9vdHMuIFJvb3RzIGFyZSBkb3VibGUgaWYgdGhleSBsaWVzIGVub3VnaCBjbG9zZSB3aXRoIGVhY2ggb3RoZXIuIAorICAgICAqIEBwYXJhbSByZXMgLSB0aGUgcm9vdHMgCisgICAgICogQHBhcmFtIHJjIC0gdGhlIHJvb3RzIGNvdW50CisgICAgICogQHJldHVybiBuZXcgcm9vdHMgY291bnQKKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGZpeFJvb3RzKGRvdWJsZSByZXNbXSwgaW50IHJjKSB7CisgICAgICAgIGludCB0YyA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCByYzsgaSsrKSB7CisgICAgICAgICAgICBvdXQ6IHsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGogPSBpICsgMTsgaiA8IHJjOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzWmVybyhyZXNbaV0gLSByZXNbal0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzW3RjKytdID0gcmVzW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0YzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWFkQ3VydmUgY2xhc3MgcHJvdmlkZXMgYmFzaWMgZnVuY3Rpb25hbGl0eSB0byBmaW5kIGN1cnZlIGNyb3NzaW5nIGFuZCBjYWxjdWxhdGluZyBib3VuZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFF1YWRDdXJ2ZSB7CisKKyAgICAgICAgZG91YmxlIGF4LCBheSwgYngsIGJ5OworICAgICAgICBkb3VibGUgQXgsIEF5LCBCeCwgQnk7CisKKyAgICAgICAgcHVibGljIFF1YWRDdXJ2ZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN4LCBkb3VibGUgY3ksIGRvdWJsZSB4MiwgZG91YmxlIHkyKSB7CisgICAgICAgICAgICBheCA9IHgyIC0geDE7CisgICAgICAgICAgICBheSA9IHkyIC0geTE7CisgICAgICAgICAgICBieCA9IGN4IC0geDE7CisgICAgICAgICAgICBieSA9IGN5IC0geTE7CisKKyAgICAgICAgICAgIEJ4ID0gYnggKyBieDsgICAvLyBCeCA9IDIuMCAqIGJ4CisgICAgICAgICAgICBBeCA9IGF4IC0gQng7ICAgLy8gQXggPSBheCAtIDIuMCAqIGJ4CisKKyAgICAgICAgICAgIEJ5ID0gYnkgKyBieTsgICAvLyBCeSA9IDIuMCAqIGJ5CisgICAgICAgICAgICBBeSA9IGF5IC0gQnk7ICAgLy8gQXkgPSBheSAtIDIuMCAqIGJ5CisgICAgICAgIH0KKworICAgICAgICBpbnQgY3Jvc3MoZG91YmxlIHJlc1tdLCBpbnQgcmMsIGRvdWJsZSBweTEsIGRvdWJsZSBweTIpIHsKKyAgICAgICAgICAgIGludCBjcm9zcyA9IDA7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmM7IGkrKykgeworICAgICAgICAgICAgICAgIGRvdWJsZSB0ID0gcmVzW2ldOworCisgICAgICAgICAgICAgICAgLy8gQ1VSVkUtT1VUU0lERQorICAgICAgICAgICAgICAgIGlmICh0IDwgLURFTFRBIHx8IHQgPiAxICsgREVMVEEpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIENVUlZFLVNUQVJUCisgICAgICAgICAgICAgICAgaWYgKHQgPCBERUxUQSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocHkxIDwgMC4wICYmIChieCAhPSAwLjAgPyBieCA6IGF4IC0gYngpIDwgMC4wKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjcm9zcy0tOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBDVVJWRS1FTkQKKyAgICAgICAgICAgICAgICBpZiAodCA+IDEgLSBERUxUQSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocHkxIDwgYXkgJiYgKGF4ICE9IGJ4ID8gYXggLSBieCA6IGJ4KSA+IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY3Jvc3MrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ1VSVkUtSU5TSURFCisgICAgICAgICAgICAgICAgZG91YmxlIHJ5ID0gdCAqICh0ICogQXkgKyBCeSk7CisgICAgICAgICAgICAgICAgLy8gcnkgPSB0ICogdCAqIEF5ICsgdCAqIEJ5CisgICAgICAgICAgICAgICAgaWYgKHJ5ID4gcHkyKSB7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSByeHQgPSB0ICogQXggKyBieDsKKyAgICAgICAgICAgICAgICAgICAgLy8gcnh0ID0gMi4wICogdCAqIEF4ICsgQnggPSAyLjAgKiB0ICogQXggKyAyLjAgKiBieAorICAgICAgICAgICAgICAgICAgICBpZiAocnh0ID4gLURFTFRBICYmIHJ4dCA8IERFTFRBKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjcm9zcyArPSByeHQgPiAwLjAgPyAxIDogLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSAvLyBmb3IKKworICAgICAgICAgICAgcmV0dXJuIGNyb3NzOworICAgICAgICB9CisKKyAgICAgICAgaW50IHNvbHZlUG9pbnQoZG91YmxlIHJlc1tdLCBkb3VibGUgcHgpIHsKKyAgICAgICAgICAgIGRvdWJsZSBlcW5bXSA9IHstcHgsIEJ4LCBBeH07CisgICAgICAgICAgICByZXR1cm4gc29sdmVRdWFkKGVxbiwgcmVzKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzb2x2ZUV4dHJlbShkb3VibGUgcmVzW10pIHsKKyAgICAgICAgICAgIGludCByYyA9IDA7CisgICAgICAgICAgICBpZiAoQXggIT0gMC4wKSB7CisgICAgICAgICAgICAgICAgcmVzW3JjKytdID0gLSBCeCAvIChBeCArIEF4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChBeSAhPSAwLjApIHsKKyAgICAgICAgICAgICAgICByZXNbcmMrK10gPSAtIEJ5IC8gKEF5ICsgQXkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJjOworICAgICAgICB9CisKKyAgICAgICAgaW50IGFkZEJvdW5kKGRvdWJsZSBib3VuZFtdLCBpbnQgYmMsIGRvdWJsZSByZXNbXSwgaW50IHJjLCBkb3VibGUgbWluWCwgZG91YmxlIG1heFgsIGJvb2xlYW4gY2hhbmdlSWQsIGludCBpZCkgeworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHJjOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgdCA9IHJlc1tpXTsKKyAgICAgICAgICAgICAgICBpZiAodCA+IC1ERUxUQSAmJiB0IDwgMSArIERFTFRBKSB7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZSByeCA9IHQgKiAodCAqIEF4ICsgQngpOworICAgICAgICAgICAgICAgICAgICBpZiAobWluWCA8PSByeCAmJiByeCA8PSBtYXhYKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZFtiYysrXSA9IHQ7CisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZFtiYysrXSA9IHJ4OworICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRbYmMrK10gPSB0ICogKHQgKiBBeSArIEJ5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kW2JjKytdID0gaWQ7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbmdlSWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCsrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGJjOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdWJpY0N1cnZlIGNsYXNzIHByb3ZpZGVzIGJhc2ljIGZ1bmN0aW9uYWxpdHkgdG8gZmluZCBjdXJ2ZSBjcm9zc2luZyBhbmQgY2FsY3VsYXRpbmcgYm91bmRzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDdWJpY0N1cnZlIHsKKworICAgICAgICBkb3VibGUgYXgsIGF5LCBieCwgYnksIGN4LCBjeTsKKyAgICAgICAgZG91YmxlIEF4LCBBeSwgQngsIEJ5LCBDeCwgQ3k7CisgICAgICAgIGRvdWJsZSBBeDMsIEJ4MjsKKworICAgICAgICBwdWJsaWMgQ3ViaWNDdXJ2ZShkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN4MSwgZG91YmxlIGN5MSwgZG91YmxlIGN4MiwgZG91YmxlIGN5MiwgZG91YmxlIHgyLCBkb3VibGUgeTIpIHsKKyAgICAgICAgICAgIGF4ID0geDIgLSB4MTsKKyAgICAgICAgICAgIGF5ID0geTIgLSB5MTsKKyAgICAgICAgICAgIGJ4ID0gY3gxIC0geDE7CisgICAgICAgICAgICBieSA9IGN5MSAtIHkxOworICAgICAgICAgICAgY3ggPSBjeDIgLSB4MTsKKyAgICAgICAgICAgIGN5ID0gY3kyIC0geTE7CisKKyAgICAgICAgICAgIEN4ID0gYnggKyBieCArIGJ4OyAgICAgICAgICAgLy8gQ3ggPSAzLjAgKiBieAorICAgICAgICAgICAgQnggPSBjeCArIGN4ICsgY3ggLSBDeCAtIEN4OyAvLyBCeCA9IDMuMCAqIGN4IC0gNi4wICogYngKKyAgICAgICAgICAgIEF4ID0gYXggLSBCeCAtIEN4OyAgICAgICAgICAgLy8gQXggPSBheCAtIDMuMCAqIGN4ICsgMy4wICogYngKKworICAgICAgICAgICAgQ3kgPSBieSArIGJ5ICsgYnk7ICAgICAgICAgICAvLyBDeSA9IDMuMCAqIGJ5CisgICAgICAgICAgICBCeSA9IGN5ICsgY3kgKyBjeSAtIEN5IC0gQ3k7IC8vIEJ5ID0gMy4wICogY3kgLSA2LjAgKiBieQorICAgICAgICAgICAgQXkgPSBheSAtIEJ5IC0gQ3k7ICAgICAgICAgICAvLyBBeSA9IGF5IC0gMy4wICogY3kgKyAzLjAgKiBieQorCisgICAgICAgICAgICBBeDMgPSBBeCArIEF4ICsgQXg7CisgICAgICAgICAgICBCeDIgPSBCeCArIEJ4OworICAgICAgICB9CisKKyAgICAgICAgaW50IGNyb3NzKGRvdWJsZSByZXNbXSwgaW50IHJjLCBkb3VibGUgcHkxLCBkb3VibGUgcHkyKSB7CisgICAgICAgICAgICBpbnQgY3Jvc3MgPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByYzsgaSsrKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIHQgPSByZXNbaV07CisKKyAgICAgICAgICAgICAgICAvLyBDVVJWRS1PVVRTSURFCisgICAgICAgICAgICAgICAgaWYgKHQgPCAtREVMVEEgfHwgdCA+IDEgKyBERUxUQSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ1VSVkUtU1RBUlQKKyAgICAgICAgICAgICAgICBpZiAodCA8IERFTFRBKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChweTEgPCAwLjAgJiYgKGJ4ICE9IDAuMCA/IGJ4IDogKGN4ICE9IGJ4ID8gY3ggLSBieCA6IGF4IC0gY3gpKSA8IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY3Jvc3MtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ1VSVkUtRU5ECisgICAgICAgICAgICAgICAgaWYgKHQgPiAxIC0gREVMVEEpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHB5MSA8IGF5ICYmIChheCAhPSBjeCA/IGF4IC0gY3ggOiAoY3ggIT0gYnggPyBjeCAtIGJ4IDogYngpKSA+IDAuMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY3Jvc3MrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ1VSVkUtSU5TSURFCisgICAgICAgICAgICAgICAgZG91YmxlIHJ5ID0gdCAqICh0ICogKHQgKiBBeSArIEJ5KSArIEN5KTsKKyAgICAgICAgICAgICAgICAvLyByeSA9IHQgKiB0ICogdCAqIEF5ICsgdCAqIHQgKiBCeSArIHQgKiBDeQorICAgICAgICAgICAgICAgIGlmIChyeSA+IHB5MikgeworICAgICAgICAgICAgICAgICAgICBkb3VibGUgcnh0ID0gdCAqICh0ICogQXgzICsgQngyKSArIEN4OworICAgICAgICAgICAgICAgICAgICAvLyByeHQgPSAzLjAgKiB0ICogdCAqIEF4ICsgMi4wICogdCAqIEJ4ICsgQ3gKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJ4dCA+IC1ERUxUQSAmJiByeHQgPCBERUxUQSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnh0ID0gdCAqIChBeDMgKyBBeDMpICsgQngyOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gcnh0ID0gNi4wICogdCAqIEF4ICsgMi4wICogQngKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyeHQgPCAtREVMVEEgfHwgcnh0ID4gREVMVEEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbmZsZWN0aW9uIHBvaW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByeHQgPSBheDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjcm9zcyArPSByeHQgPiAwLjAgPyAxIDogLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSAvL2ZvcgorCisgICAgICAgICAgICByZXR1cm4gY3Jvc3M7CisgICAgICAgIH0KKworICAgICAgICBpbnQgc29sdmVQb2ludChkb3VibGUgcmVzW10sIGRvdWJsZSBweCkgeworICAgICAgICAgICAgZG91YmxlIGVxbltdID0gey1weCwgQ3gsIEJ4LCBBeH07CisgICAgICAgICAgICByZXR1cm4gc29sdmVDdWJpYyhlcW4sIHJlcyk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgc29sdmVFeHRyZW1YKGRvdWJsZSByZXNbXSkgeworICAgICAgICAgICAgZG91YmxlIGVxbltdID0ge0N4LCBCeDIsIEF4M307CisgICAgICAgICAgICByZXR1cm4gc29sdmVRdWFkKGVxbiwgcmVzKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzb2x2ZUV4dHJlbVkoZG91YmxlIHJlc1tdKSB7CisgICAgICAgICAgICBkb3VibGUgZXFuW10gPSB7Q3ksIEJ5ICsgQnksIEF5ICsgQXkgKyBBeX07CisgICAgICAgICAgICByZXR1cm4gc29sdmVRdWFkKGVxbiwgcmVzKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBhZGRCb3VuZChkb3VibGUgYm91bmRbXSwgaW50IGJjLCBkb3VibGUgcmVzW10sIGludCByYywgZG91YmxlIG1pblgsIGRvdWJsZSBtYXhYLCBib29sZWFuIGNoYW5nZUlkLCBpbnQgaWQpIHsKKyAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCByYzsgaSsrKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIHQgPSByZXNbaV07CisgICAgICAgICAgICAgICAgaWYgKHQgPiAtREVMVEEgJiYgdCA8IDEgKyBERUxUQSkgeworICAgICAgICAgICAgICAgICAgICBkb3VibGUgcnggPSB0ICogKHQgKiAodCAqIEF4ICsgQngpICsgQ3gpOworICAgICAgICAgICAgICAgICAgICBpZiAobWluWCA8PSByeCAmJiByeCA8PSBtYXhYKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZFtiYysrXSA9IHQ7CisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZFtiYysrXSA9IHJ4OworICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRbYmMrK10gPSB0ICogKHQgKiAodCAqIEF5ICsgQnkpICsgQ3kpOworICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRbYmMrK10gPSBpZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGFuZ2VJZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYmM7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaG93IG1hbnkgdGltZXMgcmF5IGZyb20gcG9pbnQgKHgseSkgY3Jvc3MgbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjcm9zc0xpbmUoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgeCwgZG91YmxlIHkpIHsKKworICAgICAgICAvLyBMRUZUL1JJR0hUL1VQL0VNUFRZCisgICAgICAgIGlmICgoeCA8IHgxICYmIHggPCB4MikgfHwKKyAgICAgICAgICAgICh4ID4geDEgJiYgeCA+IHgyKSB8fAorICAgICAgICAgICAgKHkgPiB5MSAmJiB5ID4geTIpIHx8CisgICAgICAgICAgICAoeDEgPT0geDIpKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIERPV04KKyAgICAgICAgaWYgKHkgPCB5MSAmJiB5IDwgeTIpIHsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIElOU0lERQorICAgICAgICAgICAgaWYgKCh5MiAtIHkxKSAqICh4IC0geDEpIC8gKHgyIC0geDEpIDw9IHkgLSB5MSkgeworICAgICAgICAgICAgICAgIC8vIElOU0lERS1VUAorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gU1RBUlQKKyAgICAgICAgaWYgKHggPT0geDEpIHsKKyAgICAgICAgICAgIHJldHVybiB4MSA8IHgyID8gMCA6IC0xOworICAgICAgICB9CisKKyAgICAgICAgLy8gRU5ECisgICAgICAgIGlmICh4ID09IHgyKSB7CisgICAgICAgICAgICByZXR1cm4geDEgPCB4MiA/IDEgOiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gSU5TSURFLURPV04KKyAgICAgICAgcmV0dXJuIHgxIDwgeDIgPyAxIDogLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBob3cgbWFueSB0aW1lcyByYXkgZnJvbSBwb2ludCAoeCx5KSBjcm9zcyBxdWFyZCBjdXJ2ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNyb3NzUXVhZChkb3VibGUgeDEsIGRvdWJsZSB5MSwgZG91YmxlIGN4LCBkb3VibGUgY3ksIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgeCwgZG91YmxlIHkpIHsKKworICAgICAgICAvLyBMRUZUL1JJR0hUL1VQL0VNUFRZCisgICAgICAgIGlmICgoeCA8IHgxICYmIHggPCBjeCAmJiB4IDwgeDIpIHx8CisgICAgICAgICAgICAoeCA+IHgxICYmIHggPiBjeCAmJiB4ID4geDIpIHx8CisgICAgICAgICAgICAoeSA+IHkxICYmIHkgPiBjeSAmJiB5ID4geTIpIHx8CisgICAgICAgICAgICAoeDEgPT0gY3ggJiYgY3ggPT0geDIpKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIERPV04KKyAgICAgICAgaWYgKHkgPCB5MSAmJiB5IDwgY3kgJiYgeSA8IHkyICYmIHggIT0geDEgJiYgeCAhPSB4MikgeworICAgICAgICAgICAgaWYgKHgxIDwgeDIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geDEgPCB4ICYmIHggPCB4MiA/IDEgOiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHgyIDwgeCAmJiB4IDwgeDEgPyAtMSA6IDA7CisgICAgICAgIH0KKworICAgICAgICAvLyBJTlNJREUKKyAgICAgICAgUXVhZEN1cnZlIGMgPSBuZXcgUXVhZEN1cnZlKHgxLCB5MSwgY3gsIGN5LCB4MiwgeTIpOworICAgICAgICBkb3VibGUgcHggPSB4IC0geDE7CisgICAgICAgIGRvdWJsZSBweSA9IHkgLSB5MTsKKyAgICAgICAgZG91YmxlIHJlc1tdID0gbmV3IGRvdWJsZVszXTsKKyAgICAgICAgaW50IHJjID0gYy5zb2x2ZVBvaW50KHJlcywgcHgpOworCisgICAgICAgIHJldHVybiBjLmNyb3NzKHJlcywgcmMsIHB5LCBweSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBob3cgbWFueSB0aW1lcyByYXkgZnJvbSBwb2ludCAoeCx5KSBjcm9zcyBjdWJpYyBjdXJ2ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNyb3NzQ3ViaWMoZG91YmxlIHgxLCBkb3VibGUgeTEsIGRvdWJsZSBjeDEsIGRvdWJsZSBjeTEsIGRvdWJsZSBjeDIsIGRvdWJsZSBjeTIsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgeCwgZG91YmxlIHkpIHsKKworICAgICAgICAvLyBMRUZUL1JJR0hUL1VQL0VNUFRZCisgICAgICAgIGlmICgoeCA8IHgxICYmIHggPCBjeDEgJiYgeCA8IGN4MiAmJiB4IDwgeDIpIHx8CisgICAgICAgICAgICAoeCA+IHgxICYmIHggPiBjeDEgJiYgeCA+IGN4MiAmJiB4ID4geDIpIHx8CisgICAgICAgICAgICAoeSA+IHkxICYmIHkgPiBjeTEgJiYgeSA+IGN5MiAmJiB5ID4geTIpIHx8CisgICAgICAgICAgICAoeDEgPT0gY3gxICYmIGN4MSA9PSBjeDIgJiYgY3gyID09IHgyKSkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICAvLyBET1dOCisgICAgICAgIGlmICh5IDwgeTEgJiYgeSA8IGN5MSAmJiB5IDwgY3kyICYmIHkgPCB5MiAmJiB4ICE9IHgxICYmIHggIT0geDIpIHsKKyAgICAgICAgICAgIGlmICh4MSA8IHgyKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHgxIDwgeCAmJiB4IDwgeDIgPyAxIDogMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB4MiA8IHggJiYgeCA8IHgxID8gLTEgOiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gSU5TSURFCisgICAgICAgIEN1YmljQ3VydmUgYyA9IG5ldyBDdWJpY0N1cnZlKHgxLCB5MSwgY3gxLCBjeTEsIGN4MiwgY3kyLCB4MiwgeTIpOworICAgICAgICBkb3VibGUgcHggPSB4IC0geDE7CisgICAgICAgIGRvdWJsZSBweSA9IHkgLSB5MTsKKyAgICAgICAgZG91YmxlIHJlc1tdID0gbmV3IGRvdWJsZVszXTsKKyAgICAgICAgaW50IHJjID0gYy5zb2x2ZVBvaW50KHJlcywgcHgpOworICAgICAgICByZXR1cm4gYy5jcm9zcyhyZXMsIHJjLCBweSwgcHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaG93IG1hbnkgdGltZXMgcmF5IGZyb20gcG9pbnQgKHgseSkgY3Jvc3MgcGF0aAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNyb3NzUGF0aChQYXRoSXRlcmF0b3IgcCwgZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgIGludCBjcm9zcyA9IDA7CisgICAgICAgIGRvdWJsZSBteCwgbXksIGN4LCBjeTsKKyAgICAgICAgbXggPSBteSA9IGN4ID0gY3kgPSAwLjA7CisgICAgICAgIGRvdWJsZSBjb29yZHNbXSA9IG5ldyBkb3VibGVbNl07CisKKyAgICAgICAgd2hpbGUgKCFwLmlzRG9uZSgpKSB7CisgICAgICAgICAgICBzd2l0Y2ggKHAuY3VycmVudFNlZ21lbnQoY29vcmRzKSkgeworICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX01PVkVUTzoKKyAgICAgICAgICAgICAgICBpZiAoY3ggIT0gbXggfHwgY3kgIT0gbXkpIHsKKyAgICAgICAgICAgICAgICAgICAgY3Jvc3MgKz0gY3Jvc3NMaW5lKGN4LCBjeSwgbXgsIG15LCB4LCB5KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbXggPSBjeCA9IGNvb3Jkc1swXTsKKyAgICAgICAgICAgICAgICBteSA9IGN5ID0gY29vcmRzWzFdOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0xJTkVUTzoKKyAgICAgICAgICAgICAgICBjcm9zcyArPSBjcm9zc0xpbmUoY3gsIGN5LCBjeCA9IGNvb3Jkc1swXSwgY3kgPSBjb29yZHNbMV0sIHgsIHkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX1FVQURUTzoKKyAgICAgICAgICAgICAgICBjcm9zcyArPSBjcm9zc1F1YWQoY3gsIGN5LCBjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY3ggPSBjb29yZHNbMl0sIGN5ID0gY29vcmRzWzNdLCB4LCB5KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOgorICAgICAgICAgICAgICAgIGNyb3NzICs9IGNyb3NzQ3ViaWMoY3gsIGN5LCBjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10sIGN4ID0gY29vcmRzWzRdLCBjeSA9IGNvb3Jkc1s1XSwgeCwgeSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ0xPU0U6CisgICAgICAgICAgICAgICAgaWYgKGN5ICE9IG15IHx8IGN4ICE9IG14KSB7CisgICAgICAgICAgICAgICAgICAgIGNyb3NzICs9IGNyb3NzTGluZShjeCwgY3ksIGN4ID0gbXgsIGN5ID0gbXksIHgsIHkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHAubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGlmIChjeSAhPSBteSkgeworICAgICAgICAgICAgY3Jvc3MgKz0gY3Jvc3NMaW5lKGN4LCBjeSwgbXgsIG15LCB4LCB5KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3Jvc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBob3cgbWFueSB0aW1lcyByYXkgZnJvbSBwb2ludCAoeCx5KSBjcm9zcyBzaGFwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNyb3NzU2hhcGUoU2hhcGUgcywgZG91YmxlIHgsIGRvdWJsZSB5KSB7CisgICAgICAgIGlmICghcy5nZXRCb3VuZHMyRCgpLmNvbnRhaW5zKHgsIHkpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3Jvc3NQYXRoKHMuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpLCB4LCB5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgZW5vdWdoIHNtYWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWmVybyhkb3VibGUgdmFsKSB7CisgICAgICAgIHJldHVybiAtREVMVEEgPCB2YWwgJiYgdmFsIDwgREVMVEE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydCBib3VuZCBhcnJheQorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHNvcnRCb3VuZChkb3VibGUgYm91bmRbXSwgaW50IGJjKSB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBiYyAtIDQ7IGkgKz0gNCkgeworICAgICAgICAgICAgaW50IGsgPSBpOworICAgICAgICAgICAgZm9yKGludCBqID0gaSArIDQ7IGogPCBiYzsgaiArPSA0KSB7CisgICAgICAgICAgICAgICAgaWYgKGJvdW5kW2tdID4gYm91bmRbal0pIHsKKyAgICAgICAgICAgICAgICAgICAgayA9IGo7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGsgIT0gaSkgeworICAgICAgICAgICAgICAgIGRvdWJsZSB0bXAgPSBib3VuZFtpXTsKKyAgICAgICAgICAgICAgICBib3VuZFtpXSA9IGJvdW5kW2tdOworICAgICAgICAgICAgICAgIGJvdW5kW2tdID0gdG1wOworICAgICAgICAgICAgICAgIHRtcCA9IGJvdW5kW2kgKyAxXTsKKyAgICAgICAgICAgICAgICBib3VuZFtpICsgMV0gPSBib3VuZFtrICsgMV07CisgICAgICAgICAgICAgICAgYm91bmRbayArIDFdID0gdG1wOworICAgICAgICAgICAgICAgIHRtcCA9IGJvdW5kW2kgKyAyXTsKKyAgICAgICAgICAgICAgICBib3VuZFtpICsgMl0gPSBib3VuZFtrICsgMl07CisgICAgICAgICAgICAgICAgYm91bmRbayArIDJdID0gdG1wOworICAgICAgICAgICAgICAgIHRtcCA9IGJvdW5kW2kgKyAzXTsKKyAgICAgICAgICAgICAgICBib3VuZFtpICsgM10gPSBib3VuZFtrICsgM107CisgICAgICAgICAgICAgICAgYm91bmRbayArIDNdID0gdG1wOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgYXJlIGJvdW5kcyBpbnRlcnNlY3Qgb3Igbm90IGludGVyc2VjdCByZWN0YW5nbGUgCisgICAgICovCisgICAgc3RhdGljIGludCBjcm9zc0JvdW5kKGRvdWJsZSBib3VuZFtdLCBpbnQgYmMsIGRvdWJsZSBweTEsIGRvdWJsZSBweTIpIHsKKworICAgICAgICAvLyBMRUZUL1JJR0hUCisgICAgICAgIGlmIChiYyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIFkgY29vcmRpbmF0ZQorICAgICAgICBpbnQgdXAgPSAwOworICAgICAgICBpbnQgZG93biA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDI7IGkgPCBiYzsgaSArPSA0KSB7CisgICAgICAgICAgICBpZiAoYm91bmRbaV0gPCBweTEpIHsKKyAgICAgICAgICAgICAgICB1cCsrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGJvdW5kW2ldID4gcHkyKSB7CisgICAgICAgICAgICAgICAgZG93bisrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIENST1NTSU5HOworICAgICAgICB9CisKKyAgICAgICAgLy8gVVAKKyAgICAgICAgaWYgKGRvd24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAodXAgIT0gMCkgeworICAgICAgICAgICAgLy8gYmMgPj0gMgorICAgICAgICAgICAgc29ydEJvdW5kKGJvdW5kLCBiYyk7CisgICAgICAgICAgICBib29sZWFuIHNpZ24gPSBib3VuZFsyXSA+IHB5MjsKKyAgICAgICAgICAgIGZvcihpbnQgaSA9IDY7IGkgPCBiYzsgaSArPSA0KSB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBzaWduMiA9IGJvdW5kW2ldID4gcHkyOworICAgICAgICAgICAgICAgIGlmIChzaWduICE9IHNpZ24yICYmIGJvdW5kW2kgKyAxXSAhPSBib3VuZFtpIC0gM10pIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENST1NTSU5HOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzaWduID0gc2lnbjI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFVOS05PV047CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBob3cgbWFueSB0aW1lcyByZWN0YW5nbGUgc3RyaXBlIGNyb3NzIGxpbmUgb3IgdGhlIGFyZSBpbnRlcnNlY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBpbnRlcnNlY3RMaW5lKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHJ4MSwgZG91YmxlIHJ5MSwgZG91YmxlIHJ4MiwgZG91YmxlIHJ5MikgeworCisgICAgICAgIC8vIExFRlQvUklHSFQvVVAKKyAgICAgICAgaWYgKChyeDIgPCB4MSAmJiByeDIgPCB4MikgfHwKKyAgICAgICAgICAgIChyeDEgPiB4MSAmJiByeDEgPiB4MikgfHwKKyAgICAgICAgICAgIChyeTEgPiB5MSAmJiByeTEgPiB5MikpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gRE9XTgorICAgICAgICBpZiAocnkyIDwgeTEgJiYgcnkyIDwgeTIpIHsKKyAgICAgICAgfSBlbHNlIHsKKworICAgICAgICAgICAgLy8gSU5TSURFCisgICAgICAgICAgICBpZiAoeDEgPT0geDIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ1JPU1NJTkc7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEJ1aWxkIGJvdW5kCisgICAgICAgICAgICBkb3VibGUgYngxLCBieDI7CisgICAgICAgICAgICBpZiAoeDEgPCB4MikgeworICAgICAgICAgICAgICAgIGJ4MSA9IHgxIDwgcngxID8gcngxIDogeDE7CisgICAgICAgICAgICAgICAgYngyID0geDIgPCByeDIgPyB4MiA6IHJ4MjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYngxID0geDIgPCByeDEgPyByeDEgOiB4MjsKKyAgICAgICAgICAgICAgICBieDIgPSB4MSA8IHJ4MiA/IHgxIDogcngyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZG91YmxlIGsgPSAoeTIgLSB5MSkgLyAoeDIgLSB4MSk7CisgICAgICAgICAgICBkb3VibGUgYnkxID0gayAqIChieDEgLSB4MSkgKyB5MTsKKyAgICAgICAgICAgIGRvdWJsZSBieTIgPSBrICogKGJ4MiAtIHgxKSArIHkxOworCisgICAgICAgICAgICAvLyBCT1VORC1VUAorICAgICAgICAgICAgaWYgKGJ5MSA8IHJ5MSAmJiBieTIgPCByeTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQk9VTkQtRE9XTgorICAgICAgICAgICAgaWYgKGJ5MSA+IHJ5MiAmJiBieTIgPiByeTIpIHsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIENST1NTSU5HOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gRU1QVFkKKyAgICAgICAgaWYgKHgxID09IHgyKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENVUlZFLVNUQVJUCisgICAgICAgIGlmIChyeDEgPT0geDEpIHsKKyAgICAgICAgICAgIHJldHVybiB4MSA8IHgyID8gMCA6IC0xOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ1VSVkUtRU5ECisgICAgICAgIGlmIChyeDEgPT0geDIpIHsKKyAgICAgICAgICAgIHJldHVybiB4MSA8IHgyID8gMSA6IDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoeDEgPCB4MikgeworICAgICAgICAgICAgcmV0dXJuIHgxIDwgcngxICYmIHJ4MSA8IHgyID8gMSA6IDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHgyIDwgcngxICYmIHJ4MSA8IHgxID8gLTEgOiAwOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBob3cgbWFueSB0aW1lcyByZWN0YW5nbGUgc3RyaXBlIGNyb3NzIHF1YWQgY3VydmUgb3IgdGhlIGFyZSBpbnRlcnNlY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBpbnRlcnNlY3RRdWFkKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgY3gsIGRvdWJsZSBjeSwgZG91YmxlIHgyLCBkb3VibGUgeTIsIGRvdWJsZSByeDEsIGRvdWJsZSByeTEsIGRvdWJsZSByeDIsIGRvdWJsZSByeTIpIHsKKworICAgICAgICAvLyBMRUZUL1JJR0hUL1VQIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAgICBpZiAoKHJ4MiA8IHgxICYmIHJ4MiA8IGN4ICYmIHJ4MiA8IHgyKSB8fAorICAgICAgICAgICAgKHJ4MSA+IHgxICYmIHJ4MSA+IGN4ICYmIHJ4MSA+IHgyKSB8fAorICAgICAgICAgICAgKHJ5MSA+IHkxICYmIHJ5MSA+IGN5ICYmIHJ5MSA+IHkyKSkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICAvLyBET1dOIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAgICBpZiAocnkyIDwgeTEgJiYgcnkyIDwgY3kgJiYgcnkyIDwgeTIgJiYgcngxICE9IHgxICYmIHJ4MSAhPSB4MikgeworICAgICAgICAgICAgaWYgKHgxIDwgeDIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geDEgPCByeDEgJiYgcngxIDwgeDIgPyAxIDogMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB4MiA8IHJ4MSAmJiByeDEgPCB4MSA/IC0xIDogMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIElOU0lERSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICAgIFF1YWRDdXJ2ZSBjID0gbmV3IFF1YWRDdXJ2ZSh4MSwgeTEsIGN4LCBjeSwgeDIsIHkyKTsKKyAgICAgICAgZG91YmxlIHB4MSA9IHJ4MSAtIHgxOworICAgICAgICBkb3VibGUgcHkxID0gcnkxIC0geTE7CisgICAgICAgIGRvdWJsZSBweDIgPSByeDIgLSB4MTsKKyAgICAgICAgZG91YmxlIHB5MiA9IHJ5MiAtIHkxOworCisgICAgICAgIGRvdWJsZSByZXMxW10gPSBuZXcgZG91YmxlWzNdOworICAgICAgICBkb3VibGUgcmVzMltdID0gbmV3IGRvdWJsZVszXTsKKyAgICAgICAgaW50IHJjMSA9IGMuc29sdmVQb2ludChyZXMxLCBweDEpOworICAgICAgICBpbnQgcmMyID0gYy5zb2x2ZVBvaW50KHJlczIsIHB4Mik7CisKKyAgICAgICAgLy8gSU5TSURFLUxFRlQvUklHSFQKKyAgICAgICAgaWYgKHJjMSA9PSAwICYmIHJjMiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEJ1aWxkIGJvdW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICAgIGRvdWJsZSBtaW5YID0gcHgxIC0gREVMVEE7CisgICAgICAgIGRvdWJsZSBtYXhYID0gcHgyICsgREVMVEE7CisgICAgICAgIGRvdWJsZSBib3VuZFtdID0gbmV3IGRvdWJsZVsyOF07CisgICAgICAgIGludCBiYyA9IDA7CisgICAgICAgIC8vIEFkZCByb290cworICAgICAgICBiYyA9IGMuYWRkQm91bmQoYm91bmQsIGJjLCByZXMxLCByYzEsIG1pblgsIG1heFgsIGZhbHNlLCAwKTsKKyAgICAgICAgYmMgPSBjLmFkZEJvdW5kKGJvdW5kLCBiYywgcmVzMiwgcmMyLCBtaW5YLCBtYXhYLCBmYWxzZSwgMSk7CisgICAgICAgIC8vIEFkZCBleHRyZW1hbCBwb2ludHNgCisgICAgICAgIHJjMiA9IGMuc29sdmVFeHRyZW0ocmVzMik7CisgICAgICAgIGJjID0gYy5hZGRCb3VuZChib3VuZCwgYmMsIHJlczIsIHJjMiwgbWluWCwgbWF4WCwgdHJ1ZSwgMik7CisgICAgICAgIC8vIEFkZCBzdGFydCBhbmQgZW5kCisgICAgICAgIGlmIChyeDEgPCB4MSAmJiB4MSA8IHJ4MikgeworICAgICAgICAgICAgYm91bmRbYmMrK10gPSAwLjA7CisgICAgICAgICAgICBib3VuZFtiYysrXSA9IDAuMDsKKyAgICAgICAgICAgIGJvdW5kW2JjKytdID0gMC4wOworICAgICAgICAgICAgYm91bmRbYmMrK10gPSA0OworICAgICAgICB9CisgICAgICAgIGlmIChyeDEgPCB4MiAmJiB4MiA8IHJ4MikgeworICAgICAgICAgICAgYm91bmRbYmMrK10gPSAxLjA7CisgICAgICAgICAgICBib3VuZFtiYysrXSA9IGMuYXg7CisgICAgICAgICAgICBib3VuZFtiYysrXSA9IGMuYXk7CisgICAgICAgICAgICBib3VuZFtiYysrXSA9IDU7CisgICAgICAgIH0KKyAgICAgICAgLy8gRW5kIGJ1aWxkIGJvdW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgICAgICBpbnQgY3Jvc3MgPSBjcm9zc0JvdW5kKGJvdW5kLCBiYywgcHkxLCBweTIpOworICAgICAgICBpZiAoY3Jvc3MgIT0gVU5LTk9XTikgeworICAgICAgICAgICAgcmV0dXJuIGNyb3NzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjLmNyb3NzKHJlczEsIHJjMSwgcHkxLCBweTIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaG93IG1hbnkgdGltZXMgcmVjdGFuZ2xlIHN0cmlwZSBjcm9zcyBjdWJpYyBjdXJ2ZSBvciB0aGUgYXJlIGludGVyc2VjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGludGVyc2VjdEN1YmljKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgY3gxLCBkb3VibGUgY3kxLCBkb3VibGUgY3gyLCBkb3VibGUgY3kyLCBkb3VibGUgeDIsIGRvdWJsZSB5MiwgZG91YmxlIHJ4MSwgZG91YmxlIHJ5MSwgZG91YmxlIHJ4MiwgZG91YmxlIHJ5MikgeworCisgICAgICAgIC8vIExFRlQvUklHSFQvVVAKKyAgICAgICAgaWYgKChyeDIgPCB4MSAmJiByeDIgPCBjeDEgJiYgcngyIDwgY3gyICYmIHJ4MiA8IHgyKSB8fAorICAgICAgICAgICAgKHJ4MSA+IHgxICYmIHJ4MSA+IGN4MSAmJiByeDEgPiBjeDIgJiYgcngxID4geDIpIHx8CisgICAgICAgICAgICAocnkxID4geTEgJiYgcnkxID4gY3kxICYmIHJ5MSA+IGN5MiAmJiByeTEgPiB5MikpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gRE9XTgorICAgICAgICBpZiAocnkyIDwgeTEgJiYgcnkyIDwgY3kxICYmIHJ5MiA8IGN5MiAmJiByeTIgPCB5MiAmJiByeDEgIT0geDEgJiYgcngxICE9IHgyKSB7CisgICAgICAgICAgICBpZiAoeDEgPCB4MikgeworICAgICAgICAgICAgICAgIHJldHVybiB4MSA8IHJ4MSAmJiByeDEgPCB4MiA/IDEgOiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHgyIDwgcngxICYmIHJ4MSA8IHgxID8gLTEgOiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gSU5TSURFCisgICAgICAgIEN1YmljQ3VydmUgYyA9IG5ldyBDdWJpY0N1cnZlKHgxLCB5MSwgY3gxLCBjeTEsIGN4MiwgY3kyLCB4MiwgeTIpOworICAgICAgICBkb3VibGUgcHgxID0gcngxIC0geDE7CisgICAgICAgIGRvdWJsZSBweTEgPSByeTEgLSB5MTsKKyAgICAgICAgZG91YmxlIHB4MiA9IHJ4MiAtIHgxOworICAgICAgICBkb3VibGUgcHkyID0gcnkyIC0geTE7CisKKyAgICAgICAgZG91YmxlIHJlczFbXSA9IG5ldyBkb3VibGVbM107CisgICAgICAgIGRvdWJsZSByZXMyW10gPSBuZXcgZG91YmxlWzNdOworICAgICAgICBpbnQgcmMxID0gYy5zb2x2ZVBvaW50KHJlczEsIHB4MSk7CisgICAgICAgIGludCByYzIgPSBjLnNvbHZlUG9pbnQocmVzMiwgcHgyKTsKKworICAgICAgICAvLyBMRUZUL1JJR0hUCisgICAgICAgIGlmIChyYzEgPT0gMCAmJiByYzIgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgbWluWCA9IHB4MSAtIERFTFRBOworICAgICAgICBkb3VibGUgbWF4WCA9IHB4MiArIERFTFRBOworCisgICAgICAgIC8vIEJ1aWxkIGJvdW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICAgIGRvdWJsZSBib3VuZFtdID0gbmV3IGRvdWJsZVs0MF07CisgICAgICAgIGludCBiYyA9IDA7CisgICAgICAgIC8vIEFkZCByb290cworICAgICAgICBiYyA9IGMuYWRkQm91bmQoYm91bmQsIGJjLCByZXMxLCByYzEsIG1pblgsIG1heFgsIGZhbHNlLCAwKTsKKyAgICAgICAgYmMgPSBjLmFkZEJvdW5kKGJvdW5kLCBiYywgcmVzMiwgcmMyLCBtaW5YLCBtYXhYLCBmYWxzZSwgMSk7CisgICAgICAgIC8vIEFkZCBleHRyaW1hbCBwb2ludHMKKyAgICAgICAgcmMyID0gYy5zb2x2ZUV4dHJlbVgocmVzMik7CisgICAgICAgIGJjID0gYy5hZGRCb3VuZChib3VuZCwgYmMsIHJlczIsIHJjMiwgbWluWCwgbWF4WCwgdHJ1ZSwgMik7CisgICAgICAgIHJjMiA9IGMuc29sdmVFeHRyZW1ZKHJlczIpOworICAgICAgICBiYyA9IGMuYWRkQm91bmQoYm91bmQsIGJjLCByZXMyLCByYzIsIG1pblgsIG1heFgsIHRydWUsIDQpOworICAgICAgICAvLyBBZGQgc3RhcnQgYW5kIGVuZAorICAgICAgICBpZiAocngxIDwgeDEgJiYgeDEgPCByeDIpIHsKKyAgICAgICAgICAgIGJvdW5kW2JjKytdID0gMC4wOworICAgICAgICAgICAgYm91bmRbYmMrK10gPSAwLjA7CisgICAgICAgICAgICBib3VuZFtiYysrXSA9IDAuMDsKKyAgICAgICAgICAgIGJvdW5kW2JjKytdID0gNjsKKyAgICAgICAgfQorICAgICAgICBpZiAocngxIDwgeDIgJiYgeDIgPCByeDIpIHsKKyAgICAgICAgICAgIGJvdW5kW2JjKytdID0gMS4wOworICAgICAgICAgICAgYm91bmRbYmMrK10gPSBjLmF4OworICAgICAgICAgICAgYm91bmRbYmMrK10gPSBjLmF5OworICAgICAgICAgICAgYm91bmRbYmMrK10gPSA3OworICAgICAgICB9CisgICAgICAgIC8vIEVuZCBidWlsZCBib3VuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAgICAgaW50IGNyb3NzID0gY3Jvc3NCb3VuZChib3VuZCwgYmMsIHB5MSwgcHkyKTsKKyAgICAgICAgaWYgKGNyb3NzICE9IFVOS05PV04pIHsKKyAgICAgICAgICAgIHJldHVybiBjcm9zczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYy5jcm9zcyhyZXMxLCByYzEsIHB5MSwgcHkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhvdyBtYW55IHRpbWVzIHJlY3RhbmdsZSBzdHJpcGUgY3Jvc3MgcGF0aCBvciB0aGUgYXJlIGludGVyc2VjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGludGVyc2VjdFBhdGgoUGF0aEl0ZXJhdG9yIHAsIGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHcsIGRvdWJsZSBoKSB7CisKKyAgICAgICAgaW50IGNyb3NzID0gMDsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICBkb3VibGUgbXgsIG15LCBjeCwgY3k7CisgICAgICAgIG14ID0gbXkgPSBjeCA9IGN5ID0gMC4wOworICAgICAgICBkb3VibGUgY29vcmRzW10gPSBuZXcgZG91YmxlWzZdOworCisgICAgICAgIGRvdWJsZSByeDEgPSB4OworICAgICAgICBkb3VibGUgcnkxID0geTsKKyAgICAgICAgZG91YmxlIHJ4MiA9IHggKyB3OworICAgICAgICBkb3VibGUgcnkyID0geSArIGg7CisKKyAgICAgICAgd2hpbGUgKCFwLmlzRG9uZSgpKSB7CisgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgICAgICBzd2l0Y2ggKHAuY3VycmVudFNlZ21lbnQoY29vcmRzKSkgeworICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX01PVkVUTzoKKyAgICAgICAgICAgICAgICBpZiAoY3ggIT0gbXggfHwgY3kgIT0gbXkpIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSBpbnRlcnNlY3RMaW5lKGN4LCBjeSwgbXgsIG15LCByeDEsIHJ5MSwgcngyLCByeTIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBteCA9IGN4ID0gY29vcmRzWzBdOworICAgICAgICAgICAgICAgIG15ID0gY3kgPSBjb29yZHNbMV07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfTElORVRPOgorICAgICAgICAgICAgICAgIGNvdW50ID0gaW50ZXJzZWN0TGluZShjeCwgY3ksIGN4ID0gY29vcmRzWzBdLCBjeSA9IGNvb3Jkc1sxXSwgcngxLCByeTEsIHJ4MiwgcnkyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19RVUFEVE86CisgICAgICAgICAgICAgICAgY291bnQgPSBpbnRlcnNlY3RRdWFkKGN4LCBjeSwgY29vcmRzWzBdLCBjb29yZHNbMV0sIGN4ID0gY29vcmRzWzJdLCBjeSA9IGNvb3Jkc1szXSwgcngxLCByeTEsIHJ4MiwgcnkyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DVUJJQ1RPOgorICAgICAgICAgICAgICAgIGNvdW50ID0gaW50ZXJzZWN0Q3ViaWMoY3gsIGN5LCBjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10sIGN4ID0gY29vcmRzWzRdLCBjeSA9IGNvb3Jkc1s1XSwgcngxLCByeTEsIHJ4MiwgcnkyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19DTE9TRToKKyAgICAgICAgICAgICAgICBpZiAoY3kgIT0gbXkgfHwgY3ggIT0gbXgpIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSBpbnRlcnNlY3RMaW5lKGN4LCBjeSwgbXgsIG15LCByeDEsIHJ5MSwgcngyLCByeTIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjeCA9IG14OworICAgICAgICAgICAgICAgIGN5ID0gbXk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY291bnQgPT0gQ1JPU1NJTkcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ1JPU1NJTkc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjcm9zcyArPSBjb3VudDsKKyAgICAgICAgICAgIHAubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGlmIChjeSAhPSBteSkgeworICAgICAgICAgICAgY291bnQgPSBpbnRlcnNlY3RMaW5lKGN4LCBjeSwgbXgsIG15LCByeDEsIHJ5MSwgcngyLCByeTIpOworICAgICAgICAgICAgaWYgKGNvdW50ID09IENST1NTSU5HKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIENST1NTSU5HOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3Jvc3MgKz0gY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNyb3NzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaG93IG1hbnkgdGltZXMgcmVjdGFuZ2xlIHN0cmlwZSBjcm9zcyBzaGFwZSBvciB0aGUgYXJlIGludGVyc2VjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGludGVyc2VjdFNoYXBlKFNoYXBlIHMsIGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHcsIGRvdWJsZSBoKSB7CisgICAgICAgIGlmICghcy5nZXRCb3VuZHMyRCgpLmludGVyc2VjdHMoeCwgeSwgdywgaCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnRlcnNlY3RQYXRoKHMuZ2V0UGF0aEl0ZXJhdG9yKG51bGwpLCB4LCB5LCB3LCBoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgY3Jvc3MgY291bnQgY29ycmVzcG9uZCBpbnNpZGUgbG9jYXRpb24gZm9yIG5vbiB6ZXJvIHBhdGggcnVsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0luc2lkZU5vblplcm8oaW50IGNyb3NzKSB7CisgICAgICAgIHJldHVybiBjcm9zcyAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBjcm9zcyBjb3VudCBjb3JyZXNwb25kIGluc2lkZSBsb2NhdGlvbiBmb3IgZXZlbi1vZGQgcGF0aCBydWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSW5zaWRlRXZlbk9kZChpbnQgY3Jvc3MpIHsKKyAgICAgICAgcmV0dXJuIChjcm9zcyAmIDEpICE9IDA7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0dMVm9sYXRpbGVJbWFnZS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvR0xWb2xhdGlsZUltYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTc3YmUyMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL0dMVm9sYXRpbGVJbWFnZS5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsOworCitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuU3VyZmFjZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIEdMVm9sYXRpbGVJbWFnZSBleHRlbmRzIFZvbGF0aWxlSW1hZ2UgeworCisgICAgcHVibGljIGFic3RyYWN0IFN1cmZhY2UgZ2V0SW1hZ2VTdXJmYWNlKCk7Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9JQ29tcG9zaXRlQ29udGV4dC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvSUNvbXBvc2l0ZUNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzU2MzFmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvSUNvbXBvc2l0ZUNvbnRleHQuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbDsKKworaW1wb3J0IGphdmEuYXd0LkNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGVDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5JbWFnZVN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXIuTmF0aXZlSW1hZ2VCbGl0dGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnQgaW1wbGVtZW50YXRpb24gb2YgdGhlIENvbXBvc2l0ZUNvbnRleHQgaW50ZXJmYWNlCisgKi8KK3B1YmxpYyBjbGFzcyBJQ29tcG9zaXRlQ29udGV4dCBpbXBsZW1lbnRzIENvbXBvc2l0ZUNvbnRleHQgeworICAgIENvbXBvc2l0ZSBjb21wb3NpdGU7CisgICAgQ29sb3JNb2RlbCBzcmNDTSwgZHN0Q007CisgICAgSW1hZ2VTdXJmYWNlIHNyY1N1cmYsIGRzdFN1cmY7CisKKyAgICBwdWJsaWMgSUNvbXBvc2l0ZUNvbnRleHQoQ29tcG9zaXRlIGNvbXAsIENvbG9yTW9kZWwgc3JjLCBDb2xvck1vZGVsIGRzdCl7CisgICAgICAgIGNvbXBvc2l0ZSA9IGNvbXA7CisgICAgICAgIHNyY0NNID0gc3JjOworICAgICAgICBkc3RDTSA9IGRzdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICBzcmNTdXJmLmRpc3Bvc2UoKTsKKyAgICAgICAgZHN0U3VyZi5kaXNwb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tcG9zZShSYXN0ZXIgc3JjSW4sIFJhc3RlciBkc3RJbiwgV3JpdGFibGVSYXN0ZXIgZHN0T3V0KSB7CisKKyAgICAgICAgaWYoIXNyY0NNLmlzQ29tcGF0aWJsZVJhc3RlcihzcmNJbikpIHsKKyAgICAgICAgICAgIC8vIGF3dC40OD1UaGUgc3JjSW4gcmFzdGVyIGlzIGluY29tcGF0aWJsZSB3aXRoIHNyYyBDb2xvck1vZGVsCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQ4IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZighZHN0Q00uaXNDb21wYXRpYmxlUmFzdGVyKGRzdEluKSkgeworICAgICAgICAgICAgLy8gYXd0LjQ5PVRoZSBkc3RJbiByYXN0ZXIgaXMgaW5jb21wYXRpYmxlIHdpdGggZHN0IENvbG9yTW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmKGRzdEluICE9IGRzdE91dCl7CisgICAgICAgICAgICBpZighZHN0Q00uaXNDb21wYXRpYmxlUmFzdGVyKGRzdE91dCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEE9VGhlIGRzdE91dCByYXN0ZXIgaXMgaW5jb21wYXRpYmxlIHdpdGggZHN0IENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRBIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBkc3RPdXQuc2V0RGF0YUVsZW1lbnRzKDAsIDAsIGRzdEluKTsKKyAgICAgICAgfQorICAgICAgICBXcml0YWJsZVJhc3RlciBzcmM7CisgICAgICAgIGlmKHNyY0luIGluc3RhbmNlb2YgV3JpdGFibGVSYXN0ZXIpeworICAgICAgICAgICAgc3JjID0gKFdyaXRhYmxlUmFzdGVyKSBzcmNJbjsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBzcmMgPSBzcmNJbi5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIoKTsKKyAgICAgICAgICAgIHNyYy5zZXREYXRhRWxlbWVudHMoMCwgMCwgc3JjSW4pOworICAgICAgICB9CisgICAgICAgIHNyY1N1cmYgPSBuZXcgSW1hZ2VTdXJmYWNlKHNyY0NNLCBzcmMpOworICAgICAgICBkc3RTdXJmID0gbmV3IEltYWdlU3VyZmFjZShkc3RDTSwgZHN0T3V0KTsKKworICAgICAgICBpbnQgdyA9IE1hdGgubWluKHNyY0luLmdldFdpZHRoKCksIGRzdE91dC5nZXRXaWR0aCgpKTsKKyAgICAgICAgaW50IGggPSBNYXRoLm1pbihzcmNJbi5nZXRIZWlnaHQoKSwgZHN0T3V0LmdldEhlaWdodCgpKTsKKworICAgICAgICBOYXRpdmVJbWFnZUJsaXR0ZXIuZ2V0SW5zdGFuY2UoKS5ibGl0KDAsIDAsIHNyY1N1cmYsIDAsIDAsIGRzdFN1cmYsCisgICAgICAgICAgICAgICAgdywgaCwgY29tcG9zaXRlLCBudWxsLCBudWxsKTsKKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvSW1hZ2VTdXJmYWNlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9JbWFnZVN1cmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzY4ZGQ4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvSW1hZ2VTdXJmYWNlLmphdmEKQEAgLTAsMCArMSwzMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqIENyZWF0ZWQgb24gMTAuMTEuMjAwNQorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsOworCitpbXBvcnQgamF2YS5hd3QuY29sb3IuQ29sb3JTcGFjZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CYW5kZWRTYW1wbGVNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29tcG9uZW50Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db21wb25lbnRTYW1wbGVNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EaXJlY3RDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkluZGV4Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5NdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUGl4ZWxJbnRlcmxlYXZlZFNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuV3JpdGFibGVSYXN0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLkxVVENvbG9yQ29udmVydGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuRGF0YUJ1ZmZlckxpc3RlbmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnQgU3VyZmFjZSBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIEltYWdlcyAoQnVmZmVyZWRJbWFnZSwgCisgKiBPZmZzY3JlZW5JbWFnZSBhbmQgc28gb24pIAorICovCitwdWJsaWMgY2xhc3MgSW1hZ2VTdXJmYWNlIGV4dGVuZHMgU3VyZmFjZSBpbXBsZW1lbnRzIERhdGFCdWZmZXJMaXN0ZW5lciB7CisKKyAgICBib29sZWFuIG5hdGl2ZURyYXdhYmxlID0gdHJ1ZTsKKyAgICBpbnQgc3VyZmFjZVR5cGU7CisgICAgaW50IGNzVHlwZTsKKyAgICBDb2xvck1vZGVsIGNtOworICAgIFdyaXRhYmxlUmFzdGVyIHJhc3RlcjsKKyAgICBPYmplY3QgZGF0YTsKKyAgICAKKyAgICBib29sZWFuIG5lZWRUb1JlZnJlc2ggPSB0cnVlOworICAgIGJvb2xlYW4gZGF0YVRha2VuID0gZmFsc2U7CisgICAgCisgICAgcHJpdmF0ZSBsb25nIGNhY2hlZERhdGFQdHI7ICAgICAgIC8vIFBvaW50ZXIgZm9yIGNhY2hlZCBJbWFnZSBEYXRhCisgICAgcHJpdmF0ZSBib29sZWFuIGFscGhhUHJlOyAgICAgICAgIC8vIENhY2hlZCBJbWFnZSBEYXRhIGFscGhhIHByZW11bHRpcGxpZWQgCisKKyAgICBwdWJsaWMgSW1hZ2VTdXJmYWNlKENvbG9yTW9kZWwgY20sIFdyaXRhYmxlUmFzdGVyIHJhc3Rlcil7CisgICAgICAgIHRoaXMoY20sIHJhc3RlciwgU3VyZmFjZS5nZXRUeXBlKGNtLCByYXN0ZXIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSW1hZ2VTdXJmYWNlKENvbG9yTW9kZWwgY20sIFdyaXRhYmxlUmFzdGVyIHJhc3RlciwgaW50IHR5cGUpeworICAgICAgICBpZiAoIWNtLmlzQ29tcGF0aWJsZVJhc3RlcihyYXN0ZXIpKSB7CisgICAgICAgICAgICAvLyBhd3QuNEQ9VGhlIHJhc3RlciBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGlzIENvbG9yTW9kZWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNEQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNtID0gY207CisgICAgICAgIHRoaXMucmFzdGVyID0gcmFzdGVyOworICAgICAgICBzdXJmYWNlVHlwZSA9IHR5cGU7CisKKyAgICAgICAgZGF0YSA9IEF3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5nZXRJbnN0YW5jZSgpLgorICAgICAgICBnZXREYXRhKHJhc3Rlci5nZXREYXRhQnVmZmVyKCkpOworICAgICAgICBDb2xvclNwYWNlIGNzID0gY20uZ2V0Q29sb3JTcGFjZSgpOworICAgICAgICB0cmFuc3BhcmVuY3kgPSBjbS5nZXRUcmFuc3BhcmVuY3koKTsKKyAgICAgICAgd2lkdGggPSByYXN0ZXIuZ2V0V2lkdGgoKTsKKyAgICAgICAgaGVpZ2h0ID0gcmFzdGVyLmdldEhlaWdodCgpOworCisgICAgICAgIC8vIEZvciB0aGUgbW9tZW50IHdlIGNhbiBidWlsZCBuYXRpdmVseSBvbmx5IGltYWdlcyB3aGljaCBoYXZlIAorICAgICAgICAvLyBzUkdCLCBMaW5lYXJfUkdCLCBMaW5lYXJfR3JheSBDb2xvciBTcGFjZSBhbmQgdHlwZSBkaWZmZXJlbnQKKyAgICAgICAgLy8gZnJvbSBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NCisgICAgICAgIGlmKGNzID09IExVVENvbG9yQ29udmVydGVyLnNSR0JfQ1MpeworICAgICAgICAgICAgY3NUeXBlID0gc1JHQl9DUzsKKyAgICAgICAgfWVsc2UgaWYoY3MgPT0gTFVUQ29sb3JDb252ZXJ0ZXIuTElORUFSX1JHQl9DUyl7CisgICAgICAgICAgICBjc1R5cGUgPSBMaW5lYXJfUkdCX0NTOworICAgICAgICB9ZWxzZSBpZihjcyA9PSBMVVRDb2xvckNvbnZlcnRlci5MSU5FQVJfR1JBWV9DUyl7CisgICAgICAgICAgICBjc1R5cGUgPSBMaW5lYXJfR3JheV9DUzsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBjc1R5cGUgPSBDdXN0b21fQ1M7CisgICAgICAgICAgICBuYXRpdmVEcmF3YWJsZSA9IGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYodHlwZSA9PSBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NKXsKKyAgICAgICAgICAgIG5hdGl2ZURyYXdhYmxlID0gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCkgeworICAgICAgICByZXR1cm4gY207CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldFJhc3RlcigpIHsKKyAgICAgICAgcmV0dXJuIHJhc3RlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTdXJmYWNlRGF0YVB0cigpIHsKKyAgICAgICAgaWYoc3VyZmFjZURhdGFQdHIgPT0gMEwgJiYgbmF0aXZlRHJhd2FibGUpeworICAgICAgICAgICAgY3JlYXRlU3VmYWNlU3RydWN0dXJlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cmZhY2VEYXRhUHRyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YSgpeworICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hdGl2ZURyYXdhYmxlKCl7CisgICAgICAgIHJldHVybiBuYXRpdmVEcmF3YWJsZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFN1cmZhY2VUeXBlKCkgeworICAgICAgICByZXR1cm4gc3VyZmFjZVR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuYXRpdmUgU3VyZmFjZSBzdHJ1Y3R1cmUgd2hpY2ggdXNlZCBmb3IgbmF0aXZlIGJsaXR0aW5nCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVN1ZmFjZVN0cnVjdHVyZSgpeworICAgICAgICBpbnQgY21UeXBlID0gMDsKKyAgICAgICAgaW50IG51bUNvbXBvbmVudHMgPSBjbS5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIGJvb2xlYW4gaGFzQWxwaGEgPSBjbS5oYXNBbHBoYSgpOworICAgICAgICBib29sZWFuIGlzQWxwaGFQcmUgPSBjbS5pc0FscGhhUHJlbXVsdGlwbGllZCgpOworICAgICAgICBpbnQgdHJhbnNwYXJlbmN5ID0gY20uZ2V0VHJhbnNwYXJlbmN5KCk7CisgICAgICAgIGludCBiaXRzW10gPSBjbS5nZXRDb21wb25lbnRTaXplKCk7CisgICAgICAgIGludCBwaXhlbFN0cmlkZSA9IGNtLmdldFBpeGVsU2l6ZSgpOworICAgICAgICBpbnQgbWFza3NbXSA9IG51bGw7CisgICAgICAgIGludCBjb2xvck1hcFtdID0gbnVsbDsKKyAgICAgICAgaW50IGNvbG9yTWFwU2l6ZSA9IDA7CisgICAgICAgIGludCB0cmFuc3BQaXhlbCA9IC0xOworICAgICAgICBib29sZWFuIGlzR3JheVBhbGxldGUgPSBmYWxzZTsKKyAgICAgICAgU2FtcGxlTW9kZWwgc20gPSByYXN0ZXIuZ2V0U2FtcGxlTW9kZWwoKTsKKyAgICAgICAgaW50IHNtVHlwZSA9IDA7CisgICAgICAgIGludCBkYXRhVHlwZSA9IHNtLmdldERhdGFUeXBlKCk7CisgICAgICAgIGludCBzY2FubGluZVN0cmlkZSA9IDA7CisgICAgICAgIGludCBiYW5rSW5kZWNlc1tdID0gbnVsbDsKKyAgICAgICAgaW50IGJhbmRPZmZzZXRzW10gPSBudWxsOworICAgICAgICBpbnQgb2Zmc2V0ID0gcmFzdGVyLmdldERhdGFCdWZmZXIoKS5nZXRPZmZzZXQoKTsKKworICAgICAgICBpZihjbSBpbnN0YW5jZW9mIERpcmVjdENvbG9yTW9kZWwpeworICAgICAgICAgICAgY21UeXBlID0gRENNOworICAgICAgICAgICAgRGlyZWN0Q29sb3JNb2RlbCBkY20gPSAoRGlyZWN0Q29sb3JNb2RlbCkgY207CisgICAgICAgICAgICBtYXNrcyA9IGRjbS5nZXRNYXNrcygpOworICAgICAgICAgICAgc21UeXBlID0gU1BQU007CisgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHNtOworICAgICAgICAgICAgc2NhbmxpbmVTdHJpZGUgPSBzcHBzbS5nZXRTY2FubGluZVN0cmlkZSgpOworCisgICAgICAgIH1lbHNlIGlmKGNtIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKXsKKyAgICAgICAgICAgIGNtVHlwZSA9IElDTTsKKyAgICAgICAgICAgIEluZGV4Q29sb3JNb2RlbCBpY20gPSAoSW5kZXhDb2xvck1vZGVsKSBjbTsKKyAgICAgICAgICAgIGNvbG9yTWFwU2l6ZSA9IGljbS5nZXRNYXBTaXplKCk7CisgICAgICAgICAgICBjb2xvck1hcCA9IG5ldyBpbnRbY29sb3JNYXBTaXplXTsKKyAgICAgICAgICAgIGljbS5nZXRSR0JzKGNvbG9yTWFwKTsKKyAgICAgICAgICAgIHRyYW5zcFBpeGVsID0gaWNtLmdldFRyYW5zcGFyZW50UGl4ZWwoKTsKKyAgICAgICAgICAgIGlzR3JheVBhbGxldGUgPSBTdXJmYWNlLmlzR3JheVBhbGxldGUoaWNtKTsKKworICAgICAgICAgICAgaWYoc20gaW5zdGFuY2VvZiBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpeworICAgICAgICAgICAgICAgIHNtVHlwZSA9IE1QUFNNOworICAgICAgICAgICAgICAgIE11bHRpUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBtcHBzbSA9CisgICAgICAgICAgICAgICAgICAgIChNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHNtOworICAgICAgICAgICAgICAgIHNjYW5saW5lU3RyaWRlID0gbXBwc20uZ2V0U2NhbmxpbmVTdHJpZGUoKTsKKyAgICAgICAgICAgIH1lbHNlIGlmKHNtIGluc3RhbmNlb2YgQ29tcG9uZW50U2FtcGxlTW9kZWwpeworICAgICAgICAgICAgICAgIHNtVHlwZSA9IENTTTsKKyAgICAgICAgICAgICAgICBDb21wb25lbnRTYW1wbGVNb2RlbCBjc20gPQorICAgICAgICAgICAgICAgICAgICAoQ29tcG9uZW50U2FtcGxlTW9kZWwpIHNtOworICAgICAgICAgICAgICAgIHNjYW5saW5lU3RyaWRlID0gY3NtLmdldFNjYW5saW5lU3RyaWRlKCk7CisgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEQ9VGhlIHJhc3RlciBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGlzIENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjREIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgfWVsc2UgaWYoY20gaW5zdGFuY2VvZiBDb21wb25lbnRDb2xvck1vZGVsKXsKKyAgICAgICAgICAgIGNtVHlwZSA9IENDTTsKKyAgICAgICAgICAgIGlmKHNtIGluc3RhbmNlb2YgQ29tcG9uZW50U2FtcGxlTW9kZWwpeworICAgICAgICAgICAgICAgIENvbXBvbmVudFNhbXBsZU1vZGVsIGNzbSA9IChDb21wb25lbnRTYW1wbGVNb2RlbCkgc207CisgICAgICAgICAgICAgICAgc2NhbmxpbmVTdHJpZGUgPSBjc20uZ2V0U2NhbmxpbmVTdHJpZGUoKTsKKyAgICAgICAgICAgICAgICBiYW5rSW5kZWNlcyA9IGNzbS5nZXRCYW5rSW5kaWNlcygpOworICAgICAgICAgICAgICAgIGJhbmRPZmZzZXRzID0gY3NtLmdldEJhbmRPZmZzZXRzKCk7CisgICAgICAgICAgICAgICAgaWYoc20gaW5zdGFuY2VvZiBQaXhlbEludGVybGVhdmVkU2FtcGxlTW9kZWwpeworICAgICAgICAgICAgICAgICAgICBzbVR5cGUgPSBQSVNNOworICAgICAgICAgICAgICAgIH1lbHNlIGlmKHNtIGluc3RhbmNlb2YgQmFuZGVkU2FtcGxlTW9kZWwpeworICAgICAgICAgICAgICAgICAgICBzbVR5cGUgPSBCU007CisgICAgICAgICAgICAgICAgfWVsc2V7CisgICAgICAgICAgICAgICAgICAgIHNtVHlwZSA9IENTTTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEQ9VGhlIHJhc3RlciBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGlzIENvbG9yTW9kZWwKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjREIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBzdXJmYWNlRGF0YVB0ciA9IDBMOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHN1cmZhY2VEYXRhUHRyID0gY3JlYXRlU3VyZlN0cnVjdChzdXJmYWNlVHlwZSwgd2lkdGgsIGhlaWdodCwgY21UeXBlLCBjc1R5cGUsIHNtVHlwZSwgZGF0YVR5cGUsCisgICAgICAgICAgICAgICAgbnVtQ29tcG9uZW50cywgcGl4ZWxTdHJpZGUsIHNjYW5saW5lU3RyaWRlLCBiaXRzLCBtYXNrcywgY29sb3JNYXBTaXplLAorICAgICAgICAgICAgICAgIGNvbG9yTWFwLCB0cmFuc3BQaXhlbCwgaXNHcmF5UGFsbGV0ZSwgYmFua0luZGVjZXMsIGJhbmRPZmZzZXRzLAorICAgICAgICAgICAgICAgIG9mZnNldCwgaGFzQWxwaGEsIGlzQWxwaGFQcmUsIHRyYW5zcGFyZW5jeSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKKyAgICAgICAgaWYoc3VyZmFjZURhdGFQdHIgIT0gMEwpeworICAgICAgICAgICAgZGlzcG9zZShzdXJmYWNlRGF0YVB0cik7CisgICAgICAgICAgICBzdXJmYWNlRGF0YVB0ciA9IDBMOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyBsb25nIGdldENhY2hlZERhdGEoYm9vbGVhbiBhbHBoYVByZSl7CisgICAgICAgIGlmKG5hdGl2ZURyYXdhYmxlKXsKKyAgICAgICAgICAgIGlmKGNhY2hlZERhdGFQdHIgPT0gMEwgfHwgbmVlZFRvUmVmcmVzaCB8fCB0aGlzLmFscGhhUHJlICE9IGFscGhhUHJlKXsKKyAgICAgICAgICAgICAgICBjYWNoZWREYXRhUHRyID0gdXBkYXRlQ2FjaGUoZ2V0U3VyZmFjZURhdGFQdHIoKSwgZGF0YSwgYWxwaGFQcmUpOworICAgICAgICAgICAgICAgIHRoaXMuYWxwaGFQcmUgPSBhbHBoYVByZTsKKyAgICAgICAgICAgICAgICB2YWxpZGF0ZSgpOyAKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2FjaGVkRGF0YVB0cjsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIGNyZWF0ZVN1cmZTdHJ1Y3QoaW50IHN1cmZhY2VUeXBlLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIAorICAgICAgICAgICAgaW50IGNtVHlwZSwgaW50IGNzVHlwZSwgaW50IHNtVHlwZSwgaW50IGRhdGFUeXBlLAorICAgICAgICAgICAgaW50IG51bUNvbXBvbmVudHMsIGludCBwaXhlbFN0cmlkZSwgaW50IHNjYW5saW5lU3RyaWRlLAorICAgICAgICAgICAgaW50IGJpdHNbXSwgaW50IG1hc2tzW10sIGludCBjb2xvck1hcFNpemUsIGludCBjb2xvck1hcFtdLAorICAgICAgICAgICAgaW50IHRyYW5zcFBpeGVsLCBib29sZWFuIGlzR3JheVBhbGV0dGUsIGludCBiYW5rSW5kZWNlc1tdLCAKKyAgICAgICAgICAgIGludCBiYW5kT2Zmc2V0c1tdLCBpbnQgb2Zmc2V0LCBib29sZWFuIGhhc0FscGhhLCBib29sZWFuIGlzQWxwaGFQcmUsCisgICAgICAgICAgICBpbnQgdHJhbnNwYXJlbmN5KTsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgZGlzcG9zZShsb25nIHN0cnVjdFB0cik7CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldEltYWdlU2l6ZShsb25nIHN0cnVjdFB0ciwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTsKKworICAgIHByaXZhdGUgbmF0aXZlIGxvbmcgdXBkYXRlQ2FjaGUobG9uZyBzdHJ1Y3RQdHIsIE9iamVjdCBkYXRhLCBib29sZWFuIGFscGhhUHJlKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBTdXBwb3NlcyB0aGF0IG5ldyByYXN0ZXIgaXMgY29tcGF0aWJsZSB3aXRoIGFuIG9sZCBvbmUKKyAgICAgKiBAcGFyYW0gcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJhc3RlcihXcml0YWJsZVJhc3RlciByKSB7CisgICAgICAgIHJhc3RlciA9IHI7CisgICAgICAgIGRhdGEgPSBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuZ2V0SW5zdGFuY2UoKS5nZXREYXRhKHIuZ2V0RGF0YUJ1ZmZlcigpKTsKKyAgICAgICAgaWYgKHN1cmZhY2VEYXRhUHRyICE9IDApIHsKKyAgICAgICAgICAgIHNldEltYWdlU2l6ZShzdXJmYWNlRGF0YVB0ciwgci5nZXRXaWR0aCgpLCByLmdldEhlaWdodCgpKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLndpZHRoID0gci5nZXRXaWR0aCgpOworICAgICAgICB0aGlzLmhlaWdodCA9IHIuZ2V0SGVpZ2h0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9jaygpIHsKKyAgICAgICAgLy8gVE9ETworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB1bmxvY2soKSB7CisgICAgICAgIC8vVE9ETworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdXJmYWNlIGdldEltYWdlU3VyZmFjZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGF0YUNoYW5nZWQoKSB7CisgICAgICAgIG5lZWRUb1JlZnJlc2ggPSB0cnVlOworICAgICAgICBjbGVhclZhbGlkQ2FjaGVzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGF0YVRha2VuKCkgeworICAgICAgICBkYXRhVGFrZW4gPSB0cnVlOworICAgICAgICBuZWVkVG9SZWZyZXNoID0gdHJ1ZTsKKyAgICAgICAgY2xlYXJWYWxpZENhY2hlcygpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBkYXRhUmVsZWFzZWQoKXsKKyAgICAgICAgZGF0YVRha2VuID0gZmFsc2U7CisgICAgICAgIG5lZWRUb1JlZnJlc2ggPSB0cnVlOworICAgICAgICBjbGVhclZhbGlkQ2FjaGVzKCk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKXsKKyAgICAgICAgbmVlZFRvUmVmcmVzaCA9IHRydWU7CisgICAgICAgIGNsZWFyVmFsaWRDYWNoZXMoKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKXsKKyAgICAgICAgaWYoIW5lZWRUb1JlZnJlc2gpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZighZGF0YVRha2VuKXsKKyAgICAgICAgICAgIG5lZWRUb1JlZnJlc2ggPSBmYWxzZTsKKyAgICAgICAgICAgIEF3dEltYWdlQmFja2Rvb3JBY2Nlc3NvciBiYSA9IEF3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5nZXRJbnN0YW5jZSgpOworICAgICAgICAgICAgYmEudmFsaWRhdGUocmFzdGVyLmdldERhdGFCdWZmZXIoKSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGludmFsaWRhdGVkKCl7CisgICAgICAgIHJldHVybiBuZWVkVG9SZWZyZXNoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL011bHRpUmVjdEFyZWEuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL011bHRpUmVjdEFyZWEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDI2N2YzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvTXVsdGlSZWN0QXJlYS5qYXZhCkBAIC0wLDAgKzEsODM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbDsKKworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKK3B1YmxpYyBjbGFzcyBNdWx0aVJlY3RBcmVhIGltcGxlbWVudHMgU2hhcGUgeworCisgICAgLyoqCisgICAgICogSWYgQ0hFQ0sgaXMgdHJ1ZSB2YWxpZGF0aW9uIGNoZWNrIGFjdGl2ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gQ0hFQ0sgPSBmYWxzZTsKKworICAgIGJvb2xlYW4gc29ydGVkID0gdHJ1ZTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZWN0YW5nbGUgYnVmZmVyCisgICAgICovCisgICAgcHVibGljIGludFtdIHJlY3Q7CisgICAgCisgICAgLyoqCisgICAgICogQm91bmRpbmcgYm94CisgICAgICovCisgICAgUmVjdGFuZ2xlIGJvdW5kczsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXN1bHQgcmVjdGFuZ2xlIGFycmF5CisgICAgICovCisgICAgUmVjdGFuZ2xlW10gcmVjdGFuZ2xlczsKKworICAgIC8qKgorICAgICAqIExpbmVDYXNoIHByb3ZpZGVzIGNyZWF0aW5nIE11bHRpUmVjdEFyZWEgbGluZSBieSBsaW5lLiBVc2VkIGluIEphdmFTaGFwZVJhc3Rlcml6ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBMaW5lQ2FzaCBleHRlbmRzIE11bHRpUmVjdEFyZWEgeworCisgICAgICAgIGludCBsaW5lWTsKKyAgICAgICAgaW50IGJvdHRvbUNvdW50OworICAgICAgICBpbnRbXSBib3R0b207CisKKyAgICAgICAgcHVibGljIExpbmVDYXNoKGludCBzaXplKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICAgYm90dG9tID0gbmV3IGludFtzaXplXTsKKyAgICAgICAgICAgIGJvdHRvbUNvdW50ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldExpbmUoaW50IHkpIHsKKyAgICAgICAgICAgIGxpbmVZID0geTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNraXBMaW5lKCkgeworICAgICAgICAgICAgbGluZVkrKzsKKyAgICAgICAgICAgIGJvdHRvbUNvdW50ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGFkZExpbmUoaW50W10gcG9pbnRzLCBpbnQgcG9pbnRDb3VudCkgeworICAgICAgICAgICAgaW50IGJvdHRvbUluZGV4ID0gMDsKKyAgICAgICAgICAgIGludCBwb2ludEluZGV4ID0gMDsKKyAgICAgICAgICAgIGludCByZWN0SW5kZXggPSAwOworICAgICAgICAgICAgaW50IHBvaW50WDEgPSAwOworICAgICAgICAgICAgaW50IHBvaW50WDIgPSAwOworICAgICAgICAgICAgaW50IGJvdHRvbVgxID0gMDsKKyAgICAgICAgICAgIGludCBib3R0b21YMiA9IDA7CisgICAgICAgICAgICBib29sZWFuIGFwcGVuZFJlY3QgPSBmYWxzZTsKKyAgICAgICAgICAgIGJvb2xlYW4gZGVsZXRlUmVjdCA9IGZhbHNlOworICAgICAgICAgICAgaW50IGxhc3RDb3VudCA9IGJvdHRvbUNvdW50OworCisgICAgICAgICAgICB3aGlsZSAoYm90dG9tSW5kZXggPCBsYXN0Q291bnQgfHwgcG9pbnRJbmRleCA8IHBvaW50Q291bnQpIHsKKworICAgICAgICAgICAgICAgIGFwcGVuZFJlY3QgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBkZWxldGVSZWN0ID0gZmFsc2U7CisKKyAgICAgICAgICAgICAgICBpZiAoYm90dG9tSW5kZXggPCBsYXN0Q291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVjdEluZGV4ID0gYm90dG9tW2JvdHRvbUluZGV4XTsKKyAgICAgICAgICAgICAgICAgICAgYm90dG9tWDEgPSByZWN0W3JlY3RJbmRleF07CisgICAgICAgICAgICAgICAgICAgIGJvdHRvbVgyID0gcmVjdFtyZWN0SW5kZXggKyAyXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmRSZWN0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAocG9pbnRJbmRleCA8IHBvaW50Q291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9pbnRYMSA9IHBvaW50c1twb2ludEluZGV4XTsKKyAgICAgICAgICAgICAgICAgICAgcG9pbnRYMiA9IHBvaW50c1twb2ludEluZGV4ICsgMV07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZGVsZXRlUmVjdCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCFkZWxldGVSZWN0ICYmICFhcHBlbmRSZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChwb2ludFgxID09IGJvdHRvbVgxICYmIHBvaW50WDIgPT0gYm90dG9tWDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlY3RbcmVjdEluZGV4ICsgM10gPSByZWN0W3JlY3RJbmRleCArIDNdICsgMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50SW5kZXggKz0gMjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbUluZGV4Kys7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBkZWxldGVSZWN0ID0gcG9pbnRYMiA+PSBib3R0b21YMTsKKyAgICAgICAgICAgICAgICAgICAgYXBwZW5kUmVjdCA9IHBvaW50WDEgPD0gYm90dG9tWDI7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZVJlY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJvdHRvbUluZGV4IDwgYm90dG9tQ291bnQgLSAxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJvdHRvbSwgYm90dG9tSW5kZXggKyAxLCBib3R0b20sIGJvdHRvbUluZGV4LCBib3R0b21Db3VudCAtIGJvdHRvbUluZGV4IC0gMSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZWN0SW5kZXggLT0gNDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBib3R0b21Db3VudC0tOworICAgICAgICAgICAgICAgICAgICBsYXN0Q291bnQtLTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoYXBwZW5kUmVjdCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IHJlY3RbMF07CisgICAgICAgICAgICAgICAgICAgIGJvdHRvbVtib3R0b21Db3VudCsrXSA9IGk7CisgICAgICAgICAgICAgICAgICAgIHJlY3QgPSBNdWx0aVJlY3RBcmVhT3AuY2hlY2tCdWZTaXplKHJlY3QsIDQpOworICAgICAgICAgICAgICAgICAgICByZWN0W2krK10gPSBwb2ludFgxOworICAgICAgICAgICAgICAgICAgICByZWN0W2krK10gPSBsaW5lWTsKKyAgICAgICAgICAgICAgICAgICAgcmVjdFtpKytdID0gcG9pbnRYMjsKKyAgICAgICAgICAgICAgICAgICAgcmVjdFtpKytdID0gbGluZVk7CisgICAgICAgICAgICAgICAgICAgIHBvaW50SW5kZXggKz0gMjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsaW5lWSsrOworCisgICAgICAgICAgICBpbnZhbGlkYXRlKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY3RDYXNoIHByb3ZpZGVzIHNpbXBsZSBjcmVhdGluZyBNdWx0aVJlY3RBcmVhCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBSZWN0Q2FzaCBleHRlbmRzIE11bHRpUmVjdEFyZWEgeworCisgICAgICAgIGludFtdIGNhc2g7CisKKyAgICAgICAgcHVibGljIFJlY3RDYXNoKCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgICAgIGNhc2ggPSBuZXcgaW50W011bHRpUmVjdEFyZWFPcC5SRUNUX0NBUEFDSVRZXTsKKyAgICAgICAgICAgIGNhc2hbMF0gPSAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgYWRkUmVjdENhc2hlZChpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIpIHsKKyAgICAgICAgICAgIGFkZFJlY3QoeDEsIHkxLCB4MiwgeTIpOworICAgICAgICAgICAgaW52YWxpZGF0ZSgpOworLyoKKyAgICAgICAgICAgIC8vIEV4Y2x1ZGUgZnJvbSBjYXNoIHVubmVjZXNzYXJ5IHJlY3RhbmdsZXMKKyAgICAgICAgICAgIGludCBpID0gMTsKKyAgICAgICAgICAgIHdoaWxlKGkgPCBjYXNoWzBdKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlY3RbY2FzaFtpXSArIDNdID49IHkxIC0gMSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2FzaCwgaSwgY2FzaCwgMSwgY2FzaFswXSAtIGkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNoWzBdIC09IGkgLSAxOworCisgICAgICAgICAgICAvLyBGaW5kIGluIGNhc2ggcmVjdGFuZ2xlIHRvIGNvbmNhdGluYXRlCisgICAgICAgICAgICBpID0gMTsKKyAgICAgICAgICAgIHdoaWxlKGkgPCBjYXNoWzBdKSB7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gY2FzaFtpXTsKKyAgICAgICAgICAgICAgICBpZiAocmVjdFtpbmRleCArIDNdICE9IHkxIC0gMSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHJlY3RbaW5kZXhdID09IHgxICYmIHJlY3RbaW5kZXggKyAyXSA9PSB4MikgeworICAgICAgICAgICAgICAgICAgICByZWN0W2luZGV4ICsgM10gKz0geTIgLSB5MSArIDE7CisKKyAgICAgICAgICAgICAgICAgICAgaW50IHBvcyA9IGkgKyAxOworICAgICAgICAgICAgICAgICAgICB3aGlsZShwb3MgPCBjYXNoWzBdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjdFtpbmRleCArIDNdIDw9IHJlY3RbY2FzaFtpXSArIDNdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjYXNoLCBpICsgMSwgY2FzaCwgaSwgcG9zIC0gaSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY2FzaFtwb3MgLSAxXSA9IGluZGV4OworCisgICAgICAgICAgICAgICAgICAgIGludmFsaWRhdGUoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEFkZCByZWN0YW5nbGUgdG8gYnVmZmVyCisgICAgICAgICAgICBpbnQgaW5kZXggPSByZWN0WzBdOworICAgICAgICAgICAgcmVjdCA9IE11bHRpUmVjdEFyZWFPcC5jaGVja0J1ZlNpemUocmVjdCwgNCk7CisgICAgICAgICAgICByZWN0W2luZGV4ICsgMF0gPSB4MTsKKyAgICAgICAgICAgIHJlY3RbaW5kZXggKyAxXSA9IHkxOworICAgICAgICAgICAgcmVjdFtpbmRleCArIDJdID0geDI7CisgICAgICAgICAgICByZWN0W2luZGV4ICsgM10gPSB5MjsKKworICAgICAgICAgICAgLy8gQWRkIHJlY3RhbmdsZSB0byBjYXNoCisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gY2FzaFswXTsKKyAgICAgICAgICAgIGNhc2ggPSBNdWx0aVJlY3RBcmVhT3AuY2hlY2tCdWZTaXplKGNhc2gsIDEpOworICAgICAgICAgICAgd2hpbGUoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIGlmICh5MiA8PSByZWN0W2Nhc2hbaV0gKyAzXSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNhc2gsIGksIGNhc2gsIGkgKyAxLCBsZW5ndGggLSBpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2hbaV0gPSBpbmRleDsKKyAgICAgICAgICAgIGludmFsaWRhdGUoKTsKKyovCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBhZGRSZWN0Q2FzaGVkKGludFtdIHJlY3QsIGludCByZWN0T2ZmLCBpbnQgcmVjdExlbmd0aCkgeworICAgICAgICAgICAgZm9yKGludCBpID0gcmVjdE9mZjsgaSA8IHJlY3RPZmYgKyByZWN0TGVuZ3RoOykgeworICAgICAgICAgICAgICAgIGFkZFJlY3QocmVjdFtpKytdLCByZWN0W2krK10sIHJlY3RbaSsrXSwgcmVjdFtpKytdKTsKKy8vICAgICAgICAgICAgICBhZGRSZWN0Q2FzaGVkKHJlY3RbaSsrXSwgcmVjdFtpKytdLCByZWN0W2krK10sIHJlY3RbaSsrXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIE11bHRpUmVjdEFyZWEgcGF0aCBpdGVyYXRvcgorICAgICAqLworICAgIGNsYXNzIEl0ZXJhdG9yIGltcGxlbWVudHMgUGF0aEl0ZXJhdG9yIHsKKworICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgaW50IGluZGV4OworICAgICAgICBpbnQgcG9zOworCisgICAgICAgIGludFtdIHJlY3Q7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0OworCisgICAgICAgIEl0ZXJhdG9yKE11bHRpUmVjdEFyZWEgbXJhLCBBZmZpbmVUcmFuc2Zvcm0gdCkgeworICAgICAgICAgICAgcmVjdCA9IG5ldyBpbnRbbXJhLnJlY3RbMF0gLSAxXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobXJhLnJlY3QsIDEsIHJlY3QsIDAsIHJlY3QubGVuZ3RoKTsKKyAgICAgICAgICAgIHRoaXMudCA9IHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFdpbmRpbmdSdWxlKCkgeworICAgICAgICAgICAgcmV0dXJuIFdJTkRfTk9OX1pFUk87CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gcG9zID49IHJlY3QubGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChpbmRleCA9PSA0KSB7CisgICAgICAgICAgICAgICAgcG9zICs9IDQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbmRleCA9IChpbmRleCArIDEpICUgNTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZG91YmxlW10gY29vcmRzKSB7CisgICAgICAgICAgICBpZiAoaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuNEI9SWl0ZXJhdG9yIG91dCBvZiBib3VuZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40QiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHR5cGUgPSAwOworCisgICAgICAgICAgICBzd2l0Y2goaW5kZXgpIHsKKyAgICAgICAgICAgIGNhc2UgMCA6CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19NT1ZFVE87CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gcmVjdFtwb3MgKyAwXTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSByZWN0W3BvcyArIDFdOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTElORVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IHJlY3RbcG9zICsgMl07CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gcmVjdFtwb3MgKyAxXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSByZWN0W3BvcyArIDJdOworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHJlY3RbcG9zICsgM107CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19MSU5FVE87CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gcmVjdFtwb3MgKyAwXTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSByZWN0W3BvcyArIDNdOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfQ0xPU0U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LnRyYW5zZm9ybShjb29yZHMsIDAsIGNvb3JkcywgMCwgMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgY3VycmVudFNlZ21lbnQoZmxvYXRbXSBjb29yZHMpIHsKKyAgICAgICAgICAgIGlmIChpc0RvbmUoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC40Qj1JaXRlcmF0b3Igb3V0IG9mIGJvdW5kcworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgdHlwZSA9IDA7CisKKyAgICAgICAgICAgIHN3aXRjaChpbmRleCkgeworICAgICAgICAgICAgY2FzZSAwIDoKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX01PVkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSByZWN0W3BvcyArIDBdOworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHJlY3RbcG9zICsgMV07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19MSU5FVE87CisgICAgICAgICAgICAgICAgY29vcmRzWzBdID0gcmVjdFtwb3MgKyAyXTsKKyAgICAgICAgICAgICAgICBjb29yZHNbMV0gPSByZWN0W3BvcyArIDFdOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgIHR5cGUgPSBTRUdfTElORVRPOworICAgICAgICAgICAgICAgIGNvb3Jkc1swXSA9IHJlY3RbcG9zICsgMl07CisgICAgICAgICAgICAgICAgY29vcmRzWzFdID0gcmVjdFtwb3MgKyAzXTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICB0eXBlID0gU0VHX0xJTkVUTzsKKyAgICAgICAgICAgICAgICBjb29yZHNbMF0gPSByZWN0W3BvcyArIDBdOworICAgICAgICAgICAgICAgIGNvb3Jkc1sxXSA9IHJlY3RbcG9zICsgM107CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDQ6CisgICAgICAgICAgICAgICAgdHlwZSA9IFNFR19DTE9TRTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHQudHJhbnNmb3JtKGNvb3JkcywgMCwgY29vcmRzLCAwLCAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVtcHR5IE11bHRpUmVjdEFyZWEgCisgICAgICovCisgICAgcHVibGljIE11bHRpUmVjdEFyZWEoKSB7CisgICAgICAgIHJlY3QgPSBNdWx0aVJlY3RBcmVhT3AuY3JlYXRlQnVmKDApOworICAgIH0KKworICAgIHB1YmxpYyBNdWx0aVJlY3RBcmVhKGJvb2xlYW4gc29ydGVkKSB7CisgICAgICAgdGhpcygpOworICAgICAgIHRoaXMuc29ydGVkID0gc29ydGVkOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE11bHRpUmVjdEFyZWEgYXMgYSBjb3B5IG9mIGFub3RoZXIgb25lIAorICAgICAqLworICAgIHB1YmxpYyBNdWx0aVJlY3RBcmVhKE11bHRpUmVjdEFyZWEgbXJhKSB7CisgICAgICAgIGlmIChtcmEgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVjdCA9IE11bHRpUmVjdEFyZWFPcC5jcmVhdGVCdWYoMCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZWN0ID0gbmV3IGludFttcmEucmVjdC5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtcmEucmVjdCwgMCwgcmVjdCwgMCwgbXJhLnJlY3QubGVuZ3RoKTsKKyAgICAgICAgICAgIGNoZWNrKHRoaXMsICJNdWx0aVJlY3RBcmVhKE1SQSkiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBNdWx0aVJlY3RBcmVhIGNvbnNpc3RzIG9mIHNpbmdsZSByZWN0YW5nbGUgCisgICAgICovCisgICAgcHVibGljIE11bHRpUmVjdEFyZWEoUmVjdGFuZ2xlIHIpIHsKKyAgICAgICAgcmVjdCA9IE11bHRpUmVjdEFyZWFPcC5jcmVhdGVCdWYoMCk7CisgICAgICAgIGlmIChyICE9IG51bGwgJiYgIXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZWN0WzBdID0gNTsKKyAgICAgICAgICAgIHJlY3RbMV0gPSByLng7CisgICAgICAgICAgICByZWN0WzJdID0gci55OworICAgICAgICAgICAgcmVjdFszXSA9IHIueCArIHIud2lkdGggLSAxOworICAgICAgICAgICAgcmVjdFs0XSA9IHIueSArIHIuaGVpZ2h0IC0gMTsKKyAgICAgICAgfQorICAgICAgICBjaGVjayh0aGlzLCAiTXVsdGlSZWN0QXJlYShSZWN0YW5nbGUpIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE11bHRpUmVjdEFyZWEgY29uc2lzdHMgb2Ygc2luZ2xlIHJlY3RhbmdsZQorICAgICAqLworICAgIHB1YmxpYyBNdWx0aVJlY3RBcmVhKGludCB4MCwgaW50IHkwLCBpbnQgeDEsIGludCB5MSkgeworICAgICAgICByZWN0ID0gTXVsdGlSZWN0QXJlYU9wLmNyZWF0ZUJ1ZigwKTsKKyAgICAgICAgaWYgKHgxID49IHgwICYmIHkxID49IHkwKSB7CisgICAgICAgICAgICByZWN0WzBdID0gNTsKKyAgICAgICAgICAgIHJlY3RbMV0gPSB4MDsKKyAgICAgICAgICAgIHJlY3RbMl0gPSB5MDsKKyAgICAgICAgICAgIHJlY3RbM10gPSB4MTsKKyAgICAgICAgICAgIHJlY3RbNF0gPSB5MTsKKyAgICAgICAgfQorICAgICAgICBjaGVjayh0aGlzLCAiTXVsdGlSZWN0QXJlYShSZWN0YW5nbGUpIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE11bHRpUmVjdEFyZWEgYW5kIGFwcGVuZCByZWN0YW5nbGUgZnJvbSBidWZmZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgTXVsdGlSZWN0QXJlYShSZWN0YW5nbGVbXSBidWYpIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICBmb3IgKFJlY3RhbmdsZSBlbGVtZW50IDogYnVmKSB7CisgICAgICAgICAgICBhZGQoZWxlbWVudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE11bHRpUmVjdEFyZWEgYW5kIGFwcGVuZCByZWN0YW5nbGUgZnJvbSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBNdWx0aVJlY3RBcmVhKEFycmF5TGlzdDxSZWN0YW5nbGU+IGJ1ZikgeworICAgICAgICB0aGlzKCk7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBidWYuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFkZChidWYuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnQgcmVjdGFuZ2xlIGJ1ZmZlcgorICAgICAqLworICAgIHZvaWQgcmVzb3J0KCkgeworICAgICAgICBpbnRbXSBidWYgPSBuZXcgaW50WzRdOworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgcmVjdFswXTsgaSArPSA0KSB7CisgICAgICAgICAgICBpbnQgayA9IGk7CisgICAgICAgICAgICBpbnQgeDEgPSByZWN0W2tdOworICAgICAgICAgICAgaW50IHkxID0gcmVjdFtrICsgMV07CisgICAgICAgICAgICBmb3IoaW50IGogPSBpICsgNDsgaiA8IHJlY3RbMF07IGogKz0gNCkgeworICAgICAgICAgICAgICAgIGludCB4MiA9IHJlY3Rbal07CisgICAgICAgICAgICAgICAgaW50IHkyID0gcmVjdFtqICsgMV07CisgICAgICAgICAgICAgICAgaWYgKHkxID4geTIgfHwgKHkxID09IHkyICYmIHgxID4geDIpKSB7CisgICAgICAgICAgICAgICAgICAgIHgxID0geDI7CisgICAgICAgICAgICAgICAgICAgIHkxID0geTI7CisgICAgICAgICAgICAgICAgICAgIGsgPSBqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrICE9IGkpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlY3QsIGksIGJ1ZiwgMCwgNCk7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShyZWN0LCBrLCByZWN0LCBpLCA0KTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgcmVjdCwgaywgNCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGVxdWFscyB3aXRoIGFub3RoZXIgb2JqZWN0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgTXVsdGlSZWN0QXJlYSkgeworICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBtcmEgPSAoTXVsdGlSZWN0QXJlYSkgb2JqOworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHJlY3RbMF07IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChyZWN0W2ldICE9IG1yYS5yZWN0W2ldKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHZhbGlkYXRpb24gb2YgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBzdGF0aWMgTXVsdGlSZWN0QXJlYSBjaGVjayhNdWx0aVJlY3RBcmVhIG1yYSwgU3RyaW5nIG1zZykgeworICAgICAgICBpZiAoQ0hFQ0sgJiYgbXJhICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChNdWx0aVJlY3RBcmVhLmNoZWNrVmFsaWRhdGlvbihtcmEuZ2V0UmVjdGFuZ2xlcygpLCBtcmEuc29ydGVkKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC40Qz1JbnZhbGlkIE11bHRpUmVjdEFyZWEgaW4gbWV0aG9kIHswfQorICAgICAgICAgICAgICAgIG5ldyBSdW50aW1lRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjRDIiwgbXNnKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbXJhOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB2YWxpZGF0aW9uIG9mIE11bHRpUmVjdEFyZWEgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgY2hlY2tWYWxpZGF0aW9uKFJlY3RhbmdsZVtdIHIsIGJvb2xlYW4gc29ydGVkKSB7CisKKyAgICAgICAgLy8gQ2hlY2sgd2lkdGggYW5kIGhlaWdodAorICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHJbaV0ud2lkdGggPD0gMCB8fCByW2ldLmhlaWdodCA8PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayBvcmRlcgorICAgICAgICBpZiAoc29ydGVkKSB7CisgICAgICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChyW2kgLSAxXS55ID4gcltpXS55KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAocltpIC0gMV0ueSA9PSByW2ldLnkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJbaSAtIDFdLnggPiByW2ldLngpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgb3ZlcnJpZGUKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvcihpbnQgaiA9IGkgKyAxOyBqIDwgci5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGlmIChyW2ldLmludGVyc2VjdHMocltqXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2lnbnMgcmVjdGFuZ2xlIGZyb20gYW5vdGhlciBidWZmZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRSZWN0KGludFtdIGJ1ZiwgYm9vbGVhbiBjb3B5KSB7CisgICAgICAgIGlmIChjb3B5KSB7CisgICAgICAgICAgICByZWN0ID0gbmV3IGludFtidWYubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCByZWN0LCAwLCBidWYubGVuZ3RoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlY3QgPSBidWY7CisgICAgICAgIH0KKyAgICAgICAgaW52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuaW9uIHdpdGggYW5vdGhlciBNdWx0aVJlY3RBcmVhIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZChNdWx0aVJlY3RBcmVhIG1yYSkgeworICAgICAgICBzZXRSZWN0KHVuaW9uKHRoaXMsIG1yYSkucmVjdCwgZmFsc2UpOworICAgICAgICBpbnZhbGlkYXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJzZWN0IHdpdGggYW5vdGhlciBNdWx0aVJlY3RBcmVhIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludGVyc2VjdChNdWx0aVJlY3RBcmVhIG1yYSkgeworICAgICAgICBzZXRSZWN0KGludGVyc2VjdCh0aGlzLCBtcmEpLnJlY3QsIGZhbHNlKTsKKyAgICAgICAgaW52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YnRyYWN0IGFub3RoZXIgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdWJzdHJhY3QoTXVsdGlSZWN0QXJlYSBtcmEpIHsKKyAgICAgICAgc2V0UmVjdChzdWJ0cmFjdCh0aGlzLCBtcmEpLnJlY3QsIGZhbHNlKTsKKyAgICAgICAgaW52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuaW9uIHdpdGggUmVjdGFuZ2xlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZChSZWN0YW5nbGUgcmVjdCkgeworICAgICAgICBzZXRSZWN0KHVuaW9uKHRoaXMsIG5ldyBNdWx0aVJlY3RBcmVhKHJlY3QpKS5yZWN0LCBmYWxzZSk7CisgICAgICAgIGludmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcnNlY3Qgd2l0aCBSZWN0YW5nbGUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgaW50ZXJzZWN0KFJlY3RhbmdsZSByZWN0KSB7CisgICAgICAgIHNldFJlY3QoaW50ZXJzZWN0KHRoaXMsIG5ldyBNdWx0aVJlY3RBcmVhKHJlY3QpKS5yZWN0LCBmYWxzZSk7CisgICAgICAgIGludmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdWJ0cmFjdCByZWN0YW5nbGUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3Vic3RyYWN0KFJlY3RhbmdsZSByZWN0KSB7CisgICAgICAgIHNldFJlY3Qoc3VidHJhY3QodGhpcywgbmV3IE11bHRpUmVjdEFyZWEocmVjdCkpLnJlY3QsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmlvbiB0d28gTXV0bGlSZWN0YXJlQXJlYSBvYmplY3RzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBNdWx0aVJlY3RBcmVhIGludGVyc2VjdChNdWx0aVJlY3RBcmVhIHNyYzEsIE11bHRpUmVjdEFyZWEgc3JjMikgeworICAgICAgICBNdWx0aVJlY3RBcmVhIHJlcyA9IGNoZWNrKE11bHRpUmVjdEFyZWFPcC5JbnRlcnNlY3Rpb24uZ2V0UmVzdWx0KHNyYzEsIHNyYzIpLCAiaW50ZXJzZWN0KE1SQSxNUkEpIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcnNlY3QgdHdvIE11bHRpUmVjdEFyZWEgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTXVsdGlSZWN0QXJlYSB1bmlvbihNdWx0aVJlY3RBcmVhIHNyYzEsIE11bHRpUmVjdEFyZWEgc3JjMikgeworICAgICAgICBNdWx0aVJlY3RBcmVhIHJlcyA9IGNoZWNrKG5ldyBNdWx0aVJlY3RBcmVhT3AuVW5pb24oKS5nZXRSZXN1bHQoc3JjMSwgc3JjMiksICJ1bmlvbihNUkEsTVJBKSIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3VidHJhY3QgdHdvIE11bHRpUmVjdEFyZWEgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTXVsdGlSZWN0QXJlYSBzdWJ0cmFjdChNdWx0aVJlY3RBcmVhIHNyYzEsIE11bHRpUmVjdEFyZWEgc3JjMikgeworICAgICAgICBNdWx0aVJlY3RBcmVhIHJlcyA9IGNoZWNrKE11bHRpUmVjdEFyZWFPcC5TdWJ0cmFjdGlvbi5nZXRSZXN1bHQoc3JjMSwgc3JjMiksICJzdWJ0cmFjdChNUkEsTVJBKSIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnQgTXVsdGlSZWN0QXJlYSBvYmplY3QgdG8gb3V0cHV0IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludChNdWx0aVJlY3RBcmVhIG1yYSwgU3RyaW5nIG1zZykgeworICAgICAgICBpZiAobXJhID09IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihtc2cgKyAiPW51bGwiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUmVjdGFuZ2xlW10gcmVjdHMgPSBtcmEuZ2V0UmVjdGFuZ2xlcygpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG1zZyArICIoIiArIHJlY3RzLmxlbmd0aCArICIpIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICAgICAgZm9yIChSZWN0YW5nbGUgZWxlbWVudCA6IHJlY3RzKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAorICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC54ICsgIiwiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC55ICsgIiwiICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgKGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLSAxKSArICIsIiArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgIChlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCAtIDEpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZSBNdWx0aVJlY3RBcmVhIG9iamVjdCBieSAoeCwgeSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoaW50IHgsIGludCB5KSB7CisgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPCByZWN0WzBdOykgeworICAgICAgICAgICAgcmVjdFtpKytdICs9IHg7CisgICAgICAgICAgICByZWN0W2krK10gKz0geTsKKyAgICAgICAgICAgIHJlY3RbaSsrXSArPSB4OworICAgICAgICAgICAgcmVjdFtpKytdICs9IHk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYm91bmRzICE9IG51bGwgJiYgIWJvdW5kcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGJvdW5kcy50cmFuc2xhdGUoeCwgeSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVjdGFuZ2xlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKFJlY3RhbmdsZSBlbGVtZW50IDogcmVjdGFuZ2xlcykgeworICAgICAgICAgICAgICAgIGVsZW1lbnQudHJhbnNsYXRlKHgsIHkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHJlY3RhbmdsZSB0byB0aGUgYnVmZmVyIHdpdGhvdXQgYW55IGNoZWNraW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUmVjdChpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIpIHsKKyAgICAgICAgaW50IGkgPSByZWN0WzBdOworICAgICAgICByZWN0ID0gTXVsdGlSZWN0QXJlYU9wLmNoZWNrQnVmU2l6ZShyZWN0LCA0KTsKKyAgICAgICAgcmVjdFtpKytdID0geDE7CisgICAgICAgIHJlY3RbaSsrXSA9IHkxOworICAgICAgICByZWN0W2krK10gPSB4MjsKKyAgICAgICAgcmVjdFtpKytdID0geTI7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgaXMgTXVsdGlSZWN0QXJlYSBlbXB0eSAKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gcmVjdFswXSA9PSAxOworICAgIH0KKworICAgIHZvaWQgaW52YWxpZGF0ZSgpIHsKKyAgICAgICAgYm91bmRzID0gbnVsbDsKKyAgICAgICAgcmVjdGFuZ2xlcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBib3VuZHMgb2YgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcygpIHsKKyAgICAgICAgaWYgKGJvdW5kcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYm91bmRzOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGJvdW5kcyA9IG5ldyBSZWN0YW5nbGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCB4MSA9IHJlY3RbMV07CisgICAgICAgIGludCB5MSA9IHJlY3RbMl07CisgICAgICAgIGludCB4MiA9IHJlY3RbM107CisgICAgICAgIGludCB5MiA9IHJlY3RbNF07CisgICAgICAgIAorICAgICAgICBmb3IoaW50IGkgPSA1OyBpIDwgcmVjdFswXTsgaSArPSA0KSB7CisgICAgICAgICAgICBpbnQgcngxID0gcmVjdFtpICsgMF07CisgICAgICAgICAgICBpbnQgcnkxID0gcmVjdFtpICsgMV07CisgICAgICAgICAgICBpbnQgcngyID0gcmVjdFtpICsgMl07CisgICAgICAgICAgICBpbnQgcnkyID0gcmVjdFtpICsgM107CisgICAgICAgICAgICBpZiAocngxIDwgeDEpIHsKKyAgICAgICAgICAgICAgICB4MSA9IHJ4MTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyeDIgPiB4MikgeworICAgICAgICAgICAgICAgIHgyID0gcngyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJ5MSA8IHkxKSB7CisgICAgICAgICAgICAgICAgeTEgPSByeTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocnkyID4geTIpIHsKKyAgICAgICAgICAgICAgICB5MiA9IHJ5MjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcmV0dXJuIGJvdW5kcyA9IG5ldyBSZWN0YW5nbGUoeDEsIHkxLCB4MiAtIHgxICsgMSwgeTIgLSB5MSArIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY3R1cm4gcmVjdGFuZ2xlIGNvdW50IGluIHRoZSBidWZmZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlY3RDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIChyZWN0WzBdIC0gMSkgLyA0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgUmVjdGFuZ2xlIGFycmF5IAorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGVbXSBnZXRSZWN0YW5nbGVzKCkgeworICAgICAgICBpZiAocmVjdGFuZ2xlcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVjdGFuZ2xlczsKKyAgICAgICAgfQorCisgICAgICAgIHJlY3RhbmdsZXMgPSBuZXcgUmVjdGFuZ2xlWyhyZWN0WzBdIC0gMSkgLyA0XTsKKyAgICAgICAgaW50IGogPSAwOworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgcmVjdFswXTsgaSArPSA0KSB7CisgICAgICAgICAgICByZWN0YW5nbGVzW2orK10gPSBuZXcgUmVjdGFuZ2xlKAorICAgICAgICAgICAgICAgICAgICByZWN0W2ldLAorICAgICAgICAgICAgICAgICAgICByZWN0W2kgKyAxXSwKKyAgICAgICAgICAgICAgICAgICAgcmVjdFtpICsgMl0gLSByZWN0W2ldICsgMSwKKyAgICAgICAgICAgICAgICAgICAgcmVjdFtpICsgM10gLSByZWN0W2kgKyAxXSArIDEpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWN0YW5nbGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQm91bmRzMkQKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0Qm91bmRzMkQoKSB7CisgICAgICAgIHJldHVybiBnZXRCb3VuZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBkb2VzIHBvaW50IGxpZSBpbnNpZGUgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHkpIHsKKyAgICAgICAgZm9yKGludCBpID0gMTsgaSA8IHJlY3RbMF07IGkrPSA0KSB7CisgICAgICAgICAgICBpZiAocmVjdFtpXSA8PSB4ICYmIHggPD0gcmVjdFtpICsgMl0gJiYgcmVjdFtpICsgMV0gPD0geSAmJiB5IDw9IHJlY3RbaSArIDNdKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGRvZXMgUG9pbnQyRCBsaWUgaW5zaWRlIE11bHRpUmVjdEFyZWEgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUG9pbnQyRCBwKSB7CisgICAgICAgIHJldHVybiBjb250YWlucyhwLmdldFgoKSwgcC5nZXRZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGRvZXMgcmVjdGFuZ2xlIGxpZSBpbnNpZGUgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB3LCBkb3VibGUgaCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIik7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBkb2VzIFJlY3RhbmdsZTJEIGxpZSBpbnNpZGUgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhSZWN0YW5nbGUyRCByKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGRvZXMgcmVjdGFuZ2xlIGludGVyc2VjdCBNdWx0aVJlY3RBcmVhIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGludGVyc2VjdHMoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgdywgZG91YmxlIGgpIHsKKyAgICAgICAgUmVjdGFuZ2xlIHIgPSBuZXcgUmVjdGFuZ2xlKCk7CisgICAgICAgIHIuc2V0UmVjdCh4LCB5LCB3LCBoKTsKKyAgICAgICAgcmV0dXJuIGludGVyc2VjdHMocik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgZG9lcyBSZWN0YW5nbGUyRCBpbnRlcnNlY3QgTXVsdGlSZWN0QXJlYSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzKFJlY3RhbmdsZTJEIHIpIHsKKyAgICAgICAgaWYgKHIgPT0gbnVsbCB8fCByLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPCByZWN0WzBdOyBpKz0gNCkgeworICAgICAgICAgICAgaWYgKHIuaW50ZXJzZWN0cyhyZWN0W2ldLCByZWN0W2krMV0sIHJlY3RbaSArIDJdLXJlY3RbaV0rMSwgcmVjdFtpICsgM10tcmVjdFtpICsgMV0rMSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBwYXRoIGl0ZXJhdG9yCisgICAgICovCisgICAgcHVibGljIFBhdGhJdGVyYXRvciBnZXRQYXRoSXRlcmF0b3IoQWZmaW5lVHJhbnNmb3JtIHQsIGRvdWJsZSBmbGF0bmVzcykgeworICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKHRoaXMsIHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcGF0aCBpdGVyYXRvcgorICAgICAqLworICAgIHB1YmxpYyBQYXRoSXRlcmF0b3IgZ2V0UGF0aEl0ZXJhdG9yKEFmZmluZVRyYW5zZm9ybSB0KSB7CisgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IodGhpcywgdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBNdWx0aVJlY3RBcmVhIG9iamVjdCBjb252ZXJ0ZWQgdG8gc3RyaW5nIAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGludCBjbnQgPSBnZXRSZWN0Q291bnQoKTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigoY250IDw8IDUpICsgMTI4KTsKKyAgICAgICAgc2IuYXBwZW5kKGdldENsYXNzKCkuZ2V0TmFtZSgpKS5hcHBlbmQoIiBbIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgZm9yKGludCBpID0gMTsgaSA8IHJlY3RbMF07IGkgKz0gNCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKGkgPiAxID8gIiwgWyIgOiAiWyIpLmFwcGVuZChyZWN0W2ldKS5hcHBlbmQoIiwgIikuYXBwZW5kKHJlY3RbaSArIDFdKS4gLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgICAgIGFwcGVuZCgiLCAiKS5hcHBlbmQocmVjdFtpICsgMl0gLSByZWN0W2ldICsgMSkuYXBwZW5kKCIsICIpLiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgIGFwcGVuZChyZWN0W2kgKyAzXSAtIHJlY3RbaSArIDFdICsgMSkuYXBwZW5kKCJdIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2IuYXBwZW5kKCJdIikudG9TdHJpbmcoKTsgLy8kTk9OLU5MUy0xJAorICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9NdWx0aVJlY3RBcmVhT3AuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL011bHRpUmVjdEFyZWFPcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3NWUyMDMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9NdWx0aVJlY3RBcmVhT3AuamF2YQpAQCAtMCwwICsxLDgzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2w7CisKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKK3B1YmxpYyBjbGFzcyBNdWx0aVJlY3RBcmVhT3AgeworCisgICAgLyoqCisgICAgICogUmVjdGFuZ2xlIGJ1ZmZlciBjYXBhY2l0eQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQ1RfQ0FQQUNJVFkgPSAxNjsKKyAgICAKKyAgICAvKioKKyAgICAgKiBJZiBudW1iZXIgb2YgcmVjdGFuZ2xlIGluIE11bHRpUmVjdEFyZWEgb2JqZWN0IGxlc3MgdGhhbiBNQVhfU0lNUExFIHNpbXBsZSBhbGdvcml0aG0gYXBwbGllcyAKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1NJTVBMRSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYnVmZmVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRbXSBjcmVhdGVCdWYoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA9PSAwKSB7CisgICAgICAgICAgICBjYXBhY2l0eSA9IFJFQ1RfQ0FQQUNJVFk7CisgICAgICAgIH0KKyAgICAgICAgaW50W10gYnVmID0gbmV3IGludFtjYXBhY2l0eV07CisgICAgICAgIGJ1ZlswXSA9IDE7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGJ1ZmZlciBzaXplIGFuZCByZWFsbG9jYXRlIGlmIG5lY2Vzc2FyeSAgCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRbXSBjaGVja0J1ZlNpemUoaW50W10gYnVmLCBpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGJ1ZlswXSArIGNhcGFjaXR5ID49IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIGludCBsZW5ndGggPSBidWZbMF0gKyAoY2FwYWNpdHkgPiBSRUNUX0NBUEFDSVRZID8gY2FwYWNpdHkgOiBSRUNUX0NBUEFDSVRZKTsKKyAgICAgICAgICAgIGludFtdIHRtcCA9IG5ldyBpbnRbbGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCB0bXAsIDAsIGJ1ZlswXSk7CisgICAgICAgICAgICBidWYgPSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgYnVmWzBdICs9IGNhcGFjaXR5OworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lvbiBjbGFzcyBwcm92aWRlcyBiYXNpYyBmdW5jdGlvbmxpdHkgZm9yIE11bHRpUmVjdEFyZWEgb2JqZWN0cyB0byBtYWtlIGxvZ2ljYWwgb3BlcmF0aW9ucyAKKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgUmVnaW9uIHsKKworICAgICAgICBpbnRbXSByZWdpb247CisgICAgICAgIGludFtdIGFjdGl2ZTsKKyAgICAgICAgaW50W10gYm90dG9tOworICAgICAgICBpbnQgaW5kZXg7CisKKyAgICAgICAgcHVibGljIFJlZ2lvbihpbnRbXSByZWdpb24pIHsKKyAgICAgICAgICAgIHRoaXMucmVnaW9uID0gcmVnaW9uOworICAgICAgICAgICAgYWN0aXZlID0gbmV3IGludFtSRUNUX0NBUEFDSVRZXTsKKyAgICAgICAgICAgIGJvdHRvbSA9IG5ldyBpbnRbUkVDVF9DQVBBQ0lUWV07CisgICAgICAgICAgICBhY3RpdmVbMF0gPSAxOworICAgICAgICAgICAgYm90dG9tWzBdID0gMTsKKyAgICAgICAgICAgIGluZGV4ID0gMTsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgYWRkQWN0aXZlKGludCBpbmRleCkgeworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGFjdGl2ZVswXTsKKyAgICAgICAgICAgIGFjdGl2ZSA9IGNoZWNrQnVmU2l6ZShhY3RpdmUsIDQpOworICAgICAgICAgICAgaW50IGkgPSAxOworCisgICAgICAgICAgICB3aGlsZShpIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlZ2lvbltpbmRleF0gPCBhY3RpdmVbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSW5zZXJ0CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYWN0aXZlLCBpLCBhY3RpdmUsIGkgKyA0LCBsZW5ndGggLSBpKTsKKyAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gaTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkgKz0gNDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVnaW9uLCBpbmRleCwgYWN0aXZlLCBsZW5ndGgsIDQpOworCisgICAgICAgIH0KKworICAgICAgICB2b2lkIGZpbmRBY3RpdmUoaW50IHRvcCwgaW50IGJvdHRvbSkgeworICAgICAgICAgICAgd2hpbGUoaW5kZXggPCByZWdpb25bMF0pIHsKKyAgICAgICAgICAgICAgICBpZiAocmVnaW9uW2luZGV4ICsgMV0gPiBib3R0b20pIHsgLy8geTEgPiBib3R0b20KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAocmVnaW9uW2luZGV4ICsgM10gPj0gdG9wKSB7IC8vIHkyID49IHRvcAorICAgICAgICAgICAgICAgICAgICBhZGRBY3RpdmUoaW5kZXgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbmRleCArPSA0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdm9pZCBkZWxldGVBY3RpdmUoaW50IGJvdHRvbSkgeworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGFjdGl2ZVswXTsKKyAgICAgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPCBsZW5ndGg7KSB7CisgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVtpICsgM10gPT0gYm90dG9tKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSA0OworICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhY3RpdmUsIGkgKyA0LCBhY3RpdmUsIGksIGxlbmd0aCAtIGkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgIGkgKz0gNDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhY3RpdmVbMF0gPSBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGRlbGV0ZUFjdGl2ZSgpIHsKKyAgICAgICAgICAgIGludCBsZW5ndGggPSBhY3RpdmVbMF07CisgICAgICAgICAgICBmb3IoaW50IGkgPSBsZW5ndGggLSA0OyBpID4gMDsgaSAtPSA0KSB7CisgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVtpICsgMV0gPiBhY3RpdmVbaSArIDNdKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSA0OworICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhY3RpdmUsIGkgKyA0LCBhY3RpdmUsIGksIGxlbmd0aCAtIGkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYWN0aXZlWzBdID0gbGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBjcmVhdGVMZXZlbChpbnRbXSBsZXZlbCkgeworICAgICAgICAgICAgaW50IGxldmVsQ291bnQgPSAxOworICAgICAgICAgICAgaW50IHRvcEluZGV4ID0gMTsKKyAgICAgICAgICAgIGludCBpID0gMTsKKyAgICAgICAgICAgIHdoaWxlKGkgPCByZWdpb25bMF0pIHsKKworICAgICAgICAgICAgICAgIGludCB0b3AgPSByZWdpb25baSArIDFdOworICAgICAgICAgICAgICAgIGludCBib3R0b20gPSByZWdpb25baSArIDNdICsgMTsKKyAgICAgICAgICAgICAgICBpbnQgaiA9IHRvcEluZGV4OworCisgICAgICAgICAgICAgICAgYWRkVG9wOiB7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKGogPCBsZXZlbENvdW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGV2ZWxbal0gPT0gdG9wKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgYWRkVG9wOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxldmVsW2pdID4gdG9wKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbCwgaiwgbGV2ZWwsIGogKyAxLCBsZXZlbENvdW50IC0gaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBqKys7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBsZXZlbFtqXSA9IHRvcDsKKyAgICAgICAgICAgICAgICAgICAgbGV2ZWxDb3VudCsrOworICAgICAgICAgICAgICAgICAgICB0b3BJbmRleCA9IGo7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgYWRkQm90dG9tOiB7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKGogPCBsZXZlbENvdW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGV2ZWxbal0gPT0gYm90dG9tKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgYWRkQm90dG9tOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxldmVsW2pdID4gYm90dG9tKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbCwgaiwgbGV2ZWwsIGogKyAxLCBsZXZlbENvdW50IC0gaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBqKys7CisgICAgICAgICAgICAgICAgICAgIH07CisKKyAgICAgICAgICAgICAgICAgICAgbGV2ZWxbal0gPSBib3R0b207CisgICAgICAgICAgICAgICAgICAgIGxldmVsQ291bnQrKzsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpICs9IDQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsZXZlbFswXSA9IGxldmVsQ291bnQ7CisgICAgICAgIH0KKworICAgICAgICBzdGF0aWMgdm9pZCBzb3J0T3JkZXJlZChpbnRbXSBzcmMxLCBpbnRbXSBzcmMyLCBpbnRbXSBkc3QpIHsKKyAgICAgICAgICAgIGludCBsZW5ndGgxID0gc3JjMVswXTsKKyAgICAgICAgICAgIGludCBsZW5ndGgyID0gc3JjMlswXTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IDE7CisgICAgICAgICAgICBpbnQgaTEgPSAxOworICAgICAgICAgICAgaW50IGkyID0gMTsKKyAgICAgICAgICAgIGludCB2MSA9IHNyYzFbMV07CisgICAgICAgICAgICBpbnQgdjIgPSBzcmMyWzFdOworICAgICAgICAgICAgd2hpbGUodHJ1ZSkgeworCisgICAgICAgICAgICAgICAgTEVGVDogeworICAgICAgICAgICAgICAgICAgICB3aGlsZShpMSA8IGxlbmd0aDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHYxID0gc3JjMVtpMV07CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodjEgPj0gdjIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBMRUZUOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NvdW50KytdID0gdjE7CisgICAgICAgICAgICAgICAgICAgICAgICBpMSsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKGkyIDwgbGVuZ3RoMikgeworICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NvdW50KytdID0gc3JjMltpMisrXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBkc3RbMF0gPSBjb3VudDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIFJJR0hUOiB7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKGkyIDwgbGVuZ3RoMikgeworICAgICAgICAgICAgICAgICAgICAgICAgdjIgPSBzcmMyW2kyXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2MiA+PSB2MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIFJJR0hUOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NvdW50KytdID0gdjI7CisgICAgICAgICAgICAgICAgICAgICAgICBpMisrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKGkxIDwgbGVuZ3RoMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NvdW50KytdID0gc3JjMVtpMSsrXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBkc3RbMF0gPSBjb3VudDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmICh2MSA9PSB2MikgeworICAgICAgICAgICAgICAgICAgICBkc3RbY291bnQrK10gPSB2MTsKKyAgICAgICAgICAgICAgICAgICAgaTErKzsKKyAgICAgICAgICAgICAgICAgICAgaTIrKzsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGkxIDwgbGVuZ3RoMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdjEgPSBzcmMxW2kxXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoaTIgPCBsZW5ndGgyIC0gMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdjIgPSBzcmMyW2kyXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFVOUkVBQ0hBQkxFCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVyc2VjdGlvbiBjbGFzcyBwcm92aWRlcyBpbnRlcnNlY3Rpb24gb2YgdHdvIE11bHRpUmVjdEFyZSBhb2JqZWN0cworICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBJbnRlcnNlY3Rpb24geworCisgICAgICAgIHN0YXRpYyB2b2lkIGludGVyc2VjdFJlZ2lvbnMoaW50W10gcmVnMSwgaW50W10gcmVnMiwgTXVsdGlSZWN0QXJlYS5SZWN0Q2FzaCBkc3QsIGludCBoZWlnaHQxLCBpbnQgaGVpZ2h0MikgeworCisgICAgICAgICAgICBSZWdpb24gZDEgPSBuZXcgUmVnaW9uKHJlZzEpOworICAgICAgICAgICAgUmVnaW9uIGQyID0gbmV3IFJlZ2lvbihyZWcyKTsKKworICAgICAgICAgICAgaW50W10gbGV2ZWwgPSBuZXcgaW50W2hlaWdodDEgKyBoZWlnaHQyXTsKKyAgICAgICAgICAgIGludFtdIGxldmVsMSA9IG5ldyBpbnRbaGVpZ2h0MV07CisgICAgICAgICAgICBpbnRbXSBsZXZlbDIgPSBuZXcgaW50W2hlaWdodDJdOworICAgICAgICAgICAgZDEuY3JlYXRlTGV2ZWwobGV2ZWwxKTsKKyAgICAgICAgICAgIGQyLmNyZWF0ZUxldmVsKGxldmVsMik7CisgICAgICAgICAgICBSZWdpb24uc29ydE9yZGVyZWQobGV2ZWwxLCBsZXZlbDIsIGxldmVsKTsKKworICAgICAgICAgICAgaW50IHRvcDsKKyAgICAgICAgICAgIGludCBib3R0b20gPSBsZXZlbFsxXSAtIDE7CisgICAgICAgICAgICBmb3IoaW50IGkgPSAyOyBpIDwgbGV2ZWxbMF07IGkrKykgeworCisgICAgICAgICAgICAgICAgdG9wID0gYm90dG9tICsgMTsKKyAgICAgICAgICAgICAgICBib3R0b20gPSBsZXZlbFtpXSAtIDE7CisKKyAgICAgICAgICAgICAgICBkMS5maW5kQWN0aXZlKHRvcCwgYm90dG9tKTsKKyAgICAgICAgICAgICAgICBkMi5maW5kQWN0aXZlKHRvcCwgYm90dG9tKTsKKworICAgICAgICAgICAgICAgIGludCBpMSA9IDE7CisgICAgICAgICAgICAgICAgaW50IGkyID0gMTsKKworICAgICAgICAgICAgICAgIHdoaWxlKGkxIDwgZDEuYWN0aXZlWzBdICYmIGkyIDwgZDIuYWN0aXZlWzBdKSB7CisKKyAgICAgICAgICAgICAgICAgICAgaW50IHgxMSA9IGQxLmFjdGl2ZVtpMV07CisgICAgICAgICAgICAgICAgICAgIGludCB4MTIgPSBkMS5hY3RpdmVbaTEgKyAyXTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHgyMSA9IGQyLmFjdGl2ZVtpMl07CisgICAgICAgICAgICAgICAgICAgIGludCB4MjIgPSBkMi5hY3RpdmVbaTIgKyAyXTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoeDExIDw9IHgyMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHgxMiA+PSB4MjEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeDEyIDw9IHgyMikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZCh4MjEsIHRvcCwgeDEyLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMSArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0Q2FzaGVkKHgyMSwgdG9wLCB4MjIsIGJvdHRvbSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkyICs9IDQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMSArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHgyMiA+PSB4MTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeDIyIDw9IHgxMikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZCh4MTEsIHRvcCwgeDIyLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMiArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0Q2FzaGVkKHgxMSwgdG9wLCB4MTIsIGJvdHRvbSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkxICs9IDQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMiArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZDEuZGVsZXRlQWN0aXZlKGJvdHRvbSk7CisgICAgICAgICAgICAgICAgZDIuZGVsZXRlQWN0aXZlKGJvdHRvbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzdGF0aWMgaW50W10gc2ltcGxlSW50ZXJzZWN0KE11bHRpUmVjdEFyZWEgc3JjMSwgTXVsdGlSZWN0QXJlYSBzcmMyKSB7CisgICAgICAgICAgICBpbnRbXSByZWN0MSA9IHNyYzEucmVjdDsKKyAgICAgICAgICAgIGludFtdIHJlY3QyID0gc3JjMi5yZWN0OworICAgICAgICAgICAgaW50W10gcmVjdCA9IGNyZWF0ZUJ1ZigwKTsKKworICAgICAgICAgICAgaW50IGsgPSAxOworICAgICAgICAgICAgZm9yKGludCBpID0gMTsgaSA8IHJlY3QxWzBdOykgeworCisgICAgICAgICAgICAgICAgaW50IHgxMSA9IHJlY3QxW2krK107CisgICAgICAgICAgICAgICAgaW50IHkxMSA9IHJlY3QxW2krK107CisgICAgICAgICAgICAgICAgaW50IHgxMiA9IHJlY3QxW2krK107CisgICAgICAgICAgICAgICAgaW50IHkxMiA9IHJlY3QxW2krK107CisKKyAgICAgICAgICAgICAgICBmb3IoaW50IGogPSAxOyBqIDwgcmVjdDJbMF07KSB7CisKKyAgICAgICAgICAgICAgICAgICAgaW50IHgyMSA9IHJlY3QyW2orK107CisgICAgICAgICAgICAgICAgICAgIGludCB5MjEgPSByZWN0MltqKytdOworICAgICAgICAgICAgICAgICAgICBpbnQgeDIyID0gcmVjdDJbaisrXTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHkyMiA9IHJlY3QyW2orK107CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKHgxMSA8PSB4MjIgJiYgeDEyID49IHgyMSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgeTExIDw9IHkyMiAmJiB5MTIgPj0geTIxKQorICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICByZWN0ID0gY2hlY2tCdWZTaXplKHJlY3QsIDQpOworICAgICAgICAgICAgICAgICAgICAgICAgcmVjdFtrKytdID0geDExID4geDIxID8geDExIDogeDIxOworICAgICAgICAgICAgICAgICAgICAgICAgcmVjdFtrKytdID0geTExID4geTIxID8geTExIDogeTIxOworICAgICAgICAgICAgICAgICAgICAgICAgcmVjdFtrKytdID0geDEyID4geDIyID8geDIyIDogeDEyOworICAgICAgICAgICAgICAgICAgICAgICAgcmVjdFtrKytdID0geTEyID4geTIyID8geTIyIDogeTEyOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZWN0WzBdID0gazsKKyAgICAgICAgICAgIHJldHVybiByZWN0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBNdWx0aVJlY3RBcmVhIGdldFJlc3VsdChNdWx0aVJlY3RBcmVhIHNyYzEsIE11bHRpUmVjdEFyZWEgc3JjMikgeworCisgICAgICAgICAgICBpZiAoc3JjMSA9PSBudWxsIHx8IHNyYzIgPT0gbnVsbCB8fCBzcmMxLmlzRW1wdHkoKSB8fCBzcmMyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlSZWN0QXJlYSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBNdWx0aVJlY3RBcmVhLlJlY3RDYXNoIGRzdCA9IG5ldyBNdWx0aVJlY3RBcmVhLlJlY3RDYXNoKCk7CisKKyAgICAgICAgICAgIGlmICghc3JjMS5zb3J0ZWQgfHwgIXNyYzIuc29ydGVkIHx8IAorICAgICAgICAgICAgICAgc3JjMS5nZXRSZWN0Q291bnQoKSA8PSBNQVhfU0lNUExFIHx8IHNyYzIuZ2V0UmVjdENvdW50KCkgPD0gTUFYX1NJTVBMRSkgCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgZHN0LnNldFJlY3Qoc2ltcGxlSW50ZXJzZWN0KHNyYzEsIHNyYzIpLCBmYWxzZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFJlY3RhbmdsZSBib3VuZHMxID0gc3JjMS5nZXRCb3VuZHMoKTsKKyAgICAgICAgICAgICAgICBSZWN0YW5nbGUgYm91bmRzMiA9IHNyYzIuZ2V0Qm91bmRzKCk7CisgICAgICAgICAgICAgICAgUmVjdGFuZ2xlIGJvdW5kczMgPSBib3VuZHMxLmludGVyc2VjdGlvbihib3VuZHMyKTsKKyAgICAgICAgICAgICAgICBpZiAoYm91bmRzMy53aWR0aCA+IDAgJiYgYm91bmRzMy5oZWlnaHQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGludGVyc2VjdFJlZ2lvbnMoc3JjMS5yZWN0LCBzcmMyLnJlY3QsIGRzdCwgYm91bmRzMS5oZWlnaHQgKyAyLCBib3VuZHMyLmhlaWdodCArIDIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGRzdDsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogVW5pb24gY2xhc3MgcHJvdmlkZXMgdW5pb24gb2YgdHdvIE11bHRpUmVjdEFyZSBhb2JqZWN0cworICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBVbmlvbiB7CisKKyAgICAgICAgaW50IHJ4MSwgcngyOworICAgICAgICBpbnQgdG9wLCBib3R0b207CisgICAgICAgIE11bHRpUmVjdEFyZWEuUmVjdENhc2ggZHN0OworCisgICAgICAgIGJvb2xlYW4gbmV4dChSZWdpb24gZCwgaW50IGluZGV4KSB7CisgICAgICAgICAgICBpbnQgeDEgPSBkLmFjdGl2ZVtpbmRleF07CisgICAgICAgICAgICBpbnQgeDIgPSBkLmFjdGl2ZVtpbmRleCArIDJdOworICAgICAgICAgICAgYm9vbGVhbiByZXMgPSBmYWxzZTsKKworICAgICAgICAgICAgaWYgKHgyIDwgcngxIC0gMSkgeworICAgICAgICAgICAgICAgIHJlcyA9IHRydWU7CisgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3RDYXNoZWQoeDEsIHRvcCwgeDIsIGJvdHRvbSk7CisgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICBpZiAoeDEgPiByeDIgKyAxKSB7CisgICAgICAgICAgICAgICAgICAgIHJlcyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZChyeDEsIHRvcCwgcngyLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICByeDEgPSB4MTsKKyAgICAgICAgICAgICAgICAgICAgcngyID0geDI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzID0geDIgPD0gcngyOworICAgICAgICAgICAgICAgICAgICByeDEgPSBNYXRoLm1pbih4MSwgcngxKTsKKyAgICAgICAgICAgICAgICAgICAgcngyID0gTWF0aC5tYXgoeDIsIHJ4Mik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBUb3AKKyAgICAgICAgICAgIGlmIChkLmFjdGl2ZVtpbmRleCArIDFdIDwgdG9wKSB7CisgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3RDYXNoZWQoeDEsIGQuYWN0aXZlW2luZGV4ICsgMV0sIHgyLCB0b3AgLSAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEJvdHRvbQorICAgICAgICAgICAgaWYgKGQuYWN0aXZlW2luZGV4ICsgM10gPiBib3R0b20pIHsKKyAgICAgICAgICAgICAgICBkLmFjdGl2ZVtpbmRleCArIDFdID0gYm90dG9tICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGNoZWNrKFJlZ2lvbiBkLCBpbnQgaW5kZXgsIGJvb2xlYW4gdCkgeworICAgICAgICAgICAgaW50IHgxID0gZC5hY3RpdmVbaW5kZXhdOworICAgICAgICAgICAgaW50IHgyID0gZC5hY3RpdmVbaW5kZXggKyAyXTsKKyAgICAgICAgICAgIC8vIFRvcAorICAgICAgICAgICAgaWYgKGQuYWN0aXZlW2luZGV4ICsgMV0gPCB0b3ApIHsKKyAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZCh4MSwgZC5hY3RpdmVbaW5kZXggKyAxXSwgeDIsIHRvcCAtIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHQpIHsKKyAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZCh4MSwgdG9wLCB4MiwgYm90dG9tKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEJvdHRvbQorICAgICAgICAgICAgaWYgKGQuYWN0aXZlW2luZGV4ICsgM10gPiBib3R0b20pIHsKKyAgICAgICAgICAgICAgICBkLmFjdGl2ZVtpbmRleCArIDFdID0gYm90dG9tICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgdW5pb25SZWdpb25zKGludFtdIHJlZzEsIGludFtdIHJlZzIsIGludCBoZWlnaHQxLCBpbnQgaGVpZ2h0MikgeworICAgICAgICAgICAgUmVnaW9uIGQxID0gbmV3IFJlZ2lvbihyZWcxKTsKKyAgICAgICAgICAgIFJlZ2lvbiBkMiA9IG5ldyBSZWdpb24ocmVnMik7CisKKyAgICAgICAgICAgIGludFtdIGxldmVsID0gbmV3IGludFtoZWlnaHQxICsgaGVpZ2h0Ml07CisgICAgICAgICAgICBpbnRbXSBsZXZlbDEgPSBuZXcgaW50W2hlaWdodDFdOworICAgICAgICAgICAgaW50W10gbGV2ZWwyID0gbmV3IGludFtoZWlnaHQyXTsKKyAgICAgICAgICAgIGQxLmNyZWF0ZUxldmVsKGxldmVsMSk7CisgICAgICAgICAgICBkMi5jcmVhdGVMZXZlbChsZXZlbDIpOworICAgICAgICAgICAgUmVnaW9uLnNvcnRPcmRlcmVkKGxldmVsMSwgbGV2ZWwyLCBsZXZlbCk7CisKKyAgICAgICAgICAgIGJvdHRvbSA9IGxldmVsWzFdIC0gMTsKKyAgICAgICAgICAgIGZvcihpbnQgaSA9IDI7IGkgPCBsZXZlbFswXTsgaSsrKSB7CisKKyAgICAgICAgICAgICAgICB0b3AgPSBib3R0b20gKyAxOworICAgICAgICAgICAgICAgIGJvdHRvbSA9IGxldmVsW2ldIC0gMTsKKworICAgICAgICAgICAgICAgIGQxLmZpbmRBY3RpdmUodG9wLCBib3R0b20pOworICAgICAgICAgICAgICAgIGQyLmZpbmRBY3RpdmUodG9wLCBib3R0b20pOworCisgICAgICAgICAgICAgICAgaW50IGkxID0gMTsKKyAgICAgICAgICAgICAgICBpbnQgaTIgPSAxOworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzMSwgcmVzMjsKKworICAgICAgICAgICAgICAgIGlmIChkMS5hY3RpdmVbMF0gPiAxKSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrKGQxLCAxLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIHJ4MSA9IGQxLmFjdGl2ZVsxXTsKKyAgICAgICAgICAgICAgICAgICAgcngyID0gZDEuYWN0aXZlWzNdOworICAgICAgICAgICAgICAgICAgICBpMSArPSA0OworICAgICAgICAgICAgICAgICAgICByZXMxID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIHJlczIgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgICAgICAgICBpZiAoZDIuYWN0aXZlWzBdID4gMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2soZDIsIDEsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ4MSA9IGQyLmFjdGl2ZVsxXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ4MiA9IGQyLmFjdGl2ZVszXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGkyICs9IDQ7CisgICAgICAgICAgICAgICAgICAgICAgICByZXMxID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlczIgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG91dGVyOgorICAgICAgICAgICAgICAgIHdoaWxlKHRydWUpIHsKKworICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVzMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkxID49IGQxLmFjdGl2ZVswXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0Q2FzaGVkKHJ4MSwgdG9wLCByeDIsIGJvdHRvbSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUoaTIgPCBkMi5hY3RpdmVbMF0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2soZDIsIGkyLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaTIgKz0gNDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXMxID0gbmV4dChkMSwgaTEpOworICAgICAgICAgICAgICAgICAgICAgICAgaTEgKz0gNDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZXMyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaTIgPj0gZDIuYWN0aXZlWzBdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3RDYXNoZWQocngxLCB0b3AsIHJ4MiwgYm90dG9tKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZShpMSA8IGQxLmFjdGl2ZVswXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVjayhkMSwgaTEsIHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMSArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlczIgPSBuZXh0KGQyLCBpMik7CisgICAgICAgICAgICAgICAgICAgICAgICBpMiArPSA0OworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcmVzMSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHJlczIgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gLy8gd2hpbGUKKworICAgICAgICAgICAgICAgIGQxLmRlbGV0ZUFjdGl2ZShib3R0b20pOworICAgICAgICAgICAgICAgIGQyLmRlbGV0ZUFjdGl2ZShib3R0b20pOworCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzdGF0aWMgdm9pZCBzaW1wbGVVbmlvbihNdWx0aVJlY3RBcmVhIHNyYzEsIE11bHRpUmVjdEFyZWEgc3JjMiwgTXVsdGlSZWN0QXJlYSBkc3QpIHsKKyAgICAgICAgICAgIGlmIChzcmMxLmdldFJlY3RDb3VudCgpIDwgc3JjMi5nZXRSZWN0Q291bnQoKSkgeworICAgICAgICAgICAgICAgIHNpbXBsZVVuaW9uKHNyYzIsIHNyYzEsIGRzdCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFN1YnRyYWN0aW9uLnNpbXBsZVN1YnRyYWN0KHNyYzEsIHNyYzIsIGRzdCk7CisgICAgICAgICAgICAgICAgaW50IHBvcyA9IGRzdC5yZWN0WzBdOworICAgICAgICAgICAgICAgIGludCBzaXplID0gc3JjMi5yZWN0WzBdIC0gMTsKKyAgICAgICAgICAgICAgICBkc3QucmVjdCA9IGNoZWNrQnVmU2l6ZShkc3QucmVjdCwgc2l6ZSk7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMyLnJlY3QsMSwgZHN0LnJlY3QsIHBvcywgc2l6ZSk7CisgICAgICAgICAgICAgICAgZHN0LnJlc29ydCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgTXVsdGlSZWN0QXJlYSBnZXRSZXN1bHQoTXVsdGlSZWN0QXJlYSBzcmMxLCBNdWx0aVJlY3RBcmVhIHNyYzIpIHsKKworICAgICAgICAgICAgaWYgKHNyYzEgPT0gbnVsbCB8fCBzcmMxLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlSZWN0QXJlYShzcmMyKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNyYzIgPT0gbnVsbCB8fCBzcmMyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlSZWN0QXJlYShzcmMxKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZHN0ID0gbmV3IE11bHRpUmVjdEFyZWEuUmVjdENhc2goKTsKKworICAgICAgICAgICAgaWYgKCFzcmMxLnNvcnRlZCB8fCAhc3JjMi5zb3J0ZWQgfHwKKyAgICAgICAgICAgICAgIHNyYzEuZ2V0UmVjdENvdW50KCkgPD0gTUFYX1NJTVBMRSB8fCBzcmMyLmdldFJlY3RDb3VudCgpIDw9IE1BWF9TSU1QTEUpIAorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHNpbXBsZVVuaW9uKHNyYzEsIHNyYzIsIGRzdCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFJlY3RhbmdsZSBib3VuZHMxID0gc3JjMS5nZXRCb3VuZHMoKTsKKyAgICAgICAgICAgICAgICBSZWN0YW5nbGUgYm91bmRzMiA9IHNyYzIuZ2V0Qm91bmRzKCk7CisgICAgICAgICAgICAgICAgUmVjdGFuZ2xlIGJvdW5kczMgPSBib3VuZHMxLmludGVyc2VjdGlvbihib3VuZHMyKTsKKworICAgICAgICAgICAgICAgIGlmIChib3VuZHMzLndpZHRoIDwgMCB8fCBib3VuZHMzLmhlaWdodCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kczEueSArIGJvdW5kczEuaGVpZ2h0IDwgYm91bmRzMi55KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3Quc2V0UmVjdChhZGRWZXJSZWdpb24oc3JjMS5yZWN0LCBzcmMyLnJlY3QpLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kczIueSArIGJvdW5kczIuaGVpZ2h0IDwgYm91bmRzMS55KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LnNldFJlY3QoYWRkVmVyUmVnaW9uKHNyYzIucmVjdCwgc3JjMS5yZWN0KSwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kczEueCA8IGJvdW5kczIueCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3Quc2V0UmVjdChhZGRIb3JSZWdpb24oc3JjMS5yZWN0LCBzcmMyLnJlY3QpLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LnNldFJlY3QoYWRkSG9yUmVnaW9uKHNyYzIucmVjdCwgc3JjMS5yZWN0KSwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB1bmlvblJlZ2lvbnMoc3JjMS5yZWN0LCBzcmMyLnJlY3QsIGJvdW5kczEuaGVpZ2h0ICsgMiwgYm91bmRzMi5oZWlnaHQgKyAyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBkc3Q7CisgICAgICAgIH0KKworICAgICAgICBpbnRbXSBhZGRWZXJSZWdpb24oaW50W10gdG9wLCBpbnRbXSBib3R0b20pIHsKKyAgICAgICAgICAgIGludCBsZW5ndGggPSB0b3BbMF0gKyBib3R0b21bMF0gLSAxOworICAgICAgICAgICAgaW50W10gZHN0ID0gbmV3IGludFtsZW5ndGhdOworICAgICAgICAgICAgZHN0WzBdID0gbGVuZ3RoOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0b3AsIDEsIGRzdCwgMSwgdG9wWzBdIC0gMSk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJvdHRvbSwgMSwgZHN0LCB0b3BbMF0sIGJvdHRvbVswXSAtIDEpOworICAgICAgICAgICAgcmV0dXJuIGRzdDsKKyAgICAgICAgfQorCisgICAgICAgIGludFtdIGFkZEhvclJlZ2lvbihpbnRbXSBsZWZ0LCBpbnRbXSByaWdodCkgeworICAgICAgICAgICAgaW50IGNvdW50MSA9IGxlZnRbMF07CisgICAgICAgICAgICBpbnQgY291bnQyID0gcmlnaHRbMF07CisgICAgICAgICAgICBpbnRbXSBkc3QgPSBuZXcgaW50W2NvdW50MSArIGNvdW50MiArIDFdOworICAgICAgICAgICAgaW50IGNvdW50ID0gMTsKKyAgICAgICAgICAgIGludCBpbmRleDEgPSAxOworICAgICAgICAgICAgaW50IGluZGV4MiA9IDE7CisKKyAgICAgICAgICAgIGludCB0b3AxID0gbGVmdFsyXTsKKyAgICAgICAgICAgIGludCB0b3AyID0gcmlnaHRbMl07CisgICAgICAgICAgICBpbnQgcG9zMSwgcG9zMjsKKworICAgICAgICAgICAgd2hpbGUodHJ1ZSkgeworCisgICAgICAgICAgICAgICAgaWYgKGluZGV4MSA+PSBjb3VudDEpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShyaWdodCwgaW5kZXgyLCBkc3QsIGNvdW50LCBjb3VudDIgLSBpbmRleDIpOworICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudDIgLSBpbmRleDI7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaW5kZXgyID49IGNvdW50MikgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxlZnQsIGluZGV4MSwgZHN0LCBjb3VudCwgY291bnQxIC0gaW5kZXgxKTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gY291bnQxIC0gaW5kZXgxOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAodG9wMSA8IHRvcDIpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zMSA9IGluZGV4MTsKKyAgICAgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgxICs9IDQ7CisgICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGluZGV4MSA8IGNvdW50MSAmJiAodG9wMSA9IGxlZnRbaW5kZXgxICsgMV0pIDwgdG9wMik7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGVmdCwgcG9zMSwgZHN0LCBjb3VudCwgaW5kZXgxIC0gcG9zMSk7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGluZGV4MSAtIHBvczE7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmICh0b3AxID4gdG9wMikgeworICAgICAgICAgICAgICAgICAgICBwb3MyID0gaW5kZXgyOworICAgICAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDIgKz0gNDsKKyAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoaW5kZXgyIDwgY291bnQyICYmICh0b3AyID0gcmlnaHRbaW5kZXgyICsgMV0pIDwgdG9wMSk7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmlnaHQsIHBvczIsIGRzdCwgY291bnQsIGluZGV4MiAtIHBvczIpOworICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBpbmRleDIgLSBwb3MyOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpbnQgdG9wID0gdG9wMTsKKyAgICAgICAgICAgICAgICBwb3MxID0gaW5kZXgxOworICAgICAgICAgICAgICAgIHBvczIgPSBpbmRleDI7CisgICAgICAgICAgICAgICAgZG8gIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXgxICs9IDQ7CisgICAgICAgICAgICAgICAgfSB3aGlsZShpbmRleDEgPCBjb3VudDEgJiYgKHRvcDEgPSBsZWZ0W2luZGV4MSArIDFdKSA9PSB0b3ApOworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXgyICs9IDQ7CisgICAgICAgICAgICAgICAgfSB3aGlsZShpbmRleDIgPCBjb3VudDIgJiYgKHRvcDIgPSByaWdodFtpbmRleDIgKyAxXSkgPT0gdG9wKTsKKworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGVmdCwgcG9zMSwgZHN0LCBjb3VudCwgaW5kZXgxIC0gcG9zMSk7CisgICAgICAgICAgICAgICAgY291bnQgKz0gaW5kZXgxIC0gcG9zMTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJpZ2h0LCBwb3MyLCBkc3QsIGNvdW50LCBpbmRleDIgLSBwb3MyKTsKKyAgICAgICAgICAgICAgICBjb3VudCArPSBpbmRleDIgLSBwb3MyOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBkc3RbMF0gPSBjb3VudDsKKyAgICAgICAgICAgIHJldHVybiBkc3Q7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YnRyYWN0aW9uIGNsYXNzIHByb3ZpZGVzIHN1YnRyYWN0aW9uIG9mIHR3byBNdWx0aVJlY3RBcmUgYW9iamVjdHMKKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgU3VidHJhY3Rpb24geworCisgICAgICAgIHN0YXRpYyB2b2lkIHN1YnRyYWN0UmVnaW9ucyhpbnRbXSByZWcxLCBpbnRbXSByZWcyLCBNdWx0aVJlY3RBcmVhLlJlY3RDYXNoIGRzdCwgaW50IGhlaWdodDEsIGludCBoZWlnaHQyKSB7CisgICAgICAgICAgICBSZWdpb24gZDEgPSBuZXcgUmVnaW9uKHJlZzEpOworICAgICAgICAgICAgUmVnaW9uIGQyID0gbmV3IFJlZ2lvbihyZWcyKTsKKworICAgICAgICAgICAgaW50W10gbGV2ZWwgPSBuZXcgaW50W2hlaWdodDEgKyBoZWlnaHQyXTsKKyAgICAgICAgICAgIGludFtdIGxldmVsMSA9IG5ldyBpbnRbaGVpZ2h0MV07CisgICAgICAgICAgICBpbnRbXSBsZXZlbDIgPSBuZXcgaW50W2hlaWdodDJdOworICAgICAgICAgICAgZDEuY3JlYXRlTGV2ZWwobGV2ZWwxKTsKKyAgICAgICAgICAgIGQyLmNyZWF0ZUxldmVsKGxldmVsMik7CisgICAgICAgICAgICBSZWdpb24uc29ydE9yZGVyZWQobGV2ZWwxLCBsZXZlbDIsIGxldmVsKTsKKworICAgICAgICAgICAgaW50IHRvcDsKKyAgICAgICAgICAgIGludCBib3R0b20gPSBsZXZlbFsxXSAtIDE7CisgICAgICAgICAgICBmb3IoaW50IGkgPSAyOyBpIDwgbGV2ZWxbMF07IGkrKykgeworCisgICAgICAgICAgICAgICAgdG9wID0gYm90dG9tICsgMTsKKyAgICAgICAgICAgICAgICBib3R0b20gPSBsZXZlbFtpXSAtIDE7CisKKyAgICAgICAgICAgICAgICBkMS5maW5kQWN0aXZlKHRvcCwgYm90dG9tKTsKKyAgICAgICAgICAgICAgICBpZiAoZDEuYWN0aXZlWzBdID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgZDIuZGVsZXRlQWN0aXZlKGJvdHRvbSk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGQyLmZpbmRBY3RpdmUodG9wLCBib3R0b20pOworCisgICAgICAgICAgICAgICAgaW50IGkxID0gMTsKKyAgICAgICAgICAgICAgICBpbnQgaTIgPSAxOworCisgICAgICAgICAgICAgICAgaW50IHJ4MSA9IDA7CisgICAgICAgICAgICAgICAgaW50IHJ4MiA9IDA7CisKKyAgICAgICAgICAgICAgICBib29sZWFuIG5leHQgPSB0cnVlOworCisgICAgICAgICAgICAgICAgd2hpbGUodHJ1ZSkgeworCisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaTEgPj0gZDEuYWN0aXZlWzBdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBCb3R0b20KKyAgICAgICAgICAgICAgICAgICAgICAgIGQxLmFjdGl2ZVtpMSArIDFdID0gYm90dG9tICsgMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ4MSA9IGQxLmFjdGl2ZVtpMV07CisgICAgICAgICAgICAgICAgICAgICAgICByeDIgPSBkMS5hY3RpdmVbaTEgKyAyXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGkxICs9IDQ7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoaTIgPj0gZDIuYWN0aXZlWzBdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZChyeDEsIHRvcCwgcngyLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGludCBqID0gaTE7IGogPCBkMS5hY3RpdmVbMF07IGogKz0gNCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0Q2FzaGVkKGQxLmFjdGl2ZVtqXSwgdG9wLCBkMS5hY3RpdmVbaiArIDJdLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQxLmFjdGl2ZVtqICsgMV0gPSBib3R0b20gKyAxOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpbnQgeDEgPSBkMi5hY3RpdmVbaTJdOworICAgICAgICAgICAgICAgICAgICBpbnQgeDIgPSBkMi5hY3RpdmVbaTIgKyAyXTsKKworICAgICAgICAgICAgICAgICAgICBpZiAocngxIDwgeDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyeDIgPj0geDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocngyIDw9IHgyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICBbLS0tLS0tLS0tLS1dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgIFstLS0tLS0tLS0tLS0tXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdENhc2hlZChyeDEsIHRvcCwgeDEgLSAxLCBib3R0b20pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBbLS0tLS0tLS0tLS0tLS0tLS1dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgWy0tLS0tLV0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3RDYXNoZWQocngxLCB0b3AsIHgxIC0gMSwgYm90dG9tKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcngxID0geDIgKyAxOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMiArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWy0tLS0tXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgWy0tLS1dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3RDYXNoZWQocngxLCB0b3AsIHJ4MiwgYm90dG9tKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyeDEgPD0geDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocngyIDw9IHgyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIFstLS0tLS1dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICBbLS0tLS0tLS0tLS1dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBbLS0tLS0tLS0tLS0tXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBbLS0tLS0tLS0tXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByeDEgPSB4MiArIDE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkyICs9IDQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgIFstLS0tXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFstLS0tLV0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMiArPSA0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZDEuZGVsZXRlQWN0aXZlKCk7CisgICAgICAgICAgICAgICAgZDIuZGVsZXRlQWN0aXZlKGJvdHRvbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzdGF0aWMgdm9pZCBzdWJ0cmFjdFJlY3QoaW50IHgxMSwgaW50IHkxMSwgaW50IHgxMiwgaW50IHkxMiwgaW50W10gcmVjdCwgaW50IGluZGV4LCBNdWx0aVJlY3RBcmVhIGRzdCkgeworCisgICAgICAgICAgICBmb3IoaW50IGkgPSBpbmRleDsgaSA8IHJlY3RbMF07IGkgKz0gNCkgeworICAgICAgICAgICAgICAgIGludCB4MjEgPSByZWN0W2kgKyAwXTsKKyAgICAgICAgICAgICAgICBpbnQgeTIxID0gcmVjdFtpICsgMV07CisgICAgICAgICAgICAgICAgaW50IHgyMiA9IHJlY3RbaSArIDJdOworICAgICAgICAgICAgICAgIGludCB5MjIgPSByZWN0W2kgKyAzXTsKKworICAgICAgICAgICAgICAgIGlmICh4MTEgPD0geDIyICYmIHgxMiA+PSB4MjEgJiYgeTExIDw9IHkyMiAmJiB5MTIgPj0geTIxKSB7CisgICAgICAgICAgICAgICAgICAgIGludCB0b3AsIGJvdHRvbTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHkxMSA8IHkyMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3VidHJhY3RSZWN0KHgxMSwgeTExLCB4MTIsIHkyMSAtIDEsIHJlY3QsIGkgKyA0LCBkc3QpOworICAgICAgICAgICAgICAgICAgICAgICAgdG9wID0geTIxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdG9wID0geTExOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICh5MTIgPiB5MjIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1YnRyYWN0UmVjdCh4MTEsIHkyMiArIDEsIHgxMiwgeTEyLCByZWN0LCBpICsgNCwgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IHkyMjsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IHkxMjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoeDExIDwgeDIxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0cmFjdFJlY3QoeDExLCB0b3AsIHgyMSAtIDEsIGJvdHRvbSwgcmVjdCwgaSArIDQsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHgxMiA+IHgyMikgeworICAgICAgICAgICAgICAgICAgICAgICAgc3VidHJhY3RSZWN0KHgyMiArIDEsIHRvcCwgeDEyLCBib3R0b20sIHJlY3QsIGkgKyA0LCBkc3QpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MTEsIHkxMSwgeDEyLCB5MTIpOworICAgICAgICB9CisKKyAgICAgICAgc3RhdGljIHZvaWQgc2ltcGxlU3VidHJhY3QoTXVsdGlSZWN0QXJlYSBzcmMxLCBNdWx0aVJlY3RBcmVhIHNyYzIsIE11bHRpUmVjdEFyZWEgZHN0KSB7CisgICAgICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgc3JjMS5yZWN0WzBdOyBpICs9IDQpIHsKKyAgICAgICAgICAgICAgICBzdWJ0cmFjdFJlY3QoCisgICAgICAgICAgICAgICAgICAgICAgICBzcmMxLnJlY3RbaSArIDBdLAorICAgICAgICAgICAgICAgICAgICAgICAgc3JjMS5yZWN0W2kgKyAxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNyYzEucmVjdFtpICsgMl0sCisgICAgICAgICAgICAgICAgICAgICAgICBzcmMxLnJlY3RbaSArIDNdLAorICAgICAgICAgICAgICAgICAgICAgICAgc3JjMi5yZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkc3QucmVzb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIE11bHRpUmVjdEFyZWEgZ2V0UmVzdWx0KE11bHRpUmVjdEFyZWEgc3JjMSwgTXVsdGlSZWN0QXJlYSBzcmMyKSB7CisKKyAgICAgICAgICAgIGlmIChzcmMxID09IG51bGwgfHwgc3JjMS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE11bHRpUmVjdEFyZWEoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNyYzIgPT0gbnVsbCB8fCBzcmMyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTXVsdGlSZWN0QXJlYShzcmMxKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTXVsdGlSZWN0QXJlYS5SZWN0Q2FzaCBkc3QgPSBuZXcgTXVsdGlSZWN0QXJlYS5SZWN0Q2FzaCgpOworCisgICAgICAgICAgICBpZiAoIXNyYzEuc29ydGVkIHx8ICFzcmMyLnNvcnRlZCB8fAorICAgICAgICAgICAgICAgc3JjMS5nZXRSZWN0Q291bnQoKSA8PSBNQVhfU0lNUExFIHx8IHNyYzIuZ2V0UmVjdENvdW50KCkgPD0gTUFYX1NJTVBMRSkgCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgc2ltcGxlU3VidHJhY3Qoc3JjMSwgc3JjMiwgZHN0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgUmVjdGFuZ2xlIGJvdW5kczEgPSBzcmMxLmdldEJvdW5kcygpOworICAgICAgICAgICAgICAgIFJlY3RhbmdsZSBib3VuZHMyID0gc3JjMi5nZXRCb3VuZHMoKTsKKyAgICAgICAgICAgICAgICBSZWN0YW5nbGUgYm91bmRzMyA9IGJvdW5kczEuaW50ZXJzZWN0aW9uKGJvdW5kczIpOworCisgICAgICAgICAgICAgICAgaWYgKGJvdW5kczMud2lkdGggPiAwICYmIGJvdW5kczMuaGVpZ2h0ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBzdWJ0cmFjdFJlZ2lvbnMoc3JjMS5yZWN0LCBzcmMyLnJlY3QsIGRzdCwgYm91bmRzMS5oZWlnaHQgKyAyLCBib3VuZHMyLmhlaWdodCArIDIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRzdC5zZXRSZWN0KHNyYzEucmVjdCwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gZHN0OworICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL1N1cmZhY2UuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL1N1cmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjBhZTM4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvU3VyZmFjZS5qYXZhCkBAIC0wLDAgKzEsMzA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKiBDcmVhdGVkIG9uIDEwLjExLjIwMDUKKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbDsKKworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEuYXd0LlRyYW5zcGFyZW5jeTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db21wb25lbnRDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbXBvbmVudFNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGlyZWN0Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbmRleENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuTXVsdGlQaXhlbFBhY2tlZFNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yLkxVVENvbG9yQ29udmVydGVyOworCisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBzdXBlciBjbGFzcyBmb3Igb3RoZXJzIHR5cGVzIG9mIFN1cmZhY2VzLiAKKyAqIFN1cmZhY2UgaXMgc3RvcmluZyBkYXRhIGFuZCBkYXRhIGZvcm1hdCBkZXNjcmlwdGlvbiwgdGhhdCBhcmUgdXNpbmcKKyAqIGluIGJsaXR0aW5nIG9wZXJhdGlvbnMgICAgCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTdXJmYWNlIGltcGxlbWVudHMgVHJhbnNwYXJlbmN5eworCisgICAgLy8gQ29sb3IgU3BhY2UgVHlwZXMKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzUkdCX0NTID0gMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMaW5lYXJfUkdCX0NTID0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMaW5lYXJfR3JheV9DUyA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ3VzdG9tX0NTID0gMDsKKyAgICAKKyAgICAvLyBDb2xvciBNb2RlbCBUeXBlcworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERDTSA9IDE7ICAvLyBEaXJlY3QgQ29sb3IgTW9kZWwKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJQ00gPSAyOyAgLy8gSW5kZXggQ29sb3IgTW9kZWwKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQ00gPSAzOyAgLy8gQ29tcG9uZW50IENvbG9yIE1vZGVsCisKKyAgICAvLyBTYW1wbGUgTW9kZWwgVHlwZXMKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUFBTTSA9IDE7ICAvLyBTaW5nbGUgUGl4ZWwgUGFja2VkIFNhbXBsZSBNb2RlbAorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1QUFNNID0gMjsgIC8vIE11bHRpIFBpeGVsIFBhY2tlZCBTYW1wbGUgTW9kZWwKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDU00gICA9IDM7ICAvLyBDb21wb25lbnQgU2FtcGxlIE1vZGVsCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUElTTSAgPSA0OyAgLy8gUGl4ZWwgSW50ZXJsZWF2ZWQgU2FtcGxlIE1vZGVsCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlNNICAgPSA1OyAgLy8gQmFuZGVkIFNhbXBsZSBNb2RlbAorCisgICAgLy8gU3VyZmFjZSBUeXBlcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBTFBIQV9NQVNLID0gMHhmZjAwMDAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVEX01BU0sgPSAweDAwZmYwMDAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUkVFTl9NQVNLID0gMHgwMDAwZmYwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxVRV9NQVNLID0gMHgwMDAwMDBmZjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVEX0JHUl9NQVNLID0gMHgwMDAwMDBmZjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgR1JFRU5fQkdSX01BU0sgPSAweDAwMDBmZjAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCTFVFX0JHUl9NQVNLID0gMHgwMGZmMDAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVEXzU2NV9NQVNLID0gMHhmODAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUkVFTl81NjVfTUFTSyA9IDB4MDdlMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxVRV81NjVfTUFTSyA9IDB4MDAxZjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVEXzU1NV9NQVNLID0gMHg3YzAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUkVFTl81NTVfTUFTSyA9IDB4MDNlMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxVRV81NTVfTUFTSyA9IDB4MDAxZjsKKworICAgIHN0YXRpY3sKKyAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgU3lzdGVtLmxvYWRMaWJyYXJ5KCJnbCIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGluaXRJRHMoKTsKKyAgICAgICAgKi8KKyAgICB9CisKKworICAgIHByb3RlY3RlZCBsb25nIHN1cmZhY2VEYXRhUHRyOyAgICAgICAgLy8gUG9pbnRlciBmb3IgTmF0aXZlIFN1cmZhY2UgZGF0YQorICAgIHByb3RlY3RlZCBpbnQgdHJhbnNwYXJlbmN5ID0gT1BBUVVFOworICAgIHByb3RlY3RlZCBpbnQgd2lkdGg7CisgICAgcHJvdGVjdGVkIGludCBoZWlnaHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGxpc3QgY29udGFpbnMgY2FjaGVzIHdpdGggdGhlIGRhdGEgb2YgdGhpcyBzdXJmYWNlIHRoYXQgYXJlIHZhbGlkIGF0IHRoZSBtb21lbnQuCisgICAgICogU3VyZmFjZSBzaG91bGQgY2xlYXIgdGhpcyBsaXN0IHdoZW4gaXRzIGRhdGEgaXMgdXBkYXRlZC4KKyAgICAgKiBDYWNoZXMgbWF5IGNoZWNrIGlmIHRoZXkgYXJlIHN0aWxsIHZhbGlkIHVzaW5nIGlzQ2FjaGVWYWxpZCBtZXRob2QuCisgICAgICogV2hlbiBjYWNoZSBnZXRzIGRhdGEgZnJvbSB0aGUgc3VyZmFjZSwgaXQgc2hvdWxkIGNhbGwgYWRkVmFsaWRDYWNoZSBtZXRob2Qgb2YgdGhlIHN1cmZhY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3Q8T2JqZWN0PiB2YWxpZENhY2hlcyA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpOworCisgICAgcHVibGljIGFic3RyYWN0IENvbG9yTW9kZWwgZ2V0Q29sb3JNb2RlbCgpOworICAgIHB1YmxpYyBhYnN0cmFjdCBXcml0YWJsZVJhc3RlciBnZXRSYXN0ZXIoKTsKKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFN1cmZhY2VUeXBlKCk7IC8vIFN5cmZhY2UgdHlwZS4gSXQgaXMgZXF1YWwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWZmZXJlZEltZ2UgdHlwZQorICAgIC8qKgorICAgICAqIExvY2sgTmF0aXZlIFN1cmZhY2UgZGF0YQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGxvY2soKTsgICAgIAorICAgIAorICAgIC8qKgorICAgICAqIFVubG9jayBOYXRpdmUgU3VyZmFjZSBkYXRhIAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHVubG9jaygpOworICAgIAorICAgIC8qKgorICAgICAqIERpc3Bvc2UgTmF0aXZlIFN1cmZhY2UgZGF0YQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRpc3Bvc2UoKTsKKyAgICBwdWJsaWMgYWJzdHJhY3QgU3VyZmFjZSBnZXRJbWFnZVN1cmZhY2UoKTsKKworICAgIHB1YmxpYyBsb25nIGdldFN1cmZhY2VEYXRhUHRyKCl7CisgICAgICAgIHJldHVybiBzdXJmYWNlRGF0YVB0cjsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0NhaGVWYWxpZChPYmplY3QgY2FjaGUpIHsKKyAgICAgICAgcmV0dXJuIHZhbGlkQ2FjaGVzLmNvbnRhaW5zKGNhY2hlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBhZGRWYWxpZENhY2hlKE9iamVjdCBjYWNoZSkgeworICAgICAgICB2YWxpZENhY2hlcy5hZGQoY2FjaGUpOworICAgIH0KKworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNsZWFyVmFsaWRDYWNoZXMoKSB7CisgICAgICAgIHZhbGlkQ2FjaGVzLmNsZWFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBjb3VsZCBvciBjb2xkbid0IHRoZSBTdXJmYWNlIGJlIGJsaXQgYnkgTmF0aXZlIGJsaXR0ZXIgCisgICAgICogQHJldHVybiAtIHRydWUgaWYgdGhlIFN1cmZhY2UgY291bGQgYmUgYmxpdCBieSBOYXRpdmUgYmxpdHRlciwgCisgICAgICogICAgICAgICAgIGZhbHNlIGluIG90aGVyIGNhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hdGl2ZURyYXdhYmxlKCl7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0VHJhbnNwYXJlbmN5KCkgeworICAgICAgICByZXR1cm4gdHJhbnNwYXJlbmN5OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0V2lkdGgoKXsKKyAgICAgICAgcmV0dXJuIHdpZHRoOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SGVpZ2h0KCl7CisgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIElmIFN1cmZhY2UgaGFzIFJhc3RlciwgdGhpcyBtZXRob2QgcmV0dXJucyBkYXRhIGFycmF5IG9mIFJhc3RlcidzIERhdGFCdWZmZXIKKyAgICAgKiBAcmV0dXJuIC0gZGF0YSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0RGF0YSgpeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgCisgICAgcHVibGljIGJvb2xlYW4gaW52YWxpZGF0ZWQoKXsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCl7fQorICAgIAorICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKXt9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRhdGlvbiB0eXBlIG9mIEJ1ZmZlcmVkSW1hZ2Ugb3IgU3VyZmFjZQorICAgICAqIEBwYXJhbSBjbSAtIENvbG9yTW9kZWwKKyAgICAgKiBAcGFyYW0gcmFzdGVyIC0gV3JpdGFibGVSYXN0ZQorICAgICAqIEByZXR1cm4gLSB0eXBlIG9mIEJ1ZmZlcmVkSW1hZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRUeXBlKENvbG9yTW9kZWwgY20sIFdyaXRhYmxlUmFzdGVyIHJhc3Rlcil7CisgICAgICAgIGludCB0cmFuc2ZlclR5cGUgPSBjbS5nZXRUcmFuc2ZlclR5cGUoKTsKKyAgICAgICAgYm9vbGVhbiBoYXNBbHBoYSA9IGNtLmhhc0FscGhhKCk7CisgICAgICAgIENvbG9yU3BhY2UgY3MgPSBjbS5nZXRDb2xvclNwYWNlKCk7CisgICAgICAgIGludCBjc1R5cGUgPSBjcy5nZXRUeXBlKCk7CisgICAgICAgIFNhbXBsZU1vZGVsIHNtID0gcmFzdGVyLmdldFNhbXBsZU1vZGVsKCk7CisKKyAgICAgICAgaWYoY3NUeXBlID09IENvbG9yU3BhY2UuVFlQRV9SR0IpeworICAgICAgICAgICAgaWYoY20gaW5zdGFuY2VvZiBEaXJlY3RDb2xvck1vZGVsKXsKKyAgICAgICAgICAgICAgICBEaXJlY3RDb2xvck1vZGVsIGRjbSA9IChEaXJlY3RDb2xvck1vZGVsKSBjbTsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKHRyYW5zZmVyVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGRjbS5nZXRSZWRNYXNrKCkgPT0gUkVEX01BU0sgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkY20uZ2V0R3JlZW5NYXNrKCkgPT0gR1JFRU5fTUFTSyAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRjbS5nZXRCbHVlTWFzaygpID09IEJMVUVfTUFTSykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNBbHBoYSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkY20uZ2V0QWxwaGFNYXNrKCkgPT0gQUxQSEFfTUFTSykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkY20uaXNBbHBoYVByZW11bHRpcGxpZWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCX1BSRTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRjbS5nZXRSZWRNYXNrKCkgPT0gUkVEX0JHUl9NQVNLICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGNtLmdldEdyZWVuTWFzaygpID09IEdSRUVOX0JHUl9NQVNLICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGNtLmdldEJsdWVNYXNrKCkgPT0gQkxVRV9CR1JfTUFTSykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNBbHBoYSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX0JHUjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUOgorICAgICAgICAgICAgICAgICAgICBpZiAoZGNtLmdldFJlZE1hc2soKSA9PSBSRURfNTU1X01BU0sgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkY20uZ2V0R3JlZW5NYXNrKCkgPT0gR1JFRU5fNTU1X01BU0sgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkY20uZ2V0Qmx1ZU1hc2soKSA9PSBCTFVFXzU1NV9NQVNLICYmICFoYXNBbHBoYSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9VU0hPUlRfNTU1X1JHQjsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkY20uZ2V0UmVkTWFzaygpID09IFJFRF81NjVfTUFTSyAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRjbS5nZXRHcmVlbk1hc2soKSA9PSBHUkVFTl81NjVfTUFTSyAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRjbS5nZXRCbHVlTWFzaygpID09IEJMVUVfNTY1X01BU0spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUXzU2NV9SR0I7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9ZWxzZSBpZihjbSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCl7CisgICAgICAgICAgICAgICAgSW5kZXhDb2xvck1vZGVsIGljbSA9IChJbmRleENvbG9yTW9kZWwpIGNtOworICAgICAgICAgICAgICAgIGludCBwaXhlbEJpdHMgPSBpY20uZ2V0UGl4ZWxTaXplKCk7CisgICAgICAgICAgICAgICAgaWYodHJhbnNmZXJUeXBlID09IERhdGFCdWZmZXIuVFlQRV9CWVRFKXsKKyAgICAgICAgICAgICAgICAgICAgaWYoc20gaW5zdGFuY2VvZiBNdWx0aVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgJiYgIWhhc0FscGhhICYmCisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbEJpdHMgPCA1KXsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0JZVEVfQklOQVJZOworICAgICAgICAgICAgICAgICAgICB9ZWxzZSBpZihwaXhlbEJpdHMgPT0gOCl7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0JZVEVfSU5ERVhFRDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICAgICAgICAgIH1lbHNlIGlmKGNtIGluc3RhbmNlb2YgQ29tcG9uZW50Q29sb3JNb2RlbCl7CisgICAgICAgICAgICAgICAgQ29tcG9uZW50Q29sb3JNb2RlbCBjY20gPSAoQ29tcG9uZW50Q29sb3JNb2RlbCkgY207CisgICAgICAgICAgICAgICAgaWYodHJhbnNmZXJUeXBlID09IERhdGFCdWZmZXIuVFlQRV9CWVRFICYmCisgICAgICAgICAgICAgICAgICAgICAgICBzbSBpbnN0YW5jZW9mIENvbXBvbmVudFNhbXBsZU1vZGVsKXsKKyAgICAgICAgICAgICAgICAgICAgQ29tcG9uZW50U2FtcGxlTW9kZWwgY3NtID0KKyAgICAgICAgICAgICAgICAgICAgICAgIChDb21wb25lbnRTYW1wbGVNb2RlbCkgc207CisgICAgICAgICAgICAgICAgICAgIGludFtdIG9mZnNldHMgPSBjc20uZ2V0QmFuZE9mZnNldHMoKTsKKyAgICAgICAgICAgICAgICAgICAgaW50W10gYml0cyA9IGNjbS5nZXRDb21wb25lbnRTaXplKCk7CisgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNDdXN0b20gPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiaXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYml0c1tpXSAhPSA4IHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0c1tpXSAhPSBvZmZzZXRzLmxlbmd0aCAtIDEgLSBpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDdXN0b20gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICghaXNDdXN0b20pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2NtLmhhc0FscGhhKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFXzNCWVRFX0JHUjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2NtLmlzQWxwaGFQcmVtdWx0aXBsaWVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFXzRCWVRFX0FCR1JfUFJFOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFXzRCWVRFX0FCR1I7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9DVVNUT007CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICAgICAgfWVsc2UgaWYoY3MgPT0gTFVUQ29sb3JDb252ZXJ0ZXIuTElORUFSX0dSQVlfQ1MpeworICAgICAgICAgICAgaWYoY20gaW5zdGFuY2VvZiBDb21wb25lbnRDb2xvck1vZGVsICYmCisgICAgICAgICAgICAgICAgICAgIGNtLmdldE51bUNvbXBvbmVudHMoKSA9PSAxKXsKKyAgICAgICAgICAgICAgICBpbnQgYml0c1tdID0gY20uZ2V0Q29tcG9uZW50U2l6ZSgpOworICAgICAgICAgICAgICAgIGlmKHRyYW5zZmVyVHlwZSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgYml0c1swXSA9PSA4KXsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0dSQVk7CisgICAgICAgICAgICAgICAgfWVsc2UgaWYodHJhbnNmZXJUeXBlID09IERhdGFCdWZmZXIuVFlQRV9VU0hPUlQgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgIGJpdHNbMF0gPT0gMTYpeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF9HUkFZOworICAgICAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQnVmZmVyZWRJbWFnZS5UWVBFX0NVU1RPTTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN1cmZhY2UgZ2V0SW1hZ2VTdXJmYWNlKEltYWdlIGltYWdlKXsKKyAgICAgICAgcmV0dXJuIEF3dEltYWdlQmFja2Rvb3JBY2Nlc3Nvci5nZXRJbnN0YW5jZSgpLmdldEltYWdlU3VyZmFjZShpbWFnZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxleworICAgICAgICBkaXNwb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzR3JheVBhbGxldGUoSW5kZXhDb2xvck1vZGVsIGljbSl7CisgICAgICAgIHJldHVybiBBd3RJbWFnZUJhY2tkb29yQWNjZXNzb3IuZ2V0SW5zdGFuY2UoKS5pc0dyYXlQYWxsZXRlKGljbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6YXRpb24gb2YgTmF0aXZlIGRhdGEKKyAgICAgKiAKKyAgICAgKi8KKyAgICAvLz8/P0FXVDogcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgaW5pdElEcygpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvVGV4dFJlbmRlcmVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9UZXh0UmVuZGVyZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNTc5NTJkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvVGV4dFJlbmRlcmVyLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2w7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhWZWN0b3I7CisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUZXh0UmVuZGVyZXIgeworICAgIAorICAgIC8qKgorICAgICAqIERyYXdzIHN0cmluZyBvbiBzcGVjaWZpZWQgR3JhcGhpY3MgYXQgZGVzaXJlZCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZyBzcGVjaWZpZWQgR3JhcGhpY3MyRCBvYmplY3QKKyAgICAgKiBAcGFyYW0gc3RyIFN0cmluZyBvYmplY3QgdG8gZHJhdworICAgICAqIEBwYXJhbSB4IHN0YXJ0IFggcG9zaXRpb24gdG8gZHJhdworICAgICAqIEBwYXJhbSB5IHN0YXJ0IFkgcG9zaXRpb24gdG8gZHJhdworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRyYXdTdHJpbmcoR3JhcGhpY3MyRCBnLCBTdHJpbmcgc3RyLCBmbG9hdCB4LCBmbG9hdCB5KTsKKworICAgIC8qKgorICAgICAqIERyYXdzIHN0cmluZyBvbiBzcGVjaWZpZWQgR3JhcGhpY3MgYXQgZGVzaXJlZCBwb3NpdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZyBzcGVjaWZpZWQgR3JhcGhpY3MyRCBvYmplY3QKKyAgICAgKiBAcGFyYW0gc3RyIFN0cmluZyBvYmplY3QgdG8gZHJhdworICAgICAqIEBwYXJhbSB4IHN0YXJ0IFggcG9zaXRpb24gdG8gZHJhdworICAgICAqIEBwYXJhbSB5IHN0YXJ0IFkgcG9zaXRpb24gdG8gZHJhdworICAgICAqLyAgICAKKyAgICBwdWJsaWMgdm9pZCBkcmF3U3RyaW5nKEdyYXBoaWNzMkQgZywgU3RyaW5nIHN0ciwgaW50IHgsIGludCB5KXsKKyAgICAgICAgZHJhd1N0cmluZyhnLCBzdHIsIChmbG9hdCl4LCAoZmxvYXQpeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRHJhd3MgR2x5cGhWZWN0b3Igb24gc3BlY2lmaWVkIEdyYXBoaWNzIGF0IGRlc2lyZWQgcG9zaXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGcgc3BlY2lmaWVkIEdyYXBoaWNzMkQgb2JqZWN0CisgICAgICogQHBhcmFtIGdseXBoVmVjdG9yIEdseXBoVmVjdG9yIG9iamVjdCB0byBkcmF3CisgICAgICogQHBhcmFtIHggc3RhcnQgWCBwb3NpdGlvbiB0byBkcmF3CisgICAgICogQHBhcmFtIHkgc3RhcnQgWSBwb3NpdGlvbiB0byBkcmF3CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZHJhd0dseXBoVmVjdG9yKEdyYXBoaWNzMkQgZywgR2x5cGhWZWN0b3IgZ2x5cGhWZWN0b3IsIGZsb2F0IHgsIGZsb2F0IHkpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvWE9SQ29tcG9zaXRlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9YT1JDb21wb3NpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjdlMWQzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvWE9SQ29tcG9zaXRlLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICogQ3JlYXRlZCBvbiAyMS4xMS4yMDA1CisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2w7CisKK2ltcG9ydCBqYXZhLmF3dC5Db2xvcjsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGU7CitpbXBvcnQgamF2YS5hd3QuQ29tcG9zaXRlQ29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5SZW5kZXJpbmdIaW50czsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworCitwdWJsaWMgY2xhc3MgWE9SQ29tcG9zaXRlIGltcGxlbWVudHMgQ29tcG9zaXRlIHsKKworICAgIENvbG9yIHhvcmNvbG9yOworCisgICAgcHVibGljIFhPUkNvbXBvc2l0ZShDb2xvciB4b3Jjb2xvcil7CisgICAgICAgIHRoaXMueG9yY29sb3IgPSB4b3Jjb2xvcjsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29tcG9zaXRlQ29udGV4dCBjcmVhdGVDb250ZXh0KENvbG9yTW9kZWwgc3JjQ00sIENvbG9yTW9kZWwgZHN0Q00sCisgICAgICAgICAgICBSZW5kZXJpbmdIaW50cyBoaW50cykgeworCisgICAgICAgIHJldHVybiBuZXcgSUNvbXBvc2l0ZUNvbnRleHQodGhpcywgc3JjQ00sIGRzdENNKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29sb3IgZ2V0WE9SQ29sb3IoKXsKKyAgICAgICAgcmV0dXJuIHhvcmNvbG9yOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL0NvbG9yQ29udmVydGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9Db2xvckNvbnZlcnRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5OGUxMTQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9Db2xvckNvbnZlcnRlci5qYXZhCkBAIC0wLDAgKzEsMjU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yOworCitpbXBvcnQgamF2YS5hd3QuY29sb3IuQ29sb3JTcGFjZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLldyaXRhYmxlUmFzdGVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgY29tYmluZXMgQ29sb3JTY2FsZXIsIElDQ19UcmFuc2Zvcm0gYW5kIE5hdGl2ZUltYWdlRm9ybWF0IGZ1bmN0aW9uYWxpdHkKKyAqIGluIHRoZSB3b3JrZmxvd3MgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBpbnB1dC9vdXRwdXQgcGl4ZWwgZGF0YS4KKyAqLworcHVibGljIGNsYXNzIENvbG9yQ29udmVydGVyIHsKKyAgICBwcml2YXRlIENvbG9yU2NhbGVyIHNjYWxlciA9IG5ldyBDb2xvclNjYWxlcigpOworCisgICAgcHVibGljIHZvaWQgbG9hZFNjYWxpbmdEYXRhKENvbG9yU3BhY2UgY3MpIHsKKyAgICAgICAgc2NhbGVyLmxvYWRTY2FsaW5nRGF0YShjcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNsYXRlcyBwaXhlbHMsIHN0b3JlZCBpbiBzb3VyY2UgYnVmZmVyZWQgaW1hZ2UgYW5kIHdyaXRlcyB0aGUgZGF0YQorICAgICAqIHRvIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyAgICAgKiBAcGFyYW0gdCAtIElDQyB0cmFuc2Zvcm0KKyAgICAgKiBAcGFyYW0gc3JjIC0gc291cmNlIGltYWdlCisgICAgICogQHBhcmFtIGRzdCAtIGRlc3RpbmF0aW9uIGltYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQ29sb3IoSUNDX1RyYW5zZm9ybSB0LAorICAgICAgICAgICAgQnVmZmVyZWRJbWFnZSBzcmMsIEJ1ZmZlcmVkSW1hZ2UgZHN0KSB7CisgICAgICBOYXRpdmVJbWFnZUZvcm1hdCBzcmNJRiA9IE5hdGl2ZUltYWdlRm9ybWF0LmNyZWF0ZU5hdGl2ZUltYWdlRm9ybWF0KHNyYyk7CisgICAgICBOYXRpdmVJbWFnZUZvcm1hdCBkc3RJRiA9IE5hdGl2ZUltYWdlRm9ybWF0LmNyZWF0ZU5hdGl2ZUltYWdlRm9ybWF0KGRzdCk7CisKKyAgICAgIGlmIChzcmNJRiAhPSBudWxsICYmIGRzdElGICE9IG51bGwpIHsKKyAgICAgICAgICB0LnRyYW5zbGF0ZUNvbG9ycyhzcmNJRiwgZHN0SUYpOworICAgICAgICAgIHJldHVybjsKKyAgICAgIH0KKworICAgICAgICBzcmNJRiA9IGNyZWF0ZUltYWdlRm9ybWF0KHNyYyk7CisgICAgICAgIGRzdElGID0gY3JlYXRlSW1hZ2VGb3JtYXQoZHN0KTsKKworICAgICAgICBzaG9ydCBzcmNDaGFuRGF0YVtdID0gKHNob3J0W10pIHNyY0lGLmdldENoYW5uZWxEYXRhKCk7CisgICAgICAgIHNob3J0IGRzdENoYW5EYXRhW10gPSAoc2hvcnRbXSkgZHN0SUYuZ2V0Q2hhbm5lbERhdGEoKTsKKworICAgICAgICBDb2xvck1vZGVsIHNyY0NNID0gc3JjLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgaW50IG5Db2xvckNoYW5uZWxzID0gc3JjQ00uZ2V0TnVtQ29sb3JDb21wb25lbnRzKCk7CisgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEoc3JjQ00uZ2V0Q29sb3JTcGFjZSgpKTsgLy8gaW5wdXQgc2NhbGluZyBkYXRhCisgICAgICAgIENvbG9yTW9kZWwgZHN0Q00gPSBkc3QuZ2V0Q29sb3JNb2RlbCgpOworCisgICAgICAgIC8vIFByZXBhcmUgYXJyYXkgZm9yIGFscGhhIGNoYW5uZWwKKyAgICAgICAgZmxvYXQgYWxwaGFbXSA9IG51bGw7CisgICAgICAgIGJvb2xlYW4gc2F2ZUFscGhhID0gc3JjQ00uaGFzQWxwaGEoKSAmJiBkc3RDTS5oYXNBbHBoYSgpOworICAgICAgICBpZiAoc2F2ZUFscGhhKSB7CisgICAgICAgICAgICBhbHBoYSA9IG5ldyBmbG9hdFtzcmMuZ2V0V2lkdGgoKSpzcmMuZ2V0SGVpZ2h0KCldOworICAgICAgICB9CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgd3IgPSBzcmMuZ2V0UmFzdGVyKCk7CisgICAgICAgIGludCBzcmNEYXRhUG9zID0gMCwgYWxwaGFQb3MgPSAwOworICAgICAgICBmbG9hdCBub3JtYWxpemVkVmFsW107CisgICAgICAgIGZvciAoaW50IHJvdz0wLCBuUm93cyA9IHNyY0lGLmdldE51bVJvd3MoKTsgcm93PG5Sb3dzOyByb3crKykgeworICAgICAgICAgICAgZm9yIChpbnQgY29sPTAsIG5Db2xzID0gc3JjSUYuZ2V0TnVtQ29scygpOyBjb2w8bkNvbHM7IGNvbCsrKSB7CisgICAgICAgICAgICAgICAgbm9ybWFsaXplZFZhbCA9IHNyY0NNLmdldE5vcm1hbGl6ZWRDb21wb25lbnRzKAorICAgICAgICAgICAgICAgICAgICB3ci5nZXREYXRhRWxlbWVudHMoY29sLCByb3csIG51bGwpLAorICAgICAgICAgICAgICAgICAgICBudWxsLCAwKTsKKyAgICAgICAgICAgICAgICAvLyBTYXZlIGFscGhhIGNoYW5uZWwKKyAgICAgICAgICAgICAgICBpZiAoc2F2ZUFscGhhKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgbkNvbG9yQ2hhbm5lbHMndGggZWxlbWVudCBjYXVzZSBpdCdzIG5DaGFubmVscyAtIDEKKyAgICAgICAgICAgICAgICAgICAgYWxwaGFbYWxwaGFQb3MrK10gPSBub3JtYWxpemVkVmFsW25Db2xvckNoYW5uZWxzXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2NhbGVyLnNjYWxlKG5vcm1hbGl6ZWRWYWwsIHNyY0NoYW5EYXRhLCBzcmNEYXRhUG9zKTsKKyAgICAgICAgICAgICAgICBzcmNEYXRhUG9zICs9IG5Db2xvckNoYW5uZWxzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdC50cmFuc2xhdGVDb2xvcnMoc3JjSUYsIGRzdElGKTsKKworICAgICAgICBuQ29sb3JDaGFubmVscyA9IGRzdENNLmdldE51bUNvbG9yQ29tcG9uZW50cygpOworICAgICAgICBib29sZWFuIGZpbGxBbHBoYSA9IGRzdENNLmhhc0FscGhhKCk7CisgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEoZHN0Q00uZ2V0Q29sb3JTcGFjZSgpKTsgLy8gb3V0cHV0IHNjYWxpbmcgZGF0YQorICAgICAgICBmbG9hdCBkc3RQaXhlbFtdID0gbmV3IGZsb2F0W2RzdENNLmdldE51bUNvbXBvbmVudHMoKV07CisgICAgICAgIGludCBkc3REYXRhUG9zID0gMDsKKyAgICAgICAgYWxwaGFQb3MgPSAwOworICAgICAgICB3ciA9IGRzdC5nZXRSYXN0ZXIoKTsKKworICAgICAgICBmb3IgKGludCByb3c9MCwgblJvd3MgPSBkc3RJRi5nZXROdW1Sb3dzKCk7IHJvdzxuUm93czsgcm93KyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGNvbD0wLCBuQ29scyA9IGRzdElGLmdldE51bUNvbHMoKTsgY29sPG5Db2xzOyBjb2wrKykgeworICAgICAgICAgICAgICAgIHNjYWxlci51bnNjYWxlKGRzdFBpeGVsLCBkc3RDaGFuRGF0YSwgZHN0RGF0YVBvcyk7CisgICAgICAgICAgICAgICAgZHN0RGF0YVBvcyArPSBuQ29sb3JDaGFubmVsczsKKyAgICAgICAgICAgICAgICBpZiAoZmlsbEFscGhhKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChzYXZlQWxwaGEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdFBpeGVsW25Db2xvckNoYW5uZWxzXSA9IGFscGhhW2FscGhhUG9zKytdOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZHN0UGl4ZWxbbkNvbG9yQ2hhbm5lbHNdID0gMWY7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd3Iuc2V0RGF0YUVsZW1lbnRzKGNvbCwgcm93LAorICAgICAgICAgICAgICAgICAgICAgICAgZHN0Q00uZ2V0RGF0YUVsZW1lbnRzKGRzdFBpeGVsLCAwICwgbnVsbCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNsYXRlcyBwaXhlbHMsIHN0b3JlZCBpbiB0aGUgZmxvYXQgZGF0YSBidWZmZXIuCisgICAgICogRWFjaCBwaXhlbCBvY2N1cGllcyBzZXBhcmF0ZSBhcnJheS4gSW5wdXQgcGl4ZWxzIHBhc3NlZCBpbiB0aGUgYnVmZmVyCisgICAgICogYXJlIHJlcGxhY2VkIGJ5IG91dHB1dCBwaXhlbHMgYW5kIHRoZW4gdGhlIGJ1ZmZlciBpcyByZXR1cm5lZAorICAgICAqIEBwYXJhbSB0IC0gSUNDIHRyYW5zZm9ybQorICAgICAqIEBwYXJhbSBidWZmZXIgLSBkYXRhIGJ1ZmZlcgorICAgICAqIEBwYXJhbSBzcmNDUyAtIHNvdXJjZSBjb2xvciBzcGFjZQorICAgICAqIEBwYXJhbSBkc3RDUyAtIGRlc3RpbmF0aW9uIGNvbG9yIHNwYWNlCisgICAgICogQHBhcmFtIG5QaXhlbHMgLSBudW1iZXIgb2YgcGl4ZWxzCisgICAgICogQHJldHVybiB0cmFuc2xhdGVkIHBpeGVscworICAgICAqLworICAgIHB1YmxpYyBmbG9hdFtdW10gdHJhbnNsYXRlQ29sb3IoSUNDX1RyYW5zZm9ybSB0LAorICAgICAgICAgICAgZmxvYXQgYnVmZmVyW11bXSwKKyAgICAgICAgICAgIENvbG9yU3BhY2Ugc3JjQ1MsCisgICAgICAgICAgICBDb2xvclNwYWNlIGRzdENTLAorICAgICAgICAgICAgaW50IG5QaXhlbHMpIHsKKyAgICAgICAgLy8gU2NhbGUgc291cmNlIGRhdGEKKyAgICAgICAgaWYgKHNyY0NTICE9IG51bGwpIHsgLy8gaWYgaXQgaXMgbnVsbCB1c2Ugb2xkIHNjYWxpbmcgZGF0YQorICAgICAgICAgICAgc2NhbGVyLmxvYWRTY2FsaW5nRGF0YShzcmNDUyk7CisgICAgICAgIH0KKyAgICAgICAgaW50IG5TcmNDaGFubmVscyA9IHQuZ2V0TnVtSW5wdXRDaGFubmVscygpOworICAgICAgICBzaG9ydCBzcmNTaG9ydERhdGFbXSA9IG5ldyBzaG9ydFtuUGl4ZWxzKm5TcmNDaGFubmVsc107CisgICAgICAgIGZvciAoaW50IGk9MCwgc3JjRGF0YVBvcyA9IDA7IGk8blBpeGVsczsgaSsrKSB7CisgICAgICAgICAgICBzY2FsZXIuc2NhbGUoYnVmZmVyW2ldLCBzcmNTaG9ydERhdGEsIHNyY0RhdGFQb3MpOworICAgICAgICAgICAgc3JjRGF0YVBvcyArPSBuU3JjQ2hhbm5lbHM7CisgICAgICAgIH0KKworICAgICAgICAvLyBBcHBseSB0cmFuc2Zvcm0KKyAgICAgICAgc2hvcnQgZHN0U2hvcnREYXRhW10gPSB0aGlzLnRyYW5zbGF0ZUNvbG9yKHQsIHNyY1Nob3J0RGF0YSwgbnVsbCk7CisKKyAgICAgICAgaW50IG5Ec3RDaGFubmVscyA9IHQuZ2V0TnVtT3V0cHV0Q2hhbm5lbHMoKTsKKyAgICAgICAgaW50IGJ1ZmZlclNpemUgPSBidWZmZXJbMF0ubGVuZ3RoOworICAgICAgICBpZiAoYnVmZmVyU2l6ZSA8IG5Ec3RDaGFubmVscyArIDEpIHsgLy8gUmUtYWxsb2NhdGUgYnVmZmVyIGlmIG5lZWRlZAorICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5QaXhlbHM7IGkrKykgeworICAgICAgICAgICAgICAgIC8vIE9uZSBleHRyYSBlbGVtZW50IHJlc2VydmVkIGZvciBhbHBoYQorICAgICAgICAgICAgICAgIGJ1ZmZlcltpXSA9IG5ldyBmbG9hdFtuRHN0Q2hhbm5lbHMgKyAxXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFVuc2NhbGUgZGVzdGluYXRpb24gZGF0YQorICAgICAgICBpZiAoZHN0Q1MgIT0gbnVsbCkgeyAvLyBpZiBpdCBpcyBudWxsIHVzZSBvbGQgc2NhbGluZyBkYXRhCisgICAgICAgICAgICBzY2FsZXIubG9hZFNjYWxpbmdEYXRhKGRzdENTKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpPTAsIGRzdERhdGFQb3MgPSAwOyBpPG5QaXhlbHM7IGkrKykgeworICAgICAgICAgICAgc2NhbGVyLnVuc2NhbGUoYnVmZmVyW2ldLCBkc3RTaG9ydERhdGEsIGRzdERhdGFQb3MpOworICAgICAgICAgICAgZHN0RGF0YVBvcyArPSBuRHN0Q2hhbm5lbHM7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZXMgcGl4ZWxzIHN0b3JlZCBpbiBhIHJhc3Rlci4KKyAgICAgKiBBbGwgZGF0YSB0eXBlcyBhcmUgc3VwcG9ydGVkCisgICAgICogQHBhcmFtIHQgLSBJQ0MgdHJhbnNmb3JtCisgICAgICogQHBhcmFtIHNyYyAtIHNvdXJjZSBwaXhlbHMKKyAgICAgKiBAcGFyYW0gZHN0IC0gZGVzdGluYXRpb24gcGl4ZWxzCisgICAgICovCisgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVDb2xvcihJQ0NfVHJhbnNmb3JtIHQsIFJhc3RlciBzcmMsIFdyaXRhYmxlUmFzdGVyIGRzdCkgeworICAgICAgICB0cnl7CisgICAgICAgICAgICBOYXRpdmVJbWFnZUZvcm1hdCBzcmNGbXQgPSBOYXRpdmVJbWFnZUZvcm1hdC5jcmVhdGVOYXRpdmVJbWFnZUZvcm1hdChzcmMpOworICAgICAgICAgICAgTmF0aXZlSW1hZ2VGb3JtYXQgZHN0Rm10ID0gTmF0aXZlSW1hZ2VGb3JtYXQuY3JlYXRlTmF0aXZlSW1hZ2VGb3JtYXQoZHN0KTsKKworICAgICAgICAgIGlmIChzcmNGbXQgIT0gbnVsbCAmJiBkc3RGbXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICB0LnRyYW5zbGF0ZUNvbG9ycyhzcmNGbXQsIGRzdEZtdCk7CisgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICB9CisKKyAgICAgICAgLy8gR28gYWhlYWQgYW5kIHJlc2NhbGUgdGhlIHNvdXJjZSBpbWFnZQorICAgICAgICBzY2FsZXIubG9hZFNjYWxpbmdEYXRhKHNyYywgdC5nZXRTcmMoKSk7CisgICAgICAgIHNob3J0IHNyY0RhdGFbXSA9IHNjYWxlci5zY2FsZShzcmMpOworCisgICAgICAgIHNob3J0IGRzdERhdGFbXSA9IHRyYW5zbGF0ZUNvbG9yKHQsIHNyY0RhdGEsIG51bGwpOworCisgICAgICAgIHNjYWxlci5sb2FkU2NhbGluZ0RhdGEoZHN0LCB0LmdldERzdCgpKTsKKyAgICAgICAgc2NhbGVyLnVuc2NhbGUoZHN0RGF0YSwgZHN0KTsKKyAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZXMgcGl4ZWxzIHN0b3JlZCBpbiBhbiBhcnJheSBvZiBzaG9ydHMuCisgICAgICogU2FtcGxlcyBhcmUgc3RvcmVkIG9uZS1ieS1vbmUsIGkuZS4gYXJyYXkgc3RydWN0dXJlIGlzIGxpa2UgZm9sbG93aW5nOiBSR0JSR0JSR0IuLi4KKyAgICAgKiBUaGUgbnVtYmVyIG9mIHBpeGVscyBpcyAoc2l6ZSBvZiB0aGUgYXJyYXkpIC8gKG51bWJlciBvZiBjb21wb25lbnRzKS4KKyAgICAgKiBAcGFyYW0gdCAtIElDQyB0cmFuc2Zvcm0KKyAgICAgKiBAcGFyYW0gc3JjIC0gc291cmNlIHBpeGVscworICAgICAqIEBwYXJhbSBkc3QgLSBkZXN0aW5hdGlvbiBwaXhlbHMKKyAgICAgKiBAcmV0dXJuIGRlc3RpbmF0aW9uIHBpeGVscywgc3RvcmVkIGluIHRoZSBhcnJheSwgcGFzc2VkIGluIGRzdAorICAgICAqLworICAgIHB1YmxpYyBzaG9ydFtdIHRyYW5zbGF0ZUNvbG9yKElDQ19UcmFuc2Zvcm0gdCwgc2hvcnQgc3JjW10sIHNob3J0IGRzdFtdKSB7CisgICAgICAgIE5hdGl2ZUltYWdlRm9ybWF0IHNyY0ZtdCA9IGNyZWF0ZUltYWdlRm9ybWF0KHQsIHNyYywgMCwgdHJ1ZSk7CisgICAgICAgIE5hdGl2ZUltYWdlRm9ybWF0IGRzdEZtdCA9IGNyZWF0ZUltYWdlRm9ybWF0KHQsIGRzdCwgc3JjRm10LmdldE51bUNvbHMoKSwgZmFsc2UpOworCisgICAgICAgIHQudHJhbnNsYXRlQ29sb3JzKHNyY0ZtdCwgZHN0Rm10KTsKKworICAgICAgICByZXR1cm4gKHNob3J0W10pIGRzdEZtdC5nZXRDaGFubmVsRGF0YSgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBOYXRpdmVJbWFnZUZvcm1hdCBmcm9tIGJ1ZmZlcmVkIGltYWdlLgorICAgICAqIEBwYXJhbSBiaSAtIGJ1ZmZlcmVkIGltYWdlCisgICAgICogQHJldHVybiBjcmVhdGVkIE5hdGl2ZUltYWdlRm9ybWF0CisgICAgICovCisgICAgcHJpdmF0ZSBOYXRpdmVJbWFnZUZvcm1hdCBjcmVhdGVJbWFnZUZvcm1hdChCdWZmZXJlZEltYWdlIGJpKSB7CisgICAgICAgIGludCBuUm93cyA9IGJpLmdldEhlaWdodCgpOworICAgICAgICBpbnQgbkNvbHMgPSBiaS5nZXRXaWR0aCgpOworICAgICAgICBpbnQgbkNvbXBzID0gYmkuZ2V0Q29sb3JNb2RlbCgpLmdldE51bUNvbG9yQ29tcG9uZW50cygpOworICAgICAgICBzaG9ydCBpbWdEYXRhW10gPSBuZXcgc2hvcnRbblJvd3MqbkNvbHMqbkNvbXBzXTsKKyAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVJbWFnZUZvcm1hdCgKKyAgICAgICAgICAgICAgICBpbWdEYXRhLCBuQ29tcHMsIG5Sb3dzLCBuQ29scyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvbmUtcm93IE5hdGl2ZUltYWdlRm9ybWF0LCB1c2luZyBlaXRoZXIgbkNvbHMgaWYgaXQgaXMgcG9zaXRpdmUsCisgICAgICogb3IgYXJyLmxlbmd0aCB0byBkZXRlcm1pbmUgdGhlIG51bWJlciBvZiBwaXhlbHMKKyAgICAgKgorICAgICAqIEBwYXJhbSB0IC0gdHJhbnNmb3JtCisgICAgICogQHBhcmFtIGFyciAtIHNob3J0IGFycmF5IG9yIG51bGwgaWYgbkNvbHMgaXMgcG9zaXRpdmUKKyAgICAgKiBAcGFyYW0gbkNvbHMgLSBudW1iZXIgb2YgcGl4ZWxzIGluIHRoZSBhcnJheSBvciAwIGlmIGFycmF5IGlzIG5vdCBudWxsCisgICAgICogQHBhcmFtIGluIC0gaXMgaXQgYW4gaW5wdXQgb3Igb3V0cHV0IGFycmF5CisgICAgICogQHJldHVybiBvbmUtcm93IE5hdGl2ZUltYWdlRm9ybWF0CisgICAgICovCisgICAgcHJpdmF0ZSBOYXRpdmVJbWFnZUZvcm1hdCBjcmVhdGVJbWFnZUZvcm1hdCgKKyAgICAgICAgICAgIElDQ19UcmFuc2Zvcm0gdCwgc2hvcnQgYXJyW10sIGludCBuQ29scywgYm9vbGVhbiBpbgorICAgICkgeworICAgICAgICBpbnQgbkNvbXBvbmVudHMgPSBpbiA/IHQuZ2V0TnVtSW5wdXRDaGFubmVscygpIDogdC5nZXROdW1PdXRwdXRDaGFubmVscygpOworCisgICAgICAgIGlmIChhcnIgPT0gbnVsbCB8fCBhcnIubGVuZ3RoIDwgbkNvbHMqbkNvbXBvbmVudHMpIHsKKyAgICAgICAgICAgIGFyciA9IG5ldyBzaG9ydFtuQ29scypuQ29tcG9uZW50c107CisgICAgICAgIH0KKworICAgICAgICBpZiAobkNvbHMgPT0gMCkKKyAgICAgICAgICAgIG5Db2xzID0gYXJyLmxlbmd0aCAvIG5Db21wb25lbnRzOworCisgICAgICAgIHJldHVybiBuZXcgTmF0aXZlSW1hZ2VGb3JtYXQoYXJyLCBuQ29tcG9uZW50cywgMSwgbkNvbHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL0NvbG9yU2NhbGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9Db2xvclNjYWxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExY2MxNjkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9Db2xvclNjYWxlci5qYXZhCkBAIC0wLDAgKzEsMzU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yOworCitpbXBvcnQgamF2YS5hd3QuY29sb3IuQ29sb3JTcGFjZTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5JQ0NfUHJvZmlsZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5TYW1wbGVNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGZ1bmN0aW9uYWxpdHkgZm9yIHNjYWxpbmcgY29sb3IgZGF0YSB3aGVuCisgKiByYW5nZXMgb2YgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gY29sb3IgdmFsdWVzIGRpZmZlcnMuIAorICovCitwdWJsaWMgY2xhc3MgQ29sb3JTY2FsZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IE1BWF9TSE9SVCA9IDB4RkZGRjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBNQVhfU0lHTkVEX1NIT1JUID0gMHg3RkZGOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZmxvYXQgTUFYX1hZWiA9IDFmICsgKDMyNzY3Zi8zMjc2OGYpOworCisgICAgLy8gQ2FjaGVkIHZhbHVlcyBmb3Igc2NhbGluZyBjb2xvciBkYXRhCisgICAgcHJpdmF0ZSBmbG9hdFtdIGNoYW5uZWxNaW5WYWx1ZXMgPSBudWxsOworICAgIHByaXZhdGUgZmxvYXRbXSBjaGFubmVsTXVsaXBsaWVycyA9IG51bGw7IC8vIGZvciBzY2FsZQorICAgIHByaXZhdGUgZmxvYXRbXSBpbnZDaGFubmVsTXVsaXBsaWVycyA9IG51bGw7IC8vIGZvciB1bnNjYWxlCisKKyAgICBpbnQgbkNvbG9yQ2hhbm5lbHMgPSAwOworCisgICAgLy8gRm9yIHNjYWxpbmcgcmFzdGVycywgZmFsc2UgaWYgdHJhbnNmZXIgdHlwZSBpcyBkb3VibGUgb3IgZmxvYXQKKyAgICBib29sZWFuIGlzVFR5cGVJbnRlZ3JhbCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogTG9hZHMgc2NhbGluZyBkYXRhIGZvciByYXN0ZXIuIE5vdGUsIGlmIHByb2ZpbGUgcGYgaXMgbnVsbCwKKyAgICAgKiBmb3Igbm9uLWludGVncmFsIGRhdGEgdHlwZXMgbXVsdGlwbGllcnMgYXJlIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKiBAcGFyYW0gciAtIHJhc3RlcgorICAgICAqIEBwYXJhbSBwZiAtIHByb2ZpbGUgd2hpY2ggaGVscHMgdG8gZGV0ZXJtaW5lIHRoZSByYW5nZXMgb2YgdGhlIGNvbG9yIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2FkU2NhbGluZ0RhdGEoUmFzdGVyIHIsIElDQ19Qcm9maWxlIHBmKSB7CisgICAgICAgIGJvb2xlYW4gaXNTcmNUVHlwZUludGVncmFsID0KKyAgICAgICAgICAgIHIuZ2V0VHJhbnNmZXJUeXBlKCkgIT0gRGF0YUJ1ZmZlci5UWVBFX0ZMT0FUICYmCisgICAgICAgICAgICByLmdldFRyYW5zZmVyVHlwZSgpICE9IERhdGFCdWZmZXIuVFlQRV9ET1VCTEU7CisgICAgICAgIGlmIChpc1NyY1RUeXBlSW50ZWdyYWwpCisgICAgICAgICAgICBsb2FkU2NhbGluZ0RhdGEoci5nZXRTYW1wbGVNb2RlbCgpKTsKKyAgICAgICAgZWxzZSBpZiAocGYgIT0gbnVsbCkKKyAgICAgICAgICAgIGxvYWRTY2FsaW5nRGF0YShwZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoaXMgbWV0aG9kIG9ubHkgZm9yIGludGVncmFsIHRyYW5zZmVyIHR5cGVzLgorICAgICAqIEV4dHJhY3RzIG1pbi9tYXggdmFsdWVzIGZyb20gdGhlIHNhbXBsZSBtb2RlbAorICAgICAqIEBwYXJhbSBzbSAtIHNhbXBsZSBtb2RlbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvYWRTY2FsaW5nRGF0YShTYW1wbGVNb2RlbCBzbSkgeworICAgICAgICAvLyBTdXBwb3NpbmcgaW50ZWdyYWwgdHJhbnNmZXIgdHlwZQorICAgICAgICBpc1RUeXBlSW50ZWdyYWwgPSB0cnVlOworCisgICAgICAgIG5Db2xvckNoYW5uZWxzID0gc20uZ2V0TnVtQmFuZHMoKTsKKworICAgICAgICBjaGFubmVsTWluVmFsdWVzID0gbmV3IGZsb2F0W25Db2xvckNoYW5uZWxzXTsKKyAgICAgICAgY2hhbm5lbE11bGlwbGllcnMgPSBuZXcgZmxvYXRbbkNvbG9yQ2hhbm5lbHNdOworICAgICAgICBpbnZDaGFubmVsTXVsaXBsaWVycyA9IG5ldyBmbG9hdFtuQ29sb3JDaGFubmVsc107CisKKyAgICAgICAgYm9vbGVhbiBpc1NpZ25lZFNob3J0ID0KKyAgICAgICAgICAgIChzbS5nZXRUcmFuc2ZlclR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQpOworCisgICAgICAgIGZsb2F0IG1heFZhbDsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5Db2xvckNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgIGNoYW5uZWxNaW5WYWx1ZXNbaV0gPSAwOworICAgICAgICAgICAgaWYgKGlzU2lnbmVkU2hvcnQpIHsKKyAgICAgICAgICAgICAgICBjaGFubmVsTXVsaXBsaWVyc1tpXSA9IE1BWF9TSE9SVCAvIE1BWF9TSUdORURfU0hPUlQ7CisgICAgICAgICAgICAgICAgaW52Q2hhbm5lbE11bGlwbGllcnNbaV0gPSBNQVhfU0lHTkVEX1NIT1JUIC8gTUFYX1NIT1JUOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBtYXhWYWwgPSAoKDEgPDwgc20uZ2V0U2FtcGxlU2l6ZShpKSkgLSAxKTsKKyAgICAgICAgICAgICAgICBjaGFubmVsTXVsaXBsaWVyc1tpXSA9IE1BWF9TSE9SVCAvIG1heFZhbDsKKyAgICAgICAgICAgICAgICBpbnZDaGFubmVsTXVsaXBsaWVyc1tpXSA9IG1heFZhbCAvIE1BWF9TSE9SVDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZSB0aGlzIG1ldGhvZCBvbmx5IGZvciBkb3VibGUgb2YgZmxvYXQgdHJhbnNmZXIgdHlwZXMuCisgICAgICogRXh0cmFjdHMgc2NhbGluZyBkYXRhIGZyb20gdGhlIGNvbG9yIHNwYWNlIHNpZ25hdHVyZQorICAgICAqIGFuZCBvdGhlciB0YWdzLCBzdG9yZWQgaW4gdGhlIHByb2ZpbGUKKyAgICAgKiBAcGFyYW0gcGYgLSBJQ0MgcHJvZmlsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvYWRTY2FsaW5nRGF0YShJQ0NfUHJvZmlsZSBwZikgeworICAgICAgICAvLyBTdXBwb3NpbmcgZG91YmxlIG9yIGZsb2F0IHRyYW5zZmVyIHR5cGUKKyAgICAgICAgaXNUVHlwZUludGVncmFsID0gZmFsc2U7CisKKyAgICAgICAgbkNvbG9yQ2hhbm5lbHMgPSBwZi5nZXROdW1Db21wb25lbnRzKCk7CisKKyAgICAgICAgLy8gR2V0IG1pbi9tYXggdmFsdWVzIGRpcmVjdGx5IGZyb20gdGhlIHByb2ZpbGUKKyAgICAgICAgLy8gVmVyeSBtdWNoIGxpa2UgZmlsbE1pbk1heFZhbHVlcyBpbiBJQ0NfQ29sb3JTcGFjZQorICAgICAgICBmbG9hdCBtYXhWYWx1ZXNbXSA9IG5ldyBmbG9hdFtuQ29sb3JDaGFubmVsc107CisgICAgICAgIGZsb2F0IG1pblZhbHVlc1tdID0gbmV3IGZsb2F0W25Db2xvckNoYW5uZWxzXTsKKworICAgICAgICBzd2l0Y2ggKHBmLmdldENvbG9yU3BhY2VUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5UWVBFX1hZWjoKKyAgICAgICAgICAgICAgICBtaW5WYWx1ZXNbMF0gPSAwOworICAgICAgICAgICAgICAgIG1pblZhbHVlc1sxXSA9IDA7CisgICAgICAgICAgICAgICAgbWluVmFsdWVzWzJdID0gMDsKKyAgICAgICAgICAgICAgICBtYXhWYWx1ZXNbMF0gPSBNQVhfWFlaOworICAgICAgICAgICAgICAgIG1heFZhbHVlc1sxXSA9IE1BWF9YWVo7CisgICAgICAgICAgICAgICAgbWF4VmFsdWVzWzJdID0gTUFYX1hZWjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5UWVBFX0xhYjoKKyAgICAgICAgICAgICAgICBtaW5WYWx1ZXNbMF0gPSAwOworICAgICAgICAgICAgICAgIG1pblZhbHVlc1sxXSA9IC0xMjg7CisgICAgICAgICAgICAgICAgbWluVmFsdWVzWzJdID0gLTEyODsKKyAgICAgICAgICAgICAgICBtYXhWYWx1ZXNbMF0gPSAxMDA7CisgICAgICAgICAgICAgICAgbWF4VmFsdWVzWzFdID0gMTI3OworICAgICAgICAgICAgICAgIG1heFZhbHVlc1syXSA9IDEyNzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5Db2xvckNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbWluVmFsdWVzW2ldID0gMDsKKyAgICAgICAgICAgICAgICAgICAgbWF4VmFsdWVzW2ldID0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBjaGFubmVsTWluVmFsdWVzID0gbWluVmFsdWVzOworICAgICAgICBjaGFubmVsTXVsaXBsaWVycyA9IG5ldyBmbG9hdFtuQ29sb3JDaGFubmVsc107CisgICAgICAgIGludkNoYW5uZWxNdWxpcGxpZXJzID0gbmV3IGZsb2F0W25Db2xvckNoYW5uZWxzXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5Db2xvckNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgIGNoYW5uZWxNdWxpcGxpZXJzW2ldID0KKyAgICAgICAgICAgICAgICBNQVhfU0hPUlQgLyAobWF4VmFsdWVzW2ldIC0gY2hhbm5lbE1pblZhbHVlc1tpXSk7CisKKyAgICAgICAgICAgIGludkNoYW5uZWxNdWxpcGxpZXJzW2ldID0KKyAgICAgICAgICAgICAgICAobWF4VmFsdWVzW2ldIC0gY2hhbm5lbE1pblZhbHVlc1tpXSkgLyBNQVhfU0hPUlQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBzY2FsaW5nIGRhdGEgZnJvbSB0aGUgY29sb3Igc3BhY2UKKyAgICAgKiBAcGFyYW0gY3MgLSBjb2xvciBzcGFjZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvYWRTY2FsaW5nRGF0YShDb2xvclNwYWNlIGNzKSB7CisgICAgICAgIG5Db2xvckNoYW5uZWxzID0gY3MuZ2V0TnVtQ29tcG9uZW50cygpOworCisgICAgICAgIGNoYW5uZWxNaW5WYWx1ZXMgPSBuZXcgZmxvYXRbbkNvbG9yQ2hhbm5lbHNdOworICAgICAgICBjaGFubmVsTXVsaXBsaWVycyA9IG5ldyBmbG9hdFtuQ29sb3JDaGFubmVsc107CisgICAgICAgIGludkNoYW5uZWxNdWxpcGxpZXJzID0gbmV3IGZsb2F0W25Db2xvckNoYW5uZWxzXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5Db2xvckNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgIGNoYW5uZWxNaW5WYWx1ZXNbaV0gPSBjcy5nZXRNaW5WYWx1ZShpKTsKKworICAgICAgICAgICAgY2hhbm5lbE11bGlwbGllcnNbaV0gPQorICAgICAgICAgICAgICAgIE1BWF9TSE9SVCAvIChjcy5nZXRNYXhWYWx1ZShpKSAtIGNoYW5uZWxNaW5WYWx1ZXNbaV0pOworCisgICAgICAgICAgICBpbnZDaGFubmVsTXVsaXBsaWVyc1tpXSA9CisgICAgICAgICAgICAgICAgKGNzLmdldE1heFZhbHVlKGkpIC0gY2hhbm5lbE1pblZhbHVlc1tpXSkgLyBNQVhfU0hPUlQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTY2FsZXMgYW5kIG5vcm1hbGl6ZXMgdGhlIHdob2xlIHJhc3RlciBhbmQgcmV0dXJucyB0aGUgcmVzdWx0CisgICAgICogaW4gdGhlIGZsb2F0IGFycmF5CisgICAgICogQHBhcmFtIHIgLSBzb3VyY2UgcmFzdGVyCisgICAgICogQHJldHVybiBzY2FsZWQgYW5kIG5vcm1hbGl6ZWQgcmFzdGVyIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXRbXVtdIHNjYWxlTm9ybWFsaXplKFJhc3RlciByKSB7CisgICAgICAgIGludCB3aWR0aCA9IHIuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGhlaWdodCA9IHIuZ2V0SGVpZ2h0KCk7CisgICAgICAgIGZsb2F0IHJlc3VsdFtdW10gPSBuZXcgZmxvYXRbd2lkdGgqaGVpZ2h0XVtuQ29sb3JDaGFubmVsc107CisgICAgICAgIGZsb2F0IG5vcm1NdWx0aXBsaWVyc1tdID0gbmV3IGZsb2F0W25Db2xvckNoYW5uZWxzXTsKKworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgaWYgKGlzVFR5cGVJbnRlZ3JhbCkgeworICAgICAgICAgICAgLy8gQ2hhbmdlIG1heCB2YWx1ZSBmcm9tIE1BWF9TSE9SVCB0byAxZgorICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5Db2xvckNoYW5uZWxzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBub3JtTXVsdGlwbGllcnNbaV0gPSBjaGFubmVsTXVsaXBsaWVyc1tpXSAvIE1BWF9TSE9SVDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHNhbXBsZTsKKyAgICAgICAgICAgIGZvciAoaW50IHJvdz1yLmdldE1pblgoKTsgcm93PHdpZHRoOyByb3crKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbD1yLmdldE1pblkoKTsgY29sPGhlaWdodDsgY29sKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY2hhbiA9IDA7IGNoYW4gPCBuQ29sb3JDaGFubmVsczsgY2hhbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGUgPSByLmdldFNhbXBsZShyb3csIGNvbCwgY2hhbik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbcG9zXVtjaGFuXSA9IChzYW1wbGUgKiBub3JtTXVsdGlwbGllcnNbY2hhbl0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gSnVzdCBnZXQgdGhlIHNhbXBsZXMuLi4KKyAgICAgICAgICAgIGZvciAoaW50IHJvdz1yLmdldE1pblgoKTsgcm93PHdpZHRoOyByb3crKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbD1yLmdldE1pblkoKTsgY29sPGhlaWdodDsgY29sKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY2hhbiA9IDA7IGNoYW4gPCBuQ29sb3JDaGFubmVsczsgY2hhbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbcG9zXVtjaGFuXSA9IHIuZ2V0U2FtcGxlRmxvYXQocm93LCBjb2wsIGNoYW4pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuc2NhbGUgdGhlIHdob2xlIGZsb2F0IGFycmF5IGFuZCBwdXQgdGhlIHJlc3VsdAorICAgICAqIGluIHRoZSByYXN0ZXIKKyAgICAgKiBAcGFyYW0gciAtIGRlc3RpbmF0aW9uIHJhc3RlcgorICAgICAqIEBwYXJhbSBkYXRhIC0gaW5wdXQgcGl4ZWxzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5zY2FsZU5vcm1hbGl6ZWQoV3JpdGFibGVSYXN0ZXIgciwgZmxvYXQgZGF0YVtdW10pIHsKKyAgICAgICAgaW50IHdpZHRoID0gci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgaGVpZ2h0ID0gci5nZXRIZWlnaHQoKTsKKyAgICAgICAgZmxvYXQgbm9ybU11bHRpcGxpZXJzW10gPSBuZXcgZmxvYXRbbkNvbG9yQ2hhbm5lbHNdOworCisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBpZiAoaXNUVHlwZUludGVncmFsKSB7CisgICAgICAgICAgICAvLyBDaGFuZ2UgbWF4IHZhbHVlIGZyb20gTUFYX1NIT1JUIHRvIDFmCisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bkNvbG9yQ2hhbm5lbHM7IGkrKykgeworICAgICAgICAgICAgICAgIG5vcm1NdWx0aXBsaWVyc1tpXSA9IGludkNoYW5uZWxNdWxpcGxpZXJzW2ldICogTUFYX1NIT1JUOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgc2FtcGxlOworICAgICAgICAgICAgZm9yIChpbnQgcm93PXIuZ2V0TWluWCgpOyByb3c8d2lkdGg7IHJvdysrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sPXIuZ2V0TWluWSgpOyBjb2w8aGVpZ2h0OyBjb2wrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjaGFuID0gMDsgY2hhbiA8IG5Db2xvckNoYW5uZWxzOyBjaGFuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZSA9IChpbnQpIChkYXRhW3Bvc11bY2hhbl0gKiBub3JtTXVsdGlwbGllcnNbY2hhbl0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHIuc2V0U2FtcGxlKHJvdywgY29sLCBjaGFuLCBzYW1wbGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gSnVzdCBzZXQgdGhlIHNhbXBsZXMuLi4KKyAgICAgICAgICAgIGZvciAoaW50IHJvdz1yLmdldE1pblgoKTsgcm93PHdpZHRoOyByb3crKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbD1yLmdldE1pblkoKTsgY29sPGhlaWdodDsgY29sKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY2hhbiA9IDA7IGNoYW4gPCBuQ29sb3JDaGFubmVsczsgY2hhbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByLnNldFNhbXBsZShyb3csIGNvbCwgY2hhbiwgZGF0YVtwb3NdW2NoYW5dKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTY2FsZXMgdGhlIHdob2xlIHJhc3RlciB0byBzaG9ydCBhbmQgcmV0dXJucyB0aGUgcmVzdWx0CisgICAgICogaW4gdGhlIGFycmF5CisgICAgICogQHBhcmFtIHIgLSBzb3VyY2UgcmFzdGVyCisgICAgICogQHJldHVybiBzY2FsZWQgYW5kIG5vcm1hbGl6ZWQgcmFzdGVyIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnRbXSBzY2FsZShSYXN0ZXIgcikgeworICAgICAgICBpbnQgd2lkdGggPSByLmdldFdpZHRoKCk7CisgICAgICAgIGludCBoZWlnaHQgPSByLmdldEhlaWdodCgpOworICAgICAgICBzaG9ydCByZXN1bHRbXSA9IG5ldyBzaG9ydFt3aWR0aCpoZWlnaHQqbkNvbG9yQ2hhbm5lbHNdOworCisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBpZiAoaXNUVHlwZUludGVncmFsKSB7CisgICAgICAgICAgICBpbnQgc2FtcGxlOworICAgICAgICAgICAgZm9yIChpbnQgcm93PXIuZ2V0TWluWCgpOyByb3c8d2lkdGg7IHJvdysrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sPXIuZ2V0TWluWSgpOyBjb2w8aGVpZ2h0OyBjb2wrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjaGFuID0gMDsgY2hhbiA8IG5Db2xvckNoYW5uZWxzOyBjaGFuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZSA9IHIuZ2V0U2FtcGxlKHJvdywgY29sLCBjaGFuKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtwb3MrK10gPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHNhbXBsZSAqIGNoYW5uZWxNdWxpcGxpZXJzW2NoYW5dICsgMC41Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmbG9hdCBzYW1wbGU7CisgICAgICAgICAgICBmb3IgKGludCByb3c9ci5nZXRNaW5YKCk7IHJvdzx3aWR0aDsgcm93KyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBjb2w9ci5nZXRNaW5ZKCk7IGNvbDxoZWlnaHQ7IGNvbCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGNoYW4gPSAwOyBjaGFuIDwgbkNvbG9yQ2hhbm5lbHM7IGNoYW4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlID0gci5nZXRTYW1wbGVGbG9hdChyb3csIGNvbCwgY2hhbik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbcG9zKytdID0gKHNob3J0KSAoKHNhbXBsZSAtIGNoYW5uZWxNaW5WYWx1ZXNbY2hhbl0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBjaGFubmVsTXVsaXBsaWVyc1tjaGFuXSArIDAuNWYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5zY2FsZXMgdGhlIHdob2xlIGRhdGEgYXJyYXkgYW5kIHB1dHMgb2J0YWluZWQgdmFsdWVzIHRvIHRoZSByYXN0ZXIKKyAgICAgKiBAcGFyYW0gZGF0YSAtIGlucHV0IGRhdGEKKyAgICAgKiBAcGFyYW0gd3IgLSBkZXN0aW5hdGlvbiByYXN0ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnNjYWxlKHNob3J0W10gZGF0YSwgV3JpdGFibGVSYXN0ZXIgd3IpIHsKKyAgICAgICAgaW50IHdpZHRoID0gd3IuZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IGhlaWdodCA9IHdyLmdldEhlaWdodCgpOworCisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBpZiAoaXNUVHlwZUludGVncmFsKSB7CisgICAgICAgICAgICBpbnQgc2FtcGxlOworICAgICAgICAgICAgZm9yIChpbnQgcm93PXdyLmdldE1pblgoKTsgcm93PHdpZHRoOyByb3crKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbD13ci5nZXRNaW5ZKCk7IGNvbDxoZWlnaHQ7IGNvbCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGNoYW4gPSAwOyBjaGFuIDwgbkNvbG9yQ2hhbm5lbHM7IGNoYW4rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZSA9IChpbnQpICgoZGF0YVtwb3MrK10gJiAweEZGRkYpICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52Q2hhbm5lbE11bGlwbGllcnNbY2hhbl0gKyAwLjVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICB3ci5zZXRTYW1wbGUocm93LCBjb2wsIGNoYW4sIHNhbXBsZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmbG9hdCBzYW1wbGU7CisgICAgICAgICAgICBmb3IgKGludCByb3c9d3IuZ2V0TWluWCgpOyByb3c8d2lkdGg7IHJvdysrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sPXdyLmdldE1pblkoKTsgY29sPGhlaWdodDsgY29sKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY2hhbiA9IDA7IGNoYW4gPCBuQ29sb3JDaGFubmVsczsgY2hhbisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlID0gKGRhdGFbcG9zKytdICYgMHhGRkZGKSAqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52Q2hhbm5lbE11bGlwbGllcnNbY2hhbl0gKyBjaGFubmVsTWluVmFsdWVzW2NoYW5dOworICAgICAgICAgICAgICAgICAgICAgICAgIHdyLnNldFNhbXBsZShyb3csIGNvbCwgY2hhbiwgc2FtcGxlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNjYWxlcyBvbmUgcGl4ZWwgYW5kIHB1dHMgb2J0YWluZWQgdmFsdWVzIHRvIHRoZSBjaGFuRGF0YQorICAgICAqIEBwYXJhbSBwaXhlbERhdGEgLSBpbnB1dCBwaXhlbAorICAgICAqIEBwYXJhbSBjaGFuRGF0YSAtIG91dHB1dCBidWZmZXIKKyAgICAgKiBAcGFyYW0gY2hhbkRhdGFPZmZzZXQgLSBvdXRwdXQgYnVmZmVyIG9mZnNldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNjYWxlKGZsb2F0W10gcGl4ZWxEYXRhLCBzaG9ydFtdIGNoYW5EYXRhLCBpbnQgY2hhbkRhdGFPZmZzZXQpIHsKKyAgICAgICAgZm9yIChpbnQgY2hhbiA9IDA7IGNoYW4gPCBuQ29sb3JDaGFubmVsczsgY2hhbisrKSB7CisgICAgICAgICAgICBjaGFuRGF0YVtjaGFuRGF0YU9mZnNldCArIGNoYW5dID0KKyAgICAgICAgICAgICAgICAgICAgKHNob3J0KSAoKHBpeGVsRGF0YVtjaGFuXSAtIGNoYW5uZWxNaW5WYWx1ZXNbY2hhbl0pICoKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNdWxpcGxpZXJzW2NoYW5dICsgMC41Zik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbnNjYWxlcyBvbmUgcGl4ZWwgYW5kIHB1dHMgb2J0YWluZWQgdmFsdWVzIHRvIHRoZSBwaXhlbERhdGEKKyAgICAgKiBAcGFyYW0gcGl4ZWxEYXRhIC0gb3V0cHV0IHBpeGVsCisgICAgICogQHBhcmFtIGNoYW5EYXRhIC0gaW5wdXQgYnVmZmVyCisgICAgICogQHBhcmFtIGNoYW5EYXRhT2Zmc2V0IC0gaW5wdXQgYnVmZmVyIG9mZnNldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuc2NhbGUoZmxvYXRbXSBwaXhlbERhdGEsIHNob3J0W10gY2hhbkRhdGEsIGludCBjaGFuRGF0YU9mZnNldCkgeworICAgICAgICBmb3IgKGludCBjaGFuID0gMDsgY2hhbiA8IG5Db2xvckNoYW5uZWxzOyBjaGFuKyspIHsKKyAgICAgICAgICAgIHBpeGVsRGF0YVtjaGFuXSA9IChjaGFuRGF0YVtjaGFuRGF0YU9mZnNldCArIGNoYW5dICYgMHhGRkZGKQorICAgICAgICAgICAgICAgICogaW52Q2hhbm5lbE11bGlwbGllcnNbY2hhbl0gKyBjaGFubmVsTWluVmFsdWVzW2NoYW5dOworICAgICAgICB9CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL0lDQ19Qcm9maWxlSGVscGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9JQ0NfUHJvZmlsZUhlbHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmN2U1MTkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9JQ0NfUHJvZmlsZUhlbHBlci5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3I7CisKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5JQ0NfUHJvZmlsZTsKKworLyoqCisgKiBJbmNsdWRlcyB1dGlsaXR5IG1ldGhvZHMgZm9yIHJlYWRpbmcgSUNDIHByb2ZpbGUgZGF0YS4KKyAqIENyZWF0ZWQgdG8gcHJvdmlkZSBwdWJsaWMgYWNjZXNzIHRvIElDQ19Qcm9maWxlIG1ldGhvZHMKKyAqIGZvciBjbGFzc2VzIG91dHNpZGUgb2YgamF2YS5hd3QuY29sb3IKKyAqLworcHVibGljIGNsYXNzIElDQ19Qcm9maWxlSGVscGVyIHsKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IG1ldGhvZC4KKyAgICAgKiBHZXRzIGludGVnZXIgdmFsdWUgZnJvbSB0aGUgYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbSBieXRlQXJyYXkgLSBieXRlIGFycmF5CisgICAgICogQHBhcmFtIGlkeCAtIGJ5dGUgb2Zmc2V0CisgICAgICogQHJldHVybiBpbnRlZ2VyIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0SW50RnJvbUJ5dGVBcnJheShieXRlW10gYnl0ZUFycmF5LCBpbnQgaWR4KSB7CisgICAgICAgIHJldHVybiAoYnl0ZUFycmF5W2lkeF0gJiAweEZGKXwKKyAgICAgICAgICAgICAgICgoYnl0ZUFycmF5W2lkeCsxXSAmIDB4RkYpIDw8IDgpIHwKKyAgICAgICAgICAgICAgICgoYnl0ZUFycmF5W2lkeCsyXSAmIDB4RkYpIDw8IDE2KXwKKyAgICAgICAgICAgICAgICgoYnl0ZUFycmF5W2lkeCszXSAmIDB4RkYpIDw8IDI0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IG1ldGhvZC4KKyAgICAgKiBHZXRzIGJpZyBlbmRpYW4gaW50ZWdlciB2YWx1ZSBmcm9tIHRoZSBieXRlIGFycmF5CisgICAgICogQHBhcmFtIGJ5dGVBcnJheSAtIGJ5dGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gaWR4IC0gYnl0ZSBvZmZzZXQKKyAgICAgKiBAcmV0dXJuIGludGVnZXIgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRCaWdFbmRpYW5Gcm9tQnl0ZUFycmF5KGJ5dGVbXSBieXRlQXJyYXksIGludCBpZHgpIHsKKyAgICAgICAgcmV0dXJuICgoYnl0ZUFycmF5W2lkeF0gJiAweEZGKSA8PCAyNCkgICB8CisgICAgICAgICAgICAgICAoKGJ5dGVBcnJheVtpZHgrMV0gJiAweEZGKSA8PCAxNikgfAorICAgICAgICAgICAgICAgKChieXRlQXJyYXlbaWR4KzJdICYgMHhGRikgPDwgOCkgIHwKKyAgICAgICAgICAgICAgICggYnl0ZUFycmF5W2lkeCszXSAmIDB4RkYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFV0aWxpdHkgbWV0aG9kLgorICAgICAqIEdldHMgc2hvcnQgdmFsdWUgZnJvbSB0aGUgYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbSBieXRlQXJyYXkgLSBieXRlIGFycmF5CisgICAgICogQHBhcmFtIGlkeCAtIGJ5dGUgb2Zmc2V0CisgICAgICogQHJldHVybiBzaG9ydCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc2hvcnQgZ2V0U2hvcnRGcm9tQnl0ZUFycmF5KGJ5dGVbXSBieXRlQXJyYXksIGludCBpZHgpIHsKKyAgICAgICAgcmV0dXJuIChzaG9ydCkgKChieXRlQXJyYXlbaWR4XSAmIDB4RkYpIHwKKyAgICAgICAgICAgICAgICAgICAgICAgKChieXRlQXJyYXlbaWR4KzFdICYgMHhGRikgPDwgOCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgaW4gSUNDX1RyYW5zZm9ybSBjbGFzcyB0byBjaGVjayB0aGUgcmVuZGVyaW5nIGludGVudCBvZiB0aGUgcHJvZmlsZQorICAgICAqIEBwYXJhbSBwcm9maWxlIC0gSUNDIHByb2ZpbGUKKyAgICAgKiBAcmV0dXJuIHJlbmRlcmluZyBpbnRlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRSZW5kZXJpbmdJbnRlbnQoSUNDX1Byb2ZpbGUgcHJvZmlsZSkgeworICAgICAgICByZXR1cm4gZ2V0SW50RnJvbUJ5dGVBcnJheSgKKyAgICAgICAgICAgICAgICBwcm9maWxlLmdldERhdGEoSUNDX1Byb2ZpbGUuaWNTaWdIZWFkKSwgLy8gcGYgaGVhZGVyCisgICAgICAgICAgICAgICAgSUNDX1Byb2ZpbGUuaWNIZHJSZW5kZXJpbmdJbnRlbnQKKyAgICAgICAgICAgICk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvY29sb3IvSUNDX1RyYW5zZm9ybS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvY29sb3IvSUNDX1RyYW5zZm9ybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3NjQ2YzQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9JQ0NfVHJhbnNmb3JtLmphdmEKQEAgLTAsMCArMSwxNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3I7CisKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5JQ0NfUHJvZmlsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3IuTmF0aXZlQ01NOworCisvKioKKyAqIFRoaXMgY2xhc3MgZW5jYXBzdWxhdGVzIG5hdGl2ZSBJQ0MgdHJhbnNmb3JtIG9iamVjdCwgaXMgcmVzcG9uc2libGUgZm9yIGl0cworICogY3JlYXRpb24sIGRlc3RydWN0aW9uIGFuZCBwYXNzaW5nIGl0cyBoYW5kbGUgdG8gdGhlIG5hdGl2ZSBDTU0uCisgKi8KK3B1YmxpYyBjbGFzcyBJQ0NfVHJhbnNmb3JtIHsKKyAgICBwcml2YXRlIGxvbmcgdHJhbnNmb3JtSGFuZGxlOworICAgIHByaXZhdGUgaW50IG51bUlucHV0Q2hhbm5lbHM7CisgICAgcHJpdmF0ZSBpbnQgbnVtT3V0cHV0Q2hhbm5lbHM7CisgICAgcHJpdmF0ZSBJQ0NfUHJvZmlsZSBzcmM7CisgICAgcHJpdmF0ZSBJQ0NfUHJvZmlsZSBkc3Q7CisKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGlucHV0IGNoYW5uZWxzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtSW5wdXRDaGFubmVscygpIHsKKyAgICAgICAgcmV0dXJuIG51bUlucHV0Q2hhbm5lbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtT3V0cHV0Q2hhbm5lbHMoKSB7CisgICAgICAgIHJldHVybiBudW1PdXRwdXRDaGFubmVsczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGRzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSUNDX1Byb2ZpbGUgZ2V0RHN0KCkgeworICAgICAgICByZXR1cm4gZHN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgc3JjLgorICAgICAqLworICAgIHB1YmxpYyBJQ0NfUHJvZmlsZSBnZXRTcmMoKSB7CisgICAgICAgIHJldHVybiBzcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG11bHRpcHJvZmlsZSBJQ0MgdHJhbnNmb3JtCisgICAgICogQHBhcmFtIHByb2ZpbGVzIC0gbGlzdCBvZiBJQ0MgcHJvZmlsZXMKKyAgICAgKiBAcGFyYW0gcmVuZGVySW50ZW50cyAtIG9ubHkgaGludHMgZm9yIENNTQorICAgICAqLworICAgIHB1YmxpYyBJQ0NfVHJhbnNmb3JtKElDQ19Qcm9maWxlW10gcHJvZmlsZXMsIGludFtdIHJlbmRlckludGVudHMpIHsKKyAgICAgICAgaW50IG51bVByb2ZpbGVzID0gcHJvZmlsZXMubGVuZ3RoOworCisgICAgICAgIGxvbmdbXSBwcm9maWxlSGFuZGxlcyA9IG5ldyBsb25nW251bVByb2ZpbGVzXTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPG51bVByb2ZpbGVzOyBpKyspIHsKKyAgICAgICAgICAgIHByb2ZpbGVIYW5kbGVzW2ldID0gTmF0aXZlQ01NLmdldEhhbmRsZShwcm9maWxlc1tpXSk7CisgICAgICAgIH0KKworICAgICAgICB0cmFuc2Zvcm1IYW5kbGUgPSBOYXRpdmVDTU0uY21tQ3JlYXRlTXVsdGlwcm9maWxlVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgIHByb2ZpbGVIYW5kbGVzLAorICAgICAgICAgICAgICAgIHJlbmRlckludGVudHMpOworCisgICAgICAgIHNyYyA9IHByb2ZpbGVzWzBdOworICAgICAgICBkc3QgPSBwcm9maWxlc1tudW1Qcm9maWxlcy0xXTsKKyAgICAgICAgbnVtSW5wdXRDaGFubmVscyA9IHNyYy5nZXROdW1Db21wb25lbnRzKCk7CisgICAgICAgIG51bU91dHB1dENoYW5uZWxzID0gZHN0LmdldE51bUNvbXBvbmVudHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGlzIGFibGUgdG8gc2V0IGludGVudHMgYnkgZGVmYXVsdAorICAgICAqIEBwYXJhbSBwcm9maWxlcyAtIGxpc3Qgb2YgSUNDIHByb2ZpbGVzCisgICAgICovCisgICAgcHVibGljIElDQ19UcmFuc2Zvcm0oSUNDX1Byb2ZpbGVbXSBwcm9maWxlcykgeworICAgICAgICBpbnQgbnVtUHJvZmlsZXMgPSBwcm9maWxlcy5sZW5ndGg7CisgICAgICAgIGludFtdIHJlbmRlcmluZ0ludGVudHMgPSBuZXcgaW50W251bVByb2ZpbGVzXTsKKworICAgICAgICAvLyBEZWZhdWx0IGlzIHBlcmNlcHR1YWwKKyAgICAgICAgaW50IGN1cnJSZW5kZXJpbmdJbnRlbnQgPSBJQ0NfUHJvZmlsZS5pY1BlcmNlcHR1YWw7CisKKyAgICAgICAgLy8gcmVuZGVyIGFzIGNvbG9yaW1ldHJpYyBmb3Igb3V0cHV0IGRldmljZQorICAgICAgICBpZiAocHJvZmlsZXNbMF0uZ2V0UHJvZmlsZUNsYXNzKCkgPT0gSUNDX1Byb2ZpbGUuQ0xBU1NfT1VUUFVUKSB7CisgICAgICAgICAgICBjdXJyUmVuZGVyaW5nSW50ZW50ID0gSUNDX1Byb2ZpbGUuaWNSZWxhdGl2ZUNvbG9yaW1ldHJpYzsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGdldCB0aGUgdHJhbnNmb3JtcyBmcm9tIGVhY2ggcHJvZmlsZQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVByb2ZpbGVzOyBpKyspIHsKKyAgICAgICAgICAgIC8vIGZpcnN0IG9yIGxhc3QgcHJvZmlsZSBjYW5ub3QgYmUgYWJzdHJhY3QKKyAgICAgICAgICAgIC8vIGlmIHByb2ZpbGUgaXMgYWJzdHJhY3QsIHRoZSBvbmx5IHBvc3NpYmxlIHdheSBpcworICAgICAgICAgICAgLy8gdXNlIEFUb0IwVGFnIChwZXJjZXB0dWFsKSwgc2VlIElDQyBzcGVjCisgICAgICAgICAgICBpZiAoaSAhPSAwICYmCisgICAgICAgICAgICAgICBpICE9IG51bVByb2ZpbGVzIC0gMSAmJgorICAgICAgICAgICAgICAgcHJvZmlsZXNbaV0uZ2V0UHJvZmlsZUNsYXNzKCkgPT0gSUNDX1Byb2ZpbGUuQ0xBU1NfQUJTVFJBQ1QKKyAgICAgICAgICAgICkgeworICAgICAgICAgICAgICAgIGN1cnJSZW5kZXJpbmdJbnRlbnQgPSBJQ0NfUHJvZmlsZS5pY1BlcmNlcHR1YWw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlbmRlcmluZ0ludGVudHNbaV0gPSBjdXJyUmVuZGVyaW5nSW50ZW50OworICAgICAgICAgICAgLy8gdXNlIGN1cnJlbnQgcmVuZGVyaW5nIGludGVudAorICAgICAgICAgICAgLy8gdG8gc2VsZWN0IExVVCBmcm9tIHRoZSBuZXh0IHByb2ZpbGUgKGNoYWluaW5nKQorICAgICAgICAgICAgY3VyclJlbmRlcmluZ0ludGVudCA9CisgICAgICAgICAgICAgICAgSUNDX1Byb2ZpbGVIZWxwZXIuZ2V0UmVuZGVyaW5nSW50ZW50KHByb2ZpbGVzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdldCB0aGUgcHJvZmlsZSBoYW5kbGVzIGFuZCBnbyBhaGVhZAorICAgICAgICBsb25nW10gcHJvZmlsZUhhbmRsZXMgPSBuZXcgbG9uZ1tudW1Qcm9maWxlc107CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxudW1Qcm9maWxlczsgaSsrKSB7CisgICAgICAgICAgICBwcm9maWxlSGFuZGxlc1tpXSA9IE5hdGl2ZUNNTS5nZXRIYW5kbGUocHJvZmlsZXNbaV0pOworICAgICAgICB9CisKKyAgICAgICAgdHJhbnNmb3JtSGFuZGxlID0gTmF0aXZlQ01NLmNtbUNyZWF0ZU11bHRpcHJvZmlsZVRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBwcm9maWxlSGFuZGxlcywKKyAgICAgICAgICAgICAgICByZW5kZXJpbmdJbnRlbnRzKTsKKworICAgICAgICBzcmMgPSBwcm9maWxlc1swXTsKKyAgICAgICAgZHN0ID0gcHJvZmlsZXNbbnVtUHJvZmlsZXMtMV07CisgICAgICAgIG51bUlucHV0Q2hhbm5lbHMgPSBzcmMuZ2V0TnVtQ29tcG9uZW50cygpOworICAgICAgICBudW1PdXRwdXRDaGFubmVscyA9IGRzdC5nZXROdW1Db21wb25lbnRzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB7CisgICAgICAgIGlmICh0cmFuc2Zvcm1IYW5kbGUgIT0gMCkgeworICAgICAgICAgICAgTmF0aXZlQ01NLmNtbURlbGV0ZVRyYW5zZm9ybSh0cmFuc2Zvcm1IYW5kbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyBuYXRpdmUgY29sb3IgY29udmVyc2lvbgorICAgICAqIEBwYXJhbSBzcmMgLSBzb3VyY2UgaW1hZ2UgZm9ybWF0CisgICAgICogQHBhcmFtIGRzdCAtIGRlc3RpbmF0aW9uIGltYWdlIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUNvbG9ycyhOYXRpdmVJbWFnZUZvcm1hdCBzcmMsIE5hdGl2ZUltYWdlRm9ybWF0IGRzdCkgeworICAgICAgICBOYXRpdmVDTU0uY21tVHJhbnNsYXRlQ29sb3JzKHRyYW5zZm9ybUhhbmRsZSwgc3JjLCBkc3QpOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9MVVRDb2xvckNvbnZlcnRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvY29sb3IvTFVUQ29sb3JDb252ZXJ0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZWE2ZDI1Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvY29sb3IvTFVUQ29sb3JDb252ZXJ0ZXIuamF2YQpAQCAtMCwwICsxLDE0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisvKgorICogQ3JlYXRlZCBvbiAwMi4xMS4yMDA0CisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3I7CisKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworCitwdWJsaWMgY2xhc3MgTFVUQ29sb3JDb252ZXJ0ZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZSBmcm9tOGxSR0J0b3NSR0JfTFVUW107CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlIGZyb20xNmxSR0J0b3NSR0JfTFVUW107CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlIGZyb21zUkdCdG84bFJHQl9MVVRbXTsKKworICAgIHByaXZhdGUgc3RhdGljIHNob3J0IGZyb21zUkdCdG8xNmxSR0JfTFVUW107CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlIGZyb21zUkdCdG84c1JHQl9MVVRzW11bXTsKKworICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JTcGFjZSBMSU5FQVJfUkdCX0NTOworCisgICAgcHVibGljIHN0YXRpYyBDb2xvclNwYWNlIExJTkVBUl9HUkFZX0NTOworCisgICAgcHVibGljIHN0YXRpYyBDb2xvclNwYWNlIHNSR0JfQ1M7CisKKyAgICBwdWJsaWMgTFVUQ29sb3JDb252ZXJ0ZXIoKSB7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIGNsYXNzIHByZXBhcmVkIGFuZCByZXR1cm5lZCBsb29rdXAgdGFibGVzIGZvciBjb252ZXJzaW9uIGNvbG9yIAorICAgICAqIHZhbHVlcyBmcm9tIExpbmVhciBSR0IgQ29sb3IgU3BhY2UgdG8gc1JHQiBhbmQgdmljZSB2ZXJzYS4KKyAgICAgKiBDb252ZXJzaW9uIGlzIHByb2R1Y2luZyBhY2NvcmRpbmcgdG8gc1JHQiBDb2xvciBTcGFjZSBkZWZpbml0aW9uLgorICAgICAqICJBIFN0YW5kYXJkIERlZmF1bHQgQ29sb3IgU3BhY2UgZm9yIHRoZSBJbnRlcm5ldCAtIHNSR0IiLAorICAgICAqICBNaWNoYWVsIFN0b2tlcyAoSGV3bGV0dC1QYWNrYXJkKSwgTWF0dGhldyBBbmRlcnNvbiAoTWljcm9zb2Z0KSwgCisgICAgICogU3Jpbml2YXNhbiBDaGFuZHJhc2VrYXIgKE1pY3Jvc29mdCksIFJpY2FyZG8gTW90dGEgKEhld2xldHQtUGFja2FyZCkgCisgICAgICogVmVyc2lvbiAxLjEwLCBOb3ZlbWJlciA1LCAxOTk2IAorICAgICAqIFRoaXMgZG9jdW1lbnQgaXMgYXZhaWxhYmxlOiBodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9Db2xvci9zUkdCCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0RnJvbThsUkdCdG9zUkdCX0xVVCgpIHsKKyAgICAgICAgaWYgKGZyb204bFJHQnRvc1JHQl9MVVQgPT0gbnVsbCkgeworICAgICAgICAgICAgZnJvbThsUkdCdG9zUkdCX0xVVCA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgICAgICBmbG9hdCB2OworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgICAgIHYgPSAoZmxvYXQpaSAvIDI1NTsKKyAgICAgICAgICAgICAgICB2ID0gKHYgPD0gMC4wNDA0NWYpID8gdiAvIDEyLjkyZiA6CisgICAgICAgICAgICAgICAgICAgIChmbG9hdCkgTWF0aC5wb3coKHYgKyAwLjA1NSkgLyAxLjA1NSwgMi40KTsKKyAgICAgICAgICAgICAgICBmcm9tOGxSR0J0b3NSR0JfTFVUW2ldID0gKGJ5dGUpIE1hdGgucm91bmQodiAqIDI1NS4wZik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZyb204bFJHQnRvc1JHQl9MVVQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0RnJvbTE2bFJHQnRvc1JHQl9MVVQoKSB7CisgICAgICAgIGlmIChmcm9tMTZsUkdCdG9zUkdCX0xVVCA9PSBudWxsKSB7CisgICAgICAgICAgICBmcm9tMTZsUkdCdG9zUkdCX0xVVCA9IG5ldyBieXRlWzY1NTM2XTsKKyAgICAgICAgICAgIGZsb2F0IHY7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDY1NTM2OyBpKyspIHsKKyAgICAgICAgICAgICAgICB2ID0gKGZsb2F0KSBpIC8gNjU1MzU7CisgICAgICAgICAgICAgICAgdiA9ICh2IDw9IDAuMDQwNDVmKSA/IHYgLyAxMi45MmYgOgorICAgICAgICAgICAgICAgICAgICAoZmxvYXQpIE1hdGgucG93KCh2ICsgMC4wNTUpIC8gMS4wNTUsIDIuNCk7CisgICAgICAgICAgICAgICAgZnJvbTE2bFJHQnRvc1JHQl9MVVRbaV0gPSAoYnl0ZSkgTWF0aC5yb3VuZCh2ICogMjU1LjBmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZnJvbTE2bFJHQnRvc1JHQl9MVVQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0RnJvbXNSR0J0bzhsUkdCX0xVVCgpIHsKKyAgICAgICAgaWYgKGZyb21zUkdCdG84bFJHQl9MVVQgPT0gbnVsbCkgeworICAgICAgICAgICAgZnJvbXNSR0J0bzhsUkdCX0xVVCA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgICAgICBmbG9hdCB2OworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgICAgIHYgPSAoZmxvYXQpIGkgLyAyNTU7CisgICAgICAgICAgICAgICAgdiA9ICh2IDw9IDAuMDAzMTMwOGYpID8gdiAqIDEyLjkyZiA6CisgICAgICAgICAgICAgICAgICAgICgoZmxvYXQpIE1hdGgucG93KHYsIDEuMCAvIDIuNCkpICogMS4wNTVmIC0gMC4wNTVmOworICAgICAgICAgICAgICAgIGZyb21zUkdCdG84bFJHQl9MVVRbaV0gPSAoYnl0ZSkgTWF0aC5yb3VuZCh2ICogMjU1LjBmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZnJvbXNSR0J0bzhsUkdCX0xVVDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHNob3J0W10gZ2V0RnJvbXNSR0J0bzE2bFJHQl9MVVQoKSB7CisgICAgICAgIGlmIChmcm9tc1JHQnRvMTZsUkdCX0xVVCA9PSBudWxsKSB7CisgICAgICAgICAgICBmcm9tc1JHQnRvMTZsUkdCX0xVVCA9IG5ldyBzaG9ydFsyNTZdOworICAgICAgICAgICAgZmxvYXQgdjsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgICAgICAgICB2ID0gKGZsb2F0KSBpIC8gMjU1OworICAgICAgICAgICAgICAgIHYgPSAodiA8PSAwLjAwMzEzMDhmKSA/IHYgKiAxMi45MmYgOgorICAgICAgICAgICAgICAgICAgICAoKGZsb2F0KSBNYXRoLnBvdyh2LCAxLjAgLyAyLjQpKSAqIDEuMDU1ZiAtIDAuMDU1ZjsKKyAgICAgICAgICAgICAgICBmcm9tc1JHQnRvMTZsUkdCX0xVVFtpXSA9IChzaG9ydCkgTWF0aC5yb3VuZCh2ICogNjU1MzUuMGYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmcm9tc1JHQnRvMTZsUkdCX0xVVDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRzUkdCTFVUKGludCBiaXRzKSB7CisgICAgICAgIGlmIChiaXRzIDwgMSkgcmV0dXJuIG51bGw7CisgICAgICAgIGludCBpZHggPSBiaXRzIC0xOworICAgICAgICBpZihmcm9tc1JHQnRvOHNSR0JfTFVUcyA9PSBudWxsKSBmcm9tc1JHQnRvOHNSR0JfTFVUcyA9IG5ldyBieXRlWzE2XVtdOworCisgICAgICAgIGlmKGZyb21zUkdCdG84c1JHQl9MVVRzW2lkeF0gPT0gbnVsbCl7CisgICAgICAgICAgICBmcm9tc1JHQnRvOHNSR0JfTFVUc1tpZHhdID0gY3JlYXRlTFVUKGJpdHMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmcm9tc1JHQnRvOHNSR0JfTFVUc1tpZHhdOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBjcmVhdGVMVVQoaW50IGJpdHMpIHsKKyAgICAgICAgaW50IGx1dFNpemUgPSAoMSA8PCBiaXRzKTsKKyAgICAgICAgYnl0ZSBsdXRbXSA9IG5ldyBieXRlW2x1dFNpemVdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGx1dFNpemU7IGkrKykgeworICAgICAgICAgICAgbHV0W2ldID0gKGJ5dGUpICgyNTUuMGYgLyAobHV0U2l6ZSAtIDEpICsgMC41Zik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGx1dDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNfTElORUFSX1JHQl9DUyhDb2xvclNwYWNlIGNzKSB7CisgICAgICAgIHJldHVybiAoY3MgPT0gTElORUFSX1JHQl9DUyk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzX0xJTkVBUl9HUkFZX0NTKENvbG9yU3BhY2UgY3MpIHsKKyAgICAgICAgcmV0dXJuIChjcyA9PSBMSU5FQVJfR1JBWV9DUyk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzX3NSR0JfQ1MoQ29sb3JTcGFjZSBjcykgeworICAgICAgICByZXR1cm4gKGNzID09IHNSR0JfQ1MpOworICAgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL05hdGl2ZUNNTS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvY29sb3IvTmF0aXZlQ01NLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Y4YzdlNgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL05hdGl2ZUNNTS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuY29sb3I7CisKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5JQ0NfUHJvZmlsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgYSB3cmFwcGVyIGZvciB0aGUgbmF0aXZlIENNTSBsaWJyYXJ5CisgKi8KK3B1YmxpYyBjbGFzcyBOYXRpdmVDTU0geworCisgICAgLyoqCisgICAgICogU3RvcmFnZSBmb3IgcHJvZmlsZSBoYW5kbGVzLCBzaW5jZSB0aGV5IGFyZSBwcml2YXRlCisgICAgICogaW4gSUNDX1Byb2ZpbGUsIGJ1dCB3ZSBuZWVkIGFjY2VzcyB0byB0aGVtLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEhhc2hNYXA8SUNDX1Byb2ZpbGUsIExvbmc+IHByb2ZpbGVIYW5kbGVzID0gbmV3IEhhc2hNYXA8SUNDX1Byb2ZpbGUsIExvbmc+KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQ01NTG9hZGVkOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFkZEhhbmRsZShJQ0NfUHJvZmlsZSBrZXksIGxvbmcgaGFuZGxlKSB7CisgICAgICAgIHByb2ZpbGVIYW5kbGVzLnB1dChrZXksIG5ldyBMb25nKGhhbmRsZSkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmVIYW5kbGUoSUNDX1Byb2ZpbGUga2V5KSB7CisgICAgICAgIHByb2ZpbGVIYW5kbGVzLnJlbW92ZShrZXkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBnZXRIYW5kbGUoSUNDX1Byb2ZpbGUga2V5KSB7CisgICAgICAgIHJldHVybiBwcm9maWxlSGFuZGxlcy5nZXQoa2V5KS5sb25nVmFsdWUoKTsKKyAgICB9CisKKyAgICAvKiBJQ0MgcHJvZmlsZSBtYW5hZ2VtZW50ICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBjbW1PcGVuUHJvZmlsZShieXRlW10gZGF0YSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbW1DbG9zZVByb2ZpbGUobG9uZyBwcm9maWxlSUQpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBjbW1HZXRQcm9maWxlU2l6ZShsb25nIHByb2ZpbGVJRCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbW1HZXRQcm9maWxlKGxvbmcgcHJvZmlsZUlELCBieXRlW10gZGF0YSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGNtbUdldFByb2ZpbGVFbGVtZW50U2l6ZShsb25nIHByb2ZpbGVJRCwgaW50IHNpZ25hdHVyZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbW1HZXRQcm9maWxlRWxlbWVudChsb25nIHByb2ZpbGVJRCwgaW50IHNpZ25hdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gZGF0YSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbW1TZXRQcm9maWxlRWxlbWVudChsb25nIHByb2ZpbGVJRCwgaW50IHRhZ1NpZ25hdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gZGF0YSk7CisKKworICAgIC8qIElDQyB0cmFuc2Zvcm1zICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBjbW1DcmVhdGVNdWx0aXByb2ZpbGVUcmFuc2Zvcm0oCisgICAgICAgICAgICBsb25nW10gcHJvZmlsZUhhbmRsZXMsCisgICAgICAgICAgICBpbnRbXSByZW5kZXJpbmdJbnRlbnRzCisgICAgICAgICk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbW1EZWxldGVUcmFuc2Zvcm0obG9uZyB0cmFuc2Zvcm1IYW5kbGUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgY21tVHJhbnNsYXRlQ29sb3JzKGxvbmcgdHJhbnNmb3JtSGFuZGxlLAorICAgICAgICAgICAgTmF0aXZlSW1hZ2VGb3JtYXQgc3JjLAorICAgICAgICAgICAgTmF0aXZlSW1hZ2VGb3JtYXQgZGVzdCk7CisKKyAgICBzdGF0aWMgdm9pZCBsb2FkQ01NKCkgeworICAgICAgICBpZiAoIWlzQ01NTG9hZGVkKSB7CisgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKKyAgICAgICAgICAgICAgICAgIG5ldyBQcml2aWxlZ2VkQWN0aW9uPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ubG9hZExpYnJhcnkoImxjbW0iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gKTsKKyAgICAgICAgICAgIGlzQ01NTG9hZGVkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIGxvYWQgbmF0aXZlIENNTSBsaWJyYXJ5ICovCisgICAgc3RhdGljIHsKKyAgICAgICAgbG9hZENNTSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2NvbG9yL05hdGl2ZUltYWdlRm9ybWF0LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9OYXRpdmVJbWFnZUZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1OTQwNDcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9jb2xvci9OYXRpdmVJbWFnZUZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsNjQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmNvbG9yOworCitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbXBvbmVudFNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlNhbXBsZU1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWw7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisKKy8qKgorICogVGhpcyBjbGFzcyBjb252ZXJ0cyBqYXZhIGNvbG9yL3NhbXBsZSBtb2RlbHMgdG8gdGhlIExDTVMgcGl4ZWwgZm9ybWF0cy4KKyAqIEl0IGFsc28gZW5jYXBzdWxhdGVzIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGltYWdlIGZvcm1hdCwgd2hpY2ggbmF0aXZlIENNTQorICogbmVlZHMgdG8gaGF2ZSBpbiBvcmRlciB0byByZWFkL3dyaXRlIGRhdGEuCisgKgorICogQXQgcHJlc2VudCBwbGFuYXIgZm9ybWF0cyAobXVsdGlwbGUgYmFuZHMpIGFyZSBub3Qgc3VwcG9ydGVkCisgKiBhbmQgdGhleSBhcmUgaGFuZGxlZCBhcyBhIGNvbW1vbiAoY3VzdG9tKSBjYXNlLgorICogU2FtcGxlcyBvdGhlciB0aGFuIDEgLSA3IGJ5dGVzIGFuZCBtdWx0aXBsZSBvZiA4IGJpdHMgYXJlCisgKiBhbHNvIGhhbmRsZWQgYXMgY3VzdG9tIChhbmQgd29uJ3QgYmUgc3VwcG9ydGVkIGluIHRoZSBuZWFyZXN0IGZ1dHVyZSkuCisgKi8KK2NsYXNzIE5hdGl2ZUltYWdlRm9ybWF0IHsKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gIExDTVMgUGl4ZWwgdHlwZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFRfQU5ZID0gMDsgICAgLy8gRG9uJ3QgY2hlY2sgY29sb3JzcGFjZQorICAgIC8vIDEgJiAyIGFyZSByZXNlcnZlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQVF9HUkFZICAgICA9IDM7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBUX1JHQiAgICAgID0gNDsKKyAgICAvLyBTa2lwcGluZyBvdGhlciBzaW5jZSB3ZSBkb24ndCB1c2UgdGhlbSBoZXJlCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIC8vIENvbnZlcnNpb24gb2YgcHJlZGVmaW5lZCBCdWZmZXJlZEltYWdlIGZvcm1hdHMgdG8gTENNUyBmb3JtYXRzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOVF9SR0JfTENNU19GTVQgPQorICAgICAgICBjb2xvcnNwYWNlU2goUFRfUkdCKXwKKyAgICAgICAgZXh0cmFTaCgxKXwKKyAgICAgICAgY2hhbm5lbHNTaCgzKXwKKyAgICAgICAgYnl0ZXNTaCgxKXwKKyAgICAgICAgZG9zd2FwU2goMSl8CisgICAgICAgIHN3YXBmaXJzdFNoKDEpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOVF9BUkdCX0xDTVNfRk1UID0gSU5UX1JHQl9MQ01TX0ZNVDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTlRfQkdSX0xDTVNfRk1UID0KKyAgICAgICAgY29sb3JzcGFjZVNoKFBUX1JHQil8CisgICAgICAgIGV4dHJhU2goMSl8CisgICAgICAgIGNoYW5uZWxzU2goMyl8CisgICAgICAgIGJ5dGVzU2goMSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVEhSRUVfQllURV9CR1JfTENNU19GTVQgPQorICAgICAgICBjb2xvcnNwYWNlU2goUFRfUkdCKXwKKyAgICAgICAgY2hhbm5lbHNTaCgzKXwKKyAgICAgICAgYnl0ZXNTaCgxKXwKKyAgICAgICAgZG9zd2FwU2goMSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRk9VUl9CWVRFX0FCR1JfTENNU19GTVQgPQorICAgICAgICBjb2xvcnNwYWNlU2goUFRfUkdCKXwKKyAgICAgICAgZXh0cmFTaCgxKXwKKyAgICAgICAgY2hhbm5lbHNTaCgzKXwKKyAgICAgICAgYnl0ZXNTaCgxKXwKKyAgICAgICAgZG9zd2FwU2goMSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV9HUkFZX0xDTVNfRk1UID0KKyAgICAgICAgY29sb3JzcGFjZVNoKFBUX0dSQVkpfAorICAgICAgICBjaGFubmVsc1NoKDEpfAorICAgICAgICBieXRlc1NoKDEpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVTSE9SVF9HUkFZX0xDTVNfRk1UID0KKyAgICAgICAgY29sb3JzcGFjZVNoKFBUX0dSQVkpfAorICAgICAgICBjaGFubmVsc1NoKDEpfAorICAgICAgICBieXRlc1NoKDIpOworCisgICAgLy8gTENNUyBmb3JtYXQgcGFja2VkIGludG8gMzIgYml0IHZhbHVlLiBGb3IgZGVzY3JpcHRpb24KKyAgICAvLyBvZiB0aGlzIGZvcm1hdCByZWZlciB0byBMQ01TIGRvY3VtZW50YXRpb24uCisgICAgcHJpdmF0ZSBpbnQgY21tRm9ybWF0ID0gMDsKKworICAgIC8vIERpbWVuc2lvbnMKKyAgICBwcml2YXRlIGludCByb3dzID0gMDsKKyAgICBwcml2YXRlIGludCBjb2xzID0gMDsKKworICAgIC8vICBTY2FubGluZSBtYXkgY29udGFpbiBzb21lIHBhZGRpbmcgaW4gdGhlIGVuZAorICAgIHByaXZhdGUgaW50IHNjYW5saW5lU3RyaWRlID0gLTE7CisKKyAgICBwcml2YXRlIE9iamVjdCBpbWFnZURhdGE7CisgICAgLy8gSXQncyBwb3NzaWJsZSB0byBoYXZlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5CisgICAgcHJpdmF0ZSBpbnQgZGF0YU9mZnNldDsKKworICAgIC8vIEhhcyB0aGUgaW1hZ2UgYWxwaGEgY2hhbm5lbD8gSWYgaGFzIC0gaGVyZSBpdHMgYmFuZCBiYW5kIG9mZnNldCBnb2VzCisgICAgcHJpdmF0ZSBpbnQgYWxwaGFPZmZzZXQgPSAtMTsKKworICAgIC8vIGluaXRpYWxpemVzIHByb3BlciBmaWVsZCBJRHMKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBpbml0SURzKCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBOYXRpdmVDTU0ubG9hZENNTSgpOworICAgICAgICBpbml0SURzKCk7CisgICAgfQorCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gTENNUyBpbWFnZSBmb3JtYXQgZW5jb2RlcnMKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgY29sb3JzcGFjZVNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxNik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHN3YXBmaXJzdFNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxNCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGZsYXZvclNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxMyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHBsYW5hclNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxMik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGVuZGlhblNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGRvc3dhcFNoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAxMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGV4dHJhU2goaW50IHMpIHsKKyAgICAgICAgcmV0dXJuIChzIDw8IDcpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBjaGFubmVsc1NoKGludCBzKSB7CisgICAgICAgIHJldHVybiAocyA8PCAzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgYnl0ZXNTaChpbnQgcykgeworICAgICAgICByZXR1cm4gczsKKyAgICB9CisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gRW5kIG9mIExDTVMgaW1hZ2UgZm9ybWF0IGVuY29kZXJzCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgICAvLyBBY2Nlc3NvcnMKKyAgICBPYmplY3QgZ2V0Q2hhbm5lbERhdGEoKSB7CisgICAgICAgIHJldHVybiBpbWFnZURhdGE7CisgICAgfQorCisgICAgaW50IGdldE51bUNvbHMoKSB7CisgICAgICAgIHJldHVybiBjb2xzOworICAgIH0KKworICAgIGludCBnZXROdW1Sb3dzKCkgeworICAgICAgICByZXR1cm4gcm93czsKKyAgICB9CisKKyAgICAvLyBDb25zdHJ1Y3RvcnMKKyAgICBwdWJsaWMgTmF0aXZlSW1hZ2VGb3JtYXQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2ltcGxlIGltYWdlIGxheW91dCBmb3IgY29tbW9uIGNhc2Ugd2l0aAorICAgICAqIG5vdCBvcHRpbWl6ZWQgd29ya2Zsb3cuCisgICAgICoKKyAgICAgKiBGb3IgaGlmaSBjb2xvcnNwYWNlcyB3aXRoIDUrIGNvbG9yIGNoYW5uZWxzIGltZ0RhdGEKKyAgICAgKiBzaG91bGQgYmUgPGNvZGU+Ynl0ZTwvY29kZT4gYXJyYXkuCisgICAgICoKKyAgICAgKiBGb3IgY29tbW9uIGNvbG9yc3BhY2VzIHdpdGggdXAgdG8gNCBjb2xvciBjaGFubmVscyBpdAorICAgICAqIHNob3VsZCBiZSA8Y29kZT5zaG9ydDwvY29kZT4gYXJyYXkuCisgICAgICoKKyAgICAgKiBBbHBoYSBjaGFubmVsIGlzIGhhbmRsZWQgYnkgY2FsbGVyLCBub3QgYnkgQ01TLgorICAgICAqCisgICAgICogQ29sb3IgY2hhbm5lbHMgYXJlIGluIHRoZWlyIG5hdHVyYWwgb3JkZXIgKG5vdCBCR1IgYnV0IFJHQikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW1nRGF0YSAtIGFycmF5IG9mIDxjb2RlPmJ5dGU8L2NvZGU+IG9yIDxjb2RlPnNob3J0PC9jb2RlPgorICAgICAqIEBwYXJhbSBuQ2hhbm5lbHMgLSBudW1iZXIgb2YgY2hhbm5lbHMKKyAgICAgKiBAcGFyYW0gblJvd3MgLSBudW1iZXIgb2Ygc2NhbmxpbmVzIGluIHRoZSBpbWFnZQorICAgICAqIEBwYXJhbSBuQ29scyAtIG51bWJlciBvZiBwaXhlbHMgaW4gb25lIHJvdyBvZiB0aGUgaW1hZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgTmF0aXZlSW1hZ2VGb3JtYXQoT2JqZWN0IGltZ0RhdGEsIGludCBuQ2hhbm5lbHMsIGludCBuUm93cywgaW50IG5Db2xzKSB7CisgICAgICAgIGlmIChpbWdEYXRhIGluc3RhbmNlb2Ygc2hvcnRbXSkgeworICAgICAgICAgICAgY21tRm9ybWF0IHw9IGJ5dGVzU2goMik7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoaW1nRGF0YSBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgICAgICAgY21tRm9ybWF0IHw9IGJ5dGVzU2goMSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgLy8gYXd0LjQ3PUZpcnN0IGFyZ3VtZW50IHNob3VsZCBiZSBieXRlIG9yIHNob3J0IGFycmF5CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQ3IikpOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgY21tRm9ybWF0IHw9IGNoYW5uZWxzU2gobkNoYW5uZWxzKTsKKworICAgICAgICByb3dzID0gblJvd3M7CisgICAgICAgIGNvbHMgPSBuQ29sczsKKworICAgICAgICBpbWFnZURhdGEgPSBpbWdEYXRhOworCisgICAgICAgIGRhdGFPZmZzZXQgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZHVjZXMgaW1hZ2UgZm9ybWF0IGZyb20gdGhlIGJ1ZmZlcmVkIGltYWdlIHR5cGUKKyAgICAgKiBvciBjb2xvciBhbmQgc2FtcGxlIG1vZGVscy4KKyAgICAgKiBAcGFyYW0gYmkgLSBpbWFnZQorICAgICAqIEByZXR1cm4gaW1hZ2UgZm9ybWF0IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTmF0aXZlSW1hZ2VGb3JtYXQgY3JlYXRlTmF0aXZlSW1hZ2VGb3JtYXQoQnVmZmVyZWRJbWFnZSBiaSkgeworICAgICAgICBOYXRpdmVJbWFnZUZvcm1hdCBmbXQgPSBuZXcgTmF0aXZlSW1hZ2VGb3JtYXQoKTsKKworICAgICAgICBzd2l0Y2ggKGJpLmdldFR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQjogeworICAgICAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBJTlRfUkdCX0xDTVNfRk1UOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQVJHQjoKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0lOVF9BUkdCX1BSRTogeworICAgICAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBJTlRfQVJHQl9MQ01TX0ZNVDsKKyAgICAgICAgICAgICAgICBmbXQuYWxwaGFPZmZzZXQgPSAzOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9JTlRfQkdSOiB7CisgICAgICAgICAgICAgICAgZm10LmNtbUZvcm1hdCA9IElOVF9CR1JfTENNU19GTVQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFXzNCWVRFX0JHUjogeworICAgICAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBUSFJFRV9CWVRFX0JHUl9MQ01TX0ZNVDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfNEJZVEVfQUJHUl9QUkU6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV80QllURV9BQkdSOiB7CisgICAgICAgICAgICAgICAgZm10LmNtbUZvcm1hdCA9IEZPVVJfQllURV9BQkdSX0xDTVNfRk1UOworICAgICAgICAgICAgICAgIGZtdC5hbHBoYU9mZnNldCA9IDA7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX0JZVEVfR1JBWTogeworICAgICAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBCWVRFX0dSQVlfTENNU19GTVQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF9HUkFZOiB7CisgICAgICAgICAgICAgICAgZm10LmNtbUZvcm1hdCA9IFVTSE9SVF9HUkFZX0xDTVNfRk1UOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0JJTkFSWToKKyAgICAgICAgICAgIGNhc2UgQnVmZmVyZWRJbWFnZS5UWVBFX1VTSE9SVF81NjVfUkdCOgorICAgICAgICAgICAgY2FzZSBCdWZmZXJlZEltYWdlLlRZUEVfVVNIT1JUXzU1NV9SR0I6CisgICAgICAgICAgICBjYXNlIEJ1ZmZlcmVkSW1hZ2UuVFlQRV9CWVRFX0lOREVYRUQ6IHsKKyAgICAgICAgICAgICAgICAvLyBBIGJ1bmNoIG9mIHVuc3VwcG9ydGVkIGZvcm1hdHMKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBicmVhazsgLy8gVHJ5IHRvIGxvb2sgYXQgc2FtcGxlIG1vZGVsIGFuZCBjb2xvciBtb2RlbAorICAgICAgICB9CisKKworICAgICAgICBpZiAoZm10LmNtbUZvcm1hdCA9PSAwKSB7CisgICAgICAgICAgICBDb2xvck1vZGVsIGNtID0gYmkuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgU2FtcGxlTW9kZWwgc20gPSBiaS5nZXRTYW1wbGVNb2RlbCgpOworCisgICAgICAgICAgICBpZiAoc20gaW5zdGFuY2VvZiBDb21wb25lbnRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgICAgIENvbXBvbmVudFNhbXBsZU1vZGVsIGNzbSA9IChDb21wb25lbnRTYW1wbGVNb2RlbCkgc207CisgICAgICAgICAgICAgICAgZm10LmNtbUZvcm1hdCA9IGdldEZvcm1hdEZyb21Db21wb25lbnRNb2RlbChjc20sIGNtLmhhc0FscGhhKCkpOworICAgICAgICAgICAgICAgIGZtdC5zY2FubGluZVN0cmlkZSA9IGNhbGN1bGF0ZVNjYW5saW5lU3RyaWRlQ1NNKGNzbSwgYmkuZ2V0UmFzdGVyKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzbSBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgICAgICBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNwcHNtID0gKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHNtOworICAgICAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBnZXRGb3JtYXRGcm9tU1BQU2FtcGxlTW9kZWwoc3Bwc20sIGNtLmhhc0FscGhhKCkpOworICAgICAgICAgICAgICAgIGZtdC5zY2FubGluZVN0cmlkZSA9IGNhbGN1bGF0ZVNjYW5saW5lU3RyaWRlU1BQU00oc3Bwc20sIGJpLmdldFJhc3RlcigpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNtLmhhc0FscGhhKCkpCisgICAgICAgICAgICAgICAgZm10LmFscGhhT2Zmc2V0ID0gY2FsY3VsYXRlQWxwaGFPZmZzZXQoc20sIGJpLmdldFJhc3RlcigpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmbXQuY21tRm9ybWF0ID09IDApCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKworICAgICAgICBpZiAoIWZtdC5zZXRJbWFnZURhdGEoYmkuZ2V0UmFzdGVyKCkuZ2V0RGF0YUJ1ZmZlcigpKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBmbXQucm93cyA9IGJpLmdldEhlaWdodCgpOworICAgICAgICBmbXQuY29scyA9IGJpLmdldFdpZHRoKCk7CisKKyAgICAgICAgZm10LmRhdGFPZmZzZXQgPSBiaS5nZXRSYXN0ZXIoKS5nZXREYXRhQnVmZmVyKCkuZ2V0T2Zmc2V0KCk7CisKKyAgICAgICAgcmV0dXJuIGZtdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWR1Y2VzIGltYWdlIGZvcm1hdCBmcm9tIHRoZSByYXN0ZXIgc2FtcGxlIG1vZGVsLgorICAgICAqIEBwYXJhbSByIC0gcmFzdGVyCisgICAgICogQHJldHVybiBpbWFnZSBmb3JtYXQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBOYXRpdmVJbWFnZUZvcm1hdCBjcmVhdGVOYXRpdmVJbWFnZUZvcm1hdChSYXN0ZXIgcikgeworICAgICAgICBOYXRpdmVJbWFnZUZvcm1hdCBmbXQgPSBuZXcgTmF0aXZlSW1hZ2VGb3JtYXQoKTsKKyAgICAgICAgU2FtcGxlTW9kZWwgc20gPSByLmdldFNhbXBsZU1vZGVsKCk7CisKKyAgICAgICAgLy8gQXNzdW1lIHRoYXQgdGhlcmUncyBubyBhbHBoYQorICAgICAgICBpZiAoc20gaW5zdGFuY2VvZiBDb21wb25lbnRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgQ29tcG9uZW50U2FtcGxlTW9kZWwgY3NtID0gKENvbXBvbmVudFNhbXBsZU1vZGVsKSBzbTsKKyAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBnZXRGb3JtYXRGcm9tQ29tcG9uZW50TW9kZWwoY3NtLCBmYWxzZSk7CisgICAgICAgICAgICBmbXQuc2NhbmxpbmVTdHJpZGUgPSBjYWxjdWxhdGVTY2FubGluZVN0cmlkZUNTTShjc20sIHIpOworICAgICAgICB9IGVsc2UgaWYgKHNtIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbSA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSBzbTsKKyAgICAgICAgICAgIGZtdC5jbW1Gb3JtYXQgPSBnZXRGb3JtYXRGcm9tU1BQU2FtcGxlTW9kZWwoc3Bwc20sIGZhbHNlKTsKKyAgICAgICAgICAgIGZtdC5zY2FubGluZVN0cmlkZSA9IGNhbGN1bGF0ZVNjYW5saW5lU3RyaWRlU1BQU00oc3Bwc20sIHIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZtdC5jbW1Gb3JtYXQgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworCisgICAgICAgIGZtdC5jb2xzID0gci5nZXRXaWR0aCgpOworICAgICAgICBmbXQucm93cyA9IHIuZ2V0SGVpZ2h0KCk7CisgICAgICAgIGZtdC5kYXRhT2Zmc2V0ID0gci5nZXREYXRhQnVmZmVyKCkuZ2V0T2Zmc2V0KCk7CisKKyAgICAgICAgaWYgKCFmbXQuc2V0SW1hZ2VEYXRhKHIuZ2V0RGF0YUJ1ZmZlcigpKSkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworCisgICAgICAgIHJldHVybiBmbXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyBMQ01TIGZvcm1hdCBmcm9tIHRoZSBjb21wb25lbnQgc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIHNtIC0gc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIGhhc0FscGhhIC0gdHJ1ZSBpZiB0aGVyZSdzIGFuIGFscGhhIGNoYW5uZWwKKyAgICAgKiBAcmV0dXJuIExDTVMgZm9ybWF0CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldEZvcm1hdEZyb21Db21wb25lbnRNb2RlbChDb21wb25lbnRTYW1wbGVNb2RlbCBzbSwgYm9vbGVhbiBoYXNBbHBoYSkgeworICAgICAgICAvLyBNdWx0aXBsZSBkYXRhIGFycmF5cyAoYmFua3MpIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgaW50IGJhbmtJbmRleCA9IHNtLmdldEJhbmtJbmRpY2VzKClbMF07CisgICAgICAgIGZvciAoaW50IGk9MTsgaSA8IHNtLmdldE51bUJhbmRzKCk7IGkrKykgeworICAgICAgICAgICAgaWYgKHNtLmdldEJhbmtJbmRpY2VzKClbaV0gIT0gYmFua0luZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgY2hhbm5lbHMgPSBoYXNBbHBoYSA/IHNtLmdldE51bUJhbmRzKCktMSA6IHNtLmdldE51bUJhbmRzKCk7CisgICAgICAgIGludCBleHRyYSA9IGhhc0FscGhhID8gMSA6IDA7CisgICAgICAgIGludCBieXRlcyA9IDE7CisgICAgICAgIHN3aXRjaCAoc20uZ2V0RGF0YVR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfQllURToKKyAgICAgICAgICAgICAgICBieXRlcyA9IDE7IGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQ6CisgICAgICAgICAgICAgICAgYnl0ZXMgPSAyOyBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRGF0YUJ1ZmZlci5UWVBFX0lOVDoKKyAgICAgICAgICAgICAgICBieXRlcyA9IDQ7IGJyZWFrOworICAgICAgICAgICAgY2FzZSBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFOgorICAgICAgICAgICAgICAgIGJ5dGVzID0gMDsgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiAwOyAvLyBVbnN1cHBvcnRlZCBkYXRhIHR5cGUKKyAgICAgICAgfQorCisgICAgICAgIGludCBkb1N3YXAgPSAwOworICAgICAgICBpbnQgc3dhcEZpcnN0ID0gMDsKKyAgICAgICAgYm9vbGVhbiBrbm93bkZvcm1hdCA9IGZhbHNlOworCisgICAgICAgIGludCBpOworCisgICAgICAgIC8vICJSR0JBIgorICAgICAgICBmb3IgKGk9MDsgaSA8IHNtLmdldE51bUJhbmRzKCk7IGkrKykgeworICAgICAgICAgICAgaWYgKHNtLmdldEJhbmRPZmZzZXRzKClbaV0gIT0gaSkgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPT0gc20uZ2V0TnVtQmFuZHMoKSkgeyAvLyBPaywgaXQgaXMgaXQKKyAgICAgICAgICAgIGRvU3dhcCA9IDA7CisgICAgICAgICAgICBzd2FwRmlyc3QgPSAwOworICAgICAgICAgICAga25vd25Gb3JtYXQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLy8gIkFSR0IiCisgICAgICAgIGlmICgha25vd25Gb3JtYXQpIHsKKyAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgc20uZ2V0TnVtQmFuZHMoKS0xOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoc20uZ2V0QmFuZE9mZnNldHMoKVtpXSAhPSBpKzEpIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNtLmdldEJhbmRPZmZzZXRzKClbaV0gPT0gMCkgaSsrOworICAgICAgICAgICAgaWYgKGkgPT0gc20uZ2V0TnVtQmFuZHMoKSkgeyAvLyBPaywgaXQgaXMgaXQKKyAgICAgICAgICAgICAgICBkb1N3YXAgPSAwOworICAgICAgICAgICAgICAgIHN3YXBGaXJzdCA9IDE7CisgICAgICAgICAgICAgICAga25vd25Gb3JtYXQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gIkJHUkEiCisgICAgICAgIGlmICgha25vd25Gb3JtYXQpIHsKKyAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgc20uZ2V0TnVtQmFuZHMoKS0xOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoc20uZ2V0QmFuZE9mZnNldHMoKVtpXSAhPSBzbS5nZXROdW1CYW5kcygpIC0gMiAtIGkpIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNtLmdldEJhbmRPZmZzZXRzKClbaV0gPT0gc20uZ2V0TnVtQmFuZHMoKS0xKSBpKys7CisgICAgICAgICAgICBpZiAoaSA9PSBzbS5nZXROdW1CYW5kcygpKSB7IC8vIE9rLCBpdCBpcyBpdAorICAgICAgICAgICAgICAgIGRvU3dhcCA9IDE7CisgICAgICAgICAgICAgICAgc3dhcEZpcnN0ID0gMTsKKyAgICAgICAgICAgICAgICBrbm93bkZvcm1hdCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyAiQUJHUiIKKyAgICAgICAgaWYgKCFrbm93bkZvcm1hdCkgeworICAgICAgICAgICAgZm9yIChpPTA7IGkgPCBzbS5nZXROdW1CYW5kcygpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoc20uZ2V0QmFuZE9mZnNldHMoKVtpXSAhPSBzbS5nZXROdW1CYW5kcygpIC0gMSAtIGkpIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gc20uZ2V0TnVtQmFuZHMoKSkgeyAvLyBPaywgaXQgaXMgaXQKKyAgICAgICAgICAgICAgICBkb1N3YXAgPSAxOworICAgICAgICAgICAgICAgIHN3YXBGaXJzdCA9IDA7CisgICAgICAgICAgICAgICAga25vd25Gb3JtYXQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gWFhYIC0gUGxhbmFyIGZvcm1hdHMgYXJlIG5vdCBzdXBwb3J0ZWQgeWV0CisgICAgICAgIGlmICgha25vd25Gb3JtYXQpCisgICAgICAgICAgICByZXR1cm4gMDsKKworICAgICAgICByZXR1cm4KKyAgICAgICAgICAgIGNoYW5uZWxzU2goY2hhbm5lbHMpIHwKKyAgICAgICAgICAgIGJ5dGVzU2goYnl0ZXMpIHwKKyAgICAgICAgICAgIGV4dHJhU2goZXh0cmEpIHwKKyAgICAgICAgICAgIGRvc3dhcFNoKGRvU3dhcCkgfAorICAgICAgICAgICAgc3dhcGZpcnN0U2goc3dhcEZpcnN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIExDTVMgZm9ybWF0IGZyb20gdGhlIHNpbmdsZSBwaXhlbCBwYWNrZWQgc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIHNtIC0gc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIGhhc0FscGhhIC0gdHJ1ZSBpZiB0aGVyZSdzIGFuIGFscGhhIGNoYW5uZWwKKyAgICAgKiBAcmV0dXJuIExDTVMgZm9ybWF0CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldEZvcm1hdEZyb21TUFBTYW1wbGVNb2RlbChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsIHNtLAorICAgICAgICAgICAgYm9vbGVhbiBoYXNBbHBoYSkgeworICAgICAgICAvLyBDYW4gd2UgZXh0cmFjdCBieXRlcz8KKyAgICAgICAgaW50IG1hc2sgPSBzbS5nZXRCaXRNYXNrcygpWzBdID4+PiBzbS5nZXRCaXRPZmZzZXRzKClbMF07CisgICAgICAgIGlmICghKG1hc2sgPT0gMHhGRiB8fCBtYXNrID09IDB4RkZGRiB8fCBtYXNrID09IDB4RkZGRkZGRkYpKQorICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgLy8gQWxsIG1hc2tzIGFyZSBzYW1lPworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IHNtLmdldE51bUJhbmRzKCk7IGkrKykgeworICAgICAgICAgICAgaWYgKChzbS5nZXRCaXRNYXNrcygpW2ldID4+PiBzbS5nZXRCaXRPZmZzZXRzKClbaV0pICE9IG1hc2spCisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcGl4ZWxTaXplID0gMDsKKyAgICAgICAgLy8gQ2hlY2sgaWYgZGF0YSB0eXBlIGlzIHN1cHBvcnRlZAorICAgICAgICBpZiAoc20uZ2V0RGF0YVR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfVVNIT1JUKQorICAgICAgICAgICAgcGl4ZWxTaXplID0gMjsKKyAgICAgICAgZWxzZSBpZiAoc20uZ2V0RGF0YVR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfSU5UKQorICAgICAgICAgICAgcGl4ZWxTaXplID0gNDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIDA7CisKKworICAgICAgICBpbnQgYnl0ZXMgPSAwOworICAgICAgICBzd2l0Y2ggKG1hc2spIHsKKyAgICAgICAgICAgIGNhc2UgMHhGRjoKKyAgICAgICAgICAgICAgICBieXRlcyA9IDE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDB4RkZGRjoKKyAgICAgICAgICAgICAgICBieXRlcyA9IDI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDB4RkZGRkZGRkY6CisgICAgICAgICAgICAgICAgYnl0ZXMgPSA0OworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIDA7CisgICAgICAgIH0KKworCisgICAgICAgIGludCBjaGFubmVscyA9IGhhc0FscGhhID8gc20uZ2V0TnVtQmFuZHMoKS0xIDogc20uZ2V0TnVtQmFuZHMoKTsKKyAgICAgICAgaW50IGV4dHJhID0gaGFzQWxwaGEgPyAxIDogMDsKKyAgICAgICAgZXh0cmEgKz0gIHBpeGVsU2l6ZS9ieXRlcyAtIHNtLmdldE51bUJhbmRzKCk7IC8vIFVudXNlZCBieXRlcz8KKworICAgICAgICAvLyBGb3JtIGFuIEFycmF5TGlzdCBjb250YWluaW5nIG9mZnNldCBmb3IgZWFjaCBiYW5kCisgICAgICAgIEFycmF5TGlzdDxJbnRlZ2VyPiBvZmZzZXRzTHN0ID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgICBmb3IgKGludCBrPTA7IGsgPCBzbS5nZXROdW1CYW5kcygpOyBrKyspIHsKKyAgICAgICAgICAgIG9mZnNldHNMc3QuYWRkKG5ldyBJbnRlZ2VyKHNtLmdldEJpdE9mZnNldHMoKVtrXS8oYnl0ZXMqOCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFkZCBvZmZzZXRzIGZvciB1bnVzZWQgc3BhY2UKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHBpeGVsU2l6ZS9ieXRlczsgaSsrKSB7CisgICAgICAgICAgICBpZiAob2Zmc2V0c0xzdC5pbmRleE9mKG5ldyBJbnRlZ2VyKGkpKSA8IDApCisgICAgICAgICAgICAgICAgb2Zmc2V0c0xzdC5hZGQobmV3IEludGVnZXIoaSkpOworICAgICAgICB9CisKKyAgICAgICAgaW50IG9mZnNldHNbXSA9IG5ldyBpbnRbcGl4ZWxTaXplL2J5dGVzXTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPG9mZnNldHNMc3Quc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIG9mZnNldHNbaV0gPSBvZmZzZXRzTHN0LmdldChpKS5pbnRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGRvU3dhcCA9IDA7CisgICAgICAgIGludCBzd2FwRmlyc3QgPSAwOworICAgICAgICBib29sZWFuIGtub3duRm9ybWF0ID0gZmFsc2U7CisKKyAgICAgICAgaW50IGk7CisKKyAgICAgICAgLy8gIlJHQkEiCisgICAgICAgIGZvciAoaT0wOyBpIDwgcGl4ZWxTaXplOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChvZmZzZXRzW2ldICE9IGkpIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlmIChpID09IHBpeGVsU2l6ZSkgeyAvLyBPaywgaXQgaXMgaXQKKyAgICAgICAgICAgIGRvU3dhcCA9IDA7CisgICAgICAgICAgICBzd2FwRmlyc3QgPSAwOworICAgICAgICAgICAga25vd25Gb3JtYXQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLy8gIkFSR0IiCisgICAgICAgIGlmICgha25vd25Gb3JtYXQpIHsKKyAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgcGl4ZWxTaXplLTE7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChvZmZzZXRzW2ldICE9IGkrMSkgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob2Zmc2V0c1tpXSA9PSAwKSBpKys7CisgICAgICAgICAgICBpZiAoaSA9PSBwaXhlbFNpemUpIHsgLy8gT2ssIGl0IGlzIGl0CisgICAgICAgICAgICAgICAgZG9Td2FwID0gMDsKKyAgICAgICAgICAgICAgICBzd2FwRmlyc3QgPSAxOworICAgICAgICAgICAgICAgIGtub3duRm9ybWF0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vICJCR1JBIgorICAgICAgICBpZiAoIWtub3duRm9ybWF0KSB7CisgICAgICAgICAgICBmb3IgKGk9MDsgaSA8IHBpeGVsU2l6ZS0xOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAob2Zmc2V0c1tpXSAhPSBwaXhlbFNpemUgLSAyIC0gaSkgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob2Zmc2V0c1tpXSA9PSBwaXhlbFNpemUtMSkgaSsrOworICAgICAgICAgICAgaWYgKGkgPT0gcGl4ZWxTaXplKSB7IC8vIE9rLCBpdCBpcyBpdAorICAgICAgICAgICAgICAgIGRvU3dhcCA9IDE7CisgICAgICAgICAgICAgICAgc3dhcEZpcnN0ID0gMTsKKyAgICAgICAgICAgICAgICBrbm93bkZvcm1hdCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyAiQUJHUiIKKyAgICAgICAgaWYgKCFrbm93bkZvcm1hdCkgeworICAgICAgICAgICAgZm9yIChpPTA7IGkgPCBwaXhlbFNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChvZmZzZXRzW2ldICE9IHBpeGVsU2l6ZSAtIDEgLSBpKSBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpID09IHBpeGVsU2l6ZSkgeyAvLyBPaywgaXQgaXMgaXQKKyAgICAgICAgICAgICAgICBkb1N3YXAgPSAxOworICAgICAgICAgICAgICAgIHN3YXBGaXJzdCA9IDA7CisgICAgICAgICAgICAgICAga25vd25Gb3JtYXQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gWFhYIC0gUGxhbmFyIGZvcm1hdHMgYXJlIG5vdCBzdXBwb3J0ZWQgeWV0CisgICAgICAgIGlmICgha25vd25Gb3JtYXQpCisgICAgICAgICAgICByZXR1cm4gMDsKKworICAgICAgICByZXR1cm4KKyAgICAgICAgICAgIGNoYW5uZWxzU2goY2hhbm5lbHMpIHwKKyAgICAgICAgICAgIGJ5dGVzU2goYnl0ZXMpIHwKKyAgICAgICAgICAgIGV4dHJhU2goZXh0cmEpIHwKKyAgICAgICAgICAgIGRvc3dhcFNoKGRvU3dhcCkgfAorICAgICAgICAgICAgc3dhcGZpcnN0U2goc3dhcEZpcnN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIGRhdGEgYXJyYXkgZnJvbSB0aGUgRGF0YUJ1ZmZlciBvYmplY3QKKyAgICAgKiBAcGFyYW0gZGIgLSBkYXRhIGJ1ZmZlcgorICAgICAqIEByZXR1cm4gLSB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2V0SW1hZ2VEYXRhKERhdGFCdWZmZXIgZGIpIHsKKyAgICAgICAgQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yIGRiQWNjZXNzID0gQXd0SW1hZ2VCYWNrZG9vckFjY2Vzc29yLmdldEluc3RhbmNlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbWFnZURhdGEgPSBkYkFjY2Vzcy5nZXREYXRhKGRiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gVW5rbm93biBkYXRhIGJ1ZmZlciB0eXBlCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHNjYW5saW5lIHN0cmlkZSBpbiBieXRlcworICAgICAqIEBwYXJhbSBjc20gLSBjb21wb25lbnQgc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIHIgLSByYXN0ZXIKKyAgICAgKiBAcmV0dXJuIHNjYW5saW5lIHN0cmlkZSBpbiBieXRlcworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBjYWxjdWxhdGVTY2FubGluZVN0cmlkZUNTTShDb21wb25lbnRTYW1wbGVNb2RlbCBjc20sIFJhc3RlciByKSB7CisgICAgICAgIGlmIChjc20uZ2V0U2NhbmxpbmVTdHJpZGUoKSAhPSBjc20uZ2V0UGl4ZWxTdHJpZGUoKSpjc20uZ2V0V2lkdGgoKSkgeworICAgICAgICAgICAgaW50IGRhdGFUeXBlU2l6ZSA9IERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKHIuZ2V0RGF0YUJ1ZmZlcigpLmdldERhdGFUeXBlKCkpIC8gODsKKyAgICAgICAgICAgIHJldHVybiBjc20uZ2V0U2NhbmxpbmVTdHJpZGUoKSpkYXRhVHlwZVNpemU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgc2NhbmxpbmUgc3RyaWRlIGluIGJ5dGVzCisgICAgICogQHBhcmFtIHNwcHNtIC0gc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIHIgLSByYXN0ZXIKKyAgICAgKiBAcmV0dXJuIHNjYW5saW5lIHN0cmlkZSBpbiBieXRlcworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBjYWxjdWxhdGVTY2FubGluZVN0cmlkZVNQUFNNKFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwgc3Bwc20sIFJhc3RlciByKSB7CisgICAgICAgIGlmIChzcHBzbS5nZXRTY2FubGluZVN0cmlkZSgpICE9IHNwcHNtLmdldFdpZHRoKCkpIHsKKyAgICAgICAgICAgIGludCBkYXRhVHlwZVNpemUgPSBEYXRhQnVmZmVyLmdldERhdGFUeXBlU2l6ZShyLmdldERhdGFCdWZmZXIoKS5nZXREYXRhVHlwZSgpKSAvIDg7CisgICAgICAgICAgICByZXR1cm4gc3Bwc20uZ2V0U2NhbmxpbmVTdHJpZGUoKSpkYXRhVHlwZVNpemU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgYnl0ZSBvZmZzZXQgb2YgdGhlIGFscGhhIGNoYW5uZWwgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwaXhlbCBkYXRhCisgICAgICogQHBhcmFtIHNtIC0gc2FtcGxlIG1vZGVsCisgICAgICogQHBhcmFtIHIgLSByYXN0ZXIKKyAgICAgKiBAcmV0dXJuIGJ5dGUgb2Zmc2V0IG9mIHRoZSBhbHBoYSBjaGFubmVsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNhbGN1bGF0ZUFscGhhT2Zmc2V0KFNhbXBsZU1vZGVsIHNtLCBSYXN0ZXIgcikgeworICAgICAgICBpZiAoc20gaW5zdGFuY2VvZiBDb21wb25lbnRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgQ29tcG9uZW50U2FtcGxlTW9kZWwgY3NtID0gKENvbXBvbmVudFNhbXBsZU1vZGVsKSBzbTsKKyAgICAgICAgICAgIGludCBkYXRhVHlwZVNpemUgPQorICAgICAgICAgICAgICAgIERhdGFCdWZmZXIuZ2V0RGF0YVR5cGVTaXplKHIuZ2V0RGF0YUJ1ZmZlcigpLmdldERhdGFUeXBlKCkpIC8gODsKKyAgICAgICAgICAgIHJldHVybgorICAgICAgICAgICAgICAgIGNzbS5nZXRCYW5kT2Zmc2V0cygpW2NzbS5nZXRCYW5kT2Zmc2V0cygpLmxlbmd0aCAtIDFdICogZGF0YVR5cGVTaXplOworICAgICAgICB9IGVsc2UgaWYgKHNtIGluc3RhbmNlb2YgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCkgeworICAgICAgICAgICAgU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbCBzcHBzbSA9IChTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSBzbTsKKyAgICAgICAgICAgIHJldHVybiBzcHBzbS5nZXRCaXRPZmZzZXRzKClbc3Bwc20uZ2V0Qml0T2Zmc2V0cygpLmxlbmd0aCAtIDFdIC8gODsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsgLy8gTm8gb2Zmc2V0LCBkb24ndCBjb3B5IGFscGhhCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRGb250LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRGb250LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZThhZDFiYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvQW5kcm9pZEZvbnQuamF2YQpAQCAtMCwwICsxLDI1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuVG9vbGtpdDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkZvbnRSZW5kZXJDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmZvbnQuTGluZU1ldHJpY3M7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkZvbnRNYW5hZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250UGVlckltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkdseXBoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5MaW5lTWV0cmljc0ltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogTGludXggcGxhdGZvcm0gZm9udCBwZWVyIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIFhmdCBhbmQgRnJlZVR5cGUgbGlicmFyaWVzLgorICovCitwdWJsaWMgY2xhc3MgQW5kcm9pZEZvbnQgZXh0ZW5kcyBGb250UGVlckltcGwgeworCisgICAgLy8gUGFpcnMgb2YgW2JlZ2luLCBlbmRdLFsuLl0uLiB1bmljb2RlIHJhbmdlcyB2YWx1ZXMgCisgICAgcHJpdmF0ZSBpbnRbXSBmb250VW5pY29kZVJhbmdlczsKKyAgICAKKyAgICAvLyB0YWJsZSB3aXRoIGxvYWRlZCBjYWNoZWQgR2x5cGhzCisgICAgcHJpdmF0ZSBIYXNodGFibGUgZ2x5cGhzID0gbmV3IEhhc2h0YWJsZSgpOworICAgIAorICAgIC8vIFgxMSBkaXNwbGF5IHZhbHVlCisgICAgcHJpdmF0ZSBsb25nIGRpc3BsYXkgPSAwOworCisgICAgLy8gWDExIHNjcmVlbiB2YWx1ZQorICAgIHByaXZhdGUgaW50IHNjcmVlbiA9IDA7CisgICAgCisgICAgcHVibGljIEFuZHJvaWRGb250KFN0cmluZyBmb250TmFtZSwgaW50IGZvbnRTdHlsZSwgaW50IGZvbnRTaXplKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFdvcmthcm91bmQgOiB0byBpbml0aWFsaXplIGF3dCBwbGF0Zm9ybS1kZXBlbmRlbnQgZmllbGRzIGFuZCBsaWJyYXJpZXMuCisgICAgICAgICAqLworICAgICAgICBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCk7CisgICAgICAgIHRoaXMubmFtZSA9IGZvbnROYW1lOworICAgICAgICB0aGlzLnNpemUgPSBmb250U2l6ZTsKKyAgICAgICAgdGhpcy5zdHlsZSA9IGZvbnRTdHlsZTsKKyAgICAgICAKKyAgICAgICAgaW5pdEFuZHJvaWRGb250KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgc29tZSBuYXRpdmUgZGVwZW5kZW50IGZvbnQgaW5mb3JtYXRpb24sIGUuZy4gbnVtYmVyIG9mIGdseXBocywgCisgICAgICogZm9udCBtZXRyaWNzLCBpdGFsaWMgYW5nbGUgZXRjLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbml0QW5kcm9pZEZvbnQoKXsKKyAgICAgICAgdGhpcy5ubG0gPSBuZXcgQW5kcm9pZExpbmVNZXRyaWNzKHRoaXMsIG51bGwsICIgIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgdGhpcy5hc2NlbnQgPSBubG0uZ2V0TG9naWNhbEFzY2VudCgpOworICAgICAgICB0aGlzLmRlc2NlbnQgPSBubG0uZ2V0TG9naWNhbERlc2NlbnQoKTsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBubG0uZ2V0SGVpZ2h0KCk7CisgICAgICAgIHRoaXMubGVhZGluZyA9IG5sbS5nZXRMb2dpY2FsTGVhZGluZygpOworICAgICAgICB0aGlzLm1heEFkdmFuY2UgPSBubG0uZ2V0TG9naWNhbE1heENoYXJXaWR0aCgpOworCisgICAgICAgIGlmICh0aGlzLmZvbnRUeXBlID09IEZvbnRNYW5hZ2VyLkZPTlRfVFlQRV9UMSl7CisgICAgICAgICAgICB0aGlzLmRlZmF1bHRDaGFyID0gMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuZGVmYXVsdENoYXIgPSAwOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5tYXhDaGFyQm91bmRzID0gbmV3IFJlY3RhbmdsZTJELkZsb2F0KDAsIC1ubG0uZ2V0QXNjZW50KCksIG5sbS5nZXRNYXhDaGFyV2lkdGgoKSwgdGhpcy5oZWlnaHQpOworICAgIH0KKworCisgICAgcHVibGljIGJvb2xlYW4gY2FuRGlzcGxheShjaGFyIGNocikgeworICAgICAgICAvLyBUT0RPOiB0byBpbXByb3ZlIHBlcmZvcm1hbmNlIHRoZXJlIGlzIGEgc2VuY2UgdG8gaW1wbGVtZW50IGdldAorICAgICAgICAvLyB1bmljb2RlIHJhbmdlcyB0byBjaGVjayBpZiBjaGFyIGNhbiBiZSBkaXNwbGF5ZWQgd2l0aG91dAorICAgICAgICAvLyBuYXRpdmUgY2FsbHMgaW4gaXNHbHlwaEV4aXN0cygpIG1ldGhvZAorCisgICAgICAgIHJldHVybiBpc0dseXBoRXhpc3RzKGNocik7CisgICAgfQorCisgICAgcHVibGljIExpbmVNZXRyaWNzIGdldExpbmVNZXRyaWNzKFN0cmluZyBzdHIsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgQWZmaW5lVHJhbnNmb3JtIGF0KSB7CisKKyAgICAgICAgLy8gSW5pdGlhbGl6ZSBiYXNlbGluZSBvZmZzZXRzCisgICAgICAgIG5sbS5nZXRCYXNlbGluZU9mZnNldHMoKTsKKyAgICAgICAgCisgICAgICAgIExpbmVNZXRyaWNzSW1wbCBsbSA9IChMaW5lTWV0cmljc0ltcGwpKHRoaXMubmxtLmNsb25lKCkpOworICAgICAgICBsbS5zZXROdW1DaGFycyhzdHIubGVuZ3RoKCkpOworCisgICAgICAgIGlmICgoYXQgIT0gbnVsbCkgJiYgKCFhdC5pc0lkZW50aXR5KCkpKXsKKyAgICAgICAgICAgIGxtLnNjYWxlKChmbG9hdClhdC5nZXRTY2FsZVgoKSwgKGZsb2F0KWF0LmdldFNjYWxlWSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBsbTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFBTTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHBzTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhbWlseShMb2NhbGUgbCkgeworICAgICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgbG9jYWxpemVkIGZhbWlseQorICAgICAgICBpZiAoZm9udFR5cGUgPT0gRm9udE1hbmFnZXIuRk9OVF9UWVBFX1RUKXsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEZhbWlseSgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRoaXMuZm9udEZhbWlseU5hbWU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGb250TmFtZShMb2NhbGUgbCkgeworICAgICAgICBpZiAoKHBGb250ID09IDApIHx8ICh0aGlzLmZvbnRUeXBlID09IEZvbnRNYW5hZ2VyLkZPTlRfVFlQRV9UMSkpeworICAgICAgICAgICAgcmV0dXJuIHRoaXMubmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0aGlzLmdldEZvbnROYW1lKCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgaW50IGdldE1pc3NpbmdHbHlwaENvZGUoKSB7CisgICAgICAgIHJldHVybiBnZXREZWZhdWx0R2x5cGgoKS5nZXRHbHlwaENvZGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgR2x5cGggZ2V0R2x5cGgoY2hhciBpbmRleCkgeworICAgICAgICBHbHlwaCByZXN1bHQgPSBudWxsOworCisgICAgICAgIE9iamVjdCBrZXkgPSBuZXcgSW50ZWdlcihpbmRleCk7CisgICAgICAgIGlmIChnbHlwaHMuY29udGFpbnNLZXkoa2V5KSkgeworICAgICAgICAgICAgcmVzdWx0ID0gKEdseXBoKSBnbHlwaHMuZ2V0KGtleSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAodGhpcy5hZGRHbHlwaChpbmRleCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAoR2x5cGgpIGdseXBocy5nZXQoa2V5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5nZXREZWZhdWx0R2x5cGgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIEdseXBoIGdldERlZmF1bHRHbHlwaCgpIHsKKyAgICAJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkRlZmF1bHRHbHlwaHMgbm90IGltcGxlbWVudGVkISIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc3Bvc2VzIG5hdGl2ZSBmb250IGhhbmRsZS4gSWYgdGhpcyBmb250IHBlZXIgd2FzIGNyZWF0ZWQgZnJvbSBJbnB1dFN0cmVhbSAKKyAgICAgKiB0ZW1wb3JhcnkgY3JlYXRlZCBmb250IHJlc291cmNlIGZpbGUgaXMgZGVsZXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCl7CisgICAgICAgIFN0cmluZyB0ZW1wRGlyTmFtZTsKKyAgICAgICAgaWYgKHBGb250ICE9IDApeworICAgICAgICAgICAgcEZvbnQgPSAwOworCisgICAgICAgICAgICBpZiAoaXNDcmVhdGVkRnJvbVN0cmVhbSgpKSB7CisgICAgICAgICAgICAgICAgRmlsZSBmb250RmlsZSA9IG5ldyBGaWxlKGdldFRlbXBGb250RmlsZU5hbWUoKSk7CisgICAgICAgICAgICAgICAgdGVtcERpck5hbWUgPSBmb250RmlsZS5nZXRQYXJlbnQoKTsKKyAgICAgICAgICAgICAgICBmb250RmlsZS5kZWxldGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBnbHlwaCB0byBjYWNoZWQgR2x5cGggb2JqZWN0cyBpbiB0aGlzIExpbnV4Rm9udCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIHVDaGFyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyCisgICAgICogQHJldHVybiB0cnVlIGlmIGdseXBoIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGV4aXN0cyBpbiB0aGlzCisgICAgICogTGludXhGb250IG9yIHRoaXMgY2hhcmFjdGVyIGlzIGVzY2FwZSBzZXF1ZW5jZSBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkR2x5cGgoY2hhciB1Q2hhcikgeworICAgIAl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOyAgICAJCisgICAgfQorCisgICAvKioKKyAgICAqIEFkZHMgcmFuZ2Ugb2YgZXhpc3RpbmcgZ2x5cGhzIHRvIHRoaXMgTGludXhGb250IG9iamVjdAorICAgICogCisgICAgKiBAcGFyYW0gdUZpcnN0IHRoZSBsb3dlc3QgcmFuZ2UncyBib3VuZCwgaW5jbHVzaXZlIAorICAgICogQHBhcmFtIHVMYXN0IHRoZSBoaWdoZXN0IHJhbmdlJ3MgYm91bmQsIGV4Y2x1c2l2ZQorICAgICovCisgICAgcHVibGljIHZvaWQgYWRkR2x5cGhzKGNoYXIgdUZpcnN0LCBjaGFyIHVMYXN0KSB7CisgICAgCQorICAgICAgICBjaGFyIGluZGV4ID0gdUZpcnN0OworICAgICAgICBpZiAodUxhc3QgPCB1Rmlyc3QpIHsKKyAgICAgICAgICAgIC8vIGF3dC4wOT1taW4gcmFuZ2UgYm91bmQgdmFsdWUgaXMgZ3JhdGVyIHRoYW4gbWF4IHJhbmdlIGJvdW5kCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjA5IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKGluZGV4IDwgdUxhc3QpIHsKKyAgICAgICAgICAgIGFkZEdseXBoKGluZGV4KTsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHNwZWNpZmllZCBjaGFyYWN0ZXIgaGFzIGNvcnJlc29wbmRpbmcgZ2x5cGgsIGZhbHNlIG90aGVyd2lzZS4gIAorICAgICAqIAorICAgICAqIEBwYXJhbSB1SW5kZXggc3BlY2lmaWVkIGNoYXIKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dseXBoRXhpc3RzKGNoYXIgdUluZGV4KSB7CisgICAgCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJEZWZhdWx0R2x5cGhzIG5vdCBpbXBsZW1lbnRlZCEiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAgUmV0dXJucyBhbiBhcnJheSBvZiB1bmljb2RlIHJhbmdlcyB0aGF0IGFyZSBzdXBwb3J0ZWQgYnkgdGhpcyBMaW51eEZvbnQuIAorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRVbmljb2RlUmFuZ2VzKCkgeworICAgICAgICBpbnRbXSByYW5nZXMgPSBuZXcgaW50W2ZvbnRVbmljb2RlUmFuZ2VzLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZm9udFVuaWNvZGVSYW5nZXMsIDAsIHJhbmdlcywgMCwKKyAgICAgICAgICAgICAgICBmb250VW5pY29kZVJhbmdlcy5sZW5ndGgpOworCisgICAgICAgIHJldHVybiByYW5nZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIEZvbnQgb2JqZWN0IGlmIGl0IHdhcyBzdWNjZXNzZnVsbHkgZW1iZWRkZWQgaW4gU3lzdGVtCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGb250IGVtYmVkRm9udChTdHJpbmcgYWJzb2x1dGVQYXRoKXsKKyAgICAJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImVtYmVkRm9udCBub3QgaW1wbGVtZW50ZWQhIik7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGb250TmFtZSgpeworICAgICAgICBpZiAoKHBGb250ICE9IDApICYmIChmYWNlTmFtZSA9PSBudWxsKSl7CisgICAgICAgICAgICBpZiAodGhpcy5mb250VHlwZSA9PSBGb250TWFuYWdlci5GT05UX1RZUEVfVDEpeworICAgICAgICAgICAgICAgIGZhY2VOYW1lID0gZ2V0RmFtaWx5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhY2VOYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmFtaWx5KCkgeworICAgICAgICByZXR1cm4gZm9udEZhbWlseU5hbWU7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgaW5pdGlhdGVkIEZvbnRFeHRyYU1ldHJpY3MgaW5zdGFuY2Ugb2YgdGhpcyBXaW5kb3dzRm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9udEV4dHJhTWV0cmljcyBnZXRFeHRyYU1ldHJpY3MoKXsKKyAgICAJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRGb250TWFuYWdlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkRm9udE1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNjNhMjU2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkRm9udE1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDI3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QucGVlci5Gb250UGVlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkZvbnRNYW5hZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250UHJvcGVydHk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworCitwdWJsaWMgY2xhc3MgQW5kcm9pZEZvbnRNYW5hZ2VyIGV4dGVuZHMgRm9udE1hbmFnZXIgeworCisgICAgLy8gc2V0IG9mIGFsbCBhdmFpbGFibGUgZmFjZXMgc3VwcG9ydGVkIGJ5IGEgc3lzdGVtCisgICAgU3RyaW5nIGZhY2VzW107CisKKyAgICAvLyB3ZWlnaHQgbmFtZXMgYWNjb3JkaW5nIHRvIHhsZmQgc3RydWN0dXJlCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBMSU5VWF9XRUlHSFRfTkFNRVMgPSB7CisgICAgICAgICAgICAiYmxhY2siLCAiYm9sZCIsICJkZW1pYm9sZCIsICJtZWRpdW0iLCAibGlnaHQiIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQgLy8kTk9OLU5MUy01JAorICAgIH07CisKKyAgICAvLyBzbGFudCBuYW1lcyBhY2NvcmRpbmcgdG8geGxmZCBzdHJ1Y3R1cmUKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIExJTlVYX1NMQU5UX05BTUVTID0geworICAgICAgICAgICAgImkiLCAibyIsICJyIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH07CisKKyAgICAvKiogU2luZ2xldG9uIEFuZHJvaWRGb250TWFuYWdlciBpbnN0YW5jZSAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQW5kcm9pZEZvbnRNYW5hZ2VyIGluc3QgPSBuZXcgQW5kcm9pZEZvbnRNYW5hZ2VyKCk7CisKKyAgICBwcml2YXRlIEFuZHJvaWRGb250TWFuYWdlcigpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgZmFjZXMgPSBuZXcgU3RyaW5nW10gey8qIlBMQUlOIiwqLyAiTk9STUFMIiwgIkJPTEQiLCAiSVRBTElDIiwgIkJPTERJVEFMSUMifTsKKyAgICAgICAgaW5pdEZvbnRQcm9wZXJ0aWVzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdExDSURUYWJsZSgpeworICAgIAl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGVtcG9yYXJ5IEZpbGUgb2JqZWN0IHRvIHN0b3JlIGRhdGEgZnJvbSBJbnB1dFN0cmVhbS4KKyAgICAgKiBUaGlzIEZpbGUgb2JqZWN0IHNhdmVkIHRvIGB+Ly5mb250cy8nIGZvbGRlciB0aGF0IGlzIGluY2x1ZGVkIGluIHRoZSAKKyAgICAgKiBsaXN0IG9mIGZvbGRlcnMgc2VhcmNoZWQgZm9yIGZvbnQgZmlsZXMsIGFuZCB0aGlzIGlzIHdoZXJlIHVzZXItc3BlY2lmaWMgCisgICAgICogZm9udCBmaWxlcyBzaG91bGQgYmUgaW5zdGFsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldFRlbXBGb250RmlsZSgpdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgICBGaWxlIGZvbnRGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiakZvbnQiLCAiLnR0ZiIsIG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIikgKyIvLmZvbnRzIikpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkCisgICAgICAgIGZvbnRGaWxlLmRlbGV0ZU9uRXhpdCgpOworCisgICAgICAgIHJldHVybiBmb250RmlsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyBmUHJvcGVydGllcyBhcnJheSBmaWVsZCBmb3IgdGhlIGN1cnJlbnQgc3lzdGVtIGNvbmZpZ3VyYXRpb24gZm9udAorICAgICAqIHByb3BlcnR5IGZpbGUuCisgICAgICogCisgICAgICogUnVudGltZUV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgZm9udCBwcm9wZXJ0eSBjb250YWlucyBpbmNvcnJlY3QgZm9ybWF0IG9mIAorICAgICAqIHhsZmQgc3RyaW5nLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdHJ1ZSBpcyBzdWNjZXNzLCBmYWxzZSBpZiBmb250IHByb3BlcnR5IGRvZXNuJ3QgZXhpc3Qgb3IgZG9lc24ndAorICAgICAqIGNvbnRhaW4gcm9wZXJ0aWVzLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbml0Rm9udFByb3BlcnRpZXMoKXsKKyAgICAgICAgRmlsZSBmcEZpbGUgPSBnZXRGb250UHJvcGVydHlGaWxlKCk7CisgICAgICAgIGlmIChmcEZpbGUgPT0gbnVsbCl7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gZ2V0UHJvcGVydGllcyhmcEZpbGUpOworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCl7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpPTA7IGkgPCBMT0dJQ0FMX0ZPTlRfTkFNRVMubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgU3RyaW5nIGxOYW1lID0gTE9HSUNBTF9GT05UX05BTUVTW2ldOworICAgICAgICAgICAgZm9yIChpbnQgaj0wOyBqIDwgU1RZTEVfTkFNRVMubGVuZ3RoOyBqKyspeworICAgICAgICAgICAgICAgIFN0cmluZyBzdHlsZU5hbWUgPSBTVFlMRV9OQU1FU1tqXTsKKyAgICAgICAgICAgICAgICBWZWN0b3IgcHJvcHNWZWN0b3IgPSBuZXcgVmVjdG9yKCk7CisKKyAgICAgICAgICAgICAgICAvLyBOdW1iZXIgb2YgZW50cmllcyBmb3IgYSBsb2dpY2FsIGZvbnQKKyAgICAgICAgICAgICAgICBpbnQgbnVtQ29tcCA9IDA7CisgICAgICAgICAgICAgICAgLy8gSXMgbW9yZSBlbnRyaWVzIGZvciB0aGlzIHN0eWxlIGFuZCBsb2dpY2FsIGZvbnQgbmFtZSBsZWZ0CisgICAgICAgICAgICAgICAgYm9vbGVhbiBtb3JlRW50cmllcyA9IHRydWU7CisgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gbnVsbDsKKworICAgICAgICAgICAgICAgIHdoaWxlKG1vcmVFbnRyaWVzKXsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ29tcG9uZW50IEZvbnQgTWFwcGluZ3MgcHJvcGVydHkgbmFtZQorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJvcGVydHkgPSBGT05UX01BUFBJTkdfS0VZU1swXS5yZXBsYWNlQWxsKCJMb2dpY2FsRm9udE5hbWUiLCBsTmFtZSkucmVwbGFjZUFsbCgiU3R5bGVOYW1lIiwgc3R5bGVOYW1lKS5yZXBsYWNlQWxsKCJDb21wb25lbnRJbmRleCIsIFN0cmluZy52YWx1ZU9mKG51bUNvbXApKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKKyAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXRQcm9wZXJ0eShwcm9wZXJ0eSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIFN0eWxlTmFtZSBpcyBvbWl0dGVkLCBpdCdzIGFzc3VtZWQgdG8gYmUgcGxhaW4KKyAgICAgICAgICAgICAgICAgICAgaWYgKChqID09IDApICYmICh2YWx1ZSA9PSBudWxsKSl7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IEZPTlRfTUFQUElOR19LRVlTWzFdLnJlcGxhY2VBbGwoIkxvZ2ljYWxGb250TmFtZSIsIGxOYW1lKS5yZXBsYWNlQWxsKCJDb21wb25lbnRJbmRleCIsIFN0cmluZy52YWx1ZU9mKG51bUNvbXApKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHByb3BzLmdldFByb3BlcnR5KHByb3BlcnR5KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIGZpZWxkcyA9IHBhcnNlWExGRCh2YWx1ZSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZHMgPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjA4PXhmbGQgcGFyc2Ugc3RyaW5nIGVycm9yOiB7MH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4wOCIsIHZhbHVlKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZvbnROYW1lID0gZmllbGRzWzFdOworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHdlaWdodCA9IGZpZWxkc1syXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBpdGFsaWMgPSBmaWVsZHNbM107CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHlsZSA9IGdldEJvbGRTdHlsZSh3ZWlnaHQpIHwgZ2V0SXRhbGljU3R5bGUoaXRhbGljKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXBvbmVudCBGb250IENoYXJhY3RlciBFbmNvZGluZ3MgcHJvcGVydHkgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IHByb3BzLmdldFByb3BlcnR5KEZPTlRfQ0hBUkFDVEVSX0VOQ09ESU5HLnJlcGxhY2VBbGwoIkxvZ2ljYWxGb250TmFtZSIsIGxOYW1lKS5yZXBsYWNlQWxsKCJDb21wb25lbnRJbmRleCIsIFN0cmluZy52YWx1ZU9mKG51bUNvbXApKSk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeGNsdXNpb24gUmFuZ2VzIHByb3BlcnR5IHZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZXhjbFN0cmluZyA9IHByb3BzLmdldFByb3BlcnR5KEVYQ0xVU0lPTl9SQU5HRVMucmVwbGFjZUFsbCgiTG9naWNhbEZvbnROYW1lIiwgbE5hbWUpLnJlcGxhY2VBbGwoIkNvbXBvbmVudEluZGV4IiwgU3RyaW5nLnZhbHVlT2YobnVtQ29tcCkpKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXSBleGNsUmFuZ2UgPSBwYXJzZUludGVydmFscyhleGNsU3RyaW5nKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgRm9udFByb3BlcnR5IGZwID0gbmV3IEFuZHJvaWRGb250UHJvcGVydHkobE5hbWUsIHN0eWxlTmFtZSwgbnVsbCwgZm9udE5hbWUsIHZhbHVlLCBzdHlsZSwgZXhjbFJhbmdlLCBlbmNvZGluZyk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzVmVjdG9yLmFkZChmcCk7CisgICAgICAgICAgICAgICAgICAgICAgICBudW1Db21wKys7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtb3JlRW50cmllcyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChMT0dJQ0FMX0ZPTlRfTkFNRVNbaV0gKyAiLiIgKyBqLCBwcm9wc1ZlY3Rvcik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdHlsZSBhY2NvcmRpbmcgdG8gdGhlIHhsZmQgd2VpZ2h0IHN0cmluZy4KKyAgICAgKiBJZiB3ZWlnaHQgc3RyaW5nIGlzIGluY29ycmVjdCByZXR1cm5lZCB2YWx1ZSBpcyBGb250LlBMQUlOCisgICAgICogCisgICAgICogQHBhcmFtIHN0ciB3ZWlnaHQgbmFtZSBTdHJpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRCb2xkU3R5bGUoU3RyaW5nIHN0cil7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTElOVVhfV0VJR0hUX05BTUVTLmxlbmd0aDtpKyspeworICAgICAgICAgICAgaWYgKHN0ci5lcXVhbHNJZ25vcmVDYXNlKExJTlVYX1dFSUdIVF9OQU1FU1tpXSkpeworICAgICAgICAgICAgICAgIHJldHVybiAoaSA8IDMpID8gRm9udC5CT0xEIDogRm9udC5QTEFJTjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRm9udC5QTEFJTjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdHlsZSBhY2NvcmRpbmcgdG8gdGhlIHhsZmQgc2xhbnQgc3RyaW5nLgorICAgICAqIElmIHNsYW50IHN0cmluZyBpcyBpbmNvcnJlY3QgcmV0dXJuZWQgdmFsdWUgaXMgRm9udC5QTEFJTgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIgc2xhbnQgbmFtZSBTdHJpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRJdGFsaWNTdHlsZShTdHJpbmcgc3RyKXsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMSU5VWF9TTEFOVF9OQU1FUy5sZW5ndGg7aSsrKXsKKyAgICAgICAgICAgIGlmIChzdHIuZXF1YWxzSWdub3JlQ2FzZShMSU5VWF9TTEFOVF9OQU1FU1tpXSkpeworICAgICAgICAgICAgICAgIHJldHVybiAoaSA8IDIpID8gRm9udC5JVEFMSUMgOiBGb250LlBMQUlOOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBGb250LlBMQUlOOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHhsZmQgc3RyaW5nIGFuZCByZXR1cm5zIGFycmF5IG9mIFN0cmluZ3Mgd2l0aCBzZXBhcmF0ZSB4bGZkIAorICAgICAqIGVsZW1lbnRzLjxwPgorICAgICAqIAorICAgICAqIHhsZmQgZm9ybWF0OgorICAgICAqICAgICAgLUZvdW5kcnktRmFtaWx5LVdlaWdodC1TbGFudC1XaWR0aC1TdHlsZS1QaXhlbFNpemUtUG9pbnRTaXplLVJlc1gtUmVzWS1TcGFjaW5nLUF2Z1dpZHRoLVJlZ2lzdHJ5LUVuY29kaW5nCisgICAgICogQHBhcmFtIHhsZmQgU3RyaW5nIHBhcmFtZXRlciBpbiB4bGZkIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gcGFyc2VYTEZEKFN0cmluZyB4bGZkKXsKKyAgICAgICAgaW50IGZpZWxkc0NvdW50ID0gMTQ7CisgICAgICAgIFN0cmluZyBmaWVsZHNEZWxpbSA9ICItIjsgLy8kTk9OLU5MUy0xJAorICAgICAgICBTdHJpbmdbXSByZXMgPSBuZXcgU3RyaW5nW2ZpZWxkc0NvdW50XTsKKyAgICAgICAgaWYgKCF4bGZkLnN0YXJ0c1dpdGgoZmllbGRzRGVsaW0pKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgeGxmZCA9IHhsZmQuc3Vic3RyaW5nKDEpOworICAgICAgICBpbnQgaT0wOworICAgICAgICBpbnQgcG9zOworICAgICAgICBmb3IgKGk9MDsgaSA8IGZpZWxkc0NvdW50LTE7IGkrKyl7CisgICAgICAgICAgICBwb3MgPSB4bGZkLmluZGV4T2YoZmllbGRzRGVsaW0pOworICAgICAgICAgICAgaWYgKHBvcyAhPSAtMSl7CisgICAgICAgICAgICAgICAgcmVzW2ldID0geGxmZC5zdWJzdHJpbmcoMCwgcG9zKTsKKyAgICAgICAgICAgICAgICB4bGZkID0geGxmZC5zdWJzdHJpbmcocG9zICsgMSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHBvcyA9IHhsZmQuaW5kZXhPZihmaWVsZHNEZWxpbSk7CisKKyAgICAgICAgLy8gY2hlY2sgaWYgbm8gZmllbGRzIGxlZnQKKyAgICAgICAgaWYocG9zICE9IC0xKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJlc1tmaWVsZHNDb3VudC0xXSA9IHhsZmQ7CisKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEZhY2VJbmRleChTdHJpbmcgZmFjZU5hbWUpeworICAgIAkKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmYWNlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYoZmFjZXNbaV0uZXF1YWxzKGZhY2VOYW1lKSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRBbGxGYW1pbGllcygpeworICAgICAgICBpZiAoYWxsRmFtaWxpZXMgPT0gbnVsbCl7CisgICAgICAgIAlhbGxGYW1pbGllcyA9IG5ldyBTdHJpbmdbXXsic2Fucy1zZXJpZiIsICJzZXJpZiIsICJtb25vc3BhY2UifTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWxsRmFtaWxpZXM7CisgICAgfQorCisgICAgcHVibGljIEZvbnRbXSBnZXRBbGxGb250cygpeworICAgICAgICBGb250W10gZm9udHMgPSBuZXcgRm9udFtmYWNlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0wOyBpIDwgZm9udHMubGVuZ3RoO2krKyl7CisgICAgICAgICAgICBmb250c1tpXSA9IG5ldyBGb250KGZhY2VzW2ldLCBGb250LlBMQUlOLCAxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZm9udHM7CisgICAgfQorCisgICAgcHVibGljIEZvbnRQZWVyIGNyZWF0ZVBoeXNpY2FsRm9udFBlZXIoU3RyaW5nIG5hbWUsIGludCBzdHlsZSwgaW50IHNpemUpIHsKKyAgICAgICAgQW5kcm9pZEZvbnQgcGVlcjsKKyAgICAgICAgaW50IGZhbWlseUluZGV4ID0gZ2V0RmFtaWx5SW5kZXgobmFtZSk7CisgICAgICAgIGlmIChmYW1pbHlJbmRleCAhPSAtMSl7CisgICAgICAgICAgICAvLyAhISB3ZSB1c2UgZmFtaWx5IG5hbWVzIGZyb20gdGhlIGxpc3Qgd2l0aCBjYWNoZWQgZmFtaWxpZXMgYmVjYXVzZSAKKyAgICAgICAgICAgIC8vIHRoZXkgYXJlIGRpZmZlciBmcm9tIHRoZSBmYW1pbHkgbmFtZXMgaW4geGxmZCBzdHJ1Y3R1cmUsIGluIHhsZmQgCisgICAgICAgICAgICAvLyBmYW1pbHkgbmFtZXMgbW9zdGx5IGluIGxvd2VyIGNhc2UuCisgICAgICAgICAgICBwZWVyID0gbmV3IEFuZHJvaWRGb250KGdldEZhbWlseShmYW1pbHlJbmRleCksIHN0eWxlLCBzaXplKTsKKyAgICAgICAgICAgIHBlZXIuc2V0RmFtaWx5KGdldEZhbWlseShmYW1pbHlJbmRleCkpOworICAgICAgICAgICAgcmV0dXJuIHBlZXI7CisgICAgICAgIH0KKyAgICAgICAgaW50IGZhY2VJbmRleCA9IGdldEZhY2VJbmRleChuYW1lKTsgCisgICAgICAgIGlmIChmYWNlSW5kZXggIT0gLTEpeworCisgICAgICAgICAgICBwZWVyID0gbmV3IEFuZHJvaWRGb250KG5hbWUsIHN0eWxlLCBzaXplKTsKKyAgICAgICAgICAgIHJldHVybiBwZWVyOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRm9udFBlZXIgY3JlYXRlRGVmYXVsdEZvbnQoaW50IHN0eWxlLCBpbnQgc2l6ZSkgeworICAgIAlMb2cuaSgiREVGQVVMVCBGT05UIiwgSW50ZWdlci50b1N0cmluZyhzdHlsZSkpOworICAgICAgICByZXR1cm4gbmV3IEFuZHJvaWRGb250KERFRkFVTFRfTkFNRSwgc3R5bGUsIHNpemUpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkRm9udFByb3BlcnR5LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRGb250UHJvcGVydHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wY2ZkYzQzCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkRm9udFByb3BlcnR5LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKKy8qKgorICogQW5kcm9pZCBGb250UHJvcGVydHkgaW1wbGVtZW50YXRpb24sIGFwcGxpY2FibGUgZm9yIExpbnV4IGZvcm1hdHMgb2YgCisgKiBmb250IHByb3BlcnR5IGZpbGVzLiAKKyAqLworcHVibGljIGNsYXNzIEFuZHJvaWRGb250UHJvcGVydHkgZXh0ZW5kcyBGb250UHJvcGVydHkgeworICAgIAorICAgIC8qKiB4bGZkIHN0cmluZyB0aGF0IGlzIGFwcGxpY2FibGUgZm9yIExpbnV4IGZvbnQucHJvcGVydGllcyAqLyAKKyAgICBTdHJpbmcgeGxmZDsKKworICAgIC8qKiBsb2dpY2FsIG5hbWUgb2YgdGhlIGZvbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIEZvbnRQcm9wZXJ0eSAqLyAKKyAgICBTdHJpbmcgbG9naWNhbE5hbWU7CisgICAgCisgICAgLyoqIHN0eWxlIG5hbWUgb2YgdGhlIGZvbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIEZvbnRQcm9wZXJ0eSAqLworICAgIFN0cmluZyBzdHlsZU5hbWU7CisKKyAgICBwdWJsaWMgQW5kcm9pZEZvbnRQcm9wZXJ0eShTdHJpbmcgX2xvZ2ljYWxOYW1lLCBTdHJpbmcgX3N0eWxlTmFtZSwgU3RyaW5nIF9maWxlTmFtZSwgU3RyaW5nIF9uYW1lLCBTdHJpbmcgX3hsZmQsIGludCBfc3R5bGUsIGludFtdIGV4Y2x1c2lvblJhbmdlLCBTdHJpbmcgX2VuY29kaW5nKXsKKyAgICAgICAgdGhpcy5sb2dpY2FsTmFtZSA9IF9sb2dpY2FsTmFtZTsKKyAgICAgICAgdGhpcy5zdHlsZU5hbWUgPSBfc3R5bGVOYW1lOworICAgICAgICB0aGlzLm5hbWUgPSBfbmFtZTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IF9lbmNvZGluZzsKKyAgICAgICAgdGhpcy5leGNsUmFuZ2UgPSBleGNsdXNpb25SYW5nZTsKKyAgICAgICAgdGhpcy5maWxlTmFtZSA9IF9maWxlTmFtZTsKKyAgICAgICAgdGhpcy54bGZkID0gX3hsZmQ7CisgICAgICAgIHRoaXMuc3R5bGUgPSBfc3R5bGU7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgbG9naWNhbCBuYW1lIG9mIHRoZSBmb250IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBGb250UHJvcGVydHkuIAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9naWNhbE5hbWUoKXsKKyAgICAgICAgcmV0dXJuIGxvZ2ljYWxOYW1lOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHN0eWxlIG5hbWUgb2YgdGhlIGZvbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIEZvbnRQcm9wZXJ0eS4gCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTdHlsZU5hbWUoKXsKKyAgICAgICAgcmV0dXJuIHN0eWxlTmFtZTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyB4bGZkIHN0cmluZyBvZiB0aGlzIEZvbnRQcm9wZXJ0eS4gCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRYTEZEKCl7CisgICAgICAgIHJldHVybiB4bGZkOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcodGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArCisgICAgICAgICAgICAgICAgIltuYW1lPSIgKyBuYW1lICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIsZmlsZU5hbWU9IisgZmlsZU5hbWUgKyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgIixDaGFyc2V0PSIgKyBlbmNvZGluZyArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAiLGV4Y2xSYW5nZT0iICsgZXhjbFJhbmdlICsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICIseGxmZD0iICsgeGxmZCArICJdIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRHbHlwaFZlY3Rvci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkR2x5cGhWZWN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Y2U1YWVkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9BbmRyb2lkR2x5cGhWZWN0b3IuamF2YQpAQCAtMCwwICsxLDIxOSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3QuQW5kcm9pZEdyYXBoaWNzMkQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEuYXd0LmZvbnQuRm9udFJlbmRlckNvbnRleHQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC5HbHlwaEp1c3RpZmljYXRpb25JbmZvOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhNZXRyaWNzOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhWZWN0b3I7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CisKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUGF0aDsKKworcHVibGljIGNsYXNzIEFuZHJvaWRHbHlwaFZlY3RvciBleHRlbmRzIEdseXBoVmVjdG9yIHsKKworICAgIC8vIGFycmF5IG9mIGNoYXJzIGRlZmluZWQgaW4gY29uc3RydWN0b3IKKyAgICBwdWJsaWMgY2hhcltdIGNoYXJWZWN0b3I7CisKKyAgICAvLyBhcnJheSBvZiBHbHlwaCBvYmplY3RzLCB0aGF0IGRlc2NyaWJlIGluZm9ybWF0aW9uIGFib3V0IGdseXBocworICAgIHB1YmxpYyBHbHlwaFtdIHZlY3RvcjsKKworICAgIC8vIGFycmF5IG9mIGRlZmF1bHQgcG9zaXRpb25zIG9mIGdseXBocyBpbiBHbHlwaFZlY3RvcgorICAgIC8vIHdpdGhvdXQgYXBwbHlpbmcgR2x5cGhWZWN0b3IncyB0cmFuc2Zvcm0KKyAgICBmbG9hdFtdIGRlZmF1bHRQb3NpdGlvbnM7CisKKyAgICAvLyBhcnJheSBvZiBsb2dpY2FsIHBvc2l0aW9ucyBvZiBnbHlwaHMgaW4gR2x5cGhWZWN0b3IKKworICAgIGZsb2F0W10gbG9naWNhbFBvc2l0aW9uczsKKworICAgIC8vIGFycmF5IG9mIHZpc3VhbCAocmVhbCkgcG9zaXRpb25zIG9mIGdseXBocyBpbiBHbHlwaFZlY3RvcgorICAgIHB1YmxpYyBmbG9hdFtdIHZpc3VhbFBvc2l0aW9uczsKKworICAgIC8vIEZvbnRSZW5kZXJDb250ZXh0IGZvciB0aGlzIHZlY3Rvci4KKyAgICBwcm90ZWN0ZWQgRm9udFJlbmRlckNvbnRleHQgdmVjdG9yRlJDOworCisgICAgLy8gbGF5b3V0IGZsYWdzIG1hc2sKKyAgICBwcm90ZWN0ZWQgaW50IGxheW91dEZsYWdzID0gMDsKKworICAgIC8vIGFycmF5IG9mIGNhY2hlZCBnbHlwaCBvdXRsaW5lcyAKKyAgICBwcm90ZWN0ZWQgU2hhcGVbXSBndlNoYXBlczsKKworICAgIEZvbnRQZWVySW1wbCBwZWVyOworCisgICAgLy8gZm9udCBjb3JyZXNwb25kaW5nIHRvIHRoZSBHbHlwaFZlY3RvciAKKyAgICBGb250IGZvbnQ7CisKKyAgICAvLyBhc2NlbnQgb2YgdGhlIGZvbnQKKyAgICBmbG9hdCBhc2NlbnQ7CisKKyAgICAvLyBoZWlnaHQgb2YgdGhlIGZvbnQKKyAgICBmbG9hdCBoZWlnaHQ7CisgICAgCisgICAgLy8gbGVhZGluZyBvZiB0aGUgZm9udAorICAgIGZsb2F0IGxlYWRpbmc7CisgICAgCisgICAgLy8gZGVzY2VudCBvZiB0aGUgZm9udAorICAgIGZsb2F0IGRlc2NlbnQ7CisKKyAgICAvLyB0cmFuc2Zvcm0gb2YgdGhlIEdseXBoVmVjdG9yCisgICAgQWZmaW5lVHJhbnNmb3JtIHRyYW5zZm9ybTsKKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIEFuZHJvaWRHbHlwaFZlY3RvcihjaGFyW10gY2hhcnMsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgRm9udCBmbnQsCisgICAgICAgICAgICBpbnQgZmxhZ3MpIHsKKyAgICAgICAgaW50IGxlbiA9IGNoYXJzLmxlbmd0aDsKKyAgICAgICAgdGhpcy5mb250ID0gZm50OworICAgICAgICBMaW5lTWV0cmljc0ltcGwgbG1JbXBsID0gKExpbmVNZXRyaWNzSW1wbClmbnQuZ2V0TGluZU1ldHJpY3MoU3RyaW5nLnZhbHVlT2YoY2hhcnMpLCBmcmMpOyAgICAgCQorICAgICAgICB0aGlzLmFzY2VudCA9IGxtSW1wbC5nZXRBc2NlbnQoKTsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBsbUltcGwuZ2V0SGVpZ2h0KCk7CisgICAgICAgIHRoaXMubGVhZGluZyA9IGxtSW1wbC5nZXRMZWFkaW5nKCk7CisgICAgICAgIHRoaXMuZGVzY2VudCA9IGxtSW1wbC5nZXREZXNjZW50KCk7CisgICAgICAgIHRoaXMuY2hhclZlY3RvciA9IGNoYXJzOworICAgICAgICB0aGlzLnZlY3RvckZSQyA9IGZyYzsKKyAgICB9CisKKyAgICBwdWJsaWMgQW5kcm9pZEdseXBoVmVjdG9yKGNoYXJbXSBjaGFycywgRm9udFJlbmRlckNvbnRleHQgZnJjLCBGb250IGZudCkgeworICAgICAgICB0aGlzKGNoYXJzLCBmcmMsIGZudCwgMCk7CisgICAgfQorCisgICAgcHVibGljIEFuZHJvaWRHbHlwaFZlY3RvcihTdHJpbmcgc3RyLCBGb250UmVuZGVyQ29udGV4dCBmcmMsIEZvbnQgZm50KSB7CisgICAgICAgIHRoaXMoc3RyLnRvQ2hhckFycmF5KCksIGZyYywgZm50LCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQW5kcm9pZEdseXBoVmVjdG9yKFN0cmluZyBzdHIsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgRm9udCBmbnQsIGludCBmbGFncykgeworICAgICAgICB0aGlzKHN0ci50b0NoYXJBcnJheSgpLCBmcmMsIGZudCwgZmxhZ3MpOworICAgIH0KKworCUBPdmVycmlkZQorCXB1YmxpYyBib29sZWFuIGVxdWFscyhHbHlwaFZlY3RvciBnbHlwaFZlY3RvcikgeworCQlyZXR1cm4gZmFsc2U7CisJfQorCisJcHVibGljIGNoYXJbXSBnZXRHbHlwaHMoKSB7CisJCXJldHVybiB0aGlzLmNoYXJWZWN0b3I7CisJfQorCQorCUBPdmVycmlkZQorCXB1YmxpYyBGb250IGdldEZvbnQoKSB7CisJCXJldHVybiB0aGlzLmZvbnQ7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIEZvbnRSZW5kZXJDb250ZXh0IGdldEZvbnRSZW5kZXJDb250ZXh0KCkgeworCQlyZXR1cm4gdGhpcy52ZWN0b3JGUkM7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIGludCBnZXRHbHlwaENvZGUoaW50IGdseXBoSW5kZXgpIHsKKwkJcmV0dXJuIGNoYXJWZWN0b3JbZ2x5cGhJbmRleF07CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIGludFtdIGdldEdseXBoQ29kZXMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsCisJCQlpbnRbXSBjb2RlUmV0dXJuKSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mbyhpbnQgZ2x5cGhJbmRleCkgeworCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyBTaGFwZSBnZXRHbHlwaExvZ2ljYWxCb3VuZHMoaW50IGdseXBoSW5kZXgpIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgR2x5cGhNZXRyaWNzIGdldEdseXBoTWV0cmljcyhpbnQgZ2x5cGhJbmRleCkgeworCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworCX0KKworCXB1YmxpYyBQYXRoIGdldEFuZHJvaWRHbHlwaE91dGxpbmUoaW50IGdseXBoSW5kZXgpIHsKKwkJQW5kcm9pZEdyYXBoaWNzMkQgZyA9IEFuZHJvaWRHcmFwaGljczJELmdldEluc3RhbmNlKCk7CisgICAgICAgIFBhdGggcGF0aCA9IG5ldyBQYXRoKCk7CisgICAgICAgIGNoYXIgdG1wW10gPSBuZXcgY2hhclsxXTsKKyAgICAgICAgdG1wWzBdID0gY2hhclZlY3RvcltnbHlwaEluZGV4XTsKKyAgICAgICAgKChBbmRyb2lkR3JhcGhpY3MyRClnKS5nZXRBbmRyb2lkUGFpbnQoKS5nZXRUZXh0UGF0aChuZXcgU3RyaW5nKHRtcCksIDAsIDEsIDAsIDAsIHBhdGgpOworICAgICAgICByZXR1cm4gcGF0aDsKKwl9CisJCisJQE92ZXJyaWRlCisJcHVibGljIFNoYXBlIGdldEdseXBoT3V0bGluZShpbnQgZ2x5cGhJbmRleCkgeworCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyBQb2ludDJEIGdldEdseXBoUG9zaXRpb24oaW50IGdseXBoSW5kZXgpIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgZmxvYXRbXSBnZXRHbHlwaFBvc2l0aW9ucyhpbnQgYmVnaW5HbHlwaEluZGV4LCBpbnQgbnVtRW50cmllcywKKwkJCWZsb2F0W10gcG9zaXRpb25SZXR1cm4pIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldEdseXBoVHJhbnNmb3JtKGludCBnbHlwaEluZGV4KSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIFNoYXBlIGdldEdseXBoVmlzdWFsQm91bmRzKGludCBnbHlwaEluZGV4KSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIFJlY3RhbmdsZTJEIGdldExvZ2ljYWxCb3VuZHMoKSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIGludCBnZXROdW1HbHlwaHMoKSB7CisJCXJldHVybiBjaGFyVmVjdG9yLmxlbmd0aDsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgU2hhcGUgZ2V0T3V0bGluZShmbG9hdCB4LCBmbG9hdCB5KSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIFNoYXBlIGdldE91dGxpbmUoKSB7CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQhIik7CisJfQorCisJcHVibGljIFBhdGggZ2V0QW5kcm9pZE91dGxpbmUoKSB7CisJCUFuZHJvaWRHcmFwaGljczJEIGcgPSBBbmRyb2lkR3JhcGhpY3MyRC5nZXRJbnN0YW5jZSgpOworICAgICAgICBQYXRoIHBhdGggPSBuZXcgUGF0aCgpOworICAgICAgICAoKEFuZHJvaWRHcmFwaGljczJEKWcpLmdldEFuZHJvaWRQYWludCgpLmdldFRleHRQYXRoKG5ldyBTdHJpbmcoY2hhclZlY3RvciksIDAsIGNoYXJWZWN0b3IubGVuZ3RoLCAwLCAwLCBwYXRoKTsKKyAgICAgICAgcmV0dXJuIHBhdGg7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIFJlY3RhbmdsZTJEIGdldFZpc3VhbEJvdW5kcygpIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBwZXJmb3JtRGVmYXVsdExheW91dCgpIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBzZXRHbHlwaFBvc2l0aW9uKGludCBnbHlwaEluZGV4LCBQb2ludDJEIG5ld1BvcykgeworCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkISIpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHNldEdseXBoVHJhbnNmb3JtKGludCBnbHlwaEluZGV4LCBBZmZpbmVUcmFuc2Zvcm0gdHJhbnMpIHsKKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCEiKTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvQW5kcm9pZExpbmVNZXRyaWNzLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRMaW5lTWV0cmljcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzN2JlNmQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0FuZHJvaWRMaW5lTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250OworCitpbXBvcnQgamF2YS5hd3QuZm9udC5Gb250UmVuZGVyQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQuTGluZU1ldHJpY3NJbXBsOworCisKKy8qKgorICoKKyAqIExpbnV4IGltcGxlbWVudGF0aW9uIG9mIExpbmVNZXRyaWNzIGNsYXNzCisgKi8KK3B1YmxpYyBjbGFzcyBBbmRyb2lkTGluZU1ldHJpY3MgZXh0ZW5kcyBMaW5lTWV0cmljc0ltcGwgeworICAgIAorICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICovCisgICAgcHVibGljIEFuZHJvaWRMaW5lTWV0cmljcyggICAgQW5kcm9pZEZvbnQgZm50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb250UmVuZGVyQ29udGV4dCBmcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzdHIpeworICAgICAgICBudW1DaGFycyA9IHN0ci5sZW5ndGgoKTsKKyAgICAgICAgYmFzZUxpbmVJbmRleCA9IDA7CisKKyAgICAgICAgYXNjZW50ID0gZm50LmFzY2VudDsgICAgLy8gQXNjZW50IG9mIHRoZSBmb250CisgICAgICAgIGRlc2NlbnQgPSAtZm50LmRlc2NlbnQ7ICAvLyBEZXNjZW50IG9mIHRoZSBmb250CisgICAgICAgIGxlYWRpbmcgPSBmbnQubGVhZGluZzsgIC8vIEV4dGVybmFsIGxlYWRpbmcKKworICAgICAgICBoZWlnaHQgPSBhc2NlbnQgKyBkZXNjZW50ICsgbGVhZGluZzsgICAgLy8gSGVpZ2h0IG9mIHRoZSBmb250ICggPT0gKGFzY2VudCArIGRlc2NlbnQgKyBsZWFkaW5nKSkKKyAgICAgICAgdW5kZXJsaW5lVGhpY2tuZXNzID0gMC4wZjsKKyAgICAgICAgdW5kZXJsaW5lT2Zmc2V0ID0gMC4wZjsKKyAgICAgICAgc3RyaWtldGhyb3VnaFRoaWNrbmVzcyA9IDAuMGY7CisgICAgICAgIHN0cmlrZXRocm91Z2hPZmZzZXQgPSAwLjBmOworICAgICAgICBtYXhDaGFyV2lkdGggPSAwLjBmOworCisgICAgICAgIC8vICAgIFRPRE86IEZpbmQgb3V0IHBpeGVsIG1ldHJpY3MKKyAgICAgICAgLyoKKyAgICAgICAgICogcG9zaXRpdmUgbWV0cmljcyByb3VuZGVkIHRvIHRoZSBzbWFsbGVzdCBpbnQgdGhhdCBpcyBiaWdnZXIgdGhhbiB2YWx1ZQorICAgICAgICAgKiBuZWdhdGl2ZSBtZXRyaWNzIHJvdW5kZWQgdG8gdGhlIHNtYWxsZXN0IGludCB0aGF0IGlzIGxlc3NlciB0aGFuIHZhbHVlCisgICAgICAgICAqIHRoaWNrbmVzc2VzIHJvdW5kZWQgdG8gaW50ICgoaW50KXJvdW5kKHZhbHVlICsgMC41KSkKKyAgICAgICAgICoKKyAgICAgICAgICovCisKKyAgICAgICAgbEFzY2VudCA9IChpbnQpTWF0aC5jZWlsKGZudC5hc2NlbnQpOy8vICAgLy8gQXNjZW50IG9mIHRoZSBmb250CisgICAgICAgIGxEZXNjZW50ID0gLShpbnQpTWF0aC5jZWlsKGZudC5kZXNjZW50KTsvLyBEZXNjZW50IG9mIHRoZSBmb250CisgICAgICAgIGxMZWFkaW5nID0gKGludClNYXRoLmNlaWwobGVhZGluZyk7ICAvLyBFeHRlcm5hbCBsZWFkaW5nCisKKyAgICAgICAgbEhlaWdodCA9IGxBc2NlbnQgKyBsRGVzY2VudCArIGxMZWFkaW5nOyAgICAvLyBIZWlnaHQgb2YgdGhlIGZvbnQgKCA9PSAoYXNjZW50ICsgZGVzY2VudCArIGxlYWRpbmcpKQorCisgICAgICAgIGxVbmRlcmxpbmVUaGlja25lc3MgPSBNYXRoLnJvdW5kKHVuZGVybGluZVRoaWNrbmVzcyk7Ly8oaW50KW1ldHJpY3NbMTFdOworCisgICAgICAgIGlmICh1bmRlcmxpbmVPZmZzZXQgPj0gMCl7CisgICAgICAgICAgICBsVW5kZXJsaW5lT2Zmc2V0ID0gKGludClNYXRoLmNlaWwodW5kZXJsaW5lT2Zmc2V0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxVbmRlcmxpbmVPZmZzZXQgPSAoaW50KU1hdGguZmxvb3IodW5kZXJsaW5lT2Zmc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIGxTdHJpa2V0aHJvdWdoVGhpY2tuZXNzID0gTWF0aC5yb3VuZChzdHJpa2V0aHJvdWdoVGhpY2tuZXNzKTsgLy8oaW50KW1ldHJpY3NbMTNdOworCisgICAgICAgIGlmIChzdHJpa2V0aHJvdWdoT2Zmc2V0ID49IDApeworICAgICAgICAgICAgbFN0cmlrZXRocm91Z2hPZmZzZXQgPSAoaW50KU1hdGguY2VpbChzdHJpa2V0aHJvdWdoT2Zmc2V0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxTdHJpa2V0aHJvdWdoT2Zmc2V0ID0gKGludClNYXRoLmZsb29yKHN0cmlrZXRocm91Z2hPZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgbE1heENoYXJXaWR0aCA9IChpbnQpTWF0aC5jZWlsKG1heENoYXJXaWR0aCk7IC8vKGludCltZXRyaWNzWzE1XTsKKyAgICAgICAgdW5pdHNfcGVyX0VNID0gMDsKKworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdFtdIGdldEJhc2VsaW5lT2Zmc2V0cygpIHsKKyAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGJhc2VsaW5lIG9mZnNldHMgZm9yIFRydWVUeXBlIGZvbnRzCisgICAgICAgIGlmIChiYXNlbGluZU9mZnNldHMgPT0gbnVsbCl7CisgICAgICAgICAgICBmbG9hdFtdIGJhc2VsaW5lRGF0YSA9IG51bGw7CisKKyAgICAgICAgICAgIC8vIFRlbXBvcmFyeSB3b3JrYXJvdW5kOgorICAgICAgICAgICAgLy8gQ29tbWVudGVkIG91dCBuYXRpdmUgZGF0YSBpbml0aWFsaXphdGlvbiwgc2luY2UgaXQgY2FuIAorICAgICAgICAgICAgLy8gY2F1c2UgZmFpbHVyZXMgd2l0aCBvcGVuaW5nIGZpbGVzIGluIG11bHRpdGhyZWFkZWQgYXBwbGljYXRpb25zLgorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIFRPRE86IHN1cHBvcnQgd29yayB3aXRoIHRydWV0eXBlIGRhdGEgaW4gbXVsdGl0aHJlYWRlZAorICAgICAgICAgICAgLy8gYXBwbGljYXRpb25zLgorCisgICAgICAgICAgICAvLyBJZiBmb250IFRydWVUeXBlIGRhdGEgaXMgdGFrZW4gZnJvbSBCQVNFIHRhYmxlCisvLyAgICAgICAgICAgIGlmICgodGhpcy5mb250LmdldEZvbnRIYW5kbGUoKSAhPSAwKSAmJiAoZm9udC5nZXRGb250VHlwZSgpID09IEZvbnRNYW5hZ2VyLkZPTlRfVFlQRV9UVCkpeworLy8gICAgICAgICAgICAgICAgYmFzZWxpbmVEYXRhID0gTGludXhOYXRpdmVGb250LmdldEJhc2VsaW5lT2Zmc2V0c05hdGl2ZShmb250LmdldEZvbnRIYW5kbGUoKSwgZm9udC5nZXRTaXplKCksIGFzY2VudCwgZGVzY2VudCwgdW5pdHNfcGVyX0VNKTsKKy8vICAgICAgICAgICAgfQorLy8KKyAgICAgICAgICAgICAgICBiYXNlTGluZUluZGV4ID0gMDsKKyAgICAgICAgICAgICAgICBiYXNlbGluZU9mZnNldHMgPSBuZXcgZmxvYXRbXXswLCAoLWFzY2VudCtkZXNjZW50KS8yLCAtYXNjZW50fTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBiYXNlbGluZU9mZnNldHM7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRCYXNlbGluZUluZGV4KCkgeworICAgICAgICBpZiAoYmFzZWxpbmVPZmZzZXRzID09IG51bGwpeworICAgICAgICAgICAgLy8gZ2V0IG9mZnNldHMgYW5kIHNldCBjb3JyZWN0IGluZGV4CisgICAgICAgICAgICBnZXRCYXNlbGluZU9mZnNldHMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYmFzZUxpbmVJbmRleDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvQmFzaWNNZXRyaWNzLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0Jhc2ljTWV0cmljcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwZmIzOTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0Jhc2ljTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsMTM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LkxpbmVNZXRyaWNzOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR3JhcGhpY0F0dHJpYnV0ZTsKK2ltcG9ydCBqYXZhLmF3dC4qOworCisvKioKKyAqIERhdGU6IE1heSAxNCwgMjAwNQorICogVGltZTogNzo0NDoxMyBQTQorICoKKyAqIFRoaXMgY2xhc3MgaW5jYXBzdWxhdGVzIHRleHQgbWV0cmljcyBzcGVjaWZpYyBmb3IgdGhlIHRleHQgbGF5b3V0IG9yCisgKiBmb3IgdGhlIHNlcGFyYXRlIHRleHQgc2VnbWVudC4gVGV4dCBzZWdtZW50IGlzIGEgdGV4dCBydW4gd2l0aCB0aGUgY29uc3RhbnQgZGlyZWN0aW9uCisgKiBhbmQgYXR0cmlidXRlcyBsaWtlIGZvbnQsIGRlY29yYXRpb25zLCBldGMuIEJhc2ljTWV0cmljcyBpcyBhbHNvIHVzZWQgdG8gc3RvcmUKKyAqIGNhbGN1bGF0ZWQgdGV4dCBtZXRyaWNzIGxpa2UgYWR2YW5jZSwgYXNjZW50IG9yIGRlc2NlbnQuIHRoaXMgY2xhc3MgaXMgdmVyeSBzaW1pbGFyIHRvCisgKiBMaW5lTWV0cmljcywgYnV0IHByb3ZpZGVzIHNvbWUgYWRkaXRpb25hbCBpbmZvLCBjb25zdHJ1Y3RvcnMgYW5kIGlzIG1vcmUgdHJhbnNwYXJlbnQuCisgKi8KK3B1YmxpYyBjbGFzcyBCYXNpY01ldHJpY3MgeworICAgIGludCBiYXNlTGluZUluZGV4OworCisgICAgZmxvYXQgYXNjZW50OyAgIC8vIEFzY2VudCBvZiB0aGUgZm9udAorICAgIGZsb2F0IGRlc2NlbnQ7ICAvLyBEZXNjZW50IG9mIHRoZSBmb250CisgICAgZmxvYXQgbGVhZGluZzsgIC8vIEV4dGVybmFsIGxlYWRpbmcKKyAgICBmbG9hdCBhZHZhbmNlOworCisgICAgZmxvYXQgaXRhbGljQW5nbGU7CisgICAgZmxvYXQgc3VwZXJTY3JpcHRPZmZzZXQ7CisKKyAgICBmbG9hdCB1bmRlcmxpbmVPZmZzZXQ7CisgICAgZmxvYXQgdW5kZXJsaW5lVGhpY2tuZXNzOworCisgICAgZmxvYXQgc3RyaWtldGhyb3VnaE9mZnNldDsKKyAgICBmbG9hdCBzdHJpa2V0aHJvdWdoVGhpY2tuZXNzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBCYXNpY01ldHJpY3MgZnJvbSBMaW5lTWV0cmljcyBhbmQgZm9udAorICAgICAqIEBwYXJhbSBsbQorICAgICAqIEBwYXJhbSBmb250CisgICAgICovCisgICAgQmFzaWNNZXRyaWNzKExpbmVNZXRyaWNzIGxtLCBGb250IGZvbnQpIHsKKyAgICAgICAgYXNjZW50ID0gbG0uZ2V0QXNjZW50KCk7CisgICAgICAgIGRlc2NlbnQgPSBsbS5nZXREZXNjZW50KCk7CisgICAgICAgIGxlYWRpbmcgPSBsbS5nZXRMZWFkaW5nKCk7CisKKyAgICAgICAgdW5kZXJsaW5lT2Zmc2V0ID0gbG0uZ2V0VW5kZXJsaW5lT2Zmc2V0KCk7CisgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyA9IGxtLmdldFVuZGVybGluZVRoaWNrbmVzcygpOworCisgICAgICAgIHN0cmlrZXRocm91Z2hPZmZzZXQgPSBsbS5nZXRTdHJpa2V0aHJvdWdoT2Zmc2V0KCk7CisgICAgICAgIHN0cmlrZXRocm91Z2hUaGlja25lc3MgPSBsbS5nZXRTdHJpa2V0aHJvdWdoVGhpY2tuZXNzKCk7CisKKyAgICAgICAgYmFzZUxpbmVJbmRleCA9IGxtLmdldEJhc2VsaW5lSW5kZXgoKTsKKworICAgICAgICBpdGFsaWNBbmdsZSA9IGZvbnQuZ2V0SXRhbGljQW5nbGUoKTsKKyAgICAgICAgc3VwZXJTY3JpcHRPZmZzZXQgPSAoZmxvYXQpIGZvbnQuZ2V0VHJhbnNmb3JtKCkuZ2V0VHJhbnNsYXRlWSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgQmFzaWNNZXRyaWNzIGZyb20gR3JhcGhpY0F0dHJpYnV0ZS4KKyAgICAgKiBJdCBnZXRzIGFzY2VudCBhbmQgZGVzY2VudCBmcm9tIHRoZSBncmFwaGljIGF0dHJpYnV0ZSBhbmQKKyAgICAgKiBjb21wdXRlcyByZWFzb25hYmxlIGRlZmF1bHRzIGZvciBvdGhlciBtZXRyaWNzLgorICAgICAqIEBwYXJhbSBnYSAtIGdyYXBoaWMgYXR0cmlidXRlCisgICAgICovCisgICAgQmFzaWNNZXRyaWNzKEdyYXBoaWNBdHRyaWJ1dGUgZ2EpIHsKKyAgICAgICAgYXNjZW50ID0gZ2EuZ2V0QXNjZW50KCk7CisgICAgICAgIGRlc2NlbnQgPSBnYS5nZXREZXNjZW50KCk7CisgICAgICAgIGxlYWRpbmcgPSAyOworCisgICAgICAgIGJhc2VMaW5lSW5kZXggPSBnYS5nZXRBbGlnbm1lbnQoKTsKKworICAgICAgICBpdGFsaWNBbmdsZSA9IDA7CisgICAgICAgIHN1cGVyU2NyaXB0T2Zmc2V0ID0gMDsKKworICAgICAgICB1bmRlcmxpbmVPZmZzZXQgPSBNYXRoLm1heChkZXNjZW50LzIsIDEpOworCisgICAgICAgIC8vIEp1c3Qgc3VnZ2VzdGVkLCBzaG91bGQgYmUgY2FwX3N0ZW1fd2lkdGggb3Igc29tZXRoaW5nIGxpa2UgdGhhdAorICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgPSBNYXRoLm1heChhc2NlbnQvMTMsIDEpOworCisgICAgICAgIHN0cmlrZXRocm91Z2hPZmZzZXQgPSAtYXNjZW50LzI7IC8vIFNvbWV0aGluZyBsaWtlIG1pZGRsZSBvZiB0aGUgbGluZQorICAgICAgICBzdHJpa2V0aHJvdWdoVGhpY2tuZXNzID0gdW5kZXJsaW5lVGhpY2tuZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBtZXRyaWNzIGZyb20gdGhlIFRleHRNZXRyaWNzQ2FsY3VsYXRvciBvYmplY3QuCisgICAgICogQHBhcmFtIHRtYyAtIFRleHRNZXRyaWNzQ2FsY3VsYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBCYXNpY01ldHJpY3MoVGV4dE1ldHJpY3NDYWxjdWxhdG9yIHRtYykgeworICAgICAgICBhc2NlbnQgPSB0bWMuYXNjZW50OworICAgICAgICBkZXNjZW50ID0gdG1jLmRlc2NlbnQ7CisgICAgICAgIGxlYWRpbmcgPSB0bWMubGVhZGluZzsKKyAgICAgICAgYWR2YW5jZSA9IHRtYy5hZHZhbmNlOworICAgICAgICBiYXNlTGluZUluZGV4ID0gdG1jLmJhc2VsaW5lSW5kZXg7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldEFzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIGFzY2VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RGVzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NlbnQ7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldExlYWRpbmcoKSB7CisgICAgICAgIHJldHVybiBsZWFkaW5nOworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdCBnZXRBZHZhbmNlKCkgeworICAgICAgICByZXR1cm4gYWR2YW5jZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEJhc2VMaW5lSW5kZXgoKSB7CisgICAgICAgIHJldHVybiBiYXNlTGluZUluZGV4OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvQ2FyZXRNYW5hZ2VyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0NhcmV0TWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxOGJkZDUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0NhcmV0TWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsNTMwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogSnVuIDE0LCAyMDA1CisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LlRleHRIaXRJbmZvOworaW1wb3J0IGphdmEuYXd0LmZvbnQuVGV4dExheW91dDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uR2VuZXJhbFBhdGg7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5MaW5lMkQ7CitpbXBvcnQgamF2YS5hd3QuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3IgY3JlYXRpbmcgY2FyZXQgYW5kIGhpZ2hsaWdodCBzaGFwZXMKKyAqIChiaWRpcmVjdGlvbmFsIHRleHQgaXMgYWxzbyBzdXBwb3J0ZWQsIGJ1dCwgdW5mb3J0dW5hdGVseSwgbm90IHRlc3RlZCB5ZXQpLgorICovCitwdWJsaWMgY2xhc3MgQ2FyZXRNYW5hZ2VyIHsKKyAgICBwcml2YXRlIFRleHRSdW5CcmVha2VyIGJyZWFrZXI7CisKKyAgICBwdWJsaWMgQ2FyZXRNYW5hZ2VyKFRleHRSdW5CcmVha2VyIGJyZWFrZXIpIHsKKyAgICAgICAgdGhpcy5icmVha2VyID0gYnJlYWtlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgVGV4dEhpdEluZm8gaXMgbm90IG91dCBvZiB0aGUgdGV4dCByYW5nZSBhbmQgdGhyb3dzIHRoZQorICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBpdCBpcy4KKyAgICAgKiBAcGFyYW0gaW5mbyAtIHRleHQgaGl0IGluZm8KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tIaXQoVGV4dEhpdEluZm8gaW5mbykgeworICAgICAgICBpbnQgaWR4ID0gaW5mby5nZXRJbnNlcnRpb25JbmRleCgpOworCisgICAgICAgIGlmIChpZHggPCAwIHx8IGlkeCA+IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Mj1UZXh0SGl0SW5mbyBvdXQgb2YgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdmlzdWFsIHBvc2l0aW9uIGZyb20gdGhlIHRleHQgaGl0IGluZm8uCisgICAgICogQHBhcmFtIGhpdEluZm8gLSB0ZXh0IGhpdCBpbmZvCisgICAgICogQHJldHVybiB2aXN1YWwgaW5kZXgKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRWaXN1YWxGcm9tSGl0SW5mbyhUZXh0SGl0SW5mbyBoaXRJbmZvKSB7CisgICAgICAgIGZpbmFsIGludCBpZHggPSBoaXRJbmZvLmdldENoYXJJbmRleCgpOworCisgICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPCBicmVha2VyLmdldENoYXJDb3VudCgpKSB7CisgICAgICAgICAgICBpbnQgdmlzdWFsID0gYnJlYWtlci5nZXRWaXN1YWxGcm9tTG9naWNhbChpZHgpOworICAgICAgICAgICAgLy8gV2UgdGFrZSBuZXh0IGNoYXJhY3RlciBmb3IgKExUUiBjaGFyICsgVFJBSUxJTkcgaW5mbykgYW5kIChSVEwgKyBMRUFESU5HKQorICAgICAgICAgICAgaWYgKGhpdEluZm8uaXNMZWFkaW5nRWRnZSgpIF4gKChicmVha2VyLmdldExldmVsKGlkeCkgJiAweDEpID09IDB4MCkpIHsKKyAgICAgICAgICAgICAgICB2aXN1YWwrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB2aXN1YWw7CisgICAgICAgIH0gZWxzZSBpZiAoaWR4IDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIGJyZWFrZXIuaXNMVFIoKSA/IDA6IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gYnJlYWtlci5pc0xUUigpID8gYnJlYWtlci5nZXRDaGFyQ291bnQoKSA6IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHRleHQgaGl0IGluZm8gZnJvbSB0aGUgdmlzdWFsIHBvc2l0aW9uCisgICAgICogQHBhcmFtIHZpc3VhbCAtIHZpc3VhbCBwb3NpdGlvbgorICAgICAqIEByZXR1cm4gdGV4dCBoaXQgaW5mbworICAgICAqLworICAgIHByaXZhdGUgVGV4dEhpdEluZm8gZ2V0SGl0SW5mb0Zyb21WaXN1YWwoaW50IHZpc3VhbCkgeworICAgICAgICBmaW5hbCBib29sZWFuIGZpcnN0ID0gdmlzdWFsID09IDA7CisKKyAgICAgICAgaWYgKCEoZmlyc3QgfHwgdmlzdWFsID09IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpKSB7CisgICAgICAgICAgICBpbnQgbG9naWNhbCA9IGJyZWFrZXIuZ2V0TG9naWNhbEZyb21WaXN1YWwodmlzdWFsKTsKKyAgICAgICAgICAgIHJldHVybiAoYnJlYWtlci5nZXRMZXZlbChsb2dpY2FsKSAmIDB4MSkgPT0gMHgwID8KKyAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8ubGVhZGluZyhsb2dpY2FsKSA6IC8vIExUUgorICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mby50cmFpbGluZyhsb2dpY2FsKTsgLy8gUlRMCisgICAgICAgIH0gZWxzZSBpZiAoZmlyc3QpIHsKKyAgICAgICAgICAgIHJldHVybiBicmVha2VyLmlzTFRSKCkgPworICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mby50cmFpbGluZygtMSkgOgorICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mby5sZWFkaW5nKGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpOworICAgICAgICB9IGVsc2UgeyAvLyBMYXN0CisgICAgICAgICAgICByZXR1cm4gYnJlYWtlci5pc0xUUigpID8KKyAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8ubGVhZGluZyhicmVha2VyLmdldENoYXJDb3VudCgpKSA6CisgICAgICAgICAgICAgICAgICAgIFRleHRIaXRJbmZvLnRyYWlsaW5nKC0xKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgY2FyZXQgaW5mby4gUmVxdWlyZWQgZm9yIHRoZSBnZXRDYXJldEluZm8KKyAgICAgKiBtZXRob2RzIG9mIHRoZSBUZXh0TGF5b3V0CisgICAgICogQHBhcmFtIGhpdEluZm8gLSBzcGVjaWZpZXMgY2FyZXQgcG9zaXRpb24KKyAgICAgKiBAcmV0dXJuIGNhcmV0IGluZm8sIHNlZSBUZXh0TGF5b3V0LmdldENhcmV0SW5mbyBkb2N1bWVudGF0aW9uCisgICAgICovCisgICAgcHVibGljIGZsb2F0W10gZ2V0Q2FyZXRJbmZvKFRleHRIaXRJbmZvIGhpdEluZm8pIHsKKyAgICAgICAgY2hlY2tIaXQoaGl0SW5mbyk7CisgICAgICAgIGZsb2F0IHJlc1tdID0gbmV3IGZsb2F0WzJdOworCisgICAgICAgIGludCB2aXN1YWwgPSBnZXRWaXN1YWxGcm9tSGl0SW5mbyhoaXRJbmZvKTsKKyAgICAgICAgZmxvYXQgYWR2YW5jZSwgYW5nbGU7CisgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZzsKKworICAgICAgICBpZiAodmlzdWFsIDwgYnJlYWtlci5nZXRDaGFyQ291bnQoKSkgeworICAgICAgICAgICAgaW50IGxvZ0lkeCA9IGJyZWFrZXIuZ2V0TG9naWNhbEZyb21WaXN1YWwodmlzdWFsKTsKKyAgICAgICAgICAgIGludCBzZWdtZW50SWR4ID0gYnJlYWtlci5sb2dpY2FsMnNlZ21lbnRbbG9nSWR4XTsKKyAgICAgICAgICAgIHNlZyA9IGJyZWFrZXIucnVuU2VnbWVudHMuZ2V0KHNlZ21lbnRJZHgpOworICAgICAgICAgICAgYWR2YW5jZSA9IHNlZy54ICsgc2VnLmdldEFkdmFuY2VEZWx0YShzZWcuZ2V0U3RhcnQoKSwgbG9nSWR4KTsKKyAgICAgICAgICAgIGFuZ2xlID0gc2VnLm1ldHJpY3MuaXRhbGljQW5nbGU7CisKKyAgICAgICAgfSBlbHNlIHsgLy8gTGFzdCBjaGFyYWN0ZXIKKyAgICAgICAgICAgIGludCBsb2dJZHggPSBicmVha2VyLmdldExvZ2ljYWxGcm9tVmlzdWFsKHZpc3VhbC0xKTsKKyAgICAgICAgICAgIGludCBzZWdtZW50SWR4ID0gYnJlYWtlci5sb2dpY2FsMnNlZ21lbnRbbG9nSWR4XTsKKyAgICAgICAgICAgIHNlZyA9IGJyZWFrZXIucnVuU2VnbWVudHMuZ2V0KHNlZ21lbnRJZHgpOworICAgICAgICAgICAgYWR2YW5jZSA9IHNlZy54ICsgc2VnLmdldEFkdmFuY2VEZWx0YShzZWcuZ2V0U3RhcnQoKSwgbG9nSWR4KzEpOworICAgICAgICB9CisKKyAgICAgICAgYW5nbGUgPSBzZWcubWV0cmljcy5pdGFsaWNBbmdsZTsKKworICAgICAgICByZXNbMF0gPSBhZHZhbmNlOworICAgICAgICByZXNbMV0gPSBhbmdsZTsKKworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgcG9zaXRpb24gdG8gdGhlIHJpZ2h0IGZyb20gdGhlIGN1cnJlbnQgY2FyZXQgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0gaGl0SW5mbyAtIGN1cnJlbnQgcG9zaXRpb24KKyAgICAgKiBAcmV0dXJuIG5leHQgcG9zaXRpb24gdG8gdGhlIHJpZ2h0CisgICAgICovCisgICAgcHVibGljIFRleHRIaXRJbmZvIGdldE5leHRSaWdodEhpdChUZXh0SGl0SW5mbyBoaXRJbmZvKSB7CisgICAgICAgIGNoZWNrSGl0KGhpdEluZm8pOworICAgICAgICBpbnQgdmlzdWFsID0gZ2V0VmlzdWFsRnJvbUhpdEluZm8oaGl0SW5mbyk7CisKKyAgICAgICAgaWYgKHZpc3VhbCA9PSBicmVha2VyLmdldENoYXJDb3VudCgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFRleHRIaXRJbmZvIG5ld0luZm87CisKKyAgICAgICAgd2hpbGUodmlzdWFsIDw9IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpIHsKKyAgICAgICAgICAgIHZpc3VhbCsrOworICAgICAgICAgICAgbmV3SW5mbyA9IGdldEhpdEluZm9Gcm9tVmlzdWFsKHZpc3VhbCk7CisKKyAgICAgICAgICAgIGlmIChuZXdJbmZvLmdldENoYXJJbmRleCgpID49IGJyZWFrZXIubG9naWNhbDJzZWdtZW50Lmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbmZvOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGl0SW5mby5nZXRDaGFySW5kZXgoKSA+PSAwKSB7IC8vIERvbid0IGNoZWNrIGZvciBsZWZ0bW9zdCBpbmZvCisgICAgICAgICAgICAgICAgaWYgKAorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtlci5sb2dpY2FsMnNlZ21lbnRbbmV3SW5mby5nZXRDaGFySW5kZXgoKV0gIT0KKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrZXIubG9naWNhbDJzZWdtZW50W2hpdEluZm8uZ2V0Q2hhckluZGV4KCldCisgICAgICAgICAgICAgICAgKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbmZvOyAvLyBXZSBjcm9zc2VkIHNlZ21lbnQgYm91bmRhcnkKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZyA9IGJyZWFrZXIucnVuU2VnbWVudHMuZ2V0KGJyZWFrZXIubG9naWNhbDJzZWdtZW50W25ld0luZm8KKyAgICAgICAgICAgICAgICAgICAgLmdldENoYXJJbmRleCgpXSk7CisgICAgICAgICAgICBpZiAoIXNlZy5jaGFySGFzWmVyb0FkdmFuY2UobmV3SW5mby5nZXRDaGFySW5kZXgoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5mbzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgcG9zaXRpb24gdG8gdGhlIGxlZnQgZnJvbSB0aGUgY3VycmVudCBjYXJldCBwb3NpdGlvbgorICAgICAqIEBwYXJhbSBoaXRJbmZvIC0gY3VycmVudCBwb3NpdGlvbgorICAgICAqIEByZXR1cm4gbmV4dCBwb3NpdGlvbiB0byB0aGUgbGVmdAorICAgICAqLworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXROZXh0TGVmdEhpdChUZXh0SGl0SW5mbyBoaXRJbmZvKSB7CisgICAgICAgIGNoZWNrSGl0KGhpdEluZm8pOworICAgICAgICBpbnQgdmlzdWFsID0gZ2V0VmlzdWFsRnJvbUhpdEluZm8oaGl0SW5mbyk7CisKKyAgICAgICAgaWYgKHZpc3VhbCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFRleHRIaXRJbmZvIG5ld0luZm87CisKKyAgICAgICAgd2hpbGUodmlzdWFsID49IDApIHsKKyAgICAgICAgICAgIHZpc3VhbC0tOworICAgICAgICAgICAgbmV3SW5mbyA9IGdldEhpdEluZm9Gcm9tVmlzdWFsKHZpc3VhbCk7CisKKyAgICAgICAgICAgIGlmIChuZXdJbmZvLmdldENoYXJJbmRleCgpIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbmZvOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBEb24ndCBjaGVjayBmb3IgcmlnaHRtb3N0IGluZm8KKyAgICAgICAgICAgIGlmIChoaXRJbmZvLmdldENoYXJJbmRleCgpIDwgYnJlYWtlci5sb2dpY2FsMnNlZ21lbnQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgaWYgKAorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtlci5sb2dpY2FsMnNlZ21lbnRbbmV3SW5mby5nZXRDaGFySW5kZXgoKV0gIT0KKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrZXIubG9naWNhbDJzZWdtZW50W2hpdEluZm8uZ2V0Q2hhckluZGV4KCldCisgICAgICAgICAgICAgICAgKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbmZvOyAvLyBXZSBjcm9zc2VkIHNlZ21lbnQgYm91bmRhcnkKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZyA9IGJyZWFrZXIucnVuU2VnbWVudHMuZ2V0KGJyZWFrZXIubG9naWNhbDJzZWdtZW50W25ld0luZm8KKyAgICAgICAgICAgICAgICAgICAgLmdldENoYXJJbmRleCgpXSk7CisgICAgICAgICAgICBpZiAoIXNlZy5jaGFySGFzWmVyb0FkdmFuY2UobmV3SW5mby5nZXRDaGFySW5kZXgoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5mbzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvciBlYWNoIHZpc3VhbCBjYXJldCBwb3NpdGlvbiB0aGVyZSBhcmUgdHdvIGhpdHMuIEZvciB0aGUgc2ltcGxlIExUUiB0ZXh0IG9uZSBpcworICAgICAqIGEgdHJhaWxpbmcgb2YgdGhlIHByZXZpb3VzIGNoYXIgYW5kIGFub3RoZXIgaXMgdGhlIGxlYWRpbmcgb2YgdGhlIG5leHQgY2hhci4gVGhpcworICAgICAqIG1ldGhvZCByZXR1cm5zIHRoZSBvcHBvc2l0ZSBoaXQgZm9yIHRoZSBnaXZlbiBoaXQuCisgICAgICogQHBhcmFtIGhpdEluZm8gLSBnaXZlbiBoaXQKKyAgICAgKiBAcmV0dXJuIG9wcG9zaXRlIGhpdAorICAgICAqLworICAgIHB1YmxpYyBUZXh0SGl0SW5mbyBnZXRWaXN1YWxPdGhlckhpdChUZXh0SGl0SW5mbyBoaXRJbmZvKSB7CisgICAgICAgIGNoZWNrSGl0KGhpdEluZm8pOworCisgICAgICAgIGludCBpZHggPSBoaXRJbmZvLmdldENoYXJJbmRleCgpOworCisgICAgICAgIGludCByZXNJZHg7CisgICAgICAgIGJvb2xlYW4gcmVzSXNMZWFkaW5nOworCisgICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPCBicmVha2VyLmdldENoYXJDb3VudCgpKSB7IC8vIEhpdCBpbmZvIGluIHRoZSBtaWRkbGUKKyAgICAgICAgICAgIGludCB2aXN1YWwgPSBicmVha2VyLmdldFZpc3VhbEZyb21Mb2dpY2FsKGlkeCk7CisKKyAgICAgICAgICAgIC8vIENoYXIgaXMgTFRSICsgTEVBRElORyBpbmZvCisgICAgICAgICAgICBpZiAoKChicmVha2VyLmdldExldmVsKGlkeCkgJiAweDEpID09IDB4MCkgXiBoaXRJbmZvLmlzTGVhZGluZ0VkZ2UoKSkgeworICAgICAgICAgICAgICAgIHZpc3VhbCsrOworICAgICAgICAgICAgICAgIGlmICh2aXN1YWwgPT0gYnJlYWtlci5nZXRDaGFyQ291bnQoKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoYnJlYWtlci5pc0xUUigpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXNJZHggPSBicmVha2VyLmdldENoYXJDb3VudCgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmVzSXNMZWFkaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lkeCA9IC0xOworICAgICAgICAgICAgICAgICAgICAgICAgcmVzSXNMZWFkaW5nID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXNJZHggPSBicmVha2VyLmdldExvZ2ljYWxGcm9tVmlzdWFsKHZpc3VhbCk7CisgICAgICAgICAgICAgICAgICAgIGlmICgoYnJlYWtlci5nZXRMZXZlbChyZXNJZHgpICYgMHgxKSA9PSAweDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lzTGVhZGluZyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXNJc0xlYWRpbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdmlzdWFsLS07CisgICAgICAgICAgICAgICAgaWYgKHZpc3VhbCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoYnJlYWtlci5pc0xUUigpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXNJZHggPSAtMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lzTGVhZGluZyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzSWR4ID0gYnJlYWtlci5nZXRDaGFyQ291bnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lzTGVhZGluZyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXNJZHggPSBicmVha2VyLmdldExvZ2ljYWxGcm9tVmlzdWFsKHZpc3VhbCk7CisgICAgICAgICAgICAgICAgICAgIGlmICgoYnJlYWtlci5nZXRMZXZlbChyZXNJZHgpICYgMHgxKSA9PSAweDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lzTGVhZGluZyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzSXNMZWFkaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChpZHggPCAwKSB7IC8vIGJlZm9yZSAic3RhcnQiCisgICAgICAgICAgICBpZiAoYnJlYWtlci5pc0xUUigpKSB7CisgICAgICAgICAgICAgICAgcmVzSWR4ID0gYnJlYWtlci5nZXRMb2dpY2FsRnJvbVZpc3VhbCgwKTsKKyAgICAgICAgICAgICAgICByZXNJc0xlYWRpbmcgPSAoYnJlYWtlci5nZXRMZXZlbChyZXNJZHgpICYgMHgxKSA9PSAweDA7IC8vIExUUiBjaGFyPworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXNJZHggPSBicmVha2VyLmdldExvZ2ljYWxGcm9tVmlzdWFsKGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkgLSAxKTsKKyAgICAgICAgICAgICAgICByZXNJc0xlYWRpbmcgPSAoYnJlYWtlci5nZXRMZXZlbChyZXNJZHgpICYgMHgxKSAhPSAweDA7IC8vIFJUTCBjaGFyPworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBpZHggPT0gYnJlYWtlci5nZXRDaGFyQ291bnQoKQorICAgICAgICAgICAgaWYgKGJyZWFrZXIuaXNMVFIoKSkgeworICAgICAgICAgICAgICAgIHJlc0lkeCA9IGJyZWFrZXIuZ2V0TG9naWNhbEZyb21WaXN1YWwoYnJlYWtlci5nZXRDaGFyQ291bnQoKSAtIDEpOworICAgICAgICAgICAgICAgIHJlc0lzTGVhZGluZyA9IChicmVha2VyLmdldExldmVsKHJlc0lkeCkgJiAweDEpICE9IDB4MDsgLy8gTFRSIGNoYXI/CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc0lkeCA9IGJyZWFrZXIuZ2V0TG9naWNhbEZyb21WaXN1YWwoMCk7CisgICAgICAgICAgICAgICAgcmVzSXNMZWFkaW5nID0gKGJyZWFrZXIuZ2V0TGV2ZWwocmVzSWR4KSAmIDB4MSkgPT0gMHgwOyAvLyBSVEwgY2hhcj8KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXNJc0xlYWRpbmcgPyBUZXh0SGl0SW5mby5sZWFkaW5nKHJlc0lkeCkgOiBUZXh0SGl0SW5mby50cmFpbGluZyhyZXNJZHgpOworICAgIH0KKworICAgIHB1YmxpYyBMaW5lMkQgZ2V0Q2FyZXRTaGFwZShUZXh0SGl0SW5mbyBoaXRJbmZvLCBUZXh0TGF5b3V0IGxheW91dCkgeworICAgICAgICByZXR1cm4gZ2V0Q2FyZXRTaGFwZShoaXRJbmZvLCBsYXlvdXQsIHRydWUsIGZhbHNlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgY2FyZXQgc2hhcGUuCisgICAgICogQHBhcmFtIGhpdEluZm8gLSBoaXQgd2hlcmUgdG8gcGxhY2UgYSBjYXJldAorICAgICAqIEBwYXJhbSBsYXlvdXQgLSB0ZXh0IGxheW91dAorICAgICAqIEBwYXJhbSB1c2VJdGFsaWMgLSB1bnVzZWQgZm9yIG5vdywgd2FzIHVzZWQgdG8gY3JlYXRlCisgICAgICogc2xhbnRlZCBjYXJldHMgZm9yIGl0YWxpYyB0ZXh0CisgICAgICogQHBhcmFtIHVzZUJvdW5kcyAtIHRydWUgaWYgdGhlIGNhcmVkIHNob3VsZCBmaXQgaW50byB0aGUgcHJvdmlkZWQgYm91bmRzCisgICAgICogQHBhcmFtIGJvdW5kcyAtIGJvdW5kcyBmb3IgdGhlIGNhcmV0CisgICAgICogQHJldHVybiBjYXJldCBzaGFwZQorICAgICAqLworICAgIHB1YmxpYyBMaW5lMkQgZ2V0Q2FyZXRTaGFwZSgKKyAgICAgICAgICAgIFRleHRIaXRJbmZvIGhpdEluZm8sIFRleHRMYXlvdXQgbGF5b3V0LAorICAgICAgICAgICAgYm9vbGVhbiB1c2VJdGFsaWMsIGJvb2xlYW4gdXNlQm91bmRzLCBSZWN0YW5nbGUyRCBib3VuZHMKKyAgICApIHsKKyAgICAgICAgY2hlY2tIaXQoaGl0SW5mbyk7CisKKyAgICAgICAgZmxvYXQgeDEsIHgyLCB5MSwgeTI7CisKKyAgICAgICAgaW50IGNoYXJJZHggPSBoaXRJbmZvLmdldENoYXJJbmRleCgpOworCisgICAgICAgIGlmIChjaGFySWR4ID49IDAgJiYgY2hhcklkeCA8IGJyZWFrZXIuZ2V0Q2hhckNvdW50KCkpIHsKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZ21lbnQgPSBicmVha2VyLnJ1blNlZ21lbnRzLmdldChicmVha2VyLmxvZ2ljYWwyc2VnbWVudFtjaGFySWR4XSk7CisgICAgICAgICAgICB5MSA9IHNlZ21lbnQubWV0cmljcy5kZXNjZW50OworICAgICAgICAgICAgeTIgPSAtIHNlZ21lbnQubWV0cmljcy5hc2NlbnQgLSBzZWdtZW50Lm1ldHJpY3MubGVhZGluZzsKKworICAgICAgICAgICAgeDEgPSB4MiA9IHNlZ21lbnQuZ2V0Q2hhclBvc2l0aW9uKGNoYXJJZHgpICsgKGhpdEluZm8uaXNMZWFkaW5nRWRnZSgpID8KKyAgICAgICAgICAgICAgICAgICAgMCA6IHNlZ21lbnQuZ2V0Q2hhckFkdmFuY2UoY2hhcklkeCkpOworICAgICAgICAgICAgLy8gRGVjaWRlZCB0aGF0IHN0cmFpZ2h0IGN1cnNvciBsb29rcyBiZXR0ZXIgZXZlbiBmb3IgaXRhbGljIGZvbnRzLAorICAgICAgICAgICAgLy8gZXNwZWNpYWxseSBjb21iaW5lZCB3aXRoIGhpZ2hsaWdodGluZworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgIC8vIE5vdCBncmFwaGljcywgbmVlZCB0byBjaGVjayBpdGFsaWMgYW5nbGUgYW5kIGJhc2VsaW5lCisgICAgICAgICAgICBpZiAobGF5b3V0LmdldEJhc2VsaW5lKCkgPj0gMCkgeworICAgICAgICAgICAgICAgIGlmIChzZWdtZW50Lm1ldHJpY3MuaXRhbGljQW5nbGUgIT0gMCAmJiB1c2VJdGFsaWMpIHsKKyAgICAgICAgICAgICAgICAgICAgeDEgLT0gc2VnbWVudC5tZXRyaWNzLml0YWxpY0FuZ2xlICogc2VnbWVudC5tZXRyaWNzLmRlc2NlbnQ7CisgICAgICAgICAgICAgICAgICAgIHgyICs9IHNlZ21lbnQubWV0cmljcy5pdGFsaWNBbmdsZSAqCisgICAgICAgICAgICAgICAgICAgICAgICAoc2VnbWVudC5tZXRyaWNzLmFzY2VudCArIHNlZ21lbnQubWV0cmljcy5sZWFkaW5nKTsKKworICAgICAgICAgICAgICAgICAgICBmbG9hdCBiYXNlbGluZU9mZnNldCA9CisgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXQuZ2V0QmFzZWxpbmVPZmZzZXRzKClbbGF5b3V0LmdldEJhc2VsaW5lKCldOworICAgICAgICAgICAgICAgICAgICB5MSArPSBiYXNlbGluZU9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgeTIgKz0gYmFzZWxpbmVPZmZzZXQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgKi8KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHkxID0gbGF5b3V0LmdldERlc2NlbnQoKTsKKyAgICAgICAgICAgIHkyID0gLSBsYXlvdXQuZ2V0QXNjZW50KCkgLSBsYXlvdXQuZ2V0TGVhZGluZygpOworICAgICAgICAgICAgeDEgPSB4MiA9ICgoYnJlYWtlci5nZXRCYXNlTGV2ZWwoKSAmIDB4MSkgPT0gMCBeIGNoYXJJZHggPCAwKSA/CisgICAgICAgICAgICAgICAgICAgIGxheW91dC5nZXRBZHZhbmNlKCkgOiAwOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHVzZUJvdW5kcykgeworICAgICAgICAgICAgeTEgPSAoZmxvYXQpIGJvdW5kcy5nZXRNYXhZKCk7CisgICAgICAgICAgICB5MiA9IChmbG9hdCkgYm91bmRzLmdldE1pblkoKTsKKworICAgICAgICAgICAgaWYgKHgyID4gYm91bmRzLmdldE1heFgoKSkgeworICAgICAgICAgICAgICAgIHgxID0geDIgPSAoZmxvYXQpIGJvdW5kcy5nZXRNYXhYKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoeDEgPCBib3VuZHMuZ2V0TWluWCgpKSB7CisgICAgICAgICAgICAgICAgeDEgPSB4MiA9IChmbG9hdCkgYm91bmRzLmdldE1pblgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgTGluZTJELkZsb2F0KHgxLCB5MSwgeDIsIHkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGNhcmV0IHNoYXBlcyBmb3IgdGhlIHNwZWNpZmllZCBvZmZzZXQuIE9uIHRoZSBib3VuZGFyaWVzIHdoZXJlCisgICAgICogdGhlIHRleHQgaXMgY2hhbmdpbmcgaXRzIGRpcmVjdGlvbiB0aGlzIG1ldGhvZCBtYXkgcmV0dXJuIHR3byBzaGFwZXMKKyAgICAgKiBmb3IgdGhlIHN0cm9uZyBhbmQgdGhlIHdlYWsgY2FyZXRzLCBpbiBvdGhlciBjYXNlcyBpdCB3b3VsZCByZXR1cm4gb25lLgorICAgICAqIEBwYXJhbSBvZmZzZXQgLSBvZmZzZXQgaW4gdGhlIHRleHQuCisgICAgICogQHBhcmFtIGJvdW5kcyAtIGJvdW5kcyB0byBmaXQgdGhlIGNhcmV0cyBpbnRvCisgICAgICogQHBhcmFtIHBvbGljeSAtIGNhcmV0IHBvbGljeQorICAgICAqIEBwYXJhbSBsYXlvdXQgLSB0ZXh0IGxheW91dAorICAgICAqIEByZXR1cm4gb25lIG9yIHR3byBjYXJldCBzaGFwZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGVbXSBnZXRDYXJldFNoYXBlcygKKyAgICAgICAgICAgIGludCBvZmZzZXQsIFJlY3RhbmdsZTJEIGJvdW5kcywKKyAgICAgICAgICAgIFRleHRMYXlvdXQuQ2FyZXRQb2xpY3kgcG9saWN5LCBUZXh0TGF5b3V0IGxheW91dAorICAgICkgeworICAgICAgICBUZXh0SGl0SW5mbyBoaXQxID0gVGV4dEhpdEluZm8uYWZ0ZXJPZmZzZXQob2Zmc2V0KTsKKyAgICAgICAgVGV4dEhpdEluZm8gaGl0MiA9IGdldFZpc3VhbE90aGVySGl0KGhpdDEpOworCisgICAgICAgIFNoYXBlIGNhcmV0MSA9IGdldENhcmV0U2hhcGUoaGl0MSwgbGF5b3V0KTsKKworICAgICAgICBpZiAoZ2V0VmlzdWFsRnJvbUhpdEluZm8oaGl0MSkgPT0gZ2V0VmlzdWFsRnJvbUhpdEluZm8oaGl0MikpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU2hhcGVbXSB7Y2FyZXQxLCBudWxsfTsKKyAgICAgICAgfQorICAgICAgICBTaGFwZSBjYXJldDIgPSBnZXRDYXJldFNoYXBlKGhpdDIsIGxheW91dCk7CisKKyAgICAgICAgVGV4dEhpdEluZm8gc3Ryb25nSGl0ID0gcG9saWN5LmdldFN0cm9uZ0NhcmV0KGhpdDEsIGhpdDIsIGxheW91dCk7CisgICAgICAgIHJldHVybiBzdHJvbmdIaXQuZXF1YWxzKGhpdDEpID8KKyAgICAgICAgICAgICAgICBuZXcgU2hhcGVbXSB7Y2FyZXQxLCBjYXJldDJ9IDoKKyAgICAgICAgICAgICAgICBuZXcgU2hhcGVbXSB7Y2FyZXQyLCBjYXJldDF9OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHR3byBjYXJldHMgdG8gcHJvZHVjZSBhIGhpZ2hsaWdodCBzaGFwZS4KKyAgICAgKiBAcGFyYW0gY2FyZXQxIC0gMXN0IGNhcmV0CisgICAgICogQHBhcmFtIGNhcmV0MiAtIDJuZCBjYXJldAorICAgICAqIEByZXR1cm4gaGlnaGxpZ2h0IHNoYXBlCisgICAgICovCisgICAgR2VuZXJhbFBhdGggY29ubmVjdENhcmV0cyhMaW5lMkQgY2FyZXQxLCBMaW5lMkQgY2FyZXQyKSB7CisgICAgICAgIEdlbmVyYWxQYXRoIHBhdGggPSBuZXcgR2VuZXJhbFBhdGgoR2VuZXJhbFBhdGguV0lORF9OT05fWkVSTyk7CisgICAgICAgIHBhdGgubW92ZVRvKChmbG9hdCkgY2FyZXQxLmdldFgxKCksIChmbG9hdCkgY2FyZXQxLmdldFkxKCkpOworICAgICAgICBwYXRoLmxpbmVUbygoZmxvYXQpIGNhcmV0Mi5nZXRYMSgpLCAoZmxvYXQpIGNhcmV0Mi5nZXRZMSgpKTsKKyAgICAgICAgcGF0aC5saW5lVG8oKGZsb2F0KSBjYXJldDIuZ2V0WDIoKSwgKGZsb2F0KSBjYXJldDIuZ2V0WTIoKSk7CisgICAgICAgIHBhdGgubGluZVRvKChmbG9hdCkgY2FyZXQxLmdldFgyKCksIChmbG9hdCkgY2FyZXQxLmdldFkyKCkpOworCisgICAgICAgIHBhdGguY2xvc2VQYXRoKCk7CisKKyAgICAgICAgcmV0dXJuIHBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGhpZ2hsaWdodCBzaGFwZSBmcm9tIGdpdmVuIHR3byBoaXRzLiBUaGlzIHNoYXBlCisgICAgICogd2lsbCBhbHdheXMgYmUgdmlzdWFsbHkgY29udGlndW91cworICAgICAqIEBwYXJhbSBoaXQxIC0gMXN0IGhpdAorICAgICAqIEBwYXJhbSBoaXQyIC0gMm5kIGhpdAorICAgICAqIEBwYXJhbSBib3VuZHMgLSBib3VuZHMgdG8gZml0IHRoZSBzaGFwZSBpbnRvCisgICAgICogQHBhcmFtIGxheW91dCAtIHRleHQgbGF5b3V0CisgICAgICogQHJldHVybiBoaWdobGlnaHQgc2hhcGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgZ2V0VmlzdWFsSGlnaGxpZ2h0U2hhcGUoCisgICAgICAgICAgICBUZXh0SGl0SW5mbyBoaXQxLCBUZXh0SGl0SW5mbyBoaXQyLAorICAgICAgICAgICAgUmVjdGFuZ2xlMkQgYm91bmRzLCBUZXh0TGF5b3V0IGxheW91dAorICAgICkgeworICAgICAgICBjaGVja0hpdChoaXQxKTsKKyAgICAgICAgY2hlY2tIaXQoaGl0Mik7CisKKyAgICAgICAgTGluZTJEIGNhcmV0MSA9IGdldENhcmV0U2hhcGUoaGl0MSwgbGF5b3V0LCBmYWxzZSwgdHJ1ZSwgYm91bmRzKTsKKyAgICAgICAgTGluZTJEIGNhcmV0MiA9IGdldENhcmV0U2hhcGUoaGl0MiwgbGF5b3V0LCBmYWxzZSwgdHJ1ZSwgYm91bmRzKTsKKworICAgICAgICByZXR1cm4gY29ubmVjdENhcmV0cyhjYXJldDEsIGNhcmV0Mik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3VwcG9zZSB0aGF0IHRoZSB1c2VyIHZpc3VhbGx5IHNlbGVjdGVkIGEgYmxvY2sgb2YgdGV4dCB3aGljaCBoYXMKKyAgICAgKiBzZXZlcmFsIGRpZmZlcmVudCBsZXZlbHMgKG1peGVkIFJUTCBhbmQgTFRSKSwgc28sIGluIHRoZSBsb2dpY2FsCisgICAgICogcmVwcmVzZW50YXRpb24gb2YgdGhlIHRleHQgdGhpcyBzZWxlY3Rpb24gbWF5IGJlIG5vdCBjb250aWdvdXMuCisgICAgICogVGhpcyBtZXRob2RzIHJldHVybnMgYSBzZXQgb2YgbG9naWNhbCByYW5nZXMgZm9yIHRoZSBhcmJpdHJhcnkKKyAgICAgKiB2aXN1YWwgc2VsZWN0aW9uIHJlcHJlc2VudGVkIGJ5IHR3byBoaXRzLgorICAgICAqIEBwYXJhbSBoaXQxIC0gMXN0IGhpdAorICAgICAqIEBwYXJhbSBoaXQyIC0gMm5kIGhpdAorICAgICAqIEByZXR1cm4gbG9naWNhbCByYW5nZXMgZm9yIHRoZSBzZWxlY3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0TG9naWNhbFJhbmdlc0ZvclZpc3VhbFNlbGVjdGlvbihUZXh0SGl0SW5mbyBoaXQxLCBUZXh0SGl0SW5mbyBoaXQyKSB7CisgICAgICAgIGNoZWNrSGl0KGhpdDEpOworICAgICAgICBjaGVja0hpdChoaXQyKTsKKworICAgICAgICBpbnQgdmlzdWFsMSA9IGdldFZpc3VhbEZyb21IaXRJbmZvKGhpdDEpOworICAgICAgICBpbnQgdmlzdWFsMiA9IGdldFZpc3VhbEZyb21IaXRJbmZvKGhpdDIpOworCisgICAgICAgIGlmICh2aXN1YWwxID4gdmlzdWFsMikgeworICAgICAgICAgICAgaW50IHRtcCA9IHZpc3VhbDI7CisgICAgICAgICAgICB2aXN1YWwyID0gdmlzdWFsMTsKKyAgICAgICAgICAgIHZpc3VhbDEgPSB0bXA7CisgICAgICAgIH0KKworICAgICAgICAvLyBNYXggbGV2ZWwgaXMgMjU1LCBzbyB3ZSBkb24ndCBuZWVkIG1vcmUgdGhhbiA1MTIgZW50cmllcworICAgICAgICBpbnQgcmVzdWx0c1tdID0gbmV3IGludFs1MTJdOworCisgICAgICAgIGludCBwcmV2TG9naWNhbCwgbG9naWNhbCwgcnVuU3RhcnQsIG51bVJ1bnMgPSAwOworCisgICAgICAgIGxvZ2ljYWwgPSBydW5TdGFydCA9IHByZXZMb2dpY2FsID0gYnJlYWtlci5nZXRMb2dpY2FsRnJvbVZpc3VhbCh2aXN1YWwxKTsKKworICAgICAgICAvLyBHZXQgYWxsIHRoZSBydW5zLiBXZSB1c2UgdGhlIGZhY3QgdGhhdCBkaXJlY3Rpb24gaXMgY29uc3RhbnQgaW4gYWxsIHJ1bnMuCisgICAgICAgIGZvciAoaW50IGk9dmlzdWFsMSsxOyBpPD12aXN1YWwyOyBpKyspIHsKKyAgICAgICAgICAgIGxvZ2ljYWwgPSBicmVha2VyLmdldExvZ2ljYWxGcm9tVmlzdWFsKGkpOworICAgICAgICAgICAgaW50IGRpZmYgPSBsb2dpY2FsLXByZXZMb2dpY2FsOworCisgICAgICAgICAgICAvLyBTdGFydCBvZiB0aGUgbmV4dCBydW4gZW5jb3VudGVyZWQKKyAgICAgICAgICAgIGlmIChkaWZmID4gMSB8fCBkaWZmIDwgLTEpIHsKKyAgICAgICAgICAgICAgICByZXN1bHRzWyhudW1SdW5zKSoyXSA9IE1hdGgubWluKHJ1blN0YXJ0LCBwcmV2TG9naWNhbCk7CisgICAgICAgICAgICAgICAgcmVzdWx0c1sobnVtUnVucykqMiArIDFdID0gTWF0aC5tYXgocnVuU3RhcnQsIHByZXZMb2dpY2FsKTsKKyAgICAgICAgICAgICAgICBudW1SdW5zKys7CisgICAgICAgICAgICAgICAgcnVuU3RhcnQgPSBsb2dpY2FsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcmV2TG9naWNhbCA9IGxvZ2ljYWw7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgbGFzdCB1bnNhdmVkIHJ1bgorICAgICAgICByZXN1bHRzWyhudW1SdW5zKSoyXSA9IE1hdGgubWluKHJ1blN0YXJ0LCBsb2dpY2FsKTsKKyAgICAgICAgcmVzdWx0c1sobnVtUnVucykqMiArIDFdID0gTWF0aC5tYXgocnVuU3RhcnQsIGxvZ2ljYWwpOworICAgICAgICBudW1SdW5zKys7CisKKyAgICAgICAgaW50IHJldHZhbFtdID0gbmV3IGludFtudW1SdW5zKjJdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3VsdHMsIDAsIHJldHZhbCwgMCwgbnVtUnVucyoyKTsKKyAgICAgICAgcmV0dXJuIHJldHZhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgaGlnaGxpZ2h0IHNoYXBlIGZyb20gZ2l2ZW4gdHdvIGVuZHBvaW50cyBpbiB0aGUgbG9naWNhbAorICAgICAqIHJlcHJlc2VudGF0aW9uLiBUaGlzIHNoYXBlIGlzIG5vdCBhbHdheXMgdmlzdWFsbHkgY29udGlndW91cworICAgICAqIEBwYXJhbSBmaXJzdEVuZHBvaW50IC0gMXN0IGxvZ2ljYWwgZW5kcG9pbnQKKyAgICAgKiBAcGFyYW0gc2Vjb25kRW5kcG9pbnQgLSAybmQgbG9naWNhbCBlbmRwb2ludAorICAgICAqIEBwYXJhbSBib3VuZHMgLSBib3VuZHMgdG8gZml0IHRoZSBzaGFwZSBpbnRvCisgICAgICogQHBhcmFtIGxheW91dCAtIHRleHQgbGF5b3V0CisgICAgICogQHJldHVybiBoaWdobGlnaHQgc2hhcGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcGUgZ2V0TG9naWNhbEhpZ2hsaWdodFNoYXBlKAorICAgICAgICAgICAgaW50IGZpcnN0RW5kcG9pbnQsIGludCBzZWNvbmRFbmRwb2ludCwKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIGJvdW5kcywgVGV4dExheW91dCBsYXlvdXQKKyAgICApIHsKKyAgICAgICAgR2VuZXJhbFBhdGggcmVzID0gbmV3IEdlbmVyYWxQYXRoKCk7CisKKyAgICAgICAgZm9yIChpbnQgaT1maXJzdEVuZHBvaW50OyBpPD1zZWNvbmRFbmRwb2ludDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgZW5kUnVuID0gYnJlYWtlci5nZXRMZXZlbFJ1bkxpbWl0KGksIHNlY29uZEVuZHBvaW50KTsKKyAgICAgICAgICAgIFRleHRIaXRJbmZvIGhpdDEgPSBUZXh0SGl0SW5mby5sZWFkaW5nKGkpOworICAgICAgICAgICAgVGV4dEhpdEluZm8gaGl0MiA9IFRleHRIaXRJbmZvLnRyYWlsaW5nKGVuZFJ1bi0xKTsKKworICAgICAgICAgICAgTGluZTJEIGNhcmV0MSA9IGdldENhcmV0U2hhcGUoaGl0MSwgbGF5b3V0LCBmYWxzZSwgdHJ1ZSwgYm91bmRzKTsKKyAgICAgICAgICAgIExpbmUyRCBjYXJldDIgPSBnZXRDYXJldFNoYXBlKGhpdDIsIGxheW91dCwgZmFsc2UsIHRydWUsIGJvdW5kcyk7CisKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoY29ubmVjdENhcmV0cyhjYXJldDEsIGNhcmV0MiksIGZhbHNlKTsKKworICAgICAgICAgICAgaSA9IGVuZFJ1bjsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Db21tb25HbHlwaFZlY3Rvci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Db21tb25HbHlwaFZlY3Rvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwNDBhNjAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0NvbW1vbkdseXBoVmVjdG9yLmphdmEKQEAgLTAsMCArMSw5NTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkZvbnRSZW5kZXJDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhKdXN0aWZpY2F0aW9uSW5mbzsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkdseXBoTWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkdseXBoVmVjdG9yOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworaW1wb3J0IGphdmEuYXd0Lmdlb20uR2VuZXJhbFBhdGg7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworLyoqCisgKiBHbHlwaFZlY3RvciBpbXBsZW1lbnRhdGlvbgorICovCitwdWJsaWMgY2xhc3MgQ29tbW9uR2x5cGhWZWN0b3IgZXh0ZW5kcyBHbHlwaFZlY3RvciB7CisKKyAgICAvLyBhcnJheSBvZiB0cmFuc2Zvcm1zIG9mIGdseXBocyBpbiBHbHlwaFZlY3RvcgorICAgIHByb3RlY3RlZCBBZmZpbmVUcmFuc2Zvcm1bXSBnbHNUcmFuc2Zvcm1zOworCisgICAgLy8gYXJyYXkgb2YgY2hhcnMgZGVmaW5lZCBpbiBjb25zdHJ1Y3RvcgorICAgIHB1YmxpYyBjaGFyW10gY2hhclZlY3RvcjsKKworICAgIC8vIGFycmF5IG9mIEdseXBoIG9iamVjdHMsIHRoYXQgZGVzY3JpYmUgaW5mb3JtYXRpb24gYWJvdXQgZ2x5cGhzCisgICAgcHVibGljIEdseXBoW10gdmVjdG9yOworCisgICAgLy8gYXJyYXkgb2YgZGVmYXVsdCBwb3NpdGlvbnMgb2YgZ2x5cGhzIGluIEdseXBoVmVjdG9yCisgICAgLy8gd2l0aG91dCBhcHBseWluZyBHbHlwaFZlY3RvcidzIHRyYW5zZm9ybQorICAgIGZsb2F0W10gZGVmYXVsdFBvc2l0aW9uczsKKworICAgIC8vIGFycmF5IG9mIGxvZ2ljYWwgcG9zaXRpb25zIG9mIGdseXBocyBpbiBHbHlwaFZlY3RvcgorCisgICAgZmxvYXRbXSBsb2dpY2FsUG9zaXRpb25zOworCisgICAgLy8gYXJyYXkgb2YgdmlzdWFsIChyZWFsKSBwb3NpdGlvbnMgb2YgZ2x5cGhzIGluIEdseXBoVmVjdG9yCisgICAgcHVibGljIGZsb2F0W10gdmlzdWFsUG9zaXRpb25zOworCisgICAgLy8gRm9udFJlbmRlckNvbnRleHQgZm9yIHRoaXMgdmVjdG9yLgorICAgIHByb3RlY3RlZCBGb250UmVuZGVyQ29udGV4dCB2ZWN0b3JGUkM7CisKKyAgICAvLyBsYXlvdXQgZmxhZ3MgbWFzaworICAgIHByb3RlY3RlZCBpbnQgbGF5b3V0RmxhZ3MgPSAwOworCisgICAgLy8gYXJyYXkgb2YgY2FjaGVkIGdseXBoIG91dGxpbmVzIAorICAgIHByb3RlY3RlZCBTaGFwZVtdIGd2U2hhcGVzOworCisgICAgRm9udFBlZXJJbXBsIHBlZXI7CisKKyAgICAvLyBmb250IGNvcnJlc3BvbmRpbmcgdG8gdGhlIEdseXBoVmVjdG9yIAorICAgIEZvbnQgZm9udDsKKworICAgIC8vIGFzY2VudCBvZiB0aGUgZm9udAorICAgIGZsb2F0IGFzY2VudDsKKworICAgIC8vIGhlaWdodCBvZiB0aGUgZm9udAorICAgIGZsb2F0IGhlaWdodDsKKyAgICAKKyAgICAvLyBsZWFkaW5nIG9mIHRoZSBmb250CisgICAgZmxvYXQgbGVhZGluZzsKKyAgICAKKyAgICAvLyBkZXNjZW50IG9mIHRoZSBmb250CisgICAgZmxvYXQgZGVzY2VudDsKKworICAgIC8vIHRyYW5zZm9ybSBvZiB0aGUgR2x5cGhWZWN0b3IKKyAgICBBZmZpbmVUcmFuc2Zvcm0gdHJhbnNmb3JtOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuZXcgQ29tbW9uR2x5cGhWZWN0b3Igb2JqZWN0IGZyb20gdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFycyBhbiBhcnJheSBvZiBjaGFycworICAgICAqIEBwYXJhbSBmcmMgRm9udFJlbmRlckNvbnRleHQgb2JqZWN0CisgICAgICogQHBhcmFtIGZudCBGb250IG9iamVjdAorICAgICAqIEBwYXJhbSBmbGFncyBsYXlvdXQgZmxhZ3MKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyBDb21tb25HbHlwaFZlY3RvcihjaGFyW10gY2hhcnMsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgRm9udCBmbnQsCisgICAgICAgICAgICBpbnQgZmxhZ3MpIHsKKyAgICAgICAgaW50IGxlbiA9IGNoYXJzLmxlbmd0aDsKKworICAgICAgICB0aGlzLmZvbnQgPSBmbnQ7CisgICAgICAgIHRoaXMudHJhbnNmb3JtID0gZm50LmdldFRyYW5zZm9ybSgpOworICAgICAgICB0aGlzLnBlZXIgPSAoRm9udFBlZXJJbXBsKSBmbnQuZ2V0UGVlcigpOworCisgICAgICAgIGd2U2hhcGVzID0gbmV3IFNoYXBlW2xlbl07CisKKyAgICAgICAgLy8gISEgQXMgcG9pbnRlZCBpbiBBUEkgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIAorICAgICAgICAvLyBnZXRHbHlwaFBvc2lzaXRpb25zKGludCBpbmRleCxpbnQgbnVtRW50cmllcywgZmxvYXRbXSBwb3NpdGlvblJldHVybikgCisgICAgICAgIC8vIGFuZCBnZXRHbHlwaFBvc2l0aW9uKGludCBpbmRleCkgbWV0aG9kcywgaWYgdGhlIGluZGV4IGlzIGVxdWFscyB0byAKKyAgICAgICAgLy8gdGhlIG51bWJlciBvZiBnbHlwaHMgdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSBsYXN0IGdseXBoIG11c3QgYmUgCisgICAgICAgIC8vIHJldHVybmVkLCB0aHVzIHRoZXJlIGFyZSBuKzEgcG9zaXRpb25zIGFuZCBsYXN0IChuKzEpIHBvc2l0aW9uIAorICAgICAgICAvLyBwb2ludHMgdG8gdGhlIGVuZCBvZiBHbHlwaFZlY3Rvci4KKworICAgICAgICBsb2dpY2FsUG9zaXRpb25zID0gbmV3IGZsb2F0WyhsZW4rMSk8PDFdOworICAgICAgICB2aXN1YWxQb3NpdGlvbnMgPSBuZXcgZmxvYXRbKGxlbisxKTw8MV07CisgICAgICAgIGRlZmF1bHRQb3NpdGlvbnMgPSBuZXcgZmxvYXRbKGxlbisxKTw8MV07CisKKyAgICAgICAgZ2xzVHJhbnNmb3JtcyA9IG5ldyBBZmZpbmVUcmFuc2Zvcm1bbGVuXTsKKworICAgICAgICB0aGlzLmNoYXJWZWN0b3IgPSBjaGFyczsKKyAgICAgICAgdGhpcy52ZWN0b3JGUkMgPSBmcmM7CisgICAgICAgIC8vTGluZU1ldHJpY3NJbXBsIGxtSW1wbCA9IChMaW5lTWV0cmljc0ltcGwpcGVlci5nZXRMaW5lTWV0cmljcygpOworCisgICAgICAgIExpbmVNZXRyaWNzSW1wbCBsbUltcGwgPSAoTGluZU1ldHJpY3NJbXBsKWZudC5nZXRMaW5lTWV0cmljcyhTdHJpbmcudmFsdWVPZihjaGFycyksIGZyYyk7CisKKyAgICAgICAgdGhpcy5hc2NlbnQgPSBsbUltcGwuZ2V0QXNjZW50KCk7CisgICAgICAgIHRoaXMuaGVpZ2h0ID0gbG1JbXBsLmdldEhlaWdodCgpOworICAgICAgICB0aGlzLmxlYWRpbmcgPSBsbUltcGwuZ2V0TGVhZGluZygpOworICAgICAgICB0aGlzLmRlc2NlbnQgPSBsbUltcGwuZ2V0RGVzY2VudCgpOworICAgICAgICB0aGlzLmxheW91dEZsYWdzID0gZmxhZ3M7CisKKyAgICAgICAgaWYgKChmbGFncyAmIEZvbnQuTEFZT1VUX1JJR0hUX1RPX0xFRlQpICE9IDApeworICAgICAgICAgICAgY2hhciB2ZWN0b3JbXSA9IG5ldyBjaGFyW2xlbl07CisgICAgICAgICAgICBmb3IoaW50IGk9MDsgaSA8IGxlbjsgaSsrKXsKKyAgICAgICAgICAgICAgICB2ZWN0b3JbaV0gPSBjaGFyc1tsZW4taS0xXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMudmVjdG9yID0gcGVlci5nZXRHbHlwaHModmVjdG9yKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy52ZWN0b3IgPSBwZWVyLmdldEdseXBocyhjaGFycyk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmdsc1RyYW5zZm9ybXMgPSBuZXcgQWZmaW5lVHJhbnNmb3JtW2xlbl07CisKKyAgICAgICAgc2V0RGVmYXVsdFBvc2l0aW9ucygpOworICAgICAgICBwZXJmb3JtRGVmYXVsdExheW91dCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgbmV3IENvbW1vbkdseXBoVmVjdG9yIG9iamVjdCBmcm9tIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4gCisgICAgICogTGF5b3V0IGZsYWdzIHNldCB0byBkZWZhdWx0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFycyBhbiBhcnJheSBvZiBjaGFycworICAgICAqIEBwYXJhbSBmcmMgRm9udFJlbmRlckNvbnRleHQgb2JqZWN0CisgICAgICogQHBhcmFtIGZudCBGb250IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBDb21tb25HbHlwaFZlY3RvcihjaGFyW10gY2hhcnMsIEZvbnRSZW5kZXJDb250ZXh0IGZyYywgRm9udCBmbnQpIHsKKyAgICAgICAgdGhpcyhjaGFycywgZnJjLCBmbnQsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgbmV3IENvbW1vbkdseXBoVmVjdG9yIG9iamVjdCBmcm9tIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycy4gCisgICAgICogTGF5b3V0IGZsYWdzIHNldCB0byBkZWZhdWx0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdHIgc3BlY2lmaWVkIHN0cmluZworICAgICAqIEBwYXJhbSBmcmMgRm9udFJlbmRlckNvbnRleHQgb2JqZWN0CisgICAgICogQHBhcmFtIGZudCBGb250IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBDb21tb25HbHlwaFZlY3RvcihTdHJpbmcgc3RyLCBGb250UmVuZGVyQ29udGV4dCBmcmMsIEZvbnQgZm50KSB7CisgICAgICAgIHRoaXMoc3RyLnRvQ2hhckFycmF5KCksIGZyYywgZm50LCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG5ldyBDb21tb25HbHlwaFZlY3RvciBvYmplY3QgZnJvbSB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIHN0ciBzcGVjaWZpZWQgc3RyaW5nCisgICAgICogQHBhcmFtIGZyYyBGb250UmVuZGVyQ29udGV4dCBvYmplY3QKKyAgICAgKiBAcGFyYW0gZm50IEZvbnQgb2JqZWN0CisgICAgICogQHBhcmFtIGZsYWdzIGxheW91dCBmbGFncworICAgICAqLworICAgIHB1YmxpYyBDb21tb25HbHlwaFZlY3RvcihTdHJpbmcgc3RyLCBGb250UmVuZGVyQ29udGV4dCBmcmMsIEZvbnQgZm50LCBpbnQgZmxhZ3MpIHsKKyAgICAgICAgdGhpcyhzdHIudG9DaGFyQXJyYXkoKSwgZnJjLCBmbnQsIGZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgYXJyYXkgb2YgbG9naWNhbCBwb3NpdGlvbnMgb2YgdGhlIGdseXBocyB0bworICAgICAqIGRlZmF1bHQgd2l0aCB0aGVpciBkZWZhdWx0IGFkdmFuY2VzIGFuZCBoZWlnaHQuCisgICAgICovCisgICAgdm9pZCBzZXREZWZhdWx0UG9zaXRpb25zKCl7CisgICAgICAgIGludCBsZW4gPSBnZXROdW1HbHlwaHMoKTsKKworICAgICAgICAvLyBGaXJzdCBbeCx5XSBpcyBzZXQgaW50byBbMCwwXSBwb3NpdGlvbgorICAgICAgICAvLyBmb3IgdGhpcyByZWFzb24gc3RhcnQgaW5kZXggaXMgMQorICAgICAgICBmb3IgKGludCBpPTE7IGkgPD0gbGVuOyBpKysgKXsKKyAgICAgICAgICAgICAgICBpbnQgaWR4ID0gaSA8PCAxOworICAgICAgICAgICAgICAgIGZsb2F0IGFkdmFuY2VYID0gdmVjdG9yW2ktMV0uZ2V0R2x5cGhQb2ludE1ldHJpY3MoKS5nZXRBZHZhbmNlWCgpOworICAgICAgICAgICAgICAgIGZsb2F0IGFkdmFuY2VZID0gdmVjdG9yW2ktMV0uZ2V0R2x5cGhQb2ludE1ldHJpY3MoKS5nZXRBZHZhbmNlWSgpOworCisgICAgICAgICAgICAgICAgZGVmYXVsdFBvc2l0aW9uc1tpZHhdID0gZGVmYXVsdFBvc2l0aW9uc1tpZHgtMl0gKyBhZHZhbmNlWDsKKyAgICAgICAgICAgICAgICBkZWZhdWx0UG9zaXRpb25zW2lkeCsxXSA9IGRlZmF1bHRQb3NpdGlvbnNbaWR4LTFdICsgYWR2YW5jZVk7CisKKyAgICAgICAgfQorICAgICAgICB0cmFuc2Zvcm0udHJhbnNmb3JtKGRlZmF1bHRQb3NpdGlvbnMsIDAsIGxvZ2ljYWxQb3NpdGlvbnMsIDAsIGdldE51bUdseXBocygpKzEpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuZXMgdGhlIHBpeGVsIGJvdW5kcyBvZiB0aGlzIEdseXBoVmVjdG9yIHJlbmRlcmVkIGF0IHRoZSAKKyAgICAgKiBzcGVjaWZpZWQgeCx5IGxvY2F0aW9uIHdpdGggdGhlIGdpdmVuIEZvbnRSZW5kZXJDb250ZXh0LgorICAgICAqICAKKyAgICAgKiBAcGFyYW0gZnJjIGEgRm9udFJlbmRlckNvbnRleHQgdGhhdCBpcyB1c2VkCisgICAgICogQHBhcmFtIHggc3BlY2lmaWVkIHggY29vcmRpbmF0ZSB2YWx1ZQorICAgICAqIEBwYXJhbSB5IHNwZWNpZmllZCB5IGNvb3JkaW5hdGUgdmFsdWUKKyAgICAgKiBAcmV0dXJuIGEgUmVjdGFuZ2xlIHRoYXQgYm91bmRzIHBpeGVscyBvZiB0aGlzIEdseXBoVmVjdG9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZSBnZXRQaXhlbEJvdW5kcyhGb250UmVuZGVyQ29udGV4dCBmcmMsIGZsb2F0IHgsIGZsb2F0IHkpIHsKKworICAgICAgICBkb3VibGUgeE0sIHlNLCB4bSwgeW07CisKKyAgICAgICAgZG91YmxlIG1pblggPSAwOworICAgICAgICBkb3VibGUgbWluWSA9IDA7CisgICAgICAgIGRvdWJsZSBtYXhYID0gMDsKKyAgICAgICAgZG91YmxlIG1heFkgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5nZXROdW1HbHlwaHMoKTsgaSsrKSB7CisgICAgICAgICAgICBSZWN0YW5nbGUgZ2x5cGhCb3VuZHMgPSB0aGlzLmdldEdseXBoUGl4ZWxCb3VuZHMoaSwgZnJjLCAwLCAwKTsKKyAgICAgICAgICAgIHhtID0gZ2x5cGhCb3VuZHMuZ2V0TWluWCgpOworICAgICAgICAgICAgeW0gPSBnbHlwaEJvdW5kcy5nZXRNaW5ZKCk7CisgICAgICAgICAgICB4TSA9IGdseXBoQm91bmRzLmdldE1heFgoKTsKKyAgICAgICAgICAgIHlNID0gZ2x5cGhCb3VuZHMuZ2V0TWF4WSgpOworCisgICAgICAgICAgICBpZiAoaSA9PSAwKSB7CisgICAgICAgICAgICAgICAgbWluWCA9IHhtOworICAgICAgICAgICAgICAgIG1pblkgPSB5bTsKKyAgICAgICAgICAgICAgICBtYXhYID0geE07CisgICAgICAgICAgICAgICAgbWF4WSA9IHlNOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWluWCA+IHhtKSB7CisgICAgICAgICAgICAgICAgbWluWCA9IHhtOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1pblkgPiB5bSkgeworICAgICAgICAgICAgICAgIG1pblkgPSB5bTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtYXhYIDwgeE0pIHsKKyAgICAgICAgICAgICAgICBtYXhYID0geE07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobWF4WSA8IHlNKSB7CisgICAgICAgICAgICAgICAgbWF4WSA9IHlNOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlKChpbnQpKG1pblggKyB4KSwgKGludCkobWluWSArIHkpLCAoaW50KShtYXhYIC0gbWluWCksIChpbnQpKG1heFkgLSBtaW5ZKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICogVGhlIHZpc3VhbCBib3VuZHMgaXMgdGhlIGJvdW5kcyBvZiB0aGUgdG90YWwgb3V0bGluZSBvZiAKKyAgICAgKiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEByZXR1cm4gYSBSZWN0YW5nbGUyRCB0aGF0IGlkIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoaXMgR2x5cGhWZWN0b3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0VmlzdWFsQm91bmRzKCkgeworICAgICAgICBmbG9hdCB4TSwgeU0sIHhtLCB5bTsKKyAgICAgICAgZmxvYXQgbWluWCA9IDA7CisgICAgICAgIGZsb2F0IG1pblkgPSAwOworICAgICAgICBmbG9hdCBtYXhYID0gMDsKKyAgICAgICAgZmxvYXQgbWF4WSA9IDA7CisgICAgICAgIGJvb2xlYW4gZmlyc3RJdGVyYXRpb24gPSB0cnVlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5nZXROdW1HbHlwaHMoKTsgaSsrKSB7CisgICAgICAgICAgICBSZWN0YW5nbGUyRCBib3VuZHMgPSB0aGlzLmdldEdseXBoVmlzdWFsQm91bmRzKGkpLmdldEJvdW5kczJEKCk7CisgICAgICAgICAgICBpZiAoYm91bmRzLmdldFdpZHRoKCkgPT0gMCl7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB4bSA9IChmbG9hdClib3VuZHMuZ2V0WCgpOworICAgICAgICAgICAgeW0gPSAoZmxvYXQpYm91bmRzLmdldFkoKTsKKworICAgICAgICAgICAgeE0gPSAoZmxvYXQpKHhtICsgYm91bmRzLmdldFdpZHRoKCkpOworCisgICAgICAgICAgICB5TSA9IHltICsgKGZsb2F0KSBib3VuZHMuZ2V0SGVpZ2h0KCk7CisKKyAgICAgICAgICAgIGlmIChmaXJzdEl0ZXJhdGlvbikgeworICAgICAgICAgICAgICAgIG1pblggPSB4bTsKKyAgICAgICAgICAgICAgICBtaW5ZID0geW07CisgICAgICAgICAgICAgICAgbWF4WCA9IHhNOworICAgICAgICAgICAgICAgIG1heFkgPSB5TTsKKyAgICAgICAgICAgICAgICBmaXJzdEl0ZXJhdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAobWluWCA+IHhtKSB7CisgICAgICAgICAgICAgICAgICAgIG1pblggPSB4bTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG1pblkgPiB5bSkgeworICAgICAgICAgICAgICAgICAgICBtaW5ZID0geW07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChtYXhYIDwgeE0pIHsKKyAgICAgICAgICAgICAgICAgICAgbWF4WCA9IHhNOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobWF4WSA8IHlNKSB7CisgICAgICAgICAgICAgICAgICAgIG1heFkgPSB5TTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAodGhpcy5nZXROdW1HbHlwaHMoKSAhPSAwKSA/IG5ldyBSZWN0YW5nbGUyRC5GbG9hdChtaW5YLCBtaW5ZLAorICAgICAgICAgICAgICAgIChtYXhYIC0gbWluWCksIChtYXhZIC0gbWluWSkpIDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIG5ldyBwb3NpdGlvbiB0byB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEdseXBoUG9zaXRpb24oaW50IGdseXBoSW5kZXgsIFBvaW50MkQgbmV3UG9zKSB7CisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA+IHZlY3Rvci5sZW5ndGgpIHx8IChnbHlwaEluZGV4IDwgMCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Mz1nbHlwaEluZGV4IGlzIG91dCBvZiB2ZWN0b3IncyBsaW1pdHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgZmxvYXQgeCA9IChmbG9hdCluZXdQb3MuZ2V0WCgpOworICAgICAgICBmbG9hdCB5ID0gKGZsb2F0KW5ld1Bvcy5nZXRZKCk7CisgICAgICAgIGludCBpbmRleCA9IGdseXBoSW5kZXggPDwgMTsKKworICAgICAgICBpZiAoKHggIT0gdmlzdWFsUG9zaXRpb25zW2luZGV4XSkgfHwgKHkgIT0gdmlzdWFsUG9zaXRpb25zW2luZGV4ICsgMV0pKXsKKyAgICAgICAgICAgIHZpc3VhbFBvc2l0aW9uc1tpbmRleF0gPSB4OworICAgICAgICAgICAgdmlzdWFsUG9zaXRpb25zW2luZGV4KzFdID0geTsKKyAgICAgICAgICAgIGxheW91dEZsYWdzID0gbGF5b3V0RmxhZ3MgfCBGTEFHX0hBU19QT1NJVElPTl9BREpVU1RNRU5UUzsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIHNwZWNpZmllZCBnbHlwaCByZWxhdGl2ZSB0byB0aGUgb3JpZ2luIG9mCisgICAgICogdGhpcyBHbHlwaFZlY3RvcgorICAgICAqIEByZXR1cm4gYSBQb2ludDJEIHRoYXQgdGhlIG9yaWdpbiBvZiB0aGUgZ2x5cGggd2l0aCBzcGVjaWZpZWQgaW5kZXgKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUG9pbnQyRCBnZXRHbHlwaFBvc2l0aW9uKGludCBnbHlwaEluZGV4KSB7CisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA+IHZlY3Rvci5sZW5ndGgpIHx8IChnbHlwaEluZGV4IDwgMCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Mz1nbHlwaEluZGV4IGlzIG91dCBvZiB2ZWN0b3IncyBsaW1pdHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW50IGluZGV4ID0gZ2x5cGhJbmRleCA8PCAxOworICAgICAgICBQb2ludDJEIHBvcyA9IG5ldyBQb2ludDJELkZsb2F0KHZpc3VhbFBvc2l0aW9uc1tpbmRleF0sIHZpc3VhbFBvc2l0aW9uc1tpbmRleCsxXSk7CisKKyAgICAgICAgLy8gRm9yIGxhc3QgcG9zaXRpb24gd2UgZG9uJ3QgaGF2ZSB0byB0cmFuc2Zvcm0gISEKKyAgICAgICAgaWYoZ2x5cGhJbmRleD09dmVjdG9yLmxlbmd0aCl7CisgICAgICAgICAgICByZXR1cm4gcG9zOworICAgICAgICB9CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gZ2V0R2x5cGhUcmFuc2Zvcm0oZ2x5cGhJbmRleCk7CisgICAgICAgIGlmICgoYXQgPT0gbnVsbCkgfHwgKGF0LmlzSWRlbnRpdHkoKSkpeworICAgICAgICAgICAgcmV0dXJuIHBvczsKKyAgICAgICAgfQorCisgICAgICAgIHBvcy5zZXRMb2NhdGlvbihwb3MuZ2V0WCgpICsgYXQuZ2V0VHJhbnNsYXRlWCgpLCBwb3MuZ2V0WSgpICsgYXQuZ2V0VHJhbnNsYXRlWSgpKTsKKworICAgICAgICByZXR1cm4gcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgbmV3IHRyYW5zZm9ybSB0byB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4IHNwZWNpZmllZCBpbmRleCBvZiB0aGUgZ2x5cGgKKyAgICAgKiBAcGFyYW0gdHJhbnMgQWZmaW5lVHJhbnNmb3JtIG9mIHRoZSBnbHlwaCB3aXRoIHNwZWNpZmllZCBpbmRleAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEdseXBoVHJhbnNmb3JtKGludCBnbHlwaEluZGV4LCBBZmZpbmVUcmFuc2Zvcm0gdHJhbnMpIHsKKyAgICAgICAgaWYgKChnbHlwaEluZGV4ID49IHZlY3Rvci5sZW5ndGgpIHx8IChnbHlwaEluZGV4IDwgMCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Mz1nbHlwaEluZGV4IGlzIG91dCBvZiB2ZWN0b3IncyBsaW1pdHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoKHRyYW5zID09IG51bGwpIHx8ICh0cmFucy5pc0lkZW50aXR5KCkpKSB7CisgICAgICAgICAgICBnbHNUcmFuc2Zvcm1zW2dseXBoSW5kZXhdID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdsc1RyYW5zZm9ybXNbZ2x5cGhJbmRleF0gPSBuZXcgQWZmaW5lVHJhbnNmb3JtKHRyYW5zKTsKKyAgICAgICAgICAgIGxheW91dEZsYWdzID0gbGF5b3V0RmxhZ3MgfCBGTEFHX0hBU19UUkFOU0ZPUk1TOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWZmaW5lIHRyYW5zZm9ybSBvZiB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4IHNwZWNpZmllZCBpbmRleCBvZiB0aGUgZ2x5cGgKKyAgICAgKiBAcmV0dXJuIGFuIEFmZmluZVRyYW5zZm9ybSBvZiB0aGUgZ2x5cGggd2l0aCBzcGVjaWZpZWQgaW5kZXgKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWZmaW5lVHJhbnNmb3JtIGdldEdseXBoVHJhbnNmb3JtKGludCBnbHlwaEluZGV4KSB7CisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA+PSB0aGlzLnZlY3Rvci5sZW5ndGgpIHx8IChnbHlwaEluZGV4IDwgMCkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40Mz1nbHlwaEluZGV4IGlzIG91dCBvZiB2ZWN0b3IncyBsaW1pdHMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuZ2xzVHJhbnNmb3Jtc1tnbHlwaEluZGV4XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtZXRyaWNzIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGguCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXggc3BlY2lmaWVkIGluZGV4IG9mIHRoZSBnbHlwaAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBHbHlwaE1ldHJpY3MgZ2V0R2x5cGhNZXRyaWNzKGludCBnbHlwaEluZGV4KSB7CisKKyAgICAgICAgaWYgKChnbHlwaEluZGV4IDwgMCkgfHwgKChnbHlwaEluZGV4KSA+PSB0aGlzLmdldE51bUdseXBocygpKSkgeworICAgICAgICAgICAgLy8gYXd0LjQzPWdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIGxpbWl0cworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICAvLyBUT0RPOiBpcyB0aGVyZSBhIHNlbmNlIGluIEdseXBoTWV0cmljcworICAgICAgICAvLyBpZiBjZXJ0YWluIGdseXBoIG9yIEZvbnQgaGFzIGEgdHJhbnNmb3JtPz8KKyAgICAgICAgcmV0dXJuIHRoaXMudmVjdG9yW2dseXBoSW5kZXhdLmdldEdseXBoTWV0cmljcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBqdXN0aWZpY2F0aW9uIGluZm9ybWF0aW9uIGZvciB0aGUgZ2x5cGggd2l0aCBzcGVjaWZpZWQgZ2x5cGggCisgICAgICogaW5kZXguCisgICAgICogQHBhcmFtIGdseXBoSW5kZXggaW5kZXggb2YgYSBnbHlwaCB3aGljaCBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGlzIHRvIGJlIAorICAgICAqIHJlY2VpdmVkICAgCisgICAgICogQHJldHVybiBhIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gb2JqZWN0IHRoYXQgY29udGFpbnMgZ2x5cGgganVzdGlmaWNhdGlvbiAKKyAgICAgKiBwcm9wZXJ0aWVzIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGgKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBnZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvKGludCBnbHlwaEluZGV4KSB7CisgICAgICAgIC8vIFRPRE8gOiBGaW5kIG91dCB0aGUgc291cmNlIG9mIEp1c3RpZmljYXRpb24gaW5mbworICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEZvbnRSZW5kZXJDb250ZXh0IHBhcmFtZXRlciBvZiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb250UmVuZGVyQ29udGV4dCBnZXRGb250UmVuZGVyQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMudmVjdG9yRlJDOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZpc3VhbCBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhJbmRleCBzcGVjaWZpZWQgaW5kZXggb2YgdGhlIGdseXBoCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNoYXBlIGdldEdseXBoVmlzdWFsQm91bmRzKGludCBnbHlwaEluZGV4KSB7CisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA8IDApIHx8IChnbHlwaEluZGV4ID49IHRoaXMuZ2V0TnVtR2x5cGhzKCkpKSB7CisgICAgICAgICAgICAvLyBhd3QuNDM9Z2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgbGltaXRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGlkeCAgPSBnbHlwaEluZGV4IDw8IDE7CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGZvbnRUcmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybTsKKyAgICAgICAgZG91YmxlIHhPZmZzID0gZm9udFRyYW5zZm9ybS5nZXRUcmFuc2xhdGVYKCk7CisgICAgICAgIGRvdWJsZSB5T2ZmcyA9IGZvbnRUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWSgpOworCisgICAgICAgIGlmICh2ZWN0b3JbZ2x5cGhJbmRleF0uZ2V0V2lkdGgoKSA9PSAwKXsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoKGZsb2F0KXhPZmZzLCAoZmxvYXQpeU9mZnMsIDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gQWZmaW5lVHJhbnNmb3JtLmdldFRyYW5zbGF0ZUluc3RhbmNlKHhPZmZzLCB5T2Zmcyk7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBnbHlwaFRyYW5zZm9ybSA9IGdldEdseXBoVHJhbnNmb3JtKGdseXBoSW5kZXgpOworCisgICAgICAgIGlmICh0cmFuc2Zvcm0uaXNJZGVudGl0eSgpICYmICgoZ2x5cGhUcmFuc2Zvcm0gPT0gbnVsbCkgfHwgZ2x5cGhUcmFuc2Zvcm0uaXNJZGVudGl0eSgpKSl7CisgICAgICAgICAgICBSZWN0YW5nbGUyRCBibGFja0JveCA9IHZlY3RvcltnbHlwaEluZGV4XS5nZXRHbHlwaE1ldHJpY3MoKS5nZXRCb3VuZHMyRCgpOworICAgICAgICAgICAgYXQudHJhbnNsYXRlKHZpc3VhbFBvc2l0aW9uc1tpZHhdLCB2aXN1YWxQb3NpdGlvbnNbaWR4KzFdKTsKKyAgICAgICAgICAgIHJldHVybihhdC5jcmVhdGVUcmFuc2Zvcm1lZFNoYXBlKGJsYWNrQm94KSk7CisgICAgICAgIH0KKworICAgICAgICBHZW5lcmFsUGF0aCBzaGFwZSA9IChHZW5lcmFsUGF0aCl0aGlzLmdldEdseXBoT3V0bGluZShnbHlwaEluZGV4KTsKKyAgICAgICAgc2hhcGUudHJhbnNmb3JtKGF0KTsKKyAgICAgICAgcmV0dXJuIHNoYXBlLmdldEJvdW5kczJEKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuZXMgdGhlIHBpeGVsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIHdpdGhpbiBHbHlwaFZlY3RvciAKKyAgICAgKiByZW5kZXJlZCBhdCB0aGUgc3BlY2lmaWVkIHgseSBsb2NhdGlvbi4KKyAgICAgKiAgCisgICAgICogQHBhcmFtIGdseXBoSW5kZXggaW5kZXggb2YgdGhlIGdseXBoCisgICAgICogQHBhcmFtIGZyYyBhIEZvbnRSZW5kZXJDb250ZXh0IHRoYXQgaXMgdXNlZAorICAgICAqIEBwYXJhbSB4IHNwZWNpZmllZCB4IGNvb3JkaW5hdGUgdmFsdWUKKyAgICAgKiBAcGFyYW0geSBzcGVjaWZpZWQgeSBjb29yZGluYXRlIHZhbHVlCisgICAgICogQHJldHVybiBhIFJlY3RhbmdsZSB0aGF0IGJvdW5kcyBwaXhlbHMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0R2x5cGhQaXhlbEJvdW5kcyhpbnQgZ2x5cGhJbmRleCwgRm9udFJlbmRlckNvbnRleHQgZnJjLAorICAgICAgICAgICAgZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICAvLyBUT0RPIDogbmVlZCB0byBiZSBpbXBsZW1lbnRlZCB3aXRoIEZvbnRSZW5kZXJDb250ZXh0CisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA8IDApIHx8IChnbHlwaEluZGV4ID49IHRoaXMuZ2V0TnVtR2x5cGhzKCkpKSB7CisgICAgICAgICAgICAvLyBhd3QuNDM9Z2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgbGltaXRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaW50IGlkeCAgPSBnbHlwaEluZGV4IDw8IDE7CisKKyAgICAgICAgaWYgKHZlY3RvcltnbHlwaEluZGV4XS5nZXRXaWR0aCgpID09IDApeworICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGZvbnRUcmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybTsKKyAgICAgICAgICAgIGRvdWJsZSB4T2ZmcyA9IHggKyB2aXN1YWxQb3NpdGlvbnNbaWR4XSArIGZvbnRUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlWCgpOworICAgICAgICAgICAgZG91YmxlIHlPZmZzID0geSArIHZpc3VhbFBvc2l0aW9uc1tpZHgrMV0gKyBmb250VHJhbnNmb3JtLmdldFRyYW5zbGF0ZVkoKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlKChpbnQpeE9mZnMsIChpbnQpeU9mZnMsIDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgR2VuZXJhbFBhdGggc2hhcGUgPSAoR2VuZXJhbFBhdGgpdGhpcy5nZXRHbHlwaE91dGxpbmUoZ2x5cGhJbmRleCk7CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gQWZmaW5lVHJhbnNmb3JtLmdldFRyYW5zbGF0ZUluc3RhbmNlKHgsIHkpOworCisgICAgICAgIGlmIChmcmMgIT0gbnVsbCl7CisgICAgICAgICAgICBhdC5jb25jYXRlbmF0ZShmcmMuZ2V0VHJhbnNmb3JtKCkpOworICAgICAgICB9CisKKyAgICAgICAgc2hhcGUudHJhbnNmb3JtKGF0KTsKKworICAgICAgICBSZWN0YW5nbGUgYm91bmRzID0gc2hhcGUuZ2V0Qm91bmRzKCk7CisgICAgICAgIHJldHVybiBuZXcgUmVjdGFuZ2xlKChpbnQpYm91bmRzLmdldFgoKSwgKGludClib3VuZHMuZ2V0WSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpYm91bmRzLmdldFdpZHRoKCktMSwgKGludClib3VuZHMuZ2V0SGVpZ2h0KCktMSk7CisgICAgICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTaGFwZSB0aGF0IGVuY2xvc2VzIHNwZWNpZmllZCBnbHlwaC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhJbmRleCBzcGVjaWZpZWQgaW5kZXggb2YgdGhlIGdseXBoCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNoYXBlIGdldEdseXBoT3V0bGluZShpbnQgZ2x5cGhJbmRleCkgeworICAgICAgICBpZiAoKGdseXBoSW5kZXggPCAwKSB8fCAoZ2x5cGhJbmRleCA+PSB0aGlzLmdldE51bUdseXBocygpKSkgeworICAgICAgICAgICAgLy8gYXd0LjQzPWdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIGxpbWl0cworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChndlNoYXBlc1tnbHlwaEluZGV4XSA9PSBudWxsKSB7CisgICAgICAgICAgICBndlNoYXBlc1tnbHlwaEluZGV4XSA9IHZlY3RvcltnbHlwaEluZGV4XS5nZXRTaGFwZSgpOworICAgICAgICB9CisKKyAgICAgICAgR2VuZXJhbFBhdGggZ3AgPSAoR2VuZXJhbFBhdGgpKChHZW5lcmFsUGF0aClndlNoYXBlc1tnbHlwaEluZGV4XSkuY2xvbmUoKTsKKworICAgICAgICAvKiBBcHBseWluZyBHbHlwaFZlY3RvciBmb250IHRyYW5zZm9ybSAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gYXQgPSAoQWZmaW5lVHJhbnNmb3JtKXRoaXMudHJhbnNmb3JtLmNsb25lKCk7CisKKyAgICAgICAgLyogQXBwbHlpbmcgR2x5cGggdHJhbnNmb3JtICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBnbHlwaEFUID0gZ2V0R2x5cGhUcmFuc2Zvcm0oZ2x5cGhJbmRleCk7CisgICAgICAgIGlmIChnbHlwaEFUICE9IG51bGwpeworICAgICAgICAgICAgYXQucHJlQ29uY2F0ZW5hdGUoZ2x5cGhBVCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaWR4ICA9IGdseXBoSW5kZXggPDwgMTsKKworICAgICAgICBncC50cmFuc2Zvcm0oYXQpOworICAgICAgICBncC50cmFuc2Zvcm0oQWZmaW5lVHJhbnNmb3JtLmdldFRyYW5zbGF0ZUluc3RhbmNlKHZpc3VhbFBvc2l0aW9uc1tpZHhdLCB2aXN1YWxQb3NpdGlvbnNbaWR4KzFdKSk7CisgICAgICAgIHJldHVybiBncDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTaGFwZSB0aGF0IGlzIHRoZSBvdXRsaW5lIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgR2x5cGhWZWN0b3IgCisgICAgICogcmVuZGVyZWQgYXQgdGhlIHNwZWNpZmllZCB4LHkgY29vcmRpbmF0ZXMuCisgICAgICogCisgICAgICogQHBhcmFtIHggc3BlY2lmaWVkIHggY29vcmRpbmF0ZSB2YWx1ZQorICAgICAqIEBwYXJhbSB5IHNwZWNpZmllZCB5IGNvb3JkaW5hdGUgdmFsdWUKKyAgICAgKiBAcmV0dXJuIGEgU2hhcGUgb2JqZWN0IHRoYXQgaXMgdGhlIG91dGxpbmUgb2YgdGhpcyBHbHlwaFZlY3RvcgorICAgICAqIGF0IHRoZSBzcGVjaWZpZWQgY29vcmRpbmF0ZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNoYXBlIGdldE91dGxpbmUoZmxvYXQgeCwgZmxvYXQgeSkgeworICAgICAgICBHZW5lcmFsUGF0aCBncCA9IG5ldyBHZW5lcmFsUGF0aChHZW5lcmFsUGF0aC5XSU5EX0VWRU5fT0REKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLnZlY3Rvci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgR2VuZXJhbFBhdGggb3V0bGluZSA9IChHZW5lcmFsUGF0aClnZXRHbHlwaE91dGxpbmUoaSk7CisKKyAgICAgICAgICAgIC8qIEFwcGx5aW5nIHRyYW5zbGF0aW9uIHRvIGFjdHVhbCB2aXN1YWwgYm91bmRzICovCisgICAgICAgICAgICBvdXRsaW5lLnRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlSW5zdGFuY2UoeCwgeSkpOworICAgICAgICAgICAgZ3AuYXBwZW5kKG91dGxpbmUsIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBncDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgU2hhcGUgdGhhdCBpcyB0aGUgb3V0bGluZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYSBTaGFwZSBvYmplY3QgdGhhdCBpcyB0aGUgb3V0bGluZSBvZiB0aGlzIEdseXBoVmVjdG9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNoYXBlIGdldE91dGxpbmUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmdldE91dGxpbmUoMCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBnbHlwaGNvZGVzIGZvciB0aGUgc3BlY2lmaWVkIGdseXBocy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYmVnaW5HbHlwaEluZGV4IHRoZSBzdGFydCBpbmRleAorICAgICAqIEBwYXJhbSBudW1FbnRyaWVzIHRoZSBudW1iZXIgb2YgZ2x5cGggY29kZXMgdG8gZ2V0CisgICAgICogQHBhcmFtIGNvZGVSZXR1cm4gdGhlIGFycmF5IHRoYXQgcmVjZWl2ZXMgZ2x5cGggY29kZXMnIHZhbHVlcworICAgICAqIEByZXR1cm4gYW4gYXJyYXkgdGhhdCByZWNlaXZlcyBnbHlwaCBjb2RlcycgdmFsdWVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldEdseXBoQ29kZXMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsCisgICAgICAgICAgICBpbnRbXSBjb2RlUmV0dXJuKSB7CisKKyAgICAgICAgaWYgKChiZWdpbkdseXBoSW5kZXggPCAwKSB8fCAoKG51bUVudHJpZXMgKyBiZWdpbkdseXBoSW5kZXgpID4gdGhpcy5nZXROdW1HbHlwaHMoKSkpIHsKKyAgICAgICAgICAgIC8vIGF3dC40ND1iZWdpbkdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIHJhbmdlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG51bUVudHJpZXMgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuNDU9bnVtRW50cmllcyBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb2RlUmV0dXJuID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvZGVSZXR1cm4gPSBuZXcgaW50W251bUVudHJpZXNdOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGJlZ2luR2x5cGhJbmRleDsgaSA8IGJlZ2luR2x5cGhJbmRleCArIG51bUVudHJpZXM7IGkrKykgeworICAgICAgICAgICAgY29kZVJldHVybltpLWJlZ2luR2x5cGhJbmRleF0gPSB0aGlzLnZlY3RvcltpXS5nZXRHbHlwaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb2RlUmV0dXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbnVtRW50cmllcyBjaGFyYWN0ZXIgaW5kaWNlcyBmb3IgdGhlIHNwZWNpZmllZCBnbHlwaHMuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZ2luR2x5cGhJbmRleCB0aGUgc3RhcnQgaW5kZXgKKyAgICAgKiBAcGFyYW0gbnVtRW50cmllcyB0aGUgbnVtYmVyIG9mIGdseXBoIGNvZGVzIHRvIGdldAorICAgICAqIEBwYXJhbSBjb2RlUmV0dXJuIHRoZSBhcnJheSB0aGF0IHJlY2VpdmVzIGdseXBoIGNvZGVzJyB2YWx1ZXMKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IHRoYXQgcmVjZWl2ZXMgZ2x5cGggY2hhciBpbmRpY2VzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludFtdIGdldEdseXBoQ2hhckluZGljZXMoaW50IGJlZ2luR2x5cGhJbmRleCwgaW50IG51bUVudHJpZXMsCisgICAgICAgICAgICBpbnRbXSBjb2RlUmV0dXJuKSB7CisgICAgICAgIGlmICgoYmVnaW5HbHlwaEluZGV4IDwgMCkgfHwgKGJlZ2luR2x5cGhJbmRleCA+PSB0aGlzLmdldE51bUdseXBocygpKSkgeworICAgICAgICAgICAgLy8gYXd0LjQ0PWJlZ2luR2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDQiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmICgobnVtRW50cmllcyA8IDApCisgICAgICAgICAgICAgICAgfHwgKChudW1FbnRyaWVzICsgYmVnaW5HbHlwaEluZGV4KSA+IHRoaXMuZ2V0TnVtR2x5cGhzKCkpKSB7CisgICAgICAgICAgICAvLyBhd3QuNDU9bnVtRW50cmllcyBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb2RlUmV0dXJuID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvZGVSZXR1cm4gPSBuZXcgaW50W251bUVudHJpZXNdOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbnRyaWVzOyBpKyspIHsKKyAgICAgICAgICAgIGNvZGVSZXR1cm5baV0gPSB0aGlzLmdldEdseXBoQ2hhckluZGV4KGkgKyBiZWdpbkdseXBoSW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb2RlUmV0dXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbnVtRW50cmllcyBnbHlwaHMgcG9zaXRpb25zIGZyb20gYmVnaW5HbHlwaEluZGV4CisgICAgICogZ2x5cGggaW4gR2x5cGggVmVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBiZWdpbkdseXBoSW5kZXggdGhlIHN0YXJ0IGluZGV4CisgICAgICogQHBhcmFtIG51bUVudHJpZXMgdGhlIG51bWJlciBvZiBnbHlwaCBjb2RlcyB0byBnZXQKKyAgICAgKiBAcGFyYW0gcG9zaXRpb25SZXR1cm4gdGhlIGFycmF5IHRoYXQgcmVjZWl2ZXMgZ2x5cGhzJyBwb3NpdGlvbnMKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGZsb2F0cyB0aGF0IHJlY2VpdmVzIGdseXBoIGNoYXIgaW5kaWNlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdFtdIGdldEdseXBoUG9zaXRpb25zKGludCBiZWdpbkdseXBoSW5kZXgsIGludCBudW1FbnRyaWVzLAorICAgICAgICAgICAgZmxvYXRbXSBwb3NpdGlvblJldHVybikgeworCisgICAgICAgIGludCBsZW4gPSAodGhpcy5nZXROdW1HbHlwaHMoKSsxKSA8PCAxOworICAgICAgICBiZWdpbkdseXBoSW5kZXggKj0gMjsKKyAgICAgICAgbnVtRW50cmllcyAqPSAyOworCisgICAgICAgIGlmICgoYmVnaW5HbHlwaEluZGV4IDwgMCkgfHwgKChudW1FbnRyaWVzICsgYmVnaW5HbHlwaEluZGV4KSA+IGxlbikpIHsKKyAgICAgICAgICAgIC8vIGF3dC40ND1iZWdpbkdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIHJhbmdlCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40NCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG51bUVudHJpZXMgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuNDU9bnVtRW50cmllcyBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDUiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwb3NpdGlvblJldHVybiA9PSBudWxsKSB7CisgICAgICAgICAgICBwb3NpdGlvblJldHVybiA9IG5ldyBmbG9hdFtudW1FbnRyaWVzXTsKKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmlzdWFsUG9zaXRpb25zLCBiZWdpbkdseXBoSW5kZXgsIHBvc2l0aW9uUmV0dXJuLCAwLCBudW1FbnRyaWVzKTsKKworICAgICAgICByZXR1cm4gcG9zaXRpb25SZXR1cm47CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IG51bUVudHJpZXMgZWxlbWVudHMgb2YgdGhlIHZpc3VhbFBvc2l0aW9ucyBhcnJheSBmcm9tIGJlZ2luR2x5cGhJbmRleAorICAgICAqIG9mIG51bUVudHJpZXMgZ2x5cGhzIHBvc2l0aW9ucyBmcm9tIGJlZ2luR2x5cGhJbmRleCBnbHlwaCBpbiBHbHlwaCBWZWN0b3IuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZ2luR2x5cGhJbmRleCB0aGUgc3RhcnQgaW5kZXgKKyAgICAgKiBAcGFyYW0gbnVtRW50cmllcyB0aGUgbnVtYmVyIG9mIGdseXBoIGNvZGVzIHRvIGdldAorICAgICAqIEBwYXJhbSBzZXRQb3NpdGlvbnMgdGhlIGFycmF5IG9mIHBvc2l0aW9ucyB0byBzZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRHbHlwaFBvc2l0aW9ucyhpbnQgYmVnaW5HbHlwaEluZGV4LCBpbnQgbnVtRW50cmllcywKKyAgICAgICAgICAgIGZsb2F0W10gc2V0UG9zaXRpb25zKSB7CisKKyAgICAgICAgaW50IGxlbiA9ICh0aGlzLmdldE51bUdseXBocygpKzEpIDw8IDE7CisgICAgICAgIGJlZ2luR2x5cGhJbmRleCAqPSAyOworICAgICAgICBudW1FbnRyaWVzICo9IDI7CisKKyAgICAgICAgaWYgKChiZWdpbkdseXBoSW5kZXggPCAwKSB8fCAoKG51bUVudHJpZXMgKyBiZWdpbkdseXBoSW5kZXgpID4gbGVuKSkgeworICAgICAgICAgICAgLy8gYXd0LjQ0PWJlZ2luR2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQ0IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAobnVtRW50cmllcyA8IDApIHsKKyAgICAgICAgICAgIC8vIGF3dC40NT1udW1FbnRyaWVzIGlzIG91dCBvZiB2ZWN0b3IncyByYW5nZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40NSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZXRQb3NpdGlvbnMsIDAsIHZpc3VhbFBvc2l0aW9ucywgYmVnaW5HbHlwaEluZGV4LCBudW1FbnRyaWVzKTsKKyAgICAgICAgbGF5b3V0RmxhZ3MgPSBsYXlvdXRGbGFncyAmIEZMQUdfSEFTX1BPU0lUSU9OX0FESlVTVE1FTlRTOworCisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGVsZW1lbnRzIG9mIHRoZSB2aXN1YWxQb3NpdGlvbnMgYXJyYXkuCisgICAgICogCisgICAgICogQHBhcmFtIHNldFBvc2l0aW9ucyB0aGUgYXJyYXkgb2YgcG9zaXRpb25zIHRvIHNldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdseXBoUG9zaXRpb25zKGZsb2F0W10gc2V0UG9zaXRpb25zKSB7CisKKyAgICAgICAgaW50IGxlbiA9ICh0aGlzLmdldE51bUdseXBocygpKzEpIDw8IDE7CisgICAgICAgIGlmIChsZW4gIT0gc2V0UG9zaXRpb25zLmxlbmd0aCl7CisgICAgICAgICAgICAvLyBhd3QuNDY9bGVuZ3RoIG9mIHNldFBvc2l0aW9ucyBhcnJheSBkaWZmZXJzIGZyb20gdGhlIGxlbmd0aCBvZiBwb3NpdGlvbnMgYXJyYXkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDYiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2V0UG9zaXRpb25zLCAwLCB2aXN1YWxQb3NpdGlvbnMsIDAsIGxlbik7CisgICAgICAgIGxheW91dEZsYWdzID0gbGF5b3V0RmxhZ3MgJiBGTEFHX0hBU19QT1NJVElPTl9BREpVU1RNRU5UUzsKKworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyBnbHlwaCBjb2RlIG9mIHRoZSBzcGVjaWZpZWQgZ2x5cGguCisgICAgICogCisgICAgICogQHBhcmFtIGdseXBoSW5kZXggc3BlY2lmaWVkIGluZGV4IG9mIHRoZSBnbHlwaAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0R2x5cGhDb2RlKGludCBnbHlwaEluZGV4KSB7CisgICAgICAgIGlmIChnbHlwaEluZGV4ID49IHRoaXMudmVjdG9yLmxlbmd0aCB8fCBnbHlwaEluZGV4IDwgMCkgeworICAgICAgICAgICAgLy8gYXd0LjQzPWdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIGxpbWl0cworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuNDMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy52ZWN0b3JbZ2x5cGhJbmRleF0uZ2V0R2x5cGhDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBjaGFyYWN0ZXIgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBnbHlwaC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZ2x5cGhJbmRleCBzcGVjaWZpZWQgaW5kZXggb2YgdGhlIGdseXBoCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRHbHlwaENoYXJJbmRleChpbnQgZ2x5cGhJbmRleCkgeworCisgICAgICAgIGlmICgoZ2x5cGhJbmRleCA8IDApIHx8IChnbHlwaEluZGV4ID49IHRoaXMuZ2V0TnVtR2x5cGhzKCkpKSB7CisgICAgICAgICAgICAvLyBhd3QuNDM9Z2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgbGltaXRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQzIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICBpZiAoKHRoaXMubGF5b3V0RmxhZ3MgJiBGb250LkxBWU9VVF9SSUdIVF9UT19MRUZUKSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5jaGFyVmVjdG9yLmxlbmd0aCAtIGdseXBoSW5kZXggLSAxOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGdseXBoSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNoYXJhY3RlciB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGdseXBoLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4IHNwZWNpZmllZCBpbmRleCBvZiB0aGUgZ2x5cGgKKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRHbHlwaENoYXIoaW50IGdseXBoSW5kZXgpIHsKKworICAgICAgICBpZiAoKGdseXBoSW5kZXggPCAwKSB8fCAoZ2x5cGhJbmRleCA+PSB0aGlzLmdldE51bUdseXBocygpKSkgeworICAgICAgICAgICAgLy8gYXd0LjQzPWdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIGxpbWl0cworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzLmNoYXJWZWN0b3JbZ2x5cGhJbmRleF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzaWducyBkZWZhdWx0IHBvc2l0aW9ucyB0byBlYWNoIGdseXBoIGluIHRoaXMgR2x5cGhWZWN0b3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGVyZm9ybURlZmF1bHRMYXlvdXQoKSB7CisKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb2dpY2FsUG9zaXRpb25zLCAwLCB2aXN1YWxQb3NpdGlvbnMsIDAsIGxvZ2ljYWxQb3NpdGlvbnMubGVuZ3RoKTsKKworICAgICAgICAvLyBTZXQgcG9zaXRpb24gY2hhbmdlcyBmbGFnIHRvIHplcm8KKyAgICAgICAgY2xlYXJMYXlvdXRGbGFncyhHbHlwaFZlY3Rvci5GTEFHX0hBU19QT1NJVElPTl9BREpVU1RNRU5UUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGdseXBocyBpbiB0aGlzIEdseXBoIFZlY3RvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TnVtR2x5cGhzKCkgeworICAgICAgICByZXR1cm4gdmVjdG9yLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGlzIEdseXBoVmVjdG9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldExvZ2ljYWxCb3VuZHMoKXsKKyAgICAgICAgLy8gWFhYOiBmb3IgdHJhbnNmb3JtcyB3aGVyZSBhbiBhbmdsZSBiZXR3ZWVuIGJhc2lzIHZlY3RvcnMgaXMgbm90IDkwIGRlZ3JlZXMKKyAgICAgICAgLy8gUmVjdGFubGdlMkQgY2xhc3MgZG9lc24ndCBmaXQgYXMgTG9naWNhbCBib3VuZHMuIEZvciB0aGlzIHJlYXNvbiB3ZSB1c2UKKyAgICAgICAgLy8gb25seSBub24tdHJhbnNmb3JtZWQgYm91bmRzISEKKworICAgICAgICBmbG9hdCB4ID0gdmlzdWFsUG9zaXRpb25zWzBdOworICAgICAgICBmbG9hdCB3aWR0aCA9IHZpc3VhbFBvc2l0aW9uc1t2aXN1YWxQb3NpdGlvbnMubGVuZ3RoLTJdOworCisgICAgICAgIGRvdWJsZSBzY2FsZVkgPSAgdHJhbnNmb3JtLmdldFNjYWxlWSgpOworCisgICAgICAgIFJlY3RhbmdsZTJEIGJvdW5kcyA9IG5ldyBSZWN0YW5nbGUyRC5GbG9hdCh4LCAoZmxvYXQpKCgtdGhpcy5hc2NlbnQtdGhpcy5sZWFkaW5nKSpzY2FsZVkpLCB3aWR0aCwgKGZsb2F0KSh0aGlzLmhlaWdodCpzY2FsZVkpKTsKKyAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIEdseXBoVmVjdG9yIGVxdWFscyB0byB0aGlzIEdseXBoVmVjdG9yLgorICAgICAqIEBwYXJhbSBnbHlwaFZlY3RvciBHbHlwaFZlY3RvciBvYmplY3QgdG8gY29tcGFyZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhHbHlwaFZlY3RvciBnbHlwaFZlY3Rvcil7CisgICAgICAgIGlmIChnbHlwaFZlY3RvciA9PSB0aGlzKXsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGdseXBoVmVjdG9yICE9IG51bGwpIHsKKworICAgICAgICAgICAgaWYgKCEoZ2x5cGhWZWN0b3IuZ2V0Rm9udFJlbmRlckNvbnRleHQoKS5lcXVhbHModGhpcy52ZWN0b3JGUkMpICYmCisgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhWZWN0b3IuZ2V0Rm9udCgpLmVxdWFscyh0aGlzLmZvbnQpKSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gZXEgPSB0cnVlOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0TnVtR2x5cGhzKCk7IGkrKykgeworCisgICAgICAgICAgICAgICAgICAgIGludCBpZHggPSBpKjI7CisgICAgICAgICAgICAgICAgICAgIGVxID0gKCgoQ29tbW9uR2x5cGhWZWN0b3IpZ2x5cGhWZWN0b3IpLnZpc3VhbFBvc2l0aW9uc1tpZHhdID09IHRoaXMudmlzdWFsUG9zaXRpb25zW2lkeF0pICYmCisgICAgICAgICAgICAgICAgICAgICAgICAoKChDb21tb25HbHlwaFZlY3RvcilnbHlwaFZlY3RvcikudmlzdWFsUG9zaXRpb25zW2lkeCsxXSA9PSB0aGlzLnZpc3VhbFBvc2l0aW9uc1tpZHgrMV0pICYmCisgICAgICAgICAgICAgICAgICAgICAgICAoZ2x5cGhWZWN0b3IuZ2V0R2x5cGhDaGFySW5kZXgoaSkgPT0gdGhpcy5nZXRHbHlwaENoYXJJbmRleChpKSk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVxKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0cmFucyA9IGdseXBoVmVjdG9yLmdldEdseXBoVHJhbnNmb3JtKGkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zID09IG51bGwpeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVxID0gKHRoaXMuZ2xzVHJhbnNmb3Jtc1tpXSA9PSBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVxID0gdGhpcy5nbHNUcmFuc2Zvcm1zW2ldLmVxdWFscyh0cmFucyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoIWVxKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldHVybiAgZXE7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyBmbGFncyBkZXNjcmliaW5nIHRoZSBzdGF0ZSBvZiB0aGUgR2x5cGhWZWN0b3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRMYXlvdXRGbGFncygpIHsKKyAgICAgICAgcmV0dXJuIGxheW91dEZsYWdzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgY2hhciB3aXRoIHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogCisgICAgICogQHBhcmFtIGluZGV4IHNwZWNpZmllZCBpbmRleCBvZiB0aGUgY2hhcgorICAgICAqIAorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldENoYXIoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiB0aGlzLmNoYXJWZWN0b3JbaW5kZXhdOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXIgZGVzaXJlZCBmbGFncyBpbiBsYXlvdXQgZmxhZ3MgZGVzY3JpYmluZyB0aGUgc3RhdGUuIAorICAgICAqIAorICAgICAqIEBwYXJhbSBjbGVhckZsYWdzIGZsYWdzIG1hc2sgdG8gY2xlYXIgCisgICAgICovCisgICAgCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFyTGF5b3V0RmxhZ3MoaW50IGNsZWFyRmxhZ3MpeworICAgICAgICBsYXlvdXRGbGFncyAmPSB+Y2xlYXJGbGFnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2dpY2FsIGJvdW5kcyBvZiB0aGUgc3BlY2lmaWVkIGdseXBoIHdpdGhpbiB0aGlzIENvbW1vbkdseXBoVmVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSBnbHlwaEluZGV4IGluZGV4IG9mIHRoZSBnbHlwaCB0byBnZXQgaXQncyBsb2dpY2FsIGJvdW5kcworICAgICAqIEByZXR1cm4gbG9naWNhbCBib3VuZHMgb2YgdGhlIHNwZWNpZmllZCBnbHlwaAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaGFwZSBnZXRHbHlwaExvZ2ljYWxCb3VuZHMoaW50IGdseXBoSW5kZXgpeworICAgICAgICBpZiAoKGdseXBoSW5kZXggPCAwKSB8fCAoZ2x5cGhJbmRleCA+PSB0aGlzLmdldE51bUdseXBocygpKSl7CisgICAgICAgICAgICAvLyBhd3QuNDM9Z2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgbGltaXRzCisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC40MyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIEdseXBoIGdseXBoID0gdGhpcy52ZWN0b3JbZ2x5cGhJbmRleF07CisKKyAgICAgICAgZmxvYXQgeDAgPSB2aXN1YWxQb3NpdGlvbnNbZ2x5cGhJbmRleCoyXTsKKyAgICAgICAgZmxvYXQgeTAgPSB2aXN1YWxQb3NpdGlvbnNbZ2x5cGhJbmRleCoyKzFdOworICAgICAgICBmbG9hdCBhZHZhbmNlWCA9IGdseXBoLmdldEdseXBoUG9pbnRNZXRyaWNzKCkuZ2V0QWR2YW5jZVgoKTsKKworICAgICAgICBHZW5lcmFsUGF0aCBncCA9IG5ldyBHZW5lcmFsUGF0aCgpOworICAgICAgICBncC5tb3ZlVG8oMCwgLWFzY2VudCAtIGxlYWRpbmcpOworICAgICAgICBncC5saW5lVG8oYWR2YW5jZVggLC1hc2NlbnQgLSBsZWFkaW5nKTsKKyAgICAgICAgZ3AubGluZVRvKGFkdmFuY2VYLCBkZXNjZW50KTsKKyAgICAgICAgZ3AubGluZVRvKDAsIGRlc2NlbnQpOworICAgICAgICBncC5saW5lVG8oMCwgLWFzY2VudCAtIGxlYWRpbmcpOworICAgICAgICBncC5jbG9zZVBhdGgoKTsKKworICAgICAgICAvKiBBcHBseWluZyBHbHlwaFZlY3RvciBmb250IHRyYW5zZm9ybSAqLworICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gYXQgPSAoQWZmaW5lVHJhbnNmb3JtKXRoaXMudHJhbnNmb3JtLmNsb25lKCk7CisKKyAgICAgICAgLyogQXBwbHlpbmcgR2x5cGggdHJhbnNmb3JtICovCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBnbHlwaFRyYW5zZm9ybSA9IGdldEdseXBoVHJhbnNmb3JtKGdseXBoSW5kZXgpOworICAgICAgICBpZiAoZ2x5cGhUcmFuc2Zvcm0gIT0gbnVsbCl7CisgICAgICAgICAgICBhdC5jb25jYXRlbmF0ZShnbHlwaFRyYW5zZm9ybSk7CisgICAgICAgIH0KKworICAgICAgICAvKiBBcHBseWluZyB0cmFuc2xhdGlvbiB0byBhY3R1YWwgdmlzdWFsIGJvdW5kcyAqLworICAgICAgICBhdC5wcmVDb25jYXRlbmF0ZShBZmZpbmVUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlSW5zdGFuY2UoeDAsIHkwKSk7CisgICAgICAgIGdwLnRyYW5zZm9ybShhdCk7CisgICAgICAgIHJldHVybiBncDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBGb250IHBhcmFtZXRlciBvZiB0aGlzIEdseXBoVmVjdG9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbnQgZ2V0Rm9udCgpeworICAgICAgICByZXR1cm4gdGhpcy5mb250OworICAgIH0KKworCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Db21wb3NpdGVGb250LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0NvbXBvc2l0ZUZvbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MGNiMzM0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Db21wb3NpdGVGb250LmphdmEKQEAgLTAsMCArMSw0ODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LkZvbnRSZW5kZXJDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LmZvbnQuTGluZU1ldHJpY3M7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250UGVlckltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkZvbnRQcm9wZXJ0eTsKKworLyoqCisgKiBDb21wb3NpdGVGb250IGNsYXNzIGlzIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBsb2dpY2FsIGZvbnQgY2xhc3Nlcy4gCisgKiBFdmVyeSBsb2dpY2FsIGZvbnQgY29uc2lzdHMgb2Ygc2V2ZXJhbCBwaHlzaWNhbCBmb250cyB0aGF0IGRlc2NyaWJlZCAKKyAqIGluIGZvbnQucHJvcGVydGllcyBmaWxlIGFjY29yZGluZyB0byB0aGUgZmFjZSBuYW1lIG9mIHRoaXMgbG9naWNhbCBmb250LgorICovCitwdWJsaWMgY2xhc3MgQ29tcG9zaXRlRm9udCBleHRlbmRzIEZvbnRQZWVySW1wbHsKKyAgICAKKyAgICAvLyBhIG51bWJlciBvZiBwaHlzaWNhbCBmb250cyB0aGF0IENvbXBvc2l0ZUZvbnQgY29uc2lzdCBvZiAKKyAgICBpbnQgbnVtRm9udHM7CisKKyAgICAvLyBmb250IGZhbWlseSBuYW1lCisgICAgU3RyaW5nIGZhbWlseTsKKworICAgIC8vIGZvbnQgZmFjZSBuYW1lCisgICAgU3RyaW5nIGZhY2U7CisKKyAgICBTdHJpbmdbXSBmb250TmFtZXM7CisgICAgCisgICAgLy8gYW4gYXJyYXkgb2YgZm9udCBwcm9wZXJ0aWVzIGFwcGxpY2FibGUgdG8gdGhpcyBDb21wb3NpdGVGb250CisgICAgRm9udFByb3BlcnR5W10gZm9udFByb3BlcnRpZXM7CisgICAgCisgICAgLy8gYW4gYXJyYXkgb2YgZm9udCBwZWVycyBhcHBsaWNhYmxlIHRvIHRoaXMgQ29tcG9zaXRlRm9udAorICAgIHB1YmxpYyBGb250UGVlckltcGxbXSBmUGh5c2ljYWxGb250czsKKyAgICAKKyAgICAvLyBtaXNzaW5nIGdseXBoIGNvZGUgZmllbGQKKyAgICBpbnQgbWlzc2luZ0dseXBoQ29kZSA9IC0xOworICAgIAorICAgIC8vIGxpbmUgbWV0cmljcyBvZiB0aGlzIGZvbnQKKyAgICBMaW5lTWV0cmljc0ltcGwgbmxtID0gbnVsbDsKKyAgICAKKyAgICAvLyBjYWNoZWQgbnVtIGdseXBocyBwYXJhbWV0ZXIgb2YgdGhpcyBmb250IHRoYXQgaXMgdGhlIHN1bSBvZiBudW0gZ2x5cGhzIG9mIAorICAgIC8vIGZvbnQgcGVlcnMgY29tcG9zaW5nIHRoaXMgZm9udAorICAgIGludCBjYWNoZWROdW1HbHlwaHMgPSAtMTsKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIENvbXBvc2l0ZUZvbnQgb2JqZWN0IHRoYXQgaXMgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGxvZ2ljYWwgCisgICAgICogZmFtaWx5IG5hbWUuCisgICAgICogCisgICAgICogQHBhcmFtIGZhbWlseU5hbWUgbG9naWNhbCBmYW1pbHkgbmFtZSBDb21wb3NpdGVGb250IGlzIHRvIGJlIGNyZWF0ZWQgZnJvbQorICAgICAqIEBwYXJhbSBmYWNlTmFtZSBsb2dpY2FsIGZhY2UgbmFtZSBDb21wb3NpdGVGb250IGlzIHRvIGJlIGNyZWF0ZWQgZnJvbQorICAgICAqIEBwYXJhbSBfc3R5bGUgc3R5bGUgb2YgdGhlIENvbXBvc2l0ZUZvbnQgdG8gYmUgY3JlYXRlZAorICAgICAqIEBwYXJhbSBfc2l6ZSBzaXplIG9mIHRoZSBDb21wb3NpdGVGb250IHRvIGJlIGNyZWF0ZWQgCisgICAgICogQHBhcmFtIGZQcm9wZXJ0aWVzIGFuIGFycmF5IG9mIEZvbnRQcm9wZXJ0aWVzIGRlc2NyaWJpbmcgcGh5c2ljYWwgZm9udHMgLSAKKyAgICAgKiBwYXJ0cyBvZiBsb2dpY2FsIGZvbnQKKyAgICAgKiBAcGFyYW0gcGh5c0ZvbnRzIGFuIGFycmF5IG9mIHBoeXNpY2FsIGZvbnQgcGVlcnMgcmVsYXRlZCB0byB0aGUgQ29tcG9zaXRlRm9udAorICAgICAqIHRvIGJlIGNyZWF0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcG9zaXRlRm9udChTdHJpbmcgZmFtaWx5TmFtZSwgU3RyaW5nIGZhY2VOYW1lLCBpbnQgX3N0eWxlLCBpbnQgX3NpemUsIEZvbnRQcm9wZXJ0eVtdIGZQcm9wZXJ0aWVzLCBGb250UGVlckltcGxbXSBwaHlzRm9udHMpeworICAgICAgICB0aGlzLnNpemUgPSBfc2l6ZTsKKyAgICAgICAgdGhpcy5uYW1lID0gZmFjZU5hbWU7CisgICAgICAgIHRoaXMuZmFtaWx5ID0gZmFtaWx5TmFtZTsKKyAgICAgICAgdGhpcy5zdHlsZSA9IF9zdHlsZTsKKyAgICAgICAgdGhpcy5mYWNlID0gZmFjZU5hbWU7CisgICAgICAgIHRoaXMucHNOYW1lID0gZmFjZU5hbWU7CisgICAgICAgIHRoaXMuZm9udFByb3BlcnRpZXMgPSBmUHJvcGVydGllczsvLyAhISBTdXBwb3NlZCB0aGF0IGZQcm9wZXJ0aWVzIHBhcmFtZXRlciAhPSBudWxsCisgICAgICAgIGZQaHlzaWNhbEZvbnRzID0gcGh5c0ZvbnRzOworICAgICAgICBudW1Gb250cyA9IGZQaHlzaWNhbEZvbnRzLmxlbmd0aDsgCisgICAgICAgIHNldERlZmF1bHRMaW5lTWV0cmljcygiIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgdGhpcy51bmlmb3JtTE0gPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgRm9udFBlZXIgaW4gYXJyYXkgb2YgcGh5c2ljYWwgZm9udHMgdGhhdCBpcyBhcHBsaWNhYmxlIAorICAgICAqIGZvciB0aGUgZ2l2ZW4gY2hhcmFjdGVyLiBUaGlzIGZvbnQgaGFzIHRvIGhhdmUgdGhlIGhpZ2hlc3QgcHJpb3JpdHkgYW1vbmcgZm9udHMKKyAgICAgKiB0aGF0IGNhbiBkaXNwbGF5IHRoaXMgY2hhcmFjdGVyIGFuZCBkb24ndCBoYXZlIGV4Y2x1c2lvbiByYW5nZSBjb3ZlcmluZyAKKyAgICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiB0aGVyZSBpcyBubyBkZXNpcmVkIGZvbnRzIC0xIGlzIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaHIgc3BlY2lmaWVkIGNoYXJhY3RlcgorICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIGZvbnQgZnJvbSB0aGUgYXJyYXkgb2YgcGh5c2ljYWwgZm9udHMgdGhhdCB3aWxsIGJlIHVzZWQgCisgICAgICogZHVyaW5nIHByb2Nlc3Npbmcgb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q2hhckZvbnRJbmRleChjaGFyIGNocil7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtRm9udHM7IGkrKyl7CisgICAgICAgICAgICBpZiAoZm9udFByb3BlcnRpZXNbaV0uaXNDaGFyRXhjbHVkZWQoY2hyKSl7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZlBoeXNpY2FsRm9udHNbaV0uY2FuRGlzcGxheShjaHIpKXsKKyAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgRm9udFBlZXIgaW4gYXJyYXkgb2YgcGh5c2ljYWwgZm9udHMgdGhhdCBpcyBhcHBsaWNhYmxlIAorICAgICAqIGZvciB0aGUgZ2l2ZW4gY2hhcmFjdGVyLiBUaGlzIGZvbnQgaGFzIHRvIGhhdmUgdGhlIGhpZ2hlc3QgcHJpb3JpdHkgYW1vbmcgZm9udHMKKyAgICAgKiB0aGF0IGNhbiBkaXNwbGF5IHRoaXMgY2hhcmFjdGVyIGFuZCBkb24ndCBoYXZlIGV4Y2x1c2lvbiByYW5nZSBjb3ZlcmluZyAKKyAgICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiB0aGVyZSBpcyBubyBkZXNpcmVkIGZvbnRzIGRlZmF1bHQgdmFsdWUgaXMgcmV0dXJuZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGNociBzcGVjaWZpZWQgY2hhcmFjdGVyCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBkZWZhdWx0IGluZGV4IHRoYXQgaXMgcmV0dXJuZWQgaWYgdGhlIG5lY2Vzc2FyeSBmb250IGNvdWxkbid0IGJlIGZvdW5kLgorICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIGZvbnQgZnJvbSB0aGUgYXJyYXkgb2YgcGh5c2ljYWwgZm9udHMgdGhhdCB3aWxsIGJlIHVzZWQgCisgICAgICogZHVyaW5nIHByb2Nlc3Npbmcgb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuIAorICAgICAqLworICAgICBwdWJsaWMgaW50IGdldENoYXJGb250SW5kZXgoY2hhciBjaHIsIGludCBkZWZhdWx0VmFsdWUpeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUZvbnRzOyBpKyspeworICAgICAgICAgICAgaWYgKGZvbnRQcm9wZXJ0aWVzW2ldLmlzQ2hhckV4Y2x1ZGVkKGNocikpeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZQaHlzaWNhbEZvbnRzW2ldLmNhbkRpc3BsYXkoY2hyKSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBvbmUgb2YgdGhlIHBoeXNpY2FsIGZvbnRzIGNvbXBvc2luZyB0aGlzIGZvbnQgQ29tcG9zaXRlRm9udCAKKyAgICAgKiBjYW4gZGlzcGxheSBzcGVjaWZpZWQgY2hhcmFjdGVyLgorICAgICAqICAgCisgICAgICogQHBhcmFtIGNociBzcGVjaWZpZWQgY2hhcmFjdGVyCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuRGlzcGxheShjaGFyIGNocil7CisgICAgICAgIHJldHVybiAoZ2V0Q2hhckZvbnRJbmRleChjaHIpICE9IC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGxvZ2ljYWwgYXNjZW50IChpbiBwaXhlbHMpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRBc2NlbnQoKXsKKyAgICAgICAgcmV0dXJuIG5sbS5nZXRMb2dpY2FsQXNjZW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBMaW5lTWV0cmljcyBpbnN0YW5jZSBzY2FsZWQgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgdHJhbnNmb3JtLiAgCisgICAgICogCisgICAgICogQHBhcmFtIHN0ciBzcGVjaWZpZWQgU3RyaW5nIAorICAgICAqIEBwYXJhbSBmcmMgc3BlY2lmaWVkIEZvbnRSZW5kZXJDb250ZXh0IAorICAgICAqIEBwYXJhbSBhdCBzcGVjaWZpZWQgQWZmaW5lVHJhbnNmb3JtCisgICAgICovCisgICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMaW5lTWV0cmljcyBnZXRMaW5lTWV0cmljcyhTdHJpbmcgc3RyLCBGb250UmVuZGVyQ29udGV4dCBmcmMgLCBBZmZpbmVUcmFuc2Zvcm0gYXQpeworICAgICAgICBMaW5lTWV0cmljc0ltcGwgbG0gPSAoTGluZU1ldHJpY3NJbXBsKSh0aGlzLm5sbS5jbG9uZSgpKTsKKyAgICAgICAgbG0uc2V0TnVtQ2hhcnMoc3RyLmxlbmd0aCgpKTsKKworICAgICAgICBpZiAoKGF0ICE9IG51bGwpICYmICghYXQuaXNJZGVudGl0eSgpKSl7CisgICAgICAgICAgICBsbS5zY2FsZSgoZmxvYXQpYXQuZ2V0U2NhbGVYKCksIChmbG9hdClhdC5nZXRTY2FsZVkoKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBjYWNoZWQgTGluZU1ldHJpY3MgaW5zdGFuY2UgZm9yIHRoZSBudWxsIHN0cmluZyBvciBjcmVhdGVzIGl0IGlmCisgICAgICogaXQgd2Fzbid0IGNhY2hlZCB5ZXQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExpbmVNZXRyaWNzIGdldExpbmVNZXRyaWNzKCl7CisgICAgICAgIGlmIChubG0gPT0gbnVsbCl7CisgICAgICAgICAgICBzZXREZWZhdWx0TGluZU1ldHJpY3MoIiIsIG51bGwpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdGhpcy5ubG07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBMaW5lTWV0cmljcyBpbnN0YW5jZSBhbmQgc2V0IGNhY2hlZCBMaW5lTWV0cmljcyBmaWVsZCB0byBpdC4KKyAgICAgKiBDcmVhdGVkIExpbmVNZXRyaWNzIGhhcyBtYXhpbXVtIHZhbHVlcyBvZiB0aGUgaWRpdmlkdWFsIG1ldHJpY3Mgb2YgYWxsCisgICAgICogY29tcG9zaW5nIHBoeXNpY2FsIGZvbnRzLiBJZiB0aGVyZSBpcyBvbmx5IG9uZSBwaHlzaWNhbCBmb250IC0gaXQncyAKKyAgICAgKiBMaW5lTWV0cmljcyBvYmplY3QgaXMgcmV0dXJuZWQuCisgICAgICogCisgICAgICogQHBhcmFtIHN0ciBzcGVjaWZpZWQgU3RyaW5nIAorICAgICAqIEBwYXJhbSBmcmMgc3BlY2lmaWVkIEZvbnRSZW5kZXJDb250ZXh0IAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXREZWZhdWx0TGluZU1ldHJpY3MoU3RyaW5nIHN0ciwgRm9udFJlbmRlckNvbnRleHQgZnJjKXsKKyAgICAgICAgTGluZU1ldHJpY3MgbG0gPSBmUGh5c2ljYWxGb250c1swXS5nZXRMaW5lTWV0cmljcyhzdHIsIGZyYywgbnVsbCk7CisgICAgICAgIGZsb2F0IG1heENoYXJXaWR0aCA9IChmbG9hdClmUGh5c2ljYWxGb250c1swXS5nZXRNYXhDaGFyQm91bmRzKGZyYykuZ2V0V2lkdGgoKTsKKworICAgICAgICBpZiAobnVtRm9udHMgPT0gMSkgeworICAgICAgICAgICAgdGhpcy5ubG0gPSAoTGluZU1ldHJpY3NJbXBsKWxtOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgZmxvYXRbXSBiYXNlbGluZU9mZnNldHMgPSBsbS5nZXRCYXNlbGluZU9mZnNldHMoKTsKKyAgICAgICAgaW50IG51bUNoYXJzID0gc3RyLmxlbmd0aCgpOworCisgICAgICAgIC8vIFhYWDogZGVmYXVsdCB2YWx1ZSAtIGNvbW1vbiBmb3IgYWxsIEZvbnRzCisgICAgICAgIGludCBiYXNlTGluZUluZGV4ID0gbG0uZ2V0QmFzZWxpbmVJbmRleCgpOworCisgICAgICAgIGZsb2F0IG1heFVuZGVybGluZVRoaWNrbmVzcyA9IGxtLmdldFVuZGVybGluZVRoaWNrbmVzcygpOworICAgICAgICBmbG9hdCBtYXhVbmRlcmxpbmVPZmZzZXQgPSBsbS5nZXRVbmRlcmxpbmVPZmZzZXQoKTsKKyAgICAgICAgZmxvYXQgbWF4U3RyaWtldGhyb3VnaFRoaWNrbmVzcyA9IGxtLmdldFN0cmlrZXRocm91Z2hUaGlja25lc3MoKTsKKyAgICAgICAgZmxvYXQgbWluU3RyaWtldGhyb3VnaE9mZnNldCA9IGxtLmdldFN0cmlrZXRocm91Z2hPZmZzZXQoKTsKKyAgICAgICAgZmxvYXQgbWF4TGVhZGluZyA9IGxtLmdldExlYWRpbmcoKTsgIC8vIEV4dGVybmFsIGxlYWRpbmcKKyAgICAgICAgZmxvYXQgbWF4SGVpZ2h0ID0gbG0uZ2V0SGVpZ2h0KCk7ICAgLy8gSGVpZ2h0IG9mIHRoZSBmb250ICggPT0gKGFzY2VudCArIGRlc2NlbnQgKyBsZWFkaW5nKSkKKyAgICAgICAgZmxvYXQgbWF4QXNjZW50ID0gbG0uZ2V0QXNjZW50KCk7ICAgLy8gQXNjZW50IG9mIHRoZSBmb250CisgICAgICAgIGZsb2F0IG1heERlc2NlbnQgPSBsbS5nZXREZXNjZW50KCk7IC8vIERlc2NlbnQgb2YgdGhlIGZvbnQKKworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG51bUZvbnRzOyBpKyspeworICAgICAgICAgICAgbG0gPSBmUGh5c2ljYWxGb250c1tpXS5nZXRMaW5lTWV0cmljcyhzdHIsIGZyYywgbnVsbCk7CisgICAgICAgICAgICBpZiAobWF4VW5kZXJsaW5lVGhpY2tuZXNzIDwgbG0uZ2V0VW5kZXJsaW5lVGhpY2tuZXNzKCkpeworICAgICAgICAgICAgICAgIG1heFVuZGVybGluZVRoaWNrbmVzcyA9IGxtLmdldFVuZGVybGluZVRoaWNrbmVzcygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWF4VW5kZXJsaW5lT2Zmc2V0IDwgbG0uZ2V0VW5kZXJsaW5lT2Zmc2V0KCkpeworICAgICAgICAgICAgICAgIG1heFVuZGVybGluZU9mZnNldCA9IGxtLmdldFVuZGVybGluZU9mZnNldCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWF4U3RyaWtldGhyb3VnaFRoaWNrbmVzcyA8IGxtLmdldFN0cmlrZXRocm91Z2hUaGlja25lc3MoKSl7CisgICAgICAgICAgICAgICAgbWF4U3RyaWtldGhyb3VnaFRoaWNrbmVzcyA9IGxtLmdldFN0cmlrZXRocm91Z2hUaGlja25lc3MoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG1pblN0cmlrZXRocm91Z2hPZmZzZXQgPiBsbS5nZXRTdHJpa2V0aHJvdWdoT2Zmc2V0KCkpeworICAgICAgICAgICAgICAgIG1pblN0cmlrZXRocm91Z2hPZmZzZXQgPSBsbS5nZXRTdHJpa2V0aHJvdWdoT2Zmc2V0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChtYXhMZWFkaW5nIDwgbG0uZ2V0TGVhZGluZygpKXsKKyAgICAgICAgICAgICAgICBtYXhMZWFkaW5nID0gbG0uZ2V0TGVhZGluZygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWF4QXNjZW50IDwgbG0uZ2V0QXNjZW50KCkpeworICAgICAgICAgICAgICAgIG1heEFzY2VudCA9IGxtLmdldEFzY2VudCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobWF4RGVzY2VudCA8IGxtLmdldERlc2NlbnQoKSl7CisgICAgICAgICAgICAgICAgbWF4RGVzY2VudCA9IGxtLmdldERlc2NlbnQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmxvYXQgd2lkdGggPSAoZmxvYXQpZlBoeXNpY2FsRm9udHNbaV0uZ2V0TWF4Q2hhckJvdW5kcyhmcmMpLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpZihtYXhDaGFyV2lkdGggPCB3aWR0aCl7CisgICAgICAgICAgICAgICAgbWF4Q2hhcldpZHRoID0gd2lkdGg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBqID0wOyBqIDwgYmFzZWxpbmVPZmZzZXRzLmxlbmd0aDsgaisrKXsKKyAgICAgICAgICAgICAgICBmbG9hdFtdIG9mZnNldHMgPSBsbS5nZXRCYXNlbGluZU9mZnNldHMoKTsKKyAgICAgICAgICAgICAgICBpZiAoYmFzZWxpbmVPZmZzZXRzW2pdID4gb2Zmc2V0c1tqXSl7CisgICAgICAgICAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0c1tqXSA9IG9mZnNldHNbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICAgICAgbWF4SGVpZ2h0ID0gbWF4QXNjZW50ICsgbWF4RGVzY2VudCArIG1heExlYWRpbmc7CisKKyAgICAgICAgdGhpcy5ubG0gPSAgbmV3IExpbmVNZXRyaWNzSW1wbCgKKyAgICAgICAgICAgICAgICBudW1DaGFycywKKyAgICAgICAgICAgICAgICBiYXNlTGluZUluZGV4LAorICAgICAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0cywKKyAgICAgICAgICAgICAgICBtYXhVbmRlcmxpbmVUaGlja25lc3MsCisgICAgICAgICAgICAgICAgbWF4VW5kZXJsaW5lT2Zmc2V0LAorICAgICAgICAgICAgICAgIG1heFN0cmlrZXRocm91Z2hUaGlja25lc3MsCisgICAgICAgICAgICAgICAgbWluU3RyaWtldGhyb3VnaE9mZnNldCwKKyAgICAgICAgICAgICAgICBtYXhMZWFkaW5nLAorICAgICAgICAgICAgICAgIG1heEhlaWdodCwKKyAgICAgICAgICAgICAgICBtYXhBc2NlbnQsCisgICAgICAgICAgICAgICAgbWF4RGVzY2VudCwKKyAgICAgICAgICAgICAgICBtYXhDaGFyV2lkdGgpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGdseXBocyBpbiB0aGlzIENvbXBvc2l0ZUZvbnQgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TnVtR2x5cGhzKCl7CisgICAgICAgIGlmICh0aGlzLmNhY2hlZE51bUdseXBocyA9PSAtMSl7CisKKyAgICAgICAgICAgIHRoaXMuY2FjaGVkTnVtR2x5cGhzID0gMDsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Gb250czsgaSsrKXsKKyAgICAgICAgICAgICAgICB0aGlzLmNhY2hlZE51bUdseXBocyArPSBmUGh5c2ljYWxGb250c1tpXS5nZXROdW1HbHlwaHMoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0aGlzLmNhY2hlZE51bUdseXBoczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpdGFsaWMgYW5nbGUgb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldEl0YWxpY0FuZ2xlKCl7CisgICAgICAgIC8vICEhIG9ubHkgZmlyc3QgcGh5c2ljYWwgZm9udCB1c2VkIHRvIGdldCB0aGlzIHZhbHVlCisgICAgICAgIHJldHVybiBmUGh5c2ljYWxGb250c1swXS5nZXRJdGFsaWNBbmdsZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcmVjdGFuZ2xlIHRoYXQgYm91bmRzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGluIHRlcm1zIG9mIGNvbXBvc2l0ZSBsaW5lIG1ldHJpY3MuCisgICAgICogCisgICAgICogQHBhcmFtIGNoYXJzIGFuIGFycmF5IG9mIGNoYXJzCisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBpbml0aWFsIG9mZnNldCBpbiBhcnJheSBvZiBjaGFycworICAgICAqIEBwYXJhbSBlbmQgdGhlIGVuZCBvZmZzZXQgaW4gYXJyYXkgb2YgY2hhcnMKKyAgICAgKiBAcGFyYW0gZnJjIHNwZWNpZmllZCBGb250UmVuZGVyQ29udGV4dAorICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUyRCBnZXRTdHJpbmdCb3VuZHMoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBlbmQsIEZvbnRSZW5kZXJDb250ZXh0IGZyYyl7CisKKyAgICAgICAgTGluZU1ldHJpY3MgbG0gPSBnZXRMaW5lTWV0cmljcygpOworICAgICAgICBmbG9hdCBtaW5ZID0gLWxtLmdldEFzY2VudCgpOworICAgICAgICBmbG9hdCBtaW5YID0gMDsKKyAgICAgICAgZmxvYXQgaGVpZ2h0ID0gbG0uZ2V0SGVpZ2h0KCk7CisgICAgICAgIGZsb2F0IHdpZHRoID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKyl7CisgICAgICAgICAgICB3aWR0aCArPSBjaGFyV2lkdGgoY2hhcnNbaV0pOworICAgICAgICB9CisKKyAgICAgICAgUmVjdGFuZ2xlMkQgcmVjdDJEID0gbmV3IFJlY3RhbmdsZTJELkZsb2F0KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQpOworICAgICAgICByZXR1cm4gcmVjdDJEOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBtYXhpbXVtIHJlY3RhbmdsZSB0aGF0IGVuY2xvc2VzIGFsbCBtYXhpbXVtIGNoYXIgYm91bmRzIG9mIAorICAgICAqIHBoeXNpY2FsIGZvbnRzIGNvbXBvc2luZyB0aGlzIENvbXBvc2l0ZUZvbnQuCisgICAgICogIAorICAgICAqIEBwYXJhbSBmcmMgc3BlY2lmaWVkIEZvbnRSZW5kZXJDb250ZXh0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldE1heENoYXJCb3VuZHMoRm9udFJlbmRlckNvbnRleHQgZnJjKXsKKworICAgICAgICBSZWN0YW5nbGUyRCByZWN0MkQgPSBmUGh5c2ljYWxGb250c1swXS5nZXRNYXhDaGFyQm91bmRzKGZyYyk7CisgICAgICAgIGZsb2F0IG1pblkgPSAoZmxvYXQpcmVjdDJELmdldFkoKTsKKyAgICAgICAgZmxvYXQgbWF4V2lkdGggPSAoZmxvYXQpcmVjdDJELmdldFdpZHRoKCk7CisgICAgICAgIGZsb2F0IG1heEhlaWdodCA9IChmbG9hdClyZWN0MkQuZ2V0SGVpZ2h0KCk7CisgICAgICAgIGlmIChudW1Gb250cyA9PSAxKXsKKyAgICAgICAgICAgIHJldHVybiByZWN0MkQ7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG51bUZvbnRzOyBpKyspeworICAgICAgICAgICAgaWYgKGZQaHlzaWNhbEZvbnRzW2ldICE9IG51bGwpeworICAgICAgICAgICAgICAgIHJlY3QyRCA9IGZQaHlzaWNhbEZvbnRzW2ldLmdldE1heENoYXJCb3VuZHMoZnJjKTsKKyAgICAgICAgICAgICAgICBmbG9hdCB5ID0gKGZsb2F0KXJlY3QyRC5nZXRZKCk7CisgICAgICAgICAgICAgICAgZmxvYXQgbVdpZHRoID0gKGZsb2F0KXJlY3QyRC5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGZsb2F0IG1IZWlnaHQgPSAoZmxvYXQpcmVjdDJELmdldEhlaWdodCgpOworICAgICAgICAgICAgICAgIGlmICh5IDwgbWluWSl7CisgICAgICAgICAgICAgICAgICAgIG1pblkgPSB5OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobVdpZHRoID4gbWF4V2lkdGgpeworICAgICAgICAgICAgICAgICAgICBtYXhIZWlnaHQgPSBtV2lkdGg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGlmIChtSGVpZ2h0ID4gbWF4SGVpZ2h0KXsKKyAgICAgICAgICAgICAgICAgICAgbWF4SGVpZ2h0ID0gbUhlaWdodDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZWN0MkQgPSBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoMCwgbWluWSwgbWF4V2lkdGgsIG1heEhlaWdodCk7CisKKyAgICAgICAgcmV0dXJuIHJlY3QyRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZvbnQgbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvbnROYW1lKCl7CisgICAgICAgIHJldHVybiBmYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZm9udCBwb3N0c2NyaXB0IG5hbWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRQU05hbWUoKXsKKyAgICAgICAgcmV0dXJuIHBzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZvbnQgZmFtaWx5IG5hbWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRGYW1pbHkoKXsKKyAgICAgICAgcmV0dXJuIGZhbWlseTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIG9mIHRoZSBtaXNzaW5nIGdseXBoLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TWlzc2luZ0dseXBoQ29kZSgpeworICAgICAgICAvLyAhISBvbmx5IGZpcnN0IHBoeXNpY2FsIGZvbnQgdXNlZCB0byBnZXQgdGhpcyB2YWx1ZQorICAgICAgICByZXR1cm4gZlBoeXNpY2FsRm9udHNbMF0uZ2V0TWlzc2luZ0dseXBoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgR2x5cGggb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGNoIHNwZWNpZmllZCBjaGFyCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEdseXBoIGdldEdseXBoKGNoYXIgY2gpeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUZvbnRzOyBpKyspeworICAgICAgICAgICAgaWYgKGZvbnRQcm9wZXJ0aWVzW2ldLmlzQ2hhckV4Y2x1ZGVkKGNoKSl7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICAvKiBDb250cm9sIHN5bWJvbHMgY29uc2lkZXJlZCB0byBiZSBzdXBwb3J0ZWQgYnkgdGhlIGZvbnQgcGVlciAqLworICAgICAgICAgICAgaWYgKChjaCA8IDB4MjApIHx8IGZQaHlzaWNhbEZvbnRzW2ldLmNhbkRpc3BsYXkoY2gpKXsKKyAgICAgICAgICAgICAgICByZXR1cm4gZlBoeXNpY2FsRm9udHNbaV0uZ2V0R2x5cGgoY2gpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWZhdWx0R2x5cGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdpZHRoIG9mIHRoZSBjaGFyIHdpdGggc3BlY2lmaWVkIGluZGV4LgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmQgc3BlY2lmaWVkIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjaGFyV2lkdGgoaW50IGluZCl7CisgICAgICAgIHJldHVybiBjaGFyV2lkdGgoKGNoYXIpaW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdpZHRoIG9mIHRoZSBzcGVjaWZpZWQgY2hhci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gYyBzcGVjaWZpZWQgY2hhcmFjdGVyIAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgY2hhcldpZHRoKGNoYXIgYyl7CisgICAgICAgIEdseXBoIGdsID0gdGhpcy5nZXRHbHlwaChjKTsKKyAgICAgICAgcmV0dXJuIChpbnQpZ2wuZ2V0R2x5cGhQb2ludE1ldHJpY3MoKS5nZXRBZHZhbmNlWCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZGVidWcgaW5mb3JtYXRpb24gYWJvdXQgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCl7CisgICAgcmV0dXJuIG5ldyBTdHJpbmcodGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArCisgICAgICAgICAgICAiW25hbWU9IiArIHRoaXMubmFtZSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICIsc3R5bGU9IisgdGhpcy5zdHlsZSArIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICIsZnBzPSIgKyB0aGlzLmZvbnRQcm9wZXJ0aWVzICsgIl0iKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBHbHlwaCBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgZGVmYXVsdCBnbHlwaC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR2x5cGggZ2V0RGVmYXVsdEdseXBoKCl7CisgICAgICAgIC8vICEhIG9ubHkgZmlyc3QgcGh5c2ljYWwgZm9udCB1c2VkIHRvIGdldCB0aGlzIHZhbHVlCisgICAgICAgIHJldHVybiBmUGh5c2ljYWxGb250c1swXS5nZXREZWZhdWx0R2x5cGgoKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyBGb250RXh0cmFNZXRyaWNzIG9iamVjdCB3aXRoIGV4dHJhIG1ldHJpY3MKKyAgICAgKiByZWxhdGVkIHRvIHRoaXMgQ29tcG9zaXRlRm9udC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9udEV4dHJhTWV0cmljcyBnZXRFeHRyYU1ldHJpY3MoKXsKKyAgICAgICAgLy8gUmV0dXJucyBGb250RXh0cmFNZXRyaWNzIGluc3RhbnNlIG9mIHRoZSBmaXJzdCBwaHlzaWNhbCAKKyAgICAgICAgLy8gRm9udCBmcm9tIHRoZSBhcnJheSBvZiBmb250cy4KKyAgICAgICAgcmV0dXJuIGZQaHlzaWNhbEZvbnRzWzBdLmdldEV4dHJhTWV0cmljcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc3Bvc2VzIENvbXBvc2l0ZUZvbnQgb2JqZWN0J3MgcmVzb3VyY2VzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CisgICAgICAgIC8vIE5vdGhpbmcgdG8gZGlzcG9zZQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udEV4dHJhTWV0cmljcy5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250RXh0cmFNZXRyaWNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ3YmE2ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udEV4dHJhTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsMTQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKiAKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKKy8qKgorICogRXh0cmEgZm9udCBtZXRyaWNzOiBzdWIvc3VwZXJzY3JpcHRzIHNpemVzLCBvZmZzZXRzLCBhdmVyYWdlIGNoYXIgd2lkdGguCisgKi8KK3B1YmxpYyBjbGFzcyBGb250RXh0cmFNZXRyaWNzIHsKKyAgICAKKyAgICAvKiAhISBTdWJzY3JpcHQvc3VwZXJzY3JpcHQgbWV0cmljcyBhcmUgdW5kZWZpbmVkIGZvciBUeXBlMS4gQXMgYSBwb3NzaWJsZSAKKyAgICAgKiBzb2x1dGlvbiB3ZSBjYW4gdXNlIHZhbHVlcyBmb3IgVHlwZTEsIHRoYXQgYXJlIHByb3BvcnRpb25hdGUgdG8gVHJ1ZVR5cGUKKyAgICAgKiBvbmVzOgorICAgICAqICBTdWJzY3JpcHRTaXplWCA9PSAwLjcgKiBmb250U2l6ZQorICAgICAqICBTdWJzY3JpcHRTaXplWSA9PSAwLjY1ICogZm9udFNpemUKKyAgICAgKiAgU3Vic2NyaXB0T2Zmc2V0WCA9PSAwOworICAgICAqICBTdWJzY3JpcHRPZmZzZXRZID09IDAuMTUgKiBmb250U2l6ZTsKKyAgICAgKiAgU3VwZXJzY3JpcHRTaXplWCA9PSAwLjcgKiBmb250U2l6ZQorICAgICAqICBTdXBlcnNjcmlwdFNpemVZID09IDAuNjUgKiBmb250U2l6ZQorICAgICAqICBTdXBlcnNjcmlwdE9mZnNldFggPT0gMDsKKyAgICAgKiAgU3VwZXJzY3JpcHRPZmZzZXRZID09IDAuNDUgKiBmb250U2l6ZQorICAgICAqICAKKyAgICAgKi8KKyAgICAKKyAgICAvKgorICAgICAqIFRoZSBhdmVyYWdlIHdpZHRoIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGZvbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBsQXZlcmFnZUNoYXJXaWR0aDsKKyAgICAKKyAgICAvKgorICAgICAqIEhvcml6b250YWwgc2l6ZSBmb3Igc3Vic2NyaXB0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGxTdWJzY3JpcHRTaXplWDsKKworICAgIC8qCisgICAgICogVmVydGljYWwgc2l6ZSBmb3Igc3Vic2NyaXB0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGxTdWJzY3JpcHRTaXplWTsgCisgICAgCisgICAgLyoKKyAgICAgKiBIb3Jpem9udGFsIG9mZnNldCBmb3Igc3Vic2NyaXB0cywgdGhlIG9mZnNldCBmcm9tIHRoZSBjaGFyYWN0ZXIgb3JpZ2luIAorICAgICAqIHRvIHRoZSBvcmlnaW4gb2YgdGhlIHN1YnNjcmlwdCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBsU3Vic2NyaXB0T2Zmc2V0WDsgCisKKyAgICAvKgorICAgICAqIFZlcnRpY2FsIG9mZnNldCBmb3Igc3Vic2NyaXB0cywgdGhlIG9mZnNldCBmcm9tIHRoZSBjaGFyYWN0ZXIgb3JpZ2luIAorICAgICAqIHRvIHRoZSBvcmlnaW4gb2YgdGhlIHN1YnNjcmlwdCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBsU3Vic2NyaXB0T2Zmc2V0WTsKKyAgICAKKyAgICAvKgorICAgICAqIEhvcml6b250YWwgc2l6ZSBmb3Igc3VwZXJzY3JpcHRzLgorICAgICAqLworICAgIHByaXZhdGUgZmxvYXQgbFN1cGVyc2NyaXB0U2l6ZVg7IAorCisgICAgLyoKKyAgICAgKiBWZXJ0aWNhbCBzaXplIGZvciBzdXBlcnNjcmlwdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBsU3VwZXJzY3JpcHRTaXplWTsKKyAgICAKKyAgICAvKgorICAgICAqIEhvcml6b250YWwgb2Zmc2V0IGZvciBzdXBlcnNjcmlwdHMsIHRoZSBvZmZzZXQgZnJvbSB0aGUgY2hhcmFjdGVyIAorICAgICAqIGJhc2UgbGluZSB0byB0aGUgYmFzZSBsaW5lIG9mIHRoZSBzdXBlcnNjcmlwdCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmbG9hdCBsU3VwZXJzY3JpcHRPZmZzZXRYOworCisgICAgLyoKKyAgICAgKiBWZXJ0aWNhbCBvZmZzZXQgZm9yIHN1cGVyc2NyaXB0cywgdGhlIG9mZnNldCBmcm9tIHRoZSBjaGFyYWN0ZXIgCisgICAgICogYmFzZSBsaW5lIHRvIHRoZSBiYXNlIGxpbmUgb2YgdGhlIHN1cGVyc2NyaXB0IGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZsb2F0IGxTdXBlcnNjcmlwdE9mZnNldFk7CisgICAgCisgICAgcHVibGljIEZvbnRFeHRyYU1ldHJpY3MoKXsKKyAgICAgICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvcgorICAgIH0KKworICAgIHB1YmxpYyBGb250RXh0cmFNZXRyaWNzKGZsb2F0W10gbWV0cmljcyl7CisgICAgICAgIGxBdmVyYWdlQ2hhcldpZHRoID0gbWV0cmljc1swXTsKKyAgICAgICAgbFN1YnNjcmlwdFNpemVYID0gbWV0cmljc1sxXTsKKyAgICAgICAgbFN1YnNjcmlwdFNpemVZID0gbWV0cmljc1syXTsKKyAgICAgICAgbFN1YnNjcmlwdE9mZnNldFggPSBtZXRyaWNzWzNdOworICAgICAgICBsU3Vic2NyaXB0T2Zmc2V0WSA9IG1ldHJpY3NbNF07CisgICAgICAgIGxTdXBlcnNjcmlwdFNpemVYID0gbWV0cmljc1s1XTsKKyAgICAgICAgbFN1cGVyc2NyaXB0U2l6ZVkgPSBtZXRyaWNzWzZdOworICAgICAgICBsU3VwZXJzY3JpcHRPZmZzZXRYID0gbWV0cmljc1s3XTsKKyAgICAgICAgbFN1cGVyc2NyaXB0T2Zmc2V0WSA9IG1ldHJpY3NbOF07CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldEF2ZXJhZ2VDaGFyV2lkdGgoKXsKKyAgICAgICAgcmV0dXJuIGxBdmVyYWdlQ2hhcldpZHRoOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U3Vic2NyaXB0U2l6ZVgoKXsKKyAgICAgICAgcmV0dXJuIGxTdWJzY3JpcHRTaXplWDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U3Vic2NyaXB0U2l6ZVkoKXsKKyAgICAgICAgcmV0dXJuIGxTdWJzY3JpcHRTaXplWTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U3Vic2NyaXB0T2Zmc2V0WCgpeworICAgICAgICByZXR1cm4gbFN1YnNjcmlwdE9mZnNldFg7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldFN1YnNjcmlwdE9mZnNldFkoKXsKKyAgICAgICAgcmV0dXJuIGxTdWJzY3JpcHRPZmZzZXRZOworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdCBnZXRTdXBlcnNjcmlwdFNpemVYKCl7CisgICAgICAgIHJldHVybiBsU3VwZXJzY3JpcHRTaXplWDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U3VwZXJzY3JpcHRTaXplWSgpeworICAgICAgICByZXR1cm4gbFN1cGVyc2NyaXB0U2l6ZVk7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldFN1cGVyc2NyaXB0T2Zmc2V0WCgpeworICAgICAgICByZXR1cm4gbFN1cGVyc2NyaXB0T2Zmc2V0WDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXQgZ2V0U3VwZXJzY3JpcHRPZmZzZXRZKCl7CisgICAgICAgIHJldHVybiBsU3VwZXJzY3JpcHRPZmZzZXRZOworICAgIH0KKyAgICAKKyAgICAKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udEZpbmRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250RmluZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDliY2Y1YwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udEZpbmRlci5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqCisgKiBAZGF0ZTogSnVsIDEyLCAyMDA1CisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzRW52aXJvbm1lbnQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNob29zZXMgdGhlIGRlZmF1bHQgZm9udCBmb3IgdGhlIGdpdmVuIHRleHQuCisgKiBJZiBpdCBmaW5kcyB0aGUgY2hhcmFjdGVyIHdoaWNoIGN1cnJlbnQgZm9udCBpcyB1bmFibGUgdG8gZGlzcGxheQorICogaXQgc3RhcnRzIHRoZSBuZXh0IGZvbnQgcnVuIGFuZCBsb29rcyBmb3IgdGhlIGZvbnQgd2hpY2ggaXMgYWJsZSB0bworICogZGlzcGxheSB0aGUgY3VycmVudCBjaGFyYWN0ZXIuIEl0IGFsc28gY2FjaGVzIHRoZSBmb250IG1hcHBpbmdzCisgKiAoaW5kZXggaW4gdGhlIGFycmF5IGNvbnRhaW5pbmcgYWxsIGZvbnRzKSBmb3IgdGhlIGNoYXJhY3RlcnMsCisgKiB1c2luZyB0aGF0IGZhY3QgdGhhdCBzY3JpcHRzIGFyZSBtYWlubHkgY29udGlndW91cyBpbiB0aGUgVVRGLTE2IGVuY29kaW5nCisgKiBhbmQgdGhlcmUncyBhIGhpZ2ggcHJvYmFiaWxpdHkgdGhhdCB0aGUgdXBwZXIgYnl0ZSB3aWxsIGJlIHRoZSBzYW1lIGZvciB0aGUKKyAqIG5leHQgY2hhcmFjdGVyIGFzIGZvciB0aGUgcHJldmlvdXMuIFRoaXMgYWxsb3dzIHRvIHNhdmUgdGhlIHNwYWNlIHVzZWQgZm9yIHRoZSBjYWNoZS4KKyAqLworcHVibGljIGNsYXNzIEZvbnRGaW5kZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IERFRkFVTFRfRk9OVF9TSVpFID0gMTI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGb250IGZvbnRzW10gPQorICAgICAgICAgICAgR3JhcGhpY3NFbnZpcm9ubWVudC5nZXRMb2NhbEdyYXBoaWNzRW52aXJvbm1lbnQoKS5nZXRBbGxGb250cygpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9CTE9DS1MgPSAyNTY7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMT0NLX1NJWkUgPSAyNTY7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX01BU0sgPSAweEZGOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCTE9DS19TSElGVCA9IDg7CisKKyAgICAvLyBNYXBzIGNoYXJhY3RlcnMgaW50byB0aGUgZm9udHMgYXJyYXkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgYmxvY2tzW11bXSA9IG5ldyBpbnRbTlVNX0JMT0NLU11bXTsKKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBmb250IHdoaWNoIGlzIGFibGUgdG8gZGlzcGxheSB0aGUgZ2l2ZW4gY2hhcmFjdGVyCisgICAgICogYW5kIHNhdmVzIHRoZSBmb250IG1hcHBpbmcgZm9yIHRoaXMgY2hhcmFjdGVyCisgICAgICogQHBhcmFtIGMgLSBjaGFyYWN0ZXIKKyAgICAgKiBAcmV0dXJuIGZvbnQKKyAgICAgKi8KKyAgICBzdGF0aWMgRm9udCBmaW5kRm9udEZvckNoYXIoY2hhciBjKSB7CisgICAgICAgIGludCBibG9ja051bSA9IGMgPj4gQkxPQ0tfU0hJRlQ7CisgICAgICAgIGludCBpbmRleCA9IGMgJiBJTkRFWF9NQVNLOworCisgICAgICAgIGlmIChibG9ja3NbYmxvY2tOdW1dID09IG51bGwpIHsKKyAgICAgICAgICAgIGJsb2Nrc1tibG9ja051bV0gPSBuZXcgaW50W0JMT0NLX1NJWkVdOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJsb2Nrc1tibG9ja051bV1baW5kZXhdID09IDApIHsKKyAgICAgICAgICAgIGJsb2Nrc1tibG9ja051bV1baW5kZXhdID0gMTsKKworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZvbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGZvbnRzW2ldLmNhbkRpc3BsYXkoYykpIHsKKyAgICAgICAgICAgICAgICAgICAgYmxvY2tzW2Jsb2NrTnVtXVtpbmRleF0gPSBpKzE7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBnZXREZWZhdWx0U2l6ZUZvbnQoYmxvY2tzW2Jsb2NrTnVtXVtpbmRleF0tMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVyaXZlcyB0aGUgZGVmYXVsdCBzaXplIGZvbnQKKyAgICAgKiBAcGFyYW0gaSAtIGluZGV4IGluIHRoZSBhcnJheSBvZiBhbGwgZm9udHMKKyAgICAgKiBAcmV0dXJuIGRlcml2ZWQgZm9udAorICAgICAqLworICAgIHN0YXRpYyBGb250IGdldERlZmF1bHRTaXplRm9udChpbnQgaSkgeworICAgICAgICBpZiAoZm9udHNbaV0uZ2V0U2l6ZSgpICE9IERFRkFVTFRfRk9OVF9TSVpFKSB7CisgICAgICAgICAgICBmb250c1tpXSA9IGZvbnRzW2ldLmRlcml2ZUZvbnQoREVGQVVMVF9GT05UX1NJWkUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZvbnRzW2ldOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2lnbnMgZGVmYXVsdCBmb250cyBmb3IgdGhlIGdpdmVuIHRleHQgcnVuLgorICAgICAqIEZpcnN0IHRocmVlIHBhcmFtZXRlcnMgYXJlIGlucHV0LCBsYXN0IHRocmVlIGFyZSBvdXRwdXQuCisgICAgICogQHBhcmFtIHRleHQgLSBnaXZlbiB0ZXh0CisgICAgICogQHBhcmFtIHJ1blN0YXJ0IC0gc3RhcnQgb2YgdGhlIHRleHQgcnVuCisgICAgICogQHBhcmFtIHJ1bkxpbWl0IC0gZW5kIG9mIHRoZSB0ZXh0IHJ1bgorICAgICAqIEBwYXJhbSBydW5TdGFydHMgLSBzdGFydHMgb2YgdGhlIHJlc3VsdGluZyBmb250IHJ1bnMKKyAgICAgKiBAcGFyYW0gZm9udHMgLSBtYXBwaW5nIG9mIHRoZSBmb250IHJ1biBzdGFydHMgdG8gdGhlIGZvbnRzCisgICAgICovCisgICAgc3RhdGljIHZvaWQgZmluZEZvbnRzKGNoYXIgdGV4dFtdLCBpbnQgcnVuU3RhcnQsIGludCBydW5MaW1pdCwgTGlzdDxJbnRlZ2VyPiBydW5TdGFydHMsCisgICAgICAgICAgICBNYXA8SW50ZWdlciwgRm9udD4gZm9udHMpIHsKKyAgICAgICAgRm9udCBwcmV2Rm9udCA9IG51bGw7CisgICAgICAgIEZvbnQgY3VyckZvbnQ7CisgICAgICAgIGZvciAoaW50IGkgPSBydW5TdGFydDsgaSA8IHJ1bkxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgIGN1cnJGb250ID0gZmluZEZvbnRGb3JDaGFyKHRleHRbaV0pOworICAgICAgICAgICAgaWYgKGN1cnJGb250ICE9IHByZXZGb250KSB7CisgICAgICAgICAgICAgICAgcHJldkZvbnQgPSBjdXJyRm9udDsKKyAgICAgICAgICAgICAgICBJbnRlZ2VyIGlkeCA9IG5ldyBJbnRlZ2VyKGkpOworICAgICAgICAgICAgICAgIGZvbnRzLnB1dChpZHgsIGN1cnJGb250KTsKKyAgICAgICAgICAgICAgICBpZiAoaSAhPSBydW5TdGFydCkgeworICAgICAgICAgICAgICAgICAgICBydW5TdGFydHMuYWRkKGlkeCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250TWFuYWdlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250TWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzNTRlMjUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0ZvbnRNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSw4MTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5Gb250OworaW1wb3J0IGphdmEuYXd0LnBlZXIuRm9udFBlZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5Db21tb25HcmFwaGljczJERmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk5vdEltcGxlbWVudGVkRXhjZXB0aW9uOworCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb250TWFuYWdlciB7CisgICAgCisgICAgLy8/Pz9BV1QKKyAgICBib29sZWFuIE5PVF9JTVAgPSBmYWxzZTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBhcnJheSBvZiBmb250IGZhbWlsaWVzIG5hbWVzCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGFsbEZhbWlsaWVzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9OQU1FID0gIkRlZmF1bHQiOyAvKiBEZWZhdWx0IGZvbnQgbmFtZSAqLyAvLyROT04tTkxTLTEkCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRElBTE9HX05BTUUgPSAiRGlhbG9nIjsgIC8qIERpYWxvZyBmb250IG5hbWUgKi8gLy8kTk9OLU5MUy0xJAorCisgICAgLyoqCisgICAgICogU2V0IG9mIGNvbnN0YW50cyBhcHBsaWNhYmxlIHRvIHRoZSBUcnVlVHlwZSAnbmFtZScgdGFibGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlICBGQU1JTFlfTkFNRV9JRCAgPSAxOyAgICAgIC8qIEZhbWlseSBuYW1lIGlkZW50aWZpZXIgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSAgRk9OVF9OQU1FX0lEICA9IDQ7ICAgICAgICAvKiBGdWxsIGZvbnQgbmFtZSBpZGVudGlmaWVyICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlICBQT1NUU0NSSVBUX05BTUVfSUQgPSA2OyAgIC8qIFBvc3RTY3JpcHQgbmFtZSBpZGVudGlmaWVyICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVOR0xJU0hfTEFOR0lEID0gMHgwNDA5OyAgLyogRW5nbGlzaCAoVW5pdGVkIFN0YXRlcylsYW5ndWFnZSBpZGVudGlmaWVyICAgKi8KKworICAgIC8qKgorICAgICAqIFNldCBvZiBjb25zdGFudHMgZGVzY3JpYmluZyBmb250IHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlICBGT05UX1RZUEVfVFQgID0gNDsgICAgICAgIC8qIFRydWVUeXBlIHR5cGUgKFRSVUVUWVBFX0ZPTlRUWVBFKSAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSAgRk9OVF9UWVBFX1QxICA9IDI7ICAgICAgICAvKiBUeXBlMSB0eXBlICAgIChERVZJQ0VfRk9OVFRZUEUpICAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgIEZPTlRfVFlQRV9VTkRFRiAgPSAwOyAgICAgLyogVW5kZWZpbmVkIHR5cGUgICAgICAgICAgICAgICAgICAgICAgICovCisKKyAgICAvLyBsb2dpY2FsIGZhbWlseSB0eXBlcyAoaW5kaWNlcyBpbiBGb250TWFuYWdlci5MT0dJQ0FMX0ZPTlRfTkFNRVMpCisgICAgc3RhdGljIGZpbmFsIGludCBESUFMT0cgPSAzOyAgICAgICAgLy8gRkZfU1dJU1MKKyAgICBzdGF0aWMgZmluYWwgaW50IFNBTlNTRVJJRiA9IDE7ICAgICAvLyBGRl9TV0lTUworICAgIHN0YXRpYyBmaW5hbCBpbnQgRElBTE9HSU5QVVQgPSA0OyAgIC8vIEZGX01PREVSTgorICAgIHN0YXRpYyBmaW5hbCBpbnQgTU9OT1NQQUNFRCA9IDI7ICAgIC8vIEZGX01PREVSTgorICAgIHN0YXRpYyBmaW5hbCBpbnQgU0VSSUYgPSAwOyAgICAgICAgIC8vIEZGX1JPTUFOCisKKworICAgIC8qKgorICAgICAqIEZvbnRQcm9wZXJ0eSByZWxhdGVkIGNvbnN0YW50cy4gCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUExBVEZPUk1fRk9OVF9OQU1FID0gIlBsYXRmb3JtRm9udE5hbWUiOyAvLyROT04tTkxTLTEkCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9HSUNBTF9GT05UX05BTUUgPSAiTG9naWNhbEZvbnROYW1lIjsgLy8kTk9OLU5MUy0xJAorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTVBPTkVOVF9JTkRFWCA9ICJDb21wb25lbnRJbmRleCI7IC8vJE5PTi1OTFMtMSQKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFlMRV9JTkRFWCA9ICJTdHlsZUluZGV4IjsgLy8kTk9OLU5MUy0xJAorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBGT05UX01BUFBJTkdfS0VZUyA9IHsKKyAgICAgICAgICAgICJMb2dpY2FsRm9udE5hbWUuU3R5bGVOYW1lLkNvbXBvbmVudEluZGV4IiwgIkxvZ2ljYWxGb250TmFtZS5Db21wb25lbnRJbmRleCIgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPTlRfQ0hBUkFDVEVSX0VOQ09ESU5HID0gImZvbnRjaGFyc2V0LkxvZ2ljYWxGb250TmFtZS5Db21wb25lbnRJbmRleCI7IC8vJE5PTi1OTFMtMSQKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVYQ0xVU0lPTl9SQU5HRVMgPSAiZXhjbHVzaW9uLkxvZ2ljYWxGb250TmFtZS5Db21wb25lbnRJbmRleCI7IC8vJE5PTi1OTFMtMSQKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPTlRfRklMRV9OQU1FID0gImZpbGVuYW1lLlBsYXRmb3JtRm9udE5hbWUiOyAvLyROT04tTkxTLTEkCisKKyAgICAvKioKKyAgICAgKiBBdmFpbGFibGUgbG9naWNhbCBmb250IGZhbWlsaWVzIG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gTE9HSUNBTF9GT05UX0ZBTUlMSUVTID0geworICAgICAgICAgICAgIlNlcmlmIiwgIlNhbnNTZXJpZiIsICJNb25vc3BhY2VkIiwgIkRpYWxvZyIsICJEaWFsb2dJbnB1dCIgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgfTsKKworICAgIC8qKgorICAgICAqIEF2YWlsYWJsZSBsb2dpY2FsIGZvbnQgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBMT0dJQ0FMX0ZPTlRfTkFNRVMgPSB7CisgICAgICAgICAgICAic2VyaWYiLCAic2VyaWYucGxhaW4iLCAic2VyaWYuYm9sZCIsICJzZXJpZi5pdGFsaWMiLCAic2VyaWYuYm9sZGl0YWxpYyIsIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQgLy8kTk9OLU5MUy01JAorICAgICAgICAgICAgInNhbnNzZXJpZiIsICJzYW5zc2VyaWYucGxhaW4iLCAic2Fuc3NlcmlmLmJvbGQiLCAic2Fuc3NlcmlmLml0YWxpYyIsICJzYW5zc2VyaWYuYm9sZGl0YWxpYyIsIC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQgLy8kTk9OLU5MUy01JAorICAgICAgICAgICAgIm1vbm9zcGFjZWQiLCAibW9ub3NwYWNlZC5wbGFpbiIsICJtb25vc3BhY2VkLmJvbGQiLCAibW9ub3NwYWNlZC5pdGFsaWMiLCAibW9ub3NwYWNlZC5ib2xkaXRhbGljIiwgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgICAgICAiZGlhbG9nIiwgImRpYWxvZy5wbGFpbiIsICJkaWFsb2cuYm9sZCIsICJkaWFsb2cuaXRhbGljIiwgImRpYWxvZy5ib2xkaXRhbGljIiwgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgICAgICAiZGlhbG9naW5wdXQiLCAiZGlhbG9naW5wdXQucGxhaW4iLCAiZGlhbG9naW5wdXQuYm9sZCIsICJkaWFsb2dpbnB1dC5pdGFsaWMiLCAiZGlhbG9naW5wdXQuYm9sZGl0YWxpYyIgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgfTsKKworICAgIC8qKgorICAgICAqIEF2YWlsYWJsZSBsb2dpY2FsIGZvbnQgZmFjZSBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIExPR0lDQUxfRk9OVF9GQUNFUyA9IHsKKyAgICAgICAgICAgICJTZXJpZiIsICJTZXJpZi5wbGFpbiIsICJTZXJpZi5ib2xkIiwgIlNlcmlmLml0YWxpYyIsICJTZXJpZi5ib2xkaXRhbGljIiwgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgICAgICAiU2Fuc3NlcmlmIiwgIlNhbnNzZXJpZi5wbGFpbiIsICJTYW5zc2VyaWYuYm9sZCIsICJTYW5zc2VyaWYuaXRhbGljIiwgIlNhbnNzZXJpZi5ib2xkaXRhbGljIiwgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgICAgICAiTW9ub3NwYWNlZCIsICJNb25vc3BhY2VkLnBsYWluIiwgIk1vbm9zcGFjZWQuYm9sZCIsICJNb25vc3BhY2VkLml0YWxpYyIsICJNb25vc3BhY2VkLmJvbGRpdGFsaWMiLCAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkIC8vJE5PTi1OTFMtNSQKKyAgICAgICAgICAgICJEaWFsb2ciLCAiRGlhbG9nLnBsYWluIiwgIkRpYWxvZy5ib2xkIiwgIkRpYWxvZy5pdGFsaWMiLCAiRGlhbG9nLmJvbGRpdGFsaWMiLCAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkIC8vJE5PTi1OTFMtNSQKKyAgICAgICAgICAgICJEaWFsb2dpbnB1dCIsICJEaWFsb2dpbnB1dC5wbGFpbiIsICJEaWFsb2dpbnB1dC5ib2xkIiwgIkRpYWxvZ2lucHV0Lml0YWxpYyIsICJEaWFsb2dpbnB1dC5ib2xkaXRhbGljIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkIC8vJE5PTi1OTFMtNSQKKyAgICB9OworCisgICAgLyoqCisgICAgICogU2V0IG9mIGZvbnQgc3R5bGUgbmFtZXMuCisgICAgICogRm9udC5nZXRTdHlsZSgpIGNvcnJlc3BvbmRzIHRvIGluZGV4ZXMgaW4gU1RZTEVfTkFNRVMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBTVFlMRV9OQU1FUyA9IHsKKyAgICAgICAgICAgICJwbGFpbiIsICJib2xkIiwgIml0YWxpYyIsICJib2xkaXRhbGljIiAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJCAvLyROT04tTkxTLTQkCisgICAgfTsKKworICAgIC8qKgorICAgICAqIExvZ2ljYWwgZm9udCBzdHlsZXMgbmFtZXMgdGFibGUgd2hlcmUgZm9udCBzdHlsZXMgbmFtZXMgdXNlZCAKKyAgICAgKiBhcyB0aGUga2V5IGFuZCB0aGUgdmFsdWUgaXMgdGhlIGluZGV4IG9mIHRoaXMgc3R5bGUgbmFtZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNodGFibGU8U3RyaW5nLCBJbnRlZ2VyPiBzdHlsZV9rZXlzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIEludGVnZXI+KDQpOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSBmb250IHN0eWxlcyBrZXlzIHRhYmxlLgorICAgICAqLworICAgIHN0YXRpYyB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU1RZTEVfTkFNRVMubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgc3R5bGVfa2V5cy5wdXQoU1RZTEVfTkFNRVNbaV0sIEludGVnZXIudmFsdWVPZihpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gZm9udCBzdHlsZSBmcm9tIHRoZSBsb2dpY2FsIHN0eWxlIG5hbWUuCisgICAgICogCisgICAgICogQHBhcmFtIGxOYW1lIHN0eWxlIG5hbWUgb2YgdGhlIGxvZ2ljYWwgZmFjZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldExvZ2ljYWxTdHlsZShTdHJpbmcgbE5hbWUpeworICAgICAgICBJbnRlZ2VyIHZhbHVlID0gc3R5bGVfa2V5cy5nZXQobE5hbWUpOworICAgICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCA/IHZhbHVlLmludFZhbHVlKCk6IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBvZiBwb3NzaWJsZSAib3MiIHByb3BlcnR5IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIE9TX1ZBTFVFUyA9IHsKKyAgICAgICAgICAgICJOVCIsICI5OCIsICIyMDAwIiwgIk1lIiwgIlhQIiwgLy8gRm9yIFdpbmRvd3MgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JCAvLyROT04tTkxTLTUkCisgICAgICAgICAgICAiUmVkaGF0IiwgIlR1cmJvIiwgIlN1U0UiICAgICAgIC8vIEZvciBMaW51eCAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBTZXQgb2YgcG9zc2libGUgZm9udC5wcm9wZXJ0eSBmaWxlIG5hbWVzLgorICAgICAqIExhbmd1YWdlLCBDb3VudHJ5LCBFbmNvZGluZywgT1MsIFZlcnNpb24gc2hvdWxkIGJlIHJlcGxhY2VkIHdpdGgKKyAgICAgKiB0aGUgdmFsdWVzIGZyb20gY3VycmVudCBjb25maWd1cmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gRlBfRklMRV9OQU1FUyA9IHsKKyAgICAgICAgICAgICIvbGliL2ZvbnQucHJvcGVydGllcy5MYW5ndWFnZV9Db3VudHJ5X0VuY29kaW5nLk9TVmVyc2lvbiIsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICIvbGliL2ZvbnQucHJvcGVydGllcy5MYW5ndWFnZV9Db3VudHJ5X0VuY29kaW5nLk9TIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0NvdW50cnlfRW5jb2RpbmcuVmVyc2lvbiIsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICIvbGliL2ZvbnQucHJvcGVydGllcy5MYW5ndWFnZV9Db3VudHJ5X0VuY29kaW5nIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0NvdW50cnkuT1NWZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0NvdW50cnkuT1MiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuTGFuZ3VhZ2VfQ291bnRyeS5WZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0NvdW50cnkiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuTGFuZ3VhZ2VfRW5jb2RpbmcuT1NWZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0VuY29kaW5nLk9TIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlX0VuY29kaW5nLlZlcnNpb24iLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuTGFuZ3VhZ2VfRW5jb2RpbmciLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuTGFuZ3VhZ2UuT1NWZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlLk9TIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkxhbmd1YWdlLlZlcnNpb24iLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuTGFuZ3VhZ2UiLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuRW5jb2RpbmcuT1NWZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkVuY29kaW5nLk9TIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLkVuY29kaW5nLlZlcnNpb24iLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuRW5jb2RpbmciLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMuT1NWZXJzaW9uIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLk9TIiwgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgIi9saWIvZm9udC5wcm9wZXJ0aWVzLlZlcnNpb24iLCAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAiL2xpYi9mb250LnByb3BlcnRpZXMiIC8vJE5PTi1OTFMtMSQKKyAgICB9OworCisgICAgLyoqCisgICAgICogVGFibGUgd2l0aCBhbGwgYXZhaWxhYmxlIGZvbnQgcHJvcGVydGllcyBjb3JyZXNwb25kaW5nCisgICAgICogdG8gdGhlIGN1cnJlbnQgc3lzdGVtIGNvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHVibGljIEhhc2h0YWJsZTxTdHJpbmcsIFZlY3RvcjxGb250UHJvcGVydHk+PiBmUHJvcGVydGllcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBWZWN0b3I8Rm9udFByb3BlcnR5Pj4oKTsKKyAgICAKKyAgICBwdWJsaWMgRm9udE1hbmFnZXIoKXsKKyAgICAgICAgYWxsRmFtaWxpZXMgPSBnZXRBbGxGYW1pbGllcygpOworICAgICAgICAvKgorICAgICAgICAgKiBDcmVhdGluZyBhbmQgcmVnaXN0ZXJpbmcgc2h1dGRvd24gaG9vayB0byBmcmVlIHJlc291cmNlcworICAgICAgICAgKiBiZWZvcmUgb2JqZWN0IGlzIGRlc3Ryb3llZC4KKyAgICAgICAgICovCisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8vRGlzcG9zZU5hdGl2ZUhvb2sgc2h1dGRvd25Ib29rID0gbmV3IERpc3Bvc2VOYXRpdmVIb29rKCk7CisgICAgICAgIC8vUnVudGltZS5nZXRSdW50aW1lKCkuYWRkU2h1dGRvd25Ib29rKHNodXRkb3duSG9vayk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWF4aW11bSBudW1iZXIgb2YgdW5yZWZlcmVuY2VkIGZvbnQgcGVlcnMgdG8ga2VlcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTVBUWV9GT05UU19DQVBBQ0lUWSA9IDEwOworCisgICAgLyoqCisgICAgICogTG9jYWxlIC0gTGFuZ3VhZ2UgSUQgaGFzaCB0YWJsZS4KKyAgICAgKi8KKyAgICBIYXNodGFibGU8U3RyaW5nLCBTaG9ydD4gdGFibGVMQ0lEID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFNob3J0PigpOworCisgICAgLyoqCisgICAgICogSGFzaCB0YWJsZSB0aGF0IGNvbnRhaW5zIEZvbnRQZWVycyBpbnN0YW5jZXMuCisgICAgICovCisgICAgcHVibGljIEhhc2h0YWJsZTxTdHJpbmcsIEhhc2hNYXBSZWZlcmVuY2U+IGZvbnRzVGFibGUgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgSGFzaE1hcFJlZmVyZW5jZT4oKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZWZlcmVuY2VRdWV1ZSBmb3IgSGFzaE1hcFJlZmVyZW5jZSBvYmplY3RzIHRvIGNoZWNrCisgICAgICogaWYgdGhleSB3ZXJlIGNvbGxlY3RlZCBieSBnYXJiYWdlIGNvbGxlY3Rvci4gCisgICAgICovCisgICAgcHVibGljIFJlZmVyZW5jZVF1ZXVlPEZvbnRQZWVyPiBxdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxGb250UGVlcj4oKTsKKworICAgIC8qKgorICAgICAqIFNpbmdsZXRvbiBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgRm9udE1hbmFnZXIgaW5zdCA9IENvbW1vbkdyYXBoaWNzMkRGYWN0b3J5Lmluc3QuZ2V0Rm9udE1hbmFnZXIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgc2luZ2xldG9uIGluc3RhbmNlIG9mIEZvbnRNYW5hZ2VyCisgICAgICogCisgICAgICogQHJldHVybiBpbnN0YW5jZSBvZiBGb250TWFuYWdlciBpbXBsZW1lbnRhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRm9udE1hbmFnZXIgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBpbnN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcGxhdGZvcm0tZGVwZW5kZW50IEZvbnQgcGVlciBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCAKKyAgICAgKiBGb250IG9iamVjdCBmcm9tIHRoZSB0YWJsZSB3aXRoIGNhY2hlZCBGb250UGVlcnMgaW5zdGFuY2VzLgorICAgICAqIAorICAgICAqIE5vdGUsIHRoaXMgbWV0aG9kIGNoZWNrcyB3aGV0aGVyIEZvbnRQZWVyIHdpdGggc3BlY2lmaWVkIHBhcmFtZXRlcnMgCisgICAgICogZXhpc3RzIGluIHRoZSB0YWJsZSB3aXRoIGNhY2hlZCBGb250UGVlcnMnIGluc3RhbmNlcy4gSWYgdGhlcmUgaXMgbm8gbmVlZGVkIAorICAgICAqIGluc3RhbmNlIC0gaXQgaXMgY3JlYXRlZCBhbmQgY2FjaGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250TmFtZSBuYW1lIG9mIHRoZSBmb250IAorICAgICAqIEBwYXJhbSBfZm9udFN0eWxlIHN0eWxlIG9mIHRoZSBmb250IAorICAgICAqIEBwYXJhbSBzaXplIGZvbnQgc2l6ZQorICAgICAqIAorICAgICAqIEByZXR1cm4gcGxhdGZvcm0gZGVwZW5kZW50IEZvbnRQZWVyIGltcGxlbWVudGF0aW9uIGNyZWF0ZWQgZnJvbSAKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9udFBlZXIgZ2V0Rm9udFBlZXIoU3RyaW5nIGZvbnROYW1lLCBpbnQgX2ZvbnRTdHlsZSwgaW50IHNpemUpIHsKKyAgICAgICAgdXBkYXRlRm9udHNUYWJsZSgpOworICAgICAgICAKKyAgICAgICAgRm9udFBlZXIgcGVlciA9IG51bGw7CisgICAgICAgIFN0cmluZyBrZXk7IAorICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgaW50IGZvbnRTdHlsZSA9IF9mb250U3R5bGU7CisgICAgICAgIAorICAgICAgICBpbnQgbG9naWNhbEluZGV4ID0gZ2V0TG9naWNhbEZhY2VJbmRleChmb250TmFtZSk7CisgICAgICAgIAorICAgICAgICBpZiAobG9naWNhbEluZGV4ICE9IC0xKXsKKyAgICAgICAgICAgIG5hbWUgPSBnZXRMb2dpY2FsRmFjZUZyb21Gb250KGZvbnRTdHlsZSwgbG9naWNhbEluZGV4KTsKKyAgICAgICAgICAgIGZvbnRTdHlsZSA9IGdldFN0eWxlRnJvbUxvZ2ljYWxGYWNlKG5hbWUpOworICAgICAgICAgICAga2V5ID0gbmFtZS5jb25jYXQoU3RyaW5nLnZhbHVlT2Yoc2l6ZSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmFtZSA9IGZvbnROYW1lOworICAgICAgICAgICAga2V5ID0gbmFtZS5jb25jYXQoU3RyaW5nLnZhbHVlT2YoZm9udFN0eWxlKSkuCisgICAgICAgICAgICAgICAgICAgIGNvbmNhdChTdHJpbmcudmFsdWVPZihzaXplKSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIEhhc2hNYXBSZWZlcmVuY2UgaG1yICAgPSBmb250c1RhYmxlLmdldChrZXkpOworICAgICAgICBpZiAoaG1yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBlZXIgPSBobXIuZ2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGVlciA9PSBudWxsKSB7CisgICAgICAgICAgICBwZWVyID0gY3JlYXRlRm9udFBlZXIobmFtZSwgZm9udFN0eWxlLCBzaXplLCBsb2dpY2FsSW5kZXgpOworICAgICAgICAgICAgaWYgKHBlZXIgPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgcGVlciA9IGdldEZvbnRQZWVyKERJQUxPR19OQU1FLCBmb250U3R5bGUsIHNpemUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9udHNUYWJsZS5wdXQoa2V5LCBuZXcgSGFzaE1hcFJlZmVyZW5jZShrZXksIHBlZXIsIHF1ZXVlKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGVlcjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyBpbnN0YW5jZSBvZiBmb250IHBlZXIgKGxvZ2ljYWwgb3IgcGh5c2ljYWwpIGFjY29yZGluZyB0byB0aGUgCisgICAgICogc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogCisgICAgICogQHBhcmFtIG5hbWUgZm9udCBmYWNlIG5hbWUKKyAgICAgKiBAcGFyYW0gc3R5bGUgc3R5bGUgb2YgdGhlIGZvbnQKKyAgICAgKiBAcGFyYW0gc2l6ZSBzaXplIG9mIHRoZSBmb250CisgICAgICogQHBhcmFtIGxvZ2ljYWxJbmRleCBpbmRleCBvZiB0aGUgbG9naWNhbCBmYWNlIG5hbWUgaW4gTE9HSUNBTF9GT05UX0ZBQ0VTIAorICAgICAqIGFycmF5IG9yIC0xIGlmIGRlc2lyZWQgZm9udCBwZWVyIGlzIG5vdCBsb2dpY2FsLgorICAgICAqLworICAgIHByaXZhdGUgRm9udFBlZXIgY3JlYXRlRm9udFBlZXIoU3RyaW5nIG5hbWUsIGludCBzdHlsZSwgaW50IHNpemUsIGludCBsb2dpY2FsSW5kZXgpeworICAgICAgICBGb250UGVlciBwZWVyOworICAgICAgICBpZiAobG9naWNhbEluZGV4ICE9IC0xKXsKKyAgICAgICAgICAgIHBlZXIgPSBjcmVhdGVMb2dpY2FsRm9udFBlZXIobmFtZSwgc3R5bGUsIHNpemUpOworICAgICAgICB9ZWxzZSB7CisgICAgICAgICAgICBwZWVyID0gY3JlYXRlUGh5c2ljYWxGb250UGVlcihuYW1lLCBzdHlsZSwgc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIHJldHVybiBwZWVyOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZhbWlseSBuYW1lIGZvciBsb2dpY2FsIGZhY2UgbmFtZXMgYXMgYSBwYXJhbWV0ZXIuCisgICAgICogCisgICAgICogQHBhcmFtIGZhY2VOYW1lIGxvZ2ljYWwgZm9udCBmYWNlIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhbWlseUZyb21Mb2dpY2FsRmFjZShTdHJpbmcgZmFjZU5hbWUpeworICAgICAgICBpbnQgcG9zID0gZmFjZU5hbWUuaW5kZXhPZigiLiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGlmIChwb3MgPT0gLTEpeworICAgICAgICAgICAgcmV0dXJuIGZhY2VOYW1lOworICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgcmV0dXJuIGZhY2VOYW1lLnN1YnN0cmluZygwLCBwb3MpOworICAgIH0KKyAgICAgICAgICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgbmV3IGxvZ2ljYWwgZm9udCBwZWVyIGZvciB0aGUgcGFyYW1ldGVycyBzcGVjaWZpZWQgdXNpbmcgZm9udCAKKyAgICAgKiBwcm9wZXJ0aWVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmYWNlTmFtZSBmYWNlIG5hbWUgb2YgdGhlIGxvZ2ljYWwgZm9udCAKKyAgICAgKiBAcGFyYW0gc3R5bGUgc3R5bGUgb2YgdGhlIGZvbnQgCisgICAgICogQHBhcmFtIHNpemUgZm9udCBzaXplCisgICAgICogCisgICAgICovCisgICAgcHJpdmF0ZSBGb250UGVlciBjcmVhdGVMb2dpY2FsRm9udFBlZXIoU3RyaW5nIGZhY2VOYW1lLCBpbnQgc3R5bGUsIGludCBzaXplKXsKKyAgICAgICAgU3RyaW5nIGZhbWlseSA9IGdldEZhbWlseUZyb21Mb2dpY2FsRmFjZShmYWNlTmFtZSk7CisgICAgICAgIEZvbnRQcm9wZXJ0eVtdIGZwcyA9IGdldEZvbnRQcm9wZXJ0aWVzKGZhbWlseS50b0xvd2VyQ2FzZSgpICsgIi4iICsgc3R5bGUpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGlmIChmcHMgIT0gbnVsbCl7CisgICAgICAgICAgICBpbnQgbnVtRm9udHMgPSBmcHMubGVuZ3RoOworICAgICAgICAgICAgRm9udFBlZXJJbXBsW10gcGh5c2ljYWxGb250cyA9IG5ldyBGb250UGVlckltcGxbbnVtRm9udHNdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Gb250czsgaSsrKXsKKyAgICAgICAgICAgICAgICBGb250UHJvcGVydHkgZnAgPSBmcHNbaV07CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmcC5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgaW50IGZwU3R5bGUgPSBmcC5nZXRTdHlsZSgpOworICAgICAgICAgICAgICAgIFN0cmluZyBrZXkgPSBuYW1lLmNvbmNhdChTdHJpbmcudmFsdWVPZihmcFN0eWxlKSkuCisgICAgICAgICAgICAgICAgICAgIGNvbmNhdChTdHJpbmcudmFsdWVPZihzaXplKSk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgSGFzaE1hcFJlZmVyZW5jZSBobXIgICA9IGZvbnRzVGFibGUuZ2V0KGtleSk7CisgICAgICAgICAgICAgICAgaWYgKGhtciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHBoeXNpY2FsRm9udHNbaV0gPSAoRm9udFBlZXJJbXBsKWhtci5nZXQoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAocGh5c2ljYWxGb250c1tpXSA9PSBudWxsKXsKKyAgICAgICAgICAgICAgICAgICAgcGh5c2ljYWxGb250c1tpXSA9IChGb250UGVlckltcGwpY3JlYXRlUGh5c2ljYWxGb250UGVlcihuYW1lLCBmcFN0eWxlLCBzaXplKTsKKyAgICAgICAgICAgICAgICAgICAgZm9udHNUYWJsZS5wdXQoa2V5LCBuZXcgSGFzaE1hcFJlZmVyZW5jZShrZXksIHBoeXNpY2FsRm9udHNbaV0sIHF1ZXVlKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKHBoeXNpY2FsRm9udHNbaV0gPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgICAgIHBoeXNpY2FsRm9udHNbaV0gPSAoRm9udFBlZXJJbXBsKWdldERlZmF1bHRGb250KHN0eWxlLCBzaXplKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZUZvbnQoZmFtaWx5LCBmYWNlTmFtZSwgc3R5bGUsIHNpemUsIGZwcywgcGh5c2ljYWxGb250cyk7IAorICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBwcm9wZXJ0eSBmb3IgdGhpcyBsb2dpY2FsIGZvbnQgLSBkZWZhdWx0IGZvbnQgaXMgdG8gYmUKKyAgICAgICAgLy8gY3JlYXRlZAorICAgICAgICBGb250UGVlckltcGwgcGVlciA9IChGb250UGVlckltcGwpZ2V0RGVmYXVsdEZvbnQoc3R5bGUsIHNpemUpOworICAgICAgICAKKyAgICAgICAgcmV0dXJuIHBlZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBuZXcgcGh5c2ljYWwgZm9udCBwZWVyIGZvciB0aGUgcGFyYW1ldGVycyBzcGVjaWZpZWQgdXNpbmcgZm9udCBwcm9wZXJ0aWVzCisgICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMgaW1wbGVtZW50YXRpb25zLgorICAgICAqICAKKyAgICAgKiBAcGFyYW0gZmFjZU5hbWUgZmFjZSBuYW1lIG9yIGZhbWlseSBuYW1lIG9mIHRoZSBmb250IAorICAgICAqIEBwYXJhbSBzdHlsZSBzdHlsZSBvZiB0aGUgZm9udCAKKyAgICAgKiBAcGFyYW0gc2l6ZSBmb250IHNpemUKKyAgICAgKiAKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRm9udFBlZXIgY3JlYXRlUGh5c2ljYWxGb250UGVlcihTdHJpbmcgbmFtZSwgaW50IHN0eWxlLCBpbnQgc2l6ZSk7CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyBkZWZhdWx0IGZvbnQgcGVlciBjbGFzcyB3aXRoICJEZWZhdWx0IiBuYW1lIHRoYXQgaXMgdXN1YWxseSAKKyAgICAgKiB1c2VkIHdoZW4gZm9udCB3aXRoIHNwZWNpZmllZCBmb250IG5hbWVzIGFuZCBzdHlsZSBkb2Vzbid0IGV4c2lzdCAKKyAgICAgKiBvbiBhIHN5c3RlbS4gCisgICAgICogCisgICAgICogQHBhcmFtIHN0eWxlIHN0eWxlIG9mIHRoZSBmb250CisgICAgICogQHBhcmFtIHNpemUgc2l6ZSBvZiB0aGUgZm9udAorICAgICAqLworICAgIHB1YmxpYyBGb250UGVlciBnZXREZWZhdWx0Rm9udChpbnQgc3R5bGUsIGludCBzaXplKXsKKyAgICAgICAgdXBkYXRlRm9udHNUYWJsZSgpOworICAgICAgICAKKyAgICAgICAgRm9udFBlZXIgcGVlciA9IG51bGw7CisgICAgICAgIFN0cmluZyBrZXkgPSBERUZBVUxUX05BTUUuY29uY2F0KFN0cmluZy52YWx1ZU9mKHN0eWxlKSkuCisgICAgICAgICAgICAgICAgICAgIGNvbmNhdChTdHJpbmcudmFsdWVPZihzaXplKSk7CisgICAgICAgIAorICAgICAgICBIYXNoTWFwUmVmZXJlbmNlIGhtciAgID0gZm9udHNUYWJsZS5nZXQoa2V5KTsKKyAgICAgICAgaWYgKGhtciAhPSBudWxsKSB7CisgICAgICAgICAgICBwZWVyID0gaG1yLmdldCgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBlZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcGVlciA9IGNyZWF0ZURlZmF1bHRGb250KHN0eWxlLCBzaXplKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgKChGb250UGVlckltcGwpcGVlcikuc2V0RmFtaWx5KERFRkFVTFRfTkFNRSk7CisgICAgICAgICAgICAoKEZvbnRQZWVySW1wbClwZWVyKS5zZXRQU05hbWUoREVGQVVMVF9OQU1FKTsKKyAgICAgICAgICAgICgoRm9udFBlZXJJbXBsKXBlZXIpLnNldEZvbnROYW1lKERFRkFVTFRfTkFNRSk7CisKKyAgICAgICAgICAgIGZvbnRzVGFibGUucHV0KGtleSwgbmV3IEhhc2hNYXBSZWZlcmVuY2Uoa2V5LCBwZWVyLCBxdWV1ZSkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBlZXI7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIAorICAgICAqIFJldHVybnMgbmV3IGRlZmF1bHQgZm9udCBwZWVyIHdpdGggIkRlZmF1bHQiIG5hbWUgZm9yIHRoZSBwYXJhbWV0ZXJzIAorICAgICAqIHNwZWNpZmllZC4gVGhpcyBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMgaW1wbGVtZW50YXRpb25zLgorICAgICAqICAKKyAgICAgKiBAcGFyYW0gc3R5bGUgc3R5bGUgb2YgdGhlIGZvbnQKKyAgICAgKiBAcGFyYW0gc2l6ZSBzaXplIG9mIHRoZSBmb250CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZvbnRQZWVyIGNyZWF0ZURlZmF1bHRGb250KGludCBzdHlsZSwgaW50IHNpemUpOworICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgZmFjZSBuYW1lIG9mIHRoZSBsb2dpY2FsIGZvbnQsIHdoaWNoIGlzIHRoZSByZXN1bHQKKyAgICAgKiBvZiBzcGVjaWZpZWQgZm9udCBzdHlsZSBhbmQgZmFjZSBzdHlsZSB1bmlvbi4gICAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZm9udFN0eWxlIHNwZWNpZmllZCBzdHlsZSBvZiB0aGUgZm9udAorICAgICAqIEBwYXJhbSBsb2dpY2FsSW5kZXggaW5kZXggb2YgdGhlIHNwZWNpZmllZCBmYWNlIGZyb20gdGhlIAorICAgICAqIExPR0lDQUxfRk9OVF9GQUNFUyBhcnJheQorICAgICAqIEByZXR1cm4gcmVzdWx0aW5nIGZhY2UgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9naWNhbEZhY2VGcm9tRm9udChpbnQgZm9udFN0eWxlLCBpbnQgbG9naWNhbEluZGV4KXsKKyAgICAgICAgaW50IHN0eWxlID0gMDsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBMT0dJQ0FMX0ZPTlRfRkFDRVNbbG9naWNhbEluZGV4XTsKKyAgICAgICAgaW50IHBvcyA9IG5hbWUuaW5kZXhPZigiLiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIAorICAgICAgICBpZiAocG9zID09IC0xKXsKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVMb2dpY2FsRmFjZShuYW1lLCBmb250U3R5bGUpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBTdHJpbmcgc3R5bGVOYW1lID0gbmFtZS5zdWJzdHJpbmcocG9zKzEpOworICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMCwgcG9zKTsKKyAgICAgICAgCisgICAgICAgIC8vIGFwcGVuZGluZyBmb250IHN0eWxlIHRvIHRoZSBmYWNlIHN0eWxlCisgICAgICAgIHN0eWxlID0gZm9udFN0eWxlIHwgZ2V0TG9naWNhbFN0eWxlKHN0eWxlTmFtZSk7CisgICAgICAgIAorICAgICAgICByZXR1cm4gY3JlYXRlTG9naWNhbEZhY2UobmFtZSwgc3R5bGUpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBGdW5jdGlvbiByZXR1cm5zIHN0eWxlIHZhbHVlIGZyb20gbG9naWNhbCBmYWNlIG5hbWUuCisgICAgICogIAorICAgICAqIEBwYXJhbSBuYW1lIGZhY2UgbmFtZQorICAgICAqIEByZXR1cm4gZm9udCBzdHlsZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3R5bGVGcm9tTG9naWNhbEZhY2UoU3RyaW5nIG5hbWUpeworICAgICAgICBpbnQgc3R5bGU7CisgICAgICAgIGludCBwb3MgPSBuYW1lLmluZGV4T2YoIi4iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAKKyAgICAgICAgaWYgKHBvcyA9PSAtMSl7CisgICAgICAgICAgICByZXR1cm4gRm9udC5QTEFJTjsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgU3RyaW5nIHN0eWxlTmFtZSA9IG5hbWUuc3Vic3RyaW5nKHBvcysxKTsKKyAgICAgICAgCisgICAgICAgIHN0eWxlID0gZ2V0TG9naWNhbFN0eWxlKHN0eWxlTmFtZSk7CisgICAgICAgIAorICAgICAgICByZXR1cm4gc3R5bGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBsb2dpY2FsIGZhY2UgbmFtZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBsb2dpY2FsCisgICAgICogZmFtaWx5IG5hbWUgYW5kIHN0eWxlIG9mIHRoZSBmb250LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmYW1pbHkgZm9udCBmYW1pbHkKKyAgICAgKiBAcGFyYW0gc3R5bGVJbmRleCBpbmRleCBvZiB0aGUgc3R5bGUgbmFtZSBmcm9tIHRoZSBTVFlMRV9OQU1FUyBhcnJheSAKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNyZWF0ZUxvZ2ljYWxGYWNlKFN0cmluZyBmYW1pbHksIGludCBzdHlsZUluZGV4KXsKKyAgICAgICAgcmV0dXJuIGZhbWlseSArICIuIiArIFNUWUxFX05BTUVTW3N0eWxlSW5kZXhdOyAvLyROT04tTkxTLTEkCisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybiBsYW5ndWFnZSBJZCBmcm9tIExDSUQgaGFzaCBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQgbG9jYWxlCisgICAgICogCisgICAgICogQHBhcmFtIGwgc3BlY2lmaWVkIGxvY2FsZQorICAgICAqLworICAgIHB1YmxpYyBTaG9ydCBnZXRMQ0lEKExvY2FsZSBsKXsKKyAgICAgICAgaWYgKHRoaXMudGFibGVMQ0lELnNpemUoKSA9PSAwKXsKKyAgICAgICAgICAgIGluaXRMQ0lEVGFibGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0YWJsZUxDSUQuZ2V0KGwudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGxhdGZvcm0tZGVwZW5kZW50IExDSUQgdGFibGUgaW5pdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBpbml0TENJRFRhYmxlKCk7CisKKyAgICAvKioKKyAgICAgKiBGcmVlaW5nIG5hdGl2ZSByZXNvdXJjZXMuIFRoaXMgaG9vayBpcyB1c2VkIHRvIGF2b2lkIAorICAgICAqIHN1ZGRlbiBhcHBsaWNhdGlvbiBleGl0IGFuZCB0byBmcmVlIHJlc291cmNlcyBjcmVhdGVkIGluIG5hdGl2ZSBjb2RlLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgRGlzcG9zZU5hdGl2ZUhvb2sgZXh0ZW5kcyBUaHJlYWQgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0cnl7CisgICAgICAgICAgICAgICAgLyogRGlzcG9zaW5nIG5hdGl2ZSBmb250IHBlZXIncyByZXNvdXJjZXMgKi8KKyAgICAgICAgICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IGtFbnVtID0gZm9udHNUYWJsZS5rZXlzKCk7CisKKyAgICAgICAgICAgICAgICB3aGlsZShrRW51bS5oYXNNb3JlRWxlbWVudHMoKSl7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCBrZXkgPSBrRW51bS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBIYXNoTWFwUmVmZXJlbmNlIGhtciA9IGZvbnRzVGFibGUucmVtb3ZlKGtleSk7CisgICAgICAgICAgICAgICAgICAgIEZvbnRQZWVySW1wbCBkZWxQZWVyID0gKEZvbnRQZWVySW1wbClobXIuZ2V0KCk7CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBpZiAoKGRlbFBlZXIgIT0gbnVsbCkgJiYgKGRlbFBlZXIuZ2V0Q2xhc3MoKSAhPSBDb21wb3NpdGVGb250LmNsYXNzKSl7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSdzIG5vdGhpbmcgdG8gZGlzcG9zZSBpbiBDb21wb3NpdGVGb250IG9iamVjdHMKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbFBlZXIuZGlzcG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEZpbGUgb2JqZWN0LCBjcmVhdGVkIGluIGEgZGlyZWN0b3J5CisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBTeXN0ZW0sIHdoZXJlIEpWTSBpcyBiZWluZyByYW4uCisgICAgICoKKyAgICAgKiBJbiBMaW51eCBjYXNlIHdlIHVzZSAiLmZvbnRzIiBkaXJlY3RvcnkgKGZvciBmb250Y29uZmlnIHB1cnBvc2UpLAorICAgICAqIHdoZXJlIGZvbnQgZmlsZSBmcm9tIHRoZSBzdHJlYW0gd2lsbCBiZSBzdG9yZWQsIGhlbmNlIGluIExpbnV4Rm9udE1hbmFnZXIgdGhpcworICAgICAqIG1ldGhvZCBpcyBvdmVycmlkZGVuLgorICAgICAqIEluIFdpbmRvd3MgY2FzZSB3ZSB1c2UgV2luZG93cyB0ZW1wIGRpcmVjdG9yeSAoZGVmYXVsdCBpbXBsZW1lbnRhdGlvbikKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldFRlbXBGb250RmlsZSgpdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgICAvLz8/P0FXVAorICAgICAgICAvKgorICAgICAgICBGaWxlIGZvbnRGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiakZvbnQiLCAiLnR0ZiIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgZm9udEZpbGUuZGVsZXRlT25FeGl0KCk7CisKKyAgICAgICAgcmV0dXJuIGZvbnRGaWxlOworICAgICAgICAgKi8KKyAgICAgICAgaWYoTk9UX0lNUCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbigiZ2V0VGVtcEZvbnRGaWxlIG5vdCBJbXBsZW1lbnRlZCIpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEZpbGUgb2JqZWN0IHdpdGggZm9udCBwcm9wZXJ0aWVzLiBJdCdzIG5hbWUgb2J0YWluZWQgdXNpbmcgY3VycmVudCAKKyAgICAgKiBzeXN0ZW0gY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIGFuZCBsb2NhbGUgc2V0dGluZ3MuIElmIG5vIGFwcHJvcHJpYXRlIAorICAgICAqIGZpbGUgaXMgZm91bmQgbWV0aG9kIHJldHVybnMgbnVsbC4gCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGaWxlIGdldEZvbnRQcm9wZXJ0eUZpbGUoKXsKKyAgICAgICAgRmlsZSBmaWxlID0gbnVsbDsKKworICAgICAgICBTdHJpbmcgamF2YUhvbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIExvY2FsZSBsID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgU3RyaW5nIGxhbmd1YWdlID0gbC5nZXRMYW5ndWFnZSgpOworICAgICAgICBTdHJpbmcgY291bnRyeSA9IGwuZ2V0Q291bnRyeSgpOworICAgICAgICBTdHJpbmcgZmlsZUVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIik7IC8vJE5PTi1OTFMtMSQKKworICAgICAgICBTdHJpbmcgb3MgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGludCBpID0gMDsKKworICAgICAgICAvLyBPUyBuYW1lcyBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzIGRvbid0IG1hdGNoCisgICAgICAgIC8vIE9TIGlkZW50aWZpZXJzIHVzZWQgaW4gZm9udC5wcm9wZXJ0eSBmaWxlcworICAgICAgICBmb3IgKDsgaSA8IE9TX1ZBTFVFUy5sZW5ndGg7IGkrKyl7CisgICAgICAgICAgICBpZiAob3MuZW5kc1dpdGgoT1NfVkFMVUVTW2ldKSl7CisgICAgICAgICAgICAgICAgb3MgPSBPU19WQUxVRVNbaV07CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoaSA9PSBPU19WQUxVRVMubGVuZ3RoKXsKKyAgICAgICAgICAgIG9zID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gU3lzdGVtLmdldFByb3BlcnR5KCJvcy52ZXJzaW9uIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgU3RyaW5nIHBhdGhuYW1lOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBGUF9GSUxFX05BTUVTLmxlbmd0aDsgaSsrKXsKKyAgICAgICAgICAgIHBhdGhuYW1lID0gRlBfRklMRV9OQU1FU1tpXTsKKyAgICAgICAgICAgIGlmIChvcyAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICBwYXRobmFtZSA9IHBhdGhuYW1lLnJlcGxhY2VGaXJzdCgiT1MiLCBvcyk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcGF0aG5hbWUgPSBqYXZhSG9tZSArIHBhdGhuYW1lOworCisgICAgICAgICAgICBwYXRobmFtZSA9IHBhdGhuYW1lLnJlcGxhY2VBbGwoIkxhbmd1YWdlIiwgbGFuZ3VhZ2UpLiAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VBbGwoIkNvdW50cnkiLCBjb3VudHJ5KS4gLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlQWxsKCJFbmNvZGluZyIsIGZpbGVFbmNvZGluZykuIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZUFsbCgiVmVyc2lvbiIsIHZlcnNpb24pOyAvLyROT04tTkxTLTEkCisKKyAgICAgICAgICAgIGZpbGUgPSBuZXcgRmlsZShwYXRobmFtZSk7CisKKyAgICAgICAgICAgIGlmIChmaWxlLmV4aXN0cygpKXsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmaWxlLmV4aXN0cygpID8gZmlsZSA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBpbnRlZ2VyIHJhbmdlIHZhbHVlcworICAgICAqIGlmIHRoZSBwYXJhbWV0ZXIgZXhjbHVzaW9uU3RyaW5nIGhhcyBmb3JtYXQ6CisgICAgICogICAgICAgICAgUmFuZ2UKKyAgICAgKiAgICAgICAgICBSYW5nZSBbLCBleGNsdXNpb25TdHJpbmddCisgICAgICoKKyAgICAgKiAgICAgICAgICBSYW5nZToKKyAgICAgKiAgICAgICAgICAgICAgQ2hhci1DaGFyCisgICAgICoKKyAgICAgKiAgICAgICAgICBDaGFyOgorICAgICAqICAgICAgICAgICAgICBIZXhEaWdpdCBIZXhEaWdpdCBIZXhEaWdpdCBIZXhEaWdpdAorICAgICAqIAorICAgICAqIE1ldGhvZCByZXR1cm5zIG51bGwgaWYgdGhlIHNwZWNpZmllZCBzdHJpbmcgaXMgbnVsbC4KKyAgICAgKiAgCisgICAgICogQHBhcmFtIGV4Y2x1c2lvblN0cmluZyBzdHJpbmcgcGFyYW1ldGVyIGluIHNwZWNpZmllZCBmb3JtYXQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludFtdIHBhcnNlSW50ZXJ2YWxzKFN0cmluZyBleGNsdXNpb25TdHJpbmcpeworICAgICAgICBpbnRbXSByZXN1bHRzID0gbnVsbDsKKworICAgICAgICBpZiAoZXhjbHVzaW9uU3RyaW5nID09IG51bGwpeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBpbnRlcnZhbHMgPSBleGNsdXNpb25TdHJpbmcuc3BsaXQoIiwiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGlmIChpbnRlcnZhbHMgIT0gbnVsbCl7CisgICAgICAgICAgICBpbnQgbnVtID0gaW50ZXJ2YWxzLmxlbmd0aDsKKyAgICAgICAgICAgIGlmIChudW0gPiAwKXsKKyAgICAgICAgICAgICAgICByZXN1bHRzID0gbmV3IGludFtpbnRlcnZhbHMubGVuZ3RoIDw8IDFdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50ZXJ2YWxzLmxlbmd0aDsgaSsrKXsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhbmdlc1tdID0gaW50ZXJ2YWxzW2ldLnNwbGl0KCItIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1tpKjJdID0gSW50ZWdlci5wYXJzZUludChyYW5nZXNbMF0sIDE2KTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1tpKjIrMV0gPSBJbnRlZ2VyLnBhcnNlSW50KHJhbmdlc1sxXSwgMTYpOworCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgUHJvcGVydGllcyBmcm9tIHRoZSBwcm9wZXJ0aWVzIGZpbGUgb3IgbnVsbCBpZiAKKyAgICAgKiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIEZpbGVJbnB1dFN0cmVhbSBwcm9jZXNzaW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmaWxlIEZpbGUgb2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvcGVydGllcyBnZXRQcm9wZXJ0aWVzKEZpbGUgZmlsZSl7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBudWxsOworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbnVsbDsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKKyAgICAgICAgICAgIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BzLmxvYWQoZmlzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm9wczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIEZvbnRQcm9wZXJ0aWVzIGZyb20gdGhlIHByb3BlcnRpZXMgZmlsZQorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBuYW1lICJsb2dpY2FsIGZhY2Uuc3R5bGUiLiBFLmcuIAorICAgICAqICJkaWFsb2cuMiIgY29ycmVzcG9uZHMgdG8gdGhlIGZvbnQgZmFtaWx5IERpYWxvZyB3aXRoIGJvbGQgc3R5bGUuIAorICAgICAqCisgICAgICogQHBhcmFtIGZwTmFtZSBrZXkgb2YgdGhlIGZvbnQgcHJvcGVydGllcyBpbiB0aGUgcHJvcGVydGllcyBzZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9udFByb3BlcnR5W10gZ2V0Rm9udFByb3BlcnRpZXMoU3RyaW5nIGZwTmFtZSl7CisgICAgICAgIFZlY3RvcjxGb250UHJvcGVydHk+IHByb3BzID0gZlByb3BlcnRpZXMuZ2V0KGZwTmFtZSk7CisgICAgICAgIAorICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCl7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzaXplID0gIHByb3BzLnNpemUoKTsKKyAgICAgICAgCisgICAgICAgIGlmIChzaXplID09IDApeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBGb250UHJvcGVydHlbXSBmcHMgPSBuZXcgRm9udFByb3BlcnR5W3NpemVdOworICAgICAgICBmb3IgKGludCBpPTA7IGkgPCBmcHMubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgZnBzW2ldID0gcHJvcHMuZWxlbWVudEF0KGkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmcHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBpbmRleCBvZiB0aGUgZm9udCBuYW1lIGluIGFycmF5IG9mIGZvbnQgbmFtZXMgb3IgLTEgaWYgCisgICAgICogdGhpcyBmb250IGlzIG5vdCBsb2dpY2FsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBmb250TmFtZSBzcGVjaWZpZWQgZm9udCBuYW1lCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TG9naWNhbEZhY2VJbmRleChTdHJpbmcgZm9udE5hbWUpeworICAgICAgICBmb3IgKGludCBpPTA7IGk8TE9HSUNBTF9GT05UX05BTUVTLmxlbmd0aDsgaSsrICl7CisgICAgICAgICAgICBpZiAoTE9HSUNBTF9GT05UX05BTUVTW2ldLmVxdWFsc0lnbm9yZUNhc2UoZm9udE5hbWUpKXsKKyAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHNwZWNpZmllZCBmYW1pbHkgbmFtZSBpcyBhdmFpbGFibGUgaW4gdGhpcyAKKyAgICAgKiBHcmFwaGljc0Vudmlyb25tZW50LiAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZmFtaWx5TmFtZSB0aGUgc3BlY2lmaWVkIGZvbnQgZmFtaWx5IG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZhbWlseUV4aXN0KFN0cmluZyBmYW1pbHlOYW1lKXsKKyAgICAgICAgcmV0dXJuIChnZXRGYW1pbHlJbmRleChmYW1pbHlOYW1lKSAhPSAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBpbmRleCBvZiBmYW1pbHkgbmFtZSBmcm9tIHRoZSBhcnJheSBvZiBmYW1pbHkgbmFtZXMgYXZhaWxhYmxlIGluIAorICAgICAqIHRoaXMgR3JhcGhpY3NFbnZpcm9ubWVudCBvciAtMSBpZiBubyBmYW1pbHkgbmFtZSB3YXMgZm91bmQuCisgICAgICogCisgICAgICogQHBhcmFtIGZhbWlseU5hbWUgc3BlY2lmaWVkIGZvbnQgZmFtaWx5IG5hbWUgCisgICAgICovCisgICAgcHVibGljIGludCBnZXRGYW1pbHlJbmRleChTdHJpbmcgZmFtaWx5TmFtZSl7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxhbGxGYW1pbGllcy5sZW5ndGg7IGkrKyApeworICAgICAgICAgICAgaWYgKGZhbWlseU5hbWUuZXF1YWxzSWdub3JlQ2FzZShhbGxGYW1pbGllc1tpXSkpeworICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZhbWlseSB3aXRoIGluZGV4IHNwZWNpZmllZCBmcm9tIHRoZSBhcnJheSBvZiBmYW1pbHkgbmFtZXMgYXZhaWxhYmxlIGluIAorICAgICAqIHRoaXMgR3JhcGhpY3NFbnZpcm9ubWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIGZhbWlseSBpbiBmYW1pbGllcyBuYW1lcyBhcnJheSAKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhbWlseShpbnQgaW5kZXgpeworICAgICAgICByZXR1cm4gYWxsRmFtaWxpZXNbaW5kZXhdOworICAgIH0KKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGluZGV4IG9mIGZhY2UgbmFtZSBmcm9tIHRoZSBhcnJheSBvZiBmYWNlIG5hbWVzIGF2YWlsYWJsZSBpbiAKKyAgICAgKiB0aGlzIEdyYXBoaWNzRW52aXJvbm1lbnQgb3IgLTEgaWYgbm8gZmFjZSBuYW1lIHdhcyBmb3VuZC4gRGVmYXVsdCByZXR1cm4gCisgICAgICogdmFsdWUgaXMgLTEsIG1ldGhvZCBtdXN0IGJlIG92ZXJyaWRkZW4gYnkgRm9udE1hbmFnZXIgaW1wbGVtZW50YXRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGZhY2VOYW1lIGZvbnQgZmFjZSBuYW1lIHdoaWNoIGluZGV4IGlzIHRvIGJlIHNlYXJjaGVkCisgICAgICovCisgICAgcHVibGljIGludCBnZXRGYWNlSW5kZXgoU3RyaW5nIGZhY2VOYW1lKXsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRBbGxGYW1pbGllcygpOworCisgICAgcHVibGljIGFic3RyYWN0IEZvbnRbXSBnZXRBbGxGb250cygpOworICAgIAorICAgIC8qKgorICAgICAqIENsYXNzIGNvbnRhaW5zIFNvZnRSZWZlcmVuY2UgaW5zdGFuY2UgdGhhdCBjYW4gYmUgc3RvcmVkIGluIHRoZSAKKyAgICAgKiBIYXNodGFibGUgYnkgbWVhbnMgb2Yga2V5IGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gaXQuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBIYXNoTWFwUmVmZXJlbmNlIGV4dGVuZHMgU29mdFJlZmVyZW5jZTxGb250UGVlcj4geworICAgICAgICAKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBrZXkgZm9yIEhhc2h0YWJsZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGtleTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBzb2Z0IHJlZmVyZW5jZSB3aXRoIHRoZSBrZXkgc3BlY2lmaWVkIGFuZCAKKyAgICAgICAgICogYWRkaW5nIHRoaXMgcmVmZXJlbmNlIGluIHRoZSByZWZlcmVuY2UgcXVldWUgc3BlY2lmaWVkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgaW4gSGFzaHRhYmxlCisgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBvYmplY3QgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUga2V5CisgICAgICAgICAqIEBwYXJhbSBxdWV1ZSByZWZlcmVuY2UgcXVldWUgd2hlcmUgcmVmZXJlbmNlIGlzIHRvIGJlIGFkZGVkIAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEhhc2hNYXBSZWZlcmVuY2UoZmluYWwgU3RyaW5nIGtleSwgZmluYWwgRm9udFBlZXIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBSZWZlcmVuY2VRdWV1ZTxGb250UGVlcj4gcXVldWUpIHsKKyAgICAgICAgICAgIHN1cGVyKHZhbHVlLCBxdWV1ZSk7CisgICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBrZXkgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgU29mdFJlZmVyZW5jZSBpbnN0YW5jZSAKKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUga2V5IGluIEhhc2h0YWJsZSB3aXRoIGNhY2hlZCByZWZlcmVuY2VzCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGtleXMgZnJvbSB0aGUgSGFzaHRhYmxlIHdpdGggZm9udCBwZWVycyB3aGljaCBjb3JyZXNwb25kaW5nIAorICAgICAqIEhhc2hNYXBSZWZlcmVuY2Ugb2JqZWN0cyB3ZXJlIGdhcmJhZ2UgY29sbGVjdGVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB1cGRhdGVGb250c1RhYmxlKCkgeworICAgICAgICBIYXNoTWFwUmVmZXJlbmNlIHI7CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8vd2hpbGUgKChyID0gKEhhc2hNYXBSZWZlcmVuY2UpcXVldWUucG9sbCgpKSAhPSBudWxsKSB7CisgICAgICAgIC8vICAgIGZvbnRzVGFibGUucmVtb3ZlKHIuZ2V0S2V5KCkpOworICAgICAgICAvL30KKyAgICB9CisKK30KKworCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0ZvbnRNZXRyaWNzSW1wbC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250TWV0cmljc0ltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NzgzMzE3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250TWV0cmljc0ltcGwuamF2YQpAQCAtMCwwICsxLDI4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworaW1wb3J0IGNvbS5hbmRyb2lkLmludGVybmFsLmF3dC5BbmRyb2lkR3JhcGhpY3MyRDsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuRm9udE1ldHJpY3M7CisvL2ltcG9ydCBqYXZhLmF3dC5QYWludDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKKworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuUGFpbnQ7CisKKy8qKgorICogRm9udE1ldHJpY3MgaW1wbGVtZW50YXRpb24KKyAqLworCitwdWJsaWMgY2xhc3MgRm9udE1ldHJpY3NJbXBsIGV4dGVuZHMgRm9udE1ldHJpY3MgeworCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODQ0Njk1NjE1MjAxOTI1MTM4TDsKKworCS8vIGFzY2VudCBvZiB0aGUgZm9udAorCXByaXZhdGUgaW50IGFzY2VudDsKKworCS8vIGRlc2NlbnQgb2YgdGhlIGZvbnQKKwlwcml2YXRlIGludCBkZXNjZW50OworCisJLy8gbGVhZGluZyBvZiB0aGUgZm9udAorCXByaXZhdGUgaW50IGxlYWRpbmc7CisKKwkvLyBtYXhpbXVtIGFzY2VudCBvZiB0aGUgZm9udAorCXByaXZhdGUgaW50IG1heEFzY2VudDsKKworCS8vIG1heGltdW0gZGVzY2VudCBvZiB0aGUgZm9udAorCXByaXZhdGUgaW50IG1heERlc2NlbnQ7CisKKwkvLyBtYXhpbXVtIGFkdmFuY2Ugb2YgdGhlIGZvbnQKKwlwcml2YXRlIGludCBtYXhBZHZhbmNlOworCisJLy8gYXJyYXkgb2YgY2hhciBhZHZhbmNlIHdpZHRocworCXByaXZhdGUgaW50W10gd2lkdGhzID0gbmV3IGludFsyNTZdOworCisJLy8gZm9udCBwZWVyIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBGb250UGVlckltcGwKKwlwcml2YXRlIHRyYW5zaWVudCBGb250UGVlckltcGwgcGVlcjsKKworCS8vIFggc2NhbGUgcGFyYW1ldGVyIG9mIHRoZSBmb250IHRyYW5zZm9ybQorCXByaXZhdGUgZmxvYXQgc2NhbGVYID0gMTsKKworCXB1YmxpYyBBbmRyb2lkR3JhcGhpY3MyRCBtU2c7CisKKwlwcml2YXRlIEZvbnQgbUZuOworCisJLy8gWSBzY2FsZSBwYXJhbWV0ZXIgb2YgdGhlIGZvbnQgdHJhbnNmb3JtCisJcHJpdmF0ZSBmbG9hdCBzY2FsZVkgPSAxOworCisJLyoqCisJICogQ3JlYXRlcyBuZXcgRm9udE1lcmljc0ltcGwgb2JqZWN0IGRlc2NyaWJlZCBieSB0aGUgc3BlY2lmaWVkIEZvbnQuCisJICogCisJICogQHBhcmFtIGZudAorCSAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBGb250IG9iamVjdAorCSAqLworCXB1YmxpYyBGb250TWV0cmljc0ltcGwoRm9udCBmbnQpIHsKKwkJc3VwZXIoZm50KTsKKwkJdGhpcy5tRm4gPSBmbnQ7CisJCQorCQltU2cgPSBBbmRyb2lkR3JhcGhpY3MyRC5nZXRJbnN0YW5jZSgpOworCQlQYWludCBwID0gbVNnLmdldEFuZHJvaWRQYWludCgpOworCQkKKwkJdGhpcy5hc2NlbnQgPSAoaW50KS1wLmFzY2VudCgpOworCQl0aGlzLmRlc2NlbnQgPSAoaW50KXAuZGVzY2VudCgpOworCQl0aGlzLmxlYWRpbmcgPSBwLmdldEZvbnRNZXRyaWNzSW50KCkubGVhZGluZzsKKwkJCisJCUFmZmluZVRyYW5zZm9ybSBhdCA9IGZudC5nZXRUcmFuc2Zvcm0oKTsKKwkJaWYgKCFhdC5pc0lkZW50aXR5KCkpIHsKKwkJCXNjYWxlWCA9IChmbG9hdCkgYXQuZ2V0U2NhbGVYKCk7CisJCQlzY2FsZVkgPSAoZmxvYXQpIGF0LmdldFNjYWxlWSgpOworCQl9CisJCQkJCisJICAgIC8qCisJICAgICAqIG1ldHJpY3NbNV0gLSBzdHJpa2V0aHJvdWdoIHRoaWNrbmVzczxwPgorCSAgICAgKiAtbWV0cmljc1s2XSAtIHN0cmlrZXRocm91Z2ggb2Zmc2V0PHA+CisJICAgICAqIG1ldHJpY3NbN10gLSBtYXhpbXVtIGNoYXIgd2lkdGg8cD4KKwkgICAgICogbWV0cmljc1s4XSAtIGFzY2VudCBpbiBwaXhlbHM8cD4KKwkgICAgICogbWV0cmljc1s5XSAtIGRlc2NlbnQgaW4gcGl4bGVzPHA+CisJICAgICAqIG1ldHJpY3NbMTBdIC0gZXh0ZXJuYWwgbGVhZGluZyBpbiBwaXhlbHM8cD4KKwkgICAgICogbWV0cmljc1sxMV0gLSB1bmRlcmxpbmUgdGhpY2tuZXNzIGluIHBpeGVsczxwPgorCSAgICAgKiAtbWV0cmljc1sxMl0gLSB1bmRlcmxpbmUgb2Zmc2V0IGluIHBpeGVsczxwPgorCSAgICAgKiBtZXRyaWNzWzEzXSAtIHN0cmlrZXRocm91Z2ggdGhpY2tuZXNzIGluIHBpeGVsczxwPgorCSAgICAgKiAtbWV0cmljc1sxNF0gLSBzdHJpa2V0aHJvdWdoIG9mZnNldCBpbiBwaXhlbHM8cD4KKwkgICAgICogbWV0cmljc1sxNV0gLSBtYXhpbXVtIGNoYXIgd2lkdGggaW4gcGl4ZWxzPHA+CisKKwkgICAgICogQHBhcmFtIF9iYXNlbGluZURhdGEgYW4gYXJyYXkgb2YgMyBlbGVtZW50cyB3aXRoIGJhc2VsaW5lIG9mZnNldHMgbWV0cmljczxwPgorCSAgICAgKiBfYmFzZWxpbmVEYXRhWzBdIC0gcm9tYW4gYmFzZWxpbmUgb2Zmc2V0PHA+IAorCSAgICAgKiBfYmFzZWxpbmVEYXRhWzFdIC0gY2VudGVyIGJhc2VsaW5lIG9mZnNldDxwPgorCSAgICAgKiBfYmFzZWxpbmVEYXRhWzJdIC0gaGFuZ2luZyBiYXNlbGluZSBvZmZzZXQ8cD4KKwkgICAgICovCisJfQorCisKKwkvKioKKwkgKiBJbml0aWFsaXplIHRoZSBhcnJheSBvZiB0aGUgZmlyc3QgMjU2IGNoYXJzJyBhZHZhbmNlIHdpZHRocyBvZiB0aGUgRm9udAorCSAqIGRlc2NyaWJpbmcgdGhpcyBGb250TWV0cmljc0ltcGwgb2JqZWN0LgorCSAqLworCXByaXZhdGUgdm9pZCBpbml0V2lkdGhzKCkgeworCisJCXRoaXMud2lkdGhzID0gbmV3IGludFsyNTZdOworCQlmb3IgKGludCBjaHIgPSAwOyBjaHIgPCAyNTY7IGNocisrKSB7CisJCQl3aWR0aHNbY2hyXSA9IChpbnQpIChnZXRGb250UGVlcigpLmNoYXJXaWR0aCgoY2hhcikgY2hyKSAqIHNjYWxlWCk7CisJCX0KKworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIGFzY2VudCBvZiB0aGUgRm9udCBkZXNjcmliaW5nIHRoaXMgRm9udE1ldHJpY3NJbXBsIG9iamVjdC4KKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IGdldEFzY2VudCgpIHsKKwkJcmV0dXJuIHRoaXMuYXNjZW50OworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIGRlc2NlbnQgb2YgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QuCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIGludCBnZXREZXNjZW50KCkgeworCQlyZXR1cm4gdGhpcy5kZXNjZW50OworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIGxlYWRpbmcgb2YgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QuCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIGludCBnZXRMZWFkaW5nKCkgeworCQlyZXR1cm4gdGhpcy5sZWFkaW5nOworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIGFkdmFuY2Ugd2lkdGggb2YgdGhlIHNwZWNpZmllZCBjaGFyIG9mIHRoZSBGb250IGRlc2NyaWJpbmcKKwkgKiB0aGlzIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QuCisJICogCisJICogQHBhcmFtIGNoCisJICogICAgICAgICAgICB0aGUgY2hhciB3aGljaCB3aWR0aCBpcyB0byBiZSByZXR1cm5lZAorCSAqIEByZXR1cm4gdGhlIGFkdmFuY2Ugd2lkdGggb2YgdGhlIHNwZWNpZmllZCBjaGFyIG9mIHRoZSBGb250IGRlc2NyaWJpbmcKKwkgKiAgICAgICAgIHRoaXMgRm9udE1ldHJpY3NJbXBsIG9iamVjdAorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyBpbnQgY2hhcldpZHRoKGludCBjaCkgeworCQlpZiAoY2ggPCAyNTYpIHsKKwkJCXJldHVybiB3aWR0aHNbY2hdOworCQl9CisKKwkJcmV0dXJuIGdldEZvbnRQZWVyKCkuY2hhcldpZHRoKChjaGFyKSBjaCk7CisJfQorCisJLyoqCisJICogUmV0dXJucyB0aGUgYWR2YW5jZSB3aWR0aCBvZiB0aGUgc3BlY2lmaWVkIGNoYXIgb2YgdGhlIEZvbnQgZGVzY3JpYmluZworCSAqIHRoaXMgRm9udE1ldHJpY3NJbXBsIG9iamVjdC4KKwkgKiAKKwkgKiBAcGFyYW0gY2gKKwkgKiAgICAgICAgICAgIHRoZSBjaGFyIHdoaWNoIHdpZHRoIGlzIHRvIGJlIHJldHVybmVkCisJICogQHJldHVybiB0aGUgYWR2YW5jZSB3aWR0aCBvZiB0aGUgc3BlY2lmaWVkIGNoYXIgb2YgdGhlIEZvbnQgZGVzY3JpYmluZworCSAqICAgICAgICAgdGhpcyBGb250TWV0cmljc0ltcGwgb2JqZWN0CisJICovCisJQE92ZXJyaWRlCisJcHVibGljIGludCBjaGFyV2lkdGgoY2hhciBjaCkgeworCQlpZiAoY2ggPCAyNTYpIHsKKwkJCXJldHVybiB3aWR0aHNbY2hdOworCQl9CisJCXJldHVybiAoaW50KSAoZ2V0Rm9udFBlZXIoKS5jaGFyV2lkdGgoY2gpICogc2NhbGVYKTsKKwl9CisKKwkvKioKKwkgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGFkdmFuY2Ugb2YgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbAorCSAqIG9iamVjdC4KKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IGdldE1heEFkdmFuY2UoKSB7CisJCXJldHVybiB0aGlzLm1heEFkdmFuY2U7CisJfQorCisJLyoqCisJICogUmV0dXJucyB0aGUgbWF4aW11bSBhc2NlbnQgb2YgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbAorCSAqIG9iamVjdC4KKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IGdldE1heEFzY2VudCgpIHsKKwkJcmV0dXJuIHRoaXMubWF4QXNjZW50OworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIG1heGltdW0gZGVzY2VudCBvZiB0aGUgRm9udCBkZXNjcmliaW5nIHRoaXMgRm9udE1ldHJpY3NJbXBsCisJICogb2JqZWN0LgorCSAqLworCUBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisJQERlcHJlY2F0ZWQKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IGdldE1heERlY2VudCgpIHsKKwkJcmV0dXJuIHRoaXMubWF4RGVzY2VudDsKKwl9CisKKwkvKioKKwkgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGRlc2NlbnQgb2YgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbAorCSAqIG9iamVjdC4KKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IGdldE1heERlc2NlbnQoKSB7CisJCXJldHVybiB0aGlzLm1heERlc2NlbnQ7CisJfQorCisJLyoqCisJICogUmV0dXJucyB0aGUgYWR2YW5jZSB3aWR0aHMgb2YgdGhlIGZpcnN0IDI1NiBjaGFyYWN0ZXJzIGluIHRoZSBGb250CisJICogZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QuCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIGludFtdIGdldFdpZHRocygpIHsKKwkJcmV0dXJuIHRoaXMud2lkdGhzOworCX0KKworCS8qKgorCSAqIFJldHVybnMgdGhlIHRvdGFsIGFkdmFuY2Ugd2lkdGggb2YgdGhlIHNwZWNpZmllZCBzdHJpbmcgaW4gdGhlIG1ldHJpY3Mgb2YKKwkgKiB0aGUgRm9udCBkZXNjcmliaW5nIHRoaXMgRm9udE1ldHJpY3NJbXBsIG9iamVjdC4KKwkgKiAKKwkgKiBAcGFyYW0gc3RyCisJICogICAgICAgICAgICB0aGUgU3RyaW5nIHdoaWNoIHdpZHRoIGlzIHRvIGJlIG1lYXN1cmVkCisJICogQHJldHVybiB0aGUgdG90YWwgYWR2YW5jZSB3aWR0aCBvZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpbiB0aGUgbWV0cmljcyBvZgorCSAqICAgICAgICAgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgaW50IHN0cmluZ1dpZHRoKFN0cmluZyBzdHIpIHsKKworCQlpbnQgd2lkdGggPSAwOworCQljaGFyIGNocjsKKworCQlmb3IgKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGgoKTsgaSsrKSB7CisJCQljaHIgPSBzdHIuY2hhckF0KGkpOworCQkJd2lkdGggKz0gY2hhcldpZHRoKGNocik7CisJCX0KKwkJcmV0dXJuIHdpZHRoOworCisJCS8qCisJCSAqIGZsb2F0IHJlcyA9IDA7IGludCBsbiA9IHN0ci5sZW5ndGgoKTsgY2hhcltdIGMgPSBuZXcgY2hhcltsbl07IGZsb2F0W10gZiA9CisJCSAqIG5ldyBmbG9hdFtsbl07IHN0ci5nZXRDaGFycygwLCBsbiwgYywgMCk7IG1TZy5nZXRQYWludCgpLmdldFRleHRXaWR0aHMoYywgMCwKKwkJICogbG4sIGYpOworCQkgKiAKKwkJICogZm9yKGludCBpID0gMDsgaSA8IGYubGVuZ3RoOyBpKyspIHsgcmVzICs9IGZbaV07IH0gcmV0dXJuIChpbnQpcmVzOworCQkgKi8KKwl9CisKKwkvKioKKwkgKiBSZXR1cm5zIEZvbnRQZWVyIGltcGxlbWVudGF0aW9uIG9mIHRoZSBGb250IGRlc2NyaWJpbmcgdGhpcworCSAqIEZvbnRNZXRyaWNzSW1wbCBvYmplY3QuCisJICogCisJICogQHJldHVybiBhIEZvbnRQZWVyIG9iamVjdCwgdGhhdCBpcyB0aGUgcGxhdGZvcm0gZGVwZW5kZW50IEZvbnRQZWVyCisJICogICAgICAgICBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIEZvbnQgZGVzY3JpYmluZyB0aGlzIEZvbnRNZXRyaWNzSW1wbAorCSAqICAgICAgICAgb2JqZWN0LgorCSAqLworCUBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisJcHVibGljIEZvbnRQZWVySW1wbCBnZXRGb250UGVlcigpIHsKKwkJaWYgKHBlZXIgPT0gbnVsbCkgeworCQkJcGVlciA9IChGb250UGVlckltcGwpIGZvbnQuZ2V0UGVlcigpOworCQl9CisJCXJldHVybiBwZWVyOworCX0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udFBlZXJJbXBsLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0ZvbnRQZWVySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0ZmY5OTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L0ZvbnRQZWVySW1wbC5qYXZhCkBAIC0wLDAgKzEsNDk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250OworCisKK2ltcG9ydCBjb20uYW5kcm9pZC5pbnRlcm5hbC5hd3QuQW5kcm9pZEdyYXBoaWNzMkQ7CitpbXBvcnQgY29tLmFuZHJvaWQuaW50ZXJuYWwuYXd0LkFuZHJvaWRHcmFwaGljc0ZhY3Rvcnk7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LlRvb2xraXQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5wZWVyLkZvbnRQZWVyOworCitpbXBvcnQgamF2YS5hd3QuZm9udC5Gb250UmVuZGVyQ29udGV4dDsKK2ltcG9ydCBqYXZhLmF3dC5mb250LkxpbmVNZXRyaWNzOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5QYWludDsKKworLyoqCisgKiBBYnN0cmFjdCBjbGFzcyBmb3IgcGxhdGZvcm0gZGVwZW5kZW50IHBlZXIgaW1wbGVtZW50YXRpb24gb2YgdGhlIEZvbnQgY2xhc3MuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb250UGVlckltcGwgaW1wbGVtZW50cyBGb250UGVlcnsKKworICAgIC8vIGFzY2VudCBvZiB0aGlzIGZvbnQgcGVlciAoaW4gcGl4ZWxzKQorICAgIGludCBhc2NlbnQ7CisKKyAgICAvLyBkZXNjZW50IG9mIHRoaXMgZm9udCBwZWVyIChpbiBwaXhlbHMpCisgICAgaW50IGRlc2NlbnQ7CisKKyAgICAvLyBsZWFkaW5nIG9mIHRoaXMgZm9udCBwZWVyIChpbiBwaXhlbHMpIAorICAgIGludCBsZWFkaW5nOworCisgICAgLy8gbG9naWNhbCBtYXhpbXVtIGFkdmFuY2Ugb2YgdGhpcyBmb250IHBlZXIgKGluIHBpeGVscykKKyAgICBpbnQgbWF4QWR2YW5jZTsKKworICAgIC8vIHRoZSBoZWlnaHQgb2YgdGhpcyBmb250IHBlZXIKKyAgICBmbG9hdCBoZWlnaHQ7CisKKyAgICAvLyB0aGUgc3R5bGUgb2YgdGhpcyBmb250IHBlZXIKKyAgICBpbnQgc3R5bGU7CisKKyAgICAvLyB0aGUgcG9pbnQgc2l6ZSBvZiB0aGlzIGZvbnQgcGVlciAoaW4gcGl4ZWxzKQorICAgIGludCBzaXplOworCisgICAgLy8gdGhlIGxvZ2ljYWwgaGlnaHQgb2YgdGhpcyBmb250IHBlZXIgKGluIHBpeGVscykKKyAgICBpbnQgbG9naWNhbEhlaWdodDsKKworICAgIC8vIHRoZSBuYW1lIG9mIHRoaXMgZm9udCBwZWVyCisgICAgU3RyaW5nIG5hbWU7CisKKyAgICAvLyBmYW1pbHkgbmFtZSBvZiB0aGlzIGZvbnQgcGVlcgorICAgIFN0cmluZyBmb250RmFtaWx5TmFtZTsKKworICAgIC8vIHRoZSBGYWNlIG5hbWUgb2YgdGhpcyBmb250IHBlZXIKKyAgICBTdHJpbmcgZmFjZU5hbWU7CisKKyAgICAvLyBib3VuZHMgcmVjdGFubGdlIG9mIHRoZSBsYXJnZXN0IGNoYXJhY3RlciBpbiB0aGlzIGZvbnQgcGVlcgorICAgIFJlY3RhbmdsZTJEIG1heENoYXJCb3VuZHM7CisKKyAgICAvLyBpdGFsaWMgYW5nbGUgdmFsdWUgb2YgdGhpcyBmb250IHBlZXIKKyAgICBmbG9hdCBpdGFsaWNBbmdsZSA9IDAuMGY7CisKKyAgICAvLyB0aGUgbnVtYmVyIG9mIGdseXBocyBzdXBwb3J0ZWQgYnkgdGhpcyBmb250IHBlZXIKKyAgICBpbnQgbnVtR2x5cGhzID0gMDsKKworICAgIC8vIG5hdGl2ZSBmb250IGhhbmRsZQorICAgIGxvbmcgcEZvbnQ7CisKKyAgICAvLyBjYWNoZWQgbGluZSBtZXRyaWNzIG9iamVjdAorICAgIExpbmVNZXRyaWNzSW1wbCBubG07CisKKyAgICAvLyB0aGUgcG9zdHNjcmlwdCBuYW1lIG9mIHRoaXMgZm9udCBwZWVyCisgICAgU3RyaW5nIHBzTmFtZSA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGdseXBoIGluZGV4LCB0aGF0IGlzIHVzZWQsIHdoZW4gdGhlIGRlc2lyZWQgZ2x5cGgKKyAgICAgKiBpcyB1bnN1cHBvcnRlZCBpbiB0aGlzIEZvbnQuCisgICAgICovCisgICAgcHVibGljIGNoYXIgZGVmYXVsdENoYXIgPSAoY2hhcikweEZGRkY7CisKKyAgICAvKioKKyAgICAgKiBVbmlmb3JtIExpbmVNZXRyaWNzIGZsYWcsIHRoYXQgaXMgZmFsc2UgZm9yIENvbXBvc2l0ZUZvbnQuICAKKyAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIHRydWUuCisgICAgICovCisgICAgYm9vbGVhbiB1bmlmb3JtTE0gPSB0cnVlOworCisgICAgLyoqCisgICAgICogRmxhZyBvZiB0aGUgdHlwZSBvZiB0aGlzIEZvbnQgdGhhdCBpcyBpbmRpY2F0ZSBpcyB0aGUgRm9udAorICAgICAqIGhhcyBUcnVlVHlwZSBvciBUeXBlMSB0eXBlLiBEZWZhdWx0IHZhbHVlIGlzIEZPTlRfVFlQRV9VTkRFRi4gCisgICAgICovCisgICAgaW50IGZvbnRUeXBlID0gRm9udE1hbmFnZXIuRk9OVF9UWVBFX1VOREVGOworCisgICAgLyoqCisgICAgICogRmxhZyBpZiB0aGlzIEZvbnQgd2FzIGNyZWF0ZWQgZnJvbSBzdHJlYW0sIAorICAgICAqIHRoaXMgcGFyYW1ldGVyIHVzZWQgaW4gZmluaWxpemUgbWV0aG9kLgorICAgICAqLyAKKyAgICBwcml2YXRlIGJvb2xlYW4gY3JlYXRlZEZyb21TdHJlYW0gPSBmYWxzZTsgIAorICAgIAorICAgIC8vIHRlbW9yYXJ5IEZvbnQgZmlsZSBuYW1lLCBpZiB0aGlzIEZvbnRQZWVySW1wbCB3YXMgY3JlYXRlZCBmcm9tIElucHV0U3RyZWFtIAorICAgIHByaXZhdGUgU3RyaW5nIHRlbXBGb250RmlsZU5hbWUgPSBudWxsOyAgICAgCisgICAgCisgICAgLy8gY2FjaGVkIEZvbnRFeHRyYU1ldHJpY3Mgb2JqZWN0IHJlbGF0ZWQgdG8gdGhpcyBmb250IHBlZXIKKyAgICBGb250RXh0cmFNZXRyaWNzIGV4dHJhTWV0cml4ID0gbnVsbDsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBGb250RXh0cmFNZXRyaWNzIGdldEV4dHJhTWV0cmljcygpOworICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgTGluZU1ldHJpY3Mgb2JqZWN0IHdpdGggc3BlY2lmaWVkIHBhcmFtZXRlcnMKKyAgICAgKiBAcGFyYW0gc3RyIHNwZWNpZmllZCBTdHJpbmcKKyAgICAgKiBAcGFyYW0gZnJjIHNwZWNpZmllZCByZW5kZXIgY29udGV4dAorICAgICAqIEBwYXJhbSBhdCBzcGVjaWZpZWQgYWZmaW5lIHRyYW5zZm9ybQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTGluZU1ldHJpY3MgZ2V0TGluZU1ldHJpY3MoU3RyaW5nIHN0ciwgRm9udFJlbmRlckNvbnRleHQgZnJjLCBBZmZpbmVUcmFuc2Zvcm0gYXQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBwb3N0c2NyaXB0IG5hbWUgb2YgdGhlIGZvbnQuICAKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFBTTmFtZSgpOworICAgIAorCS8vcHJpdmF0ZSBHcmFwaGljczJEIGcgPSAoKEFuZHJvaWRHcmFwaGljc0ZhY3RvcnkpVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpLmdldEdyYXBoaWNzRmFjdG9yeSgpKS5nZXRHcmFwaGljczJEKCk7CisgICAgLy9wcml2YXRlIEdyYXBoaWNzMkQgZyA9IEFuZHJvaWRHcmFwaGljczJELmdldEluc3RhbmNlKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgcG9zdHNjcmlwdCBuYW1lIG9mIHRoZSBmb250IHRvIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyLiAgCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UFNOYW1lKFN0cmluZyBuYW1lKXsKKyAgICAgICAgdGhpcy5wc05hbWUgPSBuYW1lOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGNvZGUgb2YgdGhlIG1pc3NpbmcgZ2x5cGguIAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TWlzc2luZ0dseXBoQ29kZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBHbHlwaCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gY2hhci4KKyAgICAgKiBAcGFyYW0gY2ggc3BlY2lmaWVkIGNoYXIKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR2x5cGggZ2V0R2x5cGgoY2hhciBjaCk7CisKKyAgICAvKioKKyAgICAgKiBEaXNwb3NlcyBuZXNlc3NhcnkgcmVzb3VyY2VzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRpc3Bvc2UoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgR2x5cGggcmVwcmVzZXRpbmcgbWlzc2luZyBjaGFyLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR2x5cGggZ2V0RGVmYXVsdEdseXBoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBGb250UGVlckltcGwgY2FuIGRpc3BsYXkgdGhlIHNwZWNpZmllZCBjaGFyCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gY2FuRGlzcGxheShjaGFyIGMpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBmYW1pbHkgbmFtZSBvZiB0aGUgZm9udCBpbiBzcGVjaWZpZWQgbG9jYWxlIHNldHRpbmdzLgorICAgICAqIEBwYXJhbSBsIHNwZWNpZmllZCBMb2NhbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhbWlseShMb2NhbGUgbCl7CisgICAgICAgIHJldHVybiB0aGlzLmdldEZhbWlseSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgZmFtaWx5IG5hbWUgb2YgdGhlIGZvbnQgaW4gc3BlY2lmaWVkIGxvY2FsZSBzZXR0aW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGYW1pbHkoU3RyaW5nIGZhbWlseU5hbWUpeworICAgICAgICB0aGlzLmZvbnRGYW1pbHlOYW1lID0gZmFtaWx5TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZhY2UgbmFtZSBvZiB0aGUgZm9udCBpbiBzcGVjaWZpZWQgbG9jYWxlIHNldHRpbmdzLgorICAgICAqIEBwYXJhbSBsIHNwZWNpZmllZCBMb2NhbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvbnROYW1lKExvY2FsZSBsKXsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Rm9udE5hbWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGZvbnQgbmFtZSBvZiB0aGUgZm9udCBpbiBzcGVjaWZpZWQgbG9jYWxlIHNldHRpbmdzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbnROYW1lKFN0cmluZyBmb250TmFtZSl7CisgICAgICAgIHRoaXMuZmFjZU5hbWUgPSBmb250TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUsIGlmIHRoaXMgZm9udCBwZWVyIHdhcyBjcmVhdGVkIGZyb20gSW5wdXRTdHJlYW0sIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBJbiBjYXNlIG9mIGNyZWF0aW5nIGZvbnRzIGZyb20gSW5wdXRTdHJlYW0gc29tZSBmb250IHBlZXIgaW1wbGVtZW50YXRpb25zIAorICAgICAqIG1heSBuZWVkIHRvIGZyZWUgdGVtcG9yYXJ5IHJlc291cmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NyZWF0ZWRGcm9tU3RyZWFtKCl7CisgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZWRGcm9tU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgY3JlYXRlZEZyb21TdHJlYW0gZmxhZyB0byB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlci4KKyAgICAgKiBJZiBwYXJhbWV0ZXIgaXMgdHJ1ZSBpdCBtZWFucyBmb250IHBlZXIgd2FzIGNyZWF0ZWQgZnJvbSBJbnB1dFN0cmVhbS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmFsdWUgdHJ1ZSwgaWYgZm9udCBwZWVyIHdhcyBjcmVhdGVkIGZyb20gSW5wdXRTdHJlYW0gCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JlYXRlZEZyb21TdHJlYW0oYm9vbGVhbiB2YWx1ZSl7CisgICAgICAgIHRoaXMuY3JlYXRlZEZyb21TdHJlYW0gPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZvbnQgZmlsZSBuYW1lIG9mIHRoaXMgZm9udC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRlbXBGb250RmlsZU5hbWUoKXsKKyAgICAgICAgcmV0dXJuIHRoaXMudGVtcEZvbnRGaWxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGZvbnQgZmlsZSBuYW1lIG9mIHRoaXMgZm9udCB0byB0aGUgc3BlY2lmaWVkIG9uZS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgU3RyaW5nIHJlcHJlc2VudGluZyBmb250IGZpbGUgbmFtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbnRGaWxlTmFtZShTdHJpbmcgdmFsdWUpeworICAgICAgICB0aGlzLnRlbXBGb250RmlsZU5hbWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhZHZhbmNlIHdpZHRoIG9mIHRoZSBzcGVjaWZpZWQgY2hhciBvZiB0aGlzIEZvbnRQZWVySW1wbC4KKyAgICAgKiBOb3RlLCBpZiBnbHlwaCBpcyBhYnNlbnQgaW4gdGhlIGZvbnQncyBnbHlwaHNldCAtIHJldHVybmVkIHZhbHVlIAorICAgICAqIGlzIHRoZSBhZHZhbmNlIG9mIHRoZSBkZWFmdWFsdCBnbHlwaC4gRm9yIGVzY2FwZS1jaGFycyByZXR1cm5lZCAKKyAgICAgKiB3aWR0aCB2YWx1ZSBpcyAwLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaCB0aGUgY2hhciB3aGljaCB3aWR0aCBpcyB0byBiZSByZXR1cm5lZAorICAgICAqIEByZXR1cm4gdGhlIGFkdmFuY2Ugd2lkdGggb2YgdGhlIHNwZWNpZmllZCBjaGFyIG9mIHRoaXMgRm9udFBlZXJJbXBsCisgICAgICovCisgICAgcHVibGljIGludCBjaGFyV2lkdGgoY2hhciBjaCkgeworICAgIAlQYWludCBwOworICAgIAlBbmRyb2lkR3JhcGhpY3MyRCBnID0gQW5kcm9pZEdyYXBoaWNzMkQuZ2V0SW5zdGFuY2UoKTsKKyAgICAJaWYoZyA9PSBudWxsKSB7CisgICAgCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQW5kcm9pZEdyYXBoaWNzMkQgbm90IGluc3RhbnRpYXRlZCEiKTsKKyAgICAJfQorICAgCQlwID0gKChBbmRyb2lkR3JhcGhpY3MyRClnKS5nZXRBbmRyb2lkUGFpbnQoKTsKKyAgIAkJY2hhcltdIGNhID0ge2NofTsKKyAgIAkJZmxvYXRbXSBmYSA9IG5ldyBmbG9hdFsxXTsKKyAgIAkJcC5nZXRUZXh0V2lkdGhzKGNhLCAwLCAxLCBmYSk7CisgICAJCXJldHVybiAoaW50KWZhWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFkdmFuY2Ugd2lkdGggb2YgdGhlIHNwZWNpZmllZCBjaGFyIG9mIHRoaXMgRm9udFBlZXJJbXBsLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpbmQgdGhlIGNoYXIgd2hpY2ggd2lkdGggaXMgdG8gYmUgcmV0dXJuZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBhZHZhbmNlIHdpZHRoIG9mIHRoZSBzcGVjaWZpZWQgY2hhciBvZiB0aGlzIEZvbnRQZWVySW1wbAorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2hhcldpZHRoKGludCBpbmQpIHsKKyAgICAgICAgcmV0dXJuIGNoYXJXaWR0aCgoY2hhcilpbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgR2x5cGhzIHRoYXQgcmVwcmVzZW50IGNoYXJhY3RlcnMgZnJvbSB0aGUgc3BlY2lmaWVkIAorICAgICAqIFVuaWNvZGUgcmFuZ2UuCisgICAgICogCisgICAgICogQHBhcmFtIHVGaXJzdCBzdGFydCBwb3NpdGlvbiBpbiBVbmljb2RlIHJhbmdlCisgICAgICogQHBhcmFtIHVMYXN0IGVuZCBwb3NpdGlvbiBpbiBVbmljb2RlIHJhbmdlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaFtdIGdldEdseXBocyhjaGFyIHVGaXJzdCwgY2hhciB1TGFzdCkgeworCisgICAgICAgIGNoYXIgaSA9IHVGaXJzdDsKKyAgICAgICAgaW50IGxlbiA9IHVMYXN0IC0gdUZpcnN0OworICAgICAgICBBcnJheUxpc3Q8R2x5cGg+IGxzdCA9IG5ldyBBcnJheUxpc3Q8R2x5cGg+KGxlbik7CisKKyAgICAgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICAvLyBhd3QuMDk9bWluIHJhbmdlIGJvdW5kIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBtYXggcmFuZ2UgYm91bmQKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMDkiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlIChpIDwgdUxhc3QpIHsKKyAgICAgICAgICAgIGxzdC5hZGQodGhpcy5nZXRHbHlwaChpKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gKEdseXBoW10pIGxzdC50b0FycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBHbHlwaHMgcmVwcmVzZW50aW5nIGdpdmVuIGFycmF5IG9mIGNoYXJzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjaGFycyBzcGVjaWZpZWQgYXJyYXkgb2YgY2hhcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgR2x5cGhbXSBnZXRHbHlwaHMoY2hhcltdIGNoYXJzKSB7CisgICAgICAgIGlmIChjaGFycyA9PSBudWxsKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgR2x5cGhbXSByZXN1bHQgPSBuZXcgR2x5cGhbY2hhcnMubGVuZ3RoXTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHRbaV0gPSB0aGlzLmdldEdseXBoKGNoYXJzW2ldKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgR2x5cGhzIHJlcHJlc2VudGluZyBnaXZlbiBzdHJpbmcuCisgICAgICogCisgICAgICogQHBhcmFtIHN0ciBzcGVjaWZpZWQgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIEdseXBoW10gZ2V0R2x5cGhzKFN0cmluZyBzdHIpIHsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gc3RyLnRvQ2hhckFycmF5KCk7CisgICAgICAgIHJldHVybiB0aGlzLmdldEdseXBocyhjaGFycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmYW1pbHkgbmFtZSBvZiB0aGlzIEZvbnRQZWVySW1wbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhbWlseSgpIHsKKyAgICAgICAgcmV0dXJuIGZvbnRGYW1pbHlOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZmFjZSBuYW1lIG9mIHRoaXMgRm9udFBlZXJJbXBsLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udE5hbWUoKSB7CisgICAgICAgIGlmICh0aGlzLmZvbnRUeXBlID09IEZvbnRNYW5hZ2VyLkZPTlRfVFlQRV9UMSl7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5mb250RmFtaWx5TmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWNlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhlaWdodCBvZiB0aGlzIGZvbnQgcGVlciBpbiBwaXhlbHMuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9naWNhbEhlaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIGxvZ2ljYWxIZWlnaHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBoZWlnaHQgb2YgdGhpcyBmb250IHBlZXIgaW4gcGl4ZWxzIHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3SGVpZ2h0IG5ldyBoZWlnaHQgaW4gcGl4ZWxzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9naWNhbEhlaWdodChpbnQgbmV3SGVpZ2h0KSB7CisgICAgICAgIGxvZ2ljYWxIZWlnaHQgPSBuZXdIZWlnaHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmb250IHNpemUuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmb250IHN0eWxlLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN0eWxlKCkgeworICAgICAgICByZXR1cm4gc3R5bGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmb250IG5hbWUuIAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYm91bmRzIG9mIHRoZSBsYXJnZXN0IGNoYXIgaW4gdGhpcyBGb250UGVlckltcGwgaW4gCisgICAgICogc3BlY2lmaWVkIHJlbmRlciBjb250ZXh0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBmcmMgc3BlY2lmaWVkIEZvbnRSZW5kZXJDb250ZXh0CisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldE1heENoYXJCb3VuZHMoRm9udFJlbmRlckNvbnRleHQgZnJjKSB7CisgICAgICAgIHJldHVybiBtYXhDaGFyQm91bmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBnbHlwaHMgaW4gdGhpcyBGb250UGVlckltcGwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1HbHlwaHMoKSB7CisgICAgICAgIHJldHVybiAgbnVtR2x5cGhzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGFuZ2VucyBvZiB0aGUgaXRhbGljIGFuZ2xlIG9mIHRoaXMgRm9udFBlZXJJbXBsLgorICAgICAqIElmIHRoZSBGb250UGVlckltcGwgaGFzIFRydWVUeXBlIGZvbnQgdHlwZSwgaXRhbGljIGFuZ2xlIHZhbHVlIGNhbiBiZSAKKyAgICAgKiBjYWxjdWxhdGVkIGFzIChDaGFyU2xvcGVSdW4gLyBDaGFyU2xvcGVSaXNlKSBpbiB0ZXJtcyBvZiBHREkuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEl0YWxpY0FuZ2xlKCkgeworICAgICAgICByZXR1cm4gaXRhbGljQW5nbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBoZWlnaHQgb2YgdGhpcyBmb250IHBlZXIuIAorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRIZWlnaHQoKXsKKyAgICAgICAgcmV0dXJuIGhlaWdodDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGNhY2hlZCBMaW5lTWV0cmljcyBvYmplY3Qgb2YgdGhpcyBmb250IHBlZXIuIAorICAgICAqLworICAgIHB1YmxpYyBMaW5lTWV0cmljcyBnZXRMaW5lTWV0cmljcygpeworICAgICAgICByZXR1cm4gbmxtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbmF0aXZlIGZvbnQgaGFuZGxlIG9mIHRoaXMgZm9udCBwZWVyLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRGb250SGFuZGxlKCl7CisgICAgICAgIHJldHVybiBwRm9udDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFzY2VudCBvZiB0aGlzIGZvbnQgcGVlci4gCisgICAgICovCisgICAgcHVibGljIGludCBnZXRBc2NlbnQoKXsKKyAgICAJUGFpbnQgcDsKKyAgICAJQW5kcm9pZEdyYXBoaWNzMkQgZyA9IEFuZHJvaWRHcmFwaGljczJELmdldEluc3RhbmNlKCk7CisgICAgCWlmKGcgPT0gbnVsbCkgeworICAgIAkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkFuZHJvaWRHcmFwaGljczJEIG5vdCBpbnN0YW50aWF0ZWQhIik7CisgICAgCX0KKyAgIAkJcCA9ICgoQW5kcm9pZEdyYXBoaWNzMkQpZykuZ2V0QW5kcm9pZFBhaW50KCk7CisgICAJCXJldHVybiAoaW50KXAuYXNjZW50KCk7CisgICAgICAgIC8vcmV0dXJuIGFzY2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGRlc2NlbnQgb2YgdGhpcyBmb250IHBlZXIuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGVzY2VudCgpeworICAgICAgICByZXR1cm4gZGVzY2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGxlYWRpbmcgb2YgdGhpcyBmb250IHBlZXIuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGVhZGluZygpeworICAgICAgICByZXR1cm4gbGVhZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBmb250IHBlZXIgaGFzIHVuaWZvcm0gbGluZSBtZXRyaWNzLiAKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNVbmlmb3JtTGluZU1ldHJpY3MoKXsKKyAgICAgICAgcmV0dXJuIHVuaWZvcm1MTTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHR5cGUgb2YgdGhpcyBmb250LgorICAgICAqICAKKyAgICAgKiBAcmV0dXJuIG9uZSBvZiBjb25zdGFudCBmb250IHR5cGUgdmFsdWVzLiAKKyAgICAgKi8gICAgCisgICAgcHVibGljIGludCBnZXRGb250VHlwZSgpeworICAgICAgICByZXR1cm4gZm9udFR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBuZXcgZm9udCB0eXBlIHRvIHRoZSBmb250IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3VHlwZSBuZXcgdHlwZSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbnRUeXBlKGludCBuZXdUeXBlKXsKKyAgICAgICAgaWYgKG5ld1R5cGUgPT0gRm9udE1hbmFnZXIuRk9OVF9UWVBFX1QxIHx8IG5ld1R5cGUgPT0gRm9udE1hbmFnZXIuRk9OVF9UWVBFX1RUKXsKKyAgICAgICAgICAgIGZvbnRUeXBlID0gbmV3VHlwZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgbmV3IGZvbnQgdHlwZSB0byB0aGUgZm9udCBvYmplY3QuCisgICAgICogCisgICAgICogQHBhcmFtIG5ld1R5cGUgbmV3IHR5cGUgdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgIAorICAgICAgZGlzcG9zZSgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9Gb250UHJvcGVydHkuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udFByb3BlcnR5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGViN2NiYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvRm9udFByb3BlcnR5LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworCisvKioKKyAqIENsYXNzIGNvbnRhaW5pbmcgZm9udCBwcm9wZXJ0eSBpbmZvcm1hdGlvbi4gVGhpcyBpbmZvcm1hdGlvbiBjYW4gYmUgZm91bmQgCisgKiBpbiBmb250LnByb3BlcnR5IGZpbGVzLiBTZWUgQVBJIGRvY3VtZW50YXRpb24sIGxvZ2ljYWwgZm9udHMgZGVzY3JpcHRpb24gcGFydC4gCisgKgorICovCitwdWJsaWMgY2xhc3MgRm9udFByb3BlcnR5IHsKKworICAgIC8vIGZvbnQgZmlsZSBuYW1lIAorICAgIFN0cmluZyBmaWxlTmFtZSA9IG51bGw7CisgICAgCisgICAgLy8gbmFtZSBvZiB0aGUgZW5jb2RpbmcgdG8gYmUgdXNlZCAKKyAgICBTdHJpbmcgZW5jb2RpbmcgPSBudWxsOworICAgIAorICAgIC8vIGFycmF5IG9mIGV4Y2x1c2lvbiByYW5nZXMgKHBhaXJzIG9mIGxvdyBhbmQgaGlnaCB1bmljb2RlIGV4Y2x1c2lvbiBib3VuZHMpCisgICAgaW50W10gZXhjbFJhbmdlID0gbnVsbDsKKyAgICAKKyAgICAvLyBmb250IGZhY2UgbmFtZQorICAgIFN0cmluZyBuYW1lID0gbnVsbDsKKyAgICAKKyAgICAvLyBmb250IHN0eWxlCisgICAgaW50IHN0eWxlID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZvbnQgc3R5bGUgb2YgdGhpcyBmb250IHByb3BlcnR5LiAKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN0eWxlKCl7CisgICAgICAgIHJldHVybiB0aGlzLnN0eWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZm9udCBuYW1lIG9mIHRoaXMgZm9udCBwcm9wZXJ0eS4gCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCl7CisgICAgICAgIHJldHVybiB0aGlzLm5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBlbmNvZGluZyB1c2VkIGluIHRoaXMgZm9udCBwcm9wZXJ0eS4gCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpeworICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGluZzsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBleGNsdXNpb24gcmFuZ2VzLiBUaGlzIGFycmF5IGNvbnRhaW4gcGFpcnMgb2YgCisgICAgICogbG93IGFuZCBoaWdoIGJvdW5kcyBvZiB0aGUgaW50ZXJ2YWxzIG9mIGNoYXJhY3RlcnMgdG8gaWdub3JlIGluIAorICAgICAqIHRvdGFsIFVuaWNvZGUgY2hhcmFjdGVycyByYW5nZS4gICAKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50W10gZ2V0RXhjbHVzaW9uUmFuZ2UoKXsKKyAgICAgICAgcmV0dXJuIHRoaXMuZXhjbFJhbmdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZmlsZSBuYW1lIG9mIHRoZSBmb250IHRoYXQgaXMgZGVzY3JpYmVkIGJ5IHRoaXMgZm9udCBwcm9wZXJ0eS4gCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpeworICAgICAgICByZXR1cm4gdGhpcy5maWxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgc3BlY2lmaWVkIGNoYXJhY3RlciBjb3ZlcmVkIGJ5IGV4Y2x1c2lvbiByYW5nZXMgb2YgdGhpcyAKKyAgICAgKiBmb250IHByb3BlcnR5LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogCisgICAgICogQHBhcmFtIGNoIHNwZWNpZmllZCBjaGFyIHRvIGNoZWNrCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDaGFyRXhjbHVkZWQoY2hhciBjaCl7CisgICAgICAgIGlmIChleGNsUmFuZ2UgPT0gbnVsbCApeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleGNsUmFuZ2UubGVuZ3RoOyl7CisgICAgICAgICAgICBpbnQgbGIgPSBleGNsUmFuZ2VbaSsrXTsKKyAgICAgICAgICAgIGludCBoYiA9IGV4Y2xSYW5nZVtpKytdOworCisgICAgICAgICAgICBpZiAoY2ggPj0gbGIgJiYgY2ggPD0gaGIpeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvR2x5cGguamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvR2x5cGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NGI4ODA5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9HbHlwaC5qYXZhCkBAIC0wLDAgKzEsMjM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250OworCitpbXBvcnQgamF2YS5hd3QuU2hhcGU7CitpbXBvcnQgamF2YS5hd3QuZm9udC5HbHlwaEp1c3RpZmljYXRpb25JbmZvOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhNZXRyaWNzOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBHbHlwaHsKKworICAgIC8vIGNoYXJhY3RlciBvZiB0aGUgZ2x5cGgKKyAgICBjaGFyIGdsQ2hhcjsKKyAgICAKKyAgICAvLyBwcmVjaXNlIGdseXBoIG1ldHJpY3MKKyAgICBHbHlwaE1ldHJpY3MgZ2xNZXRyaWNzOworICAgIAorICAgIC8vIGdseXBoIG1ldHJpY3MgaW4gcGl4ZWxzCisgICAgR2x5cGhNZXRyaWNzIGdsUG9pbnRNZXRyaWNzOworICAgIAorICAgIC8vICBnbHlwaCBjb2RlIG9mIHRoaXMgR2x5cGgKKyAgICBpbnQgZ2xDb2RlOworICAgIAorICAgIC8vIGp1c3RpZmljYXRpb24gaW5mbyBvZiB0aGlzIGdseXBoCisgICAgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBnbEp1c3RJbmZvOworICAgIAorICAgIC8vIG5hdGl2ZSBmb250IGhhbmRsZSBvZiB0aGUgZm9udCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZ2x5cGgKKyAgICBsb25nIHBGb250OworICAgIAorICAgIC8vIHNpemUgb2YgdGhlIGZvbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIGdseXBoCisgICAgaW50IGZvbnRTaXplOworICAgIAorICAgIC8vIGJpdG1hcCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2x5cGgKKyAgICBieXRlW10gYml0bWFwID0gbnVsbDsKKyAgICAKKyAgICAvLyBCdWZmZXJlZCBpbWFnZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2x5cGgKKyAgICBCdWZmZXJlZEltYWdlIGltYWdlOworICAgIAorICAgIC8vIHNoYXBlIHRoYXQgcmVwcmVzZW50aW5nIHRoZSBvdXRsaW5lIG9mIHRoaXMgZ2x5cGgKKyAgICBTaGFwZSBnbE91dGxpbmUgPSBudWxsOworCisgICAgLyoqCisgICAgICogaW1hZ2UgYml0bWFwIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICAKKyAgICAvLyAgdG9wIHNpZGUgYmVhcmluZworICAgIHB1YmxpYyBpbnQgYm1wX3RvcCA9IDA7CisgICAgCisgICAgLy8gbGVmdCBzaWRlIGJlYXJpbmcKKyAgICBwdWJsaWMgaW50IGJtcF9sZWZ0ID0gMDsKKworICAgIC8vIG51bWJlciBvZiBieXRlcyBpbiByb3cKKyAgICBwdWJsaWMgaW50IGJtcF9waXRjaDsKKyAgICAKKyAgICAvLyBudW1iZXIgb2Ygcm93cworICAgIHB1YmxpYyBpbnQgYm1wX3Jvd3M7CisgICAgCisgICAgLy8gd2lkdGggb2YgdGhlIHJvdworICAgIHB1YmxpYyBpbnQgYm1wX3dpZHRoOworCisgICAgLyoqCisgICAgICogIFJldHJ1bnMgaGFuZGxlIHRvIE5hdGl2ZSBGb250IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFBGb250KCl7CisgICAgICAgIHJldHVybiB0aGlzLnBGb250OworICAgIH0KKworICAgIC8qKgorICAgICAqICBSZXRydW5zIGNoYXIgdmFsdWUgb2YgdGhpcyBnbHlwaCBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRDaGFyKCl7CisgICAgICAgIHJldHVybiBnbENoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogIFJldHJ1bnMgcHJlY2lzZSB3aWR0aCBvZiB0aGlzIGdseXBoIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2lkdGgoKXsKKyAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoKGZsb2F0KWdsTWV0cmljcy5nZXRCb3VuZHMyRCgpLmdldFdpZHRoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqICBSZXRydW5zIHByZWNpc2UgaGVpZ2h0IG9mIHRoaXMgZ2x5cGggb2JqZWN0CisgICAgICovCisgICAgcHVibGljIGludCBnZXRIZWlnaHQoKXsKKyAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoKGZsb2F0KWdsTWV0cmljcy5nZXRCb3VuZHMyRCgpLmdldEhlaWdodCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAgUmV0cnVucyBnbHlwaCBjb2RlIG9mIHRoaXMgZ2x5cGggb2JqZWN0CisgICAgICovCisgICAgcHVibGljIGludCBnZXRHbHlwaENvZGUoKXsKKyAgICAgICAgcmV0dXJuIGdsQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAgUmV0cnVucyBHbHlwaE1ldHJpY3Mgb2YgdGhpcyBnbHlwaCBvYmplY3Qgd2l0aCBwcmVjaXNlIG1ldHJpY3MuCisgICAgICovCisgICAgcHVibGljIEdseXBoTWV0cmljcyBnZXRHbHlwaE1ldHJpY3MoKXsKKyAgICAgICAgcmV0dXJuIGdsTWV0cmljczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAgUmV0cnVucyBHbHlwaE1ldHJpY3Mgb2YgdGhpcyBnbHlwaCBvYmplY3QgaW4gcGl4ZWxzLgorICAgICAqLworICAgIHB1YmxpYyBHbHlwaE1ldHJpY3MgZ2V0R2x5cGhQb2ludE1ldHJpY3MoKXsKKyAgICAgICAgcmV0dXJuIGdsUG9pbnRNZXRyaWNzOworICAgIH0KKworICAgIC8qKgorICAgICAqICBSZXRydW5zIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gb2YgdGhpcyBnbHlwaCBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBnZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvKCl7CisgICAgICAgIHJldHVybiBnbEp1c3RJbmZvOworICAgIH0KKworICAgIC8qKgorICAgICAqICBTZXRzIEp1c3RpZmljYXRpb25JbmZvIG9mIHRoaXMgZ2x5cGggb2JqZWN0CisgICAgICogCisgICAgICogQHBhcmFtIG5ld0p1c3RJbmZvIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gb2JqZWN0IHRvIHNldCB0byB0aGUgR2x5cGggb2JqZWN0IAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdseXBoSnVzdGlmaWNhdGlvbkluZm8oR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBuZXdKdXN0SW5mbyl7CisgICAgICAgIHRoaXMuZ2xKdXN0SW5mbyA9IG5ld0p1c3RJbmZvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50IGFycmF5IG9mIDMgZWxlbWVudHMsIHNvLWNhbGxlZCBBQkMgc3RydWN0dXJlIHRoYXQgY29udGFpbnMgCisgICAgICogdGhlIHdpZHRoIG9mIHRoZSBjaGFyYWN0ZXI6CisgICAgICogMXN0IGVsZW1lbnQgPSBsZWZ0IHNpZGUgYmVhcmluZyBvZiB0aGUgZ2x5cGgKKyAgICAgKiAybmQgZWxlbWVudCA9IHdpZHRoIG9mIHRoZSBnbHlwaAorICAgICAqIDNkIGVsZW1lbnQgPSByaWdodCBzaWRlIGJlYXJpbmcgb2YgdGhlIGdseXBoIAorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRBQkMoKXsKKyAgICAgICAgaW50W10gYWJjID0gbmV3IGludFszXTsKKyAgICAgICAgYWJjWzBdID0gKGludClnbE1ldHJpY3MuZ2V0TFNCKCk7CisgICAgICAgIGFiY1sxXSA9IChpbnQpZ2xNZXRyaWNzLmdldEJvdW5kczJEKCkuZ2V0V2lkdGgoKTsKKyAgICAgICAgYWJjWzJdID0gKGludClnbE1ldHJpY3MuZ2V0UlNCKCk7CisKKyAgICAgICAgcmV0dXJuIGFiYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIEJ1ZmZlcmVkSW1hZ2UgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBnbHlwaCB0byB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3SW1hZ2UgbmV3IEJ1ZmZlcmVkSW1hZ2Ugb2JqZWN0IHRvIGJlIHNldCBhcyBCdWZmZXJlZEltYWdlIAorICAgICAqIHJlcHJlc2VudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEltYWdlKEJ1ZmZlcmVkSW1hZ2UgbmV3SW1hZ2UpeworICAgICAgICB0aGlzLmltYWdlID0gbmV3SW1hZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgR2x5cGggYW5kIHNwZWNpZmllZCBvYmplY3QgYXJlIGVxdWFsLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKXsKKyAgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAob2JqICE9IG51bGwpIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgR2x5cGggZ2wgPSAoR2x5cGgpb2JqOworCisgICAgICAgICAgICByZXR1cm4gICgodGhpcy5nZXRDaGFyKCkgPT0gZ2wuZ2V0Q2hhcigpKQorICAgICAgICAgICAgICAmJiAodGhpcy5nZXRHbHlwaE1ldHJpY3MoKS5lcXVhbHMoZ2wuZ2V0R2x5cGhNZXRyaWNzKCkpKQorICAgICAgICAgICAgICAmJiAodGhpcy5nZXRHbHlwaENvZGUoKSA9PSBnbC5nZXRHbHlwaENvZGUoKSkpOworICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaGVpZ2h0IG9mIHRoZSBnbHlwaCBpbiBwb2ludHMuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UG9pbnRIZWlnaHQoKXsKKyAgICAgICAgcmV0dXJuIChpbnQpZ2xQb2ludE1ldHJpY3MuZ2V0Qm91bmRzMkQoKS5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdpZHRoIG9mIHRoZSBnbHlwaCBpbiBwb2ludHMuIAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UG9pbnRXaWR0aCgpeworICAgICAgICByZXR1cm4gKGludClnbFBvaW50TWV0cmljcy5nZXRCb3VuZHMyRCgpLmdldFdpZHRoKCk7CisgICAgfQorCisgICAgcHVibGljIFNoYXBlIGdldFNoYXBlKCl7CisgICAgICAgIGlmIChnbE91dGxpbmUgPT0gbnVsbCl7CisgICAgICAgICAgICBnbE91dGxpbmUgPSBpbml0T3V0bGluZSh0aGlzLmdsQ2hhcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdsT3V0bGluZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIEJ1ZmZlcmVkSW1hZ2UgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBnbHlwaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSBnZXRJbWFnZSgpeworICAgICAgICAvLyEhIEltcGxlbWVudGF0aW9uIGNsYXNzZXMgbXVzdCBvdmVycmlkZSB0aGlzIG1ldGhvZAorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAgUmV0dXJucyBhcnJheSBvZiBieXRlcywgcmVwcmVzZW50aW5nIGltYWdlIG9mIHRoaXMgZ2x5cGgKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldEJpdG1hcCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBzaGFwZSB0aGF0IHJlcHJlc2VudHMgb3V0bGluZSBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4gCisgICAgICogCisgICAgICogQHBhcmFtIGMgc3BlY2lmaWVkIGNoYXJhY3RlcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTaGFwZSBpbml0T3V0bGluZShjaGFyIGMpOworCit9CisKKwpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9MaW5lTWV0cmljc0ltcGwuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvTGluZU1ldHJpY3NJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcwMTQ2ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvTGluZU1ldHJpY3NJbXBsLmphdmEKQEAgLTAsMCArMSw0MTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWx5YSBTLiBPa29taW4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250LkxpbmVNZXRyaWNzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICoKKyAqIExpbmVNZXRyaWNzIGltcGxlbWVudGF0aW9uIGNsYXNzLgorICovCisKK3B1YmxpYyBjbGFzcyBMaW5lTWV0cmljc0ltcGwgZXh0ZW5kcyBMaW5lTWV0cmljcyBpbXBsZW1lbnRzIENsb25lYWJsZXsKKworICAgIC8vIGFycmF5IG9mIGJhc2VsaW5lIG9mZnNldHMKKyAgICBmbG9hdFtdIGJhc2VsaW5lT2Zmc2V0czsKKworICAgIC8vIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBtZWFzdXJlCisgICAgaW50IG51bUNoYXJzOworCisgICAgLy8gYmFzZWxpbmUgaW5kZXggb2YgdGhlIGZvbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIGxpbmUgbWV0cmljcworICAgIGludCBiYXNlTGluZUluZGV4OworCisgICAgLy8gdW5kZXJsaW5lIHRoaWNrbmVzcworICAgIGZsb2F0IHVuZGVybGluZVRoaWNrbmVzczsKKworICAgIC8vIHVuZGVybGluZSBvZmZzZXQKKyAgICBmbG9hdCB1bmRlcmxpbmVPZmZzZXQ7CisKKyAgICAvLyBzdHJpa2V0aHJvdWdoIHRoaWNrbmVzcworICAgIGZsb2F0IHN0cmlrZXRocm91Z2hUaGlja25lc3M7CisKKyAgICAvLyBzdHJpa2V0aHJvdWdoIG9mZnNldAorICAgIGZsb2F0IHN0cmlrZXRocm91Z2hPZmZzZXQ7CisKKyAgICAvLyBFeHRlcm5hbCBsZWFkaW5nCisgICAgZmxvYXQgbGVhZGluZzsKKworICAgIC8vIEhlaWdodCBvZiB0aGUgZm9udCAoID09IChhc2NlbnQrZGVzY2VudCtsZWFkaW5nKSkKKyAgICBmbG9hdCBoZWlnaHQ7CisKKyAgICAvLyBBc2NlbnQgb2YgdGhlIGZvbnQKKyAgICBmbG9hdCBhc2NlbnQ7CisKKyAgICAvLyBEZXNjZW50IG9mIHRoZSBmb250CisgICAgZmxvYXQgZGVzY2VudDsKKworICAgIC8vIFdpZHRoIG9mIHRoZSB3aWRlc3QgY2hhciBpbiB0aGUgZm9udAorICAgIGZsb2F0IG1heENoYXJXaWR0aDsKKworICAgIC8vIHVuZGVybGluZSB0aGlja25lc3MgKGluIHBpeGVscykKKyAgICBpbnQgbFVuZGVybGluZVRoaWNrbmVzczsKKworICAgIC8vIHVuZGVybGluZSBvZmZzZXQgKGluIHBpeGVscykKKyAgICBpbnQgbFVuZGVybGluZU9mZnNldDsKKworICAgIC8vIHN0cmlrZXRocm91Z2ggdGhpY2tuZXNzIChpbiBwaXhlbHMpCisgICAgaW50IGxTdHJpa2V0aHJvdWdoVGhpY2tuZXNzOworCisgICAgLy8gc3RyaWtldGhyb3VnaCBvZmZzZXQgKGluIHBpeGVscykKKyAgICBpbnQgbFN0cmlrZXRocm91Z2hPZmZzZXQ7CisKKyAgICAvLyBFeHRlcm5hbCBsZWFkaW5nIChpbiBwaXhlbHMpCisgICAgaW50IGxMZWFkaW5nOworCisgICAgLy8gSGVpZ2h0IG9mIHRoZSBmb250ICggPT0gKGFzY2VudCtkZXNjZW50K2xlYWRpbmcpKSAoaW4gcGl4ZWxzKQorICAgIGludCBsSGVpZ2h0OworCisgICAgLy8gQXNjZW50IG9mIHRoZSBmb250IChpbiBwaXhlbHMpCisgICAgaW50IGxBc2NlbnQ7CisgICAgCisgICAgLy8gRGVzY2VudCBvZiB0aGUgZm9udCAoaW4gcGl4ZWxzKQorICAgIGludCBsRGVzY2VudDsKKworICAgIC8vICBXaWR0aCBvZiB0aGUgd2lkZXN0IGNoYXIgaW4gdGhlIGZvbnQgKGluIHBpeGVscykKKyAgICBpbnQgbE1heENoYXJXaWR0aDsKKworICAgIC8vIHVuaXRzIHBlciBFTSBzcXVhcmUgaW4gZm9udCB2YWx1ZQorICAgIGludCB1bml0c19wZXJfRU0gPSAwOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBMaW5lTWV0cmljc0ltcGwgb2JqZWN0IGZyb20gc3BlY2lmaWVkIHBhcmFtZXRlcnMuIElmIGJhc2VsaW5lIGRhdGEgcGFyYW1ldGVyCisgICAgICogaXMgbnVsbCB0aGFuIHswLCAoLWFzY2VudCtkZXNjZW50KS8yLCAtYXNjZW50fSB2YWx1ZXMgYXJlIHVzZWQgZm9yIGJhc2VsaW5lIG9mZnNldHMuCisgICAgICogIAorICAgICAqIEBwYXJhbSBsZW4gYSBudW1iZXIgb2YgY2hhcmFjdGVycyAKKyAgICAgKiBAcGFyYW0gbWV0cmljcyBhbiBhcnJheSBvZiAxNiBlbGVtZW50cyB3aXRoIG1ldHJpY3MgdmFsdWVzIHRoYXQgY2FuIGJlIAorICAgICAqIGluaXRpYWxpemVkIGluIG5hdGl2ZSBjb2RlLjxwPgorICAgICAqIG1ldHJpY3NbMF0gLSBhc2NlbnQ8cD4KKyAgICAgKiBtZXRyaWNzWzFdIC0gZGVzY2VudDxwPgorICAgICAqIG1ldHJpY3NbMl0gLSBleHRlcm5hbCBsZWFkaW5nPHA+CisgICAgICogbWV0cmljc1szXSAtIHVuZGVybGluZSB0aGlja25lc3M8cD4KKyAgICAgKiAtbWV0cmljc1s0XSAtIHVuZGVybGluZSBvZmZzZXQ8cD4KKyAgICAgKiBtZXRyaWNzWzVdIC0gc3RyaWtldGhyb3VnaCB0aGlja25lc3M8cD4KKyAgICAgKiAtbWV0cmljc1s2XSAtIHN0cmlrZXRocm91Z2ggb2Zmc2V0PHA+CisgICAgICogbWV0cmljc1s3XSAtIG1heGltdW0gY2hhciB3aWR0aDxwPgorICAgICAqIG1ldHJpY3NbOF0gLSBhc2NlbnQgaW4gcGl4ZWxzPHA+CisgICAgICogbWV0cmljc1s5XSAtIGRlc2NlbnQgaW4gcGl4bGVzPHA+CisgICAgICogbWV0cmljc1sxMF0gLSBleHRlcm5hbCBsZWFkaW5nIGluIHBpeGVsczxwPgorICAgICAqIG1ldHJpY3NbMTFdIC0gdW5kZXJsaW5lIHRoaWNrbmVzcyBpbiBwaXhlbHM8cD4KKyAgICAgKiAtbWV0cmljc1sxMl0gLSB1bmRlcmxpbmUgb2Zmc2V0IGluIHBpeGVsczxwPgorICAgICAqIG1ldHJpY3NbMTNdIC0gc3RyaWtldGhyb3VnaCB0aGlja25lc3MgaW4gcGl4ZWxzPHA+CisgICAgICogLW1ldHJpY3NbMTRdIC0gc3RyaWtldGhyb3VnaCBvZmZzZXQgaW4gcGl4ZWxzPHA+CisgICAgICogbWV0cmljc1sxNV0gLSBtYXhpbXVtIGNoYXIgd2lkdGggaW4gcGl4ZWxzPHA+CisKKyAgICAgKiBAcGFyYW0gX2Jhc2VsaW5lRGF0YSBhbiBhcnJheSBvZiAzIGVsZW1lbnRzIHdpdGggYmFzZWxpbmUgb2Zmc2V0cyBtZXRyaWNzPHA+CisgICAgICogX2Jhc2VsaW5lRGF0YVswXSAtIHJvbWFuIGJhc2VsaW5lIG9mZnNldDxwPiAKKyAgICAgKiBfYmFzZWxpbmVEYXRhWzFdIC0gY2VudGVyIGJhc2VsaW5lIG9mZnNldDxwPgorICAgICAqIF9iYXNlbGluZURhdGFbMl0gLSBoYW5naW5nIGJhc2VsaW5lIG9mZnNldDxwPgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTWV0cmljc0ltcGwoaW50IGxlbiwgZmxvYXRbXSBtZXRyaWNzLCBmbG9hdFtdIF9iYXNlbGluZURhdGEpeworICAgICAgICBudW1DaGFycyA9IGxlbjsKKworICAgICAgICBhc2NlbnQgPSBtZXRyaWNzWzBdOyAgICAvLyBBc2NlbnQgb2YgdGhlIGZvbnQKKyAgICAgICAgZGVzY2VudCA9IG1ldHJpY3NbMV07ICAgLy8gRGVzY2VudCBvZiB0aGUgZm9udAorICAgICAgICBsZWFkaW5nID0gbWV0cmljc1syXTsgIC8vIEV4dGVybmFsIGxlYWRpbmcKKyAgICAgICAgaGVpZ2h0ID0gbWV0cmljc1swXSArIG1ldHJpY3NbMV0gKyBtZXRyaWNzWzJdOyAgLy8gSGVpZ2h0IG9mIHRoZSBmb250ICggPT0gKGFzY2VudCArIGRlc2NlbnQgKyBsZWFkaW5nKSkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIExpbmVNZXRyaWNzSW1wbCBvYmplY3QgZnJvbSBzcGVjaWZpZWQgcGFyYW1ldGVycy4gSWYgYmFzZWxpbmUgZGF0YSBwYXJhbWV0ZXIKKyAgICAgKiBpcyBudWxsIHRoYW4gezAsICgtYXNjZW50K2Rlc2NlbnQpLzIsIC1hc2NlbnR9IHZhbHVlcyBhcmUgdXNlZCBmb3IgYmFzZWxpbmUgb2Zmc2V0cy4KKyAgICAgKiAgCisgICAgICogQHBhcmFtIF9udW1DaGFycyBudW1iZXIgb2YgY2hhcnMgCisgICAgICogQHBhcmFtIF9iYXNlTGluZUluZGV4IGluZGV4IG9mIHRoZSBiYXNlbGluZSBvZmZzZXQKKyAgICAgKiBAcGFyYW0gX2Jhc2VsaW5lT2Zmc2V0cyBhbiBhcnJheSBvZiBiYXNlbGluZSBvZmZzZXRzCisgICAgICogQHBhcmFtIF91bmRlcmxpbmVUaGlja25lc3MgdW5kZXJsaW5lIHRoaWNrbmVzcworICAgICAqIEBwYXJhbSBfdW5kZXJsaW5lT2Zmc2V0IHVuZGVybGluZSBvZmZzZXQKKyAgICAgKiBAcGFyYW0gX3N0cmlrZXRocm91Z2hUaGlja25lc3Mgc3RyaWtldGhyb3VnaCB0aGlja25lc3MKKyAgICAgKiBAcGFyYW0gX3N0cmlrZXRocm91Z2hPZmZzZXQgc3RyaW5rZXRocm91Z2ggb2Zmc2V0CisgICAgICogQHBhcmFtIF9sZWFkaW5nIGxlYWRpbmcgb2YgdGhlIGZvbnQKKyAgICAgKiBAcGFyYW0gX2hlaWdodCBmb250IGhlaWdodAorICAgICAqIEBwYXJhbSBfYXNjZW50IGFzY2VudCBvZiB0aGUgZm9udAorICAgICAqIEBwYXJhbSBfZGVzY2VudCBkZXNjZW50IG9mIHRoZSBmb250CisgICAgICogQHBhcmFtIF9tYXhDaGFyV2lkdGggbWF4IGNoYXIgd2lkdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZU1ldHJpY3NJbXBsKGludCBfbnVtQ2hhcnMsIGludCBfYmFzZUxpbmVJbmRleCwKKyAgICAgICAgICAgIGZsb2F0W10gX2Jhc2VsaW5lT2Zmc2V0cywgZmxvYXQgX3VuZGVybGluZVRoaWNrbmVzcywKKyAgICAgICAgICAgIGZsb2F0IF91bmRlcmxpbmVPZmZzZXQsIGZsb2F0IF9zdHJpa2V0aHJvdWdoVGhpY2tuZXNzLAorICAgICAgICAgICAgZmxvYXQgX3N0cmlrZXRocm91Z2hPZmZzZXQsIGZsb2F0IF9sZWFkaW5nLCBmbG9hdCBfaGVpZ2h0LAorICAgICAgICAgICAgZmxvYXQgX2FzY2VudCwgZmxvYXQgX2Rlc2NlbnQsIGZsb2F0IF9tYXhDaGFyV2lkdGgpIHsKKworICAgICAgICBudW1DaGFycyA9IF9udW1DaGFyczsKKyAgICAgICAgYmFzZUxpbmVJbmRleCA9IF9iYXNlTGluZUluZGV4OworICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgPSBfdW5kZXJsaW5lVGhpY2tuZXNzOworICAgICAgICB1bmRlcmxpbmVPZmZzZXQgPSBfdW5kZXJsaW5lT2Zmc2V0OworICAgICAgICBzdHJpa2V0aHJvdWdoVGhpY2tuZXNzID0gX3N0cmlrZXRocm91Z2hUaGlja25lc3M7CisgICAgICAgIHN0cmlrZXRocm91Z2hPZmZzZXQgPSBfc3RyaWtldGhyb3VnaE9mZnNldDsKKyAgICAgICAgbGVhZGluZyA9IF9sZWFkaW5nOworICAgICAgICBoZWlnaHQgPSBfaGVpZ2h0OworICAgICAgICBhc2NlbnQgPSBfYXNjZW50OworICAgICAgICBkZXNjZW50ID0gX2Rlc2NlbnQ7CisgICAgICAgIGJhc2VsaW5lT2Zmc2V0cyA9IF9iYXNlbGluZU9mZnNldHM7CisgICAgICAgIGxVbmRlcmxpbmVUaGlja25lc3MgPSAoaW50KSB1bmRlcmxpbmVUaGlja25lc3M7CisgICAgICAgIGxVbmRlcmxpbmVPZmZzZXQgPSAoaW50KSB1bmRlcmxpbmVPZmZzZXQ7CisgICAgICAgIGxTdHJpa2V0aHJvdWdoVGhpY2tuZXNzID0gKGludCkgc3RyaWtldGhyb3VnaFRoaWNrbmVzczsKKyAgICAgICAgbFN0cmlrZXRocm91Z2hPZmZzZXQgPSAoaW50KSBzdHJpa2V0aHJvdWdoT2Zmc2V0OworICAgICAgICBsTGVhZGluZyA9IChpbnQpIGxlYWRpbmc7CisgICAgICAgIGxIZWlnaHQgPSAoaW50KSBoZWlnaHQ7CisgICAgICAgIGxBc2NlbnQgPSAoaW50KSBhc2NlbnQ7CisgICAgICAgIGxEZXNjZW50ID0gKGludCkgZGVzY2VudDsKKyAgICAgICAgbWF4Q2hhcldpZHRoID0gX21heENoYXJXaWR0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgTGluZU1ldHJpY3NJbXBsKCl7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbGwgbWV0cmljcyBhcmUgc2NhbGVkIGFjY29yZGluZyB0byBzY2FsZVggYW5kIHNjYWxlWSB2YWx1ZXMuIAorICAgICAqIFRoaXMgZnVuY3Rpb24gaGVscHMgdG8gcmVjb21wdXRlIG1ldHJpY3MgYWNjb3JkaW5nIHRvIHRoZSBzY2FsZSBmYWN0b3JzCisgICAgICogb2YgZGVzaXJlZCBBZmZpbmVUcmFuc2Zvcm0uCisgICAgICogCisgICAgICogQHBhcmFtIHNjYWxlWCBzY2FsZSBYIGZhY3RvcgorICAgICAqIEBwYXJhbSBzY2FsZVkgc2NhbGUgWSBmYWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzY2FsZShmbG9hdCBzY2FsZVgsIGZsb2F0IHNjYWxlWSl7CisgICAgICAgIGZsb2F0IGFic1NjYWxlWCA9IE1hdGguYWJzKHNjYWxlWCk7CisgICAgICAgIGZsb2F0IGFic1NjYWxlWSA9IE1hdGguYWJzKHNjYWxlWSk7CisKKyAgICAgICAgdW5kZXJsaW5lVGhpY2tuZXNzICo9IGFic1NjYWxlWTsKKyAgICAgICAgdW5kZXJsaW5lT2Zmc2V0ICo9IHNjYWxlWTsKKyAgICAgICAgc3RyaWtldGhyb3VnaFRoaWNrbmVzcyAqPSBhYnNTY2FsZVk7CisgICAgICAgIHN0cmlrZXRocm91Z2hPZmZzZXQgKj0gc2NhbGVZOworICAgICAgICBsZWFkaW5nICo9IGFic1NjYWxlWTsKKyAgICAgICAgaGVpZ2h0ICo9IGFic1NjYWxlWTsKKyAgICAgICAgYXNjZW50ICo9IGFic1NjYWxlWTsKKyAgICAgICAgZGVzY2VudCAqPSBhYnNTY2FsZVk7CisKKyAgICAgICAgaWYoYmFzZWxpbmVPZmZzZXRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGdldEJhc2VsaW5lT2Zmc2V0cygpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPCBiYXNlbGluZU9mZnNldHMubGVuZ3RoOyBpKyspeworICAgICAgICAgICAgYmFzZWxpbmVPZmZzZXRzW2ldICo9IHNjYWxlWTsKKyAgICAgICAgfQorCisgICAgICAgIGxVbmRlcmxpbmVUaGlja25lc3MgKj0gYWJzU2NhbGVZOworICAgICAgICBsVW5kZXJsaW5lT2Zmc2V0ICo9IHNjYWxlWTsKKyAgICAgICAgbFN0cmlrZXRocm91Z2hUaGlja25lc3MgKj0gYWJzU2NhbGVZOworICAgICAgICBsU3RyaWtldGhyb3VnaE9mZnNldCAqPSBzY2FsZVk7CisgICAgICAgIGxMZWFkaW5nICAqPSBhYnNTY2FsZVk7CisgICAgICAgIGxIZWlnaHQgKj0gYWJzU2NhbGVZOworICAgICAgICBsQXNjZW50ICo9IGFic1NjYWxlWTsKKyAgICAgICAgbERlc2NlbnQgKj0gYWJzU2NhbGVZOworICAgICAgICBtYXhDaGFyV2lkdGggKj0gYWJzU2NhbGVYOworCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG9mZnNldCBvZiB0aGUgYmFzZWxpbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0W10gZ2V0QmFzZWxpbmVPZmZzZXRzKCkgeworICAgICAgICAvLyBYWFg6IGF0IHRoZSBtb21lbnQgdGhlcmUgb25seSBob3Jpem9udGFsIG1ldHJpY3MgYXJlIHRha2VuIGludG8KKyAgICAgICAgLy8gYWNjb3VudC4gSWYgdGhlcmUgaXMgbm8gYmFzZWxpbmUgaW5mb3JtYXRpb24gaW4gVHJ1ZVR5cGUgZm9udAorICAgICAgICAvLyBmaWxlIGRlZmF1bHQgdmFsdWVzIHVzZWQ6IHswLCAtYXNjZW50LCAoLWFzY2VudCtkZXNjZW50KS8yfQorCisgICAgICAgIHJldHVybiBiYXNlbGluZU9mZnNldHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG51bWJlciBvZiBjaGFycyBpbiBzcGVjaWZpZWQgdGV4dAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TnVtQ2hhcnMoKSB7CisgICAgICAgIHJldHVybiBudW1DaGFyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGluZGV4IG9mIHRoZSBiYXNlbGluZSwgb25lIG9mIHByZWRlZmluZWQgY29uc3RhbnRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0QmFzZWxpbmVJbmRleCgpIHsKKyAgICAgICAgLy8gQmFzZWxpbmUgaW5kZXggaXMgdGhlIGRlYWZ1bHQgYmFzZWxpbmUgaW5kZXggdmFsdWUKKyAgICAgICAgLy8gdGFrZW4gZnJvbSB0aGUgVHJ1ZVR5cGUgdGFibGUgIkJBU0UiLgorICAgICAgICByZXR1cm4gYmFzZUxpbmVJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaWNrbmVzcyBvZiB0aGUgVW5kZXJsaW5lLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRVbmRlcmxpbmVUaGlja25lc3MoKSB7CisgICAgICAgIHJldHVybiB1bmRlcmxpbmVUaGlja25lc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBvZmZzZXQgb2YgdGhlIFVuZGVybGluZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0VW5kZXJsaW5lT2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gdW5kZXJsaW5lT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpY2tuZXNzIG9mIHRoZSBTdHJpa2V0aHJvdWdoIGxpbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldFN0cmlrZXRocm91Z2hUaGlja25lc3MoKSB7CisgICAgICAgIHJldHVybiBzdHJpa2V0aHJvdWdoVGhpY2tuZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgb2Zmc2V0IG9mIHRoZSBTdHJpa2V0aHJvdWdoIGxpbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldFN0cmlrZXRocm91Z2hPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBzdHJpa2V0aHJvdWdoT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlYWRpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGdldExlYWRpbmcoKSB7CisgICAgICAgIHJldHVybiBsZWFkaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgZm9udC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0SGVpZ2h0KCkgeworICAgICAgICAvL3JldHVybiBoZWlnaHQ7IC8vIGVxdWFscyB0byAoYXNjZW50ICsgZGVzY2VudCArIGxlYWRpbmcpOworICAgIAlyZXR1cm4gYXNjZW50ICsgZGVzY2VudCArIGxlYWRpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVzY2VudC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RGVzY2VudCgpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXNjZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRBc2NlbnQoKSB7CisgICAgICAgIHJldHVybiBhc2NlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBsb2dpY2FsIHRoaWNrbmVzcyBvZiB0aGUgVW5kZXJsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9naWNhbFVuZGVybGluZVRoaWNrbmVzcygpIHsKKyAgICAgICAgcmV0dXJuIGxVbmRlcmxpbmVUaGlja25lc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBsb2dpY2FsIG9mZnNldCBvZiB0aGUgVW5kZXJsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9naWNhbFVuZGVybGluZU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIGxVbmRlcmxpbmVPZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBsb2dpY2FsIHRoaWNrbmVzcyBvZiB0aGUgU3RyaWtldGhyb3VnaCBsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9naWNhbFN0cmlrZXRocm91Z2hUaGlja25lc3MoKSB7CisgICAgICAgIHJldHVybiBsU3RyaWtldGhyb3VnaFRoaWNrbmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGxvZ2ljYWwgb2Zmc2V0IG9mIHRoZSBTdHJpa2V0aHJvdWdoIGxpbmUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMb2dpY2FsU3RyaWtldGhyb3VnaE9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIGxTdHJpa2V0aHJvdWdoT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvZ2ljYWwgbGVhZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExvZ2ljYWxMZWFkaW5nKCkgeworICAgICAgICByZXR1cm4gbExlYWRpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9naWNhbCBoZWlnaHQgb2YgdGhlIGZvbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMb2dpY2FsSGVpZ2h0KCkgeworICAgICAgICByZXR1cm4gbEhlaWdodDsgLy8gZXF1YWxzIHRvIChhc2NlbnQgKyBkZXNjZW50ICsgbGVhZGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9naWNhbCBkZXNjZW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9naWNhbERlc2NlbnQoKSB7CisgICAgICAgIHJldHVybiBsRGVzY2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2dpY2FsIGFzY2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExvZ2ljYWxBc2NlbnQoKSB7CisgICAgICAgIHJldHVybiBsQXNjZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvZ2ljYWwgc2l6ZSBvZiB0aGUgd2lkZXN0IGNoYXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMb2dpY2FsTWF4Q2hhcldpZHRoKCkgeworICAgICAgICByZXR1cm4gbE1heENoYXJXaWR0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSB3aWRlc3QgY2hhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0TWF4Q2hhcldpZHRoKCkgeworICAgICAgICByZXR1cm4gbWF4Q2hhcldpZHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBudW0gY2hhcnMgdG8gdGhlIGRlc2lyZWQgdmFsdWUuCisgICAgICogCisgICAgICogQHBhcmFtIG51bSBzcGVjaWZpZWQgbnVtYmVyIG9mIGNoYXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TnVtQ2hhcnMoaW50IG51bSl7CisgICAgICAgIG51bUNoYXJzID0gbnVtOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKXsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH1jYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSl7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dERlY29yYXRvci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9UZXh0RGVjb3JhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODE5MDVmZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dERlY29yYXRvci5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250OworCitpbXBvcnQgamF2YS5hd3QuQmFzaWNTdHJva2U7CitpbXBvcnQgamF2YS5hd3QuQ29sb3I7CitpbXBvcnQgamF2YS5hd3QuR3JhcGhpY3MyRDsKK2ltcG9ydCBqYXZhLmF3dC5QYWludDsKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5TdHJva2U7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQXJlYTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkxpbmUyRDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgcmVuZGVyaW5nIHRleHQgZGVjb3JhdGlvbnMgbGlrZQorICogdW5kZXJsaW5lLCBzdHJpa2V0aHJvdWdoLCB0ZXh0IHdpdGggYmFja2dyb3VuZCwgZXRjLgorICovCitwdWJsaWMgY2xhc3MgVGV4dERlY29yYXRvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGV4dERlY29yYXRvciBpbnN0ID0gbmV3IFRleHREZWNvcmF0b3IoKTsKKyAgICBwcml2YXRlIFRleHREZWNvcmF0b3IoKSB7fQorICAgIHN0YXRpYyBUZXh0RGVjb3JhdG9yIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gaW5zdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIGVuY2Fwc3VsYXRlcyBhIHNldCBvZiBkZWNvcmF0aW9uIGF0dHJpYnV0ZXMgZm9yIGEgc2luZ2xlIHRleHQgcnVuLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBEZWNvcmF0aW9uIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmFzaWNTdHJva2UgVU5ERVJMSU5FX0xPV19PTkVfUElYRUxfU1RST0tFID0KKyAgICAgICAgICAgICAgICBuZXcgQmFzaWNTdHJva2UoMSwgQmFzaWNTdHJva2UuQ0FQX0JVVFQsIEJhc2ljU3Ryb2tlLkpPSU5fTUlURVIsIDEwKTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCYXNpY1N0cm9rZSBVTkRFUkxJTkVfTE9XX1RXT19QSVhFTF9TVFJPS0UgPQorICAgICAgICAgICAgICAgIG5ldyBCYXNpY1N0cm9rZSgyLCBCYXNpY1N0cm9rZS5DQVBfQlVUVCwgQmFzaWNTdHJva2UuSk9JTl9NSVRFUiwgMTApOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJhc2ljU3Ryb2tlIFVOREVSTElORV9MT1dfRE9UVEVEX1NUUk9LRSA9CisgICAgICAgICAgICAgICAgbmV3IEJhc2ljU3Ryb2tlKAorICAgICAgICAgICAgICAgICAgICAgICAgMSwgQmFzaWNTdHJva2UuQ0FQX0JVVFQsIEJhc2ljU3Ryb2tlLkpPSU5fTUlURVIsIDEwLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGZsb2F0W10geyAxLCAxIH0sIDAKKyAgICAgICAgICAgICAgICApOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJhc2ljU3Ryb2tlIFVOREVSTElORV9MT1dfRE9UVEVEX1NUUk9LRTIgPQorICAgICAgICAgICAgICAgIG5ldyBCYXNpY1N0cm9rZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIDEsIEJhc2ljU3Ryb2tlLkNBUF9CVVRULCBCYXNpY1N0cm9rZS5KT0lOX01JVEVSLCAxMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBmbG9hdFtdIHsgMSwgMSB9LCAxCisgICAgICAgICAgICAgICAgKTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCYXNpY1N0cm9rZSBVTkRFUkxJTkVfTE9XX0RBU0hFRF9TVFJPS0UgPQorICAgICAgICAgICAgICAgIG5ldyBCYXNpY1N0cm9rZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIDEsIEJhc2ljU3Ryb2tlLkNBUF9CVVRULCBCYXNpY1N0cm9rZS5KT0lOX01JVEVSLCAxMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBmbG9hdFtdIHsgNCwgNCB9LCAwCisgICAgICAgICAgICAgICAgKTsKKworICAgICAgICBib29sZWFuIHVsT24gPSBmYWxzZTsgLy8gSGF2ZSBzdGFuZGFyZCB1bmRlcmxpbmU/CisgICAgICAgIEJhc2ljU3Ryb2tlIHVsU3Ryb2tlOworCisgICAgICAgIEJhc2ljU3Ryb2tlIGltVWxTdHJva2U7ICAvLyBTdHJva2UgZm9yIElOUFVUX01FVEhPRF9VTkRFUkxJTkUKKyAgICAgICAgQmFzaWNTdHJva2UgaW1VbFN0cm9rZTI7IC8vIFNwZWNpYWxseSBmb3IgVU5ERVJMSU5FX0xPV19HUkFZCisKKyAgICAgICAgYm9vbGVhbiBzdHJpa2VUaHJvdWdoOworICAgICAgICBCYXNpY1N0cm9rZSBzdHJpa2VUaHJvdWdoU3Ryb2tlOworCisgICAgICAgIGJvb2xlYW4gaGF2ZVN0cm9rZXMgPSBmYWxzZTsgLy8gU3Ryb2tlcyBhbHJlYWR5IGNyZWF0ZWQ/CisKKyAgICAgICAgYm9vbGVhbiBzd2FwQmZGZzsKKyAgICAgICAgUGFpbnQgYmc7IC8vIGJhY2tncm91bmQgY29sb3IKKyAgICAgICAgUGFpbnQgZmc7IC8vIGZvcmVncm91bmQgY29sb3IKKworICAgICAgICBQYWludCBncmFwaGljc1BhaW50OyAvLyBTbG90IGZvciBzYXZpbmcgY3VycmVudCBwYWludAorCisgICAgICAgIERlY29yYXRpb24oCisgICAgICAgICAgICAgICAgSW50ZWdlciBpbVVsLAorICAgICAgICAgICAgICAgIGJvb2xlYW4gc3dhcCwKKyAgICAgICAgICAgICAgICBib29sZWFuIHN0aCwKKyAgICAgICAgICAgICAgICBQYWludCBiZywgUGFpbnQgZmcsCisgICAgICAgICAgICAgICAgYm9vbGVhbiB1bE9uKSB7CisKKyAgICAgICAgICAgIGlmIChpbVVsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hpY2ggc3Ryb2tlIHRvIHVzZQorICAgICAgICAgICAgICAgIGlmIChpbVVsID09IFRleHRBdHRyaWJ1dGUuVU5ERVJMSU5FX0xPV19PTkVfUElYRUwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5pbVVsU3Ryb2tlID0gRGVjb3JhdGlvbi5VTkRFUkxJTkVfTE9XX09ORV9QSVhFTF9TVFJPS0U7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbVVsID09IFRleHRBdHRyaWJ1dGUuVU5ERVJMSU5FX0xPV19UV09fUElYRUwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5pbVVsU3Ryb2tlID0gRGVjb3JhdGlvbi5VTkRFUkxJTkVfTE9XX1RXT19QSVhFTF9TVFJPS0U7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbVVsID09IFRleHRBdHRyaWJ1dGUuVU5ERVJMSU5FX0xPV19ET1RURUQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5pbVVsU3Ryb2tlID0gRGVjb3JhdGlvbi5VTkRFUkxJTkVfTE9XX0RPVFRFRF9TVFJPS0U7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbVVsID09IFRleHRBdHRyaWJ1dGUuVU5ERVJMSU5FX0xPV19HUkFZKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaW1VbFN0cm9rZSA9IERlY29yYXRpb24uVU5ERVJMSU5FX0xPV19ET1RURURfU1RST0tFOworICAgICAgICAgICAgICAgICAgICB0aGlzLmltVWxTdHJva2UyID0gRGVjb3JhdGlvbi5VTkRFUkxJTkVfTE9XX0RPVFRFRF9TVFJPS0UyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW1VbCA9PSBUZXh0QXR0cmlidXRlLlVOREVSTElORV9MT1dfREFTSEVEKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaW1VbFN0cm9rZSA9IERlY29yYXRpb24uVU5ERVJMSU5FX0xPV19EQVNIRURfU1RST0tFOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy51bE9uID0gdWxPbjsgLy8gSGFzIHVuZGVybGluZQorICAgICAgICAgICAgdGhpcy5zd2FwQmZGZyA9IHN3YXA7CisgICAgICAgICAgICB0aGlzLnN0cmlrZVRocm91Z2ggPSBzdGg7CisgICAgICAgICAgICB0aGlzLmJnID0gYmc7CisgICAgICAgICAgICB0aGlzLmZnID0gZmc7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBzdHJva2VzIG9mIHByb3BlciB3aWR0aCBhY2NvcmRpbmcgdG8gdGhlIGluZm8KKyAgICAgICAgICogc3RvcmVkIGluIHRoZSBCYXNpY01ldHJpY3MKKyAgICAgICAgICogQHBhcmFtIG1ldHJpY3MgLSBiYXNpYyBtZXRyaWNzCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgZ2V0U3Ryb2tlcyhCYXNpY01ldHJpY3MgbWV0cmljcykgeworICAgICAgICAgICAgaWYgKCFoYXZlU3Ryb2tlcykgeworICAgICAgICAgICAgICAgIGlmIChzdHJpa2VUaHJvdWdoKSB7CisgICAgICAgICAgICAgICAgICAgIHN0cmlrZVRocm91Z2hTdHJva2UgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCYXNpY1N0cm9rZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3Muc3RyaWtldGhyb3VnaFRoaWNrbmVzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJhc2ljU3Ryb2tlLkNBUF9CVVRULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmFzaWNTdHJva2UuSk9JTl9NSVRFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAodWxPbikgeworICAgICAgICAgICAgICAgICAgICB1bFN0cm9rZSA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJhc2ljU3Ryb2tlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljcy51bmRlcmxpbmVUaGlja25lc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCYXNpY1N0cm9rZS5DQVBfQlVUVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJhc2ljU3Ryb2tlLkpPSU5fTUlURVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaGF2ZVN0cm9rZXMgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBEZWNvcmF0aW9uIG9iamVjdCBmcm9tIHRoZSBzZXQgb2YgdGV4dCBhdHRyaWJ1dGVzCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgLSB0ZXh0IGF0dHJpYnV0ZXMKKyAgICAgKiBAcmV0dXJuIERlY29yYXRpb24gb2JqZWN0CisgICAgICovCisgICAgc3RhdGljIERlY29yYXRpb24gZ2V0RGVjb3JhdGlvbihNYXA8PyBleHRlbmRzIEF0dHJpYnV0ZSwgPz4gYXR0cmlidXRlcykgeworICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gSXQgaXMgZm9yIHBsYWluIHRleHQKKyAgICAgICAgfQorCisgICAgICAgIE9iamVjdCB1bmRlcmxpbmUgPSBhdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLlVOREVSTElORSk7CisgICAgICAgIGJvb2xlYW4gaGFzU3RhbmRhcmRVbmRlcmxpbmUgPSB1bmRlcmxpbmUgPT0gVGV4dEF0dHJpYnV0ZS5VTkRFUkxJTkVfT047CisKKyAgICAgICAgT2JqZWN0IGltVW5kZXJsaW5lID0gYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5JTlBVVF9NRVRIT0RfVU5ERVJMSU5FKTsKKyAgICAgICAgSW50ZWdlciBpbVVsID0gKEludGVnZXIpIGltVW5kZXJsaW5lOworCisgICAgICAgIGJvb2xlYW4gc3dhcEJnRmcgPQorICAgICAgICAgICAgICAgIFRleHRBdHRyaWJ1dGUuU1dBUF9DT0xPUlNfT04uZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5TV0FQX0NPTE9SUykKKyAgICAgICAgICAgICAgICApOworCisgICAgICAgIGJvb2xlYW4gc3RyaWtlVGhyb3VnaCA9CisgICAgICAgICAgICAgICAgVGV4dEF0dHJpYnV0ZS5TVFJJS0VUSFJPVUdIX09OLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0KFRleHRBdHRyaWJ1dGUuU1RSSUtFVEhST1VHSCkKKyAgICAgICAgICAgICAgICApOworCisgICAgICAgIFBhaW50IGZnID0gKFBhaW50KSBhdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLkZPUkVHUk9VTkQpOworICAgICAgICBQYWludCBiZyA9IChQYWludCkgYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5CQUNLR1JPVU5EKTsKKworICAgICAgICBpZiAoCisgICAgICAgICAgICAgICAgIWhhc1N0YW5kYXJkVW5kZXJsaW5lICYmCisgICAgICAgICAgICAgICAgaW1VbmRlcmxpbmUgPT0gbnVsbCAmJgorICAgICAgICAgICAgICAgIGZnID09IG51bGwgJiYKKyAgICAgICAgICAgICAgICBiZyA9PSBudWxsICYmCisgICAgICAgICAgICAgICAgIXN3YXBCZ0ZnICYmCisgICAgICAgICAgICAgICAgIXN0cmlrZVRocm91Z2gKKyAgICAgICAgKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IERlY29yYXRpb24oaW1VbCwgc3dhcEJnRmcsIHN0cmlrZVRocm91Z2gsIGJnLCBmZywgaGFzU3RhbmRhcmRVbmRlcmxpbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBiYWNrZ3JvdW5kIGJlZm9yZSBkcmF3aW5nIGlmIG5lZWRlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdHJzIC0gdGV4dCBzZWdtZW50CisgICAgICogQHBhcmFtIGcyZCAtIGdyYXBoaWNzIHRvIGRyYXcgdG8KKyAgICAgKiBAcGFyYW0geE9mZnNldCAtIG9mZnNldCBpbiBYIGRpcmVjdGlvbiB0byB0aGUgdXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlCisgICAgICogICAgICAgIGxheW91dCBmcm9tIHRoZSBvcmlnaW4gb2YgdGhlIGdyYXBoaWNzCisgICAgICogQHBhcmFtIHlPZmZzZXQgLSBvZmZzZXQgaW4gWSBkaXJlY3Rpb24gdG8gdGhlIHVwcGVyIGxlZnQgY29ybmVyIG9mIHRoZQorICAgICAqICAgICAgICBsYXlvdXQgZnJvbSB0aGUgb3JpZ2luIG9mIHRoZSBncmFwaGljcworICAgICAqLworICAgIHN0YXRpYyB2b2lkIHByZXBhcmVHcmFwaGljcygKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHRycywgR3JhcGhpY3MyRCBnMmQsCisgICAgICAgICAgICBmbG9hdCB4T2Zmc2V0LCBmbG9hdCB5T2Zmc2V0CisgICAgKSB7CisgICAgICAgIERlY29yYXRpb24gZCA9IHRycy5kZWNvcmF0aW9uOworCisgICAgICAgIGlmIChkLmZnID09IG51bGwgJiYgZC5iZyA9PSBudWxsICYmIGQuc3dhcEJmRmcgPT0gZmFsc2UpIHsKKyAgICAgICAgICAgIHJldHVybjsgLy8gTm90aGluZyB0byBkbworICAgICAgICB9CisKKyAgICAgICAgZC5ncmFwaGljc1BhaW50ID0gZzJkLmdldFBhaW50KCk7CisKKyAgICAgICAgaWYgKGQuZmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZC5mZyA9IGQuZ3JhcGhpY3NQYWludDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkLnN3YXBCZkZnKSB7CisgICAgICAgICAgICAvLyBGaWxsIGJhY2tncm91bmQgYXJlYQorICAgICAgICAgICAgZzJkLnNldFBhaW50KGQuZmcpOworICAgICAgICAgICAgUmVjdGFuZ2xlMkQgYmdBcmVhID0gdHJzLmdldExvZ2ljYWxCb3VuZHMoKTsKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIHRvRmlsbCA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmdBcmVhLmdldFgoKSArIHhPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmdBcmVhLmdldFkoKSArIHlPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmdBcmVhLmdldFdpZHRoKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmdBcmVhLmdldEhlaWdodCgpCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICBnMmQuZmlsbCh0b0ZpbGwpOworCisgICAgICAgICAgICAvLyBTZXQgZm9yZWdyb3VuZCBjb2xvcgorICAgICAgICAgICAgZzJkLnNldFBhaW50KGQuYmcgPT0gbnVsbCA/IENvbG9yLldISVRFIDogZC5iZyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoZC5iZyAhPSBudWxsKSB7IC8vIEZpbGwgYmFja2dyb3VuZCBhcmVhCisgICAgICAgICAgICAgICAgZzJkLnNldFBhaW50KGQuYmcpOworICAgICAgICAgICAgICAgIFJlY3RhbmdsZTJEIGJnQXJlYSA9IHRycy5nZXRMb2dpY2FsQm91bmRzKCk7CisgICAgICAgICAgICAgICAgUmVjdGFuZ2xlMkQgdG9GaWxsID0KKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJnQXJlYS5nZXRYKCkgKyB4T2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZ0FyZWEuZ2V0WSgpICsgeU9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmdBcmVhLmdldFdpZHRoKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJnQXJlYS5nZXRIZWlnaHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICBnMmQuZmlsbCh0b0ZpbGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBTZXQgZm9yZWdyb3VuZCBjb2xvcgorICAgICAgICAgICAgZzJkLnNldFBhaW50KGQuZmcpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzdG9yZXMgdGhlIG9yaWdpbmFsIHN0YXRlIG9mIHRoZSBncmFwaGljcyBpZiBuZWVkZWQKKyAgICAgKiBAcGFyYW0gZCAtIGRlY29yYXRpb24KKyAgICAgKiBAcGFyYW0gZzJkIC0gZ3JhcGhpY3MKKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCByZXN0b3JlR3JhcGhpY3MoRGVjb3JhdGlvbiBkLCBHcmFwaGljczJEIGcyZCkgeworICAgICAgICBpZiAoZC5mZyA9PSBudWxsICYmIGQuYmcgPT0gbnVsbCAmJiBkLnN3YXBCZkZnID09IGZhbHNlKSB7CisgICAgICAgICAgICByZXR1cm47IC8vIE5vdGhpbmcgdG8gZG8KKyAgICAgICAgfQorCisgICAgICAgIGcyZC5zZXRQYWludChkLmdyYXBoaWNzUGFpbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbmRlcnMgdGhlIHRleHQgZGVjb3JhdGlvbnMKKyAgICAgKiBAcGFyYW0gdHJzIC0gdGV4dCBydW4gc2VnbWVudAorICAgICAqIEBwYXJhbSBnMmQgLSBncmFwaGljcyB0byByZW5kZXIgdG8KKyAgICAgKiBAcGFyYW0geE9mZnNldCAtIG9mZnNldCBpbiBYIGRpcmVjdGlvbiB0byB0aGUgdXBwZXIgbGVmdCBjb3JuZXIKKyAgICAgKiBvZiB0aGUgbGF5b3V0IGZyb20gdGhlIG9yaWdpbiBvZiB0aGUgZ3JhcGhpY3MKKyAgICAgKiBAcGFyYW0geU9mZnNldCAtIG9mZnNldCBpbiBZIGRpcmVjdGlvbiB0byB0aGUgdXBwZXIgbGVmdCBjb3JuZXIKKyAgICAgKiBvZiB0aGUgbGF5b3V0IGZyb20gdGhlIG9yaWdpbiBvZiB0aGUgZ3JhcGhpY3MKKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBkcmF3VGV4dERlY29yYXRpb25zKAorICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgdHJzLCBHcmFwaGljczJEIGcyZCwKKyAgICAgICAgICAgIGZsb2F0IHhPZmZzZXQsIGZsb2F0IHlPZmZzZXQKKyAgICApIHsKKyAgICAgICAgRGVjb3JhdGlvbiBkID0gdHJzLmRlY29yYXRpb247CisKKyAgICAgICAgaWYgKCFkLnVsT24gJiYgZC5pbVVsU3Ryb2tlID09IG51bGwgJiYgIWQuc3RyaWtlVGhyb3VnaCkgeworICAgICAgICAgICAgcmV0dXJuOyAvLyBOb3RoaW5nIHRvIGRvCisgICAgICAgIH0KKworICAgICAgICBmbG9hdCBsZWZ0ID0geE9mZnNldCArIChmbG9hdCkgdHJzLmdldExvZ2ljYWxCb3VuZHMoKS5nZXRNaW5YKCk7CisgICAgICAgIGZsb2F0IHJpZ2h0ID0geE9mZnNldCArIChmbG9hdCkgdHJzLmdldExvZ2ljYWxCb3VuZHMoKS5nZXRNYXhYKCk7CisKKyAgICAgICAgU3Ryb2tlIHNhdmVkU3Ryb2tlID0gZzJkLmdldFN0cm9rZSgpOworCisgICAgICAgIGQuZ2V0U3Ryb2tlcyh0cnMubWV0cmljcyk7CisKKyAgICAgICAgaWYgKGQuc3RyaWtlVGhyb3VnaCkgeworICAgICAgICAgICAgZmxvYXQgeSA9IHRycy55ICsgeU9mZnNldCArIHRycy5tZXRyaWNzLnN0cmlrZXRocm91Z2hPZmZzZXQ7CisgICAgICAgICAgICBnMmQuc2V0U3Ryb2tlKGQuc3RyaWtlVGhyb3VnaFN0cm9rZSk7CisgICAgICAgICAgICBnMmQuZHJhdyhuZXcgTGluZTJELkZsb2F0KGxlZnQsIHksIHJpZ2h0LCB5KSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZC51bE9uKSB7CisgICAgICAgICAgICBmbG9hdCB5ID0gdHJzLnkgKyB5T2Zmc2V0ICsgdHJzLm1ldHJpY3MudW5kZXJsaW5lT2Zmc2V0OworICAgICAgICAgICAgZzJkLnNldFN0cm9rZShkLnVsU3Ryb2tlKTsKKyAgICAgICAgICAgIGcyZC5kcmF3KG5ldyBMaW5lMkQuRmxvYXQobGVmdCwgeSwgcmlnaHQsIHkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkLmltVWxTdHJva2UgIT0gbnVsbCkgeworICAgICAgICAgICAgZmxvYXQgeSA9IHRycy55ICsgeU9mZnNldCArIHRycy5tZXRyaWNzLnVuZGVybGluZU9mZnNldDsKKyAgICAgICAgICAgIGcyZC5zZXRTdHJva2UoZC5pbVVsU3Ryb2tlKTsKKyAgICAgICAgICAgIGcyZC5kcmF3KG5ldyBMaW5lMkQuRmxvYXQobGVmdCwgeSwgcmlnaHQsIHkpKTsKKyAgICAgICAgICAgIGlmIChkLmltVWxTdHJva2UyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB5Kys7CisgICAgICAgICAgICAgICAgZzJkLnNldFN0cm9rZShkLmltVWxTdHJva2UyKTsKKyAgICAgICAgICAgICAgICBnMmQuZHJhdyhuZXcgTGluZTJELkZsb2F0KGxlZnQsIHksIHJpZ2h0LCB5KSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBnMmQuc2V0U3Ryb2tlKHNhdmVkU3Ryb2tlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRlbmRzIHRoZSB2aXN1YWwgYm91bmRzIG9mIHRoZSB0ZXh0IHJ1biBzZWdtZW50IHRvCisgICAgICogaW5jbHVkZSB0ZXh0IGRlY29yYXRpb25zLgorICAgICAqIEBwYXJhbSB0cnMgLSB0ZXh0IHNlZ21lbnQKKyAgICAgKiBAcGFyYW0gc2VnbWVudEJvdW5kcyAtIGJvdW5kcyBvZiB0aGUgdW5kZWNvcmF0ZWQgdGV4dAorICAgICAqIEBwYXJhbSBkIC0gZGVjb3JhdGlvbgorICAgICAqIEByZXR1cm4gZXh0ZW5kZWQgYm91bmRzCisgICAgICovCisgICAgc3RhdGljIFJlY3RhbmdsZTJEIGV4dGVuZFZpc3VhbEJvdW5kcygKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHRycywKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIHNlZ21lbnRCb3VuZHMsCisgICAgICAgICAgICBEZWNvcmF0aW9uIGQKKyAgICApIHsKKyAgICAgICAgaWYgKGQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHNlZ21lbnRCb3VuZHM7CisgICAgICAgIH0KKyAgICAgICAgZG91YmxlIG1pbnggPSBzZWdtZW50Qm91bmRzLmdldE1pblgoKTsKKyAgICAgICAgZG91YmxlIG1pbnkgPSBzZWdtZW50Qm91bmRzLmdldE1pblkoKTsKKyAgICAgICAgZG91YmxlIG1heHggPSBzZWdtZW50Qm91bmRzLmdldE1heFgoKTsKKyAgICAgICAgZG91YmxlIG1heHkgPSBzZWdtZW50Qm91bmRzLmdldE1heFkoKTsKKworICAgICAgICBSZWN0YW5nbGUyRCBsYiA9IHRycy5nZXRMb2dpY2FsQm91bmRzKCk7CisKKyAgICAgICAgaWYgKGQuc3dhcEJmRmcgfHwgZC5iZyAhPSBudWxsKSB7CisgICAgICAgICAgICBtaW54ID0gTWF0aC5taW4obGIuZ2V0TWluWCgpIC0gdHJzLngsIG1pbngpOworICAgICAgICAgICAgbWlueSA9IE1hdGgubWluKGxiLmdldE1pblkoKSAtIHRycy55LCBtaW55KTsKKyAgICAgICAgICAgIG1heHggPSBNYXRoLm1heChsYi5nZXRNYXhYKCkgLSB0cnMueCwgbWF4eCk7CisgICAgICAgICAgICBtYXh5ID0gTWF0aC5tYXgobGIuZ2V0TWF4WSgpIC0gdHJzLnksIG1heHkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGQudWxPbiB8fCBkLmltVWxTdHJva2UgIT0gbnVsbCB8fCBkLnN0cmlrZVRocm91Z2gpIHsKKyAgICAgICAgICAgIG1pbnggPSBNYXRoLm1pbihsYi5nZXRNaW5YKCkgLSB0cnMueCwgbWlueCk7CisgICAgICAgICAgICBtYXh4ID0gTWF0aC5tYXgobGIuZ2V0TWF4WCgpIC0gdHJzLngsIG1heHgpOworCisgICAgICAgICAgICBkLmdldFN0cm9rZXModHJzLm1ldHJpY3MpOworCisgICAgICAgICAgICBpZiAoZC51bFN0cm9rZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbWF4eSA9IE1hdGgubWF4KAorICAgICAgICAgICAgICAgICAgICAgICAgbWF4eSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRycy5tZXRyaWNzLnVuZGVybGluZU9mZnNldCArCisgICAgICAgICAgICAgICAgICAgICAgICBkLnVsU3Ryb2tlLmdldExpbmVXaWR0aCgpCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGQuaW1VbFN0cm9rZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbWF4eSA9IE1hdGgubWF4KAorICAgICAgICAgICAgICAgICAgICAgICAgbWF4eSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRycy5tZXRyaWNzLnVuZGVybGluZU9mZnNldCArCisgICAgICAgICAgICAgICAgICAgICAgICBkLmltVWxTdHJva2UuZ2V0TGluZVdpZHRoKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgKGQuaW1VbFN0cm9rZTIgPT0gbnVsbCA/IDAgOiBkLmltVWxTdHJva2UyLmdldExpbmVXaWR0aCgpKQorICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IFJlY3RhbmdsZTJELkRvdWJsZShtaW54LCBtaW55LCBtYXh4LW1pbngsIG1heHktbWlueSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0ZW5kcyB0aGUgb3V0bGluZSBvZiB0aGUgdGV4dCBydW4gc2VnbWVudCB0bworICAgICAqIGluY2x1ZGUgdGV4dCBkZWNvcmF0aW9ucy4KKyAgICAgKiBAcGFyYW0gdHJzIC0gdGV4dCBzZWdtZW50CisgICAgICogQHBhcmFtIHNlZ21lbnRPdXRsaW5lIC0gb3V0bGluZSBvZiB0aGUgdW5kZWNvcmF0ZWQgdGV4dAorICAgICAqIEBwYXJhbSBkIC0gZGVjb3JhdGlvbgorICAgICAqIEByZXR1cm4gZXh0ZW5kZWQgb3V0bGluZQorICAgICAqLworICAgIHN0YXRpYyBTaGFwZSBleHRlbmRPdXRsaW5lKAorICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgdHJzLAorICAgICAgICAgICAgU2hhcGUgc2VnbWVudE91dGxpbmUsCisgICAgICAgICAgICBEZWNvcmF0aW9uIGQKKyAgICApIHsKKyAgICAgICAgaWYgKGQgPT0gbnVsbCB8fCAhZC51bE9uICYmIGQuaW1VbFN0cm9rZSA9PSBudWxsICYmICFkLnN0cmlrZVRocm91Z2gpIHsKKyAgICAgICAgICAgIHJldHVybiBzZWdtZW50T3V0bGluZTsgLy8gTm90aGluZyB0byBkbworICAgICAgICB9CisKKyAgICAgICAgQXJlYSByZXMgPSBuZXcgQXJlYShzZWdtZW50T3V0bGluZSk7CisKKyAgICAgICAgZmxvYXQgbGVmdCA9IChmbG9hdCkgdHJzLmdldExvZ2ljYWxCb3VuZHMoKS5nZXRNaW5YKCkgLSB0cnMueDsKKyAgICAgICAgZmxvYXQgcmlnaHQgPSAoZmxvYXQpIHRycy5nZXRMb2dpY2FsQm91bmRzKCkuZ2V0TWF4WCgpIC0gdHJzLng7CisKKyAgICAgICAgZC5nZXRTdHJva2VzKHRycy5tZXRyaWNzKTsKKworICAgICAgICBpZiAoZC5zdHJpa2VUaHJvdWdoKSB7CisgICAgICAgICAgICBmbG9hdCB5ID0gdHJzLm1ldHJpY3Muc3RyaWtldGhyb3VnaE9mZnNldDsKKyAgICAgICAgICAgIHJlcy5hZGQobmV3IEFyZWEoZC5zdHJpa2VUaHJvdWdoU3Ryb2tlLmNyZWF0ZVN0cm9rZWRTaGFwZSgKKyAgICAgICAgICAgICAgICAgICAgbmV3IExpbmUyRC5GbG9hdChsZWZ0LCB5LCByaWdodCwgeSkKKyAgICAgICAgICAgICkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkLnVsT24pIHsKKyAgICAgICAgICAgIGZsb2F0IHkgPSB0cnMubWV0cmljcy51bmRlcmxpbmVPZmZzZXQ7CisgICAgICAgICAgICByZXMuYWRkKG5ldyBBcmVhKGQudWxTdHJva2UuY3JlYXRlU3Ryb2tlZFNoYXBlKAorICAgICAgICAgICAgICAgICAgICBuZXcgTGluZTJELkZsb2F0KGxlZnQsIHksIHJpZ2h0LCB5KQorICAgICAgICAgICAgKSkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGQuaW1VbFN0cm9rZSAhPSBudWxsKSB7CisgICAgICAgICAgICBmbG9hdCB5ID0gdHJzLm1ldHJpY3MudW5kZXJsaW5lT2Zmc2V0OworICAgICAgICAgICAgcmVzLmFkZChuZXcgQXJlYShkLmltVWxTdHJva2UuY3JlYXRlU3Ryb2tlZFNoYXBlKAorICAgICAgICAgICAgICAgICAgICBuZXcgTGluZTJELkZsb2F0KGxlZnQsIHksIHJpZ2h0LCB5KQorICAgICAgICAgICAgKSkpOworCisgICAgICAgICAgICBpZiAoZC5pbVVsU3Ryb2tlMiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgeSsrOworICAgICAgICAgICAgICAgIHJlcy5hZGQobmV3IEFyZWEoZC5pbVVsU3Ryb2tlMi5jcmVhdGVTdHJva2VkU2hhcGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGluZTJELkZsb2F0KGxlZnQsIHksIHJpZ2h0LCB5KQorICAgICAgICAgICAgICAgICkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9UZXh0TWV0cmljc0NhbGN1bGF0b3IuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dE1ldHJpY3NDYWxjdWxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU1NzYyYQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dE1ldHJpY3NDYWxjdWxhdG9yLmphdmEKQEAgLTAsMCArMSwyMDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworaW1wb3J0IGphdmEuYXd0LmZvbnQuTGluZU1ldHJpY3M7CitpbXBvcnQgamF2YS5hd3QuZm9udC5HcmFwaGljQXR0cmlidXRlOworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIFRoaXMgY2xhc3Mgb3BlcmF0ZXMgd2l0aCBhbiBhcmJpdHJhcnkgdGV4dCBzdHJpbmcgd2hpY2ggY2FuIGluY2x1ZGUKKyAqIGFueSBudW1iZXIgb2Ygc3R5bGUsIGZvbnQgYW5kIGRpcmVjdGlvbiBydW5zLiBJdCBpcyByZXNwb25zaWJsZSBmb3IgY29tcHV0YXRpb24KKyAqIG9mIHRoZSB0ZXh0IG1ldHJpY3MsIHN1Y2ggYXMgYXNjZW50LCBkZXNjZW50LCBsZWFkaW5nIGFuZCBhZHZhbmNlLiBBY3R1YWxseSwKKyAqIGVhY2ggdGV4dCBydW4gc2VnbWVudCBjb250YWlucyBsb2dpYyB3aGljaCBhbGxvd3MgaXQgdG8gY29tcHV0ZSBpdHMgb3duIG1ldHJpY3MgYW5kCisgKiByZXNwb25zaWJpbGl0eSBvZiB0aGlzIGNsYXNzIGlzIHRvIGNvbWJpbmUgbWV0cmljcyBmb3IgYWxsIHNlZ21lbnRzIGluY2x1ZGVkIGluIHRoZSB0ZXh0LAorICogbWFuYWdlZCBieSB0aGUgYXNzb2NpYXRlZCBUZXh0UnVuQnJlYWtlciBvYmplY3QuCisgKi8KK3B1YmxpYyBjbGFzcyBUZXh0TWV0cmljc0NhbGN1bGF0b3IgeworICAgIFRleHRSdW5CcmVha2VyIGJyZWFrZXI7IC8vIEFzc29jaWF0ZWQgcnVuIGJyZWFrZXIKKworICAgIC8vIE1ldHJpY3MKKyAgICBmbG9hdCBhc2NlbnQgPSAwOworICAgIGZsb2F0IGRlc2NlbnQgPSAwOworICAgIGZsb2F0IGxlYWRpbmcgPSAwOworICAgIGZsb2F0IGFkdmFuY2UgPSAwOworCisgICAgcHJpdmF0ZSBmbG9hdCBiYXNlbGluZU9mZnNldHNbXTsKKyAgICBpbnQgYmFzZWxpbmVJbmRleDsKKworICAgIHB1YmxpYyBUZXh0TWV0cmljc0NhbGN1bGF0b3IoVGV4dFJ1bkJyZWFrZXIgYnJlYWtlcikgeworICAgICAgICB0aGlzLmJyZWFrZXIgPSBicmVha2VyOworICAgICAgICBjaGVja0Jhc2VsaW5lcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZWl0aGVyIHZhbHVlcyBjYWNoZWQgYnkgY2hlY2tCYXNlbGluZXMgbWV0aG9kIG9yIHJlYXNvbmFibGUKKyAgICAgKiB2YWx1ZXMgZm9yIHRoZSBUT1AgYW5kIEJPVFRPTSBhbGlnbm1lbnRzLgorICAgICAqIEBwYXJhbSBiYXNlbGluZUluZGV4IC0gYmFzZWxpbmUgaW5kZXgKKyAgICAgKiBAcmV0dXJuIGJhc2VsaW5lIG9mZnNldAorICAgICAqLworICAgIGZsb2F0IGdldEJhc2VsaW5lT2Zmc2V0KGludCBiYXNlbGluZUluZGV4KSB7CisgICAgICAgIGlmIChiYXNlbGluZUluZGV4ID49IDApIHsKKyAgICAgICAgICAgIHJldHVybiBiYXNlbGluZU9mZnNldHNbYmFzZWxpbmVJbmRleF07CisgICAgICAgIH0gZWxzZSBpZiAoYmFzZWxpbmVJbmRleCA9PSBHcmFwaGljQXR0cmlidXRlLkJPVFRPTV9BTElHTk1FTlQpIHsKKyAgICAgICAgICAgIHJldHVybiBkZXNjZW50OworICAgICAgICB9IGVsc2UgaWYgKGJhc2VsaW5lSW5kZXggPT0gR3JhcGhpY0F0dHJpYnV0ZS5UT1BfQUxJR05NRU5UKSB7CisgICAgICAgICAgICByZXR1cm4gLWFzY2VudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGF3dC4zRj1JbnZhbGlkIGJhc2VsaW5lIGluZGV4CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmxvYXRbXSBnZXRCYXNlbGluZU9mZnNldHMoKSB7CisgICAgICAgIGZsb2F0IHJldFtdID0gbmV3IGZsb2F0W2Jhc2VsaW5lT2Zmc2V0cy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJhc2VsaW5lT2Zmc2V0cywgMCwgcmV0LCAwLCBiYXNlbGluZU9mZnNldHMubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUYWtlIGJhc2VsaW5lIG9mZnNldHMgZnJvbSB0aGUgZmlyc3QgZm9udCBvciBncmFwaGljIGF0dHJpYnV0ZQorICAgICAqIGFuZCBub3JtYWxpemVzIHRoZW0sIHRoYW4gY2FjaGVzIHRoZSByZXN1bHRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNoZWNrQmFzZWxpbmVzKCkgeworICAgICAgICAvLyBUYWtlIGJhc2VsaW5lIG9mZnNldHMgb2YgdGhlIGZpcnN0IGZvbnQgYW5kIG5vcm1hbGl6ZSB0aGVtCisgICAgICAgIEhhc2hNYXA8SW50ZWdlciwgRm9udD4gZm9udHMgPSBicmVha2VyLmZvbnRzOworCisgICAgICAgIE9iamVjdCB2YWwgPSBmb250cy5nZXQobmV3IEludGVnZXIoMCkpOworCisgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBGb250KSB7CisgICAgICAgICAgICBGb250IGZpcnN0Rm9udCA9IChGb250KSB2YWw7CisgICAgICAgICAgICBMaW5lTWV0cmljcyBsbSA9IGZpcnN0Rm9udC5nZXRMaW5lTWV0cmljcyhicmVha2VyLnRleHQsIDAsIDEsIGJyZWFrZXIuZnJjKTsKKyAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0cyA9IGxtLmdldEJhc2VsaW5lT2Zmc2V0cygpOworICAgICAgICAgICAgYmFzZWxpbmVJbmRleCA9IGxtLmdldEJhc2VsaW5lSW5kZXgoKTsKKyAgICAgICAgfSBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBHcmFwaGljQXR0cmlidXRlKSB7CisgICAgICAgICAgICAvLyBHZXQgZmlyc3QgZ3JhcGhpYyBhdHRyaWJ1dGUgYW5kIHVzZSBpdAorICAgICAgICAgICAgR3JhcGhpY0F0dHJpYnV0ZSBnYSA9IChHcmFwaGljQXR0cmlidXRlKSB2YWw7CisKKyAgICAgICAgICAgIGludCBhbGlnbiA9IGdhLmdldEFsaWdubWVudCgpOworCisgICAgICAgICAgICBpZiAoCisgICAgICAgICAgICAgICAgICAgIGFsaWduID09IEdyYXBoaWNBdHRyaWJ1dGUuVE9QX0FMSUdOTUVOVCB8fAorICAgICAgICAgICAgICAgICAgICBhbGlnbiA9PSBHcmFwaGljQXR0cmlidXRlLkJPVFRPTV9BTElHTk1FTlQKKyAgICAgICAgICAgICkgeworICAgICAgICAgICAgICAgIGJhc2VsaW5lSW5kZXggPSBHcmFwaGljQXR0cmlidXRlLlJPTUFOX0JBU0VMSU5FOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBiYXNlbGluZUluZGV4ID0gYWxpZ247CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0cyA9IG5ldyBmbG9hdFszXTsKKyAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0c1swXSA9IDA7CisgICAgICAgICAgICBiYXNlbGluZU9mZnNldHNbMV0gPSAoZ2EuZ2V0RGVzY2VudCgpIC0gZ2EuZ2V0QXNjZW50KCkpIC8gMi5mOworICAgICAgICAgICAgYmFzZWxpbmVPZmZzZXRzWzJdID0gLWdhLmdldEFzY2VudCgpOworICAgICAgICB9IGVsc2UgeyAvLyBVc2UgZGVmYXVsdHMgLSBSb21hbiBiYXNlbGluZSBhbmQgemVybyBvZmZzZXRzCisgICAgICAgICAgICBiYXNlbGluZUluZGV4ID0gR3JhcGhpY0F0dHJpYnV0ZS5ST01BTl9CQVNFTElORTsKKyAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0cyA9IG5ldyBmbG9hdFszXTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vcm1hbGl6ZSBvZmZzZXRzIGlmIG5lZWRlZAorICAgICAgICBpZiAoYmFzZWxpbmVPZmZzZXRzW2Jhc2VsaW5lSW5kZXhdICE9IDApIHsKKyAgICAgICAgICAgIGZsb2F0IGJhc2VPZmZzZXQgPSBiYXNlbGluZU9mZnNldHNbYmFzZWxpbmVJbmRleF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhc2VsaW5lT2Zmc2V0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0c1tpXSAtPSBiYXNlT2Zmc2V0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgbWV0cmljcyBmb3IgdGhlIHRleHQgbWFuYWdlZCBieSB0aGUgYXNzb2NpYXRlZCBUZXh0UnVuQnJlYWtlcgorICAgICAqLworICAgIHZvaWQgY29tcHV0ZU1ldHJpY3MoKSB7CisKKyAgICAgICAgQXJyYXlMaXN0PFRleHRSdW5TZWdtZW50PiBzZWdtZW50cyA9IGJyZWFrZXIucnVuU2VnbWVudHM7CisKKyAgICAgICAgZmxvYXQgbWF4SGVpZ2h0ID0gMDsKKyAgICAgICAgZmxvYXQgbWF4SGVpZ2h0TGVhZGluZyA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgc2VnbWVudCA9IHNlZ21lbnRzLmdldChpKTsKKyAgICAgICAgICAgIEJhc2ljTWV0cmljcyBtZXRyaWNzID0gc2VnbWVudC5tZXRyaWNzOworICAgICAgICAgICAgaW50IGJhc2VsaW5lID0gbWV0cmljcy5iYXNlTGluZUluZGV4OworCisgICAgICAgICAgICBpZiAoYmFzZWxpbmUgPj0gMCkgeworICAgICAgICAgICAgICAgIGZsb2F0IGJhc2VsaW5lT2Zmc2V0ID0gYmFzZWxpbmVPZmZzZXRzW21ldHJpY3MuYmFzZUxpbmVJbmRleF07CisgICAgICAgICAgICAgICAgZmxvYXQgZml4ZWREZXNjZW50ID0gbWV0cmljcy5kZXNjZW50ICsgYmFzZWxpbmVPZmZzZXQ7CisKKyAgICAgICAgICAgICAgICBhc2NlbnQgPSBNYXRoLm1heChhc2NlbnQsIG1ldHJpY3MuYXNjZW50IC0gYmFzZWxpbmVPZmZzZXQpOworICAgICAgICAgICAgICAgIGRlc2NlbnQgPSBNYXRoLm1heChkZXNjZW50LCBmaXhlZERlc2NlbnQpOworICAgICAgICAgICAgICAgIGxlYWRpbmcgPSBNYXRoLm1heChsZWFkaW5nLCBmaXhlZERlc2NlbnQgKyBtZXRyaWNzLmxlYWRpbmcpOworICAgICAgICAgICAgfSBlbHNlIHsgLy8gUG9zaXRpb24gaXMgbm90IGZpeGVkIGJ5IHRoZSBiYXNlbGluZSwgbmVlZCBzdW0gb2YgYXNjZW50IGFuZCBkZXNjZW50CisgICAgICAgICAgICAgICAgZmxvYXQgaGVpZ2h0ID0gbWV0cmljcy5hc2NlbnQgKyBtZXRyaWNzLmRlc2NlbnQ7CisKKyAgICAgICAgICAgICAgICBtYXhIZWlnaHQgPSBNYXRoLm1heChtYXhIZWlnaHQsIGhlaWdodCk7CisgICAgICAgICAgICAgICAgbWF4SGVpZ2h0TGVhZGluZyA9IE1hdGgubWF4KG1heEhlaWdodExlYWRpbmcsIGhlaWdodCArIG1ldHJpY3MubGVhZGluZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBOZWVkIHRvIGluY3JlYXNlIHNpemVzIGZvciBncmFwaGljcz8KKyAgICAgICAgaWYgKG1heEhlaWdodExlYWRpbmcgIT0gMCkgeworICAgICAgICAgICAgZGVzY2VudCA9IE1hdGgubWF4KGRlc2NlbnQsIG1heEhlaWdodCAtIGFzY2VudCk7CisgICAgICAgICAgICBsZWFkaW5nID0gTWF0aC5tYXgobGVhZGluZywgbWF4SGVpZ2h0TGVhZGluZyAtIGFzY2VudCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBOb3JtYWxpemUgbGVhZGluZworICAgICAgICBsZWFkaW5nIC09IGRlc2NlbnQ7CisKKyAgICAgICAgQmFzaWNNZXRyaWNzIGN1cnJNZXRyaWNzOworICAgICAgICBmbG9hdCBjdXJyQWR2YW5jZSA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgc2VnbWVudCA9IHNlZ21lbnRzLmdldChicmVha2VyLmdldFNlZ21lbnRGcm9tVmlzdWFsT3JkZXIoaSkpOworICAgICAgICAgICAgY3Vyck1ldHJpY3MgPSBzZWdtZW50Lm1ldHJpY3M7CisKKyAgICAgICAgICAgIHNlZ21lbnQueSA9IGdldEJhc2VsaW5lT2Zmc2V0KGN1cnJNZXRyaWNzLmJhc2VMaW5lSW5kZXgpCisgICAgICAgICAgICAgICAgICAgICsgY3Vyck1ldHJpY3Muc3VwZXJTY3JpcHRPZmZzZXQ7CisgICAgICAgICAgICBzZWdtZW50LnggPSBjdXJyQWR2YW5jZTsKKworICAgICAgICAgICAgY3VyckFkdmFuY2UgKz0gc2VnbWVudC5nZXRBZHZhbmNlKCk7CisgICAgICAgIH0KKworICAgICAgICBhZHZhbmNlID0gY3VyckFkdmFuY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgbWV0cmljcyBhbmQgY3JlYXRlcyBCYXNpY01ldHJpY3Mgb2JqZWN0IGZyb20gdGhlbQorICAgICAqIEByZXR1cm4gYmFzaWMgbWV0cmljcworICAgICAqLworICAgIHB1YmxpYyBCYXNpY01ldHJpY3MgY3JlYXRlTWV0cmljcygpIHsKKyAgICAgICAgY29tcHV0ZU1ldHJpY3MoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCYXNpY01ldHJpY3ModGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29ycmVjdHMgYWR2YW5jZSBhZnRlciBqdXN0aWZpY2F0aW9uLiBHZXRzIEJhc2ljTWV0cmljcyBvYmplY3QKKyAgICAgKiBhbmQgdXBkYXRlcyBhZHZhbmNlIHN0b3JlZCBpbnRvIGl0LgorICAgICAqIEBwYXJhbSBtZXRyaWNzIC0gbWV0cmljcyB3aXRoIG91dGRhdGVkIGFkdmFuY2Ugd2hpY2ggc2hvdWxkIGJlIGNvcnJlY3RlZCAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb3JyZWN0QWR2YW5jZShCYXNpY01ldHJpY3MgbWV0cmljcykgeworICAgICAgICBBcnJheUxpc3Q8VGV4dFJ1blNlZ21lbnQ+IHNlZ21lbnRzID0gYnJlYWtlci5ydW5TZWdtZW50czsKKyAgICAgICAgVGV4dFJ1blNlZ21lbnQgc2VnbWVudCA9IHNlZ21lbnRzLmdldChicmVha2VyCisgICAgICAgICAgICAgICAgLmdldFNlZ21lbnRGcm9tVmlzdWFsT3JkZXIoc2VnbWVudHMuc2l6ZSgpIC0gMSkpOworCisgICAgICAgIGFkdmFuY2UgPSBzZWdtZW50LnggKyBzZWdtZW50LmdldEFkdmFuY2UoKTsKKyAgICAgICAgbWV0cmljcy5hZHZhbmNlID0gYWR2YW5jZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L1RleHRSdW5CcmVha2VyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L1RleHRSdW5CcmVha2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU2MDZmNwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dFJ1bkJyZWFrZXIuamF2YQpAQCAtMCwwICsxLDg2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250OworCisKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkdlbmVyYWxQYXRoOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS5hd3QuaW0uSW5wdXRNZXRob2RIaWdobGlnaHQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC4qOworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5UZXh0RGVjb3JhdG9yLkRlY29yYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lm1pc2MuSGFzaENvZGU7CisvLyBUT0RPIC0gYmlkaSBub3QgaW1wbGVtZW50ZWQgeWV0CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgYnJlYWtpbmcgdGhlIHRleHQgaW50byB0aGUgcnVuIHNlZ21lbnRzCisgKiB3aXRoIGNvbnN0YW50IGZvbnQsIHN0eWxlLCBvdGhlciB0ZXh0IGF0dHJpYnV0ZXMgYW5kIGRpcmVjdGlvbi4KKyAqIEl0IGFsc28gc3RvcmVzIHRoZSBjcmVhdGVkIHRleHQgcnVuIHNlZ21lbnRzIGFuZCBjb3ZlcnMgZnVuY3Rpb25hbGl0eQorICogcmVsYXRlZCB0byB0aGUgb3BlcmF0aW9ucyBvbiB0aGUgc2V0IG9mIHNlZ21lbnRzLCBsaWtlIGNhbGN1bGF0aW5nIG1ldHJpY3MsCisgKiByZW5kZXJpbmcsIGp1c3RpZmljYXRpb24sIGhpdCB0ZXN0aW5nLCBldGMuCisgKi8KK3B1YmxpYyBjbGFzcyBUZXh0UnVuQnJlYWtlciBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGFjaTsKKyAgICBGb250UmVuZGVyQ29udGV4dCBmcmM7CisKKyAgICBjaGFyW10gdGV4dDsKKworICAgIGJ5dGVbXSBsZXZlbHM7CisKKyAgICBIYXNoTWFwPEludGVnZXIsIEZvbnQ+IGZvbnRzOworICAgIEhhc2hNYXA8SW50ZWdlciwgRGVjb3JhdGlvbj4gZGVjb3JhdGlvbnM7CisKKyAgICAvLyBSZWxhdGVkIHRvIGRlZmF1bHQgZm9udCBzdWJzdGl0dXRpb24KKyAgICBpbnQgZm9yY2VkRm9udFJ1blN0YXJ0c1tdOworCisgICAgQXJyYXlMaXN0PFRleHRSdW5TZWdtZW50PiBydW5TZWdtZW50cyA9IG5ldyBBcnJheUxpc3Q8VGV4dFJ1blNlZ21lbnQ+KCk7CisKKyAgICAvLyBGb3IgZmFzdCByZXRyaWV2aW5nIG9mIHRoZSBzZWdtZW50IGNvbnRhaW5pbmcKKyAgICAvLyBjaGFyYWN0ZXIgd2l0aCBrbm93biBsb2dpY2FsIGluZGV4CisgICAgaW50IGxvZ2ljYWwyc2VnbWVudFtdOworICAgIGludCBzZWdtZW50MnZpc3VhbFtdOyAvLyBWaXN1YWwgb3JkZXIgb2Ygc2VnbWVudHMgVE9ETyAtIGltcGxlbWVudAorICAgIGludCB2aXN1YWwyc2VnbWVudFtdOworICAgIGludCBsb2dpY2FsMnZpc3VhbFtdOworICAgIGludCB2aXN1YWwybG9naWNhbFtdOworCisgICAgU2VnbWVudHNJbmZvIHN0b3JlZFNlZ21lbnRzOworICAgIHByaXZhdGUgYm9vbGVhbiBoYXZlQWxsU2VnbWVudHMgPSBmYWxzZTsKKyAgICBpbnQgc2VnbWVudHNTdGFydCwgc2VnbWVudHNFbmQ7CisKKyAgICBmbG9hdCBqdXN0aWZpY2F0aW9uID0gMS4wZjsKKworICAgIHB1YmxpYyBUZXh0UnVuQnJlYWtlcihBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgYWNpLCBGb250UmVuZGVyQ29udGV4dCBmcmMpIHsKKyAgICAgICAgdGhpcy5hY2kgPSBhY2k7CisgICAgICAgIHRoaXMuZnJjID0gZnJjOworCisgICAgICAgIHNlZ21lbnRzU3RhcnQgPSBhY2kuZ2V0QmVnaW5JbmRleCgpOworICAgICAgICBzZWdtZW50c0VuZCA9IGFjaS5nZXRFbmRJbmRleCgpOworCisgICAgICAgIGludCBsZW4gPSBzZWdtZW50c0VuZCAtIHNlZ21lbnRzU3RhcnQ7CisgICAgICAgIHRleHQgPSBuZXcgY2hhcltsZW5dOworICAgICAgICBhY2kuc2V0SW5kZXgoc2VnbWVudHNFbmQpOworICAgICAgICB3aGlsZSAobGVuLS0gIT0gMCkgeyAvLyBHb2luZyBpbiBiYWNrd2FyZCBkaXJlY3Rpb24gaXMgZmFzdGVyPyBTaW1wbGllciBjaGVja3MgaGVyZT8KKyAgICAgICAgICAgIHRleHRbbGVuXSA9IGFjaS5wcmV2aW91cygpOworICAgICAgICB9CisKKyAgICAgICAgY3JlYXRlU3R5bGVSdW5zKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmlzdWFsIG9yZGVyIG9mIHRleHQgc2VnbWVudHMgbWF5IGRpZmZlciBmcm9tIHRoZSBsb2dpY2FsIG9yZGVyLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbGN1bGF0ZXMgdmlzdWFsIHBvc2l0aW9uIG9mIHRoZSBzZWdtZW50IGZyb20gaXRzIGxvZ2ljYWwgcG9zaXRpb24uCisgICAgICogQHBhcmFtIHNlZ21lbnROdW0gLSBsb2dpY2FsIHBvc2l0aW9uIG9mIHRoZSBzZWdtZW50CisgICAgICogQHJldHVybiB2aXN1YWwgcG9zaXRpb24gb2YgdGhlIHNlZ21lbnQKKyAgICAgKi8KKyAgICBpbnQgZ2V0VmlzdWFsRnJvbVNlZ21lbnRPcmRlcihpbnQgc2VnbWVudE51bSkgeworICAgICAgICByZXR1cm4gKHNlZ21lbnQydmlzdWFsID09IG51bGwpID8gc2VnbWVudE51bSA6IHNlZ21lbnQydmlzdWFsW3NlZ21lbnROdW1dOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZpc3VhbCBvcmRlciBvZiB0ZXh0IHNlZ21lbnRzIG1heSBkaWZmZXIgZnJvbSB0aGUgbG9naWNhbCBvcmRlci4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYWxjdWxhdGVzIGxvZ2ljYWwgcG9zaXRpb24gb2YgdGhlIHNlZ21lbnQgZnJvbSBpdHMgdmlzdWFsIHBvc2l0aW9uLgorICAgICAqIEBwYXJhbSB2aXN1YWwgLSB2aXN1YWwgcG9zaXRpb24gb2YgdGhlIHNlZ21lbnQKKyAgICAgKiBAcmV0dXJuIGxvZ2ljYWwgcG9zaXRpb24gb2YgdGhlIHNlZ21lbnQKKyAgICAgKi8KKyAgICBpbnQgZ2V0U2VnbWVudEZyb21WaXN1YWxPcmRlcihpbnQgdmlzdWFsKSB7CisgICAgICAgIHJldHVybiAodmlzdWFsMnNlZ21lbnQgPT0gbnVsbCkgPyB2aXN1YWwgOiB2aXN1YWwyc2VnbWVudFt2aXN1YWxdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZpc3VhbCBvcmRlciBvZiB0aGUgY2hhcmFjdGVycyBtYXkgZGlmZmVyIGZyb20gdGhlIGxvZ2ljYWwgb3JkZXIuCisgICAgICogVGhpcyBtZXRob2QgY2FsY3VsYXRlcyB2aXN1YWwgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciBmcm9tIGl0cyBsb2dpY2FsIHBvc2l0aW9uLgorICAgICAqIEBwYXJhbSBsb2dpY2FsIC0gbG9naWNhbCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyCisgICAgICogQHJldHVybiB2aXN1YWwgcG9zaXRpb24KKyAgICAgKi8KKyAgICBpbnQgZ2V0VmlzdWFsRnJvbUxvZ2ljYWwoaW50IGxvZ2ljYWwpIHsKKyAgICAgICAgcmV0dXJuIChsb2dpY2FsMnZpc3VhbCA9PSBudWxsKSA/IGxvZ2ljYWwgOiBsb2dpY2FsMnZpc3VhbFtsb2dpY2FsXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWaXN1YWwgb3JkZXIgb2YgdGhlIGNoYXJhY3RlcnMgbWF5IGRpZmZlciBmcm9tIHRoZSBsb2dpY2FsIG9yZGVyLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbGN1bGF0ZXMgbG9naWNhbCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGZyb20gaXRzIHZpc3VhbCBwb3NpdGlvbi4KKyAgICAgKiBAcGFyYW0gdmlzdWFsIC0gdmlzdWFsIHBvc2l0aW9uCisgICAgICogQHJldHVybiBsb2dpY2FsIHBvc2l0aW9uCisgICAgICovCisgICAgaW50IGdldExvZ2ljYWxGcm9tVmlzdWFsKGludCB2aXN1YWwpIHsKKyAgICAgICAgcmV0dXJuICh2aXN1YWwybG9naWNhbCA9PSBudWxsKSA/IHZpc3VhbCA6IHZpc3VhbDJsb2dpY2FsW3Zpc3VhbF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyB0aGUgZW5kIGluZGV4IG9mIHRoZSBsZXZlbCBydW4sIGxpbWl0ZWQgYnkgdGhlIGdpdmVuIHRleHQgcnVuLgorICAgICAqIEBwYXJhbSBydW5TdGFydCAtIHJ1biBzdGFydAorICAgICAqIEBwYXJhbSBydW5FbmQgLSBydW4gZW5kCisgICAgICogQHJldHVybiBlbmQgaW5kZXggb2YgdGhlIGxldmVsIHJ1bgorICAgICAqLworICAgIGludCBnZXRMZXZlbFJ1bkxpbWl0KGludCBydW5TdGFydCwgaW50IHJ1bkVuZCkgeworICAgICAgICBpZiAobGV2ZWxzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBydW5FbmQ7CisgICAgICAgIH0KKyAgICAgICAgaW50IGVuZExldmVsUnVuID0gcnVuU3RhcnQgKyAxOworICAgICAgICBieXRlIGxldmVsID0gbGV2ZWxzW3J1blN0YXJ0XTsKKworICAgICAgICB3aGlsZSAoZW5kTGV2ZWxSdW4gPD0gcnVuRW5kICYmIGxldmVsc1tlbmRMZXZlbFJ1bl0gPT0gbGV2ZWwpIHsKKyAgICAgICAgICAgIGVuZExldmVsUnVuKys7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZW5kTGV2ZWxSdW47CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBJbnB1dE1ldGhvZEhpZ2hsaWdodCB0byB0aGUgYXR0cmlidXRlcworICAgICAqIEBwYXJhbSBhdHRycyAtIHRleHQgYXR0cmlidXRlcworICAgICAqIEByZXR1cm4gcGF0Y2hlZCB0ZXh0IGF0dHJpYnV0ZXMKKyAgICAgKi8KKyAgICBNYXA8PyBleHRlbmRzIEF0dHJpYnV0ZSwgPz4gdW5wYWNrQXR0cmlidXRlcyhNYXA8PyBleHRlbmRzIEF0dHJpYnV0ZSwgPz4gYXR0cnMpIHsKKyAgICAgICAgaWYgKGF0dHJzLmNvbnRhaW5zS2V5KFRleHRBdHRyaWJ1dGUuSU5QVVRfTUVUSE9EX0hJR0hMSUdIVCkpIHsKKyAgICAgICAgICAgIE1hcDxUZXh0QXR0cmlidXRlLCA/PiBzdHlsZXMgPSBudWxsOworCisgICAgICAgICAgICBPYmplY3QgdmFsID0gYXR0cnMuZ2V0KFRleHRBdHRyaWJ1dGUuSU5QVVRfTUVUSE9EX0hJR0hMSUdIVCk7CisKKyAgICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBBbm5vdGF0aW9uKSB7CisgICAgICAgICAgICAgICAgdmFsID0gKChBbm5vdGF0aW9uKSB2YWwpLmdldFZhbHVlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBJbnB1dE1ldGhvZEhpZ2hsaWdodCkgeworICAgICAgICAgICAgICAgIElucHV0TWV0aG9kSGlnaGxpZ2h0IGlobCA9ICgoSW5wdXRNZXRob2RIaWdobGlnaHQpIHZhbCk7CisgICAgICAgICAgICAgICAgc3R5bGVzID0gaWhsLmdldFN0eWxlKCk7CisKKyAgICAgICAgICAgICAgICBpZiAoc3R5bGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgVG9vbGtpdCB0ayA9IFRvb2xraXQuZ2V0RGVmYXVsdFRvb2xraXQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3R5bGVzID0gdGsubWFwSW5wdXRNZXRob2RIaWdobGlnaHQoaWhsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzdHlsZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEhhc2hNYXA8QXR0cmlidXRlLCBPYmplY3Q+IG5ld0F0dHJzID0gbmV3IEhhc2hNYXA8QXR0cmlidXRlLCBPYmplY3Q+KCk7CisgICAgICAgICAgICAgICAgbmV3QXR0cnMucHV0QWxsKGF0dHJzKTsKKyAgICAgICAgICAgICAgICBuZXdBdHRycy5wdXRBbGwoc3R5bGVzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3QXR0cnM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYXR0cnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnJlYWtzIHRoZSB0ZXh0IGludG8gc2VwYXJhdGUgc3R5bGUgcnVucy4KKyAgICAgKi8KKyAgICB2b2lkIGNyZWF0ZVN0eWxlUnVucygpIHsKKyAgICAgICAgLy8gVE9ETyAtIGltcGxlbWVudCBmYXN0IGFuZCBzaW1wbGUgY2FzZQorICAgICAgICBmb250cyA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEZvbnQ+KCk7CisgICAgICAgIGRlY29yYXRpb25zID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgRGVjb3JhdGlvbj4oKTsKKyAgICAgICAgLy8vLworCisgICAgICAgIEFycmF5TGlzdDxJbnRlZ2VyPiBmb3JjZWRGb250UnVuU3RhcnRzTGlzdCA9IG51bGw7CisKKyAgICAgICAgTWFwPD8gZXh0ZW5kcyBBdHRyaWJ1dGUsID8+IGF0dHJpYnV0ZXMgPSBudWxsOworCisgICAgICAgIC8vIENoZWNrIGp1c3RpZmljYXRpb24gYXR0cmlidXRlCisgICAgICAgIE9iamVjdCB2YWwgPSBhY2kuZ2V0QXR0cmlidXRlKFRleHRBdHRyaWJ1dGUuSlVTVElGSUNBVElPTik7CisgICAgICAgIGlmICh2YWwgIT0gbnVsbCkgeworICAgICAgICAgICAganVzdGlmaWNhdGlvbiA9ICgoRmxvYXQpIHZhbCkuZmxvYXRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgZm9yICgKKyAgICAgICAgICAgIGludCBpbmRleCA9IHNlZ21lbnRzU3RhcnQsIG5leHRSdW5TdGFydCA9IHNlZ21lbnRzU3RhcnQ7CisgICAgICAgICAgICBpbmRleCA8IHNlZ21lbnRzRW5kOworICAgICAgICAgICAgaW5kZXggPSBuZXh0UnVuU3RhcnQsIGFjaS5zZXRJbmRleChpbmRleCkKKyAgICAgICAgICAgKSAgeworICAgICAgICAgICAgbmV4dFJ1blN0YXJ0ID0gYWNpLmdldFJ1bkxpbWl0KCk7CisgICAgICAgICAgICBhdHRyaWJ1dGVzID0gdW5wYWNrQXR0cmlidXRlcyhhY2kuZ2V0QXR0cmlidXRlcygpKTsKKworICAgICAgICAgICAgVGV4dERlY29yYXRvci5EZWNvcmF0aW9uIGQgPSBUZXh0RGVjb3JhdG9yLmdldERlY29yYXRpb24oYXR0cmlidXRlcyk7CisgICAgICAgICAgICBkZWNvcmF0aW9ucy5wdXQobmV3IEludGVnZXIoaW5kZXgpLCBkKTsKKworICAgICAgICAgICAgLy8gRmluZCBhcHByb3ByaWF0ZSBmb250IG9yIHBsYWNlIEdyYXBoaWNBdHRyaWJ1dGUgdGhlcmUKKworICAgICAgICAgICAgLy8gMS4gVHJ5IHRvIHBpY2sgdXAgQ0hBUl9SRVBMQUNFTUVOVCAoY29tcGF0aWJpbGl0eSkKKyAgICAgICAgICAgIEZvbnQgdmFsdWUgPSAoRm9udClhdHRyaWJ1dGVzLmdldChUZXh0QXR0cmlidXRlLkNIQVJfUkVQTEFDRU1FTlQpOworCisgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIDIuIFRyeSB0byBHZXQgRk9OVAorICAgICAgICAgICAgICAgIHZhbHVlID0gKEZvbnQpYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5GT05UKTsKKworICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIDMuIFRyeSB0byBjcmVhdGUgZm9udCBmcm9tIEZBTUlMWQorICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlcy5nZXQoVGV4dEF0dHJpYnV0ZS5GQU1JTFkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gRm9udC5nZXRGb250KGF0dHJpYnV0ZXMpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIDQuIE5vIGF0dHJpYnV0ZXMgZm91bmQsIHVzaW5nIGRlZmF1bHQuCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2VkRm9udFJ1blN0YXJ0c0xpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlZEZvbnRSdW5TdGFydHNMaXN0ID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgRm9udEZpbmRlci5maW5kRm9udHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0UnVuU3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlZEZvbnRSdW5TdGFydHNMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250cworICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZm9udHMuZ2V0KG5ldyBJbnRlZ2VyKGluZGV4KSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvbnRzLnB1dChuZXcgSW50ZWdlcihpbmRleCksIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlIGhhdmUgYWRkZWQgc29tZSBkZWZhdWx0IGZvbnRzLCBzbyB3ZSBoYXZlIHNvbWUgZXh0cmEgcnVucyBpbiB0ZXh0CisgICAgICAgIGlmIChmb3JjZWRGb250UnVuU3RhcnRzTGlzdCAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3JjZWRGb250UnVuU3RhcnRzID0gbmV3IGludFtmb3JjZWRGb250UnVuU3RhcnRzTGlzdC5zaXplKCldOworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZvcmNlZEZvbnRSdW5TdGFydHNMaXN0LnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZm9yY2VkRm9udFJ1blN0YXJ0c1tpXSA9CisgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZWRGb250UnVuU3RhcnRzTGlzdC5nZXQoaSkuaW50VmFsdWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gbG9va3MgZm9yIHRoZSBlbmQgb2YgdGhlIHRleHQgcnVuIHdpdGgKKyAgICAgKiBjb25zdGFudCB0ZXh0IGF0dHJpYnV0ZXMuCisgICAgICogQHBhcmFtIHJ1blN0YXJ0IC0gc3RhcnQgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0gbWF4UG9zIC0gcG9zaXRpb24gd2hlcmUgdG8gc3RvcCBpZiBubyBydW4gbGltaXQgZm91bmQKKyAgICAgKiBAcmV0dXJuIHN0eWxlIHJ1biBsaW1pdAorICAgICAqLworICAgIGludCBnZXRTdHlsZVJ1bkxpbWl0KGludCBydW5TdGFydCwgaW50IG1heFBvcykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWNpLnNldEluZGV4KHJ1blN0YXJ0KTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeyAvLyBJbmRleCBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICBpZiAocnVuU3RhcnQgPCBzZWdtZW50c1N0YXJ0KSB7CisgICAgICAgICAgICAgICAgYWNpLmZpcnN0KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFjaS5sYXN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB3ZSBoYXZlIHNvbWUgZXh0cmEgcnVucyB3ZSBuZWVkIHRvIGNoZWNrIGZvciB0aGVpciBsaW1pdHMKKyAgICAgICAgaWYgKGZvcmNlZEZvbnRSdW5TdGFydHMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgZWxlbWVudCA6IGZvcmNlZEZvbnRSdW5TdGFydHMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA+IHJ1blN0YXJ0KSB7CisgICAgICAgICAgICAgICAgICAgIG1heFBvcyA9IE1hdGgubWluKGVsZW1lbnQsIG1heFBvcyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBNYXRoLm1pbihhY2kuZ2V0UnVuTGltaXQoKSwgbWF4UG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHNlZ21lbnRzIGZvciB0aGUgdGV4dCBydW4gd2l0aAorICAgICAqIGNvbnN0YW50IGRlY29yYXRpb24sIGZvbnQgYW5kIGJpZGkgbGV2ZWwKKyAgICAgKiBAcGFyYW0gcnVuU3RhcnQgLSBydW4gc3RhcnQKKyAgICAgKiBAcGFyYW0gcnVuRW5kIC0gcnVuIGVuZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZVNlZ21lbnRzKGludCBydW5TdGFydCwgaW50IHJ1bkVuZCkgeworICAgICAgICBpbnQgZW5kU3R5bGVSdW4sIGVuZExldmVsUnVuOworCisgICAgICAgIC8vIFRPRE8gLSB1cGRhdGUgbGV2ZWxzCisKKyAgICAgICAgaW50IHBvcyA9IHJ1blN0YXJ0LCBsZXZlbFBvczsKKworICAgICAgICBhY2kuc2V0SW5kZXgocG9zKTsKKyAgICAgICAgZmluYWwgaW50IGZpcnN0UnVuU3RhcnQgPSBhY2kuZ2V0UnVuU3RhcnQoKTsKKyAgICAgICAgT2JqZWN0IHRkZCA9IGRlY29yYXRpb25zLmdldChuZXcgSW50ZWdlcihmaXJzdFJ1blN0YXJ0KSk7CisgICAgICAgIE9iamVjdCBmb250T3JHQXR0ciA9IGZvbnRzLmdldChuZXcgSW50ZWdlcihmaXJzdFJ1blN0YXJ0KSk7CisKKyAgICAgICAgbG9naWNhbDJzZWdtZW50ID0gbmV3IGludFtydW5FbmQgLSBydW5TdGFydF07CisKKyAgICAgICAgZG8geworICAgICAgICAgICAgZW5kU3R5bGVSdW4gPSBnZXRTdHlsZVJ1bkxpbWl0KHBvcywgcnVuRW5kKTsKKworICAgICAgICAgICAgLy8gcnVuU3RhcnQgY2FuIGJlIG5vbi16ZXJvLCBidXQgYWxsIGFycmF5cyB3aWxsIGJlIGluZGV4ZWQgZnJvbSAwCisgICAgICAgICAgICBpbnQgYWp1c3RlZFBvcyA9IHBvcyAtIHJ1blN0YXJ0OworICAgICAgICAgICAgaW50IGFqdXN0ZWRFbmRTdHlsZVJ1biA9IGVuZFN0eWxlUnVuIC0gcnVuU3RhcnQ7CisgICAgICAgICAgICBsZXZlbFBvcyA9IGFqdXN0ZWRQb3M7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgZW5kTGV2ZWxSdW4gPSBnZXRMZXZlbFJ1bkxpbWl0KGxldmVsUG9zLCBhanVzdGVkRW5kU3R5bGVSdW4pOworCisgICAgICAgICAgICAgICAgaWYgKGZvbnRPckdBdHRyIGluc3RhbmNlb2YgR3JhcGhpY0F0dHJpYnV0ZSkgeworICAgICAgICAgICAgICAgICAgICBydW5TZWdtZW50cy5hZGQoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGV4dFJ1blNlZ21lbnRJbXBsLlRleHRSdW5TZWdtZW50R3JhcGhpYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEdyYXBoaWNBdHRyaWJ1dGUpZm9udE9yR0F0dHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZExldmVsUnVuIC0gbGV2ZWxQb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsUG9zICsgcnVuU3RhcnQpCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKGxvZ2ljYWwyc2VnbWVudCwgbGV2ZWxQb3MsIGVuZExldmVsUnVuLCBydW5TZWdtZW50cy5zaXplKCktMSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnRJbXBsLlRleHRTZWdtZW50SW5mbyBpID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGV4dFJ1blNlZ21lbnRJbXBsLlRleHRTZWdtZW50SW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9PSBudWxsID8gMCA6IGxldmVsc1thanVzdGVkUG9zXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGb250KSBmb250T3JHQXR0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbFBvcyArIHJ1blN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kTGV2ZWxSdW4gKyBydW5TdGFydAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisKKyAgICAgICAgICAgICAgICAgICAgcnVuU2VnbWVudHMuYWRkKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUZXh0UnVuU2VnbWVudEltcGwuVGV4dFJ1blNlZ21lbnRDb21tb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRleHREZWNvcmF0b3IuRGVjb3JhdGlvbikgdGRkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQorICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChsb2dpY2FsMnNlZ21lbnQsIGxldmVsUG9zLCBlbmRMZXZlbFJ1biwgcnVuU2VnbWVudHMuc2l6ZSgpLTEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGxldmVsUG9zID0gZW5kTGV2ZWxSdW47CisgICAgICAgICAgICB9IHdoaWxlIChsZXZlbFBvcyA8IGFqdXN0ZWRFbmRTdHlsZVJ1bik7CisKKyAgICAgICAgICAgIC8vIFByZXBhcmUgbmV4dCBpdGVyYXRpb24KKyAgICAgICAgICAgIHBvcyA9IGVuZFN0eWxlUnVuOworICAgICAgICAgICAgdGRkID0gZGVjb3JhdGlvbnMuZ2V0KG5ldyBJbnRlZ2VyKHBvcykpOworICAgICAgICAgICAgZm9udE9yR0F0dHIgPSBmb250cy5nZXQobmV3IEludGVnZXIocG9zKSk7CisgICAgICAgIH0gd2hpbGUgKHBvcyA8IHJ1bkVuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRleHQgcnVuIHNlZ21lbnRzIGFyZSB1cCB0byBkYXRlIGFuZCBjcmVhdGVzIHRoZSBuZXcgc2VnbWVudHMgaWYgbm90LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZUFsbFNlZ21lbnRzKCkgeworICAgICAgICBpZiAoICFoYXZlQWxsU2VnbWVudHMgJiYKKyAgICAgICAgICAgIChsb2dpY2FsMnNlZ21lbnQgPT0gbnVsbCB8fAorICAgICAgICAgICAgIGxvZ2ljYWwyc2VnbWVudC5sZW5ndGggIT0gc2VnbWVudHNFbmQgLSBzZWdtZW50c1N0YXJ0KQorICAgICAgICApIHsgLy8gQ2hlY2sgaWYgd2UgZG9uJ3QgaGF2ZSBhbGwgc2VnbWVudHMgeWV0CisgICAgICAgICAgICByZXNldFNlZ21lbnRzKCk7CisgICAgICAgICAgICBjcmVhdGVTZWdtZW50cyhzZWdtZW50c1N0YXJ0LCBzZWdtZW50c0VuZCk7CisgICAgICAgIH0KKworICAgICAgICBoYXZlQWxsU2VnbWVudHMgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgcG9zaXRpb24gd2hlcmUgbGluZSBzaG91bGQgYmUgYnJva2VuIHdpdGhvdXQKKyAgICAgKiB0YWtpbmcgaW50byBhY2NvdW50IHdvcmQgYm91bmRhcmllcy4KKyAgICAgKiBAcGFyYW0gc3RhcnQgLSBzdGFydCBpbmRleAorICAgICAqIEBwYXJhbSBtYXhBZHZhbmNlIC0gbWF4aW11bSBhZHZhbmNlLCB3aWR0aCBvZiB0aGUgbGluZQorICAgICAqIEByZXR1cm4gcG9zaXRpb24gd2hlcmUgdG8gYnJlYWsKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVCcmVha0luZGV4KGludCBzdGFydCwgZmxvYXQgbWF4QWR2YW5jZSkgeworICAgICAgICBpbnQgYnJlYWtJbmRleDsKKyAgICAgICAgVGV4dFJ1blNlZ21lbnQgcyA9IG51bGw7CisKKyAgICAgICAgZm9yICgKKyAgICAgICAgICAgICAgICBpbnQgc2VnbWVudEluZGV4ID0gbG9naWNhbDJzZWdtZW50W3N0YXJ0XTsKKyAgICAgICAgICAgICAgICBzZWdtZW50SW5kZXggPCBydW5TZWdtZW50cy5zaXplKCk7CisgICAgICAgICAgICAgICAgc2VnbWVudEluZGV4KysKKyAgICAgICAgICAgKSB7CisgICAgICAgICAgICBzID0gcnVuU2VnbWVudHMuZ2V0KHNlZ21lbnRJbmRleCk7CisgICAgICAgICAgICBicmVha0luZGV4ID0gcy5nZXRDaGFySW5kZXhGcm9tQWR2YW5jZShtYXhBZHZhbmNlLCBzdGFydCk7CisKKyAgICAgICAgICAgIGlmIChicmVha0luZGV4IDwgcy5nZXRFbmQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBicmVha0luZGV4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWF4QWR2YW5jZSAtPSBzLmdldEFkdmFuY2VEZWx0YShzdGFydCwgcy5nZXRFbmQoKSk7CisgICAgICAgICAgICBzdGFydCA9IHMuZ2V0RW5kKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcy5nZXRFbmQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIGNoYXJhY3RlciBpbnRvIHRoZSBtYW5hZ2VkIHRleHQuCisgICAgICogQHBhcmFtIG5ld1BhcmFncmFwaCAtIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IKKyAgICAgKiBAcGFyYW0gaW5zZXJ0UG9zIC0gaW5zZXJ0aW9uIHBvc2l0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5zZXJ0Q2hhcihBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgbmV3UGFyYWdyYXBoLCBpbnQgaW5zZXJ0UG9zKSB7CisgICAgICAgIGFjaSA9IG5ld1BhcmFncmFwaDsKKworICAgICAgICBjaGFyIGluc0NoYXIgPSBhY2kuc2V0SW5kZXgoaW5zZXJ0UG9zKTsKKworICAgICAgICBJbnRlZ2VyIGtleSA9IG5ldyBJbnRlZ2VyKGluc2VydFBvcyk7CisKKyAgICAgICAgaW5zZXJ0UG9zIC09IGFjaS5nZXRCZWdpbkluZGV4KCk7CisKKyAgICAgICAgY2hhciBuZXdUZXh0W10gPSBuZXcgY2hhclt0ZXh0Lmxlbmd0aCArIDFdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRleHQsIDAsIG5ld1RleHQsIDAsIGluc2VydFBvcyk7CisgICAgICAgIG5ld1RleHRbaW5zZXJ0UG9zXSA9IGluc0NoYXI7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGV4dCwgaW5zZXJ0UG9zLCBuZXdUZXh0LCBpbnNlcnRQb3MrMSwgdGV4dC5sZW5ndGggLSBpbnNlcnRQb3MpOworICAgICAgICB0ZXh0ID0gbmV3VGV4dDsKKworICAgICAgICBpZiAoYWNpLmdldFJ1blN0YXJ0KCkgPT0ga2V5LmludFZhbHVlKCkgJiYgYWNpLmdldFJ1bkxpbWl0KCkgPT0ga2V5LmludFZhbHVlKCkgKyAxKSB7CisgICAgICAgICAgICBjcmVhdGVTdHlsZVJ1bnMoKTsgLy8gV2UgaGF2ZSB0byBjcmVhdGUgb25lIG5ldyBydW4sIGNvdWxkIGJlIG9wdGltaXplZAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2hpZnRTdHlsZVJ1bnMoa2V5LCAxKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlc2V0U2VnbWVudHMoKTsKKworICAgICAgICBzZWdtZW50c0VuZCsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgY2hhcmFjdGVyIGZyb20gdGhlIG1hbmFnZWQgdGV4dC4KKyAgICAgKiBAcGFyYW0gbmV3UGFyYWdyYXBoIC0gbmV3IGNoYXJhY3RlciBpdGVyYXRvcgorICAgICAqIEBwYXJhbSBkZWxldGVQb3MgLSBkZWxldGlvbiBwb3NpdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUNoYXIoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIG5ld1BhcmFncmFwaCwgaW50IGRlbGV0ZVBvcykgeworICAgICAgICBhY2kgPSBuZXdQYXJhZ3JhcGg7CisKKyAgICAgICAgSW50ZWdlciBrZXkgPSBuZXcgSW50ZWdlcihkZWxldGVQb3MpOworCisgICAgICAgIGRlbGV0ZVBvcyAtPSBhY2kuZ2V0QmVnaW5JbmRleCgpOworCisgICAgICAgIGNoYXIgbmV3VGV4dFtdID0gbmV3IGNoYXJbdGV4dC5sZW5ndGggLSAxXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0ZXh0LCAwLCBuZXdUZXh0LCAwLCBkZWxldGVQb3MpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRleHQsIGRlbGV0ZVBvcysxLCBuZXdUZXh0LCBkZWxldGVQb3MsIG5ld1RleHQubGVuZ3RoIC0gZGVsZXRlUG9zKTsKKyAgICAgICAgdGV4dCA9IG5ld1RleHQ7CisKKyAgICAgICAgaWYgKGZvbnRzLmdldChrZXkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvbnRzLnJlbW92ZShrZXkpOworICAgICAgICB9CisKKyAgICAgICAgc2hpZnRTdHlsZVJ1bnMoa2V5LCAtMSk7CisKKyAgICAgICAgcmVzZXRTZWdtZW50cygpOworCisgICAgICAgIHNlZ21lbnRzRW5kLS07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hpZnQgYWxsIHJ1bnMgYWZ0ZXIgc3BlY2lmaWVkIHBvc2l0aW9uLCBuZWVkZWQgdG8gcGVyZm9tIGluc2VydGlvbgorICAgICAqIG9yIGRlbGV0aW9uIGluIHRoZSBtYW5hZ2VkIHRleHQKKyAgICAgKiBAcGFyYW0gcG9zIC0gcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQKKyAgICAgKiBAcGFyYW0gc2hpZnQgLSBzaGlmdCwgY291bGQgYmUgbmVnYXRpdmUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2hpZnRTdHlsZVJ1bnMoSW50ZWdlciBwb3MsIGZpbmFsIGludCBzaGlmdCkgeworICAgICAgICBBcnJheUxpc3Q8SW50ZWdlcj4ga2V5cyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKKworICAgICAgICBJbnRlZ2VyIGtleSwgb2xka2V5OworICAgICAgICBmb3IgKEl0ZXJhdG9yPEludGVnZXI+IGl0ID0gZm9udHMua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgIG9sZGtleSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChvbGRrZXkuaW50VmFsdWUoKSA+IHBvcy5pbnRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAga2V5cy5hZGQob2xka2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGk9MDsgaTxrZXlzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBvbGRrZXkgPSBrZXlzLmdldChpKTsKKyAgICAgICAgICAgIGtleSA9IG5ldyBJbnRlZ2VyKHNoaWZ0ICsgb2xka2V5LmludFZhbHVlKCkpOworICAgICAgICAgICAgZm9udHMucHV0KGtleSwgZm9udHMucmVtb3ZlKG9sZGtleSkpOworICAgICAgICAgICAgZGVjb3JhdGlvbnMucHV0KGtleSwgZGVjb3JhdGlvbnMucmVtb3ZlKG9sZGtleSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHN0YXRlIG9mIHRoZSBjbGFzcworICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldFNlZ21lbnRzKCkgeworICAgICAgICBydW5TZWdtZW50cyA9IG5ldyBBcnJheUxpc3Q8VGV4dFJ1blNlZ21lbnQ+KCk7CisgICAgICAgIGxvZ2ljYWwyc2VnbWVudCA9IG51bGw7CisgICAgICAgIHNlZ21lbnQydmlzdWFsID0gbnVsbDsKKyAgICAgICAgdmlzdWFsMnNlZ21lbnQgPSBudWxsOworICAgICAgICBsZXZlbHMgPSBudWxsOworICAgICAgICBoYXZlQWxsU2VnbWVudHMgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIFNlZ21lbnRzSW5mbyB7CisgICAgICAgIEFycmF5TGlzdDxUZXh0UnVuU2VnbWVudD4gcnVuU2VnbWVudHM7CisgICAgICAgIGludCBsb2dpY2FsMnNlZ21lbnRbXTsKKyAgICAgICAgaW50IHNlZ21lbnQydmlzdWFsW107CisgICAgICAgIGludCB2aXN1YWwyc2VnbWVudFtdOworICAgICAgICBieXRlIGxldmVsc1tdOworICAgICAgICBpbnQgc2VnbWVudHNTdGFydDsKKyAgICAgICAgaW50IHNlZ21lbnRzRW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmVzIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiB0aGUgY2xhc3MKKyAgICAgKiBAcGFyYW0gbmV3U2VnU3RhcnQgLSBuZXcgc3RhcnQgaW5kZXggaW4gdGhlIHRleHQKKyAgICAgKiBAcGFyYW0gbmV3U2VnRW5kIC0gbmV3IGVuZCBpbmRleCBpbiB0aGUgdGV4dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1c2hTZWdtZW50cyhpbnQgbmV3U2VnU3RhcnQsIGludCBuZXdTZWdFbmQpIHsKKyAgICAgICAgc3RvcmVkU2VnbWVudHMgPSBuZXcgU2VnbWVudHNJbmZvKCk7CisgICAgICAgIHN0b3JlZFNlZ21lbnRzLnJ1blNlZ21lbnRzID0gdGhpcy5ydW5TZWdtZW50czsKKyAgICAgICAgc3RvcmVkU2VnbWVudHMubG9naWNhbDJzZWdtZW50ID0gdGhpcy5sb2dpY2FsMnNlZ21lbnQ7CisgICAgICAgIHN0b3JlZFNlZ21lbnRzLnNlZ21lbnQydmlzdWFsID0gdGhpcy5zZWdtZW50MnZpc3VhbDsKKyAgICAgICAgc3RvcmVkU2VnbWVudHMudmlzdWFsMnNlZ21lbnQgPSB0aGlzLnZpc3VhbDJzZWdtZW50OworICAgICAgICBzdG9yZWRTZWdtZW50cy5sZXZlbHMgPSB0aGlzLmxldmVsczsKKyAgICAgICAgc3RvcmVkU2VnbWVudHMuc2VnbWVudHNTdGFydCA9IHNlZ21lbnRzU3RhcnQ7CisgICAgICAgIHN0b3JlZFNlZ21lbnRzLnNlZ21lbnRzRW5kID0gc2VnbWVudHNFbmQ7CisKKyAgICAgICAgcmVzZXRTZWdtZW50cygpOworCisgICAgICAgIHNlZ21lbnRzU3RhcnQgPSBuZXdTZWdTdGFydDsKKyAgICAgICAgc2VnbWVudHNFbmQgPSBuZXdTZWdFbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzdG9yZXMgdGhlIGludGVybmFsIHN0YXRlIG9mIHRoZSBjbGFzcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBvcFNlZ21lbnRzKCkgeworICAgICAgICBpZiAoc3RvcmVkU2VnbWVudHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ydW5TZWdtZW50cyA9IHN0b3JlZFNlZ21lbnRzLnJ1blNlZ21lbnRzOworICAgICAgICB0aGlzLmxvZ2ljYWwyc2VnbWVudCA9IHN0b3JlZFNlZ21lbnRzLmxvZ2ljYWwyc2VnbWVudDsKKyAgICAgICAgdGhpcy5zZWdtZW50MnZpc3VhbCA9IHN0b3JlZFNlZ21lbnRzLnNlZ21lbnQydmlzdWFsOworICAgICAgICB0aGlzLnZpc3VhbDJzZWdtZW50ID0gc3RvcmVkU2VnbWVudHMudmlzdWFsMnNlZ21lbnQ7CisgICAgICAgIHRoaXMubGV2ZWxzID0gc3RvcmVkU2VnbWVudHMubGV2ZWxzOworICAgICAgICB0aGlzLnNlZ21lbnRzU3RhcnQgPSBzdG9yZWRTZWdtZW50cy5zZWdtZW50c1N0YXJ0OworICAgICAgICB0aGlzLnNlZ21lbnRzRW5kID0gc3RvcmVkU2VnbWVudHMuc2VnbWVudHNFbmQ7CisgICAgICAgIHN0b3JlZFNlZ21lbnRzID0gbnVsbDsKKworICAgICAgICBpZiAocnVuU2VnbWVudHMuc2l6ZSgpID09IDAgJiYgbG9naWNhbDJzZWdtZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIGhhdmVBbGxTZWdtZW50cyA9IGZhbHNlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaGF2ZUFsbFNlZ21lbnRzID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXh0UnVuQnJlYWtlciByZXMgPSAoVGV4dFJ1bkJyZWFrZXIpIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICByZXMuc3RvcmVkU2VnbWVudHMgPSBudWxsOworICAgICAgICAgICAgQXJyYXlMaXN0PFRleHRSdW5TZWdtZW50PiBuZXdTZWdtZW50cyA9IG5ldyBBcnJheUxpc3Q8VGV4dFJ1blNlZ21lbnQ+KHJ1blNlZ21lbnRzLnNpemUoKSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1blNlZ21lbnRzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgc2VnID0gIHJ1blNlZ21lbnRzLmdldChpKTsKKyAgICAgICAgICAgICAgICBuZXdTZWdtZW50cy5hZGQoKFRleHRSdW5TZWdtZW50KXNlZy5jbG9uZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlcy5ydW5TZWdtZW50cyA9IG5ld1NlZ21lbnRzOworICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gYXd0LjNFPUNsb25lIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zRSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgVGV4dFJ1bkJyZWFrZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBUZXh0UnVuQnJlYWtlciBiciA9IChUZXh0UnVuQnJlYWtlcikgb2JqOworCisgICAgICAgIGlmIChici5nZXRBQ0koKS5lcXVhbHMoYWNpKSAmJiBici5mcmMuZXF1YWxzKGZyYykpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBIYXNoQ29kZS5jb21iaW5lKGFjaS5oYXNoQ29kZSgpLCBmcmMuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVuZGVycyB0aGUgbWFuYWdlZCB0ZXh0CisgICAgICogQHBhcmFtIGcyZCAtIGdyYXBoaWNzIHdoZXJlIHRvIHJlbmRlcgorICAgICAqIEBwYXJhbSB4T2Zmc2V0IC0gb2Zmc2V0IGluIFggZGlyZWN0aW9uIHRvIHRoZSB1cHBlciBsZWZ0IGNvcm5lcgorICAgICAqIG9mIHRoZSBsYXlvdXQgZnJvbSB0aGUgb3JpZ2luIG9mIHRoZSBncmFwaGljcworICAgICAqIEBwYXJhbSB5T2Zmc2V0IC0gb2Zmc2V0IGluIFkgZGlyZWN0aW9uIHRvIHRoZSB1cHBlciBsZWZ0IGNvcm5lcgorICAgICAqIG9mIHRoZSBsYXlvdXQgZnJvbSB0aGUgb3JpZ2luIG9mIHRoZSBncmFwaGljcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRyYXdTZWdtZW50cyhHcmFwaGljczJEIGcyZCwgZmxvYXQgeE9mZnNldCwgZmxvYXQgeU9mZnNldCkgeworICAgICAgICBmb3IgKGludCBpPTA7IGk8cnVuU2VnbWVudHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIHJ1blNlZ21lbnRzLmdldChpKS5kcmF3KGcyZCwgeE9mZnNldCwgeU9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBibGFjayBib3ggYm91bmRzIHNoYXBlCisgICAgICogQHBhcmFtIGZpcnN0RW5kcG9pbnQgLSBzdGFydCBwb3NpdGlvbgorICAgICAqIEBwYXJhbSBzZWNvbmRFbmRwb2ludCAtIGVuZCBwb3NpdGlvbgorICAgICAqIEByZXR1cm4gYmxhY2sgYm94IGJvdW5kcyBzaGFwZQorICAgICAqLworICAgIHB1YmxpYyBTaGFwZSBnZXRCbGFja0JveEJvdW5kcyhpbnQgZmlyc3RFbmRwb2ludCwgaW50IHNlY29uZEVuZHBvaW50KSB7CisgICAgICAgIEdlbmVyYWxQYXRoIGJvdW5kcyA9IG5ldyBHZW5lcmFsUGF0aCgpOworCisgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZ21lbnQ7CisKKyAgICAgICAgZm9yIChpbnQgaWR4ID0gZmlyc3RFbmRwb2ludDsgaWR4IDwgc2Vjb25kRW5kcG9pbnQ7IGlkeD1zZWdtZW50LmdldEVuZCgpKSB7CisgICAgICAgICAgICBzZWdtZW50ID0gcnVuU2VnbWVudHMuZ2V0KGxvZ2ljYWwyc2VnbWVudFtpZHhdKTsKKyAgICAgICAgICAgIGJvdW5kcy5hcHBlbmQoc2VnbWVudC5nZXRDaGFyc0JsYWNrQm94Qm91bmRzKGlkeCwgc2Vjb25kRW5kcG9pbnQpLCBmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYm91bmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdmlzdWFsIGJvdW5kcyBzaGFwZQorICAgICAqIEByZXR1cm4gdmlzdWFsIGJvdW5kcyByZWN0YW5nbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjdGFuZ2xlMkQgZ2V0VmlzdWFsQm91bmRzKCkgeworICAgICAgICBSZWN0YW5nbGUyRCBib3VuZHMgPSBudWxsOworCisgICAgICAgIGZvciAoaW50IGk9MDsgaTxydW5TZWdtZW50cy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgcyA9IHJ1blNlZ21lbnRzLmdldChpKTsKKyAgICAgICAgICAgIGlmIChib3VuZHMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFJlY3RhbmdsZTJELnVuaW9uKGJvdW5kcywgcy5nZXRWaXN1YWxCb3VuZHMoKSwgYm91bmRzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzID0gcy5nZXRWaXN1YWxCb3VuZHMoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBib3VuZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBsb2dpY2FsIGJvdW5kcyBzaGFwZQorICAgICAqIEByZXR1cm4gbG9naWNhbCBib3VuZHMgcmVjdGFuZ2xlCisgICAgICovCisgICAgcHVibGljIFJlY3RhbmdsZTJEIGdldExvZ2ljYWxCb3VuZHMoKSB7CisgICAgICAgIFJlY3RhbmdsZTJEIGJvdW5kcyA9IG51bGw7CisKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHJ1blNlZ21lbnRzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBUZXh0UnVuU2VnbWVudCBzID0gcnVuU2VnbWVudHMuZ2V0KGkpOworICAgICAgICAgICAgaWYgKGJvdW5kcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgUmVjdGFuZ2xlMkQudW5pb24oYm91bmRzLCBzLmdldExvZ2ljYWxCb3VuZHMoKSwgYm91bmRzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzID0gcy5nZXRMb2dpY2FsQm91bmRzKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYm91bmRzOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Q2hhckNvdW50KCkgeworICAgICAgICByZXR1cm4gc2VnbWVudHNFbmQgLSBzZWdtZW50c1N0YXJ0OworICAgIH0KKworICAgIHB1YmxpYyBieXRlIGdldExldmVsKGludCBpZHgpIHsKKyAgICAgICAgaWYgKGxldmVscyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGV2ZWxzW2lkeF07CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRCYXNlTGV2ZWwoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTFRSKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2hhciBnZXRDaGFyKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gdGV4dFtpbmRleF07CisgICAgfQorCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBnZXRBQ0koKSB7CisgICAgICAgIHJldHVybiBhY2k7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvdXRsaW5lIHNoYXBlIGZvciB0aGUgbWFuYWdlZCB0ZXh0CisgICAgICogQHJldHVybiBvdXRsaW5lCisgICAgICovCisgICAgcHVibGljIEdlbmVyYWxQYXRoIGdldE91dGxpbmUoKSB7CisgICAgICAgIEdlbmVyYWxQYXRoIG91dGxpbmUgPSBuZXcgR2VuZXJhbFBhdGgoKTsKKworICAgICAgICBUZXh0UnVuU2VnbWVudCBzZWdtZW50OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVuU2VnbWVudHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIHNlZ21lbnQgPSBydW5TZWdtZW50cy5nZXQoaSk7CisgICAgICAgICAgICBvdXRsaW5lLmFwcGVuZChzZWdtZW50LmdldE91dGxpbmUoKSwgZmFsc2UpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG91dGxpbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyB0ZXh0IGhpdCBpbmZvIGZyb20gdGhlIHNjcmVlbiBjb29yZGluYXRlcy4KKyAgICAgKiBDdXJyZW50IGltcGxlbWVudGF0aW9uIHRvdGFsbHkgaWdub3JlcyBZIGNvb3JkaW5hdGUuCisgICAgICogSWYgWCBjb29yZGluYXRlIGlzIG91dHNpZGUgb2YgdGhlIGxheW91dCBib3VuZGFyaWVzLCB0aGlzCisgICAgICogbWV0aG9kIHJldHVybnMgbGVmdG1vc3Qgb3IgcmlnaHRtb3N0IGhpdC4KKyAgICAgKiBAcGFyYW0geCAtIHggY29vcmRpbmF0ZSBvZiB0aGUgaGl0CisgICAgICogQHBhcmFtIHkgLSB5IGNvb3JkaW5hdGUgb2YgdGhlIGhpdAorICAgICAqIEByZXR1cm4gaGl0IGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gaGl0VGVzdChmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZ21lbnQ7CisKKyAgICAgICAgZG91YmxlIGVuZE9mUHJldlNlZyA9IC0xOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1blNlZ21lbnRzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBzZWdtZW50ID0gcnVuU2VnbWVudHMuZ2V0KGkpOworICAgICAgICAgICAgUmVjdGFuZ2xlMkQgYm91bmRzID0gc2VnbWVudC5nZXRWaXN1YWxCb3VuZHMoKTsKKyAgICAgICAgICAgIGlmICgoYm91bmRzLmdldE1pblgoKSA8PSB4ICYmIGJvdW5kcy5nZXRNYXhYKCkgPj0geCkgfHwgLy8gV2UgYXJlIGluIHRoZSBzZWdtZW50CisgICAgICAgICAgICAgICAoZW5kT2ZQcmV2U2VnIDwgeCAmJiBib3VuZHMuZ2V0TWluWCgpID4geCkpIHsgLy8gV2UgYXJlIHNvbWV3aGVyZSBiZXR3ZWVuIHRoZSBzZWdtZW50cworICAgICAgICAgICAgICAgIHJldHVybiBzZWdtZW50LmhpdFRlc3QoeCx5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVuZE9mUHJldlNlZyA9IGJvdW5kcy5nZXRNYXhYKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaXNMVFIoKSA/IFRleHRIaXRJbmZvLnRyYWlsaW5nKHRleHQubGVuZ3RoKSA6IFRleHRIaXRJbmZvLmxlYWRpbmcoMCk7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldEp1c3RpZmljYXRpb24oKSB7CisgICAgICAgIHJldHVybiBqdXN0aWZpY2F0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgcG9zaXRpb24gb2YgdGhlIGxhc3Qgbm9uIHdoaXRlc3BhY2UgY2hhcmFjdGVyCisgICAgICogaW4gdGhlIG1hbmFnZWQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHBvc2l0aW9uIG9mIHRoZSBsYXN0IG5vbiB3aGl0ZXNwYWNlIGNoYXJhY3RlcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGFzdE5vbldoaXRlc3BhY2UoKSB7CisgICAgICAgIGludCBsYXN0Tm9uV2hpdGVzcGFjZSA9IHRleHQubGVuZ3RoOworCisgICAgICAgIHdoaWxlIChsYXN0Tm9uV2hpdGVzcGFjZSA+PSAwKSB7CisgICAgICAgICAgICBsYXN0Tm9uV2hpdGVzcGFjZS0tOworICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHRleHRbbGFzdE5vbldoaXRlc3BhY2VdKSkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGxhc3ROb25XaGl0ZXNwYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGp1c3RpZmljYXRpb24gb2YgdGhlIG1hbmFnZWQgdGV4dCBieSBjaGFuZ2luZyBzZWdtZW50IHBvc2l0aW9ucworICAgICAqIGFuZCBwb3NpdGlvbnMgb2YgdGhlIGdseXBocyBpbnNpZGUgb2YgdGhlIHNlZ21lbnRzLgorICAgICAqIEBwYXJhbSBnYXAgLSBhbW91bnQgb2Ygc3BhY2Ugd2hpY2ggc2hvdWxkIGJlIGNvbXBlbnNhdGVkIGJ5IGp1c3RpZmljYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBqdXN0aWZ5KGZsb2F0IGdhcCkgeworICAgICAgICAvLyBJZ25vcmUgdHJhaWxpbmcgbG9naWNhbCB3aGl0ZXNwYWNlCisgICAgICAgIGludCBmaXJzdElkeCA9IHNlZ21lbnRzU3RhcnQ7CisgICAgICAgIGludCBsYXN0SWR4ID0gZ2V0TGFzdE5vbldoaXRlc3BhY2UoKSArIHNlZ21lbnRzU3RhcnQ7CisgICAgICAgIEp1c3RpZmljYXRpb25JbmZvIGpJbmZvc1tdID0gbmV3IEp1c3RpZmljYXRpb25JbmZvWzVdOworICAgICAgICBmbG9hdCBnYXBMZWZ0ID0gZ2FwOworCisgICAgICAgIGludCBoaWdoZXN0UHJpb3JpdHkgPSAtMTsKKyAgICAgICAgLy8gR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9LQVNISURBIGlzIDAKKyAgICAgICAgLy8gR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9OT05FIGlzIDMKKyAgICAgICAgZm9yIChpbnQgcHJpb3JpdHkgPSAwOyBwcmlvcml0eSA8PSBHbHlwaEp1c3RpZmljYXRpb25JbmZvLlBSSU9SSVRZX05PTkUgKyAxOyBwcmlvcml0eSsrKSB7CisgICAgICAgICAgICBKdXN0aWZpY2F0aW9uSW5mbyBqSW5mbyA9IG5ldyBKdXN0aWZpY2F0aW9uSW5mbygpOworICAgICAgICAgICAgakluZm8ubGFzdElkeCA9IGxhc3RJZHg7CisgICAgICAgICAgICBqSW5mby5maXJzdElkeCA9IGZpcnN0SWR4OworICAgICAgICAgICAgakluZm8uZ3JvdyA9IGdhcCA+IDA7CisgICAgICAgICAgICBqSW5mby5nYXBUb0ZpbGwgPSBnYXBMZWZ0OworCisgICAgICAgICAgICBpZiAocHJpb3JpdHkgPD0gR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9OT05FKSB7CisgICAgICAgICAgICAgICAgakluZm8ucHJpb3JpdHkgPSBwcmlvcml0eTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgakluZm8ucHJpb3JpdHkgPSBoaWdoZXN0UHJpb3JpdHk7IC8vIExhc3QgcGFzcworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1blNlZ21lbnRzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgVGV4dFJ1blNlZ21lbnQgc2VnbWVudCA9IHJ1blNlZ21lbnRzLmdldChpKTsKKyAgICAgICAgICAgICAgICBpZiAoc2VnbWVudC5nZXRTdGFydCgpIDw9IGxhc3RJZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VnbWVudC51cGRhdGVKdXN0aWZpY2F0aW9uSW5mbyhqSW5mbyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoakluZm8ucHJpb3JpdHkgPT0gaGlnaGVzdFByaW9yaXR5KSB7CisgICAgICAgICAgICAgICAgakluZm8uYWJzb3JiID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBqSW5mby5hYnNvcmJlZFdlaWdodCA9IGpJbmZvLndlaWdodDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGpJbmZvLndlaWdodCAhPSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKGhpZ2hlc3RQcmlvcml0eSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaGlnaGVzdFByaW9yaXR5ID0gcHJpb3JpdHk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGpJbmZvc1twcmlvcml0eV0gPSBqSW5mbzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGdhcExlZnQgLT0gakluZm8uZ3Jvd0xpbWl0OworCisgICAgICAgICAgICBpZiAoKChnYXBMZWZ0ID4gMCkgXiBqSW5mby5ncm93KSB8fCBnYXBMZWZ0ID09IDApIHsKKyAgICAgICAgICAgICAgICBnYXBMZWZ0ID0gMDsKKyAgICAgICAgICAgICAgICBqSW5mby5nYXBQZXJVbml0ID0gakluZm8uZ2FwVG9GaWxsL2pJbmZvLndlaWdodDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGpJbmZvLnVzZUxpbWl0cyA9IHRydWU7CisKKyAgICAgICAgICAgIGlmIChqSW5mby5hYnNvcmJlZFdlaWdodCA+IDApIHsKKyAgICAgICAgICAgICAgICBqSW5mby5hYnNvcmIgPSB0cnVlOworICAgICAgICAgICAgICAgIGpJbmZvLmFic29yYmVkR2FwUGVyVW5pdCA9CisgICAgICAgICAgICAgICAgICAgICAgICAoakluZm8uZ2FwVG9GaWxsLWpJbmZvLmdyb3dMaW1pdCkvakluZm8uYWJzb3JiZWRXZWlnaHQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmbG9hdCBjdXJySnVzdGlmaWNhdGlvbk9mZnNldCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVuU2VnbWVudHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIFRleHRSdW5TZWdtZW50IHNlZ21lbnQgPQorICAgICAgICAgICAgICAgICAgICBydW5TZWdtZW50cy5nZXQoZ2V0U2VnbWVudEZyb21WaXN1YWxPcmRlcihpKSk7CisgICAgICAgICAgICBzZWdtZW50LnggKz0gY3Vyckp1c3RpZmljYXRpb25PZmZzZXQ7CisgICAgICAgICAgICBjdXJySnVzdGlmaWNhdGlvbk9mZnNldCArPSBzZWdtZW50LmRvSnVzdGlmaWNhdGlvbihqSW5mb3MpOworICAgICAgICB9CisKKyAgICAgICAganVzdGlmaWNhdGlvbiA9IC0xOyAvLyBNYWtlIGZ1cnRoZXIganVzdGlmaWNhdGlvbiBpbXBvc3NpYmxlCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSBpbmZvcm1hdGlvbiBjb2xsZWN0ZWQgYmVmb3JlIHRoZSBhY3R1YWwKKyAgICAgKiBqdXN0aWZpY2F0aW9uIGlzIHN0YXJ0ZWQgYW5kIG5lZWRlZCB0byBwZXJmb3JtIHRoZSBqdXN0aWZpY2F0aW9uLgorICAgICAqIFRoaXMgaW5mb3JtYXRpb24gaXMgY2xvc2VseSByZWxhdGVkIHRvIHRoZSBpbmZvcm1hdGlvbiBzdG9yZWQgaW4gdGhlCisgICAgICogR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBmb3IgdGhlIHRleHQgcmVwcmVzZW50ZWQgYnkgZ2x5cGggdmVjdG9ycy4KKyAgICAgKi8KKyAgICBjbGFzcyBKdXN0aWZpY2F0aW9uSW5mbyB7CisgICAgICAgIGJvb2xlYW4gZ3JvdzsKKyAgICAgICAgYm9vbGVhbiBhYnNvcmIgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiB1c2VMaW1pdHMgPSBmYWxzZTsKKyAgICAgICAgaW50IHByaW9yaXR5ID0gMDsKKyAgICAgICAgZmxvYXQgd2VpZ2h0ID0gMDsKKyAgICAgICAgZmxvYXQgYWJzb3JiZWRXZWlnaHQgPSAwOworICAgICAgICBmbG9hdCBncm93TGltaXQgPSAwOworCisgICAgICAgIGludCBsYXN0SWR4OworICAgICAgICBpbnQgZmlyc3RJZHg7CisKKyAgICAgICAgZmxvYXQgZ2FwVG9GaWxsOworCisgICAgICAgIGZsb2F0IGdhcFBlclVuaXQgPSAwOyAvLyBQcmVjYWxjdWxhdGVkIHZhbHVlLCBnYXBUb0ZpbGwgLyB3ZWlnaHQKKyAgICAgICAgZmxvYXQgYWJzb3JiZWRHYXBQZXJVbml0ID0gMDsgLy8gUHJlY2FsY3VsYXRlZCB2YWx1ZSwgZ2FwVG9GaWxsIC8gd2VpZ2h0CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9UZXh0UnVuU2VnbWVudC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9UZXh0UnVuU2VnbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZDJjMDUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9mb250L1RleHRSdW5TZWdtZW50LmphdmEKQEAgLTAsMCArMSwxNjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmZvbnQ7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LlNoYXBlOworaW1wb3J0IGphdmEuYXd0LmZvbnQuVGV4dEhpdEluZm87CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKKworLyoqCisgKiBBYnN0cmFjdCBjbGFzcyB3aGljaCByZXByZXNlbnRzIHRoZSBzZWdtZW50IG9mIHRoZSB0ZXh0IHdpdGggY29uc3RhbnQgYXR0cmlidXRlcworICogcnVubmluZyBpbiBvbmUgZGlyZWN0aW9uIChpLmUuIGNvbnN0YW50IGxldmVsKS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFRleHRSdW5TZWdtZW50IGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKyAgICBmbG9hdCB4OyAvLyBDYWxjdWxhdGVkIHggbG9jYXRpb24gb2YgdGhpcyBzZWdtZW50IG9uIHRoZSBzY3JlZW4KKyAgICBmbG9hdCB5OyAvLyBDYWxjdWxhdGVkIHkgbG9jYXRpb24gb2YgdGhpcyBzZWdtZW50IG9uIHRoZSBzY3JlZW4KKworICAgIEJhc2ljTWV0cmljcyBtZXRyaWNzOyAvLyBNZXRyaWNzIG9mIHRoaXMgdGV4dCBydW4gc2VnbWVudAorICAgIFRleHREZWNvcmF0b3IuRGVjb3JhdGlvbiBkZWNvcmF0aW9uOyAvLyBVbmRlcmxpbmUsIHNyaWtldGhyb3VnaCwgZXRjLgorICAgIFJlY3RhbmdsZTJEIGxvZ2ljYWxCb3VuZHMgPSBudWxsOyAvLyBMb2dpY2FsIGJvdW5kaW5nIGJveCBmb3IgdGhlIHNlZ21lbnQKKyAgICBSZWN0YW5nbGUyRCB2aXN1YWxCb3VuZHMgPSBudWxsOyAvLyBWaXN1YWwgYm91bmRpbmcgYm94IGZvciB0aGUgc2VnbWVudAorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdGFydCBpbmRleCBvZiB0aGUgc2VnbWVudAorICAgICAqIEByZXR1cm4gc3RhcnQgaW5kZXgKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgZ2V0U3RhcnQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgZW5kIGluZGV4IG9mIHRoZSBzZWdtZW50CisgICAgICogQHJldHVybiBlbmQgaW5kZXgKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgZ2V0RW5kKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc2VnbWVudAorICAgICAqIEByZXR1cm4gbnVtYmVyIG9mIGNoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgZ2V0TGVuZ3RoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZW5kZXJzIHRoaXMgdGV4dCBydW4gc2VnbWVudAorICAgICAqIEBwYXJhbSBnMmQgLSBncmFwaGljcyB0byByZW5kZXIgdG8KKyAgICAgKiBAcGFyYW0geE9mZnNldCAtIFggb2Zmc2V0IGZyb20gdGhlIGdyYXBoaWNzIG9yaWdpbiB0byB0aGUKKyAgICAgKiBvcmlnaW4gb2YgdGhlIHRleHQgbGF5b3V0CisgICAgICogQHBhcmFtIHlPZmZzZXQgLSBZIG9mZnNldCBmcm9tIHRoZSBncmFwaGljcyBvcmlnaW4gdG8gdGhlCisgICAgICogb3JpZ2luIG9mIHRoZSB0ZXh0IGxheW91dAorICAgICAqLworICAgIGFic3RyYWN0IHZvaWQgZHJhdyhHcmFwaGljczJEIGcyZCwgZmxvYXQgeE9mZnNldCwgZmxvYXQgeU9mZnNldCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGJsYWNrIGJveCBib3VuZHMgc2hhcGUgZm9yIHRoZSBzcGVjaWZpZWQgcmFuZ2UKKyAgICAgKiBAcGFyYW0gc3RhcnQgLSByYW5nZSBzYXJ0CisgICAgICogQHBhcmFtIGxpbWl0IC0gcmFuZ2UgZW5kCisgICAgICogQHJldHVybiBibGFjayBib3ggYm91bmRzIHNoYXBlCisgICAgICovCisgICAgYWJzdHJhY3QgU2hhcGUgZ2V0Q2hhcnNCbGFja0JveEJvdW5kcyhpbnQgc3RhcnQsIGludCBsaW1pdCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvdXRsaW5lIHNoYXBlCisgICAgICogQHJldHVybiBvdXRsaW5lCisgICAgICovCisgICAgYWJzdHJhY3QgU2hhcGUgZ2V0T3V0bGluZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB2aXN1YWwgYm91bmRzIG9mIHRoaXMgc2VnbWVudAorICAgICAqIEByZXR1cm4gdmlzdWFsIGJvdW5kcworICAgICAqLworICAgIGFic3RyYWN0IFJlY3RhbmdsZTJEIGdldFZpc3VhbEJvdW5kcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBsb2dpY2FsIGJvdW5kcyBvZiB0aGlzIHNlZ21lbnQKKyAgICAgKiBAcmV0dXJuIGxvZ2ljYWwgYm91bmRzCisgICAgICovCisgICAgYWJzdHJhY3QgUmVjdGFuZ2xlMkQgZ2V0TG9naWNhbEJvdW5kcygpOworCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyBhZHZhbmNlIG9mIHRoZSBzZWdtZW50CisgICAgICogQHJldHVybiBhZHZhbmNlCisgICAgICovCisgICAgYWJzdHJhY3QgZmxvYXQgZ2V0QWR2YW5jZSgpOworCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyBhZHZhbmNlIGRlbHRhIGJldHdlZW4gdHdvIGNoYXJhY3RlcnMKKyAgICAgKiBAcGFyYW0gc3RhcnQgLSAxc3QgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0gZW5kIC0gMm5kIHBvc2l0aW9uCisgICAgICogQHJldHVybiBhZHZhbmNlIGluY3JlbWVudCBiZXR3ZWVuIHNwZWNpZmllZCBwb3NpdGlvbnMKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBmbG9hdCBnZXRBZHZhbmNlRGVsdGEoaW50IHN0YXJ0LCBpbnQgZW5kKTsKKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgaW5kZXggb2YgdGhlIGNoYXJhY3RlciB3aGljaCBhZHZhbmNlIGlzIGVxdWFsIHRvCisgICAgICogdGhlIGdpdmVuLiBJZiB0aGUgZ2l2ZW4gYWR2YW5jZSBpcyBncmVhdGVyIHRoZW4gdGhlIHNlZ21lbnQKKyAgICAgKiBhZHZhbmNlIGl0IHJldHVybnMgdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSBsYXN0IGNoYXJhY3Rlci4KKyAgICAgKiBAcGFyYW0gYWR2YW5jZSAtIGdpdmVuIGFkdmFuY2UKKyAgICAgKiBAcGFyYW0gc3RhcnQgLSBjaGFyYWN0ZXIsIGZyb20gd2hpY2ggdG8gc3RhcnQgbWVhc3VyaW5nIGFkdmFuY2UKKyAgICAgKiBAcmV0dXJuIGNoYXJhY3RlciBpbmRleAorICAgICAqLworICAgIGFic3RyYWN0IGludCBnZXRDaGFySW5kZXhGcm9tQWR2YW5jZShmbG9hdCBhZHZhbmNlLCBpbnQgc3RhcnQpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBjaGFyYWN0ZXIgZG9lc24ndCBjb250cmlidXRlIHRvIHRoZSB0ZXh0IGFkdmFuY2UKKyAgICAgKiBAcGFyYW0gaW5kZXggLSBjaGFyYWN0ZXIgaW5kZXgKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBoYXMgemVybyBhZHZhbmNlCisgICAgICovCisgICAgYWJzdHJhY3QgYm9vbGVhbiBjaGFySGFzWmVyb0FkdmFuY2UoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciBvbiB0aGUgc2NyZWVuCisgICAgICogQHBhcmFtIGluZGV4IC0gY2hhcmFjdGVyIGluZGV4CisgICAgICogQHJldHVybiBYIGNvb3JkaW5hdGUgb2YgdGhlIGNoYXJhY3RlciBwb3NpdGlvbgorICAgICAqLworICAgIGFic3RyYWN0IGZsb2F0IGdldENoYXJQb3NpdGlvbihpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWR2YW5jZSBvZiB0aGUgaW5kaXZpZHVhbCBjaGFyYWN0ZXIKKyAgICAgKiBAcGFyYW0gaW5kZXggLSBjaGFyYWN0ZXIgaW5kZXgKKyAgICAgKiBAcmV0dXJuIGNoYXJhY3RlciBhZHZhbmNlCisgICAgICovCisgICAgYWJzdHJhY3QgZmxvYXQgZ2V0Q2hhckFkdmFuY2UoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGV4dCBoaXQgaW5mbyBmcm9tIHRoZSBoaXQgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0geCAtIFggY29vcmRpbmF0ZSByZWxhdGl2ZSB0byB0aGUgb3JpZ2luIG9mIHRoZSBsYXlvdXQKKyAgICAgKiBAcGFyYW0geSAtIFkgY29vcmRpbmF0ZSByZWxhdGl2ZSB0byB0aGUgb3JpZ2luIG9mIHRoZSBsYXlvdXQKKyAgICAgKiBAcmV0dXJuIGhpdCBpbmZvCisgICAgICovCisgICAgYWJzdHJhY3QgVGV4dEhpdEluZm8gaGl0VGVzdChmbG9hdCB4LCBmbG9hdCB5KTsKKworICAgIC8qKgorICAgICAqIENvbGxlY3RzIGp1c3RpZmljYXRpb24gaW5mb3JtYXRpb24gaW50byBKdXN0aWZpY2F0aW9uSW5mbyBvYmplY3QKKyAgICAgKiBAcGFyYW0gakluZm8gLSBKdXN0aWZpY2F0aW9uSW5mbyBvYmplY3QKKyAgICAgKi8KKyAgICBhYnN0cmFjdCB2b2lkIHVwZGF0ZUp1c3RpZmljYXRpb25JbmZvKFRleHRSdW5CcmVha2VyLkp1c3RpZmljYXRpb25JbmZvIGpJbmZvKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGp1c3RpZmljYXRpb24gb2YgdGhlIHNlZ21lbnQuCisgICAgICogVXBkYXRlcyBwb3NpdGlvbnMgb2YgaW5kaXZpZHVhbCBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBqSW5mb3MgLSBqdXN0aWZpY2F0aW9uIGluZm9ybWF0aW9uLCBnYXRoZXJlZCBieSB0aGUgcHJldmlvdXMgcGFzc2VzCisgICAgICogQHJldHVybiBhbW91bnQgb2YgZ3Jvd3RoIG9yIHNocmluayBvZiB0aGUgc2VnbWVudAorICAgICAqLyAgICAKKyAgICBhYnN0cmFjdCBmbG9hdCBkb0p1c3RpZmljYXRpb24oVGV4dFJ1bkJyZWFrZXIuSnVzdGlmaWNhdGlvbkluZm8gakluZm9zW10pOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBjbG9uZSgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvZm9udC9UZXh0UnVuU2VnbWVudEltcGwuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dFJ1blNlZ21lbnRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVjMmQwNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ZvbnQvVGV4dFJ1blNlZ21lbnRJbXBsLmphdmEKQEAgLTAsMCArMSw5NzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udDsKKworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS5hd3QuZm9udC4qOworaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5HZW5lcmFsUGF0aDsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CisvLyBYWFggLSBUT0RPIC0gYmlkaSBub3QgaW1wbGVtZW50ZWQgeWV0CisvL2ltcG9ydCBqYXZhLnRleHQuQmlkaTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogRGF0ZTogQXByIDI1LCAyMDA1CisgKiBUaW1lOiA0OjMzOjE4IFBNCisgKgorICogVGhpcyBjbGFzcyBjb250YWlucyB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIGJlaGF2aW9yIG9mIHRoZQorICogdGV4dCBydW4gc2VnbWVudCB3aXRoIGNvbnN0YW50IHRleHQgYXR0cmlidXRlcyBhbmQgZGlyZWN0aW9uLgorICovCitwdWJsaWMgY2xhc3MgVGV4dFJ1blNlZ21lbnRJbXBsIHsKKworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3MgY29udGFpbnMgYmFzaWMgaW5mb3JtYXRpb24gcmVxdWlyZWQgZm9yIGNyZWF0aW9uCisgICAgICogb2YgdGhlIGdseXBoLWJhc2VkIHRleHQgcnVuIHNlZ21lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXh0U2VnbWVudEluZm8geworICAgICAgICAvLyBYWFggLSBUT0RPIC0gYmlkaSBub3QgaW1wbGVtZW50ZWQgeWV0CisgICAgICAgIC8vQmlkaSBiaWRpOworCisgICAgICAgIEZvbnQgZm9udDsKKyAgICAgICAgRm9udFJlbmRlckNvbnRleHQgZnJjOworCisgICAgICAgIGNoYXIgdGV4dFtdOworCisgICAgICAgIGludCBzdGFydDsKKyAgICAgICAgaW50IGVuZDsKKyAgICAgICAgaW50IGxlbmd0aDsKKworICAgICAgICBpbnQgZmxhZ3MgPSAwOworCisgICAgICAgIGJ5dGUgbGV2ZWwgPSAwOworCisgICAgICAgIFRleHRTZWdtZW50SW5mbygKKyAgICAgICAgICAgICAgICBieXRlIGxldmVsLAorICAgICAgICAgICAgICAgIEZvbnQgZm9udCwgRm9udFJlbmRlckNvbnRleHQgZnJjLAorICAgICAgICAgICAgICAgIGNoYXIgdGV4dFtdLCBpbnQgc3RhcnQsIGludCBlbmQKKyAgICAgICAgKSB7CisgICAgICAgICAgICB0aGlzLmZvbnQgPSBmb250OworICAgICAgICAgICAgdGhpcy5mcmMgPSBmcmM7CisgICAgICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OworICAgICAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0OworICAgICAgICAgICAgdGhpcy5lbmQgPSBlbmQ7CisgICAgICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWw7CisgICAgICAgICAgICBsZW5ndGggPSBlbmQgLSBzdGFydDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHNpbXBsZSB0ZXh0IHNlZ21lbnQgYmFja2VkIGJ5IHRoZSBnbHlwaCB2ZWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRleHRSdW5TZWdtZW50Q29tbW9uIGV4dGVuZHMgVGV4dFJ1blNlZ21lbnQgeworICAgICAgICBUZXh0U2VnbWVudEluZm8gaW5mbzsKKyAgICAgICAgcHJpdmF0ZSBHbHlwaFZlY3RvciBndjsKKyAgICAgICAgcHJpdmF0ZSBmbG9hdCBhZHZhbmNlSW5jcmVtZW50c1tdOworICAgICAgICBwcml2YXRlIGludCBjaGFyMmdseXBoW107CisgICAgICAgIHByaXZhdGUgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBnamlzW107IC8vIEdseXBoIGp1c3RpZmljYXRpb24gaW5mbworCisgICAgICAgIFRleHRSdW5TZWdtZW50Q29tbW9uKFRleHRTZWdtZW50SW5mbyBpLCBUZXh0RGVjb3JhdG9yLkRlY29yYXRpb24gZCkgeworICAgICAgICAgICAgLy8gWFhYIC0gdG9kbyAtIGNoZWNrIHN1cHBvcnQgYmlkaQorICAgICAgICAgICAgaS5mbGFncyAmPSB+MHgwOTsgLy8gQ2xlYXIgYmlkaSBmbGFncworCisgICAgICAgICAgICBpZiAoKGkubGV2ZWwgJiAweDEpICE9IDApIHsKKyAgICAgICAgICAgICAgICBpLmZsYWdzIHw9IEZvbnQuTEFZT1VUX1JJR0hUX1RPX0xFRlQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGluZm8gPSBpOworICAgICAgICAgICAgdGhpcy5kZWNvcmF0aW9uID0gZDsKKworICAgICAgICAgICAgTGluZU1ldHJpY3MgbG0gPSBpLmZvbnQuZ2V0TGluZU1ldHJpY3MoaS50ZXh0LCBpLnN0YXJ0LCBpLmVuZCwgaS5mcmMpOworICAgICAgICAgICAgdGhpcy5tZXRyaWNzID0gbmV3IEJhc2ljTWV0cmljcyhsbSwgaS5mb250KTsKKworICAgICAgICAgICAgaWYgKGxtLmdldE51bUNoYXJzKCkgIT0gaS5sZW5ndGgpIHsgLy8gWFhYIHRvZG8gLSBUaGlzIHNob3VsZCBiZSBoYW5kbGVkCisgICAgICAgICAgICAgICAgLy8gYXd0LjQxPUZvbnQgcmV0dXJuZWQgdW5zdXBwb3J0ZWQgdHlwZSBvZiBsaW5lIG1ldHJpY3MuIFRoaXMgY2FzZSBpcyBrbm93biwgYnV0IG5vdCBzdXBwb3J0ZWQgeWV0LgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjQxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGV4dFJ1blNlZ21lbnRDb21tb24oaW5mbywgZGVjb3JhdGlvbik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBnbHlwaCB2ZWN0b3IgZnJvbSB0aGUgbWFuYWdlZCB0ZXh0IGlmIG5lZWRlZAorICAgICAgICAgKiBAcmV0dXJuIGdseXBoIHZlY3RvcgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBHbHlwaFZlY3RvciBnZXRHbHlwaFZlY3RvcigpIHsKKyAgICAgICAgICAgIGlmIChndj09bnVsbCkgeworICAgICAgICAgICAgICAgIGd2ID0gaW5mby5mb250LmxheW91dEdseXBoVmVjdG9yKAorICAgICAgICAgICAgICAgICAgICAgICAgaW5mby5mcmMsCisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLnN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgaW5mby5lbmQgLSBpbmZvLnN0YXJ0LCAvLyBOT1RFOiBUaGlzIHBhcmFtZXRlciB2aW9sYXRlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcGVjLCBpdCBpcyBjb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGxpbWl0IGFzIHNwZWMgc3RhdGVzCisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmZsYWdzCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGd2OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlbmRlcnMgdGhpcyB0ZXh0IHJ1biBzZWdtZW50CisgICAgICAgICAqIEBwYXJhbSBnMmQgLSBncmFwaGljcyB0byByZW5kZXIgdG8KKyAgICAgICAgICogQHBhcmFtIHhPZmZzZXQgLSBYIG9mZnNldCBmcm9tIHRoZSBncmFwaGljcyBvcmlnaW4gdG8gdGhlCisgICAgICAgICAqIG9yaWdpbiBvZiB0aGUgdGV4dCBsYXlvdXQKKyAgICAgICAgICogQHBhcmFtIHlPZmZzZXQgLSBZIG9mZnNldCBmcm9tIHRoZSBncmFwaGljcyBvcmlnaW4gdG8gdGhlCisgICAgICAgICAqIG9yaWdpbiBvZiB0aGUgdGV4dCBsYXlvdXQKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICB2b2lkIGRyYXcoR3JhcGhpY3MyRCBnMmQsIGZsb2F0IHhPZmZzZXQsIGZsb2F0IHlPZmZzZXQpIHsKKyAgICAgICAgICAgIGlmIChkZWNvcmF0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBnMmQuZHJhd0dseXBoVmVjdG9yKGdldEdseXBoVmVjdG9yKCksIHhPZmZzZXQgKyB4LCB5T2Zmc2V0ICsgeSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFRleHREZWNvcmF0b3IucHJlcGFyZUdyYXBoaWNzKHRoaXMsIGcyZCwgeE9mZnNldCwgeU9mZnNldCk7CisgICAgICAgICAgICAgICAgZzJkLmRyYXdHbHlwaFZlY3RvcihnZXRHbHlwaFZlY3RvcigpLCB4T2Zmc2V0ICsgeCwgeU9mZnNldCArIHkpOworICAgICAgICAgICAgICAgIFRleHREZWNvcmF0b3IuZHJhd1RleHREZWNvcmF0aW9ucyh0aGlzLCBnMmQsIHhPZmZzZXQsIHlPZmZzZXQpOworICAgICAgICAgICAgICAgIFRleHREZWNvcmF0b3IucmVzdG9yZUdyYXBoaWNzKGRlY29yYXRpb24sIGcyZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB2aXN1YWwgYm91bmRzIG9mIHRoaXMgc2VnbWVudAorICAgICAgICAgKiBAcmV0dXJuIHZpc3VhbCBib3VuZHMKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBSZWN0YW5nbGUyRCBnZXRWaXN1YWxCb3VuZHMoKSB7CisgICAgICAgICAgICBpZiAodmlzdWFsQm91bmRzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB2aXN1YWxCb3VuZHMgPQorICAgICAgICAgICAgICAgICAgICAgICAgVGV4dERlY29yYXRvci5leHRlbmRWaXN1YWxCb3VuZHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEdseXBoVmVjdG9yKCkuZ2V0VmlzdWFsQm91bmRzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29yYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICk7CisKKyAgICAgICAgICAgICAgICB2aXN1YWxCb3VuZHMuc2V0UmVjdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIHggKyB2aXN1YWxCb3VuZHMuZ2V0WCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgeSArIHZpc3VhbEJvdW5kcy5nZXRZKCksCisgICAgICAgICAgICAgICAgICAgICAgICB2aXN1YWxCb3VuZHMuZ2V0V2lkdGgoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZpc3VhbEJvdW5kcy5nZXRIZWlnaHQoKQorICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiAoUmVjdGFuZ2xlMkQpIHZpc3VhbEJvdW5kcy5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgbG9naWNhbCBib3VuZHMgb2YgdGhpcyBzZWdtZW50CisgICAgICAgICAqIEByZXR1cm4gbG9naWNhbCBib3VuZHMKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBSZWN0YW5nbGUyRCBnZXRMb2dpY2FsQm91bmRzKCkgeworICAgICAgICAgICAgaWYgKGxvZ2ljYWxCb3VuZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2ljYWxCb3VuZHMgPSBnZXRHbHlwaFZlY3RvcigpLmdldExvZ2ljYWxCb3VuZHMoKTsKKworICAgICAgICAgICAgICAgIGxvZ2ljYWxCb3VuZHMuc2V0UmVjdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIHggKyBsb2dpY2FsQm91bmRzLmdldFgoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHkgKyBsb2dpY2FsQm91bmRzLmdldFkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2ljYWxCb3VuZHMuZ2V0V2lkdGgoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2ljYWxCb3VuZHMuZ2V0SGVpZ2h0KCkKKyAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gKFJlY3RhbmdsZTJEKSBsb2dpY2FsQm91bmRzLmNsb25lKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgZmxvYXQgZ2V0QWR2YW5jZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAoZmxvYXQpIGdldExvZ2ljYWxCb3VuZHMoKS5nZXRXaWR0aCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEF0dGVtdHMgdG8gbWFwIGVhY2ggY2hhcmFjdGVyIHRvIHRoZSBjb3JyZXNwb25kaW5nIGFkdmFuY2UgaW5jcmVtZW50CisgICAgICAgICAqLworICAgICAgICB2b2lkIGluaXRBZHZhbmNlTWFwcGluZygpIHsKKyAgICAgICAgICAgIEdseXBoVmVjdG9yIGd2ID0gZ2V0R2x5cGhWZWN0b3IoKTsKKyAgICAgICAgICAgIGludCBjaGFySW5kaWNpZXNbXSA9IGd2LmdldEdseXBoQ2hhckluZGljZXMoMCwgZ3YuZ2V0TnVtR2x5cGhzKCksIG51bGwpOworICAgICAgICAgICAgYWR2YW5jZUluY3JlbWVudHMgPSBuZXcgZmxvYXRbaW5mby5sZW5ndGhdOworCisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8Y2hhckluZGljaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYWR2YW5jZUluY3JlbWVudHNbY2hhckluZGljaWVzW2ldXSA9IGd2LmdldEdseXBoTWV0cmljcyhpKS5nZXRBZHZhbmNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ2FsY3VsYXRlcyBhZHZhbmNlIGRlbHRhIGJldHdlZW4gdHdvIGNoYXJhY3RlcnMKKyAgICAgICAgICogQHBhcmFtIHN0YXJ0IC0gMXN0IHBvc2l0aW9uCisgICAgICAgICAqIEBwYXJhbSBlbmQgLSAybmQgcG9zaXRpb24KKyAgICAgICAgICogQHJldHVybiBhZHZhbmNlIGluY3JlbWVudCBiZXR3ZWVuIHNwZWNpZmllZCBwb3NpdGlvbnMKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBmbG9hdCBnZXRBZHZhbmNlRGVsdGEoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICAvLyBHZXQgY29vcmRpbmF0ZXMgaW4gdGhlIHNlZ21lbnQgY29udGV4dAorICAgICAgICAgICAgc3RhcnQgLT0gaW5mby5zdGFydDsKKyAgICAgICAgICAgIGVuZCAtPSBpbmZvLnN0YXJ0OworCisgICAgICAgICAgICBpZiAoYWR2YW5jZUluY3JlbWVudHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluaXRBZHZhbmNlTWFwcGluZygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7CisgICAgICAgICAgICAgICAgc3RhcnQgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVuZCA+IGluZm8ubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgZW5kID0gaW5mby5sZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZsb2F0IHN1bSA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpPXN0YXJ0OyBpPGVuZDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3VtICs9IGFkdmFuY2VJbmNyZW1lbnRzW2ldOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gc3VtOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGN1bGF0ZXMgaW5kZXggb2YgdGhlIGNoYXJhY3RlciB3aGljaCBhZHZhbmNlIGlzIGVxdWFsIHRvCisgICAgICAgICAqIHRoZSBnaXZlbi4gSWYgdGhlIGdpdmVuIGFkdmFuY2UgaXMgZ3JlYXRlciB0aGVuIHRoZSBzZWdtZW50CisgICAgICAgICAqIGFkdmFuY2UgaXQgcmV0dXJucyB0aGUgcG9zaXRpb24gYWZ0ZXIgdGhlIGxhc3QgY2hhcmFjdGVyLgorICAgICAgICAgKiBAcGFyYW0gYWR2YW5jZSAtIGdpdmVuIGFkdmFuY2UKKyAgICAgICAgICogQHBhcmFtIHN0YXJ0IC0gY2hhcmFjdGVyLCBmcm9tIHdoaWNoIHRvIHN0YXJ0IG1lYXN1cmluZyBhZHZhbmNlCisgICAgICAgICAqIEByZXR1cm4gY2hhcmFjdGVyIGluZGV4CisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IGdldENoYXJJbmRleEZyb21BZHZhbmNlKGZsb2F0IGFkdmFuY2UsIGludCBzdGFydCkgeworICAgICAgICAgICAgLy8gWFhYIC0gdG9kbyAtIHByb2JhYmx5LCBwb3NzaWJsZSB0byBvcHRpbWl6ZQorICAgICAgICAgICAgLy8gQWRkIGNoZWNrIGlmIHRoZSBnaXZlbiBhZHZhbmNlIGlzIGdyZWF0ZXIgdGhlbgorICAgICAgICAgICAgLy8gdGhlIHNlZ21lbnQgYWR2YW5jZSBpbiB0aGUgYmVnaW5uaW5nLiBJbiB0aGlzIGNhc2UKKyAgICAgICAgICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gcnVuIHRocm91Z2ggYWxsIGluY3JlbWVudHMKKyAgICAgICAgICAgIGlmIChhZHZhbmNlSW5jcmVtZW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5pdEFkdmFuY2VNYXBwaW5nKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0YXJ0IC09IGluZm8uc3RhcnQ7CisKKyAgICAgICAgICAgIGlmIChzdGFydCA8IDApIHsKKyAgICAgICAgICAgICAgICBzdGFydCA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBpID0gc3RhcnQ7CisgICAgICAgICAgICBmb3IgKDsgaTxpbmZvLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYWR2YW5jZSAtPSBhZHZhbmNlSW5jcmVtZW50c1tpXTsKKyAgICAgICAgICAgICAgICBpZiAoYWR2YW5jZSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gaSArIGluZm8uc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IGdldFN0YXJ0KCkgeworICAgICAgICAgICAgcmV0dXJuIGluZm8uc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IGdldEVuZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZvLmVuZDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICAgICAgcmV0dXJuIGluZm8ubGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEF0dGVtdHMgdG8gY3JlYXRlIG1hcHBpbmcgb2YgdGhlIGNoYXJhY3RlcnMgdG8gZ2x5cGhzIGluIHRoZSBnbHlwaCB2ZWN0b3IuCisgICAgICAgICAqIEByZXR1cm4gYXJyYXkgd2hlcmUgZm9yIGVhY2ggY2hhcmFjdGVyIGluZGV4IHN0b3JlZCBjb3JyZXNwb25kaW5nIGdseXBoIGluZGV4CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGludFtdIGdldENoYXIyR2x5cGgoKSB7CisgICAgICAgICAgICBpZiAoY2hhcjJnbHlwaCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgR2x5cGhWZWN0b3IgZ3YgPSBnZXRHbHlwaFZlY3RvcigpOworICAgICAgICAgICAgICAgIGNoYXIyZ2x5cGggPSBuZXcgaW50W2luZm8ubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChjaGFyMmdseXBoLCAtMSk7CisKKyAgICAgICAgICAgICAgICAvLyBGaWxsIGdseXBoIGluZGljaWVzIGZvciBmaXJzdCBjaGFyYWN0ZXJzIGNvcnJlc3BvbmRpbmcgdG8gZWFjaCBnbHlwaAorICAgICAgICAgICAgICAgIGludCBjaGFySW5kaWNpZXNbXSA9IGd2LmdldEdseXBoQ2hhckluZGljZXMoMCwgZ3YuZ2V0TnVtR2x5cGhzKCksIG51bGwpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxjaGFySW5kaWNpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhcjJnbHlwaFtjaGFySW5kaWNpZXNbaV1dID0gaTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBJZiBzZXZlcmFsIGNoYXJhY3RlcnMgY29ycmVzcG9uZHMgdG8gb25lIGdseXBoLCBjcmVhdGUgbWFwcGluZyBmb3IgdGhlbQorICAgICAgICAgICAgICAgIC8vIFN1cHBvc2UgdGhhdCB0aGVzZSBjaGFyYWN0ZXJzIGFyZSBnb2luZyBhbGwgdG9nZXRoZXIKKyAgICAgICAgICAgICAgICBpbnQgY3VyckluZGV4ID0gMDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8Y2hhcjJnbHlwaC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcjJnbHlwaFtpXSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIyZ2x5cGhbaV0gPSBjdXJySW5kZXg7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjdXJySW5kZXggPSBjaGFyMmdseXBoW2ldOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gY2hhcjJnbHlwaDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGJsYWNrIGJveCBib3VuZHMgc2hhcGUgZm9yIHRoZSBzcGVjaWZpZWQgcmFuZ2UKKyAgICAgICAgICogQHBhcmFtIHN0YXJ0IC0gcmFuZ2Ugc2FydAorICAgICAgICAgKiBAcGFyYW0gbGltaXQgLSByYW5nZSBlbmQKKyAgICAgICAgICogQHJldHVybiBibGFjayBib3ggYm91bmRzIHNoYXBlCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgU2hhcGUgZ2V0Q2hhcnNCbGFja0JveEJvdW5kcyhpbnQgc3RhcnQsIGludCBsaW1pdCkgeworICAgICAgICAgICAgc3RhcnQgLT0gaW5mby5zdGFydDsKKyAgICAgICAgICAgIGxpbWl0IC09IGluZm8uc3RhcnQ7CisKKyAgICAgICAgICAgIGlmIChsaW1pdCA+IGluZm8ubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbGltaXQgPSBpbmZvLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgR2VuZXJhbFBhdGggcmVzdWx0ID0gbmV3IEdlbmVyYWxQYXRoKCk7CisKKyAgICAgICAgICAgIGludCBnbHlwaEluZGV4ID0gMDsKKworICAgICAgICAgICAgZm9yIChpbnQgaT1zdGFydDsgaTxsaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZ2x5cGhJbmRleCA9IGdldENoYXIyR2x5cGgoKVtpXTsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhWaXN1YWxCb3VuZHMoZ2x5cGhJbmRleCksIGZhbHNlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gU2hpZnQgdG8gdGhlIHNlZ21lbnQncyBjb29yZGluYXRlcworICAgICAgICAgICAgcmVzdWx0LnRyYW5zZm9ybShBZmZpbmVUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlSW5zdGFuY2UoeCwgeSkpOworCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGN1bGF0ZXMgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciBvbiB0aGUgc2NyZWVuCisgICAgICAgICAqIEBwYXJhbSBpbmRleCAtIGNoYXJhY3RlciBpbmRleAorICAgICAgICAgKiBAcmV0dXJuIFggY29vcmRpbmF0ZSBvZiB0aGUgY2hhcmFjdGVyIHBvc2l0aW9uCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgZmxvYXQgZ2V0Q2hhclBvc2l0aW9uKGludCBpbmRleCkgeworICAgICAgICAgICAgaW5kZXggLT0gaW5mby5zdGFydDsKKworICAgICAgICAgICAgaWYgKGluZGV4ID4gaW5mby5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBpbmRleCA9IGluZm8ubGVuZ3RoOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmbG9hdCByZXN1bHQgPSAwOworCisgICAgICAgICAgICBpbnQgZ2x5cGhJbmRleCA9IGdldENoYXIyR2x5cGgoKVtpbmRleF07CisgICAgICAgICAgICByZXN1bHQgPSAoZmxvYXQpIGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhQb3NpdGlvbihnbHlwaEluZGV4KS5nZXRYKCk7CisKKyAgICAgICAgICAgIC8vIFNoaWZ0IHRvIHRoZSBzZWdtZW50J3MgY29vcmRpbmF0ZXMKKyAgICAgICAgICAgIHJlc3VsdCArPSB4OworCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGFkdmFuY2Ugb2YgdGhlIGluZGl2aWR1YWwgY2hhcmFjdGVyCisgICAgICAgICAqIEBwYXJhbSBpbmRleCAtIGNoYXJhY3RlciBpbmRleAorICAgICAgICAgKiBAcmV0dXJuIGNoYXJhY3RlciBhZHZhbmNlCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgZmxvYXQgZ2V0Q2hhckFkdmFuY2UoaW50IGluZGV4KSB7CisgICAgICAgICAgICBpZiAoYWR2YW5jZUluY3JlbWVudHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluaXRBZHZhbmNlTWFwcGluZygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gYWR2YW5jZUluY3JlbWVudHNbaW5kZXggLSB0aGlzLmdldFN0YXJ0KCldOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIG91dGxpbmUgc2hhcGUKKyAgICAgICAgICogQHJldHVybiBvdXRsaW5lCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgU2hhcGUgZ2V0T3V0bGluZSgpIHsKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB0ID0gQWZmaW5lVHJhbnNmb3JtLmdldFRyYW5zbGF0ZUluc3RhbmNlKHgsIHkpOworICAgICAgICAgICAgcmV0dXJuIHQuY3JlYXRlVHJhbnNmb3JtZWRTaGFwZSgKKyAgICAgICAgICAgICAgICAgICAgVGV4dERlY29yYXRvci5leHRlbmRPdXRsaW5lKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0R2x5cGhWZWN0b3IoKS5nZXRPdXRsaW5lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb3JhdGlvbgorICAgICAgICAgICAgICAgICAgICApCisgICAgICAgICAgICApOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBpZiB0aGUgY2hhcmFjdGVyIGRvZXNuJ3QgY29udHJpYnV0ZSB0byB0aGUgdGV4dCBhZHZhbmNlCisgICAgICAgICAqIEBwYXJhbSBpbmRleCAtIGNoYXJhY3RlciBpbmRleAorICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBoYXMgemVybyBhZHZhbmNlCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgYm9vbGVhbiBjaGFySGFzWmVyb0FkdmFuY2UoaW50IGluZGV4KSB7CisgICAgICAgICAgICBpZiAoYWR2YW5jZUluY3JlbWVudHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluaXRBZHZhbmNlTWFwcGluZygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gYWR2YW5jZUluY3JlbWVudHNbaW5kZXggLSB0aGlzLmdldFN0YXJ0KCldID09IDA7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyB0ZXh0IGhpdCBpbmZvIGZyb20gdGhlIGhpdCBwb3NpdGlvbgorICAgICAgICAgKiBAcGFyYW0gaGl0WCAtIFggY29vcmRpbmF0ZSByZWxhdGl2ZSB0byB0aGUgb3JpZ2luIG9mIHRoZSBsYXlvdXQKKyAgICAgICAgICogQHBhcmFtIGhpdFkgLSBZIGNvb3JkaW5hdGUgcmVsYXRpdmUgdG8gdGhlIG9yaWdpbiBvZiB0aGUgbGF5b3V0CisgICAgICAgICAqIEByZXR1cm4gaGl0IGluZm8KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBUZXh0SGl0SW5mbyBoaXRUZXN0KGZsb2F0IGhpdFgsIGZsb2F0IGhpdFkpIHsKKyAgICAgICAgICAgIGhpdFggLT0geDsKKworICAgICAgICAgICAgZmxvYXQgZ2x5cGhQb3NpdGlvbnNbXSA9CisgICAgICAgICAgICAgICAgICAgIGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhQb3NpdGlvbnMoMCwgaW5mby5sZW5ndGgrMSwgbnVsbCk7CisKKyAgICAgICAgICAgIGludCBnbHlwaElkeDsKKyAgICAgICAgICAgIGJvb2xlYW4gbGVhZGluZyA9IGZhbHNlOworICAgICAgICAgICAgZm9yIChnbHlwaElkeCA9IDE7IGdseXBoSWR4IDw9IGluZm8ubGVuZ3RoOyBnbHlwaElkeCsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGdseXBoUG9zaXRpb25zWyhnbHlwaElkeCkqMl0gPj0gaGl0WCkgeworICAgICAgICAgICAgICAgICAgICBmbG9hdCBhZHZhbmNlID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaFBvc2l0aW9uc1soZ2x5cGhJZHgpKjJdIC0gZ2x5cGhQb3NpdGlvbnNbKGdseXBoSWR4LTEpKjJdOworICAgICAgICAgICAgICAgICAgICBsZWFkaW5nID0gZ2x5cGhQb3NpdGlvbnNbKGdseXBoSWR4LTEpKjJdICsgYWR2YW5jZS8yID4gaGl0WCA/IHRydWUgOiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgZ2x5cGhJZHgtLTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZ2x5cGhJZHggPT0gaW5mby5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBnbHlwaElkeC0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgY2hhcklkeCA9IGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhDaGFySW5kZXgoZ2x5cGhJZHgpOworCisgICAgICAgICAgICByZXR1cm4gKGxlYWRpbmcpIF4gKChpbmZvLmxldmVsICYgMHgxKSA9PSAweDEpPworICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mby5sZWFkaW5nKGNoYXJJZHggKyBpbmZvLnN0YXJ0KSA6CisgICAgICAgICAgICAgICAgICAgIFRleHRIaXRJbmZvLnRyYWlsaW5nKGNoYXJJZHggKyBpbmZvLnN0YXJ0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb2xsZWN0cyBHbHlwaEp1c3RpZmljYXRpb25JbmZvIG9iamVjdHMgZnJvbSB0aGUgZ2x5cGggdmVjdG9yCisgICAgICAgICAqIEByZXR1cm4gYXJyYXkgb2YgYWxsIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gb2JqZWN0cworICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBHbHlwaEp1c3RpZmljYXRpb25JbmZvW10gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKSB7CisgICAgICAgICAgICBpZiAoZ2ppcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgR2x5cGhWZWN0b3IgZ3YgPSBnZXRHbHlwaFZlY3RvcigpOworICAgICAgICAgICAgICAgIGludCBuR2x5cGhzID0gZ3YuZ2V0TnVtR2x5cGhzKCk7CisgICAgICAgICAgICAgICAgaW50IGNoYXJJbmRpY2llc1tdID0gZ3YuZ2V0R2x5cGhDaGFySW5kaWNlcygwLCBuR2x5cGhzLCBudWxsKTsKKyAgICAgICAgICAgICAgICBnamlzID0gbmV3IEdseXBoSnVzdGlmaWNhdGlvbkluZm9bbkdseXBoc107CisKKyAgICAgICAgICAgICAgICAvLyBQYXRjaDogdGVtcG9yYXJ5IHBhdGNoLCBnZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvIGlzIG5vdCBpbXBsZW1lbnRlZAorICAgICAgICAgICAgICAgIGZsb2F0IGZvbnRTaXplID0gaW5mby5mb250LmdldFNpemUyRCgpOworICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZGVmYXVsdEluZm8gPQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEdseXBoSnVzdGlmaWNhdGlvbkluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8vIHdlaWdodAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9OT05FLCAwLCAwLCAvLyBncm93CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBHbHlwaEp1c3RpZmljYXRpb25JbmZvLlBSSU9SSVRZX05PTkUsIDAsIDApOyAvLyBzaHJpbmsKKyAgICAgICAgICAgICAgICBHbHlwaEp1c3RpZmljYXRpb25JbmZvIHNwYWNlSW5mbyA9IG5ldyBHbHlwaEp1c3RpZmljYXRpb25JbmZvKAorICAgICAgICAgICAgICAgICAgICAgICAgZm9udFNpemUsIC8vIHdlaWdodAorICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9XSElURVNQQUNFLCAwLCBmb250U2l6ZSwgLy8gZ3JvdworICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgR2x5cGhKdXN0aWZpY2F0aW9uSW5mby5QUklPUklUWV9XSElURVNQQUNFLCAwLCBmb250U2l6ZSk7IC8vIHNocmluaworCisgICAgICAgICAgICAgICAgLy8vLy8vLy8KKyAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgcGF0Y2gsIGdldEdseXBoSnVzdGlmaWNhdGlvbkluZm8gaXMgbm90IGltcGxlbWVudGVkCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuR2x5cGhzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy9namlzW2ldID0gZ2V0R2x5cGhWZWN0b3IoKS5nZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvKGkpOworCisgICAgICAgICAgICAgICAgICAgIGNoYXIgYyA9IGluZm8udGV4dFtjaGFySW5kaWNpZXNbaV0gKyBpbmZvLnN0YXJ0XTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKENoYXJhY3Rlci5pc1doaXRlc3BhY2UoYykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdqaXNbaV0gPSBzcGFjZUluZm87CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBnamlzW2ldID0gZGVmYXVsdEluZm87CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gRW5kIHBhdGNoCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gZ2ppczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb2xsZWN0cyBqdXN0aWZpY2F0aW9uIGluZm9ybWF0aW9uIGludG8gSnVzdGlmaWNhdGlvbkluZm8gb2JqZWN0CisgICAgICAgICAqIEBwYXJhbSBqSW5mbyAtIEp1c3RpZmljYXRpb25JbmZvIG9iamVjdAorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHZvaWQgdXBkYXRlSnVzdGlmaWNhdGlvbkluZm8oVGV4dFJ1bkJyZWFrZXIuSnVzdGlmaWNhdGlvbkluZm8gakluZm8pIHsKKyAgICAgICAgICAgIGludCBsYXN0Q2hhciA9IE1hdGgubWluKGpJbmZvLmxhc3RJZHgsIGluZm8uZW5kKSAtIGluZm8uc3RhcnQ7CisgICAgICAgICAgICBib29sZWFuIGhhdmVGaXJzdCA9IGluZm8uc3RhcnQgPD0gakluZm8uZmlyc3RJZHg7CisgICAgICAgICAgICBib29sZWFuIGhhdmVMYXN0ID0gaW5mby5lbmQgPj0gKGpJbmZvLmxhc3RJZHggKyAxKTsKKworICAgICAgICAgICAgaW50IHByZXZHbHlwaElkeCA9IC0xOworICAgICAgICAgICAgaW50IGN1cnJHbHlwaElkeDsKKworICAgICAgICAgICAgaWYgKGpJbmZvLmdyb3cpIHsgLy8gQ2hlY2sgaG93IG11Y2ggd2UgY2FuIGdyb3cvc2hyaW5rIG9uIGN1cnJlbnQgcHJpb3JpdHkgbGV2ZWwKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bGFzdENoYXI7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBjdXJyR2x5cGhJZHggPSBnZXRDaGFyMkdseXBoKClbaV07CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJHbHlwaElkeCA9PSBwcmV2R2x5cGhJZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldmVyYWwgY2hhcnMgY291bGQgYmUgcmVwcmVzZW50ZWQgYnkgb25lIGdseXBoLAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3VwcG9zZSB0aGV5IGFyZSBjb250aWd1b3VzCisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwcmV2R2x5cGhJZHggPSBjdXJyR2x5cGhJZHg7CisKKyAgICAgICAgICAgICAgICAgICAgR2x5cGhKdXN0aWZpY2F0aW9uSW5mbyBnamkgPSBnZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvcygpW2N1cnJHbHlwaElkeF07CisgICAgICAgICAgICAgICAgICAgIGlmIChnamkuZ3Jvd1ByaW9yaXR5ID09IGpJbmZvLnByaW9yaXR5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby53ZWlnaHQgKz0gZ2ppLndlaWdodCAqIDI7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby5ncm93TGltaXQgKz0gZ2ppLmdyb3dMZWZ0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby5ncm93TGltaXQgKz0gZ2ppLmdyb3dSaWdodExpbWl0OworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdqaS5ncm93QWJzb3JiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgakluZm8uYWJzb3JiZWRXZWlnaHQgKz0gZ2ppLndlaWdodCAqIDI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxsYXN0Q2hhcjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGN1cnJHbHlwaElkeCA9IGdldENoYXIyR2x5cGgoKVtpXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJHbHlwaElkeCA9PSBwcmV2R2x5cGhJZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHByZXZHbHlwaElkeCA9IGN1cnJHbHlwaElkeDsKKworICAgICAgICAgICAgICAgICAgICBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGdqaSA9IGdldEdseXBoSnVzdGlmaWNhdGlvbkluZm9zKClbY3VyckdseXBoSWR4XTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdqaS5zaHJpbmtQcmlvcml0eSA9PSBqSW5mby5wcmlvcml0eSkgeworICAgICAgICAgICAgICAgICAgICAgICAgakluZm8ud2VpZ2h0ICs9IGdqaS53ZWlnaHQgKiAyOworICAgICAgICAgICAgICAgICAgICAgICAgakluZm8uZ3Jvd0xpbWl0IC09IGdqaS5zaHJpbmtMZWZ0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby5ncm93TGltaXQgLT0gZ2ppLnNocmlua1JpZ2h0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2ppLnNocmlua0Fic29yYikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpJbmZvLmFic29yYmVkV2VpZ2h0ICs9IGdqaS53ZWlnaHQgKiAyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGF2ZUZpcnN0KSB7ICAvLyBEb24ndCBhZGQgcGFkZGluZyBiZWZvcmUgZmlyc3QgY2hhcgorICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2ppID0gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKVtnZXRDaGFyMkdseXBoKClbMF1dOworICAgICAgICAgICAgICAgIGpJbmZvLndlaWdodCAtPSBnamkud2VpZ2h0OworICAgICAgICAgICAgICAgIGlmIChqSW5mby5ncm93KSB7CisgICAgICAgICAgICAgICAgICAgIGpJbmZvLmdyb3dMaW1pdCAtPSBnamkuZ3Jvd0xlZnRMaW1pdDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdqaS5ncm93QWJzb3JiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby5hYnNvcmJlZFdlaWdodCAtPSBnamkud2VpZ2h0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgakluZm8uZ3Jvd0xpbWl0ICs9IGdqaS5zaHJpbmtMZWZ0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChnamkuc2hyaW5rQWJzb3JiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBqSW5mby5hYnNvcmJlZFdlaWdodCAtPSBnamkud2VpZ2h0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGF2ZUxhc3QpIHsgICAvLyBEb24ndCBhZGQgcGFkZGluZyBhZnRlciBsYXN0IGNoYXIKKyAgICAgICAgICAgICAgICBHbHlwaEp1c3RpZmljYXRpb25JbmZvIGdqaSA9CisgICAgICAgICAgICAgICAgICAgICAgICBnZXRHbHlwaEp1c3RpZmljYXRpb25JbmZvcygpW2dldENoYXIyR2x5cGgoKVtsYXN0Q2hhcl1dOworICAgICAgICAgICAgICAgIGpJbmZvLndlaWdodCAtPSBnamkud2VpZ2h0OworICAgICAgICAgICAgICAgIGlmIChqSW5mby5ncm93KSB7CisgICAgICAgICAgICAgICAgICAgIGpJbmZvLmdyb3dMaW1pdCAtPSBnamkuZ3Jvd1JpZ2h0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChnamkuZ3Jvd0Fic29yYikgeworICAgICAgICAgICAgICAgICAgICAgICAgakluZm8uYWJzb3JiZWRXZWlnaHQgLT0gZ2ppLndlaWdodDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGpJbmZvLmdyb3dMaW1pdCArPSBnamkuc2hyaW5rUmlnaHRMaW1pdDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdqaS5zaHJpbmtBYnNvcmIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGpJbmZvLmFic29yYmVkV2VpZ2h0IC09IGdqaS53ZWlnaHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMganVzdGlmaWNhdGlvbiBvZiB0aGUgc2VnbWVudC4KKyAgICAgICAgICogVXBkYXRlcyBwb3NpdGlvbnMgb2YgaW5kaXZpZHVhbCBjaGFyYWN0ZXJzLgorICAgICAgICAgKiBAcGFyYW0gakluZm9zIC0ganVzdGlmaWNhdGlvbiBpbmZvcm1hdGlvbiwgZ2F0aGVyZWQgYnkgdGhlIHByZXZpb3VzIHBhc3NlcworICAgICAgICAgKiBAcmV0dXJuIGFtb3VudCBvZiBncm93dGggb3Igc2hyaW5rIG9mIHRoZSBzZWdtZW50CisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgZmxvYXQgZG9KdXN0aWZpY2F0aW9uKFRleHRSdW5CcmVha2VyLkp1c3RpZmljYXRpb25JbmZvIGpJbmZvc1tdKSB7CisgICAgICAgICAgICBpbnQgbGFzdFByaW9yaXR5ID0KKyAgICAgICAgICAgICAgICAgICAgakluZm9zW2pJbmZvcy5sZW5ndGgtMV0gPT0gbnVsbCA/CisgICAgICAgICAgICAgICAgICAgIC0xIDogakluZm9zW2pJbmZvcy5sZW5ndGgtMV0ucHJpb3JpdHk7CisKKyAgICAgICAgICAgIC8vIEdldCB0aGUgaGlnaGVzdCBwcmlvcml0eQorICAgICAgICAgICAgaW50IGhpZ2hlc3RQcmlvcml0eSA9IDA7CisgICAgICAgICAgICBmb3IgKDsgaGlnaGVzdFByaW9yaXR5PGpJbmZvcy5sZW5ndGg7IGhpZ2hlc3RQcmlvcml0eSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGpJbmZvc1toaWdoZXN0UHJpb3JpdHldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGlnaGVzdFByaW9yaXR5ID09IGpJbmZvcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgVGV4dFJ1bkJyZWFrZXIuSnVzdGlmaWNhdGlvbkluZm8gZmlyc3RJbmZvID0gakluZm9zW2hpZ2hlc3RQcmlvcml0eV07CisgICAgICAgICAgICBUZXh0UnVuQnJlYWtlci5KdXN0aWZpY2F0aW9uSW5mbyBsYXN0SW5mbyA9CisgICAgICAgICAgICAgICAgICAgIGxhc3RQcmlvcml0eSA+IDAgPyBqSW5mb3NbbGFzdFByaW9yaXR5XSA6IG51bGw7CisKKyAgICAgICAgICAgIGJvb2xlYW4gaGF2ZUZpcnN0ID0gaW5mby5zdGFydCA8PSBmaXJzdEluZm8uZmlyc3RJZHg7CisgICAgICAgICAgICBib29sZWFuIGhhdmVMYXN0ID0gaW5mby5lbmQgPj0gKGZpcnN0SW5mby5sYXN0SWR4ICsgMSk7CisKKyAgICAgICAgICAgIC8vIEhlcmUgd2Ugc3VwcG9zZSB0aGF0IEdMWVBIUyBhcmUgb3JkZXJlZCBMRUZUIFRPIFJJR0hUCisgICAgICAgICAgICBpbnQgZmlyc3RHbHlwaCA9IGhhdmVGaXJzdCA/CisgICAgICAgICAgICAgICAgICAgIGdldENoYXIyR2x5cGgoKVtmaXJzdEluZm8uZmlyc3RJZHggLSBpbmZvLnN0YXJ0XSA6CisgICAgICAgICAgICAgICAgICAgIGdldENoYXIyR2x5cGgoKVswXTsKKworICAgICAgICAgICAgaW50IGxhc3RHbHlwaCA9IGhhdmVMYXN0ID8KKyAgICAgICAgICAgICAgICAgICAgZ2V0Q2hhcjJHbHlwaCgpW2ZpcnN0SW5mby5sYXN0SWR4IC0gaW5mby5zdGFydF0gOgorICAgICAgICAgICAgICAgICAgICBnZXRDaGFyMkdseXBoKClbaW5mby5sZW5ndGggLSAxXTsKKyAgICAgICAgICAgIGlmIChoYXZlTGFzdCkgeworICAgICAgICAgICAgICAgIGxhc3RHbHlwaC0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBUZXh0UnVuQnJlYWtlci5KdXN0aWZpY2F0aW9uSW5mbyBjdXJySW5mbzsKKyAgICAgICAgICAgIGZsb2F0IGdseXBoT2Zmc2V0ID0gMDsKKyAgICAgICAgICAgIGZsb2F0IHBvc2l0aW9uSW5jcmVtZW50ID0gMDsKKyAgICAgICAgICAgIGZsb2F0IHNpZGVJbmNyZW1lbnQgPSAwOworCisgICAgICAgICAgICBpZiAoaGF2ZUZpcnN0KSB7ICAvLyBEb24ndCBhZGQgcGFkZGluZyBiZWZvcmUgZmlyc3QgY2hhcgorICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2ppID0gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKVtmaXJzdEdseXBoXTsKKyAgICAgICAgICAgICAgICBjdXJySW5mbyA9IGpJbmZvc1tnamkuZ3Jvd1ByaW9yaXR5XTsKKyAgICAgICAgICAgICAgICBpZiAoY3VyckluZm8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckluZm8udXNlTGltaXRzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckluZm8uYWJzb3JiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gZ2ppLndlaWdodCAqIGN1cnJJbmZvLmFic29yYmVkR2FwUGVyVW5pdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RJbmZvICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEluZm8ucHJpb3JpdHkgPT0gY3VyckluZm8ucHJpb3JpdHkKKyAgICAgICAgICAgICAgICAgICAgICAgICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IGdqaS53ZWlnaHQgKiBsYXN0SW5mby5hYnNvcmJlZEdhcFBlclVuaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEluZm8uZ3JvdyA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdqaS5ncm93UmlnaHRMaW1pdCA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1namkuc2hyaW5rUmlnaHRMaW1pdDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IGdqaS53ZWlnaHQgKiBjdXJySW5mby5nYXBQZXJVbml0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZmlyc3RHbHlwaCsrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZmlyc3RJbmZvLmdyb3cpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPWZpcnN0R2x5cGg7IGk8PWxhc3RHbHlwaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2ppID0gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKVtpXTsKKyAgICAgICAgICAgICAgICAgICAgY3VyckluZm8gPSBqSW5mb3NbZ2ppLmdyb3dQcmlvcml0eV07CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJySW5mbyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBzdGlsbCBoYXZlIHRvIGluY3JlbWVudCBnbHlwaCBwb3NpdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgUG9pbnQyRCBnbHlwaFBvcyA9IGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhQb3NpdGlvbihpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoUG9zLnNldExvY2F0aW9uKGdseXBoUG9zLmdldFgoKSArIGdseXBoT2Zmc2V0LCBnbHlwaFBvcy5nZXRZKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgZ2V0R2x5cGhWZWN0b3IoKS5zZXRHbHlwaFBvc2l0aW9uKGksIGdseXBoUG9zKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckluZm8udXNlTGltaXRzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBnamkuZ3Jvd0xlZnRMaW1pdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJySW5mby5hYnNvcmIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWRlSW5jcmVtZW50ID0gZ2ppLndlaWdodCAqIGN1cnJJbmZvLmFic29yYmVkR2FwUGVyVW5pdDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBzaWRlSW5jcmVtZW50OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uSW5jcmVtZW50ID0gZ2x5cGhPZmZzZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gc2lkZUluY3JlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGFzdEluZm8gIT0gbnVsbCAmJiBsYXN0SW5mby5wcmlvcml0eSA9PSBjdXJySW5mby5wcmlvcml0eSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZGVJbmNyZW1lbnQgPSBnamkud2VpZ2h0ICogbGFzdEluZm8uYWJzb3JiZWRHYXBQZXJVbml0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IHNpZGVJbmNyZW1lbnQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25JbmNyZW1lbnQgPSBnbHlwaE9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBzaWRlSW5jcmVtZW50OworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbkluY3JlbWVudCA9IGdseXBoT2Zmc2V0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gZ2ppLmdyb3dSaWdodExpbWl0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgc2lkZUluY3JlbWVudCA9IGdqaS53ZWlnaHQgKiBjdXJySW5mby5nYXBQZXJVbml0OworICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gc2lkZUluY3JlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uSW5jcmVtZW50ID0gZ2x5cGhPZmZzZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBzaWRlSW5jcmVtZW50OworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgUG9pbnQyRCBnbHlwaFBvcyA9IGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhQb3NpdGlvbihpKTsKKyAgICAgICAgICAgICAgICAgICAgZ2x5cGhQb3Muc2V0TG9jYXRpb24oZ2x5cGhQb3MuZ2V0WCgpICsgcG9zaXRpb25JbmNyZW1lbnQsIGdseXBoUG9zLmdldFkoKSk7CisgICAgICAgICAgICAgICAgICAgIGdldEdseXBoVmVjdG9yKCkuc2V0R2x5cGhQb3NpdGlvbihpLCBnbHlwaFBvcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPWZpcnN0R2x5cGg7IGk8PWxhc3RHbHlwaDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2ppID0gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKVtpXTsKKyAgICAgICAgICAgICAgICAgICAgY3VyckluZm8gPSBqSW5mb3NbZ2ppLnNocmlua1ByaW9yaXR5XTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJJbmZvID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIHN0aWxsIGhhdmUgdG8gaW5jcmVtZW50IGdseXBoIHBvc2l0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICBQb2ludDJEIGdseXBoUG9zID0gZ2V0R2x5cGhWZWN0b3IoKS5nZXRHbHlwaFBvc2l0aW9uKGkpOworICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhQb3Muc2V0TG9jYXRpb24oZ2x5cGhQb3MuZ2V0WCgpICsgZ2x5cGhPZmZzZXQsIGdseXBoUG9zLmdldFkoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBnZXRHbHlwaFZlY3RvcigpLnNldEdseXBoUG9zaXRpb24oaSwgZ2x5cGhQb3MpOworCisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJySW5mby51c2VMaW1pdHMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0IC09IGdqaS5zaHJpbmtMZWZ0TGltaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckluZm8uYWJzb3JiKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkZUluY3JlbWVudCA9IGdqaS53ZWlnaHQgKiBjdXJySW5mby5hYnNvcmJlZEdhcFBlclVuaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gc2lkZUluY3JlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbkluY3JlbWVudCA9IGdseXBoT2Zmc2V0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IHNpZGVJbmNyZW1lbnQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxhc3RJbmZvICE9IG51bGwgJiYgbGFzdEluZm8ucHJpb3JpdHkgPT0gY3VyckluZm8ucHJpb3JpdHkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWRlSW5jcmVtZW50ID0gZ2ppLndlaWdodCAqIGxhc3RJbmZvLmFic29yYmVkR2FwUGVyVW5pdDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBzaWRlSW5jcmVtZW50OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uSW5jcmVtZW50ID0gZ2x5cGhPZmZzZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gc2lkZUluY3JlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25JbmNyZW1lbnQgPSBnbHlwaE9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0IC09IGdqaS5zaHJpbmtSaWdodExpbWl0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgc2lkZUluY3JlbWVudCA9ICBnamkud2VpZ2h0ICogY3VyckluZm8uZ2FwUGVyVW5pdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IHNpZGVJbmNyZW1lbnQ7CisgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbkluY3JlbWVudCA9IGdseXBoT2Zmc2V0OworICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gc2lkZUluY3JlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIFBvaW50MkQgZ2x5cGhQb3MgPSBnZXRHbHlwaFZlY3RvcigpLmdldEdseXBoUG9zaXRpb24oaSk7CisgICAgICAgICAgICAgICAgICAgIGdseXBoUG9zLnNldExvY2F0aW9uKGdseXBoUG9zLmdldFgoKSArIHBvc2l0aW9uSW5jcmVtZW50LCBnbHlwaFBvcy5nZXRZKCkpOworICAgICAgICAgICAgICAgICAgICBnZXRHbHlwaFZlY3RvcigpLnNldEdseXBoUG9zaXRpb24oaSwgZ2x5cGhQb3MpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworCisgICAgICAgICAgICBpZiAoaGF2ZUxhc3QpIHsgICAvLyBEb24ndCBhZGQgcGFkZGluZyBhZnRlciBsYXN0IGNoYXIKKyAgICAgICAgICAgICAgICBsYXN0R2x5cGgrKzsKKworICAgICAgICAgICAgICAgIEdseXBoSnVzdGlmaWNhdGlvbkluZm8gZ2ppID0gZ2V0R2x5cGhKdXN0aWZpY2F0aW9uSW5mb3MoKVtsYXN0R2x5cGhdOworICAgICAgICAgICAgICAgIGN1cnJJbmZvID0gakluZm9zW2dqaS5ncm93UHJpb3JpdHldOworCisgICAgICAgICAgICAgICAgaWYgKGN1cnJJbmZvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJJbmZvLnVzZUxpbWl0cykgeworICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gZmlyc3RJbmZvLmdyb3cgPyBnamkuZ3Jvd0xlZnRMaW1pdCA6IC1namkuc2hyaW5rTGVmdExpbWl0OworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJJbmZvLmFic29yYikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ICs9IGdqaS53ZWlnaHQgKiBjdXJySW5mby5hYnNvcmJlZEdhcFBlclVuaXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxhc3RJbmZvICE9IG51bGwgJiYgbGFzdEluZm8ucHJpb3JpdHkgPT0gY3VyckluZm8ucHJpb3JpdHkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCArPSBnamkud2VpZ2h0ICogbGFzdEluZm8uYWJzb3JiZWRHYXBQZXJVbml0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgKz0gZ2ppLndlaWdodCAqIGN1cnJJbmZvLmdhcFBlclVuaXQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBBanVzdCBwb3NpdGlvbnMgb2YgYWxsIGdseXBocyBhZnRlciBsYXN0IGdseXBoCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT1sYXN0R2x5cGg7IGk8Z2V0R2x5cGhWZWN0b3IoKS5nZXROdW1HbHlwaHMoKSsxOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgUG9pbnQyRCBnbHlwaFBvcyA9IGdldEdseXBoVmVjdG9yKCkuZ2V0R2x5cGhQb3NpdGlvbihpKTsKKyAgICAgICAgICAgICAgICAgICAgZ2x5cGhQb3Muc2V0TG9jYXRpb24oZ2x5cGhQb3MuZ2V0WCgpICsgZ2x5cGhPZmZzZXQsIGdseXBoUG9zLmdldFkoKSk7CisgICAgICAgICAgICAgICAgICAgIGdldEdseXBoVmVjdG9yKCkuc2V0R2x5cGhQb3NpdGlvbihpLCBnbHlwaFBvcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgLy8gVXBkYXRlIHBvc2l0aW9uIGFmdGVyIGxhc3QgZ2x5cGggaW4gZ2x5cGggdmVjdG9yIC0KKyAgICAgICAgICAgICAgICAvLyB0byBnZXQgY29ycmVjdCBhZHZhbmNlIGZvciBpdAorICAgICAgICAgICAgICAgIFBvaW50MkQgZ2x5cGhQb3MgPSBnZXRHbHlwaFZlY3RvcigpLmdldEdseXBoUG9zaXRpb24obGFzdEdseXBoKzEpOworICAgICAgICAgICAgICAgIGdseXBoUG9zLnNldExvY2F0aW9uKGdseXBoUG9zLmdldFgoKSArIGdseXBoT2Zmc2V0LCBnbHlwaFBvcy5nZXRZKCkpOworICAgICAgICAgICAgICAgIGdldEdseXBoVmVjdG9yKCkuc2V0R2x5cGhQb3NpdGlvbihsYXN0R2x5cGgrMSwgZ2x5cGhQb3MpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBnamlzID0gbnVsbDsgLy8gV2UgZG9uJ3QgbmVlZCBqdXN0aWZpY2F0aW9uIGluZm9zIGFueSBtb3JlCisgICAgICAgICAgICAvLyBBbHNvIHdlIGhhdmUgdG8gcmVzZXQgY2FjaGVkIGJvdW5kcyBhbmQgbWV0cmljcworICAgICAgICAgICAgdGhpcy52aXN1YWxCb3VuZHMgPSBudWxsOworICAgICAgICAgICAgdGhpcy5sb2dpY2FsQm91bmRzID0gbnVsbDsKKworICAgICAgICAgICAgcmV0dXJuIGdseXBoT2Zmc2V0OyAvLyBIb3cgbXVjaCBvdXIgc2VnbWVudCBncm93biBvciBzaHJ1bmsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGV4dFJ1blNlZ21lbnRHcmFwaGljIGV4dGVuZHMgVGV4dFJ1blNlZ21lbnQgeworICAgICAgICBHcmFwaGljQXR0cmlidXRlIGdhOworICAgICAgICBpbnQgc3RhcnQ7CisgICAgICAgIGludCBsZW5ndGg7CisgICAgICAgIGZsb2F0IGZ1bGxBZHZhbmNlOworCisgICAgICAgIFRleHRSdW5TZWdtZW50R3JhcGhpYyhHcmFwaGljQXR0cmlidXRlIGF0dHIsIGludCBsZW4sIGludCBzdGFydCkgeworICAgICAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0OworICAgICAgICAgICAgbGVuZ3RoID0gbGVuOworICAgICAgICAgICAgZ2EgPSBhdHRyOworICAgICAgICAgICAgbWV0cmljcyA9IG5ldyBCYXNpY01ldHJpY3MoZ2EpOworICAgICAgICAgICAgZnVsbEFkdmFuY2UgPSBnYS5nZXRBZHZhbmNlKCkgKiBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGV4dFJ1blNlZ21lbnRHcmFwaGljKGdhLCBsZW5ndGgsIHN0YXJ0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlbmRlcnMgdGhpcyB0ZXh0IHJ1biBzZWdtZW50CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICB2b2lkIGRyYXcoR3JhcGhpY3MyRCBnMmQsIGZsb2F0IHhPZmZzZXQsIGZsb2F0IHlPZmZzZXQpIHsKKyAgICAgICAgICAgIGlmIChkZWNvcmF0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBUZXh0RGVjb3JhdG9yLnByZXBhcmVHcmFwaGljcyh0aGlzLCBnMmQsIHhPZmZzZXQsIHlPZmZzZXQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmbG9hdCB4UG9zID0geCArIHhPZmZzZXQ7CisgICAgICAgICAgICBmbG9hdCB5UG9zID0geSArIHlPZmZzZXQ7CisKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZ2EuZHJhdyhnMmQsIHhQb3MsIHlQb3MpOworICAgICAgICAgICAgICAgIHhQb3MgKz0gZ2EuZ2V0QWR2YW5jZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZGVjb3JhdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgVGV4dERlY29yYXRvci5kcmF3VGV4dERlY29yYXRpb25zKHRoaXMsIGcyZCwgeE9mZnNldCwgeU9mZnNldCk7CisgICAgICAgICAgICAgICAgVGV4dERlY29yYXRvci5yZXN0b3JlR3JhcGhpY3MoZGVjb3JhdGlvbiwgZzJkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFJldHVybnMgdmlzdWFsIGJvdW5kcyBvZiB0aGlzIHNlZ21lbnQKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIFJlY3RhbmdsZTJEIGdldFZpc3VhbEJvdW5kcygpIHsKKyAgICAgICAgICAgIGlmICh2aXN1YWxCb3VuZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFJlY3RhbmdsZTJEIGJvdW5kcyA9IGdhLmdldEJvdW5kcygpOworCisgICAgICAgICAgICAgICAgLy8gRmlyc3QgYW5kIGxhc3QgY2hhcnMgY2FuIGJlIG91dCBvZiBsb2dpY2FsIGJvdW5kcywgc28gd2UgY2FsY3VsYXRlCisgICAgICAgICAgICAgICAgLy8gKGJvdW5kcy5nZXRXaWR0aCgpIC0gZ2EuZ2V0QWR2YW5jZSgpKSB3aGljaCBpcyBleGFjdGx5IHRoZSBkaWZmZXJlbmNlCisgICAgICAgICAgICAgICAgYm91bmRzLnNldFJlY3QoCisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuZ2V0TWluWCgpICsgeCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kcy5nZXRNaW5ZKCkgKyB5LAorICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRzLmdldFdpZHRoKCkgLSBnYS5nZXRBZHZhbmNlKCkgKyBnZXRBZHZhbmNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuZ2V0SGVpZ2h0KCkKKyAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgIHZpc3VhbEJvdW5kcyA9IFRleHREZWNvcmF0b3IuZXh0ZW5kVmlzdWFsQm91bmRzKHRoaXMsIGJvdW5kcywgZGVjb3JhdGlvbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiAoUmVjdGFuZ2xlMkQpIHZpc3VhbEJvdW5kcy5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIFJlY3RhbmdsZTJEIGdldExvZ2ljYWxCb3VuZHMoKSB7CisgICAgICAgICAgICBpZiAobG9naWNhbEJvdW5kcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9naWNhbEJvdW5kcyA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVjdGFuZ2xlMkQuRmxvYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgsIHkgLSBtZXRyaWNzLmFzY2VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QWR2YW5jZSgpLCBtZXRyaWNzLmFzY2VudCArIG1ldHJpY3MuZGVzY2VudAorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIChSZWN0YW5nbGUyRCkgbG9naWNhbEJvdW5kcy5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGZsb2F0IGdldEFkdmFuY2UoKSB7CisgICAgICAgICAgICByZXR1cm4gZnVsbEFkdmFuY2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgZmxvYXQgZ2V0QWR2YW5jZURlbHRhKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICAgICAgcmV0dXJuIGdhLmdldEFkdmFuY2UoKSAqIChlbmQgLSBzdGFydCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IGdldENoYXJJbmRleEZyb21BZHZhbmNlKGZsb2F0IGFkdmFuY2UsIGludCBzdGFydCkgeworICAgICAgICAgICAgc3RhcnQgLT0gdGhpcy5zdGFydDsKKworICAgICAgICAgICAgaWYgKHN0YXJ0IDwgMCkgeworICAgICAgICAgICAgICAgIHN0YXJ0ID0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGNoYXJPZmZzZXQgPSAoaW50KSAoYWR2YW5jZS9nYS5nZXRBZHZhbmNlKCkpOworCisgICAgICAgICAgICBpZiAoY2hhck9mZnNldCArIHN0YXJ0ID4gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxlbmd0aCArIHRoaXMuc3RhcnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhck9mZnNldCArIHN0YXJ0ICsgdGhpcy5zdGFydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgZ2V0U3RhcnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IGdldEVuZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzdGFydCArIGxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBTaGFwZSBnZXRDaGFyc0JsYWNrQm94Qm91bmRzKGludCBzdGFydCwgaW50IGxpbWl0KSB7CisgICAgICAgICAgICBzdGFydCAtPSB0aGlzLnN0YXJ0OworICAgICAgICAgICAgbGltaXQgLT0gdGhpcy5zdGFydDsKKworICAgICAgICAgICAgaWYgKGxpbWl0ID4gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbGltaXQgPSBsZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFJlY3RhbmdsZTJEIGNoYXJCb3VuZHMgPSBnYS5nZXRCb3VuZHMoKTsKKyAgICAgICAgICAgIGNoYXJCb3VuZHMuc2V0UmVjdCgKKyAgICAgICAgICAgICAgICAgICAgY2hhckJvdW5kcy5nZXRYKCkgKyBnYS5nZXRBZHZhbmNlKCkgKiBzdGFydCArIHgsCisgICAgICAgICAgICAgICAgICAgIGNoYXJCb3VuZHMuZ2V0WSgpICsgeSwKKyAgICAgICAgICAgICAgICAgICAgY2hhckJvdW5kcy5nZXRXaWR0aCgpICsgZ2EuZ2V0QWR2YW5jZSgpICogKGxpbWl0IC0gc3RhcnQpLAorICAgICAgICAgICAgICAgICAgICBjaGFyQm91bmRzLmdldEhlaWdodCgpCisgICAgICAgICAgICApOworCisgICAgICAgICAgICByZXR1cm4gY2hhckJvdW5kczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBmbG9hdCBnZXRDaGFyUG9zaXRpb24oaW50IGluZGV4KSB7CisgICAgICAgICAgICBpbmRleCAtPSBzdGFydDsKKyAgICAgICAgICAgIGlmIChpbmRleCA+IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gZ2EuZ2V0QWR2YW5jZSgpICogaW5kZXggKyB4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGZsb2F0IGdldENoYXJBZHZhbmNlKGludCBpbmRleCkgeworICAgICAgICAgICAgcmV0dXJuIGdhLmdldEFkdmFuY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBTaGFwZSBnZXRPdXRsaW5lKCkgeworICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHQgPSBBZmZpbmVUcmFuc2Zvcm0uZ2V0VHJhbnNsYXRlSW5zdGFuY2UoeCwgeSk7CisgICAgICAgICAgICByZXR1cm4gdC5jcmVhdGVUcmFuc2Zvcm1lZFNoYXBlKAorICAgICAgICAgICAgICAgICAgICBUZXh0RGVjb3JhdG9yLmV4dGVuZE91dGxpbmUodGhpcywgZ2V0VmlzdWFsQm91bmRzKCksIGRlY29yYXRpb24pCisgICAgICAgICAgICApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gY2hhckhhc1plcm9BZHZhbmNlKGludCBpbmRleCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIFRleHRIaXRJbmZvIGhpdFRlc3QoZmxvYXQgaGl0WCwgZmxvYXQgaGl0WSkgeworICAgICAgICAgICAgaGl0WCAtPSB4OworCisgICAgICAgICAgICBmbG9hdCB0bXAgPSBoaXRYIC8gZ2EuZ2V0QWR2YW5jZSgpOworICAgICAgICAgICAgaW50IGhpdEluZGV4ID0gTWF0aC5yb3VuZCh0bXApOworCisgICAgICAgICAgICBpZiAodG1wID4gaGl0SW5kZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gVGV4dEhpdEluZm8ubGVhZGluZyhoaXRJbmRleCArIHRoaXMuc3RhcnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIFRleHRIaXRJbmZvLnRyYWlsaW5nKGhpdEluZGV4ICsgdGhpcy5zdGFydCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgdm9pZCB1cGRhdGVKdXN0aWZpY2F0aW9uSW5mbyhUZXh0UnVuQnJlYWtlci5KdXN0aWZpY2F0aW9uSW5mbyBqSW5mbykgeworICAgICAgICAgICAgLy8gRG8gbm90aGluZworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGZsb2F0IGRvSnVzdGlmaWNhdGlvbihUZXh0UnVuQnJlYWtlci5KdXN0aWZpY2F0aW9uSW5mbyBqSW5mb3NbXSkgeworICAgICAgICAgICAgLy8gRG8gbm90aGluZworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9CdWZmZXJlZEltYWdlR3JhcGhpY3MyRC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWQ2NGZiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEFsZXhleSBBLiBQZXRyZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljc0NvbmZpZ3VyYXRpb247CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuQ29tbW9uR3JhcGhpY3MyRDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXIuSmF2YUJsaXR0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXIuTmF0aXZlSW1hZ2VCbGl0dGVyOworCisvKioKKyAqIEJ1ZmZlcmVkSW1hZ2VHcmFwaGljczJEIGlzIGltcGxlbWVudGF0aW9uIG9mIENvbW1vbkdyYXBoaWNzMkQgZm9yCisgKiBkcmF3aW5nIG9uIGJ1ZmZlcmVkIGltYWdlcy4gCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJlZEltYWdlR3JhcGhpY3MyRCBleHRlbmRzIENvbW1vbkdyYXBoaWNzMkQgeworICAgIHByaXZhdGUgQnVmZmVyZWRJbWFnZSBiaSA9IG51bGw7CisgICAgcHJpdmF0ZSBSZWN0YW5nbGUgYm91bmRzID0gbnVsbDsKKworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlR3JhcGhpY3MyRChCdWZmZXJlZEltYWdlIGJpKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgICAgIHRoaXMuYmkgPSBiaTsKKyAgICAgICAgdGhpcy5ib3VuZHMgPSBuZXcgUmVjdGFuZ2xlKDAsIDAsIGJpLmdldFdpZHRoKCksIGJpLmdldEhlaWdodCgpKTsKKyAgICAgICAgY2xpcChib3VuZHMpOworICAgICAgICBkc3RTdXJmID0gU3VyZmFjZS5nZXRJbWFnZVN1cmZhY2UoYmkpOworICAgICAgICBpZihkc3RTdXJmLmlzTmF0aXZlRHJhd2FibGUoKSl7CisgICAgICAgICAgICBibGl0dGVyID0gTmF0aXZlSW1hZ2VCbGl0dGVyLmdldEluc3RhbmNlKCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgYmxpdHRlciA9IEphdmFCbGl0dGVyLmdldEluc3RhbmNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb3B5QXJlYShpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGR4LCBpbnQgZHkpIHsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3MgY3JlYXRlKCkgeworICAgICAgICBCdWZmZXJlZEltYWdlR3JhcGhpY3MyRCByZXMgPSBuZXcgQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQoYmkpOworICAgICAgICBjb3B5SW50ZXJuYWxGaWVsZHMocmVzKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgR3JhcGhpY3NDb25maWd1cmF0aW9uIGdldERldmljZUNvbmZpZ3VyYXRpb24oKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDb2xvck1vZGVsIGdldENvbG9yTW9kZWwoKSB7CisgICAgICAgIHJldHVybiBiaS5nZXRDb2xvck1vZGVsKCk7CisgICAgfQorCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldFdyaXRhYmxlUmFzdGVyKCkgeworICAgICAgICByZXR1cm4gYmkuZ2V0UmFzdGVyKCk7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0J1ZmZlcmVkSW1hZ2VTb3VyY2UuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0J1ZmZlcmVkSW1hZ2VTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZmUyNWEyCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvQnVmZmVyZWRJbWFnZVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMTM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlOworCitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbXBvbmVudENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyQnl0ZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVySW50OworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRpcmVjdENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VDb25zdW1lcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkluZGV4Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCitwdWJsaWMgY2xhc3MgQnVmZmVyZWRJbWFnZVNvdXJjZSBpbXBsZW1lbnRzIEltYWdlUHJvZHVjZXIgeworCisgICAgcHJpdmF0ZSBIYXNodGFibGU8PywgPz4gcHJvcGVydGllczsKKyAgICBwcml2YXRlIENvbG9yTW9kZWwgY207CisgICAgcHJpdmF0ZSBXcml0YWJsZVJhc3RlciByYXN0ZXI7CisgICAgcHJpdmF0ZSBpbnQgd2lkdGg7CisgICAgcHJpdmF0ZSBpbnQgaGVpZ2h0OworCisgICAgcHJpdmF0ZSBJbWFnZUNvbnN1bWVyIGljOworCisgICAgcHVibGljIEJ1ZmZlcmVkSW1hZ2VTb3VyY2UoQnVmZmVyZWRJbWFnZSBpbWFnZSwgSGFzaHRhYmxlPD8sID8+IHByb3BlcnRpZXMpeworICAgICAgICBpZihwcm9wZXJ0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucHJvcGVydGllcyA9IG5ldyBIYXNodGFibGU8T2JqZWN0LCBPYmplY3Q+KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzOworICAgICAgICB9CisKKyAgICAgICAgd2lkdGggPSBpbWFnZS5nZXRXaWR0aCgpOworICAgICAgICBoZWlnaHQgPSBpbWFnZS5nZXRIZWlnaHQoKTsKKyAgICAgICAgY20gPSBpbWFnZS5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgIHJhc3RlciA9IGltYWdlLmdldFJhc3RlcigpOworICAgIH0KKworICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlU291cmNlKEJ1ZmZlcmVkSW1hZ2UgaW1hZ2UpeworICAgICAgICB0aGlzKGltYWdlLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgcmV0dXJuICh0aGlzLmljID09IGljKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzdGFydFByb2R1Y3Rpb24oSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBhZGRDb25zdW1lcihpYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVxdWVzdFRvcERvd25MZWZ0UmlnaHRSZXNlbmQoSW1hZ2VDb25zdW1lciBpYykgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUNvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgaWYgKHRoaXMuaWMgPT0gaWMpIHsKKyAgICAgICAgICAgIHRoaXMuaWMgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICB0aGlzLmljID0gaWM7CisgICAgICAgIHN0YXJ0UHJvZHVjdGlvbigpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzdGFydFByb2R1Y3Rpb24oKXsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGljLnNldERpbWVuc2lvbnMod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICBpYy5zZXRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpOworICAgICAgICAgICAgaWMuc2V0Q29sb3JNb2RlbChjbSk7CisgICAgICAgICAgICBpYy5zZXRIaW50cyhJbWFnZUNvbnN1bWVyLlRPUERPV05MRUZUUklHSFQgfAorICAgICAgICAgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLkNPTVBMRVRFU0NBTkxJTkVTIHwKKyAgICAgICAgICAgICAgICAgICAgSW1hZ2VDb25zdW1lci5TSU5HTEVGUkFNRSB8CisgICAgICAgICAgICAgICAgICAgIEltYWdlQ29uc3VtZXIuU0lOR0xFUEFTUyk7CisgICAgICAgICAgICBpZihjbSBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCAmJgorICAgICAgICAgICAgICAgICAgICByYXN0ZXIuZ2V0VHJhbnNmZXJUeXBlKCkgPT0gRGF0YUJ1ZmZlci5UWVBFX0JZVEUgfHwKKyAgICAgICAgICAgICAgICAgICAgY20gaW5zdGFuY2VvZiBDb21wb25lbnRDb2xvck1vZGVsICYmCisgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5nZXRUcmFuc2ZlclR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJgorICAgICAgICAgICAgICAgICAgICByYXN0ZXIuZ2V0TnVtRGF0YUVsZW1lbnRzKCkgPT0gMSl7CisgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlckJ5dGUgZGJiID0gKERhdGFCdWZmZXJCeXRlKSByYXN0ZXIuZ2V0RGF0YUJ1ZmZlcigpOworICAgICAgICAgICAgICAgIGJ5dGUgZGF0YVtdID0gZGJiLmdldERhdGEoKTsKKyAgICAgICAgICAgICAgICBpbnQgb2ZmID0gZGJiLmdldE9mZnNldCgpOworICAgICAgICAgICAgICAgIGljLnNldFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBjbSwgZGF0YSwgb2ZmLCB3aWR0aCk7CisgICAgICAgICAgICB9ZWxzZSBpZihjbSBpbnN0YW5jZW9mIERpcmVjdENvbG9yTW9kZWwgJiYKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyLmdldFRyYW5zZmVyVHlwZSgpID09IERhdGFCdWZmZXIuVFlQRV9JTlQpeworICAgICAgICAgICAgICAgIERhdGFCdWZmZXJJbnQgZGJpID0gKERhdGFCdWZmZXJJbnQpIHJhc3Rlci5nZXREYXRhQnVmZmVyKCk7CisgICAgICAgICAgICAgICAgaW50IGRhdGFbXSA9IGRiaS5nZXREYXRhKCk7CisgICAgICAgICAgICAgICAgaW50IG9mZiA9IGRiaS5nZXRPZmZzZXQoKTsKKyAgICAgICAgICAgICAgICBpYy5zZXRQaXhlbHMoMCwgMCwgd2lkdGgsIGhlaWdodCwgY20sIGRhdGEsIG9mZiwgd2lkdGgpOworICAgICAgICAgICAgfWVsc2UgaWYoY20gaW5zdGFuY2VvZiBEaXJlY3RDb2xvck1vZGVsICYmCisgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5nZXRUcmFuc2ZlclR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSl7CisgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlckJ5dGUgZGJiID0gKERhdGFCdWZmZXJCeXRlKSByYXN0ZXIuZ2V0RGF0YUJ1ZmZlcigpOworICAgICAgICAgICAgICAgIGJ5dGUgZGF0YVtdID0gZGJiLmdldERhdGEoKTsKKyAgICAgICAgICAgICAgICBpbnQgb2ZmID0gZGJiLmdldE9mZnNldCgpOworICAgICAgICAgICAgICAgIGljLnNldFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBjbSwgZGF0YSwgb2ZmLCB3aWR0aCk7CisgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICBDb2xvck1vZGVsIHJnYkNNID0gQ29sb3JNb2RlbC5nZXRSR0JkZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgaW50IHBpeGVsc1tdID0gbmV3IGludFt3aWR0aF07CisgICAgICAgICAgICAgICAgT2JqZWN0IHBpeCA9IG51bGw7CisgICAgICAgICAgICAgICAgZm9yKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKXsKKyAgICAgICAgICAgICAgICAgICAgZm9yKGludCB4ID0gMCA7IHggPCB3aWR0aDsgeCsrKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeCA9IHJhc3Rlci5nZXREYXRhRWxlbWVudHMoeCwgeSwgcGl4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1t4XSA9IGNtLmdldFJHQihwaXgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGljLnNldFBpeGVscygwLCB5LCB3aWR0aCwgMSwgcmdiQ00sIHBpeGVscywgMCwgd2lkdGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGljLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5TVEFUSUNJTUFHRURPTkUpOworICAgICAgICB9Y2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgaWYgKGljICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpYy5pbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuSU1BR0VFUlJPUik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0J5dGVBcnJheURlY29kaW5nSW1hZ2VTb3VyY2UuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0J5dGVBcnJheURlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzZkN2NmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvQnl0ZUFycmF5RGVjb2RpbmdJbWFnZVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworLyoKKyAqIENyZWF0ZWQgb24gMTAuMDIuMjAwNQorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIEJ5dGVBcnJheURlY29kaW5nSW1hZ2VTb3VyY2UgZXh0ZW5kcyBEZWNvZGluZ0ltYWdlU291cmNlIHsKKworICAgIGJ5dGUgaW1hZ2VkYXRhW107CisgICAgaW50IGltYWdlb2Zmc2V0OworICAgIGludCBpbWFnZWxlbmd0aDsKKworICAgIHB1YmxpYyBCeXRlQXJyYXlEZWNvZGluZ0ltYWdlU291cmNlKGJ5dGUgaW1hZ2VkYXRhW10sIGludCBpbWFnZW9mZnNldCwKKyAgICAgICAgICAgIGludCBpbWFnZWxlbmd0aCl7CisgICAgICAgIHRoaXMuaW1hZ2VkYXRhID0gaW1hZ2VkYXRhOworICAgICAgICB0aGlzLmltYWdlb2Zmc2V0ID0gaW1hZ2VvZmZzZXQ7CisgICAgICAgIHRoaXMuaW1hZ2VsZW5ndGggPSBpbWFnZWxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZUFycmF5RGVjb2RpbmdJbWFnZVNvdXJjZShieXRlIGltYWdlZGF0YVtdKXsKKyAgICAgICAgdGhpcyhpbWFnZWRhdGEsIDAsIGltYWdlZGF0YS5sZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIGNoZWNrQ29ubmVjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLW1vZGlmaWVkCisgICAgICAgIC8vIFRPRE86IFdoeSBkb2VzIGEgQnl0ZUFycmF5SW5wdXRTdHJlYW0gbmVlZCB0byBiZSBidWZmZXJlZCBhdCBhbGw/CisgICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW1hZ2VkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VvZmZzZXQsIGltYWdlbGVuZ3RoKSwgMTAyNCk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLW1vZGlmaWVkCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9EYXRhQnVmZmVyTGlzdGVuZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0RhdGFCdWZmZXJMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3OTMwNTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9EYXRhQnVmZmVyTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKiBDcmVhdGVkIG9uIDEzLjAzLjIwMDYKKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZTsKKworcHVibGljIGludGVyZmFjZSBEYXRhQnVmZmVyTGlzdGVuZXIgeworICAgIAorICAgIHZvaWQgZGF0YUNoYW5nZWQoKTsKKyAgICB2b2lkIGRhdGFUYWtlbigpOworICAgIHZvaWQgZGF0YVJlbGVhc2VkKCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0RlY29kaW5nSW1hZ2VTb3VyY2UuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0RlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NThkNjkxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvRGVjb2RpbmdJbWFnZVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworLyoKKyAqIENyZWF0ZWQgb24gMTguMDEuMjAwNQorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZUNvbnN1bWVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlUHJvZHVjZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoaXMgaXMgYW4gYWJzdHJhY3QgY2xhc3MgdGhhdCBlbmNhcHN1bGF0ZXMgYSBtYWluIHBhcnQgb2YgSW1hZ2VQcm9kdWNlciBmdW5jdGlvbmFsaXR5CisgKiBmb3IgdGhlIGltYWdlcyBiZWluZyBkZWNvZGVkIGJ5IHRoZSBuYXRpdmUgZGVjb2RlcnMsIGxpa2UgUE5HLCBKUEVHIGFuZCBHSUYuCisgKiBJdCBoZWxwcyB0byBpbnRlZ3JhdGUgaW1hZ2UgZGVjb2RlcnMgaW50byBwcm9kdWNlci9jb25zdW1lciBtb2RlbC4gSXQgcHJvdmlkZXMKKyAqIGZ1bmN0aW9uYWxpdHkgZm9yIHdvcmtpbmcgd2l0aCBzZXZlcmFsIGRlY29kZXIgaW5zdGFuY2VzIGFuZCBzZXZlcmFsIGltYWdlIGNvbnN1bWVycworICogc2ltdWx0YW5lb3VzbHkuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEZWNvZGluZ0ltYWdlU291cmNlIGltcGxlbWVudHMgSW1hZ2VQcm9kdWNlciB7CisgICAgTGlzdDxJbWFnZUNvbnN1bWVyPiBjb25zdW1lcnMgPSBuZXcgQXJyYXlMaXN0PEltYWdlQ29uc3VtZXI+KDUpOworICAgIExpc3Q8SW1hZ2VEZWNvZGVyPiBkZWNvZGVycyA9IG5ldyBBcnJheUxpc3Q8SW1hZ2VEZWNvZGVyPig1KTsKKyAgICBib29sZWFuIGxvYWRpbmc7CisKKyAgICBJbWFnZURlY29kZXIgZGVjb2RlcjsKKworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBib29sZWFuIGNoZWNrQ29ubmVjdGlvbigpOworCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCk7CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBpZiAoIWNoZWNrQ29ubmVjdGlvbigpKSB7IC8vIE5vIHBlcm1pc3Npb24gZm9yIHRoaXMgY29uc3VtZXIKKyAgICAgICAgICAgIGljLmltYWdlQ29tcGxldGUoSW1hZ2VDb25zdW1lci5JTUFHRUVSUk9SKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIEltYWdlQ29uc3VtZXIgY29ucyA9IGZpbmRDb25zdW1lcihjb25zdW1lcnMsIGljKTsKKworICAgICAgICBpZiAoY29ucyA9PSBudWxsKSB7IC8vIFRyeSB0byBsb29rIGluIHRoZSBkZWNvZGVycworICAgICAgICAgICAgSW1hZ2VEZWNvZGVyIGQgPSBudWxsOworCisgICAgICAgICAgICAvLyBDaGVjayBmb3IgYWxsIGV4aXN0aW5nIGRlY29kZXJzCisgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPEltYWdlRGVjb2Rlcj4gaSA9IGRlY29kZXJzLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgICAgIGQgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICBjb25zID0gZmluZENvbnN1bWVyKGQuY29uc3VtZXJzLCBpYyk7CisgICAgICAgICAgICAgICAgaWYgKGNvbnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29ucyA9PSBudWxsKSB7IC8vIE5vdCBmb3VuZCwgYWRkIHRoaXMgY29uc3VtZXIKKyAgICAgICAgICAgIGNvbnN1bWVycy5hZGQoaWMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgc3RvcHMgc2VuZGluZyBkYXRhIHRvIHRoZSBnaXZlbiBjb25zdW1lcgorICAgICAqIEBwYXJhbSBpYyAtIGNvbnN1bWVyCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFib3J0Q29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBpYy5pbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuSU1BR0VFUlJPUik7CisgICAgICAgIGNvbnN1bWVycy5yZW1vdmUoaWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHN0b3BzIHNlbmRpbmcgZGF0YSB0byB0aGUgbGlzdCBvZiBjb25zdW1lcnMuCisgICAgICogQHBhcmFtIGNvbnN1bWVyc0xpc3QgLSBsaXN0IG9mIGNvbnN1bWVycworICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhYm9ydEFsbENvbnN1bWVycyhMaXN0PEltYWdlQ29uc3VtZXI+IGNvbnN1bWVyc0xpc3QpIHsKKyAgICAgICAgZm9yIChJbWFnZUNvbnN1bWVyIGltYWdlQ29uc3VtZXIgOiBjb25zdW1lcnNMaXN0KSB7CisgICAgICAgICAgICBhYm9ydENvbnN1bWVyKGltYWdlQ29uc3VtZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZUNvbnN1bWVyKEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgSW1hZ2VEZWNvZGVyIGQgPSBudWxsOworCisgICAgICAgIC8vIFJlbW92ZSBpbiBhbGwgZXhpc3RpbmcgZGVjb2RlcnMKKyAgICAgICAgZm9yIChJdGVyYXRvcjxJbWFnZURlY29kZXI+IGkgPSBkZWNvZGVycy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgIGQgPSBpLm5leHQoKTsKKyAgICAgICAgICAgIHJlbW92ZUNvbnN1bWVyKGQuY29uc3VtZXJzLCBpYyk7CisgICAgICAgICAgICBpZiAoZC5jb25zdW1lcnMuc2l6ZSgpIDw9IDApIHsKKyAgICAgICAgICAgICAgICBkLnRlcm1pbmF0ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVtb3ZlIGluIHRoZSBjdXJyZW50IHF1ZXVlIG9mIGNvbnN1bWVycworICAgICAgICByZW1vdmVDb25zdW1lcihjb25zdW1lcnMsIGljKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGF0aWMgaW1wbGVtZW50YXRpb24gb2YgcmVtb3ZlQ29uc3VtZXIgbWV0aG9kCisgICAgICogQHBhcmFtIGNvbnN1bWVyc0xpc3QgLSBsaXN0IG9mIGNvbnN1bWVycworICAgICAqIEBwYXJhbSBpYyAtIGNvbnN1bWVyIHRvIGJlIHJlbW92ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlbW92ZUNvbnN1bWVyKExpc3Q8SW1hZ2VDb25zdW1lcj4gY29uc3VtZXJzTGlzdCwgSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBJbWFnZUNvbnN1bWVyIGNvbnMgPSBudWxsOworCisgICAgICAgIGZvciAoSXRlcmF0b3I8SW1hZ2VDb25zdW1lcj4gaSA9IGNvbnN1bWVyc0xpc3QuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICBjb25zID0gaS5uZXh0KCk7CisgICAgICAgICAgICBpZiAoY29ucy5lcXVhbHMoaWMpKSB7CisgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlcXVlc3RUb3BEb3duTGVmdFJpZ2h0UmVzZW5kKEltYWdlQ29uc3VtZXIgY29uc3VtZXIpIHsKKyAgICAgICAgLy8gRG8gbm90aGluZworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydFByb2R1Y3Rpb24oSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBpZiAoaWMgIT0gbnVsbCkgeworICAgICAgICAgICAgYWRkQ29uc3VtZXIoaWMpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFsb2FkaW5nICYmIGNvbnN1bWVycy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICBJbWFnZUxvYWRlci5hZGRJbWFnZVNvdXJjZSh0aGlzKTsKKyAgICAgICAgICAgIGxvYWRpbmcgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzQ29uc3VtZXIoSW1hZ2VDb25zdW1lciBpYykgeworICAgICAgICBJbWFnZURlY29kZXIgZCA9IG51bGw7CisKKyAgICAgICAgLy8gQ2hlY2sgZm9yIGFsbCBleGlzdGluZyBkZWNvZGVycworICAgICAgICBmb3IgKEl0ZXJhdG9yPEltYWdlRGVjb2Rlcj4gaSA9IGRlY29kZXJzLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgZCA9IGkubmV4dCgpOworICAgICAgICAgICAgaWYgKGZpbmRDb25zdW1lcihkLmNvbnN1bWVycywgaWMpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIGN1cnJlbnQgcXVldWUgb2YgY29uc3VtZXJzCisgICAgICAgIHJldHVybiBmaW5kQ29uc3VtZXIoY29uc3VtZXJzLCBpYykgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIGNvbnN1bWVyIGlzIGluIHRoZSBsaXN0IGFuZCByZXR1cm5zIGl0IGl0IGlzIHRoZXJlCisgICAgICogQHBhcmFtIGNvbnN1bWVyc0xpc3QgLSBsaXN0IG9mIGNvbnN1bWVycworICAgICAqIEBwYXJhbSBpYyAtIGNvbnN1bWVyCisgICAgICogQHJldHVybiBjb25zdW1lciBpZiBmb3VuZCwgbnVsbCBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJbWFnZUNvbnN1bWVyIGZpbmRDb25zdW1lcihMaXN0PEltYWdlQ29uc3VtZXI+IGNvbnN1bWVyc0xpc3QsIEltYWdlQ29uc3VtZXIgaWMpIHsKKyAgICAgICAgSW1hZ2VDb25zdW1lciByZXMgPSBudWxsOworCisgICAgICAgIGZvciAoSXRlcmF0b3I8SW1hZ2VDb25zdW1lcj4gaSA9IGNvbnN1bWVyc0xpc3QuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICByZXMgPSBpLm5leHQoKTsKKyAgICAgICAgICAgIGlmIChyZXMuZXF1YWxzKGljKSkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhpcyBtZXRob2QgdG8gZmluaXNoIGRlY29kaW5nIG9yIGxvY2sgdGhlIGxpc3Qgb2YgY29uc3VtZXJzCisgICAgICogZm9yIGEgcGFydGljdWxhciBkZWNvZGVyCisgICAgICogQHBhcmFtIGQgLSBkZWNvZGVyCisgICAgICovCisgICAgc3luY2hyb25pemVkIHZvaWQgbG9ja0RlY29kZXIoSW1hZ2VEZWNvZGVyIGQpIHsKKyAgICAgICAgaWYgKGQgPT0gZGVjb2RlcikgeworICAgICAgICAgICAgZGVjb2RlciA9IG51bGw7CisgICAgICAgICAgICBzdGFydFByb2R1Y3Rpb24obnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBmaW5kIGFuIGFwcHJvcHJpYXRlIGRlY29kZXIgZm9yIHRoZSBpbnB1dCBzdHJlYW0gYW5kIGFkZHMgaXQKKyAgICAgKiB0byB0aGUgbGlzdCBvZiBkZWNvZGVycworICAgICAqIEByZXR1cm4gY3JlYXRlZCBkZWNvZGVyCisgICAgICovCisgICAgcHJpdmF0ZSBJbWFnZURlY29kZXIgY3JlYXRlRGVjb2RlcigpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBnZXRJbnB1dFN0cmVhbSgpOworCisgICAgICAgIEltYWdlRGVjb2RlciBkZWNvZGVyOworCisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWNvZGVyID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRlY29kZXIgPSBJbWFnZURlY29kZXIuY3JlYXRlRGVjb2Rlcih0aGlzLCBpcyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVjb2RlciAhPSBudWxsKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBkZWNvZGVycy5hZGQoZGVjb2Rlcik7CisgICAgICAgICAgICAgICAgdGhpcy5kZWNvZGVyID0gZGVjb2RlcjsKKyAgICAgICAgICAgICAgICBsb2FkaW5nID0gZmFsc2U7CisgICAgICAgICAgICAgICAgY29uc3VtZXJzID0gbmV3IEFycmF5TGlzdDxJbWFnZUNvbnN1bWVyPig1KTsgLy8gUmVzZXQgcXVldWUKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGRlY29kZXI7CisgICAgICAgIH0KKyAgICAgICAgLy8gV2Ugd2VyZSBub3QgYWJsZSB0byBmaW5kIGFwcHJvcHJpYXRlIGRlY29kZXIKKyAgICAgICAgTGlzdDxJbWFnZUNvbnN1bWVyPiBjczsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBjcyA9IGNvbnN1bWVyczsKKyAgICAgICAgICAgIGNvbnN1bWVycyA9IG5ldyBBcnJheUxpc3Q8SW1hZ2VDb25zdW1lcj4oNSk7CisgICAgICAgICAgICBsb2FkaW5nID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgYWJvcnRBbGxDb25zdW1lcnMoY3MpOworCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3AgdGhlIGdpdmVuIGRlY29kZXIgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSBsaXN0CisgICAgICogQHBhcmFtIGRyIC0gZGVjb2RlcgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlRGVjb2RlcihJbWFnZURlY29kZXIgZHIpIHsKKyAgICAgICAgbG9ja0RlY29kZXIoZHIpOworICAgICAgICBkZWNvZGVycy5yZW1vdmUoZHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHNlcnZlcyBhcyBhbiBlbnRyeSBwb2ludC4KKyAgICAgKiBJdCBzdGFydHMgdGhlIGRlY29kZXIgYW5kIGxvYWRzIHRoZSBpbWFnZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGNvbnN1bWVycy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIGxvYWRpbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBJbWFnZURlY29kZXIgZCA9IGNyZWF0ZURlY29kZXIoKTsKKyAgICAgICAgaWYgKGQgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkZWNvZGVyLmRlY29kZUltYWdlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgcmVtb3ZlRGVjb2RlcihkKTsKKyAgICAgICAgICAgICAgICBhYm9ydEFsbENvbnN1bWVycyhkLmNvbnN1bWVycyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9GaWxlRGVjb2RpbmdJbWFnZVNvdXJjZS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvRmlsZURlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NGQ0NjY0Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvRmlsZURlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE9sZWcgVi4gS2hhc2NoYW5za3kKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworLyoKKyAqIENyZWF0ZWQgb24gMjAuMDEuMjAwNQorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIEZpbGVEZWNvZGluZ0ltYWdlU291cmNlIGV4dGVuZHMgRGVjb2RpbmdJbWFnZVNvdXJjZSB7CisgIFN0cmluZyBmaWxlbmFtZTsKKworICBwdWJsaWMgRmlsZURlY29kaW5nSW1hZ2VTb3VyY2UoU3RyaW5nIGZpbGUpIHsKKyAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgc2VjdXJpdHkuY2hlY2tSZWFkKGZpbGUpOworICAgIH0KKworICAgIGZpbGVuYW1lID0gZmlsZTsKKyAgfQorCisgIEBPdmVycmlkZQorcHJvdGVjdGVkIGJvb2xlYW4gY2hlY2tDb25uZWN0aW9uKCkgeworICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VjdXJpdHkuY2hlY2tSZWFkKGZpbGVuYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCitwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB7CisgICAgdHJ5IHsKKyAgICAgIC8vIEJFR0lOIGFuZHJvaWQtbW9kaWZpZWQKKyAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVuYW1lKSwgODE5Mik7CisgICAgICAvLyBFTkQgYW5kcm9pZC1tb2RpZmllZAorICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvR2lmRGVjb2Rlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvR2lmRGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlY2IxNWIKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9HaWZEZWNvZGVyLmphdmEKQEAgLTAsMCArMSw2OTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisvKgorKiBDcmVhdGVkIG9uIDI3LjAxLjIwMDUKKyovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlQ29uc3VtZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW5kZXhDb2xvck1vZGVsOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworcHVibGljIGNsYXNzIEdpZkRlY29kZXIgZXh0ZW5kcyBJbWFnZURlY29kZXIgeworICAgIC8vIGluaXRpYWxpemVzIHByb3BlciBmaWVsZCBJRHMKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBpbml0SURzKCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBTeXN0ZW0ubG9hZExpYnJhcnkoImdsIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaW5pdElEcygpOworICAgIH0KKworICAgIC8vIEltYWdlQ29uc3VtZXIgaGludHM6IGNvbW1vbgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBiYXNlSGludHMgPQorICAgICAgICAgICAgSW1hZ2VDb25zdW1lci5TSU5HTEVQQVNTIHwgSW1hZ2VDb25zdW1lci5DT01QTEVURVNDQU5MSU5FUyB8CisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLlNJTkdMRUZSQU1FOworICAgIC8vIEltYWdlQ29uc3VtZXIgaGludHM6IGludGVybGFjZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgaW50ZXJsYWNlZEhpbnRzID0KKyAgICAgICAgICAgIGJhc2VIaW50cyB8IEltYWdlQ29uc3VtZXIuUkFORE9NUElYRUxPUkRFUjsKKworICAgIC8vIEltcG9zc2libGUgY29sb3IgdmFsdWUgLSBubyB0cmFuc2x1Y2VudCBwaXhlbHMgYWxsb3dlZAorICAgIHN0YXRpYyBmaW5hbCBpbnQgSU1QT1NTSUJMRV9WQUxVRSA9IDB4MEZGRkZGRkY7CisKKyAgICAvLyBJL08gYnVmZmVyCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9TSVpFID0gMTAyNDsKKyAgICBwcml2YXRlIGJ5dGUgYnVmZmVyW10gPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisKKyAgICBHaWZEYXRhU3RyZWFtIGdpZkRhdGFTdHJlYW0gPSBuZXcgR2lmRGF0YVN0cmVhbSgpOworICAgIEdpZkdyYXBoaWNCbG9jayBjdXJyQmxvY2s7CisKKyAgICAvLyBQb2ludGVyIHRvIG5hdGl2ZSBzdHJ1Y3R1cmUgd2hpY2ggc3RvcmUgZGVjb2Rpbmcgc3RhdGUKKyAgICAvLyBiZXR3ZWVuIHN1YnNlcXVlbnQgZGVjb2RpbmcvSU8tc3VzcGVuc2lvbiBjeWNsZXMKKyAgICBwcml2YXRlIGxvbmcgaE5hdGl2ZURlY29kZXI7IC8vIE5VTEwgaW5pdGlhbGx5CisKKyAgICAvLyBOdW1iZXIgb2YgYnl0ZXMgZWF0ZW4gYnkgdGhlIG5hdGl2ZSBkZWNvZGVyCisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNDb25zdW1lZDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjb25zdW1lcnNQcmVwYXJlZDsKKyAgICBwcml2YXRlIEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4gcHJvcGVydGllcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+KCk7CisKKyAgICAvLyBDb3VsZCBiZSBzZXQgdXAgYnkgamF2YSBjb2RlIG9yIG5hdGl2ZSBtZXRob2Qgd2hlbgorICAgIC8vIHRyYW5zcGFyZW50IHBpeGVsIGluZGV4IGNoYW5nZXMgb3IgbG9jYWwgY29sb3IgdGFibGUgZW5jb3VudGVyZWQKKyAgICBwcml2YXRlIGJvb2xlYW4gZm9yY2VSR0I7CisKKyAgICBwcml2YXRlIGJ5dGUgc2NyZWVuQnVmZmVyW107CisgICAgcHJpdmF0ZSBpbnQgc2NyZWVuUkdCQnVmZmVyW107CisKKyAgICBwdWJsaWMgR2lmRGVjb2RlcihEZWNvZGluZ0ltYWdlU291cmNlIHNyYywgSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgc3VwZXIoc3JjLCBpcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludFtdIHRvUkdCKGJ5dGUgaW1hZ2VEYXRhW10sIGJ5dGUgY29sb3JtYXBbXSwgaW50IHRyYW5zcGFyZW50Q29sb3IpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgcmVsZWFzZU5hdGl2ZURlY29kZXIobG9uZyBoRGVjb2Rlcik7CisKKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgZGVjb2RlKAorICAgICAgICAgICAgYnl0ZSBpbnB1dFtdLAorICAgICAgICAgICAgaW50IGJ5dGVzSW5CdWZmZXIsCisgICAgICAgICAgICBsb25nIGhEZWNvZGVyLAorICAgICAgICAgICAgR2lmRGF0YVN0cmVhbSBkYXRhU3RyZWFtLAorICAgICAgICAgICAgR2lmR3JhcGhpY0Jsb2NrIGN1cnJCbG9jaworICAgICAgICAgICAgKTsKKworICAgIHByaXZhdGUgaW50W10gZ2V0U2NyZWVuUkdCQnVmZmVyKCkgeworICAgICAgICBpZiAoc2NyZWVuUkdCQnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChzY3JlZW5CdWZmZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGludCB0cmFuc3BhcmVudENvbG9yID0KKyAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5nbG9iYWxDb2xvclRhYmxlLmNtLmdldFRyYW5zcGFyZW50UGl4ZWwoKTsKKyAgICAgICAgICAgICAgICB0cmFuc3BhcmVudENvbG9yID0gdHJhbnNwYXJlbnRDb2xvciA+IDAgPyB0cmFuc3BhcmVudENvbG9yIDogSU1QT1NTSUJMRV9WQUxVRTsKKyAgICAgICAgICAgICAgICBzY3JlZW5SR0JCdWZmZXIgPQorICAgICAgICAgICAgICAgICAgICAgICAgdG9SR0IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlbkJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuLmdsb2JhbENvbG9yVGFibGUuY29sb3JzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVudENvbG9yCisgICAgICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5sb2dpY2FsU2NyZWVuSGVpZ2h0ICoKKyAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5sb2dpY2FsU2NyZWVuV2lkdGg7CisgICAgICAgICAgICAgICAgc2NyZWVuUkdCQnVmZmVyID0gbmV3IGludFtzaXplXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzY3JlZW5SR0JCdWZmZXI7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVDb25zdW1lcnMoKSB7CisgICAgICAgIEdpZkxvZ2ljYWxTY3JlZW4gZ2xzID0gZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuOworICAgICAgICBzZXREaW1lbnNpb25zKGdscy5sb2dpY2FsU2NyZWVuV2lkdGgsCisgICAgICAgICAgICAgICAgZ2xzLmxvZ2ljYWxTY3JlZW5IZWlnaHQpOworICAgICAgICBzZXRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpOworCisgICAgICAgIGN1cnJCbG9jayA9IGdpZkRhdGFTdHJlYW0uZ3JhcGhpY0Jsb2Nrcy5nZXQoMCk7CisgICAgICAgIGlmIChmb3JjZVJHQikgeworICAgICAgICAgICAgc2V0Q29sb3JNb2RlbChDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXRDb2xvck1vZGVsKGdscy5nbG9iYWxDb2xvclRhYmxlLmdldENvbG9yTW9kZWwoY3VyckJsb2NrLnRyYW5zcGFyZW50Q29sb3IpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpbGwgc2NyZWVuIGJ1ZmZlciB3aXRoIHRoZSBiYWNrZ3JvdW5kIG9yIHRyYW5zcGFyZW50IGNvbG9yCisgICAgICAgIGlmIChmb3JjZVJHQikgeworICAgICAgICAgICAgaW50IGZpbGxDb2xvciA9IDB4RkYwMDAwMDA7CisgICAgICAgICAgICBpZiAoZ2xzLmJhY2tncm91bmRDb2xvciAhPSBJTVBPU1NJQkxFX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgZmlsbENvbG9yID0gZ2xzLmJhY2tncm91bmRDb2xvcjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZ2V0U2NyZWVuUkdCQnVmZmVyKCksIGZpbGxDb2xvcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgZmlsbENvbG9yID0gMDsKKworICAgICAgICAgICAgaWYgKGdscy5iYWNrZ3JvdW5kQ29sb3IgIT0gSU1QT1NTSUJMRV9WQUxVRSkgeworICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IGdscy5iYWNrZ3JvdW5kQ29sb3I7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IGdscy5nbG9iYWxDb2xvclRhYmxlLmNtLmdldFRyYW5zcGFyZW50UGl4ZWwoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2NyZWVuQnVmZmVyID0gbmV3IGJ5dGVbZ2xzLmxvZ2ljYWxTY3JlZW5IZWlnaHQqZ2xzLmxvZ2ljYWxTY3JlZW5XaWR0aF07CisgICAgICAgICAgICBBcnJheXMuZmlsbChzY3JlZW5CdWZmZXIsIChieXRlKSBmaWxsQ29sb3IpOworICAgICAgICB9CisKKyAgICAgICAgc2V0SGludHMoaW50ZXJsYWNlZEhpbnRzKTsgLy8gWFhYIC0gYWx3YXlzIHJhbmRvbSBwaXhlbCBvcmRlcgorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRlY29kZUltYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBieXRlc1JlYWQgPSAwOworICAgICAgICAgICAgaW50IG5lZWRCeXRlcywgb2Zmc2V0LCBieXRlc0luQnVmZmVyID0gMDsKKyAgICAgICAgICAgIGJvb2xlYW4gZW9zUmVhY2hlZCA9IGZhbHNlOworICAgICAgICAgICAgR2lmR3JhcGhpY0Jsb2NrIGJsb2NrVG9EaXNwb3NlID0gbnVsbDsKKworICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBncmFwaGljIGJsb2NrCisgICAgICAgICAgICBpZiAoY3VyckJsb2NrID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjdXJyQmxvY2sgPSBuZXcgR2lmR3JhcGhpY0Jsb2NrKCk7CisgICAgICAgICAgICAgICAgZ2lmRGF0YVN0cmVhbS5ncmFwaGljQmxvY2tzLmFkZChjdXJyQmxvY2spOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBSZWFkIGZyb20gdGhlIGlucHV0IHN0cmVhbQorICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIG5lZWRCeXRlcyA9IEJVRkZFUl9TSVpFIC0gYnl0ZXNJbkJ1ZmZlcjsKKyAgICAgICAgICAgICAgICBvZmZzZXQgPSBieXRlc0luQnVmZmVyOworCisgICAgICAgICAgICAgICAgYnl0ZXNSZWFkID0gaW5wdXRTdHJlYW0ucmVhZChidWZmZXIsIG9mZnNldCwgbmVlZEJ5dGVzKTsKKworICAgICAgICAgICAgICAgIGlmIChieXRlc1JlYWQgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGVvc1JlYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBieXRlc1JlYWQgPSAwOworICAgICAgICAgICAgICAgIH0gLy8gRG9uJ3QgYnJlYWssIG1heWJlIHNvbWV0aGluZyBsZWZ0IGluIGJ1ZmZlcgorCisgICAgICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvbiBob3cgbXVjaCBieXRlcyBsZWZ0IGluIGJ1ZmZlcgorICAgICAgICAgICAgICAgIGJ5dGVzSW5CdWZmZXIgKz0gYnl0ZXNSZWFkOworCisgICAgICAgICAgICAgICAgLy8gSGVyZSB3ZSBwYXNzIG51bWJlciBvZiBuZXcgYnl0ZXMgcmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gKGJ5dGVzUmVhZCkKKyAgICAgICAgICAgICAgICAvLyBzaW5jZSBuYXRpdmUgZGVjb2RlciB1c2VzIGphdmEgYnVmZmVyIGFuZCBkb2Vzbid0IGhhdmUgaXRzIG93bgorICAgICAgICAgICAgICAgIC8vIGJ1ZmZlci4gU28gaXQgYWRkcyB0aGlzIG51bWJlciB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIGxlZnQKKyAgICAgICAgICAgICAgICAvLyBpbiBidWZmZXIgZnJvbSB0aGUgcHJldmlvdXMgY2FsbC4KKyAgICAgICAgICAgICAgICBpbnQgbnVtTGluZXMgPSBkZWNvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICBoTmF0aXZlRGVjb2RlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICBjdXJyQmxvY2spOworCisgICAgICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvbiBob3cgbXVjaCBieXRlcyBsZWZ0IGluIGJ1ZmZlcgorICAgICAgICAgICAgICAgIGJ5dGVzSW5CdWZmZXIgLT0gYnl0ZXNDb25zdW1lZDsKKworICAgICAgICAgICAgICAgIGlmICgKKyAgICAgICAgICAgICAgICAgICAgICAgICFjb25zdW1lcnNQcmVwYXJlZCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuLmNvbXBsZXRlZCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuLmdsb2JhbENvbG9yVGFibGUuY29tcGxldGVkICYmCisgICAgICAgICAgICAgICAgICAgICAgICAoY3VyckJsb2NrLmltYWdlRGF0YSAhPSBudWxsIHx8IC8vIEhhdmUgdHJhbnNwYXJlbnQgcGl4ZWwgZmlsbGVkCisgICAgICAgICAgICAgICAgICAgICAgICBjdXJyQmxvY2sucmdiSW1hZ2VEYXRhICE9IG51bGwpCisgICAgICAgICAgICAgICAgKSB7CisgICAgICAgICAgICAgICAgICAgIHByZXBhcmVDb25zdW1lcnMoKTsKKyAgICAgICAgICAgICAgICAgICAgY29uc3VtZXJzUHJlcGFyZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChieXRlc0NvbnN1bWVkIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gRXJyb3IgZXhpdAorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChjdXJyQmxvY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAobnVtTGluZXMgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGlzcG9zZSBwcmV2aW91cyBpbWFnZSBvbmx5IGJlZm9yZSBzaG93aW5nIG5leHQKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1RvRGlzcG9zZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tUb0Rpc3Bvc2UuZGlzcG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrVG9EaXNwb3NlID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgY3VyckJsb2NrLnNlbmROZXdEYXRhKHRoaXMsIG51bUxpbmVzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyQmxvY2suY29tcGxldGVkICYmIGhOYXRpdmVEZWNvZGVyICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrVG9EaXNwb3NlID0gY3VyckJsb2NrOyAvLyBEaXNwb3NlIG9ubHkgYmVmb3JlIHNob3dpbmcgbmV3IHBpeGVscworICAgICAgICAgICAgICAgICAgICAgICAgY3VyckJsb2NrID0gbmV3IEdpZkdyYXBoaWNCbG9jaygpOworICAgICAgICAgICAgICAgICAgICAgICAgZ2lmRGF0YVN0cmVhbS5ncmFwaGljQmxvY2tzLmFkZChjdXJyQmxvY2spOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGhOYXRpdmVEZWNvZGVyID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGVvc1JlYWNoZWQgJiYgbnVtTGluZXMgPT0gMCkgeyAvLyBNYXliZSBpbWFnZSBpcyB0cnVuY2F0ZWQuLi4KKyAgICAgICAgICAgICAgICAgICAgcmVsZWFzZU5hdGl2ZURlY29kZXIoaE5hdGl2ZURlY29kZXIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjbG9zZVN0cmVhbSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSGVyZSBhbGwgYW5pbWF0aW9uIGdvZXMKKyAgICAgICAgLy8gUmVwZWF0IGltYWdlIGxvb3BDb3VudC0xIHRpbWVzIG9yIGluZmluaXRlbHkgaWYgbG9vcENvdW50ID0gMAorICAgICAgICBpZiAoZ2lmRGF0YVN0cmVhbS5sb29wQ291bnQgIT0gMSkgeworICAgICAgICAgICAgaWYgKGN1cnJCbG9jay5jb21wbGV0ZWQgPT0gZmFsc2UpIHsKKyAgICAgICAgICAgICAgICBnaWZEYXRhU3RyZWFtLmdyYXBoaWNCbG9ja3MucmVtb3ZlKGN1cnJCbG9jayk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBudW1GcmFtZXMgPSBnaWZEYXRhU3RyZWFtLmdyYXBoaWNCbG9ja3Muc2l6ZSgpOworICAgICAgICAgICAgLy8gQXQgZmlyc3QgbGFzdCBibG9jayB3aWxsIGJlIGRpc3Bvc2VkCisgICAgICAgICAgICBHaWZHcmFwaGljQmxvY2sgZ2IgPQorICAgICAgICAgICAgICAgICAgICBnaWZEYXRhU3RyZWFtLmdyYXBoaWNCbG9ja3MuZ2V0KG51bUZyYW1lcy0xKTsKKworICAgICAgICAgICAgSW1hZ2VMb2FkZXIuYmVnaW5BbmltYXRpb24oKTsKKworICAgICAgICAgICAgd2hpbGUgKGdpZkRhdGFTdHJlYW0ubG9vcENvdW50ICE9IDEpIHsKKyAgICAgICAgICAgICAgICBpZiAoZ2lmRGF0YVN0cmVhbS5sb29wQ291bnQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBnaWZEYXRhU3RyZWFtLmxvb3BDb3VudC0tOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFNob3cgYWxsIGZyYW1lcworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxudW1GcmFtZXM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBnYi5kaXNwb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIGdiID0gZ2lmRGF0YVN0cmVhbS5ncmFwaGljQmxvY2tzLmdldChpKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBTaG93IG9uZSBmcmFtZQorICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2VSR0IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldFBpeGVscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VMZWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYi5pbWFnZVRvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VIZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYi5nZXRSZ2JJbWFnZURhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VXaWR0aAorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldFBpeGVscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VMZWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYi5pbWFnZVRvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VIZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdiLmltYWdlRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2IuaW1hZ2VXaWR0aAorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEltYWdlTG9hZGVyLmVuZEFuaW1hdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLlNUQVRJQ0lNQUdFRE9ORSk7CisgICAgfQorCisgICAgdm9pZCBzZXRDb21tZW50KFN0cmluZyBuZXdDb21tZW50KSB7CisgICAgICAgIE9iamVjdCBjdXJyQ29tbWVudCA9IHByb3BlcnRpZXMuZ2V0KCJjb21tZW50Iik7IC8vJE5PTi1OTFMtMSQKKworICAgICAgICBpZiAoY3VyckNvbW1lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcGVydGllcy5wdXQoImNvbW1lbnQiLCBuZXdDb21tZW50KTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJvcGVydGllcy5wdXQoImNvbW1lbnQiLCAoU3RyaW5nKSBjdXJyQ29tbWVudCArICJcbiIgKyBuZXdDb21tZW50KTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgIH0KKworICAgICAgICBzZXRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpOworICAgIH0KKworICAgIGNsYXNzIEdpZkRhdGFTdHJlYW0geworICAgICAgICAvLyAgSW5kaWNhdGVzIHRoYXQgcmVhZGluZyBvZiB0aGUgd2hvbGUgZGF0YSBzdHJlYW0gYWNjb21wbGlzaGVkCisgICAgICAgIGJvb2xlYW4gY29tcGxldGVkID0gZmFsc2U7CisKKyAgICAgICAgLy8gQWRkZWQgdG8gc3VwcG9ydCBOZXRzY2FwZSAyLjAgYXBwbGljYXRpb24KKyAgICAgICAgLy8gZXh0ZW5zaW9uIGJsb2NrLgorICAgICAgICBpbnQgbG9vcENvdW50ID0gMTsKKworICAgICAgICBHaWZMb2dpY2FsU2NyZWVuIGxvZ2ljYWxTY3JlZW4gPSBuZXcgR2lmTG9naWNhbFNjcmVlbigpOworICAgICAgICBMaXN0PEdpZkdyYXBoaWNCbG9jaz4gZ3JhcGhpY0Jsb2NrcyA9IG5ldyBBcnJheUxpc3Q8R2lmR3JhcGhpY0Jsb2NrPigxMCk7IC8vIE9mIEdpZkdyYXBoaWNCbG9ja3MKKworICAgICAgICAvLyBDb21tZW50cyBmcm9tIHRoZSBpbWFnZQorICAgICAgICBTdHJpbmcgY29tbWVudHNbXTsKKyAgICB9CisKKyAgICBjbGFzcyBHaWZMb2dpY2FsU2NyZWVuIHsKKyAgICAgICAgLy8gIEluZGljYXRlcyB0aGF0IHJlYWRpbmcgb2YgdGhpcyBibG9jayBhY2NvbXBsaXNoZWQKKyAgICAgICAgYm9vbGVhbiBjb21wbGV0ZWQgPSBmYWxzZTsKKworICAgICAgICBpbnQgbG9naWNhbFNjcmVlbldpZHRoOworICAgICAgICBpbnQgbG9naWNhbFNjcmVlbkhlaWdodDsKKworICAgICAgICBpbnQgYmFja2dyb3VuZENvbG9yID0gSU1QT1NTSUJMRV9WQUxVRTsKKworICAgICAgICBHaWZDb2xvclRhYmxlIGdsb2JhbENvbG9yVGFibGUgPSBuZXcgR2lmQ29sb3JUYWJsZSgpOworICAgIH0KKworICAgIGNsYXNzIEdpZkdyYXBoaWNCbG9jayB7CisgICAgICAgIC8vICBJbmRpY2F0ZXMgdGhhdCByZWFkaW5nIG9mIHRoaXMgYmxvY2sgYWNjb21wbGlzaGVkCisgICAgICAgIGJvb2xlYW4gY29tcGxldGVkID0gZmFsc2U7CisKKyAgICAgICAgZmluYWwgc3RhdGljIGludCBESVNQT1NBTF9OT05FID0gMDsKKyAgICAgICAgZmluYWwgc3RhdGljIGludCBESVNQT1NBTF9OT0RJU1BPU0FMID0gMTsKKyAgICAgICAgZmluYWwgc3RhdGljIGludCBESVNQT1NBTF9CQUNLR1JPVU5EID0gMjsKKyAgICAgICAgZmluYWwgc3RhdGljIGludCBESVNQT1NBTF9SRVNUT1JFID0gMzsKKworICAgICAgICBpbnQgZGlzcG9zYWxNZXRob2Q7CisgICAgICAgIGludCBkZWxheVRpbWU7IC8vIE11bHRpcGxpZWQgYnkgMTAgYWxyZWFkeQorICAgICAgICBpbnQgdHJhbnNwYXJlbnRDb2xvciA9IElNUE9TU0lCTEVfVkFMVUU7CisKKyAgICAgICAgaW50IGltYWdlTGVmdDsKKyAgICAgICAgaW50IGltYWdlVG9wOworICAgICAgICBpbnQgaW1hZ2VXaWR0aDsKKyAgICAgICAgaW50IGltYWdlSGVpZ2h0OworCisgICAgICAgIC8vIEF1eGlsbGlhcnkgdmFyaWFibGVzIHRvIG1pbmltaXplIGNvbXB1dGF0aW9ucworICAgICAgICBpbnQgaW1hZ2VSaWdodDsKKyAgICAgICAgaW50IGltYWdlQm90dG9tOworCisgICAgICAgIGJvb2xlYW4gaW50ZXJsYWNlOworCisgICAgICAgIC8vIERvbid0IG5lZWQgbG9jYWwgY29sb3IgdGFibGUgLSBpZiBpdCBpcyBzcGVjaWZpZWQKKyAgICAgICAgLy8gaW1hZ2UgZGF0YSBhcmUgY29udmVydGVkIHRvIFJHQiBpbiB0aGUgbmF0aXZlIGNvZGUKKworICAgICAgICBieXRlIGltYWdlRGF0YVtdID0gbnVsbDsKKyAgICAgICAgaW50IHJnYkltYWdlRGF0YVtdID0gbnVsbDsKKworICAgICAgICBwcml2YXRlIGludCBjdXJyWSA9IDA7IC8vIEN1cnJlbnQgb3V0cHV0IHNjYW5saW5lCisKKyAgICAgICAgaW50W10gZ2V0UmdiSW1hZ2VEYXRhKCkgeworICAgICAgICAgICAgaWYgKHJnYkltYWdlRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmdiSW1hZ2VEYXRhID0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRvUkdCKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZURhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5nbG9iYWxDb2xvclRhYmxlLmNvbG9ycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRDb2xvcgorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRDb2xvciAhPSBJTVBPU1NJQkxFX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgICAgIHRyYW5zcGFyZW50Q29sb3IgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5nbG9iYWxDb2xvclRhYmxlLmNtLmdldFJHQih0cmFuc3BhcmVudENvbG9yKTsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRDb2xvciAmPSAweDAwRkZGRkZGOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZ2JJbWFnZURhdGE7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgcmVwbGFjZVRyYW5zcGFyZW50UGl4ZWxzKGludCBudW1MaW5lcykgeworICAgICAgICAgICAgTGlzdDxHaWZHcmFwaGljQmxvY2s+IGdyYXBoaWNCbG9ja3MgPSBnaWZEYXRhU3RyZWFtLmdyYXBoaWNCbG9ja3M7CisgICAgICAgICAgICBpbnQgcHJldkJsb2NrSW5kZXggPSBncmFwaGljQmxvY2tzLmluZGV4T2YodGhpcykgLSAxOworCisgICAgICAgICAgICBpZiAocHJldkJsb2NrSW5kZXggPj0gMCkgeworICAgICAgICAgICAgICAgIGludCBtYXhZID0gY3VyclkgKyBudW1MaW5lcyArIGltYWdlVG9wOworICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSBjdXJyWSAqIGltYWdlV2lkdGg7CisKKyAgICAgICAgICAgICAgICAvLyBVcGRhdGUgcmlnaHQgYW5kIGJvdHRvbSBjb29yZGluYXRlcworICAgICAgICAgICAgICAgIGltYWdlUmlnaHQgPSBpbWFnZUxlZnQgKyBpbWFnZVdpZHRoOworICAgICAgICAgICAgICAgIGltYWdlQm90dG9tID0gaW1hZ2VUb3AgKyBpbWFnZUhlaWdodDsKKworICAgICAgICAgICAgICAgIGludCBnbG9iYWxXaWR0aCA9IGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5sb2dpY2FsU2NyZWVuV2lkdGg7CisgICAgICAgICAgICAgICAgaW50IHBpeGVsVmFsdWUsIGltYWdlT2Zmc2V0OworICAgICAgICAgICAgICAgIGludCByZ2JEYXRhW10gPSBmb3JjZVJHQiA/IGdldFJnYkltYWdlRGF0YSgpIDogbnVsbDsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHkgPSBjdXJyWSArIGltYWdlVG9wOyB5IDwgbWF4WTsgeSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGltYWdlT2Zmc2V0ID0gZ2xvYmFsV2lkdGggKiB5ICsgaW1hZ2VMZWZ0OworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCB4ID0gaW1hZ2VMZWZ0OyB4IDwgaW1hZ2VSaWdodDsgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbFZhbHVlID0gZm9yY2VSR0IgPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZ2JEYXRhW29mZnNldF0gOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZURhdGFbb2Zmc2V0XSAmIDB4RkY7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGl4ZWxWYWx1ZSA9PSB0cmFuc3BhcmVudENvbG9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlUkdCKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsVmFsdWUgPSBnZXRTY3JlZW5SR0JCdWZmZXIoKSBbaW1hZ2VPZmZzZXRdOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZ2JEYXRhW29mZnNldF0gPSBwaXhlbFZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsVmFsdWUgPSBzY3JlZW5CdWZmZXIgW2ltYWdlT2Zmc2V0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VEYXRhW29mZnNldF0gPSAoYnl0ZSkgcGl4ZWxWYWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlT2Zmc2V0Kys7CisgICAgICAgICAgICAgICAgICAgIH0gLy8gZm9yCisgICAgICAgICAgICAgICAgfSAvLyBmb3IKKworICAgICAgICAgICAgfSAvLyBpZiAocHJldkJsb2NrSW5kZXggPj0gMCkKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNlbmROZXdEYXRhKEdpZkRlY29kZXIgZGVjb2RlciwgaW50IG51bUxpbmVzKSB7CisgICAgICAgICAgICAvLyBHZXQgdmFsdWVzIGZvciB0cmFuc3BhcmVudCBwaXhlbHMKKyAgICAgICAgICAgIC8vIGZyb20gdGhlIHBlcmV2aW91cyBmcmFtZXMKKyAgICAgICAgICAgIGlmICh0cmFuc3BhcmVudENvbG9yICE9IElNUE9TU0lCTEVfVkFMVUUpIHsKKyAgICAgICAgICAgICAgICByZXBsYWNlVHJhbnNwYXJlbnRQaXhlbHMobnVtTGluZXMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZm9yY2VSR0IpIHsKKyAgICAgICAgICAgICAgICBkZWNvZGVyLnNldFBpeGVscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlTGVmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlVG9wICsgY3VyclksCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgbnVtTGluZXMsCisgICAgICAgICAgICAgICAgICAgICAgICBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGdldFJnYkltYWdlRGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgY3VyclkqaW1hZ2VXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgKKyAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWNvZGVyLnNldFBpeGVscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlTGVmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlVG9wICsgY3VyclksCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgbnVtTGluZXMsCisgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VEYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgY3VyclkqaW1hZ2VXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgKKyAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjdXJyWSArPSBudW1MaW5lczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CisgICAgICAgICAgICBpbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuU0lOR0xFRlJBTUVET05FKTsKKworICAgICAgICAgICAgLy8gU2hvdyBjdXJyZW50IGZyYW1lIHVudGlsIGRlbGF5SW50ZXJ2YWwgd2lsbCBub3QgZWxhcHNlCisgICAgICAgICAgICBpZiAoZGVsYXlUaW1lID4gMCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcChkZWxheVRpbWUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOyAvLyBBbGxvdyBjb25zdW1lcnMgdG8gY29uc3VtZSBkYXRhCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIERvbid0IGRpc3Bvc2UgaWYgaW1hZ2UgaXMgb3V0c2lkZSBvZiB0aGUgdmlzaWJsZSBhcmVhCisgICAgICAgICAgICBpZiAoaW1hZ2VMZWZ0ID4gZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuLmxvZ2ljYWxTY3JlZW5XaWR0aCB8fAorICAgICAgICAgICAgICAgICAgICBpbWFnZVRvcCA+IGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5sb2dpY2FsU2NyZWVuSGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgZGlzcG9zYWxNZXRob2QgPSBESVNQT1NBTF9OT05FOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzd2l0Y2goZGlzcG9zYWxNZXRob2QpIHsKKyAgICAgICAgICAgICAgICBjYXNlIERJU1BPU0FMX0JBQ0tHUk9VTkQ6IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlUkdCKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBnZXRSZ2JJbWFnZURhdGEoKTsgLy8gRW5zdXJlIHRoYXQgdHJhbnNwYXJlbnRDb2xvciBpcyBSR0IsIG5vdCBpbmRleAorCisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGF0YVtdID0gbmV3IGludFtpbWFnZVdpZHRoKmltYWdlSGVpZ2h0XTsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGF0aWJpbGl0eTogRmlsbCB3aXRoIHRyYW5zcGFyZW50IGNvbG9yIGlmIHdlIGhhdmUgb25lCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRDb2xvciAhPSBJTVBPU1NJQkxFX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRDb2xvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpZkRhdGFTdHJlYW0ubG9naWNhbFNjcmVlbi5iYWNrZ3JvdW5kQ29sb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlTGVmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VUb3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlSGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aAorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFRvU2NyZWVuQnVmZmVyKGRhdGEpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZSBkYXRhW10gPSBuZXcgYnl0ZVtpbWFnZVdpZHRoKmltYWdlSGVpZ2h0XTsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGF0aWJpbGl0eTogRmlsbCB3aXRoIHRyYW5zcGFyZW50IGNvbG9yIGlmIHdlIGhhdmUgb25lCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRDb2xvciAhPSBJTVBPU1NJQkxFX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIHRyYW5zcGFyZW50Q29sb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuZmlsbCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgZ2lmRGF0YVN0cmVhbS5sb2dpY2FsU2NyZWVuLmJhY2tncm91bmRDb2xvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldFBpeGVscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VMZWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVRvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VIZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgKKyAgICAgICAgICAgICAgICAgICAgICAgICk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRUb1NjcmVlbkJ1ZmZlcihkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSBESVNQT1NBTF9SRVNUT1JFOiB7CisgICAgICAgICAgICAgICAgICAgIHNjcmVlbkJ1ZmZlclRvU2NyZWVuKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIERJU1BPU0FMX05PTkU6CisgICAgICAgICAgICAgICAgY2FzZSBESVNQT1NBTF9OT0RJU1BPU0FMOgorICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ29weSB0cmFuc21pdHRlZCBkYXRhIHRvIHRoZSBzY3JlZW4gYnVmZmVyCisgICAgICAgICAgICAgICAgICAgIE9iamVjdCBkYXRhID0gZm9yY2VSR0IgPyAoT2JqZWN0KSBnZXRSZ2JJbWFnZURhdGEoKSA6IGltYWdlRGF0YTsKKyAgICAgICAgICAgICAgICAgICAgc2VuZFRvU2NyZWVuQnVmZmVyKGRhdGEpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgc2VuZFRvU2NyZWVuQnVmZmVyKE9iamVjdCBkYXRhKSB7CisgICAgICAgICAgICBpbnQgZGF0YUludFtdOworICAgICAgICAgICAgYnl0ZSBkYXRhQnl0ZVtdOworCisgICAgICAgICAgICBpbnQgd2lkdGggPSBnaWZEYXRhU3RyZWFtLmxvZ2ljYWxTY3JlZW4ubG9naWNhbFNjcmVlbldpZHRoOworCisKKyAgICAgICAgICAgIGlmIChmb3JjZVJHQikgeworICAgICAgICAgICAgICAgIGRhdGFJbnQgPSAoaW50W10pIGRhdGE7CisKKyAgICAgICAgICAgICAgICBpZiAoaW1hZ2VXaWR0aCA9PSB3aWR0aCkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGFJbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRTY3JlZW5SR0JCdWZmZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUxlZnQgKyBpbWFnZVRvcCp3aWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW50Lmxlbmd0aAorICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIEVhY2ggc2NhbmxpbmUKKyAgICAgICAgICAgICAgICAgICAgY29weVNjYW5saW5lcyhkYXRhSW50LCBnZXRTY3JlZW5SR0JCdWZmZXIoKSwgd2lkdGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGF0YUJ5dGUgPSAoYnl0ZVtdKSBkYXRhOworCisgICAgICAgICAgICAgICAgaWYgKGltYWdlV2lkdGggPT0gd2lkdGgpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhQnl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlbkJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUxlZnQgKyBpbWFnZVRvcCp3aWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhQnl0ZS5sZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBFYWNoIHNjYW5saW5lCisgICAgICAgICAgICAgICAgICAgIGNvcHlTY2FubGluZXMoZGF0YUJ5dGUsIHNjcmVlbkJ1ZmZlciwgd2lkdGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSAvLyBzZW5kVG9TY3JlZW5CdWZmZXIKKworICAgICAgICBwcml2YXRlIHZvaWQgY29weVNjYW5saW5lcyhPYmplY3Qgc3JjLCBPYmplY3QgZHN0LCBpbnQgd2lkdGgpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxpbWFnZUhlaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICBpKmltYWdlV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICBkc3QsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUxlZnQgKyBpKndpZHRoICsgaW1hZ2VUb3Aqd2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0gLy8gZm9yCisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgc2NyZWVuQnVmZmVyVG9TY3JlZW4oKSB7CisgICAgICAgICAgICBpbnQgd2lkdGggPSBnaWZEYXRhU3RyZWFtLmxvZ2ljYWxTY3JlZW4ubG9naWNhbFNjcmVlbldpZHRoOworCisgICAgICAgICAgICBPYmplY3QgZHN0ID0gZm9yY2VSR0IgPworICAgICAgICAgICAgICAgICAgICAoT2JqZWN0KSBuZXcgaW50W2ltYWdlV2lkdGgqaW1hZ2VIZWlnaHRdIDoKKyAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbaW1hZ2VXaWR0aCppbWFnZUhlaWdodF07CisKKyAgICAgICAgICAgIE9iamVjdCBzcmMgPSBmb3JjZVJHQiA/CisgICAgICAgICAgICAgICAgICAgIGdldFNjcmVlblJHQkJ1ZmZlcigpIDoKKyAgICAgICAgICAgICAgICAgICAgKE9iamVjdCkgc2NyZWVuQnVmZmVyOworCisgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICAgICAgICAgIE9iamVjdCB0b1NlbmQ7CisKKyAgICAgICAgICAgIGlmICh3aWR0aCA9PSBpbWFnZVdpZHRoKSB7CisgICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW1hZ2VXaWR0aCAqIGltYWdlVG9wOworICAgICAgICAgICAgICAgIHRvU2VuZCA9IHNyYzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGltYWdlSGVpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VMZWZ0ICsgaSp3aWR0aCArIGltYWdlVG9wKndpZHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKmltYWdlV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aAorICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgIH0gLy8gZm9yCisgICAgICAgICAgICAgICAgdG9TZW5kID0gZHN0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZm9yY2VSR0IpIHsKKyAgICAgICAgICAgICAgICBzZXRQaXhlbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUxlZnQsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVRvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgKGludCBbXSl0b1NlbmQsCisgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2V0UGl4ZWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VMZWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VUb3AsCisgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VIZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUgW10pdG9TZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aAorICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBHaWZDb2xvclRhYmxlIHsKKyAgICAgICAgLy8gIEluZGljYXRlcyB0aGF0IHJlYWRpbmcgb2YgdGhpcyBibG9jayBhY2NvbXBsaXNoZWQKKyAgICAgICAgYm9vbGVhbiBjb21wbGV0ZWQgPSBmYWxzZTsKKworICAgICAgICBJbmRleENvbG9yTW9kZWwgY20gPSBudWxsOworICAgICAgICBpbnQgc2l6ZSA9IDA7IC8vIEFjdHVhbCBudW1iZXIgb2YgY29sb3JzIGluIHRoZSBjb2xvciB0YWJsZQorICAgICAgICBieXRlIGNvbG9yc1tdID0gbmV3IGJ5dGVbMjU2KjNdOworCisgICAgICAgIEluZGV4Q29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKGludCB0cmFuc3BhcmVudENvbG9yKSB7CisgICAgICAgICAgICBpZiAoY20gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICh0cmFuc3BhcmVudENvbG9yICE9IGNtLmdldFRyYW5zcGFyZW50UGl4ZWwoKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY20gPSBudWxsOyAvLyBGb3JjZSBkZWZhdWx0IEFSR0IgY29sb3IgbW9kZWwKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNtOworICAgICAgICAgICAgfSBlbHNlCisgICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRlZCAmJiBzaXplID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRDb2xvciA9PSBJTVBPU1NJQkxFX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY20gPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5kZXhDb2xvck1vZGVsKDgsIHNpemUsIGNvbG9ycywgMCwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW50Q29sb3IgPiBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gdHJhbnNwYXJlbnRDb2xvciArIDE7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNtID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5kZXhDb2xvck1vZGVsKDgsIHNpemUsIGNvbG9ycywgMCwgZmFsc2UsIHRyYW5zcGFyZW50Q29sb3IpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGNtID0gbnVsbDsgLy8gRm9yY2UgZGVmYXVsdCBBUkdCIGNvbG9yIG1vZGVsCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9JbWFnZURlY29kZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0ltYWdlRGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxNjEyOGUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9JbWFnZURlY29kZXIuamF2YQpAQCAtMCwwICsxLDI1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKy8qCisgKiBDcmVhdGVkIG9uIDE4LjAxLjIwMDUKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlOworCitpbXBvcnQgY29tLmFuZHJvaWQuaW50ZXJuYWwuYXd0LkFuZHJvaWRJbWFnZURlY29kZXI7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlQ29uc3VtZXI7CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisKKy8qKgorICogVGhpcyBjbGFzcyBjb250YWlucyBjb21tb24gZnVuY3Rpb25hbGl0eSBmb3IgYWxsIGltYWdlIGRlY29kZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSW1hZ2VEZWNvZGVyIHsKKyAgICAKKyAgICAvKiogSW1hZ2UgdHlwZXMgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHRU5FUklDX0RFQ09ERVIgPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpQR19ERUNPREVSID0gMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHSUZfREVDT0RFUiA9IDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0RFQ09ERVIgPSAzOworICAgIAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfQllURVNfSU5fU0lHTkFUVVJFID0gODsKKworICAgIHByb3RlY3RlZCBMaXN0PEltYWdlQ29uc3VtZXI+IGNvbnN1bWVyczsKKyAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW07CisgICAgcHJvdGVjdGVkIERlY29kaW5nSW1hZ2VTb3VyY2Ugc3JjOworCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gdGVybWluYXRlZDsKKworICAgIC8qKgorICAgICAqIENob29zZXMgYXBwcm9wcmlhdGUgaW1hZ2UgZGVjb2RlciBieSBsb29raW5nIGludG8gaW5wdXQgc3RyZWFtIGFuZCBjaGVja2luZworICAgICAqIHRoZSBpbWFnZSBzaWduYXR1cmUuCisgICAgICogQHBhcmFtIHNyYyAtIGltYWdlIHByb2R1Y2VyLCByZXF1aXJlZCBmb3IgcGFzc2luZyBkYXRhIHRvIGl0IGZyb20gdGhlCisgICAgICogY3JlYXRlZCBkZWNvZGVyIHZpYSBjYWxsYmFja3MKKyAgICAgKiBAcGFyYW0gaXMgLSBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIGRlY29kZXIKKyAgICAgKi8KKyAgICBzdGF0aWMgSW1hZ2VEZWNvZGVyIGNyZWF0ZURlY29kZXIoRGVjb2RpbmdJbWFnZVNvdXJjZSBzcmMsIElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgIElucHV0U3RyZWFtIG1hcmthYmxlOworCisgICAgICAgIGlmICghaXMubWFya1N1cHBvcnRlZCgpKSB7CisgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLW1vZGlmaWVkCisgICAgICAgICAgICBtYXJrYWJsZSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzLCA4MTkyKTsKKyAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLW1vZGlmaWVkCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtYXJrYWJsZSA9IGlzOworICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgLy8gUmVhZCB0aGUgc2lnbmF0dXJlIGZyb20gdGhlIHN0cmVhbSBhbmQgdGhlbiByZXNldCBpdCBiYWNrCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXJrYWJsZS5tYXJrKE1BWF9CWVRFU19JTl9TSUdOQVRVUkUpOworCisgICAgICAgICAgICBieXRlW10gc2lnbmF0dXJlID0gbmV3IGJ5dGVbTUFYX0JZVEVTX0lOX1NJR05BVFVSRV07CisgICAgICAgICAgICBtYXJrYWJsZS5yZWFkKHNpZ25hdHVyZSwgMCwgTUFYX0JZVEVTX0lOX1NJR05BVFVSRSk7CisgICAgICAgICAgICBtYXJrYWJsZS5yZXNldCgpOworCisgICAgICAgICAgICBpZiAoKHNpZ25hdHVyZVswXSAmIDB4RkYpID09IDB4RkYgJiYKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsxXSAmIDB4RkYpID09IDB4RDggJiYKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsyXSAmIDB4RkYpID09IDB4RkYpIHsgLy8gSlBFRworICAgICAgICAgICAgICAgIHJldHVybiBsb2FkRGVjb2RlcihQTkdfREVDT0RFUiwgc3JjLCBpcyk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChzaWduYXR1cmVbMF0gJiAweEZGKSA9PSAweDQ3ICYmIC8vIEcKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsxXSAmIDB4RkYpID09IDB4NDkgJiYgLy8gSQorICAgICAgICAgICAgICAgICAgICAoc2lnbmF0dXJlWzJdICYgMHhGRikgPT0gMHg0NikgeyAvLyBGCisgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWREZWNvZGVyKEdJRl9ERUNPREVSLCBzcmMsIGlzKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKHNpZ25hdHVyZVswXSAmIDB4RkYpID09IDEzNyAmJiAvLyBQTkcgc2lnbmF0dXJlOiAxMzcgODAgNzggNzEgMTMgMTAgMjYgMTAKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsxXSAmIDB4RkYpID09IDgwICYmCisgICAgICAgICAgICAgICAgICAgIChzaWduYXR1cmVbMl0gJiAweEZGKSA9PSA3OCAmJgorICAgICAgICAgICAgICAgICAgICAoc2lnbmF0dXJlWzNdICYgMHhGRikgPT0gNzEgJiYKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs0XSAmIDB4RkYpID09IDEzICYmCisgICAgICAgICAgICAgICAgICAgIChzaWduYXR1cmVbNV0gJiAweEZGKSA9PSAxMCAmJgorICAgICAgICAgICAgICAgICAgICAoc2lnbmF0dXJlWzZdICYgMHhGRikgPT0gMjYgJiYKKyAgICAgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs3XSAmIDB4RkYpID09IDEwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWREZWNvZGVyKEpQR19ERUNPREVSLCBzcmMsIGlzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGxvYWREZWNvZGVyKEdFTkVSSUNfREVDT0RFUiwgc3JjLCBpcyk7CisgICAgICAgICAgICAKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeyAvLyBTaWxlbnRseQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIAorICAgIC8qCisgICAgICogSW4gdGhlIGZ1dHVyZSwgd2UgbWlnaHQgcmV0dXJuIGRpZmZlcmVudCBkZWNvZGVycyBmb3IgZGlmZmVyZW4gaW1hZ2UgdHlwZXMuCisgICAgICogQnV0IGZvciBub3csIHdlIGFsd2F5cyByZXR1cm4gdGhlIGdlbmVyaWMgb25lLgorICAgICAqIEFsc286IHdlIGNvdWxkIGFkZCBhIGZhY3RvcnkgdG8gbG9hZCBpbWFnZSBkZWNvZGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEltYWdlRGVjb2RlciBsb2FkRGVjb2RlcihpbnQgdHlwZSwgRGVjb2RpbmdJbWFnZVNvdXJjZSBzcmMsIAorICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBbmRyb2lkSW1hZ2VEZWNvZGVyKHNyYywgaXMpOworICAgIH0KKworICAgIHByb3RlY3RlZCBJbWFnZURlY29kZXIoRGVjb2RpbmdJbWFnZVNvdXJjZSBfc3JjLCBJbnB1dFN0cmVhbSBpcykgeworICAgICAgICBzcmMgPSBfc3JjOworICAgICAgICBjb25zdW1lcnMgPSBzcmMuY29uc3VtZXJzOworICAgICAgICBpbnB1dFN0cmVhbSA9IGlzOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRlY29kZUltYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlU3RyZWFtKCkgeworICAgICAgICBpZiAoaW5wdXRTdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcHMgdGhlIGRlY29kaW5nIGJ5IGludGVycnVwdGluZyB0aGUgY3VycmVudCBkZWNvZGluZyB0aHJlYWQuCisgICAgICogVXNlZCB3aGVuIGFsbCBjb25zdW1lcnMgYXJlIHJlbW92ZWQgYW5kIHRoZXJlJ3Mgbm8gbW9yZSBuZWVkIHRvCisgICAgICogcnVuIHRoZSBkZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlcm1pbmF0ZSgpIHsKKyAgICAgICAgc3JjLmxvY2tEZWNvZGVyKHRoaXMpOworICAgICAgICBjbG9zZVN0cmVhbSgpOworCisgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKAorICAgICAgICAgICAgICAgIG5ldyBQcml2aWxlZ2VkQWN0aW9uPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICk7CisKKyAgICAgICAgdGVybWluYXRlZCA9IHRydWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0RGltZW5zaW9ucyhpbnQgdywgaW50IGgpIHsKKyAgICAgICAgaWYgKHRlcm1pbmF0ZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoSW1hZ2VDb25zdW1lciBpYyA6IGNvbnN1bWVycykgeworICAgICAgICAgICAgaWMuc2V0RGltZW5zaW9ucyh3LCBoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFByb3BlcnRpZXMoSGFzaHRhYmxlPD8sID8+IHByb3BzKSB7CisgICAgICAgIGlmICh0ZXJtaW5hdGVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEltYWdlQ29uc3VtZXIgaWMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGljLnNldFByb3BlcnRpZXMocHJvcHMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0Q29sb3JNb2RlbChDb2xvck1vZGVsIGNtKSB7CisgICAgICAgIGlmICh0ZXJtaW5hdGVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEltYWdlQ29uc3VtZXIgaWMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGljLnNldENvbG9yTW9kZWwoY20pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0SGludHMoaW50IGhpbnRzKSB7CisgICAgICAgIGlmICh0ZXJtaW5hdGVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEltYWdlQ29uc3VtZXIgaWMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGljLnNldEhpbnRzKGhpbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFBpeGVscygKKyAgICAgICAgICAgIGludCB4LCBpbnQgeSwKKyAgICAgICAgICAgIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIENvbG9yTW9kZWwgbW9kZWwsCisgICAgICAgICAgICBieXRlIHBpeFtdLAorICAgICAgICAgICAgaW50IG9mZiwgaW50IHNjYW5zaXplCisgICAgICAgICAgICApIHsKKyAgICAgICAgaWYgKHRlcm1pbmF0ZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHNyYy5sb2NrRGVjb2Rlcih0aGlzKTsKKworICAgICAgICBmb3IgKEltYWdlQ29uc3VtZXIgaWMgOiBjb25zdW1lcnMpIHsKKyAgICAgICAgICAgIGljLnNldFBpeGVscyh4LCB5LCB3LCBoLCBtb2RlbCwgcGl4LCBvZmYsIHNjYW5zaXplKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFBpeGVscygKKyAgICAgICAgICAgIGludCB4LCBpbnQgeSwKKyAgICAgICAgICAgIGludCB3LCBpbnQgaCwKKyAgICAgICAgICAgIENvbG9yTW9kZWwgbW9kZWwsCisgICAgICAgICAgICBpbnQgcGl4W10sCisgICAgICAgICAgICBpbnQgb2ZmLCBpbnQgc2NhbnNpemUKKyAgICAgICAgICAgICkgeworICAgICAgICBpZiAodGVybWluYXRlZCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgc3JjLmxvY2tEZWNvZGVyKHRoaXMpOworCisgICAgICAgIGZvciAoSW1hZ2VDb25zdW1lciBpYyA6IGNvbnN1bWVycykgeworICAgICAgICAgICAgaWMuc2V0UGl4ZWxzKHgsIHksIHcsIGgsIG1vZGVsLCBwaXgsIG9mZiwgc2NhbnNpemUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgaW1hZ2VDb21wbGV0ZShpbnQgc3RhdHVzKSB7CisgICAgICAgIGlmICh0ZXJtaW5hdGVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBzcmMubG9ja0RlY29kZXIodGhpcyk7CisKKyAgICAgICAgSW1hZ2VDb25zdW1lciBpYyA9IG51bGw7CisKKyAgICAgICAgZm9yIChJdGVyYXRvcjxJbWFnZUNvbnN1bWVyPiBpID0gY29uc3VtZXJzLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpYyA9IGkubmV4dCgpOworICAgICAgICAgICAgfSBjYXRjaCAoQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaSA9IGNvbnN1bWVycy5pdGVyYXRvcigpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWMuaW1hZ2VDb21wbGV0ZShzdGF0dXMpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9JbWFnZUxvYWRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvSW1hZ2VMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzdkMTgwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvSW1hZ2VMb2FkZXIuamF2YQpAQCAtMCwwICsxLDIwOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBPbGVnIFYuIEtoYXNjaGFuc2t5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKy8qCisgKiBDcmVhdGVkIG9uIDE4LjAxLjIwMDUKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3Igc2ltdWx0YW5lb3VzIGxvYWRpbmcgb2YKKyAqIHNldmVyYWwgaW1hZ2VzIGFuZCBydW5uaW5nIGFuaW1hdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEltYWdlTG9hZGVyIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAvLyBDb250YWlucyBJbWFnZUxvYWRlciBvYmplY3RzCisgICAgLy8gYW5kIHF1ZXVlIG9mIGltYWdlIHNvdXJjZXMgd2FpdGluZyB0byBiZSBsb2FkZWQKKyAgICBzdGF0aWMgY2xhc3MgSW1hZ2VMb2FkZXJzU3RvcmFnZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfVEhSRUFEUyA9IDU7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUSU1FT1VUID0gNDAwMDsKKyAgICAgICAgc3RhdGljIEltYWdlTG9hZGVyc1N0b3JhZ2UgaW5zdGFuY2U7CisKKyAgICAgICAgTGlzdDxEZWNvZGluZ0ltYWdlU291cmNlPiBxdWV1ZSA9IG5ldyBMaW5rZWRMaXN0PERlY29kaW5nSW1hZ2VTb3VyY2U+KCk7CisgICAgICAgIExpc3Q8VGhyZWFkPiBsb2FkZXJzID0gbmV3IEFycmF5TGlzdDxUaHJlYWQ+KE1BWF9USFJFQURTKTsKKworICAgICAgICBwcml2YXRlIGludCBmcmVlTG9hZGVyczsKKworICAgICAgICBwcml2YXRlIEltYWdlTG9hZGVyc1N0b3JhZ2UoKSB7fQorCisgICAgICAgIHN0YXRpYyBJbWFnZUxvYWRlcnNTdG9yYWdlIGdldFN0b3JhZ2UoKSB7CisgICAgICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEltYWdlTG9hZGVyc1N0b3JhZ2UoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlOworICAgICAgICB9CisgICAgfQorCisgICAgSW1hZ2VMb2FkZXIoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgICAgIHNldERhZW1vbih0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgbmV3IHRocmVhZCB3aGljaCBpcyBhYmxlIHRvIGxvYWQgYW4gaW1hZ2UKKyAgICAgKiBvciBydW4gYW5pbWF0aW9uIChpZiB0aGUgbnVtYmVyIG9mIGV4aXN0aW5nIGxvYWRlciB0aHJlYWRzIGRvZXMgbm90CisgICAgICogZXhjZWVkIHRoZSBsaW1pdCkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjcmVhdGVMb2FkZXIoKSB7CisgICAgICAgIGZpbmFsIEltYWdlTG9hZGVyc1N0b3JhZ2Ugc3RvcmFnZSA9IEltYWdlTG9hZGVyc1N0b3JhZ2UuZ2V0U3RvcmFnZSgpOworCisgICAgICAgIHN5bmNocm9uaXplZChzdG9yYWdlLmxvYWRlcnMpIHsKKyAgICAgICAgICAgIGlmIChzdG9yYWdlLmxvYWRlcnMuc2l6ZSgpIDwgSW1hZ2VMb2FkZXJzU3RvcmFnZS5NQVhfVEhSRUFEUykgeworICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByaXZpbGVnZWRBY3Rpb248Vm9pZD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbWFnZUxvYWRlciBsb2FkZXIgPSBuZXcgSW1hZ2VMb2FkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZS5sb2FkZXJzLmFkZChsb2FkZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZXIuc3RhcnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGltYWdlIHNvdXJjZSB0byB0aGUgcXVldWUgYW5kIHN0YXJ0cyBhIG5ldyBsb2FkZXIKKyAgICAgKiB0aHJlYWQgaWYgcmVxdWlyZWQKKyAgICAgKiBAcGFyYW0gaW1nU3JjIC0gaW1hZ2Ugc291cmNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFkZEltYWdlU291cmNlKERlY29kaW5nSW1hZ2VTb3VyY2UgaW1nU3JjKSB7CisgICAgICAgIEltYWdlTG9hZGVyc1N0b3JhZ2Ugc3RvcmFnZSA9IEltYWdlTG9hZGVyc1N0b3JhZ2UuZ2V0U3RvcmFnZSgpOworICAgICAgICBzeW5jaHJvbml6ZWQoc3RvcmFnZS5xdWV1ZSkgeworICAgICAgICAgICAgaWYgKCFzdG9yYWdlLnF1ZXVlLmNvbnRhaW5zKGltZ1NyYykpIHsKKyAgICAgICAgICAgICAgICBzdG9yYWdlLnF1ZXVlLmFkZChpbWdTcmMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0b3JhZ2UuZnJlZUxvYWRlcnMgPT0gMCkgeworICAgICAgICAgICAgICAgIGNyZWF0ZUxvYWRlcigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzdG9yYWdlLnF1ZXVlLm5vdGlmeSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FpdHMgZm9yIGEgbmV3IEltYWdlU291cmNlIHVudGlsIHRpbW91dCBleHBpcmVzLgorICAgICAqIExvYWRlciB0aHJlYWQgd2lsbCB0ZXJtaW5hdGUgYWZ0ZXIgcmV0dXJuaW5nIGZyb20gdGhpcyBtZXRob2QKKyAgICAgKiBpZiB0aW1lb3V0IGV4cGlyZWQgYW5kIGltYWdlIHNvdXJjZSB3YXMgbm90IHBpY2tlZCB1cCBmcm9tIHRoZSBxdWV1ZS4KKyAgICAgKiBAcmV0dXJuIGltYWdlIHNvdXJjZSBwaWNrZWQgdXAgZnJvbSB0aGUgcXVldWUgb3IgbnVsbCBpZiB0aW1lb3V0IGV4cGlyZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBEZWNvZGluZ0ltYWdlU291cmNlIGdldFdhaXRpbmdJbWFnZVNvdXJjZSgpIHsKKyAgICAgICAgSW1hZ2VMb2FkZXJzU3RvcmFnZSBzdG9yYWdlID0gSW1hZ2VMb2FkZXJzU3RvcmFnZS5nZXRTdG9yYWdlKCk7CisKKyAgICAgICAgc3luY2hyb25pemVkKHN0b3JhZ2UucXVldWUpIHsKKyAgICAgICAgICAgIERlY29kaW5nSW1hZ2VTb3VyY2UgaXNyYyA9IG51bGw7CisKKyAgICAgICAgICAgIGlmIChzdG9yYWdlLnF1ZXVlLnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3RvcmFnZS5mcmVlTG9hZGVycysrOworICAgICAgICAgICAgICAgICAgICBzdG9yYWdlLnF1ZXVlLndhaXQoSW1hZ2VMb2FkZXJzU3RvcmFnZS5USU1FT1VUKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHN0b3JhZ2UuZnJlZUxvYWRlcnMtLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzdG9yYWdlLnF1ZXVlLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBpc3JjID0gc3RvcmFnZS5xdWV1ZS5nZXQoMCk7CisgICAgICAgICAgICAgICAgc3RvcmFnZS5xdWV1ZS5yZW1vdmUoMCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBpc3JjOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW50cnkgcG9pbnQgb2YgdGhlIGxvYWRlciB0aHJlYWQuIFBpY2tzIHVwIGltYWdlIHNvdXJjZXMgYW5kCisgICAgICogcnVucyBkZWNvZGVycyBmb3IgdGhlbSB3aGlsZSB0aGVyZSBhcmUgYXZhaWxhYmxlIGltYWdlIHNvdXJjZXMgaW4gdGhlIHF1ZXVlLgorICAgICAqIElmIHRoZXJlIGFyZSBubyBhbmQgdGltZW91dCBleHBpcmVzIGl0IHRlcm1pbmF0ZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICBJbWFnZUxvYWRlcnNTdG9yYWdlIHN0b3JhZ2UgPSBJbWFnZUxvYWRlcnNTdG9yYWdlLmdldFN0b3JhZ2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKHN0b3JhZ2UubG9hZGVycy5jb250YWlucyh0aGlzKSkgeworICAgICAgICAgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOyAvLyBSZXNldCB0aGUgaW50ZXJydXB0ZWQgZmxhZworICAgICAgICAgICAgICAgIERlY29kaW5nSW1hZ2VTb3VyY2UgaXNyYyA9IGdldFdhaXRpbmdJbWFnZVNvdXJjZSgpOworICAgICAgICAgICAgICAgIGlmIChpc3JjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlzcmMubG9hZCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBEb24ndCB3YWl0IGlmIHRpbWVvdXQgZXhwaXJlZCAtIHRlcm1pbmF0ZSBsb2FkZXIKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3luY2hyb25pemVkKHN0b3JhZ2UubG9hZGVycykgeworICAgICAgICAgICAgICAgIHN0b3JhZ2UubG9hZGVycy5yZW1vdmUoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGN1cnJlbnQgdGhyZWFkIGZyb20gbG9hZGVycyAoc28gd2UgYXJlIGFibGUKKyAgICAgKiB0byBjcmVhdGUgbW9yZSBsb2FkZXJzKSBhbmQgZGVjcmVhc2VzIGl0cyBwcmlvcml0eS4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBiZWdpbkFuaW1hdGlvbigpIHsKKyAgICAgICAgSW1hZ2VMb2FkZXJzU3RvcmFnZSBzdG9yYWdlID0gSW1hZ2VMb2FkZXJzU3RvcmFnZS5nZXRTdG9yYWdlKCk7CisgICAgICAgIFRocmVhZCBjdXJyVGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQoc3RvcmFnZSkgeworICAgICAgICAgICAgc3RvcmFnZS5sb2FkZXJzLnJlbW92ZShjdXJyVGhyZWFkKTsKKworICAgICAgICAgICAgaWYgKHN0b3JhZ2UuZnJlZUxvYWRlcnMgPCBzdG9yYWdlLnF1ZXVlLnNpemUoKSkgeworICAgICAgICAgICAgICAgIGNyZWF0ZUxvYWRlcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY3VyclRocmVhZC5zZXRQcmlvcml0eShUaHJlYWQuTUlOX1BSSU9SSVRZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyB0aGUgY3VycmVudCB0aHJlYWQgdG8gd2FpdCBmb3IgdGhlIG5ldyBpbWFnZXMgdG8gbG9hZAorICAgICAqIGlmIHRoZXJlIGFyZSBmcmVlIHBsYWNlaG9sZGVycyBmb3IgbG9hZGVycworICAgICAqLworICAgIHN0YXRpYyB2b2lkIGVuZEFuaW1hdGlvbigpIHsKKyAgICAgICAgSW1hZ2VMb2FkZXJzU3RvcmFnZSBzdG9yYWdlID0gSW1hZ2VMb2FkZXJzU3RvcmFnZS5nZXRTdG9yYWdlKCk7CisgICAgICAgIFRocmVhZCBjdXJyVGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQoc3RvcmFnZSkgeworICAgICAgICAgICAgaWYgKHN0b3JhZ2UubG9hZGVycy5zaXplKCkgPCBJbWFnZUxvYWRlcnNTdG9yYWdlLk1BWF9USFJFQURTICYmCisgICAgICAgICAgICAgICAgICAgICFzdG9yYWdlLmxvYWRlcnMuY29udGFpbnMoY3VyclRocmVhZCkKKyAgICAgICAgICAgICkgeworICAgICAgICAgICAgICAgIHN0b3JhZ2UubG9hZGVycy5hZGQoY3VyclRocmVhZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBjdXJyVGhyZWFkLnNldFByaW9yaXR5KFRocmVhZC5OT1JNX1BSSU9SSVRZKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvSnBlZ0RlY29kZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0pwZWdEZWNvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmU2NDQyNwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL0pwZWdEZWNvZGVyLmphdmEKQEAgLTAsMCArMSwyMzEgQEAKKy8qCisqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKgorKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS4qOworaW1wb3J0IGphdmEuYXd0LmNvbG9yLkNvbG9yU3BhY2U7CitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitwdWJsaWMgY2xhc3MgSnBlZ0RlY29kZXIgZXh0ZW5kcyBJbWFnZURlY29kZXIgeworICAgIC8vIE9ubHkgMiBvdXRwdXQgY29sb3JzcGFjZXMgZXhwZWN0ZWQuIE90aGVycyBhcmUgY29udmVydGVkIGludG8KKyAgICAvLyB0aGVzZSBvbmVzLgorICAgIC8vIDEuIEdyYXlzY2FsZQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19HUkFZU0NBTEUgPSAxOworICAgIC8vIDIuIFJHQgorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19SR0IgPSAyOworCisgICAgLy8gRmxhZ3MgZm9yIHRoZSBjb25zdW1lciwgcHJvZ3Jlc3NpdmUgSlBFRworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBoaW50ZmxhZ3NQcm9ncmVzc2l2ZSA9CisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLlNJTkdMRUZSQU1FIHwgLy8gSlBFRyBpcyBhIHN0YXRpYyBpbWFnZQorICAgICAgICAgICAgSW1hZ2VDb25zdW1lci5UT1BET1dOTEVGVFJJR0hUIHwgLy8gVGhpcyBvcmRlciBpcyBvbmx5IG9uZSBwb3NzaWJsZQorICAgICAgICAgICAgSW1hZ2VDb25zdW1lci5DT01QTEVURVNDQU5MSU5FUzsgLy8gRG9uJ3QgZGVsaXZlciBpbmNvbXBsZXRlIHNjYW5saW5lcworICAgIC8vIEZsYWdzIGZvciB0aGUgY29uc3VtZXIsIHNpbmdsZXBhc3MgSlBFRworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBoaW50ZmxhZ3NTaW5nbGUgPQorICAgICAgICAgICAgSW1hZ2VDb25zdW1lci5TSU5HTEVQQVNTIHwKKyAgICAgICAgICAgIGhpbnRmbGFnc1Byb2dyZXNzaXZlOworCisgICAgLy8gQnVmZmVyIGZvciB0aGUgc3RyZWFtCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9TSVpFID0gMTAyNDsKKyAgICBwcml2YXRlIGJ5dGUgYnVmZmVyW10gPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisKKyAgICAvLyAzIHBvc3NpYmxlIGNvbG9yIG1vZGVscyBvbmx5CisgICAgcHJpdmF0ZSBzdGF0aWMgQ29sb3JNb2RlbCBjbVJHQjsKKyAgICBwcml2YXRlIHN0YXRpYyBDb2xvck1vZGVsIGNtR3JheTsKKworICAgIC8vIGluaXRpYWxpemVzIHByb3BlciBmaWVsZCBJRHMKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBpbml0SURzKCk7CisKKyAgICAvLyBQb2ludGVyIHRvIG5hdGl2ZSBzdHJ1Y3R1cmUgd2hpY2ggc3RvcmUgZGVjb2Rpbmcgc3RhdGUKKyAgICAvLyBiZXR3ZWVuIHN1YnNlcXVlbnQgZGVjb2RpbmcvSU8tc3VzcGVuc2lvbiBjeWNsZXMKKyAgICBwcml2YXRlIGxvbmcgaE5hdGl2ZURlY29kZXIgPSAwOyAvLyBOVUxMIGluaXRpYWxseQorCisgICAgcHJpdmF0ZSBib29sZWFuIGhlYWRlckRvbmUgPSBmYWxzZTsKKworICAgIC8vIE5leHQgNCBtZW1iZXJzIGFyZSBmaWxsZWQgYnkgdGhlIG5hdGl2ZSBtZXRob2QgKGRlY29tcHJlc3MpLgorICAgIC8vIFdlIGNhbiBzaW1wbHkgY2hlY2sgaWYgaW1hZ2VXaWR0aCBpcyBzdGlsbCBuZWdhdGl2ZSB0byBmaW5kCisgICAgLy8gb3V0IGlmIHRoZXkgYXJlIGFscmVhZHkgZmlsbGVkLgorICAgIHByaXZhdGUgaW50IGltYWdlV2lkdGggPSAtMTsKKyAgICBwcml2YXRlIGludCBpbWFnZUhlaWdodCA9IC0xOworICAgIHByaXZhdGUgYm9vbGVhbiBwcm9ncmVzc2l2ZSA9IGZhbHNlOworICAgIHByaXZhdGUgaW50IGpwZWdDb2xvclNwYWNlID0gMDsKKworICAgIC8vIFN0b3JlcyBudW1iZXIgb2YgYnl0ZXMgY29uc3VtZWQgYnkgdGhlIG5hdGl2ZSBkZWNvZGVyCisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNDb25zdW1lZCA9IDA7CisgICAgLy8gU3RvcmVzIGN1cnJlbnQgc2NhbmxpbmUgcmV0dXJuZWQgYnkgdGhlIGRlY29kZXIKKyAgICBwcml2YXRlIGludCBjdXJyU2NhbmxpbmUgPSAwOworCisgICAgcHJpdmF0ZSBDb2xvck1vZGVsIGNtID0gbnVsbDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFN5c3RlbS5sb2FkTGlicmFyeSgianBlZ2RlY29kZXIiKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGNtR3JheSA9IG5ldyBDb21wb25lbnRDb2xvck1vZGVsKAorICAgICAgICAgICAgICAgIENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19HUkFZKSwKKyAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UsCisgICAgICAgICAgICAgICAgVHJhbnNwYXJlbmN5Lk9QQVFVRSwgRGF0YUJ1ZmZlci5UWVBFX0JZVEUKKyAgICAgICAgKTsKKworICAgICAgICAvLyBDcmVhdGUgUkdCIGNvbG9yIG1vZGVsCisgICAgICAgIGNtUkdCID0gbmV3IERpcmVjdENvbG9yTW9kZWwoMjQsIDB4RkYwMDAwLCAweEZGMDAsIDB4RkYpOworCisgICAgICAgIGluaXRJRHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSnBlZ0RlY29kZXIoRGVjb2RpbmdJbWFnZVNvdXJjZSBzcmMsIElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgIHN1cGVyKHNyYywgaXMpOworICAgIH0KKworICAgIC8qCisgICAgcHVibGljIEpwZWdEZWNvZGVyKElucHV0U3RyZWFtIGlTdHJlYW0sIEltYWdlQ29uc3VtZXIgaUNvbnN1bWVyKSB7CisgICAgaW5wdXRTdHJlYW0gPSBpU3RyZWFtOworICAgIGNvbnN1bWVyID0gaUNvbnN1bWVyOworICAgIH0KKyAgICAqLworCisgICAgLyoqCisgICAgICogQHJldHVybiAtIG5vdCBOVUxMIGlmIGNhbGwgaXMgc3VjY2Vzc2Z1bAorICAgICAqLworICAgIHByaXZhdGUgbmF0aXZlIE9iamVjdCBkZWNvZGUoCisgICAgICAgICAgICBieXRlW10gaW5wdXQsCisgICAgICAgICAgICBpbnQgYnl0ZXNJbkJ1ZmZlciwKKyAgICAgICAgICAgIGxvbmcgaERlY29kZXIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgcmVsZWFzZU5hdGl2ZURlY29kZXIobG9uZyBoRGVjb2Rlcik7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkZWNvZGVJbWFnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gMCwgZGF0YUxlbmd0aCA9IDA7CisgICAgICAgICAgICBib29sZWFuIGVvc1JlYWNoZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGludCBuZWVkQnl0ZXMsIG9mZnNldCwgYnl0ZXNJbkJ1ZmZlciA9IDA7CisgICAgICAgICAgICBieXRlIGJ5dGVPdXRbXSA9IG51bGw7CisgICAgICAgICAgICBpbnQgaW50T3V0W10gPSBudWxsOworICAgICAgICAgICAgLy8gUmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBuZWVkQnl0ZXMgPSBCVUZGRVJfU0laRSAtIGJ5dGVzSW5CdWZmZXI7CisgICAgICAgICAgICAgICAgb2Zmc2V0ID0gYnl0ZXNJbkJ1ZmZlcjsKKworICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCA9IGlucHV0U3RyZWFtLnJlYWQoYnVmZmVyLCBvZmZzZXQsIG5lZWRCeXRlcyk7CisKKyAgICAgICAgICAgICAgICBpZiAoYnl0ZXNSZWFkIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBieXRlc1JlYWQgPSAwOy8vYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGVvc1JlYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gLy8gRG9uJ3QgYnJlYWssIG1heWJlIHNvbWV0aGluZyBsZWZ0IGluIGJ1ZmZlcgorCisgICAgICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvbiBob3cgbXVjaCBieXRlcyBsZWZ0IGluIGJ1ZmZlcgorICAgICAgICAgICAgICAgIGJ5dGVzSW5CdWZmZXIgKz0gYnl0ZXNSZWFkOworCisgICAgICAgICAgICAgICAgLy8gSGVyZSB3ZSBwYXNzIG92ZXJhbGwgbnVtYmVyIG9mIGJ5dGVzIGxlZnQgaW4gdGhlIGphdmEgYnVmZmVyCisgICAgICAgICAgICAgICAgLy8gKGJ5dGVzSW5CdWZmZXIpIHNpbmNlIGpwZWcgZGVjb2RlciBoYXMgaXRzIG93biBidWZmZXIgYW5kIGNvbnN1bWVzCisgICAgICAgICAgICAgICAgLy8gYXMgbWFueSBieXRlcyBhcyBpdCBjYW4uIElmIHRoZXJlIGFyZSBhbnkgdW5jb25zdW1lZCBieXRlcworICAgICAgICAgICAgICAgIC8vIGl0IGRpZG4ndCBhZGQgdGhlbSB0byBpdHMgYnVmZmVyLi4uCisgICAgICAgICAgICAgICAgT2JqZWN0IGFyciA9IGRlY29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzSW5CdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBoTmF0aXZlRGVjb2Rlcik7CisKKyAgICAgICAgICAgICAgICAvLyBLZWVwIHRyYWNrIG9uIGhvdyBtdWNoIGJ5dGVzIGxlZnQgaW4gYnVmZmVyCisgICAgICAgICAgICAgICAgYnl0ZXNJbkJ1ZmZlciAtPSBieXRlc0NvbnN1bWVkOworCisgICAgICAgICAgICAgICAgaWYgKCFoZWFkZXJEb25lICYmIGltYWdlV2lkdGggIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuSGVhZGVyKCk7CisgICAgICAgICAgICAgICAgICAgIGhlYWRlckRvbmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChieXRlc0NvbnN1bWVkIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gRXJyb3IgZXhpdAorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChhcnIgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZU91dCA9IChieXRlW10pIGFycjsKKyAgICAgICAgICAgICAgICAgICAgZGF0YUxlbmd0aCA9IGJ5dGVPdXQubGVuZ3RoOworICAgICAgICAgICAgICAgICAgICByZXR1cm5EYXRhKGJ5dGVPdXQsIGN1cnJTY2FubGluZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcnIgaW5zdGFuY2VvZiBpbnRbXSkgeworICAgICAgICAgICAgICAgICAgICBpbnRPdXQgPSAoaW50W10pIGFycjsKKyAgICAgICAgICAgICAgICAgICAgZGF0YUxlbmd0aCA9IGludE91dC5sZW5ndGg7CisgICAgICAgICAgICAgICAgICAgIHJldHVybkRhdGEoaW50T3V0LCBjdXJyU2NhbmxpbmUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRhdGFMZW5ndGggPSAwOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChoTmF0aXZlRGVjb2RlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChkYXRhTGVuZ3RoID09IDAgJiYgZW9zUmVhY2hlZCkgeworICAgICAgICAgICAgICAgICAgICByZWxlYXNlTmF0aXZlRGVjb2RlcihoTmF0aXZlRGVjb2Rlcik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBQcm9iYWJseSBpbWFnZSBpcyB0cnVuY2F0ZWQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbWFnZUNvbXBsZXRlKEltYWdlQ29uc3VtZXIuU1RBVElDSU1BR0VET05FKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGNsb3NlU3RyZWFtKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXR1cm5IZWFkZXIoKSB7CisgICAgICAgIHNldERpbWVuc2lvbnMoaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQpOworCisgICAgICAgIHN3aXRjaCAoanBlZ0NvbG9yU3BhY2UpIHsKKyAgICAgICAgICAgIGNhc2UgSkNTX0dSQVlTQ0FMRTogY20gPSBjbUdyYXk7IGJyZWFrOworICAgICAgICAgICAgY2FzZSBKQ1NfUkdCOiBjbSA9IGNtUkdCOyBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6IAorICAgICAgICAgICAgICAgIC8vIGF3dC4zRD1Vbmtub3duIGNvbG9yc3BhY2UKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNEIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgc2V0Q29sb3JNb2RlbChjbSk7CisKKyAgICAgICAgc2V0SGludHMocHJvZ3Jlc3NpdmUgPyBoaW50ZmxhZ3NQcm9ncmVzc2l2ZSA6IGhpbnRmbGFnc1NpbmdsZSk7CisKKyAgICAgICAgc2V0UHJvcGVydGllcyhuZXcgSGFzaHRhYmxlPE9iamVjdCwgT2JqZWN0PigpKTsgLy8gRW1wdHkKKyAgICB9CisKKyAgICAvLyBTZW5kIHRoZSBkYXRhIHRvIHRoZSBjb25zdW1lcgorICAgIHB1YmxpYyB2b2lkIHJldHVybkRhdGEoaW50IGRhdGFbXSwgaW50IGN1cnJTY2FuTGluZSkgeworICAgICAgICAvLyBTZW5kIDEgb3IgbW9yZSBzY2FubGluZXMgdG8gdGhlIGNvbnN1bWVyLgorICAgICAgICBpbnQgbnVtU2NhbmxpbmVzID0gZGF0YS5sZW5ndGggLyBpbWFnZVdpZHRoOworICAgICAgICBpZiAobnVtU2NhbmxpbmVzID4gMCkgeworICAgICAgICAgICAgc2V0UGl4ZWxzKAorICAgICAgICAgICAgICAgICAgICAwLCBjdXJyU2NhbkxpbmUgLSBudW1TY2FubGluZXMsCisgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgsIG51bVNjYW5saW5lcywKKyAgICAgICAgICAgICAgICAgICAgY20sIGRhdGEsIDAsIGltYWdlV2lkdGgKKyAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXR1cm5EYXRhKGJ5dGUgZGF0YVtdLCBpbnQgY3VyclNjYW5MaW5lKSB7CisgICAgICAgIGludCBudW1TY2FubGluZXMgPSBkYXRhLmxlbmd0aCAvIGltYWdlV2lkdGg7CisgICAgICAgIGlmIChudW1TY2FubGluZXMgPiAwKSB7CisgICAgICAgICAgICBzZXRQaXhlbHMoCisgICAgICAgICAgICAgICAgICAgIDAsIGN1cnJTY2FuTGluZSAtIG51bVNjYW5saW5lcywKKyAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aCwgbnVtU2NhbmxpbmVzLAorICAgICAgICAgICAgICAgICAgICBjbSwgZGF0YSwgMCwgaW1hZ2VXaWR0aAorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL09mZnNjcmVlbkltYWdlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9PZmZzY3JlZW5JbWFnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0NDVmOGUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9PZmZzY3JlZW5JbWFnZS5qYXZhCkBAIC0wLDAgKzEsNTMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKy8qCisgKiBDcmVhdGVkIG9uIDIyLjEyLjIwMDQKKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzOworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQ29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db21wb25lbnRDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckJ5dGU7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckludDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EaXJlY3RDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdlQ29uc3VtZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW1hZ2VPYnNlcnZlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkluZGV4Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLkltYWdlU3VyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50IGltcGxlbWVudGF0aW9uIG9mIGFic3RyYWN0IEltYWdlIGNsYXNzCisgKi8KK3B1YmxpYyBjbGFzcyBPZmZzY3JlZW5JbWFnZSBleHRlbmRzIEltYWdlIGltcGxlbWVudHMgSW1hZ2VDb25zdW1lciB7CisKKyAgICBzdGF0aWMgZmluYWwgQ29sb3JNb2RlbCByZ2JDTSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgIEltYWdlUHJvZHVjZXIgc3JjOworICAgIEJ1ZmZlcmVkSW1hZ2UgaW1hZ2U7CisgICAgQ29sb3JNb2RlbCBjbTsKKyAgICBXcml0YWJsZVJhc3RlciByYXN0ZXI7CisgICAgYm9vbGVhbiBpc0ludFJHQjsKKyAgICBIYXNodGFibGU8PywgPz4gcHJvcGVydGllczsKKyAgICBWZWN0b3I8SW1hZ2VPYnNlcnZlcj4gb2JzZXJ2ZXJzOworICAgIGludCB3aWR0aDsKKyAgICBpbnQgaGVpZ2h0OworICAgIGludCBpbWFnZVN0YXRlOworICAgIGludCBoaW50czsKKyAgICBwcml2YXRlIGJvb2xlYW4gcHJvZHVjaW5nOworICAgIHByaXZhdGUgSW1hZ2VTdXJmYWNlIGltYWdlU3VyZjsKKworICAgIHB1YmxpYyBPZmZzY3JlZW5JbWFnZShJbWFnZVByb2R1Y2VyIGlwKXsKKyAgICAgICAgaW1hZ2VTdGF0ZSA9IDA7CisgICAgICAgIHNyYyA9IGlwOworICAgICAgICB3aWR0aCA9IC0xOworICAgICAgICBoZWlnaHQgPSAtMTsKKyAgICAgICAgb2JzZXJ2ZXJzID0gbmV3IFZlY3RvcjxJbWFnZU9ic2VydmVyPigpOworICAgICAgICBwcm9kdWNpbmcgPSBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lLCBJbWFnZU9ic2VydmVyIG9ic2VydmVyKSB7CisgICAgICAgIGlmKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYXd0LjM4PVByb3BlcnR5IG5hbWUgaXMgbm90IGRlZmluZWQKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zOCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisgICAgICAgIGlmKHByb3BlcnRpZXMgPT0gbnVsbCl7CisgICAgICAgICAgICBhZGRPYnNlcnZlcihvYnNlcnZlcik7CisgICAgICAgICAgICBzdGFydFByb2R1Y3Rpb24oKTsKKyAgICAgICAgICAgIGlmKHByb3BlcnRpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIE9iamVjdCBwcm9wID0gcHJvcGVydGllcy5nZXQobmFtZSk7CisgICAgICAgIGlmKHByb3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcCA9IFVuZGVmaW5lZFByb3BlcnR5OworICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm9wOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZVByb2R1Y2VyIGdldFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIHNyYzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFdpZHRoKEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgaWYoKGltYWdlU3RhdGUgJiBJbWFnZU9ic2VydmVyLldJRFRIKSA9PSAwKXsKKyAgICAgICAgICAgIGFkZE9ic2VydmVyKG9ic2VydmVyKTsKKyAgICAgICAgICAgIHN0YXJ0UHJvZHVjdGlvbigpOworICAgICAgICAgICAgaWYoKGltYWdlU3RhdGUgJiBJbWFnZU9ic2VydmVyLldJRFRIKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEhlaWdodChJbWFnZU9ic2VydmVyIG9ic2VydmVyKSB7CisgICAgICAgIGlmKChpbWFnZVN0YXRlICYgSW1hZ2VPYnNlcnZlci5IRUlHSFQpID09IDApeworICAgICAgICAgICAgYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIpOworICAgICAgICAgICAgc3RhcnRQcm9kdWN0aW9uKCk7CisgICAgICAgICAgICBpZigoaW1hZ2VTdGF0ZSAmIEltYWdlT2JzZXJ2ZXIuSEVJR0hUKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBoZWlnaHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEdyYXBoaWNzIGdldEdyYXBoaWNzKCkgeworICAgICAgICAvLyBhd3QuMzk9VGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGZvciBpbWFnZSBvYnRhaW5lZCBmcm9tIEltYWdlUHJvZHVjZXIKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjM5IikpOyAvLyROT04tTkxTLTEkCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB7CisgICAgICAgIHN0b3BQcm9kdWN0aW9uKCk7CisgICAgICAgIGltYWdlVXBkYXRlKHRoaXMsIEltYWdlT2JzZXJ2ZXIuQUJPUlQsIC0xLCAtMSwgLTEsIC0xKTsKKyAgICAgICAgaW1hZ2VTdGF0ZSAmPSB+SW1hZ2VPYnNlcnZlci5FUlJPUjsKKyAgICAgICAgaW1hZ2VTdGF0ZSA9IDA7CisgICAgICAgIGltYWdlID0gbnVsbDsKKyAgICAgICAgY20gPSBudWxsOworICAgICAgICByYXN0ZXIgPSBudWxsOworICAgICAgICBoaW50cyA9IDA7CisgICAgICAgIHdpZHRoID0gLTE7CisgICAgICAgIGhlaWdodCA9IC0xOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnRpZXMoSGFzaHRhYmxlPD8sID8+IHByb3BlcnRpZXMpIHsKKyAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllczsKKyAgICAgICAgaW1hZ2VVcGRhdGUodGhpcywgSW1hZ2VPYnNlcnZlci5QUk9QRVJUSUVTLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2xvck1vZGVsKENvbG9yTW9kZWwgY20pIHsKKyAgICAgICAgdGhpcy5jbSA9IGNtOworICAgIH0KKworICAgIC8qCisgICAgICogV2Ugc3VwcG9zZSB3aGF0IGluIGNhc2UgbG9hZGluZyBKUEVHIGltYWdlIHRoZW4gaW1hZ2UgaGFzIERpcmVjdENvbG9yTW9kZWwKKyAgICAgKiBhbmQgZm9yIGluZmlsbCBpbWFnZSBSYXN0ZXIgd2lsbCB1c2Ugc2V0UGl4ZWxzIG1ldGhvZCB3aXRoIGludCBhcnJheS4KKyAgICAgKgorICAgICAqIEluIGNhc2UgbG9hZGluZyBHSUYgaW1hZ2UsIGZvciByYXN0ZXIgaW5maWxsLCBpcyB1c2VkIHNldFBpeGVscyBtZXRob2Qgd2l0aAorICAgICAqIGJ5dGUgYXJyYXkgYW5kIENvbG9yIE1vZGVsIGlzIEluZGV4Q29sb3JNb2RlbC4gQnV0IENvbG9yIE1vZGVsIG1heQorICAgICAqIGJlIGNoYW5nZWQgZHVyaW5nIHRoaXMgcHJvY2Vzcy4gVGhlbiBpcyBjYWxsZWQgc2V0UGl4ZWxzIG1ldGhvZCB3aXRoCisgICAgICogaW50IGFycmF5IGFuZCBpbWFnZSBmb3JjZSB0byBkZWZhdWx0IGNvbG9yIG1vZGVsIC0gaW50IEFSR0IuIFRoZSByZXN0CisgICAgICogcGl4ZWxzIGFyZSBzZW5kaW5nIGluIERpcmVjdENvbG9yTW9kZWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBDb2xvck1vZGVsIG1vZGVsLAorICAgICAgICAgICAgaW50W10gcGl4ZWxzLCBpbnQgb2ZmLCBpbnQgc2NhbnNpemUpIHsKKyAgICAgICAgaWYocmFzdGVyID09IG51bGwpeworICAgICAgICAgICAgaWYoY20gPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgaWYobW9kZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0E9Q29sb3IgTW9kZWwgaXMgbnVsbAorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0EiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY20gPSBtb2RlbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNyZWF0ZVJhc3RlcigpOworICAgICAgICB9CisKKyAgICAgICAgaWYobW9kZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgbW9kZWwgPSBjbTsKKyAgICAgICAgfQorICAgICAgICBpZihjbSAhPSBtb2RlbCl7CisgICAgICAgICAgICBmb3JjZVRvSW50QVJHQigpOworICAgICAgICB9CisKKyAgICAgICAgaWYoY20gPT0gbW9kZWwgJiYgbW9kZWwuZ2V0VHJhbnNmZXJUeXBlKCkgPT0gRGF0YUJ1ZmZlci5UWVBFX0lOVCAmJgorICAgICAgICAgICAgICAgIHJhc3Rlci5nZXROdW1EYXRhRWxlbWVudHMoKSA9PSAxKXsKKworICAgICAgICAgICAgRGF0YUJ1ZmZlckludCBkYmkgPSAoRGF0YUJ1ZmZlckludCkgcmFzdGVyLmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgICAgIGludCBkYXRhW10gPSBkYmkuZ2V0RGF0YSgpOworICAgICAgICAgICAgaW50IHNjYW5saW5lID0gcmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQgcm9mID0gZGJpLmdldE9mZnNldCgpICsgeSAqIHNjYW5saW5lICsgeDsKKyAgICAgICAgICAgIGZvcihpbnQgbGluZU9mZiA9IG9mZiwgbGluZSA9IHk7IGxpbmUgPCB5ICsgaDsKKyAgICAgICAgICAgICAgICBsaW5lKyssIGxpbmVPZmYgKz0gc2NhbnNpemUsIHJvZiArPSBzY2FubGluZSl7CisKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBpeGVscywgbGluZU9mZiwgZGF0YSwgcm9mLCB3KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9ZWxzZSBpZihpc0ludFJHQil7CisgICAgICAgICAgICBpbnQgYnVmZltdID0gbmV3IGludFt3XTsKKyAgICAgICAgICAgIERhdGFCdWZmZXJJbnQgZGJpID0gKERhdGFCdWZmZXJJbnQpIHJhc3Rlci5nZXREYXRhQnVmZmVyKCk7CisgICAgICAgICAgICBpbnQgZGF0YVtdID0gZGJpLmdldERhdGEoKTsKKyAgICAgICAgICAgIGludCBzY2FubGluZSA9IHJhc3Rlci5nZXRXaWR0aCgpOworICAgICAgICAgICAgaW50IHJvZiA9IGRiaS5nZXRPZmZzZXQoKSArIHkgKiBzY2FubGluZSArIHg7CisgICAgICAgICAgICBmb3IgKGludCBzeSA9IHksIHNPZmYgPSBvZmY7IHN5IDwgeSArIGg7IHN5KyssIHNPZmYgKz0gc2NhbnNpemUsCisgICAgICAgICAgICAgICAgcm9mICs9IHNjYW5saW5lKSB7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBzeCA9IHgsIGlkeCA9IDA7IHN4IDwgeCArIHc7IHN4KyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZbaWR4XSA9IG1vZGVsLmdldFJHQihwaXhlbHNbc09mZiArIGlkeF0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmYsIDAsIGRhdGEsIHJvZiwgdyk7CisgICAgICAgICAgICB9CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgT2JqZWN0IGJ1ZiA9IG51bGw7CisgICAgICAgICAgICBmb3IgKGludCBzeSA9IHksIHNPZmYgPSBvZmY7IHN5IDwgeSArIGg7IHN5KyssIHNPZmYgKz0gc2NhbnNpemUpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBzeCA9IHgsIGlkeCA9IDA7IHN4IDwgeCArIHc7IHN4KyssIGlkeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCByZ2IgPSBtb2RlbC5nZXRSR0IocGl4ZWxzW3NPZmYgKyBpZHhdKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmID0gY20uZ2V0RGF0YUVsZW1lbnRzKHJnYiwgYnVmKTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyLnNldERhdGFFbGVtZW50cyhzeCwgc3ksIGJ1Zik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGltYWdlU3VyZiAhPSBudWxsKSB7CisgICAgICAgICAgICBpbWFnZVN1cmYuaW52YWxpZGF0ZSgpOworICAgICAgICB9CisKKyAgICAgICAgaW1hZ2VVcGRhdGUodGhpcywgSW1hZ2VPYnNlcnZlci5TT01FQklUUywgMCwgMCwgd2lkdGgsIGhlaWdodCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWxzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBDb2xvck1vZGVsIG1vZGVsLAorICAgICAgICAgICAgYnl0ZVtdIHBpeGVscywgaW50IG9mZiwgaW50IHNjYW5zaXplKSB7CisKKyAgICAgICAgaWYocmFzdGVyID09IG51bGwpeworICAgICAgICAgICAgaWYoY20gPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgaWYobW9kZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0E9Q29sb3IgTW9kZWwgaXMgbnVsbAorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0EiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY20gPSBtb2RlbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNyZWF0ZVJhc3RlcigpOworICAgICAgICB9CisgICAgICAgIGlmKG1vZGVsID09IG51bGwpIHsKKyAgICAgICAgICAgIG1vZGVsID0gY207CisgICAgICAgIH0KKyAgICAgICAgaWYobW9kZWwgIT0gY20peworICAgICAgICAgICAgZm9yY2VUb0ludEFSR0IoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmKGlzSW50UkdCKXsKKyAgICAgICAgICAgIGludCBidWZmW10gPSBuZXcgaW50W3ddOworICAgICAgICAgICAgSW5kZXhDb2xvck1vZGVsIGljbSA9IChJbmRleENvbG9yTW9kZWwpIG1vZGVsOworICAgICAgICAgICAgaW50IGNvbG9yTWFwW10gPSBuZXcgaW50W2ljbS5nZXRNYXBTaXplKCldOworICAgICAgICAgICAgaWNtLmdldFJHQnMoY29sb3JNYXApOworICAgICAgICAgICAgRGF0YUJ1ZmZlckludCBkYmkgPSAoRGF0YUJ1ZmZlckludCkgcmFzdGVyLmdldERhdGFCdWZmZXIoKTsKKyAgICAgICAgICAgIGludCBkYXRhW10gPSBkYmkuZ2V0RGF0YSgpOworICAgICAgICAgICAgaW50IHNjYW5saW5lID0gcmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgICAgICBpbnQgcm9mID0gZGJpLmdldE9mZnNldCgpICsgeSAqIHNjYW5saW5lICsgeDsKKyAgICAgICAgICAgIGlmKG1vZGVsIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKXsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHN5ID0geSwgc09mZiA9IG9mZjsgc3kgPCB5ICsgaDsgc3krKywgc09mZiArPSBzY2Fuc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgcm9mICs9IHNjYW5saW5lKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHN4ID0geCwgaWR4ID0gMDsgc3ggPCB4ICsgdzsgc3grKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZbaWR4XSA9IGNvbG9yTWFwW3BpeGVsc1tzT2ZmICsgaWR4XSAmIDB4ZmZdOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZiwgMCwgZGF0YSwgcm9mLCB3KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9ZWxzZXsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHN5ID0geSwgc09mZiA9IG9mZjsgc3kgPCB5ICsgaDsgc3krKywgc09mZiArPSBzY2Fuc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgcm9mICs9IHNjYW5saW5lKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHN4ID0geCwgaWR4ID0gMDsgc3ggPCB4ICsgdzsgc3grKywgaWR4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZbaWR4XSA9IG1vZGVsLmdldFJHQihwaXhlbHNbc09mZiArIGlkeF0gJiAweGZmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmYsIDAsIGRhdGEsIHJvZiwgdyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9ZWxzZSBpZihtb2RlbCA9PSBjbSAmJiBtb2RlbC5nZXRUcmFuc2ZlclR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJgorICAgICAgICAgICAgICAgIHJhc3Rlci5nZXROdW1EYXRhRWxlbWVudHMoKSA9PSAxKXsKKworICAgICAgICAgICAgRGF0YUJ1ZmZlckJ5dGUgZGJiID0gKERhdGFCdWZmZXJCeXRlKXJhc3Rlci5nZXREYXRhQnVmZmVyKCk7CisgICAgICAgICAgICBieXRlIGRhdGFbXSA9IGRiYi5nZXREYXRhKCk7CisgICAgICAgICAgICBpbnQgc2NhbmxpbmUgPSByYXN0ZXIuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGludCByb2YgPSBkYmIuZ2V0T2Zmc2V0KCkgKyB5ICogc2NhbmxpbmUgKyB4OworICAgICAgICAgICAgZm9yKGludCBsaW5lT2ZmID0gb2ZmLCBsaW5lID0geTsgbGluZSA8IHkgKyBoOworICAgICAgICAgICAgICAgIGxpbmUrKywgbGluZU9mZiArPSBzY2Fuc2l6ZSwgcm9mICs9IHNjYW5saW5lKXsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBpeGVscywgbGluZU9mZiwgZGF0YSwgcm9mLCB3KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZCAodGFrZW4gZnJvbSBuZXdlciBIYXJtb255KQorICAgICAgICB9ZWxzZSBpZihtb2RlbCA9PSBjbSAmJiBtb2RlbC5nZXRUcmFuc2ZlclR5cGUoKSA9PSBEYXRhQnVmZmVyLlRZUEVfQllURSAmJgorICAgICAgICAgICAgICAgIGNtIGluc3RhbmNlb2YgQ29tcG9uZW50Q29sb3JNb2RlbCl7CisKKyAgICAgICAgICAgIGludCBuYyA9IGNtLmdldE51bUNvbXBvbmVudHMoKTsKKyAgICAgICAgICAgIGJ5dGUgc3RyaWRlW10gPSBuZXcgYnl0ZVtzY2Fuc2l6ZV07CisgICAgICAgICAgICBmb3IgKGludCBzeSA9IHksIHNPZmYgPSBvZmY7IHN5IDwgeSArIGg7IHN5KyssIHNPZmYgKz0gc2NhbnNpemUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBpeGVscywgc09mZiwgc3RyaWRlLCAwLCBzY2Fuc2l6ZSk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgcmFzdGVyLnNldERhdGFFbGVtZW50cyh4LCBzeSwgdywgMSwgc3RyaWRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKyAgICAgICAgfWVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgc3kgPSB5LCBzT2ZmID0gb2ZmOyBzeSA8IHkgKyBoOyBzeSsrLCBzT2ZmICs9IHNjYW5zaXplKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgc3ggPSB4LCBpZHggPSAwOyBzeCA8IHggKyB3OyBzeCsrLCBpZHgrKykgeworICAgICAgICAgICAgICAgICAgICBpbnQgcmdiID0gbW9kZWwuZ2V0UkdCKHBpeGVsc1tzT2ZmICsgaWR4XSAmIDB4ZmYpOworICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0RGF0YUVsZW1lbnRzKHN4LCBzeSwgY20uZ2V0RGF0YUVsZW1lbnRzKHJnYiwgbnVsbCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbWFnZVN1cmYgIT0gbnVsbCkgeworICAgICAgICAgICAgaW1hZ2VTdXJmLmludmFsaWRhdGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGltYWdlVXBkYXRlKHRoaXMsIEltYWdlT2JzZXJ2ZXIuU09NRUJJVFMsIDAsIDAsIHdpZHRoLCBoZWlnaHQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERpbWVuc2lvbnMoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisgICAgICAgIGlmKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApeworICAgICAgICAgICAgaW1hZ2VDb21wbGV0ZShJbWFnZU9ic2VydmVyLkVSUk9SKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKKyAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgIGltYWdlVXBkYXRlKHRoaXMsIChJbWFnZU9ic2VydmVyLkhFSUdIVCB8IEltYWdlT2JzZXJ2ZXIuV0lEVEgpLAorICAgICAgICAgICAgICAgIDAsIDAsIHdpZHRoLCBoZWlnaHQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEhpbnRzKGludCBoaW50cykgeworICAgICAgICB0aGlzLmhpbnRzID0gaGludHM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW1hZ2VDb21wbGV0ZShpbnQgc3RhdGUpIHsKKyAgICAgICAgaW50IGZsYWc7CisgICAgICAgIHN3aXRjaChzdGF0ZSl7CisgICAgICAgIGNhc2UgSU1BR0VBQk9SVEVEOgorICAgICAgICAgICAgZmxhZyA9IEltYWdlT2JzZXJ2ZXIuQUJPUlQ7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBJTUFHRUVSUk9SOgorICAgICAgICAgICAgZmxhZyA9IEltYWdlT2JzZXJ2ZXIuRVJST1IgfCBJbWFnZU9ic2VydmVyLkFCT1JUOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU0lOR0xFRlJBTUVET05FOgorICAgICAgICAgICAgZmxhZyA9IEltYWdlT2JzZXJ2ZXIuRlJBTUVCSVRTOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU1RBVElDSU1BR0VET05FOgorICAgICAgICAgICAgZmxhZyA9IEltYWdlT2JzZXJ2ZXIuQUxMQklUUzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgLy8gYXd0LjNCPUluY29ycmVjdCBJbWFnZUNvbnN1bWVyIGNvbXBsZXRpb24gc3RhdHVzCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNCIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgIH0KKyAgICAgICAgaW1hZ2VVcGRhdGUodGhpcywgZmxhZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7CisKKyAgICAgICAgaWYoKGZsYWcgJiAoSW1hZ2VPYnNlcnZlci5FUlJPUiB8IEltYWdlT2JzZXJ2ZXIuQUJPUlQgfAorICAgICAgICAgICAgICAgIEltYWdlT2JzZXJ2ZXIuQUxMQklUUykpICE9IDAgKSB7CisgICAgICAgICAgICBzdG9wUHJvZHVjdGlvbigpOworICAgICAgICAgICAgb2JzZXJ2ZXJzLnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgLypzeW5jaHJvbml6ZWQqLyBCdWZmZXJlZEltYWdlIGdldEJ1ZmZlcmVkSW1hZ2UoKXsKKyAgICAgICAgaWYoaW1hZ2UgPT0gbnVsbCl7CisgICAgICAgICAgICBDb2xvck1vZGVsIG1vZGVsID0gZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgV3JpdGFibGVSYXN0ZXIgd3IgPSBnZXRSYXN0ZXIoKTsKKyAgICAgICAgICAgIGlmKG1vZGVsICE9IG51bGwgJiYgd3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGltYWdlID0gbmV3IEJ1ZmZlcmVkSW1hZ2UobW9kZWwsIHdyLCBtb2RlbC5pc0FscGhhUHJlbXVsdGlwbGllZCgpLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1hZ2U7CisgICAgfQorCisgICAgcHVibGljIC8qc3luY2hyb25pemVkKi8gaW50IGNoZWNrSW1hZ2UoSW1hZ2VPYnNlcnZlciBvYnNlcnZlcil7CisgICAgICAgIGFkZE9ic2VydmVyKG9ic2VydmVyKTsKKyAgICAgICAgcmV0dXJuIGltYWdlU3RhdGU7CisgICAgfQorCisgICAgcHVibGljIC8qc3luY2hyb25pemVkKi8gYm9vbGVhbiBwcmVwYXJlSW1hZ2UoSW1hZ2VPYnNlcnZlciBvYnNlcnZlcil7CisgICAgICAgIGlmKChpbWFnZVN0YXRlICYgSW1hZ2VPYnNlcnZlci5FUlJPUikgIT0gMCl7CisgICAgICAgICAgICBpZihvYnNlcnZlciAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICBvYnNlcnZlci5pbWFnZVVwZGF0ZSh0aGlzLCBJbWFnZU9ic2VydmVyLkVSUk9SIHwKKyAgICAgICAgICAgICAgICAgICAgICAgIEltYWdlT2JzZXJ2ZXIuQUJPUlQsIC0xLCAtMSwgLTEsIC0xKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZigoaW1hZ2VTdGF0ZSAmIEltYWdlT2JzZXJ2ZXIuQUxMQklUUykgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIpOworICAgICAgICBzdGFydFByb2R1Y3Rpb24oKTsKKyAgICAgICAgcmV0dXJuICgoaW1hZ2VTdGF0ZSAmIEltYWdlT2JzZXJ2ZXIuQUxMQklUUykgIT0gMCk7CisgICAgfQorCisgICAgcHVibGljIC8qc3luY2hyb25pemVkKi8gQ29sb3JNb2RlbCBnZXRDb2xvck1vZGVsKCl7CisgICAgICAgIGlmKGNtID09IG51bGwpIHsKKyAgICAgICAgICAgIHN0YXJ0UHJvZHVjdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjbTsKKyAgICB9CisKKyAgICBwdWJsaWMgLypzeW5jaHJvbml6ZWQqLyBXcml0YWJsZVJhc3RlciBnZXRSYXN0ZXIoKXsKKyAgICAgICAgaWYocmFzdGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHN0YXJ0UHJvZHVjdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByYXN0ZXI7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdGF0ZSgpeworICAgICAgICByZXR1cm4gaW1hZ2VTdGF0ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIC8qc3luY2hyb25pemVkKi8gdm9pZCBhZGRPYnNlcnZlcihJbWFnZU9ic2VydmVyIG9ic2VydmVyKXsKKyAgICAgICAgaWYob2JzZXJ2ZXIgIT0gbnVsbCl7CisgICAgICAgICAgaWYob2JzZXJ2ZXJzLmNvbnRhaW5zKG9ic2VydmVyKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgICAgaWYoKGltYWdlU3RhdGUgJiBJbWFnZU9ic2VydmVyLkVSUk9SKSAhPSAwKXsKKyAgICAgICAgICAgICAgb2JzZXJ2ZXIuaW1hZ2VVcGRhdGUodGhpcywgSW1hZ2VPYnNlcnZlci5FUlJPUiB8CisgICAgICAgICAgICAgICAgICAgICAgSW1hZ2VPYnNlcnZlci5BQk9SVCwgLTEsIC0xLCAtMSwgLTEpOworICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgfQorICAgICAgICAgIGlmKChpbWFnZVN0YXRlICYgSW1hZ2VPYnNlcnZlci5BTExCSVRTKSAhPSAwKXsKKyAgICAgICAgICAgICAgb2JzZXJ2ZXIuaW1hZ2VVcGRhdGUodGhpcywgaW1hZ2VTdGF0ZSwgMCwgMCwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgb2JzZXJ2ZXJzLmFkZEVsZW1lbnQob2JzZXJ2ZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydFByb2R1Y3Rpb24oKXsKKyAgICAgICAgaWYoIXByb2R1Y2luZyl7CisgICAgICAgICAgICBpbWFnZVN0YXRlICY9IH5JbWFnZU9ic2VydmVyLkFCT1JUOworICAgICAgICAgICAgcHJvZHVjaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIHNyYy5zdGFydFByb2R1Y3Rpb24odGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHN0b3BQcm9kdWN0aW9uKCl7CisgICAgICAgIHByb2R1Y2luZyA9IGZhbHNlOworICAgICAgICBzcmMucmVtb3ZlQ29uc3VtZXIodGhpcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVJhc3RlcigpeworICAgICAgICB0cnl7CisgICAgICAgICAgICByYXN0ZXIgPSBjbS5jcmVhdGVDb21wYXRpYmxlV3JpdGFibGVSYXN0ZXIod2lkdGgsIGhlaWdodCk7CisgICAgICAgICAgICBpc0ludFJHQiA9IGZhbHNlOworICAgICAgICAgICAgaWYoY20gaW5zdGFuY2VvZiBEaXJlY3RDb2xvck1vZGVsKXsKKyAgICAgICAgICAgICAgICBEaXJlY3RDb2xvck1vZGVsIGRjbSA9IChEaXJlY3RDb2xvck1vZGVsKSBjbTsKKyAgICAgICAgICAgICAgICBpZihkY20uZ2V0VHJhbnNmZXJUeXBlKCkgPT0gRGF0YUJ1ZmZlci5UWVBFX0lOVCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgZGNtLmdldFJlZE1hc2soKSA9PSAweGZmMDAwMCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgZGNtLmdldEdyZWVuTWFzaygpID09IDB4ZmYwMCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgZGNtLmdldEJsdWVNYXNrKCkgPT0gMHhmZil7CisgICAgICAgICAgICAgICAgICAgIGlzSW50UkdCID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH1jYXRjaChFeGNlcHRpb24gZSl7CisgICAgICAgICAgICBjbSA9IENvbG9yTW9kZWwuZ2V0UkdCZGVmYXVsdCgpOworICAgICAgICAgICAgcmFzdGVyID0gY20uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHdpZHRoLCBoZWlnaHQpOworICAgICAgICAgICAgaXNJbnRSR0IgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSAvKnN5bmNocm9uaXplZCovIHZvaWQgaW1hZ2VVcGRhdGUoSW1hZ2UgaW1nLCBpbnQgaW5mb2ZsYWdzLCBpbnQgeCwgaW50IHksCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQpeworCisgICAgICAgIGltYWdlU3RhdGUgfD0gaW5mb2ZsYWdzOworICAgICAgICBmb3IgKEltYWdlT2JzZXJ2ZXIgb2JzZXJ2ZXIgOiBvYnNlcnZlcnMpIHsKKyAgICAgICAgICAgIG9ic2VydmVyLmltYWdlVXBkYXRlKHRoaXMsIGluZm9mbGFncywgeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgICAgIH0KKworLy8gICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZm9yY2VUb0ludEFSR0IoKXsKKworICAgICAgICBpbnQgdyA9IHJhc3Rlci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgaCA9IHJhc3Rlci5nZXRIZWlnaHQoKTsKKworICAgICAgICBXcml0YWJsZVJhc3RlciBkZXN0UmFzdGVyID0gcmdiQ00uY3JlYXRlQ29tcGF0aWJsZVdyaXRhYmxlUmFzdGVyKHcsIGgpOworCisgICAgICAgIE9iamVjdCBvYmogPSBudWxsOworICAgICAgICBpbnQgcGl4ZWxzW10gPSBuZXcgaW50W3ddOworCisgICAgICAgIGlmKGNtIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKXsKKyAgICAgICAgICAgIEluZGV4Q29sb3JNb2RlbCBpY20gPSAoSW5kZXhDb2xvck1vZGVsKSBjbTsKKyAgICAgICAgICAgIGludCBjb2xvck1hcFtdID0gbmV3IGludFtpY20uZ2V0TWFwU2l6ZSgpXTsKKyAgICAgICAgICAgIGljbS5nZXRSR0JzKGNvbG9yTWFwKTsKKworICAgICAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoOyB5KyspIHsKKyAgICAgICAgICAgICAgICBvYmogPSByYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKDAsIHksIHcsIDEsIG9iaik7CisgICAgICAgICAgICAgICAgYnl0ZSBiYVtdID0gKGJ5dGVbXSkgb2JqOworICAgICAgICAgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgYmEubGVuZ3RoOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW3hdID0gY29sb3JNYXBbYmFbeF0gJiAweGZmXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZGVzdFJhc3Rlci5zZXREYXRhRWxlbWVudHMoMCwgeSwgdywgMSwgcGl4ZWxzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGZvcihpbnQgeSA9IDA7IHkgPCBoOyB5KyspeworICAgICAgICAgICAgICAgIGZvcihpbnQgeCA9IDA7IHggPCB3OyB4KyspeworICAgICAgICAgICAgICAgICAgICBvYmogPSByYXN0ZXIuZ2V0RGF0YUVsZW1lbnRzKHgsIHksIG9iaik7CisgICAgICAgICAgICAgICAgICAgIHBpeGVsc1t4XSA9IGNtLmdldFJHQihvYmopOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBkZXN0UmFzdGVyLnNldERhdGFFbGVtZW50cygwLCB5LCB3LCAxLCBwaXhlbHMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkKHRoaXMpeworICAgICAgICAgICAgaWYoaW1hZ2VTdXJmICE9IG51bGwpeworICAgICAgICAgICAgICAgIGltYWdlU3VyZi5kaXNwb3NlKCk7CisgICAgICAgICAgICAgICAgaW1hZ2VTdXJmID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmKGltYWdlICE9IG51bGwpeworICAgICAgICAgICAgICAgIGltYWdlLmZsdXNoKCk7CisgICAgICAgICAgICAgICAgaW1hZ2UgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY20gPSByZ2JDTTsKKyAgICAgICAgICAgIHJhc3RlciA9IGRlc3RSYXN0ZXI7CisgICAgICAgICAgICBpc0ludFJHQiA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSW1hZ2VTdXJmYWNlIGdldEltYWdlU3VyZmFjZSgpIHsKKyAgICAgICAgaWYgKGltYWdlU3VyZiA9PSBudWxsKSB7CisgICAgICAgICAgICBDb2xvck1vZGVsIG1vZGVsID0gZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgV3JpdGFibGVSYXN0ZXIgd3IgPSBnZXRSYXN0ZXIoKTsKKyAgICAgICAgICAgIGlmKG1vZGVsICE9IG51bGwgJiYgd3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGltYWdlU3VyZiA9IG5ldyBJbWFnZVN1cmZhY2UobW9kZWwsIHdyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1hZ2VTdXJmOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL09yZGluYXJ5V3JpdGFibGVSYXN0ZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL09yZGluYXJ5V3JpdGFibGVSYXN0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzQ4ZTFiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvT3JkaW5hcnlXcml0YWJsZVJhc3Rlci5qYXZhCkBAIC0wLDAgKzEsMTUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKy8qCisgKiBDcmVhdGVkIG9uIDMwLjA5LjIwMDQKKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZTsKKworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5EYXRhQnVmZmVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5TYW1wbGVNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKKworcHVibGljIGNsYXNzIE9yZGluYXJ5V3JpdGFibGVSYXN0ZXIgZXh0ZW5kcyBXcml0YWJsZVJhc3RlciB7CisKKyAgICBwdWJsaWMgT3JkaW5hcnlXcml0YWJsZVJhc3RlcihTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCwKKyAgICAgICAgICAgIERhdGFCdWZmZXIgZGF0YUJ1ZmZlciwgUmVjdGFuZ2xlIGFSZWdpb24sCisgICAgICAgICAgICBQb2ludCBzYW1wbGVNb2RlbFRyYW5zbGF0ZSwgV3JpdGFibGVSYXN0ZXIgcGFyZW50KSB7CisgICAgICAgIHN1cGVyKHNhbXBsZU1vZGVsLCBkYXRhQnVmZmVyLCBhUmVnaW9uLCBzYW1wbGVNb2RlbFRyYW5zbGF0ZSwgcGFyZW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgT3JkaW5hcnlXcml0YWJsZVJhc3RlcihTYW1wbGVNb2RlbCBzYW1wbGVNb2RlbCwKKyAgICAgICAgICAgIERhdGFCdWZmZXIgZGF0YUJ1ZmZlciwgUG9pbnQgb3JpZ2luKSB7CisgICAgICAgIHN1cGVyKHNhbXBsZU1vZGVsLCBkYXRhQnVmZmVyLCBvcmlnaW4pOworICAgIH0KKworICAgIHB1YmxpYyBPcmRpbmFyeVdyaXRhYmxlUmFzdGVyKFNhbXBsZU1vZGVsIHNhbXBsZU1vZGVsLCBQb2ludCBvcmlnaW4pIHsKKyAgICAgICAgc3VwZXIoc2FtcGxlTW9kZWwsIG9yaWdpbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgT2JqZWN0IGluRGF0YSkgeworICAgICAgICBzdXBlci5zZXREYXRhRWxlbWVudHMoeCwgeSwgaW5EYXRhKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhRWxlbWVudHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIE9iamVjdCBpbkRhdGEpIHsKKyAgICAgICAgc3VwZXIuc2V0RGF0YUVsZW1lbnRzKHgsIHksIHcsIGgsIGluRGF0YSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVdyaXRhYmxlQ2hpbGQoaW50IHBhcmVudFgsIGludCBwYXJlbnRZLCBpbnQgdywKKyAgICAgICAgICAgIGludCBoLCBpbnQgY2hpbGRNaW5YLCBpbnQgY2hpbGRNaW5ZLCBpbnRbXSBiYW5kTGlzdCkgeworICAgICAgICByZXR1cm4gc3VwZXIuY3JlYXRlV3JpdGFibGVDaGlsZChwYXJlbnRYLCBwYXJlbnRZLCB3LCBoLCBjaGlsZE1pblgsCisgICAgICAgICAgICAgICAgY2hpbGRNaW5ZLCBiYW5kTGlzdCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGNyZWF0ZVdyaXRhYmxlVHJhbnNsYXRlZENoaWxkKGludCBjaGlsZE1pblgsCisgICAgICAgICAgICBpbnQgY2hpbGRNaW5ZKSB7CisgICAgICAgIHJldHVybiBzdXBlci5jcmVhdGVXcml0YWJsZVRyYW5zbGF0ZWRDaGlsZChjaGlsZE1pblgsIGNoaWxkTWluWSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFdyaXRhYmxlUmFzdGVyIGdldFdyaXRhYmxlUGFyZW50KCkgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0V3JpdGFibGVQYXJlbnQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSZWN0KFJhc3RlciBzcmNSYXN0ZXIpIHsKKyAgICAgICAgc3VwZXIuc2V0UmVjdChzcmNSYXN0ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlY3QoaW50IGR4LCBpbnQgZHksIFJhc3RlciBzcmNSYXN0ZXIpIHsKKyAgICAgICAgc3VwZXIuc2V0UmVjdChkeCwgZHksIHNyY1Jhc3Rlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGF0YUVsZW1lbnRzKGludCB4LCBpbnQgeSwgUmFzdGVyIGluUmFzdGVyKSB7CisgICAgICAgIHN1cGVyLnNldERhdGFFbGVtZW50cyh4LCB5LCBpblJhc3Rlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoaW50IHgsIGludCB5LCBpbnRbXSBpQXJyYXkpIHsKKyAgICAgICAgc3VwZXIuc2V0UGl4ZWwoeCwgeSwgaUFycmF5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChpbnQgeCwgaW50IHksIGZsb2F0W10gZkFycmF5KSB7CisgICAgICAgIHN1cGVyLnNldFBpeGVsKHgsIHksIGZBcnJheSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoaW50IHgsIGludCB5LCBkb3VibGVbXSBkQXJyYXkpIHsKKyAgICAgICAgc3VwZXIuc2V0UGl4ZWwoeCwgeSwgZEFycmF5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludFtdIGlBcnJheSkgeworICAgICAgICBzdXBlci5zZXRQaXhlbHMoeCwgeSwgdywgaCwgaUFycmF5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGZsb2F0W10gZkFycmF5KSB7CisgICAgICAgIHN1cGVyLnNldFBpeGVscyh4LCB5LCB3LCBoLCBmQXJyYXkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBpeGVscyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgZG91YmxlW10gZEFycmF5KSB7CisgICAgICAgIHN1cGVyLnNldFBpeGVscyh4LCB5LCB3LCBoLCBkQXJyYXkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBpbnRbXSBpQXJyYXkpIHsKKyAgICAgICAgc3VwZXIuc2V0U2FtcGxlcyh4LCB5LCB3LCBoLCBiLCBpQXJyYXkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNhbXBsZXMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCBiLCBmbG9hdFtdIGZBcnJheSkgeworICAgICAgICBzdXBlci5zZXRTYW1wbGVzKHgsIHksIHcsIGgsIGIsIGZBcnJheSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCwgaW50IGIsIGRvdWJsZVtdIGRBcnJheSkgeworICAgICAgICBzdXBlci5zZXRTYW1wbGVzKHgsIHksIHcsIGgsIGIsIGRBcnJheSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIGludCBzKSB7CisgICAgICAgIHN1cGVyLnNldFNhbXBsZSh4LCB5LCBiLCBzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTYW1wbGUoaW50IHgsIGludCB5LCBpbnQgYiwgZmxvYXQgcykgeworICAgICAgICBzdXBlci5zZXRTYW1wbGUoeCwgeSwgYiwgcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2FtcGxlKGludCB4LCBpbnQgeSwgaW50IGIsIGRvdWJsZSBzKSB7CisgICAgICAgIHN1cGVyLnNldFNhbXBsZSh4LCB5LCBiLCBzKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvUG5nRGVjb2Rlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvUG5nRGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlODU2MDAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9QbmdEZWNvZGVyLmphdmEKQEAgLTAsMCArMSwyNzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICoKKyAqIEBkYXRlOiBKdWwgMjIsIDIwMDUKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLio7CitpbXBvcnQgamF2YS5hd3QuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCitwdWJsaWMgY2xhc3MgUG5nRGVjb2RlciBleHRlbmRzIEltYWdlRGVjb2RlciB7CisgICAgLy8gaW5pdGlhbGl6ZXMgcHJvcGVyIGZpZWxkIElEcworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGluaXRJRHMoKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFN5c3RlbS5sb2FkTGlicmFyeSgiZ2wiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBpbml0SURzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGhpbnRmbGFncyA9CisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLlNJTkdMRUZSQU1FIHwgLy8gUE5HIGlzIGEgc3RhdGljIGltYWdlCisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLlRPUERPV05MRUZUUklHSFQgfCAvLyBUaGlzIG9yZGVyIGlzIG9ubHkgb25lIHBvc3NpYmxlCisgICAgICAgICAgICBJbWFnZUNvbnN1bWVyLkNPTVBMRVRFU0NBTkxJTkVTOyAvLyBEb24ndCBkZWxpdmVyIGluY29tcGxldGUgc2NhbmxpbmVzCisKKyAgICAvLyBFYWNoIHBpeGVsIGlzIGEgZ3JheXNjYWxlIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfR1JBWSA9IDA7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhbiBSLEcsQiB0cmlwbGUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX1JHQiA9IDI7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhIHBhbGV0dGUgaW5kZXgsIGEgUExURSBjaHVuayBtdXN0IGFwcGVhci4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfUExURSA9IDM7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhIGdyYXlzY2FsZSBzYW1wbGUsIGZvbGxvd2VkIGJ5IGFuIGFscGhhIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfR1JBWV9BTFBIQSA9IDQ7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhbiBSLEcsQiB0cmlwbGUsIGZvbGxvd2VkIGJ5IGFuIGFscGhhIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfUkdCQSA9IDY7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5QVVRfQlVGRkVSX1NJWkUgPSA0MDk2OworICAgIHByaXZhdGUgYnl0ZSBidWZmZXJbXSA9IG5ldyBieXRlW0lOUFVUX0JVRkZFUl9TSVpFXTsKKworICAgIC8vIEJ1ZmZlcnMgZm9yIGRlY29kZWQgaW1hZ2UgZGF0YQorICAgIGJ5dGUgYnl0ZU91dFtdOworICAgIGludCBpbnRPdXRbXTsKKworICAgIC8vIE5hdGl2ZSBwb2ludGVyIHRvIHBuZyBkZWNvZGVyIGRhdGEKKyAgICBwcml2YXRlIGxvbmcgaE5hdGl2ZURlY29kZXI7CisKKyAgICBpbnQgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQ7CisgICAgaW50IGNvbG9yVHlwZTsKKyAgICBpbnQgYml0RGVwdGg7CisgICAgYnl0ZSBjbWFwW107CisKKyAgICBib29sZWFuIHRyYW5zZmVySW50czsgLy8gSXMgdHJhbnNmZXIgdHlwZSBpbnQ/Li4gb3IgYnl0ZT8KKyAgICBpbnQgZGF0YUVsZW1lbnRzUGVyUGl4ZWwgPSAxOworCisgICAgQ29sb3JNb2RlbCBjbTsKKworICAgIGludCB1cGRhdGVGcm9tU2NhbmxpbmU7IC8vIEZpcnN0IHNjYW5saW5lIHRvIHVwZGF0ZQorICAgIGludCBudW1TY2FubGluZXM7IC8vIE51bWJlciBvZiBzY2FubGluZXMgdG8gdXBkYXRlCisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIGRlY29kZShieXRlW10gaW5wdXQsIGludCBieXRlc0luQnVmZmVyLCBsb25nIGhEZWNvZGVyKTsKKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHJlbGVhc2VOYXRpdmVEZWNvZGVyKGxvbmcgaERlY29kZXIpOworCisgICAgcHVibGljIFBuZ0RlY29kZXIoRGVjb2RpbmdJbWFnZVNvdXJjZSBzcmMsIElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgIHN1cGVyKHNyYywgaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRlY29kZUltYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBieXRlc1JlYWQgPSAwOworICAgICAgICAgICAgaW50IG5lZWRCeXRlcywgb2Zmc2V0LCBieXRlc0luQnVmZmVyID0gMDsKKyAgICAgICAgICAgIC8vIFJlYWQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgbmVlZEJ5dGVzID0gSU5QVVRfQlVGRkVSX1NJWkUgLSBieXRlc0luQnVmZmVyOworICAgICAgICAgICAgICAgIG9mZnNldCA9IGJ5dGVzSW5CdWZmZXI7CisKKyAgICAgICAgICAgICAgICBieXRlc1JlYWQgPSBpbnB1dFN0cmVhbS5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBuZWVkQnl0ZXMpOworCisgICAgICAgICAgICAgICAgaWYgKGJ5dGVzUmVhZCA8IDApIHsgLy8gQnJlYWssIG5vdGhpbmcgdG8gcmVhZCBmcm9tIGJ1ZmZlciwgaW1hZ2UgdHJ1bmNhdGVkPworICAgICAgICAgICAgICAgICAgICByZWxlYXNlTmF0aXZlRGVjb2RlcihoTmF0aXZlRGVjb2Rlcik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIEtlZXAgdHJhY2sgb24gaG93IG11Y2ggYnl0ZXMgbGVmdCBpbiBidWZmZXIKKyAgICAgICAgICAgICAgICBieXRlc0luQnVmZmVyICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICBoTmF0aXZlRGVjb2RlciA9IGRlY29kZShidWZmZXIsIGJ5dGVzSW5CdWZmZXIsIGhOYXRpdmVEZWNvZGVyKTsKKyAgICAgICAgICAgICAgICAvLyBQTkcgZGVjb2RlciBhbHdheXMgY29uc3VtZXMgYWxsIGJ5dGVzIGF0IG9uY2UKKyAgICAgICAgICAgICAgICBieXRlc0luQnVmZmVyID0gMDsKKworICAgICAgICAgICAgICAgIC8vIGlmIChieXRlc0NvbnN1bWVkIDwgMCkKKyAgICAgICAgICAgICAgICAvL2JyZWFrOyAvLyBFcnJvciBleGl0CisKKyAgICAgICAgICAgICAgICByZXR1cm5EYXRhKCk7CisKKyAgICAgICAgICAgICAgICAvLyBPSywgd2UgZGVjb2RlZCBhbGwgdGhlIHBpY3R1cmUgaW4gdGhlIHJpZ2h0IHdheS4uLgorICAgICAgICAgICAgICAgIGlmIChoTmF0aXZlRGVjb2RlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLlNUQVRJQ0lNQUdFRE9ORSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaW1hZ2VDb21wbGV0ZShJbWFnZUNvbnN1bWVyLklNQUdFRVJST1IpOworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGNsb3NlU3RyZWFtKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmV0dXJuSGVhZGVyKCkgeyAvLyBDYWxsZWQgZnJvbSBuYXRpdmUgY29kZQorICAgICAgICBzZXREaW1lbnNpb25zKGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0KTsKKworICAgICAgICBzd2l0Y2ggKGNvbG9yVHlwZSkgeworICAgICAgICAgICAgY2FzZSBQTkdfQ09MT1JfVFlQRV9HUkFZOiB7CisgICAgICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gNCAmJiBiaXREZXB0aCAhPSAyICYmIGJpdERlcHRoICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjNDPVVua25vd24gUE5HIGNvbG9yIHR5cGUKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBncmF5IGNvbG9yIG1vZGVsCisgICAgICAgICAgICAgICAgaW50IG51bUVudHJpZXMgPSAxIDw8IGJpdERlcHRoOworICAgICAgICAgICAgICAgIGludCBzY2FsZUZhY3RvciA9IDI1NSAvIChudW1FbnRyaWVzLTEpOworICAgICAgICAgICAgICAgIGJ5dGUgY29tcHNbXSA9IG5ldyBieXRlW251bUVudHJpZXNdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtRW50cmllczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbXBzW2ldID0gKGJ5dGUpIChpICogc2NhbGVGYWN0b3IpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBJbmRleENvbG9yTW9kZWwoLypiaXREZXB0aCovOCwgbnVtRW50cmllcywgY29tcHMsIGNvbXBzLCBjb21wcyk7CisKKyAgICAgICAgICAgICAgICB0cmFuc2ZlckludHMgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FzZSBQTkdfQ09MT1JfVFlQRV9SR0I6IHsKKyAgICAgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0M9VW5rbm93biBQTkcgY29sb3IgdHlwZQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY20gPSBuZXcgRGlyZWN0Q29sb3JNb2RlbCgyNCwgMHhGRjAwMDAsIDB4RkYwMCwgMHhGRik7CisKKyAgICAgICAgICAgICAgICB0cmFuc2ZlckludHMgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIFBOR19DT0xPUl9UWVBFX1BMVEU6IHsKKyAgICAgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCAmJiBiaXREZXB0aCAhPSA0ICYmIGJpdERlcHRoICE9IDIgJiYgYml0RGVwdGggIT0gMSkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0M9VW5rbm93biBQTkcgY29sb3IgdHlwZQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY20gPSBuZXcgSW5kZXhDb2xvck1vZGVsKC8qYml0RGVwdGgqLzgsIGNtYXAubGVuZ3RoIC8gMywgY21hcCwgMCwgZmFsc2UpOworCisgICAgICAgICAgICAgICAgdHJhbnNmZXJJbnRzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgUE5HX0NPTE9SX1RZUEVfR1JBWV9BTFBIQTogeworICAgICAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSA4KSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuM0MiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBjbSA9IG5ldyBDb21wb25lbnRDb2xvck1vZGVsKENvbG9yU3BhY2UuZ2V0SW5zdGFuY2UoQ29sb3JTcGFjZS5DU19HUkFZKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNwYXJlbmN5LlRSQU5TTFVDRU5ULAorICAgICAgICAgICAgICAgICAgICAgICAgRGF0YUJ1ZmZlci5UWVBFX0JZVEUpOworCisgICAgICAgICAgICAgICAgdHJhbnNmZXJJbnRzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZGF0YUVsZW1lbnRzUGVyUGl4ZWwgPSAyOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYXNlIFBOR19DT0xPUl9UWVBFX1JHQkE6IHsKKyAgICAgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhd3QuM0M9VW5rbm93biBQTkcgY29sb3IgdHlwZQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjNDIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY20gPSBDb2xvck1vZGVsLmdldFJHQmRlZmF1bHQoKTsKKworICAgICAgICAgICAgICAgIHRyYW5zZmVySW50cyA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIGF3dC4zQz1Vbmtub3duIFBORyBjb2xvciB0eXBlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zQyIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAgLy8gQ3JlYXRlIG91dHB1dCBidWZmZXIKKyAgICAgICAgaWYgKHRyYW5zZmVySW50cykgeworICAgICAgICAgICAgaW50T3V0ID0gbmV3IGludFtpbWFnZVdpZHRoICogaW1hZ2VIZWlnaHRdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnl0ZU91dCA9IG5ldyBieXRlW2ltYWdlV2lkdGggKiBpbWFnZUhlaWdodCAqIGRhdGFFbGVtZW50c1BlclBpeGVsXTsKKyAgICAgICAgfQorCisgICAgICAgIHNldENvbG9yTW9kZWwoY20pOworCisgICAgICAgIHNldEhpbnRzKGhpbnRmbGFncyk7CisgICAgICAgIHNldFByb3BlcnRpZXMobmV3IEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4oKSk7IC8vIEVtcHR5CisgICAgfQorCisgICAgLy8gU2VuZCB0aGUgZGF0YSB0byB0aGUgY29uc3VtZXIKKyAgICBwcml2YXRlIHZvaWQgcmV0dXJuRGF0YSgpIHsKKyAgICAgICAgLy8gU2VuZCAxIG9yIG1vcmUgc2NhbmxpbmVzIHRvIHRoZSBjb25zdW1lci4KKyAgICAgICAgaWYgKG51bVNjYW5saW5lcyA+IDApIHsKKyAgICAgICAgICAgIC8vIE5hdGl2ZSBkZWNvZGVyIGNvdWxkIGhhdmUgcmV0dXJuZWQKKyAgICAgICAgICAgIC8vIHNvbWUgZGF0YSBmcm9tIHRoZSBuZXh0IHBhc3MsIGhhbmRsZSBpdCBoZXJlCisgICAgICAgICAgICBpbnQgcGFzczEsIHBhc3MyOworICAgICAgICAgICAgaWYgKHVwZGF0ZUZyb21TY2FubGluZSArIG51bVNjYW5saW5lcyA+IGltYWdlSGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgcGFzczEgPSBpbWFnZUhlaWdodCAtIHVwZGF0ZUZyb21TY2FubGluZTsKKyAgICAgICAgICAgICAgICBwYXNzMiA9IHVwZGF0ZUZyb21TY2FubGluZSArIG51bVNjYW5saW5lcyAtIGltYWdlSGVpZ2h0OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwYXNzMSA9IG51bVNjYW5saW5lczsKKyAgICAgICAgICAgICAgICBwYXNzMiA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyYW5zZmVyKHVwZGF0ZUZyb21TY2FubGluZSwgcGFzczEpOworICAgICAgICAgICAgaWYgKHBhc3MyICE9IDApIHsKKyAgICAgICAgICAgICAgICB0cmFuc2ZlcigwLCBwYXNzMik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmZXIoaW50IHVwZGF0ZUZyb21TY2FubGluZSwgaW50IG51bVNjYW5saW5lcykgeworICAgICAgICBpZiAodHJhbnNmZXJJbnRzKSB7CisgICAgICAgICAgICBzZXRQaXhlbHMoCisgICAgICAgICAgICAgICAgICAgIDAsIHVwZGF0ZUZyb21TY2FubGluZSwKKyAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aCwgbnVtU2NhbmxpbmVzLAorICAgICAgICAgICAgICAgICAgICBjbSwgaW50T3V0LAorICAgICAgICAgICAgICAgICAgICB1cGRhdGVGcm9tU2NhbmxpbmUgKiBpbWFnZVdpZHRoLAorICAgICAgICAgICAgICAgICAgICBpbWFnZVdpZHRoCisgICAgICAgICAgICApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0UGl4ZWxzKAorICAgICAgICAgICAgICAgICAgICAwLCB1cGRhdGVGcm9tU2NhbmxpbmUsCisgICAgICAgICAgICAgICAgICAgIGltYWdlV2lkdGgsIG51bVNjYW5saW5lcywKKyAgICAgICAgICAgICAgICAgICAgY20sIGJ5dGVPdXQsCisgICAgICAgICAgICAgICAgICAgIHVwZGF0ZUZyb21TY2FubGluZSAqIGltYWdlV2lkdGggKiBkYXRhRWxlbWVudHNQZXJQaXhlbCwKKyAgICAgICAgICAgICAgICAgICAgaW1hZ2VXaWR0aCAqIGRhdGFFbGVtZW50c1BlclBpeGVsCisgICAgICAgICAgICApOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvaW1hZ2UvUG5nRGVjb2RlckphdmEuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL1BuZ0RlY29kZXJKYXZhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY1NDVmOQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL1BuZ0RlY29kZXJKYXZhLmphdmEKQEAgLTAsMCArMSwyODIgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZTsKKworLy8gQSBzaW1wbGUgUE5HIGRlY29kZXIgc291cmNlIGNvZGUgaW4gSmF2YS4KK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKK2ltcG9ydCBqYXZhLmF3dC5JbnNldHM7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXI7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckJ5dGU7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuSW5kZXhDb2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5DUkMzMjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkluZmxhdGVySW5wdXRTdHJlYW07CisKKy8vaW1wb3J0IGphdmF4LnN3aW5nLkpGcmFtZTsKKworcHVibGljIGNsYXNzIFBuZ0RlY29kZXJKYXZhIHsKKyAKKy8qCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBuYW1lID0gImxvZ28ucG5nIjsKKyAgICBpZiAoYXJncy5sZW5ndGggPiAwKQorICAgICAgbmFtZSA9IGFyZ3NbMF07CisgICAgSW5wdXRTdHJlYW0gaW4gPSBQbmdEZWNvZGVySmF2YS5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOworICAgIGZpbmFsIEJ1ZmZlcmVkSW1hZ2UgaW1hZ2UgPSBQbmdEZWNvZGVySmF2YS5kZWNvZGUoaW4pOworICAgIGluLmNsb3NlKCk7CisKKyAgICBKRnJhbWUgZiA9IG5ldyBKRnJhbWUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBwYWludChHcmFwaGljcyBnKSB7CisgICAgICAgIEluc2V0cyBpbnNldHMgPSBnZXRJbnNldHMoKTsKKyAgICAgICAgZy5kcmF3SW1hZ2UoaW1hZ2UsIGluc2V0cy5sZWZ0LCBpbnNldHMudG9wLCBudWxsKTsKKyAgICAgIH0KKyAgICB9OworICAgIGYuc2V0VmlzaWJsZSh0cnVlKTsKKyAgICBJbnNldHMgaW5zZXRzID0gZi5nZXRJbnNldHMoKTsKKyAgICBmLnNldFNpemUoaW1hZ2UuZ2V0V2lkdGgoKSArIGluc2V0cy5sZWZ0ICsgaW5zZXRzLnJpZ2h0LCBpbWFnZQorICAgICAgICAuZ2V0SGVpZ2h0KCkKKyAgICAgICAgKyBpbnNldHMudG9wICsgaW5zZXRzLmJvdHRvbSk7CisgIH0KKyAgKi8KKworICBwdWJsaWMgc3RhdGljIEJ1ZmZlcmVkSW1hZ2UgZGVjb2RlKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIERhdGFJbnB1dFN0cmVhbSBkYXRhSW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKGluKTsKKyAgICByZWFkU2lnbmF0dXJlKGRhdGFJbik7CisgICAgUE5HRGF0YSBjaHVua3MgPSByZWFkQ2h1bmtzKGRhdGFJbik7CisKKyAgICBsb25nIHdpZHRoTG9uZyA9IGNodW5rcy5nZXRXaWR0aCgpOworICAgIGxvbmcgaGVpZ2h0TG9uZyA9IGNodW5rcy5nZXRIZWlnaHQoKTsKKyAgICBpZiAod2lkdGhMb25nID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgaGVpZ2h0TG9uZyA+IEludGVnZXIuTUFYX1ZBTFVFKQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGF0IGltYWdlIGlzIHRvbyB3aWRlIG9yIHRhbGwuIik7CisgICAgaW50IHdpZHRoID0gKGludCkgd2lkdGhMb25nOworICAgIGludCBoZWlnaHQgPSAoaW50KSBoZWlnaHRMb25nOworCisgICAgQ29sb3JNb2RlbCBjbSA9IGNodW5rcy5nZXRDb2xvck1vZGVsKCk7CisgICAgV3JpdGFibGVSYXN0ZXIgcmFzdGVyID0gY2h1bmtzLmdldFJhc3RlcigpOworCisgICAgQnVmZmVyZWRJbWFnZSBpbWFnZSA9IG5ldyBCdWZmZXJlZEltYWdlKGNtLCByYXN0ZXIsIGZhbHNlLCBudWxsKTsKKworICAgIHJldHVybiBpbWFnZTsKKyAgfQorCisgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCByZWFkU2lnbmF0dXJlKERhdGFJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIHNpZ25hdHVyZSA9IGluLnJlYWRMb25nKCk7CisgICAgaWYgKHNpZ25hdHVyZSAhPSAweDg5NTA0ZTQ3MGQwYTFhMGFMKQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQTkcgc2lnbmF0dXJlIG5vdCBmb3VuZCEiKTsKKyAgfQorCisgIHByb3RlY3RlZCBzdGF0aWMgUE5HRGF0YSByZWFkQ2h1bmtzKERhdGFJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQTkdEYXRhIGNodW5rcyA9IG5ldyBQTkdEYXRhKCk7CisKKyAgICBib29sZWFuIHRydWNraW5nID0gdHJ1ZTsKKyAgICB3aGlsZSAodHJ1Y2tpbmcpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIC8vIFJlYWQgdGhlIGxlbmd0aC4KKyAgICAgICAgaW50IGxlbmd0aCA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA8IDApCisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTb3JyeSwgdGhhdCBmaWxlIGlzIHRvbyBsb25nLiIpOworICAgICAgICAvLyBSZWFkIHRoZSB0eXBlLgorICAgICAgICBieXRlW10gdHlwZUJ5dGVzID0gbmV3IGJ5dGVbNF07CisgICAgICAgIGluLnJlYWRGdWxseSh0eXBlQnl0ZXMpOworICAgICAgICAvLyBSZWFkIHRoZSBkYXRhLgorICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIGluLnJlYWRGdWxseShkYXRhKTsKKyAgICAgICAgLy8gUmVhZCB0aGUgQ1JDLgorICAgICAgICBsb25nIGNyYyA9IGluLnJlYWRJbnQoKSAmIDB4MDAwMDAwMDBmZmZmZmZmZkw7IC8vIE1ha2UgaXQKKyAgICAgICAgLy8gdW5zaWduZWQuCisgICAgICAgIGlmICh2ZXJpZnlDUkModHlwZUJ5dGVzLCBkYXRhLCBjcmMpID09IGZhbHNlKQorICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhhdCBmaWxlIGFwcGVhcnMgdG8gYmUgY29ycnVwdGVkLiIpOworCisgICAgICAgIFBOR0NodW5rIGNodW5rID0gbmV3IFBOR0NodW5rKHR5cGVCeXRlcywgZGF0YSk7CisgICAgICAgIGNodW5rcy5hZGQoY2h1bmspOworICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVvZmUpIHsKKyAgICAgICAgdHJ1Y2tpbmcgPSBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGNodW5rczsKKyAgfQorCisgIHByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiB2ZXJpZnlDUkMoYnl0ZVtdIHR5cGVCeXRlcywgYnl0ZVtdIGRhdGEsIGxvbmcgY3JjKSB7CisgICAgQ1JDMzIgY3JjMzIgPSBuZXcgQ1JDMzIoKTsKKyAgICBjcmMzMi51cGRhdGUodHlwZUJ5dGVzKTsKKyAgICBjcmMzMi51cGRhdGUoZGF0YSk7CisgICAgbG9uZyBjYWxjdWxhdGVkID0gY3JjMzIuZ2V0VmFsdWUoKTsKKyAgICByZXR1cm4gKGNhbGN1bGF0ZWQgPT0gY3JjKTsKKyAgfQorfQorCitjbGFzcyBQTkdEYXRhIHsKKyAgcHJpdmF0ZSBpbnQgbU51bWJlck9mQ2h1bmtzOworCisgIHByaXZhdGUgUE5HQ2h1bmtbXSBtQ2h1bmtzOworCisgIHB1YmxpYyBQTkdEYXRhKCkgeworICAgIG1OdW1iZXJPZkNodW5rcyA9IDA7CisgICAgbUNodW5rcyA9IG5ldyBQTkdDaHVua1sxMF07CisgIH0KKworICBwdWJsaWMgdm9pZCBhZGQoUE5HQ2h1bmsgY2h1bmspIHsKKyAgICBtQ2h1bmtzW21OdW1iZXJPZkNodW5rcysrXSA9IGNodW5rOworICAgIGlmIChtTnVtYmVyT2ZDaHVua3MgPj0gbUNodW5rcy5sZW5ndGgpIHsKKyAgICAgIFBOR0NodW5rW10gbGFyZ2VyQXJyYXkgPSBuZXcgUE5HQ2h1bmtbbUNodW5rcy5sZW5ndGggKyAxMF07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1DaHVua3MsIDAsIGxhcmdlckFycmF5LCAwLCBtQ2h1bmtzLmxlbmd0aCk7CisgICAgICBtQ2h1bmtzID0gbGFyZ2VyQXJyYXk7CisgICAgfQorICB9CisKKyAgcHVibGljIGxvbmcgZ2V0V2lkdGgoKSB7CisgICAgcmV0dXJuIGdldENodW5rKCJJSERSIikuZ2V0VW5zaWduZWRJbnQoMCk7CisgIH0KKworICBwdWJsaWMgbG9uZyBnZXRIZWlnaHQoKSB7ICAgIHJldHVybiBnZXRDaHVuaygiSUhEUiIpLmdldFVuc2lnbmVkSW50KDQpOworICB9CisKKyAgcHVibGljIHNob3J0IGdldEJpdHNQZXJQaXhlbCgpIHsKKyAgICByZXR1cm4gZ2V0Q2h1bmsoIklIRFIiKS5nZXRVbnNpZ25lZEJ5dGUoOCk7CisgIH0KKworICBwdWJsaWMgc2hvcnQgZ2V0Q29sb3JUeXBlKCkgeworICAgIHJldHVybiBnZXRDaHVuaygiSUhEUiIpLmdldFVuc2lnbmVkQnl0ZSg5KTsKKyAgfQorCisgIHB1YmxpYyBzaG9ydCBnZXRDb21wcmVzc2lvbigpIHsKKyAgICByZXR1cm4gZ2V0Q2h1bmsoIklIRFIiKS5nZXRVbnNpZ25lZEJ5dGUoMTApOworICB9CisKKyAgcHVibGljIHNob3J0IGdldEZpbHRlcigpIHsKKyAgICByZXR1cm4gZ2V0Q2h1bmsoIklIRFIiKS5nZXRVbnNpZ25lZEJ5dGUoMTEpOworICB9CisKKyAgcHVibGljIHNob3J0IGdldEludGVybGFjZSgpIHsKKyAgICByZXR1cm4gZ2V0Q2h1bmsoIklIRFIiKS5nZXRVbnNpZ25lZEJ5dGUoMTIpOworICB9CisKKyAgcHVibGljIENvbG9yTW9kZWwgZ2V0Q29sb3JNb2RlbCgpIHsKKyAgICBzaG9ydCBjb2xvclR5cGUgPSBnZXRDb2xvclR5cGUoKTsKKyAgICBpbnQgYml0c1BlclBpeGVsID0gZ2V0Qml0c1BlclBpeGVsKCk7CisKKyAgICBpZiAoY29sb3JUeXBlID09IDMpIHsKKyAgICAgIGJ5dGVbXSBwYWxldHRlRGF0YSA9IGdldENodW5rKCJQTFRFIikuZ2V0RGF0YSgpOworICAgICAgaW50IHBhbGV0dGVMZW5ndGggPSBwYWxldHRlRGF0YS5sZW5ndGggLyAzOworICAgICAgcmV0dXJuIG5ldyBJbmRleENvbG9yTW9kZWwoYml0c1BlclBpeGVsLCBwYWxldHRlTGVuZ3RoLAorICAgICAgICAgIHBhbGV0dGVEYXRhLCAwLCBmYWxzZSk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVW5zdXBwb3J0ZWQgY29sb3IgdHlwZTogIiArIGNvbG9yVHlwZSk7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBwdWJsaWMgV3JpdGFibGVSYXN0ZXIgZ2V0UmFzdGVyKCkgeworICAgIGludCB3aWR0aCA9IChpbnQpIGdldFdpZHRoKCk7CisgICAgaW50IGhlaWdodCA9IChpbnQpIGdldEhlaWdodCgpOworICAgIGludCBiaXRzUGVyUGl4ZWwgPSBnZXRCaXRzUGVyUGl4ZWwoKTsKKyAgICBzaG9ydCBjb2xvclR5cGUgPSBnZXRDb2xvclR5cGUoKTsKKworICAgIGlmIChjb2xvclR5cGUgPT0gMykgeworICAgICAgYnl0ZVtdIGltYWdlRGF0YSA9IGdldEltYWdlRGF0YSgpOworICAgICAgLy9PcmlnOiBEYXRhQnVmZmVyIGRiID0gbmV3IERhdGFCdWZmZXJCeXRlKGltYWdlRGF0YSwgaW1hZ2VEYXRhLmxlbmd0aCk7CisgICAgICBpbnQgbGVuID0gTWF0aC5tYXgoaW1hZ2VEYXRhLmxlbmd0aCwgKHdpZHRoIC0gMSkgKiAoaGVpZ2h0IC0xKSk7CisgICAgICBEYXRhQnVmZmVyIGRiID0gbmV3IERhdGFCdWZmZXJCeXRlKGltYWdlRGF0YSwgbGVuKTsKKyAgICAgIFdyaXRhYmxlUmFzdGVyIHJhc3RlciA9IFJhc3Rlci5jcmVhdGVQYWNrZWRSYXN0ZXIoZGIsIHdpZHRoLAorICAgICAgICAgIGhlaWdodCwgYml0c1BlclBpeGVsLCBudWxsKTsKKyAgICAgIHJldHVybiByYXN0ZXI7CisgICAgfSBlbHNlCisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlVuc3VwcG9ydGVkIGNvbG9yIHR5cGUhIik7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGdldEltYWdlRGF0YSgpIHsKKyAgICB0cnkgeworICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIC8vIFdyaXRlIGFsbCB0aGUgSURBVCBkYXRhIGludG8gdGhlIGFycmF5LgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtTnVtYmVyT2ZDaHVua3M7IGkrKykgeworICAgICAgICBQTkdDaHVuayBjaHVuayA9IG1DaHVua3NbaV07CisgICAgICAgIGlmIChjaHVuay5nZXRUeXBlU3RyaW5nKCkuZXF1YWxzKCJJREFUIikpIHsKKyAgICAgICAgICBvdXQud3JpdGUoY2h1bmsuZ2V0RGF0YSgpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAvLyBOb3cgZGVmbGF0ZSB0aGUgZGF0YS4KKyAgICAgIEluZmxhdGVySW5wdXRTdHJlYW0gaW4gPSBuZXcgSW5mbGF0ZXJJbnB1dFN0cmVhbSgKKyAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob3V0LnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBpbmZsYXRlZE91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIGludCByZWFkTGVuZ3RoOworICAgICAgYnl0ZVtdIGJsb2NrID0gbmV3IGJ5dGVbODE5Ml07CisgICAgICB3aGlsZSAoKHJlYWRMZW5ndGggPSBpbi5yZWFkKGJsb2NrKSkgIT0gLTEpCisgICAgICAgIGluZmxhdGVkT3V0LndyaXRlKGJsb2NrLCAwLCByZWFkTGVuZ3RoKTsKKyAgICAgIGluZmxhdGVkT3V0LmZsdXNoKCk7CisgICAgICBieXRlW10gaW1hZ2VEYXRhID0gaW5mbGF0ZWRPdXQudG9CeXRlQXJyYXkoKTsKKyAgICAgIC8vIENvbXB1dGUgdGhlIHJlYWwgbGVuZ3RoLgorICAgICAgaW50IHdpZHRoID0gKGludCkgZ2V0V2lkdGgoKTsKKyAgICAgIGludCBoZWlnaHQgPSAoaW50KSBnZXRIZWlnaHQoKTsKKyAgICAgIGludCBiaXRzUGVyUGl4ZWwgPSBnZXRCaXRzUGVyUGl4ZWwoKTsKKyAgICAgIGludCBsZW5ndGggPSB3aWR0aCAqIGhlaWdodCAqIGJpdHNQZXJQaXhlbCAvIDg7CisKKyAgICAgIGJ5dGVbXSBwcnVuZWREYXRhID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKworICAgICAgLy8gV2UgY2FuIG9ubHkgZGVhbCB3aXRoIG5vbi1pbnRlcmxhY2VkIGltYWdlcy4KKyAgICAgIGlmIChnZXRJbnRlcmxhY2UoKSA9PSAwKSB7CisgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICBpZiAoKGkgKiA4IC8gYml0c1BlclBpeGVsKSAlIHdpZHRoID09IDApIHsKKyAgICAgICAgICAgIGluZGV4Kys7IC8vIFNraXAgdGhlIGZpbHRlciBieXRlLgorICAgICAgICAgIH0KKyAgICAgICAgICBwcnVuZWREYXRhW2ldID0gaW1hZ2VEYXRhW2luZGV4KytdOworICAgICAgICB9CisgICAgICB9IGVsc2UKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDb3VsZG4ndCB1bmRvIGludGVybGFjaW5nLiIpOworCisgICAgICByZXR1cm4gcHJ1bmVkRGF0YTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBwdWJsaWMgUE5HQ2h1bmsgZ2V0Q2h1bmsoU3RyaW5nIHR5cGUpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1OdW1iZXJPZkNodW5rczsgaSsrKQorICAgICAgaWYgKG1DaHVua3NbaV0uZ2V0VHlwZVN0cmluZygpLmVxdWFscyh0eXBlKSkKKyAgICAgICAgcmV0dXJuIG1DaHVua3NbaV07CisgICAgcmV0dXJuIG51bGw7CisgIH0KK30KKworY2xhc3MgUE5HQ2h1bmsgeworICBwcml2YXRlIGJ5dGVbXSBtVHlwZTsKKworICBwcml2YXRlIGJ5dGVbXSBtRGF0YTsKKworICBwdWJsaWMgUE5HQ2h1bmsoYnl0ZVtdIHR5cGUsIGJ5dGVbXSBkYXRhKSB7CisgICAgbVR5cGUgPSB0eXBlOworICAgIG1EYXRhID0gZGF0YTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIG5ldyBTdHJpbmcobVR5cGUsICJVVEY4Iik7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1ZWUpIHsKKyAgICAgIHJldHVybiAiIjsKKyAgICB9CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoKSB7CisgICAgcmV0dXJuIG1EYXRhOworICB9CisKKyAgcHVibGljIGxvbmcgZ2V0VW5zaWduZWRJbnQoaW50IG9mZnNldCkgeworICAgIGxvbmcgdmFsdWUgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKQorICAgICAgdmFsdWUgKz0gKG1EYXRhW29mZnNldCArIGldICYgMHhmZikgPDwgKCgzIC0gaSkgKiA4KTsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKworICBwdWJsaWMgc2hvcnQgZ2V0VW5zaWduZWRCeXRlKGludCBvZmZzZXQpIHsKKyAgICByZXR1cm4gKHNob3J0KSAobURhdGFbb2Zmc2V0XSAmIDB4MDBmZik7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9VUkxEZWNvZGluZ0ltYWdlU291cmNlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9pbWFnZS9VUkxEZWNvZGluZ0ltYWdlU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTE4OTlkNgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL2ltYWdlL1VSTERlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElnb3IgVi4gU3RvbHlhcm92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKy8qCisgKiBDcmVhdGVkIG9uIDEwLjAyLjIwMDUKKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworCitwdWJsaWMgY2xhc3MgVVJMRGVjb2RpbmdJbWFnZVNvdXJjZSBleHRlbmRzIERlY29kaW5nSW1hZ2VTb3VyY2UgeworCisgICAgVVJMIHVybDsKKworICAgIHB1YmxpYyBVUkxEZWNvZGluZ0ltYWdlU291cmNlKFVSTCB1cmwpeworICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIGlmIChzZWN1cml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICBzZWN1cml0eS5jaGVja0Nvbm5lY3QodXJsLmdldEhvc3QoKSwgdXJsLmdldFBvcnQoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFBlcm1pc3Npb24gcCA9IHVybC5vcGVuQ29ubmVjdGlvbigpLmdldFBlcm1pc3Npb24oKTsKKyAgICAgICAgICAgICAgICBzZWN1cml0eS5jaGVja1Blcm1pc3Npb24ocCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy51cmwgPSB1cmw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gY2hlY2tDb25uZWN0aW9uKCkgeworICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIGlmIChzZWN1cml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNlY3VyaXR5LmNoZWNrQ29ubmVjdCh1cmwuZ2V0SG9zdCgpLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICB0cnl7CisgICAgICAgICAgICBVUkxDb25uZWN0aW9uIHVjID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLW1vZGlmaWVkCisgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0odWMuZ2V0SW5wdXRTdHJlYW0oKSwgODE5Mik7CisgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1tb2RpZmllZAorICAgICAgICB9Y2F0Y2goSU9FeGNlcHRpb24gZSl7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL0JsaXR0ZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9CbGl0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2I4MDEyZQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9CbGl0dGVyLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICogQ3JlYXRlZCBvbiAxNC4xMS4yMDA1CisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyOworCitpbXBvcnQgamF2YS5hd3QuQ29sb3I7CitpbXBvcnQgamF2YS5hd3QuQ29tcG9zaXRlOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuU3VyZmFjZTsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciBvYmplY3RzIHdoaWNoIGNhbiBkcmF3aW5nIEltYWdlcyBvbiBvdGhlciBJbWFnZXMgd2hpY2ggaGF2ZSAKKyAqIEdyYXBoaWNzIG9yIG9uIHRoZSBkaXNwbGF5LiAgCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQmxpdHRlciB7CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLAorICAgICAgICAgICAgaW50IGRzdFgsIGludCBkc3RZLCBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSBzeXN4Zm9ybSwgQWZmaW5lVHJhbnNmb3JtIHhmb3JtLAorICAgICAgICAgICAgQ29tcG9zaXRlIGNvbXAsIENvbG9yIGJnY29sb3IsCisgICAgICAgICAgICBNdWx0aVJlY3RBcmVhIGNsaXApOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYmxpdChpbnQgc3JjWCwgaW50IHNyY1ksIFN1cmZhY2Ugc3JjU3VyZiwKKyAgICAgICAgICAgIGludCBkc3RYLCBpbnQgZHN0WSwgU3VyZmFjZSBkc3RTdXJmLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsCisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gc3lzeGZvcm0sIENvbXBvc2l0ZSBjb21wLCBDb2xvciBiZ2NvbG9yLAorICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBjbGlwKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGJsaXQoaW50IHNyY1gsIGludCBzcmNZLCBTdXJmYWNlIHNyY1N1cmYsCisgICAgICAgICAgICBpbnQgZHN0WCwgaW50IGRzdFksIFN1cmZhY2UgZHN0U3VyZiwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgQ29tcG9zaXRlIGNvbXAsIENvbG9yIGJnY29sb3IsIE11bHRpUmVjdEFyZWEgY2xpcCk7CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9KYXZhQXJjUmFzdGVyaXplci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL0phdmFBcmNSYXN0ZXJpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjY0M2I0MQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9KYXZhQXJjUmFzdGVyaXplci5qYXZhCkBAIC0wLDAgKzEsNTAyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLk11bHRpUmVjdEFyZWE7CisKK3B1YmxpYyBjbGFzcyBKYXZhQXJjUmFzdGVyaXplciB7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHBhcnRpY3VsYXIgYXJjIHNlZ21lbnQgdG8gbXJhIAorICAgICAqLworICAgIHN0YXRpYyB2b2lkIGFkZFgwTGluZVNlZyhNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBiLCBpbnQgc3RhcnQsIGludCBmaW5pc2gpIHsKKyAgICAgICAgaW50IHgxID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCB4MiA9IGxpbmVbaV07CisgICAgICAgICAgICBpbnQgeSA9IGN5ICsgKGIgLSBpKTsKKyAgICAgICAgICAgIGlmICh4MSA8PSBmaW5pc2ggJiYgeDIgPj0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICBtcmEuYWRkUmVjdChjeCArIE1hdGgubWF4KHgxLCBzdGFydCksIHksIGN4ICsgTWF0aC5taW4oeDIsIGZpbmlzaCksIHkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeDEgPSB4MiArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhZGRYMUxpbmVTZWcoTXVsdGlSZWN0QXJlYSBtcmEsIGludFtdIGxpbmUsIGludCBjeCwgaW50IGN5LCBpbnQgYiwgaW50IHN0YXJ0LCBpbnQgZmluaXNoKSB7CisgICAgICAgIGludCB4MSA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgeDIgPSBsaW5lW2ldOworICAgICAgICAgICAgaW50IHkgPSBjeSAtIChiIC0gaSk7CisgICAgICAgICAgICBpZiAoeDEgPD0gZmluaXNoICYmIHgyID49IHN0YXJ0KSB7CisgICAgICAgICAgICAgICAgbXJhLmFkZFJlY3QoY3ggKyBNYXRoLm1heCh4MSwgc3RhcnQpLCB5LCBjeCArIE1hdGgubWluKHgyLCBmaW5pc2gpLCB5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHgxID0geDIgKyAxOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkWDJMaW5lU2VnKE11bHRpUmVjdEFyZWEgbXJhLCBpbnRbXSBsaW5lLCBpbnQgY3gsIGludCBjeSwgaW50IGIsIGludCBzdGFydCwgaW50IGZpbmlzaCkgeworICAgICAgICBpbnQgeDEgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW50IHgyID0gbGluZVtpXTsKKyAgICAgICAgICAgIGludCB5ID0gY3kgLSAoYiAtIGkpOworICAgICAgICAgICAgaWYgKHgxIDw9IGZpbmlzaCAmJiB4MiA+PSBzdGFydCkgeworICAgICAgICAgICAgICAgIG1yYS5hZGRSZWN0KGN4IC0gTWF0aC5taW4oeDIsIGZpbmlzaCksIHksIGN4IC0gTWF0aC5tYXgoeDEsIHN0YXJ0KSwgeSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB4MSA9IHgyICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFkZFgzTGluZVNlZyhNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBiLCBpbnQgc3RhcnQsIGludCBmaW5pc2gpIHsKKyAgICAgICAgaW50IHgxID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCB4MiA9IGxpbmVbaV07CisgICAgICAgICAgICBpbnQgeSA9IGN5ICsgKGIgLSBpKTsKKyAgICAgICAgICAgIGlmICh4MSA8PSBmaW5pc2ggJiYgeDIgPj0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICBtcmEuYWRkUmVjdChjeCAtIE1hdGgubWluKHgyLCBmaW5pc2gpLCB5LCBjeCAtIE1hdGgubWF4KHgxLCBzdGFydCksIHkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeDEgPSB4MiArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhZGRZMExpbmVTZWcoTXVsdGlSZWN0QXJlYSBtcmEsIGludFtdIGxpbmUsIGludCBjeCwgaW50IGN5LCBpbnQgYiwgaW50IHN0YXJ0LCBpbnQgZmluaXNoKSB7CisgICAgICAgIGludCB5MSA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgeCA9IGN4ICsgKGIgLSBpKTsKKyAgICAgICAgICAgIGludCB5MiA9IGxpbmVbaV07CisgICAgICAgICAgICBpZiAoeTEgPD0gZmluaXNoICYmIHkyID49IHN0YXJ0KSB7CisgICAgICAgICAgICAgICAgbXJhLmFkZFJlY3QoeCwgY3kgKyBNYXRoLm1heCh5MSwgc3RhcnQpLCB4LCBjeSArIE1hdGgubWluKHkyLCBmaW5pc2gpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHkxID0geTIgKyAxOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkWTFMaW5lU2VnKE11bHRpUmVjdEFyZWEgbXJhLCBpbnRbXSBsaW5lLCBpbnQgY3gsIGludCBjeSwgaW50IGIsIGludCBzdGFydCwgaW50IGZpbmlzaCkgeworICAgICAgICBpbnQgeTEgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW50IHggPSBjeCAtIChiIC0gaSk7CisgICAgICAgICAgICBpbnQgeTIgPSBsaW5lW2ldOworICAgICAgICAgICAgaWYgKHkxIDw9IGZpbmlzaCAmJiB5MiA+PSBzdGFydCkgeworICAgICAgICAgICAgICAgIG1yYS5hZGRSZWN0KHgsIGN5ICsgTWF0aC5tYXgoeTEsIHN0YXJ0KSwgeCwgY3kgKyBNYXRoLm1pbih5MiwgZmluaXNoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB5MSA9IHkyICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFkZFkyTGluZVNlZyhNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBiLCBpbnQgc3RhcnQsIGludCBmaW5pc2gpIHsKKyAgICAgICAgaW50IHkxID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCB4ID0gY3ggLSAoYiAtIGkpOworICAgICAgICAgICAgaW50IHkyID0gbGluZVtpXTsKKyAgICAgICAgICAgIGlmICh5MSA8PSBmaW5pc2ggJiYgeTIgPj0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICBtcmEuYWRkUmVjdCh4LCBjeSAtIE1hdGgubWluKHkyLCBmaW5pc2gpLCB4LCBjeSAtIE1hdGgubWF4KHkxLCBzdGFydCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeTEgPSB5MiArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhZGRZM0xpbmVTZWcoTXVsdGlSZWN0QXJlYSBtcmEsIGludFtdIGxpbmUsIGludCBjeCwgaW50IGN5LCBpbnQgYiwgaW50IHN0YXJ0LCBpbnQgZmluaXNoKSB7CisgICAgICAgIGludCB5MSA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgeCA9IGN4ICsgKGIgLSBpKTsKKyAgICAgICAgICAgIGludCB5MiA9IGxpbmVbaV07CisgICAgICAgICAgICBpZiAoeTEgPD0gZmluaXNoICYmIHkyID49IHN0YXJ0KSB7CisgICAgICAgICAgICAgICAgbXJhLmFkZFJlY3QoeCwgY3kgLSBNYXRoLm1pbih5MiwgZmluaXNoKSwgeCwgY3kgLSBNYXRoLm1heCh5MSwgc3RhcnQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHkxID0geTIgKyAxOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkWDBMaW5lKE11bHRpUmVjdEFyZWEgbXJhLCBpbnRbXSBsaW5lLCBpbnQgY3gsIGludCBjeSwgaW50IGIpIHsKKyAgICAgICAgaW50IHByZXYgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbXJhLmFkZFJlY3QoY3ggKyBwcmV2LCBjeSArIChiIC0gaSksIGN4ICsgbGluZVtpXSwgY3kgKyAoYiAtIGkpKTsKKyAgICAgICAgICAgIHByZXYgPSBsaW5lW2ldICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFkZFgxTGluZShNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBiKSB7CisgICAgICAgIGludCBwcmV2ID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1yYS5hZGRSZWN0KGN4ICsgcHJldiwgY3kgLSAoYiAtIGkpLCBjeCArIGxpbmVbaV0sIGN5IC0gKGIgLSBpKSk7CisgICAgICAgICAgICBwcmV2ID0gbGluZVtpXSArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhZGRYMkxpbmUoTXVsdGlSZWN0QXJlYSBtcmEsIGludFtdIGxpbmUsIGludCBjeCwgaW50IGN5LCBpbnQgYikgeworICAgICAgICBpbnQgcHJldiA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtcmEuYWRkUmVjdChjeCAtIGxpbmVbaV0sIGN5IC0gKGIgLSBpKSwgY3ggLSBwcmV2LCBjeSAtIChiIC0gaSkpOworICAgICAgICAgICAgcHJldiA9IGxpbmVbaV0gKyAxOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkWDNMaW5lKE11bHRpUmVjdEFyZWEgbXJhLCBpbnRbXSBsaW5lLCBpbnQgY3gsIGludCBjeSwgaW50IGIpIHsKKyAgICAgICAgaW50IHByZXYgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbXJhLmFkZFJlY3QoY3ggLSBsaW5lW2ldLCBjeSArIChiIC0gaSksIGN4IC0gcHJldiwgY3kgKyAoYiAtIGkpKTsKKyAgICAgICAgICAgIHByZXYgPSBsaW5lW2ldICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFkZFkwTGluZShNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBhKSB7CisgICAgICAgIGludCBwcmV2ID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1yYS5hZGRSZWN0KGN4ICsgKGEgLSBpKSwgY3kgKyBwcmV2LCBjeCArIChhIC0gaSksIGN5ICsgbGluZVtpXSk7CisgICAgICAgICAgICBwcmV2ID0gbGluZVtpXSArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhZGRZMUxpbmUoTXVsdGlSZWN0QXJlYSBtcmEsIGludFtdIGxpbmUsIGludCBjeCwgaW50IGN5LCBpbnQgYSkgeworICAgICAgICBpbnQgcHJldiA9IDA7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtcmEuYWRkUmVjdChjeCAtIChhIC0gaSksIGN5ICsgcHJldiwgY3ggLSAoYSAtIGkpLCBjeSArIGxpbmVbaV0pOworICAgICAgICAgICAgcHJldiA9IGxpbmVbaV0gKyAxOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkWTJMaW5lKE11bHRpUmVjdEFyZWEgbXJhLCBpbnRbXSBsaW5lLCBpbnQgY3gsIGludCBjeSwgaW50IGEpIHsKKyAgICAgICAgaW50IHByZXYgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbXJhLmFkZFJlY3QoY3ggLSAoYSAtIGkpLCBjeSAtIGxpbmVbaV0sIGN4IC0gKGEgLSBpKSwgY3kgLSBwcmV2KTsKKyAgICAgICAgICAgIHByZXYgPSBsaW5lW2ldICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFkZFkzTGluZShNdWx0aVJlY3RBcmVhIG1yYSwgaW50W10gbGluZSwgaW50IGN4LCBpbnQgY3ksIGludCBhKSB7CisgICAgICAgIGludCBwcmV2ID0gMDsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1yYS5hZGRSZWN0KGN4ICsgKGEgLSBpKSwgY3kgLSBsaW5lW2ldLCBjeCArIChhIC0gaSksIGN5IC0gcHJldik7CisgICAgICAgICAgICBwcmV2ID0gbGluZVtpXSArIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG5vcm1hbGl6ZWQgYW5nbGUgKGZyb20gMCB0byAzNjAgZGVncmVlcykKKyAgICAgKi8KKyAgICBzdGF0aWMgZG91YmxlIGdldE5vcm1BbmdsZShkb3VibGUgYW5nbGUpIHsKKyAgICAgICAgYW5nbGUgLT0gTWF0aC5mbG9vcihhbmdsZSAvIDM2MCkgKiAzNjA7CisgICAgICAgIGlmIChhbmdsZSA8IDApIHsKKyAgICAgICAgICAgIGFuZ2xlICs9IDM2MDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYW5nbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhcmMgbG9va3VwIHRhYmxlCisgICAgICovCisgICAgc3RhdGljIGludFtdIGNyZWF0ZUxpbmUoaW50IGEsIGludCBiLCBpbnQgeGNvdW50LCBpbnQgeWNvdW50KSB7CisgICAgICAgIGludFtdIGJ1ZiA9IG5ldyBpbnRbYiAtIHljb3VudCArIDFdOworICAgICAgICBpbnQgZCA9IGEgKiBhICsgMiAqIGIgKiBiIC0gMiAqIGEgKiBhICogYjsKKyAgICAgICAgaW50IHggPSAwOworICAgICAgICBpbnQgeSA9IGI7CisgICAgICAgIHdoaWxlICh5ID49IHljb3VudCkgeworICAgICAgICAgICAgaWYgKGQgPCAwKSB7CisgICAgICAgICAgICAgICAgZCA9IGQgKyBiICogYiAqICg0ICogeCArIDYpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBidWZbYiAtIHldID0geDsKKyAgICAgICAgICAgICAgICBkID0gZCArIGIgKiBiICogKDQgKiB4ICsgNikgKyA0ICogYSAqIGEgKiAoMSAtIHkpOworICAgICAgICAgICAgICAgIHktLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHgrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgaGVhZC90YWlsIGFyYyBzZWdtZW50IHRvIE11bHRpUmVjdEFyZWEKKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBhZGRTZWcoTXVsdGlSZWN0QXJlYSBtcmEsIGludCBjeDEsIGludCBjeTEsIGludCBjeDIsIGludCBjeTIsIGludCBhLCBpbnQgYiwgaW50W10geGxpbmUsIGludFtdIHlsaW5lLCBpbnRbXSBib3VuZHMpIHsKKyAgICAgICAgc3dpdGNoKGJvdW5kc1swXSkgeworICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICBhZGRZM0xpbmVTZWcobXJhLCB5bGluZSwgY3gyLCBjeTEsIGEsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICBhZGRYMUxpbmVTZWcobXJhLCB4bGluZSwgY3gyLCBjeTEsIGIsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBhZGRYMkxpbmVTZWcobXJhLCB4bGluZSwgY3gxLCBjeTEsIGIsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICBhZGRZMkxpbmVTZWcobXJhLCB5bGluZSwgY3gxLCBjeTEsIGEsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDQ6CisgICAgICAgICAgICBhZGRZMUxpbmVTZWcobXJhLCB5bGluZSwgY3gxLCBjeTIsIGEsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDU6CisgICAgICAgICAgICBhZGRYM0xpbmVTZWcobXJhLCB4bGluZSwgY3gxLCBjeTIsIGIsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDY6CisgICAgICAgICAgICBhZGRYMExpbmVTZWcobXJhLCB4bGluZSwgY3gyLCBjeTIsIGIsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDc6CisgICAgICAgICAgICBhZGRZMExpbmVTZWcobXJhLCB5bGluZSwgY3gyLCBjeTIsIGEsIGJvdW5kc1sxXSwgYm91bmRzWzJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBib3VuZHMgZm9yIG5vbiBxdWFkcmF0aWMgYXJjIGhlYWQKKyAgICAgKi8KKyAgICBzdGF0aWMgaW50W10gZ2V0U2VnbWVudDEoZG91YmxlIGFuZ2xlLCBpbnQgYXgsIGludCBheSwgaW50IHhjb3VudCwgaW50IHljb3VudCkgeworICAgICAgICBpbnRbXSBib3VuZHMgPSBuZXcgaW50WzNdOworICAgICAgICBzd2l0Y2goKGludCkoYW5nbGUgLyA5MCkpIHsKKyAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgaWYgKHhjb3VudCA8ICBheCkgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDA7IC8vIFkzCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gLWF5OworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IHljb3VudDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gMTsgLy8gWDEKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSAwOworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IGF4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIGlmICh4Y291bnQgPiAtYXgpIHsKKyAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSAyOyAvLyBYMgorICAgICAgICAgICAgICAgIGJvdW5kc1sxXSA9IC1heDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSB4Y291bnQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDM7IC8vIFkyCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gMDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSAtYXk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgaWYgKHhjb3VudCA8IC1heCkgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDQ7IC8vIFkxCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gYXk7CisgICAgICAgICAgICAgICAgYm91bmRzWzJdID0geWNvdW50OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSA1OyAvLyBYMworICAgICAgICAgICAgICAgIGJvdW5kc1sxXSA9IDA7CisgICAgICAgICAgICAgICAgYm91bmRzWzJdID0gLWF4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgIGlmICh4Y291bnQgPiAgYXgpIHsKKyAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSA2OyAvLyBYMAorICAgICAgICAgICAgICAgIGJvdW5kc1sxXSA9IGF4OworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IHhjb3VudDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gNzsgLy8gWTAKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSAwOworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IGF5OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJvdW5kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGJvdW5kcyBmb3Igbm9uIHF1YWRyYXRpYyBhcmMgdGFpbAorICAgICAqLworICAgIHN0YXRpYyBpbnRbXSBnZXRTZWdtZW50Mihkb3VibGUgYW5nbGUsIGludCBheCwgaW50IGF5LCBpbnQgeGNvdW50LCBpbnQgeWNvdW50KSB7CisgICAgICAgIGludFtdIGJvdW5kcyA9IG5ldyBpbnRbM107CisgICAgICAgIHN3aXRjaCgoaW50KShhbmdsZSAvIDkwKSkgeworICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICBpZiAoeGNvdW50IDwgIGF4KSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gMDsgLy8gWTMKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSAwOworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IC1heTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gMTsgLy8gWDEKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSBheDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSB4Y291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgaWYgKHhjb3VudCA+IC1heCkgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDI7IC8vIFgyCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gMDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSAtYXg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDM7IC8vIFkyCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gLWF5OworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IHljb3VudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBpZiAoeGNvdW50IDwgLWF4KSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gNDsgLy8gWTEKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSAwOworICAgICAgICAgICAgICAgIGJvdW5kc1syXSA9IGF5OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSA1OyAvLyBYMworICAgICAgICAgICAgICAgIGJvdW5kc1sxXSA9IC1heDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSB4Y291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgaWYgKHhjb3VudCA+ICBheCkgeworICAgICAgICAgICAgICAgIGJvdW5kc1swXSA9IDY7IC8vIFgwCisgICAgICAgICAgICAgICAgYm91bmRzWzFdID0gMDsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSBheDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gNzsgLy8gWTAKKyAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSBheTsKKyAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSB5Y291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYm91bmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJhc3Rlcml6ZXMgYXJjIHVzaW5nIGNsaXBwaW5kIGFuZCBkYXNoaW5nIHN0eWxlCisgICAgICogQHBhcmFtIHgxIC0gdGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgbGVmdC11cHBlciBjb3JuZXIgb2YgdGhlIGFyYyBib3VuZHMKKyAgICAgKiBAcGFyYW0geTEgLSB0aGUgeSBjb29yZGluYXRlIG9mIHRoZSBsZWZ0LXVwcGVyIGNvcm5lciBvZiB0aGUgYXJjIGJvdW5kcworICAgICAqIEBwYXJhbSB3aWR0aCAtIHRoZSB3aWR0aCBvZiB0aGUgYXJjIGJvdW5kcworICAgICAqIEBwYXJhbSBoZWlnaHQgLSB0aGUgaGVpZ2h0IG9mIHRoZSBhcmMgYm91bmRzCisgICAgICogQHBhcmFtIGFuZ2xlU3RhcnQgLSB0aGUgc3RhcnQgYW5nbGUgb2YgdGhlIGFyYyBpbiBkZWdyZWVzCisgICAgICogQHBhcmFtIGFuZ2xlRXh0ZW50IC0gdGhlIGFuZ2xlIGV4dGVudCBpbiBkZWdyZWVzCisgICAgICogQHBhcmFtIGNsaXAgLSB0aGUgTXVsdGlSZWN0QXJlYSBvYmplY3Qgb2YgY2xpcHBpbmcgYXJlYQorICAgICAqIEByZXR1cm4gYSBNdWx0aVJlY3RBcmVhIG9mIHJhc3Rlcml6ZXIgYXJjCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBNdWx0aVJlY3RBcmVhIHJhc3Rlcml6ZShpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgZG91YmxlIGFuZ2xlU3RhcnQsIGRvdWJsZSBhbmdsZUV4dGVudCwgTXVsdGlSZWN0QXJlYSBjbGlwKSB7CisKKyAgICAgICAgTXVsdGlSZWN0QXJlYSBtcmEgPSBuZXcgTXVsdGlSZWN0QXJlYShmYWxzZSk7CisKKyAgICAgICAgaW50IGN4MSwgY3gyLCBjeTEsIGN5MjsKKyAgICAgICAgY3gxID0gY3gyID0geCArIHdpZHRoIC8gMjsKKyAgICAgICAgY3kxID0gY3kyID0geSArIGhlaWdodCAvIDI7CisKKyAgICAgICAgaWYgKHdpZHRoICUgMiA9PSAwKSB7CisgICAgICAgICAgICBjeDItLTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChoZWlnaHQgJSAyID09IDApIHsKKyAgICAgICAgICAgIGN5Mi0tOworICAgICAgICB9CisKKyAgICAgICAgaW50IGEgPSB3aWR0aCAvIDI7CisgICAgICAgIGludCBiID0gaGVpZ2h0IC8gMjsKKyAgICAgICAgZG91YmxlIGMgPSBNYXRoLnNxcnQoYSAqIGEgKyBiICogYik7CisKKyAgICAgICAgaW50IHhjb3VudCwgeWNvdW50OworICAgICAgICBpZiAoYSA8IGIpIHsKKyAgICAgICAgICAgIHhjb3VudCA9IChpbnQpTWF0aC5jZWlsKGEgKiBhIC8gYyk7CisgICAgICAgICAgICB5Y291bnQgPSAoaW50KU1hdGguZmxvb3IoYiAqIGIgLyBjKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHhjb3VudCA9IChpbnQpTWF0aC5mbG9vcihhICogYSAvIGMpOworICAgICAgICAgICAgeWNvdW50ID0gKGludClNYXRoLmNlaWwoYiAqIGIgLyBjKTsKKyAgICAgICAgfQorCisgICAgICAgIGludFtdIHhsaW5lID0gY3JlYXRlTGluZShhLCBiLCB4Y291bnQsIHljb3VudCk7CisgICAgICAgIGludFtdIHlsaW5lID0gY3JlYXRlTGluZShiLCBhLCB5Y291bnQsIHhjb3VudCk7CisKKyAgICAgICAgLy8gQ29ycmVjdCBsaW5lcworICAgICAgICBpbnQgaSA9IHhsaW5lLmxlbmd0aDsKKyAgICAgICAgd2hpbGUoeGxpbmVbLS1pXSA+IHhjb3VudCkgeworICAgICAgICAgICAgeGxpbmVbaV0gPSB4Y291bnQ7CisgICAgICAgIH0KKworICAgICAgICBpID0geWxpbmUubGVuZ3RoOworICAgICAgICB3aGlsZSh5bGluZVstLWldID4geWNvdW50KSB7CisgICAgICAgICAgICB5bGluZVtpXSA9IHljb3VudDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChNYXRoLmFicyhhbmdsZUV4dGVudCkgPj0gMzYwKSB7CisgICAgICAgICAgICAvLyBSYXN0ZXJpemUgQ0lSQ0xFCisgICAgICAgICAgICBhZGRYMExpbmUobXJhLCB4bGluZSwgY3gyLCBjeTIsIGIpOworICAgICAgICAgICAgYWRkWDFMaW5lKG1yYSwgeGxpbmUsIGN4MiwgY3kxLCBiKTsKKyAgICAgICAgICAgIGFkZFgyTGluZShtcmEsIHhsaW5lLCBjeDEsIGN5MSwgYik7CisgICAgICAgICAgICBhZGRYM0xpbmUobXJhLCB4bGluZSwgY3gxLCBjeTIsIGIpOworICAgICAgICAgICAgYWRkWTBMaW5lKG1yYSwgeWxpbmUsIGN4MiwgY3kyLCBhKTsKKyAgICAgICAgICAgIGFkZFkxTGluZShtcmEsIHlsaW5lLCBjeDEsIGN5MiwgYSk7CisgICAgICAgICAgICBhZGRZMkxpbmUobXJhLCB5bGluZSwgY3gxLCBjeTEsIGEpOworICAgICAgICAgICAgYWRkWTNMaW5lKG1yYSwgeWxpbmUsIGN4MiwgY3kxLCBhKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIFJhc3Rlcml6ZSBBUkMKKyAgICAgICAgICAgIGFuZ2xlU3RhcnQgPSBnZXROb3JtQW5nbGUoYW5nbGVTdGFydCk7CisgICAgICAgICAgICBkb3VibGUgYW5nbGVGaW5pc2ggPSBnZXROb3JtQW5nbGUoYW5nbGVTdGFydCArIGFuZ2xlRXh0ZW50KTsKKworICAgICAgICAgICAgaWYgKGFuZ2xlRXh0ZW50IDwgMCkgeworICAgICAgICAgICAgICAgIGRvdWJsZSB0bXAgPSBhbmdsZVN0YXJ0OworICAgICAgICAgICAgICAgIGFuZ2xlU3RhcnQgPSBhbmdsZUZpbmlzaDsKKyAgICAgICAgICAgICAgICBhbmdsZUZpbmlzaCA9IHRtcDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZG91YmxlIHJhZFN0YXJ0ID0gLU1hdGgudG9SYWRpYW5zKGFuZ2xlU3RhcnQpOworICAgICAgICAgICAgZG91YmxlIHJhZEZpbmlzaCA9IC1NYXRoLnRvUmFkaWFucyhhbmdsZUZpbmlzaCk7CisgICAgICAgICAgICBpbnQgYXgxID0gKGludCkoYSAqIE1hdGguY29zKHJhZFN0YXJ0KSk7CisgICAgICAgICAgICBpbnQgYXkxID0gKGludCkoYiAqIE1hdGguc2luKHJhZFN0YXJ0KSk7CisgICAgICAgICAgICBpbnQgYXgyID0gKGludCkoYSAqIE1hdGguY29zKHJhZEZpbmlzaCkpOworICAgICAgICAgICAgaW50IGF5MiA9IChpbnQpKGIgKiBNYXRoLnNpbihyYWRGaW5pc2gpKTsKKworICAgICAgICAgICAgaW50W10gc2VnMSA9IGdldFNlZ21lbnQxKGFuZ2xlU3RhcnQsIGF4MSwgYXkxLCB4Y291bnQsIHljb3VudCk7CisgICAgICAgICAgICBpbnRbXSBzZWcyID0gZ2V0U2VnbWVudDIoYW5nbGVGaW5pc2gsIGF4MiwgYXkyLCB4Y291bnQsIHljb3VudCk7CisKKyAgICAgICAgICAgIC8vIFN0YXJ0IGFuZCBGaW5pc2ggbG9jYXRlZCBpbiB0aGUgc2FtZSBxdWF0ZXIKKyAgICAgICAgICAgIGlmIChhbmdsZVN0YXJ0IDwgYW5nbGVGaW5pc2ggJiYgc2VnMVswXSA9PSBzZWcyWzBdKSB7CisgICAgICAgICAgICAgICAgaWYgKHNlZzFbMF0gJSAyID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgc2VnMVsyXSA9IHNlZzJbMl07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2VnMVsxXSA9IHNlZzJbMV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFkZFNlZyhtcmEsIGN4MSwgY3kxLCBjeDIsIGN5MiwgYSwgYiwgeGxpbmUsIHlsaW5lLCBzZWcxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbXJhOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhZGRTZWcobXJhLCBjeDEsIGN5MSwgY3gyLCBjeTIsIGEsIGIsIHhsaW5lLCB5bGluZSwgc2VnMSk7CisgICAgICAgICAgICBhZGRTZWcobXJhLCBjeDEsIGN5MSwgY3gyLCBjeTIsIGEsIGIsIHhsaW5lLCB5bGluZSwgc2VnMik7CisKKyAgICAgICAgICAgIGludCBzdGFydFNlZyA9IChzZWcxWzBdICsgMSkgJSA4OworICAgICAgICAgICAgaW50IGZpbmlzaFNlZyA9IHNlZzJbMF07CisKKyAgICAgICAgICAgIHdoaWxlIChzdGFydFNlZyAhPSBmaW5pc2hTZWcpIHsKKyAgICAgICAgICAgICAgICBzd2l0Y2goc3RhcnRTZWcpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICAgICAgICAgIGFkZFkzTGluZShtcmEsIHlsaW5lLCBjeDIsIGN5MSwgYSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICAgICAgYWRkWDFMaW5lKG1yYSwgeGxpbmUsIGN4MiwgY3kxLCBiKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgICAgICBhZGRYMkxpbmUobXJhLCB4bGluZSwgY3gxLCBjeTEsIGIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICAgICAgICAgIGFkZFkyTGluZShtcmEsIHlsaW5lLCBjeDEsIGN5MSwgYSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgNDoKKyAgICAgICAgICAgICAgICAgICAgYWRkWTFMaW5lKG1yYSwgeWxpbmUsIGN4MSwgY3kyLCBhKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA1OgorICAgICAgICAgICAgICAgICAgICBhZGRYM0xpbmUobXJhLCB4bGluZSwgY3gxLCBjeTIsIGIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDY6CisgICAgICAgICAgICAgICAgICAgIGFkZFgwTGluZShtcmEsIHhsaW5lLCBjeDIsIGN5MiwgYik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgNzoKKyAgICAgICAgICAgICAgICAgICAgYWRkWTBMaW5lKG1yYSwgeWxpbmUsIGN4MiwgY3kyLCBhKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN0YXJ0U2VnID0gKHN0YXJ0U2VnICsgMSkgJSA4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGNsaXAgIT0gbnVsbCkgeworICAgICAgICAgICAgbXJhLmludGVyc2VjdChjbGlwKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtcmE7CisgICAgfQorCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL0phdmFCbGl0dGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YUJsaXR0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2UwYTU5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL0phdmFCbGl0dGVyLmphdmEKQEAgLTAsMCArMSw2MTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqIENyZWF0ZWQgb24gMTguMTEuMjAwNQorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlcjsKKworaW1wb3J0IGphdmEuYXd0LkFscGhhQ29tcG9zaXRlOworaW1wb3J0IGphdmEuYXd0LkNvbG9yOworaW1wb3J0IGphdmEuYXd0LkNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5Db21wb3NpdGVDb250ZXh0OworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLk5vbmludmVydGlibGVUcmFuc2Zvcm1FeGNlcHRpb247CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5SZWN0YW5nbGUyRDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJhc3RlcjsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuTXVsdGlSZWN0QXJlYTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5YT1JDb21wb3NpdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMuTWVzc2FnZXM7CisKKy8qKgorICogSmF2YSBpbXBsZW5ldGF0aW9uIG9mIHRoZSBCbGl0dGVyIGludGVyZmFjZS4gVXNpbmcgd2hlbiB3ZSBjYW4ndCAKKyAqIGRyYXcgaW1hZ2VzIG5hdGl2ZWx5LgorICovCitwdWJsaWMgY2xhc3MgSmF2YUJsaXR0ZXIgaW1wbGVtZW50cyBCbGl0dGVyIHsKKworICAgIC8qKgorICAgICAqIEluc3RlYWQgb2YgbXVsdGlwbGljYXRpb24gYW5kIGRpdmlzaW9uIHdlIGFyZSB1c2luZyB2YWx1ZXMgZnJvbQorICAgICAqIExvb2t1cCB0YWJsZXMuCisgICAgICovCisgICAgc3RhdGljIGJ5dGUgbXVsTFVUW11bXTsgLy8gTG9va3VwIHRhYmxlIGZvciBtdWx0aXBsaWNhdGlvbgorICAgIHN0YXRpYyBieXRlIGRpdkxVVFtdW107IC8vIExvb2t1cCB0YWJsZSBmb3IgZGl2aXNpb24KKworICAgIHN0YXRpY3sKKyAgICAgICAgbXVsTFVUID0gbmV3IGJ5dGVbMjU2XVsyNTZdOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspeworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IDI1NjsgaisrKXsKKyAgICAgICAgICAgICAgICBtdWxMVVRbaV1bal0gPSAoYnl0ZSkoKGZsb2F0KShpICogaikvMjU1ICsgMC41Zik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZGl2TFVUID0gbmV3IGJ5dGVbMjU2XVsyNTZdOworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgMjU2OyBpKyspeworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IGk7IGorKyl7CisgICAgICAgICAgICAgICAgZGl2TFVUW2ldW2pdID0gKGJ5dGUpKCgoZmxvYXQpaiAvIDI1NSkgLyAoKGZsb2F0KWkvIDI1NSkgKiAyNTUgKyAwLjVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvcihpbnQgaiA9IGk7IGogPCAyNTY7IGorKyl7CisgICAgICAgICAgICAgICAgZGl2TFVUW2ldW2pdID0gKGJ5dGUpMjU1OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgc3RhdGljIGludCBBbHBoYUNvbXBvc2l0ZU1vZGUgPSAxOworICAgIGZpbmFsIHN0YXRpYyBpbnQgWE9STW9kZSA9IDI7CisKKyAgICBmaW5hbCBzdGF0aWMgSmF2YUJsaXR0ZXIgaW5zdCA9IG5ldyBKYXZhQmxpdHRlcigpOworCisgICAgcHVibGljIHN0YXRpYyBKYXZhQmxpdHRlciBnZXRJbnN0YW5jZSgpeworICAgICAgICByZXR1cm4gaW5zdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQWZmaW5lVHJhbnNmb3JtIHN5c3hmb3JtLAorICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIHhmb3JtLCBDb21wb3NpdGUgY29tcCwgQ29sb3IgYmdjb2xvciwKKyAgICAgICAgICAgIE11bHRpUmVjdEFyZWEgY2xpcCkgeworCisgICAgICAgIGlmKHhmb3JtID09IG51bGwpeworICAgICAgICAgICAgYmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCBkc3RYLCBkc3RZLCBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICBzeXN4Zm9ybSwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgZG91YmxlIHNjYWxlWCA9IHhmb3JtLmdldFNjYWxlWCgpOworICAgICAgICAgICAgZG91YmxlIHNjYWxlWSA9IHhmb3JtLmdldFNjYWxlWSgpOworICAgICAgICAgICAgZG91YmxlIHNjYWxlZFggPSBkc3RYIC8gc2NhbGVYOworICAgICAgICAgICAgZG91YmxlIHNjYWxlZFkgPSBkc3RZIC8gc2NhbGVZOworICAgICAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGF0ID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICAgICAgYXQuc2V0VG9UcmFuc2xhdGlvbihzY2FsZWRYLCBzY2FsZWRZKTsKKyAgICAgICAgICAgIHhmb3JtLmNvbmNhdGVuYXRlKGF0KTsKKyAgICAgICAgICAgIHN5c3hmb3JtLmNvbmNhdGVuYXRlKHhmb3JtKTsKKyAgICAgICAgICAgIGJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgMCwgMCwgZHN0U3VyZiwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgc3lzeGZvcm0sIGNvbXAsIGJnY29sb3IsIGNsaXApOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQWZmaW5lVHJhbnNmb3JtIHN5c3hmb3JtLAorICAgICAgICAgICAgQ29tcG9zaXRlIGNvbXAsIENvbG9yIGJnY29sb3IsIE11bHRpUmVjdEFyZWEgY2xpcCkgeworCisgICAgICAgIGlmKHN5c3hmb3JtID09IG51bGwpIHsKKyAgICAgICAgICAgIHN5c3hmb3JtID0gbmV3IEFmZmluZVRyYW5zZm9ybSgpOworICAgICAgICB9CisgICAgICAgIGludCB0eXBlID0gc3lzeGZvcm0uZ2V0VHlwZSgpOworICAgICAgICBzd2l0Y2godHlwZSl7CisgICAgICAgICAgICBjYXNlIEFmZmluZVRyYW5zZm9ybS5UWVBFX1RSQU5TTEFUSU9OOgorICAgICAgICAgICAgICAgIGRzdFggKz0gc3lzeGZvcm0uZ2V0VHJhbnNsYXRlWCgpOworICAgICAgICAgICAgICAgIGRzdFkgKz0gc3lzeGZvcm0uZ2V0VHJhbnNsYXRlWSgpOworICAgICAgICAgICAgY2FzZSBBZmZpbmVUcmFuc2Zvcm0uVFlQRV9JREVOVElUWToKKyAgICAgICAgICAgICAgICAgYmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCBkc3RYLCBkc3RZLCBkc3RTdXJmLAorICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGludCBzcmNXID0gc3JjU3VyZi5nZXRXaWR0aCgpOworICAgICAgICAgICAgICAgIGludCBzcmNIID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKworICAgICAgICAgICAgICAgIGludCB3ID0gc3JjWCArIHdpZHRoIDwgc3JjVyA/IHdpZHRoIDogc3JjVyAtIHNyY1g7CisgICAgICAgICAgICAgICAgaW50IGggPSBzcmNZICsgaGVpZ2h0IDwgc3JjSCA/IGhlaWdodCA6IHNyY0ggLSBzcmNZOworCisgICAgICAgICAgICAgICAgQ29sb3JNb2RlbCBzcmNDTSA9IHNyY1N1cmYuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICAgICAgICAgIFJhc3RlciBzcmNSID0gc3JjU3VyZi5nZXRSYXN0ZXIoKS5jcmVhdGVDaGlsZChzcmNYLCBzcmNZLAorICAgICAgICAgICAgICAgICAgICAgICAgdywgaCwgMCwgMCwgbnVsbCk7CisKKyAgICAgICAgICAgICAgICBDb2xvck1vZGVsIGRzdENNID0gZHN0U3VyZi5nZXRDb2xvck1vZGVsKCk7CisgICAgICAgICAgICAgICAgV3JpdGFibGVSYXN0ZXIgZHN0UiA9IGRzdFN1cmYuZ2V0UmFzdGVyKCk7CisKKyAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZEJsaXQoc3JjQ00sIHNyY1IsIDAsIDAsIGRzdENNLCBkc3RSLCBkc3RYLCBkc3RZLCB3LCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgc3lzeGZvcm0sIGNvbXAsIGJnY29sb3IsIGNsaXApOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKworICAgICAgICBqYXZhQmx0KHNyY1gsIHNyY1ksIHNyY1N1cmYuZ2V0V2lkdGgoKSwgc3JjU3VyZi5nZXRIZWlnaHQoKSwKKyAgICAgICAgICAgICAgICBzcmNTdXJmLmdldENvbG9yTW9kZWwoKSwgc3JjU3VyZi5nZXRSYXN0ZXIoKSwgZHN0WCwgZHN0WSwKKyAgICAgICAgICAgICAgICBkc3RTdXJmLmdldFdpZHRoKCksIGRzdFN1cmYuZ2V0SGVpZ2h0KCksCisgICAgICAgICAgICAgICAgZHN0U3VyZi5nZXRDb2xvck1vZGVsKCksIGRzdFN1cmYuZ2V0UmFzdGVyKCksCisgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisKKyAgICB9CisgICAgcHVibGljIHZvaWQgamF2YUJsdChpbnQgc3JjWCwgaW50IHNyY1ksIGludCBzcmNXLCBpbnQgc3JjSCwKKyAgICAgICAgICAgIENvbG9yTW9kZWwgc3JjQ00sIFJhc3RlciBzcmNSYXN0LCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBpbnQgZHN0VywgaW50IGRzdEgsIENvbG9yTW9kZWwgZHN0Q00sIFdyaXRhYmxlUmFzdGVyIGRzdFJhc3QsCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIENvbXBvc2l0ZSBjb21wLCBDb2xvciBiZ2NvbG9yLAorICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBjbGlwKXsKKworICAgICAgICBpbnQgc3JjWDIgPSBzcmNXIC0gMTsKKyAgICAgICAgaW50IHNyY1kyID0gc3JjSCAtIDE7CisgICAgICAgIGludCBkc3RYMiA9IGRzdFcgLSAxOworICAgICAgICBpbnQgZHN0WTIgPSBkc3RIIC0gMTsKKworICAgICAgICBpZihzcmNYIDwgMCl7CisgICAgICAgICAgICB3aWR0aCArPSBzcmNYOworICAgICAgICAgICAgc3JjWCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgaWYoc3JjWSA8IDApeworICAgICAgICAgICAgaGVpZ2h0ICs9IHNyY1k7CisgICAgICAgICAgICBzcmNZID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIGlmKGRzdFggPCAwKXsKKyAgICAgICAgICAgIHdpZHRoICs9IGRzdFg7CisgICAgICAgICAgICBzcmNYIC09IGRzdFg7CisgICAgICAgICAgICBkc3RYID0gMDsKKyAgICAgICAgfQorICAgICAgICBpZihkc3RZIDwgMCl7CisgICAgICAgICAgICBoZWlnaHQgKz0gZHN0WTsKKyAgICAgICAgICAgIHNyY1kgLT0gZHN0WTsKKyAgICAgICAgICAgIGRzdFkgPSAwOworICAgICAgICB9CisKKyAgICAgICAgaWYoc3JjWCA+IHNyY1gyIHx8IHNyY1kgPiBzcmNZMikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmKGRzdFggPiBkc3RYMiB8fCBkc3RZID4gZHN0WTIpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmKHNyY1ggKyB3aWR0aCA+IHNyY1gyKSB7CisgICAgICAgICAgICB3aWR0aCA9IHNyY1gyIC0gc3JjWCArIDE7CisgICAgICAgIH0KKyAgICAgICAgaWYoc3JjWSArIGhlaWdodCA+IHNyY1kyKSB7CisgICAgICAgICAgICBoZWlnaHQgPSBzcmNZMiAtIHNyY1kgKyAxOworICAgICAgICB9CisgICAgICAgIGlmKGRzdFggKyB3aWR0aCA+IGRzdFgyKSB7CisgICAgICAgICAgICB3aWR0aCA9IGRzdFgyIC0gZHN0WCArIDE7CisgICAgICAgIH0KKyAgICAgICAgaWYoZHN0WSArIGhlaWdodCA+IGRzdFkyKSB7CisgICAgICAgICAgICBoZWlnaHQgPSBkc3RZMiAtIGRzdFkgKyAxOworICAgICAgICB9CisKKyAgICAgICAgaWYod2lkdGggPD0gMCB8fCBoZWlnaHQgPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNsaXBSZWN0c1tdOworICAgICAgICBpZihjbGlwICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNsaXBSZWN0cyA9IGNsaXAucmVjdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNsaXBSZWN0cyA9IG5ldyBpbnRbXXs1LCAwLCAwLCBkc3RXIC0gMSwgZHN0SCAtIDF9OworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpc0FscGhhQ29tcCA9IGZhbHNlOworICAgICAgICBpbnQgcnVsZSA9IDA7CisgICAgICAgIGZsb2F0IGFscGhhID0gMDsKKyAgICAgICAgYm9vbGVhbiBpc1hPUkNvbXAgPSBmYWxzZTsKKyAgICAgICAgQ29sb3IgeG9yY29sb3IgPSBudWxsOworICAgICAgICBDb21wb3NpdGVDb250ZXh0IGNvbnQgPSBudWxsOworCisgICAgICAgIGlmKGNvbXAgaW5zdGFuY2VvZiBBbHBoYUNvbXBvc2l0ZSl7CisgICAgICAgICAgICBpc0FscGhhQ29tcCA9IHRydWU7CisgICAgICAgICAgICBBbHBoYUNvbXBvc2l0ZSBhYyA9IChBbHBoYUNvbXBvc2l0ZSkgY29tcDsKKyAgICAgICAgICAgIHJ1bGUgPSBhYy5nZXRSdWxlKCk7CisgICAgICAgICAgICBhbHBoYSA9IGFjLmdldEFscGhhKCk7CisgICAgICAgIH1lbHNlIGlmKGNvbXAgaW5zdGFuY2VvZiBYT1JDb21wb3NpdGUpeworICAgICAgICAgICAgaXNYT1JDb21wID0gdHJ1ZTsKKyAgICAgICAgICAgIFhPUkNvbXBvc2l0ZSB4Y29tcCA9IChYT1JDb21wb3NpdGUpIGNvbXA7CisgICAgICAgICAgICB4b3Jjb2xvciA9IHhjb21wLmdldFhPUkNvbG9yKCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgY29udCA9IGNvbXAuY3JlYXRlQ29udGV4dChzcmNDTSwgZHN0Q00sIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgZm9yKGludCBpID0gMTsgaSA8IGNsaXBSZWN0c1swXTsgaSArPSA0KXsKKyAgICAgICAgICAgIGludCBfc3ggPSBzcmNYOworICAgICAgICAgICAgaW50IF9zeSA9IHNyY1k7CisKKyAgICAgICAgICAgIGludCBfZHggPSBkc3RYOworICAgICAgICAgICAgaW50IF9keSA9IGRzdFk7CisKKyAgICAgICAgICAgIGludCBfdyA9IHdpZHRoOworICAgICAgICAgICAgaW50IF9oID0gaGVpZ2h0OworCisgICAgICAgICAgICBpbnQgY3ggPSBjbGlwUmVjdHNbaV07ICAgICAgICAgIC8vIENsaXBwaW5nIGxlZnQgdG9wIFgKKyAgICAgICAgICAgIGludCBjeSA9IGNsaXBSZWN0c1tpICsgMV07ICAgICAgLy8gQ2xpcHBpbmcgbGVmdCB0b3AgWQorICAgICAgICAgICAgaW50IGN4MiA9IGNsaXBSZWN0c1tpICsgMl07ICAgICAvLyBDbGlwcGluZyByaWdodCBib3R0b20gWAorICAgICAgICAgICAgaW50IGN5MiA9IGNsaXBSZWN0c1tpICsgM107ICAgICAvLyBDbGlwcGluZyByaWdodCBib3R0b20gWQorCisgICAgICAgICAgICBpZihfZHggPiBjeDIgfHwgX2R5ID4gY3kyIHx8IGRzdFgyIDwgY3ggfHwgZHN0WTIgPCBjeSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZihjeCA+IF9keCl7CisgICAgICAgICAgICAgICAgaW50IHNoeCA9IGN4IC0gX2R4OworICAgICAgICAgICAgICAgIF93IC09IHNoeDsKKyAgICAgICAgICAgICAgICBfZHggPSBjeDsKKyAgICAgICAgICAgICAgICBfc3ggKz0gc2h4OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZihjeSA+IF9keSl7CisgICAgICAgICAgICAgICAgaW50IHNoeSA9IGN5IC0gX2R5OworICAgICAgICAgICAgICAgIF9oIC09IHNoeTsKKyAgICAgICAgICAgICAgICBfZHkgPSBjeTsKKyAgICAgICAgICAgICAgICBfc3kgKz0gc2h5OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZihfZHggKyBfdyA+IGN4MiArIDEpeworICAgICAgICAgICAgICAgIF93ID0gY3gyIC0gX2R4ICsgMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYoX2R5ICsgX2ggPiBjeTIgKyAxKXsKKyAgICAgICAgICAgICAgICBfaCA9IGN5MiAtIF9keSArIDE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKF9zeCA+IHNyY1gyIHx8IF9zeSA+IHNyY1kyKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKGlzQWxwaGFDb21wKXsKKyAgICAgICAgICAgICAgICBhbHBoYUNvbXBvc2UoX3N4LCBfc3ksIHNyY0NNLCBzcmNSYXN0LCBfZHgsIF9keSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdENNLCBkc3RSYXN0LCBfdywgX2gsIHJ1bGUsIGFscGhhLCBiZ2NvbG9yKTsKKyAgICAgICAgICAgIH1lbHNlIGlmKGlzWE9SQ29tcCl7CisgICAgICAgICAgICAgICAgeG9yQ29tcG9zZShfc3gsIF9zeSwgc3JjQ00sIHNyY1Jhc3QsIF9keCwgX2R5LAorICAgICAgICAgICAgICAgICAgICAgICAgZHN0Q00sIGRzdFJhc3QsIF93LCBfaCwgeG9yY29sb3IpOworICAgICAgICAgICAgfWVsc2V7CisgICAgICAgICAgICAgICAgUmFzdGVyIHNyID0gc3JjUmFzdC5jcmVhdGVDaGlsZChfc3gsIF9zeSwgX3csIF9oLCAwLCAwLCBudWxsKTsKKyAgICAgICAgICAgICAgICBXcml0YWJsZVJhc3RlciBkciA9IGRzdFJhc3QuY3JlYXRlV3JpdGFibGVDaGlsZChfZHgsIF9keSwKKyAgICAgICAgICAgICAgICAgICAgICAgIF93LCBfaCwgMCwgMCwgbnVsbCk7CisgICAgICAgICAgICAgICAgY29udC5jb21wb3NlKHNyLCBkciwgZHIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgdm9pZCBhbHBoYUNvbXBvc2UoaW50IHNyY1gsIGludCBzcmNZLCBDb2xvck1vZGVsIHNyY0NNLCBSYXN0ZXIgc3JjUmFzdCwKKyAgICAgICAgICAgIGludCBkc3RYLCBpbnQgZHN0WSwgQ29sb3JNb2RlbCBkc3RDTSwgV3JpdGFibGVSYXN0ZXIgZHN0UmFzdCwKKyAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IHJ1bGUsIGZsb2F0IGFscGhhLCBDb2xvciBiZ2NvbG9yKXsKKworICAgICAgICBPYmplY3Qgc3JjUGl4ZWwsIGRzdFBpeGVsOworICAgICAgICBpbnQgc3JjQ29uc3RBbGxwaGEgPSAoaW50KShhbHBoYSAqIDI1NSArIDAuNWYpOworICAgICAgICBpbnQgc3JjUkdCLCBkc3RSR0IgPSAwOworCisgICAgICAgIGlmKGJnY29sb3IgIT0gbnVsbCl7CisgICAgICAgICAgICBkc3RSR0IgPSBiZ2NvbG9yLmdldFJHQigpOworICAgICAgICB9CisKKyAgICAgICAgZm9yKGludCBzeSA9IHNyY1ksIGR5ID0gZHN0WSwgc3JjWU1heCA9IHNyY1kgKyBoZWlnaHQ7IHN5IDwgc3JjWU1heDsgc3krKywgZHkrKyl7CisgICAgICAgICAgICBmb3IoaW50IHN4ID0gc3JjWCwgZHggPSBkc3RYLCBzcmNYTWF4ID0gc3JjWCArIHdpZHRoOyBzeCA8IHNyY1hNYXg7IHN4KyssIGR4KyspeworICAgICAgICAgICAgICAgIHNyY1BpeGVsID0gc3JjUmFzdC5nZXREYXRhRWxlbWVudHMoc3gsIHN5LCBudWxsKTsKKyAgICAgICAgICAgICAgICBzcmNSR0IgPSBzcmNDTS5nZXRSR0Ioc3JjUGl4ZWwpOworICAgICAgICAgICAgICAgIGlmKGJnY29sb3IgPT0gbnVsbCl7CisgICAgICAgICAgICAgICAgICAgIGRzdFBpeGVsID0gZHN0UmFzdC5nZXREYXRhRWxlbWVudHMoZHgsIGR5LCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZHN0UkdCID0gZHN0Q00uZ2V0UkdCKGRzdFBpeGVsKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBkc3RSR0IgPSBjb21wb3NlKHNyY1JHQiwgc3JjQ00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiwgZHN0Q00uaGFzQWxwaGEoKSwgZHN0Q00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGUsIHNyY0NvbnN0QWxscGhhKTsKKworICAgICAgICAgICAgICAgIGRzdFBpeGVsID0gZHN0Q00uZ2V0RGF0YUVsZW1lbnRzKGRzdFJHQiwgbnVsbCk7CisgICAgICAgICAgICAgICAgZHN0UmFzdC5zZXREYXRhRWxlbWVudHMoZHgsZHksZHN0UGl4ZWwpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgdm9pZCB4b3JDb21wb3NlKGludCBzcmNYLCBpbnQgc3JjWSwgQ29sb3JNb2RlbCBzcmNDTSwgUmFzdGVyIHNyY1Jhc3QsCisgICAgICAgICAgICBpbnQgZHN0WCwgaW50IGRzdFksIENvbG9yTW9kZWwgZHN0Q00sIFdyaXRhYmxlUmFzdGVyIGRzdFJhc3QsCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIENvbG9yIHhvcmNvbG9yKXsKKworICAgICAgICBPYmplY3Qgc3JjUGl4ZWwsIGRzdFBpeGVsOworICAgICAgICBpbnQgeG9yUkdCID0geG9yY29sb3IuZ2V0UkdCKCk7CisgICAgICAgIGludCBzcmNSR0IsIGRzdFJHQjsKKworICAgICAgICBmb3IoaW50IHN5ID0gc3JjWSwgZHkgPSBkc3RZLCBzcmNZTWF4ID0gc3JjWSArIGhlaWdodDsgc3kgPCBzcmNZTWF4OyBzeSsrLCBkeSsrKXsKKyAgICAgICAgICAgIGZvcihpbnQgc3ggPSBzcmNYLCBkeCA9IGRzdFgsIHNyY1hNYXggPSBzcmNYICsgd2lkdGg7IHN4IDwgc3JjWE1heDsgc3grKywgZHgrKyl7CisgICAgICAgICAgICAgICAgc3JjUGl4ZWwgPSBzcmNSYXN0LmdldERhdGFFbGVtZW50cyhzeCwgc3ksIG51bGwpOworICAgICAgICAgICAgICAgIGRzdFBpeGVsID0gZHN0UmFzdC5nZXREYXRhRWxlbWVudHMoZHgsIGR5LCBudWxsKTsKKworICAgICAgICAgICAgICAgIHNyY1JHQiA9IHNyY0NNLmdldFJHQihzcmNQaXhlbCk7CisgICAgICAgICAgICAgICAgZHN0UkdCID0gZHN0Q00uZ2V0UkdCKGRzdFBpeGVsKTsKKyAgICAgICAgICAgICAgICBkc3RSR0IgPSBzcmNSR0IgXiB4b3JSR0IgXiBkc3RSR0I7CisKKyAgICAgICAgICAgICAgICBkc3RSR0IgPSAweGZmMDAwMDAwIHwgZHN0UkdCOworICAgICAgICAgICAgICAgIGRzdFBpeGVsID0gZHN0Q00uZ2V0RGF0YUVsZW1lbnRzKGRzdFJHQiwgZHN0UGl4ZWwpOworICAgICAgICAgICAgICAgIGRzdFJhc3Quc2V0RGF0YUVsZW1lbnRzKGR4LGR5LGRzdFBpeGVsKTsKKworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmb3JtZWRCbGl0KENvbG9yTW9kZWwgc3JjQ00sIFJhc3RlciBzcmNSLCBpbnQgc3JjWCwgaW50IHNyY1ksCisgICAgICAgICAgICBDb2xvck1vZGVsIGRzdENNLCBXcml0YWJsZVJhc3RlciBkc3RSLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEFmZmluZVRyYW5zZm9ybSBhdCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLE11bHRpUmVjdEFyZWEgY2xpcCkgeworCisgICAgICAgIFJlY3RhbmdsZSBzcmNCb3VuZHMgPSBuZXcgUmVjdGFuZ2xlKHdpZHRoLCBoZWlnaHQpOworICAgICAgICBSZWN0YW5nbGUgZHN0QmxpdEJvdW5kcyA9IG5ldyBSZWN0YW5nbGUoZHN0WCwgZHN0WSwgc3JjUi5nZXRXaWR0aCgpLCBzcmNSLmdldEhlaWdodCgpKTsKKworICAgICAgICBSZWN0YW5nbGUgdHJhbnNTcmNCb3VuZHMgPSBnZXRCb3VuZHMyRChhdCwgc3JjQm91bmRzKS5nZXRCb3VuZHMoKTsKKyAgICAgICAgUmVjdGFuZ2xlIHRyYW5zRHN0QmxpdEJvdW5kcyA9IGdldEJvdW5kczJEKGF0LCBkc3RCbGl0Qm91bmRzKS5nZXRCb3VuZHMoKTsKKworICAgICAgICBpbnQgdHJhbnNsYXRlWCA9IHRyYW5zRHN0QmxpdEJvdW5kcy54IC0gdHJhbnNTcmNCb3VuZHMueDsKKyAgICAgICAgaW50IHRyYW5zbGF0ZVkgPSB0cmFuc0RzdEJsaXRCb3VuZHMueSAtIHRyYW5zU3JjQm91bmRzLnk7CisKKyAgICAgICAgQWZmaW5lVHJhbnNmb3JtIGludiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgaW52ID0gYXQuY3JlYXRlSW52ZXJzZSgpOworICAgICAgICB9IGNhdGNoIChOb25pbnZlcnRpYmxlVHJhbnNmb3JtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGRvdWJsZVtdIG0gPSBuZXcgZG91YmxlWzZdOworICAgICAgICBpbnYuZ2V0TWF0cml4KG0pOworCisgICAgICAgIGludCBjbGlwUmVjdHNbXTsKKyAgICAgICAgaWYoY2xpcCAhPSBudWxsKSB7CisgICAgICAgICAgICBjbGlwUmVjdHMgPSBjbGlwLnJlY3Q7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjbGlwUmVjdHMgPSBuZXcgaW50W117NSwgMCwgMCwgZHN0Ui5nZXRXaWR0aCgpLCBkc3RSLmdldEhlaWdodCgpfTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjb21wVHlwZSA9IDA7CisgICAgICAgIGludCBzcmNDb25zdEFscGhhID0gMDsKKyAgICAgICAgaW50IHJ1bGUgPSAwOworICAgICAgICBpbnQgYmdSR0IgPSBiZ2NvbG9yID09IG51bGwgPyAwIDogYmdjb2xvci5nZXRSR0IoKTsKKyAgICAgICAgaW50IHNyY1JHQiA9IDAsIGRzdFJHQiA9IDA7CisgICAgICAgIE9iamVjdCBzcmNWYWwgPSBudWxsLCBkc3RWYWwgPSBudWxsOworICAgICAgICBpZihjb21wIGluc3RhbmNlb2YgQWxwaGFDb21wb3NpdGUpeworICAgICAgICAgICAgY29tcFR5cGUgPSBBbHBoYUNvbXBvc2l0ZU1vZGU7CisgICAgICAgICAgICBBbHBoYUNvbXBvc2l0ZSBhYyA9IChBbHBoYUNvbXBvc2l0ZSkgY29tcDsKKyAgICAgICAgICAgIHJ1bGUgPSBhYy5nZXRSdWxlKCk7CisgICAgICAgICAgICBzcmNDb25zdEFscGhhID0gKGludCkoYWMuZ2V0QWxwaGEoKSAqIDI1NSArIDAuNWYpOworICAgICAgICB9ZWxzZSBpZihjb21wIGluc3RhbmNlb2YgWE9SQ29tcG9zaXRlKXsKKyAgICAgICAgICAgIGNvbXBUeXBlID0gWE9STW9kZTsKKyAgICAgICAgICAgIFhPUkNvbXBvc2l0ZSB4b3IgPSAoWE9SQ29tcG9zaXRlKSBjb21wOworICAgICAgICAgICAgYmdSR0IgPSB4b3IuZ2V0WE9SQ29sb3IoKS5nZXRSR0IoKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPCBjbGlwUmVjdHNbMF07IGkgKz0gNCl7CisgICAgICAgICAgICBSZWN0YW5nbGUgZHN0Qm91bmRzID0gbmV3IFJlY3RhbmdsZShjbGlwUmVjdHNbaV0sIGNsaXBSZWN0c1tpICsgMV0sIDAsIDApOworICAgICAgICAgICAgZHN0Qm91bmRzLmFkZChjbGlwUmVjdHNbaSArIDJdICsgMSwgY2xpcFJlY3RzW2kgKyAxXSk7CisgICAgICAgICAgICBkc3RCb3VuZHMuYWRkKGNsaXBSZWN0c1tpICsgMl0gKyAxLCBjbGlwUmVjdHNbaSArIDNdICsgMSk7CisgICAgICAgICAgICBkc3RCb3VuZHMuYWRkKGNsaXBSZWN0c1tpXSwgY2xpcFJlY3RzW2kgKyAzXSArIDEpOworCisgICAgICAgICAgICBSZWN0YW5nbGUgYm91bmRzID0gZHN0Qm91bmRzLmludGVyc2VjdGlvbih0cmFuc0RzdEJsaXRCb3VuZHMpOworCisgICAgICAgICAgICBpbnQgbWluU3JjWCA9IHNyY0JvdW5kcy54OworICAgICAgICAgICAgaW50IG1pblNyY1kgPSBzcmNCb3VuZHMueTsKKyAgICAgICAgICAgIGludCBtYXhTcmNYID0gbWluU3JjWCArIHNyY0JvdW5kcy53aWR0aDsKKyAgICAgICAgICAgIGludCBtYXhTcmNZID0gbWluU3JjWSArIHNyY0JvdW5kcy5oZWlnaHQ7CisKKyAgICAgICAgICAgIGludCBtaW5YID0gYm91bmRzLng7CisgICAgICAgICAgICBpbnQgbWluWSA9IGJvdW5kcy55OworICAgICAgICAgICAgaW50IG1heFggPSBtaW5YICsgYm91bmRzLndpZHRoOworICAgICAgICAgICAgaW50IG1heFkgPSBtaW5ZICsgYm91bmRzLmhlaWdodDsKKworICAgICAgICAgICAgaW50IGh4ID0gKGludCkoKG1bMF0gKiAyNTYpICsgMC41KTsKKyAgICAgICAgICAgIGludCBoeSA9IChpbnQpKChtWzFdICogMjU2KSArIDAuNSk7CisgICAgICAgICAgICBpbnQgdnggPSAoaW50KSgobVsyXSAqIDI1NikgKyAwLjUpOworICAgICAgICAgICAgaW50IHZ5ID0gKGludCkoKG1bM10gKiAyNTYpICsgMC41KTsKKyAgICAgICAgICAgIGludCBzeCA9IChpbnQpKChtWzRdICsgbVswXSAqIChib3VuZHMueCAtIHRyYW5zbGF0ZVgpICsgbVsyXSAqIChib3VuZHMueSAtIHRyYW5zbGF0ZVkpKSAqIDI1NiArIDAuNSk7CisgICAgICAgICAgICBpbnQgc3kgPSAoaW50KSgobVs1XSArIG1bMV0gKiAoYm91bmRzLnggLSB0cmFuc2xhdGVYKSArIG1bM10gKiAoYm91bmRzLnkgLSB0cmFuc2xhdGVZKSkgKiAyNTYgKyAwLjUpOworCisgICAgICAgICAgICB2eCAtPSBoeCAqIGJvdW5kcy53aWR0aDsKKyAgICAgICAgICAgIHZ5IC09IGh5ICogYm91bmRzLndpZHRoOworCisgICAgICAgICAgICBmb3IoaW50IHkgPSBtaW5ZOyB5IDwgbWF4WTsgeSsrKSB7CisgICAgICAgICAgICAgICAgZm9yKGludCB4ID0gbWluWDsgeCA8IG1heFg7IHgrKykgeworICAgICAgICAgICAgICAgICAgICBpbnQgcHggPSBzeCA+PiA4OworICAgICAgICAgICAgICAgICAgICBpbnQgcHkgPSBzeSA+PiA4OworICAgICAgICAgICAgICAgICAgICBpZiAocHggPj0gbWluU3JjWCAmJiBweSA+PSBtaW5TcmNZICYmIHB4IDwgbWF4U3JjWCAmJiBweSA8IG1heFNyY1kpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaChjb21wVHlwZSl7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZU1vZGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1ZhbCA9IHNyY1IuZ2V0RGF0YUVsZW1lbnRzKHB4ICwgcHkgLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjUkdCID0gc3JjQ00uZ2V0UkdCKHNyY1ZhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGJnY29sb3IgIT0gbnVsbCl7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RSR0IgPSBiZ1JHQjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RWYWwgPSBkc3RSLmdldERhdGFFbGVtZW50cyh4LCB5LCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiA9IGRzdENNLmdldFJHQihkc3RWYWwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiA9IGNvbXBvc2Uoc3JjUkdCLCBzcmNDTS5pc0FscGhhUHJlbXVsdGlwbGllZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiwgZHN0Q00uaGFzQWxwaGEoKSwgZHN0Q00uaXNBbHBoYVByZW11bHRpcGxpZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlLCBzcmNDb25zdEFscGhhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0VmFsID0gZHN0Q00uZ2V0RGF0YUVsZW1lbnRzKGRzdFJHQiwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFIuc2V0RGF0YUVsZW1lbnRzKHgsIHksIGRzdFZhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBYT1JNb2RlOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNWYWwgPSBzcmNSLmdldERhdGFFbGVtZW50cyhweCAsIHB5ICwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1JHQiA9IHNyY0NNLmdldFJHQihzcmNWYWwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RWYWwgPSBkc3RSLmdldERhdGFFbGVtZW50cyh4LCB5LCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0UkdCID0gZHN0Q00uZ2V0UkdCKGRzdFZhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiA9IHNyY1JHQiBeIGJnUkdCOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFJHQiA9IDB4ZmYwMDAwMDAgfCBkc3RSR0I7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFZhbCA9IGRzdENNLmdldERhdGFFbGVtZW50cyhkc3RSR0IsIG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RSLnNldERhdGFFbGVtZW50cyh4LCB5LCBkc3RWYWwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF3dC4zNz1Vbmtub3duICBjb21wb3NpdGUgdHlwZSB7MH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zNyIsIC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wLmdldENsYXNzKCkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzeCArPSBoeDsKKyAgICAgICAgICAgICAgICAgICAgc3kgKz0gaHk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN4ICs9IHZ4OworICAgICAgICAgICAgICAgIHN5ICs9IHZ5OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIFJlY3RhbmdsZTJEIGdldEJvdW5kczJEKEFmZmluZVRyYW5zZm9ybSBhdCwgUmVjdGFuZ2xlIHIpIHsKKyAgICAgICAgaW50IHggPSByLng7CisgICAgICAgIGludCB5ID0gci55OworICAgICAgICBpbnQgd2lkdGggPSByLndpZHRoOworICAgICAgICBpbnQgaGVpZ2h0ID0gci5oZWlnaHQ7CisKKyAgICAgICAgZmxvYXRbXSBjb3JuZXJzID0geworICAgICAgICAgICAgeCwgeSwKKyAgICAgICAgICAgIHggKyB3aWR0aCwgeSwKKyAgICAgICAgICAgIHggKyB3aWR0aCwgeSArIGhlaWdodCwKKyAgICAgICAgICAgIHgsIHkgKyBoZWlnaHQKKyAgICAgICAgfTsKKworICAgICAgICBhdC50cmFuc2Zvcm0oY29ybmVycywgMCwgY29ybmVycywgMCwgNCk7CisKKyAgICAgICAgUmVjdGFuZ2xlMkQuRmxvYXQgYm91bmRzID0gbmV3IFJlY3RhbmdsZTJELkZsb2F0KGNvcm5lcnNbMF0sIGNvcm5lcnNbMV0sIDAgLCAwKTsKKyAgICAgICAgYm91bmRzLmFkZChjb3JuZXJzWzJdLCBjb3JuZXJzWzNdKTsKKyAgICAgICAgYm91bmRzLmFkZChjb3JuZXJzWzRdLCBjb3JuZXJzWzVdKTsKKyAgICAgICAgYm91bmRzLmFkZChjb3JuZXJzWzZdLCBjb3JuZXJzWzddKTsKKworICAgICAgICByZXR1cm4gYm91bmRzOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGNvbXBvc2UoaW50IHNyY1JHQiwgYm9vbGVhbiBpc1NyY0FscGhhUHJlLAorICAgICAgICAgICAgaW50IGRzdFJHQiwgYm9vbGVhbiBkc3RIYXNBbHBoYSwgYm9vbGVhbiBpc0RzdEFscGhhUHJlLAorICAgICAgICAgICAgaW50IHJ1bGUsIGludCBzcmNDb25zdEFscGhhKXsKKworICAgICAgICBpbnQgc2EsIHNyLCBzZywgc2IsIGRhLCBkciwgZGcsIGRiOworCisgICAgICAgIHNhID0gKHNyY1JHQiA+PiAyNCkgJiAweGZmOworICAgICAgICBzciA9IChzcmNSR0IgPj4gMTYpICYgMHhmZjsKKyAgICAgICAgc2cgPSAoc3JjUkdCID4+IDgpICYgMHhmZjsKKyAgICAgICAgc2IgPSBzcmNSR0IgJiAweGZmOworCisgICAgICAgIGlmKGlzU3JjQWxwaGFQcmUpeworICAgICAgICAgICAgc2EgPSBtdWxMVVRbc3JjQ29uc3RBbHBoYV1bc2FdICYgMHhmZjsKKyAgICAgICAgICAgIHNyID0gbXVsTFVUW3NyY0NvbnN0QWxwaGFdW3NyXSAmIDB4ZmY7CisgICAgICAgICAgICBzZyA9IG11bExVVFtzcmNDb25zdEFscGhhXVtzZ10gJiAweGZmOworICAgICAgICAgICAgc2IgPSBtdWxMVVRbc3JjQ29uc3RBbHBoYV1bc2JdICYgMHhmZjsKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICBzYSA9IG11bExVVFtzcmNDb25zdEFscGhhXVtzYV0gJiAweGZmOworICAgICAgICAgICAgc3IgPSBtdWxMVVRbc2FdW3NyXSAmIDB4ZmY7CisgICAgICAgICAgICBzZyA9IG11bExVVFtzYV1bc2ddICYgMHhmZjsKKyAgICAgICAgICAgIHNiID0gbXVsTFVUW3NhXVtzYl0gJiAweGZmOworICAgICAgICB9CisKKyAgICAgICAgZGEgPSAoZHN0UkdCID4+IDI0KSAmIDB4ZmY7CisgICAgICAgIGRyID0gKGRzdFJHQiA+PiAxNikgJiAweGZmOworICAgICAgICBkZyA9IChkc3RSR0IgPj4gOCkgJiAweGZmOworICAgICAgICBkYiA9IGRzdFJHQiAmIDB4ZmY7CisKKyAgICAgICAgaWYoIWlzRHN0QWxwaGFQcmUpeworICAgICAgICAgICAgZHIgPSBtdWxMVVRbZGFdW2RyXSAmIDB4ZmY7CisgICAgICAgICAgICBkZyA9IG11bExVVFtkYV1bZGddICYgMHhmZjsKKyAgICAgICAgICAgIGRiID0gbXVsTFVUW2RhXVtkYl0gJiAweGZmOworICAgICAgICB9CisKKyAgICAgICAgaW50IEZzID0gMDsKKyAgICAgICAgaW50IEZkID0gMDsKKyAgICAgICAgc3dpdGNoKHJ1bGUpeworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLkNMRUFSOgorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5EU1Q6CisgICAgICAgICAgICBGZCA9IDI1NTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuRFNUX0FUT1A6CisgICAgICAgICAgICBGcyA9IDI1NSAtIGRhOworICAgICAgICAgICAgRmQgPSBzYTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuRFNUX0lOOgorICAgICAgICAgICAgRmQgPSBzYTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuRFNUX09VVDoKKyAgICAgICAgICAgIEZkID0gMjU1IC0gc2E7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLkRTVF9PVkVSOgorICAgICAgICAgICAgRnMgPSAyNTUgLSBkYTsKKyAgICAgICAgICAgIEZkID0gMjU1OworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5TUkM6CisgICAgICAgICAgICBGcyA9IDI1NTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuU1JDX0FUT1A6CisgICAgICAgICAgICBGcyA9IGRhOworICAgICAgICAgICAgRmQgPSAyNTUgLSBzYTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuU1JDX0lOOgorICAgICAgICAgICAgRnMgPSBkYTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgQWxwaGFDb21wb3NpdGUuU1JDX09VVDoKKyAgICAgICAgICAgIEZzID0gMjU1IC0gZGE7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFscGhhQ29tcG9zaXRlLlNSQ19PVkVSOgorICAgICAgICAgICAgRnMgPSAyNTU7CisgICAgICAgICAgICBGZCA9IDI1NSAtIHNhOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBBbHBoYUNvbXBvc2l0ZS5YT1I6CisgICAgICAgICAgICBGcyA9IDI1NSAtIGRhOworICAgICAgICAgICAgRmQgPSAyNTUgLSBzYTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGRyID0gKG11bExVVFtzcl1bRnNdICYgMHhmZikgKyAobXVsTFVUW2RyXVtGZF0gJiAweGZmKTsKKyAgICAgICAgZGcgPSAobXVsTFVUW3NnXVtGc10gJiAweGZmKSArIChtdWxMVVRbZGddW0ZkXSAmIDB4ZmYpOworICAgICAgICBkYiA9IChtdWxMVVRbc2JdW0ZzXSAmIDB4ZmYpICsgKG11bExVVFtkYl1bRmRdICYgMHhmZik7CisKKyAgICAgICAgZGEgPSAobXVsTFVUW3NhXVtGc10gJiAweGZmKSArIChtdWxMVVRbZGFdW0ZkXSAmIDB4ZmYpOworCisgICAgICAgIGlmKCFpc0RzdEFscGhhUHJlKXsKKyAgICAgICAgICAgIGlmKGRhICE9IDI1NSl7CisgICAgICAgICAgICAgICAgZHIgPSBkaXZMVVRbZGFdW2RyXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgZGcgPSBkaXZMVVRbZGFdW2RnXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgZGIgPSBkaXZMVVRbZGFdW2RiXSAmIDB4ZmY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYoIWRzdEhhc0FscGhhKSB7CisgICAgICAgICAgICBkYSA9IDB4ZmY7CisgICAgICAgIH0KKyAgICAgICAgZHN0UkdCID0gKGRhIDw8IDI0KSB8IChkciA8PCAxNikgfCAoZGcgPDwgOCkgfCBkYjsKKworICAgICAgICByZXR1cm4gZHN0UkdCOworCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YUxpbmVSYXN0ZXJpemVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YUxpbmVSYXN0ZXJpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWI2ZjdiNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9KYXZhTGluZVJhc3Rlcml6ZXIuamF2YQpAQCAtMCwwICsxLDc2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEZW5pcyBNLiBLaXNoZW5rbworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworCisKK3B1YmxpYyBjbGFzcyBKYXZhTGluZVJhc3Rlcml6ZXIgeworCisgICAgLyoqCisgICAgICogIExpbmVEYXNoZXIgY2xhc3MgcHJvdmlkZXMgZGFzaGluZyBmb3IgcGFydGljdWxhciBkYXNoIHN0eWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBMaW5lRGFzaGVyIHsKKworICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgIGZsb2F0IHBvczsKKyAgICAgICAgZmxvYXQgcGhhc2U7CisgICAgICAgIGZsb2F0IGRhc2hbXTsKKyAgICAgICAgZmxvYXQgaW52W107CisgICAgICAgIGJvb2xlYW4gdmlzaWJsZTsKKworICAgICAgICBwdWJsaWMgTGluZURhc2hlcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBMaW5lRGFzaGVyKGZsb2F0IGRhc2hbXSwgZmxvYXQgcGhhc2UpIHsKKyAgICAgICAgICAgIHRoaXMuZGFzaCA9IGRhc2g7CisgICAgICAgICAgICB0aGlzLnBoYXNlID0gcGhhc2U7CisKKyAgICAgICAgICAgIGludiA9IG5ldyBmbG9hdFtkYXNoLmxlbmd0aF07CisgICAgICAgICAgICBpbnQgaiA9IGRhc2gubGVuZ3RoOworICAgICAgICAgICAgZm9yIChmbG9hdCBlbGVtZW50IDogZGFzaCkgeworICAgICAgICAgICAgICAgIGludlstLWpdID0gZWxlbWVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGluZGV4ID0gMDsKKyAgICAgICAgICAgIHdoaWxlIChwaGFzZSA+IGRhc2hbaW5kZXhdKSB7CisgICAgICAgICAgICAgICAgcGhhc2UgLT0gZGFzaFtpbmRleF07CisgICAgICAgICAgICAgICAgaW5kZXggPSAoaW5kZXggKyAxKSAlIGRhc2gubGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdmlzaWJsZSA9IGluZGV4ICUgMiA9PSAwOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBtb3ZlKGZsb2F0IHN0ZXApIHsgLy8gbWFpbiBkYXNoZXIKKyAgICAgICAgICAgIHBvcyArPSBzdGVwOworICAgICAgICAgICAgc3RlcCArPSBwaGFzZTsKKyAgICAgICAgICAgIHdoaWxlKHN0ZXAgPj0gZGFzaFtpbmRleF0pIHsKKyAgICAgICAgICAgICAgICBzdGVwIC09IGRhc2hbaW5kZXhdOworICAgICAgICAgICAgICAgIGluZGV4ID0gKGluZGV4ICsgMSkgJSBkYXNoLmxlbmd0aDsKKyAgICAgICAgICAgICAgICB2aXNpYmxlID0gIXZpc2libGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwaGFzZSA9IHN0ZXA7CisgICAgICAgIH0KKworICAgICAgICBmbG9hdCBuZXh0RGFzaCgpIHsKKyAgICAgICAgICAgIHBoYXNlID0gMC4wZjsKKyAgICAgICAgICAgIGluZGV4ID0gKGluZGV4ICsgMSkgJSBkYXNoLmxlbmd0aDsKKyAgICAgICAgICAgIHZpc2libGUgPSAhdmlzaWJsZTsKKyAgICAgICAgICAgIHJldHVybiBkYXNoW2luZGV4XTsKKyAgICAgICAgfQorCisgICAgICAgIExpbmVEYXNoZXIgY3JlYXRlRGlhZ29uYWwoZG91YmxlIGssIGZsb2F0IGxlbmd0aCwgYm9vbGVhbiBpbnZlcnQpIHsKKyAgICAgICAgICAgIExpbmVEYXNoZXIgbG9jYWwgPSBuZXcgTGluZURhc2hlcigpOworICAgICAgICAgICAgbG9jYWwuZGFzaCA9IG5ldyBmbG9hdFtkYXNoLmxlbmd0aF07CisgICAgICAgICAgICBpZiAoaW52ZXJ0KSB7IC8vIGludmVydGVkIGRhc2hlcgorICAgICAgICAgICAgICAgIG1vdmUobGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBsb2NhbC5waGFzZSA9IChmbG9hdCkoKGRhc2hbaW5kZXhdIC0gcGhhc2UpICogayk7CisgICAgICAgICAgICAgICAgbG9jYWwudmlzaWJsZSA9IHZpc2libGU7CisgICAgICAgICAgICAgICAgbG9jYWwuaW5kZXggPSBpbnYubGVuZ3RoIC0gaW5kZXggLSAxOworICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBpbnYubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWwuZGFzaFtpXSA9IChmbG9hdCkoaW52W2ldICogayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBsb2NhbC5waGFzZSA9IChmbG9hdCkocGhhc2UgKiBrKTsKKyAgICAgICAgICAgICAgICBsb2NhbC52aXNpYmxlID0gdmlzaWJsZTsKKyAgICAgICAgICAgICAgICBsb2NhbC5pbmRleCA9IGluZGV4OworICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBkYXNoLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsLmRhc2hbaV0gPSAoZmxvYXQpKGRhc2hbaV0gKiBrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbW92ZShsZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxvY2FsOworICAgICAgICB9CisKKyAgICAgICAgTGluZURhc2hlciBjcmVhdGVPcnRvZ29uYWwoZmxvYXQgbGVuZ3RoLCBib29sZWFuIGludmVydCkgeworICAgICAgICAgICAgTGluZURhc2hlciBsb2NhbCA9IG5ldyBMaW5lRGFzaGVyKCk7CisgICAgICAgICAgICBsb2NhbC5kYXNoID0gbmV3IGZsb2F0W2Rhc2gubGVuZ3RoXTsKKyAgICAgICAgICAgIGlmIChpbnZlcnQpIHsgLy8gaW52ZXJ0ZWQgZGFzaGVyCisgICAgICAgICAgICAgICAgbW92ZShsZW5ndGgpOworICAgICAgICAgICAgICAgIGxvY2FsLnBoYXNlID0gZGFzaFtpbmRleF0gLSBwaGFzZTsKKyAgICAgICAgICAgICAgICBsb2NhbC52aXNpYmxlID0gdmlzaWJsZTsKKyAgICAgICAgICAgICAgICBsb2NhbC5pbmRleCA9IGludi5sZW5ndGggLSBpbmRleCAtIDE7CisgICAgICAgICAgICAgICAgbG9jYWwuZGFzaCA9IGludjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbG9jYWwucGhhc2UgPSBwaGFzZTsKKyAgICAgICAgICAgICAgICBsb2NhbC52aXNpYmxlID0gdmlzaWJsZTsKKyAgICAgICAgICAgICAgICBsb2NhbC5pbmRleCA9IGluZGV4OworICAgICAgICAgICAgICAgIGxvY2FsLmRhc2ggPSBkYXNoOworICAgICAgICAgICAgICAgIG1vdmUobGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsb2NhbDsKKyAgICAgICAgfQorCisgICAgICAgIExpbmVEYXNoZXIgY3JlYXRlQ2hpbGQoZmxvYXQgc3RhcnQpIHsKKyAgICAgICAgICAgIExpbmVEYXNoZXIgY2hpbGQgPSBuZXcgTGluZURhc2hlcigpOworICAgICAgICAgICAgY2hpbGQucGhhc2UgPSBwaGFzZTsKKyAgICAgICAgICAgIGNoaWxkLnZpc2libGUgPSB2aXNpYmxlOworICAgICAgICAgICAgY2hpbGQuaW5kZXggPSBpbmRleDsKKyAgICAgICAgICAgIGNoaWxkLmRhc2ggPSBkYXNoOworICAgICAgICAgICAgY2hpbGQubW92ZShzdGFydCk7CisgICAgICAgICAgICByZXR1cm4gY2hpbGQ7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIExpbmUgY2xhc3MgcHJvdmlkZXMgcmFzdGVyaXphdGlvbiBmb3IgZGlmZmVyZW50IGxpbmUgdHlwZXMKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgTGluZSB7CisKKyAgICAgICAgaW50IHgxLCB5MSwgeDIsIHkyOworICAgICAgICBpbnQgeCwgeTsKKyAgICAgICAgTXVsdGlSZWN0QXJlYSBkc3Q7CisKKyAgICAgICAgTGluZShpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIsIE11bHRpUmVjdEFyZWEgZHN0KSB7CisgICAgICAgICAgICB0aGlzLngxID0geDE7CisgICAgICAgICAgICB0aGlzLnkxID0geTE7CisgICAgICAgICAgICB0aGlzLngyID0geDI7CisgICAgICAgICAgICB0aGlzLnkyID0geTI7CisgICAgICAgICAgICB0aGlzLmRzdCA9IGRzdDsKKyAgICAgICAgfQorCisgICAgICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBEaWFnIGV4dGVuZHMgTGluZSB7CisgICAgICAgICAgICBpbnQgZHgsIGR5LCBhZHgsIGFkeSwgc3gsIHN5OworICAgICAgICAgICAgaW50IGVCYXNlLCBlUG9zLCBlTmVnOworICAgICAgICAgICAgaW50IHhjb3VudDsKKyAgICAgICAgICAgIGludCBlOworCisgICAgICAgICAgICBEaWFnKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MiwgTXVsdGlSZWN0QXJlYSBkc3QpIHsKKyAgICAgICAgICAgICAgICBzdXBlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgICAgICBkeCA9IHgyIC0geDE7CisgICAgICAgICAgICAgICAgZHkgPSB5MiAtIHkxOworICAgICAgICAgICAgICAgIHN5ID0gMTsKKyAgICAgICAgICAgICAgICBpZiAoZHggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGFkeCA9IGR4OworICAgICAgICAgICAgICAgICAgICBzeCA9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYWR4ID0gLWR4OworICAgICAgICAgICAgICAgICAgICBzeCA9IC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhZHkgPSBkeTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmxvYXQgZ2V0TGVuZ3RoKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAoZmxvYXQpTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RhdGljIGNsYXNzIEhvciBleHRlbmRzIERpYWcgeworCisgICAgICAgICAgICAgICAgSG9yKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MiwgTXVsdGlSZWN0QXJlYSBkc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIGVCYXNlID0gYWR5ICsgYWR5IC0gYWR4OworICAgICAgICAgICAgICAgICAgICBlUG9zID0gMiAqIChhZHkgLSBhZHgpOworICAgICAgICAgICAgICAgICAgICBlTmVnID0gYWR5ICsgYWR5OworICAgICAgICAgICAgICAgICAgICB4Y291bnQgPSBhZHg7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IHgxOworICAgICAgICAgICAgICAgICAgICB5ID0geTE7CisgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZSh4Y291bnQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplQ2xpcHBlZChpbnQgbngxLCBpbnQgbnkxLCBpbnQgbngyLCBpbnQgbnkyKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZSArIDIgKiAoYWR5ICogTWF0aC5hYnMobngxIC0geDEpIC0gYWR4ICogTWF0aC5hYnMobnkxIC0geTEpKTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IG54MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IG55MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplKGR4ID4gMCA/IG54MiAtIG54MSA6IG54MSAtIG54Mik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoaW50IGNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIGludCBweCA9IHg7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzeCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3QocHgsIHksIHgsIHkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0KHgsIHksIHB4LCB5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBzeDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICs9IHN5OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgKz0gZVBvczsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBweCA9IHg7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgKz0gZU5lZzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IHN4OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChzeCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0KHB4LCB5LCB4LCB5KTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0KHgsIHksIHB4LCB5KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgc2tpcChpbnQgY291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNvdW50LS0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IHN4OworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgKz0gc3k7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSArPSBlUG9zOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlICs9IGVOZWc7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RhdGljIGNsYXNzIFZlciBleHRlbmRzIERpYWcgeworCisgICAgICAgICAgICAgICAgVmVyKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MiwgTXVsdGlSZWN0QXJlYSBkc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIGVCYXNlID0gYWR4ICsgYWR4IC0gYWR5OworICAgICAgICAgICAgICAgICAgICBlUG9zID0gMiAqIChhZHggLSBhZHkpOworICAgICAgICAgICAgICAgICAgICBlTmVnID0gYWR4ICsgYWR4OworICAgICAgICAgICAgICAgICAgICB4Y291bnQgPSBhZHk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IHgxOworICAgICAgICAgICAgICAgICAgICB5ID0geTE7CisgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZSh4Y291bnQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplQ2xpcHBlZChpbnQgbngxLCBpbnQgbnkxLCBpbnQgbngyLCBpbnQgbnkyKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZSArIDIgKiAoYWR4ICogTWF0aC5hYnMobnkxIC0geTEpIC0gYWR5ICogTWF0aC5hYnMobngxIC0geDEpKTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IG54MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IG55MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplKG55MiAtIG55MSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoaW50IGNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIGludCBweSA9IHk7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdC5hZGRSZWN0KHgsIHB5LCB4LCB5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IHN4OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgKz0gc3k7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSArPSBlUG9zOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB5ID0geTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSArPSBzeTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlICs9IGVOZWc7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3QoeCwgcHksIHgsIHkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgc2tpcChpbnQgY291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNvdW50LS0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB5ICs9IHN5OworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gc3g7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSArPSBlUG9zOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlICs9IGVOZWc7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RhdGljIGNsYXNzIEhvckRhc2hlZCBleHRlbmRzIEhvciB7CisKKyAgICAgICAgICAgICAgICBMaW5lRGFzaGVyIGxvY2FsOworCisgICAgICAgICAgICAgICAgSG9yRGFzaGVkKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MiwgTXVsdGlSZWN0QXJlYSBkc3QsIExpbmVEYXNoZXIgZGFzaGVyLCBib29sZWFuIGludmVydCkgeworICAgICAgICAgICAgICAgICAgICBzdXBlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgbGVuZ3RoID0gZ2V0TGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsID0gZGFzaGVyLmNyZWF0ZURpYWdvbmFsKHhjb3VudCAvIGxlbmd0aCwgbGVuZ3RoLCBpbnZlcnQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICBlID0gZUJhc2U7CisgICAgICAgICAgICAgICAgICAgIHggPSB4MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IHkxOworICAgICAgICAgICAgICAgICAgICByYXN0ZXJpemVEYXNoKHhjb3VudCwgbG9jYWwpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplQ2xpcHBlZChpbnQgbngxLCBpbnQgbnkxLCBpbnQgbngyLCBpbnQgbnkyKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZSArIDIgKiAoYWR5ICogTWF0aC5hYnMobngxIC0geDEpIC0gYWR4ICogTWF0aC5hYnMobnkxIC0geTEpKTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IG54MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IG55MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplRGFzaChNYXRoLmFicyhueDIgLSBueDEpLCBsb2NhbC5jcmVhdGVDaGlsZChNYXRoLmFicyhueDEgLSB4MSkpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RhdGljIGNsYXNzIFZlckRhc2hlZCBleHRlbmRzIFZlciB7CisKKyAgICAgICAgICAgICAgICBMaW5lRGFzaGVyIGxvY2FsOworCisgICAgICAgICAgICAgICAgVmVyRGFzaGVkKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MiwgTXVsdGlSZWN0QXJlYSBkc3QsIExpbmVEYXNoZXIgZGFzaGVyLCBib29sZWFuIGludmVydCkgeworICAgICAgICAgICAgICAgICAgICBzdXBlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgZmxvYXQgbGVuZ3RoID0gZ2V0TGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsID0gZGFzaGVyLmNyZWF0ZURpYWdvbmFsKHhjb3VudCAvIGxlbmd0aCwgbGVuZ3RoLCBpbnZlcnQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICBlID0gZUJhc2U7CisgICAgICAgICAgICAgICAgICAgIHggPSB4MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IHkxOworICAgICAgICAgICAgICAgICAgICByYXN0ZXJpemVEYXNoKHhjb3VudCwgbG9jYWwpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplQ2xpcHBlZChpbnQgbngxLCBpbnQgbnkxLCBpbnQgbngyLCBpbnQgbnkyKSB7CisgICAgICAgICAgICAgICAgICAgIGUgPSBlQmFzZSArIDIgKiAoYWR4ICogTWF0aC5hYnMobnkxIC0geTEpIC0gYWR5ICogTWF0aC5hYnMobngxIC0geDEpKTsKKyAgICAgICAgICAgICAgICAgICAgeCA9IG54MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IG55MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplRGFzaChueTIgLSBueTEsIGxvY2FsLmNyZWF0ZUNoaWxkKG55MSAtIHkxKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoaW50W10gY2xpcCwgaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgaW50IGN4MSA9IGNsaXBbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICBpbnQgY3kxID0gY2xpcFtpbmRleCArIDFdOworICAgICAgICAgICAgICAgIGludCBjeDIgPSBjbGlwW2luZGV4ICsgMl0gKyAxOworICAgICAgICAgICAgICAgIGludCBjeTIgPSBjbGlwW2luZGV4ICsgM10gKyAxOworCisgICAgICAgICAgICAgICAgaW50IGNvZGUxID0KKyAgICAgICAgICAgICAgICAgICAgKHgxIDwgY3gxID8gMSA6IDApIHwgKHgxID49IGN4MiA/IDIgOiAwKSB8CisgICAgICAgICAgICAgICAgICAgICh5MSA8IGN5MSA/IDggOiAwKSB8ICh5MSA+PSBjeTIgPyA0IDogMCk7CisgICAgICAgICAgICAgICAgaW50IGNvZGUyID0KKyAgICAgICAgICAgICAgICAgICAgKHgyIDwgY3gxID8gMSA6IDApIHwgKHgyID49IGN4MiA/IDIgOiAwKSB8CisgICAgICAgICAgICAgICAgICAgICh5MiA8IGN5MSA/IDggOiAwKSB8ICh5MiA+PSBjeTIgPyA0IDogMCk7CisKKyAgICAgICAgICAgICAgICAvLyBPdXRzaWRlCisgICAgICAgICAgICAgICAgaWYgKChjb2RlMSAmIGNvZGUyKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBJbnNpZGUKKyAgICAgICAgICAgICAgICBpZiAoY29kZTEgPT0gMCAmJiBjb2RlMiA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gQ2xpcAorICAgICAgICAgICAgICAgIGludCBueDEgPSB4MTsKKyAgICAgICAgICAgICAgICBpbnQgbnkxID0geTE7CisgICAgICAgICAgICAgICAgaW50IG54MiA9IHgyOworICAgICAgICAgICAgICAgIGludCBueTIgPSB5MjsKKyAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIGNsaXAKKyAgICAgICAgICAgICAgICBjeDEgLT0geDE7IGN4MiAtPSB4MTsKKyAgICAgICAgICAgICAgICBjeTEgLT0geTE7IGN5MiAtPSB5MTsKKy8vICAgICAgICAgICAgICAgIGludCBkOworICAgICAgICAgICAgICAgIGludCBuZXd4MSA9IDAsIG5ld3kxID0gMCwgbmV3eDIgPSAwLCBuZXd5MiA9IDA7CisgICAgICAgICAgICAgICAgaWYgKGNvZGUxICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbmV3eDEgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChjb2RlMSAmIDgpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgcG9pbnQgMSB3aXRoIHRvcCBjbGlwIGJvdW5kCisgICAgICAgICAgICAgICAgICAgICAgICBuZXd5MSA9IGN5MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3gxID0gY2xpcFkoZHgsIGR5LCBuZXd5MSwgdHJ1ZSk7CisKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoY29kZTEgJiA0KSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbGlwIHBvaW50IDEgd2l0aCBib3R0b20gY2xpcCBib3VuZAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3eTEgPSBjeTIgLSAxOworICAgICAgICAgICAgICAgICAgICAgICAgbmV3eDEgPSBjbGlwWShkeCwgZHksIG5ld3kxLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKChjb2RlMSAmIDEpICE9IDAgJiYgKGN4MSA+IG5ld3gxIHx8IG5ld3gxID09IEludGVnZXIuTUFYX1ZBTFVFKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBwb2ludCAxIHdpdGggbGVmdCBjbGlwIGJvdW5kCisgICAgICAgICAgICAgICAgICAgICAgICBuZXd4MSA9IGN4MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3kxID0gY2xpcFgoZHgsIGR5LCBuZXd4MSwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChjb2RlMSAmIDIpICE9IDAgJiYgKG5ld3gxID49IGN4MiB8fCBuZXd4MSA9PSBJbnRlZ2VyLk1BWF9WQUxVRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgcG9pbnQgMSB3aXRoIHJpZ2h0IGNsaXAgYm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3gxID0gY3gyIC0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3kxID0gY2xpcFgoZHgsIGR5LCBuZXd4MSwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXd4MSA8IGN4MSB8fCBuZXd4MSA+PSBjeDIgfHwgbmV3eTEgPCBjeTEgfHwgbmV3eTEgPj0gY3kyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgICAgICBkID0gMiAqIChhZHkgKiBNYXRoLmFicyhuZXd4MSkgLSBhZHggKiBNYXRoLmFicyhuZXd5MSkpICsgMiAqIGFkeSAtIGFkeDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworLy8gICAgICAgICAgICAgICAgICAgIGQgPSAoYWR5IDw8IDEpIC0gYWR4OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChjb2RlMiAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIG5ld3gyPUludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICAgICAgICAgICAgICBpZiAoKGNvZGUyICYgOCkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBwb2ludCAyIHdpdGggdG9wIGNsaXAgYm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3kyID0gY3kxOworICAgICAgICAgICAgICAgICAgICAgICAgbmV3eDIgPSBjbGlwWShkeCwgZHksIG5ld3kyLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoY29kZTIgJiA0KSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbGlwIHBvaW50IDIgd2l0aCBib3R0b20gY2xpcCBib3VuZAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3eTIgPSBjeTIgLSAxOworICAgICAgICAgICAgICAgICAgICAgICAgbmV3eDIgPSBjbGlwWShkeCwgZHksIG5ld3kyLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKChjb2RlMiAmIDEpICE9IDAgJiYgKGN4MSA+IG5ld3gyIHx8IG5ld3gyID09IEludGVnZXIuTUFYX1ZBTFVFKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpcCBwb2ludCAyIHdpdGggbGVmdCBjbGlwIGJvdW5kCisgICAgICAgICAgICAgICAgICAgICAgICBuZXd4MiA9IGN4MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3kyID0gY2xpcFgoZHgsIGR5LCBuZXd4MiwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChjb2RlMiAmIDIpICE9IDAgJiYgKG5ld3gyID49IGN4MiB8fCBuZXd4MiA9PSBJbnRlZ2VyLk1BWF9WQUxVRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaXAgcG9pbnQgMiB3aXRoIHJpZ2h0IGNsaXAgYm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3gyID0gY3gyIC0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld3kyID0gY2xpcFgoZHgsIGR5LCBuZXd4MiwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXd4MiA8IGN4MSB8fCBuZXd4MiA+PSBjeDIgfHwgbmV3eTIgPCBjeTEgfHwgbmV3eTIgPj0gY3kyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbngyID0geDEgKyBuZXd4MjsKKyAgICAgICAgICAgICAgICAgICAgbnkyID0geTEgKyBuZXd5MjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbngxID0geDEgKyBuZXd4MTsKKyAgICAgICAgICAgICAgICBueTEgPSB5MSArIG5ld3kxOworCisgICAgICAgICAgICAgICAgcmFzdGVyaXplQ2xpcHBlZChueDEsIG55MSwgbngyLCBueTIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhYnN0cmFjdCB2b2lkIHJhc3Rlcml6ZUNsaXBwZWQoaW50IG54MSwgaW50IG55MSwgaW50IG54MiwgaW50IG55Mik7CisKKyAgICAgICAgfQorCisgICAgICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBPcnRvZyBleHRlbmRzIExpbmUgeworCisgICAgICAgICAgICBPcnRvZyhpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIsIE11bHRpUmVjdEFyZWEgZHN0KSB7CisgICAgICAgICAgICAgICAgc3VwZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0YXRpYyBjbGFzcyBIb3IgZXh0ZW5kcyBPcnRvZyB7CisKKyAgICAgICAgICAgICAgICBpbnQgZHg7CisKKyAgICAgICAgICAgICAgICBIb3IoaW50IHgxLCBpbnQgeTEsIGludCB4MiwgaW50IHkyLCBNdWx0aVJlY3RBcmVhIGRzdCkgeworICAgICAgICAgICAgICAgICAgICBzdXBlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgZHggPSB4MiAtIHgxOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZHggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MSwgeTEsIHgyLCB5Mik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MiwgeTIsIHgxLCB5MSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICB2b2lkIHJhc3Rlcml6ZShpbnQgc3RlcCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgcHggPSB4OworICAgICAgICAgICAgICAgICAgICBpZiAoZHggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IHN0ZXA7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdChweCwgeTEsIHggLSAxLCB5Mik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4IC09IHN0ZXA7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4ICsgMSwgeTIsIHB4LCB5MSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICB2b2lkIHNraXAoaW50IHN0ZXApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGR4ID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBzdGVwOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgeCAtPSBzdGVwOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemVDbGlwcGVkKGludCBueDEsIGludCBueDIpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG54MSA8IG54MikgeworICAgICAgICAgICAgICAgICAgICAgICAgZHN0LmFkZFJlY3QobngxLCB5MSwgbngyLCB5MSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdChueDIsIHkxLCBueDEsIHkxKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKGludFtdIGNsaXAsIGludCBpbmRleCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoeTEgPj0gY2xpcFtpbmRleCArIDFdICYmIHkxIDw9IGNsaXBbaW5kZXggKyAzXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGN4MSA9IGNsaXBbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBjeDIgPSBjbGlwW2luZGV4ICsgMl07CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeDEgPD0gY3gyICYmIHgyID49IGN4MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBueDEsIG54MjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZHggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG54MSA9IE1hdGgubWF4KHgxLCBjeDEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueDIgPSBNYXRoLm1pbih4MiwgY3gyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueDIgPSBNYXRoLm1heCh4MiwgY3gxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbngxID0gTWF0aC5taW4oeDEsIGN4Mik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZUNsaXBwZWQobngxLCBueDIpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0YXRpYyBjbGFzcyBWZXIgZXh0ZW5kcyBPcnRvZyB7CisKKyAgICAgICAgICAgICAgICBpbnQgZHk7CisKKyAgICAgICAgICAgICAgICBWZXIoaW50IHgxLCBpbnQgeTEsIGludCB4MiwgaW50IHkyLCBNdWx0aVJlY3RBcmVhIGRzdCkgeworICAgICAgICAgICAgICAgICAgICBzdXBlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgZHkgPSB5MiAtIHkxOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MSwgeTEsIHgyLCB5Mik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCByYXN0ZXJpemUoaW50IHN0ZXApIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHB5ID0geTsKKyAgICAgICAgICAgICAgICAgICAgeSArPSBzdGVwOworICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MSwgcHksIHgyLCB5IC0gMSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgdm9pZCBza2lwKGludCBzdGVwKSB7CisgICAgICAgICAgICAgICAgICAgIHkgKz0gc3RlcDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB2b2lkIHJhc3Rlcml6ZUNsaXBwZWQoaW50IG55MSwgaW50IG55MikgeworICAgICAgICAgICAgICAgICAgICBkc3QuYWRkUmVjdCh4MSwgbnkxLCB4MSwgbnkyKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICB2b2lkIHJhc3Rlcml6ZShpbnRbXSBjbGlwLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHgxID49IGNsaXBbaW5kZXhdICYmIHgxIDw9IGNsaXBbaW5kZXggKyAyXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGN5MSA9IGNsaXBbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBjeTIgPSBjbGlwW2luZGV4ICsgM107CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeTEgPD0gY3kyICYmIHkyID49IGN5MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZUNsaXBwZWQoTWF0aC5tYXgoeTEsIGN5MSksIE1hdGgubWluKHkyLCBjeTIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzdGF0aWMgY2xhc3MgSG9yRGFzaGVkIGV4dGVuZHMgSG9yIHsKKworICAgICAgICAgICAgICAgIExpbmVEYXNoZXIgbG9jYWw7CisKKyAgICAgICAgICAgICAgICBIb3JEYXNoZWQoaW50IHgxLCBpbnQgeTEsIGludCB4MiwgaW50IHkyLCBNdWx0aVJlY3RBcmVhIGRzdCwgTGluZURhc2hlciBkYXNoZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIGR4ID0geDIgLSB4MTsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWwgPSBkYXNoZXIuY3JlYXRlT3J0b2dvbmFsKE1hdGguYWJzKGR4KSwgZmFsc2UpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICB4ID0geDE7CisgICAgICAgICAgICAgICAgICAgIHkgPSB5MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplRGFzaChNYXRoLmFicyhkeCksIGxvY2FsKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICB2b2lkIHJhc3Rlcml6ZUNsaXBwZWQoaW50IG54MSwgaW50IG54MikgeworICAgICAgICAgICAgICAgICAgICB4ID0gbngxOworICAgICAgICAgICAgICAgICAgICB5ID0geTE7CisgICAgICAgICAgICAgICAgICAgIHJhc3Rlcml6ZURhc2goTWF0aC5hYnMobngyIC0gbngxKSwgbG9jYWwuY3JlYXRlQ2hpbGQoTWF0aC5hYnMobngxIC0geDEpKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0YXRpYyBjbGFzcyBWZXJEYXNoZWQgZXh0ZW5kcyBWZXIgeworCisgICAgICAgICAgICAgICAgTGluZURhc2hlciBsb2NhbDsKKworICAgICAgICAgICAgICAgIFZlckRhc2hlZChpbnQgeDEsIGludCB5MSwgaW50IHgyLCBpbnQgeTIsIE11bHRpUmVjdEFyZWEgZHN0LCBMaW5lRGFzaGVyIGRhc2hlciwgYm9vbGVhbiBpbnZlcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIGR5ID0geTIgLSB5MTsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWwgPSBkYXNoZXIuY3JlYXRlT3J0b2dvbmFsKGR5LCBpbnZlcnQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplKCkgeworICAgICAgICAgICAgICAgICAgICB4ID0geDE7CisgICAgICAgICAgICAgICAgICAgIHkgPSB5MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplRGFzaChkeSwgbG9jYWwpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgcmFzdGVyaXplQ2xpcHBlZChpbnQgbnkxLCBpbnQgbnkyKSB7CisgICAgICAgICAgICAgICAgICAgIHggPSB4MTsKKyAgICAgICAgICAgICAgICAgICAgeSA9IG55MTsKKyAgICAgICAgICAgICAgICAgICAgcmFzdGVyaXplRGFzaChueTIgLSBueTEsIGxvY2FsLmNyZWF0ZUNoaWxkKG55MSkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKworICAgICAgICBhYnN0cmFjdCB2b2lkIHJhc3Rlcml6ZSgpOworICAgICAgICBhYnN0cmFjdCB2b2lkIHJhc3Rlcml6ZShpbnRbXSBjbGlwLCBpbnQgaW5kZXgpOworICAgICAgICBhYnN0cmFjdCB2b2lkIHJhc3Rlcml6ZShpbnQgY291bnQpOworICAgICAgICBhYnN0cmFjdCB2b2lkIHNraXAoaW50IGNvdW50KTsKKworICAgICAgICB2b2lkIHJhc3Rlcml6ZURhc2goaW50IGNvdW50LCBMaW5lRGFzaGVyIGRhc2hlcikgeworICAgICAgICAgICAgZmxvYXQgZGVsdGEgPSBkYXNoZXIuZGFzaFtkYXNoZXIuaW5kZXhdIC0gZGFzaGVyLnBoYXNlOworICAgICAgICAgICAgaW50IHN0ZXAgPSAoaW50KWRlbHRhOworICAgICAgICAgICAgZGVsdGEgLT0gc3RlcDsKKyAgICAgICAgICAgIHdoaWxlKGNvdW50ID4gc3RlcCkgeworICAgICAgICAgICAgICAgIGlmIChkYXNoZXIudmlzaWJsZSkgeworICAgICAgICAgICAgICAgICAgICByYXN0ZXJpemUoc3RlcCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2tpcChzdGVwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY291bnQgLT0gc3RlcDsKKyAgICAgICAgICAgICAgICBkZWx0YSArPSBkYXNoZXIubmV4dERhc2goKTsKKyAgICAgICAgICAgICAgICBzdGVwID0gKGludClkZWx0YTsKKyAgICAgICAgICAgICAgICBkZWx0YSAtPSBzdGVwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNvdW50ID4gMCAmJiBkYXNoZXIudmlzaWJsZSkgeworICAgICAgICAgICAgICAgIHJhc3Rlcml6ZShjb3VudCk7CisgICAgICAgICAgICAgICAgZGFzaGVyLm1vdmUoY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21tb24gY2xpcHBpbmcgbWV0aG9kCisgICAgICovCisgICAgc3RhdGljIGludCBjbGlwKGludCBkWDEsIGludCBkWDIsIGludCBjWCwgYm9vbGVhbiB0b3ApIHsKKyAgICAgICAgaW50IGFkWDEgPSBkWDEgPCAwID8gLWRYMSA6IGRYMTsKKyAgICAgICAgaW50IGFkWDIgPSBkWDIgPCAwID8gLWRYMiA6IGRYMjsKKyAgICAgICAgaWYgKGFkWDEgPD0gYWRYMikgeworICAgICAgICAgICAgLy8gb2J0dXNlIGludGVyc2VjdGlvbiBhbmdsZQorICAgICAgICAgICAgcmV0dXJuICgoZFgxIDw8IDEpICogY1ggKyAoZFgxID4gMCA/IGRYMiA6IC1kWDIpKSAvIChkWDIgPDwgMSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGs7CisgICAgICAgIGlmICh0b3ApIHsKKyAgICAgICAgICAgIGsgPSAtZFgxICsgKGRYMiA8IDAgPyAwIDogZFgxID4gMCA/IChkWDIgPDwgMSkgOiAtKGRYMiA8PCAxKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBrID0gZFgxICsgKGRYMiA+IDAgPyAwIDogZFgxID4gMCA/IChkWDIgPDwgMSkgOiAtKGRYMiA8PCAxKSk7CisgICAgICAgIH0KKworICAgICAgICBrICs9IGRYMSA+IDAgPT0gZFgyID4gMCA/IC0xIDogMTsKKyAgICAgICAgcmV0dXJuICgoZFgxIDw8IDEpICogY1ggKyBrKSAvIChkWDIgPDwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xpcHBpbmcgYWxvbmcgWCBheGlzCisgICAgICovCisgICAgc3RhdGljIGludCBjbGlwWChpbnQgZHgsIGludCBkeSwgaW50IGN5LCBib29sZWFuIHRvcCkgeworICAgICAgICByZXR1cm4gY2xpcChkeSwgZHgsIGN5LCB0b3ApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsaXBwaW5nIGFsb25nIFkgYXhpcworICAgICAqLworICAgIHN0YXRpYyBpbnQgY2xpcFkoaW50IGR4LCBpbnQgZHksIGludCBjeCwgYm9vbGVhbiB0b3ApIHsKKyAgICAgICAgcmV0dXJuIGNsaXAoZHgsIGR5LCBjeCwgdG9wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSYXN0ZXJpemVzIGxpbmUgdXNpbmcgY2xpcHBpbmQgYW5kIGRhc2hpbmcgc3R5bGUKKyAgICAgKiBAcGFyYW0geDEgLSB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50CisgICAgICogQHBhcmFtIHkxIC0gdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludAorICAgICAqIEBwYXJhbSB4MiAtIHRoZSB4IGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50CisgICAgICogQHBhcmFtIHkyIC0gdGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQKKyAgICAgKiBAcGFyYW0gY2xpcCAtIHRoZSBNdWx0aVJlY3RBcmVhIG9iamVjdCBvZiBjbGlwcGluZyBhcmVhCisgICAgICogQHBhcmFtIGRhc2hlciAtIHRoZSBkYXNoZXIgc3R5bGUKKyAgICAgKiBAcGFyYW0gaW52ZXJ0IC0gdGhlIGludmVydCBpbmRpY2F0b3IsIGFsd2F5cyBmYWxzZQorICAgICAqIEByZXR1cm4gYSBNdWx0aVJlY3RBcmVhIG9mIHJhc3Rlcml6ZXIgbGluZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTXVsdGlSZWN0QXJlYSByYXN0ZXJpemUoaW50IHgxLCBpbnQgeTEsIGludCB4MiwgaW50IHkyLCBNdWx0aVJlY3RBcmVhIGNsaXAsIExpbmVEYXNoZXIgZGFzaGVyLCBib29sZWFuIGludmVydCkgeworCisgICAgICAgIE11bHRpUmVjdEFyZWEgZHN0ID0gbmV3IE11bHRpUmVjdEFyZWEoZmFsc2UpOworICAgICAgICBpbnQgZHggPSB4MiAtIHgxOworICAgICAgICBpbnQgZHkgPSB5MiAtIHkxOworCisgICAgICAgIC8vIFBvaW50CisgICAgICAgIGlmIChkeCA9PSAwICYmIGR5ID09IDApIHsKKyAgICAgICAgICAgIGlmICgoY2xpcCA9PSBudWxsIHx8IGNsaXAuY29udGFpbnMoeDEsIHkxKSkgJiYgKGRhc2hlciA9PSBudWxsIHx8IGRhc2hlci52aXNpYmxlKSkgeworICAgICAgICAgICAgICAgIGRzdCA9IG5ldyBNdWx0aVJlY3RBcmVhKHgxLCB5MSwgeDEsIHkxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkc3Q7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZHkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gcmFzdGVyaXplKHgyLCB5MiwgeDEsIHkxLCBjbGlwLCBkYXNoZXIsIHRydWUpOworICAgICAgICB9CisKKyAgICAgICAgTGluZSBsaW5lOworICAgICAgICBpZiAoZGFzaGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChkeCA9PSAwKSB7CisgICAgICAgICAgICAgICAgbGluZSA9IG5ldyBMaW5lLk9ydG9nLlZlcih4MSwgeTEsIHgyLCB5MiwgZHN0KTsKKyAgICAgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgICAgIGlmIChkeSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBuZXcgTGluZS5PcnRvZy5Ib3IoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGR5IDwgTWF0aC5hYnMoZHgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbmV3IExpbmUuRGlhZy5Ib3IoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbmV3IExpbmUuRGlhZy5WZXIoeDEsIHkxLCB4MiwgeTIsIGRzdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoZHggPT0gMCkgeworICAgICAgICAgICAgICAgIGxpbmUgPSBuZXcgTGluZS5PcnRvZy5WZXJEYXNoZWQoeDEsIHkxLCB4MiwgeTIsIGRzdCwgZGFzaGVyLCBpbnZlcnQpOworICAgICAgICAgICAgfSBlbHNlCisgICAgICAgICAgICAgICAgaWYgKGR5ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbGluZSA9IG5ldyBMaW5lLk9ydG9nLkhvckRhc2hlZCh4MSwgeTEsIHgyLCB5MiwgZHN0LCBkYXNoZXIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChkeSA8IE1hdGguYWJzKGR4KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbGluZSA9IG5ldyBMaW5lLkRpYWcuSG9yRGFzaGVkKHgxLCB5MSwgeDIsIHkyLCBkc3QsIGRhc2hlciwgaW52ZXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBuZXcgTGluZS5EaWFnLlZlckRhc2hlZCh4MSwgeTEsIHgyLCB5MiwgZHN0LCBkYXNoZXIsIGludmVydCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH0KKworCisgICAgICAgIGlmIChjbGlwID09IG51bGwgfHwgY2xpcC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGxpbmUucmFzdGVyaXplKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgY2xpcC5yZWN0WzBdOyBpICs9IDQpIHsKKyAgICAgICAgICAgICAgICBsaW5lLnJhc3Rlcml6ZShjbGlwLnJlY3QsIGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGRzdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9KYXZhU2hhcGVSYXN0ZXJpemVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YVNoYXBlUmFzdGVyaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiYWFmNTMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YVNoYXBlUmFzdGVyaXplci5qYXZhCkBAIC0wLDAgKzEsNDc1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERlbmlzIE0uIEtpc2hlbmtvCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXI7CisKK2ltcG9ydCBqYXZhLmF3dC5TaGFwZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLlBhdGhJdGVyYXRvcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuTXVsdGlSZWN0QXJlYTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworcHVibGljIGNsYXNzIEphdmFTaGFwZVJhc3Rlcml6ZXIgeworCisgICAgc3RhdGljIGZpbmFsIGludCBQT0lOVF9DQVBBQ0lUWSA9IDE2OworCisgICAgaW50IGVkZ2VzQ291bnQ7CisgICAgaW50IGVkZ2VDdXI7CisgICAgaW50W10gZWRnZXNYOworICAgIGludFtdIGVkZ2VzWTsKKyAgICBpbnRbXSBlZGdlc1lTOyAvLyBZIGNvb3JkaW5hdGUgb2YgZWRnZSBTVEFSVCBwb2ludAorICAgIGludFtdIGVkZ2VzTjsKKyAgICBpbnRbXSBlZGdlc0RZOworICAgIGludFtdIGJvdW5kczsKKyAgICBpbnQgYm91bmRDb3VudDsKKyAgICBib29sZWFuW10gZWRnZXNFeHQ7IC8vIEV4dHJlbWFsIHBvaW50cworCisgICAgaW50IGFjdGl2ZUNvdW50OworICAgIGZsb2F0W10gYWN0aXZlWDsKKyAgICBpbnRbXSBhY3RpdmVZRW5kOworICAgIGZsb2F0W10gYWN0aXZlWFN0ZXA7CisgICAgaW50W10gYWN0aXZlRFk7CisgICAgYm9vbGVhbltdIGFjdGl2ZUV4dDsKKworICAgIGludFtdIGNyb3NzWDsKKyAgICBpbnRbXSBjcm9zc0RZOworCisgICAgRmlsbGVyIGZpbGxlcjsKKworICAgIC8qKgorICAgICAqIFJhc3Rlcml6YXRpb24gZmlsbGVyIGZvciBkaWZmZXJlbnQgcGF0aCBydWxlcworICAgICAqLworICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBGaWxsZXIgeworCisgICAgICAgIHN0YXRpYyBjbGFzcyBOb25aZXJvIGV4dGVuZHMgRmlsbGVyIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgdm9pZCBhZGQoTXVsdGlSZWN0QXJlYS5MaW5lQ2FzaCByZWN0LCBpbnRbXSBwb2ludHMsIGludFtdIG9yaWVudCwgaW50IGxlbmd0aCwgaW50IHkpIHsKKworICAgICAgICAgICAgICAgIGludFtdIGRzdCA9IG5ldyBpbnRbbGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBpbnQgZHN0TGVuZ3RoID0gMTsKKyAgICAgICAgICAgICAgICBkc3RbMF0gPSBwb2ludHNbMF07CisgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICBib29sZWFuIGluc2lkZSA9IHRydWU7CisgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IG9yaWVudFtpXSA+IDAgPyAxIDogLTE7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkc3RbZHN0TGVuZ3RoKytdID0gcG9pbnRzW2ldOworICAgICAgICAgICAgICAgICAgICAgICAgaW5zaWRlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluc2lkZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdFtkc3RMZW5ndGgrK10gPSBwb2ludHNbaV07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zaWRlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMTsgaSA8IGRzdExlbmd0aDsgaSArPSAyKSB7CisgICAgICAgICAgICAgICAgICAgIGRzdFtpXS0tOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGRzdExlbmd0aCA9IGV4Y2x1ZGVFbXB0eShkc3QsIGRzdExlbmd0aCk7CisvLyAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0Iik7CisKKyAgICAgICAgICAgICAgICBkc3RMZW5ndGggPSB1bmlvbihkc3QsIGRzdExlbmd0aCk7CisKKyAgICAgICAgICAgICAgICByZWN0LmFkZExpbmUoZHN0LCBkc3RMZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc3RhdGljIGNsYXNzIEV2ZW5PZGQgZXh0ZW5kcyBGaWxsZXIgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICB2b2lkIGFkZChNdWx0aVJlY3RBcmVhLkxpbmVDYXNoIHJlY3QsIGludFtdIHBvaW50cywgaW50W10gb3JpZW50LCBpbnQgbGVuZ3RoLCBpbnQgeSkgeworICAgIC8qCisgICAgICAgICAgICAgICAgaW50W10gYnVmID0gbmV3IGludFtsZW5ndGhdOworICAgICAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGVuZ3RoIC0gMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChwb2ludHNbaV0gIT0gcG9pbnRzW2kgKyAxXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnVmW2orK10gPSBwb2ludHNbaV07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgKi8KKyAgICAgICAgICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyBpICs9IDIpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9pbnRzW2ldLS07CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgbGVuZ3RoID0gZXhjbHVkZUVtcHR5KHBvaW50cywgbGVuZ3RoKTsKKy8vICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3QiKTsKKworICAgICAgICAgICAgICAgIGxlbmd0aCA9IHVuaW9uKHBvaW50cywgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICByZWN0LmFkZExpbmUocG9pbnRzLCBsZW5ndGgpOworICAgIC8qCisgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxlbmd0aDspIHsKKyAgICAgICAgICAgICAgICAgICAgcmVjdC5hZGQocG9pbnRzW2krK10sIHksIHBvaW50c1tpKytdLCB5KTsKKyAgICAgICAgICAgICAgICB9CisgICAgKi8KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGFic3RyYWN0IHZvaWQgYWRkKE11bHRpUmVjdEFyZWEuTGluZUNhc2ggcmVjdCwgaW50W10gcG9pbnRzLCBpbnRbXSBvcmllbnQsIGludCBsZW5ndGgsIGludCB5KTsKKworICAgICAgICBzdGF0aWMgaW50IGV4Y2x1ZGVFbXB0eShpbnRbXSBwb2ludHMsIGludCBsZW5ndGgpIHsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIHdoaWxlKGkgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBpZiAocG9pbnRzW2ldIDw9IHBvaW50c1tpICsgMV0pIHsKKyAgICAgICAgICAgICAgICAgICAgaSArPSAyOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSAyOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBvaW50cywgaSArIDIsIHBvaW50cywgaSwgbGVuZ3RoIC0gaSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIHN0YXRpYyBpbnQgdW5pb24oaW50W10gcG9pbnRzLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgICAgICBpbnQgaSA9IDE7CisgICAgICAgICAgICB3aGlsZShpIDwgbGVuZ3RoIC0gMSkgeworICAgICAgICAgICAgICAgIGlmIChwb2ludHNbaV0gPCBwb2ludHNbaSAtIDFdKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocG9pbnRzLCBpICsgMSwgcG9pbnRzLCBpIC0gMSwgbGVuZ3RoIC0gaSAtIDEpOworICAgICAgICAgICAgICAgICAgICBsZW5ndGggLT0gMjsKKyAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICBpZiAocG9pbnRzW2ldID49IHBvaW50c1tpICsgMV0gLSAxKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocG9pbnRzLCBpICsgMiwgcG9pbnRzLCBpLCBsZW5ndGggLSBpIC0gMik7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSAyOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGkgKz0gMjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgSmF2YVNoYXBlUmFzdGVyaXplcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgYnVmZmVyIHNpemUgYW5kIHJlYWxsb2MgaWYgbmVjZXNzYXJ5CisgICAgICovCisgICAgaW50W10gY2hlY2tCdWZTaXplKGludFtdIGJ1ZiwgaW50IHNpemUpIHsKKyAgICAgICAgaWYgKHNpemUgPT0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgaW50W10gdG1wOworICAgICAgICAgICAgdG1wID0gbmV3IGludFtzaXplICsgUE9JTlRfQ0FQQUNJVFldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIHRtcCwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBidWYgPSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRvIHRoZSBidWZmZXJzIG5ldyBlZGdlIAorICAgICAqLworICAgIHZvaWQgYWRkRWRnZShpbnQgeCwgaW50IHksIGludCBudW0pIHsKKyAgICAgICAgZWRnZXNYID0gY2hlY2tCdWZTaXplKGVkZ2VzWCwgZWRnZXNDb3VudCk7CisgICAgICAgIGVkZ2VzWSA9IGNoZWNrQnVmU2l6ZShlZGdlc1ksIGVkZ2VzQ291bnQpOworICAgICAgICBlZGdlc04gPSBjaGVja0J1ZlNpemUoZWRnZXNOLCBlZGdlc0NvdW50KTsKKyAgICAgICAgZWRnZXNYW2VkZ2VzQ291bnRdID0geDsKKyAgICAgICAgZWRnZXNZW2VkZ2VzQ291bnRdID0geTsKKyAgICAgICAgZWRnZXNOW2VkZ2VzQ291bnRdID0gKG51bSA8PCAxNikgfCBlZGdlc0NvdW50OworICAgICAgICBlZGdlc0NvdW50Kys7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZSBhbGwgYnVmZmVycyBhbmQgdmFyaWFibGUgdG8gcmFzdGVyaXplIHNoYXBlIAorICAgICAqLworICAgIHZvaWQgbWFrZUJ1ZmZlcihQYXRoSXRlcmF0b3IgcGF0aCwgZG91YmxlIGZsYXRuZXNzKSB7CisgICAgICAgIGVkZ2VzWCA9IG5ldyBpbnRbUE9JTlRfQ0FQQUNJVFldOworICAgICAgICBlZGdlc1kgPSBuZXcgaW50W1BPSU5UX0NBUEFDSVRZXTsKKyAgICAgICAgZWRnZXNOID0gbmV3IGludFtQT0lOVF9DQVBBQ0lUWV07CisgICAgICAgIGJvdW5kcyA9IG5ldyBpbnRbUE9JTlRfQ0FQQUNJVFldOworICAgICAgICBib3VuZENvdW50ID0gMDsKKyAgICAgICAgZWRnZXNDb3VudCA9IDA7CisKKyAgICAgICAgaWYgKHBhdGguZ2V0V2luZGluZ1J1bGUoKSA9PSBQYXRoSXRlcmF0b3IuV0lORF9FVkVOX09ERCkgeworICAgICAgICAgICAgZmlsbGVyID0gbmV3IEZpbGxlci5FdmVuT2RkKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWxsZXIgPSBuZXcgRmlsbGVyLk5vblplcm8oKTsKKyAgICAgICAgfQorICAgICAgICBmbG9hdFtdIGNvb3JkcyA9IG5ldyBmbG9hdFsyXTsKKyAgICAgICAgYm9vbGVhbiBjbG9zZWQgPSB0cnVlOworICAgICAgICB3aGlsZSAoIXBhdGguaXNEb25lKCkpIHsKKyAgICAgICAgICAgIHN3aXRjaChwYXRoLmN1cnJlbnRTZWdtZW50KGNvb3JkcykpIHsKKyAgICAgICAgICAgIGNhc2UgUGF0aEl0ZXJhdG9yLlNFR19NT1ZFVE86CisgICAgICAgICAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgYm91bmRDb3VudCsrOworICAgICAgICAgICAgICAgICAgICBib3VuZHMgPSBjaGVja0J1ZlNpemUoYm91bmRzLCBib3VuZENvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgYm91bmRzW2JvdW5kQ291bnRdID0gZWRnZXNDb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYWRkRWRnZSgoaW50KWNvb3Jkc1swXSwgKGludCljb29yZHNbMV0sIGJvdW5kQ291bnQpOworICAgICAgICAgICAgICAgIGNsb3NlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBQYXRoSXRlcmF0b3IuU0VHX0xJTkVUTzoKKyAgICAgICAgICAgICAgICBhZGRFZGdlKChpbnQpY29vcmRzWzBdLCAoaW50KWNvb3Jkc1sxXSwgYm91bmRDb3VudCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFBhdGhJdGVyYXRvci5TRUdfQ0xPU0U6CisgICAgICAgICAgICAgICAgYm91bmRDb3VudCsrOworICAgICAgICAgICAgICAgIGJvdW5kcyA9IGNoZWNrQnVmU2l6ZShib3VuZHMsIGJvdW5kQ291bnQpOworICAgICAgICAgICAgICAgIGJvdW5kc1tib3VuZENvdW50XSA9IGVkZ2VzQ291bnQ7CisgICAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gYXd0LjM2PVdyb25nIHNlZ21lbnQKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4zNiIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcGF0aC5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIGJvdW5kQ291bnQrKzsKKyAgICAgICAgICAgIGJvdW5kcyA9IGNoZWNrQnVmU2l6ZShib3VuZHMsIGJvdW5kQ291bnQpOworICAgICAgICAgICAgYm91bmRzW2JvdW5kQ291bnRdID0gZWRnZXNDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnQgYnVmZmVycworICAgICAqLworICAgIHZvaWQgc29ydChpbnRbXSBtYXN0ZXIsIGludFtdIHNsYXZlLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsZW5ndGggLSAxOyBpKyspIHsKKyAgICAgICAgICAgIGludCBudW0gPSBpOworICAgICAgICAgICAgaW50IG1pbiA9IG1hc3RlcltudW1dOworICAgICAgICAgICAgZm9yKGludCBqID0gaSArIDE7IGogPCBsZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGlmIChtYXN0ZXJbal0gPCBtaW4pIHsKKyAgICAgICAgICAgICAgICAgICAgbnVtID0gajsKKyAgICAgICAgICAgICAgICAgICAgbWluID0gbWFzdGVyW251bV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG51bSAhPSBpKSB7CisgICAgICAgICAgICAgICAgbWFzdGVyW251bV0gPSBtYXN0ZXJbaV07CisgICAgICAgICAgICAgICAgbWFzdGVyW2ldID0gbWluOworICAgICAgICAgICAgICAgIG1pbiA9IHNsYXZlW251bV07CisgICAgICAgICAgICAgICAgc2xhdmVbbnVtXSA9IHNsYXZlW2ldOworICAgICAgICAgICAgICAgIHNsYXZlW2ldID0gbWluOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaW50IGdldE5leHQoaW50IGN1cikgeworICAgICAgICBpbnQgbiA9IGVkZ2VzTltjdXJdOworICAgICAgICBpbnQgYm91bmQgPSBuID4+IDE2OworICAgICAgICBpbnQgbnVtID0gKG4gJiAweEZGRkYpICsgMTsKKyAgICAgICAgaWYgKG51bSA9PSBib3VuZHNbYm91bmQgKyAxXSkgeworICAgICAgICAgICAgcmV0dXJuIGJvdW5kc1tib3VuZF07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bTsKKyAgICB9CisKKyAgICBpbnQgZ2V0UHJldihpbnQgY3VyKSB7CisgICAgICAgIGludCBuID0gZWRnZXNOW2N1cl07CisgICAgICAgIGludCBib3VuZCA9IG4gPj4gMTY7CisgICAgICAgIGludCBudW0gPSAobiAmIDB4RkZGRikgLSAxOworICAgICAgICBpZiAobnVtIDwgYm91bmRzW2JvdW5kXSkgeworICAgICAgICAgICAgcmV0dXJuIGJvdW5kc1tib3VuZCArIDFdIC0gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVtOworICAgIH0KKworICAgIGludCBnZXROZXh0U2hhcGUoaW50IGN1cikgeworICAgICAgICBpbnQgYm91bmQgPSBlZGdlc05bY3VyXSA+PiAxNjsKKyAgICAgICAgcmV0dXJuIGJvdW5kc1tib3VuZCArIDFdOworICAgIH0KKworICAgIHZvaWQgaW5pdCgpIHsKKworICAgICAgICBlZGdlc1lTID0gbmV3IGludFtlZGdlc0NvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlZGdlc1ksIDAsIGVkZ2VzWVMsIDAsIGVkZ2VzQ291bnQpOworICAgICAgICAvLyBDcmVhdGUgZWRnZXNEWQorICAgICAgICBlZGdlc0RZID0gbmV3IGludFtlZGdlc0NvdW50XTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGVkZ2VzQ291bnQ7IGkrKykgeworICAgICAgICAgICAgaW50IGR5ID0gZWRnZXNZW2dldE5leHQoaSldIC0gZWRnZXNZW2ldOworICAgICAgICAgICAgZWRnZXNEWVtpXSA9IGR5OworICAgICAgICB9CisKKyAgICAgICAgLy8gQ3JlYXRlIGVkZ2VzRXh0CisgICAgICAgIGVkZ2VzRXh0ID0gbmV3IGJvb2xlYW5bZWRnZXNDb3VudF07CisgICAgICAgIGludCBwcmV2ID0gLTE7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgaW50IHBvcyA9IDA7CisgICAgICAgIHdoaWxlKGkgPCBlZGdlc0NvdW50KSB7CisKKyAgICAgICAgICAgIFRPUDogeworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VzRFlbaV0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBUT1A7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaSA9IGdldE5leHQoaSk7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoaSAhPSBwb3MpOworICAgICAgICAgICAgICAgIGkgPSBwb3MgPSBnZXROZXh0U2hhcGUoaSk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEJPVFRPTTogeworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VzRFlbaV0gPCAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBCT1RUT007CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VzRFlbaV0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcmV2ID0gaTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpID0gZ2V0TmV4dChpKTsKKyAgICAgICAgICAgICAgICB9IHdoaWxlIChpICE9IHBvcyk7CisgICAgICAgICAgICAgICAgaSA9IHBvcyA9IGdldE5leHRTaGFwZShpKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHByZXYgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBlZGdlc0V4dFtwcmV2XSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlZGdlc0V4dFtpXSA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBTb3J0IGVkZ2VzWSBhbmQgZWRnZXNOCisgICAgICAgIHNvcnQoZWRnZXNZUywgZWRnZXNOLCBlZGdlc0NvdW50KTsKKworICAgICAgICBlZGdlQ3VyID0gMDsKKyAgICAgICAgYWN0aXZlQ291bnQgPSAwOworICAgICAgICBhY3RpdmVYID0gbmV3IGZsb2F0W2VkZ2VzQ291bnRdOworICAgICAgICBhY3RpdmVZRW5kID0gbmV3IGludFtlZGdlc0NvdW50XTsKKyAgICAgICAgYWN0aXZlWFN0ZXAgPSBuZXcgZmxvYXRbZWRnZXNDb3VudF07CisgICAgICAgIGFjdGl2ZURZID0gbmV3IGludFtlZGdlc0NvdW50XTsKKyAgICAgICAgYWN0aXZlRXh0ID0gbmV3IGJvb2xlYW5bZWRnZXNDb3VudF07CisKKyAgICAgICAgY3Jvc3NYID0gbmV3IGludFtlZGdlc0NvdW50XTsKKyAgICAgICAgY3Jvc3NEWSA9IG5ldyBpbnRbZWRnZXNDb3VudF07CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFya3MgZWRnZSBhcyBhY3RpdmUKKyAgICAgKi8KKyAgICB2b2lkIGFkZEFjdGl2ZUVkZ2UoaW50IGxldmVsWSwgaW50IHN0YXJ0LCBpbnQgZW5kLCBib29sZWFuIGJhY2spIHsKKyAgICAgICAgaW50IGR5ID0gYmFjayA/IC1lZGdlc0RZW2VuZF0gOiBlZGdlc0RZW3N0YXJ0XTsKKyAgICAgICAgaWYgKGR5IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgeDEgPSBlZGdlc1hbc3RhcnRdOworICAgICAgICBpbnQgZHggPSBlZGdlc1hbZW5kXSAtIHgxOworICAgICAgICBhY3RpdmVYW2FjdGl2ZUNvdW50XSA9IHgxOworICAgICAgICBhY3RpdmVZRW5kW2FjdGl2ZUNvdW50XSA9IGVkZ2VzWVtlbmRdOworICAgICAgICBhY3RpdmVYU3RlcFthY3RpdmVDb3VudF0gPSBkeCAvIChmbG9hdClkeTsKKyAgICAgICAgYWN0aXZlRFlbYWN0aXZlQ291bnRdID0gYmFjayA/IC1keSA6IGR5OworICAgICAgICBhY3RpdmVFeHRbYWN0aXZlQ291bnRdID0gYmFjayA/IGVkZ2VzRXh0W2VuZF0gOiBlZGdlc0V4dFtzdGFydF07CisgICAgICAgIGFjdGl2ZUNvdW50Kys7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBuZXcgYWN0aXZlIGVkZ2VzCisgICAgICovCisgICAgaW50IGZpbmRBY3RpdmVFZGdlcyhpbnQgbGV2ZWxZKSB7CisKKyAgICAgICAgaW50IGVkZ2VBY3RpdmUgPSBlZGdlQ3VyOworICAgICAgICB3aGlsZSAoZWRnZUFjdGl2ZSA8IGVkZ2VzQ291bnQgJiYgZWRnZXNZU1tlZGdlQWN0aXZlXSA9PSBsZXZlbFkpIHsKKyAgICAgICAgICAgIGVkZ2VBY3RpdmUrKzsKKyAgICAgICAgfQorCisgICAgICAgIGludCBhY3RpdmVOZXh0ID0gZWRnZUFjdGl2ZTsKKworICAgICAgICB3aGlsZSAoZWRnZUFjdGl2ZSA+IGVkZ2VDdXIpIHsKKyAgICAgICAgICAgIGVkZ2VBY3RpdmUtLTsKKyAgICAgICAgICAgIGludCBudW0gPSBlZGdlc05bZWRnZUFjdGl2ZV0gJiAweEZGRkY7CisgICAgICAgICAgICBhZGRBY3RpdmVFZGdlKGxldmVsWSwgbnVtLCBnZXRQcmV2KGVkZ2VBY3RpdmUpLCB0cnVlKTsKKyAgICAgICAgICAgIGFkZEFjdGl2ZUVkZ2UobGV2ZWxZLCBudW0sIGdldE5leHQoZWRnZUFjdGl2ZSksIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIGVkZ2VDdXIgPSBhY3RpdmVOZXh0OworCisgICAgICAgIGlmIChhY3RpdmVOZXh0ID09IGVkZ2VzQ291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiBlZGdlc1lbZWRnZXNDb3VudCAtIDFdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlZGdlc1lTW2FjdGl2ZU5leHRdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJhc3Rlcml6ZXMgc2hhcGUgd2l0aCBwYXJ0aWN1bGFyIGZsYXRuZXNzCisgICAgICogQHBhcmFtIHNoYXBlIC0gdGhlIHNvdXplIFNoYXBlIHRvIGJlIHJhc3Rlcml6ZWQKKyAgICAgKiBAcGFyYW0gZmxhdG5lc3MgLSB0aGUgcmFzdGVyaXphdGlvbiBmbGF0bmVzcworICAgICAqIEByZXR1cm4gYSBNdWx0aVJlY3RBcmVhIG9mIHJhc3Rlcml6ZWQgc2hhcGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTXVsdGlSZWN0QXJlYSByYXN0ZXJpemUoU2hhcGUgc2hhcGUsIGRvdWJsZSBmbGF0bmVzcykgeworCisgICAgICAgIFBhdGhJdGVyYXRvciBwYXRoID0gc2hhcGUuZ2V0UGF0aEl0ZXJhdG9yKG51bGwsIGZsYXRuZXNzKTsKKworICAgICAgICAvLyBTaGFwZSBpcyBlbXB0eQorICAgICAgICBpZiAocGF0aC5pc0RvbmUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNdWx0aVJlY3RBcmVhKCk7CisgICAgICAgIH0KKworICAgICAgICBtYWtlQnVmZmVyKHBhdGgsIGZsYXRuZXNzKTsKKworICAgICAgICBpbml0KCk7CisKKyAgICAgICAgaW50IHkgPSBlZGdlc1lTWzBdOworICAgICAgICBpbnQgbmV4dFkgPSB5OworICAgICAgICBpbnQgY3Jvc3NDb3VudDsKKworICAgICAgICBNdWx0aVJlY3RBcmVhLkxpbmVDYXNoIHJlY3QgPSBuZXcgTXVsdGlSZWN0QXJlYS5MaW5lQ2FzaChlZGdlc0NvdW50KTsKKyAgICAgICAgcmVjdC5zZXRMaW5lKHkpOworCisgICAgICAgIHdoaWxlKHkgPD0gbmV4dFkpIHsKKworICAgICAgICAgICAgY3Jvc3NDb3VudCA9IDA7CisKKyAgICAgICAgICAgIGlmICh5ID09IG5leHRZKSB7CisKKyAgICAgICAgICAgICAgICBpbnQgaSA9IGFjdGl2ZUNvdW50OworICAgICAgICAgICAgICAgIHdoaWxlKGkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGktLTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVlFbmRbaV0gPT0geSkgeworCisgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVDb3VudC0tOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGFjdGl2ZUNvdW50IC0gaTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwb3MgPSBpICsgMTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFjdGl2ZVgsIHBvcywgYWN0aXZlWCwgaSwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFjdGl2ZVlFbmQsIHBvcywgYWN0aXZlWUVuZCwgaSwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFjdGl2ZVhTdGVwLCBwb3MsIGFjdGl2ZVhTdGVwLCBpLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYWN0aXZlRFksIHBvcywgYWN0aXZlRFksIGksIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhY3RpdmVFeHQsIHBvcywgYWN0aXZlRXh0LCBpLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgbmV4dFkgPSBmaW5kQWN0aXZlRWRnZXMoeSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEdldCBYIGNyb3NzaW5ncworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGFjdGl2ZUNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBjcm9zc1hbY3Jvc3NDb3VudF0gPSAoaW50KU1hdGguY2VpbChhY3RpdmVYW2ldKTsKKyAgICAgICAgICAgICAgICBjcm9zc0RZW2Nyb3NzQ291bnRdID0gYWN0aXZlRFlbaV07CisgICAgICAgICAgICAgICAgY3Jvc3NDb3VudCsrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY3Jvc3NDb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmVjdC5za2lwTGluZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBTb3J0IFggY3Jvc3NpbmdzCisgICAgICAgICAgICAgICAgc29ydChjcm9zc1gsIGNyb3NzRFksIGNyb3NzQ291bnQpOworICAgICAgICAgICAgICAgIGZpbGxlci5hZGQocmVjdCwgY3Jvc3NYLCBjcm9zc0RZLCBjcm9zc0NvdW50LCB5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGFjdGl2ZUNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBhY3RpdmVYW2ldICs9IGFjdGl2ZVhTdGVwW2ldOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB5Kys7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVjdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2dsL3JlbmRlci9KYXZhVGV4dFJlbmRlcmVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YVRleHRSZW5kZXJlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMmJhNTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvSmF2YVRleHRSZW5kZXJlci5qYXZhCkBAIC0wLDAgKzEsMjYzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5yZW5kZXI7CisKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmEuYXd0LmltYWdlLio7CisKKworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhNZXRyaWNzOworaW1wb3J0IGphdmEuYXd0LmZvbnQuR2x5cGhWZWN0b3I7CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5BZmZpbmVUcmFuc2Zvcm07CitpbXBvcnQgamF2YS5hd3QuZ2VvbS5Qb2ludDJEOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5UZXh0UmVuZGVyZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkNvbW1vbkdseXBoVmVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuZm9udC5Gb250UGVlckltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkdseXBoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQ7CisKK3B1YmxpYyBjbGFzcyBKYXZhVGV4dFJlbmRlcmVyIGV4dGVuZHMgVGV4dFJlbmRlcmVyIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSmF2YVRleHRSZW5kZXJlciBpbnN0ID0gbmV3IEphdmFUZXh0UmVuZGVyZXIoKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdHbHlwaFZlY3RvcihHcmFwaGljczJEIGcsIEdseXBoVmVjdG9yIGdseXBoVmVjdG9yLAorICAgICAgICAgICAgZmxvYXQgeCwgZmxvYXQgeSkgeworCisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBhdCA9IGcuZ2V0VHJhbnNmb3JtKCk7CisgICAgICAgIFJlY3RhbmdsZSBjID0gZy5nZXRDbGlwQm91bmRzKCk7CisgICAgICAgIGlmIChhdCAhPSBudWxsKXsKKyAgICAgICAgICAgIGludCBhdFR5cGUgPSBhdC5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZiAoYXRUeXBlID09IEFmZmluZVRyYW5zZm9ybS5UWVBFX1RSQU5TTEFUSU9OKSB7CisgICAgICAgICAgICAgICAgYy50cmFuc2xhdGUoKGludClNYXRoLnJvdW5kKGF0LmdldFRyYW5zbGF0ZVgoKSksIChpbnQpTWF0aC5yb3VuZChhdC5nZXRUcmFuc2xhdGVZKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFdyaXRhYmxlUmFzdGVyIHdyID0gKChCdWZmZXJlZEltYWdlR3JhcGhpY3MyRClnKS5nZXRXcml0YWJsZVJhc3RlcigpOworICAgICAgICBDb2xvck1vZGVsIGNtID0gKChCdWZmZXJlZEltYWdlR3JhcGhpY3MyRClnKS5nZXRDb2xvck1vZGVsKCk7CisKKyAgICAgICAgUmVjdGFuZ2xlIHJCb3VuZHMgPSB3ci5nZXRCb3VuZHMoKTsKKworICAgICAgICBPYmplY3QgY29sb3IgPSBjbS5nZXREYXRhRWxlbWVudHMoZy5nZXRDb2xvcigpLmdldFJHQigpLCBudWxsKTsKKworICAgICAgICBkcmF3Q2xpcEdseXBoVmVjdG9yKHdyLCBjb2xvciwgZ2x5cGhWZWN0b3IsIChpbnQpTWF0aC5yb3VuZCh4ICsgYXQuZ2V0VHJhbnNsYXRlWCgpKSwgKGludClNYXRoLnJvdW5kKHkgKyBhdC5nZXRUcmFuc2xhdGVZKCkpLAorICAgICAgICBNYXRoLm1heChjLngsckJvdW5kcy54KSwKKyAgICAgICAgTWF0aC5tYXgoYy55LHJCb3VuZHMueSksCisgICAgICAgIE1hdGgubWluKChpbnQpTWF0aC5yb3VuZChjLmdldE1heFgoKSksIChpbnQpTWF0aC5yb3VuZChyQm91bmRzLmdldE1heFgoKSkpLAorICAgICAgICBNYXRoLm1pbigoaW50KU1hdGgucm91bmQoYy5nZXRNYXhZKCkpLCAoaW50KU1hdGgucm91bmQockJvdW5kcy5nZXRNYXhZKCkpKSk7CisKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRyYXdTdHJpbmcoR3JhcGhpY3MyRCBnLCBTdHJpbmcgc3RyLCBmbG9hdCB4LCBmbG9hdCB5KSB7CisgICAgICAgIEFmZmluZVRyYW5zZm9ybSBhdCA9IGcuZ2V0VHJhbnNmb3JtKCk7CisgICAgICAgIFJlY3RhbmdsZSBjID0gZy5nZXRDbGlwQm91bmRzKCk7CisgICAgICAgIGlmIChhdCAhPSBudWxsKXsKKyAgICAgICAgICAgIGludCBhdFR5cGUgPSBhdC5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZiAoYXRUeXBlID09IEFmZmluZVRyYW5zZm9ybS5UWVBFX1RSQU5TTEFUSU9OKSB7CisgICAgICAgICAgICAgICAgYy50cmFuc2xhdGUoKGludClNYXRoLnJvdW5kKGF0LmdldFRyYW5zbGF0ZVgoKSksIChpbnQpTWF0aC5yb3VuZChhdC5nZXRUcmFuc2xhdGVZKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBXcml0YWJsZVJhc3RlciB3ciA9ICgoQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQpZykuZ2V0V3JpdGFibGVSYXN0ZXIoKTsKKyAgICAgICAgQ29sb3JNb2RlbCBjbSA9ICgoQnVmZmVyZWRJbWFnZUdyYXBoaWNzMkQpZykuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICBSZWN0YW5nbGUgckJvdW5kcyA9IHdyLmdldEJvdW5kcygpOworCisgICAgICAgIE9iamVjdCBjb2xvciA9IGNtLmdldERhdGFFbGVtZW50cyhnLmdldENvbG9yKCkuZ2V0UkdCKCksIG51bGwpOworCisgICAgICAgIGRyYXdDbGlwU3RyaW5nKHdyLCBjb2xvciwgc3RyLCAoRm9udFBlZXJJbXBsKSAoZy5nZXRGb250KCkuZ2V0UGVlcigpKSwKKyAgICAgICAgICAgICAgICAoaW50KU1hdGgucm91bmQoeCArIGF0LmdldFRyYW5zbGF0ZVgoKSksIChpbnQpTWF0aC5yb3VuZCh5ICsgYXQuZ2V0VHJhbnNsYXRlWSgpKSwKKyAgICAgICAgICAgICAgICBNYXRoLm1heChjLngsckJvdW5kcy54KSwKKyAgICAgICAgICAgICAgICBNYXRoLm1heChjLnksckJvdW5kcy55KSwKKyAgICAgICAgICAgICAgICBNYXRoLm1pbigoaW50KU1hdGgucm91bmQoYy5nZXRNYXhYKCkpLCAoaW50KU1hdGgucm91bmQockJvdW5kcy5nZXRNYXhYKCkpKSwKKyAgICAgICAgICAgICAgICBNYXRoLm1pbigoaW50KU1hdGgucm91bmQoYy5nZXRNYXhZKCkpLCAoaW50KU1hdGgucm91bmQockJvdW5kcy5nZXRNYXhZKCkpKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAKKyAgICAgKiBEcmF3cyBzdHJpbmcgb24gc3BlY2lmaWVkIHJhc3RlciBhdCBkZXNpcmVkIHBvc2l0aW9uLgorICAgICAqICAKKyAgICAgKiBAcGFyYW0gcmFzdGVyIHNwZWNpZmllZCBXcml0YWJsZVJhc3RlciB0byBkcmF3IGF0CisgICAgICogQHBhcmFtIGNvbG9yIGNvbG9yIG9mIHRoZSB0ZXh0CisgICAgICogQHBhcmFtIGdseXBoVmVjdG9yIEdseXBoVmVjdG9yIG9iamVjdCB0byBkcmF3CisgICAgICogQHBhcmFtIHggc3RhcnQgWCBwb3NpdGlvbiB0byBkcmF3CisgICAgICogQHBhcmFtIHkgc3RhcnQgWSBwb3NpdGlvbiB0byBkcmF3CisgICAgICogQHBhcmFtIGNNaW5YIG1pbmltdW0geCBvZiB0aGUgcmFzdGVyIGFyZWEgdG8gZHJhdworICAgICAqIEBwYXJhbSBjTWluWSBtaW5pbXVtIHkgb2YgdGhlIHJhc3RlciBhcmVhIHRvIGRyYXcKKyAgICAgKiBAcGFyYW0gY01heFggbWF4aW11bSB4IG9mIHRoZSByYXN0ZXIgYXJlYSB0byBkcmF3CisgICAgICogQHBhcmFtIGNNYXhZIG1heGltdW0geSBvZiB0aGUgcmFzdGVyIGFyZWEgdG8gZHJhdworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRyYXdDbGlwR2x5cGhWZWN0b3IoV3JpdGFibGVSYXN0ZXIgcmFzdGVyLCBPYmplY3QgY29sb3IsCisgICAgICAgICAgICBHbHlwaFZlY3RvciBnbHlwaFZlY3RvciwgaW50IHgsIGludCB5LAorICAgICAgICAgICAgaW50IGNNaW5YLCBpbnQgY01pblksIGludCBjTWF4WCwgaW50IGNNYXhZKSB7CisgICAgICAgIC8vIFRPRE86IGltcGxlbWVudCBjb21wbGV4IGNsaXBwaW5nCisKKyAgICAgICAgaW50IHhTcmNTdXJmLCB5U3JjU3VyZjsgLy8gU3RhcnQgcG9pbnQgaW4gU3RyaW5nIHJlY3RhbmdsZQorICAgICAgICBpbnQgeERzdFN1cmYsIHlEc3RTdXJmOyAvLyBTdGFydCBwb2ludCBpbiBTdXJmYWNlIHJlY3RhbmdsZQorICAgICAgICBpbnQgY2xXaWR0aCwgY2xIZWlnaHQ7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnbHlwaFZlY3Rvci5nZXROdW1HbHlwaHMoKTsgaSsrKSB7CisgICAgICAgICAgICBHbHlwaCBnbCA9ICgoQ29tbW9uR2x5cGhWZWN0b3IpIGdseXBoVmVjdG9yKS52ZWN0b3JbaV07CisKKyAgICAgICAgICAgIGlmIChnbC5nZXRQb2ludFdpZHRoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBieXRlW10gZGF0YSA9IGdsLmdldEJpdG1hcCgpOworICAgICAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFBvaW50MkQgcG9zID0gZ2x5cGhWZWN0b3IuZ2V0R2x5cGhQb3NpdGlvbihpKTsKKworICAgICAgICAgICAgICAgIHhTcmNTdXJmID0gMDsvL2dsLmJtcF9sZWZ0OworICAgICAgICAgICAgICAgIHlTcmNTdXJmID0gMDsvL2dsLmJtcF9yb3dzIC0gZ2wuYm1wX3RvcDsKKworICAgICAgICAgICAgICAgIHhEc3RTdXJmID0geCArIChpbnQpcG9zLmdldFgoKSArIChpbnQpIGdsLmdldEdseXBoUG9pbnRNZXRyaWNzKCkuZ2V0TFNCKCk7Ly8gKyBnbC5ibXBfbGVmdDsKKyAgICAgICAgICAgICAgICB5RHN0U3VyZiA9IHkgLSBnbC5ibXBfdG9wLypnZXRQb2ludEhlaWdodCgpKi8gICsgKGludCkgcG9zLmdldFkoKTsvLyAtIChnbC5ibXBfcm93cy1nbC5ibXBfdG9wKTsKKworICAgICAgICAgICAgICAgIGludCB0ZXh0V2lkdGggPSBnbC5ibXBfd2lkdGg7CisgICAgICAgICAgICAgICAgaW50IHRleHRIZWlnaHQgPSBnbC5nZXRQb2ludEhlaWdodCgpOworCisgICAgICAgICAgICAgICAgLy8gaWYgUmVnaW9ucyBkb24ndCBpbnRlcnNlY3QKKyAgICAgICAgICAgICAgICBpZiAoKHhEc3RTdXJmID4gY01heFgpIHx8ICh5RHN0U3VyZiA+IGNNYXhZKSB8fCAoeERzdFN1cmYgKyB0ZXh0V2lkdGggPCBjTWluWCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh5RHN0U3VyZiArIHRleHRIZWlnaHQgPCBjTWluWSkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh4RHN0U3VyZiA+PSBjTWluWCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2xXaWR0aCA9IE1hdGgubWluKHRleHRXaWR0aCwgY01heFggLSB4RHN0U3VyZik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4U3JjU3VyZiArPSBjTWluWCAtIHhEc3RTdXJmOworICAgICAgICAgICAgICAgICAgICAgICAgY2xXaWR0aCA9IE1hdGgubWluKGNNYXhYIC0gY01pblgsIHRleHRXaWR0aCAtIChjTWluWCAtIHhEc3RTdXJmKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB4RHN0U3VyZiA9IGNNaW5YOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICh5RHN0U3VyZiA+PSBjTWluWSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2xIZWlnaHQgPSBNYXRoLm1pbih0ZXh0SGVpZ2h0LCBjTWF4WSAtIHlEc3RTdXJmKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHlTcmNTdXJmICs9IGNNaW5ZIC0geURzdFN1cmY7CisgICAgICAgICAgICAgICAgICAgICAgICBjbEhlaWdodCA9IE1hdGgubWluKGNNYXhZIC0gY01pblksIHRleHRIZWlnaHQgLSAoY01pblkgLSB5RHN0U3VyZikpOworICAgICAgICAgICAgICAgICAgICAgICAgeURzdFN1cmYgPSBjTWluWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyAgICAgRHJhd2luZyBvbiB0aGUgUmFzdGVyCisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGg9MDsgaDxjbEhlaWdodDsgaCsrKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHc9MDsgdyA8IGNsV2lkdGggOyB3KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlIGN1cnJCeXRlID0gZGF0YVsoeVNyY1N1cmYgKyBoKSpnbC5ibXBfcGl0Y2ggKyAoeFNyY1N1cmYrdykvOF07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbXB0eUJ5dGUgPSAoKGN1cnJCeXRlICYgKDEgPDwgKDcgLSAoKHhTcmNTdXJmK3cpICUgOCkpKSkgIT0gMCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtcHR5Qnl0ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXN0ZXIuc2V0RGF0YUVsZW1lbnRzKHhEc3RTdXJmK3csIHlEc3RTdXJmK2gsIGNvbG9yKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIHRvIGRvCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIERyYXdzIHN0cmluZyBvbiBzcGVjaWZpZWQgcmFzdGVyIGF0IGRlc2lyZWQgcG9zaXRpb24uCisgICAgICogIAorICAgICAqIEBwYXJhbSByYXN0ZXIgc3BlY2lmaWVkIFdyaXRhYmxlUmFzdGVyIHRvIGRyYXcgYXQKKyAgICAgKiBAcGFyYW0gY29sb3IgY29sb3Igb2YgdGhlIHRleHQKKyAgICAgKiBAcGFyYW0gc3RyIHRleHQgdG8gZHJhdworICAgICAqIEBwYXJhbSBmb250IGZvbnQgcGVlciB0byB1c2UgZm9yIGRyYXdpbmcgdGV4dAorICAgICAqIEBwYXJhbSB4IHN0YXJ0IFggcG9zaXRpb24gdG8gZHJhdworICAgICAqIEBwYXJhbSB5IHN0YXJ0IFkgcG9zaXRpb24gdG8gZHJhdworICAgICAqIEBwYXJhbSBjTWluWCBtaW5pbXVtIHggb2YgdGhlIHJhc3RlciBhcmVhIHRvIGRyYXcKKyAgICAgKiBAcGFyYW0gY01pblkgbWluaW11bSB5IG9mIHRoZSByYXN0ZXIgYXJlYSB0byBkcmF3CisgICAgICogQHBhcmFtIGNNYXhYIG1heGltdW0geCBvZiB0aGUgcmFzdGVyIGFyZWEgdG8gZHJhdworICAgICAqIEBwYXJhbSBjTWF4WSBtYXhpbXVtIHkgb2YgdGhlIHJhc3RlciBhcmVhIHRvIGRyYXcKKyAgICAgKi8gICAgCisgICAgcHVibGljIHZvaWQgZHJhd0NsaXBTdHJpbmcoV3JpdGFibGVSYXN0ZXIgcmFzdGVyLCBPYmplY3QgY29sb3IsIFN0cmluZyBzdHIsCisgICAgICAgICAgICBGb250UGVlckltcGwgZm9udCwgaW50IHgsIGludCB5LCBpbnQgY01pblgsIGludCBjTWluWSwgaW50IGNNYXhYLAorICAgICAgICAgICAgaW50IGNNYXhZKSB7CisgICAgICAgIC8vIFRPRE86IGltcGxlbWVudCBjb21wbGV4IGNsaXBwaW5nCisKKyAgICAgICAgaW50IHhTcmNTdXJmLCB5U3JjU3VyZjsgLy8gU3RhcnQgcG9pbnQgaW4gU3RyaW5nIHJlY3RhbmdsZQorICAgICAgICBpbnQgeERzdFN1cmYsIHlEc3RTdXJmOyAvLyBTdGFydCBwb2ludCBpbiBTdXJmYWNlIHJlY3RhbmdsZQorICAgICAgICBpbnQgY2xXaWR0aCwgY2xIZWlnaHQ7CisKKyAgICAgICAgY2hhcltdIGNoYXJzID0gc3RyLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgaW50IHhCYXNlTGluZSA9IHg7CisgICAgICAgIGludCB5QmFzZUxpbmUgPSB5OworCisgICAgICAgIGZvciAoY2hhciBlbGVtZW50IDogY2hhcnMpIHsKKyAgICAgICAgICAgIEdseXBoIGdsID0gZm9udC5nZXRHbHlwaChlbGVtZW50KTsKKyAgICAgICAgICAgIEdseXBoTWV0cmljcyBwb2ludE1ldHJpY3MgPSBnbC5nZXRHbHlwaFBvaW50TWV0cmljcygpOworICAgICAgICAgICAgaWYgKGdsLmdldFdpZHRoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHhCYXNlTGluZSArPSBwb2ludE1ldHJpY3MuZ2V0QWR2YW5jZVgoKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnl0ZVtdIGRhdGEgPSBnbC5nZXRCaXRtYXAoKTsKKyAgICAgICAgICAgIGlmIChkYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB4QmFzZUxpbmUgKz0gcG9pbnRNZXRyaWNzLmdldEFkdmFuY2VYKCk7CisgICAgICAgICAgICB9IGVsc2UgeworCisgICAgICAgICAgICAgICAgeFNyY1N1cmYgPSAwOworICAgICAgICAgICAgICAgIHlTcmNTdXJmID0gMDsKKworICAgICAgICAgICAgICAgIHhEc3RTdXJmID0gTWF0aC5yb3VuZCh4QmFzZUxpbmUgKyBnbC5nZXRHbHlwaFBvaW50TWV0cmljcygpLmdldExTQigpKTsKKyAgICAgICAgICAgICAgICB5RHN0U3VyZiA9IHlCYXNlTGluZSAtIGdsLmJtcF90b3A7CisKKyAgICAgICAgICAgICAgICBpbnQgdGV4dFdpZHRoID0gZ2wuYm1wX3dpZHRoOworICAgICAgICAgICAgICAgIGludCB0ZXh0SGVpZ2h0ID0gZ2wuZ2V0UG9pbnRIZWlnaHQoKTsKKworICAgICAgICAgICAgICAgIC8vIGlmIFJlZ2lvbnMgZG9uJ3QgaW50ZXJzZWN0CisgICAgICAgICAgICAgICAgaWYgKCh4RHN0U3VyZiA+IGNNYXhYKSB8fCAoeURzdFN1cmYgPiBjTWF4WSkgfHwgKHhEc3RTdXJmICsgdGV4dFdpZHRoIDwgY01pblgpCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAoeURzdFN1cmYgKyB0ZXh0SGVpZ2h0IDwgY01pblkpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgdG8gZG8KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAoeERzdFN1cmYgPj0gY01pblgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsV2lkdGggPSBNYXRoLm1pbih0ZXh0V2lkdGgsIGNNYXhYIC0geERzdFN1cmYpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgeFNyY1N1cmYgKz0gY01pblggLSB4RHN0U3VyZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsV2lkdGggPSBNYXRoLm1pbihjTWF4WCAtIGNNaW5YLCB0ZXh0V2lkdGggLSAoY01pblggLSB4RHN0U3VyZikpOworICAgICAgICAgICAgICAgICAgICAgICAgeERzdFN1cmYgPSBjTWluWDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoeURzdFN1cmYgPj0gY01pblkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsSGVpZ2h0ID0gTWF0aC5taW4odGV4dEhlaWdodCwgY01heFkgLSB5RHN0U3VyZik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB5U3JjU3VyZiArPSBjTWluWSAtIHlEc3RTdXJmOworICAgICAgICAgICAgICAgICAgICAgICAgY2xIZWlnaHQgPSBNYXRoLm1pbihjTWF4WSAtIGNNaW5ZLCB0ZXh0SGVpZ2h0IC0gKGNNaW5ZIC0geURzdFN1cmYpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHlEc3RTdXJmID0gY01pblk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBEcmF3aW5nIG9uIHRoZSBSYXN0ZXIKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaD0wOyBoPGNsSGVpZ2h0OyBoKyspeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgdz0wOyB3IDwgY2xXaWR0aCA7IHcrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGUgY3VyckJ5dGUgPSBkYXRhWyh5U3JjU3VyZiArIGgpKmdsLmJtcF9waXRjaCArICh4U3JjU3VyZit3KS84XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVtcHR5Qnl0ZSA9ICgoY3VyckJ5dGUgJiAoMSA8PCAoNyAtICgoeFNyY1N1cmYrdykgJSA4KSkpKSAhPSAwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1wdHlCeXRlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhc3Rlci5zZXREYXRhRWxlbWVudHMoeERzdFN1cmYrdywgeURzdFN1cmYraCwgY29sb3IpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgdG8gZG8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgeEJhc2VMaW5lICs9IHBvaW50TWV0cmljcy5nZXRBZHZhbmNlWCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL05hdGl2ZUltYWdlQmxpdHRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL05hdGl2ZUltYWdlQmxpdHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwZWJjOTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvTmF0aXZlSW1hZ2VCbGl0dGVyLmphdmEKQEAgLTAsMCArMSwyMTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgSWdvciBWLiBTdG9seWFyb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqIENyZWF0ZWQgb24gMjYuMTEuMjAwNQorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLnJlbmRlcjsKKworaW1wb3J0IGphdmEuYXd0LkFscGhhQ29tcG9zaXRlOworaW1wb3J0IGphdmEuYXd0LkNvbG9yOworaW1wb3J0IGphdmEuYXd0LkNvbXBvc2l0ZTsKK2ltcG9ydCBqYXZhLmF3dC5nZW9tLkFmZmluZVRyYW5zZm9ybTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5JbWFnZVN1cmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuU3VyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLlhPUkNvbXBvc2l0ZTsKKworLyoqCisgKiBUaGlzIGtpbmQgb2YgYmxpdHRlcnMgaXMgaW50ZW5kZWQgZm9yIGRyYXdpbmcgb25lIGltYWdlIG9uIHRoZSBidWZmZXJlZAorICogb3Igdm9sYXRpbGUgaW1hZ2UuIEZvciB0aGUgbW9tZW50IHdlIGNhbiBibGl0IG5hdGl2ZWx5IEJ1ZmZlcmVkIEltYWdlcyB3aGljaCAKKyAqIGhhdmUgc1JHQiwgTGluZWFyX1JHQiwgTGluZWFyX0dyYXkgQ29sb3IgU3BhY2UgYW5kIHR5cGUgZGlmZmVyZW50IAorICogZnJvbSBCdWZmZXJlZEltYWdlLlRZUEVfQ1VTVE9NLCBWb2xhdGlsZSBJbWFnZXMgYW5kIEltYWdlcyB3aGljaCByZWNlaXZlZCAKKyAqIHVzaW5nIFRvb2xraXQgYW5kIENvbXBvbmVudCBjbGFzc2VzLgorICovCitwdWJsaWMgY2xhc3MgTmF0aXZlSW1hZ2VCbGl0dGVyIGltcGxlbWVudHMgQmxpdHRlciB7CisKKworICAgIGZpbmFsIHN0YXRpYyBOYXRpdmVJbWFnZUJsaXR0ZXIgaW5zdCA9IG5ldyBOYXRpdmVJbWFnZUJsaXR0ZXIoKTsKKworICAgIHB1YmxpYyBzdGF0aWMgTmF0aXZlSW1hZ2VCbGl0dGVyIGdldEluc3RhbmNlKCl7CisgICAgICAgIHJldHVybiBpbnN0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGJsaXQoaW50IHNyY1gsIGludCBzcmNZLCBTdXJmYWNlIHNyY1N1cmYsIGludCBkc3RYLCBpbnQgZHN0WSwKKyAgICAgICAgICAgIFN1cmZhY2UgZHN0U3VyZiwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBBZmZpbmVUcmFuc2Zvcm0gc3lzeGZvcm0sCisgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0geGZvcm0sIENvbXBvc2l0ZSBjb21wLCBDb2xvciBiZ2NvbG9yLAorICAgICAgICAgICAgTXVsdGlSZWN0QXJlYSBjbGlwKSB7CisKKyAgICAgICAgaWYoIXNyY1N1cmYuaXNOYXRpdmVEcmF3YWJsZSgpKXsKKyAgICAgICAgICAgIEphdmFCbGl0dGVyLmluc3QuYmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCBkc3RYLCBkc3RZLCBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICBzeXN4Zm9ybSwgeGZvcm0sIGNvbXAsIGJnY29sb3IsIGNsaXApOworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGlmKHhmb3JtID09IG51bGwpeworICAgICAgICAgICAgICAgIGJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5c3hmb3JtLCBjb21wLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIGRvdWJsZSBzY2FsZVggPSB4Zm9ybS5nZXRTY2FsZVgoKTsKKyAgICAgICAgICAgICAgICBkb3VibGUgc2NhbGVZID0geGZvcm0uZ2V0U2NhbGVZKCk7CisgICAgICAgICAgICAgICAgZG91YmxlIHNjYWxlZFggPSBkc3RYIC8gc2NhbGVYOworICAgICAgICAgICAgICAgIGRvdWJsZSBzY2FsZWRZID0gZHN0WSAvIHNjYWxlWTsKKyAgICAgICAgICAgICAgICBBZmZpbmVUcmFuc2Zvcm0gYXQgPSBuZXcgQWZmaW5lVHJhbnNmb3JtKCk7CisgICAgICAgICAgICAgICAgYXQuc2V0VG9UcmFuc2xhdGlvbihzY2FsZWRYLCBzY2FsZWRZKTsKKyAgICAgICAgICAgICAgICB4Zm9ybS5jb25jYXRlbmF0ZShhdCk7CisgICAgICAgICAgICAgICAgc3lzeGZvcm0uY29uY2F0ZW5hdGUoeGZvcm0pOworICAgICAgICAgICAgICAgIGJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgMCwgMCwgZHN0U3VyZiwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5c3hmb3JtLCBjb21wLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGJsaXQoaW50IHNyY1gsIGludCBzcmNZLCBTdXJmYWNlIHNyY1N1cmYsIGludCBkc3RYLCBpbnQgZHN0WSwKKyAgICAgICAgICAgIFN1cmZhY2UgZHN0U3VyZiwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBBZmZpbmVUcmFuc2Zvcm0gc3lzeGZvcm0sCisgICAgICAgICAgICBDb21wb3NpdGUgY29tcCwgQ29sb3IgYmdjb2xvciwgTXVsdGlSZWN0QXJlYSBjbGlwKSB7CisKKyAgICAgICAgaWYoIXNyY1N1cmYuaXNOYXRpdmVEcmF3YWJsZSgpKXsKKyAgICAgICAgICAgIEphdmFCbGl0dGVyLmluc3QuYmxpdChzcmNYLCBzcmNZLCBzcmNTdXJmLCBkc3RYLCBkc3RZLCBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICBzeXN4Zm9ybSwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgIH1lbHNleworICAgICAgICAgICAgaW50IHR5cGUgPSBzeXN4Zm9ybS5nZXRUeXBlKCk7CisgICAgICAgICAgICBzd2l0Y2godHlwZSl7CisgICAgICAgICAgICAgICAgY2FzZSBBZmZpbmVUcmFuc2Zvcm0uVFlQRV9UUkFOU0xBVElPTjoKKyAgICAgICAgICAgICAgICAgICAgZHN0WCArPSBzeXN4Zm9ybS5nZXRUcmFuc2xhdGVYKCk7CisgICAgICAgICAgICAgICAgICAgIGRzdFkgKz0gc3lzeGZvcm0uZ2V0VHJhbnNsYXRlWSgpOworICAgICAgICAgICAgICAgIGNhc2UgQWZmaW5lVHJhbnNmb3JtLlRZUEVfSURFTlRJVFk6CisgICAgICAgICAgICAgICAgICAgIGJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgZHN0U3VyZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCBjb21wLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBOZWVkIHRvIHJlYWxpemUgQWZmaW5lIFRyYW5zZm9ybWF0aW9uCisgICAgICAgICAgICAgICAgICAgIGlmKHNyY1N1cmYgaW5zdGFuY2VvZiBJbWFnZVN1cmZhY2UpeworICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUJsaXR0ZXIuaW5zdC5ibGl0KHNyY1gsIHNyY1ksIHNyY1N1cmYsIGRzdFgsIGRzdFksIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN4Zm9ybSwgY29tcCwgYmdjb2xvciwgY2xpcCk7CisgICAgICAgICAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgICAgICAgICAgaW50IHcgPSBzcmNTdXJmLmdldFdpZHRoKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaCA9IHNyY1N1cmYuZ2V0SGVpZ2h0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBCdWZmZXJlZEltYWdlIHRtcCA9IG5ldyBCdWZmZXJlZEltYWdlKHcsIGgsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQik7CisgICAgICAgICAgICAgICAgICAgICAgICBTdXJmYWNlIHRtcFN1cmYgPSBTdXJmYWNlLmdldEltYWdlU3VyZmFjZSh0bXApOworICAgICAgICAgICAgICAgICAgICAgICAgYmxpdCgwLCAwLCBzcmNTdXJmLCAwLCAwLCB0bXBTdXJmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3LCBoLCBBbHBoYUNvbXBvc2l0ZS5TcmNPdmVyLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIEphdmFCbGl0dGVyLmluc3QuYmxpdChzcmNYLCBzcmNZLCB0bXBTdXJmLCBkc3RYLCBkc3RZLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0U3VyZiwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzeGZvcm0sIGNvbXAsIGJnY29sb3IsIGNsaXApOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQ29tcG9zaXRlIGNvbXAsCisgICAgICAgICAgICBDb2xvciBiZ2NvbG9yLCBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKworICAgICAgICBpZighc3JjU3VyZi5pc05hdGl2ZURyYXdhYmxlKCkpeworICAgICAgICAgICAgSmF2YUJsaXR0ZXIuaW5zdC5ibGl0KHNyY1gsIHNyY1ksIHNyY1N1cmYsIGRzdFgsIGRzdFksIGRzdFN1cmYsIHdpZHRoLCBoZWlnaHQsCisgICAgICAgICAgICAgICAgICAgIGNvbXAsIGJnY29sb3IsIGNsaXApOworICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgIGxvbmcgZHN0U3VyZlN0cnVjdCA9IGRzdFN1cmYuZ2V0U3VyZmFjZURhdGFQdHIoKTsKKyAgICAgICAgICAgIE9iamVjdCBkc3REYXRhID0gZHN0U3VyZi5nZXREYXRhKCk7CisgICAgICAgICAgICBpbnQgY2xpcFJlY3RzW107CisgICAgICAgICAgICBpZihjbGlwICE9IG51bGwpeworICAgICAgICAgICAgICAgIGNsaXBSZWN0cyA9IGNsaXAucmVjdDsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIGNsaXBSZWN0cyA9IG5ldyBpbnRbXXs1LCAwLCAwLCBkc3RTdXJmLmdldFdpZHRoKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkc3RTdXJmLmdldEhlaWdodCgpfTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYoIShzcmNTdXJmIGluc3RhbmNlb2YgSW1hZ2VTdXJmYWNlKSl7CisgICAgICAgICAgICAgICAgc3JjU3VyZiA9IHNyY1N1cmYuZ2V0SW1hZ2VTdXJmYWNlKCk7CisgICAgICAgICAgICAgICAgaWYoYmdjb2xvciAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICAgICAgYmdjb2xvciA9IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBsb25nIHNyY1N1cmZTdHJ1Y3QgPSBzcmNTdXJmLmdldFN1cmZhY2VEYXRhUHRyKCk7CisgICAgICAgICAgICBPYmplY3Qgc3JjRGF0YSA9IHNyY1N1cmYuZ2V0RGF0YSgpOworICAgICAgICAgICAgaWYoY29tcCBpbnN0YW5jZW9mIEFscGhhQ29tcG9zaXRlKXsKKyAgICAgICAgICAgICAgICBBbHBoYUNvbXBvc2l0ZSBhYyA9IChBbHBoYUNvbXBvc2l0ZSkgY29tcDsKKyAgICAgICAgICAgICAgICBpbnQgY29tcFR5cGUgPSBhYy5nZXRSdWxlKCk7CisgICAgICAgICAgICAgICAgZmxvYXQgYWxwaGEgPSBhYy5nZXRBbHBoYSgpOworICAgICAgICAgICAgICAgIGlmKGJnY29sb3IgIT0gbnVsbCl7CisgICAgICAgICAgICAgICAgICAgIGJsdEJHKHNyY1gsIHNyY1ksIHNyY1N1cmZTdHJ1Y3QsIHNyY0RhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0WCwgZHN0WSwgZHN0U3VyZlN0cnVjdCwgZHN0RGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCBiZ2NvbG9yLmdldFJHQigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBUeXBlLCBhbHBoYSwgY2xpcFJlY3RzLCBzcmNTdXJmLmludmFsaWRhdGVkKCkpOworICAgICAgICAgICAgICAgICAgICBkc3RTdXJmLmludmFsaWRhdGUoKTsKKyAgICAgICAgICAgICAgICAgICAgc3JjU3VyZi52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgICAgICBibHQoc3JjWCwgc3JjWSwgc3JjU3VyZlN0cnVjdCwgc3JjRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RYLCBkc3RZLCBkc3RTdXJmU3RydWN0LCBkc3REYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIGNvbXBUeXBlLCBhbHBoYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwUmVjdHMsIHNyY1N1cmYuaW52YWxpZGF0ZWQoKSk7CisgICAgICAgICAgICAgICAgICAgIGRzdFN1cmYuaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgICAgICBzcmNTdXJmLnZhbGlkYXRlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfWVsc2UgaWYoY29tcCBpbnN0YW5jZW9mIFhPUkNvbXBvc2l0ZSl7CisgICAgICAgICAgICAgICAgWE9SQ29tcG9zaXRlIHhjb21wID0gKFhPUkNvbXBvc2l0ZSkgY29tcDsKKyAgICAgICAgICAgICAgICB4b3Ioc3JjWCwgc3JjWSwgc3JjU3VyZlN0cnVjdCwgc3JjRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzdFgsIGRzdFksIGRzdFN1cmZTdHJ1Y3QsIGRzdERhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCB4Y29tcC5nZXRYT1JDb2xvcigpLmdldFJHQigpLAorICAgICAgICAgICAgICAgICAgICAgICAgY2xpcFJlY3RzLCBzcmNTdXJmLmludmFsaWRhdGVkKCkpOworICAgICAgICAgICAgICAgIGRzdFN1cmYuaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgIHNyY1N1cmYudmFsaWRhdGUoKTsKKyAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgIGlmKHNyY1N1cmYgaW5zdGFuY2VvZiBJbWFnZVN1cmZhY2UpeworICAgICAgICAgICAgICAgICAgICBKYXZhQmxpdHRlci5pbnN0LmJsaXQoc3JjWCwgc3JjWSwgc3JjU3VyZiwgZHN0WCwgZHN0WSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0U3VyZiwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wLCBiZ2NvbG9yLCBjbGlwKTsKKyAgICAgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICAgICAgaW50IHcgPSBzcmNTdXJmLmdldFdpZHRoKCk7CisgICAgICAgICAgICAgICAgICAgIGludCBoID0gc3JjU3VyZi5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgICAgICAgICAgQnVmZmVyZWRJbWFnZSB0bXAgPSBuZXcgQnVmZmVyZWRJbWFnZSh3LCBoLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQik7CisgICAgICAgICAgICAgICAgICAgIFN1cmZhY2UgdG1wU3VyZiA9IFN1cmZhY2UuZ2V0SW1hZ2VTdXJmYWNlKHRtcCk7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgdG1wU3VyZlN0cnVjdCA9IHRtcFN1cmYuZ2V0U3VyZmFjZURhdGFQdHIoKTsKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHRtcERhdGEgPSB0bXBTdXJmLmdldERhdGEoKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHRtcENsaXBbXSA9IG5ldyBpbnRbXXs1LCAwLCAwLCBzcmNTdXJmLmdldFdpZHRoKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjU3VyZi5nZXRIZWlnaHQoKX07CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBibHQoMCwgMCwgc3JjU3VyZlN0cnVjdCwgc3JjRGF0YSwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBTdXJmU3RydWN0LCB0bXBEYXRhLCB3LCBoLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbHBoYUNvbXBvc2l0ZS5TUkNfT1ZFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLjBmLCB0bXBDbGlwLCBzcmNTdXJmLmludmFsaWRhdGVkKCkpOworICAgICAgICAgICAgICAgICAgICBzcmNTdXJmLnZhbGlkYXRlKCk7CisgICAgICAgICAgICAgICAgICAgIEphdmFCbGl0dGVyLmluc3QuYmxpdChzcmNYLCBzcmNZLCB0bXBTdXJmLCBkc3RYLCBkc3RZLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RTdXJmLCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAsIGJnY29sb3IsIGNsaXApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBibHRCRyhpbnQgc3JjWCwgaW50IHNyY1ksIGxvbmcgc3JzU3VyZkRhdGFQdHIsCisgICAgICAgICAgICBPYmplY3Qgc3JjRGF0YSwgaW50IGRzdFgsIGludCBkc3RZLCBsb25nIGRzdFN1cmZEYXRhUHRyLAorICAgICAgICAgICAgT2JqZWN0IGRzdERhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJnY29sb3IsCisgICAgICAgICAgICBpbnQgY29tcFR5cGUsIGZsb2F0IGFscGhhLCBpbnQgY2xpcFtdLCBib29sZWFuIGludmFsaWRhdGVkKTsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgYmx0KGludCBzcmNYLCBpbnQgc3JjWSwgbG9uZyBzcnNTdXJmRGF0YVB0ciwKKyAgICAgICAgICAgIE9iamVjdCBzcmNEYXRhLCBpbnQgZHN0WCwgaW50IGRzdFksIGxvbmcgZHN0U3VyZkRhdGFQdHIsCisgICAgICAgICAgICBPYmplY3QgZHN0RGF0YSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgY29tcFR5cGUsCisgICAgICAgICAgICBmbG9hdCBhbHBoYSwgaW50IGNsaXBbXSwgYm9vbGVhbiBpbnZhbGlkYXRlZCk7CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHhvcihpbnQgc3JjWCwgaW50IHNyY1ksIGxvbmcgc3JzU3VyZkRhdGFQdHIsCisgICAgICAgICAgICBPYmplY3Qgc3JjRGF0YSwgaW50IGRzdFgsIGludCBkc3RZLCBsb25nIGRzdFN1cmZEYXRhUHRyLAorICAgICAgICAgICAgT2JqZWN0IGRzdERhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IHhvcmNvbG9yLAorICAgICAgICAgICAgaW50IGNsaXBbXSwgYm9vbGVhbiBpbnZhbGlkYXRlZCk7CisKKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL051bGxCbGl0dGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9nbC9yZW5kZXIvTnVsbEJsaXR0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDMyZTRlCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvZ2wvcmVuZGVyL051bGxCbGl0dGVyLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJZ29yIFYuIFN0b2x5YXJvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICogQ3JlYXRlZCBvbiAwNy4xMi4yMDA1CisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wucmVuZGVyOworCitpbXBvcnQgamF2YS5hd3QuQ29sb3I7CitpbXBvcnQgamF2YS5hd3QuQ29tcG9zaXRlOworaW1wb3J0IGphdmEuYXd0Lmdlb20uQWZmaW5lVHJhbnNmb3JtOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuU3VyZmFjZTsKKworCitwdWJsaWMgY2xhc3MgTnVsbEJsaXR0ZXIgaW1wbGVtZW50cyBCbGl0dGVyIHsKKworICAgIHN0YXRpYyBCbGl0dGVyIGluc3QgPSBuZXcgTnVsbEJsaXR0ZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIEJsaXR0ZXIgZ2V0SW5zdGFuY2UoKXsKKyAgICAgICAgcmV0dXJuIGluc3Q7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYmxpdChpbnQgc3JjWCwgaW50IHNyY1ksIFN1cmZhY2Ugc3JjU3VyZiwgaW50IGRzdFgsIGludCBkc3RZLAorICAgICAgICAgICAgU3VyZmFjZSBkc3RTdXJmLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEFmZmluZVRyYW5zZm9ybSBzeXN4Zm9ybSwKKyAgICAgICAgICAgIEFmZmluZVRyYW5zZm9ybSB4Zm9ybSwgQ29tcG9zaXRlIGNvbXAsIENvbG9yIGJnY29sb3IsCisgICAgICAgICAgICBNdWx0aVJlY3RBcmVhIGNsaXApIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBibGl0KGludCBzcmNYLCBpbnQgc3JjWSwgU3VyZmFjZSBzcmNTdXJmLCBpbnQgZHN0WCwgaW50IGRzdFksCisgICAgICAgICAgICBTdXJmYWNlIGRzdFN1cmYsIGludCB3aWR0aCwgaW50IGhlaWdodCwgQWZmaW5lVHJhbnNmb3JtIHN5c3hmb3JtLAorICAgICAgICAgICAgQ29tcG9zaXRlIGNvbXAsIENvbG9yIGJnY29sb3IsIE11bHRpUmVjdEFyZWEgY2xpcCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGJsaXQoaW50IHNyY1gsIGludCBzcmNZLCBTdXJmYWNlIHNyY1N1cmYsIGludCBkc3RYLCBpbnQgZHN0WSwKKyAgICAgICAgICAgIFN1cmZhY2UgZHN0U3VyZiwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBDb21wb3NpdGUgY29tcCwKKyAgICAgICAgICAgIENvbG9yIGJnY29sb3IsIE11bHRpUmVjdEFyZWEgY2xpcCkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW0vSW5wdXRNZXRob2RDb250ZXh0LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9pbS9JbnB1dE1ldGhvZENvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWVkMTFmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW0vSW5wdXRNZXRob2RDb250ZXh0LmphdmEKQEAgLTAsMCArMSw1NjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKiogCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmltOworCisvLz8/P0FXVAoraW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsKKy8vaW1wb3J0IGphdmEuYXd0LktleWJvYXJkRm9jdXNNYW5hZ2VyOworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKKy8vaW1wb3J0IGphdmEuYXd0LldpbmRvdzsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC5Gb2N1c0V2ZW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LklucHV0TWV0aG9kRXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuS2V5RXZlbnQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0SGl0SW5mbzsKK2ltcG9ydCBqYXZhLmF3dC5pbS5JbnB1dENvbnRleHQ7CitpbXBvcnQgamF2YS5hd3QuaW0uSW5wdXRNZXRob2RSZXF1ZXN0czsKK2ltcG9ydCBqYXZhLmF3dC5pbS5zcGkuSW5wdXRNZXRob2Q7CitpbXBvcnQgamF2YS5hd3QuaW0uc3BpLklucHV0TWV0aG9kRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmxhbmcuQ2hhcmFjdGVyLlN1YnNldDsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLy8/Pz9BV1QKKy8vaW1wb3J0IGphdmF4LnN3aW5nLkpGcmFtZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUlNOworCisvKioKKyAqIEltcGxlbWVudGF0aW9uIG9mIElucHV0TWV0aG9kQ29udGV4dAorICogaW50ZXJmYWNlLCBhbHNvIHByb3ZpZGVzIGFsbCB1c2VmdWwKKyAqIGZ1bmN0aW9uYWxpdHkgb2YgSW5wdXRDb250ZXh0CisgKiAKKyAqLworcHVibGljIGNsYXNzIElucHV0TWV0aG9kQ29udGV4dCBleHRlbmRzIElucHV0Q29udGV4dCBpbXBsZW1lbnRzCisgICAgICAgIGphdmEuYXd0LmltLnNwaS5JbnB1dE1ldGhvZENvbnRleHQgeyAgICAKKworICAgIC8vPz8/QVdUCisgICAgcHJpdmF0ZSBJbnB1dE1ldGhvZCBpbnB1dE1ldGhvZDsgLy8gY3VycmVudCBJTQorICAgIHByaXZhdGUgQ29tcG9uZW50IGNsaWVudDsgLy8gY3VycmVudCAiYWN0aXZlIiBjbGllbnQgY29tcG9uZW50CisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgQ29tcG9zaXRpb25XaW5kb3cgY29tcG9zZVdpbmRvdzsgLy8gY29tcG9zaXRpb24gV2luZG93ICAgIAorICAgIHByaXZhdGUgZmluYWwgTWFwPElucHV0TWV0aG9kRGVzY3JpcHRvciwgSW5wdXRNZXRob2Q+IGltSW5zdGFuY2VzOyAvLyBNYXA8SW5wdXRNZXRob2REZXNjcmlwdG9yLCBJbnB1dE1ldGhvZD4KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxMb2NhbGUsIElucHV0TWV0aG9kPiBsb2NhbGVJTTsgLy8gTWFwPExvY2FsZSwgSW5wdXRNZXRob2Q+IGxhc3QgdXNlci1zZWxlY3RlZCBJTSBmb3IgbG9jYWxlCisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8SW5wdXRNZXRob2Q+IG5vdGlmeUlNOyAvLyBzZXQgb2YgSU1zIHRvIG5vdGlmeSBvZiBjbGllbnQgd2luZG93IGJvdW5kcyBjaGFuZ2VzCisgICAgCisgICAgLyoqCisgICAgICogYSBmbGFnIGluZGljYXRpbmcgdGhhdCBJTSBzaG91bGQgYmUgbm90aWZpZWQgb2YgY2xpZW50IHdpbmRvdworICAgICAqIHBvc2l0aW9uL3Zpc2liaWxpdHkgY2hhbmdlcyBhcyBzb29uIGFzIGl0IGlzIGFjdGl2YXRlZChuZXcgY2xpZW50CisgICAgICogYXBwZWFycykKKyAgICAgKi8gICAgCisgICAgcHJpdmF0ZSBib29sZWFuIHBlbmRpbmdDbGllbnROb3RpZnk7CisgICAgcHJpdmF0ZSBDb21wb25lbnQgbmV4dENvbXA7IC8vIGNvbXBvbmVudCB0byBnYWluIGZvY3VzIGFmdGVyIGVuZENvbXBvc2l0aW9uKCkKKyAgICAvLz8/P0FXVDogcHJpdmF0ZSBmaW5hbCBTZXQ8V2luZG93PiBpbVdpbmRvd3M7IC8vIHNldCBvZiBhbGwgSU0gd2luZG93cyBjcmVhdGVkIGJ5IHRoaXMgaW5zdGFuY2UKKyAgICBwcml2YXRlIGZpbmFsIE5hdGl2ZUlNIG5hdGl2ZUlNOworICAgIAorCisgCisgICAgcHVibGljIElucHV0TWV0aG9kQ29udGV4dCgpIHsKKyAgICAgICAgbm90aWZ5SU0gPSBuZXcgSGFzaFNldDxJbnB1dE1ldGhvZD4oKTsKKy8vPz8/QVdUOiAgICAgICAgaW1XaW5kb3dzID0gbmV3IEhhc2hTZXQ8V2luZG93PigpOworICAgICAgICBpbUluc3RhbmNlcyA9IG5ldyBIYXNoTWFwPElucHV0TWV0aG9kRGVzY3JpcHRvciwgSW5wdXRNZXRob2Q+KCk7CisgICAgICAgIGxvY2FsZUlNID0gbmV3IEhhc2hNYXA8TG9jYWxlLCBJbnB1dE1ldGhvZD4oKTsKKyAgICAgICAgc2VsZWN0SW5wdXRNZXRob2QoTG9jYWxlLlVTKTsgLy8gbm90IGRlZmF1bHQ/CisgICAgICAgIG5hdGl2ZUlNID0gKE5hdGl2ZUlNKSBpbnB1dE1ldGhvZDsKKyAgICB9CisKKyAgICAvLz8/P0FXVAorICAgIC8qCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZGlzcGF0Y2hFdmVudChBV1RFdmVudCBldmVudCkgeworICAgICAgICBpbnQgaWQgPSBldmVudC5nZXRJRCgpOyAKKyAgICAgICAgaWYgKChpZCA+PSBGb2N1c0V2ZW50LkZPQ1VTX0ZJUlNUKSAmJiAoaWQgPD1Gb2N1c0V2ZW50LkZPQ1VTX0xBU1QpKSB7CisgICAgICAgICAgICBkaXNwYXRjaEZvY3VzRXZlbnQoKEZvY3VzRXZlbnQpIGV2ZW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGhhbmRsZSBzcGVjaWFsIEtFWV9QUkVTU0VECisgICAgICAgICAgICAvLyBldmVudCB0byBzaG93IElNIHNlbGVjdGlvbiBtZW51CisgICAgICAgICAgICBpZiAoaWQgPT0gS2V5RXZlbnQuS0VZX1BSRVNTRUQpIHsKKyAgICAgICAgICAgICAgICBLZXlFdmVudCBrZSA9IChLZXlFdmVudCkgZXZlbnQ7CisgICAgICAgICAgICAgICAgSU1NYW5hZ2VyLnNlbGVjdElNKGtlLCB0aGlzLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1NYW5hZ2VyLmdldFdpbmRvdyhrZS5nZXRDb21wb25lbnQoKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gZGlzcGF0Y2ggYWxsIGlucHV0IGV2ZW50cyB0byB0aGUgY3VycmVudCBJTToKKyAgICAgICAgICAgIGlmIChpbnB1dE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5wdXRNZXRob2QuZGlzcGF0Y2hFdmVudChldmVudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSB2b2lkIGRpc3BhdGNoRm9jdXNFdmVudChGb2N1c0V2ZW50IGZlKSB7CisgICAgICAgIHN3aXRjaCAoZmUuZ2V0SUQoKSkgeworICAgICAgICBjYXNlIEZvY3VzRXZlbnQuRk9DVVNfTE9TVDogICAgICAgICAgICAKKyAgICAgICAgICAgIGlmIChpbnB1dE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5wdXRNZXRob2QuZGVhY3RpdmF0ZShmZS5pc1RlbXBvcmFyeSgpKTsgICAgICAgICAgICAgICAgCisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGb2N1c0V2ZW50LkZPQ1VTX0dBSU5FRDoKKyAgICAgICAgICAgIAorICAgICAgICAgICAgQ29tcG9uZW50IGNvbXAgPSBmZS5nZXRDb21wb25lbnQoKTsKKyAgICAgICAgICAgIGlmIChpbVdpbmRvd3MuY29udGFpbnMoY29tcCkpIHsKKyAgICAgICAgICAgICAgICAvLyBwcmV2ZW50IGFjdGl2YXRpbmcgd2hlbiBJTSB3aW5kb3dzCisgICAgICAgICAgICAgICAgLy8gYXR0YWNoZWQgdG8gdGhpcyBjb250ZXh0IGdhaW4gZm9jdXMgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgSW5wdXRNZXRob2RDb250ZXh0IGxhc3RBY3RpdmUgPSBJTU1hbmFnZXIuZ2V0TGFzdEFjdGl2ZUlNQygpOworICAgICAgICAgICAgaWYgKChsYXN0QWN0aXZlICE9IHRoaXMpICYmIChsYXN0QWN0aXZlICE9IG51bGwpKSB7CisgICAgICAgICAgICAgICAgbGFzdEFjdGl2ZS5oaWRlV2luZG93cygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlucHV0TWV0aG9kICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhY3RpdmF0ZUlNKGlucHV0TWV0aG9kKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldENvbXBvc2l0aW9uV2luZG93KCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIElNTWFuYWdlci5zaG93Q29tcG9zaXRpb25XaW5kb3coY29tcG9zZVdpbmRvdyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjbGllbnQgPT0gY29tcCkgeworICAgICAgICAgICAgICAgICAgICBpZiAobmV4dENvbXAgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGVtcG9yYXJpbHkgZ290IGZvY3VzIHRvCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbmQgY29tcG9zaXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgIGVuZENvbXBvc2l0aW9uKCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIGZvY3VzIHRvIG5ldyBjbGllbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudCA9IG5leHRDb21wOworICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENvbXAgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50LnJlcXVlc3RGb2N1c0luV2luZG93KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChjbGllbnQgIT0gbnVsbCkgJiYgZ2V0Q29tcG9zaXRpb25XaW5kb3coKS5pc1Zpc2libGUoKSkgeworICAgICAgICAgICAgICAgICAgICAvLyB0ZW1wb3JhcmlseSByZXR1cm4gZm9jdXMgYmFjaworICAgICAgICAgICAgICAgICAgICAvLyB0byBwcmV2aW91cyBjbGllbnQgdG8gYmUgYWJsZQorICAgICAgICAgICAgICAgICAgICAvLyB0byBlbmQgY29tcG9zaXRpb24KKyAgICAgICAgICAgICAgICAgICAgbmV4dENvbXAgPSBjb21wOworICAgICAgICAgICAgICAgICAgICBjbGllbnQucmVxdWVzdEZvY3VzSW5XaW5kb3coKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBjbGllbnQgPSBjb21wOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwZW5kaW5nQ2xpZW50Tm90aWZ5KSB7CisgICAgICAgICAgICAgICAgbm90aWZ5Q2xpZW50V2luZG93Q2hhbmdlKElNTWFuYWdlci5nZXRXaW5kb3coY29tcCkuZ2V0Qm91bmRzKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhY3RpdmF0ZUlNKElucHV0TWV0aG9kIGltKSB7CisgICAgICAgIGltLmFjdGl2YXRlKCk7CisgICAgICAgIGlmICgobmF0aXZlSU0gIT0gbnVsbCkgJiYgKGltICE9IG5hdGl2ZUlNKSkgeworICAgICAgICAgICAgLy8gd2hlbiBKYXZhIElNIGlzIGFjdGl2ZQorICAgICAgICAgICAgLy8gbmF0aXZlIGlucHV0IG1ldGhvZCBlZGl0b3IgbXVzdCBiZQorICAgICAgICAgICAgLy8gZXhwbGljaXRseSBkaXNhYmxlZAorICAgICAgICAgICAgbmF0aXZlSU0uZGlzYWJsZUlNRSgpOworICAgICAgICB9CisgICAgICAgIElNTWFuYWdlci5zZXRMYXN0QWN0aXZlSU1DKHRoaXMpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHJpdmF0ZSB2b2lkIGhpZGVXaW5kb3dzKCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5wdXRNZXRob2QuaGlkZVdpbmRvd3MoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29tcG9zZVdpbmRvdyAhPSBudWxsKSB7CisgICAgICAgICAgICBjb21wb3NlV2luZG93LmhpZGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVDb21wb3NpdGlvbldpbmRvdygpIHsKKyAgICAgICAgY29tcG9zZVdpbmRvdyA9IG5ldyBDb21wb3NpdGlvbldpbmRvdyhjbGllbnQpOyAgICAgICAgCisgICAgfQorICAgIAorICAgIHByaXZhdGUgQ29tcG9zaXRpb25XaW5kb3cgZ2V0Q29tcG9zaXRpb25XaW5kb3coKSB7CisgICAgICAgIGlmIChjb21wb3NlV2luZG93ID09IG51bGwpIHsKKyAgICAgICAgICAgIGNyZWF0ZUNvbXBvc2l0aW9uV2luZG93KCk7CisgICAgICAgIH0KKyAgICAgICAgY29tcG9zZVdpbmRvdy5zZXRDbGllbnQoY2xpZW50KTsKKyAgICAgICAgcmV0dXJuIGNvbXBvc2VXaW5kb3c7ICAgICAgICAKKyAgICB9CisgICAgKi8KKyAgICAKKyAgICAvKioKKyAgICAgKiBHZXRzIGlucHV0IG1ldGhvZCByZXF1ZXN0cyBmb3IgdGhlIGN1cnJlbnQgY2xpZW50CisgICAgICogaXJyZXNwZWN0aXZlIG9mIGlucHV0IHN0eWxlLgorICAgICAqIEByZXR1cm4gaW5wdXQgbWV0aG9kIHJlcXVlc3RzIG9mIGNvbXBvc2l0aW9uIHdpbmRvdyBpZgorICAgICAqIGNsaWVudCBpcyBwYXNzaXZlLAorICAgICAqIG90aGVyd2lzZSBpbnB1dCBtZXRob2QgcmVxdWVzdHMgb2YgY2xpZW50CisgICAgICovCisgICAgcHJpdmF0ZSBJbnB1dE1ldGhvZFJlcXVlc3RzIGdldElNUmVxdWVzdHMoKSB7CisgICAgICAgIElucHV0TWV0aG9kUmVxdWVzdHMgaW1SZXF1ZXN0cyA9IG51bGw7CisgICAgCisgICAgICAgIGlmIChjbGllbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgaW1SZXF1ZXN0cyA9IGNsaWVudC5nZXRJbnB1dE1ldGhvZFJlcXVlc3RzKCk7CisgICAgICAgICAgICAvLz8/P0FXVAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgIGlmIChpbVJlcXVlc3RzID09IG51bGwpIHsgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaW1SZXF1ZXN0cyA9IGdldENvbXBvc2l0aW9uV2luZG93KCkuZ2V0SW5wdXRNZXRob2RSZXF1ZXN0cygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKi8KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcmV0dXJuIGltUmVxdWVzdHM7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEdldHMgaW5wdXQgbWV0aG9kIHJlcXVlc3RzIGZvciB0aGUgY3VycmVudCBjbGllbnQgJiBpbnB1dCBzdHlsZS4KKyAgICAgKiBAcmV0dXJuIGlucHV0IG1ldGhvZCByZXF1ZXN0cyBvZiBjb21wb3NpdGlvbiB3aW5kb3cgaWYKKyAgICAgKiBpbnB1dCBzdHlsZSBpcyAiYmVsb3ctdGhlLXNwb3QiKG9yIGNsaWVudCBpcyBwYXNzaXZlKSwKKyAgICAgKiBvdGhlcndpc2UgY2xpZW50IGlucHV0IG1ldGhvZCByZXF1ZXN0cworICAgICAqLworICAgIHByaXZhdGUgSW5wdXRNZXRob2RSZXF1ZXN0cyBnZXRTdHlsZUlNUmVxdWVzdHMoKSB7CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIGlmIChJTU1hbmFnZXIuYmVsb3dUaGVTcG90KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDb21wb3NpdGlvbldpbmRvdygpLmdldElucHV0TWV0aG9kUmVxdWVzdHMoKTsKKyAgICAgICAgfQorICAgICAgICAqLworICAgICAgICByZXR1cm4gZ2V0SU1SZXF1ZXN0cygpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgY2xvc2VJTShpbnB1dE1ldGhvZCk7CisgICAgICAgICAgICBpbnB1dE1ldGhvZC5kaXNwb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgbm90aWZ5SU0uY2xlYXIoKTsKKyAgICAgICAgc3VwZXIuZGlzcG9zZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGVuZENvbXBvc2l0aW9uKCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5wdXRNZXRob2QuZW5kQ29tcG9zaXRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci5lbmRDb21wb3NpdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0SW5wdXRNZXRob2RDb250cm9sT2JqZWN0KCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGlucHV0TWV0aG9kLmdldENvbnRyb2xPYmplY3QoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SW5wdXRNZXRob2RDb250cm9sT2JqZWN0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7CisgICAgICAgIGlmIChpbnB1dE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXRNZXRob2QuZ2V0TG9jYWxlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2FsZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcG9zaXRpb25FbmFibGVkKCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGlucHV0TWV0aG9kLmlzQ29tcG9zaXRpb25FbmFibGVkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLmlzQ29tcG9zaXRpb25FbmFibGVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVjb252ZXJ0KCkgeworICAgICAgICBpZiAoaW5wdXRNZXRob2QgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5wdXRNZXRob2QucmVjb252ZXJ0KCk7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIucmVjb252ZXJ0KCk7CisgICAgfQorCisgICAgLy8/Pz9BV1QKKyAgICAvKgorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZU5vdGlmeShDb21wb25lbnQgY2xpZW50KSB7CisgICAgICAgIGlmICgoaW5wdXRNZXRob2QgIT0gbnVsbCkgJiYgKGNsaWVudCA9PSB0aGlzLmNsaWVudCkpIHsKKyAgICAgICAgICAgIGlucHV0TWV0aG9kLnJlbW92ZU5vdGlmeSgpOworICAgICAgICAgICAgY2xpZW50ID0gbnVsbDsKKyAgICAgICAgICAgIC8vIHNldCBmbGFnIGluZGljYXRpbmcgdGhhdCBJTSBzaG91bGQgYmUgbm90aWZpZWQKKyAgICAgICAgICAgIC8vIGFzIHNvb24gYXMgaXQgaXMgYWN0aXZhdGVkKG5ldyBjbGllbnQgYXBwZWFycykKKyAgICAgICAgICAgIHBlbmRpbmdDbGllbnROb3RpZnkgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBzdXBlci5yZW1vdmVOb3RpZnkoY2xpZW50KTsKKyAgICB9CisgICAgKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHNlbGVjdElucHV0TWV0aG9kKExvY2FsZSBsb2NhbGUpIHsgICAgICAgIAorICAgICAgICAKKyAgICAgICAgaWYgKChpbnB1dE1ldGhvZCAhPSBudWxsKSAmJiBpbnB1dE1ldGhvZC5zZXRMb2NhbGUobG9jYWxlKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gZmlyc3QKKyAgICAgICAgLy8gdGFrZSBsYXN0IHVzZXItc2VsZWN0ZWQgSU0gZm9yIGxvY2FsZSAgICAgICAgICAgIAorICAgICAgICBJbnB1dE1ldGhvZCBuZXdJTSA9IGxvY2FsZUlNLmdldChsb2NhbGUpOworICAgICAgICAKKyAgICAgICAgLy8gaWYgbm90IGZvdW5kIHNlYXJjaCB0aHJvdWdoIElNIGRlc2NyaXB0b3JzCisgICAgICAgIC8vIGFuZCB0YWtlIGFscmVhZHkgY3JlYXRlZCBpbnN0YW5jZSBpZiBleGlzdHMKKyAgICAgICAgLy8gb3IgY3JlYXRlLCBzdG9yZSBuZXcgSU0gaW5zdGFuY2UgaW4gZGVzY3JpcHRvci0+aW5zdGFuY2UgbWFwCisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIGlmIChuZXdJTSA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ld0lNID0gZ2V0SU1JbnN0YW5jZShJTU1hbmFnZXIuZ2V0SU1EZXNjcmlwdG9ycygpLml0ZXJhdG9yKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBleGNlcHRpb25zIC0ganVzdCByZXR1cm4gZmFsc2UKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAqLworICAgICAgICAKKyAgICAgICAgcmV0dXJuIHN3aXRjaFRvSU0obG9jYWxlLCBuZXdJTSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIHN3aXRjaFRvSU0oTG9jYWxlIGxvY2FsZSwgSW5wdXRNZXRob2QgbmV3SU0pIHsKKyAgICAgICAgLy8/Pz9BV1QKKyAgICAgICAgLyoKKyAgICAgICAgaWYgKG5ld0lNICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNsb3NlSU0oaW5wdXRNZXRob2QpOworICAgICAgICAgICAgY2xpZW50ID0gS2V5Ym9hcmRGb2N1c01hbmFnZXIuCisgICAgICAgICAgICBnZXRDdXJyZW50S2V5Ym9hcmRGb2N1c01hbmFnZXIoKS5nZXRGb2N1c093bmVyKCk7CisgICAgICAgICAgICBpbml0SU0obmV3SU0sIGxvY2FsZSk7CisgICAgICAgICAgICBpbnB1dE1ldGhvZCA9IG5ld0lNOworICAgICAgICAgICAgCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAqLworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIElzIGNhbGxlZCB3aGVuIElNIGlzIHNlbGVjdGVkIGZyb20gVUkKKyAgICAgKi8KKyAgICB2b2lkIHNlbGVjdElNKElucHV0TWV0aG9kRGVzY3JpcHRvciBpbWQsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN3aXRjaFRvSU0obG9jYWxlLCBnZXRJTUluc3RhbmNlKGltZCkpOyAgICAgICAgICAgIAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgaW5wdXQgbWV0aG9kIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4KKyAgICAgKiBsb2NhbGUgZnJvbSB0aGUgZ2l2ZW4gbGlzdCBvZiBkZXNjcmlwdG9ycworICAgICAqIEBwYXJhbSBkZXNjcmlwdG9ycyBpdGVyYXRvciBvZiB0aGUgbGlzdCBvZiBJTSBkZXNjcmlwdG9ycworICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhlIElNCisgICAgICogQHJldHVybiBpbnB1dCBtZXRob2QgaW5zdGFuY2UKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRNZXRob2QgZ2V0SU1JbnN0YW5jZShJdGVyYXRvcjxJbnB1dE1ldGhvZERlc2NyaXB0b3I+IGRlc2NyaXB0b3JzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUgbG9jYWxlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKGRlc2NyaXB0b3JzLmhhc05leHQoKSkgeworICAgICAgICAgICAgSW5wdXRNZXRob2REZXNjcmlwdG9yIGRlc2MgPSBkZXNjcmlwdG9ycy5uZXh0KCk7CisgICAgICAgICAgICBMb2NhbGVbXSBsb2NzID0gZGVzYy5nZXRBdmFpbGFibGVMb2NhbGVzKCk7CisgICAgICAgICAgICBmb3IgKExvY2FsZSBlbGVtZW50IDogbG9jcykgeworICAgICAgICAgICAgICAgIGlmIChsb2NhbGUuZXF1YWxzKGVsZW1lbnQpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRJTUluc3RhbmNlKGRlc2MpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIElucHV0TWV0aG9kIGdldElNSW5zdGFuY2UoSW5wdXRNZXRob2REZXNjcmlwdG9yIGltZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElucHV0TWV0aG9kIGltID0gaW1JbnN0YW5jZXMuZ2V0KGltZCk7CisgICAgICAgIGlmIChpbSA9PSBudWxsKSB7CisgICAgICAgICAgICBpbSA9IGltZC5jcmVhdGVJbnB1dE1ldGhvZCgpOworICAgICAgICAgICAgaW0uc2V0SW5wdXRNZXRob2RDb250ZXh0KHRoaXMpOworICAgICAgICAgICAgaW1JbnN0YW5jZXMucHV0KGltZCwgaW0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSB2b2lkIGluaXRJTShJbnB1dE1ldGhvZCBpbSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAoaW0gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGltLnNldExvY2FsZShsb2NhbGUpOworICAgICAgICBpbS5zZXRDaGFyYWN0ZXJTdWJzZXRzKG51bGwpOworICAgICAgICAvLz8/P0FXVDogYWN0aXZhdGVJTShpbSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbS5zZXRDb21wb3NpdGlvbkVuYWJsZWQoaW5wdXRNZXRob2QgIT0gbnVsbCA/IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0TWV0aG9kLmlzQ29tcG9zaXRpb25FbmFibGVkKCkgOiB0cnVlKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gdW9lKSB7CisKKyAgICAgICAgfQorICAgICAgICAKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xvc2VJTShJbnB1dE1ldGhvZCBpbSkgeworICAgICAgICBpZiAoaW0gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpbS5pc0NvbXBvc2l0aW9uRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBpbS5lbmRDb21wb3NpdGlvbigpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpbS5kZWFjdGl2YXRlKHRydWUpOworICAgICAgICBpbS5oaWRlV2luZG93cygpOworICAgICAgICAKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3Vic2V0cyhTdWJzZXRbXSBzdWJzZXRzKSB7CisgICAgICAgIGlmIChpbnB1dE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnB1dE1ldGhvZC5zZXRDaGFyYWN0ZXJTdWJzZXRzKHN1YnNldHMpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLnNldENoYXJhY3RlclN1YnNldHMoc3Vic2V0cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q29tcG9zaXRpb25FbmFibGVkKGJvb2xlYW4gZW5hYmxlKSB7CisgICAgICAgIGlmIChpbnB1dE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnB1dE1ldGhvZC5zZXRDb21wb3NpdGlvbkVuYWJsZWQoZW5hYmxlKTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci5zZXRDb21wb3NpdGlvbkVuYWJsZWQoZW5hYmxlKTsKKyAgICB9CisKKyAgICAvLz8/P0FXVAorICAgIC8qCisgICAgcHVibGljIEpGcmFtZSBjcmVhdGVJbnB1dE1ldGhvZEpGcmFtZShTdHJpbmcgdGl0bGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGF0dGFjaFRvSW5wdXRDb250ZXh0KSB7CisgICAgICAgIEpGcmFtZSBqZiA9IG5ldyBJTUpGcmFtZSh0aXRsZSwgYXR0YWNoVG9JbnB1dENvbnRleHQgPyB0aGlzIDogbnVsbCk7CisgICAgICAgIGltV2luZG93cy5hZGQoamYpOworICAgICAgICByZXR1cm4gamY7CisgICAgfQorCisgICAgcHVibGljIFdpbmRvdyBjcmVhdGVJbnB1dE1ldGhvZFdpbmRvdyhTdHJpbmcgdGl0bGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGF0dGFjaFRvSW5wdXRDb250ZXh0KSB7CisgICAgICAgIFdpbmRvdyB3ID0gbmV3IElNV2luZG93KHRpdGxlLCBhdHRhY2hUb0lucHV0Q29udGV4dCA/IHRoaXMgOiBudWxsKTsKKyAgICAgICAgaW1XaW5kb3dzLmFkZCh3KTsKKyAgICAgICAgcmV0dXJuIHc7CisgICAgfQorICAgICovCisgICAgCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaElucHV0TWV0aG9kRXZlbnQoaW50IGlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvbW1pdHRlZENoYXJhY3RlckNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0SGl0SW5mbyBjYXJldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEhpdEluZm8gdmlzaWJsZVBvc2l0aW9uKSB7CisgICAgICAgIGlmIChjbGllbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIElucHV0TWV0aG9kRXZlbnQgaW1lID0gbmV3IElucHV0TWV0aG9kRXZlbnQoY2xpZW50LCBpZCwgdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21taXR0ZWRDaGFyYWN0ZXJDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJldCwgdmlzaWJsZVBvc2l0aW9uKTsKKyAgICAgICAgCisKKyAgICAgICAgaWYgKChjbGllbnQuZ2V0SW5wdXRNZXRob2RSZXF1ZXN0cygpICE9IG51bGwpICYmCisgICAgICAgICAgICAhSU1NYW5hZ2VyLmJlbG93VGhlU3BvdCgpKSB7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGNsaWVudC5kaXNwYXRjaEV2ZW50KGltZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIHNob3cvaGlkZSBjb21wb3NpdGlvbiB3aW5kb3cgaWYgbmVjZXNzYXJ5CisgICAgICAgICAgICBpZiAoY29tbWl0dGVkQ2hhcmFjdGVyQ291bnQgPCB0ZXh0LmdldEVuZEluZGV4KCkpIHsKKyAgICAgICAgICAgICAgICBJTU1hbmFnZXIuc2hvd0NvbXBvc2l0aW9uV2luZG93KGdldENvbXBvc2l0aW9uV2luZG93KCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBnZXRDb21wb3NpdGlvbldpbmRvdygpLmhpZGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbXBvc2VXaW5kb3cuZ2V0QWN0aXZlQ2xpZW50KCkuZGlzcGF0Y2hFdmVudChpbWUpOworICAgICAgICB9CisgICAgICAgICovCisgICAgICAgIAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuYWJsZUNsaWVudFdpbmRvd05vdGlmaWNhdGlvbihJbnB1dE1ldGhvZCBpbnB1dE1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbmFibGUpIHsKKyAgICAgICAgaWYgKGVuYWJsZSkgeworICAgICAgICAgICAgbm90aWZ5SU0uYWRkKGlucHV0TWV0aG9kKTsKKyAgICAgICAgICAgIC8vPz8/QVdUCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgaWYgKGNsaWVudCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbm90aWZ5Q2xpZW50V2luZG93Q2hhbmdlKElNTWFuYWdlci5nZXRXaW5kb3coY2xpZW50KS5nZXRCb3VuZHMoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHBlbmRpbmdDbGllbnROb3RpZnkgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKi8KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5vdGlmeUlNLnJlbW92ZShpbnB1dE1ldGhvZCk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBjYW5jZWxMYXRlc3RDb21taXR0ZWRUZXh0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzKSB7CisgICAgICAgIHJldHVybiBnZXRJTVJlcXVlc3RzKCkuY2FuY2VsTGF0ZXN0Q29tbWl0dGVkVGV4dChhdHRyaWJ1dGVzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGdldENvbW1pdHRlZFRleHQoaW50IGJlZ2luSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbmRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlW10gYXR0cmlidXRlcykgeworICAgICAgICByZXR1cm4gZ2V0SU1SZXF1ZXN0cygpLmdldENvbW1pdHRlZFRleHQoYmVnaW5JbmRleCwgZW5kSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbW1pdHRlZFRleHRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBnZXRJTVJlcXVlc3RzKCkuZ2V0Q29tbWl0dGVkVGV4dExlbmd0aCgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SW5zZXJ0UG9zaXRpb25PZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBnZXRJTVJlcXVlc3RzKCkuZ2V0SW5zZXJ0UG9zaXRpb25PZmZzZXQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgVGV4dEhpdEluZm8gZ2V0TG9jYXRpb25PZmZzZXQoaW50IHgsIGludCB5KSB7CisgICAgICAgIElucHV0TWV0aG9kUmVxdWVzdHMgaW1yID0gZ2V0U3R5bGVJTVJlcXVlc3RzKCk7CisgICAgICAgIGlmIChpbXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGltci5nZXRMb2NhdGlvbk9mZnNldCh4LCB5KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGdldFNlbGVjdGVkVGV4dChBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzKSB7CisgICAgICAgIHJldHVybiBnZXRJTVJlcXVlc3RzKCkuZ2V0U2VsZWN0ZWRUZXh0KGF0dHJpYnV0ZXMpOworICAgIH0KKworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0VGV4dExvY2F0aW9uKFRleHRIaXRJbmZvIG9mZnNldCkgeyAgICAgICAgCisgICAgICAgIHJldHVybiBnZXRTdHlsZUlNUmVxdWVzdHMoKS5nZXRUZXh0TG9jYXRpb24ob2Zmc2V0KTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogVG8gYmUgY2FsbGVkIGJ5IEFXVCB3aGVuIGNsaWVudCBXaW5kb3cncyBib3VuZHMvdmlzaWJpbGl0eS9zdGF0ZQorICAgICAqIGNoYW5nZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5vdGlmeUNsaWVudFdpbmRvd0NoYW5nZShSZWN0YW5nbGUgYm91bmRzKSB7CisgICAgICAgIGlmIChub3RpZnlJTS5jb250YWlucyhpbnB1dE1ldGhvZCkpIHsKKyAgICAgICAgICAgIGlucHV0TWV0aG9kLm5vdGlmeUNsaWVudFdpbmRvd0NoYW5nZShib3VuZHMpOworICAgICAgICB9CisgICAgICAgIHBlbmRpbmdDbGllbnROb3RpZnkgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgSW5wdXRNZXRob2QgZ2V0SW5wdXRNZXRob2QoKSB7CisgICAgICAgIHJldHVybiBpbnB1dE1ldGhvZDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgQ29tcG9uZW50IGdldENsaWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNsaWVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgTmF0aXZlSU0gZ2V0TmF0aXZlSU0oKSB7CisgICAgICAgIHJldHVybiBuYXRpdmVJTTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9pbnRlcm5hbC9ubHMvTWVzc2FnZXMuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2ludGVybmFsL25scy9NZXNzYWdlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzNDAzNTgKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9pbnRlcm5hbC9ubHMvTWVzc2FnZXMuamF2YQpAQCAtMCwwICsxLDE1MSBAQAorLyogCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICogCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qCisgKiBUSEUgRklMRSBIQVMgQkVFTiBBVVRPR0VORVJBVEVEIEJZIE1TR1RPT0wgVE9PTC4KKyAqIEFsbCBjaGFuZ2VzIG1hZGUgdG8gdGhpcyBmaWxlIG1hbnVhbGx5IHdpbGwgYmUgb3ZlcndyaXR0ZW4gCisgKiBpZiB0aGlzIHRvb2wgcnVucyBhZ2Fpbi4gQmV0dGVyIG1ha2UgY2hhbmdlcyBpbiB0aGUgdGVtcGxhdGUgZmlsZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzOworCisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CisKKy8vIEJFR0lOIGFuZHJvaWQtZGVsZXRlZAorLyoKKyAqIEZvciBBbmRyb2lkLCB0aGlzIG1vZHVsZSBpcyBhIHNlcGFyYXRlIGxpYnJhcnkgYW5kIG5vdCBwYXJ0IG9mIHRoZQorICogYm9vdCBjbGFzc3BhdGgsIHNvIGl0cyByZXNvdXJjZXMgd29uJ3QgYmUgZm91bmQgb24gdGhlIGJvb3QgY2xhc3NwYXRoCisgKiBhcyBpcyBhc3N1bWVkIGJ5IE1zZ0hlbHAuZ2V0U3RyaW5nKCkuIFdlIGluc3RlYWQgdXNlIGEgbG9jYWwgTXNnSGVscAorICogd2hpY2ggYm90dG9tcyBvdXQgaW4gYSBjYWxsIHRvIHRoZSB1c2VmdWwgcGFydCBvZiBpdHMgbG93ZXItbGV2ZWwKKyAqIG5hbWVzYWtlLgorICovCisvL2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLnZtLlZNOworLy9pbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Nc2dIZWxwOworLy8gRU5EIGFuZHJvaWQtZGVsZXRlZAorCisvKioKKyAqIFRoaXMgY2xhc3MgcmV0cmlldmVzIHN0cmluZ3MgZnJvbSBhIHJlc291cmNlIGJ1bmRsZSBhbmQgcmV0dXJucyB0aGVtLAorICogZm9ybWF0dGluZyB0aGVtIHdpdGggTWVzc2FnZUZvcm1hdCB3aGVuIHJlcXVpcmVkLgorICogPHA+CisgKiBJdCBpcyB1c2VkIGJ5IHRoZSBzeXN0ZW0gY2xhc3NlcyB0byBwcm92aWRlIG5hdGlvbmFsIGxhbmd1YWdlIHN1cHBvcnQsIGJ5CisgKiBsb29raW5nIHVwIG1lc3NhZ2VzIGluIHRoZSA8Y29kZT4KKyAqICAgIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLm1lc3NhZ2VzCisgKiA8L2NvZGU+CisgKiByZXNvdXJjZSBidW5kbGUuIE5vdGUgdGhhdCBpZiB0aGlzIGZpbGUgaXMgbm90IGF2YWlsYWJsZSwgb3IgYW4gaW52YWxpZCBrZXkKKyAqIGlzIGxvb2tlZCB1cCwgb3IgcmVzb3VyY2UgYnVuZGxlIHN1cHBvcnQgaXMgbm90IGF2YWlsYWJsZSwgdGhlIGtleSBpdHNlbGYKKyAqIHdpbGwgYmUgcmV0dXJuZWQgYXMgdGhlIGFzc29jaWF0ZWQgbWVzc2FnZS4gVGhpcyBtZWFucyB0aGF0IHRoZSA8ZW0+S0VZPC9lbT4KKyAqIHNob3VsZCBhIHJlYXNvbmFibGUgaHVtYW4tcmVhZGFibGUgKGVuZ2xpc2gpIHN0cmluZy4KKyAqIAorICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZXMgeworCisgICAgLy8gQkVHSU4gYW5kcm9pZC1kZWxldGVkCisgICAgLy9wcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc1Jlc291cmNlID0KKyAgICAvLyAgICAib3JnLmFwYWNoZS5oYXJtb255LmF3dC5pbnRlcm5hbC5ubHMubWVzc2FnZXMiOworICAgIC8vIEVORCBhbmRyb2lkLWRlbGV0ZWQKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG5vIGFyZ3VtZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnKSB7CisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICByZXR1cm4gTXNnSGVscC5nZXRTdHJpbmcobXNnKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggdGFrZXMgMSBhcmd1bWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEBwYXJhbSBhcmcKKyAgICAgKiAgICAgICAgICAgIE9iamVjdCB0aGUgb2JqZWN0IHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbWVzc2FnZSBmb3IgdGhhdCBrZXkgaW4gdGhlIHN5c3RlbSBtZXNzYWdlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZywgT2JqZWN0IGFyZykgeworICAgICAgICByZXR1cm4gZ2V0U3RyaW5nKG1zZywgbmV3IE9iamVjdFtdIHsgYXJnIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggdGFrZXMgMSBpbnRlZ2VyIGFyZ3VtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHBhcmFtIGFyZworICAgICAqICAgICAgICAgICAgaW50IHRoZSBpbnRlZ2VyIHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbWVzc2FnZSBmb3IgdGhhdCBrZXkgaW4gdGhlIHN5c3RlbSBtZXNzYWdlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZywgaW50IGFyZykgeworICAgICAgICByZXR1cm4gZ2V0U3RyaW5nKG1zZywgbmV3IE9iamVjdFtdIHsgSW50ZWdlci50b1N0cmluZyhhcmcpIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggdGFrZXMgMSBjaGFyYWN0ZXIgYXJndW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgU3RyaW5nIHRoZSBrZXkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICBjaGFyIHRoZSBjaGFyYWN0ZXIgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBjaGFyIGFyZykgeworICAgICAgICByZXR1cm4gZ2V0U3RyaW5nKG1zZywgbmV3IE9iamVjdFtdIHsgU3RyaW5nLnZhbHVlT2YoYXJnKSB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBtZXNzYWdlIHdoaWNoIHRha2VzIDIgYXJndW1lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHBhcmFtIGFyZzEKKyAgICAgKiAgICAgICAgICAgIE9iamVjdCBhbiBvYmplY3QgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEBwYXJhbSBhcmcyCisgICAgICogICAgICAgICAgICBPYmplY3QgYW5vdGhlciBvYmplY3QgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBPYmplY3QgYXJnMSwgT2JqZWN0IGFyZzIpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0cmluZyhtc2csIG5ldyBPYmplY3RbXSB7IGFyZzEsIGFyZzIgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCB0YWtlcyBzZXZlcmFsIGFyZ3VtZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEBwYXJhbSBhcmdzCisgICAgICogICAgICAgICAgICBPYmplY3RbXSB0aGUgb2JqZWN0cyB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2csIE9iamVjdFtdIGFyZ3MpIHsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHJldHVybiBNc2dIZWxwLmdldFN0cmluZyhtc2csIGFyZ3MpOworICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgfQorCisgICAgLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisgICAgLy8gRHVwbGljYXRlIGNvZGUgd2FzIGRyb3BwZWQgaW4gZmF2b3Igb2YgdXNpbmcgTXNnSGVscC4KKyAgICAvLyBFTkQgYW5kcm9pZC1ub3RlCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9pbnRlcm5hbC9ubHMvTXNnSGVscC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW50ZXJuYWwvbmxzL01zZ0hlbHAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTdmZTExCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW50ZXJuYWwvbmxzL01zZ0hlbHAuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKgorICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgY2xhc3Mgb2YgdGhlIHNhbWUgbmFtZSBpbgorICogb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOworaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgY29udGFpbnMgaGVscGVyIG1ldGhvZHMgZm9yIGxvYWRpbmcgcmVzb3VyY2UgYnVuZGxlcyBhbmQKKyAqIGZvcm1hdHRpbmcgZXh0ZXJuYWwgbWVzc2FnZSBzdHJpbmdzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTXNnSGVscCB7CisgICAgLyoqIG5hbWUgb2YgdGhlIHJlc291cmNlIGZvciB0aGlzIGNsYXNzICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU09VUkNFX05BTUUgPQorICAgICAgICAiL29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW50ZXJuYWwvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMiOworCisgICAgLyoqIHRoZSByZXNvdXJjZSBidW5kbGUgZm9yIHRoaXMgY2xhc3MgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZXNvdXJjZUJ1bmRsZSBUSEVfQlVORExFOworCisgICAgc3RhdGljIHsKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmIgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IE1zZ0hlbHAuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgUkVTT1VSQ0VfTkFNRSk7CisgICAgICAgICAgICByYiA9IG5ldyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlKGluKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwud2FybmluZygiQ291bGRuJ3QgcmVhZCByZXNvdXJjZSBidW5kbGU6ICIgKworICAgICAgICAgICAgICAgICAgICBleCk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIFNob3VsZG4ndCBoYXBwZW4sIGJ1dCBkZWFsIGF0IGxlYXN0IHNvbWV3aGF0IGdyYWNlZnVsbHkuCisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLndhcm5pbmcoIkNvdWxkbid0IGZpbmQgcmVzb3VyY2UgYnVuZGxlOiAiICsKKyAgICAgICAgICAgICAgICAgICAgZXgpOworICAgICAgICB9CisKKyAgICAgICAgVEhFX0JVTkRMRSA9IHJiOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZykgeworICAgICAgICBpZiAoVEhFX0JVTkRMRSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbXNnOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gVEhFX0JVTkRMRS5nZXRTdHJpbmcobXNnKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAiTWlzc2luZyBtZXNzYWdlOiAiICsgbXNnOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIFN0cmluZyBmb3JtYXQgPSBtc2c7CisgICAgICAgIGlmIChUSEVfQlVORExFICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9ybWF0ID0gVEhFX0JVTkRMRS5nZXRTdHJpbmcobXNnKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Nc2dIZWxwLmZvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3N0YXRlL01lbnVJdGVtU3RhdGUuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3N0YXRlL01lbnVJdGVtU3RhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTNlNTBiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvc3RhdGUvTWVudUl0ZW1TdGF0ZS5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC5zdGF0ZTsKKworaW1wb3J0IGphdmEuYXd0LkRpbWVuc2lvbjsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKKy8qKgorICogU3RhdGUgb2YgbWVudSBpdGVtCisgKi8KKworcHVibGljIGludGVyZmFjZSBNZW51SXRlbVN0YXRlIHsKKworICAgIFN0cmluZyBnZXRUZXh0KCk7CisgICAgUmVjdGFuZ2xlIGdldFRleHRCb3VuZHMoKTsKKyAgICB2b2lkIHNldFRleHRCb3VuZHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpOworCisgICAgU3RyaW5nIGdldFNob3J0Y3V0KCk7CisgICAgUmVjdGFuZ2xlIGdldFNob3J0Y3V0Qm91bmRzKCk7CisgICAgdm9pZCBzZXRTaG9ydGN1dEJvdW5kcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCk7CisKKyAgICBSZWN0YW5nbGUgZ2V0SXRlbUJvdW5kcygpOworICAgIHZvaWQgc2V0SXRlbUJvdW5kcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCk7CisKKyAgICBib29sZWFuIGlzTWVudSgpOworICAgIGJvb2xlYW4gaXNDaGVja2VkKCk7CisgICAgYm9vbGVhbiBpc0VuYWJsZWQoKTsKKworICAgIGJvb2xlYW4gaXNDaGVja0JveCgpOworICAgIGJvb2xlYW4gaXNTZXBhcmF0b3IoKTsKKworICAgIERpbWVuc2lvbiBnZXRNZW51U2l6ZSgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvc3RhdGUvTWVudVN0YXRlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC9zdGF0ZS9NZW51U3RhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjRhNDlhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvc3RhdGUvTWVudVN0YXRlLmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LnN0YXRlOworCitpbXBvcnQgamF2YS5hd3QuRm9udDsKK2ltcG9ydCBqYXZhLmF3dC5Gb250TWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5Qb2ludDsKKworLyoqCisgKiBTdGF0ZSBvZiBwb3AtdXAgb3IgZHJvcC1kb3duIG1lbnUKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIE1lbnVTdGF0ZSB7CisgICAgaW50IGdldFdpZHRoKCk7CisgICAgaW50IGdldEhlaWdodCgpOworICAgIFBvaW50IGdldExvY2F0aW9uKCk7CisKKyAgICB2b2lkIHNldFNpemUoaW50IHcsIGludCBoKTsKKworICAgIEZvbnQgZ2V0Rm9udCgpOworICAgIGJvb2xlYW4gaXNGb250U2V0KCk7CisgICAgRm9udE1ldHJpY3MgZ2V0Rm9udE1ldHJpY3MoRm9udCBmKTsKKworICAgIGludCBnZXRJdGVtQ291bnQoKTsKKyAgICBpbnQgZ2V0U2VsZWN0ZWRJdGVtSW5kZXgoKTsKKworICAgIE1lbnVJdGVtU3RhdGUgZ2V0SXRlbShpbnQgaW5kZXgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvc3RhdGUvU3RhdGUuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3N0YXRlL1N0YXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGI4NzA2ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3N0YXRlL1N0YXRlLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LnN0YXRlOworCitpbXBvcnQgamF2YS5hd3QuQ29sb3I7CitpbXBvcnQgamF2YS5hd3QuRGltZW5zaW9uOworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuRm9udE1ldHJpY3M7CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworCisvKioKKyAqIFN0YXRlIG9mIHRoZSBjb21wb25lbnQKKyAqLworcHVibGljIGludGVyZmFjZSBTdGF0ZSB7CisKKyAgICBib29sZWFuIGlzRW5hYmxlZCgpOworICAgIGJvb2xlYW4gaXNWaXNpYmxlKCk7CisgICAgYm9vbGVhbiBpc0ZvY3VzZWQoKTsKKworICAgIEZvbnQgZ2V0Rm9udCgpOworICAgIGJvb2xlYW4gaXNGb250U2V0KCk7CisgICAgRm9udE1ldHJpY3MgZ2V0Rm9udE1ldHJpY3MoKTsKKworICAgIENvbG9yIGdldEJhY2tncm91bmQoKTsKKyAgICBib29sZWFuIGlzQmFja2dyb3VuZFNldCgpOworCisgICAgQ29sb3IgZ2V0VGV4dENvbG9yKCk7CisgICAgYm9vbGVhbiBpc1RleHRDb2xvclNldCgpOworCisgICAgUmVjdGFuZ2xlIGdldEJvdW5kcygpOworICAgIERpbWVuc2lvbiBnZXRTaXplKCk7CisKKyAgICBEaW1lbnNpb24gZ2V0RGVmYXVsdE1pbmltdW1TaXplKCk7CisgICAgdm9pZCBzZXREZWZhdWx0TWluaW11bVNpemUoRGltZW5zaW9uIHNpemUpOworCisgICAgbG9uZyBnZXRXaW5kb3dJZCgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0NyZWF0aW9uUGFyYW1zLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvQ3JlYXRpb25QYXJhbXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2M1ODFkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0NyZWF0aW9uUGFyYW1zLmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRG1pdHJ5IEEuIER1cm5ldgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrOworCisvKioKKyAqIFRoaXMgY2xhc3MgZGVzY3JpYmVzIGNyb3NzLXBsYXRmb3JtIE5hdGl2ZVdpbmRvdyBjcmVhdGlvbiBwYXJhbXMKKyAqIFNlZSBhbHNvIFdpbmRvd0ZhY3RvcnkuY3JlYXRlV2luZG93CisgKi8KK3B1YmxpYyBjbGFzcyBDcmVhdGlvblBhcmFtcyB7CisgICAgLyoqCisgICAgICogSW5pdGlhbCBzdGF0ZSBpcyBtYXhpbWl6ZWQgdmVydGljYWx5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgTUFYSU1JWkVEX1ZFUlQgPSAxOworICAgIC8qKgorICAgICAqIEluaXRpYWwgc3RhdGUgaXMgbWF4aW1pemVkIGhvcml6b250YWx5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgTUFYSU1JWkVEX0hPUklaID0gMjsKKyAgICAvKioKKyAgICAgKiBJbml0aWFsIHN0YXRlIGlzIG1heGltaXplZCBib3RoCisgICAgICogaG9yaXpvbnRhbHkgYW5kIHZlcnRpY2FseQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIE1BWElNSVpFRCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdG9wLWxldmVsIHdpbmRvdyB0aGF0IGhhcyBhbGwgcG9zc2libGUgZGVjb3JhdGlvbnMsCisgICAgICogaGFzIG5vIG93bmVyIGFuZCBpcyBkaXNwbGF5ZWQgaW4gdGFza2JhcgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IERFQ09SX1RZUEVfRlJBTUUgPSAxOworICAgIC8qKgorICAgICAqIFRoZSBkaWFsb2cgd2luZG93CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgREVDT1JfVFlQRV9ESUFMT0cgPSAyOworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2llbnQgdW5kZWNvcmF0ZWQgcG9wLXVwIHdpbmRvdworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IERFQ09SX1RZUEVfUE9QVVAgPSAzOworICAgIC8qKgorICAgICAqIFRoZSB1bmRlY29yYWRlZCBwb3AtdXAgd2luZG93CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgREVDT1JfVFlQRV9VTkRFQ09SID0gNDsKKyAgICAvKioKKyAgICAgKiBOb24tTURJIGNoaWxkIHdpbmRvdworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IERFQ09SX1RZUEVfTk9ORSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsIHguCisgICAgICovCisgICAgcHVibGljIGludCB4ID0gMDsKKyAgICAvKioKKyAgICAgKiBJbml0aWFsIHkuCisgICAgICovCisgICAgcHVibGljIGludCB5ID0gMDsKKyAgICAvKioKKyAgICAgKiBJbml0aWFsIHdpZHRoLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgdyA9IDE7CisgICAgLyoqCisgICAgICogSW5pdGlhbCBoZWlnaHQuCisgICAgICovCisgICAgcHVibGljIGludCBoID0gMTsKKyAgICAvKioKKyAgICAgKiBUaGUgZGVjb3JhdGlvbiB0eXBlIG9mIHRoZSB0b3AtbGV2ZWwgd2luZG93LiBUaGUgcG9zc2libGUgdmFsdWVzIGFyZToKKyAgICAgKiBERUNPUl9UWVBFX0ZSQU1FLCBERUNPUl9UWVBFX0RJQUxPRywgREVDT1JfVFlQRV9QT1BVUCBhbmQgREVDT1JfVFlQRV9VTkRFQ09SCisgICAgICovCisgICAgcHVibGljIGludCBkZWNvclR5cGUgPSBERUNPUl9UWVBFX05PTkU7CisgICAgLyoqCisgICAgICogV2luZG93IGlzIGNoaWxkIG9mIHBhcmVudCwgb3RoZXJ3aXNlIGl0J3MKKyAgICAgKiB0b3BsZXZlbChjaGlsZCBvZiBkZXNrdG9wKSB3aW5kb3cgb3duZWQgYnkgcGFyZW50LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNoaWxkID0gZmFsc2U7CisgICAgLyoqCisgICAgICogV2luZG93IGlzIHJlc2l6YWJsZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlc2l6YWJsZSA9IHRydWU7CisgICAgLyoqCisgICAgICogVGhlIHdpbmRvdyBoYXMgbm8gZGVjb3JhdGlvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB1bmRlY29yYXRlZCA9IGZhbHNlOworICAgIC8qKgorICAgICAqIEluaXRpYWwgdmlzaWJpbGl0eSBzdGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB2aXNpYmxlID0gZmFsc2U7CisgICAgLyoqCisgICAgICogV2luZG93IGlzIEFMV0FZUyB0b3Btb3N0IGluIFogb3JkZXIuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdG9wbW9zdCA9IGZhbHNlOworICAgIC8qKgorICAgICAqIFdpbmRvdyBpcyBkaXNhYmxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBkaXNhYmxlZCA9IGZhbHNlOworICAgIC8qKgorICAgICAqIFdpbmRvdyBpbml0aWFsbHkgaWNvbmlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGljb25pZmllZCA9IGZhbHNlOworICAgIC8qKgorICAgICAqIEJpdHdpc2UgT1Igb2YgTUFYSU1JWkVEXyogY29uc3RhbnRzLgorICAgICAqIE1lYW5zIGlmIHdpbmRvdyBpcyBpbml0aWFsbHkgbWF4aW1pemVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbWF4aW1pemVkU3RhdGUgPSAwOworICAgIC8qKgorICAgICAqIFRlbGxzIHRoYXQgd2luZG93IHBvc2l0aW9uIHNob3VsZCBiZSBkZXRlcm1pbmVkIGJ5IG5hdGl2ZSB3aW5kb3dpbmcgc3lzdGVtIAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGxvY2F0aW9uQnlQbGF0Zm9ybSA9IGZhbHNlOworICAgIC8qKgorICAgICAqIElkIG9mIHBhcmVudCBvciBvd25lciB3aW5kb3csIHNlZSBjaGlsZCBmaWVsZAorICAgICAqIEZvciBub24tY2hpbGQgd2luZG93IHdpdGhvdXQgb3duZXIgZXF1YWxzIDAuCisgICAgICovCisgICAgcHVibGljIGxvbmcgcGFyZW50SWQgPSAwOworICAgIC8qKgorICAgICAqIE5hbWUgd2ljaCBpcyBkaXNwbGF5ZWQgb24gdGl0bGViYXIsIHRhc2tiYXIgYW5kIHZpc2libGUKKyAgICAgKiBmb3Igc3lzdGVtIHJlcXVlc3RzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmFtZSA9IG51bGw7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0N1cnNvckZhY3RvcnkuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9DdXJzb3JGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzVlN2QzMwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9DdXJzb3JGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKK2ltcG9ydCBqYXZhLmF3dC5EaW1lbnNpb247CitpbXBvcnQgamF2YS5hd3QuSW1hZ2U7CisKKy8qKgorICogUHJvdmlkZXMgZmFjdG9yeSBmb3IgTmF0aXZlQ3Vyc29yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDdXJzb3JGYWN0b3J5IHsKKyAgICBwcm90ZWN0ZWQgTmF0aXZlQ3Vyc29yW10gc3lzdGVtQ3Vyc29ycyA9IHsKKyAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIG51bGwsCisgICAgICAgICAgICBudWxsLCBudWxsLCBudWxsLCBudWxsLAorICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgIG51bGwsIG51bGwsCisgICAgfTsKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuZCByZXR1cm5zIE5hdGl2ZUN1cnNvciBmb3IgcHJlZGVmaW5lZAorICAgICAqIEphdmEgQ3Vyc29yCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAtIHR5cGUgb2YgcHJlZGVmaW5lZCBKYXZhIEN1cnNvcgorICAgICAqIEByZXR1cm4gY3JlYXRlZCBjdXJzb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTmF0aXZlQ3Vyc29yIGNyZWF0ZUN1cnNvcihpbnQgdHlwZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgY2FjaGVkIGluc3RhbmNlIG9mIHN5c3RlbShwcmVkZWZpbmVkKSBuYXRpdmUgY3Vyc29yCisgICAgICogb3IgY3JlYXRlcyBhIG5ldyBvbmUuIFRoaXMgaXMgYSBwbGF0Zm9ybS1pbmRlcGVuZGVudCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAtIHR5cGUgb2YgcHJlZGVmaW5lZCBKYXZhIEN1cnNvcgorICAgICAqIEByZXR1cm4gY3JlYXRlZCBjdXJzb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgTmF0aXZlQ3Vyc29yIGdldEN1cnNvcihpbnQgdHlwZSkgeworICAgICAgICBpZiAodHlwZSA+PSAwICYmIHR5cGUgPCBzeXN0ZW1DdXJzb3JzLmxlbmd0aCkgeworICAgICAgICAgICAgTmF0aXZlQ3Vyc29yIGN1cnNvciA9IHN5c3RlbUN1cnNvcnNbdHlwZV07CisgICAgICAgICAgICBpZiAoY3Vyc29yID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjdXJzb3IgPSBjcmVhdGVDdXJzb3IodHlwZSk7CisgICAgICAgICAgICAgICAgc3lzdGVtQ3Vyc29yc1t0eXBlXSA9IGN1cnNvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgY3VzdG9tIE5hdGl2ZUN1cnNvciBmcm9tIGltYWdlCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW1nIC0gaW1hZ2Uoc291cmNlKSB0byBjcmVhdGUgY3Vyc29yIGZyb20KKyAgICAgKiBAcGFyYW0geEhvdFNwb3QgLSB4IGNvb3JkaW5hdGUgb2YgdGhlIGhvdHNwb3QgcmVsYXRpdmUgdG8gdGhlIHNvdXJjZSdzIG9yaWdpbgorICAgICAqIEBwYXJhbSB5SG90U3BvdCAtIHkgY29vcmRpbmF0ZSBvZiB0aGUgaG90c3BvdCByZWxhdGl2ZSB0byB0aGUgc291cmNlJ3Mgb3JpZ2luCisgICAgICogQHJldHVybiBjcmVhdGVkIGN1cnNvcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBOYXRpdmVDdXJzb3IgY3JlYXRlQ3VzdG9tQ3Vyc29yKEltYWdlIGltZywgaW50IHhIb3RTcG90LCBpbnQgeUhvdFNwb3QpOworCisgICAgLyoqCisgICAgICogUXVlcnkgbmF0aXZlIHN5c3RlbSBmb3IgdGhlIGJlc3QgY3Vyc29yIHNpemUgY2xvc2VzdCB0byBzcGVjaWZpZWQgZGltZW5zaW9ucworICAgICAqIEBwYXJhbSBwcmVmV2lkdGggLSBwcmVmZXJyZWQgd2lkdGgKKyAgICAgKiBAcGFyYW0gcHJlZkhlaWdodCAtIHByZWZlcnJlZCBoZWlnaHQKKyAgICAgKiBAcmV0dXJuIGNsb3Nlc3Qgc3VwcG9ydGVkIGRpbWVuc2lvbnMgdG8gb25lcyBzcGVjaWZpZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGltZW5zaW9uIGdldEJlc3RDdXJzb3JTaXplKGludCBwcmVmV2lkdGgsIGludCBwcmVmSGVpZ2h0KTsKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gbWF4aW11bSBudW1iZXIgb2YgY29sb3JzIHN1cHBvcnRlZCBieSBjdXN0b20gY3Vyc29ycworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TWF4aW11bUN1cnNvckNvbG9ycygpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0dyYXBoaWNzRmFjdG9yeS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0dyYXBoaWNzRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkN2M4NGYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvR3JhcGhpY3NGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YsIEFsZXhleSBBLiBQZXRyZW5rbywgT2xlZyBWLiBLaGFzY2hhbnNreQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrOworCitpbXBvcnQgamF2YS5hd3QuRm9udDsKK2ltcG9ydCBqYXZhLmF3dC5Gb250TWV0cmljczsKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOworaW1wb3J0IGphdmEuYXd0LkdyYXBoaWNzRW52aXJvbm1lbnQ7CitpbXBvcnQgamF2YS5hd3QucGVlci5Gb250UGVlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLk11bHRpUmVjdEFyZWE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5mb250LkZvbnRNYW5hZ2VyOworCitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5DYW52YXM7CitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5QYWludDsKKworCisvKioKKyAqIEdyYXBoaWNzRmFjdG9yeSBpbnRlcmZhY2UgZGVmaW5lcyBtZXRob2RzIGZvciBHcmFwaGljczJEIAorICogYW5kIGZvbnQgc3R1ZmYgaW5zdGFuY2VzIGZhY3Rvcmllcy4KKyAqLworcHVibGljIGludGVyZmFjZSBHcmFwaGljc0ZhY3RvcnkgeworICAgIHN0YXRpYyBmaW5hbCBGb250TWV0cmljcyBjYWNoZUZNW10gPSAgbmV3IEZvbnRNZXRyaWNzWzEwXTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIEdyYXBoaWNzMkQgaW5zdGFuY2UgZm9yIHNwZWNpZmllZCBuYXRpdmUgd2luZG93LgorICAgICAqICAKKyAgICAgKiBAcGFyYW0gd2luIE5hdGl2ZSB3aW5kb3cgdG8gZHJhdworICAgICAqIEBwYXJhbSB0cmFuc2xhdGVYIFRyYW5zbGF0aW9uIGFsb25nIFggYXhpcworICAgICAqIEBwYXJhbSB0cmFuc2xhdGVZIFRyYW5zbGF0aW9uIGFsb25nIFkgYXhpcworICAgICAqIEBwYXJhbSBjbGlwIENsaXBwaW5nIGFyZWEgZm9yIGEgbmV3IEdyYXBoaWNzMkQgaW5zdGFuY2UKKyAgICAgKiBAcmV0dXJuIE5ldyBHcmFwaGljczJEIGluc3RhbmNlIGZvciBzcGVjaWZpZWQgbmF0aXZlIHdpbmRvdworICAgICAqIEBkZXByZWNhdGVkCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBHcmFwaGljczJEIGdldEdyYXBoaWNzMkQoTmF0aXZlV2luZG93IHdpbiwgaW50IHRyYW5zbGF0ZVgsIGludCB0cmFuc2xhdGVZLCBNdWx0aVJlY3RBcmVhIGNsaXApOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBHcmFwaGljczJEIGluc3RhbmNlIGZvciBzcGVjaWZpZWQgbmF0aXZlIHdpbmRvdy4KKyAgICAgKiAgCisgICAgICogQHBhcmFtIHdpbiBOYXRpdmUgd2luZG93IHRvIGRyYXcKKyAgICAgKiBAcGFyYW0gdHJhbnNsYXRlWCBUcmFuc2xhdGlvbiBhbG9uZyBYIGF4aXMKKyAgICAgKiBAcGFyYW0gdHJhbnNsYXRlWSBUcmFuc2xhdGlvbiBhbG9uZyBZIGF4aXMKKyAgICAgKiBAcGFyYW0gd2lkdGggV2lkdGggb2YgZHJhd2luZyBhcmVhCisgICAgICogQHBhcmFtIGhlaWdodCBIZWlnaHQgb2YgZHJhd2luZyBhcmVhCisgICAgICogQHJldHVybiBOZXcgR3JhcGhpY3MyRCBpbnN0YW5jZSBmb3Igc3BlY2lmaWVkIG5hdGl2ZSB3aW5kb3cKKyAgICAgKi8KKyAgICBHcmFwaGljczJEIGdldEdyYXBoaWNzMkQoTmF0aXZlV2luZG93IHdpbiwgaW50IHRyYW5zbGF0ZVgsIGludCB0cmFuc2xhdGVZLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpOworICAgIC8vID8/P0FXVDogbm90IHN0YW5kYXJkIGhhcm1vbnkKKyAgICBHcmFwaGljczJEIGdldEdyYXBoaWNzMkQoQ2FudmFzIGMsIFBhaW50IHApOworICAgIAorICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5zdGFuY2Ugb2YgR3JhcGhpY3NFbnZpcm9ubWVudCBmb3Igc3BlY2lmaWVkIFdpbmRvd0ZhY3RvcnkKKyAgICAgKiAgCisgICAgICogQHBhcmFtIHdmIFdpbmRvd0ZhY3RvcnkKKyAgICAgKiBAcmV0dXJuIE5ldyBpbnN0YW5jZSBvZiBHcmFwaGljc0Vudmlyb25tZW50CisgICAgICovCisgICAgR3JhcGhpY3NFbnZpcm9ubWVudCBjcmVhdGVHcmFwaGljc0Vudmlyb25tZW50KFdpbmRvd0ZhY3Rvcnkgd2YpOworICAgIAorICAgIC8vIEZvbnQgbWV0aG9kcworICAgIEZvbnRNZXRyaWNzIGdldEZvbnRNZXRyaWNzKEZvbnQgZm9udCk7CisgICAgRm9udE1hbmFnZXIgZ2V0Rm9udE1hbmFnZXIoKTsKKyAgICBGb250UGVlciBnZXRGb250UGVlcihGb250IGZvbnQpOworICAgIEZvbnQgZW1iZWRGb250KFN0cmluZyBmb250RmlsZVBhdGgpOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL0tleUluZm8uamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9LZXlJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWY4YTI5YQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9LZXlJbmZvLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUV2ZW50OworCisvKioKKyAqIEtleXN0cm9rZSBpbmZvcm1hdGlvbgorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBLZXlJbmZvIHsKKworICAgIHB1YmxpYyBpbnQgdktleTsKKyAgICBwdWJsaWMgaW50IGtleUxvY2F0aW9uOworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmdCdWZmZXIga2V5Q2hhcnM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1ZLRVkgPSBLZXlFdmVudC5WS19VTkRFRklORUQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MT0NBVElPTiA9IEtleUV2ZW50LktFWV9MT0NBVElPTl9TVEFOREFSRDsKKworICAgIHB1YmxpYyBLZXlJbmZvKCkgeworICAgICAgICB2S2V5ID0gREVGQVVMVF9WS0VZOworICAgICAgICBrZXlMb2NhdGlvbiA9IERFRkFVTFRfTE9DQVRJT047CisgICAgICAgIGtleUNoYXJzID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEtleUNoYXJzKGNoYXIgY2gpIHsKKyAgICAgICAga2V5Q2hhcnMuc2V0TGVuZ3RoKDApOworICAgICAgICBrZXlDaGFycy5hcHBlbmQoY2gpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEtleUNoYXJzKFN0cmluZ0J1ZmZlciBzYikgeworICAgICAgICBrZXlDaGFycy5zZXRMZW5ndGgoMCk7CisgICAgICAgIGtleUNoYXJzLmFwcGVuZChzYik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUN1cnNvci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUN1cnNvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjNmViMWUKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlQ3Vyc29yLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBEbWl0cnkgQS4gRHVybmV2CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBwcm92aWRlcyBhY2Nlc3MgdG8gcGxhdGZvcm0gZGVwZW5kZW50IGZ1bmN0aW9uYWxpdHkKKyAqIGZvciB0aGUgY2xhc3MgamF2YS5hd3QuQ3Vyc29yLgorICovCitwdWJsaWMgaW50ZXJmYWNlIE5hdGl2ZUN1cnNvciB7CisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBjdXJzb3Igc2hhcGUKKyAgICAgKiB0byB0aGlzIGN1cnNvciB3aGVuIGEgcG9pbnRlciBpcyBpbnNpZGUKKyAgICAgKiBAcGFyYW0gd2luSUQgLSB3aW5kb3coY3VycmVudGx5IHVzZWQgb25seSBvbiBYMTEpCisgICAgICovCisgICAgdm9pZCBzZXRDdXJzb3IobG9uZyB3aW5JRCk7CisgICAgLyoqCisgICAgICogRGVzdHJveXMgdGhlIG5hdGl2ZSByZXNvdXJjZSBhc3NvY2lhdGVkIHdpdGgKKyAgICAgKiB0aGlzIGN1cnNvcgorICAgICAqLworICAgIHZvaWQgZGVzdHJveUN1cnNvcigpOworCisgICAgLyoqCisgICAgICogQHJldHVybiBOYXRpdmUgaGFuZGxlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGN1cnNvcgorICAgICAqLworICAgIGxvbmcgZ2V0SWQoKTsKKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUV2ZW50LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlRXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDcxYzFhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUV2ZW50LmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWlraGFpbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKK2ltcG9ydCBqYXZhLmF3dC5JbnNldHM7CitpbXBvcnQgamF2YS5hd3QuUmVjdGFuZ2xlOworaW1wb3J0IGphdmEuYXd0LlBvaW50OworaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUV2ZW50OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5NdWx0aVJlY3RBcmVhOworCisKKy8qKgorICogVGhlIGludGVyZmFjZSBkZXNjcmliaW5nIGNyb3NzLXBsYXRmb3JtIHRyYW5zbGF0aW9uIG9mIHN5c3RlbQorICogbWVzc2FnZXMuCisgKgorICogPHAvPlNvbWUgbWVzc2FnZXMgY2FuIGFwcGVhciBvbmx5IG9uIHNwZWNpZmljIHBsYXRmb3JtLAorICogYnV0IHRoZXkgc3RpbGwgY2FuIGhhdmUgY3Jvc3MtcGxhdGZvcm0gaW50ZXJwcmV0YXRpb24gaWYgdGhlCisgKiBhcHBsaWNhdGlvbiBzaG91bGQgYmUgYXdhcmUgb2YgdGhlbSBhbmQgY2FuIHJlYWN0IHVzaW5nCisgKiBjcm9zcy1wbGF0Zm9ybSBBUEkuCisgKgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTmF0aXZlRXZlbnQgeworCisgICAgLyoqCisgICAgICogTWVzc2FnZSBoYXMgbm8gY29tbW9uIGNyb3NzLXBsYXRmb3JtCisgICAgICogaW50ZXJwcmV0YXRpb24gYW5kIHNob3VsZCBiZSBza2lwcGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElEX1BMQVRGT1JNID0gMDsKKworICAgIC8qKgorICAgICAqIFdpbmRvdyBib3VuZHMgaGF2ZSBjaGFuZ2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElEX0JPVU5EU19DSEFOR0VEID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBXaW5kb3cgZGVjb3JhdGlvbiBzaXplIGhhcyBjaGFuZ2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElEX0lOU0VUU19DSEFOR0VEID0gLTI7CisKKyAgICAvKioKKyAgICAgKiBXaW5kb3cgd2FzIGp1c3QgY3JlYXRlZCAoV01fQ1JFQVRFIG9uIFdpbmRvd3MpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSURfQ1JFQVRFRCA9IC0zOworCisgICAgLyoqCisgICAgICogTW91c2UgZ3JhYiB3YXMgY2FuY2VsZWQgYnkgdGhlIG5hdGl2ZSBzeXN0ZW0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRF9NT1VTRV9HUkFCX0NBTkNFTEVEID0gLTQ7CisKKyAgICAvKioKKyAgICAgKiBTeXN0ZW0gY29sb3Igc2NoZW1lIG9yIHZpc3VhbCB0aGVtZSB3YXMgY2hhbmdlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElEX1RIRU1FX0NIQU5HRUQgPSAtNTsKKworICAgIHByb3RlY3RlZCBsb25nIHdpbmRvd0lkOworICAgIHByb3RlY3RlZCBpbnQgZXZlbnRJZDsKKyAgICBwcm90ZWN0ZWQgbG9uZyBvdGhlcldpbmRvd0lkOworCisgICAgcHJvdGVjdGVkIFBvaW50IHNjcmVlblBvczsKKyAgICBwcm90ZWN0ZWQgUG9pbnQgbG9jYWxQb3M7CisgICAgcHJvdGVjdGVkIFJlY3RhbmdsZSB3aW5kb3dSZWN0OworCisgICAgcHJvdGVjdGVkIGludCBtb2RpZmllcnM7CisgICAgcHJvdGVjdGVkIGludCBtb3VzZUJ1dHRvbjsKKyAgICBwcm90ZWN0ZWQgaW50IHdoZWVsUm90YXRpb247CisKKyAgICBwcm90ZWN0ZWQgS2V5SW5mbyBrZXlJbmZvID0gbmV3IEtleUluZm8oKTsKKworICAgIHByb3RlY3RlZCBpbnQgd2luZG93U3RhdGUgPSAtMTsKKyAgICBwcm90ZWN0ZWQgbG9uZyB0aW1lOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3lzdGVtIHdpbmRvdyBpZCBvZiB0aGUgZXZlbnQgcmVjaXBpZW50LgorICAgICAqIEByZXR1cm4gSFdORCBvbiBXaW5kb3dzLCB4d2luZG5vdyBvbiBYCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0V2luZG93SWQoKSB7CisgICAgICAgIHJldHVybiB3aW5kb3dJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGNyb3NzLXBsYXRmb3JtIGV2ZW50IGlkCisgICAgICogc2hvdWxkIGJlIG9uZSBvZiBJRF8qIGNvbnN0YW50cyBvcgorICAgICAqIGlkIGNvbnN0YW50cyBmcm9tIGphdmEuYXd0LkFXVEV2ZW50IHN1YmNsYXNlc3MKKyAgICAgKiBAcmV0dXJuIGNyb3NzLXBsYXRmb3JtIGV2ZW50IGlkCisgICAgICovCisgICAgcHVibGljIGludCBnZXRFdmVudElkKCkgeworICAgICAgICByZXR1cm4gZXZlbnRJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiBjdXJzb3Igd2hlbiBldmVudCBvY2N1cmVkIHJlbGF0aXZlIHRvCisgICAgICogdG9wLWxlZnQgY29ybmVyIG9mIHJlY2lwaWVudCB3aW5kb3cKKyAgICAgKiBAcmV0dXJuIHBvc2l0aW9uIG9mIGN1cnNvciBpbiBsb2NhbCBjb29yZGluYXRlcworICAgICAqLworICAgIHB1YmxpYyBQb2ludCBnZXRMb2NhbFBvcygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsUG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIGN1cnNvciB3aGVuIGV2ZW50IG9jY3VyZWQKKyAgICAgKiBpbiBzY3JlZW4gY29vcmRpbmF0ZXMuCisgICAgICogQHJldHVybiBwb3NpdGlvbiBvZiBjdXJzb3IgaW4gc2NyZWVuIGNvb3JkaW5hdGVzCisgICAgICovCisgICAgcHVibGljIFBvaW50IGdldFNjcmVlblBvcygpIHsKKyAgICAgICAgcmV0dXJuIHNjcmVlblBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVjaXBpZW50IHdpbmRvdyBib3VuZHMgd2hlbiB0aGUgZXZlbnQgb2NjdXJlZAorICAgICAqIEByZXR1cm4gd2luZG93IGJvdW5kcworICAgICAqLworICAgIHB1YmxpYyBSZWN0YW5nbGUgZ2V0V2luZG93UmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIHdpbmRvd1JlY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2Yga2V5Ym9hcmQgYW5kIG1vdXNlIGJ1dHRvbnMgd2hlbiB0aGUgZXZlbnQKKyAgICAgKiBvY2N1cmVkIGlmIGV2ZW50IGZyb20gbW91c2Ugb3Iga2V5Ym9hcmQsIGZvciBvdGhlciBldmVudHMgY2FuCisgICAgICogcmV0dXJuIGp1bmsgdmFsdWVzLiBUaGUgdmFsdWUgaXMgYml0d2lzZSBPUiBvZgorICAgICAqIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQgKl9ET1dOIGNvbnN0YW50cy4KKyAgICAgKgorICAgICAqIE1ldGhvZCBpcyBhd2FyZSBvZiBzeXN0ZW0gbW91c2UgYnV0dG9uIHN3YXAgZm9yIGxlZnQtaGFuZAorICAgICAqIG1vdXNlIGFuZCByZXR1cm4gc3dhcHBlZCB2YWx1ZXMuCisgICAgICogQHJldHVybiBiaXR3aXNlIE9SIG9mIGphdmEuYXd0LmV2ZW50LklucHV0RXZlbnQgKl9ET1dOIGNvbnN0YW50cworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5wdXRNb2RpZmllcnMoKSB7CisgICAgICAgIHJldHVybiBtb2RpZmllcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaWNvbmlmaWVkL21heGltaXplZCBzdGF0ZSBvZiByZWNpcGllbnQgd2luZG93IGlmCisgICAgICogZXZlbnQgaXMgc3RhdGUgcmVsYXRlZCwgZm9yIG90aGVyIGV2ZW50cyBjYW4ganVuayB2YWx1ZXMuCisgICAgICogVGhlIHZhbHVlIGhhcyB0aGUgc2FtZSBtZWFuaW5nIGFzIEZyYW1lLmdldEV4dGVuZGVkU3RhdGUKKyAgICAgKiBJdCdzIGJpdHdpc2UgT1Igb2YgSUNPTklGSUVELCBNQVhJTUlaRURfSE9SSVosIE1BWElNSVpFRF9WRVJUCisgICAgICogQHJldHVybiBiaXR3aXNlIE9SIG9mIElDT05JRklFRCwgTUFYSU1JWkVEX0hPUklaLCBNQVhJTUlaRURfVkVSVAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2luZG93U3RhdGUoKSB7CisgICAgICAgIHJldHVybiB3aW5kb3dTdGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2FtZSBtZWFuaW5nIGFzIGphdmEuYXd0LmV2ZW50LmdldEtleUNvZGUKKyAgICAgKiBAcmV0dXJuIGphdmEuYXd0LmV2ZW50IFZLXyogY29uc3RhbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZLZXkoKSB7CisgICAgICAgIHJldHVybiAoa2V5SW5mbyAhPSBudWxsKSA/IGtleUluZm8udktleSA6IEtleUluZm8uREVGQVVMVF9WS0VZOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBzYW1lIG1lYW5pbmcgYXMgamF2YS5hd3QuZXZlbnQuZ2V0S2V5TG9jYXRpb24KKyAgICAgKiBAcmV0dXJuIGphdmEuYXd0LmV2ZW50IEtFWV9MT0NBVElPTl8qIGNvbnN0YW50CisgICAgICovCisgICAgcHVibGljIGludCBnZXRLZXlMb2NhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIChrZXlJbmZvICE9IG51bGwpID8ga2V5SW5mby5rZXlMb2NhdGlvbiA6IEtleUluZm8uREVGQVVMVF9MT0NBVElPTjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQKKyAgICAgKiBIYXMgbWVhbmluZyBvbmx5IGZvciBLRVlfUFJFU1NFRCBhcyBzaG91bGQgYmUgdHJhbnNsYXRlZCB0bworICAgICAqIHNlcmllIG9mIEtFWV9UWVBFRCBldmVudHMuIEZvciBkZWFkIGtleXMgYW5kIGlucHV0IG1ldGhvZHMKKyAgICAgKiBvbmUga2V5IHByZXNzIGNhbiBnZW5lcmF0ZSBtdWx0aXBsZSBrZXkgY2hhcnMuCisgICAgICogQHJldHVybiBzdHJpbmcgb2YgY2hhcmFjdGVycworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZ2V0S2V5Q2hhcnMoKSB7CisgICAgICAgIGlmIChrZXlJbmZvID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChrZXlJbmZvLnZLZXkgPT0gS2V5RXZlbnQuVktfRU5URVIpIHsKKyAgICAgICAgICAgIGtleUluZm8ua2V5Q2hhcnMuc2V0TGVuZ3RoKDApOworICAgICAgICAgICAga2V5SW5mby5zZXRLZXlDaGFycygnXG4nKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4ga2V5SW5mby5rZXlDaGFyczsKKyAgICB9CisKKyAgICBwdWJsaWMgY2hhciBnZXRMYXN0Q2hhcigpIHsKKyAgICAgICAgaWYgKGtleUluZm8gPT0gbnVsbCB8fCBrZXlJbmZvLmtleUNoYXJzLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBLZXlFdmVudC5DSEFSX1VOREVGSU5FRDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4ga2V5SW5mby5rZXlDaGFycy5jaGFyQXQoa2V5SW5mby5rZXlDaGFycy5sZW5ndGgoKS0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgbW91c2UgYnV0dG9uIHdoaWNoIGNoYW5nZWQgaXQncyBzdGF0ZSwKKyAgICAgKiBvdGhlcndpc2UgMC4KKyAgICAgKiBMZWZ0IGJ1dHRvbiBpcyAxLCBtaWRkbGUgYnV0dG9uIGlzIDIsIHJpZ2h0IGJ1dHRvbiBpcyAzLgorICAgICAqCisgICAgICogTWV0aG9kIGlzIGF3YXJlIG9mIHN5c3RlbSBtb3VzZSBidXR0b24gc3dhcCBmb3IgbGVmdC1oYW5kCisgICAgICogbW91c2UgYW5kIHJldHVybiBzd2FwcGVkIHZhbHVlcy4KKyAgICAgKiBAcmV0dXJuIG1vdXNlIGJ1dHRvbiBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1vdXNlQnV0dG9uKCkgeworICAgICAgICByZXR1cm4gbW91c2VCdXR0b247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aW1lIHdoZW4gdGhlIG1lc3NhZ2Ugd2FzIHJlY2VpdmVkCisgICAgICogQHJldHVybiB0aW1lIGluIG1pbGxpc2Vjb25kcworICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWUoKSB7CisgICAgICAgIHJldHVybiB0aW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvciB0aGUgZm9jdXMgZXZlbnQgY29udGFpbnMgdGhlIG9wb3NpdGUgd2luZG93LgorICAgICAqIFRoaXMgbWVhbnMgaXQgbG9zdCBmb2N1cyBpZiByZWNpcGllbnQgZ2FpbnMgaXQsCisgICAgICogb3Igd2lsbCBnYWluIGZvY3VzIGlmIHJlY2lwaWVudCBsb29zZXMgaXQuCisgICAgICogQHJldHVybiBIV05EIG9uIFdpbmRvd3MsIHh3aW5kbm93IG9uIFgKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRPdGhlcldpbmRvd0lkKCkgeworICAgICAgICByZXR1cm4gb3RoZXJXaW5kb3dJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSAiZGlydHkiIGFyZWEgb2YgdGhlIHdpbmRvdyBhcyBzZXQgb2Ygbm9uLWludGVyc2VjdGluZworICAgICAqIHJlY3RhbmdsZXMuIFRoaXMgYXJlYSBpcyB0byBiZSBwYWludGVkLgorICAgICAqIEByZXR1cm4gbm9uLWVtcHR5IGFycmF5IG9mIG51bGwgaWYgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTXVsdGlSZWN0QXJlYSBnZXRDbGlwUmVjdHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlICJkaXJ0eSIgYXJlYSBvZiB0aGUgd2luZG93IGFzIG9uZSByZWN0YW5nbGUuCisgICAgICogVGhpcyBhcmVhIGlzIHRvIGJlIHBhaW50ZWQuCisgICAgICogQHJldHVybiBub24tbnVsbCBSZWN0YW5nbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUmVjdGFuZ2xlIGdldENsaXBCb3VuZHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHdpbmRvdyBpbnNldHMuIEluc2V0cyBpcyBhcmVhIHdoaWNoIGJlbG9uZ3MgdG8KKyAgICAgKiB3aW5kb3cgc29tZWhvdyBidXQgaXMgb3V0c2lkZSBvZiBpdCdzIGNsaWVudCBhcmVhLAorICAgICAqIGl0IHVzdWFsbHkgY29udGFpbnMgc3lzdGVtIHByb3ZpZGVkIGJvcmRlciBhbmQgdGl0bGViYXIuCisgICAgICogQHJldHVybiBub24tbnVsbCBqYXZhLmF3dC5JbnNldHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW5zZXRzIGdldEluc2V0cygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGV2ZW50IGlzIHBvcHVwIG1lbnUgdHJpZ2dlci4KKyAgICAgKiBAcmV0dXJuIGJvb2xlYW4gZmxhZworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldFRyaWdnZXIoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiAiY2xpY2tzIiB0aGUgbW91c2Ugd2hlZWwgd2FzIHJvdGF0ZWQuCisgICAgICogQHJldHVybiBuZWdhdGl2ZSB2YWx1ZXMgaWYgdGhlIG1vdXNlIHdoZWVsIHdhcyByb3RhdGVkIHVwL2F3YXkgZnJvbSB0aGUgdXNlciwKKyAgICAgKiBhbmQgcG9zaXRpdmUgdmFsdWVzIGlmIHRoZSBtb3VzZSB3aGVlbCB3YXMgcm90YXRlZCBkb3duLyB0b3dhcmRzIHRoZSB1c2VyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRXaGVlbFJvdGF0aW9uKCkgeworICAgICAgICByZXR1cm4gd2hlZWxSb3RhdGlvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlRXZlbnRRdWV1ZS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUV2ZW50UXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzM4Y2QxCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUV2ZW50UXVldWUuamF2YQpAQCAtMCwwICsxLDExNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWtoYWlsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworCisKKy8qKgorICogRGVzY3JpYmVzIHRoZSBjcm9zcy1wbGF0Zm9ybSBuYXRpdmUgZXZlbnQgcXVldWUgaW50ZXJmYWNlCisgKgorICogPHAvPiBUaGUgaW1wbGVtZW50YXRpb24gY29uc3RydWN0b3Igc2hvdWxkIHJlbWVtYmVyIHRocmVhZCBpdCB3YXMKKyAqIGNyZWF0ZWQuIEFsbCBvdGhlciBtZXRob2RzIHdvdWxkIGJlIGNhbGxlZCBvYmx5IGZyb20gdGhpcyB0aHJlYWQsCisgKiBleGNlcHQgYXdha2UoKS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE5hdGl2ZUV2ZW50UXVldWUgeworICAgIAorICAgIHByaXZhdGUgU2h1dGRvd25XYXRjaGRvZyBzaHV0ZG93bldhdGNoZG9nOworICAgIHByaXZhdGUgY2xhc3MgRXZlbnRNb25pdG9yIHt9CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgZXZlbnRNb25pdG9yID0gbmV3IEV2ZW50TW9uaXRvcigpOworICAgIHByaXZhdGUgZmluYWwgTGlua2VkTGlzdDxOYXRpdmVFdmVudD4gZXZlbnRRdWV1ZSA9IG5ldyBMaW5rZWRMaXN0PE5hdGl2ZUV2ZW50PigpOworCisgICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBUYXNrIHsKKyAgICAgICAgcHVibGljIHZvbGF0aWxlIE9iamVjdCByZXR1cm5WYWx1ZTsKKworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwZXJmb3JtKCk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEJsb2NrcyBjdXJyZW50IHRocmVhZCB1bnRpbCBuYXRpdmUgZXZlbnQgcXVldWUgaXMgbm90IGVtcHR5CisgICAgICogb3IgYXdha2VuIGZyb20gb3RoZXIgdGhyZWFkIGJ5IGF3YWtlKCkuCisgICAgICoKKyAgICAgKiA8cC8+U2hvdWxkIGJlIGNhbGxlZCBvbmx5IG9uIHRyZWFkIHdoaWNoCisgICAgICogd2lsbCBwcm9jZXNzIG5hdGl2ZSBldmVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGlmIGV2ZW50IGxvb3Agc2hvdWxkIGJlIHN0b3BwZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiB3YWl0RXZlbnQoKTsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBvciBub3QgdGhlIG5hdGl2ZSBldmVudCBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKiBBbiBxdWV1ZSBpcyBlbXB0eSBpZiBpdCBjb250YWlucyBubyBtZXNzYWdlcyB3YWl0aW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBxdWV1ZSBpcyBlbXB0eTsgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkKGV2ZW50UXVldWUpIHsKKyAgICAgICAgICAgIHJldHVybiBldmVudFF1ZXVlLmlzRW1wdHkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBOYXRpdmVFdmVudCBnZXROZXh0RXZlbnQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoZXZlbnRRdWV1ZSkgeworICAgICAgICAgICAgaWYgKGV2ZW50UXVldWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgc2h1dGRvd25XYXRjaGRvZy5zZXROYXRpdmVRdWV1ZUVtcHR5KHRydWUpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGV2ZW50UXVldWUucmVtb3ZlKDApOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHByb3RlY3RlZCB2b2lkIGFkZEV2ZW50KE5hdGl2ZUV2ZW50IGV2ZW50KSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoZXZlbnRRdWV1ZSkgeworICAgICAgICAgICAgZXZlbnRRdWV1ZS5hZGQoZXZlbnQpOworICAgICAgICAgICAgc2h1dGRvd25XYXRjaGRvZy5zZXROYXRpdmVRdWV1ZUVtcHR5KGZhbHNlKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGV2ZW50TW9uaXRvcikgeworICAgICAgICAgICAgZXZlbnRNb25pdG9yLm5vdGlmeSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRFdmVudE1vbml0b3IoKSB7CisgICAgICAgIHJldHVybiBldmVudE1vbml0b3I7CisgICAgfQorCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYXdha2UoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgQVdUIHN5c3RlbSB3aW5kb3cgSUQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFXVCBzeXN0ZW0gd2luZG93IElECisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGxvbmcgZ2V0SmF2YVdpbmRvdygpOworCisgICAgLyoqCisgICAgICogQWRkIE5hdGl2ZUV2ZW50IHRvIHRoZSBxdWV1ZQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRpc3BhdGNoRXZlbnQoKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHBlcmZvcm1UYXNrKFRhc2sgdGFzayk7CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwZXJmb3JtTGF0ZXIoVGFzayB0YXNrKTsKKyAgICAKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTaHV0ZG93bldhdGNoZG9nKFNodXRkb3duV2F0Y2hkb2cgd2F0Y2hkb2cpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChldmVudFF1ZXVlKSB7CisgICAgICAgICAgICBzaHV0ZG93bldhdGNoZG9nID0gd2F0Y2hkb2c7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9OYXRpdmVFdmVudFRocmVhZC5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUV2ZW50VGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDUwYWRkNAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9OYXRpdmVFdmVudFRocmVhZC5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKKworLyoqCisgKiBOYXRpdmVFdmVudFRocmVhZAorICovCitwdWJsaWMgY2xhc3MgTmF0aXZlRXZlbnRUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgIAorICAgIHB1YmxpYyBpbnRlcmZhY2UgSW5pdCB7CisgICAgICAgIFdUSyBpbml0KCk7CisgICAgfQorICAgIAorICAgIE5hdGl2ZUV2ZW50UXVldWUgbmF0aXZlUXVldWU7CisgICAgSW5pdCBpbml0OworICAgIAorICAgIHByaXZhdGUgV1RLIHd0azsKKyAgICAKKyAgICBwdWJsaWMgTmF0aXZlRXZlbnRUaHJlYWQoKSB7CisgICAgICAgIHN1cGVyKCJBV1QtTmF0aXZlRXZlbnRUaHJlYWQiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBzZXREYWVtb24odHJ1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd3RrID0gaW5pdC5pbml0KCk7CisgICAgICAgICAgICAgICAgbmF0aXZlUXVldWUgPSB3dGsuZ2V0TmF0aXZlRXZlbnRRdWV1ZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcnVuTW9kYWxMb29wKCk7CisgICAgfQorCisgICAgdm9pZCBydW5Nb2RhbExvb3AoKSB7CisgICAgICAgIHdoaWxlIChuYXRpdmVRdWV1ZS53YWl0RXZlbnQoKSkgeworICAgICAgICAgICAgbmF0aXZlUXVldWUuZGlzcGF0Y2hFdmVudCgpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIHN0YXJ0KEluaXQgaW5pdCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHRoaXMuaW5pdCA9IGluaXQ7CisgICAgICAgICAgICBzdXBlci5zdGFydCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3YWl0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIFdUSyBnZXRXVEsoKSB7CisgICAgICAgIHJldHVybiB3dGs7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUlNLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlSU0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjI2ZjRhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL05hdGl2ZUlNLmphdmEKQEAgLTAsMCArMSwxMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKiogCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LkFXVEV2ZW50OworaW1wb3J0IGphdmEuYXd0LkFXVEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CitpbXBvcnQgamF2YS5hd3QuaW0uc3BpLklucHV0TWV0aG9kOworaW1wb3J0IGphdmEuYXd0LmltLnNwaS5JbnB1dE1ldGhvZENvbnRleHQ7CitpbXBvcnQgamF2YS5hd3QuaW0uc3BpLklucHV0TWV0aG9kRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmxhbmcuQ2hhcmFjdGVyLlN1YnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIEEgY3Jvc3MtcGxhdGZvcm0gaW50ZXJmYWNlIGZvciBuYXRpdmUgaW5wdXQKKyAqIG1ldGhvZCBzdWItc3lzdGVtIGZ1bmN0aW9uYWxpdHkuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBOYXRpdmVJTSBpbXBsZW1lbnRzIElucHV0TWV0aG9kLCBJbnB1dE1ldGhvZERlc2NyaXB0b3IgeworICAgIHByb3RlY3RlZCBJbnB1dE1ldGhvZENvbnRleHQgaW1jOworCisgICAgcHVibGljIHZvaWQgYWN0aXZhdGUoKSB7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkZWFjdGl2YXRlKGJvb2xlYW4gaXNUZW1wb3JhcnkpIHsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoRXZlbnQoQVdURXZlbnQgZXZlbnQpIHsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmRDb21wb3NpdGlvbigpIHsKKworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udHJvbE9iamVjdCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGhpZGVXaW5kb3dzKCkgeworCisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNDb21wb3NpdGlvbkVuYWJsZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBub3RpZnlDbGllbnRXaW5kb3dDaGFuZ2UoUmVjdGFuZ2xlIGJvdW5kcykgeworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjb252ZXJ0KCkgeworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlTm90aWZ5KCkgeworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3Vic2V0cyhTdWJzZXRbXSBzdWJzZXRzKSB7CisKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgc2V0Q29tcG9zaXRpb25FbmFibGVkKGJvb2xlYW4gZW5hYmxlKSB7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dE1ldGhvZENvbnRleHQoSW5wdXRNZXRob2RDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgaW1jID0gY29udGV4dDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIExvY2FsZVtdIGdldEF2YWlsYWJsZUxvY2FsZXMoKSB0aHJvd3MgQVdURXhjZXB0aW9uIHsKKyAgICAJcmV0dXJuIG5ldyBMb2NhbGVbXXtMb2NhbGUuZ2V0RGVmYXVsdCgpLCBMb2NhbGUuRU5HTElTSH07CisgICAgICAgIC8vcmV0dXJuIG5ldyBMb2NhbGVbXXtMb2NhbGUuZ2V0RGVmYXVsdCgpLCBMb2NhbGUuVVN9OworICAgIH0KKworICAgIHB1YmxpYyBJbnB1dE1ldGhvZCBjcmVhdGVJbnB1dE1ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geyAgICAgICAgCisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRNZXRob2REaXNwbGF5TmFtZShMb2NhbGUgaW5wdXRMb2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY2FsZSBkaXNwbGF5TGFuZ3VhZ2UpIHsKKyAgICAgICAgcmV0dXJuICJTeXN0ZW0gaW5wdXQgbWV0aG9kcyI7IC8vJE5PTi1OTFMtMSQKKyAgICB9CisKKyAgICBwdWJsaWMgSW1hZ2UgZ2V0SW5wdXRNZXRob2RJY29uKExvY2FsZSBpbnB1dExvY2FsZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEeW5hbWljTG9jYWxlTGlzdCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNhYmxlSU1FKCk7CisgICAgCisvLyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNhYmxlSU1FKGxvbmcgaWQpOworCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlTW91c2VJbmZvLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlTW91c2VJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY5Njk3NQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9OYXRpdmVNb3VzZUluZm8uamF2YQpAQCAtMCwwICsxLDQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LlBvaW50OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgcHJvdmlkZXMgYWNjZXNzIHRvIHBsYXRmb3JtIGRlcGVuZGVudCBmdW5jdGlvbmFsaXR5CisgKiBmb3IgY2xhc3NlcyBqYXZhLmF3dC5Qb2ludGVySW5mbyAmIGphdmEuYXd0Lk1vdXNlSW5mby4KKyAqLworcHVibGljIGludGVyZmFjZSBOYXRpdmVNb3VzZUluZm8geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgUG9pbnQgdGhhdCByZXByZXNlbnRzCisgICAgICogdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBwb2ludGVyIG9uIHRoZSBzY3JlZW4uCisgICAgICovCisgICAgUG9pbnQgZ2V0TG9jYXRpb24oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBidXR0b25zIG9uIHRoZSBtb3VzZS4KKyAgICAgKiBJZiBubyBtb3VzZSBpcyBpbnN0YWxsZWQgcmV0dXJucyAtMS4KKyAgICAgKi8KKyAgICBpbnQgZ2V0TnVtYmVyT2ZCdXR0b25zKCk7Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlUm9ib3QuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9OYXRpdmVSb2JvdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiMzU0ZDAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlUm9ib3QuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIERtaXRyeSBBLiBEdXJuZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LkNvbG9yOworaW1wb3J0IGphdmEuYXd0LlJlY3RhbmdsZTsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworCisvKioKKyAqIEEgY3Jvc3MtcGxhdGZvcm0gaW50ZXJmYWNlIGZvciBqYXZhLmF3dC5Sb2JvdCBpbXBsZW1lbnRhdGlvbgorICovCitwdWJsaWMgaW50ZXJmYWNlIE5hdGl2ZVJvYm90IHsKKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5hd3QuUm9ib3QjY3JlYXRlU2NyZWVuQ2FwdHVyZShSZWN0YW5nbGUpCisgICAgICogQHBhcmFtIHNjcmVlblJlY3QgcmVjdGFuZ2xlIHRvIGNhcHR1cmUgaW4gc2NyZWVuIGNvb3JkaW5hdGVzCisgICAgICogQHJldHVybiB0aGUgY2FwdHVyZWQgaW1hZ2Ugb3IgbnVsbCBpZgorICAgICAqIGNhcHR1cmUgZmFpbGVkLgorICAgICAqLworICAgIEJ1ZmZlcmVkSW1hZ2UgY3JlYXRlU2NyZWVuQ2FwdHVyZShSZWN0YW5nbGUgc2NyZWVuUmVjdCk7CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuYXd0LlJvYm90I2dldFBpeGVsQ29sb3IoaW50LCBpbnQpCisgICAgICovCisgICAgQ29sb3IgZ2V0UGl4ZWwoaW50IHgsIGludCB5KTsKKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlIGEgbmF0aXZlIHN5c3RlbSBrZXlib2FyZCBpbnB1dCBldmVudC4KKyAgICAgKiBAcGFyYW0ga2V5Y29kZSBBIEphdmEgdmlydHVhbCBrZXkgY29kZQorICAgICAqIEBwYXJhbSBwcmVzcyBBIGtleSBpcyBwcmVzc2VkIGlmIHRydWUsIHJlbGVhc2VkIG90aGVyd2lzZQorICAgICAqIEBzZWUgamF2YS5hd3QuUm9ib3Qja2V5UHJlc3MoaW50KQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGtleWNvZGUgaXMgaW52YWxpZCBpbiB0aGUgbmF0aXZlIHN5c3RlbQorICAgICAqLworICAgIHZvaWQga2V5RXZlbnQoaW50IGtleWNvZGUsIGJvb2xlYW4gcHJlc3MpOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGUgYSBuYXRpdmUgc3lzdGVtIG1vdXNlIGJ1dHRvbihzKSBwcmVzcyBvciByZWxlYXNlIGV2ZW50LgorICAgICAqIEBwYXJhbSBidXR0b25zIEEgbWFzayBvZiBKYXZhIG1vdXNlIGJ1dHRvbiBmbGFncworICAgICAqIEBwYXJhbSBwcmVzcyBidXR0b25zIGFyZSBwcmVzc2VkIGlmIHRydWUsIHJlbGVhc2VkIG90aGVyd2lzZQorICAgICAqIEBzZWUgamF2YS5hd3QuUm9ib3QjbW91c2VQcmVzcyhpbnQpCisgICAgICovCisgICAgdm9pZCBtb3VzZUJ1dHRvbihpbnQgYnV0dG9ucywgYm9vbGVhbiBwcmVzcyk7CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSBhIG5hdGl2ZSBzeXN0ZW0gbW91c2UgbW90aW9uIGV2ZW50LgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmF3dC5Sb2JvdCNtb3VzZU1vdmUoaW50LCBpbnQpCisgICAgICovCisgICAgdm9pZCBtb3VzZU1vdmUoaW50IHgsIGludCB5KTsKKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlIGEgbmF0aXZlIHN5c3RlbSBtb3VzZSB3aGVlbCBldmVudC4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5hd3QuUm9ib3QjbW91c2VXaGVlbChpbnQpCisgICAgICovCisgICAgdm9pZCBtb3VzZVdoZWVsKGludCB3aGVlbEFtdCk7Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlV2luZG93LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvTmF0aXZlV2luZG93LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzNmZDZjMAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9OYXRpdmVXaW5kb3cuamF2YQpAQCAtMCwwICsxLDIyMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBNaWtoYWlsIERhbmlsb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LkltYWdlOworaW1wb3J0IGphdmEuYXd0Lkluc2V0czsKK2ltcG9ydCBqYXZhLmF3dC5Qb2ludDsKK2ltcG9ydCBqYXZhLmF3dC5SZWN0YW5nbGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLk11bHRpUmVjdEFyZWE7CisKKworLyoqCisgKiBQcm92aWRlcyBjcm9zcy1wbGF0Zm9ybSB3YXkgdG8gbWFuaXB1bGF0ZSBuYXRpdmUgd2luZG93LgorICoKKyAqIFJlc3VsdHMgb2YgbWV0aG9kcyBhcmUgcmVwb3J0ZWQgdGhyb3VnaCBuYXRpdmUgbWVzc2FnZXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTmF0aXZlV2luZG93IHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHN5c3RlbSBpZCBvZiB0aGUgYXNzb2NpYXRlZCB3aW5kb3cKKyAgICAgKiBAcmV0dXJuIEhXTkQgb24gV2luZG93cywgeHdpbmRvdyBvbiBYCisgICAgICovCisgICAgbG9uZyBnZXRJZCgpOworCisgICAgLyoqCisgICAgICogU2hvd3MvaGlkZXMgd2luZG93CisgICAgICogQHBhcmFtIHYgLSBuZXcgdmlzaWJpbGl0eQorICAgICAqLworICAgIHZvaWQgc2V0VmlzaWJsZShib29sZWFuIHYpOworCisgICAgLyoqCisgICAgICogTWVhbnMgb25seSBzaXplIHNob3VsZCBiZSBjaGFuZ2VkCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBCT1VORFNfTk9NT1ZFID0gMTsKKworICAgIC8qKgorICAgICAqIE1lYW5zIG9ubHkgcG9zaXRpb24gc2hvdWxkIGJlIGNoYW5nZWQKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IEJPVU5EU19OT1NJWkUgPSAyOworCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gc2V0IGRlc2lyZWQgd2luZG93IGJvdW5kcy4gSXQncyBub3QgZ3VyYW50aWVkIHRoZQorICAgICAqIHByb3BlcnR5IHdpbGwgaGF2ZSB0aGUgZGVzaXJlZCB2YWx1ZS4gVGhlIHZhbHVlIGNoYW5nZQorICAgICAqIHNob3VsZCBiZSByZXBvcnRlZCBieSBzeXN0ZW0gZXZlbnQgKGFzIGZvciBvdGhlciBwcm9wZXJ0aWVzKS4KKyAgICAgKgorICAgICAqIDxwLz4gIElmIGNoaWxkLCBwb3NpdGlvbiBpcyByZWxhdGl2ZSB0byBwYXJlbnQgd2luZG93LgorICAgICAqIEBwYXJhbSB4IC0gZGVzaXJlZCB4CisgICAgICogQHBhcmFtIHkgLSBkZXNpcmVkIHkKKyAgICAgKiBAcGFyYW0gdyAtIGRlc2lyZWQgd2lkdGgKKyAgICAgKiBAcGFyYW0gaCAtIGRlc2lyZWQgaGVpZ2h0CisgICAgICogQHBhcmFtIGJvdW5kc01hc2sgLSBiaXR3aXNlIE9SIG9mIEJPVU5EU18qIGNvbnN0YW50cy4KKyAgICAgKiBHb3Zlcm5zIHRoZSBuZXcgYm91bmRzIGludGVycHJldGF0aW9uLgorICAgICAqLworICAgIHZvaWQgc2V0Qm91bmRzKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoLCBpbnQgYm91bmRzTWFzayk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGxhc3Qgbm90aWZpZWQgd2luZG93IGJvdW5kcy4gVGhpcyBtZWFucyB0aGUgbGFzdCBib3VuZHMKKyAgICAgKiByZXBvcnRlZCBieSBzeXN0ZW0gZXZlbnQuCisgICAgICoKKyAgICAgKiA8cC8+ICBJZiBjaGlsZCwgcG9zaXRpb24gaXMgcmVsYXRpdmUgdG8gcGFyZW50IHdpbmRvdy4KKyAgICAgKiBAcmV0dXJuIGxhc3Qgbm90aWZpZWQgd2luZG93IGJvdW5kcworICAgICAqLworICAgIFJlY3RhbmdsZSBnZXRCb3VuZHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgbGFzdCBub3RpZmllZCBpbnNldHMuIFRoaXMgbWVhbnMgdGhlIGxhc3QgaW5zZXRzCisgICAgICogcmVwb3J0ZWQgYnkgc3lzdGVtIGV2ZW50LiBJbnNldHMgYXJlIG1hcmdpbnMgYXJvdW5kIGNsaWVudCBhcmVhCisgICAgICogb2N1cGllZCBieSBzeXN0ZW0gcHJvdmlkZWQgZGVjb3IsIHVzdXNhbGx5IGJvcmRlciBhbmQgdGl0bGViYXIuCisgICAgICogQHJldHVybiBsYXN0IG5vdGlmaWVkIGluc2V0cworICAgICAqLworICAgIEluc2V0cyBnZXRJbnNldHMoKTsKKworICAgIC8qKgorICAgICAqIEVuYWJsZXMvZGlzYWJsZXMgcHJvY2Vzc2luZyBvZiBpbnB1dCAoa2V5LCBtb3VzZSkgZXZlbnQKKyAgICAgKiBieSB3aW5kb3cuIElmIGRpc2FibGVkIGlucHV0IGV2ZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgLSBpZiBlbmFibGVkCisgICAgICovCisgICAgdm9pZCBzZXRFbmFibGVkKGJvb2xlYW4gdmFsdWUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgImZvY3VzYWJsZSIgd2luZG93IHN0YXRlLgorICAgICAqIEBwYXJhbSB2YWx1ZSAtIGlmIHRydWUgbWFrZXMgd2luZG93IGZvY3VzYWJsZQorICAgICAqLworICAgIHZvaWQgc2V0Rm9jdXNhYmxlKGJvb2xlYW4gdmFsdWUpOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGN1cnJlbnQgZm9jdXNhYmxlIHdpbmRvdyBzdGF0ZQorICAgICAqLworICAgIGJvb2xlYW4gaXNGb2N1c2FibGUoKTsKKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIHNldCBhcHBsaWNhdGlvbiBpbnB1dCBmb2N1cyB0byB0aGUgd2luZG93IG9yIGNsZWFyCisgICAgICogY3VycmVudCBmb2N1cyBmcm9tIGZvY3VzZWQgd2luZG93LgorICAgICAqCisgICAgICogPHAvPiBGb3IgdG9wbGV2ZWwgd2luZG93cyBpdCdzIG5vdCBndXJhbnRpZWQgZm9jdXMgd2lsbCBsYW5kIGluCisgICAgICogZGVzaXJlZCB3aW5kb3cgZXZlbiBpZiBmdW5jdGlvbiByZXR1cm5zIHRydWUuIEZvY3VzIHRyYXZlcnNhbCBzaG91bGQgYmUgdHJhY2tlZAorICAgICAqIGJ5IHByb2Nlc3Npbmcgc3lzdGVtIGV2ZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2N1cyAgLSBpZiB0cnVlIHNldHMgZm9jdXMsIGVsc2UgY2xlYXJzIGZvY3VzCisgICAgICogQHJldHVybiBpZiBzdWNjZXNzCisgICAgICovCisgICAgYm9vbGVhbiBzZXRGb2N1cyhib29sZWFuIGZvY3VzKTsKKworICAgIC8qKgorICAgICAqIERlc3Ryb3lzIHRoZSBhc3Njb2lhdGVkIHdpbmRvdy4KKyAgICAgKiBBdHRlbXB0cyB0byB1c2UgaXQgdGhlcmVhZnRlciBjYW4gcmVzdWx0IGluCisgICAgICogdW5wcmVkaWN0YWJsZSBiZWNoYXZpb3IuCisgICAgICovCisgICAgdm9pZCBkaXNwb3NlKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2VzIHdpbmRvdyBaLW9yZGVyIHRvIHBsYWNlIHRoaXMgd2luZG93IHVuZGVyLCBJZiB3IGlzIG51bGwKKyAgICAgKiBwbGFjZXMgcGxhY2VzIHRoaXMgd2luZG93IG9uIHRoZSB0b3AuIFotb3JkZXIgaXMgcGVyIHBhcmVudC4KKyAgICAgKiBUb3BsZXZlbHMgYSBjaGlsZHJlbiBvZiBkZXNrdG9wIGluIHRlcm1zIG9mIFotb3JkZXIuCisgICAgICogQHBhcmFtIHcgLSB3aW5kb3cgdG8gcGxhY2UgdW5kZXIuCisgICAgICovCisgICAgdm9pZCBwbGFjZUFmdGVyKE5hdGl2ZVdpbmRvdyB3KTsKKworICAgIC8qKgorICAgICAqIFBsYWNlcyB3aW5kb3cgb24gdG9wIG9mIFotb3JkZXIKKyAgICAgKi8KKyAgICB2b2lkIHRvRnJvbnQoKTsKKworICAgIC8qKgorICAgICAqIFBsYWNlcyB3aW5kb3cgb24gYm90dG9tIG9mIFotb3JkZXIKKyAgICAgKi8KKyAgICB2b2lkIHRvQmFjaygpOworCisgICAgLyoqCisgICAgICogTWFrZXMgdGhlIHdpbmRvdyByZXNpemFibGUvbm90IHJlc2l6YWJsZSBieSB1c2VyCisgICAgICogQHBhcmFtIHZhbHVlIC0gaWYgcmVzaXphYmxlCisgICAgICovCisgICAgdm9pZCBzZXRSZXNpemFibGUoYm9vbGVhbiB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB3aW5kb3cgY2FwdGlvbgorICAgICAqIEBwYXJhbSB0aXRsZSAtIGNhcHRpb24gdGV4dAorICAgICAqLworICAgIHZvaWQgc2V0VGl0bGUoU3RyaW5nIHRpdGxlKTsKKworICAgIC8qKgorICAgICAqIEFjdGl2YXRlIHRoZSBtb3VzZSBldmVudCBjYXB0dXJpbmcKKyAgICAgKi8KKyAgICB2b2lkIGdyYWJNb3VzZSgpOworCisgICAgLyoqCisgICAgICogRGVhY3RpdmF0ZSBtb3VzZSBldmVudCBjYXB0dXJpbmcKKyAgICAgKi8KKyAgICB2b2lkIHVuZ3JhYk1vdXNlKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgZXh0ZW5kZWQgc3RhdGUgZm9yIHRvcC1sZXZlbCB3aW5kb3cuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhdGUgLSBuZXcgc3RhdGUsIGJpdG1hc2sgb2YgSUNPTklGSUVELCBNQVhJTUlaRURfQk9USCwgZXRjLgorICAgICAqLworICAgIHZvaWQgc2V0U3RhdGUoaW50IHN0YXRlKTsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgaW1hZ2UgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBtaW5pbWl6ZWQgaWNvbiBmb3IKKyAgICAgKiB0b3AtbGV2ZWwgW2RlY29yYXRlZF0gd2luZG93LgorICAgICAqIEBwYXJhbSBpbWFnZSB0aGUgaWNvbiBpbWFnZSB0byBiZSBkaXNwbGF5ZWQKKyAgICAgKi8KKyAgICB2b2lkIHNldEljb25JbWFnZShJbWFnZSBpbWFnZSk7CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyB3aW5kb3cgdG9wLW1vc3QgaWYgdmFsdWUgaXMgdHJ1ZSwKKyAgICAgKiBub24tdG9wbW9zdChub3JtYWwpIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICB2b2lkIHNldEFsd2F5c09uVG9wKGJvb2xlYW4gdmFsdWUpOworCisgICAgLyoqCisgICAgICogU2V0IGRlc2lyZWQgW3RvcC1sZXZlbF0gd2luZG93IGJvdW5kcyB3aGVuIGJlaW5nIGluIG1heGltaXplZCBzdGF0ZS4KKyAgICAgKiBGaWVsZHMgc2V0IHRvIEludGVnZXIuTUFYX1ZBTFVFIGFyZSBpZ25vcmVkW3N5c3RlbS1zdXBwbGllZCB2YWx1ZXMgYXJlCisgICAgICogdXNlZCBpbnN0ZWFkXQorICAgICAqLworICAgIHZvaWQgc2V0TWF4aW1pemVkQm91bmRzKFJlY3RhbmdsZSBib3VuZHMpOworCisgICAgLyoqCisgICAgICogR2V0IGFic29sdXRlIHBvc2l0aW9uIG9uIHRoZSBzY3JlZW4KKyAgICAgKi8KKyAgICBQb2ludCBnZXRTY3JlZW5Qb3MoKTsKKworICAgIC8qKgorICAgICAqIFNldCBhIHdpbmRvdyAicGFja2VkIiBmbGFnOgorICAgICAqIHRoZSBmbGFnIGluZGljYXRlcyB0aGF0IGlmIGluc2V0cyBjaGFuZ2UKKyAgICAgKiBjbGllbnQgYXJlYSBzaG91bGRuJ3QgYmUgcmVzaXplZCwgYnV0IGZyYW1lCisgICAgICogbXVzdCBiZSByZXNpemVkIGluc3RlYWQKKyAgICAgKi8KKyAgICB2b2lkIHNldFBhY2tlZChib29sZWFuIHBhY2tlZCk7CisgICAgCisgICAgLyoqCisgICAgICogTWFrZSB3aW5kb3cgYW4gImlucHV0IG1ldGhvZCB3aW5kb3ciIGJ5IHNldHRpbmcKKyAgICAgKiBzcGVjaWFsIHdpbmRvdyBzdHlsZSwgZS4gZy4gc21hbGwgdGl0bGUgYmFyLCBubworICAgICAqIGNsb3NlLCBtaW5pbWl6ZS9tYXhpbWl6ZSBidXR0b25zLiBGb3IgaW50ZXJuYWwKKyAgICAgKiB1c2UgYnkgaW5wdXQgbWV0aG9kIGZyYW1ld29yay4KKyAgICAgKgorICAgICAqLworICAgIHZvaWQgc2V0SU1TdHlsZSgpOworCisgICAgTXVsdGlSZWN0QXJlYSBnZXRPYnNjdXJlZFJlZ2lvbihSZWN0YW5nbGUgcGFydCk7Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvU2h1dGRvd25UaHJlYWQuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9TaHV0ZG93blRocmVhZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwMWViNDYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvU2h1dGRvd25UaHJlYWQuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pY2hhZWwgRGFuaWxvdiwgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmludGVybmFsLm5scy5NZXNzYWdlczsKKworcHVibGljIGZpbmFsIGNsYXNzIFNodXRkb3duVGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFdhdGNoZG9nIHsKKyAgICB9CisKKyAgICBwdWJsaWMgU2h1dGRvd25UaHJlYWQoKSB7CisgICAgICAgIHNldE5hbWUoIkFXVC1TaHV0ZG93biIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIHNldERhZW1vbihmYWxzZSk7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgYm9vbGVhbiBzaG91bGRTdG9wID0gZmFsc2U7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgbm90aWZ5QWxsKCk7IC8vIHN5bmNocm9uaXplIHRoZSBzdGFydHVwCisKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd2FpdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkU3RvcCkgeworICAgICAgICAgICAgICAgICAgICBub3RpZnlBbGwoKTsgLy8gc3luY2hyb25pemUgdGhlIHNodXRkb3duCisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzdGFydCgpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBzdXBlci5zdGFydCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3YWl0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjI2PVNodXRkb3duIHRocmVhZCB3YXMgaW50ZXJydXB0ZWQgd2hpbGUgc3RhcnRpbmcKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI2IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBzaG91bGRTdG9wID0gdHJ1ZTsKKyAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3YWl0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjI3PVNodXRkb3duIHRocmVhZCB3YXMgaW50ZXJydXB0ZWQgd2hpbGUgc3RvcHBpbmcKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI3IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvU2h1dGRvd25XYXRjaGRvZy5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL1NodXRkb3duV2F0Y2hkb2cuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZWZhNTE5Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL1NodXRkb3duV2F0Y2hkb2cuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqIAorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworLyoqCisgKiBTaHV0ZG93biBXYXRjaGRvZworICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2h1dGRvd25XYXRjaGRvZyB7CisgICAgCisgICAgcHJpdmF0ZSBib29sZWFuIG5hdGl2ZVF1ZXVlRW1wdHkgPSB0cnVlOworICAgIHByaXZhdGUgYm9vbGVhbiBhd3RRdWV1ZUVtcHR5ID0gdHJ1ZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gd2luZG93TGlzdEVtcHR5ID0gdHJ1ZTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBmb3JjZWRTaHV0ZG93biA9IGZhbHNlOworICAgIAorICAgIHByaXZhdGUgU2h1dGRvd25UaHJlYWQgdGhyZWFkOworCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldE5hdGl2ZVF1ZXVlRW1wdHkoYm9vbGVhbiBlbXB0eSkgeworICAgICAgICBuYXRpdmVRdWV1ZUVtcHR5ID0gZW1wdHk7CisgICAgICAgIGNoZWNrU2h1dGRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0QXd0UXVldWVFbXB0eShib29sZWFuIGVtcHR5KSB7CisgICAgICAgIGF3dFF1ZXVlRW1wdHkgPSBlbXB0eTsKKyAgICAgICAgY2hlY2tTaHV0ZG93bigpOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRXaW5kb3dMaXN0RW1wdHkoYm9vbGVhbiBlbXB0eSkgeworICAgICAgICB3aW5kb3dMaXN0RW1wdHkgPSBlbXB0eTsKKyAgICAgICAgY2hlY2tTaHV0ZG93bigpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZm9yY2VTaHV0ZG93bigpIHsKKyAgICAgICAgZm9yY2VkU2h1dGRvd24gPSB0cnVlOworICAgICAgICBzaHV0ZG93bigpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3RhcnQoKSB7CisgICAgICAgIGtlZXBBbGl2ZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1NodXRkb3duKCkgeworICAgICAgICBpZiAoY2FuU2h1dGRvd24oKSkgeworICAgICAgICAgICAgc2h1dGRvd24oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGtlZXBBbGl2ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNhblNodXRkb3duKCkgeworICAgICAgICByZXR1cm4gKG5hdGl2ZVF1ZXVlRW1wdHkgJiYgYXd0UXVldWVFbXB0eSAmJiB3aW5kb3dMaXN0RW1wdHkpIHx8CisgICAgICAgICAgICAgICAgZm9yY2VkU2h1dGRvd247CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGtlZXBBbGl2ZSgpIHsKKyAgICAgICAgaWYgKHRocmVhZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJlYWQgPSBuZXcgU2h1dGRvd25UaHJlYWQoKTsKKyAgICAgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNodXRkb3duKCkgeworICAgICAgICBpZiAodGhyZWFkICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocmVhZC5zaHV0ZG93bigpOworICAgICAgICAgICAgdGhyZWFkID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9TeW5jaHJvbml6ZXIuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9TeW5jaHJvbml6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWVhYTBiCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL1N5bmNocm9uaXplci5qYXZhCkBAIC0wLDAgKzEsMjAwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIE1pa2hhaWwgRGFuaWxvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrOworCitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuaW50ZXJuYWwubmxzLk1lc3NhZ2VzOworCisvKioKKyAqIENsYXNzIHN5bmNocm9uaXplciBpcyB0byBwcm90ZWN0IEFXVCBzdGF0ZSBpbnRlZ3JpdHkgaW4gbXVsdGl0aHJlYWRpbmcgZW52aXJvbm1lbnQuCisgKiBJdCBpcyBzdXBwb3NlZCB0byBoYXZlIGEgY2hpbGQgY2xhc3MgcGVyIG5hdGl2ZSBwbGF0Zm9ybS4KKyAqIFRoZSBvbmx5IGluc3RhbmNlIGlzIGNyZWF0ZWQgb24gdGhlIGZpcnN0IHVzZSBvZiBvbmUgb2YgdGhlIGNvcmUgQVdUIGNsYXNzZXMuCisgKiBSZWdpc3RlcnMgV1RLIG9uIHRoZSBkaXNwYXRjaCB0aHJlYWQgc3RhcnR1cC4KKyAqIEl0IGlzIGp1c3QgYSBzcGVjaWFsIGtpbmQgb2YgbXV0ZXguCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBTeW5jaHJvbml6ZXIgeworICAgIC8vVE9ETzogdGhpbmsgYWJvdXQgamF2YS51dGlsLmNvbmN1cnJlbnQgdXNlIGZvciBmYXN0ZXIgYmxvY2tpbmcvYXdha2luZyBvcGVyYXRpb25zCisgICAgLy9UT0RPOiB0aGluayBhYm91dCBhbGwgc3luY2hyb25pemVkIG1ldGhvZHMuIElzIHRoZXJlIG5lZWQgdG8gc3luY2hyb25pemUgZXZlcnl0aGluZz8KKworICAgIC8qKgorICAgICAqIFRoaXMgZmllbGQgaG9sZHMgdGhlIGNvdW50ZXIgb2YgbG9jayBvcGVyYXRpb24uCisgICAgICogVG8gZnJlZSBzeW5jaHJvbml6ZXIgdW5sb2NrIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCAkYWNxdWVzdENvdW50ZXIgdGltZXMuCisgICAgICogRXF1YWxzIHRvIDAgd2hlbiBzeW5jaHJvbml6ZXIgaXMgZnJlZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGFjcXVlc3RDb3VudGVyOworCisgICAgLyoqCisgICAgICogVGhpcyBmaWVsZCBob2xkcyB0aGUgb3duZXIgb2Ygc3luY2hyb25pemVyLgorICAgICAqIE93bmVyIG9mIHN5bmNocm9uaXplciBpcyBhIGxhc3QgdGhyZWFkIHRoYXQgc3VjY2Vzc2Z1bGx5IGxvY2tlZCBzeW5jaHJvbml6ZXIgYW5kCisgICAgICogc3RpbGwgaGF2bid0IGZyZWVkIGl0LiBFcXVhbHMgdG8gbnVsbCB3aGVuIHN5bmNocm9uaXplciBpcyBmcmVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBUaHJlYWQgb3duZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZpZWxkIGhvbGRzIHRoZSB3YWl0IHF1ZXVlLgorICAgICAqIFdhaXQgcXVldWUgaXMgYSBxdWV1ZSB3aGVyZSB0aHJlYWQgd2FpdCBmb3Igc3luY2hyb25pemVyIGFjY2Vzcy4KKyAgICAgKiBFbXB0eSB3aGVuIHN5bmNocm9uaXplciBpcyBmcmVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBMaW5rZWRMaXN0PFRocmVhZD4gd2FpdFF1ZXVlID0gbmV3IExpbmtlZExpc3Q8VGhyZWFkPigpOworCisgICAgLyoqCisgICAgICogVGhlIGV2ZW50IGRpc3BhdGNoIHRocmVhZAorICAgICAqLworICAgIHByb3RlY3RlZCBUaHJlYWQgZGlzcGF0Y2hUaHJlYWQ7CisKKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxUaHJlYWQsIEludGVnZXI+IHN0b3JlZFN0YXRlcyA9IG5ldyBIYXNodGFibGU8VGhyZWFkLCBJbnRlZ2VyPigpOworCisgICAgLyoqCisgICAgICogQWNxdWlyZSB0aGUgbG9jayBmb3IgdGhpcyBzeW5jaHJvbml6ZXIuIE5lc3RlZCBsb2NrIGlzIHN1cHBvcnRlZC4KKyAgICAgKiBJZiB0aGUgbXV0ZXggaXMgYWxyZWFkeSBsb2NrZWQgYnkgYW5vdGhlciB0aHJlYWQsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIGJlIHB1dAorICAgICAqIGludG8gd2FpdCBxdWV1ZSB1bnRpbCB0aGUgbG9jayBiZWNvbWVzIGF2YWlsYWJsZS4KKyAgICAgKiBBbGwgdXNlciB0aHJlYWRzIGFyZSBzZXJ2ZWQgaW4gRklGTyBvcmRlci4gRGlzcGF0Y2ggdGhyZWFkIGhhcyBoaWdoZXIgcHJpb3JpdHkuCisgICAgICogU3VwcG9zZWQgdG8gYmUgdXNlZCBpbiBUb29sa2l0LmxvY2tBV1QoKSBvbmx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvY2soKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgVGhyZWFkIGN1clRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisKKyAgICAgICAgICAgIGlmIChhY3F1ZXN0Q291bnRlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgYWNxdWVzdENvdW50ZXIgPSAxOworICAgICAgICAgICAgICAgIG93bmVyID0gY3VyVGhyZWFkOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAob3duZXIgPT0gY3VyVGhyZWFkKSB7CisgICAgICAgICAgICAgICAgICAgIGFjcXVlc3RDb3VudGVyKys7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1clRocmVhZCA9PSBkaXNwYXRjaFRocmVhZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgd2FpdFF1ZXVlLmFkZEZpcnN0KGN1clRocmVhZCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3YWl0UXVldWUuYWRkTGFzdChjdXJUaHJlYWQpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3YWl0KCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvd25lciAhPSBjdXJUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YWl0UXVldWUucmVtb3ZlKGN1clRocmVhZCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXd0LjFGPVdhaXRpbmcgZm9yIHJlc291cmNlIGFjY2VzcyB0aHJlYWQgaW50ZXJydXB0ZWQgbm90IGZyb20gdW5sb2NrIG1ldGhvZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihNZXNzYWdlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFN0cmluZygiYXd0LjFGIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlIHRoZSBsb2NrIGZvciB0aGlzIHN5bmNocm9uaXplci4KKyAgICAgKiBJZiB3YWl0IHF1ZXVlIGlzIG5vdCBlbXB0eSB0aGUgZmlyc3Qgd2FpdGluZyB0aHJlYWQgYWNxdWlyZXMgdGhlIGxvY2suCisgICAgICogU3VwcG9zZWQgdG8gYmUgdXNlZCBpbiBUb29sa2l0LnVubG9ja0FXVCgpIG9ubHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5sb2NrKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChhY3F1ZXN0Q291bnRlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gYXd0LjIwPUNhbid0IHVubG9jayBub3QgbG9ja2VkIHJlc291cmNlLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIwIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob3duZXIgIT0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4yMT1Ob3Qgb3duZXIgY2FuJ3QgdW5sb2NrIHJlc291cmNlLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjIxIikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFjcXVlc3RDb3VudGVyLS07CisgICAgICAgICAgICBpZiAoYWNxdWVzdENvdW50ZXIgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmICh3YWl0UXVldWUuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBhY3F1ZXN0Q291bnRlciA9IDE7CisgICAgICAgICAgICAgICAgICAgIG93bmVyID0gd2FpdFF1ZXVlLnJlbW92ZUZpcnN0KCk7CisgICAgICAgICAgICAgICAgICAgIG93bmVyLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG93bmVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgc3RhdGUgb2YgdGhpcyBzeW5jaHJvbml6ZXIgYW5kIGZyZWVzIGl0LgorICAgICAqIFN1cHBvc2VkIHRvIGJlIHVzZWQgaW4gVG9vbGtpdC51bnNhZmVJbnZva2VBbmRXYWl0VW5kZXJBV1RMb2NrKCkgb25seSBpbiBwYWlyIHdpdGgKKyAgICAgKiBsb2NrQW5kUmVzdG9yZVN0YXRlKCkuCisgICAgICogRG8gbm90IGNhbGwgaXQgZGlyZWN0bHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RvcmVTdGF0ZUFuZEZyZWUoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgVGhyZWFkIGN1clRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisKKyAgICAgICAgICAgIGlmIChvd25lciAhPSBjdXJUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjI9Tm90IG93bmVyIGNhbid0IGZyZWUgcmVzb3VyY2UuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjIiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdG9yZWRTdGF0ZXMuY29udGFpbnNLZXkoY3VyVGhyZWFkKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4yMz1PbmUgdGhyZWFkIGNhbid0IHN0b3JlIHN0YXRlIHNldmVyYWwgdGltZXMgaW4gYSByb3cuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJhd3QuMjMiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RvcmVkU3RhdGVzLnB1dChjdXJUaHJlYWQsIG5ldyBJbnRlZ2VyKGFjcXVlc3RDb3VudGVyKSk7CisgICAgICAgICAgICBhY3F1ZXN0Q291bnRlciA9IDE7CisgICAgICAgICAgICB1bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvY2tzIHRoaXMgc3luY2hyb25pemVyIGFuZCByZXN0b3JlcyBpdCdzIHN0YXRlLgorICAgICAqIFN1cHBvc2VkIHRvIGJlIHVzZWQgaW4gVG9vbGtpdC51bnNhZmVJbnZva2VBbmRXYWl0VW5kZXJBV1RMb2NrKCkgb25seSBpbiBwYWlyIHdpdGgKKyAgICAgKiBzdG9yZVN0YXRlQW5kRnJlZSgpLgorICAgICAqIERvIG5vdCBjYWxsIGl0IGRpcmVjdGx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvY2tBbmRSZXN0b3JlU3RhdGUoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgVGhyZWFkIGN1clRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisKKyAgICAgICAgICAgIGlmIChvd25lciA9PSBjdXJUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICAvLyBhd3QuMjQ9T3duZXIgY2FuJ3Qgb3ZlcndyaXRlIHJlc291cmNlIHN0YXRlLiBMb2NrIG9wZXJhdGlvbnMgbWF5IGJlIGxvc3QuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlcy5nZXRTdHJpbmcoImF3dC4yNCIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFzdG9yZWRTdGF0ZXMuY29udGFpbnNLZXkoY3VyVGhyZWFkKSkgeworICAgICAgICAgICAgICAgIC8vIGF3dC4yNT1ObyBzdGF0ZSBzdG9yZWQgZm9yIGN1cnJlbnQgdGhyZWFkLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiYXd0LjI1IikpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGxvY2soKTsKKyAgICAgICAgICAgIGFjcXVlc3RDb3VudGVyID0gc3RvcmVkU3RhdGVzLmdldChjdXJUaHJlYWQpLmludFZhbHVlKCk7CisgICAgICAgICAgICBzdG9yZWRTdGF0ZXMucmVtb3ZlKGN1clRocmVhZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHJlZmVyZW5jZXMgdG8gV1RLIGFuZCBldmVudCBkaXNwYXRjaCB0aHJlYWQuCisgICAgICogQ2FsbGVkIG9uIHRvb2xraXQgc3RhcnR1cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3dGsgLSByZWZlcmVuY2UgdG8gV1RLIGluc3RhbmNlCisgICAgICogQHBhcmFtIGRpc3BhdGNoVGhyZWFkIC0gcmVmZXJlbmNlIHRvIGV2ZW50IGRpc3BhdGNoIHRocmVhZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVudmlyb25tZW50KFdUSyB3dGssIFRocmVhZCBkaXNwYXRjaFRocmVhZCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hUaHJlYWQgPSBkaXNwYXRjaFRocmVhZDsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL1N5c3RlbVByb3BlcnRpZXMuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9TeXN0ZW1Qcm9wZXJ0aWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI1OWYwZQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9TeXN0ZW1Qcm9wZXJ0aWVzLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBQYXZlbCBEb2xnb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd0azsKKworaW1wb3J0IGphdmEuYXd0LkZvbnQ7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlOworaW1wb3J0IGphdmEuYXd0LmltLklucHV0TWV0aG9kSGlnaGxpZ2h0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogTmF0aXZlUHJvcGVydGllcworICovCisKK3B1YmxpYyBpbnRlcmZhY2UgU3lzdGVtUHJvcGVydGllcyB7CisKKyAgICAvKioKKyAgICAgKiBHZXQgY3VycmVudCB2YWx1ZSBvZiBhIHN5c3RlbSBjb2xvcgorICAgICAqIEBwYXJhbSBpbmRleCAtIG9uZSBvZiBqYXZhLmF3dC5TeXN0ZW1Db2xvciBjb25zdGFudHMKKyAgICAgKiBAcmV0dXJuIEFSR0IgdmFsdWUgb2YgcmVxdWVzdGVkIHN5c3RlbSBjb2xvcgorICAgICAqLworICAgIGludCBnZXRTeXN0ZW1Db2xvckFSR0IoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIEdldCBkZWZhdWx0IGZvbnQgZm9yIEdVSSBlbGVtZW50cyBzdWNoIGFzIG1lbnVzIGFuZCBidXR0b25zCisgICAgICogQHJldHVybiB0aGUgZm9udCBvYmplY3QKKyAgICAgKi8KKyAgICBGb250IGdldERlZmF1bHRGb250KCk7CisgICAgCisgICAgLyoqCisgICAgICogRmlsbCB0aGUgZ2l2ZW4gTWFwIHdpdGggc3lzdGVtIHByb3BlcnRpZXMKKyAgICAgKi8KKyAgICB2b2lkIGluaXQoTWFwPFN0cmluZywgPz4gZGVza3RvcFByb3BlcnRpZXMpOworCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIGdpdmVuIG1hcCB3aXRoIHN5c3RlbS1kZXBlbmRlbnQgdmlzdWFsIHRleHQKKyAgICAgKiBhdHRyaWJ1dGVzIGZvciB0aGUgYWJzdHJhY3QgZGVzY3JpcHRpb24gCisgICAgICogb2YgdGhlIGdpdmVuIGlucHV0IG1ldGhvZCBoaWdobGlnaHQKKyAgICAgKiBAc2VlIGphdmEuYXd0LlRvb2xraXQubWFwSW5wdXRNZXRob2RIaWdobGlnaHQoKQorICAgICAqLworICAgIHZvaWQgbWFwSW5wdXRNZXRob2RIaWdobGlnaHQoSW5wdXRNZXRob2RIaWdobGlnaHQgaGlnaGxpZ2h0LCBNYXA8VGV4dEF0dHJpYnV0ZSwgPz4gbWFwKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9XVEsuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9XVEsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MTYyZmJkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9hd3Qvd3RrL1dUSy5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUGF2ZWwgRG9sZ292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKK2ltcG9ydCBqYXZhLmF3dC5HcmFwaGljc0RldmljZTsKKworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgV1RLIHsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBHcmFwaGljc0ZhY3RvcnkgZ2V0R3JhcGhpY3NGYWN0b3J5KCk7CisgICAgcHVibGljIGFic3RyYWN0IE5hdGl2ZUV2ZW50UXVldWUgZ2V0TmF0aXZlRXZlbnRRdWV1ZSgpOworICAgIHB1YmxpYyBhYnN0cmFjdCBXaW5kb3dGYWN0b3J5IGdldFdpbmRvd0ZhY3RvcnkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgcGxhdGZvcm0gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGludGVyZmFjZQorICAgICAqIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLkN1cnNvckZhY3RvcnkuCisgICAgICogQHJldHVybiBpbXBsZW1lbnRhdGlvbiBvZiBDdXJzb3JGYWN0b3J5CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEN1cnNvckZhY3RvcnkgZ2V0Q3Vyc29yRmFjdG9yeSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBwbGF0Zm9ybSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgaW50ZXJmYWNlCisgICAgICogb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGsuTmF0aXZlTW91c2VJbmZvLgorICAgICAqIEByZXR1cm4gaW1wbGVtZW50YXRpb24gb2YgTmF0aXZlTW91c2VJbmZvCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE5hdGl2ZU1vdXNlSW5mbyBnZXROYXRpdmVNb3VzZUluZm8oKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBTeXN0ZW1Qcm9wZXJ0aWVzIGdldFN5c3RlbVByb3BlcnRpZXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgcGxhdGZvcm0gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGludGVyZmFjZQorICAgICAqIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZVJvYm90LgorICAgICAqIEByZXR1cm4gaW1wbGVtZW50YXRpb24gb2YgTmF0aXZlUm9ib3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTmF0aXZlUm9ib3QgZ2V0TmF0aXZlUm9ib3QoR3JhcGhpY3NEZXZpY2Ugc2NyZWVuKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHBsYXRmb3JtIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIG9mIHRoZSBhYnN0cmFjdAorICAgICAqIGNsYXNzIG9yZy5hcGFjaGUuaGFybW9ueS5hd3Qud3RrLk5hdGl2ZUlNLgorICAgICAqIEByZXR1cm4gaW1wbGVtZW50YXRpb24gb2YgTmF0aXZlSU0KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTmF0aXZlSU0gZ2V0TmF0aXZlSU0oKTsKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L3d0ay9XaW5kb3dGYWN0b3J5LmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvV2luZG93RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNjA0ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L2F3dC93dGsvV2luZG93RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgTWlraGFpbCBEYW5pbG92CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmF3dC53dGs7CisKK2ltcG9ydCBqYXZhLmF3dC5EaW1lbnNpb247CitpbXBvcnQgamF2YS5hd3QuUG9pbnQ7CisKKy8qKgorICogUHJvdmlkZXMgZmFjdG9yeSBmb3IgTmF0aXZlV2luZG93CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgV2luZG93RmFjdG9yeSB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgcmV0dXJucyBOYXRpdmVXaW5kb3cgd2l0aCBkZXNpcmVkCisgICAgICogY3JlYXRpb24gcGFyYW1zCisgICAgICoKKyAgICAgKiBAcGFyYW0gcCAtIGluaXRpYWwgd2luZG93IHByb3BlcnRpZXMKKyAgICAgKiBAcmV0dXJuIGNyZWF0ZWQgd2luZG93CisgICAgICovCisgICAgTmF0aXZlV2luZG93IGNyZWF0ZVdpbmRvdyhDcmVhdGlvblBhcmFtcyBwKTsKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgTmF0aXZlV2luZG93IGluc3RhbmNlIGNvbm5lY3RlZCB0byBleGlzdGluZyBuYXRpdmUgcmVzb3VyY2UKKyAgICAgKiBAcGFyYW0gbmF0aXZlV2luZG93SWQgLSBpZCBvZiBleGlzdGluZyB3aW5kb3cKKyAgICAgKiBAcmV0dXJuIGNyZWF0ZWQgTmF0aXZlV2luZG93IGluc3RhbmNlCisgICAgICovCisgICAgTmF0aXZlV2luZG93IGF0dGFjaFdpbmRvdyhsb25nIG5hdGl2ZVdpbmRvd0lkKTsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIE5hdGl2ZVdpbmRvdyBpbnN0YW5jZSBpZiBjcmVhdGVkIGJ5IHRoaXMgaW5zdGFuY2Ugb2YKKyAgICAgKiBXaW5kb3dGYWN0b3J5LCBvdGhlcndpc2UgbnVsbAorICAgICAqCisgICAgICogQHBhcmFtIGlkIC0gSFdORCBvbiBXaW5kb3dzIHh3aW5kb3cgb24gWAorICAgICAqIEByZXR1cm4gTmF0aXZlV2luZG93IG9yIG51bGwgaWYgdW5rbm93bgorICAgICAqLworICAgIE5hdGl2ZVdpbmRvdyBnZXRXaW5kb3dCeUlkKGxvbmcgaWQpOworICAgIC8qKgorICAgICAqIFJldHVybnMgTmF0aXZlV2luZG93IGluc3RhbmNlIG9mIHRoZSB0b3AtbGV2ZWwgd2luZG93CisgICAgICogdGhhdCBjb250YWlucyBhIHNwZWNpZmllZCBwb2ludCBhbmQgd2FzCisgICAgICogY3JlYXRlZCBieSB0aGlzIGluc3RhbmNlIG9mIFdpbmRvd0ZhY3RvcnkKKyAgICAgKiBAcGFyYW0gcCAtIFBvaW50IHRvIGNoZWNrCisgICAgICogQHJldHVybiBOYXRpdmVXaW5kb3cgb3IgbnVsbCBpZiB0aGUgcG9pbnQgaXMKKyAgICAgKiBub3Qgd2l0aGluIGEgd2luZG93IGNyZWF0ZWQgYnkgdGhpcyBXaW5kb3dGYWN0b3J5CisgICAgICovCisgICAgTmF0aXZlV2luZG93IGdldFdpbmRvd0Zyb21Qb2ludChQb2ludCBwKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBuYXRpdmUgc3lzdGVtIHN1cHBvcnRzIHRoZSBzdGF0ZSBmb3Igd2luZG93cy4KKyAgICAgKiBUaGlzIG1ldGhvZCB0ZWxscyB3aGV0aGVyIHRoZSBVSSBjb25jZXB0IG9mLCBzYXksIG1heGltaXphdGlvbiBvciBpY29uaWZpY2F0aW9uIGlzIHN1cHBvcnRlZC4KKyAgICAgKiBJdCB3aWxsIGFsd2F5cyByZXR1cm4gZmFsc2UgZm9yICJjb21wb3VuZCIgc3RhdGVzIGxpa2UgRnJhbWUuSUNPTklGSUVEfEZyYW1lLk1BWElNSVpFRF9WRVJULgorICAgICAqIEluIG90aGVyIHdvcmRzLCB0aGUgcnVsZSBvZiB0aHVtYiBpcyB0aGF0IG9ubHkgcXVlcmllcyB3aXRoIGEgc2luZ2xlIGZyYW1lIHN0YXRlCisgICAgICogY29uc3RhbnQgYXMgYW4gYXJndW1lbnQgYXJlIG1lYW5pbmdmdWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhdGUgLSBvbmUgb2YgbmFtZWQgZnJhbWUgc3RhdGUgY29uc3RhbnRzLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpcyB0aGlzIGZyYW1lIHN0YXRlIGlzIHN1cHBvcnRlZCBieSB0aGlzIFRvb2xraXQgaW1wbGVtZW50YXRpb24sIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzV2luZG93U3RhdGVTdXBwb3J0ZWQoaW50IHN0YXRlKTsKKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5Db21wb25lbnRJbnRlcm5hbHMKKyAgICAgKi8KKyAgICB2b2lkIHNldENhcmV0UG9zaXRpb24oaW50IHgsIGludCB5KTsKKworICAgIC8qKgorICAgICAqIFJlcXVlc3Qgc2l6ZSBvZiBhcmJpdHJhcnkgbmF0aXZlIHdpbmRvdworICAgICAqIEBwYXJhbSBpZCAtIHdpbmRvdyBJRAorICAgICAqIEByZXR1cm4gd2luZG93IHNpemUKKyAgICAgKi8KKyAgICBEaW1lbnNpb24gZ2V0V2luZG93U2l6ZUJ5SWQobG9uZyBpZCk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9iZWFucy9pbnRlcm5hbC9ubHMvTWVzc2FnZXMuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYmVhbnMvaW50ZXJuYWwvbmxzL01lc3NhZ2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTFlODE2OAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYmVhbnMvaW50ZXJuYWwvbmxzL01lc3NhZ2VzLmphdmEKQEAgLTAsMCArMSwxNTEgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqIAorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKgorICogVEhFIEZJTEUgSEFTIEJFRU4gQVVUT0dFTkVSQVRFRCBCWSBNU0dUT09MIFRPT0wuCisgKiBBbGwgY2hhbmdlcyBtYWRlIHRvIHRoaXMgZmlsZSBtYW51YWxseSB3aWxsIGJlIG92ZXJ3cml0dGVuIAorICogaWYgdGhpcyB0b29sIHJ1bnMgYWdhaW4uIEJldHRlciBtYWtlIGNoYW5nZXMgaW4gdGhlIHRlbXBsYXRlIGZpbGUuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYmVhbnMuaW50ZXJuYWwubmxzOworCisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CisKKy8vIEJFR0lOIGFuZHJvaWQtZGVsZXRlZAorLyoKKyAqIEZvciBBbmRyb2lkLCB0aGlzIG1vZHVsZSBpcyBhIHNlcGFyYXRlIGxpYnJhcnkgYW5kIG5vdCBwYXJ0IG9mIHRoZQorICogYm9vdCBjbGFzc3BhdGgsIHNvIGl0cyByZXNvdXJjZXMgd29uJ3QgYmUgZm91bmQgb24gdGhlIGJvb3QgY2xhc3NwYXRoCisgKiBhcyBpcyBhc3N1bWVkIGJ5IE1zZ0hlbHAuZ2V0U3RyaW5nKCkuIFdlIGluc3RlYWQgdXNlIGEgbG9jYWwgTXNnSGVscAorICogd2hpY2ggYm90dG9tcyBvdXQgaW4gYSBjYWxsIHRvIHRoZSB1c2VmdWwgcGFydCBvZiBpdHMgbG93ZXItbGV2ZWwKKyAqIG5hbWVzYWtlLgorICovCisvL2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLnZtLlZNOworLy9pbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Nc2dIZWxwOworLy8gRU5EIGFuZHJvaWQtZGVsZXRlZAorCisvKioKKyAqIFRoaXMgY2xhc3MgcmV0cmlldmVzIHN0cmluZ3MgZnJvbSBhIHJlc291cmNlIGJ1bmRsZSBhbmQgcmV0dXJucyB0aGVtLAorICogZm9ybWF0dGluZyB0aGVtIHdpdGggTWVzc2FnZUZvcm1hdCB3aGVuIHJlcXVpcmVkLgorICogPHA+CisgKiBJdCBpcyB1c2VkIGJ5IHRoZSBzeXN0ZW0gY2xhc3NlcyB0byBwcm92aWRlIG5hdGlvbmFsIGxhbmd1YWdlIHN1cHBvcnQsIGJ5CisgKiBsb29raW5nIHVwIG1lc3NhZ2VzIGluIHRoZSA8Y29kZT4KKyAqICAgIG9yZy5hcGFjaGUuaGFybW9ueS5iZWFucy5pbnRlcm5hbC5ubHMubWVzc2FnZXMKKyAqIDwvY29kZT4KKyAqIHJlc291cmNlIGJ1bmRsZS4gTm90ZSB0aGF0IGlmIHRoaXMgZmlsZSBpcyBub3QgYXZhaWxhYmxlLCBvciBhbiBpbnZhbGlkIGtleQorICogaXMgbG9va2VkIHVwLCBvciByZXNvdXJjZSBidW5kbGUgc3VwcG9ydCBpcyBub3QgYXZhaWxhYmxlLCB0aGUga2V5IGl0c2VsZgorICogd2lsbCBiZSByZXR1cm5lZCBhcyB0aGUgYXNzb2NpYXRlZCBtZXNzYWdlLiBUaGlzIG1lYW5zIHRoYXQgdGhlIDxlbT5LRVk8L2VtPgorICogc2hvdWxkIGEgcmVhc29uYWJsZSBodW1hbi1yZWFkYWJsZSAoZW5nbGlzaCkgc3RyaW5nLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBNZXNzYWdlcyB7CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWRlbGV0ZWQKKyAgICAvLyBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc1Jlc291cmNlID0KKyAgICAvLyAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5iZWFucy5pbnRlcm5hbC5ubHMubWVzc2FnZXMiOyAvLyROT04tTkxTLTEkCisgICAgLy8gRU5EIGFuZHJvaWQtZGVsZXRlZAorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCBoYXMgbm8gYXJndW1lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2cpIHsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHJldHVybiBNc2dIZWxwLmdldFN0cmluZyhtc2cpOworICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCB0YWtlcyAxIGFyZ3VtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHBhcmFtIGFyZworICAgICAqICAgICAgICAgICAgT2JqZWN0IHRoZSBvYmplY3QgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBPYmplY3QgYXJnKSB7CisgICAgICAgIHJldHVybiBnZXRTdHJpbmcobXNnLCBuZXcgT2JqZWN0W10geyBhcmcgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCB0YWtlcyAxIGludGVnZXIgYXJndW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgU3RyaW5nIHRoZSBrZXkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICBpbnQgdGhlIGludGVnZXIgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBpbnQgYXJnKSB7CisgICAgICAgIHJldHVybiBnZXRTdHJpbmcobXNnLCBuZXcgT2JqZWN0W10geyBJbnRlZ2VyLnRvU3RyaW5nKGFyZykgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCB0YWtlcyAxIGNoYXJhY3RlciBhcmd1bWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEBwYXJhbSBhcmcKKyAgICAgKiAgICAgICAgICAgIGNoYXIgdGhlIGNoYXJhY3RlciB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2csIGNoYXIgYXJnKSB7CisgICAgICAgIHJldHVybiBnZXRTdHJpbmcobXNnLCBuZXcgT2JqZWN0W10geyBTdHJpbmcudmFsdWVPZihhcmcpIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggdGFrZXMgMiBhcmd1bWVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgU3RyaW5nIHRoZSBrZXkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gYXJnMQorICAgICAqICAgICAgICAgICAgT2JqZWN0IGFuIG9iamVjdCB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHBhcmFtIGFyZzIKKyAgICAgKiAgICAgICAgICAgIE9iamVjdCBhbm90aGVyIG9iamVjdCB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2csIE9iamVjdCBhcmcxLCBPYmplY3QgYXJnMikgeworICAgICAgICByZXR1cm4gZ2V0U3RyaW5nKG1zZywgbmV3IE9iamVjdFtdIHsgYXJnMSwgYXJnMiB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBtZXNzYWdlIHdoaWNoIHRha2VzIHNldmVyYWwgYXJndW1lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIE9iamVjdFtdIHRoZSBvYmplY3RzIHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbWVzc2FnZSBmb3IgdGhhdCBrZXkgaW4gdGhlIHN5c3RlbSBtZXNzYWdlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZywgT2JqZWN0W10gYXJncykgeworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgcmV0dXJuIE1zZ0hlbHAuZ2V0U3RyaW5nKG1zZywgYXJncyk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKyAgICAvLyBEdXBsaWNhdGUgY29kZSB3YXMgZHJvcHBlZCBpbiBmYXZvciBvZiB1c2luZyBNc2dIZWxwLgorICAgIC8vIEVORCBhbmRyb2lkLW5vdGUKK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYmVhbnMvaW50ZXJuYWwvbmxzL01zZ0hlbHAuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkvYmVhbnMvaW50ZXJuYWwvbmxzL01zZ0hlbHAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OGZhYWJmCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS9iZWFucy9pbnRlcm5hbC9ubHMvTXNnSGVscC5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qCisgKiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGJhc2VkIG9uIHRoZSBjbGFzcyBvZiB0aGUgc2FtZSBuYW1lIGluCisgKiBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmJlYW5zLmludGVybmFsLm5sczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydHlSZXNvdXJjZUJ1bmRsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIGhlbHBlciBtZXRob2RzIGZvciBsb2FkaW5nIHJlc291cmNlIGJ1bmRsZXMgYW5kCisgKiBmb3JtYXR0aW5nIGV4dGVybmFsIG1lc3NhZ2Ugc3RyaW5ncy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1zZ0hlbHAgeworICAgIC8qKiBuYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhpcyBjbGFzcyAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNPVVJDRV9OQU1FID0KKyAgICAgICAgIi9vcmcvYXBhY2hlL2hhcm1vbnkvYmVhbnMvaW50ZXJuYWwvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMiOworCisgICAgLyoqIHRoZSByZXNvdXJjZSBidW5kbGUgZm9yIHRoaXMgY2xhc3MgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZXNvdXJjZUJ1bmRsZSBUSEVfQlVORExFOworCisgICAgc3RhdGljIHsKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmIgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IE1zZ0hlbHAuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgUkVTT1VSQ0VfTkFNRSk7CisgICAgICAgICAgICByYiA9IG5ldyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlKGluKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwud2FybmluZygiQ291bGRuJ3QgcmVhZCByZXNvdXJjZSBidW5kbGU6ICIgKworICAgICAgICAgICAgICAgICAgICBleCk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIFNob3VsZG4ndCBoYXBwZW4sIGJ1dCBkZWFsIGF0IGxlYXN0IHNvbWV3aGF0IGdyYWNlZnVsbHkuCisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLndhcm5pbmcoIkNvdWxkbid0IGZpbmQgcmVzb3VyY2UgYnVuZGxlOiAiICsKKyAgICAgICAgICAgICAgICAgICAgZXgpOworICAgICAgICB9CisKKyAgICAgICAgVEhFX0JVTkRMRSA9IHJiOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZykgeworICAgICAgICBpZiAoVEhFX0JVTkRMRSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbXNnOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gVEhFX0JVTkRMRS5nZXRTdHJpbmcobXNnKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAiTWlzc2luZyBtZXNzYWdlOiAiICsgbXNnOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIFN0cmluZyBmb3JtYXQgPSBtc2c7CisgICAgICAgIGlmIChUSEVfQlVORExFICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9ybWF0ID0gVEhFX0JVTkRMRS5nZXRTdHJpbmcobXNnKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudXRpbC5Nc2dIZWxwLmZvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL2ludGVybmFsL25scy9NZXNzYWdlcy5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vaW50ZXJuYWwvbmxzL01lc3NhZ2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDk4ZTFiYgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL2ludGVybmFsL25scy9NZXNzYWdlcy5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqIAorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoKKyAqIFRIRSBGSUxFIEhBUyBCRUVOIEFVVE9HRU5FUkFURUQgQlkgTVNHVE9PTCBUT09MLgorICogQWxsIGNoYW5nZXMgbWFkZSB0byB0aGlzIGZpbGUgbWFudWFsbHkgd2lsbCBiZSBvdmVyd3JpdHRlbiAKKyAqIGlmIHRoaXMgdG9vbCBydW5zIGFnYWluLiBCZXR0ZXIgbWFrZSBjaGFuZ2VzIGluIHRoZSB0ZW1wbGF0ZSBmaWxlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5pbnRlcm5hbC5ubHM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsLk1zZ0hlbHA7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXRyaWV2ZXMgc3RyaW5ncyBmcm9tIGEgcmVzb3VyY2UgYnVuZGxlIGFuZCByZXR1cm5zIHRoZW0sCisgKiBmb3JtYXR0aW5nIHRoZW0gd2l0aCBNZXNzYWdlRm9ybWF0IHdoZW4gcmVxdWlyZWQuCisgKiA8cD4KKyAqIEl0IGlzIHVzZWQgYnkgdGhlIHN5c3RlbSBjbGFzc2VzIHRvIHByb3ZpZGUgbmF0aW9uYWwgbGFuZ3VhZ2Ugc3VwcG9ydCwgYnkKKyAqIGxvb2tpbmcgdXAgbWVzc2FnZXMgaW4gdGhlIDxjb2RlPgorICogICAgb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5pbnRlcm5hbC5ubHMubWVzc2FnZXMKKyAqIDwvY29kZT4KKyAqIHJlc291cmNlIGJ1bmRsZS4gTm90ZSB0aGF0IGlmIHRoaXMgZmlsZSBpcyBub3QgYXZhaWxhYmxlLCBvciBhbiBpbnZhbGlkIGtleQorICogaXMgbG9va2VkIHVwLCBvciByZXNvdXJjZSBidW5kbGUgc3VwcG9ydCBpcyBub3QgYXZhaWxhYmxlLCB0aGUga2V5IGl0c2VsZgorICogd2lsbCBiZSByZXR1cm5lZCBhcyB0aGUgYXNzb2NpYXRlZCBtZXNzYWdlLiBUaGlzIG1lYW5zIHRoYXQgdGhlIDxlbT5LRVk8L2VtPgorICogc2hvdWxkIGEgcmVhc29uYWJsZSBodW1hbi1yZWFkYWJsZSAoZW5nbGlzaCkgc3RyaW5nLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBNZXNzYWdlcyB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc1Jlc291cmNlID0KKyAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uaW50ZXJuYWwubmxzLm1lc3NhZ2VzIjsgLy8kTk9OLU5MUy0xJAorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCBoYXMgbm8gYXJndW1lbnRzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2cpIHsKKyAgICAgICAgcmV0dXJuIE1zZ0hlbHAuZ2V0U3RyaW5nKHNSZXNvdXJjZSwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBtZXNzYWdlIHdoaWNoIHRha2VzIDEgYXJndW1lbnQuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgU3RyaW5nIHRoZSBrZXkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICBPYmplY3QgdGhlIG9iamVjdCB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2csIE9iamVjdCBhcmcpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0cmluZyhtc2csIG5ldyBPYmplY3RbXSB7IGFyZyB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBtZXNzYWdlIHdoaWNoIHRha2VzIDEgaW50ZWdlciBhcmd1bWVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEBwYXJhbSBhcmcKKyAgICAgKiAgICAgICAgICAgIGludCB0aGUgaW50ZWdlciB0byBpbnNlcnQgaW4gdGhlIGZvcm1hdHRlZCBvdXRwdXQuCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIG1lc3NhZ2UgZm9yIHRoYXQga2V5IGluIHRoZSBzeXN0ZW0gbWVzc2FnZSBidW5kbGUuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBtc2csIGludCBhcmcpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0cmluZyhtc2csIG5ldyBPYmplY3RbXSB7IEludGVnZXIudG9TdHJpbmcoYXJnKSB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBtZXNzYWdlIHdoaWNoIHRha2VzIDEgY2hhcmFjdGVyIGFyZ3VtZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUga2V5IHRvIGxvb2sgdXAuCisgICAgICogQHBhcmFtIGFyZworICAgICAqICAgICAgICAgICAgY2hhciB0aGUgY2hhcmFjdGVyIHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbWVzc2FnZSBmb3IgdGhhdCBrZXkgaW4gdGhlIHN5c3RlbSBtZXNzYWdlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZywgY2hhciBhcmcpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0cmluZyhtc2csIG5ldyBPYmplY3RbXSB7IFN0cmluZy52YWx1ZU9mKGFyZykgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbWVzc2FnZSB3aGljaCB0YWtlcyAyIGFyZ3VtZW50cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICBTdHJpbmcgdGhlIGtleSB0byBsb29rIHVwLgorICAgICAqIEBwYXJhbSBhcmcxCisgICAgICogICAgICAgICAgICBPYmplY3QgYW4gb2JqZWN0IHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcGFyYW0gYXJnMgorICAgICAqICAgICAgICAgICAgT2JqZWN0IGFub3RoZXIgb2JqZWN0IHRvIGluc2VydCBpbiB0aGUgZm9ybWF0dGVkIG91dHB1dC4KKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbWVzc2FnZSBmb3IgdGhhdCBrZXkgaW4gdGhlIHN5c3RlbSBtZXNzYWdlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIG1zZywgT2JqZWN0IGFyZzEsIE9iamVjdCBhcmcyKSB7CisgICAgICAgIHJldHVybiBnZXRTdHJpbmcobXNnLCBuZXcgT2JqZWN0W10geyBhcmcxLCBhcmcyIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhIG1lc3NhZ2Ugd2hpY2ggdGFrZXMgc2V2ZXJhbCBhcmd1bWVudHMuCisgICAgICogCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgU3RyaW5nIHRoZSBrZXkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgT2JqZWN0W10gdGhlIG9iamVjdHMgdG8gaW5zZXJ0IGluIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LgorICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBtZXNzYWdlIGZvciB0aGF0IGtleSBpbiB0aGUgc3lzdGVtIG1lc3NhZ2UgYnVuZGxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB7CisgICAgICAgIHJldHVybiBNc2dIZWxwLmdldFN0cmluZyhzUmVzb3VyY2UsIG1zZywgYXJncyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vaW50ZXJuYWwvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9pbnRlcm5hbC9ubHMvbWVzc2FnZXMucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTQ5ZGQ4Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vaW50ZXJuYWwvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMKQEAgLTAsMCArMSwxOCBAQAorIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisjIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyMgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyMgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgIAorIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIyAgCisjICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgCisKKyMgbWVzc2FnZXMgZm9yIEVOIGxvY2FsZQoraW1hZ2Vpby4xPVdyb25nIGJpdERlcHRoLW51bUJhbmRzIGNvbXBvc2l0aW9uClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFVdGlscy5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vbWV0YWRhdGEvSUlPTWV0YWRhdGFVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhZWVmZGQKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9tZXRhZGF0YS9JSU9NZXRhZGF0YVV0aWxzLmphdmEKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ubWV0YWRhdGE7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKKworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGFGb3JtYXQ7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5tZXRhZGF0YS5JSU9NZXRhZGF0YUZvcm1hdEltcGw7CisKK3B1YmxpYyBjbGFzcyBJSU9NZXRhZGF0YVV0aWxzIHsKKyAgICBwcml2YXRlIElJT01ldGFkYXRhVXRpbHMoKSB7fSAKKworICAgIHB1YmxpYyBzdGF0aWMgSUlPTWV0YWRhdGFGb3JtYXQgaW5zdGFudGlhdGVNZXRhZGF0YUZvcm1hdCgKKyAgICAgICAgICAgIFN0cmluZyBmb3JtYXROYW1lLCBib29sZWFuIHN0YW5kYXJkRm9ybWF0U3VwcG9ydGVkLAorICAgICAgICAgICAgU3RyaW5nIG5hdGl2ZU1ldGFkYXRhRm9ybWF0TmFtZSwgU3RyaW5nIG5hdGl2ZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLAorICAgICAgICAgICAgU3RyaW5nIFtdIGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lcywgU3RyaW5nIFtdIGV4dHJhTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzCisgICAgKSB7CisgICAgICAgIGlmIChmb3JtYXROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImZvcm1hdE5hbWUgPT0gbnVsbCEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZm9ybWF0TmFtZS5lcXVhbHMoSUlPTWV0YWRhdGFGb3JtYXRJbXBsLnN0YW5kYXJkTWV0YWRhdGFGb3JtYXROYW1lKSkgeworICAgICAgICAgICAgaWYgKHN0YW5kYXJkRm9ybWF0U3VwcG9ydGVkKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIElJT01ldGFkYXRhRm9ybWF0SW1wbC5nZXRTdGFuZGFyZEZvcm1hdEluc3RhbmNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gbnVsbDsKKworICAgICAgICBpZiAoZm9ybWF0TmFtZS5lcXVhbHMobmF0aXZlTWV0YWRhdGFGb3JtYXROYW1lKSkgeworICAgICAgICAgICAgY2xhc3NOYW1lID0gbmF0aXZlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWU7CisgICAgICAgIH0gZWxzZSBpZiAoZXh0cmFNZXRhZGF0YUZvcm1hdE5hbWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0cmFNZXRhZGF0YUZvcm1hdE5hbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdE5hbWUuZXF1YWxzKGV4dHJhTWV0YWRhdGFGb3JtYXROYW1lc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gZXh0cmFNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXNbaV07CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZm9ybWF0IG5hbWUiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdldCB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXIgYW5kIHRyeSB0byB1c2UgaXQgZmlyc3QKKyAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dENsYXNzbG9hZGVyID0gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoCisgICAgICAgICAgICAgICAgbmV3IFByaXZpbGVnZWRBY3Rpb248Q2xhc3NMb2FkZXI+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgQ2xhc3MgY2xzOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbHMgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgdHJ1ZSwgY29udGV4dENsYXNzbG9hZGVyKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIFVzZSBjdXJyZW50IGNsYXNzIGxvYWRlcgorICAgICAgICAgICAgICAgIGNscyA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICgiQ2FuJ3Qgb2J0YWluIGZvcm1hdCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vPz8/QVdUOgorICAgICAgICAgICAgLy9NZXRob2QgZ2V0SW5zdGFuY2UgPSBjbHMuZ2V0TWV0aG9kKCJnZXRJbnN0YW5jZSIpOworICAgICAgICAgICAgLy9yZXR1cm4gKElJT01ldGFkYXRhRm9ybWF0KSBnZXRJbnN0YW5jZS5pbnZva2UobnVsbCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlMSA9IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbid0IG9idGFpbiBmb3JtYXQiKTsKKyAgICAgICAgICAgIGUxLmluaXRDYXVzZShlKTsgLy8gQWRkIHNvbWUgZGV0YWlscyB0byB0aGUgbWVzc2FnZQorICAgICAgICAgICAgdGhyb3cgZTE7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSUlTRGVjb2RpbmdJbWFnZVNvdXJjZS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0lJU0RlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTFmOTA2Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0lJU0RlY29kaW5nSW1hZ2VTb3VyY2UuamF2YQpAQCAtMCwwICsxLDExNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuRGVjb2RpbmdJbWFnZVNvdXJjZTsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGFsbG93cyB1c2FnZSBvZiB0aGUgamF2YTJkIGpwZWdkZWNvZGVyIHdpdGggSW1hZ2VJbnB1dFN0cmVhbSBpbgorICogdGhlIEpQRUdJbWFnZVJlYWRlci4gVGVtcG9yYXJ5LCBvbmx5IHRvIG1ha2UgSlBFR0ltYWdlUmVhZGVyI3JlYWQoLi4pCisgKiB3b3JraW5nLgorICoKKyAqLworcHVibGljIGNsYXNzIElJU0RlY29kaW5nSW1hZ2VTb3VyY2UgZXh0ZW5kcyBEZWNvZGluZ0ltYWdlU291cmNlIHsKKworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaXM7CisKKyAgICBwdWJsaWMgSUlTRGVjb2RpbmdJbWFnZVNvdXJjZShJbWFnZUlucHV0U3RyZWFtIGlpcykgeworICAgICAgICBpcyA9IG5ldyBJSVNUb0lucHV0U3RyZWFtV3JhcHBlcihpaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIGNoZWNrQ29ubmVjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICByZXR1cm4gaXM7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIElJU1RvSW5wdXRTdHJlYW1XcmFwcGVyIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgICAgIHByaXZhdGUgSW1hZ2VJbnB1dFN0cmVhbSBpbnB1dDsKKworICAgICAgICBwdWJsaWMgSUlTVG9JbnB1dFN0cmVhbVdyYXBwZXIoSW1hZ2VJbnB1dFN0cmVhbSBpbnB1dCkgeworICAgICAgICAgICAgdGhpcy5pbnB1dD1pbnB1dDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlYWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXQucmVhZChiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXQucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXQuc2tpcEJ5dGVzKG4pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIAlyZXR1cm4gdHJ1ZTsgIC8vIFRoaXMgaXMgb3JpZworICAgICAgICAJCisgICAgICAgICAgICAvLyA/Pz9BV1Q6IEZJWE1FCisgICAgICAgIAkvLyBUaGlzIGlzIGFuIGVycm9yIGluIEhhcm1vbnkuIE5vdCBhbGwgaW5wdXQgc3RyZWFtcworICAgICAgICAJLy8gaGF2ZSBtYXJrIHN1cHBvcnQgYW5kIGl0IGlzIG5vdCBvayB0byBqdXN0IHJldHVybiB0cnVlLiAKKyAgICAgICAgCS8vIFRoZXJlIHNob3VsZCBiZSBhbiBpbnB1dC5tYXJrU3VwcG9ydGVkKCkuIEhvd2V2ZXIsIGlmIAorICAgICAgICAJLy8gdGhpcyBjYWxsIHJldHVybnMgZmFsc2UsIG5vdGhpbmcgd29ya3MgYW55bW9yZS4KKyAgICAgICAgCQorICAgICAgICAJLy8gVGhlIGJhY2tzaWRlIGlzIHRoYXQgQml0bWFwRmFjdG9yeSB1c2VzIGEgY2FsbCB0byBtYXJrU3VwcG9ydCgpCisgICAgICAgIAkvLyB0byBmaW5kIG91dCBpZiBpdCBuZWVkcyB0byB3YXJwIHRoZSBzdHJlYW0gaW4gYQorICAgICAgICAJLy8gQnVmZmVyZWRJbnB1dFN0cmVhbSB0byBnZXQgbWFyayBzdXBwb3J0LCBhbmQgdGhpcyBmYWlscyEKKyAgICAgICAgCQorICAgICAgICAJLy8gQ3VycmVudGx5LCB0aGUgaGFjayBpcyBpbiBCaXRtYXBGYWN0b3J5LCB3aGVyZSB3ZSBhbHdheXMKKyAgICAgICAgCS8vIHdyYXAgdGhlIHN0cmVhbSBpbiBhIEJ1ZmZlcmVkSW5wdXRTdHJlYW0uCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZGxpbWl0KSB7CisgICAgICAgICAgICBpbnB1dC5tYXJrKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW5wdXQucmVzZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnB1dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdDb25zdHMuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHQ29uc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY3YTgyNQotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHQ29uc3RzLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnOworCitwdWJsaWMgY2xhc3MgSlBFR0NvbnN0cyB7CisKKyAgICBwcml2YXRlIEpQRUdDb25zdHMoKSB7fQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09JID0gMHhEODsKKworICAgIC8vLS0gSUpHIChJbmRlcGVuZGVkIEpQRUcgR3JvdXApIGNvbG9yIHNwYWNlcworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19VTktOT1cgPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19HUkFZU0NBTEUgPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19SR0IgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19ZQ2JDciA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSkNTX0NNWUsgPSA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19ZQ0MgPSA1OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19SR0JBID0gNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKQ1NfWUNiQ3JBID0gNzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKQ1NfWUNDQSA9IDEwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpDU19ZQ0NLID0gMTE7CisKKyAgICBwdWJsaWMgc3RhdGljIGludFtdW10gQkFORF9PRkZTRVRTID0ge3t9LCB7MH0sIHswLCAxfSwgezAsIDEsIDJ9LCB7MCwgMSwgMiwgM319OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBERUZBVUxUX0pQRUdfQ09NUFJFU1NJT05fUVVBTElUWSA9IDAuNzVmOworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVJlYWRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExMGVkMjMKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR0ltYWdlUmVhZGVyLmphdmEKQEAgLTAsMCArMSwxMjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS40ICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVJlYWRlcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlUmVhZFBhcmFtOworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VUeXBlU3BlY2lmaWVyOworaW1wb3J0IGphdmF4LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdJbWFnZVJlYWRQYXJhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGE7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VSZWFkZXJTcGk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlLkRlY29kaW5nSW1hZ2VTb3VyY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5PZmZzY3JlZW5JbWFnZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkJ1ZmZlcmVkSW1hZ2U7CisKKy8qKgorICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIG9yZy5hcGFjaGUuaGFybW9ueS5hd3QuZ2wuaW1hZ2UuSnBlZ0RlY29kZXIgdG8gcmVhZAorICogYW4gaW1hZ2UuIFRoZSBvbmx5IGltcGxlbWVudGVkIG1ldGhvZCBpcyByZWFkKC4uKTsKKyAqCisgKiBUT0RPOiBJbXBsZW1lbnRzIGdlbmVyaWMgZGVjb2RlciB0byBiZSB1c2VkIGJ5IGphdmFkMiBhbmQgaW1hZ2VpbworICoKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5KcGVnRGVjb2RlcgorICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZy5JSVNEZWNvZGluZ0ltYWdlU291cmNlCisgKi8KK3B1YmxpYyBjbGFzcyBKUEVHSW1hZ2VSZWFkZXIgZXh0ZW5kcyBJbWFnZVJlYWRlciB7CisKKyAgICBJbWFnZUlucHV0U3RyZWFtIGlpczsKKworICAgIHB1YmxpYyBKUEVHSW1hZ2VSZWFkZXIoSW1hZ2VSZWFkZXJTcGkgaW1hZ2VSZWFkZXJTcGkpIHsKKyAgICAgICAgc3VwZXIoaW1hZ2VSZWFkZXJTcGkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0SGVpZ2h0KGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLy0tIFRPRE8gaW1sZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRXaWR0aChpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8tLSBUT0RPIGltbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TnVtSW1hZ2VzKGJvb2xlYW4gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8tLSBUT0RPIGltbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxJbWFnZVR5cGVTcGVjaWZpZXI+IGdldEltYWdlVHlwZXMoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vLS0gVE9ETyBpbWxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0U3RyZWFtTWV0YWRhdGEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLy0tIFRPRE8gaW1sZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElJT01ldGFkYXRhIGdldEltYWdlTWV0YWRhdGEoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vLS0gVE9ETyBpbWxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSByZWFkKGludCBpLCBJbWFnZVJlYWRQYXJhbSBpbWFnZVJlYWRQYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCBzdHJlYW0gPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgRGVjb2RpbmdJbWFnZVNvdXJjZSBzb3VyY2UgPSBuZXcgSUlTRGVjb2RpbmdJbWFnZVNvdXJjZShpaXMpOworICAgICAgICBPZmZzY3JlZW5JbWFnZSBpbWFnZSA9IG5ldyBPZmZzY3JlZW5JbWFnZShzb3VyY2UpOworICAgICAgICBzb3VyY2UuYWRkQ29uc3VtZXIoaW1hZ2UpOworICAgICAgICBzb3VyY2UubG9hZCgpOworICAgICAgICAvLyBUaGUgaW50ZXJydXB0ZWQgZmxhZyBzaG91bGQgYmUgY2xlYXJlZCBiZWNhdXNlIEltYWdlRGVjb2RlciBpbnRlcnJ1cHRzCisgICAgICAgIC8vIGN1cnJlbnQgdGhyZWFkIHdoaWxlIGRlY29kaW5nLiBUaGUgc2FtZSB0ZWNobmlxdWUgaXMgdXNlZCBpbgorICAgICAgICAvLyBJbWFnZUxvYWRlciNydW4oKS4gQW5vdGhlciBzb2x1dGlvbiBjYW4gYmUgdG8gY3JlYXRlCisgICAgICAgIC8vIGEgc2VwYXJhdGUgZGVjb2RpbmcgdGhyZWFkLiBIb3dldmVyLCBkZWNvZGVyIGtlZXBzIGl0cyBvd24gcG9vbAorICAgICAgICAvLyBvZiB0aHJlYWRzIHNvIGNyZWF0aW5nIGEgbmV3IHRocmVhZCB3aWxsIGJlIGp1c3QgYSB3YXN0ZSBvZiByZXNvdXJjZXMuCisgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOworICAgICAgICByZXR1cm4gaW1hZ2UuZ2V0QnVmZmVyZWRJbWFnZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIHJlYWQoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKGksIG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldElucHV0KE9iamVjdCBpbnB1dCwgYm9vbGVhbiBzZWVrRm9yd2FyZE9ubHksIGJvb2xlYW4gaWdub3JlTWV0YWRhdGEpIHsKKyAgICAgICAgc3VwZXIuc2V0SW5wdXQoaW5wdXQsIHNlZWtGb3J3YXJkT25seSwgaWdub3JlTWV0YWRhdGEpOworICAgICAgICBpaXMgPSAoSW1hZ2VJbnB1dFN0cmVhbSkgaW5wdXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlUmVhZFBhcmFtIGdldERlZmF1bHRSZWFkUGFyYW0oKSB7CisgICAgICAgIHJldHVybiBuZXcgSlBFR0ltYWdlUmVhZFBhcmFtKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVJlYWRlclNwaS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVJlYWRlclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3MTljZTcKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR0ltYWdlUmVhZGVyU3BpLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjMgJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VSZWFkZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VSZWFkZXJTcGk7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuU2VydmljZVJlZ2lzdHJ5OworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBKUEVHSW1hZ2VSZWFkZXJTcGkgZXh0ZW5kcyBJbWFnZVJlYWRlclNwaSB7CisKKyAgICBwdWJsaWMgSlBFR0ltYWdlUmVhZGVyU3BpKCkgeworICAgICAgICBzdXBlcihKUEVHU3BpQ29uc3RzLnZlbmRvck5hbWUsIEpQRUdTcGlDb25zdHMudmVyc2lvbiwKKyAgICAgICAgICAgICAgICBKUEVHU3BpQ29uc3RzLm5hbWVzLCBKUEVHU3BpQ29uc3RzLnN1ZmZpeGVzLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMuTUlNRVR5cGVzLCBKUEVHU3BpQ29uc3RzLnJlYWRlckNsYXNzTmFtZSwKKyAgICAgICAgICAgICAgICBTVEFOREFSRF9JTlBVVF9UWVBFLCBKUEVHU3BpQ29uc3RzLndyaXRlclNwaU5hbWVzLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMuc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0LAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMubmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMubmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5leHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5leHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcywKKyAgICAgICAgICAgICAgICBKUEVHU3BpQ29uc3RzLnN1cHBvcnRzU3RhbmRhcmRJbWFnZU1ldGFkYXRhRm9ybWF0LAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMubmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5uYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMuZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5leHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzKTsKKyAgICB9CisKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNhbkRlY29kZUlucHV0KE9iamVjdCBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEltYWdlSW5wdXRTdHJlYW0gbWFya2FibGUgPSAoSW1hZ2VJbnB1dFN0cmVhbSkgc291cmNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFya2FibGUubWFyaygpOworCisgICAgICAgICAgICBieXRlW10gc2lnbmF0dXJlID0gbmV3IGJ5dGVbM107CisgICAgICAgICAgICBtYXJrYWJsZS5zZWVrKDApOworICAgICAgICAgICAgbWFya2FibGUucmVhZChzaWduYXR1cmUsIDAsIDMpOworICAgICAgICAgICAgbWFya2FibGUucmVzZXQoKTsKKworICAgICAgICAgICAgaWYgKChzaWduYXR1cmVbMF0gJiAweEZGKSA9PSAweEZGICYmCisgICAgICAgICAgICAgICAgICAgIChzaWduYXR1cmVbMV0gJiAweEZGKSA9PSBKUEVHQ29uc3RzLlNPSSAmJgorICAgICAgICAgICAgICAgICAgICAoc2lnbmF0dXJlWzJdICYgMHhGRikgPT0gMHhGRikgeyAvLyBKUEVHCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZVJlYWRlciBjcmVhdGVSZWFkZXJJbnN0YW5jZShPYmplY3QgZXh0ZW5zaW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IEpQRUdJbWFnZVJlYWRlcih0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgcmV0dXJuICJEUkwgSlBFRyBkZWNvZGVyIjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvblJlZ2lzdHJhdGlvbihTZXJ2aWNlUmVnaXN0cnkgcmVnaXN0cnksIENsYXNzPD8+IGNhdGVnb3J5KSB7CisgICAgICAgIC8vIHN1cGVyLm9uUmVnaXN0cmF0aW9uKHJlZ2lzdHJ5LCBjYXRlZ29yeSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVdyaXRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVdyaXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlM2U4NzYKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR0ltYWdlV3JpdGVyLmphdmEKQEAgLTAsMCArMSw0MDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworaW1wb3J0IGNvbS5hbmRyb2lkLmludGVybmFsLmF3dC5JbWFnZU91dHB1dFN0cmVhbVdyYXBwZXI7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVyOworaW1wb3J0IGphdmF4LmltYWdlaW8uSUlPSW1hZ2U7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVR5cGVTcGVjaWZpZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVdyaXRlUGFyYW07CitpbXBvcnQgamF2YXguaW1hZ2Vpby5wbHVnaW5zLmpwZWcuSlBFR0ltYWdlV3JpdGVQYXJhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVdyaXRlclNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLm1ldGFkYXRhLklJT01ldGFkYXRhOworCitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5CaXRtYXA7CitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5CaXRtYXBGYWN0b3J5OworaW1wb3J0IGFuZHJvaWQuZ3JhcGhpY3MuQml0bWFwLkNvbXByZXNzRm9ybWF0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuYXd0LmltYWdlLio7CitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZhLmF3dC5jb2xvci5Db2xvclNwYWNlOworCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworcHVibGljIGNsYXNzIEpQRUdJbWFnZVdyaXRlciBleHRlbmRzIEltYWdlV3JpdGVyIHsKKworICAgIC8vIC8qID8/P0FXVDogRGVidWdnaW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOworICAgIHByaXZhdGUgc3RhdGljIEJpdG1hcCBibTsKKyAgICBwdWJsaWMgc3RhdGljIEJpdG1hcCBnZXRCaXRtYXAoKSB7CisgICAgICAgIHJldHVybiBibTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgQnVmZmVyZWRJbWFnZSBidWZJbWc7CisgICAgcHVibGljIHN0YXRpYyBCdWZmZXJlZEltYWdlIGdldEJ1ZkltYWdlKCkgeworICAgICAgICByZXR1cm4gYnVmSW1nOworICAgIH0KKyAgICBzdGF0aWMgcHJpdmF0ZSBSZW5kZXJlZEltYWdlIHJlbkltZzsKKyAgICBzdGF0aWMgcHVibGljIFJlbmRlcmVkSW1hZ2UgZ2V0UmVuSW1hZ2UoKSB7CisgICAgICAgIHJldHVybiByZW5JbWc7CisgICAgfQorICAgIC8vICovCisgICAgCisgICAgcHJpdmF0ZSBsb25nIGNpbmZvOworICAgIHByaXZhdGUgUmVuZGVyZWRJbWFnZSBpbWFnZTsKKyAgICBwcml2YXRlIFJhc3RlciBzb3VyY2VSYXN0ZXI7CisgICAgcHJpdmF0ZSBXcml0YWJsZVJhc3RlciBzY2FuUmFzdGVyOworICAgIHByaXZhdGUgaW50IHNyY1hPZmYgPSAwOworICAgIHByaXZhdGUgaW50IHNyY1lPZmYgPSAwOworICAgIHByaXZhdGUgaW50IHNyY1dpZHRoOworICAgIHByaXZhdGUgaW50IHNyY0hlaWdodDsKKworICAgIC8vLS0geSBzdGVwIGZvciBpbWFnZSBzdWJzYW1wbGluZworICAgIHByaXZhdGUgaW50IGRlbHRhWSA9IDE7CisgICAgLy8tLSB4IHN0ZXAgZm9yIGltYWdlIHN1YnNhbXBsaW5nCisgICAgcHJpdmF0ZSBpbnQgZGVsdGFYID0gMTsKKworICAgIHByaXZhdGUgSW1hZ2VPdXRwdXRTdHJlYW0gaW9zOworCisgICAgcHVibGljIEpQRUdJbWFnZVdyaXRlcihJbWFnZVdyaXRlclNwaSBpbWFnZVdyaXRlclNwaSkgeworICAgICAgICBzdXBlcihpbWFnZVdyaXRlclNwaSk7CisgICAgICAgIC8vPz8/QVdUOiBjaW5mbyA9IGluaXRDb21wcmVzc2lvbk9iaigpOworICAgICAgICBjaW5mbyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIH0KKworICAgIHN0YXRpYyB7CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIFN5c3RlbS5sb2FkTGlicmFyeSgianBlZ2VuY29kZXIiKTsKKyAgICAgICAgaW5pdFdyaXRlcklkcyhJbWFnZU91dHB1dFN0cmVhbS5jbGFzcyk7CisgICAgICAgICovCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoSUlPTWV0YWRhdGEgaWlvTWV0YWRhdGEsIElJT0ltYWdlIGlpb0ltYWdlLCBJbWFnZVdyaXRlUGFyYW0gcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGlmIChpb3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW9zID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaWlvSW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW1hZ2UgZXF1YWxzIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIFJlbmRlcmVkSW1hZ2UgaW1nID0gbnVsbDsKKyAgICAgICAgaWYgKCFpaW9JbWFnZS5oYXNSYXN0ZXIoKSkgeworICAgICAgICAgICAgaW1nID0gaWlvSW1hZ2UuZ2V0UmVuZGVyZWRJbWFnZSgpOworICAgICAgICAgICAgaWYgKGltZyBpbnN0YW5jZW9mIEJ1ZmZlcmVkSW1hZ2UpIHsKKyAgICAgICAgICAgICAgICBzb3VyY2VSYXN0ZXIgPSAoKEJ1ZmZlcmVkSW1hZ2UpIGltZykuZ2V0UmFzdGVyKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNvdXJjZVJhc3RlciA9IGltZy5nZXREYXRhKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzb3VyY2VSYXN0ZXIgPSBpaW9JbWFnZS5nZXRSYXN0ZXIoKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gQVdUPz8/OiBEZWJ1Z2dpbmcKKyAgICAgICAgaWYgKERFQlVHKSB7CisgICAgICAgICAgICBpZiggaW1nPT1udWxsICkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKko6IEltYWdlIGlzIE5VTEwiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVuSW1nID0gaW1nOworICAgICAgICAgICAgICAgIGJ1ZkltZyA9IChCdWZmZXJlZEltYWdlKWltZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBudW1CYW5kcyA9IHNvdXJjZVJhc3Rlci5nZXROdW1CYW5kcygpOworICAgICAgICBpbnQgc291cmNlSUpHQ3MgPSBpbWcgPT0gbnVsbCA/IEpQRUdDb25zdHMuSkNTX1VOS05PVyA6IGdldFNvdXJjZUNTVHlwZShpbWcpOworCisgICAgICAgIHNyY1dpZHRoID0gc291cmNlUmFzdGVyLmdldFdpZHRoKCk7CisgICAgICAgIHNyY0hlaWdodCA9IHNvdXJjZVJhc3Rlci5nZXRIZWlnaHQoKTsKKworICAgICAgICBpbnQgZGVzdFdpZHRoID0gc3JjV2lkdGg7CisgICAgICAgIGludCBkZXN0SGVpZ2h0ID0gc3JjSGVpZ2h0OworCisgICAgICAgIGJvb2xlYW4gcHJvZ3Jlc3NpdmUgPSBmYWxzZTsKKyAgICAgICAgIAorICAgICAgICBpZiAocGFyYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgUmVjdGFuZ2xlIHJlZyA9IHBhcmFtLmdldFNvdXJjZVJlZ2lvbigpOworICAgICAgICAgICAgaWYgKHJlZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc3JjWE9mZiA9IHJlZy54OworICAgICAgICAgICAgICAgIHNyY1lPZmYgPSByZWcueTsKKworICAgICAgICAgICAgICAgIHNyY1dpZHRoID0gcmVnLndpZHRoICsgc3JjWE9mZiA+IHNyY1dpZHRoCisgICAgICAgICAgICAgICAgICAgICAgICA/IHNyY1dpZHRoIC0gc3JjWE9mZgorICAgICAgICAgICAgICAgICAgICAgICAgOiByZWcud2lkdGg7CisgICAgICAgICAgICAgICAgc3JjSGVpZ2h0ID0gcmVnLmhlaWdodCArIHNyY1lPZmYgPiBzcmNIZWlnaHQKKyAgICAgICAgICAgICAgICAgICAgICAgID8gc3JjSGVpZ2h0IC0gc3JjWU9mZgorICAgICAgICAgICAgICAgICAgICAgICAgOiByZWcuaGVpZ2h0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLy0tIFRPRE8gdW5jb21tZW50IHdoZW4gSlBFR0ltYWdlV3JpdGVQYXJhbSBiZSBpbXBsZW1lbnRlZAorICAgICAgICAgICAgLy8tLSBPbmx5IGRlZmF1bHQgcHJvZ3Jlc3NpdmUgbW9kZSB5ZXQKKyAgICAgICAgICAgIC8vIHByb2dyZXNzaXZlID0gcGFyYW0uZ2V0UHJvZ3Jlc3NpdmVNb2RlKCkgPT0gIEltYWdlV3JpdGVQYXJhbS5NT0RFX0RFRkFVTFQ7CisKKyAgICAgICAgICAgIC8vLS0gZGVmIGlzIDEKKyAgICAgICAgICAgIGRlbHRhWCA9IHBhcmFtLmdldFNvdXJjZVhTdWJzYW1wbGluZygpOworICAgICAgICAgICAgZGVsdGFZID0gcGFyYW0uZ2V0U291cmNlWVN1YnNhbXBsaW5nKCk7CisKKyAgICAgICAgICAgIC8vLS0gZGVmIGlzIDAKKyAgICAgICAgICAgIGludCBvZmZzZXRYID0gcGFyYW0uZ2V0U3Vic2FtcGxpbmdYT2Zmc2V0KCk7CisgICAgICAgICAgICBpbnQgb2Zmc2V0WSA9IHBhcmFtLmdldFN1YnNhbXBsaW5nWU9mZnNldCgpOworCisgICAgICAgICAgICBzcmNYT2ZmICs9IG9mZnNldFg7CisgICAgICAgICAgICBzcmNZT2ZmICs9IG9mZnNldFk7CisgICAgICAgICAgICBzcmNXaWR0aCAtPSBvZmZzZXRYOworICAgICAgICAgICAgc3JjSGVpZ2h0IC09IG9mZnNldFk7CisKKyAgICAgICAgICAgIGRlc3RXaWR0aCA9IChzcmNXaWR0aCArIGRlbHRhWCAtIDEpIC8gZGVsdGFYOworICAgICAgICAgICAgZGVzdEhlaWdodCA9IChzcmNIZWlnaHQgKyBkZWx0YVkgLSAxKSAvIGRlbHRhWTsKKyAgICAgICAgfQorCisgICAgICAgIC8vLS0gZGVmYXVsdCBEUVRzIChzZWUgSlBFR1FUYWJsZSBqYXZhIGRvYyBhbmQgSlBFRyBzcGVjIEsxICYgSzIgdGFibGVzKQorICAgICAgICAvLy0tIGF0IGh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL0pQRUcvaXR1LXQ4MS5wZGYKKyAgICAgICAgLy8tLSBPbmx5IGZpZ3VyaW5nIG91dCBob3cgdG8gc2V0IERRVCBpbiBJSkcgbGlicmFyeSBmb3IgZnV0dXJlIG1ldGFkYXRhCisgICAgICAgIC8vLS0gc3VwcG9ydC4gSUpHIGRlZiB0YWJsZXMgYXJlIHRoZSBzYW1lLgorICAgICAgICAvL0pQRUdRVGFibGVbXSBkcXQgPSBuZXcgSlBFR1FUYWJsZVsyXTsKKy8vICAgICAgICBpbnRbXVtdIGRxdCA9IG51bGw7CisvLyAgICAgICAgaW50W11bXSBkcXQgPSBuZXcgaW50WzJdW107CisvLyAgICAgICAgZHF0WzBdID0gSlBFR1FUYWJsZS5LMURpdjJMdW1pbmFuY2UuZ2V0VGFibGUoKTsKKy8vICAgICAgICBkcXRbMV0gPSBKUEVHUVRhYmxlLksyRGl2MkNocm9taW5hbmNlLmdldFRhYmxlKCk7CisgICAgICAgIAorICAgICAgICAvLz8/P0FXVDogSSB0aGluayB3ZSBkb24ndCBuZWVkIHRoaXMgYW15bW9yZQorICAgICAgICAvKgorICAgICAgICAvLy0tIHVzaW5nIGRlZmF1bHQgY29sb3Igc3BhY2UKKyAgICAgICAgLy8tLSBUT0RPOiBUYWtlIGRlc3RpbmF0aW9uIGNzIGZyb20gcGFyYW0gb3IgdXNlIGRlZmF1bHQgaWYgdGhlcmUgaXMgbm8gY3MKKyAgICAgICAgaW50IGRlc3RJSkdDcyA9IGltZyA9PSBudWxsID8gSlBFR0NvbnN0cy5KQ1NfVU5LTk9XIDogZ2V0RGVzdGluYXRpb25DU1R5cGUoaW1nKTsKKworICAgICAgICBEYXRhQnVmZmVyQnl0ZSBkYnVmZmVyID0gbmV3IERhdGFCdWZmZXJCeXRlKG51bUJhbmRzICogc3JjV2lkdGgpOworCisgICAgICAgIHNjYW5SYXN0ZXIgPSBSYXN0ZXIuY3JlYXRlSW50ZXJsZWF2ZWRSYXN0ZXIoZGJ1ZmZlciwgc3JjV2lkdGgsIDEsCisgICAgICAgICAgICAgICAgbnVtQmFuZHMgKiBzcmNXaWR0aCwgbnVtQmFuZHMsIEpQRUdDb25zdHMuQkFORF9PRkZTRVRTW251bUJhbmRzXSwgbnVsbCk7CisKKyAgICAgICAgZW5jb2RlKGRidWZmZXIuZ2V0RGF0YSgpLCBzcmNXaWR0aCwgZGVzdFdpZHRoLCBkZXN0SGVpZ2h0LCBkZWx0YVgsCisgICAgICAgICAgICAgICAgc291cmNlSUpHQ3MsIGRlc3RJSkdDcywgbnVtQmFuZHMsIHByb2dyZXNzaXZlLAorICAgICAgICAgICAgICAgIG51bGwsIGNpbmZvKTsKKyAgICAgICAgKi8KKyAgICAgICAgCisgICAgICAgIFNhbXBsZU1vZGVsIG1vZGVsID0gc291cmNlUmFzdGVyLmdldFNhbXBsZU1vZGVsKCk7CisgICAgICAgIAorICAgICAgICBpZiAobW9kZWwgaW5zdGFuY2VvZiBTaW5nbGVQaXhlbFBhY2tlZFNhbXBsZU1vZGVsKSB7CisgICAgICAgICAgICBEYXRhQnVmZmVySW50IGlidWYgPSAoRGF0YUJ1ZmZlckludClzb3VyY2VSYXN0ZXIuZ2V0RGF0YUJ1ZmZlcigpOworICAgICAgICAgICAgaW50W10gcGl4ZWxzID0gaWJ1Zi5nZXREYXRhKCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIENyZWF0ZSBhIGJpdG1hcCB3aXRoIHRoZSBwaXhlbAorICAgICAgICAgICAgYm0gPSBCaXRtYXAuY3JlYXRlQml0bWFwKHBpeGVscywgc3JjV2lkdGgsIHNyY0hlaWdodCwgQml0bWFwLkNvbmZpZy5BUkdCXzg4ODgpOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBVc2UgQml0bWFwLmNvbXByZXNzKCkgdG8gd3JpdGUgdGhlIGltYWdlCisgICAgICAgICAgICBJbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIgaW9zdyA9IG5ldyBJbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIoaW9zKTsKKyAgICAgICAgICAgIGJtLmNvbXByZXNzKENvbXByZXNzRm9ybWF0LkpQRUcsIDEwMCwgaW9zdyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyA/Pz9BV1Q6IEFkZCBzdXBwb3J0IGZvciBvdGhlciBjb2xvciBtb2RlbHMKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDb2xvciBtb2RlbCBub3Qgc3VwcG9ydGVkIHlldCIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgeworICAgICAgICBzdXBlci5kaXNwb3NlKCk7CisgICAgICAgIGlmIChjaW5mbyAhPSAwKSB7CisgICAgICAgICAgICAvLz8/P0FXVDogZGlzcG9zZShjaW5mbyk7CisgICAgICAgICAgICBjaW5mbyA9IDA7CisgICAgICAgICAgICBpb3MgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0RGVmYXVsdFN0cmVhbU1ldGFkYXRhKEltYWdlV3JpdGVQYXJhbSBpbWFnZVdyaXRlUGFyYW0pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyBJSU9NZXRhZGF0YSBnZXREZWZhdWx0SW1hZ2VNZXRhZGF0YShJbWFnZVR5cGVTcGVjaWZpZXIgaW1hZ2VUeXBlU3BlY2lmaWVyLCBJbWFnZVdyaXRlUGFyYW0gaW1hZ2VXcml0ZVBhcmFtKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgY29udmVydFN0cmVhbU1ldGFkYXRhKElJT01ldGFkYXRhIGlpb01ldGFkYXRhLCBJbWFnZVdyaXRlUGFyYW0gaW1hZ2VXcml0ZVBhcmFtKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IHN1cHBvcnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgY29udmVydEltYWdlTWV0YWRhdGEoSUlPTWV0YWRhdGEgaWlvTWV0YWRhdGEsIEltYWdlVHlwZVNwZWNpZmllciBpbWFnZVR5cGVTcGVjaWZpZXIsIEltYWdlV3JpdGVQYXJhbSBpbWFnZVdyaXRlUGFyYW0pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3Qgc3VwcG9ydGVkIHlldCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dChPYmplY3Qgb3V0cHV0KSB7CisgICAgICAgIHN1cGVyLnNldE91dHB1dChvdXRwdXQpOworICAgICAgICBpb3MgPSAoSW1hZ2VPdXRwdXRTdHJlYW0pIG91dHB1dDsKKyAgICAgICAgLy8/Pz9BV1Q6IHNldElPUyhpb3MsIGNpbmZvKTsKKyAgICAgICAgc291cmNlUmFzdGVyID0gbnVsbDsKKyAgICAgICAgc2NhblJhc3RlciA9IG51bGw7CisgICAgICAgIHNyY1hPZmYgPSAwOworICAgICAgICBzcmNZT2ZmID0gMDsKKyAgICAgICAgc3JjV2lkdGggPSAwOworICAgICAgICBzcmNIZWlnaHQgPSAwOworICAgICAgICBkZWx0YVkgPSAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZyZWVzIHJlc291cmNlcworICAgICAqIEBwYXJhbSBzdHJ1Y3RQb2ludGVyCisgICAgICovCisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgbmF0aXZlIHZvaWQgZGlzcG9zZShsb25nIHN0cnVjdFBvaW50ZXIpOworCisgICAgLyoqCisgICAgICogSW5pdHMgbWV0aG9kcyBJZHMgZm9yIG5hdGl2ZSB0byBqYXZhIGNhbGxiYWNrcworICAgICAqIEBwYXJhbSBpb3NDbGFzcworICAgICAqLworICAgIC8vPz8/QVdUOiBwcml2YXRlIG5hdGl2ZSBzdGF0aWMgdm9pZCBpbml0V3JpdGVySWRzKENsYXNzPEltYWdlT3V0cHV0U3RyZWFtPiBpb3NDbGFzcyk7CisKKyAgICAvKioKKyAgICAgKiBJbml0cyBjb21wcmVzc2lvbiBvYmplY3RzCisgICAgICogQHJldHVybiBwb2ludGVyIHRvIHRoZSBuYXRpdmUgc3RydWN0dXJlCisgICAgICovCisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgbmF0aXZlIGxvbmcgaW5pdENvbXByZXNzaW9uT2JqKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGltYWdlIG91dHB1dCBzdHJlYW0gaW4gSUpHIGxheWVyCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqLworICAgIC8vPz8/QVdUOiBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldElPUyhJbWFnZU91dHB1dFN0cmVhbSBzdHJlYW0sIGxvbmcgc3RydWN0UG9pbnRlcik7CisKKyAgICAvKioKKyAgICAgKiBSdW5zIGVuY29kaW5nIHByb2Nlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YSBpbWFnZSBkYXRhIGJ1ZmZlciB0byBlbmNvZGUKKyAgICAgKiBAcGFyYW0gc3JjV2lkdGggLSBzb3VyY2Ugd2lkdGgKKyAgICAgKiBAcGFyYW0gd2lkdGggLSBkZXN0aW5hdGlvbiB3aWR0aAorICAgICAqIEBwYXJhbSBoZWlnaHQgZGVzdGluYXRpb24gaGVpZ2h0CisgICAgICogQHBhcmFtIGRlbHRhWCAtIHggc3Vic2FtcGxpbmcgc3RlcAorICAgICAqIEBwYXJhbSBpbkNvbG9yU3BhY2UgLSBvcmlnaW5hbCBjb2xvciBzcGFjZQorICAgICAqIEBwYXJhbSBvdXRDb2xvclNwYWNlIC0gZGVzdGluYXRpb24gY29sb3Igc3BhY2UKKyAgICAgKiBAcGFyYW0gbnVtQmFuZHMgLSBudW1iZXIgb2YgYmFuZHMKKyAgICAgKiBAcGFyYW0gY2luZm8gLSBuYXRpdmUgaGFuZGxlcgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICAvLz8/P0FXVDoKKyAgICAvKgorICAgIHByaXZhdGUgbmF0aXZlIGJvb2xlYW4gZW5jb2RlKGJ5dGVbXSBkYXRhLCBpbnQgc3JjV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgZGVsdGFYLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbkNvbG9yU3BhY2UsIGludCBvdXRDb2xvclNwYWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1CYW5kcywgYm9vbGVhbiBwcm9ncmVzc2l2ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXVtdIGRxdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGNpbmZvKTsKKyAgICAqLworCisgICAgLyoqCisgICAgICogQ2FsbGJhY2sgZm9yIGdldHRpbmcgYSBuZXh0IHNjYW5saW5lCisgICAgICogQHBhcmFtIHNjYW5saW5lIHNjYW4gbGluZSBudW1iZXIKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIHZvaWQgZ2V0U2NhbkxpbmUoaW50IHNjYW5saW5lKSB7CisgICAgICAgIC8vLS0gVE9ETzogcHJvY2Vzc0ltYWdlUHJvZ3Jlc3MgaW4gSW1hZ2VXcml0ZXIKKyAgICAgICAgUmFzdGVyIGNoaWxkID0gc291cmNlUmFzdGVyLmNyZWF0ZUNoaWxkKHNyY1hPZmYsCisgICAgICAgICAgICAgICAgc3JjWU9mZiArIHNjYW5saW5lICogZGVsdGFZLCBzcmNXaWR0aCwgMSwgMCwgMCwgbnVsbCk7CisKKyAgICAgICAgc2NhblJhc3Rlci5zZXRSZWN0KGNoaWxkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIGNvbG9yIHNwYWNlIHR5cGVzIHRvIElKRyBjb2xvciBzcGFjZXMKKyAgICAgKiBAcGFyYW0gaW1hZ2UKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0U291cmNlQ1NUeXBlKFJlbmRlcmVkSW1hZ2UgaW1hZ2UpIHsKKyAgICAgICAgaW50IHR5cGUgPSBKUEVHQ29uc3RzLkpDU19VTktOT1c7CisgICAgICAgIENvbG9yTW9kZWwgY20gPSBpbWFnZS5nZXRDb2xvck1vZGVsKCk7CisKKyAgICAgICAgaWYgKG51bGwgPT0gY20pIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNtIGluc3RhbmNlb2YgSW5kZXhDb2xvck1vZGVsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkluZGV4Q29sb3JNb2RlbCBpcyBub3Qgc3VwcG9ydGVkIHlldCIpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBoYXNBbHBoYSA9IGNtLmhhc0FscGhhKCk7CisgICAgICAgIENvbG9yU3BhY2UgY3MgPSBjbS5nZXRDb2xvclNwYWNlKCk7CisgICAgICAgIHN3aXRjaChjcy5nZXRUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5UWVBFX0dSQVk6CisgICAgICAgICAgICAgICAgdHlwZSA9IEpQRUdDb25zdHMuSkNTX0dSQVlTQ0FMRTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLlRZUEVfUkdCOgorICAgICAgICAgICAgICAgIHR5cGUgPSBoYXNBbHBoYSA/IEpQRUdDb25zdHMuSkNTX1JHQkEgOiBKUEVHQ29uc3RzLkpDU19SR0I7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5UWVBFX1lDYkNyOgorICAgICAgICAgICAgICAgIHR5cGUgPSBoYXNBbHBoYSA/IEpQRUdDb25zdHMuSkNTX1lDYkNyQSA6IEpQRUdDb25zdHMuSkNTX1lDYkNyOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuVFlQRV8zQ0xSOgorICAgICAgICAgICAgICAgICB0eXBlID0gaGFzQWxwaGEgPyBKUEVHQ29uc3RzLkpDU19ZQ0NBIDogSlBFR0NvbnN0cy5KQ1NfWUNDOworICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLlRZUEVfQ01ZSzoKKyAgICAgICAgICAgICAgICAgIHR5cGUgPSBKUEVHQ29uc3RzLkpDU19DTVlLOworICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBkZXN0aW5hdGlvbiBjb2xvciBzcGFjZS4KKyAgICAgKiAoWUNiQ3JbQV0gZm9yIFJHQikKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbWFnZQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXREZXN0aW5hdGlvbkNTVHlwZShSZW5kZXJlZEltYWdlIGltYWdlKSB7CisgICAgICAgIGludCB0eXBlID0gSlBFR0NvbnN0cy5KQ1NfVU5LTk9XOworICAgICAgICBDb2xvck1vZGVsIGNtID0gaW1hZ2UuZ2V0Q29sb3JNb2RlbCgpOworICAgICAgICBpZiAobnVsbCAhPSBjbSkgeworICAgICAgICAgICAgYm9vbGVhbiBoYXNBbHBoYSA9IGNtLmhhc0FscGhhKCk7CisgICAgICAgICAgICBDb2xvclNwYWNlIGNzID0gY20uZ2V0Q29sb3JTcGFjZSgpOworCisgICAgICAgICAgICBzd2l0Y2goY3MuZ2V0VHlwZSgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLlRZUEVfR1JBWToKKyAgICAgICAgICAgICAgICAgICAgdHlwZSA9IEpQRUdDb25zdHMuSkNTX0dSQVlTQ0FMRTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuVFlQRV9SR0I6CisgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBoYXNBbHBoYSA/IEpQRUdDb25zdHMuSkNTX1lDYkNyQSA6IEpQRUdDb25zdHMuSkNTX1lDYkNyOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgIGNhc2UgQ29sb3JTcGFjZS5UWVBFX1lDYkNyOgorICAgICAgICAgICAgICAgICAgICB0eXBlID0gaGFzQWxwaGEgPyBKUEVHQ29uc3RzLkpDU19ZQ2JDckEgOiBKUEVHQ29uc3RzLkpDU19ZQ2JDcjsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICBjYXNlIENvbG9yU3BhY2UuVFlQRV8zQ0xSOgorICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IGhhc0FscGhhID8gSlBFR0NvbnN0cy5KQ1NfWUNDQSA6IEpQRUdDb25zdHMuSkNTX1lDQzsKKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgY2FzZSBDb2xvclNwYWNlLlRZUEVfQ01ZSzoKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gSlBFR0NvbnN0cy5KQ1NfQ01ZSzsKKyAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgSW1hZ2VXcml0ZVBhcmFtIGdldERlZmF1bHRXcml0ZVBhcmFtKCkgeworICAgICAgICByZXR1cm4gbmV3IEpQRUdJbWFnZVdyaXRlUGFyYW0oZ2V0TG9jYWxlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHSW1hZ2VXcml0ZXJTcGkuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHSW1hZ2VXcml0ZXJTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzk5MGUwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9qcGVnL0pQRUdJbWFnZVdyaXRlclNwaS5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4zICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uc3BpLkltYWdlV3JpdGVyU3BpOworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VXcml0ZXI7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVR5cGVTcGVjaWZpZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgSlBFR0ltYWdlV3JpdGVyU3BpIGV4dGVuZHMgSW1hZ2VXcml0ZXJTcGkgeworCisgICAgcHVibGljIEpQRUdJbWFnZVdyaXRlclNwaSgpIHsKKyAgICAgICAgc3VwZXIoSlBFR1NwaUNvbnN0cy52ZW5kb3JOYW1lLCBKUEVHU3BpQ29uc3RzLnZlcnNpb24sCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5uYW1lcywgSlBFR1NwaUNvbnN0cy5zdWZmaXhlcywgSlBFR1NwaUNvbnN0cy5NSU1FVHlwZXMsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy53cml0ZXJDbGFzc05hbWUsIFNUQU5EQVJEX09VVFBVVF9UWVBFLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMucmVhZGVyU3BpTmFtZXMsIEpQRUdTcGlDb25zdHMuc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0IC8qVE9ETzogc3VwcG9ydCBzdC4gbWV0YWRhdGEgZm9ybWF0Ki8sCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5uYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUsIEpQRUdTcGlDb25zdHMubmF0aXZlU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5leHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMsIEpQRUdTcGlDb25zdHMuZXh0cmFTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMsCisgICAgICAgICAgICAgICAgSlBFR1NwaUNvbnN0cy5zdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdCwgSlBFR1NwaUNvbnN0cy5uYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZSwgSlBFR1NwaUNvbnN0cy5uYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lLAorICAgICAgICAgICAgICAgIEpQRUdTcGlDb25zdHMuZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0TmFtZXMsIEpQRUdTcGlDb25zdHMuZXh0cmFJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlSW1hZ2UoSW1hZ2VUeXBlU3BlY2lmaWVyIGltYWdlVHlwZVNwZWNpZmllcikgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2VXcml0ZXIgY3JlYXRlV3JpdGVySW5zdGFuY2UoT2JqZWN0IG8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSlBFR0ltYWdlV3JpdGVyKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIkRSTCBKUEVHIEVuY29kZXIiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvanBlZy9KUEVHU3BpQ29uc3RzLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR1NwaUNvbnN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzYjRhNTAKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL2pwZWcvSlBFR1NwaUNvbnN0cy5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZzsKKworLyoqCisgKiBAYXV0aG9yIFJ1c3RlbSBWLiBSYWZpa292CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMiAkCisgKi8KK3B1YmxpYyBjbGFzcyBKUEVHU3BpQ29uc3RzIHsKKyAgICBwcml2YXRlIEpQRUdTcGlDb25zdHMoKSB7fQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmVuZG9yTmFtZSA9ICJJbnRlbCBDb3Jwb3JhdGlvbiI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmVyc2lvbiA9ICIwLjEgYmV0YSI7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHJlYWRlckNsYXNzTmFtZSA9ICJvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZy5KUEVHSW1hZ2VSZWFkZXIiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgd3JpdGVyQ2xhc3NOYW1lID0gIm9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdJbWFnZVdyaXRlciI7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nW10gbmFtZXMgPSB7ImpwZWciLCAianBnIiwgIkpQRUciLCAiSlBHIn07CisgICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHN1ZmZpeGVzID0geyJqcGVnIiwgImpwZyJ9OworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBNSU1FVHlwZXMgPSB7ImltYWdlL2pwZWcifTsKKworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSB3cml0ZXJTcGlOYW1lcyA9IHsib3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLmpwZWcuSlBFR0ltYWdlV3JpdGVyU3BpIn07CisgICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHJlYWRlclNwaU5hbWVzID0geyJvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZy5KUEVHSW1hZ2VSZWFkZXJTcGkifTsKKworICAgIC8vLS0gVE9ETyBmaWxsIHRoaXMgc3R1ZmYgd2l0aCBjb3JyZWN0IGRhdGEKKyAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBzdXBwb3J0c1N0YW5kYXJkU3RyZWFtTWV0YWRhdGFGb3JtYXQgPSBmYWxzZTsKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZSA9IG51bGw7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdENsYXNzTmFtZSA9IG51bGw7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXROYW1lcyA9IG51bGw7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzID0gbnVsbDsKKyAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBzdXBwb3J0c1N0YW5kYXJkSW1hZ2VNZXRhZGF0YUZvcm1hdCA9IGZhbHNlOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgbmF0aXZlSW1hZ2VNZXRhZGF0YUZvcm1hdE5hbWUgPQorICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLk15Rm9ybWF0TWV0YWRhdGFfMS4wIjsKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIG5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWUgPQorICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLk15Rm9ybWF0TWV0YWRhdGEiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcyA9IG51bGw7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGV4dHJhSW1hZ2VNZXRhZGF0YUZvcm1hdENsYXNzTmFtZXMgPSBudWxsOworCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVJlYWRlci5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODAwNDFjCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VSZWFkZXIuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5wbmc7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuYXd0LmdsLmltYWdlLkRlY29kaW5nSW1hZ2VTb3VyY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmF3dC5nbC5pbWFnZS5PZmZzY3JlZW5JbWFnZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMuanBlZy5JSVNEZWNvZGluZ0ltYWdlU291cmNlOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVJlYWRlcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlVHlwZVNwZWNpZmllcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlUmVhZFBhcmFtOworaW1wb3J0IGphdmF4LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdJbWFnZVJlYWRQYXJhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVJlYWRlclNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGE7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuQnVmZmVyZWRJbWFnZTsKKworcHVibGljIGNsYXNzIFBOR0ltYWdlUmVhZGVyICBleHRlbmRzIEltYWdlUmVhZGVyIHsKKyAgICBJbWFnZUlucHV0U3RyZWFtIGlpczsKKworICAgIHB1YmxpYyBQTkdJbWFnZVJlYWRlcihJbWFnZVJlYWRlclNwaSBpbWFnZVJlYWRlclNwaSkgeworICAgICAgICBzdXBlcihpbWFnZVJlYWRlclNwaSk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXROdW1JbWFnZXMoYm9vbGVhbiBhbGxvd1NlYXJjaCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8tLSBUT0RPIGltbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0V2lkdGgoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vLS0gVE9ETyBpbWxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEhlaWdodChpbnQgaW1hZ2VJbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8tLSBUT0RPIGltbGVtZW50CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibm90IGltcGxlbWVudGVkIHlldCIpOworICAgIH0KKworICAgIHB1YmxpYyBJdGVyYXRvcjxJbWFnZVR5cGVTcGVjaWZpZXI+IGdldEltYWdlVHlwZXMoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vLS0gVE9ETyBpbWxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0U3RyZWFtTWV0YWRhdGEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLy0tIFRPRE8gaW1sZW1lbnQKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgaW1wbGVtZW50ZWQgeWV0Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElJT01ldGFkYXRhIGdldEltYWdlTWV0YWRhdGEoaW50IGltYWdlSW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vLS0gVE9ETyBpbWxlbWVudAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnVmZmVyZWRJbWFnZSByZWFkKGludCBpLCBJbWFnZVJlYWRQYXJhbSBpbWFnZVJlYWRQYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCBzdHJlYW0gPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgRGVjb2RpbmdJbWFnZVNvdXJjZSBzb3VyY2UgPSBuZXcgSUlTRGVjb2RpbmdJbWFnZVNvdXJjZShpaXMpOworICAgICAgICBPZmZzY3JlZW5JbWFnZSBpbWFnZSA9IG5ldyBPZmZzY3JlZW5JbWFnZShzb3VyY2UpOworICAgICAgICBzb3VyY2UuYWRkQ29uc3VtZXIoaW1hZ2UpOworICAgICAgICBzb3VyY2UubG9hZCgpOworICAgICAgICAvLyBUaGUgaW50ZXJydXB0ZWQgZmxhZyBzaG91bGQgYmUgY2xlYXJlZCBiZWNhdXNlIEltYWdlRGVjb2RlciBpbnRlcnJ1cHRzCisgICAgICAgIC8vIGN1cnJlbnQgdGhyZWFkIHdoaWxlIGRlY29kaW5nIChkdWUgaXRzIGFyY2hpdGVjdHVyZSkuCisgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOworICAgICAgICByZXR1cm4gaW1hZ2UuZ2V0QnVmZmVyZWRJbWFnZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCdWZmZXJlZEltYWdlIHJlYWQoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKGksIG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldElucHV0KE9iamVjdCBpbnB1dCwgYm9vbGVhbiBzZWVrRm9yd2FyZE9ubHksIGJvb2xlYW4gaWdub3JlTWV0YWRhdGEpIHsKKyAgICAgICAgc3VwZXIuc2V0SW5wdXQoaW5wdXQsIHNlZWtGb3J3YXJkT25seSwgaWdub3JlTWV0YWRhdGEpOworICAgICAgICBpaXMgPSAoSW1hZ2VJbnB1dFN0cmVhbSkgaW5wdXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlUmVhZFBhcmFtIGdldERlZmF1bHRSZWFkUGFyYW0oKSB7CisgICAgICAgIHJldHVybiBuZXcgSW1hZ2VSZWFkUGFyYW0oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVJlYWRlclNwaS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VSZWFkZXJTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGY4YjEwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VSZWFkZXJTcGkuamF2YQpAQCAtMCwwICsxLDg4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLnBuZzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5qcGVnLkpQRUdTcGlDb25zdHM7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZVJlYWRlclNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5TZXJ2aWNlUmVnaXN0cnk7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5JbWFnZVJlYWRlcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIFBOR0ltYWdlUmVhZGVyU3BpIGV4dGVuZHMgSW1hZ2VSZWFkZXJTcGkgeworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE5HX05BTUVTW10gPSBuZXcgU3RyaW5nW10geyJwbmciLCAiUE5HIn07CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBQTkdfU1VGRklYRVNbXSA9IG5ldyBTdHJpbmdbXSB7InBuZyJ9OworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE5HX01JTUVfVFlQRVNbXSA9IG5ldyBTdHJpbmdbXSB7ImltYWdlL3BuZyJ9OworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE5HX1JFQURFUl9DTEFTU19OQU1FID0gIm9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5wbmcuUE5HSW1hZ2VSZWFkZXIiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE5HX1JFQURFUl9TUElfTkFNRVNbXSA9IHsib3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLnBuZy5QTkdJbWFnZVJlYWRlclNwaSJ9OworCisgICAgcHVibGljIFBOR0ltYWdlUmVhZGVyU3BpKCkgeworICAgICAgICBzdXBlcigKKyAgICAgICAgICAgICAgICBKUEVHU3BpQ29uc3RzLnZlbmRvck5hbWUsIEpQRUdTcGlDb25zdHMudmVyc2lvbiwKKyAgICAgICAgICAgICAgICBQTkdfTkFNRVMsIFBOR19TVUZGSVhFUywKKyAgICAgICAgICAgICAgICBQTkdfTUlNRV9UWVBFUywgUE5HX1JFQURFUl9DTEFTU19OQU1FLAorICAgICAgICAgICAgICAgIFNUQU5EQVJEX0lOUFVUX1RZUEUsIG51bGwsCisgICAgICAgICAgICAgICAgZmFsc2UsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLCBmYWxzZSwgCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsCisgICAgICAgICk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuRGVjb2RlSW5wdXQoT2JqZWN0IHNvdXJjZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW1hZ2VJbnB1dFN0cmVhbSBtYXJrYWJsZSA9IChJbWFnZUlucHV0U3RyZWFtKSBzb3VyY2U7CisgICAgICAgIG1hcmthYmxlLm1hcmsoKTsKKworICAgICAgICBieXRlW10gc2lnbmF0dXJlID0gbmV3IGJ5dGVbOF07CisgICAgICAgIG1hcmthYmxlLnNlZWsoMCk7CisKKyAgICAgICAgaW50IG5CeXRlcyA9IG1hcmthYmxlLnJlYWQoc2lnbmF0dXJlLCAwLCA4KTsKKyAgICAgICAgaWYobkJ5dGVzICE9IDgpIG1hcmthYmxlLnJlYWQoc2lnbmF0dXJlLCBuQnl0ZXMsIDgtbkJ5dGVzKTsKKyAgICAgICAgbWFya2FibGUucmVzZXQoKTsKKworICAgICAgICAvLyBQTkcgc2lnbmF0dXJlOiAxMzcgODAgNzggNzEgMTMgMTAgMjYgMTAKKyAgICAgICAgcmV0dXJuICAoc2lnbmF0dXJlWzBdICYgMHhGRikgPT0gMTM3ICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsxXSAmIDB4RkYpID09IDgwICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVsyXSAmIDB4RkYpID09IDc4ICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVszXSAmIDB4RkYpID09IDcxICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs0XSAmIDB4RkYpID09IDEzICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs1XSAmIDB4RkYpID09IDEwICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs2XSAmIDB4RkYpID09IDI2ICYmCisgICAgICAgICAgICAgICAgKHNpZ25hdHVyZVs3XSAmIDB4RkYpID09IDEwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZVJlYWRlciBjcmVhdGVSZWFkZXJJbnN0YW5jZShPYmplY3QgZXh0ZW5zaW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFBOR0ltYWdlUmVhZGVyKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIkRSTCBQTkcgZGVjb2RlciI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25SZWdpc3RyYXRpb24oU2VydmljZVJlZ2lzdHJ5IHJlZ2lzdHJ5LCBDbGFzczw/PiBjYXRlZ29yeSkgeworICAgICAgICBzdXBlci5vblJlZ2lzdHJhdGlvbihyZWdpc3RyeSwgY2F0ZWdvcnkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvcG5nL1BOR0ltYWdlV3JpdGVyLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVdyaXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyYThkN2QKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVdyaXRlci5qYXZhCkBAIC0wLDAgKzEsMjQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFZpc2tvdiBOaWtvbGF5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLnBuZzsKKworaW1wb3J0IGNvbS5hbmRyb2lkLmludGVybmFsLmF3dC5JbWFnZU91dHB1dFN0cmVhbVdyYXBwZXI7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkNvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckJ5dGU7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuRGF0YUJ1ZmZlckludDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbmRleENvbG9yTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuUmFzdGVyOworaW1wb3J0IGphdmEuYXd0LmltYWdlLlJlbmRlcmVkSW1hZ2U7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuU2FtcGxlTW9kZWw7CitpbXBvcnQgamF2YS5hd3QuaW1hZ2UuU2luZ2xlUGl4ZWxQYWNrZWRTYW1wbGVNb2RlbDsKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Xcml0YWJsZVJhc3RlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5JSU9JbWFnZTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlVHlwZVNwZWNpZmllcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVQYXJhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVyOworaW1wb3J0IGphdmF4LmltYWdlaW8ubWV0YWRhdGEuSUlPTWV0YWRhdGE7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VXcml0ZXJTcGk7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLmludGVybmFsLm5scy5NZXNzYWdlczsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuTm90SW1wbGVtZW50ZWRFeGNlcHRpb247CisKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkJpdG1hcDsKK2ltcG9ydCBhbmRyb2lkLmdyYXBoaWNzLkJpdG1hcC5Db21wcmVzc0Zvcm1hdDsKKworcHVibGljIGNsYXNzIFBOR0ltYWdlV3JpdGVyIGV4dGVuZHMgSW1hZ2VXcml0ZXIgeworICAgIAorICAgIC8vIC8qID8/P0FXVDogRGVidWdnaW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOworICAgIHByaXZhdGUgc3RhdGljIEJpdG1hcCBibTsKKyAgICBwdWJsaWMgc3RhdGljIEJpdG1hcCBnZXRCaXRtYXAoKSB7CisgICAgICAgIHJldHVybiBibTsKKyAgICB9CisgICAgLy8gKi8KKyAgICAKKyAgICBwcml2YXRlIHN0YXRpYyBpbnRbXVtdIEJBTkRfT0ZGU0VUUyA9IHsKKyAgICAgICAgICAgIHt9LCB7CisgICAgICAgICAgICAgICAgMCB9LCB7CisgICAgICAgICAgICAgICAgICAgIDAsIDEgfSwgeworICAgICAgICAgICAgICAgICAgICAwLCAxLCAyIH0sIHsKKyAgICAgICAgICAgICAgICAgICAgMCwgMSwgMiwgMyB9IH07CisKKyAgICAvLyBFYWNoIHBpeGVsIGlzIGEgZ3JheXNjYWxlIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfR1JBWSA9IDA7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhbiBSLEcsQiB0cmlwbGUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBOR19DT0xPUl9UWVBFX1JHQiA9IDI7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhIHBhbGV0dGUgaW5kZXgsIGEgUExURSBjaHVuayBtdXN0IGFwcGVhci4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfUExURSA9IDM7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhIGdyYXlzY2FsZSBzYW1wbGUsIGZvbGxvd2VkIGJ5IGFuIGFscGhhIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfR1JBWV9BTFBIQSA9IDQ7CisgICAgLy8gRWFjaCBwaXhlbCBpcyBhbiBSLEcsQiB0cmlwbGUsIGZvbGxvd2VkIGJ5IGFuIGFscGhhIHNhbXBsZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE5HX0NPTE9SX1RZUEVfUkdCQSA9IDY7CisgICAgCisgICAgLy8/Pz9BV1Q6IHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGluaXRJRHMoQ2xhc3M8SW1hZ2VPdXRwdXRTdHJlYW0+IGlvc0NsYXNzKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIC8vPz8/QVdUCisgICAgICAgIC8qCisgICAgICAgIFN5c3RlbS5sb2FkTGlicmFyeSgicG5nZW5jb2RlciIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGluaXRJRHMoSW1hZ2VPdXRwdXRTdHJlYW0uY2xhc3MpOworICAgICAgICAqLworICAgIH0KKyAgICAKKyAgICAvKgorICAgIHByaXZhdGUgbmF0aXZlIGludCBlbmNvZGUoYnl0ZVtdIGlucHV0LCBpbnQgYnl0ZXNJbkJ1ZmZlciwgaW50IGJ5dGVQaXhlbFNpemUsIE9iamVjdCBpb3MsIGludCBpbWFnZVdpZHRoLAorICAgICAgICAgICAgaW50IGltYWdlSGVpZ2h0LCBpbnQgYml0RGVwdGgsIGludCBjb2xvclR5cGUsIGludFtdIHBhbGV0dGUsIGludCBpLCBib29sZWFuIGIpOworICAgICovCisgICAgCisgICAgcHJvdGVjdGVkIFBOR0ltYWdlV3JpdGVyKEltYWdlV3JpdGVyU3BpIGl3U3BpKSB7CisgICAgICAgIHN1cGVyKGl3U3BpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgY29udmVydFN0cmVhbU1ldGFkYXRhKElJT01ldGFkYXRhIGFyZzAsIEltYWdlV3JpdGVQYXJhbSBhcmcxKSB7CisgICAgICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJSU9NZXRhZGF0YSBjb252ZXJ0SW1hZ2VNZXRhZGF0YShJSU9NZXRhZGF0YSBhcmcwLCBJbWFnZVR5cGVTcGVjaWZpZXIgYXJnMSwgSW1hZ2VXcml0ZVBhcmFtIGFyZzIpIHsKKyAgICAgICAgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElJT01ldGFkYXRhIGdldERlZmF1bHRJbWFnZU1ldGFkYXRhKEltYWdlVHlwZVNwZWNpZmllciBhcmcwLCBJbWFnZVdyaXRlUGFyYW0gYXJnMSkgeworICAgICAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSUlPTWV0YWRhdGEgZ2V0RGVmYXVsdFN0cmVhbU1ldGFkYXRhKEltYWdlV3JpdGVQYXJhbSBhcmcwKSB7CisgICAgICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKElJT01ldGFkYXRhIHN0cmVhbU1ldGFkYXRhLCBJSU9JbWFnZSBpaW9JbWFnZSwgSW1hZ2VXcml0ZVBhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk91dHB1dCBub3QgYmVlbiBzZXQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaWlvSW1hZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW1hZ2UgZXF1YWxzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBBV1Q/Pz86IEkgdGhpbmsgdGhpcyBpcyBub3QgbmVlZGVkIGFueW1vcmUKKyAgICAgICAgLy8gaWYgKGlpb0ltYWdlLmhhc1Jhc3RlcigpICYmICFjYW5Xcml0ZVJhc3RlcnMoKSkgeworICAgICAgICAvLyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNhbid0IHdyaXRlIHJhc3RlciIpOworICAgICAgICAvL30vLyBJbWFnZU91dHB1dFN0cmVhbUltcGwKKyAgICAgICAgCisgICAgICAgIFJhc3RlciBzb3VyY2VSYXN0ZXI7CisgICAgICAgIFJlbmRlcmVkSW1hZ2UgaW1nID0gbnVsbDsKKyAgICAgICAgaWYgKCFpaW9JbWFnZS5oYXNSYXN0ZXIoKSkgeworICAgICAgICAgICAgaW1nID0gaWlvSW1hZ2UuZ2V0UmVuZGVyZWRJbWFnZSgpOworICAgICAgICAgICAgaWYgKGltZyBpbnN0YW5jZW9mIEJ1ZmZlcmVkSW1hZ2UpIHsKKyAgICAgICAgICAgICAgICBzb3VyY2VSYXN0ZXIgPSAoKEJ1ZmZlcmVkSW1hZ2UpIGltZykuZ2V0UmFzdGVyKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNvdXJjZVJhc3RlciA9IGltZy5nZXREYXRhKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzb3VyY2VSYXN0ZXIgPSBpaW9JbWFnZS5nZXRSYXN0ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIFNhbXBsZU1vZGVsIG1vZGVsID0gc291cmNlUmFzdGVyLmdldFNhbXBsZU1vZGVsKCk7CisgICAgICAgIGludCBzcmNXaWR0aCA9IHNvdXJjZVJhc3Rlci5nZXRXaWR0aCgpOworICAgICAgICBpbnQgc3JjSGVpZ2h0ID0gc291cmNlUmFzdGVyLmdldEhlaWdodCgpOworICAgICAgICBpbnQgbnVtQmFuZHMgPSBtb2RlbC5nZXROdW1CYW5kcygpOworICAgICAgICAKKyAgICAgICAgQ29sb3JNb2RlbCBjb2xvck1vZGVsID0gaW1nLmdldENvbG9yTW9kZWwoKTsKKyAgICAgICAgaW50IHBpeGVsU2l6ZSA9IGNvbG9yTW9kZWwuZ2V0UGl4ZWxTaXplKCk7CisgICAgICAgIGludCBieXRlUGl4ZWxTaXplID0gcGl4ZWxTaXplIC8gODsKKyAgICAgICAgaW50IGJpdERlcHRoID0gcGl4ZWxTaXplIC8gbnVtQmFuZHM7CisgICAgICAgIAorICAgICAgICAvLyBieXRlIHBlciBiYW5kCisgICAgICAgIGludCBicGIgPSBiaXREZXB0aCA+IDggPyAyIDogMTsKKyAgICAgICAgCisgICAgICAgIGJvb2xlYW4gaXNJbnRlcmxhY2UgPSB0cnVlOworICAgICAgICBpZiAocGFyYW0gaW5zdGFuY2VvZiBQTkdJbWFnZVdyaXRlclBhcmFtKSB7CisgICAgICAgICAgICBpc0ludGVybGFjZSA9ICgoUE5HSW1hZ2VXcml0ZXJQYXJhbSkgcGFyYW0pLmdldEludGVybGFjZSgpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpbnQgY29sb3JUeXBlID0gUE5HX0NPTE9SX1RZUEVfR1JBWTsKKyAgICAgICAgaW50W10gcGFsZXR0ZSA9IG51bGw7CisgICAgICAgIAorICAgICAgICBpZiAoY29sb3JNb2RlbCBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDEgJiYgYml0RGVwdGggIT0gMiAmJiBiaXREZXB0aCAhPSA0ICYmIGJpdERlcHRoICE9IDgpIHsKKy8vICAgICAgICAgICAgICBXcm9uZyBiaXREZXB0aC1udW1CYW5kcyBjb21wb3NpdGlvbgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJpbWFnZWlvLjEiKSk7Ly8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG51bUJhbmRzICE9IDEpIHsKKy8vICAgICAgICAgICAgICBXcm9uZyBiaXREZXB0aC1udW1CYW5kcyBjb21wb3NpdGlvbgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJpbWFnZWlvLjEiKSk7Ly8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBJbmRleENvbG9yTW9kZWwgaWNtID0gKEluZGV4Q29sb3JNb2RlbCkgY29sb3JNb2RlbDsKKyAgICAgICAgICAgIHBhbGV0dGUgPSBuZXcgaW50W2ljbS5nZXRNYXBTaXplKCldOworICAgICAgICAgICAgaWNtLmdldFJHQnMocGFsZXR0ZSk7CisgICAgICAgICAgICBjb2xvclR5cGUgPSBQTkdfQ09MT1JfVFlQRV9QTFRFOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKG51bUJhbmRzID09IDEpIHsKKyAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSAxICYmIGJpdERlcHRoICE9IDIgJiYgYml0RGVwdGggIT0gNCAmJiBiaXREZXB0aCAhPSA4ICYmIGJpdERlcHRoICE9IDE2KSB7CisvLyAgICAgICAgICAgICAgV3JvbmcgYml0RGVwdGgtbnVtQmFuZHMgY29tcG9zaXRpb24KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLmdldFN0cmluZygiaW1hZ2Vpby4xIikpOy8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbG9yVHlwZSA9IFBOR19DT0xPUl9UWVBFX0dSQVk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAobnVtQmFuZHMgPT0gMikgeworICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gMTYpIHsKKy8vICAgICAgICAgICAgICBXcm9uZyBiaXREZXB0aC1udW1CYW5kcyBjb21wb3NpdGlvbgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJpbWFnZWlvLjEiKSk7Ly8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgY29sb3JUeXBlID0gUE5HX0NPTE9SX1RZUEVfR1JBWV9BTFBIQTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChudW1CYW5kcyA9PSAzKSB7CisgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCAmJiBiaXREZXB0aCAhPSAxNikgeworLy8gICAgICAgICAgICAgIFdyb25nIGJpdERlcHRoLW51bUJhbmRzIGNvbXBvc2l0aW9uCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5nZXRTdHJpbmcoImltYWdlaW8uMSIpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgfQorICAgICAgICAgICAgY29sb3JUeXBlID0gUE5HX0NPTE9SX1RZUEVfUkdCOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKG51bUJhbmRzID09IDQpIHsKKyAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSA4ICYmIGJpdERlcHRoICE9IDE2KSB7CisgICAgICAgICAgICAgICAgLy9Xcm9uZyBiaXREZXB0aC1udW1CYW5kcyBjb21wb3NpdGlvbgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuZ2V0U3RyaW5nKCJpbWFnZWlvLjEiKSk7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbG9yVHlwZSA9IFBOR19DT0xPUl9UWVBFX1JHQkE7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIC8qID8/P0FXVDogSSB0aGluayB0aGlzIGlzIG5vdCBuZWVkZWQgYW55bW9yZQorICAgICAgICBpbnQgZGJ1ZmZlckxlbmdodCA9IGJ5dGVQaXhlbFNpemUgKiBpbWFnZUhlaWdodCAqIGltYWdlV2lkdGg7CisgICAgICAgIERhdGFCdWZmZXJCeXRlIGRidWZmZXIgPSBuZXcgRGF0YUJ1ZmZlckJ5dGUoZGJ1ZmZlckxlbmdodCk7CisKKyAgICAgICAgV3JpdGFibGVSYXN0ZXIgc2NhblJhc3RlciA9IFJhc3Rlci5jcmVhdGVJbnRlcmxlYXZlZFJhc3RlcihkYnVmZmVyLCBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCwgYnBiICogbnVtQmFuZHMKKyAgICAgICAgICAgICAgICAqIGltYWdlV2lkdGgsIGJwYiAqIG51bUJhbmRzLCBCQU5EX09GRlNFVFNbbnVtQmFuZHNdLCBudWxsKTsKKworICAgICAgICBzY2FuUmFzdGVyLnNldFJlY3QoKChCdWZmZXJlZEltYWdlKSBpbWFnZSkuZ2V0UmFzdGVyKCkvLyBpbWFnZS5nZXREYXRhKCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlQ2hpbGQoMCwgMCwgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQsIDAsIDAsIG51bGwpKTsKKyAgICAgICAgKi8KKworICAgICAgICBpZiAoREVCVUcpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKiByYXN0ZXI6IiArIHNvdXJjZVJhc3Rlcik7ICAgICAgICAKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKiBtb2RlbDoiICsgbW9kZWwpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqIHR5cGU6IiArIGNvbG9yVHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmIChtb2RlbCBpbnN0YW5jZW9mIFNpbmdsZVBpeGVsUGFja2VkU2FtcGxlTW9kZWwpIHsKKyAgICAgICAgICAgIERhdGFCdWZmZXJJbnQgaWJ1ZiA9IChEYXRhQnVmZmVySW50KXNvdXJjZVJhc3Rlci5nZXREYXRhQnVmZmVyKCk7CisgICAgICAgICAgICBpbnRbXSBwaXhlbHMgPSBpYnVmLmdldERhdGEoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gQ3JlYXRlIGEgYml0bWFwIHdpdGggdGhlIHBpeGVsCisgICAgICAgICAgICBibSA9IEJpdG1hcC5jcmVhdGVCaXRtYXAocGl4ZWxzLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBCaXRtYXAuQ29uZmlnLkFSR0JfODg4OCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIFVzZSBCaXRtYXAuY29tcHJlc3MoKSB0byB3cml0ZSB0aGUgaW1hZ2UKKyAgICAgICAgICAgIEltYWdlT3V0cHV0U3RyZWFtIGlvcyA9IChJbWFnZU91dHB1dFN0cmVhbSkgZ2V0T3V0cHV0KCk7CisgICAgICAgICAgICBJbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIgaW9zdyA9IG5ldyBJbWFnZU91dHB1dFN0cmVhbVdyYXBwZXIoaW9zKTsKKyAgICAgICAgICAgIGJtLmNvbXByZXNzKENvbXByZXNzRm9ybWF0LlBORywgMTAwLCBpb3N3KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vID8/P0FXVDogQWRkIHN1cHBvcnQgZm9yIG90aGVyIGNvbG9yIG1vZGVscworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkNvbG9yIG1vZGVsIG5vdCBzdXBwb3J0ZWQgeWV0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSW1hZ2VXcml0ZVBhcmFtIGdldERlZmF1bHRXcml0ZVBhcmFtKCkgeworICAgICAgICByZXR1cm4gbmV3IFBOR0ltYWdlV3JpdGVyUGFyYW0oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVdyaXRlclBhcmFtLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVdyaXRlclBhcmFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmYzYTAwMAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3BsdWdpbnMvcG5nL1BOR0ltYWdlV3JpdGVyUGFyYW0uamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIFZpc2tvdiBOaWtvbGF5CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5wbHVnaW5zLnBuZzsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uSW1hZ2VXcml0ZVBhcmFtOworCitwdWJsaWMgY2xhc3MgUE5HSW1hZ2VXcml0ZXJQYXJhbSBleHRlbmRzIEltYWdlV3JpdGVQYXJhbSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNJbnRlcmxhY2UgPSB0cnVlOworCisgICAgcHVibGljIFBOR0ltYWdlV3JpdGVyUGFyYW0oKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0SW50ZXJsYWNlKCkgeworICAgICAgICByZXR1cm4gaXNJbnRlcmxhY2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW50ZXJsYWNlKGJvb2xlYW4gYikgeworICAgICAgICBpc0ludGVybGFjZSA9IGI7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9wbHVnaW5zL3BuZy9QTkdJbWFnZVdyaXRlclNwaS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VXcml0ZXJTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZWVkMTRkCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vcGx1Z2lucy9wbmcvUE5HSW1hZ2VXcml0ZXJTcGkuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBWaXNrb3YgTmlrb2xheQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8ucGx1Z2lucy5wbmc7CisKK2ltcG9ydCBqYXZhLmF3dC5pbWFnZS5Db2xvck1vZGVsOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkRhdGFCdWZmZXJCeXRlOworaW1wb3J0IGphdmEuYXd0LmltYWdlLkluZGV4Q29sb3JNb2RlbDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlVHlwZVNwZWNpZmllcjsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLkltYWdlV3JpdGVyOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3BpLkltYWdlV3JpdGVyU3BpOworCitwdWJsaWMgY2xhc3MgUE5HSW1hZ2VXcml0ZXJTcGkgZXh0ZW5kcyBJbWFnZVdyaXRlclNwaSB7CisKKyAgICBwdWJsaWMgUE5HSW1hZ2VXcml0ZXJTcGkoKSB7CisgICAgICAgIHN1cGVyKCJJbnRlbCBDb3Jwb3JhdGlvbiIsLy8gdmVuZG9yTmFtZQorICAgICAgICAgICAgICAgICIxLjAiLC8vIHZlcnNpb24KKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICAgICAgICAgInBuZyIsICJQTkciIH0sLy8gbmFtZXMKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICAgICAgICAgInBuZyIsICJQTkciIH0sLy8gc3VmZml4ZXMKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICAgICAiaW1hZ2UvcG5nIiB9LC8vIE1JTUVUeXBlcworICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMucG5nLlBOR0ltYWdlV3JpdGVyIiwvLyB3cml0ZXJDbGFzc05hbWUKKyAgICAgICAgICAgICAgICBTVEFOREFSRF9PVVRQVVRfVFlQRSwvLyBvdXRwdXRUeXBlcworICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnBsdWdpbnMucG5nLlBOR0ltYWdlV3JpdGVyU3BpIiB9LC8vIHJlYWRlclNwaU5hbWVzCisgICAgICAgICAgICAgICAgZmFsc2UsLy8gc3VwcG9ydHNTdGFuZGFyZFN0cmVhbU1ldGFkYXRhRm9ybWF0CisgICAgICAgICAgICAgICAgbnVsbCwvLyBuYXRpdmVTdHJlYW1NZXRhZGF0YUZvcm1hdE5hbWUKKyAgICAgICAgICAgICAgICBudWxsLC8vIG5hdGl2ZVN0cmVhbU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lCisgICAgICAgICAgICAgICAgbnVsbCwvLyBleHRyYVN0cmVhbU1ldGFkYXRhRm9ybWF0TmFtZXMKKyAgICAgICAgICAgICAgICBudWxsLC8vIGV4dHJhU3RyZWFtTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzCisgICAgICAgICAgICAgICAgZmFsc2UsLy8gc3VwcG9ydHNTdGFuZGFyZEltYWdlTWV0YWRhdGFGb3JtYXQKKyAgICAgICAgICAgICAgICBudWxsLC8vIG5hdGl2ZUltYWdlTWV0YWRhdGFGb3JtYXROYW1lCisgICAgICAgICAgICAgICAgbnVsbCwvLyBuYXRpdmVJbWFnZU1ldGFkYXRhRm9ybWF0Q2xhc3NOYW1lCisgICAgICAgICAgICAgICAgbnVsbCwvLyBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXROYW1lcworICAgICAgICAgICAgICAgIG51bGwvLyBleHRyYUltYWdlTWV0YWRhdGFGb3JtYXRDbGFzc05hbWVzCisgICAgICAgICk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlSW1hZ2UoSW1hZ2VUeXBlU3BlY2lmaWVyIHR5cGUpIHsKKyAgICAgICAgYm9vbGVhbiBjYW5FbmNvZGUgPSB0cnVlOworCisgICAgICAgIGludCBudW1CYW5kcyA9IHR5cGUuZ2V0U2FtcGxlTW9kZWwoKS5nZXROdW1CYW5kcygpOworCisgICAgICAgIENvbG9yTW9kZWwgY29sb3JNb2RlbCA9IHR5cGUuZ2V0Q29sb3JNb2RlbCgpOworCisgICAgICAgIGludCBiaXREZXB0aCA9IGNvbG9yTW9kZWwuZ2V0UGl4ZWxTaXplKCkgLyBudW1CYW5kczsKKworICAgICAgICBpZiAoY29sb3JNb2RlbCBpbnN0YW5jZW9mIEluZGV4Q29sb3JNb2RlbCkgeworICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDEgJiYgYml0RGVwdGggIT0gMiAmJiBiaXREZXB0aCAhPSA0ICYmIGJpdERlcHRoICE9IDgpIHsKKyAgICAgICAgICAgICAgICBjYW5FbmNvZGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChudW1CYW5kcyAhPSAxKSB7CisgICAgICAgICAgICAgICAgY2FuRW5jb2RlID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAobnVtQmFuZHMgPT0gMSkgeworICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDEgJiYgYml0RGVwdGggIT0gMiAmJiBiaXREZXB0aCAhPSA0ICYmIGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gMTYpIHsKKyAgICAgICAgICAgICAgICBjYW5FbmNvZGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChudW1CYW5kcyA9PSAyKSB7CisgICAgICAgICAgICBpZiAoYml0RGVwdGggIT0gOCAmJiBiaXREZXB0aCAhPSAxNikgeworICAgICAgICAgICAgICAgIGNhbkVuY29kZSA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKG51bUJhbmRzID09IDMpIHsKKyAgICAgICAgICAgIGlmIChiaXREZXB0aCAhPSA4ICYmIGJpdERlcHRoICE9IDE2KSB7CisgICAgICAgICAgICAgICAgY2FuRW5jb2RlID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAobnVtQmFuZHMgPT0gNCkgeworICAgICAgICAgICAgaWYgKGJpdERlcHRoICE9IDggJiYgYml0RGVwdGggIT0gMTYpIHsKKyAgICAgICAgICAgICAgICBjYW5FbmNvZGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjYW5FbmNvZGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlV3JpdGVyIGNyZWF0ZVdyaXRlckluc3RhbmNlKE9iamVjdCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFBOR0ltYWdlV3JpdGVyKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGFyZzApIHsKKyAgICAgICAgcmV0dXJuICJEUkwgUE5HIGVuY29kZXIiOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL0ZpbGVJSVNTcGkuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9GaWxlSUlTU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDRmZGQ3NgotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9GaWxlSUlTU3BpLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VJbnB1dFN0cmVhbVNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkZpbGVJbWFnZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5GaWxlSW1hZ2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgRmlsZUlJU1NwaSBleHRlbmRzIEltYWdlSW5wdXRTdHJlYW1TcGkgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZW5kb3IgPSAiQXBhY2hlIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZXIgPSAiMC4xIjsKKworICAgIHB1YmxpYyBGaWxlSUlTU3BpKCkgeworICAgICAgICBzdXBlcih2ZW5kb3IsIHZlciwgRmlsZS5jbGFzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlSW5wdXRTdHJlYW0gY3JlYXRlSW5wdXRTdHJlYW1JbnN0YW5jZShPYmplY3QgaW5wdXQsIGJvb2xlYW4gdXNlQ2FjaGUsCisgICAgICAgICAgICBGaWxlIGNhY2hlRGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoRmlsZS5jbGFzcy5pc0luc3RhbmNlKGlucHV0KSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW1hZ2VJbnB1dFN0cmVhbSgoRmlsZSkgaW5wdXQpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBqYXZhLmlvLkZpbGUiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgcmV0dXJuICJGaWxlIElJUyBTcGkiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9GaWxlSU9TU3BpLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvRmlsZUlPU1NwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjZGE2YTEKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvRmlsZUlPU1NwaS5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnNwaTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uc3BpLkltYWdlT3V0cHV0U3RyZWFtU3BpOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkltYWdlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmltYWdlaW8uc3RyZWFtLkZpbGVJbWFnZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgRmlsZUlPU1NwaSBleHRlbmRzIEltYWdlT3V0cHV0U3RyZWFtU3BpIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmVuZG9yID0gIkFwYWNoZSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmVyID0gIjAuMSI7CisKKyAgICBwdWJsaWMgRmlsZUlPU1NwaSgpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yLCB2ZXIsIEZpbGUuY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbWFnZU91dHB1dFN0cmVhbSBjcmVhdGVPdXRwdXRTdHJlYW1JbnN0YW5jZShPYmplY3Qgb3V0cHV0LCBib29sZWFuIHVzZUNhY2hlLAorICAgICAgICAgICAgRmlsZSBjYWNoZURpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG91dHB1dCBpbnN0YW5jZW9mIEZpbGUpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUltYWdlT3V0cHV0U3RyZWFtKChGaWxlKSBvdXRwdXQpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm91dHB1dCBpcyBub3QgaW5zdGFuY2Ugb2YgRmlsZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIkZpbGUgSU9TIFNwaSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL0lucHV0U3RyZWFtSUlTU3BpLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvSW5wdXRTdHJlYW1JSVNTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDJmZWYwCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL0lucHV0U3RyZWFtSUlTU3BpLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VJbnB1dFN0cmVhbVNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS4qOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIElucHV0U3RyZWFtSUlTU3BpIGV4dGVuZHMgSW1hZ2VJbnB1dFN0cmVhbVNwaSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHZlbmRvciA9ICJBcGFjaGUiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHZlciA9ICIwLjEiOworCisgICAgcHVibGljIElucHV0U3RyZWFtSUlTU3BpKCkgeworICAgICAgICBzdXBlcih2ZW5kb3IsIHZlciwgSW5wdXRTdHJlYW0uY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIk91dHB1dCBTdHJlYW0gSU9TIFNwaSI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuVXNlQ2FjaGVGaWxlKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2VJbnB1dFN0cmVhbSBjcmVhdGVJbnB1dFN0cmVhbUluc3RhbmNlKE9iamVjdCBpbnB1dCwgYm9vbGVhbiB1c2VDYWNoZSwgRmlsZSBjYWNoZURpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgSW5wdXRTdHJlYW0pIHsKKyAgICAgICAgICAgIGlmICh1c2VDYWNoZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUNhY2hlSW1hZ2VJbnB1dFN0cmVhbSgoSW5wdXRTdHJlYW0pIGlucHV0LCBjYWNoZURpcik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWVtb3J5Q2FjaGVJbWFnZUlucHV0U3RyZWFtKChJbnB1dFN0cmVhbSkgaW5wdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk91dHB1dCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSW5wdXRTdHJlYW0iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvT3V0cHV0U3RyZWFtSU9TU3BpLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvT3V0cHV0U3RyZWFtSU9TU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGQxZTg4ZAotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9PdXRwdXRTdHJlYW1JT1NTcGkuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnguaW1hZ2Vpby5zcGk7CisKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnNwaS5JbWFnZU91dHB1dFN0cmVhbVNwaTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5JbWFnZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5GaWxlQ2FjaGVJbWFnZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5NZW1vcnlDYWNoZUltYWdlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBPdXRwdXRTdHJlYW1JT1NTcGkgZXh0ZW5kcyBJbWFnZU91dHB1dFN0cmVhbVNwaSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHZlbmRvciA9ICJBcGFjaGUiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHZlciA9ICIwLjEiOworCisgICAgcHVibGljIE91dHB1dFN0cmVhbUlPU1NwaSgpIHsKKyAgICAgICAgc3VwZXIodmVuZG9yLCB2ZXIsIE91dHB1dFN0cmVhbS5jbGFzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEltYWdlT3V0cHV0U3RyZWFtIGNyZWF0ZU91dHB1dFN0cmVhbUluc3RhbmNlKE9iamVjdCBvdXRwdXQsIGJvb2xlYW4gdXNlQ2FjaGUsIEZpbGUgY2FjaGVEaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvdXRwdXQgaW5zdGFuY2VvZiBPdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgICAgIGlmICh1c2VDYWNoZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUNhY2hlSW1hZ2VPdXRwdXRTdHJlYW0oKE91dHB1dFN0cmVhbSkgb3V0cHV0LCBjYWNoZURpcik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWVtb3J5Q2FjaGVJbWFnZU91dHB1dFN0cmVhbSgoT3V0cHV0U3RyZWFtKSBvdXRwdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk91dHB1dCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgT3V0cHV0U3RyZWFtIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbihMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiAiT3V0cHV0IFN0cmVhbSBJT1MgU3BpIjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Vc2VDYWNoZUZpbGUoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9SQUZJSVNTcGkuamF2YSBiL2F3dC9vcmcvYXBhY2hlL2hhcm1vbnkveC9pbWFnZWlvL3NwaS9SQUZJSVNTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTdlYjg3Ci0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL1JBRklJU1NwaS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgUnVzdGVtIFYuIFJhZmlrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnNwaTsKKworaW1wb3J0IGphdmF4LmltYWdlaW8uc3BpLkltYWdlSW5wdXRTdHJlYW1TcGk7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5pbWFnZWlvLnN0cmVhbS5GaWxlSW1hZ2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIFJBRklJU1NwaSBleHRlbmRzIEltYWdlSW5wdXRTdHJlYW1TcGkgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZW5kb3IgPSAiQXBhY2hlIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZXIgPSAiMC4xIjsKKworICAgIHB1YmxpYyBSQUZJSVNTcGkoKSB7CisgICAgICAgIHN1cGVyKHZlbmRvciwgdmVyLCBSYW5kb21BY2Nlc3NGaWxlLmNsYXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2VJbnB1dFN0cmVhbSBjcmVhdGVJbnB1dFN0cmVhbUluc3RhbmNlKE9iamVjdCBpbnB1dCwgYm9vbGVhbiB1c2VDYWNoZSwKKyAgICAgICAgICAgIEZpbGUgY2FjaGVEaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChSYW5kb21BY2Nlc3NGaWxlLmNsYXNzLmlzSW5zdGFuY2UoaW5wdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbWFnZUlucHV0U3RyZWFtKChSYW5kb21BY2Nlc3NGaWxlKSBpbnB1dCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiaW5wdXQgaXMgbm90IGFuIGluc3RhbmNlIG9mIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIlJhbmRvbUFjY2Vzc0ZpbGUgSUlTIFNwaSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL1JBRklPU1NwaS5qYXZhIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3BpL1JBRklPU1NwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5ZDM2NDkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zcGkvUkFGSU9TU3BpLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBSdXN0ZW0gVi4gUmFmaWtvdgorICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjIgJAorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54LmltYWdlaW8uc3BpOworCitpbXBvcnQgamF2YXguaW1hZ2Vpby5zcGkuSW1hZ2VPdXRwdXRTdHJlYW1TcGk7CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uSW1hZ2VPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YXguaW1hZ2Vpby5zdHJlYW0uRmlsZUltYWdlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgUkFGSU9TU3BpIGV4dGVuZHMgSW1hZ2VPdXRwdXRTdHJlYW1TcGkgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZW5kb3IgPSAiQXBhY2hlIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZXIgPSAiMC4xIjsKKworICAgIHB1YmxpYyBSQUZJT1NTcGkoKSB7CisgICAgICAgIHN1cGVyKHZlbmRvciwgdmVyLCBSYW5kb21BY2Nlc3NGaWxlLmNsYXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW1hZ2VPdXRwdXRTdHJlYW0gY3JlYXRlT3V0cHV0U3RyZWFtSW5zdGFuY2UoT2JqZWN0IG91dHB1dCwgYm9vbGVhbiB1c2VDYWNoZSwKKyAgICAgICAgICAgIEZpbGUgY2FjaGVEaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvdXRwdXQgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3NGaWxlKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbWFnZU91dHB1dFN0cmVhbSgoUmFuZG9tQWNjZXNzRmlsZSkgb3V0cHV0KTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJvdXRwdXQgaXMgbm90IGluc3RhbmNlIG9mIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gIlJhbmRvbUFjY2Vzc0ZpbGUgSU9TIFNwaSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3RyZWFtL1JhbmRvbUFjY2Vzc01lbW9yeUNhY2hlLmphdmEgYi9hd3Qvb3JnL2FwYWNoZS9oYXJtb255L3gvaW1hZ2Vpby9zdHJlYW0vUmFuZG9tQWNjZXNzTWVtb3J5Q2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NGY3YjJhCi0tLSAvZGV2L251bGwKKysrIGIvYXd0L29yZy9hcGFjaGUvaGFybW9ueS94L2ltYWdlaW8vc3RyZWFtL1JhbmRvbUFjY2Vzc01lbW9yeUNhY2hlLmphdmEKQEAgLTAsMCArMSwyMjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueC5pbWFnZWlvLnN0cmVhbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitwdWJsaWMgZmluYWwgY2xhc3MgUmFuZG9tQWNjZXNzTWVtb3J5Q2FjaGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCTE9DS19TSElGVCA9IDk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMT0NLX1NJWkUgPSAxIDw8IEJMT0NLX1NISUZUOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCTE9DS19NQVNLID0gQkxPQ0tfU0laRSAtIDE7CisgICAgCisgICAgcHJpdmF0ZSBsb25nIGxlbmd0aDsKKworICAgIHByaXZhdGUgaW50IGZpcnN0VW5kaXNwb3NlZCA9IDA7CisKKyAgICBwcml2YXRlIEFycmF5TGlzdDxieXRlW10+IGJsb2NrcyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworCisgICAgcHVibGljIFJhbmRvbUFjY2Vzc01lbW9yeUNhY2hlKCkgeworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgYmxvY2tzLmNsZWFyKCk7CisgICAgICAgIGxlbmd0aCA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGdyb3cobG9uZyBwb3MpIHsKKyAgICAgICAgaW50IGJsb2Nrc05lZWRlZCA9IChpbnQpKHBvcyA+PiBCTE9DS19TSElGVCkgLSBibG9ja3Muc2l6ZSgpICsgMTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpIDwgYmxvY2tzTmVlZGVkOyBpKyspIHsKKyAgICAgICAgICAgIGJsb2Nrcy5hZGQobmV3IGJ5dGVbQkxPQ0tfU0laRV0pOworICAgICAgICB9CisKKyAgICAgICAgbGVuZ3RoID0gcG9zICsgMTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwdXREYXRhKGludCBvbmVCeXRlLCBsb25nIHBvcykgeworICAgICAgICBpZiAocG9zID49IGxlbmd0aCkgeworICAgICAgICAgICAgZ3Jvdyhwb3MpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGJsb2NrID0gYmxvY2tzLmdldCgoaW50KShwb3MgPj4gQkxPQ0tfU0hJRlQpKTsKKyAgICAgICAgYmxvY2tbKGludCkocG9zICYgQkxPQ0tfTUFTSyldID0gKGJ5dGUpIG9uZUJ5dGU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHV0RGF0YShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQsIGxvbmcgcG9zKSB7CisgICAgICAgIGlmIChjb3VudCA+IGJ1ZmZlci5sZW5ndGggLSBvZmZzZXQgfHwgY291bnQgPCAwIHx8IG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvdW50ID09IDApeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBsYXN0UG9zID0gcG9zICsgY291bnQgLSAxOworICAgICAgICBpZiAobGFzdFBvcyA+PSBsZW5ndGgpIHsKKyAgICAgICAgICAgIGdyb3cobGFzdFBvcyk7CisgICAgICAgIH0KKworICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CisgICAgICAgICAgICBieXRlW10gYmxvY2sgPSBibG9ja3MuZ2V0KChpbnQpKHBvcyA+PiBCTE9DS19TSElGVCkpOworICAgICAgICAgICAgaW50IGJsb2NrT2Zmc2V0ID0gKGludCkocG9zICYgQkxPQ0tfTUFTSyk7CisgICAgICAgICAgICBpbnQgdG9Db3B5ID0gTWF0aC5taW4oQkxPQ0tfU0laRSAtIGJsb2NrT2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgb2Zmc2V0LCBibG9jaywgYmxvY2tPZmZzZXQsIHRvQ29weSk7CisgICAgICAgICAgICBwb3MgKz0gdG9Db3B5OworICAgICAgICAgICAgY291bnQgLT0gdG9Db3B5OworICAgICAgICAgICAgb2Zmc2V0ICs9IHRvQ29weTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0RGF0YShsb25nIHBvcykgeworICAgICAgICBpZiAocG9zID49IGxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGJsb2NrID0gYmxvY2tzLmdldCgoaW50KShwb3MgPj4gQkxPQ0tfU0hJRlQpKTsKKyAgICAgICAgcmV0dXJuIGJsb2NrWyhpbnQpKHBvcyAmIEJMT0NLX01BU0spXSAmIDB4RkY7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXREYXRhKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCwgbG9uZyBwb3MpIHsKKyAgICAgICAgaWYgKGNvdW50ID4gYnVmZmVyLmxlbmd0aCAtIG9mZnNldCB8fCBjb3VudCA8IDAgfHwgb2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvcyA+PSBsZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb3VudCArIHBvcyA+IGxlbmd0aCkgeworICAgICAgICAgICAgY291bnQgPSAoaW50KSAobGVuZ3RoIC0gcG9zKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBibG9jayA9IGJsb2Nrcy5nZXQoKGludCkocG9zID4+IEJMT0NLX1NISUZUKSk7CisgICAgICAgIGludCBuYnl0ZXMgPSBNYXRoLm1pbihjb3VudCwgQkxPQ0tfU0laRSAtIChpbnQpKHBvcyAmIEJMT0NLX01BU0spKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9jaywgKGludCkocG9zICYgQkxPQ0tfTUFTSyksIGJ1ZmZlciwgb2Zmc2V0LCBuYnl0ZXMpOworCisgICAgICAgIHJldHVybiBuYnl0ZXM7CisgICAgfQorICAgIC8qCisgICAgcHVibGljIHZvaWQgc2Vlayhsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvcyA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic2VlayBwb3NpdGlvbiBpcyBuZWdhdGl2ZSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zID0gcG9zOyAKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRnVsbHkoYnl0ZVtdIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZEZ1bGx5KGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKDAgPD0gb2Zmc2V0ICYmIG9mZnNldCA8PSBidWZmZXIubGVuZ3RoICYmIDAgPD0gY291bnQgJiYgY291bnQgPD0gYnVmZmVyLmxlbmd0aCAtIG9mZnNldCkgeworICAgICAgICAgICAgd2hpbGUgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSByZWFkKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSByZXN1bHQ7CisgICAgICAgICAgICAgICAgICAgIGNvdW50IC09IHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldEZpbGVQb2ludGVyKCkgeworICAgICAgICByZXR1cm4gcG9zOworICAgIH0KKyovCisKKyAgICBwdWJsaWMgdm9pZCBmcmVlQmVmb3JlKGxvbmcgcG9zKSB7CisgICAgICAgIGludCBibG9ja0lkeCA9IChpbnQpKHBvcyA+PiBCTE9DS19TSElGVCk7CisgICAgICAgIGlmIChibG9ja0lkeCA8PSBmaXJzdFVuZGlzcG9zZWQpIHsgLy8gTm90aGluZyB0byBkbworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGZpcnN0VW5kaXNwb3NlZDsgaSA8IGJsb2NrSWR4OyBpKyspIHsKKyAgICAgICAgICAgIGJsb2Nrcy5zZXQoaSwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBmaXJzdFVuZGlzcG9zZWQgPSBibG9ja0lkeDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGFwcGVuZERhdGEoSW5wdXRTdHJlYW0gaXMsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBzdGFydFBvcyA9IGxlbmd0aDsKKyAgICAgICAgbG9uZyBsYXN0UG9zID0gbGVuZ3RoICsgY291bnQgLSAxOworICAgICAgICBncm93KGxhc3RQb3MpOyAvLyBDaGFuZ2VzIGxlbmd0aAorCisgICAgICAgIGludCBibG9ja0lkeCA9IChpbnQpKHN0YXJ0UG9zID4+IEJMT0NLX1NISUZUKTsKKyAgICAgICAgaW50IG9mZnNldCA9IChpbnQpIChzdGFydFBvcyAmIEJMT0NLX01BU0spOworCisgICAgICAgIGludCBieXRlc0FwcGVuZGVkID0gMDsKKworICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CisgICAgICAgICAgICBieXRlW10gYmxvY2sgPSBibG9ja3MuZ2V0KGJsb2NrSWR4KTsKKyAgICAgICAgICAgIGludCB0b0NvcHkgPSBNYXRoLm1pbihCTE9DS19TSVpFIC0gb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICBjb3VudCAtPSB0b0NvcHk7CisKKyAgICAgICAgICAgIHdoaWxlICh0b0NvcHkgPiAwKSB7CisgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IGlzLnJlYWQoYmxvY2ssIG9mZnNldCwgdG9Db3B5KTsKKworICAgICAgICAgICAgICAgIGlmIChieXRlc1JlYWQgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSAoY291bnQgLSBieXRlc0FwcGVuZGVkKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGVzQXBwZW5kZWQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdG9Db3B5IC09IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICBvZmZzZXQgKz0gYnl0ZXNSZWFkOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBibG9ja0lkeCsrOworICAgICAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBnZXREYXRhKE91dHB1dFN0cmVhbSBvcywgaW50IGNvdW50LCBsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvcyArIGNvdW50ID4gbGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiQXJndW1lbnQgb3V0IG9mIGNhY2hlIik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYmxvY2tJZHggPSAoaW50KShwb3MgPj4gQkxPQ0tfU0hJRlQpOworICAgICAgICBpbnQgb2Zmc2V0ID0gKGludCkgKHBvcyAmIEJMT0NLX01BU0spOworICAgICAgICBpZiAoYmxvY2tJZHggPCBmaXJzdFVuZGlzcG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJUaGUgcmVxdWVzdGVkIGRhdGEgYXJlIGFscmVhZHkgZGlzcG9zZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgIGJ5dGVbXSBibG9jayA9IGJsb2Nrcy5nZXQoYmxvY2tJZHgpOworICAgICAgICAgICAgaW50IHRvV3JpdGUgPSBNYXRoLm1pbihCTE9DS19TSVpFIC0gb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICBvcy53cml0ZShibG9jaywgb2Zmc2V0LCB0b1dyaXRlKTsKKworICAgICAgICAgICAgYmxvY2tJZHgrKzsKKyAgICAgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgICAgICBjb3VudCAtPSB0b1dyaXRlOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYXd0L3Jlc291cmNlcy9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2ludGVybmFsL25scy9tZXNzYWdlcy5wcm9wZXJ0aWVzIGIvYXd0L3Jlc291cmNlcy9vcmcvYXBhY2hlL2hhcm1vbnkvYXd0L2ludGVybmFsL25scy9tZXNzYWdlcy5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNjQ3ZTkKLS0tIC9kZXYvbnVsbAorKysgYi9hd3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9hd3QvaW50ZXJuYWwvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMKQEAgLTAsMCArMSw0OTUgQEAKKyMgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisjIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisjICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisjIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjICAKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgIAorIyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisjIAorCisjIG1lc3NhZ2VzIGZvciBFTiBsb2NhbGUKK2F3dC4wMD1Gb250UmVuZGVyQ29udGV4dCBpcyBudWxsCithd3QuMDE9J3swfScgcGFyYW1ldGVyIGlzIG51bGwKK2F3dC4wMj0nezB9JyBwYXJhbWV0ZXIgaGFzIHplcm8gbGVuZ3RoCithd3QuMDM9J3swfScgaXRlcmF0b3IgcGFyYW1ldGVyIGlzIG51bGwKK2F3dC4wND0nezB9JyBpdGVyYXRvciBwYXJhbWV0ZXIgaGFzIHplcm8gbGVuZ3RoCithd3QuMDU9T3BlcmF0aW9uIGNhbm5vdCBiZSBudWxsCithd3QuMDY9VW5leHBlY3RlZCB0eXBlIG9mIHRoZSBpbnRlcm5hbCBkYXRhIGJ1ZmZlcgorYXd0LjA3PVRyYW5zZmVyIGRhdGEgaXMgbm90IGF2YWlsYWJsZQorYXd0LjA4PXhmbGQgcGFyc2Ugc3RyaW5nIGVycm9yOiB7MH0KK2F3dC4wOT1taW4gcmFuZ2UgYm91bmQgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG1heCByYW5nZSBib3VuZAorYXd0LjBBPUNhbm5vdCB1c2UgU2luZ2xlUGl4ZWRQYWNrZWRTYW1wbGVNb2RlbCBmb3IgYnBwID0gezB9Cithd3QuMEI9V3JvbmcgY29sb3IgbW9kZWwgY3JlYXRlZCBmb3IgZHJhd2FibGUKK2F3dC4wQz1Vbmtub3duIHZpc3VhbCBjbGFzcworYXd0LjBEPUludmFsaWQgdHJhbnNwYXJlbmN5Cithd3QuMEU9RGltZW5zaW9ucyBvZiB0aGUgaW1hZ2Ugc2hvdWxkIGJlIHBvc2l0aXZlCithd3QuMEY9Q2Fubm90IG9wZW4gZGlzcGxheSAnezB9JworYXd0LjEwPU9ubHkgMzItYml0IGZvcm1hdCBpcyBzdXBwb3J0ZWQgZm9yIHdpbmRvdyBzdGF0ZSBvcGVyYXRpb25zLgorYXd0LjExPUludmFsaWQga2V5IGNvZGUKK2F3dC4xMj1YVGVzdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHlvdXIgWCBzZXJ2ZXJcIQorYXd0LjEzPUNhbm5vdCBhbGxvY2F0ZSBjb2xvciBuYW1lZCAnezB9JworYXd0LjE0PVRyYW5zZmVyIGRhdGEgaXMgbm90IGF2YWlsYWJsZQorYXd0LjE1PUNhbiBub3QgZ2V0IG1vbml0b3IgaW5mbworYXd0LjE2PUNhbiBub3QgY3JlYXRlIERDIGZvciBkZXZpY2UKK2F3dC4xNz1Vbmtub3duIENvbXBvc2l0ZSB0eXBlIDogezB9Cithd3QuMTg9VHJhbnNwYXJlbmN5IGlzIG5vdCBzdXBwb3J0ZWQKK2F3dC4xOT1JbGxlZ2FsIHNpemUgb2Ygdm9sYXRpbGUgaW1hZ2UKK2F3dC4xQT1GYWlsZWQgdG8gcmVnaXN0ZXIgd2luZG93IGNsYXNzIHswfSBHZXRMYXN0RXJyb3IgcmV0dXJuZWQgezF9Cithd3QuMUI9SW52YWxpZCBrZXkgY29kZQorYXd0LjFDPUZhaWx1cmUgdG8gY3JlYXRlIEphdmFXaW5kb3cgR2V0TGFzdEVycm9yIHJldHVybmVkIHswfQorYXd0LjFEPUNhbm5vdCBnZXQgZGF0YSBmcm9tIE9MRSBjbGlwYm9hcmQKK2F3dC4xRT1BdHRlbXB0IHRvIHJlcGxhY2UgV2luZG93UHJvYyBoYW5kbGVyCithd3QuMUY9V2FpdGluZyBmb3IgcmVzb3VyY2UgYWNjZXNzIHRocmVhZCBpbnRlcnJ1cHRlZCBub3QgZnJvbSB1bmxvY2sgbWV0aG9kCithd3QuMjA9Q2FuJ3QgdW5sb2NrIG5vdCBsb2NrZWQgcmVzb3VyY2UKK2F3dC4yMT1Ob3Qgb3duZXIgY2FuJ3QgdW5sb2NrIHJlc291cmNlCithd3QuMjI9Tm90IG93bmVyIGNhbid0IGZyZWUgcmVzb3VyY2UKK2F3dC4yMz1PbmUgdGhyZWFkIGNhbid0IHN0b3JlIHN0YXRlIHNldmVyYWwgdGltZXMgaW4gYSByb3cKK2F3dC4yND1Pd25lciBjYW4ndCBvdmVyd3JpdGUgcmVzb3VyY2Ugc3RhdGUuIExvY2sgb3BlcmF0aW9ucyBtYXkgYmUgbG9zdAorYXd0LjI1PU5vIHN0YXRlIHN0b3JlZCBmb3IgY3VycmVudCB0aHJlYWQKK2F3dC4yNj1TaHV0ZG93biB0aHJlYWQgd2FzIGludGVycnVwdGVkIHdoaWxlIHN0YXJ0aW5nCithd3QuMjc9U2h1dGRvd24gdGhyZWFkIHdhcyBpbnRlcnJ1cHRlZCB3aGlsZSBzdG9wcGluZworYXd0LjI4PWJhZCBpbmRleDogezB9Cithd3QuMjk9SW52YWxpZCByYW5nZQorYXd0LjJBPVBvc2l0aW9uIG5vdCByZXByZXNlbnRlZCBieSB2aWV3Cithd3QuMkI9Tm8gd29yZCBhdCB7MH0KK2F3dC4yQz1JbnZhbGlkIHBvc2l0aW9uOiB7MH0KK2F3dC4yRD1JbnZhbGlkIGRpcmVjdGlvbgorYXd0LjJFPXswfSBub3QgaW4gcmFuZ2UgezF9LHsyfQorYXd0LjJGPU5vIG1vcmUgd29yZHMKK2F3dC4zMD13cm9uZyBudW1iZXIgb2YgZWxlbWVudHMgdG8gY29weTogezB9LCBzaXplOiB7MX0KK2F3dC4zMT1ubyByb29tIHRvIGNvcHk6IHswfSwgc2l6ZTogezF9Cithd3QuMzI9U3RyaW5nOiAnezB9JyBkb2VzIG5vdCBmaXQKK2F3dC4zMz1pbmRleCBpcyBvdXQgb2YgcmFuZ2UKK2F3dC4zND1Jbml0aWFsIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYXJyYXkgaXMgd3Jvbmc6IHswfQorYXd0LjM1PVdyb25nIG51bWJlciBvZiBlbGVtZW50cyB0byBjb3B5OiB7MH0KK2F3dC4zNj1Xcm9uZyBzZWdtZW50Cithd3QuMzc9VW5rbm93biAgY29tcG9zaXRlIHR5cGUgezB9Cithd3QuMzg9UHJvcGVydHkgbmFtZSBpcyBub3QgZGVmaW5lZAorYXd0LjM5PVRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgaW1hZ2Ugb2J0YWluZWQgZnJvbSBJbWFnZVByb2R1Y2VyCithd3QuM0E9Q29sb3IgTW9kZWwgaXMgbnVsbAorYXd0LjNCPUluY29ycmVjdCBJbWFnZUNvbnN1bWVyIGNvbXBsZXRpb24gc3RhdHVzCithd3QuM0M9VW5rbm93biBQTkcgY29sb3IgdHlwZQorYXd0LjNEPVVua25vd24gY29sb3JzcGFjZQorYXd0LjNFPUNsb25lIG5vdCBzdXBwb3J0ZWQKK2F3dC4zRj1JbnZhbGlkIGJhc2VsaW5lIGluZGV4Cithd3QuNDA9V3JvbmcgbnVtYmVyIG9mIG1ldHJpY3NcIQorYXd0LjQxPUZvbnQgcmV0dXJuZWQgdW5zdXBwb3J0ZWQgdHlwZSBvZiBsaW5lIG1ldHJpY3MuIFRoaXMgY2FzZSBpcyBrbm93biwgYnV0IG5vdCBzdXBwb3J0ZWQgeWV0LgorYXd0LjQyPVRleHRIaXRJbmZvIG91dCBvZiByYW5nZQorYXd0LjQzPWdseXBoSW5kZXggaXMgb3V0IG9mIHZlY3RvcidzIGxpbWl0cworYXd0LjQ0PWJlZ2luR2x5cGhJbmRleCBpcyBvdXQgb2YgdmVjdG9yJ3MgcmFuZ2UKK2F3dC40NT1udW1FbnRyaWVzIGlzIG91dCBvZiB2ZWN0b3IncyByYW5nZQorYXd0LjQ2PWxlbmd0aCBvZiBzZXRQb3NpdGlvbnMgYXJyYXkgZGlmZmVycyBmcm9tIHRoZSBsZW5ndGggb2YgcG9zaXRpb25zIGFycmF5Cithd3QuNDc9Rmlyc3QgYXJndW1lbnQgc2hvdWxkIGJlIGJ5dGUgb3Igc2hvcnQgYXJyYXkKK2F3dC40OD1UaGUgc3JjSW4gcmFzdGVyIGlzIGluY29tcGF0aWJsZSB3aXRoIHNyYyBDb2xvck1vZGVsCithd3QuNDk9VGhlIGRzdEluIHJhc3RlciBpcyBpbmNvbXBhdGlibGUgd2l0aCBkc3QgQ29sb3JNb2RlbAorYXd0LjRBPVRoZSBkc3RPdXQgcmFzdGVyIGlzIGluY29tcGF0aWJsZSB3aXRoIGRzdCBDb2xvck1vZGVsCithd3QuNEI9SXRlcmF0b3Igb3V0IG9mIGJvdW5kcworYXd0LjRDPUludmFsaWQgTXVsdGlSZWN0QXJlYSBpbiBtZXRob2QgezB9Cithd3QuNEQ9VGhlIHJhc3RlciBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGlzIENvbG9yTW9kZWwKK2F3dC40RT1Vbmtub3duIG5hdGl2ZSBwbGF0Zm9ybS4KK2F3dC40Rj1EYXRhIGlzIG5vdCBhdmFpbGFibGUKK2F3dC41MD1JdGVyYXRvciBpcyByZWFkLW9ubHkKK2F3dC41MT1Db21wb25lbnQgZXhwZWN0ZWQgdG8gYmUgYSBwYXJlbnQKK2F3dC41Mj1UaW1lIGludGVydmFsIGNhbid0IGJlIDw9IDAKK2F3dC41Mz1IYW5kbGVyIGNhbid0IGJlIG51bGwKK2F3dC41ND1LZXkgZXZlbnQgZm9yIHVuZm9jdXNlZCBjb21wb25lbnQKK2F3dC41NT1Eb3VibGUgbW91c2UgZW50ZXIgZXZlbnQgZm9yIGNvbXBvbmVudAorYXd0LjU2PURvdWJsZSBtb3VzZSBleGl0IGV2ZW50IGZvciBjb21wb25lbnQKK2F3dC41Nz1Eb3VibGUgZm9jdXMgZ2FpbmVkIGV2ZW50IGZvciBjb21wb25lbnQKK2F3dC41OD1Eb3VibGUgZm9jdXMgbG9zdCBldmVudCBmb3IgY29tcG9uZW50Cithd3QuNTk9QXBwbGljYXRpb24gaGFzIHJ1biBvdXQgb2YgY29udGV4dCB0aHJlYWQgZ3JvdXAKK2F3dC41QT1EZWZhdWx0IGNsYXNzIGZvciBQcmludGVySm9iIGlzIG5vdCBmb3VuZAorYXd0LjVCPU5vIGFjY2VzcyB0byBkZWZhdWx0IGNsYXNzIGZvciBQcmludGVySm9iCithd3QuNUM9SW5zdGFudGlhdGlvbiBleGNlcHRpb24gZm9yIFByaW50ZXJKb2IKK2F3dC41RD17MH0gaXMgbm90IHN1cHBvcnRlZAorYXd0LjVFPXBhZ2VJbmRleCBpcyBtb3JlIHRoYW4gYm9vayBzaXplCithd3QuNUY9d3Jvbmcgb3JpZW50YXRpb24KK2F3dC42MD1XaWR0aCBhbmQgSGVpZ2h0IG11c3RuJ3QgYmUgZXF1YWwgemVybyBib3RoCithd3QuNjE9VW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiB7MH0KK2F3dC42Mj1Xcm9uZyBtYXNrIDogezB9Cithd3QuNjM9Q29vcmRpbmF0ZXMgYXJlIG5vdCBpbiBib3VuZHMKK2F3dC42ND1UaGUgbnVtYmVyIG9mIHRoZSBiYW5kcyBpbiB0aGUgc3Vic2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGJhbmRzIGluIHRoZSBzYW1wbGUgbW9kZWwKK2F3dC42NT1udWxsIGFyZ3VtZW50Cithd3QuNjY9SW52YWxpZCBmb3JtYXQKK2F3dC42Nz1zdWJjbGFzcyBpcyBub3QgZGVyaXZlZCBmcm9tIEFXVEtleVN0cm9rZQorYXd0LjY4PXN1YmNsYXNzIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQKK2F3dC42OT1jb2x1bW5zIGxlc3MgdGhhbiB6ZXJvLgorYXd0LjZBPXJvd3MgbGVzcyB0aGFuIHplcm8uCithd3QuNkI9UXVldWUgc3RhY2sgaXMgZW1wdHkKK2F3dC42Qz1FdmVudCBxdWV1ZSBzdGFjayBpcyBicm9rZW4KK2F3dC42RD1Qb2ludCBpcyBudWxsCithd3QuNkU9Q29sb3IgaXMgbnVsbAorYXd0LjZGPUluZGV4IGxlc3MgdGhhbiB6ZXJvCithd3QuNzA9TWVudUl0ZW0gaXMgbnVsbAorYXd0LjcxPVBhcmVudCBpcyBudWxsCithd3QuNzI9S2V5IGV2ZW50IGZvciB1bmZvY3VzZWQgY29tcG9uZW50Cithd3QuNzM9bm8gc3VjaCBpdGVtCithd3QuNzQ9SW5wdXQgcGFyYW1ldGVycyBhIGFuZCBiIHNob3VsZCBub3QgYmUgbnVsbAorYXd0Ljc1PXJvd3MgYW5kIGNvbHMgY2Fubm90IGJvdGggYmUgemVybworYXd0Ljc2PXJvd3MgYW5kIGNvbHMgY2Fubm90IGJlIG5lZ2F0aXZlCithd3QuNzc9ZGVmYXVsdCBmb2N1cyB0cmF2ZXJzYWwgcG9saWN5IGNhbm5vdCBiZSBudWxsCithd3QuNzg9aW52YWxpZCBmb2N1cyB0cmF2ZXJzYWwga2V5IGlkZW50aWZpZXIKK2F3dC43OT1jYW5ub3Qgc2V0IG51bGwgZm9jdXMgdHJhdmVyc2FsIGtleQorYXd0LjdBPWZvY3VzIHRyYXZlcnNhbCBrZXlzIGNhbm5vdCBtYXAgdG8gS0VZX1RZUEVEIGV2ZW50cworYXd0LjdCPWZvY3VzIHRyYXZlcnNhbCBrZXlzIG11c3QgYmUgdW5pcXVlIGZvciBhIENvbXBvbmVudAorYXd0LjdDPXRoaXMgS2V5Ym9hcmRGb2N1c01hbmFnZXIgaXMgbm90IGluc3RhbGxlZCBpbiB0aGUgY3VycmVudCB0aHJlYWQncyBjb250ZXh0Cithd3QuN0Q9UHJvcGVydHkgbmFtZSBpcyBudWxsCithd3QuN0U9aW52YWxpZCBob3RTcG90Cithd3QuN0Y9QWRkTGF5b3V0Q29tcG9uZW50OiBhdHRlbXB0IHRvIGFkZCBudWxsIGNvbXBvbmVudAorYXd0LjgwPUFkZExheW91dENvbXBvbmVudDogY29uc3RyYWludCBvYmplY3QgbXVzdCBiZSBHcmlkQmFnQ29uc3RyYWludHMKK2F3dC44MT1BZGRMYXlvdXRDb21wb25lbnQ6IHswfQorYXd0LjgyPVJlbW92ZUxheW91dENvbXBvbmVudDogYXR0ZW1wdCB0byByZW1vdmUgbnVsbCBjb21wb25lbnQKK2F3dC44Mz1TZXRDb25zdHJhaW50czogYXR0ZW1wdCB0byBnZXQgY29uc3RyYWludHMgb2YgbnVsbCBjb21wb25lbnQKK2F3dC44ND1TZXRDb25zdHJhaW50czogYXR0ZW1wdCB0byBzZXQgbnVsbCBjb25zdHJhaW50cworYXd0Ljg1PVNldENvbnN0cmFpbnRzOiB7MH0KK2F3dC44Nj1NaW5pbXVtTGF5b3V0U2l6ZTogezB9Cithd3QuODc9UHJlZmVycmVkTGF5b3V0U2l6ZTogezB9Cithd3QuODg9TGF5b3V0Q29udGFpbmVyOiB7MH0KK2F3dC44OT1Mb29rdXBDb25zdHJhaW50czogYXR0ZW1wdCB0byBnZXQgY29uc3RyYWludHMgb2YgbnVsbCBjb21wb25lbnQKK2F3dC44QT1BZGp1c3RGb3JHcmF2aXR5OiBhdHRlbXB0IHRvIHVzZSBudWxsIGNvbnN0cmFpbnRzCithd3QuOEI9QWRqdXN0Rm9yR3Jhdml0eTogYXR0ZW1wdCB0byB1c2UgbnVsbCByZWN0YW5nbGUKK2F3dC44Qz1BZGp1c3RGb3JHcmF2aXR5OiB7MH0KK2F3dC44RD1SRU1JTkRFUiBjb21wb25lbnQgZXhwZWN0ZWQgYWZ0ZXIgUkVMQVRJVkUgb25lCithd3QuOEU9Y29tcG9uZW50IGlzIG91dCBvZiBncmlkJ3MgcmFuZ2UKK2F3dC44Rj1XZWlnaHRzJyBvdmVycmlkZXMgYXJyYXkgaXMgdG9vIGxvbmcKK2F3dC45MD1MZW5ndGhzJyBvdmVycmlkZXMgYXJyYXkgaXMgdG9vIGxvbmcKK2F3dC45MT1VbnN1cHBvcnRlZCBjb25zdHJhaW50cyBvYmplY3Q6IHswfQorYXd0LjkyPUNvbnN0cmFpbnRzIG9iamVjdCBtdXN0IGJlIFN0cmluZworYXd0LjkzPWNhbm5vdCBnZXQgY29tcG9uZW50OiBpbnZhbGlkIGNvbnN0cmFpbnQ6IHswfQorYXd0Ljk0PXRyYW5zZm9ybSBjYW4gbm90IGJlIG51bGwKK2F3dC45NT1Xcm9uZyBzdGFydCBpbmRleDogezB9Cithd3QuOTY9V3JvbmcgZmluaXNoIGluZGV4OiB7MH0KK2F3dC45Nz1Xcm9uZyByYW5nZSBsZW5ndGg6IHswfQorYXd0Ljk4PVdyb25nIGNvdW50IHZhbHVlLCBjYW4gbm90IGJlIG5lZ2F0aXZlOiB7MH0KK2F3dC45OT1Xcm9uZyBbc3RhcnQgKyBjb3VudF0gaXMgb3V0IG9mIHJhbmdlOiB7MH0KK2F3dC45QT1VbnN1cHBvcnRlZCBmb250IGZvcm1hdAorYXd0LjlCPUNhbid0IGNyZWF0ZSBmb250IC0gYmFkIGZvbnQgZGF0YQorYXd0LjlDPXdyb25nIHZhbHVlIG9mIEdyaWRCYWdDb25zdHJhaW50czogezB9Cithd3QuOUQ9cmVsYXRpdmUgZ3JpZCBzaXplIHBhcmFtZXRlciBnb2VzIGFmdGVyIGFic29sdXRlIGdyaWQgY29vcmRpbmF0ZQorYXd0LjlFPXdyb25nIHZhbHVlcyBzdW0gb2YgR3JpZEJhZ0NvbnN0cmFpbnRzJyBncmlkd2lkdGggYW5kIGdyaWR4Cithd3QuOUY9d3JvbmcgdmFsdWVzIHN1bSBvZiBHcmlkQmFnQ29uc3RyYWludHMnIGdyaWRoZWlnaHQgYW5kIGdyaWR5Cithd3QuMTAwPWNvbXBvbmVudCBoYXMgUkVMQVRJVkUgd2lkdGggYW5kIGhlaWdodAorYXd0LjEwMT1wb3NpdGlvbiBsZXNzIHRoYW4gemVyby4KK2F3dC4xMDI9Y29sdW1ucyBsZXNzIHRoYW4gemVyby4KK2F3dC4xMDM9aXRlbSBpcyBudWxsCithd3QuMTA0PWl0ZW0gZG9lc24ndCBleGlzdCBpbiB0aGUgY2hvaWNlIG1lbnUKK2F3dC4xMDU9aW5kZXggbGVzcyB0aGFuIHplcm8KK2F3dC4xMDY9c3BlY2lmaWVkIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGl0ZW1zCithd3QuMTA3PUNvbG9yIHBhcmFtZXRlciBvdXRzaWRlIG9mIGV4cGVjdGVkIHJhbmdlOiBjb21wb25lbnQgezB9Cithd3QuMTA4PUFscGhhIHZhbHVlIG91dHNpZGUgb2YgZXhwZWN0ZWQgcmFuZ2UKK2F3dC4xMDk9Q29sb3IgcGFyYW1ldGVyIG91dHNpZGUgb2YgZXhwZWN0ZWQgcmFuZ2UKK2F3dC4xMEE9UHJpb3JpdHkgbXVzdCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMSwgaW5jbHVzaXZlCithd3QuMTBCPWFDb250YWluZXIgYW5kIGFDb21wb25lbnQgY2Fubm90IGJlIG51bGwKK2F3dC4xMEM9YUNvbnRhaW5lciBpcyBub3QgYSBmb2N1cyBjeWNsZSByb290IG9mIGFDb21wb25lbnQKK2F3dC4xMEQ9YUNvbnRhaW5lciBzaG91bGQgYmUgZm9jdXMgY3ljbGUgcm9vdCBvciBmb2N1cyB0cmF2ZXJzYWwgcG9saWN5IHByb3ZpZGVyCithd3QuMTBFPWZvY3VzQ3ljbGVSb290IGNhbm5vdCBiZSBudWxsCithd3QuMTBGPWltcHJvcGVyIGFsaWdubWVudDogezB9Cithd3QuMTEwPUl0ZXJhdG9yIG91dCBvZiBib3VuZHMKK2F3dC4xMTE9UGFyYW1ldGVyIG5wb2ludHMgaXMgZ3JlYXRlciB0aGFuIGFycmF5IGxlbmd0aAorYXd0LjExMj1OZWdhdGl2ZSBudW1iZXIgb2YgcG9pbnRzCithd3QuMTEzPWlsbGVnYWwgc2Nyb2xsYmFyIG9yaWVudGF0aW9uCithd3QuMTE0PUltYWdlIGlzIG51bGwKK2F3dC4xMTU9QW5jaG9yIGlzIG51bGwKK2F3dC4xMTY9SW52YWxpZCB2YWx1ZSBmb3IgbWVkaWEKK2F3dC4xMTc9SW52YWxpZCB2YWx1ZSBmb3Igb3JpZW50YXRpb25SZXF1ZXN0ZWQKK2F3dC4xMTg9SW52YWxpZCB2YWx1ZSBmb3IgcHJpbnRlclJlc29sdXRpb24KK2F3dC4xMTk9SW52YWxpZCB2YWx1ZSBmb3Igb3JpZ2luCithd3QuMTFBPUludmFsaWQgdmFsdWUgZm9yIHByaW50UXVhbGl0eQorYXd0LjExQj1JbnZhbGlkIHZhbHVlIGZvciBwcmludGVyUmVzb2x1dGlvbltdCithd3QuMTFDPUludmFsaWQgdmFsdWUgZm9yIGNvbG9yCithd3QuMTFEPVVua25vd24gcnVsZQorYXd0LjExRT1Xcm9uZyBhbHBoYSB2YWx1ZQorYXd0LjExRj1wYXJlbnQgaXMgbm90IGEgY29tcG9uZW50Cithd3QuMTIwPW9yaWdpbiBpcyBub3QgYSBkZXNjZW5kYW50IG9mIHBhcmVudAorYXd0LjEyMT1wYXJlbnQgbXVzdCBiZSBzaG93aW5nIG9uIHRoZSBzY3JlZW4KK2F3dC4xMjI9RG9lcyBub3Qgc3VwcG9ydCBkaXNwbGF5IG1vZGUgY2hhbmdlcworYXd0LjEyMz1VbnN1cHBvcnRlZCBkaXNwbGF5IG1vZGU6IHswfQorYXd0LjEyND1DYW5ub3QgY2hhbmdlIHRoZSBtb2RhbGl0eSB3aGlsZSB0aGUgZGlhbG9nIGlzIHZpc2libGUKK2F3dC4xMjU9bnVsbCBvd25lciB3aW5kb3cKK2F3dC4xMjY9V2luZG93IGlzIHNob3dpbmcKK2F3dC4xMjc9Q2Fubm90IGNoYW5nZSB0aGUgZGVjb3JhdGlvbnMgd2hpbGUgdGhlIHdpbmRvdyBpcyB2aXNpYmxlCithd3QuMTI4PUdyYXBoaWNzIGVudmlyb25tZW50IGlzIGhlYWRsZXNzCithd3QuMTI5PU5vdCBhIHNjcmVlbiBkZXZpY2UKK2F3dC4xMkE9aWxsZWdhbCBjb21wb25lbnQgcG9zaXRpb24KK2F3dC4xMkI9YWRkaW5nIGNvbnRhaW5lciB0byBpdHNlbGYKK2F3dC4xMkM9YWRkaW5nIGNvbnRhaW5lcidzIHBhcmVudCB0byBpdHNlbGYKK2F3dC4xMkQ9YWRkaW5nIGEgd2luZG93IHRvIGEgY29udGFpbmVyCithd3QuMTJFPVVua25vd24gY29tcG9uZW50IGV2ZW50IGlkCithd3QuMTJGPUF0dGVtcHQgdG8gc3RhcnQgbmVzdGVkIG1vdXNlIGdyYWIKK2F3dC4xMzA9QXR0ZW1wdCB0byBncmFiIG1vdXNlIGluIG5vdCBkaXNwbGF5YWJsZSB3aW5kb3cKK2F3dC4xMzE9QWRkTGF5b3V0Q29tcG9uZW50OiBjb25zdHJhaW50IG9iamVjdCBtdXN0IGJlIFN0cmluZworYXd0LjEzMj13cm9uZyBwYXJlbnQgZm9yIENhcmRMYXlvdXQKK2F3dC4xMzM9TmVnYXRpdmUgd2lkdGgKK2F3dC4xMzQ9SWxsZWdhbCBjYXAKK2F3dC4xMzU9SWxsZWdhbCBqb2luCithd3QuMTM2PW1pdGVyTGltaXQgbGVzcyB0aGFuIDEuMGYKK2F3dC4xMzc9TmVnYXRpdmUgZGFzaFBoYXNlCithd3QuMTM4PVplcm8gZGFzaCBsZW5ndGgKK2F3dC4xMzk9TmVnYXRpdmUgZGFzaFt7MH1dCithd3QuMTNBPUFsbCBkYXNoIGxlbmd0aHMgemVybworYXd0LjEzQj1vZmZzZXQgb2ZmIGlzIG91dCBvZiByYW5nZQorYXd0LjEzQz1udW1iZXIgb2YgZWxlbWV0cyBsZW4gaXMgb3V0IG9mIHJhbmdlCithd3QuMTNEPVJlY3RhbmdsZSB3aWR0aCBhbmQgaGVpZ2h0IG11c3QgYmUgPiAwCithd3QuMTNFPUNhbm5vdCBjYWxsIG1ldGhvZCBmcm9tIHRoZSBldmVudCBkaXNwYXRjaGVyIHRocmVhZAorYXd0LjEzRj1EZWxheSBtdXN0IGJlIHRvIDAgdG8gNjAsMDAwbXMKK2F3dC4xNDA9SW52YWxpZCBjb21iaW5hdGlvbiBvZiBidXR0b24gZmxhZ3MKK2F3dC4xNDE9ZmFpbGVkIHRvIHBhcnNlIGhvdHNwb3QgcHJvcGVydHkgZm9yIGN1cnNvcjogCithd3QuMTQyPUV4Y2VwdGlvbjogY2xhc3MgezB9IHsxfSBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nOiB7Mn0KK2F3dC4xNDM9aWxsZWdhbCBjdXJzb3IgdHlwZQorYXd0LjE0ND1DYW4gYmUgc2V0IGJ5IHNjcm9sbHBhbmUgb25seQorYXd0LjE0NT1pbGxlZ2FsIGZpbGUgZGlhbG9nIG1vZGUKK2F3dC4xNDY9aWxsZWdhbCBzY3JvbGxiYXIgZGlzcGxheSBwb2xpY3kKK2F3dC4xNDc9cG9zaXRpb24gZ3JlYXRlciB0aGFuIDAKK2F3dC4xNDg9Y2hpbGQgaXMgbnVsbAorYXd0LjE0OT1TY3JvbGxQYW5lIGNvbnRyb2xzIGxheW91dAorYXd0LjE0QT1DYW4gbm90IGNyZWF0ZSBWb2xhdGlsZUltYWdlIHdpdGggc3BlY2lmaWVkIGNhcGFiaWxpdGllcworYXd0LjE0Qj1Pbmx5IENhbnZhcyBvciBXaW5kb3cgaXMgYWxsb3dlZAorYXd0LjE0Qz1OdW1iZXIgb2YgYnVmZmVycyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvbmUKK2F3dC4xNEQ9QnVmZmVyIGNhcGFiaWxpdGllcyBzaG91bGQgc3VwcG9ydCBmbGlwcGluZworYXd0LjE0RT1Db21wb25lbnQgc2hvdWxkIGJlIGRpc3BsYXlhYmxlCithd3QuMTRGPWludmFsaWQgZm9jdXMgdHJhdmVyc2FsIGtleSBpZGVudGlmaWVyCithd3QuMTUwPW5vIHBhcmVudAorYXd0LjE1MT1jb21wb25lbnQgbXVzdCBiZSBzaG93aW5nIG9uIHRoZSBzY3JlZW4gdG8gZGV0ZXJtaW5lIGl0cyBsb2NhdGlvbgorYXd0LjE1Mj1JbnZhbGlkIG51bWJlciBvZiBjb3BpZXMKK2F3dC4xNTM9SW52YWxpZCB2YWx1ZSBmb3IgbWF4UGFnZQorYXd0LjE1ND1JbnZhbGlkIHZhbHVlIGZvciBtaW5QYWdlCithd3QuMTU1PUludmFsaWQgdmFsdWUgZm9yIGZyb21QYWdlCithd3QuMTU2PUludmFsaWQgdmFsdWUgZm9yIHRvUGFnZQorYXd0LjE1Nz1JbnZhbGlkIHZhbHVlIGZvciBwYWdlUmFuZ2VzCithd3QuMTU4PUludmFsaWQgdmFsdWUgZm9yIGRlc3RpbmF0aW9uCithd3QuMTU5PUludmFsaWQgdmFsdWUgZm9yIGRpYWxvZworYXd0LjE1QT1JbnZhbGlkIHZhbHVlIGZvciBkZWZhdWx0U2VsZWN0aW9uCithd3QuMTVCPUludmFsaWQgdmFsdWUgZm9yIG11bHRpcGxlRG9jdW1lbnRIYW5kbGluZworYXd0LjE1Qz1JbnZhbGlkIHZhbHVlIGZvciBhdHRyaWJ1dGUgc2lkZXMKK2F3dC4xNUQ9SW52YWxpZCBjb2xvcnNwYWNlCithd3QuMTVFPVVua25vd24gY29tcG9uZW50LiBNdXN0IGJlIFJFRENPTVBPTkVOVCwgR1JFRU5DT01QT05FTlQgb3IgQkxVRUNPTVBPTkVOVC4KK2F3dC4xNUY9UHJvZmlsZSBjbGFzcyBkb2VzIG5vdCBjb21wbHkgd2l0aCBJQ0Mgc3BlY2lmaWNhdGlvbgorYXd0LjE2MD1Db2xvciBzcGFjZSBkb2Vzbid0IGNvbXBseSB3aXRoIElDQyBzcGVjaWZpY2F0aW9uCithd3QuMTYxPVVuYWJsZSB0byBvcGVuIGZpbGUgezB9Cithd3QuMTYyPUludmFsaWQgSUNDIFByb2ZpbGUgRGF0YQorYXd0LjE2Mz1DYW4ndCBvcGVuIGNvbG9yIHByb2ZpbGUKK2F3dC4xNjQ9Tm90IGEgcHJlZGVmaW5lZCBjb2xvciBzcGFjZQorYXd0LjE2NT1Db2xvciBzcGFjZSBkb2Vzbid0IGNvbXBseSB3aXRoIElDQyBzcGVjaWZpY2F0aW9uCithd3QuMTY2PVRSQyBpcyBub3QgYSBzaW1wbGUgZ2FtbWEgdmFsdWUKK2F3dC4xNjc9VFJDIGlzIGEgZ2FtbWEgdmFsdWUsIG5vdCBhIHRhYmxlCithd3QuMTY4PUludmFsaWQgcHJvZmlsZSBjbGFzcworYXd0LjE2OT1Db21wb25lbnQgaW5kZXggb3V0IG9mIHJhbmdlCithd3QuMTZBPUludmFsaWQgY29tcG9uZW50IGluZGV4OiB7MH0KK2F3dC4xNkI9Tm90IGEgcHJlZGVmaW5lZCBjb2xvcnNwYWNlCithd3QuMTZDPUNhbid0IGxvYWQgY2xhc3M6IHswfQorYXd0LjE2RD1DYW4ndCBwYXJzZSBNSU1FIHR5cGU6IHswfQorYXd0LjE2RT1UcmFuc2ZlcmFibGUgaGFzIG51bGwgZGF0YQorYXd0LjE2Rj1DYW4ndCBjcmVhdGUgcmVhZGVyIGZvciB0aGlzIHJlcHJlc2VudGF0aW9uIGNsYXNzCithd3QuMTcwPUNhbid0IGNyZWF0ZSBkZWZhdWx0IEQmRCBjdXJzb3I6IHswfQorYXd0LjE3MT1BdHRlbXB0IHRvIHN0YXJ0IGEgZHJhZyB3aGlsZSBhbiBleGlzdGluZyBkcmFnIG9wZXJhdGlvbiBpcyBzdGlsbCBleGVjdXRpbmcKK2F3dC4xNzI9RHJhZyBzb3VyY2UgaXMgbnVsbAorYXd0LjE3Mz1PbmUgbGlzdGVuZXIgaXMgYWxyZWFkeSBleGlzdAorYXd0LjE3ND1kZ2wgaXMgbm90IGN1cnJlbnQgbGlzdGVuZXIKK2F3dC4xNzU9TGlzdGVuZXIgbWlzbWF0Y2gKK2F3dC4xNzY9RHJvcFRhcmdldCBjYW5ub3QgYmUgYWRkZWQgYXMgbGlzdGVuZXIgdG8gaXRzZWxmCithd3QuMTc3PUludmFsaWQgdXNlciBhY3Rpb24KK2F3dC4xNzg9SW52YWxpZCBzb3VyY2UgYWN0aW9uCithd3QuMTc5PUNvbnRleHQgcGVlciBpcyBudWxsCithd3QuMTdBPVRyaWdnZXIgZXZlbnQgaXMgbnVsbAorYXd0LjE3Qj1DYW4ndCBpbml0IEFDVElPTl9OT05FIGRyYWcKK2F3dC4xN0M9SW1hZ2Ugb2Zmc2V0IGlzIG51bGwKK2F3dC4xN0Q9VHJhbnNmZXJhYmxlIGlzIG51bGwKK2F3dC4xN0U9Q29tcG9uZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUgdHJpZ2dlciBldmVudCBpcyBudWxsCithd3QuMTdGPURyYWdTb3VyY2UgZm9yIHRoZSB0cmlnZ2VyIGV2ZW50IGlzIG51bGwKK2F3dC4xODA9U291cmNlIGFjdGlvbnMgZm9yIHRoZSBEcmFnR2VzdHVyZVJlY29nbml6ZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmlnZ2VyIGV2ZW50IGFyZSBlcXVhbCB0byBEbkRDb25zdGFudHMuQUNUSU9OX05PTkUKK2F3dC4xODE9QXR0ZW1wdCB0byByZWdpc3RlciBjb250ZXh0IGFzIGl0cyBsaXN0ZW5lcgorYXd0LjE4Mj1kc2wgaXMgbm90IGN1cnJlbnQgbGlzdGVuZXIKK2F3dC4xODM9SW52YWxpZCBzdGF0dXMKK2F3dC4xODQ9SW52YWxpZCBhY3Rpb24KK2F3dC4xODU9Q29tcG9uZW50IGlzIG51bGwKK2F3dC4xODY9RHJhZ1NvdXJjZSBpcyBudWxsCithd3QuMTg3PU9yaWdpbiBpcyBudWxsCithd3QuMTg4PUV2ZW50IGxpc3QgaXMgbnVsbAorYXd0LjE4OT1FdmVudCBsaXN0IGlzIGVtcHR5Cithd3QuMThBPUNvbnRleHQgaXMgbnVsbAorYXd0LjE4Qj1JbnZhbGlkIGJ1dHRvbiB2YWx1ZQorYXd0LjE4Qz1DYW5ub3QgaW52b2tlIG51bGwgcnVubmFibGUKK2F3dC4xOEQ9U291cmNlIGlzIG51bGwKK2F3dC4xOEU9V3JvbmcgZXZlbnQgaWQKK2F3dC4xOEY9VGV4dCBtdXN0IGJlIG51bGwgZm9yIENBUkVUX1BPU0lUSU9OX0NIQU5HRUQKK2F3dC4xOTA9V3JvbmcgY29tbWl0dGVkQ2hhcmFjdGVyQ291bnQKK2F3dC4xOTE9SW52YWxpZCBrZXlDb2RlIGZvciBLRVlfVFlQRUQgZXZlbnQsIG11c3QgYmUgVktfVU5ERUZJTkVECithd3QuMTkyPUludmFsaWQga2V5Q2hhciBmb3IgS0VZX1RZUEVEIGV2ZW50LCBjYW4ndCBiZSBDSEFSX1VOREVGSU5FRAorYXd0LjE5Mz1MaXN0ZW5lciBjYW4ndCBiZSB6ZXJvCithd3QuMTk0PVVua25vd24gYXR0cmlidXRlIG5hbWUKK2F3dC4xOTU9T2Zmc2V0IGlzIG91dCBvZiBib3VuZHMKK2F3dC4xOTY9SnVzdGlmaWNhdGlvbiBpbXBvc3NpYmxlLCBsYXlvdXQgYWxyZWFkeSBqdXN0aWZpZWQKK2F3dC4xOTc9RW5kcG9pbnRzIGFyZSBvdXQgb2YgcmFuZ2UKK2F3dC4xOTg9SWxsZWdhbCBhbGlnbm1lbnQgYXJndW1lbnQKK2F3dC4xOTk9SWxsZWdhbCByYW5nZSBhcmd1bWVudCB2YWx1ZTogezB9Cithd3QuMTlBPXN0YXJ0IG9yIGNvdW50IGFyZ3VtZW50cyBhcmUgb3V0IG9mIHRleHQgcmFuZ2UKK2F3dC4xOUI9Y291bnQgYXJndW1lbnQgbXVzdCBiZSBwb3NpdGl2ZQorYXd0LjE5Qz13ZWlnaHQgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcgorYXd0LjE5RD1ncm93TGVmdExpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIKK2F3dC4xOUU9Z3Jvd1JpZ2h0TGltaXQgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcgorYXd0LjE5Rj1pbmNvcnJlY3QgdmFsdWUgZm9yIHNocmlua1ByaW9yaXR5LCBtb3JlIHRoYW4gUFJJT1JJVFlfTk9ORSBvciBsZXNzIHRoYW4gUFJJT1JJVFlfS0FTSElEQSB2YWx1ZQorYXd0LjIwMD1pbmNvcnJlY3QgdmFsdWUgZm9yIGdyb3dQcmlvcml0eSwgbW9yZSB0aGFuIFBSSU9SSVRZX05PTkUgb3IgbGVzcyB0aGFuIFBSSU9SSVRZX0tBU0hJREEgdmFsdWUKK2F3dC4yMDE9c2hyaW5rTGVmdExpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIKK2F3dC4yMDI9c2hyaW5rUmlnaHRMaW1pdCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyCithd3QuMjAzPU9mZnNldCBsaW1pdCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIGN1cnJlbnQgcG9zaXRpb24KK2F3dC4yMDQ9RGV0ZXJtaW5hbnQgaXMgemVybworYXd0LjIwNT1JbnZhbGlkIHR5cGUgb2YgQXJjOiB7MH0KK2F3dC4yMDY9RmxhdG5lc3MgaXMgbGVzcyB0aGVuIHplcm8KK2F3dC4yMDc9TGltaXQgaXMgbGVzcyB0aGVuIHplcm8KK2F3dC4yMDg9UGF0aCBpcyBudWxsCithd3QuMjA5PUludmFsaWQgd2luZGluZyBydWxlIHZhbHVlCithd3QuMjBBPUZpcnN0IHNlZ21lbnQgc2hvdWxkIGJlIFNFR19NT1ZFVE8gdHlwZQorYXd0LjIwQj11bmtub3duIGlucHV0IG1ldGhvZCBoaWdobGlnaHQgc3RhdGUKK2F3dC4yMEM9TnVtYmVyIG9mIEJpdHMgZXF1YWxzIHRvIHplcm8KK2F3dC4yMEQ9VGhlIG51bWJlciBvZiBiaXRzIHBlciBwaXhlbCBpcyBub3QgYSBwb3dlciBvZiAyIG9yIHBpeGVscyBzcGFuIGRhdGEgZWxlbWVudCBib3VuZGFyaWVzCithd3QuMjBFPURhdGEgQml0IG9mZnNldCBpcyBub3QgYSBtdWx0aXBsZSBvZiBwaXhlbCBiaXQgc3RyaWRlCithd3QuMjBGPU51bWJlciBvZiBiYW5kcyBtdXN0IGJlIG9ubHkgMQorYXd0LjIxMD1UaGUgY29tcG9uZW50IHZhbHVlIGZvciB0aGlzIENvbG9yTW9kZWwgaXMgc2lnbmVkCithd3QuMjExPVBpeGVsIHZhbHVlcyBmb3IgdGhpcyBDb2xvck1vZGVsIGFyZSBub3QgY29udmVuaWVudGx5IHJlcHJlc2VudGFibGUgYXMgYSBzaW5nbGUgaW50Cithd3QuMjEyPVRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgY29tcG9uZW50IGluIHRoaXMgQ29sb3JNb2RlbAorYXd0LjIxMz1UaGlzIENvbXBvbmVudENvbG9yTW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgdW5ub3JtYWxpemVkIGZvcm0KK2F3dC4yMTQ9VGhpcyBDb2xvciBNb2RlbCBkb2Vzbid0IHN1cHBvcnQgdGhpcyB0cmFuc2ZlclR5cGUKK2F3dC4yMTU9dHJhbnNmZXJUeXBlIGlzIG5vdCBvbmUgb2YgRGF0YUJ1ZmZlci5UWVBFX0JZVEUsIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQsIERhdGFCdWZmZXIuVFlQRV9JTlQsIERhdGFCdWZmZXIuVFlQRV9TSE9SVCwgRGF0YUJ1ZmZlci5UWVBFX0ZMT0FULCBvciBEYXRhQnVmZmVyLlRZUEVfRE9VQkxFCithd3QuMjE2PVRoZSBjb21wb25lbnRzIGFycmF5IGlzIG5vdCBsYXJnZSBlbm91Z2ggdG8gaG9sZCBhbGwgdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzCithd3QuMjE3PVRoZSB0cmFuc2ZlciB0eXBlIG9mIHRoaXMgQ29tcG9uZW50Q29sb3JNb2RlbCBpcyBub3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgdHJhbnNmZXIgdHlwZXM6IERhdGFCdWZmZXIuVFlQRV9CWVRFLCBEYXRhQnVmZmVyLlRZUEVfVVNIT1JULCBvciBEYXRhQnVmZmVyLlRZUEVfSU5UCithd3QuMjE4PVRoZSBjb21wb25lbnRzIGFycmF5IGlzIG5vdCBsYXJnZSBlbm91Z2ggdG8gaG9sZCBhbGwgdGhlIGNvbG9yIGFuZCBhbHBoYSBjb21wb25lbnRzCithd3QuMjE5PVRoaXMgdHJhbnNmZXJUeXBlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBjb2xvciBtb2RlbAorYXd0LjIxQT1UaGlzIENvbXBvbmVudENvbG9yTW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIHRyYW5zZmVyVHlwZQorYXd0LjIxQj1UaGUgbGVuZ3RoIG9mIG5vcm1Db21wb25lbnRzIG1pbnVzIG5vcm1PZmZzZXQgaXMgbGVzcyB0aGFuIG51bUNvbXBvbmVudHMKK2F3dC4yMUM9VGhlIG51bWJlciBvZiBzY2FsZSBmYWN0b3JzIHNob3VsZCBub3QgYmUgemVybworYXd0LjIxRD1OdW1iZXIgb2Ygc3JjIGJhbmRzICh7MH0pIGRvZXMgbm90IG1hdGNoIG51bWJlciBvZiBkc3QgYmFuZHMgKHsxfSkKK2F3dC4yMUU9TnVtYmVyIG9mIHNjYWxpbmcgY29uc3RhbnRzIGlzIG5vdCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJhbmRzCithd3QuMjFGPVVuYWJsZSB0byB0cmFuc2Zvcm0gc291cmNlCithd3QuMjIwPVNvdXJjZSBzaG91bGQgbm90IGhhdmUgSW5kZXhDb2xvck1vZGVsCithd3QuMjIxPVRoZSBpbWFnZVR5cGUgaXMgVFlQRV9CWVRFX0JJTkFSWSBhbmQgdGhlIGNvbG9yIG1hcCBoYXMgbW9yZSB0aGFuIDE2IGVudHJpZXMKK2F3dC4yMjI9VGhlIGltYWdlVHlwZSBpcyBub3QgVFlQRV9CWVRFX0JJTkFSWSBvciBUWVBFX0JZVEVfSU5ERVhFRAorYXd0LjIyMz1UaGUgaW1hZ2VUeXBlIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggQ29sb3JNb2RlbAorYXd0LjIyND1Vbmtub3duIGltYWdlIHR5cGUKK2F3dC4yMjU9UHJvcGVydHkgbmFtZSBpcyBudWxsCithd3QuMjI2PUJvdGggdGlsZVggYW5kIHRpbGVZIGFyZSBub3QgZXF1YWwgdG8gMAorYXd0LjIyNz1UaGlzIGltYWdlIHR5cGUgY2FuJ3QgaGF2ZSBhbHBoYQorYXd0LjIyOD1taW5YIG9yIG1pblkgb2YgdGhpcyByYXN0ZXIgbm90IGVxdWFsIHRvIHplcm8KK2F3dC4yMjk9TnVtYmVyIG9mIGNvbXBvbmVudHMgaW4gdGhlIExVVCBkb2VzIG5vdCBtYXRjaCB0aGUgbnVtYmVyIG9mIGJhbmRzCithd3QuMjJBPVdyb25nIHR5cGUgb2YgcGl4ZWxzIGFycmF5Cithd3QuMjJCPUxlbmd0aCBvZiBkYXRhIHNob3VsZCBub3QgYmUgbGVzcyB0aGFuIHdpZHRoKmhlaWdodAorYXd0LjIyQz1Vbmtub3duIGRhdGEgdHlwZSB7MH0KK2F3dC4yMkQ9VGhpcyB0cmFuc2ZlclR5cGUgKCB7MH0gKSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgY29sb3IgbW9kZWwKK2F3dC4yMkU9dyBvciBoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvCithd3QuMjJGPVRoZSBwcm9kdWN0IG9mIHcgYW5kIGggaXMgZ3JlYXRlciB0aGFuIEludGVnZXIuTUFYX1ZBTFVFCithd3QuMjMwPWRhdGFUeXBlIGlzIG5vdCBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkYXRhIHR5cGVzCithd3QuMjMxPU51bWJlciBvZiBiYW5kcyBtdXN0IGJlIG1vcmUgdGhlbiAwCithd3QuMjMyPU9mZnNldCBzaG91bGQgYmUgbm90IGxlc3MgdGhhbiB6ZXJvCithd3QuMjMzPU51bWJlciBvZiBjb21wb25lbnRzIHNob3VsZCBiZSBwb3NpdGl2ZQorYXd0LjIzND1XaWR0aCBvciBIZWlnaHQgZXF1YWxzIHplcm8KK2F3dC4yMzU9V3JvbmcgRGF0YSBCdWZmZXIgdHlwZSA6IHswfQorYXd0LjIzNj1UaGUgYml0cyBpcyBsZXNzIHRoYW4gMSBvciBncmVhdGVyIHRoYW4gMzIKK2F3dC4yMzc9U291cmNlIGFuZCBkZXN0aW5hdGlvbnMgcmFzdGVycyBkbyBub3QgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgYmFuZHMKK2F3dC4yMzg9VGhlIG51bWJlciBvZiBhcnJheXMgaW4gdGhlIExvb2t1cFRhYmxlIGRvZXMgbm90IG1lZXQgdGhlIHJlc3RyaWN0aW9ucworYXd0LjIzOT1UaGUgc3BhY2UgaXMgbm90IGEgVFlQRV9SR0Igc3BhY2UKK2F3dC4yM0E9VGhlIG1pbi9tYXggbm9ybWFsaXplZCBjb21wb25lbnQgdmFsdWVzIGFyZSBub3QgMC4wLzEuMAorYXd0LjIzQj1UaGUgbWFzayBvZiB0aGUgezB9IGNvbXBvbmVudCBpcyBub3QgY29udGlndW91cworYXd0LjIzQz1UaGUgbWFzayBvZiB0aGUgYWxwaGEgY29tcG9uZW50IGlzIG5vdCBjb250aWd1b3VzCithd3QuMjNEPVRoZSBtYXNrIG9mIHRoZSByZWQgY29tcG9uZW50IGlzIG5vdCBjb250aWd1b3VzCithd3QuMjNFPVRoZSBtYXNrIG9mIHRoZSBncmVlbiBjb21wb25lbnQgaXMgbm90IGNvbnRpZ3VvdXMKK2F3dC4yM0Y9VGhlIG1hc2sgb2YgdGhlIGJsdWUgY29tcG9uZW50IGlzIG5vdCBjb250aWd1b3VzCithd3QuMjQwPVRoZSB0cmFuc2ZlclR5cGUgbm90IGlzIG9uZSBvZiBEYXRhQnVmZmVyLlRZUEVfQllURSwgRGF0YUJ1ZmZlci5UWVBFX1VTSE9SVCBvciBEYXRhQnVmZmVyLlRZUEVfSU5UCithd3QuMjQxPUFueSBvZmZzZXQgYmV0d2VlbiBiYW5kcyBpcyBncmVhdGVyIHRoYW4gdGhlIFNjYW5saW5lIHN0cmlkZQorYXd0LjI0Mj1QaXhlbCBzdHJpZGUgaXMgbGVzcyB0aGFuIGFueSBvZmZzZXQgYmV0d2VlbiBiYW5kcworYXd0LjI0Mz1Qcm9kdWN0IG9mIFBpeGVsIHN0cmlkZSBhbmQgdyBpcyBncmVhdGVyIHRoYW4gU2NhbmxpbmUgc3RyaWRlCithd3QuMjQ0PVdpZHRoIG9yIEhlaWdodCBvZiBjaGlsZCBSYXN0ZXIgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KK2F3dC4yNDU9cGFyZW50WCBkaXNwb3NlcyBvdXRzaWRlIFJhc3RlcgorYXd0LjI0Nj1wYXJlbnRZIGRpc3Bvc2VzIG91dHNpZGUgUmFzdGVyCithd3QuMjQ3PXBhcmVudFggKyB3IHJlc3VsdHMgaW4gaW50ZWdlciBvdmVyZmxvdworYXd0LjI0OD1wYXJlbnRZICsgaCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yNDk9Y2hpbGRNaW5YICsgdyByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yNEE9Y2hpbGRNaW5ZICsgaCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yNEI9UGl4ZWwgc3RyaWRlIG11c3QgYmUgPj0gMAorYXd0LjI0Qz1TY2FubGluZSBzdHJpZGUgbXVzdCBiZSA+PSAwCithd3QuMjREPUJhbmsgSW5kaWNlcyBsZW5ndGggbXVzdCBiZSBlcXVhbCBCYW5rIE9mZnNldHMgbGVuZ3RoCithd3QuMjRFPUluZGV4IG9mIHswfSBiYW5rIG11c3QgYmUgPj0gMAorYXd0LjI0Rj1VbmFibGUgdG8gaW52ZXJ0IHRyYW5zZm9ybSB7MH0KK2F3dC4yNTA9VW5rbm93biBpbnRlcnBvbGF0aW9uIHR5cGU6IHswfQorYXd0LjI1MT1UcmFuc2Zvcm1lZCB3aWR0aCAoezB9KSBhbmQgaGVpZ2h0ICh7MX0pIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMAorYXd0LjI1Mj1Tb3VyY2UgY2FuJ3QgYmUgc2FtZSBhcyB0aGUgZGVzdGluYXRpb24KK2F3dC4yNTM9RGlmZmVyZW50IG51bWJlciBvZiBiYW5kcyBpbiBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uCithd3QuMjU0PU51bWJlciBvZiBiYW5kcyBpbiB0aGUgc291cmNlIHJhc3RlciAoezB9KSBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgbWF0cml4IFt7MX14ezJ9XQorYXd0LjI1NT1OdW1iZXIgb2YgYmFuZHMgaW4gdGhlIGRlc3RpbmF0aW9uIHJhc3RlciAoezB9KSBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgbWF0cml4IFt7MX14ezJ9XQorYXd0LjI1Nj1Tb3VyY2UgcmFzdGVyIGlzIG51bGwKK2F3dC4yNTc9U291cmNlIHJhc3RlciBpcyBlcXVhbCB0byBkZXN0aW5hdGlvbgorYXd0LjI1OD1OdW1iZXIgb2Ygc291cmNlIGJhbmRzICh7MH0pIGlzIG5vdCBlcXVhbCB0byBudW1iZXIgb2YgZGVzdGluYXRpb24gYmFuZHMgKHsxfSkKK2F3dC4yNTk9U291cmNlIGltYWdlIGlzIG51bGwKK2F3dC4yNUE9U291cmNlIGVxdWFscyB0byBkZXN0aW5hdGlvbgorYXd0LjI1Qj1OdWxsIENvbG9yU3BhY2UgcGFzc2VkIGFzIGEgcGFyYW1ldGVyCithd3QuMjVDPU51bGwgcHJvZmlsZXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyCithd3QuMjVEPVNvdXJjZSBvciBkZXN0aW5hdGlvbiBjb2xvciBzcGFjZSBpcyBub3QgZGVmaW5lZAorYXd0LjI1RT1JbmNvcnJlY3QgbnVtYmVyIG9mIHNvdXJjZSByYXN0ZXIgYmFuZHMuIFNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGNvbG9yIGNvbXBvbmVudHMgb2Ygc291cmNlIGNvbG9yc3BhY2UuCithd3QuMjVGPUluY29ycmVjdCBudW1iZXIgb2YgZGVzdGluYXRpb24gcmFzdGVyIGJhbmRzLiBTaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBjb2xvciBjb21wb25lbnRzIG9mIGRlc3RpbmF0aW9uIGNvbG9yc3BhY2UuCithd3QuMjYwPUluY29tcGF0aWJsZSByYXN0ZXJzIC0gd2lkdGggb3IgaGVpZ2h0IGRpZmZlcnMKK2F3dC4yNjE9RGVzdGluYXRpb24gY29sb3Igc3BhY2UgaXMgdW5kZWZpbmVkCithd3QuMjYyPURlc3Rpb25hdGlvbiBjb2xvciBzcGFjZSBzaG91bGQgYmUgZGVmaW5lZAorYXd0LjI2Mz1JbmNvbXBhdGlibGUgaW1hZ2VzIC0gd2lkdGggb3IgaGVpZ2h0IGRpZmZlcnMKK2F3dC4yNjQ9U2l6ZSBvZiB0aGUgY29sb3IgbWFwIGlzIGxlc3MgdGhhbiAxCithd3QuMjY1PVRoZSByYXN0ZXIgYXJndW1lbnQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzIEluZGV4Q29sb3JNb2RlbAorYXd0LjI2Nj1UaGUgbnVtYmVyIG9mIGJpdHMgaW4gYSBwaXhlbCBpcyBncmVhdGVyIHRoYW4gMTYKK2F3dC4yNjc9VGhlIHRyYW5zZmVyVHlwZSBpcyBpbnZhbGlkCithd3QuMjY4PVRoZSBwaXhlbCBpcyBub3QgYSBwcmltaXRpdmUgYXJyYXkgb2YgdHlwZSB0cmFuc2ZlclR5cGUKK2F3dC4yNjk9VGhlIHRyYW5zZmVyVHlwZSBpcyBub3Qgb25lIG9mIERhdGFCdWZmZXIuVFlQRV9CWVRFIG9yIERhdGFCdWZmZXIuVFlQRV9VU0hPUlQKK2F3dC4yNkE9SW5jb3JyZWN0IEltYWdlQ29uc3VtZXIgY29tcGxldGlvbiBzdGF0dXMKK2F3dC4yNkI9VGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBwaXhlbCB2YWx1ZXMgaXMgbGVzcyB0aGFuIDEKK2F3dC4yNkM9Yml0cyBpcyBudWxsCithd3QuMjZEPVRoZSBlbGVtZW50cyBpbiBiaXRzIGlzIGxlc3MgdGhhbiAwCithd3QuMjZFPVRoZSBzdW0gb2YgdGhlIG51bWJlciBvZiBiaXRzIGluIGJpdHMgaXMgbGVzcyB0aGFuIDEKK2F3dC4yNkY9VGhlIGNzcGFjZSBpcyBudWxsCithd3QuMjcwPVRoZSB0cmFuc3BhcmVuY3kgaXMgbm90IGEgdmFsaWQgdmFsdWUKK2F3dC4yNzE9VGhlIG51bWJlciBvZiBiaXRzIGluIGJpdHMgaXMgbGVzcyB0aGFuIDEKK2F3dC4yNzI9VGhlIGxlbmd0aCBvZiBjb21wb25lbnRzIG1pbnVzIG9mZnNldCBpcyBsZXNzIHRoYW4gbnVtQ29tcG9uZW50cworYXd0LjI3Mz1UaGUgbGVuZ3RoIG9mIG5vcm1Db21wb25lbnRzIG1pbnVzIG5vcm1PZmZzZXQgaXMgbGVzcyB0aGFuIG51bUNvbXBvbmVudHMKK2F3dC4yNzQ9Y29tcG9uZW50SWR4IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb3IgbGVzcyB0aGFuIHplcm8KK2F3dC4yNzU9VGhpcyBwaXhlbCByZXByZXNlbnRhdGlvbiBpcyBub3Qgc3V1cG9ydGVkIGJ5IHRpcyBDb2xvciBNb2RlbAorYXd0LjI3Nj1sb2NhdGlvbi54ICsgdyBvciBsb2NhdGlvbi55ICsgaCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yNzc9YmFua0luZGljZXMgb3IgYmFuZE9mZnNldHMgaXMgbnVsbAorYXd0LjI3OD1kYXRhQnVmZmVyIGlzIG51bGwKK2F3dC4yNzk9YmFuZHMgaXMgbGVzcyB0aGFuIDEKK2F3dC4yN0E9ZGF0YUJ1ZmZlciBoYXMgbW9yZSB0aGFuIG9uZSBiYW5rCithd3QuMjdCPWJhbmRPZmZzZXRzIGlzIG51bGwKK2F3dC4yN0M9YmFuZE1hc2tzIGlzIG51bGwKK2F3dC4yN0Q9Yml0c1BlckJhbmQgb3IgYmFuZHMgaXMgbm90IGdyZWF0ZXIgdGhhbiB6ZXJvCithd3QuMjdFPVRoZSBwcm9kdWN0IG9mIGJpdHNQZXJCYW5kIGFuZCBiYW5kcyBpcyBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBiaXRzIGhlbGQgYnkgZGF0YVR5cGUKK2F3dC4yN0Y9U2FtcGxlTW9kZWwgb3IgRGF0YUJ1ZmZlciBpcyBudWxsCithd3QuMjgwPVNhbXBsZU1vZGVsIGlzIG51bGwKK2F3dC4yODE9c2FtcGxlTW9kZWwsIGRhdGFCdWZmZXIsIGFSZWdpb24gb3Igc2FtcGxlTW9kZWxUcmFuc2xhdGUgaXMgbnVsbAorYXd0LjI4Mj1hUmVnaW9uIGhhcyB3aWR0aCBvciBoZWlnaHQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KK2F3dC4yODM9T3ZlcmZsb3cgWCBjb29yZGluYXRlIG9mIFJhc3RlcgorYXd0LjI4ND1PdmVyZmxvdyBZIGNvb3JkaW5hdGUgb2YgUmFzdGVyCithd3QuMjg1PVdpZHRoIG9yIEhlaWdodCBvZiBjaGlsZCBSYXN0ZXIgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KK2F3dC4yODY9cGFyZW50WCBkaXNwb3NlcyBvdXRzaWRlIFJhc3RlcgorYXd0LjI4Nz1wYXJlbnRZIGRpc3Bvc2VzIG91dHNpZGUgUmFzdGVyCithd3QuMjg4PXBhcmVudFggKyB3aWR0aCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yODk9cGFyZW50WSArIGhlaWdodCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yOEE9Y2hpbGRNaW5YICsgd2lkdGggcmVzdWx0cyBpbiBpbnRlZ2VyIG92ZXJmbG93Cithd3QuMjhCPWNoaWxkTWluWSArIGhlaWdodCByZXN1bHRzIGluIGludGVnZXIgb3ZlcmZsb3cKK2F3dC4yOEM9UmVjdCBpcyBudWxsCithd3QuMjhEPUxlbmd0aCBvZiBkYXRhQXJyYXlbezB9XSBpcyBsZXNzIHRoYW4gc2l6ZSArIG9mZnNldFt7MX1dCithd3QuMjhFPUxlbmd0aCBvZiBkYXRhQXJyYXkgaXMgbGVzcyB0aGFuIHNpemUgKyBvZmZzZXQKK2F3dC4yOEY9U291cmNlIGFuZCBkZXN0aW5hdGlvbiByYXN0ZXJzIGRvIG5vdCBoYXZlIHRoZSBzYW1lIHdpZHRoIQorYXd0LjI5MD1Tb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHJhc3RlcnMgZG8gbm90IGhhdmUgdGhlIHNhbWUgaGVpZ2h0IQorYXd0LjI5MT1Tb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGltYWdlcyBkbyBub3QgaGF2ZSB0aGUgc2FtZSB3aWR0aCEKK2F3dC4yOTI9U291cmNlIGFuZCBkZXN0aW5hdGlvbiBpbWFnZXMgZG8gbm90IGhhdmUgdGhlIHNhbWUgaGVpZ2h0IQorYXd0LjI5ND1waXhlbCBpcyBudWxsCithd3QuMjk1PWRhdGEgaXMgbnVsbAorYXd0LjI5Nj1jYW4ndCBhbGxvY2F0ZSBtZW1vcnkgb24gdmlkZW8gY2FyZCB0byBjcmVhdGUgbmV3IGRpc3BsYXkgbGlzdAorYXd0LjI5Nz1JbnZhbGlkIGtleUxvY2F0aW9uCithd3QuMjk4PWRhdGFCdWZmZXIgaXMgdG9vIHNtYWxsCisKK2F3dC5lcnIuMDA9ZmlsZSBkaWFsb2cgezB9IGVycm9yIQorYXd0LmVyci4wMT1lcnJvcjogezB9Cithd3QuZXJyLjAyPUdESVBsdXMgRHJhd0RyaXZlclN0cmluZyBlcnJvciBzdGF0dXMgPSB7MH0KK2F3dC5lcnIuMDM9Z2RpcERyYXdDb21wb3NpdGVHbHlwaFZlY3RvcjogR0RJUGx1cyBEcmF3RHJpdmVyU3RyaW5nIGVycm9yIHN0YXR1cyA9IHswfQorYXd0LmVyci4wND1nZGlwRHJhd0NvbXBvc2l0ZUdseXBoVmVjdG9yOiBHRElQbHVzIERyYXdEcml2ZXJTdHJpbmcgZXJyb3Igc3RhdHVzID0gezB9CmRpZmYgLS1naXQgYS9hd3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9iZWFucy9pbnRlcm5hbHMvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMgYi9hd3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9iZWFucy9pbnRlcm5hbHMvbmxzL21lc3NhZ2VzLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzJiMWM4YwotLS0gL2Rldi9udWxsCisrKyBiL2F3dC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2JlYW5zL2ludGVybmFscy9ubHMvbWVzc2FnZXMucHJvcGVydGllcwpAQCAtMCwwICsxLDEwMyBAQAorIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisjIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyMgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyMgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgIAorIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIyAgCisjICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgCisKKyMgbWVzc2FnZXMgZm9yIEVOIGxvY2FsZQorYmVhbnMuMDA9bm8gZ2V0dGVyIGZvciB7MH0gcHJvcGVydHkKK2JlYW5zLjAxPW5vIHByb3BlcnR5IGZvciBuYW1lIHswfSBpcyBmb3VuZAorYmVhbnMuMDI9aW4gRGVmYXVsdFBlcnNpc3RlbmNlRGVsZWdhdGUubXV0YXRlc1RvKCkgezB9IDogezF9CitiZWFucy4wMz1UYXJnZXQgQmVhbiBjbGFzcyBpcyBudWxsCitiZWFucy4wND1iYWQgcHJvcGVydHkgbmFtZQorYmVhbnMuMDU9TW9kaWZpZXIgZm9yIHNldHRlciBtZXRob2Qgc2hvdWxkIGJlIHB1YmxpYy4KK2JlYW5zLjA2PU51bWJlciBvZiBwYXJhbWV0ZXJzIGluIHNldHRlciBtZXRob2QgaXMgbm90IGVxdWFsIHRvIDEuCitiZWFucy4wNz1QYXJhbWV0ZXIgdHlwZSBpbiBzZXR0ZXIgbWV0aG9kIGRvZXMgbm90IGNvcnJlc3BvbmRzIHRvIHByZWRlZmluZWQuCitiZWFucy4wOD1OdW1iZXIgb2YgcGFyYW1ldGVycyBpbiBnZXR0ZXIgbWV0aG9kIGlzIG5vdCBlcXVhbCB0byAwLgorYmVhbnMuMDk9UGFyYW1ldGVyIHR5cGUgaW4gZ2V0dGVyIG1ldGhvZCBkb2VzIG5vdCBjb3JyZXNwb25kcyB0byBwcmVkZWZpbmVkLgorYmVhbnMuMEE9TW9kaWZpZXIgZm9yIGdldHRlciBtZXRob2Qgc2hvdWxkIGJlIHB1YmxpYy4KK2JlYW5zLjBCPUV4Y2VwdGlvbiBpbiBjb21tYW5kIGV4ZWN1dGlvbgorYmVhbnMuMEM9c291cmNlIGlzIG51bGwKK2JlYW5zLjBEPUVycm9yIGluIGV4cHJlc3Npb246IHswfQorYmVhbnMuMEU9Q2hhbmdlcyBhcmUgbnVsbAorYmVhbnMuMEY9VGhlIG5ldyBCZWFuQ29udGV4dCBjYW4gbm90IGJlIHNldAorYmVhbnMuMTA9bm8gbm9kZSBpcyBmb3VuZCBmb3Igc3RhdGVtZW50IHdpdGggdGFyZ2V0ID0gezB9CitiZWFucy4xMT1ubyBnZXR0ZXIgZm9yIHByb3BlcnR5IHswfSBmb3VuZAorYmVhbnMuMTI9Y2Fubm90IGFjY2VzcyBwcm9wZXJ0eSB7MH0gZ2V0dGVyCitiZWFucy4xMz1ubyBzZXR0ZXIgZm9yIHByb3BlcnR5IHswfSBmb3VuZAorYmVhbnMuMTQ9RXhjZXB0aW9uIHdoaWxlIGZpbmRpbmcgcHJvcGVydHkgZGVzY3JpcHRvcgorYmVhbnMuMTU9VGhlIGxpc3RlbmVyIGlzIG51bGwKK2JlYW5zLjE2PVRoZSBwcm92aWRlciBpcyBudWxsCitiZWFucy4xNz1UaGUgY2hpbGQgaXMgbnVsbAorYmVhbnMuMTg9VGhlIHJlcXVlc3RvciBpcyBudWxsCitiZWFucy4xOT1UaGUgc2VydmljZSBjbGFzcyBpcyBudWxsCitiZWFucy4xQT1UaGUgc2VydmljZSBzZWxlY3RvciBpcyBudWxsCitiZWFucy4xQj1UaGUgc2VydmljZSBpcyBudWxsCitiZWFucy4xQz1UaGUgZXZlbnQgaXMgbnVsbAorYmVhbnMuMUQ9YmVhbiBpcyBudWxsCitiZWFucy4xRT1JbGxlZ2FsIGNsYXNzIG5hbWU6IHswfQorYmVhbnMuMUY9TWV0aG9kIG5vdCBmb3VuZDogZ2V0ezB9CitiZWFucy4yMD1NZXRob2Qgbm90IGZvdW5kOiBzZXR7MH0KK2JlYW5zLjIxPU1vZGlmaWVyIGZvciBpbmRleGVkIGdldHRlciBtZXRob2Qgc2hvdWxkIGJlIHB1YmxpYy4KK2JlYW5zLjIyPU51bWJlciBvZiBwYXJhbWV0ZXJzIGluIGdldHRlciBtZXRob2QgaXMgbm90IGVxdWFsIHRvIDEuCitiZWFucy4yMz1QYXJhbWV0ZXIgaW4gaW5kZXhlZCBnZXR0ZXIgbWV0aG9kIGlzIG5vdCBvZiBpbnRlZ2VyIHR5cGUuCitiZWFucy4yND1QYXJhbWV0ZXIgdHlwZSBpbiBpbmRleGVkIGdldHRlciBtZXRob2QgZG9lcyBub3QgY29ycmVzcG9uZCB0byBwcmVkZWZpbmVkLgorYmVhbnMuMjU9TW9kaWZpZXIgZm9yIGluZGV4ZWQgc2V0dGVyIG1ldGhvZCBzaG91bGQgYmUgcHVibGljLgorYmVhbnMuMjY9TnVtYmVyIG9mIHBhcmFtZXRlcnMgaW4gaW5kZXhlZCBzZXR0ZXIgbWV0aG9kIGlzIG5vdCBlcXVhbCB0byAyLgorYmVhbnMuMjc9Rmlyc3QgcGFyYW1ldGVyIHR5cGUgaW4gaW5kZXhlZCBzZXR0ZXIgbWV0aG9kIHNob3VsZCBiZSBpbnQuCitiZWFucy4yOD1TZWNvbmQgcGFyYW1ldGVyIHR5cGUgaW4gaW5kZXhlZCBzZXR0ZXIgbWV0aG9kIGRvZXMgbm90IGNvcnJlc3BvbmRzIHRvIHByZWRlZmluZWQuCitiZWFucy4yOT1NZW1iZXJzaGlwIGxpc3RlbmVyIGlzIG51bGwKK2JlYW5zLjJBPVRhcmdldCBjaGlsZCBjYW4gbm90IGJlIG51bGwKK2JlYW5zLjJCPVJlc291cmNlIG5hbWUgY2FuIG5vdCBiZSBudWxsCitiZWFucy4yQz1UaGUgY2hpbGQgY2FuIG5vdCBiZSBudWxsCitiZWFucy4yRD1JbnZhbGlkIHJlc291cmNlCitiZWFucy4yRT1Qcm9wZXJ0eVZldG9FeGNlcHRpb24gd2FzIHRocm93biB3aGlsZSByZW1vdmluZyBhIGNoaWxkOiB7MH07IE9yaWdpbmFsIGVycm9yIG1lc3NhZ2U6ezF9CitiZWFucy4yRj1UYXJnZXQgY2hpbGQgaXMgbnVsbAorYmVhbnMuMzA9UHJvcGVydHlWZXRvRXhjZXB0aW9uIHdhcyB0aHJvd24gd2hpbGUgYWRkaW5nIGEgY2hpbGQ6IHswfTsgT3JpZ2luYWwgZXJyb3IgbWVzc2FnZTp7MX0KK2JlYW5zLjMxPU5vIHZhbGlkIG1ldGhvZCB7MH0gZm9yIHsxfSBmb3VuZC4KK2JlYW5zLjMyPUNhbm5vdCBhY3F1aXJlIGV2ZW50IHR5cGUgZnJvbSB7MH0gbGlzdGVuZXIuCitiZWFucy4zMz17MH0gZG9lcyBub3QgcmV0dXJuIDx2b2lkPgorYmVhbnMuMzQ9ezB9IHNob3VsZCBoYXZlIGEgc2luZ2xlIGlucHV0IHBhcmFtZXRlcgorYmVhbnMuMzU9U2luZ2xlIHBhcmFtZXRlciBkb2VzIG5vdCBtYXRjaCB0byB7MH0gY2xhc3MKK2JlYW5zLjM2PU5vIGlucHV0IHBhcmFtcyBhcmUgYWxsb3dlZCBmb3IgZ2V0TGlzdGVuZXJNZXRob2QKK2JlYW5zLjM3PVJldHVybiB0eXBlIG9mIGdldExpc3RlbmVyTWV0aG9kIGlzIG5vdCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMKK2JlYW5zLjM4PUFkZCBhbmQgcmVtb3ZlIG1ldGhvZHMgYXJlIG5vdCBhdmFpbGFibGUKK2JlYW5zLjM5PUNhbm5vdCBnZW5lcmF0ZSBldmVudCBzZXQgZGVzY3JpcHRvciBmb3IgbmFtZSB7MH0uCitiZWFucy4zQT1FdmVudCB0eXBlIHdpdGggbmFtZSB7MH0gaXMgbm90IGZvdW5kLgorYmVhbnMuM0I9c2tpcHBpbmcgZXhwcmVzc2lvbiB7MH0uLi4KK2JlYW5zLjNDPVVua25vd24gbWV0aG9kIG5hbWUgZm9yIGFycmF5CitiZWFucy4zRD1GaXJzdCBwYXJhbWV0ZXIgaW4gYXJyYXkgZ2V0dGVyKHNldHRlcikgaXMgbm90IG9mIEludGVnZXIgdHlwZQorYmVhbnMuM0U9SWxsZWdhbCBudW1iZXIgb2YgYXJndW1lbnRzIGluIGFycmF5IGdldHRlcgorYmVhbnMuM0Y9SWxsZWdhbCBudW1iZXIgb2YgYXJndW1lbnRzIGluIGFycmF5IHNldHRlcgorYmVhbnMuNDA9Tm8gY29uc3RydWN0b3IgZm9yIGNsYXNzIHswfSBmb3VuZAorYmVhbnMuNDE9Tm8gbWV0aG9kIHdpdGggbmFtZSB7MH0gaXMgZm91bmQKK2JlYW5zLjQyPXRhcmdldCBpcyBub3QgZ2VuZXJhdGVkOiBjbGFzc25hbWUgezB9IGlzIG5vdCBmb3VuZAorYmVhbnMuNDM9Q2Fubm90IGNvbnZlcnQgezB9IHRvIGNoYXIKK2JlYW5zLjQ0PWZvciBwcm9wZXJ0eSB7MH0gbm8gZ2V0dGVyKHNldHRlcikgaXMgZm91bmQKK2JlYW5zLjQ1PW1ldGhvZCBuYW1lIGlzIG5vdCBnZW5lcmF0ZWQ6IGVycm9yIGluIGdldE1ldGhvZE5hbWUoKQorYmVhbnMuNDY9Tm90IGEgdmFsaWQgY2hpbGQKK2JlYW5zLjQ3PVVuYWJsZSB0byBpbnN0YW50aWF0ZSBwcm9wZXJ0eSBlZGl0b3IKK2JlYW5zLjQ4PVByb3BlcnR5IGVkaXRvciBpcyBub3QgYXNzaWduYWJsZSBmcm9tIHRoZSBQcm9wZXJ0eUVkaXRvciBpbnRlcmZhY2UKK2JlYW5zLjQ5PUNoaWxkIGNhbm5vdCBpbXBsZW1lbnQgYm90aCBCZWFuQ29udGV4dENoaWxkIGFuZCBCZWFuQ29udGV4dFByb3h5CitiZWFucy40QT1uZXdJbnN0YW5jZSBpcyBudWxsCitiZWFucy40Qj10eXBlIGlzIG51bGwKK2JlYW5zLjRDPWVuY29kZXIgaXMgbnVsbAorYmVhbnMuNEQ9SW52YWxpZCBtZXRob2QgY2FsbAorYmVhbnMuNEU9c3RvcENsYXNzIGlzIG5vdCBhbmNlc3RvciBvZiBiZWFuQ2xhc3MKK2JlYW5zLjRGPXNlYXJjaCBwYXRoIGlzIG51bGwKK2JlYW5zLjUwPW5vdCBhbiBpbmRleGVkIHByb3BlcnR5CitiZWFucy41MT1MaXN0ZW5lciBtZXRob2QgezB9IHNob3VsZCBoYXZlIHBhcmFtZXRlciBvZiB0eXBlIHsxfQorYmVhbnMuNTI9bGlzdGVuZXJNZXRob2ROYW1lKHMpIGlzIG51bGwKK2JlYW5zLjUzPWV2ZW50U2V0TmFtZSBpcyBudWxsCitiZWFucy41ND1saXN0ZW5lclR5cGUgaXMgbnVsbAorYmVhbnMuNTU9TWV0aG9kIGlzIG51bGwKZGlmZiAtLWdpdCBhL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0FuZHJvaWQubWsgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkZmU2NTkKLS0tIC9kZXYvbnVsbAorKysgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsNTkgQEAKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQorCisjCisjIFNldCBVU0VfQ0FNRVJBX1NUVUIgZm9yIG5vbi1lbXVsYXRvciBhbmQgbm9uLXNpbXVsYXRvciBidWlsZHMsIGlmIHlvdSB3YW50CisjIHRoZSBjYW1lcmEgc2VydmljZSB0byB1c2UgdGhlIGZha2UgY2FtZXJhLiAgRm9yIGVtdWxhdG9yIG9yIHNpbXVsYXRvciBidWlsZHMsCisjIHdlIGFsd2F5cyB1c2UgdGhlIGZha2UgY2FtZXJhLgorCitpZmVxICgkKFVTRV9DQU1FUkFfU1RVQiksKQorVVNFX0NBTUVSQV9TVFVCOj1mYWxzZQoraWZuZXEgKCQoZmlsdGVyIHNvb25lciBnZW5lcmljIHNpbSwkKFRBUkdFVF9ERVZJQ0UpKSwpCitVU0VfQ0FNRVJBX1NUVUI6PXRydWUKK2VuZGlmICNsaWJjYW1lcmFzdHViCitlbmRpZgorCitpZmVxICgkKFVTRV9DQU1FUkFfU1RVQiksdHJ1ZSkKKyMKKyMgbGliY2FtZXJhc3R1YgorIworCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfU1JDX0ZJTEVTOj0gICAgICAgICAgICAgICBcCisgICAgQ2FtZXJhSGFyZHdhcmVTdHViLmNwcCAgICAgIFwKKyAgICBGYWtlQ2FtZXJhLmNwcAorCitMT0NBTF9NT0RVTEU6PSBsaWJjYW1lcmFzdHViCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVM6PSBsaWJ1aQorCitpbmNsdWRlICQoQlVJTERfU1RBVElDX0xJQlJBUlkpCitlbmRpZiAjIFVTRV9DQU1FUkFfU1RVQgorCisjCisjIGxpYmNhbWVyYXNlcnZpY2UKKyMKKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9ICAgICAgICAgICAgICAgXAorICAgIENhbWVyYVNlcnZpY2UuY3BwCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVM6PSBcCisgICAgbGlidWkgXAorICAgIGxpYnV0aWxzIFwKKyAgICBsaWJjdXRpbHMKKworTE9DQUxfTU9EVUxFOj0gbGliY2FtZXJhc2VydmljZQorCitMT0NBTF9DRkxBR1MrPS1ETE9HX1RBRz1cIkNhbWVyYVNlcnZpY2VcIgorCitpZmVxICgkKFVTRV9DQU1FUkFfU1RVQiksIHRydWUpCitMT0NBTF9TVEFUSUNfTElCUkFSSUVTICs9IGxpYmNhbWVyYXN0dWIKK0xPQ0FMX0NGTEFHUyArPSAtaW5jbHVkZSBDYW1lcmFIYXJkd2FyZVN0dWIuaAorZWxzZQorTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBsaWJjYW1lcmEgCitlbmRpZgorCitpbmNsdWRlICQoQlVJTERfU0hBUkVEX0xJQlJBUlkpCisKZGlmZiAtLWdpdCBhL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0NhbWVyYUhhcmR3YXJlU3R1Yi5jcHAgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW1lcmFIYXJkd2FyZVN0dWIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmMWFlOGUKLS0tIC9kZXYvbnVsbAorKysgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW1lcmFIYXJkd2FyZVN0dWIuY3BwCkBAIC0wLDAgKzEsMzg4IEBACisvKgorKioKKyoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjZGVmaW5lIExPR19UQUcgIkNhbWVyYUhhcmR3YXJlU3R1YiIKKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgIkNhbWVyYUhhcmR3YXJlU3R1Yi5oIgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisKKyNpbmNsdWRlICJDYW5uZWRKcGVnLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworQ2FtZXJhSGFyZHdhcmVTdHViOjpDYW1lcmFIYXJkd2FyZVN0dWIoKQorICAgICAgICAgICAgICAgICAgOiBtUGFyYW1ldGVycygpLAorICAgICAgICAgICAgICAgICAgICBtUHJldmlld0hlYXAoMCksCisgICAgICAgICAgICAgICAgICAgIG1SYXdIZWFwKDApLAorICAgICAgICAgICAgICAgICAgICBtRmFrZUNhbWVyYSgwKSwKKyAgICAgICAgICAgICAgICAgICAgbVByZXZpZXdGcmFtZVNpemUoMCksCisgICAgICAgICAgICAgICAgICAgIG1SYXdQaWN0dXJlQ2FsbGJhY2soMCksCisgICAgICAgICAgICAgICAgICAgIG1KcGVnUGljdHVyZUNhbGxiYWNrKDApLAorICAgICAgICAgICAgICAgICAgICBtUGljdHVyZUNhbGxiYWNrQ29va2llKDApLAorICAgICAgICAgICAgICAgICAgICBtUHJldmlld0NhbGxiYWNrKDApLAorICAgICAgICAgICAgICAgICAgICBtUHJldmlld0NhbGxiYWNrQ29va2llKDApLAorICAgICAgICAgICAgICAgICAgICBtQXV0b0ZvY3VzQ2FsbGJhY2soMCksCisgICAgICAgICAgICAgICAgICAgIG1BdXRvRm9jdXNDYWxsYmFja0Nvb2tpZSgwKSwKKyAgICAgICAgICAgICAgICAgICAgbUN1cnJlbnRQcmV2aWV3RnJhbWUoMCkKK3sKKyAgICBpbml0RGVmYXVsdFBhcmFtZXRlcnMoKTsKK30KKwordm9pZCBDYW1lcmFIYXJkd2FyZVN0dWI6OmluaXREZWZhdWx0UGFyYW1ldGVycygpCit7CisgICAgQ2FtZXJhUGFyYW1ldGVycyBwOworCisgICAgcC5zZXRQcmV2aWV3U2l6ZSgxNzYsIDE0NCk7CisgICAgcC5zZXRQcmV2aWV3RnJhbWVSYXRlKDE1KTsKKyAgICBwLnNldFByZXZpZXdGb3JtYXQoInl1djQyMnNwIik7CisKKyAgICBwLnNldFBpY3R1cmVTaXplKGtDYW5uZWRKcGVnV2lkdGgsIGtDYW5uZWRKcGVnSGVpZ2h0KTsKKyAgICBwLnNldFBpY3R1cmVGb3JtYXQoImpwZWciKTsKKworICAgIGlmIChzZXRQYXJhbWV0ZXJzKHApICE9IE5PX0VSUk9SKSB7CisgICAgICAgIExPR0UoIkZhaWxlZCB0byBzZXQgZGVmYXVsdCBwYXJhbWV0ZXJzPyEiKTsKKyAgICB9IAorfQorCit2b2lkIENhbWVyYUhhcmR3YXJlU3R1Yjo6aW5pdEhlYXBMb2NrZWQoKQoreworICAgIC8vIENyZWF0ZSByYXcgaGVhcC4KKyAgICBpbnQgcGljdHVyZV93aWR0aCwgcGljdHVyZV9oZWlnaHQ7CisgICAgbVBhcmFtZXRlcnMuZ2V0UGljdHVyZVNpemUoJnBpY3R1cmVfd2lkdGgsICZwaWN0dXJlX2hlaWdodCk7CisgICAgbVJhd0hlYXAgPSBuZXcgTWVtb3J5SGVhcEJhc2UocGljdHVyZV93aWR0aCAqIDIgKiBwaWN0dXJlX2hlaWdodCk7CisKKyAgICBpbnQgcHJldmlld193aWR0aCwgcHJldmlld19oZWlnaHQ7CisgICAgbVBhcmFtZXRlcnMuZ2V0UHJldmlld1NpemUoJnByZXZpZXdfd2lkdGgsICZwcmV2aWV3X2hlaWdodCk7CisgICAgTE9HRCgiaW5pdEhlYXBMb2NrZWQ6IHByZXZpZXcgc2l6ZT0lZHglZCIsIHByZXZpZXdfd2lkdGgsIHByZXZpZXdfaGVpZ2h0KTsKKworICAgIC8vIE5vdGUgdGhhdCB3ZSBlbmZvcmNlIHl1djQyMiBpbiBzZXRQYXJhbWV0ZXJzKCkuCisgICAgaW50IGhvd19iaWcgPSBwcmV2aWV3X3dpZHRoICogcHJldmlld19oZWlnaHQgKiAyOworCisgICAgLy8gSWYgd2UgYXJlIGJlaW5nIHJlaW5pdGlhbGl6ZWQgdG8gdGhlIHNhbWUgc2l6ZSBhcyBiZWZvcmUsIG5vCisgICAgLy8gd29yayBuZWVkcyB0byBiZSBkb25lLgorICAgIGlmIChob3dfYmlnID09IG1QcmV2aWV3RnJhbWVTaXplKQorICAgICAgICByZXR1cm47CisKKyAgICBtUHJldmlld0ZyYW1lU2l6ZSA9IGhvd19iaWc7CisKKyAgICAvLyBNYWtlIGEgbmV3IG1tYXAnZWQgaGVhcCB0aGF0IGNhbiBiZSBzaGFyZWQgYWNyb3NzIHByb2Nlc3Nlcy4gCisgICAgLy8gdXNlIGNvZGUgYmVsb3cgdG8gdGVzdCB3aXRoIHBtZW0KKyAgICBtUHJldmlld0hlYXAgPSBuZXcgTWVtb3J5SGVhcEJhc2UobVByZXZpZXdGcmFtZVNpemUgKiBrQnVmZmVyQ291bnQpOworICAgIC8vIE1ha2UgYW4gSU1lbW9yeSBmb3IgZWFjaCBmcmFtZSBzbyB0aGF0IHdlIGNhbiByZXVzZSB0aGVtIGluIGNhbGxiYWNrcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtCdWZmZXJDb3VudDsgaSsrKSB7CisgICAgICAgIG1CdWZmZXJzW2ldID0gbmV3IE1lbW9yeUJhc2UobVByZXZpZXdIZWFwLCBpICogbVByZXZpZXdGcmFtZVNpemUsIG1QcmV2aWV3RnJhbWVTaXplKTsKKyAgICB9CisgICAgCisgICAgLy8gUmVjcmVhdGUgdGhlIGZha2UgY2FtZXJhIHRvIHJlZmxlY3QgdGhlIGN1cnJlbnQgc2l6ZS4KKyAgICBkZWxldGUgbUZha2VDYW1lcmE7CisgICAgbUZha2VDYW1lcmEgPSBuZXcgRmFrZUNhbWVyYShwcmV2aWV3X3dpZHRoLCBwcmV2aWV3X2hlaWdodCk7Cit9CisKK0NhbWVyYUhhcmR3YXJlU3R1Yjo6fkNhbWVyYUhhcmR3YXJlU3R1YigpCit7CisgICAgZGVsZXRlIG1GYWtlQ2FtZXJhOworICAgIG1GYWtlQ2FtZXJhID0gMDsgLy8gcGFyYW5vaWEKKyAgICBzaW5nbGV0b24uY2xlYXIoKTsKK30KKworc3A8SU1lbW9yeUhlYXA+IENhbWVyYUhhcmR3YXJlU3R1Yjo6Z2V0UHJldmlld0hlYXAoKSBjb25zdAoreworICAgIHJldHVybiBtUHJldmlld0hlYXA7Cit9CisKK3NwPElNZW1vcnlIZWFwPiBDYW1lcmFIYXJkd2FyZVN0dWI6OmdldFJhd0hlYXAoKSBjb25zdAoreworICAgIHJldHVybiBtUmF3SGVhcDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2ludCBDYW1lcmFIYXJkd2FyZVN0dWI6OnByZXZpZXdUaHJlYWQoKQoreworICAgIG1Mb2NrLmxvY2soKTsKKyAgICAgICAgLy8gdGhlIGF0dHJpYnV0ZXMgYmVsb3cgY2FuIGNoYW5nZSB1bmRlciBvdXIgZmVldC4uLgorCisgICAgICAgIGludCBwcmV2aWV3RnJhbWVSYXRlID0gbVBhcmFtZXRlcnMuZ2V0UHJldmlld0ZyYW1lUmF0ZSgpOworCisgICAgICAgIC8vIEZpbmQgdGhlIG9mZnNldCB3aXRoaW4gdGhlIGhlYXAgb2YgdGhlIGN1cnJlbnQgYnVmZmVyLgorICAgICAgICBzc2l6ZV90IG9mZnNldCA9IG1DdXJyZW50UHJldmlld0ZyYW1lICogbVByZXZpZXdGcmFtZVNpemU7CisKKyAgICAgICAgc3A8TWVtb3J5SGVhcEJhc2U+IGhlYXAgPSBtUHJldmlld0hlYXA7CisgICAgCisgICAgICAgIC8vIHRoaXMgYXNzdW1lcyB0aGUgaW50ZXJuYWwgc3RhdGUgb2YgZmFrZSBjYW1lcmEgZG9lc24ndCBjaGFuZ2UKKyAgICAgICAgLy8gKG9yIGlzIHRocmVhZCBzYWZlKQorICAgICAgICBGYWtlQ2FtZXJhKiBmYWtlQ2FtZXJhID0gbUZha2VDYW1lcmE7CisgICAgICAgIAorICAgICAgICBzcDxNZW1vcnlCYXNlPiBidWZmZXIgPSBtQnVmZmVyc1ttQ3VycmVudFByZXZpZXdGcmFtZV07CisgICAgICAgIAorICAgIG1Mb2NrLnVubG9jaygpOworCisgICAgLy8gVE9ETzogaGVyZSBjaGVjayBhbGwgdGhlIGNvbmRpdGlvbnMgdGhhdCBjb3VsZCBnbyB3cm9uZworICAgIGlmIChidWZmZXIgIT0gMCkgeworICAgICAgICAvLyBDYWxjdWxhdGUgaG93IGxvbmcgdG8gd2FpdCBiZXR3ZWVuIGZyYW1lcy4KKyAgICAgICAgaW50IGRlbGF5ID0gKGludCkoMTAwMDAwMC4wZiAvIGZsb2F0KHByZXZpZXdGcmFtZVJhdGUpKTsKKyAgICAKKyAgICAgICAgLy8gVGhpcyBpcyBhbHdheXMgdmFsaWQsIGV2ZW4gaWYgdGhlIGNsaWVudCBkaWVkIC0tIHRoZSBtZW1vcnkKKyAgICAgICAgLy8gaXMgc3RpbGwgbWFwcGVkIGluIG91ciBwcm9jZXNzLgorICAgICAgICB2b2lkICpiYXNlID0gaGVhcC0+YmFzZSgpOworICAgIAorICAgICAgICAvLyBGaWxsIHRoZSBjdXJyZW50IGZyYW1lIHdpdGggdGhlIGZha2UgY2FtZXJhLgorICAgICAgICB1aW50OF90ICpmcmFtZSA9ICgodWludDhfdCAqKWJhc2UpICsgb2Zmc2V0OworICAgICAgICBmYWtlQ2FtZXJhLT5nZXROZXh0RnJhbWVBc1l1djQyMihmcmFtZSk7CisgICAgCisgICAgICAgIC8vTE9HVigicHJldmlld1RocmVhZDogZ2VuZXJhdGVkIGZyYW1lIHRvIGJ1ZmZlciAlZCIsIG1DdXJyZW50UHJldmlld0ZyYW1lKTsKKyAgICAgICAgCisgICAgICAgIC8vIE5vdGlmeSB0aGUgY2xpZW50IG9mIGEgbmV3IGZyYW1lLgorICAgICAgICBtUHJldmlld0NhbGxiYWNrKGJ1ZmZlciwgbVByZXZpZXdDYWxsYmFja0Nvb2tpZSk7CisgICAgCisgICAgICAgIC8vIEFkdmFuY2UgdGhlIGJ1ZmZlciBwb2ludGVyLgorICAgICAgICBtQ3VycmVudFByZXZpZXdGcmFtZSA9IChtQ3VycmVudFByZXZpZXdGcmFtZSArIDEpICUga0J1ZmZlckNvdW50OworCisgICAgICAgIC8vIFdhaXQgZm9yIGl0Li4uCisgICAgICAgIHVzbGVlcChkZWxheSk7CisgICAgfQorCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBDYW1lcmFIYXJkd2FyZVN0dWI6OnN0YXJ0UHJldmlldyhwcmV2aWV3X2NhbGxiYWNrIGNiLCB2b2lkKiB1c2VyKQoreworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICBpZiAobVByZXZpZXdUaHJlYWQgIT0gMCkgeworICAgICAgICAvLyBhbHJlYWR5IHJ1bm5pbmcKKyAgICAgICAgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworICAgIH0KKyAgICBtUHJldmlld0NhbGxiYWNrID0gY2I7CisgICAgbVByZXZpZXdDYWxsYmFja0Nvb2tpZSA9IHVzZXI7CisgICAgbVByZXZpZXdUaHJlYWQgPSBuZXcgUHJldmlld1RocmVhZCh0aGlzKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3ZvaWQgQ2FtZXJhSGFyZHdhcmVTdHViOjpzdG9wUHJldmlldygpCit7CisgICAgc3A8UHJldmlld1RocmVhZD4gcHJldmlld1RocmVhZDsKKyAgICAKKyAgICB7IC8vIHNjb3BlIGZvciB0aGUgbG9jaworICAgICAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgICAgIHByZXZpZXdUaHJlYWQgPSBtUHJldmlld1RocmVhZDsKKyAgICB9CisKKyAgICAvLyBkb24ndCBob2xkIHRoZSBsb2NrIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSB0aHJlYWQgdG8gcXVpdAorICAgIGlmIChwcmV2aWV3VGhyZWFkICE9IDApIHsKKyAgICAgICAgcHJldmlld1RocmVhZC0+cmVxdWVzdEV4aXRBbmRXYWl0KCk7CisgICAgfQorCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIG1QcmV2aWV3VGhyZWFkLmNsZWFyKCk7Cit9CisKK2Jvb2wgQ2FtZXJhSGFyZHdhcmVTdHViOjpwcmV2aWV3RW5hYmxlZCgpIHsKKyAgICByZXR1cm4gbVByZXZpZXdUaHJlYWQgIT0gMDsKK30KKworc3RhdHVzX3QgQ2FtZXJhSGFyZHdhcmVTdHViOjpzdGFydFJlY29yZGluZyhyZWNvcmRpbmdfY2FsbGJhY2sgY2IsIHZvaWQqIHVzZXIpCit7CisgICAgcmV0dXJuIFVOS05PV05fRVJST1I7Cit9CisKK3ZvaWQgQ2FtZXJhSGFyZHdhcmVTdHViOjpzdG9wUmVjb3JkaW5nKCkKK3sKK30KKworYm9vbCBDYW1lcmFIYXJkd2FyZVN0dWI6OnJlY29yZGluZ0VuYWJsZWQoKQoreworICAgIHJldHVybiBmYWxzZTsKK30KKwordm9pZCBDYW1lcmFIYXJkd2FyZVN0dWI6OnJlbGVhc2VSZWNvcmRpbmdGcmFtZShjb25zdCBzcDxJTWVtb3J5PiYgbWVtKQoreworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworaW50IENhbWVyYUhhcmR3YXJlU3R1Yjo6YmVnaW5BdXRvRm9jdXNUaHJlYWQodm9pZCAqY29va2llKQoreworICAgIENhbWVyYUhhcmR3YXJlU3R1YiAqYyA9IChDYW1lcmFIYXJkd2FyZVN0dWIgKiljb29raWU7CisgICAgcmV0dXJuIGMtPmF1dG9Gb2N1c1RocmVhZCgpOworfQorCitpbnQgQ2FtZXJhSGFyZHdhcmVTdHViOjphdXRvRm9jdXNUaHJlYWQoKQoreworICAgIGlmIChtQXV0b0ZvY3VzQ2FsbGJhY2sgIT0gTlVMTCkgeworICAgICAgICBtQXV0b0ZvY3VzQ2FsbGJhY2sodHJ1ZSwgbUF1dG9Gb2N1c0NhbGxiYWNrQ29va2llKTsKKyAgICAgICAgbUF1dG9Gb2N1c0NhbGxiYWNrID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKK30KKworc3RhdHVzX3QgQ2FtZXJhSGFyZHdhcmVTdHViOjphdXRvRm9jdXMoYXV0b2ZvY3VzX2NhbGxiYWNrIGFmX2NiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdXNlcikKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisKKyAgICBpZiAobUF1dG9Gb2N1c0NhbGxiYWNrICE9IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIG1BdXRvRm9jdXNDYWxsYmFjayA9PSBhZl9jYiA/IE5PX0VSUk9SIDogSU5WQUxJRF9PUEVSQVRJT047CisgICAgfQorCisgICAgbUF1dG9Gb2N1c0NhbGxiYWNrID0gYWZfY2I7CisgICAgbUF1dG9Gb2N1c0NhbGxiYWNrQ29va2llID0gdXNlcjsKKyAgICBpZiAoY3JlYXRlVGhyZWFkKGJlZ2luQXV0b0ZvY3VzVGhyZWFkLCB0aGlzKSA9PSBmYWxzZSkKKyAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvKnN0YXRpYyovIGludCBDYW1lcmFIYXJkd2FyZVN0dWI6OmJlZ2luUGljdHVyZVRocmVhZCh2b2lkICpjb29raWUpCit7CisgICAgQ2FtZXJhSGFyZHdhcmVTdHViICpjID0gKENhbWVyYUhhcmR3YXJlU3R1YiAqKWNvb2tpZTsKKyAgICByZXR1cm4gYy0+cGljdHVyZVRocmVhZCgpOworfQorCitpbnQgQ2FtZXJhSGFyZHdhcmVTdHViOjpwaWN0dXJlVGhyZWFkKCkKK3sKKyAgICBpZiAobVNodXR0ZXJDYWxsYmFjaykKKyAgICAgICAgbVNodXR0ZXJDYWxsYmFjayhtUGljdHVyZUNhbGxiYWNrQ29va2llKTsKKworICAgIGlmIChtUmF3UGljdHVyZUNhbGxiYWNrKSB7CisgICAgICAgIC8vRklYTUU6IHVzZSBhIGNhbm5lZCBZVVYgaW1hZ2UhCisgICAgICAgIC8vIEluIHRoZSBtZWFudGltZSBqdXN0IG1ha2UgYW5vdGhlciBmYWtlIGNhbWVyYSBwaWN0dXJlLgorICAgICAgICBpbnQgdywgaDsKKyAgICAgICAgbVBhcmFtZXRlcnMuZ2V0UGljdHVyZVNpemUoJncsICZoKTsKKyAgICAgICAgc3A8TWVtb3J5QmFzZT4gbWVtID0gbmV3IE1lbW9yeUJhc2UobVJhd0hlYXAsIDAsIHcgKiAyICogaCk7CisgICAgICAgIEZha2VDYW1lcmEgY2FtKHcsIGgpOworICAgICAgICBjYW0uZ2V0TmV4dEZyYW1lQXNZdXY0MjIoKHVpbnQ4X3QgKiltUmF3SGVhcC0+YmFzZSgpKTsKKyAgICAgICAgaWYgKG1SYXdQaWN0dXJlQ2FsbGJhY2spCisgICAgICAgICAgICBtUmF3UGljdHVyZUNhbGxiYWNrKG1lbSwgbVBpY3R1cmVDYWxsYmFja0Nvb2tpZSk7CisgICAgfQorCisgICAgaWYgKG1KcGVnUGljdHVyZUNhbGxiYWNrKSB7CisgICAgICAgIHNwPE1lbW9yeUhlYXBCYXNlPiBoZWFwID0gbmV3IE1lbW9yeUhlYXBCYXNlKGtDYW5uZWRKcGVnU2l6ZSk7CisgICAgICAgIHNwPE1lbW9yeUJhc2U+IG1lbSA9IG5ldyBNZW1vcnlCYXNlKGhlYXAsIDAsIGtDYW5uZWRKcGVnU2l6ZSk7CisgICAgICAgIG1lbWNweShoZWFwLT5iYXNlKCksIGtDYW5uZWRKcGVnLCBrQ2FubmVkSnBlZ1NpemUpOworICAgICAgICBpZiAobUpwZWdQaWN0dXJlQ2FsbGJhY2spCisgICAgICAgICAgICBtSnBlZ1BpY3R1cmVDYWxsYmFjayhtZW0sIG1QaWN0dXJlQ2FsbGJhY2tDb29raWUpOworICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IENhbWVyYUhhcmR3YXJlU3R1Yjo6dGFrZVBpY3R1cmUoc2h1dHRlcl9jYWxsYmFjayBzaHV0dGVyX2NiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfY2FsbGJhY2sgcmF3X2NiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcGVnX2NhbGxiYWNrIGpwZWdfY2IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIHVzZXIpCit7CisgICAgc3RvcFByZXZpZXcoKTsKKyAgICBtU2h1dHRlckNhbGxiYWNrID0gc2h1dHRlcl9jYjsKKyAgICBtUmF3UGljdHVyZUNhbGxiYWNrID0gcmF3X2NiOworICAgIG1KcGVnUGljdHVyZUNhbGxiYWNrID0ganBlZ19jYjsKKyAgICBtUGljdHVyZUNhbGxiYWNrQ29va2llID0gdXNlcjsKKyAgICBpZiAoY3JlYXRlVGhyZWFkKGJlZ2luUGljdHVyZVRocmVhZCwgdGhpcykgPT0gZmFsc2UpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IENhbWVyYUhhcmR3YXJlU3R1Yjo6Y2FuY2VsUGljdHVyZShib29sIGNhbmNlbF9zaHV0dGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2FuY2VsX3JhdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGNhbmNlbF9qcGVnKQoreworICAgIGlmIChjYW5jZWxfc2h1dHRlcikgbVNodXR0ZXJDYWxsYmFjayA9IE5VTEw7CisgICAgaWYgKGNhbmNlbF9yYXcpIG1SYXdQaWN0dXJlQ2FsbGJhY2sgPSBOVUxMOworICAgIGlmIChjYW5jZWxfanBlZykgbUpwZWdQaWN0dXJlQ2FsbGJhY2sgPSBOVUxMOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQ2FtZXJhSGFyZHdhcmVTdHViOjpkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykgY29uc3QKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKyAgICBBdXRvTXV0ZXggbG9jaygmbUxvY2spOworICAgIGlmIChtRmFrZUNhbWVyYSAhPSAwKSB7CisgICAgICAgIG1GYWtlQ2FtZXJhLT5kdW1wKGZkLCBhcmdzKTsKKyAgICAgICAgbVBhcmFtZXRlcnMuZHVtcChmZCwgYXJncyk7CisgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgMjU1LCAiIHByZXZpZXcgZnJhbWUoJWQpLCBzaXplICglZCksIHJ1bm5pbmcoJXMpXG4iLCBtQ3VycmVudFByZXZpZXdGcmFtZSwgbVByZXZpZXdGcmFtZVNpemUsIG1QcmV2aWV3UnVubmluZz8idHJ1ZSI6ICJmYWxzZSIpOworICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiTm8gY2FtZXJhIGNsaWVudCB5ZXQuXG4iKTsKKyAgICB9CisgICAgd3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBDYW1lcmFIYXJkd2FyZVN0dWI6OnNldFBhcmFtZXRlcnMoY29uc3QgQ2FtZXJhUGFyYW1ldGVycyYgcGFyYW1zKQoreworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICAvLyBYWFggdmVyaWZ5IHBhcmFtcworCisgICAgaWYgKHN0cmNtcChwYXJhbXMuZ2V0UHJldmlld0Zvcm1hdCgpLCAieXV2NDIyc3AiKSAhPSAwKSB7CisgICAgICAgIExPR0UoIk9ubHkgeXV2NDIyc3AgcHJldmlldyBpcyBzdXBwb3J0ZWQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmIChzdHJjbXAocGFyYW1zLmdldFBpY3R1cmVGb3JtYXQoKSwgImpwZWciKSAhPSAwKSB7CisgICAgICAgIExPR0UoIk9ubHkganBlZyBzdGlsbCBwaWN0dXJlcyBhcmUgc3VwcG9ydGVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpbnQgdywgaDsKKyAgICBwYXJhbXMuZ2V0UGljdHVyZVNpemUoJncsICZoKTsKKyAgICBpZiAodyAhPSBrQ2FubmVkSnBlZ1dpZHRoICYmIGggIT0ga0Nhbm5lZEpwZWdIZWlnaHQpIHsKKyAgICAgICAgTE9HRSgiU3RpbGwgcGljdHVyZSBzaXplIG11c3QgYmUgc2l6ZSBvZiBjYW5uZWQgSlBFRyAoJWR4JWQpIiwKKyAgICAgICAgICAgICBrQ2FubmVkSnBlZ1dpZHRoLCBrQ2FubmVkSnBlZ0hlaWdodCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBtUGFyYW1ldGVycyA9IHBhcmFtczsKKworICAgIGluaXRIZWFwTG9ja2VkKCk7CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK0NhbWVyYVBhcmFtZXRlcnMgQ2FtZXJhSGFyZHdhcmVTdHViOjpnZXRQYXJhbWV0ZXJzKCkgY29uc3QKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgcmV0dXJuIG1QYXJhbWV0ZXJzOworfQorCit2b2lkIENhbWVyYUhhcmR3YXJlU3R1Yjo6cmVsZWFzZSgpCit7Cit9CisKK3dwPENhbWVyYUhhcmR3YXJlSW50ZXJmYWNlPiBDYW1lcmFIYXJkd2FyZVN0dWI6OnNpbmdsZXRvbjsKKworc3A8Q2FtZXJhSGFyZHdhcmVJbnRlcmZhY2U+IENhbWVyYUhhcmR3YXJlU3R1Yjo6Y3JlYXRlSW5zdGFuY2UoKQoreworICAgIGlmIChzaW5nbGV0b24gIT0gMCkgeworICAgICAgICBzcDxDYW1lcmFIYXJkd2FyZUludGVyZmFjZT4gaGFyZHdhcmUgPSBzaW5nbGV0b24ucHJvbW90ZSgpOworICAgICAgICBpZiAoaGFyZHdhcmUgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGhhcmR3YXJlOworICAgICAgICB9CisgICAgfQorICAgIHNwPENhbWVyYUhhcmR3YXJlSW50ZXJmYWNlPiBoYXJkd2FyZShuZXcgQ2FtZXJhSGFyZHdhcmVTdHViKCkpOworICAgIHNpbmdsZXRvbiA9IGhhcmR3YXJlOworICAgIHJldHVybiBoYXJkd2FyZTsKK30KKworZXh0ZXJuICJDIiBzcDxDYW1lcmFIYXJkd2FyZUludGVyZmFjZT4gb3BlbkNhbWVyYUhhcmR3YXJlKCkKK3sKKyAgICByZXR1cm4gQ2FtZXJhSGFyZHdhcmVTdHViOjpjcmVhdGVJbnN0YW5jZSgpOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvQ2FtZXJhSGFyZHdhcmVTdHViLmggYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW1lcmFIYXJkd2FyZVN0dWIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDI2ZDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvQ2FtZXJhSGFyZHdhcmVTdHViLmgKQEAgLTAsMCArMSwxMjQgQEAKKy8qCisqKgorKiogQ29weXJpZ2h0IDIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9IQVJEV0FSRV9DQU1FUkFfSEFSRFdBUkVfU1RVQl9ICisjZGVmaW5lIEFORFJPSURfSEFSRFdBUkVfQ0FNRVJBX0hBUkRXQVJFX1NUVUJfSAorCisjaW5jbHVkZSAiRmFrZUNhbWVyYS5oIgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKyNpbmNsdWRlIDx1aS9DYW1lcmFIYXJkd2FyZUludGVyZmFjZS5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9NZW1vcnlIZWFwQmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBDYW1lcmFIYXJkd2FyZVN0dWIgOiBwdWJsaWMgQ2FtZXJhSGFyZHdhcmVJbnRlcmZhY2UgeworcHVibGljOgorICAgIHZpcnR1YWwgc3A8SU1lbW9yeUhlYXA+IGdldFByZXZpZXdIZWFwKCkgY29uc3Q7CisgICAgdmlydHVhbCBzcDxJTWVtb3J5SGVhcD4gZ2V0UmF3SGVhcCgpIGNvbnN0OworCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFydFByZXZpZXcocHJldmlld19jYWxsYmFjayBjYiwgdm9pZCogdXNlcik7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBzdG9wUHJldmlldygpOworICAgIHZpcnR1YWwgYm9vbCAgICAgICAgcHJldmlld0VuYWJsZWQoKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc3RhcnRSZWNvcmRpbmcocmVjb3JkaW5nX2NhbGxiYWNrIGNiLCB2b2lkKiB1c2VyKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHN0b3BSZWNvcmRpbmcoKTsKKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgIHJlY29yZGluZ0VuYWJsZWQoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHJlbGVhc2VSZWNvcmRpbmdGcmFtZShjb25zdCBzcDxJTWVtb3J5PiYgbWVtKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgYXV0b0ZvY3VzKGF1dG9mb2N1c19jYWxsYmFjaywgdm9pZCAqdXNlcik7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICB0YWtlUGljdHVyZShzaHV0dGVyX2NhbGxiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X2NhbGxiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganBlZ19jYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIHVzZXIpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgY2FuY2VsUGljdHVyZShib29sIGNhbmNlbF9zaHV0dGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGNhbmNlbF9yYXcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2FuY2VsX2pwZWcpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpIGNvbnN0OworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0UGFyYW1ldGVycyhjb25zdCBDYW1lcmFQYXJhbWV0ZXJzJiBwYXJhbXMpOworICAgIHZpcnR1YWwgQ2FtZXJhUGFyYW1ldGVycyAgZ2V0UGFyYW1ldGVycygpIGNvbnN0OworICAgIHZpcnR1YWwgdm9pZCByZWxlYXNlKCk7CisKKyAgICBzdGF0aWMgc3A8Q2FtZXJhSGFyZHdhcmVJbnRlcmZhY2U+IGNyZWF0ZUluc3RhbmNlKCk7CisKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICBDYW1lcmFIYXJkd2FyZVN0dWIoKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5DYW1lcmFIYXJkd2FyZVN0dWIoKTsKKworICAgIHN0YXRpYyB3cDxDYW1lcmFIYXJkd2FyZUludGVyZmFjZT4gc2luZ2xldG9uOworCisgICAgc3RhdGljIGNvbnN0IGludCBrQnVmZmVyQ291bnQgPSA0OworCisgICAgY2xhc3MgUHJldmlld1RocmVhZCA6IHB1YmxpYyBUaHJlYWQgeworICAgICAgICBDYW1lcmFIYXJkd2FyZVN0dWIqIG1IYXJkd2FyZTsKKyAgICBwdWJsaWM6CisgICAgICAgIFByZXZpZXdUaHJlYWQoQ2FtZXJhSGFyZHdhcmVTdHViKiBodykKKyAgICAgICAgICAgIDogVGhyZWFkKGZhbHNlKSwgbUhhcmR3YXJlKGh3KSB7IH0KKyAgICAgICAgdmlydHVhbCB2b2lkIG9uRmlyc3RSZWYoKSB7CisgICAgICAgICAgICBydW4oIkNhbWVyYVByZXZpZXdUaHJlYWQiLCBQUklPUklUWV9VUkdFTlRfRElTUExBWSk7CisgICAgICAgIH0KKyAgICAgICAgdmlydHVhbCBib29sIHRocmVhZExvb3AoKSB7CisgICAgICAgICAgICBtSGFyZHdhcmUtPnByZXZpZXdUaHJlYWQoKTsKKyAgICAgICAgICAgIC8vIGxvb3AgdW50aWwgd2UgbmVlZCB0byBxdWl0CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICB2b2lkIGluaXREZWZhdWx0UGFyYW1ldGVycygpOworICAgIHZvaWQgaW5pdEhlYXBMb2NrZWQoKTsKKworICAgIGludCBwcmV2aWV3VGhyZWFkKCk7CisKKyAgICBzdGF0aWMgaW50IGJlZ2luQXV0b0ZvY3VzVGhyZWFkKHZvaWQgKmNvb2tpZSk7CisgICAgaW50IGF1dG9Gb2N1c1RocmVhZCgpOworCisgICAgc3RhdGljIGludCBiZWdpblBpY3R1cmVUaHJlYWQodm9pZCAqY29va2llKTsKKyAgICBpbnQgcGljdHVyZVRocmVhZCgpOworCisgICAgbXV0YWJsZSBNdXRleCAgICAgICBtTG9jazsKKworICAgIENhbWVyYVBhcmFtZXRlcnMgICAgbVBhcmFtZXRlcnM7CisKKyAgICBzcDxNZW1vcnlIZWFwQmFzZT4gIG1QcmV2aWV3SGVhcDsKKyAgICBzcDxNZW1vcnlIZWFwQmFzZT4gIG1SYXdIZWFwOworICAgIHNwPE1lbW9yeUJhc2U+ICAgICAgbUJ1ZmZlcnNba0J1ZmZlckNvdW50XTsKKworICAgIEZha2VDYW1lcmEgICAgICAgICAgKm1GYWtlQ2FtZXJhOworICAgIGJvb2wgICAgICAgICAgICAgICAgbVByZXZpZXdSdW5uaW5nOworICAgIGludCAgICAgICAgICAgICAgICAgbVByZXZpZXdGcmFtZVNpemU7CisKKyAgICBzaHV0dGVyX2NhbGxiYWNrICAgIG1TaHV0dGVyQ2FsbGJhY2s7CisgICAgcmF3X2NhbGxiYWNrICAgICAgICBtUmF3UGljdHVyZUNhbGxiYWNrOworICAgIGpwZWdfY2FsbGJhY2sgICAgICAgbUpwZWdQaWN0dXJlQ2FsbGJhY2s7CisgICAgdm9pZCAgICAgICAgICAgICAgICAqbVBpY3R1cmVDYWxsYmFja0Nvb2tpZTsKKworICAgIC8vIHByb3RlY3RlZCBieSBtTG9jaworICAgIHNwPFByZXZpZXdUaHJlYWQ+ICAgbVByZXZpZXdUaHJlYWQ7CisgICAgcHJldmlld19jYWxsYmFjayAgICBtUHJldmlld0NhbGxiYWNrOworICAgIHZvaWQgICAgICAgICAgICAgICAgKm1QcmV2aWV3Q2FsbGJhY2tDb29raWU7CisKKyAgICBhdXRvZm9jdXNfY2FsbGJhY2sgIG1BdXRvRm9jdXNDYWxsYmFjazsKKyAgICB2b2lkICAgICAgICAgICAgICAgICptQXV0b0ZvY3VzQ2FsbGJhY2tDb29raWU7CisKKyAgICAvLyBvbmx5IHVzZWQgZnJvbSBQcmV2aWV3VGhyZWFkCisgICAgaW50ICAgICAgICAgICAgICAgICBtQ3VycmVudFByZXZpZXdGcmFtZTsKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvQ2FtZXJhU2VydmljZS5jcHAgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW1lcmFTZXJ2aWNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNWUzYjIxCi0tLSAvZGV2L251bGwKKysrIGIvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvQ2FtZXJhU2VydmljZS5jcHAKQEAgLTAsMCArMSwxMDczIEBACisvKgorKioKKyoqIENvcHlyaWdodCAoQykgMjAwOCwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKiogQ29weXJpZ2h0IChDKSAyMDA4IEhUQyBJbmMuCisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisvLyNkZWZpbmUgTE9HX05ERUJVRyAwCisjZGVmaW5lIExPR19UQUcgIkNhbWVyYVNlcnZpY2UiCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzE2Lmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5QmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBCYXNlLmg+CisjaW5jbHVkZSA8dWkvSUNhbWVyYVNlcnZpY2UuaD4KKworI2luY2x1ZGUgIkNhbWVyYVNlcnZpY2UuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitleHRlcm4gIkMiIHsKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxwdGhyZWFkLmg+Cit9CisKKy8vIFdoZW4geW91IGVuYWJsZSB0aGlzLCBhcyB3ZWxsIGFzIERFQlVHX1JFRlM9MSBhbmQKKy8vIERFQlVHX1JFRlNfRU5BQkxFRF9CWV9ERUZBVUxUPTAgaW4gbGlidXRpbHMvUmVmQmFzZS5jcHAsIHRoaXMgd2lsbCB0cmFjayBhbGwKKy8vIHJlZmVyZW5jZXMgdG8gdGhlIENhbWVyYVNlcnZpY2U6OkNsaWVudCBpbiBvcmRlciB0byBjYXRjaCB0aGUgY2FzZSB3aGVyZSB0aGUKKy8vIGNsaWVudCBpcyBiZWluZyBkZXN0cm95ZWQgd2hpbGUgYSBjYWxsYmFjayBmcm9tIHRoZSBDYW1lcmFIYXJkd2FyZUludGVyZmFjZQorLy8gaXMgb3V0c3RhbmRpbmcuICBUaGlzIGlzIGEgc2VyaW91cyBidWcgYmVjYXVzZSBpZiB3ZSBtYWtlIGFub3RoZXIgY2FsbCBpbnRvCisvLyBDYW1lcmFIYXJkd3JlSW50ZXJmYWNlIHRoYXQgaXRzZWxmIHRyaWdnZXJzIGEgY2FsbGJhY2ssIHdlIHdpbGwgZGVhZGxvY2suCisKKyNkZWZpbmUgREVCVUdfQ0xJRU5UX1JFRkVSRU5DRVMgMAorCisjZGVmaW5lIFBJQ1RVUkVfVElNRU9VVCBzZWNvbmRzKDUpCisKKyNkZWZpbmUgREVCVUdfRFVNUF9QUkVWSUVXX0ZSQU1FX1RPX0ZJTEUgMCAvKiBuLXRoIGZyYW1lIHRvIHdyaXRlICovCisjZGVmaW5lIERFQlVHX0RVTVBfSlBFR19TTkFQU0hPVF9UT19GSUxFIDAKKyNkZWZpbmUgREVCVUdfRFVNUF9ZVVZfU05BUFNIT1RfVE9fRklMRSAwCisKKyNpZiBERUJVR19EVU1QX1BSRVZJRVdfRlJBTUVfVE9fRklMRQorc3RhdGljIGludCBkZWJ1Z19mcmFtZV9jbnQ7CisjZW5kaWYKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIENhbWVyYVNlcnZpY2U6Omluc3RhbnRpYXRlKCkgeworICAgIGRlZmF1bHRTZXJ2aWNlTWFuYWdlcigpLT5hZGRTZXJ2aWNlKAorICAgICAgICAgICAgU3RyaW5nMTYoIm1lZGlhLmNhbWVyYSIpLCBuZXcgQ2FtZXJhU2VydmljZSgpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitDYW1lcmFTZXJ2aWNlOjpDYW1lcmFTZXJ2aWNlKCkgOgorICAgIEJuQ2FtZXJhU2VydmljZSgpCit7CisgICAgTE9HSSgiQ2FtZXJhU2VydmljZSBzdGFydGVkOiBwaWQ9JWQiLCBnZXRwaWQoKSk7Cit9CisKK0NhbWVyYVNlcnZpY2U6On5DYW1lcmFTZXJ2aWNlKCkKK3sKKyAgICBpZiAobUNsaWVudCAhPSAwKSB7CisgICAgICAgIExPR0UoIm1DbGllbnQgd2FzIHN0aWxsIGNvbm5lY3RlZCBpbiBkZXN0cnVjdG9yISIpOworICAgIH0KK30KKworc3A8SUNhbWVyYT4gQ2FtZXJhU2VydmljZTo6Y29ubmVjdChjb25zdCBzcDxJQ2FtZXJhQ2xpZW50PiYgY2FtZXJhQ2xpZW50KQoreworICAgIExPR0QoIkNvbm5lY3QgRSBmcm9tIElDYW1lcmFDbGllbnQgJXAiLCBjYW1lcmFDbGllbnQtPmFzQmluZGVyKCkuZ2V0KCkpOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIHNwPENsaWVudD4gY2xpZW50OworICAgIGlmIChtQ2xpZW50ICE9IDApIHsKKyAgICAgICAgc3A8Q2xpZW50PiBjdXJyZW50Q2xpZW50ID0gbUNsaWVudC5wcm9tb3RlKCk7CisgICAgICAgIGlmIChjdXJyZW50Q2xpZW50ICE9IDApIHsKKyAgICAgICAgICAgIHNwPElDYW1lcmFDbGllbnQ+IGN1cnJlbnRDYW1lcmFDbGllbnQoY3VycmVudENsaWVudC0+Z2V0Q2FtZXJhQ2xpZW50KCkpOworICAgICAgICAgICAgaWYgKGNhbWVyYUNsaWVudC0+YXNCaW5kZXIoKSA9PSBjdXJyZW50Q2FtZXJhQ2xpZW50LT5hc0JpbmRlcigpKSB7CisgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0aGUgc2FtZSBjbGllbnQgcmVjb25uZWN0aW5nLi4uCisgICAgICAgICAgICAgICAgTE9HRCgiQ29ubmVjdCBYIHNhbWUgY2xpZW50ICglcCkgaXMgcmVjb25uZWN0aW5nLi4uIiwgY2FtZXJhQ2xpZW50LT5hc0JpbmRlcigpLmdldCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudENsaWVudDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gaXQncyBhbm90aGVyIGNsaWVudC4uLiByZWplY3QgaXQKKyAgICAgICAgICAgICAgICBMT0dEKCJuZXcgY2xpZW50ICglcCkgYXR0ZW1wdGluZyB0byBjb25uZWN0IC0gcmVqZWN0ZWQiLCBjYW1lcmFDbGllbnQtPmFzQmluZGVyKCkuZ2V0KCkpOworICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBjYW4ndCBwcm9tb3RlLCB0aGUgcHJldmlvdXMgY2xpZW50IGhhcyBkaWVkLi4uCisgICAgICAgICAgICBMT0dEKCJuZXcgY2xpZW50IGNvbm5lY3RpbmcsIG9sZCByZWZlcmVuY2Ugd2FzIGRhbmdsaW5nLi4uIik7CisgICAgICAgICAgICBtQ2xpZW50LmNsZWFyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBjcmVhdGUgYSBuZXcgQ2xpZW50IG9iamVjdAorICAgIGNsaWVudCA9IG5ldyBDbGllbnQodGhpcywgY2FtZXJhQ2xpZW50LCBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpOworICAgIG1DbGllbnQgPSBjbGllbnQ7CisjaWYgREVCVUdfQ0xJRU5UX1JFRkVSRU5DRVMKKyAgICAvLyBFbmFibGUgdHJhY2tpbmcgZm9yIHRoaXMgb2JqZWN0LCBhbmQgdHJhY2sgaW5jcmVtZW50cyBhbmQgZGVjcmVtZW50cyBvZgorICAgIC8vIHRoZSByZWZjb3VudC4KKyAgICBjbGllbnQtPnRyYWNrTWUodHJ1ZSwgdHJ1ZSk7CisjZW5kaWYKKyAgICBMT0dEKCJDb25uZWN0IFgiKTsKKyAgICByZXR1cm4gY2xpZW50OworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OnJlbW92ZUNsaWVudChjb25zdCBzcDxJQ2FtZXJhQ2xpZW50PiYgY2FtZXJhQ2xpZW50KQoreworICAgIC8vIGRlY2xhciB0aGlzIG91dHNpZGUgdGhlIGxvY2sgdG8gbWFrZSBhYnNvbHV0ZWx5IHN1cmUgdGhlCisgICAgLy8gZGVzdHJ1Y3RvciB3b24ndCBiZSBjYWxsZWQgd2l0aCB0aGUgbG9jayBoZWxkLgorICAgIHNwPENsaWVudD4gY2xpZW50OworCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworCisgICAgaWYgKG1DbGllbnQgPT0gMCkgeworICAgICAgICAvLyBUaGlzIGhhcHBlbnMgd2hlbiB3ZSBoYXZlIGFscmVhZHkgZGlzY29ubmVjdGVkLgorICAgICAgICBMT0dWKCJtQ2xpZW50IGlzIG51bGwuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBQcm9tb3RlIG1DbGllbnQuIEl0IHNob3VsZCBuZXZlciBmYWlsIGJlY2F1c2Ugd2UncmUgY2FsbGVkIGZyb20KKyAgICAvLyBhIGJpbmRlciBjYWxsLCBzbyBzb21lb25lIGhhcyB0byBoYXZlIGEgc3Ryb25nIHJlZmVyZW5jZS4KKyAgICBjbGllbnQgPSBtQ2xpZW50LnByb21vdGUoKTsKKyAgICBpZiAoY2xpZW50ID09IDApIHsKKyAgICAgICAgTE9HVygiY2FuJ3QgZ2V0IGEgc3Ryb25nIHJlZmVyZW5jZSBvbiBtQ2xpZW50ISIpOworICAgICAgICBtQ2xpZW50LmNsZWFyKCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoY2FtZXJhQ2xpZW50LT5hc0JpbmRlcigpICE9IGNsaWVudC0+Z2V0Q2FtZXJhQ2xpZW50KCktPmFzQmluZGVyKCkpIHsKKyAgICAgICAgLy8gdWdoISB0aGF0J3Mgbm90IG91ciBjbGllbnQhIQorICAgICAgICBMT0dXKCJyZW1vdmVDbGllbnQoKSBjYWxsZWQsIGJ1dCBtQ2xpZW50IGRvZXNuJ3QgbWF0Y2ghIik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gb2theSwgZ29vZCwgZm9yZ2V0IGFib3V0IG1DbGllbnQKKyAgICAgICAgbUNsaWVudC5jbGVhcigpOworICAgIH0KK30KKworQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpDbGllbnQoY29uc3Qgc3A8Q2FtZXJhU2VydmljZT4mIGNhbWVyYVNlcnZpY2UsCisgICAgICAgIGNvbnN0IHNwPElDYW1lcmFDbGllbnQ+JiBjYW1lcmFDbGllbnQsIHBpZF90IGNsaWVudFBpZCkKK3sKKyAgICBMT0dEKCJDbGllbnQgRSBjb25zdHJ1Y3RvciIpOworICAgIG1DYW1lcmFTZXJ2aWNlID0gY2FtZXJhU2VydmljZTsKKyAgICBtQ2FtZXJhQ2xpZW50ID0gY2FtZXJhQ2xpZW50OworICAgIG1DbGllbnRQaWQgPSBjbGllbnRQaWQ7CisgICAgbUhhcmR3YXJlID0gb3BlbkNhbWVyYUhhcmR3YXJlKCk7CisgICAgbVVzZU92ZXJsYXkgPSBtSGFyZHdhcmUtPnVzZU92ZXJsYXkoKTsKKworICAgIC8vIENhbGxiYWNrIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQKKyAgICBtUHJldmlld0NhbGxiYWNrRmxhZyA9IEZSQU1FX0NBTExCQUNLX0ZMQUdfTk9PUDsKKyAgICBMT0dEKCJDbGllbnQgWCBjb25zdHJ1Y3RvciIpOworfQorCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OmNoZWNrUGlkKCkKK3sKKyAgICBpZiAobUNsaWVudFBpZCA9PSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpIHJldHVybiBOT19FUlJPUjsKKyAgICBMT0dXKCJBdHRlbXB0IHRvIHVzZSBsb2NrZWQgY2FtZXJhICglcCkgZnJvbSBkaWZmZXJlbnQgcHJvY2VzcyIsIGdldENhbWVyYUNsaWVudCgpLT5hc0JpbmRlcigpLmdldCgpKTsKKyAgICByZXR1cm4gLUVCVVNZOworfQorCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OmxvY2soKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgLy8gbG9jayBjYW1lcmEgdG8gdGhpcyBjbGllbnQgaWYgdGhlIHRoZSBjYW1lcmEgaXMgdW5sb2NrZWQKKyAgICBpZiAobUNsaWVudFBpZCA9PSAwKSB7CisgICAgICAgIG1DbGllbnRQaWQgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCk7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgLy8gcmV0dXJucyBOT19FUlJPUiBpZiB0aGUgY2xpZW50IGFscmVhZHkgb3ducyB0aGUgY2FtZXJhLCAtRUJVU1kgb3RoZXJ3aXNlCisgICAgcmV0dXJuIGNoZWNrUGlkKCk7Cit9CisKK3N0YXR1c190IENhbWVyYVNlcnZpY2U6OkNsaWVudDo6dW5sb2NrKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIC8vIGFsbG93IGFueW9uZSB0byB1c2UgY2FtZXJhCisgICAgTE9HVigidW5sb2NrICglcCkiLCBnZXRDYW1lcmFDbGllbnQoKS0+YXNCaW5kZXIoKS5nZXQoKSk7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gY2hlY2tQaWQoKTsKKyAgICBpZiAocmVzdWx0ID09IE5PX0VSUk9SKSBtQ2xpZW50UGlkID0gMDsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OmNvbm5lY3QoY29uc3Qgc3A8SUNhbWVyYUNsaWVudD4mIGNsaWVudCkKK3sKKyAgICAvLyBjb25uZWN0IGEgbmV3IHByb2Nlc3MgdG8gdGhlIGNhbWVyYQorICAgIExPR1YoImNvbm5lY3QgKCVwKSIsIGNsaWVudC0+YXNCaW5kZXIoKS5nZXQoKSk7CisKKyAgICAvLyBJIGhhdGUgdGhpcyBoYWNrLCBidXQgdGhpbmdzIGdldCByZWFsbHkgdWdseSB3aGVuIHRoZSBtZWRpYSByZWNvcmRlcgorICAgIC8vIHNlcnZpY2UgaXMgaGFuZGluZyBiYWNrIHRoZSBjYW1lcmEgdG8gdGhlIGFwcC4gVGhlIElDYW1lcmFDbGllbnQKKyAgICAvLyBkZXN0cnVjdG9yIHdpbGwgYmUgY2FsbGVkIGR1cmluZyB0aGUgc2FtZSBJUEMsIG1ha2luZyBpdCBsb29rIGxpa2UKKyAgICAvLyB0aGUgcmVtb3RlIGNsaWVudCBpcyB0cnlpbmcgdG8gZGlzY29ubmVjdC4gVGhpcyBoYWNrIHRlbXBvcmFyaWx5CisgICAgLy8gc2V0cyB0aGUgbUNsaWVudFBpZCB0byBhbiBpbnZhbGlkIHBpZCB0byBwcmV2ZW50IHRoZSBoYXJkd2FyZSBmcm9tCisgICAgLy8gIGJlaW5nIHRvcm4gZG93bi4KKyAgICB7CisKKyAgICAgICAgLy8gaG9sZCBhIHJlZmVyZW5jZSB0byB0aGUgb2xkIGNsaWVudCBvciB3ZSB3aWxsIGRlYWRsb2NrIGlmIHRoZSBjbGllbnQgaXMKKyAgICAgICAgLy8gaW4gdGhlIHNhbWUgcHJvY2VzcyBhbmQgd2UgaG9sZCB0aGUgbG9jayB3aGVuIHdlIHJlbW92ZSB0aGUgcmVmZXJlbmNlCisgICAgICAgIHNwPElDYW1lcmFDbGllbnQ+IG9sZENsaWVudDsKKyAgICAgICAgeworICAgICAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgICAgIGlmIChtQ2xpZW50UGlkICE9IDApIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJUcmllZCB0byBjb25uZWN0IHRvIGxvY2tlZCBjYW1lcmEiKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLUVCVVNZOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2xkQ2xpZW50ID0gbUNhbWVyYUNsaWVudDsKKworICAgICAgICAgICAgLy8gZGlkIHRoZSBjbGllbnQgYWN0dWFsbHkgY2hhbmdlPworICAgICAgICAgICAgaWYgKGNsaWVudC0+YXNCaW5kZXIoKSA9PSBtQ2FtZXJhQ2xpZW50LT5hc0JpbmRlcigpKSByZXR1cm4gTk9fRVJST1I7CisKKyAgICAgICAgICAgIG1DYW1lcmFDbGllbnQgPSBjbGllbnQ7CisgICAgICAgICAgICBtQ2xpZW50UGlkID0gLTE7CisgICAgICAgICAgICBtUHJldmlld0NhbGxiYWNrRmxhZyA9IEZSQU1FX0NBTExCQUNLX0ZMQUdfTk9PUDsKKyAgICAgICAgICAgIExPR1YoImNvbm5lY3QgbmV3IHByb2Nlc3MgKCVkKSB0byBleGlzdGluZyBjYW1lcmEgY2xpZW50IiwgbUNsaWVudFBpZCk7CisgICAgICAgIH0KKworICAgIH0KKyAgICAvLyB0aGUgb2xkIGNsaWVudCBkZXN0cnVjdG9yIGlzIGNhbGxlZCB3aGVuIG9sZENsaWVudCBnb2VzIG91dCBvZiBzY29wZQorICAgIC8vIG5vdyB3ZSBzZXQgdGhlIG5ldyBQSUQgdG8gbG9jayB0aGUgaW50ZXJmYWNlIGFnYWluCisgICAgbUNsaWVudFBpZCA9IElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKTsKKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworI2lmIEhBVkVfQU5EUk9JRF9PUworc3RhdGljIHZvaWQgKnVucmVnaXN0ZXJfc3VyZmFjZSh2b2lkICphcmcpCit7CisgICAgSVN1cmZhY2UgKnN1cmZhY2UgPSAoSVN1cmZhY2UgKilhcmc7CisgICAgc3VyZmFjZS0+dW5yZWdpc3RlckJ1ZmZlcnMoKTsKKyAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5mbHVzaENvbW1hbmRzKCk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisjZW5kaWYKKworQ2FtZXJhU2VydmljZTo6Q2xpZW50Ojp+Q2xpZW50KCkKK3sKKyAgICAvLyB0ZWFyIGRvd24gY2xpZW50CisgICAgTE9HRCgiQ2xpZW50ICglcCkgIEUgZGVzdHJ1Y3RvciIsIGdldENhbWVyYUNsaWVudCgpLT5hc0JpbmRlcigpLmdldCgpKTsKKyAgICBpZiAobVN1cmZhY2UgIT0gMCAmJiAhbVVzZU92ZXJsYXkpIHsKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICAgICAgcHRocmVhZF90IHRocjsKKyAgICAgICAgLy8gV2UgdW5yZWdpc3RlciB0aGUgYnVmZmVycyBpbiBhIGRpZmZlcmVudCB0aHJlYWQgYmVjYXVzZSBiaW5kZXIgZG9lcworICAgICAgICAvLyBub3QgbGV0IHVzIG1ha2Ugc3ljaHJvbm91cyB0cmFuc2FjdGlvbnMgaW4gYSBiaW5kZXIgZGVzdHJ1Y3RvciAodGhhdAorICAgICAgICAvLyBpcywgdXBvbiBvdXIgcmVhY2hpbmcgYSByZWZjb3VudCBvZiB6ZXJvLikKKyAgICAgICAgcHRocmVhZF9jcmVhdGUoJnRociwgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgdW5yZWdpc3Rlcl9zdXJmYWNlLAorICAgICAgICAgICAgICAgICAgICAgICBtU3VyZmFjZS5nZXQoKSk7CisgICAgICAgIHB0aHJlYWRfam9pbih0aHIsIE5VTEwpOworI2Vsc2UKKyAgICAgICAgbVN1cmZhY2UtPnVucmVnaXN0ZXJCdWZmZXJzKCk7CisjZW5kaWYKKyAgICB9CisKKyAgICAvLyBtYWtlIHN1cmUgd2UgdGVhciBkb3duIHRoZSBoYXJkd2FyZQorICAgIG1DbGllbnRQaWQgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCk7CisgICAgZGlzY29ubmVjdCgpOworICAgIExPR0QoIkNsaWVudCBYIGRlc3RydWN0b3IiKTsKK30KKwordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OmRpc2Nvbm5lY3QoKQoreworICAgIExPR0QoIkNsaWVudCAoJXApIEUgZGlzY29ubmVjdCBmcm9tICglZCkiLAorICAgICAgICAgICAgZ2V0Q2FtZXJhQ2xpZW50KCktPmFzQmluZGVyKCkuZ2V0KCksCisgICAgICAgICAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpOworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICBpZiAobUNsaWVudFBpZCA8PSAwKSB7CisgICAgICAgIExPR1YoImNhbWVyYSBpcyB1bmxvY2tlZCwgZG9uJ3QgdGVhciBkb3duIGhhcmR3YXJlIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGNoZWNrUGlkKCkgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgTE9HVigiRGlmZmVyZW50IGNsaWVudCAtIGRvbid0IGRpc2Nvbm5lY3QiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIG1DYW1lcmFTZXJ2aWNlLT5yZW1vdmVDbGllbnQobUNhbWVyYUNsaWVudCk7CisgICAgaWYgKG1IYXJkd2FyZSAhPSAwKSB7CisgICAgICAgIExPR1YoImhhcmR3YXJlIHRlYXJkb3duIik7CisgICAgICAgIC8vIEJlZm9yZSBkZXN0cm95aW5nIG1IYXJkd2FyZSwgd2UgbXVzdCBtYWtlIHN1cmUgaXQncyBpbiB0aGUKKyAgICAgICAgLy8gaWRsZSBzdGF0ZS4KKyAgICAgICAgbUhhcmR3YXJlLT5zdG9wUHJldmlldygpOworICAgICAgICAvLyBDYW5jZWwgYWxsIHBpY3R1cmUgY2FsbGJhY2tzLgorICAgICAgICBtSGFyZHdhcmUtPmNhbmNlbFBpY3R1cmUodHJ1ZSwgdHJ1ZSwgdHJ1ZSk7CisgICAgICAgIC8vIFJlbGVhc2UgdGhlIGhhcmR3YXJlIHJlc291cmNlcy4KKyAgICAgICAgbUhhcmR3YXJlLT5yZWxlYXNlKCk7CisgICAgfQorICAgIG1IYXJkd2FyZS5jbGVhcigpOworICAgIExPR0QoIkNsaWVudCBYIGRpc2Nvbm5lY3QiKTsKK30KKworLy8gcGFzcyB0aGUgYnVmZmVyZWQgSVN1cmZhY2UgdG8gdGhlIGNhbWVyYSBzZXJ2aWNlCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnNldFByZXZpZXdEaXNwbGF5KGNvbnN0IHNwPElTdXJmYWNlPiYgc3VyZmFjZSkKK3sKKyAgICBMT0dEKCJzZXRQcmV2aWV3RGlzcGxheSglcCkiLCBzdXJmYWNlLmdldCgpKTsKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gY2hlY2tQaWQoKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSByZXR1cm4gcmVzdWx0OworICAgIE11dGV4OjpBdXRvbG9jayBzdXJmYWNlTG9jayhtU3VyZmFjZUxvY2spOworICAgIC8vIGFzQmluZGVyKCkgaXMgc2FmZSBvbiBOVUxMIChyZXR1cm5zIE5VTEwpCisgICAgaWYgKHN1cmZhY2UtPmFzQmluZGVyKCkgIT0gbVN1cmZhY2UtPmFzQmluZGVyKCkpIHsKKyAgICAgICAgaWYgKG1TdXJmYWNlICE9IDAgJiYgIW1Vc2VPdmVybGF5KSB7CisgICAgICAgICAgICBMT0dEKCJjbGVhcmluZyBvbGQgcHJldmlldyBzdXJmYWNlICVwIiwgbVN1cmZhY2UuZ2V0KCkpOworICAgICAgICAgICAgbVN1cmZhY2UtPnVucmVnaXN0ZXJCdWZmZXJzKCk7CisgICAgICAgIH0KKyAgICAgICAgbVN1cmZhY2UgPSBzdXJmYWNlOworICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8vIHNldCB0aGUgcHJldmlldyBjYWxsYmFjayBmbGFnIHRvIGFmZmVjdCBob3cgdGhlIHJlY2VpdmVkIGZyYW1lcyBmcm9tCisvLyBwcmV2aWV3IGFyZSBoYW5kbGVkLgordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnNldFByZXZpZXdDYWxsYmFja0ZsYWcoaW50IGNhbGxiYWNrX2ZsYWcpCit7CisgICAgTE9HVigic2V0UHJldmlld0NhbGxiYWNrRmxhZyIpOworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICBpZiAoY2hlY2tQaWQoKSAhPSBOT19FUlJPUikgcmV0dXJuOworICAgIG1QcmV2aWV3Q2FsbGJhY2tGbGFnID0gY2FsbGJhY2tfZmxhZzsKK30KKworLy8gc3RhcnQgcHJldmlldyBtb2RlLCBtdXN0IGNhbGwgc2V0UHJldmlld0Rpc3BsYXkgZmlyc3QKK3N0YXR1c190IENhbWVyYVNlcnZpY2U6OkNsaWVudDo6c3RhcnRDYW1lcmFNb2RlKGNhbWVyYV9tb2RlIG1vZGUpCit7CisgICAgTE9HRCgic3RhcnRDYW1lcmFNb2RlKCVkKSIsIG1vZGUpOworCisgICAgLyogd2UgY2Fubm90IGNhbGwgaW50byBtSGFyZHdhcmUgd2l0aCBtTG9jayBoZWxkIGJlY2F1c2UKKyAgICAgKiBtSGFyZHdhcmUgaGFzIGNhbGxiYWNrcyBvbnRvIHVzIHdoaWNoIGFjcXVpcmUgdGhpcyBsb2NrCisgICAgICovCisKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gY2hlY2tQaWQoKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSByZXR1cm4gcmVzdWx0OworCisgICAgaWYgKG1IYXJkd2FyZSA9PSAwKSB7CisgICAgICAgIExPR0UoIm1IYXJkd2FyZSBpcyBOVUxMLCByZXR1cm5pbmcuIik7CisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICB9CisKKyAgICBpZiAobVN1cmZhY2UgPT0gMCkgeworICAgICAgICBMT0dFKCJzZXRQcmV2aWV3RGlzcGxheSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgc3RhcnRDYW1lcmFNb2RlISIpOworICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgfQorCisgICAgc3dpdGNoKG1vZGUpIHsKKyAgICBjYXNlIENBTUVSQV9SRUNPUkRJTkdfTU9ERToKKyAgICAgICAgcmV0dXJuIHN0YXJ0UmVjb3JkaW5nTW9kZSgpOworCisgICAgZGVmYXVsdDogLy8gQ0FNRVJBX1BSRVZJRVdfTU9ERQorICAgICAgICByZXR1cm4gc3RhcnRQcmV2aWV3TW9kZSgpOworICAgIH0KK30KKworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpzdGFydFJlY29yZGluZ01vZGUoKQoreworICAgIExPR1YoInN0YXJ0UmVjb3JkaW5nTW9kZSIpOworCisgICAgc3RhdHVzX3QgcmV0ID0gVU5LTk9XTl9FUlJPUjsKKworICAgIC8vIGlmIHByZXZpZXcgaGFzIG5vdCBiZWVuIHN0YXJ0ZWQsIHN0YXJ0IHByZXZpZXcgZmlyc3QKKyAgICBpZiAoIW1IYXJkd2FyZS0+cHJldmlld0VuYWJsZWQoKSkgeworICAgICAgICByZXQgPSBzdGFydFByZXZpZXdNb2RlKCk7CisgICAgICAgIGlmIChyZXQgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBpZiByZWNvcmRpbmcgaGFzIGJlZW4gZW5hYmxlZCwgbm90aGluZyBuZWVkcyB0byBiZSBkb25lCisgICAgaWYgKG1IYXJkd2FyZS0+cmVjb3JkaW5nRW5hYmxlZCgpKSB7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisKKyAgICAvLyBzdGFydCByZWNvcmRpbmcgbW9kZQorICAgIHJldCA9IG1IYXJkd2FyZS0+c3RhcnRSZWNvcmRpbmcocmVjb3JkaW5nQ2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtQ2FtZXJhU2VydmljZS5nZXQoKSk7CisgICAgaWYgKHJldCAhPSBOT19FUlJPUikgeworICAgICAgICBMT0dFKCJtSGFyZHdhcmUtPnN0YXJ0UmVjb3JkaW5nKCkgZmFpbGVkIHdpdGggc3RhdHVzICVkIiwgcmV0KTsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKK30KKworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpzdGFydFByZXZpZXdNb2RlKCkKK3sKKyAgICBMT0dWKCJzdGFydFByZXZpZXdNb2RlIik7CisKKyAgICAvLyBpZiBwcmV2aWV3IGhhcyBiZWVuIGVuYWJsZWQsIG5vdGhpbmcgbmVlZHMgdG8gYmUgZG9uZQorICAgIGlmIChtSGFyZHdhcmUtPnByZXZpZXdFbmFibGVkKCkpIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKworICAgIC8vIHN0YXJ0IHByZXZpZXcgbW9kZQorI2lmIERFQlVHX0RVTVBfUFJFVklFV19GUkFNRV9UT19GSUxFCisgICAgZGVidWdfZnJhbWVfY250ID0gMDsKKyNlbmRpZgorICAgIHN0YXR1c190IHJldCA9IFVOS05PV05fRVJST1I7CisgICAgaW50IHcsIGg7CisgICAgQ2FtZXJhUGFyYW1ldGVycyBwYXJhbXMobUhhcmR3YXJlLT5nZXRQYXJhbWV0ZXJzKCkpOworICAgIHBhcmFtcy5nZXRQcmV2aWV3U2l6ZSgmdywgJmgpOworCisgICAgaWYgKG1Vc2VPdmVybGF5KSB7CisgICAgICAgIGNvbnN0IGNoYXIgKmZvcm1hdCA9IHBhcmFtcy5nZXRQcmV2aWV3Rm9ybWF0KCk7CisgICAgICAgIGludCBmbXQ7CisgICAgICAgIExPR0QoIlVzZSBPdmVybGF5cyIpOworICAgICAgICBpZiAoIXN0cmNtcChmb3JtYXQsICJ5dXY0MjJpIikpCisgICAgICAgICAgICBmbXQgPSBPVkVSTEFZX0ZPUk1BVF9ZQ2JDcl80MjJfSTsKKyAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChmb3JtYXQsICJyZ2I1NjUiKSkKKyAgICAgICAgICAgIGZtdCA9IE9WRVJMQVlfRk9STUFUX1JHQl81NjU7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgTE9HRSgiSW52YWxpZCBwcmV2aWV3IGZvcm1hdCBmb3Igb3ZlcmxheXMiKTsKKyAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOworICAgICAgICB9CisgICAgICAgIHNwPE92ZXJsYXlSZWY+IHJlZiA9IG1TdXJmYWNlLT5jcmVhdGVPdmVybGF5KHcsIGgsIGZtdCk7CisgICAgICAgIHJldCA9IG1IYXJkd2FyZS0+c2V0T3ZlcmxheShuZXcgT3ZlcmxheShyZWYpKTsKKyAgICAgICAgaWYgKHJldCAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgTE9HRSgibUhhcmR3YXJlLT5zZXRPdmVybGF5KCkgZmFpbGVkIHdpdGggc3RhdHVzICVkXG4iLCByZXQpOworICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgfQorICAgICAgICByZXQgPSBtSGFyZHdhcmUtPnN0YXJ0UHJldmlldyhOVUxMLCBtQ2FtZXJhU2VydmljZS5nZXQoKSk7CisgICAgICAgIGlmIChyZXQgIT0gTk9fRVJST1IpCisgICAgICAgICAgICBMT0dFKCJtSGFyZHdhcmUtPnN0YXJ0UHJldmlldygpIGZhaWxlZCB3aXRoIHN0YXR1cyAlZFxuIiwgcmV0KTsKKworICAgIH0gZWxzZSB7CisgICAgICAgIHJldCA9IG1IYXJkd2FyZS0+c3RhcnRQcmV2aWV3KHByZXZpZXdDYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUNhbWVyYVNlcnZpY2UuZ2V0KCkpOworICAgICAgICBpZiAocmV0ID09IE5PX0VSUk9SKSB7CisKKyAgICAgICAgICAgIG1TdXJmYWNlLT51bnJlZ2lzdGVyQnVmZmVycygpOworCisgICAgICAgICAgICB1aW50MzJfdCB0cmFuc2Zvcm0gPSAwOworICAgICAgICAgICAgaWYgKHBhcmFtcy5nZXRPcmllbnRhdGlvbigpID09CisgICAgICAgICAgICAgICAgQ2FtZXJhUGFyYW1ldGVyczo6Q0FNRVJBX09SSUVOVEFUSU9OX1BPUlRSQUlUKSB7CisgICAgICAgICAgICAgIExPR1YoInBvcnRyYWl0IG1vZGUiKTsKKyAgICAgICAgICAgICAgdHJhbnNmb3JtID0gSVN1cmZhY2U6OkJ1ZmZlckhlYXA6OlJPVF85MDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIElTdXJmYWNlOjpCdWZmZXJIZWFwIGJ1ZmZlcnModywgaCwgdywgaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElYRUxfRk9STUFUX1lDYkNyXzQyMF9TUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtSGFyZHdhcmUtPmdldFByZXZpZXdIZWFwKCkpOworCisgICAgICAgICAgICBtU3VyZmFjZS0+cmVnaXN0ZXJCdWZmZXJzKGJ1ZmZlcnMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIExPR0UoIm1IYXJkd2FyZS0+c3RhcnRQcmV2aWV3KCkgZmFpbGVkIHdpdGggc3RhdHVzICVkIiwgcmV0KTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmV0OworfQorCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnN0YXJ0UHJldmlldygpCit7CisgICAgcmV0dXJuIHN0YXJ0Q2FtZXJhTW9kZShDQU1FUkFfUFJFVklFV19NT0RFKTsKK30KKworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpzdGFydFJlY29yZGluZygpCit7CisgICAgcmV0dXJuIHN0YXJ0Q2FtZXJhTW9kZShDQU1FUkFfUkVDT1JESU5HX01PREUpOworfQorCisvLyBzdG9wIHByZXZpZXcgbW9kZQordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnN0b3BQcmV2aWV3KCkKK3sKKyAgICBMT0dEKCJzdG9wUHJldmlldygpIik7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgaWYgKGNoZWNrUGlkKCkgIT0gTk9fRVJST1IpIHJldHVybjsKKworICAgIGlmIChtSGFyZHdhcmUgPT0gMCkgeworICAgICAgICBMT0dFKCJtSGFyZHdhcmUgaXMgTlVMTCwgcmV0dXJuaW5nLiIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgbUhhcmR3YXJlLT5zdG9wUHJldmlldygpOworICAgIExPR0QoInN0b3BQcmV2aWV3KCksIGhhcmR3YXJlIHN0b3BwZWQgT0siKTsKKworICAgIGlmIChtU3VyZmFjZSAhPSAwICYmICFtVXNlT3ZlcmxheSkgeworICAgICAgICBtU3VyZmFjZS0+dW5yZWdpc3RlckJ1ZmZlcnMoKTsKKyAgICB9CisgICAgbVByZXZpZXdCdWZmZXIuY2xlYXIoKTsKK30KKworLy8gc3RvcCByZWNvcmRpbmcgbW9kZQordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnN0b3BSZWNvcmRpbmcoKQoreworICAgIExPR1YoInN0b3BSZWNvcmRpbmcoKSIpOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIGlmIChjaGVja1BpZCgpICE9IE5PX0VSUk9SKSByZXR1cm47CisKKyAgICBpZiAobUhhcmR3YXJlID09IDApIHsKKyAgICAgICAgTE9HRSgibUhhcmR3YXJlIGlzIE5VTEwsIHJldHVybmluZy4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIG1IYXJkd2FyZS0+c3RvcFJlY29yZGluZygpOworICAgIExPR1YoInN0b3BSZWNvcmRpbmcoKSwgaGFyZHdhcmUgc3RvcHBlZCBPSyIpOworICAgIG1QcmV2aWV3QnVmZmVyLmNsZWFyKCk7Cit9CisKKy8vIHJlbGVhc2UgYSByZWNvcmRpbmcgZnJhbWUKK3ZvaWQgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpyZWxlYXNlUmVjb3JkaW5nRnJhbWUoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSkKK3sKKyAgICBMT0dWKCJyZWxlYXNlUmVjb3JkaW5nRnJhbWUoKSIpOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIGlmIChjaGVja1BpZCgpICE9IE5PX0VSUk9SKSByZXR1cm47CisKKyAgICBpZiAobUhhcmR3YXJlID09IDApIHsKKyAgICAgICAgTE9HRSgibUhhcmR3YXJlIGlzIE5VTEwsIHJldHVybmluZy4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIG1IYXJkd2FyZS0+cmVsZWFzZVJlY29yZGluZ0ZyYW1lKG1lbSk7Cit9CisKK2Jvb2wgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpwcmV2aWV3RW5hYmxlZCgpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIGlmIChtSGFyZHdhcmUgPT0gMCkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBtSGFyZHdhcmUtPnByZXZpZXdFbmFibGVkKCk7Cit9CisKK2Jvb2wgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpyZWNvcmRpbmdFbmFibGVkKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgaWYgKG1IYXJkd2FyZSA9PSAwKSByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIG1IYXJkd2FyZS0+cmVjb3JkaW5nRW5hYmxlZCgpOworfQorCisvLyBTYWZlbHkgcmV0cmlldmVzIGEgc3Ryb25nIHBvaW50ZXIgdG8gdGhlIGNsaWVudCBkdXJpbmcgYSBoYXJkd2FyZSBjYWxsYmFjay4KK3NwPENhbWVyYVNlcnZpY2U6OkNsaWVudD4gQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpnZXRDbGllbnRGcm9tQ29va2llKHZvaWQqIHVzZXIpCit7CisgICAgc3A8Q2xpZW50PiBjbGllbnQgPSAwOworICAgIENhbWVyYVNlcnZpY2UgKnNlcnZpY2UgPSBzdGF0aWNfY2FzdDxDYW1lcmFTZXJ2aWNlKj4odXNlcik7CisgICAgaWYgKHNlcnZpY2UgIT0gTlVMTCkgeworICAgICAgICBNdXRleDo6QXV0b2xvY2sgb3VyTG9jayhzZXJ2aWNlLT5tTG9jayk7CisgICAgICAgIGlmIChzZXJ2aWNlLT5tQ2xpZW50ICE9IDApIHsKKyAgICAgICAgICAgIGNsaWVudCA9IHNlcnZpY2UtPm1DbGllbnQucHJvbW90ZSgpOworICAgICAgICAgICAgaWYgKGNsaWVudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgTE9HRSgiZ2V0Q2xpZW50RnJvbUNvb2tpZTogY2xpZW50IGFwcGVhcnMgdG8gaGF2ZSBkaWVkIik7CisgICAgICAgICAgICAgICAgc2VydmljZS0+bUNsaWVudC5jbGVhcigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HRSgiZ2V0Q2xpZW50RnJvbUNvb2tpZTogZ290IGNhbGxiYWNrIGJ1dCBjbGllbnQgd2FzIE5VTEwiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY2xpZW50OworfQorCisKKyNpZiBERUJVR19EVU1QX0pQRUdfU05BUFNIT1RfVE9fRklMRSB8fCBcCisgICAgREVCVUdfRFVNUF9ZVVZfU05BUFNIT1RfVE9fRklMRSB8fCBcCisgICAgREVCVUdfRFVNUF9QUkVWSUVXX0ZSQU1FX1RPX0ZJTEUKK3N0YXRpYyB2b2lkIGR1bXBfdG9fZmlsZShjb25zdCBjaGFyICpmbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpidWYsIHVpbnQzMl90IHNpemUpCit7CisgICAgaW50IG53LCBjbnQgPSAwOworICAgIHVpbnQzMl90IHdyaXR0ZW4gPSAwOworCisgICAgTE9HRCgib3BlbmluZyBmaWxlIFslc11cbiIsIGZuYW1lKTsKKyAgICBpbnQgZmQgPSBvcGVuKGZuYW1lLCBPX1JEV1IgfCBPX0NSRUFUKTsKKyAgICBpZiAoZmQgPCAwKSB7CisgICAgICAgIExPR0UoImZhaWxlZCB0byBjcmVhdGUgZmlsZSBbJXNdOiAlcyIsIGZuYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgTE9HRCgid3JpdGluZyAlZCBieXRlcyB0byBmaWxlIFslc11cbiIsIHNpemUsIGZuYW1lKTsKKyAgICB3aGlsZSAod3JpdHRlbiA8IHNpemUpIHsKKyAgICAgICAgbncgPSA6OndyaXRlKGZkLAorICAgICAgICAgICAgICAgICAgICAgYnVmICsgd3JpdHRlbiwKKyAgICAgICAgICAgICAgICAgICAgIHNpemUgLSB3cml0dGVuKTsKKyAgICAgICAgaWYgKG53IDwgMCkgeworICAgICAgICAgICAgTE9HRSgiZmFpbGVkIHRvIHdyaXRlIHRvIGZpbGUgWyVzXTogJXMiLAorICAgICAgICAgICAgICAgICBmbmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHdyaXR0ZW4gKz0gbnc7CisgICAgICAgIGNudCsrOworICAgIH0KKyAgICBMT0dEKCJkb25lIHdyaXRpbmcgJWQgYnl0ZXMgdG8gZmlsZSBbJXNdIGluICVkIHBhc3Nlc1xuIiwKKyAgICAgICAgIHNpemUsIGZuYW1lLCBjbnQpOworICAgIDo6Y2xvc2UoZmQpOworfQorI2VuZGlmCisKKy8vIHByZXZpZXcgY2FsbGJhY2sgLSBmcmFtZSBidWZmZXIgdXBkYXRlCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cHJldmlld0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0sIHZvaWQqIHVzZXIpCit7CisgICAgTE9HVigicHJldmlld0NhbGxiYWNrKCkiKTsKKyAgICBzcDxDbGllbnQ+IGNsaWVudCA9IGdldENsaWVudEZyb21Db29raWUodXNlcik7CisgICAgaWYgKGNsaWVudCA9PSAwKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyNpZiBERUJVR19IRUFQX0xFQUtTICYmIDAgLy8gZGVidWdnaW5nCisgICAgaWYgKGdXZWFrSGVhcCA9PSBOVUxMKSB7CisgICAgICAgIHNzaXplX3Qgb2Zmc2V0OworICAgICAgICBzaXplX3Qgc2l6ZTsKKyAgICAgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXAgPSBtZW0tPmdldE1lbW9yeSgmb2Zmc2V0LCAmc2l6ZSk7CisgICAgICAgIGlmIChnV2Vha0hlYXAgIT0gaGVhcCkgeworICAgICAgICAgICAgTE9HRCgiU0VUVElORyBQUkVWSUVXIEhFQVAiKTsKKyAgICAgICAgICAgIGhlYXAtPnRyYWNrTWUodHJ1ZSwgdHJ1ZSk7CisgICAgICAgICAgICBnV2Vha0hlYXAgPSBoZWFwOworICAgICAgICB9CisgICAgfQorI2VuZGlmCisKKyNpZiBERUJVR19EVU1QX1BSRVZJRVdfRlJBTUVfVE9fRklMRQorICAgIHsKKyAgICAgICAgaWYgKGRlYnVnX2ZyYW1lX2NudCsrID09IERFQlVHX0RVTVBfUFJFVklFV19GUkFNRV9UT19GSUxFKSB7CisgICAgICAgICAgICBzc2l6ZV90IG9mZnNldDsKKyAgICAgICAgICAgIHNpemVfdCBzaXplOworICAgICAgICAgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXAgPSBtZW0tPmdldE1lbW9yeSgmb2Zmc2V0LCAmc2l6ZSk7CisgICAgICAgICAgICBkdW1wX3RvX2ZpbGUoIi9kYXRhL3ByZXZpZXcueXV2IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAodWludDhfdCAqKWhlYXAtPmJhc2UoKSArIG9mZnNldCwgc2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisjZW5kaWYKKworICAgIC8vIFRoZSBzdHJvbmcgcG9pbnRlciBndWFyYW50ZWVzIHRoZSBjbGllbnQgd2lsbCBleGlzdCwgYnV0IG5vIGxvY2sgaXMgaGVsZC4KKyAgICBjbGllbnQtPnBvc3RQcmV2aWV3RnJhbWUobWVtKTsKKworI2lmIERFQlVHX0NMSUVOVF9SRUZFUkVOQ0VTCisgICAgLy8qKioqIGlmIHRoZSBjbGllbnQncyByZWZjb3VudCBpcyAxLCB0aGVuIHdlIGFyZSBhYm91dCB0byBkZXN0cm95IGl0IGhlcmUsCisgICAgLy8gd2hpY2ggaXMgYmFkLS1wcmludCBhbGwgcmVmY291bnRzLgorICAgIGlmIChjbGllbnQtPmdldFN0cm9uZ0NvdW50KCkgPT0gMSkgeworICAgICAgICBMT0dFKCIrKysrKysrKysrKysrKysrIChQUkVWSUVXKSBUSElTIFdJTEwgQ0FVU0UgQSBMT0NLVVAhIik7CisgICAgICAgIGNsaWVudC0+cHJpbnRSZWZzKCk7CisgICAgfQorI2VuZGlmCit9CisKKy8vIHJlY29yZGluZyBjYWxsYmFjawordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnJlY29yZGluZ0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0sIHZvaWQqIHVzZXIpCit7CisgICAgTE9HVigicmVjb3JkaW5nQ2FsbGJhY2siKTsKKyAgICBzcDxDbGllbnQ+IGNsaWVudCA9IGdldENsaWVudEZyb21Db29raWUodXNlcik7CisgICAgaWYgKGNsaWVudCA9PSAwKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gVGhlIHN0cm9uZyBwb2ludGVyIGd1YXJhbnRlZXMgdGhlIGNsaWVudCB3aWxsIGV4aXN0LCBidXQgbm8gbG9jayBpcyBoZWxkLgorICAgIGNsaWVudC0+cG9zdFJlY29yZGluZ0ZyYW1lKG1lbSk7Cit9CisKKy8vIHRha2UgYSBwaWN0dXJlIC0gaW1hZ2UgaXMgcmV0dXJuZWQgaW4gY2FsbGJhY2sKK3N0YXR1c190IENhbWVyYVNlcnZpY2U6OkNsaWVudDo6YXV0b0ZvY3VzKCkKK3sKKyAgICBMT0dWKCJhdXRvRm9jdXMiKTsKKworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICBzdGF0dXNfdCByZXN1bHQgPSBjaGVja1BpZCgpOworICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpIHJldHVybiByZXN1bHQ7CisKKyAgICBpZiAobUhhcmR3YXJlID09IDApIHsKKyAgICAgICAgTE9HRSgibUhhcmR3YXJlIGlzIE5VTEwsIHJldHVybmluZy4iKTsKKyAgICAgICAgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworICAgIH0KKworICAgIHJldHVybiBtSGFyZHdhcmUtPmF1dG9Gb2N1cyhhdXRvRm9jdXNDYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUNhbWVyYVNlcnZpY2UuZ2V0KCkpOworfQorCisvLyB0YWtlIGEgcGljdHVyZSAtIGltYWdlIGlzIHJldHVybmVkIGluIGNhbGxiYWNrCitzdGF0dXNfdCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnRha2VQaWN0dXJlKCkKK3sKKyAgICBMT0dEKCJ0YWtlUGljdHVyZSIpOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIGxvY2sobUxvY2spOworICAgIHN0YXR1c190IHJlc3VsdCA9IGNoZWNrUGlkKCk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgcmV0dXJuIHJlc3VsdDsKKworICAgIGlmIChtSGFyZHdhcmUgPT0gMCkgeworICAgICAgICBMT0dFKCJtSGFyZHdhcmUgaXMgTlVMTCwgcmV0dXJuaW5nLiIpOworICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgfQorCisgICAgcmV0dXJuIG1IYXJkd2FyZS0+dGFrZVBpY3R1cmUoc2h1dHRlckNhbGxiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl1dlBpY3R1cmVDYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcGVnUGljdHVyZUNhbGxiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1DYW1lcmFTZXJ2aWNlLmdldCgpKTsKK30KKworLy8gcGljdHVyZSBjYWxsYmFjayAtIHNuYXBzaG90IHRha2VuCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6c2h1dHRlckNhbGxiYWNrKHZvaWQgKnVzZXIpCit7CisgICAgc3A8Q2xpZW50PiBjbGllbnQgPSBnZXRDbGllbnRGcm9tQ29va2llKHVzZXIpOworICAgIGlmIChjbGllbnQgPT0gMCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gU2NyZWVuIGdvZXMgYmxhY2sgYWZ0ZXIgdGhlIGJ1ZmZlciBpcyB1bnJlZ2lzdGVyZWQuCisgICAgaWYgKGNsaWVudC0+bVN1cmZhY2UgIT0gMCAmJiAhY2xpZW50LT5tVXNlT3ZlcmxheSkgeworICAgICAgICBjbGllbnQtPm1TdXJmYWNlLT51bnJlZ2lzdGVyQnVmZmVycygpOworICAgIH0KKworICAgIGNsaWVudC0+cG9zdFNodXR0ZXIoKTsKKworICAgIC8vIEl0IHRha2VzIHNvbWUgdGltZSBiZWZvcmUgeXV2UGljdHVyZSBjYWxsYmFjayB0byBiZSBjYWxsZWQuCisgICAgLy8gUmVnaXN0ZXIgdGhlIGJ1ZmZlciBmb3IgcmF3IGltYWdlIGhlcmUgdG8gcmVkdWNlIGxhdGVuY3kuCisgICAgaWYgKGNsaWVudC0+bVN1cmZhY2UgIT0gMCAmJiAhY2xpZW50LT5tVXNlT3ZlcmxheSkgeworICAgICAgICBpbnQgdywgaDsKKyAgICAgICAgQ2FtZXJhUGFyYW1ldGVycyBwYXJhbXMoY2xpZW50LT5tSGFyZHdhcmUtPmdldFBhcmFtZXRlcnMoKSk7CisgICAgICAgIHBhcmFtcy5nZXRQaWN0dXJlU2l6ZSgmdywgJmgpOworICAgICAgICB1aW50MzJfdCB0cmFuc2Zvcm0gPSAwOworICAgICAgICBpZiAocGFyYW1zLmdldE9yaWVudGF0aW9uKCkgPT0gQ2FtZXJhUGFyYW1ldGVyczo6Q0FNRVJBX09SSUVOVEFUSU9OX1BPUlRSQUlUKSB7CisgICAgICAgICAgICBMT0dWKCJwb3J0cmFpdCBtb2RlIik7CisgICAgICAgICAgICB0cmFuc2Zvcm0gPSBJU3VyZmFjZTo6QnVmZmVySGVhcDo6Uk9UXzkwOworICAgICAgICB9CisgICAgICAgIElTdXJmYWNlOjpCdWZmZXJIZWFwIGJ1ZmZlcnModywgaCwgdywgaCwKKyAgICAgICAgICAgIFBJWEVMX0ZPUk1BVF9ZQ2JDcl80MjBfU1AsIHRyYW5zZm9ybSwgMCwgY2xpZW50LT5tSGFyZHdhcmUtPmdldFJhd0hlYXAoKSk7CisKKyAgICAgICAgY2xpZW50LT5tU3VyZmFjZS0+cmVnaXN0ZXJCdWZmZXJzKGJ1ZmZlcnMpOworICAgIH0KK30KKworLy8gcGljdHVyZSBjYWxsYmFjayAtIHJhdyBpbWFnZSByZWFkeQordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6Onl1dlBpY3R1cmVDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgbWVtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp1c2VyKQoreworICAgIHNwPENsaWVudD4gY2xpZW50ID0gZ2V0Q2xpZW50RnJvbUNvb2tpZSh1c2VyKTsKKyAgICBpZiAoY2xpZW50ID09IDApIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAobWVtID09IE5VTEwpIHsKKyAgICAgICAgY2xpZW50LT5wb3N0UmF3KE5VTEwpOworICAgICAgICBjbGllbnQtPnBvc3RFcnJvcihVTktOT1dOX0VSUk9SKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHNzaXplX3Qgb2Zmc2V0OworICAgIHNpemVfdCBzaXplOworICAgIHNwPElNZW1vcnlIZWFwPiBoZWFwID0gbWVtLT5nZXRNZW1vcnkoJm9mZnNldCwgJnNpemUpOworI2lmIERFQlVHX0hFQVBfTEVBS1MgJiYgMCAvLyBkZWJ1Z2dpbmcKKyAgICBnV2Vha0hlYXAgPSBoZWFwOyAvLyBkZWJ1Z2dpbmcKKyNlbmRpZgorCisgICAgLy9MT0dWKCJ5dXZQaWN0dXJlQ2FsbGJhY2soJWQsICVkLCAlcCkiLCBvZmZzZXQsIHNpemUsIHVzZXIpOworI2lmIERFQlVHX0RVTVBfWVVWX1NOQVBTSE9UX1RPX0ZJTEUgLy8gZm9yIHRlc3RpbmcgcHVyc3Bvc2VzIG9ubHkKKyAgICBkdW1wX3RvX2ZpbGUoIi9kYXRhL3Bob3RvLnl1diIsCisgICAgICAgICAgICAgICAgICh1aW50OF90ICopaGVhcC0+YmFzZSgpICsgb2Zmc2V0LCBzaXplKTsKKyNlbmRpZgorCisgICAgLy8gUHV0IHRoZSBZVVYgdmVyc2lvbiBvZiB0aGUgc25hcHNob3QgaW4gdGhlIHByZXZpZXcgZGlzcGxheS4KKyAgICBpZiAoY2xpZW50LT5tU3VyZmFjZSAhPSAwICYmICFjbGllbnQtPm1Vc2VPdmVybGF5KSB7CisgICAgICAgIGNsaWVudC0+bVN1cmZhY2UtPnBvc3RCdWZmZXIob2Zmc2V0KTsKKyAgICB9CisKKyAgICBjbGllbnQtPnBvc3RSYXcobWVtKTsKKworI2lmIERFQlVHX0NMSUVOVF9SRUZFUkVOQ0VTCisgICAgLy8qKioqIGlmIHRoZSBjbGllbnQncyByZWZjb3VudCBpcyAxLCB0aGVuIHdlIGFyZSBhYm91dCB0byBkZXN0cm95IGl0IGhlcmUsCisgICAgLy8gd2hpY2ggaXMgYmFkLS1wcmludCBhbGwgcmVmY291bnRzLgorICAgIGlmIChjbGllbnQtPmdldFN0cm9uZ0NvdW50KCkgPT0gMSkgeworICAgICAgICBMT0dFKCIrKysrKysrKysrKysrKysrIChSQVcpIFRISVMgV0lMTCBDQVVTRSBBIExPQ0tVUCEiKTsKKyAgICAgICAgY2xpZW50LT5wcmludFJlZnMoKTsKKyAgICB9CisjZW5kaWYKK30KKworLy8gcGljdHVyZSBjYWxsYmFjayAtIGpwZWcgcmVhZHkKK3ZvaWQgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpqcGVnUGljdHVyZUNhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0sIHZvaWQgKnVzZXIpCit7CisgICAgc3A8Q2xpZW50PiBjbGllbnQgPSBnZXRDbGllbnRGcm9tQ29va2llKHVzZXIpOworICAgIGlmIChjbGllbnQgPT0gMCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChtZW0gPT0gTlVMTCkgeworICAgICAgICBjbGllbnQtPnBvc3RKcGVnKE5VTEwpOworICAgICAgICBjbGllbnQtPnBvc3RFcnJvcihVTktOT1dOX0VSUk9SKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8qKiBXZSBhYnNvbHV0ZWx5IENBTk5PVCBjYWxsIGludG8gdXNlciBjb2RlIHdpdGggYSBsb2NrIGhlbGQgKiovCisKKyNpZiBERUJVR19EVU1QX0pQRUdfU05BUFNIT1RfVE9fRklMRSAvLyBmb3IgdGVzdGluZyBwdXJzcG9zZXMgb25seQorICAgIHsKKyAgICAgICAgc3NpemVfdCBvZmZzZXQ7CisgICAgICAgIHNpemVfdCBzaXplOworICAgICAgICBzcDxJTWVtb3J5SGVhcD4gaGVhcCA9IG1lbS0+Z2V0TWVtb3J5KCZvZmZzZXQsICZzaXplKTsKKyAgICAgICAgZHVtcF90b19maWxlKCIvZGF0YS9waG90by5qcGciLAorICAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QgKiloZWFwLT5iYXNlKCkgKyBvZmZzZXQsIHNpemUpOworICAgIH0KKyNlbmRpZgorCisgICAgY2xpZW50LT5wb3N0SnBlZyhtZW0pOworCisjaWYgREVCVUdfQ0xJRU5UX1JFRkVSRU5DRVMKKyAgICAvLyoqKiogaWYgdGhlIGNsaWVudCdzIHJlZmNvdW50IGlzIDEsIHRoZW4gd2UgYXJlIGFib3V0IHRvIGRlc3Ryb3kgaXQgaGVyZSwKKyAgICAvLyB3aGljaCBpcyBiYWQtLXByaW50IGFsbCByZWZjb3VudHMuCisgICAgaWYgKGNsaWVudC0+Z2V0U3Ryb25nQ291bnQoKSA9PSAxKSB7CisgICAgICAgIExPR0UoIisrKysrKysrKysrKysrKysgKEpQRUcpIFRISVMgV0lMTCBDQVVTRSBBIExPQ0tVUCEiKTsKKyAgICAgICAgY2xpZW50LT5wcmludFJlZnMoKTsKKyAgICB9CisjZW5kaWYKK30KKwordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OmF1dG9Gb2N1c0NhbGxiYWNrKGJvb2wgZm9jdXNlZCwgdm9pZCAqdXNlcikKK3sKKyAgICBMT0dWKCJhdXRvRm9jdXNDYWxsYmFjayIpOworCisgICAgc3A8Q2xpZW50PiBjbGllbnQgPSBnZXRDbGllbnRGcm9tQ29va2llKHVzZXIpOworICAgIGlmIChjbGllbnQgPT0gMCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgY2xpZW50LT5wb3N0QXV0b0ZvY3VzKGZvY3VzZWQpOworCisjaWYgREVCVUdfQ0xJRU5UX1JFRkVSRU5DRVMKKyAgICBpZiAoY2xpZW50LT5nZXRTdHJvbmdDb3VudCgpID09IDEpIHsKKyAgICAgICAgTE9HRSgiKysrKysrKysrKysrKysrKyAoQVVUT0ZPQ1VTKSBUSElTIFdJTEwgQ0FVU0UgQSBMT0NLVVAhIik7CisgICAgICAgIGNsaWVudC0+cHJpbnRSZWZzKCk7CisgICAgfQorI2VuZGlmCit9CisKKy8vIHNldCBwcmV2aWV3L2NhcHR1cmUgcGFyYW1ldGVycyAtIGtleS92YWx1ZSBwYWlycworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpzZXRQYXJhbWV0ZXJzKGNvbnN0IFN0cmluZzgmIHBhcmFtcykKK3sKKyAgICBMT0dEKCJzZXRQYXJhbWV0ZXJzKCVzKSIsIHBhcmFtcy5zdHJpbmcoKSk7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gY2hlY2tQaWQoKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSByZXR1cm4gcmVzdWx0OworCisgICAgaWYgKG1IYXJkd2FyZSA9PSAwKSB7CisgICAgICAgIExPR0UoIm1IYXJkd2FyZSBpcyBOVUxMLCByZXR1cm5pbmcuIik7CisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICB9CisKKyAgICBDYW1lcmFQYXJhbWV0ZXJzIHAocGFyYW1zKTsKKyAgICBtSGFyZHdhcmUtPnNldFBhcmFtZXRlcnMocCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvLyBnZXQgcHJldmlldy9jYXB0dXJlIHBhcmFtZXRlcnMgLSBrZXkvdmFsdWUgcGFpcnMKK1N0cmluZzggQ2FtZXJhU2VydmljZTo6Q2xpZW50OjpnZXRQYXJhbWV0ZXJzKCkgY29uc3QKK3sKKyAgICBMT0dEKCJnZXRQYXJhbWV0ZXJzIik7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgbG9jayhtTG9jayk7CisKKyAgICBpZiAobUhhcmR3YXJlID09IDApIHsKKyAgICAgICAgTE9HRSgibUhhcmR3YXJlIGlzIE5VTEwsIHJldHVybmluZy4iKTsKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoKTsKKyAgICB9CisKKyAgICByZXR1cm4gbUhhcmR3YXJlLT5nZXRQYXJhbWV0ZXJzKCkuZmxhdHRlbigpOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cG9zdEF1dG9Gb2N1cyhib29sIGZvY3VzZWQpCit7CisgICAgTE9HVigicG9zdEF1dG9Gb2N1cyIpOworICAgIG1DYW1lcmFDbGllbnQtPmF1dG9Gb2N1c0NhbGxiYWNrKGZvY3VzZWQpOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cG9zdFNodXR0ZXIoKQoreworICAgIG1DYW1lcmFDbGllbnQtPnNodXR0ZXJDYWxsYmFjaygpOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cG9zdFJhdyhjb25zdCBzcDxJTWVtb3J5PiYgbWVtKQoreworICAgIExPR0QoInBvc3RSYXciKTsKKyAgICBtQ2FtZXJhQ2xpZW50LT5yYXdDYWxsYmFjayhtZW0pOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cG9zdEpwZWcoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSkKK3sKKyAgICBMT0dEKCJwb3N0SnBlZyIpOworICAgIG1DYW1lcmFDbGllbnQtPmpwZWdDYWxsYmFjayhtZW0pOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6Y29weUZyYW1lQW5kUG9zdENvcGllZEZyYW1lKHNwPElNZW1vcnlIZWFwPiBoZWFwLCBzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSkKK3sKKyAgICBMT0dWKCJjb3B5RnJhbWVBbmRQb3N0Q29waWVkRnJhbWUiKTsKKyAgICAvLyBJdCBpcyBuZWNlc3NhcnkgdG8gY29weSBvdXQgb2YgcG1lbSBiZWZvcmUgc2VuZGluZyB0aGlzIHRvCisgICAgLy8gdGhlIGNhbGxiYWNrLiBGb3IgZWZmaWNpZW5jeSwgcmV1c2UgdGhlIHNhbWUgTWVtb3J5SGVhcEJhc2UKKyAgICAvLyBwcm92aWRlZCBpdCdzIGJpZyBlbm91Z2guIERvbid0IGFsbG9jYXRlIHRoZSBtZW1vcnkgb3IKKyAgICAvLyBwZXJmb3JtIHRoZSBjb3B5IGlmIHRoZXJlJ3Mgbm8gY2FsbGJhY2suCisgICAgaWYgKG1QcmV2aWV3QnVmZmVyID09IDApIHsKKyAgICAgICAgbVByZXZpZXdCdWZmZXIgPSBuZXcgTWVtb3J5SGVhcEJhc2Uoc2l6ZSwgMCwgTlVMTCk7CisgICAgfSBlbHNlIGlmIChzaXplID4gbVByZXZpZXdCdWZmZXItPnZpcnR1YWxTaXplKCkpIHsKKyAgICAgICAgbVByZXZpZXdCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgbVByZXZpZXdCdWZmZXIgPSBuZXcgTWVtb3J5SGVhcEJhc2Uoc2l6ZSwgMCwgTlVMTCk7CisgICAgICAgIGlmIChtUHJldmlld0J1ZmZlciA9PSAwKSB7CisgICAgICAgICAgICBMT0dFKCJmYWlsZWQgdG8gYWxsb2NhdGUgc3BhY2UgZm9yIHByZXZpZXcgYnVmZmVyIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisgICAgbWVtY3B5KG1QcmV2aWV3QnVmZmVyLT5iYXNlKCksCisgICAgICAgICAgICh1aW50OF90ICopaGVhcC0+YmFzZSgpICsgb2Zmc2V0LCBzaXplKTsKKworICAgIHNwPE1lbW9yeUJhc2U+IGZyYW1lID0gbmV3IE1lbW9yeUJhc2UobVByZXZpZXdCdWZmZXIsIDAsIHNpemUpOworICAgIGlmIChmcmFtZSA9PSAwKSB7CisgICAgICAgIExPR0UoImZhaWxlZCB0byBhbGxvY2F0ZSBzcGFjZSBmb3IgZnJhbWUgY2FsbGJhY2siKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBtQ2FtZXJhQ2xpZW50LT5wcmV2aWV3Q2FsbGJhY2soZnJhbWUpOworfQorCit2b2lkIENhbWVyYVNlcnZpY2U6OkNsaWVudDo6cG9zdFJlY29yZGluZ0ZyYW1lKGNvbnN0IHNwPElNZW1vcnk+JiBmcmFtZSkKK3sKKyAgICBMT0dWKCJwb3N0UmVjb3JkaW5nRnJhbWUiKTsKKyAgICBpZiAoZnJhbWUgPT0gMCkgeworICAgICAgICBMT0dXKCJmcmFtZSBpcyBhIG51bGwgcG9pbnRlciIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIG1DYW1lcmFDbGllbnQtPnJlY29yZGluZ0NhbGxiYWNrKGZyYW1lKTsKK30KKwordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnBvc3RQcmV2aWV3RnJhbWUoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSkKK3sKKyAgICBMT0dWKCJwb3N0UHJldmlld0ZyYW1lIik7CisgICAgaWYgKG1lbSA9PSAwKSB7CisgICAgICAgIExPR1coIm1lbSBpcyBhIG51bGwgcG9pbnRlciIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgc3NpemVfdCBvZmZzZXQ7CisgICAgc2l6ZV90IHNpemU7CisgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXAgPSBtZW0tPmdldE1lbW9yeSgmb2Zmc2V0LCAmc2l6ZSk7CisgICAgeworICAgICAgICBNdXRleDo6QXV0b2xvY2sgc3VyZmFjZUxvY2sobVN1cmZhY2VMb2NrKTsKKyAgICAgICAgaWYgKG1TdXJmYWNlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIG1TdXJmYWNlLT5wb3N0QnVmZmVyKG9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBJcyB0aGUgY2FsbGJhY2sgZW5hYmxlZCBvciBub3Q/CisgICAgaWYgKCEobVByZXZpZXdDYWxsYmFja0ZsYWcgJiBGUkFNRV9DQUxMQkFDS19GTEFHX0VOQUJMRV9NQVNLKSkgeworICAgICAgICAvLyBJZiB0aGUgZW5hYmxlIGJpdCBpcyBvZmYsIHRoZSBjb3B5LW91dCBhbmQgb25lLXNob3QgYml0cyBhcmUgaWdub3JlZAorICAgICAgICBMT0dWKCJmcmFtZSBjYWxsYmFjayBpcyBkaWFibGVkIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBJcyB0aGUgcmVjZWl2ZWQgZnJhbWUgY29waWVkIG91dCBvciBub3Q/CisgICAgaWYgKG1QcmV2aWV3Q2FsbGJhY2tGbGFnICYgRlJBTUVfQ0FMTEJBQ0tfRkxBR19DT1BZX09VVF9NQVNLKSB7CisgICAgICAgIExPR1YoImZyYW1lIGlzIGNvcGllZCBvdXQiKTsKKyAgICAgICAgY29weUZyYW1lQW5kUG9zdENvcGllZEZyYW1lKGhlYXAsIG9mZnNldCwgc2l6ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HVigiZnJhbWUgaXMgZGlyZWN0bHkgc2VudCBvdXQgd2l0aG91dCBjb3B5aW5nIik7CisgICAgICAgIG1DYW1lcmFDbGllbnQtPnByZXZpZXdDYWxsYmFjayhtZW0pOworICAgIH0KKworICAgIC8vIElzIHRoaXMgaXMgb25lLXNob3Qgb25seT8KKyAgICBpZiAobVByZXZpZXdDYWxsYmFja0ZsYWcgJiBGUkFNRV9DQUxMQkFDS19GTEFHX09ORV9TSE9UX01BU0spIHsKKyAgICAgICAgTE9HVigiT25lLXNob3Qgb25seSwgdGh1cyBjbGVhciB0aGUgYml0cyBhbmQgZGlzYWJsZSBmcmFtZSBjYWxsYmFjayIpOworICAgICAgICBtUHJldmlld0NhbGxiYWNrRmxhZyAmPSB+KEZSQU1FX0NBTExCQUNLX0ZMQUdfT05FX1NIT1RfTUFTSyB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FX0NBTExCQUNLX0ZMQUdfQ09QWV9PVVRfTUFTSyB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FX0NBTExCQUNLX0ZMQUdfRU5BQkxFX01BU0spOworICAgIH0KK30KKwordm9pZCBDYW1lcmFTZXJ2aWNlOjpDbGllbnQ6OnBvc3RFcnJvcihzdGF0dXNfdCBlcnJvcikKK3sKKyAgICBtQ2FtZXJhQ2xpZW50LT5lcnJvckNhbGxiYWNrKGVycm9yKTsKK30KKworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgaWYgKGNoZWNrQ2FsbGluZ1Blcm1pc3Npb24oU3RyaW5nMTYoImFuZHJvaWQucGVybWlzc2lvbi5EVU1QIikpID09IGZhbHNlKSB7CisgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlBlcm1pc3Npb24gRGVuaWFsOiAiCisgICAgICAgICAgICAgICAgImNhbid0IGR1bXAgQ2FtZXJhU2VydmljZSBmcm9tIHBpZD0lZCwgdWlkPSVkXG4iLAorICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSwKKyAgICAgICAgICAgICAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nVWlkKCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgIHdyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIH0gZWxzZSB7CisgICAgICAgIEF1dG9NdXRleCBsb2NrKCZtTG9jayk7CisgICAgICAgIGlmIChtQ2xpZW50ICE9IDApIHsKKyAgICAgICAgICAgIHNwPENsaWVudD4gY3VycmVudENsaWVudCA9IG1DbGllbnQucHJvbW90ZSgpOworICAgICAgICAgICAgc3ByaW50ZihidWZmZXIsICJDbGllbnQgKCVwKSBQSUQ6ICVkXG4iLAorICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2xpZW50LT5nZXRDYW1lcmFDbGllbnQoKS0+YXNCaW5kZXIoKS5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudENsaWVudC0+bUNsaWVudFBpZCk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgICAgICB3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICAgICAgICAgIGN1cnJlbnRDbGllbnQtPm1IYXJkd2FyZS0+ZHVtcChmZCwgYXJncyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJObyBjYW1lcmEgY2xpZW50IHlldC5cbiIpOworICAgICAgICAgICAgd3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisKKyNpZiBERUJVR19IRUFQX0xFQUtTCisKKyNkZWZpbmUgQ0hFQ0tfSU5URVJGQUNFKGludGVyZmFjZSwgZGF0YSwgcmVwbHkpIFwKKyAgICAgICAgZG8geyBpZiAoIWRhdGEuZW5mb3JjZUludGVyZmFjZShpbnRlcmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSkpIHsgXAorICAgICAgICAgICAgTE9HVygiQ2FsbCBpbmNvcnJlY3RseSByb3V0ZWQgdG8gIiAjaW50ZXJmYWNlKTsgXAorICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOyBcCisgICAgICAgIH0gfSB3aGlsZSAoMCkKKworc3RhdHVzX3QgQ2FtZXJhU2VydmljZTo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIC8vIHBlcm1pc3Npb24gY2hlY2tzLi4uCisgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgQm5DYW1lcmFTZXJ2aWNlOjpDT05ORUNUOgorICAgICAgICAgICAgSVBDVGhyZWFkU3RhdGUqIGlwYyA9IElQQ1RocmVhZFN0YXRlOjpzZWxmKCk7CisgICAgICAgICAgICBjb25zdCBpbnQgcGlkID0gaXBjLT5nZXRDYWxsaW5nUGlkKCk7CisgICAgICAgICAgICBjb25zdCBpbnQgc2VsZl9waWQgPSBnZXRwaWQoKTsKKyAgICAgICAgICAgIGlmIChwaWQgIT0gc2VsZl9waWQpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSdyZSBjYWxsZWQgZnJvbSBhIGRpZmZlcmVudCBwcm9jZXNzLCBkbyB0aGUgcmVhbCBjaGVjaworICAgICAgICAgICAgICAgIGlmICghY2hlY2tDYWxsaW5nUGVybWlzc2lvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzE2KCJhbmRyb2lkLnBlcm1pc3Npb24uQ0FNRVJBIikpKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IHVpZCA9IGlwYy0+Z2V0Q2FsbGluZ1VpZCgpOworICAgICAgICAgICAgICAgICAgICBMT0dFKCJQZXJtaXNzaW9uIERlbmlhbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYW4ndCB1c2UgdGhlIGNhbWVyYSBwaWQ9JWQsIHVpZD0lZCIsIHBpZCwgdWlkKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIHN0YXR1c190IGVyciA9IEJuQ2FtZXJhU2VydmljZTo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworCisgICAgTE9HRCgiKysrIG9uVHJhbnNhY3QgZXJyICVkIGNvZGUgJWQiLCBlcnIsIGNvZGUpOworCisgICAgaWYgKGVyciA9PSBVTktOT1dOX1RSQU5TQUNUSU9OIHx8IGVyciA9PSBQRVJNSVNTSU9OX0RFTklFRCkgeworICAgICAgICAvLyB0aGUgJ3NlcnZpY2UnIGNvbW1hbmQgaW50ZXJyb2dhdGVzIHRoaXMgYmluZGVyIGZvciBpdHMgbmFtZSwgYW5kIHRoZW4gc3VwcGxpZXMgaXQKKyAgICAgICAgLy8gZXZlbiBmb3IgdGhlIGRlYnVnZ2luZyBjb21tYW5kcy4gIHRoYXQgbWVhbnMgd2UgbmVlZCB0byBjaGVjayBmb3IgaXQgaGVyZSwgdXNpbmcKKyAgICAgICAgLy8gSVN1cmZhY2VDb21wb3NlciAoc2luY2Ugd2UgZGVsZWdhdGVkIHRoZSBJTlRFUkZBQ0VfVFJBTlNBQ1RJT04gaGFuZGxpbmcgdG8KKyAgICAgICAgLy8gQm5TdXJmYWNlQ29tcG9zZXIgYmVmb3JlIGZhbGxpbmcgdGhyb3VnaCB0byB0aGlzIGNvZGUpLgorCisgICAgICAgIExPR0QoIisrKyBvblRyYW5zYWN0IGNvZGUgJWQiLCBjb2RlKTsKKworICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYVNlcnZpY2UsIGRhdGEsIHJlcGx5KTsKKworICAgICAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIDEwMDA6CisgICAgICAgIHsKKyAgICAgICAgICAgIGlmIChnV2Vha0hlYXAgIT0gMCkgeworICAgICAgICAgICAgICAgIHNwPElNZW1vcnlIZWFwPiBoID0gZ1dlYWtIZWFwLnByb21vdGUoKTsKKyAgICAgICAgICAgICAgICBJTWVtb3J5SGVhcCAqcCA9IGdXZWFrSGVhcC51bnNhZmVfZ2V0KCk7CisgICAgICAgICAgICAgICAgTE9HRCgiQ0hFQ0tJTkcgV0VBSyBSRUZFUkVOQ0UgJXAgKCVwKSIsIGguZ2V0KCksIHApOworICAgICAgICAgICAgICAgIGlmIChoICE9IDApCisgICAgICAgICAgICAgICAgICAgIGgtPnByaW50UmVmcygpOworICAgICAgICAgICAgICAgIGJvb2wgYXR0ZW1wdF90b19kZWxldGUgPSBkYXRhLnJlYWRJbnQzMigpID09IDE7CisgICAgICAgICAgICAgICAgaWYgKGF0dGVtcHRfdG9fZGVsZXRlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIE5PVCBTQUZFIQorICAgICAgICAgICAgICAgICAgICBMT0dEKCJERUxFVElORyBXRUFLIFJFRkVSRU5DRSAlcCAoJXApIiwgaC5nZXQoKSwgcCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChwKSBkZWxldGUgcDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGVycjsKK30KKworI2VuZGlmIC8vIERFQlVHX0hFQVBfTEVBS1MKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0NhbWVyYVNlcnZpY2UuaCBiL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0NhbWVyYVNlcnZpY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOWI3OTI3Ci0tLSAvZGV2L251bGwKKysrIGIvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvQ2FtZXJhU2VydmljZS5oCkBAIC0wLDAgKzEsMjA2IEBACisvKgorKioKKyoqIENvcHlyaWdodCAoQykgMjAwOCwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKiogQ29weXJpZ2h0IChDKSAyMDA4IEhUQyBJbmMuCisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfU0VSVkVSU19DQU1FUkFfQ0FNRVJBU0VSVklDRV9ICisjZGVmaW5lIEFORFJPSURfU0VSVkVSU19DQU1FUkFfQ0FNRVJBU0VSVklDRV9ICisKKyNpbmNsdWRlIDx1aS9JQ2FtZXJhU2VydmljZS5oPgorI2luY2x1ZGUgPHVpL0NhbWVyYUhhcmR3YXJlSW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8dWkvQ2FtZXJhLmg+CisKK2NsYXNzIGFuZHJvaWQ6Ok1lbW9yeUhlYXBCYXNlOworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBMSUtFTFkoIGV4cCApICAgICAgIChfX2J1aWx0aW5fZXhwZWN0KCAoZXhwKSAhPSAwLCB0cnVlICApKQorI2RlZmluZSBVTkxJS0VMWSggZXhwICkgICAgIChfX2J1aWx0aW5fZXhwZWN0KCAoZXhwKSAhPSAwLCBmYWxzZSApKQorCisvLyBXaGVuIGVuYWJsZWQsIHRoaXMgZmVhdHVyZSBhbGxvd3MgeW91IHRvIHNlbmQgYW4gZXZlbnQgdG8gdGhlIENhbWVyYVNlcnZpY2UKKy8vIHNvIHRoYXQgeW91IGNhbiBjYXVzZSBhbGwgcmVmZXJlbmNlcyB0byB0aGUgaGVhcCBvYmplY3QgZ1dlYWtIZWFwLCBkZWZpbmVkCisvLyBiZWxvdywgdG8gYmUgcHJpbnRlZC4gWW91IHdpbGwgYWxzbyBuZWVkIHRvIHNldCBERUJVR19SRUZTPTEgYW5kCisvLyBERUJVR19SRUZTX0VOQUJMRURfQllfREVGQVVMVD0wIGluIGxpYnV0aWxzL1JlZkJhc2UuY3BwLiBZb3UganVzdCBoYXZlIHRvCisvLyBzZXQgZ1dlYWtIZWFwIHRvIHRoZSBhcHByb3ByaWF0ZSBoZWFwIHlvdSB3YW50IHRvIHRyYWNrLgorCisjZGVmaW5lIERFQlVHX0hFQVBfTEVBS1MgMAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIENhbWVyYVNlcnZpY2UgOiBwdWJsaWMgQm5DYW1lcmFTZXJ2aWNlCit7CisgICAgY2xhc3MgQ2xpZW50OworCitwdWJsaWM6CisgICAgc3RhdGljIHZvaWQgaW5zdGFudGlhdGUoKTsKKworICAgIC8vIElDYW1lcmFTZXJ2aWNlIGludGVyZmFjZQorICAgIHZpcnR1YWwgc3A8SUNhbWVyYT4gICAgIGNvbm5lY3QoY29uc3Qgc3A8SUNhbWVyYUNsaWVudD4mIGNhbWVyYUNsaWVudCk7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICByZW1vdmVDbGllbnQoY29uc3Qgc3A8SUNhbWVyYUNsaWVudD4mIGNhbWVyYUNsaWVudCk7CisKKyNpZiBERUJVR19IRUFQX0xFQUtTCisgICAgdmlydHVhbCBzdGF0dXNfdCBvblRyYW5zYWN0KAorICAgICAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKTsKKyNlbmRpZgorCitwcml2YXRlOgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBjbGFzcyBDbGllbnQgOiBwdWJsaWMgQm5DYW1lcmEgeworCisgICAgcHVibGljOgorICAgICAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBkaXNjb25uZWN0KCk7CisKKyAgICAgICAgLy8gY29ubmVjdCBuZXcgY2xpZW50IHdpdGggZXhpc3RpbmcgY2FtZXJhIHJlbW90ZQorICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBjb25uZWN0KGNvbnN0IHNwPElDYW1lcmFDbGllbnQ+JiBjbGllbnQpOworCisgICAgICAgIC8vIHByZXZlbnQgb3RoZXIgcHJvY2Vzc2VzIGZyb20gdXNpbmcgdGhpcyBJQ2FtZXJhIGludGVyZmFjZQorICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBsb2NrKCk7CisKKyAgICAgICAgLy8gYWxsb3cgb3RoZXIgcHJvY2Vzc2VzIHRvIHVzZSB0aGlzIElDYW1lcmEgaW50ZXJmYWNlCisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIHVubG9jaygpOworCisgICAgICAgIC8vIHBhc3MgdGhlIGJ1ZmZlcmVkIElTdXJmYWNlIHRvIHRoZSBjYW1lcmEgc2VydmljZQorICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBzZXRQcmV2aWV3RGlzcGxheShjb25zdCBzcDxJU3VyZmFjZT4mIHN1cmZhY2UpOworCisgICAgICAgIC8vIHNldCB0aGUgcHJldmlldyBjYWxsYmFjayBmbGFnIHRvIGFmZmVjdCBob3cgdGhlIHJlY2VpdmVkIGZyYW1lcyBmcm9tCisgICAgICAgIC8vIHByZXZpZXcgYXJlIGhhbmRsZWQuCisgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHNldFByZXZpZXdDYWxsYmFja0ZsYWcoaW50IGNhbGxiYWNrX2ZsYWcpOworCisgICAgICAgIC8vIHN0YXJ0IHByZXZpZXcgbW9kZSwgbXVzdCBjYWxsIHNldFByZXZpZXdEaXNwbGF5IGZpcnN0CisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIHN0YXJ0UHJldmlldygpOworCisgICAgICAgIC8vIHN0b3AgcHJldmlldyBtb2RlCisgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHN0b3BQcmV2aWV3KCk7CisKKyAgICAgICAgLy8gZ2V0IHByZXZpZXcgc3RhdGUKKyAgICAgICAgdmlydHVhbCBib29sICAgICAgICAgICAgcHJldmlld0VuYWJsZWQoKTsKKworICAgICAgICAvLyBzdGFydCByZWNvcmRpbmcgbW9kZQorICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBzdGFydFJlY29yZGluZygpOworCisgICAgICAgIC8vIHN0b3AgcmVjb3JkaW5nIG1vZGUKKyAgICAgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgc3RvcFJlY29yZGluZygpOworCisgICAgICAgIC8vIGdldCByZWNvcmRpbmcgc3RhdGUKKyAgICAgICAgdmlydHVhbCBib29sICAgICAgICAgICAgcmVjb3JkaW5nRW5hYmxlZCgpOworCisgICAgICAgIC8vIHJlbGVhc2UgYSByZWNvcmRpbmcgZnJhbWUKKyAgICAgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVsZWFzZVJlY29yZGluZ0ZyYW1lKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0pOworCisgICAgICAgIC8vIGF1dG8gZm9jdXMKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgYXV0b0ZvY3VzKCk7CisKKyAgICAgICAgLy8gdGFrZSBhIHBpY3R1cmUgLSByZXR1cm5zIGFuIElNZW1vcnkgKHJlZi1jb3VudGVkIG1tYXApCisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIHRha2VQaWN0dXJlKCk7CisKKyAgICAgICAgLy8gc2V0IHByZXZpZXcvY2FwdHVyZSBwYXJhbWV0ZXJzIC0ga2V5L3ZhbHVlIHBhaXJzCisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIHNldFBhcmFtZXRlcnMoY29uc3QgU3RyaW5nOCYgcGFyYW1zKTsKKworICAgICAgICAvLyBnZXQgcHJldmlldy9jYXB0dXJlIHBhcmFtZXRlcnMgLSBrZXkvdmFsdWUgcGFpcnMKKyAgICAgICAgdmlydHVhbCBTdHJpbmc4ICAgICAgICAgZ2V0UGFyYW1ldGVycygpIGNvbnN0OworCisgICAgICAgIC8vIG91ciBjbGllbnQuLi4KKyAgICAgICAgY29uc3Qgc3A8SUNhbWVyYUNsaWVudD4mICAgIGdldENhbWVyYUNsaWVudCgpIGNvbnN0IHsgcmV0dXJuIG1DYW1lcmFDbGllbnQ7IH0KKworICAgIHByaXZhdGU6CisgICAgICAgIGZyaWVuZCBjbGFzcyBDYW1lcmFTZXJ2aWNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQoY29uc3Qgc3A8Q2FtZXJhU2VydmljZT4mIGNhbWVyYVNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8SUNhbWVyYUNsaWVudD4mIGNhbWVyYUNsaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWRfdCBjbGllbnRQaWQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQoKTsKKyAgICAgICAgdmlydHVhbCAgICAgICAgICAgICAgICAgfkNsaWVudCgpOworCisgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICAgIGNoZWNrUGlkKCk7CisKKyAgICAgICAgc3RhdGljICAgICAgdm9pZCAgICAgICAgcmVjb3JkaW5nQ2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCogdXNlcik7CisgICAgICAgIHN0YXRpYyAgICAgIHZvaWQgICAgICAgIHByZXZpZXdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgbWVtLCB2b2lkKiB1c2VyKTsKKyAgICAgICAgc3RhdGljICAgICAgdm9pZCAgICAgICAgc2h1dHRlckNhbGxiYWNrKHZvaWQgKnVzZXIpOworICAgICAgICBzdGF0aWMgICAgICB2b2lkICAgICAgICB5dXZQaWN0dXJlQ2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCogdXNlcik7CisgICAgICAgIHN0YXRpYyAgICAgIHZvaWQgICAgICAgIGpwZWdQaWN0dXJlQ2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCogdXNlcik7CisgICAgICAgIHN0YXRpYyAgICAgIHZvaWQgICAgICAgIGF1dG9Gb2N1c0NhbGxiYWNrKGJvb2wgZm9jdXNlZCwgdm9pZCogdXNlcik7CisgICAgICAgIHN0YXRpYyAgICAgIHNwPENsaWVudD4gIGdldENsaWVudEZyb21Db29raWUodm9pZCogdXNlcik7CisKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgcG9zdFNodXR0ZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgcG9zdFJhdyhjb25zdCBzcDxJTWVtb3J5PiYgbWVtKTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgcG9zdEpwZWcoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSk7CisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHBvc3RQcmV2aWV3RnJhbWUoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSk7CisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHBvc3RSZWNvcmRpbmdGcmFtZShjb25zdCBzcDxJTWVtb3J5PiYgZnJhbWUpOworICAgICAgICAgICAgICAgICAgICB2b2lkICAgICAgICBjb3B5RnJhbWVBbmRQb3N0Q29waWVkRnJhbWUoc3A8SU1lbW9yeUhlYXA+IGhlYXAsIHNpemVfdCBvZmZzZXQsIHNpemVfdCBzaXplKTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgcG9zdEVycm9yKHN0YXR1c190IGVycm9yKTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgcG9zdEF1dG9Gb2N1cyhib29sIGZvY3VzZWQpOworCisgICAgICAgIC8vIGNhbWVyYSBvcGVyYXRpb24gbW9kZQorICAgICAgICBlbnVtIGNhbWVyYV9tb2RlIHsKKyAgICAgICAgICAgIENBTUVSQV9QUkVWSUVXX01PREUgICA9IDAsICAvLyBmcmFtZSBhdXRvbWF0aWNhbGx5IHJlbGVhc2VkCisgICAgICAgICAgICBDQU1FUkFfUkVDT1JESU5HX01PREUgPSAxLCAgLy8gZnJhbWUgaGFzIHRvIGJlIGV4cGxpY2l0bHkgcmVsZWFzZWQgYnkgcmVsZWFzZVJlY29yZGluZ0ZyYW1lKCkKKyAgICAgICAgfTsKKyAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICAgICAgc3RhcnRDYW1lcmFNb2RlKGNhbWVyYV9tb2RlIG1vZGUpOworICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgICAgICBzdGFydFByZXZpZXdNb2RlKCk7CisgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgICAgIHN0YXJ0UmVjb3JkaW5nTW9kZSgpOworCisgICAgICAgIC8vIEVuc3VyZXMgYXRvbWljaXR5IGFtb25nIHRoZSBwdWJsaWMgbWV0aG9kcworICAgICAgICBtdXRhYmxlICAgICBNdXRleCAgICAgICAgICAgICAgICAgICAgICAgbUxvY2s7CisKKyAgICAgICAgLy8gbVN1cmZhY2VMb2NrIHN5bmNocm9uaXplcyBhY2Nlc3MgdG8gbVN1cmZhY2UgYmV0d2VlbgorICAgICAgICAvLyBzZXRQcmV2aWV3U3VyZmFjZSgpIGFuZCBwb3N0UHJldmlld0ZyYW1lKCkuICBOb3RlIHRoYXQgYW1vbmcKKyAgICAgICAgLy8gdGhlIHB1YmxpYyBtZXRob2RzLCBhbGwgYWNjZXNzZXMgdG8gbVN1cmZhY2UgYXJlCisgICAgICAgIC8vIHN5bmNyaG9uaXplZCBieSBtTG9jay4gIEhvd2V2ZXIsIHBvc3RQcmV2aWV3RnJhbWUoKSBpcyBjYWxsZWQKKyAgICAgICAgLy8gYnkgdGhlIENhbWVyYUhhcmR3YXJlSW50ZXJmYWNlIGNhbGxiYWNrLCBhbmQgbmVlZHMgdG8KKyAgICAgICAgLy8gYWNjZXNzIG1TdXJmYWNlLiAgSXQgY2Fubm90IGhvbGQgbUxvY2ssIGhvd2V2ZXIsIGJlY2F1c2UKKyAgICAgICAgLy8gc3RvcFByZXZpZXcoKSBtYXkgYmUgaG9sZGluZyB0aGF0IGxvY2sgd2hpbGUgYXR0ZW1wdGluZworICAgICAgICAvLyB0byBzdG9wIHByZXZpZXcsIGFuZCBzdG9wUHJldmlldyBpdHNlbGYgd2lsbCBibG9jayB3YWl0aW5nCisgICAgICAgIC8vIGZvciBhIGNhbGxiYWNrIGZyb20gQ2FtZXJhSGFyZHdhcmVJbnRlcmZhY2UuICBJZiB0aGlzCisgICAgICAgIC8vIGhhcHBlbnMsIGl0IHdpbGwgY2F1c2UgYSBkZWFkbG9jay4KKyAgICAgICAgbXV0YWJsZSAgICAgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgIG1TdXJmYWNlTG9jazsKKyAgICAgICAgbXV0YWJsZSAgICAgQ29uZGl0aW9uICAgICAgICAgICAgICAgICAgIG1SZWFkeTsKKyAgICAgICAgICAgICAgICAgICAgc3A8Q2FtZXJhU2VydmljZT4gICAgICAgICAgIG1DYW1lcmFTZXJ2aWNlOworICAgICAgICAgICAgICAgICAgICBzcDxJU3VyZmFjZT4gICAgICAgICAgICAgICAgbVN1cmZhY2U7CisgICAgICAgICAgICAgICAgICAgIHNwPE1lbW9yeUhlYXBCYXNlPiAgICAgICAgICBtUHJldmlld0J1ZmZlcjsKKyAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgIG1QcmV2aWV3Q2FsbGJhY2tGbGFnOworCisgICAgICAgICAgICAgICAgICAgIC8vIHRoZXNlIGFyZSBpbW11dGFibGUgb25jZSB0aGUgb2JqZWN0IGlzIGNyZWF0ZWQsCisgICAgICAgICAgICAgICAgICAgIC8vIHRoZXkgZG9uJ3QgbmVlZCB0byBiZSBwcm90ZWN0ZWQgYnkgYSBsb2NrCisgICAgICAgICAgICAgICAgICAgIHNwPElDYW1lcmFDbGllbnQ+ICAgICAgICAgICBtQ2FtZXJhQ2xpZW50OworICAgICAgICAgICAgICAgICAgICBzcDxDYW1lcmFIYXJkd2FyZUludGVyZmFjZT4gbUhhcmR3YXJlOworICAgICAgICAgICAgICAgICAgICBwaWRfdCAgICAgICAgICAgICAgICAgICAgICAgbUNsaWVudFBpZDsKKyAgICAgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgIG1Vc2VPdmVybGF5OworICAgIH07CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbWVyYVNlcnZpY2UoKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgICAgICB+Q2FtZXJhU2VydmljZSgpOworCisgICAgbXV0YWJsZSAgICAgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgIG1Mb2NrOworICAgICAgICAgICAgICAgIHdwPENsaWVudD4gICAgICAgICAgICAgICAgICBtQ2xpZW50OworCisjaWYgREVCVUdfSEVBUF9MRUFLUworICAgICAgICAgICAgICAgIHdwPElNZW1vcnlIZWFwPiAgICAgICAgICAgICBnV2Vha0hlYXA7CisjZW5kaWYKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCmRpZmYgLS1naXQgYS9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW5uZWRKcGVnLmggYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9DYW5uZWRKcGVnLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTMyNTYwYQotLS0gL2Rldi9udWxsCisrKyBiL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0Nhbm5lZEpwZWcuaApAQCAtMCwwICsxLDE1NDYgQEAKK2NvbnN0IGludCBrQ2FubmVkSnBlZ1dpZHRoID0gMjEzOworY29uc3QgaW50IGtDYW5uZWRKcGVnSGVpZ2h0ID0gMzUwOworY29uc3QgaW50IGtDYW5uZWRKcGVnU2l6ZSA9IDE4NDc0OworCitjb25zdCBjaGFyIGtDYW5uZWRKcGVnW10gPSB7CisgIDB4ZmYsIDB4ZDgsIDB4ZmYsIDB4ZTAsIDB4MDAsIDB4MTAsIDB4NGEsIDB4NDYsIDB4NDksIDB4NDYsIDB4MDAsIDB4MDEsCisgIDB4MDEsIDB4MDEsIDB4MDAsIDB4NDgsIDB4MDAsIDB4NDgsIDB4MDAsIDB4MDAsIDB4ZmYsIDB4ZGIsIDB4MDAsIDB4NDMsCisgIDB4MDAsIDB4MDUsIDB4MDMsIDB4MDQsIDB4MDQsIDB4MDQsIDB4MDMsIDB4MDUsIDB4MDQsIDB4MDQsIDB4MDQsIDB4MDUsCisgIDB4MDUsIDB4MDUsIDB4MDYsIDB4MDcsIDB4MGMsIDB4MDgsIDB4MDcsIDB4MDcsIDB4MDcsIDB4MDcsIDB4MGYsIDB4MGIsCisgIDB4MGIsIDB4MDksIDB4MGMsIDB4MTEsIDB4MGYsIDB4MTIsIDB4MTIsIDB4MTEsIDB4MGYsIDB4MTEsIDB4MTEsIDB4MTMsCisgIDB4MTYsIDB4MWMsIDB4MTcsIDB4MTMsIDB4MTQsIDB4MWEsIDB4MTUsIDB4MTEsIDB4MTEsIDB4MTgsIDB4MjEsIDB4MTgsCisgIDB4MWEsIDB4MWQsIDB4MWQsIDB4MWYsIDB4MWYsIDB4MWYsIDB4MTMsIDB4MTcsIDB4MjIsIDB4MjQsIDB4MjIsIDB4MWUsCisgIDB4MjQsIDB4MWMsIDB4MWUsIDB4MWYsIDB4MWUsIDB4ZmYsIDB4ZGIsIDB4MDAsIDB4NDMsIDB4MDEsIDB4MDUsIDB4MDUsCisgIDB4MDUsIDB4MDcsIDB4MDYsIDB4MDcsIDB4MGUsIDB4MDgsIDB4MDgsIDB4MGUsIDB4MWUsIDB4MTQsIDB4MTEsIDB4MTQsCisgIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsCisgIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsCisgIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsCisgIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsIDB4MWUsCisgIDB4MWUsIDB4MWUsIDB4ZmYsIDB4YzAsIDB4MDAsIDB4MTEsIDB4MDgsIDB4MDEsIDB4NWUsIDB4MDAsIDB4ZDUsIDB4MDMsCisgIDB4MDEsIDB4MjIsIDB4MDAsIDB4MDIsIDB4MTEsIDB4MDEsIDB4MDMsIDB4MTEsIDB4MDEsIDB4ZmYsIDB4YzQsIDB4MDAsCisgIDB4MWMsIDB4MDAsIDB4MDAsIDB4MDIsIDB4MDIsIDB4MDMsIDB4MDEsIDB4MDEsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsCisgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDYsIDB4MDUsIDB4MDcsIDB4MDEsIDB4MDMsCisgIDB4MDQsIDB4MDIsIDB4MDgsIDB4ZmYsIDB4YzQsIDB4MDAsIDB4NTUsIDB4MTAsIDB4MDAsIDB4MDEsIDB4MDMsIDB4MDQsCisgIDB4MDAsIDB4MDMsIDB4MDMsIDB4MDUsIDB4MGEsIDB4MDksIDB4MDgsIDB4MDksIDB4MDIsIDB4MDYsIDB4MDMsIDB4MDAsCisgIDB4MDEsIDB4MDIsIDB4MDMsIDB4MDQsIDB4MDAsIDB4MDUsIDB4MDYsIDB4MTEsIDB4MDcsIDB4MTIsIDB4MjEsIDB4MTMsCisgIDB4MzEsIDB4NDEsIDB4MTQsIDB4MjIsIDB4NTEsIDB4NjEsIDB4NzEsIDB4MTUsIDB4MjMsIDB4MzIsIDB4MzQsIDB4MzcsCisgIDB4NzIsIDB4NzUsIDB4ODEsIDB4YjEsIDB4YjMsIDB4MDgsIDB4MTcsIDB4MzMsIDB4NDIsIDB4NTIsIDB4NjIsIDB4NzYsCisgIDB4OTMsIDB4YjIsIDB4MTYsIDB4MjQsIDB4NDMsIDB4NTMsIDB4NTYsIDB4OTEsIDB4YTEsIDB4ZDIsIDB4MjUsIDB4MzYsCisgIDB4NjMsIDB4NzMsIDB4ODIsIDB4OTIsIDB4YTIsIDB4YzEsIDB4ZDEsIDB4NjUsIDB4ZjAsIDB4MjYsIDB4MjcsIDB4NjQsCisgIDB4NjYsIDB4NzQsIDB4ZTEsIDB4ODMsIDB4YzIsIDB4ZjEsIDB4ZmYsIDB4YzQsIDB4MDAsIDB4MWIsIDB4MDEsIDB4MDEsCisgIDB4MDAsIDB4MDMsIDB4MDEsIDB4MDEsIDB4MDEsIDB4MDEsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsCisgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDEsIDB4MDIsIDB4MDMsIDB4MDQsIDB4MDUsIDB4MDYsIDB4MDcsIDB4ZmYsCisgIDB4YzQsIDB4MDAsIDB4MzUsIDB4MTEsIDB4MDAsIDB4MDIsIDB4MDEsIDB4MDMsIDB4MDMsIDB4MDEsIDB4MDUsIDB4MDUsCisgIDB4MDcsIDB4MDQsIDB4MDMsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDEsIDB4MDIsIDB4MDMsCisgIDB4MDQsIDB4MTEsIDB4MTIsIDB4MjEsIDB4MzEsIDB4NDEsIDB4MDUsIDB4MjIsIDB4MzIsIDB4NTEsIDB4NjEsIDB4MDYsCisgIDB4MTMsIDB4NzEsIDB4ODEsIDB4YjEsIDB4MTQsIDB4MzMsIDB4NDIsIDB4OTEsIDB4YTEsIDB4YzEsIDB4ZDEsIDB4MTUsCisgIDB4MjMsIDB4ZTEsIDB4ZjAsIDB4MjQsIDB4NTMsIDB4OTIsIDB4ZmYsIDB4ZGEsIDB4MDAsIDB4MGMsIDB4MDMsIDB4MDEsCisgIDB4MDAsIDB4MDIsIDB4MTEsIDB4MDMsIDB4MTEsIDB4MDAsIDB4M2YsIDB4MDAsIDB4ZmIsIDB4MmUsIDB4OGEsIDB4MmIsCisgIDB4Y2EsIDB4OTUsIDB4YWUsIDB4ZmUsIDB4ZWEsIDB4MDMsIDB4ZDUsIDB4MTUsIDB4OGQsIDB4ZmIsIDB4MjgsIDB4ZGYsCisgIDB4YjIsIDB4ODAsIDB4Y2QsIDB4MTUsIDB4OGQsIDB4ZmIsIDB4MjgsIDB4ZGYsIDB4YjIsIDB4ODAsIDB4Y2QsIDB4MTUsCisgIDB4OGQsIDB4ZmIsIDB4MjgsIDB4ZTYsIDB4YTAsIDB4MzMsIDB4NDUsIDB4NjMsIDB4OWEsIDB4YjMsIDB4NDAsIDB4MTQsCisgIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NDUsIDB4MTQsIDB4NTAsIDB4MDUsIDB4MTQsCisgIDB4NTYsIDB4MzcsIDB4NDAsIDB4NjYsIDB4OGEsIDB4MzcsIDB4ZDYsIDB4YjEsIDB4YmYsIDB4NjUsIDB4MDEsIDB4OWEsCisgIDB4MmIsIDB4MWIsIDB4ZjYsIDB4NTEsIDB4YmYsIDB4NjUsIDB4MDEsIDB4OWEsIDB4MmIsIDB4MWIsIDB4ZjYsIDB4NTEsCisgIDB4YmYsIDB4NjUsIDB4MDEsIDB4OWEsIDB4MmIsIDB4YzksIDB4NTYsIDB4YmIsIDB4ZWIsIDB4ZDAsIDB4YTAsIDB4MGEsCisgIDB4MmIsIDB4Y2EsIDB4OTUsIDB4YTMsIDB4NDUsIDB4MDEsIDB4ZWEsIDB4OTMsIDB4NzgsIDB4ZTEsIDB4YjEsIDB4YzEsCisgIDB4ZWMsIDB4YjgsIDB4ODIsIDB4NDEsIDB4ZjcsIDB4MWUsIDB4NGYsIDB4NzEsIDB4ZDcsIDB4ZjQsIDB4NjYsIDB4OWMsCisgIDB4YTksIDB4MzcsIDB4OGUsIDB4NWYsIDB4MjMsIDB4YjksIDB4NzcsIDB4ZDAsIDB4ZjIsIDB4N2UsIDB4ZWMsIDB4ZDAsCisgIDB4MTUsIDB4YjMsIDB4NWMsIDB4M2MsIDB4YzEsIDB4ZDQsIDB4ZDIsIDB4MTQsIDB4NzEsIDB4N2IsIDB4NjksIDB4MjUsCisgIDB4MjAsIDB4OWYsIDB4N2EsIDB4YWYsIDB4NWYsIDB4OGIsIDB4YmMsIDB4MWIsIDB4ZmIsIDB4MmQsIDB4NmMsIDB4ZmQsCisgIDB4ZDUsIDB4MzMsIDB4MzEsIDB4ZjksIDB4MTYsIDB4ZmUsIDB4NjgsIDB4ZmIsIDB4MmIsIDB4ZGQsIDB4N2IsIDB4OWEsCisgIDB4MjMsIDB4ZTQsIDB4NzgsIDB4OWEsIDB4ZTUsIDB4ZTYsIDB4MmIsIDB4N2UsIDB4MmUsIDB4ZjAsIDB4NmYsIDB4ZWMsCisgIDB4YjUsIDB4YjMsIDB4ZjcsIDB4NTQsIDB4MWUsIDB4MWUsIDB4NjAsIDB4YzMsIDB4YWYsIDB4ZjIsIDB4NWEsIDB4ZDksCisgIDB4YWYsIDB4ZjcsIDB4NTQsIDB4YzcsIDB4MzYsIDB4NTQsIDB4NjgsIDB4NTAsIDB4ZGUsIDB4OTksIDB4MzIsIDB4NDMsCisgIDB4NTEsIDB4YTMsIDB4MzAsIDB4OTIsIDB4YjcsIDB4NWUsIDB4NzUsIDB4NDEsIDB4MjgsIDB4NDIsIDB4NDAsIDB4ZWEsCisgIDB4NTQsIDB4NGYsIDB4NDAsIDB4MmEsIDB4MmUsIDB4Y2YsIDB4MTMsIDB4MjgsIDB4Y2QsIDB4ZjksIDB4NWMsIDB4YjMsCisgIDB4MDcsIDB4YjEsIDB4Y2MsIDB4N2QsIDB4NjMsIDB4N2UsIDB4ZWIsIDB4NDksIDB4NjcsIDB4ZjksIDB4ZDQsIDB4OTQsCisgIDB4ZmEsIDB4NjMsIDB4MzQsIDB4YWYsIDB4ODAsIDB4OTMsIDB4ZTAsIDB4ZTMsIDB4ODMsIDB4YWUsIDB4ZjYsIDB4MTAsCisgIDB4N2EsIDB4MWEsIDB4Y2UsIDB4YTQsIDB4YTksIDB4NTMsIDB4NTksIDB4OTIsIDB4NDYsIDB4OTQsIDB4ZTMsIDB4NTIsCisgIDB4YTMsIDB4YzQsIDB4NWIsIDB4MTcsIDB4MmYsIDB4OTgsIDB4ZGYsIDB4MGIsIDB4ZWMsIDB4YWEsIDB4NjUsIDB4YTksCisgIDB4ZjYsIDB4MWIsIDB4NjAsIDB4OTIsIDB4ZmYsIDB4MDAsIDB4NDgsIDB4ZjEsIDB4MTksIDB4OGMsIDB4YTcsIDB4YTQsCisgIDB4M2UsIDB4N2QsIDB4MDgsIDB4NjksIDB4MDAsIDB4YWQsIDB4NWYsIDB4NTAsIDB4ZDcsIDB4YTcsIDB4NTUsIDB4OTgsCisgIDB4MWMsIDB4MjgsIDB4OTMsIDB4OTEsIDB4ODQsIDB4MmEsIDB4MGUsIDB4MDksIDB4NjIsIDB4YzUsIDB4MjAsIDB4YTgsCisgIDB4ZWYsIDB4Y2EsIDB4NmUsIDB4Y2MsIDB4ODcsIDB4ZTUsIDB4OTEsIDB4YWUsIDB4ZjQsIDB4YzcsIDB4NDIsIDB4YjksCisgIDB4NTAsIDB4N2UsIDB4N2EsIDB4ZjYsIDB4M2YsIDB4NDYsIDB4YWUsIDB4OWMsIDB4MzMsIDB4MGEsIDB4YzcsIDB4NzEsCisgIDB4NDYsIDB4ZDYsIDB4YmIsIDB4NGMsIDB4MWYsIDB4ZTcsIDB4NmYsIDB4MGYsIDB4ZTcsIDB4MzMsIDB4YTQsIDB4MmMsCisgIDB4YmIsIDB4MmEsIDB4NDEsIDB4ZjQsIDB4YWQsIDB4ZDUsIDB4NzksIDB4YzcsIDB4YmIsIDB4YmIsIDB4YTIsIDB4NDcsCisgIDB4ODAsIDB4MTQsIDB4YzUsIDB4YWEsIDB4ZjMsIDB4ZWEsIDB4NWMsIDB4NmEsIDB4ZjAsIDB4YTQsIDB4OGUsIDB4ZmEsCisgIDB4NzQsIDB4MzQsIDB4ZWUsIDB4ZGIsIDB4NjUsIDB4NDcsIDB4OGUsIDB4N2UsIDB4MGYsIDB4MWMsIDB4MzcsIDB4YjYsCisgIDB4YmUsIDB4MjYsIDB4NWMsIDB4NmQsIDB4ZWYsIDB4ZGYsIDB4MjYsIDB4ZWIsIDB4ZjIsIDB4OTMsIDB4MWMsIDB4ZTUsCisgIDB4NmQsIDB4M2UsIDB4OTAsIDB4OTYsIDB4NWIsIDB4ZTUsIDB4NmMsIDB4MGYsIDB4NjgsIDB4MjcsIDB4ZDcsIDB4NGMsCisgIDB4YmYsIDB4OGEsIDB4MmUsIDB4MTksIDB4ZmYsIDB4MDAsIDB4NjIsIDB4YWMsIDB4ZmYsIDB4MDAsIDB4YjgsIDB4YTcsCisgIDB4OGEsIDB4MmIsIDB4OWMsIDB4ZTgsIDB4MTIsIDB4M2YsIDB4MTQsIDB4N2MsIDB4MzMsIDB4ZmUsIDB4YzUsIDB4NTksCisgIDB4ZmYsIDB4MDAsIDB4NzEsIDB4NDcsIDB4ZTIsIDB4OGYsIDB4ODYsIDB4N2YsIDB4ZDgsIDB4YWIsIDB4M2YsIDB4ZWUsCisgIDB4MjksIDB4ZGUsIDB4OGEsIDB4MDEsIDB4MDksIDB4Y2UsIDB4MTYsIDB4NzAsIDB4YWQsIDB4YjcsIDB4ZDAsIDB4YzMsCisgIDB4OTgsIDB4OGQsIDB4ODksIDB4MGUsIDB4YjksIDB4ZjAsIDB4MTAsIDB4YTYsIDB4YzAsIDB4NTIsIDB4YmQsIDB4ODMsCisgIDB4N2QsIDB4NmIsIDB4NzcsIDB4ZTIsIDB4OGYsIDB4ODYsIDB4N2YsIDB4ZDgsIDB4YWIsIDB4M2YsIDB4ZWUsIDB4MmIsCisgIDB4YjYsIDB4ZWYsIDB4ZWYsIDB4OWMsIDB4NDAsIDB4YjUsIDB4MjMsIDB4YWYsIDB4OTgsIDB4Y2EsIDB4ZDUsIDB4ZjYsCisgIDB4ZDMsIDB4NTUsIDB4NzIsIDB4ZGIsIDB4ZDcsIDB4NzUsIDB4NjUsIDB4NTEsIDB4NjMsIDB4YzIsIDB4ZjEsIDB4ZmEsCisgIDB4MjcsIDB4ZmIsIDB4OTAsIDB4OWUsIDB4NDQsIDB4OGYsIDB4YzUsIDB4MWYsIDB4MGMsIDB4ZmYsIDB4MDAsIDB4YjEsCisgIDB4NTYsIDB4N2YsIDB4ZGMsIDB4NTEsIDB4ZjgsIDB4YTMsIDB4ZTEsIDB4OWYsIDB4ZjYsIDB4MmEsIDB4Y2YsIDB4ZmIsCisgIDB4OGEsIDB4NzcsIDB4YTIsIDB4YmEsIDB4ODksIDB4MTIsIDB4M2YsIDB4MTQsIDB4N2MsIDB4MzMsIDB4ZmUsIDB4YzUsCisgIDB4NTksIDB4ZmYsIDB4MDAsIDB4NzEsIDB4NTgsIDB4NTcsIDB4MDgsIDB4YjgsIDB4NjYsIDB4YTQsIDB4OTQsIDB4OWMsCisgIDB4MmEsIDB4ZDEsIDB4YTIsIDB4MzQsIDB4NzQsIDB4Y2UsIDB4YTksIDB4ZTIsIDB4OGEsIDB4MDIsIDB4OTEsIDB4YmUsCisgIDB4N2UsIDB4MGUsIDB4MzgsIDB4NzAsIDB4NzUsIDB4ZDksIDB4NTgsIDB4YTksIDB4MTYsIDB4YTcsIDB4ZDQsIDB4NzYsCisgIDB4MjMsIDB4NGMsIDB4NmIsIDB4Y2IsIDB4YTEsIDB4YTgsIDB4ZmEsIDB4MGEsIDB4MWMsIDB4M2MsIDB4ZTksIDB4ZGYsCisgIDB4ZWEsIDB4YWQsIDB4M2UsIDB4Y2EsIDB4NTgsIDB4YjgsIDB4NjEsIDB4MzYsIDB4Y2MsIDB4NjgsIDB4N2YsIDB4ZjEsCisgIDB4OGYsIDB4MGMsIDB4ZTAsIDB4MzcsIDB4MTksIDB4M2YsIDB4MGEsIDB4ZWIsIDB4NjgsIDB4NjksIDB4NTIsIDB4YTIsCisgIDB4MDEsIDB4YWUsIDB4ZjUsIDB4YTMsIDB4NWQsIDB4YWIsIDB4NDMsIDB4ZDYsIDB4NTIsIDB4YTQsIDB4OGYsIDB4ZDIsCisgIDB4ZjEsIDB4YWYsIDB4YTUsIDB4NDgsIDB4MWIsIDB4ZGQsIDB4NjMsIDB4NDIsIDB4YjQsIDB4ODUsIDB4NDcsIDB4MGUsCisgIDB4MGMsIDB4ZTcsIDB4NGQsIDB4NGYsIDB4OTMsIDB4ZTcsIDB4ZmIsIDB4NzYsIDB4MTEsIDB4YzMsIDB4YWIsIDB4OTQsCisgIDB4MjYsIDB4ZTYsIDB4ZGIsIDB4YWMsIDB4MzYsIDB4NTksIDB4OTEsIDB4OWQsIDB4MWIsIDB4NmQsIDB4ZTYsIDB4MTIsCisgIDB4MTYsIDB4ODUsIDB4OGYsIDB4NTEsIDB4NDksIDB4MjMsIDB4ZmYsIDB4MDAsIDB4N2EsIDB4YWUsIDB4ODEsIDB4YzMsCisgIDB4YmMsIDB4MWIsIDB4NWYsIDB4ZWEsIDB4YjUsIDB4YjMsIDB4ZjcsIDB4NTQsIDB4ZjEsIDB4OTUsIDB4NzAsIDB4Y2UsCisgIDB4ZGYsIDB4MmEsIDB4NzMsIDB4ZjcsIDB4OGMsIDB4NTYsIDB4NTEsIDB4YzYsIDB4ZWYsIDB4NGUsIDB4OWUsIDB4NjcsCisgIDB4MWMsIDB4NjEsIDB4YjAsIDB4YTgsIDB4YjIsIDB4OTUsIDB4ZmYsIDB4MDAsIDB4ZDQsIDB4MzEsIDB4ZDEsIDB4MmIsCisgIDB4ZGYsIDB4ZTksIDB4MGUsIDB4NTUsIDB4OGYsIDB4ZDIsIDB4ZjAsIDB4YTUsIDB4NTgsIDB4YjcsIDB4ODksIDB4ZDAsCisgIDB4ZWYsIDB4MjgsIDB4YzcsIDB4YjIsIDB4YWIsIDB4N2EsIDB4MmQsIDB4MTcsIDB4ODUsIDB4ODIsIDB4NjMsIDB4OTQsCisgIDB4YjgsIDB4NTcsIDB4MTYsIDB4NzgsIDB4MWQsIDB4ZWEsIDB4OGUsIDB4ZTEsIDB4MWQsIDB4NzQsIDB4M2EsIDB4OTQsCisgIDB4MTEsIDB4Y2MsIDB4OTEsIDB4ZTksIDB4MWUsIDB4NzUsIDB4NzcsIDB4ZDIsIDB4YWQsIDB4NGUsIDB4YTYsIDB4Y2QsCisgIDB4MjQsIDB4Y2UsIDB4MGEsIDB4YjQsIDB4NmEsIDB4NTMsIDB4ZGQsIDB4MzYsIDB4ZDEsIDB4YzMsIDB4ZjgsIDB4YmIsCisgIDB4YzEsIDB4YmYsIDB4YjIsIDB4ZDYsIDB4Y2YsIDB4ZGQsIDB4NTEsIDB4ZjgsIDB4YmIsIDB4YzEsIDB4YmYsIDB4YjIsCisgIDB4ZDYsIDB4Y2YsIDB4ZGQsIDB4NTMsIDB4NDgsIDB4ZWUsIDB4YTIsIDB4YmEsIDB4NzQsIDB4NDcsIDB4YzgsIDB4ZTcsCisgIDB4ZDcsIDB4MmYsIDB4MzEsIDB4MGUsIDB4ZjEsIDB4ODgsIDB4ZTMsIDB4MzYsIDB4NGIsIDB4YzYsIDB4MmQsIDB4M2EsCisgIDB4ZDEsIDB4NjUsIDB4ODcsIDB4MDYsIDB4NTAsIDB4YzksIDB4MmQsIDB4ZTgsIDB4ZWQsIDB4NTksIDB4NDcsIDB4MmEsCisgIDB4YjksIDB4NGIsIDB4YTAsIDB4MTEsIDB4YmYsIDB4NDEsIDB4MTUsIDB4ZjQsIDB4NjAsIDB4ZWUsIDB4YWEsIDB4M2YsCisgIDB4MzMsIDB4ZjgsIDB4ZDYsIDB4MmQsIDB4ZmIsIDB4NGYsIDB4NmUsIDB4ZmIsIDB4ZTEsIDB4NTcsIDB4ODAsIDB4ZWUsCisgIDB4YWYsIDB4MzYsIDB4ZWQsIDB4MjUsIDB4NTMsIDB4NjMsIDB4ZDIsIDB4YjUsIDB4NmQsIDB4YzMsIDB4NzMsIDB4MDQsCisgIDB4NmMsIDB4ZjcsIDB4ZDEsIDB4NTksIDB4YTIsIDB4YjksIDB4NGUsIDB4OTAsIDB4YTQsIDB4ZGUsIDB4MzksIDB4N2MsCisgIDB4OGUsIDB4ZTUsIDB4ZGYsIDB4NDMsIDB4YzksIDB4ZmIsIDB4YjMsIDB4NGUsIDB4NTQsIDB4OWIsIDB4YzcsIDB4MmYsCisgIDB4OTEsIDB4ZGMsIDB4YmIsIDB4ZTgsIDB4NzksIDB4M2YsIDB4NzYsIDB4NjgsIDB4MDUsIDB4ZTYsIDB4M2YsIDB4MjIsCisgIDB4ZGYsIDB4Y2QsIDB4MWYsIDB4NjUsIDB4NjgsIDB4YmIsIDB4ZGMsIDB4NjEsIDB4NWEsIDB4MmQsIDB4OTIsIDB4MmUsCisgIDB4NTcsIDB4MjksIDB4MDgsIDB4OGYsIDB4MTIsIDB4M2EsIDB4MzksIDB4ZGQsIDB4NzEsIDB4NWIsIDB4ZDAsIDB4MWUsCisgIDB4YWYsIDB4NDksIDB4MjcsIDB4NDAsIDB4MDEsIDB4ZDQsIDB4OTIsIDB4MDUsIDB4NzQsIDB4MzEsIDB4ZjksIDB4MjYsCisgIDB4YzcsIDB4YTUsIDB4MjAsIDB4MGUsIDB4OWUsIDB4YWEsIDB4ZTAsIDB4ZTEsIDB4ZWQsIDB4YTEsIDB4MTksIDB4YmUsCisgIDB4NDIsIDB4OGMsIDB4YmEsIDB4N2EsIDB4NzksIDB4ZjEsIDB4ZmIsIDB4NWMsIDB4ODUsIDB4MjYsIDB4YzYsIDB4YzIsCisgIDB4YmUsIDB4MGMsIDB4OTksIDB4MDgsIDB4M2MsIDB4YWIsIDB4OTgsIDB4YTEsIDB4ZTIsIDB4MTIsIDB4YTAsIDB4NTIsCisgIDB4ZDgsIDB4M2QsIDB4M2EsIDB4MTUsIDB4ZjcsIDB4OTQsIDB4OTEsIDB4ZWMsIDB4ZDYsIDB4YWEsIDB4YTksIDB4NDcsCisgIDB4MjcsIDB4OGYsIDB4NDYsIDB4OTMsIDB4YTksIDB4MmMsIDB4MWQsIDB4MTgsIDB4OGUsIDB4MTcsIDB4MzMsIDB4MjksCisgIDB4OTcsIDB4MWYsIDB4MjIsIDB4Y2QsIDB4YTEsIDB4YWUsIDB4M2MsIDB4MjYsIDB4NWMsIDB4NGIsIDB4ZDYsIDB4Y2IsCisgIDB4MGIsIDB4YTMsIDB4YTMsIDB4NjQsIDB4MWQsIDB4YTUsIDB4ZjksIDB4NDMsIDB4YjksIDB4NGUsIDB4ZjgsIDB4ODYsCisgIDB4ZmEsIDB4YTUsIDB4YmYsIDB4NWEsIDB4YjYsIDB4NDUsIDB4YjAsIDB4MDcsIDB4NGEsIDB4MDAsIDB4MWEsIDB4ZTksCisgIDB4ZmUsIDB4MTUsIDB4OWEsIDB4ZjIsIDB4MjUsIDB4MjcsIDB4MzcsIDB4OTYsIDB4N2EsIDB4ZDEsIDB4ODIsIDB4OGEsCisgIDB4YzIsIDB4MGEsIDB4MmIsIDB4OTIsIDB4ZWUsIDB4ZmMsIDB4YTgsIDB4ZDAsIDB4MWMsIDB4N2EsIDB4MWMsIDB4NmYsCisgIDB4MjksIDB4NzksIDB4MjMsIDB4Y2QsIDB4NmYsIDB4N2EsIDB4ZGQsIDB4NzEsIDB4ZTMsIDB4ZjcsIDB4ZjgsIDB4NzcsCisgIDB4NjQsIDB4NzIsIDB4MDIsIDB4NTksIDB4OTIsIDB4OWUsIDB4OGUsIDB4MzIsIDB4YmUsIDB4OGEsIDB4MDcsIDB4ZmUsCisgIDB4ZjUsIDB4Y2QsIDB4MmIsIDB4OWEsIDB4NzEsIDB4YWEsIDB4YTksIDB4NDksIDB4ZTEsIDB4YmUsIDB4M2QsIDB4NDksCisgIDB4Y2YsIDB4NDIsIDB4NWUsIDB4OGEsIDB4ZDcsIDB4MjUsIDB4ZjYsIDB4NjMsIDB4MzAsIDB4YTcsIDB4OWYsIDB4NzEsCisgIDB4MmQsIDB4YjYsIDB4OTEsIDB4YjIsIDB4YTUsIDB4MWQsIDB4MGEsIDB4YWUsIDB4YjIsIDB4OGMsIDB4ZTksIDB4ZjcsCisgIDB4ZDQsIDB4YjgsIDB4ZDYsIDB4OGYsIDB4N2EsIDB4NmIsIDB4YjgsIDB4YmMsIDB4N2UsIDB4MTIsIDB4YmQsIDB4OWUsCisgIDB4OGEsIDB4ZTYsIDB4YmYsIDB4ZWQsIDB4M2EsIDB4MTYsIDB4MzAsIDB4ZDUsIDB4NTUsIDB4ZWYsIDB4ZDEsIDB4NzUsCisgIDB4NjQsIDB4NGEsIDB4NDksIDB4NzIsIDB4M2UsIDB4NWMsIDB4YWUsIDB4ZDYsIDB4ZGIsIDB4NzIsIDB4NzksIDB4YTYsCisgIDB4Y2MsIDB4NjksIDB4OWYsIDB4NTEsIDB4M2QsIDB4N2YsIDB4YjgsIDB4NzUsIDB4YTUsIDB4YzksIDB4OWMsIDB4NDAsCisgIDB4YjQsIDB4YjQsIDB4NDgsIDB4NjEsIDB4OTcsIDB4ZGYsIDB4ZjUsIDB4ZWIsIDB4NDIsIDB4YWIsIDB4MTcsIDB4OWQsCisgIDB4NzUsIDB4ZTcsIDB4MGIsIDB4OGYsIDB4MzgsIDB4YTcsIDB4MTYsIDB4N2IsIDB4ZDQsIDB4YTMsIDB4YjMsIDB4NWUsCisgIDB4MmIsIDB4ZTMsIDB4YWUsIDB4N2QsIDB4YWIsIDB4YjksIDB4OWIsIDB4ZmUsIDB4ZDQsIDB4NTQsIDB4NTcsIDB4ZTYsCisgIDB4ZmYsIDB4MDAsIDB4ZGYsIDB4OTEsIDB4OTMsIDB4YWEsIDB4ZmEsIDB4MGQsIDB4ZWYsIDB4NjYsIDB4MGMsIDB4YjksCisgIDB4OTMsIDB4YjUsIDB4NzcsIDB4MzAsIDB4OTcsIDB4YzgsIDB4ZGIsIDB4MjUsIDB4YjAsIDB4OGUsIDB4NzEsIDB4YmUsCisgIDB4YmUsIDB4MzQsIDB4YzcsIDB4MGYsIDB4ODgsIDB4MTYsIDB4ODcsIDB4NTQsIDB4MDMsIDB4ZWQsIDB4M2UsIDB4YzYsCisgIDB4ZmMsIDB4NDgsIDB4ZDgsIDB4ZmYsIDB4MDAsIDB4MGEsIDB4YWIsIDB4NDAsIDB4MjQsIDB4ODAsIDB4MDEsIDB4MjQsCisgIDB4ZjcsIDB4MDEsIDB4NWQsIDB4NzMsIDB4NmQsIDB4OTcsIDB4MDgsIDB4NGQsIDB4MjEsIDB4ZDksIDB4NTEsIDB4MWQsCisgIDB4NjUsIDB4MGIsIDB4ZjgsIDB4MmEsIDB4NTIsIDB4N2EsIDB4MWEsIDB4ZTMsIDB4YjYsIDB4ZWQsIDB4Y2IsIDB4ZmEsCisgIDB4NWEsIDB4YTcsIDB4MWQsIDB4ZDMsIDB4NzksIDB4N2IsIDB4MTAsIDB4YTcsIDB4MjIsIDB4ZWEsIDB4YjcsIDB4NWQsCisgIDB4MjAsIDB4NWMsIDB4NTEsIDB4Y2YsIDB4MGUsIDB4NTMsIDB4NmUsIDB4OGYsIDB4NDAsIDB4M2QsIDB4NDcsIDB4ZDUsCisgIDB4NWQsIDB4OTUsIDB4NDEsIDB4NDYsIDB4OTAsIDB4ZmMsIDB4NjcsIDB4NDMsIDB4YjEsIDB4ZGQsIDB4NWIsIDB4NGIsCisgIDB4MWQsIDB4Y2EsIDB4NDksIDB4ZDEsIDB4YWIsIDB4MDcsIDB4MTAsIDB4Y2QsIDB4YmIsIDB4NjUsIDB4YTIsIDB4MTUsCisgIDB4ZGQsIDB4NDEsIDB4MmIsIDB4M2QsIDB4MTAsIDB4ZjcsIDB4NzAsIDB4M2UsIDB4ZGEsIDB4ZmEsIDB4NWUsIDB4Y2QsCisgIDB4ZjYsIDB4OWEsIDB4OTUsIDB4YzQsIDB4OTUsIDB4M2EsIDB4ZWIsIDB4NGIsIDB4N2QsIDB4N2EsIDB4N2YsIDB4ODMsCisgIDB4NDgsIDB4ZDQsIDB4NGYsIDB4OTEsIDB4ZjIsIDB4OGEsIDB4MDEsIDB4MDQsIDB4NmMsIDB4MWQsIDB4ODMsIDB4NDUsCisgIDB4N2QsIDB4NDEsIDB4YTAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDYsIDB4MGEsIDB4NDEsIDB4M2IsIDB4YTgsIDB4N2MsCisgIDB4YmYsIDB4MWIsIDB4YjMsIDB4ZTUsIDB4NTYsIDB4NDcsIDB4YWMsIDB4ZjcsIDB4YTgsIDB4YmUsIDB4NTEsIDB4MTksCisgIDB4YzUsIDB4MDUsIDB4YTQsIDB4YTQsIDB4ZjIsIDB4YWQsIDB4YTcsIDB4MTMsIDB4ZDUsIDB4MmUsIDB4MjEsIDB4NDMsCisgIDB4YWEsIDB4MTYsIDB4OTMsIDB4ZDQsIDB4MjgsIDB4NzUsIDB4MTUsIDB4MzMsIDB4NDYsIDB4YTgsIDB4MGEsIDB4NDUsCisgIDB4MmUsIDB4NWQsIDB4NzEsIDB4NWIsIDB4ZjMsIDB4NTgsIDB4YWUsIDB4NTEsIDB4MjQsIDB4NGEsIDB4MzIsIDB4MzYsCisgIDB4MmMsIDB4ZjcsIDB4NTIsIDB4OWUsIDB4NDEsIDB4MzgsIDB4MjQsIDB4NmMsIDB4YjQsIDB4ZTAsIDB4ZWUsIDB4NGIsCisgIDB4ZTksIDB4MDMsIDB4NjcsIDB4NWQsIDB4MTYsIDB4M2MsIDB4ZTEsIDB4YWUsIDB4YTIsIDB4YTcsIDB4YTksIDB4ZGIsCisgIDB4MzMsIDB4YzYsIDB4ZWQsIDB4OTksIDB4NTYsIDB4M2YsIDB4MmEsIDB4Y2IsIDB4NzQsIDB4NmQsIDB4NjUsIDB4ODcsCisgIDB4ODAsIDB4MjgsIDB4NzEsIDB4YjUsIDB4NzIsIDB4YmEsIDB4Y2IsIDB4ODksIDB4ZWEsIDB4ODcsIDB4MWIsIDB4NTAsCisgIDB4ZWEsIDB4OTUsIDB4YTQsIDB4ODAsIDB4YTAsIDB4N2QsIDB4MzUsIDB4NTcsIDB4ZTMsIDB4MTMsIDB4MmUsIDB4M2QsCisgIDB4YTQsIDB4ZWIsIDB4MDUsIDB4ZmIsIDB4OTMsIDB4ZGQsIDB4Y2IsIDB4M2IsIDB4ODEsIDB4ODksIDB4NmEsIDB4NDIsCisgIDB4NDIsIDB4NTMsIDB4MjEsIDB4MjQsIDB4NzMsIDB4MzUsIDB4MjEsIDB4MDAsIDB4NzcsIDB4MjUsIDB4YzQsIDB4ZWMsCisgIDB4ZWIsIDB4YzEsIDB4NDEsIDB4NDMsIDB4YzMsIDB4NTUsIDB4ZTksIDB4NWEsIDB4ZDcsIDB4ZDUsIDB4ZGQsIDB4OTcsCisgIDB4MjcsIDB4OWIsIDB4NzMsIDB4NDMsIDB4NGYsIDB4N2EsIDB4M2MsIDB4MWEsIDB4NzMsIDB4M2YsIDB4OGQsIDB4NjIsCisgIDB4ZGYsIDB4YjQsIDB4ZjYsIDB4ZWYsIDB4YmUsIDB4MTUsIDB4NzgsIDB4MGUsIDB4ZWEsIDB4YTMsIDB4YjMsIDB4M2YsCisgIDB4OGQsIDB4NjIsIDB4ZGYsIDB4YjQsIDB4ZjYsIDB4ZGYsIDB4YmUsIDB4MTUsIDB4NzgsIDB4OGUsIDB4ZWEsIDB4ZTcsCisgIDB4YmMsIDB4ZmIsIDB4Y2YsIDB4OTEsIDB4ZDEsIDB4NjksIDB4ZjcsIDB4NjEsIDB4NDUsIDB4MTQsIDB4NTcsIDB4MjksCisgIDB4ZDQsIDB4MTQsIDB4OWIsIDB4YzcsIDB4MmYsIDB4OTEsIDB4ZGMsIDB4YmIsIDB4ZTgsIDB4NzksIDB4M2YsIDB4NzYsCisgIDB4NjksIDB4Y2EsIDB4OTMsIDB4MzgsIDB4ZTQsIDB4N2YsIDB4ZjksIDB4M2QsIDB4OTcsIDB4NzQsIDB4ZGYsIDB4ZmEsCisgIDB4MjIsIDB4NGYsIDB4ZGQsIDB4OWEsIDB4MDEsIDB4MDMsIDB4MjgsIDB4MTIsIDB4YWUsIDB4NDksIDB4YjUsIDB4NjIsCisgIDB4NTYsIDB4ZDcsIDB4OTYsIDB4Y2MsIDB4ZGIsIDB4ZmIsIDB4YmUsIDB4NGMsIDB4YTcsIDB4NTAsIDB4NzQsIDB4YTYsCisgIDB4MjIsIDB4YTUsIDB4MWMsIDB4ZDIsIDB4MWQsIDB4MWUsIDB4ODIsIDB4MTAsIDB4MzksIDB4NDcsIDB4ZWIsIDB4MmQsCisgIDB4MzUsIDB4NzQsIDB4NWEsIDB4YTAsIDB4NDQsIDB4YjYsIDB4NWIsIDB4MjMsIDB4NWIsIDB4NjAsIDB4MzAsIDB4ODgsCisgIDB4ZjEsIDB4MjIsIDB4YjQsIDB4OTYsIDB4NTgsIDB4NjksIDB4MDMsIDB4Y2QsIDB4NDIsIDB4MTIsIDB4MzQsIDB4OTAsCisgIDB4M2QsIDB4ODAsIDB4MGEsIDB4YWMsIDB4NzgsIDB4NTEsIDB4MTAsIDB4ZGMsIDB4ZjgsIDB4ODcsIDB4OTAsIDB4ZGYsCisgIDB4MWQsIDB4NGYsIDB4MzMsIDB4NTYsIDB4OTgsIDB4YWMsIDB4NTksIDB4ZTIsIDB4MWQsIDB4ZjQsIDB4MGIsIDB4NTIsCisgIDB4NDMsIDB4ZjIsIDB4MGUsIDB4YmQsIDB4MjcsIDB4OTksIDB4ODEsIDB4YmYsIDB4ZDQsIDB4YWIsIDB4NjAsIDB4NTYsCisgIDB4ZjcsIDB4MzUsIDB4MzUsIDB4Y2QsIDB4ZmEsIDB4MTgsIDB4NWIsIDB4NDMsIDB4NDQsIDB4MTcsIDB4YTgsIDB4MDEsCisgIDB4YTEsIDB4YWEsIDB4MjgsIDB4YTIsIDB4YjAsIDB4MzcsIDB4MGEsIDB4ODEsIDB4YzgsIDB4ZjEsIDB4ZjgsIDB4YjMsCisgIDB4NDEsIDB4OWEsIDB4YzMsIDB4OWUsIDB4NDcsIDB4MzEsIDB4YTEsIDB4Y2MsIDB4OTcsIDB4ZDEsIDB4ZDMsIDB4YmIsCisgIDB4ZDMsIDB4NTMsIDB4ZDQsIDB4OWQsIDB4YzQsIDB4ZmIsIDB4YjksIDB4ODcsIDB4NmQsIDB4NGQsIDB4YmQsIDB4OTUsCisgIDB4NjksIDB4ZDksIDB4M2YsIDB4MGIsIDB4ZDQsIDB4OGEsIDB4ZjMsIDB4ZmIsIDB4NTIsIDB4NzQsIDB4NjksIDB4ZGEsCisgIDB4Y2EsIDB4NzUsIDB4OTYsIDB4NTIsIDB4ZmEsIDB4ZjQsIDB4YzEsIDB4NTksIDB4NjMsIDB4MWIsIDB4ODksIDB4NTksCisgIDB4MDYsIDB4NDUsIDB4NzMsIDB4YjksIDB4YjQsIDB4ODgsIDB4NzIsIDB4NWYsIDB4NGEsIDB4OWIsIDB4NmIsIDB4Y2QsCisgIDB4MjUsIDB4MWQsIDB4MDMsIDB4ODQsIDB4NzgsIDB4OWEsIDB4ODQsIDB4YWQsIDB4OTEsIDB4NjMsIDB4YmQsIDB4MjksCisgIDB4ZjQsIDB4YjMsIDB4MWQsIDB4YTUsIDB4MzgsIDB4ZTIsIDB4YmIsIDB4OTIsIDB4OTEsIDB4ZDQsIDB4ZDcsIDB4YjksCisgIDB4ZDAsIDB4YTUsIDB4NDEsIDB4N2IsIDB4YjEsIDB4OTYsIDB4YzIsIDB4ZDksIDB4NWUsIDB4YjcsIDB4YTUsIDB4MGQsCisgIDB4NTcsIDB4ZTUsIDB4ZDUsIDB4YWEsIDB4NTYsIDB4YjgsIDB4NmUsIDB4YWQsIDB4NGMsIDB4YmUsIDB4OTksIDB4ZmQsCisgIDB4YjIsIDB4NzMsIDB4YmMsIDB4YmQsIDB4Y2QsIDB4MTQsIDB4NTEsIDB4NDUsIDB4NzMsIDB4MTAsIDB4NzQsIDB4NWIsCisgIDB4MjQsIDB4MDgsIDB4OTcsIDB4MDYsIDB4MjQsIDB4YTksIDB4MWMsIDB4ZTEsIDB4YTUsIDB4ODUsIDB4MTQsIDB4ZmEsCisgIDB4NzUsIDB4NGUsIDB4MTksIDB4OWUsIDB4NTksIDB4NmYsIDB4YmEsIDB4ZDksIDB4ODQsIDB4MzgsIDB4OGQsIDB4MmMsCisgIDB4YWQsIDB4NmEsIDB4MDUsIDB4NDUsIDB4NjksIDB4ZDcsIDB4MmUsIDB4YTksIDB4MWUsIDB4OGEsIDB4ZWUsIDB4YjcsCisgIDB4ZWQsIDB4MGEsIDB4ZDYsIDB4ZjQsIDB4NjcsIDB4NDYsIDB4MWMsIDB4NGIsIDB4OTIsIDB4NTQsIDB4OWEsIDB4NTgsCisgIDB4MGEsIDB4MjgsIDB4NDgsIDB4MmEsIDB4M2EsIDB4MDAsIDB4OTIsIDB4N2MsIDB4MDUsIDB4MzAsIDB4NTksIDB4YjEsCisgIDB4M2IsIDB4OWMsIDB4ZjQsIDB4ODcsIDB4NWQsIDB4NDgsIDB4OGIsIDB4MWYsIDB4YmMsIDB4YjgsIDB4ZWYsIDB4NGUsCisgIDB4OWUsIDB4Y2EsIDB4YzIsIDB4ODUsIDB4YjUsIDB4NWIsIDB4ODksIDB4NjksIDB4YTUsIDB4MTYsIDB4ZDgsIDB4NDksCisgIDB4YmUsIDB4MDYsIDB4YWUsIDB4MWEsIDB4ZTQsIDB4MGEsIDB4OTYsIDB4ZDEsIDB4YjUsIDB4NGIsIDB4NWUsIDB4ZGQsCisgIDB4NmMsIDB4NmQsIDB4YTUsIDB4MWUsIDB4ZjUsIDB4MjcsIDB4ZDEsIDB4ZWQsIDB4YTcsIDB4NDcsIDB4ZGQsIDB4NmQsCisgIDB4ODYsIDB4NTYsIDB4ZjMsIDB4Y2IsIDB4NGEsIDB4MWIsIDB4NDAsIDB4ZGEsIDB4OTQsIDB4NGUsIDB4ODAsIDB4MTUsCisgIDB4NWQsIDB4YzcsIDB4OTMsIDB4OGMsIDB4ZTMsIDB4MGUsIDB4ODUsIDB4YjAsIDB4YTUsIDB4Y2YsIDB4OWEsIDB4OWUsCisgIDB4OWMsIDB4ZTAsIDB4ZjQsIDB4NGQsIDB4NGEsIDB4NzEsIDB4MTYsIDB4ZTAsIDB4NWYsIDB4YzQsIDB4YTMsIDB4YmYsCisgIDB4MTUsIDB4NWUsIDB4ZjMsIDB4MjUsIDB4NjksIDB4ZTYsIDB4MjMsIDB4ZDEsIDB4YTIsIDB4NzUsIDB4ZmYsIDB4MDAsCisgIDB4YmYsIDB4NDUsIDB4N2QsIDB4ZjUsIDB4OGYsIDB4NjgsIDB4M2IsIDB4NmIsIDB4MjksIDB4NDYsIDB4YWMsIDB4OTQsCisgIDB4YTcsIDB4NGQsIDB4NzAsIDB4OWUsIDB4NzYsIDB4ZTksIDB4OTYsIDB4NmQsIDB4MTksIDB4NjEsIDB4NmUsIDB4NzgsCisgIDB4OWYsIDB4YzQsIDB4MzgsIDB4NGQsIDB4M2UsIDB4NWIsIDB4OGIsIDB4MGQsIDB4YzcsIDB4ZDAsIDB4MGYsIDB4YzMsCisgIDB4MmEsIDB4ZTUsIDB4MDcsIDB4ZDgsIDB4MmEsIDB4NmYsIDB4MWEsIDB4YzksIDB4NjAsIDB4NWYsIDB4MDEsIDB4NDMsCisgIDB4MDQsIDB4YjYsIDB4ZmEsIDB4NDYsIDB4ZDQsIDB4ZDIsIDB4ZmIsIDB4ZjUsIDB4ZTksIDB4MWUsIDB4OWEsIDB4YTYsCisgIDB4NmIsIDB4YjIsIDB4Y2IsIDB4M2QsIDB4Y2IsIDB4NjUsIDB4ZDEsIDB4ODksIDB4YWQsIDB4MTMsIDB4YjYsIDB4ZDUsCisgIDB4YjIsIDB4MDcsIDB4ODgsIDB4ZjEsIDB4MWYsIDB4ZGQsIDB4NWUsIDB4MGQsIDB4YWYsIDB4YjQsIDB4ZjcsIDB4NGEsCisgIDB4YmEsIDB4NzUsIDB4OWEsIDB4NzEsIDB4N2MsIDB4YWMsIDB4NzEsIDB4ZjAsIDB4MjgsIDB4YWEsIDB4M2MsIDB4ZWUsCisgIDB4NWUsIDB4YjQsIDB4NTYsIDB4YTgsIDB4OGYsIDB4YjcsIDB4MmEsIDB4MmIsIDB4NTIsIDB4MWEsIDB4NTAsIDB4NTMsCisgIDB4NmUsIDB4MjQsIDB4MjksIDB4MjQsIDB4NzgsIDB4ODMsIDB4NWIsIDB4NmIsIDB4ZjQsIDB4MjQsIDB4ZDQsIDB4OTYsCisgIDB4NTEsIDB4YjgsIDB4NmIsIDB4YWUsIDB4ZWEsIDB4YWUsIDB4ZTMsIDB4NWMsIDB4MWYsIDB4NzIsIDB4MmUsIDB4MTYsCisgIDB4OWMsIDB4ZmEsIDB4MzgsIDB4ZTUsIDB4NGMsIDB4MjUsIDB4YTYsIDB4MDUsIDB4ZGYsIDB4NDcsIDB4NDEsIDB4NzAsCisgIDB4OWUsIDB4NTgsIDB4MDEsIDB4NDcsIDB4ZmQsIDB4ZDMsIDB4YTUsIDB4MGIsIDB4MWUsIDB4ODAsIDB4NTcsIDB4ZTksCisgIDB4YWIsIDB4NDYsIDB4YTMsIDB4YjIsIDB4NWIsIDB4NGMsIDB4NWIsIDB4ZjUsIDB4ODIsIDB4ZTEsIDB4NjQsIDB4OWEsCisgIDB4OWUsIDB4NjgsIDB4ZDMsIDB4ZTMsIDB4MzksIDB4MTksIDB4ZGYsIDB4OWEsIDB4YjQsIDB4OTQsIDB4OWQsIDB4N2EsCisgIDB4ZmEsIDB4ZDUsIDB4ZTMsIDB4MmQsIDB4MmQsIDB4MzQsIDB4NTYsIDB4NTEsIDB4NTIsIDB4NGQsIDB4MzIsIDB4YTAsCisgIDB4Y2MsIDB4YzEsIDB4MTIsIDB4YjEsIDB4NjAsIDB4N2IsIDB4YzYsIDB4NGYsIDB4NmUsIDB4ZmIsIDB4ZTEsIDB4NTcsCisgIDB4ODAsIDB4ZWUsIDB4YWYsIDB4OWIsIDB4YWQsIDB4ZDMsIDB4YTQsIDB4Y2YsIDB4YzUsIDB4NzAsIDB4NTcsIDB4MjcsCisgIDB4MTIsIDB4NjcsIDB4MzEsIDB4OTIsIDB4NWIsIDB4ZTIsIDB4NGIsIDB4ZGYsIDB4N2YsIDB4NmUsIDB4Y2MsIDB4OGUsCisgIDB4YzksIDB4Y2QsIDB4ZmEsIDB4Y2EsIDB4OTAsIDB4NGYsIDB4ZDcsIDB4NWYsIDB4NDgsIDB4OGUsIDB4ZWEsIDB4ZGUsCisgIDB4ZWQsIDB4ZWEsIDB4OWEsIDB4N2UsIDB4ODYsIDB4MTYsIDB4YWIsIDB4NGMsIDB4MWEsIDB4ZjUsIDB4MGEsIDB4MjgsCisgIDB4YTIsIDB4YjksIDB4OGUsIDB4OTAsIDB4YTQsIDB4ZGUsIDB4MzcsIDB4OGQsIDB4ZjAsIDB4N2YsIDB4MmUsIDB4MWIsCisgIDB4ZDcsIDB4ZmEsIDB4MjIsIDB4NDcsIDB4ZGQsIDB4OWEsIDB4NzIsIDB4YTQsIDB4ZWUsIDB4MzcsIDB4NzQsIDB4ZTEsCisgIDB4MDYsIDB4NWMsIDB4N2QsIDB4MTYsIDB4ODksIDB4MWYsIDB4NzYsIDB4NjgsIDB4MDgsIDB4OGYsIDB4YzEsIDB4Y2QsCisgIDB4MjEsIDB4ZWUsIDB4MWIsIDB4MGIsIDB4YzcsIDB4NGUsIDB4ZDIsIDB4ZWYsIDB4NzMsIDB4OWIsIDB4MzUsIDB4NjQsCisgIDB4N2EsIDB4ZTQsIDB4MmQsIDB4MDksIDB4ZmYsIDB4MDAsIDB4YTEsIDB4MDgsIDB4MTUsIDB4NjQsIDB4NTUsIDB4N2IsCisgIDB4ZjgsIDB4MzcsIDB4YTUsIDB4MjMsIDB4ODEsIDB4YjgsIDB4OTgsIDB4MWUsIDB4MzAsIDB4NDIsIDB4OGYsIDB4YjQsCisgIDB4YWQsIDB4NDQsIDB4ZmYsIDB4MDAsIDB4ODksIDB4MzUsIDB4NjEsIDB4NTEsIDB4ZWUsIDB4ZjIsIDB4NDIsIDB4ZDgsCisgIDB4MjgsIDB4YTIsIDB4OGEsIDB4MTIsIDB4MTUsIDB4NGUsIDB4ZjEsIDB4MDIsIDB4NjIsIDB4YTUsIDB4ZTQsIDB4ZjIsCisgIDB4N2MsIDB4ZTIsIDB4NTIsIDB4YzksIDB4ZWMsIDB4ZDIsIDB4M2QsIDB4MWEsIDB4YWIsIDB4ODgsIDB4ZjcsIDB4NTUsCisgIDB4MTcsIDB4N2UsIDB4MjUsIDB4NTcsIDB4YTksIDB4YTQsIDB4ZjcsIDB4ZjYsIDB4ZWEsIDB4ZmIsIDB4NmIsIDB4ZTQsCisgIDB4ZmQsIDB4YWQsIDB4YTgsIDB4ZTMsIDB4NmYsIDB4MDgsIDB4MmUsIDB4YWYsIDB4ZTgsIDB4OGMsIDB4YWEsIDB4ZjAsCisgIDB4NzYsIDB4ZTEsIDB4OTcsIDB4NzYsIDB4NmMsIDB4ZDcsIDB4OTQsIDB4Y2EsIDB4OTAsIDB4ZDksIDB4NWIsIDB4NjUsCisgIDB4MjUsIDB4MjcsIDB4OTcsIDB4YmMsIDB4NmYsIDB4YzYsIDB4YmIsIDB4MzMsIDB4ZGIsIDB4ZjQsIDB4NWIsIDB4ZGMsCisgIDB4OTYsIDB4M2MsIDB4OTEsIDB4YjUsIDB4MDQsIDB4MzQsIDB4MGYsIDB4OWUsIDB4YTEsIDB4YTIsIDB4NzcsIDB4NGIsCisgIDB4MzQsIDB4NTcsIDB4YzcsIDB4YzcsIDB4YjQsIDB4MmIsIDB4NDYsIDB4ZDUsIDB4ZGEsIDB4YWYsIDB4MGIsIDB4NzksCisgIDB4MzIsIDB4ZDQsIDB4ZjEsIDB4ODAsIDB4YTIsIDB4YmQsIDB4YjIsIDB4ZDMsIDB4YWYsIDB4MzgsIDB4MWIsIDB4NjUsCisgIDB4YjUsIDB4MzgsIDB4YjMsIDB4ZGMsIDB4MTIsIDB4MzYsIDB4NjksIDB4OWEsIDB4ZDksIDB4ODcsIDB4NDgsIDB4NTMsCisgIDB4NDIsIDB4NGQsIDB4ZDksIDB4ZjQsIDB4NDEsIDB4OGUsIDB4M2EsIDB4OWUsIDB4NjMsIDB4ZTcsIDB4MWEsIDB4Y2UsCisgIDB4ZGEsIDB4Y2UsIDB4YjUsIDB4Y2IsIDB4YzUsIDB4MjgsIDB4ZTcsIDB4ZTksIDB4ZjMsIDB4NjEsIDB4MjYsIDB4YzUsCisgIDB4NzQsIDB4MjEsIDB4NmUsIDB4MjgsIDB4MjUsIDB4MDksIDB4MmEsIDB4NTEsIDB4ZWUsIDB4MDAsIDB4NmUsIDB4OTksCisgIDB4MmQsIDB4MTgsIDB4N2MsIDB4ZjksIDB4MmQsIDB4ODksIDB4MTMsIDB4NTQsIDB4OTgsIDB4NTEsIDB4ZmIsIDB4Y2EsCisgIDB4OWMsIDB4M2EsIDB4M2EsIDB4ZjYsIDB4NTQsIDB4ODMsIDB4OTcsIDB4Y2IsIDB4MDUsIDB4ODksIDB4MDUsIDB4YWIsCisgIDB4MmMsIDB4MzEsIDB4MjUsIDB4ZjEsIDB4ZDAsIDB4YmUsIDB4ZTAsIDB4ZTksIDB4NGIsIDB4NzcsIDB4N2IsIDB4ZGQsCisgIDB4Y2EsIDB4ZTgsIDB4ZTEsIDB4NTQsIDB4YjksIDB4MmIsIDB4NTIsIDB4N2MsIDB4MTAsIDB4MGUsIDB4OTIsIDB4M2UsCisgIDB4YWEsIDB4ZWQsIDB4ZjcsIDB4MzYsIDB4NzYsIDB4YmYsIDB4N2IsIDB4MmYsIDB4NzksIDB4MmYsIDB4MjgsIDB4ZjEsCisgIDB4ZjMsIDB4N2QsIDB4N2UsIDB4NDQsIDB4ZTEsIDB4MjEsIDB4OTQsIDB4ZGMsIDB4NzEsIDB4OWMsIDB4NzgsIDB4NzIsCisgIDB4ZGIsIDB4ZDgsIDB4ZjcsIDB4NDIsIDB4NTgsIDB4ZmUsIDB4OTUsIDB4N2YsIDB4MDQsIDB4MWEsIDB4NWYsIDB4YmMsCisgIDB4ZTQsIDB4NTcsIDB4NGIsIDB4YTIsIDB4ODgsIDB4N2UsIDB4NDEsIDB4NDMsIDB4NWUsIDB4MGQsIDB4YTMsIDB4YTIsCisgIDB4NDUsIDB4NDQsIDB4ZDEsIDB4NTgsIDB4NTcsIDB4ZWQsIDB4MmEsIDB4ZDUsIDB4NjMsIDB4ZWUsIDB4ZTMsIDB4ZGQsCisgIDB4OGYsIDB4OTIsIDB4ZDksIDB4N2MsIDB4ZmMsIDB4ZmUsIDB4NjQsIDB4MzksIDB4MzYsIDB4MTQsIDB4ZWQsIDB4ODcsCisgIDB4MzgsIDB4OGIsIDB4ZDYsIDB4MzksIDB4MzcsIDB4MWQsIDB4N2QsIDB4NDMsIDB4YjQsIDB4NGEsIDB4N2IsIDB4NDgsCisgIDB4ZTQsIDB4ZjgsIDB4MWYsIDB4ZmYsIDB4MDAsIDB4ZGYsIDB4ZmIsIDB4ZDIsIDB4NGQsIDB4NzcsIDB4NTgsIDB4MmUsCisgIDB4MGUsIDB4NWIsIDB4MmUsIDB4Y2MsIDB4NGMsIDB4NmMsIDB4ZmMsIDB4MDUsIDB4NzksIDB4YzMsIDB4ZDIsIDB4M2MsCisgIDB4NDUsIDB4NTcsIDB4YjMsIDB4YWUsIDB4NTUsIDB4YmQsIDB4NzQsIDB4ZTcsIDB4ZTEsIDB4N2IsIDB4M2YsIDB4ODMsCisgIDB4ZTQsIDB4NDUsIDB4ZTEsIDB4OWMsIDB4NmUsIDB4YjYsIDB4YjYsIDB4OWQsIDB4NWIsIDB4NGUsIDB4MjQsIDB4YTUsCisgIDB4NjgsIDB4NTEsIDB4NGEsIDB4ODEsIDB4ZjAsIDB4MjMsIDB4YmMsIDB4NTcsIDB4OWEsIDB4NmEsIDB4ZTIsIDB4MzUsCisgIDB4YmQsIDB4YjYsIDB4YWUsIDB4MGQsIDB4NWQsIDB4NjIsIDB4ZjUsIDB4OGQsIDB4MzksIDB4MjEsIDB4N2IsIDB4MWUsCisgIDB4MGEsIDB4ZDcsIDB4ZmQsIDB4YzcsIDB4ZmQsIDB4ZTksIDB4NTYsIDB4YjIsIDB4YmMsIDB4YjYsIDB4NzYsIDB4ZDUsCisgIDB4YTUsIDB4NDksIDB4ZjQsIDB4ZmQsIDB4NTcsIDB4NDcsIDB4ZjksIDB4MDYsIDB4YjAsIDB4ZjAsIDB4NTksIDB4N2MsCisgIDB4MmIsIDB4YmIsIDB4NzYsIDB4ZjAsIDB4MWMsIDB4YjUsIDB4YmEsIDB4YWQsIDB4YWQsIDB4OGYsIDB4MzksIDB4YmQsCisgIDB4ZjgsIDB4YTQsIDB4ZmYsIDB4MDAsIDB4ZTAsIDB4ZmYsIDB4MDAsIDB4ZGEsIDB4OWQsIDB4YWEsIDB4OGUsIDB4YzcsCisgIDB4MmUsIDB4NGIsIDB4YjUsIDB4NWUsIDB4MTgsIDB4OTgsIDB4OTIsIDB4NzksIDB4NTIsIDB4YWQsIDB4MmMsIDB4N2EsCisgIDB4NTIsIDB4N2IsIDB4ZWEsIDB4ZWUsIDB4NjUsIDB4YzQsIDB4M2MsIDB4Y2EsIDB4MWQsIDB4NmMsIDB4ODUsIDB4MjEsCisgIDB4NjAsIDB4MTAsIDB4NDcsIDB4ODgsIDB4YWYsIDB4YmUsIDB4ZjYsIDB4NmEsIDB4ZmIsIDB4ZWQsIDB4MTYsIDB4YmUsCisgIDB4ZWEsIDB4NGYsIDB4YmQsIDB4MGQsIDB4YmUsIDB4NWQsIDB4M2YsIDB4ODMsIDB4NmEsIDB4NzIsIDB4Y2EsIDB4M2QsCisgIDB4ZDYsIDB4MDgsIDB4ZWIsIDB4NTksIDB4YTMsIDB4NTUsIDB4ZjQsIDB4NjYsIDB4ODcsIDB4Y2UsIDB4MzcsIDB4NTgsCisgIDB4YzIsIDB4ZGIsIDB4OWIsIDB4Y2YsIDB4YjUsIDB4MDUsIDB4ZjMsIDB4MDYsIDB4ZjgsIDB4OGIsIDB4NmYsIDB4OTYsCisgIDB4OWYsIDB4NTIsIDB4NjQsIDB4ODYsIDB4NWUsIDB4M2YsIDB4ZjUsIDB4MjksIDB4NzUsIDB4ZjQsIDB4NzAsIDB4ZWUsCisgIDB4YWYsIDB4OWUsIDB4MzMsIDB4NTEsIDB4YWUsIDB4MzMsIDB4ZGMsIDB4ZmYsIDB4MDAsIDB4NmEsIDB4NzEsIDB4ZDMsCisgIDB4ZjUsIDB4ZjIsIDB4MDEsIDB4ZmYsIDB4MDAsIDB4OGEsIDB4ZmEsIDB4MWMsIDB4NzcsIDB4NTYsIDB4OTMsIDB4NzksCisgIDB4YzcsIDB4YzAsIDB4Y2UsIDB4MWMsIDB4YmYsIDB4OGYsIDB4ZjAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4NjYsIDB4NjgsCisgIDB4MTQsIDB4OWIsIDB4YzYsIDB4ZjMsIDB4YWUsIDB4MTAsIDB4NjUsIDB4YTcsIDB4ZmYsIDB4MDAsIDB4NDgsIDB4OTEsCisgIDB4ZjcsIDB4NjYsIDB4OWMsIDB4YTksIDB4MzMsIDB4OGUsIDB4NWYsIDB4MjMsIDB4YjksIDB4NzcsIDB4ZDAsIDB4ZjIsCisgIDB4N2UsIDB4ZWMsIDB4ZDAsIDB4MTEsIDB4OWYsIDB4ODMsIDB4NzksIDB4MmQsIDB4ZjAsIDB4ODIsIDB4ZDUsIDB4MDUsCisgIDB4NjcsIDB4ZGYsIDB4NjAsIDB4M2YsIDB4MmUsIDB4MWIsIDB4YTAsIDB4ZjcsIDB4ODIsIDB4ZGMsIDB4OTcsIDB4NTMsCisgIDB4YWYsIDB4ZWUsIDB4MDMsIDB4ZmIsIDB4ZWEsIDB4YzYsIDB4YWEsIDB4YjcsIDB4ODIsIDB4YjIsIDB4YmMsIDB4ODcsCisgIDB4MjIsIDB4Y2IsIDB4MzEsIDB4YjcsIDB4MzQsIDB4OTIsIDB4NjQsIDB4YjUsIDB4NzgsIDB4OGYsIDB4YjMsIDB4ZjAsCisgIDB4OWIsIDB4OTAsIDB4ZDgsIDB4NGEsIDB4ZjQsIDB4M2QsIDB4MDEsIDB4ZDYsIDB4OWMsIDB4ZmYsIDB4MDAsIDB4OTgsCisgIDB4N2EsIDB4NmEsIDB4ZDIsIDB4MWQsIDB4ZDUsIDB4NjksIDB4YWQsIDB4MzIsIDB4NjgsIDB4YWMsIDB4MjUsIDB4YWEsCisgIDB4MjksIDB4ODUsIDB4MTQsIDB4NTEsIDB4NTUsIDB4MmMsIDB4MTUsIDB4NGEsIDB4ZTYsIDB4NzEsIDB4OGMsIDB4NGMsCisgIDB4OWEsIDB4NmIsIDB4NDQsIDB4MTAsIDB4MGIsIDB4OWMsIDB4YzMsIDB4ZDgsIDB4N2EsIDB4ZDUsIDB4ZDUsIDB4NGEsCisgIDB4ZDksIDB4OGQsIDB4ODYsIDB4ZDcsIDB4MjYsIDB4NGEsIDB4NmUsIDB4ZDcsIDB4MTcsIDB4ZDQsIDB4Y2IsIDB4NGQsCisgIDB4MjMsIDB4OTUsIDB4Y2UsIDB4NTEsIDB4ZjAsIDB4YmQsIDB4MTUsIDB4ZTAsIDB4ZmIsIDB4NDMsIDB4NjEsIDB4MmIsCisgIDB4Y2IsIDB4NjUsIDB4YTMsIDB4OTgsIDB4YmMsIDB4ZWYsIDB4YjYsIDB4ZGQsIDB4NGEsIDB4NGUsIDB4MzksIDB4NDUsCisgIDB4NTksIDB4MTYsIDB4MzQsIDB4ODksIDB4NGUsIDB4ODYsIDB4YTMsIDB4YjIsIDB4YjcsIDB4NTYsIDB4N2IsIDB4ODIsCisgIDB4NDYsIDB4ZTksIDB4YTYsIDB4MDYsIDB4MWUsIDB4MTksIDB4NjgsIDB4NGEsIDB4YmUsIDB4Y2IsIDB4NmUsIDB4MWIsCisgIDB4M2QsIDB4ZmMsIDB4OWIsIDB4ZjMsIDB4OGQsIDB4N2IsIDB4OTcsIDB4OTYsIDB4NDMsIDB4YjcsIDB4YjQsIDB4NjMsCisgIDB4NjMsIDB4ZDAsIDB4NTAsIDB4Y2EsIDB4N2IsIDB4YmIsIDB4NjUsIDB4OGYsIDB4MzgsIDB4ZmEsIDB4ZTksIDB4NWEsCisgIDB4N2MsIDB4ZTksIDB4NzMsIDB4OWUsIDB4MmUsIDB4Y2IsIDB4OTAsIDB4YjcsIDB4NTQsIDB4N2YsIDB4NDgsIDB4ZDcsCisgIDB4YzUsIDB4NjIsIDB4Y2EsIDB4ZDcsIDB4OWYsIDB4ZWUsIDB4Y2IsIDB4ZjIsIDB4OGYsIDB4ZjIsIDB4Y2MsIDB4NzYsCisgIDB4NDMsIDB4NWIsIDB4ZjksIDB4MmQsIDB4YTYsIDB4ZDAsIDB4ZDksIDB4NjMsIDB4MWYsIDB4ODIsIDB4OTIsIDB4YmUsCisgIDB4ZTIsIDB4ZmIsIDB4ODMsIDB4YWQsIDB4MmMsIDB4NWMsIDB4ZWUsIDB4OTMsIDB4ZWUsIDB4NGUsIDB4OTcsIDB4MjYsCisgIDB4NDksIDB4NWIsIDB4ODcsIDB4ZDEsIDB4YmUsIDB4ODMsIDB4ZWEsIDB4YWUsIDB4M2EsIDB4MmIsIDB4OWEsIDB4ZTcsCisgIDB4YjQsIDB4MmIsIDB4ZGMsIDB4MmQsIDB4MmQsIDB4ZTIsIDB4M2UsIDB4NGIsIDB4NjUsIDB4ZjksIDB4MTAsIDB4ZTQsCisgIDB4ZDgsIDB4NTEsIDB4NDUsIDB4MTUsIDB4YzIsIDB4NDAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NDUsIDB4MTQsCisgIDB4NTAsIDB4MGYsIDB4MTgsIDB4ZTIsIDB4ODYsIDB4NDEsIDB4ODgsIDB4Y2EsIDB4YjIsIDB4MzgsIDB4NDEsIDB4OTMsCisgIDB4MTgsIDB4NzYsIDB4OTEsIDB4YzksIDB4ZmYsIDB4MDAsIDB4MGYsIDB4ZmMsIDB4N2QsIDB4NzQsIDB4OGUsIDB4YTAsCisgIDB4NTIsIDB4YTIsIDB4OTUsIDB4MDIsIDB4MDgsIDB4M2EsIDB4MjAsIDB4ZjgsIDB4NTQsIDB4OWUsIDB4MmYsIDB4NzMsCisgIDB4NTUsIDB4YWEsIDB4ZjQsIDB4YzQsIDB4YTAsIDB4NGYsIDB4MjAsIDB4NTcsIDB4MmIsIDB4ODMsIDB4ZDIsIDB4OTMsCisgIDB4ZGYsIDB4NTIsIDB4NWMsIDB4NDIsIDB4YjYsIDB4MjYsIDB4MWQsIDB4ZTAsIDB4NGMsIDB4OGUsIDB4MzcsIDB4MWEsCisgIDB4NmEsIDB4N2IsIDB4NTQsIDB4MTEsIDB4ZGQsIDB4YmYsIDB4MWYsIDB4ZmMsIDB4ZmQsIDB4NzUsIDB4ZWMsIDB4NTcsCisgIDB4ZmYsIDB4MDAsIDB4OTUsIDB4NjcsIDB4MWEsIDB4ZGYsIDB4OGEsIDB4OWYsIDB4NzUsIDB4ZmMsIDB4M2YsIDB4MGIsCisgIDB4ZmQsIDB4YmYsIDB4MjIsIDB4Y2YsIDB4NzUsIDB4OTEsIDB4NmEsIDB4YWQsIDB4MmUsIDB4MTgsIDB4NWQsIDB4YmMsCisgIDB4YjIsIDB4ZDAsIDB4NjAsIDB4M2EsIDB4YWQsIDB4YmIsIDB4MTcsIDB4YTIsIDB4NzcsIDB4ZTIsIDB4ODMsIDB4ZGQsCisgIDB4ZmQsIDB4ZGQsIDB4ZDUsIDB4NTYsIDB4ZDQsIDB4YzYsIDB4MTksIDB4NzEsIDB4NWQsIDB4YjcsIDB4MjEsIDB4OGMsCisgIDB4ZWEsIDB4NDksIDB4ZTQsIDB4NzEsIDB4NDEsIDB4YjcsIDB4MDcsIDB4YTQsIDB4MTMsIDB4YWYsIDB4ZmMsIDB4MWEsCisgIDB4YWYsIDB4NjIsIDB4ZGUsIDB4YmIsIDB4M2IsIDB4YjgsIDB4YzksIDB4ZjAsIDB4ZjYsIDB4N2YsIDB4MDcsIDB4ZmMsCisgIDB4MDgsIDB4M2MsIDB4MzIsIDB4ZTksIDB4YWMsIDB4MTMsIDB4YWEsIDB4Y2QsIDB4NjgsIDB4OWIsIDB4MjUsIDB4OTgsCisgIDB4OTEsIDB4OWUsIDB4OTUsIDB4MjUsIDB4YzQsIDB4YjQsIDB4YzMsIDB4MmQsIDB4YTksIDB4YzcsIDB4MTYsIDB4YTMsCisgIDB4YTAsIDB4OTQsIDB4YTQsIDB4NmMsIDB4OTMsIDB4ZWMsIDB4MTUsIDB4ZmEsIDB4YTEsIDB4ZDIsIDB4N2MsIDB4ZjksCisgIDB4OTIsIDB4M2MsIDB4ZGMsIDB4ZGUsIDB4MjcsIDB4NWMsIDB4ZWUsIDB4MGMsIDB4YWIsIDB4OTksIDB4MDcsIDB4M2IsCisgIDB4YjMsIDB4YzMsIDB4ZGYsIDB4ZWIsIDB4MzIsIDB4ZGIsIDB4MDEsIDB4NWYsIDB4ZjUsIDB4MjgsIDB4ZDcsIDB4ZDEsCisgIDB4NDMsIDB4YmEsIDB4YmUsIDB4NjksIDB4YjMsIDB4YTEsIDB4ZDcsIDB4NzEsIDB4ZmMsIDB4NTYsIDB4ZWYsIDB4MjUsCisgIDB4YjIsIDB4ZGMsIDB4OWIsIDB4ZGUsIDB4NjMsIDB4MTYsIDB4ZWMsIDB4ZjIsIDB4N2QsIDB4MDYsIDB4NDQsIDB4YTIsCisgIDB4YjQsIDB4OGYsIDB4YTksIDB4MDUsIDB4MDMsIDB4ZWEsIDB4YWYsIDB4YTUsIDB4ODUsIDB4NmIsIDB4NTYsIDB4M2EsCisgIDB4NzAsIDB4YmQsIDB4MGMsIDB4NjgsIDB4Y2IsIDB4NTYsIDB4NWYsIDB4YTgsIDB4NTEsIDB4NDUsIDB4MTUsIDB4OTEsCisgIDB4YjAsIDB4NTIsIDB4NjcsIDB4MWMsIDB4YmUsIDB4NDcsIDB4NzIsIDB4ZWYsIDB4YTEsIDB4ZTQsIDB4ZmQsIDB4ZDksCisgIDB4YTcsIDB4M2EsIDB4NGMsIDB4ZTMsIDB4OTEsIDB4ZDcsIDB4MDcsIDB4NzIsIDB4ZmQsIDB4ZjcsIDB4N2IsIDB4OTEsCisgIDB4MjcsIDB4ZWUsIDB4Y2QsIDB4MDAsIDB4ODMsIDB4NzQsIDB4OTgsIDB4MzEsIDB4OWMsIDB4OGUsIDB4YzMsIDB4OWEsCisgIDB4OTUsIDB4NzIsIDB4NDQsIDB4ODYsIDB4MGMsIDB4MWIsIDB4YTksIDB4MWUsIDB4MTAsIDB4ZGUsIDB4MjksIDB4ZjcsCisgIDB4YzUsIDB4NzgsIDB4ZTksIDB4YjcsIDB4MDMsIDB4NmIsIDB4ZjksIDB4YmMsIDB4ZjUsIDB4NzgsIDB4YTcsIDB4YjgsCisgIDB4NTUsIDB4NjUsIDB4MWEsIDB4ZDAsIDB4ZjUsIDB4ZGUsIDB4MTIsIDB4YTIsIDB4MTgsIDB4N2UsIDB4NTMsIDB4MWQsCisgIDB4ZTYsIDB4YmIsIDB4MzcsIDB4NTAsIDB4ZTAsIDB4ZDIsIDB4MTYsIDB4OTIsIDB4MzQsIDB4NTIsIDB4NDksIDB4ZjAsCisgIDB4MjAsIDB4OTEsIDB4NWQsIDB4NWMsIDB4MzYsIDB4OWYsIDB4MzcsIDB4MTksIDB4OWMsIDB4OWUsIDB4MWMsIDB4ZTQsCisgIDB4NmYsIDB4ZjMsIDB4YmYsIDB4MTksIDB4OTIsIDB4YmIsIDB4MWMsIDB4YzUsIDB4OWQsIDB4ZjksIDB4N2MsIDB4MzQsCisgIDB4ZmUsIDB4NjYsIDB4ZmMsIDB4NWUsIDB4NmIsIDB4YTIsIDB4NTQsIDB4M2IsIDB4Y2EsIDB4NzksIDB4NTUsIDB4ZDcsCisgIDB4NmEsIDB4ZDcsIDB4NWQsIDB4ZGMsIDB4NjIsIDB4YTUsIDB4OTQsIDB4Y2UsIDB4NGIsIDB4NDksIDB4NGIsIDB4NGUsCisgIDB4MWEsIDB4ZTAsIDB4YjAsIDB4ZWEsIDB4MzcsIDB4MjMsIDB4YmIsIDB4YjMsIDB4NjUsIDB4YjYsIDB4MmUsIDB4NjMsCisgIDB4YzMsIDB4OTgsIDB4OGUsIDB4ODgsIDB4NDYsIDB4ZjUsIDB4Y2MsIDB4YWYsIDB4NDUsIDB4NDksIDB4MGEsIDB4NGEsCisgIDB4ZTIsIDB4ZDMsIDB4MmUsIDB4YWUsIDB4ZDUsIDB4MTUsIDB4ZDQsIDB4NmMsIDB4YTEsIDB4MGUsIDB4OWUsIDB4N2QsCisgIDB4N2EsIDB4YzcsIDB4NGEsIDB4ZjEsIDB4YmIsIDB4NGUsIDB4ZTIsIDB4NzYsIDB4ZjYsIDB4OTMsIDB4YWIsIDB4NGYsCisgIDB4OTQsIDB4OGUsIDB4YTksIDB4M2MsIDB4MjEsIDB4NWEsIDB4NWUsIDB4NjksIDB4N2UsIDB4N2QsIDB4ZjIsIDB4ZTIsCisgIDB4MjUsIDB4MDYsIDB4NTMsIDB4YmUsIDB4ODgsIDB4NDIsIDB4NDYsIDB4YTksIDB4OGIsIDB4MWIsIDB4YzgsIDB4N2YsCisgIDB4OTQsIDB4NzEsIDB4OWUsIDB4YjIsIDB4NWQsIDB4MTIsIDB4OGUsIDB4ZDksIDB4YzYsIDB4YzgsIDB4NDIsIDB4YzAsCisgIDB4ZDAsIDB4NTcsIDB4ZmYsIDB4MDAsIDB4YmEsIDB4YWUsIDB4YWIsIDB4N2QsIDB4YmUsIDB4NTMsIDB4OTAsIDB4YTYsCisgIDB4YjMsIDB4MmQsIDB4YTMsIDB4YTUsIDB4YjQsIDB4YjAsIDB4YTEsIDB4NWYsIDB4OWQsIDB4NWEsIDB4ZjYsIDB4YzUsCisgIDB4Y2QsIDB4M2EsIDB4YmEsIDB4YWEsIDB4Y2QsIDB4Y2EsIDB4MmYsIDB4OTQsIDB4ZjcsIDB4Y2EsIDB4ZWEsIDB4NzMsCisgIDB4YTksIDB4YmMsIDB4ZWUsIDB4MTcsIDB4MDgsIDB4YWUsIDB4NDIsIDB4OWEsIDB4ZjQsIDB4NTcsIDB4NDYsIDB4OTYsCisgIDB4ZDIsIDB4OGEsIDB4NGQsIDB4NjgsIDB4YTcsIDB4MWUsIDB4MjAsIDB4NDUsIDB4NmUsIDB4NWMsIDB4NzgsIDB4OTksCisgIDB4MDQsIDB4NTAsIDB4MGIsIDB4NzIsIDB4MTAsIDB4MDMsIDB4OWEsIDB4ZjAsIDB4NTUsIDB4MjcsIDB4NTcsIDB4MjUsCisgIDB4ZjUsIDB4YjcsIDB4ZDksIDB4YWIsIDB4Y2EsIDB4OWEsIDB4ZTMsIDB4OTUsIDB4ZWEsIDB4OWYsIDB4MDQsIDB4NDksCisgIDB4NjEsIDB4ODUsIDB4MTQsIDB4NTEsIDB4NWMsIDB4NjQsIDB4MDUsIDB4MTQsIDB4NTEsIDB4NDAsIDB4MTQsIDB4NTEsCisgIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NGYsIDB4NTYsIDB4ODQsIDB4ZmYsIDB4MDAsIDB4MjksCisgIDB4ZjAsIDB4YjcsIDB4MmQsIDB4YTQsIDB4ODMsIDB4MzYsIDB4MTEsIDB4ZTYsIDB4NjQsIDB4OWUsIDB4ZjIsIDB4M2MsCisgIDB4MDcsIDB4ZGEsIDB4M2UsIDB4YjEsIDB4NDgsIDB4YjUsIDB4MzMsIDB4ODYsIDB4ZGQsIDB4MGQsIDB4YTYsIDB4ZmEsCisgIDB4Y2IsIDB4ZTQsIDB4OWUsIDB4YzksIDB4NjcsIDB4OTEsIDB4YzEsIDB4ZWEsIDB4MzUsIDB4ZTksIDB4NzYsIDB4NjUsCisgIDB4NzgsIDB4NTIsIDB4YWQsIDB4YTIsIDB4YTcsIDB4ODIsIDB4N2QsIDB4ZDcsIDB4ZjAsIDB4N2QsIDB4N2UsIDB4NWMsCisgIDB4OTYsIDB4OGIsIDB4YzMsIDB4MjIsIDB4YTQsIDB4YzcsIDB4N2EsIDB4MzMsIDB4Y2EsIDB4NjUsIDB4ZjYsIDB4OTQsCisgIDB4ZGIsIDB4ODksIDB4M2EsIDB4MjksIDB4NTAsIDB4ZDUsIDB4MzIsIDB4ZjAsIDB4ZmYsIDB4MDAsIDB4MWYsIDB4N2UsCisgIDB4ZTMsIDB4NzQsIDB4NmUsIDB4NmIsIDB4YzgsIDB4MjgsIDB4ODksIDB4MWQsIDB4NDEsIDB4NDQsIDB4OTEsIDB4ZjAsCisgIDB4ZDQsIDB4M2IsIDB4OTIsIDB4M2YsIDB4ZWYsIDB4NTYsIDB4ODMsIDB4ZDAsIDB4ZTEsIDB4NGEsIDB4ZTUsIDB4NzEsCisgIDB4ZDgsIDB4Y2MsIDB4YmIsIDB4ZTIsIDB4MTQsIDB4YTQsIDB4MDMsIDB4NWIsIDB4OWIsIDB4NDIsIDB4MWIsIDB4NDAsCisgIDB4NDMsIDB4NjgsIDB4NGEsIDB4MTIsIDB4M2IsIDB4ODIsIDB4NDYsIDB4ODAsIDB4YWYsIDB4YWIsIDB4YjQsIDB4ZjYsCisgIDB4NWEsIDB4MTQsIDB4YWIsIDB4YWEsIDB4OTMsIDB4OWUsIDB4YTgsIDB4YWQsIDB4ZDIsIDB4YzcsIDB4ZDQsIDB4ZDEsCisgIDB4NTMsIDB4YzMsIDB4M2QsIDB4NTUsIDB4NzUsIDB4YzcsIDB4N2IsIDB4ODIsIDB4ZDcsIDB4OGUsIDB4NDcsIDB4YzQsCisgIDB4MjIsIDB4M2EsIDB4NTEsIDB4MzcsIDB4MjUsIDB4N2IsIDB4YzgsIDB4YzksIDB4NDksIDB4ZjMsIDB4OWIsIDB4ODgsCisgIDB4MDAsIDB4NTQsIDB4YTcsIDB4M2QsIDB4ODEsIDB4YmQsIDB4YTMsIDB4ZGEsIDB4ZTIsIDB4NjksIDB4ZWEsIDB4ZjEsCisgIDB4NzIsIDB4ODMsIDB4NjcsIDB4YjUsIDB4Y2EsIDB4YmEsIDB4NWMsIDB4YTUsIDB4MzcsIDB4MTYsIDB4MTQsIDB4NDYsCisgIDB4OTQsIDB4ZjMsIDB4ZWYsIDB4MzgsIDB4NzQsIDB4OTQsIDB4MjEsIDB4MjMsIDB4NjQsIDB4OTMsIDB4NTQsIDB4ZWQsCisgIDB4OTUsIDB4YzksIDB4YjksIDB4MGQsIDB4ZmUsIDB4NmUsIDB4NmYsIDB4NzUsIDB4OGMsIDB4ZTQsIDB4NzcsIDB4YTYsCisgIDB4YjYsIDB4MjMsIDB4ZGIsIDB4NjIsIDB4M2EsIDB4MzQsIDB4YjgsIDB4NzAsIDB4NDEsIDB4ZGEsIDB4NDIsIDB4YzcsCisgIDB4ODMsIDB4OGUsIDB4MWYsIDB4M2QsIDB4NDMsIDB4YmMsIDB4NmQsIDB4MjksIDB4ZmMsIDB4ZGEsIDB4ZmIsIDB4M2EsCisgIDB4MTQsIDB4OWQsIDB4NDksIDB4ZTAsIDB4OGEsIDB4ZDUsIDB4NTUsIDB4MzgsIDB4ZTcsIDB4YTksIDB4YTcsIDB4MmUsCisgIDB4NDMsIDB4NmQsIDB4M2QsIDB4OGEsIDB4YjQsIDB4ZDIsIDB4MDIsIDB4MWIsIDB4NGUsIDB4NGIsIDB4NmQsIDB4NGEsCisgIDB4NTIsIDB4MDYsIDB4ODIsIDB4NDAsIDB4NzgsIDB4NjgsIDB4MGYsIDB4NjUsIDB4NWUsIDB4NjMsIDB4YmEsIDB4YTgsCisgIDB4ZWMsIDB4Y2IsIDB4ZTMsIDB4MzgsIDB4YjcsIDB4N2YsIDB4ZmEsIDB4Y2YsIDB4NmUsIDB4ZmIsIDB4ZTEsIDB4NTcsCisgIDB4ODgsIDB4ZWUsIDB4YWQsIDB4MmYsIDB4M2UsIDB4ZjMsIDB4ZTQsIDB4NjcsIDB4NjcsIDB4ZjcsIDB4NjEsIDB4NDUsCisgIDB4MTQsIDB4NTcsIDB4MjksIDB4ZDQsIDB4MTQsIDB4OTksIDB4YzcsIDB4MWYsIDB4OTEsIDB4ZWMsIDB4YjcsIDB4ZTgsCisgIDB4ODksIDB4MWYsIDB4YzAsIDB4NjksIDB4Y2UsIDB4OTMsIDB4MzgsIDB4ZTMsIDB4ZjIsIDB4M2QsIDB4OTcsIDB4N2QsCisgIDB4MTEsIDB4MjMsIDB4ZjgsIDB4MGQsIDB4MDAsIDB4ZGIsIDB4MTEsIDB4MDksIDB4NGMsIDB4NTYsIDB4OTIsIDB4OTAsCisgIDB4MDAsIDB4MDksIDB4MWQsIDB4MDAsIDB4YTgsIDB4NWMsIDB4ZTcsIDB4MTcsIDB4ODEsIDB4OTUsIDB4ZDksIDB4YzQsCisgIDB4MDksIDB4NmIsIDB4NzYsIDB4M2IsIDB4ZWMsIDB4YjgsIDB4OTksIDB4MTAsIDB4NjYsIDB4YjIsIDB4NzQsIDB4ZjQsCisgIDB4MzksIDB4MDksIDB4ZjgsIDB4MGUsIDB4YjYsIDB4N2YsIDB4NDgsIDB4MWYsIDB4MGUsIDB4ZTIsIDB4MzYsIDB4MDgsCisgIDB4MjAsIDB4OWEsIDB4OWMsIDB4OGQsIDB4ZjEsIDB4NzYsIDB4ZmUsIDB4NjAsIDB4ZmIsIDB4MmIsIDB4NjEsIDB4MWIsCisgIDB4YTAsIDB4MTEsIDB4ZjEsIDB4M2MsIDB4YjYsIDB4NzQsIDB4N2IsIDB4YWIsIDB4NzgsIDB4OTYsIDB4NmMsIDB4ZGIsCisgIDB4MzAsIDB4YWYsIDB4ZGEsIDB4M2UsIDB4NDcsIDB4MjksIDB4MDMsIDB4OTYsIDB4MzUsIDB4ZDksIDB4MDMsIDB4ZjMsCisgIDB4ZDksIDB4MjcsIDB4YjksIDB4YzAsIDB4M2EsIDB4YTksIDB4YTMsIDB4ZTcsIDB4MGUsIDB4YTQsIDB4NmQsIDB4M2QsCisgIDB4NjksIDB4YmUsIDB4ZTEsIDB4MTIsIDB4M2QsIDB4YzIsIDB4MTMsIDB4OTEsIDB4MjQsIDB4YTAsIDB4MmQsIDB4YTcsCisgIDB4MDYsIDB4ODgsIDB4YWUsIDB4M2MsIDB4OWIsIDB4MWYsIDB4YjMsIDB4ZTQsIDB4OTYsIDB4ODcsIDB4MmQsIDB4NTcsCisgIDB4YjgsIDB4MmQsIDB4Y2MsIDB4ODgsIDB4YjIsIDB4MTUsIDB4YzgsIDB4YWQsIDB4ODIsIDB4ODUsIDB4MGUsIDB4ZTUsCisgIDB4YTEsIDB4NDMsIDB4YWEsIDB4MTQsIDB4M2IsIDB4YzIsIDB4OTIsIDB4NDEsIDB4MDcsIDB4YmEsIDB4OTMsIDB4ZmIsCisgIDB4NGMsIDB4ZDcsIDB4MDUsIDB4NDYsIDB4OWYsIDB4NGMsIDB4YmMsIDB4ZDMsIDB4MWUsIDB4NDcsIDB4NzMsIDB4YWQsCisgIDB4ODAsIDB4NmUsIDB4YjEsIDB4MTMsIDB4ZDcsIDB4ZTEsIDB4MjcsIDB4YTIsIDB4NjQsIDB4YTQsIDB4MDAsIDB4M2EsCisgIDB4OGUsIDB4NTcsIDB4M2QsIDB4NGIsIDB4M2QsIDB4NGQsIDB4NjUsIDB4MTUsIDB4MjQsIDB4ZTMsIDB4MjUsIDB4OTQsCisgIDB4YzEsIDB4MWQsIDB4OTEsIDB4ZTEsIDB4MTcsIDB4MWIsIDB4NzksIDB4NTMsIDB4ZjAsIDB4NDIsIDB4YTYsIDB4YzYsCisgIDB4ZWYsIDB4ZjMsIDB4NDcsIDB4YmUsIDB4MjcsIDB4ZGEsIDB4M2MsIDB4N2QsIDB4YTIsIDB4OTUsIDB4MDgsIDB4MjAsCisgIDB4OTAsIDB4NDEsIDB4MDQsIDB4NzQsIDB4MjAsIDB4ZDUsIDB4ZDEsIDB4OGEsIDB4ZTQsIDB4ZjYsIDB4MmMsIDB4YTIsCisgIDB4MDcsIDB4OTcsIDB4NTgsIDB4YWUsIDB4NmMsIDB4NGQsIDB4NjksIDB4MjcsIDB4OTUsIDB4YzAsIDB4ODIsIDB4NDMsCisgIDB4OGMsIDB4YWIsIDB4ZjQsIDB4NWMsIDB4NDEsIDB4ZDIsIDB4OTAsIDB4YWYsIDB4ZDUsIDB4NTAsIDB4MDcsIDB4ZDUsCisgIDB4NWUsIDB4YWYsIDB4NTgsIDB4ZWQsIDB4YTIsIDB4ZWYsIDB4YjUsIDB4NGEsIDB4OGEsIDB4OTAsIDB4ZWYsIDB4ZjUsCisgIDB4YWQsIDB4ZjksIDB4YWIsIDB4ZmUsIDB4ZjEsIDB4ZGYsIDB4ZjUsIDB4ZWUsIDB4YmUsIDB4NDYsIDB4ZmYsIDB4MDAsCisgIDB4ZDksIDB4NTgsIDB4Y2QsIDB4YjksIDB4ZGEsIDB4Y2IsIDB4MWUsIDB4OGYsIDB4OGYsIDB4OTMsIDB4MzIsIDB4OTUsCisgIDB4M2YsIDB4MjEsIDB4MjcsIDB4MDYsIDB4N2QsIDB4YmIsIDB4YTUsIDB4YTIsIDB4NjYsIDB4M2IsIDB4MjQsIDB4ZWYsCisgIDB4OTksIDB4MjUsIDB4NmMsIDB4NmYsIDB4YzAsIDB4ZDIsIDB4N2MsIDB4YTYsIDB4MWMsIDB4OGQsIDB4MjUsIDB4YzYsCisgIDB4MWQsIDB4MWEsIDB4NWIsIDB4NmEsIDB4MjksIDB4MjIsIDB4YWMsIDB4MDQsIDB4NjEsIDB4MTMsIDB4YWQsIDB4NzcsCisgIDB4MjYsIDB4NjcsIDB4ZGEsIDB4MjYsIDB4YTEsIDB4ZGUsIDB4YzksIDB4N2IsIDB4ZWMsIDB4ZGQsIDB4MWMsIDB4YWEsCisgIDB4MjMsIDB4YzQsIDB4NmMsIDB4NzQsIDB4M2YsIDB4ZTEsIDB4NWMsIDB4NWMsIDB4NDgsIDB4YjEsIDB4YzksIDB4ZjIsCisgIDB4ZTQsIDB4NWMsIDB4ZTMsIDB4NDUsIDB4NzEsIDB4NDksIDB4NzksIDB4M2UsIDB4ZmMsIDB4MTAsIDB4OTIsIDB4YWUsCisgIDB4NTUsIDB4N2EsIDB4ZjUsIDB4NWUsIDB4NTUsIDB4ZWYsIDB4NjcsIDB4NWMsIDB4ZmQsIDB4OGQsIDB4M2EsIDB4YjAsCisgIDB4N2EsIDB4YTksIDB4ZWQsIDB4ZTcsIDB4OTgsIDB4YmUsIDB4MzgsIDB4ZjIsIDB4N2YsIDB4YTEsIDB4NTcsIDB4MTcsCisgIDB4OGQsIDB4YzQsIDB4OGEsIDB4MjgsIDB4MjAsIDB4ODIsIDB4NDEsIDB4MDQsIDB4MTEsIDB4ZTAsIDB4NjgsIDB4YWYsCisgIDB4OWEsIDB4MzMsIDB4MGEsIDB4MjgsIDB4YTIsIDB4ODAsIDB4MjgsIDB4YTIsIDB4YmQsIDB4MzQsIDB4ZDMsIDB4OGYsCisgIDB4MmMsIDB4MjEsIDB4YTYsIDB4ZDYsIDB4ZTIsIDB4OGYsIDB4NzIsIDB4NTIsIDB4OWQsIDB4OWEsIDB4OTQsIDB4OWIsCisgIDB4ZDksIDB4MDMsIDB4Y2QsIDB4MTUsIDB4MzksIDB4NmYsIDB4YzQsIDB4YWYsIDB4ZjMsIDB4NDgsIDB4MjksIDB4ODAsCisgIDB4YjYsIDB4NTAsIDB4N2YsIDB4MzksIDB4ZmYsIDB4MDAsIDB4MzMsIDB4NWYsIDB4NTEsIDB4ZWIsIDB4ZmUsIDB4MTQsCisgIDB4ZDMsIDB4NjksIDB4ZTEsIDB4ZGIsIDB4MjgsIDB4MjEsIDB4NzcsIDB4NDksIDB4YTUsIDB4YzMsIDB4ZTIsIDB4ZGIsCisgIDB4MDMsIDB4NDMsIDB4ZmUsIDB4NjMsIDB4ZDQsIDB4ZmYsIDB4MDAsIDB4NzAsIDB4YWYsIDB4NGUsIDB4ZGIsIDB4YjEsCisgIDB4YWYsIDB4NmUsIDB4NWYsIDB4NzYsIDB4OWIsIDB4NGIsIDB4Y2QsIDB4ZWMsIDB4YmYsIDB4NWYsIDB4ZDgsIDB4YjIsCisgIDB4ODMsIDB4NjUsIDB4N2QsIDB4MTYsIDB4M2IsIDB4ZjIsIDB4OWYsIDB4NGIsIDB4MTEsIDB4OTksIDB4NWIsIDB4Y2UsCisgIDB4YWIsIDB4YjksIDB4MjgsIDB4NGUsIDB4YzksIDB4YTcsIDB4YmMsIDB4NjcsIDB4MDIsIDB4NTEsIDB4NTIsIDB4MjQsCisgIDB4ZGUsIDB4ZDUsIDB4Y2EsIDB4MDYsIDB4ODgsIDB4OGUsIDB4ODUsIDB4NzUsIDB4M2YsIDB4MzgsIDB4OGYsIDB4YjAsCisgIDB4N2YsIDB4N2QsIDB4M2IsIDB4ZGIsIDB4MmQsIDB4OTAsIDB4MmQsIDB4OGMsIDB4ZjYsIDB4NTAsIDB4NjIsIDB4YjYsCisgIDB4YzIsIDB4N2MsIDB4NGEsIDB4NDcsIDB4NTMsIDB4ZWQsIDB4M2QsIDB4ZTcsIDB4ZWIsIDB4YWUsIDB4YTIsIDB4NDgsCisgIDB4YWYsIDB4YWQsIDB4ZWMsIDB4ZmYsIDB4MDAsIDB4NjYsIDB4MjgsIDB4ZDEsIDB4NmEsIDB4NzcsIDB4MGYsIDB4NTMsCisgIDB4ZjIsIDB4ZTksIDB4ZmUsIDB4N2YsIDB4ZGQsIDB4OGQsIDB4NjMsIDB4NGQsIDB4MmUsIDB4NDEsIDB4YjQsIDB4MjUsCisgIDB4YjYsIDB4ZDIsIDB4ZGEsIDB4MTIsIDB4MTIsIDB4OTQsIDB4ODAsIDB4MTIsIDB4MDcsIDB4NzAsIDB4MDIsIDB4YjksCisgIDB4NmUsIDB4ZDcsIDB4MTgsIDB4MzYsIDB4OWIsIDB4NzQsIDB4OGIsIDB4OTUsIDB4Y2EsIDB4NWIsIDB4MTAsIDB4ZTEsCisgIDB4NDYsIDB4NmMsIDB4YjgsIDB4ZmIsIDB4ZWYsIDB4MmMsIDB4MjUsIDB4MGQsIDB4YTQsIDB4NzcsIDB4OTIsIDB4NGYsCisgIDB4NDEsIDB4NGIsIDB4NzksIDB4NDYsIDB4N2QsIDB4NmMsIDB4YjUsIDB4NWMsIDB4N2QsIDB4YzQsIDB4YjUsIDB4YzcsCisgIDB4N2YsIDB4MjAsIDB4YzgsIDB4NTQsIDB4M2MsIDB4Y2IsIDB4NWQsIDB4YmYsIDB4NGIsIDB4NzEsIDB4MWUsIDB4ODUsCisgIDB4M2MsIDB4YjIsIDB4NzksIDB4MTgsIDB4NDcsIDB4NzcsIDB4OWMsIDB4YjIsIDB4M2QsIDB4NDEsIDB4NDcsIDB4YTUsCisgIDB4NzAsIDB4NWIsIDB4ZjAsIDB4ZWIsIDB4YTUsIDB4ZmUsIDB4ZTYsIDB4YzUsIDB4ZWYsIDB4ODgsIDB4NzIsIDB4NjIsCisgIDB4Y2QsIDB4NWMsIDB4NzcsIDB4MDMsIDB4YjAsIDB4YWMsIDB4YjEsIDB4NDksIDB4MzAsIDB4MjEsIDB4YWMsIDB4MWYsCisgIDB4MzUsIDB4NmEsIDB4ZTYsIDB4MDAsIDB4YmUsIDB4ZTgsIDB4ZmQsIDB4MjUsIDB4MDAsIDB4OTQsIDB4OWYsIDB4ODIsCisgIDB4OTAsIDB4N2EsIDB4ZDcsIDB4ZDQsIDB4ZjAsIDB4NjgsIDB4NzIsIDB4NDQsIDB4OGIsIDB4MzMsIDB4ODksIDB4MzcsCisgIDB4MTgsIDB4ZDcsIDB4N2IsIDB4YzQsIDB4NTcsIDB4ZTAsIDB4ZTIsIDB4MTEsIDB4MWUsIDB4NDMsIDB4ZjYsIDB4ZWIsCisgIDB4NzMsIDB4YzksIDB4MjgsIDB4NzYsIDB4ZTgsIDB4ZWEsIDB4NGUsIDB4ZDMsIDB4MjEsIDB4ZjQsIDB4OWUsIDB4YTksCisgIDB4NjUsIDB4MjQsIDB4MDIsIDB4ZGIsIDB4NjcsIDB4YWEsIDB4ODgsIDB4ZTcsIDB4NWUsIDB4ODYsIDB4OTMsIDB4NGUsCisgIDB4ZjcsIDB4M2IsIDB4MzQsIDB4MTksIDB4ZTksIDB4ZGIsIDB4OGQsIDB4ZjIsIDB4MzksIDB4ZTAsIDB4YjQsIDB4NzQsCisgIDB4MjMsIDB4ZmYsIDB4MDAsIDB4MzUsIDB4MjIsIDB4MDAsIDB4ZDUsIDB4MWEsIDB4MWEsIDB4YTksIDB4OGMsIDB4OWMsCisgIDB4NWUsIDB4NTEsIDB4NTksIDB4NDUsIDB4NDksIDB4NjEsIDB4OTUsIDB4MTcsIDB4MTIsIDB4ZWMsIDB4ZDIsIDB4NmQsCisgIDB4ZDIsIDB4MzEsIDB4NjcsIDB4NTQsIDB4YTQsIDB4YjgsIDB4YzksIDB4Y2EsIDB4MmQsIDB4YTAsIDB4MmMsIDB4NzQsCisgIDB4MjMsIDB4ZGYsIDB4ODcsIDB4NzgsIDB4YWIsIDB4NzgsIDB4NzcsIDB4NTIsIDB4MjcsIDB4MTksIDB4NDcsIDB4ZjMsCisgIDB4MmMsIDB4NWYsIDB4ZjYsIDB4YWEsIDB4ZDksIDB4ZjcsIDB4ZTIsIDB4OWUsIDB4ZWEsIDB4ZDUsIDB4MmEsIDB4NGEsCisgIDB4YTMsIDB4Y2MsIDB4ODgsIDB4YTcsIDB4NGQsIDB4NTMsIDB4NTgsIDB4NDEsIDB4NDUsIDB4NzksIDB4MjQsIDB4ODMsCisgIDB4YTAsIDB4MDEsIDB4ZmEsIDB4ZTgsIDB4YWEsIDB4MTcsIDB4M2QsIDB4NTIsIDB4NjcsIDB4MWMsIDB4N2UsIDB4NDcsCisgIDB4YjIsIDB4ZWYsIDB4YTIsIDB4MjQsIDB4N2YsIDB4MDEsIDB4YTcsIDB4M2EsIDB4NGMsIDB4ZTMsIDB4OGYsIDB4YzgsCisgIDB4ZjYsIDB4NWQsIDB4ZjQsIDB4NDQsIDB4OGYsIDB4ZTAsIDB4MzQsIDB4MDMsIDB4N2MsIDB4NmYsIDB4OGIsIDB4YjcsCisgIDB4ZjMsIDB4MDcsIDB4ZDksIDB4NWIsIDB4MmIsIDB4NWMsIDB4NmYsIDB4OGIsIDB4YjcsIDB4ZjMsIDB4MDcsIDB4ZDksCisgIDB4NWIsIDB4MjgsIDB4MDMsIDB4NWQsIDB4NjgsIDB4ZDUsIDB4MTQsIDB4NTAsIDB4MGEsIDB4ZDksIDB4M2UsIDB4MDcsCisgIDB4OGUsIDB4ZGYsIDB4YTcsIDB4N2IsIDB4YTYsIDB4ZTQsIDB4NzcsIDB4YWQsIDB4ZjcsIDB4NzQsIDB4OGQsIDB4MjIsCisgIDB4ZTksIDB4NmUsIDB4NzgsIDB4YzYsIDB4OTYsIDB4OWYsIDB4NTcsIDB4NjgsIDB4OGQsIDB4MTUsIDB4MGYsIDB4ZDUsCisgIDB4NWYsIDB4MzIsIDB4N2QsIDB4NTUsIDB4MTQsIDB4MjIsIDB4ZjEsIDB4MzcsIDB4MWUsIDB4ZjgsIDB4OTQsIDB4ZmIsCisgIDB4NWUsIDB4NjMsIDB4MGQsIDB4MDAsIDB4ZTksIDB4YTksIDB4YzMsIDB4YzgsIDB4NjYsIDB4ODEsIDB4ZTAsIDB4MDMsCisgIDB4YTgsIDB4NDksIDB4NjksIDB4NjcsIDB4ZGEsIDB4ODQsIDB4N2IsIDB4N2MsIDB4NjksIDB4ZjcsIDB4NWQsIDB4NzcsCisgIDB4NDcsIDB4MjgsIDB4YTAsIDB4MTEsIDB4MDcsIDB4MTMsIDB4NmQsIDB4ZDYsIDB4ZjAsIDB4NTMsIDB4OTUsIDB4ZDgsCisgIDB4NzIsIDB4MWMsIDB4NjQsIDB4YTAsIDB4MDAsIDB4YTcsIDB4NjYsIDB4NDAsIDB4NTMsIDB4YjEsIDB4YjcsIDB4ZWEsCisgIDB4N2QsIDB4OWUsIDB4NzYsIDB4ZjUsIDB4ZWIsIDB4NTEsIDB4NGYsIDB4ZDUsIDB4NGMsIDB4YjYsIDB4MmMsIDB4OWYsCisgIDB4MWQsIDB4YmYsIDB4YTQsIDB4YWEsIDB4YzcsIDB4N2QsIDB4YjYsIDB4NWMsIDB4ZjQsIDB4MzYsIDB4NDQsIDB4NTksCisgIDB4NDgsIDB4NzAsIDB4ODEsIDB4ZWIsIDB4MDksIDB4MjQsIDB4OGEsIDB4OTYsIDB4ZDUsIDB4MmUsIDB4NWYsIDB4ZjAsCisgIDB4MmMsIDB4MmEsIDB4ZmMsIDB4YjUsIDB4MzksIDB4NzcsIDB4YzUsIDB4YWQsIDB4MTIsIDB4ZGUsIDB4NTcsIDB4N2IsCisgIDB4Y2EsIDB4OGEsIDB4ODAsIDB4ZWYsIDB4ZDQsIDB4YjAsIDB4MDIsIDB4ODcsIDB4ZDQsIDB4NjgsIDB4MDksIDB4YzksCisgIDB4MzEsIDB4MjIsIDB4NDksIDB4MWYsIDB4Y2UsIDB4NjIsIDB4MzAsIDB4ZjgsIDB4ZmYsIDB4MDAsIDB4NjgsIDB4ZDgsCisgIDB4NTcsIDB4ZGIsIDB4NTEsIDB4ZWUsIDB4ZTMsIDB4MzYsIDB4MDcsIDB4YjcsIDB4Y2YsIDB4NjksIDB4OGMsIDB4M2UsCisgIDB4NmEsIDB4NzksIDB4N2UsIDB4Y2EsIDB4NWIsIDB4NWYsIDB4MGIsIDB4YWMsIDB4NmMsIDB4MjEsIDB4MmQsIDB4ZDksCisgIDB4NmYsIDB4NTksIDB4NTUsIDB4OTEsIDB4MjksIDB4ZWUsIDB4NGMsIDB4MmIsIDB4ZTQsIDB4OGUsIDB4NDEsIDB4ZmYsCisgIDB4MDAsIDB4MDMsIDB4OGEsIDB4NWEsIDB4N2YsIDB4YzIsIDB4YTEsIDB4MzIsIDB4ZjAsIDB4MzAsIDB4YjgsIDB4NjEsCisgIDB4ZGIsIDB4OWYsIDB4MWMsIDB4YTYsIDB4ZDksIDB4NWEsIDB4ZDcsIDB4OTgsIDB4MmUsIDB4YzgsIDB4ODIsIDB4ZWEsCisgIDB4OTcsIDB4ZWMsIDB4MDUsIDB4YTQsIDB4YTksIDB4NWYsIDB4NTYsIDB4ZWIsIDB4MWEsIDB4OTYsIDB4ZDQsIDB4NmEsCisgIDB4NzgsIDB4ZTAsIDB4OWYsIDB4YzUsIDB4MjYsIDB4NDYsIDB4MTAsIDB4ZWUsIDB4YWMsIDB4MzcsIDB4MWIsIDB4MjcsCisgIDB4YWQsIDB4YjAsIDB4N2QsIDB4NGYsIDB4MzgsIDB4M2YsIDB4ZmUsIDB4ZDUsIDB4OTQsIDB4NjEsIDB4ZjgsIDB4ZGEsCisgIDB4NGYsIDB4NGIsIDB4NjIsIDB4NGYsIDB4YjUsIDB4ZDUsIDB4OWYsIDB4YjUsIDB4NTUsIDB4NGUsIDB4NWEsIDB4YjgsCisgIDB4OTksIDB4MTYsIDB4NzQsIDB4ZDEsIDB4MTYsIDB4MGYsIDB4ZTEsIDB4MTEsIDB4OGIsIDB4MjksIDB4ZDMsIDB4ZjAsCisgIDB4NTMsIDB4NzAsIDB4YjAsIDB4MjUsIDB4OTAsIDB4YWYsIDB4NjIsIDB4OTQsIDB4ZWIsIDB4NjAsIDB4ZmQsIDB4NTQsCisgIDB4ZmQsIDB4MGEsIDB4ZGIsIDB4YzQsIDB4YzksIDB4YjEsIDB4ZDEsIDB4MjYsIDB4MWYsIDB4MTIsIDB4MzEsIDB4YjksCisgIDB4MGMsIDB4MmMsIDB4NmQsIDB4MGUsIDB4MzUsIDB4OGYsIDB4NzMsIDB4MjEsIDB4NDMsIDB4ZDIsIDB4MDgsIDB4OTMsCisgIDB4YTMsIDB4NTgsIDB4N2YsIDB4NGUsIDB4YjMsIDB4ZmYsIDB4MDAsIDB4YWEsIDB4M2YsIDB4ZjksIDB4NWYsIDB4YzAsCisgIDB4ZDIsIDB4YmMsIDB4ODcsIDB4MDYsIDB4MzEsIDB4ZWIsIDB4MTMsIDB4M2QsIDB4NWIsIDB4YjQsIDB4YzQsIDB4ZDgsCisgIDB4ZjEsIDB4NTMsIDB4NDEsIDB4NWYsIDB4NmUsIDB4ZWEsIDB4NDEsIDB4OTYsIDB4OWEsIDB4NjUsIDB4MWMsIDB4YWMsCisgIDB4YjQsIDB4ZGIsIDB4NDksIDB4ZjQsIDB4MjEsIDB4M2EsIDB4MTQsIDB4ODgsIDB4MzEsIDB4YWUsIDB4MjYsIDB4MzksCisgIDB4ZjksIDB4N2UsIDB4MjcsIDB4YzUsIDB4NmYsIDB4ZmYsIDB4MDAsIDB4YzcsIDB4YzcsIDB4MWEsIDB4NGUsIDB4YmYsCisgIDB4ZTcsIDB4NzEsIDB4NzUsIDB4YjUsIDB4NTgsIDB4M2UsIDB4NDEsIDB4MmQsIDB4YmUsIDB4NWIsIDB4YTcsIDB4MTMsCisgIDB4YjIsIDB4OTcsIDB4N2YsIDB4ZmMsIDB4MzYsIDB4ZTIsIDB4NDUsIDB4MWYsIDB4ZjQsIDB4MzMsIDB4YmYsIDB4ZjEsCisgIDB4YWUsIDB4OGEsIDB4NzQsIDB4MjksIDB4ZDMsIDB4ZjAsIDB4NDUsIDB4MmYsIDB4ODIsIDB4MjcsIDB4MDgsIDB4NzksCisgIDB4MjcsIDB4ZDUsIDB4NTAsIDB4ZjksIDB4NTYsIDB4NTEsIDB4NjAsIDB4YzUsIDB4YTEsIDB4MjIsIDB4NjYsIDB4NDMsCisgIDB4NzUsIDB4OGQsIDB4NmYsIDB4NjUsIDB4YzUsIDB4NzIsIDB4MzQsIDB4NWQsIDB4NTcsIDB4OWMsIDB4ZTIsIDB4YjUsCisgIDB4YmUsIDB4NTQsIDB4MjQsIDB4NzUsIDB4NTEsIDB4ZDcsIDB4ODAsIDB4MDQsIDB4ZDIsIDB4M2QsIDB4OGUsIDB4Y2MsCisgIDB4ZGQsIDB4ODcsIDB4OGMsIDB4ZjAsIDB4NmQsIDB4NzEsIDB4MmYsIDB4NzcsIDB4ZTksIDB4ZTMsIDB4ZjksIDB4M2YsCisgIDB4MjYsIDB4NGMsIDB4YjEsIDB4NzEsIDB4YjksIDB4YmQsIDB4MjcsIDB4OWIsIDB4NmYsIDB4YjAsIDB4ODYsIDB4Y2YsCisgIDB4MmEsIDB4ODksIDB4NDgsIDB4ZjgsIDB4MmUsIDB4NmIsIDB4NDAsIDB4NzgsIDB4ZDQsIDB4OGMsIDB4MTIsIDB4MzIsCisgIDB4NmUsIDB4MzEsIDB4YmYsIDB4M2QsIDB4YjAsIDB4OTUsIDB4ZGIsIDB4YjEsIDB4NTgsIDB4OGIsIDB4ODQsIDB4ZGIsCisgIDB4OWUsIDB4MDYsIDB4N2MsIDB4OGUsIDB4NTUsIDB4M2EsIDB4MTIsIDB4N2MsIDB4N2IsIDB4MzYsIDB4OTIsIDB4ZGEsCisgIDB4NGYsIDB4YTAsIDB4YmEsIDB4NDcsIDB4NzgsIDB4YWQsIDB4NDEsIDB4YjEsIDB4NTksIDB4ZjUsIDB4ZDIsIDB4ZWEsCisgIDB4NGEsIDB4MzEsIDB4MGMsIDB4MjIsIDB4ZjUsIDB4NzMsIDB4MDQsIDB4OGUsIDB4NTksIDB4NzcsIDB4MDQsIDB4N2IsCisgIDB4OWIsIDB4MTcsIDB4OTQsIDB4ZmUsIDB4NzYsIDB4ZGUsIDB4MWQsIDB4YWEsIDB4ODcsIDB4Y2QsIDB4NmMsIDB4ZDcsCisgIDB4OTMsIDB4OGEsIDB4ZTYsIDB4MzksIDB4MDEsIDB4ZGUsIDB4NWYsIDB4OTYsIDB4OTgsIDB4OTAsIDB4ZDQsIDB4N2MsCisgIDB4ZWIsIDB4NjYsIDB4M2UsIDB4OTUsIDB4NDYsIDB4NDIsIDB4ODcsIDB4NWUsIDB4OGIsIDB4OTAsIDB4YWQsIDB4YmMsCisgIDB4YTAsIDB4NDcsIDB4N2YsIDB4MmYsIDB4NjcsIDB4ZWMsIDB4YTcsIDB4ZDAsIDB4MDEsIDB4MWUsIDB4MDQsIDB4MWYsCisgIDB4NTUsIDB4NjcsIDB4NDIsIDB4ODAsIDB4OGEsIDB4YzYsIDB4NzEsIDB4ZGIsIDB4MWUsIDB4MzcsIDB4NmQsIDB4MTYsCisgIDB4ZmIsIDB4MGQsIDB4YWUsIDB4MzUsIDB4YmEsIDB4MzAsIDB4M2MsIDB4Y2EsIDB4NDMsIDB4MjgsIDB4ZDcsIDB4M2EsCisgIDB4YmMsIDB4NTQsIDB4YTMsIDB4ZGUsIDB4YTUsIDB4MWYsIDB4MTUsIDB4MTIsIDB4NDksIDB4ZjQsIDB4ZDQsIDB4YWUsCisgIDB4YmEsIDB4NmEsIDB4OGEsIDB4MjgsIDB4MDIsIDB4OGEsIDB4MjgsIDB4YTAsIDB4MTEsIDB4MzgsIDB4Y2IsIDB4ZjEsCisgIDB4MmMsIDB4NWYsIDB4ZjYsIDB4YWEsIDB4ZDksIDB4ZjcsIDB4ZTIsIDB4OWUsIDB4ZTksIDB4MTMsIDB4OGMsIDB4YmYsCisgIDB4MTIsIDB4YzUsIDB4ZmYsIDB4MDAsIDB4NmEsIDB4YWQsIDB4OWYsIDB4N2UsIDB4MjksIDB4ZWUsIDB4ODAsIDB4YzEsCisgIDB4ZWYsIDB4ZGQsIDB4MTQsIDB4MWEsIDB4MmEsIDB4NTEsIDB4NTYsIDB4Y2MsIDB4ZDIsIDB4NjcsIDB4MWMsIDB4N2UsCisgIDB4NDcsIDB4YjIsIDB4ZWYsIDB4YTIsIDB4MjQsIDB4N2YsIDB4MDEsIDB4YTcsIDB4M2EsIDB4NGMsIDB4ZTMsIDB4OGYsCisgIDB4YzgsIDB4ZjYsIDB4NWQsIDB4ZjQsIDB4NDQsIDB4OGYsIDB4ZTAsIDB4MzUsIDB4MDUsIDB4ODYsIDB4ZjgsIDB4ZGYsCisgIDB4MTcsIDB4NmYsIDB4ZTYsIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTYsIDB4YjgsIDB4ZGYsIDB4MTcsIDB4NmYsIDB4ZTYsCisgIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTAsIDB4MDUsIDB4MTQsIDB4NTYsIDB4MDksIDB4M2IsIDB4ZWUsIDB4YTAsIDB4MzMsCisgIDB4NTgsIDB4MmEsIDB4ZDcsIDB4N2QsIDB4MjgsIDB4ZTcsIDB4M2MsIDB4NDgsIDB4YzMsIDB4ZjAsIDB4ZDcsIDB4NTEsCisgIDB4MTYsIDB4ZjUsIDB4NzcsIDB4NDcsIDB4YmEsIDB4MmUsIDB4ZmUsIDB4NDIsIDB4ZGIsIDB4MTUsIDB4YjUsIDB4NDgsCisgIDB4OTgsIDB4ZjEsIDB4ZjAsIDB4MDksIDB4NjUsIDB4YjAsIDB4NTYsIDB4NzcsIDB4ZDMsIDB4YTksIDB4MDAsIDB4N2EsCisgIDB4ZTksIDB4NjQsIDB4ZTQsIDB4MWMsIDB4NTYsIDB4Y2MsIDB4NTUsIDB4YzksIDB4OGMsIDB4ZTMsIDB4NGMsIDB4ZTEsCisgIDB4MTYsIDB4YzUsIDB4NzQsIDB4ZjcsIDB4NGYsIDB4MjEsIDB4NDgsIDB4N2EsIDB4NjIsIDB4ODcsIDB4ZmIsIDB4MzgsCisgIDB4OGQsIDB4YWIsIDB4NDksIDB4M2YsIDB4ZWYsIDB4NTYsIDB4M2QsIDB4OTQsIDB4MDUsIDB4OGQsIDB4N2QsIDB4YmQsCisgIDB4NWEsIDB4NmMsIDB4MzYsIDB4YzcsIDB4NmUsIDB4NzcsIDB4YmIsIDB4OTQsIDB4NGIsIDB4NmMsIDB4MjYsIDB4NDYsCisgIDB4ZGMsIDB4OTEsIDB4MjksIDB4ZDQsIDB4YjYsIDB4ODQsIDB4ZmYsIDB4MDAsIDB4YzQsIDB4YTIsIDB4MDUsIDB4NTcsCisgIDB4NmIsIDB4ZTIsIDB4ZTQsIDB4OGIsIDB4ZmEsIDB4OGIsIDB4M2MsIDB4MzQsIDB4YzIsIDB4YWYsIDB4MTksIDB4NjAsCisgIDB4M2IsIDB4ZDUsIDB4YzUsIDB4ZDEsIDB4ZWUsIDB4N2QsIDB4YjgsIDB4NmIsIDB4ZDAsIDB4ZmIsIDB4YzMsIDB4NmIsCisgIDB4ZWIsIDB4ZmEsIDB4MDksIDB4NTcsIDB4YjYsIDB4YmEsIDB4YWMsIDB4N2MsIDB4MWQsIDB4YzcsIDB4ZDMsIDB4NzYsCisgIDB4NjYsIDB4ZmYsIDB4MDAsIDB4OTcsIDB4Y2YsIDB4YjgsIDB4NjYsIDB4YjcsIDB4YzYsIDB4YmEsIDB4YjcsIDB4MmEsCisgIDB4ZjIsIDB4YjAsIDB4YjYsIDB4NTksIDB4M2YsIDB4ZWMsIDB4YTMsIDB4YTQsIDB4MDYsIDB4OWIsIDB4MWYsIDB4ZjAsCisgIDB4OTMsIDB4ZWIsIDB4YWIsIDB4MTksIDB4MjksIDB4NGEsIDB4M2MsIDB4ZDQsIDB4ODAsIDB4MDAsIDB4MWQsIDB4MDAsCisgIDB4MWQsIDB4MDUsIDB4MDEsIDB4NTYsIDB4MWMsIDB4M2IsIDB4ODksIDB4YjksIDB4NjcsIDB4ZmEsIDB4ZWIsIDB4OWQsCisgIDB4MzMsIDB4NjIsIDB4ODAsIDB4YjEsIDB4ZTcsIDB4ZGIsIDB4MzEsIDB4NTYsIDB4OTQsIDB4ZDIsIDB4ZDQsIDB4MzUsCisgIDB4ZjAsIDB4NTcsIDB4MmQsIDB4Y2QsIDB4YjksIDB4ZWQsIDB4ZTQsIDB4NGEsIDB4MzcsIDB4NGMsIDB4MTgsIDB4OGYsCisgIDB4MGEsIDB4MzgsIDB4NzcsIDB4OGIsIDB4YzgsIDB4MTMsIDB4MmQsIDB4MzgsIDB4YTUsIDB4YmMsIDB4NGUsIDB4ZWYsCisgIDB4MzMsIDB4NjQsIDB4YTQsIDB4YzksIDB4OTAsIDB4NGYsIDB4YTQsIDB4YmEsIDB4ZTksIDB4NTIsIDB4ZjcsIDB4ZjUsCisgIDB4ZDMsIDB4YTgsIDB4MDMsIDB4NTQsIDB4NmYsIDB4YzMsIDB4NTQsIDB4MDcsIDB4MGQsIDB4ZGEsIDB4YzksIDB4NjcsCisgIDB4YmIsIDB4YjEsIDB4ZTQsIDB4ZjcsIDB4NmIsIDB4NTQsIDB4MWIsIDB4ODMsIDB4M2EsIDB4ZDcsIDB4NjcsIDB4MmEsCisgIDB4M2EsIDB4MWQsIDB4NGUsIDB4YmQsIDB4MWEsIDB4NTAsIDB4MjIsIDB4YWEsIDB4OWMsIDB4YjMsIDB4MGQsIDB4NzcsCisgIDB4ODYsIDB4MTIsIDB4M2YsIDB4OTYsIDB4ZGMsIDB4MzEsIDB4YjcsIDB4M2UsIDB4ZDQsIDB4MTYsIDB4MTcsIDB4Y2YsCisgIDB4N2QsIDB4YzYsIDB4ZTIsIDB4MjgsIDB4ZjksIDB4M2MsIDB4ZDgsIDB4ZmYsIDB4MDAsIDB4OWUsIDB4ZWIsIDB4MmQsCisgIDB4MWUsIDB4ODgsIDB4N2QsIDB4MDMsIDB4YTgsIDB4ZTUsIDB4ZDAsIDB4NTAsIDB4MDQsIDB4NmIsIDB4NzUsIDB4NzAsCisgIDB4YmMsIDB4ZjMsIDB4NmMsIDB4YjQsIDB4YjcsIDB4NWQsIDB4NzEsIDB4MDgsIDB4NmQsIDB4MDAsIDB4OTUsIDB4MjksCisgIDB4NmEsIDB4ZDAsIDB4NDgsIDB4MWUsIDB4MjQsIDB4ZjgsIDB4NTcsIDB4MDUsIDB4OWEsIDB4ZjksIDB4NjUsIDB4YmQsCisgIDB4YTEsIDB4YzcsIDB4YWMsIDB4ZDcsIDB4NjgsIDB4MTcsIDB4MjQsIDB4MzQsIDB4YTAsIDB4OTcsIDB4MTUsIDB4MTYsCisgIDB4NGEsIDB4MWQsIDB4NGEsIDB4MGYsIDB4YTAsIDB4ZjIsIDB4OTMsIDB4YTMsIDB4NDAsIDB4MTgsIDB4Y2QsIDB4ZjIsCisgIDB4ZDcsIDB4OTEsIDB4ZTMsIDB4ZjAsIDB4NmYsIDB4YjYsIDB4NTksIDB4YWQsIDB4Y2MsIDB4YjcsIDB4NGQsIDB4NjQsCisgIDB4M2MsIDB4YzMsIDB4ZTgsIDB4ZWUsIDB4NTIsIDB4NGYsIDB4ZDgsIDB4N2MsIDB4MDgsIDB4M2QsIDB4YzQsIDB4MWEsCisgIDB4OTAsIDB4ZDksIDB4MWIsIDB4ZDgsIDB4YWEsIDB4OTMsIDB4MDcsIDB4ZTUsIDB4ZTEsIDB4ZDcsIDB4MTYsIDB4YWUsCisgIDB4NTgsIDB4MzMsIDB4ZGUsIDB4ZjMsIDB4NjAsIDB4YzksIDB4OWMsIDB4NzYsIDB4ZWQsIDB4OGYsIDB4MWUsIDB4ZTQsCisgIDB4MzUsIDB4MjMsIDB4YmUsIDB4NTQsIDB4NTEsIDB4ZDMsIDB4NDMsIDB4YWYsIDB4YmUsIDB4YTQsIDB4MGYsIDB4MDUsCisgIDB4MmIsIDB4ZDEsIDB4NTYsIDB4ODUsIDB4ZjIsIDB4MWIsIDB4ZDcsIDB4MWIsIDB4MzQsIDB4ZWIsIDB4N2MsIDB4NzksCisgIDB4OGUsIDB4YzIsIDB4N2EsIDB4NGMsIDB4NzcsIDB4MTksIDB4NDQsIDB4OTYsIDB4YzYsIDB4ZDYsIDB4Y2EsIDB4OTQsCisgIDB4OTIsIDB4MDIsIDB4YzAsIDB4ZjQsIDB4OGQsIDB4ZWYsIDB4ZWEsIDB4YTAsIDB4MjksIDB4ZDgsIDB4OTksIDB4MmQsCisgIDB4YzIsIDB4ZTUsIDB4OTUsIDB4ZTQsIDB4MTcsIDB4MWMsIDB4NmMsIDB4YjcsIDB4MmEsIDB4ZmIsIDB4OTAsIDB4M2EsCisgIDB4OWIsIDB4NmQsIDB4ODgsIDB4MmMsIDB4MDUsIDB4YjcsIDB4MGUsIDB4ZGYsIDB4MTQsIDB4YWQsIDB4MGUsIDB4NGUsCisgIDB4NzAsIDB4OGUsIDB4ZTYsIDB4OGIsIDB4Y2EsIDB4NzgsIDB4YTQsIDB4N2YsIDB4NDgsIDB4NDIsIDB4MTIsIDB4MzcsCisgIDB4YmQsIDB4OGIsIDB4NWYsIDB4MGQsIDB4YzcsIDB4NjAsIDB4ZTMsIDB4MTgsIDB4ZTQsIDB4NWIsIDB4MzQsIDB4MTIsCisgIDB4YjUsIDB4YTEsIDB4OTAsIDB4NTQsIDB4ZWIsIDB4Y2UsIDB4MWQsIDB4YjgsIDB4ZmIsIDB4YWEsIDB4M2MsIDB4Y2UsCisgIDB4M2EsIDB4YjMsIDB4ZTIsIDB4YjUsIDB4MjgsIDB4OTUsIDB4MTMsIDB4ZTksIDB4M2UsIDB4OGQsIDB4MGEsIDB4ODksCisgIDB4ZTEsIDB4NmUsIDB4MDEsIDB4NjksIDB4YzAsIDB4YWMsIDB4MjksIDB4ODMsIDB4MGQsIDB4YzcsIDB4MjYsIDB4NGQsCisgIDB4NzUsIDB4MGQsIDB4ODksIDB4OTMsIDB4ZGUsIDB4ZmMsIDB4YTQsIDB4ODIsIDB4ODQsIDB4ZjIsIDB4YTAsIDB4N2EsCisgIDB4MTIsIDB4ODQsIDB4OGUsIDB4ODksIDB4NDAsIDB4ZTgsIDB4M2EsIDB4OWUsIDB4YTQsIDB4OTIsIDB4NWIsIDB4YzcsCisgIDB4NDEsIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NDUsIDB4MTQsCisgIDB4NTAsIDB4MDgsIDB4OWMsIDB4NjUsIDB4ZjgsIDB4OTYsIDB4MmYsIDB4ZmIsIDB4NTUsIDB4NmMsIDB4ZmIsIDB4ZjEsCisgIDB4NGYsIDB4NzQsIDB4ODksIDB4YzYsIDB4NWYsIDB4ODksIDB4NjIsIDB4ZmYsIDB4MDAsIDB4YjUsIDB4NTYsIDB4Y2YsCisgIDB4YmYsIDB4MTQsIDB4ZjcsIDB4NDAsIDB4NzksIDB4NTEsIDB4ZWIsIDB4NDUsIDB4NjQsIDB4OGQsIDB4OWUsIDB4ZjMsCisgIDB4NDUsIDB4MGEsIDB4YjQsIDB4ZjIsIDB4NjYsIDB4OTMsIDB4MzgsIDB4ZTMsIDB4ZjIsIDB4M2QsIDB4OTcsIDB4N2QsCisgIDB4MTEsIDB4MjMsIDB4ZjgsIDB4MGQsIDB4MzksIDB4ZDIsIDB4NjcsIDB4MWMsIDB4N2UsIDB4NDcsIDB4YjIsIDB4ZWYsCisgIDB4YTIsIDB4MjQsIDB4N2YsIDB4MDEsIDB4YTEsIDB4NjEsIDB4YmUsIDB4MzcsIDB4YzUsIDB4ZGIsIDB4ZjksIDB4ODMsCisgIDB4ZWMsIDB4YWYsIDB4NjQsIDB4ZmIsIDB4MmEsIDB4MmUsIDB4ZjUsIDB4N2IsIDB4YjUsIDB4ZTMsIDB4YjgsIDB4ZWIsCisgIDB4ZDcsIDB4OWIsIDB4ZDQsIDB4ZTYsIDB4NjAsIDB4ZGIsIDB4ZTIsIDB4MzIsIDB4MWMsIDB4N2QsIDB4ZjcsIDB4NGUsCisgIDB4OTIsIDB4ODEsIDB4ZDAsIDB4MGYsIDB4NTksIDB4MjQsIDB4OTAsIDB4MDAsIDB4MWQsIDB4NDksIDB4MjAsIDB4MGQsCisgIDB4OTMsIDB4NTUsIDB4ZWEsIDB4YTYsIDB4NzEsIDB4MDMsIDB4ODksIDB4NDAsIDB4YTIsIDB4ZDYsIDB4NjQsIDB4NjAsCisgIDB4OTgsIDB4YWEsIDB4ZjUsIDB4YjksIDB4NmYsIDB4MzcsIDB4ZmUsIDB4OTgsIDB4OTgsIDB4OGYsIDB4MWUsIDB4Y2QsCisgIDB4YjMsIDB4ZDIsIDB4MzIsIDB4NGYsIDB4ODIsIDB4OTUsIDB4YjUsIDB4ZWIsIDB4NDQsIDB4MDQsIDB4ZWUsIDB4ODAsCisgIDB4NjAsIDB4Y2UsIDB4YjgsIDB4OWQsIDB4OGQsIDB4NjIsIDB4OTMsIDB4NWIsIDB4YjUsIDB4MjgsIDB4Y2EsIDB4YmMsCisgIDB4ZGYsIDB4OWUsIDB4ZDgsIDB4NjIsIDB4Y2IsIDB4NjksIDB4NmIsIDB4Y2EsIDB4NjYsIDB4YjksIDB4ZWIsIDB4MjgsCisgIDB4MDcsIDB4Y2MsIDB4NGYsIDB4ZWIsIDB4MmMsIDB4YTQsIDB4N2EsIDB4ZmEsIDB4NTQsIDB4MGYsIDB4YjksIDB4NWMsCisgIDB4NWIsIDB4Y2QsIDB4MDAsIDB4NTUsIDB4ZWEsIDB4ZjEsIDB4MTMsIDB4MDEsIDB4YjQsIDB4M2EsIDB4MzYsIDB4NjEsCisgIDB4NWEsIDB4MDgsIDB4OTMsIDB4NzIsIDB4NTIsIDB4NGYsIDB4ZTYsIDB4YjksIDB4MjEsIDB4NjMsIDB4OTEsIDB4YTUsCisgIDB4NmIsIDB4YzUsIDB4YjQsIDB4YTgsIDB4OGQsIDB4ZmMsIDB4MmEsIDB4NzMsIDB4YzEsIDB4ZjAsIDB4YWMsIDB4NWYsCisgIDB4MGMsIDB4YjcsIDB4MTgsIDB4OTgsIDB4ZTUsIDB4YTEsIDB4ODgsIDB4N2QsIDB4YTcsIDB4NTcsIDB4ZGYsIDB4ZDcsCisgIDB4MzMsIDB4ZjIsIDB4MTUsIDB4YmQsIDB4OTUsIDB4M2EsIDB4ZTksIDB4ZGEsIDB4ZGMsIDB4NTYsIDB4YzksIDB4ZWEsCisgIDB4YTIsIDB4NjksIDB4ODcsIDB4NDIsIDB4ODAsIDB4NTYsIDB4YzEsIDB4YjAsIDB4MGMsIDB4NGYsIDB4MGMsIDB4NjksCisgIDB4YzMsIDB4NjAsIDB4YjQsIDB4MzIsIDB4Y2MsIDB4YjcsIDB4YjYsIDB4NjQsIDB4NGQsIDB4NzQsIDB4OTcsIDB4NjUsCisgIDB4NDgsIDB4NTEsIDB4ZWEsIDB4NGIsIDB4OGYsIDB4MmIsIDB4NmIsIDB4NTYsIDB4Y2YsIDB4YTQsIDB4ZWIsIDB4ZDAsCisgIDB4MDUsIDB4NzcsIDB4ZTUsIDB4ZjksIDB4NTYsIDB4M2IsIDB4ODgsIDB4ZGEsIDB4Y2QsIDB4Y2YsIDB4MjQsIDB4YmMsCisgIDB4NDQsIDB4YjYsIDB4NDUsIDB4ZGYsIDB4MmEsIDB4NTYsIDB4ZjIsIDB4ZjQsIDB4YTcsIDB4MTUsIDB4ZmEsIDB4MjgsCisgIDB4NDgsIDB4ZjMsIDB4OTYsIDB4YWYsIDB4ZDUsIDB4NDgsIDB4MjQsIDB4ZmEsIDB4MmIsIDB4YjIsIDB4ZjAsIDB4ZGQsCisgIDB4Y2QsIDB4ZDQsIDB4NDcsIDB4NGQsIDB4YWUsIDB4NTQsIDB4NzgsIDB4ZWEsIDB4MTIsIDB4NWIsIDB4NTMsIDB4ZTUsCisgIDB4ZTYsIDB4NGIsIDB4OWMsIDB4Y2MsIDB4ODMsIDB4ZTcsIDB4YTUsIDB4M2EsIDB4NTAsIDB4ZDIsIDB4ODgsIDB4ZWUsCisgIDB4MjcsIDB4NjAsIDB4N2EsIDB4MGQsIDB4N2IsIDB4OTMsIDB4NmYsIDB4ODEsIDB4MmUsIDB4NWMsIDB4NjksIDB4NzIsCisgIDB4YTAsIDB4YzYsIDB4N2EsIDB4NGMsIDB4NTUsIDB4MTUsIDB4NDcsIDB4NzUsIDB4YzYsIDB4OTIsIDB4YTUsIDB4YjIsCisgIDB4NGYsIDB4NDIsIDB4NTIsIDB4NDgsIDB4ZGEsIDB4NzcsIDB4ZWEsIDB4YTAsIDB4MTIsIDB4NzEsIDB4OWMsIDB4ZGYsCisgIDB4MjcsIDB4Y2IsIDB4MmYsIDB4ZDEsIDB4OTUsIDB4NjMsIDB4YzMsIDB4MjYsIDB4NWIsIDB4ZjEsIDB4OTQsIDB4YTgsCisgIDB4OTksIDB4MTcsIDB4NGIsIDB4ZGUsIDB4ZTMsIDB4M2IsIDB4MjEsIDB4M2EsIDB4ZTgsIDB4MjMsIDB4YzcsIDB4ZjgsCisgIDB4N2QsIDB4NDksIDB4MDcsIDB4OTksIDB4Y2UsIDB4NTEsIDB4YWYsIDB4MGEsIDB4NzEsIDB4OWIsIDB4NjksIDB4ODksCisgIDB4MzIsIDB4ZWQsIDB4NmYsIDB4YmIsIDB4M2MsIDB4NWYsIDB4MTIsIDB4NjAsIDB4MDcsIDB4N2IsIDB4MDAsIDB4ODcsCisgIDB4OTYsIDB4OTQsIDB4N2IsIDB4ZTIsIDB4NDIsIDB4NTQsIDB4NTQsIDB4OTAsIDB4NzQsIDB4YWUsIDB4ODMsIDB4YTcsCisgIDB4MzAsIDB4M2EsIDB4ZWIsIDB4NTAsIDB4MzksIDB4N2YsIDB4MTEsIDB4NzEsIDB4MWMsIDB4NWUsIDB4NGYsIDB4OTAsCisgIDB4NGUsIDB4YjksIDB4ZjksIDB4NGQsIDB4ZDUsIDB4NjMsIDB4NmQsIDB4ZGIsIDB4MjAsIDB4YjYsIDB4NjQsIDB4Y2MsCisgIDB4NzAsIDB4ZWIsIDB4NjMsIDB4NGQsIDB4MjMsIDB4NmEsIDB4MDMsIDB4ZjUsIDB4OTUsIDB4YTQsIDB4ZmEsIDB4ZTksCisgIDB4MzIsIDB4ZTMsIDB4OTYsIDB4NzEsIDB4MTMsIDB4MjYsIDB4ZGEsIDB4MmQsIDB4YjEsIDB4YTMsIDB4NjEsIDB4NTYsCisgIDB4ZTUsIDB4N2YsIDB4NGQsIDB4MjQsIDB4MjIsIDB4NjUsIDB4YzUsIDB4NDMsIDB4ZDQsIDB4ZDgsIDB4M2QsIDB4OTMsCisgIDB4NDcsIDB4ZTcsIDB4MTcsIDB4MDgsIDB4ZjQsIDB4NzgsIDB4NTUsIDB4ZTEsIDB4NGUsIDB4NTMsIDB4ZjAsIDB4YTIsCisgIDB4OTMsIDB4YTksIDB4MTgsIDB4NzgsIDB4OTksIDB4NjcsIDB4NjQsIDB4NzksIDB4MDUsIDB4OGYsIDB4MWEsIDB4YjUsCisgIDB4YWUsIDB4ZTUsIDB4N2YsIDB4YmEsIDB4YzIsIDB4YjUsIDB4NDIsIDB4NmYsIDB4YmQsIDB4ZTksIDB4NmYsIDB4YTUsCisgIDB4YjQsIDB4N2IsIDB4MDEsIDB4MjcsIDB4YTksIDB4ZjUsIDB4MGUsIDB4YjUsIDB4NDAsIDB4NjYsIDB4OWYsIDB4ODUsCisgIDB4MzUsIDB4YWQsIDB4NGQsIDB4YjgsIDB4ZDYsIDB4MDEsIDB4NjYsIDB4NTUsIDB4ZGYsIDB4NWMsIDB4YzksIDB4ZjcsCisgIDB4NDIsIDB4NjYsIDB4ZGEsIDB4OGUsIDB4MDgsIDB4M2EsIDB4MjUsIDB4MjgsIDB4MWUsIDB4N2EsIDB4ODcsIDB4YjcsCisgIDB4OTMsIDB4ZWIsIDB4MTUsIDB4M2EsIDB4Y2UsIDB4MDMsIDB4ODksIDB4Y2MsIDB4ZjIsIDB4YTEsIDB4OTQsIDB4NDQsCisgIDB4OTMsIDB4OTIsIDB4YmIsIDB4M2EsIDB4M2EsIDB4YTMsIDB4YzksIDB4OWQsIDB4NzUsIDB4NzgsIDB4YzgsIDB4OTIsCisgIDB4OTQsIDB4MmIsIDB4YzUsIDB4YjUsIDB4MmIsIDB4YTMsIDB4NWEsIDB4ZWYsIDB4MDEsIDB4MDEsIDB4MzUsIDB4ZjIsCisgIDB4YjcsIDB4MTAsIDB4MzAsIDB4ZWIsIDB4Y2YsIDB4ZTAsIDB4ZmYsIDB4MDAsIDB4YzQsIDB4OTgsIDB4ZWUsIDB4YTUsCisgIDB4NWUsIDB4ZTksIDB4NjIsIDB4ZDcsIDB4MjUsIDB4MTUsIDB4NDIsIDB4OTgsIDB4YTYsIDB4ZDIsIDB4YTIsIDB4ZTMsCisgIDB4NDAsIDB4OGUsIDB4NjEsIDB4ZDQsIDB4NjksIDB4MGYsIDB4YTAsIDB4MTEsIDB4ZDQsIDB4NjgsIDB4ZjUsIDB4MDQsCisgIDB4NmIsIDB4N2QsIDB4MzQsIDB4OWQsIDB4MTksIDB4NTMsIDB4NmIsIDB4NTEsIDB4NDgsIDB4NTYsIDB4NTUsIDB4MTMsCisgIDB4ZDIsIDB4MzYsIDB4ZTQsIDB4NTcsIDB4MmMsIDB4ZWIsIDB4ODgsIDB4NmUsIDB4ODksIDB4MTksIDB4OWQsIDB4ZmUsCisgIDB4NmMsIDB4ODgsIDB4MGIsIDB4MjEsIDB4NGQsIDB4YzAsIDB4MWUsIDB4ZjEsIDB4MTEsIDB4NDMsIDB4N2YsIDB4OWEsCisgIDB4ZDIsIDB4MDEsIDB4MmUsIDB4ZmIsIDB4NDAsIDB4NzcsIDB4NWUsIDB4MjQsIDB4NzcsIDB4ZDMsIDB4OWUsIDB4MjYsCisgIDB4ZmMsIDB4ZGMsIDB4MzIsIDB4NzQsIDB4NWMsIDB4YjYsIDB4ZDcsIDB4ZGEsIDB4NDksIDB4NTUsIDB4OTUsIDB4YjAsCisgIDB4NmUsIDB4NmQsIDB4MzQsIDB4OTQsIDB4YTQsIDB4M2QsIDB4NmQsIDB4ZDAsIDB4NGIsIDB4ODgsIDB4M2EsIDB4NTEsCisgIDB4MGEsIDB4MjgsIDB4MDAsIDB4MmQsIDB4MDMsIDB4OTksIDB4NDQsIDB4MTQsIDB4N2MsIDB4MTQsIDB4NmUsIDB4YmEsCisgIDB4MjAsIDB4NDUsIDB4ODEsIDB4MjEsIDB4YmYsIDB4MmQsIDB4NjYsIDB4NDIsIDB4NjYsIDB4MjUsIDB4ZDQsIDB4MjUsCisgIDB4ZTUsIDB4M2MsIDB4MDksIDB4MjksIDB4MjksIDB4NTAsIDB4MDQsIDB4MjksIDB4NDQsIDB4ZTgsIDB4OWUsIDB4ODQsCisgIDB4NjksIDB4NGIsIDB4ZWMsIDB4ZmUsIDB4NzksIDB4YTYsIDB4MmIsIDB4MjUsIDB4YjgsIDB4YjgsIDB4YTYsIDB4YTQsCisgIDB4MDYsIDB4MTAsIDB4ODgsIDB4YTEsIDB4YzQsIDB4ZWUsIDB4NDMsIDB4OWMsIDB4OWMsIDB4YmQsIDB4N2YsIDB4NDUsCisgIDB4NGEsIDB4MWMsIDB4YmMsIDB4ZGUsIDB4YjQsIDB4MjUsIDB4NjQsIDB4ZWYsIDB4ZjIsIDB4ODYsIDB4YjcsIDB4OGQsCisgIDB4MTQsIDB4ZDYsIDB4MGUsIDB4NzksIDB4NTYsIDB4NzksIDB4YzksIDB4NmMsIDB4NzEsIDB4NWIsIDB4MTksIDB4NmYsCisgIDB4M2YsIDB4ZTEsIDB4ZmIsIDB4NGUsIDB4ZDgsIDB4YTYsIDB4MzYsIDB4OWIsIDB4YTQsIDB4NjIsIDB4ZGQsIDB4ZGIsCisgIDB4MWYsIDB4OWUsIDB4ZGEsIDB4YjYsIDB4MWIsIDB4OTIsIDB4ODEsIDB4Y2UsIDB4ZDIsIDB4YzIsIDB4YmYsIDB4NDEsCisgIDB4NDAsIDB4ZjIsIDB4OWYsIDB4NGEsIDB4NTYsIDB4NmEsIDB4NTMsIDB4ODUsIDB4OTksIDB4NmIsIDB4MTksIDB4Y2UsCisgIDB4MDUsIDB4NmIsIDB4YzksIDB4MWEsIDB4NmIsIDB4YjAsIDB4NzIsIDB4NGIsIDB4NWMsIDB4YjIsIDB4YTMsIDB4OWUsCisgIDB4ZjYsIDB4MjQsIDB4MjAsIDB4OTQsIDB4M2EsIDB4ZDksIDB4MWYsIDB4YWEsIDB4YjQsIDB4YTgsIDB4NzUsIDB4ZjAsCisgIDB4ZDEsIDB4ZjEsIDB4YTQsIDB4ZWUsIDB4MDksIDB4NWMsIDB4MDYsIDB4M2YsIDB4NzMsIDB4OWIsIDB4YzMsIDB4NDksCisgIDB4NGUsIDB4MjgsIDB4YjEsIDB4MTUsIDB4MDYsIDB4NzUsIDB4ODUsIDB4NmIsIDB4M2QsIDB4NWMsIDB4ODQsIDB4YTUsCisgIDB4NzksIDB4Y2MsIDB4ZWYsIDB4YzQsIDB4YjIsIDB4ZTEsIDB4ZDcsIDB4N2YsIDB4YzAsIDB4NTIsIDB4M2QsIDB4MTUsCisgIDB4YWEsIDB4MTIsIDB4ODcsIDB4MGQsIDB4NzgsIDB4ZDgsIDB4ZmMsIDB4MjcsIDB4MTMsIDB4ZDksIDB4ZTMsIDB4MTksCisgIDB4ZTQsIDB4OGUsIDB4ZGEsIDB4MmEsIDB4ODcsIDB4YzAsIDB4OGIsIDB4NzYsIDB4MDgsIDB4ZjcsIDB4YzQsIDB4MWYsCisgIDB4NDAsIDB4N2QsIDB4MjksIDB4ZTYsIDB4MWYsIDB4YWMsIDB4OTIsIDB4M2MsIDB4NmIsIDB4OGUsIDB4NTEsIDB4NzEsCisgIDB4NzgsIDB4NjcsIDB4NjQsIDB4NjQsIDB4YTQsIDB4YjIsIDB4OGIsIDB4N2MsIDB4NzQsIDB4MTQsIDB4NTYsIDB4MTIsCisgIDB4NzYsIDB4OTAsIDB4NmIsIDB4MzUsIDB4NTIsIDB4YzEsIDB4NDUsIDB4MTQsIDB4NTAsIDB4MDUsIDB4MTQsIDB4NTEsCisgIDB4NDAsIDB4MWQsIDB4NjgsIDB4YTIsIDB4OGEsIDB4MDEsIDB4MTMsIDB4OGMsIDB4YmYsIDB4MTIsIDB4YzUsIDB4ZmYsCisgIDB4MDAsIDB4NmEsIDB4YWQsIDB4OWYsIDB4N2UsIDB4MjksIDB4ZWUsIDB4OTEsIDB4MzgsIDB4Y2IsIDB4ZjEsIDB4MmMsCisgIDB4NWYsIDB4ZjYsIDB4YWEsIDB4ZDksIDB4ZjcsIDB4ZTIsIDB4OWUsIDB4ZTgsIDB4MDIsIDB4OGEsIDB4ZjIsIDB4YTIsCisgIDB4NDEsIDB4ZTgsIDB4MDcsIDB4ZDYsIDB4NzUsIDB4NDUsIDB4MDEsIDB4ZWEsIDB4OTMsIDB4MzgsIDB4ZTMsIDB4YmYsCisgIDB4YzQsIDB4ZmUsIDB4NWMsIDB4M2YsIDB4ZjQsIDB4ODksIDB4MWEsIDB4ZmYsIDB4MDAsIDB4OTAsIDB4ZDMsIDB4OWQsCisgIDB4MjYsIDB4NzEsIDB4YzcsIDB4ZTQsIDB4N2IsIDB4MmUsIDB4ZmEsIDB4MjIsIDB4NDcsIDB4ZjAsIDB4MWEsIDB4MDIsCisgIDB4YmUsIDB4OWYsIDB4N2YsIDB4NjMsIDB4MjcsIDB4ZTIsIDB4NTIsIDB4ZmQsIDB4ZDIsIDB4NjEsIDB4NGYsIDB4ZGIsCisgIDB4YWMsIDB4MzcsIDB4MzcsIDB4MmQsIDB4YjYsIDB4NzgsIDB4YWIsIDB4ZDcsIDB4NjYsIDB4NjcsIDB4MzAsIDB4Y2EsCisgIDB4NWMsIDB4N2UsIDB4NjMsIDB4YTksIDB4M2QsIDB4ZTUsIDB4MWMsIDB4ZTgsIDB4NDMsIDB4NjAsIDB4ZWYsIDB4NDQsCisgIDB4OTUsIDB4MGUsIDB4YTcsIDB4YTUsIDB4ZGIsIDB4MDUsIDB4OTYsIDB4ZDksIDB4OGEsIDB4ODQsIDB4YTAsIDB4YTgsCisgIDB4ODIsIDB4MzYsIDB4NTQsIDB4N2IsIDB4ZDQsIDB4NGYsIDB4NzksIDB4M2UsIDB4YjMsIDB4NWYsIDB4MzgsIDB4NzEsCisgIDB4MzYsIDB4MWMsIDB4Y2MsIDB4M2YsIDB4OGQsIDB4YjYsIDB4ZjksIDB4NjksIDB4OTgsIDB4ZDQsIDB4N2IsIDB4M2UsCisgIDB4NTAsIDB4ZmEsIDB4NmUsIDB4MmMsIDB4YWQsIDB4ZjAsIDB4N2IsIDB4MzYsIDB4NjcsIDB4MzIsIDB4Y2YsIDB4NjUsCisgIDB4MjUsIDB4YWUsIDB4ODAsIDB4ZWIsIDB4YjYsIDB4NjAsIDB4ODIsIDB4MGUsIDB4YmEsIDB4YjgsIDB4ZGEsIDB4NDcsCisgIDB4YTYsIDB4YWYsIDB4NWMsIDB4MTYsIDB4ZjAsIDB4YzUsIDB4ZGYsIDB4MWYsIDB4OGMsIDB4ZjMsIDB4MGYsIDB4MDcsCisgIDB4NTEsIDB4ZDksIDB4MjUsIDB4NmQsIDB4YWIsIDB4NDQsIDB4MTUsIDB4MzYsIDB4YTEsIDB4YjQsIDB4YWIsIDB4NDcsCisgIDB4YWYsIDB4NzEsIDB4ZjEsIDB4ZWIsIDB4NWEsIDB4ZTMsIDB4MzQsIDB4ZjIsIDB4YmEsIDB4MzMsIDB4MjcsIDB4MmMsCisgIDB4NTQsIDB4YzMsIDB4ZWEsIDB4ODYsIDB4MDIsIDB4NzUsIDB4ZTEsIDB4ZDIsIDB4YmMsIDB4YjgsIDB4ZTIsIDB4NWIsCisgIDB4NmQsIDB4NGIsIDB4NzEsIDB4NDksIDB4NDIsIDB4NTIsIDB4MzYsIDB4YTIsIDB4NGUsIDB4ODAsIDB4MWUsIDB4OTMsCisgIDB4NTQsIDB4MWYsIDB4MWMsIDB4N2YsIDB4MDgsIDB4ODUsIDB4NjEsIDB4YjksIDB4MTQsIDB4OWMsIDB4NGYsIDB4MTQsCisgIDB4YzUsIDB4OWYsIDB4YmUsIDB4NWUsIDB4NTksIDB4MjEsIDB4YjcsIDB4NjQsIDB4M2MsIDB4NGEsIDB4MjIsIDB4YjQsCisgIDB4YjIsIDB4OTAsIDB4YWUsIDB4NWYsIDB4MzcsIDB4NmEsIDB4NzAsIDB4ODAsIDB4NDYsIDB4YzAsIDB4ZTUsIDB4MDMsCisgIDB4N2EsIDB4ZGYsIDB4N2QsIDB4N2MsIDB4NzcsIDB4YzYsIDB4ZWUsIDB4MjksIDB4NzEsIDB4NDcsIDB4MjksIDB4YmIsCisgIDB4NDgsIDB4YjQsIDB4ZTYsIDB4MTcsIDB4ZjksIDB4MDksIDB4OGUsIDB4OWQsIDB4MWYsIDB4MjAsIDB4OGIsIDB4ZWYsCisgIDB4NTEsIDB4OGEsIDB4NDgsIDB4ZDgsIDB4ZjMsIDB4NTIsIDB4N2MsIDB4ZWUsIDB4ODQsIDB4N2MsIDB4MjIsIDB4YTIsCisgIDB4M2IsIDB4YWIsIDB4MzQsIDB4OGQsIDB4MzIsIDB4OGYsIDB4YmUsIDB4YWYsIDB4M2MsIDB4NjAsIDB4YzcsIDB4M2MsCisgIDB4YjYsIDB4NDUsIDB4YWYsIDB4MTEsIDB4NjIsIDB4NDYsIDB4NjMsIDB4NzUsIDB4NjAsIDB4ZjIsIDB4YmMsIDB4ZDUsCisgIDB4YWQsIDB4NDksIDB4MzEsIDB4ZDgsIDB4NTcsIDB4ODcsIDB4NmIsIDB4MjEsIDB4NDcsIDB4YjMsIDB4NDcsIDB4NzEsCisgIDB4ZTgsIDB4MGEsIDB4OTUsIDB4ZWEsIDB4YTUsIDB4NmIsIDB4YTMsIDB4YjksIDB4YjYsIDB4NDQsIDB4ZGIsIDB4YjIsCisgIDB4MzIsIDB4ZWMsIDB4OTUsIDB4MTgsIDB4ZmQsIDB4YWYsIDB4YmMsIDB4ZGIsIDB4YWMsIDB4OGUsIDB4OTYsIDB4N2MsCisgIDB4Y2YsIDB4NDMsIDB4ZDIsIDB4ZDQsIDB4MDMsIDB4ODcsIDB4YmYsIDB4NDQsIDB4MzYsIDB4MTAsIDB4M2QsIDB4YjUsCisgIDB4ZjMsIDB4NzcsIDB4ZTAsIDB4MjksIDB4NzQsIDB4NGIsIDB4NzksIDB4MTYsIDB4NGIsIDB4NjYsIDB4NWIsIDB4ODksCisgIDB4ZGMsIDB4ODgsIDB4OGQsIDB4NDksIDB4NDIsIDB4MDksIDB4ZTgsIDB4N2IsIDB4MzUsIDB4OTQsIDB4OWUsIDB4OWYsCisgIDB4ZmYsIDB4MDAsIDB4MjAsIDB4ZmUsIDB4ZWEsIDB4ZmEsIDB4MWIsIDB4ODksIDB4MzksIDB4MjYsIDB4M2YsIDB4ODksCisgIDB4ZGIsIDB4NWIsIDB4YmMsIDB4ZGUsIDB4ZDIsIDB4ZWMsIDB4YjcsIDB4YjksIDB4YmIsIDB4MmIsIDB4N2MsIDB4MDYsCisgIDB4OTMsIDB4ZGEsIDB4M2IsIDB4MjUsIDB4ZWYsIDB4MDAsIDB4ZGIsIDB4N2UsIDB4MmEsIDB4ZmQsIDB4NjMsIDB4ZGQsCisgIDB4ZWEsIDB4ZjEsIDB4ZWUsIDB4YTEsIDB4NDYsIDB4MWEsIDB4MzUsIDB4YjMsIDB4OGEsIDB4YmQsIDB4NTksIDB4ZWIsCisgIDB4ZDAsIDB4ODksIDB4MWMsIDB4NDIsIDB4ZGQsIDB4OGUsIDB4ZGIsIDB4NjEsIDB4MjksIDB4YWMsIDB4NzIsIDB4ZGMsCisgIDB4Y2MsIDB4NDYsIDB4MTUsIDB4ZDUsIDB4NmIsIDB4NmQsIDB4ODIsIDB4OTIsIDB4ZjEsIDB4ZmQsIDB4MjUsIDB4MmMsCisgIDB4OGQsIDB4YjgsIDB4NzcsIDB4ZTIsIDB4NDksIDB4ZjYsIDB4ZDQsIDB4ZDgsIDB4ZWYsIDB4ZGYsIDB4ZDUsIDB4ZWIsCisgIDB4ZmYsIDB4MDAsIDB4ZGYsIDB4ZmUsIDB4ZmEsIDB4ZDUsIDB4MjgsIDB4ZGUsIDB4NDcsIDB4YzcsIDB4NGIsIDB4YzUsCisgIDB4ZDEsIDB4MGIsIDB4NmUsIDB4MGUsIDB4MmYsIDB4OGMsIDB4MzIsIDB4ZTgsIDB4ZTcsIDB4OGYsIDB4NmQsIDB4OTgsCisgIDB4ZGIsIDB4YjMsIDB4MjYsIDB4MmQsIDB4MWUsIDB4MWMsIDB4YzgsIDB4NjgsIDB4MjksIDB4NDMsIDB4ZmIsIDB4OTMsCisgIDB4NTYsIDB4NzQsIDB4MWIsIDB4ZTIsIDB4ZDksIDB4ODcsIDB4MWUsIDB4M2QsIDB4ZDEsIDB4YjcsIDB4NWMsIDB4YmQsCisgIDB4YTUsIDB4MDksIDB4MTIsIDB4MjIsIDB4YzcsIDB4ODYsIDB4ZWIsIDB4NmEsIDB4ZTcsIDB4MDAsIDB4MTUsIDB4MjgsCisgIDB4MjEsIDB4Y2QsIDB4MjksIDB4MGQsIDB4ZjUsIDB4ZDgsIDB4NTIsIDB4YjQsIDB4M2MsIDB4MzcsIDB4YmEsIDB4ZWEsCisgIDB4ODUsIDB4NTgsIDB4YmQsIDB4OGUsIDB4NDksIDB4ZDMsIDB4OTcsIDB4MmMsIDB4NTIsIDB4Y2UsIDB4ZjgsIDB4ODMsCisgIDB4NzMsIDB4NGQsIDB4ZTksIDB4NzgsIDB4YTYsIDB4MDUsIDB4NmYsIDB4NjYsIDB4ZTcsIDB4N2IsIDB4NmQsIDB4YzAsCisgIDB4ZGMsIDB4YjksIDB4OTIsIDB4MTIsIDB4N2MsIDB4OTIsIDB4MGEsIDB4OTQsIDB4MzYsIDB4MTIsIDB4NzksIDB4N2MsCisgIDB4ZTcsIDB4NWQsIDB4ZDcsIDB4NWUsIDB4Y2QsIDB4MjAsIDB4OTEsIDB4ZTMsIDB4ZGMsIDB4NDUsIDB4NDIsIDB4NzEsCisgIDB4MWYsIDB4MGMsIDB4Y2QsIDB4ZWUsIDB4ZGMsIDB4MTAsIDB4YzksIDB4MjMsIDB4NjYsIDB4ZjcsIDB4MGIsIDB4Y2QsCisgIDB4ZGUsIDB4NDAsIDB4NjksIDB4MTIsIDB4ZWQsIDB4ZTUsIDB4NTYsIDB4YjYsIDB4MjMsIDB4YzUsIDB4ODYsIDB4ZjMsCisgIDB4NjcsIDB4OTgsIDB4OTQsIDB4ODQsIDB4OTIsIDB4ZjAsIDB4MGEsIDB4NGYsIDB4MzIsIDB4MzYsIDB4YTAsIDB4MDcsCisgIDB4OWQsIDB4YjIsIDB4MDcsIDB4NzgsIDB4YjUsIDB4YjgsIDB4NjcsIDB4NjIsIDB4ZjIsIDB4MGMsIDB4NGEsIDB4ZjYsCisgIDB4ZWUsIDB4MmIsIDB4NmIsIDB4ODksIDB4MDMsIDB4MjMsIDB4NWQsIDB4YzUsIDB4ZTYsIDB4ODIsIDB4YTcsIDB4MjgsCisgIDB4MmMsIDB4NDcsIDB4MGIsIDB4NTgsIDB4NTcsIDB4M2EsIDB4YjQsIDB4NGYsIDB4MzYsIDB4ZDIsIDB4YjAsIDB4YjMsCisgIDB4YTIsIDB4NzksIDB4OTUsIDB4YTAsIDB4NGUsIDB4ODAsIDB4ZDQsIDB4OGUsIDB4MmYsIDB4OGQsIDB4ZGMsIDB4NzEsCisgIDB4YmMsIDB4MjIsIDB4ZjUsIDB4NzQsIDB4Y2YsIDB4NmUsIDB4ZmUsIDB4ZTgsIDB4ZGQsIDB4NWQsIDB4OGMsIDB4ZmYsCisgIDB4MDAsIDB4OTYsIDB4NDgsIDB4MTIsIDB4ZGUsIDB4NzEsIDB4OTIsIDB4YzksIDB4NGYsIDB4NDEsIDB4ZDksIDB4YTgsCisgIDB4ODQsIDB4MDMsIDB4ZDAsIDB4OWYsIDB4MzUsIDB4MDksIDB4ZDcsIDB4MzcsIDB4MjgsIDB4ZjQsIDB4OWYsIDB4M2EsCisgIDB4YmQsIDB4NjksIDB4NGQsIDB4YjQsIDB4Y2YsIDB4NDYsIDB4ODUsIDB4MTgsIDB4YzEsIDB4MjYsIDB4OGEsIDB4NDMsCisgIDB4ZjAsIDB4NjYsIDB4NGEsIDB4YWUsIDB4M2MsIDB4MjYsIDB4YjIsIDB4YzYsIDB4OTAsIDB4MWIsIDB4NjYsIDB4ZWMsCisgIDB4ZDAsIDB4NzEsIDB4NzEsIDB4MTUsIDB4MjksIDB4YjUsIDB4M2EsIDB4MDQsIDB4NjAsIDB4ZTksIDB4NDgsIDB4NzUsCisgIDB4YTQsIDB4MjgsIDB4ODQsIDB4OTIsIDB4MGUsIDB4ZDIsIDB4NDgsIDB4ZWUsIDB4MjksIDB4ZWIsIDB4ZDcsIDB4YTUsCisgIDB4NTksIDB4NGMsIDB4ZGIsIDB4MmUsIDB4MmIsIDB4OWMsIDB4NWUsIDB4NGIsIDB4NDksIDB4MGUsIDB4MjEsIDB4NWEsCisgIDB4MzMsIDB4YWUsIDB4MGIsIDB4MTIsIDB4MWUsIDB4MjMsIDB4N2YsIDB4ZDEsIDB4YjYsIDB4OWYsIDB4MzEsIDB4MDMsCisgIDB4YmYsIDB4ZDEsIDB4ZjMsIDB4NjksIDB4NjIsIDB4ZGQsIDB4NjUsIDB4NWUsIDB4MTUsIDB4ODcsIDB4MTgsIDB4MzIsCisgIDB4MTYsIDB4OTYsIDB4ZGQsIDB4YzcsIDB4NmUsIDB4OTEsIDB4ZWUsIDB4YjEsIDB4NDcsIDB4MmYsIDB4OWMsIDB4Y2MsCisgIDB4MTksIDB4ZWEsIDB4NGEsIDB4MWYsIDB4NmIsIDB4ZTYsIDB4ODUsIDB4YWQsIDB4Y2QsIDB4ODEsIDB4ZDMsIDB4NmQsCisgIDB4ODMsIDB4ZTEsIDB4NTYsIDB4M2EsIDB4MTgsIDB4NmQsIDB4YjcsIDB4OWQsIDB4NzEsIDB4M2MsIDB4ZGMsIDB4ZWUsCisgIDB4MWYsIDB4M2MsIDB4OTUsIDB4MTMsIDB4ZGQsIDB4ZDMsIDB4YTAsIDB4M2QsIDB4MDAsIDB4ZTksIDB4ZGMsIDB4MzQsCisgIDB4MmIsIDB4YjYsIDB4ZGQsIDB4ZWIsIDB4OGYsIDB4YzAsIDB4ZTMsIDB4YjgsIDB4NWEsIDB4NjUsIDB4YjcsIDB4NTIsCisgIDB4MDcsIDB4MzcsIDB4YjcsIDB4ZGMsIDB4OWMsIDB4ODksIDB4MGEsIDB4ZjksIDB4NjEsIDB4ZGEsIDB4YWYsIDB4ZjYsCisgIDB4MjcsIDB4YmMsIDB4YjYsIDB4MDcsIDB4NWQsIDB4NzYsIDB4ZTQsIDB4MjcsIDB4NGUsIDB4YjAsIDB4YWYsIDB4ZDUsCisgIDB4NzUsIDB4YmUsIDB4NjQsIDB4NmIsIDB4YTYsIDB4OGYsIDB4MjksIDB4ZjAsIDB4YTcsIDB4M2MsIDB4OWEsIDB4ZGQsCisgIDB4NjcsIDB4ZTIsIDB4ZmYsIDB4MDAsIDB4MDgsIDB4MzUsIDB4MDYsIDB4NDksIDB4NDMsIDB4NTcsIDB4MzgsIDB4YzgsCisgIDB4OTcsIDB4NmUsIDB4OTcsIDB4ZGMsIDB4ZTQsIDB4NDksIDB4MjksIDB4M2MsIDB4Y2QsIDB4MmYsIDB4ZDIsIDB4OTUsCisgIDB4MjEsIDB4YzQsIDB4ODAsIDB4NDcsIDB4YTksIDB4NDIsIDB4YTMsIDB4N2MsIDB4N2YsIDB4ZmQsIDB4ZDQsIDB4NzcsCisgIDB4MGQsIDB4YTcsIDB4N2YsIDB4MjQsIDB4NzgsIDB4ODMsIDB4MmYsIDB4MTYsIDB4NzgsIDB4ZjIsIDB4ZDksIDB4ZjIsCisgIDB4NDUsIDB4YjksIDB4M2UsIDB4ZDQsIDB4NGYsIDB4NDQsIDB4YjMsIDB4MzAsIDB4MGUsIDB4NjksIDB4MmMsIDB4MGYsCisgIDB4NDAsIDB4NTgsIDB4ZjcsIDB4ZDQsIDB4OGUsIDB4OWQsIDB4N2IsIDB4NWEsIDB4Y2EsIDB4ZjIsIDB4OTYsIDB4N2IsCisgIDB4ZTgsIDB4ZDIsIDB4Y2UsIDB4YTYsIDB4M2IsIDB4OGMsIDB4NmIsIDB4ZTAsIDB4Y2UsIDB4NjIsIDB4ZmUsIDB4NWYsCisgIDB4ODYsIDB4MjEsIDB4ZWIsIDB4YTIsIDB4MTEsIDB4MWUsIDB4ZmYsIDB4MDAsIDB4NmQsIDB4NzUsIDB4NzYsIDB4ZmIsCisgIDB4ZGMsIDB4NmQsIDB4ZTgsIDB4YjEsIDB4MzEsIDB4YTMsIDB4Y2EsIDB4ZTcsIDB4NDEsIDB4ZjksIDB4YWEsIDB4ZTgsCisgIDB4YjQsIDB4ZmEsIDB4NDIsIDB4ODUsIDB4M2IsIDB4OGUsIDB4ZWEsIDB4YTcsIDB4ZjMsIDB4MzQsIDB4YTMsIDB4ODYsCisgIDB4ZGMsIDB4NWQsIDB4ODMsIDB4OWUsIDB4MzUsIDB4ZWYsIDB4NTgsIDB4ZjYsIDB4NTAsIDB4YjYsIDB4YWQsIDB4NTksCisgIDB4MTAsIDB4MWQsIDB4MTAsIDB4YzQsIDB4YWUsIDB4ZTgsIDB4OTIsIDB4YzgsIDB4ZGUsIDB4ODYsIDB4ZmYsIDB4MDAsCisgIDB4MjQsIDB4YTMsIDB4ZGMsIDB4MDEsIDB4NDksIDB4YWIsIDB4ODAsIDB4NzcsIDB4NzcsIDB4NmEsIDB4YmMsIDB4ZjMsCisgIDB4ZDAsIDB4MGEsIDB4MjgsIDB4YTIsIDB4ODAsIDB4MjgsIDB4YTIsIDB4OGEsIDB4MDAsIDB4YTIsIDB4OGEsIDB4MjgsCisgIDB4MDQsIDB4NGUsIDB4MzIsIDB4ZmMsIDB4NGIsIDB4MTcsIDB4ZmQsIDB4YWEsIDB4YjYsIDB4N2QsIDB4ZjgsIDB4YTcsCisgIDB4YmEsIDB4NDQsIDB4ZTMsIDB4MmYsIDB4YzQsIDB4YjEsIDB4N2YsIDB4ZGEsIDB4YWIsIDB4NjcsIDB4ZGYsIDB4OGEsCisgIDB4N2IsIDB4YTAsIDB4MzAsIDB4NDAsIDB4M2QsIDB4ZTIsIDB4OGEsIDB4Y2QsIDB4MTUsIDB4MDAsIDB4MjksIDB4MzMsCisgIDB4OGUsIDB4M2YsIDB4MjMsIDB4ZDksIDB4NzcsIDB4ZDEsIDB4MTIsIDB4M2YsIDB4ODAsIDB4ZDMsIDB4OWQsIDB4MjYsCisgIDB4NzEsIDB4YzcsIDB4ZTQsIDB4N2IsIDB4MmUsIDB4ZmEsIDB4MjIsIDB4NDcsIDB4ZjAsIDB4MWEsIDB4OTAsIDB4NDcsCisgIDB4NzEsIDB4Y2YsIDB4MDYsIDB4NTYsIDB4N2QsIDB4YzMsIDB4MjcsIDB4ZWQsIDB4NzAsIDB4ZGMsIDB4MmMsIDB4NWUsCisgIDB4MjIsIDB4ZjYsIDB4NzMsIDB4YWQsIDB4MTIsIDB4MTIsIDB4NzQsIDB4YTYsIDB4NjUsIDB4YjUsIDB4ZDUsIDB4YjIsCisgIDB4MGYsIDB4ODYsIDB4ZmEsIDB4YTcsIDB4ZmUsIDB4MmEsIDB4YWUsIDB4YjgsIDB4MjMsIDB4YzQsIDB4YzksIDB4MzcsCisgIDB4OWIsIDB4YjMsIDB4NmYsIDB4ZGQsIDB4OTYsIDB4YjQsIDB4YzgsIDB4YjgsIDB4YjYsIDB4YjcsIDB4NTQsIDB4ZDIsCisgIDB4YzYsIDB4YmIsIDB4MDksIDB4MGMsIDB4ZjIsIDB4YjcsIDB4MzYsIDB4MzEsIDB4ZjQsIDB4MTQsIDB4MmYsIDB4OTUsCisgIDB4ZDQsIDB4ODMsIDB4YmYsIDB4MzEsIDB4ZTEsIDB4ZDQsIDB4ZjIsIDB4OTMsIDB4NWYsIDB4NDIsIDB4YzYsIDB4MWYsCisgIDB4Y2QsIDB4ZGIsIDB4ZjksIDB4ODMsIDB4ZWMsIDB4YWYsIDB4OTcsIDB4MzgsIDB4ZDUsIDB4OGQsIDB4M2IsIDB4ODUsCisgIDB4NzEsIDB4YTIsIDB4MmQsIDB4ZGEsIDB4ZGMsIDB4NDMsIDB4MTYsIDB4ZWMsIDB4YjIsIDB4NWEsIDB4MjQsIDB4NDQsCisgIDB4NzAsIDB4YWIsIDB4OTUsIDB4YjgsIDB4ZDcsIDB4YTYsIDB4YzEsIDB4MDAsIDB4MmMsIDB4OWUsIDB4ZTQsIDB4NDgsCisgIDB4NDIsIDB4OTQsIDB4ZGEsIDB4YmEsIDB4OGUsIDB4YWUsIDB4MTUsIDB4NzcsIDB4MjMsIDB4NTUsIDB4N2EsIDB4NzIsCisgIDB4ZDIsIDB4ZjcsIDB4ZTAsIDB4YTUsIDB4NDgsIDB4NmEsIDB4NWUsIDB4YTYsIDB4MzgsIDB4ZjcsIDB4ODksIDB4N2IsCisgIDB4OTMsIDB4YzQsIDB4NzcsIDB4NmUsIDB4MDMsIDB4YjQsIDB4NWMsIDB4MmMsIDB4OTcsIDB4ZGYsIDB4ZTEsIDB4YmEsCisgIDB4NTYsIDB4MDIsIDB4MWEsIDB4OTQsIDB4ODQsIDB4ZmIsIDB4ZjMsIDB4MmEsIDB4M2EsIDB4MjcsIDB4NGEsIDB4NGEsCisgIDB4NTIsIDB4ZWEsIDB4N2IsIDB4ODEsIDB4ZTUsIDB4NzAsIDB4NzgsIDB4MGEsIDB4YTAsIDB4YjgsIDB4ZmIsIDB4ODMsCisgIDB4YWQsIDB4OGIsIDB4MTQsIDB4M2MsIDB4YTIsIDB4MzEsIDB4NzEsIDB4ZDUsIDB4YjYsIDB4YmUsIDB4YzIsIDB4NTIsCisgIDB4OTUsIDB4ZTYsIDB4ZjMsIDB4MjAsIDB4OWYsIDB4MzUsIDB4NjksIDB4MGEsIDB4ZWIsIDB4Y2EsIDB4MTUsIDB4ZTYsCisgIDB4OWUsIDB4YTcsIDB4NWQsIDB4MzcsIDB4YWEsIDB4ZmIsIDB4M2QsIDB4ZjgsIDB4NzAsIDB4YjgsIDB4YTUsIDB4YzIsCisgIDB4ZDUsIDB4ZGIsIDB4MTksIDB4NzcsIDB4YjEsIDB4OTMsIDB4Y2EsIDB4ODksIDB4NzYsIDB4YzcsIDB4NWQsIDB4NDgsCisgIDB4MmIsIDB4OGQsIDB4MjEsIDB4YjUsIDB4NmQsIDB4MDUsIDB4NDAsIDB4ZWYsIDB4YWEsIDB4MTYsIDB4MGEsIDB4MTQsCisgIDB4M2QsIDB4MWMsIDB4YzIsIDB4YWIsIDB4ZmMsIDB4NTIsIDB4MjAsIDB4YzksIDB4MmMsIDB4NGYsIDB4MzUsIDB4MzIsCisgIDB4Y2UsIDB4ZDYsIDB4YTQsIDB4ODcsIDB4MjEsIDB4NWUsIDB4MjIsIDB4MzgsIDB4YjAsIDB4ZGIsIDB4NGMsIDB4M2EsCisgIDB4OTMsIDB4YzgsIDB4ZjMsIDB4MmEsIDB4MDAsIDB4YTksIDB4ZDcsIDB4MTQsIDB4MGYsIDB4YzEsIDB4MmEsIDB4M2EsCisgIDB4ZDEsIDB4NGEsIDB4OTMsIDB4YWEsIDB4ZTksIDB4OGQsIDB4M2QsIDB4NTksIDB4ODMsIDB4MzksIDB4ZTUsIDB4NTMsCisgIDB4MTgsIDB4OTksIDB4ZjEsIDB4N2YsIDB4MDcsIDB4YjMsIDB4MTcsIDB4NzAsIDB4NGUsIDB4MjEsIDB4NWIsIDB4MzIsCisgIDB4MjQsIDB4ODUsIDB4MjksIDB4ODYsIDB4OTcsIDB4YzksIDB4MjksIDB4YjEsIDB4ZGUsIDB4ZTMsIDB4MmIsIDB4MWEsCisgIDB4NTgsIDB4MWUsIDB4YmQsIDB4MWQsIDB4OGYsIDB4NTgsIDB4MTUsIDB4ZjcsIDB4OGIsIDB4OTYsIDB4YmIsIDB4NDUsCisgIDB4ZWIsIDB4MjksIDB4YjMsIDB4NWYsIDB4NmQsIDB4ZjIsIDB4NTgsIDB4NWQsIDB4Y2UsIDB4NzQsIDB4NTEsIDB4MTYsCisgIDB4MDQsIDB4YzUsIDB4YTksIDB4MmEsIDB4NGMsIDB4NzgsIDB4YWEsIDB4ZGIsIDB4OGIsIDB4NzUsIDB4YjQsIDB4MmIsCisgIDB4YTcsIDB4MzEsIDB4MWEsIDB4MWIsIDB4ZjEsIDB4ZTYsIDB4NDgsIDB4M2IsIDB4MWIsIDB4MDcsIDB4ZTUsIDB4ZmIsCisgIDB4Y2YsIDB4ZTAsIDB4ZDcsIDB4NzMsIDB4NTcsIDB4MTEsIDB4ZTYsIDB4ZTMsIDB4ZjYsIDB4OWIsIDB4ZjQsIDB4MzYsCisgIDB4MjAsIDB4ZjksIDB4MTEsIDB4YjgsIDB4NDIsIDB4N2EsIDB4NWYsIDB4MzEsIDB4NTEsIDB4NmYsIDB4YjQsIDB4MDgsCisgIDB4MmQsIDB4YWIsIDB4OTQsIDB4N2MsIDB4MjQsIDB4OTIsIDB4MzYsIDB4N2MsIDB4NDEsIDB4MDcsIDB4NDMsIDB4N2EsCisgIDB4YWIsIDB4OWYsIDB4ZjAsIDB4NzksIDB4YjYsIDB4NWMsIDB4MmQsIDB4ZjgsIDB4N2QsIDB4YzcsIDB4MGQsIDB4YzgsCisgIDB4NjMsIDB4MmEsIDB4MjUsIDB4ZmEsIDB4YzMsIDB4MmMsIDB4MzIsIDB4NjQsIDB4MjAsIDB4ZWQsIDB4NGEsIDB4NjgsCisgIDB4ZmIsIDB4ZTQsIDB4NzcsIDB4MWIsIDB4NTksIDB4ZWYsIDB4NDgsIDB4M2IsIDB4MDksIDB4ZjYsIDB4NjgsIDB4OGUsCisgIDB4ZmEsIDB4YmQsIDB4MTgsIDB4Y2QsIDB4NjYsIDB4MTgsIDB4ZTcsIDB4ZWEsIDB4NTYsIDB4YjQsIDB4YTksIDB4YzksCisgIDB4YTksIDB4YTcsIDB4YzcsIDB4ZDAsIDB4YjUsIDB4YWYsIDB4MzcsIDB4MGIsIDB4YzYsIDB4MmYsIDB4N2QsIDB4YjYsCisgIDB4NjIsIDB4OTgsIDB4NTYsIDB4MmEsIDB4ZjMsIDB4MzAsIDB4ZTYsIDB4NDgsIDB4NGIsIDB4NTMsIDB4YWYsIDB4Y2YsCisgIDB4YzMsIDB4NWMsIDB4YjAsIDB4MWQsIDB4NTIsIDB4NzksIDB4YjksIDB4OTYsIDB4OTQsIDB4YTksIDB4MmEsIDB4NTksCisgIDB4ZjMsIDB4ODEsIDB4MmUsIDB4MmQsIDB4NDAsIDB4MGUsIDB4YTAsIDB4NmYsIDB4NWEsIDB4MTIsIDB4N2MsIDB4NDAsCisgIDB4NjEsIDB4NGMsIDB4NWQsIDB4MzEsIDB4ODksIDB4NGYsIDB4YmMsIDB4ZDMsIDB4YjcsIDB4MjUsIDB4OTcsIDB4NjEsCisgIDB4YzgsIDB4NWIsIDB4NGQsIDB4NzIsIDB4MjUsIDB4ZTYsIDB4Y2IsIDB4NDUsIDB4YzUsIDB4MmIsIDB4OTQsIDB4OTIsCisgIDB4NDAsIDB4MGIsIDB4NmQsIDB4MWEsIDB4MWIsIDB4M2EsIDB4ZTcsIDB4ZWYsIDB4ZjEsIDB4YTEsIDB4OGMsIDB4YjMsCisgIDB4MjksIDB4NjIsIDB4MzgsIDB4NjEsIDB4ZmIsIDB4NmQsIDB4YTYsIDB4NzMsIDB4YzAsIDB4NjksIDB4MzIsIDB4NDQsCisgIDB4YTUsIDB4YjAsIDB4MTcsIDB4ZTgsIDB4MjUsIDB4YWUsIDB4NDUsIDB4NmIsIDB4ZWEsIDB4NTcsIDB4ZjcsIDB4NzcsCisgIDB4NTQsIDB4NTksIDB4NGMsIDB4ZTksIDB4YjcsIDB4MzMsIDB4NzUsIDB4YmQsIDB4Y2IsIDB4NmUsIDB4NTQsIDB4ZDAsCisgIDB4ZDksIDB4NjksIDB4YjQsIDB4YjQsIDB4OGUsIDB4NDYsIDB4NjMsIDB4MjAsIDB4OWQsIDB4YTksIDB4MmQsIDB4OGQsCisgIDB4OTMsIDB4YjIsIDB4NDAsIDB4ZGEsIDB4ODksIDB4MjQsIDB4ZTgsIDB4NzcsIDB4MGUsIDB4OTUsIDB4NGEsIDB4NTYsCisgIDB4ZjUsIDB4MzUsIDB4YTYsIDB4Y2IsIDB4NTYsIDB4YWYsIDB4NGYsIDB4NDYsIDB4MTYsIDB4ZTYsIDB4ZjgsIDB4NTEsCisgIDB4ZTcsIDB4MzcsIDB4NzAsIDB4NWMsIDB4Y2IsIDB4MmQsIDB4YzQsIDB4YzAsIDB4YjgsIDB4M2EsIDB4ZGEsIDB4NTIsCisgIDB4YjAsIDB4YTYsIDB4NDMsIDB4YWQsIDB4NDgsIDB4MDksIDB4ZGUsIDB4OTIsIDB4YTQsIDB4NmMsIDB4MWUsIDB4NjEsCisgIDB4Y2MsIDB4NzQsIDB4YTAsIDB4NDcsIDB4NGUsIDB4ODcsIDB4NjMsIDB4NDAsIDB4NzIsIDB4NGIsIDB4ODksIDB4MmUsCisgIDB4ZTYsIDB4ZjMsIDB4NmYsIDB4NWYsIDB4ZWUsIDB4OTIsIDB4NmUsIDB4YWEsIDB4NjksIDB4NDEsIDB4NmQsIDB4YjIsCisgIDB4YjAsIDB4MWIsIDB4OGUsIDB4ODUsIDB4MGUsIDB4ZTIsIDB4MWEsIDB4NGYsIDB4NDIsIDB4NDcsIDB4ZWIsIDB4ZjMsCisgIDB4MTEsIDB4NWQsIDB4ODUsIDB4YzQsIDB4YjQsIDB4MGIsIDB4Y2IsIDB4NTgsIDB4NDIsIDB4NWIsIDB4MWMsIDB4ZTUsCisgIDB4NjUsIDB4NWQsIDB4MTIsIDB4MDcsIDB4NWQsIDB4OTMsIDB4ZTAsIDB4M2EsIDB4NzUsIDB4ZGUsIDB4YmIsIDB4YWEsCisgIDB4MmYsIDB4MWEsIDB4YmIsIDB4Y2IsIDB4YmYsIDB4YzYsIDB4OTUsIDB4NzYsIDB4OTAsIDB4OTEsIDB4ZTQsIDB4ZjIsCisgIDB4MjYsIDB4M2EsIDB4NjAsIDB4YWMsIDB4MzQsIDB4NTEsIDB4ZGEsIDB4YzYsIDB4MDcsIDB4NDgsIDB4NzMsIDB4NWQsCisgIDB4ZmUsIDB4NzYsIDB4ODksIDB4MDcsIDB4NWQsIDB4NDYsIDB4OGUsIDB4YmEsIDB4ZDcsIDB4NjcsIDB4YmIsIDB4OGYsCisgIDB4YmMsIDB4Y2UsIDB4MzksIDB4MzgsIDB4OTUsIDB4NDksIDB4N2IsIDB4YmMsIDB4NjcsIDB4ODIsIDB4MDMsIDB4OGQsCisgIDB4ZjIsIDB4NTMsIDB4MTIsIDB4ZDAsIDB4ODksIDB4Y2IsIDB4NGIsIDB4OGIsIDB4NGQsIDB4ZGUsIDB4YzMsIDB4M2EsCisgIDB4YzgsIDB4ZTYsIDB4ZmEsIDB4OGUsIDB4ZGQsIDB4MWEsIDB4NzYsIDB4M2YsIDB4ZDYsIDB4N2QsIDB4ZjMsIDB4NTQsCisgIDB4ZTksIDB4YTIsIDB4M2EsIDB4MTMsIDB4YjIsIDB4M2IsIDB4Y2YsIDB4YTYsIDB4OTcsIDB4ZjgsIDB4OTgsIDB4NWEsCisgIDB4NDYsIDB4MDQsIDB4YmIsIDB4ODMsIDB4YTMsIDB4OWYsIDB4ZGMsIDB4NGIsIDB4YjQsIDB4MGIsIDB4OTgsIDB4MDQsCisgIDB4NmYsIDB4Y2QsIDB4MGYsIDB4MjUsIDB4YjcsIDB4M2EsIDB4MWYsIDB4ZDQsIDB4NWEsIDB4YTksIDB4ODUsIDB4NDAsCisgIDB4ODUsIDB4MjgsIDB4MWUsIDB4ZmQsIDB4OWEsIDB4YWQsIDB4MTgsIDB4ZTksIDB4OWMsIDB4OTEsIDB4NmEsIDB4ZDIsCisgIDB4ZDUsIDB4MTgsIDB4YjMsIDB4MTUsIDB4MDksIDB4OWEsIDB4NTksIDB4NWQsIDB4YmQsIDB4ZDgsIDB4ZDQsIDB4YzQsCisgIDB4MjksIDB4MDIsIDB4MmQsIDB4Y2UsIDB4MzMsIDB4YzgsIDB4OTcsIDB4NmQsIDB4OTIsIDB4N2YsIDB4YTAsIDB4OTQsCisgIDB4ZDEsIDB4ZTYsIDB4NmQsIDB4N2UsIDB4YjEsIDB4YmUsIDB4ODQsIDB4NzgsIDB4YTQsIDB4YTgsIDB4NzgsIDB4ZDQsCisgIDB4ZGQsIDB4MWEsIDB4YWQsIDB4ZTQsIDB4OTMsIDB4NGQsIDB4MzMsIDB4MTQsIDB4ZGEsIDB4NjksIDB4YTIsIDB4NGUsCisgIDB4ZGEsIDB4ZWQsIDB4YTMsIDB4OGIsIDB4ZmMsIDB4MjMsIDB4OTEsIDB4MGUsIDB4ZTksIDB4MTQsIDB4YjIsIDB4ZDUsCisgIDB4Y2UsIDB4MzMsIDB4OTAsIDB4YWUsIDB4NTEsIDB4NGYsIDB4NTUsIDB4YzQsIDB4OTIsIDB4OTIsIDB4NTIsIDB4ZTIsCisgIDB4MGYsIDB4YTEsIDB4NDgsIDB4NzAsIDB4NmMsIDB4MWYsIDB4NTIsIDB4NGQsIDB4NzIsIDB4NzAsIDB4MTMsIDB4MjQsCisgIDB4YjksIDB4NWMsIDB4YjEsIDB4OTksIDB4NTgsIDB4YmUsIDB4NDgsIDB4ZTcsIDB4M2UsIDB4NTEsIDB4OGIsIDB4NDgsCisgIDB4ZjcsIDB4MzIsIDB4ZTYsIDB4NGYsIDB4N2IsIDB4ZTEsIDB4MjMsIDB4ZGUsIDB4NjQsIDB4ZjUsIDB4ZWEsIDB4NTIsCisgIDB4ZWIsIDB4N2MsIDB4YWEsIDB4ZGYsIDB4YTcsIDB4OWIsIDB4ZDEsIDB4NGIsIDB4NzYsIDB4MTksIDB4YTksIDB4YzIsCisgIDB4ZjgsIDB4OWUsIDB4ZGMsIDB4OTIsIDB4YWUsIDB4NGIsIDB4MWUsIDB4NTgsIDB4ZTIsIDB4MjIsIDB4Y2MsIDB4MDQsCisgIDB4ZjksIDB4OTEsIDB4ZWUsIDB4MjEsIDB4M2EsIDB4NjUsIDB4ZGYsIDB4NTAsIDB4NzUsIDB4MjksIDB4ZWMsIDB4Y2YsCisgIDB4ZWIsIDB4MjUsIDB4YmYsIDB4NGQsIDB4NzYsIDB4NzEsIDB4ODMsIDB4OWYsIDB4MDIsIDB4Y2QsIDB4YWMsIDB4ZmMsCisgIDB4NWIsIDB4ODgsIDB4ODUsIDB4MjYsIDB4ZGUsIDB4OTAsIDB4OGIsIDB4NGUsIDB4NTAsIDB4ODQsIDB4MGUsIDB4OGEsCisgIDB4ODYsIDB4YjUsIDB4NjksIDB4YTksIDB4MDcsIDB4ZDIsIDB4NTksIDB4NzEsIDB4NDMsIDB4NjcsIDB4YmYsIDB4OTUsCisgIDB4NDQsIDB4NzcsIDB4MGEsIDB4ZjEsIDB4NmEsIDB4NDEsIDB4ZDMsIDB4OTMsIDB4ODksIDB4ZWMsIDB4NTIsIDB4OWUsCisgIDB4YjgsIDB4YTYsIDB4NWIsIDB4ZTksIDB4MjQsIDB4ODAsIDB4NGQsIDB4NjYsIDB4YmMsIDB4YjQsIDB4YjQsIDB4MzgsCisgIDB4ZDIsIDB4NWMsIDB4NmQsIDB4NDksIDB4NWEsIDB4MTYsIDB4MDIsIDB4OTIsIDB4YTQsIDB4OWQsIDB4ODIsIDB4MGYsCisgIDB4NzEsIDB4MTUsIDB4ZWEsIDB4YTgsIDB4NjgsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsCisgIDB4MDIsIDB4MjcsIDB4MTksIDB4N2UsIDB4MjUsIDB4OGIsIDB4ZmUsIDB4ZDUsIDB4NWIsIDB4M2UsIDB4ZmMsIDB4NTMsCisgIDB4ZGQsIDB4MjIsIDB4NzEsIDB4OTcsIDB4ZTIsIDB4NTgsIDB4YmYsIDB4ZWQsIDB4NTUsIDB4YjMsIDB4ZWYsIDB4YzUsCisgIDB4M2QsIDB4ZDAsIDB4MDUsIDB4MTQsIDB4NTEsIDB4NTAsIDB4MDIsIDB4OTMsIDB4MzgsIDB4ZTMsIDB4ZjIsIDB4M2QsCisgIDB4OTcsIDB4N2QsIDB4MTEsIDB4MjMsIDB4ZjgsIDB4MGQsIDB4MzksIDB4ZDIsIDB4NjcsIDB4MWMsIDB4N2UsIDB4NDcsCisgIDB4YjIsIDB4ZWYsIDB4YTIsIDB4MjQsIDB4N2YsIDB4MDEsIDB4YTksIDB4MDMsIDB4N2MsIDB4NmYsIDB4OGIsIDB4YjcsCisgIDB4ZjMsIDB4MDcsIDB4ZDksIDB4NGEsIDB4OWMsIDB4NWYsIDB4YzIsIDB4MjEsIDB4NzEsIDB4MGIsIDB4MDEsIDB4YjksCisgIDB4ZTMsIDB4MTIsIDB4YzgsIDB4NjksIDB4ZDcsIDB4ZGIsIDB4ZTcsIDB4ODcsIDB4MjMsIDB4ZjMsIDB4YTMsIDB4YzgsCisgIDB4NGYsIDB4NTYsIDB4ZGMsIDB4NDksIDB4ZWYsIDB4MDQsIDB4MmIsIDB4YmYsIDB4NWUsIDB4MDQsIDB4OGYsIDB4MWEsCisgIDB4NmIsIDB4OGQsIDB4ZjEsIDB4NzYsIDB4ZmUsIDB4NjAsIDB4ZmIsIDB4MmIsIDB4NjYsIDB4YmEsIDB4ZDAsIDB4MWYsCisgIDB4MzAsIDB4NzAsIDB4NGYsIDB4MmUsIDB4YjgsIDB4MzEsIDB4M2QsIDB4YmYsIDB4NzUsIDB4MTIsIDB4NjMsIDB4Y2UsCisgIDB4N2EsIDB4NWIsIDB4YjAsIDB4YWUsIDB4YjEsIDB4ZDYsIDB4NzUsIDB4ZTQsIDB4ZjcsIDB4ODYsIDB4NDcsIDB4YmYsCisgIDB4N2IsIDB4MTMsIDB4MjUsIDB4YjQsIDB4ZjYsIDB4YzMsIDB4ZDIsIDB4YjQsIDB4M2QsIDB4YWYsIDB4MGEsIDB4NzAsCisgIDB4ZTIsIDB4NDUsIDB4YTYsIDB4MzUsIDB4ODMsIDB4MzgsIDB4ODcsIDB4OTYsIDB4YzYsIDB4NDksIDB4NjYsIDB4Y2QsCisgIDB4OTIsIDB4YWQsIDB4YjgsIDB4YjMsIDB4ZGMsIDB4NDYsIDB4OTMsIDB4ZTQsIDB4YjMsIDB4YjUsIDB4Y2EsIDB4YzQsCisgIDB4OGUsIDB4YmIsIDB4ZTUsIDB4ZWQsIDB4MTMsIDB4ZWYsIDB4MmEsIDB4M2UsIDB4OWUsIDB4Y2YsIDB4ZDMsIDB4NGEsCisgIDB4ZmYsIDB4MDAsIDB4ODQsIDB4MzYsIDB4M2EsIDB4YWMsIDB4NTMsIDB4ODksIDB4NTEsIDB4ZjIsIDB4YzgsIDB4NmYsCisgIDB4MjYsIDB4MGQsIDB4YTMsIDB4MmMsIDB4MmMsIDB4ZGIsIDB4ZWUsIDB4MmYsIDB4OWUsIDB4OGQsIDB4YzIsIDB4YmEsCisgIDB4MzQsIDB4NzksIDB4YTAsIDB4Y2MsIDB4NTcsIDB4NGUsIDB4ODMsIDB4OTgsIDB4MDQsIDB4MjgsIDB4ZmUsIDB4ODEsCisgIDB4NWYsIDB4ZTksIDB4NTUsIDB4OGIsIDB4ODksIDB4NDksIDB4YjYsIDB4ZjEsIDB4MTMsIDB4MDIsIDB4YjgsIDB4NjMsCisgIDB4NzcsIDB4OTgsIDB4YWIsIDB4NjUsIDB4MzIsIDB4ZGIsIDB4NzYsIDB4MjQsIDB4YzgsIDB4OGEsIDB4NTAsIDB4ZWQsCisgIDB4MjEsIDB4YzgsIDB4NDEsIDB4ZDMsIDB4OGQsIDB4ZmEsIDB4OTQsIDB4ODUsIDB4OGUsIDB4NjQsIDB4OWYsIDB4NTAsCisgIDB4MjMsIDB4YzIsIDB4YmEsIDB4MjEsIDB4MzcsIDB4YTcsIDB4NTcsIDB4NTgsIDB4ZmQsIDB4MGUsIDB4N2EsIDB4OTAsCisgIDB4NWEsIDB4YjEsIDB4ZDIsIDB4NWYsIDB4NTEsIDB4NTMsIDB4ODgsIDB4OTYsIDB4YjksIDB4OGEsIDB4MTEsIDB4NzIsCisgIDB4MmIsIDB4NGMsIDB4MTEsIDB4M2UsIDB4NzUsIDB4YjQsIDB4MzgsIDB4ODcsIDB4YTAsIDB4NjgsIDB4MWYsIDB4MmYsCisgIDB4ODYsIDB4ZTYsIDB4YmIsIDB4NjYsIDB4M2EsIDB4ZjQsIDB4MmEsIDB4ZjMsIDB4NTIsIDB4YjQsIDB4NmYsIDB4ZjMsCisgIDB4OTAsIDB4MDcsIDB4OGQsIDB4NmIsIDB4YzEsIDB4ZWUsIDB4ZDYsIDB4ZTcsIDB4MjUsIDB4ODgsIDB4ZDYsIDB4ZDksCisgIDB4Y2UsIDB4NGIsIDB4YjQsIDB4Y2UsIDB4OGEsIDB4ODksIDB4MzYsIDB4OTcsIDB4MTYsIDB4OTUsIDB4MjksIDB4NDgsCisgIDB4NGUsIDB4ZDYsIDB4MWMsIDB4NjAsIDB4YWMsIDB4ZjUsIDB4ZjcsIDB4YjIsIDB4OWQsIDB4ZjIsIDB4MjgsIDB4ZjMsCisgIDB4MjcsIDB4OTgsIDB4OGYsIDB4MDEsIDB4NTIsIDB4MzgsIDB4M2MsIDB4ZWIsIDB4OGIsIDB4OTAsIDB4ZTQsIDB4ZDksCisgIDB4NmYsIDB4YWEsIDB4ZGQsIDB4ZmEsIDB4YzgsIDB4ZjEsIDB4ODMsIDB4NzEsIDB4M2QsIDB4ZGQsIDB4YTksIDB4MDAsCisgIDB4MTYsIDB4ZGYsIDB4MWYsIDB4YWEsIDB4ZWIsIDB4N2MsIDB4YWIsIDB4MDcsIDB4ZDMsIDB4Y2MsIDB4MmIsIDB4OTIsCisgIDB4ZTMsIDB4ODgsIDB4M2MsIDB4OGIsIDB4OWMsIDB4OWIsIDB4YWUsIDB4MmQsIDB4N2UsIDB4OTEsIDB4OGYsIDB4NGIsCisgIDB4OTgsIDB4YWUsIDB4NzksIDB4YWQsIDB4YjcsIDB4MWQsIDB4MTIsIDB4MjIsIDB4YzksIDB4NWYsIDB4ZjUsIDB4OGEsCisgIDB4NjEsIDB4NWQsIDB4MDMsIDB4OWYsIDB4YWMsIDB4OTIsIDB4OTIsIDB4N2MsIDB4NzcsIDB4NWUsIDB4OGEsIDB4ZWYsCisgIDB4NjIsIDB4NzEsIDB4M2MsIDB4ZTYsIDB4ZjEsIDB4ZGQsIDB4OTAsIDB4ZDUsIDB4Y2MsIDB4OTAsIDB4NGEsIDB4N2QsCisgIDB4MDMsIDB4N2EsIDB4ZjQsIDB4ZDYsIDB4MzYsIDB4MDgsIDB4MWQsIDB4NDEsIDB4MWQsIDB4ZmIsIDB4ZGYsIDB4NGEsCisgIDB4NTMsIDB4YjgsIDB4MzEsIDB4NzksIDB4YzcsIDB4NmQsIDB4ODksIDB4YmEsIDB4MTksIDB4ZjMsIDB4YjIsIDB4MGUsCisgIDB4YzUsIDB4M2MsIDB4ZDcsIDB4MzYsIDB4OTQsIDB4ODQsIDB4MDcsIDB4MWUsIDB4NDYsIDB4Y2UsIDB4ZGQsIDB4NjUsCisgIDB4MDksIDB4MDAsIDB4MjUsIDB4NjksIDB4ZDgsIDB4ZjMsIDB4MDcsIDB4NDUsIDB4MjUsIDB4MjQsIDB4N2MsIDB4MmUsCisgIDB4YTYsIDB4NGUsIDB4Y2QsIDB4NzgsIDB4YjcsIDB4NWYsIDB4MmQsIDB4MmQsIDB4ZGQsIDB4YWQsIDB4MTMsIDB4ZDksCisgIDB4OWIsIDB4MDksIDB4ZjQsIDB4ODUsIDB4MjEsIDB4ZTYsIDB4NTUsIDB4YjQsIDB4ZTgsIDB4ZjUsIDB4M2IsIDB4ZjEsCisgIDB4NDksIDB4ZWUsIDB4MWEsIDB4MjAsIDB4MWEsIDB4YmUsIDB4YmQsIDB4ZjAsIDB4Y2EsIDB4NjksIDB4ZDgsIDB4ZDUsCisgIDB4OWIsIDB4NjUsIDB4MTAsIDB4MzEsIDB4OWIsIDB4NTgsIDB4OTcsIDB4MzUsIDB4ODksIDB4OTIsIDB4YmIsIDB4NTUsCisgIDB4MTYsIDB4ZDksIDB4NjIsIDB4MmMsIDB4NzIsIDB4ZWEsIDB4ZGQsIDB4NTcsIDB4YTMsIDB4NWQsIDB4YzksIDB4MWUsCisgIDB4OTIsIDB4YTIsIDB4MDcsIDB4NzcsIDB4YjIsIDB4YTAsIDB4MzEsIDB4NWIsIDB4ODYsIDB4N2QsIDB4N2UsIDB4YmUsCisgIDB4YzcsIDB4OWYsIDB4NzMsIDB4ODUsIDB4MTcsIDB4MWQsIDB4YjAsIDB4MjAsIDB4MjksIDB4NDIsIDB4MWIsIDB4ODgsCisgIDB4MGIsIDB4OTUsIDB4MmIsIDB4YTEsIDB4MDksIDB4MDQsIDB4YWIsIDB4YWEsIDB4NTIsIDB4MGUsIDB4ODksIDB4ZjMsCisgIDB4NTIsIDB4N2QsIDB4MWIsIDB4ZWYsIDB4YTcsIDB4MWUsIDB4NzcsIDB4NWIsIDB4NDksIDB4ZjMsIDB4OTQsIDB4OTUsCisgIDB4MTIsIDB4NDEsIDB4MDAsIDB4ZjgsIDB4ZmUsIDB4NzcsIDB4ZDUsIDB4YmUsIDB4ODMsIDB4N2UsIDB4ODMsIDB4NWMsCisgIDB4NzEsIDB4NmQsIDB4YjEsIDB4NjMsIDB4NGMsIDB4N2UsIDB4NGMsIDB4NjYsIDB4YjksIDB4NjQsIDB4NDgsIDB4NTcsCisgIDB4YmUsIDB4YmMsIDB4NTYsIDB4NTYsIDB4YTUsIDB4MWQsIDB4NmMsIDB4OWQsIDB4OTIsIDB4NzQsIDB4OTQsIDB4OGUsCisgIDB4ZTAsIDB4MDgsIDB4MDMsIDB4YWYsIDB4YTIsIDB4YWIsIDB4MjQsIDB4ZGIsIDB4Y2UsIDB4NGIsIDB4NDUsIDB4YTQsCisgIDB4YjEsIDB4ODMsIDB4NGYsIDB4MTAsIDB4ZGMsIDB4NjcsIDB4ZjEsIDB4NmIsIDB4OWEsIDB4YTUsIDB4YzIsIDB4MzksCisgIDB4M2QsIDB4YzIsIDB4OTIsIDB4NGEsIDB4ODksIDB4MWEsIDB4NGEsIDB4YjUsIDB4ZTYsIDB4N2YsIDB4ZDQsIDB4MDUsCisgIDB4NzgsIDB4OTEsIDB4OWIsIDB4NjIsIDB4NTAsIDB4MTgsIDB4NDAsIDB4OWQsIDB4OTMsIDB4ZGEsIDB4MWIsIDB4NzUsCisgIDB4MjgsIDB4MWQsIDB4YTIsIDB4MDQsIDB4YTQsIDB4MjksIDB4NDksIDB4M2EsIDB4ZWEsIDB4MDgsIDB4NDksIDB4MjQsCisgIDB4NTIsIDB4ZDUsIDB4ZDYsIDB4ZWUsIDB4ZGUsIDB4NGYsIDB4MmEsIDB4MGQsIDB4YTIsIDB4MDMsIDB4MjUsIDB4ZGMsCisgIDB4NTcsIDB4ZGQsIDB4NDYsIDB4OTksIDB4YmEsIDB4ZGMsIDB4OTIsIDB4OTAsIDB4NTksIDB4NzksIDB4ZjQsIDB4OTIsCisgIDB4ZTMsIDB4NTEsIDB4MWIsIDB4MjcsIDB4YTIsIDB4ZDAsIDB4NWMsIDB4NmQsIDB4MDEsIDB4NmEsIDB4MWQsIDB4MzYsCisgIDB4OTQsIDB4MjQsIDB4MWQsIDB4YTgsIDB4ZDQsIDB4OWUsIDB4NGIsIDB4MTcsIDB4MTIsIDB4YzcsIDB4NjcsIDB4MjIsCisgIDB4ZTYsIDB4ZWQsIDB4ZTcsIDB4ZjksIDB4M2QsIDB4NzEsIDB4OTAsIDB4YjEsIDB4ZDgsIDB4ZjksIDB4MWEsIDB4MDAsCisgIDB4OTAsIDB4ZmUsIDB4Y2YsIDB4YzEsIDB4NDIsIDB4NWEsIDB4NDgsIDB4NzUsIDB4NjcsIDB4ZDAsIDB4M2MsIDB4ZjQsCisgIDB4ZmEsIDB4NTAsIDB4NzcsIDB4NTgsIDB4NGEsIDB4NzIsIDB4NTIsIDB4OTQsIDB4ZTIsIDB4YjIsIDB4NzQsIDB4NDYsCisgIDB4MTEsIDB4NzEsIDB4OGMsIDB4MjQsIDB4ZjAsIDB4NmQsIDB4MWMsIDB4NGUsIDB4YzAsIDB4ZDUsIDB4YWUsIDB4NGMsCisgIDB4OGQsIDB4ODUsIDB4ZWYsIDB4YmIsIDB4OTEsIDB4ODcsIDB4OTUsIDB4ZjYsIDB4MjAsIDB4ZDcsIDB4YTMsIDB4YzQsCisgIDB4ZGMsIDB4MDUsIDB4MDksIDB4MmEsIDB4N2IsIDB4MjcsIDB4ODcsIDB4MWQsIDB4MjAsIDB4ZWIsIDB4OWEsIDB4NDIsCisgIDB4NTYsIDB4YzgsIDB4MjcsIDB4ZDAsIDB4MGEsIDB4ZDIsIDB4MzYsIDB4N2QsIDB4NWQsIDB4ZjUsIDB4MmQsIDB4NjQsCisgIDB4ZmMsIDB4NzAsIDB4NjQsIDB4NmMsIDB4YTEsIDB4YTgsIDB4NTIsIDB4MTcsIDB4OGYsIDB4YzAsIDB4MGEsIDB4MjAsCisgIDB4NWQsIDB4NmYsIDB4NTEsIDB4ODAsIDB4OWEsIDB4ZWEsIDB4MzcsIDB4ZDEsIDB4NDksIDB4ODYsIDB4ODMsIDB4Y2EsCisgIDB4ODUsIDB4NmIsIDB4YmMsIDB4YjgsIDB4NDcsIDB4YTcsIDB4OTAsIDB4NzcsIDB4NTQsIDB4ZWYsIDB4ZjIsIDB4NjcsCisgIDB4MDYsIDB4YzMsIDB4ZTUsIDB4YzYsIDB4YmMsIDB4ZTUsIDB4OTcsIDB4NjksIDB4MzcsIDB4Y2IsIDB4ZTYsIDB4ZjUsCisgIDB4MWEsIDB4NjUsIDB4ZTUsIDB4ZjMsIDB4MmUsIDB4NDksIDB4NTYsIDB4YzEsIDB4ZTUsIDB4OGUsIDB4YzAsIDB4MWEsCisgIDB4NDksIDB4ZGYsIDB4ODMsIDB4NDgsIDB4MDcsIDB4ZGIsIDB4NTksIDB4NGEsIDB4ZWUsIDB4NGIsIDB4YzgsIDB4ZDIsCisgIDB4MzYsIDB4OTEsIDB4N2UsIDB4NjgsIDB4NGMsIDB4NzUsIDB4YmIsIDB4OTcsIDB4MTIsIDB4NjMsIDB4MzcsIDB4NjcsCisgIDB4YjMsIDB4NjMsIDB4YjcsIDB4MDEsIDB4NjEsIDB4OTAsIDB4ZmIsIDB4MmEsIDB4OTcsIDB4NzksIDB4OWMsIDB4ODMsCisgIDB4MTUsIDB4YWUsIDB4YzksIDB4MmUsIDB4MjUsIDB4NjQsIDB4YzcsIDB4NDIsIDB4YmQsIDB4ZjEsIDB4YzUsIDB4MWUsCisgIDB4NWQsIDB4MDUsIDB4MDQsIDB4ODQsIDB4ODMsIDB4YTMsIDB4YmEsIDB4YmIsIDB4ZWYsIDB4NzYsIDB4ZDgsIDB4MzcsCisgIDB4OWIsIDB4MzQsIDB4YmIsIDB4NGQsIDB4ZDIsIDB4MjMsIDB4NzIsIDB4ZTEsIDB4NGMsIDB4NjEsIDB4NGMsIDB4NDgsCisgIDB4NjUsIDB4YzEsIDB4YjQsIDB4YjgsIDB4ODUsIDB4MGUsIDB4NTUsIDB4MjQsIDB4OGYsIDB4NTgsIDB4MjYsIDB4OTMsCisgIDB4NjYsIDB4NjQsIDB4OTksIDB4MzUsIDB4ZTEsIDB4NjEsIDB4OWIsIDB4NGMsIDB4MzYsIDB4YjEsIDB4ZjgsIDB4Y2EsCisgIDB4ZGUsIDB4YTQsIDB4NGUsIDB4NmYsIDB4YjcsIDB4OTgsIDB4YjEsIDB4YWYsIDB4ZTgsIDB4ZTMsIDB4MjQsIDB4ZTksCisgIDB4MWQsIDB4NDcsIDB4N2IsIDB4YWEsIDB4MWUsIDB4YjQsIDB4NTAsIDB4NzEsIDB4M2IsIDB4ODQsIDB4YzAsIDB4YTcsCisgIDB4MWYsIDB4YmUsIDB4ZTUsIDB4NmUsIDB4MzgsIDB4NzYsIDB4NGIsIDB4Y2IsIDB4YmIsIDB4NzksIDB4MzEsIDB4M2UsCisgIDB4YzYsIDB4ZGEsIDB4NDgsIDB4NDAsIDB4MWUsIDB4YTIsIDB4MmIsIDB4OWUsIDB4YTMsIDB4OWQsIDB4NDcsIDB4YWEsCisgIDB4NDcsIDB4NDUsIDB4MzUsIDB4MGEsIDB4NmIsIDB4NGEsIDB4MjIsIDB4YjgsIDB4MGIsIDB4NzMsIDB4OTksIDB4NjcsCisgIDB4NTUsIDB4ZGIsIDB4ODUsIDB4MzcsIDB4ZDksIDB4MmEsIDB4N2EsIDB4ZTcsIDB4OGEsIDB4YTksIDB4MjksIDB4ODQsCisgIDB4ZmIsIDB4YTcsIDB4Y2UsIDB4OTksIDB4NmQsIDB4NWUsIDB4Y2MsIDB4NzcsIDB4N2QsIDB4NjUsIDB4MjMsIDB4NmQsCisgIDB4YWIsIDB4NWQsIDB4YzUsIDB4MDMsIDB4ZDMsIDB4NTYsIDB4YjAsIDB4ZWUsIDB4YWYsIDB4OWMsIDB4MzgsIDB4Y2EsCisgIDB4YmMsIDB4OGYsIDB4ODcsIDB4NzksIDB4MjYsIDB4M2IsIDB4YzQsIDB4MTksIDB4NmUsIDB4YzksIDB4YmIsIDB4MzUsCisgIDB4NjksIDB4NzcsIDB4YjAsIDB4MzMsIDB4NGIsIDB4NjgsIDB4MGYsIDB4YmQsIDB4MDUsIDB4ZGYsIDB4Y2IsIDB4NDMsCisgIDB4OTEsIDB4YzgsIDB4MDIsIDB4NTQsIDB4YjQsIDB4ZTksIDB4MmUsIDB4MzYsIDB4YjAsIDB4MDAsIDB4MjUsIDB4MmEsCisgIDB4MDcsIDB4YTksIDB4MDUsIDB4NWYsIDB4NDIsIDB4ZGIsIDB4MjcsIDB4NDUsIDB4YjksIDB4NWIsIDB4NjMsIDB4NWMsCisgIDB4NjAsIDB4YmUsIDB4ZGMsIDB4ODgsIDB4OTIsIDB4OTksIDB4NDMsIDB4Y2MsIDB4M2EsIDB4ODMsIDB4YjQsIDB4YWQsCisgIDB4MGIsIDB4MDAsIDB4YTUsIDB4NDMsIDB4ZDQsIDB4NDEsIDB4MDYsIDB4YjEsIDB4MzYsIDB4M2EsIDB4YTgsIDB4YTIsCisgIDB4OGEsIDB4MDAsIDB4YTIsIDB4OGEsIDB4MjgsIDB4MDQsIDB4NGUsIDB4MzIsIDB4ZmMsIDB4NGIsIDB4MTcsIDB4ZmQsCisgIDB4YWEsIDB4YjYsIDB4N2QsIDB4ZjgsIDB4YTcsIDB4YmEsIDB4NDQsIDB4ZTMsIDB4MmYsIDB4YzQsIDB4YjEsIDB4N2YsCisgIDB4ZGEsIDB4YWIsIDB4NjcsIDB4ZGYsIDB4OGEsIDB4N2IsIDB4YTAsIDB4MGEsIDB4MjgsIDB4YTIsIDB4YTAsIDB4MDUsCisgIDB4MjYsIDB4NzEsIDB4YzcsIDB4ZTQsIDB4N2IsIDB4MmUsIDB4ZmEsIDB4MjIsIDB4NDcsIDB4ZjAsIDB4MWEsIDB4NzMsCisgIDB4YTQsIDB4Y2UsIDB4MzgsIDB4ZmMsIDB4OGYsIDB4NjUsIDB4ZGYsIDB4NDQsIDB4NDgsIDB4ZmUsIDB4MDMsIDB4NTIsCisgIDB4MDYsIDB4ZjgsIDB4ZGYsIDB4MTcsIDB4NmYsIDB4ZTYsIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTYsIDB4YjgsIDB4ZGYsCisgIDB4MTcsIDB4NmYsIDB4ZTYsIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTAsIDB4MGIsIDB4YmMsIDB4NDcsIDB4YzUsIDB4MmQsCisgIDB4ZDksIDB4YzYsIDB4MTUsIDB4NzcsIDB4YzUsIDB4YWUsIDB4YTgsIDB4ZGMsIDB4NWIsIDB4OGMsIDB4NzIsIDB4ZDcsCisgIDB4MzcsIDB4NzksIDB4NmQsIDB4N2QsIDB4ZTgsIDB4NTgsIDB4ZjUsIDB4YTUsIDB4NDAsIDB4MjgsIDB4N2IsIDB4MmIsCisgIDB4ZTcsIDB4MGUsIDB4MTMsIDB4ZTQsIDB4NTcsIDB4M2IsIDB4M2UsIDB4NGEsIDB4MTgsIDB4YmQsIDB4MmIsIDB4YjAsCisgIDB4YmQsIDB4NDYsIDB4OTgsIDB4OGMsIDB4N2YsIDB4MjIsIDB4MDQsIDB4ZjQsIDB4MzMsIDB4OWIsIDB4NDksIDB4ZjIsCisgIDB4MjksIDB4ODcsIDB4ZDIsIDB4OTksIDB4MGQsIDB4MjAsIDB4YjQsIDB4NGYsIDB4OGEsIDB4OWIsIDB4NDEsIDB4M2YsCisgIDB4MGIsIDB4YWYsIDB4ZDYsIDB4MDQsIDB4NmMsIDB4ZWUsIDB4YmUsIDB4NzUsIDB4ZmMsIDB4MjgsIDB4NzEsIDB4ODgsCisgIDB4OTYsIDB4NGMsIDB4OTIsIDB4MjcsIDB4MTAsIDB4OWMsIDB4NGIsIDB4OGQsIDB4ZDgsIDB4ZWUsIDB4OGMsIDB4MjYsCisgIDB4YzUsIDB4OTUsIDB4YTksIDB4YWQsIDB4ZWQsIDB4YTYsIDB4NTYsIDB4YTAsIDB4NjMsIDB4Y2QsIDB4MWEsIDB4ZmMsCisgIDB4ZTYsIDB4NWQsIDB4MDgsIDB4M2IsIDB4ZWYsIDB4ZDIsIDB4NTIsIDB4M2MsIDB4NGQsIDB4NWEsIDB4MTIsIDB4NzAsCisgIDB4OTIsIDB4NjgsIDB4YWMsIDB4ZTIsIDB4YTcsIDB4MWMsIDB4MzEsIDB4YTMsIDB4OGIsIDB4MGQsIDB4YjUsIDB4NjksCisgIDB4OTcsIDB4NmUsIDB4ZTIsIDB4OWMsIDB4MjQsIDB4OTQsIDB4YzQsIDB4NmQsIDB4YTQsIDB4YzEsIDB4YzgsIDB4NTAsCisgIDB4OTEsIDB4YmYsIDB4ZTYsIDB4ODUsIDB4NWUsIDB4NjMsIDB4ZTcsIDB4ZDIsIDB4NTksIDB4NzAsIDB4OTIsIDB4N2YsCisgIDB4NTEsIDB4NmIsIDB4ZjQsIDB4MGEsIDB4OTEsIDB4ZDgsIDB4NTIsIDB4NzYsIDB4MGEsIDB4NTQsIDB4OWQsIDB4N2MsCisgIDB4MjAsIDB4NzYsIDB4MzUsIDB4ZTksIDB4YWQsIDB4MWMsIDB4MWQsIDB4YmYsIDB4MmUsIDB4ZmQsIDB4NjUsIDB4OWQsCisgIDB4OGUsIDB4ZTQsIDB4YWQsIDB4MzIsIDB4ZWQsIDB4YzEsIDB4ODUsIDB4YjksIDB4NmUsIDB4YmIsIDB4MzMsIDB4YTAsCisgIDB4NWIsIDB4NzEsIDB4ZDAsIDB4ODEsIDB4YjUsIDB4OGYsIDB4MDIsIDB4ZGIsIDB4Y2QsIDB4YTksIDB4MmUsIDB4MjcsCisgIDB4YzAsIDB4ODUsIDB4NzQsIDB4YTQsIDB4NzYsIDB4ZTcsIDB4NWYsIDB4MzEsIDB4MGIsIDB4ODMsIDB4ZGMsIDB4MzIsCisgIDB4ODUsIDB4MDEsIDB4Y2IsIDB4YTUsIDB4ZWUsIDB4MTcsIDB4NWIsIDB4NDMsIDB4ZjIsIDB4MDIsIDB4YmIsIDB4MDMsCisgIDB4NmUsIDB4MjcsIDB4NGQsIDB4M2UsIDB4ZmIsIDB4ODAsIDB4NzUsIDB4MGQsIDB4N2UsIDB4NDksIDB4NDAsIDB4MGUsCisgIDB4NjUsIDB4MjksIDB4MDMsIDB4NWQsIDB4ZmIsIDB4MWQsIDB4ZjQsIDB4MmEsIDB4MjgsIDB4MzcsIDB4MWUsIDB4OGYsCisgIDB4NzQsIDB4NzAsIDB4NTYsIDB4YTYsIDB4ZTYsIDB4YjUsIDB4NzUsIDB4NWIsIDB4MzIsIDB4NTMsIDB4ODksIDB4NzksCisgIDB4MTQsIDB4YWIsIDB4M2MsIDB4MzgsIDB4YjYsIDB4ZGIsIDB4NTMsIDB4ZWQsIDB4YjEsIDB4NzgsIDB4YmEsIDB4MmQsCisgIDB4YzQsIDB4YzcsIDB4NzUsIDB4NjMsIDB4OTgsIDB4NDYsIDB4NjksIDB4MDksIDB4MmEsIDB4N2EsIDB4NDEsIDB4NGYsCisgIDB4ZTcsIDB4NzIsIDB4YTAsIDB4NjksIDB4MjMsIDB4YzUsIDB4NDUsIDB4MjAsIDB4ZjQsIDB4ZGUsIDB4OTcsIDB4YjEsCisgIDB4Y2MsIDB4NDIsIDB4ZDUsIDB4NmYsIDB4YzksIDB4NjcsIDB4NTgsIDB4MTIsIDB4YmIsIDB4OTQsIDB4MDksIDB4MjYsCisgIDB4M2EsIDB4NjcsIDB4ZGIsIDB4YTcsIDB4YzcsIDB4OTQsIDB4NWEsIDB4OTQsIDB4YTYsIDB4ZDQsIDB4NDAsIDB4NzksCisgIDB4YjcsIDB4MTQsIDB4OWYsIDB4MzUsIDB4YzIsIDB4OTcsIDB4N2EsIDB4ZTksIDB4NDEsIDB4NDAsIDB4MDcsIDB4MDcsCisgIDB4ODAsIDB4MTUsIDB4MWQsIDB4MjcsIDB4MTQsIDB4NWMsIDB4NGUsIDB4MjgsIDB4YjcsIDB4MmEsIDB4N2MsIDB4YjcsCisgIDB4YWUsIDB4NzIsIDB4OWUsIDB4YjQsIDB4MzYsIDB4YjksIDB4OTcsIDB4MTcsIDB4YmMsIDB4ZDAsIDB4NDksIDB4OWMsCisgIDB4YzgsIDB4NTIsIDB4NTIsIDB4MzcsIDB4Y2EsIDB4ZGIsIDB4NjksIDB4NmQsIDB4MDQsIDB4MDQsIDB4ZmEsIDB4MDksCisgIDB4MjQsIDB4OTIsIDB4NDksIDB4YTYsIDB4YjcsIDB4ZWYsIDB4NzEsIDB4MzIsIDB4MWIsIDB4ZmMsIDB4MzcsIDB4NzAsCisgIDB4ZmIsIDB4NGMsIDB4ZWMsIDB4YWEsIDB4ZTcsIDB4NmUsIDB4NTMsIDB4YTgsIDB4NGIsIDB4OTAsIDB4NDgsIDB4NDQsCisgIDB4MzYsIDB4ZmIsIDB4NDQsIDB4NzIsIDB4YWQsIDB4MGUsIDB4YzksIDB4NWYsIDB4YmQsIDB4ODEsIDB4ZDAsIDB4MWQsCisgIDB4MjcsIDB4OTksIDB4NWIsIDB4NDgsIDB4ZTksIDB4ZDIsIDB4YjUsIDB4NzIsIDB4NTksIDB4NzIsIDB4OWUsIDB4ZDgsCisgIDB4MzIsIDB4NTEsIDB4NzgsIDB4NGEsIDB4M2IsIDB4ZTQsIDB4ZGEsIDB4YWMsIDB4NzcsIDB4MzIsIDB4NmQsIDB4N2MsCisgIDB4OTAsIDB4YjMsIDB4YzQsIDB4YWQsIDB4YTEsIDB4YTAsIDB4OGYsIDB4MmEsIDB4YjIsIDB4MzIsIDB4ZWIsIDB4ODAsCisgIDB4MGUsIDB4ZWYsIDB4MzksIDB4MmEsIDB4NDAsIDB4M2YsIDB4ZjIsIDB4ZWUsIDB4OTYsIDB4ZWUsIDB4YjEsIDB4NmQsCisgIDB4MmYsIDB4NWMsIDB4N2QsIDB4YzgsIDB4YmUsIDB4ZTQsIDB4YjcsIDB4ZmMsIDB4ZTYsIDB4ZTYsIDB4MDEsIDB4ZmYsCisgIDB4MDAsIDB4NDEsIDB4NWEsIDB4OTksIDB4NGEsIDB4NTAsIDB4YWYsIDB4ZjcsIDB4YWQsIDB4YjAsIDB4MTIsIDB4MDAsCisgIDB4ZjUsIDB4YmEsIDB4YjAsIDB4OWYsIDB4NGQsIDB4NTgsIDB4OGQsIDB4ZjAsIDB4ZjIsIDB4ZjcsIDB4NzUsIDB4OGEsCisgIDB4ZTQsIDB4YmUsIDB4MjEsIDB4ZTUsIDB4NDgsIDB4ODMsIDB4NmUsIDB4MDksIDB4ZTYsIDB4NzYsIDB4ZDcsIDB4NjUsCisgIDB4NzEsIDB4NTEsIDB4OTgsIDB4MDksIDB4MWUsIDB4MGYsIDB4NDksIDB4NTYsIDB4OWMsIDB4NTgsIDB4ZDcsIDB4N2YsCisgIDB4MmYsIDB4NjYsIDB4MmEsIDB4NTIsIDB4ZDcsIDB4N2QsIDB4YjAsIDB4NTgsIDB4MmQsIDB4ZjEsIDB4YWMsIDB4OWMsCisgIDB4MzUsIDB4YzUsIDB4MTEsIDB4MmQsIDB4OTcsIDB4NWQsIDB4MGMsIDB4YjIsIDB4YjgsIDB4ZTksIDB4NGMsIDB4NjgsCisgIDB4NmEsIDB4NTcsIDB4NWUsIDB4NjUsIDB4MTcsIDB4NDgsIDB4ZGIsIDB4YmEsIDB4MDAsIDB4OTIsIDB4YTQsIDB4MjUsCisgIDB4N2UsIDB4M2IsIDB4M2IsIDB4YWUsIDB4NmEsIDB4OTcsIDB4MzEsIDB4ZTIsIDB4MDgsIDB4ZWEsIDB4YTcsIDB4NmIsCisgIDB4MjcsIDB4YmMsIDB4YzgsIDB4M2IsIDB4NGUsIDB4MGIsIDB4OWIsIDB4NWYsIDB4ZWQsIDB4ZTksIDB4ODMsIDB4NzQsCisgIDB4N2UsIDB4MWUsIDB4MTMsIDB4NjEsIDB4ZDIsIDB4MTIsIDB4MmQsIDB4ZDYsIDB4YzAsIDB4ODcsIDB4ZTYsIDB4MTQsCisgIDB4MjEsIDB4NWMsIDB4YzksIDB4MDUsIDB4ZDIsIDB4M2IsIDB4MjYsIDB4NzQsIDB4NDAsIDB4MjMsIDB4YjMsIDB4NGEsCisgIDB4ODgsIDB4ZjAsIDB4NTAsIDB4YTksIDB4OWIsIDB4MjQsIDB4NmUsIDB4MWQsIDB4NjAsIDB4YjIsIDB4ZTQsIDB4YjcsCisgIDB4OGQsIDB4ZGEsIDB4OWYsIDB4YmMsIDB4NWYsIDB4Y2EsIDB4N2YsIDB4OWMsIDB4YWUsIDB4MWEsIDB4NTUsIDB4M2UsCisgIDB4N2IsIDB4ODcsIDB4YjgsIDB4ZjYsIDB4YWYsIDB4MjgsIDB4OWUsIDB4NGQsIDB4OWYsIDB4MDUsIDB4YTksIDB4MjMsCisgIDB4ZDUsIDB4NWIsIDB4OWQsIDB4YjEsIDB4NWYsIDB4NzIsIDB4ODUsIDB4MmMsIDB4NWUsIDB4ZWYsIDB4MGIsIDB4OTMsCisgIDB4MTAsIDB4OWQsIDB4MmEsIDB4MzQsIDB4NWUsIDB4NjgsIDB4ZjAsIDB4ZmQsIDB4NjksIDB4ZDAsIDB4M2QsIDB4YTMsCisgIDB4YTAsIDB4MWYsIDB4MTUsIDB4MmIsIDB4OTQsIDB4ZmUsIDB4ODgsIDB4YWUsIDB4ZTYsIDB4ZGEsIDB4YzUsIDB4NmMsCisgIDB4Y2QsIDB4MWIsIDB4NzAsIDB4OWEsIDB4NDgsIDB4NmIsIDB4NmEsIDB4NTQsIDB4NmIsIDB4NzMsIDB4MmEsIDB4ZTQsCisgIDB4NmIsIDB4NDMsIDB4NjQsIDB4YTksIDB4MGMsIDB4YTQsIDB4ZjIsIDB4ZjQsIDB4ZjEsIDB4M2EsIDB4YWMsIDB4MjQsCisgIDB4OWIsIDB4NzksIDB4OWIsIDB4MzYsIDB4ODYsIDB4MjMsIDB4YjQsIDB4MTEsIDB4YzgsIDB4YzUsIDB4ZDMsIDB4MmIsCisgIDB4YzksIDB4ZGQsIDB4NzIsIDB4M2IsIDB4NmYsIDB4MGMsIDB4NzAsIDB4YTAsIDB4MDIsIDB4ZTQsIDB4MDYsIDB4ZDIsCisgIDB4MGMsIDB4ZTQsIDB4YTAsIDB4ZWMsIDB4MDUsIDB4MjksIDB4YzcsIDB4MTMsIDB4Y2EsIDB4OTAsIDB4N2EsIDB4ZTgsCisgIDB4YjYsIDB4OTUsIDB4ZjUsIDB4ZmMsIDB4ZmEsIDB4ODUsIDB4OTgsIDB4YzQsIDB4MWMsIDB4NWEsIDB4ZmIsIDB4M2QsCisgIDB4YzUsIDB4YTEsIDB4OGYsIDB4MjksIDB4NjYsIDB4MTAsIDB4OTMsIDB4MjEsIDB4ZDksIDB4NGIsIDB4NzAsIDB4M2YsCisgIDB4M2MsIDB4MTIsIDB4NDEsIDB4NmQsIDB4MTIsIDB4MTYsIDB4NzYsIDB4YTIsIDB4MzQsIDB4OGYsIDB4MzcsIDB4NjcsCisgIDB4YWEsIDB4YzAsIDB4MDksIDB4MTQsIDB4ZTksIDB4NzYsIDB4YjYsIDB4NDgsIDB4N2EsIDB4ZDYsIDB4ZDUsIDB4ZDIsCisgIDB4ZDEsIDB4MmIsIDB4Y2EsIDB4NjcsIDB4NDMsIDB4NDksIDB4OTEsIDB4NmQsIDB4NzMsIDB4NjMsIDB4ZGYsIDB4NTAsCisgIDB4NDAsIDB4MjUsIDB4OTUsIDB4MWUsIDB4ZTUsIDB4MjEsIDB4NjAsIDB4MDEsIDB4ZWEsIDB4M2MsIDB4YTcsIDB4YzAsCisgIDB4NTQsIDB4Y2MsIDB4MDUsIDB4NWIsIDB4MmYsIDB4NTAsIDB4ZTAsIDB4NWQsIDB4OWEsIDB4NjUsIDB4YTcsIDB4ZDEsCisgIDB4YzgsIDB4MWQsIDB4OGMsIDB4YjcsIDB4MTAsIDB4MGEsIDB4OWEsIDB4ZTYsIDB4MWQsIDB4NzUsIDB4ZTIsIDB4OTUsCisgIDB4NzgsIDB4MWYsIDB4NjYsIDB4YWEsIDB4OWEsIDB4YjQsIDB4ZWMsIDB4OGIsIDB4ZTksIDB4ZDUsIDB4YmIsIDB4MjMsCisgIDB4YWYsIDB4YjIsIDB4MTEsIDB4NjksIDB4YzMsIDB4ZTQsIDB4ZGMsIDB4ZWQsIDB4NGMsIDB4YTEsIDB4OWUsIDB4NDYsCisgIDB4MTIsIDB4ZTksIDB4NTEsIDB4NjgsIDB4OTIsIDB4ODYsIDB4ZmEsIDB4NzMsIDB4MmMsIDB4YTQsIDB4ZTgsIDB4OWUsCisgIDB4NTQsIDB4OTUsIDB4MmIsIDB4NDcsIDB4ZDEsIDB4NDgsIDB4MzcsIDB4MzQsIDB4NGMsIDB4OTEsIDB4MmEsIDB4NmIsCisgIDB4YTgsIDB4OGYsIDB4ZTUsIDB4NTEsIDB4YTIsIDB4MmYsIDB4NGUsIDB4NGYsIDB4YmEsIDB4Y2EsIDB4NzEsIDB4MjksCisgIDB4M2UsIDB4NzEsIDB4MWMsIDB4ZmMsIDB4ZmMsIDB4ZTgsIDB4NDIsIDB4NDYsIDB4ODcsIDB4MzcsIDB4YmQsIDB4MjcsCisgIDB4YTIsIDB4NGEsIDB4MGYsIDB4NTIsIDB4NDgsIDB4MTYsIDB4ZWIsIDB4OGQsIDB4YTEsIDB4ZDYsIDB4ZDYsIDB4ZGIsCisgIDB4ODksIDB4MGEsIDB4NDIsIDB4ODEsIDB4MGEsIDB4NGEsIDB4YmEsIDB4ODIsIDB4MGYsIDB4ODEsIDB4MDcsIDB4ZWMsCisgIDB4YTUsIDB4MTcsIDB4MzEsIDB4MWMsIDB4MjYsIDB4Y2EsIDB4OTEsIDB4NzEsIDB4OWUsIDB4ZGIsIDB4NDgsIDB4OGQsCisgIDB4MGMsIDB4NzMsIDB4MzYsIDB4NjcsIDB4Y2IsIDB4NTIsIDB4ZDgsIDB4OGMsIDB4M2QsIDB4MjEsIDB4MmIsIDB4NTcsCisgIDB4MjIsIDB4NDAsIDB4ZjAsIDB4M2UsIDB4MTUsIDB4NTUsIDB4YmYsIDB4MjQsIDB4ZjgsIDB4NzgsIDB4MzQsIDB4NWQsCisgIDB4MmMsIDB4ZjIsIDB4MzIsIDB4N2UsIDB4MTQsIDB4NWMsIDB4ZWMsIDB4OTMsIDB4MTYsIDB4YTksIDB4MmUsIDB4YmYsCisgIDB4MTksIDB4ZTYsIDB4YTIsIDB4YzgsIDB4NzQsIDB4ZWYsIDB4YjYsIDB4ZTUsIDB4MjQsIDB4YzcsIDB4NzgsIDB4ZmEsCisgIDB4NDksIDB4ZDMsIDB4NmEsIDB4MjcsIDB4YzQsIDB4ZWUsIDB4OTAsIDB4N2YsIDB4MDYsIDB4N2IsIDB4ZmEsIDB4YWMsCisgIDB4ZWUsIDB4MWUsIDB4MWMsIDB4NWMsIDB4MTQsIDB4YTQsIDB4YjAsIDB4YTgsIDB4MmQsIDB4ZGUsIDB4YjEsIDB4YjUsCisgIDB4YWMsIDB4ZWMsIDB4MzksIDB4MDEsIDB4ZjEsIDB4Y2MsIDB4YTYsIDB4MDEsIDB4M2QsIDB4ZWEsIDB4NjUsIDB4YzIsCisgIDB4YTQsIDB4N2MsIDB4ZGUsIDB4NWYsIDB4MGEsIDB4NzMsIDB4YjksIDB4ZTYsIDB4MTcsIDB4M2MsIDB4OWEsIDB4MDMsCisgIDB4ZjAsIDB4NzgsIDB4N2QsIDB4NjcsIDB4OTMsIDB4MzAsIDB4M2MsIDB4OTIsIDB4ZDIsIDB4NmYsIDB4MzIsIDB4NDcsCisgIDB4NjEsIDB4MDksIDB4YWQsIDB4ODIsIDB4MzksIDB4ZDAsIDB4NTUsIDB4ZTcsIDB4YmIsIDB4YWYsIDB4ZDQsIDB4NDksCisgIDB4MWUsIDB4YmEsIDB4ODIsIDB4ZTIsIDB4YTYsIDB4MGYsIDB4MmEsIDB4ZDEsIDB4YzMsIDB4ZmMsIDB4NzYsIDB4ZjMsCisgIDB4ODgsIDB4MjMsIDB4YjcsIDB4YzgsIDB4NzAsIDB4MjYsIDB4ZDEsIDB4MjIsIDB4ZGYsIDB4ZTYsIDB4ZjIsIDB4YWEsCisgIDB4NjMsIDB4MGQsIDB4YTAsIDB4MjYsIDB4NDMsIDB4MGEsIDB4ZDcsIDB4ZjUsIDB4OGQsIDB4ODMsIDB4ZDMsIDB4ZjQsCisgIDB4ODAsIDB4ZjQsIDB4ZDEsIDB4YWMsIDB4MTIsIDB4OWUsIDB4NGIsIDB4ODQsIDB4NTEsIDB4NTAsIDB4ZjgsIDB4NmUsCisgIDB4NDUsIDB4NmMsIDB4Y2EsIDB4ZjEsIDB4NmIsIDB4NmUsIDB4NDcsIDB4NjcsIDB4N2IsIDB4YjYsIDB4ODEsIDB4NzEsCisgIDB4OGUsIDB4OTksIDB4MGMsIDB4YWIsIDB4NWQsIDB4NzQsIDB4YTEsIDB4ZGMsIDB4NDcsIDB4ODIsIDB4ODEsIDB4ZTgsCisgIDB4NDcsIDB4ODEsIDB4MDYsIDB4YTYsIDB4MDcsIDB4NzUsIDB4NDEsIDB4MjEsIDB4NDUsIDB4MTQsIDB4NTAsIDB4MDgsCisgIDB4OWMsIDB4NjUsIDB4ZjgsIDB4OTYsIDB4MmYsIDB4ZmIsIDB4NTUsIDB4NmMsIDB4ZmIsIDB4ZjEsIDB4NGYsIDB4NzQsCisgIDB4ODksIDB4YzYsIDB4NWYsIDB4ODksIDB4NjIsIDB4ZmYsIDB4MDAsIDB4YjUsIDB4NTYsIDB4Y2YsIDB4YmYsIDB4MTQsCisgIDB4ZjcsIDB4NDAsIDB4MWUsIDB4MjYsIDB4OGEsIDB4ZjIsIDB4YTQsIDB4ODIsIDB4N2EsIDB4ZDEsIDB4NGMsIDB4MTEsCisgIDB4OTQsIDB4N2EsIDB4YTQsIDB4Y2UsIDB4MzgsIDB4ZmMsIDB4OGYsIDB4NjUsIDB4ZGYsIDB4NDQsIDB4NDgsIDB4ZmUsCisgIDB4MDMsIDB4NGUsIDB4NzQsIDB4OTksIDB4YzcsIDB4MWYsIDB4OTEsIDB4ZWMsIDB4YmIsIDB4ZTgsIDB4ODksIDB4MWYsCisgIDB4YzAsIDB4NjgsIDB4NDgsIDB4ZGYsIDB4MWIsIDB4ZTIsIDB4ZWQsIDB4ZmMsIDB4YzEsIDB4ZjYsIDB4NTYsIDB4Y2EsCisgIDB4ZDcsIDB4MWIsIDB4ZTIsIDB4ZWQsIDB4ZmMsIDB4YzEsIDB4ZjYsIDB4NTYsIDB4Y2EsIDB4MDAsIDB4YTgsIDB4ZGMsCisgIDB4YTIsIDB4YzksIDB4NmUsIDB4YzgsIDB4ZjEsIDB4ZTksIDB4ZjYsIDB4MWIsIDB4YjMsIDB4MDEsIDB4ZjgsIDB4MzcsCisgIDB4MDYsIDB4MTcsIDB4MWQsIDB4ZjYsIDB4Y2YsIDB4OGEsIDB4NTQsIDB4MzQsIDB4NzUsIDB4ZTgsIDB4MjMsIDB4YmMsCisgIDB4MWYsIDB4MDIsIDB4MDUsIDB4NDksIDB4NTAsIDB4NDYsIDB4ZTgsIDB4MGYsIDB4OTgsIDB4NzgsIDB4MzUsIDB4MTIsCisgIDB4ZTUsIDB4NmEsIDB4YmYsIDB4NWMsIDB4NzEsIDB4YTksIDB4MzEsIDB4NWUsIDB4OTMsIDB4OTYsIDB4ZTMsIDB4NGIsCisgIDB4NmEsIDB4ZDMsIDB4M2UsIDB4NDAsIDB4OTIsIDB4MWIsIDB4NGMsIDB4OGIsIDB4NWEsIDB4NTIsIDB4YjcsIDB4MjEsCisgIDB4NGQsIDB4ZTQsIDB4NTcsIDB4ZTUsIDB4NTQsIDB4MDEsIDB4NGIsIDB4NWIsIDB4MWQsIDB4NDIsIDB4NGEsIDB4N2IsCisgIDB4ZjUsIDB4ZDIsIDB4ZWEsIDB4YmUsIDB4NjMsIDB4MTYsIDB4NmMsIDB4ZTYsIDB4MTQsIDB4MmIsIDB4ODQsIDB4OTcsCisgIDB4MjYsIDB4NDEsIDB4YjksIDB4NDUsIDB4NGEsIDB4OTAsIDB4YzQsIDB4ZTgsIDB4MmYsIDB4NzYsIDB4NmYsIDB4YjQsCisgIDB4MTUsIDB4YWUsIDB4NjQsIDB4ODMsIDB4ZDUsIDB4MmEsIDB4NDIsIDB4YjQsIDB4MGYsIDB4MmEsIDB4ODIsIDB4ODcsCisgIDB4YWIsIDB4NzUsIDB4NWIsIDB4ZmUsIDB4MTQsIDB4NTYsIDB4MjQsIDB4NTgsIDB4ZTYsIDB4YzAsIDB4ZTIsIDB4OWMsCisgIDB4NzgsIDB4NGIsIDB4OTUsIDB4MTIsIDB4MmIsIDB4MGEsIDB4YjQsIDB4ZTUsIDB4MzEsIDB4NWEsIDB4ZTgsIDB4YTksCisgIDB4NzYsIDB4YjcsIDB4Y2YsIDB4MmEsIDB4OTUsIDB4ZDMsIDB4YmQsIDB4NGQsIDB4MjgsIDB4ZjMsIDB4MjcsIDB4ZDAsCisgIDB4NDgsIDB4M2UsIDB4MTUsIDB4ZDcsIDB4YzMsIDB4ZWMsIDB4ZTIsIDB4NGQsIDB4OWIsIDB4MWEsIDB4YmQsIDB4NDMsCisgIDB4OWUsIDB4ZmEsIDB4MjcsIDB4ZGMsIDB4ZWQsIDB4MmMsIDB4MzcsIDB4ZDksIDB4YmUsIDB4MGUsIDB4ZDEsIDB4M2QsCisgIDB4MGUsIDB4MjQsIDB4MmEsIDB4MjQsIDB4OTAsIDB4N2YsIDB4NDUsIDB4ZDQsIDB4YTksIDB4M2MsIDB4YzcsIDB4YzEsCisgIDB4NDEsIDB4NjAsIDB4ZjcsIDB4NTYsIDB4ZjEsIDB4N2EsIDB4YTEsIDB4OGUsIDB4YWIsIDB4NzQsIDB4NjMsIDB4MzUsCisgIDB4ODksIDB4ZTcsIDB4YTMsIDB4ZDksIDB4OTMsIDB4MzMsIDB4YjgsIDB4NjcsIDB4OGEsIDB4NDIsIDB4M2UsIDB4ZWIsCisgIDB4ZjEsIDB4MTMsIDB4MjUsIDB4OTUsIDB4N2UsIDB4NjUsIDB4YWUsIDB4OGQsIDB4YjUsIDB4NzMsIDB4NzUsIDB4YjYsCisgIDB4MjIsIDB4MGQsIDB4MWQsIDB4OGQsIDB4YjAsIDB4ZDgsIDB4NGEsIDB4NWQsIDB4NTcsIDB4NDEsIDB4ZjAsIDB4ZjksCisgIDB4YjYsIDB4N2IsIDB4ODUsIDB4NGIsIDB4ZmYsIDB4MDAsIDB4MjksIDB4NmUsIDB4MGUsIDB4NDYsIDB4NmEsIDB4ZGYsCisgIDB4ODgsIDB4NjMsIDB4ZWQsIDB4NWIsIDB4YTEsIDB4MjUsIDB4MDEsIDB4MmMsIDB4M2IsIDB4MzUsIDB4ODIsIDB4ZGUsCisgIDB4OTMsIDB4ZTEsIDB4ZDksIDB4YzUsIDB4NGUsIDB4OTUsIDB4YWQsIDB4NzcsIDB4NzMsIDB4OTYsIDB4ZmQsIDB4ODQsCisgIDB4NTcsIDB4YTQsIDB4NWEsIDB4NjIsIDB4YzEsIDB4NzEsIDB4ZTksIDB4ZjcsIDB4MjksIDB4NGQsIDB4YmQsIDB4MzYsCisgIDB4MWIsIDB4N2MsIDB4ZjMsIDB4YWYsIDB4NTIsIDB4OTIsIDB4MTQsIDB4ZTMsIDB4NjcsIDB4NWIsIDB4MjgsIDB4NjQsCisgIDB4MTEsIDB4ZWYsIDB4NjksIDB4ZWIsIDB4YTAsIDB4OTQsIDB4ZjUsIDB4ZjQsIDB4ZWMsIDB4OWQsIDB4OWUsIDB4YWYsCisgIDB4NzYsIDB4Y2QsIDB4YTIsIDB4M2EsIDB4MWUsIDB4OGQsIDB4OGYsIDB4YWQsIDB4YTYsIDB4MWQsIDB4NTgsIDB4NGIsCisgIDB4NjYsIDB4NjQsIDB4YTQsIDB4YjMsIDB4MjYsIDB4NWEsIDB4YmYsIDB4NDUsIDB4YTYsIDB4YzgsIDB4MjUsIDB4NGEsCisgIDB4ZDAsIDB4ZTgsIDB4OTUsIDB4MTQsIDB4MTMsIDB4ZDAsIDB4NTUsIDB4NWEsIDB4NGIsIDB4NzksIDB4ZWUsIDB4YzksCisgIDB4NTksIDB4N2IsIDB4NDMsIDB4NjQsIDB4MjksIDB4ZGQsIDB4ZTIsIDB4MzksIDB4ZWUsIDB4YWEsIDB4ZmYsIDB4MDAsCisgIDB4OTQsIDB4ODgsIDB4YjgsIDB4ZGUsIDB4YTUsIDB4NDQsIDB4NjAsIDB4Y2MsIDB4NzEsIDB4NTIsIDB4OTIsIDB4ODQsCisgIDB4YjAsIDB4YzMsIDB4NjksIDB4MDMsIDB4NjUsIDB4YTYsIDB4Y2UsIDB4OWIsIDB4MmEsIDB4ZWEsIDB4MzUsIDB4YTAsCisgIDB4YTUsIDB4NmMsIDB4ZTgsIDB4YTgsIDB4MWEsIDB4NjcsIDB4Y2EsIDB4ZDksIDB4NjYsIDB4ZDIsIDB4NmMsIDB4MTksCisgIDB4MzMsIDB4MmIsIDB4NzUsIDB4ZDgsIDB4ZDAsIDB4YTQsIDB4MjgsIDB4NDgsIDB4NTIsIDB4OTQsIDB4NGUsIDB4ZGEsCisgIDB4N2QsIDB4MDEsIDB4MWMsIDB4ZTcsIDB4N2QsIDB4YzAsIDB4MWUsIDB4Y2YsIDB4ZDgsIDB4MzcsIDB4NGMsIDB4YTEsCisgIDB4OWIsIDB4MmUsIDB4NDUsIDB4MGEsIDB4MTUsIDB4YzEsIDB4NzEsIDB4YTMsIDB4NGYsIDB4OGUsIDB4NDIsIDB4NWYsCisgIDB4OGMsIDB4YjcsIDB4MWIsIDB4ZTYsIDB4ZDYsIDB4YzcsIDB4NDIsIDB4MzcsIDB4ZGQsIDB4ZTEsIDB4ZjUsIDB4OGYsCisgIDB4NTUsIDB4NzMsIDB4YjEsIDB4NzUsIDB4YzcsIDB4YjIsIDB4MzYsIDB4YTQsIDB4ZGEsIDB4ZGIsIDB4OWIsIDB4MWEsCisgIDB4NjIsIDB4NTYsIDB4MWMsIDB4NjEsIDB4ZjgsIDB4ZWEsIDB4MjQsIDB4MjksIDB4NDAsIDB4MTIsIDB4ODUsIDB4OGUsCisgIDB4NTMsIDB4YTMsIDB4YWUsIDB4ZjEsIDB4YjEsIDB4ZDMsIDB4YWUsIDB4ZjcsIDB4ZGQsIDB4NTEsIDB4ZWYsIDB4MWYsCisgIDB4MWQsIDB4MGIsIDB4N2IsIDB4YjUsIDB4ZjMsIDB4MzUsIDB4NjUsIDB4YWQsIDB4MTYsIDB4ZjEsIDB4MDcsIDB4ZDMsCisgIDB4MDUsIDB4YTcsIDB4NTQsIDB4Y2IsIDB4NjEsIDB4MGIsIDB4NWIsIDB4NGMsIDB4MTMsIDB4Y2UsIDB4ZTMsIDB4MDEsCisgIDB4NjksIDB4NTMsIDB4ODksIDB4NGUsIDB4OGUsIDB4ZjYsIDB4NTAsIDB4MTQsIDB4MDYsIDB4YmIsIDB4ZjcsIDB4YWEsCisgIDB4OGYsIDB4NWUsIDB4NjEsIDB4OGIsIDB4NWIsIDB4NjEsIDB4MzUsIDB4MTYsIDB4Y2QsIDB4ZDksIDB4Y2EsIDB4NWIsCisgIDB4OWYsIDB4OTAsIDB4ODcsIDB4MDEsIDB4YWUsIDB4NjUsIDB4YWYsIDB4ZDgsIDB4ODQsIDB4OGQsIDB4OGYsIDB4NmUsCisgIDB4YjUsIDB4ZTksIDB4YWUsIDB4NGMsIDB4NWEsIDB4ZjYsIDB4YWIsIDB4MDMsIDB4ZWEsIDB4YzUsIDB4NmYsIDB4Y2YsCisgIDB4YWIsIDB4YjYsIDB4OGEsIDB4NzksIDB4MjIsIDB4YmUsIDB4YmUsIDB4OGEsIDB4OTAsIDB4Y2YsIDB4ZTYsIDB4MmMsCisgIDB4MGYsIDB4MWUsIDB4OWQsIDB4MGUsIDB4YmIsIDB4OTQsIDB4MTUsIDB4ZTEsIDB4NWUsIDB4YWUsIDB4MzksIDB4ZGUsCisgIDB4MjMsIDB4NjQsIDB4OWMsIDB4YjgsIDB4MTYsIDB4ZTYsIDB4MGMsIDB4ZmIsIDB4YjMsIDB4YmUsIDB4NzEsIDB4ODUsCisgIDB4NmMsIDB4OGQsIDB4ZGEsIDB4NDgsIDB4NzAsIDB4ZmEsIDB4NTQsIDB4OTQsIDB4OGQsIDB4OGYsIDB4NmEsIDB4YjQsCisgIDB4M2QsIDB4NzUsIDB4M2EsIDB4MWUsIDB4NzMsIDB4OGMsIDB4OTQsIDB4ZDYsIDB4YjEsIDB4OGMsIDB4ZTAsIDB4OWIsCisgIDB4YzEsIDB4MjEsIDB4NGYsIDB4ODMsIDB4OGYsIDB4YTEsIDB4OGIsIDB4ODMsIDB4NmQsIDB4YjAsIDB4YjIsIDB4ZjMsCisgIDB4YWUsIDB4MzcsIDB4MTksIDB4MjcsIDB4N2QsIDB4ODMsIDB4NmEsIDB4NTksIDB4NTIsIDB4NWIsIDB4MjcsIDB4YzcsCisgIDB4NDAsIDB4ZWIsIDB4ZDUsIDB4ZGQsIDB4ZDcsIDB4NWIsIDB4YTUsIDB4YjcsIDB4MzMsIDB4MmMsIDB4N2IsIDB4MGYsCisgIDB4YmEsIDB4ZGYsIDB4MjAsIDB4NWMsIDB4MjcsIDB4YjQsIDB4ZGIsIDB4MWUsIDB4NTQsIDB4ODksIDB4MTEsIDB4OWEsCisgIDB4NDksIDB4MmIsIDB4NWEsIDB4OTQsIDB4ZjIsIDB4NzYsIDB4YjQsIDB4MjEsIDB4MjMsIDB4NjUsIDB4NDcsIDB4OWMsCisgIDB4MjksIDB4NWEsIDB4NDgsIDB4MjcsIDB4Y2YsIDB4ZWUsIDB4YTAsIDB4YzMsIDB4ZTIsIDB4MGUsIDB4NTcsIDB4YjMsCisgIDB4M2EsIDB4NDMsIDB4NzgsIDB4N2QsIDB4YWQsIDB4NDcsIDB4NWQsIDB4ODMsIDB4MWMsIDB4OTIsIDB4MjcsIDB4MzgsCisgIDB4OWYsIDB4NWEsIDB4YmEsIDB4YjYsIDB4ZDcsIDB4NGQsIDB4NzgsIDB4MzgsIDB4N2UsIDB4NmQsIDB4NmUsIDB4YjUsCisgIDB4YzEsIDB4YzEsIDB4YjAsIDB4YzcsIDB4MWYsIDB4NTUsIDB4YWQsIDB4YTYsIDB4MjcsIDB4NWYsIDB4NTYsIDB4YjQsCisgIDB4YjQsIDB4ZTEsIDB4ZjIsIDB4ODQsIDB4YzgsIDB4YjgsIDB4NDgsIDB4NWEsIDB4YjQsIDB4OTAsIDB4OTUsIDB4MjksCisgIDB4NjcsIDB4OTgsIDB4MGUsIDB4ODMsIDB4YTYsIDB4YzIsIDB4NDAsIDB4ZjAsIDB4MDAsIDB4NTUsIDB4NzAsIDB4OTcsCisgIDB4MjUsIDB4ZDMsIDB4NmMsIDB4ZDYsIDB4OWIsIDB4ZDYsIDB4N2YsIDB4OTIsIDB4OTEsIDB4ZWUsIDB4MjUsIDB4OGQsCisgIDB4YmMsIDB4NzYsIDB4MGEsIDB4YmIsIDB4YTYsIDB4NWUsIDB4MDEsIDB4ZWQsIDB4ODgsIDB4ZjEsIDB4ZTUsIDB4OGUsCisgIDB4OTMsIDB4Y2QsIDB4YmYsIDB4OWUsIDB4NTEsIDB4ZWMsIDB4YWYsIDB4NWYsIDB4YzgsIDB4OWIsIDB4MGQsIDB4YjksCisgIDB4YTUsIDB4ZGYsIDB4ZjMsIDB4NGIsIDB4OGIsIDB4ZDksIDB4MGMsIDB4OTgsIDB4YTksIDB4ZWQsIDB4OTQsIDB4ZmQsCisgIDB4Y2YsIDB4Y2UsIDB4NjEsIDB4OTIsIDB4M2MsIDB4NWIsIDB4NjAsIDB4MGUsIDB4NDAsIDB4N2MsIDB4MDcsIDB4NDUsCisgIDB4MmIsIDB4N2QsIDB4YzQsIDB4OWEsIDB4ZGQsIDB4OTQsIDB4NWMsIDB4ZjIsIDB4ZjgsIDB4NTYsIDB4YTUsIDB4NGIsCisgIDB4OTIsIDB4YzUsIDB4YmEsIDB4MGMsIDB4MjcsIDB4NTYsIDB4ZGIsIDB4NzIsIDB4MWQsIDB4OGUsIDB4ZWEsIDB4OTYsCisgIDB4ZjQsIDB4MDYsIDB4OTQsIDB4YjQsIDB4ODUsIDB4M2EsIDB4NDksIDB4MDEsIDB4MmIsIDB4ZTUsIDB4NDksIDB4M2QsCisgIDB4YzAsIDB4NjgsIDB4ZjUsIDB4ZWEsIDB4MDcsIDB4NWQsIDB4MTMsIDB4MmMsIDB4MzgsIDB4YmQsIDB4YzksIDB4MzMsCisgIDB4YTAsIDB4NTksIDB4ZGMsIDB4OGMsIDB4MzIsIDB4MGIsIDB4N2IsIDB4ZTgsIDB4NzAsIDB4NDksIDB4OTIsIDB4YjUsCisgIDB4MzgsIDB4ZjcsIDB4NmUsIDB4OGUsIDB4NTcsIDB4MDAsIDB4NzUsIDB4NDQsIDB4ZjMsIDB4MjksIDB4YjMsIDB4ZTYsCisgIDB4ZWMsIDB4NzcsIDB4NjgsIDB4ZjQsIDB4ZDcsIDB4NGEsIDB4OGQsIDB4NGQsIDB4ZjAsIDB4NGEsIDB4OGEsIDB4NWMsCisgIDB4OWQsIDB4OTcsIDB4ZmMsIDB4OTYsIDB4ZmQsIDB4MGUsIDB4YzEsIDB4MjYsIDB4ZTUsIDB4MGYsIDB4MTgsIDB4NzEsCisgIDB4ODgsIDB4YTgsIDB4NDgsIDB4NGEsIDB4MWMsIDB4OTIsIDB4ZjAsIDB4MGUsIDB4YjQsIDB4MGUsIDB4ODcsIDB4NmEsCisgIDB4YTYsIDB4NDAsIDB4M2UsIDB4NjIsIDB4NzcsIDB4Y2MsIDB4NDEsIDB4NTAsIDB4NTYsIDB4ODEsIDB4ZTgsIDB4M2IsCisgIDB4YWIsIDB4NTEsIDB4YjUsIDB4YzAsIDB4OTgsIDB4OTksIDB4NWUsIDB4NDUsIDB4OTIsIDB4NGMsIDB4N2EsIDB4ZmIsCisgIDB4MTUsIDB4NDAsIDB4MjYsIDB4NzMsIDB4YjMsIDB4MDksIDB4NGEsIDB4MWUsIDB4ZDAsIDB4NTAsIDB4NGYsIDB4NjYsCisgIDB4OTIsIDB4MWIsIDB4ZTQsIDB4M2IsIDB4MDAsIDB4YTQsIDB4MjQsIDB4NzQsIDB4NTcsIDB4YWMsIDB4MWEsIDB4OGYsCisgIDB4YjQsIDB4NjYsIDB4MzcsIDB4NzksIDB4ZWUsIDB4YmUsIDB4YjUsIDB4ZGEsIDB4NDQsIDB4ZmIsIDB4N2MsIDB4YzgsCisgIDB4ZTgsIDB4N2QsIDB4ODgsIDB4ZTEsIDB4ODcsIDB4NTIsIDB4ZTIsIDB4MDIsIDB4ZGIsIDB4NGUsIDB4ZGEsIDB4NTksCisgIDB4NWEsIDB4MDMsIDB4M2QsIDB4OWUsIDB4ZjksIDB4OGYsIDB4NjksIDB4Y2YsIDB4ZDQsIDB4MWYsIDB4ODMsIDB4NTAsCisgIDB4MzYsIDB4OWIsIDB4NmQsIDB4YmUsIDB4M2EsIDB4YTIsIDB4YTYsIDB4ZGYsIDB4N2YsIDB4ODUsIDB4NzIsIDB4YmQsCisgIDB4YmEsIDB4YzMsIDB4NzAsIDB4ZDQsIDB4ZDUsIDB4YTgsIDB4MzYsIDB4OTksIDB4MGUsIDB4MDQsIDB4YTMsIDB4YjgsCisgIDB4YmUsIDB4NDksIDB4ZjcsIDB4YjQsIDB4ODQsIDB4ZWIsIDB4YjUsIDB4ZTUsIDB4ZTcsIDB4MDAsIDB4MDAsIDB4MTUsCisgIDB4YmQsIDB4MjYsIDB4YTMsIDB4NjUsIDB4YzksIDB4M2IsIDB4YmUsIDB4MGUsIDB4MWUsIDB4MGEsIDB4ZGMsIDB4YzYsCisgIDB4MjMsIDB4OWYsIDB4YzksIDB4YzIsIDB4ZDYsIDB4ZDcsIDB4OTMsIDB4NTgsIDB4ZjIsIDB4NjQsIDB4YmQsIDB4NzksCisgIDB4YzcsIDB4ZGIsIDB4ZGYsIDB4OWIsIDB4MTksIDB4ZjAsIDB4YTIsIDB4MjYsIDB4YzIsIDB4MWUsIDB4MWEsIDB4NGIsCisgIDB4OWIsIDB4NzEsIDB4M2EsIDB4ZDcsIDB4OWEsIDB4YWYsIDB4ZWUsIDB4YmQsIDB4NTMsIDB4ZGMsIDB4MmEsIDB4OTIsCisgIDB4ZTMsIDB4MWUsIDB4MzEsIDB4OTAsIDB4YmIsIDB4ODYsIDB4NWIsIDB4MWEsIDB4ODEsIDB4MTIsIDB4ZDUsIDB4MGEsCisgIDB4ZTMsIDB4NjgsIDB4OTQsIDB4ODksIDB4NTgsIDB4ZjMsIDB4ZjAsIDB4YjksIDB4Y2YsIDB4OTIsIDB4NGMsIDB4NDcsCisgIDB4ZTQsIDB4ZGEsIDB4NzEsIDB4NGIsIDB4ZWEsIDB4YjQsIDB4M2MsIDB4MzYsIDB4ZDksIDB4M2UsIDB4NmUsIDB4ZDQsCisgIDB4YjQsIDB4ZWMsIDB4MWQsIDB4ZWUsIDB4YWMsIDB4NmUsIDB4MTYsIDB4ZTYsIDB4NTAsIDB4NzMsIDB4Y2MsIDB4MTIsCisgIDB4ZGIsIDB4OTMsIDB4YzAsIDB4NDEsIDB4NjQsIDB4NDksIDB4NmYsIDB4NGYsIDB4YzcsIDB4NTEsIDB4ZjMsIDB4ZTMsCisgIDB4YmUsIDB4OTMsIDB4Y2EsIDB4ZTMsIDB4NGEsIDB4MWUsIDB4MDUsIDB4MmEsIDB4MDQsIDB4NzUsIDB4ZjAsIDB4ZDEsCisgIDB4ZjEsIDB4YTgsIDB4MjQsIDB4NjgsIDB4YTIsIDB4ODEsIDB4ZGQsIDB4NDUsIDB4MDAsIDB4ODksIDB4YzYsIDB4NWYsCisgIDB4ODksIDB4NjIsIDB4ZmYsIDB4MDAsIDB4YjUsIDB4NTYsIDB4Y2YsIDB4YmYsIDB4MTQsIDB4ZjcsIDB4NDgsIDB4OWMsCisgIDB4NjUsIDB4ZjgsIDB4OTYsIDB4MmYsIDB4ZmIsIDB4NTUsIDB4NmMsIDB4ZmIsIDB4ZjEsIDB4NGYsIDB4NzQsIDB4MDcsCisgIDB4OTUsIDB4MTAsIDB4MGYsIDB4NTIsIDB4MDcsIDB4YjYsIDB4OGEsIDB4YzksIDB4MWQsIDB4NjgsIDB4YTgsIDB4MTgsCisgIDB4NDYsIDB4NjksIDB4MzMsIDB4OGUsIDB4M2YsIDB4MjMsIDB4ZDksIDB4NzcsIDB4ZDEsIDB4MTIsIDB4M2YsIDB4ODAsCisgIDB4ZDMsIDB4OWQsIDB4MjYsIDB4NzEsIDB4YzcsIDB4ZTQsIDB4N2IsIDB4MmUsIDB4ZmEsIDB4MjIsIDB4NDcsIDB4ZjAsCisgIDB4MWEsIDB4OTAsIDB4MzcsIDB4YzYsIDB4ZjgsIDB4YmIsIDB4N2YsIDB4MzAsIDB4N2QsIDB4OTUsIDB4YjIsIDB4YjUsCisgIDB4YzYsIDB4ZjgsIDB4YmIsIDB4N2YsIDB4MzAsIDB4N2QsIDB4OTUsIDB4YjIsIDB4ODAsIDB4MjgsIDB4YTIsIDB4OGEsCisgIDB4MDMsIDB4OTYsIDB4ZTksIDB4MGEsIDB4MmQsIDB4Y2EsIDB4ZGYsIDB4MjYsIDB4ZGYsIDB4MzksIDB4ODYsIDB4ZTQsCisgIDB4NDUsIDB4OTQsIDB4ZDIsIDB4OTksIDB4N2QsIDB4YTUsIDB4OGQsIDB4YTUsIDB4YzQsIDB4MjgsIDB4MTAsIDB4YTQsCisgIDB4OTEsIDB4ZTgsIDB4MjAsIDB4OWEsIDB4ZjgsIDB4ZGEsIDB4ZTMsIDB4MDYsIDB4ZTEsIDB4ODQsIDB4Y2EsIDB4YmQsCisgIDB4ZTIsIDB4NzMsIDB4MjQsIDB4MmYsIDB4YjQsIDB4YzUsIDB4ZDgsIDB4NTQsIDB4NTQsIDB4YmEsIDB4YjUsIDB4MTIsCisgIDB4NWUsIDB4YjEsIDB4NDksIDB4NzMsIDB4OWUsIDB4MjQsIDB4OGQsIDB4ZjgsIDB4ZjksIDB4MmMsIDB4OTIsIDB4MDIsCisgIDB4YmYsIDB4NTUsIDB4YzUsIDB4NzgsIDB4MjYsIDB4YmUsIDB4ZDMsIDB4ZDUsIDB4NTIsIDB4ZmYsIDB4MDAsIDB4ODQsCisgIDB4ZWUsIDB4M2UsIDB4ZmMsIDB4N2IsIDB4N2MsIDB4MGUsIDB4MjYsIDB4NWEsIDB4MjAsIDB4MjYsIDB4NzQsIDB4ZmMsCisgIDB4NjgsIDB4MzgsIDB4OWIsIDB4OGMsIDB4MzIsIDB4OWUsIDB4NjEsIDB4NzAsIDB4YjUsIDB4M2EsIDB4MzksIDB4NjUsCisgIDB4MzAsIDB4YTEsIDB4ZTMsIDB4ZTYsIDB4OTIsIDB4YTEsIDB4YmUsIDB4ZWYsIDB4MzgsIDB4ZDQsIDB4YTcsIDB4ODcsCisgIDB4OTIsIDB4MWEsIDB4Y2EsIDB4YzAsIDB4ZDksIDB4OGYsIDB4NGMsIDB4NjMsIDB4MzksIDB4YzAsIDB4MjQsIDB4YmQsCisgIDB4MDksIDB4YzEsIDB4MWQsIDB4ZWIsIDB4ODMsIDB4NDUsIDB4NDQsIDB4ZjcsIDB4ODYsIDB4MjQsIDB4MDAsIDB4MDIsCisgIDB4OTAsIDB4YWYsIDB4NWEsIDB4MWMsIDB4NDksIDB4MDQsIDB4N2EsIDB4M2QsIDB4YmIsIDB4YTgsIDB4MzUsIDB4ZTMsCisgIDB4ZjcsIDB4OTcsIDB4ZWYsIDB4ODIsIDB4NWEsIDB4ZWMsIDB4OTcsIDB4MTcsIDB4ZWUsIDB4NGIsIDB4NWYsIDB4OTQsCisgIDB4MTEsIDB4MmUsIDB4N2UsIDB4ZWQsIDB4ZDEsIDB4NWQsIDB4NTYsIDB4OGEsIDB4OTYsIDB4MDAsIDB4ZjMsIDB4OTcsCisgIDB4YTIsIDB4OTQsIDB4ZTksIDB4MWQsIDB4N2EsIDB4MDEsIDB4YmQsIDB4NjgsIDB4NmEsIDB4YmQsIDB4ZTAsIDB4NjIsCisgIDB4ZTcsIDB4NDAsIDB4OTksIDB4MmUsIDB4ZDksIDB4ODgsIDB4ZGYsIDB4MTgsIDB4MmYsIDB4YzYsIDB4ZWMsIDB4OTYsCisgIDB4YzMsIDB4NTMsIDB4YjksIDB4OTUsIDB4MTYsIDB4ZWYsIDB4NmYsIDB4NzUsIDB4M2MsIDB4ZDAsIDB4ZTQsIDB4MTIsCisgIDB4OWYsIDB4MzksIDB4YjcsIDB4ODMsIDB4N2UsIDB4ZjQsIDB4YTcsIDB4MTIsIDB4MGYsIDB4OWMsIDB4Y2UsIDB4OTQsCisgIDB4MDksIDB4ZDYsIDB4YWQsIDB4ZTcsIDB4YTQsIDB4NzEsIDB4NTYsIDB4NmEsIDB4ZmIsIDB4MzYsIDB4YWQsIDB4MTgsCisgIDB4YTUsIDB4YTksIDB4MjQsIDB4ZjUsIDB4N2QsIDB4NzcsIDB4MTcsIDB4YTQsIDB4OTQsIDB4OGYsIDB4NDgsIDB4NDAsCisgIDB4NjUsIDB4MWMsIDB4YzcsIDB4ZGEsIDB4YTQsIDB4ZWUsIDB4YjQsIDB4OTcsIDB4MzksIDB4N2QsIDB4NGMsIDB4YTMsCisgIDB4YzYsIDB4MTcsIDB4NDEsIDB4YWEsIDB4ZGIsIDB4MWUsIDB4MmQsIDB4YTIsIDB4ZDQsIDB4ZGMsIDB4NjUsIDB4YmEsCisgIDB4ZGEsIDB4NTIsIDB4OWUsIDB4NzUsIDB4MmQsIDB4NGEsIDB4M2MsIDB4YTksIDB4MmEsIDB4NTEsIDB4MmEsIDB4NWEsCisgIDB4YjQsIDB4NGYsIDB4NDAsIDB4NGEsIDB4OTQsIDB4NzUsIDB4ZTEsIDB4YmEsIDB4YWUsIDB4NjMsIDB4ZGQsIDB4ZjEsCisgIDB4OTYsIDB4YWYsIDB4MzIsIDB4MTUsIDB4ODMsIDB4ZDgsIDB4ZTYsIDB4ZTUsIDB4NzcsIDB4MzAsIDB4ZjEsIDB4MmQsCisgIDB4YmEsIDB4Y2YsIDB4OWQsIDB4MTYsIDB4MGEsIDB4YjksIDB4NzQsIDB4YTQsIDB4MjYsIDB4NDIsIDB4ZjQsIDB4OTYsCisgIDB4ZDIsIDB4NzYsIDB4NDksIDB4NGEsIDB4NDksIDB4M2IsIDB4MjcsIDB4YTcsIDB4ODUsIDB4NDgsIDB4ZGMsIDB4YjAsCisgIDB4ZmIsIDB4NWIsIDB4NGQsIDB4MGIsIDB4OGYsIDB4MTAsIDB4ZjIsIDB4NDksIDB4NTcsIDB4ZDQsIDB4OTUsIDB4ODQsCisgIDB4ODgsIDB4ZWUsIDB4MGUsIDB4YzIsIDB4MjIsIDB4ZDUsIDB4ZGUsIDB4MTIsIDB4MjMsIDB4YjcsIDB4YjIsIDB4ZTksCisgIDB4ZWYsIDB4ZjMsIDB4NTQsIDB4NTcsIDB4YmYsIDB4MDEsIDB4NTIsIDB4M2YsIDB4Y2EsIDB4NDQsIDB4ZjYsIDB4ZjAsCisgIDB4ZjEsIDB4YmIsIDB4MDUsIDB4YWQsIDB4Y2IsIDB4NWMsIDB4OTcsIDB4NTAsIDB4YTUsIDB4MjMsIDB4Y2IsIDB4NjAsCisgIDB4YTksIDB4YTYsIDB4NjMsIDB4YzYsIDB4NDAsIDB4ZjMsIDB4OWQsIDB4MDgsIDB4MWEsIDB4MGEsIDB4MWIsIDB4MjksCisgIDB4NDgsIDB4NGUsIDB4ZDIsIDB4NzYsIDB4YTEsIDB4YmQsIDB4NzgsIDB4ZDMsIDB4YmEsIDB4YmQsIDB4NGQsIDB4MzEsCisgIDB4MjYsIDB4NDUsIDB4NGUsIDB4YzMsIDB4MmUsIDB4ZDksIDB4MzQsIDB4NjUsIDB4NGEsIDB4ZTIsIDB4NGQsIDB4ZjYsCisgIDB4M2IsIDB4NzYsIDB4ZTQsIDB4MTIsIDB4YjMsIDB4NmMsIDB4YjcsIDB4OWUsIDB4Y2QsIDB4ODQsIDB4MjcsIDB4ZDAsCisgIDB4ZTQsIDB4ODUsIDB4MGUsIDB4ZDEsIDB4NWQsIDB4M2IsIDB4Y2EsIDB4N2IsIDB4MzEsIDB4ZWQsIDB4ZWYsIDB4M2QsCisgIDB4YjYsIDB4NmIsIDB4YmUsIDB4MTksIDB4OGYsIDB4NDMsIDB4NjIsIDB4Y2IsIDB4ODUsIDB4ZGIsIDB4NjEsIDB4ZjYsCisgIDB4ZDIsIDB4NTcsIDB4ZDksIDB4YzUsIDB4ODksIDB4MTUsIDB4YWUsIDB4YzEsIDB4MzIsIDB4MDgsIDB4MDcsIDB4NmIsCisgIDB4ZWQsIDB4MGEsIDB4NzQsIDB4YjQsIDB4YTQsIDB4MDIsIDB4NTQsIDB4YjEsIDB4Y2MsIDB4NDAsIDB4MWUsIDB4MjQsCisgIDB4ZWEsIDB4OGMsIDB4OGUsIDB4ZGIsIDB4MmUsIDB4MGMsIDB4YmIsIDB4NDQsIDB4ZWIsIDB4Y2QsIDB4ZGQsIDB4ZmIsCisgIDB4YmQsIDB4OTksIDB4MTIsIDB4ZDIsIDB4MjcsIDB4MzUsIDB4MjEsIDB4YTYsIDB4OTIsIDB4ODQsIDB4MmQsIDB4NjMsCisgIDB4OTEsIDB4YTcsIDB4MDAsIDB4NGEsIDB4NTMsIDB4ZWYsIDB4NjksIDB4NWEsIDB4ODYsIDB4YzEsIDB4MjcsIDB4NWQsCisgIDB4MGYsIDB4ODEsIDB4ZGYsIDB4MWUsIDB4NTMsIDB4OTUsIDB4NDQsIDB4YjgsIDB4NDAsIDB4NzYsIDB4MzMsIDB4MzEsCisgIDB4YTYsIDB4YjEsIDB4OTAsIDB4ZGIsIDB4NjYsIDB4MDMsIDB4MDksIDB4YTUsIDB4YzcsIDB4NWIsIDB4NmUsIDB4MjksCisgIDB4ZTAsIDB4YTIsIDB4MTEsIDB4Y2EsIDB4MDgsIDB4MWMsIDB4ZTgsIDB4NzEsIDB4M2MsIDB4YzAsIDB4OTQsIDB4ZWQsCisgIDB4M2MsIDB4YWEsIDB4M2QsIDB4N2MsIDB4NDMsIDB4NzksIDB4MGQsIDB4YTIsIDB4NzUsIDB4ZTUsIDB4MDksIDB4YzksCisgIDB4OWEsIDB4ODksIDB4MGQsIDB4ZGIsIDB4ZTQsIDB4ZjgsIDB4NjYsIDB4Y2UsIDB4ZjQsIDB4OTQsIDB4MjIsIDB4ZTgsCisgIDB4ODgsIDB4MGQsIDB4YWQsIDB4YjUsIDB4YjAsIDB4YzksIDB4ZDgsIDB4MWEsIDB4NzAsIDB4YWYsIDB4NmEsIDB4NmMsCisgIDB4YTgsIDB4YTQsIDB4MmMsIDB4ZTksIDB4MjcsIDB4OTcsIDB4NjQsIDB4NjgsIDB4NmUsIDB4YjksIDB4YWUsIDB4OTMsCisgIDB4NzEsIDB4NjksIDB4ZjgsIDB4OWMsIDB4ODksIDB4ZDYsIDB4MDEsIDB4MTIsIDB4MTQsIDB4OGIsIDB4MTMsIDB4OGUsCisgIDB4NDgsIDB4OGUsIDB4NTIsIDB4YzAsIDB4NDAsIDB4OGEsIDB4ZmIsIDB4NjQsIDB4ODIsIDB4ODUsIDB4ODAsIDB4MDcsCisgIDB4MmYsIDB4M2UsIDB4OGEsIDB4MGEsIDB4NGYsIDB4NTIsIDB4MTUsIDB4ZDAsIDB4NmYsIDB4YmIsIDB4ODYsIDB4ZWEsCisgIDB4YWMsIDB4OTUsIDB4ODQsIDB4NWMsIDB4MmQsIDB4ZDcsIDB4NjksIDB4NjYsIDB4MzQsIDB4MmIsIDB4YTIsIDB4ZGQsCisgIDB4NjksIDB4ODQsIDB4M2UsIDB4ZGEsIDB4MWQsIDB4N2QsIDB4MjgsIDB4NzMsIDB4N2MsIDB4ZTgsIDB4NjksIDB4YjYsCisgIDB4NGEsIDB4OTQsIDB4ZjksIDB4MDEsIDB4NWUsIDB4NmEsIDB4OTQsIDB4MTEsIDB4Y2IsIDB4ZDMsIDB4OTgsIDB4MmEsCisgIDB4YjMsIDB4MWUsIDB4MWQsIDB4YWUsIDB4NDUsIDB4ZmIsIDB4YzgsIDB4YTAsIDB4NDQsIDB4OTksIDB4NmQsIDB4N2QsCisgIDB4OTYsIDB4ZDMsIDB4MzEsIDB4ZjcsIDB4ZWYsIDB4MjEsIDB4NmUsIDB4OTYsIDB4OTMsIDB4YmUsIDB4NDYsIDB4ZDQsCisgIDB4ZDIsIDB4MTYsIDB4YTIsIDB4ODUsIDB4MmMsIDB4ZTgsIDB4ODAsIDB4YjMsIDB4Y2QsIDB4YzksIDB4YTAsIDB4MzUsCisgIDB4ZDQsIDB4MGEsIDB4NjEsIDB4MmYsIDB4NTIsIDB4NzcsIDB4NjEsIDB4NzUsIDB4YmMsIDB4NjUsIDB4MmIsIDB4NWQsCisgIDB4ZDMsIDB4Y2EsIDB4OWIsIDB4NDQsIDB4M2IsIDB4MmMsIDB4YjYsIDB4ODgsIDB4NmYsIDB4ZGQsIDB4NTYsIDB4OTIsCisgIDB4YzgsIDB4OGMsIDB4YjUsIDB4YTMsIDB4NDUsIDB4MmEsIDB4NWYsIDB4MzEsIDB4ZWQsIDB4NTMsIDB4ZGUsIDB4NTIsCisgIDB4ODQsIDB4MjcsIDB4OTgsIDB4OTUsIDB4MDAsIDB4NDgsIDB4ZDEsIDB4YWQsIDB4NDYsIDB4ZDksIDB4NjksIDB4OTcsCisgIDB4MzksIDB4OGIsIDB4NTUsIDB4YWQsIDB4ZTksIDB4OTcsIDB4NWIsIDB4OWIsIDB4ZDEsIDB4NDIsIDB4NWMsIDB4NmUsCisgIDB4ZTAsIDB4YzksIDB4ODgsIDB4ODMsIDB4MWQsIDB4YjQsIDB4ODAsIDB4MTYsIDB4ZjIsIDB4ODMsIDB4NDksIDB4NzksCisgIDB4ZTYsIDB4YjksIDB4ODgsIDB4ZDIsIDB4MGEsIDB4OTQsIDB4OTIsIDB4NDksIDB4MDQsIDB4ZTgsIDB4MTMsIDB4NWQsCisgIDB4ZjksIDB4NjMsIDB4YjMsIDB4MzEsIDB4MGIsIDB4OTQsIDB4NGMsIDB4OGUsIDB4NTIsIDB4ZWUsIDB4MzksIDB4MmMsCisgIDB4MzQsIDB4MzIsIDB4YjYsIDB4NjMsIDB4YjYsIDB4ZTIsIDB4NWEsIDB4MmUsIDB4YjAsIDB4ZmEsIDB4ODgsIDB4MjUsCisgIDB4NjksIDB4ZTUsIDB4NGEsIDB4NzYsIDB4MTQsIDB4ODQsIDB4YWIsIDB4NDMsIDB4NWIsIDB4ZDgsIDB4ZTUsIDB4MWYsCisgIDB4MGMsIDB4MDEsIDB4OWMsIDB4OWUsIDB4ZTksIDB4NmUsIDB4Y2EsIDB4ZDgsIDB4YjYsIDB4MmIsIDB4MWUsIDB4OTEsCisgIDB4MmQsIDB4MzcsIDB4NDksIDB4MGEsIDB4NTMsIDB4MjksIDB4ZWMsIDB4NDIsIDB4OTgsIDB4N2QsIDB4MzEsIDB4NWMsCisgIDB4MWMsIDB4YWUsIDB4YTksIDB4NWIsIDB4NGUsIDB4ZGIsIDB4NDgsIDB4ZTgsIDB4YTAsIDB4YTUsIDB4MjcsIDB4ZTEsCisgIDB4YTEsIDB4M2EsIDB4MDcsIDB4YjgsIDB4YzYsIDB4ZmQsIDB4NDIsIDB4YzYsIDB4NzYsIDB4M2QsIDB4NjQsIDB4YjEsCisgIDB4ZTcsIDB4NWEsIDB4OTcsIDB4NmIsIDB4MzksIDB4MWMsIDB4ODYsIDB4NmUsIDB4NzgsIDB4ZjIsIDB4MGEsIDB4Y2EsCisgIDB4ZTMsIDB4NDYsIDB4ODMsIDB4YzgsIDB4OTAsIDB4ZjIsIDB4NTMsIDB4ZWYsIDB4MmQsIDB4ZjIsIDB4MDIsIDB4NzksCisgIDB4OWIsIDB4MjQsIDB4MTAsIDB4OTAsIDB4N2YsIDB4M2YsIDB4OTAsIDB4NzUsIDB4ZGUsIDB4ODYsIDB4Y2MsIDB4YzIsCisgIDB4ZTMsIDB4NjgsIDB4YmIsIDB4ZTEsIDB4ZDAsIDB4MzIsIDB4NGIsIDB4MWMsIDB4OTQsIDB4YTIsIDB4NTMsIDB4MGIsCisgIDB4NDcsIDB4YjksIDB4NmUsIDB4YjIsIDB4MDAsIDB4NTIsIDB4Y2IsIDB4YmEsIDB4NGEsIDB4OTksIDB4NmYsIDB4YTYsCisgIDB4OTQsIDB4NTQsIDB4OWQsIDB4OGQsIDB4MGUsIDB4ZTIsIDB4OTAsIDB4N2YsIDB4MzYsIDB4YjgsIDB4MTUsIDB4ZWUsCisgIDB4ZDAsIDB4YjYsIDB4NDQsIDB4YzcsIDB4ZjIsIDB4ODksIDB4NmUsIDB4MmMsIDB4OTUsIDB4MzYsIDB4ZWIsIDB4YWQsCisgIDB4MzYsIDB4ODAsIDB4ZjQsIDB4ZDksIDB4NDksIDB4NmQsIDB4NjEsIDB4NDksIDB4MDksIDB4NmQsIDB4OTEsIDB4Y2EsCisgIDB4ZGEsIDB4NzYsIDB4OWQsIDB4MTUsIDB4OTIsIDB4NzcsIDB4YTMsIDB4ZDEsIDB4MzUsIDB4ZDcsIDB4NjAsIDB4YjcsCisgIDB4YzQsIDB4YjksIDB4ZGUsIDB4NjQsIDB4MmUsIDB4YzAsIDB4YzMsIDB4YjYsIDB4NTYsIDB4ZTAsIDB4MTQsIDB4YzcsCisgIDB4N2EsIDB4NGMsIDB4YjYsIDB4ZDQsIDB4ZWMsIDB4ZDQsIDB4YjgsIDB4YTQsIDB4ZjMsIDB4MjksIDB4YTYsIDB4YmIsCisgIDB4NjIsIDB4YTAsIDB4ZDIsIDB4NDIsIDB4NTQsIDB4MzYsIDB4NDAsIDB4MjEsIDB4NWIsIDB4ZTksIDB4ZDAsIDB4NmMsCisgIDB4YjYsIDB4NWMsIDB4MDUsIDB4OTcsIDB4YzksIDB4Y2YsIDB4NzAsIDB4OTksIDB4N2IsIDB4N2IsIDB4MTEsIDB4MzYsCisgIDB4NWMsIDB4OTEsIDB4ZjQsIDB4YzYsIDB4MGYsIDB4MjgsIDB4MzMsIDB4MjYsIDB4ZTUsIDB4MzUsIDB4ODYsIDB4ZTMsCisgIDB4MDIsIDB4OTAsIDB4YTEsIDB4ZDEsIDB4OTYsIDB4NTAsIDB4ZTIsIDB4ZDQsIDB4YjcsIDB4NDgsIDB4MWIsIDB4MDQsCisgIDB4MTAsIDB4OTAsIDB4NDEsIDB4MjMsIDB4YzAsIDB4NTIsIDB4ZGUsIDB4MzksIDB4NzgsIDB4YjcsIDB4ZTEsIDB4N2MsCisgIDB4NzQsIDB4OTAsIDB4YzQsIDB4MDksIDB4MDQsIDB4ZTIsIDB4ZDksIDB4ZDMsIDB4Y2EsIDB4NWEsIDB4MDIsIDB4OTAsCisgIDB4YTQsIDB4MDgsIDB4NzcsIDB4OTQsIDB4MjQsIDB4MTcsIDB4MTAsIDB4NTIsIDB4YWQsIDB4MjksIDB4M2QsIDB4YjMsCisgIDB4N2EsIDB4NWYsIDB4NTEsIDB4ZDUsIDB4NDMsIDB4YTcsIDB4NGEsIDB4NmQsIDB4OWMsIDB4NmUsIDB4MTgsIDB4YmUsCisgIDB4NDcsIDB4MzIsIDB4NTMsIDB4ZDEsIDB4NjUsIDB4ZTQsIDB4ZDIsIDB4OWMsIDB4OGEsIDB4ODUsIDB4ZGEsIDB4ODIsCisgIDB4OGIsIDB4NjEsIDB4ZmUsIDB4YzUsIDB4YjUsIDB4N2YsIDB4MzgsIDB4NjksIDB4MDQsIDB4MDQsIDB4ODIsIDB4ZTAsCisgIDB4MGIsIDB4ZTcsIDB4MWQsIDB4MDEsIDB4NTgsIDB4ZDIsIDB4NzYsIDB4NGEsIDB4NzcsIDB4NGIsIDB4ZmMsIDB4NTEsCisgIDB4YjEsIDB4NDYsIDB4ZTIsIDB4NGMsIDB4NjYsIDB4YWQsIDB4YjYsIDB4YzQsIDB4NDksIDB4YjcsIDB4ZGUsIDB4MjUsCisgIDB4YzUsIDB4NTMsIDB4ZWEsIDB4ZWQsIDB4MTEsIDB4Y2EsIDB4ZWMsIDB4MDcsIDB4OTksIDB4ZGIsIDB4OTEsIDB4MjQsCisgIDB4MzgsIDB4MDEsIDB4ZjMsIDB4MTYsIDB4MWMsIDB4ZjMsIDB4NDAsIDB4ZWYsIDB4NTIsIDB4MWQsIDB4NWYsIDB4NzgsCisgIDB4MWQsIDB4MGYsIDB4N2QsIDB4YzIsIDB4YzcsIDB4MDUsIDB4Y2MsIDB4OTMsIDB4YjEsIDB4YmEsIDB4Y2QsIDB4MjMsCisgIDB4ZjAsIDB4NTcsIDB4MzQsIDB4NzMsIDB4MzYsIDB4YzEsIDB4NjMsIDB4Y2YsIDB4OWUsIDB4Y2YsIDB4OTIsIDB4ZGUsCisgIDB4YTEsIDB4MmQsIDB4NTAsIDB4MmYsIDB4MzEsIDB4MDgsIDB4ZDIsIDB4OTgsIDB4OWEsIDB4ZDEsIDB4ZTUsIDB4NzEsCisgIDB4MjQsIDB4NzgsIDB4MDIsIDB4N2MsIDB4ZTEsIDB4ZWEsIDB4NTAsIDB4ZjQsIDB4NTMsIDB4YzAsIDB4YTgsIDB4MjQsCisgIDB4NDQsIDB4ZTMsIDB4MmYsIDB4YzQsIDB4YjEsIDB4N2YsIDB4ZGEsIDB4YWIsIDB4NjcsIDB4ZGYsIDB4OGEsIDB4N2IsCisgIDB4YTQsIDB4NGUsIDB4MzIsIDB4ZmMsIDB4NGIsIDB4MTcsIDB4ZmQsIDB4YWEsIDB4YjYsIDB4N2QsIDB4ZjgsIDB4YTcsCisgIDB4YmEsIDB4MDAsIDB4YTIsIDB4OGEsIDB4MjgsIDB4MDIsIDB4OTMsIDB4MzgsIDB4ZTMsIDB4ZjIsIDB4M2QsIDB4OTcsCisgIDB4N2QsIDB4MTEsIDB4MjMsIDB4ZjgsIDB4MGQsIDB4MzksIDB4ZDIsIDB4NjcsIDB4MWMsIDB4N2UsIDB4NDcsIDB4YjIsCisgIDB4ZWYsIDB4YTIsIDB4MjQsIDB4N2YsIDB4MDEsIDB4YTAsIDB4MWIsIDB4ZTMsIDB4N2MsIDB4NWQsIDB4YmYsIDB4OTgsCisgIDB4M2UsIDB4Y2EsIDB4ZDksIDB4NWEsIDB4ZTMsIDB4N2MsIDB4NWQsIDB4YmYsIDB4OTgsIDB4M2UsIDB4Y2EsIDB4ZDksCisgIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTYsIDB4YjksIDB4MGQsIDB4YjQsIDB4ZmIsIDB4NGUsIDB4MzIsCisgIDB4ZjMsIDB4NjgsIDB4NzUsIDB4YjcsIDB4MTIsIDB4NTIsIDB4YjQsIDB4MjgsIDB4NmMsIDB4MjgsIDB4MTEsIDB4ZDQsCisgIDB4MTEsIDB4ZTgsIDB4MjIsIDB4YjYsIDB4NTAsIDB4NDYsIDB4ZTgsIDB4MGYsIDB4OGQsIDB4ZTUsIDB4NDMsIDB4OTMsCisgIDB4YzIsIDB4NmUsIDB4MjEsIDB4Y2IsIDB4YjQsIDB4MjcsIDB4YjcsIDB4ZWMsIDB4ZjEsIDB4YzQsIDB4YWUsIDB4NzUsCisgIDB4YjEsIDB4NWQsIDB4NDksIDB4OTksIDB4OGYsIDB4YmUsIDB4ZWYsIDB4MzMsIDB4ZWMsIDB4OGUsIDB4ZWQsIDB4YWUsCisgIDB4MmIsIDB4YTcsIDB4YjYsIDB4MWYsIDB4YWEsIDB4MWQsIDB4ZjAsIDB4ZDUsIDB4N2QsIDB4MjksIDB4MjIsIDB4ZjQsCisgIDB4ZWQsIDB4ZDgsIDB4NWEsIDB4NjIsIDB4YzQsIDB4YmIsIDB4YTIsIDB4ZGYsIDB4MWUsIDB4NjMsIDB4MmIsIDB4NzEsCisgIDB4ZjksIDB4NmQsIDB4ZjIsIDB4YTksIDB4NmEsIDB4ZDEsIDB4NmQsIDB4MjksIDB4NDMsIDB4NjUsIDB4NWIsIDB4MDAsCisgIDB4YWIsIDB4YjQsIDB4MDcsIDB4OTgsIDB4ODIsIDB4NzUsIDB4YWQsIDB4NzUsIDB4M2IsIDB4MGIsIDB4NWYsIDB4ODQsCisgIDB4YzYsIDB4MjksIDB4MmUsIDB4ZWQsIDB4ODksIDB4YzcsIDB4Y2IsIDB4MmMsIDB4MzEsIDB4OWIsIDB4N2IsIDB4MjMsCisgIDB4YzUsIDB4NWMsIDB4NTUsIDB4YzIsIDB4MjMsIDB4NmIsIDB4NDAsIDB4NTAsIDB4OTQsIDB4YzcsIDB4MmUsIDB4YTQsCisgIDB4NDYsIDB4NTAsIDB4ZjEsIDB4NDMsIDB4OGQsIDB4ZjMsIDB4MDIsIDB4OWYsIDB4MWQsIDB4NmIsIDB4YzYsIDB4YWIsCisgIDB4YmUsIDB4MGYsIDB4M2YsIDB4NjUsIDB4YzgsIDB4YWMsIDB4YWIsIDB4YzEsIDB4OWUsIDB4OTAsIDB4ZTIsIDB4ZWQsCisgIDB4NmEsIDB4OGUsIDB4ZGQsIDB4YzcsIDB4MWUsIDB4OTIsIDB4YjUsIDB4ZWQsIDB4YzEsIDB4MDEsIDB4ZDUsIDB4MWUsCisgIDB4Y2QsIDB4MjUsIDB4NDMsIDB4NDcsIDB4OTksIDB4ODcsIDB4MDIsIDB4OTgsIDB4NWUsIDB4ODgsIDB4MjAsIDB4YTEsCisgIDB4MjcsIDB4N2QsIDB4YzYsIDB4YjUsIDB4ODcsIDB4N2EsIDB4M2EsIDB4NGMsIDB4YTcsIDB4ZGQsIDB4OTYsIDB4YWYsCisgIDB4Y2MsIDB4YjUsIDB4ZjMsIDB4MDgsIDB4YTcsIDB4MGIsIDB4NzYsIDB4MjYsIDB4NTksIDB4MWQsIDB4MzcsIDB4MGIsCisgIDB4YWMsIDB4NzgsIDB4YWQsIDB4YWQsIDB4ODcsIDB4ZTMsIDB4NDgsIDB4OTYsIDB4YjcsIDB4OGEsIDB4MTQsIDB4ZTEsCisgIDB4NDgsIDB4NGIsIDB4YzgsIDB4MmUsIDB4MTIsIDB4NDIsIDB4YjYsIDB4MDIsIDB4MDgsIDB4MDQsIDB4MGQsIDB4MmYsCisgIDB4N2EsIDB4MWEsIDB4M2IsIDB4ZjUsIDB4OTMsIDB4ZGQsIDB4NmQsIDB4MTksIDB4NDQsIDB4NjgsIDB4MTEsIDB4ZWMsCisgIDB4YWEsIDB4NzEsIDB4ZmIsIDB4YTAsIDB4NzksIDB4YjUsIDB4MzIsIDB4MWEsIDB4MGEsIDB4NGEsIDB4OTgsIDB4NjksCisgIDB4N2EsIDB4NGIsIDB4YTUsIDB4YzIsIDB4OWUsIDB4YWQsIDB4YTAsIDB4YjQsIDB4YTUsIDB4OGUsIDB4YmEsIDB4MjQsCisgIDB4ODEsIDB4YWQsIDB4OTAsIDB4MzUsIDB4YzksIDB4MGEsIDB4YzksIDB4NzIsIDB4NmEsIDB4NWEsIDB4MmMsIDB4YWQsCisgIDB4Y2EsIDB4N2EsIDB4ZmMsIDB4NmQsIDB4YTUsIDB4MGIsIDB4NTksIDB4OTQsIDB4ZTIsIDB4OWEsIDB4OGEsIDB4ZDMsCisgIDB4OWEsIDB4ZTYsIDB4NDEsIDB4NzQsIDB4YTgsIDB4YWQsIDB4YzcsIDB4ZGMsIDB4ZDYsIDB4OTQsIDB4MTMsIDB4YmUsCisgIDB4NTEsIDB4YjAsIDB4NGUsIDB4OGUsIDB4YjUsIDB4ZWUsIDB4MGEsIDB4MmQsIDB4ZTYsIDB4ZjUsIDB4MjIsIDB4ZDMsCisgIDB4OTYsIDB4MDgsIDB4NzYsIDB4Y2UsIDB4NDksIDB4MGQsIDB4MzEsIDB4MGEsIDB4ZDksIDB4MTEsIDB4YzIsIDB4ZDQsCisgIDB4NTksIDB4NWMsIDB4ZTgsIDB4MmEsIDB4MGUsIDB4ZTgsIDB4MDQsIDB4OTUsIDB4OTUsIDB4MTQsIDB4MzgsIDB4OWUsCisgIDB4NTMsIDB4YjAsIDB4OWUsIDB4Y2MsIDB4OGUsIDB4YmIsIDB4ZDksIDB4Y2YsIDB4MmIsIDB4ODQsIDB4NjksIDB4YmYsCisgIDB4MmMsIDB4ZTcsIDB4NzIsIDB4ZGYsIDB4NzcsIDB4NjUsIDB4MTEsIDB4YjEsIDB4ZGIsIDB4YzIsIDB4OWMsIDB4YmEsCisgIDB4M2UsIDB4NWIsIDB4NDIsIDB4OWYsIDB4NjIsIDB4MjIsIDB4YmIsIDB4NjcsIDB4ZTUsIDB4MzQsIDB4OTUsIDB4MTIsCisgIDB4OTAsIDB4ZWIsIDB4YWIsIDB4NGIsIDB4NmQsIDB4YjIsIDB4ZDksIDB4MjksIDB4MDAsIDB4ZTgsIDB4NmQsIDB4NWEsCisgIDB4M2EsIDB4M2QsIDB4ZjUsIDB4ZDEsIDB4NmYsIDB4NjYsIDB4MTIsIDB4ZjIsIDB4MDksIDB4NzYsIDB4ZjUsIDB4NWIsCisgIDB4OTMsIDB4ODgsIDB4ODgsIDB4ZWMsIDB4YjYsIDB4YjksIDB4MDksIDB4OGQsIDB4ZDksIDB4ODcsIDB4ZTUsIDB4MTcsCisgIDB4NTYsIDB4YWUsIDB4NTAsIDB4ZGIsIDB4YTksIDB4ZWEsIDB4MWEsIDB4ZjMsIDB4MzQsIDB4NzksIDB4NzksIDB4NGYsCisgIDB4MzEsIDB4ZDYsIDB4YzYsIDB4YmEsIDB4ZTksIDB4YmYsIDB4MmQsIDB4NzgsIDB4NTQsIDB4ZTksIDB4MGUsIDB4NjMsCisgIDB4MjIsIDB4MGEsIDB4MTgsIDB4YmEsIDB4MjEsIDB4MTIsIDB4NWEsIDB4NDMsIDB4YzUsIDB4N2QsIDB4OTIsIDB4MGIsCisgIDB4MmIsIDB4NDIsIDB4NWQsIDB4NjgsIDB4MjksIDB4MjksIDB4NTcsIDB4NjYsIDB4ODUsIDB4MjUsIDB4Y2QsIDB4YTUsCisgIDB4NWEsIDB4MjksIDB4NDIsIDB4ODEsIDB4ZDgsIDB4MDAsIDB4ZjQsIDB4MzIsIDB4MjYsIDB4MWEsIDB4Y2UsIDB4MTMsCisgIDB4MDEsIDB4ZTksIDB4MmQsIDB4YjUsIDB4MDIsIDB4MjMsIDB4MWMsIDB4ZTEsIDB4ZGIsIDB4ODMsIDB4ZTksIDB4NTMsCisgIDB4NGQsIDB4YWQsIDB4NGEsIDB4ZTUsIDB4MjgsIDB4NmQsIDB4YWQsIDB4YTksIDB4MGEsIDB4NTksIDB4MGIsIDB4NGEsCisgIDB4NTUsIDB4Y2UsIDB4OTIsIDB4OTEsIDB4ZTYsIDB4OGUsIDB4NTIsIDB4NzcsIDB4NTMsIDB4Y2YsIDB4MjEsIDB4N2EsCisgIDB4MWIsIDB4NzIsIDB4MzYsIDB4NjQsIDB4ZTEsIDB4NzMsIDB4ZGQsIDB4YmEsIDB4NTksIDB4NDgsIDB4OTYsIDB4OTksCisgIDB4OTAsIDB4Y2MsIDB4NzgsIDB4ODgsIDB4OWYsIDB4MzUsIDB4NGEsIDB4NGMsIDB4NzcsIDB4OWIsIDB4MjUsIDB4ZDUsCisgIDB4MzYsIDB4OTcsIDB4MWMsIDB4M2QsIDB4MDMsIDB4ODgsIDB4MGIsIDB4ZDYsIDB4Y2UsIDB4ODIsIDB4ZDAsIDB4OTEsCisgIDB4ZDAsIDB4MWUsIDB4OWEsIDB4NzIsIDB4NjcsIDB4ZDksIDB4Y2YsIDB4MWEsIDB4ODMsIDB4MTIsIDB4MDQsIDB4MWUsCisgIDB4NjksIDB4NmIsIDB4NDksIDB4NGMsIDB4YTEsIDB4ZGIsIDB4MTAsIDB4MTgsIDB4OGUsIDB4YjQsIDB4MTIsIDB4YTQsCisgIDB4M2MsIDB4YjQsIDB4NmMsIDB4MjEsIDB4NWMsIDB4ZTksIDB4NmQsIDB4NDksIDB4NDgsIDB4MjUsIDB4NDEsIDB4NDgsCisgIDB4MGEsIDB4ZDYsIDB4ODcsIDB4NWUsIDB4ZWIsIDB4NWMsIDB4MmIsIDB4OGMsIDB4OWIsIDB4ODIsIDB4OWUsIDB4ODcsCisgIDB4MWQsIDB4YWIsIDB4YzEsIDB4ODIsIDB4YTcsIDB4MTgsIDB4NDQsIDB4ODksIDB4NGEsIDB4ZjIsIDB4NTgsIDB4MmQsCisgIDB4MmYsIDB4NWMsIDB4YWUsIDB4MDYsIDB4OWEsIDB4NDgsIDB4NTIsIDB4OWMsIDB4NTcsIDB4NTIsIDB4OTIsIDB4YjUsCisgIDB4NmYsIDB4ZjMsIDB4ODIsIDB4NGYsIDB4NzgsIDB4YWQsIDB4NTYsIDB4ODUsIDB4ZGEsIDB4MmUsIDB4NGIsIDB4MmMsCisgIDB4ZTQsIDB4ZWEsIDB4NGMsIDB4MTcsIDB4NTUsIDB4MzEsIDB4ZjgsIDB4OTEsIDB4ZWMsIDB4YTgsIDB4N2YsIDB4YjMsCisgIDB4OGUsIDB4YzEsIDB4NmIsIDB4NDQsIDB4ZWMsIDB4MjMsIDB4NDEsIDB4YzIsIDB4NTIsIDB4NTIsIDB4YmUsIDB4NjUsCisgIDB4N2UsIDB4NmEsIDB4YzYsIDB4ODAsIDB4YTgsIDB4ZjQsIDB4NDMsIDB4MTgsIDB4ZGQsIDB4OWUsIDB4MTEsIDB4MWUsCisgIDB4NDMsIDB4OTIsIDB4MjMsIDB4NTksIDB4MjcsIDB4MzQsIDB4ZTUsIDB4ZTAsIDB4NWIsIDB4NTYsIDB4OTcsIDB4MTUsCisgIDB4MDIsIDB4MTcsIDB4YmUsIDB4NmQsIDB4YzAsIDB4OWYsIDB4MzUsIDB4NzIsIDB4YTQsIDB4M2EsIDB4MTAsIDB4OTIsCisgIDB4YWQsIDB4MWUsIDB4NjAsIDB4ODAsIDB4MTIsIDB4NDksIDB4ZDEsIDB4ZWEsIDB4M2EsIDB4NTcsIDB4NDUsIDB4ODUsCisgIDB4MTYsIDB4ZmIsIDB4ODMsIDB4YWYsIDB4YjYsIDB4ZTEsIDB4NTYsIDB4MzUsIDB4MDgsIDB4NGYsIDB4MzAsIDB4ZGEsCisgIDB4YjUsIDB4NDUsIDB4ZTQsIDB4ODgsIDB4ZTMsIDB4YWYsIDB4MjEsIDB4MWMsIDB4Y2EsIDB4ZWQsIDB4MTYsIDB4ZDksCisgIDB4ZDksIDB4MjQsIDB4MTIsIDB4NTIsIDB4MTAsIDB4YTAsIDB4MzksIDB4MDAsIDB4M2UsIDB4NzYsIDB4ZmEsIDB4NDYsCisgIDB4NDgsIDB4YmIsIDB4Y2IsIDB4YzIsIDB4MmUsIDB4MDksIDB4YjUsIDB4ZGIsIDB4NWMsIDB4ODEsIDB4MjIsIDB4MDIsCisgIDB4ZTUsIDB4MTksIDB4YzksIDB4MTIsIDB4YTUsIDB4NzYsIDB4NmIsIDB4N2EsIDB4M2IsIDB4ZGMsIDB4YzEsIDB4NDksCisgIDB4ZWQsIDB4NTcsIDB4YjEsIDB4Y2UsIDB4ZGEsIDB4ZDMsIDB4ZDAsIDB4MjgsIDB4ZjksIDB4ZTgsIDB4MjAsIDB4MDMsCisgIDB4YjQsIDB4OWEsIDB4ZDMsIDB4OTIsIDB4YTYsIDB4ZGQsIDB4N2UsIDB4OWEsIDB4ZjUsIDB4YzYsIDB4ZTgsIDB4MjAsCisgIDB4NDMsIDB4YjcsIDB4NGEsIDB4NjksIDB4YTQsIDB4YTUsIDB4YjksIDB4YjAsIDB4OWMsIDB4NzEsIDB4NzMsIDB4OWUsCisgIDB4NmQsIDB4NGIsIDB4ZTUsIDB4NzUsIDB4OTYsIDB4OTIsIDB4YTQsIDB4YmQsIDB4YjQsIDB4YTUsIDB4NWEsIDB4MGIsCisgIDB4MWEsIDB4MmEsIDB4ZGUsIDB4ODAsIDB4MjksIDB4ZDEsIDB4YTksIDB4ZjUsIDB4NjEsIDB4M2UsIDB4ODgsIDB4OTAsCisgIDB4N2UsIDB4NjUsIDB4YzMsIDB4MGQsIDB4YmIsIDB4ZGMsIDB4NTksIDB4ODYsIDB4Y2EsIDB4MmYsIDB4MGUsIDB4Y2EsCisgIDB4NzEsIDB4YjksIDB4NmQsIDB4MmEsIDB4NTQsIDB4YjAsIDB4OTcsIDB4ZGUsIDB4OGEsIDB4OTAsIDB4MWIsIDB4NTMsCisgIDB4MDgsIDB4NWEsIDB4ZjQsIDB4MTQsIDB4ZTMsIDB4NmEsIDB4MDEsIDB4NDAsIDB4MjgsIDB4ZjksIDB4YzksIDB4NWYsCisgIDB4NTMsIDB4YmUsIDB4ZmUsIDB4NmIsIDB4ZWMsIDB4MzcsIDB4MzMsIDB4NWIsIDB4ZGEsIDB4MjQsIDB4NTgsIDB4NWIsCisgIDB4N2UsIDB4MzIsIDB4ZDIsIDB4Y2EsIDB4NTcsIDB4MmUsIDB4NDMsIDB4NzIsIDB4NDMsIDB4NjksIDB4NmQsIDB4ZjYsCisgIDB4ZDYsIDB4OTIsIDB4YzgsIDB4MGUsIDB4YTUsIDB4MmIsIDB4NDcsIDB4NmMsIDB4MDIsIDB4OWQsIDB4NDksIDB4ZDAsCisgIDB4NTgsIDB4MDEsIDB4NWEsIDB4M2YsIDB4OWIsIDB4YWUsIDB4ZWIsIDB4NjUsIDB4YjYsIDB4ZWMsIDB4NTEsIDB4MjIsCisgIDB4NmYsIDB4ZjIsIDB4NjksIDB4MzcsIDB4MmUsIDB4NjYsIDB4MTIsIDB4ODIsIDB4NmUsIDB4Y2UsIDB4YTEsIDB4ODIsCisgIDB4ZTMsIDB4NjAsIDB4ZjMsIDB4NzYsIDB4NGMsIDB4YjAsIDB4OTQsIDB4YTgsIDB4MzYsIDB4MzYsIDB4MDEsIDB4ZjMsCisgIDB4YzgsIDB4MjQsIDB4ZWIsIDB4OTgsIDB4OWQsIDB4NzQsIDB4ZjMsIDB4NjEsIDB4NTYsIDB4MzUsIDB4NzcsIDB4NjYsCisgIDB4ZGMsIDB4OWIsIDB4ZjQsIDB4ZTUsIDB4YmQsIDB4NzEsIDB4OWIsIDB4MGQsIDB4NTIsIDB4ZDksIDB4ODgsIDB4MWQsCisgIDB4NWIsIDB4NGMsIDB4YzQsIDB4NmMsIDB4MWUsIDB4NTUsIDB4MjEsIDB4YjQsIDB4MjAsIDB4ODQsIDB4YTQsIDB4YjYsCisgIDB4NGYsIDB4MjksIDB4M2QsIDB4NTUsIDB4YjQsIDB4ZjcsIDB4ZDEsIDB4NzksIDB4MjQsIDB4MWUsIDB4ZGIsIDB4YjMsCisgIDB4YzMsIDB4NzEsIDB4ZGQsIDB4YjksIDB4Y2QsIDB4ZDQsIDB4ZmIsIDB4NWIsIDB4OTksIDB4MmYsIDB4OTAsIDB4YTUsCisgIDB4NmMsIDB4MjUsIDB4ODYsIDB4MDIsIDB4NTMsIDB4MTUsIDB4ODUsIDB4MTMsIDB4YTcsIDB4MDksIDB4NzUsIDB4ZDIsCisgIDB4MGIsIDB4Y2UsIDB4ZjQsIDB4ZDcsIDB4OWEsIDB4MDAsIDB4NGYsIDB4NTEsIDB4YTQsIDB4OWEsIDB4ZGYsIDB4ODksCisgIDB4MzcsIDB4NmYsIDB4YmIsIDB4YzcsIDB4NDIsIDB4M2MsIDB4YjEsIDB4ZmIsIDB4MmIsIDB4NGYsIDB4MTcsIDB4OWMsCisgIDB4NjIsIDB4Y2YsIDB4MGIsIDB4ZjksIDB4YTIsIDB4ZGEsIDB4NGEsIDB4MTYsIDB4NWIsIDB4MmEsIDB4NzgsIDB4YTcsCisgIDB4Y2YsIDB4NTMsIDB4OWIsIDB4MWUsIDB4NzcsIDB4NTAsIDB4OTAsIDB4N2EsIDB4MTAsIDB4N2IsIDB4Y2MsIDB4NmQsCisgIDB4YmYsIDB4MmMsIDB4OTUsIDB4ODgsIDB4Y2YsIDB4NjcsIDB4MTksIDB4N2EsIDB4MzMsIDB4NTIsIDB4NjAsIDB4YzIsCisgIDB4MGIsIDB4NjAsIDB4Y2IsIDB4MGIsIDB4ZjMsIDB4YzksIDB4M2MsIDB4YWUsIDB4MzQsIDB4ZTIsIDB4ODEsIDB4ZWEsCisgIDB4YmQsIDB4YTEsIDB4N2EsIDB4NTAsIDB4NDcsIDB4MzIsIDB4ZjksIDB4ODIsIDB4OGYsIDB4MmUsIDB4ODgsIDB4YWUsCisgIDB4OTQsIDB4NjEsIDB4ZjIsIDB4YjIsIDB4MGIsIDB4ZjMsIDB4ZDksIDB4MmEsIDB4YTEsIDB4YjEsIDB4NmMsIDB4MjUsCisgIDB4ZDQsIDB4YjksIDB4MTksIDB4MzIsIDB4NTksIDB4NzQsIDB4MzksIDB4YmUsIDB4NDQsIDB4ODcsIDB4MWMsIDB4MjgsCisgIDB4NmQsIDB4ZDQsIDB4NjgsIDB4MjgsIDB4YTEsIDB4M2UsIDB4ZjYsIDB4ZTcsIDB4MzYsIDB4ZjksIDB4NDEsIDB4MjAsCisgIDB4MTIsIDB4NDUsIDB4MzEsIDB4ZDUsIDB4OGMsIDB4ZjQsIDB4NDIsIDB4NTQsIDB4NTksIDB4YjIsIDB4NzgsIDB4NmIsCisgIDB4YzcsIDB4NzQsIDB4Y2MsIDB4OWEsIDB4ZTksIDB4NWQsIDB4OWIsIDB4MjcsIDB4NzEsIDB4OWIsIDB4NmQsIDB4ZDUsCisgIDB4ZmUsIDB4ODEsIDB4MDIsIDB4NjEsIDB4NDksIDB4ZjIsIDB4MzksIDB4NjcsIDB4YjgsIDB4MDIsIDB4ZWEsIDB4MTIsCisgIDB4YTYsIDB4OTYsIDB4NzUsIDB4ZDUsIDB4NmQsIDB4OTUsIDB4NzgsIDB4ODEsIDB4NWYsIDB4NDIsIDB4MjcsIDB4YWEsCisgIDB4NzcsIDB4NTUsIDB4ZjYsIDB4NGQsIDB4ODIsIDB4ZGEsIDB4NzIsIDB4MGIsIDB4MTUsIDB4ZGYsIDB4MTEsIDB4YjksCisgIDB4YmEsIDB4ZWMsIDB4ZDcsIDB4MmYsIDB4MTEsIDB4YjksIDB4ZTUsIDB4Y2UsIDB4NzAsIDB4OGUsIDB4ZDUsIDB4YjcsCisgIDB4MTEsIDB4YWUsIDB4YzksIDB4NjgsIDB4NGEsIDB4NDAsIDB4MDgsIDB4MDgsIDB4NTcsIDB4NTQsIDB4ODEsIDB4YWQsCisgIDB4N2EsIDB4Y2UsIDB4YzksIDB4Y2YsIDB4MDAsIDB4YjIsIDB4NGIsIDB4YWUsIDB4NDMsIDB4YzMsIDB4ZTQsIDB4MzUsCisgIDB4OTAsIDB4NjgsIDB4ZGYsIDB4NmMsIDB4YjIsIDB4ZGYsIDB4YjMsIDB4ZGQsIDB4MTcsIDB4YmQsIDB4ODcsIDB4MjQsCisgIDB4NDcsIDB4NTcsIDB4MjEsIDB4NWUsIDB4ZmYsIDB4MDAsIDB4NTgsIDB4NzIsIDB4YTgsIDB4ZmEsIDB4YzksIDB4YTgsCisgIDB4NjksIDB4YTAsIDB4OWEsIDB4NjYsIDB4ZWUsIDB4MzIsIDB4ZmMsIDB4NGIsIDB4MTcsIDB4ZmQsIDB4YWEsIDB4YjYsCisgIDB4N2QsIDB4ZjgsIDB4YTcsIDB4YmEsIDB4NDQsIDB4ZTMsIDB4MjcsIDB4YzQsIDB4NzEsIDB4N2YsIDB4ZGEsIDB4YWIsCisgIDB4NjcsIDB4ZGYsIDB4OGEsIDB4N2IsIDB4YTgsIDB4MjQsIDB4MjgsIDB4YWMsIDB4NmYsIDB4NDcsIDB4YTksIDB4MTQsCisgIDB4NTAsIDB4MTksIDB4YTQsIDB4Y2UsIDB4MzgsIDB4ZmMsIDB4OGYsIDB4NjUsIDB4ZGYsIDB4NDQsIDB4NDgsIDB4ZmUsCisgIDB4MDMsIDB4NGUsIDB4NzQsIDB4OTksIDB4YzcsIDB4MWYsIDB4OTEsIDB4ZWMsIDB4YmIsIDB4ZTgsIDB4ODksIDB4MWYsCisgIDB4YzAsIDB4NjgsIDB4MDYsIDB4ZjgsIDB4ZGYsIDB4MTcsIDB4NmYsIDB4ZTYsIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTYsCisgIDB4YjgsIDB4ZGYsIDB4MTcsIDB4NmYsIDB4ZTYsIDB4MGYsIDB4YjIsIDB4YjYsIDB4NTAsIDB4MDUsIDB4MTQsIDB4NTEsCisgIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDEsIDB4ZTUsIDB4NDAsIDB4NmYsIDB4NjQsIDB4NmYsIDB4ZDEsIDB4NWYsCisgIDB4MjIsIDB4NjYsIDB4NTYsIDB4MjksIDB4OWMsIDB4MzcsIDB4ZTIsIDB4NWMsIDB4YmIsIDB4NTUsIDB4YTksIDB4ODIsCisgIDB4NWIsIDB4OGMsIDB4YjcsIDB4ZjIsIDB4NGMsIDB4NWQsIDB4YTEsIDB4ZDAsIDB4NDgsIDB4OGMsIDB4YTEsIDB4ZmUsCisgIDB4OTMsIDB4YjYsIDB4YTcsIDB4ZmUsIDB4MTEsIDB4ZGIsIDB4MjAsIDB4NzgsIDB4MTQsIDB4MGUsIDB4ZjIsIDB4YWEsCisgIDB4ZmEsIDB4ZjcsIDB4NWQsIDB4NzcsIDB4NTUsIDB4YTcsIDB4ZTEsIDB4MTEsIDB4ODgsIDB4NGYsIDB4YzksIDB4YjAsCisgIDB4NzQsIDB4ZGMsIDB4NzEsIDB4ZWYsIDB4MzMsIDB4MjgsIDB4YzcsIDB4YTQsIDB4MjYsIDB4ZWIsIDB4NjUsIDB4NzQsCisgIDB4MGQsIDB4YWIsIDB4YjYsIDB4NmYsIDB4YWEsIDB4OWIsIDB4ZjUsIDB4ODUsIDB4YTQsIDB4MTQsIDB4ZWIsIDB4YjgsCisgIDB4OWQsIDB4NmUsIDB4YTUsIDB4M2MsIDB4M2MsIDB4YTIsIDB4MWEsIDB4Y2EsIDB4YzMsIDB4MzksIDB4NTgsIDB4YmMsCisgIDB4NWMsIDB4NmUsIDB4YjYsIDB4MDYsIDB4YjIsIDB4MWMsIDB4NGUsIDB4NjMsIDB4ZWYsIDB4YTIsIDB4NzcsIDB4OTMsCisgIDB4Y2IsIDB4MGUsIDB4MzQsIDB4YzcsIDB4NmMsIDB4OTUsIDB4NzIsIDB4YTQsIDB4NzUsIDB4NWEsIDB4MDEsIDB4ZTYsCisgIDB4MjgsIDB4NzEsIDB4YmQsIDB4MjQsIDB4OTQsIDB4ZWQsIDB4NDksIDB4NTIsIDB4NDcsIDB4NGUsIDB4ZmEsIDB4ZDMsCisgIDB4OTYsIDB4NDcsIDB4YjcsIDB4NjQsIDB4MTMsIDB4ZTMsIDB4OWMsIDB4YWUsIDB4ZTIsIDB4ZGQsIDB4OTksIDB4YjgsCisgIDB4Y2MsIDB4YTgsIDB4MzAsIDB4ZGIsIDB4YWEsIDB4NmYsIDB4Y2EsIDB4OWMsIDB4MjUsIDB4NmQsIDB4YWMsIDB4MzgsCisgIDB4ZTIsIDB4MTMsIDB4Y2MsIDB4MWEsIDB4NmQsIDB4MWQsIDB4OTgsIDB4ZDEsIDB4ZGUsIDB4ZjYsIDB4NDksIDB4MjUsCisgIDB4M2QsIDB4YzUsIDB4MDMsIDB4ZjAsIDB4NzgsIDB4Y2MsIDB4YTAsIDB4YzcsIDB4YjgsIDB4YjcsIDB4MTIsIDB4MjIsCisgIDB4MTUsIDB4MTIsIDB4Y2QsIDB4N2EsIDB4NGIsIDB4OTcsIDB4MmIsIDB4NDMsIDB4MjQsIDB4NzksIDB4YjEsIDB4Y2UsCisgIDB4ZmYsIDB4MDAsIDB4OWUsIDB4YzIsIDB4ZjUsIDB4MTYsIDB4NWUsIDB4MjUsIDB4NDksIDB4NGYsIDB4ZTgsIDB4MmQsCisgIDB4MjYsIDB4YWQsIDB4N2MsIDB4NjYsIDB4ZmQsIDB4NmEsIDB4YjIsIDB4M2IsIDB4MDIsIDB4YzMsIDB4MzYsIDB4ZGQsCisgIDB4MjYsIDB4M2MsIDB4YzksIDB4Y2QsIDB4NmQsIDB4ZDksIDB4NGIsIDB4NjgsIDB4YWMsIDB4NGIsIDB4OTQsIDB4MTQsCisgIDB4YTAsIDB4ZTIsIDB4NTQsIDB4YjEsIDB4ZjAsIDB4OTYsIDB4NDgsIDB4ZTYsIDB4ZDEsIDB4ZWYsIDB4NGEsIDB4ODYsCisgIDB4YmEsIDB4NzcsIDB4NmIsIDB4MzUsIDB4OWMsIDB4MzgsIDB4ZjUsIDB4MzIsIDB4ODMsIDB4NGIsIDB4MmEsIDB4NWQsCisgIDB4MGYsIDB4NzgsIDB4Y2MsIDB4NWIsIDB4YmMsIDB4ODAsIDB4NmYsIDB4OTYsIDB4NjQsIDB4NDQsIDB4NTgsIDB4N2QsCisgIDB4YWUsIDB4NTYsIDB4MjcsIDB4NWQsIDB4NTQsIDB4YTcsIDB4MWUsIDB4OTIsIDB4ZDcsIDB4N2EsIDB4NDIsIDB4MTAsCisgIDB4ZGYsIDB4MmEsIDB4MTgsIDB4NjksIDB4NDcsIDB4NDQsIDB4NzIsIDB4ZWYsIDB4N2QsIDB4MDksIDB4NGUsIDB4YzUsCisgIDB4NzMsIDB4ZTMsIDB4MzIsIDB4YjEsIDB4YjksIDB4OGUsIDB4YzYsIDB4NTYsIDB4NGQsIDB4ZTQsIDB4ZjIsIDB4MzIsCisgIDB4MTksIDB4YTIsIDB4NDAsIDB4NzUsIDB4YjksIDB4YTksIDB4MGIsIDB4MGMsIDB4YTksIDB4YTUsIDB4MDAsIDB4ZWIsCisgIDB4MGQsIDB4ODUsIDB4MGQsIDB4MjQsIDB4MjQsIDB4MjksIDB4M2QsIDB4YzMsIDB4NmEsIDB4MWEsIDB4NTEsIDB4ZGUsCisgIDB4ZjcsIDB4NTEsIDB4OTYsIDB4ZDUsIDB4NWUsIDB4ZTMsIDB4ZGUsIDB4NTUsIDB4ZmMsIDB4OWEsIDB4N2UsIDB4NzQsCisgIDB4Y2IsIDB4MDQsIDB4MjcsIDB4OWQsIDB4OGIsIDB4MWQsIDB4MmQsIDB4MjEsIDB4YTUsIDB4MzIsIDB4YTYsIDB4YjksCisgIDB4NDIsIDB4ZjQsIDB4ODcsIDB4MTYsIDB4ZTIsIDB4NzksIDB4M2IsIDB4MzUsIDB4YTksIDB4NDgsIDB4ZTcsIDB4ZDIsCisgIDB4ZDIsIDB4NTIsIDB4OTAsIDB4MDYsIDB4OTQsIDB4OWUsIDB4YmEsIDB4ZTcsIDB4MmIsIDB4MWQsIDB4OTQsIDB4ZDQsCisgIDB4YWIsIDB4Y2QsIDB4ZjYsIDB4NmIsIDB4ZDIsIDB4YTYsIDB4MmUsIDB4NjgsIDB4N2QsIDB4ODQsIDB4NWIsIDB4M2IsCisgIDB4NDMsIDB4MTksIDB4MmYsIDB4MDQsIDB4MjUsIDB4YjYsIDB4OWEsIDB4NDMsIDB4ZmMsIDB4YmMsIDB4ODUsIDB4ZDIsCisgIDB4MTIsIDB4OTEsIDB4Y2UsIDB4MGEsIDB4NGUsIDB4Y2UsIDB4ODYsIDB4ODcsIDB4NGEsIDB4YzksIDB4NjMsIDB4OTMsCisgIDB4NWQsIDB4ZmEsIDB4MWIsIDB4OTksIDB4OTksIDB4NzksIDB4YzcsIDB4ZWUsIDB4YzYsIDB4Y2YsIDB4OGMsIDB4MjksCisgIDB4MzIsIDB4NmQsIDB4OTYsIDB4ZDcsIDB4YzgsIDB4ZjIsIDB4NjEsIDB4MTUsIDB4ZDcsIDB4OTAsIDB4NTgsIDB4N2MsCisgIDB4MDcsIDB4MTIsIDB4OWUsIDB4NjYsIDB4YzIsIDB4OGEsIDB4NWQsIDB4NDEsIDB4ZTYsIDB4ZDcsIDB4MzAsIDB4ZTUsCisgIDB4NTIsIDB4MTQsIDB4MDEsIDB4MjAsIDB4ZjUsIDB4MzksIDB4YmQsIDB4YzYsIDB4NmEsIDB4ZWIsIDB4NzUsIDB4OTEsCisgIDB4MjYsIDB4ZTYsIDB4ODYsIDB4ZDgsIDB4OWEsIDB4ZTksIDB4OGUsIDB4YTYsIDB4MmQsIDB4NmQsIDB4YzIsIDB4NmEsCisgIDB4NzQsIDB4ODIsIDB4YTYsIDB4ODIsIDB4ZjksIDB4NWUsIDB4NzEsIDB4MDcsIDB4NjEsIDB4YTUsIDB4ZjksIDB4ZTMsCisgIDB4NGEsIDB4ZTYsIDB4MDAsIDB4MDQsIDB4ZjUsIDB4MjcsIDB4YzIsIDB4NTUsIDB4ZmIsIDB4MDYsIDB4NGYsIDB4MWIsCisgIDB4MTcsIDB4OTYsIDB4Y2QsIDB4OWEsIDB4ZTEsIDB4MDIsIDB4ZGYsIDB4MjQsIDB4MzYsIDB4YTUsIDB4MjYsIDB4ZGIsCisgIDB4MGQsIDB4ODAsIDB4NWIsIDB4MjAsIDB4ZWYsIDB4NjksIDB4NTMsIDB4YWEsIDB4M2MsIDB4ZWEsIDB4NzUsIDB4NDksCisgIDB4ZmUsIDB4OTMsIDB4Y2QsIDB4ZjMsIDB4YmEsIDB4OTAsIDB4NmIsIDB4N2MsIDB4MGMsIDB4YWIsIDB4MWUsIDB4YjIsCisgIDB4ZGIsIDB4MTAsIDB4YTgsIDB4MTYsIDB4MGIsIDB4YjMsIDB4NzYsIDB4ZjcsIDB4NTgsIDB4NGMsIDB4OTYsIDB4NWMsCisgIDB4ODUsIDB4NmMsIDB4NzUsIDB4ZjQsIDB4MzksIDB4Y2MsIDB4M2MsIDB4ZWUsIDB4NjUsIDB4MzYsIDB4OTMsIDB4Y2EsCisgIDB4ZTAsIDB4MjAsIDB4ODUsIDB4NzMsIDB4OTAsIDB4N2EsIDB4NmYsIDB4N2EsIDB4ZWIsIDB4NGMsIDB4OTIsIDB4OTIsCisgIDB4MzYsIDB4NTgsIDB4ZjEsIDB4ZmIsIDB4ZTgsIDB4NzEsIDB4ZTcsIDB4ZDcsIDB4MmMsIDB4NWEsIDB4ZDcsIDB4MmIsCisgIDB4OTcsIDB4YjcsIDB4NzksIDB4NGIsIDB4MTIsIDB4NjcsIDB4M2EsIDB4OTAsIDB4NGUsIDB4OTIsIDB4NTYsIDB4NDAsCisgIDB4NjksIDB4YTAsIDB4MzcsIDB4ZjAsIDB4NTAsIDB4ODIsIDB4OTEsIDB4YjMsIDB4YWUsIDB4YmIsIDB4MzUsIDB4M2YsCisgIDB4NmMsIDB4YjQsIDB4ZGEsIDB4MmMsIDB4ODUsIDB4ZDcsIDB4ZDksIDB4NmMsIDB4OTksIDB4MmIsIDB4NDcsIDB4YmYsCisgIDB4NDksIDB4NzksIDB4NmEsIDB4NzUsIDB4ZjcsIDB4NDAsIDB4ZmQsIDB4MjUsIDB4MmIsIDB4NmEsIDB4MjMsIDB4ZDUsCisgIDB4ZGQsIDB4ZTgsIDB4MTQsIDB4ODIsIDB4YWMsIDB4YzMsIDB4M2EsIDB4Y2IsIDB4ZDYsIDB4MjMsIDB4ZTEsIDB4ZjYsCisgIDB4MmYsIDB4NzIsIDB4MjAsIDB4MTMsIDB4YTUsIDB4NWMsIDB4NjYsIDB4MjksIDB4MGUsIDB4YjgsIDB4NDcsIDB4NGYsCisgIDB4ODIsIDB4MDYsIDB4ZGEsIDB4NDksIDB4ZjUsIDB4ZWQsIDB4ZDIsIDB4M2MsIDB4NTEsIDB4YmEsIDB4OWIsIDB4YzYsCisgIDB4YjgsIDB4N2UsIDB4OTgsIDB4ZjEsIDB4OTQsIDB4NmYsIDB4ZjcsIDB4MTcsIDB4ZWUsIDB4MmUsIDB4M2UsIDB4NDIsCisgIDB4YTQsIDB4MzYsIDB4MWQsIDB4NTEsIDB4NGIsIDB4ZTcsIDB4ZmQsIDB4YWEsIDB4Y2YsIDB4OWUsIDB4ZTgsIDB4ZmQsCisgIDB4NTIsIDB4NDMsIDB4N2UsIDB4ODQsIDB4MDEsIDB4YTEsIDB4NTAsIDB4NDksIDB4MmUsIDB4YWMsIDB4YmEsIDB4ZDksCisgIDB4MjEsIDB4NDUsIDB4OGIsIDB4MzMsIDB4MzIsIDB4YWYsIDB4MzIsIDB4NDcsIDB4OWEsIDB4NWEsIDB4ODgsIDB4ZGYsCisgIDB4NDQsIDB4MWYsIDB4ZDcsIDB4NWEsIDB4YjQsIDB4OTQsIDB4N2IsIDB4MTQsIDB4NzcsIDB4ZWEsIDB4YTgsIDB4MzYsCisgIDB4MzAsIDB4NjksIDB4OTcsIDB4MTUsIDB4MjIsIDB4N2QsIDB4ZDYsIDB4NDQsIDB4NjgsIDB4NzIsIDB4N2MsIDB4YmQsCisgIDB4YzksIDB4Y2QsIDB4YzcsIDB4NjYsIDB4M2IsIDB4NzIsIDB4MDQsIDB4NDUsIDB4MmYsIDB4NWYsIDB4OTMsIDB4NzEsCisgIDB4YzQsIDB4ZWQsIDB4MmIsIDB4M2EsIDB4ZGEsIDB4YmEsIDB4MTQsIDB4ZWMsIDB4OWUsIDB4OWUsIDB4MjUsIDB4YmQsCisgIDB4ZDksIDB4MTYsIDB4YmIsIDB4MzQsIDB4MzQsIDB4MzAsIDB4OTAsIDB4Y2MsIDB4NjYsIDB4OTAsIDB4MzQsIDB4ZGIsCisgIDB4MmQsIDB4MjAsIDB4MGQsIDB4N2EsIDB4ODIsIDB4NDUsIDB4MjUsIDB4NjYsIDB4YmMsIDB4NDcsIDB4YjcsIDB4NTksCisgIDB4NWIsIDB4NmMsIDB4NGEsIDB4OTYsIDB4ODgsIDB4MjEsIDB4ZjMsIDB4Y2EsIDB4YzMsIDB4NDEsIDB4MjUsIDB4ZDksCisgIDB4MmYsIDB4OWYsIDB4NDMsIDB4NmQsIDB4YTcsIDB4NmEsIDB4NTEsIDB4ZjUsIDB4MjQsIDB4MTMsIDB4ZWMsIDB4YWQsCisgIDB4NjksIDB4ZDEsIDB4OTQsIDB4ZjcsIDB4NWMsIDB4NzksIDB4OTgsIDB4Y2UsIDB4YjQsIDB4NjEsIDB4YjcsIDB4NTEsCisgIDB4YjYsIDB4MGMsIDB4NmIsIDB4NDYsIDB4MzcsIDB4MDEsIDB4NGQsIDB4YTUsIDB4ZDUsIDB4MjQsIDB4YjgsIDB4ZTEsCisgIDB4NzUsIDB4ZDcsIDB4MWUsIDB4NzAsIDB4YjgsIDB4ZjMsIDB4ZWUsIDB4MTAsIDB4MDEsIDB4NWEsIDB4ODksIDB4ZWEsCisgIDB4YTUsIDB4NzQsIDB4MDMsIDB4ZDAsIDB4MDAsIDB4MDAsIDB4NjgsIDB4MDAsIDB4MmEsIDB4MjYsIDB4ZTUsIDB4OTIsCisgIDB4M2MsIDB4ZjcsIDB4YmQsIDB4NDIsIDB4NDEsIDB4NjUsIDB4MDQsIDB4ZWIsIDB4OWMsIDB4ODAsIDB4NTQsIDB4N2QsCisgIDB4OWUsIDB4MDMsIDB4ZWQsIDB4YWEsIDB4YmEsIDB4ZmYsIDB4MDAsIDB4OTQsIDB4NWMsIDB4YTMsIDB4MzQsIDB4ZGQsCisgIDB4ZWIsIDB4MmMsIDB4OWYsIDB4MTcsIDB4MDMsIDB4YzcsIDB4Y2YsIDB4OWMsIDB4YTksIDB4MTcsIDB4ODcsIDB4MDIsCisgIDB4ZWUsIDB4NzIsIDB4ODcsIDB4YTEsIDB4OTgsIDB4ZTksIDB4MjcsIDB4OTMsIDB4N2QsIDB4ZGIsIDB4NTcsIDB4MzEsCisgIDB4ZDcsIDB4ZTYsIDB4OGEsIDB4ODEsIDB4ZmMsIDB4NmUsIDB4NjYsIDB4MTksIDB4YjMsIDB4NmUsIDB4YzMsIDB4ZTAsCisgIDB4MTYsIDB4MDcsIDB4MjIsIDB4NWIsIDB4NjgsIDB4ZjMsIDB4MWUsIDB4YzgsIDB4YWYsIDB4NDksIDB4NGIsIDB4NGMsCisgIDB4YTMsIDB4YWUsIDB4YmQsIDB4ZWQsIDB4MmEsIDB4MjAsIDB4MjgsIDB4ZjgsIDB4ZjUsIDB4M2IsIDB4ZmQsIDB4NGEsCisgIDB4ZDUsIDB4N2IsIDB4YWEsIDB4NWIsIDB4YmUsIDB4ZjMsIDB4ZmQsIDB4MGMsIDB4YTQsIDB4YWIsIDB4NTUsIDB4ZjQsCisgIDB4NDUsIDB4YjksIDB4NzUsIDB4YzksIDB4MmMsIDB4N2MsIDB4M2MsIDB4YzUsIDB4YTcsIDB4NjUsIDB4NTksIDB4N2QsCisgIDB4YzEsIDB4YjgsIDB4MmMsIDB4ODQsIDB4NzksIDB4ODksIDB4NzEsIDB4NWUsIDB4ZmEsIDB4ZjEsIDB4ZDcsIDB4NDQsCisgIDB4MjEsIDB4M2QsIDB4ZWEsIDB4NTIsIDB4OGUsIDB4YjQsIDB4M2MsIDB4M2IsIDB4ZmIsIDB4YjYsIDB4NmIsIDB4OWIsCisgIDB4ZjAsIDB4NmYsIDB4YjMsIDB4NWMsIDB4ZWQsIDB4YmMsIDB4MzcsIDB4MTcsIDB4NWIsIDB4ZGIsIDB4NDUsIDB4OWIsCisgIDB4YWUsIDB4NDcsIDB4M2EsIDB4NDUsIDB4ZjIsIDB4NjMsIDB4NDcsIDB4YmQsIDB4YjUsIDB4NDksIDB4NWYsIDB4M2EsCisgIDB4NTIsIDB4N2QsIDB4NjEsIDB4MWMsIDB4ODAsIDB4OGYsIDB4MDMsIDB4YjEsIDB4NGIsIDB4ZGMsIDB4M2IsIDB4ZTAsCisgIDB4NDQsIDB4NjYsIDB4YWUsIDB4NGQsIDB4NjUsIDB4OWMsIDB4NTQsIDB4YmEsIDB4MzksIDB4OWMsIDB4NjUsIDB4OWIsCisgIDB4ZTYsIDB4NGIsIDB4OTMsIDB4MDksIDB4NWMsIDB4NDgsIDB4N2QsIDB4NzYsIDB4MTIsIDB4Y2IsIDB4NDcsIDB4Y2QsCisgIDB4ZTksIDB4ZDMsIDB4YTksIDB4MWEsIDB4ZDgsIDB4ZDgsIDB4MDIsIDB4YWUsIDB4YzAsIDB4M2EsIDB4NzcsIDB4NTYsCisgIDB4MTUsIDB4MjYsIDB4ZTcsIDB4MjcsIDB4MjYsIDB4NmYsIDB4NGUsIDB4MGEsIDB4MTEsIDB4ZDIsIDB4ODQsIDB4NWUsCisgIDB4MzIsIDB4N2MsIDB4NDcsIDB4MTcsIDB4ZmQsIDB4YWEsIDB4YjYsIDB4N2QsIDB4ZjgsIDB4YTcsIDB4YmEsIDB4NDQsCisgIDB4ZTMsIDB4MjAsIDB4ZDQsIDB4MWMsIDB4NWMsIDB4N2YsIDB4ZjcsIDB4NTUsIDB4YjMsIDB4ZWYsIDB4YzUsIDB4M2QsCisgIDB4ZDUsIDB4MGIsIDB4OWUsIDB4NTcsIDB4ZGYsIDB4ZDAsIDB4OTEsIDB4NDUsIDB4NjQsIDB4OGQsIDB4OWEsIDB4MjgsCisgIDB4NDMsIDB4YzksIDB4OWEsIDB4NGMsIDB4ZTMsIDB4OGYsIDB4YzgsIDB4ZjYsIDB4NWQsIDB4ZjQsIDB4NDQsIDB4OGYsCisgIDB4ZTAsIDB4MzQsIDB4ZTcsIDB4NTAsIDB4MWMsIDB4NDUsIDB4YjIsIDB4YzgsIDB4YzksIDB4MzAsIDB4NWIsIDB4ZTYsCisgIDB4M2YsIDB4MTEsIDB4ZDYsIDB4ZDksIDB4OTEsIDB4NzAsIDB4ODIsIDB4ZWMsIDB4NjYsIDB4OWMsIDB4NzMsIDB4N2MsCisgIDB4ODksIDB4NTIsIDB4ZDIsIDB4NDAsIDB4MmEsIDB4ZDcsIDB4NWQsIDB4NmUsIDB4ODQsIDB4OTMsIDB4NzEsIDB4YmUsCisgIDB4MmUsIDB4ZGYsIDB4Y2MsIDB4MWYsIDB4NjUsIDB4NmMsIDB4YWEsIDB4ZmQsIDB4YmYsIDB4YzcsIDB4MmEsIDB4MWIsCisgIDB4NGEsIDB4MDMsIDB4NTgsIDB4MTEsIDB4MDksIDB4MWEsIDB4ZGYsIDB4NjksIDB4MmYsIDB4YWYsIDB4ZmQsIDB4MzUsCisgIDB4ZWIsIDB4OWIsIDB4OGMsIDB4YmYsIDB4ZDQsIDB4ZTAsIDB4M2YsIDB4YmQsIDB4OTcsIDB4ZmUsIDB4NWEsIDB4MDEsCisgIDB4ZmEsIDB4OGEsIDB4NDEsIDB4ZTcsIDB4ZTMsIDB4MmYsIDB4ZjUsIDB4NTgsIDB4MGYsIDB4ZWYsIDB4NjUsIDB4ZmYsCisgIDB4MDAsIDB4OTYsIDB4OGUsIDB4NmUsIDB4MzIsIDB4ZmYsIDB4MDAsIDB4NTMsIDB4ODAsIDB4ZmUsIDB4ZjYsIDB4NWYsCisgIDB4ZjksIDB4NjgsIDB4MDcsIDB4ZWEsIDB4MjksIDB4MDcsIDB4OWIsIDB4OGMsIDB4YmYsIDB4ZDQsIDB4ZTAsIDB4M2YsCisgIDB4YmQsIDB4OTcsIDB4ZmUsIDB4NWEsIDB4MzksIDB4ZjgsIDB4Y2IsIDB4ZmQsIDB4NTYsIDB4MDMsIDB4ZmIsIDB4ZDksCisgIDB4N2YsIDB4ZTUsIDB4YTAsIDB4MWYsIDB4YTgsIDB4MjMsIDB4NzQsIDB4ODMsIDB4Y2YsIDB4YzYsIDB4NWYsIDB4ZWEsCisgIDB4YjAsIDB4MWYsIDB4ZGUsIDB4NGIsIDB4ZmYsIDB4MDAsIDB4MmQsIDB4MWMsIDB4ZmMsIDB4NjUsIDB4ZmUsIDB4YWIsCisgIDB4MDEsIDB4ZmQsIDB4ZTQsIDB4YmYsIDB4ZjIsIDB4ZDAsIDB4MTQsIDB4OTcsIDB4MTUsIDB4NzEsIDB4NDksIDB4NTgsCisgIDB4ODcsIDB4MTIsIDB4ZTUsIDB4NWEsIDB4YWMsIDB4YzgsIDB4NGIsIDB4MzEsIDB4ZjIsIDB4NDksIDB4MjYsIDB4ZmQsCisgIDB4OGIsIDB4MmYsIDB4NWEsIDB4NDQsIDB4N2IsIDB4ZGIsIDB4MjksIDB4ZjcsIDB4ZjgsIDB4YmIsIDB4ZWUsIDB4NGEsCisgIDB4MjQsIDB4YjUsIDB4YjQsIDB4ZjUsIDB4ZTgsIDB4NDksIDB4MDAsIDB4N2MsIDB4MWEsIDB4YjMsIDB4MmMsIDB4MzcsCisgIDB4OWIsIDB4MDYsIDB4NTUsIDB4ODMsIDB4YzUsIDB4YzgsIDB4NWEsIDB4YjcsIDB4MzEsIDB4MjksIDB4ZjksIDB4NGMsCisgIDB4MzMsIDB4ZTQsIDB4ZTIsIDB4NDMsIDB4OGEsIDB4NDIsIDB4M2MsIDB4ZTUsIDB4YTUsIDB4MWMsIDB4OGYsIDB4ODAsCisgIDB4NDcsIDB4MzAsIDB4NmQsIDB4NDQsIDB4ZWMsIDB4MWYsIDB4ZDEsIDB4MjMsIDB4YTUsIDB4NzAsIDB4NzEsIDB4NzMsCisgIDB4MGMsIDB4ZTIsIDB4YjYsIDB4NzcsIDB4ODgsIDB4YjksIDB4NmIsIDB4OTQsIDB4MzAsIDB4YzgsIDB4ZjIsIDB4YTMsCisgIDB4M2MsIDB4ZGMsIDB4ZGIsIDB4N2MsIDB4OTgsIDB4YWUsIDB4YzksIDB4MGYsIDB4NDcsIDB4OTIsIDB4ZDIsIDB4YjksCisgIDB4OTAsIDB4YjQsIDB4MTUsIDB4MjcsIDB4NWIsIDB4ZWYsIDB4MWQsIDB4N2EsIDB4NzUsIDB4MzUsIDB4NWYsIDB4ZjAsCisgIDB4YjcsIDB4MjYsIDB4OGUsIDB4YmIsIDB4ODIsIDB4MTUsIDB4MzYsIDB4MzAsIDB4OGQsIDB4NmIsIDB4Y2IsIDB4NWYsCisgIDB4NzUsIDB4NDYsIDB4M2EsIDB4YmEsIDB4MjIsIDB4MDUsIDB4ZTksIDB4MDMsIDB4NTMsIDB4YTEsIDB4MTEsIDB4ZGUsCisgIDB4OGUsIDB4ZDAsIDB4ZTksIDB4ZTQsIDB4MGUsIDB4OWIsIDB4ZTYsIDB4MjAsIDB4NzUsIDB4YWQsIDB4YTksIDB4NjIsCisgIDB4NTksIDB4ODMsIDB4ZWIsIDB4ZjUsIDB4MzIsIDB4YWIsIDB4OTgsIDB4ZTIsIDB4NmIsIDB4YTcsIDB4ZDAsIDB4YmIsCisgIDB4YWYsIDB4ZDgsIDB4Y2MsIDB4YzcsIDB4ZjEsIDB4YzcsIDB4ODQsIDB4NmIsIDB4ZjQsIDB4YWIsIDB4ODQsIDB4ODYsCisgIDB4MzksIDB4NDMsIDB4OTAsIDB4OTIsIDB4NTAsIDB4ZDQsIDB4NTcsIDB4ZDAsIDB4ODUsIDB4MDIsIDB4YTgsIDB4ZGQsCisgIDB4OTIsIDB4NDYsIDB4OTAsIDB4MTQsIDB4MDEsIDB4NDcsIDB4N2YsIDB4MzAsIDB4ZDgsIDB4ZDksIDB4MjIsIDB4YjUsCisgIDB4OGMsIDB4YWEsIDB4ZDcsIDB4N2EsIDB4YjUsIDB4Y2YsIDB4ODUsIDB4NzUsIDB4YjcsIDB4YWEsIDB4MWQsIDB4OTUsCisgIDB4YzQsIDB4MjEsIDB4MzEsIDB4ZTUsIDB4MWYsIDB4MzUsIDB4MGYsIDB4MzQsIDB4YjQsIDB4MDUsIDB4MjAsIDB4YjQsCisgIDB4NDAsIDB4M2IsIDB4NzUsIDB4MmEsIDB4ZjMsIDB4NzksIDB4MTMsIDB4ZTcsIDB4MjUsIDB4NDMsIDB4YmIsIDB4YmIsCisgIDB4N2EsIDB4MmQsIDB4MzgsIDB4ZWIsIDB4OGUsIDB4NGYsIDB4OWQsIDB4MmUsIDB4MzUsIDB4ZjIsIDB4MzQsIDB4MDYsCisgIDB4MjcsIDB4YmMsIDB4MWYsIDB4N2MsIDB4YjQsIDB4NTUsIDB4ZGIsIDB4NzMsIDB4ODQsIDB4ZjIsIDB4YTksIDB4NDksCisgIDB4NDIsIDB4ZDQsIDB4NWIsIDB4NmQsIDB4NjQsIDB4NmIsIDB4OTksIDB4NDEsIDB4MjQsIDB4MTIsIDB4MzcsIDB4YTAsCisgIDB4NjksIDB4ODYsIDB4MWMsIDB4M2MsIDB4MzYsIDB4YzQsIDB4OTYsIDB4OTcsIDB4MGEsIDB4MGQsIDB4YmQsIDB4MGYsCisgIDB4MzIsIDB4ZDgsIDB4NmQsIDB4MGUsIDB4MzQsIDB4Y2EsIDB4NTQsIDB4ZTksIDB4MDAsIDB4NmIsIDB4YWEsIDB4YjUsCisgIDB4YjIsIDB4NzUsIDB4ZTIsIDB4NGQsIDB4NDYsIDB4ODYsIDB4OWUsIDB4MzEsIDB4YjgsIDB4ZjcsIDB4ODksIDB4YWMsCisgIDB4YjcsIDB4YjAsIDB4YWYsIDB4OGIsIDB4ZDgsIDB4ZjMsIDB4NTYsIDB4ZTcsIDB4ZmIsIDB4YWUsIDB4OTcsIDB4MGMsCisgIDB4NjUsIDB4ZGMsIDB4NjMsIDB4YjIsIDB4ZjQsIDB4YzYsIDB4ZTUsIDB4YzgsIDB4MDUsIDB4YWUsIDB4ZGMsIDB4MzQsCisgIDB4ODQsIDB4MTcsIDB4MGIsIDB4NDksIDB4NmMsIDB4MmMsIDB4MmYsIDB4NDksIDB4MWIsIDB4NmYsIDB4OWMsIDB4MjcsCisgIDB4N2IsIDB4M2IsIDB4MWIsIDB4ZDUsIDB4MzQsIDB4ZGEsIDB4YjAsIDB4N2MsIDB4N2EsIDB4MjQsIDB4NjYsIDB4NTMsCisgIDB4MmUsIDB4MTMsIDB4NTcsIDB4MDksIDB4MjgsIDB4ZGEsIDB4ZGQsIDB4N2QsIDB4ZjQsIDB4MDMsIDB4ZGIsIDB4MzgsCisgIDB4NTQsIDB4NTQsIDB4YTUsIDB4YTksIDB4M2YsIDB4MDcsIDB4N2IsIDB4NTEsIDB4ZDcsIDB4NGUsIDB4OWQsIDB4MDAsCisgIDB4ZWUsIDB4YTIsIDB4NDYsIDB4NTQsIDB4ODAsIDB4OWQsIDB4NDUsIDB4OGEsIDB4NDgsIDB4MDAsIDB4ZjksIDB4Y2UsCisgIDB4MmIsIDB4YTAsIDB4ZjYsIDB4ZWIsIDB4ZmYsIDB4MDAsIDB4MzUsIDB4NWQsIDB4NWQsIDB4YjgsIDB4YjMsIDB4MDYsCisgIDB4ZTUsIDB4NzAsIDB4NTUsIDB4YWEsIDB4YzIsIDB4ZWMsIDB4ZGMsIDB4YTIsIDB4ZTIsIDB4MDksIDB4MDYsIDB4MDUsCisgIDB4ODEsIDB4YWUsIDB4ZGYsIDB4OTMsIDB4YzMsIDB4ZGYsIDB4MWMsIDB4MDQsIDB4MzYsIDB4ZDgsIDB4ZGYsIDB4OGEsCisgIDB4ZDYsIDB4MmIsIDB4NGYsIDB4YjMsIDB4Y2YsIDB4OTksIDB4ZWMsIDB4NjcsIDB4ZjYsIDB4ODgsIDB4N2UsIDB4MGQsCisgIDB4Y2IsIDB4NjYsIDB4N2QsIDB4ZTIsIDB4ZGQsIDB4MDEsIDB4MWQsIDB4OTksIDB4NzAsIDB4MmQsIDB4NjksIDB4ZWUsCisgIDB4NmQsIDB4YmUsIDB4YmEsIDB4ZmYsIDB4MDAsIDB4YjAsIDB4YTQsIDB4MWMsIDB4ZDcsIDB4ODksIDB4OTYsIDB4ZmIsCisgIDB4NGIsIDB4YWQsIDB4YzQsIDB4OTMsIDB4MzgsIDB4MzEsIDB4MmEsIDB4NDcsIDB4NDgsIDB4ZjAsIDB4MjIsIDB4YjYsCisgIDB4YTcsIDB4ZTYsIDB4M2UsIDB4N2MsIDB4MzksIDB4NWIsIDB4NDAsIDB4MmIsIDB4M2YsIDB4ZGMsIDB4MDcsIDB4YWYsCisgIDB4YzYsIDB4YTksIDB4MGUsIDB4MjMsIDB4NzEsIDB4M2QsIDB4MTYsIDB4ODIsIDB4YTgsIDB4ZDksIDB4NGUsIDB4NTUsCisgIDB4MWUsIDB4YzgsIDB4ZTksIDB4MjUsIDB4M2UsIDB4ZTAsIDB4NjIsIDB4ZWUsIDB4MjIsIDB4NzUsIDB4Y2QsIDB4NWQsCisgIDB4ZmUsIDB4NjMsIDB4ZDIsIDB4Y2YsIDB4YmQsIDB4NDcsIDB4M2IsIDB4ZWYsIDB4ZTQsIDB4MDUsIDB4NWQsIDB4N2EsCisgIDB4MWEsIDB4ZTMsIDB4ZTEsIDB4ZTUsIDB4ODcsIDB4OGMsIDB4YjksIDB4ODQsIDB4NTksIDB4M2YsIDB4OGIsIDB4ZmMsCisgIDB4NWUsIDB4MTcsIDB4MGEsIDB4ZWMsIDB4MzIsIDB4OTIsIDB4YTUsIDB4MmEsIDB4ZWIsIDB4MjQsIDB4MmQsIDB4Y2IsCisgIDB4OGMsIDB4ZGUsIDB4YTMsIDB4NWQsIDB4YTMsIDB4ZWUsIDB4NmQsIDB4ZTUsIDB4NmYsIDB4NWIsIDB4ZGEsIDB4NDIsCisgIDB4NTMsIDB4NGQsIDB4NTQsIDB4ZTksIDB4ZjgsIDB4NTYsIDB4NWYsIDB4OWIsIDB4MWEsIDB4MmEsIDB4NTQsIDB4ZjEsCisgIDB4M2MsIDB4MjEsIDB4Y2IsIDB4MzksIDB4Y2UsIDB4YTUsIDB4NWIsIDB4MjMsIDB4MmUsIDB4NWUsIDB4NTMsIDB4N2QsCisgIDB4ODcsIDB4YzMsIDB4ZDgsIDB4NGIsIDB4NDcsIDB4M2EsIDB4MWEsIDB4OTIsIDB4NTMsIDB4MzIsIDB4ZmIsIDB4MjEsCisgIDB4M2QsIDB4M2EsIDB4YTIsIDB4MzIsIDB4NDksIDB4NDMsIDB4M2IsIDB4ZGUsIDB4YjksIDB4OTYsIDB4NTQsIDB4NDcsCisgIDB4ODgsIDB4MTQsIDB4ODUsIDB4ODgsIDB4NWQsIDB4ZjgsIDB4OGIsIDB4OWEsIDB4Y2UsIDB4NzcsIDB4ZjEsIDB4MjksCisgIDB4ODMsIDB4MzksIDB4NjEsIDB4OGQsIDB4MjMsIDB4NjgsIDB4N2YsIDB4MzEsIDB4YmYsIDB4YWIsIDB4YjcsIDB4OWMsCisgIDB4ZmEsIDB4NzcsIDB4YTMsIDB4YTcsIDB4OWMsIDB4MDUsIDB4MjksIDB4MWYsIDB4YTgsIDB4ZDgsIDB4NTYsIDB4YjUsCisgIDB4ZDMsIDB4NTQsIDB4Y2YsIDB4ODAsIDB4ZmUsIDB4MGIsIDB4ZDcsIDB4Y2MsIDB4NzYsIDB4ZjAsIDB4NmYsIDB4NzcsCisgIDB4YTQsIDB4ZTIsIDB4YjksIDB4NzUsIDB4ZDcsIDB4YjUsIDB4ZWQsIDB4NDMsIDB4ZDcsIDB4NzksIDB4MTIsIDB4OTQsCisgIDB4ZGYsIDB4MzAsIDB4M2IsIDB4MGEsIDB4MmQsIDB4ODQsIDB4ZTksIDB4NjcsIDB4ZTcsIDB4OTUsIDB4MGEsIDB4YmMsCisgIDB4NTksIDB4NmYsIDB4OGMsIDB4MGMsIDB4MzQsIDB4ODYsIDB4OTksIDB4OGQsIDB4YzMsIDB4ZjYsIDB4ZGIsIDB4NmQsCisgIDB4MjEsIDB4MjgsIDB4NGEsIDB4NTcsIDB4MmQsIDB4MjEsIDB4MjksIDB4MWQsIDB4YzAsIDB4MDAsIDB4OWUsIDB4ODMsCisgIDB4YTcsIDB4NzUsIDB4NjUsIDB4M2EsIDB4YjIsIDB4OWYsIDB4MmMsIDB4ZGEsIDB4MTQsIDB4YTMsIDB4MGUsIDB4MGEsCisgIDB4ZmIsIDB4MDIsIDB4ZmMsIDB4MTgsIDB4ZjEsIDB4ZDgsIDB4ZDcsIDB4MDQsIDB4ZTQsIDB4MWMsIDB4NGEsIDB4YmIsCisgIDB4NGUsIDB4Y2UsIDB4ZWYsIDB4ZWIsIDB4NTcsIDB4M2IsIDB4OGIsIDB4OWMsIDB4ZWEsIDB4OGMsIDB4NjAsIDB4YWUsCisgIDB4OWQsIDB4MzksIDB4MDksIDB4MjUsIDB4N2EsIDB4M2QsIDB4MzQsIDB4YTIsIDB4NTMsIDB4YTEsIDB4ZjAsIDB4NDUsCisgIDB4NWYsIDB4NzAsIDB4ZTEsIDB4YzUsIDB4ODcsIDB4MTEsIDB4YTgsIDB4OTAsIDB4ZTMsIDB4YjUsIDB4MWEsIDB4M2IsCisgIDB4MjksIDB4MDgsIDB4NmQsIDB4YTYsIDB4OTAsIDB4MTAsIDB4OTQsIDB4MjQsIDB4NzgsIDB4MDAsIDB4M2EsIDB4MDEsCisgIDB4ZWMsIDB4YTQsIDB4N2QsIDB4ZjEsIDB4OTMsIDB4ZmEsIDB4YWMsIDB4MDcsIDB4ZjcsIDB4OTIsIDB4ZmYsIDB4MDAsCisgIDB4Y2IsIDB4NTksIDB4MGEsIDB4ZTMsIDB4MmYsIDB4ZjUsIDB4MzgsIDB4MGYsIDB4ZWYsIDB4NjUsIDB4ZmYsIDB4MDAsCisgIDB4OTYsIDB4YjMsIDB4MmUsIDB4M2UsIDB4ZTgsIDB4NTYsIDB4NDcsIDB4NGEsIDB4NDEsIDB4ZTcsIDB4ZTMsIDB4MmYsCisgIDB4ZjUsIDB4NTgsIDB4MGYsIDB4ZWYsIDB4NjUsIDB4ZmYsIDB4MDAsIDB4OTYsIDB4OGUsIDB4N2UsIDB4MzIsIDB4ZmYsCisgIDB4MDAsIDB4NTUsIDB4ODAsIDB4ZmUsIDB4ZjIsIDB4NWYsIDB4ZjksIDB4NjgsIDB4MGYsIDB4N2MsIDB4NjUsIDB4ZjgsCisgIDB4OTYsIDB4MmYsIDB4ZmIsIDB4NTUsIDB4NmMsIDB4ZmIsIDB4ZjEsIDB4NGYsIDB4NzUsIDB4NTgsIDB4ZGQsIDB4YWMsCisgIDB4NWMsIDB4NGQsIDB4YzgsIDB4NjYsIDB4NTksIDB4NWEsIDB4YmUsIDB4YWYsIDB4MTAsIDB4NjIsIDB4MDQsIDB4MWIsCisgIDB4YjQsIDB4NmIsIDB4ODMsIDB4YTYsIDB4MTIsIDB4YTQsIDB4MTcsIDB4NTQsIDB4MTksIDB4NTgsIDB4NTcsIDB4MmEsCisgIDB4NDIsIDB4YzYsIDB4YmEsIDB4ZWEsIDB4YWMsIDB4ZWEsIDB4MDAsIDB4YTIsIDB4YjAsIDB4NDksIDB4ZjAsIDB4YTIsCisgIDB4ODAsIDB4Y2QsIDB4MWEsIDB4ZWIsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NDUsIDB4MTQsIDB4NTAsIDB4MDUsIDB4MTQsCisgIDB4NTEsIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDEsIDB4NWYsIDB4MmIsCisgIDB4N2UsIDB4MTEsIDB4MzgsIDB4NzUsIDB4Y2YsIDB4MGEsIDB4YzksIDB4ZWYsIDB4NzksIDB4N2MsIDB4MWMsIDB4N2QsCisgIDB4ZWIsIDB4ZjYsIDB4MDksIDB4OTEsIDB4ODYsIDB4OWMsIDB4YzgsIDB4ZTAsIDB4NDMsIDB4NTEsIDB4NGMsIDB4YTgsCisgIDB4MTIsIDB4ZGIsIDB4ZGYsIDB4MjQsIDB4ZTYsIDB4MDgsIDB4ZjgsIDB4MGIsIDB4MWYsIDB4MGIsIDB4OTgsIDB4NzQsCisgIDB4ZGYsIDB4MzAsIDB4NTcsIDB4NDIsIDB4MGQsIDB4N2QsIDB4NTMsIDB4NTgsIDB4NTIsIDB4NDIsIDB4YmEsIDB4MjgsCisgIDB4NmMsIDB4MWUsIDB4ODQsIDB4NTAsIDB4MWYsIDB4MTksIDB4ZTMsIDB4M2MsIDB4NDYsIDB4ZTIsIDB4NWMsIDB4N2IsCisgIDB4MTIsIDB4MmUsIDB4OTYsIDB4OWIsIDB4NjQsIDB4MWUsIDB4MjgsIDB4NjMsIDB4Y2QsIDB4NjgsIDB4NzksIDB4NzUsCisgIDB4YWQsIDB4NjUsIDB4YWIsIDB4OTMsIDB4NDksIDB4ZjAsIDB4MTIsIDB4MjMsIDB4OGQsIDB4YTksIDB4MGUsIDB4MDEsCisgIDB4ZGUsIDB4NDIsIDB4MDgsIDB4ZGYsIDB4ZTcsIDB4MTAsIDB4NzYsIDB4NTgsIDB4ZWMsIDB4ZGMsIDB4NTIsIDB4Y2IsCisgIDB4YjIsIDB4MDgsIDB4Y2IsIDB4N2UsIDB4ZDUsIDB4YzMsIDB4MjksIDB4NzYsIDB4ODgsIDB4NmQsIDB4OTAsIDB4OTcsCisgIDB4YWUsIDB4OTksIDB4MWMsIDB4ZTQsIDB4ZGIsIDB4ZTEsIDB4MzIsIDB4NzcsIDB4ZDQsIDB4YTksIDB4NmEsIDB4NGUsCisgIDB4ZDUsIDB4ZWIsIDB4MDksIDB4ZDksIDB4ZjUsIDB4NTUsIDB4OGQsIDB4YzQsIDB4MGYsIDB4YzEsIDB4ZDcsIDB4MDUsCisgIDB4YzgsIDB4ZWUsIDB4YzYsIDB4ZmIsIDB4NjUsIDB4NzIsIDB4ZTMsIDB4ODcsIDB4ZGUsIDB4ZjcsIDB4YmYsIDB4MmQsCisgIDB4YjEsIDB4YmQsIDB4ZTQsIDB4ZmMsIDB4YzcsIDB4ZDIsIDB4YTQsIDB4MDEsIDB4YWQsIDB4ZjgsIDB4ZWMsIDB4NjgsCisgIDB4OTMsIDB4ZDQsIDB4OWEsIDB4ZTYsIDB4YjQsIDB4N2UsIDB4MGQsIDB4YjgsIDB4NmEsIDB4ZWUsIDB4Y2QsIDB4ZGQsCisgIDB4ZjMsIDB4NGIsIDB4Y2UsIDB4NDksIDB4OWMsIDB4Y2UsIDB4NmMsIDB4MGUsIDB4NTMsIDB4N2MsIDB4YjgsIDB4MjksCisgIDB4ZDYsIDB4YzYsIDB4YmYsIDB4NTAsIDB4NmIsIDB4NjMsIDB4YTAsIDB4ZTgsIDB4NDksIDB4MWUsIDB4YWEsIDB4ZGQsCisgIDB4NWMsIDB4ZDQsIDB4NGIsIDB4MTksIDB4MzAsIDB4NzYsIDB4ZDQsIDB4ZGIsIDB4Y2IsIDB4NDUsIDB4NGQsIDB4MTcsCisgIDB4M2YsIDB4NzIsIDB4NmQsIDB4YzMsIDB4ZGMsIDB4ZWIsIDB4NDIsIDB4MmUsIDB4OWMsIDB4NWUsIDB4YzksIDB4MDQsCisgIDB4ODAsIDB4ZjAsIDB4NjIsIDB4Y2MsIDB4Y2EsIDB4ZTEsIDB4NTksIDB4YTAsIDB4MTAsIDB4ODUsIDB4MjMsIDB4YjMsCisgIDB4MmIsIDB4ZWYsIDB4NzksIDB4MWUsIDB4NzksIDB4MjcsIDB4OWYsIDB4Y2QsIDB4M2EsIDB4MWQsIDB4ZDQsIDB4ZTksCisgIDB4MDMsIDB4ODMsIDB4ZmMsIDB4NTUsIDB4Y2MsIDB4ZWQsIDB4Y2QsIDB4YzMsIDB4Y2QsIDB4ZjIsIDB4ZTgsIDB4MTgsCisgIDB4NTYsIDB4M2MsIDB4NDcsIDB4ZmEsIDB4YjcsIDB4OGEsIDB4NDcsIDB4MGQsIDB4MjMsIDB4OTMsIDB4YTcsIDB4OWEsCisgIDB4YjcsIDB4M2IsIDB4YmMsIDB4MDcsIDB4N2YsIDB4MzgsIDB4YWYsIDB4YTEsIDB4NmMsIDB4ZjYsIDB4OWIsIDB4NWQsCisgIDB4OWEsIDB4MGEsIDB4NjAsIDB4NWEsIDB4MmQsIDB4ZDEsIDB4MmQsIDB4ZjEsIDB4MTEsIDB4ZjAsIDB4NTksIDB4OGEsCisgIDB4Y2EsIDB4NWEsIDB4NDAsIDB4ZjYsIDB4MjUsIDB4MjAsIDB4MGEsIDB4ZWMsIDB4MDAsIDB4MGEsIDB4Y2EsIDB4NTMsCisgIDB4OTQsIDB4YjksIDB4MzUsIDB4OGMsIDB4MjMsIDB4MWUsIDB4MTEsIDB4NWYsIDB4NzAsIDB4ZTMsIDB4ODIsIDB4ZmMsCisgIDB4MzYsIDB4YzAsIDB4NDMsIDB4NGUsIDB4ZTMsIDB4ZDgsIDB4Y2MsIDB4NTEsIDB4MzUsIDB4YjEsIDB4ZjEsIDB4ZTksCisgIDB4NDMsIDB4YjcsIDB4OTIsIDB4NGYsIDB4YTcsIDB4OWQsIDB4N2IsIDB4ZTUsIDB4M2YsIDB4MzcsIDB4NDMsIDB4ZDUsCisgIDB4NTYsIDB4MGYsIDB4MjgsIDB4YWMsIDB4ODEsIDB4YWUsIDB4ZWEsIDB4MmEsIDB4YTUsIDB4OGMsIDB4NjgsIDB4NTYsCisgIDB4NjgsIDB4YTIsIDB4ODAsIDB4MjgsIDB4YTIsIDB4OGEsIDB4MDAsIDB4YTIsIDB4OGEsIDB4MjgsIDB4MDMsIDB4NDIsCisgIDB4OGEsIDB4MjgsIDB4YTAsIDB4MzAsIDB4NTIsIDB4MGYsIDB4N2QsIDB4MTUsIDB4OWEsIDB4MjgsIDB4MDIsIDB4OGEsCisgIDB4MjgsIDB4YTAsIDB4MGEsIDB4MjgsIDB4YTIsIDB4ODAsIDB4MjgsIDB4YTIsIDB4OGEsIDB4MDAsIDB4YTIsIDB4OGEsCisgIDB4MjgsIDB4MDIsIDB4OGEsIDB4MjgsIDB4YTAsIDB4MGEsIDB4MjgsIDB4YTIsIDB4ODAsIDB4MzUsIDB4NDUsIDB4MTQsCisgIDB4NTAsIDB4MDUsIDB4MTQsIDB4NTEsIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsIDB4NTEsIDB4NDUsIDB4MTQsCisgIDB4MDEsIDB4NDUsIDB4MTQsIDB4NTAsIDB4MDUsIDB4MTQsIDB4NTEsIDB4NDAsIDB4MTQsIDB4NTEsIDB4NDUsIDB4MDAsCisgIDB4NTEsIDB4NDUsIDB4MTQsIDB4MDcsIDB4ZmYsIDB4ZDkKK307CmRpZmYgLS1naXQgYS9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9GYWtlQ2FtZXJhLmNwcCBiL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0Zha2VDYW1lcmEuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1OTJlYWIKLS0tIC9kZXYvbnVsbAorKysgYi9jYW1lcmEvbGliY2FtZXJhc2VydmljZS9GYWtlQ2FtZXJhLmNwcApAQCAtMCwwICsxLDQwNCBAQAorI2RlZmluZSBMT0dfVEFHICJGYWtlQ2FtZXJhIgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSAiRmFrZUNhbWVyYS5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0YXRpYyBpbnQgdGFibGVzX2luaXRpYWxpemVkID0gMDsKK3VpbnQ4X3QgKmdZVGFibGUsICpnQ2JUYWJsZSwgKmdDclRhYmxlOworCitzdGF0aWMgaW50CitjbGFtcChpbnQgIHgpCit7CisgICAgaWYgKHggPiAyNTUpIHJldHVybiAyNTU7CisgICAgaWYgKHggPCAwKSAgIHJldHVybiAwOworICAgIHJldHVybiB4OworfQorCisvKiB0aGUgZXF1YXRpb24gdXNlZCBieSB0aGUgdmlkZW8gY29kZSB0byB0cmFuc2xhdGUgWVVWIHRvIFJHQiBsb29rcyBsaWtlIHRoaXMKKyAqCisgKiAgICBZICA9IChZMCAtIDE2KSprMAorICogICAgQ2IgPSBDYjAgLSAxMjgKKyAqICAgIENyID0gQ3IwIC0gMTI4CisgKgorICogICAgRyA9ICggWSAtIGsxKkNyIC0gazIqQ2IgKQorICogICAgUiA9ICggWSArIGszKkNyICkKKyAqICAgIEIgPSAoIFkgKyBrNCpDYiApCisgKgorICovCisKK3N0YXRpYyBjb25zdCBkb3VibGUgIGswID0gMS4xNjQ7CitzdGF0aWMgY29uc3QgZG91YmxlICBrMSA9IDAuODEzOworc3RhdGljIGNvbnN0IGRvdWJsZSAgazIgPSAwLjM5MTsKK3N0YXRpYyBjb25zdCBkb3VibGUgIGszID0gMS41OTY7CitzdGF0aWMgY29uc3QgZG91YmxlICBrNCA9IDIuMDE4OworCisvKiBsZXQncyB0cnkgdG8gZXh0cmFjdCB0aGUgdmFsdWUgb2YgWQorICoKKyAqICAgRyArIGsxL2szKlIgKyBrMi9rNCpCID0gWSooIDEgKyBrMS9rMyArIGsyL2s0ICkKKyAqCisgKiAgIFkgID0gKCBHICsgazEvazMqUiArIGsyL2s0KkIgKSAvICgxICsgazEvazMgKyBrMi9rNCkKKyAqICAgWTAgPSAoIEcwICsgazEvazMqUjAgKyBrMi9rNCpCMCApIC8gKCgxICsgazEvazMgKyBrMi9rNCkqazApICsgMTYKKyAqCisgKiBsZXQgZGVmaW5lOgorICogICBrWXIgPSBrMS9rMworICogICBrWWIgPSBrMi9rNAorICogICBrWXkgPSBrMCAqICggMSArIGtZciArIGtZYiApCisgKgorICogd2UgaGF2ZToKKyAqICAgIFkgID0gKCBHICsga1lyKlIgKyBrWWIqQiApCisgKiAgICBZMCA9IGNsYW1wWyBZL2tZeSArIDE2IF0KKyAqLworCitzdGF0aWMgY29uc3QgZG91YmxlIGtZciA9IGsxL2szOworc3RhdGljIGNvbnN0IGRvdWJsZSBrWWIgPSBrMi9rNDsKK3N0YXRpYyBjb25zdCBkb3VibGUga1l5ID0gazAqKCAxLiArIGtZciArIGtZYiApOworCitzdGF0aWMgdm9pZAoraW5pdFl0YWIoIHZvaWQgKQoreworICAgIGNvbnN0ICBpbnQgaW1heCA9IChpbnQpKCAoa1lyICsga1liKSooMzEgPDwgMikgKyAoNjEgPDwgMykgKyAwLjEgKTsKKyAgICBpbnQgICAgaTsKKworICAgIGdZVGFibGUgPSAodWludDhfdCAqKW1hbGxvYyhpbWF4KTsKKworICAgIGZvcihpPTA7IGk8aW1heDsgaSsrKSB7CisgICAgICAgIGludCAgeCA9IChpbnQpKGkva1l5ICsgMTYuNSk7CisgICAgICAgIGlmICh4IDwgMTYpIHggPSAxNjsKKyAgICAgICAgZWxzZSBpZiAoeCA+IDIzNSkgeCA9IDIzNTsKKyAgICAgICAgZ1lUYWJsZVtpXSA9ICh1aW50OF90KSB4OworICAgIH0KK30KKworLyoKKyAqICAgdGhlIHNvdXJjZSBpcyBSR0I1NjUsIHNvIGFkanVzdCBmb3IgOC1iaXQgcmFuZ2Ugb2YgaW5wdXQgdmFsdWVzOgorICoKKyAqICAgRyA9IChwaXhlbHMgPj4gMykgJiAweEZDOworICogICBSID0gKHBpeGVscyA+PiA4KSAmIDB4Rjg7CisgKiAgIEIgPSAocGl4ZWxzICYgMHgxZikgPDwgMzsKKyAqCisgKiAgIFIyID0gKHBpeGVscyA+PiAxMSkgICAgICBSID0gUjIqOAorICogICBCMiA9IChwaXhlbHMgJiAweDFmKSAgICAgQiA9IEIyKjgKKyAqCisgKiAgIGtZcipSID0ga1lyMipSMiA9PiAga1lyMiA9IGtZcio4CisgKiAgIGtZYipCID0ga1liMipCMiA9PiAga1liMiA9IGtZYio4CisgKgorICogICB3ZSB3YW50IHRvIHVzZSBpbnRlZ2VyIG11bHRpcGxpY2F0aW9uczoKKyAqCisgKiAgIFNISUZUMSA9IDkKKyAqCisgKiAgIChBTFBIQSpSMikgPj4gU0hJRlQxID09IFIqa1lyICA9PiAgQUxQSEEgPSBrWXIqOCooMSA8PCBTSElGVDEpCisgKgorICogICBBTFBIQSA9IGtZciooMSA8PCAoU0hJRlQxKzMpKQorICogICBCRVRBICA9IGtZYiooMSA8PCAoU0hJRlQxKzMpKQorICovCisKK3N0YXRpYyBjb25zdCBpbnQgIFNISUZUMSAgPSA5Oworc3RhdGljIGNvbnN0IGludCAgQUxQSEEgICA9IChpbnQpKCBrWXIqKDEgPDwgKFNISUZUMSszKSkgKyAwLjUgKTsKK3N0YXRpYyBjb25zdCBpbnQgIEJFVEEgICAgPSAoaW50KSgga1liKigxIDw8IChTSElGVDErMykpICsgMC41ICk7CisKKy8qCisgKiAgbm93IGxldCdzIHRyeSB0byBnZXQgdGhlIHZhbHVlcyBvZiBDYiBhbmQgQ3IKKyAqCisgKiAgUi1CID0gKGszKkNyIC0gazQqQ2IpCisgKgorICogICAgazMqQ3IgPSBrNCpDYiArIChSLUIpCisgKiAgICBrNCpDYiA9IGszKkNyIC0gKFItQikKKyAqCisgKiAgUi1HID0gKGsxK2szKSpDciArIGsyKkNiCisgKiAgICAgID0gKGsxK2szKSpDciArIGsyL2s0KihrMypDciAtIChSLUIpL2swKQorICogICAgICA9IChrMSArIGszICsgazIqazMvazQpKkNyIC0gazIvazQqKFItQikKKyAqCisgKiAga1JyKkNyID0gKFItRykgKyBrWWIqKFItQikKKyAqCisgKiAgQ3IgID0gKChSLUcpICsga1liKihSLUIpKS9rUnIKKyAqICBDcjAgPSBjbGFtcChDciArIDEyOCkKKyAqLworCitzdGF0aWMgY29uc3QgZG91YmxlICBrUnIgPSAoazEgKyBrMyArIGsyKmszL2s0KTsKKworc3RhdGljIHZvaWQKK2luaXRDcnRhYiggdm9pZCApCit7CisgICAgdWludDhfdCAqcFRhYmxlOworICAgIGludCBpOworCisgICAgZ0NyVGFibGUgPSAodWludDhfdCAqKW1hbGxvYyg3NjgqMik7CisKKyAgICBwVGFibGUgPSBnQ3JUYWJsZSArIDM4NDsKKyAgICBmb3IoaT0tMzg0OyBpPDM4NDsgaSsrKQorICAgICAgICBwVGFibGVbaV0gPSAodWludDhfdCkgY2xhbXAoIGkva1JyICsgMTI4LjUgKTsKK30KKworLyoKKyAqICBCLUcgPSAoazIgKyBrNCkqQ2IgKyBrMSpDcgorICogICAgICA9IChrMiArIGs0KSpDYiArIGsxL2szKihrNCpDYiArIChSLUIpKQorICogICAgICA9IChrMiArIGs0ICsgazEqazQvazMpKkNiICsgazEvazMqKFItQikKKyAqCisgKiAga0JiKkNiID0gKEItRykgLSBrWXIqKFItQikKKyAqCisgKiAgQ2IgICA9ICgoQi1HKSAtIGtZciooUi1CKSkva0JiCisgKiAgQ2IwICA9IGNsYW1wKENiICsgMTI4KQorICoKKyAqLworCitzdGF0aWMgY29uc3QgZG91YmxlICBrQmIgPSAoazIgKyBrNCArIGsxKms0L2szKTsKKworc3RhdGljIHZvaWQKK2luaXRDYnRhYiggdm9pZCApCit7CisgICAgdWludDhfdCAqcFRhYmxlOworICAgIGludCBpOworCisgICAgZ0NiVGFibGUgPSAodWludDhfdCAqKW1hbGxvYyg3NjgqMik7CisKKyAgICBwVGFibGUgPSBnQ2JUYWJsZSArIDM4NDsKKyAgICBmb3IoaT0tMzg0OyBpPDM4NDsgaSsrKQorICAgICAgICBwVGFibGVbaV0gPSAodWludDhfdCkgY2xhbXAoIGkva0JiICsgMTI4LjUgKTsKK30KKworLyoKKyAqICAgU0hJRlQyID0gMTYKKyAqCisgKiAgIERFTFRBID0ga1liKigxIDw8IFNISUZUMikKKyAqICAgR0FNTUEgPSBrWXIqKDEgPDwgU0hJRlQyKQorICovCisKK3N0YXRpYyBjb25zdCBpbnQgIFNISUZUMiA9IDE2Oworc3RhdGljIGNvbnN0IGludCAgREVMVEEgID0ga1liKigxIDw8IFNISUZUMik7CitzdGF0aWMgY29uc3QgaW50ICBHQU1NQSAgPSBrWXIqKDEgPDwgU0hJRlQyKTsKKworaW50MzJfdCBjY3JnYjE2dG95dXZfd29fY29sb3JrZXkodWludDhfdCAqcmdiMTYsdWludDhfdCAqeXV2NDIyLHVpbnQzMl90ICpwYXJhbSx1aW50OF90ICp0YWJsZVtdKQoreworICAgIHVpbnQxNl90ICppbnB1dFJHQiA9ICh1aW50MTZfdCopcmdiMTY7CisgICAgdWludDhfdCAqb3V0WVVWID0gIHl1djQyMjsKKyAgICBpbnQzMl90IHdpZHRoX2RzdCA9IHBhcmFtWzBdOworICAgIGludDMyX3QgaGVpZ2h0X2RzdCA9IHBhcmFtWzFdOworICAgIGludDMyX3QgcGl0Y2hfZHN0ID0gcGFyYW1bMl07CisgICAgaW50MzJfdCBtaGVpZ2h0X2RzdCA9IHBhcmFtWzNdOworICAgIGludDMyX3QgcGl0Y2hfc3JjID0gcGFyYW1bNF07CisgICAgdWludDhfdCAqeV90YWIgPSB0YWJsZVswXTsKKyAgICB1aW50OF90ICpjYl90YWIgPSB0YWJsZVsxXTsKKyAgICB1aW50OF90ICpjcl90YWIgPSB0YWJsZVsyXTsKKworICAgIGludDMyX3Qgc2l6ZTE2ID0gcGl0Y2hfZHN0Km1oZWlnaHRfZHN0OworICAgIGludDMyX3QgaSxqLGNvdW50OworICAgIGludDMyX3QgaWxpbWl0LGpsaW1pdDsKKyAgICB1aW50OF90ICp0ZW1wWSwqdGVtcFUsKnRlbXBWOworICAgIHVpbnQxNl90IHBpeGVsczsKKyAgICBpbnQgICB0bXA7Cit1aW50MzJfdCB0ZW1wOworCisgICAgdGVtcFkgPSBvdXRZVVY7CisgICAgdGVtcFUgPSBvdXRZVVYgKyAoaGVpZ2h0X2RzdCAqIHBpdGNoX2RzdCk7CisgICAgdGVtcFYgPSB0ZW1wVSArIDE7CisKKyAgICBqbGltaXQgPSBoZWlnaHRfZHN0OworICAgIGlsaW1pdCA9IHdpZHRoX2RzdDsKKworICAgIGZvcihqPTA7IGo8amxpbWl0OyBqKz0xKQorICAgIHsKKyAgICAgICAgZm9yIChpPTA7IGk8aWxpbWl0OyBpKz0yKQorICAgICAgICB7CisgICAgICAgICAgICBpbnQzMl90ICAgR19kcyA9IDAsIEJfZHMgPSAwLCBSX2RzID0gMDsKKyAgICAgICAgICAgIHVpbnQ4X3QgICB5MCwgeTEsIHUsIHY7CisKKyAgICAgICAgICAgIHBpeGVscyA9ICBpbnB1dFJHQltpXTsKKyAgICAgICAgICAgIHRlbXAgPSAoQUxQSEEqKHBpeGVscyAmIDB4MDAxRikgKyBCRVRBKihwaXhlbHM+PjExKSApOworICAgICAgICAgICAgeTAgICA9IHlfdGFiWyh0ZW1wPj5TSElGVDEpICsgKChwaXhlbHM+PjMpICYgMHgwMEZDKV07CisKKyAgICAgICAgICAgIEdfZHMgICAgKz0gKHBpeGVscz4+MSkgJiAweDAzRTA7CisgICAgICAgICAgICBCX2RzICAgICs9IChwaXhlbHM8PDUpICYgMHgwM0UwOworICAgICAgICAgICAgUl9kcyAgICArPSAocGl4ZWxzPj42KSAmIDB4MDNFMDsKKworICAgICAgICAgICAgcGl4ZWxzID0gIGlucHV0UkdCW2krMV07CisgICAgICAgICAgICB0ZW1wID0gKEFMUEhBKihwaXhlbHMgJiAweDAwMUYpICsgQkVUQSoocGl4ZWxzPj4xMSkgKTsKKyAgICAgICAgICAgIHkxICAgPSB5X3RhYlsodGVtcD4+U0hJRlQxKSArICgocGl4ZWxzPj4zKSAmIDB4MDBGQyldOworCisgICAgICAgICAgICBHX2RzICAgICs9IChwaXhlbHM+PjEpICYgMHgwM0UwOworICAgICAgICAgICAgQl9kcyAgICArPSAocGl4ZWxzPDw1KSAmIDB4MDNFMDsKKyAgICAgICAgICAgIFJfZHMgICAgKz0gKHBpeGVscz4+NikgJiAweDAzRTA7CisKKyAgICAgICAgICAgIFJfZHMgPj49IDE7CisgICAgICAgICAgICBCX2RzID4+PSAxOworICAgICAgICAgICAgR19kcyA+Pj0gMTsKKworICAgICAgICAgICAgdG1wID0gUl9kcyAtIEJfZHM7CisKKyAgICAgICAgICAgIHUgPSBjYl90YWJbKCgoUl9kcy1HX2RzKTw8U0hJRlQyKSArIERFTFRBKnRtcCk+PihTSElGVDIrMildOworICAgICAgICAgICAgdiA9IGNyX3RhYlsoKChCX2RzLUdfZHMpPDxTSElGVDIpIC0gR0FNTUEqdG1wKT4+KFNISUZUMisyKV07CisKKyAgICAgICAgICAgIHRlbXBZWzBdID0geTA7CisgICAgICAgICAgICB0ZW1wWVsxXSA9IHkxOworICAgICAgICAgICAgdGVtcFVbMF0gPSB1OworICAgICAgICAgICAgdGVtcFZbMF0gPSB2OworCisgICAgICAgICAgICB0ZW1wWSArPSAyOworICAgICAgICAgICAgdGVtcFUgKz0gMjsKKyAgICAgICAgICAgIHRlbXBWICs9IDI7CisgICAgICAgIH0KKworICAgICAgICBpbnB1dFJHQiArPSBwaXRjaF9zcmM7CisgICAgfQorCisgICAgcmV0dXJuIDE7Cit9CisKKyNkZWZpbmUgbWluKGEsYikgKChhKTwoYik/KGEpOihiKSkKKyNkZWZpbmUgbWF4KGEsYikgKChhKT4oYik/KGEpOihiKSkKKworc3RhdGljIHZvaWQgY29udmVydF9yZ2IxNl90b195dXY0MjIodWludDhfdCAqcmdiLCB1aW50OF90ICp5dXYsIGludCB3aWR0aCwgaW50IGhlaWdodCkKK3sKKyAgICBpZiAoIXRhYmxlc19pbml0aWFsaXplZCkgeworICAgICAgICBpbml0WXRhYigpOworICAgICAgICBpbml0Q3J0YWIoKTsKKyAgICAgICAgaW5pdENidGFiKCk7CisgICAgICAgIHRhYmxlc19pbml0aWFsaXplZCA9IDE7CisgICAgfQorCisgICAgdWludDMyX3QgcGFyYW1bNl07CisgICAgcGFyYW1bMF0gPSAodWludDMyX3QpIHdpZHRoOworICAgIHBhcmFtWzFdID0gKHVpbnQzMl90KSBoZWlnaHQ7CisgICAgcGFyYW1bMl0gPSAodWludDMyX3QpIHdpZHRoOworICAgIHBhcmFtWzNdID0gKHVpbnQzMl90KSBoZWlnaHQ7CisgICAgcGFyYW1bNF0gPSAodWludDMyX3QpIHdpZHRoOworICAgIHBhcmFtWzVdID0gKHVpbnQzMl90KSAwOworCisgICAgdWludDhfdCAqdGFibGVbM107CisgICAgdGFibGVbMF0gPSBnWVRhYmxlOworICAgIHRhYmxlWzFdID0gZ0NiVGFibGUgKyAzODQ7CisgICAgdGFibGVbMl0gPSBnQ3JUYWJsZSArIDM4NDsKKworICAgIGNjcmdiMTZ0b3l1dl93b19jb2xvcmtleShyZ2IsIHl1diwgcGFyYW0sIHRhYmxlKTsKK30KKworY29uc3QgaW50IEZha2VDYW1lcmE6OmtSZWQ7Citjb25zdCBpbnQgRmFrZUNhbWVyYTo6a0dyZWVuOworY29uc3QgaW50IEZha2VDYW1lcmE6OmtCbHVlOworCitGYWtlQ2FtZXJhOjpGYWtlQ2FtZXJhKGludCB3aWR0aCwgaW50IGhlaWdodCkKKyAgICAgICAgICA6IG1UbXBSZ2IxNkJ1ZmZlcigwKQoreworICAgIHNldFNpemUod2lkdGgsIGhlaWdodCk7Cit9CisKK0Zha2VDYW1lcmE6On5GYWtlQ2FtZXJhKCkKK3sKKyAgICBkZWxldGVbXSBtVG1wUmdiMTZCdWZmZXI7Cit9CisKK3ZvaWQgRmFrZUNhbWVyYTo6c2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpCit7CisgICAgbVdpZHRoID0gd2lkdGg7CisgICAgbUhlaWdodCA9IGhlaWdodDsKKyAgICBtQ291bnRlciA9IDA7CisgICAgbUNoZWNrWCA9IDA7CisgICAgbUNoZWNrWSA9IDA7CisKKyAgICAvLyBUaGlzIHdpbGwgY2F1c2UgaXQgdG8gYmUgcmVhbGxvY2F0ZWQgb24gdGhlIG5leHQgY2FsbAorICAgIC8vIHRvIGdldE5leHRGcmFtZUFzWXV2NDIyKCkuCisgICAgZGVsZXRlW10gbVRtcFJnYjE2QnVmZmVyOworICAgIG1UbXBSZ2IxNkJ1ZmZlciA9IDA7Cit9CisKK3ZvaWQgRmFrZUNhbWVyYTo6Z2V0TmV4dEZyYW1lQXNSZ2I1NjUodWludDE2X3QgKmJ1ZmZlcikKK3sKKyAgICBpbnQgc2l6ZSA9IG1XaWR0aCAvIDEwOworCisgICAgZHJhd0NoZWNrZXJib2FyZChidWZmZXIsIHNpemUpOworCisgICAgaW50IHggPSAoKG1Db3VudGVyKjMpJjI1NSk7CisgICAgaWYoeD4xMjgpIHggPSAyNTUgLSB4OworICAgIGludCB5ID0gKChtQ291bnRlcio1KSYyNTUpOworICAgIGlmKHk+MTI4KSB5ID0gMjU1IC0geTsKKworICAgIGRyYXdTcXVhcmUoYnVmZmVyLCB4KnNpemUvMzIsIHkqc2l6ZS8zMiwgKHNpemUqNSk+PjEsIChtQ291bnRlciYweDEwMCk/a1JlZDprR3JlZW4sIGtCbHVlKTsKKworICAgIG1Db3VudGVyKys7Cit9CisKK3ZvaWQgRmFrZUNhbWVyYTo6Z2V0TmV4dEZyYW1lQXNZdXY0MjIodWludDhfdCAqYnVmZmVyKQoreworICAgIGlmIChtVG1wUmdiMTZCdWZmZXIgPT0gMCkKKyAgICAgICAgbVRtcFJnYjE2QnVmZmVyID0gbmV3IHVpbnQxNl90W21XaWR0aCAqIG1IZWlnaHRdOworCisgICAgZ2V0TmV4dEZyYW1lQXNSZ2I1NjUobVRtcFJnYjE2QnVmZmVyKTsKKyAgICBjb252ZXJ0X3JnYjE2X3RvX3l1djQyMigodWludDhfdCopbVRtcFJnYjE2QnVmZmVyLCBidWZmZXIsIG1XaWR0aCwgbUhlaWdodCk7Cit9CisKK3ZvaWQgRmFrZUNhbWVyYTo6ZHJhd1NxdWFyZSh1aW50MTZfdCAqZHN0LCBpbnQgeCwgaW50IHksIGludCBzaXplLCBpbnQgY29sb3IsIGludCBzaGFkb3cpCit7CisgICAgaW50IHNxdWFyZV94c3RvcCwgc3F1YXJlX3lzdG9wLCBzaGFkb3dfeHN0b3AsIHNoYWRvd195c3RvcDsKKworICAgIHNxdWFyZV94c3RvcCA9IG1pbihtV2lkdGgsIHgrc2l6ZSk7CisgICAgc3F1YXJlX3lzdG9wID0gbWluKG1IZWlnaHQsIHkrc2l6ZSk7CisgICAgc2hhZG93X3hzdG9wID0gbWluKG1XaWR0aCwgeCtzaXplKyhzaXplLzQpKTsKKyAgICBzaGFkb3dfeXN0b3AgPSBtaW4obUhlaWdodCwgeStzaXplKyhzaXplLzQpKTsKKworICAgIC8vIERvIHRoZSBzaGFkb3cuCisgICAgdWludDE2X3QgKnNoID0gJmRzdFsoeSsoc2l6ZS80KSkqbVdpZHRoXTsKKyAgICBmb3IgKGludCBqID0geSArIChzaXplLzQpOyBqIDwgc2hhZG93X3lzdG9wOyBqKyspIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IHggKyAoc2l6ZS80KTsgaSA8IHNoYWRvd194c3RvcDsgaSsrKSB7CisgICAgICAgICAgICBzaFtpXSAmPSBzaGFkb3c7CisgICAgICAgIH0KKyAgICAgICAgc2ggKz0gbVdpZHRoOworICAgIH0KKworICAgIC8vIERyYXcgdGhlIHNxdWFyZS4KKyAgICB1aW50MTZfdCAqc3EgPSAmZHN0W3kqbVdpZHRoXTsKKyAgICBmb3IgKGludCBqID0geTsgaiA8IHNxdWFyZV95c3RvcDsgaisrKSB7CisgICAgICAgIGZvciAoaW50IGkgPSB4OyBpIDwgc3F1YXJlX3hzdG9wOyBpKyspIHsKKyAgICAgICAgICAgIHNxW2ldID0gY29sb3I7CisgICAgICAgIH0KKyAgICAgICAgc3EgKz0gbVdpZHRoOworICAgIH0KK30KKwordm9pZCBGYWtlQ2FtZXJhOjpkcmF3Q2hlY2tlcmJvYXJkKHVpbnQxNl90ICpkc3QsIGludCBzaXplKQoreworICAgIGJvb2wgYmxhY2sgPSB0cnVlOworCisgICAgaWYoKG1DaGVja1gvc2l6ZSkmMSkKKyAgICAgICAgYmxhY2sgPSBmYWxzZTsKKyAgICBpZigobUNoZWNrWS9zaXplKSYxKQorICAgICAgICBibGFjayA9ICFibGFjazsKKworICAgIGludCBjb3VudHkgPSBtQ2hlY2tZJXNpemU7CisgICAgaW50IGNoZWNreHJlbWFpbmRlciA9IG1DaGVja1glc2l6ZTsKKworICAgIGZvcihpbnQgeT0wO3k8bUhlaWdodDt5KyspIHsKKyAgICAgICAgaW50IGNvdW50eCA9IGNoZWNreHJlbWFpbmRlcjsKKyAgICAgICAgYm9vbCBjdXJyZW50ID0gYmxhY2s7CisgICAgICAgIGZvcihpbnQgeD0wO3g8bVdpZHRoO3grKykgeworICAgICAgICAgICAgZHN0W3kqbVdpZHRoK3hdID0gY3VycmVudD8wOjB4ZmZmZjsKKyAgICAgICAgICAgIGlmKGNvdW50eCsrID49IHNpemUpIHsKKyAgICAgICAgICAgICAgICBjb3VudHg9MDsKKyAgICAgICAgICAgICAgICBjdXJyZW50ID0gIWN1cnJlbnQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYoY291bnR5KysgPj0gc2l6ZSkgeworICAgICAgICAgICAgY291bnR5PTA7CisgICAgICAgICAgICBibGFjayA9ICFibGFjazsKKyAgICAgICAgfQorICAgIH0KKyAgICBtQ2hlY2tYICs9IDM7CisgICAgbUNoZWNrWSsrOworfQorCisKK3N0YXR1c190IEZha2VDYW1lcmE6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGNvbnN0IHNpemVfdCBTSVpFID0gMjU2OworICAgIGNoYXIgYnVmZmVyW1NJWkVdOworICAgIFN0cmluZzggcmVzdWx0OworICAgIHNucHJpbnRmKGJ1ZmZlciwgMjU1LCAiIHdpZHRoIHggaGVpZ2h0ICglZCB4ICVkKSwgY291bnRlciAoJWQpLCBjaGVjayB4LXkgY29vcmRpbmF0ZSglZCwgJWQpXG4iLCBtV2lkdGgsIG1IZWlnaHQsIG1Db3VudGVyLCBtQ2hlY2tYLCBtQ2hlY2tZKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgOjp3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0Zha2VDYW1lcmEuaCBiL2NhbWVyYS9saWJjYW1lcmFzZXJ2aWNlL0Zha2VDYW1lcmEuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2M5OTRjCi0tLSAvZGV2L251bGwKKysrIGIvY2FtZXJhL2xpYmNhbWVyYXNlcnZpY2UvRmFrZUNhbWVyYS5oCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisqKgorKiogQ29weXJpZ2h0IDIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2lmbmRlZiBBTkRST0lEX0hBUkRXQVJFX0ZBS0VDQU1FUkFfSAorI2RlZmluZSBBTkRST0lEX0hBUkRXQVJFX0ZBS0VDQU1FUkFfSAorCisjaW5jbHVkZSA8dWkvQ2FtZXJhSGFyZHdhcmVJbnRlcmZhY2UuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBGYWtlQ2FtZXJhIHsKK3B1YmxpYzoKKyAgICBGYWtlQ2FtZXJhKGludCB3aWR0aCwgaW50IGhlaWdodCk7CisgICAgfkZha2VDYW1lcmEoKTsKKworICAgIHZvaWQgc2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpOworICAgIHZvaWQgZ2V0TmV4dEZyYW1lQXNSZ2I1NjUodWludDE2X3QgKmJ1ZmZlcik7CisgICAgdm9pZCBnZXROZXh0RnJhbWVBc1l1djQyMih1aW50OF90ICpidWZmZXIpOworICAgIHN0YXR1c190IGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKworcHJpdmF0ZToKKyAgICB2b2lkIGRyYXdTcXVhcmUodWludDE2X3QgKmJ1ZmZlciwgaW50IHgsIGludCB5LCBpbnQgc2l6ZSwgaW50IGNvbG9yLCBpbnQgc2hhZG93KTsKKyAgICB2b2lkIGRyYXdDaGVja2VyYm9hcmQodWludDE2X3QgKmJ1ZmZlciwgaW50IHNpemUpOworCisgICAgc3RhdGljIGNvbnN0IGludCBrUmVkID0gMHhmODAwOworICAgIHN0YXRpYyBjb25zdCBpbnQga0dyZWVuID0gMHgwN2MwOworICAgIHN0YXRpYyBjb25zdCBpbnQga0JsdWUgPSAweDAwM2U7CisKKyAgICBpbnQgICAgICAgICBtV2lkdGgsIG1IZWlnaHQ7CisgICAgaW50ICAgICAgICAgbUNvdW50ZXI7CisgICAgaW50ICAgICAgICAgbUNoZWNrWCwgbUNoZWNrWTsKKyAgICB1aW50MTZfdCAgICAqbVRtcFJnYjE2QnVmZmVyOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfSEFSRFdBUkVfRkFLRUNBTUVSQV9ICmRpZmYgLS1naXQgYS9jbWRzL3J1bnRpbWUvQW5kcm9pZC5tayBiL2NtZHMvcnVudGltZS9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyMWViMmIKLS0tIC9kZXYvbnVsbAorKysgYi9jbWRzL3J1bnRpbWUvQW5kcm9pZC5tawpAQCAtMCwwICsxLDI5IEBACitpZmVxICgkKFRBUkdFVF9TSU1VTEFUT1IpLHRydWUpCisKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKwlTZXJ2aWNlTWFuYWdlci5jcHAgXAorCVNpZ25hbEhhbmRsZXIuY3BwIFwKKwltYWluX3J1bnRpbWUuY3BwIAorCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJ1dGlscyBcCisJbGliYW5kcm9pZF9ydW50aW1lIFwKKwlsaWJjdXRpbHMgXAorCWxpYnVpIFwKKwlsaWJzeXN0ZW1fc2VydmVyIFwKKwlsaWJoYXJkd2FyZV9sZWdhY3kKKworTE9DQUxfQ19JTkNMVURFUyA6PSBcCisJJChKTklfSF9JTkNMVURFKQorCitpZmVxICgkKFRBUkdFVF9PUyksbGludXgpCisJTE9DQUxfQ0ZMQUdTICs9IC1EWFBfVU5JWAorZW5kaWYKKworTE9DQUxfTU9EVUxFOj0gcnVudGltZQorCitpbmNsdWRlICQoQlVJTERfRVhFQ1VUQUJMRSkKK2VuZGlmCmRpZmYgLS1naXQgYS9jbWRzL3J1bnRpbWUvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMiBiL2NtZHMvcnVudGltZS9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9jbWRzL3J1bnRpbWUvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpkaWZmIC0tZ2l0IGEvY21kcy9ydW50aW1lL05PVElDRSBiL2NtZHMvcnVudGltZS9OT1RJQ0UKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzViMWVmYQotLS0gL2Rldi9udWxsCisrKyBiL2NtZHMvcnVudGltZS9OT1RJQ0UKQEAgLTAsMCArMSwxOTAgQEAKKworICAgQ29weXJpZ2h0IChjKSAyMDA1LTIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0CisgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvCisKKyAgIFRFUk1TIEFORCBDT05ESVRJT05TIEZPUiBVU0UsIFJFUFJPRFVDVElPTiwgQU5EIERJU1RSSUJVVElPTgorCisgICAxLiBEZWZpbml0aW9ucy4KKworICAgICAgIkxpY2Vuc2UiIHNoYWxsIG1lYW4gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwKKyAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgorCisgICAgICAiTGljZW5zb3IiIHNoYWxsIG1lYW4gdGhlIGNvcHlyaWdodCBvd25lciBvciBlbnRpdHkgYXV0aG9yaXplZCBieQorICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgorCisgICAgICAiTGVnYWwgRW50aXR5IiBzaGFsbCBtZWFuIHRoZSB1bmlvbiBvZiB0aGUgYWN0aW5nIGVudGl0eSBhbmQgYWxsCisgICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCisgICAgICBjb250cm9sIHdpdGggdGhhdCBlbnRpdHkuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLAorICAgICAgImNvbnRyb2wiIG1lYW5zIChpKSB0aGUgcG93ZXIsIGRpcmVjdCBvciBpbmRpcmVjdCwgdG8gY2F1c2UgdGhlCisgICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgorICAgICAgb3RoZXJ3aXNlLCBvciAoaWkpIG93bmVyc2hpcCBvZiBmaWZ0eSBwZXJjZW50ICg1MCUpIG9yIG1vcmUgb2YgdGhlCisgICAgICBvdXRzdGFuZGluZyBzaGFyZXMsIG9yIChpaWkpIGJlbmVmaWNpYWwgb3duZXJzaGlwIG9mIHN1Y2ggZW50aXR5LgorCisgICAgICAiWW91IiAob3IgIllvdXIiKSBzaGFsbCBtZWFuIGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBleGVyY2lzaW5nIHBlcm1pc3Npb25zIGdyYW50ZWQgYnkgdGhpcyBMaWNlbnNlLgorCisgICAgICAiU291cmNlIiBmb3JtIHNoYWxsIG1lYW4gdGhlIHByZWZlcnJlZCBmb3JtIGZvciBtYWtpbmcgbW9kaWZpY2F0aW9ucywKKyAgICAgIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gc29mdHdhcmUgc291cmNlIGNvZGUsIGRvY3VtZW50YXRpb24KKyAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCisKKyAgICAgICJPYmplY3QiIGZvcm0gc2hhbGwgbWVhbiBhbnkgZm9ybSByZXN1bHRpbmcgZnJvbSBtZWNoYW5pY2FsCisgICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CisgICAgICBub3QgbGltaXRlZCB0byBjb21waWxlZCBvYmplY3QgY29kZSwgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb24sCisgICAgICBhbmQgY29udmVyc2lvbnMgdG8gb3RoZXIgbWVkaWEgdHlwZXMuCisKKyAgICAgICJXb3JrIiBzaGFsbCBtZWFuIHRoZSB3b3JrIG9mIGF1dGhvcnNoaXAsIHdoZXRoZXIgaW4gU291cmNlIG9yCisgICAgICBPYmplY3QgZm9ybSwgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIExpY2Vuc2UsIGFzIGluZGljYXRlZCBieSBhCisgICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKKyAgICAgIChhbiBleGFtcGxlIGlzIHByb3ZpZGVkIGluIHRoZSBBcHBlbmRpeCBiZWxvdykuCisKKyAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKKyAgICAgIGZvcm0sIHRoYXQgaXMgYmFzZWQgb24gKG9yIGRlcml2ZWQgZnJvbSkgdGhlIFdvcmsgYW5kIGZvciB3aGljaCB0aGUKKyAgICAgIGVkaXRvcmlhbCByZXZpc2lvbnMsIGFubm90YXRpb25zLCBlbGFib3JhdGlvbnMsIG9yIG90aGVyIG1vZGlmaWNhdGlvbnMKKyAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCisgICAgICBvZiB0aGlzIExpY2Vuc2UsIERlcml2YXRpdmUgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29ya3MgdGhhdCByZW1haW4KKyAgICAgIHNlcGFyYWJsZSBmcm9tLCBvciBtZXJlbHkgbGluayAob3IgYmluZCBieSBuYW1lKSB0byB0aGUgaW50ZXJmYWNlcyBvZiwKKyAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCisKKyAgICAgICJDb250cmlidXRpb24iIHNoYWxsIG1lYW4gYW55IHdvcmsgb2YgYXV0aG9yc2hpcCwgaW5jbHVkaW5nCisgICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCisgICAgICB0byB0aGF0IFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCB0aGF0IGlzIGludGVudGlvbmFsbHkKKyAgICAgIHN1Ym1pdHRlZCB0byBMaWNlbnNvciBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIKKyAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgorICAgICAgdGhlIGNvcHlyaWdodCBvd25lci4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sICJzdWJtaXR0ZWQiCisgICAgICBtZWFucyBhbnkgZm9ybSBvZiBlbGVjdHJvbmljLCB2ZXJiYWwsIG9yIHdyaXR0ZW4gY29tbXVuaWNhdGlvbiBzZW50CisgICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bworICAgICAgY29tbXVuaWNhdGlvbiBvbiBlbGVjdHJvbmljIG1haWxpbmcgbGlzdHMsIHNvdXJjZSBjb2RlIGNvbnRyb2wgc3lzdGVtcywKKyAgICAgIGFuZCBpc3N1ZSB0cmFja2luZyBzeXN0ZW1zIHRoYXQgYXJlIG1hbmFnZWQgYnksIG9yIG9uIGJlaGFsZiBvZiwgdGhlCisgICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKKyAgICAgIGV4Y2x1ZGluZyBjb21tdW5pY2F0aW9uIHRoYXQgaXMgY29uc3BpY3VvdXNseSBtYXJrZWQgb3Igb3RoZXJ3aXNlCisgICAgICBkZXNpZ25hdGVkIGluIHdyaXRpbmcgYnkgdGhlIGNvcHlyaWdodCBvd25lciBhcyAiTm90IGEgQ29udHJpYnV0aW9uLiIKKworICAgICAgIkNvbnRyaWJ1dG9yIiBzaGFsbCBtZWFuIExpY2Vuc29yIGFuZCBhbnkgaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKKyAgICAgIG9uIGJlaGFsZiBvZiB3aG9tIGEgQ29udHJpYnV0aW9uIGhhcyBiZWVuIHJlY2VpdmVkIGJ5IExpY2Vuc29yIGFuZAorICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCisKKyAgIDIuIEdyYW50IG9mIENvcHlyaWdodCBMaWNlbnNlLiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAorICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKKyAgICAgIGNvcHlyaWdodCBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBEZXJpdmF0aXZlIFdvcmtzIG9mLAorICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCisgICAgICBXb3JrIGFuZCBzdWNoIERlcml2YXRpdmUgV29ya3MgaW4gU291cmNlIG9yIE9iamVjdCBmb3JtLgorCisgICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKKyAgICAgIHVzZSwgb2ZmZXIgdG8gc2VsbCwgc2VsbCwgaW1wb3J0LCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBXb3JrLAorICAgICAgd2hlcmUgc3VjaCBsaWNlbnNlIGFwcGxpZXMgb25seSB0byB0aG9zZSBwYXRlbnQgY2xhaW1zIGxpY2Vuc2FibGUKKyAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCisgICAgICBDb250cmlidXRpb24ocykgYWxvbmUgb3IgYnkgY29tYmluYXRpb24gb2YgdGhlaXIgQ29udHJpYnV0aW9uKHMpCisgICAgICB3aXRoIHRoZSBXb3JrIHRvIHdoaWNoIHN1Y2ggQ29udHJpYnV0aW9uKHMpIHdhcyBzdWJtaXR0ZWQuIElmIFlvdQorICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKKyAgICAgIGNyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlIFdvcmsKKyAgICAgIG9yIGEgQ29udHJpYnV0aW9uIGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsgY29uc3RpdHV0ZXMgZGlyZWN0CisgICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCisgICAgICBncmFudGVkIHRvIFlvdSB1bmRlciB0aGlzIExpY2Vuc2UgZm9yIHRoYXQgV29yayBzaGFsbCB0ZXJtaW5hdGUKKyAgICAgIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4KKworICAgNC4gUmVkaXN0cmlidXRpb24uIFlvdSBtYXkgcmVwcm9kdWNlIGFuZCBkaXN0cmlidXRlIGNvcGllcyBvZiB0aGUKKyAgICAgIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mIGluIGFueSBtZWRpdW0sIHdpdGggb3Igd2l0aG91dAorICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKKyAgICAgIG1lZXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCisgICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgorICAgICAgICAgIERlcml2YXRpdmUgV29ya3MgYSBjb3B5IG9mIHRoaXMgTGljZW5zZTsgYW5kCisKKyAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKKyAgICAgICAgICBzdGF0aW5nIHRoYXQgWW91IGNoYW5nZWQgdGhlIGZpbGVzOyBhbmQKKworICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCisgICAgICAgICAgdGhhdCBZb3UgZGlzdHJpYnV0ZSwgYWxsIGNvcHlyaWdodCwgcGF0ZW50LCB0cmFkZW1hcmssIGFuZAorICAgICAgICAgIGF0dHJpYnV0aW9uIG5vdGljZXMgZnJvbSB0aGUgU291cmNlIGZvcm0gb2YgdGhlIFdvcmssCisgICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgorICAgICAgICAgIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBhbmQKKworICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCisgICAgICAgICAgZGlzdHJpYnV0aW9uLCB0aGVuIGFueSBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUgbXVzdAorICAgICAgICAgIGluY2x1ZGUgYSByZWFkYWJsZSBjb3B5IG9mIHRoZSBhdHRyaWJ1dGlvbiBub3RpY2VzIGNvbnRhaW5lZAorICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAorICAgICAgICAgIHBlcnRhaW4gdG8gYW55IHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3MsIGluIGF0IGxlYXN0IG9uZQorICAgICAgICAgIG9mIHRoZSBmb2xsb3dpbmcgcGxhY2VzOiB3aXRoaW4gYSBOT1RJQ0UgdGV4dCBmaWxlIGRpc3RyaWJ1dGVkCisgICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgorICAgICAgICAgIGRvY3VtZW50YXRpb24sIGlmIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIERlcml2YXRpdmUgV29ya3M7IG9yLAorICAgICAgICAgIHdpdGhpbiBhIGRpc3BsYXkgZ2VuZXJhdGVkIGJ5IHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpZiBhbmQKKyAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKKyAgICAgICAgICBvZiB0aGUgTk9USUNFIGZpbGUgYXJlIGZvciBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9ubHkgYW5kCisgICAgICAgICAgZG8gbm90IG1vZGlmeSB0aGUgTGljZW5zZS4gWW91IG1heSBhZGQgWW91ciBvd24gYXR0cmlidXRpb24KKyAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQorICAgICAgICAgIG9yIGFzIGFuIGFkZGVuZHVtIHRvIHRoZSBOT1RJQ0UgdGV4dCBmcm9tIHRoZSBXb3JrLCBwcm92aWRlZAorICAgICAgICAgIHRoYXQgc3VjaCBhZGRpdGlvbmFsIGF0dHJpYnV0aW9uIG5vdGljZXMgY2Fubm90IGJlIGNvbnN0cnVlZAorICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KKworICAgICAgWW91IG1heSBhZGQgWW91ciBvd24gY29weXJpZ2h0IHN0YXRlbWVudCB0byBZb3VyIG1vZGlmaWNhdGlvbnMgYW5kCisgICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCisgICAgICBmb3IgdXNlLCByZXByb2R1Y3Rpb24sIG9yIGRpc3RyaWJ1dGlvbiBvZiBZb3VyIG1vZGlmaWNhdGlvbnMsIG9yCisgICAgICBmb3IgYW55IHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBhcyBhIHdob2xlLCBwcm92aWRlZCBZb3VyIHVzZSwKKyAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAorICAgICAgdGhlIGNvbmRpdGlvbnMgc3RhdGVkIGluIHRoaXMgTGljZW5zZS4KKworICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAorICAgICAgYW55IENvbnRyaWJ1dGlvbiBpbnRlbnRpb25hbGx5IHN1Ym1pdHRlZCBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrCisgICAgICBieSBZb3UgdG8gdGhlIExpY2Vuc29yIHNoYWxsIGJlIHVuZGVyIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCisgICAgICBOb3R3aXRoc3RhbmRpbmcgdGhlIGFib3ZlLCBub3RoaW5nIGhlcmVpbiBzaGFsbCBzdXBlcnNlZGUgb3IgbW9kaWZ5CisgICAgICB0aGUgdGVybXMgb2YgYW55IHNlcGFyYXRlIGxpY2Vuc2UgYWdyZWVtZW50IHlvdSBtYXkgaGF2ZSBleGVjdXRlZAorICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgorCisgICA2LiBUcmFkZW1hcmtzLiBUaGlzIExpY2Vuc2UgZG9lcyBub3QgZ3JhbnQgcGVybWlzc2lvbiB0byB1c2UgdGhlIHRyYWRlCisgICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCisgICAgICBleGNlcHQgYXMgcmVxdWlyZWQgZm9yIHJlYXNvbmFibGUgYW5kIGN1c3RvbWFyeSB1c2UgaW4gZGVzY3JpYmluZyB0aGUKKyAgICAgIG9yaWdpbiBvZiB0aGUgV29yayBhbmQgcmVwcm9kdWNpbmcgdGhlIGNvbnRlbnQgb2YgdGhlIE5PVElDRSBmaWxlLgorCisgICA3LiBEaXNjbGFpbWVyIG9mIFdhcnJhbnR5LiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IKKyAgICAgIGFncmVlZCB0byBpbiB3cml0aW5nLCBMaWNlbnNvciBwcm92aWRlcyB0aGUgV29yayAoYW5kIGVhY2gKKyAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yCisgICAgICBpbXBsaWVkLCBpbmNsdWRpbmcsIHdpdGhvdXQgbGltaXRhdGlvbiwgYW55IHdhcnJhbnRpZXMgb3IgY29uZGl0aW9ucworICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQorICAgICAgUEFSVElDVUxBUiBQVVJQT1NFLiBZb3UgYXJlIHNvbGVseSByZXNwb25zaWJsZSBmb3IgZGV0ZXJtaW5pbmcgdGhlCisgICAgICBhcHByb3ByaWF0ZW5lc3Mgb2YgdXNpbmcgb3IgcmVkaXN0cmlidXRpbmcgdGhlIFdvcmsgYW5kIGFzc3VtZSBhbnkKKyAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KKworICAgOC4gTGltaXRhdGlvbiBvZiBMaWFiaWxpdHkuIEluIG5vIGV2ZW50IGFuZCB1bmRlciBubyBsZWdhbCB0aGVvcnksCisgICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKKyAgICAgIHVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyAoc3VjaCBhcyBkZWxpYmVyYXRlIGFuZCBncm9zc2x5CisgICAgICBuZWdsaWdlbnQgYWN0cykgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNoYWxsIGFueSBDb250cmlidXRvciBiZQorICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAorICAgICAgaW5jaWRlbnRhbCwgb3IgY29uc2VxdWVudGlhbCBkYW1hZ2VzIG9mIGFueSBjaGFyYWN0ZXIgYXJpc2luZyBhcyBhCisgICAgICByZXN1bHQgb2YgdGhpcyBMaWNlbnNlIG9yIG91dCBvZiB0aGUgdXNlIG9yIGluYWJpbGl0eSB0byB1c2UgdGhlCisgICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCisgICAgICB3b3JrIHN0b3BwYWdlLCBjb21wdXRlciBmYWlsdXJlIG9yIG1hbGZ1bmN0aW9uLCBvciBhbnkgYW5kIGFsbAorICAgICAgb3RoZXIgY29tbWVyY2lhbCBkYW1hZ2VzIG9yIGxvc3NlcyksIGV2ZW4gaWYgc3VjaCBDb250cmlidXRvcgorICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgorCisgICA5LiBBY2NlcHRpbmcgV2FycmFudHkgb3IgQWRkaXRpb25hbCBMaWFiaWxpdHkuIFdoaWxlIHJlZGlzdHJpYnV0aW5nCisgICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAorICAgICAgYW5kIGNoYXJnZSBhIGZlZSBmb3IsIGFjY2VwdGFuY2Ugb2Ygc3VwcG9ydCwgd2FycmFudHksIGluZGVtbml0eSwKKyAgICAgIG9yIG90aGVyIGxpYWJpbGl0eSBvYmxpZ2F0aW9ucyBhbmQvb3IgcmlnaHRzIGNvbnNpc3RlbnQgd2l0aCB0aGlzCisgICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQorICAgICAgb24gWW91ciBvd24gYmVoYWxmIGFuZCBvbiBZb3VyIHNvbGUgcmVzcG9uc2liaWxpdHksIG5vdCBvbiBiZWhhbGYKKyAgICAgIG9mIGFueSBvdGhlciBDb250cmlidXRvciwgYW5kIG9ubHkgaWYgWW91IGFncmVlIHRvIGluZGVtbmlmeSwKKyAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQorICAgICAgaW5jdXJyZWQgYnksIG9yIGNsYWltcyBhc3NlcnRlZCBhZ2FpbnN0LCBzdWNoIENvbnRyaWJ1dG9yIGJ5IHJlYXNvbgorICAgICAgb2YgeW91ciBhY2NlcHRpbmcgYW55IHN1Y2ggd2FycmFudHkgb3IgYWRkaXRpb25hbCBsaWFiaWxpdHkuCisKKyAgIEVORCBPRiBURVJNUyBBTkQgQ09ORElUSU9OUworCmRpZmYgLS1naXQgYS9jbWRzL3J1bnRpbWUvU2VydmljZU1hbmFnZXIuY3BwIGIvY21kcy9ydW50aW1lL1NlcnZpY2VNYW5hZ2VyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NThhOTVjCi0tLSAvZGV2L251bGwKKysrIGIvY21kcy9ydW50aW1lL1NlcnZpY2VNYW5hZ2VyLmNwcApAQCAtMCwwICsxLDc0IEBACisvLworLy8gQ29weXJpZ2h0IDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorLy8KKworI2RlZmluZSBMT0dfVEFHICJTZXJ2aWNlTWFuYWdlciIKKworI2luY2x1ZGUgIlNlcnZpY2VNYW5hZ2VyLmgiCisjaW5jbHVkZSAiU2lnbmFsSGFuZGxlci5oIgorCisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKyNpbmNsdWRlIDx1dGlscy9QYXJjZWwuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvUHJvY2Vzc1N0YXRlLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3V0aWxzL1N0YXRpYy5oPgorCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitCU2VydmljZU1hbmFnZXI6OkJTZXJ2aWNlTWFuYWdlcigpCit7Cit9CisKK3NwPElCaW5kZXI+IEJTZXJ2aWNlTWFuYWdlcjo6Z2V0U2VydmljZShjb25zdCBTdHJpbmcxNiYgbmFtZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIHNzaXplX3QgaSA9IG1TZXJ2aWNlcy5pbmRleE9mS2V5KG5hbWUpOworICAgIExPR1YoIlNlcnZpY2VNYW5hZ2VyOiBnZXRTZXJ2aWNlKCVzKSAtPiAlZFxuIiwgU3RyaW5nOChuYW1lKS5zdHJpbmcoKSwgaSk7CisgICAgaWYgKGkgPj0gMCkgcmV0dXJuIG1TZXJ2aWNlcy52YWx1ZUF0KGkpOworICAgIHJldHVybiBOVUxMOworfQorCitzcDxJQmluZGVyPiBCU2VydmljZU1hbmFnZXI6OmNoZWNrU2VydmljZShjb25zdCBTdHJpbmcxNiYgbmFtZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIHNzaXplX3QgaSA9IG1TZXJ2aWNlcy5pbmRleE9mS2V5KG5hbWUpOworICAgIExPR1YoIlNlcnZpY2VNYW5hZ2VyOiBnZXRTZXJ2aWNlKCVzKSAtPiAlZFxuIiwgU3RyaW5nOChuYW1lKS5zdHJpbmcoKSwgaSk7CisgICAgaWYgKGkgPj0gMCkgcmV0dXJuIG1TZXJ2aWNlcy52YWx1ZUF0KGkpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0dXNfdCBCU2VydmljZU1hbmFnZXI6OmFkZFNlcnZpY2UoY29uc3QgU3RyaW5nMTYmIG5hbWUsIGNvbnN0IHNwPElCaW5kZXI+JiBzZXJ2aWNlKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgTE9HSSgiU2VydmljZU1hbmFnZXI6IGFkZFNlcnZpY2UoJXMsICVwKVxuIiwgU3RyaW5nOChuYW1lKS5zdHJpbmcoKSwgc2VydmljZS5nZXQoKSk7CisgICAgY29uc3Qgc3NpemVfdCByZXMgPSBtU2VydmljZXMuYWRkKG5hbWUsIHNlcnZpY2UpOworICAgIGlmIChyZXMgPj0gTk9fRVJST1IpIHsKKyAgICAgICAgbUNoYW5nZWQuYnJvYWRjYXN0KCk7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworVmVjdG9yPFN0cmluZzE2PiBCU2VydmljZU1hbmFnZXI6Omxpc3RTZXJ2aWNlcygpCit7CisgICAgVmVjdG9yPFN0cmluZzE2PiByZXM7CisKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIGNvbnN0IHNpemVfdCBOID0gbVNlcnZpY2VzLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgIHJlcy5hZGQobVNlcnZpY2VzLmtleUF0KGkpKTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvY21kcy9ydW50aW1lL1NlcnZpY2VNYW5hZ2VyLmggYi9jbWRzL3J1bnRpbWUvU2VydmljZU1hbmFnZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDljZWM4Ci0tLSAvZGV2L251bGwKKysrIGIvY21kcy9ydW50aW1lL1NlcnZpY2VNYW5hZ2VyLmgKQEAgLTAsMCArMSwzOCBAQAorLy8KKy8vIENvcHlyaWdodCAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKy8vCisjaWZuZGVmIEFORFJPSURfU0VSVklDRV9NQU5BR0VSX0gKKyNkZWZpbmUgQU5EUk9JRF9TRVJWSUNFX01BTkFHRVJfSAorCisjaW5jbHVkZSA8dXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCU2VydmljZU1hbmFnZXIgOiBwdWJsaWMgQm5TZXJ2aWNlTWFuYWdlcgoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCU2VydmljZU1hbmFnZXIoKTsKKyAgICAKKyAgICB2aXJ0dWFsIHNwPElCaW5kZXI+ICAgICAgICAgZ2V0U2VydmljZSggY29uc3QgU3RyaW5nMTYmIG5hbWUpIGNvbnN0OworICAgIHZpcnR1YWwgc3A8SUJpbmRlcj4gICAgICAgICBjaGVja1NlcnZpY2UoIGNvbnN0IFN0cmluZzE2JiBuYW1lKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICAgICAgYWRkU2VydmljZSggY29uc3QgU3RyaW5nMTYmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBzZXJ2aWNlKTsKKyAgICB2aXJ0dWFsIFZlY3RvcjxTdHJpbmcxNj4gICAgbGlzdFNlcnZpY2VzKCk7CisKKyAgICAKK3ByaXZhdGU6CisgICAgbXV0YWJsZSBNdXRleCAgICAgICAgICAgICAgIG1Mb2NrOworICAgIG11dGFibGUgQ29uZGl0aW9uICAgICAgICAgICBtQ2hhbmdlZDsKKyAgICBzcDxJUGVybWlzc2lvbkNvbnRyb2xsZXI+ICAgbVBlcm1pc3Npb25Db250cm9sbGVyOworICAgIEtleWVkVmVjdG9yPFN0cmluZzE2LCBzcDxJQmluZGVyPiA+IG1TZXJ2aWNlczsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfU0VSVklDRV9NQU5BR0VSX0gKZGlmZiAtLWdpdCBhL2NtZHMvcnVudGltZS9TaWduYWxIYW5kbGVyLmNwcCBiL2NtZHMvcnVudGltZS9TaWduYWxIYW5kbGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jY2NhYWJmCi0tLSAvZGV2L251bGwKKysrIGIvY21kcy9ydW50aW1lL1NpZ25hbEhhbmRsZXIuY3BwCkBAIC0wLDAgKzEsMjQ5IEBACisvLworLy8gQ29weXJpZ2h0IDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorLy8KKworI2RlZmluZSBMT0dfVEFHICJTaWduYWxIYW5kbGVyIgorCisjaW5jbHVkZSAiU2lnbmFsSGFuZGxlci5oIgorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3lzL3dhaXQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBTaWduYWxIYW5kbGVyOjpQcm9jZXNzVGhyZWFkIDogcHVibGljIFRocmVhZAoreworcHVibGljOgorICAgIFByb2Nlc3NUaHJlYWQoU2lnbmFsSGFuZGxlciYgc2gpCisgICAgICAgIDogVGhyZWFkKGZhbHNlKQorICAgICAgICAsIG1Pd25lcihzaCkKKyAgICB7CisgICAgfQorCisgICAgdmlydHVhbCBib29sIHRocmVhZExvb3AoKQorICAgIHsKKyAgICAgICAgY2hhciBidWZmZXJbMzJdOworICAgICAgICByZWFkKG1Pd25lci5tQXZhaWxNc2dbMF0sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworCisgICAgICAgIExPR1YoIlNpZ25hbCBjb21tYW5kIHByb2Nlc3NpbmcgdGhyZWFkIHdva2UgdXAhIik7CisKKyAgICAgICAgaWYgKG1Pd25lci5tTG9zdENvbW1hbmRzKSB7CisgICAgICAgICAgICBMT0dFKCJMb3N0ICVkIHNpZ25hbHMhIiwgbU93bmVyLm1Mb3N0Q29tbWFuZHMpOworICAgICAgICAgICAgbU93bmVyLm1Mb3N0Q29tbWFuZHMgPSAwOworICAgICAgICB9CisKKyAgICAgICAgaW50IGN1cjsKKyAgICAgICAgd2hpbGUgKChjdXI9bU93bmVyLm1Db21tYW5kQm90dG9tKSAhPSBtT3duZXIubUNvbW1hbmRUb3ApIHsKKyAgICAgICAgICAgIGlmIChtT3duZXIubUNvbW1hbmRzW2N1cl0uZmlsbGVkID09IDApIHsKKyAgICAgICAgICAgICAgICBMT0dWKCJDb21tYW5kIGF0ICVkIGlzIG5vdCB5ZXQgZmlsbGVkIiwgY3VyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTE9HVigiUHJvY2Vzc2luZyBjb21tYW5kIGF0ICVkLCB0b3AgaXMgJWQiLAorICAgICAgICAgICAgICAgICBjdXIsIG1Pd25lci5tQ29tbWFuZFRvcCk7CisgICAgICAgICAgICBwcm9jZXNzQ29tbWFuZChtT3duZXIubUNvbW1hbmRzW2N1cl0pOworICAgICAgICAgICAgbU93bmVyLm1Db21tYW5kc1tjdXJdLmZpbGxlZCA9IDA7CisKKyAgICAgICAgICAgIGludCBuZXh0ID0gbU93bmVyLm1Db21tYW5kQm90dG9tKzE7CisgICAgICAgICAgICBpZiAobmV4dCA+PSBDT01NQU5EX1FVRVVFX1NJWkUpIHsKKyAgICAgICAgICAgICAgICBuZXh0ID0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbU93bmVyLm1Db21tYW5kQm90dG9tID0gbmV4dDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHZvaWQgcHJvY2Vzc0NvbW1hbmQoY29uc3QgQ29tbWFuZEVudHJ5JiBlbnRyeSkKKyAgICB7CisgICAgICAgIHN3aXRjaCAoZW50cnkuc2lnbnVtKSB7CisgICAgICAgIGNhc2UgU0lHQ0hMRDogeworICAgICAgICAgICAgbU93bmVyLm1Mb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHNzaXplX3QgaSA9IG1Pd25lci5tQ2hpbGRIYW5kbGVycy5pbmRleE9mS2V5KGVudHJ5LmluZm8uc2lfcGlkKTsKKyAgICAgICAgICAgIENoaWxkSGFuZGxlciBjaDsKKyAgICAgICAgICAgIGlmIChpID49IDApIHsKKyAgICAgICAgICAgICAgICBjaCA9IG1Pd25lci5tQ2hpbGRIYW5kbGVycy52YWx1ZUF0KGkpOworICAgICAgICAgICAgICAgIG1Pd25lci5tQ2hpbGRIYW5kbGVycy5yZW1vdmVJdGVtc0F0KGkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbU93bmVyLm1Mb2NrLnVubG9jaygpOworCisgICAgICAgICAgICBMT0dEKCJTSUdDSExEOiBwaWQ9JWQsIGhhbmRsZSBpbmRleD0lZCIsIGVudHJ5LmluZm8uc2lfcGlkLCBpKTsKKworICAgICAgICAgICAgaWYgKGkgPj0gMCkgeworICAgICAgICAgICAgICAgIGludCByZXMgPSB3YWl0cGlkKGVudHJ5LmluZm8uc2lfcGlkLCBOVUxMLCBXTk9IQU5HKTsKKyAgICAgICAgICAgICAgICBMT0dXX0lGKHJlcyA9PSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIlJlY2VpdmVkIFNJR0NITEQsIGJ1dCBwaWQgJWQgaXMgbm90IHlldCBzdG9wcGVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LmluZm8uc2lfcGlkKTsKKyAgICAgICAgICAgICAgICBpZiAoY2guaGFuZGxlcikgeworICAgICAgICAgICAgICAgICAgICBjaC5oYW5kbGVyKGVudHJ5LmluZm8uc2lfcGlkLCBjaC51c2VyRGF0YSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJVbmhhbmRsZWQgU0lHQ0hMRCBmb3IgcGlkICVkIiwgZW50cnkuaW5mby5zaV9waWQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgU2lnbmFsSGFuZGxlciYgbU93bmVyOworfTsKKworCitNdXRleCBTaWduYWxIYW5kbGVyOjptSW5zdGFuY2VMb2NrOworU2lnbmFsSGFuZGxlciogU2lnbmFsSGFuZGxlcjo6bUluc3RhbmNlID0gTlVMTDsKKworc3RhdHVzX3QgU2lnbmFsSGFuZGxlcjo6c2V0Q2hpbGRIYW5kbGVyKHBpZF90IGNoaWxkUGlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRfY2FsbGJhY2tfdCBoYW5kbGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIHVzZXJEYXRhKQoreworICAgIFNpZ25hbEhhbmRsZXIqIGNvbnN0IHNlbGYgPSBnZXRJbnN0YW5jZSgpOworCisgICAgc2VsZi0+bUxvY2subG9jaygpOworCisgICAgLy8gRmlyc3QgbWFrZSBzdXJlIHRoaXMgY2hpbGQgaGFzbid0IGFscmVhZHkgZXhpdGVkLgorICAgIHBpZF90IHJlcyA9IHdhaXRwaWQoY2hpbGRQaWQsIE5VTEwsIFdOT0hBTkcpOworICAgIGlmIChyZXMgIT0gMCkgeworICAgICAgICBpZiAocmVzIDwgMCkgeworICAgICAgICAgICAgTE9HVygic2V0Q2hpbGRIYW5kbGVyIHdhaXRwaWQgb2YgJWQgZmFpbGVkOiAlZCAoJXMpIiwKKyAgICAgICAgICAgICAgICAgY2hpbGRQaWQsIHJlcywgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR1coInNldENoaWxkSGFuZGxlciB3YWl0cGlkIG9mICVkIHNhaWQgJWQgYWxyZWFkeSBkZWFkIiwKKyAgICAgICAgICAgICAgICAgY2hpbGRQaWQsIHJlcyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBTb21lIGtpbmQgb2YgZXJyb3IuLi4gIGp1c3QgaGFuZGxlIHRoZSBleGl0IG5vdy4KKyAgICAgICAgc2VsZi0+bUxvY2sudW5sb2NrKCk7CisKKyAgICAgICAgaWYgKGhhbmRsZXIpIHsKKyAgICAgICAgICAgIGhhbmRsZXIoY2hpbGRQaWQsIHVzZXJEYXRhKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJldHVybiBhbiBlcnJvciBjb2RlIC0tIDAgbWVhbnMgaXQgYWxyZWFkeSBleGl0ZWQuCisgICAgICAgIHJldHVybiAoc3RhdHVzX3QpcmVzOworICAgIH0KKworICAgIENoaWxkSGFuZGxlciBlbnRyeTsKKyAgICBlbnRyeS5jaGlsZFBpZCA9IGNoaWxkUGlkOworICAgIGVudHJ5LnRhZyA9IHRhZzsKKyAgICBlbnRyeS5oYW5kbGVyID0gaGFuZGxlcjsKKyAgICBlbnRyeS51c2VyRGF0YSA9IHVzZXJEYXRhOworCisgICAgLy8gTm90ZTogdGhpcyByZXBsYWNlcyBhbiBleGlzdGluZyBlbnRyeSBmb3IgdGhpcyBwaWQsIGlmIHRoZXJlIGFscmVhZHkKKyAgICAvLyBpcyBvbmUuICBUaGlzIGlzIHRoZSByZXF1aXJlZCBiZWhhdmlvci4KKyAgICBMT0dEKCJzZXRDaGlsZEhhbmRsZXIgYWRkaW5nIHBpZCAlZCwgdGFnICVkLCBoYW5kbGVyICVwLCBkYXRhICVwIiwKKyAgICAgICAgIGNoaWxkUGlkLCB0YWcsIGhhbmRsZXIsIHVzZXJEYXRhKTsKKyAgICBzZWxmLT5tQ2hpbGRIYW5kbGVycy5hZGQoY2hpbGRQaWQsIGVudHJ5KTsKKworICAgIHNlbGYtPm1Mb2NrLnVubG9jaygpOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIFNpZ25hbEhhbmRsZXI6OmtpbGxBbGxDaGlsZHJlbihpbnQgdGFnKQoreworICAgIFNpZ25hbEhhbmRsZXIqIGNvbnN0IHNlbGYgPSBnZXRJbnN0YW5jZSgpOworCisgICAgQXV0b011dGV4IF9sIChzZWxmLT5tTG9jayk7CisgICAgY29uc3Qgc2l6ZV90IE4gPSBzZWxmLT5tQ2hpbGRIYW5kbGVycy5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPE47IGkrKykgeworICAgICAgICBjb25zdCBDaGlsZEhhbmRsZXImIGNoKHNlbGYtPm1DaGlsZEhhbmRsZXJzLnZhbHVlQXQoaSkpOworICAgICAgICBpZiAodGFnID09IDAgfHwgY2gudGFnID09IHRhZykgeworICAgICAgICAgICAgY29uc3QgcGlkX3QgcGlkID0gY2guY2hpbGRQaWQ7CisgICAgICAgICAgICBMT0dJKCJLaWxsaW5nIGNoaWxkICVkICh0YWcgJWQpXG4iLCBwaWQsIGNoLnRhZyk7CisgICAgICAgICAgICBraWxsKHBpZCwgU0lHS0lMTCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK1NpZ25hbEhhbmRsZXI6OlNpZ25hbEhhbmRsZXIoKQorICAgIDogbUNvbW1hbmRUb3AoMCkKKyAgICAsIG1Db21tYW5kQm90dG9tKDApCisgICAgLCBtTG9zdENvbW1hbmRzKDApCit7CisgICAgbWVtc2V0KG1Db21tYW5kcywgMCwgc2l6ZW9mKG1Db21tYW5kcykpOworCisgICAgaW50IHJlcyA9IHBpcGUobUF2YWlsTXNnKTsKKyAgICBMT0dFX0lGKHJlcyAhPSAwLCAiVW5hYmxlIHRvIGNyZWF0ZSBzaWduYWwgaGFuZGxlciBwaXBlOiAlcyIsIHN0cmVycm9yKGVycm5vKSk7CisKKyAgICBtUHJvY2Vzc1RocmVhZCA9IG5ldyBQcm9jZXNzVGhyZWFkKCp0aGlzKTsKKyAgICBtUHJvY2Vzc1RocmVhZC0+cnVuKCJTaWduYWxIYW5kbGVyIiwgUFJJT1JJVFlfSElHSEVTVCk7CisKKyAgICBzdHJ1Y3Qgc2lnYWN0aW9uIHNhOworICAgIG1lbXNldCgmc2EsIDAsIHNpemVvZihzYSkpOworICAgIHNhLnNhX3NpZ2FjdGlvbiA9IHNpZ0FjdGlvbjsKKyAgICBzYS5zYV9mbGFncyA9IFNBX05PQ0xEU1RPUHxTQV9TSUdJTkZPOworICAgIHNpZ2FjdGlvbihTSUdDSExELCAmc2EsIE5VTEwpOworfQorCitTaWduYWxIYW5kbGVyOjp+U2lnbmFsSGFuZGxlcigpCit7Cit9CisKK1NpZ25hbEhhbmRsZXIqIFNpZ25hbEhhbmRsZXI6OmdldEluc3RhbmNlKCkKK3sKKyAgICBBdXRvTXV0ZXggX2wobUluc3RhbmNlTG9jayk7CisgICAgaWYgKG1JbnN0YW5jZSA9PSBOVUxMKSB7CisgICAgICAgIG1JbnN0YW5jZSA9IG5ldyBTaWduYWxIYW5kbGVyKCk7CisgICAgfQorICAgIHJldHVybiBtSW5zdGFuY2U7Cit9CisKK3ZvaWQgU2lnbmFsSGFuZGxlcjo6c2lnQWN0aW9uKGludCBzaWdudW0sIHNpZ2luZm9fdCogaW5mbywgdm9pZCopCit7CisgICAgc3RhdGljIGNvbnN0IGNoYXIgd2FrZXVwTXNnWzFdID0geyAweGZmIH07CisKKyAgICAvLyBJZiBvdXIgc2lnbmFsIGhhbmRsZXIgaXMgYmVpbmcgY2FsbGVkLCB0aGVuIHdlIGtub3cgd2UgaGF2ZQorICAgIC8vIGFscmVhZHkgaW5pdGlhbGl6ZWQgdGhlIFNpZ25hbEhhbmRsZXIgY2xhc3MgYW5kIHRodXMgbUluc3RhbmNlCisgICAgLy8gaXMgdmFsaWQuCisgICAgU2lnbmFsSGFuZGxlciogY29uc3Qgc2VsZiA9IG1JbnN0YW5jZTsKKworICAgIC8vIFhYWCBUaGlzIGlzIG5vdCBzYWZlIQorICAgICNpZiAwCisgICAgTE9HVigiU2lnbmFsICVkOiBzaWdubz0lZCwgZXJybm89JWQsIGNvZGU9JWQsIHBpZD0lZFxuIiwKKyAgICAgICAgICAgc2lnbnVtLAorICAgICAgICAgICBpbmZvLT5zaV9zaWdubywgaW5mby0+c2lfZXJybm8sIGluZm8tPnNpX2NvZGUsCisgICAgICAgICAgIGluZm8tPnNpX3BpZCk7CisgICAgI2VuZGlmCisKKyAgICBpbnQzMl90IG9sZFRvcCwgbmV3VG9wOworCisgICAgLy8gRmluZCB0aGUgbmV4dCBjb21tYW5kIHNsb3QuLi4KKyAgICBkbyB7CisgICAgICAgIG9sZFRvcCA9IHNlbGYtPm1Db21tYW5kVG9wOworCisgICAgICAgIG5ld1RvcCA9IG9sZFRvcCArIDE7CisgICAgICAgIGlmIChuZXdUb3AgPj0gQ09NTUFORF9RVUVVRV9TSVpFKSB7CisgICAgICAgICAgICBuZXdUb3AgPSAwOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5ld1RvcCA9PSBzZWxmLT5tQ29tbWFuZEJvdHRvbSkgeworICAgICAgICAgICAgLy8gVGhlIGJ1ZmZlciBpcyBmaWxsZWQgdXAhICBPdWNoIQorICAgICAgICAgICAgLy8gWFhYIFRoaXMgaXMgbm90IHNhZmUhCisgICAgICAgICAgICAjaWYgMAorICAgICAgICAgICAgTE9HRSgiQ29tbWFuZCBidWZmZXIgb3ZlcmZsb3chICBuZXdUb3A9JWRcbiIsIG5ld1RvcCk7CisgICAgICAgICAgICAjZW5kaWYKKyAgICAgICAgICAgIGFuZHJvaWRfYXRvbWljX2FkZCgxLCAmc2VsZi0+bUxvc3RDb21tYW5kcyk7CisgICAgICAgICAgICB3cml0ZShzZWxmLT5tQXZhaWxNc2dbMV0sIHdha2V1cE1zZywgc2l6ZW9mKHdha2V1cE1zZykpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfSB3aGlsZShhbmRyb2lkX2F0b21pY19jbXB4Y2hnKG9sZFRvcCwgbmV3VG9wLCAmKHNlbGYtPm1Db21tYW5kVG9wKSkpOworCisgICAgLy8gRmlsbCBpbiB0aGUgY29tbWFuZCBkYXRhLi4uCisgICAgc2VsZi0+bUNvbW1hbmRzW29sZFRvcF0uc2lnbnVtID0gc2lnbnVtOworICAgIHNlbGYtPm1Db21tYW5kc1tvbGRUb3BdLmluZm8gPSAqaW5mbzsKKworICAgIC8vIEFuZCBub3cgbWFrZSB0aGlzIGNvbW1hbmQgYXZhaWxhYmxlLgorICAgIHNlbGYtPm1Db21tYW5kc1tvbGRUb3BdLmZpbGxlZCA9IDE7CisKKyAgICAvLyBXYWtlIHVwIHRoZSBwcm9jZXNzaW5nIHRocmVhZC4KKyAgICB3cml0ZShzZWxmLT5tQXZhaWxNc2dbMV0sIHdha2V1cE1zZywgc2l6ZW9mKHdha2V1cE1zZykpOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9jbWRzL3J1bnRpbWUvU2lnbmFsSGFuZGxlci5oIGIvY21kcy9ydW50aW1lL1NpZ25hbEhhbmRsZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjRlZjhlCi0tLSAvZGV2L251bGwKKysrIGIvY21kcy9ydW50aW1lL1NpZ25hbEhhbmRsZXIuaApAQCAtMCwwICsxLDEzNyBAQAorLy8KKy8vIENvcHlyaWdodCAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKy8vCisjaWZuZGVmIEFORFJPSURfU0lHTkFMX0hBTkRMRVJfSAorI2RlZmluZSBBTkRST0lEX1NJR05BTF9IQU5ETEVSX0gKKworI2luY2x1ZGUgPHV0aWxzL0tleWVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8c2lnbmFsLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitlbnVtIHsKKyAgICBERUZBVUxUX1BST0NFU1NfVEFHID0gMQorfTsKKworY2xhc3MgU2lnbmFsSGFuZGxlcgoreworcHVibGljOgorICAgIHR5cGVkZWYgdm9pZCAoKmNoaWxkX2NhbGxiYWNrX3QpKHBpZF90IGNoaWxkLCB2b2lkKiB1c2VyRGF0YSk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSBoYW5kbGVyIGZvciB3aGVuIGEgY2hpbGQgcHJvY2VzcyBleGl0cy4gIEJ5IGNhbGxpbmcKKyAgICAgKiB0aGlzLCBhIHdhaXRwaWQoKSB3aWxsIGJlIGRvbmUgd2hlbiB0aGUgY2hpbGQgZXhpdHMgdG8gcmVtb3ZlCisgICAgICogaXQgZnJvbSB0aGUgem9tYmllIHN0YXRlLiAgWW91IGNhbiBhbHNvIG9wdGlvbmFsbHkgc3BlY2lmeSBhCisgICAgICogaGFuZGxlciB0byBiZSBjYWxsZWQgd2hlbiB0aGUgY2hpbGQgZXhpdHMuCisgICAgICogCisgICAgICogSWYgdGhlcmUgaXMgYWxyZWFkeSBhIGhhbmRsZXIgZm9yIHRoaXMgY2hpbGQgcHJvY2VzcywgaXQgaXMKKyAgICAgKiByZXBsYWNlZCBieSB0aGlzIG5ldyBoYW5kbGVyLiAgSW4gdGhpcyBjYXNlIHRoZSBvbGQgaGFuZGxlcidzCisgICAgICogZnVuY3Rpb24gaXMgbm90IGNhbGxlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2hpbGRQaWQgUHJvY2VzcyBJRCBvZiBjaGlsZCB0byB3YXRjaC4KKyAgICAgKiBAcGFyYW0gY2hpbGRUYWcgVXNlci1kZWZpbmVkIHRhZyBmb3IgdGhpcyBjaGlsZC4gIE11c3QgYmUKKyAgICAgKiAgICAgICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHplcm8uCisgICAgICogQHBhcmFtIGhhbmRsZXIgSWYgbm9uLU5VTEwsIHRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICBjaGlsZCBleGl0cy4gIEl0IG1heSBiZSBjYWxsZWQgaW4gZWl0aGVyIGEKKyAgICAgKiAgICAgICAgICAgICAgICBzZXBhcmF0ZSBzaWduYWwgaGFuZGxpbmcgdGhyZWFkLCBvcgorICAgICAqICAgICAgICAgICAgICAgIGltbWVkaWF0ZWx5IGlmIHRoZSBjaGlsZCBoYXMgYWxyZWFkeSBleGl0ZWQuCisgICAgICogQHBhcmFtIHVzZXJEYXRhIFByb3BhZ2V0ZWQgYXMtaXMgdG8gaGFuZGxlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHN0YXR1c190IE5PX0VSUk9SIGlmIGFsbCBpcyB3ZWxsLgorICAgICAqLworICAgIHN0YXRpYyBzdGF0dXNfdCAgICAgICAgICAgICBzZXRDaGlsZEhhbmRsZXIocGlkX3QgY2hpbGRQaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hpbGRUYWcgPSBERUZBVUxUX1BST0NFU1NfVEFHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRfY2FsbGJhY2tfdCBoYW5kbGVyID0gTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIHVzZXJEYXRhID0gTlVMTCk7CisKKyAgICAvKioKKyAgICAgKiBLaWxsIGFsbCBvZiB0aGUgY2hpbGQgcHJvY2Vzc2VzIGZvciB3aGljaCB3ZSBoYXZlIGEgd2FpdGluZworICAgICAqIGhhbmRsZXIsIHdob3NlIHRhZyBpcyB0aGUgZ2l2ZW4gdmFsdWUuICBJZiB0YWcgaXMgMCwgYWxsCisgICAgICogY2hpbGRyZW4gYXJlIGtpbGxlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFnCisgICAgICovCisgICAgc3RhdGljIHZvaWQgICAgICAgICAgICAgICAgIGtpbGxBbGxDaGlsZHJlbihpbnQgdGFnID0gMCk7CisKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpZ25hbEhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflNpZ25hbEhhbmRsZXIoKTsKKworICAgIHN0YXRpYyBTaWduYWxIYW5kbGVyKiAgICAgICBnZXRJbnN0YW5jZSgpOworCisgICAgc3RhdGljIHZvaWQgICAgICAgICAgICAgICAgIHNpZ0FjdGlvbihpbnQsIHNpZ2luZm9fdCosIHZvaWQqKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gU2hhcmVkIHN0YXRlLi4uICBhbGwgb2YgdGhpcyBpcyBwcm90ZWN0ZWQgYnkgbUxvY2suCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgIG1Mb2NrOworCisgICAgc3RydWN0IENoaWxkSGFuZGxlcgorICAgIHsKKyAgICAgICAgcGlkX3QgY2hpbGRQaWQ7CisgICAgICAgIGludCB0YWc7CisgICAgICAgIGNoaWxkX2NhbGxiYWNrX3QgaGFuZGxlcjsKKyAgICAgICAgdm9pZCogdXNlckRhdGE7CisgICAgfTsKKyAgICBLZXllZFZlY3RvcjxwaWRfdCwgQ2hpbGRIYW5kbGVyPiAgICBtQ2hpbGRIYW5kbGVyczsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gQ29tbW1hbmQgcXVldWUuLi4gIGRhdGEgaXMgaW5zZXJ0ZWQgYnkgdGhlIHNpZ25hbAorICAgIC8vIGhhbmRsZXIgdXNpbmcgYXRvbWljIG9wcywgYW5kIHJldHJpZXZlZCBieSB0aGUKKyAgICAvLyBzaWduYWwgcHJvY2Vzc2luZyB0aHJlYWQuICBCZWNhdXNlIHRoZXNlIGFyZSB0b3VjaGVkCisgICAgLy8gYnkgdGhlIHNpZ25hbCBoYW5kbGVyLCBubyBsb2NrIGlzIHVzZWQuCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIGVudW0geworICAgICAgICBDT01NQU5EX1FVRVVFX1NJWkUgPSA2NAorICAgIH07CisgICAgc3RydWN0IENvbW1hbmRFbnRyeQorICAgIHsKKyAgICAgICAgaW50IGZpbGxlZDsKKyAgICAgICAgaW50IHNpZ251bTsKKyAgICAgICAgc2lnaW5mb190IGluZm87CisgICAgfTsKKworICAgIC8vIFRoZSB0b3Agb2YgdGhlIHF1ZXVlLiAgVGhpcyBpcyBpbmNyZW1lbnRlZCBhdG9taWNhbGx5IGJ5IHRoZQorICAgIC8vIHNpZ25hbCBoYW5kbGVyIGJlZm9yZSBwbGFjaW5nIGEgY29tbWFuZCBpbiB0aGUgcXVldWUuCisgICAgdm9sYXRpbGUgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgbUNvbW1hbmRUb3A7CisKKyAgICAvLyBUaGUgYm90dG9tIG9mIHRoZSBxdWV1ZS4gIE9ubHkgbW9kaWZpZWQgYnkgdGhlIHByb2Nlc3NpbmcKKyAgICAvLyB0aHJlYWQ7IHRoZSBzaWduYWwgaGFuZGxlciByZWFkcyBpdCBvbmx5IHRvIGRldGVybWluZSBpZiB0aGUKKyAgICAvLyBxdWV1ZSBpcyBmdWxsLgorICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1Db21tYW5kQm90dG9tOworCisgICAgLy8gSW5jcmVtZW50ZWQgZWFjaCB0aW1lIHdlIHJlY2VpdmUgYSBzaWduYWwgYW5kIGRvbid0IGhhdmUgcm9vbQorICAgIC8vIGZvciBpdCBvbiB0aGUgY29tbWFuZCBxdWV1ZS4KKyAgICB2b2xhdGlsZSBpbnQzMl90ICAgICAgICAgICAgICAgICAgICBtTG9zdENvbW1hbmRzOworCisgICAgLy8gVGhlIGNvbW1hbmQgcHJvY2Vzc2luZyB0aHJlYWQuCisgICAgY2xhc3MgUHJvY2Vzc1RocmVhZDsKKyAgICBzcDxUaHJlYWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICBtUHJvY2Vzc1RocmVhZDsKKworICAgIC8vIFBpcGUgdXNlZCB0byB0ZWxsIGNvbW1hbmQgcHJvY2Vzc2luZyB0aHJlYWQgd2hlbiBuZXcgY29tbWFuZHMuCisgICAgLy8gYXJlIGF2YWlsYWJsZS4gIFRoZSB0aHJlYWQgYmxvY2tzIG9uIHRoZSByZWFkIGVuZCwgdGhlIHNpZ25hbAorICAgIC8vIGhhbmRsZXIgd3JpdGVzIHdoZW4gaXQgZW5xdWV1ZXMgbmV3IGNvbW1hbmRzLgorICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1BdmFpbE1zZ1syXTsKKworICAgIC8vIFRoZSBjb21tYW5kcy4KKyAgICBDb21tYW5kRW50cnkgICAgICAgICAgICAgICAgICAgICAgICBtQ29tbWFuZHNbQ09NTUFORF9RVUVVRV9TSVpFXTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gU2luZ2xldG9uLgorICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBzdGF0aWMgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgICBtSW5zdGFuY2VMb2NrOworICAgIHN0YXRpYyBTaWduYWxIYW5kbGVyKiAgICAgICAgICAgICAgIG1JbnN0YW5jZTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfU0lHTkFMX0hBTkRMRVJfSApkaWZmIC0tZ2l0IGEvY21kcy9ydW50aW1lL21haW5fcnVudGltZS5jcHAgYi9jbWRzL3J1bnRpbWUvbWFpbl9ydW50aW1lLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTMxYTllCi0tLSAvZGV2L251bGwKKysrIGIvY21kcy9ydW50aW1lL21haW5fcnVudGltZS5jcHAKQEAgLTAsMCArMSw1MTQgQEAKKy8vCisvLyBDb3B5cmlnaHQgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisvLworLy8gTWFpbiBlbnRyeSBwb2ludCBmb3IgcnVudGltZS4KKy8vCisKKyNpbmNsdWRlICJTZXJ2aWNlTWFuYWdlci5oIgorI2luY2x1ZGUgIlNpZ25hbEhhbmRsZXIuaCIKKworI2luY2x1ZGUgPHV0aWxzLmg+CisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Qcm9jZXNzU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4gIAorI2luY2x1ZGUgPGN1dGlscy96eWdvdGUuaD4KKworI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3V0aWxzL1N0YXRpYy5oPgorCisjaW5jbHVkZSA8dWkvSVN1cmZhY2VDb21wb3Nlci5oPgorCisjaW5jbHVkZSA8YW5kcm9pZF9ydW50aW1lL0FuZHJvaWRSdW50aW1lLmg+CisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8Z2V0b3B0Lmg+CisjaW5jbHVkZSA8c2lnbmFsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGxpbnV4L2NhcGFiaWxpdHkuaD4KKyNpbmNsdWRlIDxsaW51eC9pb2N0bC5oPgorI2lmZGVmIEhBVkVfQU5EUk9JRF9PUworIyBpbmNsdWRlIDxsaW51eC9hbmRyb2lkX2FsYXJtLmg+CisjZW5kaWYKKworI3VuZGVmIExPR19UQUcKKyNkZWZpbmUgTE9HX1RBRyAicnVudGltZSIKKworc3RhdGljIGNvbnN0IGNoYXIqIFpZR09URV9BUkdWW10gPSB7IAorICAgICItLXNldHVpZD0xMDAwIiwKKyAgICAiLS1zZXRnaWQ9MTAwMCIsCisgICAgIi0tc2V0Z3JvdXBzPTEwMDEsMTAwMiwxMDAzLDEwMDQsMTAwNSwxMDA2LDEwMDcsMTAwOCwxMDA5LDEwMTAsMzAwMSwzMDAyLDMwMDMiLAorICAgIC8qIENBUF9TWVNfVFRZX0NPTkZJRyAmIENBUF9TWVNfUkVTT1VSQ0UgJiBDQVBfTkVUX0JST0FEQ0FTVCAmCisgICAgICogQ0FQX05FVF9BRE1JTiAmIENBUF9ORVRfUkFXICYgQ0FQX05FVF9CSU5EX1NFUlZJQ0UgICYgQ0FQX0tJTEwgJgorICAgICAqIENBUF9TWVNfQk9PVAorICAgICAqLworICAgICItLWNhcGFiaWxpdGllcz04ODE2MTMxMiw4ODE2MTMxMiIsCisgICAgIi0tcnVudGltZS1pbml0IiwKKyAgICAiLS1uaWNlLW5hbWU9c3lzdGVtX3NlcnZlciIsCisgICAgImNvbS5hbmRyb2lkLnNlcnZlci5TeXN0ZW1TZXJ2ZXIiCit9OworCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworZXh0ZXJuICJDIiBzdGF0dXNfdCBzeXN0ZW1faW5pdCgpOworCitlbnVtIHsKKyAgICBTWVNURU1fUFJPQ0VTU19UQUcgPSBERUZBVUxUX1BST0NFU1NfVEFHKzEKK307CisKK2V4dGVybiBNdXRleCBnRXZlbnRRTXV0ZXg7CitleHRlcm4gQ29uZGl0aW9uIGdFdmVudFFDb25kaXRpb247CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworZXh0ZXJuIHN0YXR1c190IGFwcF9pbml0KGNvbnN0IGNoYXIqIGNsYXNzTmFtZSk7CitleHRlcm4gdm9pZCBzZXRfZmluaXNoX2luaXRfZnVuYyh2b2lkICgqZnVuYykoKSk7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8ga2lsbCB0aGlzIHByb2Nlc3MgKHJ1bnRpbWUpIHdoZW4gdGhlIHN5c3RlbV9zZXJ2ZXIgZGllcy4KKyAqLworY2xhc3MgR3JpbVJlYXBlciA6IHB1YmxpYyBJQmluZGVyOjpEZWF0aFJlY2lwaWVudCB7CitwdWJsaWM6IAorICAgIEdyaW1SZWFwZXIoKSB7IH0KKworICAgIHZpcnR1YWwgdm9pZCBiaW5kZXJEaWVkKGNvbnN0IHdwPElCaW5kZXI+JiB3aG8pCisgICAgeworICAgICAgICBMT0dJKCJHcmltIFJlYXBlciBraWxsaW5nIHJ1bnRpbWUuLi4iKTsKKyAgICAgICAga2lsbChnZXRwaWQoKSwgU0lHS0lMTCk7CisgICAgfQorfTsKKworZXh0ZXJuIHZvaWQgUXVpY2tUZXN0cygpOworCisvKgorICogUHJpbnQgdXNhZ2UgaW5mby4KKyAqLworc3RhdGljIHZvaWQgdXNhZ2UoY29uc3QgY2hhciogYXJndjApCit7CisgICAgZnByaW50ZihzdGRlcnIsCisgICAgICAgICJVc2FnZTogcnVudGltZSBbLWcgZ2FtbWFdIFstbCBsb2dmaWxlXSBbLW5dIFstc11cbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgIFstaiBhcHAtY29tcG9uZW50XSBbLXYgYXBwLXZlcmJdIFstZCBhcHAtZGF0YV1cbiIKKyAgICAgICAgIlxuIgorICAgICAgICAiLWw6IEZpbGUgdG8gc2VuZCBsb2cgbWVzc2FnZXMgdG9cbiIKKyAgICAgICAgIi1uOiBEb24ndCBwcmludCB0byBzdGRvdXQvc3RkZXJyXG4iCisgICAgICAgICItczogRm9yY2Ugc2luZ2xlLXByb2Nlc3MgbW9kZVxuIgorICAgICAgICAiLWo6IEN1c3RvbSBob21lIGFwcCBjb21wb25lbnQgbmFtZVxuIgorICAgICAgICAiLXY6IEN1c3RvbSBob21lIGFwcCBpbnRlbnQgdmVyYlxuIgorICAgICAgICAiLWQ6IEN1c3RvbSBob21lIGFwcCBpbnRlbnQgZGF0YVxuIgorICAgICk7CisgICAgZXhpdCgxKTsKK30KKworLy8gU2VsZWN0ZWQgYXBwbGljYXRpb24gdG8gcnVuLgorc3RhdGljIGNvbnN0IGNoYXIqIGdJbml0aWFsQXBwbGljYXRpb24gPSBOVUxMOworc3RhdGljIGNvbnN0IGNoYXIqIGdJbml0aWFsVmVyYiA9IE5VTEw7CitzdGF0aWMgY29uc3QgY2hhciogZ0luaXRpYWxEYXRhID0gTlVMTDsKKworc3RhdGljIHZvaWQgd3JpdGVTdHJpbmdUb1BhcmNlbChQYXJjZWwmIHBhcmNlbCwgY29uc3QgY2hhciogc3RyKQoreworICAgIGlmIChzdHIpIHsKKyAgICAgICAgcGFyY2VsLndyaXRlU3RyaW5nMTYoU3RyaW5nMTYoc3RyKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcGFyY2VsLndyaXRlU3RyaW5nMTYoTlVMTCwgMCk7CisgICAgfQorfQorCisvKgorICogU3RhcnRpbmcgcG9pbnQgZm9yIHByb2dyYW0gbG9naWMuCisgKgorICogUmV0dXJucyB3aXRoIGFuIGV4aXQgc3RhdHVzIGNvZGUgKDAgb24gc3VjY2Vzcywgbm9uemVybyBvbiBlcnJvcikuCisgKi8KK3N0YXRpYyBpbnQgcnVuKHNwPFByb2Nlc3NTdGF0ZT4mIHByb2MpCit7CisgICAgLy8gVGVtcG9yYXJ5IGhhY2sgdG8gY2FsbCBzdGFydFJ1bm5pbmcoKSBvbiB0aGUgYWN0aXZpdHkgbWFuYWdlci4KKyAgICBzcDxJU2VydmljZU1hbmFnZXI+IHNtID0gZGVmYXVsdFNlcnZpY2VNYW5hZ2VyKCk7CisgICAgc3A8SUJpbmRlcj4gYW07CisgICAgd2hpbGUgKChhbSA9IHNtLT5nZXRTZXJ2aWNlKFN0cmluZzE2KCJhY3Rpdml0eSIpKSkgPT0gTlVMTCkgeworICAgICAgICBMT0dJKCJXYWl0aW5nIGZvciBhY3Rpdml0eSBtYW5hZ2VyLi4uIik7CisgICAgfQorICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAvLyBYWFggTmVlZCB0byBhbHNvIHN1cHBseSBhIHBhY2thZ2UgbmFtZSBmb3IgdGhpcyB0byB3b3JrIGFnYWluLgorICAgIC8vIElBY3Rpdml0eU1hbmFnZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSBpcyB0aGUgdG9rZW4gZm9yIGludm9raW5nIG9uIHRoaXMgaW50ZXJmYWNlOworICAgIC8vIGhhcmRjb2RpbmcgaXQgaGVyZSBhdm9pZHMgaGF2aW5nIHRvIGxpbmsgd2l0aCB0aGUgZnVsbCBBY3Rpdml0eSBNYW5hZ2VyIGxpYnJhcnkKKyAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oU3RyaW5nMTYoImFuZHJvaWQuYXBwLklBY3Rpdml0eU1hbmFnZXIiKSk7CisgICAgd3JpdGVTdHJpbmdUb1BhcmNlbChkYXRhLCBOVUxMKTsKKyAgICB3cml0ZVN0cmluZ1RvUGFyY2VsKGRhdGEsIGdJbml0aWFsQXBwbGljYXRpb24pOworICAgIHdyaXRlU3RyaW5nVG9QYXJjZWwoZGF0YSwgZ0luaXRpYWxWZXJiKTsKKyAgICB3cml0ZVN0cmluZ1RvUGFyY2VsKGRhdGEsIGdJbml0aWFsRGF0YSk7CitMT0dJKCJydW4oKSBzZW5kaW5nIEZJUlNUX0NBTExfVFJBTlNBQ1RJT04gdG8gYWN0aXZpdHkgbWFuYWdlciIpOworICAgIGFtLT50cmFuc2FjdChJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworCisgICAgaWYgKHByb2MtPnN1cHBvcnRzUHJvY2Vzc2VzKCkpIHsKKyAgICAgICAgLy8gTm93IHdlIGxpbmsgdG8gdGhlIEFjdGl2aXR5IE1hbmFnZXIgd2FpdGluZyBmb3IgaXQgdG8gZGllLiBJZiBpdCBkb2VzIGtpbGwgb3Vyc2VsZi4KKyAgICAgICAgLy8gaW5pdGQgd2lsbCByZXN0YXJ0IHRoaXMgcHJvY2VzcyBhbmQgYnJpbmcgdGhlIHN5c3RlbSBiYWNrIHVwLgorICAgICAgICBzcDxHcmltUmVhcGVyPiBncmltID0gbmV3IEdyaW1SZWFwZXIoKTsKKyAgICAgICAgYW0tPmxpbmtUb0RlYXRoKGdyaW0sIGdyaW0uZ2V0KCksIDApOworCisgICAgICAgIC8vIE5vdyBqb2luIHRoZSB0aHJlYWQgcG9vbC4gTm90ZSB0aGlzIGlzIG5lZWRlZCBzbyB0aGF0IHRoZSBtZXNzYWdlIGVucXVldWVkIGluIHRoZSBkcml2ZXIKKyAgICAgICAgLy8gZm9yIHRoZSBsaW5rVG9EZWF0aCBnZXRzIHByb2Nlc3NlZC4KKyAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+am9pblRocmVhZFBvb2woKTsKKyAgICB9IGVsc2UgeworICAgICAgICAvLyBLZWVwIHRoaXMgdGhyZWFkIHJ1bm5pbmcgZm9yZXZlci4uLgorICAgICAgICB3aGlsZSAoMSkgeworICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKKworfTsgIC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKworLyoKKyAqIFBvc3Qtc3lzdGVtLXByb2Nlc3MgaW5pdGlhbGl6YXRpb24uCisgKiAKKyAqIFRoaXMgZnVuY3Rpb24gY29udGludWVzIGluaXRpYWxpemF0aW9uIGFmdGVyIHRoZSBzeXN0ZW0gcHJvY2VzcworICogaGFzIGJlZW4gaW5pdGlhbGl6ZWQuICBJdCBuZWVkcyB0byBiZSBzZXBhcmF0ZSBiZWNhdXNlIHRoZSBzeXN0ZW0KKyAqIGluaXRpYWxpemF0aW9uIG5lZWRzIHRvIGNhcmUgb2Ygc3RhcnRpbmcgdGhlIEFuZHJvaWQgcnVudGltZSBpZiBpdCBpcyBub3QKKyAqIHJ1bm5pbmcgaW4gaXRzIG93biBwcm9jZXNzLCB3aGljaCBkb2Vzbid0IHJldHVybiB1bnRpbCB0aGUgcnVudGltZSBpcworICogYmVpbmcgc2h1dCBkb3duLiAgU28gaXQgd2lsbCBjYWxsIGJhY2sgdG8gaGVyZSBmcm9tIGluc2lkZSBvZiBEYWx2aWssCisgKiB0byBhbGxvdyB1cyB0byBjb250aW51ZSBib290aW5nIHVwLgorICovCitzdGF0aWMgdm9pZCBmaW5pc2hfc3lzdGVtX2luaXQoc3A8UHJvY2Vzc1N0YXRlPiYgcHJvYykKK3sKKyAgICAvLyBJZiB3ZSBhcmUgcnVubmluZyBtdWx0aXByb2Nlc3MsIHdlIG5vdyBuZWVkIHRvIGhhdmUgdGhlCisgICAgLy8gdGhyZWFkIHBvb2wgc3RhcnRlZCBoZXJlLiAgV2UgZG9uJ3QgZG8gdGhpcyBpbiBib290X2luaXQoKQorICAgIC8vIGJlY2F1c2Ugd2hlbiBydW5uaW5nIHNpbmdsZSBwcm9jZXNzIHdlIG5lZWQgdG8gc3RhcnQgdGhlCisgICAgLy8gdGhyZWFkIHBvb2wgYWZ0ZXIgdGhlIEFuZHJvaWQgcnVudGltZSBoYXMgYmVlbiBzdGFydGVkIChzbworICAgIC8vIHRoZSBwb29sIHVzZXMgRGFsdmlrIHRocmVhZHMpLgorICAgIGlmIChwcm9jLT5zdXBwb3J0c1Byb2Nlc3NlcygpKSB7CisgICAgICAgIHByb2MtPnN0YXJ0VGhyZWFkUG9vbCgpOworICAgIH0KK30KKworCisvLyBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGVuZm9yY2Ugc2VjdXJpdHkgdG8gZGlmZmVyZW50CisvLyByb290IGNvbnRleHRzLiAgRm9yIG5vdywgd2UganVzdCBnaXZlIGV2ZXJ5IGFjY2Vzcy4KK3N0YXRpYyBib29sIGNvbnRleHRDaGVja2VyKAorICAgIGNvbnN0IFN0cmluZzE2JiBuYW1lLCBjb25zdCBzcDxJQmluZGVyPiYgY2FsbGVyLCB2b2lkKiB1c2VyRGF0YSkKK3sKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIEluaXRpYWxpemF0aW9uIG9mIGJvb3Qgc2VydmljZXMuCisgKgorICogVGhpcyBpcyB3aGVyZSB3ZSBwZXJmb3JtIGluaXRpYWxpemF0aW9uIG9mIGFsbCBvZiBvdXIgbG93LWxldmVsCisgKiBib290IHNlcnZpY2VzLiAgTW9zdCBpbXBvcnRhbnRseSwgaGVyZSB3ZSBiZWNvbWUgdGhlIGNvbnRleHQKKyAqIG1hbmFnZXIgYW5kIHVzZSB0aGF0IHRvIHB1Ymxpc2ggdGhlIHNlcnZpY2UgbWFuYWdlciB0aGF0IHdpbGwgcHJvdmlkZQorICogYWNjZXNzIHRvIGFsbCBvdGhlciBzZXJ2aWNlcy4KKyAqLworc3RhdGljIHZvaWQgYm9vdF9pbml0KCkKK3sKKyAgICBMT0dJKCJFbnRlcmVkIGJvb3RfaW5pdCgpIVxuIik7CisgICAgCisgICAgc3A8UHJvY2Vzc1N0YXRlPiBwcm9jKFByb2Nlc3NTdGF0ZTo6c2VsZigpKTsKKyAgICBMT0dEKCJQcm9jZXNzU3RhdGU6ICVwXG4iLCBwcm9jLmdldCgpKTsKKyAgICBwcm9jLT5iZWNvbWVDb250ZXh0TWFuYWdlcihjb250ZXh0Q2hlY2tlciwgTlVMTCk7CisgICAgCisgICAgaWYgKHByb2MtPnN1cHBvcnRzUHJvY2Vzc2VzKCkpIHsKKyAgICAgICAgTE9HSSgiQmluZGVyIGRyaXZlciBvcGVuZWQuICBNdWx0aXByb2Nlc3MgZW5hYmxlZC5cbiIpOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR0koIkJpbmRlciBkcml2ZXIgbm90IGZvdW5kLiAgUHJvY2Vzc2VzIG5vdCBzdXBwb3J0ZWQuXG4iKTsKKyAgICB9CisgICAgCisgICAgc3A8QlNlcnZpY2VNYW5hZ2VyPiBzbSA9IG5ldyBCU2VydmljZU1hbmFnZXI7CisgICAgcHJvYy0+c2V0Q29udGV4dE9iamVjdChzbSk7Cit9CisKKy8qCisgKiBSZWRpcmVjdCBzdGRpbi9zdGRvdXQvc3RkZXJyIHRvIC9kZXYvbnVsbC4KKyAqLworc3RhdGljIHZvaWQgcmVkaXJlY3RTdGRGZHModm9pZCkKK3sKKyAgICBpbnQgZmQgPSBvcGVuKCIvZGV2L251bGwiLCBPX1JEV1IsIDApOworICAgIGlmIChmZCA8IDApIHsKKyAgICAgICAgTE9HVygiVW5hYmxlIHRvIG9wZW4gL2Rldi9udWxsOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICB9IGVsc2UgeworICAgICAgICBkdXAyKGZkLCAwKTsKKyAgICAgICAgZHVwMihmZCwgMSk7CisgICAgICAgIGR1cDIoZmQsIDIpOworICAgICAgICBjbG9zZShmZCk7CisgICAgfQorfQorCitzdGF0aWMgaW50IGhhc0Rpcihjb25zdCBjaGFyKiBkaXIpCit7CisgICAgc3RydWN0IHN0YXQgczsKKyAgICBpbnQgcmVzID0gc3RhdChkaXIsICZzKTsKKyAgICBpZiAocmVzID09IDApIHsKKyAgICAgICAgcmV0dXJuIFNfSVNESVIocy5zdF9tb2RlKTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIHZhbGlkYXRlVGltZSgpCit7CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgaW50IGZkOworICAgIGludCByZXM7CisgICAgdGltZV90IG1pbl90aW1lID0gMTE2NzY1MjgwMDsgLy8gamFuIDEgMjAwNywgdHlwZSAnZGF0ZSAtdWQgIjEvMSAxMjowMCIgKyVzJyB0byBnZXQgdmFsdWUgZm9yIGN1cnJlbnQgeWVhcgorICAgIHN0cnVjdCB0aW1lc3BlYyB0czsKKyAgICAKKyAgICBmZCA9IG9wZW4oIi9kZXYvYWxhcm0iLCBPX1JEV1IpOworICAgIGlmKGZkIDwgMCkgeworICAgICAgICBMT0dXKCJVbmFibGUgdG8gb3BlbiBhbGFybSBkcml2ZXI6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHJlcyA9IGlvY3RsKGZkLCBBTkRST0lEX0FMQVJNX0dFVF9USU1FKEFORFJPSURfQUxBUk1fUlRDX1dBS0VVUCksICZ0cyk7CisgICAgaWYocmVzIDwgMCkgeworICAgICAgICBMT0dXKCJVbmFibGUgdG8gcmVhZCBydGMsICVzXG4iLCBzdHJlcnJvcihlcnJubykpOworICAgIH0KKyAgICBlbHNlIGlmKHRzLnR2X3NlYyA+PSBtaW5fdGltZSkgeworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorICAgIExPR1coIkludmFsaWQgdGltZSBkZXRlY3RlZCwgJWxkIHNldCB0byAlbGRcbiIsIHRzLnR2X3NlYywgbWluX3RpbWUpOworICAgIHRzLnR2X3NlYyA9IG1pbl90aW1lOworICAgIHRzLnR2X25zZWMgPSAwOworICAgIHJlcyA9IGlvY3RsKGZkLCBBTkRST0lEX0FMQVJNX1NFVF9SVEMsICZ0cyk7CisgICAgaWYocmVzIDwgMCkgeworICAgICAgICBMT0dXKCJVbmFibGUgdG8gc2V0IHJ0YyB0byAlbGQ6ICVzXG4iLCB0cy50dl9zZWMsIHN0cmVycm9yKGVycm5vKSk7CisgICAgfQorZG9uZToKKyAgICBjbG9zZShmZCk7CisjZW5kaWYKK30KKworI2lmbmRlZiBIQVZFX0FORFJPSURfT1MKK2NsYXNzIFF1aWNrUnVudGltZSA6IHB1YmxpYyBBbmRyb2lkUnVudGltZQoreworcHVibGljOgorICAgIFF1aWNrUnVudGltZSgpIHt9CisKKyAgICB2aXJ0dWFsIHZvaWQgb25TdGFydGVkKCkKKyAgICB7CisgICAgICAgIHByaW50ZigiUXVpY2tSdW50aW1lOiBvblN0YXJ0ZWRcbiIpOworICAgIH0KK307CisjZW5kaWYKKworc3RhdGljIHN0YXR1c190IHN0YXJ0X3Byb2Nlc3MoY29uc3QgY2hhciogbmFtZSk7CisKK3N0YXRpYyB2b2lkIHJlc3RhcnRfbWUocGlkX3QgY2hpbGQsIHZvaWQqIHVzZXJEYXRhKQoreworICAgIHN0YXJ0X3Byb2Nlc3MoKGNvbnN0IGNoYXIqKXVzZXJEYXRhKTsKK30KKworc3RhdGljIHN0YXR1c190IHN0YXJ0X3Byb2Nlc3MoY29uc3QgY2hhciogbmFtZSkKK3sKKyAgICBTdHJpbmc4IHBhdGgobmFtZSk7CisgICAgVmVjdG9yPGNvbnN0IGNoYXIqPiBhcmdzOworICAgIFN0cmluZzggbGVhZihwYXRoLmdldFBhdGhMZWFmKCkpOworICAgIFN0cmluZzggcGFyZW50RGlyKHBhdGguZ2V0UGF0aERpcigpKTsKKyAgICBhcmdzLmluc2VydEF0KGxlYWYuc3RyaW5nKCksIDApOworICAgIGFyZ3MuYWRkKHBhcmVudERpci5zdHJpbmcoKSk7CisgICAgYXJncy5hZGQoTlVMTCk7CisgICAgcGlkX3QgY2hpbGQgPSBmb3JrKCk7CisgICAgaWYgKGNoaWxkIDwgMCkgeworICAgICAgICBzdGF0dXNfdCBlcnIgPSBlcnJubzsKKyAgICAgICAgTE9HRSgiKioqIGZvcmsgb2YgY2hpbGQgJXMgZmFpbGVkOiAlcyIsIGxlYWYuc3RyaW5nKCksIHN0cmVycm9yKGVycikpOworICAgICAgICByZXR1cm4gLWVycm5vOworICAgIH0gZWxzZSBpZiAoY2hpbGQgPT0gMCkgeworICAgICAgICBMT0dJKCJFeGVjdXRpbmc6ICVzIiwgcGF0aC5zdHJpbmcoKSk7CisgICAgICAgIGV4ZWN2KHBhdGguc3RyaW5nKCksIGNvbnN0X2Nhc3Q8Y2hhcioqPihhcmdzLmFycmF5KCkpKTsKKyAgICAgICAgaW50IGVyciA9IGVycm5vOworICAgICAgICBMT0dFKCJFeGVjIGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycikpOworICAgICAgICBfZXhpdChlcnIpOworICAgIH0gZWxzZSB7CisgICAgICAgIFNpZ25hbEhhbmRsZXI6OnNldENoaWxkSGFuZGxlcihjaGlsZCwgREVGQVVMVF9QUk9DRVNTX1RBRywKKyAgICAgICAgICAgICAgICByZXN0YXJ0X21lLCAodm9pZCopbmFtZSk7CisgICAgfQorICAgIHJldHVybiAtZXJybm87Cit9CisKKy8qCisgKiBBcHBsaWNhdGlvbiBlbnRyeSBwb2ludC4KKyAqCisgKiBQYXJzZSBhcmd1bWVudHMsIHNldCBzb21lIHZhbHVlcywgYW5kIHBhc3MgY29udHJvbCBvZmYgdG8gUnVuKCkuCisgKgorICogVGhpcyBpcyByZWRlZmluZWQgdG8gIlNETF9tYWluIiBvbiBTREwgc2ltdWxhdG9yIGJ1aWxkcywgYW5kCisgKiAicnVudGltZV9tYWluIiBvbiB3eFdpZGdldHMgYnVpbGRzLgorICovCitleHRlcm4gIkMiCitpbnQgbWFpbihpbnQgYXJnYywgY2hhciogY29uc3QgYXJndltdKQoreworICAgIGJvb2wgc2luZ2xlUHJvY2VzcyA9IGZhbHNlOworICAgIGNvbnN0IGNoYXIqIGxvZ0ZpbGUgPSBOVUxMOworICAgIGludCBpYzsKKyAgICBpbnQgcmVzdWx0ID0gMTsKKyAgICBwaWRfdCBzeXN0ZW1QaWQ7CisgICAgCisgICAgc3A8UHJvY2Vzc1N0YXRlPiBwcm9jOworCisjaWZuZGVmIEhBVkVfQU5EUk9JRF9PUworICAgIC8qIFNldCBzdGRvdXQvc3RkZXJyIHRvIHVuYnVmZmVyZWQgZm9yIE1pbkdXL01TWVMuICovCisgICAgLy9zZXR2YnVmKHN0ZG91dCwgTlVMTCwgX0lPTkJGLCAwKTsKKyAgICAvL3NldHZidWYoc3RkZXJyLCBOVUxMLCBfSU9OQkYsIDApOworICAgIAorICAgIExPR0koImNvbW1hbmRsaW5lIGFyZ3M6XG4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ2M7IGkrKykKKyAgICAgICAgTE9HSSgiICAlMmQ6ICclcydcbiIsIGksIGFyZ3ZbaV0pOworI2VuZGlmCisKKyAgICB3aGlsZSAoMSkgeworICAgICAgICBpYyA9IGdldG9wdChhcmdjLCBhcmd2LCAiZzpqOnY6ZDpsOm5zIik7CisgICAgICAgIGlmIChpYyA8IDApCisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBzd2l0Y2ggKGljKSB7CisgICAgICAgIGNhc2UgJ2cnOgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2onOgorICAgICAgICAgICAgZ0luaXRpYWxBcHBsaWNhdGlvbiA9IG9wdGFyZzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICd2JzoKKyAgICAgICAgICAgIGdJbml0aWFsVmVyYiA9IG9wdGFyZzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdkJzoKKyAgICAgICAgICAgIGdJbml0aWFsRGF0YSA9IG9wdGFyZzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdsJzoKKyAgICAgICAgICAgIGxvZ0ZpbGUgPSBvcHRhcmc7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnbic6CisgICAgICAgICAgICByZWRpcmVjdFN0ZEZkcygpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgc2luZ2xlUHJvY2VzcyA9IHRydWU7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnPyc6CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBMT0dFKCJydW50aW1lOiB1bnJlY29nbml6ZWQgZmxhZyAtJWNcbiIsIGljKTsKKyAgICAgICAgICAgIHVzYWdlKGFyZ3ZbMF0pOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKG9wdGluZCA8IGFyZ2MpIHsKKyAgICAgICAgTE9HRSgicnVudGltZTogZXh0cmEgc3R1ZmY6ICVzXG4iLCBhcmd2W29wdGluZF0pOworICAgICAgICB1c2FnZShhcmd2WzBdKTsKKyAgICB9CisKKyAgICBpZiAoc2luZ2xlUHJvY2VzcykgeworICAgICAgICBQcm9jZXNzU3RhdGU6OnNldFNpbmdsZVByb2Nlc3ModHJ1ZSk7CisgICAgfQorCisgICAgaWYgKGxvZ0ZpbGUgIT0gTlVMTCkgeworICAgICAgICBhbmRyb2lkX2xvZ1RvRmlsZShOVUxMLCBsb2dGaWxlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFNldCB1cCBBTkRST0lEXyogZW52aXJvbm1lbnQgdmFyaWFibGVzLgorICAgICAqCisgICAgICogVE9ETzogdGhlIHVzZSBvZiAkQU5EUk9JRF9QUk9EVUNUX09VVCB3aWxsIGdvIGF3YXkgc29vbi4KKyAgICAgKi8KKyAgICBzdGF0aWMgY29uc3QgY2hhcioga1N5c3RlbURpciA9ICIvc3lzdGVtIjsKKyAgICBzdGF0aWMgY29uc3QgY2hhcioga0RhdGFEaXIgPSAiL2RhdGEiOworICAgIHN0YXRpYyBjb25zdCBjaGFyKiBrQXBwU3ViZGlyID0gIi9hcHAiOworICAgIGNvbnN0IGNoYXIqIG91dCA9IE5VTEw7CisjaWZuZGVmIEhBVkVfQU5EUk9JRF9PUworICAgIC8vb3V0ID0gZ2V0ZW52KCJBTkRST0lEX1BST0RVQ1RfT1VUIik7CisjZW5kaWYKKyAgICBpZiAob3V0ID09IE5VTEwpCisgICAgICAgIG91dCA9ICIiOworCisgICAgY2hhciogc3lzdGVtRGlyID0gKGNoYXIqKSBtYWxsb2Moc3RybGVuKG91dCkgKyBzdHJsZW4oa1N5c3RlbURpcikgKzEpOworICAgIGNoYXIqIGRhdGFEaXIgPSAoY2hhciopIG1hbGxvYyhzdHJsZW4ob3V0KSArIHN0cmxlbihrRGF0YURpcikgKzEpOworCisgICAgc3ByaW50ZihzeXN0ZW1EaXIsICIlcyVzIiwgb3V0LCBrU3lzdGVtRGlyKTsKKyAgICBzcHJpbnRmKGRhdGFEaXIsICIlcyVzIiwgb3V0LCBrRGF0YURpcik7CisgICAgc2V0ZW52KCJBTkRST0lEX1JPT1QiLCBzeXN0ZW1EaXIsIDEpOworICAgIHNldGVudigiQU5EUk9JRF9EQVRBIiwgZGF0YURpciwgMSk7CisKKyAgICBjaGFyKiBhc3NldERpciA9IChjaGFyKikgbWFsbG9jKHN0cmxlbihzeXN0ZW1EaXIpICsgc3RybGVuKGtBcHBTdWJkaXIpICsxKTsKKyAgICBzcHJpbnRmKGFzc2V0RGlyLCAiJXMlcyIsIHN5c3RlbURpciwga0FwcFN1YmRpcik7CisKKyAgICBMT0dJKCJTdGFydHVwOiBzeXM9JyVzJyBhc3NldD0nJXMnIGRhdGE9JyVzJ1xuIiwKKyAgICAgICAgc3lzdGVtRGlyLCBhc3NldERpciwgZGF0YURpcik7CisgICAgZnJlZShzeXN0ZW1EaXIpOworICAgIGZyZWUoZGF0YURpcik7CisKKyNpZmRlZiBIQVZFX0FORFJPSURfT1MKKyAgICAvKiBzZXQgdXAgYSBwcm9jZXNzIGdyb3VwIGZvciBlYXNpZXIga2lsbGluZyBvbiB0aGUgZGV2aWNlICovCisgICAgc2V0cGdpZCgwLCBnZXRwaWQoKSk7CisjZW5kaWYKKworICAgIC8vIENoYW5nZSB0byBhc3NldCBkaXIuICBUaGlzIGlzIG9ubHkgbmVjZXNzYXJ5IGlmIHdlJ3ZlIGNoYW5nZWQgdG8KKyAgICAvLyBhIGRpZmZlcmVudCBkaXJlY3RvcnksIGJ1dCB0aGVyZSdzIGxpdHRsZSBoYXJtIGluIGRvaW5nIGl0IHJlZ2FyZGxlc3MuCisgICAgLy8KKyAgICAvLyBFeHBlY3RpbmcgYXNzZXRzIHRvIGxpdmUgaW4gdGhlIGN1cnJlbnQgZGlyIGlzIG5vdCBhIGdyZWF0IGlkZWEsCisgICAgLy8gYmVjYXVzZSBzb21lIG9mIG91ciBjb2RlIG9yIG9uZSBvZiBvdXIgbGlicmFyaWVzIGNvdWxkIGNoYW5nZSB0aGUKKyAgICAvLyBkaXJlY3Rvcnkgb3V0IGZyb20gdW5kZXIgdXMuICBQcmVzZXJ2ZSB0aGUgYmVoYXZpb3IgZm9yIG5vdy4KKyAgICBpZiAoY2hkaXIoYXNzZXREaXIpICE9IDApIHsKKyAgICAgICAgTE9HVygiV0FSTklORzogY291bGQgbm90IGNoYW5nZSBkaXIgdG8gJyVzJzogJXNcbiIsCisgICAgICAgICAgICAgYXNzZXREaXIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgfQorICAgIGZyZWUoYXNzZXREaXIpOworCisjaWYgMAorICAgIC8vIEhhY2sgdG8ga2VlcCBsaWJjIGZyb20gYmVhdGluZyB0aGUgZmlsZXN5c3RlbSB0byBkZWF0aC4gIEl0J3MKKyAgICAvLyBoaXR0aW5nIC9ldGMvbG9jYWx0aW1lIGZyZXF1ZW50bHksIAorICAgIC8vCisgICAgLy8gVGhpcyBzdGF0ZW1lbnQgbG9ja3MgdXMgaW50byBQYWNpZmljIHRpbWUuICBXZSBjb3VsZCBkbyBiZXR0ZXIsCisgICAgLy8gYnV0IHRoZXJlJ3Mgbm90IG11Y2ggcG9pbnQgdW50aWwgd2UncmUgc3VyZSB0aGF0IHRoZSBsaWJyYXJ5CisgICAgLy8gY2FuJ3QgYmUgY2hhbmdlZCB0byBkbyBtb3JlIGFsb25nIHRoZSBsaW5lcyBvZiB3aGF0IHdlIHdhbnQuCisjaWZuZGVmIFhQX1dJTgorICAgIHNldGVudigiVFoiLCAiUFNUKzhQRFQsTTQuMS4wLzIsTTEwLjUuMC8yIiwgdHJ1ZSk7CisjZW5kaWYKKyNlbmRpZgorCisgICAgLyogdHJhY2sgb3VyIHByb2dyZXNzIHRocm91Z2ggdGhlIGJvb3Qgc2VxdWVuY2UgKi8KKyAgICBjb25zdCBpbnQgTE9HX0JPT1RfUFJPR1JFU1NfU1RBUlQgPSAzMDAwOworICAgIExPR19FVkVOVF9MT05HKExPR19CT09UX1BST0dSRVNTX1NUQVJULCAKKyAgICAgICAgbnMybXMoc3lzdGVtVGltZShTWVNURU1fVElNRV9NT05PVE9OSUMpKSk7CisKKyAgICB2YWxpZGF0ZVRpbWUoKTsKKworICAgIHByb2MgPSBQcm9jZXNzU3RhdGU6OnNlbGYoKTsKKyAgICAKKyAgICBib290X2luaXQoKTsKKyAgICAKKyAgICAvKiBJZiB3ZSBhcmUgaW4gbXVsdGlwcm9jZXNzIG1vZGUsIGhhdmUgenlnb3RlIHNwYXduIHRoZSBzeXN0ZW0KKyAgICAgKiBzZXJ2ZXIgcHJvY2VzcyBhbmQgY2FsbCBzeXN0ZW1faW5pdCgpLiBJZiB3ZSBhcmUgcnVubmluZyBpbgorICAgICAqIHNpbmdsZSBwcm9jZXNzIG1vZGUganVzdCBjYWxsIHN5c3RlbV9pbml0KCkgZGlyZWN0bHkuCisgICAgICovCisgICAgaWYgKHByb2MtPnN1cHBvcnRzUHJvY2Vzc2VzKCkpIHsKKyAgICAgICAgLy8gSWYgc3RkaW8gbG9nZ2luZyBpcyBvbiwgc3lzdGVtX3NlcnZlciBzaG91bGQgbm90IGluaGVyaXQgb3VyIHN0ZGlvCisgICAgICAgIC8vIFRoZSBkYWx2aWt2bSBpbnN0YW5jZSB3aWxsIGNvcHkgc3RkaW8gdG8gdGhlIGxvZyBvbiBpdHMgb3duCisgICAgICAgIGNoYXIgcHJvcEJ1ZltQUk9QRVJUWV9WQUxVRV9NQVhdOworICAgICAgICBib29sIGxvZ1N0ZGlvID0gZmFsc2U7CisgICAgICAgIHByb3BlcnR5X2dldCgibG9nLnJlZGlyZWN0LXN0ZGlvIiwgcHJvcEJ1ZiwgIiIpOworICAgICAgICBsb2dTdGRpbyA9IChzdHJjbXAocHJvcEJ1ZiwgInRydWUiKSA9PSAwKTsKKworICAgICAgICB6eWdvdGVfcnVuX29uZXNob3QoKGludCkoIWxvZ1N0ZGlvKSwgCisgICAgICAgICAgICAgICAgc2l6ZW9mKFpZR09URV9BUkdWKSAvIHNpemVvZihaWUdPVEVfQVJHVlswXSksIAorICAgICAgICAgICAgICAgIFpZR09URV9BUkdWKTsKKworICAgICAgICAvL3N0YXJ0X3Byb2Nlc3MoIi9zeXN0ZW0vYmluL21lZGlhc2VydmVyIik7CisKKyAgICB9IGVsc2UgeworI2lmbmRlZiBIQVZFX0FORFJPSURfT1MKKyAgICAgICAgUXVpY2tSdW50aW1lKiBydW50ID0gbmV3IFF1aWNrUnVudGltZSgpOworICAgICAgICBydW50LT5zdGFydCgiY29tL2FuZHJvaWQvc2VydmVyL1N5c3RlbVNlcnZlciIsIAorICAgICAgICAgICAgICAgICAgICBmYWxzZSAvKiBzcG9udGFuZW91c2x5IGZvcmsgc3lzdGVtIHNlcnZlciBmcm9tIHp5Z290ZSAqLyk7CisjZW5kaWYKKyAgICB9CisKKyAgICAvL3ByaW50ZigiKysrIHBvc3Qtenlnb3RlXG4iKTsKKworICAgIGZpbmlzaF9zeXN0ZW1faW5pdChwcm9jKTsKKyAgICBydW4ocHJvYyk7CisgICAgCitiYWlsOgorICAgIGlmIChwcm9jICE9IE5VTEwpIHsKKyAgICAgICAgcHJvYy0+c2V0Q29udGV4dE9iamVjdChOVUxMKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9jbWRzL3N1cmZhY2VmbGluZ2VyL0FuZHJvaWQubWsgYi9jbWRzL3N1cmZhY2VmbGluZ2VyL0FuZHJvaWQubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdjM2Q5NAotLS0gL2Rldi9udWxsCisrKyBiL2NtZHMvc3VyZmFjZWZsaW5nZXIvQW5kcm9pZC5tawpAQCAtMCwwICsxLDE2IEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVM6PSBcCisJbWFpbl9zdXJmYWNlZmxpbmdlci5jcHAgCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgOj0gXAorCWxpYnN1cmZhY2VmbGluZ2VyIFwKKwlsaWJ1dGlscworCitMT0NBTF9DX0lOQ0xVREVTIDo9IFwKKwkkKExPQ0FMX1BBVEgpLy4uLy4uL2xpYnMvc3VyZmFjZWZsaW5nZXIKKworTE9DQUxfTU9EVUxFOj0gc3VyZmFjZWZsaW5nZXIKKworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCmRpZmYgLS1naXQgYS9jbWRzL3N1cmZhY2VmbGluZ2VyL21haW5fc3VyZmFjZWZsaW5nZXIuY3BwIGIvY21kcy9zdXJmYWNlZmxpbmdlci9tYWluX3N1cmZhY2VmbGluZ2VyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yzg5NTc4Ci0tLSAvZGV2L251bGwKKysrIGIvY21kcy9zdXJmYWNlZmxpbmdlci9tYWluX3N1cmZhY2VmbGluZ2VyLmNwcApAQCAtMCwwICsxLDE4IEBACisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Qcm9jZXNzU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPFN1cmZhY2VGbGluZ2VyLmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCitpbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpCit7CisgICAgc3A8UHJvY2Vzc1N0YXRlPiBwcm9jKFByb2Nlc3NTdGF0ZTo6c2VsZigpKTsKKyAgICBzcDxJU2VydmljZU1hbmFnZXI+IHNtID0gZGVmYXVsdFNlcnZpY2VNYW5hZ2VyKCk7CisgICAgTE9HSSgiU2VydmljZU1hbmFnZXI6ICVwIiwgc20uZ2V0KCkpOworICAgIFN1cmZhY2VGbGluZ2VyOjppbnN0YW50aWF0ZSgpOworICAgIFByb2Nlc3NTdGF0ZTo6c2VsZigpLT5zdGFydFRocmVhZFBvb2woKTsKKyAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5qb2luVGhyZWFkUG9vbCgpOworfQpkaWZmIC0tZ2l0IGEvaW0vamF2YS9hbmRyb2lkL2ltL0JyYW5kaW5nUmVzb3VyY2VJRHMuamF2YSBiL2ltL2phdmEvYW5kcm9pZC9pbS9CcmFuZGluZ1Jlc291cmNlSURzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTk2MDcyMgotLS0gL2Rldi9udWxsCisrKyBiL2ltL2phdmEvYW5kcm9pZC9pbS9CcmFuZGluZ1Jlc291cmNlSURzLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGFuZHJvaWQuaW07CisKKy8qKgorICogQGhpZGUKKyAqIERlZmluZXMgdGhlIElEcyBvZiBicmFuZGluZyByZXNvdXJjZXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQnJhbmRpbmdSZXNvdXJjZUlEcyB7CisgICAgLyoqCisgICAgICogVGhlIGxvZ28gaWNvbiBvZiB0aGUgcHJvdmlkZXIgd2hpY2ggaXMgZGlzcGxheWVkIGluIHRoZSBsYW5kaW5nIHBhZ2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFJBV0FCTEVfTE9HTyAgICAgICAgICAgICAgICA9IDEwMDsKKyAgICAvKioKKyAgICAgKiBUaGUgaWNvbiBvZiBvbmxpbmUgcHJlc2VuY2Ugc3RhdHVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERSQVdBQkxFX1BSRVNFTkNFX09OTElORSAgICAgPSAxMDI7CisgICAgLyoqCisgICAgICogVGhlIGljb24gb2YgYnVzeSBwcmVzZW5jZSBzdGF0dXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFJBV0FCTEVfUFJFU0VOQ0VfQlVTWSAgICAgICA9IDEwMzsKKyAgICAvKioKKyAgICAgKiBUaGUgaWNvbiBvZiBhd2F5IHByZXNlbmNlIHN0YXR1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEUkFXQUJMRV9QUkVTRU5DRV9BV0FZICAgICAgID0gMTA0OworICAgIC8qKgorICAgICAqIFRoZSBpY29uIG9mIGludmlzaWJsZSBwcmVzZW5jZSBzdGF0dXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFJBV0FCTEVfUFJFU0VOQ0VfSU5WSVNJQkxFICA9IDEwNTsKKyAgICAvKioKKyAgICAgKiBUaGUgaWNvbiBvZiBvZmZsaW5lIHByZXNlbmNlIHN0YXR1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEUkFXQUJMRV9QUkVTRU5DRV9PRkZMSU5FICAgID0gMTA2OworICAgIC8qKgorICAgICAqIFRoZSBsYWJlbCBvZiB0aGUgbWVudSB0byBnbyB0byB0aGUgY29udGFjdCBsaXN0IHNjcmVlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfTUVOVV9DT05UQUNUX0xJU1QgICAgID0gMTA3OworCit9CmRpZmYgLS1naXQgYS9pbS9qYXZhL2FuZHJvaWQvaW0vSUltUGx1Z2luLmFpZGwgYi9pbS9qYXZhL2FuZHJvaWQvaW0vSUltUGx1Z2luLmFpZGwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI5Y2QwZQotLS0gL2Rldi9udWxsCisrKyBiL2ltL2phdmEvYW5kcm9pZC9pbS9JSW1QbHVnaW4uYWlkbApAQCAtMCwwICsxLDY5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgYW5kcm9pZC5pbTsKKworLyoqCisgKiBAaGlkZQorICovCitpbnRlcmZhY2UgSUltUGx1Z2luIHsKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgdGhlIHBsdWdpbiB0aGUgZnJvbnQgZG9vciBhY3Rpdml0eSBpcyBjcmVhdGVkLiBUaGlzIGdpdmVzIHRoZSBwbHVnaW4gYSBjaGFuY2UgdG8KKyAgICAgKiBzdGFydCBpdHMgb3duIHNlcnZpY3MsIGV0Yy4KKyAgICAgKi8KKyAgICB2b2lkIG9uU3RhcnQoKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgdGhlIHBsdWdpbiB0aGUgZnJvbnQgZG9vciBhY3Rpdml0eSBpcyBzdG9wcGluZy4KKyAgICAgKi8KKyAgICB2b2lkIG9uU3RvcCgpOworCisgICAgLyoqCisgICAgICogU2lnbiBpbiB0byB0aGUgc2VydmljZSBmb3IgdGhlIGFjY291bnQgcGFzc2VkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGFjY291bnQgdGhlIGFjY291bnQgaWQgZm9yIHRoZSBhY2NvbnQgdG8gYmUgc2lnbmVkIGludG8uCisgICAgICovCisgICAgdm9pZCBzaWduSW4obG9uZyBhY2NvdW50KTsKKworICAgIC8qKgorICAgICAqIFNpZ24gb3V0IG9mIHRoZSBzZXJ2aWNlIGZvciB0aGUgYWNjb3VudCBwYXNzZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWNjb3VudCB0aGUgYWNjb3VudCBpZCBmb3IgdGhlIGFjY29udCB0byBiZSBzaWduZWQgb3V0IG9mLgorICAgICAqLworICAgIHZvaWQgc2lnbk91dChsb25nIGFjY291bnQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBuYW1lIHVzZWQgdG8gbG9hZCB0aGUgcmVzb3VyY2VzIGZvciB0aGUgZ2l2ZW4gcHJvdmlkZXIgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHBhY2thZ2UgbmFtZSB0byBsb2FkIHRoZSByZXNvdXJjcyBmb3IgdGhlIGdpdmVuIHByb3ZpZGVyLgorICAgICAqLworICAgIFN0cmluZyBnZXRSZXNvdXJjZVBhY2thZ2VOYW1lRm9yUHJvdmlkZXIoU3RyaW5nIHByb3ZpZGVyTmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbWFwIG9mIGJyYW5kaW5nIHJlc291cmNlcyBmb3IgdGhlIGdpdmVuIHByb3ZpZGVyLiBUaGUga2V5cyBhcmUgZGVmaW5lZAorICAgICAqIGluIHtAbGluayBhbmRyb2lkLmltLkJyYW5kaW5nUmVzb3VyY2VJRHN9LiBUaGUgdmFsdWVzIGFyZSB0aGUgcmVzb3VyY2UgaWRlbnRpZmllcnMgZ2VuZXJhdGVkCisgICAgICogYnkgdGhlIGFhcHQgdG9vbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG1hcCBvZiBicmFuZGluZyByZXNvdXJjZXMgZm9yIHRoZSBnaXZlbiBwcm92aWRlci4KKyAgICAgKi8KKyAgICBNYXAgZ2V0UmVzb3VyY2VNYXBGb3JQcm92aWRlcihTdHJpbmcgcHJvdmlkZXJOYW1lKTsKKworICAgIC8qCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2Ygc3VwcG9ydGVkIElNIHByb3ZpZGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBMaXN0IG9mIHN1cHBvcnRlZCBwcm92aWRlcnMuCisgICAgICovCisgICAgTGlzdCBnZXRTdXBwb3J0ZWRQcm92aWRlcnMoKTsKK30KZGlmZiAtLWdpdCBhL2ltL2phdmEvYW5kcm9pZC9pbS9JbVBsdWdpbkNvbnN0cy5qYXZhIGIvaW0vamF2YS9hbmRyb2lkL2ltL0ltUGx1Z2luQ29uc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE2NDkzZgotLS0gL2Rldi9udWxsCisrKyBiL2ltL2phdmEvYW5kcm9pZC9pbS9JbVBsdWdpbkNvbnN0cy5qYXZhCkBAIC0wLDAgKzEsMjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGFuZHJvaWQuaW07CisKKy8qKgorICogQGhpZGUKKyAqLworcHVibGljIGNsYXNzIEltUGx1Z2luQ29uc3RzIHsKKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZW50IGFjdGlvbiBuYW1lIGZvciB0aGUgcGx1Z2luIHNlcnZpY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUExVR0lOX0FDVElPTl9OQU1FID0gImFuZHJvaWQuaW0ucGx1Z2luIjsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9pbmNsdWRlL3BpbS9FdmVudFJlY3VycmVuY2UuaCBiL2luY2x1ZGUvcGltL0V2ZW50UmVjdXJyZW5jZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZWRhNDEKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3BpbS9FdmVudFJlY3VycmVuY2UuaApAQCAtMCwwICsxLDgyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKyNpZm5kZWYgX1BJTV9FVkVOVF9SRUNVUlJFTkNFX0gKKyNkZWZpbmUgX1BJTV9FVkVOVF9SRUNVUlJFTkNFX0gKKworI2luY2x1ZGUgPHV0aWxzL1N0cmluZzE2Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RydWN0IEV2ZW50UmVjdXJyZW5jZQoreworcHVibGljOgorICAgICAgICAgICAgICAgIEV2ZW50UmVjdXJyZW5jZSgpOworICAgICAgICAgICAgICAgIH5FdmVudFJlY3VycmVuY2UoKTsKKyAgICAKKyAgICBzdGF0dXNfdCAgICBwYXJzZShjb25zdCBTdHJpbmcxNiYpOworCisKKyAgICBlbnVtIGZyZXFfdCB7CisgICAgICAgIFNFQ09ORExZID0gMSwKKyAgICAgICAgTUlOVVRFTFkgPSAyLAorICAgICAgICBIT1VSTFkgPSAzLAorICAgICAgICBEQUlMWSA9IDQsCisgICAgICAgIFdFRUtMWSA9IDUsCisgICAgICAgIE1PTlRITFkgPSA2LAorICAgICAgICBZRUFSTFkgPSA3CisgICAgfTsKKworICAgIGVudW0geworICAgICAgICBTVSA9IDB4MDAwMTAwMDAsCisgICAgICAgIE1PID0gMHgwMDAyMDAwMCwKKyAgICAgICAgVFUgPSAweDAwMDQwMDAwLAorICAgICAgICBXRSA9IDB4MDAwODAwMDAsCisgICAgICAgIFRIID0gMHgwMDEwMDAwMCwKKyAgICAgICAgRlIgPSAweDAwMjAwMDAwLAorICAgICAgICBTQSA9IDB4MDA0MDAwMDAKKyAgICB9OworICAgIAorICAgIGZyZXFfdCAgICBmcmVxOworICAgIFN0cmluZzE2ICB1bnRpbDsKKyAgICBpbnQgICAgICAgY291bnQ7CisgICAgaW50ICAgICAgIGludGVydmFsOworICAgIGludCogICAgICBieXNlY29uZDsKKyAgICBpbnQgICAgICAgYnlzZWNvbmRDb3VudDsKKyAgICBpbnQqICAgICAgYnltaW51dGU7CisgICAgaW50ICAgICAgIGJ5bWludXRlQ291bnQ7CisgICAgaW50KiAgICAgIGJ5aG91cjsKKyAgICBpbnQgICAgICAgYnlob3VyQ291bnQ7CisgICAgaW50KiAgICAgIGJ5ZGF5OworICAgIGludCogICAgICBieWRheU51bTsKKyAgICBpbnQgICAgICAgYnlkYXlDb3VudDsgICAKKyAgICBpbnQqICAgICAgYnltb250aGRheTsKKyAgICBpbnQgICAgICAgYnltb250aGRheUNvdW50OworICAgIGludCogICAgICBieXllYXJkYXk7CisgICAgaW50ICAgICAgIGJ5eWVhcmRheUNvdW50OworICAgIGludCogICAgICBieXdlZWtubzsKKyAgICBpbnQgICAgICAgYnl3ZWVrbm9Db3VudDsKKyAgICBpbnQqICAgICAgYnltb250aDsKKyAgICBpbnQgICAgICAgYnltb250aENvdW50OworICAgIGludCogICAgICBieXNldHBvczsKKyAgICBpbnQgICAgICAgYnlzZXRwb3NDb3VudDsKKyAgICBpbnQgICAgICAgd2tzdDsKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBfUElNX0VWRU5UX1JFQ1VSUkVOQ0VfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9wcml2YXRlL29wZW5nbGVzL2dsX2NvbnRleHQuaCBiL2luY2x1ZGUvcHJpdmF0ZS9vcGVuZ2xlcy9nbF9jb250ZXh0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM3YWQ0NgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvcHJpdmF0ZS9vcGVuZ2xlcy9nbF9jb250ZXh0LmgKQEAgLTAsMCArMSw2MzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfT1BFTkdMRVNfQ09OVEVYVF9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfQ09OVEVYVF9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisjaWZkZWYgSEFWRV9BTkRST0lEX09TCisjaW5jbHVkZSA8YmlvbmljX3Rscy5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxwcml2YXRlL3BpeGVsZmxpbmdlci9nZ2xfY29udGV4dC5oPgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2xleHQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjb25zdCB1bnNpZ25lZCBpbnQgT0dMRVNfTlVNX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTID0gMTA7CisKK2NsYXNzIEVHTFRleHR1cmVPYmplY3Q7CitjbGFzcyBFR0xTdXJmYWNlTWFuYWdlcjsKK2NsYXNzIEVHTEJ1ZmZlck9iamVjdE1hbmFnZXI7CisKK25hbWVzcGFjZSBnbCB7CisgCitzdHJ1Y3Qgb2dsZXNfY29udGV4dF90Oworc3RydWN0IG1hdHJpeHhfdDsKK3N0cnVjdCB0cmFuc2Zvcm1fdDsKK3N0cnVjdCBidWZmZXJfdDsKKworb2dsZXNfY29udGV4dF90KiBnZXRHbENvbnRleHQoKTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0YXRpYyBpbmxpbmUgdm9pZCBzd2FwKFQmIGEsIFQmIGIpIHsKKyAgICBUIHQoYSk7IGEgPSBiOyBiID0gdDsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgVCBtYXgoVCBhLCBUIGIpIHsKKyAgICByZXR1cm4gYTxiID8gYiA6IGE7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoraW5saW5lIFQgbWF4KFQgYSwgVCBiLCBUIGMpIHsKKyAgICByZXR1cm4gbWF4KGEsIG1heChiLCBjKSk7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoraW5saW5lIFQgbWluKFQgYSwgVCBiKSB7CisgICAgcmV0dXJuIGE8YiA/IGEgOiBiOworfQordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2lubGluZSBUIG1pbihUIGEsIFQgYiwgVCBjKSB7CisgICAgcmV0dXJuIG1pbihhLCBtaW4oYiwgYykpOworfQordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2lubGluZSBUIG1pbihUIGEsIFQgYiwgVCBjLCBUIGQpIHsKKyAgICByZXR1cm4gbWluKG1pbihhLGIpLCBtaW4oYyxkKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHZlcnRpY2VzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCB2ZWMzX3QgeworICAgIHVuaW9uIHsKKyAgICAgICAgc3RydWN0IHsgR0xmaXhlZCB4LCB5LCB6OyB9OworICAgICAgICBzdHJ1Y3QgeyBHTGZpeGVkIHIsIGcsIGI7IH07CisgICAgICAgIHN0cnVjdCB7IEdMZml4ZWQgUywgVCwgUjsgfTsKKyAgICAgICAgR0xmaXhlZCB2WzNdOworICAgIH07Cit9OworCitzdHJ1Y3QgdmVjNF90IHsKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7IEdMZml4ZWQgeCwgeSwgeiwgdzsgfTsKKyAgICAgICAgc3RydWN0IHsgR0xmaXhlZCByLCBnLCBiLCBhOyB9OworICAgICAgICBzdHJ1Y3QgeyBHTGZpeGVkIFMsIFQsIFIsIFE7IH07CisgICAgICAgIEdMZml4ZWQgdls0XTsKKyAgICB9OworfTsKKworc3RydWN0IHZlcnRleF90IHsKKyAgICBlbnVtIHsKKyAgICAgICAgLy8gdGhlc2UgY29uc3RhbnQgbWF0dGVyIGZvciBvdXIgY2xpcHBpbmcgCisgICAgICAgIENMSVBfTCAgICAgICAgICA9IDB4MDAwMSwgICAvLyBjbGlwcGluZyBmbGFncworICAgICAgICBDTElQX1IgICAgICAgICAgPSAweDAwMDIsCisgICAgICAgIENMSVBfQiAgICAgICAgICA9IDB4MDAwNCwKKyAgICAgICAgQ0xJUF9UICAgICAgICAgID0gMHgwMDA4LAorICAgICAgICBDTElQX04gICAgICAgICAgPSAweDAwMTAsCisgICAgICAgIENMSVBfRiAgICAgICAgICA9IDB4MDAyMCwKKworICAgICAgICBFWUUgICAgICAgICAgICAgPSAweDAwNDAsCisgICAgICAgIFJFU0VSVkVEICAgICAgICA9IDB4MDA4MCwKKyAgICAgICAgCisgICAgICAgIFVTRVJfQ0xJUF8wICAgICA9IDB4MDEwMCwgICAvLyB1c2VyIGNsaXBwaW5nIGZsYWdzCisgICAgICAgIFVTRVJfQ0xJUF8xICAgICA9IDB4MDIwMCwKKyAgICAgICAgVVNFUl9DTElQXzIgICAgID0gMHgwNDAwLAorICAgICAgICBVU0VSX0NMSVBfMyAgICAgPSAweDA4MDAsCisgICAgICAgIFVTRVJfQ0xJUF80ICAgICA9IDB4MTAwMCwKKyAgICAgICAgVVNFUl9DTElQXzUgICAgID0gMHgyMDAwLAorCisgICAgICAgIExJVCAgICAgICAgICAgICA9IDB4NDAwMCwgICAvLyBsaWdodGluZyBoYXMgYmVlbiBhcHBsaWVkCisgICAgICAgIFRUICAgICAgICAgICAgICA9IDB4ODAwMCwgICAvLyB0ZXh0dXJlIGNvb3JkcyB0cmFuc2Zvcm1lZAorCisgICAgICAgIEZSVVNUVU1fQ0xJUF9BTEw9IDB4MDAzRiwKKyAgICAgICAgVVNFUl9DTElQX0FMTCAgID0gMHgzRjAwLAorICAgICAgICBDTElQX0FMTCAgICAgICAgPSAweDNGM0YsCisgICAgfTsKKyAgICAKKyAgICAvLyB0aGUgZmllbGRzIGJlbG93IGFyZSBhcnJhbmdlZCB0byBtaW5pbWl6ZSBkLWNhY2hlIHVzYWdlCisgICAgLy8gd2UgZ3JvdXAgdG9nZXRoZXIsIGJ5IGNhY2hlLWxpbmUsIHRoZSBmaWVsZHMgbW9zdCBsaWtlbHkgdG8gYmUgdXNlZAorCisgICAgdW5pb24geworICAgIHZlYzRfdCAgICAgICAgICBvYmo7CisgICAgdmVjNF90ICAgICAgICAgIGV5ZTsKKyAgICB9OworICAgIHZlYzRfdCAgICAgICAgICBjbGlwOworICAgIAorICAgIHVpbnQzMl90ICAgICAgICBmbGFnczsKKyAgICBzaXplX3QgICAgICAgICAgaW5kZXg7ICAvLyBjYWNoZSB0YWcsIGFuZCB2ZXJ0ZXggaW5kZXgKKyAgICBHTGZpeGVkICAgICAgICAgZm9nOworICAgIHVpbnQ4X3QgICAgICAgICBsb2NrZWQ7CisgICAgdWludDhfdCAgICAgICAgIG1ydTsKKyAgICB1aW50OF90ICAgICAgICAgcmVzZXJ2ZWRbMl07CisgICAgdmVjNF90ICAgICAgICAgIHdpbmRvdzsKKworICAgIHZlYzRfdCAgICAgICAgICBjb2xvcjsKKyAgICB2ZWM0X3QgICAgICAgICAgdGV4dHVyZVtHR0xfVEVYVFVSRV9VTklUX0NPVU5UXTsKKyAgICB1aW50MzJfdCAgICAgICAgcmVzZXJ2ZWQxWzRdOworICAgIAorICAgIGlubGluZSB2b2lkIGNsZWFyKCkgeworICAgICAgICBmbGFncyA9IGluZGV4ID0gbG9ja2VkID0gbXJ1ID0gMDsKKyAgICB9Cit9OworCitzdHJ1Y3QgcG9pbnRfc2l6ZV90IHsKKyAgICBHR0xjb29yZCAgICBzaXplOworICAgIEdMYm9vbGVhbiAgIHNtb290aDsKK307CisKK3N0cnVjdCBsaW5lX3dpZHRoX3QgeworICAgIEdHTGNvb3JkICAgIHdpZHRoOworICAgIEdMYm9vbGVhbiAgIHNtb290aDsKK307CisKK3N0cnVjdCBwb2x5Z29uX29mZnNldF90IHsKKyAgICBHTGZpeGVkICAgICBmYWN0b3I7CisgICAgR0xmaXhlZCAgICAgdW5pdHM7CisgICAgR0xib29sZWFuICAgZW5hYmxlOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gYXJyYXlzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBhcnJheV90IHsKKyAgICB0eXBlZGVmIHZvaWQgKCpmZXRjaGVyX3QpKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqLCBjb25zdCBHTHZvaWQqKTsKKyAgICBmZXRjaGVyX3QgICAgICAgZmV0Y2g7CisgICAgR0x2b2lkIGNvbnN0KiAgIHBoeXNpY2FsX3BvaW50ZXI7CisgICAgR0xpbnQgICAgICAgICAgIHNpemU7CisgICAgR0xzaXplaSAgICAgICAgIHN0cmlkZTsKKyAgICBHTHZvaWQgY29uc3QqICAgcG9pbnRlcjsKKyAgICBidWZmZXJfdCBjb25zdCogYm87CisgICAgdWludDE2X3QgICAgICAgIHR5cGU7CisgICAgR0xib29sZWFuICAgICAgIGVuYWJsZTsKKyAgICBHTGJvb2xlYW4gICAgICAgcGFkOworICAgIEdMc2l6ZWkgICAgICAgICBib3VuZHM7CisgICAgdm9pZCBpbml0KEdMaW50LCBHTGVudW0sIEdMc2l6ZWksIGNvbnN0IEdMdm9pZCAqLCBjb25zdCBidWZmZXJfdCosIEdMc2l6ZWkpOworICAgIGlubGluZSB2b2lkIHJlc29sdmUoKTsKKyAgICBpbmxpbmUgY29uc3QgR0x1Ynl0ZSogZWxlbWVudChHTGludCBpKSBjb25zdCB7CisgICAgICAgIHJldHVybiAoY29uc3QgR0x1Ynl0ZSopcGh5c2ljYWxfcG9pbnRlciArIGkgKiBzdHJpZGU7CisgICAgfQorfTsKKworc3RydWN0IGFycmF5X21hY2hpbmVfdCB7CisgICAgYXJyYXlfdCAgICAgICAgIHZlcnRleDsKKyAgICBhcnJheV90ICAgICAgICAgbm9ybWFsOworICAgIGFycmF5X3QgICAgICAgICBjb2xvcjsKKyAgICBhcnJheV90ICAgICAgICAgdGV4dHVyZVtHR0xfVEVYVFVSRV9VTklUX0NPVU5UXTsKKyAgICB1aW50OF90ICAgICAgICAgYWN0aXZlVGV4dHVyZTsKKyAgICB1aW50OF90ICAgICAgICAgdG11OworICAgIHVpbnQxNl90ICAgICAgICBjdWxsOworICAgIHVpbnQzMl90ICAgICAgICBmbGFnczsKKyAgICBHTGVudW0gICAgICAgICAgaW5kaWNlc1R5cGU7CisgICAgYnVmZmVyX3QgY29uc3QqIGFycmF5X2J1ZmZlcjsKKyAgICBidWZmZXJfdCBjb25zdCogZWxlbWVudF9hcnJheV9idWZmZXI7CisgICAgCisgICAgdm9pZCAoKmNvbXBpbGVFbGVtZW50cykob2dsZXNfY29udGV4dF90KiwgdmVydGV4X3QqLCBHTGludCwgR0xzaXplaSk7CisgICAgdm9pZCAoKmNvbXBpbGVFbGVtZW50KShvZ2xlc19jb250ZXh0X3QqLCB2ZXJ0ZXhfdCosIEdMaW50KTsKKworICAgIHZvaWQgKCptdnBfdHJhbnNmb3JtKSh0cmFuc2Zvcm1fdCBjb25zdCosIHZlYzRfdCosIHZlYzRfdCBjb25zdCopOworICAgIHZvaWQgKCptdl90cmFuc2Zvcm0pKHRyYW5zZm9ybV90IGNvbnN0KiwgdmVjNF90KiwgdmVjNF90IGNvbnN0Kik7CisgICAgdm9pZCAoKnRleF90cmFuc2Zvcm1bMl0pKHRyYW5zZm9ybV90IGNvbnN0KiwgdmVjNF90KiwgdmVjNF90IGNvbnN0Kik7CisgICAgdm9pZCAoKnBlcnNwZWN0aXZlKShvZ2xlc19jb250ZXh0X3QqYywgdmVydGV4X3QqIHYpOworICAgIHZvaWQgKCpjbGlwVmVydGV4KShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiBudiwKKyAgICAgICAgICAgIEdHTGZpeGVkIHQsIGNvbnN0IHZlcnRleF90KiBzLCBjb25zdCB2ZXJ0ZXhfdCogcCk7CisgICAgdm9pZCAoKmNsaXBFeWUpKG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIG52LAorICAgICAgICAgICAgR0dMZml4ZWQgdCwgY29uc3QgdmVydGV4X3QqIHMsIGNvbnN0IHZlcnRleF90KiBwKTsKK307CisKK3N0cnVjdCB2ZXJ0ZXhfY2FjaGVfdCB7CisgICAgZW51bSB7CisgICAgICAgIC8vIG11c3QgYmUgYXQgbGVhc3QgNAorICAgICAgICAvLyAzIHZlcnRpY2UgZm9yIHRyaWFuZ2xlcworICAgICAgICAvLyBvciAyICsgMiBmb3IgaW5kZXhlZCB0cmlhbmdsZXMgdy8gY2FjaGUgY29udGVudGlvbgorICAgICAgICBWRVJURVhfQlVGRkVSX1NJWkUgID0gOCwKKyAgICAgICAgLy8gbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBhbmQgYXQgbGVhc3QgMworICAgICAgICBWRVJURVhfQ0FDSEVfU0laRSAgID0gNjQsICAgLy8gOCBLQgorCisgICAgICAgIElOREVYX0JJVFMgICAgICA9IDE2LAorICAgICAgICBJTkRFWF9NQVNLICAgICAgPSAoKDFMVTw8SU5ERVhfQklUUyktMSksCisgICAgICAgIElOREVYX1NFUSAgICAgICA9IDFMVTw8SU5ERVhfQklUUywKKyAgICB9OworICAgIHZlcnRleF90KiAgICAgICB2QnVmZmVyOworICAgIHZlcnRleF90KiAgICAgICB2Q2FjaGU7CisgICAgdWludDMyX3QgICAgICAgIHNlcXVlbmNlOworICAgIHZvaWQqICAgICAgICAgICBiYXNlOworICAgIHVpbnQzMl90ICAgICAgICB0b3RhbDsKKyAgICB1aW50MzJfdCAgICAgICAgbWlzc2VzOworICAgIGludDY0X3QgICAgICAgICBzdGFydFRpbWU7CisgICAgdm9pZCBpbml0KCk7CisgICAgdm9pZCB1bmluaXQoKTsKKyAgICB2b2lkIGNsZWFyKCk7CisgICAgdm9pZCBkdW1wX3N0YXRzKEdMZW51bSBtb2RlKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGZvZworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgZm9nX3QgeworICAgIEdMZml4ZWQgICAgIGRlbnNpdHk7CisgICAgR0xmaXhlZCAgICAgc3RhcnQ7CisgICAgR0xmaXhlZCAgICAgZW5kOworICAgIEdMZml4ZWQgICAgIGludkVuZE1pbnVzU3RhcnQ7CisgICAgR0xlbnVtICAgICAgbW9kZTsKKyAgICBHTGZpeGVkICAgICAoKmZvZykob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkIHopOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gdXNlciBjbGlwIHBsYW5lcworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCB1bnNpZ25lZCBpbnQgT0dMRVNfTUFYX0NMSVBfUExBTkVTID0gNjsKKworc3RydWN0IGNsaXBfcGxhbmVfdCB7CisgICAgdmVjNF90ICAgICAgZXF1YXRpb247Cit9OworCitzdHJ1Y3QgdXNlcl9jbGlwX3BsYW5lc190IHsKKyAgICBjbGlwX3BsYW5lX3QgICAgcGxhbmVbT0dMRVNfTUFYX0NMSVBfUExBTkVTXTsKKyAgICB1aW50MzJfdCAgICAgICAgZW5hYmxlOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gbGlnaHRpbmcKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgdW5zaWduZWQgaW50IE9HTEVTX01BWF9MSUdIVFMgPSA4OworCitzdHJ1Y3QgbGlnaHRfdCB7CisgICAgdmVjNF90ICAgICAgYW1iaWVudDsKKyAgICB2ZWM0X3QgICAgICBkaWZmdXNlOworICAgIHZlYzRfdCAgICAgIHNwZWN1bGFyOworICAgIHZlYzRfdCAgICAgIGltcGxpY2l0QW1iaWVudDsKKyAgICB2ZWM0X3QgICAgICBpbXBsaWNpdERpZmZ1c2U7CisgICAgdmVjNF90ICAgICAgaW1wbGljaXRTcGVjdWxhcjsKKyAgICB2ZWM0X3QgICAgICBwb3NpdGlvbjsgICAgICAgLy8gcG9zaXRpb24gaW4gZXllIHNwYWNlCisgICAgdmVjNF90ICAgICAgb2JqUG9zaXRpb247CisgICAgdmVjNF90ICAgICAgbm9ybWFsaXplZE9ialBvc2l0aW9uOworICAgIHZlYzRfdCAgICAgIHNwb3REaXI7CisgICAgdmVjNF90ICAgICAgbm9ybWFsaXplZFNwb3REaXI7CisgICAgR0xmaXhlZCAgICAgc3BvdEV4cDsKKyAgICBHTGZpeGVkICAgICBzcG90Q3V0b2ZmOworICAgIEdMZml4ZWQgICAgIHNwb3RDdXRvZmZDb3NpbmU7CisgICAgR0xmaXhlZCAgICAgYXR0ZW51YXRpb25bM107CisgICAgR0xmaXhlZCAgICAgckNvbnN0QXR0ZW51YXRpb247CisgICAgR0xib29sZWFuICAgZW5hYmxlOworfTsKKworc3RydWN0IG1hdGVyaWFsX3QgeworICAgIHZlYzRfdCAgICAgIGFtYmllbnQ7CisgICAgdmVjNF90ICAgICAgZGlmZnVzZTsKKyAgICB2ZWM0X3QgICAgICBzcGVjdWxhcjsKKyAgICB2ZWM0X3QgICAgICBlbWlzc2lvbjsKKyAgICBHTGZpeGVkICAgICBzaGluaW5lc3M7Cit9OworCitzdHJ1Y3QgbGlnaHRfbW9kZWxfdCB7CisgICAgdmVjNF90ICAgICAgYW1iaWVudDsKKyAgICBHTGJvb2xlYW4gICB0d29TaWRlOworfTsKKworc3RydWN0IGNvbG9yX21hdGVyaWFsX3QgeworICAgIEdMZW51bSAgICAgIGZhY2U7CisgICAgR0xlbnVtICAgICAgbW9kZTsKKyAgICBHTGJvb2xlYW4gICBlbmFibGU7Cit9OworCitzdHJ1Y3QgbGlnaHRpbmdfdCB7CisgICAgbGlnaHRfdCAgICAgICAgICAgICBsaWdodHNbT0dMRVNfTUFYX0xJR0hUU107CisgICAgbWF0ZXJpYWxfdCAgICAgICAgICBmcm9udDsKKyAgICBsaWdodF9tb2RlbF90ICAgICAgIGxpZ2h0TW9kZWw7CisgICAgY29sb3JfbWF0ZXJpYWxfdCAgICBjb2xvck1hdGVyaWFsOworICAgIHVpbnQzMl90ICAgICAgICAgICAgZW5hYmxlZExpZ2h0czsKKyAgICBHTGJvb2xlYW4gICAgICAgICAgIGVuYWJsZTsKKyAgICB2ZWM0X3QgICAgICAgICAgICAgIGltcGxpY2l0U2NlbmVFbWlzc2lvbkFuZEFtYmllbnQ7CisgICAgR0xlbnVtICAgICAgICAgICAgICBzaGFkZU1vZGVsOworICAgIHR5cGVkZWYgdm9pZCAoKmxpZ2h0X2ZjdF90KShvZ2xlc19jb250ZXh0X3QqLCB2ZXJ0ZXhfdCopOworICAgIHZvaWQgKCpsaWdodFZlcnRleCkob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdik7CisgICAgdm9pZCAoKmxpZ2h0VHJpYW5nbGUpKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpOworfTsKKworc3RydWN0IGN1bGxpbmdfdCB7CisgICAgR0xlbnVtICAgICAgY3VsbEZhY2U7CisgICAgR0xlbnVtICAgICAgZnJvbnRGYWNlOworICAgIEdMYm9vbGVhbiAgIGVuYWJsZTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHRleHR1cmVzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCB0ZXh0dXJlX3VuaXRfdCB7CisgICAgR0x1aW50ICAgICAgICAgICAgICBuYW1lOworICAgIEVHTFRleHR1cmVPYmplY3QqICAgdGV4dHVyZTsKKyAgICB1aW50OF90ICAgICAgICAgICAgIGRpcnR5OworfTsKKworc3RydWN0IHRleHR1cmVfc3RhdGVfdAoreworICAgIHRleHR1cmVfdW5pdF90ICAgICAgdG11W0dHTF9URVhUVVJFX1VOSVRfQ09VTlRdOworICAgIGludCAgICAgICAgICAgICAgICAgYWN0aXZlOyAgICAgLy8gYWN0aXZlIHRtdQorICAgIEVHTFRleHR1cmVPYmplY3QqICAgZGVmYXVsdFRleHR1cmU7CisgICAgR0dMQ29udGV4dCogICAgICAgICBnZ2w7CisgICAgdWludDhfdCAgICAgICAgICAgICBwYWNrQWxpZ25tZW50OworICAgIHVpbnQ4X3QgICAgICAgICAgICAgdW5wYWNrQWxpZ25tZW50OworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gdHJhbnNmb3JtYXRpb24gYW5kIG1hdHJpY2VzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBtYXRyaXhmX3Q7CisKK3N0cnVjdCBtYXRyaXh4X3QgeworICAgIEdMZml4ZWQgbVsxNl07CisgICAgdm9pZCBsb2FkKGNvbnN0IG1hdHJpeGZfdCYgcmhzKTsKK307CisKK3N0cnVjdCBtYXRyaXhfc3RhY2tfdDsKKworCitzdHJ1Y3QgbWF0cml4Zl90IHsKKyAgICB2b2lkIGxvYWRJZGVudGl0eSgpOworICAgIHZvaWQgbG9hZChjb25zdCBtYXRyaXhmX3QmIHJocyk7CisKKyAgICBpbmxpbmUgR0xmbG9hdCogZWRpdEVsZW1lbnRzKCkgeyByZXR1cm4gbTsgfQorICAgIGlubGluZSBHTGZsb2F0IGNvbnN0KiBlbGVtZW50cygpIGNvbnN0IHsgcmV0dXJuIG07IH0KKworICAgIHZvaWQgc2V0KGNvbnN0IEdMZml4ZWQqIHJocyk7CisgICAgdm9pZCBzZXQoY29uc3QgR0xmbG9hdCogcmhzKTsKKworICAgIHN0YXRpYyB2b2lkIG11bHRpcGx5KG1hdHJpeGZfdCYgciwKKyAgICAgICAgICAgIGNvbnN0IG1hdHJpeGZfdCYgbGhzLCBjb25zdCBtYXRyaXhmX3QmIHJocyk7CisKKyAgICB2b2lkIGR1bXAoY29uc3QgY2hhciogd2hhdCk7CisKK3ByaXZhdGU6CisgICAgZnJpZW5kIHN0cnVjdCBtYXRyaXhfc3RhY2tfdDsKKyAgICBHTGZsb2F0ICAgICBtWzE2XTsKKyAgICB2b2lkIGxvYWQoY29uc3QgR0xmaXhlZCogcmhzKTsKKyAgICB2b2lkIGxvYWQoY29uc3QgR0xmbG9hdCogcmhzKTsKKyAgICB2b2lkIG11bHRpcGx5KGNvbnN0IG1hdHJpeGZfdCYgcmhzKTsKKyAgICB2b2lkIHRyYW5zbGF0ZShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KTsKKyAgICB2b2lkIHNjYWxlKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopOworICAgIHZvaWQgcm90YXRlKEdMZmxvYXQgYSwgR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeik7Cit9OworCitlbnVtIHsKKyAgICBPUF9JREVOVElUWSAgICAgICAgID0gMHgwMCwKKyAgICBPUF9UUkFOU0xBVEUgICAgICAgID0gMHgwMSwKKyAgICBPUF9VTklGT1JNX1NDQUxFICAgID0gMHgwMiwKKyAgICBPUF9TQ0FMRSAgICAgICAgICAgID0gMHgwNSwKKyAgICBPUF9ST1RBVEUgICAgICAgICAgID0gMHgwOCwKKyAgICBPUF9TS0VXICAgICAgICAgICAgID0gMHgxMCwKKyAgICBPUF9BTEwgICAgICAgICAgICAgID0gMHgxRgorfTsKKworc3RydWN0IHRyYW5zZm9ybV90IHsKKyAgICBlbnVtIHsKKyAgICAgICAgRkxBR1NfMkRfUFJPSkVDVElPTiA9IDB4MQorICAgIH07CisgICAgbWF0cml4eF90ICAgICAgIG1hdHJpeDsKKyAgICB1aW50MzJfdCAgICAgICAgZmxhZ3M7CisgICAgdWludDMyX3QgICAgICAgIG9wczsKKyAgICAKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7CisgICAgICAgICAgICB2b2lkICgqcG9pbnQyKSh0cmFuc2Zvcm1fdCBjb25zdCogdCwgdmVjNF90KiwgdmVjNF90IGNvbnN0Kik7CisgICAgICAgICAgICB2b2lkICgqcG9pbnQzKSh0cmFuc2Zvcm1fdCBjb25zdCogdCwgdmVjNF90KiwgdmVjNF90IGNvbnN0Kik7CisgICAgICAgICAgICB2b2lkICgqcG9pbnQ0KSh0cmFuc2Zvcm1fdCBjb25zdCogdCwgdmVjNF90KiwgdmVjNF90IGNvbnN0Kik7CisgICAgICAgIH07CisgICAgICAgIHZvaWQgKCpwb2ludHZbM10pKHRyYW5zZm9ybV90IGNvbnN0KiB0LCB2ZWM0X3QqLCB2ZWM0X3QgY29uc3QqKTsKKyAgICB9OworCisgICAgdm9pZCBsb2FkSWRlbnRpdHkoKTsKKyAgICB2b2lkIHBpY2tlcigpOworICAgIHZvaWQgZHVtcChjb25zdCBjaGFyKiB3aGF0KTsKK307CisKK3N0cnVjdCBtdnVpX3RyYW5zZm9ybV90IDogcHVibGljIHRyYW5zZm9ybV90Cit7CisgICAgdm9pZCBwaWNrZXIoKTsKK307CisKK3N0cnVjdCBtYXRyaXhfc3RhY2tfdCB7CisgICAgZW51bSB7CisgICAgICAgIERPX1BJQ0tFUiAgICAgICAgICAgPSAweDEsCisgICAgICAgIERPX0ZMT0FUX1RPX0ZJWEVEICAgPSAweDIKKyAgICB9OworICAgIHRyYW5zZm9ybV90ICAgICB0cmFuc2Zvcm07CisgICAgdWludDhfdCAgICAgICAgIG1heERlcHRoOworICAgIHVpbnQ4X3QgICAgICAgICBkZXB0aDsKKyAgICB1aW50OF90ICAgICAgICAgZGlydHk7CisgICAgdWludDhfdCAgICAgICAgIHJlc2VydmVkOworICAgIG1hdHJpeGZfdCAgICAgICAqc3RhY2s7CisgICAgdWludDhfdCAgICAgICAgICpvcHM7CisgICAgdm9pZCBpbml0KGludCBkZXB0aCk7CisgICAgdm9pZCB1bmluaXQoKTsKKyAgICB2b2lkIGxvYWRJZGVudGl0eSgpOworICAgIHZvaWQgbG9hZChjb25zdCBHTGZpeGVkKiByaHMpOworICAgIHZvaWQgbG9hZChjb25zdCBHTGZsb2F0KiByaHMpOworICAgIHZvaWQgbXVsdGlwbHkoY29uc3QgbWF0cml4Zl90JiByaHMpOworICAgIHZvaWQgdHJhbnNsYXRlKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopOworICAgIHZvaWQgc2NhbGUoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeik7CisgICAgdm9pZCByb3RhdGUoR0xmbG9hdCBhLCBHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KTsKKyAgICBHTGludCBwdXNoKCk7CisgICAgR0xpbnQgcG9wKCk7CisgICAgdm9pZCB2YWxpZGF0ZSgpOworICAgIG1hdHJpeGZfdCYgdG9wKCkgeyByZXR1cm4gc3RhY2tbZGVwdGhdOyB9CisgICAgY29uc3QgbWF0cml4Zl90JiB0b3AoKSBjb25zdCB7IHJldHVybiBzdGFja1tkZXB0aF07IH0KKyAgICBjb25zdCB1aW50MzJfdCB0b3Bfb3BzKCkgY29uc3QgeyByZXR1cm4gb3BzW2RlcHRoXTsgfQorICAgIGlubGluZSBib29sIGlzUmlnaWRCb2R5KCkgY29uc3QgeworICAgICAgICByZXR1cm4gIShvcHNbZGVwdGhdICYgfihPUF9UUkFOU0xBVEV8T1BfVU5JRk9STV9TQ0FMRXxPUF9ST1RBVEUpKTsKKyAgICB9Cit9OworCitzdHJ1Y3QgdnBfdHJhbnNmb3JtX3QgeworICAgIHRyYW5zZm9ybV90ICAgICB0cmFuc2Zvcm07CisgICAgbWF0cml4Zl90ICAgICAgIG1hdHJpeDsKKyAgICBHTGZsb2F0ICAgICAgICAgek5lYXI7CisgICAgR0xmbG9hdCAgICAgICAgIHpGYXI7CisgICAgdm9pZCBsb2FkSWRlbnRpdHkoKTsKK307CisKK3N0cnVjdCB0cmFuc2Zvcm1fc3RhdGVfdCB7CisgICAgZW51bSB7CisgICAgICAgIE1PREVMVklFVyAgICAgICAgICAgPSAweDAxLAorICAgICAgICBQUk9KRUNUSU9OICAgICAgICAgID0gMHgwMiwKKyAgICAgICAgVklFV1BPUlQgICAgICAgICAgICA9IDB4MDQsCisgICAgICAgIFRFWFRVUkUgICAgICAgICAgICAgPSAweDA4LAorICAgICAgICBNVlVJICAgICAgICAgICAgICAgID0gMHgxMCwKKyAgICAgICAgTVZJVCAgICAgICAgICAgICAgICA9IDB4MjAsCisgICAgICAgIE1WUCAgICAgICAgICAgICAgICAgPSAweDQwLAorICAgIH07CisgICAgbWF0cml4X3N0YWNrX3QgICAgICAqY3VycmVudDsKKyAgICBtYXRyaXhfc3RhY2tfdCAgICAgIG1vZGVsdmlldzsKKyAgICBtYXRyaXhfc3RhY2tfdCAgICAgIHByb2plY3Rpb247CisgICAgbWF0cml4X3N0YWNrX3QgICAgICB0ZXh0dXJlW0dHTF9URVhUVVJFX1VOSVRfQ09VTlRdOworCisgICAgLy8gbW9kZWx2aWV3ICogcHJvamVjdGlvbgorICAgIHRyYW5zZm9ybV90ICAgICAgICAgbXZwICAgICBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDMyKSkpOworICAgIC8vIHZpZXdwb3J0IHRyYW5zZm9ybWF0aW9uCisgICAgdnBfdHJhbnNmb3JtX3QgICAgICB2cHQgICAgIF9fYXR0cmlidXRlX18oKGFsaWduZWQoMzIpKSk7CisgICAgLy8gc2FtZSBmb3IgNC1EIHZlcnRpY2VzCisgICAgdHJhbnNmb3JtX3QgICAgICAgICBtdnA0OworICAgIC8vIGZ1bGwgbW9kZWx2aWV3IGludmVyc2UgdHJhbnNwb3NlCisgICAgdHJhbnNmb3JtX3QgICAgICAgICBtdml0NDsKKyAgICAvLyB1cHBlciAzeDMgb2YgbXYtaW52ZXJzZS10cmFuc3Bvc2UgKGZvciBub3JtYWxzKQorICAgIG12dWlfdHJhbnNmb3JtX3QgICAgbXZ1aTsKKworICAgIEdMZW51bSAgICAgICAgICAgICAgbWF0cml4TW9kZTsKKyAgICBHTGVudW0gICAgICAgICAgICAgIHJlc2NhbGVOb3JtYWxzOworICAgIHVpbnQzMl90ICAgICAgICAgICAgZGlydHk7CisgICAgdm9pZCBpbnZhbGlkYXRlKCk7CisgICAgdm9pZCB1cGRhdGVfbXZwKCk7CisgICAgdm9pZCB1cGRhdGVfbXZpdCgpOworICAgIHZvaWQgdXBkYXRlX212dWkoKTsKK307CisKK3N0cnVjdCB2aWV3cG9ydF90IHsKKyAgICBHTGludCAgICAgICB4OworICAgIEdMaW50ICAgICAgIHk7CisgICAgR0xzaXplaSAgICAgdzsKKyAgICBHTHNpemVpICAgICBoOyAKKyAgICBzdHJ1Y3QgeworICAgICAgICBHTGludCAgICAgICB4OworICAgICAgICBHTGludCAgICAgICB5OworICAgIH0gc3VyZmFjZXBvcnQ7ICAKKyAgICBzdHJ1Y3QgeworICAgICAgICBHTGludCAgICAgICB4OworICAgICAgICBHTGludCAgICAgICB5OworICAgICAgICBHTHNpemVpICAgICB3OworICAgICAgICBHTHNpemVpICAgICBoOyAKKyAgICB9IHNjaXNzb3I7ICAKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIExlcnBpbmcKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RydWN0IGNvbXB1dGVfaXRlcmF0b3JzX3QKK3sKKyAgICB2b2lkIGluaXRUcmlhbmdsZSgKKyAgICAgICAgICAgIHZlcnRleF90IGNvbnN0KiB2MCwKKyAgICAgICAgICAgIHZlcnRleF90IGNvbnN0KiB2MSwKKyAgICAgICAgICAgIHZlcnRleF90IGNvbnN0KiB2Mik7CisKKyAgICB2b2lkIGluaXRMaW5lKAorICAgICAgICAgICAgdmVydGV4X3QgY29uc3QqIHYwLAorICAgICAgICAgICAgdmVydGV4X3QgY29uc3QqIHYxKTsKKworICAgIGlubGluZSB2b2lkIGluaXRMZXJwKHZlcnRleF90IGNvbnN0KiB2MCwgdWludDMyX3QgZW5hYmxlcyk7CisKKyAgICBpbnQgaXRlcmF0b3JzU2NhbGUoaW50MzJfdCBpdFszXSwKKyAgICAgICAgICAgIGludDMyX3QgYzAsIGludDMyX3QgYzEsIGludDMyX3QgYzIpIGNvbnN0OworCisgICAgdm9pZCBpdGVyYXRvcnMxNjE2KEdHTGZpeGVkIGl0WzNdLAorICAgICAgICAgICAgR0dMZml4ZWQgYzAsIEdHTGZpeGVkIGMxLCBHR0xmaXhlZCBjMikgY29uc3Q7CisKKyAgICB2b2lkIGl0ZXJhdG9yczAwMzIoaW50MzJfdCBpdFszXSwKKyAgICAgICAgICAgIGludDMyX3QgYzAsIGludDMyX3QgYzEsIGludDMyX3QgYzIpIGNvbnN0OworCisgICAgdm9pZCBpdGVyYXRvcnMwMDMyKGludDY0X3QgaXRbM10sCisgICAgICAgICAgICBpbnQzMl90IGMwLCBpbnQzMl90IGMxLCBpbnQzMl90IGMyKSBjb25zdDsKKworICAgIEdHTGNvb3JkIGFyZWEoKSBjb25zdCB7IHJldHVybiBtX2FyZWE7IH0KKworcHJpdmF0ZToKKyAgICAvLyBkb24ndCBjaGFuZ2Ugb3JkZXIgb2YgbWVtYmVycyBoZXJlIC0tIHVzZWQgYnkgaXRlcmF0b3JzLlMKKyAgICBHR0xjb29yZCBtX2R4MDEsIG1fZHkxMCwgbV9keDIwLCBtX2R5MDI7CisgICAgR0dMY29vcmQgbV94MCwgbV95MDsKKyAgICBHR0xjb29yZCBtX2FyZWE7CisgICAgdWludDhfdCBtX3NjYWxlOworICAgIHVpbnQ4X3QgbV9hcmVhX3NjYWxlOworICAgIHVpbnQ4X3QgbV9yZXNlcnZlZFsyXTsKKworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gc3RhdGUKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmZGVmIEhBVkVfQU5EUk9JRF9PUworICAgIC8vIFdlIGhhdmUgYSBkZWRpY2F0ZWQgVExTIHNsb3QgaW4gYmlvbmljCisgICAgaW5saW5lIHZvaWQgc2V0R2xUaHJlYWRTcGVjaWZpYyhvZ2xlc19jb250ZXh0X3QgKnZhbHVlKSB7CisgICAgICAgICgodWludDMyX3QgKilfX2dldF90bHMoKSlbVExTX1NMT1RfT1BFTkdMXSA9ICh1aW50MzJfdCl2YWx1ZTsKKyAgICB9CisgICAgaW5saW5lIG9nbGVzX2NvbnRleHRfdCogZ2V0R2xUaHJlYWRTcGVjaWZpYygpIHsKKyAgICAgICAgcmV0dXJuIChvZ2xlc19jb250ZXh0X3QgKikoKCh1bnNpZ25lZCAqKV9fZ2V0X3RscygpKVtUTFNfU0xPVF9PUEVOR0xdKTsKKyAgICB9CisjZWxzZQorICAgIGV4dGVybiBwdGhyZWFkX2tleV90IGdHTEtleTsKKyAgICBpbmxpbmUgdm9pZCBzZXRHbFRocmVhZFNwZWNpZmljKG9nbGVzX2NvbnRleHRfdCAqdmFsdWUpIHsKKyAgICAgICAgcHRocmVhZF9zZXRzcGVjaWZpYyhnR0xLZXksIHZhbHVlKTsKKyAgICB9CisgICAgaW5saW5lIG9nbGVzX2NvbnRleHRfdCogZ2V0R2xUaHJlYWRTcGVjaWZpYygpIHsKKyAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PG9nbGVzX2NvbnRleHRfdCo+KHB0aHJlYWRfZ2V0c3BlY2lmaWMoZ0dMS2V5KSk7CisgICAgfQorI2VuZGlmCisKKworc3RydWN0IHByaW1zX3QgeworICAgIHR5cGVkZWYgb2dsZXNfY29udGV4dF90KiBHTDsKKyAgICB2b2lkICgqcmVuZGVyUG9pbnQpKEdMLCB2ZXJ0ZXhfdCopOworICAgIHZvaWQgKCpyZW5kZXJMaW5lKShHTCwgdmVydGV4X3QqLCB2ZXJ0ZXhfdCopOworICAgIHZvaWQgKCpyZW5kZXJUcmlhbmdsZSkoR0wsIHZlcnRleF90KiwgdmVydGV4X3QqLCB2ZXJ0ZXhfdCopOworfTsKKworc3RydWN0IG9nbGVzX2NvbnRleHRfdCB7CisgICAgY29udGV4dF90ICAgICAgICAgICAgICAgcmFzdGVyaXplcjsKKyAgICBhcnJheV9tYWNoaW5lX3QgICAgICAgICBhcnJheXMgICAgICAgICBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDMyKSkpOworICAgIHRleHR1cmVfc3RhdGVfdCAgICAgICAgIHRleHR1cmVzOworICAgIHRyYW5zZm9ybV9zdGF0ZV90ICAgICAgIHRyYW5zZm9ybXM7CisgICAgdmVydGV4X2NhY2hlX3QgICAgICAgICAgdmM7CisgICAgcHJpbXNfdCAgICAgICAgICAgICAgICAgcHJpbXM7CisgICAgY3VsbGluZ190ICAgICAgICAgICAgICAgY3VsbDsKKyAgICBsaWdodGluZ190ICAgICAgICAgICAgICBsaWdodGluZzsKKyAgICB1c2VyX2NsaXBfcGxhbmVzX3QgICAgICBjbGlwUGxhbmVzOworICAgIGNvbXB1dGVfaXRlcmF0b3JzX3QgICAgIGxlcnA7ICAgICAgICAgICBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDMyKSkpOworICAgIHZlcnRleF90ICAgICAgICAgICAgICAgIGN1cnJlbnQ7CisgICAgdmVjNF90ICAgICAgICAgICAgICAgICAgY3VycmVudENvbG9yQ2xhbXBlZDsKKyAgICB2ZWMzX3QgICAgICAgICAgICAgICAgICBjdXJyZW50Tm9ybWFsOworICAgIHZpZXdwb3J0X3QgICAgICAgICAgICAgIHZpZXdwb3J0OworICAgIHBvaW50X3NpemVfdCAgICAgICAgICAgIHBvaW50OworICAgIGxpbmVfd2lkdGhfdCAgICAgICAgICAgIGxpbmU7CisgICAgcG9seWdvbl9vZmZzZXRfdCAgICAgICAgcG9seWdvbk9mZnNldDsKKyAgICBmb2dfdCAgICAgICAgICAgICAgICAgICBmb2c7CisgICAgdWludDMyX3QgICAgICAgICAgICAgICAgcGVyc3BlY3RpdmUgOiAxOworICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgIHRyYW5zZm9ybVRleHR1cmVzIDogMTsKKyAgICBFR0xTdXJmYWNlTWFuYWdlciogICAgICBzdXJmYWNlTWFuYWdlcjsKKyAgICBFR0xCdWZmZXJPYmplY3RNYW5hZ2VyKiBidWZmZXJPYmplY3RNYW5hZ2VyOworICAgIEdMZW51bSAgICAgICAgICAgICAgICAgIGVycm9yOworCisgICAgc3RhdGljIGlubGluZSBvZ2xlc19jb250ZXh0X3QqIGdldCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEdsVGhyZWFkU3BlY2lmaWMoKTsKKyAgICB9CisKK307CisKK307IC8vIG5hbWVzcGFjZSBnbAorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfT1BFTkdMRVNfQ09OVEVYVF9ICisKZGlmZiAtLWdpdCBhL2luY2x1ZGUvcHJpdmF0ZS91aS9MYXllclN0YXRlLmggYi9pbmNsdWRlL3ByaXZhdGUvdWkvTGF5ZXJTdGF0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2ZmNkODAKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3ByaXZhdGUvdWkvTGF5ZXJTdGF0ZS5oCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQ09NUE9TRVJfTEFZRVJfU1RBVEVfSAorI2RlZmluZSBBTkRST0lEX0NPTVBPU0VSX0xBWUVSX1NUQVRFX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisKKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUZsaW5nZXJDbGllbnQuaD4KKyNpbmNsdWRlIDx1aS9SZWdpb24uaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdWkvU2hhcmVkU3RhdGUuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBQYXJjZWw7CisKK3N0cnVjdCBsYXllcl9zdGF0ZV90IHsKKworICAgIGxheWVyX3N0YXRlX3QoKQorICAgICAgICA6ICAgc3VyZmFjZSgwKSwgd2hhdCgwKSwKKyAgICAgICAgICAgIHgoMCksIHkoMCksIHooMCksIHcoMCksIGgoMCksCisgICAgICAgICAgICBhbHBoYSgwKSwgdGludCgwKSwgZmxhZ3MoMCksIG1hc2soMCksCisgICAgICAgICAgICByZXNlcnZlZCgwKQorICAgIHsKKyAgICAgICAgbWF0cml4LmRzZHggPSBtYXRyaXguZHRkeSA9IDEuMGY7CisgICAgICAgIG1hdHJpeC5kc2R5ID0gbWF0cml4LmR0ZHggPSAwLjBmOworICAgIH0KKworICAgIHN0YXR1c190ICAgIHdyaXRlKFBhcmNlbCYgb3V0cHV0KSBjb25zdDsKKyAgICBzdGF0dXNfdCAgICByZWFkKGNvbnN0IFBhcmNlbCYgaW5wdXQpOworCisgICAgICAgICAgICBzdHJ1Y3QgbWF0cml4MjJfdCB7CisgICAgICAgICAgICAgICAgZmxvYXQgICBkc2R4OworICAgICAgICAgICAgICAgIGZsb2F0ICAgZHRkeDsKKyAgICAgICAgICAgICAgICBmbG9hdCAgIGRzZHk7CisgICAgICAgICAgICAgICAgZmxvYXQgICBkdGR5OworICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIFN1cmZhY2VJRCAgICAgICBzdXJmYWNlOworICAgICAgICAgICAgdWludDMyX3QgICAgICAgIHdoYXQ7CisgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgeDsKKyAgICAgICAgICAgIGludDMyX3QgICAgICAgICB5OworICAgICAgICAgICAgdWludDMyX3QgICAgICAgIHo7CisgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgdzsKKyAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICBoOworICAgICAgICAgICAgZmxvYXQgICAgICAgICAgIGFscGhhOworICAgICAgICAgICAgdWludDMyX3QgICAgICAgIHRpbnQ7CisgICAgICAgICAgICB1aW50OF90ICAgICAgICAgZmxhZ3M7CisgICAgICAgICAgICB1aW50OF90ICAgICAgICAgbWFzazsKKyAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICByZXNlcnZlZDsKKyAgICAgICAgICAgIG1hdHJpeDIyX3QgICAgICBtYXRyaXg7CisgICAgICAgICAgICAvLyBub24gUE9EIG11c3QgYmUgbGFzdC4gc2VlIHdyaXRlL3JlYWQKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgICAgICB0cmFuc3BhcmVudFJlZ2lvbjsKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0NPTVBPU0VSX0xBWUVSX1NUQVRFX0gKKwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9wcml2YXRlL3VpL1NoYXJlZFN0YXRlLmggYi9pbmNsdWRlL3ByaXZhdGUvdWkvU2hhcmVkU3RhdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDZkMGFkCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9wcml2YXRlL3VpL1NoYXJlZFN0YXRlLmgKQEAgLTAsMCArMSwxNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfVUlfU0hBUkVEX1NUQVRFX0gKKyNkZWZpbmUgQU5EUk9JRF9VSV9TSEFSRURfU1RBVEVfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFRoZXNlIHN0cnVjdHVyZXMgYXJlIHNoYXJlZCBiZXR3ZWVuIHRoZSBjb21wb3NlciBwcm9jZXNzIGFuZCBpdHMgY2xpZW50cworICovCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3Qgc3VyZmFjZV9pbmZvX3QgeyAvLyA0IGxvbmdzLCAxNiBieXRlcworICAgIGVudW0geworICAgICAgICBlQnVmZmVyRGlydHkgICAgPSAweDAxCisgICAgfTsKKyAgICB1aW50MTZfdCAgICB3OworICAgIHVpbnQxNl90ICAgIGg7CisgICAgdWludDE2X3QgICAgc3RyaWRlOworICAgIHVpbnQxNl90ICAgIGJwcjsKKyAgICB1aW50MTZfdCAgICByZXNlcnZlZDsKKyAgICB1aW50OF90ICAgICBmb3JtYXQ7CisgICAgdWludDhfdCAgICAgZmxhZ3M7CisgICAgc3NpemVfdCAgICAgYml0c19vZmZzZXQ7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgdWludDMyX3QgTlVNX0xBWUVSU19NQVggPSAzMTsKKworZW51bSB7IC8vIGxheWVyX2NibGtfdCBzd2FwU3RhdGUKKyAgICBlSW5kZXggICAgICAgICAgICAgID0gMHgwMDAwMDAwMSwKKyAgICBlRmxpcFJlcXVlc3RlZCAgICAgID0gMHgwMDAwMDAwMiwKKyAgICAKKyAgICBlUmVzaXplQnVmZmVyMCAgICAgID0gMHgwMDAwMDAwNCwKKyAgICBlUmVzaXplQnVmZmVyMSAgICAgID0gMHgwMDAwMDAwOCwgICAgCisgICAgZVJlc2l6ZVJlcXVlc3RlZCAgICA9IGVSZXNpemVCdWZmZXIwIHwgZVJlc2l6ZUJ1ZmZlcjEsCisgICAgCisgICAgZUJ1c3kgICAgICAgICAgICAgICA9IDB4MDAwMDAwMTAsCisgICAgZUxvY2tlZCAgICAgICAgICAgICA9IDB4MDAwMDAwMjAsCisgICAgZU5leHRGbGlwUGVuZGluZyAgICA9IDB4MDAwMDAwNDAsICAgIAorICAgIGVJbnZhbGlkU3VyZmFjZSAgICAgPSAweDAwMDAwMDgwCit9OworCitlbnVtIHsgLy8gbGF5ZXJfY2Jsa190IGZsYWdzCisgICAgZUxheWVyTm90UG9zdGVkICAgICA9IDB4MDAwMDAwMDEsCisgICAgZU5vQ29weUJhY2sgICAgICAgICA9IDB4MDAwMDAwMDIsCisgICAgZVJlc2VydmVkICAgICAgICAgICA9IDB4MDAwMDAwN0MsCisgICAgZUJ1ZmZlckluZGV4U2hpZnQgICA9IDcsCisgICAgZUJ1ZmZlckluZGV4ICAgICAgICA9IDE8PGVCdWZmZXJJbmRleFNoaWZ0LAorfTsKKworc3RydWN0IGZsYXRfcmVnaW9uX3QgICAgLy8gNDAgYnl0ZXMKK3sKKyAgICBpbnQzMl90ICAgICBjb3VudDsKKyAgICBpbnQxNl90ICAgICBsOworICAgIGludDE2X3QgICAgIHQ7CisgICAgaW50MTZfdCAgICAgcjsKKyAgICBpbnQxNl90ICAgICBiOworICAgIHVpbnQxNl90ICAgIHJ1bnNbMTRdOworfTsKKworc3RydWN0IGxheWVyX2NibGtfdCAgICAgLy8gKDEyOCBieXRlcykKK3sKKyAgICB2b2xhdGlsZSAgICBpbnQzMl90ICAgICAgICAgICAgIHN3YXBTdGF0ZTsgICAgICAvLyAgNAorICAgIHZvbGF0aWxlICAgIGludDMyX3QgICAgICAgICAgICAgZmxhZ3M7ICAgICAgICAgIC8vICA0CisgICAgdm9sYXRpbGUgICAgaW50MzJfdCAgICAgICAgICAgICBpZGVudGl0eTsgICAgICAgLy8gIDQKKyAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHJlc2VydmVkOyAgICAgICAvLyAgNAorICAgICAgICAgICAgICAgIHN1cmZhY2VfaW5mb190ICAgICAgc3VyZmFjZVsyXTsgICAgIC8vIDMyCisgICAgICAgICAgICAgICAgZmxhdF9yZWdpb25fdCAgICAgICByZWdpb25bMl07ICAgICAgLy8gODAKKworICAgIHN0YXRpYyBpbmxpbmUgaW50IGJhY2tCdWZmZXIodWludDMyX3Qgc3RhdGUpIHsKKyAgICAgICAgcmV0dXJuICgoc3RhdGUgJiBlSW5kZXgpIF4gKChzdGF0ZSAmIGVGbGlwUmVxdWVzdGVkKT4+MSkpOworICAgIH0KKyAgICBzdGF0aWMgaW5saW5lIGludCBmcm9udEJ1ZmZlcih1aW50MzJfdCBzdGF0ZSkgeworICAgICAgICByZXR1cm4gMSAtIGJhY2tCdWZmZXIoc3RhdGUpOworICAgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgcGVyX2NsaWVudF9jYmxrX3QgICAvLyA0S0IgbWF4Cit7CisgICAgICAgICAgICAgICAgTXV0ZXggICAgICAgICAgIGxvY2s7CisgICAgICAgICAgICAgICAgQ29uZGl0aW9uICAgICAgIGN2OworICAgICAgICAgICAgICAgIGxheWVyX2NibGtfdCAgICBsYXllcnNbTlVNX0xBWUVSU19NQVhdIF9fYXR0cmlidXRlX18oKGFsaWduZWQoMzIpKSk7CisKKyAgICBlbnVtIHsKKyAgICAgICAgQkxPQ0tJTkcgPSAweDAwMDAwMDAxLAorICAgICAgICBJTlNQRUNUICA9IDB4MDAwMDAwMDIKKyAgICB9OworCisgICAgcGVyX2NsaWVudF9jYmxrX3QoKTsKKworICAgIC8vIHRoZXNlIGZ1bmN0aW9ucyBhcmUgdXNlZCBieSB0aGUgY2xpZW50cworICAgIHN0YXR1c190IHZhbGlkYXRlKHNpemVfdCBpKSBjb25zdDsKKyAgICBpbnQzMl90IGxvY2tfbGF5ZXIoc2l6ZV90IGksIHVpbnQzMl90IGZsYWdzKTsKKyAgICB1aW50MzJfdCB1bmxvY2tfbGF5ZXJfYW5kX3Bvc3Qoc2l6ZV90IGkpOworICAgIHZvaWQgdW5sb2NrX2xheWVyKHNpemVfdCBpKTsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgdWludDMyX3QgTlVNX0RJU1BMQVlfTUFYID0gNDsKKworc3RydWN0IGRpc3BsYXlfY2Jsa190Cit7CisgICAgdWludDE2X3QgICAgdzsKKyAgICB1aW50MTZfdCAgICBoOworICAgIHVpbnQ4X3QgICAgIGZvcm1hdDsKKyAgICB1aW50OF90ICAgICBvcmllbnRhdGlvbjsKKyAgICB1aW50OF90ICAgICByZXNlcnZlZFsyXTsKKyAgICBmbG9hdCAgICAgICBmcHM7CisgICAgZmxvYXQgICAgICAgZGVuc2l0eTsKKyAgICBmbG9hdCAgICAgICB4ZHBpOworICAgIGZsb2F0ICAgICAgIHlkcGk7CisgICAgdWludDMyX3QgICAgcGFkWzJdOworfTsKKworc3RydWN0IHN1cmZhY2VfZmxpbmdlcl9jYmxrX3QgICAvLyA0S0IgbWF4Cit7CisgICAgc3VyZmFjZV9mbGluZ2VyX2NibGtfdCgpOworICAgIAorICAgIHVpbnQ4X3QgICAgICAgICBjb25uZWN0ZWQ7CisgICAgdWludDhfdCAgICAgICAgIHJlc2VydmVkWzNdOworICAgIHVpbnQzMl90ICAgICAgICBwYWRbN107CisgCisgICAgZGlzcGxheV9jYmxrX3QgIGRpc3BsYXlzW05VTV9ESVNQTEFZX01BWF07Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8Ym9vbD4gc3RydWN0IENUQTsKK3RlbXBsYXRlPD4gc3RydWN0IENUQTx0cnVlPiB7IH07CisKKy8vIGNvbXBpbGUtdGltZSBhc3NlcnRpb25zLiBqdXN0IHRvIGF2b2lkIGNhdGFzdHJvcGhlcy4KK2lubGluZSB2b2lkIGNvbXBpbGVfdGltZV9hc3NlcnRzKCkgeworICAgIENUQTxzaXplb2YobGF5ZXJfY2Jsa190KSA9PSAxMjg+IHNpemVvZl9fbGF5ZXJfY2Jsa190X19lcV8xMjg7CisgICAgKHZvaWQpc2l6ZW9mX19sYXllcl9jYmxrX3RfX2VxXzEyODsgLy8gd2UgZG9uJ3Qgd2FudCBhIHdhcm5pbmcKKyAgICBDVEE8c2l6ZW9mKHBlcl9jbGllbnRfY2Jsa190KSA8PSA0MDk2PiBzaXplb2ZfX3Blcl9jbGllbnRfY2Jsa190X19sZV80MDk2OworICAgICh2b2lkKXNpemVvZl9fcGVyX2NsaWVudF9jYmxrX3RfX2xlXzQwOTY7ICAvLyB3ZSBkb24ndCB3YW50IGEgd2FybmluZworICAgIENUQTxzaXplb2Yoc3VyZmFjZV9mbGluZ2VyX2NibGtfdCkgPD0gNDA5Nj4gc2l6ZW9mX19zdXJmYWNlX2ZsaW5nZXJfY2Jsa190X19sZV80MDk2OworICAgICh2b2lkKXNpemVvZl9fc3VyZmFjZV9mbGluZ2VyX2NibGtfdF9fbGVfNDA5NjsgIC8vIHdlIGRvbid0IHdhbnQgYSB3YXJuaW5nCit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX1VJX1NIQVJFRF9TVEFURV9ICisKZGlmZiAtLWdpdCBhL2luY2x1ZGUvcHJpdmF0ZS91aS9TdXJmYWNlRmxpbmdlclN5bmNocm8uaCBiL2luY2x1ZGUvcHJpdmF0ZS91aS9TdXJmYWNlRmxpbmdlclN5bmNocm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjkxYjYxCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9wcml2YXRlL3VpL1N1cmZhY2VGbGluZ2VyU3luY2hyby5oCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKKyNpZm5kZWYgQU5EUk9JRF9TVVJGQUNFX0ZMSU5HRVJfU1lOQ0hST19ICisjZGVmaW5lIEFORFJPSURfU1VSRkFDRV9GTElOR0VSX1NZTkNIUk9fSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlQ29tcG9zZXIuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBTdXJmYWNlRmxpbmdlcjsKKworY2xhc3MgU3VyZmFjZUZsaW5nZXJTeW5jaHJvCit7CitwdWJsaWM6CisKKyAgICAgICAgICAgICAgICAvLyBjbGllbnQgY29uc3RydWN0b3IKKyAgICAgICAgICAgICAgICBTdXJmYWNlRmxpbmdlclN5bmNocm8oY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIGZsaW5nZXIpOworICAgICAgICAgICAgICAgIH5TdXJmYWNlRmxpbmdlclN5bmNocm8oKTsKKyAgICAKKyAgICAgICAgICAgICAgICAvLyBzaWduYWwgc3VyZmFjZWZsaW5nZXIgZm9yIHNvbWUgd29yaworICAgIHN0YXR1c190ICAgIHNpZ25hbCgpOworICAgIAorcHJpdmF0ZToKKyAgICBjbGFzcyBCYXJyaWVyIHsKKyAgICBwdWJsaWM6CisgICAgICAgIEJhcnJpZXIoKTsKKyAgICAgICAgfkJhcnJpZXIoKTsKKyAgICAgICAgdm9pZCBvcGVuKCk7CisgICAgICAgIHZvaWQgY2xvc2UoKTsKKyAgICAgICAgdm9pZCB3YWl0QW5kQ2xvc2UoKTsKKyAgICAgICAgc3RhdHVzX3Qgd2FpdEFuZENsb3NlKG5zZWNzX3QgdGltZW91dCk7CisgICAgcHJpdmF0ZToKKyAgICAgICAgZW51bSB7IE9QRU5FRCwgQ0xPU0VEIH07CisgICAgICAgIG11dGFibGUgICAgIE11dGV4ICAgICAgIGxvY2s7CisgICAgICAgIG11dGFibGUgICAgIENvbmRpdGlvbiAgIGN2OworICAgICAgICB2b2xhdGlsZSAgICBpbnQgICAgICAgICBzdGF0ZTsKKyAgICB9OworCisgICAgZnJpZW5kIGNsYXNzIFN1cmZhY2VGbGluZ2VyOworCisgICAgICAgICAgICAgICAgLy8gc2VydmVyIGNvbnN0cnVjdG9yCisgICAgICAgICAgICAgICAgU3VyZmFjZUZsaW5nZXJTeW5jaHJvKCk7CisgICAgICAgICAgICAgICAgCisgICAgdm9pZCAgICAgICAgb3BlbigpOworICAgIAorICAgICAgICAgICAgICAgIC8vIHdhaXQgdW50aWwgdGhlcmUgaXMgc29tZSB3b3JrIHRvIGRvCisgICAgc3RhdHVzX3QgICAgd2FpdCgpOworICAgIHN0YXR1c190ICAgIHdhaXQobnNlY3NfdCB0aW1lb3V0KTsKKyAgICAKKyAgICBzcDxJU3VyZmFjZUNvbXBvc2VyPiBtU3VyZmFjZUNvbXBvc2VyOworICAgIEJhcnJpZXIgICAgICAgICAgICAgIG1CYXJyaWVyOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfU1VSRkFDRV9GTElOR0VSX1NZTkNIUk9fSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3ByaXZhdGUvdXRpbHMvU3RhdGljLmggYi9pbmNsdWRlL3ByaXZhdGUvdXRpbHMvU3RhdGljLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjE0MzliNwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvcHJpdmF0ZS91dGlscy9TdGF0aWMuaApAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gQWxsIHN0YXRpYyB2YXJpYWJsZXMgZ28gaGVyZSwgdG8gY29udHJvbCBpbml0aWFsaXphdGlvbiBhbmQKKy8vIGRlc3RydWN0aW9uIG9yZGVyIGluIHRoZSBsaWJyYXJ5LgorCisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0tleWVkVmVjdG9yLmg+CisKKyNpZm5kZWYgTElCVVRJTFNfTkFUSVZFCisjaW5jbHVkZSA8dXRpbHMvSUJpbmRlci5oPgorI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1dGlscy9Qcm9jZXNzU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNlbmRpZgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyBGb3IgVGV4dFN0cmVhbS5jcHAKK2V4dGVybiBWZWN0b3I8aW50MzJfdD4gZ1RleHRCdWZmZXJzOworCisvLyBGb3IgU3RyaW5nOC5jcHAKK2V4dGVybiB2b2lkIGluaXRpYWxpemVfc3RyaW5nOCgpOworZXh0ZXJuIHZvaWQgdGVybWluYXRlX3N0cmluZzgoKTsKKworLy8gRm9yIFN0cmluZzE2LmNwcAorZXh0ZXJuIHZvaWQgaW5pdGlhbGl6ZV9zdHJpbmcxNigpOworZXh0ZXJuIHZvaWQgdGVybWluYXRlX3N0cmluZzE2KCk7CisKKworCisjaWZuZGVmIExJQlVUSUxTX05BVElWRQorCisvLyBGb3IgUHJvY2Vzc1N0YXRlLmNwcAorZXh0ZXJuIE11dGV4IGdQcm9jZXNzTXV0ZXg7CitleHRlcm4gc3A8UHJvY2Vzc1N0YXRlPiBnUHJvY2VzczsKKworLy8gRm9yIFNlcnZpY2VNYW5hZ2VyLmNwcAorZXh0ZXJuIE11dGV4IGdEZWZhdWx0U2VydmljZU1hbmFnZXJMb2NrOworZXh0ZXJuIHNwPElTZXJ2aWNlTWFuYWdlcj4gZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlcjsKK2V4dGVybiBzcDxJUGVybWlzc2lvbkNvbnRyb2xsZXI+IGdQZXJtaXNzaW9uQ29udHJvbGxlcjsKKworI2VuZGlmCisKK30gICAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9wcml2YXRlL3V0aWxzL2JpbmRlcl9tb2R1bGUuaCBiL2luY2x1ZGUvcHJpdmF0ZS91dGlscy9iaW5kZXJfbW9kdWxlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmRmMzI3ZQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvcHJpdmF0ZS91dGlscy9iaW5kZXJfbW9kdWxlLmgKQEAgLTAsMCArMSwxNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIF9CSU5ERVJfTU9EVUxFX0hfCisjZGVmaW5lIF9CSU5ERVJfTU9EVUxFX0hfCisKKyNpZmRlZiBfX2NwbHVzcGx1cworbmFtZXNwYWNlIGFuZHJvaWQgeworI2VuZGlmCisKKyNpZiBkZWZpbmVkKEhBVkVfQU5EUk9JRF9PUykKKworLyogb2J0YWluIHN0cnVjdHVyZXMgYW5kIGNvbnN0YW50cyBmcm9tIHRoZSBrZXJuZWwgaGVhZGVyICovCisKKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKyNpbmNsdWRlIDxsaW51eC9iaW5kZXIuaD4KKworI2Vsc2UKKworLyogU29tZSBwYXJ0cyBvZiB0aGUgc2ltdWxhdG9yIG5lZWQgZmFrZSB2ZXJzaW9ucyBvZiB0aGlzIAorICogc3R1ZmYgaW4gb3JkZXIgdG8gY29tcGlsZS4gIFJlYWxseSB0aGlzIHNob3VsZCBnbyBhd2F5CisgKiBlbnRpcmVseS4uLgorICovCisKKyNkZWZpbmUgQklOREVSX0NVUlJFTlRfUFJPVE9DT0xfVkVSU0lPTiA3CisKKyNkZWZpbmUgQklOREVSX1RZUEVfQklOREVSIDEKKyNkZWZpbmUgQklOREVSX1RZUEVfV0VBS19CSU5ERVIgMgorI2RlZmluZSBCSU5ERVJfVFlQRV9IQU5ETEUgMworI2RlZmluZSBCSU5ERVJfVFlQRV9XRUFLX0hBTkRMRSA0CisjZGVmaW5lIEJJTkRFUl9UWVBFX0ZEIDUKKworc3RydWN0IGZsYXRfYmluZGVyX29iamVjdCB7CisgICAgdW5zaWduZWQgbG9uZyB0eXBlOworICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7CisgICAgdW5pb24geworICAgICAgICB2b2lkICpiaW5kZXI7CisgICAgICAgIHNpZ25lZCBsb25nIGhhbmRsZTsKKyAgICB9OworICAgIHZvaWQgKmNvb2tpZTsKK307CisKK3N0cnVjdCBiaW5kZXJfd3JpdGVfcmVhZCB7CisgICAgc2lnbmVkIGxvbmcgd3JpdGVfc2l6ZTsKKyAgICBzaWduZWQgbG9uZyB3cml0ZV9jb25zdW1lZDsKKyAgICB1bnNpZ25lZCBsb25nIHdyaXRlX2J1ZmZlcjsKKyAgICBzaWduZWQgbG9uZyByZWFkX3NpemU7CisgICAgc2lnbmVkIGxvbmcgcmVhZF9jb25zdW1lZDsKKyAgICB1bnNpZ25lZCBsb25nIHJlYWRfYnVmZmVyOworfTsKKworc3RydWN0IGJpbmRlcl90cmFuc2FjdGlvbl9kYXRhIHsKKyAgICB1bmlvbiB7CisgICAgICAgIHNpemVfdCBoYW5kbGU7CisgICAgICAgIHZvaWQgKnB0cjsKKyAgICB9IHRhcmdldDsKKyAgICB2b2lkICpjb29raWU7CisgICAgdW5zaWduZWQgaW50IGNvZGU7CisgICAgCisgICAgdW5zaWduZWQgaW50IGZsYWdzOworICAgIHBpZF90IHNlbmRlcl9waWQ7CisgICAgdWlkX3Qgc2VuZGVyX2V1aWQ7CisgICAgc2l6ZV90IGRhdGFfc2l6ZTsKKyAgICBzaXplX3Qgb2Zmc2V0c19zaXplOworICAgIAorICAgIHVuaW9uIHsKKyAgICAgICAgc3RydWN0IHsKKyAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlcjsKKyAgICAgICAgICAgIGNvbnN0IHZvaWQgKm9mZnNldHM7CisgICAgICAgIH0gcHRyOworICAgICAgICB1aW50OF90IGJ1Zls4XTsKKyAgICB9IGRhdGE7Cit9OworCitlbnVtIHRyYW5zYWN0aW9uX2ZsYWdzIHsKKyAgICBURl9PTkVfV0FZID0gMHgwMSwKKyAgICBURl9ST09UX09CSkVDVCA9IDB4MDQsCisgICAgVEZfU1RBVFVTX0NPREUgPSAweDA4LAorICAgIFRGX0FDQ0VQVF9GRFMgPSAweDEwLAorfTsKKworCitlbnVtIHsKKyAgICBGTEFUX0JJTkRFUl9GTEFHX1BSSU9SSVRZX01BU0sgPSAweGZmLAorICAgIEZMQVRfQklOREVSX0ZMQUdfQUNDRVBUU19GRFMgPSAweDEwMCwKK307CisKK2VudW0gQmluZGVyRHJpdmVyUmV0dXJuUHJvdG9jb2wgeworICAgIEJSX0VSUk9SLAorICAgIEJSX09LLAorICAgIEJSX1RSQU5TQUNUSU9OLAorICAgIEJSX1JFUExZLAorICAgIEJSX0FDUVVJUkVfUkVTVUxULAorICAgIEJSX0RFQURfUkVQTFksCisgICAgQlJfVFJBTlNBQ1RJT05fQ09NUExFVEUsCisgICAgQlJfSU5DUkVGUywKKyAgICBCUl9BQ1FVSVJFLAorICAgIEJSX1JFTEVBU0UsCisgICAgQlJfREVDUkVGUywKKyAgICBCUl9BVFRFTVBUX0FDUVVJUkUsCisgICAgQlJfTk9PUCwKKyAgICBCUl9TUEFXTl9MT09QRVIsCisgICAgQlJfRklOSVNIRUQsCisgICAgQlJfREVBRF9CSU5ERVIsCisgICAgQlJfQ0xFQVJfREVBVEhfTk9USUZJQ0FUSU9OX0RPTkUsCisgICAgQlJfRkFJTEVEX1JFUExZLAorfTsKKworZW51bSBCaW5kZXJEcml2ZXJDb21tYW5kUHJvdG9jb2wgeworICAgIEJDX1RSQU5TQUNUSU9OLAorICAgIEJDX1JFUExZLAorICAgIEJDX0FDUVVJUkVfUkVTVUxULAorICAgIEJDX0ZSRUVfQlVGRkVSLAorICAgIEJDX0lOQ1JFRlMsCisgICAgQkNfQUNRVUlSRSwKKyAgICBCQ19SRUxFQVNFLAorICAgIEJDX0RFQ1JFRlMsCisgICAgQkNfSU5DUkVGU19ET05FLAorICAgIEJDX0FDUVVJUkVfRE9ORSwKKyAgICBCQ19BVFRFTVBUX0FDUVVJUkUsCisgICAgQkNfUkVHSVNURVJfTE9PUEVSLAorICAgIEJDX0VOVEVSX0xPT1BFUiwKKyAgICBCQ19FWElUX0xPT1BFUiwKKyAgICBCQ19SRVFVRVNUX0RFQVRIX05PVElGSUNBVElPTiwKKyAgICBCQ19DTEVBUl9ERUFUSF9OT1RJRklDQVRJT04sCisgICAgQkNfREVBRF9CSU5ERVJfRE9ORSwKK307CisKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK30gICAvLyBuYW1lc3BhY2UgYW5kcm9pZAorI2VuZGlmCisKKyNlbmRpZiAvLyBfQklOREVSX01PRFVMRV9IXwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9wcml2YXRlL3V0aWxzL2Z1dGV4X3N5bmNocm8uaCBiL2luY2x1ZGUvcHJpdmF0ZS91dGlscy9mdXRleF9zeW5jaHJvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWMyYWIxOTk1Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9wcml2YXRlL3V0aWxzL2Z1dGV4X3N5bmNocm8uaApAQCAtMCwwICsxLDYwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBfRlVURVhfU1lOQ0hST19ICisjZGVmaW5lIF9GVVRFWF9TWU5DSFJPX0gKKworI2lmbmRlZiBIQVZFX0ZVVEVYCisjZXJyb3IgIkhBVkVfRlVURVggbm90IGRlZmluZWQiCisjZW5kaWYKKworI2RlZmluZSBGVVRFWF9XQUlUX0lORklOSVRFICgwKQorCit0eXBlZGVmIHN0cnVjdCBmdXRleF9tdXRleF90IGZ1dGV4X211dGV4X3Q7CisKK3N0cnVjdCBmdXRleF9tdXRleF90IAoreworICAgIHZvbGF0aWxlIGludCB2YWx1ZTsKK307CisKK3R5cGVkZWYgc3RydWN0IGZ1dGV4X2NvbmRfdCBmdXRleF9jb25kX3Q7CisKK3N0cnVjdCBmdXRleF9jb25kX3QgCit7CisgICAgdm9sYXRpbGUgaW50IHZhbHVlOworfTsKKworCisjaWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKK3ZvaWQgZnV0ZXhfbXV0ZXhfaW5pdChmdXRleF9tdXRleF90ICptKTsKK2ludCBmdXRleF9tdXRleF9sb2NrKGZ1dGV4X211dGV4X3QgKm0sIHVuc2lnbmVkIG1zZWMpOwordm9pZCBmdXRleF9tdXRleF91bmxvY2soZnV0ZXhfbXV0ZXhfdCAqbSk7CitpbnQgZnV0ZXhfbXV0ZXhfdHJ5bG9jayhmdXRleF9tdXRleF90ICptKTsKKwordm9pZCBmdXRleF9jb25kX2luaXQoZnV0ZXhfY29uZF90ICpjKTsKK2ludCBmdXRleF9jb25kX3dhaXQoZnV0ZXhfY29uZF90ICpjLCBmdXRleF9tdXRleF90ICptLCB1bnNpZ25lZCBtc2VjKTsKK3ZvaWQgZnV0ZXhfY29uZF9zaWduYWwoZnV0ZXhfY29uZF90ICpjKTsKK3ZvaWQgZnV0ZXhfY29uZF9icm9hZGNhc3QoZnV0ZXhfY29uZF90ICpjKTsKKworI2lmIF9fY3BsdXNwbHVzCit9IC8vIGV4dGVybiAiQyIKKyNlbmRpZgorCisjZW5kaWYgLy8gX0ZVVEVYX1NZTkNIUk9fSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0NhbWVyYS5oIGIvaW5jbHVkZS91aS9DYW1lcmEuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTkzZmVhCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9DYW1lcmEuaApAQCAtMCwwICsxLDE5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKiBDb3B5cmlnaHQgKEMpIDIwMDggSFRDIEluYy4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0hBUkRXQVJFX0NBTUVSQV9ICisjZGVmaW5lIEFORFJPSURfSEFSRFdBUkVfQ0FNRVJBX0gKKworI2luY2x1ZGUgPHVpL0lDYW1lcmFDbGllbnQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKgorICogQSBzZXQgb2YgYml0IG1hc2tzIGZvciBzcGVjaWZ5aW5nIGhvdyB0aGUgcmVjZWl2ZWQgcHJldmlldyBmcmFtZXMgYXJlCisgKiBoYW5kbGVkIGJlZm9yZSB0aGUgcHJldmlld0NhbGxiYWNrKCkgY2FsbC4KKyAqCisgKiBUaGUgbGVhc3Qgc2lnbmlmaWNhbnQgMyBiaXRzIG9mIGFuICJpbnQiIHZhbHVlIGFyZSB1c2VkIGZvciB0aGlzIHB1cnBvc2U6CisgKgorICogLi4uLi4gMCAwIDAKKyAqICAgICAgIF4gXiBeCisgKiAgICAgICB8IHwgfC0tLS0tLS0tLT4gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGNhbGxiYWNrIGlzIGVuYWJsZWQgb3Igbm90CisgKiAgICAgICB8IHwtLS0tLS0tLS0tLT4gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGNhbGxiYWNrIGlzIG9uZS1zaG90IG9yIG5vdAorICogICAgICAgfC0tLS0tLS0tLS0tLS0+IGRldGVybWluZSB3aGV0aGVyIHRoZSBmcmFtZSBpcyBjb3BpZWQgb3V0IG9yIG5vdAorICoKKyAqIFdBUk5JTkc6CisgKiBXaGVuIGEgZnJhbWUgaXMgc2VudCBkaXJlY3RseSB3aXRob3V0IGNvcHlpbmcsIGl0IGlzIHRoZSBmcmFtZSByZWNlaXZlcidzCisgKiByZXNwb25zaWJsaXR5IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBmcmFtZSBkYXRhIHdvbid0IGdldCBjb3JydXB0ZWQgYnkKKyAqIHN1YnNlcXVlbnQgcHJldmlldyBmcmFtZXMgZmlsbGVkIGJ5IHRoZSBjYW1lcmEuIFRoaXMgZmxhZyBpcyByZWNvbW1lbmRlZAorICogb25seSB3aGVuIGNvcHlpbmcgb3V0IGRhdGEgYnJpbmdzIHNpZ25pZmljYW50IHBlcmZvcm1hbmNlIHByaWNlIGFuZCB0aGUKKyAqIGhhbmRsaW5nL3Byb2Nlc3Npbmcgb2YgdGhlIHJlY2VpdmVkIGZyYW1lIGRhdGEgaXMgYWx3YXlzIGZhc3RlciB0aGFuCisgKiB0aGUgcHJldmlldyBmcmFtZSByYXRlIHNvIHRoYXQgZGF0YSBjb3JydXB0aW9uIHdvbid0IG9jY3VyLgorICoKKyAqIEZvciBpbnN0YW5jZSwKKyAqIDEuIDB4MDAgZGlzYWJsZXMgdGhlIGNhbGxiYWNrLiBJbiB0aGlzIGNhc2UsIGNvcHkgb3V0IGFuZCBvbmUgc2hvdCBiaXRzCisgKiAgICBhcmUgaWdub3JlZC4KKyAqIDIuIDB4MDEgZW5hYmxlcyBhIGNhbGxiYWNrIHdpdGhvdXQgY29weWluZyBvdXQgdGhlIHJlY2VpdmVkIGZyYW1lcy4gQQorICogICAgdHlwaWNhbCB1c2UgY2FzZSBpcyB0aGUgQ2FtY29yZGVyIGFwcGxpY2F0aW9uIHRvIGF2b2lkIG1ha2luZyBjb3N0bHkKKyAqICAgIGZyYW1lIGNvcGllcy4KKyAqIDMuIDB4MDUgaXMgZW5hYmxpbmcgYSBjYWxsYmFjayB3aXRoIGZyYW1lIGNvcGllZCBvdXQgcmVwZWF0ZWRseS4gQSB0eXBpY2FsCisgKiAgICB1c2UgY2FzZSBpcyB0aGUgQ2FtZXJhIGFwcGxpY2F0aW9uLgorICogNC4gMHgwNyBpcyBlbmFibGluZyBhIGNhbGxiYWNrIHdpdGggZnJhbWUgY29waWVkIG91dCBvbmx5IG9uY2UuIEEgdHlwaWNhbCB1c2UKKyAqICAgIGNhc2UgaXMgdGhlIEJhcmNvZGUgc2Nhbm5lciBhcHBsaWNhdGlvbi4KKyAqLworI2RlZmluZSBGUkFNRV9DQUxMQkFDS19GTEFHX0VOQUJMRV9NQVNLICAgICAgICAgICAgICAweDAxCisjZGVmaW5lIEZSQU1FX0NBTExCQUNLX0ZMQUdfT05FX1NIT1RfTUFTSyAgICAgICAgICAgIDB4MDIKKyNkZWZpbmUgRlJBTUVfQ0FMTEJBQ0tfRkxBR19DT1BZX09VVF9NQVNLICAgICAgICAgICAgMHgwNAorCisvLyBUeXBpY2FsIHVzZSBjYXNlcworI2RlZmluZSBGUkFNRV9DQUxMQkFDS19GTEFHX05PT1AgICAgICAgICAgICAgICAgICAgICAweDAwCisjZGVmaW5lIEZSQU1FX0NBTExCQUNLX0ZMQUdfQ0FNQ09SREVSICAgICAgICAgICAgICAgIDB4MDEKKyNkZWZpbmUgRlJBTUVfQ0FMTEJBQ0tfRkxBR19DQU1FUkEgICAgICAgICAgICAgICAgICAgMHgwNQorI2RlZmluZSBGUkFNRV9DQUxMQkFDS19GTEFHX0JBUkNPREVfU0NBTk5FUiAgICAgICAgICAweDA3CisKK2NsYXNzIElDYW1lcmFTZXJ2aWNlOworY2xhc3MgSUNhbWVyYTsKK2NsYXNzIFN1cmZhY2U7CitjbGFzcyBNdXRleDsKK2NsYXNzIFN0cmluZzg7CisKK3R5cGVkZWYgdm9pZCAoKnNodXR0ZXJfY2FsbGJhY2spKHZvaWQgKmNvb2tpZSk7Cit0eXBlZGVmIHZvaWQgKCpmcmFtZV9jYWxsYmFjaykoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCAqY29va2llKTsKK3R5cGVkZWYgdm9pZCAoKmF1dG9mb2N1c19jYWxsYmFjaykoYm9vbCBmb2N1c2VkLCB2b2lkICpjb29raWUpOwordHlwZWRlZiB2b2lkICgqZXJyb3JfY2FsbGJhY2spKHN0YXR1c190IGVyciwgdm9pZCAqY29va2llKTsKKworY2xhc3MgQ2FtZXJhIDogcHVibGljIEJuQ2FtZXJhQ2xpZW50LCBwdWJsaWMgSUJpbmRlcjo6RGVhdGhSZWNpcGllbnQKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgIC8vIGNvbnN0cnVjdCBhIGNhbWVyYSBjbGllbnQgZnJvbSBhbiBleGlzdGluZyByZW1vdGUKKyAgICAgICAgICAgIENhbWVyYShjb25zdCBzcDxJQ2FtZXJhPiYgY2FtZXJhKTsKKworICAgIHN0YXRpYyAgc3A8Q2FtZXJhPiAgY29ubmVjdCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfkNhbWVyYSgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgaW5pdCgpOworCisgICAgICAgICAgICBzdGF0dXNfdCAgICByZWNvbm5lY3QoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgIGxvY2soKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHVubG9jaygpOworCisgICAgICAgICAgICBzdGF0dXNfdCAgICBnZXRTdGF0dXMoKSB7IHJldHVybiBtU3RhdHVzOyB9CisKKyAgICAgICAgICAgIC8vIHBhc3MgdGhlIGJ1ZmZlcmVkIElTdXJmYWNlIHRvIHRoZSBjYW1lcmEgc2VydmljZQorICAgICAgICAgICAgc3RhdHVzX3QgICAgc2V0UHJldmlld0Rpc3BsYXkoY29uc3Qgc3A8U3VyZmFjZT4mIHN1cmZhY2UpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgc2V0UHJldmlld0Rpc3BsYXkoY29uc3Qgc3A8SVN1cmZhY2U+JiBzdXJmYWNlKTsKKworICAgICAgICAgICAgLy8gc3RhcnQgcHJldmlldyBtb2RlLCBtdXN0IGNhbGwgc2V0UHJldmlld0Rpc3BsYXkgZmlyc3QKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHN0YXJ0UHJldmlldygpOworCisgICAgICAgICAgICAvLyBzdG9wIHByZXZpZXcgbW9kZQorICAgICAgICAgICAgdm9pZCAgICAgICAgc3RvcFByZXZpZXcoKTsKKworICAgICAgICAgICAgLy8gZ2V0IHByZXZpZXcgc3RhdGUKKyAgICAgICAgICAgIGJvb2wgICAgICAgIHByZXZpZXdFbmFibGVkKCk7CisKKyAgICAgICAgICAgIC8vIHN0YXJ0IHJlY29yZGluZyBtb2RlLCBtdXN0IGNhbGwgc2V0UHJldmlld0Rpc3BsYXkgZmlyc3QKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHN0YXJ0UmVjb3JkaW5nKCk7CisKKyAgICAgICAgICAgIC8vIHN0b3AgcmVjb3JkaW5nIG1vZGUKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHN0b3BSZWNvcmRpbmcoKTsKKworICAgICAgICAgICAgLy8gZ2V0IHJlY29yZGluZyBzdGF0ZQorICAgICAgICAgICAgYm9vbCAgICAgICAgcmVjb3JkaW5nRW5hYmxlZCgpOworCisgICAgICAgICAgICAvLyByZWxlYXNlIGEgcmVjb3JkaW5nIGZyYW1lCisgICAgICAgICAgICB2b2lkICAgICAgICByZWxlYXNlUmVjb3JkaW5nRnJhbWUoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSk7CisKKyAgICAgICAgICAgIC8vIGF1dG9Gb2N1cyAtIHN0YXR1cyByZXR1cm5lZCBmcm9tIGNhbGxiYWNrCisgICAgICAgICAgICBzdGF0dXNfdCAgICBhdXRvRm9jdXMoKTsKKworICAgICAgICAgICAgLy8gdGFrZSBhIHBpY3R1cmUgLSBwaWN0dXJlIHJldHVybmVkIGZyb20gY2FsbGJhY2sKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHRha2VQaWN0dXJlKCk7CisKKyAgICAgICAgICAgIC8vIHNldCBwcmV2aWV3L2NhcHR1cmUgcGFyYW1ldGVycyAtIGtleS92YWx1ZSBwYWlycworICAgICAgICAgICAgc3RhdHVzX3QgICAgc2V0UGFyYW1ldGVycyhjb25zdCBTdHJpbmc4JiBwYXJhbXMpOworCisgICAgICAgICAgICAvLyBnZXQgcHJldmlldy9jYXB0dXJlIHBhcmFtZXRlcnMgLSBrZXkvdmFsdWUgcGFpcnMKKyAgICAgICAgICAgIFN0cmluZzggICAgIGdldFBhcmFtZXRlcnMoKSBjb25zdDsKKworICAgICAgICAgICAgdm9pZCAgICAgICAgc2V0U2h1dHRlckNhbGxiYWNrKHNodXR0ZXJfY2FsbGJhY2sgY2IsIHZvaWQgKmNvb2tpZSk7CisgICAgICAgICAgICB2b2lkICAgICAgICBzZXRSYXdDYWxsYmFjayhmcmFtZV9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHNldEpwZWdDYWxsYmFjayhmcmFtZV9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHNldFJlY29yZGluZ0NhbGxiYWNrKGZyYW1lX2NhbGxiYWNrIGNiLCB2b2lkICpjb29raWUpOworICAgICAgICAgICAgdm9pZCAgICAgICAgc2V0UHJldmlld0NhbGxiYWNrKGZyYW1lX2NhbGxiYWNrIGNiLCB2b2lkICpjb29raWUsIGludCBwcmV2aWV3X2NhbGxiYWNrX2ZsYWcgPSBGUkFNRV9DQUxMQkFDS19GTEFHX05PT1ApOworICAgICAgICAgICAgdm9pZCAgICAgICAgc2V0RXJyb3JDYWxsYmFjayhlcnJvcl9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHNldEF1dG9Gb2N1c0NhbGxiYWNrKGF1dG9mb2N1c19jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKTsKKworICAgIC8vIElDYW1lcmFDbGllbnQgaW50ZXJmYWNlCisgICAgdmlydHVhbCB2b2lkICAgICAgICBzaHV0dGVyQ2FsbGJhY2soKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHJhd0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBwaWN0dXJlKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGpwZWdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgcGljdHVyZSk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBwcmV2aWV3Q2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIGZyYW1lKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGVycm9yQ2FsbGJhY2soc3RhdHVzX3QgZXJyb3IpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgYXV0b0ZvY3VzQ2FsbGJhY2soYm9vbCBmb2N1c2VkKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHJlY29yZGluZ0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBmcmFtZSk7CisKKyAgICBzcDxJQ2FtZXJhPiAgICAgICAgIHJlbW90ZSgpOworCitwcml2YXRlOgorICAgICAgICAgICAgICAgICAgICAgICAgQ2FtZXJhKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB2aXJ0dWFsIHZvaWQgYmluZGVyRGllZChjb25zdCB3cDxJQmluZGVyPiYgd2hvKTsKKworICAgICAgICAgICAgY2xhc3MgRGVhdGhOb3RpZmllcjogcHVibGljIElCaW5kZXI6OkRlYXRoUmVjaXBpZW50CisgICAgICAgICAgICB7CisgICAgICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgRGVhdGhOb3RpZmllcigpIHsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB2aXJ0dWFsIHZvaWQgYmluZGVyRGllZChjb25zdCB3cDxJQmluZGVyPiYgd2hvKTsKKyAgICAgICAgICAgIH07CisKKyAgICAgICAgICAgIHN0YXRpYyBzcDxEZWF0aE5vdGlmaWVyPiBtRGVhdGhOb3RpZmllcjsKKworICAgICAgICAgICAgLy8gaGVscGVyIGZ1bmN0aW9uIHRvIG9idGFpbiBjYW1lcmEgc2VydmljZSBoYW5kbGUKKyAgICAgICAgICAgIHN0YXRpYyBjb25zdCBzcDxJQ2FtZXJhU2VydmljZT4mIGdldENhbWVyYVNlcnZpY2UoKTsKKworICAgICAgICAgICAgc3A8SUNhbWVyYT4gICAgICAgICBtQ2FtZXJhOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBtU3RhdHVzOworCisgICAgICAgICAgICBzaHV0dGVyX2NhbGxiYWNrICAgIG1TaHV0dGVyQ2FsbGJhY2s7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgICptU2h1dHRlckNhbGxiYWNrQ29va2llOworICAgICAgICAgICAgZnJhbWVfY2FsbGJhY2sgICAgICBtUmF3Q2FsbGJhY2s7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgICptUmF3Q2FsbGJhY2tDb29raWU7CisgICAgICAgICAgICBmcmFtZV9jYWxsYmFjayAgICAgIG1KcGVnQ2FsbGJhY2s7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgICptSnBlZ0NhbGxiYWNrQ29va2llOworICAgICAgICAgICAgZnJhbWVfY2FsbGJhY2sgICAgICBtUHJldmlld0NhbGxiYWNrOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAqbVByZXZpZXdDYWxsYmFja0Nvb2tpZTsKKyAgICAgICAgICAgIGZyYW1lX2NhbGxiYWNrICAgICAgbVJlY29yZGluZ0NhbGxiYWNrOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAqbVJlY29yZGluZ0NhbGxiYWNrQ29va2llOworICAgICAgICAgICAgZXJyb3JfY2FsbGJhY2sgICAgICBtRXJyb3JDYWxsYmFjazsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgKm1FcnJvckNhbGxiYWNrQ29va2llOworICAgICAgICAgICAgYXV0b2ZvY3VzX2NhbGxiYWNrICBtQXV0b0ZvY3VzQ2FsbGJhY2s7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgICptQXV0b0ZvY3VzQ2FsbGJhY2tDb29raWU7CisKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBEZWF0aE5vdGlmaWVyOworCisgICAgICAgICAgICBzdGF0aWMgIE11dGV4ICAgICAgICAgICAgICAgbUxvY2s7CisgICAgICAgICAgICBzdGF0aWMgIHNwPElDYW1lcmFTZXJ2aWNlPiAgbUNhbWVyYVNlcnZpY2U7CisKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0NhbWVyYUhhcmR3YXJlSW50ZXJmYWNlLmggYi9pbmNsdWRlL3VpL0NhbWVyYUhhcmR3YXJlSW50ZXJmYWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzMwMzZmMAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvQ2FtZXJhSGFyZHdhcmVJbnRlcmZhY2UuaApAQCAtMCwwICsxLDE5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9IQVJEV0FSRV9DQU1FUkFfSEFSRFdBUkVfSU5URVJGQUNFX0gKKyNkZWZpbmUgQU5EUk9JRF9IQVJEV0FSRV9DQU1FUkFfSEFSRFdBUkVfSU5URVJGQUNFX0gKKworI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dWkvQ2FtZXJhUGFyYW1ldGVycy5oPgorI2luY2x1ZGUgPHVpL092ZXJsYXkuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKiogQ2FsbGJhY2sgZm9yIHN0YXJ0UHJldmlldygpICovCit0eXBlZGVmIHZvaWQgKCpwcmV2aWV3X2NhbGxiYWNrKShjb25zdCBzcDxJTWVtb3J5PiYgbWVtLCB2b2lkKiB1c2VyKTsKKworLyoqIENhbGxiYWNrIGZvciBzdGFydFJlY29yZCgpICovCit0eXBlZGVmIHZvaWQgKCpyZWNvcmRpbmdfY2FsbGJhY2spKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0sIHZvaWQqIHVzZXIpOworCisvKiogQ2FsbGJhY2sgZm9yIHRha2VQaWN0dXJlKCkgKi8KK3R5cGVkZWYgdm9pZCAoKnNodXR0ZXJfY2FsbGJhY2spKHZvaWQqIHVzZXIpOworCisvKiogQ2FsbGJhY2sgZm9yIHRha2VQaWN0dXJlKCkgKi8KK3R5cGVkZWYgdm9pZCAoKnJhd19jYWxsYmFjaykoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCogdXNlcik7CisKKy8qKiBDYWxsYmFjayBmb3IgdGFrZVBpY3R1cmUoKSAqLwordHlwZWRlZiB2b2lkICgqanBlZ19jYWxsYmFjaykoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSwgdm9pZCogdXNlcik7CisKKy8qKiBDYWxsYmFjayBmb3IgYXV0b0ZvY3VzKCkgKi8KK3R5cGVkZWYgdm9pZCAoKmF1dG9mb2N1c19jYWxsYmFjaykoYm9vbCBmb2N1c2VkLCB2b2lkKiB1c2VyKTsKKworLyoqCisgKiBDYW1lcmFIYXJkd2FyZUludGVyZmFjZS5oIGRlZmluZXMgdGhlIGludGVyZmFjZSB0byB0aGUKKyAqIGNhbWVyYSBoYXJkd2FyZSBhYnN0cmFjdGlvbiBsYXllciwgdXNlZCBmb3Igc2V0dGluZyBhbmQgZ2V0dGluZworICogcGFyYW1ldGVycywgbGl2ZSBwcmV2aWV3aW5nLCBhbmQgdGFraW5nIHBpY3R1cmVzLgorICoKKyAqIEl0IGlzIGEgcmVmZXJlbmNlZCBjb3VudGVkIGludGVyZmFjZSB3aXRoIFJlZkJhc2UgYXMgaXRzIGJhc2UgY2xhc3MuCisgKiBDYW1lcmFTZXJ2aWNlIGNhbGxzIG9wZW5DYW1lcmFIYXJkd2FyZSgpIHRvIHJldHJpZXZlIGEgc3Ryb25nIHBvaW50ZXIgdG8gdGhlCisgKiBpbnN0YW5jZSBvZiB0aGlzIGludGVyZmFjZSBhbmQgbWF5IGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcy4gVGhlCisgKiBmb2xsb3dpbmcgc3RlcHMgZGVzY3JpYmUgYSB0eXBpY2FsIHNlcXVlbmNlOgorICoKKyAqICAgLSMgQWZ0ZXIgQ2FtZXJhU2VydmljZSBjYWxscyBvcGVuQ2FtZXJhSGFyZHdhcmUoKSwgZ2V0UGFyYW1ldGVycygpIGFuZAorICogICAgICBzZXRQYXJhbWV0ZXJzKCkgYXJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGUgY2FtZXJhIGluc3RhbmNlLgorICogICAgICBDYW1lcmFTZXJ2aWNlIGNhbGxzIGdldFByZXZpZXdIZWFwKCkgdG8gZXN0YWJsaXNoIGFjY2VzcyB0byB0aGUKKyAqICAgICAgcHJldmlldyBoZWFwIHNvIGl0IGNhbiBiZSByZWdpc3RlcmVkIHdpdGggU3VyZmFjZUZsaW5nZXIgZm9yCisgKiAgICAgIGVmZmljaWVudCBkaXNwbGF5IHVwZGF0aW5nIHdoaWxlIGluIHByZXZpZXcgbW9kZS4KKyAqICAgLSMgc3RhcnRQcmV2aWV3KCkgaXMgY2FsbGVkLCB3aGljaCBpcyBwYXNzZWQgYSBwcmV2aWV3X2NhbGxiYWNrKCkKKyAqICAgICAgZnVuY3Rpb24gYW5kIGEgdXNlciBwYXJhbWV0ZXIuIFRoZSBjYW1lcmEgaW5zdGFuY2UgdGhlbiBwZXJpb2RpY2FsbHkKKyAqICAgICAgY2FsbHMgcHJldmlld19jYWxsYmFjaygpIGVhY2ggdGltZSBhIG5ldyBwcmV2aWV3IGZyYW1lIGlzIGF2YWlsYWJsZS4KKyAqICAgICAgVGhlIGNhbGxiYWNrIHJvdXRpbmUgaGFzIHR3byBwYXJhbWV0ZXJzOiB0aGUgZmlyc3QgaXMgYSBwb2ludGVyIHRvCisgKiAgICAgIHRoZSBJTWVtb3J5IGNvbnRhaW5pbmcgdGhlIGZyYW1lIGFuZCB0aGUgc2Vjb25kIGEgdXNlciBwYXJhbWV0ZXIuIElmCisgKiAgICAgIHRoZSBwcmV2aWV3X2NhbGxiYWNrIGNvZGUgbmVlZHMgdG8gdXNlIHRoaXMgbWVtb3J5IGFmdGVyIHJldHVybmluZywKKyAqICAgICAgaXQgbXVzdCBjb3B5IHRoZSBkYXRhLgorICoKKyAqIFByaW9yIHRvIHRha2luZyBhIHBpY3R1cmUsIENhbWVyYVNlcnZpY2UgY2FsbHMgYXV0b2ZvY3VzKCkgd2l0aAorICogYXV0b2ZvY3VzX2NhbGxiYWNrKCkgYW5kIGEgdXNlciBwYXJhbWV0ZXIuIFdoZW4gYXV0byBmb2N1c2luZyBoYXMKKyAqIGNvbXBsZXRlZCwgdGhlIGNhbWVyYSBpbnN0YW5jZSBjYWxscyBhdXRvZm9jdXNfY2FsbGJhY2soKSwgd2hpY2ggaW5mb3JtcworICogdGhlIGFwcGxpY2F0aW9uIHdoZXRoZXIgZm9jdXNpbmcgd2FzIHN1Y2Nlc3NmdWwuIFRoZSBjYW1lcmEgaW5zdGFuY2UKKyAqIG9ubHkgY2FsbHMgYXV0b2ZvY3VzX2NhbGxiYWNrKCkgb25jZSBhbmQgaXQgaXMgdXAgdG8gdGhlIGFwcGxpY2F0aW9uIHRvCisgKiBjYWxsIGF1dG9Gb2N1cygpIGFnYWluIGlmIHJlZm9jdXNpbmcgaXMgZGVzaXJlZC4KKyAqCisgKiBDYW1lcmFTZXJ2aWNlIGNhbGxzIHRha2VQaWN0dXJlKCkgdG8gcmVxdWVzdCB0aGUgY2FtZXJhIGluc3RhbmNlIHRha2UgYQorICogcGljdHVyZS4gVGhpcyBtZXRob2QgaGFzIHR3byBjYWxsYmFja3M6IHJhd19jYWxsYmFjaygpIGFuZCBqcGVnX2NhbGxiYWNrKCkuCisgKiBXaGVuIHRoZSByYXcgaW1hZ2UgaXMgYXZhaWxhYmxlLCByYXdfY2FsbGJhY2soKSBpcyBjYWxsZWQgd2l0aCBhIHBvaW50ZXIKKyAqIHRvIHRoZSBJTWVtb3J5IGNvbnRhaW5pbmcgdGhlIHJhdyBpbWFnZS4gV2hlbiB0aGUganBlZyBpbWFnZSBpcyBhdmFpbGFibGUsCisgKiBqcGVnX2NhbGxiYWNrKCkgaXMgY2FsbGVkIHdpdGggYSBwb2ludGVyIHRvIHRoZSBJTWVtb3J5IGNvbnRhaW5pbmcgdGhlCisgKiBqcGVnIGltYWdlLiBBcyB3aXRoIHByZXZpZXdfY2FsbGJhY2soKSwgdGhlIG1lbW9yeSBtdXN0IGJlIGNvcGllZCBpZiBpdCdzCisgKiBuZWVkZWQgYWZ0ZXIgcmV0dXJuaW5nLgorICovCitjbGFzcyBDYW1lcmFIYXJkd2FyZUludGVyZmFjZSA6IHB1YmxpYyB2aXJ0dWFsIFJlZkJhc2UgeworcHVibGljOgorICAgIHZpcnR1YWwgfkNhbWVyYUhhcmR3YXJlSW50ZXJmYWNlKCkgeyB9CisKKyAgICAvKiogUmV0dXJuIHRoZSBJTWVtb3J5SGVhcCBmb3IgdGhlIHByZXZpZXcgaW1hZ2UgaGVhcCAqLworICAgIHZpcnR1YWwgc3A8SU1lbW9yeUhlYXA+ICAgICAgICAgZ2V0UHJldmlld0hlYXAoKSBjb25zdCA9IDA7CisKKyAgICAvKiogUmV0dXJuIHRoZSBJTWVtb3J5SGVhcCBmb3IgdGhlIHJhdyBpbWFnZSBoZWFwICovCisgICAgdmlydHVhbCBzcDxJTWVtb3J5SGVhcD4gICAgICAgICBnZXRSYXdIZWFwKCkgY29uc3QgPSAwOworCisgICAgLyoqCisgICAgICogU3RhcnQgcHJldmlldyBtb2RlLiBXaGVuIGEgcHJldmlldyBpbWFnZSBpcyBhdmFpbGFibGUKKyAgICAgKiBwcmV2aWV3X2NhbGxiYWNrIGlzIGNhbGxlZCB3aXRoIHRoZSB1c2VyIHBhcmFtZXRlci4gVGhlCisgICAgICogY2FsbCBiYWNrIHBhcmFtZXRlciBtYXkgYmUgbnVsbC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHN0YXJ0UHJldmlldyhwcmV2aWV3X2NhbGxiYWNrIGNiLCB2b2lkKiB1c2VyKSA9IDA7CisgICAgLyoqCisgICAgICogT25seSB1c2VkIGlmIG92ZXJsYXlzIGFyZSB1c2VkIGZvciBjYW1lcmEgcHJldmlldy4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIGJvb2wgdXNlT3ZlcmxheSgpIHtyZXR1cm4gZmFsc2U7fQorICAgIHZpcnR1YWwgc3RhdHVzX3Qgc2V0T3ZlcmxheShjb25zdCBzcDxPdmVybGF5PiAmb3ZlcmxheSkge3JldHVybiBCQURfVkFMVUU7fQorCisgICAgLyoqCisgICAgICogU3RvcCBhIHByZXZpb3VzbHkgc3RhcnRlZCBwcmV2aWV3LgorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcFByZXZpZXcoKSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcHJldmlldyBpcyBlbmFibGVkLgorICAgICAqLworICAgIHZpcnR1YWwgYm9vbCAgICAgICAgcHJldmlld0VuYWJsZWQoKSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGFydCByZWNvcmQgbW9kZS4gV2hlbiBhIHJlY29yZCBpbWFnZSBpcyBhdmFpbGFibGUgcmVjb3JkaW5nX2NhbGxiYWNrKCkKKyAgICAgKiBpcyBjYWxsZWQgd2l0aCB0aGUgdXNlciBwYXJhbWV0ZXIuICBFdmVyeSByZWNvcmQgZnJhbWUgbXVzdCBiZSByZWxlYXNlZAorICAgICAqIGJ5IGNhbGxpbmcgcmVsZWFzZVJlY29yZGluZ0ZyYW1lKCkuCisgICAgICovCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFydFJlY29yZGluZyhyZWNvcmRpbmdfY2FsbGJhY2sgY2IsIHZvaWQqIHVzZXIpID0gMDsKKworICAgIC8qKgorICAgICAqIFN0b3AgYSBwcmV2aW91c2x5IHN0YXJ0ZWQgcmVjb3JkaW5nLgorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcFJlY29yZGluZygpID0gMDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiByZWNvcmRpbmcgaXMgZW5hYmxlZC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgIHJlY29yZGluZ0VuYWJsZWQoKSA9IDA7CisgICAgCisgICAgLyoqCisgICAgICogUmVsZWFzZSBhIHJlY29yZCBmcmFtZSBwcmV2aW91c2x5IHJldHVybmVkIGJ5IHRoZSByZWNvcmRpbmdfY2FsbGJhY2soKQorICAgICAqIHBhc3NlZCB0byBzdGFydFJlY29yZCgpLgorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgcmVsZWFzZVJlY29yZGluZ0ZyYW1lKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0pID0gMDsKKworICAgIC8qKgorICAgICAqIFN0YXJ0IGF1dG8gZm9jdXMsIHRoZSBjYWxsYmFjayByb3V0aW5lIGlzIGNhbGxlZAorICAgICAqIG9uY2Ugd2hlbiBmb2N1c2luZyBpcyBjb21wbGV0ZS4gYXV0b0ZvY3VzKCkgd2lsbAorICAgICAqIGJlIGNhbGxlZCBhZ2FpbiBpZiBhbm90aGVyIGF1dG8gZm9jdXMgaXMgbmVlZGVkLgorICAgICAqLworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgYXV0b0ZvY3VzKGF1dG9mb2N1c19jYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiB1c2VyKSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUYWtlIGEgcGljdHVyZS4gVGhlIHJhd19jYWxsYmFjayBpcyBjYWxsZWQgd2hlbgorICAgICAqIHRoZSB1bmNvbXByZXNzZWQgaW1hZ2UgaXMgYXZhaWxhYmxlLiBUaGUganBlZ19jYWxsYmFjaworICAgICAqIGlzIGNhbGxlZCB3aGVuIHRoZSBjb21wcmVzc2VkIGltYWdlIGlzIGF2YWlsYWJsZS4gVGhlc2UKKyAgICAgKiBjYWxsIGJhY2tzIG1heSBiZSBudWxsLiBUaGUgdXNlciBwYXJhbWV0ZXIgaXMgcGFzc2VkCisgICAgICogdG8gZWFjaCBvZiB0aGUgY2FsbCBiYWNrIHJvdXRpbmVzLgorICAgICAqLworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgdGFrZVBpY3R1cmUoc2h1dHRlcl9jYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd19jYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpwZWdfY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiB1c2VyKSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWwgYSBwaWN0dXJlIHRoYXQgd2FzIHN0YXJ0ZWQgd2l0aCB0YWtlUGljdHVyZS4gIFlvdSBtYXkgY2FuY2VsIGFueQorICAgICAqIG9mIHRoZSBzaHV0dGVyLCByYXcsIG9yIGpwZWcgY2FsbGJhY2tzLiAgQ2FsbGluZyB0aGlzIG1ldGhvZCB3aGVuIG5vCisgICAgICogcGljdHVyZSBpcyBiZWluZyB0YWtlbiBpcyBhIG5vLW9wLgorICAgICAqLworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgY2FuY2VsUGljdHVyZShib29sIGNhbmNlbF9zaHV0dGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGNhbmNlbF9yYXcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2FuY2VsX2pwZWcpID0gMDsKKworICAgIC8qKiBTZXQgdGhlIGNhbWVyYSBwYXJhbWV0ZXJzLiAqLworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0UGFyYW1ldGVycyhjb25zdCBDYW1lcmFQYXJhbWV0ZXJzJiBwYXJhbXMpID0gMDsKKworICAgIC8qKiBSZXR1cm4gdGhlIGNhbWVyYSBwYXJhbWV0ZXJzLiAqLworICAgIHZpcnR1YWwgQ2FtZXJhUGFyYW1ldGVycyAgZ2V0UGFyYW1ldGVycygpIGNvbnN0ID0gMDsKKworICAgIC8qKgorICAgICAqIFJlbGVhc2UgdGhlIGhhcmR3YXJlIHJlc291cmNlcyBvd25lZCBieSB0aGlzIG9iamVjdC4gIE5vdGUgdGhhdCB0aGlzIGlzCisgICAgICogKm5vdCogZG9uZSBpbiB0aGUgZGVzdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHZvaWQgcmVsZWFzZSgpID0gMDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBEdW1wIHN0YXRlIG9mIHRoZSBjYW1lcmEgaGFyZHdhcmUKKyAgICAgKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190IGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKSBjb25zdCA9IDA7Cit9OworCisvKiogZmFjdG9yeSBmdW5jdGlvbiB0byBpbnN0YW50aWF0ZSBhIGNhbWVyYSBoYXJkd2FyZSBvYmplY3QgKi8KK2V4dGVybiAiQyIgc3A8Q2FtZXJhSGFyZHdhcmVJbnRlcmZhY2U+IG9wZW5DYW1lcmFIYXJkd2FyZSgpOworCit9OyAgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0NhbWVyYVBhcmFtZXRlcnMuaCBiL2luY2x1ZGUvdWkvQ2FtZXJhUGFyYW1ldGVycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljYTE4MDYKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL0NhbWVyYVBhcmFtZXRlcnMuaApAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0hBUkRXQVJFX0NBTUVSQV9QQVJBTUVURVJTX0gKKyNkZWZpbmUgQU5EUk9JRF9IQVJEV0FSRV9DQU1FUkFfUEFSQU1FVEVSU19ICisKKyNpbmNsdWRlIDx1dGlscy9LZXllZFZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBDYW1lcmFQYXJhbWV0ZXJzCit7CitwdWJsaWM6CisgICAgQ2FtZXJhUGFyYW1ldGVycygpOworICAgIENhbWVyYVBhcmFtZXRlcnMoY29uc3QgU3RyaW5nOCAmcGFyYW1zKSB7IHVuZmxhdHRlbihwYXJhbXMpOyB9CisgICAgfkNhbWVyYVBhcmFtZXRlcnMoKTsKKworICAgIGVudW0geworICAgICAgICBDQU1FUkFfT1JJRU5UQVRJT05fVU5LTk9XTiA9IDAsCisgICAgICAgIENBTUVSQV9PUklFTlRBVElPTl9QT1JUUkFJVCA9IDEsCisgICAgICAgIENBTUVSQV9PUklFTlRBVElPTl9MQU5EU0NBUEUgPSAyLAorICAgIH07CisKKyAgICBTdHJpbmc4IGZsYXR0ZW4oKSBjb25zdDsKKyAgICB2b2lkIHVuZmxhdHRlbihjb25zdCBTdHJpbmc4ICZwYXJhbXMpOworCisgICAgdm9pZCBzZXQoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSk7CisgICAgdm9pZCBzZXQoY29uc3QgY2hhciAqa2V5LCBpbnQgdmFsdWUpOworICAgIGNvbnN0IGNoYXIgKmdldChjb25zdCBjaGFyICprZXkpIGNvbnN0OworICAgIGludCBnZXRJbnQoY29uc3QgY2hhciAqa2V5KSBjb25zdDsKKworICAgIC8qIHByZXZpZXctc2l6ZT0xNzZ4MTQ0ICovCisgICAgdm9pZCBzZXRQcmV2aWV3U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpOworICAgIHZvaWQgZ2V0UHJldmlld1NpemUoaW50ICp3aWR0aCwgaW50ICpoZWlnaHQpIGNvbnN0OworCisgICAgLyogcHJldmlldy1mcHM9MTUgKi8KKyAgICB2b2lkIHNldFByZXZpZXdGcmFtZVJhdGUoaW50IGZwcyk7CisgICAgaW50IGdldFByZXZpZXdGcmFtZVJhdGUoKSBjb25zdDsKKworICAgIC8qIHByZXZpZXctZm9ybWF0PXJnYjU2NXx5dXY0MjIgKi8KKyAgICB2b2lkIHNldFByZXZpZXdGb3JtYXQoY29uc3QgY2hhciAqZm9ybWF0KTsKKyAgICBjb25zdCBjaGFyICpnZXRQcmV2aWV3Rm9ybWF0KCkgY29uc3Q7CisKKyAgICAvKiBwaWN0dXJlLXNpemU9MTAyNHg3NjggKi8KKyAgICB2b2lkIHNldFBpY3R1cmVTaXplKGludCB3aWR0aCwgaW50IGhlaWdodCk7CisgICAgdm9pZCBnZXRQaWN0dXJlU2l6ZShpbnQgKndpZHRoLCBpbnQgKmhlaWdodCkgY29uc3Q7CisKKyAgICAvKiBwaWN0dXJlLWZvcm1hdD15dXY0MjJ8anBlZyAqLworICAgIHZvaWQgc2V0UGljdHVyZUZvcm1hdChjb25zdCBjaGFyICpmb3JtYXQpOworICAgIGNvbnN0IGNoYXIgKmdldFBpY3R1cmVGb3JtYXQoKSBjb25zdDsKKworICAgIGludCBnZXRPcmllbnRhdGlvbigpIGNvbnN0OworICAgIHZvaWQgc2V0T3JpZW50YXRpb24oaW50IG9yaWVudGF0aW9uKTsKKworICAgIHZvaWQgZHVtcCgpIGNvbnN0OworICAgIHN0YXR1c190IGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBEZWZhdWx0S2V5ZWRWZWN0b3I8U3RyaW5nOCxTdHJpbmc4PiAgICBtTWFwOworfTsKKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWkvRGlzcGxheUluZm8uaCBiL2luY2x1ZGUvdWkvRGlzcGxheUluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDE5ZWZlCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9EaXNwbGF5SW5mby5oCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKKyNpZm5kZWYgQU5EUk9JRF9VSV9ESVNQTEFZX0lORk9fSAorI2RlZmluZSBBTkRST0lEX1VJX0RJU1BMQVlfSU5GT19ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RydWN0IERpc3BsYXlJbmZvIHsKKyAgICB1aW50MzJfdCAgICAgICAgICAgIHc7CisgICAgdWludDMyX3QgICAgICAgICAgICBoOworICAgIFBpeGVsRm9ybWF0SW5mbyAgICAgcGl4ZWxGb3JtYXRJbmZvOworICAgIHVpbnQ4X3QgICAgICAgICAgICAgb3JpZW50YXRpb247CisgICAgdWludDhfdCAgICAgICAgICAgICByZXNlcnZlZFszXTsKKyAgICBmbG9hdCAgICAgICAgICAgICAgIGZwczsKKyAgICBmbG9hdCAgICAgICAgICAgICAgIGRlbnNpdHk7CisgICAgZmxvYXQgICAgICAgICAgICAgICB4ZHBpOworICAgIGZsb2F0ICAgICAgICAgICAgICAgeWRwaTsKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0NPTVBPU0VSX0RJU1BMQVlfSU5GT19ICisKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWkvRUdMRGlzcGxheVN1cmZhY2UuaCBiL2luY2x1ZGUvdWkvRUdMRGlzcGxheVN1cmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGI1ODUzCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9FR0xEaXNwbGF5U3VyZmFjZS5oCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfRUdMX0RJU1BMQVlfU1VSRkFDRV9ICisjZGVmaW5lIEFORFJPSURfRUdMX0RJU1BMQVlfU1VSRkFDRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1RpbWVycy5oPgorCisjaW5jbHVkZSA8dWkvRUdMTmF0aXZlU3VyZmFjZS5oPgorCisjaW5jbHVkZSA8cGl4ZWxmbGluZ2VyL3BpeGVsZmxpbmdlci5oPgorI2luY2x1ZGUgPGxpbnV4L2ZiLmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisKK3N0cnVjdCBjb3B5Yml0X2RldmljZV90Oworc3RydWN0IGNvcHliaXRfaW1hZ2VfdDsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgUmVnaW9uOworY2xhc3MgUmVjdDsKKworY2xhc3MgRUdMRGlzcGxheVN1cmZhY2UgOiBwdWJsaWMgRUdMTmF0aXZlU3VyZmFjZTxFR0xEaXNwbGF5U3VyZmFjZT4KK3sKK3B1YmxpYzoKKyAgICBFR0xEaXNwbGF5U3VyZmFjZSgpOworICAgIH5FR0xEaXNwbGF5U3VyZmFjZSgpOworICAgIAorICAgIGludDMyX3QgZ2V0UGFnZUZsaXBDb3VudCgpIGNvbnN0OworICAgIHZvaWQgICAgY29weUZyb250VG9CYWNrKGNvbnN0IFJlZ2lvbiYgY29weWJhY2spOworICAgIHZvaWQgICAgY29weUZyb250VG9JbWFnZShjb25zdCBjb3B5Yml0X2ltYWdlX3QmIGRzdCk7CisgICAgdm9pZCAgICBjb3B5QmFja1RvSW1hZ2UoY29uc3QgY29weWJpdF9pbWFnZV90JiBkc3QpOworICAgIAorICAgIHZvaWQgICAgICAgIHNldFN3YXBSZWN0YW5nbGUoaW50IGwsIGludCB0LCBpbnQgdywgaW50IGgpOworCitwcml2YXRlOgorICAgIHN0YXRpYyB2b2lkICAgICAgICAgaG9va19pbmNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpOworICAgIHN0YXRpYyB2b2lkICAgICAgICAgaG9va19kZWNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpOworICAgIHN0YXRpYyB1aW50MzJfdCAgICAgaG9va19zd2FwQnVmZmVycyhOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdyk7CisgICAgIAorICAgICAgICAgICAgdWludDMyX3QgICAgc3dhcEJ1ZmZlcnMoKTsKKworICAgICAgICAgICAgc3RhdHVzX3QgICAgbWFwRnJhbWVCdWZmZXIoKTsKKworICAgICAgICAgICAgZW51bSB7CisgICAgICAgICAgICAgICAgUEFHRV9GTElQID0gMHgwMDAwMDAwMQorICAgICAgICAgICAgfTsKKyAgICBHR0xTdXJmYWNlICAgICAgICAgIG1GYlsyXTsKKyAgICBpbnQgICAgICAgICAgICAgICAgIG1JbmRleDsKKyAgICB1aW50MzJfdCAgICAgICAgICAgIG1GbGFnczsKKyAgICBzaXplX3QgICAgICAgICAgICAgIG1TaXplOworICAgIGZiX3Zhcl9zY3JlZW5pbmZvICAgbUluZm87CisgICAgZmJfZml4X3NjcmVlbmluZm8gICBtRmluZm87CisgICAgaW50MzJfdCAgICAgICAgICAgICBtUGFnZUZsaXBDb3VudDsKKyAgICBuc2Vjc190ICAgICAgICAgICAgIG1UaW1lOworICAgIGludDMyX3QgICAgICAgICAgICAgbVN3YXBDb3VudDsKKyAgICBuc2Vjc190ICAgICAgICAgICAgIG1TbGVlcDsKKyAgICB1aW50MzJfdCAgICAgICAgICAgIG1GZWF0dXJlRmxhZ3M7CisgICAgY29weWJpdF9kZXZpY2VfdCogICBtQmxpdEVuZ2luZTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9FR0xfRElTUExBWV9TVVJGQUNFX0gKKwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9FR0xOYXRpdmVTdXJmYWNlLmggYi9pbmNsdWRlL3VpL0VHTE5hdGl2ZVN1cmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTY0ZTdjCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9FR0xOYXRpdmVTdXJmYWNlLmgKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9FR0xfTkFUSVZFX1NVUkZBQ0VfSAorI2RlZmluZSBBTkRST0lEX0VHTF9OQVRJVkVfU1VSRkFDRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPGN1dGlscy9hdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsbmF0aXZlcy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0ZW1wbGF0ZSA8Y2xhc3MgVFlQRT4KK2NsYXNzIEVHTE5hdGl2ZVN1cmZhY2UgOiBwdWJsaWMgZWdsX25hdGl2ZV93aW5kb3dfdCwgcHVibGljIExpZ2h0UmVmQmFzZTxUWVBFPgoreworcHVibGljOgorICAgIEVHTE5hdGl2ZVN1cmZhY2UoKSB7IAorICAgICAgICBtZW1zZXQoZWdsX25hdGl2ZV93aW5kb3dfdDo6cmVzZXJ2ZWQsIDAsIAorICAgICAgICAgICAgICAgIHNpemVvZihlZ2xfbmF0aXZlX3dpbmRvd190OjpyZXNlcnZlZCkpOworICAgICAgICBtZW1zZXQoZWdsX25hdGl2ZV93aW5kb3dfdDo6cmVzZXJ2ZWRfcHJvYywgMCwgCisgICAgICAgICAgICAgICAgc2l6ZW9mKGVnbF9uYXRpdmVfd2luZG93X3Q6OnJlc2VydmVkX3Byb2MpKTsKKyAgICAgICAgbWVtc2V0KGVnbF9uYXRpdmVfd2luZG93X3Q6Om9lbSwgMCwgCisgICAgICAgICAgICAgICAgc2l6ZW9mKGVnbF9uYXRpdmVfd2luZG93X3Q6Om9lbSkpOworICAgIH0KK3Byb3RlY3RlZDoKKyAgICBFR0xOYXRpdmVTdXJmYWNlJiBvcGVyYXRvciA9IChjb25zdCBFR0xOYXRpdmVTdXJmYWNlJiByaHMpOworICAgIEVHTE5hdGl2ZVN1cmZhY2UoY29uc3QgRUdMTmF0aXZlU3VyZmFjZSYgcmhzKTsKKyAgICBpbmxpbmUgfkVHTE5hdGl2ZVN1cmZhY2UoKSB7IH07Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfRUdMX1NVUkZBQ0VfSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0VHTE5hdGl2ZVdpbmRvd1N1cmZhY2UuaCBiL2luY2x1ZGUvdWkvRUdMTmF0aXZlV2luZG93U3VyZmFjZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0OTQyMzQKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL0VHTE5hdGl2ZVdpbmRvd1N1cmZhY2UuaApAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0VHTF9OQVRJVkVfV0lORE9XX1NVUkZBQ0VfSAorI2RlZmluZSBBTkRST0lEX0VHTF9OQVRJVkVfV0lORE9XX1NVUkZBQ0VfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dWkvRUdMTmF0aXZlU3VyZmFjZS5oPgorI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgU3VyZmFjZTsKKworY2xhc3MgRUdMTmF0aXZlV2luZG93U3VyZmFjZSA6IHB1YmxpYyBFR0xOYXRpdmVTdXJmYWNlPEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U+Cit7CitwdWJsaWM6CisgICAgRUdMTmF0aXZlV2luZG93U3VyZmFjZShjb25zdCBzcDxTdXJmYWNlPiYgc3VyZmFjZSk7CisgICAgfkVHTE5hdGl2ZVdpbmRvd1N1cmZhY2UoKTsKKworICAgIHZvaWQgICAgICAgIHNldFN3YXBSZWN0YW5nbGUoaW50IGwsIGludCB0LCBpbnQgdywgaW50IGgpOworCitwcml2YXRlOgorICAgIHN0YXRpYyB2b2lkICAgICAgICAgaG9va19pbmNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpOworICAgIHN0YXRpYyB2b2lkICAgICAgICAgaG9va19kZWNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpOworICAgIHN0YXRpYyB1aW50MzJfdCAgICAgaG9va19zd2FwQnVmZmVycyhOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdyk7CisgICAgc3RhdGljIHZvaWQgICAgICAgICBob29rX2Nvbm5lY3QoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpOworICAgIHN0YXRpYyB2b2lkICAgICAgICAgaG9va19kaXNjb25uZWN0KE5hdGl2ZVdpbmRvd1R5cGUgd2luZG93KTsKKworICAgICAgICAgICAgdWludDMyX3QgICAgc3dhcEJ1ZmZlcnMoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3A8U3VyZmFjZT4gbVN1cmZhY2U7CisgICAgICAgICAgICBib29sICAgICAgICBtQ29ubmVjdGVkOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvLyBBTkRST0lEX0VHTF9OQVRJVkVfV0lORE9XX1NVUkZBQ0VfSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0V2ZW50SHViLmggYi9pbmNsdWRlL3VpL0V2ZW50SHViLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg0OGQ4YwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvRXZlbnRIdWIuaApAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisjaWZuZGVmIF9SVU5USU1FX0VWRU5UX0hVQl9ICisjZGVmaW5lIF9SVU5USU1FX0VWRU5UX0hVQl9ICisKKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzLmg+CisKKyNpbmNsdWRlIDxsaW51eC9pbnB1dC5oPgorCitzdHJ1Y3QgcG9sbGZkOworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEtleUxheW91dE1hcDsKKworLyoKKyAqIEdyYW5kIENlbnRyYWwgU3RhdGlvbiBmb3IgZXZlbnRzLiAgV2l0aCBhIHNpbmdsZSBjYWxsIHRvIHdhaXRFdmVudCgpCisgKiB5b3UgY2FuIHdhaXQgZm9yOgorICogIC0gaW5wdXQgZXZlbnRzIGZyb20gdGhlIGtleXBhZCBvZiBhIHJlYWwgZGV2aWNlCisgKiAgLSBpbnB1dCBldmVudHMgYW5kIG1ldGEtZXZlbnRzIChlLmcuICJxdWl0IikgZnJvbSB0aGUgc2ltdWxhdG9yCisgKiAgLSBzeW50aGV0aWMgZXZlbnRzIGZyb20gdGhlIHJ1bnRpbWUgKGUuZy4gIlVSTCBmZXRjaCBjb21wbGV0ZWQiKQorICogIC0gcmVhbCBvciBmb3JnZWQgInZzeW5jIiBldmVudHMKKyAqCisgKiBEbyBub3QgaW5zdGFudGlhdGUgdGhpcyBjbGFzcy4gIEluc3RlYWQsIGNhbGwgc3RhcnRVcCgpLgorICovCitjbGFzcyBFdmVudEh1YiA6IHB1YmxpYyBSZWZCYXNlCit7CitwdWJsaWM6CisgICAgRXZlbnRIdWIoKTsKKyAgICAKKyAgICBzdGF0dXNfdCBlcnJvckNoZWNrKCkgY29uc3Q7CisgICAgCisgICAgLy8gYml0IGZpZWxkcyBmb3IgY2xhc3NlcyBvZiBkZXZpY2VzLgorICAgIGVudW0geworICAgICAgICBDTEFTU19LRVlCT0FSRCAgICAgID0gMHgwMDAwMDAwMSwKKyAgICAgICAgQ0xBU1NfQUxQSEFLRVkgICAgICA9IDB4MDAwMDAwMDIsCisgICAgICAgIENMQVNTX1RPVUNIU0NSRUVOICAgPSAweDAwMDAwMDA0LAorICAgICAgICBDTEFTU19UUkFDS0JBTEwgICAgID0gMHgwMDAwMDAwOAorICAgIH07CisgICAgdWludDMyX3QgZ2V0RGV2aWNlQ2xhc3NlcyhpbnQzMl90IGRldmljZUlkKSBjb25zdDsKKyAgICAKKyAgICBTdHJpbmc4IGdldERldmljZU5hbWUoaW50MzJfdCBkZXZpY2VJZCkgY29uc3Q7CisgICAgCisgICAgaW50IGdldEFic29sdXRlSW5mbyhpbnQzMl90IGRldmljZUlkLCBpbnQgYXhpcywgaW50ICpvdXRNaW5WYWx1ZSwKKyAgICAgICAgICAgIGludCogb3V0TWF4VmFsdWUsIGludCogb3V0RmxhdCwgaW50KiBvdXRGdXp6KSBjb25zdDsKKyAgICAgICAgCisgICAgaW50IGdldFN3aXRjaFN0YXRlKGludCBzdykgY29uc3Q7CisgICAgaW50IGdldFN3aXRjaFN0YXRlKGludDMyX3QgZGV2aWNlSWQsIGludCBzdykgY29uc3Q7CisgICAgCisgICAgaW50IGdldFNjYW5jb2RlU3RhdGUoaW50IGtleSkgY29uc3Q7CisgICAgaW50IGdldFNjYW5jb2RlU3RhdGUoaW50MzJfdCBkZXZpY2VJZCwgaW50IGtleSkgY29uc3Q7CisgICAgCisgICAgaW50IGdldEtleWNvZGVTdGF0ZShpbnQga2V5KSBjb25zdDsKKyAgICBpbnQgZ2V0S2V5Y29kZVN0YXRlKGludDMyX3QgZGV2aWNlSWQsIGludCBrZXkpIGNvbnN0OworICAgIAorICAgIC8vIHNwZWNpYWwgdHlwZSBjb2RlcyB3aGVuIGRldmljZXMgYXJlIGFkZGVkL3JlbW92ZWQuCisgICAgZW51bSB7CisgICAgICAgIERFVklDRV9BRERFRCA9IDB4MTAwMDAwMDAsCisgICAgICAgIERFVklDRV9SRU1PVkVEID0gMHgyMDAwMDAwMAorICAgIH07CisgICAgCisgICAgLy8gZXhhbWluZSBrZXkgaW5wdXQgZGV2aWNlcyBmb3Igc3BlY2lmaWMgZnJhbWV3b3JrIGtleWNvZGUgc3VwcG9ydAorICAgIGJvb2wgaGFzS2V5cyhzaXplX3QgbnVtQ29kZXMsIGludDMyX3QqIGtleUNvZGVzLCB1aW50OF90KiBvdXRGbGFncyk7CisKKyAgICB2aXJ0dWFsIGJvb2wgZ2V0RXZlbnQoaW50MzJfdCogb3V0RGV2aWNlSWQsIGludDMyX3QqIG91dFR5cGUsCisgICAgICAgICAgICBpbnQzMl90KiBvdXRTY2FuY29kZSwgaW50MzJfdCogb3V0S2V5Y29kZSwgdWludDMyX3QgKm91dEZsYWdzLAorICAgICAgICAgICAgaW50MzJfdCogb3V0VmFsdWUsIG5zZWNzX3QqIG91dFdoZW4pOworICAgIAorcHJvdGVjdGVkOgorICAgIHZpcnR1YWwgfkV2ZW50SHViKCk7CisgICAgdmlydHVhbCB2b2lkIG9uRmlyc3RSZWYoKTsKKyAgICAKK3ByaXZhdGU6CisgICAgYm9vbCBvcGVuUGxhdGZvcm1JbnB1dCh2b2lkKTsKKyAgICBpbnQzMl90IGNvbnZlcnREZXZpY2VLZXlfVElfUDIoaW50IGNvZGUpOworCisgICAgaW50IG9wZW5fZGV2aWNlKGNvbnN0IGNoYXIgKmRldmljZSk7CisgICAgaW50IGNsb3NlX2RldmljZShjb25zdCBjaGFyICpkZXZpY2UpOworICAgIGludCBzY2FuX2Rpcihjb25zdCBjaGFyICpkaXJuYW1lKTsKKyAgICBpbnQgcmVhZF9ub3RpZnkoaW50IG5mZCk7CisKKyAgICBzdGF0dXNfdCBtRXJyb3I7CisKKyAgICBzdHJ1Y3QgZGV2aWNlX3QgeworICAgICAgICBjb25zdCBpbnQzMl90ICAgaWQ7CisgICAgICAgIGNvbnN0IFN0cmluZzggICBwYXRoOworICAgICAgICBTdHJpbmc4ICAgICAgICAgbmFtZTsKKyAgICAgICAgdWludDMyX3QgICAgICAgIGNsYXNzZXM7CisgICAgICAgIHVpbnQ4X3QqICAgICAgICBrZXlCaXRtYXNrOworICAgICAgICBLZXlMYXlvdXRNYXAqICAgbGF5b3V0TWFwOworICAgICAgICBTdHJpbmc4ICAgICAgICAga2V5bGF5b3V0RmlsZW5hbWU7CisgICAgICAgIGRldmljZV90KiAgICAgICBuZXh0OworICAgICAgICAKKyAgICAgICAgZGV2aWNlX3QoaW50MzJfdCBfaWQsIGNvbnN0IGNoYXIqIF9wYXRoKTsKKyAgICAgICAgfmRldmljZV90KCk7CisgICAgfTsKKworICAgIGRldmljZV90KiBnZXREZXZpY2UoaW50MzJfdCBkZXZpY2VJZCkgY29uc3Q7CisgICAgCisgICAgLy8gUHJvdGVjdCBhbGwgaW50ZXJuYWwgc3RhdGUuCisgICAgbXV0YWJsZSBNdXRleCAgIG1Mb2NrOworICAgIAorICAgIGJvb2wgICAgICAgICAgICBtSGF2ZUZpcnN0S2V5Ym9hcmQ7CisgICAgaW50MzJfdCAgICAgICAgIG1GaXJzdEtleWJvYXJkSWQ7IC8vIHRoZSBBUEkgaXMgdGhhdCB0aGUgYnVpbGQgaW4ga2V5Ym9hcmQgaXMgaWQgMCwgc28gbWFwIGl0CisgICAgCisgICAgc3RydWN0IGRldmljZV9lbnQgeworICAgICAgICBkZXZpY2VfdCogZGV2aWNlOworICAgICAgICB1aW50MzJfdCBzZXE7CisgICAgfTsKKyAgICBkZXZpY2VfZW50ICAgICAgKm1EZXZpY2VzQnlJZDsKKyAgICBpbnQgICAgICAgICAgICAgbU51bURldmljZXNCeUlkOworICAgIAorICAgIGRldmljZV90ICAgICAgICAqbU9wZW5pbmdEZXZpY2VzOworICAgIGRldmljZV90ICAgICAgICAqbUNsb3NpbmdEZXZpY2VzOworICAgIAorICAgIGRldmljZV90ICAgICAgICAqKm1EZXZpY2VzOworICAgIHN0cnVjdCBwb2xsZmQgICAqbUZEczsKKyAgICBpbnQgICAgICAgICAgICAgbUZEQ291bnQ7CisgICAgCisgICAgLy8gZGV2aWNlIGlkcyB0aGF0IHJlcG9ydCBwYXJ0aWN1bGFyIHN3aXRjaGVzLgorI2lmZGVmIEVWX1NXCisgICAgaW50MzJfdCAgICAgICAgIG1Td2l0Y2hlc1tTV19NQVgrMV07CisjZW5kaWYKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBfUlVOVElNRV9FVkVOVF9IVUJfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9JQ2FtZXJhLmggYi9pbmNsdWRlL3VpL0lDYW1lcmEuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDFmYjYzCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9JQ2FtZXJhLmgKQEAgLTAsMCArMSwxMDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfSEFSRFdBUkVfSUNBTUVSQV9ICisjZGVmaW5lIEFORFJPSURfSEFSRFdBUkVfSUNBTUVSQV9ICisKKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvSUludGVyZmFjZS5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlLmg+CisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1aS9DYW1lcmEuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJQ2FtZXJhQ2xpZW50OworCitjbGFzcyBJQ2FtZXJhOiBwdWJsaWMgSUludGVyZmFjZQoreworcHVibGljOgorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoQ2FtZXJhKTsKKworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGRpc2Nvbm5lY3QoKSA9IDA7CisKKyAgICAvLyBjb25uZWN0IG5ldyBjbGllbnQgd2l0aCBleGlzdGluZyBjYW1lcmEgcmVtb3RlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgY29ubmVjdChjb25zdCBzcDxJQ2FtZXJhQ2xpZW50PiYgY2xpZW50KSA9IDA7CisKKyAgICAvLyBwcmV2ZW50IG90aGVyIHByb2Nlc3NlcyBmcm9tIHVzaW5nIHRoaXMgSUNhbWVyYSBpbnRlcmZhY2UKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBsb2NrKCkgPSAwOworCisgICAgLy8gYWxsb3cgb3RoZXIgcHJvY2Vzc2VzIHRvIHVzZSB0aGlzIElDYW1lcmEgaW50ZXJmYWNlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgdW5sb2NrKCkgPSAwOworCisgICAgLy8gcGFzcyB0aGUgYnVmZmVyZWQgSVN1cmZhY2UgdG8gdGhlIGNhbWVyYSBzZXJ2aWNlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgc2V0UHJldmlld0Rpc3BsYXkoY29uc3Qgc3A8SVN1cmZhY2U+JiBzdXJmYWNlKSA9IDA7CisKKyAgICAvLyBzZXQgdGhlIHByZXZpZXcgY2FsbGJhY2sgZmxhZyB0byBhZmZlY3QgaG93IHRoZSByZWNlaXZlZCBmcmFtZXMgZnJvbQorICAgIC8vIHByZXZpZXcgYXJlIGhhbmRsZWQuCisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgc2V0UHJldmlld0NhbGxiYWNrRmxhZyhpbnQgZmxhZykgPSAwOworCisgICAgLy8gc3RhcnQgcHJldmlldyBtb2RlLCBtdXN0IGNhbGwgc2V0UHJldmlld0Rpc3BsYXkgZmlyc3QKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBzdGFydFByZXZpZXcoKSA9IDA7CisKKyAgICAvLyBzdG9wIHByZXZpZXcgbW9kZQorICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHN0b3BQcmV2aWV3KCkgPSAwOworCisgICAgLy8gZ2V0IHByZXZpZXcgc3RhdGUKKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgICAgICBwcmV2aWV3RW5hYmxlZCgpID0gMDsKKworICAgIC8vIHN0YXJ0IHJlY29yZGluZyBtb2RlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgc3RhcnRSZWNvcmRpbmcoKSA9IDA7CisKKyAgICAvLyBzdG9wIHJlY29yZGluZyBtb2RlCisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgc3RvcFJlY29yZGluZygpID0gMDsgICAgCisKKyAgICAvLyBnZXQgcmVjb3JkaW5nIHN0YXRlCisgICAgdmlydHVhbCBib29sICAgICAgICAgICAgcmVjb3JkaW5nRW5hYmxlZCgpID0gMDsKKworICAgIC8vIHJlbGVhc2UgYSByZWNvcmRpbmcgZnJhbWUKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZWxlYXNlUmVjb3JkaW5nRnJhbWUoY29uc3Qgc3A8SU1lbW9yeT4mIG1lbSkgPSAwOworCisgICAgLy8gYXV0byBmb2N1cworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIGF1dG9Gb2N1cygpID0gMDsKKworICAgIC8vIHRha2UgYSBwaWN0dXJlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgdGFrZVBpY3R1cmUoKSA9IDA7CisKKyAgICAvLyBzZXQgcHJldmlldy9jYXB0dXJlIHBhcmFtZXRlcnMgLSBrZXkvdmFsdWUgcGFpcnMKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBzZXRQYXJhbWV0ZXJzKGNvbnN0IFN0cmluZzgmIHBhcmFtcykgPSAwOworCisgICAgLy8gZ2V0IHByZXZpZXcvY2FwdHVyZSBwYXJhbWV0ZXJzIC0ga2V5L3ZhbHVlIHBhaXJzCisgICAgdmlydHVhbCBTdHJpbmc4ICAgICAgICAgZ2V0UGFyYW1ldGVycygpIGNvbnN0ID0gMDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQm5DYW1lcmE6IHB1YmxpYyBCbkludGVyZmFjZTxJQ2FtZXJhPgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgb25UcmFuc2FjdCggdWludDMyX3QgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmNlbCogcmVwbHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDApOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0lDYW1lcmFDbGllbnQuaCBiL2luY2x1ZGUvdWkvSUNhbWVyYUNsaWVudC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczYjk1MWMKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL0lDYW1lcmFDbGllbnQuaApAQCAtMCwwICsxLDU1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0hBUkRXQVJFX0lDQU1FUkFfQVBQX0gKKyNkZWZpbmUgQU5EUk9JRF9IQVJEV0FSRV9JQ0FNRVJBX0FQUF9ICisKKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvSUludGVyZmFjZS5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJQ2FtZXJhQ2xpZW50OiBwdWJsaWMgSUludGVyZmFjZQoreworcHVibGljOgorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoQ2FtZXJhQ2xpZW50KTsKKworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHNodXR0ZXJDYWxsYmFjaygpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByYXdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgcGljdHVyZSkgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGpwZWdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgcGljdHVyZSkgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHByZXZpZXdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgZnJhbWUpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBlcnJvckNhbGxiYWNrKHN0YXR1c190IGVycm9yKSA9IDA7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgYXV0b0ZvY3VzQ2FsbGJhY2soYm9vbCBmb2N1c2VkKSA9IDA7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVjb3JkaW5nQ2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIGZyYW1lKSA9IDA7CisKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQm5DYW1lcmFDbGllbnQ6IHB1YmxpYyBCbkludGVyZmFjZTxJQ2FtZXJhQ2xpZW50PgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgb25UcmFuc2FjdCggdWludDMyX3QgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmNlbCogcmVwbHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDApOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0lDYW1lcmFTZXJ2aWNlLmggYi9pbmNsdWRlL3VpL0lDYW1lcmFTZXJ2aWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGZkODkyMwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvSUNhbWVyYVNlcnZpY2UuaApAQCAtMCwwICsxLDU1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0hBUkRXQVJFX0lDQU1FUkFTRVJWSUNFX0gKKyNkZWZpbmUgQU5EUk9JRF9IQVJEV0FSRV9JQ0FNRVJBU0VSVklDRV9ICisKKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvSUludGVyZmFjZS5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorCisjaW5jbHVkZSA8dWkvSUNhbWVyYUNsaWVudC5oPgorI2luY2x1ZGUgPHVpL0lDYW1lcmEuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJQ2FtZXJhU2VydmljZSA6IHB1YmxpYyBJSW50ZXJmYWNlCit7Citwcm90ZWN0ZWQ6CisgICAgZW51bSB7CisgICAgICAgIENPTk5FQ1QgPSBJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OLAorICAgIH07CisKK3B1YmxpYzoKKyAgICBERUNMQVJFX01FVEFfSU5URVJGQUNFKENhbWVyYVNlcnZpY2UpOworCisgICAgdmlydHVhbCBzcDxJQ2FtZXJhPiAgICAgY29ubmVjdChjb25zdCBzcDxJQ2FtZXJhQ2xpZW50PiYgY2FtZXJhQ2xpZW50KSA9IDA7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEJuQ2FtZXJhU2VydmljZTogcHVibGljIEJuSW50ZXJmYWNlPElDYW1lcmFTZXJ2aWNlPgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgb25UcmFuc2FjdCggdWludDMyX3QgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmNlbCogcmVwbHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDApOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0lPdmVybGF5LmggYi9pbmNsdWRlL3VpL0lPdmVybGF5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjk5YjFiMAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvSU92ZXJsYXkuaApAQCAtMCwwICsxLDUzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0lPVkVSTEFZX0gKKyNkZWZpbmUgQU5EUk9JRF9JT1ZFUkxBWV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJT3ZlcmxheSA6IHB1YmxpYyBJSW50ZXJmYWNlCit7CitwdWJsaWM6IAorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoT3ZlcmxheSk7CisKKyAgICB2aXJ0dWFsIHZvaWQgZGVzdHJveSgpID0gMDsgLy8gb25lLXdheQorfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCbk92ZXJsYXkgOiBwdWJsaWMgQm5JbnRlcmZhY2U8SU92ZXJsYXk+Cit7CitwdWJsaWM6CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBvblRyYW5zYWN0KCB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCk7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0lPVkVSTEFZX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWkvSVN1cmZhY2UuaCBiL2luY2x1ZGUvdWkvSVN1cmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44N2IzMjBmCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9JU3VyZmFjZS5oCkBAIC0wLDAgKzEsMTA1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0lTVVJGQUNFX0gKKyNkZWZpbmUgQU5EUk9JRF9JU1VSRkFDRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlL2hhcmR3YXJlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKwordHlwZWRlZiBpbnQzMl90ICAgIFN1cmZhY2VJRDsKKworY2xhc3MgSU1lbW9yeUhlYXA7CitjbGFzcyBPdmVybGF5UmVmOworCitjbGFzcyBJU3VyZmFjZSA6IHB1YmxpYyBJSW50ZXJmYWNlCit7Citwcm90ZWN0ZWQ6CisgICAgZW51bSB7CisgICAgICAgIFJFR0lTVEVSX0JVRkZFUlMgPSBJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OLAorICAgICAgICBVTlJFR0lTVEVSX0JVRkZFUlMsCisgICAgICAgIFBPU1RfQlVGRkVSLCAvLyBvbmUtd2F5IHRyYW5zYWN0aW9uCisgICAgICAgIENSRUFURV9PVkVSTEFZLAorICAgIH07CisKK3B1YmxpYzogCisgICAgREVDTEFSRV9NRVRBX0lOVEVSRkFDRShTdXJmYWNlKTsKKworICAgIAorICAgIGNsYXNzIEJ1ZmZlckhlYXAgeworICAgIHB1YmxpYzoKKyAgICAgICAgZW51bSB7CisgICAgICAgICAgICAvKiByb3RhdGUgc291cmNlIGltYWdlIDkwIGRlZ3JlZXMgKi8KKyAgICAgICAgICAgIFJPVF85MCAgICA9IEhBTF9UUkFOU0ZPUk1fUk9UXzkwLAorICAgICAgICB9OworICAgICAgICBCdWZmZXJIZWFwKCk7CisgICAgICAgIAorICAgICAgICBCdWZmZXJIZWFwKHVpbnQzMl90IHcsIHVpbnQzMl90IGgsCisgICAgICAgICAgICAgICAgaW50MzJfdCBob3Jfc3RyaWRlLCBpbnQzMl90IHZlcl9zdHJpZGUsIAorICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0IGZvcm1hdCwgY29uc3Qgc3A8SU1lbW9yeUhlYXA+JiBoZWFwKTsKKyAgICAgICAgCisgICAgICAgIEJ1ZmZlckhlYXAodWludDMyX3QgdywgdWludDMyX3QgaCwKKyAgICAgICAgICAgICAgICBpbnQzMl90IGhvcl9zdHJpZGUsIGludDMyX3QgdmVyX3N0cmlkZSwgCisgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXQgZm9ybWF0LCB1aW50MzJfdCB0cmFuc2Zvcm0sIHVpbnQzMl90IGZsYWdzLAorICAgICAgICAgICAgICAgIGNvbnN0IHNwPElNZW1vcnlIZWFwPiYgaGVhcCk7CisgICAgICAgIAorICAgICAgICB+QnVmZmVySGVhcCgpOyAKKyAgICAgICAgCisgICAgICAgIHVpbnQzMl90IHc7CisgICAgICAgIHVpbnQzMl90IGg7CisgICAgICAgIGludDMyX3QgaG9yX3N0cmlkZTsKKyAgICAgICAgaW50MzJfdCB2ZXJfc3RyaWRlOworICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQ7CisgICAgICAgIHVpbnQzMl90IHRyYW5zZm9ybTsKKyAgICAgICAgdWludDMyX3QgZmxhZ3M7CisgICAgICAgIHNwPElNZW1vcnlIZWFwPiBoZWFwOworICAgIH07CisgICAgCisgICAgdmlydHVhbCBzdGF0dXNfdCByZWdpc3RlckJ1ZmZlcnMoY29uc3QgQnVmZmVySGVhcCYgYnVmZmVycykgPSAwOworCisgICAgdmlydHVhbCB2b2lkIHBvc3RCdWZmZXIoc3NpemVfdCBvZmZzZXQpID0gMDsgLy8gb25lLXdheQorCisgICAgdmlydHVhbCB2b2lkIHVucmVnaXN0ZXJCdWZmZXJzKCkgPSAwOworICAgIAorICAgIHZpcnR1YWwgc3A8T3ZlcmxheVJlZj4gY3JlYXRlT3ZlcmxheSgKKyAgICAgICAgICAgIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIGludDMyX3QgZm9ybWF0KSA9IDA7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEJuU3VyZmFjZSA6IHB1YmxpYyBCbkludGVyZmFjZTxJU3VyZmFjZT4KK3sKK3B1YmxpYzoKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIG9uVHJhbnNhY3QoIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfSVNVUkZBQ0VfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9JU3VyZmFjZUNvbXBvc2VyLmggYi9pbmNsdWRlL3VpL0lTdXJmYWNlQ29tcG9zZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOWVlYjMwCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9JU3VyZmFjZUNvbXBvc2VyLmgKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfSVNVUkZBQ0VfQ09NUE9TRVJfSAorI2RlZmluZSBBTkRST0lEX0lTVVJGQUNFX0NPTVBPU0VSX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvUmVmQmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2VGbGluZ2VyQ2xpZW50Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBEaXNwbGF5SW5mbzsKK2NsYXNzIElHUFVDYWxsYmFjazsKKworY2xhc3MgSVN1cmZhY2VDb21wb3NlciA6IHB1YmxpYyBJSW50ZXJmYWNlCit7CitwdWJsaWM6CisgICAgREVDTEFSRV9NRVRBX0lOVEVSRkFDRShTdXJmYWNlQ29tcG9zZXIpOworCisgICAgZW51bSB7IC8vIChrZWVwIGluIHN5bmMgd2l0aCBTdXJmYWNlLmphdmEpCisgICAgICAgIGVIaWRkZW4gICAgICAgICAgICAgPSAweDAwMDAwMDA0LAorICAgICAgICBlR1BVICAgICAgICAgICAgICAgID0gMHgwMDAwMDAwOCwKKyAgICAgICAgZUhhcmR3YXJlICAgICAgICAgICA9IDB4MDAwMDAwMTAsCisgICAgICAgIGVEZXN0cm95QmFja2J1ZmZlciAgPSAweDAwMDAwMDIwLAorICAgICAgICBlU2VjdXJlICAgICAgICAgICAgID0gMHgwMDAwMDA4MCwKKyAgICAgICAgZU5vblByZW11bHRpcGxpZWQgICA9IDB4MDAwMDAxMDAsCisgICAgICAgIGVQdXNoQnVmZmVycyAgICAgICAgPSAweDAwMDAwMjAwLAorCisgICAgICAgIGVGWFN1cmZhY2VOb3JtYWwgICAgPSAweDAwMDAwMDAwLAorICAgICAgICBlRlhTdXJmYWNlQmx1ciAgICAgID0gMHgwMDAxMDAwMCwKKyAgICAgICAgZUZYU3VyZmFjZURpbSAgICAgICA9IDB4MDAwMjAwMDAsCisgICAgICAgIGVGWFN1cmZhY2VNYXNrICAgICAgPSAweDAwMEYwMDAwLAorICAgIH07CisKKyAgICBlbnVtIHsKKyAgICAgICAgZVBvc2l0aW9uQ2hhbmdlZCAgICAgICAgICAgID0gMHgwMDAwMDAwMSwKKyAgICAgICAgZUxheWVyQ2hhbmdlZCAgICAgICAgICAgICAgID0gMHgwMDAwMDAwMiwKKyAgICAgICAgZVNpemVDaGFuZ2VkICAgICAgICAgICAgICAgID0gMHgwMDAwMDAwNCwKKyAgICAgICAgZUFscGhhQ2hhbmdlZCAgICAgICAgICAgICAgID0gMHgwMDAwMDAwOCwKKyAgICAgICAgZU1hdHJpeENoYW5nZWQgICAgICAgICAgICAgID0gMHgwMDAwMDAxMCwKKyAgICAgICAgZVRyYW5zcGFyZW50UmVnaW9uQ2hhbmdlZCAgID0gMHgwMDAwMDAyMCwKKyAgICAgICAgZVZpc2liaWxpdHlDaGFuZ2VkICAgICAgICAgID0gMHgwMDAwMDA0MCwKKyAgICAgICAgZUZyZWV6ZVRpbnRDaGFuZ2VkICAgICAgICAgID0gMHgwMDAwMDA4MCwKKyAgICAgICAgZURlc3Ryb3llZCAgICAgICAgICAgICAgICAgID0gMHgwMDAwMDEwMAorICAgIH07CisKKyAgICBlbnVtIHsKKyAgICAgICAgZUxheWVySGlkZGVuICAgICAgICA9IDB4MDEsCisgICAgICAgIGVMYXllckZyb3plbiAgICAgICAgPSAweDAyLAorICAgICAgICBlTGF5ZXJEaXRoZXIgICAgICAgID0gMHgwNCwKKyAgICAgICAgZUxheWVyRmlsdGVyICAgICAgICA9IDB4MDgsCisgICAgICAgIGVMYXllckJsdXJGcmVlemUgICAgPSAweDEwCisgICAgfTsKKworICAgIGVudW0geworICAgICAgICBlT3JpZW50YXRpb25EZWZhdWx0ICAgICA9IDAsCisgICAgICAgIGVPcmllbnRhdGlvbjkwICAgICAgICAgID0gMSwKKyAgICAgICAgZU9yaWVudGF0aW9uMTgwICAgICAgICAgPSAyLAorICAgICAgICBlT3JpZW50YXRpb24yNzAgICAgICAgICA9IDMsCisgICAgICAgIGVPcmllbnRhdGlvblN3YXBNYXNrICAgID0gMHgwMQorICAgIH07CisKKyAgICAvKiBjcmVhdGUgY29ubmVjdGlvbiB3aXRoIHN1cmZhY2UgZmxpbmdlciwgcmVxdWlyZXMKKyAgICAgKiBBQ0NFU1NfU1VSRkFDRV9GTElOR0VSIHBlcm1pc3Npb24KKyAgICAgKi8KKworICAgIHZpcnR1YWwgc3A8SVN1cmZhY2VGbGluZ2VyQ2xpZW50PiBjcmVhdGVDb25uZWN0aW9uKCkgPSAwOworCisgICAgLyogcmV0cmlldmUgdGhlIGNvbnRyb2wgYmxvY2sgKi8KKyAgICB2aXJ0dWFsIHNwPElNZW1vcnk+IGdldENibGsoKSBjb25zdCA9IDA7CisKKyAgICAvKiBvcGVuL2Nsb3NlIHRyYW5zYWN0aW9ucy4gcmVjcXVpcmVzIEFDQ0VTU19TVVJGQUNFX0ZMSU5HRVIgcGVybWlzc2lvbiAqLworICAgIHZpcnR1YWwgdm9pZCBvcGVuR2xvYmFsVHJhbnNhY3Rpb24oKSA9IDA7CisgICAgdmlydHVhbCB2b2lkIGNsb3NlR2xvYmFsVHJhbnNhY3Rpb24oKSA9IDA7CisKKyAgICAvKiBbdW5dZnJlZXplIGRpc3BsYXkuIHJlY3F1aXJlcyBBQ0NFU1NfU1VSRkFDRV9GTElOR0VSIHBlcm1pc3Npb24gKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190IGZyZWV6ZURpc3BsYXkoRGlzcGxheUlEIGRweSwgdWludDMyX3QgZmxhZ3MpID0gMDsKKyAgICB2aXJ0dWFsIHN0YXR1c190IHVuZnJlZXplRGlzcGxheShEaXNwbGF5SUQgZHB5LCB1aW50MzJfdCBmbGFncykgPSAwOworCisgICAgLyogU2V0IGRpc3BsYXkgb3JpZW50YXRpb24uIHJlY3F1aXJlcyBBQ0NFU1NfU1VSRkFDRV9GTElOR0VSIHBlcm1pc3Npb24gKi8KKyAgICB2aXJ0dWFsIGludCBzZXRPcmllbnRhdGlvbihEaXNwbGF5SUQgZHB5LCBpbnQgb3JpZW50YXRpb24pID0gMDsKKworICAgIC8qIHNpZ25hbCB0aGF0IHdlJ3JlIGRvbmUgYm9vdGluZy4KKyAgICAgKiByZWNxdWlyZXMgQUNDRVNTX1NVUkZBQ0VfRkxJTkdFUiBwZXJtaXNzaW9uCisgICAgICovCisgICAgdmlydHVhbCB2b2lkIGJvb3RGaW5pc2hlZCgpID0gMDsKKworICAgIC8qIGdldCBhY2Nlc3MgdG8gdGhlIEdQVS4gQWNjZXNzIGlzIHJlbGlucXVpc2hlZCB3aGVuIHJlbGVhc2luZyByZWdzICovCisgICAgc3RydWN0IGdwdV9pbmZvX3QgeworICAgICAgICBzdHJ1Y3QgZ3B1X3JlZ2lvbl90IHsKKyAgICAgICAgICAgIHNwPElNZW1vcnk+IHJlZ2lvbjsKKyAgICAgICAgICAgIHNpemVfdCByZXNlcnZlZDsKKyAgICAgICAgfTsKKyAgICAgICAgc3A8SU1lbW9yeT4gICAgICAgICAgICAgcmVnczsKKyAgICAgICAgc2l6ZV90ICAgICAgICAgICAgICAgICAgY291bnQ7CisgICAgICAgIGdwdV9yZWdpb25fdCAgICAgICAgICAgIHJlZ2lvbnNbMl07CisgICAgfTsKKyAgICB2aXJ0dWFsIHN0YXR1c190IHJlcXVlc3RHUFUoCisgICAgICAgICAgICBjb25zdCBzcDxJR1BVQ2FsbGJhY2s+JiBjYWxsYmFjaywKKyAgICAgICAgICAgIGdwdV9pbmZvX3QqIGdwdSkgPSAwOworCisgICAgLyogdGFrZSB0aGUgZ3B1IGJhY2sgZnJvbSBhbnkgYXBwcyB1c2luZyBpdC4gVGhleSdsbCBnZXQgYQorICAgICAqIEVHTF9DT05URVhUX0xPU1QgZXJyb3IgKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190IHJldm9rZUdQVSgpID0gMDsKKworICAgIC8qIFNpZ25hbCBzdXJmYWNlZmxpbmdlciB0aGF0IHRoZXJlIG1pZ2h0IGJlIHNvbWUgd29yayB0byBkbworICAgICAqIFRoaXMgaXMgYW4gQVNZTkNIUk9OT1VTIGNhbGwuCisgICAgICovCisgICAgdmlydHVhbCB2b2lkIHNpZ25hbCgpIGNvbnN0ID0gMDsKK307CisKK2NsYXNzIElHUFVDYWxsYmFjayA6IHB1YmxpYyBJSW50ZXJmYWNlCit7CitwdWJsaWM6CisgICAgREVDTEFSRV9NRVRBX0lOVEVSRkFDRShHUFVDYWxsYmFjayk7CisgICAgdmlydHVhbCB2b2lkIGdwdUxvc3QoKSA9IDA7IC8vb25lLXdheQorfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCblN1cmZhY2VDb21wb3NlciA6IHB1YmxpYyBCbkludGVyZmFjZTxJU3VyZmFjZUNvbXBvc2VyPgoreworcHVibGljOgorICAgIGVudW0geworICAgICAgICAvLyBOb3RlOiBCT09UX0ZJTklTSEVEIG11c3QgcmVtYWluIHRoaXMgdmFsdWUsIGl0IGlzIGNhbGxlZCBmcm9tCisgICAgICAgIC8vIEphdmEgYnkgQWN0aXZpdHlNYW5hZ2VyU2VydmljZS4KKyAgICAgICAgQk9PVF9GSU5JU0hFRCA9IElCaW5kZXI6OkZJUlNUX0NBTExfVFJBTlNBQ1RJT04sCisgICAgICAgIENSRUFURV9DT05ORUNUSU9OLAorICAgICAgICBHRVRfQ0JMSywKKyAgICAgICAgT1BFTl9HTE9CQUxfVFJBTlNBQ1RJT04sCisgICAgICAgIENMT1NFX0dMT0JBTF9UUkFOU0FDVElPTiwKKyAgICAgICAgU0VUX09SSUVOVEFUSU9OLAorICAgICAgICBGUkVFWkVfRElTUExBWSwKKyAgICAgICAgVU5GUkVFWkVfRElTUExBWSwKKyAgICAgICAgUkVRVUVTVF9HUFUsCisgICAgICAgIFJFVk9LRV9HUFUsCisgICAgICAgIFNJR05BTAorICAgIH07CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIG9uVHJhbnNhY3QoIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKK307CisKK2NsYXNzIEJuR1BVQ2FsbGJhY2sgOiBwdWJsaWMgQm5JbnRlcmZhY2U8SUdQVUNhbGxiYWNrPgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgb25UcmFuc2FjdCggdWludDMyX3QgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmNlbCogcmVwbHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDApOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9JU1VSRkFDRV9DT01QT1NFUl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0lTdXJmYWNlRmxpbmdlckNsaWVudC5oIGIvaW5jbHVkZS91aS9JU3VyZmFjZUZsaW5nZXJDbGllbnQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjkzNjFkCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9JU3VyZmFjZUZsaW5nZXJDbGllbnQuaApAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0lTVVJGQUNFX0ZMSU5HRVJfQ0xJRU5UX0gKKyNkZWZpbmUgQU5EUk9JRF9JU1VSRkFDRV9GTElOR0VSX0NMSUVOVF9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisKKyNpbmNsdWRlIDx1aS9JU3VyZmFjZS5oPgorCisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKyAgCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgUmVjdDsKK2NsYXNzIFBvaW50OworY2xhc3MgSU1lbW9yeTsKK2NsYXNzIElTdXJmYWNlOworCit0eXBlZGVmIGludDMyX3QgICAgQ2xpZW50SUQ7Cit0eXBlZGVmIGludDMyX3QgICAgRGlzcGxheUlEOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIGxheWVyX3N0YXRlX3Q7CisKK2NsYXNzIElTdXJmYWNlRmxpbmdlckNsaWVudCA6IHB1YmxpYyBJSW50ZXJmYWNlCit7CitwdWJsaWM6IAorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoU3VyZmFjZUZsaW5nZXJDbGllbnQpOworCisgICAgc3RydWN0IHN1cmZhY2VfZGF0YV90IHsKKyAgICAgICAgaW50MzJfdCAgICAgICAgICAgICB0b2tlbjsKKyAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBpZGVudGl0eTsKKyAgICAgICAgc3A8SU1lbW9yeUhlYXA+ICAgICBoZWFwWzJdOworICAgICAgICBzdGF0dXNfdCByZWFkRnJvbVBhcmNlbChjb25zdCBQYXJjZWwmIHBhcmNlbCk7CisgICAgICAgIHN0YXR1c190IHdyaXRlVG9QYXJjZWwoUGFyY2VsKiBwYXJjZWwpIGNvbnN0OworICAgIH07CisgICAgCisgICAgdmlydHVhbCB2b2lkIGdldENvbnRyb2xCbG9ja3Moc3A8SU1lbW9yeT4qIGN0bCkgY29uc3QgPSAwOworCisgICAgdmlydHVhbCBzcDxJU3VyZmFjZT4gY3JlYXRlU3VyZmFjZSggc3VyZmFjZV9kYXRhX3QqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBpZCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncykgPSAwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkZXN0cm95U3VyZmFjZShTdXJmYWNlSUQgc2lkKSA9IDA7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldFN0YXRlKGludDMyX3QgY291bnQsIGNvbnN0IGxheWVyX3N0YXRlX3QqIHN0YXRlcykgPSAwOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCblN1cmZhY2VGbGluZ2VyQ2xpZW50IDogcHVibGljIEJuSW50ZXJmYWNlPElTdXJmYWNlRmxpbmdlckNsaWVudD4KK3sKK3B1YmxpYzoKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIG9uVHJhbnNhY3QoIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfSVNVUkZBQ0VfRkxJTkdFUl9DTElFTlRfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9LZXlDaGFyYWN0ZXJNYXAuaCBiL2luY2x1ZGUvdWkvS2V5Q2hhcmFjdGVyTWFwLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmFkMmNmOAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvS2V5Q2hhcmFjdGVyTWFwLmgKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgX1VJX0tFWV9DSEFSQUNURVJfTUFQX0gKKyNkZWZpbmUgX1VJX0tFWV9DSEFSQUNURVJfTUFQX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworY2xhc3MgS2V5Q2hhcmFjdGVyTWFwCit7CitwdWJsaWM6CisgICAgfktleUNoYXJhY3Rlck1hcCgpOworCisgICAgLy8gc2VlIHRoZSBqYXZhZG9jIGZvciBhbmRyb2lkLnRleHQubWV0aG9kLktleUNoYXJhY3Rlck1hcCBmb3Igd2hhdAorICAgIC8vIHRoZXNlIGRvCisgICAgdW5zaWduZWQgc2hvcnQgZ2V0KGludCBrZXljb2RlLCBpbnQgbWV0YSk7CisgICAgdW5zaWduZWQgc2hvcnQgZ2V0TnVtYmVyKGludCBrZXljb2RlKTsKKyAgICB1bnNpZ25lZCBzaG9ydCBnZXRNYXRjaChpbnQga2V5Y29kZSwgY29uc3QgdW5zaWduZWQgc2hvcnQqIGNoYXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFyc2l6ZSwgdWludDMyX3QgbW9kaWZpZXJzKTsKKyAgICB1bnNpZ25lZCBzaG9ydCBnZXREaXNwbGF5TGFiZWwoaW50IGtleWNvZGUpOworICAgIGJvb2wgZ2V0S2V5RGF0YShpbnQga2V5Y29kZSwgdW5zaWduZWQgc2hvcnQgKmRpc3BsYXlMYWJlbCwKKyAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKm51bWJlciwgdW5zaWduZWQgc2hvcnQqIHJlc3VsdHMpOworICAgIGlubGluZSB1bnNpZ25lZCBpbnQgZ2V0S2V5Ym9hcmRUeXBlKCkgeyByZXR1cm4gbV90eXBlOyB9CisgICAgYm9vbCBnZXRFdmVudHModWludDE2X3QqIGNoYXJzLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgIFZlY3RvcjxpbnQzMl90Pioga2V5cywgVmVjdG9yPHVpbnQzMl90PiogbW9kaWZpZXJzKTsKKworICAgIHN0YXRpYyBLZXlDaGFyYWN0ZXJNYXAqIGxvYWQoaW50IGlkKTsKKworICAgIGVudW0geworICAgICAgICBOVU1FUklDID0gMSwKKyAgICAgICAgUTE0ID0gMiwKKyAgICAgICAgUVdFUlRZID0gMyAvLyBvciBBWkVSVFkgb3Igd2hhdGV2ZXIKKyAgICB9OworCisjZGVmaW5lIE1FVEFfTUFTSyAzCisKK3ByaXZhdGU6CisgICAgc3RydWN0IEtleQorICAgIHsKKyAgICAgICAgaW50MzJfdCBrZXljb2RlOworICAgICAgICB1aW50MTZfdCBkaXNwbGF5X2xhYmVsOworICAgICAgICB1aW50MTZfdCBudW1iZXI7CisgICAgICAgIHVpbnQxNl90IGRhdGFbTUVUQV9NQVNLICsgMV07CisgICAgfTsKKworICAgIEtleUNoYXJhY3Rlck1hcCgpOworICAgIHN0YXRpYyBLZXlDaGFyYWN0ZXJNYXAqIHRyeV9maWxlKGNvbnN0IGNoYXIqIGZpbGVuYW1lKTsKKyAgICBLZXkqIGZpbmRfa2V5KGludCBrZXljb2RlKTsKKyAgICBib29sIGZpbmRfY2hhcih1aW50MTZfdCBjLCB1aW50MzJfdCoga2V5LCB1aW50MzJfdCogbW9kcyk7CisKKyAgICB1bnNpZ25lZCBpbnQgbV90eXBlOworICAgIHVuc2lnbmVkIGludCBtX2tleUNvdW50OworICAgIEtleSogbV9rZXlzOworfTsKKworI2VuZGlmIC8vIF9VSV9LRVlfQ0hBUkFDVEVSX01BUF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL0tleWNvZGVMYWJlbHMuaCBiL2luY2x1ZGUvdWkvS2V5Y29kZUxhYmVscy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmYTZkMmIKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL0tleWNvZGVMYWJlbHMuaApAQCAtMCwwICsxLDIzNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgX1VJX0tFWUNPREVfTEFCRUxTX0gKKyNkZWZpbmUgX1VJX0tFWUNPREVfTEFCRUxTX0gKKworc3RydWN0IEtleWNvZGVMYWJlbCB7CisgICAgY29uc3QgY2hhciAqbGl0ZXJhbDsKKyAgICBpbnQgdmFsdWU7Cit9OworCitzdGF0aWMgY29uc3QgS2V5Y29kZUxhYmVsIEtFWUNPREVTW10gPSB7CisgICAgeyAiU09GVF9MRUZUIiwgMSB9LAorICAgIHsgIlNPRlRfUklHSFQiLCAyIH0sCisgICAgeyAiSE9NRSIsIDMgfSwKKyAgICB7ICJCQUNLIiwgNCB9LAorICAgIHsgIkNBTEwiLCA1IH0sCisgICAgeyAiRU5EQ0FMTCIsIDYgfSwKKyAgICB7ICIwIiwgNyB9LAorICAgIHsgIjEiLCA4IH0sCisgICAgeyAiMiIsIDkgfSwKKyAgICB7ICIzIiwgMTAgfSwKKyAgICB7ICI0IiwgMTEgfSwKKyAgICB7ICI1IiwgMTIgfSwKKyAgICB7ICI2IiwgMTMgfSwKKyAgICB7ICI3IiwgMTQgfSwKKyAgICB7ICI4IiwgMTUgfSwKKyAgICB7ICI5IiwgMTYgfSwKKyAgICB7ICJTVEFSIiwgMTcgfSwKKyAgICB7ICJQT1VORCIsIDE4IH0sCisgICAgeyAiRFBBRF9VUCIsIDE5IH0sCisgICAgeyAiRFBBRF9ET1dOIiwgMjAgfSwKKyAgICB7ICJEUEFEX0xFRlQiLCAyMSB9LAorICAgIHsgIkRQQURfUklHSFQiLCAyMiB9LAorICAgIHsgIkRQQURfQ0VOVEVSIiwgMjMgfSwKKyAgICB7ICJWT0xVTUVfVVAiLCAyNCB9LAorICAgIHsgIlZPTFVNRV9ET1dOIiwgMjUgfSwKKyAgICB7ICJQT1dFUiIsIDI2IH0sCisgICAgeyAiQ0FNRVJBIiwgMjcgfSwKKyAgICB7ICJDTEVBUiIsIDI4IH0sCisgICAgeyAiQSIsIDI5IH0sCisgICAgeyAiQiIsIDMwIH0sCisgICAgeyAiQyIsIDMxIH0sCisgICAgeyAiRCIsIDMyIH0sCisgICAgeyAiRSIsIDMzIH0sCisgICAgeyAiRiIsIDM0IH0sCisgICAgeyAiRyIsIDM1IH0sCisgICAgeyAiSCIsIDM2IH0sCisgICAgeyAiSSIsIDM3IH0sCisgICAgeyAiSiIsIDM4IH0sCisgICAgeyAiSyIsIDM5IH0sCisgICAgeyAiTCIsIDQwIH0sCisgICAgeyAiTSIsIDQxIH0sCisgICAgeyAiTiIsIDQyIH0sCisgICAgeyAiTyIsIDQzIH0sCisgICAgeyAiUCIsIDQ0IH0sCisgICAgeyAiUSIsIDQ1IH0sCisgICAgeyAiUiIsIDQ2IH0sCisgICAgeyAiUyIsIDQ3IH0sCisgICAgeyAiVCIsIDQ4IH0sCisgICAgeyAiVSIsIDQ5IH0sCisgICAgeyAiViIsIDUwIH0sCisgICAgeyAiVyIsIDUxIH0sCisgICAgeyAiWCIsIDUyIH0sCisgICAgeyAiWSIsIDUzIH0sCisgICAgeyAiWiIsIDU0IH0sCisgICAgeyAiQ09NTUEiLCA1NSB9LAorICAgIHsgIlBFUklPRCIsIDU2IH0sCisgICAgeyAiQUxUX0xFRlQiLCA1NyB9LAorICAgIHsgIkFMVF9SSUdIVCIsIDU4IH0sCisgICAgeyAiU0hJRlRfTEVGVCIsIDU5IH0sCisgICAgeyAiU0hJRlRfUklHSFQiLCA2MCB9LAorICAgIHsgIlRBQiIsIDYxIH0sCisgICAgeyAiU1BBQ0UiLCA2MiB9LAorICAgIHsgIlNZTSIsIDYzIH0sCisgICAgeyAiRVhQTE9SRVIiLCA2NCB9LAorICAgIHsgIkVOVkVMT1BFIiwgNjUgfSwKKyAgICB7ICJFTlRFUiIsIDY2IH0sCisgICAgeyAiREVMIiwgNjcgfSwKKyAgICB7ICJHUkFWRSIsIDY4IH0sCisgICAgeyAiTUlOVVMiLCA2OSB9LAorICAgIHsgIkVRVUFMUyIsIDcwIH0sCisgICAgeyAiTEVGVF9CUkFDS0VUIiwgNzEgfSwKKyAgICB7ICJSSUdIVF9CUkFDS0VUIiwgNzIgfSwKKyAgICB7ICJCQUNLU0xBU0giLCA3MyB9LAorICAgIHsgIlNFTUlDT0xPTiIsIDc0IH0sCisgICAgeyAiQVBPU1RST1BIRSIsIDc1IH0sCisgICAgeyAiU0xBU0giLCA3NiB9LAorICAgIHsgIkFUIiwgNzcgfSwKKyAgICB7ICJOVU0iLCA3OCB9LAorICAgIHsgIkhFQURTRVRIT09LIiwgNzkgfSwKKyAgICB7ICJGT0NVUyIsIDgwIH0sCisgICAgeyAiUExVUyIsIDgxIH0sCisgICAgeyAiTUVOVSIsIDgyIH0sCisgICAgeyAiTk9USUZJQ0FUSU9OIiwgODMgfSwKKyAgICB7ICJTRUFSQ0giLCA4NCB9LAorICAgIHsgIlBMQVlQQVVTRSIsIDg1IH0sCisgICAgeyAiU1RPUCIsIDg2IH0sCisgICAgeyAiTkVYVFNPTkciLCA4NyB9LAorICAgIHsgIlBSRVZJT1VTU09ORyIsIDg4IH0sCisgICAgeyAiUkVXSU5EIiwgODkgfSwKKyAgICB7ICJGT1JXQVJEIiwgOTAgfSwKKyAgICB7ICJNVVRFIiwgOTEgfSwKKworICAgIC8vIE5PVEU6IElmIHlvdSBhZGQgYSBuZXcga2V5Y29kZSBoZXJlIHlvdSBtdXN0IGFsc28gYWRkIGl0IHRvOgorICAgIC8vICAgKGVudW0gS2V5Q29kZSwgaW4gdGhpcyBmaWxlKQorICAgIC8vICAgZnJhbWV3b3Jrcy9iYXNlL2NvcmUvamF2YS9hbmRyb2lkL3ZpZXcvS2V5RXZlbnQuamF2YQorICAgIC8vICAgdG9vbHMvcHVwcGV0X21hc3Rlci9QdXBwZXRNYXN0ZXIubmF2X2tleXMucHkKKyAgICAvLyAgIGZyYW1ld29ya3MvYmFzZS9jb3JlL3Jlcy9yZXMvdmFsdWVzL2F0dHJzLnhtbAorCisgICAgeyBOVUxMLCAwIH0KK307CisKKy8vIFRoZXNlIGNvbnN0YW50cyBuZWVkIHRvIG1hdGNoIHRoZSBhYm92ZSBtYXBwaW5ncy4KK3R5cGVkZWYgZW51bSBLZXlDb2RlIHsKKyAgICBrS2V5Q29kZVVua25vd24gPSAwLAorCisgICAga0tleUNvZGVTb2Z0TGVmdCA9IDEsCisgICAga0tleUNvZGVTb2Z0UmlnaHQgPSAyLAorICAgIGtLZXlDb2RlSG9tZSA9IDMsCisgICAga0tleUNvZGVCYWNrID0gNCwKKyAgICBrS2V5Q29kZUNhbGwgPSA1LAorICAgIGtLZXlDb2RlRW5kQ2FsbCA9IDYsCisgICAga0tleUNvZGUwID0gNywKKyAgICBrS2V5Q29kZTEgPSA4LAorICAgIGtLZXlDb2RlMiA9IDksCisgICAga0tleUNvZGUzID0gMTAsCisgICAga0tleUNvZGU0ID0gMTEsCisgICAga0tleUNvZGU1ID0gMTIsCisgICAga0tleUNvZGU2ID0gMTMsCisgICAga0tleUNvZGU3ID0gMTQsCisgICAga0tleUNvZGU4ID0gMTUsCisgICAga0tleUNvZGU5ID0gMTYsCisgICAga0tleUNvZGVTdGFyID0gMTcsCisgICAga0tleUNvZGVQb3VuZCA9IDE4LAorICAgIGtLZXlDb2RlRHBhZFVwID0gMTksCisgICAga0tleUNvZGVEcGFkRG93biA9IDIwLAorICAgIGtLZXlDb2RlRHBhZExlZnQgPSAyMSwKKyAgICBrS2V5Q29kZURwYWRSaWdodCA9IDIyLAorICAgIGtLZXlDb2RlRHBhZENlbnRlciA9IDIzLAorICAgIGtLZXlDb2RlVm9sdW1lVXAgPSAyNCwKKyAgICBrS2V5Q29kZVZvbHVtZURvd24gPSAyNSwKKyAgICBrS2V5Q29kZVBvd2VyID0gMjYsCisgICAga0tleUNvZGVDYW1lcmEgPSAyNywKKyAgICBrS2V5Q29kZUNsZWFyID0gMjgsCisgICAga0tleUNvZGVBID0gMjksCisgICAga0tleUNvZGVCID0gMzAsCisgICAga0tleUNvZGVDID0gMzEsCisgICAga0tleUNvZGVEID0gMzIsCisgICAga0tleUNvZGVFID0gMzMsCisgICAga0tleUNvZGVGID0gMzQsCisgICAga0tleUNvZGVHID0gMzUsCisgICAga0tleUNvZGVIID0gMzYsCisgICAga0tleUNvZGVJID0gMzcsCisgICAga0tleUNvZGVKID0gMzgsCisgICAga0tleUNvZGVLID0gMzksCisgICAga0tleUNvZGVMID0gNDAsCisgICAga0tleUNvZGVNID0gNDEsCisgICAga0tleUNvZGVOID0gNDIsCisgICAga0tleUNvZGVPID0gNDMsCisgICAga0tleUNvZGVQID0gNDQsCisgICAga0tleUNvZGVRID0gNDUsCisgICAga0tleUNvZGVSID0gNDYsCisgICAga0tleUNvZGVTID0gNDcsCisgICAga0tleUNvZGVUID0gNDgsCisgICAga0tleUNvZGVVID0gNDksCisgICAga0tleUNvZGVWID0gNTAsCisgICAga0tleUNvZGVXID0gNTEsCisgICAga0tleUNvZGVYID0gNTIsCisgICAga0tleUNvZGVZID0gNTMsCisgICAga0tleUNvZGVaID0gNTQsCisgICAga0tleUNvZGVDb21tYSA9IDU1LAorICAgIGtLZXlDb2RlUGVyaW9kID0gNTYsCisgICAga0tleUNvZGVBbHRMZWZ0ID0gNTcsCisgICAga0tleUNvZGVBbHRSaWdodCA9IDU4LAorICAgIGtLZXlDb2RlU2hpZnRMZWZ0ID0gNTksCisgICAga0tleUNvZGVTaGlmdFJpZ2h0ID0gNjAsCisgICAga0tleUNvZGVUYWIgPSA2MSwKKyAgICBrS2V5Q29kZVNwYWNlID0gNjIsCisgICAga0tleUNvZGVTeW0gPSA2MywKKyAgICBrS2V5Q29kZUV4cGxvcmVyID0gNjQsCisgICAga0tleUNvZGVFbnZlbG9wZSA9IDY1LAorICAgIGtLZXlDb2RlTmV3bGluZSA9IDY2LAorICAgIGtLZXlDb2RlRGVsID0gNjcsCisgICAga0tleUNvZGVHcmF2ZSA9IDY4LAorICAgIGtLZXlDb2RlTWludXMgPSA2OSwKKyAgICBrS2V5Q29kZUVxdWFscyA9IDcwLAorICAgIGtLZXlDb2RlTGVmdEJyYWNrZXQgPSA3MSwKKyAgICBrS2V5Q29kZVJpZ2h0QnJhY2tldCA9IDcyLAorICAgIGtLZXlDb2RlQmFja3NsYXNoID0gNzMsCisgICAga0tleUNvZGVTZW1pY29sb24gPSA3NCwKKyAgICBrS2V5Q29kZUFwb3N0cm9waGUgPSA3NSwKKyAgICBrS2V5Q29kZVNsYXNoID0gNzYsCisgICAga0tleUNvZGVBdCA9IDc3LAorICAgIGtLZXlDb2RlTnVtID0gNzgsCisgICAga0tleUNvZGVIZWFkU2V0SG9vayA9IDc5LAorICAgIGtLZXlDb2RlRm9jdXMgPSA4MCwKKyAgICBrS2V5Q29kZVBsdXMgPSA4MSwKKyAgICBrS2V5Q29kZU1lbnUgPSA4MiwKKyAgICBrS2V5Q29kZU5vdGlmaWNhdGlvbiA9IDgzLAorICAgIGtLZXlDb2RlU2VhcmNoID0gODQsCisgICAga0tleUNvZGVQbGF5UGF1c2UgPSA4NSwKKyAgICBrS2V5Q29kZVN0b3AgPSA4NiwKKyAgICBrS2V5Q29kZU5leHRTb25nID0gODcsCisgICAga0tleUNvZGVQcmV2aW91c1NvbmcgPSA4OCwKKyAgICBrS2V5Q29kZVJld2luZCA9IDg5LAorICAgIGtLZXlDb2RlRm9yd2FyZCA9IDkwLAorICAgIGtLZXlDb2RlTXV0ZSA9IDkxCit9IEtleUNvZGU7CisKK3N0YXRpYyBjb25zdCBLZXljb2RlTGFiZWwgRkxBR1NbXSA9IHsKKyAgICB7ICJXQUtFIiwgMHgwMDAwMDAwMSB9LAorICAgIHsgIldBS0VfRFJPUFBFRCIsIDB4MDAwMDAwMDIgfSwKKyAgICB7ICJTSElGVCIsIDB4MDAwMDAwMDQgfSwKKyAgICB7ICJDQVBTX0xPQ0siLCAweDAwMDAwMDA4IH0sCisgICAgeyAiQUxUIiwgMHgwMDAwMDAxMCB9LAorICAgIHsgIkFMVF9HUiIsIDB4MDAwMDAwMjAgfSwKKyAgICB7ICJNRU5VIiwgMHgwMDAwMDA0MCB9LAorICAgIHsgIkxBVU5DSEVSIiwgMHgwMDAwMDA4MCB9LAorICAgIHsgTlVMTCwgMCB9Cit9OworCisjZW5kaWYgLy8gX1VJX0tFWUNPREVfTEFCRUxTX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWkvT3ZlcmxheS5oIGIvaW5jbHVkZS91aS9PdmVybGF5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjY1MTRiNAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvT3ZlcmxheS5oCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX09WRVJMQVlfSAorI2RlZmluZSBBTkRST0lEX09WRVJMQVlfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9JSW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8dXRpbHMvUmVmQmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvSU92ZXJsYXkuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlL292ZXJsYXkuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJTWVtb3J5OworY2xhc3MgSU1lbW9yeUhlYXA7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgT3ZlcmxheVJlZiA6IHB1YmxpYyBMaWdodFJlZkJhc2U8T3ZlcmxheVJlZj4KK3sKK3B1YmxpYzoKKyAgICBPdmVybGF5UmVmKG92ZXJsYXlfaGFuZGxlX3QsIGNvbnN0IHNwPElPdmVybGF5PiYsCisgICAgICAgICAgICB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGYsIHVpbnQzMl90IHdzLCB1aW50MzJfdCBocyk7CisKKyAgICBzdGF0aWMgc3A8T3ZlcmxheVJlZj4gcmVhZEZyb21QYXJjZWwoY29uc3QgUGFyY2VsJiBkYXRhKTsKKyAgICBzdGF0aWMgc3RhdHVzX3Qgd3JpdGVUb1BhcmNlbChQYXJjZWwqIHJlcGx5LCBjb25zdCBzcDxPdmVybGF5UmVmPiYgbyk7ICAgIAorCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBMaWdodFJlZkJhc2U8T3ZlcmxheVJlZj47CisgICAgZnJpZW5kIGNsYXNzIE92ZXJsYXk7CisKKyAgICBPdmVybGF5UmVmKCk7CisgICAgdmlydHVhbCB+T3ZlcmxheVJlZigpOworCisgICAgb3ZlcmxheV9oYW5kbGVfdCBtT3ZlcmxheUhhbmRsZTsKKyAgICBzcDxJT3ZlcmxheT4gbU92ZXJsYXlDaGFubmVsOworICAgIHVpbnQzMl90IG1XaWR0aDsKKyAgICB1aW50MzJfdCBtSGVpZ2h0OworICAgIGludDMyX3QgIG1Gb3JtYXQ7CisgICAgaW50MzJfdCAgbVdpZHRoU3RyaWRlOworICAgIGludDMyX3QgIG1IZWlnaHRTdHJpZGU7CisgICAgYm9vbCBtT3duSGFuZGxlOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBPdmVybGF5IDogcHVibGljIHZpcnR1YWwgUmVmQmFzZQoreworcHVibGljOgorICAgIE92ZXJsYXkoY29uc3Qgc3A8T3ZlcmxheVJlZj4mIG92ZXJsYXlSZWYpOworCisgICAgLyogZGVzdHJveXMgdGhpcyBvdmVybGF5ICovCisgICAgdm9pZCBkZXN0cm95KCk7CisgICAgCisgICAgLyogZ2V0IHRoZSBIQUwgaGFuZGxlIGZvciB0aGlzIG92ZXJsYXkgKi8KKyAgICBvdmVybGF5X2hhbmRsZV90IGdldEhhbmRsZVJlZigpIGNvbnN0OworCisgICAgLyogYmxvY2tzIHVudGlsIGFuIG92ZXJsYXkgYnVmZmVyIGlzIGF2YWlsYWJsZSBhbmQgcmV0dXJuIHRoYXQgYnVmZmVyLiAqLworICAgIHN0YXR1c190IGRlcXVldWVCdWZmZXIob3ZlcmxheV9idWZmZXJfdCogYnVmZmVyKTsKKworICAgIC8qIHJlbGVhc2UgdGhlIG92ZXJsYXkgYnVmZmVyIGFuZCBwb3N0IGl0ICovCisgICAgc3RhdHVzX3QgcXVldWVCdWZmZXIob3ZlcmxheV9idWZmZXJfdCBidWZmZXIpOworCisgICAgLyogcmV0dXJucyB0aGUgYWRkcmVzcyBvZiBhIGdpdmVuIGJ1ZmZlciBpZiBzdXBwb3J0ZWQsIE5VTEwgb3RoZXJ3aXNlLiAqLworICAgIHZvaWQqIGdldEJ1ZmZlckFkZHJlc3Mob3ZlcmxheV9idWZmZXJfdCBidWZmZXIpOworCisgICAgLyogZ2V0IHBoeXNpY2FsIGluZm9ybWF0aW9ucyBhYm91dCB0aGUgb3ZlcmxheSAqLworICAgIHVpbnQzMl90IGdldFdpZHRoKCkgY29uc3Q7CisgICAgdWludDMyX3QgZ2V0SGVpZ2h0KCkgY29uc3Q7CisgICAgaW50MzJfdCBnZXRGb3JtYXQoKSBjb25zdDsKKyAgICBpbnQzMl90IGdldFdpZHRoU3RyaWRlKCkgY29uc3Q7CisgICAgaW50MzJfdCBnZXRIZWlnaHRTdHJpZGUoKSBjb25zdDsKKyAgICBpbnQzMl90IGdldEJ1ZmZlckNvdW50KCkgY29uc3Q7CisgICAgc3RhdHVzX3QgZ2V0U3RhdHVzKCkgY29uc3Q7CisgICAgCitwcml2YXRlOgorICAgIHZpcnR1YWwgfk92ZXJsYXkoKTsKKworICAgIHNwPE92ZXJsYXlSZWY+IG1PdmVybGF5UmVmOworICAgIG92ZXJsYXlfZGF0YV9kZXZpY2VfdCAqbU92ZXJsYXlEYXRhOworICAgIHN0YXR1c190IG1TdGF0dXM7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09WRVJMQVlfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9QaXhlbEZvcm1hdC5oIGIvaW5jbHVkZS91aS9QaXhlbEZvcm1hdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0YWY4MjMKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL1BpeGVsRm9ybWF0LmgKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworCisvLyBQaXhlbCBmb3JtYXRzIHVzZWQgYWNyb3NzIHRoZSBzeXN0ZW0uCisvLyBUaGVzZSBmb3JtYXRzIG1pZ2h0IG5vdCBhbGwgYmUgc3VwcG9ydGVkIGJ5IGFsbCByZW5kZXJlcnMsIGZvciBpbnN0YW5jZQorLy8gc2tpYSBvciBTdXJmYWNlRmxpbmdlciBhcmUgbm90IHJlcXVpcmVkIHRvIHN1cHBvcnQgYWxsIG9mIHRoZXNlIGZvcm1hdHMKKy8vIChlaXRoZXIgYXMgc291cmNlIG9yIGRlc3RpbmF0aW9uKQorCisvLyBYWFg6IHdlIHNob3VsZCBjb25zb2xpZGF0ZSB0aGVzZSBmb3JtYXRzIGFuZCBza2lhJ3MKKworI2lmbmRlZiBVSV9QSVhFTEZPUk1BVF9ICisjZGVmaW5lIFVJX1BJWEVMRk9STUFUX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHBpeGVsZmxpbmdlci9mb3JtYXQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitlbnVtIHsKKyAgICAvLworICAgIC8vIHRoZXNlIGNvbnN0YW50cyBuZWVkIHRvIG1hdGNoIHRob3NlCisgICAgLy8gaW4gZ3JhcGhpY3MvUGl4ZWxGb3JtYXQuamF2YSAmIHBpeGVsZmxpbmdlci9mb3JtYXQuaAorICAgIC8vCisgICAgUElYRUxfRk9STUFUX1VOS05PV04gICAgPSAgIDAsCisgICAgUElYRUxfRk9STUFUX05PTkUgICAgICAgPSAgIDAsCisKKyAgICAvLyBsb2dpY2FsIHBpeGVsIGZvcm1hdHMgdXNlZCBieSB0aGUgU3VyZmFjZUZsaW5nZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBQSVhFTF9GT1JNQVRfQ1VTVE9NICAgICAgICAgPSAtNCwKKyAgICAgICAgLy8gQ3VzdG9tIHBpeGVsLWZvcm1hdCBkZXNjcmliZWQgYnkgYSBQaXhlbEZvcm1hdEluZm8gc3RydWN0dXJlCisKKyAgICBQSVhFTF9GT1JNQVRfVFJBTlNMVUNFTlQgICAgPSAtMywKKyAgICAgICAgLy8gU3lzdGVtIGNob29zZXMgYSBmb3JtYXQgdGhhdCBzdXBwb3J0cyB0cmFuc2x1Y2VuY3kgKG1hbnkgYWxwaGEgYml0cykKKworICAgIFBJWEVMX0ZPUk1BVF9UUkFOU1BBUkVOVCAgICA9IC0yLAorICAgICAgICAvLyBTeXN0ZW0gY2hvb3NlcyBhIGZvcm1hdCB0aGF0IHN1cHBvcnRzIHRyYW5zcGFyZW5jeQorICAgICAgICAvLyAoYXQgbGVhc3QgMSBhbHBoYSBiaXQpCisKKyAgICBQSVhFTF9GT1JNQVRfT1BBUVVFICAgICAgICAgPSAtMSwKKyAgICAgICAgLy8gU3lzdGVtIGNob29zZXMgYW4gb3BhcXVlIGZvcm1hdCAobm8gYWxwaGEgYml0cyByZXF1aXJlZCkKKyAgICAKKyAgICAvLyByZWFsIHBpeGVsIGZvcm1hdHMgc3VwcG9ydGVkIGZvciByZW5kZXJpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIFBJWEVMX0ZPUk1BVF9SR0JBXzg4ODggICA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4LCAgLy8gNHg4LWJpdCBSR0JBCisgICAgUElYRUxfRk9STUFUX1JHQlhfODg4OCAgID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JYXzg4ODgsICAvLyA0eDgtYml0IFJHQjAKKyAgICBQSVhFTF9GT1JNQVRfUkdCXzg4OCAgICAgPSBHR0xfUElYRUxfRk9STUFUX1JHQl84ODgsICAgIC8vIDN4OC1iaXQgUkdCCisgICAgUElYRUxfRk9STUFUX1JHQl81NjUgICAgID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1LCAgICAvLyAxNi1iaXQgUkdCCisgICAgUElYRUxfRk9STUFUX0JHUkFfODg4OCAgID0gR0dMX1BJWEVMX0ZPUk1BVF9CR1JBXzg4ODgsICAvLyA0eDgtYml0IEJHUkEKKyAgICBQSVhFTF9GT1JNQVRfUkdCQV81NTUxICAgPSBHR0xfUElYRUxfRk9STUFUX1JHQkFfNTU1MSwgIC8vIDE2LWJpdCBBUkdCCisgICAgUElYRUxfRk9STUFUX1JHQkFfNDQ0NCAgID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzQ0NDQsICAvLyAxNi1iaXQgQVJHQgorICAgIFBJWEVMX0ZPUk1BVF9BXzggICAgICAgICA9IEdHTF9QSVhFTF9GT1JNQVRfQV84LCAgICAgICAgLy8gOC1iaXQgQQorICAgIFBJWEVMX0ZPUk1BVF9MXzggICAgICAgICA9IEdHTF9QSVhFTF9GT1JNQVRfTF84LCAgICAgICAgLy8gOC1iaXQgTCAoUj1HPUI9TCkKKyAgICBQSVhFTF9GT1JNQVRfTEFfODggICAgICAgPSBHR0xfUElYRUxfRk9STUFUX0xBXzg4LCAgICAgIC8vIDE2LWJpdCBMQQorICAgIFBJWEVMX0ZPUk1BVF9SR0JfMzMyICAgICA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzMzMiwgICAgLy8gOC1iaXQgUkdCCisKKyAgICBQSVhFTF9GT1JNQVRfWUNiQ3JfNDIyX1NQPSBHR0xfUElYRUxfRk9STUFUX1lDYkNyXzQyMl9TUCwKKyAgICBQSVhFTF9GT1JNQVRfWUNiQ3JfNDIwX1NQPSBHR0xfUElYRUxfRk9STUFUX1lDYkNyXzQyMF9TUCwKKyAgICBQSVhFTF9GT1JNQVRfWUNiQ3JfNDIyX1AgPSBHR0xfUElYRUxfRk9STUFUX1lDYkNyXzQyMl9QLAorICAgIFBJWEVMX0ZPUk1BVF9ZQ2JDcl80MjBfUCA9IEdHTF9QSVhFTF9GT1JNQVRfWUNiQ3JfNDIwX1AsCisgICAgUElYRUxfRk9STUFUX1lDYkNyXzQyMl9JID0gR0dMX1BJWEVMX0ZPUk1BVF9ZQ2JDcl80MjJfSSwKKyAgICBQSVhFTF9GT1JNQVRfWUNiQ3JfNDIwX0kgPSBHR0xfUElYRUxfRk9STUFUX1lDYkNyXzQyMF9JLAorCisgICAgLy8gTmV3IGZvcm1hdHMgY2FuIGJlIGFkZGVkIGlmIHRoZXkncmUgYWxzbyBkZWZpbmVkIGluCisgICAgLy8gcGl4ZWxmbGluZ2VyL2Zvcm1hdC5oCit9OworCit0eXBlZGVmIGludDMyX3QgUGl4ZWxGb3JtYXQ7CisKK3N0cnVjdCBQaXhlbEZvcm1hdEluZm8KK3sKKyAgICBlbnVtIHsgLy8gY29tcG9uZW50cworICAgICAgICBBTFBIQSAgICAgICAgICAgICAgID0gMSwKKyAgICAgICAgUkdCICAgICAgICAgICAgICAgICA9IDIsCisgICAgICAgIFJHQkEgICAgICAgICAgICAgICAgPSAzLAorICAgICAgICBMVU1JTkFOQ0UgICAgICAgICAgID0gNCwKKyAgICAgICAgTFVNSU5BTkNFX0FMUEhBICAgICA9IDUsCisgICAgICAgIFlfQ0JfQ1JfU1AgICAgICAgICAgPSA2LAorICAgICAgICBZX0NCX0NSX1AgICAgICAgICAgID0gNywKKyAgICAgICAgWV9DQl9DUl9JICAgICAgICAgICA9IDgsCisgICAgfTsKKworICAgIGlubGluZSBQaXhlbEZvcm1hdEluZm8oKSA6IHZlcnNpb24oc2l6ZW9mKFBpeGVsRm9ybWF0SW5mbykpIHsgfQorICAgIHNpemVfdCBnZXRTY2FubGluZVNpemUodW5zaWduZWQgaW50IHdpZHRoKSBjb25zdDsKKyAgICBzaXplX3QgICAgICB2ZXJzaW9uOworICAgIFBpeGVsRm9ybWF0IGZvcm1hdDsKKyAgICBzaXplX3QgICAgICBieXRlc1BlclBpeGVsOworICAgIHNpemVfdCAgICAgIGJpdHNQZXJQaXhlbDsKKyAgICB1aW50OF90ICAgICBoX2FscGhhOworICAgIHVpbnQ4X3QgICAgIGxfYWxwaGE7CisgICAgdWludDhfdCAgICAgaF9yZWQ7CisgICAgdWludDhfdCAgICAgbF9yZWQ7CisgICAgdWludDhfdCAgICAgaF9ncmVlbjsKKyAgICB1aW50OF90ICAgICBsX2dyZWVuOworICAgIHVpbnQ4X3QgICAgIGhfYmx1ZTsKKyAgICB1aW50OF90ICAgICBsX2JsdWU7CisgICAgdWludDhfdCAgICAgY29tcG9uZW50czsKKyAgICB1aW50OF90ICAgICByZXNlcnZlZDBbM107CisgICAgdWludDMyX3QgICAgcmVzZXJ2ZWQxOworfTsKKworLy8gQ29uc2lkZXIgY2FjaGluZyB0aGUgcmVzdWx0cyBvZiB0aGVzZSBmdW5jdGlvbnMgYXJlIHRoZXkncmUgbm90CisvLyBndWFyYW50ZWVkIHRvIGJlIGZhc3QuCitzc2l6ZV90ICAgICBieXRlc1BlclBpeGVsKFBpeGVsRm9ybWF0IGZvcm1hdCk7Citzc2l6ZV90ICAgICBiaXRzUGVyUGl4ZWwoUGl4ZWxGb3JtYXQgZm9ybWF0KTsKK3N0YXR1c190ICAgIGdldFBpeGVsRm9ybWF0SW5mbyhQaXhlbEZvcm1hdCBmb3JtYXQsIFBpeGVsRm9ybWF0SW5mbyogaW5mbyk7CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBVSV9QSVhFTEZPUk1BVF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL1BvaW50LmggYi9pbmNsdWRlL3VpL1BvaW50LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJiYWQxZQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvUG9pbnQuaApAQCAtMCwwICsxLDg4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1VJX1BPSU5UCisjZGVmaW5lIEFORFJPSURfVUlfUE9JTlQKKworI2luY2x1ZGUgPHV0aWxzL1R5cGVIZWxwZXJzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgUG9pbnQKK3sKK3B1YmxpYzoKKyAgICBpbnQgeDsKKyAgICBpbnQgeTsKKworICAgIC8vIHdlIGRvbid0IHByb3ZpZGUgY29weS1jdG9yIGFuZCBvcGVyYXRvcj0gb24gcHVycG9zZQorICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgZ2VuZXJhdGVkIHZlcnNpb25zCisKKyAgICAvLyBEZWZhdWx0IGNvbnN0cnVjdG9yIGRvZXNuJ3QgaW5pdGlhbGl6ZSB0aGUgUG9pbnQKKyAgICBpbmxpbmUgUG9pbnQoKQorICAgIHsKKyAgICB9CisKKyAgICBpbmxpbmUgUG9pbnQoaW50IF94LCBpbnQgX3kpIDogeChfeCksIHkoX3kpCisgICAgeworICAgIH0KKworICAgIGlubGluZSBib29sIG9wZXJhdG9yID09IChjb25zdCBQb2ludCYgcmhzKSBjb25zdCB7CisgICAgICAgIHJldHVybiAoeCA9PSByaHMueCkgJiYgKHkgPT0gcmhzLnkpOworICAgIH0KKyAgICBpbmxpbmUgYm9vbCBvcGVyYXRvciAhPSAoY29uc3QgUG9pbnQmIHJocykgY29uc3QgeworICAgICAgICByZXR1cm4gIW9wZXJhdG9yID09IChyaHMpOworICAgIH0KKworICAgIGlubGluZSBib29sIGlzT3JpZ2luKCkgY29uc3QgeworICAgICAgICByZXR1cm4gISh4fHkpOworICAgIH0KKworICAgIC8vIG9wZXJhdG9yIDwgZGVmaW5lcyBhbiBvcmRlciB3aGljaCBhbGxvd3MgdG8gdXNlIHBvaW50cyBpbiBzb3J0ZWQKKyAgICAvLyB2ZWN0b3JzLgorICAgIGJvb2wgb3BlcmF0b3IgPCAoY29uc3QgUG9pbnQmIHJocykgY29uc3QgeworICAgICAgICByZXR1cm4geTxyaHMueSB8fCAoeT09cmhzLnkgJiYgeDxyaHMueCk7CisgICAgfQorCisgICAgaW5saW5lIFBvaW50JiBvcGVyYXRvciAtICgpIHsKKyAgICAgICAgeD0teDsKKyAgICAgICAgeT0teTsKKyAgICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICAKKyAgICBpbmxpbmUgUG9pbnQmIG9wZXJhdG9yICs9IChjb25zdCBQb2ludCYgcmhzKSB7CisgICAgICAgIHggKz0gcmhzLng7CisgICAgICAgIHkgKz0gcmhzLnk7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgaW5saW5lIFBvaW50JiBvcGVyYXRvciAtPSAoY29uc3QgUG9pbnQmIHJocykgeworICAgICAgICB4IC09IHJocy54OworICAgICAgICB5IC09IHJocy55OworICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorICAgIAorICAgIFBvaW50IG9wZXJhdG9yICsgKGNvbnN0IFBvaW50JiByaHMpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIFBvaW50KHgrcmhzLngsIHkrcmhzLnkpOworICAgIH0KKyAgICBQb2ludCBvcGVyYXRvciAtIChjb25zdCBQb2ludCYgcmhzKSBjb25zdCB7CisgICAgICAgIHJldHVybiBQb2ludCh4LXJocy54LCB5LXJocy55KTsKKyAgICB9ICAgIAorfTsKKworQU5EUk9JRF9CQVNJQ19UWVBFU19UUkFJVFMoUG9pbnQpCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX1VJX1BPSU5UCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL1JlY3QuaCBiL2luY2x1ZGUvdWkvUmVjdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMzI4NDcKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3VpL1JlY3QuaApAQCAtMCwwICsxLDE1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9VSV9SRUNUCisjZGVmaW5lIEFORFJPSURfVUlfUkVDVAorCisjaW5jbHVkZSA8dXRpbHMvVHlwZUhlbHBlcnMuaD4KKyNpbmNsdWRlIDx1aS9Qb2ludC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIFJlY3QKK3sKK3B1YmxpYzoKKyAgICBpbnQgbGVmdDsKKyAgICBpbnQgdG9wOworICAgIGludCByaWdodDsKKyAgICBpbnQgYm90dG9tOworCisgICAgLy8gd2UgZG9uJ3QgcHJvdmlkZSBjb3B5LWN0b3IgYW5kIG9wZXJhdG9yPSBvbiBwdXJwb3NlCisgICAgLy8gYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciBnZW5lcmF0ZWQgdmVyc2lvbnMKKworICAgIGlubGluZSBSZWN0KCkKKyAgICB7CisgICAgfQorCisgICAgaW5saW5lIFJlY3QoaW50IHcsIGludCBoKQorICAgICAgICA6IGxlZnQoMCksIHRvcCgwKSwgcmlnaHQodyksIGJvdHRvbShoKQorICAgIHsKKyAgICB9CisKKyAgICBpbmxpbmUgUmVjdChpbnQgbCwgaW50IHQsIGludCByLCBpbnQgYikKKyAgICAgICAgOiBsZWZ0KGwpLCB0b3AodCksIHJpZ2h0KHIpLCBib3R0b20oYikKKyAgICB7CisgICAgfQorCisgICAgaW5saW5lIFJlY3QoY29uc3QgUG9pbnQmIGx0LCBjb25zdCBQb2ludCYgcmIpIAorICAgICAgICA6IGxlZnQobHQueCksIHRvcChsdC55KSwgcmlnaHQocmIueCksIGJvdHRvbShyYi55KQorICAgIHsKKyAgICB9CisKKyAgICB2b2lkIG1ha2VJbnZhbGlkKCk7CisgICAgCisgICAgLy8gYSB2YWxpZCByZWN0YW5nbGUgaGFzIGEgbm9uIG5lZ2F0aXZlIHdpZHRoIGFuZCBoZWlnaHQKKyAgICBpbmxpbmUgYm9vbCBpc1ZhbGlkKCkgY29uc3QgeworICAgICAgICByZXR1cm4gKHdpZHRoKCk+PTApICYmIChoZWlnaHQoKT49MCk7CisgICAgfQorCisgICAgLy8gYW4gZW1wdHkgcmVjdCBoYXMgYSB6ZXJvIHdpZHRoIG9yIGhlaWdodCwgb3IgaXMgaW52YWxpZAorICAgIGlubGluZSBib29sIGlzRW1wdHkoKSBjb25zdCB7CisgICAgICAgIHJldHVybiAod2lkdGgoKTw9MCkgfHwgKGhlaWdodCgpPD0wKTsKKyAgICB9CisKKyAgICBpbmxpbmUgdm9pZCBzZXQoY29uc3QgUmVjdCYgcmhzKSB7CisgICAgICAgIG9wZXJhdG9yID0gKHJocyk7CisgICAgfQorCisgICAgLy8gcmVjdGFuZ2xlJ3Mgd2lkdGgKKyAgICBpbmxpbmUgaW50IHdpZHRoKCkgY29uc3QgeworICAgICAgICByZXR1cm4gcmlnaHQtbGVmdDsKKyAgICB9CisgICAgCisgICAgLy8gcmVjdGFuZ2xlJ3MgaGVpZ2h0CisgICAgaW5saW5lIGludCBoZWlnaHQoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBib3R0b20tdG9wOworICAgIH0KKworICAgIC8vIHJldHVybnMgbGVmdC10b3AgUG9pbnQgbm9uLWNvbnN0IHJlZmVyZW5jZSwgY2FuIGJlIGFzc2lnbmVkCisgICAgaW5saW5lIFBvaW50JiBsZWZ0VG9wKCkgeworICAgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQb2ludCY+KGxlZnQpOworICAgIH0KKyAgICAvLyByZXR1cm5zIHJpZ2h0IGJvdHRvbSBub24tY29uc3QgcmVmZXJlbmNlLCBjYW4gYmUgYXNzaWduZWQKKyAgICBpbmxpbmUgUG9pbnQmIHJpZ2h0Qm90dG9tKCkgeworICAgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQb2ludCY+KHJpZ2h0KTsKKyAgICB9CisgICAgCisgICAgLy8gdGhlIGZvbGxvd2luZyA0IGZ1bmN0aW9ucyByZXR1cm4gdGhlIDQgY29ybmVycyBvZiB0aGUgcmVjdCBhcyBQb2ludAorICAgIGlubGluZSBjb25zdCBQb2ludCYgbGVmdFRvcCgpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUG9pbnQmPihsZWZ0KTsKKyAgICB9CisgICAgaW5saW5lIGNvbnN0IFBvaW50JiByaWdodEJvdHRvbSgpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUG9pbnQmPihyaWdodCk7CisgICAgfQorICAgIFBvaW50IHJpZ2h0VG9wKCkgY29uc3QgeworICAgICAgICByZXR1cm4gUG9pbnQocmlnaHQsIHRvcCk7CisgICAgfQorICAgIFBvaW50IGxlZnRCb3R0b20oKSBjb25zdCB7CisgICAgICAgIHJldHVybiBQb2ludChsZWZ0LCBib3R0b20pOworICAgIH0KKworICAgIC8vIGNvbXBhcmlzb25zCisgICAgaW5saW5lIGJvb2wgb3BlcmF0b3IgPT0gKGNvbnN0IFJlY3QmIHJocykgY29uc3QgeworICAgICAgICByZXR1cm4gKGxlZnQgPT0gcmhzLmxlZnQpICYmICh0b3AgPT0gcmhzLnRvcCkgJiYKKyAgICAgICAgICAgICAgIChyaWdodCA9PSByaHMucmlnaHQpICYmIChib3R0b20gPT0gcmhzLmJvdHRvbSk7CisgICAgfQorCisgICAgaW5saW5lIGJvb2wgb3BlcmF0b3IgIT0gKGNvbnN0IFJlY3QmIHJocykgY29uc3QgeworICAgICAgICByZXR1cm4gIW9wZXJhdG9yID09IChyaHMpOworICAgIH0KKworICAgIC8vIG9wZXJhdG9yIDwgZGVmaW5lcyBhbiBvcmRlciB3aGljaCBhbGxvd3MgdG8gdXNlIHJlY3RhbmdsZXMgaW4gc29ydGVkCisgICAgLy8gdmVjdG9ycy4KKyAgICBib29sIG9wZXJhdG9yIDwgKGNvbnN0IFJlY3QmIHJocykgY29uc3Q7CisKKyAgICBSZWN0JiBvZmZzZXRUb09yaWdpbigpIHsKKyAgICAgICAgcmlnaHQgLT0gbGVmdDsKKyAgICAgICAgYm90dG9tIC09IHRvcDsKKyAgICAgICAgbGVmdCA9IHRvcCA9IDA7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgUmVjdCYgb2Zmc2V0VG8oY29uc3QgUG9pbnQmIHApIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldFRvKHAueCwgcC55KTsKKyAgICB9CisgICAgUmVjdCYgb2Zmc2V0QnkoY29uc3QgUG9pbnQmIGRwKSB7CisgICAgICAgIHJldHVybiBvZmZzZXRCeShkcC54LCBkcC55KTsKKyAgICB9CisgICAgUmVjdCYgb3BlcmF0b3IgKz0gKGNvbnN0IFBvaW50JiByaHMpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldEJ5KHJocy54LCByaHMueSk7CisgICAgfQorICAgIFJlY3QmIG9wZXJhdG9yIC09IChjb25zdCBQb2ludCYgcmhzKSB7CisgICAgICAgIHJldHVybiBvZmZzZXRCeSgtcmhzLngsIC1yaHMueSk7CisgICAgfQorICAgIFJlY3Qgb3BlcmF0b3IgKyAoY29uc3QgUG9pbnQmIHJocykgY29uc3Q7CisgICAgUmVjdCBvcGVyYXRvciAtIChjb25zdCBQb2ludCYgcmhzKSBjb25zdDsKKworICAgIHZvaWQgdHJhbnNsYXRlKGludCBkeCwgaW50IGR5KSB7IC8vIGxlZ2FjeSwgZG9uJ3QgdXNlLgorICAgICAgICBvZmZzZXRCeShkeCwgZHkpOworICAgIH0KKyAKKyAgICBSZWN0JiAgIG9mZnNldFRvKGludCB4LCBpbnQgeSk7CisgICAgUmVjdCYgICBvZmZzZXRCeShpbnQgeCwgaW50IHkpOworICAgIGJvb2wgICAgaW50ZXJzZWN0KGNvbnN0IFJlY3QmIHdpdGgsIFJlY3QqIHJlc3VsdCkgY29uc3Q7Cit9OworCitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyhSZWN0KQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9VSV9SRUNUCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VpL1JlZ2lvbi5oIGIvaW5jbHVkZS91aS9SZWdpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Njg5NjczCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9SZWdpb24uaApAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9VSV9SRUdJT05fSAorI2RlZmluZSBBTkRST0lEX1VJX1JFR0lPTl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorCisjaW5jbHVkZSA8dWkvUmVjdC5oPgorCisjaW5jbHVkZSA8aGFyZHdhcmUvY29weWJpdC5oPgorCisjaW5jbHVkZSA8Y29yZS9Ta1JlZ2lvbi5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgU3RyaW5nODsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitjbGFzcyBSZWdpb24KK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgIFJlZ2lvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgUmVnaW9uKGNvbnN0IFJlZ2lvbiYgcmhzKTsKKyAgICBleHBsaWNpdCAgICAgICAgICAgIFJlZ2lvbihjb25zdCBTa1JlZ2lvbiYgcmhzKTsKKyAgICBleHBsaWNpdCAgICAgICAgICAgIFJlZ2lvbihjb25zdCBSZWN0JiByaHMpOworICAgIGV4cGxpY2l0ICAgICAgICAgICAgUmVnaW9uKGNvbnN0IFBhcmNlbCYgcGFyY2VsKTsKKyAgICBleHBsaWNpdCAgICAgICAgICAgIFJlZ2lvbihjb25zdCB2b2lkKiBidWZmZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgflJlZ2lvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgIFJlZ2lvbiYgb3BlcmF0b3IgPSAoY29uc3QgUmVnaW9uJiByaHMpOworCisgICAgaW5saW5lICBib29sICAgICAgICBpc0VtcHR5KCkgY29uc3QgICAgIHsgcmV0dXJuIG1SZWdpb24uaXNFbXB0eSgpOyB9CisgICAgaW5saW5lICBib29sICAgICAgICBpc1JlY3QoKSBjb25zdCAgICAgIHsgcmV0dXJuIG1SZWdpb24uaXNSZWN0KCk7IH0KKworICAgICAgICAgICAgUmVjdCAgICAgICAgYm91bmRzKCkgY29uc3Q7CisKKyAgICAgICAgICAgIGNvbnN0IFNrUmVnaW9uJiB0b1NrUmVnaW9uKCkgY29uc3Q7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGNsZWFyKCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBzZXQoY29uc3QgUmVjdCYgcik7CisgICAgICAgIAorICAgICAgICAgICAgUmVnaW9uJiAgICAgb3JTZWxmKGNvbnN0IFJlY3QmIHJocyk7CisgICAgICAgICAgICBSZWdpb24mICAgICBhbmRTZWxmKGNvbnN0IFJlY3QmIHJocyk7CisKKyAgICAgICAgICAgIC8vIGJvb2xlYW4gb3BlcmF0b3JzLCBhcHBsaWVkIG9uIHRoaXMKKyAgICAgICAgICAgIFJlZ2lvbiYgICAgIG9yU2VsZihjb25zdCBSZWdpb24mIHJocyk7CisgICAgICAgICAgICBSZWdpb24mICAgICBhbmRTZWxmKGNvbnN0IFJlZ2lvbiYgcmhzKTsKKyAgICAgICAgICAgIFJlZ2lvbiYgICAgIHN1YnRyYWN0U2VsZihjb25zdCBSZWdpb24mIHJocyk7CisKKyAgICAgICAgICAgIC8vIHRoZXNlIHRyYW5zbGF0ZSByaHMgZmlyc3QKKyAgICAgICAgICAgIFJlZ2lvbiYgICAgIHRyYW5zbGF0ZVNlbGYoaW50IGR4LCBpbnQgZHkpOworICAgICAgICAgICAgUmVnaW9uJiAgICAgb3JTZWxmKGNvbnN0IFJlZ2lvbiYgcmhzLCBpbnQgZHgsIGludCBkeSk7CisgICAgICAgICAgICBSZWdpb24mICAgICBhbmRTZWxmKGNvbnN0IFJlZ2lvbiYgcmhzLCBpbnQgZHgsIGludCBkeSk7CisgICAgICAgICAgICBSZWdpb24mICAgICBzdWJ0cmFjdFNlbGYoY29uc3QgUmVnaW9uJiByaHMsIGludCBkeCwgaW50IGR5KTsKKworICAgICAgICAgICAgLy8gYm9vbGVhbiBvcGVyYXRvcnMKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgIG1lcmdlKGNvbnN0IFJlZ2lvbiYgcmhzKSBjb25zdDsKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgIGludGVyc2VjdChjb25zdCBSZWdpb24mIHJocykgY29uc3Q7CisgICAgICAgICAgICBSZWdpb24gICAgICBzdWJ0cmFjdChjb25zdCBSZWdpb24mIHJocykgY29uc3Q7CisKKyAgICAgICAgICAgIC8vIHRoZXNlIHRyYW5zbGF0ZSByaHMgZmlyc3QKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgIHRyYW5zbGF0ZShpbnQgZHgsIGludCBkeSkgY29uc3Q7CisgICAgICAgICAgICBSZWdpb24gICAgICBtZXJnZShjb25zdCBSZWdpb24mIHJocywgaW50IGR4LCBpbnQgZHkpIGNvbnN0OworICAgICAgICAgICAgUmVnaW9uICAgICAgaW50ZXJzZWN0KGNvbnN0IFJlZ2lvbiYgcmhzLCBpbnQgZHgsIGludCBkeSkgY29uc3Q7CisgICAgICAgICAgICBSZWdpb24gICAgICBzdWJ0cmFjdChjb25zdCBSZWdpb24mIHJocywgaW50IGR4LCBpbnQgZHkpIGNvbnN0OworCisgICAgLy8gY29udmVuaWVuY2Ugb3BlcmF0b3JzIG92ZXJsb2FkcworICAgIGlubGluZSAgUmVnaW9uICAgICAgb3BlcmF0b3IgfCAoY29uc3QgUmVnaW9uJiByaHMpIGNvbnN0OworICAgIGlubGluZSAgUmVnaW9uICAgICAgb3BlcmF0b3IgJiAoY29uc3QgUmVnaW9uJiByaHMpIGNvbnN0OworICAgIGlubGluZSAgUmVnaW9uICAgICAgb3BlcmF0b3IgLSAoY29uc3QgUmVnaW9uJiByaHMpIGNvbnN0OworICAgIGlubGluZSAgUmVnaW9uICAgICAgb3BlcmF0b3IgKyAoY29uc3QgUG9pbnQmIHB0KSBjb25zdDsKKworICAgIGlubGluZSAgUmVnaW9uJiAgICAgb3BlcmF0b3IgfD0gKGNvbnN0IFJlZ2lvbiYgcmhzKTsKKyAgICBpbmxpbmUgIFJlZ2lvbiYgICAgIG9wZXJhdG9yICY9IChjb25zdCBSZWdpb24mIHJocyk7CisgICAgaW5saW5lICBSZWdpb24mICAgICBvcGVyYXRvciAtPSAoY29uc3QgUmVnaW9uJiByaHMpOworICAgIGlubGluZSAgUmVnaW9uJiAgICAgb3BlcmF0b3IgKz0gKGNvbnN0IFBvaW50JiBwdCk7CisKKyAgICBjbGFzcyBpdGVyYXRvciB7CisgICAgICAgIFNrUmVnaW9uOjpJdGVyYXRvciAgbUl0OworICAgIHB1YmxpYzoKKyAgICAgICAgaXRlcmF0b3IoY29uc3QgUmVnaW9uJiByKTsKKyAgICAgICAgaW5saW5lIG9wZXJhdG9yIGJvb2wgKCkgY29uc3QgeyByZXR1cm4gIWRvbmUoKTsgfQorICAgICAgICBpbnQgaXRlcmF0ZShSZWN0KiByZWN0KTsKKyAgICBwcml2YXRlOgorICAgICAgICBpbmxpbmUgYm9vbCBkb25lKCkgY29uc3QgeworICAgICAgICAgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8U2tSZWdpb246Okl0ZXJhdG9yJj4obUl0KS5kb25lKCk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgICAgICAgICBzaXplX3QgICAgICByZWN0cyhWZWN0b3I8UmVjdD4mIHJlY3RMaXN0KSBjb25zdDsKKworICAgICAgICAgICAgLy8gZmxhdHRlbi91bmZsYXR0ZW4gYSByZWdpb24gdG8vZnJvbSBhIFBhcmNlbAorICAgICAgICAgICAgc3RhdHVzX3QgICAgd3JpdGUoUGFyY2VsJiBwYXJjZWwpIGNvbnN0OworICAgICAgICAgICAgc3RhdHVzX3QgICAgcmVhZChjb25zdCBQYXJjZWwmIHBhcmNlbCk7CisKKyAgICAgICAgICAgIC8vIGZsYXR0ZW4vdW5mbGF0dGVuIGEgcmVnaW9uIHRvL2Zyb20gYSByYXcgYnVmZmVyCisgICAgICAgICAgICBzc2l6ZV90ICAgICB3cml0ZSh2b2lkKiBidWZmZXIsIHNpemVfdCBzaXplKSBjb25zdDsKKyAgICBzdGF0aWMgIHNzaXplX3QgICAgIHdyaXRlRW1wdHkodm9pZCogYnVmZmVyLCBzaXplX3Qgc2l6ZSk7CisKKyAgICAgICAgICAgIHNzaXplX3QgICAgIHJlYWQoY29uc3Qgdm9pZCogYnVmZmVyKTsKKyAgICBzdGF0aWMgIGJvb2wgICAgICAgIGlzRW1wdHkodm9pZCogYnVmZmVyKTsKKworICAgIHZvaWQgICAgICAgIGR1bXAoU3RyaW5nOCYgb3V0LCBjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncz0wKSBjb25zdDsKKyAgICB2b2lkICAgICAgICBkdW1wKGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzPTApIGNvbnN0OworCitwcml2YXRlOgorICAgIFNrUmVnaW9uICAgIG1SZWdpb247Cit9OworCisKK1JlZ2lvbiBSZWdpb246Om9wZXJhdG9yIHwgKGNvbnN0IFJlZ2lvbiYgcmhzKSBjb25zdCB7CisgICAgcmV0dXJuIG1lcmdlKHJocyk7Cit9CitSZWdpb24gUmVnaW9uOjpvcGVyYXRvciAmIChjb25zdCBSZWdpb24mIHJocykgY29uc3QgeworICAgIHJldHVybiBpbnRlcnNlY3QocmhzKTsKK30KK1JlZ2lvbiBSZWdpb246Om9wZXJhdG9yIC0gKGNvbnN0IFJlZ2lvbiYgcmhzKSBjb25zdCB7CisgICAgcmV0dXJuIHN1YnRyYWN0KHJocyk7Cit9CitSZWdpb24gUmVnaW9uOjpvcGVyYXRvciArIChjb25zdCBQb2ludCYgcHQpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJhbnNsYXRlKHB0LngsIHB0LnkpOworfQorCisKK1JlZ2lvbiYgUmVnaW9uOjpvcGVyYXRvciB8PSAoY29uc3QgUmVnaW9uJiByaHMpIHsKKyAgICByZXR1cm4gb3JTZWxmKHJocyk7Cit9CitSZWdpb24mIFJlZ2lvbjo6b3BlcmF0b3IgJj0gKGNvbnN0IFJlZ2lvbiYgcmhzKSB7CisgICAgcmV0dXJuIGFuZFNlbGYocmhzKTsKK30KK1JlZ2lvbiYgUmVnaW9uOjpvcGVyYXRvciAtPSAoY29uc3QgUmVnaW9uJiByaHMpIHsKKyAgICByZXR1cm4gc3VidHJhY3RTZWxmKHJocyk7Cit9CitSZWdpb24mIFJlZ2lvbjo6b3BlcmF0b3IgKz0gKGNvbnN0IFBvaW50JiBwdCkgeworICAgIHJldHVybiB0cmFuc2xhdGVTZWxmKHB0LngsIHB0LnkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RydWN0IHJlZ2lvbl9pdGVyYXRvciA6IHB1YmxpYyBjb3B5Yml0X3JlZ2lvbl90IHsKKyAgICByZWdpb25faXRlcmF0b3IoY29uc3QgUmVnaW9uJiByZWdpb24pIDogaShyZWdpb24pIHsKKyAgICAgICAgdGhpcy0+bmV4dCA9IGl0ZXJhdGU7CisgICAgfQorcHJpdmF0ZToKKyAgICBzdGF0aWMgaW50IGl0ZXJhdGUoY29weWJpdF9yZWdpb25fdCBjb25zdCAqIHNlbGYsIGNvcHliaXRfcmVjdF90KiByZWN0KSB7CisgICAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCByZWdpb25faXRlcmF0b3IqPihzZWxmKQorICAgICAgICAtPmkuaXRlcmF0ZShyZWludGVycHJldF9jYXN0PFJlY3QqPihyZWN0KSk7CisgICAgfQorICAgIG11dGFibGUgUmVnaW9uOjppdGVyYXRvciBpOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfVUlfUkVHSU9OX0gKKwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9TdXJmYWNlLmggYi9pbmNsdWRlL3VpL1N1cmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzk1M2E5Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91aS9TdXJmYWNlLmgKQEAgLTAsMCArMSwxMzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfVUlfU1VSRkFDRV9ICisjZGVmaW5lIEFORFJPSURfVUlfU1VSRkFDRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDx1aS9JU3VyZmFjZS5oPgorI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvUmVnaW9uLmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2VGbGluZ2VyQ2xpZW50Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIFJlY3Q7CitjbGFzcyBTdXJmYWNlQ29tcG9zZXJDbGllbnQ7CisKK2NsYXNzIFN1cmZhY2UgOiBwdWJsaWMgUmVmQmFzZQoreworCitwdWJsaWM6CisgICAgc3RydWN0IFN1cmZhY2VJbmZvIHsKKyAgICAgICAgdWludDMyX3QgICAgdzsKKyAgICAgICAgdWludDMyX3QgICAgaDsKKyAgICAgICAgdWludDMyX3QgICAgYnByOworICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQ7CisgICAgICAgIHZvaWQqICAgICAgIGJpdHM7CisgICAgICAgIHZvaWQqICAgICAgIGJhc2U7CisgICAgICAgIHVpbnQzMl90ICAgIHJlc2VydmVkWzJdOworICAgIH07CisKKyAgICBib29sICAgICAgICBpc1ZhbGlkKCkgY29uc3QgeyByZXR1cm4gdGhpcyAmJiBtVG9rZW4+PTAgJiYgbUNsaWVudCE9MDsgfQorICAgIFN1cmZhY2VJRCAgIElEKCkgY29uc3QgICAgICB7IHJldHVybiBtVG9rZW47IH0KKworICAgIHN0YXR1c190ICAgIGxvY2soU3VyZmFjZUluZm8qIGluZm8sIGJvb2wgYmxvY2tpbmcgPSB0cnVlKTsKKyAgICBzdGF0dXNfdCAgICBsb2NrKFN1cmZhY2VJbmZvKiBpbmZvLCBSZWdpb24qIGRpcnR5LCBib29sIGJsb2NraW5nID0gdHJ1ZSk7CisgICAgc3RhdHVzX3QgICAgdW5sb2NrQW5kUG9zdCgpOworICAgIHN0YXR1c190ICAgIHVubG9jaygpOworCisgICAgdm9pZCogICAgICAgaGVhcEJhc2UoaW50IGkpIGNvbnN0OworICAgIHVpbnQzMl90ICAgIGdldEZsYWdzKCkgY29uc3QgeyByZXR1cm4gbUZsYWdzOyB9CisKKyAgICAvLyBzZXRTd2FwUmVjdGFuZ2xlKCkgaXMgbWFpbmx5IHVzZWQgYnkgRUdMCisgICAgdm9pZCAgICAgICAgc2V0U3dhcFJlY3RhbmdsZShjb25zdCBSZWN0JiByKTsKKyAgICBjb25zdCBSZWN0JiBzd2FwUmVjdGFuZ2xlKCkgY29uc3Q7CisgICAgc3RhdHVzX3QgICAgbmV4dEJ1ZmZlcihTdXJmYWNlSW5mbyogaW5mbyk7CisKKyAgICBzcDxTdXJmYWNlPiAgICAgICAgIGR1cCgpIGNvbnN0OworICAgIHN0YXRpYyBzcDxTdXJmYWNlPiAgcmVhZEZyb21QYXJjZWwoUGFyY2VsKiBwYXJjZWwpOworICAgIHN0YXRpYyBzdGF0dXNfdCAgICAgd3JpdGVUb1BhcmNlbChjb25zdCBzcDxTdXJmYWNlPiYgc3VyZmFjZSwgUGFyY2VsKiBwYXJjZWwpOworICAgIHN0YXRpYyBib29sICAgICAgICAgaXNTYW1lU3VyZmFjZShjb25zdCBzcDxTdXJmYWNlPiYgbGhzLCBjb25zdCBzcDxTdXJmYWNlPiYgcmhzKTsKKworICAgIHN0YXR1c190ICAgIHNldExheWVyKGludDMyX3QgbGF5ZXIpOworICAgIHN0YXR1c190ICAgIHNldFBvc2l0aW9uKGludDMyX3QgeCwgaW50MzJfdCB5KTsKKyAgICBzdGF0dXNfdCAgICBzZXRTaXplKHVpbnQzMl90IHcsIHVpbnQzMl90IGgpOworICAgIHN0YXR1c190ICAgIGhpZGUoKTsKKyAgICBzdGF0dXNfdCAgICBzaG93KGludDMyX3QgbGF5ZXIgPSAtMSk7CisgICAgc3RhdHVzX3QgICAgZnJlZXplKCk7CisgICAgc3RhdHVzX3QgICAgdW5mcmVlemUoKTsKKyAgICBzdGF0dXNfdCAgICBzZXRGbGFncyh1aW50MzJfdCBmbGFncywgdWludDMyX3QgbWFzayk7CisgICAgc3RhdHVzX3QgICAgc2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KGNvbnN0IFJlZ2lvbiYgdHJhbnNwYXJlbnQpOworICAgIHN0YXR1c190ICAgIHNldEFscGhhKGZsb2F0IGFscGhhPTEuMGYpOworICAgIHN0YXR1c190ICAgIHNldE1hdHJpeChmbG9hdCBkc2R4LCBmbG9hdCBkdGR4LCBmbG9hdCBkc2R5LCBmbG9hdCBkdGR5KTsKKyAgICBzdGF0dXNfdCAgICBzZXRGcmVlemVUaW50KHVpbnQzMl90IHRpbnQpOworCisgICAgdWludDMyX3QgICAgZ2V0SWRlbnRpdHkoKSBjb25zdCB7IHJldHVybiBtSWRlbnRpdHk7IH0KK3ByaXZhdGU6CisgICAgZnJpZW5kIGNsYXNzIFN1cmZhY2VDb21wb3NlckNsaWVudDsKKworICAgIC8vIGNhbWVyYSBhbmQgY2FtY29yZGVyIG5lZWQgYWNjZXNzIHRvIHRoZSBJU3VyZmFjZSBiaW5kZXIgaW50ZXJmYWNlIGZvciBwcmV2aWV3CisgICAgZnJpZW5kIGNsYXNzIENhbWVyYTsKKyAgICBmcmllbmQgY2xhc3MgTWVkaWFSZWNvcmRlcjsKKyAgICAvLyBtZWRpYXBsYXllciBuZWVkcyBhY2Nlc3MgdG8gSVN1cmZhY2UgZm9yIGRpc3BsYXkKKyAgICBmcmllbmQgY2xhc3MgTWVkaWFQbGF5ZXI7CisgICAgZnJpZW5kIGNsYXNzIFRlc3Q7CisgICAgY29uc3Qgc3A8SVN1cmZhY2U+JiBnZXRJU3VyZmFjZSgpIGNvbnN0IHsgcmV0dXJuIG1TdXJmYWNlOyB9CisKKyAgICAvLyBjYW4ndCBiZSBjb3BpZWQKKyAgICBTdXJmYWNlJiBvcGVyYXRvciA9IChTdXJmYWNlJiByaHMpOworICAgIFN1cmZhY2UoY29uc3QgU3VyZmFjZSYgcmhzKTsKKworICAgIFN1cmZhY2UoY29uc3Qgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiYgY2xpZW50LAorICAgICAgICAgICAgY29uc3Qgc3A8SVN1cmZhY2U+JiBzdXJmYWNlLAorICAgICAgICAgICAgY29uc3QgSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpzdXJmYWNlX2RhdGFfdCYgZGF0YSwKKyAgICAgICAgICAgIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIFBpeGVsRm9ybWF0IGZvcm1hdCwgdWludDMyX3QgZmxhZ3MsCisgICAgICAgICAgICBib29sIG93bmVyID0gdHJ1ZSk7CisKKyAgICBTdXJmYWNlKFN1cmZhY2UgY29uc3QqIHJocyk7CisKKyAgICB+U3VyZmFjZSgpOworCisgICAgUmVnaW9uIGRpcnR5UmVnaW9uKCkgY29uc3Q7CisgICAgdm9pZCBzZXREaXJ0eVJlZ2lvbihjb25zdCBSZWdpb24mIHJlZ2lvbikgY29uc3Q7CisKKyAgICAvLyB0aGlzIGxvY2tzIHByb3RlY3RzIGNhbGxzIHRvIGxvY2tTdXJmYWNlKCkgLyB1bmxvY2tTdXJmYWNlKCkKKyAgICAvLyBhbmQgaXMgY2FsbGVkIGJ5IFN1cmZhY2VDb21wb3NlckNsaWVudC4KKyAgICBNdXRleCYgZ2V0TG9jaygpIGNvbnN0IHsgcmV0dXJuIG1TdXJmYWNlTG9jazsgfQorCisgICAgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiAgIG1DbGllbnQ7CisgICAgc3A8SVN1cmZhY2U+ICAgICAgICAgICAgICAgIG1TdXJmYWNlOworICAgIHNwPElNZW1vcnlIZWFwPiAgICAgICAgICAgICBtSGVhcFsyXTsKKyAgICBTdXJmYWNlSUQgICAgICAgICAgICAgICAgICAgbVRva2VuOworICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgICAgICBtSWRlbnRpdHk7CisgICAgUGl4ZWxGb3JtYXQgICAgICAgICAgICAgICAgIG1Gb3JtYXQ7CisgICAgdWludDMyX3QgICAgICAgICAgICAgICAgICAgIG1GbGFnczsKKyAgICBjb25zdCBib29sICAgICAgICAgICAgICAgICAgbU93bmVyOworICAgIG11dGFibGUgdm9pZCogICAgICAgICAgICAgICBtU3VyZmFjZUhlYXBCYXNlWzJdOworICAgIG11dGFibGUgUmVnaW9uICAgICAgICAgICAgICBtRGlydHlSZWdpb247CisgICAgbXV0YWJsZSBSZWN0ICAgICAgICAgICAgICAgIG1Td2FwUmVjdGFuZ2xlOworICAgIG11dGFibGUgdWludDhfdCAgICAgICAgICAgICBtQmFja2J1ZmZlckluZGV4OworICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICBtU3VyZmFjZUxvY2s7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9VSV9TVVJGQUNFX0gKKwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91aS9TdXJmYWNlQ29tcG9zZXJDbGllbnQuaCBiL2luY2x1ZGUvdWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQ5MjIyZAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50LmgKQEAgLTAsMCArMSwxNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfU1VSRkFDRV9DT01QT1NFUl9DTElFTlRfSAorI2RlZmluZSBBTkRST0lEX1NVUkZBQ0VfQ09NUE9TRVJfQ0xJRU5UX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvU29ydGVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUNvbXBvc2VyLmg+CisjaW5jbHVkZSA8dWkvUmVnaW9uLmg+CisjaW5jbHVkZSA8dWkvU3VyZmFjZS5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBSZWdpb247CitjbGFzcyBTdXJmYWNlRmxpbmdlclN5bmNocm87CitzdHJ1Y3QgcGVyX2NsaWVudF9jYmxrX3Q7CitzdHJ1Y3QgbGF5ZXJfY2Jsa190OworCitjbGFzcyBTdXJmYWNlQ29tcG9zZXJDbGllbnQgOiB2aXJ0dWFsIHB1YmxpYyBSZWZCYXNlCit7CitwdWJsaWM6ICAgIAorICAgICAgICAgICAgICAgIFN1cmZhY2VDb21wb3NlckNsaWVudCgpOworICAgIHZpcnR1YWwgICAgIH5TdXJmYWNlQ29tcG9zZXJDbGllbnQoKTsKKworICAgIC8vIEFsd2F5cyBtYWtlIHN1cmUgd2UgY291bGQgaW5pdGlhbGl6ZQorICAgIHN0YXR1c190ICAgIGluaXRDaGVjaygpIGNvbnN0OworCisgICAgLy8gUmV0dXJuIHRoZSBjb25uZWN0aW9uIG9mIHRoaXMgY2xpZW50CisgICAgc3A8SUJpbmRlcj4gY29ubmVjdGlvbigpIGNvbnN0OworICAgIAorICAgIC8vIFJldHJpZXZlIGEgY2xpZW50IGZvciBhbiBleGlzdGluZyBjb25uZWN0aW9uLgorICAgIHN0YXRpYyBzcDxTdXJmYWNlQ29tcG9zZXJDbGllbnQ+CisgICAgICAgICAgICAgICAgY2xpZW50Rm9yQ29ubmVjdGlvbihjb25zdCBzcDxJQmluZGVyPiYgY29ubik7CisKKyAgICAvLyBGb3JjaWJseSByZW1vdmUgY29ubmVjdGlvbiBiZWZvcmUgYWxsIHJlZmVyZW5jZXMgaGF2ZSBnb25lIGF3YXkuCisgICAgdm9pZCAgICAgICAgZGlzcG9zZSgpOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gc3VyZmFjZSBjcmVhdGlvbiAvIGRlc3RydWN0aW9uCisKKyAgICAvLyEgQ3JlYXRlIGEgc3VyZmFjZQorICAgIHNwPFN1cmZhY2U+ICAgY3JlYXRlU3VyZmFjZSgKKyAgICAgICAgICAgIGludCBwaWQsICAgICAgICAgICAgLy8hPCBwaWQgb2YgdGhlIHByb2Nlc3MgdGhlIHN1cmZhY2VjIGlzIGZvcgorICAgICAgICAgICAgRGlzcGxheUlEIGRpc3BsYXksICAvLyE8IERpc3BsYXkgdG8gY3JlYXRlIHRoaXMgc3VyZmFjZSBvbgorICAgICAgICAgICAgdWludDMyX3QgdywgICAgICAgICAvLyE8IHdpZHRoIGluIHBpeGVsCisgICAgICAgICAgICB1aW50MzJfdCBoLCAgICAgICAgIC8vITwgaGVpZ2h0IGluIHBpeGVsCisgICAgICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQsIC8vITwgcGl4ZWwtZm9ybWF0IGRlc2lyZWQKKyAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCAgLy8hPCB1c2FnZSBmbGFncworICAgICk7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyBDb21wb3NlciBwYXJhbWV0ZXJzCisgICAgLy8gQWxsIGNvbXBvc2VyIHBhcmFtZXRlcnMgbXVzdCBiZSBjaGFuZ2VkIHdpdGhpbiBhIHRyYW5zYWN0aW9uCisgICAgLy8gc2V2ZXJhbCBzdXJmYWNlcyBjYW4gYmUgdXBkYXRlZCBpbiBvbmUgdHJhbnNhY3Rpb24sIGFsbCBjaGFuZ2VzIGFyZQorICAgIC8vIGNvbW1pdHRlZCBhdCBvbmNlIHdoZW4gdGhlIHRyYW5zYWN0aW9uIGlzIGNsb3NlZC4KKyAgICAvLyBDbG9zZVRyYW5zYWN0aW9uKCkgdXN1YWxseSByZXF1aXJlcyBhbiBJUEMgd2l0aCB0aGUgc2VydmVyLgorICAgIAorICAgIC8vISBPcGVuIGEgY29tcG9zZXIgdHJhbnNhY3Rpb24KKyAgICBzdGF0dXNfdCAgICBvcGVuVHJhbnNhY3Rpb24oKTsKKworICAgIC8vISBjb21taXQgdGhlIHRyYW5zYWN0aW9uCisgICAgc3RhdHVzX3QgICAgY2xvc2VUcmFuc2FjdGlvbigpOworCisgICAgLy8hIE9wZW4gYSBjb21wb3NlciB0cmFuc2FjdGlvbiBvbiBhbGwgYWN0aXZlIFN1cmZhY2VDb21wb3NlckNsaWVudHMuCisgICAgc3RhdGljIHZvaWQgb3Blbkdsb2JhbFRyYW5zYWN0aW9uKCk7CisgICAgICAgIAorICAgIC8vISBDbG9zZSBhIGNvbXBvc2VyIHRyYW5zYWN0aW9uIG9uIGFsbCBhY3RpdmUgU3VyZmFjZUNvbXBvc2VyQ2xpZW50cy4KKyAgICBzdGF0aWMgdm9pZCBjbG9zZUdsb2JhbFRyYW5zYWN0aW9uKCk7CisgICAgCisgICAgLy8hIEZyZWV6ZSB0aGUgc3BlY2lmaWVkIGRpc3BsYXkgYnV0IG5vdCB0cmFuc2FjdGlvbnMuCisgICAgc3RhdGljIHN0YXR1c190IGZyZWV6ZURpc3BsYXkoRGlzcGxheUlEIGRweSwgdWludDMyX3QgZmxhZ3MgPSAwKTsKKyAgICAgICAgCisgICAgLy8hIFJlc3VtZSB1cGRhdGVzIG9uIHRoZSBzcGVjaWZpZWQgZGlzcGxheS4KKyAgICBzdGF0aWMgc3RhdHVzX3QgdW5mcmVlemVEaXNwbGF5KERpc3BsYXlJRCBkcHksIHVpbnQzMl90IGZsYWdzID0gMCk7CisKKyAgICAvLyEgU2V0IHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gZGlzcGxheQorICAgIHN0YXRpYyBpbnQgc2V0T3JpZW50YXRpb24oRGlzcGxheUlEIGRweSwgaW50IG9yaWVudGF0aW9uKTsKKworICAgIC8vIFF1ZXJ5IHRoZSBudW1iZXIgb2YgZGlzcGxheXMKKyAgICBzdGF0aWMgc3NpemVfdCBnZXROdW1iZXJPZkRpc3BsYXlzKCk7CisKKyAgICAvLyBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBkaXNwbGF5CisgICAgc3RhdGljIHN0YXR1c190IGdldERpc3BsYXlJbmZvKERpc3BsYXlJRCBkcHksIERpc3BsYXlJbmZvKiBpbmZvKTsKKyAgICBzdGF0aWMgc3NpemVfdCBnZXREaXNwbGF5V2lkdGgoRGlzcGxheUlEIGRweSk7CisgICAgc3RhdGljIHNzaXplX3QgZ2V0RGlzcGxheUhlaWdodChEaXNwbGF5SUQgZHB5KTsKKyAgICBzdGF0aWMgc3NpemVfdCBnZXREaXNwbGF5T3JpZW50YXRpb24oRGlzcGxheUlEIGRweSk7CisKKworcHJpdmF0ZToKKyAgICBmcmllbmQgY2xhc3MgU3VyZmFjZTsKKyAgICAKKyAgICBTdXJmYWNlQ29tcG9zZXJDbGllbnQoY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIHNtLCAKKyAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBjb25uKTsKKworICAgIHN0YXR1c190ICAgIGhpZGUoU3VyZmFjZSogc3VyZmFjZSk7CisgICAgc3RhdHVzX3QgICAgc2hvdyhTdXJmYWNlKiBzdXJmYWNlLCBpbnQzMl90IGxheWVyID0gLTEpOworICAgIHN0YXR1c190ICAgIGZyZWV6ZShTdXJmYWNlKiBzdXJmYWNlKTsKKyAgICBzdGF0dXNfdCAgICB1bmZyZWV6ZShTdXJmYWNlKiBzdXJmYWNlKTsKKyAgICBzdGF0dXNfdCAgICBzZXRGbGFncyhTdXJmYWNlKiBzdXJmYWNlLCB1aW50MzJfdCBmbGFncywgdWludDMyX3QgbWFzayk7CisgICAgc3RhdHVzX3QgICAgc2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KFN1cmZhY2UqIHN1cmZhY2UsIGNvbnN0IFJlZ2lvbiYgdHJhbnNwYXJlbnQpOworICAgIHN0YXR1c190ICAgIHNldExheWVyKFN1cmZhY2UqIHN1cmZhY2UsIGludDMyX3QgbGF5ZXIpOworICAgIHN0YXR1c190ICAgIHNldEFscGhhKFN1cmZhY2UqIHN1cmZhY2UsIGZsb2F0IGFscGhhPTEuMGYpOworICAgIHN0YXR1c190ICAgIHNldEZyZWV6ZVRpbnQoU3VyZmFjZSogc3VyZmFjZSwgdWludDMyX3QgdGludCk7CisgICAgc3RhdHVzX3QgICAgc2V0TWF0cml4KFN1cmZhY2UqIHN1cmZhY2UsIGZsb2F0IGRzZHgsIGZsb2F0IGR0ZHgsIGZsb2F0IGRzZHksIGZsb2F0IGR0ZHkpOworICAgIHN0YXR1c190ICAgIHNldFBvc2l0aW9uKFN1cmZhY2UqIHN1cmZhY2UsIGludDMyX3QgeCwgaW50MzJfdCB5KTsKKyAgICBzdGF0dXNfdCAgICBzZXRTaXplKFN1cmZhY2UqIHN1cmZhY2UsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgpOworICAgIAorICAgIC8vISBVbmxvY2sgdGhlIHN1cmZhY2UsIGFuZCBzcGVjaWZ5IHRoZSBkaXJ0eSByZWdpb24gaWYgYW55CisgICAgc3RhdHVzX3QgICAgdW5sb2NrQW5kUG9zdFN1cmZhY2UoU3VyZmFjZSogc3VyZmFjZSk7CisgICAgc3RhdHVzX3QgICAgdW5sb2NrU3VyZmFjZShTdXJmYWNlKiBzdXJmYWNlKTsKKworICAgIHN0YXR1c190ICAgIGxvY2tTdXJmYWNlKFN1cmZhY2UqIHN1cmZhY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3VyZmFjZTo6U3VyZmFjZUluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnaW9uKiBkaXJ0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJsb2NraW5nID0gdHJ1ZSk7CisKKyAgICBzdGF0dXNfdCAgICBuZXh0QnVmZmVyKFN1cmZhY2UqIHN1cmZhY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3VyZmFjZTo6U3VyZmFjZUluZm8qIGluZm8pOworCisgICAgc3RhdHVzX3QgICAgZGVzdHJveVN1cmZhY2UoU3VyZmFjZUlEIHNpZCk7CisKKyAgICB2b2lkICAgICAgICBfaW5pdChjb25zdCBzcDxJU3VyZmFjZUNvbXBvc2VyPiYgc20sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElTdXJmYWNlRmxpbmdlckNsaWVudD4mIGNvbm4pOworICAgIHZvaWQgICAgICAgIF9zaWduYWxfc2VydmVyKCk7CisgICAgc3RhdGljIHZvaWQgX3NlbmRfZGlydHlfcmVnaW9uKGxheWVyX2NibGtfdCogbGNibGssIGNvbnN0IFJlZ2lvbiYgZGlydHkpOworCisgICAgaW5saW5lIGxheWVyX3N0YXRlX3QqICAgX2dldF9zdGF0ZV9sKGNvbnN0IHNwPFN1cmZhY2U+JiBzdXJmYWNlKTsKKyAgICBsYXllcl9zdGF0ZV90KiAgICAgICAgICBfbG9ja0xheWVyU3RhdGUoY29uc3Qgc3A8U3VyZmFjZT4mIHN1cmZhY2UpOworICAgIGlubGluZSB2b2lkICAgICAgICAgICAgIF91bmxvY2tMYXllclN0YXRlKCk7CisKKyAgICBzdGF0dXNfdCB2YWxpZGF0ZVN1cmZhY2UoCisgICAgICAgICAgICBwZXJfY2xpZW50X2NibGtfdCBjb25zdCogY2JsaywgU3VyZmFjZSBjb25zdCAqIHN1cmZhY2UpOworCisgICAgdm9pZCBwaW5IZWFwKGNvbnN0IHNwPElNZW1vcnlIZWFwPiYgaGVhcCk7CisKKyAgICBtdXRhYmxlICAgICBNdXRleCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtTG9jazsKKyAgICAgICAgICAgICAgICBsYXllcl9zdGF0ZV90KiAgICAgICAgICAgICAgICAgICAgICBtUHJlYnVpbHRMYXllclN0YXRlOworICAgICAgICAgICAgICAgIFNvcnRlZFZlY3RvcjxsYXllcl9zdGF0ZV90PiAgICAgICAgIG1TdGF0ZXM7CisgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbVRyYW5zYWN0aW9uT3BlbjsKKworICAgICAgICAgICAgICAgIC8vIHRoZXNlIGRvbid0IG5lZWQgdG8gYmUgcHJvdGVjdGVkIGJlY2F1c2UgdGhleSBuZXZlciBjaGFuZ2UKKyAgICAgICAgICAgICAgICAvLyBhZnRlciBhc3NpZ25tZW50CisgICAgICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICAgICAgICAgIG1TdGF0dXM7CisgICAgICAgICAgICAgICAgcGVyX2NsaWVudF9jYmxrX3QqICAgICAgICAgIG1Db250cm9sOworICAgICAgICAgICAgICAgIHNwPElNZW1vcnk+ICAgICAgICAgICAgICAgICBtQ29udHJvbE1lbW9yeTsKKyAgICAgICAgICAgICAgICBzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+ICAgbUNsaWVudDsKKyAgICAgICAgICAgICAgICBzcDxJTWVtb3J5SGVhcD4gICAgICAgICAgICAgbVN1cmZhY2VIZWFwOworICAgICAgICAgICAgICAgIHVpbnQ4X3QqICAgICAgICAgICAgICAgICAgICBtU3VyZmFjZUhlYXBCYXNlOworICAgICAgICAgICAgICAgIHZvaWQqICAgICAgICAgICAgICAgICAgICAgICBtR0w7CisgICAgICAgICAgICAgICAgU3VyZmFjZUZsaW5nZXJTeW5jaHJvKiAgICAgIG1TaWduYWxTZXJ2ZXI7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9TVVJGQUNFX0NPTVBPU0VSX0NMSUVOVF9ICisKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMuaCBiL2luY2x1ZGUvdXRpbHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMDY0OGIxCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy5oCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gSGFuZHkgdXRpbGl0eSBmdW5jdGlvbnMgYW5kIHBvcnRhYmlsaXR5IGNvZGUuICBUaGlzIGZpbGUgaW5jbHVkZXMgYWxsCisvLyBvZiB0aGUgZ2VuZXJhbGx5LXVzZWZ1bCBoZWFkZXJzIGluIHRoZSAidXRpbHMiIGRpcmVjdG9yeS4KKy8vCisjaWZuZGVmIF9MSUJTX1VUSUxTX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfSAorCisjaW5jbHVkZSA8dXRpbHMvcG9ydGVkLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL1RpbWVycy5oPgorI2luY2x1ZGUgPHV0aWxzL0xpc3QuaD4KKyNpbmNsdWRlIDx1dGlscy9zdHJpbmdfYXJyYXkuaD4KKyNpbmNsdWRlIDx1dGlscy9taXNjLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisKKyNlbmRpZiAvLyBfTElCU19VVElMU19ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0FuZHJvaWRVbmljb2RlLmggYi9pbmNsdWRlL3V0aWxzL0FuZHJvaWRVbmljb2RlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTYzZmNkMAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvQW5kcm9pZFVuaWNvZGUuaApAQCAtMCwwICsxLDI1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisKKyNpZm5kZWYgQU5EUk9JRF9VTklDT0RFX0gKKyNkZWZpbmUgQU5EUk9JRF9VTklDT0RFX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjZGVmaW5lIFJFUExBQ0VNRU5UX0NIQVIgKDB4RkZGRCkKKworLy8gdGhpcyBwYXJ0IG9mIGNvZGUgaXMgY29waWVkIGZyb20gdW1hY2hpbmUuaCB1bmRlciBJQ1UKKy8qKgorICogRGVmaW5lIFVDaGFyMzIgYXMgYSB0eXBlIGZvciBzaW5nbGUgVW5pY29kZSBjb2RlIHBvaW50cy4KKyAqIFVDaGFyMzIgaXMgYSBzaWduZWQgMzItYml0IGludGVnZXIgKHNhbWUgYXMgaW50MzJfdCkuCisgKgorICogVGhlIFVuaWNvZGUgY29kZSBwb2ludCByYW5nZSBpcyAwLi4weDEwZmZmZi4KKyAqIEFsbCBvdGhlciB2YWx1ZXMgKG5lZ2F0aXZlIG9yID49MHgxMTAwMDApIGFyZSBpbGxlZ2FsIGFzIFVuaWNvZGUgY29kZSBwb2ludHMuCisgKiBUaGV5IG1heSBiZSB1c2VkIGFzIHNlbnRpbmVsIHZhbHVlcyB0byBpbmRpY2F0ZSAiZG9uZSIsICJlcnJvciIKKyAqIG9yIHNpbWlsYXIgbm9uLWNvZGUgcG9pbnQgY29uZGl0aW9ucy4KKyAqCisgKiBAc3RhYmxlIElDVSAyLjQKKyAqLwordHlwZWRlZiBpbnQzMl90IFVDaGFyMzI7CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworICAgIGNsYXNzIEVuY29kaW5nOworICAgIC8qKgorICAgICAqIFxjbGFzcyBVbmljb2RlCisgICAgICoKKyAgICAgKiBIZWxwZXIgY2xhc3MgZm9yIGdldHRpbmcgcHJvcGVydGllcyBvZiBVbmljb2RlIGNoYXJhY3RlcnMuIENoYXJhY3RlcnMKKyAgICAgKiBjYW4gaGF2ZSBvbmUgb2YgdGhlIHR5cGVzIGxpc3RlZCBpbiBDaGFyVHlwZSBhbmQgZWFjaCBjaGFyYWN0ZXIgY2FuIGhhdmUgdGhlCisgICAgICogZGlyZWN0aW9uYWxpdHkgb2YgRGlyZWN0aW9uLgorICAgICAqLworICAgIGNsYXNzIFVuaWNvZGUKKyAgICB7CisgICAgcHVibGljOgorICAgICAgICAvKioKKyAgICAgICAgICogRGlyZWN0aW9ucyBzcGVjaWZpZWQgaW4gdGhlIFVuaWNvZGUgc3RhbmRhcmQuIFRoZXNlIGRpcmVjdGlvbnMgbWFwIGRpcmVjdGx5CisgICAgICAgICAqIHRvIGphdmEubGFuZy5DaGFyYWN0ZXIuCisgICAgICAgICAqLworICAgICAgICBlbnVtIERpcmVjdGlvbiB7CisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9VTkRFRklORUQgPSAtMSwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX0xFRlRfVE9fUklHSFQsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9SSUdIVF9UT19MRUZULAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVF9BUkFCSUMsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9FVVJPUEVBTl9OVU1CRVIsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9FVVJPUEVBTl9OVU1CRVJfU0VQQVJBVE9SLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfRVVST1BFQU5fTlVNQkVSX1RFUk1JTkFUT1IsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9BUkFCSUNfTlVNQkVSLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfQ09NTU9OX05VTUJFUl9TRVBBUkFUT1IsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9OT05TUEFDSU5HX01BUkssCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9CT1VOREFSWV9ORVVUUkFMLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfUEFSQUdSQVBIX1NFUEFSQVRPUiwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX1NFR01FTlRfU0VQQVJBVE9SLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfV0hJVEVTUEFDRSwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX09USEVSX05FVVRSQUxTLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVF9FTUJFRERJTkcsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9MRUZUX1RPX1JJR0hUX09WRVJSSURFLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVF9FTUJFRERJTkcsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9SSUdIVF9UT19MRUZUX09WRVJSSURFLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfUE9QX0RJUkVDVElPTkFMX0ZPUk1BVAorICAgICAgICB9OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDaGFyYWN0ZXIgdHlwZXMgYXMgc3BlY2lmaWVkIGluIHRoZSBVbmljb2RlIHN0YW5kYXJkLiBUaGVzZSBtYXAgZGlyZWN0bHkgdG8KKyAgICAgICAgICogamF2YS5sYW5nLkNoYXJhY3Rlci4KKyAgICAgICAgICovCisgICAgICAgIGVudW0gQ2hhclR5cGUgeworICAgICAgICAgICAgQ0hBUlRZUEVfVU5BU1NJR05FRCA9IDAsCisgICAgICAgICAgICBDSEFSVFlQRV9VUFBFUkNBU0VfTEVUVEVSLAorICAgICAgICAgICAgQ0hBUlRZUEVfTE9XRVJDQVNFX0xFVFRFUiwKKyAgICAgICAgICAgIENIQVJUWVBFX1RJVExFQ0FTRV9MRVRURVIsCisgICAgICAgICAgICBDSEFSVFlQRV9NT0RJRklFUl9MRVRURVIsCisgICAgICAgICAgICBDSEFSVFlQRV9PVEhFUl9MRVRURVIsCisgICAgICAgICAgICBDSEFSVFlQRV9OT05fU1BBQ0lOR19NQVJLLAorICAgICAgICAgICAgQ0hBUlRZUEVfRU5DTE9TSU5HX01BUkssCisgICAgICAgICAgICBDSEFSVFlQRV9DT01CSU5JTkdfU1BBQ0lOR19NQVJLLAorICAgICAgICAgICAgQ0hBUlRZUEVfREVDSU1BTF9ESUdJVF9OVU1CRVIsCisgICAgICAgICAgICBDSEFSVFlQRV9MRVRURVJfTlVNQkVSLAorICAgICAgICAgICAgQ0hBUlRZUEVfT1RIRVJfTlVNQkVSLAorICAgICAgICAgICAgQ0hBUlRZUEVfU1BBQ0VfU0VQQVJBVE9SLAorICAgICAgICAgICAgQ0hBUlRZUEVfTElORV9TRVBBUkFUT1IsCisgICAgICAgICAgICBDSEFSVFlQRV9QQVJBR1JBUEhfU0VQQVJBVE9SLAorICAgICAgICAgICAgQ0hBUlRZUEVfQ09OVFJPTCwKKyAgICAgICAgICAgIENIQVJUWVBFX0ZPUk1BVCwKKyAgICAgICAgICAgIENIQVJUWVBFX01JU1NJTkdfVkFMVUVfRk9SX0pBVkEsICAgIC8qIFRoaXMgaXMgdGhlIG15c3RlcmlvdXMgbWlzc2luZyAxNyB2YWx1ZSBmcm9tIHRoZSBqYXZhIGNvbnN0YW50cyAqLworICAgICAgICAgICAgQ0hBUlRZUEVfUFJJVkFURV9VU0UsCisgICAgICAgICAgICBDSEFSVFlQRV9TVVJST0dBVEUsCisgICAgICAgICAgICBDSEFSVFlQRV9EQVNIX1BVTkNUVUFUSU9OLAorICAgICAgICAgICAgQ0hBUlRZUEVfU1RBUlRfUFVOQ1RVQVRJT04sCisgICAgICAgICAgICBDSEFSVFlQRV9FTkRfUFVOQ1RVQVRJT04sCisgICAgICAgICAgICBDSEFSVFlQRV9DT05ORUNUT1JfUFVOQ1RVQVRJT04sCisgICAgICAgICAgICBDSEFSVFlQRV9PVEhFUl9QVU5DVFVBVElPTiwKKyAgICAgICAgICAgIENIQVJUWVBFX01BVEhfU1lNQk9MLAorICAgICAgICAgICAgQ0hBUlRZUEVfQ1VSUkVOQ1lfU1lNQk9MLAorICAgICAgICAgICAgQ0hBUlRZUEVfTU9ESUZJRVJfU1lNQk9MLAorICAgICAgICAgICAgQ0hBUlRZUEVfT1RIRVJfU1lNQk9MLAorICAgICAgICAgICAgQ0hBUlRZUEVfSU5JVElBTF9RVU9URV9QVU5DVFVBVElPTiwKKyAgICAgICAgICAgIENIQVJUWVBFX0ZJTkFMX1FVT1RFX1BVTkNUVUFUSU9OCisgICAgICAgIH07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIERlY29tcG9zaXRpb24gdHlwZXMgYXMgZGVzY3JpYmVkIGJ5IHRoZSB1bmljb2RlIHN0YW5kYXJkLiBUaGVzZSB2YWx1ZXMgbWFwIHRvCisgICAgICAgICAqIHRoZSBzYW1lIHZhbHVlcyBpbiB1Y2hhci5oIGluIElDVS4KKyAgICAgICAgICovCisgICAgICAgIGVudW0gRGVjb21wb3NpdGlvblR5cGUgeworICAgICAgICAgICAgREVDT01QT1NJVElPTl9OT05FID0gMCwKKyAgICAgICAgICAgIERFQ09NUE9TSVRJT05fQ0FOT05JQ0FMLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9DT01QQVQsCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX0NJUkNMRSwKKyAgICAgICAgICAgIERFQ09NUE9TSVRJT05fRklOQUwsCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX0ZPTlQsCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX0ZSQUNUSU9OLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9JTklUSUFMLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9JU09MQVRFRCwKKyAgICAgICAgICAgIERFQ09NUE9TSVRJT05fTUVESUFMLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9OQVJST1csCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX05PQlJFQUssCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX1NNQUxMLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9TUVVBUkUsCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX1NVQiwKKyAgICAgICAgICAgIERFQ09NUE9TSVRJT05fU1VQRVIsCisgICAgICAgICAgICBERUNPTVBPU0lUSU9OX1ZFUlRJQ0FMLAorICAgICAgICAgICAgREVDT01QT1NJVElPTl9XSURFCisgICAgICAgIH07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHBhY2tlZCBkYXRhIGZvciBqYXZhIGNhbGxzCisgICAgICAgICAqIEBwYXJhbSBjIFRoZSB1bmljb2RlIGNoYXJhY3Rlci4KKyAgICAgICAgICogQHJldHVybiBUaGUgcGFja2VkIGRhdGEgZm9yIHRoZSBjaGFyYWN0ZXIuCisgICAgICAgICAqCisgICAgICAgICAqIENvcGllZCBmcm9tIGphdmEubGFuZy5DaGFyYWN0ZXIgaW1wbGVtZW50YXRpb246CisgICAgICAgICAqIDEgMSAxIDEgMSAxIDEgMSAxIDEgMSAxIDEgMSAxIDEKKyAgICAgICAgICogRiBFIEQgQyBCIEEgOSA4IDcgNiA1IDQgMyAyIDEgMCBGIEUgRCBDIEIgQSA5IDggNyA2IDUgNCAzIDIgMSAwCisgICAgICAgICAqIAorICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMxIHR5cGVzICAgICAgICAgICAgICAgICAtLS0tLS0tLS0KKyAgICAgICAgICogICAgICAgICAgICAgICAgICAgMTggZGlyZWN0aW9uYWxpdGllcyAgICAgICAtLS0tLS0tLS0KKyAgICAgICAgICogICAgICAgICAgICAgICAgICAgMiBtaXJyb3JlZHMgICAgICAgICAgICAgLQorICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLS0tLS0tLS0tLSAgICAgIDU2ICB0b3VwcGVyIGRpZmZzCisgICAgICAgICAqICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tICAgICAgICAgICAgICAgICAgNDggIHRvbG93ZXIgZGlmZnMKKyAgICAgICAgICogICAgICAgICAgICAgICAtLS0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0IHRvdGl0bGVjYXNlIGRpZmZzCisgICAgICAgICAqIC0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4NCBudW1lcmljIHZhbHVlcworICAgICAgICAgKiAgICAgLS0tLS0tLS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjQgbWlycm9yIGNoYXIgZGlmZnMKKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyB1aW50MzJfdCBnZXRQYWNrZWREYXRhKFVDaGFyMzIgYyk7CisgICAgICAgIAorICAgICAgICAvKioKKyAgICAgICAgICogR2V0IHRoZSBDaGFyYWN0ZXIgdHlwZS4KKyAgICAgICAgICogQHBhcmFtIGMgVGhlIHVuaWNvZGUgY2hhcmFjdGVyLgorICAgICAgICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIncyB0eXBlIG9yIENIQVJUWVBFX1VOQVNTSUdORUQgaWYgdGhlIGNoYXJhY3RlciBpcyBpbnZhbGlkCisgICAgICAgICAqICAgICAgICAgb3IgaGFzIGFuIHVuYXNzaWduZWQgY2xhc3MuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgQ2hhclR5cGUgZ2V0VHlwZShVQ2hhcjMyIGMpOyAgICAKKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0IHRoZSBDaGFyYWN0ZXIncyBkZWNvbXBvc2l0aW9uIHR5cGUuCisgICAgICAgICAqIEBwYXJhbSBjIFRoZSB1bmljb2RlIGNoYXJhY3Rlci4KKyAgICAgICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyJ3MgZGVjb21wb3NpdGlvbiB0eXBlIG9yIERFQ09NUE9TSVRJT05fTk9ORSBpcyB0aGVyZSAKKyAgICAgICAgICogICAgICAgICBpcyBubyBkZWNvbXBvc2l0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIERlY29tcG9zaXRpb25UeXBlIGdldERlY29tcG9zaXRpb25UeXBlKFVDaGFyMzIgYyk7CisgICAgICAgIAorICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgZGlnaXQgdmFsdWUgb2YgYSBjaGFyYWN0ZXIgb3IgLTEgaWYgdGhlIGNoYXJhY3RlcgorICAgICAgICAgKiBpcyBub3Qgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFkaXguCisgICAgICAgICAqCisgICAgICAgICAqIFRoZSBkaWdpdCB2YWx1ZSBpcyBjb21wdXRlZCBmb3IgaW50ZWdlciBjaGFyYWN0ZXJzIGFuZCBsZXR0ZXJzCisgICAgICAgICAqIHdpdGhpbiB0aGUgZ2l2ZW4gcmFkaXguIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgaGFuZGxlIFJvbWFuIE51bWVyYWxzLAorICAgICAgICAgKiBmcmFjdGlvbnMsIG9yIGFueSBvdGhlciBjaGFyYWN0ZXJzIHRoYXQgbWF5IHJlcHJlc2VudCBudW1iZXJzLgorICAgICAgICAgKiAKKyAgICAgICAgICogQHBhcmFtIGMgVGhlIHVuaWNvZGUgY2hhcmFjdGVyCisgICAgICAgICAqIEBwYXJhbSByYWRpeCBUaGUgaW50ZW5kZWQgcmFkaXguCisgICAgICAgICAqIEByZXR1cm4gVGhlIGRpZ2l0IHZhbHVlIG9yIC0xIGlmIHRoZXJlIGlzIG5vIGRpZ2l0IHZhbHVlIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdXRzaWRlIHRoZSByYWRpeC4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBpbnQgZ2V0RGlnaXRWYWx1ZShVQ2hhcjMyIGMsIGludCByYWRpeCA9IDEwKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJuIHRoZSBudW1lcmljIHZhbHVlIG9mIGEgY2hhcmFjdGVyCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBjIFRoZSB1bmljb2RlIGNoYXJhY3Rlci4KKyAgICAgICAgICogQHJldHVybiBUaGUgbnVtZXJpYyB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyLiAtMSBpZiB0aGUgY2hhcmFjdGVyIGhhcyBubyBudW1lcmljIHZhbHVlLCAKKyAgICAgICAgICogICAgICAgICAtMiBpZiB0aGUgY2hhcmFjdGVyIGhhcyBhIG51bWVyaWMgdmFsdWUgdGhhdCBpcyBub3QgcmVwcmVzZW50YWJsZSBieSBhbiBpbnRlZ2VyLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGludCBnZXROdW1lcmljVmFsdWUoVUNoYXIzMiBjKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29udmVydCB0aGUgY2hhcmFjdGVyIHRvIGxvd2VyY2FzZQorICAgICAgICAgKiBAcGFyYW0gYyBUaGUgdW5pY29kZSBjaGFyYWN0ZXIuCisgICAgICAgICAqIEByZXR1cm4gVGhlIGxvd2VyY2FzZSBjaGFyYWN0ZXIgZXF1aXZhbGVudCBvZiBjLiBJZiBjIGRvZXMgbm90IGhhdmUgYSBsb3dlcmNhc2UgZXF1aXZhbGVudCwKKyAgICAgICAgICogICAgICAgICB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyIGlzIHJldHVybmVkLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIFVDaGFyMzIgdG9Mb3dlcihVQ2hhcjMyIGMpOworICAgICAgICAgICAgCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb252ZXJ0IHRoZSBjaGFyYWN0ZXIgdG8gdXBwZXJjYXNlCisgICAgICAgICAqIEBwYXJhbSBjIFRoZSB1bmljb2RlIGNoYXJhY3Rlci4KKyAgICAgICAgICogQHJldHVybiBUaGUgdXBwZXJjYXNlIGNoYXJhY3RlciBlcXVpdmFsZW50IG9mIGMuIElmIGMgZG9lcyBub3QgaGF2ZSBhbiB1cHBlcmNhc2UgZXF1aXZhbGVudCwKKyAgICAgICAgICogICAgICAgICB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyIGlzIHJldHVybmVkLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIFVDaGFyMzIgdG9VcHBlcihVQ2hhcjMyIGMpOworICAgIAorICAgICAgICAvKioKKyAgICAgICAgICogR2V0IHRoZSBkaXJlY3Rpb25hbGl0eSBvZiB0aGUgY2hhcmFjdGVyLgorICAgICAgICAgKiBAcGFyYW0gYyBUaGUgdW5pY29kZSBjaGFyYWN0ZXIuCisgICAgICAgICAqIEByZXR1cm4gVGhlIGRpcmVjdGlvbiBvZiB0aGUgY2hhcmFjdGVyIG9yIERJUkVDVElPTkFMSVRZX1VOREVGSU5FRC4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBEaXJlY3Rpb24gZ2V0RGlyZWN0aW9uYWxpdHkoVUNoYXIzMiBjKTsKKyAgICAgICAgICAgIAorICAgICAgICAvKioKKyAgICAgICAgICogQ2hlY2sgaWYgdGhlIGNoYXJhY3RlciBpcyBhIG1pcnJvcmVkIGNoYXJhY3Rlci4gVGhpcyBtZWFucyB0aGF0IHRoZSBjaGFyYWN0ZXIKKyAgICAgICAgICogaGFzIGFuIGVxdWl2YWxlbnQgY2hhcmFjdGVyIHRoYXQgaXMgdGhlIG1pcnJvciBpbWFnZSBvZiBpdHNlbGYuCisgICAgICAgICAqIEBwYXJhbSBjIFRoZSB1bmljb2RlIGNoYXJhY3Rlci4KKyAgICAgICAgICogQHJldHVybiBUcnVlIGlmZiBjIGhhcyBhIG1pcnJvciBlcXVpdmFsZW50LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGJvb2wgaXNNaXJyb3JlZChVQ2hhcjMyIGMpOworICAgICAgICAgCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm4gdGhlIG1pcnJvciBvZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyLgorICAgICAgICAgKiBAcGFyYW0gYyBUaGUgdW5pY29kZSBjaGFyYWN0ZXIuCisgICAgICAgICAqIEByZXR1cm4gVGhlIG1pcnJvciBlcXVpdmFsZW50IG9mIGMuIElmIGMgZG9lcyBub3QgaGF2ZSBhIG1pcnJvciBlcXVpdmFsZW50LAorICAgICAgICAgKiAgICAgICAgIHRoZSBvcmlnaW5hbCBjaGFyYWN0ZXIgaXMgcmV0dXJuZWQuCisgICAgICAgICAqIEBzZWUgaXNNaXJyb3JlZAorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIFVDaGFyMzIgdG9NaXJyb3IoVUNoYXIzMiBjKTsKKyAgICAgICAgCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb252ZXJ0IHRoZSBjaGFyYWN0ZXIgdG8gdGl0bGUgY2FzZS4KKyAgICAgICAgICogQHBhcmFtIGMgVGhlIHVuaWNvZGUgY2hhcmFjdGVyLgorICAgICAgICAgKiBAcmV0dXJuIFRoZSB0aXRsZWNhc2UgZXF1aXZhbGVudCBvZiBjLiBJZiBjIGRvZXMgbm90IGhhdmUgYSB0aXRsZWNhc2UgZXF1aXZhbGVudCwKKyAgICAgICAgICogICAgICAgICB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyIGlzIHJldHVybmVkLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIFVDaGFyMzIgdG9UaXRsZShVQ2hhcjMyIGMpOworCisgICB9OworCit9CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9Bc3NldC5oIGIvaW5jbHVkZS91dGlscy9Bc3NldC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1M2EyMDQKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0Fzc2V0LmgKQEAgLTAsMCArMSwzMTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gQ2xhc3MgcHJvdmlkaW5nIGFjY2VzcyB0byBhIHJlYWQtb25seSBhc3NldC4gIEFzc2V0IG9iamVjdHMgYXJlIE5PVAorLy8gdGhyZWFkLXNhZmUsIGFuZCBzaG91bGQgbm90IGJlIHNoYXJlZCBhY3Jvc3MgdGhyZWFkcy4KKy8vCisjaWZuZGVmIF9fTElCU19BU1NFVF9ICisjZGVmaW5lIF9fTElCU19BU1NFVF9ICisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgIkZpbGVNYXAuaCIKKyNpbmNsdWRlICJTdHJpbmc4LmgiCisjaW5jbHVkZSAiRXJyb3JzLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHByb3ZpZGUgcmVhZC1vbmx5IG9wZXJhdGlvbnMgb24gYSBieXRlIHN0cmVhbS4KKyAqCisgKiBBY2Nlc3MgbWF5IGJlIG9wdGltaXplZCBmb3Igc3RyZWFtaW5nLCByYW5kb20sIG9yIHdob2xlIGJ1ZmZlciBtb2Rlcy4gIEFsbAorICogb3BlcmF0aW9ucyBhcmUgc3VwcG9ydGVkIHJlZ2FyZGxlc3Mgb2YgaG93IHRoZSBmaWxlIHdhcyBvcGVuZWQsIGJ1dCBzb21lCisgKiB0aGluZ3Mgd2lsbCBiZSBsZXNzIGVmZmljaWVudC4gIFtwYXNzIHRoYXQgaW4/P10KKyAqCisgKiAiQXNzZXQiIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgdHlwZXMgb2YgYXNzZXRzLiAgVGhlIGNsYXNzZXMgYmVsb3cKKyAqIHByb3ZpZGUgbW9zdCBvZiB0aGUgaW1wbGVtZW50YXRpb24uICBUaGUgQXNzZXRNYW5hZ2VyIHVzZXMgb25lIG9mIHRoZQorICogc3RhdGljICJjcmVhdGUiIGZ1bmN0aW9ucyBkZWZpbmVkIGhlcmUgdG8gY3JlYXRlIGEgbmV3IGluc3RhbmNlLgorICovCitjbGFzcyBBc3NldCB7CitwdWJsaWM6CisgICAgdmlydHVhbCB+QXNzZXQodm9pZCk7CisKKyAgICBzdGF0aWMgaW50MzJfdCBnZXRHbG9iYWxDb3VudCgpOworICAgIAorICAgIC8qIHVzZWQgd2hlbiBvcGVuaW5nIGFuIGFzc2V0ICovCisgICAgdHlwZWRlZiBlbnVtIEFjY2Vzc01vZGUgeworICAgICAgICBBQ0NFU1NfVU5LTk9XTiA9IDAsCisKKyAgICAgICAgLyogcmVhZCBjaHVua3MsIGFuZCBzZWVrIGZvcndhcmQgYW5kIGJhY2t3YXJkICovCisgICAgICAgIEFDQ0VTU19SQU5ET00sCisKKyAgICAgICAgLyogcmVhZCBzZXF1ZW50aWFsbHksIHdpdGggYW4gb2NjYXNpb25hbCBmb3J3YXJkIHNlZWsgKi8KKyAgICAgICAgQUNDRVNTX1NUUkVBTUlORywKKworICAgICAgICAvKiBjYWxsZXIgcGxhbnMgdG8gYXNrIGZvciBhIHJlYWQtb25seSBidWZmZXIgd2l0aCBhbGwgZGF0YSAqLworICAgICAgICBBQ0NFU1NfQlVGRkVSLAorICAgIH0gQWNjZXNzTW9kZTsKKworICAgIGVudW0geworICAgICAgICAvKiBkYXRhIGxhcmdlciB0aGFuIHRoaXMgZG9lcyBub3QgZ2V0IHVuY29tcHJlc3NlZCBpbnRvIGEgYnVmZmVyICovCisjaWZkZWYgSEFWRV9BTkRST0lEX09TCisgICAgICAgIFVOQ09NUFJFU1NfREFUQV9NQVggPSAxICogMTAyNCAqIDEwMjQKKyNlbHNlCisgICAgICAgIFVOQ09NUFJFU1NfREFUQV9NQVggPSAyICogMTAyNCAqIDEwMjQKKyNlbmRpZgorICAgIH07CisKKyAgICAvKgorICAgICAqIFJlYWQgZGF0YSBmcm9tIHRoZSBjdXJyZW50IG9mZnNldC4gIFJldHVybnMgdGhlIGFjdHVhbCBudW1iZXIgb2YKKyAgICAgKiBieXRlcyByZWFkLCAwIG9uIEVPRiwgb3IgLTEgb24gZXJyb3IuCisgICAgICovCisgICAgdmlydHVhbCBzc2l6ZV90IHJlYWQodm9pZCogYnVmLCBzaXplX3QgY291bnQpID0gMDsKKworICAgIC8qCisgICAgICogU2VlayB0byB0aGUgc3BlY2lmaWVkIG9mZnNldC4gICJ3aGVuY2UiIHVzZXMgdGhlIHNhbWUgdmFsdWVzIGFzCisgICAgICogbHNlZWsvZnNlZWsuICBSZXR1cm5zIHRoZSBuZXcgcG9zaXRpb24gb24gc3VjY2Vzcywgb3IgKG9mZl90KSAtMQorICAgICAqIG9uIGZhaWx1cmUuCisgICAgICovCisgICAgdmlydHVhbCBvZmZfdCBzZWVrKG9mZl90IG9mZnNldCwgaW50IHdoZW5jZSkgPSAwOworCisgICAgLyoKKyAgICAgKiBDbG9zZSB0aGUgYXNzZXQsIGZyZWVpbmcgYWxsIGFzc29jaWF0ZWQgcmVzb3VyY2VzLgorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCBjbG9zZSh2b2lkKSA9IDA7CisKKyAgICAvKgorICAgICAqIEdldCBhIHBvaW50ZXIgdG8gYSBidWZmZXIgd2l0aCB0aGUgZW50aXJlIGNvbnRlbnRzIG9mIHRoZSBmaWxlLgorICAgICAqLworICAgIHZpcnR1YWwgY29uc3Qgdm9pZCogZ2V0QnVmZmVyKGJvb2wgd29yZEFsaWduZWQpID0gMDsKKworICAgIC8qCisgICAgICogR2V0IHRoZSB0b3RhbCBhbW91bnQgb2YgZGF0YSB0aGF0IGNhbiBiZSByZWFkLgorICAgICAqLworICAgIHZpcnR1YWwgb2ZmX3QgZ2V0TGVuZ3RoKHZvaWQpIGNvbnN0ID0gMDsKKworICAgIC8qCisgICAgICogR2V0IHRoZSB0b3RhbCBhbW91bnQgb2YgZGF0YSB0aGF0IGNhbiBiZSByZWFkIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICovCisgICAgdmlydHVhbCBvZmZfdCBnZXRSZW1haW5pbmdMZW5ndGgodm9pZCkgY29uc3QgPSAwOworCisgICAgLyoKKyAgICAgKiBPcGVuIGEgbmV3IGZpbGUgZGVzY3JpcHRvciB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlYWQgdGhpcyBhc3NldC4KKyAgICAgKiBSZXR1cm5zIC0xIGlmIHlvdSBjYW4gbm90IHVzZSB0aGUgZmlsZSBkZXNjcmlwdG9yIChmb3IgZXhhbXBsZSBpZiB0aGUKKyAgICAgKiBhc3NldCBpcyBjb21wcmVzc2VkKS4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIGludCBvcGVuRmlsZURlc2NyaXB0b3Iob2ZmX3QqIG91dFN0YXJ0LCBvZmZfdCogb3V0TGVuZ3RoKSBjb25zdCA9IDA7CisgICAgCisgICAgLyoKKyAgICAgKiBHZXQgYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIGFzc2V0J3Mgc291cmNlLiAgVGhpcyBtaWdodCBiZSBhIGZ1bGwKKyAgICAgKiBwYXRoLCBpdCBtaWdodCBiZSBhIGNvbG9uLXNlcGFyYXRlZCBsaXN0IG9mIGlkZW50aWZpZXJzLgorICAgICAqCisgICAgICogVGhpcyBpcyBOT1QgaW50ZW5kZWQgdG8gYmUgdXNlZCBmb3IgYW55dGhpbmcgZXhjZXB0IGRlYnVnIG91dHB1dC4KKyAgICAgKiBETyBOT1QgdHJ5IHRvIHBhcnNlIHRoaXMgb3IgdXNlIGl0IHRvIG9wZW4gYSBmaWxlLgorICAgICAqLworICAgIGNvbnN0IGNoYXIqIGdldEFzc2V0U291cmNlKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1Bc3NldFNvdXJjZS5zdHJpbmcoKTsgfQorCitwcm90ZWN0ZWQ6CisgICAgQXNzZXQodm9pZCk7ICAgICAgICAvLyBjb25zdHJ1Y3Rvcjsgb25seSBpbnZva2VkIGluZGlyZWN0bHkKKworICAgIC8qIGhhbmRsZSBjb21tb24gc2VlaygpIGhvdXNla2VlcGluZyAqLworICAgIG9mZl90IGhhbmRsZVNlZWsob2ZmX3Qgb2Zmc2V0LCBpbnQgd2hlbmNlLCBvZmZfdCBjdXJQb3NuLCBvZmZfdCBtYXhQb3NuKTsKKworICAgIC8qIHNldCB0aGUgYXNzZXQgc291cmNlIHN0cmluZyAqLworICAgIHZvaWQgc2V0QXNzZXRTb3VyY2UoY29uc3QgU3RyaW5nOCYgcGF0aCkgeyBtQXNzZXRTb3VyY2UgPSBwYXRoOyB9CisKKyAgICBBY2Nlc3NNb2RlIGdldEFjY2Vzc01vZGUodm9pZCkgY29uc3QgeyByZXR1cm4gbUFjY2Vzc01vZGU7IH0KKworcHJpdmF0ZToKKyAgICAvKiB0aGVzZSBvcGVyYXRpb25zIGFyZSBub3QgaW1wbGVtZW50ZWQgKi8KKyAgICBBc3NldChjb25zdCBBc3NldCYgc3JjKTsKKyAgICBBc3NldCYgb3BlcmF0b3I9KGNvbnN0IEFzc2V0JiBzcmMpOworCisgICAgLyogQXNzZXRNYW5hZ2VyIG5lZWRzIGFjY2VzcyB0byBvdXIgImNyZWF0ZSIgZnVuY3Rpb25zICovCisgICAgZnJpZW5kIGNsYXNzIEFzc2V0TWFuYWdlcjsKKworICAgIC8qCisgICAgICogQ3JlYXRlIHRoZSBhc3NldCBmcm9tIGEgbmFtZWQgZmlsZSBvbiBkaXNrLgorICAgICAqLworICAgIHN0YXRpYyBBc3NldCogY3JlYXRlRnJvbUZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUsIEFjY2Vzc01vZGUgbW9kZSk7CisKKyAgICAvKgorICAgICAqIENyZWF0ZSB0aGUgYXNzZXQgZnJvbSBhIG5hbWVkLCBjb21wcmVzc2VkIGZpbGUgb24gZGlzayAoZS5nLiAiLmd6IikuCisgICAgICovCisgICAgc3RhdGljIEFzc2V0KiBjcmVhdGVGcm9tQ29tcHJlc3NlZEZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUsCisgICAgICAgIEFjY2Vzc01vZGUgbW9kZSk7CisKKyNpZiAwCisgICAgLyoKKyAgICAgKiBDcmVhdGUgdGhlIGFzc2V0IGZyb20gYSBzZWdtZW50IG9mIGFuIG9wZW4gZmlsZS4gIFRoaXMgd2lsbCBmYWlsCisgICAgICogaWYgIm9mZnNldCIgYW5kICJsZW5ndGgiIGRvbid0IGZpdCB3aXRoaW4gdGhlIGJvdW5kcyBvZiB0aGUgZmlsZS4KKyAgICAgKgorICAgICAqIFRoZSBhc3NldCB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBzdGF0aWMgQXNzZXQqIGNyZWF0ZUZyb21GaWxlU2VnbWVudChpbnQgZmQsIG9mZl90IG9mZnNldCwgc2l6ZV90IGxlbmd0aCwKKyAgICAgICAgQWNjZXNzTW9kZSBtb2RlKTsKKworICAgIC8qCisgICAgICogQ3JlYXRlIGZyb20gY29tcHJlc3NlZCBkYXRhLiAgImZkIiBzaG91bGQgYmUgc2Vla2VkIHRvIHRoZSBzdGFydCBvZgorICAgICAqIHRoZSBjb21wcmVzc2VkIGRhdGEuICBUaGlzIGNvdWxkIGJlIGluc2lkZSBhIGd6aXAgZmlsZSBvciBwYXJ0IG9mIGEKKyAgICAgKiBaaXAgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIFRoZSBhc3NldCB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKgorICAgICAqIFRoaXMgbWF5IG5vdCB2ZXJpZnkgdGhlIHZhbGlkaXR5IG9mIHRoZSBjb21wcmVzc2VkIGRhdGEgdW50aWwgZmlyc3QKKyAgICAgKiB1c2UuCisgICAgICovCisgICAgc3RhdGljIEFzc2V0KiBjcmVhdGVGcm9tQ29tcHJlc3NlZERhdGEoaW50IGZkLCBvZmZfdCBvZmZzZXQsCisgICAgICAgIGludCBjb21wcmVzc2lvbk1ldGhvZCwgc2l6ZV90IGNvbXByZXNzZWRMZW5ndGgsCisgICAgICAgIHNpemVfdCB1bmNvbXByZXNzZWRMZW5ndGgsIEFjY2Vzc01vZGUgbW9kZSk7CisjZW5kaWYKKworICAgIC8qCisgICAgICogQ3JlYXRlIHRoZSBhc3NldCBmcm9tIGEgbWVtb3J5LW1hcHBlZCBmaWxlIHNlZ21lbnQuCisgICAgICoKKyAgICAgKiBUaGUgYXNzZXQgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBGaWxlTWFwLgorICAgICAqLworICAgIHN0YXRpYyBBc3NldCogY3JlYXRlRnJvbVVuY29tcHJlc3NlZE1hcChGaWxlTWFwKiBkYXRhTWFwLCBBY2Nlc3NNb2RlIG1vZGUpOworCisgICAgLyoKKyAgICAgKiBDcmVhdGUgdGhlIGFzc2V0IGZyb20gYSBtZW1vcnktbWFwcGVkIGZpbGUgc2VnbWVudCB3aXRoIGNvbXByZXNzZWQKKyAgICAgKiBkYXRhLiAgIm1ldGhvZCIgaXMgYSBaaXAgYXJjaGl2ZSBjb21wcmVzc2lvbiBtZXRob2QgY29uc3RhbnQuCisgICAgICoKKyAgICAgKiBUaGUgYXNzZXQgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBGaWxlTWFwLgorICAgICAqLworICAgIHN0YXRpYyBBc3NldCogY3JlYXRlRnJvbUNvbXByZXNzZWRNYXAoRmlsZU1hcCogZGF0YU1hcCwgaW50IG1ldGhvZCwKKyAgICAgICAgc2l6ZV90IHVuY29tcHJlc3NlZExlbiwgQWNjZXNzTW9kZSBtb2RlKTsKKworCisgICAgLyoKKyAgICAgKiBDcmVhdGUgZnJvbSBhIHJlZmVyZW5jZS1jb3VudGVkIGNodW5rIG9mIHNoYXJlZCBtZW1vcnkuCisgICAgICovCisgICAgLy8gVE9ETworCisgICAgQWNjZXNzTW9kZSAgbUFjY2Vzc01vZGU7ICAgICAgICAvLyBob3cgdGhlIGFzc2V0IHdhcyBvcGVuZWQKKyAgICBTdHJpbmc4ICAgIG1Bc3NldFNvdXJjZTsgICAgICAgLy8gZGVidWcgc3RyaW5nCit9OworCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqCisgKiBJbm5hcmRzIGZvbGxvdy4gIERvIG5vdCB1c2UgdGhlc2UgY2xhc3NlcyBkaXJlY3RseS4KKyAqLworCisvKgorICogQW4gYXNzZXQgYmFzZWQgb24gYW4gdW5jb21wcmVzc2VkIGZpbGUgb24gZGlzay4gIEl0IG1heSBlbmNvbXBhc3MgdGhlCisgKiBlbnRpcmUgZmlsZSBvciBqdXN0IGEgcGllY2Ugb2YgaXQuICBBY2Nlc3MgaXMgdGhyb3VnaCBmcmVhZC9mc2Vlay4KKyAqLworY2xhc3MgX0ZpbGVBc3NldCA6IHB1YmxpYyBBc3NldCB7CitwdWJsaWM6CisgICAgX0ZpbGVBc3NldCh2b2lkKTsKKyAgICB2aXJ0dWFsIH5fRmlsZUFzc2V0KHZvaWQpOworCisgICAgLyoKKyAgICAgKiBVc2UgYSBwaWVjZSBvZiBhbiBhbHJlYWR5LW9wZW4gZmlsZS4KKyAgICAgKgorICAgICAqIE9uIHN1Y2Nlc3MsIHRoZSBvYmplY3QgdGFrZXMgb3duZXJzaGlwIG9mICJmZCIuCisgICAgICovCisgICAgc3RhdHVzX3Qgb3BlbkNodW5rKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBpbnQgZmQsIG9mZl90IG9mZnNldCwgc2l6ZV90IGxlbmd0aCk7CisKKyAgICAvKgorICAgICAqIFVzZSBhIG1lbW9yeS1tYXBwZWQgcmVnaW9uLgorICAgICAqCisgICAgICogT24gc3VjY2VzcywgdGhlIG9iamVjdCB0YWtlcyBvd25lcnNoaXAgb2YgImRhdGFNYXAiLgorICAgICAqLworICAgIHN0YXR1c190IG9wZW5DaHVuayhGaWxlTWFwKiBkYXRhTWFwKTsKKworICAgIC8qCisgICAgICogU3RhbmRhcmQgQXNzZXQgaW50ZXJmYWNlcy4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHNzaXplX3QgcmVhZCh2b2lkKiBidWYsIHNpemVfdCBjb3VudCk7CisgICAgdmlydHVhbCBvZmZfdCBzZWVrKG9mZl90IG9mZnNldCwgaW50IHdoZW5jZSk7CisgICAgdmlydHVhbCB2b2lkIGNsb3NlKHZvaWQpOworICAgIHZpcnR1YWwgY29uc3Qgdm9pZCogZ2V0QnVmZmVyKGJvb2wgd29yZEFsaWduZWQpOworICAgIHZpcnR1YWwgb2ZmX3QgZ2V0TGVuZ3RoKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1MZW5ndGg7IH0KKyAgICB2aXJ0dWFsIG9mZl90IGdldFJlbWFpbmluZ0xlbmd0aCh2b2lkKSBjb25zdCB7IHJldHVybiBtTGVuZ3RoLW1PZmZzZXQ7IH0KKyAgICB2aXJ0dWFsIGludCBvcGVuRmlsZURlc2NyaXB0b3Iob2ZmX3QqIG91dFN0YXJ0LCBvZmZfdCogb3V0TGVuZ3RoKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBvZmZfdCAgICAgICBtU3RhcnQ7ICAgICAgICAgLy8gYWJzb2x1dGUgZmlsZSBvZmZzZXQgb2Ygc3RhcnQgb2YgY2h1bmsKKyAgICBvZmZfdCAgICAgICBtTGVuZ3RoOyAgICAgICAgLy8gbGVuZ3RoIG9mIHRoZSBjaHVuaworICAgIG9mZl90ICAgICAgIG1PZmZzZXQ7ICAgICAgICAvLyBjdXJyZW50IGxvY2FsIG9mZnNldCwgMCA9PSBtU3RhcnQKKyAgICBGSUxFKiAgICAgICBtRnA7ICAgICAgICAgICAgLy8gZm9yIHJlYWQvc2VlaworICAgIGNoYXIqICAgICAgIG1GaWxlTmFtZTsgICAgICAvLyBmb3Igb3BlbmluZworCisgICAgLyoKKyAgICAgKiBUbyBzdXBwb3J0IGdldEJ1ZmZlcigpIHdlIGVpdGhlciBuZWVkIHRvIHJlYWQgdGhlIGVudGlyZSB0aGluZyBpbnRvCisgICAgICogYSBidWZmZXIgb3IgbWVtb3J5LW1hcCBpdC4gIEZvciBzbWFsbCBmaWxlcyBpdCdzIHByb2JhYmx5IGJlc3QgdG8KKyAgICAgKiBqdXN0IHJlYWQgdGhlbSBpbi4KKyAgICAgKi8KKyAgICBlbnVtIHsga1JlYWRWc01hcFRocmVzaG9sZCA9IDQwOTYgfTsKKworICAgIEZpbGVNYXAqICAgIG1NYXA7ICAgICAgICAgICAvLyBmb3IgbWVtb3J5IG1hcAorICAgIHVuc2lnbmVkIGNoYXIqIG1CdWY7ICAgICAgICAvLyBmb3IgcmVhZAorICAgIAorICAgIGNvbnN0IHZvaWQqIGVuc3VyZUFsaWdubWVudChGaWxlTWFwKiBtYXApOworfTsKKworCisvKgorICogQW4gYXNzZXQgYmFzZWQgb24gY29tcHJlc3NlZCBkYXRhIGluIGEgZmlsZS4KKyAqLworY2xhc3MgX0NvbXByZXNzZWRBc3NldCA6IHB1YmxpYyBBc3NldCB7CitwdWJsaWM6CisgICAgX0NvbXByZXNzZWRBc3NldCh2b2lkKTsKKyAgICB2aXJ0dWFsIH5fQ29tcHJlc3NlZEFzc2V0KHZvaWQpOworCisgICAgLyoKKyAgICAgKiBVc2UgYSBwaWVjZSBvZiBhbiBhbHJlYWR5LW9wZW4gZmlsZS4KKyAgICAgKgorICAgICAqIE9uIHN1Y2Nlc3MsIHRoZSBvYmplY3QgdGFrZXMgb3duZXJzaGlwIG9mICJmZCIuCisgICAgICovCisgICAgc3RhdHVzX3Qgb3BlbkNodW5rKGludCBmZCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY29tcHJlc3Npb25NZXRob2QsCisgICAgICAgIHNpemVfdCB1bmNvbXByZXNzZWRMZW4sIHNpemVfdCBjb21wcmVzc2VkTGVuKTsKKworICAgIC8qCisgICAgICogVXNlIGEgbWVtb3J5LW1hcHBlZCByZWdpb24uCisgICAgICoKKyAgICAgKiBPbiBzdWNjZXNzLCB0aGUgb2JqZWN0IHRha2VzIG93bmVyc2hpcCBvZiAiZmQiLgorICAgICAqLworICAgIHN0YXR1c190IG9wZW5DaHVuayhGaWxlTWFwKiBkYXRhTWFwLCBpbnQgY29tcHJlc3Npb25NZXRob2QsCisgICAgICAgIHNpemVfdCB1bmNvbXByZXNzZWRMZW4pOworCisgICAgLyoKKyAgICAgKiBTdGFuZGFyZCBBc3NldCBpbnRlcmZhY2VzLgorICAgICAqLworICAgIHZpcnR1YWwgc3NpemVfdCByZWFkKHZvaWQqIGJ1Ziwgc2l6ZV90IGNvdW50KTsKKyAgICB2aXJ0dWFsIG9mZl90IHNlZWsob2ZmX3Qgb2Zmc2V0LCBpbnQgd2hlbmNlKTsKKyAgICB2aXJ0dWFsIHZvaWQgY2xvc2Uodm9pZCk7CisgICAgdmlydHVhbCBjb25zdCB2b2lkKiBnZXRCdWZmZXIoYm9vbCB3b3JkQWxpZ25lZCk7CisgICAgdmlydHVhbCBvZmZfdCBnZXRMZW5ndGgodm9pZCkgY29uc3QgeyByZXR1cm4gbVVuY29tcHJlc3NlZExlbjsgfQorICAgIHZpcnR1YWwgb2ZmX3QgZ2V0UmVtYWluaW5nTGVuZ3RoKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1VbmNvbXByZXNzZWRMZW4tbU9mZnNldDsgfQorICAgIHZpcnR1YWwgaW50IG9wZW5GaWxlRGVzY3JpcHRvcihvZmZfdCogb3V0U3RhcnQsIG9mZl90KiBvdXRMZW5ndGgpIGNvbnN0IHsgcmV0dXJuIC0xOyB9CisKK3ByaXZhdGU6CisgICAgb2ZmX3QgICAgICAgbVN0YXJ0OyAgICAgICAgIC8vIG9mZnNldCB0byBzdGFydCBvZiBjb21wcmVzc2VkIGRhdGEKKyAgICBvZmZfdCAgICAgICBtQ29tcHJlc3NlZExlbjsgLy8gbGVuZ3RoIG9mIHRoZSBjb21wcmVzc2VkIGRhdGEKKyAgICBvZmZfdCAgICAgICBtVW5jb21wcmVzc2VkTGVuOyAvLyBsZW5ndGggb2YgdGhlIHVuY29tcHJlc3NlZCBkYXRhCisgICAgb2ZmX3QgICAgICAgbU9mZnNldDsgICAgICAgIC8vIGN1cnJlbnQgb2Zmc2V0LCAwID09IHN0YXJ0IG9mIHVuY29tcCBkYXRhCisKKyAgICBGaWxlTWFwKiAgICBtTWFwOyAgICAgICAgICAgLy8gZm9yIG1lbW9yeS1tYXBwZWQgaW5wdXQKKyAgICBpbnQgICAgICAgICBtRmQ7ICAgICAgICAgICAgLy8gZm9yIGZpbGUgaW5wdXQKKworICAgIHVuc2lnbmVkIGNoYXIqICBtQnVmOyAgICAgICAvLyBmb3IgZ2V0QnVmZmVyKCkKK307CisKKy8vIG5lZWQ6IHNoYXJlZCBtbWFwIHZlcnNpb24/CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBfX0xJQlNfQVNTRVRfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9Bc3NldERpci5oIGIvaW5jbHVkZS91dGlscy9Bc3NldERpci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiZjhhMzUKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0Fzc2V0RGlyLmgKQEAgLTAsMCArMSwxNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gQWNjZXNzIGEgY2h1bmsgb2YgdGhlIGFzc2V0IGhpZXJhcmNoeSBhcyBpZiBpdCB3ZXJlIGEgc2luZ2xlIGRpcmVjdG9yeS4KKy8vCisjaWZuZGVmIF9fTElCU19BU1NFVERJUl9ICisjZGVmaW5lIF9fTElCU19BU1NFVERJUl9ICisKKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvU29ydGVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvbWlzYy5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8qCisgKiBUaGlzIHByb3ZpZGVzIHZlY3Rvci1zdHlsZSBhY2Nlc3MgdG8gYSBkaXJlY3RvcnkuICBXZSBkbyB0aGlzIHJhdGhlcgorICogdGhhbiBtb2RlbGluZyBvcGVuZGlyL3JlYWRkaXIgYWNjZXNzIGJlY2F1c2UgaXQncyBzaW1wbGVyIGFuZCB0aGUKKyAqIG5hdHVyZSBvZiB0aGUgb3BlcmF0aW9uIHJlcXVpcmVzIHVzIHRvIGhhdmUgYWxsIGRhdGEgb24gaGFuZCBhbnl3YXkuCisgKgorICogVGhlIGxpc3Qgb2YgZmlsZXMgd2lsbCBiZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIGJ5IEFTQ0lJIHZhbHVlLgorICoKKyAqIFRoZSBjb250ZW50cyBhcmUgcG9wdWxhdGVkIGJ5IG91ciBmcmllbmQsIHRoZSBBc3NldE1hbmFnZXIuCisgKi8KK2NsYXNzIEFzc2V0RGlyIHsKK3B1YmxpYzoKKyAgICBBc3NldERpcih2b2lkKQorICAgICAgICA6IG1GaWxlSW5mbyhOVUxMKQorICAgICAgICB7fQorICAgIHZpcnR1YWwgfkFzc2V0RGlyKHZvaWQpIHsKKyAgICAgICAgZGVsZXRlIG1GaWxlSW5mbzsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFZlY3Rvci1zdHlsZSBhY2Nlc3MuCisgICAgICovCisgICAgc2l6ZV90IGdldEZpbGVDb3VudCh2b2lkKSB7IHJldHVybiBtRmlsZUluZm8tPnNpemUoKTsgfQorICAgIGNvbnN0IFN0cmluZzgmIGdldEZpbGVOYW1lKGludCBpZHgpIHsKKyAgICAgICAgcmV0dXJuIG1GaWxlSW5mby0+aXRlbUF0KGlkeCkuZ2V0RmlsZU5hbWUoKTsKKyAgICB9CisgICAgY29uc3QgU3RyaW5nOCYgZ2V0U291cmNlTmFtZShpbnQgaWR4KSB7CisgICAgICAgIHJldHVybiBtRmlsZUluZm8tPml0ZW1BdChpZHgpLmdldFNvdXJjZU5hbWUoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldCB0aGUgdHlwZSBvZiBhIGZpbGUgKHVzdWFsbHkgcmVndWxhciBvciBkaXJlY3RvcnkpLgorICAgICAqLworICAgIEZpbGVUeXBlIGdldEZpbGVUeXBlKGludCBpZHgpIHsKKyAgICAgICAgcmV0dXJuIG1GaWxlSW5mby0+aXRlbUF0KGlkeCkuZ2V0RmlsZVR5cGUoKTsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgLyogdGhlc2Ugb3BlcmF0aW9ucyBhcmUgbm90IGltcGxlbWVudGVkICovCisgICAgQXNzZXREaXIoY29uc3QgQXNzZXREaXImIHNyYyk7CisgICAgY29uc3QgQXNzZXREaXImIG9wZXJhdG9yPShjb25zdCBBc3NldERpciYgc3JjKTsKKworICAgIGZyaWVuZCBjbGFzcyBBc3NldE1hbmFnZXI7CisKKyAgICAvKgorICAgICAqIFRoaXMgaG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgZmlsZXMgaW4gdGhlIGFzc2V0IGhpZXJhcmNoeS4KKyAgICAgKi8KKyAgICBjbGFzcyBGaWxlSW5mbyB7CisgICAgcHVibGljOgorICAgICAgICBGaWxlSW5mbyh2b2lkKSB7fQorICAgICAgICBGaWxlSW5mbyhjb25zdCBTdHJpbmc4JiBwYXRoKSAgICAgIC8vIHVzZWZ1bCBmb3IgZS5nLiBzdmVjdC5pbmRleE9mCisgICAgICAgICAgICA6IG1GaWxlTmFtZShwYXRoKSwgbUZpbGVUeXBlKGtGaWxlVHlwZVVua25vd24pCisgICAgICAgICAgICB7fQorICAgICAgICB+RmlsZUluZm8odm9pZCkge30KKyAgICAgICAgRmlsZUluZm8oY29uc3QgRmlsZUluZm8mIHNyYykgeworICAgICAgICAgICAgY29weU1lbWJlcnMoc3JjKTsKKyAgICAgICAgfQorICAgICAgICBjb25zdCBGaWxlSW5mbyYgb3BlcmF0b3I9IChjb25zdCBGaWxlSW5mbyYgc3JjKSB7CisgICAgICAgICAgICBpZiAodGhpcyAhPSAmc3JjKQorICAgICAgICAgICAgICAgIGNvcHlNZW1iZXJzKHNyYyk7CisgICAgICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGNvcHlNZW1iZXJzKGNvbnN0IEZpbGVJbmZvJiBzcmMpIHsKKyAgICAgICAgICAgIG1GaWxlTmFtZSA9IHNyYy5tRmlsZU5hbWU7CisgICAgICAgICAgICBtRmlsZVR5cGUgPSBzcmMubUZpbGVUeXBlOworICAgICAgICAgICAgbVNvdXJjZU5hbWUgPSBzcmMubVNvdXJjZU5hbWU7CisgICAgICAgIH0KKworICAgICAgICAvKiBuZWVkIHRoaXMgZm9yIFNvcnRlZFZlY3RvcjsgbXVzdCBjb21wYXJlIG9ubHkgb24gZmlsZSBuYW1lICovCisgICAgICAgIGJvb2wgb3BlcmF0b3I8IChjb25zdCBGaWxlSW5mbyYgcmhzKSBjb25zdCB7CisgICAgICAgICAgICByZXR1cm4gbUZpbGVOYW1lIDwgcmhzLm1GaWxlTmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIHVzZWQgYnkgQXNzZXRNYW5hZ2VyICovCisgICAgICAgIGJvb2wgb3BlcmF0b3I9PSAoY29uc3QgRmlsZUluZm8mIHJocykgY29uc3QgeworICAgICAgICAgICAgcmV0dXJuIG1GaWxlTmFtZSA9PSByaHMubUZpbGVOYW1lOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBzZXQoY29uc3QgU3RyaW5nOCYgcGF0aCwgRmlsZVR5cGUgdHlwZSkgeworICAgICAgICAgICAgbUZpbGVOYW1lID0gcGF0aDsKKyAgICAgICAgICAgIG1GaWxlVHlwZSA9IHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBjb25zdCBTdHJpbmc4JiBnZXRGaWxlTmFtZSh2b2lkKSBjb25zdCB7IHJldHVybiBtRmlsZU5hbWU7IH0KKyAgICAgICAgdm9pZCBzZXRGaWxlTmFtZShjb25zdCBTdHJpbmc4JiBwYXRoKSB7IG1GaWxlTmFtZSA9IHBhdGg7IH0KKworICAgICAgICBGaWxlVHlwZSBnZXRGaWxlVHlwZSh2b2lkKSBjb25zdCB7IHJldHVybiBtRmlsZVR5cGU7IH0KKyAgICAgICAgdm9pZCBzZXRGaWxlVHlwZShGaWxlVHlwZSB0eXBlKSB7IG1GaWxlVHlwZSA9IHR5cGU7IH0KKworICAgICAgICBjb25zdCBTdHJpbmc4JiBnZXRTb3VyY2VOYW1lKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1Tb3VyY2VOYW1lOyB9CisgICAgICAgIHZvaWQgc2V0U291cmNlTmFtZShjb25zdCBTdHJpbmc4JiBwYXRoKSB7IG1Tb3VyY2VOYW1lID0gcGF0aDsgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEhhbmR5IHV0aWxpdHkgZm9yIGZpbmRpbmcgYW4gZW50cnkgaW4gYSBzb3J0ZWQgdmVjdG9yIG9mIEZpbGVJbmZvLgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hpbmcgZW50cnksIG9yIC0xIGlmIG5vbmUgZm91bmQuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgaW50IGZpbmRFbnRyeShjb25zdCBTb3J0ZWRWZWN0b3I8RmlsZUluZm8+KiBwVmVjdG9yLAorICAgICAgICAgICAgY29uc3QgU3RyaW5nOCYgZmlsZU5hbWUpOworCisgICAgcHJpdmF0ZToKKyAgICAgICAgU3RyaW5nOCAgICBtRmlsZU5hbWU7ICAgICAgLy8gZmlsZW5hbWUgb25seQorICAgICAgICBGaWxlVHlwZSAgICBtRmlsZVR5cGU7ICAgICAgLy8gcmVndWxhciwgZGlyZWN0b3J5LCBldGMKKworICAgICAgICBTdHJpbmc4ICAgIG1Tb3VyY2VOYW1lOyAgICAvLyBjdXJyZW50bHkgZGVidWctb25seQorICAgIH07CisKKyAgICAvKiBBc3NldE1hbmFnZXIgdXNlcyB0aGlzIHRvIGluaXRpYWxpemUgdXMgKi8KKyAgICB2b2lkIHNldEZpbGVMaXN0KFNvcnRlZFZlY3RvcjxGaWxlSW5mbz4qIGxpc3QpIHsgbUZpbGVJbmZvID0gbGlzdDsgfQorCisgICAgU29ydGVkVmVjdG9yPEZpbGVJbmZvPiogbUZpbGVJbmZvOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIF9fTElCU19BU1NFVERJUl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0Fzc2V0TWFuYWdlci5oIGIvaW5jbHVkZS91dGlscy9Bc3NldE1hbmFnZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTRjMGU4Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9Bc3NldE1hbmFnZXIuaApAQCAtMCwwICsxLDMyMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBBc3NldCBtYW5hZ2VtZW50IGNsYXNzLiAgQXNzZXRNYW5hZ2VyIG9iamVjdHMgYXJlIHRocmVhZC1zYWZlLgorLy8KKyNpZm5kZWYgX19MSUJTX0FTU0VUTUFOQUdFUl9ICisjZGVmaW5lIF9fTElCU19BU1NFVE1BTkFHRVJfSAorCisjaW5jbHVkZSA8dXRpbHMvQXNzZXQuaD4KKyNpbmNsdWRlIDx1dGlscy9Bc3NldERpci5oPgorI2luY2x1ZGUgPHV0aWxzL0tleWVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzE2Lmg+CisjaW5jbHVkZSA8dXRpbHMvWmlwRmlsZVJPLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEFzc2V0OyAgICAgICAgLy8gZndkIGRlY2wgZm9yIHRoaW5ncyB0aGF0IGluY2x1ZGUgQXNzZXQuaCBmaXJzdAorY2xhc3MgUmVzVGFibGU7CitzdHJ1Y3QgUmVzVGFibGVfY29uZmlnOworCisvKgorICogRXZlcnkgYXBwbGljYXRpb24gdGhhdCB1c2VzIGFzc2V0cyBuZWVkcyBvbmUgaW5zdGFuY2Ugb2YgdGhpcy4gIEEKKyAqIHNpbmdsZSBpbnN0YW5jZSBtYXkgYmUgc2hhcmVkIGFjcm9zcyBtdWx0aXBsZSB0aHJlYWRzLCBhbmQgYSBzaW5nbGUKKyAqIHRocmVhZCBtYXkgaGF2ZSBtb3JlIHRoYW4gb25lIGluc3RhbmNlICh0aGUgbGF0dGVyIGlzIGRpc2NvdXJhZ2VkKS4KKyAqCisgKiBUaGUgcHVycG9zZSBvZiB0aGUgQXNzZXRNYW5hZ2VyIGlzIHRvIGNyZWF0ZSBBc3NldCBvYmplY3RzLiAgVG8gZG8KKyAqIHRoaXMgZWZmaWNpZW50bHkgaXQgbWF5IGNhY2hlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbnMgb2YKKyAqIGZpbGVzIGl0IGhhcyBzZWVuLiAgVGhpcyBjYW4gYmUgY29udHJvbGxlZCB3aXRoIHRoZSAiY2FjaGVNb2RlIgorICogYXJndW1lbnQuCisgKgorICogVGhlIGFzc2V0IGhpZXJhcmNoeSBtYXkgYmUgZXhhbWluZWQgbGlrZSBhIGZpbGVzeXN0ZW0sIHVzaW5nCisgKiBBc3NldERpciBvYmplY3RzIHRvIHBlcnVzZSBhIHNpbmdsZSBkaXJlY3RvcnkuCisgKi8KK2NsYXNzIEFzc2V0TWFuYWdlciB7CitwdWJsaWM6CisgICAgdHlwZWRlZiBlbnVtIENhY2hlTW9kZSB7CisgICAgICAgIENBQ0hFX1VOS05PV04gPSAwLAorICAgICAgICBDQUNIRV9PRkYsICAgICAgICAgIC8vIGRvbid0IHRyeSB0byBjYWNoZSBmaWxlIGxvY2F0aW9ucworICAgICAgICBDQUNIRV9ERUZFUiwgICAgICAgIC8vIGNvbnN0cnVjdCBjYWNoZSBhcyBwaWVjZXMgYXJlIG5lZWRlZAorICAgICAgICAvL0NBQ0hFX1NDQU4sICAgICAgICAgLy8gc2NhbiBmdWxsKCEpIGFzc2V0IGhpZXJhcmNoeSBhdCBpbml0KCkgdGltZQorICAgIH0gQ2FjaGVNb2RlOworCisgICAgQXNzZXRNYW5hZ2VyKENhY2hlTW9kZSBjYWNoZU1vZGUgPSBDQUNIRV9PRkYpOworICAgIHZpcnR1YWwgfkFzc2V0TWFuYWdlcih2b2lkKTsKKworICAgIHN0YXRpYyBpbnQzMl90IGdldEdsb2JhbENvdW50KCk7CisgICAgCisgICAgLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAqIEFkZCBhIG5ldyBzb3VyY2UgZm9yIGFzc2V0cy4gIFRoaXMgY2FuIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyB0bworICAgICAqIGxvb2sgaW4gbXVsdGlwbGUgcGxhY2VzIGZvciBhc3NldHMuICBJdCBjYW4gYmUgZWl0aGVyIGEgZGlyZWN0b3J5IChmb3IKKyAgICAgKiBmaW5kaW5nIGFzc2V0cyBhcyByYXcgZmlsZXMgb24gdGhlIGRpc2spIG9yIGEgWklQIGZpbGUuICBUaGlzIG5ld2x5CisgICAgICogYWRkZWQgYXNzZXQgcGF0aCB3aWxsIGJlIGV4YW1pbmVkIGZpcnN0IHdoZW4gc2VhcmNoaW5nIGZvciBhc3NldHMsCisgICAgICogYmVmb3JlIGFueSB0aGF0IHdlcmUgcHJldmlvdXNseSBhZGRlZC4KKyAgICAgKgorICAgICAqIFJldHVybnMgInRydWUiIG9uIHN1Y2Nlc3MsICJmYWxzZSIgb24gZmFpbHVyZS4gIElmICdjb29raWUnIGlzIG5vbi1OVUxMLAorICAgICAqIHRoZW4gb24gc3VjY2VzcywgKmNvb2tpZSBpcyBzZXQgdG8gdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlCisgICAgICogbmV3bHktYWRkZWQgYXNzZXQgc291cmNlLgorICAgICAqLworICAgIGJvb2wgYWRkQXNzZXRQYXRoKGNvbnN0IFN0cmluZzgmIHBhdGgsIHZvaWQqKiBjb29raWUpOworCisgICAgLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAqIENvbnZlbmllbmNlIGZvciBhZGRpbmcgdGhlIHN0YW5kYXJkIHN5c3RlbSBhc3NldHMuICBVc2VzIHRoZQorICAgICAqIEFORFJPSURfUk9PVCBlbnZpcm9ubWVudCB2YXJpYWJsZSB0byBmaW5kIHRoZW0uCisgICAgICovCisgICAgYm9vbCBhZGREZWZhdWx0QXNzZXRzKCk7CisKKyAgICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICogSXRlcmF0ZSBvdmVyIHRoZSBhc3NldCBwYXRocyBpbiB0aGlzIG1hbmFnZXIuICAoUHJldmlvdXNseQorICAgICAqIGFkZGVkIHZpYSBhZGRBc3NldFBhdGgoKSBhbmQgYWRkRGVmYXVsdEFzc2V0cygpLikgIE9uIGZpcnN0IGNhbGwsCisgICAgICogJ2Nvb2tpZScgbXVzdCBiZSBOVUxMLCByZXN1bHRpbmcgaW4gdGhlIGZpcnN0IGNvb2tpZSBiZWluZyByZXR1cm5lZC4KKyAgICAgKiBFYWNoIG5leHQgY29va2llIHdpbGwgYmUgcmV0dXJuZWQgdGhlcmUtYWZ0ZXIsIHVudGlsIE5VTEwgaW5kaWNhdGluZworICAgICAqIHRoZSBlbmQgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKi8KKyAgICB2b2lkKiBuZXh0QXNzZXRQYXRoKHZvaWQqIGNvb2tpZSkgY29uc3Q7CisKKyAgICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICogUmV0dXJuIGFuIGFzc2V0IHBhdGggaW4gdGhlIG1hbmFnZXIuICAnd2hpY2gnIG11c3QgYmUgYmV0d2VlbiAwIGFuZAorICAgICAqIGNvdW50QXNzZXRQYXRocygpLgorICAgICAqLworICAgIFN0cmluZzggZ2V0QXNzZXRQYXRoKHZvaWQqIGNvb2tpZSkgY29uc3Q7CisKKyAgICAvKgorICAgICAqIFNldCB0aGUgY3VycmVudCBsb2NhbGUgYW5kIHZlbmRvci4gIFRoZSBsb2NhbGUgY2FuIGNoYW5nZSBkdXJpbmcKKyAgICAgKiB0aGUgbGlmZXRpbWUgb2YgYW4gQXNzZXRNYW5hZ2VyIGlmIHRoZSB1c2VyIHVwZGF0ZXMgdGhlIGRldmljZSdzCisgICAgICogbGFuZ3VhZ2Ugc2V0dGluZy4gIFRoZSB2ZW5kb3IgaXMgbGVzcyBsaWtlbHkgdG8gY2hhbmdlLgorICAgICAqCisgICAgICogUGFzcyBpbiBOVUxMIHRvIGluZGljYXRlIG5vIHByZWZlcmVuY2UuCisgICAgICovCisgICAgdm9pZCBzZXRMb2NhbGUoY29uc3QgY2hhciogbG9jYWxlKTsKKyAgICB2b2lkIHNldFZlbmRvcihjb25zdCBjaGFyKiB2ZW5kb3IpOworCisgICAgLyoKKyAgICAgKiBDaG9vc2Ugc2NyZWVuIG9yaWVudGF0aW9uIGZvciByZXNvdXJjZXMgdmFsdWVzIHJldHVybmVkLgorICAgICAqLworICAgIHZvaWQgc2V0Q29uZmlndXJhdGlvbihjb25zdCBSZXNUYWJsZV9jb25maWcmIGNvbmZpZywgY29uc3QgY2hhciogbG9jYWxlID0gTlVMTCk7CisKKyAgICB0eXBlZGVmIEFzc2V0OjpBY2Nlc3NNb2RlIEFjY2Vzc01vZGU7ICAgICAgIC8vIHR5cGluZyBzaG9ydGN1dAorCisgICAgLyoKKyAgICAgKiBPcGVuIGFuIGFzc2V0LgorICAgICAqCisgICAgICogVGhpcyB3aWxsIHNlYXJjaCB0aHJvdWdoIGxvY2FsZS1zcGVjaWZpYyBhbmQgdmVuZG9yLXNwZWNpZmljCisgICAgICogZGlyZWN0b3JpZXMgYW5kIHBhY2thZ2VzIHRvIGZpbmQgdGhlIGZpbGUuCisgICAgICoKKyAgICAgKiBUaGUgb2JqZWN0IHJldHVybmVkIGRvZXMgbm90IGRlcGVuZCBvbiB0aGUgQXNzZXRNYW5hZ2VyLiAgSXQgc2hvdWxkCisgICAgICogYmUgZnJlZWQgYnkgY2FsbGluZyBBc3NldDo6Y2xvc2UoKS4KKyAgICAgKi8KKyAgICBBc3NldCogb3Blbihjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKTsKKworICAgIC8qCisgICAgICogT3BlbiBhIG5vbi1hc3NldCBmaWxlIGFzIGFuIGFzc2V0LgorICAgICAqCisgICAgICogVGhpcyBpcyBmb3Igb3BlbmluZyBmaWxlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiBhbiBhc3NldCBwYWNrYWdlCisgICAgICogYnV0IGFyZW4ndCBhc3NldHMuICBUaGVzZSBzaXQgb3V0c2lkZSB0aGUgdXN1YWwgImxvY2FsZS92ZW5kb3IiCisgICAgICogcGF0aCBoaWVyYXJjaHksIGFuZCB3aWxsIG5vdCBiZSBzZWVuIGJ5ICJBc3NldERpciIgb3IgaW5jbHVkZWQKKyAgICAgKiBpbiBvdXIgZmlsZW5hbWUgY2FjaGUuCisgICAgICovCisgICAgQXNzZXQqIG9wZW5Ob25Bc3NldChjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKTsKKworICAgIC8qCisgICAgICogRXhwbGljaXQgbm9uLWFzc2V0IGZpbGUuICBUaGUgZmlsZSBleHBsaWNpdGx5IG5hbWVkIGJ5IHRoZSBjb29raWUgKHRoZQorICAgICAqIHJlc291cmNlIHNldCB0byBsb29rIGluKSBhbmQgZmlsZU5hbWUgd2lsbCBiZSBvcGVuZWQgYW5kIHJldHVybmVkLgorICAgICAqLworICAgIEFzc2V0KiBvcGVuTm9uQXNzZXQodm9pZCogY29va2llLCBjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKTsKKworICAgIC8qCisgICAgICogT3BlbiBhIGRpcmVjdG9yeSB3aXRoaW4gdGhlIGFzc2V0IGhpZXJhcmNoeS4KKyAgICAgKgorICAgICAqIFRoZSBjb250ZW50cyBvZiB0aGUgZGlyZWN0b3J5IGFyZSBhbiBhbWFsZ2FtIG9mIHZlbmRvci1zcGVjaWZpYywKKyAgICAgKiBsb2NhbGUtc3BlY2lmaWMsIGFuZCBnZW5lcmljIGFzc2V0cyBzdG9yZWQgbG9vc2VseSBvciBpbiBhc3NldAorICAgICAqIHBhY2thZ2VzLiAgRGVwZW5kaW5nIG9uIHRoZSBjYWNoZSBzZXR0aW5nIGFuZCBwcmV2aW91cyBhY2Nlc3NlcywKKyAgICAgKiB0aGlzIGNhbGwgbWF5IGluY3VyIHNpZ25pZmljYW50IGRpc2sgb3ZlcmhlYWQuCisgICAgICoKKyAgICAgKiBUbyBvcGVuIHRoZSB0b3AtbGV2ZWwgZGlyZWN0b3J5LCBwYXNzIGluICIiLgorICAgICAqLworICAgIEFzc2V0RGlyKiBvcGVuRGlyKGNvbnN0IGNoYXIqIGRpck5hbWUpOworCisgICAgLyoKKyAgICAgKiBHZXQgdGhlIHR5cGUgb2YgYSBmaWxlIGluIHRoZSBhc3NldCBoaWVyYXJjaHkuICBUaGV5IHdpbGwgZWl0aGVyCisgICAgICogYmUgInJlZ3VsYXIiIG9yICJkaXJlY3RvcnkiLiAgW0N1cnJlbnRseSBvbmx5IHdvcmtzIGZvciAicmVndWxhciIuXQorICAgICAqCisgICAgICogQ2FuIGFsc28gYmUgdXNlZCBhcyBhIHF1aWNrIHRlc3QgZm9yIGV4aXN0ZW5jZSBvZiBhIGZpbGUuCisgICAgICovCisgICAgRmlsZVR5cGUgZ2V0RmlsZVR5cGUoY29uc3QgY2hhciogZmlsZU5hbWUpOworCisgICAgLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAqIFJldHVybiB0aGUgY29tcGxldGUgcmVzb3VyY2UgdGFibGUgdG8gZmluZCB0aGluZ3MgaW4gdGhlIHBhY2thZ2UuCisgICAgICovCisgICAgY29uc3QgUmVzVGFibGUmIGdldFJlc291cmNlcyhib29sIHJlcXVpcmVkID0gdHJ1ZSkgY29uc3Q7CisKKyAgICAvKgorICAgICAqIERpc2NhcmQgY2FjaGVkIGZpbGVuYW1lIGluZm9ybWF0aW9uLiAgVGhpcyBvbmx5IG5lZWRzIHRvIGJlIGNhbGxlZAorICAgICAqIGlmIHNvbWVib2R5IGhhcyB1cGRhdGVkIHRoZSBzZXQgb2YgImxvb3NlIiBmaWxlcywgYW5kIHdlIHdhbnQgdG8KKyAgICAgKiBkaXNjYXJkIG91ciBjYWNoZWQgbm90aW9uIG9mIHdoYXQncyB3aGVyZS4KKyAgICAgKi8KKyAgICB2b2lkIHB1cmdlKHZvaWQpIHsgcHVyZ2VGaWxlTmFtZUNhY2hlTG9ja2VkKCk7IH0KKworICAgIC8qCisgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGZpbGVzIHRoaXMgQXNzZXRNYW5hZ2VyIHJlZmVyZW5jZXMgYXJlIGFsbAorICAgICAqIHVwLXRvLWRhdGUgKGhhdmUgbm90IGJlZW4gY2hhbmdlZCBzaW5jZSBpdCB3YXMgY3JlYXRlZCkuICBJZiBmYWxzZQorICAgICAqIGlzIHJldHVybmVkLCB5b3Ugd2lsbCBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBBc3NldE1hbmFnZXIgdG8gZ2V0CisgICAgICogdGhlIGN1cnJlbnQgZGF0YS4KKyAgICAgKi8KKyAgICBib29sIGlzVXBUb0RhdGUoKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGtub3duIGxvY2FsZXMgZm9yIHRoaXMgYXNzZXQgbWFuYWdlciBvYmplY3QuCisgICAgICovCisgICAgdm9pZCBnZXRMb2NhbGVzKFZlY3RvcjxTdHJpbmc4PiogbG9jYWxlcykgY29uc3Q7CisKK3ByaXZhdGU6CisgICAgc3RydWN0IGFzc2V0X3BhdGgKKyAgICB7CisgICAgICAgIFN0cmluZzggcGF0aDsKKyAgICAgICAgRmlsZVR5cGUgdHlwZTsKKyAgICB9OworCisgICAgQXNzZXQqIG9wZW5JblBhdGhMb2NrZWQoY29uc3QgY2hhciogZmlsZU5hbWUsIEFjY2Vzc01vZGUgbW9kZSwKKyAgICAgICAgY29uc3QgYXNzZXRfcGF0aCYgcGF0aCk7CisgICAgQXNzZXQqIG9wZW5Ob25Bc3NldEluUGF0aExvY2tlZChjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlLAorICAgICAgICBjb25zdCBhc3NldF9wYXRoJiBwYXRoKTsKKyAgICBBc3NldCogb3BlbkluTG9jYWxlVmVuZG9yTG9ja2VkKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBBY2Nlc3NNb2RlIG1vZGUsCisgICAgICAgIGNvbnN0IGFzc2V0X3BhdGgmIHBhdGgsIGNvbnN0IGNoYXIqIGxvY2FsZSwgY29uc3QgY2hhciogdmVuZG9yKTsKKyAgICBTdHJpbmc4IGNyZWF0ZVBhdGhOYW1lTG9ja2VkKGNvbnN0IGFzc2V0X3BhdGgmIHBhdGgsIGNvbnN0IGNoYXIqIGxvY2FsZSwKKyAgICAgICAgY29uc3QgY2hhciogdmVuZG9yKTsKKyAgICBTdHJpbmc4IGNyZWF0ZVBhdGhOYW1lTG9ja2VkKGNvbnN0IGFzc2V0X3BhdGgmIHBhdGgsIGNvbnN0IGNoYXIqIHJvb3REaXIpOworICAgIFN0cmluZzggY3JlYXRlWmlwU291cmNlTmFtZUxvY2tlZChjb25zdCBTdHJpbmc4JiB6aXBGaWxlTmFtZSwKKyAgICAgICAgY29uc3QgU3RyaW5nOCYgZGlyTmFtZSwgY29uc3QgU3RyaW5nOCYgZmlsZU5hbWUpOworCisgICAgWmlwRmlsZVJPKiBnZXRaaXBGaWxlTG9ja2VkKGNvbnN0IGFzc2V0X3BhdGgmIHBhdGgpOworICAgIEFzc2V0KiBvcGVuQXNzZXRGcm9tRmlsZUxvY2tlZChjb25zdCBTdHJpbmc4JiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKTsKKyAgICBBc3NldCogb3BlbkFzc2V0RnJvbVppcExvY2tlZChjb25zdCBaaXBGaWxlUk8qIHBaaXBGaWxlLAorICAgICAgICBjb25zdCBaaXBFbnRyeVJPIGVudHJ5LCBBY2Nlc3NNb2RlIG1vZGUsIGNvbnN0IFN0cmluZzgmIGVudHJ5TmFtZSk7CisKKyAgICBib29sIHNjYW5BbmRNZXJnZURpckxvY2tlZChTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcE1lcmdlZEluZm8sCisgICAgICAgIGNvbnN0IGFzc2V0X3BhdGgmIHBhdGgsIGNvbnN0IGNoYXIqIHJvb3REaXIsIGNvbnN0IGNoYXIqIGRpck5hbWUpOworICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBzY2FuRGlyTG9ja2VkKGNvbnN0IFN0cmluZzgmIHBhdGgpOworICAgIGJvb2wgc2NhbkFuZE1lcmdlWmlwTG9ja2VkKFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbywKKyAgICAgICAgY29uc3QgYXNzZXRfcGF0aCYgcGF0aCwgY29uc3QgY2hhciogcm9vdERpciwgY29uc3QgY2hhciogZGlyTmFtZSk7CisgICAgdm9pZCBtZXJnZUluZm9Mb2NrZWQoU29ydGVkVmVjdG9yPEFzc2V0RGlyOjpGaWxlSW5mbz4qIHBNZXJnZWRJbmZvLAorICAgICAgICBjb25zdCBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcENvbnRlbnRzKTsKKworICAgIHZvaWQgbG9hZEZpbGVOYW1lQ2FjaGVMb2NrZWQodm9pZCk7CisgICAgdm9pZCBmbmNTY2FuTG9ja2VkKFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbywKKyAgICAgICAgY29uc3QgY2hhciogZGlyTmFtZSk7CisgICAgYm9vbCBmbmNTY2FuQW5kTWVyZ2VEaXJMb2NrZWQoCisgICAgICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbywKKyAgICAgICAgY29uc3QgYXNzZXRfcGF0aCYgcGF0aCwgY29uc3QgY2hhciogbG9jYWxlLCBjb25zdCBjaGFyKiB2ZW5kb3IsCisgICAgICAgIGNvbnN0IGNoYXIqIGRpck5hbWUpOworICAgIHZvaWQgcHVyZ2VGaWxlTmFtZUNhY2hlTG9ja2VkKHZvaWQpOworCisgICAgY29uc3QgUmVzVGFibGUqIGdldFJlc1RhYmxlKGJvb2wgcmVxdWlyZWQgPSB0cnVlKSBjb25zdDsKKyAgICB2b2lkIHNldExvY2FsZUxvY2tlZChjb25zdCBjaGFyKiBsb2NhbGUpOworICAgIHZvaWQgdXBkYXRlUmVzb3VyY2VQYXJhbXNMb2NrZWQoKSBjb25zdDsKKworICAgIGNsYXNzIFNoYXJlZFppcCA6IHB1YmxpYyBSZWZCYXNlIHsKKyAgICBwdWJsaWM6CisgICAgICAgIHN0YXRpYyBzcDxTaGFyZWRaaXA+IGdldChjb25zdCBTdHJpbmc4JiBwYXRoKTsKKworICAgICAgICBaaXBGaWxlUk8qIGdldFppcCgpOworCisgICAgICAgIEFzc2V0KiBnZXRSZXNvdXJjZVRhYmxlQXNzZXQoKTsKKyAgICAgICAgQXNzZXQqIHNldFJlc291cmNlVGFibGVBc3NldChBc3NldCogYXNzZXQpOworCisgICAgICAgIGJvb2wgaXNVcFRvRGF0ZSgpOworICAgICAgICAKKyAgICBwcm90ZWN0ZWQ6CisgICAgICAgIH5TaGFyZWRaaXAoKTsKKworICAgIHByaXZhdGU6CisgICAgICAgIFNoYXJlZFppcChjb25zdCBTdHJpbmc4JiBwYXRoLCB0aW1lX3QgbW9kV2hlbik7CisgICAgICAgIFNoYXJlZFppcCgpOyAvLyA8LS0gbm90IGltcGxlbWVudGVkCisKKyAgICAgICAgU3RyaW5nOCBtUGF0aDsKKyAgICAgICAgWmlwRmlsZVJPKiBtWmlwRmlsZTsKKyAgICAgICAgdGltZV90IG1Nb2RXaGVuOworCisgICAgICAgIEFzc2V0KiBtUmVzb3VyY2VUYWJsZUFzc2V0OworCisgICAgICAgIHN0YXRpYyBNdXRleCBnTG9jazsKKyAgICAgICAgc3RhdGljIERlZmF1bHRLZXllZFZlY3RvcjxTdHJpbmc4LCB3cDxTaGFyZWRaaXA+ID4gZ09wZW47CisgICAgfTsKKworICAgIC8qCisgICAgICogTWFuYWdlIGEgc2V0IG9mIFppcCBmaWxlcy4gIEZvciBlYWNoIGZpbGUgd2UgbmVlZCBhIHBvaW50ZXIgdG8gdGhlCisgICAgICogWmlwRmlsZSBhbmQgYSB0aW1lX3Qgd2l0aCB0aGUgZmlsZSdzIG1vZGlmaWNhdGlvbiBkYXRlLgorICAgICAqCisgICAgICogV2UgY3VycmVudGx5IG9ubHkgaGF2ZSB0d28gemlwIGZpbGVzIChjdXJyZW50IGFwcCwgImNvbW1vbiIgYXBwKS4KKyAgICAgKiAoVGhpcyB3YXMgb3JpZ2luYWxseSB3cml0dGVuIGZvciA4LCBiYXNlZCBvbiBhcHAvbG9jYWxlL3ZlbmRvci4pCisgICAgICovCisgICAgY2xhc3MgWmlwU2V0IHsKKyAgICBwdWJsaWM6CisgICAgICAgIFppcFNldCh2b2lkKTsKKyAgICAgICAgflppcFNldCh2b2lkKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBSZXR1cm4gYSBaaXBGaWxlUk8gc3RydWN0dXJlIGZvciBhIFppcEZpbGVSTyB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogcGFyYW1ldGVycy4KKyAgICAgICAgICovCisgICAgICAgIFppcEZpbGVSTyogZ2V0WmlwKGNvbnN0IFN0cmluZzgmIHBhdGgpOworCisgICAgICAgIEFzc2V0KiBnZXRaaXBSZXNvdXJjZVRhYmxlKGNvbnN0IFN0cmluZzgmIHBhdGgpOworICAgICAgICBBc3NldCogc2V0WmlwUmVzb3VyY2VUYWJsZShjb25zdCBTdHJpbmc4JiBwYXRoLCBBc3NldCogYXNzZXQpOworCisgICAgICAgIC8vIGdlbmVyYXRlIHBhdGgsIGUuZy4gImNvbW1vbi9lbi1VUy1ub29nbGUuemlwIgorICAgICAgICBzdGF0aWMgU3RyaW5nOCBnZXRQYXRoTmFtZShjb25zdCBjaGFyKiBwYXRoKTsKKworICAgICAgICBib29sIGlzVXBUb0RhdGUoKTsKKyAgICAgICAgCisgICAgcHJpdmF0ZToKKyAgICAgICAgdm9pZCBjbG9zZVppcChpbnQgaWR4KTsKKworICAgICAgICBpbnQgZ2V0SW5kZXgoY29uc3QgU3RyaW5nOCYgemlwKSBjb25zdDsKKyAgICAgICAgbXV0YWJsZSBWZWN0b3I8U3RyaW5nOD4gbVppcFBhdGg7CisgICAgICAgIG11dGFibGUgVmVjdG9yPHNwPFNoYXJlZFppcD4gPiBtWmlwRmlsZTsKKyAgICB9OworCisgICAgLy8gUHJvdGVjdCBhbGwgaW50ZXJuYWwgc3RhdGUuCisgICAgbXV0YWJsZSBNdXRleCAgIG1Mb2NrOworCisgICAgWmlwU2V0ICAgICAgICAgIG1aaXBTZXQ7CisKKyAgICBWZWN0b3I8YXNzZXRfcGF0aD4gbUFzc2V0UGF0aHM7CisgICAgY2hhciogICAgICAgICAgIG1Mb2NhbGU7CisgICAgY2hhciogICAgICAgICAgIG1WZW5kb3I7CisKKyAgICBtdXRhYmxlIFJlc1RhYmxlKiBtUmVzb3VyY2VzOworICAgIFJlc1RhYmxlX2NvbmZpZyogbUNvbmZpZzsKKworICAgIC8qCisgICAgICogQ2FjaGVkIGRhdGEgZm9yICJsb29zZSIgZmlsZXMuICBUaGlzIGxldHMgdXMgYXZvaWQgcG9raW5nIGF0IHRoZQorICAgICAqIGZpbGVzeXN0ZW0gd2hlbiBzZWFyY2hpbmcgZm9yIGxvb3NlIGFzc2V0cy4gIEVhY2ggZW50cnkgaXMgdGhlCisgICAgICogImV4dGVuZGVkIHBhcnRpYWwiIHBhdGgsIGUuZy4gImRlZmF1bHQvZGVmYXVsdC9mb28vYmFyLnR4dCIuICBUaGUKKyAgICAgKiBmdWxsIHNldCBvZiBmaWxlcyBpcyBwcmVzZW50LCBpbmNsdWRpbmcgIi5FWENMVURFIiBlbnRyaWVzLgorICAgICAqCisgICAgICogV2UgZG8gbm90IGNhY2hlIGRpcmVjdG9yeSBuYW1lcy4gIFdlIGRvbid0IHJldGFpbiB0aGUgIi5neiIsCisgICAgICogYmVjYXVzZSB0byBvdXIgY2xpZW50cyAiZm9vIiBhbmQgImZvby5neiIgYm90aCBsb29rIGxpa2UgImZvbyIuCisgICAgICovCisgICAgQ2FjaGVNb2RlICAgICAgIG1DYWNoZU1vZGU7ICAgICAgICAgLy8gaXMgdGhlIGNhY2hlIGVuYWJsZWQ/CisgICAgYm9vbCAgICAgICAgICAgIG1DYWNoZVZhbGlkOyAgICAgICAgLy8gY2xlYXIgd2hlbiBsb2NhbGUgb3IgdmVuZG9yIGNoYW5nZXMKKyAgICBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiBtQ2FjaGU7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gX19MSUJTX0FTU0VUTUFOQUdFUl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0F0b21pYy5oIGIvaW5jbHVkZS91dGlscy9BdG9taWMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWI0NzZjCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9BdG9taWMuaApAQCAtMCwwICsxLDIyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1VUSUxTX0FUT01JQ19ICisjZGVmaW5lIEFORFJPSURfVVRJTFNfQVRPTUlDX0gKKworI2luY2x1ZGUgPGN1dGlscy9hdG9taWMuaD4KKworI2VuZGlmIC8vIEFORFJPSURfVVRJTFNfQVRPTUlDX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvQmluZGVyLmggYi9pbmNsdWRlL3V0aWxzL0JpbmRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1YjhkOTgKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0JpbmRlci5oCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0JJTkRFUl9ICisjZGVmaW5lIEFORFJPSURfQklOREVSX0gKKworI2luY2x1ZGUgPHV0aWxzL0lCaW5kZXIuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEJCaW5kZXIgOiBwdWJsaWMgSUJpbmRlcgoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgQkJpbmRlcigpOworCisgICAgdmlydHVhbCBTdHJpbmcxNiAgICBnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkgY29uc3Q7CisgICAgdmlydHVhbCBib29sICAgICAgICBpc0JpbmRlckFsaXZlKCkgY29uc3Q7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBwaW5nQmluZGVyKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHRyYW5zYWN0KCAgIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgbGlua1RvRGVhdGgoY29uc3Qgc3A8RGVhdGhSZWNpcGllbnQ+JiByZWNpcGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBjb29raWUgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgdW5saW5rVG9EZWF0aCggIGNvbnN0IHdwPERlYXRoUmVjaXBpZW50PiYgcmVjaXBpZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGNvb2tpZSA9IE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdwPERlYXRoUmVjaXBpZW50Piogb3V0UmVjaXBpZW50ID0gTlVMTCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGF0dGFjaE9iamVjdCggICBjb25zdCB2b2lkKiBvYmplY3RJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBvYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY2xlYW51cENvb2tpZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RfY2xlYW51cF9mdW5jIGZ1bmMpOworICAgIHZpcnR1YWwgdm9pZCogICAgICAgZmluZE9iamVjdChjb25zdCB2b2lkKiBvYmplY3RJRCkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBkZXRhY2hPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpOworCisgICAgdmlydHVhbCBCQmluZGVyKiAgICBsb2NhbEJpbmRlcigpOworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCAgICAgICAgICAgICB+QkJpbmRlcigpOworCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBvblRyYW5zYWN0KCB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCk7CisKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICBCQmluZGVyKGNvbnN0IEJCaW5kZXImIG8pOworICAgICAgICAgICAgQkJpbmRlciYgICAgb3BlcmF0b3I9KGNvbnN0IEJCaW5kZXImIG8pOworCisgICAgY2xhc3MgRXh0cmFzOworCisgICAgICAgICAgICBFeHRyYXMqICAgICBtRXh0cmFzOworICAgICAgICAgICAgdm9pZCogICAgICAgbVJlc2VydmVkMDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCcFJlZkJhc2UgOiBwdWJsaWMgdmlydHVhbCBSZWZCYXNlCit7Citwcm90ZWN0ZWQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnBSZWZCYXNlKGNvbnN0IHNwPElCaW5kZXI+JiBvKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgICAgICB+QnBSZWZCYXNlKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgb25GaXJzdFJlZigpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIG9uTGFzdFN0cm9uZ1JlZihjb25zdCB2b2lkKiBpZCk7CisgICAgdmlydHVhbCBib29sICAgICAgICAgICAgb25JbmNTdHJvbmdBdHRlbXB0ZWQodWludDMyX3QgZmxhZ3MsIGNvbnN0IHZvaWQqIGlkKTsKKworICAgIGlubGluZSAgSUJpbmRlciogICAgICAgIHJlbW90ZSgpICAgICAgICAgICAgICAgIHsgcmV0dXJuIG1SZW1vdGU7IH0KKyAgICBpbmxpbmUgIElCaW5kZXIqICAgICAgICByZW1vdGUoKSBjb25zdCAgICAgICAgICB7IHJldHVybiBtUmVtb3RlOyB9CisKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnBSZWZCYXNlKGNvbnN0IEJwUmVmQmFzZSYgbyk7CisgICAgQnBSZWZCYXNlJiAgICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IEJwUmVmQmFzZSYgbyk7CisKKyAgICBJQmluZGVyKiBjb25zdCAgICAgICAgICBtUmVtb3RlOworICAgIFJlZkJhc2U6OndlYWtyZWZfdHlwZSogIG1SZWZzOworICAgIHZvbGF0aWxlIGludDMyX3QgICAgICAgIG1TdGF0ZTsKK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9CSU5ERVJfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9CcEJpbmRlci5oIGIvaW5jbHVkZS91dGlscy9CcEJpbmRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiOTZlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0JwQmluZGVyLmgKQEAgLTAsMCArMSwxMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQlBCSU5ERVJfSAorI2RlZmluZSBBTkRST0lEX0JQQklOREVSX0gKKworI2luY2x1ZGUgPHV0aWxzL0lCaW5kZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9LZXllZFZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEJwQmluZGVyIDogcHVibGljIElCaW5kZXIKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgIEJwQmluZGVyKGludDMyX3QgaGFuZGxlKTsKKworICAgIGlubGluZSAgaW50MzJfdCAgICAgaGFuZGxlKCkgY29uc3QgeyByZXR1cm4gbUhhbmRsZTsgfQorCisgICAgdmlydHVhbCBTdHJpbmcxNiAgICBnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkgY29uc3Q7CisgICAgdmlydHVhbCBib29sICAgICAgICBpc0JpbmRlckFsaXZlKCkgY29uc3Q7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBwaW5nQmluZGVyKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHRyYW5zYWN0KCAgIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgbGlua1RvRGVhdGgoY29uc3Qgc3A8RGVhdGhSZWNpcGllbnQ+JiByZWNpcGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBjb29raWUgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHVubGlua1RvRGVhdGgoICBjb25zdCB3cDxEZWF0aFJlY2lwaWVudD4mIHJlY2lwaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBjb29raWUgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cDxEZWF0aFJlY2lwaWVudD4qIG91dFJlY2lwaWVudCA9IE5VTEwpOworCisgICAgdmlydHVhbCB2b2lkICAgICAgICBhdHRhY2hPYmplY3QoICAgY29uc3Qgdm9pZCogb2JqZWN0SUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogb2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGNsZWFudXBDb29raWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0X2NsZWFudXBfZnVuYyBmdW5jKTsKKyAgICB2aXJ0dWFsIHZvaWQqICAgICAgIGZpbmRPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpIGNvbnN0OworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgZGV0YWNoT2JqZWN0KGNvbnN0IHZvaWQqIG9iamVjdElEKTsKKworICAgIHZpcnR1YWwgQnBCaW5kZXIqICAgcmVtb3RlQmluZGVyKCk7CisKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHNldENvbnN0YW50RGF0YShjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSk7CisgICAgICAgICAgICB2b2lkICAgICAgICBzZW5kT2JpdHVhcnkoKTsKKworICAgIGNsYXNzIE9iamVjdE1hbmFnZXIKKyAgICB7CisgICAgcHVibGljOgorICAgICAgICAgICAgICAgICAgICBPYmplY3RNYW5hZ2VyKCk7CisgICAgICAgICAgICAgICAgICAgIH5PYmplY3RNYW5hZ2VyKCk7CisKKyAgICAgICAgdm9pZCAgICAgICAgYXR0YWNoKCBjb25zdCB2b2lkKiBvYmplY3RJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBvYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY2xlYW51cENvb2tpZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQmluZGVyOjpvYmplY3RfY2xlYW51cF9mdW5jIGZ1bmMpOworICAgICAgICB2b2lkKiAgICAgICBmaW5kKGNvbnN0IHZvaWQqIG9iamVjdElEKSBjb25zdDsKKyAgICAgICAgdm9pZCAgICAgICAgZGV0YWNoKGNvbnN0IHZvaWQqIG9iamVjdElEKTsKKworICAgICAgICB2b2lkICAgICAgICBraWxsKCk7CisKKyAgICBwcml2YXRlOgorICAgICAgICAgICAgICAgICAgICBPYmplY3RNYW5hZ2VyKGNvbnN0IE9iamVjdE1hbmFnZXImKTsKKyAgICAgICAgT2JqZWN0TWFuYWdlciYgb3BlcmF0b3I9KGNvbnN0IE9iamVjdE1hbmFnZXImKTsKKworICAgICAgICBzdHJ1Y3QgZW50cnlfdAorICAgICAgICB7CisgICAgICAgICAgICB2b2lkKiBvYmplY3Q7CisgICAgICAgICAgICB2b2lkKiBjbGVhbnVwQ29va2llOworICAgICAgICAgICAgSUJpbmRlcjo6b2JqZWN0X2NsZWFudXBfZnVuYyBmdW5jOworICAgICAgICB9OworCisgICAgICAgIEtleWVkVmVjdG9yPGNvbnN0IHZvaWQqLCBlbnRyeV90PiBtT2JqZWN0czsKKyAgICB9OworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCAgICAgICAgICAgICB+QnBCaW5kZXIoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIG9uRmlyc3RSZWYoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIG9uTGFzdFN0cm9uZ1JlZihjb25zdCB2b2lkKiBpZCk7CisgICAgdmlydHVhbCBib29sICAgICAgICBvbkluY1N0cm9uZ0F0dGVtcHRlZCh1aW50MzJfdCBmbGFncywgY29uc3Qgdm9pZCogaWQpOworCitwcml2YXRlOgorICAgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBtSGFuZGxlOworCisgICAgc3RydWN0IE9iaXR1YXJ5IHsKKyAgICAgICAgd3A8RGVhdGhSZWNpcGllbnQ+IHJlY2lwaWVudDsKKyAgICAgICAgdm9pZCogY29va2llOworICAgICAgICB1aW50MzJfdCBmbGFnczsKKyAgICB9OworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHJlcG9ydE9uZURlYXRoKGNvbnN0IE9iaXR1YXJ5JiBvYml0KTsKKworICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICBtTG9jazsKKyAgICAgICAgICAgIHZvbGF0aWxlIGludDMyX3QgICAgbUFsaXZlOworICAgICAgICAgICAgdm9sYXRpbGUgaW50MzJfdCAgICBtT2JpdHNTZW50OworICAgICAgICAgICAgVmVjdG9yPE9iaXR1YXJ5PiogICBtT2JpdHVhcmllczsKKyAgICAgICAgICAgIE9iamVjdE1hbmFnZXIgICAgICAgbU9iamVjdHM7CisgICAgICAgICAgICBQYXJjZWwqICAgICAgICAgICAgIG1Db25zdGFudERhdGE7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfQlBCSU5ERVJfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9CdWZmZXIuaCBiL2luY2x1ZGUvdXRpbHMvQnVmZmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUyMmIwZgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvQnVmZmVyLmgKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIF9fVVRJTFNfQlVGRkVSX0hfXworI2RlZmluZSBfX1VUSUxTX0JVRkZFUl9IX18gMQorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBCdWZmZXIKK3sKK3ByaXZhdGU6CisgICAgY2hhciAqYnVmOworICAgIGludCBidWZzaXo7CisgICAgaW50IHVzZWQ7CisgICAgdm9pZCBlbnN1cmVDYXBhY2l0eShpbnQgbGVuKTsKKworICAgIHZvaWQKKyAgICBtYWtlUm9vbUZvcihpbnQgbGVuKQorICAgIHsKKyAgICAgICAgaWYgKGxlbiArIHVzZWQgPj0gYnVmc2l6KSB7CisgICAgICAgICAgICBidWZzaXogPSAobGVuICsgdXNlZCkgKiAzLzIgKyAyOworICAgICAgICAgICAgY2hhciAqYmxhaCA9IG5ldyBjaGFyW2J1ZnNpel07CisKKyAgICAgICAgICAgIG1lbWNweShibGFoLCBidWYsIHVzZWQpOworICAgICAgICAgICAgZGVsZXRlW10gYnVmOworICAgICAgICAgICAgYnVmID0gYmxhaDsKKyAgICAgICAgfQorICAgIH0KKyAgICAKK3B1YmxpYzoKKyAgICBCdWZmZXIoKQorICAgIHsKKyAgICAgICAgYnVmc2l6ID0gMTY7CisgICAgICAgIGJ1ZiA9IG5ldyBjaGFyW2J1ZnNpel07CisgICAgICAgIGNsZWFyKCk7CisgICAgfQorCisgICAgfkJ1ZmZlcigpCisgICAgeworICAgICAgIGRlbGV0ZVtdIGJ1ZjsKKyAgICB9CisKKyAgICB2b2lkCisgICAgY2xlYXIoKQorICAgIHsKKyAgICAgICAgYnVmWzBdID0gJ1wwJzsKKyAgICAgICAgdXNlZCA9IDA7CisgICAgfQorCisgICAgaW50CisgICAgbGVuZ3RoKCkKKyAgICB7CisgICAgICAgIHJldHVybiB1c2VkOworICAgIH0KKworICAgIHZvaWQKKyAgICBhcHBlbmQoY29uc3QgY2hhciBjKQorICAgIHsKKyAgICAgICAgbWFrZVJvb21Gb3IoMSk7CisgICAgICAgIGJ1Zlt1c2VkXSA9IGM7CisgICAgICAgIHVzZWQrKzsKKyAgICAgICAgYnVmW3VzZWRdID0gJ1wwJzsKKyAgICB9CisKKyAgICB2b2lkCisgICAgYXBwZW5kKGNvbnN0IGNoYXIgKnMsIGludCBsZW4pCisgICAgeworICAgICAgICBtYWtlUm9vbUZvcihsZW4pOworCisgICAgICAgIG1lbWNweShidWYgKyB1c2VkLCBzLCBsZW4pOworICAgICAgICB1c2VkICs9IGxlbjsKKyAgICAgICAgYnVmW3VzZWRdID0gJ1wwJzsKKyAgICB9CisKKyAgICB2b2lkCisgICAgYXBwZW5kKGNvbnN0IGNoYXIgKnMpCisgICAgeworICAgICAgICBhcHBlbmQocywgc3RybGVuKHMpKTsKKyAgICB9CisKKyAgICBjaGFyICoKKyAgICBnZXRCeXRlcygpCisgICAgeworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KK307CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9CdWZmZXJlZFRleHRPdXRwdXQuaCBiL2luY2x1ZGUvdXRpbHMvQnVmZmVyZWRUZXh0T3V0cHV0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjljNjI0MAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvQnVmZmVyZWRUZXh0T3V0cHV0LmgKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9CVUZGRVJFRFRFWFRPVVRQVVRfSAorI2RlZmluZSBBTkRST0lEX0JVRkZFUkVEVEVYVE9VVFBVVF9ICisKKyNpbmNsdWRlIDx1dGlscy9UZXh0T3V0cHV0Lmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPGN1dGlscy91aW8uaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEJ1ZmZlcmVkVGV4dE91dHB1dCA6IHB1YmxpYyBUZXh0T3V0cHV0Cit7CitwdWJsaWM6CisgICAgLy8qKiBGbGFncyBmb3IgY29uc3RydWN0b3IgKi8KKyAgICBlbnVtIHsKKyAgICAgICAgTVVMVElUSFJFQURFRCA9IDB4MDAwMQorICAgIH07CisgICAgCisgICAgICAgICAgICAgICAgICAgICAgICBCdWZmZXJlZFRleHRPdXRwdXQodWludDMyX3QgZmxhZ3MgPSAwKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5CdWZmZXJlZFRleHRPdXRwdXQoKTsKKyAgICAKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHByaW50KGNvbnN0IGNoYXIqIHR4dCwgc2l6ZV90IGxlbik7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBtb3ZlSW5kZW50KGludCBkZWx0YSk7CisgICAgCisgICAgdmlydHVhbCB2b2lkICAgICAgICBwdXNoQnVuZGxlKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBwb3BCdW5kbGUoKTsKKyAgICAKK3Byb3RlY3RlZDoKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHdyaXRlTGluZXMoY29uc3Qgc3RydWN0IGlvdmVjJiB2ZWMsIHNpemVfdCBOKSA9IDA7CisKK3ByaXZhdGU6CisgICAgc3RydWN0IEJ1ZmZlclN0YXRlOworICAgIHN0cnVjdCBUaHJlYWRTdGF0ZTsKKyAgICAKKyAgICBzdGF0aWMgIFRocmVhZFN0YXRlKmdldFRocmVhZFN0YXRlKCk7CisgICAgc3RhdGljICB2b2lkICAgICAgICB0aHJlYWREZXN0cnVjdG9yKHZvaWQgKnN0KTsKKyAgICAKKyAgICAgICAgICAgIEJ1ZmZlclN0YXRlKmdldEJ1ZmZlcigpIGNvbnN0OworICAgICAgICAgICAgCisgICAgdWludDMyX3QgICAgICAgICAgICBtRmxhZ3M7CisgICAgY29uc3QgaW50MzJfdCAgICAgICBtU2VxOworICAgIGNvbnN0IGludDMyX3QgICAgICAgbUluZGV4OworICAgIAorICAgIE11dGV4ICAgICAgICAgICAgICAgbUxvY2s7CisgICAgQnVmZmVyU3RhdGUqICAgICAgICBtR2xvYmFsU3RhdGU7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0JVRkZFUkVEVEVYVE9VVFBVVF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0J5dGVPcmRlci5oIGIvaW5jbHVkZS91dGlscy9CeXRlT3JkZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzA2MDY3Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9CeXRlT3JkZXIuaApAQCAtMCwwICsxLDY5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKworI2lmbmRlZiBfTElCU19VVElMU19CWVRFX09SREVSX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfQllURV9PUkRFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpZmRlZiBIQVZFX1dJTlNPQ0sKKyNpbmNsdWRlIDx3aW5zb2NrMi5oPgorI2Vsc2UKKyNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CisjZW5kaWYKKworLyoKKyAqIFRoZXNlIG1hY3JvcyBhcmUgbGlrZSB0aGUgaHRvbi9udG9oIGJ5dGUgc3dhcHBpbmcgbWFjcm9zLAorICogZXhjZXB0IHRoZXkgYWxsb3cgeW91IHRvIHN3YXAgdG8gYW5kIGZyb20gdGhlICJkZXZpY2UiIGJ5dGUKKyAqIG9yZGVyLiAgVGhlIGRldmljZSBieXRlIG9yZGVyIGlzIHRoZSBlbmRpYW5uZXNzIG9mIHRoZSB0YXJnZXQKKyAqIGRldmljZSAtLSBmb3IgdGhlIEFSTSBDUFVzIHdlIHVzZSB0b2RheSwgdGhpcyBpcyBsaXR0bGUgZW5kaWFuLgorICoKKyAqIE5vdGUgdGhhdCB0aGUgYnl0ZSBzd2FwcGluZyBmdW5jdGlvbnMgaGF2ZSBub3QgYmVlbiBvcHRpbWl6ZWQKKyAqIG11Y2g7IHBlcmZvcm1hbmNlIGlzIGN1cnJlbnRseSBub3QgYW4gaXNzdWUgZm9yIHRoZW0gc2luY2UgdGhlCisgKiBpbnRlbnQgaXMgdG8gYWxsb3cgdXMgdG8gYXZvaWQgYnl0ZSBzd2FwcGluZyBvbiB0aGUgZGV2aWNlLgorICovCisKKyNkZWZpbmUgREVWSUNFX0JZVEVfT1JERVIgTElUVExFX0VORElBTgorCisjaWYgQllURV9PUkRFUiA9PSBERVZJQ0VfQllURV9PUkRFUgorCisjZGVmaW5lCWR0b2hsKHgpCSh4KQorI2RlZmluZQlkdG9ocyh4KQkoeCkKKyNkZWZpbmUJaHRvZGwoeCkJKHgpCisjZGVmaW5lCWh0b2RzKHgpCSh4KQorCisjZWxzZQorCitzdGF0aWMgaW5saW5lIHVpbnQzMl90IGFuZHJvaWRfc3dhcF9sb25nKHVpbnQzMl90IHYpCit7CisgICAgcmV0dXJuICh2PDwyNCkgfCAoKHY8PDgpJjB4MDBGRjAwMDApIHwgKCh2Pj44KSYweDAwMDBGRjAwKSB8ICh2Pj4yNCk7Cit9CisKK3N0YXRpYyBpbmxpbmUgdWludDE2X3QgYW5kcm9pZF9zd2FwX3Nob3J0KHVpbnQxNl90IHYpCit7CisgICAgcmV0dXJuICh2PDw4KSB8ICh2Pj44KTsKK30KKworI2RlZmluZQlkdG9obCh4KQkoYW5kcm9pZF9zd2FwX2xvbmcoeCkpCisjZGVmaW5lCWR0b2hzKHgpCShhbmRyb2lkX3N3YXBfc2hvcnQoeCkpCisjZGVmaW5lCWh0b2RsKHgpCShhbmRyb2lkX3N3YXBfbG9uZyh4KSkKKyNkZWZpbmUJaHRvZHMoeCkJKGFuZHJvaWRfc3dhcF9zaG9ydCh4KSkKKworI2VuZGlmCisKKyNlbmRpZiAvLyBfTElCU19VVElMU19CWVRFX09SREVSX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvQ2FsbFN0YWNrLmggYi9pbmNsdWRlL3V0aWxzL0NhbGxTdGFjay5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyYzhjZTUKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0NhbGxTdGFjay5oCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQ0FMTFNUQUNLX0gKKyNkZWZpbmUgQU5EUk9JRF9DQUxMU1RBQ0tfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIENhbGxTdGFjaworeworcHVibGljOgorICAgIGVudW0geworICAgICAgICBNQVhfREVQVEggPSAzMQorICAgIH07CisKKyAgICBDYWxsU3RhY2soKTsKKyAgICBDYWxsU3RhY2soY29uc3QgQ2FsbFN0YWNrJiByaHMpOworICAgIH5DYWxsU3RhY2soKTsKKworICAgIENhbGxTdGFjayYgb3BlcmF0b3IgPSAoY29uc3QgQ2FsbFN0YWNrJiByaHMpOworICAgIAorICAgIGJvb2wgb3BlcmF0b3IgPT0gKGNvbnN0IENhbGxTdGFjayYgcmhzKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yICE9IChjb25zdCBDYWxsU3RhY2smIHJocykgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciA8IChjb25zdCBDYWxsU3RhY2smIHJocykgY29uc3Q7CisgICAgYm9vbCBvcGVyYXRvciA+PSAoY29uc3QgQ2FsbFN0YWNrJiByaHMpIGNvbnN0OworICAgIGJvb2wgb3BlcmF0b3IgPiAoY29uc3QgQ2FsbFN0YWNrJiByaHMpIGNvbnN0OworICAgIGJvb2wgb3BlcmF0b3IgPD0gKGNvbnN0IENhbGxTdGFjayYgcmhzKSBjb25zdDsKKyAgICAKKyAgICBjb25zdCB2b2lkKiBvcGVyYXRvciBbXSAoaW50IGluZGV4KSBjb25zdDsKKyAgICAKKyAgICB2b2lkIGNsZWFyKCk7CisKKyAgICB2b2lkIHVwZGF0ZShpbnQzMl90IGlnbm9yZURlcHRoPTAsIGludDMyX3QgbWF4RGVwdGg9TUFYX0RFUFRIKTsKKworICAgIC8vIER1bXAgYSBzdGFjayB0cmFjZSB0byB0aGUgbG9nCisgICAgdm9pZCBkdW1wKGNvbnN0IGNoYXIqIHByZWZpeCA9IDApIGNvbnN0OworCisgICAgLy8gUmV0dXJuIGEgc3RyaW5nIChwb3NzaWJseSB2ZXJ5IGxvbmcpIGNvbnRhaW5pbmcgdGhlIGNvbXBsZXRlIHN0YWNrIHRyYWNlCisgICAgU3RyaW5nOCB0b1N0cmluZyhjb25zdCBjaGFyKiBwcmVmaXggPSAwKSBjb25zdDsKKyAgICAKKyAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIG1Db3VudDsgfQorCitwcml2YXRlOgorICAgIC8vIEludGVybmFsIGhlbHBlciBmdW5jdGlvbgorICAgIFN0cmluZzggdG9TdHJpbmdTaW5nbGVMZXZlbChjb25zdCBjaGFyKiBwcmVmaXgsIGludDMyX3QgbGV2ZWwpIGNvbnN0OworCisgICAgc2l6ZV90ICAgICAgbUNvdW50OworICAgIGNvbnN0IHZvaWQqIG1TdGFja1tNQVhfREVQVEhdOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfQ0FMTFNUQUNLX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvRGVidWcuaCBiL2luY2x1ZGUvdXRpbHMvRGVidWcuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjYyYjljCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9EZWJ1Zy5oCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gRGVidWdnaW5nIHRvb2xzLiAgVGhlc2Ugc2hvdWxkIGJlIGFibGUgdG8gYmUgc3RyaXBwZWQKKy8vIGluIHJlbGVhc2UgYnVpbGRzLgorLy8KKyNpZm5kZWYgQU5EUk9JRF9ERUJVR19ICisjZGVmaW5lIEFORFJPSURfREVCVUdfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKwordGVtcGxhdGU8Ym9vbD4gc3RydWN0IENvbXBpbGVUaW1lQXNzZXJ0OwordGVtcGxhdGU8PiBzdHJ1Y3QgQ29tcGlsZVRpbWVBc3NlcnQ8dHJ1ZT4ge307CisKK2NvbnN0IGNoYXIqIHN0cmluZ0ZvckluZGVudChpbnQzMl90IGluZGVudExldmVsKTsKKwordHlwZWRlZiB2b2lkICgqZGVidWdQcmludEZ1bmMpKHZvaWQqIGNvb2tpZSwgY29uc3QgY2hhciogdHh0KTsKKwordm9pZCBwcmludFR5cGVDb2RlKHVpbnQzMl90IHR5cGVDb2RlLAorICAgIGRlYnVnUHJpbnRGdW5jIGZ1bmMgPSAwLCB2b2lkKiBjb29raWUgPSAwKTsKK3ZvaWQgcHJpbnRIZXhEYXRhKGludDMyX3QgaW5kZW50LCBjb25zdCB2b2lkICpidWYsIHNpemVfdCBsZW5ndGgsCisgICAgc2l6ZV90IGJ5dGVzUGVyTGluZT0xNiwgaW50MzJfdCBzaW5nbGVMaW5lQnl0ZXNDdXRvZmY9MTYsCisgICAgc2l6ZV90IGFsaWdubWVudD0wLCBib29sIGNBcnJheVN0eWxlPWZhbHNlLAorICAgIGRlYnVnUHJpbnRGdW5jIGZ1bmMgPSAwLCB2b2lkKiBjb29raWUgPSAwKTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfREVCVUdfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9FbmRpYW4uaCBiL2luY2x1ZGUvdXRpbHMvRW5kaWFuLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTlmMjUwNAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvRW5kaWFuLmgKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBBbmRyb2lkIGVuZGlhbi1uZXNzIGRlZmluZXMuCisvLworI2lmbmRlZiBfTElCU19VVElMU19FTkRJQU5fSAorI2RlZmluZSBfTElCU19VVElMU19FTkRJQU5fSAorCisjaWYgZGVmaW5lZChIQVZFX0VORElBTl9IKQorCisjaW5jbHVkZSA8ZW5kaWFuLmg+CisKKyNlbHNlIC8qbm90IEhBVkVfRU5ESUFOX0gqLworCisjZGVmaW5lIF9fQklHX0VORElBTiAweDEwMDAKKyNkZWZpbmUgX19MSVRUTEVfRU5ESUFOIDB4MDAwMQorCisjaWYgZGVmaW5lZChIQVZFX0xJVFRMRV9FTkRJQU4pCisjIGRlZmluZSBfX0JZVEVfT1JERVIgX19MSVRUTEVfRU5ESUFOCisjZWxzZQorIyBkZWZpbmUgX19CWVRFX09SREVSIF9fQklHX0VORElBTgorI2VuZGlmCisKKyNlbmRpZiAvKm5vdCBIQVZFX0VORElBTl9IKi8KKworI2VuZGlmIC8qX0xJQlNfVVRJTFNfRU5ESUFOX0gqLwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9FcnJvcnMuaCBiL2luY2x1ZGUvdXRpbHMvRXJyb3JzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWJmOWU2ZgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvRXJyb3JzLmgKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9FUlJPUlNfSAorI2RlZmluZSBBTkRST0lEX0VSUk9SU19ICisKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIHVzZSB0aGlzIHR5cGUgdG8gcmV0dXJuIGVycm9yIGNvZGVzCisjaWZkZWYgSEFWRV9NU19DX1JVTlRJTUUKK3R5cGVkZWYgaW50ICAgICAgICAgc3RhdHVzX3Q7CisjZWxzZQordHlwZWRlZiBpbnQzMl90ICAgICBzdGF0dXNfdDsKKyNlbmRpZgorCisvKiB0aGUgTVMgQyBydW50aW1lIGxhY2tzIGEgZmV3IGVycm9yIGNvZGVzICovCisKKy8qCisgKiBFcnJvciBjb2Rlcy4gCisgKiBBbGwgZXJyb3IgY29kZXMgYXJlIG5lZ2F0aXZlIHZhbHVlcy4KKyAqLworCisvLyBXaW4zMiAjZGVmaW5lcyBOT19FUlJPUiBhcyB3ZWxsLiAgSXQgaGFzIHRoZSBzYW1lIHZhbHVlLCBzbyB0aGVyZSdzIG5vCisvLyByZWFsIGNvbmZsaWN0LCB0aG91Z2ggaXQncyBhIGJpdCBhd2t3YXJkLgorI2lmZGVmIF9XSU4zMgorIyB1bmRlZiBOT19FUlJPUgorI2VuZGlmCisgCitlbnVtIHsKKyAgICBPSyAgICAgICAgICAgICAgICA9IDAsICAgIC8vIEV2ZXJ5dGhpbmcncyBzd2VsbC4KKyAgICBOT19FUlJPUiAgICAgICAgICA9IDAsICAgIC8vIE5vIGVycm9ycy4KKyAgICAKKyAgICBVTktOT1dOX0VSUk9SICAgICAgID0gMHg4MDAwMDAwMCwKKworICAgIE5PX01FTU9SWSAgICAgICAgICAgPSAtRU5PTUVNLAorICAgIElOVkFMSURfT1BFUkFUSU9OICAgPSAtRU5PU1lTLAorICAgIEJBRF9WQUxVRSAgICAgICAgICAgPSAtRUlOVkFMLAorICAgIEJBRF9UWVBFICAgICAgICAgICAgPSAweDgwMDAwMDAxLAorICAgIE5BTUVfTk9UX0ZPVU5EICAgICAgPSAtRU5PRU5ULAorICAgIFBFUk1JU1NJT05fREVOSUVEICAgPSAtRVBFUk0sCisgICAgTk9fSU5JVCAgICAgICAgICAgICA9IC1FTk9ERVYsCisgICAgQUxSRUFEWV9FWElTVFMgICAgICA9IC1FRVhJU1QsCisgICAgREVBRF9PQkpFQ1QgICAgICAgICA9IC1FUElQRSwKKyAgICBGQUlMRURfVFJBTlNBQ1RJT04gID0gMHg4MDAwMDAwMiwKKyAgICBKUEFSS1NfQlJPS0VfSVQgICAgID0gLUVQSVBFLAorI2lmICFkZWZpbmVkKEhBVkVfTVNfQ19SVU5USU1FKQorICAgIEJBRF9JTkRFWCAgICAgICAgICAgPSAtRU9WRVJGTE9XLAorICAgIE5PVF9FTk9VR0hfREFUQSAgICAgPSAtRU5PREFUQSwKKyAgICBXT1VMRF9CTE9DSyAgICAgICAgID0gLUVXT1VMREJMT0NLLCAKKyAgICBUSU1FRF9PVVQgICAgICAgICAgID0gLUVUSU1FLAorICAgIFVOS05PV05fVFJBTlNBQ1RJT04gPSAtRUJBRE1TRywKKyNlbHNlICAgIAorICAgIEJBRF9JTkRFWCAgICAgICAgICAgPSAtRTJCSUcsCisgICAgTk9UX0VOT1VHSF9EQVRBICAgICA9IDB4ODAwMDAwMDMsCisgICAgV09VTERfQkxPQ0sgICAgICAgICA9IDB4ODAwMDAwMDQsCisgICAgVElNRURfT1VUICAgICAgICAgICA9IDB4ODAwMDAwMDUsCisgICAgVU5LTk9XTl9UUkFOU0FDVElPTiA9IDB4ODAwMDAwMDYsCisjZW5kaWYgICAgCit9OworCisvLyBSZXN0b3JlIGRlZmluZTsgZW51bWVyYXRpb24gaXMgaW4gImFuZHJvaWQiIG5hbWVzcGFjZSwgc28gdGhlIHZhbHVlIGRlZmluZWQKKy8vIHRoZXJlIHdvbid0IHdvcmsgZm9yIFdpbjMyIGNvZGUgaW4gYSBkaWZmZXJlbnQgbmFtZXNwYWNlLgorI2lmZGVmIF9XSU4zMgorIyBkZWZpbmUgTk9fRVJST1IgMEwKKyNlbmRpZgorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorICAgIAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgCisjZW5kaWYgLy8gQU5EUk9JRF9FUlJPUlNfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9GaWxlTWFwLmggYi9pbmNsdWRlL3V0aWxzL0ZpbGVNYXAuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZGZkM2JlCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9GaWxlTWFwLmgKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gRW5jYXBzdWxhdGUgYSBzaGFyZWQgZmlsZSBtYXBwaW5nLgorLy8KKyNpZm5kZWYgX19MSUJTX0ZJTEVfTUFQX0gKKyNkZWZpbmUgX19MSUJTX0ZJTEVfTUFQX0gKKworI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaWZkZWYgSEFWRV9XSU4zMl9GSUxFTUFQCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2VuZGlmCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFRoaXMgcmVwcmVzZW50cyBhIG1lbW9yeS1tYXBwZWQgZmlsZS4gIEl0IG1pZ2h0IGJlIHRoZSBlbnRpcmUgZmlsZSBvcgorICogb25seSBwYXJ0IG9mIGl0LiAgVGhpcyByZXF1aXJlcyBhIGxpdHRsZSBib29ra2VlcGluZyBiZWNhdXNlIHRoZSBtYXBwaW5nCisgKiBuZWVkcyB0byBiZSBhbGlnbmVkIG9uIHBhZ2UgYm91bmRhcmllcywgYW5kIGluIHNvbWUgY2FzZXMgd2UnZCBsaWtlIHRvCisgKiBoYXZlIG11bHRpcGxlIHJlZmVyZW5jZXMgdG8gdGhlIG1hcHBlZCBhcmVhIHdpdGhvdXQgY3JlYXRpbmcgYWRkaXRpb25hbAorICogbWFwcy4KKyAqCisgKiBUaGlzIGFsd2F5cyB1c2VzIE1BUF9TSEFSRUQuCisgKgorICogVE9ETzogd2Ugc2hvdWxkIGJlIGFibGUgdG8gY3JlYXRlIGEgbmV3IEZpbGVNYXAgdGhhdCBpcyBhIHN1YnNldCBvZgorICogYW4gZXhpc3RpbmcgRmlsZU1hcCBhbmQgc2hhcmVzIHRoZSB1bmRlcmx5aW5nIG1hcHBlZCBwYWdlcy4gIFJlcXVpcmVzCisgKiBjb21wbGV0aW5nIHRoZSByZWZjb3VudGluZyBzdHVmZiBhbmQgcG9zc2libHkgaW50cm9kdWNpbmcgdGhlIG5vdGlvbgorICogb2YgYSBGaWxlTWFwIGhpZXJhcmNoeS4KKyAqLworY2xhc3MgRmlsZU1hcCB7CitwdWJsaWM6CisgICAgRmlsZU1hcCh2b2lkKTsKKworICAgIC8qCisgICAgICogQ3JlYXRlIGEgbmV3IG1hcHBpbmcgb24gYW4gb3BlbiBmaWxlLgorICAgICAqCisgICAgICogQ2xvc2luZyB0aGUgZmlsZSBkZXNjcmlwdG9yIGRvZXMgbm90IHVubWFwIHRoZSBwYWdlcywgc28gd2UgZG9uJ3QKKyAgICAgKiBjbGFpbSBvd25lcnNoaXAgb2YgdGhlIGZkLgorICAgICAqCisgICAgICogUmV0dXJucyAiZmFsc2UiIG9uIGZhaWx1cmUuCisgICAgICovCisgICAgYm9vbCBjcmVhdGUoY29uc3QgY2hhciogb3JpZ0ZpbGVOYW1lLCBpbnQgZmQsCisgICAgICAgICAgICAgICAgb2ZmX3Qgb2Zmc2V0LCBzaXplX3QgbGVuZ3RoLCBib29sIHJlYWRPbmx5KTsKKworICAgIC8qCisgICAgICogUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBmaWxlIHRoaXMgbWFwIGNhbWUgZnJvbSwgaWYga25vd24uCisgICAgICovCisgICAgY29uc3QgY2hhciogZ2V0RmlsZU5hbWUodm9pZCkgY29uc3QgeyByZXR1cm4gbUZpbGVOYW1lOyB9CisgICAgCisgICAgLyoKKyAgICAgKiBHZXQgYSBwb2ludGVyIHRvIHRoZSBwaWVjZSBvZiB0aGUgZmlsZSB3ZSByZXF1ZXN0ZWQuCisgICAgICovCisgICAgdm9pZCogZ2V0RGF0YVB0cih2b2lkKSBjb25zdCB7IHJldHVybiBtRGF0YVB0cjsgfQorCisgICAgLyoKKyAgICAgKiBHZXQgdGhlIGxlbmd0aCB3ZSByZXF1ZXN0ZWQuCisgICAgICovCisgICAgc2l6ZV90IGdldERhdGFMZW5ndGgodm9pZCkgY29uc3QgeyByZXR1cm4gbURhdGFMZW5ndGg7IH0KKworICAgIC8qCisgICAgICogR2V0IHRoZSBkYXRhIG9mZnNldCB1c2VkIHRvIGNyZWF0ZSB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBvZmZfdCBnZXREYXRhT2Zmc2V0KHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1EYXRhT2Zmc2V0OyB9CisKKyAgICAvKgorICAgICAqIEdldCBhICJjb3B5IiBvZiB0aGUgb2JqZWN0LgorICAgICAqLworICAgIEZpbGVNYXAqIGFjcXVpcmUodm9pZCkgeyBtUmVmQ291bnQrKzsgcmV0dXJuIHRoaXM7IH0KKworICAgIC8qCisgICAgICogQ2FsbCB0aGlzIHdoZW4gbWFwcGluZyBpcyBubyBsb25nZXIgbmVlZGVkLgorICAgICAqLworICAgIHZvaWQgcmVsZWFzZSh2b2lkKSB7CisgICAgICAgIGlmICgtLW1SZWZDb3VudCA8PSAwKQorICAgICAgICAgICAgZGVsZXRlIHRoaXM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIG1hcHMgZGlyZWN0bHkgdG8gbWFkdmlzZSgpIHZhbHVlcywgYnV0IGFsbG93cyB1cyB0byBhdm9pZAorICAgICAqIGluY2x1ZGluZyA8c3lzL21tYW4uaD4gZXZlcnl3aGVyZS4KKyAgICAgKi8KKyAgICBlbnVtIE1hcEFkdmljZSB7CisgICAgICAgIE5PUk1BTCwgUkFORE9NLCBTRVFVRU5USUFMLCBXSUxMTkVFRCwgRE9OVE5FRUQKKyAgICB9OworCisgICAgLyoKKyAgICAgKiBBcHBseSBhbiBtYWR2aXNlKCkgY2FsbCB0byB0aGUgZW50aXJlIGZpbGUuCisgICAgICoKKyAgICAgKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgLTEgb24gZmFpbHVyZS4KKyAgICAgKi8KKyAgICBpbnQgYWR2aXNlKE1hcEFkdmljZSBhZHZpY2UpOworCitwcm90ZWN0ZWQ6CisgICAgLy8gZG9uJ3QgZGVsZXRlIG9iamVjdHM7IGNhbGwgcmVsZWFzZSgpCisgICAgfkZpbGVNYXAodm9pZCk7CisKK3ByaXZhdGU6CisgICAgLy8gdGhlc2UgYXJlIG5vdCBpbXBsZW1lbnRlZAorICAgIEZpbGVNYXAoY29uc3QgRmlsZU1hcCYgc3JjKTsKKyAgICBjb25zdCBGaWxlTWFwJiBvcGVyYXRvcj0oY29uc3QgRmlsZU1hcCYgc3JjKTsKKworICAgIGludCAgICAgICAgIG1SZWZDb3VudDsgICAgICAvLyByZWZlcmVuY2UgY291bnQKKyAgICBjaGFyKiAgICAgICBtRmlsZU5hbWU7ICAgICAgLy8gb3JpZ2luYWwgZmlsZSBuYW1lLCBpZiBrbm93bgorICAgIHZvaWQqICAgICAgIG1CYXNlUHRyOyAgICAgICAvLyBiYXNlIG9mIG1tYXAgYXJlYTsgcGFnZSBhbGlnbmVkCisgICAgc2l6ZV90ICAgICAgbUJhc2VMZW5ndGg7ICAgIC8vIGxlbmd0aCwgbWVhc3VyZWQgZnJvbSAibUJhc2VQdHIiCisgICAgb2ZmX3QgICAgICAgbURhdGFPZmZzZXQ7ICAgIC8vIG9mZnNldCB1c2VkIHdoZW4gbWFwIHdhcyBjcmVhdGVkCisgICAgdm9pZCogICAgICAgbURhdGFQdHI7ICAgICAgIC8vIHN0YXJ0IG9mIHJlcXVlc3RlZCBkYXRhLCBvZmZzZXQgZnJvbSBiYXNlCisgICAgc2l6ZV90ICAgICAgbURhdGFMZW5ndGg7ICAgIC8vIGxlbmd0aCwgbWVhc3VyZWQgZnJvbSAibURhdGFQdHIiCisjaWZkZWYgSEFWRV9XSU4zMl9GSUxFTUFQCisgICAgSEFORExFICAgICAgbUZpbGVIYW5kbGU7ICAgIC8vIFdpbjMyIGZpbGUgaGFuZGxlCisgICAgSEFORExFICAgICAgbUZpbGVNYXBwaW5nOyAgIC8vIFdpbjMyIGZpbGUgbWFwcGluZyBoYW5kbGUKKyNlbmRpZgorCisgICAgc3RhdGljIGxvbmcgbVBhZ2VTaXplOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIF9fTElCU19GSUxFX01BUF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0lCaW5kZXIuaCBiL2luY2x1ZGUvdXRpbHMvSUJpbmRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczNzAzMzAKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL0lCaW5kZXIuaApAQCAtMCwwICsxLDE1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9JQklOREVSX0gKKyNkZWZpbmUgQU5EUk9JRF9JQklOREVSX0gKKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorCisKKyNkZWZpbmUgQl9QQUNLX0NIQVJTKGMxLCBjMiwgYzMsIGM0KSBcCisgICAgKCgoKGMxKTw8MjQpKSB8ICgoKGMyKTw8MTYpKSB8ICgoKGMzKTw8OCkpIHwgKGM0KSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEJCaW5kZXI7CitjbGFzcyBCcEJpbmRlcjsKK2NsYXNzIElJbnRlcmZhY2U7CitjbGFzcyBQYXJjZWw7CisKKy8qKgorICogQmFzZSBjbGFzcyBhbmQgbG93LWxldmVsIHByb3RvY29sIGZvciBhIHJlbW90YWJsZSBvYmplY3QuCisgKiBZb3UgY2FuIGRlcml2ZSBmcm9tIHRoaXMgY2xhc3MgdG8gY3JlYXRlIGFuIG9iamVjdCBmb3Igd2hpY2ggb3RoZXIKKyAqIHByb2Nlc3NlcyBjYW4gaG9sZCByZWZlcmVuY2VzIHRvIGl0LiAgQ29tbXVuaWNhdGlvbiBiZXR3ZWVuIHByb2Nlc3NlcworICogKG1ldGhvZCBjYWxscywgcHJvcGVydHkgZ2V0IGFuZCBzZXQpIGlzIGRvd24gdGhyb3VnaCBhIGxvdy1sZXZlbAorICogcHJvdG9jb2wgaW1wbGVtZW50ZWQgb24gdG9wIG9mIHRoZSB0cmFuc2FjdCgpIEFQSS4KKyAqLworY2xhc3MgSUJpbmRlciA6IHB1YmxpYyB2aXJ0dWFsIFJlZkJhc2UKK3sKK3B1YmxpYzoKKyAgICBlbnVtIHsKKyAgICAgICAgRklSU1RfQ0FMTF9UUkFOU0FDVElPTiAgPSAweDAwMDAwMDAxLAorICAgICAgICBMQVNUX0NBTExfVFJBTlNBQ1RJT04gICA9IDB4MDBmZmZmZmYsCisKKyAgICAgICAgUElOR19UUkFOU0FDVElPTiAgICAgICAgPSBCX1BBQ0tfQ0hBUlMoJ18nLCdQJywnTicsJ0cnKSwKKyAgICAgICAgRFVNUF9UUkFOU0FDVElPTiAgICAgICAgPSBCX1BBQ0tfQ0hBUlMoJ18nLCdEJywnTScsJ1AnKSwKKyAgICAgICAgSU5URVJGQUNFX1RSQU5TQUNUSU9OICAgPSBCX1BBQ0tfQ0hBUlMoJ18nLCAnTicsICdUJywgJ0YnKSwKKworICAgICAgICAvLyBDb3JyZXNwb25kcyB0byB0Zk9uZVdheSAtLSBhbiBhc3luY2hyb25vdXMgY2FsbC4KKyAgICAgICAgRkxBR19PTkVXQVkgICAgICAgICAgICAgPSAweDAwMDAwMDAxCisgICAgfTsKKworICAgIGlubGluZSAgICAgICAgICAgICAgICAgIElCaW5kZXIoKSB7IH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgSUJpbmRlciBpbXBsZW1lbnRzIHRoZSBpbnRlcmZhY2UgbmFtZWQgYnkKKyAgICAgKiBAYSBkZXNjcmlwdG9yLiAgSWYgaXQgZG9lcywgdGhlIGJhc2UgcG9pbnRlciB0byBpdCBpcyByZXR1cm5lZCwKKyAgICAgKiB3aGljaCB5b3UgY2FuIHNhZmVseSBzdGF0aWNfY2FzdDw+IHRvIHRoZSBjb25jcmV0ZSBDKysgaW50ZXJmYWNlLgorICAgICAqLworICAgIHZpcnR1YWwgc3A8SUludGVyZmFjZT4gIHF1ZXJ5TG9jYWxJbnRlcmZhY2UoY29uc3QgU3RyaW5nMTYmIGRlc2NyaXB0b3IpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGUgaW50ZXJmYWNlIHByb3ZpZGVkIGJ5IHRoaXMgSUJpbmRlcgorICAgICAqIG9iamVjdC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIFN0cmluZzE2ICAgICAgICBnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkgY29uc3QgPSAwOworCisgICAgdmlydHVhbCBib29sICAgICAgICAgICAgaXNCaW5kZXJBbGl2ZSgpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBwaW5nQmluZGVyKCkgPSAwOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKSA9IDA7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICB0cmFuc2FjdCggICB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCkgPSAwOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgYWxsb3dzIHlvdSB0byBhZGQgZGF0YSB0aGF0IGlzIHRyYW5zcG9ydGVkIHRocm91Z2gKKyAgICAgKiBJUEMgYWxvbmcgd2l0aCB5b3VyIElCaW5kZXIgcG9pbnRlci4gIFdoZW4gaW1wbGVtZW50aW5nIGEgQmluZGVyCisgICAgICogb2JqZWN0LCBvdmVycmlkZSBpdCB0byB3cml0ZSB5b3VyIGRlc2lyZWQgZGF0YSBpbiB0byBAYSBvdXREYXRhLgorICAgICAqIFlvdSBjYW4gdGhlbiBjYWxsIGdldENvbnN0YW50RGF0YSgpIG9uIHlvdXIgSUJpbmRlciB0byByZXRyaWV2ZQorICAgICAqIHRoYXQgZGF0YSwgZnJvbSBhbnkgcHJvY2Vzcy4gIFlvdSBNVVNUIHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAgICogd3JpdHRlbiBpbiB0byB0aGUgcGFyY2VsIChpbmNsdWRpbmcgcGFkZGluZykuCisgICAgICovCisgICAgY2xhc3MgRGVhdGhSZWNpcGllbnQgOiBwdWJsaWMgdmlydHVhbCBSZWZCYXNlCisgICAgeworICAgIHB1YmxpYzoKKyAgICAgICAgdmlydHVhbCB2b2lkIGJpbmRlckRpZWQoY29uc3Qgd3A8SUJpbmRlcj4mIHdobykgPSAwOworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlciB0aGUgQGEgcmVjaXBpZW50IGZvciBhIG5vdGlmaWNhdGlvbiBpZiB0aGlzIGJpbmRlcgorICAgICAqIGdvZXMgYXdheS4gIElmIHRoaXMgYmluZGVyIG9iamVjdCB1bmV4cGVjdGVkbHkgZ29lcyBhd2F5CisgICAgICogKHR5cGljYWxseSBiZWNhdXNlIGl0cyBob3N0aW5nIHByb2Nlc3MgaGFzIGJlZW4ga2lsbGVkKSwKKyAgICAgKiB0aGVuIERlYXRoUmVjaXBpZW50OjpiaW5kZXJEaWVkKCkgd2lsbCBiZSBjYWxsZWQgd2l0aCBhIHJlZmVyZW5lCisgICAgICogdG8gdGhpcy4KKyAgICAgKgorICAgICAqIFRoZSBAYSBjb29raWUgaXMgb3B0aW9uYWwgLS0gaWYgbm9uLU5VTEwsIGl0IHNob3VsZCBiZSBhCisgICAgICogbWVtb3J5IGFkZHJlc3MgdGhhdCB5b3Ugb3duICh0aGF0IGlzLCB5b3Uga25vdyBpdCBpcyB1bmlxdWUpLgorICAgICAqCisgICAgICogQG5vdGUgWW91IHdpbGwgb25seSByZWNlaXZlIGRlYXRoIG5vdGlmaWNhdGlvbnMgZm9yIHJlbW90ZSBiaW5kZXJzLAorICAgICAqIGFzIGxvY2FsIGJpbmRlcnMgYnkgZGVmaW5pdGlvbiBjYW4ndCBkaWUgd2l0aG91dCB5b3UgZHlpbmcgYXMgd2VsbC4KKyAgICAgKiBUcnlpbmcgdG8gdXNlIHRoaXMgZnVuY3Rpb24gb24gYSBsb2NhbCBiaW5kZXIgd2lsbCByZXN1bHQgaW4gYW4KKyAgICAgKiBJTlZBTElEX09QRVJBVElPTiBjb2RlIGJlaW5nIHJldHVybmVkIGFuZCBub3RoaW5nIGhhcHBlbmluZy4KKyAgICAgKgorICAgICAqIEBub3RlIFRoaXMgbGluayBhbHdheXMgaG9sZHMgYSB3ZWFrIHJlZmVyZW5jZSB0byBpdHMgcmVjaXBpZW50LgorICAgICAqCisgICAgICogQG5vdGUgWW91IHdpbGwgb25seSByZWNlaXZlIGEgd2VhayByZWZlcmVuY2UgdG8gdGhlIGRlYWQKKyAgICAgKiBiaW5kZXIuICBZb3Ugc2hvdWxkIG5vdCB0cnkgdG8gcHJvbW90ZSB0aGlzIHRvIGEgc3Ryb25nIHJlZmVyZW5jZS4KKyAgICAgKiAoTm9yIHNob3VsZCB5b3UgbmVlZCB0bywgYXMgdGhlcmUgaXMgbm90aGluZyB1c2VmdWwgeW91IGNhbgorICAgICAqIGRpcmVjdGx5IGRvIHdpdGggaXQgbm93IHRoYXQgaXQgaGFzIHBhc3NlZCBvbi4pCisgICAgICovCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgbGlua1RvRGVhdGgoY29uc3Qgc3A8RGVhdGhSZWNpcGllbnQ+JiByZWNpcGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY29va2llID0gTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDApID0gMDsKKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBkZWF0aCBub3RpZmljYXRpb24uCisgICAgICogVGhlIEBhIHJlY2lwaWVudCB3aWxsIG5vIGxvbmdlciBiZSBjYWxsZWQgaWYgdGhpcyBvYmplY3QKKyAgICAgKiBkaWVzLiAgVGhlIEBhIGNvb2tpZSBpcyBvcHRpb25hbC4gIElmIG5vbi1OVUxMLCB5b3UgY2FuCisgICAgICogc3VwcGx5IGEgTlVMTCBAYSByZWNpcGllbnQsIGFuZCB0aGUgcmVjaXBpZW50IHByZXZpb3VzbHkKKyAgICAgKiBhZGRlZCB3aXRoIHRoYXQgY29va2llIHdpbGwgYmUgdW5saW5rZWQuCisgICAgICovCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgdW5saW5rVG9EZWF0aCggIGNvbnN0IHdwPERlYXRoUmVjaXBpZW50PiYgcmVjaXBpZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBjb29raWUgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdwPERlYXRoUmVjaXBpZW50Piogb3V0UmVjaXBpZW50ID0gTlVMTCkgPSAwOworCisgICAgdmlydHVhbCBib29sICAgICAgICAgICAgY2hlY2tTdWJjbGFzcyhjb25zdCB2b2lkKiBzdWJjbGFzc0lEKSBjb25zdDsKKworICAgIHR5cGVkZWYgdm9pZCAoKm9iamVjdF9jbGVhbnVwX2Z1bmMpKGNvbnN0IHZvaWQqIGlkLCB2b2lkKiBvYmosIHZvaWQqIGNsZWFudXBDb29raWUpOworCisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgYXR0YWNoT2JqZWN0KCAgIGNvbnN0IHZvaWQqIG9iamVjdElELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBvYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGNsZWFudXBDb29raWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdF9jbGVhbnVwX2Z1bmMgZnVuYykgPSAwOworICAgIHZpcnR1YWwgdm9pZCogICAgICAgICAgIGZpbmRPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBkZXRhY2hPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpID0gMDsKKworICAgIHZpcnR1YWwgQkJpbmRlciogICAgICAgIGxvY2FsQmluZGVyKCk7CisgICAgdmlydHVhbCBCcEJpbmRlciogICAgICAgcmVtb3RlQmluZGVyKCk7CisKK3Byb3RlY3RlZDoKKyAgICBpbmxpbmUgdmlydHVhbCAgICAgICAgICB+SUJpbmRlcigpIHsgfQorCitwcml2YXRlOgorfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvLyBBTkRST0lEX0lCSU5ERVJfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9JSW50ZXJmYWNlLmggYi9pbmNsdWRlL3V0aWxzL0lJbnRlcmZhY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTk3MjJhCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9JSW50ZXJmYWNlLmgKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworI2lmbmRlZiBBTkRST0lEX0lJTlRFUkZBQ0VfSAorI2RlZmluZSBBTkRST0lEX0lJTlRFUkZBQ0VfSAorCisjaW5jbHVkZSA8dXRpbHMvQmluZGVyLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBJSW50ZXJmYWNlIDogcHVibGljIHZpcnR1YWwgUmVmQmFzZQoreworcHVibGljOgorICAgICAgICAgICAgc3A8SUJpbmRlcj4gICAgICAgICBhc0JpbmRlcigpOworICAgICAgICAgICAgc3A8Y29uc3QgSUJpbmRlcj4gICBhc0JpbmRlcigpIGNvbnN0OworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCBJQmluZGVyKiAgICAgICAgICAgIG9uQXNCaW5kZXIoKSA9IDA7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIElOVEVSRkFDRT4KK2lubGluZSBzcDxJTlRFUkZBQ0U+IGludGVyZmFjZV9jYXN0KGNvbnN0IHNwPElCaW5kZXI+JiBvYmopCit7CisgICAgcmV0dXJuIElOVEVSRkFDRTo6YXNJbnRlcmZhY2Uob2JqKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBJTlRFUkZBQ0U+CitjbGFzcyBCbkludGVyZmFjZSA6IHB1YmxpYyBJTlRFUkZBQ0UsIHB1YmxpYyBCQmluZGVyCit7CitwdWJsaWM6CisgICAgdmlydHVhbCBzcDxJSW50ZXJmYWNlPiAgICAgIHF1ZXJ5TG9jYWxJbnRlcmZhY2UoY29uc3QgU3RyaW5nMTYmIF9kZXNjcmlwdG9yKTsKKyAgICB2aXJ0dWFsIFN0cmluZzE2ICAgICAgICAgICAgZ2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpIGNvbnN0OworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCBJQmluZGVyKiAgICAgICAgICAgIG9uQXNCaW5kZXIoKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8dHlwZW5hbWUgSU5URVJGQUNFPgorY2xhc3MgQnBJbnRlcmZhY2UgOiBwdWJsaWMgSU5URVJGQUNFLCBwdWJsaWMgQnBSZWZCYXNlCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJwSW50ZXJmYWNlKGNvbnN0IHNwPElCaW5kZXI+JiByZW1vdGUpOworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCBJQmluZGVyKiAgICAgICAgICAgIG9uQXNCaW5kZXIoKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBERUNMQVJFX01FVEFfSU5URVJGQUNFKElOVEVSRkFDRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHN0YXRpYyBjb25zdCBTdHJpbmcxNiBkZXNjcmlwdG9yOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHN0YXRpYyBzcDxJIyNJTlRFUkZBQ0U+IGFzSW50ZXJmYWNlKGNvbnN0IHNwPElCaW5kZXI+JiBvYmopOyAgICAgICAgXAorICAgIHZpcnR1YWwgU3RyaW5nMTYgZ2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpIGNvbnN0OyAgICAgICAgICAgICAgICAgICAgXAorCisjZGVmaW5lIElNUExFTUVOVF9NRVRBX0lOVEVSRkFDRShJTlRFUkZBQ0UsIE5BTUUpICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3QgU3RyaW5nMTYgSSMjSU5URVJGQUNFOjpkZXNjcmlwdG9yKE5BTUUpOyAgICAgICAgICAgICAgICAgICAgICBcCisgICAgU3RyaW5nMTYgSSMjSU5URVJGQUNFOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkgY29uc3QgeyAgICAgICAgICAgICBcCisgICAgICAgIHJldHVybiBJIyNJTlRFUkZBQ0U6OmRlc2NyaXB0b3I7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3A8SSMjSU5URVJGQUNFPiBJIyNJTlRFUkZBQ0U6OmFzSW50ZXJmYWNlKGNvbnN0IHNwPElCaW5kZXI+JiBvYmopICBcCisgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHNwPEkjI0lOVEVSRkFDRT4gaW50cjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChvYmogIT0gTlVMTCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBpbnRyID0gc3RhdGljX2Nhc3Q8SSMjSU5URVJGQUNFKj4oICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgb2JqLT5xdWVyeUxvY2FsSW50ZXJmYWNlKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICBJIyNJTlRFUkZBQ0U6OmRlc2NyaXB0b3IpLmdldCgpKTsgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBpZiAoaW50ciA9PSBOVUxMKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgaW50ciA9IG5ldyBCcCMjSU5URVJGQUNFKG9iaik7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHJldHVybiBpbnRyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vIHVzZXItc2VydmljYWJsZSBwYXJ0cyBhZnRlciB0aGlzLi4uCisKK3RlbXBsYXRlPHR5cGVuYW1lIElOVEVSRkFDRT4KK2lubGluZSBzcDxJSW50ZXJmYWNlPiBCbkludGVyZmFjZTxJTlRFUkZBQ0U+OjpxdWVyeUxvY2FsSW50ZXJmYWNlKAorICAgICAgICBjb25zdCBTdHJpbmcxNiYgX2Rlc2NyaXB0b3IpCit7CisgICAgaWYgKF9kZXNjcmlwdG9yID09IElOVEVSRkFDRTo6ZGVzY3JpcHRvcikgcmV0dXJuIHRoaXM7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIElOVEVSRkFDRT4KK2lubGluZSBTdHJpbmcxNiBCbkludGVyZmFjZTxJTlRFUkZBQ0U+OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkgY29uc3QKK3sKKyAgICByZXR1cm4gSU5URVJGQUNFOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIElOVEVSRkFDRT4KK0lCaW5kZXIqIEJuSW50ZXJmYWNlPElOVEVSRkFDRT46Om9uQXNCaW5kZXIoKQoreworICAgIHJldHVybiB0aGlzOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBJTlRFUkZBQ0U+CitpbmxpbmUgQnBJbnRlcmZhY2U8SU5URVJGQUNFPjo6QnBJbnRlcmZhY2UoY29uc3Qgc3A8SUJpbmRlcj4mIHJlbW90ZSkKKyAgICA6IEJwUmVmQmFzZShyZW1vdGUpCit7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIElOVEVSRkFDRT4KK2lubGluZSBJQmluZGVyKiBCcEludGVyZmFjZTxJTlRFUkZBQ0U+OjpvbkFzQmluZGVyKCkKK3sKKyAgICByZXR1cm4gcmVtb3RlKCk7Cit9CisgICAgCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0lJTlRFUkZBQ0VfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9JTWVtb3J5LmggYi9pbmNsdWRlL3V0aWxzL0lNZW1vcnkuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWEzZmQ3Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9JTWVtb3J5LmgKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9JTUVNT1JZX0gKKyNkZWZpbmUgQU5EUk9JRF9JTUVNT1JZX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisKKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvSUludGVyZmFjZS5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgSU1lbW9yeUhlYXAgOiBwdWJsaWMgSUludGVyZmFjZQoreworcHVibGljOgorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoTWVtb3J5SGVhcCk7CisKKyAgICAvLyBmbGFncyByZXR1cm5lZCBieSBnZXRGbGFncygpCisgICAgZW51bSB7CisgICAgICAgIFJFQURfT05MWSAgID0gMHgwMDAwMDAwMSwKKyAgICAgICAgTUFQX09OQ0UgICAgPSAweDAwMDAwMDAyCisgICAgfTsKKworICAgIHZpcnR1YWwgaW50ICAgICAgICAgZ2V0SGVhcElEKCkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCogICAgICAgZ2V0QmFzZSgpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHNpemVfdCAgICAgIGdldFNpemUoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCB1aW50MzJfdCAgICBnZXRGbGFncygpIGNvbnN0ID0gMDsKKworICAgIC8vIHRoZXNlIGFyZSB0aGVyZSBqdXN0IGZvciBiYWNrd2FyZCBzb3VyY2UgY29tcGF0aWJpbGl0eQorICAgIGludDMyX3QgaGVhcElEKCkgY29uc3QgeyByZXR1cm4gZ2V0SGVhcElEKCk7IH0KKyAgICB2b2lkKiAgIGJhc2UoKSBjb25zdCAgeyByZXR1cm4gZ2V0QmFzZSgpOyB9CisgICAgc2l6ZV90ICB2aXJ0dWFsU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIGdldFNpemUoKTsgfQorfTsKKworY2xhc3MgQm5NZW1vcnlIZWFwIDogcHVibGljIEJuSW50ZXJmYWNlPElNZW1vcnlIZWFwPgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3Qgb25UcmFuc2FjdCggCisgICAgICAgICAgICB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgUGFyY2VsKiByZXBseSwKKyAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCk7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIElNZW1vcnkgOiBwdWJsaWMgSUludGVyZmFjZQoreworcHVibGljOgorICAgIERFQ0xBUkVfTUVUQV9JTlRFUkZBQ0UoTWVtb3J5KTsKKworICAgIHZpcnR1YWwgc3A8SU1lbW9yeUhlYXA+IGdldE1lbW9yeShzc2l6ZV90KiBvZmZzZXQ9MCwgc2l6ZV90KiBzaXplPTApIGNvbnN0ID0gMDsKKworICAgIC8vIGhlbHBlcnMKKyAgICB2b2lkKiBmYXN0UG9pbnRlcihjb25zdCBzcDxJQmluZGVyPiYgaGVhcCwgc3NpemVfdCBvZmZzZXQpIGNvbnN0OworICAgIHZvaWQqIHBvaW50ZXIoKSBjb25zdDsKKyAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0OworICAgIHNzaXplX3Qgb2Zmc2V0KCkgY29uc3Q7Cit9OworCitjbGFzcyBCbk1lbW9yeSA6IHB1YmxpYyBCbkludGVyZmFjZTxJTWVtb3J5PgoreworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3Qgb25UcmFuc2FjdCgKKyAgICAgICAgICAgIHVpbnQzMl90IGNvZGUsCisgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfSU1FTU9SWV9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0lQQ1RocmVhZFN0YXRlLmggYi9pbmNsdWRlL3V0aWxzL0lQQ1RocmVhZFN0YXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ5MGZkMwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvSVBDVGhyZWFkU3RhdGUuaApAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9JUENfVEhSRUFEX1NUQVRFX0gKKyNkZWZpbmUgQU5EUk9JRF9JUENfVEhSRUFEX1NUQVRFX0gKKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL1Byb2Nlc3NTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorCisjaWZkZWYgSEFWRV9XSU4zMl9QUk9DCit0eXBlZGVmICBpbnQgIHVpZF90OworI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBJUENUaHJlYWRTdGF0ZQoreworcHVibGljOgorICAgIHN0YXRpYyAgSVBDVGhyZWFkU3RhdGUqICAgICBzZWxmKCk7CisgICAgCisgICAgICAgICAgICBzcDxQcm9jZXNzU3RhdGU+ICAgIHByb2Nlc3MoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBjbGVhckxhc3RFcnJvcigpOworCisgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgIGdldENhbGxpbmdQaWQoKTsKKyAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgZ2V0Q2FsbGluZ1VpZCgpOworICAgICAgICAgICAgCisgICAgICAgICAgICBpbnQ2NF90ICAgICAgICAgICAgIGNsZWFyQ2FsbGluZ0lkZW50aXR5KCk7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHJlc3RvcmVDYWxsaW5nSWRlbnRpdHkoaW50NjRfdCB0b2tlbik7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgZmx1c2hDb21tYW5kcygpOworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGpvaW5UaHJlYWRQb29sKGJvb2wgaXNNYWluID0gdHJ1ZSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIFN0b3AgdGhlIGxvY2FsIHByb2Nlc3MuCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0b3BQcm9jZXNzKGJvb2wgaW1tZWRpYXRlID0gdHJ1ZSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgdHJhbnNhY3QoaW50MzJfdCBoYW5kbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpOworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGluY1N0cm9uZ0hhbmRsZShpbnQzMl90IGhhbmRsZSk7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGRlY1N0cm9uZ0hhbmRsZShpbnQzMl90IGhhbmRsZSk7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGluY1dlYWtIYW5kbGUoaW50MzJfdCBoYW5kbGUpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBkZWNXZWFrSGFuZGxlKGludDMyX3QgaGFuZGxlKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgYXR0ZW1wdEluY1N0cm9uZ0hhbmRsZShpbnQzMl90IGhhbmRsZSk7CisgICAgc3RhdGljICB2b2lkICAgICAgICAgICAgICAgIGV4cHVuZ2VIYW5kbGUoaW50MzJfdCBoYW5kbGUsIElCaW5kZXIqIGJpbmRlcik7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIHJlcXVlc3REZWF0aE5vdGlmaWNhdGlvbiggICBpbnQzMl90IGhhbmRsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJwQmluZGVyKiBwcm94eSk7IAorICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBjbGVhckRlYXRoTm90aWZpY2F0aW9uKCBpbnQzMl90IGhhbmRsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnBCaW5kZXIqIHByb3h5KTsgCisKKyAgICBzdGF0aWMgIHZvaWQgICAgICAgICAgICAgICAgc2h1dGRvd24oKTsKKyAgICAKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5JUENUaHJlYWRTdGF0ZSgpOworCisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIHNlbmRSZXBseShjb25zdCBQYXJjZWwmIHJlcGx5LCB1aW50MzJfdCBmbGFncyk7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIHdhaXRGb3JSZXNwb25zZShQYXJjZWwgKnJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX3QgKmFjcXVpcmVSZXN1bHQ9TlVMTCk7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIHRhbGtXaXRoRHJpdmVyKGJvb2wgZG9SZWNlaXZlPXRydWUpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZVRyYW5zYWN0aW9uRGF0YShpbnQzMl90IGNtZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgYmluZGVyRmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgaGFuZGxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJjZWwmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190KiBzdGF0dXNCdWZmZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBleGVjdXRlQ29tbWFuZChpbnQzMl90IGNvbW1hbmQpOworICAgICAgICAgICAgCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGNsZWFyQ2FsbGVyKCk7CisgICAgICAgICAgICAKKyAgICBzdGF0aWMgIHZvaWQgICAgICAgICAgICAgICAgdGhyZWFkRGVzdHJ1Y3Rvcih2b2lkICpzdCk7CisgICAgc3RhdGljICB2b2lkICAgICAgICAgICAgICAgIGZyZWVCdWZmZXIoUGFyY2VsKiBwYXJjZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCogZGF0YSwgc2l6ZV90IGRhdGFTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCogb2JqZWN0cywgc2l6ZV90IG9iamVjdHNTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIGNvb2tpZSk7CisgICAgCisgICAgY29uc3QgICBzcDxQcm9jZXNzU3RhdGU+ICAgIG1Qcm9jZXNzOworICAgICAgICAgICAgVmVjdG9yPEJCaW5kZXIqPiAgICBtUGVuZGluZ1N0cm9uZ0RlcmVmczsKKyAgICAgICAgICAgIFZlY3RvcjxSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqPiBtUGVuZGluZ1dlYWtEZXJlZnM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgUGFyY2VsICAgICAgICAgICAgICBtSW47CisgICAgICAgICAgICBQYXJjZWwgICAgICAgICAgICAgIG1PdXQ7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIG1MYXN0RXJyb3I7CisgICAgICAgICAgICBwaWRfdCAgICAgICAgICAgICAgIG1DYWxsaW5nUGlkOworICAgICAgICAgICAgdWlkX3QgICAgICAgICAgICAgICBtQ2FsbGluZ1VpZDsKK307CisgICAgCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfSVBDX1RIUkVBRF9TVEFURV9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0lQZXJtaXNzaW9uQ29udHJvbGxlci5oIGIvaW5jbHVkZS91dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjFkZDM0Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuaApAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKyNpZm5kZWYgQU5EUk9JRF9JUEVSTUlTU0lPTl9DT05UUk9MTEVSX0gKKyNkZWZpbmUgQU5EUk9JRF9JUEVSTUlTU0lPTl9DT05UUk9MTEVSX0gKKworI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIElQZXJtaXNzaW9uQ29udHJvbGxlciA6IHB1YmxpYyBJSW50ZXJmYWNlCit7CitwdWJsaWM6CisgICAgREVDTEFSRV9NRVRBX0lOVEVSRkFDRShQZXJtaXNzaW9uQ29udHJvbGxlcik7CisKKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKGNvbnN0IFN0cmluZzE2JiBwZXJtaXNzaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBwaWQsIGludDMyX3QgdWlkKSA9IDA7CisgICAgCisgICAgZW51bSB7CisgICAgICAgIENIRUNLX1BFUk1JU1NJT05fVFJBTlNBQ1RJT04gPSBJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OCisgICAgfTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQm5QZXJtaXNzaW9uQ29udHJvbGxlciA6IHB1YmxpYyBCbkludGVyZmFjZTxJUGVybWlzc2lvbkNvbnRyb2xsZXI+Cit7CitwdWJsaWM6CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBvblRyYW5zYWN0KCB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCk7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0lQRVJNSVNTSU9OX0NPTlRST0xMRVJfSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0lTZXJ2aWNlTWFuYWdlci5oIGIvaW5jbHVkZS91dGlscy9JU2VydmljZU1hbmFnZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2Q5OWZlCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9JU2VydmljZU1hbmFnZXIuaApAQCAtMCwwICsxLDk4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKyNpZm5kZWYgQU5EUk9JRF9JU0VSVklDRV9NQU5BR0VSX0gKKyNkZWZpbmUgQU5EUk9JRF9JU0VSVklDRV9NQU5BR0VSX0gKKworI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDx1dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9WZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgSVNlcnZpY2VNYW5hZ2VyIDogcHVibGljIElJbnRlcmZhY2UKK3sKK3B1YmxpYzoKKyAgICBERUNMQVJFX01FVEFfSU5URVJGQUNFKFNlcnZpY2VNYW5hZ2VyKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIGFuIGV4aXN0aW5nIHNlcnZpY2UsIGJsb2NraW5nIGZvciBhIGZldyBzZWNvbmRzCisgICAgICogaWYgaXQgZG9lc24ndCB5ZXQgZXhpc3QuCisgICAgICovCisgICAgdmlydHVhbCBzcDxJQmluZGVyPiAgICAgICAgIGdldFNlcnZpY2UoIGNvbnN0IFN0cmluZzE2JiBuYW1lKSBjb25zdCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSBhbiBleGlzdGluZyBzZXJ2aWNlLCBub24tYmxvY2tpbmcuCisgICAgICovCisgICAgdmlydHVhbCBzcDxJQmluZGVyPiAgICAgICAgIGNoZWNrU2VydmljZSggY29uc3QgU3RyaW5nMTYmIG5hbWUpIGNvbnN0ID0gMDsKKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVyIGEgc2VydmljZS4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICAgICAgYWRkU2VydmljZSggY29uc3QgU3RyaW5nMTYmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBzZXJ2aWNlKSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gbGlzdCBvZiBhbGwgZXhpc3Rpbmcgc2VydmljZXMuCisgICAgICovCisgICAgdmlydHVhbCBWZWN0b3I8U3RyaW5nMTY+ICAgIGxpc3RTZXJ2aWNlcygpID0gMDsKKworICAgIGVudW0geworICAgICAgICBHRVRfU0VSVklDRV9UUkFOU0FDVElPTiA9IElCaW5kZXI6OkZJUlNUX0NBTExfVFJBTlNBQ1RJT04sCisgICAgICAgIENIRUNLX1NFUlZJQ0VfVFJBTlNBQ1RJT04sCisgICAgICAgIEFERF9TRVJWSUNFX1RSQU5TQUNUSU9OLAorICAgICAgICBMSVNUX1NFUlZJQ0VTX1RSQU5TQUNUSU9OLAorICAgIH07Cit9OworCitzcDxJU2VydmljZU1hbmFnZXI+IGRlZmF1bHRTZXJ2aWNlTWFuYWdlcigpOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBJTlRFUkZBQ0U+CitzdGF0dXNfdCBnZXRTZXJ2aWNlKGNvbnN0IFN0cmluZzE2JiBuYW1lLCBzcDxJTlRFUkZBQ0U+KiBvdXRTZXJ2aWNlKQoreworICAgIGNvbnN0IHNwPElTZXJ2aWNlTWFuYWdlcj4gc20gPSBkZWZhdWx0U2VydmljZU1hbmFnZXIoKTsKKyAgICBpZiAoc20gIT0gTlVMTCkgeworICAgICAgICAqb3V0U2VydmljZSA9IGludGVyZmFjZV9jYXN0PElOVEVSRkFDRT4oc20tPmdldFNlcnZpY2UobmFtZSkpOworICAgICAgICBpZiAoKCpvdXRTZXJ2aWNlKSAhPSBOVUxMKSByZXR1cm4gTk9fRVJST1I7CisgICAgfQorICAgIHJldHVybiBOQU1FX05PVF9GT1VORDsKK30KKworYm9vbCBjaGVja0NhbGxpbmdQZXJtaXNzaW9uKGNvbnN0IFN0cmluZzE2JiBwZXJtaXNzaW9uKTsKK2Jvb2wgY2hlY2tDYWxsaW5nUGVybWlzc2lvbihjb25zdCBTdHJpbmcxNiYgcGVybWlzc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90KiBvdXRQaWQsIGludDMyX3QqIG91dFVpZCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQm5TZXJ2aWNlTWFuYWdlciA6IHB1YmxpYyBCbkludGVyZmFjZTxJU2VydmljZU1hbmFnZXI+Cit7CitwdWJsaWM6CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBvblRyYW5zYWN0KCB1aW50MzJfdCBjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gMCk7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0lTRVJWSUNFX01BTkFHRVJfSAorCmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0tleWVkVmVjdG9yLmggYi9pbmNsdWRlL3V0aWxzL0tleWVkVmVjdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjQ1MTNlZQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvS2V5ZWRWZWN0b3IuaApAQCAtMCwwICsxLDIwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9LRVlFRF9WRUNUT1JfSAorI2RlZmluZSBBTkRST0lEX0tFWUVEX1ZFQ1RPUl9ICisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1NvcnRlZFZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL1R5cGVIZWxwZXJzLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLRVksIHR5cGVuYW1lIFZBTFVFPgorY2xhc3MgS2V5ZWRWZWN0b3IKK3sKK3B1YmxpYzoKKyAgICB0eXBlZGVmIEtFWSAgICBrZXlfdHlwZTsKKyAgICB0eXBlZGVmIFZBTFVFICB2YWx1ZV90eXBlOworCisgICAgaW5saW5lICAgICAgICAgICAgICAgICAgS2V5ZWRWZWN0b3IoKTsKKworICAgIC8qCisgICAgICogZW1wdHkgdGhlIHZlY3RvcgorICAgICAqLworCisgICAgaW5saW5lICB2b2lkICAgICAgICAgICAgY2xlYXIoKSAgICAgICAgICAgICAgICAgICAgIHsgbVZlY3Rvci5jbGVhcigpOyB9CisKKyAgICAvKiEgCisgICAgICogdmVjdG9yIHN0YXRzCisgICAgICovCisKKyAgICAvLyEgcmV0dXJucyBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHZlY3RvcgorICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgIHNpemUoKSBjb25zdCAgICAgICAgICAgICAgICB7IHJldHVybiBtVmVjdG9yLnNpemUoKTsgfQorICAgIC8vISByZXR1cm5zIHdldGhlciBvciBub3QgdGhlIHZlY3RvciBpcyBlbXB0eQorICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgIGlzRW1wdHkoKSBjb25zdCAgICAgICAgICAgICB7IHJldHVybiBtVmVjdG9yLmlzRW1wdHkoKTsgfQorICAgIC8vISByZXR1cm5zIGhvdyBtYW55IGl0ZW1zIGNhbiBiZSBzdG9yZWQgd2l0aG91dCByZWFsbG9jYXRpbmcgdGhlIGJhY2tpbmcgc3RvcmUKKyAgICBpbmxpbmUgIHNpemVfdCAgICAgICAgICBjYXBhY2l0eSgpIGNvbnN0ICAgICAgICAgICAgeyByZXR1cm4gbVZlY3Rvci5jYXBhY2l0eSgpOyB9CisgICAgLy8hIHNldHN0IHRoZSBjYXBhY2l0eS4gY2FwYWNpdHkgY2FuIG5ldmVyIGJlIHJlZHVjZWQgbGVzcyB0aGFuIHNpemUoKQorICAgIGlubGluZSBzc2l6ZV90ICAgICAgICAgIHNldENhcGFjaXR5KHNpemVfdCBzaXplKSAgICB7IHJldHVybiBtVmVjdG9yLnNldENhcGFjaXR5KHNpemUpOyB9CisgICAgCisgICAgLyohIAorICAgICAqIGFjY2Vzc29ycworICAgICAqLworICAgICAgICAgICAgY29uc3QgVkFMVUUmICAgIHZhbHVlRm9yKGNvbnN0IEtFWSYga2V5KSBjb25zdDsKKyAgICAgICAgICAgIGNvbnN0IFZBTFVFJiAgICB2YWx1ZUF0KHNpemVfdCBpbmRleCkgY29uc3Q7CisgICAgICAgICAgICBjb25zdCBLRVkmICAgICAga2V5QXQoc2l6ZV90IGluZGV4KSBjb25zdDsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBpbmRleE9mS2V5KGNvbnN0IEtFWSYga2V5KSBjb25zdDsKKworICAgIC8qIQorICAgICAqIG1vZGlmaW5nIHRoZSBhcnJheQorICAgICAqLworCisgICAgICAgICAgICBWQUxVRSYgICAgICAgICAgZWRpdFZhbHVlRm9yKGNvbnN0IEtFWSYga2V5KTsKKyAgICAgICAgICAgIFZBTFVFJiAgICAgICAgICBlZGl0VmFsdWVBdChzaXplX3QgaW5kZXgpOworCisgICAgICAgICAgICAvKiEgCisgICAgICAgICAgICAgKiBhZGQvaW5zZXJ0L3JlcGxhY2UgaXRlbXMKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgIAorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZChjb25zdCBLRVkmIGtleSwgY29uc3QgVkFMVUUmIGl0ZW0pOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIHJlcGxhY2VWYWx1ZUZvcihjb25zdCBLRVkmIGtleSwgY29uc3QgVkFMVUUmIGl0ZW0pOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIHJlcGxhY2VWYWx1ZUF0KHNpemVfdCBpbmRleCwgY29uc3QgVkFMVUUmIGl0ZW0pOworCisgICAgLyohCisgICAgICogcmVtb3ZlIGl0ZW1zCisgICAgICovCisKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZW1vdmVJdGVtKGNvbnN0IEtFWSYga2V5KTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZW1vdmVJdGVtc0F0KHNpemVfdCBpbmRleCwgc2l6ZV90IGNvdW50ID0gMSk7CisgICAgICAgICAgICAKK3ByaXZhdGU6CisgICAgICAgICAgICBTb3J0ZWRWZWN0b3I8IGtleV92YWx1ZV9wYWlyX3Q8S0VZLCBWQUxVRT4gPiAgICBtVmVjdG9yOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8qKgorICogVmFyaWF0aW9uIG9mIEtleWVkVmVjdG9yIHRoYXQgaG9sZHMgYSBkZWZhdWx0IHZhbHVlIHRvIHJldHVybiB3aGVuCisgKiB2YWx1ZUZvcigpIGlzIGNhbGxlZCB3aXRoIGEga2V5IHRoYXQgZG9lc24ndCBleGlzdC4KKyAqLwordGVtcGxhdGUgPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+CitjbGFzcyBEZWZhdWx0S2V5ZWRWZWN0b3IgOiBwdWJsaWMgS2V5ZWRWZWN0b3I8S0VZLCBWQUxVRT4KK3sKK3B1YmxpYzoKKyAgICBpbmxpbmUgICAgICAgICAgICAgICAgICBEZWZhdWx0S2V5ZWRWZWN0b3IoY29uc3QgVkFMVUUmIGRlZlZhbHVlID0gVkFMVUUoKSk7CisgICAgICAgICAgICBjb25zdCBWQUxVRSYgICAgdmFsdWVGb3IoY29uc3QgS0VZJiBrZXkpIGNvbnN0OworCitwcml2YXRlOgorICAgICAgICAgICAgVkFMVUUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbURlZmF1bHQ7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitLZXllZFZlY3RvcjxLRVksVkFMVUU+OjpLZXllZFZlY3RvcigpCit7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorc3NpemVfdCBLZXllZFZlY3RvcjxLRVksVkFMVUU+OjppbmRleE9mS2V5KGNvbnN0IEtFWSYga2V5KSBjb25zdCB7CisgICAgcmV0dXJuIG1WZWN0b3IuaW5kZXhPZigga2V5X3ZhbHVlX3BhaXJfdDxLRVksVkFMVUU+KGtleSkgKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitjb25zdCBWQUxVRSYgS2V5ZWRWZWN0b3I8S0VZLFZBTFVFPjo6dmFsdWVGb3IoY29uc3QgS0VZJiBrZXkpIGNvbnN0IHsKKyAgICBzc2l6ZV90IGkgPSBpbmRleE9mS2V5KGtleSk7CisgICAgYXNzZXJ0KGk+PTApOworICAgIHJldHVybiBtVmVjdG9yLml0ZW1BdChpKS52YWx1ZTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitjb25zdCBWQUxVRSYgS2V5ZWRWZWN0b3I8S0VZLFZBTFVFPjo6dmFsdWVBdChzaXplX3QgaW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gbVZlY3Rvci5pdGVtQXQoaW5kZXgpLnZhbHVlOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBLRVksIHR5cGVuYW1lIFZBTFVFPiBpbmxpbmUKK2NvbnN0IEtFWSYgS2V5ZWRWZWN0b3I8S0VZLFZBTFVFPjo6a2V5QXQoc2l6ZV90IGluZGV4KSBjb25zdCB7CisgICAgcmV0dXJuIG1WZWN0b3IuaXRlbUF0KGluZGV4KS5rZXk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorVkFMVUUmIEtleWVkVmVjdG9yPEtFWSxWQUxVRT46OmVkaXRWYWx1ZUZvcihjb25zdCBLRVkmIGtleSkgeworICAgIHNzaXplX3QgaSA9IGluZGV4T2ZLZXkoa2V5KTsKKyAgICBhc3NlcnQoaT49MCk7CisgICAgcmV0dXJuIG1WZWN0b3IuZWRpdEl0ZW1BdChpKS52YWx1ZTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitWQUxVRSYgS2V5ZWRWZWN0b3I8S0VZLFZBTFVFPjo6ZWRpdFZhbHVlQXQoc2l6ZV90IGluZGV4KSB7CisgICAgcmV0dXJuIG1WZWN0b3IuZWRpdEl0ZW1BdChpbmRleCkudmFsdWU7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorc3NpemVfdCBLZXllZFZlY3RvcjxLRVksVkFMVUU+OjphZGQoY29uc3QgS0VZJiBrZXksIGNvbnN0IFZBTFVFJiB2YWx1ZSkgeworICAgIHJldHVybiBtVmVjdG9yLmFkZCgga2V5X3ZhbHVlX3BhaXJfdDxLRVksVkFMVUU+KGtleSwgdmFsdWUpICk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorc3NpemVfdCBLZXllZFZlY3RvcjxLRVksVkFMVUU+OjpyZXBsYWNlVmFsdWVGb3IoY29uc3QgS0VZJiBrZXksIGNvbnN0IFZBTFVFJiB2YWx1ZSkgeworICAgIGtleV92YWx1ZV9wYWlyX3Q8S0VZLFZBTFVFPiBwYWlyKGtleSwgdmFsdWUpOworICAgIG1WZWN0b3IucmVtb3ZlKHBhaXIpOworICAgIHJldHVybiBtVmVjdG9yLmFkZChwYWlyKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitzc2l6ZV90IEtleWVkVmVjdG9yPEtFWSxWQUxVRT46OnJlcGxhY2VWYWx1ZUF0KHNpemVfdCBpbmRleCwgY29uc3QgVkFMVUUmIGl0ZW0pIHsKKyAgICBpZiAoaW5kZXg8c2l6ZSgpKSB7CisgICAgICAgIG1WZWN0b3IuZWRpdFZhbHVlQXQoaW5kZXgpLnZhbHVlID0gaXRlbTsKKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKyAgICByZXR1cm4gQkFEX0lOREVYOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBLRVksIHR5cGVuYW1lIFZBTFVFPiBpbmxpbmUKK3NzaXplX3QgS2V5ZWRWZWN0b3I8S0VZLFZBTFVFPjo6cmVtb3ZlSXRlbShjb25zdCBLRVkmIGtleSkgeworICAgIHJldHVybiBtVmVjdG9yLnJlbW92ZShrZXlfdmFsdWVfcGFpcl90PEtFWSxWQUxVRT4oa2V5KSk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorc3NpemVfdCBLZXllZFZlY3RvcjxLRVksIFZBTFVFPjo6cmVtb3ZlSXRlbXNBdChzaXplX3QgaW5kZXgsIHNpemVfdCBjb3VudCkgeworICAgIHJldHVybiBtVmVjdG9yLnJlbW92ZUl0ZW1zQXQoaW5kZXgsIGNvdW50KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIEtFWSwgdHlwZW5hbWUgVkFMVUU+IGlubGluZQorRGVmYXVsdEtleWVkVmVjdG9yPEtFWSxWQUxVRT46OkRlZmF1bHRLZXllZFZlY3Rvcihjb25zdCBWQUxVRSYgZGVmVmFsdWUpCisgICAgOiBtRGVmYXVsdChkZWZWYWx1ZSkKK3sKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4gaW5saW5lCitjb25zdCBWQUxVRSYgRGVmYXVsdEtleWVkVmVjdG9yPEtFWSxWQUxVRT46OnZhbHVlRm9yKGNvbnN0IEtFWSYga2V5KSBjb25zdCB7CisgICAgc3NpemVfdCBpID0gaW5kZXhPZktleShrZXkpOworICAgIHJldHVybiBpID49IDAgPyBLZXllZFZlY3RvcjxLRVksVkFMVUU+Ojp2YWx1ZUF0KGkpIDogbURlZmF1bHQ7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9LRVlFRF9WRUNUT1JfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9MaXN0LmggYi9pbmNsdWRlL3V0aWxzL0xpc3QuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTZiZTlhCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9MaXN0LmgKQEAgLTAsMCArMSwyODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gVGVtcGxhdGVkIGxpc3QgY2xhc3MuICBOb3JtYWxseSB3ZSdkIHVzZSBTVEwsIGJ1dCB3ZSBkb24ndCBoYXZlIHRoYXQuCisvLyBUaGlzIGNsYXNzIG1pbWljcyBTVEwncyBpbnRlcmZhY2VzLgorLy8KKy8vIE9iamVjdHMgYXJlIGNvcGllZCBpbnRvIHRoZSBsaXN0IHdpdGggdGhlICc9JyBvcGVyYXRvciBvciB3aXRoIGNvcHktCisvLyBjb25zdHJ1Y3Rpb24sIHNvIGlmIHRoZSBjb21waWxlcidzIGF1dG8tZ2VuZXJhdGVkIHZlcnNpb25zIHdvbid0IHdvcmsgZm9yCisvLyB5b3UsIGRlZmluZSB5b3VyIG93bi4KKy8vCisvLyBUaGUgb25seSBjbGFzcyB5b3Ugd2FudCB0byB1c2UgZnJvbSBoZXJlIGlzICJMaXN0Ii4gIERvIG5vdCB1c2UgY2xhc3NlcworLy8gc3RhcnRpbmcgd2l0aCAiXyIgZGlyZWN0bHkuCisvLworI2lmbmRlZiBfTElCU19VVElMU19MSVNUX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfTElTVF9ICisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIE9uZSBlbGVtZW50IGluIHRoZSBsaXN0LgorICovCit0ZW1wbGF0ZTxjbGFzcyBUPiBjbGFzcyBfTGlzdE5vZGUgeworcHVibGljOgorICAgIHR5cGVkZWYgX0xpc3ROb2RlPFQ+IF9Ob2RlOworCisgICAgX0xpc3ROb2RlKGNvbnN0IFQmIHZhbCkgOiBtVmFsKHZhbCkge30KKyAgICB+X0xpc3ROb2RlKHZvaWQpIHt9CisKKyAgICBUJiBnZXRSZWYodm9pZCkgeyByZXR1cm4gbVZhbDsgfQorICAgIHZvaWQgc2V0VmFsKGNvbnN0IFQmIHZhbCkgeyBtVmFsID0gdmFsOyB9CisKKyAgICBfTm9kZSogZ2V0UHJldih2b2lkKSBjb25zdCB7IHJldHVybiBtcFByZXY7IH0KKyAgICB2b2lkIHNldFByZXYoX05vZGUqIHB0cikgeyBtcFByZXYgPSBwdHI7IH0KKyAgICBfTm9kZSogZ2V0TmV4dCh2b2lkKSBjb25zdCB7IHJldHVybiBtcE5leHQ7IH0KKyAgICB2b2lkIHNldE5leHQoX05vZGUqIHB0cikgeyBtcE5leHQgPSBwdHI7IH0KKworcHJpdmF0ZToKKyAgICBUICAgICAgICAgICBtVmFsOworICAgIF9Ob2RlKiAgICAgIG1wUHJldjsKKyAgICBfTm9kZSogICAgICBtcE5leHQ7Cit9OworCisvKgorICogSXRlcmF0b3IgZm9yIHdhbGtpbmcgdGhyb3VnaCB0aGUgbGlzdC4KKyAqLwordGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgVHJlZj4gY2xhc3MgX0xpc3RJdGVyYXRvciB7CitwdWJsaWM6CisgICAgdHlwZWRlZiBfTGlzdEl0ZXJhdG9yPFQsVHJlZj4gX0l0ZXI7CisgICAgdHlwZWRlZiBfTGlzdE5vZGU8VD4gX05vZGU7CisKKyAgICBfTGlzdEl0ZXJhdG9yKHZvaWQpIHt9CisgICAgX0xpc3RJdGVyYXRvcihfTm9kZSogcHRyKSA6IG1wTm9kZShwdHIpIHt9CisgICAgfl9MaXN0SXRlcmF0b3Iodm9pZCkge30KKworICAgIC8qCisgICAgICogRGVyZWZlcmVuY2Ugb3BlcmF0b3IuICBVc2VkIHRvIGdldCBhdCB0aGUganVpY3kgaW5zaWRlcy4KKyAgICAgKi8KKyAgICBUcmVmIG9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuIG1wTm9kZS0+Z2V0UmVmKCk7IH0KKworICAgIC8qCisgICAgICogSXRlcmF0b3IgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgX0l0ZXImIHJpZ2h0KSBjb25zdCB7IHJldHVybiBtcE5vZGUgPT0gcmlnaHQubXBOb2RlOyB9CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IF9JdGVyJiByaWdodCkgY29uc3QgeyByZXR1cm4gbXBOb2RlICE9IHJpZ2h0Lm1wTm9kZTsgfQorCisgICAgLyoKKyAgICAgKiBJbmNyL2RlY3IsIHVzZWQgdG8gbW92ZSB0aHJvdWdoIHRoZSBsaXN0LgorICAgICAqLworICAgIF9JdGVyJiBvcGVyYXRvcisrKHZvaWQpIHsgICAgICAgIC8vIHByZS1pbmNyZW1lbnQKKyAgICAgICAgbXBOb2RlID0gbXBOb2RlLT5nZXROZXh0KCk7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgX0l0ZXIgb3BlcmF0b3IrKyhpbnQpIHsgICAgICAgICAgLy8gcG9zdC1pbmNyZW1lbnQKKyAgICAgICAgX0l0ZXIgdG1wID0gKnRoaXM7CisgICAgICAgICsrKnRoaXM7CisgICAgICAgIHJldHVybiB0bXA7CisgICAgfQorICAgIF9JdGVyJiBvcGVyYXRvci0tKHZvaWQpIHsgICAgICAgIC8vIHByZS1pbmNyZW1lbnQKKyAgICAgICAgbXBOb2RlID0gbXBOb2RlLT5nZXRQcmV2KCk7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgX0l0ZXIgb3BlcmF0b3ItLShpbnQpIHsgICAgICAgICAgLy8gcG9zdC1pbmNyZW1lbnQKKyAgICAgICAgX0l0ZXIgdG1wID0gKnRoaXM7CisgICAgICAgIC0tKnRoaXM7CisgICAgICAgIHJldHVybiB0bXA7CisgICAgfQorCisgICAgX05vZGUqIGdldE5vZGUodm9pZCkgY29uc3QgeyByZXR1cm4gbXBOb2RlOyB9CisKK3ByaXZhdGU6CisgICAgX05vZGUqICAgICAgbXBOb2RlOworfTsKKworCisvKgorICogRG91Ymx5LWxpbmtlZCBsaXN0LiAgSW5zdGFudGlhdGUgd2l0aCAiTGlzdDxNeUNsYXNzPiBteUxpc3QiLgorICoKKyAqIE9iamVjdHMgYWRkZWQgdG8gdGhlIGxpc3QgYXJlIGNvcGllZCB1c2luZyB0aGUgYXNzaWdubWVudCBvcGVyYXRvciwKKyAqIHNvIHRoaXMgbXVzdCBiZSBkZWZpbmVkLgorICovCit0ZW1wbGF0ZTxjbGFzcyBUPiBjbGFzcyBMaXN0IHsKK3B1YmxpYzoKKyAgICB0eXBlZGVmIF9MaXN0Tm9kZTxUPiBfTm9kZTsKKworICAgIExpc3Qodm9pZCkgeworICAgICAgICBwcmVwKCk7CisgICAgfQorICAgIExpc3QoY29uc3QgTGlzdDxUPiYgc3JjKSB7ICAgICAgLy8gY29weS1jb25zdHJ1Y3RvcgorICAgICAgICBwcmVwKCk7CisgICAgICAgIGluc2VydChiZWdpbigpLCBzcmMuYmVnaW4oKSwgc3JjLmVuZCgpKTsKKyAgICB9CisgICAgdmlydHVhbCB+TGlzdCh2b2lkKSB7CisgICAgICAgIGNsZWFyKCk7CisgICAgICAgIGRlbGV0ZVtdICh1bnNpZ25lZCBjaGFyKikgbXBNaWRkbGU7CisgICAgfQorCisgICAgdHlwZWRlZiBfTGlzdEl0ZXJhdG9yPFQsVCY+IGl0ZXJhdG9yOworICAgIHR5cGVkZWYgX0xpc3RJdGVyYXRvcjxULCBjb25zdCBUJj4gY29uc3RfaXRlcmF0b3I7CisKKyAgICBMaXN0PFQ+JiBvcGVyYXRvcj0oY29uc3QgTGlzdDxUPiYgcmlnaHQpOworCisgICAgLyogcmV0dXJucyB0cnVlIGlmIHRoZSBsaXN0IGlzIGVtcHR5ICovCisgICAgYm9vbCBlbXB0eSh2b2lkKSBjb25zdCB7IHJldHVybiBtcE1pZGRsZS0+Z2V0TmV4dCgpID09IG1wTWlkZGxlOyB9CisKKyAgICAvKiByZXR1cm4gI29mIGVsZW1lbnRzIGluIGxpc3QgKi8KKyAgICB1bnNpZ25lZCBpbnQgc2l6ZSh2b2lkKSBjb25zdCB7CisgICAgICAgIHJldHVybiBkaXN0YW5jZShiZWdpbigpLCBlbmQoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGVsZW1lbnQgb3Igb25lIHBhc3QgdGhlIGxhc3QgZWxlbWVudC4gIFRoZQorICAgICAqIF9MaXN0Tm9kZSogd2UncmUgcmV0dXJuaW5nIGlzIGNvbnZlcnRlZCB0byBhbiAiaXRlcmF0b3IiIGJ5IGEKKyAgICAgKiBjb25zdHJ1Y3RvciBpbiBfTGlzdEl0ZXJhdG9yLgorICAgICAqLworICAgIGl0ZXJhdG9yIGJlZ2luKCkgICAgICAgICAgICAgICAgeyByZXR1cm4gbXBNaWRkbGUtPmdldE5leHQoKTsgfQorICAgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkgY29uc3QgICAgeyByZXR1cm4gbXBNaWRkbGUtPmdldE5leHQoKTsgfQorICAgIGl0ZXJhdG9yIGVuZCgpICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbXBNaWRkbGU7IH0KKyAgICBjb25zdF9pdGVyYXRvciBlbmQoKSBjb25zdCAgICAgIHsgcmV0dXJuIG1wTWlkZGxlOyB9CisKKyAgICAvKiBhZGQgdGhlIG9iamVjdCB0byB0aGUgaGVhZCBvciB0YWlsIG9mIHRoZSBsaXN0ICovCisgICAgdm9pZCBwdXNoX2Zyb250KGNvbnN0IFQmIHZhbCkgeyBpbnNlcnQoYmVnaW4oKSwgdmFsKTsgfQorICAgIHZvaWQgcHVzaF9iYWNrKGNvbnN0IFQmIHZhbCkgeyBpbnNlcnQoZW5kKCksIHZhbCk7IH0KKworICAgIC8qIGluc2VydCBiZWZvcmUgdGhlIGN1cnJlbnQgbm9kZTsgcmV0dXJucyBpdGVyYXRvciBhdCBuZXcgbm9kZSAqLworICAgIGl0ZXJhdG9yIGluc2VydChpdGVyYXRvciBwb3NuLCBjb25zdCBUJiB2YWwpIHsKKyAgICAgICAgX05vZGUqIG5ld05vZGUgPSBuZXcgX05vZGUodmFsKTsgICAgICAgIC8vIGFsbG9jICYgY29weS1jb25zdHJ1Y3QKKyAgICAgICAgbmV3Tm9kZS0+c2V0TmV4dChwb3NuLmdldE5vZGUoKSk7CisgICAgICAgIG5ld05vZGUtPnNldFByZXYocG9zbi5nZXROb2RlKCktPmdldFByZXYoKSk7CisgICAgICAgIHBvc24uZ2V0Tm9kZSgpLT5nZXRQcmV2KCktPnNldE5leHQobmV3Tm9kZSk7CisgICAgICAgIHBvc24uZ2V0Tm9kZSgpLT5zZXRQcmV2KG5ld05vZGUpOworICAgICAgICByZXR1cm4gbmV3Tm9kZTsKKyAgICB9CisKKyAgICAvKiBpbnNlcnQgYSByYW5nZSBvZiBlbGVtZW50cyBiZWZvcmUgdGhlIGN1cnJlbnQgbm9kZSAqLworICAgIHZvaWQgaW5zZXJ0KGl0ZXJhdG9yIHBvc24sIGNvbnN0X2l0ZXJhdG9yIGZpcnN0LCBjb25zdF9pdGVyYXRvciBsYXN0KSB7CisgICAgICAgIGZvciAoIDsgZmlyc3QgIT0gbGFzdDsgKytmaXJzdCkKKyAgICAgICAgICAgIGluc2VydChwb3NuLCAqZmlyc3QpOworICAgIH0KKworICAgIC8qIHJlbW92ZSBvbmUgZW50cnk7IHJldHVybnMgaXRlcmF0b3IgYXQgbmV4dCBub2RlICovCisgICAgaXRlcmF0b3IgZXJhc2UoaXRlcmF0b3IgcG9zbikgeworICAgICAgICBfTm9kZSogcE5leHQgPSBwb3NuLmdldE5vZGUoKS0+Z2V0TmV4dCgpOworICAgICAgICBfTm9kZSogcFByZXYgPSBwb3NuLmdldE5vZGUoKS0+Z2V0UHJldigpOworICAgICAgICBwUHJldi0+c2V0TmV4dChwTmV4dCk7CisgICAgICAgIHBOZXh0LT5zZXRQcmV2KHBQcmV2KTsKKyAgICAgICAgZGVsZXRlIHBvc24uZ2V0Tm9kZSgpOworICAgICAgICByZXR1cm4gcE5leHQ7CisgICAgfQorCisgICAgLyogcmVtb3ZlIGEgcmFuZ2Ugb2YgZWxlbWVudHMgKi8KKyAgICBpdGVyYXRvciBlcmFzZShpdGVyYXRvciBmaXJzdCwgaXRlcmF0b3IgbGFzdCkgeworICAgICAgICB3aGlsZSAoZmlyc3QgIT0gbGFzdCkKKyAgICAgICAgICAgIGVyYXNlKGZpcnN0KyspOyAgICAgLy8gZG9uJ3QgZXJhc2UgdGhhbiBpbmNyIGxhdGVyIQorICAgICAgICByZXR1cm4gbGFzdDsKKyAgICB9CisKKyAgICAvKiByZW1vdmUgYWxsIGNvbnRlbnRzIG9mIHRoZSBsaXN0ICovCisgICAgdm9pZCBjbGVhcih2b2lkKSB7CisgICAgICAgIF9Ob2RlKiBwQ3VycmVudCA9IG1wTWlkZGxlLT5nZXROZXh0KCk7CisgICAgICAgIF9Ob2RlKiBwTmV4dDsKKworICAgICAgICB3aGlsZSAocEN1cnJlbnQgIT0gbXBNaWRkbGUpIHsKKyAgICAgICAgICAgIHBOZXh0ID0gcEN1cnJlbnQtPmdldE5leHQoKTsKKyAgICAgICAgICAgIGRlbGV0ZSBwQ3VycmVudDsKKyAgICAgICAgICAgIHBDdXJyZW50ID0gcE5leHQ7CisgICAgICAgIH0KKyAgICAgICAgbXBNaWRkbGUtPnNldFByZXYobXBNaWRkbGUpOworICAgICAgICBtcE1pZGRsZS0+c2V0TmV4dChtcE1pZGRsZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBNZWFzdXJlIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBpdGVyYXRvcnMuICBPbiBleGlzdCwgImZpcnN0IgorICAgICAqIHdpbGwgYmUgZXF1YWwgdG8gImxhc3QiLiAgVGhlIGl0ZXJhdG9ycyBtdXN0IHJlZmVyIHRvIHRoZSBzYW1lCisgICAgICogbGlzdC4KKyAgICAgKgorICAgICAqIChUaGlzIGlzIGFjdHVhbGx5IGEgZ2VuZXJpYyBpdGVyYXRvciBmdW5jdGlvbi4gIEl0IHNob3VsZCBiZSBwYXJ0CisgICAgICogb2Ygc29tZSBvdGhlciBjbGFzcywgcG9zc2libHkgYW4gaXRlcmF0b3IgYmFzZSBjbGFzcy4gIEl0IG5lZWRzIHRvCisgICAgICoga25vdyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGEgbGlzdCwgd2hpY2ggaGFzIHRvIG1hcmNoIHRocm91Z2gsCisgICAgICogYW5kIGEgdmVjdG9yLCB3aGljaCBjYW4ganVzdCBkbyBwb2ludGVyIG1hdGguKQorICAgICAqLworICAgIHVuc2lnbmVkIGludCBkaXN0YW5jZShpdGVyYXRvciBmaXJzdCwgaXRlcmF0b3IgbGFzdCkgeworICAgICAgICB1bnNpZ25lZCBpbnQgY291bnQgPSAwOworICAgICAgICB3aGlsZSAoZmlyc3QgIT0gbGFzdCkgeworICAgICAgICAgICAgKytmaXJzdDsKKyAgICAgICAgICAgICsrY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50OworICAgIH0KKyAgICB1bnNpZ25lZCBpbnQgZGlzdGFuY2UoY29uc3RfaXRlcmF0b3IgZmlyc3QsIGNvbnN0X2l0ZXJhdG9yIGxhc3QpIGNvbnN0IHsKKyAgICAgICAgdW5zaWduZWQgaW50IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKGZpcnN0ICE9IGxhc3QpIHsKKyAgICAgICAgICAgICsrZmlyc3Q7CisgICAgICAgICAgICArK2NvdW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgLyoKKyAgICAgKiBJIHdhbnQgYSBfTGlzdE5vZGUgYnV0IGRvbid0IG5lZWQgaXQgdG8gaG9sZCB2YWxpZCBkYXRhLiAgTW9yZQorICAgICAqIHRvIHRoZSBwb2ludCwgSSBkb24ndCB3YW50IFQncyBjb25zdHJ1Y3RvciB0byBmaXJlLCBzaW5jZSBpdAorICAgICAqIG1pZ2h0IGhhdmUgc2lkZS1lZmZlY3RzIG9yIHJlcXVpcmUgYXJndW1lbnRzLiAgU28sIHdlIGRvIHRoaXMKKyAgICAgKiBzbGlnaHRseSB1bmNvdXRoIHN0b3JhZ2UgYWxsb2MuCisgICAgICovCisgICAgdm9pZCBwcmVwKHZvaWQpIHsKKyAgICAgICAgbXBNaWRkbGUgPSAoX05vZGUqKSBuZXcgdW5zaWduZWQgY2hhcltzaXplb2YoX05vZGUpXTsKKyAgICAgICAgbXBNaWRkbGUtPnNldFByZXYobXBNaWRkbGUpOworICAgICAgICBtcE1pZGRsZS0+c2V0TmV4dChtcE1pZGRsZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIG5vZGUgcGxheXMgdGhlIHJvbGUgb2YgInBvaW50ZXIgdG8gaGVhZCIgYW5kICJwb2ludGVyIHRvIHRhaWwiLgorICAgICAqIEl0IHNpdHMgaW4gdGhlIG1pZGRsZSBvZiBhIGNpcmN1bGFyIGxpc3Qgb2Ygbm9kZXMuICBUaGUgaXRlcmF0b3IKKyAgICAgKiBydW5zIGFyb3VuZCB0aGUgY2lyY2xlIHVudGlsIGl0IGVuY291bnRlcnMgdGhpcyBvbmUuCisgICAgICovCisgICAgX05vZGUqICAgICAgbXBNaWRkbGU7Cit9OworCisvKgorICogQXNzaWdubWVudCBvcGVyYXRvci4KKyAqCisgKiBUaGUgc2ltcGxlc3Qgd2F5IHRvIGRvIHRoaXMgd291bGQgYmUgdG8gY2xlYXIgb3V0IHRoZSB0YXJnZXQgbGlzdCBhbmQKKyAqIGZpbGwgaXQgd2l0aCB0aGUgc291cmNlLiAgSG93ZXZlciwgd2UgY2FuIHNwZWVkIHRoaW5ncyBhbG9uZyBieQorICogcmUtdXNpbmcgZXhpc3RpbmcgZWxlbWVudHMuCisgKi8KK3RlbXBsYXRlPGNsYXNzIFQ+CitMaXN0PFQ+JiBMaXN0PFQ+OjpvcGVyYXRvcj0oY29uc3QgTGlzdDxUPiYgcmlnaHQpCit7CisgICAgaWYgKHRoaXMgPT0gJnJpZ2h0KQorICAgICAgICByZXR1cm4gKnRoaXM7ICAgICAgIC8vIHNlbGYtYXNzaWdubWVudAorICAgIGl0ZXJhdG9yIGZpcnN0RHN0ID0gYmVnaW4oKTsKKyAgICBpdGVyYXRvciBsYXN0RHN0ID0gZW5kKCk7CisgICAgY29uc3RfaXRlcmF0b3IgZmlyc3RTcmMgPSByaWdodC5iZWdpbigpOworICAgIGNvbnN0X2l0ZXJhdG9yIGxhc3RTcmMgPSByaWdodC5lbmQoKTsKKyAgICB3aGlsZSAoZmlyc3RTcmMgIT0gbGFzdFNyYyAmJiBmaXJzdERzdCAhPSBsYXN0RHN0KQorICAgICAgICAqZmlyc3REc3QrKyA9ICpmaXJzdFNyYysrOworICAgIGlmIChmaXJzdFNyYyA9PSBsYXN0U3JjKSAgICAgICAgLy8gcmFuIG91dCBvZiBlbGVtZW50cyBpbiBzb3VyY2U/CisgICAgICAgIGVyYXNlKGZpcnN0RHN0LCBsYXN0RHN0KTsgICAvLyB5ZXMsIGVyYXNlIGFueSBleHRyYXMKKyAgICBlbHNlCisgICAgICAgIGluc2VydChsYXN0RHN0LCBmaXJzdFNyYywgbGFzdFNyYyk7ICAgICAvLyBjb3B5IHJlbWFpbmluZyBvdmVyCisgICAgcmV0dXJuICp0aGlzOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gX0xJQlNfVVRJTFNfTElTVF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0xvZy5oIGIvaW5jbHVkZS91dGlscy9Mb2cuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzZjYzhiCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9Mb2cuaApAQCAtMCwwICsxLDMzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEMvQysrIGxvZ2dpbmcgZnVuY3Rpb25zLiAgU2VlIHRoZSBsb2dnaW5nIGRvY3VtZW50YXRpb24gZm9yIEFQSSBkZXRhaWxzLgorLy8KKy8vIFdlJ2QgbGlrZSB0aGVzZSB0byBiZSBhdmFpbGFibGUgZnJvbSBDIGNvZGUgKGluIGNhc2Ugd2UgaW1wb3J0IHNvbWUgZnJvbQorLy8gc29tZXdoZXJlKSwgc28gdGhpcyBoYXMgYSBDIGludGVyZmFjZS4KKy8vCisvLyBUaGUgb3V0cHV0IHdpbGwgYmUgY29ycmVjdCB3aGVuIHRoZSBsb2cgZmlsZSBpcyBzaGFyZWQgYmV0d2VlbiBtdWx0aXBsZQorLy8gdGhyZWFkcyBhbmQvb3IgbXVsdGlwbGUgcHJvY2Vzc2VzIHNvIGxvbmcgYXMgdGhlIG9wZXJhdGluZyBzeXN0ZW0KKy8vIHN1cHBvcnRzIE9fQVBQRU5ELiAgVGhlc2UgY2FsbHMgaGF2ZSBtdXRleC1wcm90ZWN0ZWQgZGF0YSBzdHJ1Y3R1cmVzCisvLyBhbmQgc28gYXJlIE5PVCByZWVudHJhbnQuICBEbyBub3QgdXNlIExPRyBpbiBhIHNpZ25hbCBoYW5kbGVyLgorLy8KKyNpZm5kZWYgX0xJQlNfVVRJTFNfTE9HX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfTE9HX0gKKworI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKworI2VuZGlmIC8vIF9MSUJTX1VUSUxTX0xPR19ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL0xvZ1NvY2tldC5oIGIvaW5jbHVkZS91dGlscy9Mb2dTb2NrZXQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWZiZmI1Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9Mb2dTb2NrZXQuaApAQCAtMCwwICsxLDIwIEBACisvKiB1dGlscy9Mb2dTb2NrZXQuaAorKiogCisqKiBDb3B5cmlnaHQgMjAwOCwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIFRoaXMgZmlsZSBpcyBkdWFsIGxpY2Vuc2VkLiAgSXQgbWF5IGJlIHJlZGlzdHJpYnV0ZWQgYW5kL29yIG1vZGlmaWVkCisqKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEFwYWNoZSAyLjAgTGljZW5zZSBPUiB2ZXJzaW9uIDIgb2YgdGhlIEdOVQorKiogR2VuZXJhbCBQdWJsaWMgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgX1VUSUxTX0xPR1NPQ0tFVF9ICisjZGVmaW5lIF9VVElMU19MT0dTT0NLRVRfSAorCisjZGVmaW5lIFNPQ0tFVF9DTE9TRV9MT0NBTCAwCisKK3ZvaWQgYWRkX3NlbmRfc3RhdHMoaW50IGZkLCBpbnQgc2VuZCk7Cit2b2lkIGFkZF9yZWN2X3N0YXRzKGludCBmZCwgaW50IHJlY3YpOwordm9pZCBsb2dfc29ja2V0X2Nsb3NlKGludCBmZCwgc2hvcnQgcmVhc29uKTsKK3ZvaWQgbG9nX3NvY2tldF9jb25uZWN0KGludCBmZCwgdW5zaWduZWQgaW50IGlwLCB1bnNpZ25lZCBzaG9ydCBwb3J0KTsKKworI2VuZGlmIC8qIF9VVElMU19MT0dTT0NLRVRfSCAqLwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9NZW1vcnlCYXNlLmggYi9pbmNsdWRlL3V0aWxzL01lbW9yeUJhc2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjVhOWQyCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9NZW1vcnlCYXNlLmgKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9NRU1PUllfQkFTRV9ICisjZGVmaW5lIEFORFJPSURfTUVNT1JZX0JBU0VfSAorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTWVtb3J5QmFzZSA6IHB1YmxpYyBCbk1lbW9yeSAKK3sKK3B1YmxpYzoKKyAgICBNZW1vcnlCYXNlKGNvbnN0IHNwPElNZW1vcnlIZWFwPiYgaGVhcCwgc3NpemVfdCBvZmZzZXQsIHNpemVfdCBzaXplKTsKKyAgICB2aXJ0dWFsIH5NZW1vcnlCYXNlKCk7CisgICAgdmlydHVhbCBzcDxJTWVtb3J5SGVhcD4gZ2V0TWVtb3J5KHNzaXplX3QqIG9mZnNldCwgc2l6ZV90KiBzaXplKSBjb25zdDsKKworcHJvdGVjdGVkOgorICAgIHNpemVfdCBnZXRTaXplKCkgY29uc3QgeyByZXR1cm4gbVNpemU7IH0KKyAgICBzc2l6ZV90IGdldE9mZnNldCgpIGNvbnN0IHsgcmV0dXJuIG1PZmZzZXQ7IH0KKyAgICBjb25zdCBzcDxJTWVtb3J5SGVhcD4mIGdldEhlYXAoKSBjb25zdCB7IHJldHVybiBtSGVhcDsgfQorCitwcml2YXRlOgorICAgIHNpemVfdCAgICAgICAgICBtU2l6ZTsKKyAgICBzc2l6ZV90ICAgICAgICAgbU9mZnNldDsKKyAgICBzcDxJTWVtb3J5SGVhcD4gbUhlYXA7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX01FTU9SWV9CQVNFX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvTWVtb3J5RGVhbGVyLmggYi9pbmNsdWRlL3V0aWxzL01lbW9yeURlYWxlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1NGI2MjcKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL01lbW9yeURlYWxlci5oCkBAIC0wLDAgKzEsMjM4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX01FTU9SWV9ERUFMRVJfSAorI2RlZmluZSBBTkRST0lEX01FTU9SWV9ERUFMRVJfSAorCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5SGVhcEJhc2UuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorY2xhc3MgU3RyaW5nODsKKworLyoKKyAqIGludGVyZmFjZSBmb3IgaW1wbGVtZW50aW5nIGEgImhlYXAiLiBBIGhlYXAgYmFzaWNhbGx5IHByb3ZpZGVzCisgKiB0aGUgSU1lbW9yeUhlYXAgaW50ZXJmYWNlIGZvciBjcm9zcy1wcm9jZXNzIHNoYXJpbmcgYW5kIHRoZQorICogYWJpbGl0eSB0byBtYXAvdW5tYXAgcGFnZXMgd2l0aGluIHRoZSBoZWFwLgorICovCitjbGFzcyBIZWFwSW50ZXJmYWNlIDogcHVibGljIHZpcnR1YWwgQm5NZW1vcnlIZWFwCit7CitwdWJsaWM6CisgICAgLy8gYWxsIHZhbHVlcyBtdXN0IGJlIHBhZ2UtYWxpZ25lZAorICAgIHZpcnR1YWwgc3A8SU1lbW9yeT4gbWFwTWVtb3J5KHNpemVfdCBvZmZzZXQsIHNpemVfdCBzaXplKSA9IDA7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8qCisgKiBpbnRlcmZhY2UgZm9yIGltcGxlbWVudGluZyBhbiBhbGxvY2F0b3IuIEFuIGFsbG9jYXRvciBwcm92aWRlcworICogbWV0aG9kcyBmb3IgYWxsb2NhdGluZyBhbmQgZnJlZWluZyBtZW1vcnkgYmxvY2tzIGFuZCBkdW1waW5nCisgKiBpdHMgc3RhdGUuCisgKi8KK2NsYXNzIEFsbG9jYXRvckludGVyZmFjZSA6IHB1YmxpYyBSZWZCYXNlCit7CitwdWJsaWM6CisgICAgZW51bSB7CisgICAgICAgIFBBR0VfQUxJR05FRCA9IDB4MDAwMDAwMDEKKyAgICB9OworCisgICAgdmlydHVhbCBzaXplX3QgICAgICBhbGxvY2F0ZShzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MgPSAwKSA9IDA7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkZWFsbG9jYXRlKHNpemVfdCBvZmZzZXQpID0gMDsKKyAgICB2aXJ0dWFsIHNpemVfdCAgICAgIHNpemUoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBkdW1wKGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzID0gMCkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgZHVtcChTdHJpbmc4JiByZXMsCisgICAgICAgICAgICBjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncyA9IDApIGNvbnN0ID0gMDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLyoKKyAqIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIEhlYXBJbnRlcmZhY2Ugb24gdG9wIG9mIG1tYXAoKSAKKyAqLworY2xhc3MgU2hhcmVkSGVhcCA6IHB1YmxpYyBIZWFwSW50ZXJmYWNlLCBwdWJsaWMgTWVtb3J5SGVhcEJhc2UKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgIFNoYXJlZEhlYXAoc2l6ZV90IHNpemUsIHVpbnQzMl90IGZsYWdzID0gMCwgY2hhciBjb25zdCAqIG5hbWUgPSBOVUxMKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5TaGFyZWRIZWFwKCk7CisgICAgdmlydHVhbCBzcDxJTWVtb3J5PiBtYXBNZW1vcnkoc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvKgorICogQSBzaW1wbGUgdGVtcGxhdGl6ZWQgZG91Ymx5IGxpbmtlZC1saXN0IGltcGxlbWVudGF0aW9uCisgKi8KKwordGVtcGxhdGUgPHR5cGVuYW1lIE5PREU+CitjbGFzcyBMaW5rZWRMaXN0Cit7CisgICAgTk9ERSogIG1GaXJzdDsKKyAgICBOT0RFKiAgbUxhc3Q7CisKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICBMaW5rZWRMaXN0KCkgOiBtRmlyc3QoMCksIG1MYXN0KDApIHsgfQorICAgIGJvb2wgICAgICAgIGlzRW1wdHkoKSBjb25zdCB7IHJldHVybiBtRmlyc3QgPT0gMDsgfQorICAgIE5PREUgY29uc3QqIGhlYWQoKSBjb25zdCB7IHJldHVybiBtRmlyc3Q7IH0KKyAgICBOT0RFKiAgICAgICBoZWFkKCkgeyByZXR1cm4gbUZpcnN0OyB9CisgICAgTk9ERSBjb25zdCogdGFpbCgpIGNvbnN0IHsgcmV0dXJuIG1MYXN0OyB9CisgICAgTk9ERSogICAgICAgdGFpbCgpIHsgcmV0dXJuIG1MYXN0OyB9CisKKyAgICB2b2lkIGluc2VydEFmdGVyKE5PREUqIG5vZGUsIE5PREUqIG5ld05vZGUpIHsKKyAgICAgICAgbmV3Tm9kZS0+cHJldiA9IG5vZGU7CisgICAgICAgIG5ld05vZGUtPm5leHQgPSBub2RlLT5uZXh0OworICAgICAgICBpZiAobm9kZS0+bmV4dCA9PSAwKSBtTGFzdCA9IG5ld05vZGU7CisgICAgICAgIGVsc2UgICAgICAgICAgICAgICAgIG5vZGUtPm5leHQtPnByZXYgPSBuZXdOb2RlOworICAgICAgICBub2RlLT5uZXh0ID0gbmV3Tm9kZTsKKyAgICB9CisKKyAgICB2b2lkIGluc2VydEJlZm9yZShOT0RFKiBub2RlLCBOT0RFKiBuZXdOb2RlKSB7CisgICAgICAgICBuZXdOb2RlLT5wcmV2ID0gbm9kZS0+cHJldjsKKyAgICAgICAgIG5ld05vZGUtPm5leHQgPSBub2RlOworICAgICAgICAgaWYgKG5vZGUtPnByZXYgPT0gMCkgICBtRmlyc3QgPSBuZXdOb2RlOworICAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICBub2RlLT5wcmV2LT5uZXh0ID0gbmV3Tm9kZTsKKyAgICAgICAgIG5vZGUtPnByZXYgPSBuZXdOb2RlOworICAgIH0KKworICAgIHZvaWQgaW5zZXJ0SGVhZChOT0RFKiBuZXdOb2RlKSB7CisgICAgICAgIGlmIChtRmlyc3QgPT0gMCkgeworICAgICAgICAgICAgbUZpcnN0ID0gbUxhc3QgPSBuZXdOb2RlOworICAgICAgICAgICAgbmV3Tm9kZS0+cHJldiA9IG5ld05vZGUtPm5leHQgPSAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW5zZXJ0QmVmb3JlKG1GaXJzdCwgbmV3Tm9kZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgdm9pZCBpbnNlcnRUYWlsKE5PREUqIG5ld05vZGUpIHsKKyAgICAgICAgaWYgKG1MYXN0ID09IDApIGluc2VydEJlZ2lubmluZyhuZXdOb2RlKTsKKyAgICAgICAgZWxzZSAgICAgICAgICAgIGluc2VydEFmdGVyKG1MYXN0LCBuZXdOb2RlKTsKKyAgICB9CisKKyAgICBOT0RFKiByZW1vdmUoTk9ERSogbm9kZSkgeworICAgICAgICBpZiAobm9kZS0+cHJldiA9PSAwKSAgICBtRmlyc3QgPSBub2RlLT5uZXh0OworICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICBub2RlLT5wcmV2LT5uZXh0ID0gbm9kZS0+bmV4dDsKKyAgICAgICAgaWYgKG5vZGUtPm5leHQgPT0gMCkgICAgbUxhc3QgPSBub2RlLT5wcmV2OworICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICBub2RlLT5uZXh0LT5wcmV2ID0gbm9kZS0+cHJldjsKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorfTsKKworCisvKgorICogY29uY3JldGUgaW1wbGVtZW50YXRpb24gb2YgQWxsb2NhdG9ySW50ZXJmYWNlIHVzaW5nIGEgc2ltcGxlCisgKiBiZXN0LWZpdCBhbGxvY2F0aW9uIHNjaGVtZQorICovCitjbGFzcyBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yIDogcHVibGljIEFsbG9jYXRvckludGVyZmFjZQoreworcHVibGljOgorCisgICAgICAgICAgICAgICAgICAgICAgICBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yKHNpemVfdCBzaXplKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5TaW1wbGVCZXN0Rml0QWxsb2NhdG9yKCk7CisKKyAgICB2aXJ0dWFsIHNpemVfdCAgICAgIGFsbG9jYXRlKHNpemVfdCBzaXplLCB1aW50MzJfdCBmbGFncyA9IDApOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZGVhbGxvY2F0ZShzaXplX3Qgb2Zmc2V0KTsKKyAgICB2aXJ0dWFsIHNpemVfdCAgICAgIHNpemUoKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGR1bXAoY29uc3QgY2hhciogd2hhdCwgdWludDMyX3QgZmxhZ3MgPSAwKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGR1bXAoU3RyaW5nOCYgcmVzLAorICAgICAgICAgICAgY29uc3QgY2hhciogd2hhdCwgdWludDMyX3QgZmxhZ3MgPSAwKSBjb25zdDsKKworcHJpdmF0ZToKKworICAgIHN0cnVjdCBjaHVua190IHsKKyAgICAgICAgY2h1bmtfdChzaXplX3Qgc3RhcnQsIHNpemVfdCBzaXplKSAKKyAgICAgICAgICAgIDogc3RhcnQoc3RhcnQpLCBzaXplKHNpemUpLCBmcmVlKDEpLCBwcmV2KDApLCBuZXh0KDApIHsKKyAgICAgICAgfQorICAgICAgICBzaXplX3QgICAgICAgICAgICAgIHN0YXJ0OworICAgICAgICBzaXplX3QgICAgICAgICAgICAgIHNpemUgOiAyODsKKyAgICAgICAgaW50ICAgICAgICAgICAgICAgICBmcmVlIDogNDsKKyAgICAgICAgbXV0YWJsZSBjaHVua190KiAgICBwcmV2OworICAgICAgICBtdXRhYmxlIGNodW5rX3QqICAgIG5leHQ7CisgICAgfTsKKworICAgIHNzaXplX3QgIGFsbG9jKHNpemVfdCBzaXplLCB1aW50MzJfdCBmbGFncyk7CisgICAgY2h1bmtfdCogZGVhbGxvYyhzaXplX3Qgc3RhcnQpOworICAgIHZvaWQgICAgIGR1bXBfbChjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncyA9IDApIGNvbnN0OworICAgIHZvaWQgICAgIGR1bXBfbChTdHJpbmc4JiByZXMsIGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzID0gMCkgY29uc3Q7CisKKyAgICBzdGF0aWMgY29uc3QgaW50ICAgIGtNZW1vcnlBbGlnbjsKKyAgICBtdXRhYmxlIE11dGV4ICAgICAgIG1Mb2NrOworICAgIExpbmtlZExpc3Q8Y2h1bmtfdD4gbUxpc3Q7CisgICAgc2l6ZV90ICAgICAgICAgICAgICBtSGVhcFNpemU7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIE1lbW9yeURlYWxlciA6IHB1YmxpYyBSZWZCYXNlCit7CitwdWJsaWM6CisKKyAgICBlbnVtIHsKKyAgICAgICAgUkVBRF9PTkxZID0gTWVtb3J5SGVhcEJhc2U6OlJFQURfT05MWSwKKyAgICAgICAgUEFHRV9BTElHTkVEID0gQWxsb2NhdG9ySW50ZXJmYWNlOjpQQUdFX0FMSUdORUQKKyAgICB9OworCisgICAgLy8gY3JlYXRlcyBhIG1lbW9yeSBkZWFsZXIgd2l0aCB0aGUgU2hhcmVkSGVhcCBhbmQgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcgorICAgIE1lbW9yeURlYWxlcihzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MgPSAwLCBjb25zdCBjaGFyKiBuYW1lID0gMCk7CisKKyAgICAvLyBwcm92aWRlIGEgY3VzdG9tIGhlYXAgYnV0IHVzZSB0aGUgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcgorICAgIE1lbW9yeURlYWxlcihjb25zdCBzcDxIZWFwSW50ZXJmYWNlPiYgaGVhcCk7CisKKyAgICAvLyBwcm92aWRlIGJvdGggY3VzdG9tIGhlYXAgYW5kIGFsbG9jb3RhcgorICAgIE1lbW9yeURlYWxlcigKKyAgICAgICAgICAgIGNvbnN0IHNwPEhlYXBJbnRlcmZhY2U+JiBoZWFwLAorICAgICAgICAgICAgY29uc3Qgc3A8QWxsb2NhdG9ySW50ZXJmYWNlPiYgYWxsb2NhdG9yKTsKKworICAgIHZpcnR1YWwgfk1lbW9yeURlYWxlcigpOworCisgICAgdmlydHVhbCBzcDxJTWVtb3J5PiBhbGxvY2F0ZShzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MgPSAwKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGRlYWxsb2NhdGUoc2l6ZV90IG9mZnNldCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBkdW1wKGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzID0gMCkgY29uc3Q7CisKKworICAgIHNwPElNZW1vcnlIZWFwPiBnZXRNZW1vcnlIZWFwKCkgY29uc3QgeyByZXR1cm4gaGVhcCgpOyB9CisgICAgc3A8QWxsb2NhdG9ySW50ZXJmYWNlPiBnZXRBbGxvY2F0b3IoKSBjb25zdCB7IHJldHVybiBhbGxvY2F0b3IoKTsgfQorCitwcml2YXRlOiAgICAKKyAgICBjb25zdCBzcDxIZWFwSW50ZXJmYWNlPiYgICAgICAgIGhlYXAoKSBjb25zdDsKKyAgICBjb25zdCBzcDxBbGxvY2F0b3JJbnRlcmZhY2U+JiAgIGFsbG9jYXRvcigpIGNvbnN0OworCisgICAgY2xhc3MgQWxsb2NhdGlvbiA6IHB1YmxpYyBCbk1lbW9yeSB7CisgICAgcHVibGljOgorICAgICAgICBBbGxvY2F0aW9uKGNvbnN0IHNwPE1lbW9yeURlYWxlcj4mIGRlYWxlciwKKyAgICAgICAgICAgICAgICBzc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUsIGNvbnN0IHNwPElNZW1vcnk+JiBtZW1vcnkpOworICAgICAgICB2aXJ0dWFsIH5BbGxvY2F0aW9uKCk7CisgICAgICAgIHZpcnR1YWwgc3A8SU1lbW9yeUhlYXA+IGdldE1lbW9yeShzc2l6ZV90KiBvZmZzZXQsIHNpemVfdCogc2l6ZSkgY29uc3Q7CisgICAgcHJpdmF0ZToKKyAgICAgICAgc3A8TWVtb3J5RGVhbGVyPiAgICAgICAgbURlYWxlcjsKKyAgICAgICAgc3NpemVfdCAgICAgICAgICAgICAgICAgbU9mZnNldDsKKyAgICAgICAgc2l6ZV90ICAgICAgICAgICAgICAgICAgbVNpemU7CisgICAgICAgIHNwPElNZW1vcnk+ICAgICAgICAgICAgIG1NZW1vcnk7CisgICAgfTsKKworICAgIHNwPEhlYXBJbnRlcmZhY2U+ICAgICAgICAgICBtSGVhcDsKKyAgICBzcDxBbGxvY2F0b3JJbnRlcmZhY2U+ICAgICAgbUFsbG9jYXRvcjsKK307CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfTUVNT1JZX0RFQUxFUl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL01lbW9yeUhlYXBCYXNlLmggYi9pbmNsdWRlL3V0aWxzL01lbW9yeUhlYXBCYXNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc0YWNmNAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvTWVtb3J5SGVhcEJhc2UuaApAQCAtMCwwICsxLDk4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX01FTU9SWV9IRUFQX0JBU0VfSAorI2RlZmluZSBBTkRST0lEX01FTU9SWV9IRUFQX0JBU0VfSAorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTWVtb3J5SGVhcEJhc2UgOiBwdWJsaWMgdmlydHVhbCBCbk1lbW9yeUhlYXAgCit7CitwdWJsaWM6CisgICAgZW51bSB7CisgICAgICAgIFJFQURfT05MWSA9IElNZW1vcnlIZWFwOjpSRUFEX09OTFksCisgICAgICAgIE1BUF9PTkNFID0gSU1lbW9yeUhlYXA6Ok1BUF9PTkNFLAorICAgICAgICAvLyBtZW1vcnkgd29uJ3QgYmUgbWFwcGVkIGxvY2FsbHksIGJ1dCB3aWxsIGJlIG1hcHBlZCBpbiB0aGUgcmVtb3RlCisgICAgICAgIC8vIHByb2Nlc3MuCisgICAgICAgIERPTlRfTUFQX0xPQ0FMTFkgPSAweDAwMDAwMTAwCisgICAgfTsKKworICAgIC8qIAorICAgICAqIG1hcHMgdGhlIG1lbW9yeSByZWZlcmVuY2VkIGJ5IGZkLiBidXQgRE9FU04nVCB0YWtlIG93bmVyc2hpcAorICAgICAqIG9mIHRoZSBmaWxlZGVzY3JpcHRvciAoaXQgbWFrZXMgYSBjb3B5IHdpdGggZHVwKCkKKyAgICAgKi8KKyAgICBNZW1vcnlIZWFwQmFzZShpbnQgZmQsIHNpemVfdCBzaXplLCB1aW50MzJfdCBmbGFncyA9IDApOworICAgIAorICAgIC8qCisgICAgICogbWFwcyBtZW1vcnkgZnJvbSB0aGUgZ2l2ZW4gZGV2aWNlCisgICAgICovCisgICAgTWVtb3J5SGVhcEJhc2UoY29uc3QgY2hhciogZGV2aWNlLCBzaXplX3Qgc2l6ZSA9IDAsIHVpbnQzMl90IGZsYWdzID0gMCk7CisKKyAgICAvKgorICAgICAqIG1hcHMgbWVtb3J5IGZyb20gYXNobWVtLCB3aXRoIHRoZSBnaXZlbiBuYW1lIGZvciBkZWJ1Z2dpbmcKKyAgICAgKi8KKyAgICBNZW1vcnlIZWFwQmFzZShzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MgPSAwLCBjaGFyIGNvbnN0KiBuYW1lID0gTlVMTCk7CisKKyAgICB2aXJ0dWFsIH5NZW1vcnlIZWFwQmFzZSgpOworCisgICAgLyogaW1wbGVtZW50IElNZW1vcnlIZWFwIGludGVyZmFjZSAqLworICAgIHZpcnR1YWwgaW50ICAgICAgICAgZ2V0SGVhcElEKCkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkKiAgICAgICBnZXRCYXNlKCkgY29uc3Q7CisgICAgdmlydHVhbCBzaXplX3QgICAgICBnZXRTaXplKCkgY29uc3Q7CisgICAgdmlydHVhbCB1aW50MzJfdCAgICBnZXRGbGFncygpIGNvbnN0OworCisgICAgY29uc3QgY2hhciogICAgICAgICBnZXREZXZpY2UoKSBjb25zdDsKKyAgICAKKyAgICAvKiB0aGlzIGNsb3NlcyB0aGlzIGhlYXAgLS0gdXNlIGNhcmVmdWxseSAqLworICAgIHZvaWQgZGlzcG9zZSgpOworCisgICAgLyogdGhpcyBpcyBvbmx5IG5lZWRlZCBhcyBhIHdvcmthcm91bmQsIHVzZSBvbmx5IGlmIHlvdSBrbm93CisgICAgICogd2hhdCB5b3UgYXJlIGRvaW5nICovCisgICAgc3RhdHVzX3Qgc2V0RGV2aWNlKGNvbnN0IGNoYXIqIGRldmljZSkgeworICAgICAgICBpZiAobURldmljZSA9PSAwKQorICAgICAgICAgICAgbURldmljZSA9IGRldmljZTsKKyAgICAgICAgcmV0dXJuIG1EZXZpY2UgPyBOT19FUlJPUiA6IEFMUkVBRFlfRVhJU1RTOworICAgIH0KKyAgICAKK3Byb3RlY3RlZDoKKyAgICAgICAgICAgIE1lbW9yeUhlYXBCYXNlKCk7CisgICAgLy8gaW5pdCgpIHRha2VzIG93bmVyc2hpcCBvZiBmZAorICAgIHN0YXR1c190IGluaXQoaW50IGZkLCB2b2lkICpiYXNlLCBpbnQgc2l6ZSwKKyAgICAgICAgICAgIGludCBmbGFncyA9IDAsIGNvbnN0IGNoYXIqIGRldmljZSA9IE5VTEwpOyAgICAKKworcHJpdmF0ZToKKyAgICBzdGF0dXNfdCBtYXBmZChpbnQgZmQsIHNpemVfdCBzaXplKTsKKworICAgIGludCAgICAgICAgIG1GRDsKKyAgICBzaXplX3QgICAgICBtU2l6ZTsKKyAgICB2b2lkKiAgICAgICBtQmFzZTsKKyAgICB1aW50MzJfdCAgICBtRmxhZ3M7CisgICAgY29uc3QgY2hhciogbURldmljZTsKKyAgICBib29sICAgICAgICBtTmVlZFVubWFwOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9NRU1PUllfSEVBUF9CQVNFX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvTWVtb3J5SGVhcFBtZW0uaCBiL2luY2x1ZGUvdXRpbHMvTWVtb3J5SGVhcFBtZW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MDMzNWFkCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9NZW1vcnlIZWFwUG1lbS5oCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfTUVNT1JZX0hFQVBfUE1FTV9ICisjZGVmaW5lIEFORFJPSURfTUVNT1JZX0hFQVBfUE1FTV9ICisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKworI2luY2x1ZGUgPHV0aWxzL01lbW9yeURlYWxlci5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorI2luY2x1ZGUgPHV0aWxzL1NvcnRlZFZlY3Rvci5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIE1lbW9yeUhlYXBCYXNlOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTWVtb3J5SGVhcFBtZW0gOiBwdWJsaWMgSGVhcEludGVyZmFjZSwgcHVibGljIE1lbW9yeUhlYXBCYXNlCit7CitwdWJsaWM6CisgICAgY2xhc3MgTWVtb3J5UG1lbSA6IHB1YmxpYyBCbk1lbW9yeSB7CisgICAgcHVibGljOgorICAgICAgICBNZW1vcnlQbWVtKGNvbnN0IHNwPE1lbW9yeUhlYXBQbWVtPiYgaGVhcCk7CisgICAgICAgIH5NZW1vcnlQbWVtKCk7CisgICAgcHJvdGVjdGVkOgorICAgICAgICBjb25zdCBzcDxNZW1vcnlIZWFwUG1lbT4mICBnZXRIZWFwKCkgY29uc3QgeyByZXR1cm4gbUNsaWVudEhlYXA7IH0KKyAgICBwcml2YXRlOgorICAgICAgICBmcmllbmQgY2xhc3MgTWVtb3J5SGVhcFBtZW07CisgICAgICAgIHZpcnR1YWwgdm9pZCByZXZva2UoKSA9IDA7CisgICAgICAgIHNwPE1lbW9yeUhlYXBQbWVtPiAgbUNsaWVudEhlYXA7CisgICAgfTsKKyAgICAKKyAgICBNZW1vcnlIZWFwUG1lbShjb25zdCBzcDxNZW1vcnlIZWFwQmFzZT4mIHBtZW1IZWFwLAorICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gSU1lbW9yeUhlYXA6Ok1BUF9PTkNFKTsKKyAgICB+TWVtb3J5SGVhcFBtZW0oKTsKKworICAgIC8qIEhlYXBJbnRlcmZhY2UgYWRkaXRpb25zICovCisgICAgdmlydHVhbCBzcDxJTWVtb3J5PiBtYXBNZW1vcnkoc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpOworCisgICAgLyogbWFrZSB0aGUgd2hvbGUgaGVhcCB2aXNpYmxlICh5b3Uga25vdyB3aG8geW91IGFyZSkgKi8KKyAgICB2aXJ0dWFsIHN0YXR1c190IHNsYXAoKTsKKyAgICAKKyAgICAvKiBoaWRlIChyZXZva2UpIHRoZSB3aG9sZSBoZWFwICh0aGUgY2xpZW50IHdpbGwgc2VlIHRoZSBnYXJiYWdlIHBhZ2UpICovCisgICAgdmlydHVhbCBzdGF0dXNfdCB1bnNsYXAoKTsKKyAgICAKKyAgICAvKiByZXZva2UgYWxsIGFsbG9jYXRpb25zIG1hZGUgYnkgdGhpcyBoZWFwICovCisgICAgdmlydHVhbCB2b2lkIHJldm9rZSgpOworCitwcml2YXRlOgorICAgIC8qIHVzZSB0aGlzIHRvIGNyZWF0ZSB5b3VyIG93biBJTWVtb3J5IGZvciBtYXBNZW1vcnkgKi8KKyAgICB2aXJ0dWFsIHNwPE1lbW9yeVBtZW0+IGNyZWF0ZU1lbW9yeShzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSk7CisgICAgdm9pZCByZW1vdmUoY29uc3Qgd3A8TWVtb3J5UG1lbT4mIG1lbW9yeSk7CisKK3ByaXZhdGU6CisgICAgc3A8TWVtb3J5SGVhcEJhc2U+ICAgICAgICAgICAgICBtUGFyZW50SGVhcDsKKyAgICBtdXRhYmxlIE11dGV4ICAgICAgICAgICAgICAgICAgIG1Mb2NrOworICAgIFNvcnRlZFZlY3Rvcjwgd3A8TWVtb3J5UG1lbT4gPiAgbUFsbG9jYXRpb25zOworfTsKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX01FTU9SWV9IRUFQX1BNRU1fSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9QYXJjZWwuaCBiL2luY2x1ZGUvdXRpbHMvUGFyY2VsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA4N2M0NAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvUGFyY2VsLmgKQEAgLTAsMCArMSwyMDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfUEFSQ0VMX0gKKyNkZWZpbmUgQU5EUk9JRF9QQVJDRUxfSAorCisjaW5jbHVkZSA8Y3V0aWxzL25hdGl2ZV9oYW5kbGUuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nMTYuaD4KKyNpbmNsdWRlIDx1dGlscy9WZWN0b3IuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIElCaW5kZXI7CitjbGFzcyBQcm9jZXNzU3RhdGU7CitjbGFzcyBTdHJpbmc4OworY2xhc3MgVGV4dE91dHB1dDsKKworc3RydWN0IGZsYXRfYmluZGVyX29iamVjdDsgIC8vIGRlZmluZWQgaW4gc3VwcG9ydF9wL2JpbmRlcl9tb2R1bGUuaAorCitjbGFzcyBQYXJjZWwKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgIFBhcmNlbCgpOworICAgICAgICAgICAgICAgICAgICAgICAgflBhcmNlbCgpOworICAgIAorICAgIGNvbnN0IHVpbnQ4X3QqICAgICAgZGF0YSgpIGNvbnN0OworICAgIHNpemVfdCAgICAgICAgICAgICAgZGF0YVNpemUoKSBjb25zdDsKKyAgICBzaXplX3QgICAgICAgICAgICAgIGRhdGFBdmFpbCgpIGNvbnN0OworICAgIHNpemVfdCAgICAgICAgICAgICAgZGF0YVBvc2l0aW9uKCkgY29uc3Q7CisgICAgc2l6ZV90ICAgICAgICAgICAgICBkYXRhQ2FwYWNpdHkoKSBjb25zdDsKKyAgICAKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHNldERhdGFTaXplKHNpemVfdCBzaXplKTsKKyAgICB2b2lkICAgICAgICAgICAgICAgIHNldERhdGFQb3NpdGlvbihzaXplX3QgcG9zKSBjb25zdDsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHNldERhdGFDYXBhY2l0eShzaXplX3Qgc2l6ZSk7CisgICAgCisgICAgc3RhdHVzX3QgICAgICAgICAgICBzZXREYXRhKGNvbnN0IHVpbnQ4X3QqIGJ1ZmZlciwgc2l6ZV90IGxlbik7CisKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIGFwcGVuZEZyb20oUGFyY2VsICpwYXJjZWwsIHNpemVfdCBzdGFydCwgc2l6ZV90IGxlbik7CisKKyAgICBib29sICAgICAgICAgICAgICAgIGhhc0ZpbGVEZXNjcmlwdG9ycygpIGNvbnN0OworCisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZUludGVyZmFjZVRva2VuKGNvbnN0IFN0cmluZzE2JiBpbnRlcmZhY2UpOworICAgIGJvb2wgICAgICAgICAgICAgICAgZW5mb3JjZUludGVyZmFjZShjb25zdCBTdHJpbmcxNiYgaW50ZXJmYWNlKSBjb25zdDsKKyAgICAgICAgICAgIAorICAgIHZvaWQgICAgICAgICAgICAgICAgZnJlZURhdGEoKTsKKworICAgIGNvbnN0IHNpemVfdCogICAgICAgb2JqZWN0cygpIGNvbnN0OworICAgIHNpemVfdCAgICAgICAgICAgICAgb2JqZWN0c0NvdW50KCkgY29uc3Q7CisgICAgCisgICAgc3RhdHVzX3QgICAgICAgICAgICBlcnJvckNoZWNrKCkgY29uc3Q7CisgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRFcnJvcihzdGF0dXNfdCBlcnIpOworICAgIAorICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGUoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IGxlbik7CisgICAgdm9pZCogICAgICAgICAgICAgICB3cml0ZUlucGxhY2Uoc2l6ZV90IGxlbik7CisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZVVucGFkZGVkKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBsZW4pOworICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGVJbnQzMihpbnQzMl90IHZhbCk7CisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZUludDY0KGludDY0X3QgdmFsKTsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHdyaXRlRmxvYXQoZmxvYXQgdmFsKTsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHdyaXRlRG91YmxlKGRvdWJsZSB2YWwpOworICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGVDU3RyaW5nKGNvbnN0IGNoYXIqIHN0cik7CisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZVN0cmluZzgoY29uc3QgU3RyaW5nOCYgc3RyKTsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHdyaXRlU3RyaW5nMTYoY29uc3QgU3RyaW5nMTYmIHN0cik7CisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZVN0cmluZzE2KGNvbnN0IGNoYXIxNl90KiBzdHIsIHNpemVfdCBsZW4pOworICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGVTdHJvbmdCaW5kZXIoY29uc3Qgc3A8SUJpbmRlcj4mIHZhbCk7CisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZVdlYWtCaW5kZXIoY29uc3Qgd3A8SUJpbmRlcj4mIHZhbCk7CisKKyAgICAvLyBkb2Vzbid0IHRha2Ugb3duZXJzaGlwIG9mIHRoZSBuYXRpdmVfaGFuZGxlCisgICAgc3RhdHVzX3QgICAgICAgICAgICB3cml0ZU5hdGl2ZUhhbmRsZShjb25zdCBuYXRpdmVfaGFuZGxlJiBoYW5kbGUpOworICAgIAorICAgIC8vIFBsYWNlIGEgZmlsZSBkZXNjcmlwdG9yIGludG8gdGhlIHBhcmNlbC4gIFRoZSBnaXZlbiBmZCBtdXN0IHJlbWFpbgorICAgIC8vIHZhbGlkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIHBhcmNlbC4KKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHdyaXRlRmlsZURlc2NyaXB0b3IoaW50IGZkKTsKKyAgICAKKyAgICAvLyBQbGFjZSBhIGZpbGUgZGVzY3JpcHRvciBpbnRvIHRoZSBwYXJjZWwuICBBIGR1cCBvZiB0aGUgZmQgaXMgbWFkZSwgd2hpY2gKKyAgICAvLyB3aWxsIGJlIGNsb3NlZCBvbmNlIHRoZSBwYXJjZWwgaXMgZGVzdHJveWVkLgorICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGVEdXBGaWxlRGVzY3JpcHRvcihpbnQgZmQpOworICAgIAorICAgIHN0YXR1c190ICAgICAgICAgICAgd3JpdGVPYmplY3QoY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0JiB2YWwsIGJvb2wgbnVsbE1ldGFEYXRhKTsKKworICAgIHZvaWQgICAgICAgICAgICAgICAgcmVtb3ZlKHNpemVfdCBzdGFydCwgc2l6ZV90IGFtdCk7CisgICAgCisgICAgc3RhdHVzX3QgICAgICAgICAgICByZWFkKHZvaWQqIG91dERhdGEsIHNpemVfdCBsZW4pIGNvbnN0OworICAgIGNvbnN0IHZvaWQqICAgICAgICAgcmVhZElucGxhY2Uoc2l6ZV90IGxlbikgY29uc3Q7CisgICAgaW50MzJfdCAgICAgICAgICAgICByZWFkSW50MzIoKSBjb25zdDsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHJlYWRJbnQzMihpbnQzMl90ICpwQXJnKSBjb25zdDsKKyAgICBpbnQ2NF90ICAgICAgICAgICAgIHJlYWRJbnQ2NCgpIGNvbnN0OworICAgIHN0YXR1c190ICAgICAgICAgICAgcmVhZEludDY0KGludDY0X3QgKnBBcmcpIGNvbnN0OworICAgIGZsb2F0ICAgICAgICAgICAgICAgcmVhZEZsb2F0KCkgY29uc3Q7CisgICAgc3RhdHVzX3QgICAgICAgICAgICByZWFkRmxvYXQoZmxvYXQgKnBBcmcpIGNvbnN0OworICAgIGRvdWJsZSAgICAgICAgICAgICAgcmVhZERvdWJsZSgpIGNvbnN0OworICAgIHN0YXR1c190ICAgICAgICAgICAgcmVhZERvdWJsZShkb3VibGUgKnBBcmcpIGNvbnN0OworCisgICAgY29uc3QgY2hhciogICAgICAgICByZWFkQ1N0cmluZygpIGNvbnN0OworICAgIFN0cmluZzggICAgICAgICAgICAgcmVhZFN0cmluZzgoKSBjb25zdDsKKyAgICBTdHJpbmcxNiAgICAgICAgICAgIHJlYWRTdHJpbmcxNigpIGNvbnN0OworICAgIGNvbnN0IGNoYXIxNl90KiAgICAgcmVhZFN0cmluZzE2SW5wbGFjZShzaXplX3QqIG91dExlbikgY29uc3Q7CisgICAgc3A8SUJpbmRlcj4gICAgICAgICByZWFkU3Ryb25nQmluZGVyKCkgY29uc3Q7CisgICAgd3A8SUJpbmRlcj4gICAgICAgICByZWFkV2Vha0JpbmRlcigpIGNvbnN0OworCisgICAgCisgICAgLy8gaWYgYWxsb2MgaXMgTlVMTCwgbmF0aXZlX2hhbmRsZSBpcyBhbGxvY2F0ZWQgd2l0aCBtYWxsb2MoKSwgb3RoZXJ3aXNlCisgICAgLy8gYWxsb2MgaXMgdXNlZC4gSWYgdGhlIGZ1bmN0aW9uIGZhaWxzLCB0aGUgZWZmZWN0cyBvZiBhbGxvYygpIG11c3QgYmUKKyAgICAvLyByZXZlcnRlZCBieSB0aGUgY2FsbGVyLgorICAgIG5hdGl2ZV9oYW5kbGUqICAgICByZWFkTmF0aXZlSGFuZGxlKAorICAgICAgICAgICAgbmF0aXZlX2hhbmRsZSogKCphbGxvYykodm9pZCogY29va2llLCBpbnQgbnVtRmRzLCBpbnQgaW50cyksCisgICAgICAgICAgICB2b2lkKiBjb29raWUpIGNvbnN0OworCisgICAgCisgICAgLy8gUmV0cmlldmUgYSBmaWxlIGRlc2NyaXB0b3IgZnJvbSB0aGUgcGFyY2VsLiAgVGhpcyByZXR1cm5zIHRoZSByYXcgZmQKKyAgICAvLyBpbiB0aGUgcGFyY2VsLCB3aGljaCB5b3UgZG8gbm90IG93biAtLSB1c2UgZHVwKCkgdG8gZ2V0IHlvdXIgb3duIGNvcHkuCisgICAgaW50ICAgICAgICAgICAgICAgICByZWFkRmlsZURlc2NyaXB0b3IoKSBjb25zdDsKKyAgICAKKyAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIHJlYWRPYmplY3QoYm9vbCBudWxsTWV0YURhdGEpIGNvbnN0OworCisgICAgLy8gRXhwbGljaXRseSBjbG9zZSBhbGwgZmlsZSBkZXNjcmlwdG9ycyBpbiB0aGUgcGFyY2VsLgorICAgIHZvaWQgICAgICAgICAgICAgICAgY2xvc2VGaWxlRGVzY3JpcHRvcnMoKTsKKyAgICAKKyAgICB0eXBlZGVmIHZvaWQgICAgICAgICgqcmVsZWFzZV9mdW5jKShQYXJjZWwqIHBhcmNlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90KiBkYXRhLCBzaXplX3QgZGF0YVNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6ZV90KiBvYmplY3RzLCBzaXplX3Qgb2JqZWN0c1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY29va2llKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgIGNvbnN0IHVpbnQ4X3QqICAgICAgaXBjRGF0YSgpIGNvbnN0OworICAgIHNpemVfdCAgICAgICAgICAgICAgaXBjRGF0YVNpemUoKSBjb25zdDsKKyAgICBjb25zdCBzaXplX3QqICAgICAgIGlwY09iamVjdHMoKSBjb25zdDsKKyAgICBzaXplX3QgICAgICAgICAgICAgIGlwY09iamVjdHNDb3VudCgpIGNvbnN0OworICAgIHZvaWQgICAgICAgICAgICAgICAgaXBjU2V0RGF0YVJlZmVyZW5jZShjb25zdCB1aW50OF90KiBkYXRhLCBzaXplX3QgZGF0YVNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCogb2JqZWN0cywgc2l6ZV90IG9iamVjdHNDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsZWFzZV9mdW5jIHJlbEZ1bmMsIHZvaWQqIHJlbENvb2tpZSk7CisgICAgCisgICAgdm9pZCAgICAgICAgICAgICAgICBwcmludChUZXh0T3V0cHV0JiB0bywgdWludDMyX3QgZmxhZ3MgPSAwKSBjb25zdDsKKyAgICAKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwoY29uc3QgUGFyY2VsJiBvKTsKKyAgICBQYXJjZWwmICAgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBQYXJjZWwmIG8pOworICAgIAorICAgIHN0YXR1c190ICAgICAgICAgICAgZmluaXNoV3JpdGUoc2l6ZV90IGxlbik7CisgICAgdm9pZCAgICAgICAgICAgICAgICByZWxlYXNlT2JqZWN0cygpOworICAgIHZvaWQgICAgICAgICAgICAgICAgYWNxdWlyZU9iamVjdHMoKTsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIGdyb3dEYXRhKHNpemVfdCBsZW4pOworICAgIHN0YXR1c190ICAgICAgICAgICAgcmVzdGFydFdyaXRlKHNpemVfdCBkZXNpcmVkKTsKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIGNvbnRpbnVlV3JpdGUoc2l6ZV90IGRlc2lyZWQpOworICAgIHZvaWQgICAgICAgICAgICAgICAgZnJlZURhdGFOb0luaXQoKTsKKyAgICB2b2lkICAgICAgICAgICAgICAgIGluaXRTdGF0ZSgpOworICAgIHZvaWQgICAgICAgICAgICAgICAgc2NhbkZvckZkcygpIGNvbnN0OworICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgc3RhdHVzX3QgICAgICAgICAgICBtRXJyb3I7CisgICAgdWludDhfdCogICAgICAgICAgICBtRGF0YTsKKyAgICBzaXplX3QgICAgICAgICAgICAgIG1EYXRhU2l6ZTsKKyAgICBzaXplX3QgICAgICAgICAgICAgIG1EYXRhQ2FwYWNpdHk7CisgICAgbXV0YWJsZSBzaXplX3QgICAgICBtRGF0YVBvczsKKyAgICBzaXplX3QqICAgICAgICAgICAgIG1PYmplY3RzOworICAgIHNpemVfdCAgICAgICAgICAgICAgbU9iamVjdHNTaXplOworICAgIHNpemVfdCAgICAgICAgICAgICAgbU9iamVjdHNDYXBhY2l0eTsKKyAgICBtdXRhYmxlIHNpemVfdCAgICAgIG1OZXh0T2JqZWN0SGludDsKKworICAgIG11dGFibGUgYm9vbCAgICAgICAgbUZkc0tub3duOworICAgIG11dGFibGUgYm9vbCAgICAgICAgbUhhc0ZkczsKKyAgICAKKyAgICByZWxlYXNlX2Z1bmMgICAgICAgIG1Pd25lcjsKKyAgICB2b2lkKiAgICAgICAgICAgICAgIG1Pd25lckNvb2tpZTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUgVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3QgUGFyY2VsJiBwYXJjZWwpCit7CisgICAgcGFyY2VsLnByaW50KHRvKTsKKyAgICByZXR1cm4gdG87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBHZW5lcmljIGFjcXVpcmUgYW5kIHJlbGVhc2Ugb2Ygb2JqZWN0cy4KK3ZvaWQgYWNxdWlyZV9vYmplY3QoY29uc3Qgc3A8UHJvY2Vzc1N0YXRlPiYgcHJvYywKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0JiBvYmosIGNvbnN0IHZvaWQqIHdobyk7Cit2b2lkIHJlbGVhc2Vfb2JqZWN0KGNvbnN0IHNwPFByb2Nlc3NTdGF0ZT4mIHByb2MsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCYgb2JqLCBjb25zdCB2b2lkKiB3aG8pOworCit2b2lkIGZsYXR0ZW5fYmluZGVyKGNvbnN0IHNwPFByb2Nlc3NTdGF0ZT4mIHByb2MsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIsIGZsYXRfYmluZGVyX29iamVjdCogb3V0KTsKK3ZvaWQgZmxhdHRlbl9iaW5kZXIoY29uc3Qgc3A8UHJvY2Vzc1N0YXRlPiYgcHJvYywKKyAgICAgICAgICAgICAgICAgICAgY29uc3Qgd3A8SUJpbmRlcj4mIGJpbmRlciwgZmxhdF9iaW5kZXJfb2JqZWN0KiBvdXQpOworc3RhdHVzX3QgdW5mbGF0dGVuX2JpbmRlcihjb25zdCBzcDxQcm9jZXNzU3RhdGU+JiBwcm9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QmIGZsYXQsIHNwPElCaW5kZXI+KiBvdXQpOworc3RhdHVzX3QgdW5mbGF0dGVuX2JpbmRlcihjb25zdCBzcDxQcm9jZXNzU3RhdGU+JiBwcm9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QmIGZsYXQsIHdwPElCaW5kZXI+KiBvdXQpOworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfUEFSQ0VMX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvUGlwZS5oIGIvaW5jbHVkZS91dGlscy9QaXBlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQwNDE2OAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvUGlwZS5oCkBAIC0wLDAgKzEsMTA4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEZJRk8gSS9PLgorLy8KKyNpZm5kZWYgX0xJQlNfVVRJTFNfUElQRV9ICisjZGVmaW5lIF9MSUJTX1VUSUxTX1BJUEVfSAorCisjaWZkZWYgSEFWRV9BTkRST0lEX09TCisjZXJyb3IgRE8gTk9UIFVTRSBUSElTIEZJTEUgSU4gVEhFIERFVklDRSBCVUlMRAorI2VuZGlmCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFNpbXBsZSBhbm9ueW1vdXMgdW5pZGlyZWN0aW9uYWwgcGlwZS4KKyAqCisgKiBUaGUgcHJpbWFyeSBnb2FsIGlzIHRvIGNyZWF0ZSBhbiBpbXBsZW1lbnRhdGlvbiB3aXRoIG1pbmltYWwgb3ZlcmhlYWQKKyAqIHVuZGVyIExpbnV4LiAgTWFraW5nIFdpbmRvd3MsIE1hYyBPUyBYLCBhbmQgTGludXggYWxsIHdvcmsgdGhlIHNhbWUgd2F5CisgKiBpcyBhIHNlY29uZGFyeSBnb2FsLiAgUGFydCBvZiB0aGlzIGdvYWwgaXMgdG8gaGF2ZSBzb21ldGhpbmcgdGhhdCBjYW4KKyAqIGJlIGZlZCB0byBhIHNlbGVjdCgpIGNhbGwsIHNvIHRoYXQgdGhlIGFwcGxpY2F0aW9uIGNhbiBzbGVlcCBpbiB0aGUKKyAqIGtlcm5lbCB1bnRpbCBzb21ldGhpbmcgaW50ZXJlc3RpbmcgaGFwcGVucy4KKyAqLworY2xhc3MgUGlwZSB7CitwdWJsaWM6CisgICAgUGlwZSh2b2lkKTsKKyAgICB2aXJ0dWFsIH5QaXBlKHZvaWQpOworCisgICAgLyogQ3JlYXRlIHRoZSBwaXBlICovCisgICAgYm9vbCBjcmVhdGUodm9pZCk7CisKKyAgICAvKiBDcmVhdGUgYSByZWFkLW9ubHkgcGlwZSwgdXNpbmcgdGhlIHN1cHBsaWVkIGhhbmRsZSBhcyByZWFkIGhhbmRsZSAqLworICAgIGJvb2wgY3JlYXRlUmVhZGVyKHVuc2lnbmVkIGxvbmcgaGFuZGxlKTsKKyAgICAvKiBDcmVhdGUgYSB3cml0ZS1vbmx5IHBpcGUsIHVzaW5nIHRoZSBzdXBwbGllZCBoYW5kbGUgYXMgd3JpdGUgaGFuZGxlICovCisgICAgYm9vbCBjcmVhdGVXcml0ZXIodW5zaWduZWQgbG9uZyBoYW5kbGUpOworCisgICAgLyogSXMgdGhpcyBvYmplY3QgcmVhZHkgdG8gZ28/ICovCisgICAgYm9vbCBpc0NyZWF0ZWQodm9pZCk7CisKKyAgICAvKgorICAgICAqIFJlYWQgImNvdW50IiBieXRlcyBmcm9tIHRoZSBwaXBlLiAgUmV0dXJucyB0aGUgYW1vdW50IG9mIGRhdGEgcmVhZCwKKyAgICAgKiBvciAwIGlmIG5vIGRhdGEgYXZhaWxhYmxlIGFuZCB3ZSdyZSBub24tYmxvY2tpbmcuCisgICAgICogUmV0dXJucyAtMSBvbiBlcnJvci4KKyAgICAgKi8KKyAgICBpbnQgcmVhZCh2b2lkKiBidWYsIGludCBjb3VudCk7CisKKyAgICAvKgorICAgICAqIFdyaXRlICJjb3VudCIgYnl0ZXMgaW50byB0aGUgcGlwZS4gIFJldHVybnMgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4sCisgICAgICogb3IgMCBpZiB0aGVyZSdzIG5vIHJvb20gZm9yIG1vcmUgZGF0YSBhbmQgd2UncmUgbm9uLWJsb2NraW5nLgorICAgICAqIFJldHVybnMgLTEgb24gZXJyb3IuCisgICAgICovCisgICAgaW50IHdyaXRlKGNvbnN0IHZvaWQqIGJ1ZiwgaW50IGNvdW50KTsKKworICAgIC8qIFJldHVybnMgInRydWUiIGlmIGRhdGEgaXMgYXZhaWxhYmxlIHRvIHJlYWQgKi8KKyAgICBib29sIHJlYWRSZWFkeSh2b2lkKTsKKworICAgIC8qIEVuYWJsZSBvciBkaXNhYmxlIG5vbi1ibG9ja2luZyBJL08gZm9yIHJlYWRzICovCisgICAgYm9vbCBzZXRSZWFkTm9uQmxvY2tpbmcoYm9vbCB2YWwpOworICAgIC8qIEVuYWJsZSBvciBkaXNhYmxlIG5vbi1ibG9ja2luZyBJL08gZm9yIHdyaXRlcy4gIE9ubHkgd29ya3Mgb24gTGludXguICovCisgICAgYm9vbCBzZXRXcml0ZU5vbkJsb2NraW5nKGJvb2wgdmFsKTsKKworICAgIC8qCisgICAgICogR2V0IHRoZSBoYW5kbGUuICBPbmx5IHVzZWZ1bCBpbiBzb21lIHBsYXRmb3JtLXNwZWNpZmljIHNpdHVhdGlvbnMuCisgICAgICovCisgICAgdW5zaWduZWQgbG9uZyBnZXRSZWFkSGFuZGxlKHZvaWQpOworICAgIHVuc2lnbmVkIGxvbmcgZ2V0V3JpdGVIYW5kbGUodm9pZCk7CisKKyAgICAvKgorICAgICAqIE1vZGlmeSBpbmhlcml0YW5jZSwgaS5lLiB3aGV0aGVyIG9yIG5vdCBhIGNoaWxkIHByb2Nlc3Mgd2lsbCBnZXQKKyAgICAgKiBjb3BpZXMgb2YgdGhlIGRlc2NyaXB0b3JzLiAgU3lzdGVtcyB3aXRoIGZvcmsrZXhlYyBhbGxvdyB1cyB0byBjbG9zZQorICAgICAqIHRoZSBkZXNjcmlwdG9ycyBiZWZvcmUgbGF1bmNoaW5nIHRoZSBjaGlsZCBwcm9jZXNzLCBidXQgV2luMzIKKyAgICAgKiBkb2Vzbid0IGFsbG93IGl0LgorICAgICAqLworICAgIGJvb2wgZGlzYWxsb3dSZWFkSW5oZXJpdCh2b2lkKTsKKyAgICBib29sIGRpc2FsbG93V3JpdGVJbmhlcml0KHZvaWQpOworCisgICAgLyoKKyAgICAgKiBDbG9zZSBvbmUgc2lkZSBvciB0aGUgb3RoZXIuICBVc2VmdWwgaW4gdGhlIHBhcmVudCBhZnRlciBsYXVuY2hpbmcKKyAgICAgKiBhIGNoaWxkIHByb2Nlc3MuCisgICAgICovCisgICAgYm9vbCBjbG9zZVJlYWQodm9pZCk7CisgICAgYm9vbCBjbG9zZVdyaXRlKHZvaWQpOworCitwcml2YXRlOgorICAgIGJvb2wgICAgbVJlYWROb25CbG9ja2luZzsKKyAgICBib29sICAgIG1Xcml0ZU5vbkJsb2NraW5nOworCisgICAgdW5zaWduZWQgbG9uZyBtUmVhZEhhbmRsZTsKKyAgICB1bnNpZ25lZCBsb25nIG1Xcml0ZUhhbmRsZTsKK307CisKK307IC8vIGFuZHJvaWQKKworI2VuZGlmIC8vIF9MSUJTX1VUSUxTX1BJUEVfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9Qcm9jZXNzU3RhdGUuaCBiL2luY2x1ZGUvdXRpbHMvUHJvY2Vzc1N0YXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzk1ODRmNAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvUHJvY2Vzc1N0YXRlLmgKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfUFJPQ0VTU19TVEFURV9ICisjZGVmaW5lIEFORFJPSURfUFJPQ0VTU19TVEFURV9ICisKKyNpbmNsdWRlIDx1dGlscy9JQmluZGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nMTYuaD4KKworI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIEdsb2JhbCB2YXJpYWJsZXMKK2V4dGVybiBpbnQgICAgICAgICAgICAgICAgIG1BcmdDOworZXh0ZXJuIGNvbnN0IGNoYXIqIGNvbnN0KiAgbUFyZ1Y7CitleHRlcm4gaW50ICAgICAgICAgICAgICAgICBtQXJnTGVuOworCitjbGFzcyBJUENUaHJlYWRTdGF0ZTsKKworY2xhc3MgUHJvY2Vzc1N0YXRlIDogcHVibGljIHZpcnR1YWwgUmVmQmFzZQoreworcHVibGljOgorICAgIHN0YXRpYyAgc3A8UHJvY2Vzc1N0YXRlPiAgICBzZWxmKCk7CisKKyAgICBzdGF0aWMgIHZvaWQgICAgICAgICAgICAgICAgc2V0U2luZ2xlUHJvY2Vzcyhib29sIHNpbmdsZVByb2Nlc3MpOworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHNldENvbnRleHRPYmplY3QoY29uc3Qgc3A8SUJpbmRlcj4mIG9iamVjdCk7CisgICAgICAgICAgICBzcDxJQmluZGVyPiAgICAgICAgIGdldENvbnRleHRPYmplY3QoY29uc3Qgc3A8SUJpbmRlcj4mIGNhbGxlcik7CisgICAgICAgIAorICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRDb250ZXh0T2JqZWN0KGNvbnN0IHNwPElCaW5kZXI+JiBvYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nMTYmIG5hbWUpOworICAgICAgICAgICAgc3A8SUJpbmRlcj4gICAgICAgICBnZXRDb250ZXh0T2JqZWN0KGNvbnN0IFN0cmluZzE2JiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBjYWxsZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICBzdXBwb3J0c1Byb2Nlc3NlcygpIGNvbnN0OworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0YXJ0VGhyZWFkUG9vbCgpOworICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgdHlwZWRlZiBib29sICgqY29udGV4dF9jaGVja19mdW5jKShjb25zdCBTdHJpbmcxNiYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+JiBjYWxsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiB1c2VyRGF0YSk7CisgICAgICAgIAorICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICBpc0NvbnRleHRNYW5hZ2VyKHZvaWQpIGNvbnN0OworICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICBiZWNvbWVDb250ZXh0TWFuYWdlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRfY2hlY2tfZnVuYyBjaGVja0Z1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiB1c2VyRGF0YSk7CisKKyAgICAgICAgICAgIHNwPElCaW5kZXI+ICAgICAgICAgZ2V0U3Ryb25nUHJveHlGb3JIYW5kbGUoaW50MzJfdCBoYW5kbGUpOworICAgICAgICAgICAgd3A8SUJpbmRlcj4gICAgICAgICBnZXRXZWFrUHJveHlGb3JIYW5kbGUoaW50MzJfdCBoYW5kbGUpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBleHB1bmdlSGFuZGxlKGludDMyX3QgaGFuZGxlLCBJQmluZGVyKiBiaW5kZXIpOworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHNldEFyZ3MoaW50IGFyZ2MsIGNvbnN0IGNoYXIqIGNvbnN0IGFyZ3ZbXSk7CisgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgIGdldEFyZ0MoKSBjb25zdDsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNvbnN0KiAgZ2V0QXJnVigpIGNvbnN0OworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHNldEFyZ1YwKGNvbnN0IGNoYXIqIHR4dCk7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc3Bhd25Qb29sZWRUaHJlYWQoYm9vbCBpc01haW4pOworICAgICAgICAgICAgCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBJUENUaHJlYWRTdGF0ZTsKKyAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc1N0YXRlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5Qcm9jZXNzU3RhdGUoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9jZXNzU3RhdGUoY29uc3QgUHJvY2Vzc1N0YXRlJiBvKTsKKyAgICAgICAgICAgIFByb2Nlc3NTdGF0ZSYgICAgICAgb3BlcmF0b3I9KGNvbnN0IFByb2Nlc3NTdGF0ZSYgbyk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHN0cnVjdCBoYW5kbGVfZW50cnkgeworICAgICAgICAgICAgICAgIElCaW5kZXIqIGJpbmRlcjsKKyAgICAgICAgICAgICAgICBSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqIHJlZnM7CisgICAgICAgICAgICB9OworICAgICAgICAgICAgCisgICAgICAgICAgICBoYW5kbGVfZW50cnkqICAgICAgIGxvb2t1cEhhbmRsZUxvY2tlZChpbnQzMl90IGhhbmRsZSk7CisKKyAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgbURyaXZlckZEOworICAgICAgICAgICAgdm9pZCogICAgICAgICAgICAgICBtVk1TdGFydDsKKyAgICAgICAgICAgIAorICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICBtTG9jazsgIC8vIHByb3RlY3RzIGV2ZXJ5dGhpbmcgYmVsb3cuCisgICAgICAgICAgICAKKyAgICAgICAgICAgIFZlY3RvcjxoYW5kbGVfZW50cnk+bUhhbmRsZVRvT2JqZWN0OworCisgICAgICAgICAgICBib29sICAgICAgICAgICAgICAgIG1NYW5hZ2VzQ29udGV4dHM7CisgICAgICAgICAgICBjb250ZXh0X2NoZWNrX2Z1bmMgIG1CaW5kZXJDb250ZXh0Q2hlY2tGdW5jOworICAgICAgICAgICAgdm9pZCogICAgICAgICAgICAgICBtQmluZGVyQ29udGV4dFVzZXJEYXRhOworICAgICAgICAgICAgCisgICAgICAgICAgICBLZXllZFZlY3RvcjxTdHJpbmcxNiwgc3A8SUJpbmRlcj4gPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtQ29udGV4dHM7CisKKworICAgICAgICAgICAgU3RyaW5nOCAgICAgICAgICAgICBtUm9vdERpcjsKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgbVRocmVhZFBvb2xTdGFydGVkOworICAgIHZvbGF0aWxlIGludDMyX3QgICAgICAgICAgICBtVGhyZWFkUG9vbFNlcTsKK307CisgICAgCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfUFJPQ0VTU19TVEFURV9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1JlZkJhc2UuaCBiL2luY2x1ZGUvdXRpbHMvUmVmQmFzZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiZGEwZmQKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1JlZkJhc2UuaApAQCAtMCwwICsxLDU1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9SRUZfQkFTRV9ICisjZGVmaW5lIEFORFJPSURfUkVGX0JBU0VfSAorCisjaW5jbHVkZSA8Y3V0aWxzL2F0b21pYy5oPgorI2luY2x1ZGUgPHV0aWxzL1RleHRPdXRwdXQuaD4KKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3Mgd3A7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIENPTVBBUkUoX29wXykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgb3BlcmF0b3IgX29wXyAoY29uc3Qgc3A8VD4mIG8pIGNvbnN0IHsgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gbV9wdHIgX29wXyBvLm1fcHRyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgb3BlcmF0b3IgX29wXyAoY29uc3Qgd3A8VD4mIG8pIGNvbnN0IHsgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gbV9wdHIgX29wXyBvLm1fcHRyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgb3BlcmF0b3IgX29wXyAoY29uc3QgVCogbykgY29uc3QgeyAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gbV9wdHIgX29wXyBvOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8dHlwZW5hbWUgVT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK2lubGluZSBib29sIG9wZXJhdG9yIF9vcF8gKGNvbnN0IHNwPFU+JiBvKSBjb25zdCB7ICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIG1fcHRyIF9vcF8gby5tX3B0cjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK3RlbXBsYXRlPHR5cGVuYW1lIFU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgYm9vbCBvcGVyYXRvciBfb3BfIChjb25zdCB3cDxVPiYgbykgY29uc3QgeyAgICAgICAgICAgICAgXAorICAgIHJldHVybiBtX3B0ciBfb3BfIG8ubV9wdHI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTx0eXBlbmFtZSBVPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgb3BlcmF0b3IgX29wXyAoY29uc3QgVSogbykgY29uc3QgeyAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gbV9wdHIgX29wXyBvOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBSZWZCYXNlCit7CitwdWJsaWM6CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgaW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICBkZWNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0OworICAgIAorICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIGZvcmNlSW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKworICAgICAgICAgICAgLy8hIERFQlVHR0lORyBPTkxZOiBHZXQgY3VycmVudCBzdHJvbmcgcmVmIGNvdW50LgorICAgICAgICAgICAgaW50MzJfdCAgICAgICAgIGdldFN0cm9uZ0NvdW50KCkgY29uc3Q7CisKKyAgICBjbGFzcyB3ZWFrcmVmX3R5cGUKKyAgICB7CisgICAgcHVibGljOgorICAgICAgICBSZWZCYXNlKiAgICAgICAgICAgIHJlZkJhc2UoKSBjb25zdDsKKyAgICAgICAgCisgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgaW5jV2Vhayhjb25zdCB2b2lkKiBpZCk7CisgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgZGVjV2Vhayhjb25zdCB2b2lkKiBpZCk7CisgICAgICAgIAorICAgICAgICBib29sICAgICAgICAgICAgICAgIGF0dGVtcHRJbmNTdHJvbmcoY29uc3Qgdm9pZCogaWQpOworICAgICAgICAKKyAgICAgICAgLy8hIFRoaXMgaXMgb25seSBzYWZlIGlmIHlvdSBoYXZlIHNldCBPQkpFQ1RfTElGRVRJTUVfRk9SRVZFUi4KKyAgICAgICAgYm9vbCAgICAgICAgICAgICAgICBhdHRlbXB0SW5jV2Vhayhjb25zdCB2b2lkKiBpZCk7CisKKyAgICAgICAgLy8hIERFQlVHR0lORyBPTkxZOiBHZXQgY3VycmVudCB3ZWFrIHJlZiBjb3VudC4KKyAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBnZXRXZWFrQ291bnQoKSBjb25zdDsKKworICAgICAgICAvLyEgREVCVUdHSU5HIE9OTFk6IFByaW50IHJlZmVyZW5jZXMgaGVsZCBvbiBvYmplY3QuCisgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgcHJpbnRSZWZzKCkgY29uc3Q7CisKKyAgICAgICAgLy8hIERFQlVHR0lORyBPTkxZOiBFbmFibGUgdHJhY2tpbmcgZm9yIHRoaXMgb2JqZWN0LgorICAgICAgICAvLyBlbmFibGUgLS0gZW5hYmxlL2Rpc2FibGUgdHJhY2tpbmcKKyAgICAgICAgLy8gcmV0YWluIC0tIHdoZW4gdHJhY2tpbmcgaXMgZW5hYmxlLCBpZiB0cnVlLCB0aGVuIHdlIHNhdmUgYSBzdGFjayB0cmFjZQorICAgICAgICAvLyAgICAgICAgICAgZm9yIGVhY2ggcmVmZXJlbmNlIGFuZCBkZXJlZmVyZW5jZTsgd2hlbiByZXRhaW4gPT0gZmFsc2UsIHdlCisgICAgICAgIC8vICAgICAgICAgICBtYXRjaCB1cCByZWZlcmVuY2VzIGFuZCBkZXJlZmVyZW5jZXMgYW5kIGtlZXAgb25seSB0aGUgCisgICAgICAgIC8vICAgICAgICAgICBvdXRzdGFuZGluZyBvbmVzLgorICAgICAgICAKKyAgICAgICAgdm9pZCAgICAgICAgICAgICAgICB0cmFja01lKGJvb2wgZW5hYmxlLCBib29sIHJldGFpbik7CisgICAgfTsKKyAgICAKKyAgICAgICAgICAgIHdlYWtyZWZfdHlwZSogICBjcmVhdGVXZWFrKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgd2Vha3JlZl90eXBlKiAgIGdldFdlYWtSZWZzKCkgY29uc3Q7CisKKyAgICAgICAgICAgIC8vISBERUJVR0dJTkcgT05MWTogUHJpbnQgcmVmZXJlbmNlcyBoZWxkIG9uIG9iamVjdC4KKyAgICBpbmxpbmUgIHZvaWQgICAgICAgICAgICBwcmludFJlZnMoKSBjb25zdCB7IGdldFdlYWtSZWZzKCktPnByaW50UmVmcygpOyB9CisKKyAgICAgICAgICAgIC8vISBERUJVR0dJTkcgT05MWTogRW5hYmxlIHRyYWNraW5nIG9mIG9iamVjdC4KKyAgICBpbmxpbmUgIHZvaWQgICAgICAgICAgICB0cmFja01lKGJvb2wgZW5hYmxlLCBib29sIHJldGFpbikKKyAgICB7IAorICAgICAgICBnZXRXZWFrUmVmcygpLT50cmFja01lKGVuYWJsZSwgcmV0YWluKTsgCisgICAgfQorCitwcm90ZWN0ZWQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmQmFzZSgpOworICAgIHZpcnR1YWwgICAgICAgICAgICAgICAgIH5SZWZCYXNlKCk7CisgICAgCisgICAgLy8hIEZsYWdzIGZvciBleHRlbmRPYmplY3RMaWZldGltZSgpCisgICAgZW51bSB7CisgICAgICAgIE9CSkVDVF9MSUZFVElNRV9XRUFLICAgID0gMHgwMDAxLAorICAgICAgICBPQkpFQ1RfTElGRVRJTUVfRk9SRVZFUiA9IDB4MDAwMworICAgIH07CisgICAgCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgZXh0ZW5kT2JqZWN0TGlmZXRpbWUoaW50MzJfdCBtb2RlKTsKKyAgICAgICAgICAgIAorICAgIC8vISBGbGFncyBmb3Igb25JbmNTdHJvbmdBdHRlbXB0ZWQoKQorICAgIGVudW0geworICAgICAgICBGSVJTVF9JTkNfU1RST05HID0gMHgwMDAxCisgICAgfTsKKyAgICAKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBvbkZpcnN0UmVmKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgb25MYXN0U3Ryb25nUmVmKGNvbnN0IHZvaWQqIGlkKTsKKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgICAgICBvbkluY1N0cm9uZ0F0dGVtcHRlZCh1aW50MzJfdCBmbGFncywgY29uc3Qgdm9pZCogaWQpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIG9uTGFzdFdlYWtSZWYoY29uc3Qgdm9pZCogaWQpOworCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyB3ZWFrcmVmX3R5cGU7CisgICAgY2xhc3Mgd2Vha3JlZl9pbXBsOworICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZkJhc2UoY29uc3QgUmVmQmFzZSYgbyk7CisgICAgICAgICAgICBSZWZCYXNlJiAgICAgICAgb3BlcmF0b3I9KGNvbnN0IFJlZkJhc2UmIG8pOworICAgICAgICAgICAgCisgICAgICAgIHdlYWtyZWZfaW1wbCogY29uc3QgbVJlZnM7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGUgPGNsYXNzIFQ+CitjbGFzcyBMaWdodFJlZkJhc2UKK3sKK3B1YmxpYzoKKyAgICBpbmxpbmUgTGlnaHRSZWZCYXNlKCkgOiBtQ291bnQoMCkgeyB9CisgICAgaW5saW5lIHZvaWQgaW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdCB7CisgICAgICAgIGFuZHJvaWRfYXRvbWljX2luYygmbUNvdW50KTsKKyAgICB9CisgICAgaW5saW5lIHZvaWQgZGVjU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdCB7CisgICAgICAgIGlmIChhbmRyb2lkX2F0b21pY19kZWMoJm1Db3VudCkgPT0gMSkgeworICAgICAgICAgICAgZGVsZXRlIHN0YXRpY19jYXN0PGNvbnN0IFQqPih0aGlzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAKK3Byb3RlY3RlZDoKKyAgICBpbmxpbmUgfkxpZ2h0UmVmQmFzZSgpIHsgfQorICAgIAorcHJpdmF0ZToKKyAgICBtdXRhYmxlIHZvbGF0aWxlIGludDMyX3QgbUNvdW50OworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorY2xhc3Mgc3AKK3sKK3B1YmxpYzoKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZkJhc2U6OndlYWtyZWZfdHlwZSB3ZWFrcmVmX3R5cGU7CisgICAgCisgICAgaW5saW5lIHNwKCkgOiBtX3B0cigwKSB7IH0KKworICAgIHNwKFQqIG90aGVyKTsKKyAgICBzcChjb25zdCBzcDxUPiYgb3RoZXIpOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHNwKFUqIG90aGVyKTsKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBzcChjb25zdCBzcDxVPiYgb3RoZXIpOworCisgICAgfnNwKCk7CisgICAgCisgICAgLy8gQXNzaWdubWVudAorCisgICAgc3AmIG9wZXJhdG9yID0gKFQqIG90aGVyKTsKKyAgICBzcCYgb3BlcmF0b3IgPSAoY29uc3Qgc3A8VD4mIG90aGVyKTsKKyAgICAKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBzcCYgb3BlcmF0b3IgPSAoY29uc3Qgc3A8VT4mIG90aGVyKTsKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBzcCYgb3BlcmF0b3IgPSAoVSogb3RoZXIpOworICAgIAorICAgIC8vISBTcGVjaWFsIG9wdGltaXphdGlvbiBmb3IgdXNlIGJ5IFByb2Nlc3NTdGF0ZSAoYW5kIG5vYm9keSBlbHNlKS4KKyAgICB2b2lkIGZvcmNlX3NldChUKiBvdGhlcik7CisgICAgCisgICAgLy8gUmVzZXQKKyAgICAKKyAgICB2b2lkIGNsZWFyKCk7CisgICAgCisgICAgLy8gQWNjZXNzb3JzCisKKyAgICBpbmxpbmUgIFQmICAgICAgb3BlcmF0b3IqICgpIGNvbnN0ICB7IHJldHVybiAqbV9wdHI7IH0KKyAgICBpbmxpbmUgIFQqICAgICAgb3BlcmF0b3ItPiAoKSBjb25zdCB7IHJldHVybiBtX3B0cjsgIH0KKyAgICBpbmxpbmUgIFQqICAgICAgZ2V0KCkgY29uc3QgICAgICAgICB7IHJldHVybiBtX3B0cjsgfQorCisgICAgLy8gT3BlcmF0b3JzCisgICAgICAgIAorICAgIENPTVBBUkUoPT0pCisgICAgQ09NUEFSRSghPSkKKyAgICBDT01QQVJFKD4pCisgICAgQ09NUEFSRSg8KQorICAgIENPTVBBUkUoPD0pCisgICAgQ09NUEFSRSg+PSkKKworcHJpdmF0ZTogICAgCisgICAgdGVtcGxhdGU8dHlwZW5hbWUgWT4gZnJpZW5kIGNsYXNzIHNwOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFk+IGZyaWVuZCBjbGFzcyB3cDsKKworICAgIC8vIE9wdGltaXphdGlvbiBmb3Igd3A6OnByb21vdGUoKS4KKyAgICBzcChUKiBwLCB3ZWFrcmVmX3R5cGUqIHJlZnMpOworICAgIAorICAgIFQqICAgICAgICAgICAgICBtX3B0cjsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3Qgc3A8VD4mIHZhbCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIHdwCit7CitwdWJsaWM6CisgICAgdHlwZWRlZiB0eXBlbmFtZSBSZWZCYXNlOjp3ZWFrcmVmX3R5cGUgd2Vha3JlZl90eXBlOworICAgIAorICAgIGlubGluZSB3cCgpIDogbV9wdHIoMCkgeyB9CisKKyAgICB3cChUKiBvdGhlcik7CisgICAgd3AoY29uc3Qgd3A8VD4mIG90aGVyKTsKKyAgICB3cChjb25zdCBzcDxUPiYgb3RoZXIpOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHdwKFUqIG90aGVyKTsKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiB3cChjb25zdCBzcDxVPiYgb3RoZXIpOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHdwKGNvbnN0IHdwPFU+JiBvdGhlcik7CisKKyAgICB+d3AoKTsKKyAgICAKKyAgICAvLyBBc3NpZ25tZW50CisKKyAgICB3cCYgb3BlcmF0b3IgPSAoVCogb3RoZXIpOworICAgIHdwJiBvcGVyYXRvciA9IChjb25zdCB3cDxUPiYgb3RoZXIpOworICAgIHdwJiBvcGVyYXRvciA9IChjb25zdCBzcDxUPiYgb3RoZXIpOworICAgIAorICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHdwJiBvcGVyYXRvciA9IChVKiBvdGhlcik7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVT4gd3AmIG9wZXJhdG9yID0gKGNvbnN0IHdwPFU+JiBvdGhlcik7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVT4gd3AmIG9wZXJhdG9yID0gKGNvbnN0IHNwPFU+JiBvdGhlcik7CisgICAgCisgICAgdm9pZCBzZXRfb2JqZWN0X2FuZF9yZWZzKFQqIG90aGVyLCB3ZWFrcmVmX3R5cGUqIHJlZnMpOworCisgICAgLy8gcHJvbW90aW9uIHRvIHNwCisgICAgCisgICAgc3A8VD4gcHJvbW90ZSgpIGNvbnN0OworCisgICAgLy8gUmVzZXQKKyAgICAKKyAgICB2b2lkIGNsZWFyKCk7CisKKyAgICAvLyBBY2Nlc3NvcnMKKyAgICAKKyAgICBpbmxpbmUgIHdlYWtyZWZfdHlwZSogZ2V0X3JlZnMoKSBjb25zdCB7IHJldHVybiBtX3JlZnM7IH0KKyAgICAKKyAgICBpbmxpbmUgIFQqIHVuc2FmZV9nZXQoKSBjb25zdCB7IHJldHVybiBtX3B0cjsgfQorCisgICAgLy8gT3BlcmF0b3JzCisgICAgICAgIAorICAgIENPTVBBUkUoPT0pCisgICAgQ09NUEFSRSghPSkKKyAgICBDT01QQVJFKD4pCisgICAgQ09NUEFSRSg8KQorICAgIENPTVBBUkUoPD0pCisgICAgQ09NUEFSRSg+PSkKKworcHJpdmF0ZToKKyAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBZPiBmcmllbmQgY2xhc3Mgc3A7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgWT4gZnJpZW5kIGNsYXNzIHdwOworCisgICAgVCogICAgICAgICAgICAgIG1fcHRyOworICAgIHdlYWtyZWZfdHlwZSogICBtX3JlZnM7Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK1RleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGNvbnN0IHdwPFQ+JiB2YWwpOworCisjdW5kZWYgQ09NUEFSRQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vIHVzZXIgc2VydmljZWFibGUgcGFydHMgYmVsb3cgaGVyZS4KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3NwPFQ+OjpzcChUKiBvdGhlcikKKyAgICA6IG1fcHRyKG90aGVyKQoreworICAgIGlmIChvdGhlcikgb3RoZXItPmluY1N0cm9uZyh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3NwPFQ+OjpzcChjb25zdCBzcDxUPiYgb3RoZXIpCisgICAgOiBtX3B0cihvdGhlci5tX3B0cikKK3sKKyAgICBpZiAobV9wdHIpIG1fcHRyLT5pbmNTdHJvbmcodGhpcyk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHRlbXBsYXRlPHR5cGVuYW1lIFU+CitzcDxUPjo6c3AoVSogb3RoZXIpIDogbV9wdHIob3RoZXIpCit7CisgICAgaWYgKG90aGVyKSBvdGhlci0+aW5jU3Ryb25nKHRoaXMpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgorc3A8VD46OnNwKGNvbnN0IHNwPFU+JiBvdGhlcikKKyAgICA6IG1fcHRyKG90aGVyLm1fcHRyKQoreworICAgIGlmIChtX3B0cikgbV9wdHItPmluY1N0cm9uZyh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3NwPFQ+Ojp+c3AoKQoreworICAgIGlmIChtX3B0cikgbV9wdHItPmRlY1N0cm9uZyh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3NwPFQ+JiBzcDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgc3A8VD4mIG90aGVyKSB7CisgICAgaWYgKG90aGVyLm1fcHRyKSBvdGhlci5tX3B0ci0+aW5jU3Ryb25nKHRoaXMpOworICAgIGlmIChtX3B0cikgbV9wdHItPmRlY1N0cm9uZyh0aGlzKTsKKyAgICBtX3B0ciA9IG90aGVyLm1fcHRyOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3NwPFQ+JiBzcDxUPjo6b3BlcmF0b3IgPSAoVCogb3RoZXIpCit7CisgICAgaWYgKG90aGVyKSBvdGhlci0+aW5jU3Ryb25nKHRoaXMpOworICAgIGlmIChtX3B0cikgbV9wdHItPmRlY1N0cm9uZyh0aGlzKTsKKyAgICBtX3B0ciA9IG90aGVyOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gdGVtcGxhdGU8dHlwZW5hbWUgVT4KK3NwPFQ+JiBzcDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgc3A8VT4mIG90aGVyKQoreworICAgIGlmIChvdGhlci5tX3B0cikgb3RoZXIubV9wdHItPmluY1N0cm9uZyh0aGlzKTsKKyAgICBpZiAobV9wdHIpIG1fcHRyLT5kZWNTdHJvbmcodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlci5tX3B0cjsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHRlbXBsYXRlPHR5cGVuYW1lIFU+CitzcDxUPiYgc3A8VD46Om9wZXJhdG9yID0gKFUqIG90aGVyKQoreworICAgIGlmIChvdGhlcikgb3RoZXItPmluY1N0cm9uZyh0aGlzKTsKKyAgICBpZiAobV9wdHIpIG1fcHRyLT5kZWNTdHJvbmcodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlcjsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+ICAgIAordm9pZCBzcDxUPjo6Zm9yY2Vfc2V0KFQqIG90aGVyKQoreworICAgIG90aGVyLT5mb3JjZUluY1N0cm9uZyh0aGlzKTsKKyAgICBtX3B0ciA9IG90aGVyOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgordm9pZCBzcDxUPjo6Y2xlYXIoKQoreworICAgIGlmIChtX3B0cikgeworICAgICAgICBtX3B0ci0+ZGVjU3Ryb25nKHRoaXMpOworICAgICAgICBtX3B0ciA9IDA7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3A8VD46OnNwKFQqIHAsIHdlYWtyZWZfdHlwZSogcmVmcykKKyAgICA6IG1fcHRyKChwICYmIHJlZnMtPmF0dGVtcHRJbmNTdHJvbmcodGhpcykpID8gcCA6IDApCit7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgoraW5saW5lIFRleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGNvbnN0IHNwPFQ+JiB2YWwpCit7CisgICAgdG8gPDwgInNwPD4oIiA8PCB2YWwuZ2V0KCkgPDwgIikiOworICAgIHJldHVybiB0bzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Cit3cDxUPjo6d3AoVCogb3RoZXIpCisgICAgOiBtX3B0cihvdGhlcikKK3sKKyAgICBpZiAob3RoZXIpIG1fcmVmcyA9IG90aGVyLT5jcmVhdGVXZWFrKHRoaXMpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgord3A8VD46OndwKGNvbnN0IHdwPFQ+JiBvdGhlcikKKyAgICA6IG1fcHRyKG90aGVyLm1fcHRyKSwgbV9yZWZzKG90aGVyLm1fcmVmcykKK3sKKyAgICBpZiAobV9wdHIpIG1fcmVmcy0+aW5jV2Vhayh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3dwPFQ+Ojp3cChjb25zdCBzcDxUPiYgb3RoZXIpCisgICAgOiBtX3B0cihvdGhlci5tX3B0cikKK3sKKyAgICBpZiAobV9wdHIpIHsKKyAgICAgICAgbV9yZWZzID0gbV9wdHItPmNyZWF0ZVdlYWsodGhpcyk7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgord3A8VD46OndwKFUqIG90aGVyKQorICAgIDogbV9wdHIob3RoZXIpCit7CisgICAgaWYgKG90aGVyKSBtX3JlZnMgPSBvdGhlci0+Y3JlYXRlV2Vhayh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gdGVtcGxhdGU8dHlwZW5hbWUgVT4KK3dwPFQ+Ojp3cChjb25zdCB3cDxVPiYgb3RoZXIpCisgICAgOiBtX3B0cihvdGhlci5tX3B0cikKK3sKKyAgICBpZiAobV9wdHIpIHsKKyAgICAgICAgbV9yZWZzID0gb3RoZXIubV9yZWZzOworICAgICAgICBtX3JlZnMtPmluY1dlYWsodGhpcyk7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgord3A8VD46OndwKGNvbnN0IHNwPFU+JiBvdGhlcikKKyAgICA6IG1fcHRyKG90aGVyLm1fcHRyKQoreworICAgIGlmIChtX3B0cikgeworICAgICAgICBtX3JlZnMgPSBtX3B0ci0+Y3JlYXRlV2Vhayh0aGlzKTsKKyAgICB9Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Cit3cDxUPjo6fndwKCkKK3sKKyAgICBpZiAobV9wdHIpIG1fcmVmcy0+ZGVjV2Vhayh0aGlzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoVCogb3RoZXIpCit7CisgICAgd2Vha3JlZl90eXBlKiBuZXdSZWZzID0KKyAgICAgICAgb3RoZXIgPyBvdGhlci0+Y3JlYXRlV2Vhayh0aGlzKSA6IDA7CisgICAgaWYgKG1fcHRyKSBtX3JlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlcjsKKyAgICBtX3JlZnMgPSBuZXdSZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgd3A8VD4mIG90aGVyKQoreworICAgIGlmIChvdGhlci5tX3B0cikgb3RoZXIubV9yZWZzLT5pbmNXZWFrKHRoaXMpOworICAgIGlmIChtX3B0cikgbV9yZWZzLT5kZWNXZWFrKHRoaXMpOworICAgIG1fcHRyID0gb3RoZXIubV9wdHI7CisgICAgbV9yZWZzID0gb3RoZXIubV9yZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgc3A8VD4mIG90aGVyKQoreworICAgIHdlYWtyZWZfdHlwZSogbmV3UmVmcyA9CisgICAgICAgIG90aGVyICE9IE5VTEwgPyBvdGhlci0+Y3JlYXRlV2Vhayh0aGlzKSA6IDA7CisgICAgaWYgKG1fcHRyKSBtX3JlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlci5nZXQoKTsKKyAgICBtX3JlZnMgPSBuZXdSZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gdGVtcGxhdGU8dHlwZW5hbWUgVT4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoVSogb3RoZXIpCit7CisgICAgd2Vha3JlZl90eXBlKiBuZXdSZWZzID0KKyAgICAgICAgb3RoZXIgPyBvdGhlci0+Y3JlYXRlV2Vhayh0aGlzKSA6IDA7CisgICAgaWYgKG1fcHRyKSBtX3JlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlcjsKKyAgICBtX3JlZnMgPSBuZXdSZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gdGVtcGxhdGU8dHlwZW5hbWUgVT4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgd3A8VT4mIG90aGVyKQoreworICAgIGlmIChvdGhlci5tX3B0cikgb3RoZXIubV9yZWZzLT5pbmNXZWFrKHRoaXMpOworICAgIGlmIChtX3B0cikgbV9yZWZzLT5kZWNXZWFrKHRoaXMpOworICAgIG1fcHRyID0gb3RoZXIubV9wdHI7CisgICAgbV9yZWZzID0gb3RoZXIubV9yZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4gdGVtcGxhdGU8dHlwZW5hbWUgVT4KK3dwPFQ+JiB3cDxUPjo6b3BlcmF0b3IgPSAoY29uc3Qgc3A8VT4mIG90aGVyKQoreworICAgIHdlYWtyZWZfdHlwZSogbmV3UmVmcyA9CisgICAgICAgIG90aGVyICE9IE5VTEwgPyBvdGhlci0+Y3JlYXRlV2Vhayh0aGlzKSA6IDA7CisgICAgaWYgKG1fcHRyKSBtX3JlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlci5nZXQoKTsKKyAgICBtX3JlZnMgPSBuZXdSZWZzOworICAgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3ZvaWQgd3A8VD46OnNldF9vYmplY3RfYW5kX3JlZnMoVCogb3RoZXIsIHdlYWtyZWZfdHlwZSogcmVmcykKK3sKKyAgICBpZiAob3RoZXIpIHJlZnMtPmluY1dlYWsodGhpcyk7CisgICAgaWYgKG1fcHRyKSBtX3JlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgbV9wdHIgPSBvdGhlcjsKKyAgICBtX3JlZnMgPSByZWZzOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3A8VD4gd3A8VD46OnByb21vdGUoKSBjb25zdAoreworICAgIHJldHVybiBzcDxUPihtX3B0ciwgbV9yZWZzKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3ZvaWQgd3A8VD46OmNsZWFyKCkKK3sKKyAgICBpZiAobV9wdHIpIHsKKyAgICAgICAgbV9yZWZzLT5kZWNXZWFrKHRoaXMpOworICAgICAgICBtX3B0ciA9IDA7CisgICAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2lubGluZSBUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCB3cDxUPiYgdmFsKQoreworICAgIHRvIDw8ICJ3cDw+KCIgPDwgdmFsLnVuc2FmZV9nZXQoKSA8PCAiKSI7CisgICAgcmV0dXJuIHRvOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfUkVGX0JBU0VfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9SZXNvdXJjZVR5cGVzLmggYi9pbmNsdWRlL3V0aWxzL1Jlc291cmNlVHlwZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZDNmY2YyCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9SZXNvdXJjZVR5cGVzLmgKQEAgLTAsMCArMSwxNzIwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIERlZmluaXRpb25zIG9mIHJlc291cmNlIGRhdGEgc3RydWN0dXJlcy4KKy8vCisjaWZuZGVmIF9MSUJTX1VUSUxTX1JFU09VUkNFX1RZUEVTX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfUkVTT1VSQ0VfVFlQRVNfSAorCisjaW5jbHVkZSA8dXRpbHMvQXNzZXQuaD4KKyNpbmNsdWRlIDx1dGlscy9CeXRlT3JkZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorCisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAgUE5HIEV4dGVuc2lvbnMKKyAqCisgKiAgTmV3IHByaXZhdGUgY2h1bmtzIHRoYXQgbWF5IGJlIHBsYWNlZCBpbiBQTkcgaW1hZ2VzLgorICoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLworCisvKioKKyAqIFRoaXMgY2h1bmsgc3BlY2lmaWVzIGhvdyB0byBzcGxpdCBhbiBpbWFnZSBpbnRvIHNlZ21lbnRzIGZvcgorICogc2NhbGluZy4KKyAqCisgKiBUaGVyZSBhcmUgSiBob3Jpem9udGFsIGFuZCBLIHZlcnRpY2FsIHNlZ21lbnRzLiAgVGhlc2Ugc2VnbWVudHMgZGl2aWRlCisgKiB0aGUgaW1hZ2UgaW50byBKKksgcmVnaW9ucyBhcyBmb2xsb3dzICh3aGVyZSBKPTQgYW5kIEs9Myk6CisgKgorICogICAgICBGMCAgIFMwICAgIEYxICAgICBTMQorICogICArLS0tLS0rLS0tLSstLS0tLS0rLS0tLS0tLSsKKyAqIFMyfCAgMCAgfCAgMSB8ICAyICAgfCAgIDMgICB8CisgKiAgICstLS0tLSstLS0tKy0tLS0tLSstLS0tLS0tKworICogICB8ICAgICB8ICAgIHwgICAgICB8ICAgICAgIHwKKyAqICAgfCAgICAgfCAgICB8ICAgICAgfCAgICAgICB8CisgKiBGMnwgIDQgIHwgIDUgfCAgNiAgIHwgICA3ICAgfAorICogICB8ICAgICB8ICAgIHwgICAgICB8ICAgICAgIHwKKyAqICAgfCAgICAgfCAgICB8ICAgICAgfCAgICAgICB8CisgKiAgICstLS0tLSstLS0tKy0tLS0tLSstLS0tLS0tKworICogUzN8ICA4ICB8ICA5IHwgIDEwICB8ICAgMTEgIHwKKyAqICAgKy0tLS0tKy0tLS0rLS0tLS0tKy0tLS0tLS0rCisgKgorICogRWFjaCBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBzZWdtZW50IGlzIGNvbnNpZGVyZWQgdG8gYnkgZWl0aGVyCisgKiBzdHJldGNoYWJsZSAobWFya2VkIGJ5IHRoZSBTeCBsYWJlbHMpIG9yIGZpeGVkIChtYXJrZWQgYnkgdGhlIEZ5CisgKiBsYWJlbHMpLCBpbiB0aGUgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBheGlzLCByZXNwZWN0aXZlbHkuIEluIHRoZQorICogYWJvdmUgZXhhbXBsZSwgdGhlIGZpcnN0IGlzIGhvcml6b250YWwgc2VnbWVudCAoRjApIGlzIGZpeGVkLCB0aGUKKyAqIG5leHQgaXMgc3RyZXRjaGFibGUgYW5kIHRoZW4gdGhleSBjb250aW51ZSB0byBhbHRlcm5hdGUuIE5vdGUgdGhhdAorICogdGhlIHNlZ21lbnQgbGlzdCBmb3IgZWFjaCBheGlzIGNhbiBiZWdpbiBvciBlbmQgd2l0aCBhIHN0cmV0Y2hhYmxlCisgKiBvciBmaXhlZCBzZWdtZW50LgorICoKKyAqIFRoZSByZWxhdGl2ZSBzaXplcyBvZiB0aGUgc3RyZXRjaHkgc2VnbWVudHMgaW5kaWNhdGVzIHRoZSByZWxhdGl2ZQorICogYW1vdW50IG9mIHN0cmV0Y2hpbmVzcyBvZiB0aGUgcmVnaW9ucyBib3JkZXJlZCBieSB0aGUgc2VnbWVudHMuICBGb3IKKyAqIGV4YW1wbGUsIHJlZ2lvbnMgMywgNyBhbmQgMTEgYWJvdmUgd2lsbCB0YWtlIHVwIG1vcmUgaG9yaXpvbnRhbCBzcGFjZQorICogdGhhbiByZWdpb25zIDEsIDUgYW5kIDkgc2luY2UgdGhlIGhvcml6b25hbCBzZWdtZW50IGFzc29jaWF0ZWQgd2l0aAorICogdGhlIGZpcnN0IHNldCBvZiByZWdpb25zIGlzIGxhcmdlciB0aGFuIHRoZSBvdGhlciBzZXQgb2YgcmVnaW9ucy4gIFRoZQorICogcmF0aW9zIG9mIHRoZSBhbW91bnQgb2YgaG9yaXpvbnRhbCAob3IgdmVydGljYWwpIHNwYWNlIHRha2VuIGJ5IGFueQorICogdHdvIHN0cmV0Y2hhYmxlIHNsaWNlcyBpcyBleGFjdGx5IHRoZSByYXRpbyBvZiB0aGVpciBjb3JyZXNwb25kaW5nCisgKiBzZWdtZW50IGxlbmd0aHMuCisgKgorICogeERpdnMgYW5kIHlEaXZzIHBvaW50IHRvIGFycmF5cyBvZiBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBwaXhlbAorICogaW5kaWNlcy4gIFRoZSBmaXJzdCBwYWlyIG9mIERpdnMgKGluIGVpdGhlciBhcnJheSkgaW5kaWNhdGUgdGhlCisgKiBzdGFydGluZyBhbmQgZW5kaW5nIHBvaW50cyBvZiB0aGUgZmlyc3Qgc3RyZXRjaGFibGUgc2VnbWVudCBpbiB0aGF0CisgKiBheGlzLiBUaGUgbmV4dCBwYWlyIHNwZWNpZmllcyB0aGUgbmV4dCBzdHJldGNoYWJsZSBzZWdtZW50LCBldGMuIFNvCisgKiBpbiB0aGUgYWJvdmUgZXhhbXBsZSB4RGl2WzBdIGFuZCB4RGl2WzFdIHNwZWNpZnkgdGhlIGhvcml6b250YWwKKyAqIGNvb3JkaW5hdGVzIGZvciB0aGUgcmVnaW9ucyBsYWJlbGVkIDEsIDUgYW5kIDkuICB4RGl2WzJdIGFuZAorICogeERpdlszXSBzcGVjaWZ5IHRoZSBjb29yZGluYXRlcyBmb3IgcmVnaW9ucyAzLCA3IGFuZCAxMS4gTm90ZSB0aGF0CisgKiB0aGUgbGVmdG1vc3Qgc2xpY2VzIGFsd2F5cyBzdGFydCBhdCB4PTAgYW5kIHRoZSByaWdodG1vc3Qgc2xpY2VzCisgKiBhbHdheXMgZW5kIGF0IHRoZSBlbmQgb2YgdGhlIGltYWdlLiBTbywgZm9yIGV4YW1wbGUsIHRoZSByZWdpb25zIDAsCisgKiA0IGFuZCA4ICh3aGljaCBhcmUgZml4ZWQgYWxvbmcgdGhlIFggYXhpcykgc3RhcnQgYXQgeCB2YWx1ZSAwIGFuZAorICogZ28gdG8geERpdlswXSBhbWQgc2xpY2VzIDIsIDYgYW5kIDEwIHN0YXJ0IGF0IHhEaXZbMV0gYW5kIGVuZCBhdAorICogeERpdlsyXS4KKyAqCisgKiBUaGUgYXJyYXkgcG9pbnRlZCB0byBieSB0aGUgY29sb3JzIGZpZWxkIGxpc3RzIGNvbnRhaW5zIGhpbnRzIGZvcgorICogZWFjaCBvZiB0aGUgcmVnaW9ucy4gIFRoZXkgYXJlIG9yZGVyZWQgYWNjb3JkaW5nIGxlZnQtdG8tcmlnaHQgYW5kCisgKiB0b3AtdG8tYm90dG9tIGFzIGluZGljYXRlZCBhYm92ZS4gRm9yIGVhY2ggc2VnbWVudCB0aGF0IGlzIGEgc29saWQKKyAqIGNvbG9yIHRoZSBhcnJheSBlbnRyeSB3aWxsIGNvbnRhaW4gdGhhdCBjb2xvciB2YWx1ZTsgb3RoZXJ3aXNlIGl0CisgKiB3aWxsIGNvbnRhaW4gTk9fQ09MT1IuICBTZWdtZW50cyB0aGF0IGFyZSBjb21wbGV0ZWx5IHRyYW5zcGFyZW50CisgKiB3aWxsIGFsd2F5cyBoYXZlIHRoZSB2YWx1ZSBUUkFOU1BBUkVOVF9DT0xPUi4KKyAqCisgKiBUaGUgUE5HIGNodW5rIHR5cGUgaXMgIm5wVGMiLgorICovCitzdHJ1Y3QgUmVzX3BuZ185cGF0Y2gKK3sKKyAgICBSZXNfcG5nXzlwYXRjaCgpIDogd2FzRGVzZXJpYWxpemVkKGZhbHNlKSwgeERpdnMoTlVMTCksCisgICAgICAgICAgICAgICAgICAgICAgIHlEaXZzKE5VTEwpLCBjb2xvcnMoTlVMTCkgeyB9CisKKyAgICBpbnQ4X3Qgd2FzRGVzZXJpYWxpemVkOworICAgIGludDhfdCBudW1YRGl2czsKKyAgICBpbnQ4X3QgbnVtWURpdnM7CisgICAgaW50OF90IG51bUNvbG9yczsKKworICAgIC8vIFRoZXNlIHRlbGwgd2hlcmUgdGhlIG5leHQgc2VjdGlvbiBvZiBhIHBhdGNoIHN0YXJ0cy4KKyAgICAvLyBGb3IgZXhhbXBsZSwgdGhlIGZpcnN0IHBhdGNoIGluY2x1ZGVzIHRoZSBwaXhlbHMgZnJvbQorICAgIC8vIDAgdG8geERpdnNbMF0tMSBhbmQgdGhlIHNlY29uZCBwYXRjaCBpbmNsdWRlcyB0aGUgcGl4ZWxzCisgICAgLy8gZnJvbSB4RGl2c1swXSB0byB4RGl2c1sxXS0xLgorICAgIC8vIE5vdGU6IGFsbG9jYXRpb24vZnJlZSBvZiB0aGVzZSBwb2ludGVycyBpcyBsZWZ0IHRvIHRoZSBjYWxsZXIuCisgICAgaW50MzJfdCogeERpdnM7CisgICAgaW50MzJfdCogeURpdnM7CisKKyAgICBpbnQzMl90IHBhZGRpbmdMZWZ0LCBwYWRkaW5nUmlnaHQ7CisgICAgaW50MzJfdCBwYWRkaW5nVG9wLCBwYWRkaW5nQm90dG9tOworCisgICAgZW51bSB7CisgICAgICAgIC8vIFRoZSA5IHBhdGNoIHNlZ21lbnQgaXMgbm90IGEgc29saWQgY29sb3IuCisgICAgICAgIE5PX0NPTE9SID0gMHgwMDAwMDAwMSwKKworICAgICAgICAvLyBUaGUgOSBwYXRjaCBzZWdtZW50IGlzIGNvbXBsZXRlbHkgdHJhbnNwYXJlbnQuCisgICAgICAgIFRSQU5TUEFSRU5UX0NPTE9SID0gMHgwMDAwMDAwMAorICAgIH07CisgICAgLy8gTm90ZTogYWxsb2NhdGlvbi9mcmVlIG9mIHRoaXMgcG9pbnRlciBpcyBsZWZ0IHRvIHRoZSBjYWxsZXIuCisgICAgdWludDMyX3QqIGNvbG9yczsKKworICAgIC8vIENvbnZlcnQgZGF0YSBmcm9tIGRldmljZSByZXByZXNlbnRhdGlvbiB0byBQTkcgZmlsZSByZXByZXNlbnRhdGlvbi4KKyAgICB2b2lkIGRldmljZVRvRmlsZSgpOworICAgIC8vIENvbnZlcnQgZGF0YSBmcm9tIFBORyBmaWxlIHJlcHJlc2VudGF0aW9uIHRvIGRldmljZSByZXByZXNlbnRhdGlvbi4KKyAgICB2b2lkIGZpbGVUb0RldmljZSgpOworICAgIC8vIFNlcmlhbGl6ZS9NYXJzaGFsbCB0aGUgcGF0Y2ggZGF0YSBpbnRvIGEgbmV3bHkgbWFsbG9jLWVkIGJsb2NrCisgICAgdm9pZCogc2VyaWFsaXplKCk7CisgICAgLy8gU2VyaWFsaXplL01hcnNoYWxsIHRoZSBwYXRjaCBkYXRhCisgICAgdm9pZCBzZXJpYWxpemUodm9pZCogb3V0RGF0YSk7CisgICAgLy8gRGVzZXJpYWxpemUvVW5tYXJzaGFsbCB0aGUgcGF0Y2ggZGF0YQorICAgIHN0YXRpYyBSZXNfcG5nXzlwYXRjaCogZGVzZXJpYWxpemUoY29uc3Qgdm9pZCogZGF0YSk7CisgICAgLy8gQ29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGUgc2VyaWFsaXplZCBkYXRhIHN0cnVjdHVyZQorICAgIHNpemVfdCBzZXJpYWxpemVkU2l6ZSgpOworfTsKKworLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAgQmFzZSBUeXBlcworICoKKyAqICBUaGVzZSBhcmUgc3RhbmRhcmQgdHlwZXMgdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gbXVsdGlwbGUgc3BlY2lmaWMKKyAqICByZXNvdXJjZSB0eXBlcy4KKyAqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KKworLyoqCisgKiBIZWFkZXIgdGhhdCBhcHBlYXJzIGF0IHRoZSBmcm9udCBvZiBldmVyeSBkYXRhIGNodW5rIGluIGEgcmVzb3VyY2UuCisgKi8KK3N0cnVjdCBSZXNDaHVua19oZWFkZXIKK3sKKyAgICAvLyBUeXBlIGlkZW50aWZpZXIgZm9yIHRoaXMgY2h1bmsuICBUaGUgbWVhbmluZyBvZiB0aGlzIHZhbHVlIGRlcGVuZHMKKyAgICAvLyBvbiB0aGUgY29udGFpbmluZyBjaHVuay4KKyAgICB1aW50MTZfdCB0eXBlOworCisgICAgLy8gU2l6ZSBvZiB0aGUgY2h1bmsgaGVhZGVyIChpbiBieXRlcykuICBBZGRpbmcgdGhpcyB2YWx1ZSB0bworICAgIC8vIHRoZSBhZGRyZXNzIG9mIHRoZSBjaHVuayBhbGxvd3MgeW91IHRvIGZpbmQgaXRzIGFzc29jaWF0ZWQgZGF0YQorICAgIC8vIChpZiBhbnkpLgorICAgIHVpbnQxNl90IGhlYWRlclNpemU7CisKKyAgICAvLyBUb3RhbCBzaXplIG9mIHRoaXMgY2h1bmsgKGluIGJ5dGVzKS4gIFRoaXMgaXMgdGhlIGNodW5rU2l6ZSBwbHVzCisgICAgLy8gdGhlIHNpemUgb2YgYW55IGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBjaHVuay4gIEFkZGluZyB0aGlzIHZhbHVlCisgICAgLy8gdG8gdGhlIGNodW5rIGFsbG93cyB5b3UgdG8gY29tcGxldGVseSBza2lwIGl0cyBjb250ZW50cyAoaW5jbHVkaW5nCisgICAgLy8gYW55IGNoaWxkIGNodW5rcykuICBJZiB0aGlzIHZhbHVlIGlzIHRoZSBzYW1lIGFzIGNodW5rU2l6ZSwgdGhlcmUgaXMKKyAgICAvLyBubyBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgY2h1bmsuCisgICAgdWludDMyX3Qgc2l6ZTsKK307CisKK2VudW0geworICAgIFJFU19OVUxMX1RZUEUgICAgICAgICAgICAgICA9IDB4MDAwMCwKKyAgICBSRVNfU1RSSU5HX1BPT0xfVFlQRSAgICAgICAgPSAweDAwMDEsCisgICAgUkVTX1RBQkxFX1RZUEUgICAgICAgICAgICAgID0gMHgwMDAyLAorICAgIFJFU19YTUxfVFlQRSAgICAgICAgICAgICAgICA9IDB4MDAwMywKKworICAgIC8vIENodW5rIHR5cGVzIGluIFJFU19YTUxfVFlQRQorICAgIFJFU19YTUxfRklSU1RfQ0hVTktfVFlQRSAgICA9IDB4MDEwMCwKKyAgICBSRVNfWE1MX1NUQVJUX05BTUVTUEFDRV9UWVBFPSAweDAxMDAsCisgICAgUkVTX1hNTF9FTkRfTkFNRVNQQUNFX1RZUEUgID0gMHgwMTAxLAorICAgIFJFU19YTUxfU1RBUlRfRUxFTUVOVF9UWVBFICA9IDB4MDEwMiwKKyAgICBSRVNfWE1MX0VORF9FTEVNRU5UX1RZUEUgICAgPSAweDAxMDMsCisgICAgUkVTX1hNTF9DREFUQV9UWVBFICAgICAgICAgID0gMHgwMTA0LAorICAgIFJFU19YTUxfTEFTVF9DSFVOS19UWVBFICAgICA9IDB4MDE3ZiwKKyAgICAvLyBUaGlzIGNvbnRhaW5zIGEgdWludDMyX3QgYXJyYXkgbWFwcGluZyBzdHJpbmdzIGluIHRoZSBzdHJpbmcKKyAgICAvLyBwb29sIGJhY2sgdG8gcmVzb3VyY2UgaWRlbnRpZmllcnMuICBJdCBpcyBvcHRpb25hbC4KKyAgICBSRVNfWE1MX1JFU09VUkNFX01BUF9UWVBFICAgPSAweDAxODAsCisKKyAgICAvLyBDaHVuayB0eXBlcyBpbiBSRVNfVEFCTEVfVFlQRQorICAgIFJFU19UQUJMRV9QQUNLQUdFX1RZUEUgICAgICA9IDB4MDIwMCwKKyAgICBSRVNfVEFCTEVfVFlQRV9UWVBFICAgICAgICAgPSAweDAyMDEsCisgICAgUkVTX1RBQkxFX1RZUEVfU1BFQ19UWVBFICAgID0gMHgwMjAyCit9OworCisvKioKKyAqIE1hY3JvcyBmb3IgYnVpbGRpbmcvc3BsaXR0aW5nIHJlc291cmNlIGlkZW50aWZpZXJzLgorICovCisjZGVmaW5lIFJlc19WQUxJRElEKHJlc2lkKSAocmVzaWQgIT0gMCkKKyNkZWZpbmUgUmVzX0NIRUNLSUQocmVzaWQpICgocmVzaWQmMHhGRkZGMDAwMCkgIT0gMCkKKyNkZWZpbmUgUmVzX01BS0VJRChwYWNrYWdlLCB0eXBlLCBlbnRyeSkgXAorICAgICgoKHBhY2thZ2UrMSk8PDI0KSB8ICgoKHR5cGUrMSkmMHhGRik8PDE2KSB8IChlbnRyeSYweEZGRkYpKQorI2RlZmluZSBSZXNfR0VUUEFDS0FHRShpZCkgKChpZD4+MjQpLTEpCisjZGVmaW5lIFJlc19HRVRUWVBFKGlkKSAoKChpZD4+MTYpJjB4RkYpLTEpCisjZGVmaW5lIFJlc19HRVRFTlRSWShpZCkgKGlkJjB4RkZGRikKKworI2RlZmluZSBSZXNfSU5URVJOQUxJRChyZXNpZCkgKChyZXNpZCYweEZGRkYwMDAwKSAhPSAwICYmIChyZXNpZCYweEZGMDAwMCkgPT0gMCkKKyNkZWZpbmUgUmVzX01BS0VJTlRFUk5BTChlbnRyeSkgKDB4MDEwMDAwMDAgfCAoZW50cnkmMHhGRkZGKSkKKyNkZWZpbmUgUmVzX01BS0VBUlJBWShlbnRyeSkgKDB4MDIwMDAwMDAgfCAoZW50cnkmMHhGRkZGKSkKKworI2RlZmluZSBSZXNfTUFYUEFDS0FHRSAyNTUKKworLyoqCisgKiBSZXByZXNlbnRhdGlvbiBvZiBhIHZhbHVlIGluIGEgcmVzb3VyY2UsIHN1cHBseWluZyB0eXBlCisgKiBpbmZvcm1hdGlvbi4KKyAqLworc3RydWN0IFJlc192YWx1ZQoreworICAgIC8vIE51bWJlciBvZiBieXRlcyBpbiB0aGlzIHN0cnVjdHVyZS4KKyAgICB1aW50MTZfdCBzaXplOworCisgICAgLy8gQWx3YXlzIHNldCB0byAwLgorICAgIHVpbnQ4X3QgcmVzMDsKKyAgICAgICAgCisgICAgLy8gVHlwZSBvZiB0aGUgZGF0YSB2YWx1ZS4KKyAgICBlbnVtIHsKKyAgICAgICAgLy8gQ29udGFpbnMgbm8gZGF0YS4KKyAgICAgICAgVFlQRV9OVUxMID0gMHgwMCwKKyAgICAgICAgLy8gVGhlICdkYXRhJyBob2xkcyBhIFJlc1RhYmxlX3JlZiwgYSByZWZlcmVuY2UgdG8gYW5vdGhlciByZXNvdXJjZQorICAgICAgICAvLyB0YWJsZSBlbnRyeS4KKyAgICAgICAgVFlQRV9SRUZFUkVOQ0UgPSAweDAxLAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGhvbGRzIGFuIGF0dHJpYnV0ZSByZXNvdXJjZSBpZGVudGlmaWVyLgorICAgICAgICBUWVBFX0FUVFJJQlVURSA9IDB4MDIsCisgICAgICAgIC8vIFRoZSAnZGF0YScgaG9sZHMgYW4gaW5kZXggaW50byB0aGUgY29udGFpbmluZyByZXNvdXJjZSB0YWJsZSdzCisgICAgICAgIC8vIGdsb2JhbCB2YWx1ZSBzdHJpbmcgcG9vbC4KKyAgICAgICAgVFlQRV9TVFJJTkcgPSAweDAzLAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGhvbGRzIGEgc2luZ2xlLXByZWNpc2lvbiBmbG9hdGluZyBwb2ludCBudW1iZXIuCisgICAgICAgIFRZUEVfRkxPQVQgPSAweDA0LAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGhvbGRzIGEgY29tcGxleCBudW1iZXIgZW5jb2RpbmcgYSBkaW1lbnNpb24gdmFsdWUsCisgICAgICAgIC8vIHN1Y2ggYXMgIjEwMGluIi4KKyAgICAgICAgVFlQRV9ESU1FTlNJT04gPSAweDA1LAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGhvbGRzIGEgY29tcGxleCBudW1iZXIgZW5jb2RpbmcgYSBmcmFjdGlvbiBvZiBhCisgICAgICAgIC8vIGNvbnRhaW5lci4KKyAgICAgICAgVFlQRV9GUkFDVElPTiA9IDB4MDYsCisKKyAgICAgICAgLy8gQmVnaW5uaW5nIG9mIGludGVnZXIgZmxhdm9ycy4uLgorICAgICAgICBUWVBFX0ZJUlNUX0lOVCA9IDB4MTAsCisKKyAgICAgICAgLy8gVGhlICdkYXRhJyBpcyBhIHJhdyBpbnRlZ2VyIHZhbHVlIG9mIHRoZSBmb3JtIG4uLm4uCisgICAgICAgIFRZUEVfSU5UX0RFQyA9IDB4MTAsCisgICAgICAgIC8vIFRoZSAnZGF0YScgaXMgYSByYXcgaW50ZWdlciB2YWx1ZSBvZiB0aGUgZm9ybSAweG4uLm4uCisgICAgICAgIFRZUEVfSU5UX0hFWCA9IDB4MTEsCisgICAgICAgIC8vIFRoZSAnZGF0YScgaXMgZWl0aGVyIDAgb3IgMSwgZm9yIGlucHV0ICJmYWxzZSIgb3IgInRydWUiIHJlc3BlY3RpdmVseS4KKyAgICAgICAgVFlQRV9JTlRfQk9PTEVBTiA9IDB4MTIsCisKKyAgICAgICAgLy8gQmVnaW5uaW5nIG9mIGNvbG9yIGludGVnZXIgZmxhdm9ycy4uLgorICAgICAgICBUWVBFX0ZJUlNUX0NPTE9SX0lOVCA9IDB4MWMsCisKKyAgICAgICAgLy8gVGhlICdkYXRhJyBpcyBhIHJhdyBpbnRlZ2VyIHZhbHVlIG9mIHRoZSBmb3JtICNhYXJyZ2diYi4KKyAgICAgICAgVFlQRV9JTlRfQ09MT1JfQVJHQjggPSAweDFjLAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGlzIGEgcmF3IGludGVnZXIgdmFsdWUgb2YgdGhlIGZvcm0gI3JyZ2diYi4KKyAgICAgICAgVFlQRV9JTlRfQ09MT1JfUkdCOCA9IDB4MWQsCisgICAgICAgIC8vIFRoZSAnZGF0YScgaXMgYSByYXcgaW50ZWdlciB2YWx1ZSBvZiB0aGUgZm9ybSAjYXJnYi4KKyAgICAgICAgVFlQRV9JTlRfQ09MT1JfQVJHQjQgPSAweDFlLAorICAgICAgICAvLyBUaGUgJ2RhdGEnIGlzIGEgcmF3IGludGVnZXIgdmFsdWUgb2YgdGhlIGZvcm0gI3JnYi4KKyAgICAgICAgVFlQRV9JTlRfQ09MT1JfUkdCNCA9IDB4MWYsCisKKyAgICAgICAgLy8gLi4uZW5kIG9mIGludGVnZXIgZmxhdm9ycy4KKyAgICAgICAgVFlQRV9MQVNUX0NPTE9SX0lOVCA9IDB4MWYsCisKKyAgICAgICAgLy8gLi4uZW5kIG9mIGludGVnZXIgZmxhdm9ycy4KKyAgICAgICAgVFlQRV9MQVNUX0lOVCA9IDB4MWYKKyAgICB9OworICAgIHVpbnQ4X3QgZGF0YVR5cGU7CisKKyAgICAvLyBTdHJ1Y3R1cmUgb2YgY29tcGxleCBkYXRhIHZhbHVlcyAoVFlQRV9VTklUIGFuZCBUWVBFX0ZSQUNUSU9OKQorICAgIGVudW0geworICAgICAgICAvLyBXaGVyZSB0aGUgdW5pdCB0eXBlIGluZm9ybWF0aW9uIGlzLiAgVGhpcyBnaXZlcyB1cyAxNiBwb3NzaWJsZQorICAgICAgICAvLyB0eXBlcywgYXMgZGVmaW5lZCBiZWxvdy4KKyAgICAgICAgQ09NUExFWF9VTklUX1NISUZUID0gMCwKKyAgICAgICAgQ09NUExFWF9VTklUX01BU0sgPSAweGYsCisKKyAgICAgICAgLy8gVFlQRV9ESU1FTlNJT046IFZhbHVlIGlzIHJhdyBwaXhlbHMuCisgICAgICAgIENPTVBMRVhfVU5JVF9QWCA9IDAsCisgICAgICAgIC8vIFRZUEVfRElNRU5TSU9OOiBWYWx1ZSBpcyBEZXZpY2UgSW5kZXBlbmRlbnQgUGl4ZWxzLgorICAgICAgICBDT01QTEVYX1VOSVRfRElQID0gMSwKKyAgICAgICAgLy8gVFlQRV9ESU1FTlNJT046IFZhbHVlIGlzIGEgU2NhbGVkIGRldmljZSBpbmRlcGVuZGVudCBQaXhlbHMuCisgICAgICAgIENPTVBMRVhfVU5JVF9TUCA9IDIsCisgICAgICAgIC8vIFRZUEVfRElNRU5TSU9OOiBWYWx1ZSBpcyBpbiBwb2ludHMuCisgICAgICAgIENPTVBMRVhfVU5JVF9QVCA9IDMsCisgICAgICAgIC8vIFRZUEVfRElNRU5TSU9OOiBWYWx1ZSBpcyBpbiBpbmNoZXMuCisgICAgICAgIENPTVBMRVhfVU5JVF9JTiA9IDQsCisgICAgICAgIC8vIFRZUEVfRElNRU5TSU9OOiBWYWx1ZSBpcyBpbiBtaWxsaW1ldGVycy4KKyAgICAgICAgQ09NUExFWF9VTklUX01NID0gNSwKKworICAgICAgICAvLyBUWVBFX0ZSQUNUSU9OOiBBIGJhc2ljIGZyYWN0aW9uIG9mIHRoZSBvdmVyYWxsIHNpemUuCisgICAgICAgIENPTVBMRVhfVU5JVF9GUkFDVElPTiA9IDAsCisgICAgICAgIC8vIFRZUEVfRlJBQ1RJT046IEEgZnJhY3Rpb24gb2YgdGhlIHBhcmVudCBzaXplLgorICAgICAgICBDT01QTEVYX1VOSVRfRlJBQ1RJT05fUEFSRU5UID0gMSwKKworICAgICAgICAvLyBXaGVyZSB0aGUgcmFkaXggaW5mb3JtYXRpb24gaXMsIHRlbGxpbmcgd2hlcmUgdGhlIGRlY2ltYWwgcGxhY2UKKyAgICAgICAgLy8gYXBwZWFycyBpbiB0aGUgbWFudGlzc2EuICBUaGlzIGdpdmUgdXMgNCBwb3NzaWJsZSBmaXhlZCBwb2ludAorICAgICAgICAvLyByZXByZXNlbnRhdGlvbnMgYXMgZGVmaW5lZCBiZWxvdy4KKyAgICAgICAgQ09NUExFWF9SQURJWF9TSElGVCA9IDQsCisgICAgICAgIENPTVBMRVhfUkFESVhfTUFTSyA9IDB4MywKKworICAgICAgICAvLyBUaGUgbWFudGlzc2EgaXMgYW4gaW50ZWdyYWwgbnVtYmVyIC0tIGkuZS4sIDB4bm5ubm5uLjAKKyAgICAgICAgQ09NUExFWF9SQURJWF8yM3AwID0gMCwKKyAgICAgICAgLy8gVGhlIG1hbnRpc3NhIG1hZ25pdHVkZSBpcyAxNiBiaXRzIC0tIGkuZSwgMHhubm5uLm5uCisgICAgICAgIENPTVBMRVhfUkFESVhfMTZwNyA9IDEsCisgICAgICAgIC8vIFRoZSBtYW50aXNzYSBtYWduaXR1ZGUgaXMgOCBiaXRzIC0tIGkuZSwgMHhubi5ubm5uCisgICAgICAgIENPTVBMRVhfUkFESVhfOHAxNSA9IDIsCisgICAgICAgIC8vIFRoZSBtYW50aXNzYSBtYWduaXR1ZGUgaXMgMCBiaXRzIC0tIGkuZSwgMHgwLm5ubm5ubgorICAgICAgICBDT01QTEVYX1JBRElYXzBwMjMgPSAzLAorCisgICAgICAgIC8vIFdoZXJlIHRoZSBhY3R1YWwgdmFsdWUgaXMuICBUaGlzIGdpdmVzIHVzIDIzIGJpdHMgb2YKKyAgICAgICAgLy8gcHJlY2lzaW9uLiAgVGhlIHRvcCBiaXQgaXMgdGhlIHNpZ24uCisgICAgICAgIENPTVBMRVhfTUFOVElTU0FfU0hJRlQgPSA4LAorICAgICAgICBDT01QTEVYX01BTlRJU1NBX01BU0sgPSAweGZmZmZmZgorICAgIH07CisKKyAgICAvLyBUaGUgZGF0YSBmb3IgdGhpcyBpdGVtLCBhcyBpbnRlcnByZXRlZCBhY2NvcmRpbmcgdG8gZGF0YVR5cGUuCisgICAgdWludDMyX3QgZGF0YTsKKworICAgIHZvaWQgY29weUZyb21fZHRvaChjb25zdCBSZXNfdmFsdWUmIHNyYyk7Cit9OworCisvKioKKyAqICBUaGlzIGlzIGEgcmVmZXJlbmNlIHRvIGEgdW5pcXVlIGVudHJ5IChhIFJlc1RhYmxlX2VudHJ5IHN0cnVjdHVyZSkKKyAqICBpbiBhIHJlc291cmNlIHRhYmxlLiAgVGhlIHZhbHVlIGlzIHN0cnVjdHVyZWQgYXM6IDB4cHB0dGVlZWUsCisgKiAgd2hlcmUgcHAgaXMgdGhlIHBhY2thZ2UgaW5kZXgsIHR0IGlzIHRoZSB0eXBlIGluZGV4IGluIHRoYXQKKyAqICBwYWNrYWdlLCBhbmQgZWVlZSBpcyB0aGUgZW50cnkgaW5kZXggaW4gdGhhdCB0eXBlLiAgVGhlIHBhY2thZ2UKKyAqICBhbmQgdHlwZSB2YWx1ZXMgc3RhcnQgYXQgMSBmb3IgdGhlIGZpcnN0IGl0ZW0sIHRvIGhlbHAgY2F0Y2ggY2FzZXMKKyAqICB3aGVyZSB0aGV5IGhhdmUgbm90IGJlZW4gc3VwcGxpZWQuCisgKi8KK3N0cnVjdCBSZXNUYWJsZV9yZWYKK3sKKyAgICB1aW50MzJfdCBpZGVudDsKK307CisKKy8qKgorICogUmVmZXJlbmNlIHRvIGEgc3RyaW5nIGluIGEgc3RyaW5nIHBvb2wuCisgKi8KK3N0cnVjdCBSZXNTdHJpbmdQb29sX3JlZgoreworICAgIC8vIEluZGV4IGludG8gdGhlIHN0cmluZyBwb29sIHRhYmxlICh1aW50MzJfdC1vZmZzZXQgZnJvbSB0aGUgaW5kaWNlcworICAgIC8vIGltbWVkaWF0ZWx5IGFmdGVyIFJlc1N0cmluZ1Bvb2xfaGVhZGVyKSBhdCB3aGljaCB0byBmaW5kIHRoZSBsb2NhdGlvbgorICAgIC8vIG9mIHRoZSBzdHJpbmcgZGF0YSBpbiB0aGUgcG9vbC4KKyAgICB1aW50MzJfdCBpbmRleDsKK307CisKKy8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogIFN0cmluZyBQb29sCisgKgorICogIEEgc2V0IG9mIHN0cmluZ3MgdGhhdCBjYW4gYmUgcmVmZXJlbmNlcyBieSBvdGhlcnMgdGhyb3VnaCBhCisgKiAgUmVzU3RyaW5nUG9vbF9yZWYuCisgKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCisKKy8qKgorICogRGVmaW5pdGlvbiBmb3IgYSBwb29sIG9mIHN0cmluZ3MuICBUaGUgZGF0YSBvZiB0aGlzIGNodW5rIGlzIGFuCisgKiBhcnJheSBvZiB1aW50MzJfdCBwcm92aWRpbmcgaW5kaWNlcyBpbnRvIHRoZSBwb29sLCByZWxhdGl2ZSB0bworICogc3RyaW5nc1N0YXJ0LiAgQXQgc3RyaW5nc1N0YXJ0IGFyZSBhbGwgb2YgdGhlIFVURi0xNiBzdHJpbmdzCisgKiBjb25jYXRlbmF0ZWQgdG9nZXRoZXI7IGVhY2ggc3RhcnRzIHdpdGggYSB1aW50MTZfdCBvZiB0aGUgc3RyaW5nJ3MKKyAqIGxlbmd0aCBhbmQgZWFjaCBlbmRzIHdpdGggYSAweDAwMDAgdGVybWluYXRvci4gIElmIGEgc3RyaW5nIGlzID4KKyAqIDMyNzY3IGNoYXJhY3RlcnMsIHRoZSBoaWdoIGJpdCBvZiB0aGUgbGVuZ3RoIGlzIHNldCBtZWFuaW5nIHRvIHRha2UKKyAqIHRob3NlIDE1IGJpdHMgYXMgYSBoaWdoIHdvcmQgYW5kIGl0IHdpbGwgYmUgZm9sbG93ZWQgYnkgYW5vdGhlcgorICogdWludDE2X3QgY29udGFpbmluZyB0aGUgbG93IHdvcmQuCisgKgorICogSWYgc3R5bGVDb3VudCBpcyBub3QgemVybywgdGhlbiBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIGFycmF5IG9mCisgKiB1aW50MzJfdCBpbmRpY2VzIGludG8gdGhlIHN0cmluZyB0YWJsZSBpcyBhbm90aGVyIGFycmF5IG9mIGluZGljZXMKKyAqIGludG8gYSBzdHlsZSB0YWJsZSBzdGFydGluZyBhdCBzdHlsZXNTdGFydC4gIEVhY2ggZW50cnkgaW4gdGhlCisgKiBzdHlsZSB0YWJsZSBpcyBhbiBhcnJheSBvZiBSZXNTdHJpbmdQb29sX3NwYW4gc3RydWN0dXJlcy4KKyAqLworc3RydWN0IFJlc1N0cmluZ1Bvb2xfaGVhZGVyCit7CisgICAgc3RydWN0IFJlc0NodW5rX2hlYWRlciBoZWFkZXI7CisKKyAgICAvLyBOdW1iZXIgb2Ygc3RyaW5ncyBpbiB0aGlzIHBvb2wgKG51bWJlciBvZiB1aW50MzJfdCBpbmRpY2VzIHRoYXQgZm9sbG93CisgICAgLy8gaW4gdGhlIGRhdGEpLgorICAgIHVpbnQzMl90IHN0cmluZ0NvdW50OworCisgICAgLy8gTnVtYmVyIG9mIHN0eWxlIHNwYW4gYXJyYXlzIGluIHRoZSBwb29sIChudW1iZXIgb2YgdWludDMyX3QgaW5kaWNlcworICAgIC8vIGZvbGxvdyB0aGUgc3RyaW5nIGluZGljZXMpLgorICAgIHVpbnQzMl90IHN0eWxlQ291bnQ7CisKKyAgICAvLyBGbGFncy4KKyAgICBlbnVtIHsKKyAgICAgICAgLy8gSWYgc2V0LCB0aGUgc3RyaW5nIGluZGV4IGlzIHNvcnRlZCBieSB0aGUgc3RyaW5nIHZhbHVlcyAoYmFzZWQKKyAgICAgICAgLy8gb24gc3RyY21wMTYoKSkuCisgICAgICAgIFNPUlRFRF9GTEFHID0gMTw8MAorICAgIH07CisgICAgdWludDMyX3QgZmxhZ3M7CisKKyAgICAvLyBJbmRleCBmcm9tIGhlYWRlciBvZiB0aGUgc3RyaW5nIGRhdGEuCisgICAgdWludDMyX3Qgc3RyaW5nc1N0YXJ0OworCisgICAgLy8gSW5kZXggZnJvbSBoZWFkZXIgb2YgdGhlIHN0eWxlIGRhdGEuCisgICAgdWludDMyX3Qgc3R5bGVzU3RhcnQ7Cit9OworCisvKioKKyAqIFRoaXMgc3RydWN0dXJlIGRlZmluZXMgYSBzcGFuIG9mIHN0eWxlIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aAorICogYSBzdHJpbmcgaW4gdGhlIHBvb2wuCisgKi8KK3N0cnVjdCBSZXNTdHJpbmdQb29sX3NwYW4KK3sKKyAgICBlbnVtIHsKKyAgICAgICAgRU5EID0gMHhGRkZGRkZGRgorICAgIH07CisKKyAgICAvLyBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBzcGFuIC0tIHRoYXQgaXMsIHRoZSBuYW1lIG9mIHRoZSBYTUwKKyAgICAvLyB0YWcgdGhhdCBkZWZpbmVkIGl0LiAgVGhlIHNwZWNpYWwgdmFsdWUgRU5EICgweEZGRkZGRkZGKSBpbmRpY2F0ZXMKKyAgICAvLyB0aGUgZW5kIG9mIGFuIGFycmF5IG9mIHNwYW5zLgorICAgIFJlc1N0cmluZ1Bvb2xfcmVmIG5hbWU7CisKKyAgICAvLyBUaGUgcmFuZ2Ugb2YgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIHRoYXQgdGhpcyBzcGFuIGFwcGxpZXMgdG8uCisgICAgdWludDMyX3QgZmlyc3RDaGFyLCBsYXN0Q2hhcjsKK307CisKKy8qKgorICogQ29udmVuaWVuY2UgY2xhc3MgZm9yIGFjY2Vzc2luZyBkYXRhIGluIGEgUmVzU3RyaW5nUG9vbCByZXNvdXJjZS4KKyAqLworY2xhc3MgUmVzU3RyaW5nUG9vbAoreworcHVibGljOgorICAgIFJlc1N0cmluZ1Bvb2woKTsKKyAgICBSZXNTdHJpbmdQb29sKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCBib29sIGNvcHlEYXRhPWZhbHNlKTsKKyAgICB+UmVzU3RyaW5nUG9vbCgpOworCisgICAgc3RhdHVzX3Qgc2V0VG8oY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIGJvb2wgY29weURhdGE9ZmFsc2UpOworCisgICAgc3RhdHVzX3QgZ2V0RXJyb3IoKSBjb25zdDsKKworICAgIHZvaWQgdW5pbml0KCk7CisKKyAgICBpbmxpbmUgY29uc3QgY2hhcjE2X3QqIHN0cmluZ0F0KGNvbnN0IFJlc1N0cmluZ1Bvb2xfcmVmJiByZWYsIHNpemVfdCogb3V0TGVuKSBjb25zdCB7CisgICAgICAgIHJldHVybiBzdHJpbmdBdChyZWYuaW5kZXgsIG91dExlbik7CisgICAgfQorICAgIGNvbnN0IGNoYXIxNl90KiBzdHJpbmdBdChzaXplX3QgaWR4LCBzaXplX3QqIG91dExlbikgY29uc3Q7CisKKyAgICBjb25zdCBSZXNTdHJpbmdQb29sX3NwYW4qIHN0eWxlQXQoY29uc3QgUmVzU3RyaW5nUG9vbF9yZWYmIHJlZikgY29uc3Q7CisgICAgY29uc3QgUmVzU3RyaW5nUG9vbF9zcGFuKiBzdHlsZUF0KHNpemVfdCBpZHgpIGNvbnN0OworCisgICAgc3NpemVfdCBpbmRleE9mU3RyaW5nKGNvbnN0IGNoYXIxNl90KiBzdHIsIHNpemVfdCBzdHJMZW4pIGNvbnN0OworCisgICAgc2l6ZV90IHNpemUoKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBzdGF0dXNfdCAgICAgICAgICAgICAgICAgICAgbUVycm9yOworICAgIHZvaWQqICAgICAgICAgICAgICAgICAgICAgICBtT3duZWREYXRhOworICAgIGNvbnN0IFJlc1N0cmluZ1Bvb2xfaGVhZGVyKiBtSGVhZGVyOworICAgIHNpemVfdCAgICAgICAgICAgICAgICAgICAgICBtU2l6ZTsKKyAgICBjb25zdCB1aW50MzJfdCogICAgICAgICAgICAgbUVudHJpZXM7CisgICAgY29uc3QgdWludDMyX3QqICAgICAgICAgICAgIG1FbnRyeVN0eWxlczsKKyAgICBjb25zdCBjaGFyMTZfdCogICAgICAgICAgICAgbVN0cmluZ3M7CisgICAgdWludDMyX3QgICAgICAgICAgICAgICAgICAgIG1TdHJpbmdQb29sU2l6ZTsgICAgLy8gbnVtYmVyIG9mIHVpbnQxNl90CisgICAgY29uc3QgdWludDMyX3QqICAgICAgICAgICAgIG1TdHlsZXM7CisgICAgdWludDMyX3QgICAgICAgICAgICAgICAgICAgIG1TdHlsZVBvb2xTaXplOyAgICAvLyBudW1iZXIgb2YgdWludDMyX3QKK307CisKKy8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogIFhNTCBUcmVlCisgKgorICogIEJpbmFyeSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBUaGlzIGlzIGRlc2lnbmVkIHRvCisgKiAgZXhwcmVzcyBldmVyeXRoaW5nIGluIGFuIFhNTCBkb2N1bWVudCwgaW4gYSBmb3JtIHRoYXQgaXMgbXVjaAorICogIGVhc2llciB0byBwYXJzZSBvbiB0aGUgZGV2aWNlLgorICoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLworCisvKioKKyAqIFhNTCB0cmVlIGhlYWRlci4gIFRoaXMgYXBwZWFycyBhdCB0aGUgZnJvbnQgb2YgYW4gWE1MIHRyZWUsCisgKiBkZXNjcmliaW5nIGl0cyBjb250ZW50LiAgSXQgaXMgZm9sbG93ZWQgYnkgYSBmbGF0IGFycmF5IG9mCisgKiBSZXNYTUxUcmVlX25vZGUgc3RydWN0dXJlczsgdGhlIGhpZXJhcmNoeSBvZiB0aGUgWE1MIGRvY3VtZW50CisgKiBpcyBkZXNjcmliZWQgYnkgdGhlIG9jY3VycmFuY2Ugb2YgUkVTX1hNTF9TVEFSVF9FTEVNRU5UX1RZUEUKKyAqIGFuZCBjb3JyZXNwb25kaW5nIFJFU19YTUxfRU5EX0VMRU1FTlRfVFlQRSBub2RlcyBpbiB0aGUgYXJyYXkuCisgKi8KK3N0cnVjdCBSZXNYTUxUcmVlX2hlYWRlcgoreworICAgIHN0cnVjdCBSZXNDaHVua19oZWFkZXIgaGVhZGVyOworfTsKKworLyoqCisgKiBCYXNpYyBYTUwgdHJlZSBub2RlLiAgQSBzaW5nbGUgaXRlbSBpbiB0aGUgWE1MIGRvY3VtZW50LiAgRXh0ZW5kZWQgaW5mbworICogYWJvdXQgdGhlIG5vZGUgY2FuIGJlIGZvdW5kIGFmdGVyIGhlYWRlci5oZWFkZXJTaXplLgorICovCitzdHJ1Y3QgUmVzWE1MVHJlZV9ub2RlCit7CisgICAgc3RydWN0IFJlc0NodW5rX2hlYWRlciBoZWFkZXI7CisKKyAgICAvLyBMaW5lIG51bWJlciBpbiBvcmlnaW5hbCBzb3VyY2UgZmlsZSBhdCB3aGljaCB0aGlzIGVsZW1lbnQgYXBwZWFyZWQuCisgICAgdWludDMyX3QgbGluZU51bWJlcjsKKworICAgIC8vIE9wdGlvbmFsIFhNTCBjb21tZW50IHRoYXQgd2FzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQ7IC0xIGlmIG5vbmUuCisgICAgc3RydWN0IFJlc1N0cmluZ1Bvb2xfcmVmIGNvbW1lbnQ7Cit9OworCisvKioKKyAqIEV4dGVuZGVkIFhNTCB0cmVlIG5vZGUgZm9yIENEQVRBIHRhZ3MgLS0gaW5jbHVkZXMgdGhlIENEQVRBIHN0cmluZy4KKyAqIEFwcGVhcnMgaGVhZGVyLmhlYWRlclNpemUgYnl0ZXMgYWZ0ZXIgYSBSZXNYTUxUcmVlX25vZGUuCisgKi8KK3N0cnVjdCBSZXNYTUxUcmVlX2NkYXRhRXh0Cit7CisgICAgLy8gVGhlIHJhdyBDREFUQSBjaGFyYWN0ZXIgZGF0YS4KKyAgICBzdHJ1Y3QgUmVzU3RyaW5nUG9vbF9yZWYgZGF0YTsKKyAgICAKKyAgICAvLyBUaGUgdHlwZWQgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhIGlmIHRoaXMgaXMgYSBDREFUQSBub2RlLgorICAgIHN0cnVjdCBSZXNfdmFsdWUgdHlwZWREYXRhOworfTsKKworLyoqCisgKiBFeHRlbmRlZCBYTUwgdHJlZSBub2RlIGZvciBuYW1lc3BhY2Ugc3RhcnQvZW5kIG5vZGVzLgorICogQXBwZWFycyBoZWFkZXIuaGVhZGVyU2l6ZSBieXRlcyBhZnRlciBhIFJlc1hNTFRyZWVfbm9kZS4KKyAqLworc3RydWN0IFJlc1hNTFRyZWVfbmFtZXNwYWNlRXh0Cit7CisgICAgLy8gVGhlIHByZWZpeCBvZiB0aGUgbmFtZXNwYWNlLgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiBwcmVmaXg7CisgICAgCisgICAgLy8gVGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlLgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiB1cmk7Cit9OworCisvKioKKyAqIEV4dGVuZGVkIFhNTCB0cmVlIG5vZGUgZm9yIGVsZW1lbnQgc3RhcnQvZW5kIG5vZGVzLgorICogQXBwZWFycyBoZWFkZXIuaGVhZGVyU2l6ZSBieXRlcyBhZnRlciBhIFJlc1hNTFRyZWVfbm9kZS4KKyAqLworc3RydWN0IFJlc1hNTFRyZWVfZW5kRWxlbWVudEV4dAoreworICAgIC8vIFN0cmluZyBvZiB0aGUgZnVsbCBuYW1lc3BhY2Ugb2YgdGhpcyBlbGVtZW50LgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiBuczsKKyAgICAKKyAgICAvLyBTdHJpbmcgbmFtZSBvZiB0aGlzIG5vZGUgaWYgaXQgaXMgYW4gRUxFTUVOVDsgdGhlIHJhdworICAgIC8vIGNoYXJhY3RlciBkYXRhIGlmIHRoaXMgaXMgYSBDREFUQSBub2RlLgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiBuYW1lOworfTsKKworLyoqCisgKiBFeHRlbmRlZCBYTUwgdHJlZSBub2RlIGZvciBzdGFydCB0YWdzIC0tIGluY2x1ZGVzIGF0dHJpYnV0ZQorICogaW5mb3JtYXRpb24uCisgKiBBcHBlYXJzIGhlYWRlci5oZWFkZXJTaXplIGJ5dGVzIGFmdGVyIGEgUmVzWE1MVHJlZV9ub2RlLgorICovCitzdHJ1Y3QgUmVzWE1MVHJlZV9hdHRyRXh0Cit7CisgICAgLy8gU3RyaW5nIG9mIHRoZSBmdWxsIG5hbWVzcGFjZSBvZiB0aGlzIGVsZW1lbnQuCisgICAgc3RydWN0IFJlc1N0cmluZ1Bvb2xfcmVmIG5zOworICAgIAorICAgIC8vIFN0cmluZyBuYW1lIG9mIHRoaXMgbm9kZSBpZiBpdCBpcyBhbiBFTEVNRU5UOyB0aGUgcmF3CisgICAgLy8gY2hhcmFjdGVyIGRhdGEgaWYgdGhpcyBpcyBhIENEQVRBIG5vZGUuCisgICAgc3RydWN0IFJlc1N0cmluZ1Bvb2xfcmVmIG5hbWU7CisgICAgCisgICAgLy8gQnl0ZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhpcyBzdHJ1Y3R1cmUgd2hlcmUgdGhlIGF0dHJpYnV0ZXMgc3RhcnQuCisgICAgdWludDE2X3QgYXR0cmlidXRlU3RhcnQ7CisgICAgCisgICAgLy8gU2l6ZSBvZiB0aGUgUmVzWE1MVHJlZV9hdHRyaWJ1dGUgc3RydWN0dXJlcyB0aGF0IGZvbGxvdy4KKyAgICB1aW50MTZfdCBhdHRyaWJ1dGVTaXplOworICAgIAorICAgIC8vIE51bWJlciBvZiBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCBhbiBFTEVNRU5ULiAgVGhlc2UgYXJlCisgICAgLy8gYXZhaWxhYmxlIGFzIGFuIGFycmF5IG9mIFJlc1hNTFRyZWVfYXR0cmlidXRlIHN0cnVjdHVyZXMKKyAgICAvLyBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhpcyBub2RlLgorICAgIHVpbnQxNl90IGF0dHJpYnV0ZUNvdW50OworICAgIAorICAgIC8vIEluZGV4ICgxLWJhc2VkKSBvZiB0aGUgImlkIiBhdHRyaWJ1dGUuIDAgaWYgbm9uZS4KKyAgICB1aW50MTZfdCBpZEluZGV4OworICAgIAorICAgIC8vIEluZGV4ICgxLWJhc2VkKSBvZiB0aGUgImNsYXNzIiBhdHRyaWJ1dGUuIDAgaWYgbm9uZS4KKyAgICB1aW50MTZfdCBjbGFzc0luZGV4OworICAgIAorICAgIC8vIEluZGV4ICgxLWJhc2VkKSBvZiB0aGUgInN0eWxlIiBhdHRyaWJ1dGUuIDAgaWYgbm9uZS4KKyAgICB1aW50MTZfdCBzdHlsZUluZGV4OworfTsKKworc3RydWN0IFJlc1hNTFRyZWVfYXR0cmlidXRlCit7CisgICAgLy8gTmFtZXNwYWNlIG9mIHRoaXMgYXR0cmlidXRlLgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiBuczsKKyAgICAKKyAgICAvLyBOYW1lIG9mIHRoaXMgYXR0cmlidXRlLgorICAgIHN0cnVjdCBSZXNTdHJpbmdQb29sX3JlZiBuYW1lOworCisgICAgLy8gVGhlIG9yaWdpbmFsIHJhdyBzdHJpbmcgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUuCisgICAgc3RydWN0IFJlc1N0cmluZ1Bvb2xfcmVmIHJhd1ZhbHVlOworICAgIAorICAgIC8vIFByb2Nlc3Nlc2QgdHlwZWQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUuCisgICAgc3RydWN0IFJlc192YWx1ZSB0eXBlZFZhbHVlOworfTsKKworY2xhc3MgUmVzWE1MVHJlZTsKKworY2xhc3MgUmVzWE1MUGFyc2VyCit7CitwdWJsaWM6CisgICAgUmVzWE1MUGFyc2VyKGNvbnN0IFJlc1hNTFRyZWUmIHRyZWUpOworCisgICAgZW51bSBldmVudF9jb2RlX3QgeworICAgICAgICBCQURfRE9DVU1FTlQgPSAtMSwKKyAgICAgICAgU1RBUlRfRE9DVU1FTlQgPSAwLAorICAgICAgICBFTkRfRE9DVU1FTlQgPSAxLAorICAgICAgICAKKyAgICAgICAgRklSU1RfQ0hVTktfQ09ERSA9IFJFU19YTUxfRklSU1RfQ0hVTktfVFlQRSwgCisgICAgICAgIAorICAgICAgICBTVEFSVF9OQU1FU1BBQ0UgPSBSRVNfWE1MX1NUQVJUX05BTUVTUEFDRV9UWVBFLAorICAgICAgICBFTkRfTkFNRVNQQUNFID0gUkVTX1hNTF9FTkRfTkFNRVNQQUNFX1RZUEUsCisgICAgICAgIFNUQVJUX1RBRyA9IFJFU19YTUxfU1RBUlRfRUxFTUVOVF9UWVBFLAorICAgICAgICBFTkRfVEFHID0gUkVTX1hNTF9FTkRfRUxFTUVOVF9UWVBFLAorICAgICAgICBURVhUID0gUkVTX1hNTF9DREFUQV9UWVBFCisgICAgfTsKKworICAgIHN0cnVjdCBSZXNYTUxQb3NpdGlvbgorICAgIHsKKyAgICAgICAgZXZlbnRfY29kZV90ICAgICAgICAgICAgICAgIGV2ZW50Q29kZTsKKyAgICAgICAgY29uc3QgUmVzWE1MVHJlZV9ub2RlKiAgICAgIGN1ck5vZGU7CisgICAgICAgIGNvbnN0IHZvaWQqICAgICAgICAgICAgICAgICBjdXJFeHQ7CisgICAgfTsKKworICAgIHZvaWQgcmVzdGFydCgpOworCisgICAgZXZlbnRfY29kZV90IGdldEV2ZW50VHlwZSgpIGNvbnN0OworICAgIC8vIE5vdGUsIHVubGlrZSBYbWxQdWxsUGFyc2VyLCB0aGUgZmlyc3QgY2FsbCB0byBuZXh0KCkgd2lsbCByZXR1cm4KKyAgICAvLyBTVEFSVF9UQUcgb2YgdGhlIGZpcnN0IGVsZW1lbnQuCisgICAgZXZlbnRfY29kZV90IG5leHQoKTsKKworICAgIC8vIFRoZXNlIGFyZSBhdmFpbGFibGUgZm9yIGFsbCBub2RlczoKKyAgICBjb25zdCBpbnQzMl90IGdldENvbW1lbnRJRCgpIGNvbnN0OworICAgIGNvbnN0IHVpbnQxNl90KiBnZXRDb21tZW50KHNpemVfdCogb3V0TGVuKSBjb25zdDsKKyAgICBjb25zdCB1aW50MzJfdCBnZXRMaW5lTnVtYmVyKCkgY29uc3Q7CisgICAgCisgICAgLy8gVGhpcyBpcyBhdmFpbGFibGUgZm9yIFRFWFQ6CisgICAgY29uc3QgaW50MzJfdCBnZXRUZXh0SUQoKSBjb25zdDsKKyAgICBjb25zdCB1aW50MTZfdCogZ2V0VGV4dChzaXplX3QqIG91dExlbikgY29uc3Q7CisgICAgc3NpemVfdCBnZXRUZXh0VmFsdWUoUmVzX3ZhbHVlKiBvdXRWYWx1ZSkgY29uc3Q7CisgICAgCisgICAgLy8gVGhlc2UgYXJlIGF2YWlsYWJsZSBmb3IgU1RBUlRfTkFNRVNQQUNFIGFuZCBFTkRfTkFNRVNQQUNFOgorICAgIGNvbnN0IGludDMyX3QgZ2V0TmFtZXNwYWNlUHJlZml4SUQoKSBjb25zdDsKKyAgICBjb25zdCB1aW50MTZfdCogZ2V0TmFtZXNwYWNlUHJlZml4KHNpemVfdCogb3V0TGVuKSBjb25zdDsKKyAgICBjb25zdCBpbnQzMl90IGdldE5hbWVzcGFjZVVyaUlEKCkgY29uc3Q7CisgICAgY29uc3QgdWludDE2X3QqIGdldE5hbWVzcGFjZVVyaShzaXplX3QqIG91dExlbikgY29uc3Q7CisgICAgCisgICAgLy8gVGhlc2UgYXJlIGF2YWlsYWJsZSBmb3IgU1RBUlRfVEFHIGFuZCBFTkRfVEFHOgorICAgIGNvbnN0IGludDMyX3QgZ2V0RWxlbWVudE5hbWVzcGFjZUlEKCkgY29uc3Q7CisgICAgY29uc3QgdWludDE2X3QqIGdldEVsZW1lbnROYW1lc3BhY2Uoc2l6ZV90KiBvdXRMZW4pIGNvbnN0OworICAgIGNvbnN0IGludDMyX3QgZ2V0RWxlbWVudE5hbWVJRCgpIGNvbnN0OworICAgIGNvbnN0IHVpbnQxNl90KiBnZXRFbGVtZW50TmFtZShzaXplX3QqIG91dExlbikgY29uc3Q7CisgICAgCisgICAgLy8gUmVtYWluaW5nIG1ldGhvZHMgYXJlIGZvciByZXRyaWV2aW5nIGluZm9ybWF0aW9uIGFib3V0IGF0dHJpYnV0ZXMKKyAgICAvLyBhc3NvY2lhdGVkIHdpdGggYSBTVEFSVF9UQUc6CisgICAgCisgICAgc2l6ZV90IGdldEF0dHJpYnV0ZUNvdW50KCkgY29uc3Q7CisgICAgCisgICAgLy8gUmV0dXJucyAtMSBpZiBubyBuYW1lc3BhY2UsIC0yIGlmIGlkeCBvdXQgb2YgcmFuZ2UuCisgICAgY29uc3QgaW50MzJfdCBnZXRBdHRyaWJ1dGVOYW1lc3BhY2VJRChzaXplX3QgaWR4KSBjb25zdDsKKyAgICBjb25zdCB1aW50MTZfdCogZ2V0QXR0cmlidXRlTmFtZXNwYWNlKHNpemVfdCBpZHgsIHNpemVfdCogb3V0TGVuKSBjb25zdDsKKyAgICAKKyAgICBjb25zdCBpbnQzMl90IGdldEF0dHJpYnV0ZU5hbWVJRChzaXplX3QgaWR4KSBjb25zdDsKKyAgICBjb25zdCB1aW50MTZfdCogZ2V0QXR0cmlidXRlTmFtZShzaXplX3QgaWR4LCBzaXplX3QqIG91dExlbikgY29uc3Q7CisgICAgY29uc3QgdWludDMyX3QgZ2V0QXR0cmlidXRlTmFtZVJlc0lEKHNpemVfdCBpZHgpIGNvbnN0OworICAgIAorICAgIGNvbnN0IGludDMyX3QgZ2V0QXR0cmlidXRlVmFsdWVTdHJpbmdJRChzaXplX3QgaWR4KSBjb25zdDsKKyAgICBjb25zdCB1aW50MTZfdCogZ2V0QXR0cmlidXRlU3RyaW5nVmFsdWUoc2l6ZV90IGlkeCwgc2l6ZV90KiBvdXRMZW4pIGNvbnN0OworICAgIAorICAgIGludDMyX3QgZ2V0QXR0cmlidXRlRGF0YVR5cGUoc2l6ZV90IGlkeCkgY29uc3Q7CisgICAgaW50MzJfdCBnZXRBdHRyaWJ1dGVEYXRhKHNpemVfdCBpZHgpIGNvbnN0OworICAgIHNzaXplX3QgZ2V0QXR0cmlidXRlVmFsdWUoc2l6ZV90IGlkeCwgUmVzX3ZhbHVlKiBvdXRWYWx1ZSkgY29uc3Q7CisKKyAgICBzc2l6ZV90IGluZGV4T2ZBdHRyaWJ1dGUoY29uc3QgY2hhciogbnMsIGNvbnN0IGNoYXIqIGF0dHIpIGNvbnN0OworICAgIHNzaXplX3QgaW5kZXhPZkF0dHJpYnV0ZShjb25zdCBjaGFyMTZfdCogbnMsIHNpemVfdCBuc0xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIGF0dHIsIHNpemVfdCBhdHRyTGVuKSBjb25zdDsKKworICAgIHNzaXplX3QgaW5kZXhPZklEKCkgY29uc3Q7CisgICAgc3NpemVfdCBpbmRleE9mQ2xhc3MoKSBjb25zdDsKKyAgICBzc2l6ZV90IGluZGV4T2ZTdHlsZSgpIGNvbnN0OworCisgICAgdm9pZCBnZXRQb3NpdGlvbihSZXNYTUxQb3NpdGlvbiogcG9zKSBjb25zdDsKKyAgICB2b2lkIHNldFBvc2l0aW9uKGNvbnN0IFJlc1hNTFBvc2l0aW9uJiBwb3MpOworCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBSZXNYTUxUcmVlOworICAgIAorICAgIGV2ZW50X2NvZGVfdCBuZXh0Tm9kZSgpOworCisgICAgY29uc3QgUmVzWE1MVHJlZSYgICAgICAgICAgIG1UcmVlOworICAgIGV2ZW50X2NvZGVfdCAgICAgICAgICAgICAgICBtRXZlbnRDb2RlOworICAgIGNvbnN0IFJlc1hNTFRyZWVfbm9kZSogICAgICBtQ3VyTm9kZTsKKyAgICBjb25zdCB2b2lkKiAgICAgICAgICAgICAgICAgbUN1ckV4dDsKK307CisKKy8qKgorICogQ29udmVuaWVuY2UgY2xhc3MgZm9yIGFjY2Vzc2luZyBkYXRhIGluIGEgUmVzWE1MVHJlZSByZXNvdXJjZS4KKyAqLworY2xhc3MgUmVzWE1MVHJlZSA6IHB1YmxpYyBSZXNYTUxQYXJzZXIKK3sKK3B1YmxpYzoKKyAgICBSZXNYTUxUcmVlKCk7CisgICAgUmVzWE1MVHJlZShjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgYm9vbCBjb3B5RGF0YT1mYWxzZSk7CisgICAgflJlc1hNTFRyZWUoKTsKKworICAgIHN0YXR1c190IHNldFRvKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCBib29sIGNvcHlEYXRhPWZhbHNlKTsKKworICAgIHN0YXR1c190IGdldEVycm9yKCkgY29uc3Q7CisKKyAgICB2b2lkIHVuaW5pdCgpOworCisgICAgY29uc3QgUmVzU3RyaW5nUG9vbCYgZ2V0U3RyaW5ncygpIGNvbnN0OworCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBSZXNYTUxQYXJzZXI7CisKKyAgICBzdGF0dXNfdCB2YWxpZGF0ZU5vZGUoY29uc3QgUmVzWE1MVHJlZV9ub2RlKiBub2RlKSBjb25zdDsKKworICAgIHN0YXR1c190ICAgICAgICAgICAgICAgICAgICBtRXJyb3I7CisgICAgdm9pZCogICAgICAgICAgICAgICAgICAgICAgIG1Pd25lZERhdGE7CisgICAgY29uc3QgUmVzWE1MVHJlZV9oZWFkZXIqICAgIG1IZWFkZXI7CisgICAgc2l6ZV90ICAgICAgICAgICAgICAgICAgICAgIG1TaXplOworICAgIGNvbnN0IHVpbnQ4X3QqICAgICAgICAgICAgICBtRGF0YUVuZDsKKyAgICBSZXNTdHJpbmdQb29sICAgICAgICAgICAgICAgbVN0cmluZ3M7CisgICAgY29uc3QgdWludDMyX3QqICAgICAgICAgICAgIG1SZXNJZHM7CisgICAgc2l6ZV90ICAgICAgICAgICAgICAgICAgICAgIG1OdW1SZXNJZHM7CisgICAgY29uc3QgUmVzWE1MVHJlZV9ub2RlKiAgICAgIG1Sb290Tm9kZTsKKyAgICBjb25zdCB2b2lkKiAgICAgICAgICAgICAgICAgbVJvb3RFeHQ7CisgICAgZXZlbnRfY29kZV90ICAgICAgICAgICAgICAgIG1Sb290Q29kZTsKK307CisKKy8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogIFJFU09VUkNFIFRBQkxFCisgKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCisKKy8qKgorICogSGVhZGVyIGZvciBhIHJlc291cmNlIHRhYmxlLiAgSXRzIGRhdGEgY29udGFpbnMgYSBzZXJpZXMgb2YKKyAqIGFkZGl0aW9uYWwgY2h1bmtzOgorICogICAqIEEgUmVzU3RyaW5nUG9vbF9oZWFkZXIgY29udGFpbmluZyBhbGwgdGFibGUgdmFsdWVzLgorICogICAqIE9uZSBvciBtb3JlIFJlc1RhYmxlX3BhY2thZ2UgY2h1bmtzLgorICoKKyAqIFNwZWNpZmljIGVudHJpZXMgd2l0aGluIGEgcmVzb3VyY2UgdGFibGUgY2FuIGJlIHVuaXF1ZWx5IGlkZW50aWZpZWQKKyAqIHdpdGggYSBzaW5nbGUgaW50ZWdlciBhcyBkZWZpbmVkIGJ5IHRoZSBSZXNUYWJsZV9yZWYgc3RydWN0dXJlLgorICovCitzdHJ1Y3QgUmVzVGFibGVfaGVhZGVyCit7CisgICAgc3RydWN0IFJlc0NodW5rX2hlYWRlciBoZWFkZXI7CisKKyAgICAvLyBUaGUgbnVtYmVyIG9mIFJlc1RhYmxlX3BhY2thZ2Ugc3RydWN0dXJlcy4KKyAgICB1aW50MzJfdCBwYWNrYWdlQ291bnQ7Cit9OworCisvKioKKyAqIEEgY29sbGVjdGlvbiBvZiByZXNvdXJjZSBkYXRhIHR5cGVzIHdpdGhpbiBhIHBhY2thZ2UuICBGb2xsb3dlZCBieQorICogb25lIG9yIG1vcmUgUmVzVGFibGVfdHlwZSBhbmQgUmVzVGFibGVfdHlwZVNwZWMgc3RydWN0dXJlcyBjb250YWluaW5nIHRoZQorICogZW50cnkgdmFsdWVzIGZvciBlYWNoIHJlc291cmNlIHR5cGUuCisgKi8KK3N0cnVjdCBSZXNUYWJsZV9wYWNrYWdlCit7CisgICAgc3RydWN0IFJlc0NodW5rX2hlYWRlciBoZWFkZXI7CisKKyAgICAvLyBJZiB0aGlzIGlzIGEgYmFzZSBwYWNrYWdlLCBpdHMgSUQuICBQYWNrYWdlIElEcyBzdGFydAorICAgIC8vIGF0IDEgKGNvcnJlc3BvbmRpbmcgdG8gdGhlIHZhbHVlIG9mIHRoZSBwYWNrYWdlIGJpdHMgaW4gYQorICAgIC8vIHJlc291cmNlIGlkZW50aWZpZXIpLiAgMCBtZWFucyB0aGlzIGlzIG5vdCBhIGJhc2UgcGFja2FnZS4KKyAgICB1aW50MzJfdCBpZDsKKworICAgIC8vIEFjdHVhbCBuYW1lIG9mIHRoaXMgcGFja2FnZSwgXDAtdGVybWluYXRlZC4KKyAgICBjaGFyMTZfdCBuYW1lWzEyOF07CisKKyAgICAvLyBPZmZzZXQgdG8gYSBSZXNTdHJpbmdQb29sX2hlYWRlciBkZWZpbmluZyB0aGUgcmVzb3VyY2UKKyAgICAvLyB0eXBlIHN5bWJvbCB0YWJsZS4gIElmIHplcm8sIHRoaXMgcGFja2FnZSBpcyBpbmhlcml0aW5nIGZyb20KKyAgICAvLyBhbm90aGVyIGJhc2UgcGFja2FnZSAob3ZlcnJpZGluZyBzcGVjaWZpYyB2YWx1ZXMgaW4gaXQpLgorICAgIHVpbnQzMl90IHR5cGVTdHJpbmdzOworCisgICAgLy8gTGFzdCBpbmRleCBpbnRvIHR5cGVTdHJpbmdzIHRoYXQgaXMgZm9yIHB1YmxpYyB1c2UgYnkgb3RoZXJzLgorICAgIHVpbnQzMl90IGxhc3RQdWJsaWNUeXBlOworCisgICAgLy8gT2Zmc2V0IHRvIGEgUmVzU3RyaW5nUG9vbF9oZWFkZXIgZGVmaW5pbmcgdGhlIHJlc291cmNlCisgICAgLy8ga2V5IHN5bWJvbCB0YWJsZS4gIElmIHplcm8sIHRoaXMgcGFja2FnZSBpcyBpbmhlcml0aW5nIGZyb20KKyAgICAvLyBhbm90aGVyIGJhc2UgcGFja2FnZSAob3ZlcnJpZGluZyBzcGVjaWZpYyB2YWx1ZXMgaW4gaXQpLgorICAgIHVpbnQzMl90IGtleVN0cmluZ3M7CisKKyAgICAvLyBMYXN0IGluZGV4IGludG8ga2V5U3RyaW5ncyB0aGF0IGlzIGZvciBwdWJsaWMgdXNlIGJ5IG90aGVycy4KKyAgICB1aW50MzJfdCBsYXN0UHVibGljS2V5OworfTsKKworLyoqCisgKiBEZXNjcmliZXMgYSBwYXJ0aWN1bGFyIHJlc291cmNlIGNvbmZpZ3VyYXRpb24uCisgKi8KK3N0cnVjdCBSZXNUYWJsZV9jb25maWcKK3sKKyAgICAvLyBOdW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBzdHJ1Y3R1cmUuCisgICAgdWludDMyX3Qgc2l6ZTsKKyAgICAKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7CisgICAgICAgICAgICAvLyBNb2JpbGUgY291bnRyeSBjb2RlIChmcm9tIFNJTSkuICAwIG1lYW5zICJhbnkiLgorICAgICAgICAgICAgdWludDE2X3QgbWNjOworICAgICAgICAgICAgLy8gTW9iaWxlIG5ldHdvcmsgY29kZSAoZnJvbSBTSU0pLiAgMCBtZWFucyAiYW55Ii4KKyAgICAgICAgICAgIHVpbnQxNl90IG1uYzsKKyAgICAgICAgfTsKKyAgICAgICAgdWludDMyX3QgaW1zaTsKKyAgICB9OworICAgIAorICAgIHVuaW9uIHsKKyAgICAgICAgc3RydWN0IHsKKyAgICAgICAgICAgIC8vIFwwXDAgbWVhbnMgImFueSIuICBPdGhlcndpc2UsIGVuLCBmciwgZXRjLgorICAgICAgICAgICAgY2hhciBsYW5ndWFnZVsyXTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gXDBcMCBtZWFucyAiYW55Ii4gIE90aGVyd2lzZSwgVVMsIENBLCBldGMuCisgICAgICAgICAgICBjaGFyIGNvdW50cnlbMl07CisgICAgICAgIH07CisgICAgICAgIHVpbnQzMl90IGxvY2FsZTsKKyAgICB9OworICAgIAorICAgIGVudW0geworICAgICAgICBPUklFTlRBVElPTl9BTlkgID0gMHgwMDAwLAorICAgICAgICBPUklFTlRBVElPTl9QT1JUID0gMHgwMDAxLAorICAgICAgICBPUklFTlRBVElPTl9MQU5EID0gMHgwMDAyLAorICAgICAgICBPUklFTlRBVElPTl9TUVVBUkUgPSAweDAwMDIsCisgICAgfTsKKyAgICAKKyAgICBlbnVtIHsKKyAgICAgICAgVE9VQ0hTQ1JFRU5fQU5ZICA9IDB4MDAwMCwKKyAgICAgICAgVE9VQ0hTQ1JFRU5fTk9UT1VDSCAgPSAweDAwMDEsCisgICAgICAgIFRPVUNIU0NSRUVOX1NUWUxVUyAgPSAweDAwMDIsCisgICAgICAgIFRPVUNIU0NSRUVOX0ZJTkdFUiAgPSAweDAwMDMsCisgICAgfTsKKyAgICAKKyAgICBlbnVtIHsKKyAgICAgICAgREVOU0lUWV9BTlkgPSAwCisgICAgfTsKKyAgICAKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7CisgICAgICAgICAgICB1aW50OF90IG9yaWVudGF0aW9uOworICAgICAgICAgICAgdWludDhfdCB0b3VjaHNjcmVlbjsKKyAgICAgICAgICAgIHVpbnQxNl90IGRlbnNpdHk7CisgICAgICAgIH07CisgICAgICAgIHVpbnQzMl90IHNjcmVlblR5cGU7CisgICAgfTsKKyAgICAKKyAgICBlbnVtIHsKKyAgICAgICAgS0VZQk9BUkRfQU5ZICA9IDB4MDAwMCwKKyAgICAgICAgS0VZQk9BUkRfTk9LRVlTICA9IDB4MDAwMSwKKyAgICAgICAgS0VZQk9BUkRfUVdFUlRZICA9IDB4MDAwMiwKKyAgICAgICAgS0VZQk9BUkRfMTJLRVkgID0gMHgwMDAzLAorICAgIH07CisgICAgCisgICAgZW51bSB7CisgICAgICAgIE5BVklHQVRJT05fQU5ZICA9IDB4MDAwMCwKKyAgICAgICAgTkFWSUdBVElPTl9OT05BViAgPSAweDAwMDEsCisgICAgICAgIE5BVklHQVRJT05fRFBBRCAgPSAweDAwMDIsCisgICAgICAgIE5BVklHQVRJT05fVFJBQ0tCQUxMICA9IDB4MDAwMywKKyAgICAgICAgTkFWSUdBVElPTl9XSEVFTCAgPSAweDAwMDQsCisgICAgfTsKKyAgICAKKyAgICBlbnVtIHsKKyAgICAgICAgTUFTS19LRVlTSElEREVOID0gMHgwMDAzLAorICAgICAgICBTSElGVF9LRVlTSElEREVOID0gMCwKKyAgICAgICAgS0VZU0hJRERFTl9BTlkgPSAweDAwMDAsCisgICAgICAgIEtFWVNISURERU5fTk8gPSAweDAwMDEsCisgICAgICAgIEtFWVNISURERU5fWUVTID0gMHgwMDAyLAorICAgICAgICBLRVlTSElEREVOX1NPRlQgPSAweDAwMDMsCisgICAgfTsKKyAgICAKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7CisgICAgICAgICAgICB1aW50OF90IGtleWJvYXJkOworICAgICAgICAgICAgdWludDhfdCBuYXZpZ2F0aW9uOworICAgICAgICAgICAgdWludDhfdCBpbnB1dEZsYWdzOworICAgICAgICAgICAgdWludDhfdCBwYWQwOworICAgICAgICB9OworICAgICAgICB1aW50MzJfdCBpbnB1dDsKKyAgICB9OworICAgIAorICAgIGVudW0geworICAgICAgICBTQ1JFRU5XSURUSF9BTlkgPSAwCisgICAgfTsKKyAgICAKKyAgICBlbnVtIHsKKyAgICAgICAgU0NSRUVOSEVJR0hUX0FOWSA9IDAKKyAgICB9OworICAgIAorICAgIHVuaW9uIHsKKyAgICAgICAgc3RydWN0IHsKKyAgICAgICAgICAgIHVpbnQxNl90IHNjcmVlbldpZHRoOworICAgICAgICAgICAgdWludDE2X3Qgc2NyZWVuSGVpZ2h0OworICAgICAgICB9OworICAgICAgICB1aW50MzJfdCBzY3JlZW5TaXplOworICAgIH07CisgICAgCisgICAgZW51bSB7CisgICAgICAgIFNES1ZFUlNJT05fQU5ZID0gMAorICAgIH07CisgICAgCisgICAgZW51bSB7CisgICAgICAgIE1JTk9SVkVSU0lPTl9BTlkgPSAwCisgICAgfTsKKyAgICAKKyAgICB1bmlvbiB7CisgICAgICAgIHN0cnVjdCB7CisgICAgICAgICAgICB1aW50MTZfdCBzZGtWZXJzaW9uOworICAgICAgICAgICAgLy8gRm9yIG5vdyBtaW5vclZlcnNpb24gbXVzdCBhbHdheXMgYmUgMCEhISAgSXRzIG1lYW5pbmcKKyAgICAgICAgICAgIC8vIGlzIGN1cnJlbnRseSB1bmRlZmluZWQuCisgICAgICAgICAgICB1aW50MTZfdCBtaW5vclZlcnNpb247CisgICAgICAgIH07CisgICAgICAgIHVpbnQzMl90IHZlcnNpb247CisgICAgfTsKKyAgICAKKyAgICBpbmxpbmUgdm9pZCBjb3B5RnJvbURldmljZU5vU3dhcChjb25zdCBSZXNUYWJsZV9jb25maWcmIG8pIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IHNpemUgPSBkdG9obChvLnNpemUpOworICAgICAgICBpZiAoc2l6ZSA+PSBzaXplb2YoUmVzVGFibGVfY29uZmlnKSkgeworICAgICAgICAgICAgKnRoaXMgPSBvOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbWVtY3B5KHRoaXMsICZvLCBzaXplKTsKKyAgICAgICAgICAgIG1lbXNldCgoKHVpbnQ4X3QqKXRoaXMpK3NpemUsIDAsIHNpemVvZihSZXNUYWJsZV9jb25maWcpLXNpemUpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIGlubGluZSB2b2lkIGNvcHlGcm9tRHRvSChjb25zdCBSZXNUYWJsZV9jb25maWcmIG8pIHsKKyAgICAgICAgY29weUZyb21EZXZpY2VOb1N3YXAobyk7CisgICAgICAgIHNpemUgPSBzaXplb2YoUmVzVGFibGVfY29uZmlnKTsKKyAgICAgICAgbWNjID0gZHRvaHMobWNjKTsKKyAgICAgICAgbW5jID0gZHRvaHMobW5jKTsKKyAgICAgICAgZGVuc2l0eSA9IGR0b2hzKGRlbnNpdHkpOworICAgICAgICBzY3JlZW5XaWR0aCA9IGR0b2hzKHNjcmVlbldpZHRoKTsKKyAgICAgICAgc2NyZWVuSGVpZ2h0ID0gZHRvaHMoc2NyZWVuSGVpZ2h0KTsKKyAgICAgICAgc2RrVmVyc2lvbiA9IGR0b2hzKHNka1ZlcnNpb24pOworICAgICAgICBtaW5vclZlcnNpb24gPSBkdG9ocyhtaW5vclZlcnNpb24pOworICAgIH0KKyAgICAKKyAgICBpbmxpbmUgdm9pZCBzd2FwSHRvRCgpIHsKKyAgICAgICAgc2l6ZSA9IGh0b2RsKHNpemUpOworICAgICAgICBtY2MgPSBodG9kcyhtY2MpOworICAgICAgICBtbmMgPSBodG9kcyhtbmMpOworICAgICAgICBkZW5zaXR5ID0gaHRvZHMoZGVuc2l0eSk7CisgICAgICAgIHNjcmVlbldpZHRoID0gaHRvZHMoc2NyZWVuV2lkdGgpOworICAgICAgICBzY3JlZW5IZWlnaHQgPSBodG9kcyhzY3JlZW5IZWlnaHQpOworICAgICAgICBzZGtWZXJzaW9uID0gaHRvZHMoc2RrVmVyc2lvbik7CisgICAgICAgIG1pbm9yVmVyc2lvbiA9IGh0b2RzKG1pbm9yVmVyc2lvbik7CisgICAgfQorICAgIAorICAgIGlubGluZSBpbnQgY29tcGFyZShjb25zdCBSZXNUYWJsZV9jb25maWcmIG8pIGNvbnN0IHsKKyAgICAgICAgaW50MzJfdCBkaWZmID0gKGludDMyX3QpKGltc2kgLSBvLmltc2kpOworICAgICAgICBpZiAoZGlmZiAhPSAwKSByZXR1cm4gZGlmZjsKKyAgICAgICAgZGlmZiA9IChpbnQzMl90KShsb2NhbGUgLSBvLmxvY2FsZSk7CisgICAgICAgIGlmIChkaWZmICE9IDApIHJldHVybiBkaWZmOworICAgICAgICBkaWZmID0gKGludDMyX3QpKHNjcmVlblR5cGUgLSBvLnNjcmVlblR5cGUpOworICAgICAgICBpZiAoZGlmZiAhPSAwKSByZXR1cm4gZGlmZjsKKyAgICAgICAgZGlmZiA9IChpbnQzMl90KShpbnB1dCAtIG8uaW5wdXQpOworICAgICAgICBpZiAoZGlmZiAhPSAwKSByZXR1cm4gZGlmZjsKKyAgICAgICAgZGlmZiA9IChpbnQzMl90KShzY3JlZW5TaXplIC0gby5zY3JlZW5TaXplKTsKKyAgICAgICAgaWYgKGRpZmYgIT0gMCkgcmV0dXJuIGRpZmY7CisgICAgICAgIGRpZmYgPSAoaW50MzJfdCkodmVyc2lvbiAtIG8udmVyc2lvbik7CisgICAgICAgIHJldHVybiAoaW50KWRpZmY7CisgICAgfQorICAgIAorICAgIC8vIEZsYWdzIGluZGljYXRpbmcgYSBzZXQgb2YgY29uZmlnIHZhbHVlcy4gIFRoZXNlIGZsYWcgY29uc3RhbnRzIG11c3QKKyAgICAvLyBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBvbmVzIGluIGFuZHJvaWQuY29udGVudC5wbS5BY3Rpdml0eUluZm8gYW5kCisgICAgLy8gYXR0cnNfbWFuaWZlc3QueG1sLgorICAgIGVudW0geworICAgICAgICBDT05GSUdfTUNDID0gMHgwMDAxLAorICAgICAgICBDT05GSUdfTU5DID0gMHgwMDAyLAorICAgICAgICBDT05GSUdfTE9DQUxFID0gMHgwMDA0LAorICAgICAgICBDT05GSUdfVE9VQ0hTQ1JFRU4gPSAweDAwMDgsCisgICAgICAgIENPTkZJR19LRVlCT0FSRCA9IDB4MDAxMCwKKyAgICAgICAgQ09ORklHX0tFWUJPQVJEX0hJRERFTiA9IDB4MDAyMCwKKyAgICAgICAgQ09ORklHX05BVklHQVRJT04gPSAweDAwNDAsCisgICAgICAgIENPTkZJR19PUklFTlRBVElPTiA9IDB4MDA4MCwKKyAgICAgICAgQ09ORklHX0RFTlNJVFkgPSAweDAxMDAsCisgICAgICAgIENPTkZJR19TQ1JFRU5fU0laRSA9IDB4MDIwMCwKKyAgICAgICAgQ09ORklHX1ZFUlNJT04gPSAweDA0MDAKKyAgICB9OworICAgIAorICAgIC8vIENvbXBhcmUgdHdvIGNvbmZpZ3VyYXRpb24sIHJldHVybmluZyBDT05GSUdfKiBmbGFncyBzZXQgZm9yIGVhY2ggdmFsdWUKKyAgICAvLyB0aGF0IGlzIGRpZmZlcmVudC4KKyAgICBpbmxpbmUgaW50IGRpZmYoY29uc3QgUmVzVGFibGVfY29uZmlnJiBvKSBjb25zdCB7CisgICAgICAgIGludCBkaWZmcyA9IDA7CisgICAgICAgIGlmIChtY2MgIT0gby5tY2MpIGRpZmZzIHw9IENPTkZJR19NQ0M7CisgICAgICAgIGlmIChtbmMgIT0gby5tbmMpIGRpZmZzIHw9IENPTkZJR19NTkM7CisgICAgICAgIGlmIChsb2NhbGUgIT0gby5sb2NhbGUpIGRpZmZzIHw9IENPTkZJR19MT0NBTEU7CisgICAgICAgIGlmIChvcmllbnRhdGlvbiAhPSBvLm9yaWVudGF0aW9uKSBkaWZmcyB8PSBDT05GSUdfT1JJRU5UQVRJT047CisgICAgICAgIGlmIChkZW5zaXR5ICE9IG8uZGVuc2l0eSkgZGlmZnMgfD0gQ09ORklHX0RFTlNJVFk7CisgICAgICAgIGlmICh0b3VjaHNjcmVlbiAhPSBvLnRvdWNoc2NyZWVuKSBkaWZmcyB8PSBDT05GSUdfVE9VQ0hTQ1JFRU47CisgICAgICAgIGlmICgoKGlucHV0RmxhZ3Neby5pbnB1dEZsYWdzKSZNQVNLX0tFWVNISURERU4pICE9IDApIGRpZmZzIHw9IENPTkZJR19LRVlCT0FSRF9ISURERU47CisgICAgICAgIGlmIChrZXlib2FyZCAhPSBvLmtleWJvYXJkKSBkaWZmcyB8PSBDT05GSUdfS0VZQk9BUkQ7CisgICAgICAgIGlmIChuYXZpZ2F0aW9uICE9IG8ubmF2aWdhdGlvbikgZGlmZnMgfD0gQ09ORklHX05BVklHQVRJT047CisgICAgICAgIGlmIChzY3JlZW5TaXplICE9IG8uc2NyZWVuU2l6ZSkgZGlmZnMgfD0gQ09ORklHX1NDUkVFTl9TSVpFOworICAgICAgICBpZiAodmVyc2lvbiAhPSBvLnZlcnNpb24pIGRpZmZzIHw9IENPTkZJR19WRVJTSU9OOworICAgICAgICByZXR1cm4gZGlmZnM7CisgICAgfQorICAgIAorICAgIC8vIFJldHVybiB0cnVlIGlmICd0aGlzJyBpcyBtb3JlIHNwZWNpZmljIHRoYW4gJ28nLiAgT3B0aW9uYWxseSwgaWYKKyAgICAvLyAncmVxdWVzdGVkJyBpcyBudWxsLCB0aGVuIHRoZXkgd2lsbCBhbHNvIGJlIGNvbXBhcmVkIGFnYWluc3QgdGhlCisgICAgLy8gcmVxdWVzdGVkIGNvbmZpZ3VyYXRpb24gYW5kIHRydWUgd2lsbCBvbmx5IGJlIHJldHVybmVkIGlmICd0aGlzJworICAgIC8vIGlzIGEgYmV0dGVyIGNhbmRpZGF0ZSB0aGFuICdvJyBmb3IgdGhlIGNvbmZpZ3VyYXRpb24uICBUaGlzIGFzc3VtZXMgdGhhdAorICAgIC8vIG1hdGNoKCkgaGFzIGFscmVhZHkgYmVlbiB1c2VkIHRvIHJlbW92ZSBhbnkgY29uZmlndXJhdGlvbnMgdGhhdCBkb24ndAorICAgIC8vIG1hdGNoIHRoZSByZXF1ZXN0ZWQgY29uZmlndXJhdGlvbiBhdCBhbGw7IGlmIHRoZXkgYXJlIG5vdCBmaXJzdCBmaWx0ZXJlZCwKKyAgICAvLyBub24tbWF0Y2hpbmcgcmVzdWx0cyBjYW4gYmUgY29uc2lkZXJlZCBiZXR0ZXIgdGhhbiBtYXRjaGluZyBvbmVzLgorICAgIGlubGluZSBib29sCisgICAgaXNCZXR0ZXJUaGFuKGNvbnN0IFJlc1RhYmxlX2NvbmZpZyYgbywgY29uc3QgUmVzVGFibGVfY29uZmlnKiByZXF1ZXN0ZWQgPSBOVUxMKSBjb25zdCB7CisgICAgICAgIC8vIFRoZSBvcmRlciBvZiB0aGUgZm9sbG93aW5nIHRlc3RzIGRlZmluZXMgdGhlIGltcG9ydGFuY2Ugb2Ygb25lCisgICAgICAgIC8vIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyIG92ZXIgYW5vdGhlci4gIFRob3NlIHRlc3RzIGZpcnN0IGFyZSBtb3JlCisgICAgICAgIC8vIGltcG9ydGFudCwgdHJ1bXBpbmcgYW55IHZhbHVlcyBpbiB0aG9zZSBmb2xsb3dpbmcgdGhlbS4KKyAgICAgICAgaWYgKGltc2kgIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPmltc2kgIT0gMCkpIHsKKyAgICAgICAgICAgIGlmIChtY2MgIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPm1jYyAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLm1jYyA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtbmMgIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPm1uYyAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLm1uYyA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobG9jYWxlICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5sb2NhbGUgIT0gMCkpIHsKKyAgICAgICAgICAgIGlmIChsYW5ndWFnZVswXSAhPSAwICYmICghcmVxdWVzdGVkIHx8IHJlcXVlc3RlZC0+bGFuZ3VhZ2VbMF0gIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoby5sYW5ndWFnZVswXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjb3VudHJ5WzBdICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5jb3VudHJ5WzBdICE9IDApKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uY291bnRyeVswXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc2NyZWVuVHlwZSAhPSAwICYmICghcmVxdWVzdGVkIHx8IHJlcXVlc3RlZC0+c2NyZWVuVHlwZSAhPSAwKSkgeworICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5vcmllbnRhdGlvbiAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLm9yaWVudGF0aW9uID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGRlbnNpdHkgIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPmRlbnNpdHkgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoby5kZW5zaXR5ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRvdWNoc2NyZWVuICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT50b3VjaHNjcmVlbiAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLnRvdWNoc2NyZWVuID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dCAhPSAwICYmICghcmVxdWVzdGVkIHx8IHJlcXVlc3RlZC0+aW5wdXQgIT0gMCkpIHsKKyAgICAgICAgICAgIGNvbnN0IGludCBrZXlzSGlkZGVuID0gaW5wdXRGbGFncyZNQVNLX0tFWVNISURERU47CisgICAgICAgICAgICBjb25zdCBpbnQgcmVxS2V5c0hpZGRlbiA9IHJlcXVlc3RlZAorICAgICAgICAgICAgICAgICAgICA/IHJlcXVlc3RlZC0+aW5wdXRGbGFncyZNQVNLX0tFWVNISURERU4gOiAwOworICAgICAgICAgICAgaWYgKGtleXNIaWRkZW4gIT0gMCAmJiByZXFLZXlzSGlkZGVuICE9IDApIHsKKyAgICAgICAgICAgICAgICBjb25zdCBpbnQgb0tleXNIaWRkZW4gPSBvLmlucHV0RmxhZ3MmTUFTS19LRVlTSElEREVOOworICAgICAgICAgICAgICAgIC8vTE9HSSgiaXNCZXR0ZXJUaGFuIGtleXNIaWRkZW46IGN1cj0lZCwgZ2l2ZW49JWQsIGNvbmZpZz0lZFxuIiwKKyAgICAgICAgICAgICAgICAvLyAgICAgICAga2V5c0hpZGRlbiwgb0tleXNIaWRkZW4sIHJlcUtleXNIaWRkZW4pOworICAgICAgICAgICAgICAgIGlmIChvS2V5c0hpZGRlbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vTE9HSSgiQmV0dGVyIGJlY2F1c2UgMCEiKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIEZvciBjb21wYXRpYmlsaXR5LCB3ZSBjb3VudCBLRVlTSElEREVOX05PIGFzIGJlaW5nCisgICAgICAgICAgICAgICAgLy8gdGhlIHNhbWUgYXMgS0VZU0hJRERFTl9TT0ZULiAgSGVyZSB3ZSBkaXNhbWJpZ3VhdGUgdGhlc2UKKyAgICAgICAgICAgICAgICAvLyBtYXkgbWFraW5nIGFuIGV4YWN0IG1hdGNoIG1vcmUgc3BlY2lmaWMuCisgICAgICAgICAgICAgICAgaWYgKGtleXNIaWRkZW4gPT0gcmVxS2V5c0hpZGRlbiAmJiBvS2V5c0hpZGRlbiAhPSByZXFLZXlzSGlkZGVuKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gaXMgYW4gZXhhY3QgbWF0Y2gsIGFuZAorICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZ2l2ZW4gb25lIGlzIG5vdCwgc28gdGhlIGN1cnJlbnQgb25lIGlzIGJldHRlci4KKyAgICAgICAgICAgICAgICAgICAgLy9MT0dJKCJCZXR0ZXIgYmVjYXVzZSBvdGhlciBub3Qgc2FtZSEiKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleWJvYXJkICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5rZXlib2FyZCAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLmtleWJvYXJkID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG5hdmlnYXRpb24gIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPm5hdmlnYXRpb24gIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoby5uYXZpZ2F0aW9uID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChzY3JlZW5TaXplICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5zY3JlZW5TaXplICE9IDApKSB7CisgICAgICAgICAgICBpZiAoc2NyZWVuV2lkdGggIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPnNjcmVlbldpZHRoICE9IDApKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uc2NyZWVuV2lkdGggPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2NyZWVuSGVpZ2h0ICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5zY3JlZW5IZWlnaHQgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoby5zY3JlZW5IZWlnaHQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZlcnNpb24gIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPnZlcnNpb24gIT0gMCkpIHsKKyAgICAgICAgICAgIGlmIChzZGtWZXJzaW9uICE9IDAgJiYgKCFyZXF1ZXN0ZWQgfHwgcmVxdWVzdGVkLT5zZGtWZXJzaW9uICE9IDApKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uc2RrVmVyc2lvbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtaW5vclZlcnNpb24gIT0gMCAmJiAoIXJlcXVlc3RlZCB8fCByZXF1ZXN0ZWQtPm1pbm9yVmVyc2lvbiAhPSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChvLm1pbm9yVmVyc2lvbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIAorICAgIC8vIFJldHVybiB0cnVlIGlmICd0aGlzJyBjYW4gYmUgY29uc2lkZXJlZCBhIG1hdGNoIGZvciB0aGUgcGFyYW1ldGVycyBpbiAKKyAgICAvLyAnc2V0dGluZ3MnLgorICAgIC8vIE5vdGUgdGhpcyBpcyBhc3ltZXRyaWMuICBBIGRlZmF1bHQgcGllY2Ugb2YgZGF0YSB3aWxsIG1hdGNoIGV2ZXJ5IHJlcXVlc3QKKyAgICAvLyBidXQgYSByZXF1ZXN0IGZvciB0aGUgZGVmYXVsdCBzaG91bGQgbm90IG1hdGNoIG9kZCBzcGVjaWZpY3MKKyAgICAvLyAoaWUsIHJlcXVlc3Qgd2l0aCBubyBtY2Mgc2hvdWxkIG5vdCBtYXRjaCBhIHBhcnRpY3VsYXIgbWNjJ3MgZGF0YSkKKyAgICAvLyBzZXR0aW5ncyBpcyB0aGUgcmVxdWVzdGVkIHNldHRpbmdzCisgICAgaW5saW5lIGJvb2wgbWF0Y2goY29uc3QgUmVzVGFibGVfY29uZmlnJiBzZXR0aW5ncykgY29uc3QgeworICAgICAgICBpZiAoaW1zaSAhPSAwKSB7CisgICAgICAgICAgICBpZiAoKHNldHRpbmdzLm1jYyAhPSAwICYmIG1jYyAhPSAwCisgICAgICAgICAgICAgICAgICYmIG1jYyAhPSBzZXR0aW5ncy5tY2MpIHx8IAorICAgICAgICAgICAgICAgIChzZXR0aW5ncy5tY2MgPT0gMCAmJiBtY2MgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKHNldHRpbmdzLm1uYyAhPSAwICYmIG1uYyAhPSAwCisgICAgICAgICAgICAgICAgICYmIG1uYyAhPSBzZXR0aW5ncy5tbmMpIHx8CisgICAgICAgICAgICAgICAgKHNldHRpbmdzLm1uYyA9PSAwICYmIG1uYyAhPSAwKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobG9jYWxlICE9IDApIHsKKyAgICAgICAgICAgIGlmIChzZXR0aW5ncy5sYW5ndWFnZVswXSAhPSAwICYmIGxhbmd1YWdlWzBdICE9IDAKKyAgICAgICAgICAgICAgICAmJiAobGFuZ3VhZ2VbMF0gIT0gc2V0dGluZ3MubGFuZ3VhZ2VbMF0KKyAgICAgICAgICAgICAgICAgICAgfHwgbGFuZ3VhZ2VbMV0gIT0gc2V0dGluZ3MubGFuZ3VhZ2VbMV0pKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNldHRpbmdzLmNvdW50cnlbMF0gIT0gMCAmJiBjb3VudHJ5WzBdICE9IDAKKyAgICAgICAgICAgICAgICAmJiAoY291bnRyeVswXSAhPSBzZXR0aW5ncy5jb3VudHJ5WzBdCisgICAgICAgICAgICAgICAgICAgIHx8IGNvdW50cnlbMV0gIT0gc2V0dGluZ3MuY291bnRyeVsxXSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjcmVlblR5cGUgIT0gMCkgeworICAgICAgICAgICAgaWYgKHNldHRpbmdzLm9yaWVudGF0aW9uICE9IDAgJiYgb3JpZW50YXRpb24gIT0gMAorICAgICAgICAgICAgICAgICYmIG9yaWVudGF0aW9uICE9IHNldHRpbmdzLm9yaWVudGF0aW9uKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRGVuc2l0eSBub3QgdGFrZW4gaW50byBhY2NvdW50LCBhbHdheXMgbWF0Y2gsIG5vIG1hdHRlciB3aGF0CisgICAgICAgICAgICAvLyBkZW5zaXR5IGlzIHNwZWNpZmllZCBmb3IgdGhlIHJlc291cmNlCisgICAgICAgICAgICBpZiAoc2V0dGluZ3MudG91Y2hzY3JlZW4gIT0gMCAmJiB0b3VjaHNjcmVlbiAhPSAwCisgICAgICAgICAgICAgICAgJiYgdG91Y2hzY3JlZW4gIT0gc2V0dGluZ3MudG91Y2hzY3JlZW4pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0ICE9IDApIHsKKyAgICAgICAgICAgIGNvbnN0IGludCBrZXlzSGlkZGVuID0gaW5wdXRGbGFncyZNQVNLX0tFWVNISURERU47CisgICAgICAgICAgICBjb25zdCBpbnQgc2V0S2V5c0hpZGRlbiA9IHNldHRpbmdzLmlucHV0RmxhZ3MmTUFTS19LRVlTSElEREVOOworICAgICAgICAgICAgaWYgKHNldEtleXNIaWRkZW4gIT0gMCAmJiBrZXlzSGlkZGVuICE9IDAKKyAgICAgICAgICAgICAgICAmJiBrZXlzSGlkZGVuICE9IHNldEtleXNIaWRkZW4pIHsKKyAgICAgICAgICAgICAgICAvLyBGb3IgY29tcGF0aWJpbGl0eSwgd2UgY291bnQgYSByZXF1ZXN0IGZvciBLRVlTSElEREVOX05PIGFzIGFsc28KKyAgICAgICAgICAgICAgICAvLyBtYXRjaGluZyB0aGUgbW9yZSByZWNlbnQgS0VZU0hJRERFTl9TT0ZULiAgQmFzaWNhbGx5CisgICAgICAgICAgICAgICAgLy8gS0VZU0hJRERFTl9OTyBtZWFucyB0aGVyZSBpcyBzb21lIGtpbmQgb2Yga2V5Ym9hcmQgYXZhaWxhYmxlLgorICAgICAgICAgICAgICAgIC8vTE9HSSgiTWF0Y2hpbmcga2V5c0hpZGRlbjogaGF2ZT0lZCwgY29uZmlnPSVkXG4iLCBrZXlzSGlkZGVuLCBzZXRLZXlzSGlkZGVuKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5c0hpZGRlbiAhPSBLRVlTSElEREVOX05PIHx8IHNldEtleXNIaWRkZW4gIT0gS0VZU0hJRERFTl9TT0ZUKSB7CisgICAgICAgICAgICAgICAgICAgIC8vTE9HSSgiTm8gbWF0Y2ghIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2V0dGluZ3Mua2V5Ym9hcmQgIT0gMCAmJiBrZXlib2FyZCAhPSAwCisgICAgICAgICAgICAgICAgJiYga2V5Ym9hcmQgIT0gc2V0dGluZ3Mua2V5Ym9hcmQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2V0dGluZ3MubmF2aWdhdGlvbiAhPSAwICYmIG5hdmlnYXRpb24gIT0gMAorICAgICAgICAgICAgICAgICYmIG5hdmlnYXRpb24gIT0gc2V0dGluZ3MubmF2aWdhdGlvbikgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc2NyZWVuU2l6ZSAhPSAwKSB7CisgICAgICAgICAgICBpZiAoc2V0dGluZ3Muc2NyZWVuV2lkdGggIT0gMCAmJiBzY3JlZW5XaWR0aCAhPSAwCisgICAgICAgICAgICAgICAgJiYgc2NyZWVuV2lkdGggIT0gc2V0dGluZ3Muc2NyZWVuV2lkdGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2V0dGluZ3Muc2NyZWVuSGVpZ2h0ICE9IDAgJiYgc2NyZWVuSGVpZ2h0ICE9IDAKKyAgICAgICAgICAgICAgICAmJiBzY3JlZW5IZWlnaHQgIT0gc2V0dGluZ3Muc2NyZWVuSGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICh2ZXJzaW9uICE9IDApIHsKKyAgICAgICAgICAgIGlmIChzZXR0aW5ncy5zZGtWZXJzaW9uICE9IDAgJiYgc2RrVmVyc2lvbiAhPSAwCisgICAgICAgICAgICAgICAgJiYgc2RrVmVyc2lvbiAhPSBzZXR0aW5ncy5zZGtWZXJzaW9uKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNldHRpbmdzLm1pbm9yVmVyc2lvbiAhPSAwICYmIG1pbm9yVmVyc2lvbiAhPSAwCisgICAgICAgICAgICAgICAgJiYgbWlub3JWZXJzaW9uICE9IHNldHRpbmdzLm1pbm9yVmVyc2lvbikgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICB2b2lkIGdldExvY2FsZShjaGFyIHN0cls2XSkgY29uc3QgeworICAgICAgICBtZW1zZXQoc3RyLCAwLCA2KTsKKyAgICAgICAgaWYgKGxhbmd1YWdlWzBdKSB7CisgICAgICAgICAgICBzdHJbMF0gPSBsYW5ndWFnZVswXTsKKyAgICAgICAgICAgIHN0clsxXSA9IGxhbmd1YWdlWzFdOworICAgICAgICAgICAgaWYgKGNvdW50cnlbMF0pIHsKKyAgICAgICAgICAgICAgICBzdHJbMl0gPSAnXyc7CisgICAgICAgICAgICAgICAgc3RyWzNdID0gY291bnRyeVswXTsKKyAgICAgICAgICAgICAgICBzdHJbNF0gPSBjb3VudHJ5WzFdOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgU3RyaW5nOCB0b1N0cmluZygpIGNvbnN0IHsKKyAgICAgICAgY2hhciBidWZbMjAwXTsKKyAgICAgICAgc3ByaW50ZihidWYsICJpbXNpPSVkLyVkIGxhbmc9JWMlYyByZWc9JWMlYyBvcmllbnQ9MHglMDJ4IHRvdWNoPTB4JTAyeCBkZW5zPTB4JTAyeCAiCisgICAgICAgICAgICAgICAgImtiZD0weCUwMnggbmF2PTB4JTAyeCBpbnB1dD0weCUwMnggc2NyZWVuVz0weCUwNHggc2NyZWVuSD0weCUwNHggdmVycz0lZC4lZCIsCisgICAgICAgICAgICAgICAgbWNjLCBtbmMsCisgICAgICAgICAgICAgICAgbGFuZ3VhZ2VbMF0gPyBsYW5ndWFnZVswXSA6ICctJywgbGFuZ3VhZ2VbMV0gPyBsYW5ndWFnZVsxXSA6ICctJywKKyAgICAgICAgICAgICAgICBjb3VudHJ5WzBdID8gY291bnRyeVswXSA6ICctJywgY291bnRyeVsxXSA/IGNvdW50cnlbMV0gOiAnLScsCisgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHRvdWNoc2NyZWVuLCBkZW5zaXR5LCBrZXlib2FyZCwgbmF2aWdhdGlvbiwgaW5wdXRGbGFncywKKyAgICAgICAgICAgICAgICBzY3JlZW5XaWR0aCwgc2NyZWVuSGVpZ2h0LCBzZGtWZXJzaW9uLCBtaW5vclZlcnNpb24pOworICAgICAgICByZXR1cm4gU3RyaW5nOChidWYpOworICAgIH0KK307CisKKy8qKgorICogQSBzcGVjaWZpY2F0aW9uIG9mIHRoZSByZXNvdXJjZXMgZGVmaW5lZCBieSBhIHBhcnRpY3VsYXIgdHlwZS4KKyAqCisgKiBUaGVyZSBzaG91bGQgYmUgb25lIG9mIHRoZXNlIGNodW5rcyBmb3IgZWFjaCByZXNvdXJjZSB0eXBlLgorICoKKyAqIFRoaXMgc3RydWN0dXJlIGlzIGZvbGxvd2VkIGJ5IGFuIGFycmF5IG9mIGludGVnZXJzIHByb3ZpZGluZyB0aGUgc2V0IG9mCisgKiBjb25maWd1YXRpb24gY2hhbmdlIGZsYWdzIChSZXNUYWJsZV9jb25maWc6OkNPTkZJR18qKSB0aGF0IGhhdmUgbXVsdGlwbGUKKyAqIHJlc291cmNlcyBmb3IgdGhhdCBjb25maWd1cmF0aW9uLiAgSW4gYWRkaXRpb24sIHRoZSBoaWdoIGJpdCBpcyBzZXQgaWYgdGhhdAorICogcmVzb3VyY2UgaGFzIGJlZW4gbWFkZSBwdWJsaWMuCisgKi8KK3N0cnVjdCBSZXNUYWJsZV90eXBlU3BlYworeworICAgIHN0cnVjdCBSZXNDaHVua19oZWFkZXIgaGVhZGVyOworCisgICAgLy8gVGhlIHR5cGUgaWRlbnRpZmllciB0aGlzIGNodW5rIGlzIGhvbGRpbmcuICBUeXBlIElEcyBzdGFydAorICAgIC8vIGF0IDEgKGNvcnJlc3BvbmRpbmcgdG8gdGhlIHZhbHVlIG9mIHRoZSB0eXBlIGJpdHMgaW4gYQorICAgIC8vIHJlc291cmNlIGlkZW50aWZpZXIpLiAgMCBpcyBpbnZhbGlkLgorICAgIHVpbnQ4X3QgaWQ7CisgICAgCisgICAgLy8gTXVzdCBiZSAwLgorICAgIHVpbnQ4X3QgcmVzMDsKKyAgICAvLyBNdXN0IGJlIDAuCisgICAgdWludDE2X3QgcmVzMTsKKyAgICAKKyAgICAvLyBOdW1iZXIgb2YgdWludDMyX3QgZW50cnkgY29uZmlndXJhdGlvbiBtYXNrcyB0aGF0IGZvbGxvdy4KKyAgICB1aW50MzJfdCBlbnRyeUNvdW50OworCisgICAgZW51bSB7CisgICAgICAgIC8vIEFkZGl0aW9uYWwgZmxhZyBpbmRpY2F0aW5nIGFuIGVudHJ5IGlzIHB1YmxpYy4KKyAgICAgICAgU1BFQ19QVUJMSUMgPSAweDQwMDAwMDAwCisgICAgfTsKK307CisKKy8qKgorICogQSBjb2xsZWN0aW9uIG9mIHJlc291cmNlIGVudHJpZXMgZm9yIGEgcGFydGljdWxhciByZXNvdXJjZSBkYXRhCisgKiB0eXBlLiBGb2xsb3dlZCBieSBhbiBhcnJheSBvZiB1aW50MzJfdCBkZWZpbmluZyB0aGUgcmVzb3VyY2UKKyAqIHZhbHVlcywgY29ycmVzcG9uZGluZyB0byB0aGUgYXJyYXkgb2YgdHlwZSBzdHJpbmdzIGluIHRoZQorICogUmVzVGFibGVfcGFja2FnZTo6dHlwZVN0cmluZ3Mgc3RyaW5nIGJsb2NrLiBFYWNoIG9mIHRoZXNlIGhvbGQgYW4KKyAqIGluZGV4IGZyb20gZW50cmllc1N0YXJ0OyBhIHZhbHVlIG9mIE5PX0VOVFJZIG1lYW5zIHRoYXQgZW50cnkgaXMKKyAqIG5vdCBkZWZpbmVkLgorICoKKyAqIFRoZXJlIG1heSBiZSBtdWx0aXBsZSBvZiB0aGVzZSBjaHVua3MgZm9yIGEgcGFydGljdWxhciByZXNvdXJjZSB0eXBlLAorICogc3VwcGx5IGRpZmZlcmVudCBjb25maWd1cmF0aW9uIHZhcmlhdGlvbnMgZm9yIHRoZSByZXNvdXJjZSB2YWx1ZXMgb2YKKyAqIHRoYXQgdHlwZS4KKyAqCisgKiBJdCB3b3VsZCBiZSBuaWNlIHRvIGhhdmUgYW4gYWRkaXRpb25hbCBvcmRlcmVkIGluZGV4IG9mIGVudHJpZXMsIHNvCisgKiB3ZSBjYW4gZG8gYSBiaW5hcnkgc2VhcmNoIGlmIHRyeWluZyB0byBmaW5kIGEgcmVzb3VyY2UgYnkgc3RyaW5nIG5hbWUuCisgKi8KK3N0cnVjdCBSZXNUYWJsZV90eXBlCit7CisgICAgc3RydWN0IFJlc0NodW5rX2hlYWRlciBoZWFkZXI7CisKKyAgICBlbnVtIHsKKyAgICAgICAgTk9fRU5UUlkgPSAweEZGRkZGRkZGCisgICAgfTsKKyAgICAKKyAgICAvLyBUaGUgdHlwZSBpZGVudGlmaWVyIHRoaXMgY2h1bmsgaXMgaG9sZGluZy4gIFR5cGUgSURzIHN0YXJ0CisgICAgLy8gYXQgMSAoY29ycmVzcG9uZGluZyB0byB0aGUgdmFsdWUgb2YgdGhlIHR5cGUgYml0cyBpbiBhCisgICAgLy8gcmVzb3VyY2UgaWRlbnRpZmllcikuICAwIGlzIGludmFsaWQuCisgICAgdWludDhfdCBpZDsKKyAgICAKKyAgICAvLyBNdXN0IGJlIDAuCisgICAgdWludDhfdCByZXMwOworICAgIC8vIE11c3QgYmUgMC4KKyAgICB1aW50MTZfdCByZXMxOworICAgIAorICAgIC8vIE51bWJlciBvZiB1aW50MzJfdCBlbnRyeSBpbmRpY2VzIHRoYXQgZm9sbG93LgorICAgIHVpbnQzMl90IGVudHJ5Q291bnQ7CisKKyAgICAvLyBPZmZzZXQgZnJvbSBoZWFkZXIgd2hlcmUgUmVzVGFibGVfZW50cnkgZGF0YSBzdGFydHMuCisgICAgdWludDMyX3QgZW50cmllc1N0YXJ0OworICAgIAorICAgIC8vIENvbmZpZ3VyYXRpb24gdGhpcyBjb2xsZWN0aW9uIG9mIGVudHJpZXMgaXMgZGVzaWduZWQgZm9yLgorICAgIFJlc1RhYmxlX2NvbmZpZyBjb25maWc7Cit9OworCisvKioKKyAqIFRoaXMgaXMgdGhlIGJlZ2lubmluZyBvZiBpbmZvcm1hdGlvbiBhYm91dCBhbiBlbnRyeSBpbiB0aGUgcmVzb3VyY2UKKyAqIHRhYmxlLiAgSXQgaG9sZHMgdGhlIHJlZmVyZW5jZSB0byB0aGUgbmFtZSBvZiB0aGlzIGVudHJ5LCBhbmQgaXMKKyAqIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IG9uZSBvZjoKKyAqICAgKiBBIFJlc192YWx1ZSBzdHJ1Y3R1cmVzLCBpZiBGTEFHX0NPTVBMRVggaXMgLW5vdC0gc2V0LgorICogICAqIEFuIGFycmF5IG9mIFJlc1RhYmxlX21hcCBzdHJ1Y3R1cmVzLCBpZiBGTEFHX0NPTVBMRVggaXMgc2V0LgorICogICAgIFRoZXNlIHN1cHBseSBhIHNldCBvZiBuYW1lL3ZhbHVlIG1hcHBpbmdzIG9mIGRhdGEuCisgKi8KK3N0cnVjdCBSZXNUYWJsZV9lbnRyeQoreworICAgIC8vIE51bWJlciBvZiBieXRlcyBpbiB0aGlzIHN0cnVjdHVyZS4KKyAgICB1aW50MTZfdCBzaXplOworCisgICAgZW51bSB7CisgICAgICAgIC8vIElmIHNldCwgdGhpcyBpcyBhIGNvbXBsZXggZW50cnksIGhvbGRpbmcgYSBzZXQgb2YgbmFtZS92YWx1ZQorICAgICAgICAvLyBtYXBwaW5ncy4gIEl0IGlzIGZvbGxvd2VkIGJ5IGFuIGFycmF5IG9mIFJlc1RhYmxlX21hcCBzdHJ1Y3R1cmVzLgorICAgICAgICBGTEFHX0NPTVBMRVggPSAweDAwMDEsCisgICAgICAgIC8vIElmIHNldCwgdGhpcyByZXNvdXJjZSBoYXMgYmVlbiBkZWNsYXJlZCBwdWJsaWMsIHNvIGxpYnJhcmllcworICAgICAgICAvLyBhcmUgYWxsb3dlZCB0byByZWZlcmVuY2UgaXQuCisgICAgICAgIEZMQUdfUFVCTElDID0gMHgwMDAyCisgICAgfTsKKyAgICB1aW50MTZfdCBmbGFnczsKKyAgICAKKyAgICAvLyBSZWZlcmVuY2UgaW50byBSZXNUYWJsZV9wYWNrYWdlOjprZXlTdHJpbmdzIGlkZW50aWZ5aW5nIHRoaXMgZW50cnkuCisgICAgc3RydWN0IFJlc1N0cmluZ1Bvb2xfcmVmIGtleTsKK307CisKKy8qKgorICogRXh0ZW5kZWQgZm9ybSBvZiBhIFJlc1RhYmxlX2VudHJ5IGZvciBtYXAgZW50cmllcywgZGVmaW5pbmcgYSBwYXJlbnQgbWFwCisgKiByZXNvdXJjZSBmcm9tIHdoaWNoIHRvIGluaGVyaXQgdmFsdWVzLgorICovCitzdHJ1Y3QgUmVzVGFibGVfbWFwX2VudHJ5IDogcHVibGljIFJlc1RhYmxlX2VudHJ5Cit7CisgICAgLy8gUmVzb3VyY2UgaWRlbnRpZmllciBvZiB0aGUgcGFyZW50IG1hcHBpbmcsIG9yIDAgaWYgdGhlcmUgaXMgbm9uZS4KKyAgICBSZXNUYWJsZV9yZWYgcGFyZW50OworICAgIC8vIE51bWJlciBvZiBuYW1lL3ZhbHVlIHBhaXJzIHRoYXQgZm9sbG93IGZvciBGTEFHX0NPTVBMRVguCisgICAgdWludDMyX3QgY291bnQ7Cit9OworCisvKioKKyAqIEEgc2luZ2xlIG5hbWUvdmFsdWUgbWFwcGluZyB0aGF0IGlzIHBhcnQgb2YgYSBjb21wbGV4IHJlc291cmNlCisgKiBlbnRyeS4KKyAqLworc3RydWN0IFJlc1RhYmxlX21hcAoreworICAgIC8vIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyIGRlZmluaW5nIHRoaXMgbWFwcGluZydzIG5hbWUuICBGb3IgYXR0cmlidXRlCisgICAgLy8gcmVzb3VyY2VzLCAnbmFtZScgY2FuIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHNwZWNpYWwgcmVzb3VyY2UgdHlwZXMKKyAgICAvLyB0byBzdXBwbHkgbWV0YS1kYXRhIGFib3V0IHRoZSBhdHRyaWJ1dGU7IGZvciBhbGwgb3RoZXIgcmVzb3VyY2UgdHlwZXMKKyAgICAvLyBpdCBtdXN0IGJlIGFuIGF0dHJpYnV0ZSByZXNvdXJjZS4KKyAgICBSZXNUYWJsZV9yZWYgbmFtZTsKKworICAgIC8vIFNwZWNpYWwgdmFsdWVzIGZvciAnbmFtZScgd2hlbiBkZWZpbmluZyBhdHRyaWJ1dGUgcmVzb3VyY2VzLgorICAgIGVudW0geworICAgICAgICAvLyBUaGlzIGVudHJ5IGhvbGRzIHRoZSBhdHRyaWJ1dGUncyB0eXBlIGNvZGUuCisgICAgICAgIEFUVFJfVFlQRSA9IFJlc19NQUtFSU5URVJOQUwoMCksCisKKyAgICAgICAgLy8gRm9yIGludGVncmFsIGF0dHJpYnV0ZXMsIHRoaXMgaXMgdGhlIG1pbmltdW0gdmFsdWUgaXQgY2FuIGhvbGQuCisgICAgICAgIEFUVFJfTUlOID0gUmVzX01BS0VJTlRFUk5BTCgxKSwKKworICAgICAgICAvLyBGb3IgaW50ZWdyYWwgYXR0cmlidXRlcywgdGhpcyBpcyB0aGUgbWF4aW11bSB2YWx1ZSBpdCBjYW4gaG9sZC4KKyAgICAgICAgQVRUUl9NQVggPSBSZXNfTUFLRUlOVEVSTkFMKDIpLAorCisgICAgICAgIC8vIExvY2FsaXphdGlvbiBvZiB0aGlzIHJlc291cmNlIGlzIGNhbiBiZSBlbmNvdXJhZ2VkIG9yIHJlcXVpcmVkIHdpdGgKKyAgICAgICAgLy8gYW4gYWFwdCBmbGFnIGlmIHRoaXMgaXMgc2V0CisgICAgICAgIEFUVFJfTDEwTiA9IFJlc19NQUtFSU5URVJOQUwoMyksCisKKyAgICAgICAgLy8gZm9yIHBsdXJhbCBzdXBwb3J0LCBzZWUgYW5kcm9pZC5jb250ZW50LnJlcy5QbHVyYWxSdWxlcyNhdHRyRm9yUXVhbnRpdHkoaW50KQorICAgICAgICBBVFRSX09USEVSID0gUmVzX01BS0VJTlRFUk5BTCg0KSwKKyAgICAgICAgQVRUUl9aRVJPID0gUmVzX01BS0VJTlRFUk5BTCg1KSwKKyAgICAgICAgQVRUUl9PTkUgPSBSZXNfTUFLRUlOVEVSTkFMKDYpLAorICAgICAgICBBVFRSX1RXTyA9IFJlc19NQUtFSU5URVJOQUwoNyksCisgICAgICAgIEFUVFJfRkVXID0gUmVzX01BS0VJTlRFUk5BTCg4KSwKKyAgICAgICAgQVRUUl9NQU5ZID0gUmVzX01BS0VJTlRFUk5BTCg5KQorICAgICAgICAKKyAgICB9OworCisgICAgLy8gQml0IG1hc2sgb2YgYWxsb3dlZCB0eXBlcywgZm9yIHVzZSB3aXRoIEFUVFJfVFlQRS4KKyAgICBlbnVtIHsKKyAgICAgICAgLy8gTm8gdHlwZSBoYXMgYmVlbiBkZWZpbmVkIGZvciB0aGlzIGF0dHJpYnV0ZSwgdXNlIGdlbmVyaWMKKyAgICAgICAgLy8gdHlwZSBoYW5kbGluZy4gIFRoZSBsb3cgMTYgYml0cyBhcmUgZm9yIHR5cGVzIHRoYXQgY2FuIGJlCisgICAgICAgIC8vIGhhbmRsZWQgZ2VuZXJpY2FsbHk7IHRoZSB1cHBlciAxNiByZXF1aXJlIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAgICAgICAgLy8gaW4gdGhlIGJhZyBzbyBjYW4gbm90IGJlIGhhbmRsZWQgZ2VuZXJpY2FsbHkgZm9yIFRZUEVfQU5ZLgorICAgICAgICBUWVBFX0FOWSA9IDB4MDAwMEZGRkYsCisKKyAgICAgICAgLy8gQXR0cmlidXRlIGhvbGRzIGEgcmVmZXJlbmNlcyB0byBhbm90aGVyIHJlc291cmNlLgorICAgICAgICBUWVBFX1JFRkVSRU5DRSA9IDE8PDAsCisKKyAgICAgICAgLy8gQXR0cmlidXRlIGhvbGRzIGEgZ2VuZXJpYyBzdHJpbmcuCisgICAgICAgIFRZUEVfU1RSSU5HID0gMTw8MSwKKworICAgICAgICAvLyBBdHRyaWJ1dGUgaG9sZHMgYW4gaW50ZWdlciB2YWx1ZS4gIEFUVFJfTUlOIGFuZCBBVFRSX01JTiBjYW4KKyAgICAgICAgLy8gb3B0aW9uYWxseSBzcGVjaWZ5IGEgY29uc3RyYWluZWQgcmFuZ2Ugb2YgcG9zc2libGUgaW50ZWdlciB2YWx1ZXMuCisgICAgICAgIFRZUEVfSU5URUdFUiA9IDE8PDIsCisKKyAgICAgICAgLy8gQXR0cmlidXRlIGhvbGRzIGEgYm9vbGVhbiBpbnRlZ2VyLgorICAgICAgICBUWVBFX0JPT0xFQU4gPSAxPDwzLAorCisgICAgICAgIC8vIEF0dHJpYnV0ZSBob2xkcyBhIGNvbG9yIHZhbHVlLgorICAgICAgICBUWVBFX0NPTE9SID0gMTw8NCwKKworICAgICAgICAvLyBBdHRyaWJ1dGUgaG9sZHMgYSBmbG9hdGluZyBwb2ludCB2YWx1ZS4KKyAgICAgICAgVFlQRV9GTE9BVCA9IDE8PDUsCisKKyAgICAgICAgLy8gQXR0cmlidXRlIGhvbGRzIGEgZGltZW5zaW9uIHZhbHVlLCBzdWNoIGFzICIyMHB4Ii4KKyAgICAgICAgVFlQRV9ESU1FTlNJT04gPSAxPDw2LAorCisgICAgICAgIC8vIEF0dHJpYnV0ZSBob2xkcyBhIGZyYWN0aW9uIHZhbHVlLCBzdWNoIGFzICIyMCUiLgorICAgICAgICBUWVBFX0ZSQUNUSU9OID0gMTw8NywKKworICAgICAgICAvLyBBdHRyaWJ1dGUgaG9sZHMgYW4gZW51bWVyYXRpb24uICBUaGUgZW51bWVyYXRpb24gdmFsdWVzIGFyZQorICAgICAgICAvLyBzdXBwbGllZCBhcyBhZGRpdGlvbmFsIGVudHJpZXMgaW4gdGhlIG1hcC4KKyAgICAgICAgVFlQRV9FTlVNID0gMTw8MTYsCisKKyAgICAgICAgLy8gQXR0cmlidXRlIGhvbGRzIGEgYml0bWFrcyBvZiBmbGFncy4gIFRoZSBmbGFnIGJpdCB2YWx1ZXMgYXJlCisgICAgICAgIC8vIHN1cHBsaWVkIGFzIGFkZGl0aW9uYWwgZW50cmllcyBpbiB0aGUgbWFwLgorICAgICAgICBUWVBFX0ZMQUdTID0gMTw8MTcKKyAgICB9OworCisgICAgLy8gRW51bSBvZiBsb2NhbGl6YXRpb24gbW9kZXMsIGZvciB1c2Ugd2l0aCBBVFRSX0wxME4uCisgICAgZW51bSB7CisgICAgICAgIEwxME5fTk9UX1JFUVVJUkVEID0gMCwKKyAgICAgICAgTDEwTl9TVUdHRVNURUQgICAgPSAxCisgICAgfTsKKyAgICAKKyAgICAvLyBUaGlzIG1hcHBpbmcncyB2YWx1ZS4KKyAgICBSZXNfdmFsdWUgdmFsdWU7Cit9OworCisvKioKKyAqIENvbnZlbmllbmNlIGNsYXNzIGZvciBhY2Nlc3NpbmcgZGF0YSBpbiBhIFJlc1RhYmxlIHJlc291cmNlLgorICovCitjbGFzcyBSZXNUYWJsZQoreworcHVibGljOgorICAgIFJlc1RhYmxlKCk7CisgICAgUmVzVGFibGUoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIHZvaWQqIGNvb2tpZSwKKyAgICAgICAgICAgICBib29sIGNvcHlEYXRhPWZhbHNlKTsKKyAgICB+UmVzVGFibGUoKTsKKworICAgIHN0YXR1c190IGFkZChjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgdm9pZCogY29va2llLAorICAgICAgICAgICAgICAgICBib29sIGNvcHlEYXRhPWZhbHNlKTsKKyAgICBzdGF0dXNfdCBhZGQoQXNzZXQqIGFzc2V0LCB2b2lkKiBjb29raWUsCisgICAgICAgICAgICAgICAgIGJvb2wgY29weURhdGE9ZmFsc2UpOworCisgICAgc3RhdHVzX3QgZ2V0RXJyb3IoKSBjb25zdDsKKworICAgIHZvaWQgdW5pbml0KCk7CisKKyAgICBzdHJ1Y3QgcmVzb3VyY2VfbmFtZQorICAgIHsKKyAgICAgICAgY29uc3QgY2hhcjE2X3QqIHBhY2thZ2U7CisgICAgICAgIHNpemVfdCBwYWNrYWdlTGVuOworICAgICAgICBjb25zdCBjaGFyMTZfdCogdHlwZTsKKyAgICAgICAgc2l6ZV90IHR5cGVMZW47CisgICAgICAgIGNvbnN0IGNoYXIxNl90KiBuYW1lOworICAgICAgICBzaXplX3QgbmFtZUxlbjsKKyAgICB9OworCisgICAgYm9vbCBnZXRSZXNvdXJjZU5hbWUodWludDMyX3QgcmVzSUQsIHJlc291cmNlX25hbWUqIG91dE5hbWUpIGNvbnN0OworCisgICAgLyoqCisgICAgICogUmV0cmlldmUgdGhlIHZhbHVlIG9mIGEgcmVzb3VyY2UuICBJZiB0aGUgcmVzb3VyY2UgaXMgZm91bmQsIHJldHVybnMgYQorICAgICAqIHZhbHVlID49IDAgaW5kaWNhdGluZyB0aGUgdGFibGUgaXQgaXMgaW4gKGZvciB1c2Ugd2l0aAorICAgICAqIGdldFRhYmxlU3RyaW5nQmxvY2soKSBhbmQgZ2V0VGFibGVDb29raWUoKSkgYW5kIGZpbGxzIGluICdvdXRWYWx1ZScuICBJZgorICAgICAqIG5vdCBmb3VuZCwgcmV0dXJucyBhIG5lZ2F0aXZlIGVycm9yIGNvZGUuCisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBkbyByZWZlcmVuY2UgdHJhdmVyc2FsLiAgSWYgeW91IHdhbnQKKyAgICAgKiB0byBmb2xsb3cgcmVmZXJlbmNlcyB0byBvdGhlciByZXNvdXJjZXMgdG8gZ2V0IHRoZSAicmVhbCIgdmFsdWUgdG8KKyAgICAgKiB1c2UsIHlvdSBuZWVkIHRvIGNhbGwgcmVzb2x2ZVJlZmVyZW5jZSgpIGFmdGVyIHRoaXMgZnVuY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzSUQgVGhlIGRlc2lyZWQgcmVzb3J1Y2UgaWRlbnRpZmllci4KKyAgICAgKiBAcGFyYW0gb3V0VmFsdWUgRmlsbGVkIGluIHdpdGggdGhlIHJlc291cmNlIGRhdGEgdGhhdCB3YXMgZm91bmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNzaXplX3QgRWl0aGVyIGEgPj0gMCB0YWJsZSBpbmRleCBvciBhIG5lZ2F0aXZlIGVycm9yIGNvZGUuCisgICAgICovCisgICAgc3NpemVfdCBnZXRSZXNvdXJjZSh1aW50MzJfdCByZXNJRCwgUmVzX3ZhbHVlKiBvdXRWYWx1ZSwgYm9vbCBtYXlCZUJhZz1mYWxzZSwKKyAgICAgICAgICAgIHVpbnQzMl90KiBvdXRTcGVjRmxhZ3M9TlVMTCwgUmVzVGFibGVfY29uZmlnKiBvdXRDb25maWc9TlVMTCkgY29uc3Q7CisKKyAgICBpbmxpbmUgc3NpemVfdCBnZXRSZXNvdXJjZShjb25zdCBSZXNUYWJsZV9yZWYmIHJlcywgUmVzX3ZhbHVlKiBvdXRWYWx1ZSwKKyAgICAgICAgICAgIHVpbnQzMl90KiBvdXRTcGVjRmxhZ3M9TlVMTCkgY29uc3QgeworICAgICAgICByZXR1cm4gZ2V0UmVzb3VyY2UocmVzLmlkZW50LCBvdXRWYWx1ZSwgZmFsc2UsIG91dFNwZWNGbGFncywgTlVMTCk7CisgICAgfQorCisgICAgc3NpemVfdCByZXNvbHZlUmVmZXJlbmNlKFJlc192YWx1ZSogaW5PdXRWYWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NpemVfdCBibG9ja0luZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCogb3V0TGFzdFJlZiA9IE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90KiBpbm91dFR5cGVTcGVjRmxhZ3MgPSBOVUxMKSBjb25zdDsKKworICAgIGVudW0geworICAgICAgICBUTVBfQlVGRkVSX1NJWkUgPSAxNgorICAgIH07CisgICAgY29uc3QgY2hhcjE2X3QqIHZhbHVlVG9TdHJpbmcoY29uc3QgUmVzX3ZhbHVlKiB2YWx1ZSwgc2l6ZV90IHN0cmluZ0Jsb2NrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIxNl90IHRtcEJ1ZmZlcltUTVBfQlVGRkVSX1NJWkVdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCogb3V0TGVuKTsKKworICAgIHN0cnVjdCBiYWdfZW50cnkgeworICAgICAgICBzc2l6ZV90IHN0cmluZ0Jsb2NrOworICAgICAgICBSZXNUYWJsZV9tYXAgbWFwOworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSB0aGUgYmFnIG9mIGEgcmVzb3VyY2UuICBJZiB0aGUgcmVzb3J1Y2UgaXMgZm91bmQsIHJldHVybnMgdGhlCisgICAgICogbnVtYmVyIG9mIGJhZ3MgaXQgY29udGFpbnMgYW5kICdvdXRCYWcnIHBvaW50cyB0byBhbiBhcnJheSBvZiB0aGVpcgorICAgICAqIHZhbHVlcy4gIElmIG5vdCBmb3VuZCwgYSBuZWdhdGl2ZSBlcnJvciBjb2RlIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gLWRvZXMtIGRvIHJlZmVyZW5jZSB0cmF2ZXJzYWwgb2YgdGhlIGJhZyBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc0lEIFRoZSBkZXNpcmVkIHJlc291cmNlIGlkZW50aWZpZXIuCisgICAgICogQHBhcmFtIG91dEJhZyBGaWxsZWQgaW5tIHdpdGggYSBwb2ludGVyIHRvIHRoZSBiYWcgbWFwcGluZ3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNzaXplX3QgRWl0aGVyIGEgPj0gMCBiYWcgY291bnQgb2YgbmVnYXRpdmUgZXJyb3IgY29kZS4KKyAgICAgKi8KKyAgICBzc2l6ZV90IGxvY2tCYWcodWludDMyX3QgcmVzSUQsIGNvbnN0IGJhZ19lbnRyeSoqIG91dEJhZykgY29uc3Q7CisKKyAgICB2b2lkIHVubG9ja0JhZyhjb25zdCBiYWdfZW50cnkqIGJhZykgY29uc3Q7CisKKyAgICB2b2lkIGxvY2soKSBjb25zdDsKKworICAgIHNzaXplX3QgZ2V0QmFnTG9ja2VkKHVpbnQzMl90IHJlc0lELCBjb25zdCBiYWdfZW50cnkqKiBvdXRCYWcsCisgICAgICAgICAgICB1aW50MzJfdCogb3V0VHlwZVNwZWNGbGFncz1OVUxMKSBjb25zdDsKKworICAgIHZvaWQgdW5sb2NrKCkgY29uc3Q7CisKKyAgICBjbGFzcyBUaGVtZSB7CisgICAgcHVibGljOgorICAgICAgICBUaGVtZShjb25zdCBSZXNUYWJsZSYgdGFibGUpOworICAgICAgICB+VGhlbWUoKTsKKworICAgICAgICBpbmxpbmUgY29uc3QgUmVzVGFibGUmIGdldFJlc1RhYmxlKCkgY29uc3QgeyByZXR1cm4gbVRhYmxlOyB9CisKKyAgICAgICAgc3RhdHVzX3QgYXBwbHlTdHlsZSh1aW50MzJfdCByZXNJRCwgYm9vbCBmb3JjZT1mYWxzZSk7CisgICAgICAgIHN0YXR1c190IHNldFRvKGNvbnN0IFRoZW1lJiBvdGhlcik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHJpZXZlIGEgdmFsdWUgaW4gdGhlIHRoZW1lLiAgSWYgdGhlIHRoZW1lIGRlZmluZXMgdGhpcworICAgICAgICAgKiB2YWx1ZSwgcmV0dXJucyBhIHZhbHVlID49IDAgaW5kaWNhdGluZyB0aGUgdGFibGUgaXQgaXMgaW4KKyAgICAgICAgICogKGZvciB1c2Ugd2l0aCBnZXRUYWJsZVN0cmluZ0Jsb2NrKCkgYW5kIGdldFRhYmxlQ29va2llKSBhbmQKKyAgICAgICAgICogZmlsbHMgaW4gJ291dFZhbHVlJy4gIElmIG5vdCBmb3VuZCwgcmV0dXJucyBhIG5lZ2F0aXZlIGVycm9yCisgICAgICAgICAqIGNvZGUuCisgICAgICAgICAqCisgICAgICAgICAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRvIHJlZmVyZW5jZSB0cmF2ZXJzYWwuICBJZiB5b3Ugd2FudAorICAgICAgICAgKiB0byBmb2xsb3cgcmVmZXJlbmNlcyB0byBvdGhlciByZXNvdXJjZXMgdG8gZ2V0IHRoZSAicmVhbCIgdmFsdWUgdG8KKyAgICAgICAgICogdXNlLCB5b3UgbmVlZCB0byBjYWxsIHJlc29sdmVSZWZlcmVuY2UoKSBhZnRlciB0aGlzIGZ1bmN0aW9uLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcmVzSUQgQSByZXNvdXJjZSBpZGVudGlmaWVyIG5hbWluZyB0aGUgZGVzaXJlZCB0aGVtZQorICAgICAgICAgKiAgICAgICAgICAgICAgYXR0cmlidXRlLgorICAgICAgICAgKiBAcGFyYW0gb3V0VmFsdWUgRmlsbGVkIGluIHdpdGggdGhlIHRoZW1lIHZhbHVlIHRoYXQgd2FzCisgICAgICAgICAqICAgICAgICAgICAgICAgICBmb3VuZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiBzc2l6ZV90IEVpdGhlciBhID49IDAgdGFibGUgaW5kZXggb3IgYSBuZWdhdGl2ZSBlcnJvciBjb2RlLgorICAgICAgICAgKi8KKyAgICAgICAgc3NpemVfdCBnZXRBdHRyaWJ1dGUodWludDMyX3QgcmVzSUQsIFJlc192YWx1ZSogb3V0VmFsdWUsCisgICAgICAgICAgICAgICAgdWludDMyX3QqIG91dFR5cGVTcGVjRmxhZ3MgPSBOVUxMKSBjb25zdDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBpcyBsaWtlIFJlc1RhYmxlOjpyZXNvbHZlUmVmZXJlbmNlKCksIGJ1dCBhbHNvIHRha2VzCisgICAgICAgICAqIGNhcmUgb2YgcmVzb2x2aW5nIGF0dHJpYnV0ZSByZWZlcmVuY2VzIHRvIHRoZSB0aGVtZS4KKyAgICAgICAgICovCisgICAgICAgIHNzaXplX3QgcmVzb2x2ZUF0dHJpYnV0ZVJlZmVyZW5jZShSZXNfdmFsdWUqIGluT3V0VmFsdWUsCisgICAgICAgICAgICAgICAgc3NpemVfdCBibG9ja0luZGV4LCB1aW50MzJfdCogb3V0TGFzdFJlZiA9IE5VTEwsCisgICAgICAgICAgICAgICAgdWludDMyX3QqIGlub3V0VHlwZVNwZWNGbGFncyA9IE5VTEwpIGNvbnN0OworCisgICAgICAgIHZvaWQgZHVtcFRvTG9nKCkgY29uc3Q7CisgICAgICAgIAorICAgIHByaXZhdGU6CisgICAgICAgIFRoZW1lKGNvbnN0IFRoZW1lJik7CisgICAgICAgIFRoZW1lJiBvcGVyYXRvcj0oY29uc3QgVGhlbWUmKTsKKworICAgICAgICBzdHJ1Y3QgdGhlbWVfZW50cnkgeworICAgICAgICAgICAgc3NpemVfdCBzdHJpbmdCbG9jazsKKyAgICAgICAgICAgIHVpbnQzMl90IHR5cGVTcGVjRmxhZ3M7CisgICAgICAgICAgICBSZXNfdmFsdWUgdmFsdWU7CisgICAgICAgIH07CisgICAgICAgIHN0cnVjdCB0eXBlX2luZm8geworICAgICAgICAgICAgc2l6ZV90IG51bUVudHJpZXM7CisgICAgICAgICAgICB0aGVtZV9lbnRyeSogZW50cmllczsKKyAgICAgICAgfTsKKyAgICAgICAgc3RydWN0IHBhY2thZ2VfaW5mbyB7CisgICAgICAgICAgICBzaXplX3QgbnVtVHlwZXM7CisgICAgICAgICAgICB0eXBlX2luZm8gdHlwZXNbXTsKKyAgICAgICAgfTsKKworICAgICAgICB2b2lkIGZyZWVfcGFja2FnZShwYWNrYWdlX2luZm8qIHBpKTsKKyAgICAgICAgcGFja2FnZV9pbmZvKiBjb3B5X3BhY2thZ2UocGFja2FnZV9pbmZvKiBwaSk7CisKKyAgICAgICAgY29uc3QgUmVzVGFibGUmIG1UYWJsZTsKKyAgICAgICAgcGFja2FnZV9pbmZvKiAgIG1QYWNrYWdlc1tSZXNfTUFYUEFDS0FHRV07CisgICAgfTsKKworICAgIHZvaWQgc2V0UGFyYW1ldGVycyhjb25zdCBSZXNUYWJsZV9jb25maWcqIHBhcmFtcyk7CisgICAgdm9pZCBnZXRQYXJhbWV0ZXJzKFJlc1RhYmxlX2NvbmZpZyogcGFyYW1zKSBjb25zdDsKKworICAgIC8vIFJldHJpZXZlIGFuIGlkZW50aWZpZXIgKHdoaWNoIGNhbiBiZSBwYXNzZWQgdG8gZ2V0UmVzb3VyY2UpCisgICAgLy8gZm9yIGEgZ2l2ZW4gcmVzb3VyY2UgbmFtZS4gIFRoZSAnbmFtZScgY2FuIGJlIGZ1bGx5IHF1YWxpZmllZAorICAgIC8vICg8cGFja2FnZT46PHR5cGU+LjxiYXNlbmFtZT4pIG9yIHRoZSBwYWNrYWdlIG9yIHR5cGUgY29tcG9uZW50cworICAgIC8vIGNhbiBiZSBkcm9wcGVkIGlmIGRlZmF1bHQgdmFsdWVzIGFyZSBzdXBwbGllZCBoZXJlLgorICAgIC8vCisgICAgLy8gUmV0dXJucyAwIGlmIG5vIHN1Y2ggcmVzb3VyY2Ugd2FzIGZvdW5kLCBlbHNlIGEgdmFsaWQgcmVzb3VyY2UgSUQuCisgICAgdWludDMyX3QgaWRlbnRpZmllckZvck5hbWUoY29uc3QgY2hhcjE2X3QqIG5hbWUsIHNpemVfdCBuYW1lTGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiB0eXBlID0gMCwgc2l6ZV90IHR5cGVMZW4gPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBkZWZQYWNrYWdlID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgZGVmUGFja2FnZUxlbiA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QqIG91dFR5cGVTcGVjRmxhZ3MgPSBOVUxMKSBjb25zdDsKKworICAgIHN0YXRpYyBib29sIGV4cGFuZFJlc291cmNlUmVmKGNvbnN0IHVpbnQxNl90KiByZWZTdHIsIHNpemVfdCByZWZMZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYqIG91dFBhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYqIG91dFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYqIG91dE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nMTYqIGRlZlR5cGUgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFN0cmluZzE2KiBkZWZQYWNrYWdlID0gTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiogb3V0RXJyb3JNc2cgPSBOVUxMKTsKKworICAgIHN0YXRpYyBib29sIHN0cmluZ1RvSW50KGNvbnN0IGNoYXIxNl90KiBzLCBzaXplX3QgbGVuLCBSZXNfdmFsdWUqIG91dFZhbHVlKTsKKyAgICBzdGF0aWMgYm9vbCBzdHJpbmdUb0Zsb2F0KGNvbnN0IGNoYXIxNl90KiBzLCBzaXplX3QgbGVuLCBSZXNfdmFsdWUqIG91dFZhbHVlKTsKKworICAgIC8vIFVzZWQgd2l0aCBzdHJpbmdUb1ZhbHVlLgorICAgIGNsYXNzIEFjY2Vzc29yCisgICAgeworICAgIHB1YmxpYzoKKyAgICAgICAgaW5saW5lIHZpcnR1YWwgfkFjY2Vzc29yKCkgeyB9CisKKyAgICAgICAgdmlydHVhbCB1aW50MzJfdCBnZXRDdXN0b21SZXNvdXJjZShjb25zdCBTdHJpbmcxNiYgcGFja2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTdHJpbmcxNiYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTdHJpbmcxNiYgbmFtZSkgY29uc3QgPSAwOworICAgICAgICB2aXJ0dWFsIHVpbnQzMl90IGdldEN1c3RvbVJlc291cmNlV2l0aENyZWF0aW9uKGNvbnN0IFN0cmluZzE2JiBwYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFN0cmluZzE2JiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFN0cmluZzE2JiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvb2wgY3JlYXRlSWZOZWVkZWQgPSBmYWxzZSkgPSAwOworICAgICAgICB2aXJ0dWFsIHVpbnQzMl90IGdldFJlbWFwcGVkUGFja2FnZSh1aW50MzJfdCBvcmlnUGFja2FnZSkgY29uc3QgPSAwOworICAgICAgICB2aXJ0dWFsIGJvb2wgZ2V0QXR0cmlidXRlVHlwZSh1aW50MzJfdCBhdHRySUQsIHVpbnQzMl90KiBvdXRUeXBlKSA9IDA7CisgICAgICAgIHZpcnR1YWwgYm9vbCBnZXRBdHRyaWJ1dGVNaW4odWludDMyX3QgYXR0cklELCB1aW50MzJfdCogb3V0TWluKSA9IDA7CisgICAgICAgIHZpcnR1YWwgYm9vbCBnZXRBdHRyaWJ1dGVNYXgodWludDMyX3QgYXR0cklELCB1aW50MzJfdCogb3V0TWF4KSA9IDA7CisgICAgICAgIHZpcnR1YWwgYm9vbCBnZXRBdHRyaWJ1dGVFbnVtKHVpbnQzMl90IGF0dHJJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIG5hbWUsIHNpemVfdCBuYW1lTGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNfdmFsdWUqIG91dFZhbHVlKSA9IDA7CisgICAgICAgIHZpcnR1YWwgYm9vbCBnZXRBdHRyaWJ1dGVGbGFncyh1aW50MzJfdCBhdHRySUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyMTZfdCogbmFtZSwgc2l6ZV90IG5hbWVMZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNfdmFsdWUqIG91dFZhbHVlKSA9IDA7CisgICAgICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0QXR0cmlidXRlTDEwTih1aW50MzJfdCBhdHRySUQpID0gMDsKKyAgICAgICAgdmlydHVhbCBib29sIGdldExvY2FsaXphdGlvblNldHRpbmcoKSA9IDA7CisgICAgICAgIHZpcnR1YWwgdm9pZCByZXBvcnRFcnJvcih2b2lkKiBhY2Nlc3NvckNvb2tpZSwgY29uc3QgY2hhciogZm10LCAuLi4pID0gMDsKKyAgICB9OworCisgICAgLy8gQ29udmVydCBhIHN0cmluZyB0byBhIHJlc291cmNlIHZhbHVlLiAgSGFuZGxlcyBzdGFuZGFyZCAiQHJlcyIsCisgICAgLy8gIiNjb2xvciIsICIxMjMiLCBhbmQgIjB4MWJkIiB0eXBlczsgcGVyZm9ybXMgZXNjYXBpbmcgb2Ygc3RyaW5ncy4KKyAgICAvLyBUaGUgcmVzdWx0aW5nIHZhbHVlIGlzIHBsYWNlZCBpbiAnb3V0VmFsdWUnOyBpZiBpdCBpcyBhIHN0cmluZyB0eXBlLAorICAgIC8vICdvdXRTdHJpbmcnIHJlY2VpdmVzIHRoZSBzdHJpbmcuICBJZiAnYXR0cklEJyBpcyBzdXBwbGllZCwgdGhlIHZhbHVlIGlzCisgICAgLy8gdHlwZSBjaGVja2VkIGFnYWluc3QgdGhpcyBhdHRyaWJ1dGUgYW5kIGl0IGlzIHVzZWQgdG8gcGVyZm9ybSBlbnVtCisgICAgLy8gZXZhbHVhdGlvbi4gIElmICdhY2NjZXNzb3InIGlzIHN1cHBsaWVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gYXR0ZW1wdCB0bworICAgIC8vIHJlc29sdmUgcmVzb3VyY2VzIHRoYXQgZG8gbm90IGV4aXN0IGluIHRoaXMgUmVzVGFibGUuICBJZiAnYXR0clR5cGUnIGlzCisgICAgLy8gc3VwcGxpZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIHR5cGUgY2hlY2tlZCBmb3IgdGhpcyBmb3JtYXQgaWYgJ2F0dHJJRCcKKyAgICAvLyBpcyBub3Qgc3VwcGxpZWQgb3IgZm91bmQuCisgICAgYm9vbCBzdHJpbmdUb1ZhbHVlKFJlc192YWx1ZSogb3V0VmFsdWUsIFN0cmluZzE2KiBvdXRTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzLCBzaXplX3QgbGVuLAorICAgICAgICAgICAgICAgICAgICAgICBib29sIHByZXNlcnZlU3BhY2VzLCBib29sIGNvZXJjZVR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGF0dHJJRCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFN0cmluZzE2KiBkZWZUeXBlID0gTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nMTYqIGRlZlBhY2thZ2UgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NvciogYWNjZXNzb3IgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBhY2Nlc3NvckNvb2tpZSA9IE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGF0dHJUeXBlID0gUmVzVGFibGVfbWFwOjpUWVBFX0FOWSwKKyAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBlbmZvcmNlUHJpdmF0ZSA9IHRydWUpIGNvbnN0OworCisgICAgLy8gUGVyZm9ybSBwcm9jZXNzaW5nIG9mIGVzY2FwZXMgYW5kIHF1b3RlcyBpbiBhIHN0cmluZy4KKyAgICBzdGF0aWMgYm9vbCBjb2xsZWN0U3RyaW5nKFN0cmluZzE2KiBvdXRTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyMTZfdCogcywgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcHJlc2VydmVTcGFjZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiogb3V0RXJyb3JNc2cgPSBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBhcHBlbmQgPSBmYWxzZSk7CisKKyAgICBzaXplX3QgZ2V0QmFzZVBhY2thZ2VDb3VudCgpIGNvbnN0OworICAgIGNvbnN0IGNoYXIxNl90KiBnZXRCYXNlUGFja2FnZU5hbWUoc2l6ZV90IGlkeCkgY29uc3Q7CisgICAgdWludDMyX3QgZ2V0QmFzZVBhY2thZ2VJZChzaXplX3QgaWR4KSBjb25zdDsKKworICAgIHNpemVfdCBnZXRUYWJsZUNvdW50KCkgY29uc3Q7CisgICAgY29uc3QgUmVzU3RyaW5nUG9vbCogZ2V0VGFibGVTdHJpbmdCbG9jayhzaXplX3QgaW5kZXgpIGNvbnN0OworICAgIHZvaWQqIGdldFRhYmxlQ29va2llKHNpemVfdCBpbmRleCkgY29uc3Q7CisKKyAgICAvLyBSZXR1cm4gdGhlIGNvbmZpZ3VyYXRpb25zIChSZXNUYWJsZV9jb25maWcpIHRoYXQgd2Uga25vdyBhYm91dAorICAgIHZvaWQgZ2V0Q29uZmlndXJhdGlvbnMoVmVjdG9yPFJlc1RhYmxlX2NvbmZpZz4qIGNvbmZpZ3MpIGNvbnN0OworCisgICAgdm9pZCBnZXRMb2NhbGVzKFZlY3RvcjxTdHJpbmc4PiogbG9jYWxlcykgY29uc3Q7CisKKyNpZm5kZWYgSEFWRV9BTkRST0lEX09TCisgICAgdm9pZCBwcmludCgpIGNvbnN0OworI2VuZGlmCisKK3ByaXZhdGU6CisgICAgc3RydWN0IEhlYWRlcjsKKyAgICBzdHJ1Y3QgVHlwZTsKKyAgICBzdHJ1Y3QgUGFja2FnZTsKKyAgICBzdHJ1Y3QgUGFja2FnZUdyb3VwOworICAgIHN0cnVjdCBiYWdfc2V0OworCisgICAgc3RhdHVzX3QgYWRkKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCB2b2lkKiBjb29raWUsCisgICAgICAgICAgICAgICAgIEFzc2V0KiBhc3NldCwgYm9vbCBjb3B5RGF0YSk7CisKKyAgICBzc2l6ZV90IGdldFJlc291cmNlUGFja2FnZUluZGV4KHVpbnQzMl90IHJlc0lEKSBjb25zdDsKKyAgICBzc2l6ZV90IGdldEVudHJ5KAorICAgICAgICBjb25zdCBQYWNrYWdlKiBwYWNrYWdlLCBpbnQgdHlwZUluZGV4LCBpbnQgZW50cnlJbmRleCwKKyAgICAgICAgY29uc3QgUmVzVGFibGVfY29uZmlnKiBjb25maWcsCisgICAgICAgIGNvbnN0IFJlc1RhYmxlX3R5cGUqKiBvdXRUeXBlLCBjb25zdCBSZXNUYWJsZV9lbnRyeSoqIG91dEVudHJ5LAorICAgICAgICBjb25zdCBUeXBlKiogb3V0VHlwZUNsYXNzKSBjb25zdDsKKyAgICBzdGF0dXNfdCBwYXJzZVBhY2thZ2UoCisgICAgICAgIGNvbnN0IFJlc1RhYmxlX3BhY2thZ2UqIGNvbnN0IHBrZywgY29uc3QgSGVhZGVyKiBjb25zdCBoZWFkZXIpOworCisgICAgbXV0YWJsZSBNdXRleCAgICAgICAgICAgICAgIG1Mb2NrOworCisgICAgc3RhdHVzX3QgICAgICAgICAgICAgICAgICAgIG1FcnJvcjsKKworICAgIFJlc1RhYmxlX2NvbmZpZyAgICAgICAgICAgICBtUGFyYW1zOworCisgICAgLy8gQXJyYXkgb2YgYWxsIHJlc291cmNlIHRhYmxlcy4KKyAgICBWZWN0b3I8SGVhZGVyKj4gICAgICAgICAgICAgbUhlYWRlcnM7CisKKyAgICAvLyBBcnJheSBvZiBwYWNrYWdlcyBpbiBhbGwgcmVzb3VyY2UgdGFibGVzLgorICAgIFZlY3RvcjxQYWNrYWdlR3JvdXAqPiAgICAgICBtUGFja2FnZUdyb3VwczsKKworICAgIC8vIE1hcHBpbmcgZnJvbSByZXNvdXJjZSBwYWNrYWdlIElEcyB0byBpbmRpY2VzIGludG8gdGhlIGludGVybmFsCisgICAgLy8gcGFja2FnZSBhcnJheS4KKyAgICB1aW50OF90ICAgICAgICAgICAgICAgICAgICAgbVBhY2thZ2VNYXBbMjU2XTsKK307CisKK30gICAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gX0xJQlNfVVRJTFNfUkVTT1VSQ0VfVFlQRVNfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9TaGFyZWRCdWZmZXIuaCBiL2luY2x1ZGUvdXRpbHMvU2hhcmVkQnVmZmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQ1MDhiMAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvU2hhcmVkQnVmZmVyLmgKQEAgLTAsMCArMSwxNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfU0hBUkVEX0JVRkZFUl9ICisjZGVmaW5lIEFORFJPSURfU0hBUkVEX0JVRkZFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgU2hhcmVkQnVmZmVyCit7CitwdWJsaWM6CisKKyAgICAvKiBmbGFncyB0byB1c2Ugd2l0aCByZWxlYXNlKCkgKi8KKyAgICBlbnVtIHsKKyAgICAgICAgZUtlZXBTdG9yYWdlID0gMHgwMDAwMDAwMQorICAgIH07CisKKyAgICAvKiEgYWxsb2NhdGUgYSBidWZmZXIgb2Ygc2l6ZSAnc2l6ZScgYW5kIGFjcXVpcmUoKSBpdC4KKyAgICAgKiAgY2FsbCByZWxlYXNlKCkgdG8gZnJlZSBpdC4KKyAgICAgKi8KKyAgICBzdGF0aWMgICAgICAgICAgU2hhcmVkQnVmZmVyKiAgICAgICAgICAgYWxsb2Moc2l6ZV90IHNpemUpOworICAgIAorICAgIC8qISBmcmVlIHRoZSBtZW1vcnkgYXNzb2NpYXRlZCB3aXRoIHRoZSBTaGFyZWRCdWZmZXIuCisgICAgICogRmFpbHMgaWYgdGhlcmUgYXJlIGFueSB1c2VycyBhc3NvY2lhdGVkIHdpdGggdGhpcyBTaGFyZWRCdWZmZXIuCisgICAgICogSW4gb3RoZXIgd29yZHMsIHRoZSBidWZmZXIgbXVzdCBoYXZlIGJlZW4gcmVsZWFzZSBieSBhbGwgaXRzCisgICAgICogdXNlcnMuCisgICAgICovCisgICAgc3RhdGljICAgICAgICAgIHNzaXplX3QgICAgICAgICAgICAgICAgIGRlYWxsb2MoY29uc3QgU2hhcmVkQnVmZmVyKiByZWxlYXNlZCk7CisgICAgCisgICAgLy8hIGdldCB0aGUgU2hhcmVkQnVmZmVyIGZyb20gdGhlIGRhdGEgcG9pbnRlcgorICAgIHN0YXRpYyAgaW5saW5lICBjb25zdCBTaGFyZWRCdWZmZXIqICAgICBzaGFyZWRCdWZmZXIoY29uc3Qgdm9pZCogZGF0YSk7CisKKyAgICAvLyEgYWNjZXNzIHRoZSBkYXRhIGZvciByZWFkCisgICAgaW5saW5lICAgICAgICAgIGNvbnN0IHZvaWQqICAgICAgICAgICAgIGRhdGEoKSBjb25zdDsKKyAgICAKKyAgICAvLyEgYWNjZXNzIHRoZSBkYXRhIGZvciByZWFkL3dyaXRlCisgICAgaW5saW5lICAgICAgICAgIHZvaWQqICAgICAgICAgICAgICAgICAgIGRhdGEoKTsKKworICAgIC8vISBnZXQgc2l6ZSBvZiB0aGUgYnVmZmVyCisgICAgaW5saW5lICAgICAgICAgIHNpemVfdCAgICAgICAgICAgICAgICAgIHNpemUoKSBjb25zdDsKKyAKKyAgICAvLyEgZ2V0IGJhY2sgYSBTaGFyZWRCdWZmZXIgb2JqZWN0IGZyb20gaXRzIGRhdGEKKyAgICBzdGF0aWMgIGlubGluZSAgU2hhcmVkQnVmZmVyKiAgICAgICAgICAgYnVmZmVyRnJvbURhdGEodm9pZCogZGF0YSk7CisgICAgCisgICAgLy8hIGdldCBiYWNrIGEgU2hhcmVkQnVmZmVyIG9iamVjdCBmcm9tIGl0cyBkYXRhCisgICAgc3RhdGljICBpbmxpbmUgIGNvbnN0IFNoYXJlZEJ1ZmZlciogICAgIGJ1ZmZlckZyb21EYXRhKGNvbnN0IHZvaWQqIGRhdGEpOworCisgICAgLy8hIGdldCB0aGUgc2l6ZSBvZiBhIFNoYXJlZEJ1ZmZlciBvYmplY3QgZnJvbSBpdHMgZGF0YQorICAgIHN0YXRpYyAgaW5saW5lICBzaXplX3QgICAgICAgICAgICAgICAgICBzaXplRnJvbURhdGEoY29uc3Qgdm9pZCogZGF0YSk7CisgICAgCisgICAgLy8hIGVkaXQgdGhlIGJ1ZmZlciAoZ2V0IGEgd3JpdHRhYmxlLCBvciBub24tY29uc3QsIHZlcnNpb24gb2YgaXQpCisgICAgICAgICAgICAgICAgICAgIFNoYXJlZEJ1ZmZlciogICAgICAgICAgIGVkaXQoKSBjb25zdDsKKworICAgIC8vISBlZGl0IHRoZSBidWZmZXIsIHJlc2l6aW5nIGlmIG5lZWRlZAorICAgICAgICAgICAgICAgICAgICBTaGFyZWRCdWZmZXIqICAgICAgICAgICBlZGl0UmVzaXplKHNpemVfdCBzaXplKSBjb25zdDsKKworICAgIC8vISBsaWtlIGVkaXQoKSBidXQgZmFpbHMgaWYgYSBjb3B5IGlzIHJlcXVpcmVkCisgICAgICAgICAgICAgICAgICAgIFNoYXJlZEJ1ZmZlciogICAgICAgICAgIGF0dGVtcHRFZGl0KCkgY29uc3Q7CisgICAgCisgICAgLy8hIHJlc2l6ZSBhbmQgZWRpdCB0aGUgYnVmZmVyLCBsb29zZSBpdCdzIGNvbnRlbnQuCisgICAgICAgICAgICAgICAgICAgIFNoYXJlZEJ1ZmZlciogICAgICAgICAgIHJlc2V0KHNpemVfdCBzaXplKSBjb25zdDsKKworICAgIC8vISBhY3F1aXJlL3JlbGVhc2UgYSByZWZlcmVuY2Ugb24gdGhpcyBidWZmZXIKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgYWNxdWlyZSgpIGNvbnN0OworICAgICAgICAgICAgICAgICAgICAKKyAgICAvKiEgcmVsZWFzZSBhIHJlZmVyZW5jZSBvbiB0aGlzIGJ1ZmZlciwgd2l0aCB0aGUgb3B0aW9uIG9mIG5vdAorICAgICAqIGZyZWVpbmcgdGhlIG1lbW9yeSBhc3NvY2lhdGVkIHdpdGggaXQgaWYgaXQgd2FzIHRoZSBsYXN0IHJlZmVyZW5jZQorICAgICAqIHJldHVybnMgdGhlIHByZXZpb3VzIHJlZmVyZW5jZSBjb3VudAorICAgICAqLyAgICAgCisgICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgIHJlbGVhc2UodWludDMyX3QgZmxhZ3MgPSAwKSBjb25zdDsKKyAgICAKKyAgICAvLyEgcmV0dXJucyB3ZXRoZXIgb3Igbm90IHdlJ3JlIHRoZSBvbmx5IG93bmVyCisgICAgaW5saW5lICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgICAgIG9ubHlPd25lcigpIGNvbnN0OworICAgIAorCitwcml2YXRlOgorICAgICAgICBpbmxpbmUgU2hhcmVkQnVmZmVyKCkgeyB9CisgICAgICAgIGlubGluZSB+U2hhcmVkQnVmZmVyKCkgeyB9CisgICAgICAgIGlubGluZSBTaGFyZWRCdWZmZXIoY29uc3QgU2hhcmVkQnVmZmVyJik7CisgCisgICAgICAgIC8vIDE2IGJ5dGVzLiBtdXN0IGJlIHNpemVkIHRvIHByZXNlcnZlIGNvcnJlY3QgYWxpbmdtZW50LgorICAgICAgICBtdXRhYmxlIGludDMyX3QgICAgICAgIG1SZWZzOworICAgICAgICAgICAgICAgIHNpemVfdCAgICAgICAgIG1TaXplOworICAgICAgICAgICAgICAgIHVpbnQzMl90ICAgICAgIG1SZXNlcnZlZFsyXTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCBTaGFyZWRCdWZmZXIqIFNoYXJlZEJ1ZmZlcjo6c2hhcmVkQnVmZmVyKGNvbnN0IHZvaWQqIGRhdGEpIHsKKyAgICByZXR1cm4gZGF0YSA/IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgU2hhcmVkQnVmZmVyICo+KGRhdGEpLTEgOiAwOworfQorCitjb25zdCB2b2lkKiBTaGFyZWRCdWZmZXI6OmRhdGEoKSBjb25zdCB7CisgICAgcmV0dXJuIHRoaXMgKyAxOworfQorCit2b2lkKiBTaGFyZWRCdWZmZXI6OmRhdGEoKSB7CisgICAgcmV0dXJuIHRoaXMgKyAxOworfQorCitzaXplX3QgU2hhcmVkQnVmZmVyOjpzaXplKCkgY29uc3QgeworICAgIHJldHVybiBtU2l6ZTsKK30KKworU2hhcmVkQnVmZmVyKiBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKHZvaWQqIGRhdGEpCit7CisgICAgcmV0dXJuICgoU2hhcmVkQnVmZmVyKilkYXRhKS0xOworfQorICAgIAorY29uc3QgU2hhcmVkQnVmZmVyKiBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKGNvbnN0IHZvaWQqIGRhdGEpCit7CisgICAgcmV0dXJuICgoY29uc3QgU2hhcmVkQnVmZmVyKilkYXRhKS0xOworfQorCitzaXplX3QgU2hhcmVkQnVmZmVyOjpzaXplRnJvbURhdGEoY29uc3Qgdm9pZCogZGF0YSkKK3sKKyAgICByZXR1cm4gKCgoY29uc3QgU2hhcmVkQnVmZmVyKilkYXRhKS0xKS0+bVNpemU7Cit9CisKK2Jvb2wgU2hhcmVkQnVmZmVyOjpvbmx5T3duZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIChtUmVmcyA9PSAxKTsKK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvLyBBTkRST0lEX1ZFQ1RPUl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1NvY2tldC5oIGIvaW5jbHVkZS91dGlscy9Tb2NrZXQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjdmNDA2Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9Tb2NrZXQuaApAQCAtMCwwICsxLDgwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIFNvY2tldCBjbGFzcy4gIE1vZGVsZWQgYWZ0ZXIgSmF2YSBjbGFzc2VzLgorLy8KKyNpZm5kZWYgX1JVTlRJTUVfU09DS0VUX0gKKyNkZWZpbmUgX1JVTlRJTUVfU09DS0VUX0gKKworI2luY2x1ZGUgPHV0aWxzL2luZXRfYWRkcmVzcy5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8qCisgKiBCYXNpYyBzb2NrZXQgY2xhc3MsIG5lZWRlZCB0byBhYnN0cmFjdCBhd2F5IHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuCisgKiBCU0Qgc29ja2V0cyBhbmQgV2luU29jay4gIFRoaXMgZXN0YWJsaXNoZXMgYSBzdHJlYW1pbmcgbmV0d29yaworICogY29ubmVjdGlvbiAoVENQL0lQKSB0byBzb21lYm9keS4KKyAqLworY2xhc3MgU29ja2V0IHsKK3B1YmxpYzoKKyAgICBTb2NrZXQodm9pZCk7CisgICAgflNvY2tldCh2b2lkKTsKKworICAgIC8vIENyZWF0ZSBhIGNvbm5lY3Rpb24gdG8gc29tZXdoZXJlLgorICAgIC8vIFJldHVybiAwIG9uIHN1Y2Nlc3MuCisgICAgaW50IGNvbm5lY3QoY29uc3QgY2hhciogaG9zdCwgaW50IHBvcnQpOworICAgIGludCBjb25uZWN0KGNvbnN0IEluZXRBZGRyZXNzKiBhZGRyLCBpbnQgcG9ydCk7CisKKworICAgIC8vIENsb3NlIHRoZSBzb2NrZXQuICBEb24ndCB0cnkgdG8gdXNlIHRoaXMgb2JqZWN0IGFnYWluIGFmdGVyCisgICAgLy8gY2FsbGluZyB0aGlzLiAgUmV0dXJucyBmYWxzZSBvbiBmYWlsdXJlLgorICAgIGJvb2wgY2xvc2Uodm9pZCk7CisKKyAgICAvLyBJZiB3ZSBjcmVhdGVkIHRoZSBzb2NrZXQgd2l0aG91dCBhbiBhZGRyZXNzLCB3ZSBjYW4gdXNlIHRoZXNlCisgICAgLy8gdG8gZmluaXNoIHRoZSBjb25uZWN0aW9uLiAgUmV0dXJucyAwIG9uIHN1Y2Nlc3MuCisgICAgaW50IGJpbmQoY29uc3QgU29ja2V0QWRkcmVzcyYgYmluZFBvaW50KTsKKyAgICBpbnQgY29ubmVjdChjb25zdCBTb2NrZXRBZGRyZXNzJiBlbmRQb2ludCk7CisKKyAgICAvLyBIZXJlIHdlIGRldmlhdGUgZnJvbSB0aGUgdHJhZGl0aW9uYWwgb2JqZWN0LW9yaWVudGVkIGZhbmNpbmVzcworICAgIC8vIGFuZCBqdXN0IHByb3ZpZGUgcmVhZC93cml0ZSBvcGVyYXRvcnMgaW5zdGVhZCBvZiBnZXR0ZXJzIGZvcgorICAgIC8vIG9iamVjdHMgdGhhdCBhYnN0cmFjdCBhIHN0cmVhbS4KKyAgICAvLworICAgIC8vIFN0YW5kYXJkIHJlYWQvd3JpdGUgc2VtYW50aWNzLgorICAgIGludCByZWFkKHZvaWQqIGJ1Ziwgc3NpemVfdCBsZW4pIGNvbnN0OworICAgIGludCB3cml0ZShjb25zdCB2b2lkKiBidWYsIHNzaXplX3QgbGVuKSBjb25zdDsKKworICAgIC8vIFRoaXMgbXVzdCBiZSBjYWxsZWQgb25jZSwgYXQgcHJvZ3JhbSBzdGFydHVwLgorICAgIHN0YXRpYyBib29sIGJvb3RJbml0KHZvaWQpOworICAgIHN0YXRpYyB2b2lkIGZpbmFsU2h1dGRvd24odm9pZCk7CisKK3ByaXZhdGU6CisgICAgLy8gSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBlc3RhYmxpc2hlcyBhIGNvbm5lY3Rpb24uCisgICAgaW50IGRvQ29ubmVjdChjb25zdCBJbmV0U29ja2V0QWRkcmVzcyYgYWRkcik7CisKKyAgICB1bnNpZ25lZCBsb25nICAgbVNvY2s7ICAgICAgLy8gaG9sZHMgU09DS0VUIG9yIGludAorCisgICAgc3RhdGljIGJvb2wgICAgIG1Cb290SW5pdGlhbGl6ZWQ7Cit9OworCisKKy8vIGRlYnVnIC0tIHVuaXQgdGVzdHMKK3ZvaWQgVGVzdFNvY2tldHModm9pZCk7CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBfUlVOVElNRV9TT0NLRVRfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9Tb3J0ZWRWZWN0b3IuaCBiL2luY2x1ZGUvdXRpbHMvU29ydGVkVmVjdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzhhNjE1MwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvU29ydGVkVmVjdG9yLmgKQEAgLTAsMCArMSwyODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfU09SVEVEX1ZFQ1RPUl9ICisjZGVmaW5lIEFORFJPSURfU09SVEVEX1ZFQ1RPUl9ICisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3RvckltcGwuaD4KKyNpbmNsdWRlIDx1dGlscy9UeXBlSGVscGVycy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCit0ZW1wbGF0ZSA8Y2xhc3MgVFlQRT4KK2NsYXNzIFNvcnRlZFZlY3RvciA6IHByaXZhdGUgU29ydGVkVmVjdG9ySW1wbAoreworcHVibGljOgorICAgICAgICAgICAgdHlwZWRlZiBUWVBFICAgIHZhbHVlX3R5cGU7CisgICAgCisgICAgLyohIAorICAgICAqIENvbnN0cnVjdG9ycyBhbmQgZGVzdHJ1Y3RvcnMKKyAgICAgKi8KKyAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3J0ZWRWZWN0b3IoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3J0ZWRWZWN0b3IoY29uc3QgU29ydGVkVmVjdG9yPFRZUEU+JiByaHMpOworICAgIHZpcnR1YWwgICAgICAgICAgICAgICAgIH5Tb3J0ZWRWZWN0b3IoKTsKKworICAgIC8qISBjb3B5IG9wZXJhdG9yICovCisgICAgY29uc3QgU29ydGVkVmVjdG9yPFRZUEU+JiAgIG9wZXJhdG9yID0gKGNvbnN0IFNvcnRlZFZlY3RvcjxUWVBFPiYgcmhzKSBjb25zdDsgICAgCisgICAgU29ydGVkVmVjdG9yPFRZUEU+JiAgICAgICAgIG9wZXJhdG9yID0gKGNvbnN0IFNvcnRlZFZlY3RvcjxUWVBFPiYgcmhzKTsgICAgCisKKyAgICAvKgorICAgICAqIGVtcHR5IHRoZSB2ZWN0b3IKKyAgICAgKi8KKworICAgIGlubGluZSAgdm9pZCAgICAgICAgICAgIGNsZWFyKCkgICAgICAgICAgICAgeyBWZWN0b3JJbXBsOjpjbGVhcigpOyB9CisKKyAgICAvKiEgCisgICAgICogdmVjdG9yIHN0YXRzCisgICAgICovCisKKyAgICAvLyEgcmV0dXJucyBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHZlY3RvcgorICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgIHNpemUoKSBjb25zdCAgICAgICAgICAgICAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpzaXplKCk7IH0KKyAgICAvLyEgcmV0dXJucyB3ZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3IgaXMgZW1wdHkKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICBpc0VtcHR5KCkgY29uc3QgICAgICAgICAgICAgeyByZXR1cm4gVmVjdG9ySW1wbDo6aXNFbXB0eSgpOyB9CisgICAgLy8hIHJldHVybnMgaG93IG1hbnkgaXRlbXMgY2FuIGJlIHN0b3JlZCB3aXRob3V0IHJlYWxsb2NhdGluZyB0aGUgYmFja2luZyBzdG9yZQorICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgIGNhcGFjaXR5KCkgY29uc3QgICAgICAgICAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpjYXBhY2l0eSgpOyB9CisgICAgLy8hIHNldHN0IHRoZSBjYXBhY2l0eS4gY2FwYWNpdHkgY2FuIG5ldmVyIGJlIHJlZHVjZWQgbGVzcyB0aGFuIHNpemUoKQorICAgIGlubGluZSAgc3NpemVfdCAgICAgICAgIHNldENhcGFjaXR5KHNpemVfdCBzaXplKSAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpzZXRDYXBhY2l0eShzaXplKTsgfQorCisgICAgLyohIAorICAgICAqIEMtc3R5bGUgYXJyYXkgYWNjZXNzCisgICAgICovCisgICAgIAorICAgIC8vISByZWFkLW9ubHkgQy1zdHlsZSBhY2Nlc3MgCisgICAgaW5saW5lICBjb25zdCBUWVBFKiAgICAgYXJyYXkoKSBjb25zdDsKKworICAgIC8vISByZWFkLXdyaXRlIEMtc3R5bGUgYWNjZXNzLiBCRSBWRVJZIENBUkVGVUwgd2hlbiBtb2RpZnlpbmcgdGhlIGFycmF5CisgICAgLy8hIHlvdSB1c3Qga2VlcCBpdCBzb3J0ZWQhIFlvdSB1c3VhbGx5IGRvbid0IHVzZSB0aGlzIGZ1bmN0aW9uLgorICAgICAgICAgICAgVFlQRSogICAgICAgICAgIGVkaXRBcnJheSgpOworCisgICAgICAgICAgICAvLyEgZmluZHMgdGhlIGluZGV4IG9mIGFuIGl0ZW0KKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBpbmRleE9mKGNvbnN0IFRZUEUmIGl0ZW0pIGNvbnN0OworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyEgZmluZHMgd2hlcmUgdGhpcyBpdGVtIHNob3VsZCBiZSBpbnNlcnRlZAorICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIG9yZGVyT2YoY29uc3QgVFlQRSYgaXRlbSkgY29uc3Q7CisgICAgICAgICAgICAKKyAgICAKKyAgICAvKiEgCisgICAgICogYWNjZXNzb3JzCisgICAgICovCisKKyAgICAvLyEgcmVhZC1vbmx5IGFjY2VzcyB0byBhbiBpdGVtIGF0IGEgZ2l2ZW4gaW5kZXgKKyAgICBpbmxpbmUgIGNvbnN0IFRZUEUmICAgICBvcGVyYXRvciBbXSAoc2l6ZV90IGluZGV4KSBjb25zdDsKKyAgICAvLyEgYWx0ZXJuYXRlIG5hbWUgZm9yIG9wZXJhdG9yIFtdCisgICAgaW5saW5lICBjb25zdCBUWVBFJiAgICAgaXRlbUF0KHNpemVfdCBpbmRleCkgY29uc3Q7CisgICAgLy8hIHN0YWNrLXVzYWdlIG9mIHRoZSB2ZWN0b3IuIHJldHVybnMgdGhlIHRvcCBvZiB0aGUgc3RhY2sgKGxhc3QgZWxlbWVudCkKKyAgICAgICAgICAgIGNvbnN0IFRZUEUmICAgICB0b3AoKSBjb25zdDsKKyAgICAvLyEgc2FtZSBhcyBvcGVyYXRvciBbXSwgYnV0IGFsbG93cyB0byBhY2Nlc3MgdGhlIHZlY3RvciBiYWNrd2FyZCAoZnJvbSB0aGUgZW5kKSB3aXRoIGEgbmVnYXRpdmUgaW5kZXgKKyAgICAgICAgICAgIGNvbnN0IFRZUEUmICAgICBtaXJyb3JJdGVtQXQoc3NpemVfdCBpbmRleCkgY29uc3Q7CisKKyAgICAvKiEKKyAgICAgKiBtb2RpZmluZyB0aGUgYXJyYXkKKyAgICAgKi8KKworICAgICAgICAgICAgLy8hIGFkZCBhbiBpdGVtIGluIHRoZSByaWdodCBwbGFjZSAoYW5kIHJlcGxhY2UgdGhlIG9uZSB0aGF0IGlzIHRoZXJlKQorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZChjb25zdCBUWVBFJiBpdGVtKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8hIGVkaXRJdGVtQXQoKSBNVVNUIE5PVCBjaGFuZ2UgdGhlIG9yZGVyIG9mIHRoaXMgaXRlbQorICAgICAgICAgICAgVFlQRSYgICAgICAgICAgIGVkaXRJdGVtQXQoc2l6ZV90IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICooIHN0YXRpY19jYXN0PFRZUEUgKj4oVmVjdG9ySW1wbDo6ZWRpdEl0ZW1Mb2NhdGlvbihpbmRleCkpICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vISBtZXJnZXMgYSB2ZWN0b3IgaW50byB0aGlzIG9uZQorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIG1lcmdlKGNvbnN0IFZlY3RvcjxUWVBFPiYgdmVjdG9yKTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBtZXJnZShjb25zdCBTb3J0ZWRWZWN0b3I8VFlQRT4mIHZlY3Rvcik7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vISByZW1vdmVzIGFuIGl0ZW0KKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZW1vdmUoY29uc3QgVFlQRSYpOworCisgICAgLy8hIHJlbW92ZSBzZXZlcmFsIGl0ZW1zCisgICAgaW5saW5lICBzc2l6ZV90ICAgICAgICAgcmVtb3ZlSXRlbXNBdChzaXplX3QgaW5kZXgsIHNpemVfdCBjb3VudCA9IDEpOworICAgIC8vISByZW1vdmUgb25lIGl0ZW0KKyAgICBpbmxpbmUgIHNzaXplX3QgICAgICAgICByZW1vdmVBdChzaXplX3QgaW5kZXgpICB7IHJldHVybiByZW1vdmVJdGVtc0F0KGluZGV4KTsgfQorICAgICAgICAgICAgCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCB2b2lkICAgIGRvX2NvbnN0cnVjdCh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fZGVzdHJveSh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fY29weSh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fc3BsYXQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogaXRlbSwgc2l6ZV90IG51bSkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkICAgIGRvX21vdmVfZm9yd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fbW92ZV9iYWNrd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIGludCAgICAgZG9fY29tcGFyZShjb25zdCB2b2lkKiBsaHMsIGNvbnN0IHZvaWQqIHJocykgY29uc3Q7Cit9OworCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTm8gdXNlciBzZXJ2aWNlYWJsZSBwYXJ0cyBmcm9tIGhlcmUuLi4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK1NvcnRlZFZlY3RvcjxUWVBFPjo6U29ydGVkVmVjdG9yKCkKKyAgICA6IFNvcnRlZFZlY3RvckltcGwoc2l6ZW9mKFRZUEUpLAorICAgICAgICAgICAgICAgICgodHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9jdG9yICAgPyBIQVNfVFJJVklBTF9DVE9SICAgOiAwKQorICAgICAgICAgICAgICAgIHwodHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9kdG9yICAgPyBIQVNfVFJJVklBTF9EVE9SICAgOiAwKQorICAgICAgICAgICAgICAgIHwodHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9jb3B5ICAgPyBIQVNfVFJJVklBTF9DT1BZICAgOiAwKQorICAgICAgICAgICAgICAgIHwodHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9hc3NpZ24gPyBIQVNfVFJJVklBTF9BU1NJR04gOiAwKSkKKyAgICAgICAgICAgICAgICApCit7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorU29ydGVkVmVjdG9yPFRZUEU+OjpTb3J0ZWRWZWN0b3IoY29uc3QgU29ydGVkVmVjdG9yPFRZUEU+JiByaHMpCisgICAgOiBTb3J0ZWRWZWN0b3JJbXBsKHJocykgeworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK1NvcnRlZFZlY3RvcjxUWVBFPjo6flNvcnRlZFZlY3RvcigpIHsKKyAgICBmaW5pc2hfdmVjdG9yKCk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorU29ydGVkVmVjdG9yPFRZUEU+JiBTb3J0ZWRWZWN0b3I8VFlQRT46Om9wZXJhdG9yID0gKGNvbnN0IFNvcnRlZFZlY3RvcjxUWVBFPiYgcmhzKSB7CisgICAgU29ydGVkVmVjdG9ySW1wbDo6b3BlcmF0b3IgPSAocmhzKTsKKyAgICByZXR1cm4gKnRoaXM7IAorfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK2NvbnN0IFNvcnRlZFZlY3RvcjxUWVBFPiYgU29ydGVkVmVjdG9yPFRZUEU+OjpvcGVyYXRvciA9IChjb25zdCBTb3J0ZWRWZWN0b3I8VFlQRT4mIHJocykgY29uc3QgeworICAgIFNvcnRlZFZlY3RvckltcGw6Om9wZXJhdG9yID0gKHJocyk7CisgICAgcmV0dXJuICp0aGlzOyAKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitjb25zdCBUWVBFKiBTb3J0ZWRWZWN0b3I8VFlQRT46OmFycmF5KCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBUWVBFICo+KGFycmF5SW1wbCgpKTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitUWVBFKiBTb3J0ZWRWZWN0b3I8VFlQRT46OmVkaXRBcnJheSgpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VFlQRSAqPihlZGl0QXJyYXlJbXBsKCkpOworfQorCisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorY29uc3QgVFlQRSYgU29ydGVkVmVjdG9yPFRZUEU+OjpvcGVyYXRvcltdKHNpemVfdCBpbmRleCkgY29uc3QgeworICAgIGFzc2VydCggaW5kZXg8c2l6ZSgpICk7CisgICAgcmV0dXJuICooYXJyYXkoKSArIGluZGV4KTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitjb25zdCBUWVBFJiBTb3J0ZWRWZWN0b3I8VFlQRT46Oml0ZW1BdChzaXplX3QgaW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gb3BlcmF0b3JbXShpbmRleCk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorY29uc3QgVFlQRSYgU29ydGVkVmVjdG9yPFRZUEU+OjptaXJyb3JJdGVtQXQoc3NpemVfdCBpbmRleCkgY29uc3QgeworICAgIGFzc2VydCggKGluZGV4PjAgPyBpbmRleCA6IC1pbmRleCk8c2l6ZSgpICk7CisgICAgcmV0dXJuICooYXJyYXkoKSArICgoaW5kZXg8MCkgPyAoc2l6ZSgpLWluZGV4KSA6IGluZGV4KSk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorY29uc3QgVFlQRSYgU29ydGVkVmVjdG9yPFRZUEU+Ojp0b3AoKSBjb25zdCB7CisgICAgcmV0dXJuICooYXJyYXkoKSArIHNpemUoKSAtIDEpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgU29ydGVkVmVjdG9yPFRZUEU+OjphZGQoY29uc3QgVFlQRSYgaXRlbSkgeworICAgIHJldHVybiBTb3J0ZWRWZWN0b3JJbXBsOjphZGQoJml0ZW0pOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgU29ydGVkVmVjdG9yPFRZUEU+OjppbmRleE9mKGNvbnN0IFRZUEUmIGl0ZW0pIGNvbnN0IHsKKyAgICByZXR1cm4gU29ydGVkVmVjdG9ySW1wbDo6aW5kZXhPZigmaXRlbSk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorc2l6ZV90IFNvcnRlZFZlY3RvcjxUWVBFPjo6b3JkZXJPZihjb25zdCBUWVBFJiBpdGVtKSBjb25zdCB7CisgICAgcmV0dXJuIFNvcnRlZFZlY3RvckltcGw6Om9yZGVyT2YoJml0ZW0pOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgU29ydGVkVmVjdG9yPFRZUEU+OjptZXJnZShjb25zdCBWZWN0b3I8VFlQRT4mIHZlY3RvcikgeworICAgIHJldHVybiBTb3J0ZWRWZWN0b3JJbXBsOjptZXJnZShyZWludGVycHJldF9jYXN0PGNvbnN0IFZlY3RvckltcGwmPih2ZWN0b3IpKTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitzc2l6ZV90IFNvcnRlZFZlY3RvcjxUWVBFPjo6bWVyZ2UoY29uc3QgU29ydGVkVmVjdG9yPFRZUEU+JiB2ZWN0b3IpIHsKKyAgICByZXR1cm4gU29ydGVkVmVjdG9ySW1wbDo6bWVyZ2UocmVpbnRlcnByZXRfY2FzdDxjb25zdCBTb3J0ZWRWZWN0b3JJbXBsJj4odmVjdG9yKSk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorc3NpemVfdCBTb3J0ZWRWZWN0b3I8VFlQRT46OnJlbW92ZShjb25zdCBUWVBFJiBpdGVtKSB7CisgICAgcmV0dXJuIFNvcnRlZFZlY3RvckltcGw6OnJlbW92ZSgmaXRlbSk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorc3NpemVfdCBTb3J0ZWRWZWN0b3I8VFlQRT46OnJlbW92ZUl0ZW1zQXQoc2l6ZV90IGluZGV4LCBzaXplX3QgY291bnQpIHsKKyAgICByZXR1cm4gVmVjdG9ySW1wbDo6cmVtb3ZlSXRlbXNBdChpbmRleCwgY291bnQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4KK3ZvaWQgU29ydGVkVmVjdG9yPFRZUEU+Ojpkb19jb25zdHJ1Y3Qodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QgeworICAgIGNvbnN0cnVjdF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihzdG9yYWdlKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFNvcnRlZFZlY3RvcjxUWVBFPjo6ZG9fZGVzdHJveSh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgZGVzdHJveV90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihzdG9yYWdlKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFNvcnRlZFZlY3RvcjxUWVBFPjo6ZG9fY29weSh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgY29weV90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oZnJvbSksIG51bSApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPgordm9pZCBTb3J0ZWRWZWN0b3I8VFlQRT46OmRvX3NwbGF0KHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCBudW0pIGNvbnN0IHsKKyAgICBzcGxhdF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oaXRlbSksIG51bSApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPgordm9pZCBTb3J0ZWRWZWN0b3I8VFlQRT46OmRvX21vdmVfZm9yd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgbW92ZV9mb3J3YXJkX3R5cGUoIHJlaW50ZXJwcmV0X2Nhc3Q8VFlQRSo+KGRlc3QpLCByZWludGVycHJldF9jYXN0PGNvbnN0IFRZUEUqPihmcm9tKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFNvcnRlZFZlY3RvcjxUWVBFPjo6ZG9fbW92ZV9iYWNrd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgbW92ZV9iYWNrd2FyZF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oZnJvbSksIG51bSApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPgoraW50IFNvcnRlZFZlY3RvcjxUWVBFPjo6ZG9fY29tcGFyZShjb25zdCB2b2lkKiBsaHMsIGNvbnN0IHZvaWQqIHJocykgY29uc3QgeworICAgIHJldHVybiBjb21wYXJlX3R5cGUoICpyZWludGVycHJldF9jYXN0PGNvbnN0IFRZUEUqPihsaHMpLCAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4ocmhzKSApOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9TT1JURURfVkVDVE9SX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvU3RvcFdhdGNoLmggYi9pbmNsdWRlL3V0aWxzL1N0b3BXYXRjaC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjMGJlYmMKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1N0b3BXYXRjaC5oCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfU1RPUFdBVENIX0gKKyNkZWZpbmUgQU5EUk9JRF9TVE9QV0FUQ0hfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9UaW1lcnMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgU3RvcFdhdGNoCit7CitwdWJsaWM6CisgICAgICAgIFN0b3BXYXRjaCggIGNvbnN0IGNoYXIgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgIGludCBjbG9jayA9IFNZU1RFTV9USU1FX01PTk9UT05JQywKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSAwKTsKKyAgICAgICAgflN0b3BXYXRjaCgpOworICAgICAgICAKKyAgICAgICAgY29uc3QgY2hhciogbmFtZSgpIGNvbnN0OworICAgICAgICBuc2Vjc190ICAgICBsYXAoKTsKKyAgICAgICAgbnNlY3NfdCAgICAgZWxhcHNlZFRpbWUoKSBjb25zdDsKKyAgICAgICAgCitwcml2YXRlOgorICAgIGNvbnN0IGNoYXIqICAgICBtTmFtZTsKKyAgICBpbnQgICAgICAgICAgICAgbUNsb2NrOworICAgIHVpbnQzMl90ICAgICAgICBtRmxhZ3M7CisgICAgCisgICAgc3RydWN0IGxhcF90IHsKKyAgICAgICAgbnNlY3NfdCAgICAgc29GYXI7CisgICAgICAgIG5zZWNzX3QgICAgIHRoaXNMYXA7CisgICAgfTsKKyAgICAKKyAgICBuc2Vjc190ICAgICAgICAgbVN0YXJ0VGltZTsKKyAgICBsYXBfdCAgICAgICAgICAgbUxhcHNbOF07CisgICAgaW50ICAgICAgICAgICAgIG1OdW1MYXBzOworfTsKKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9TVE9QV0FUQ0hfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9TdHJpbmcxNi5oIGIvaW5jbHVkZS91dGlscy9TdHJpbmcxNi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyZDIyZWUKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1N0cmluZzE2LmgKQEAgLTAsMCArMSwyNjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfU1RSSU5HMTZfSAorI2RlZmluZSBBTkRST0lEX1NUUklORzE2X0gKKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL1NoYXJlZEJ1ZmZlci5oPgorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitleHRlcm4gIkMiIHsKKwordHlwZWRlZiB1aW50MTZfdCBjaGFyMTZfdDsKKworLy8gU3RhbmRhcmQgc3RyaW5nIGZ1bmN0aW9ucyBvbiBjaGFyMTYgc3RyaW5ncy4KK2ludCBzdHJjbXAxNihjb25zdCBjaGFyMTZfdCAqLCBjb25zdCBjaGFyMTZfdCAqKTsKK2ludCBzdHJuY21wMTYoY29uc3QgY2hhcjE2X3QgKnMxLCBjb25zdCBjaGFyMTZfdCAqczIsIHNpemVfdCBuKTsKK3NpemVfdCBzdHJsZW4xNihjb25zdCBjaGFyMTZfdCAqKTsKK3NpemVfdCBzdHJubGVuMTYoY29uc3QgY2hhcjE2X3QgKiwgc2l6ZV90KTsKK2NoYXIxNl90ICpzdHJjcHkxNihjaGFyMTZfdCAqLCBjb25zdCBjaGFyMTZfdCAqKTsKK2NoYXIxNl90ICpzdHJuY3B5MTYoY2hhcjE2X3QgKiwgY29uc3QgY2hhcjE2X3QgKiwgc2l6ZV90KTsKKworLy8gVmVyc2lvbiBvZiBjb21wYXJpc29uIHRoYXQgc3VwcG9ydHMgZW1iZWRkZWQgbnVsbHMuCisvLyBUaGlzIGlzIGRpZmZlcmVudCB0aGFuIHN0cm5jbXAoKSBiZWNhdXNlIHdlIGRvbid0IHN0b3AKKy8vIGF0IGEgbnVsIGNoYXJhY3RlciBhbmQgY29uc2lkZXIgdGhlIHN0cmluZ3MgdG8gYmUgZGlmZmVyZW50CisvLyBpZiB0aGUgbGVuZ3RocyBhcmUgZGlmZmVyZW50ICh0aHVzIHdlIG5lZWQgdG8gc3VwcGx5IHRoZQorLy8gbGVuZ3RocyBvZiBib3RoIHN0cmluZ3MpLiAgVGhpcyBjYW4gYWxzbyBiZSB1c2VkIHdoZW4KKy8vIHlvdXIgc3RyaW5nIGlzIG5vdCBudWwtdGVybWluYXRlZCBhcyBpdCB3aWxsIGhhdmUgdGhlCisvLyBlcXVpdmFsZW50IHJlc3VsdCBhcyBzdHJjbXAxNiAodW5saWtlIHN0cm5jbXAxNikuCitpbnQgc3RyemNtcDE2KGNvbnN0IGNoYXIxNl90ICpzMSwgc2l6ZV90IG4xLCBjb25zdCBjaGFyMTZfdCAqczIsIHNpemVfdCBuMik7CisKKy8vIFZlcnNpb24gb2Ygc3RyemNtcDE2IGZvciBjb21wYXJpbmcgc3RyaW5ncyBpbiBkaWZmZXJlbnQgZW5kaWFubmVzcy4KK2ludCBzdHJ6Y21wMTZfaF9uKGNvbnN0IGNoYXIxNl90ICpzMUgsIHNpemVfdCBuMSwgY29uc3QgY2hhcjE2X3QgKnMyTiwgc2l6ZV90IG4yKTsKKworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBTdHJpbmc4OworY2xhc3MgVGV4dE91dHB1dDsKKworLy8hIFRoaXMgaXMgYSBzdHJpbmcgaG9sZGluZyBVVEYtMTYgY2hhcmFjdGVycy4KK2NsYXNzIFN0cmluZzE2Cit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzE2KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzE2KGNvbnN0IFN0cmluZzE2JiBvKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYoY29uc3QgU3RyaW5nMTYmIG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBiZWdpbj0wKTsKKyAgICBleHBsaWNpdCAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYoY29uc3QgY2hhcjE2X3QqIG8pOworICAgIGV4cGxpY2l0ICAgICAgICAgICAgICAgICAgICBTdHJpbmcxNihjb25zdCBjaGFyMTZfdCogbywgc2l6ZV90IGxlbik7CisgICAgZXhwbGljaXQgICAgICAgICAgICAgICAgICAgIFN0cmluZzE2KGNvbnN0IFN0cmluZzgmIG8pOworICAgIGV4cGxpY2l0ICAgICAgICAgICAgICAgICAgICBTdHJpbmcxNihjb25zdCBjaGFyKiBvKTsKKyAgICBleHBsaWNpdCAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYoY29uc3QgY2hhciogbywgc2l6ZV90IGxlbik7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflN0cmluZzE2KCk7CisgICAgCisgICAgaW5saW5lICBjb25zdCBjaGFyMTZfdCogICAgIHN0cmluZygpIGNvbnN0OworICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgICAgICBzaXplKCkgY29uc3Q7CisgICAgCisgICAgaW5saW5lICBjb25zdCBTaGFyZWRCdWZmZXIqIHNoYXJlZEJ1ZmZlcigpIGNvbnN0OworICAgIAorICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRUbyhjb25zdCBTdHJpbmcxNiYgb3RoZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBzZXRUbyhjb25zdCBjaGFyMTZfdCogb3RoZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBzZXRUbyhjb25zdCBjaGFyMTZfdCogb3RoZXIsIHNpemVfdCBsZW4pOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBzZXRUbyhjb25zdCBTdHJpbmcxNiYgb3RoZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBiZWdpbj0wKTsKKyAgICAKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgYXBwZW5kKGNvbnN0IFN0cmluZzE2JiBvdGhlcik7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIGFwcGVuZChjb25zdCBjaGFyMTZfdCogb3RoZXIsIHNpemVfdCBsZW4pOworICAgICAgICAgICAgCisgICAgaW5saW5lICBTdHJpbmcxNiYgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBTdHJpbmcxNiYgb3RoZXIpOworICAgIAorICAgIGlubGluZSAgU3RyaW5nMTYmICAgICAgICAgICBvcGVyYXRvcis9KGNvbnN0IFN0cmluZzE2JiBvdGhlcik7CisgICAgaW5saW5lICBTdHJpbmcxNiAgICAgICAgICAgIG9wZXJhdG9yKyhjb25zdCBTdHJpbmcxNiYgb3RoZXIpIGNvbnN0OworCisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIGluc2VydChzaXplX3QgcG9zLCBjb25zdCBjaGFyMTZfdCogY2hycyk7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIGluc2VydChzaXplX3QgcG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIGNocnMsIHNpemVfdCBsZW4pOworCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgICAgIGZpbmRGaXJzdChjaGFyMTZfdCBjKSBjb25zdDsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICAgICAgZmluZExhc3QoY2hhcjE2X3QgYykgY29uc3Q7CisKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgc3RhcnRzV2l0aChjb25zdCBTdHJpbmcxNiYgcHJlZml4KSBjb25zdDsKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgc3RhcnRzV2l0aChjb25zdCBjaGFyMTZfdCogcHJlZml4KSBjb25zdDsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBtYWtlTG93ZXIoKTsKKworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICByZXBsYWNlQWxsKGNoYXIxNl90IHJlcGxhY2VUaGlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIxNl90IHdpdGhUaGlzKTsKKworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICByZW1vdmUoc2l6ZV90IGxlbiwgc2l6ZV90IGJlZ2luPTApOworCisgICAgaW5saW5lICBpbnQgICAgICAgICAgICAgICAgIGNvbXBhcmUoY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdDsKKworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcjwoY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I8PShjb25zdCBTdHJpbmcxNiYgb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcj09KGNvbnN0IFN0cmluZzE2JiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yIT0oY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I+PShjb25zdCBTdHJpbmcxNiYgb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcj4oY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdDsKKyAgICAKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I8KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yPD0oY29uc3QgY2hhcjE2X3QqIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBjaGFyMTZfdCogb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvciE9KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yPj0oY29uc3QgY2hhcjE2X3QqIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I+KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3Q7CisgICAgCisgICAgaW5saW5lICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yIGNvbnN0IGNoYXIxNl90KigpIGNvbnN0OworICAgIAorcHJpdmF0ZToKKyAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiAgICAgbVN0cmluZzsKK307CisKK1RleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGNvbnN0IFN0cmluZzE2JiB2YWwpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vIHVzZXIgc2VydmljYWJsZSBwYXJ0cyBiZWxvdy4KKworaW5saW5lIGludCBjb21wYXJlX3R5cGUoY29uc3QgU3RyaW5nMTYmIGxocywgY29uc3QgU3RyaW5nMTYmIHJocykKK3sKKyAgICByZXR1cm4gbGhzLmNvbXBhcmUocmhzKTsKK30KKworaW5saW5lIGludCBzdHJpY3RseV9vcmRlcl90eXBlKGNvbnN0IFN0cmluZzE2JiBsaHMsIGNvbnN0IFN0cmluZzE2JiByaHMpCit7CisgICAgcmV0dXJuIGNvbXBhcmVfdHlwZShsaHMsIHJocykgPCAwOworfQorCitpbmxpbmUgY29uc3QgY2hhcjE2X3QqIFN0cmluZzE2OjpzdHJpbmcoKSBjb25zdAoreworICAgIHJldHVybiBtU3RyaW5nOworfQorCitpbmxpbmUgc2l6ZV90IFN0cmluZzE2OjpzaXplKCkgY29uc3QKK3sKKyAgICByZXR1cm4gU2hhcmVkQnVmZmVyOjpzaXplRnJvbURhdGEobVN0cmluZykvc2l6ZW9mKGNoYXIxNl90KS0xOworfQorCitpbmxpbmUgY29uc3QgU2hhcmVkQnVmZmVyKiBTdHJpbmcxNjo6c2hhcmVkQnVmZmVyKCkgY29uc3QKK3sKKyAgICByZXR1cm4gU2hhcmVkQnVmZmVyOjpidWZmZXJGcm9tRGF0YShtU3RyaW5nKTsKK30KKworaW5saW5lIFN0cmluZzE2JiBTdHJpbmcxNjo6b3BlcmF0b3I9KGNvbnN0IFN0cmluZzE2JiBvdGhlcikKK3sKKyAgICBzZXRUbyhvdGhlcik7CisgICAgcmV0dXJuICp0aGlzOworfQorCitpbmxpbmUgU3RyaW5nMTYmIFN0cmluZzE2OjpvcGVyYXRvcis9KGNvbnN0IFN0cmluZzE2JiBvdGhlcikKK3sKKyAgICBhcHBlbmQob3RoZXIpOworICAgIHJldHVybiAqdGhpczsKK30KKworaW5saW5lIFN0cmluZzE2IFN0cmluZzE2OjpvcGVyYXRvcisoY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdAoreworICAgIFN0cmluZzE2IHRtcDsKKyAgICB0bXAgKz0gb3RoZXI7CisgICAgcmV0dXJuIHRtcDsKK30KKworaW5saW5lIGludCBTdHJpbmcxNjo6Y29tcGFyZShjb25zdCBTdHJpbmcxNiYgb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cnpjbXAxNihtU3RyaW5nLCBzaXplKCksIG90aGVyLm1TdHJpbmcsIG90aGVyLnNpemUoKSk7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcjwoY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJ6Y21wMTYobVN0cmluZywgc2l6ZSgpLCBvdGhlci5tU3RyaW5nLCBvdGhlci5zaXplKCkpIDwgMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nMTY6Om9wZXJhdG9yPD0oY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJ6Y21wMTYobVN0cmluZywgc2l6ZSgpLCBvdGhlci5tU3RyaW5nLCBvdGhlci5zaXplKCkpIDw9IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcj09KGNvbnN0IFN0cmluZzE2JiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyemNtcDE2KG1TdHJpbmcsIHNpemUoKSwgb3RoZXIubVN0cmluZywgb3RoZXIuc2l6ZSgpKSA9PSAwOworfQorCitpbmxpbmUgYm9vbCBTdHJpbmcxNjo6b3BlcmF0b3IhPShjb25zdCBTdHJpbmcxNiYgb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cnpjbXAxNihtU3RyaW5nLCBzaXplKCksIG90aGVyLm1TdHJpbmcsIG90aGVyLnNpemUoKSkgIT0gMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nMTY6Om9wZXJhdG9yPj0oY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJ6Y21wMTYobVN0cmluZywgc2l6ZSgpLCBvdGhlci5tU3RyaW5nLCBvdGhlci5zaXplKCkpID49IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcj4oY29uc3QgU3RyaW5nMTYmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJ6Y21wMTYobVN0cmluZywgc2l6ZSgpLCBvdGhlci5tU3RyaW5nLCBvdGhlci5zaXplKCkpID4gMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nMTY6Om9wZXJhdG9yPChjb25zdCBjaGFyMTZfdCogb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cmNtcDE2KG1TdHJpbmcsIG90aGVyKSA8IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcjw9KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wMTYobVN0cmluZywgb3RoZXIpIDw9IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcj09KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wMTYobVN0cmluZywgb3RoZXIpID09IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvciE9KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wMTYobVN0cmluZywgb3RoZXIpICE9IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcj49KGNvbnN0IGNoYXIxNl90KiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wMTYobVN0cmluZywgb3RoZXIpID49IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzE2OjpvcGVyYXRvcj4oY29uc3QgY2hhcjE2X3QqIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJjbXAxNihtU3RyaW5nLCBvdGhlcikgPiAwOworfQorCitpbmxpbmUgU3RyaW5nMTY6Om9wZXJhdG9yIGNvbnN0IGNoYXIxNl90KigpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1TdHJpbmc7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9TVFJJTkcxNl9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1N0cmluZzguaCBiL2luY2x1ZGUvdXRpbHMvU3RyaW5nOC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0OWZhZjYKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1N0cmluZzguaApAQCAtMCwwICsxLDM1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9TVFJJTkc4X0gKKyNkZWZpbmUgQU5EUk9JRF9TVFJJTkc4X0gKKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorCisvLyBOZWVkIHRoaXMgZm9yIHRoZSBjaGFyMTZfdCB0eXBlOyBTdHJpbmc4Lmggc2hvdWxkIG5vdAorLy8gYmUgZGVwZWRlbnQgb24gdGhlIFN0cmluZzE2IGNsYXNzLgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzE2Lmg+CisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgVGV4dE91dHB1dDsKKworLy8hIFRoaXMgaXMgYSBzdHJpbmcgaG9sZGluZyBVVEYtOCBjaGFyYWN0ZXJzLgorY2xhc3MgU3RyaW5nOAoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgoY29uc3QgU3RyaW5nOCYgbyk7CisgICAgZXhwbGljaXQgICAgICAgICAgICAgICAgICAgIFN0cmluZzgoY29uc3QgY2hhciogbyk7CisgICAgZXhwbGljaXQgICAgICAgICAgICAgICAgICAgIFN0cmluZzgoY29uc3QgY2hhciogbywgc2l6ZV90IG51bUNoYXJzKTsKKyAgICAKKyAgICBleHBsaWNpdCAgICAgICAgICAgICAgICAgICAgU3RyaW5nOChjb25zdCBTdHJpbmcxNiYgbyk7CisgICAgZXhwbGljaXQgICAgICAgICAgICAgICAgICAgIFN0cmluZzgoY29uc3QgY2hhcjE2X3QqIG8pOworICAgIGV4cGxpY2l0ICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KGNvbnN0IGNoYXIxNl90KiBvLCBzaXplX3QgbnVtQ2hhcnMpOworICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+U3RyaW5nOCgpOworICAgIAorICAgIGlubGluZSAgY29uc3QgY2hhciogICAgICAgICBzdHJpbmcoKSBjb25zdDsKKyAgICBpbmxpbmUgIHNpemVfdCAgICAgICAgICAgICAgc2l6ZSgpIGNvbnN0OworICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgICAgICBsZW5ndGgoKSBjb25zdDsKKyAgICBpbmxpbmUgIHNpemVfdCAgICAgICAgICAgICAgYnl0ZXMoKSBjb25zdDsKKyAgICAKKyAgICBpbmxpbmUgIGNvbnN0IFNoYXJlZEJ1ZmZlciogc2hhcmVkQnVmZmVyKCkgY29uc3Q7CisgICAgCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHNldFRvKGNvbnN0IFN0cmluZzgmIG90aGVyKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgc2V0VG8oY29uc3QgY2hhciogb3RoZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBzZXRUbyhjb25zdCBjaGFyKiBvdGhlciwgc2l6ZV90IG51bUNoYXJzKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgc2V0VG8oY29uc3QgY2hhcjE2X3QqIG90aGVyLCBzaXplX3QgbnVtQ2hhcnMpOworICAgIAorICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBhcHBlbmQoY29uc3QgU3RyaW5nOCYgb3RoZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBhcHBlbmQoY29uc3QgY2hhciogb3RoZXIpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICBhcHBlbmQoY29uc3QgY2hhciogb3RoZXIsIHNpemVfdCBudW1DaGFycyk7CisKKyAgICBpbmxpbmUgIFN0cmluZzgmICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IFN0cmluZzgmIG90aGVyKTsKKyAgICBpbmxpbmUgIFN0cmluZzgmICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IGNoYXIqIG90aGVyKTsKKyAgICAKKyAgICBpbmxpbmUgIFN0cmluZzgmICAgICAgICAgICAgb3BlcmF0b3IrPShjb25zdCBTdHJpbmc4JiBvdGhlcik7CisgICAgaW5saW5lICBTdHJpbmc4ICAgICAgICAgICAgIG9wZXJhdG9yKyhjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3Q7CisgICAgCisgICAgaW5saW5lICBTdHJpbmc4JiAgICAgICAgICAgIG9wZXJhdG9yKz0oY29uc3QgY2hhciogb3RoZXIpOworICAgIGlubGluZSAgU3RyaW5nOCAgICAgICAgICAgICBvcGVyYXRvcisoY29uc3QgY2hhciogb3RoZXIpIGNvbnN0OworCisgICAgaW5saW5lICBpbnQgICAgICAgICAgICAgICAgIGNvbXBhcmUoY29uc3QgU3RyaW5nOCYgb3RoZXIpIGNvbnN0OworCisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yPChjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yPD0oY29uc3QgU3RyaW5nOCYgb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcj09KGNvbnN0IFN0cmluZzgmIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yPj0oY29uc3QgU3RyaW5nOCYgb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcj4oY29uc3QgU3RyaW5nOCYgb3RoZXIpIGNvbnN0OworICAgIAorICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcjwoY29uc3QgY2hhciogb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcjw9KGNvbnN0IGNoYXIqIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBjaGFyKiBvdGhlcikgY29uc3Q7CisgICAgaW5saW5lICBib29sICAgICAgICAgICAgICAgIG9wZXJhdG9yIT0oY29uc3QgY2hhciogb3RoZXIpIGNvbnN0OworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICBvcGVyYXRvcj49KGNvbnN0IGNoYXIqIG90aGVyKSBjb25zdDsKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICAgICAgb3BlcmF0b3I+KGNvbnN0IGNoYXIqIG90aGVyKSBjb25zdDsKKyAgICAKKyAgICBpbmxpbmUgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IgY29uc3QgY2hhciooKSBjb25zdDsKKyAgICAKKyAgICAgICAgICAgIGNoYXIqICAgICAgICAgICAgICAgbG9ja0J1ZmZlcihzaXplX3Qgc2l6ZSk7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHVubG9ja0J1ZmZlcigpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICB1bmxvY2tCdWZmZXIoc2l6ZV90IHNpemUpOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIG9mIG90aGVyIGluIHRoaXMgYXQgb3IgYWZ0ZXIKKyAgICAgICAgICAgIC8vIHN0YXJ0LCBvciAtMSBpZiBub3QgZm91bmQKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICAgICAgZmluZChjb25zdCBjaGFyKiBvdGhlciwgc2l6ZV90IHN0YXJ0ID0gMCkgY29uc3Q7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgdG9Mb3dlcigpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICB0b0xvd2VyKHNpemVfdCBzdGFydCwgc2l6ZV90IG51bUNoYXJzKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgdG9VcHBlcigpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICB0b1VwcGVyKHNpemVfdCBzdGFydCwgc2l6ZV90IG51bUNoYXJzKTsKKyAgICAgICAgICAgIAorICAgIC8qCisgICAgICogVGhlc2UgbWV0aG9kcyBvcGVyYXRlIG9uIHRoZSBzdHJpbmcgYXMgaWYgaXQgd2VyZSBhIHBhdGggbmFtZS4KKyAgICAgKi8KKworICAgIC8qCisgICAgICogU2V0IHRoZSBmaWxlbmFtZSBmaWVsZCB0byBhIHNwZWNpZmljIHZhbHVlLgorICAgICAqCisgICAgICogTm9ybWFsaXplcyB0aGUgZmlsZW5hbWUsIHJlbW92aW5nIGEgdHJhaWxpbmcgJy8nIGlmIHByZXNlbnQuCisgICAgICovCisgICAgdm9pZCBzZXRQYXRoTmFtZShjb25zdCBjaGFyKiBuYW1lKTsKKyAgICB2b2lkIHNldFBhdGhOYW1lKGNvbnN0IGNoYXIqIG5hbWUsIHNpemVfdCBudW1DaGFycyk7CisKKyAgICAvKgorICAgICAqIEdldCBqdXN0IHRoZSBmaWxlbmFtZSBjb21wb25lbnQuCisgICAgICoKKyAgICAgKiAiL3RtcC9mb28vYmFyLmMiIC0tPiAiYmFyLmMiCisgICAgICovCisgICAgU3RyaW5nOCBnZXRQYXRoTGVhZih2b2lkKSBjb25zdDsKKworICAgIC8qCisgICAgICogUmVtb3ZlIHRoZSBsYXN0IChmaWxlIG5hbWUpIGNvbXBvbmVudCwgbGVhdmluZyBqdXN0IHRoZSBkaXJlY3RvcnkKKyAgICAgKiBuYW1lLgorICAgICAqCisgICAgICogIi90bXAvZm9vL2Jhci5jIiAtLT4gIi90bXAvZm9vIgorICAgICAqICIvdG1wIiAtLT4gIiIgLy8gPz8/Pz8gc2hvdWxkbid0IHRoaXMgYmUgIi8iID8/Pz8gWFhYCisgICAgICogImJhci5jIiAtLT4gIiIKKyAgICAgKi8KKyAgICBTdHJpbmc4IGdldFBhdGhEaXIodm9pZCkgY29uc3Q7CisKKyAgICAvKgorICAgICAqIFJldHJpZXZlIHRoZSBmcm9udCAocm9vdCBkaXIpIGNvbXBvbmVudC4gIE9wdGlvbmFsbHkgYWxzbyByZXR1cm4gdGhlCisgICAgICogcmVtYWluaW5nIGNvbXBvbmVudHMuCisgICAgICoKKyAgICAgKiAiL3RtcC9mb28vYmFyLmMiIC0tPiAidG1wIiAocmVtYWluID0gImZvby9iYXIuYyIpCisgICAgICogIi90bXAiIC0tPiAidG1wIiAocmVtYWluID0gIiIpCisgICAgICogImJhci5jIiAtLT4gImJhci5jIiAocmVtYWluID0gIiIpCisgICAgICovCisgICAgU3RyaW5nOCB3YWxrUGF0aChTdHJpbmc4KiBvdXRSZW1haW5zID0gTlVMTCkgY29uc3Q7CisKKyAgICAvKgorICAgICAqIFJldHVybiB0aGUgZmlsZW5hbWUgZXh0ZW5zaW9uLiAgVGhpcyBpcyB0aGUgbGFzdCAnLicgYW5kIHVwIHRvCisgICAgICogZm91ciBjaGFyYWN0ZXJzIHRoYXQgZm9sbG93IGl0LiAgVGhlICcuJyBpcyBpbmNsdWRlZCBpbiBjYXNlIHdlCisgICAgICogZGVjaWRlIHRvIGV4cGFuZCBvdXIgZGVmaW5pdGlvbiBvZiB3aGF0IGNvbnN0aXR1dGVzIGFuIGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqICIvdG1wL2Zvby9iYXIuYyIgLS0+ICIuYyIKKyAgICAgKiAiL3RtcCIgLS0+ICIiCisgICAgICogIi90bXAvZm9vLmJhci9iYXoiIC0tPiAiIgorICAgICAqICJmb28uanBlZyIgLS0+ICIuanBlZyIKKyAgICAgKiAiZm9vLiIgLS0+ICIiCisgICAgICovCisgICAgU3RyaW5nOCBnZXRQYXRoRXh0ZW5zaW9uKHZvaWQpIGNvbnN0OworCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIHBhdGggd2l0aG91dCB0aGUgZXh0ZW5zaW9uLiAgUnVsZXMgZm9yIHdoYXQgY29uc3RpdHV0ZXMKKyAgICAgKiBhbiBleHRlbnNpb24gYXJlIGRlc2NyaWJlZCBpbiB0aGUgY29tbWVudCBmb3IgZ2V0UGF0aEV4dGVuc2lvbigpLgorICAgICAqCisgICAgICogIi90bXAvZm9vL2Jhci5jIiAtLT4gIi90bXAvZm9vL2JhciIKKyAgICAgKi8KKyAgICBTdHJpbmc4IGdldEJhc2VQYXRoKHZvaWQpIGNvbnN0OworCisgICAgLyoKKyAgICAgKiBBZGQgYSBjb21wb25lbnQgdG8gdGhlIHBhdGhuYW1lLiAgV2UgZ3VhcmFudGVlIHRoYXQgdGhlcmUgaXMKKyAgICAgKiBleGFjdGx5IG9uZSBwYXRoIHNlcGFyYXRvciBiZXR3ZWVuIHRoZSBvbGQgcGF0aCBhbmQgdGhlIG5ldy4KKyAgICAgKiBJZiB0aGVyZSBpcyBubyBleGlzdGluZyBuYW1lLCB3ZSBqdXN0IGNvcHkgdGhlIG5ldyBuYW1lIGluLgorICAgICAqCisgICAgICogSWYgbGVhZiBpcyBhIGZ1bGx5IHF1YWxpZmllZCBwYXRoIChpLmUuIHN0YXJ0cyB3aXRoICcvJywgaXQKKyAgICAgKiByZXBsYWNlcyB3aGF0ZXZlciB3YXMgdGhlcmUgYmVmb3JlLgorICAgICAqLworICAgIFN0cmluZzgmIGFwcGVuZFBhdGgoY29uc3QgY2hhciogbGVhZik7CisgICAgU3RyaW5nOCYgYXBwZW5kUGF0aChjb25zdCBTdHJpbmc4JiBsZWFmKSAgeyByZXR1cm4gYXBwZW5kUGF0aChsZWFmLnN0cmluZygpKTsgfQorCisgICAgLyoKKyAgICAgKiBMaWtlIGFwcGVuZFBhdGgoKSwgYnV0IGRvZXMgbm90IGFmZmVjdCB0aGlzIHN0cmluZy4gIFJldHVybnMgYSBuZXcgb25lIGluc3RlYWQuCisgICAgICovCisgICAgU3RyaW5nOCBhcHBlbmRQYXRoQ29weShjb25zdCBjaGFyKiBsZWFmKSBjb25zdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBTdHJpbmc4IHAoKnRoaXMpOyBwLmFwcGVuZFBhdGgobGVhZik7IHJldHVybiBwOyB9CisgICAgU3RyaW5nOCBhcHBlbmRQYXRoQ29weShjb25zdCBTdHJpbmc4JiBsZWFmKSBjb25zdCB7IHJldHVybiBhcHBlbmRQYXRoQ29weShsZWFmLnN0cmluZygpKTsgfQorCisgICAgLyoKKyAgICAgKiBDb252ZXJ0cyBhbGwgc2VwYXJhdG9ycyBpbiB0aGlzIHN0cmluZyB0byAvLCB0aGUgZGVmYXVsdCBwYXRoIHNlcGFyYXRvci4KKyAgICAgKgorICAgICAqIElmIHRoZSBkZWZhdWx0IE9TIHNlcGFyYXRvciBpcyBiYWNrc2xhc2gsIHRoaXMgY29udmVydHMgYWxsCisgICAgICogYmFja3NsYXNoZXMgdG8gc2xhc2hlcywgaW4tcGxhY2UuIE90aGVyd2lzZSBpdCBkb2VzIG5vdGhpbmcuCisgICAgICogUmV0dXJucyBzZWxmLgorICAgICAqLworICAgIFN0cmluZzgmIGNvbnZlcnRUb1Jlc1BhdGgoKTsKKworcHJpdmF0ZToKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICAgICAgcmVhbF9hcHBlbmQoY29uc3QgY2hhciogb3RoZXIsIHNpemVfdCBudW1DaGFycyk7CisgICAgICAgICAgICBjaGFyKiAgICAgICAgICAgICAgIGZpbmRfZXh0ZW5zaW9uKHZvaWQpIGNvbnN0OworCisgICAgICAgICAgICBjb25zdCBjaGFyKiBtU3RyaW5nOworfTsKKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3QgU3RyaW5nMTYmIHZhbCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTm8gdXNlciBzZXJ2aWNhYmxlIHBhcnRzIGJlbG93LgorCitpbmxpbmUgaW50IGNvbXBhcmVfdHlwZShjb25zdCBTdHJpbmc4JiBsaHMsIGNvbnN0IFN0cmluZzgmIHJocykKK3sKKyAgICByZXR1cm4gbGhzLmNvbXBhcmUocmhzKTsKK30KKworaW5saW5lIGludCBzdHJpY3RseV9vcmRlcl90eXBlKGNvbnN0IFN0cmluZzgmIGxocywgY29uc3QgU3RyaW5nOCYgcmhzKQoreworICAgIHJldHVybiBjb21wYXJlX3R5cGUobGhzLCByaHMpIDwgMDsKK30KKworaW5saW5lIGNvbnN0IGNoYXIqIFN0cmluZzg6OnN0cmluZygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1TdHJpbmc7Cit9CisKK2lubGluZSBzaXplX3QgU3RyaW5nODo6bGVuZ3RoKCkgY29uc3QKK3sKKyAgICByZXR1cm4gU2hhcmVkQnVmZmVyOjpzaXplRnJvbURhdGEobVN0cmluZyktMTsKK30KKworaW5saW5lIHNpemVfdCBTdHJpbmc4OjpzaXplKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbGVuZ3RoKCk7Cit9CisKK2lubGluZSBzaXplX3QgU3RyaW5nODo6Ynl0ZXMoKSBjb25zdAoreworICAgIHJldHVybiBTaGFyZWRCdWZmZXI6OnNpemVGcm9tRGF0YShtU3RyaW5nKS0xOworfQorCitpbmxpbmUgY29uc3QgU2hhcmVkQnVmZmVyKiBTdHJpbmc4OjpzaGFyZWRCdWZmZXIoKSBjb25zdAoreworICAgIHJldHVybiBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpOworfQorCitpbmxpbmUgU3RyaW5nOCYgU3RyaW5nODo6b3BlcmF0b3I9KGNvbnN0IFN0cmluZzgmIG90aGVyKQoreworICAgIHNldFRvKG90aGVyKTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK2lubGluZSBTdHJpbmc4JiBTdHJpbmc4OjpvcGVyYXRvcj0oY29uc3QgY2hhciogb3RoZXIpCit7CisgICAgc2V0VG8ob3RoZXIpOworICAgIHJldHVybiAqdGhpczsKK30KKworaW5saW5lIFN0cmluZzgmIFN0cmluZzg6Om9wZXJhdG9yKz0oY29uc3QgU3RyaW5nOCYgb3RoZXIpCit7CisgICAgYXBwZW5kKG90aGVyKTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK2lubGluZSBTdHJpbmc4IFN0cmluZzg6Om9wZXJhdG9yKyhjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3QKK3sKKyAgICBTdHJpbmc4IHRtcDsKKyAgICB0bXAgKz0gb3RoZXI7CisgICAgcmV0dXJuIHRtcDsKK30KKworaW5saW5lIFN0cmluZzgmIFN0cmluZzg6Om9wZXJhdG9yKz0oY29uc3QgY2hhciogb3RoZXIpCit7CisgICAgYXBwZW5kKG90aGVyKTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK2lubGluZSBTdHJpbmc4IFN0cmluZzg6Om9wZXJhdG9yKyhjb25zdCBjaGFyKiBvdGhlcikgY29uc3QKK3sKKyAgICBTdHJpbmc4IHRtcDsKKyAgICB0bXAgKz0gb3RoZXI7CisgICAgcmV0dXJuIHRtcDsKK30KKworaW5saW5lIGludCBTdHJpbmc4Ojpjb21wYXJlKGNvbnN0IFN0cmluZzgmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJjbXAobVN0cmluZywgb3RoZXIubVN0cmluZyk7Cit9CisKK2lubGluZSBib29sIFN0cmluZzg6Om9wZXJhdG9yPChjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyLm1TdHJpbmcpIDwgMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nODo6b3BlcmF0b3I8PShjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyLm1TdHJpbmcpIDw9IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzg6Om9wZXJhdG9yPT0oY29uc3QgU3RyaW5nOCYgb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cmNtcChtU3RyaW5nLCBvdGhlci5tU3RyaW5nKSA9PSAwOworfQorCitpbmxpbmUgYm9vbCBTdHJpbmc4OjpvcGVyYXRvciE9KGNvbnN0IFN0cmluZzgmIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJjbXAobVN0cmluZywgb3RoZXIubVN0cmluZykgIT0gMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nODo6b3BlcmF0b3I+PShjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyLm1TdHJpbmcpID49IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzg6Om9wZXJhdG9yPihjb25zdCBTdHJpbmc4JiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyLm1TdHJpbmcpID4gMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nODo6b3BlcmF0b3I8KGNvbnN0IGNoYXIqIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJjbXAobVN0cmluZywgb3RoZXIpIDwgMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nODo6b3BlcmF0b3I8PShjb25zdCBjaGFyKiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyKSA8PSAwOworfQorCitpbmxpbmUgYm9vbCBTdHJpbmc4OjpvcGVyYXRvcj09KGNvbnN0IGNoYXIqIG90aGVyKSBjb25zdAoreworICAgIHJldHVybiBzdHJjbXAobVN0cmluZywgb3RoZXIpID09IDA7Cit9CisKK2lubGluZSBib29sIFN0cmluZzg6Om9wZXJhdG9yIT0oY29uc3QgY2hhciogb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cmNtcChtU3RyaW5nLCBvdGhlcikgIT0gMDsKK30KKworaW5saW5lIGJvb2wgU3RyaW5nODo6b3BlcmF0b3I+PShjb25zdCBjaGFyKiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gc3RyY21wKG1TdHJpbmcsIG90aGVyKSA+PSAwOworfQorCitpbmxpbmUgYm9vbCBTdHJpbmc4OjpvcGVyYXRvcj4oY29uc3QgY2hhciogb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuIHN0cmNtcChtU3RyaW5nLCBvdGhlcikgPiAwOworfQorCitpbmxpbmUgU3RyaW5nODo6b3BlcmF0b3IgY29uc3QgY2hhciooKSBjb25zdAoreworICAgIHJldHVybiBtU3RyaW5nOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfU1RSSU5HOF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1N5c3RlbUNsb2NrLmggYi9pbmNsdWRlL3V0aWxzL1N5c3RlbUNsb2NrLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2MzMTliZQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvU3lzdGVtQ2xvY2suaApAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1VUSUxTX1NZU1RFTUNMT0NLX0gKKyNkZWZpbmUgQU5EUk9JRF9VVElMU19TWVNURU1DTE9DS19ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitpbnQgc2V0Q3VycmVudFRpbWVNaWxsaXMoaW50NjRfdCBtaWxsaXMpOworaW50NjRfdCB1cHRpbWVNaWxsaXMoKTsKK2ludDY0X3QgZWxhcHNlZFJlYWx0aW1lKCk7CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX1VUSUxTX1NZU1RFTUNMT0NLX0gKKwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9UZXh0T3V0cHV0LmggYi9pbmNsdWRlL3V0aWxzL1RleHRPdXRwdXQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOGQ4NmJhCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9UZXh0T3V0cHV0LmgKQEAgLTAsMCArMSwxOTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfVEVYVE9VVFBVVF9ICisjZGVmaW5lIEFORFJPSURfVEVYVE9VVFBVVF9ICisKKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgVGV4dE91dHB1dAoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgVGV4dE91dHB1dCgpIHsgfQorICAgIHZpcnR1YWwgICAgICAgICAgICAgflRleHRPdXRwdXQoKSB7IH0KKyAgICAKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHByaW50KGNvbnN0IGNoYXIqIHR4dCwgc2l6ZV90IGxlbikgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgbW92ZUluZGVudChpbnQgZGVsdGEpID0gMDsKKyAgICAKKyAgICBjbGFzcyBCdW5kbGUgeworICAgIHB1YmxpYzoKKyAgICAgICAgaW5saW5lIEJ1bmRsZShUZXh0T3V0cHV0JiB0bykgOiBtVE8odG8pIHsgdG8ucHVzaEJ1bmRsZSgpOyB9CisgICAgICAgIGlubGluZSB+QnVuZGxlKCkgeyBtVE8ucG9wQnVuZGxlKCk7IH0KKyAgICBwcml2YXRlOgorICAgICAgICBUZXh0T3V0cHV0JiAgICAgbVRPOworICAgIH07CisgICAgCisgICAgdmlydHVhbCB2b2lkICAgICAgICBwdXNoQnVuZGxlKCkgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgcG9wQnVuZGxlKCkgPSAwOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFRleHQgb3V0cHV0IHN0cmVhbSBmb3IgcHJpbnRpbmcgdG8gdGhlIGxvZyAodmlhIHV0aWxzL0xvZy5oKS4KK2V4dGVybiBUZXh0T3V0cHV0JiBhbG9nOworCisvLyBUZXh0IG91dHB1dCBzdHJlYW0gZm9yIHByaW50aW5nIHRvIHN0ZG91dC4KK2V4dGVybiBUZXh0T3V0cHV0JiBhb3V0OworCisvLyBUZXh0IG91dHB1dCBzdHJlYW0gZm9yIHByaW50aW5nIHRvIHN0ZGVyci4KK2V4dGVybiBUZXh0T3V0cHV0JiBhZXJyOworCit0eXBlZGVmIFRleHRPdXRwdXQmICgqVGV4dE91dHB1dE1hbmlwRnVuYykoVGV4dE91dHB1dCYpOworCitUZXh0T3V0cHV0JiBlbmRsKFRleHRPdXRwdXQmIHRvKTsKK1RleHRPdXRwdXQmIGluZGVudChUZXh0T3V0cHV0JiB0byk7CitUZXh0T3V0cHV0JiBkZWRlbnQoVGV4dE91dHB1dCYgdG8pOworCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCBjaGFyKiBzdHIpOworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY2hhcik7ICAgICAvLyB3cml0ZXMgcmF3IGNoYXJhY3RlcgorVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgYm9vbCk7CitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBpbnQpOworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgbG9uZyk7CitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCB1bnNpZ25lZCBpbnQpOworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgdW5zaWduZWQgbG9uZyk7CitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBsb25nIGxvbmcpOworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgdW5zaWduZWQgbG9uZyBsb25nKTsKK1RleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGZsb2F0KTsKK1RleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGRvdWJsZSk7CitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBUZXh0T3V0cHV0TWFuaXBGdW5jIGZ1bmMpOworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3Qgdm9pZCopOworCitjbGFzcyBUeXBlQ29kZSAKK3sKK3B1YmxpYzoKKyAgICBpbmxpbmUgVHlwZUNvZGUodWludDMyX3QgY29kZSk7CisgICAgaW5saW5lIH5UeXBlQ29kZSgpOworCisgICAgaW5saW5lIHVpbnQzMl90IHR5cGVDb2RlKCkgY29uc3Q7CisgICAgCitwcml2YXRlOgorICAgIHVpbnQzMl90IG1Db2RlOworfTsKKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3QgVHlwZUNvZGUmIHZhbCk7CisKK2NsYXNzIEhleER1bXAKK3sKK3B1YmxpYzoKKyAgICBIZXhEdW1wKGNvbnN0IHZvaWQgKmJ1Ziwgc2l6ZV90IHNpemUsIHNpemVfdCBieXRlc1BlckxpbmU9MTYpOworICAgIGlubGluZSB+SGV4RHVtcCgpOworICAgIAorICAgIGlubGluZSBIZXhEdW1wJiBzZXRCeXRlc1BlckxpbmUoc2l6ZV90IGJ5dGVzUGVyTGluZSk7CisgICAgaW5saW5lIEhleER1bXAmIHNldFNpbmdsZUxpbmVDdXRvZmYoaW50MzJfdCBieXRlcyk7CisgICAgaW5saW5lIEhleER1bXAmIHNldEFsaWdubWVudChzaXplX3QgYWxpZ25tZW50KTsKKyAgICBpbmxpbmUgSGV4RHVtcCYgc2V0Q0FycmF5U3R5bGUoYm9vbCBlbmFibGVkKTsKKyAgICAKKyAgICBpbmxpbmUgY29uc3Qgdm9pZCogYnVmZmVyKCkgY29uc3Q7CisgICAgaW5saW5lIHNpemVfdCBzaXplKCkgY29uc3Q7CisgICAgaW5saW5lIHNpemVfdCBieXRlc1BlckxpbmUoKSBjb25zdDsKKyAgICBpbmxpbmUgaW50MzJfdCBzaW5nbGVMaW5lQ3V0b2ZmKCkgY29uc3Q7CisgICAgaW5saW5lIHNpemVfdCBhbGlnbm1lbnQoKSBjb25zdDsKKyAgICBpbmxpbmUgYm9vbCBjYXJyYXlTdHlsZSgpIGNvbnN0OworCitwcml2YXRlOgorICAgIGNvbnN0IHZvaWQqIG1CdWZmZXI7CisgICAgc2l6ZV90IG1TaXplOworICAgIHNpemVfdCBtQnl0ZXNQZXJMaW5lOworICAgIGludDMyX3QgbVNpbmdsZUxpbmVDdXRvZmY7CisgICAgc2l6ZV90IG1BbGlnbm1lbnQ7CisgICAgYm9vbCBtQ0FycmF5U3R5bGU7Cit9OworCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCBIZXhEdW1wJiB2YWwpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vIHVzZXIgc2VydmljYWJsZSBwYXJ0cyBiZWxvdy4KKworaW5saW5lIFRleHRPdXRwdXQmIGVuZGwoVGV4dE91dHB1dCYgdG8pCit7CisgICAgdG8ucHJpbnQoIlxuIiwgMSk7CisgICAgcmV0dXJuIHRvOworfQorCitpbmxpbmUgVGV4dE91dHB1dCYgaW5kZW50KFRleHRPdXRwdXQmIHRvKQoreworICAgIHRvLm1vdmVJbmRlbnQoMSk7CisgICAgcmV0dXJuIHRvOworfQorCitpbmxpbmUgVGV4dE91dHB1dCYgZGVkZW50KFRleHRPdXRwdXQmIHRvKQoreworICAgIHRvLm1vdmVJbmRlbnQoLTEpOworICAgIHJldHVybiB0bzsKK30KKworaW5saW5lIFRleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIGNvbnN0IGNoYXIqIHN0cikKK3sKKyAgICB0by5wcmludChzdHIsIHN0cmxlbihzdHIpKTsKKyAgICByZXR1cm4gdG87Cit9CisKK2lubGluZSBUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjaGFyIGMpCit7CisgICAgdG8ucHJpbnQoJmMsIDEpOworICAgIHJldHVybiB0bzsKK30KKworaW5saW5lIFRleHRPdXRwdXQmIG9wZXJhdG9yPDwoVGV4dE91dHB1dCYgdG8sIFRleHRPdXRwdXRNYW5pcEZ1bmMgZnVuYykKK3sKKyAgICByZXR1cm4gKCpmdW5jKSh0byk7Cit9CisKK2lubGluZSBUeXBlQ29kZTo6VHlwZUNvZGUodWludDMyX3QgY29kZSkgOiBtQ29kZShjb2RlKSB7IH0KK2lubGluZSBUeXBlQ29kZTo6flR5cGVDb2RlKCkgeyB9CitpbmxpbmUgdWludDMyX3QgVHlwZUNvZGU6OnR5cGVDb2RlKCkgY29uc3QgeyByZXR1cm4gbUNvZGU7IH0KKworaW5saW5lIEhleER1bXA6On5IZXhEdW1wKCkgeyB9CisKK2lubGluZSBIZXhEdW1wJiBIZXhEdW1wOjpzZXRCeXRlc1BlckxpbmUoc2l6ZV90IGJ5dGVzUGVyTGluZSkgeworICAgIG1CeXRlc1BlckxpbmUgPSBieXRlc1BlckxpbmU7IHJldHVybiAqdGhpczsKK30KK2lubGluZSBIZXhEdW1wJiBIZXhEdW1wOjpzZXRTaW5nbGVMaW5lQ3V0b2ZmKGludDMyX3QgYnl0ZXMpIHsKKyAgICBtU2luZ2xlTGluZUN1dG9mZiA9IGJ5dGVzOyByZXR1cm4gKnRoaXM7Cit9CitpbmxpbmUgSGV4RHVtcCYgSGV4RHVtcDo6c2V0QWxpZ25tZW50KHNpemVfdCBhbGlnbm1lbnQpIHsKKyAgICBtQWxpZ25tZW50ID0gYWxpZ25tZW50OyByZXR1cm4gKnRoaXM7Cit9CitpbmxpbmUgSGV4RHVtcCYgSGV4RHVtcDo6c2V0Q0FycmF5U3R5bGUoYm9vbCBlbmFibGVkKSB7CisgICAgbUNBcnJheVN0eWxlID0gZW5hYmxlZDsgcmV0dXJuICp0aGlzOworfQorCitpbmxpbmUgY29uc3Qgdm9pZCogSGV4RHVtcDo6YnVmZmVyKCkgY29uc3QgeyByZXR1cm4gbUJ1ZmZlcjsgfQoraW5saW5lIHNpemVfdCBIZXhEdW1wOjpzaXplKCkgY29uc3QgeyByZXR1cm4gbVNpemU7IH0KK2lubGluZSBzaXplX3QgSGV4RHVtcDo6Ynl0ZXNQZXJMaW5lKCkgY29uc3QgeyByZXR1cm4gbUJ5dGVzUGVyTGluZTsgfQoraW5saW5lIGludDMyX3QgSGV4RHVtcDo6c2luZ2xlTGluZUN1dG9mZigpIGNvbnN0IHsgcmV0dXJuIG1TaW5nbGVMaW5lQ3V0b2ZmOyB9CitpbmxpbmUgc2l6ZV90IEhleER1bXA6OmFsaWdubWVudCgpIGNvbnN0IHsgcmV0dXJuIG1BbGlnbm1lbnQ7IH0KK2lubGluZSBib29sIEhleER1bXA6OmNhcnJheVN0eWxlKCkgY29uc3QgeyByZXR1cm4gbUNBcnJheVN0eWxlOyB9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfVEVYVE9VVFBVVF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1RpbWVVdGlscy5oIGIvaW5jbHVkZS91dGlscy9UaW1lVXRpbHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTllMDIxCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9UaW1lVXRpbHMuaApAQCAtMCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1RJTUVfSAorI2RlZmluZSBBTkRST0lEX1RJTUVfSAorCisjaW5jbHVkZSA8dGltZS5oPgorI2luY2x1ZGUgPGN1dGlscy90enRpbWUuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8qCisgKiBUaGlzIGNsYXNzIGlzIHRoZSBjb3JlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBhbmRyb2lkLnV0aWwuVGltZSBqYXZhCisgKiBjbGFzcy4gIEl0IGRvZXNuJ3QgaW1wbGVtZW50IHNvbWUgb2YgdGhlIG1ldGhvZHMgdGhhdCBhcmUgaW1wbGVtZW50ZWQKKyAqIGluIEphdmEuICBUaGV5IGNvdWxkIGJlIGRvbmUgaGVyZSwgYnV0IGl0J3Mgbm90IGV4cGVjdGVkIHRoYXQgdGhpcyBjbGFzcworICogd2lsbCBiZSB1c2VkLiAgSWYgdGhhdCBhc3N1bXB0aW9uIGlzIGluY29ycmVjdCwgZmVlbCBmcmVlIHRvIHVwZGF0ZSB0aGlzCisgKiBmaWxlLiAgVGhlIHJlYXNvbiB0byBkbyBpdCBoZXJlIGlzIHRvIG5vdCBtaXggdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMKKyAqIGNsYXNzIGFuZCB0aGUgam5pIGdsdWUgY29kZS4KKyAqLworY2xhc3MgVGltZQoreworcHVibGljOgorICAgIHN0cnVjdCB0bSB0OworCisgICAgLy8gdGhpcyBvYmplY3QgZG9lc24ndCBvd24gdGhpcyBzdHJpbmcKKyAgICBjb25zdCBjaGFyICp0aW1lem9uZTsKKworICAgIGVudW0geworICAgICAgICBTRUMgPSAxLAorICAgICAgICBNSU4gPSAyLAorICAgICAgICBIT1VSID0gMywKKyAgICAgICAgTURBWSA9IDQsCisgICAgICAgIE1PTiA9IDUsCisgICAgICAgIFlFQVIgPSA2LAorICAgICAgICBXREFZID0gNywKKyAgICAgICAgWURBWSA9IDgKKyAgICB9OworCisgICAgc3RhdGljIGludCBjb21wYXJlKFRpbWUmIGEsIFRpbWUmIGIpOworCisgICAgVGltZSgpOworCisgICAgdm9pZCBzd2l0Y2hUaW1lem9uZShjb25zdCBjaGFyICp0aW1lem9uZSk7CisgICAgU3RyaW5nOCBmb3JtYXQoY29uc3QgY2hhciAqZm9ybWF0LCBjb25zdCBzdHJ1Y3Qgc3RyZnRpbWVfbG9jYWxlICpsb2NhbGUpIGNvbnN0OworICAgIHZvaWQgZm9ybWF0MjQ0NShzaG9ydCogYnVmLCBib29sIGhhc1RpbWUpIGNvbnN0OworICAgIFN0cmluZzggdG9TdHJpbmcoKSBjb25zdDsKKyAgICB2b2lkIHNldFRvTm93KCk7CisgICAgaW50NjRfdCB0b01pbGxpcyhib29sIGlnbm9yZURzdCk7CisgICAgdm9pZCBzZXQoaW50NjRfdCBtaWxsaXMpOworCisgICAgaW5saW5lIHZvaWQgc2V0KGludCBzZWMsIGludCBtaW4sIGludCBob3VyLCBpbnQgbWRheSwgaW50IG1vbiwgaW50IHllYXIsCisgICAgICAgICAgICBpbnQgaXNkc3QpCisgICAgeworICAgICAgICB0aGlzLT50LnRtX3NlYyA9IHNlYzsKKyAgICAgICAgdGhpcy0+dC50bV9taW4gPSBtaW47CisgICAgICAgIHRoaXMtPnQudG1faG91ciA9IGhvdXI7CisgICAgICAgIHRoaXMtPnQudG1fbWRheSA9IG1kYXk7CisgICAgICAgIHRoaXMtPnQudG1fbW9uID0gbW9uOworICAgICAgICB0aGlzLT50LnRtX3llYXIgPSB5ZWFyOworICAgICAgICB0aGlzLT50LnRtX2lzZHN0ID0gaXNkc3Q7CisjaWZkZWYgSEFWRV9UTV9HTVRPRkYKKyAgICAgICAgdGhpcy0+dC50bV9nbXRvZmYgPSAwOworI2VuZGlmCisgICAgICAgIHRoaXMtPnQudG1fd2RheSA9IDA7CisgICAgICAgIHRoaXMtPnQudG1feWRheSA9IDA7CisgICAgfQorfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfVElNRV9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1RpbWVyUHJvYmUuaCBiL2luY2x1ZGUvdXRpbHMvVGltZXJQcm9iZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyZTMyYjIKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1RpbWVyUHJvYmUuaApAQCAtMCwwICsxLDcyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1RJTUVSX1BST0JFX0gKKyNkZWZpbmUgQU5EUk9JRF9USU1FUl9QUk9CRV9ICisKKyNpZiAwICYmIGRlZmluZWQoSEFWRV9QT1NJWF9DTE9DS1MpCisjZGVmaW5lIEVOQUJMRV9USU1FUl9QUk9CRSAxCisjZWxzZQorI2RlZmluZSBFTkFCTEVfVElNRVJfUFJPQkUgMAorI2VuZGlmCisKKyNpZiBFTkFCTEVfVElNRVJfUFJPQkUKKworI2luY2x1ZGUgPHRpbWUuaD4KKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorCisjZGVmaW5lIFRJTUVSX1BST0JFKHRhZykgXAorICAgIHN0YXRpYyBpbnQgX3RpbWVyX3Nsb3RfOyBcCisgICAgYW5kcm9pZDo6VGltZXJQcm9iZSBwcm9iZSh0YWcsICZfdGltZXJfc2xvdF8pCisjZGVmaW5lIFRJTUVSX1BST0JFX0VORCgpIHByb2JlLmVuZCgpCisjZWxzZQorI2RlZmluZSBUSU1FUl9QUk9CRSh0YWcpCisjZGVmaW5lIFRJTUVSX1BST0JFX0VORCgpCisjZW5kaWYKKworI2lmIEVOQUJMRV9USU1FUl9QUk9CRQorbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBUaW1lclByb2JlIHsKK3B1YmxpYzoKKyAgICBUaW1lclByb2JlKGNvbnN0IGNoYXIgdGFnW10sIGludCogc2xvdCk7CisgICAgdm9pZCBlbmQoKTsKKyAgICB+VGltZXJQcm9iZSgpOworcHJpdmF0ZToKKyAgICBzdHJ1Y3QgQnVja2V0IHsKKyAgICAgICAgaW50IG1TdGFydCwgbVJlYWwsIG1Qcm9jZXNzLCBtVGhyZWFkLCBtQ291bnQ7CisgICAgICAgIGNvbnN0IGNoYXIqIG1UYWc7CisgICAgICAgIGludCogbVNsb3RQdHI7CisgICAgICAgIGludCBtSW5kZW50OworICAgIH07CisgICAgc3RhdGljIFZlY3RvcjxCdWNrZXQ+IGdCdWNrZXRzOworICAgIHN0YXRpYyBUaW1lclByb2JlKiBnRXhlY3V0ZUNoYWluOworICAgIHN0YXRpYyBpbnQgZ0luZGVudDsKKyAgICBzdGF0aWMgdGltZXNwZWMgZ1JlYWxCYXNlOworICAgIFRpbWVyUHJvYmUqIG1OZXh0OworICAgIHN0YXRpYyB1aW50MzJfdCBFbGFwc2VkVGltZShjb25zdCB0aW1lc3BlYyYgc3RhcnQsIGNvbnN0IHRpbWVzcGVjJiBlbmQpOworICAgIHZvaWQgcHJpbnQoY29uc3QgdGltZXNwZWMmIHIsIGNvbnN0IHRpbWVzcGVjJiBwLCBjb25zdCB0aW1lc3BlYyYgdCkgY29uc3Q7CisgICAgdGltZXNwZWMgbVJlYWxTdGFydCwgbVBTdGFydCwgbVRTdGFydDsKKyAgICBjb25zdCBjaGFyKiBtVGFnOworICAgIGludCBtSW5kZW50OworICAgIGludCBtQnVja2V0OworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmCisjZW5kaWYKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvVGltZXJzLmggYi9pbmNsdWRlL3V0aWxzL1RpbWVycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2MTAzOTkKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1RpbWVycy5oCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIFRpbWVyIGZ1bmN0aW9ucy4KKy8vCisjaWZuZGVmIF9MSUJTX1VUSUxTX1RJTUVSU19ICisjZGVmaW5lIF9MSUJTX1VUSUxTX1RJTUVSU19ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEMgQVBJCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKwordHlwZWRlZiBpbnQ2NF90IG5zZWNzX3Q7ICAgICAgIC8vIG5hbm8tc2Vjb25kcworCitzdGF0aWMgaW5saW5lIG5zZWNzX3Qgc2Vjb25kc190b19uYW5vc2Vjb25kcyhuc2Vjc190IHNlY3MpCit7CisgICAgcmV0dXJuIHNlY3MqMTAwMDAwMDAwMDsKK30KKworc3RhdGljIGlubGluZSBuc2Vjc190IG1pbGxpc2Vjb25kc190b19uYW5vc2Vjb25kcyhuc2Vjc190IHNlY3MpCit7CisgICAgcmV0dXJuIHNlY3MqMTAwMDAwMDsKK30KKworc3RhdGljIGlubGluZSBuc2Vjc190IG1pY3Jvc2Vjb25kc190b19uYW5vc2Vjb25kcyhuc2Vjc190IHNlY3MpCit7CisgICAgcmV0dXJuIHNlY3MqMTAwMDsKK30KKworc3RhdGljIGlubGluZSBuc2Vjc190IG5hbm9zZWNvbmRzX3RvX3NlY29uZHMobnNlY3NfdCBzZWNzKQoreworICAgIHJldHVybiBzZWNzLzEwMDAwMDAwMDA7Cit9CisKK3N0YXRpYyBpbmxpbmUgbnNlY3NfdCBuYW5vc2Vjb25kc190b19taWxsaXNlY29uZHMobnNlY3NfdCBzZWNzKQoreworICAgIHJldHVybiBzZWNzLzEwMDAwMDA7Cit9CisKK3N0YXRpYyBpbmxpbmUgbnNlY3NfdCBuYW5vc2Vjb25kc190b19taWNyb3NlY29uZHMobnNlY3NfdCBzZWNzKQoreworICAgIHJldHVybiBzZWNzLzEwMDA7Cit9CisKK3N0YXRpYyBpbmxpbmUgbnNlY3NfdCBzMm5zKG5zZWNzX3QgdikgIHtyZXR1cm4gc2Vjb25kc190b19uYW5vc2Vjb25kcyh2KTt9CitzdGF0aWMgaW5saW5lIG5zZWNzX3QgbXMybnMobnNlY3NfdCB2KSB7cmV0dXJuIG1pbGxpc2Vjb25kc190b19uYW5vc2Vjb25kcyh2KTt9CitzdGF0aWMgaW5saW5lIG5zZWNzX3QgdXMybnMobnNlY3NfdCB2KSB7cmV0dXJuIG1pY3Jvc2Vjb25kc190b19uYW5vc2Vjb25kcyh2KTt9CitzdGF0aWMgaW5saW5lIG5zZWNzX3QgbnMycyhuc2Vjc190IHYpICB7cmV0dXJuIG5hbm9zZWNvbmRzX3RvX3NlY29uZHModik7fQorc3RhdGljIGlubGluZSBuc2Vjc190IG5zMm1zKG5zZWNzX3Qgdikge3JldHVybiBuYW5vc2Vjb25kc190b19taWxsaXNlY29uZHModik7fQorc3RhdGljIGlubGluZSBuc2Vjc190IG5zMnVzKG5zZWNzX3Qgdikge3JldHVybiBuYW5vc2Vjb25kc190b19taWNyb3NlY29uZHModik7fQorCitzdGF0aWMgaW5saW5lIG5zZWNzX3Qgc2Vjb25kcyhuc2Vjc190IHYpICAgICAgeyByZXR1cm4gczJucyh2KTsgfQorc3RhdGljIGlubGluZSBuc2Vjc190IG1pbGxpc2Vjb25kcyhuc2Vjc190IHYpIHsgcmV0dXJuIG1zMm5zKHYpOyB9CitzdGF0aWMgaW5saW5lIG5zZWNzX3QgbWljcm9zZWNvbmRzKG5zZWNzX3QgdikgeyByZXR1cm4gdXMybnModik7IH0KKworZW51bSB7CisgICAgU1lTVEVNX1RJTUVfUkVBTFRJTUUgPSAwLCAgLy8gc3lzdGVtLXdpZGUgcmVhbHRpbWUgY2xvY2sKKyAgICBTWVNURU1fVElNRV9NT05PVE9OSUMgPSAxLCAvLyBtb25vdG9uaWMgdGltZSBzaW5jZSB1bnNwZWNpZmllZCBzdGFydGluZyBwb2ludAorICAgIFNZU1RFTV9USU1FX1BST0NFU1MgPSAyLCAgIC8vIGhpZ2gtcmVzb2x1dGlvbiBwZXItcHJvY2VzcyBjbG9jaworICAgIFNZU1RFTV9USU1FX1RIUkVBRCA9IDMgICAgIC8vIGhpZ2gtcmVzb2x1dGlvbiBwZXItdGhyZWFkIGNsb2NrCit9OworICAgIAorLy8gcmV0dXJuIHRoZSBzeXN0ZW0tdGltZSBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBjbG9jaworI2lmZGVmIF9fY3BsdXNwbHVzCituc2Vjc190IHN5c3RlbVRpbWUoaW50IGNsb2NrID0gU1lTVEVNX1RJTUVfTU9OT1RPTklDKTsKKyNlbHNlCituc2Vjc190IHN5c3RlbVRpbWUoaW50IGNsb2NrKTsKKyNlbmRpZiAvLyBkZWYgX19jcGx1c3BsdXMKKworLy8gcmV0dXJuIHRoZSBzeXN0ZW0tdGltZSBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBjbG9jaworaW50IHNsZWVwRm9ySW50ZXJ2YWwobG9uZyBpbnRlcnZhbCwgc3RydWN0IHRpbWV2YWwqIHBOZXh0VGljayk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfSAvLyBleHRlcm4gIkMiCisjZW5kaWYKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBDKysgQVBJCisKKyNpZmRlZiBfX2NwbHVzcGx1cworCituYW1lc3BhY2UgYW5kcm9pZCB7CisvKgorICogVGltZSB0aGUgZHVyYXRpb24gb2Ygc29tZXRoaW5nLgorICoKKyAqIEluY2x1ZGVzIHNvbWUgdGltZXZhbCBtYW5pcHVsYXRpb24gZnVuY3Rpb25zLgorICovCitjbGFzcyBEdXJhdGlvblRpbWVyIHsKK3B1YmxpYzoKKyAgICBEdXJhdGlvblRpbWVyKHZvaWQpIHt9CisgICAgfkR1cmF0aW9uVGltZXIodm9pZCkge30KKworICAgIC8vIFN0YXJ0IHRoZSB0aW1lci4KKyAgICB2b2lkIHN0YXJ0KHZvaWQpOworICAgIC8vIFN0b3AgdGhlIHRpbWVyLgorICAgIHZvaWQgc3RvcCh2b2lkKTsKKyAgICAvLyBHZXQgdGhlIGR1cmF0aW9uIGluIG1pY3Jvc2Vjb25kcy4KKyAgICBsb25nIGxvbmcgZHVyYXRpb25Vc2Vjcyh2b2lkKSBjb25zdDsKKworICAgIC8vIFN1YnRyYWN0IHR3byB0aW1ldmFscy4gIFJldHVybnMgdGhlIGRpZmZlcmVuY2UgKHB0djEtcHR2MikgaW4KKyAgICAvLyBtaWNyb3NlY29uZHMuCisgICAgc3RhdGljIGxvbmcgbG9uZyBzdWJ0cmFjdFRpbWV2YWxzKGNvbnN0IHN0cnVjdCB0aW1ldmFsKiBwdHYxLAorICAgICAgICBjb25zdCBzdHJ1Y3QgdGltZXZhbCogcHR2Mik7CisKKyAgICAvLyBBZGQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZSB0byB0aGUgdGltZXZhbC4KKyAgICBzdGF0aWMgdm9pZCBhZGRUb1RpbWV2YWwoc3RydWN0IHRpbWV2YWwqIHB0diwgbG9uZyB1c2VjKTsKKworcHJpdmF0ZToKKyAgICBzdHJ1Y3QgdGltZXZhbCAgbVN0YXJ0V2hlbjsKKyAgICBzdHJ1Y3QgdGltZXZhbCAgbVN0b3BXaGVuOworfTsKKworfTsgLy8gYW5kcm9pZAorI2VuZGlmIC8vIGRlZiBfX2NwbHVzcGx1cworCisjZW5kaWYgLy8gX0xJQlNfVVRJTFNfVElNRVJTX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvVHlwZUhlbHBlcnMuaCBiL2luY2x1ZGUvdXRpbHMvVHlwZUhlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMDRjMzdmCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9UeXBlSGVscGVycy5oCkBAIC0wLDAgKzEsMjU0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1RZUEVfSEVMUEVSU19ICisjZGVmaW5lIEFORFJPSURfVFlQRV9IRUxQRVJTX0gKKworI2luY2x1ZGUgPG5ldz4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFR5cGVzIHRyYWl0cworICovCisgICAgCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfY3RvciAgeyBlbnVtIHsgdmFsdWUgPSBmYWxzZSB9OyB9OwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCB0cmFpdF90cml2aWFsX2R0b3IgIHsgZW51bSB7IHZhbHVlID0gZmFsc2UgfTsgfTsKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdHJ1Y3QgdHJhaXRfdHJpdmlhbF9jb3B5ICB7IGVudW0geyB2YWx1ZSA9IGZhbHNlIH07IH07Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfYXNzaWdueyBlbnVtIHsgdmFsdWUgPSBmYWxzZSB9OyB9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IHRyYWl0X3BvaW50ZXIgICAgIHsgZW51bSB7IHZhbHVlID0gZmFsc2UgfTsgfTsgICAgCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IHRyYWl0X3BvaW50ZXI8VCo+IHsgZW51bSB7IHZhbHVlID0gdHJ1ZSB9OyB9OworCisjZGVmaW5lIEFORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCBUICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGU8PiBzdHJ1Y3QgdHJhaXRfdHJpdmlhbF9jdG9yPCBUID4gIHsgZW51bSB7IHZhbHVlID0gdHJ1ZSB9OyB9OyAgICBcCisgICAgdGVtcGxhdGU8PiBzdHJ1Y3QgdHJhaXRfdHJpdmlhbF9kdG9yPCBUID4gIHsgZW51bSB7IHZhbHVlID0gdHJ1ZSB9OyB9OyAgICBcCisgICAgdGVtcGxhdGU8PiBzdHJ1Y3QgdHJhaXRfdHJpdmlhbF9jb3B5PCBUID4gIHsgZW51bSB7IHZhbHVlID0gdHJ1ZSB9OyB9OyAgICBcCisgICAgdGVtcGxhdGU8PiBzdHJ1Y3QgdHJhaXRfdHJpdmlhbF9hc3NpZ248IFQgPnsgZW51bSB7IHZhbHVlID0gdHJ1ZSB9OyB9OyAKKworI2RlZmluZSBBTkRST0lEX1RZUEVfVFJBSVRTKCBULCBjdG9yLCBkdG9yLCBjb3B5LCBhc3NpZ24gKSAgICAgICAgICAgICAgICAgICAgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfY3RvcjwgVCA+ICB7IGVudW0geyB2YWx1ZSA9IGN0b3IgfTsgfTsgICAgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfZHRvcjwgVCA+ICB7IGVudW0geyB2YWx1ZSA9IGR0b3IgfTsgfTsgICAgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfY29weTwgVCA+ICB7IGVudW0geyB2YWx1ZSA9IGNvcHkgfTsgfTsgICAgXAorICAgIHRlbXBsYXRlPD4gc3RydWN0IHRyYWl0X3RyaXZpYWxfYXNzaWduPCBUID57IGVudW0geyB2YWx1ZSA9IGFzc2lnbiB9OyB9OyAKKwordGVtcGxhdGUgPHR5cGVuYW1lIFRZUEU+CitzdHJ1Y3QgdHJhaXRzIHsKKyAgICBlbnVtIHsKKyAgICAgICAgaXNfcG9pbnRlciAgICAgICAgICA9IHRyYWl0X3BvaW50ZXI8VFlQRT46OnZhbHVlLAorICAgICAgICBoYXNfdHJpdmlhbF9jdG9yICAgID0gaXNfcG9pbnRlciB8fCB0cmFpdF90cml2aWFsX2N0b3I8VFlQRT46OnZhbHVlLAorICAgICAgICBoYXNfdHJpdmlhbF9kdG9yICAgID0gaXNfcG9pbnRlciB8fCB0cmFpdF90cml2aWFsX2R0b3I8VFlQRT46OnZhbHVlLAorICAgICAgICBoYXNfdHJpdmlhbF9jb3B5ICAgID0gaXNfcG9pbnRlciB8fCB0cmFpdF90cml2aWFsX2NvcHk8VFlQRT46OnZhbHVlLAorICAgICAgICBoYXNfdHJpdmlhbF9hc3NpZ24gID0gaXNfcG9pbnRlciB8fCB0cmFpdF90cml2aWFsX2Fzc2lnbjxUWVBFPjo6dmFsdWUgICAKKyAgICB9OworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CitzdHJ1Y3QgYWdncmVnYXRlX3RyYWl0cyB7CisgICAgZW51bSB7CisgICAgICAgIGlzX3BvaW50ZXIgICAgICAgICAgPSBmYWxzZSwKKyAgICAgICAgaGFzX3RyaXZpYWxfY3RvciAgICA9IHRyYWl0czxUPjo6aGFzX3RyaXZpYWxfY3RvciAmJiB0cmFpdHM8VT46Omhhc190cml2aWFsX2N0b3IsCisgICAgICAgIGhhc190cml2aWFsX2R0b3IgICAgPSB0cmFpdHM8VD46Omhhc190cml2aWFsX2R0b3IgJiYgdHJhaXRzPFU+OjpoYXNfdHJpdmlhbF9kdG9yLAorICAgICAgICBoYXNfdHJpdmlhbF9jb3B5ICAgID0gdHJhaXRzPFQ+OjpoYXNfdHJpdmlhbF9jb3B5ICYmIHRyYWl0czxVPjo6aGFzX3RyaXZpYWxfY29weSwKKyAgICAgICAgaGFzX3RyaXZpYWxfYXNzaWduICA9IHRyYWl0czxUPjo6aGFzX3RyaXZpYWxfYXNzaWduICYmIHRyYWl0czxVPjo6aGFzX3RyaXZpYWxfYXNzaWduCisgICAgfTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvKgorICogYmFzaWMgdHlwZXMgdHJhaXRzCisgKi8KKyAKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCB2b2lkICk7CitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyggYm9vbCApOworQU5EUk9JRF9CQVNJQ19UWVBFU19UUkFJVFMoIGNoYXIgKTsKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCB1bnNpZ25lZCBjaGFyICk7CitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyggc2hvcnQgKTsKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCB1bnNpZ25lZCBzaG9ydCApOworQU5EUk9JRF9CQVNJQ19UWVBFU19UUkFJVFMoIGludCApOworQU5EUk9JRF9CQVNJQ19UWVBFU19UUkFJVFMoIHVuc2lnbmVkIGludCApOworQU5EUk9JRF9CQVNJQ19UWVBFU19UUkFJVFMoIGxvbmcgKTsKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCB1bnNpZ25lZCBsb25nICk7CitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyggbG9uZyBsb25nICk7CitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyggdW5zaWduZWQgbG9uZyBsb25nICk7CitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyggZmxvYXQgKTsKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKCBkb3VibGUgKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAKKy8qCisgKiBjb21wYXJlIGFuZCBvcmRlciB0eXBlcworICovCisKK3RlbXBsYXRlPHR5cGVuYW1lIFRZUEU+IGlubGluZQoraW50IHN0cmljdGx5X29yZGVyX3R5cGUoY29uc3QgVFlQRSYgbGhzLCBjb25zdCBUWVBFJiByaHMpIHsKKyAgICByZXR1cm4gKGxocyA8IHJocykgPyAxIDogMDsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVFlQRT4gaW5saW5lCitpbnQgY29tcGFyZV90eXBlKGNvbnN0IFRZUEUmIGxocywgY29uc3QgVFlQRSYgcmhzKSB7CisgICAgcmV0dXJuIHN0cmljdGx5X29yZGVyX3R5cGUocmhzLCBsaHMpIC0gc3RyaWN0bHlfb3JkZXJfdHlwZShsaHMsIHJocyk7Cit9CisKKy8qCisgKiBjcmVhdGUsIGRlc3Ryb3ksIGNvcHkgYW5kIGFzc2lnbiB0eXBlcy4uLgorICovCisgCit0ZW1wbGF0ZTx0eXBlbmFtZSBUWVBFPiBpbmxpbmUKK3ZvaWQgY29uc3RydWN0X3R5cGUoVFlQRSogcCwgc2l6ZV90IG4pIHsKKyAgICBpZiAoIXRyYWl0czxUWVBFPjo6aGFzX3RyaXZpYWxfY3RvcikgeworICAgICAgICB3aGlsZSAobi0tKSB7CisgICAgICAgICAgICBuZXcocCsrKSBUWVBFOworICAgICAgICB9CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUWVBFPiBpbmxpbmUKK3ZvaWQgZGVzdHJveV90eXBlKFRZUEUqIHAsIHNpemVfdCBuKSB7CisgICAgaWYgKCF0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2R0b3IpIHsKKyAgICAgICAgd2hpbGUgKG4tLSkgeworICAgICAgICAgICAgcC0+flRZUEUoKTsKKyAgICAgICAgICAgIHArKzsKKyAgICAgICAgfQorICAgIH0KK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVFlQRT4gaW5saW5lCit2b2lkIGNvcHlfdHlwZShUWVBFKiBkLCBjb25zdCBUWVBFKiBzLCBzaXplX3QgbikgeworICAgIGlmICghdHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9jb3B5KSB7CisgICAgICAgIHdoaWxlIChuLS0pIHsKKyAgICAgICAgICAgIG5ldyhkKSBUWVBFKCpzKTsKKyAgICAgICAgICAgIGQrKywgcysrOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgbWVtY3B5KGQscyxuKnNpemVvZihUWVBFKSk7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUWVBFPiBpbmxpbmUKK3ZvaWQgYXNzaWduX3R5cGUoVFlQRSogZCwgY29uc3QgVFlQRSogcywgc2l6ZV90IG4pIHsKKyAgICBpZiAoIXRyYWl0czxUWVBFPjo6aGFzX3RyaXZpYWxfYXNzaWduKSB7CisgICAgICAgIHdoaWxlIChuLS0pIHsKKyAgICAgICAgICAgICpkKysgPSAqcysrOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgbWVtY3B5KGQscyxuKnNpemVvZihUWVBFKSk7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUWVBFPiBpbmxpbmUKK3ZvaWQgc3BsYXRfdHlwZShUWVBFKiB3aGVyZSwgY29uc3QgVFlQRSogd2hhdCwgc2l6ZV90IG4pIHsKKyAgICBpZiAoIXRyYWl0czxUWVBFPjo6aGFzX3RyaXZpYWxfY29weSkgeworICAgICAgICB3aGlsZSAobi0tKSB7CisgICAgICAgICAgICBuZXcod2hlcmUpIFRZUEUoKndoYXQpOworICAgICAgICAgICAgd2hlcmUrKzsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgICB3aGlsZSAobi0tKSB7CisgICAgICAgICAgICAgKndoZXJlKysgPSAqd2hhdDsKKyAgICAgICAgfQorICAgIH0KK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVFlQRT4gaW5saW5lCit2b2lkIG1vdmVfZm9yd2FyZF90eXBlKFRZUEUqIGQsIGNvbnN0IFRZUEUqIHMsIHNpemVfdCBuID0gMSkgeworICAgIGlmICghdHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9jb3B5IHx8ICF0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2R0b3IpIHsKKyAgICAgICAgZCArPSBuOworICAgICAgICBzICs9IG47CisgICAgICAgIHdoaWxlIChuLS0pIHsKKyAgICAgICAgICAgIC0tZCwgLS1zOworICAgICAgICAgICAgaWYgKCF0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2NvcHkpIHsKKyAgICAgICAgICAgICAgICBuZXcoZCkgVFlQRSgqcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICpkID0gKnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXRyYWl0czxUWVBFPjo6aGFzX3RyaXZpYWxfZHRvcikgeworICAgICAgICAgICAgICAgIHMtPn5UWVBFKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBtZW1tb3ZlKGQscyxuKnNpemVvZihUWVBFKSk7CisgICAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUWVBFPiBpbmxpbmUKK3ZvaWQgbW92ZV9iYWNrd2FyZF90eXBlKFRZUEUqIGQsIGNvbnN0IFRZUEUqIHMsIHNpemVfdCBuID0gMSkgeworICAgIGlmICghdHJhaXRzPFRZUEU+OjpoYXNfdHJpdmlhbF9jb3B5IHx8ICF0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2R0b3IpIHsKKyAgICAgICAgd2hpbGUgKG4tLSkgeworICAgICAgICAgICAgaWYgKCF0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2NvcHkpIHsKKyAgICAgICAgICAgICAgICBuZXcoZCkgVFlQRSgqcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICpkID0gKnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXRyYWl0czxUWVBFPjo6aGFzX3RyaXZpYWxfZHRvcikgeworICAgICAgICAgICAgICAgIHMtPn5UWVBFKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkKyssIHMrKzsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIG1lbW1vdmUoZCxzLG4qc2l6ZW9mKFRZUEUpKTsKKyAgICB9Cit9CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLyoKKyAqIGEga2V5L3ZhbHVlIHBhaXIKKyAqLworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS0VZLCB0eXBlbmFtZSBWQUxVRT4KK3N0cnVjdCBrZXlfdmFsdWVfcGFpcl90IHsKKyAgICBLRVkgICAgIGtleTsKKyAgICBWQUxVRSAgIHZhbHVlOworICAgIGtleV92YWx1ZV9wYWlyX3QoKSB7IH0KKyAgICBrZXlfdmFsdWVfcGFpcl90KGNvbnN0IGtleV92YWx1ZV9wYWlyX3QmIG8pIDoga2V5KG8ua2V5KSwgdmFsdWUoby52YWx1ZSkgeyB9CisgICAga2V5X3ZhbHVlX3BhaXJfdChjb25zdCBLRVkmIGssIGNvbnN0IFZBTFVFJiB2KSA6IGtleShrKSwgdmFsdWUodikgIHsgfQorICAgIGtleV92YWx1ZV9wYWlyX3QoY29uc3QgS0VZJiBrKSA6IGtleShrKSB7IH0KKyAgICBpbmxpbmUgYm9vbCBvcGVyYXRvciA8IChjb25zdCBrZXlfdmFsdWVfcGFpcl90JiBvKSBjb25zdCB7CisgICAgICAgIHJldHVybiBzdHJpY3RseV9vcmRlcl90eXBlKGtleSwgby5rZXkpOworICAgIH0KK307CisKK3RlbXBsYXRlPD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLLCB0eXBlbmFtZSBWPgorc3RydWN0IHRyYWl0X3RyaXZpYWxfY3Rvcjwga2V5X3ZhbHVlX3BhaXJfdDxLLCBWPiA+Cit7IGVudW0geyB2YWx1ZSA9IGFnZ3JlZ2F0ZV90cmFpdHM8SyxWPjo6aGFzX3RyaXZpYWxfY3RvciB9OyB9OwordGVtcGxhdGU8PiAKK3RlbXBsYXRlIDx0eXBlbmFtZSBLLCB0eXBlbmFtZSBWPgorc3RydWN0IHRyYWl0X3RyaXZpYWxfZHRvcjwga2V5X3ZhbHVlX3BhaXJfdDxLLCBWPiA+Cit7IGVudW0geyB2YWx1ZSA9IGFnZ3JlZ2F0ZV90cmFpdHM8SyxWPjo6aGFzX3RyaXZpYWxfZHRvciB9OyB9OwordGVtcGxhdGU8PiAKK3RlbXBsYXRlIDx0eXBlbmFtZSBLLCB0eXBlbmFtZSBWPgorc3RydWN0IHRyYWl0X3RyaXZpYWxfY29weTwga2V5X3ZhbHVlX3BhaXJfdDxLLCBWPiA+Cit7IGVudW0geyB2YWx1ZSA9IGFnZ3JlZ2F0ZV90cmFpdHM8SyxWPjo6aGFzX3RyaXZpYWxfY29weSB9OyB9OwordGVtcGxhdGU8PiAKK3RlbXBsYXRlIDx0eXBlbmFtZSBLLCB0eXBlbmFtZSBWPgorc3RydWN0IHRyYWl0X3RyaXZpYWxfYXNzaWduPCBrZXlfdmFsdWVfcGFpcl90PEssIFY+ID4KK3sgZW51bSB7IHZhbHVlID0gYWdncmVnYXRlX3RyYWl0czxLLFY+OjpoYXNfdHJpdmlhbF9hc3NpZ259O307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2VuZGlmIC8vIEFORFJPSURfVFlQRV9IRUxQRVJTX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvVmVjdG9yLmggYi9pbmNsdWRlL3V0aWxzL1ZlY3Rvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlMzY1ZDgKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL1ZlY3Rvci5oCkBAIC0wLDAgKzEsMzU5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1ZFQ1RPUl9ICisjZGVmaW5lIEFORFJPSURfVkVDVE9SX0gKKworI2luY2x1ZGUgPG5ldz4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1ZlY3RvckltcGwuaD4KKyNpbmNsdWRlIDx1dGlscy9UeXBlSGVscGVycy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKiEKKyAqIFRoZSBtYWluIHRlbXBsYXRlZCB2ZWN0b3IgY2xhc3MgZW5zdXJpbmcgdHlwZSBzYWZldHkKKyAqIHdoaWxlIG1ha2luZyB1c2Ugb2YgVmVjdG9ySW1wbC4KKyAqIFRoaXMgaXMgdGhlIGNsYXNzIHVzZXJzIHdhbnQgdG8gdXNlLgorICovCisKK3RlbXBsYXRlIDxjbGFzcyBUWVBFPgorY2xhc3MgVmVjdG9yIDogcHJpdmF0ZSBWZWN0b3JJbXBsCit7CitwdWJsaWM6CisgICAgICAgICAgICB0eXBlZGVmIFRZUEUgICAgdmFsdWVfdHlwZTsKKyAgICAKKyAgICAvKiEgCisgICAgICogQ29uc3RydWN0b3JzIGFuZCBkZXN0cnVjdG9ycworICAgICAqLworICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvcigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvcihjb25zdCBWZWN0b3I8VFlQRT4mIHJocyk7CisgICAgdmlydHVhbCAgICAgICAgICAgICAgICAgflZlY3RvcigpOworCisgICAgLyohIGNvcHkgb3BlcmF0b3IgKi8KKyAgICAgICAgICAgIGNvbnN0IFZlY3RvcjxUWVBFPiYgICAgIG9wZXJhdG9yID0gKGNvbnN0IFZlY3RvcjxUWVBFPiYgcmhzKSBjb25zdDsKKyAgICAgICAgICAgIFZlY3RvcjxUWVBFPiYgICAgICAgICAgIG9wZXJhdG9yID0gKGNvbnN0IFZlY3RvcjxUWVBFPiYgcmhzKTsgICAgCisKKyAgICAvKgorICAgICAqIGVtcHR5IHRoZSB2ZWN0b3IKKyAgICAgKi8KKworICAgIGlubGluZSAgdm9pZCAgICAgICAgICAgIGNsZWFyKCkgICAgICAgICAgICAgeyBWZWN0b3JJbXBsOjpjbGVhcigpOyB9CisKKyAgICAvKiEgCisgICAgICogdmVjdG9yIHN0YXRzCisgICAgICovCisKKyAgICAvLyEgcmV0dXJucyBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHZlY3RvcgorICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgIHNpemUoKSBjb25zdCAgICAgICAgICAgICAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpzaXplKCk7IH0KKyAgICAvLyEgcmV0dXJucyB3ZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3IgaXMgZW1wdHkKKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICBpc0VtcHR5KCkgY29uc3QgICAgICAgICAgICAgeyByZXR1cm4gVmVjdG9ySW1wbDo6aXNFbXB0eSgpOyB9CisgICAgLy8hIHJldHVybnMgaG93IG1hbnkgaXRlbXMgY2FuIGJlIHN0b3JlZCB3aXRob3V0IHJlYWxsb2NhdGluZyB0aGUgYmFja2luZyBzdG9yZQorICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgIGNhcGFjaXR5KCkgY29uc3QgICAgICAgICAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpjYXBhY2l0eSgpOyB9CisgICAgLy8hIHNldHN0IHRoZSBjYXBhY2l0eS4gY2FwYWNpdHkgY2FuIG5ldmVyIGJlIHJlZHVjZWQgbGVzcyB0aGFuIHNpemUoKQorICAgIGlubGluZSAgc3NpemVfdCAgICAgICAgIHNldENhcGFjaXR5KHNpemVfdCBzaXplKSAgICB7IHJldHVybiBWZWN0b3JJbXBsOjpzZXRDYXBhY2l0eShzaXplKTsgfQorCisgICAgLyohIAorICAgICAqIEMtc3R5bGUgYXJyYXkgYWNjZXNzCisgICAgICovCisgICAgIAorICAgIC8vISByZWFkLW9ubHkgQy1zdHlsZSBhY2Nlc3MgCisgICAgaW5saW5lICBjb25zdCBUWVBFKiAgICAgYXJyYXkoKSBjb25zdDsKKyAgICAvLyEgcmVhZC13cml0ZSBDLXN0eWxlIGFjY2VzcworICAgICAgICAgICAgVFlQRSogICAgICAgICAgIGVkaXRBcnJheSgpOworICAgIAorICAgIC8qISAKKyAgICAgKiBhY2Nlc3NvcnMKKyAgICAgKi8KKworICAgIC8vISByZWFkLW9ubHkgYWNjZXNzIHRvIGFuIGl0ZW0gYXQgYSBnaXZlbiBpbmRleAorICAgIGlubGluZSAgY29uc3QgVFlQRSYgICAgIG9wZXJhdG9yIFtdIChzaXplX3QgaW5kZXgpIGNvbnN0OworICAgIC8vISBhbHRlcm5hdGUgbmFtZSBmb3Igb3BlcmF0b3IgW10KKyAgICBpbmxpbmUgIGNvbnN0IFRZUEUmICAgICBpdGVtQXQoc2l6ZV90IGluZGV4KSBjb25zdDsKKyAgICAvLyEgc3RhY2stdXNhZ2Ugb2YgdGhlIHZlY3Rvci4gcmV0dXJucyB0aGUgdG9wIG9mIHRoZSBzdGFjayAobGFzdCBlbGVtZW50KQorICAgICAgICAgICAgY29uc3QgVFlQRSYgICAgIHRvcCgpIGNvbnN0OworICAgIC8vISBzYW1lIGFzIG9wZXJhdG9yIFtdLCBidXQgYWxsb3dzIHRvIGFjY2VzcyB0aGUgdmVjdG9yIGJhY2t3YXJkIChmcm9tIHRoZSBlbmQpIHdpdGggYSBuZWdhdGl2ZSBpbmRleAorICAgICAgICAgICAgY29uc3QgVFlQRSYgICAgIG1pcnJvckl0ZW1BdChzc2l6ZV90IGluZGV4KSBjb25zdDsKKworICAgIC8qIQorICAgICAqIG1vZGlmaW5nIHRoZSBhcnJheQorICAgICAqLworCisgICAgLy8hIGNvcHktb24gd3JpdGUgc3VwcG9ydCwgZ3JhbnRzIHdyaXRlIGFjY2VzcyB0byBhbiBpdGVtCisgICAgICAgICAgICBUWVBFJiAgICAgICAgICAgZWRpdEl0ZW1BdChzaXplX3QgaW5kZXgpOworICAgIC8vISBncmFudHMgcmlnaHQgYWNjZXMgdG8gdGhlIHRvcCBvZiB0aGUgc3RhY2sgKGxhc3QgZWxlbWVudCkKKyAgICAgICAgICAgIFRZUEUmICAgICAgICAgICBlZGl0VG9wKCk7CisKKyAgICAgICAgICAgIC8qISAKKyAgICAgICAgICAgICAqIGFwcGVuZC9pbnNlcnQgYW5vdGhlciB2ZWN0b3IKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgCisgICAgLy8hIGluc2VydCBhbm90aGVyIHZlY3RvciBhdCBhIGdpdmVuIGluZGV4CisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgaW5zZXJ0VmVjdG9yQXQoY29uc3QgVmVjdG9yPFRZUEU+JiB2ZWN0b3IsIHNpemVfdCBpbmRleCk7CisKKyAgICAvLyEgYXBwZW5kIGFub3RoZXIgdmVjdG9yIGF0IHRoZSBlbmQgb2YgdGhpcyBvbmUKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBhcHBlbmRWZWN0b3IoY29uc3QgVmVjdG9yPFRZUEU+JiB2ZWN0b3IpOworCisKKyAgICAgICAgICAgIC8qISAKKyAgICAgICAgICAgICAqIGFkZC9pbnNlcnQvcmVwbGFjZSBpdGVtcworICAgICAgICAgICAgICovCisgICAgICAgICAgICAgCisgICAgLy8hIGluc2VydCBvbmUgb3Igc2V2ZXJhbCBpdGVtcyBpbml0aWFsaXplZCB3aXRoIHRoZWlyIGRlZmF1bHQgY29uc3RydWN0b3IKKyAgICBpbmxpbmUgIHNzaXplX3QgICAgICAgICBpbnNlcnRBdChzaXplX3QgaW5kZXgsIHNpemVfdCBudW1JdGVtcyA9IDEpOworICAgIC8vISBpbnNlcnQgb24gb25yIHNldmVyYWwgaXRlbXMgaW5pdGlhbGl6ZWQgZnJvbSBhIHByb3RvdHlwZSBpdGVtCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgaW5zZXJ0QXQoY29uc3QgVFlQRSYgcHJvdG90eXBlX2l0ZW0sIHNpemVfdCBpbmRleCwgc2l6ZV90IG51bUl0ZW1zID0gMSk7CisgICAgLy8hIHBvcCB0aGUgdG9wIG9mIHRoZSBzdGFjayAocmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50KS4gTm8tb3AgaWYgdGhlIHN0YWNrJ3MgZW1wdHkKKyAgICBpbmxpbmUgIHZvaWQgICAgICAgICAgICBwb3AoKTsKKyAgICAvLyEgcHVzaGVzIGFuIGl0ZW0gaW5pdGlhbGl6ZWQgd2l0aCBpdHMgZGVmYXVsdCBjb25zdHJ1Y3RvcgorICAgIGlubGluZSAgdm9pZCAgICAgICAgICAgIHB1c2goKTsKKyAgICAvLyEgcHVzaGVzIGFuIGl0ZW0gb24gdGhlIHRvcCBvZiB0aGUgc3RhY2sKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICBwdXNoKGNvbnN0IFRZUEUmIGl0ZW0pOworICAgIC8vISBzYW1lIGFzIHB1c2goKSBidXQgcmV0dXJucyB0aGUgaW5kZXggdGhlIGl0ZW0gd2FzIGFkZGVkIGF0IChvciBhbiBlcnJvcikKKyAgICBpbmxpbmUgIHNzaXplX3QgICAgICAgICBhZGQoKTsKKyAgICAvLyEgc2FtZSBhcyBwdXNoKCkgYnV0IHJldHVybnMgdGhlIGluZGV4IHRoZSBpdGVtIHdhcyBhZGRlZCBhdCAob3IgYW4gZXJyb3IpCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgYWRkKGNvbnN0IFRZUEUmIGl0ZW0pOyAgICAgICAgICAgIAorICAgIC8vISByZXBsYWNlIGFuIGl0ZW0gd2l0aCBhIG5ldyBvbmUgaW5pdGlhbGl6ZWQgd2l0aCBpdHMgZGVmYXVsdCBjb25zdHJ1Y3RvcgorICAgIGlubGluZSAgc3NpemVfdCAgICAgICAgIHJlcGxhY2VBdChzaXplX3QgaW5kZXgpOworICAgIC8vISByZXBsYWNlIGFuIGl0ZW0gd2l0aCBhIG5ldyBvbmUKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZXBsYWNlQXQoY29uc3QgVFlQRSYgaXRlbSwgc2l6ZV90IGluZGV4KTsKKworICAgIC8qIQorICAgICAqIHJlbW92ZSBpdGVtcworICAgICAqLworCisgICAgLy8hIHJlbW92ZSBzZXZlcmFsIGl0ZW1zCisgICAgaW5saW5lICBzc2l6ZV90ICAgICAgICAgcmVtb3ZlSXRlbXNBdChzaXplX3QgaW5kZXgsIHNpemVfdCBjb3VudCA9IDEpOworICAgIC8vISByZW1vdmUgb25lIGl0ZW0KKyAgICBpbmxpbmUgIHNzaXplX3QgICAgICAgICByZW1vdmVBdChzaXplX3QgaW5kZXgpICB7IHJldHVybiByZW1vdmVJdGVtc0F0KGluZGV4KTsgfQorCisgICAgLyohCisgICAgICogc29ydCAoc3RhYmxlKSB0aGUgYXJyYXkKKyAgICAgKi8KKyAgICAgCisgICAgIHR5cGVkZWYgaW50ICgqY29tcGFyX3QpKGNvbnN0IFRZUEUqIGxocywgY29uc3QgVFlQRSogcmhzKTsKKyAgICAgdHlwZWRlZiBpbnQgKCpjb21wYXJfcl90KShjb25zdCBUWVBFKiBsaHMsIGNvbnN0IFRZUEUqIHJocywgdm9pZCogc3RhdGUpOworICAgICAKKyAgICAgaW5saW5lIHN0YXR1c190ICAgICAgICBzb3J0KGNvbXBhcl90IGNtcCk7CisgICAgIGlubGluZSBzdGF0dXNfdCAgICAgICAgc29ydChjb21wYXJfcl90IGNtcCwgdm9pZCogc3RhdGUpOworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCB2b2lkICAgIGRvX2NvbnN0cnVjdCh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fZGVzdHJveSh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fY29weSh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fc3BsYXQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogaXRlbSwgc2l6ZV90IG51bSkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkICAgIGRvX21vdmVfZm9yd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgZG9fbW92ZV9iYWNrd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdDsKK307CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBObyB1c2VyIHNlcnZpY2VhYmxlIHBhcnRzIGZyb20gaGVyZS4uLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorVmVjdG9yPFRZUEU+OjpWZWN0b3IoKQorICAgIDogVmVjdG9ySW1wbChzaXplb2YoVFlQRSksCisgICAgICAgICAgICAgICAgKCh0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2N0b3IgICA/IEhBU19UUklWSUFMX0NUT1IgICA6IDApCisgICAgICAgICAgICAgICAgfCh0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2R0b3IgICA/IEhBU19UUklWSUFMX0RUT1IgICA6IDApCisgICAgICAgICAgICAgICAgfCh0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2NvcHkgICA/IEhBU19UUklWSUFMX0NPUFkgICA6IDApCisgICAgICAgICAgICAgICAgfCh0cmFpdHM8VFlQRT46Omhhc190cml2aWFsX2Fzc2lnbiA/IEhBU19UUklWSUFMX0FTU0lHTiA6IDApKQorICAgICAgICAgICAgICAgICkKK3sKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitWZWN0b3I8VFlQRT46OlZlY3Rvcihjb25zdCBWZWN0b3I8VFlQRT4mIHJocykKKyAgICA6IFZlY3RvckltcGwocmhzKSB7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorVmVjdG9yPFRZUEU+Ojp+VmVjdG9yKCkgeworICAgIGZpbmlzaF92ZWN0b3IoKTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitWZWN0b3I8VFlQRT4mIFZlY3RvcjxUWVBFPjo6b3BlcmF0b3IgPSAoY29uc3QgVmVjdG9yPFRZUEU+JiByaHMpIHsKKyAgICBWZWN0b3JJbXBsOjpvcGVyYXRvciA9IChyaHMpOworICAgIHJldHVybiAqdGhpczsgCit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorY29uc3QgVmVjdG9yPFRZUEU+JiBWZWN0b3I8VFlQRT46Om9wZXJhdG9yID0gKGNvbnN0IFZlY3RvcjxUWVBFPiYgcmhzKSBjb25zdCB7CisgICAgVmVjdG9ySW1wbDo6b3BlcmF0b3IgPSAocmhzKTsKKyAgICByZXR1cm4gKnRoaXM7IAorfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK2NvbnN0IFRZUEUqIFZlY3RvcjxUWVBFPjo6YXJyYXkoKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbnN0IFRZUEUgKj4oYXJyYXlJbXBsKCkpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK1RZUEUqIFZlY3RvcjxUWVBFPjo6ZWRpdEFycmF5KCkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUWVBFICo+KGVkaXRBcnJheUltcGwoKSk7Cit9CisKKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitjb25zdCBUWVBFJiBWZWN0b3I8VFlQRT46Om9wZXJhdG9yW10oc2l6ZV90IGluZGV4KSBjb25zdCB7CisgICAgTE9HX0ZBVEFMX0lGKCBpbmRleD49c2l6ZSgpLAorICAgICAgICAgICAgICAgICAgIml0ZW1BdDogaW5kZXggJWQgaXMgcGFzdCBzaXplICVkIiwgKGludClpbmRleCwgKGludClzaXplKCkgKTsKKyAgICByZXR1cm4gKihhcnJheSgpICsgaW5kZXgpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK2NvbnN0IFRZUEUmIFZlY3RvcjxUWVBFPjo6aXRlbUF0KHNpemVfdCBpbmRleCkgY29uc3QgeworICAgIHJldHVybiBvcGVyYXRvcltdKGluZGV4KTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitjb25zdCBUWVBFJiBWZWN0b3I8VFlQRT46Om1pcnJvckl0ZW1BdChzc2l6ZV90IGluZGV4KSBjb25zdCB7CisgICAgTE9HX0ZBVEFMX0lGKCAoaW5kZXg+MCA/IGluZGV4IDogLWluZGV4KT49c2l6ZSgpLAorICAgICAgICAgICAgICAgICAgIm1pcnJvckl0ZW1BdDogaW5kZXggJWQgaXMgcGFzdCBzaXplICVkIiwKKyAgICAgICAgICAgICAgICAgIChpbnQpaW5kZXgsIChpbnQpc2l6ZSgpICk7CisgICAgcmV0dXJuICooYXJyYXkoKSArICgoaW5kZXg8MCkgPyAoc2l6ZSgpLWluZGV4KSA6IGluZGV4KSk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorY29uc3QgVFlQRSYgVmVjdG9yPFRZUEU+Ojp0b3AoKSBjb25zdCB7CisgICAgcmV0dXJuICooYXJyYXkoKSArIHNpemUoKSAtIDEpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK1RZUEUmIFZlY3RvcjxUWVBFPjo6ZWRpdEl0ZW1BdChzaXplX3QgaW5kZXgpIHsKKyAgICByZXR1cm4gKiggc3RhdGljX2Nhc3Q8VFlQRSAqPihlZGl0SXRlbUxvY2F0aW9uKGluZGV4KSkgKTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCitUWVBFJiBWZWN0b3I8VFlQRT46OmVkaXRUb3AoKSB7CisgICAgcmV0dXJuICooIHN0YXRpY19jYXN0PFRZUEUgKj4oZWRpdEl0ZW1Mb2NhdGlvbihzaXplKCktMSkpICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorc3NpemVfdCBWZWN0b3I8VFlQRT46Omluc2VydFZlY3RvckF0KGNvbnN0IFZlY3RvcjxUWVBFPiYgdmVjdG9yLCBzaXplX3QgaW5kZXgpIHsKKyAgICByZXR1cm4gVmVjdG9ySW1wbDo6aW5zZXJ0VmVjdG9yQXQocmVpbnRlcnByZXRfY2FzdDxjb25zdCBWZWN0b3JJbXBsJj4odmVjdG9yKSwgaW5kZXgpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjphcHBlbmRWZWN0b3IoY29uc3QgVmVjdG9yPFRZUEU+JiB2ZWN0b3IpIHsKKyAgICByZXR1cm4gVmVjdG9ySW1wbDo6YXBwZW5kVmVjdG9yKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgVmVjdG9ySW1wbCY+KHZlY3RvcikpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjppbnNlcnRBdChjb25zdCBUWVBFJiBpdGVtLCBzaXplX3QgaW5kZXgsIHNpemVfdCBudW1JdGVtcykgeworICAgIHJldHVybiBWZWN0b3JJbXBsOjppbnNlcnRBdCgmaXRlbSwgaW5kZXgsIG51bUl0ZW1zKTsKK30KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gaW5saW5lCit2b2lkIFZlY3RvcjxUWVBFPjo6cHVzaChjb25zdCBUWVBFJiBpdGVtKSB7CisgICAgcmV0dXJuIFZlY3RvckltcGw6OnB1c2goJml0ZW0pOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjphZGQoY29uc3QgVFlQRSYgaXRlbSkgeworICAgIHJldHVybiBWZWN0b3JJbXBsOjphZGQoJml0ZW0pOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjpyZXBsYWNlQXQoY29uc3QgVFlQRSYgaXRlbSwgc2l6ZV90IGluZGV4KSB7CisgICAgcmV0dXJuIFZlY3RvckltcGw6OnJlcGxhY2VBdCgmaXRlbSwgaW5kZXgpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjppbnNlcnRBdChzaXplX3QgaW5kZXgsIHNpemVfdCBudW1JdGVtcykgeworICAgIHJldHVybiBWZWN0b3JJbXBsOjppbnNlcnRBdChpbmRleCwgbnVtSXRlbXMpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3ZvaWQgVmVjdG9yPFRZUEU+Ojpwb3AoKSB7CisgICAgVmVjdG9ySW1wbDo6cG9wKCk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQordm9pZCBWZWN0b3I8VFlQRT46OnB1c2goKSB7CisgICAgVmVjdG9ySW1wbDo6cHVzaCgpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjphZGQoKSB7CisgICAgcmV0dXJuIFZlY3RvckltcGw6OmFkZCgpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3NzaXplX3QgVmVjdG9yPFRZUEU+OjpyZXBsYWNlQXQoc2l6ZV90IGluZGV4KSB7CisgICAgcmV0dXJuIFZlY3RvckltcGw6OnJlcGxhY2VBdChpbmRleCk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+IGlubGluZQorc3NpemVfdCBWZWN0b3I8VFlQRT46OnJlbW92ZUl0ZW1zQXQoc2l6ZV90IGluZGV4LCBzaXplX3QgY291bnQpIHsKKyAgICByZXR1cm4gVmVjdG9ySW1wbDo6cmVtb3ZlSXRlbXNBdChpbmRleCwgY291bnQpOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3N0YXR1c190IFZlY3RvcjxUWVBFPjo6c29ydChWZWN0b3I8VFlQRT46OmNvbXBhcl90IGNtcCkgeworICAgIHJldHVybiBWZWN0b3JJbXBsOjpzb3J0KChWZWN0b3JJbXBsOjpjb21wYXJfdCljbXApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBpbmxpbmUKK3N0YXR1c190IFZlY3RvcjxUWVBFPjo6c29ydChWZWN0b3I8VFlQRT46OmNvbXBhcl9yX3QgY21wLCB2b2lkKiBzdGF0ZSkgeworICAgIHJldHVybiBWZWN0b3JJbXBsOjpzb3J0KChWZWN0b3JJbXBsOjpjb21wYXJfcl90KWNtcCwgc3RhdGUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4KK3ZvaWQgVmVjdG9yPFRZUEU+Ojpkb19jb25zdHJ1Y3Qodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QgeworICAgIGNvbnN0cnVjdF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihzdG9yYWdlKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFZlY3RvcjxUWVBFPjo6ZG9fZGVzdHJveSh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgZGVzdHJveV90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihzdG9yYWdlKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFZlY3RvcjxUWVBFPjo6ZG9fY29weSh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgY29weV90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oZnJvbSksIG51bSApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPgordm9pZCBWZWN0b3I8VFlQRT46OmRvX3NwbGF0KHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCBudW0pIGNvbnN0IHsKKyAgICBzcGxhdF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oaXRlbSksIG51bSApOworfQorCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPgordm9pZCBWZWN0b3I8VFlQRT46OmRvX21vdmVfZm9yd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgbW92ZV9mb3J3YXJkX3R5cGUoIHJlaW50ZXJwcmV0X2Nhc3Q8VFlQRSo+KGRlc3QpLCByZWludGVycHJldF9jYXN0PGNvbnN0IFRZUEUqPihmcm9tKSwgbnVtICk7Cit9CisKK3RlbXBsYXRlPGNsYXNzIFRZUEU+Cit2b2lkIFZlY3RvcjxUWVBFPjo6ZG9fbW92ZV9iYWNrd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgbW92ZV9iYWNrd2FyZF90eXBlKCByZWludGVycHJldF9jYXN0PFRZUEUqPihkZXN0KSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oZnJvbSksIG51bSApOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9WRUNUT1JfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9WZWN0b3JJbXBsLmggYi9pbmNsdWRlL3V0aWxzL1ZlY3RvckltcGwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNTI1MjI5Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9WZWN0b3JJbXBsLmgKQEAgLTAsMCArMSwxOTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfVkVDVE9SX0lNUExfSAorI2RlZmluZSBBTkRST0lEX1ZFQ1RPUl9JTVBMX0gKKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vIHVzZXIgc2VydmljZWFibGUgcGFydHMgaW4gaGVyZS4uLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyohCisgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgZ3V0cyBvZiB0aGUgdmVjdG9yPD4gY2xhc3MKKyAqIHRoaXMgZW5zdXJlcyBiYWNrd2FyZCBiaW5hcnkgY29tcGF0aWJpbGl0eSBhbmQKKyAqIHJlZHVjZXMgY29kZSBzaXplLgorICogRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMsIHdlIGV4cG9zZSBtU3RvcmFnZSBhbmQgbUNvdW50CisgKiBzbyB0aGVzZSBmaWVsZHMgYXJlIHNldCBpbiBzdG9uZS4KKyAqCisgKi8KKworY2xhc3MgVmVjdG9ySW1wbAoreworcHVibGljOgorICAgIGVudW0geyAvLyBmbGFncyBwYXNzZWQgdG8gdGhlIGN0b3IKKyAgICAgICAgSEFTX1RSSVZJQUxfQ1RPUiAgICA9IDB4MDAwMDAwMDEsCisgICAgICAgIEhBU19UUklWSUFMX0RUT1IgICAgPSAweDAwMDAwMDAyLAorICAgICAgICBIQVNfVFJJVklBTF9DT1BZICAgID0gMHgwMDAwMDAwNCwKKyAgICAgICAgSEFTX1RSSVZJQUxfQVNTSUdOICA9IDB4MDAwMDAwMDgKKyAgICB9OworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9ySW1wbChzaXplX3QgaXRlbVNpemUsIHVpbnQzMl90IGZsYWdzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JJbXBsKGNvbnN0IFZlY3RvckltcGwmIHJocyk7CisgICAgdmlydHVhbCAgICAgICAgICAgICAgICAgflZlY3RvckltcGwoKTsKKworICAgIC8qISBtdXN0IGJlIGNhbGxlZCBmcm9tIHN1YmNsYXNzZXMgZGVzdHJ1Y3RvciAqLworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIGZpbmlzaF92ZWN0b3IoKTsKKworICAgICAgICAgICAgVmVjdG9ySW1wbCYgICAgIG9wZXJhdG9yID0gKGNvbnN0IFZlY3RvckltcGwmIHJocyk7ICAgIAorICAgICAgICAgICAgCisgICAgLyohIEMtc3R5bGUgYXJyYXkgYWNjZXNzICovCisgICAgaW5saW5lICBjb25zdCB2b2lkKiAgICAgYXJyYXlJbXBsKCkgY29uc3QgICAgICAgeyByZXR1cm4gbVN0b3JhZ2U7IH0KKyAgICAgICAgICAgIHZvaWQqICAgICAgICAgICBlZGl0QXJyYXlJbXBsKCk7CisgICAgICAgICAgICAKKyAgICAvKiEgdmVjdG9yIHN0YXRzICovCisgICAgaW5saW5lICBzaXplX3QgICAgICAgICAgc2l6ZSgpIGNvbnN0ICAgICAgICB7IHJldHVybiBtQ291bnQ7IH0KKyAgICBpbmxpbmUgIGJvb2wgICAgICAgICAgICBpc0VtcHR5KCkgY29uc3QgICAgIHsgcmV0dXJuIG1Db3VudCA9PSAwOyB9CisgICAgICAgICAgICBzaXplX3QgICAgICAgICAgY2FwYWNpdHkoKSBjb25zdDsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBzZXRDYXBhY2l0eShzaXplX3Qgc2l6ZSk7CisKKyAgICAgICAgICAgIC8qISBhcHBlbmQvaW5zZXJ0IGFub3RoZXIgdmVjdG9yICovCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgaW5zZXJ0VmVjdG9yQXQoY29uc3QgVmVjdG9ySW1wbCYgdmVjdG9yLCBzaXplX3QgaW5kZXgpOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFwcGVuZFZlY3Rvcihjb25zdCBWZWN0b3JJbXBsJiB2ZWN0b3IpOworICAgICAgICAgICAgCisgICAgICAgICAgICAvKiEgYWRkL2luc2VydC9yZXBsYWNlIGl0ZW1zICovCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgaW5zZXJ0QXQoc2l6ZV90IHdoZXJlLCBzaXplX3QgbnVtSXRlbXMgPSAxKTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBpbnNlcnRBdChjb25zdCB2b2lkKiBpdGVtLCBzaXplX3Qgd2hlcmUsIHNpemVfdCBudW1JdGVtcyA9IDEpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIHBvcCgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIHB1c2goKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICBwdXNoKGNvbnN0IHZvaWQqIGl0ZW0pOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZCgpOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZChjb25zdCB2b2lkKiBpdGVtKTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZXBsYWNlQXQoc2l6ZV90IGluZGV4KTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICByZXBsYWNlQXQoY29uc3Qgdm9pZCogaXRlbSwgc2l6ZV90IGluZGV4KTsKKworICAgICAgICAgICAgLyohIHJlbW92ZSBpdGVtcyAqLworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIHJlbW92ZUl0ZW1zQXQoc2l6ZV90IGluZGV4LCBzaXplX3QgY291bnQgPSAxKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICBjbGVhcigpOworCisgICAgICAgICAgICBjb25zdCB2b2lkKiAgICAgaXRlbUxvY2F0aW9uKHNpemVfdCBpbmRleCkgY29uc3Q7CisgICAgICAgICAgICB2b2lkKiAgICAgICAgICAgZWRpdEl0ZW1Mb2NhdGlvbihzaXplX3QgaW5kZXgpOworCisgICAgICAgICAgICB0eXBlZGVmIGludCAoKmNvbXBhcl90KShjb25zdCB2b2lkKiBsaHMsIGNvbnN0IHZvaWQqIHJocyk7CisgICAgICAgICAgICB0eXBlZGVmIGludCAoKmNvbXBhcl9yX3QpKGNvbnN0IHZvaWQqIGxocywgY29uc3Qgdm9pZCogcmhzLCB2b2lkKiBzdGF0ZSk7CisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgc29ydChjb21wYXJfdCBjbXApOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgIHNvcnQoY29tcGFyX3JfdCBjbXAsIHZvaWQqIHN0YXRlKTsKKworcHJvdGVjdGVkOgorICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGl0ZW1TaXplKCkgY29uc3Q7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgcmVsZWFzZV9zdG9yYWdlKCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBkb19jb25zdHJ1Y3Qodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGRvX2Rlc3Ryb3kodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGRvX2NvcHkodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogZnJvbSwgc2l6ZV90IG51bSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGRvX3NwbGF0KHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCBudW0pIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICBkb19tb3ZlX2ZvcndhcmQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogZnJvbSwgc2l6ZV90IG51bSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIGRvX21vdmVfYmFja3dhcmQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogZnJvbSwgc2l6ZV90IG51bSkgY29uc3QgPSAwOworCisgICAgLy8gdGFrZSBjYXJlIG9mIEZCQy4uLgorICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkVmVjdG9ySW1wbDEoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZXNlcnZlZFZlY3RvckltcGwyKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVzZXJ2ZWRWZWN0b3JJbXBsMygpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkVmVjdG9ySW1wbDQoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZXNlcnZlZFZlY3RvckltcGw1KCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVzZXJ2ZWRWZWN0b3JJbXBsNigpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkVmVjdG9ySW1wbDcoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZXNlcnZlZFZlY3RvckltcGw4KCk7CisgICAgCitwcml2YXRlOgorICAgICAgICB2b2lkKiBfZ3JvdyhzaXplX3Qgd2hlcmUsIHNpemVfdCBhbW91bnQpOworICAgICAgICB2b2lkICBfc2hyaW5rKHNpemVfdCB3aGVyZSwgc2l6ZV90IGFtb3VudCk7CisKKyAgICAgICAgaW5saW5lIHZvaWQgX2RvX2NvbnN0cnVjdCh2b2lkKiBzdG9yYWdlLCBzaXplX3QgbnVtKSBjb25zdDsKKyAgICAgICAgaW5saW5lIHZvaWQgX2RvX2Rlc3Ryb3kodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3Q7CisgICAgICAgIGlubGluZSB2b2lkIF9kb19jb3B5KHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGZyb20sIHNpemVfdCBudW0pIGNvbnN0OworICAgICAgICBpbmxpbmUgdm9pZCBfZG9fc3BsYXQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogaXRlbSwgc2l6ZV90IG51bSkgY29uc3Q7CisgICAgICAgIGlubGluZSB2b2lkIF9kb19tb3ZlX2ZvcndhcmQodm9pZCogZGVzdCwgY29uc3Qgdm9pZCogZnJvbSwgc2l6ZV90IG51bSkgY29uc3Q7CisgICAgICAgIGlubGluZSB2b2lkIF9kb19tb3ZlX2JhY2t3YXJkKHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGZyb20sIHNpemVfdCBudW0pIGNvbnN0OworCisgICAgICAgICAgICAvLyBUaGVzZSAyIGZpZWxkcyBhcmUgZXhwb3NlZCBpbiB0aGUgaW5saW5lcyBiZWxvdywKKyAgICAgICAgICAgIC8vIHNvIHRoZXkncmUgc2V0IGluIHN0b25lLgorICAgICAgICAgICAgdm9pZCAqICAgICAgbVN0b3JhZ2U7ICAgLy8gYmFzZSBhZGRyZXNzIG9mIHRoZSB2ZWN0b3IKKyAgICAgICAgICAgIHNpemVfdCAgICAgIG1Db3VudDsgICAgIC8vIG51bWJlciBvZiBpdGVtcworCisgICAgY29uc3QgICB1aW50MzJfdCAgICBtRmxhZ3M7CisgICAgY29uc3QgICBzaXplX3QgICAgICBtSXRlbVNpemU7Cit9OworCisKKworY2xhc3MgU29ydGVkVmVjdG9ySW1wbCA6IHB1YmxpYyBWZWN0b3JJbXBsCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9ySW1wbChzaXplX3QgaXRlbVNpemUsIHVpbnQzMl90IGZsYWdzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3J0ZWRWZWN0b3JJbXBsKGNvbnN0IFZlY3RvckltcGwmIHJocyk7CisgICAgdmlydHVhbCAgICAgICAgICAgICAgICAgflNvcnRlZFZlY3RvckltcGwoKTsKKyAgICAKKyAgICBTb3J0ZWRWZWN0b3JJbXBsJiAgICAgb3BlcmF0b3IgPSAoY29uc3QgU29ydGVkVmVjdG9ySW1wbCYgcmhzKTsgICAgCisKKyAgICAvLyEgZmluZHMgdGhlIGluZGV4IG9mIGFuIGl0ZW0KKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBpbmRleE9mKGNvbnN0IHZvaWQqIGl0ZW0pIGNvbnN0OworCisgICAgLy8hIGZpbmRzIHdoZXJlIHRoaXMgaXRlbSBzaG91bGQgYmUgaW5zZXJ0ZWQKKyAgICAgICAgICAgIHNpemVfdCAgICAgICAgICBvcmRlck9mKGNvbnN0IHZvaWQqIGl0ZW0pIGNvbnN0OworCisgICAgLy8hIGFkZCBhbiBpdGVtIGluIHRoZSByaWdodCBwbGFjZSAob3IgcmVwbGFjZXMgaXQgaWYgdGhlcmUgaXMgb25lKQorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZChjb25zdCB2b2lkKiBpdGVtKTsKKworICAgIC8vISBtZXJnZXMgYSB2ZWN0b3IgaW50byB0aGlzIG9uZQorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIG1lcmdlKGNvbnN0IFZlY3RvckltcGwmIHZlY3Rvcik7CisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgbWVyZ2UoY29uc3QgU29ydGVkVmVjdG9ySW1wbCYgdmVjdG9yKTsKKyAgICAgICAgICAgICAKKyAgICAvLyEgcmVtb3ZlcyBhbiBpdGVtCisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgcmVtb3ZlKGNvbnN0IHZvaWQqIGl0ZW0pOworICAgICAgICAKK3Byb3RlY3RlZDoKKyAgICB2aXJ0dWFsIGludCAgICAgICAgICAgICBkb19jb21wYXJlKGNvbnN0IHZvaWQqIGxocywgY29uc3Qgdm9pZCogcmhzKSBjb25zdCA9IDA7CisKKyAgICAvLyB0YWtlIGNhcmUgb2YgRkJDLi4uCisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVzZXJ2ZWRTb3J0ZWRWZWN0b3JJbXBsMSgpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkU29ydGVkVmVjdG9ySW1wbDIoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZXNlcnZlZFNvcnRlZFZlY3RvckltcGwzKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVzZXJ2ZWRTb3J0ZWRWZWN0b3JJbXBsNCgpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkU29ydGVkVmVjdG9ySW1wbDUoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICByZXNlcnZlZFNvcnRlZFZlY3RvckltcGw2KCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICAgICAgcmVzZXJ2ZWRTb3J0ZWRWZWN0b3JJbXBsNygpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgIHJlc2VydmVkU29ydGVkVmVjdG9ySW1wbDgoKTsKKworcHJpdmF0ZToKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBfaW5kZXhPcmRlck9mKGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCogb3JkZXIgPSAwKSBjb25zdDsKKworICAgICAgICAgICAgLy8gdGhlc2UgYXJlIG1hZGUgcHJpdmF0ZSwgYmVjYXVzZSB0aGV5IGNhbid0IGJlIHVzZWQgb24gYSBTb3J0ZWRWZWN0b3IKKyAgICAgICAgICAgIC8vICh0aGV5IGRvbid0IGhhdmUgYW4gaW1wbGVtZW50YXRpb24gZWl0aGVyKQorICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGFkZCgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIHBvcCgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIHB1c2goKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICBwdXNoKGNvbnN0IHZvaWQqIGl0ZW0pOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGluc2VydFZlY3RvckF0KGNvbnN0IFZlY3RvckltcGwmIHZlY3Rvciwgc2l6ZV90IGluZGV4KTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBhcHBlbmRWZWN0b3IoY29uc3QgVmVjdG9ySW1wbCYgdmVjdG9yKTsKKyAgICAgICAgICAgIHNzaXplX3QgICAgICAgICBpbnNlcnRBdChzaXplX3Qgd2hlcmUsIHNpemVfdCBudW1JdGVtcyA9IDEpOworICAgICAgICAgICAgc3NpemVfdCAgICAgICAgIGluc2VydEF0KGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCB3aGVyZSwgc2l6ZV90IG51bUl0ZW1zID0gMSk7CisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgcmVwbGFjZUF0KHNpemVfdCBpbmRleCk7CisgICAgICAgICAgICBzc2l6ZV90ICAgICAgICAgcmVwbGFjZUF0KGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCBpbmRleCk7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLy8gQU5EUk9JRF9WRUNUT1JfSU1QTF9ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL1ppcEVudHJ5LmggYi9pbmNsdWRlL3V0aWxzL1ppcEVudHJ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQ2OThkZgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvWmlwRW50cnkuaApAQCAtMCwwICsxLDM0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBaaXAgYXJjaGl2ZSBlbnRyaWVzLgorLy8KKy8vIFRoZSBaaXBFbnRyeSBjbGFzcyBpcyB0aWdodGx5IG1lc2hlZCB3aXRoIHRoZSBaaXBGaWxlIGNsYXNzLgorLy8KKyNpZm5kZWYgX19MSUJTX1pJUEVOVFJZX0gKKyNkZWZpbmUgX19MSUJTX1pJUEVOVFJZX0gKKworI2luY2x1ZGUgIkVycm9ycy5oIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBaaXBGaWxlOworCisvKgorICogWmlwRW50cnkgb2JqZWN0cyByZXByZXNlbnQgYSBzaW5nbGUgZW50cnkgaW4gYSBaaXAgYXJjaGl2ZS4KKyAqCisgKiBZb3UgY2FuIHVzZSBvbmUgb2YgdGhlc2UgdG8gZ2V0IG9yIHNldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBlbnRyeSwgYnV0CisgKiB0aGVyZSBhcmUgbm8gZnVuY3Rpb25zIGhlcmUgZm9yIGFjY2Vzc2luZyB0aGUgZGF0YSBpdHNlbGYuICAoV2UgY291bGQKKyAqIHR1Y2sgYSBwb2ludGVyIHRvIHRoZSBaaXBGaWxlIGluIGhlcmUgZm9yIGNvbnZlbmllbmNlLCBidXQgdGhhdCByYWlzZXMKKyAqIHRoZSBsaWtlbGlob29kIG9mIHVzaW5nIFppcEVudHJ5IG9iamVjdHMgYWZ0ZXIgZGlzY2FyZGluZyB0aGUgWmlwRmlsZS4pCisgKgorICogRmlsZSBpbmZvcm1hdGlvbiBpcyBzdG9yZWQgaW4gdHdvIHBsYWNlczogbmV4dCB0byB0aGUgZmlsZSBkYXRhICh0aGUgTG9jYWwKKyAqIEZpbGUgSGVhZGVyLCBhbmQgcG9zc2libHkgYSBEYXRhIERlc2NyaXB0b3IpLCBhbmQgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZQorICogKHRoZSBDZW50cmFsIERpcmVjdG9yeSBFbnRyeSkuICBUaGUgdHdvIG11c3QgYmUga2VwdCBpbiBzeW5jLgorICovCitjbGFzcyBaaXBFbnRyeSB7CitwdWJsaWM6CisgICAgZnJpZW5kIGNsYXNzIFppcEZpbGU7CisKKyAgICBaaXBFbnRyeSh2b2lkKQorICAgICAgICA6IG1EZWxldGVkKGZhbHNlKSwgbU1hcmtlZChmYWxzZSkKKyAgICAgICAge30KKyAgICB+WmlwRW50cnkodm9pZCkge30KKworICAgIC8qCisgICAgICogUmV0dXJucyAidHJ1ZSIgaWYgdGhlIGRhdGEgaXMgY29tcHJlc3NlZC4KKyAgICAgKi8KKyAgICBib29sIGlzQ29tcHJlc3NlZCh2b2lkKSBjb25zdCB7CisgICAgICAgIHJldHVybiBtQ0RFLm1Db21wcmVzc2lvbk1ldGhvZCAhPSBrQ29tcHJlc3NTdG9yZWQ7CisgICAgfQorICAgIGludCBnZXRDb21wcmVzc2lvbk1ldGhvZCh2b2lkKSBjb25zdCB7IHJldHVybiBtQ0RFLm1Db21wcmVzc2lvbk1ldGhvZDsgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIHVuY29tcHJlc3NlZCBsZW5ndGguCisgICAgICovCisgICAgb2ZmX3QgZ2V0VW5jb21wcmVzc2VkTGVuKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1DREUubVVuY29tcHJlc3NlZFNpemU7IH0KKworICAgIC8qCisgICAgICogUmV0dXJuIHRoZSBjb21wcmVzc2VkIGxlbmd0aC4gIEZvciB1bmNvbXByZXNzZWQgZGF0YSwgdGhpcyByZXR1cm5zCisgICAgICogdGhlIHNhbWUgdGhpbmcgYXMgZ2V0VW5jb21wcmVzZXNkTGVuKCkuCisgICAgICovCisgICAgb2ZmX3QgZ2V0Q29tcHJlc3NlZExlbih2b2lkKSBjb25zdCB7IHJldHVybiBtQ0RFLm1Db21wcmVzc2VkU2l6ZTsgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIGFic29sdXRlIGZpbGUgb2Zmc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgY29tcHJlc3NlZCBvcgorICAgICAqIHVuY29tcHJlc3NlZCBkYXRhLgorICAgICAqLworICAgIG9mZl90IGdldEZpbGVPZmZzZXQodm9pZCkgY29uc3QgeworICAgICAgICByZXR1cm4gbUNERS5tTG9jYWxIZWFkZXJSZWxPZmZzZXQgKworICAgICAgICAgICAgICAgIExvY2FsRmlsZUhlYWRlcjo6a0xGSExlbiArCisgICAgICAgICAgICAgICAgbUxGSC5tRmlsZU5hbWVMZW5ndGggKworICAgICAgICAgICAgICAgIG1MRkgubUV4dHJhRmllbGRMZW5ndGg7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIGRhdGEgQ1JDLgorICAgICAqLworICAgIHVuc2lnbmVkIGxvbmcgZ2V0Q1JDMzIodm9pZCkgY29uc3QgeyByZXR1cm4gbUNERS5tQ1JDMzI7IH0KKworICAgIC8qCisgICAgICogUmV0dXJuIGZpbGUgbW9kaWZpY2F0aW9uIHRpbWUgaW4gVU5JWCBzZWNvbmRzLXNpbmNlLWVwb2NoLgorICAgICAqLworICAgIHRpbWVfdCBnZXRNb2RXaGVuKHZvaWQpIGNvbnN0OworCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIGFyY2hpdmVkIGZpbGUgbmFtZS4KKyAgICAgKi8KKyAgICBjb25zdCBjaGFyKiBnZXRGaWxlTmFtZSh2b2lkKSBjb25zdCB7IHJldHVybiAoY29uc3QgY2hhciopIG1DREUubUZpbGVOYW1lOyB9CisKKyAgICAvKgorICAgICAqIEFwcGxpY2F0aW9uLWRlZmluZWQgIm1hcmsiLiAgQ2FuIGJlIHVzZWZ1bCB3aGVuIHN5bmNocm9uaXppbmcgdGhlCisgICAgICogY29udGVudHMgb2YgYW4gYXJjaGl2ZSB3aXRoIGNvbnRlbnRzIG9uIGRpc2suCisgICAgICovCisgICAgYm9vbCBnZXRNYXJrZWQodm9pZCkgY29uc3QgeyByZXR1cm4gbU1hcmtlZDsgfQorICAgIHZvaWQgc2V0TWFya2VkKGJvb2wgdmFsKSB7IG1NYXJrZWQgPSB2YWw7IH0KKworICAgIC8qCisgICAgICogU29tZSBiYXNpYyBmdW5jdGlvbnMgZm9yIHJhdyBkYXRhIG1hbmlwdWxhdGlvbi4gICJMRSIgbWVhbnMKKyAgICAgKiBMaXR0bGUgRW5kaWFuLgorICAgICAqLworICAgIHN0YXRpYyBpbmxpbmUgdW5zaWduZWQgc2hvcnQgZ2V0U2hvcnRMRShjb25zdCB1bnNpZ25lZCBjaGFyKiBidWYpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZlswXSB8IChidWZbMV0gPDwgOCk7CisgICAgfQorICAgIHN0YXRpYyBpbmxpbmUgdW5zaWduZWQgbG9uZyBnZXRMb25nTEUoY29uc3QgdW5zaWduZWQgY2hhciogYnVmKSB7CisgICAgICAgIHJldHVybiBidWZbMF0gfCAoYnVmWzFdIDw8IDgpIHwgKGJ1ZlsyXSA8PCAxNikgfCAoYnVmWzNdIDw8IDI0KTsKKyAgICB9CisgICAgc3RhdGljIGlubGluZSB2b2lkIHB1dFNob3J0TEUodW5zaWduZWQgY2hhciogYnVmLCBzaG9ydCB2YWwpIHsKKyAgICAgICAgYnVmWzBdID0gKHVuc2lnbmVkIGNoYXIpIHZhbDsKKyAgICAgICAgYnVmWzFdID0gKHVuc2lnbmVkIGNoYXIpICh2YWwgPj4gOCk7CisgICAgfQorICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBwdXRMb25nTEUodW5zaWduZWQgY2hhciogYnVmLCBsb25nIHZhbCkgeworICAgICAgICBidWZbMF0gPSAodW5zaWduZWQgY2hhcikgdmFsOworICAgICAgICBidWZbMV0gPSAodW5zaWduZWQgY2hhcikgKHZhbCA+PiA4KTsKKyAgICAgICAgYnVmWzJdID0gKHVuc2lnbmVkIGNoYXIpICh2YWwgPj4gMTYpOworICAgICAgICBidWZbM10gPSAodW5zaWduZWQgY2hhcikgKHZhbCA+PiAyNCk7CisgICAgfQorCisgICAgLyogZGVmaW5lZCBmb3IgWmlwIGFyY2hpdmVzICovCisgICAgZW51bSB7CisgICAgICAgIGtDb21wcmVzc1N0b3JlZCAgICAgPSAwLCAgICAgICAgLy8gbm8gY29tcHJlc3Npb24KKyAgICAgICAgLy8gc2hydW5rICAgICAgICAgICA9IDEsCisgICAgICAgIC8vIHJlZHVjZWQgMSAgICAgICAgPSAyLAorICAgICAgICAvLyByZWR1Y2VkIDIgICAgICAgID0gMywKKyAgICAgICAgLy8gcmVkdWNlZCAzICAgICAgICA9IDQsCisgICAgICAgIC8vIHJlZHVjZWQgNCAgICAgICAgPSA1LAorICAgICAgICAvLyBpbXBsb2RlZCAgICAgICAgID0gNiwKKyAgICAgICAgLy8gdG9rZW5pemVkICAgICAgICA9IDcsCisgICAgICAgIGtDb21wcmVzc0RlZmxhdGVkICAgPSA4LCAgICAgICAgLy8gc3RhbmRhcmQgZGVmbGF0ZQorICAgICAgICAvLyBEZWZsYXRlNjQgICAgICAgID0gOSwKKyAgICAgICAgLy8gbGliIGltcGxvZGVkICAgICA9IDEwLAorICAgICAgICAvLyByZXNlcnZlZCAgICAgICAgID0gMTEsCisgICAgICAgIC8vIGJ6aXAyICAgICAgICAgICAgPSAxMiwKKyAgICB9OworCisgICAgLyoKKyAgICAgKiBEZWxldGlvbiBmbGFnLiAgSWYgc2V0LCB0aGUgZW50cnkgd2lsbCBiZSByZW1vdmVkIG9uIHRoZSBuZXh0CisgICAgICogY2FsbCB0byAiZmx1c2giLgorICAgICAqLworICAgIGJvb2wgZ2V0RGVsZXRlZCh2b2lkKSBjb25zdCB7IHJldHVybiBtRGVsZXRlZDsgfQorCitwcm90ZWN0ZWQ6CisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHRoZSBzdHJ1Y3R1cmUgZnJvbSB0aGUgZmlsZSwgd2hpY2ggaXMgcG9pbnRpbmcgYXQKKyAgICAgKiBvdXIgQ2VudHJhbCBEaXJlY3RvcnkgZW50cnkuCisgICAgICovCisgICAgc3RhdHVzX3QgaW5pdEZyb21DREUoRklMRSogZnApOworCisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHRoZSBzdHJ1Y3R1cmUgZm9yIGEgbmV3IGZpbGUuICBXZSBuZWVkIHRoZSBmaWxlbmFtZQorICAgICAqIGFuZCBjb21tZW50IHNvIHRoYXQgd2UgY2FuIHByb3Blcmx5IHNpemUgdGhlIExGSCBhcmVhLiAgVGhlCisgICAgICogZmlsZW5hbWUgaXMgbWFuZGF0b3J5LCB0aGUgY29tbWVudCBpcyBvcHRpb25hbC4KKyAgICAgKi8KKyAgICB2b2lkIGluaXROZXcoY29uc3QgY2hhciogZmlsZU5hbWUsIGNvbnN0IGNoYXIqIGNvbW1lbnQpOworCisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHRoZSBzdHJ1Y3R1cmUgd2l0aCB0aGUgY29udGVudHMgb2YgYSBaaXBFbnRyeSBmcm9tCisgICAgICogYW5vdGhlciBmaWxlLgorICAgICAqLworICAgIHN0YXR1c190IGluaXRGcm9tRXh0ZXJuYWwoY29uc3QgWmlwRmlsZSogcFppcEZpbGUsIGNvbnN0IFppcEVudHJ5KiBwRW50cnkpOworCisgICAgLyoKKyAgICAgKiBBZGQgc29tZSBwYWQgYnl0ZXMgdG8gdGhlIExGSC4gIFdlIGRvIHRoaXMgYnkgYWRkaW5nIG9yIHJlc2l6aW5nCisgICAgICogdGhlICJleHRyYSIgZmllbGQuCisgICAgICovCisgICAgc3RhdHVzX3QgYWRkUGFkZGluZyhpbnQgcGFkZGluZyk7CisKKyAgICAvKgorICAgICAqIFNldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZGF0YSBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKi8KKyAgICB2b2lkIHNldERhdGFJbmZvKGxvbmcgdW5jb21wTGVuLCBsb25nIGNvbXBMZW4sIHVuc2lnbmVkIGxvbmcgY3JjMzIsCisgICAgICAgIGludCBjb21wcmVzc2lvbk1ldGhvZCk7CisKKyAgICAvKgorICAgICAqIFNldCB0aGUgbW9kaWZpY2F0aW9uIGRhdGUuCisgICAgICovCisgICAgdm9pZCBzZXRNb2RXaGVuKHRpbWVfdCB3aGVuKTsKKworICAgIC8qCisgICAgICogUmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGxvY2FsIGZpbGUgaGVhZGVyLgorICAgICAqLworICAgIG9mZl90IGdldExGSE9mZnNldCh2b2lkKSBjb25zdCB7IHJldHVybiBtQ0RFLm1Mb2NhbEhlYWRlclJlbE9mZnNldDsgfQorCisgICAgLyoKKyAgICAgKiBTZXQgdGhlIG9mZnNldCBvZiB0aGUgbG9jYWwgZmlsZSBoZWFkZXIsIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZgorICAgICAqIHRoZSBjdXJyZW50IGZpbGUuCisgICAgICovCisgICAgdm9pZCBzZXRMRkhPZmZzZXQob2ZmX3Qgb2Zmc2V0KSB7CisgICAgICAgIG1DREUubUxvY2FsSGVhZGVyUmVsT2Zmc2V0ID0gKGxvbmcpIG9mZnNldDsKKyAgICB9CisKKyAgICAvKiBtYXJrIGZvciBkZWxldGlvbjsgdXNlZCBieSBaaXBGaWxlOjpyZW1vdmUoKSAqLworICAgIHZvaWQgc2V0RGVsZXRlZCh2b2lkKSB7IG1EZWxldGVkID0gdHJ1ZTsgfQorCitwcml2YXRlOgorICAgIC8qIHRoZXNlIGFyZSBwcml2YXRlIGFuZCBub3QgZGVmaW5lZCAqLworICAgIFppcEVudHJ5KGNvbnN0IFppcEVudHJ5JiBzcmMpOworICAgIFppcEVudHJ5JiBvcGVyYXRvcj0oY29uc3QgWmlwRW50cnkmIHNyYyk7CisKKyAgICAvKiByZXR1cm5zICJ0cnVlIiBpZiB0aGUgQ0RFIGFuZCB0aGUgTEZIIGFncmVlICovCisgICAgYm9vbCBjb21wYXJlSGVhZGVycyh2b2lkKSBjb25zdDsKKyAgICB2b2lkIGNvcHlDREV0b0xGSCh2b2lkKTsKKworICAgIGJvb2wgICAgICAgIG1EZWxldGVkOyAgICAgICAvLyBzZXQgaWYgZW50cnkgaXMgcGVuZGluZyBkZWxldGlvbgorICAgIGJvb2wgICAgICAgIG1NYXJrZWQ7ICAgICAgICAvLyBhcHAtZGVmaW5lZCBtYXJrZXIKKworICAgIC8qCisgICAgICogRXZlcnkgZW50cnkgaW4gdGhlIFppcCBhcmNoaXZlIHN0YXJ0cyBvZmYgd2l0aCBvbmUgb2YgdGhlc2UuCisgICAgICovCisgICAgY2xhc3MgTG9jYWxGaWxlSGVhZGVyIHsKKyAgICBwdWJsaWM6CisgICAgICAgIExvY2FsRmlsZUhlYWRlcih2b2lkKSA6CisgICAgICAgICAgICBtVmVyc2lvblRvRXh0cmFjdCgwKSwKKyAgICAgICAgICAgIG1HUEJpdEZsYWcoMCksCisgICAgICAgICAgICBtQ29tcHJlc3Npb25NZXRob2QoMCksCisgICAgICAgICAgICBtTGFzdE1vZEZpbGVUaW1lKDApLAorICAgICAgICAgICAgbUxhc3RNb2RGaWxlRGF0ZSgwKSwKKyAgICAgICAgICAgIG1DUkMzMigwKSwKKyAgICAgICAgICAgIG1Db21wcmVzc2VkU2l6ZSgwKSwKKyAgICAgICAgICAgIG1VbmNvbXByZXNzZWRTaXplKDApLAorICAgICAgICAgICAgbUZpbGVOYW1lTGVuZ3RoKDApLAorICAgICAgICAgICAgbUV4dHJhRmllbGRMZW5ndGgoMCksCisgICAgICAgICAgICBtRmlsZU5hbWUoTlVMTCksCisgICAgICAgICAgICBtRXh0cmFGaWVsZChOVUxMKQorICAgICAgICB7fQorICAgICAgICB2aXJ0dWFsIH5Mb2NhbEZpbGVIZWFkZXIodm9pZCkgeworICAgICAgICAgICAgZGVsZXRlW10gbUZpbGVOYW1lOworICAgICAgICAgICAgZGVsZXRlW10gbUV4dHJhRmllbGQ7CisgICAgICAgIH0KKworICAgICAgICBzdGF0dXNfdCByZWFkKEZJTEUqIGZwKTsKKyAgICAgICAgc3RhdHVzX3Qgd3JpdGUoRklMRSogZnApOworCisgICAgICAgIC8vIHVuc2lnbmVkIGxvbmcgbVNpZ25hdHVyZTsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1WZXJzaW9uVG9FeHRyYWN0OworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbUdQQml0RmxhZzsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1Db21wcmVzc2lvbk1ldGhvZDsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1MYXN0TW9kRmlsZVRpbWU7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtTGFzdE1vZEZpbGVEYXRlOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbUNSQzMyOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbUNvbXByZXNzZWRTaXplOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbVVuY29tcHJlc3NlZFNpemU7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtRmlsZU5hbWVMZW5ndGg7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtRXh0cmFGaWVsZExlbmd0aDsKKyAgICAgICAgdW5zaWduZWQgY2hhciogIG1GaWxlTmFtZTsKKyAgICAgICAgdW5zaWduZWQgY2hhciogIG1FeHRyYUZpZWxkOworCisgICAgICAgIGVudW0geworICAgICAgICAgICAga1NpZ25hdHVyZSAgICAgID0gMHgwNDAzNGI1MCwKKyAgICAgICAgICAgIGtMRkhMZW4gICAgICAgICA9IDMwLCAgICAgICAvLyBMb2NhbEZpbGVIZHIgbGVuLCBleGNsLiB2YXIgZmllbGRzCisgICAgICAgIH07CisKKyAgICAgICAgdm9pZCBkdW1wKHZvaWQpIGNvbnN0OworICAgIH07CisKKyAgICAvKgorICAgICAqIEV2ZXJ5IGVudHJ5IGluIHRoZSBaaXAgYXJjaGl2ZSBoYXMgb25lIG9mIHRoZXNlIGluIHRoZSAiY2VudHJhbAorICAgICAqIGRpcmVjdG9yeSIgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBjbGFzcyBDZW50cmFsRGlyRW50cnkgeworICAgIHB1YmxpYzoKKyAgICAgICAgQ2VudHJhbERpckVudHJ5KHZvaWQpIDoKKyAgICAgICAgICAgIG1WZXJzaW9uTWFkZUJ5KDApLAorICAgICAgICAgICAgbVZlcnNpb25Ub0V4dHJhY3QoMCksCisgICAgICAgICAgICBtR1BCaXRGbGFnKDApLAorICAgICAgICAgICAgbUNvbXByZXNzaW9uTWV0aG9kKDApLAorICAgICAgICAgICAgbUxhc3RNb2RGaWxlVGltZSgwKSwKKyAgICAgICAgICAgIG1MYXN0TW9kRmlsZURhdGUoMCksCisgICAgICAgICAgICBtQ1JDMzIoMCksCisgICAgICAgICAgICBtQ29tcHJlc3NlZFNpemUoMCksCisgICAgICAgICAgICBtVW5jb21wcmVzc2VkU2l6ZSgwKSwKKyAgICAgICAgICAgIG1GaWxlTmFtZUxlbmd0aCgwKSwKKyAgICAgICAgICAgIG1FeHRyYUZpZWxkTGVuZ3RoKDApLAorICAgICAgICAgICAgbUZpbGVDb21tZW50TGVuZ3RoKDApLAorICAgICAgICAgICAgbURpc2tOdW1iZXJTdGFydCgwKSwKKyAgICAgICAgICAgIG1JbnRlcm5hbEF0dHJzKDApLAorICAgICAgICAgICAgbUV4dGVybmFsQXR0cnMoMCksCisgICAgICAgICAgICBtTG9jYWxIZWFkZXJSZWxPZmZzZXQoMCksCisgICAgICAgICAgICBtRmlsZU5hbWUoTlVMTCksCisgICAgICAgICAgICBtRXh0cmFGaWVsZChOVUxMKSwKKyAgICAgICAgICAgIG1GaWxlQ29tbWVudChOVUxMKQorICAgICAgICB7fQorICAgICAgICB2aXJ0dWFsIH5DZW50cmFsRGlyRW50cnkodm9pZCkgeworICAgICAgICAgICAgZGVsZXRlW10gbUZpbGVOYW1lOworICAgICAgICAgICAgZGVsZXRlW10gbUV4dHJhRmllbGQ7CisgICAgICAgICAgICBkZWxldGVbXSBtRmlsZUNvbW1lbnQ7CisgICAgICAgIH0KKworICAgICAgICBzdGF0dXNfdCByZWFkKEZJTEUqIGZwKTsKKyAgICAgICAgc3RhdHVzX3Qgd3JpdGUoRklMRSogZnApOworCisgICAgICAgIC8vIHVuc2lnbmVkIGxvbmcgbVNpZ25hdHVyZTsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1WZXJzaW9uTWFkZUJ5OworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbVZlcnNpb25Ub0V4dHJhY3Q7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtR1BCaXRGbGFnOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbUNvbXByZXNzaW9uTWV0aG9kOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbUxhc3RNb2RGaWxlVGltZTsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1MYXN0TW9kRmlsZURhdGU7CisgICAgICAgIHVuc2lnbmVkIGxvbmcgICBtQ1JDMzI7CisgICAgICAgIHVuc2lnbmVkIGxvbmcgICBtQ29tcHJlc3NlZFNpemU7CisgICAgICAgIHVuc2lnbmVkIGxvbmcgICBtVW5jb21wcmVzc2VkU2l6ZTsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1GaWxlTmFtZUxlbmd0aDsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1FeHRyYUZpZWxkTGVuZ3RoOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbUZpbGVDb21tZW50TGVuZ3RoOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbURpc2tOdW1iZXJTdGFydDsKKyAgICAgICAgdW5zaWduZWQgc2hvcnQgIG1JbnRlcm5hbEF0dHJzOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbUV4dGVybmFsQXR0cnM7CisgICAgICAgIHVuc2lnbmVkIGxvbmcgICBtTG9jYWxIZWFkZXJSZWxPZmZzZXQ7CisgICAgICAgIHVuc2lnbmVkIGNoYXIqICBtRmlsZU5hbWU7CisgICAgICAgIHVuc2lnbmVkIGNoYXIqICBtRXh0cmFGaWVsZDsKKyAgICAgICAgdW5zaWduZWQgY2hhciogIG1GaWxlQ29tbWVudDsKKworICAgICAgICB2b2lkIGR1bXAodm9pZCkgY29uc3Q7CisKKyAgICAgICAgZW51bSB7CisgICAgICAgICAgICBrU2lnbmF0dXJlICAgICAgPSAweDAyMDE0YjUwLAorICAgICAgICAgICAga0NERUxlbiAgICAgICAgID0gNDYsICAgICAgIC8vIENlbnRyYWxEaXJFbnQgbGVuLCBleGNsLiB2YXIgZmllbGRzCisgICAgICAgIH07CisgICAgfTsKKworICAgIGVudW0geworICAgICAgICAvL2tEYXRhRGVzY3JpcHRvclNpZ25hdHVyZSAgPSAweDA4MDc0YjUwLCAgIC8vIGN1cnJlbnRseSB1bnVzZWQKKyAgICAgICAga0RhdGFEZXNjcmlwdG9yTGVuICA9IDE2LCAgICAgICAgICAgLy8gZm91ciAzMi1iaXQgZmllbGRzCisKKyAgICAgICAga0RlZmF1bHRWZXJzaW9uICAgICA9IDIwLCAgICAgICAgICAgLy8gbmVlZCBkZWZsYXRlLCBub3RoaW5nIG11Y2ggZWxzZQorICAgICAgICBrRGVmYXVsdE1hZGVCeSAgICAgID0gMHgwMzE3LCAgICAgICAvLyAwMz1VTklYLCAxNz1zcGVjIHYyLjMKKyAgICAgICAga1VzZXNEYXRhRGVzY3IgICAgICA9IDB4MDAwOCwgICAgICAgLy8gR1BCaXRGbGFnIGJpdCAzCisgICAgfTsKKworICAgIExvY2FsRmlsZUhlYWRlciAgICAgbUxGSDsKKyAgICBDZW50cmFsRGlyRW50cnkgICAgIG1DREU7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gX19MSUJTX1pJUEVOVFJZX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvWmlwRmlsZS5oIGIvaW5jbHVkZS91dGlscy9aaXBGaWxlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRkZjViYgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvWmlwRmlsZS5oCkBAIC0wLDAgKzEsMjY5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEdlbmVyYWwtcHVycG9zZSBaaXAgYXJjaGl2ZSBhY2Nlc3MuICBUaGlzIGNsYXNzIGFsbG93cyBib3RoIHJlYWRpbmcgYW5kCisvLyB3cml0aW5nIHRvIFppcCBhcmNoaXZlcywgaW5jbHVkaW5nIGRlbGV0aW9uIG9mIGV4aXN0aW5nIGVudHJpZXMuCisvLworI2lmbmRlZiBfX0xJQlNfWklQRklMRV9ICisjZGVmaW5lIF9fTElCU19aSVBGSUxFX0gKKworI2luY2x1ZGUgIlppcEVudHJ5LmgiCisjaW5jbHVkZSAiVmVjdG9yLmgiCisjaW5jbHVkZSAiRXJyb3JzLmgiCisjaW5jbHVkZSA8c3RkaW8uaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKgorICogTWFuaXB1bGF0ZSBhIFppcCBhcmNoaXZlLgorICoKKyAqIFNvbWUgY2hhbmdlcyB3aWxsIG5vdCBiZSB2aXNpYmxlIGluIHRoZSB1bnRpbCB1bnRpbCAiZmx1c2giIGlzIGNhbGxlZC4KKyAqCisgKiBUaGUgY29ycmVjdCB3YXkgdG8gdXBkYXRlIGEgZmlsZSBhcmNoaXZlIGlzIHRvIG1ha2UgYWxsIGNoYW5nZXMgdG8gYQorICogY29weSBvZiB0aGUgYXJjaGl2ZSBpbiBhIHRlbXBvcmFyeSBmaWxlLCBhbmQgdGhlbiB1bmxpbmsvcmVuYW1lIG92ZXIKKyAqIHRoZSBvcmlnaW5hbCBhZnRlciBldmVyeXRoaW5nIGNvbXBsZXRlcy4gIEJlY2F1c2Ugd2UncmUgb25seSBpbnRlcmVzdGVkCisgKiBpbiB1c2luZyB0aGlzIGZvciBwYWNrYWdpbmcsIHdlIGRvbid0IHdvcnJ5IGFib3V0IHN1Y2ggdGhpbmdzLiAgQ3Jhc2hpbmcKKyAqIGFmdGVyIG1ha2luZyBjaGFuZ2VzIGFuZCBiZWZvcmUgZmx1c2goKSBjb21wbGV0ZXMgY291bGQgbGVhdmUgdXMgd2l0aAorICogYW4gdW51c2FibGUgWmlwIGFyY2hpdmUuCisgKi8KK2NsYXNzIFppcEZpbGUgeworcHVibGljOgorICAgIFppcEZpbGUodm9pZCkKKyAgICAgIDogbVppcEZwKE5VTEwpLCBtUmVhZE9ubHkoZmFsc2UpLCBtTmVlZENEUmV3cml0ZShmYWxzZSkKKyAgICAgIHt9CisgICAgflppcEZpbGUodm9pZCkgeworICAgICAgICBpZiAoIW1SZWFkT25seSkKKyAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgIGlmIChtWmlwRnAgIT0gTlVMTCkKKyAgICAgICAgICAgIGZjbG9zZShtWmlwRnApOworICAgICAgICBkaXNjYXJkRW50cmllcygpOworICAgIH0KKworICAgIC8qCisgICAgICogT3BlbiBhIG5ldyBvciBleGlzdGluZyBhcmNoaXZlLgorICAgICAqLworICAgIHR5cGVkZWYgZW51bSB7CisgICAgICAgIGtPcGVuUmVhZE9ubHkgICA9IDB4MDEsCisgICAgICAgIGtPcGVuUmVhZFdyaXRlICA9IDB4MDIsCisgICAgICAgIGtPcGVuQ3JlYXRlICAgICA9IDB4MDQsICAgICAvLyBjcmVhdGUgaWYgaXQgZG9lc24ndCBleGlzdAorICAgICAgICBrT3BlblRydW5jYXRlICAgPSAweDA4LCAgICAgLy8gaWYgaXQgZXhpc3RzLCBlbXB0eSBpdAorICAgIH07CisgICAgc3RhdHVzX3Qgb3Blbihjb25zdCBjaGFyKiB6aXBGaWxlTmFtZSwgaW50IGZsYWdzKTsKKworICAgIC8qCisgICAgICogQWRkIGEgZmlsZSB0byB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlLiAgU3BlY2lmeSB3aGV0aGVyIHlvdSB3YW50IHRoZQorICAgICAqIGxpYnJhcnkgdG8gdHJ5IHRvIHN0b3JlIGl0IGNvbXByZXNzZWQuCisgICAgICoKKyAgICAgKiBJZiAic3RvcmFnZU5hbWUiIGlzIHNwZWNpZmllZCwgdGhlIGFyY2hpdmUgd2lsbCB1c2UgdGhhdCBpbnN0ZWFkCisgICAgICogb2YgImZpbGVOYW1lIi4KKyAgICAgKgorICAgICAqIElmIHRoZXJlIGlzIGFscmVhZHkgYW4gZW50cnkgd2l0aCB0aGUgc2FtZSBuYW1lLCB0aGUgY2FsbCBmYWlscy4KKyAgICAgKiBFeGlzdGluZyBlbnRyaWVzIHdpdGggdGhlIHNhbWUgbmFtZSBtdXN0IGJlIHJlbW92ZWQgZmlyc3QuCisgICAgICoKKyAgICAgKiBJZiAicHBFbnRyeSIgaXMgbm9uLU5VTEwsIGEgcG9pbnRlciB0byB0aGUgbmV3IGVudHJ5IHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICovCisgICAgc3RhdHVzX3QgYWRkKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBpbnQgY29tcHJlc3Npb25NZXRob2QsCisgICAgICAgIFppcEVudHJ5KiogcHBFbnRyeSkKKyAgICB7CisgICAgICAgIHJldHVybiBhZGQoZmlsZU5hbWUsIGZpbGVOYW1lLCBjb21wcmVzc2lvbk1ldGhvZCwgcHBFbnRyeSk7CisgICAgfQorICAgIHN0YXR1c190IGFkZChjb25zdCBjaGFyKiBmaWxlTmFtZSwgY29uc3QgY2hhciogc3RvcmFnZU5hbWUsCisgICAgICAgIGludCBjb21wcmVzc2lvbk1ldGhvZCwgWmlwRW50cnkqKiBwcEVudHJ5KQorICAgIHsKKyAgICAgICAgcmV0dXJuIGFkZENvbW1vbihmaWxlTmFtZSwgTlVMTCwgMCwgc3RvcmFnZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgWmlwRW50cnk6OmtDb21wcmVzc1N0b3JlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb21wcmVzc2lvbk1ldGhvZCwgcHBFbnRyeSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBZGQgYSBmaWxlIHRoYXQgaXMgYWxyZWFkeSBjb21wcmVzc2VkIHdpdGggZ3ppcC4KKyAgICAgKgorICAgICAqIElmICJwcEVudHJ5IiBpcyBub24tTlVMTCwgYSBwb2ludGVyIHRvIHRoZSBuZXcgZW50cnkgd2lsbCBiZSByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBzdGF0dXNfdCBhZGRHemlwKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBjb25zdCBjaGFyKiBzdG9yYWdlTmFtZSwKKyAgICAgICAgWmlwRW50cnkqKiBwcEVudHJ5KQorICAgIHsKKyAgICAgICAgcmV0dXJuIGFkZENvbW1vbihmaWxlTmFtZSwgTlVMTCwgMCwgc3RvcmFnZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgWmlwRW50cnk6OmtDb21wcmVzc0RlZmxhdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgIFppcEVudHJ5OjprQ29tcHJlc3NEZWZsYXRlZCwgcHBFbnRyeSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBZGQgYSBmaWxlIGZyb20gYW4gaW4tbWVtb3J5IGRhdGEgYnVmZmVyLgorICAgICAqCisgICAgICogSWYgInBwRW50cnkiIGlzIG5vbi1OVUxMLCBhIHBvaW50ZXIgdG8gdGhlIG5ldyBlbnRyeSB3aWxsIGJlIHJldHVybmVkLgorICAgICAqLworICAgIHN0YXR1c190IGFkZChjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgY29uc3QgY2hhciogc3RvcmFnZU5hbWUsCisgICAgICAgIGludCBjb21wcmVzc2lvbk1ldGhvZCwgWmlwRW50cnkqKiBwcEVudHJ5KQorICAgIHsKKyAgICAgICAgcmV0dXJuIGFkZENvbW1vbihOVUxMLCBkYXRhLCBzaXplLCBzdG9yYWdlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBaaXBFbnRyeTo6a0NvbXByZXNzU3RvcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uTWV0aG9kLCBwcEVudHJ5KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFkZCBhbiBlbnRyeSBieSBjb3B5aW5nIGl0IGZyb20gYW5vdGhlciB6aXAgZmlsZS4gIElmICJwYWRkaW5nIiBpcworICAgICAqIG5vbnplcm8sIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzIHdpbGwgYmUgYWRkZWQgdG8gdGhlICJleHRyYSIKKyAgICAgKiBmaWVsZCBpbiB0aGUgaGVhZGVyLgorICAgICAqCisgICAgICogSWYgInBwRW50cnkiIGlzIG5vbi1OVUxMLCBhIHBvaW50ZXIgdG8gdGhlIG5ldyBlbnRyeSB3aWxsIGJlIHJldHVybmVkLgorICAgICAqLworICAgIHN0YXR1c190IGFkZChjb25zdCBaaXBGaWxlKiBwU291cmNlWmlwLCBjb25zdCBaaXBFbnRyeSogcFNvdXJjZUVudHJ5LAorICAgICAgICBpbnQgcGFkZGluZywgWmlwRW50cnkqKiBwcEVudHJ5KTsKKworICAgIC8qCisgICAgICogTWFyayBhbiBlbnRyeSBhcyBoYXZpbmcgYmVlbiByZW1vdmVkLiAgSXQgaXMgbm90IGFjdHVhbGx5IGRlbGV0ZWQKKyAgICAgKiBmcm9tIHRoZSBhcmNoaXZlIG9yIG91ciBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZXMgdW50aWwgZmx1c2goKSBpcworICAgICAqIGNhbGxlZC4KKyAgICAgKi8KKyAgICBzdGF0dXNfdCByZW1vdmUoWmlwRW50cnkqIHBFbnRyeSk7CisKKyAgICAvKgorICAgICAqIEZsdXNoIGNoYW5nZXMuICBJZiBtTmVlZENEUmV3cml0ZSBpcyBzZXQsIHRoaXMgd3JpdGVzIHRoZSBjZW50cmFsIGRpci4KKyAgICAgKi8KKyAgICBzdGF0dXNfdCBmbHVzaCh2b2lkKTsKKworICAgIC8qCisgICAgICogRXhwYW5kIHRoZSBkYXRhIGludG8gdGhlIGJ1ZmZlciBwcm92aWRlZC4gIFRoZSBidWZmZXIgbXVzdCBob2xkCisgICAgICogYXQgbGVhc3QgPHVuY29tcHJlc3NlZCBsZW4+IGJ5dGVzLiAgVmFyaWF0aW9uIGV4cGFuZHMgZGlyZWN0bHkKKyAgICAgKiB0byBhIGZpbGUuCisgICAgICoKKyAgICAgKiBSZXR1cm5zICJmYWxzZSIgaWYgYW4gZXJyb3Igd2FzIGVuY291bnRlcmVkIGluIHRoZSBjb21wcmVzc2VkIGRhdGEuCisgICAgICovCisgICAgLy9ib29sIHVuY29tcHJlc3MoY29uc3QgWmlwRW50cnkqIHBFbnRyeSwgdm9pZCogYnVmKSBjb25zdDsKKyAgICAvL2Jvb2wgdW5jb21wcmVzcyhjb25zdCBaaXBFbnRyeSogcEVudHJ5LCBGSUxFKiBmcCkgY29uc3Q7CisgICAgdm9pZCogdW5jb21wcmVzcyhjb25zdCBaaXBFbnRyeSogcEVudHJ5KTsKKworICAgIC8qCisgICAgICogR2V0IGFuIGVudHJ5LCBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vdCBmb3VuZC4KKyAgICAgKgorICAgICAqIERvZXMgbm90IHJldHVybiBlbnRyaWVzIHBlbmRpbmcgZGVsZXRpb24uCisgICAgICovCisgICAgWmlwRW50cnkqIGdldEVudHJ5QnlOYW1lKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdDsKKworICAgIC8qCisgICAgICogR2V0IHRoZSBOdGggZW50cnkgaW4gdGhlIGFyY2hpdmUuCisgICAgICoKKyAgICAgKiBUaGlzIHdpbGwgcmV0dXJuIGFuIGVudHJ5IHRoYXQgaXMgcGVuZGluZyBkZWxldGlvbi4KKyAgICAgKi8KKyAgICBpbnQgZ2V0TnVtRW50cmllcyh2b2lkKSBjb25zdCB7IHJldHVybiBtRW50cmllcy5zaXplKCk7IH0KKyAgICBaaXBFbnRyeSogZ2V0RW50cnlCeUluZGV4KGludCBpZHgpIGNvbnN0OworCitwcml2YXRlOgorICAgIC8qIHRoZXNlIGFyZSBwcml2YXRlIGFuZCBub3QgZGVmaW5lZCAqLworICAgIFppcEZpbGUoY29uc3QgWmlwRmlsZSYgc3JjKTsKKyAgICBaaXBGaWxlJiBvcGVyYXRvcj0oY29uc3QgWmlwRmlsZSYgc3JjKTsKKworICAgIGNsYXNzIEVuZE9mQ2VudHJhbERpciB7CisgICAgcHVibGljOgorICAgICAgICBFbmRPZkNlbnRyYWxEaXIodm9pZCkgOgorICAgICAgICAgICAgbURpc2tOdW1iZXIoMCksCisgICAgICAgICAgICBtRGlza1dpdGhDZW50cmFsRGlyKDApLAorICAgICAgICAgICAgbU51bUVudHJpZXMoMCksCisgICAgICAgICAgICBtVG90YWxOdW1FbnRyaWVzKDApLAorICAgICAgICAgICAgbUNlbnRyYWxEaXJTaXplKDApLAorICAgICAgICAgICAgbUNlbnRyYWxEaXJPZmZzZXQoMCksCisgICAgICAgICAgICBtQ29tbWVudExlbigwKSwKKyAgICAgICAgICAgIG1Db21tZW50KE5VTEwpCisgICAgICAgICAgICB7fQorICAgICAgICB2aXJ0dWFsIH5FbmRPZkNlbnRyYWxEaXIodm9pZCkgeworICAgICAgICAgICAgZGVsZXRlW10gbUNvbW1lbnQ7CisgICAgICAgIH0KKworICAgICAgICBzdGF0dXNfdCByZWFkQnVmKGNvbnN0IHVuc2lnbmVkIGNoYXIqIGJ1ZiwgaW50IGxlbik7CisgICAgICAgIHN0YXR1c190IHdyaXRlKEZJTEUqIGZwKTsKKworICAgICAgICAvL3Vuc2lnbmVkIGxvbmcgICBtU2lnbmF0dXJlOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbURpc2tOdW1iZXI7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtRGlza1dpdGhDZW50cmFsRGlyOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbU51bUVudHJpZXM7CisgICAgICAgIHVuc2lnbmVkIHNob3J0ICBtVG90YWxOdW1FbnRyaWVzOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbUNlbnRyYWxEaXJTaXplOworICAgICAgICB1bnNpZ25lZCBsb25nICAgbUNlbnRyYWxEaXJPZmZzZXQ7ICAgICAgLy8gb2Zmc2V0IGZyb20gZmlyc3QgZGlzaworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbUNvbW1lbnRMZW47CisgICAgICAgIHVuc2lnbmVkIGNoYXIqICBtQ29tbWVudDsKKworICAgICAgICBlbnVtIHsKKyAgICAgICAgICAgIGtTaWduYXR1cmUgICAgICA9IDB4MDYwNTRiNTAsCisgICAgICAgICAgICBrRU9DRExlbiAgICAgICAgPSAyMiwgICAgICAgLy8gRW5kT2ZDZW50cmFsRGlyIGxlbiwgZXhjbC4gY29tbWVudAorCisgICAgICAgICAgICBrTWF4Q29tbWVudExlbiAgPSA2NTUzNSwgICAgLy8gbG9uZ2VzdCBwb3NzaWJsZSBpbiB1c2hvcnQKKyAgICAgICAgICAgIGtNYXhFT0NEU2VhcmNoICA9IGtNYXhDb21tZW50TGVuICsgRW5kT2ZDZW50cmFsRGlyOjprRU9DRExlbiwKKworICAgICAgICB9OworCisgICAgICAgIHZvaWQgZHVtcCh2b2lkKSBjb25zdDsKKyAgICB9OworCisKKyAgICAvKiByZWFkIGFsbCBlbnRyaWVzIGluIHRoZSBjZW50cmFsIGRpciAqLworICAgIHN0YXR1c190IHJlYWRDZW50cmFsRGlyKHZvaWQpOworCisgICAgLyogY3J1bmNoIGRlbGV0ZWQgZW50cmllcyBvdXQgKi8KKyAgICBzdGF0dXNfdCBjcnVuY2hBcmNoaXZlKHZvaWQpOworCisgICAgLyogY2xlYW4gdXAgbUVudHJpZXMgKi8KKyAgICB2b2lkIGRpc2NhcmRFbnRyaWVzKHZvaWQpOworCisgICAgLyogY29tbW9uIGhhbmRsZXIgZm9yIGFsbCAiYWRkIiBmdW5jdGlvbnMgKi8KKyAgICBzdGF0dXNfdCBhZGRDb21tb24oY29uc3QgY2hhciogZmlsZU5hbWUsIGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLAorICAgICAgICBjb25zdCBjaGFyKiBzdG9yYWdlTmFtZSwgaW50IHNvdXJjZVR5cGUsIGludCBjb21wcmVzc2lvbk1ldGhvZCwKKyAgICAgICAgWmlwRW50cnkqKiBwcEVudHJ5KTsKKworICAgIC8qIGNvcHkgYWxsIG9mICJzcmNGcCIgaW50byAiZHN0RnAiICovCisgICAgc3RhdHVzX3QgY29weUZwVG9GcChGSUxFKiBkc3RGcCwgRklMRSogc3JjRnAsIHVuc2lnbmVkIGxvbmcqIHBDUkMzMik7CisgICAgLyogY29weSBhbGwgb2YgImRhdGEiIGludG8gImRzdEZwIiAqLworICAgIHN0YXR1c190IGNvcHlEYXRhVG9GcChGSUxFKiBkc3RGcCwKKyAgICAgICAgY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIHVuc2lnbmVkIGxvbmcqIHBDUkMzMik7CisgICAgLyogY29weSBzb21lIG9mICJzcmNGcCIgaW50byAiZHN0RnAiICovCisgICAgc3RhdHVzX3QgY29weVBhcnRpYWxGcFRvRnAoRklMRSogZHN0RnAsIEZJTEUqIHNyY0ZwLCBsb25nIGxlbmd0aCwKKyAgICAgICAgdW5zaWduZWQgbG9uZyogcENSQzMyKTsKKyAgICAvKiBsaWtlIG1lbW1vdmUoKSwgYnV0IG9uIHBhcnRzIG9mIGEgc2luZ2xlIGZpbGUgKi8KKyAgICBzdGF0dXNfdCBmaWxlbW92ZShGSUxFKiBmcCwgb2ZmX3QgZGVzdCwgb2ZmX3Qgc3JjLCBzaXplX3Qgbik7CisgICAgLyogY29tcHJlc3MgYWxsIG9mICJzcmNGcCIgaW50byAiZHN0RnAiLCB1c2luZyBEZWZsYXRlICovCisgICAgc3RhdHVzX3QgY29tcHJlc3NGcFRvRnAoRklMRSogZHN0RnAsIEZJTEUqIHNyY0ZwLAorICAgICAgICBjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgdW5zaWduZWQgbG9uZyogcENSQzMyKTsKKworICAgIC8qIGdldCBtb2RpZmljYXRpb24gZGF0ZSBmcm9tIGEgZmlsZSBkZXNjcmlwdG9yICovCisgICAgdGltZV90IGdldE1vZFRpbWUoaW50IGZkKTsKKworICAgIC8qCisgICAgICogV2UgdXNlIHN0ZGlvIEZJTEUqLCB3aGljaCBnaXZlcyB1cyBidWZmZXJpbmcgYnV0IG1ha2VzIGRlYWxpbmcKKyAgICAgKiB3aXRoIGZpbGVzID4yR0IgYXdrd2FyZC4gIFVudGlsIHdlIHN1cHBvcnQgWmlwNjQsIHdlJ3JlIGZpbmUuCisgICAgICovCisgICAgRklMRSogICAgICAgICAgIG1aaXBGcDsgICAgICAgICAgICAgLy8gWmlwIGZpbGUgcG9pbnRlcgorCisgICAgLyogb25lIG9mIHRoZXNlIHBlciBmaWxlICovCisgICAgRW5kT2ZDZW50cmFsRGlyIG1FT0NEOworCisgICAgLyogZGlkIHdlIG9wZW4gdGhpcyByZWFkLW9ubHk/ICovCisgICAgYm9vbCAgICAgICAgICAgIG1SZWFkT25seTsKKworICAgIC8qIHNldCB0aGlzIHdoZW4gd2UgdHJhc2ggdGhlIGNlbnRyYWwgZGlyICovCisgICAgYm9vbCAgICAgICAgICAgIG1OZWVkQ0RSZXdyaXRlOworCisgICAgLyoKKyAgICAgKiBPbmUgWmlwRW50cnkgcGVyIGVudHJ5IGluIHRoZSB6aXAgZmlsZS4gIEknbSB1c2luZyBwb2ludGVycyBpbnN0ZWFkCisgICAgICogb2Ygb2JqZWN0cyBiZWNhdXNlIGl0J3MgZWFzaWVyIHRoYW4gbWFraW5nIG9wZXJhdG9yPSB3b3JrIGZvciB0aGUKKyAgICAgKiBjbGFzc2VzIGFuZCBzdWItY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBWZWN0b3I8WmlwRW50cnkqPiAgIG1FbnRyaWVzOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIF9fTElCU19aSVBGSUxFX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvWmlwRmlsZUNSTy5oIGIvaW5jbHVkZS91dGlscy9aaXBGaWxlQ1JPLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzBlMDAzNgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvWmlwRmlsZUNSTy5oCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gQyBBUEkgZm9yIGVhZC1vbmx5IGFjY2VzcyB0byBaaXAgYXJjaGl2ZXMsIHdpdGggbWluaW1hbCBoZWFwIGFsbG9jYXRpb24uCisvLworI2lmbmRlZiBfX0xJQlNfWklQRklMRUNST19ICisjZGVmaW5lIF9fTElCU19aSVBGSUxFQ1JPX0gKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoKKyAqIFRyaXZpYWwgdHlwZWRlZiB0byBlbnN1cmUgdGhhdCBaaXBGaWxlQ1JPIGlzIG5vdCB0cmVhdGVkIGFzIGEgc2ltcGxlIGludGVnZXIuCisgKi8KK3R5cGVkZWYgdm9pZCogWmlwRmlsZUNSTzsKKworLyoKKyAqIFRyaXZpYWwgdHlwZWRlZiB0byBlbnN1cmUgdGhhdCBaaXBFbnRyeUNSTyBpcyBub3QgdHJlYXRlZCBhcyBhIHNpbXBsZQorICogaW50ZWdlci4gIFdlIHVzZSBOVUxMIHRvIGluZGljYXRlIGFuIGludmFsaWQgdmFsdWUuCisgKi8KK3R5cGVkZWYgdm9pZCogWmlwRW50cnlDUk87CisKK2V4dGVybiBaaXBGaWxlQ1JPIFppcEZpbGVYUk9fb3Blbihjb25zdCBjaGFyKiBwYXRoKTsKKworZXh0ZXJuIHZvaWQgWmlwRmlsZUNST19kZXN0cm95KFppcEZpbGVDUk8gemlwKTsKKworZXh0ZXJuIFppcEVudHJ5Q1JPIFppcEZpbGVDUk9fZmluZEVudHJ5QnlOYW1lKFppcEZpbGVDUk8gemlwLAorICAgICAgICBjb25zdCBjaGFyKiBmaWxlTmFtZSk7CisKK2V4dGVybiBib29sIFppcEZpbGVDUk9fZ2V0RW50cnlJbmZvKFppcEZpbGVDUk8gemlwLCBaaXBFbnRyeUNSTyBlbnRyeSwKKyAgICAgICAgaW50KiBwTWV0aG9kLCBsb25nKiBwVW5jb21wTGVuLAorICAgICAgICBsb25nKiBwQ29tcExlbiwgb2ZmX3QqIHBPZmZzZXQsIGxvbmcqIHBNb2RXaGVuLCBsb25nKiBwQ3JjMzIpOworCitleHRlcm4gYm9vbCBaaXBGaWxlQ1JPX3VuY29tcHJlc3NFbnRyeShaaXBGaWxlQ1JPIHppcCwgWmlwRW50cnlDUk8gZW50cnksIGludCBmZCk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKl9fTElCU19aSVBGSUxFQ1JPX0gqLwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9aaXBGaWxlUk8uaCBiL2luY2x1ZGUvdXRpbHMvWmlwRmlsZVJPLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTFjNGYyZgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvWmlwRmlsZVJPLmgKQEAgLTAsMCArMSwyMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gUmVhZC1vbmx5IGFjY2VzcyB0byBaaXAgYXJjaGl2ZXMsIHdpdGggbWluaW1hbCBoZWFwIGFsbG9jYXRpb24uCisvLworLy8gVGhpcyBpcyBzaW1pbGFyIHRvIHRoZSBtb3JlLWNvbXBsZXRlIFppcEZpbGUgY2xhc3MsIGJ1dCBubyBhdHRlbXB0CisvLyBoYXMgYmVlbiBtYWRlIHRvIG1ha2UgdGhlbSBpbnRlcmNoYW5nZWFibGUuICBUaGlzIGNsYXNzIG9wZXJhdGVzIHVuZGVyCisvLyBhIHZlcnkgZGlmZmVyZW50IHNldCBvZiBhc3N1bXB0aW9ucyBhbmQgY29uc3RyYWludHMuCisvLworI2lmbmRlZiBfX0xJQlNfWklQRklMRVJPX0gKKyNkZWZpbmUgX19MSUJTX1pJUEZJTEVST19ICisKKyNpbmNsdWRlICJFcnJvcnMuaCIKKyNpbmNsdWRlICJGaWxlTWFwLmgiCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8qCisgKiBUcml2aWFsIHR5cGVkZWYgdG8gZW5zdXJlIHRoYXQgWmlwRW50cnlSTyBpcyBub3QgdHJlYXRlZCBhcyBhIHNpbXBsZQorICogaW50ZWdlci4gIFdlIHVzZSBOVUxMIHRvIGluZGljYXRlIGFuIGludmFsaWQgdmFsdWUuCisgKi8KK3R5cGVkZWYgdm9pZCogWmlwRW50cnlSTzsKKworLyoKKyAqIE9wZW4gYSBaaXAgYXJjaGl2ZSBmb3IgcmVhZGluZy4KKyAqCisgKiBXZSB3YW50ICJvcGVuIiBhbmQgImZpbmQgZW50cnkgYnkgbmFtZSIgdG8gYmUgZmFzdCBvcGVyYXRpb25zLCBhbmQgd2UKKyAqIHdhbnQgdG8gdXNlIGFzIGxpdHRsZSBtZW1vcnkgYXMgcG9zc2libGUuICBXZSBtZW1vcnktbWFwIHRoZSBmaWxlLAorICogYW5kIGxvYWQgYSBoYXNoIHRhYmxlIHdpdGggcG9pbnRlcnMgdG8gdGhlIGZpbGVuYW1lcyAod2hpY2ggYXJlbid0CisgKiBudWxsLXRlcm1pbmF0ZWQpLiAgVGhlIG90aGVyIGZpZWxkcyBhcmUgYXQgYSBmaXhlZCBvZmZzZXQgZnJvbSB0aGUKKyAqIGZpbGVuYW1lLCBzbyB3ZSBkb24ndCBuZWVkIHRvIGV4dHJhY3QgdGhvc2UgKGJ1dCB3ZSBkbyBuZWVkIHRvIGJ5dGUtcmVhZAorICogYW5kIGVuZGlhbi1zd2FwIHRoZW0gZXZlcnkgdGltZSB3ZSB3YW50IHRoZW0pLgorICoKKyAqIFRvIHNwZWVkIGNvbXBhcmlzb25zIHdoZW4gZG9pbmcgYSBsb29rdXAgYnkgbmFtZSwgd2UgY291bGQgbWFrZSB0aGUgbWFwcGluZworICogInByaXZhdGUiIChjb3B5LW9uLXdyaXRlKSBhbmQgbnVsbC10ZXJtaW5hdGUgdGhlIGZpbGVuYW1lcyBhZnRlciB2ZXJpZnlpbmcKKyAqIHRoZSByZWNvcmQgc3RydWN0dXJlLiAgSG93ZXZlciwgdGhpcyByZXF1aXJlcyBhIHByaXZhdGUgbWFwcGluZyBvZgorICogZXZlcnkgcGFnZSB0aGF0IHRoZSBDZW50cmFsIERpcmVjdG9yeSB0b3VjaGVzLiAgRWFzaWVyIHRvIHR1Y2sgYSBjb3B5CisgKiBvZiB0aGUgc3RyaW5nIGxlbmd0aCBpbnRvIHRoZSBoYXNoIHRhYmxlIGVudHJ5LgorICovCitjbGFzcyBaaXBGaWxlUk8geworcHVibGljOgorICAgIFppcEZpbGVSTygpCisgICAgICAgIDogbUZkKC0xKSwgbUZpbGVNYXAoTlVMTCksIG1IYXNoVGFibGVTaXplKC0xKSwgbUhhc2hUYWJsZShOVUxMKQorICAgICAgICB7fQorICAgIH5aaXBGaWxlUk8oKSB7CisgICAgICAgIGZyZWUobUhhc2hUYWJsZSk7CisgICAgICAgIGlmIChtRmlsZU1hcCkKKyAgICAgICAgICAgIG1GaWxlTWFwLT5yZWxlYXNlKCk7CisgICAgICAgIGlmIChtRmQgPj0gMCkKKyAgICAgICAgICAgIGNsb3NlKG1GZCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPcGVuIGFuIGFyY2hpdmUuCisgICAgICovCisgICAgc3RhdHVzX3Qgb3Blbihjb25zdCBjaGFyKiB6aXBGaWxlTmFtZSk7CisKKyAgICAvKgorICAgICAqIEZpbmQgYW4gZW50cnksIGJ5IG5hbWUuICBSZXR1cm5zIHRoZSBlbnRyeSBpZGVudGlmaWVyLCBvciBOVUxMIGlmCisgICAgICogbm90IGZvdW5kLgorICAgICAqCisgICAgICogSWYgdHdvIGVudHJpZXMgaGF2ZSB0aGUgc2FtZSBuYW1lLCBvbmUgd2lsbCBiZSBjaG9zZW4gYXQgc2VtaS1yYW5kb20uCisgICAgICovCisgICAgWmlwRW50cnlSTyBmaW5kRW50cnlCeU5hbWUoY29uc3QgY2hhciogZmlsZU5hbWUpIGNvbnN0OworCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlICNvZiBlbnRyaWVzIGluIHRoZSBaaXAgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBpbnQgZ2V0TnVtRW50cmllcyh2b2lkKSBjb25zdCB7CisgICAgICAgIHJldHVybiBtTnVtRW50cmllczsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybiB0aGUgTnRoIGVudHJ5LiAgWmlwIGZpbGUgZW50cmllcyBhcmUgbm90IHN0b3JlZCBpbiBzb3J0ZWQKKyAgICAgKiBvcmRlciwgYW5kIHVwZGF0ZWQgZW50cmllcyBtYXkgYXBwZWFyIGF0IHRoZSBlbmQsIHNvIGFueW9uZSB3YWxraW5nCisgICAgICogdGhlIGFyY2hpdmUgbmVlZHMgdG8gYXZvaWQgbWFraW5nIG9yZGVyaW5nIGFzc3VtcHRpb25zLiAgV2UgdGFrZQorICAgICAqIHRoYXQgZnVydGhlciBieSByZXR1cm5pbmcgdGhlIE50aCBub24tZW1wdHkgZW50cnkgaW4gdGhlIGhhc2ggdGFibGUKKyAgICAgKiByYXRoZXIgdGhhbiB0aGUgTnRoIGVudHJ5IGluIHRoZSBhcmNoaXZlLgorICAgICAqCisgICAgICogVmFsaWQgdmFsdWVzIGFyZSBbMC4ubnVtRW50cmllcykuCisgICAgICoKKyAgICAgKiBbVGhpcyBpcyBjdXJyZW50bHkgTyhuKS4gIElmIGl0IG5lZWRzIHRvIGJlIGZhc3Qgd2UgY2FuIGFsbG9jYXRlIGFuCisgICAgICogYWRkaXRpb25hbCBkYXRhIHN0cnVjdHVyZSBvciBwcm92aWRlIGFuIGl0ZXJhdG9yIGludGVyZmFjZS5dCisgICAgICovCisgICAgWmlwRW50cnlSTyBmaW5kRW50cnlCeUluZGV4KGludCBpZHgpIGNvbnN0OworCisgICAgLyoKKyAgICAgKiBDb3B5IHRoZSBmaWxlbmFtZSBpbnRvIHRoZSBzdXBwbGllZCBidWZmZXIuICBSZXR1cm5zIDAgb24gc3VjY2VzcywKKyAgICAgKiAtMSBpZiAiZW50cnkiIGlzIGludmFsaWQsIG9yIHRoZSBmaWxlbmFtZSBsZW5ndGggaWYgaXQgZGlkbid0IGZpdC4gIFRoZQorICAgICAqIGxlbmd0aCwgYW5kIHRoZSByZXR1cm5lZCBzdHJpbmcsIGluY2x1ZGUgdGhlIG51bGwtdGVybWluYXRpb24uCisgICAgICovCisgICAgaW50IGdldEVudHJ5RmlsZU5hbWUoWmlwRW50cnlSTyBlbnRyeSwgY2hhciogYnVmZmVyLCBpbnQgYnVmTGVuKSBjb25zdDsKKworICAgIC8qCisgICAgICogR2V0IHRoZSB2aXRhbCBzdGF0cyBmb3IgYW4gZW50cnkuICBQYXNzIGluIE5VTEwgcG9pbnRlcnMgZm9yIGFueXRoaW5nCisgICAgICogeW91IGRvbid0IG5lZWQuCisgICAgICoKKyAgICAgKiAiKnBPZmZzZXQiIGhvbGRzIHRoZSBaaXAgZmlsZSBvZmZzZXQgb2YgdGhlIGVudHJ5J3MgZGF0YS4KKyAgICAgKgorICAgICAqIFJldHVybnMgImZhbHNlIiBpZiAiZW50cnkiIGlzIGJvZ3VzIG9yIGlmIHRoZSBkYXRhIGluIHRoZSBaaXAgZmlsZQorICAgICAqIGFwcGVhcnMgdG8gYmUgYmFkLgorICAgICAqLworICAgIGJvb2wgZ2V0RW50cnlJbmZvKFppcEVudHJ5Uk8gZW50cnksIGludCogcE1ldGhvZCwgbG9uZyogcFVuY29tcExlbiwKKyAgICAgICAgbG9uZyogcENvbXBMZW4sIG9mZl90KiBwT2Zmc2V0LCBsb25nKiBwTW9kV2hlbiwgbG9uZyogcENyYzMyKSBjb25zdDsKKworICAgIC8qCisgICAgICogQ3JlYXRlIGEgbmV3IEZpbGVNYXAgb2JqZWN0IHRoYXQgbWFwcyBhIHN1YnNldCBvZiB0aGUgYXJjaGl2ZS4gIEZvcgorICAgICAqIGFuIHVuY29tcHJlc3NlZCBlbnRyeSB0aGlzIGVmZmVjdGl2ZWx5IHByb3ZpZGVzIGEgcG9pbnRlciB0byB0aGUKKyAgICAgKiBhY3R1YWwgZGF0YSwgZm9yIGEgY29tcHJlc3NlZCBlbnRyeSB0aGlzIHByb3ZpZGVzIHRoZSBpbnB1dCBidWZmZXIKKyAgICAgKiBmb3IgaW5mbGF0ZSgpLgorICAgICAqLworICAgIEZpbGVNYXAqIGNyZWF0ZUVudHJ5RmlsZU1hcChaaXBFbnRyeVJPIGVudHJ5KSBjb25zdDsKKworICAgIC8qCisgICAgICogVW5jb21wcmVzcyB0aGUgZGF0YSBpbnRvIGEgYnVmZmVyLiAgRGVwZW5kaW5nIG9uIHRoZSBjb21wcmVzc2lvbgorICAgICAqIGZvcm1hdCwgdGhpcyBpcyBlaXRoZXIgYW4gImluZmxhdGUiIG9wZXJhdGlvbiBvciBhIG1lbWNweS4KKyAgICAgKgorICAgICAqIFVzZSAidW5jb21wTGVuIiBmcm9tIGdldEVudHJ5SW5mbygpIHRvIGRldGVybWluZSB0aGUgcmVxdWlyZWQKKyAgICAgKiBidWZmZXIgc2l6ZS4KKyAgICAgKgorICAgICAqIFJldHVybnMgInRydWUiIG9uIHN1Y2Nlc3MuCisgICAgICovCisgICAgYm9vbCB1bmNvbXByZXNzRW50cnkoWmlwRW50cnlSTyBlbnRyeSwgdm9pZCogYnVmZmVyKSBjb25zdDsKKworICAgIC8qCisgICAgICogVW5jb21wcmVzcyB0aGUgZGF0YSB0byBhbiBvcGVuIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBib29sIHVuY29tcHJlc3NFbnRyeShaaXBFbnRyeVJPIGVudHJ5LCBpbnQgZmQpIGNvbnN0OworCisgICAgLyogWmlwIGNvbXByZXNzaW9uIG1ldGhvZHMgd2Ugc3VwcG9ydCAqLworICAgIGVudW0geworICAgICAgICBrQ29tcHJlc3NTdG9yZWQgICAgID0gMCwgICAgICAgIC8vIG5vIGNvbXByZXNzaW9uCisgICAgICAgIGtDb21wcmVzc0RlZmxhdGVkICAgPSA4LCAgICAgICAgLy8gc3RhbmRhcmQgZGVmbGF0ZQorICAgIH07CisKKyAgICAvKgorICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVuY29tcHJlc3MgZGVmbGF0ZWQgZGF0YSwgYnVmZmVyIHRvIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbCBpbmZsYXRlQnVmZmVyKHZvaWQqIG91dEJ1ZiwgY29uc3Qgdm9pZCogaW5CdWYsCisgICAgICAgIGxvbmcgdW5jb21wTGVuLCBsb25nIGNvbXBMZW4pOworCisgICAgLyoKKyAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1bmNvbXByZXNzIGRlZmxhdGVkIGRhdGEsIGJ1ZmZlciB0byBmZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbCBpbmZsYXRlQnVmZmVyKGludCBmZCwgY29uc3Qgdm9pZCogaW5CdWYsCisgICAgICAgIGxvbmcgdW5jb21wTGVuLCBsb25nIGNvbXBMZW4pOworCisgICAgLyoKKyAgICAgKiBTb21lIGJhc2ljIGZ1bmN0aW9ucyBmb3IgcmF3IGRhdGEgbWFuaXB1bGF0aW9uLiAgIkxFIiBtZWFucworICAgICAqIExpdHRsZSBFbmRpYW4uCisgICAgICovCisgICAgc3RhdGljIGlubGluZSB1bnNpZ25lZCBzaG9ydCBnZXQyTEUoY29uc3QgdW5zaWduZWQgY2hhciogYnVmKSB7CisgICAgICAgIHJldHVybiBidWZbMF0gfCAoYnVmWzFdIDw8IDgpOworICAgIH0KKyAgICBzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGxvbmcgZ2V0NExFKGNvbnN0IHVuc2lnbmVkIGNoYXIqIGJ1ZikgeworICAgICAgICByZXR1cm4gYnVmWzBdIHwgKGJ1ZlsxXSA8PCA4KSB8IChidWZbMl0gPDwgMTYpIHwgKGJ1ZlszXSA8PCAyNCk7CisgICAgfQorCitwcml2YXRlOgorICAgIC8qIHRoZXNlIGFyZSBwcml2YXRlIGFuZCBub3QgZGVmaW5lZCAqLyAKKyAgICBaaXBGaWxlUk8oY29uc3QgWmlwRmlsZVJPJiBzcmMpOworICAgIFppcEZpbGVSTyYgb3BlcmF0b3I9KGNvbnN0IFppcEZpbGVSTyYgc3JjKTsKKworICAgIC8qIHBhcnNlIHRoZSBhcmNoaXZlLCBwcmVwcGluZyBpbnRlcm5hbCBzdHJ1Y3R1cmVzICovCisgICAgYm9vbCBwYXJzZVppcEFyY2hpdmUodm9pZCk7CisKKyAgICAvKiBhZGQgYSBuZXcgZW50cnkgdG8gdGhlIGhhc2ggdGFibGUgKi8KKyAgICB2b2lkIGFkZFRvSGFzaChjb25zdCBjaGFyKiBzdHIsIGludCBzdHJMZW4sIHVuc2lnbmVkIGludCBoYXNoKTsKKworICAgIC8qIGNvbXB1dGUgc3RyaW5nIGhhc2ggY29kZSAqLworICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgY29tcHV0ZUhhc2goY29uc3QgY2hhciogc3RyLCBpbnQgbGVuKTsKKworICAgIC8qIGNvbnZlcnQgYSBaaXBFbnRyeVJPIGJhY2sgdG8gYSBoYXNoIHRhYmxlIGluZGV4ICovCisgICAgaW50IGVudHJ5VG9JbmRleChjb25zdCBaaXBFbnRyeVJPIGVudHJ5KSBjb25zdDsKKworICAgIC8qCisgICAgICogT25lIGVudHJ5IGluIHRoZSBoYXNoIHRhYmxlLgorICAgICAqLworICAgIHR5cGVkZWYgc3RydWN0IEhhc2hFbnRyeSB7CisgICAgICAgIGNvbnN0IGNoYXIqICAgICBuYW1lOworICAgICAgICB1bnNpZ25lZCBzaG9ydCAgbmFtZUxlbjsKKyAgICAgICAgLy91bnNpZ25lZCBpbnQgICAgaGFzaDsKKyAgICB9IEhhc2hFbnRyeTsKKworICAgIC8qIG9wZW4gWmlwIGFyY2hpdmUgKi8KKyAgICBpbnQgICAgICAgICBtRmQ7CisKKyAgICAvKiBtYXBwZWQgZmlsZSAqLworICAgIEZpbGVNYXAqICAgIG1GaWxlTWFwOworCisgICAgLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIFppcCBhcmNoaXZlICovCisgICAgaW50ICAgICAgICAgbU51bUVudHJpZXM7CisKKyAgICAvKgorICAgICAqIFdlIGtub3cgaG93IG1hbnkgZW50cmllcyBhcmUgaW4gdGhlIFppcCBhcmNoaXZlLCBzbyB3ZSBoYXZlIGEKKyAgICAgKiBmaXhlZC1zaXplIGhhc2ggdGFibGUuICBXZSBwcm9iZSBmb3IgYW4gZW1wdHkgc2xvdC4KKyAgICAgKi8KKyAgICBpbnQgICAgICAgICBtSGFzaFRhYmxlU2l6ZTsKKyAgICBIYXNoRW50cnkqICBtSGFzaFRhYmxlOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8qX19MSUJTX1pJUEZJTEVST19IKi8KZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvWmlwVXRpbHMuaCBiL2luY2x1ZGUvdXRpbHMvWmlwVXRpbHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MmM0MmI2Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9aaXBVdGlscy5oCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gTWlzY2VsbGFuZW91cyB6aXAvZ3ppcCB1dGlsaXR5IGZ1bmN0aW9ucy4KKy8vCisjaWZuZGVmIF9fTElCU19aSVBVVElMU19ICisjZGVmaW5lIF9fTElCU19aSVBVVElMU19ICisKKyNpbmNsdWRlIDxzdGRpby5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8qCisgKiBDb250YWluZXIgY2xhc3MgZm9yIHV0aWxpdHkgZnVuY3Rpb25zLCBwcmltYXJpbHkgZm9yIG5hbWVzcGFjZSByZWFzb25zLgorICovCitjbGFzcyBaaXBVdGlscyB7CitwdWJsaWM6CisgICAgLyoKKyAgICAgKiBHZW5lcmFsIHV0aWxpdHkgZnVuY3Rpb24gZm9yIHVuY29tcHJlc3NpbmcgImRlZmxhdGUiIGRhdGEgZnJvbSBhIGZpbGUKKyAgICAgKiB0byBhIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbCBpbmZsYXRlVG9CdWZmZXIoaW50IGZkLCB2b2lkKiBidWYsIGxvbmcgdW5jb21wcmVzc2VkTGVuLAorICAgICAgICBsb25nIGNvbXByZXNzZWRMZW4pOworICAgIHN0YXRpYyBib29sIGluZmxhdGVUb0J1ZmZlcihGSUxFKiBmcCwgdm9pZCogYnVmLCBsb25nIHVuY29tcHJlc3NlZExlbiwKKyAgICAgICAgbG9uZyBjb21wcmVzc2VkTGVuKTsKKworICAgIC8qCisgICAgICogU29tZWRheSB3ZSBtaWdodCB3YW50IHRvIG1ha2UgdGhpcyBnZW5lcmljIGFuZCBoYW5kbGUgYnppcDIgIi5iejIiCisgICAgICogZmlsZXMgdG9vLgorICAgICAqCisgICAgICogV2UgY291bGQgZGVjbGFyZSBnemlwIHRvIGJlIGEgc3ViLWNsYXNzIG9mIHppcCB0aGF0IGhhcyBleGFjdGx5CisgICAgICogb25lIGFsd2F5cy1jb21wcmVzc2VkIGVudHJ5LCBidXQgd2UgY3VycmVudGx5IHdhbnQgdG8gdHJlYXQgWmlwCisgICAgICogYW5kIGd6aXAgYXMgZGlzdGluY3QsIHNvIHRoZXJlJ3Mgbm8gdmFsdWUuCisgICAgICoKKyAgICAgKiBUaGUgemxpYiBsaWJyYXJ5IGhhcyBzb21lIGd6aXAgdXRpbGl0aWVzLCBidXQgaXQgaGFzIG5vIGludGVyZmFjZQorICAgICAqIGZvciBleHRyYWN0aW5nIHRoZSB1bmNvbXByZXNzZWQgbGVuZ3RoIG9mIHRoZSBmaWxlICh5b3UgZG8gKm5vdCoKKyAgICAgKiB3YW50IHRvIGd6c2VlayB0byB0aGUgZW5kKS4KKyAgICAgKgorICAgICAqIFBhc3MgaW4gYSBzZWVrZWQgZmlsZSBwb2ludGVyIGZvciB0aGUgZ3ppcCBmaWxlLiAgSWYgdGhpcyBpcyBhIGd6aXAKKyAgICAgKiBmaWxlLCB3ZSBzZXQgb3VyIHJldHVybiB2YWx1ZXMgYXBwcm9wcmlhdGVseSBhbmQgcmV0dXJuICJ0cnVlIiB3aXRoCisgICAgICogdGhlIGZpbGUgc2Vla2VkIHRvIHRoZSBzdGFydCBvZiB0aGUgY29tcHJlc3NlZCBkYXRhLgorICAgICAqLworICAgIHN0YXRpYyBib29sIGV4YW1pbmVHemlwKEZJTEUqIGZwLCBpbnQqIHBDb21wcmVzc2lvbk1ldGhvZCwKKyAgICAgICAgbG9uZyogcFVuY29tcHJlc3NlZExlbiwgbG9uZyogcENvbXByZXNzZWRMZW4sIHVuc2lnbmVkIGxvbmcqIHBDUkMzMik7CisKK3ByaXZhdGU6CisgICAgWmlwVXRpbHMoKSB7fQorICAgIH5aaXBVdGlscygpIHt9Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLypfX0xJQlNfWklQVVRJTFNfSCovCmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL2FzaG1lbS5oIGIvaW5jbHVkZS91dGlscy9hc2htZW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODU0Nzc1Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9hc2htZW0uaApAQCAtMCwwICsxLDQxIEBACisvKiB1dGlscy9hc2htZW0uaAorICoqCisgKiogQ29weXJpZ2h0IDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoqCisgKiogVGhpcyBmaWxlIGlzIGR1YWwgbGljZW5zZWQuICBJdCBtYXkgYmUgcmVkaXN0cmlidXRlZCBhbmQvb3IgbW9kaWZpZWQKKyAqKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEFwYWNoZSAyLjAgTGljZW5zZSBPUiB2ZXJzaW9uIDIgb2YgdGhlIEdOVQorICoqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBfVVRJTFNfQVNITUVNX0gKKyNkZWZpbmUgX1VUSUxTX0FTSE1FTV9ICisKKyNpbmNsdWRlIDxsaW51eC9saW1pdHMuaD4KKyNpbmNsdWRlIDxsaW51eC9pb2N0bC5oPgorCisjZGVmaW5lIEFTSE1FTV9OQU1FX0xFTgkJMjU2CisKKyNkZWZpbmUgQVNITUVNX05BTUVfREVGCQkiZGV2L2FzaG1lbSIKKworLyogUmV0dXJuIHZhbHVlcyBmcm9tIEFTSE1FTV9QSU46IFdhcyB0aGUgbWFwcGluZyBwdXJnZWQgd2hpbGUgdW5waW5uZWQ/ICovCisjZGVmaW5lIEFTSE1FTV9OT1RfUkVBUEVECTAKKyNkZWZpbmUgQVNITUVNX1dBU19SRUFQRUQJMQorCisvKiBSZXR1cm4gdmFsdWVzIGZyb20gQVNITUVNX1VOUElOOiBJcyB0aGUgbWFwcGluZyBub3cgcGlubmVkIG9yIHVucGlubmVkPyAqLworI2RlZmluZSBBU0hNRU1fTk9XX1VOUElOTkVECTAKKyNkZWZpbmUgQVNITUVNX05PV19QSU5ORUQJMQorCisjZGVmaW5lIF9fQVNITUVNSU9DCQkweDc3CisKKyNkZWZpbmUgQVNITUVNX1NFVF9OQU1FCQlfSU9XKF9fQVNITUVNSU9DLCAxLCBjaGFyW0FTSE1FTV9OQU1FX0xFTl0pCisjZGVmaW5lIEFTSE1FTV9HRVRfTkFNRQkJX0lPUihfX0FTSE1FTUlPQywgMiwgY2hhcltBU0hNRU1fTkFNRV9MRU5dKQorI2RlZmluZSBBU0hNRU1fU0VUX1NJWkUJCV9JT1coX19BU0hNRU1JT0MsIDMsIHNpemVfdCkKKyNkZWZpbmUgQVNITUVNX0dFVF9TSVpFCQlfSU8oX19BU0hNRU1JT0MsIDQpCisjZGVmaW5lIEFTSE1FTV9TRVRfUFJPVF9NQVNLCV9JT1coX19BU0hNRU1JT0MsIDUsIHVuc2lnbmVkIGxvbmcpCisjZGVmaW5lIEFTSE1FTV9HRVRfUFJPVF9NQVNLCV9JTyhfX0FTSE1FTUlPQywgNikKKyNkZWZpbmUgQVNITUVNX1BJTgkJX0lPKF9fQVNITUVNSU9DLCA3KQorI2RlZmluZSBBU0hNRU1fVU5QSU4JCV9JTyhfX0FTSE1FTUlPQywgOCkKKyNkZWZpbmUgQVNITUVNX0lTUElOTkVECQlfSU8oX19BU0hNRU1JT0MsIDkpCisjZGVmaW5lIEFTSE1FTV9QVVJHRV9BTExfQ0FDSEVTCV9JTyhfX0FTSE1FTUlPQywgMTApCisKKyNlbmRpZgkvKiBfVVRJTFNfQVNITUVNX0ggKi8KZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvZXhlY3V0YWJsZXBhdGguaCBiL2luY2x1ZGUvdXRpbHMvZXhlY3V0YWJsZXBhdGguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTc5NDMyCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91dGlscy9leGVjdXRhYmxlcGF0aC5oCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIF9VVElMU19FWEVDVVRBQkxFUEFUSF9ICisjZGVmaW5lIF9VVElMU19FWEVDVVRBQkxFUEFUSF9ICisKKyNpbmNsdWRlIDxsaW1pdHMuaD4KKworLy8gcmV0dXJucyB0aGUgcGF0aCB0byB0aGlzIGV4ZWN1dGFibGUKKyNpZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIgorI2VuZGlmCit2b2lkIGV4ZWN1dGFibGVwYXRoKGNoYXIgc1tQQVRIX01BWF0pOworCisjZW5kaWYgLy8gX1VUSUxTX0VYRUNVVEFCTEVQQVRIX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvaW5ldF9hZGRyZXNzLmggYi9pbmNsdWRlL3V0aWxzL2luZXRfYWRkcmVzcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiZDg2NzIKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL2luZXRfYWRkcmVzcy5oCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEludGVybmV0IGFkZHJlc3MgY2xhc3Nlcy4gIE1vZGVsZWQgYWZ0ZXIgSmF2YSBjbGFzc2VzLgorLy8KKyNpZm5kZWYgX1JVTlRJTUVfSU5FVF9BRERSRVNTX0gKKyNkZWZpbmUgX1JVTlRJTUVfSU5FVF9BRERSRVNTX0gKKworI2lmZGVmIEhBVkVfQU5EUk9JRF9PUworI2Vycm9yIERPIE5PVCBVU0UgVEhJUyBGSUxFIElOIFRIRSBERVZJQ0UgQlVJTEQKKyNlbmRpZgorCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFRoaXMgY2xhc3MgaG9sZHMgSW50ZXJuZXQgYWRkcmVzc2VzLiAgUGVyaGFwcyBtb3JlIHVzZWZ1bCBpcyBpdHMKKyAqIGFiaWxpdHkgdG8gbG9vayB1cCBhZGRyZXNzZXMgYnkgbmFtZS4KKyAqCisgKiBJbnZva2Ugb25lIG9mIHRoZSBzdGF0aWMgZmFjdG9yeSBtZXRob2RzIHRvIGNyZWF0ZSBhIG5ldyBvYmplY3QuCisgKi8KK2NsYXNzIEluZXRBZGRyZXNzIHsKK3B1YmxpYzoKKyAgICB2aXJ0dWFsIH5JbmV0QWRkcmVzcyh2b2lkKTsKKworICAgIC8vIGNyZWF0ZSBmcm9tIHcueC55Lnogb3IgZm9vLmJhci5jb20gbm90YXRpb24KKyAgICBzdGF0aWMgSW5ldEFkZHJlc3MqIGdldEJ5TmFtZShjb25zdCBjaGFyKiBob3N0KTsKKworICAgIC8vIGNvcHktY29uc3RydWN0aW9uCisgICAgSW5ldEFkZHJlc3MoY29uc3QgSW5ldEFkZHJlc3MmIG9yaWcpOworCisgICAgY29uc3Qgdm9pZCogZ2V0QWRkcmVzcyh2b2lkKSBjb25zdCB7IHJldHVybiBtQWRkcmVzczsgfQorICAgIGludCBnZXRBZGRyZXNzTGVuZ3RoKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1MZW5ndGg7IH0KKyAgICBjb25zdCBjaGFyKiBnZXRIb3N0TmFtZSh2b2lkKSBjb25zdCB7IHJldHVybiBtTmFtZTsgfQorCitwcml2YXRlOgorICAgIEluZXRBZGRyZXNzKHZvaWQpOworICAgIC8vIGFzc2lnbm1lbnQgKHByaXZhdGUpCisgICAgSW5ldEFkZHJlc3MmIG9wZXJhdG9yPShjb25zdCBJbmV0QWRkcmVzcyYgYWRkcik7CisKKyAgICAvLyB1c2UgYSB2b2lkKiBoZXJlIHNvIHdlIGRvbid0IGhhdmUgdG8gZXhwb3NlIGFjdHVhbCBzb2NrZXQgaGVhZGVycworICAgIHZvaWQqICAgICAgIG1BZGRyZXNzOyAgIC8vIHRoaXMgaXMgcmVhbGx5IGEgcHRyIHRvIHNvY2thZGRyX2luCisgICAgaW50ICAgICAgICAgbUxlbmd0aDsKKyAgICBjaGFyKiAgICAgICBtTmFtZTsKK307CisKKworLyoKKyAqIEJhc2UgY2xhc3MgZm9yIHNvY2tldCBhZGRyZXNzZXMuCisgKi8KK2NsYXNzIFNvY2tldEFkZHJlc3MgeworcHVibGljOgorICAgIFNvY2tldEFkZHJlc3MoKSB7fQorICAgIHZpcnR1YWwgflNvY2tldEFkZHJlc3MoKSB7fQorfTsKKworCisvKgorICogSW50ZXJuZXQgYWRkcmVzcyBjbGFzcy4gIFRoaXMgY29tYmluZXMgYW4gSW5ldEFkZHJlc3Mgd2l0aCBhIHBvcnQuCisgKi8KK2NsYXNzIEluZXRTb2NrZXRBZGRyZXNzIDogcHVibGljIFNvY2tldEFkZHJlc3MgeworcHVibGljOgorICAgIEluZXRTb2NrZXRBZGRyZXNzKCkgOgorICAgICAgICBtQWRkcmVzcygwKSwgbVBvcnQoLTEpCisgICAgICAgIHt9CisgICAgfkluZXRTb2NrZXRBZGRyZXNzKHZvaWQpIHsKKyAgICAgICAgZGVsZXRlIG1BZGRyZXNzOworICAgIH0KKworICAgIC8vIENyZWF0ZSBhbiBhZGRyZXNzIHdpdGggYSBob3N0IHdpbGRjYXJkICh1c2VmdWwgZm9yIHNlcnZlcnMpLgorICAgIGJvb2wgY3JlYXRlKGludCBwb3J0KTsKKyAgICAvLyBDcmVhdGUgYW4gYWRkcmVzcyB3aXRoIHRoZSBzcGVjaWZpZWQgaG9zdCBhbmQgcG9ydC4KKyAgICBib29sIGNyZWF0ZShjb25zdCBJbmV0QWRkcmVzcyogYWRkciwgaW50IHBvcnQpOworICAgIC8vIENyZWF0ZSBhbiBhZGRyZXNzIHdpdGggdGhlIHNwZWNpZmllZCBob3N0IGFuZCBwb3J0LiAgRG9lcyB0aGUKKyAgICAvLyBob3N0bmFtZSBsb29rdXAuCisgICAgYm9vbCBjcmVhdGUoY29uc3QgY2hhciogaG9zdCwgaW50IHBvcnQpOworCisgICAgY29uc3QgSW5ldEFkZHJlc3MqIGdldEFkZHJlc3Modm9pZCkgY29uc3QgeyByZXR1cm4gbUFkZHJlc3M7IH0KKyAgICBjb25zdCBpbnQgZ2V0UG9ydCh2b2lkKSBjb25zdCB7IHJldHVybiBtUG9ydDsgfQorICAgIGNvbnN0IGNoYXIqIGdldEhvc3ROYW1lKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1BZGRyZXNzLT5nZXRIb3N0TmFtZSgpOyB9CisKK3ByaXZhdGU6CisgICAgSW5ldEFkZHJlc3MqIG1BZGRyZXNzOworICAgIGludCAgICAgICAgIG1Qb3J0OworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIF9SVU5USU1FX0lORVRfQUREUkVTU19ICmRpZmYgLS1naXQgYS9pbmNsdWRlL3V0aWxzL21pc2MuaCBiL2luY2x1ZGUvdXRpbHMvbWlzYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyZTg0YjQKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL3V0aWxzL21pc2MuaApAQCAtMCwwICsxLDkzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEhhbmR5IHV0aWxpdHkgZnVuY3Rpb25zIGFuZCBwb3J0YWJpbGl0eSBjb2RlLgorLy8KKyNpZm5kZWYgX0xJQlNfVVRJTFNfTUlTQ19ICisjZGVmaW5lIF9MSUJTX1VUSUxTX01JU0NfSAorCisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKyNpbmNsdWRlICJ1dGlscy9FbmRpYW4uaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKiBnZXQgI29mIGVsZW1lbnRzIGluIGEgc3RhdGljIGFycmF5ICovCisjaWZuZGVmIE5FTEVNCisjIGRlZmluZSBORUxFTSh4KSAoKGludCkgKHNpemVvZih4KSAvIHNpemVvZigoeClbMF0pKSkKKyNlbmRpZgorCisvKgorICogTWFrZSBhIGNvcHkgb2YgdGhlIHN0cmluZywgdXNpbmcgIm5ld1tdIiBpbnN0ZWFkIG9mICJtYWxsb2MiLiAgRnJlZSB0aGUKKyAqIHN0cmluZyB3aXRoIGRlbGV0ZVtdLgorICoKKyAqIFJldHVybnMgTlVMTCBpZiAic3RyIiBpcyBOVUxMLgorICovCitjaGFyKiBzdHJkdXBOZXcoY29uc3QgY2hhciogc3RyKTsKKworLyoKKyAqIENvbmNhdGVuYXRlIGFuIGFyZ3VtZW50IHZlY3RvciBpbnRvIGEgc2luZ2xlIHN0cmluZy4gIElmIGFyZ2MgaXMgPj0gMAorICogaXQgd2lsbCBiZSB1c2VkOyBpZiBpdCdzIDwgMCB0aGVuIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIGFyZyB2ZWN0b3IKKyAqIG11c3QgYmUgTlVMTC4KKyAqCisgKiBUaGlzIGluc2VydHMgYSBzcGFjZSBiZXR3ZWVuIGVhY2ggYXJndW1lbnQuCisgKgorICogVGhpcyBkb2VzIG5vdCBhdXRvbWF0aWNhbGx5IGFkZCBkb3VibGUgcXVvdGVzIGFyb3VuZCBhcmd1bWVudHMgd2l0aAorICogc3BhY2VzIGluIHRoZW0uICBUaGlzIHByYWN0aWNlIGlzIG5lY2Vzc2FyeSBmb3IgV2luMzIsIGJlY2F1c2UgV2luMzIncworICogQ3JlYXRlUHJvY2VzcyBjYWxsIGlzIHN0dXBpZC4KKyAqCisgKiBUaGUgY2FsbGVyIHNob3VsZCBkZWxldGVbXSB0aGUgcmV0dXJuZWQgc3RyaW5nLgorICovCitjaGFyKiBjb25jYXRBcmd2KGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pOworCisvKgorICogQ291bnQgdXAgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgaW4gImFyZ3YiLiAgVGhlIGNvdW50IGRvZXMgbm90IGluY2x1ZGUKKyAqIHRoZSBmaW5hbCBOVUxMIGVudHJ5LgorICovCitpbnQgY291bnRBcmd2KGNvbnN0IGNoYXIqIGNvbnN0IGFyZ3ZbXSk7CisKKy8qCisgKiBTb21lIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB3b3JraW5nIHdpdGggZmlsZXMuICBUaGVzZSBjb3VsZCBiZSBtYWRlCisgKiBwYXJ0IG9mIGEgIkZpbGUiIGNsYXNzLgorICovCit0eXBlZGVmIGVudW0gRmlsZVR5cGUgeworICAgIGtGaWxlVHlwZVVua25vd24gPSAwLAorICAgIGtGaWxlVHlwZU5vbmV4aXN0ZW50LCAgICAgICAvLyBpLmUuIEVOT0VOVAorICAgIGtGaWxlVHlwZVJlZ3VsYXIsCisgICAga0ZpbGVUeXBlRGlyZWN0b3J5LAorICAgIGtGaWxlVHlwZUNoYXJEZXYsCisgICAga0ZpbGVUeXBlQmxvY2tEZXYsCisgICAga0ZpbGVUeXBlRmlmbywKKyAgICBrRmlsZVR5cGVTeW1saW5rLAorICAgIGtGaWxlVHlwZVNvY2tldCwKK30gRmlsZVR5cGU7CisvKiBnZXQgdGhlIGZpbGUncyB0eXBlOyBmb2xsb3dzIHN5bWxpbmtzICovCitGaWxlVHlwZSBnZXRGaWxlVHlwZShjb25zdCBjaGFyKiBmaWxlTmFtZSk7CisvKiBnZXQgdGhlIGZpbGUncyBtb2RpZmljYXRpb24gZGF0ZTsgcmV0dXJucyAtMSB3L2Vycm5vIHNldCBvbiBmYWlsdXJlICovCit0aW1lX3QgZ2V0RmlsZU1vZERhdGUoY29uc3QgY2hhciogZmlsZU5hbWUpOworCisvKgorICogUm91bmQgdXAgdG8gdGhlIG5lYXJlc3QgcG93ZXIgb2YgMi4gIEhhbmR5IGZvciBoYXNoIHRhYmxlcy4KKyAqLwordW5zaWduZWQgaW50IHJvdW5kVXBQb3dlcjIodW5zaWduZWQgaW50IHZhbCk7CisKK3ZvaWQgc3RycmV2ZXJzZShjaGFyKiBiZWdpbiwgY2hhciogZW5kKTsKK3ZvaWQga19pdG9hKGludCB2YWx1ZSwgY2hhciogc3RyLCBpbnQgYmFzZSk7CitjaGFyKiBpdG9hKGludCB2YWwsIGludCBiYXNlKTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIF9MSUJTX1VUSUxTX01JU0NfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9wb3J0ZWQuaCBiL2luY2x1ZGUvdXRpbHMvcG9ydGVkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIzYmUwMQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvcG9ydGVkLmgKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBTdGFuZGFyZCBmdW5jdGlvbnMgcG9ydGVkIHRvIHRoZSBjdXJyZW50IHBsYXRmb3JtLiAgTm90ZSB0aGVzZSBhcmUgTk9UCisvLyBpbiB0aGUgImFuZHJvaWQiIG5hbWVzcGFjZS4KKy8vCisjaWZuZGVmIF9MSUJTX1VUSUxTX1BPUlRFRF9ICisjZGVmaW5lIF9MSUJTX1VUSUxTX1BPUlRFRF9ICisKKyNpbmNsdWRlIDxzeXMvdGltZS5oPiAgICAgICAvLyBmb3IgdGltZXZhbAorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qIGxpYnJhcnkgcmVwbGFjZW1lbnQgZnVuY3Rpb25zICovCisjaWYgZGVmaW5lZChORUVEX0dFVFRJTUVPRkRBWSkKK2ludCBnZXR0aW1lb2ZkYXkoc3RydWN0IHRpbWV2YWwqIHR2LCBzdHJ1Y3QgdGltZXpvbmUqIHR6KTsKKyNlbmRpZgorI2lmIGRlZmluZWQoTkVFRF9VU0xFRVApCit2b2lkIHVzbGVlcCh1bnNpZ25lZCBsb25nIHVzZWMpOworI2VuZGlmCisjaWYgZGVmaW5lZChORUVEX1BJUEUpCitpbnQgcGlwZShpbnQgZmlsZWRlc1syXSk7CisjZW5kaWYKKyNpZiBkZWZpbmVkKE5FRURfU0VURU5WKQoraW50IHNldGVudihjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiB2YWx1ZSwgaW50IG92ZXJ3cml0ZSk7Cit2b2lkIHVuc2V0ZW52KGNvbnN0IGNoYXIqIG5hbWUpOworY2hhciogZ2V0ZW52KGNvbnN0IGNoYXIqIG5hbWUpOworI2VuZGlmCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvLyBfTElCU19VVElMU19QT1JURURfSApkaWZmIC0tZ2l0IGEvaW5jbHVkZS91dGlscy9zdHJpbmdfYXJyYXkuaCBiL2luY2x1ZGUvdXRpbHMvc3RyaW5nX2FycmF5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY0ZGRhMgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvc3RyaW5nX2FycmF5LmgKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gU29ydGFibGUgYXJyYXkgb2Ygc3RyaW5ncy4gIFNUTC1pc2gsIGJ1dCBTVEwtZnJlZS4KKy8vICAKKyNpZm5kZWYgX0xJQlNfVVRJTFNfU1RSSU5HX0FSUkFZX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfU1RSSU5HX0FSUkFZX0gKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vCisvLyBBbiBleHBhbmRpbmcgYXJyYXkgb2Ygc3RyaW5ncy4gIEFkZCwgZ2V0LCBzb3J0LCBkZWxldGUuCisvLworY2xhc3MgU3RyaW5nQXJyYXkgeworcHVibGljOgorICAgIFN0cmluZ0FycmF5KCkKKyAgICAgICAgOiBtTWF4KDApLCBtQ3VycmVudCgwKSwgbUFycmF5KE5VTEwpCisgICAgICAgIHt9CisgICAgdmlydHVhbCB+U3RyaW5nQXJyYXkoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbUN1cnJlbnQ7IGkrKykKKyAgICAgICAgICAgIGRlbGV0ZVtdIG1BcnJheVtpXTsKKyAgICAgICAgZGVsZXRlW10gbUFycmF5OworICAgIH0KKworICAgIC8vCisgICAgLy8gQWRkIGEgc3RyaW5nLiAgQSBjb3B5IG9mIHRoZSBzdHJpbmcgaXMgbWFkZS4KKyAgICAvLworICAgIGJvb2wgcHVzaF9iYWNrKGNvbnN0IGNoYXIqIHN0cikgeworICAgICAgICBpZiAobUN1cnJlbnQgPj0gbU1heCkgeworICAgICAgICAgICAgY2hhcioqIHRtcDsKKworICAgICAgICAgICAgaWYgKG1NYXggPT0gMCkKKyAgICAgICAgICAgICAgICBtTWF4ID0gMTY7ICAgICAgLy8gaW5pdGlhbCBzdG9yYWdlCisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgbU1heCAqPSAyOworCisgICAgICAgICAgICB0bXAgPSBuZXcgY2hhcipbbU1heF07CisgICAgICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICAgICAgICBtZW1jcHkodG1wLCBtQXJyYXksIG1DdXJyZW50ICogc2l6ZW9mKGNoYXIqKSk7CisgICAgICAgICAgICBkZWxldGVbXSBtQXJyYXk7CisgICAgICAgICAgICBtQXJyYXkgPSB0bXA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbGVuID0gc3RybGVuKHN0cik7CisgICAgICAgIG1BcnJheVttQ3VycmVudF0gPSBuZXcgY2hhcltsZW4rMV07CisgICAgICAgIG1lbWNweShtQXJyYXlbbUN1cnJlbnRdLCBzdHIsIGxlbisxKTsKKyAgICAgICAgbUN1cnJlbnQrKzsKKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvLworICAgIC8vIERlbGV0ZSBhbiBlbnRyeS4KKyAgICAvLworICAgIHZvaWQgZXJhc2UoaW50IGlkeCkgeworICAgICAgICBpZiAoaWR4IDwgMCB8fCBpZHggPj0gbUN1cnJlbnQpCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGRlbGV0ZVtdIG1BcnJheVtpZHhdOworICAgICAgICBpZiAoaWR4IDwgbUN1cnJlbnQtMSkgeworICAgICAgICAgICAgbWVtbW92ZSgmbUFycmF5W2lkeF0sICZtQXJyYXlbaWR4KzFdLAorICAgICAgICAgICAgICAgIChtQ3VycmVudC0xIC0gaWR4KSAqIHNpemVvZihjaGFyKikpOworICAgICAgICB9CisgICAgICAgIG1DdXJyZW50LS07CisgICAgfQorCisgICAgLy8KKyAgICAvLyBTb3J0IHRoZSBhcnJheS4KKyAgICAvLworICAgIHZvaWQgc29ydChpbnQgKCpjb21wYXJlKShjb25zdCB2b2lkKiwgY29uc3Qgdm9pZCopKSB7CisgICAgICAgIHFzb3J0KG1BcnJheSwgbUN1cnJlbnQsIHNpemVvZihjaGFyKiksIGNvbXBhcmUpOworICAgIH0KKworICAgIC8vCisgICAgLy8gUGFzcyB0aGlzIHRvIHRoZSBzb3J0IHJvdXRpbmUgdG8gZG8gYW4gYXNjZW5kaW5nIGFscGhhYmV0aWNhbCBzb3J0LgorICAgIC8vCisgICAgc3RhdGljIGludCBjbXBBc2NlbmRpbmdBbHBoYShjb25zdCB2b2lkKiBwc3RyMSwgY29uc3Qgdm9pZCogcHN0cjIpIHsKKyAgICAgICAgcmV0dXJuIHN0cmNtcCgqKGNvbnN0IGNoYXIqKilwc3RyMSwgKihjb25zdCBjaGFyKiopcHN0cjIpOworICAgIH0KKworICAgIC8vCisgICAgLy8gR2V0IHRoZSAjb2YgaXRlbXMgaW4gdGhlIGFycmF5LgorICAgIC8vCisgICAgaW5saW5lIGludCBzaXplKHZvaWQpIGNvbnN0IHsgcmV0dXJuIG1DdXJyZW50OyB9CisKKyAgICAvLworICAgIC8vIFJldHVybiBlbnRyeSBOLgorICAgIC8vIFtzaG91bGQgdXNlIG9wZXJhdG9yW10gaGVyZV0KKyAgICAvLworICAgIGNvbnN0IGNoYXIqIGdldEVudHJ5KGludCBpZHgpIGNvbnN0IHsKKyAgICAgICAgaWYgKGlkeCA8IDAgfHwgaWR4ID49IG1DdXJyZW50KQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJldHVybiBtQXJyYXlbaWR4XTsKKyAgICB9CisKKyAgICAvLworICAgIC8vIFNldCBlbnRyeSBOIHRvIHNwZWNpZmllZCBzdHJpbmcuCisgICAgLy8gW3Nob3VsZCB1c2Ugb3BlcmF0b3JbXSBoZXJlXQorICAgIC8vCisgICAgdm9pZCBzZXRFbnRyeShpbnQgaWR4LCBjb25zdCBjaGFyKiBzdHIpIHsKKyAgICAgICAgaWYgKGlkeCA8IDAgfHwgaWR4ID49IG1DdXJyZW50KQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBkZWxldGVbXSBtQXJyYXlbaWR4XTsKKyAgICAgICAgaW50IGxlbiA9IHN0cmxlbihzdHIpOworICAgICAgICBtQXJyYXlbaWR4XSA9IG5ldyBjaGFyW2xlbisxXTsKKyAgICAgICAgbWVtY3B5KG1BcnJheVtpZHhdLCBzdHIsIGxlbisxKTsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgaW50ICAgICBtTWF4OworICAgIGludCAgICAgbUN1cnJlbnQ7CisgICAgY2hhcioqICBtQXJyYXk7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gX0xJQlNfVVRJTFNfU1RSSU5HX0FSUkFZX0gKZGlmZiAtLWdpdCBhL2luY2x1ZGUvdXRpbHMvdGhyZWFkcy5oIGIvaW5jbHVkZS91dGlscy90aHJlYWRzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2RjYTgxMAotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvdXRpbHMvdGhyZWFkcy5oCkBAIC0wLDAgKzEsMzQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBfTElCU19VVElMU19USFJFQURTX0gKKyNkZWZpbmUgX0xJQlNfVVRJTFNfVEhSRUFEU19ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx0aW1lLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gQyBBUEkKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCit0eXBlZGVmIHZvaWQqIGFuZHJvaWRfdGhyZWFkX2lkX3Q7CisKK3R5cGVkZWYgaW50ICgqYW5kcm9pZF90aHJlYWRfZnVuY190KSh2b2lkKik7CisKK2VudW0geworICAgIC8qCisgICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAgICAgKiAqKiBLZWVwIGluIHN5bmMgd2l0aCBhbmRyb2lkLm9zLlByb2Nlc3MuamF2YSAqKgorICAgICAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICogCisgICAgICogVGhpcyBtYXBzIGRpcmVjdGx5IHRvIHRoZSAibmljZSIgcHJpb3JpdGVzIHdlIHVzZSBpbiBBbmRyb2lkLgorICAgICAqIEEgdGhyZWFkIHByaW9yaXR5IHNob3VsZCBiZSBjaG9zZW4gaW52ZXJzZS1wcm9wb3J0aW5hbGx5IHRvCisgICAgICogdGhlIGFtb3VudCBvZiB3b3JrIHRoZSB0aHJlYWQgaXMgZXhwZWN0ZWQgdG8gZG8uIFRoZSBtb3JlIHdvcmsKKyAgICAgKiBhIHRocmVhZCB3aWxsIGRvLCB0aGUgbGVzcyBmYXZvcmFibGUgcHJpb3JpdHkgaXQgc2hvdWxkIGdldCBzbyB0aGF0IAorICAgICAqIGl0IGRvZXNuJ3Qgc3RhcnZlIHRoZSBzeXN0ZW0uIFRocmVhZHMgbm90IGJlaGF2aW5nIHByb3Blcmx5IG1pZ2h0CisgICAgICogYmUgInB1bmlzaGVkIiBieSB0aGUga2VybmVsLgorICAgICAqIFVzZSB0aGUgbGV2ZWxzIGJlbG93IHdoZW4gYXBwcm9wcmlhdGUuIEludGVybWVkaWF0ZSB2YWx1ZXMgYXJlCisgICAgICogYWNjZXB0YWJsZSwgcHJlZmVyYWJseSB1c2UgdGhlIHtNT1JFfExFU1N9X0ZBVk9SQUJMRSBjb25zdGFudHMgYmVsb3cuCisgICAgICovCisgICAgQU5EUk9JRF9QUklPUklUWV9MT1dFU1QgICAgICAgICA9ICAxOSwKKworICAgIC8qIHVzZSBmb3IgYmFja2dyb3VuZCB0YXNrcyAqLworICAgIEFORFJPSURfUFJJT1JJVFlfQkFDS0dST1VORCAgICAgPSAgMTAsCisgICAgCisgICAgLyogbW9zdCB0aHJlYWRzIHJ1biBhdCBub3JtYWwgcHJpb3JpdHkgKi8KKyAgICBBTkRST0lEX1BSSU9SSVRZX05PUk1BTCAgICAgICAgID0gICAwLAorICAgIAorICAgIC8qIHRocmVhZHMgY3VycmVudGx5IHJ1bm5pbmcgYSBVSSB0aGF0IHRoZSB1c2VyIGlzIGludGVyYWN0aW5nIHdpdGggKi8KKyAgICBBTkRST0lEX1BSSU9SSVRZX0ZPUkVHUk9VTkQgICAgID0gIC0yLAorCisgICAgLyogdGhlIG1haW4gVUkgdGhyZWFkIGhhcyBhIHNsaWdodGx5IG1vcmUgZmF2b3JhYmxlIHByaW9yaXR5ICovCisgICAgQU5EUk9JRF9QUklPUklUWV9ESVNQTEFZICAgICAgICA9ICAtNCwKKyAgICAKKyAgICAvKiB1aSBzZXJ2aWNlIHRyZWFkcyBtaWdodCB3YW50IHRvIHJ1biBhdCBhIHVyZ2VudCBkaXNwbGF5ICh1bmNvbW1vbikgKi8KKyAgICBBTkRST0lEX1BSSU9SSVRZX1VSR0VOVF9ESVNQTEFZID0gIC04LAorICAgIAorICAgIC8qIGFsbCBub3JtYWwgYXVkaW8gdGhyZWFkcyAqLworICAgIEFORFJPSURfUFJJT1JJVFlfQVVESU8gICAgICAgICAgPSAtMTYsCisgICAgCisgICAgLyogc2VydmljZSBhdWRpbyB0aHJlYWRzICh1bmNvbW1vbikgKi8KKyAgICBBTkRST0lEX1BSSU9SSVRZX1VSR0VOVF9BVURJTyAgID0gLTE5LAorCisgICAgLyogc2hvdWxkIG5ldmVyIGJlIHVzZWQgaW4gcHJhY3RpY2UuIHJlZ3VsYXIgcHJvY2VzcyBtaWdodCBub3QgCisgICAgICogYmUgYWxsb3dlZCB0byB1c2UgdGhpcyBsZXZlbCAqLworICAgIEFORFJPSURfUFJJT1JJVFlfSElHSEVTVCAgICAgICAgPSAtMjAsCisKKyAgICBBTkRST0lEX1BSSU9SSVRZX0RFRkFVTFQgICAgICAgID0gQU5EUk9JRF9QUklPUklUWV9OT1JNQUwsCisgICAgQU5EUk9JRF9QUklPUklUWV9NT1JFX0ZBVk9SQUJMRSA9IC0xLAorICAgIEFORFJPSURfUFJJT1JJVFlfTEVTU19GQVZPUkFCTEUgPSArMSwKK307CisKKy8vIENyZWF0ZSBhbmQgcnVuIGEgbmV3IHRocmVhZC4KK2V4dGVybiBpbnQgYW5kcm9pZENyZWF0ZVRocmVhZChhbmRyb2lkX3RocmVhZF9mdW5jX3QsIHZvaWQgKik7CisKKy8vIENyZWF0ZSB0aHJlYWQgd2l0aCBsb3RzIG9mIHBhcmFtZXRlcnMKK2V4dGVybiBpbnQgYW5kcm9pZENyZWF0ZVRocmVhZEV0YyhhbmRyb2lkX3RocmVhZF9mdW5jX3QgZW50cnlGdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp1c2VyRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB0aHJlYWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGhyZWFkUHJpb3JpdHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRocmVhZFN0YWNrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkX3RocmVhZF9pZF90ICp0aHJlYWRJZCk7CisKKy8vIEdldCBzb21lIHNvcnQgb2YgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IHRocmVhZC4KK2V4dGVybiBhbmRyb2lkX3RocmVhZF9pZF90IGFuZHJvaWRHZXRUaHJlYWRJZCgpOworCisvLyBMb3ctbGV2ZWwgdGhyZWFkIGNyZWF0aW9uIC0tIG5ldmVyIGNyZWF0ZXMgdGhyZWFkcyB0aGF0IGNhbgorLy8gaW50ZXJhY3Qgd2l0aCB0aGUgSmF2YSBWTS4KK2V4dGVybiBpbnQgYW5kcm9pZENyZWF0ZVJhd1RocmVhZEV0YyhhbmRyb2lkX3RocmVhZF9mdW5jX3QgZW50cnlGdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp1c2VyRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB0aHJlYWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGhyZWFkUHJpb3JpdHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRocmVhZFN0YWNrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkX3RocmVhZF9pZF90ICp0aHJlYWRJZCk7CisKKy8vIFVzZWQgYnkgdGhlIEphdmEgUnVudGltZSB0byBjb250cm9sIGhvdyB0aHJlYWRzIGFyZSBjcmVhdGVkLCBzbyB0aGF0CisvLyB0aGV5IGNhbiBiZSBwcm9wZXIgYW5kIGxvdmVseSBKYXZhIHRocmVhZHMuCit0eXBlZGVmIGludCAoKmFuZHJvaWRfY3JlYXRlX3RocmVhZF9mbikoYW5kcm9pZF90aHJlYWRfZnVuY190IGVudHJ5RnVuY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdXNlckRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdGhyZWFkTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRocmVhZFByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0aHJlYWRTdGFja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kcm9pZF90aHJlYWRfaWRfdCAqdGhyZWFkSWQpOworCitleHRlcm4gdm9pZCBhbmRyb2lkU2V0Q3JlYXRlVGhyZWFkRnVuYyhhbmRyb2lkX2NyZWF0ZV90aHJlYWRfZm4gZnVuYyk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gQysrIEFQSQorCisjaWZkZWYgX19jcGx1c3BsdXMKKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9UaW1lcnMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCit0eXBlZGVmIGFuZHJvaWRfdGhyZWFkX2lkX3QgdGhyZWFkX2lkX3Q7CisKK3R5cGVkZWYgYW5kcm9pZF90aHJlYWRfZnVuY190IHRocmVhZF9mdW5jX3Q7CisKK2VudW0geworICAgIFBSSU9SSVRZX0xPV0VTVCAgICAgICAgID0gQU5EUk9JRF9QUklPUklUWV9MT1dFU1QsCisgICAgUFJJT1JJVFlfQkFDS0dST1VORCAgICAgPSBBTkRST0lEX1BSSU9SSVRZX0JBQ0tHUk9VTkQsCisgICAgUFJJT1JJVFlfTk9STUFMICAgICAgICAgPSBBTkRST0lEX1BSSU9SSVRZX05PUk1BTCwKKyAgICBQUklPUklUWV9GT1JFR1JPVU5EICAgICA9IEFORFJPSURfUFJJT1JJVFlfRk9SRUdST1VORCwKKyAgICBQUklPUklUWV9ESVNQTEFZICAgICAgICA9IEFORFJPSURfUFJJT1JJVFlfRElTUExBWSwKKyAgICBQUklPUklUWV9VUkdFTlRfRElTUExBWSA9IEFORFJPSURfUFJJT1JJVFlfVVJHRU5UX0RJU1BMQVksCisgICAgUFJJT1JJVFlfQVVESU8gICAgICAgICAgPSBBTkRST0lEX1BSSU9SSVRZX0FVRElPLAorICAgIFBSSU9SSVRZX1VSR0VOVF9BVURJTyAgID0gQU5EUk9JRF9QUklPUklUWV9VUkdFTlRfQVVESU8sCisgICAgUFJJT1JJVFlfSElHSEVTVCAgICAgICAgPSBBTkRST0lEX1BSSU9SSVRZX0hJR0hFU1QsCisgICAgUFJJT1JJVFlfREVGQVVMVCAgICAgICAgPSBBTkRST0lEX1BSSU9SSVRZX0RFRkFVTFQsCisgICAgUFJJT1JJVFlfTU9SRV9GQVZPUkFCTEUgPSBBTkRST0lEX1BSSU9SSVRZX01PUkVfRkFWT1JBQkxFLAorICAgIFBSSU9SSVRZX0xFU1NfRkFWT1JBQkxFID0gQU5EUk9JRF9QUklPUklUWV9MRVNTX0ZBVk9SQUJMRSwKK307CisKKy8vIENyZWF0ZSBhbmQgcnVuIGEgbmV3IHRocmVhZC4KK2lubGluZSBib29sIGNyZWF0ZVRocmVhZCh0aHJlYWRfZnVuY190IGYsIHZvaWQgKmEpIHsKKyAgICByZXR1cm4gYW5kcm9pZENyZWF0ZVRocmVhZChmLCBhKSA/IHRydWUgOiBmYWxzZTsKK30KKworLy8gQ3JlYXRlIHRocmVhZCB3aXRoIGxvdHMgb2YgcGFyYW1ldGVycworaW5saW5lIGJvb2wgY3JlYXRlVGhyZWFkRXRjKHRocmVhZF9mdW5jX3QgZW50cnlGdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp1c2VyRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB0aHJlYWROYW1lID0gImFuZHJvaWQ6dW5uYW1lZF90aHJlYWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGhyZWFkUHJpb3JpdHkgPSBQUklPUklUWV9ERUZBVUxULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0aHJlYWRTdGFja1NpemUgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVhZF9pZF90ICp0aHJlYWRJZCA9IDApCit7CisgICAgcmV0dXJuIGFuZHJvaWRDcmVhdGVUaHJlYWRFdGMoZW50cnlGdW5jdGlvbiwgdXNlckRhdGEsIHRocmVhZE5hbWUsCisgICAgICAgIHRocmVhZFByaW9yaXR5LCB0aHJlYWRTdGFja1NpemUsIHRocmVhZElkKSA/IHRydWUgOiBmYWxzZTsKK30KKworLy8gR2V0IHNvbWUgc29ydCBvZiB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLgoraW5saW5lIHRocmVhZF9pZF90IGdldFRocmVhZElkKCkgeworICAgIHJldHVybiBhbmRyb2lkR2V0VGhyZWFkSWQoKTsKK30KKworLyoKKyAqIFNpbXBsZSBtdXRleCBjbGFzcy4gIFRoZSBpbXBsZW1lbnRhdGlvbiBpcyBzeXN0ZW0tZGVwZW5kZW50LgorICoKKyAqIFRoZSBtdXRleCBtdXN0IGJlIHVubG9ja2VkIGJ5IHRoZSB0aHJlYWQgdGhhdCBsb2NrZWQgaXQuICBUaGV5IGFyZSBub3QKKyAqIHJlY3Vyc2l2ZSwgaS5lLiB0aGUgc2FtZSB0aHJlYWQgY2FuJ3QgbG9jayBpdCBtdWx0aXBsZSB0aW1lcy4KKyAqLworY2xhc3MgTXV0ZXggeworcHVibGljOgorICAgICAgICAgICAgICAgIE11dGV4KCk7CisgICAgICAgICAgICAgICAgTXV0ZXgoY29uc3QgY2hhciogbmFtZSk7CisgICAgICAgICAgICAgICAgfk11dGV4KCk7CisKKyAgICAvLyBsb2NrIG9yIHVubG9jayB0aGUgbXV0ZXgKKyAgICBzdGF0dXNfdCAgICBsb2NrKCk7CisgICAgdm9pZCAgICAgICAgdW5sb2NrKCk7CisKKyAgICAvLyBsb2NrIGlmIHBvc3NpYmxlOyByZXR1cm5zIDAgb24gc3VjY2VzcywgZXJyb3Igb3RoZXJ3aXNlCisgICAgc3RhdHVzX3QgICAgdHJ5TG9jaygpOworCisgICAgLy8gTWFuYWdlcyB0aGUgbXV0ZXggYXV0b21hdGljYWxseS4gSXQnbGwgYmUgbG9ja2VkIHdoZW4gQXV0b2xvY2sgaXMKKyAgICAvLyBjb25zdHJ1Y3RlZCBhbmQgcmVsZWFzZWQgd2hlbiBBdXRvbG9jayBnb2VzIG91dCBvZiBzY29wZS4KKyAgICBjbGFzcyBBdXRvbG9jayB7CisgICAgcHVibGljOgorICAgICAgICBpbmxpbmUgQXV0b2xvY2soTXV0ZXgmIG11dGV4KSA6IG1wTXV0ZXgoJm11dGV4KSB7IG11dGV4LmxvY2soKTsgfQorICAgICAgICBpbmxpbmUgQXV0b2xvY2soTXV0ZXgqIG11dGV4KSA6IG1wTXV0ZXgobXV0ZXgpIHsgbXV0ZXgtPmxvY2soKTsgfQorICAgICAgICBpbmxpbmUgfkF1dG9sb2NrKCkgeyBtcE11dGV4LT51bmxvY2soKTsgfQorICAgIHByaXZhdGU6CisgICAgICAgIE11dGV4KiAgbXBNdXRleDsKKyAgICB9OworCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBDb25kaXRpb247CisgICAgCisgICAgLy8gQSBtdXRleCBjYW5ub3QgYmUgY29waWVkCisgICAgICAgICAgICAgICAgTXV0ZXgoY29uc3QgTXV0ZXgmKTsKKyAgICBNdXRleCYgICAgICBvcGVyYXRvciA9IChjb25zdCBNdXRleCYpOworICAgIHZvaWQgICAgICAgIF9pbml0KCk7CisgICAgCisgICAgdm9pZCogICBtU3RhdGU7Cit9OworCisvKgorICogQXV0b21hdGljIG11dGV4LiAgRGVjbGFyZSBvbmUgb2YgdGhlc2UgYXQgdGhlIHRvcCBvZiBhIGZ1bmN0aW9uLgorICogV2hlbiB0aGUgZnVuY3Rpb24gcmV0dXJucywgaXQgd2lsbCBnbyBvdXQgb2Ygc2NvcGUsIGFuZCByZWxlYXNlIHRoZQorICogbXV0ZXguCisgKi8KKyAKK3R5cGVkZWYgTXV0ZXg6OkF1dG9sb2NrIEF1dG9NdXRleDsKKworCisvKgorICogQ29uZGl0aW9uIHZhcmlhYmxlIGNsYXNzLiAgVGhlIGltcGxlbWVudGF0aW9uIGlzIHN5c3RlbS1kZXBlbmRlbnQuCisgKgorICogQ29uZGl0aW9uIHZhcmlhYmxlcyBhcmUgcGFpcmVkIHVwIHdpdGggbXV0ZXhlcy4gIExvY2sgdGhlIG11dGV4LAorICogY2FsbCB3YWl0KCksIHRoZW4gZWl0aGVyIHJlLXdhaXQoKSBpZiB0aGluZ3MgYXJlbid0IHF1aXRlIHdoYXQgeW91IHdhbnQsCisgKiBvciB1bmxvY2sgdGhlIG11dGV4IGFuZCBjb250aW51ZS4gIEFsbCB0aHJlYWRzIGNhbGxpbmcgd2FpdCgpIG11c3QKKyAqIHVzZSB0aGUgc2FtZSBtdXRleCBmb3IgYSBnaXZlbiBDb25kaXRpb24uCisgKi8KK2NsYXNzIENvbmRpdGlvbiB7CitwdWJsaWM6CisgICAgQ29uZGl0aW9uKCk7CisgICAgfkNvbmRpdGlvbigpOworICAgIC8vIFdhaXQgb24gdGhlIGNvbmRpdGlvbiB2YXJpYWJsZS4gIExvY2sgdGhlIG11dGV4IGJlZm9yZSBjYWxsaW5nLgorICAgIHN0YXR1c190IHdhaXQoTXV0ZXgmIG11dGV4KTsKKyAgICAvLyBXYWl0IG9uIHRoZSBjb25kaXRpb24gdmFyaWFibGUgdW50aWwgdGhlIGdpdmVuIHRpbWUuICBMb2NrIHRoZSBtdXRleAorICAgIC8vIGJlZm9yZSBjYWxsaW5nLgorICAgIHN0YXR1c190IHdhaXQoTXV0ZXgmIG11dGV4LCBuc2Vjc190IGFic3RpbWUpOworICAgIC8vIHNhbWUgd2l0aCByZWxhdGl2ZSB0aW1lb3V0CisgICAgc3RhdHVzX3Qgd2FpdFJlbGF0aXZlKE11dGV4JiBtdXRleCwgbnNlY3NfdCByZWx0aW1lKTsKKyAgICAvLyBTaWduYWwgdGhlIGNvbmRpdGlvbiB2YXJpYWJsZSwgYWxsb3dpbmcgb25lIHRocmVhZCB0byBjb250aW51ZS4KKyAgICB2b2lkIHNpZ25hbCgpOworICAgIC8vIFNpZ25hbCB0aGUgY29uZGl0aW9uIHZhcmlhYmxlLCBhbGxvd2luZyBhbGwgdGhyZWFkcyB0byBjb250aW51ZS4KKyAgICB2b2lkIGJyb2FkY2FzdCgpOworCitwcml2YXRlOgorICAgIHZvaWQqICAgbVN0YXRlOworfTsKKworCisvKgorICogUmVhZC93cml0ZSBsb2NrLiAgVGhlIHJlc291cmNlIGNhbiBoYXZlIG11bHRpcGxlIHJlYWRlcnMgb3Igb25lIHdyaXRlciwKKyAqIGJ1dCBjYW4ndCBiZSByZWFkIGFuZCB3cml0dGVuIGF0IHRoZSBzYW1lIHRpbWUuCisgKgorICogVGhlIHNhbWUgdGhyZWFkIHNob3VsZCBub3QgY2FsbCBhIGxvY2sgZnVuY3Rpb24gd2hpbGUgaXQgYWxyZWFkeSBoYXMKKyAqIGEgbG9jay4gIChTaG91bGQgYmUgb2theSBmb3IgbXVsdGlwbGUgcmVhZGVycy4pCisgKi8KK2NsYXNzIFJlYWRXcml0ZUxvY2sgeworcHVibGljOgorICAgIFJlYWRXcml0ZUxvY2soKQorICAgICAgICA6IG1OdW1SZWFkZXJzKDApLCBtTnVtV3JpdGVycygwKQorICAgICAgICB7fQorICAgIH5SZWFkV3JpdGVMb2NrKCkge30KKworICAgIHZvaWQgbG9ja0ZvclJlYWQoKTsKKyAgICBib29sIHRyeUxvY2tGb3JSZWFkKCk7CisgICAgdm9pZCB1bmxvY2tGb3JSZWFkKCk7CisKKyAgICB2b2lkIGxvY2tGb3JXcml0ZSgpOworICAgIGJvb2wgdHJ5TG9ja0ZvcldyaXRlKCk7CisgICAgdm9pZCB1bmxvY2tGb3JXcml0ZSgpOworCitwcml2YXRlOgorICAgIGludCAgICAgICAgIG1OdW1SZWFkZXJzOworICAgIGludCAgICAgICAgIG1OdW1Xcml0ZXJzOworCisgICAgTXV0ZXggICAgICAgbUxvY2s7CisgICAgQ29uZGl0aW9uICAgbVJlYWRXYWl0ZXI7CisgICAgQ29uZGl0aW9uICAgbVdyaXRlV2FpdGVyOworI2lmIGRlZmluZWQoUFJJTlRfUkVOREVSX1RJTUVTKQorICAgIER1cmF0aW9uVGltZXIgbURlYnVnVGltZXI7CisjZW5kaWYKK307CisKKworLyoKKyAqIFRoaXMgaXMgb3VyIHNwaWZmeSB0aHJlYWQgb2JqZWN0IQorICovCisKK2NsYXNzIFRocmVhZCA6IHZpcnR1YWwgcHVibGljIFJlZkJhc2UKK3sKK3B1YmxpYzoKKyAgICAvLyBDcmVhdGUgYSBUaHJlYWQgb2JqZWN0LCBidXQgZG9lc24ndCBjcmVhdGUgb3Igc3RhcnQgdGhlIGFzc29jaWF0ZWQKKyAgICAvLyB0aHJlYWQuIFNlZSB0aGUgcnVuKCkgbWV0aG9kLgorICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkKGJvb2wgY2FuQ2FsbEphdmEgPSB0cnVlKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5UaHJlYWQoKTsKKworICAgIC8vIFN0YXJ0IHRoZSB0aHJlYWQgaW4gdGhyZWFkTG9vcCgpIHdoaWNoIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkLgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgcnVuKCAgICBjb25zdCBjaGFyKiBuYW1lID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBwcmlvcml0eSA9IFBSSU9SSVRZX0RFRkFVTFQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzdGFjayA9IDApOworICAgIAorICAgIC8vIEFzayB0aGlzIG9iamVjdCdzIHRocmVhZCB0byBleGl0LiBUaGlzIGZ1bmN0aW9uIGlzIGFzeW5jaHJvbm91cywgd2hlbiB0aGUKKyAgICAvLyBmdW5jdGlvbiByZXR1cm5zIHRoZSB0aHJlYWQgbWlnaHQgc3RpbGwgYmUgcnVubmluZy4gT2YgY291cnNlLCB0aGlzCisgICAgLy8gZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCBmcm9tIGEgZGlmZmVyZW50IHRocmVhZC4KKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHJlcXVlc3RFeGl0KCk7CisKKyAgICAvLyBHb29kIHBsYWNlIHRvIGRvIG9uZS10aW1lIGluaXRpYWxpemF0aW9ucworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgcmVhZHlUb1J1bigpOworICAgIAorICAgIC8vIENhbGwgcmVxdWVzdEV4aXQoKSBhbmQgd2FpdCB1bnRpbCB0aGlzIG9iamVjdCdzIHRocmVhZCBleGl0cy4KKyAgICAvLyBCRSBWRVJZIENBUkVGVUwgb2YgZGVhZGxvY2tzLiBJbiBwYXJ0aWN1bGFyLCBpdCB3b3VsZCBiZSBzaWxseSB0byBjYWxsCisgICAgLy8gdGhpcyBmdW5jdGlvbiBmcm9tIHRoaXMgb2JqZWN0J3MgdGhyZWFkLiBXaWxsIHJldHVybiBXT1VMRF9CTE9DSyBpbgorICAgIC8vIHRoYXQgY2FzZS4KKyAgICAgICAgICAgIHN0YXR1c190ICAgIHJlcXVlc3RFeGl0QW5kV2FpdCgpOworCitwcm90ZWN0ZWQ6CisgICAgLy8gZXhpdFBlbmRpbmcoKSByZXR1cm5zIHRydWUgaWYgcmVxdWVzdEV4aXQoKSBoYXMgYmVlbiBjYWxsZWQuCisgICAgICAgICAgICBib29sICAgICAgICBleGl0UGVuZGluZygpIGNvbnN0OworICAgIAorcHJpdmF0ZToKKyAgICAvLyBEZXJpdmVkIGNsYXNzIG11c3QgaW1wbGVtdGVudCB0aHJlYWRMb29wKCkuIFRoZSB0aHJlYWQgc3RhcnRzIGl0cyBsaWZlCisgICAgLy8gaGVyZS4gVGhlcmUgYXJlIHR3byB3YXlzIG9mIHVzaW5nIHRoZSBUaHJlYWQgb2JqZWN0OgorICAgIC8vIDEpIGxvb3A6IGlmIHRocmVhZExvb3AoKSByZXR1cm5zIHRydWUsIGl0IHdpbGwgYmUgY2FsbGVkIGFnYWluIGlmCisgICAgLy8gICAgICAgICAgcmVxdWVzdEV4aXQoKSB3YXNuJ3QgY2FsbGVkLgorICAgIC8vIDIpIG9uY2U6IGlmIHRocmVhZExvb3AoKSByZXR1cm5zIGZhbHNlLCB0aGUgdGhyZWFkIHdpbGwgZXhpdCB1cG9uIHJldHVybi4KKyAgICB2aXJ0dWFsIGJvb2wgICAgICAgIHRocmVhZExvb3AoKSA9IDA7CisKK3ByaXZhdGU6CisgICAgVGhyZWFkJiBvcGVyYXRvcj0oY29uc3QgVGhyZWFkJik7CisgICAgc3RhdGljICBpbnQgICAgICAgICAgICAgX3RocmVhZExvb3Aodm9pZCogdXNlcik7CisgICAgY29uc3QgICBib29sICAgICAgICAgICAgbUNhbkNhbGxKYXZhOworICAgICAgICAgICAgdGhyZWFkX2lkX3QgICAgIG1UaHJlYWQ7CisgICAgICAgICAgICBNdXRleCAgICAgICAgICAgbUxvY2s7CisgICAgICAgICAgICBDb25kaXRpb24gICAgICAgbVRocmVhZEV4aXRlZENvbmRpdGlvbjsKKyAgICAgICAgICAgIHN0YXR1c190ICAgICAgICBtU3RhdHVzOworICAgIHZvbGF0aWxlIGJvb2wgICAgICAgICAgIG1FeGl0UGVuZGluZzsKKyAgICB2b2xhdGlsZSBib29sICAgICAgICAgICBtUnVubmluZzsKKyAgICAgICAgICAgIHNwPFRocmVhZD4gICAgICBtSG9sZFNlbGY7Cit9OworCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAgLy8gX19jcGx1c3BsdXMKKworI2VuZGlmIC8vIF9MSUJTX1VUSUxTX1RIUkVBRFNfSApkaWZmIC0tZ2l0IGEvbGlicy9hdWRpb2ZsaW5nZXIvQTJkcEF1ZGlvSW50ZXJmYWNlLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0EyZHBBdWRpb0ludGVyZmFjZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIwMGY4YwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvYXVkaW9mbGluZ2VyL0EyZHBBdWRpb0ludGVyZmFjZS5jcHAKQEAgLTAsMCArMSwyNDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8bWF0aC5oPgorCisjZGVmaW5lIExPR19OREVCVUcgMAorI2RlZmluZSBMT0dfVEFHICJBMmRwQXVkaW9JbnRlcmZhY2UiCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorCisjaW5jbHVkZSAiQTJkcEF1ZGlvSW50ZXJmYWNlLmgiCisjaW5jbHVkZSAiYXVkaW8vbGliYTJkcC5oIgorCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBMmRwQXVkaW9JbnRlcmZhY2U6OkEyZHBBdWRpb0ludGVyZmFjZSgpIDoKKyAgICBtT3V0cHV0KDApCit7Cit9CisKK0EyZHBBdWRpb0ludGVyZmFjZTo6fkEyZHBBdWRpb0ludGVyZmFjZSgpCit7CisgICAgZGVsZXRlIG1PdXRwdXQ7Cit9CisKK3N0YXR1c190IEEyZHBBdWRpb0ludGVyZmFjZTo6aW5pdENoZWNrKCkKK3sKKyAgICByZXR1cm4gMDsKK30KKworQXVkaW9TdHJlYW1PdXQqIEEyZHBBdWRpb0ludGVyZmFjZTo6b3Blbk91dHB1dFN0cmVhbSgKKyAgICAgICAgaW50IGZvcm1hdCwgaW50IGNoYW5uZWxDb3VudCwgdWludDMyX3Qgc2FtcGxlUmF0ZSwgc3RhdHVzX3QgKnN0YXR1cykKK3sKKyAgICBMT0dEKCJBMmRwQXVkaW9JbnRlcmZhY2U6Om9wZW5PdXRwdXRTdHJlYW0gJWQsICVkLCAlZFxuIiwgZm9ybWF0LCBjaGFubmVsQ291bnQsIHNhbXBsZVJhdGUpOworICAgIE11dGV4OjpBdXRvbG9jayBsb2NrKG1Mb2NrKTsKKyAgICBzdGF0dXNfdCBlcnIgPSAwOworCisgICAgLy8gb25seSBvbmUgb3V0cHV0IHN0cmVhbSBhbGxvd2VkCisgICAgaWYgKG1PdXRwdXQpIHsKKyAgICAgICAgaWYgKHN0YXR1cykKKyAgICAgICAgICAgICpzdGF0dXMgPSAtMTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLy8gY3JlYXRlIG5ldyBvdXRwdXQgc3RyZWFtCisgICAgQTJkcEF1ZGlvU3RyZWFtT3V0KiBvdXQgPSBuZXcgQTJkcEF1ZGlvU3RyZWFtT3V0KCk7CisgICAgaWYgKChlcnIgPSBvdXQtPnNldChmb3JtYXQsIGNoYW5uZWxDb3VudCwgc2FtcGxlUmF0ZSkpID09IE5PX0VSUk9SKSB7CisgICAgICAgIG1PdXRwdXQgPSBvdXQ7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZGVsZXRlIG91dDsKKyAgICB9CisgICAgCisgICAgaWYgKHN0YXR1cykKKyAgICAgICAgKnN0YXR1cyA9IGVycjsKKyAgICByZXR1cm4gbU91dHB1dDsKK30KKworQXVkaW9TdHJlYW1JbiogQTJkcEF1ZGlvSW50ZXJmYWNlOjpvcGVuSW5wdXRTdHJlYW0oCisgICAgICAgIGludCBmb3JtYXQsIGludCBjaGFubmVsQ291bnQsIHVpbnQzMl90IHNhbXBsZVJhdGUsIHN0YXR1c190ICpzdGF0dXMsCisgICAgICAgIEF1ZGlvU3lzdGVtOjphdWRpb19pbl9hY291c3RpY3MgYWNvdXN0aWNzKQoreworICAgIGlmIChzdGF0dXMpCisgICAgICAgICpzdGF0dXMgPSAtMTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpzZXRNaWNNdXRlKGJvb2wgc3RhdGUpCit7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXR1c190IEEyZHBBdWRpb0ludGVyZmFjZTo6Z2V0TWljTXV0ZShib29sKiBzdGF0ZSkKK3sKKyAgICByZXR1cm4gMDsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpzZXRQYXJhbWV0ZXIoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKK3sKKyAgICBMT0dEKCJzZXRQYXJhbWV0ZXIgJXMsJXNcbiIsIGtleSwgdmFsdWUpOworICAgIAorICAgIGlmICgha2V5IHx8ICF2YWx1ZSkKKyAgICAgICAgcmV0dXJuIC1FSU5WQUw7CisgICAgCisgICAgaWYgKHN0cmNtcChrZXksICJhMmRwX3NpbmtfYWRkcmVzcyIpID09IDApIHsgICAgICAgIAorICAgICAgICByZXR1cm4gbU91dHB1dC0+c2V0QWRkcmVzcyh2YWx1ZSk7CisgICAgfQorICAgIGlmIChzdHJjbXAoa2V5LCAiYmx1ZXRvb3RoX2VuYWJsZWQiKSA9PSAwICYmCisgICAgICAgIHN0cmNtcCh2YWx1ZSwgImZhbHNlIikgPT0gMCkgeworICAgICAgICByZXR1cm4gbU91dHB1dC0+Y2xvc2UoKTsKKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpzZXRWb2ljZVZvbHVtZShmbG9hdCB2KQoreworICAgIHJldHVybiAwOworfQorCitzdGF0dXNfdCBBMmRwQXVkaW9JbnRlcmZhY2U6OnNldE1hc3RlclZvbHVtZShmbG9hdCB2KQoreworICAgIHJldHVybiAwOworfQorCitzdGF0dXNfdCBBMmRwQXVkaW9JbnRlcmZhY2U6OmRvUm91dGluZygpCit7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXR1c190IEEyZHBBdWRpb0ludGVyZmFjZTo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgcmV0dXJuIDA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQTJkcEF1ZGlvSW50ZXJmYWNlOjpBMmRwQXVkaW9TdHJlYW1PdXQ6OkEyZHBBdWRpb1N0cmVhbU91dCgpIDoKKyAgICBtRmQoLTEpLCBtU3RhbmRieSh0cnVlKSwgbVN0YXJ0Q291bnQoMCksIG1SZXRyeUNvdW50KDApLCBtRGF0YShOVUxMKQoreworICAgIC8vIHVzZSBhbnkgYWRkcmVzcyBieSBkZWZhdWx0CisgICAgc3RybmNweShtQTJkcEFkZHJlc3MsICIwMDowMDowMDowMDowMDowMCIsIHNpemVvZihtQTJkcEFkZHJlc3MpKTsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpBMmRwQXVkaW9TdHJlYW1PdXQ6OnNldCgKKyAgICAgICAgaW50IGZvcm1hdCwgaW50IGNoYW5uZWxzLCB1aW50MzJfdCByYXRlKQoreworICAgIExPR0QoIkEyZHBBdWRpb1N0cmVhbU91dDo6c2V0ICVkLCAlZCwgJWRcbiIsIGZvcm1hdCwgY2hhbm5lbHMsIHJhdGUpOworCisgICAgLy8gZml4IHVwIGRlZmF1bHRzCisgICAgaWYgKGZvcm1hdCA9PSAwKSBmb3JtYXQgPSBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVDsKKyAgICBpZiAoY2hhbm5lbHMgPT0gMCkgY2hhbm5lbHMgPSBjaGFubmVsQ291bnQoKTsKKyAgICBpZiAocmF0ZSA9PSAwKSByYXRlID0gc2FtcGxlUmF0ZSgpOworCisgICAgLy8gY2hlY2sgdmFsdWVzCisgICAgaWYgKChmb3JtYXQgIT0gQXVkaW9TeXN0ZW06OlBDTV8xNl9CSVQpIHx8CisgICAgICAgICAgICAoY2hhbm5lbHMgIT0gY2hhbm5lbENvdW50KCkpIHx8CisgICAgICAgICAgICAocmF0ZSAhPSBzYW1wbGVSYXRlKCkpKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitBMmRwQXVkaW9JbnRlcmZhY2U6OkEyZHBBdWRpb1N0cmVhbU91dDo6fkEyZHBBdWRpb1N0cmVhbU91dCgpCit7CisgICAgY2xvc2UoKTsKK30KKworc3NpemVfdCBBMmRwQXVkaW9JbnRlcmZhY2U6OkEyZHBBdWRpb1N0cmVhbU91dDo6d3JpdGUoY29uc3Qgdm9pZCogYnVmZmVyLCBzaXplX3QgYnl0ZXMpCit7ICAgIAorICAgIHN0YXR1c190IHN0YXR1cyA9IE5PX0lOSVQ7CisgICAgc2l6ZV90IHJlbWFpbmluZyA9IGJ5dGVzOworCisgICAgaWYgKCFtRGF0YSkgeworICAgICAgICBzdGF0dXMgPSBhMmRwX2luaXQoNDQxMDAsIDIsICZtRGF0YSk7CisgICAgICAgIGlmIChzdGF0dXMgPCAwKSB7CisgICAgICAgICAgICBMT0dFKCJhMmRwX2luaXQgZmFpbGVkIGVycjogJWRcbiIsIHN0YXR1cyk7CisgICAgICAgICAgICBtRGF0YSA9IE5VTEw7CisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICB9CisgICAgICAgIGEyZHBfc2V0X3NpbmsobURhdGEsIG1BMmRwQWRkcmVzcyk7CisgICAgfQorICAgIAorICAgIHdoaWxlIChyZW1haW5pbmcgPiAwKSB7CisgICAgICAgIHN0YXR1cyA9IGEyZHBfd3JpdGUobURhdGEsIGJ1ZmZlciwgcmVtYWluaW5nKTsKKyAgICAgICAgaWYgKHN0YXR1cyA8PSAwKSB7CisgICAgICAgICAgICBMT0dFKCJhMmRwX3dyaXRlIGZhaWxlZCBlcnI6ICVkXG4iLCBzdGF0dXMpOworICAgICAgICAgICAgZ290byBFcnJvcjsKKyAgICAgICAgfQorICAgICAgICByZW1haW5pbmcgLT0gc3RhdHVzOworICAgICAgICBidWZmZXIgPSAoKGNoYXIgKilidWZmZXIpICsgc3RhdHVzOworICAgIH0KKworICAgIG1TdGFuZGJ5ID0gZmFsc2U7CisgICAgCisgICAgcmV0dXJuIGJ5dGVzOworCitFcnJvcjoKKyAgICAvLyBTaW11bGF0ZSBhdWRpbyBvdXRwdXQgdGltaW5nIGluIGNhc2Ugb2YgZXJyb3IKKyAgICB1c2xlZXAoYnl0ZXMgKiAxMDAwMDAwIC8gZnJhbWVTaXplKCkgLyBzYW1wbGVSYXRlKCkpOworCisgICAgcmV0dXJuIHN0YXR1czsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpBMmRwQXVkaW9TdHJlYW1PdXQ6OnN0YW5kYnkoKQoreworICAgIGludCByZXN1bHQgPSAwOworCisgICAgaWYgKCFtU3RhbmRieSkgeworICAgICAgICByZXN1bHQgPSBhMmRwX3N0b3AobURhdGEpOworICAgICAgICBpZiAocmVzdWx0ID09IDApCisgICAgICAgICAgICBtU3RhbmRieSA9IHRydWU7CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdHVzX3QgQTJkcEF1ZGlvSW50ZXJmYWNlOjpBMmRwQXVkaW9TdHJlYW1PdXQ6OnNldEFkZHJlc3MoY29uc3QgY2hhciogYWRkcmVzcykKK3sKKyAgICBpZiAoc3RybGVuKGFkZHJlc3MpIDwgc2l6ZW9mKG1BMmRwQWRkcmVzcykpCisgICAgICAgIHJldHVybiAtRUlOVkFMOworCisgICAgaWYgKHN0cmNtcChhZGRyZXNzLCBtQTJkcEFkZHJlc3MpKSB7CisgICAgICAgIHN0cmNweShtQTJkcEFkZHJlc3MsIGFkZHJlc3MpOworICAgICAgICBpZiAobURhdGEpCisgICAgICAgICAgICBhMmRwX3NldF9zaW5rKG1EYXRhLCBtQTJkcEFkZHJlc3MpOworICAgIH0KKyAgICAKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IEEyZHBBdWRpb0ludGVyZmFjZTo6QTJkcEF1ZGlvU3RyZWFtT3V0OjpjbG9zZSgpCit7CisgICAgaWYgKG1EYXRhKSB7CisgICAgICAgIGEyZHBfY2xlYW51cChtRGF0YSk7CisgICAgICAgIG1EYXRhID0gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBMmRwQXVkaW9JbnRlcmZhY2U6OkEyZHBBdWRpb1N0cmVhbU91dDo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BMmRwQXVkaW9JbnRlcmZhY2UuaCBiL2xpYnMvYXVkaW9mbGluZ2VyL0EyZHBBdWRpb0ludGVyZmFjZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1NmU4YTAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BMmRwQXVkaW9JbnRlcmZhY2UuaApAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQTJEUF9BVURJT19IQVJEV0FSRV9ICisjZGVmaW5lIEEyRFBfQVVESU9fSEFSRFdBUkVfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDxoYXJkd2FyZV9sZWdhY3kvQXVkaW9IYXJkd2FyZUJhc2UuaD4KKworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEEyZHBBdWRpb0ludGVyZmFjZSA6IHB1YmxpYyBBdWRpb0hhcmR3YXJlQmFzZQoreworICAgIGNsYXNzIEEyZHBBdWRpb1N0cmVhbU91dDsKKworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgQTJkcEF1ZGlvSW50ZXJmYWNlKCk7CisgICAgdmlydHVhbCAgICAgICAgICAgICB+QTJkcEF1ZGlvSW50ZXJmYWNlKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBpbml0Q2hlY2soKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0Vm9pY2VWb2x1bWUoZmxvYXQgdm9sdW1lKTsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldE1hc3RlclZvbHVtZShmbG9hdCB2b2x1bWUpOworCisgICAgLy8gbWljIG11dGUKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldE1pY011dGUoYm9vbCBzdGF0ZSk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBnZXRNaWNNdXRlKGJvb2wqIHN0YXRlKTsKKworICAgIC8vIFRlbXBvcmFyeSBpbnRlcmZhY2UsIGRvIG5vdCB1c2UKKyAgICAvLyBUT0RPOiBSZXBsYWNlIHdpdGggYSBtb3JlIGdlbmVyaWMga2V5OnZhbHVlIGdldC9zZXQgbWVjaGFuaXNtCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRQYXJhbWV0ZXIoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSk7CisKKyAgICAvLyBjcmVhdGUgSS9PIHN0cmVhbXMKKyAgICB2aXJ0dWFsIEF1ZGlvU3RyZWFtT3V0KiBvcGVuT3V0cHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9ybWF0PTAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFubmVsQ291bnQ9MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZT0wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfdCAqc3RhdHVzPTApOworCisgICAgdmlydHVhbCBBdWRpb1N0cmVhbUluKiBvcGVuSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFubmVsQ291bnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICpzdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvU3lzdGVtOjphdWRpb19pbl9hY291c3RpY3MgYWNvdXN0aWNzKTsKKworcHJvdGVjdGVkOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZG9Sb3V0aW5nKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKK3ByaXZhdGU6CisgICAgY2xhc3MgQTJkcEF1ZGlvU3RyZWFtT3V0IDogcHVibGljIEF1ZGlvU3RyZWFtT3V0IHsKKyAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQTJkcEF1ZGlvU3RyZWFtT3V0KCk7CisgICAgICAgIHZpcnR1YWwgICAgICAgICAgICAgfkEyZHBBdWRpb1N0cmVhbU91dCgpOworICAgICAgICAgICAgICAgIHN0YXR1c190ICAgIHNldChpbnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlKTsKKyAgICAgICAgdmlydHVhbCB1aW50MzJfdCAgICBzYW1wbGVSYXRlKCkgY29uc3QgeyByZXR1cm4gNDQxMDA7IH0KKyAgICAgICAgLy8gU0JDIGNvZGVjIHdhbnRzIGEgbXVsdGlwbGUgb2YgNTEyCisgICAgICAgIHZpcnR1YWwgc2l6ZV90ICAgICAgYnVmZmVyU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIDUxMiAqIDIwOyB9CisgICAgICAgIHZpcnR1YWwgaW50ICAgICAgICAgY2hhbm5lbENvdW50KCkgY29uc3QgeyByZXR1cm4gMjsgfQorICAgICAgICB2aXJ0dWFsIGludCAgICAgICAgIGZvcm1hdCgpIGNvbnN0IHsgcmV0dXJuIEF1ZGlvU3lzdGVtOjpQQ01fMTZfQklUOyB9CisgICAgICAgIHZpcnR1YWwgdWludDMyX3QgICAgbGF0ZW5jeSgpIGNvbnN0IHsgcmV0dXJuICgoMTAwMCpidWZmZXJTaXplKCkpL2ZyYW1lU2l6ZSgpKS9zYW1wbGVSYXRlKCkgKyAyMDA7IH0KKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRWb2x1bWUoZmxvYXQgdm9sdW1lKSB7IHJldHVybiBJTlZBTElEX09QRVJBVElPTjsgfQorICAgICAgICB2aXJ0dWFsIHNzaXplX3QgICAgIHdyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgc2l6ZV90IGJ5dGVzKTsKKyAgICAgICAgICAgICAgICBzdGF0dXNfdCAgICBzdGFuZGJ5KCk7CisgICAgICAgICAgICAgICAgc3RhdHVzX3QgICAgY2xvc2UoKTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICBwcml2YXRlOgorICAgICAgICBmcmllbmQgY2xhc3MgQTJkcEF1ZGlvSW50ZXJmYWNlOworICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIHNldEFkZHJlc3MoY29uc3QgY2hhciogYWRkcmVzcyk7CisKKyAgICBwcml2YXRlOgorICAgICAgICAgICAgICAgIGludCAgICAgICAgIG1GZDsKKyAgICAgICAgICAgICAgICBib29sICAgICAgICBtU3RhbmRieTsKKyAgICAgICAgICAgICAgICBpbnQgICAgICAgICBtU3RhcnRDb3VudDsKKyAgICAgICAgICAgICAgICBpbnQgICAgICAgICBtUmV0cnlDb3VudDsKKyAgICAgICAgICAgICAgICBjaGFyICAgICAgICBtQTJkcEFkZHJlc3NbMjBdOworICAgICAgICAgICAgICAgIHZvaWQqICAgICAgIG1EYXRhOworICAgIH07CisKKyAgICBNdXRleCAgICAgICAgICAgICAgICAgICBtTG9jazsKKyAgICBBMmRwQXVkaW9TdHJlYW1PdXQqICAgICBtT3V0cHV0OworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQTJEUF9BVURJT19IQVJEV0FSRV9ICmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BbmRyb2lkLm1rIGIvbGlicy9hdWRpb2ZsaW5nZXIvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGQ1MTZiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQW5kcm9pZC5tawpAQCAtMCwwICsxLDU2IEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKyAgICBBdWRpb0hhcmR3YXJlR2VuZXJpYy5jcHAgXAorICAgIEF1ZGlvSGFyZHdhcmVTdHViLmNwcCBcCisgICAgQXVkaW9EdW1wSW50ZXJmYWNlLmNwcCBcCisgICAgQXVkaW9IYXJkd2FyZUludGVyZmFjZS5jcHAKKworTE9DQUxfU0hBUkVEX0xJQlJBUklFUyA6PSBcCisgICAgbGliY3V0aWxzIFwKKyAgICBsaWJ1dGlscyBcCisgICAgbGlibWVkaWEgXAorICAgIGxpYmhhcmR3YXJlX2xlZ2FjeQorCitpZmVxICgkKHN0cmlwICQoQk9BUkRfVVNFU19HRU5FUklDX0FVRElPKSksdHJ1ZSkKKyAgTE9DQUxfQ0ZMQUdTICs9IC1ER0VORVJJQ19BVURJTworZW5kaWYKKworTE9DQUxfTU9EVUxFOj0gbGliYXVkaW9pbnRlcmZhY2UKKworaW5jbHVkZSAkKEJVSUxEX1NUQVRJQ19MSUJSQVJZKQorCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfU1JDX0ZJTEVTOj0gICAgICAgICAgICAgICBcCisgICAgQXVkaW9GbGluZ2VyLmNwcCAgICAgICAgICAgIFwKKyAgICBBdWRpb01peGVyLmNwcC5hcm0gICAgICAgICAgXAorICAgIEF1ZGlvUmVzYW1wbGVyLmNwcC5hcm0gICAgICBcCisgICAgQXVkaW9SZXNhbXBsZXJTaW5jLmNwcC5hcm0gIFwKKyAgICBBdWRpb1Jlc2FtcGxlckN1YmljLmNwcC5hcm0KKworTE9DQUxfU0hBUkVEX0xJQlJBUklFUyA6PSBcCisgICAgbGliY3V0aWxzIFwKKyAgICBsaWJ1dGlscyBcCisgICAgbGlibWVkaWEgXAorICAgIGxpYmhhcmR3YXJlX2xlZ2FjeQorCitpZmVxICgkKHN0cmlwICQoQk9BUkRfVVNFU19HRU5FUklDX0FVRElPKSksdHJ1ZSkKKyAgTE9DQUxfU1RBVElDX0xJQlJBUklFUyArPSBsaWJhdWRpb2ludGVyZmFjZQorZWxzZQorICBMT0NBTF9TSEFSRURfTElCUkFSSUVTICs9IGxpYmF1ZGlvCitlbmRpZgorCitMT0NBTF9NT0RVTEU6PSBsaWJhdWRpb2ZsaW5nZXIKKworaWZlcSAoJChCT0FSRF9IQVZFX0JMVUVUT09USCksdHJ1ZSkKKyAgTE9DQUxfU1JDX0ZJTEVTICs9IEEyZHBBdWRpb0ludGVyZmFjZS5jcHAKKyAgTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBsaWJhMmRwCisgIExPQ0FMX0NGTEFHUyArPSAtRFdJVEhfQkxVRVRPT1RIIC1EV0lUSF9BMkRQCisgIExPQ0FMX0NfSU5DTFVERVMgKz0gJChjYWxsIGluY2x1ZGUtcGF0aC1mb3IsIGJsdWV6LWxpYnMpCisgIExPQ0FMX0NfSU5DTFVERVMgKz0gJChjYWxsIGluY2x1ZGUtcGF0aC1mb3IsIGJsdWV6LXV0aWxzKQorZW5kaWYKKworaW5jbHVkZSAkKEJVSUxEX1NIQVJFRF9MSUJSQVJZKQpkaWZmIC0tZ2l0IGEvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9CdWZmZXJQcm92aWRlci5oIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9CdWZmZXJQcm92aWRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhNDY3YzcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0J1ZmZlclByb3ZpZGVyLmgKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9BVURJT19CVUZGRVJfUFJPVklERVJfSAorI2RlZmluZSBBTkRST0lEX0FVRElPX0JVRkZFUl9QUk9WSURFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBBdWRpb0J1ZmZlclByb3ZpZGVyCit7CitwdWJsaWM6CisKKyAgICBzdHJ1Y3QgQnVmZmVyIHsKKyAgICAgICAgdW5pb24geworICAgICAgICAgICAgdm9pZCogICAgICAgcmF3OworICAgICAgICAgICAgc2hvcnQqICAgICAgaTE2OworICAgICAgICAgICAgaW50OF90KiAgICAgaTg7CisgICAgICAgIH07CisgICAgICAgIHNpemVfdCBmcmFtZUNvdW50OworICAgIH07CisgICAgCisgICAgdmlydHVhbCBzdGF0dXNfdCBnZXROZXh0QnVmZmVyKEJ1ZmZlciogYnVmZmVyKSA9IDA7CisgICAgdmlydHVhbCB2b2lkIHJlbGVhc2VCdWZmZXIoQnVmZmVyKiBidWZmZXIpID0gMDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0FVRElPX0JVRkZFUl9QUk9WSURFUl9ICmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0R1bXBJbnRlcmZhY2UuY3BwIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9EdW1wSW50ZXJmYWNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDk0MGNiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9EdW1wSW50ZXJmYWNlLmNwcApAQCAtMCwwICsxLDExNyBAQAorLyogLy9kZXZpY2Uvc2VydmVycy9BdWRpb0ZsaW5nZXIvQXVkaW9EdW1wSW50ZXJmYWNlLmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjZGVmaW5lIExPR19UQUcgIkF1ZGlvRmxpbmdlckR1bXAiCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCisjaW5jbHVkZSAiQXVkaW9EdW1wSW50ZXJmYWNlLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworYm9vbCBnRmlyc3QgPSB0cnVlOyAgICAgICAvLyB0cnVlIGlmIGZpcnN0IHdyaXRlIGFmdGVyIGEgc3RhbmRieQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvRHVtcEludGVyZmFjZTo6QXVkaW9EdW1wSW50ZXJmYWNlKEF1ZGlvSGFyZHdhcmVJbnRlcmZhY2UqIGh3KQoreworICAgIGlmKGh3ID09IDApIHsKKyAgICAgICAgTE9HRSgiRHVtcCBjb25zdHJ1Y3QgaHcgPSAwIik7CisgICAgfQorICAgIG1GaW5hbEludGVyZmFjZSA9IGh3OworICAgIG1TdHJlYW1PdXQgPSAwOworfQorCisKK0F1ZGlvRHVtcEludGVyZmFjZTo6fkF1ZGlvRHVtcEludGVyZmFjZSgpCit7CisgICAgaWYobUZpbmFsSW50ZXJmYWNlKSBkZWxldGUgbUZpbmFsSW50ZXJmYWNlOworICAgIGlmKG1TdHJlYW1PdXQpIGRlbGV0ZSBtU3RyZWFtT3V0OworfQorCisKK0F1ZGlvU3RyZWFtT3V0KiBBdWRpb0R1bXBJbnRlcmZhY2U6Om9wZW5PdXRwdXRTdHJlYW0oCisgICAgICAgIGludCBmb3JtYXQsIGludCBjaGFubmVsQ291bnQsIHVpbnQzMl90IHNhbXBsZVJhdGUsIHN0YXR1c190ICpzdGF0dXMpCit7CisgICAgQXVkaW9TdHJlYW1PdXQqIG91dEZpbmFsID0gbUZpbmFsSW50ZXJmYWNlLT5vcGVuT3V0cHV0U3RyZWFtKGZvcm1hdCwgY2hhbm5lbENvdW50LCBzYW1wbGVSYXRlLCBzdGF0dXMpOworCisgICAgaWYob3V0RmluYWwpIHsKKyAgICAgICAgbVN0cmVhbU91dCA9ICBuZXcgQXVkaW9TdHJlYW1PdXREdW1wKG91dEZpbmFsKTsKKyAgICAgICAgcmV0dXJuIG1TdHJlYW1PdXQ7CisgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HRSgiRHVtcCBvdXRGaW5hbD0wIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBdWRpb1N0cmVhbU91dER1bXA6OkF1ZGlvU3RyZWFtT3V0RHVtcCggQXVkaW9TdHJlYW1PdXQqIGZpbmFsU3RyZWFtKQoreworICAgIG1GaW5hbFN0cmVhbSA9IGZpbmFsU3RyZWFtOworICAgIG1PdXRGaWxlID0gMDsKK30KKworCitBdWRpb1N0cmVhbU91dER1bXA6On5BdWRpb1N0cmVhbU91dER1bXAoKQoreworICAgIENsb3NlKCk7CisgICAgZGVsZXRlIG1GaW5hbFN0cmVhbTsKK30KKworc3NpemVfdCBBdWRpb1N0cmVhbU91dER1bXA6OndyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgc2l6ZV90IGJ5dGVzKQoreworICAgIHNzaXplX3QgcmV0OworCisgICAgcmV0ID0gbUZpbmFsU3RyZWFtLT53cml0ZShidWZmZXIsIGJ5dGVzKTsKKyAgICBpZighbU91dEZpbGUgJiYgZ0ZpcnN0KSB7CisgICAgICAgIGdGaXJzdCA9IGZhbHNlOworICAgICAgICAvLyBjaGVjayBpZiBkdW1wIGZpbGUgZXhpc3QKKyAgICAgICAgbU91dEZpbGUgPSBmb3BlbihGTElOR0VSX0RVTVBfTkFNRSwgInIiKTsKKyAgICAgICAgaWYobU91dEZpbGUpIHsKKyAgICAgICAgICAgIGZjbG9zZShtT3V0RmlsZSk7CisgICAgICAgICAgICBtT3V0RmlsZSA9IGZvcGVuKEZMSU5HRVJfRFVNUF9OQU1FLCAiYWIiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAobU91dEZpbGUpIHsKKyAgICAgICAgZndyaXRlKGJ1ZmZlciwgYnl0ZXMsIDEsIG1PdXRGaWxlKTsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKK30KKworc3RhdHVzX3QgQXVkaW9TdHJlYW1PdXREdW1wOjpzdGFuZGJ5KCkKK3sKKyAgICBDbG9zZSgpOworICAgIGdGaXJzdCA9IHRydWU7CisgICAgcmV0dXJuIG1GaW5hbFN0cmVhbS0+c3RhbmRieSgpOworfQorCisKK3ZvaWQgQXVkaW9TdHJlYW1PdXREdW1wOjpDbG9zZSh2b2lkKQoreworICAgIGlmKG1PdXRGaWxlKSB7CisgICAgICAgIGZjbG9zZShtT3V0RmlsZSk7CisgICAgICAgIG1PdXRGaWxlID0gMDsKKyAgICB9Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0R1bXBJbnRlcmZhY2UuaCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvRHVtcEludGVyZmFjZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhOTQxMDIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0R1bXBJbnRlcmZhY2UuaApAQCAtMCwwICsxLDk3IEBACisvKiAvL2RldmljZS9zZXJ2ZXJzL0F1ZGlvRmxpbmdlci9BdWRpb0R1bXBJbnRlcmZhY2UuaAorKioKKyoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfQVVESU9fRFVNUF9JTlRFUkZBQ0VfSAorI2RlZmluZSBBTkRST0lEX0FVRElPX0RVTVBfSU5URVJGQUNFX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8aGFyZHdhcmVfbGVnYWN5L0F1ZGlvSGFyZHdhcmVCYXNlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworI2RlZmluZSBGTElOR0VSX0RVTVBfTkFNRSAiL2RhdGEvRmxpbmdlck91dC5wY20iIC8vIG5hbWUgb2YgZmlsZSB1c2VkIGZvciBkdW1wCisKK2NsYXNzIEF1ZGlvU3RyZWFtT3V0RHVtcCA6IHB1YmxpYyBBdWRpb1N0cmVhbU91dCB7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb1N0cmVhbU91dER1bXAoIEF1ZGlvU3RyZWFtT3V0KiBGaW5hbFN0cmVhbSk7CisgICAgICAgICAgICAgICAgICAgICAgICB+QXVkaW9TdHJlYW1PdXREdW1wKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB2aXJ0dWFsIHNzaXplX3QgICAgIHdyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgc2l6ZV90IGJ5dGVzKTsKKworICAgIHZpcnR1YWwgdWludDMyX3QgICAgc2FtcGxlUmF0ZSgpIGNvbnN0IHsgcmV0dXJuIG1GaW5hbFN0cmVhbS0+c2FtcGxlUmF0ZSgpOyB9CisgICAgdmlydHVhbCBzaXplX3QgICAgICBidWZmZXJTaXplKCkgY29uc3QgeyByZXR1cm4gbUZpbmFsU3RyZWFtLT5idWZmZXJTaXplKCk7IH0KKyAgICB2aXJ0dWFsIGludCAgICAgICAgIGNoYW5uZWxDb3VudCgpIGNvbnN0IHsgcmV0dXJuIG1GaW5hbFN0cmVhbS0+Y2hhbm5lbENvdW50KCk7IH0KKyAgICB2aXJ0dWFsIGludCAgICAgICAgIGZvcm1hdCgpIGNvbnN0IHsgcmV0dXJuIG1GaW5hbFN0cmVhbS0+Zm9ybWF0KCk7IH0KKyAgICB2aXJ0dWFsIHVpbnQzMl90ICAgIGxhdGVuY3koKSBjb25zdCB7IHJldHVybiBtRmluYWxTdHJlYW0tPmxhdGVuY3koKTsgfQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0Vm9sdW1lKGZsb2F0IHZvbHVtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBtRmluYWxTdHJlYW0tPnNldFZvbHVtZSh2b2x1bWUpOyB9CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFuZGJ5KCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykgeyByZXR1cm4gbUZpbmFsU3RyZWFtLT5kdW1wKGZkLCBhcmdzKTsgfQorICAgIHZvaWQgICAgICAgICAgICAgICAgQ2xvc2Uodm9pZCk7CisKK3ByaXZhdGU6CisgICAgQXVkaW9TdHJlYW1PdXQgICAgICAqbUZpbmFsU3RyZWFtOworICAgIEZJTEUgICAgICAgICAgICAgICAgKm1PdXRGaWxlOyAgICAgLy8gb3V0cHV0IGZpbGUKK307CisKKworY2xhc3MgQXVkaW9EdW1wSW50ZXJmYWNlIDogcHVibGljIEF1ZGlvSGFyZHdhcmVCYXNlCit7CisKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvRHVtcEludGVyZmFjZShBdWRpb0hhcmR3YXJlSW50ZXJmYWNlKiBodyk7CisgICAgdmlydHVhbCBBdWRpb1N0cmVhbU91dCogb3Blbk91dHB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdD0wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50PTAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGU9MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX3QgKnN0YXR1cz0wKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5BdWRpb0R1bXBJbnRlcmZhY2UoKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgaW5pdENoZWNrKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB7cmV0dXJuIG1GaW5hbEludGVyZmFjZS0+aW5pdENoZWNrKCk7fQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0Vm9pY2VWb2x1bWUoZmxvYXQgdm9sdW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtyZXR1cm4gbUZpbmFsSW50ZXJmYWNlLT5zZXRWb2ljZVZvbHVtZSh2b2x1bWUpO30KKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldE1hc3RlclZvbHVtZShmbG9hdCB2b2x1bWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPnNldE1hc3RlclZvbHVtZSh2b2x1bWUpO30KKworICAgIC8vIG1pYyBtdXRlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRNaWNNdXRlKGJvb2wgc3RhdGUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPnNldE1pY011dGUoc3RhdGUpO30KKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIGdldE1pY011dGUoYm9vbCogc3RhdGUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPmdldE1pY011dGUoc3RhdGUpO30KKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0UGFyYW1ldGVyKGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPnNldFBhcmFtZXRlcihrZXksIHZhbHVlKTt9CisKKyAgICB2aXJ0dWFsIEF1ZGlvU3RyZWFtSW4qIG9wZW5JbnB1dFN0cmVhbSggaW50IGZvcm1hdCwgaW50IGNoYW5uZWxDb3VudCwgdWludDMyX3Qgc2FtcGxlUmF0ZSwgc3RhdHVzX3QgKnN0YXR1cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9TeXN0ZW06OmF1ZGlvX2luX2Fjb3VzdGljcyBhY291c3RpY3MpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPm9wZW5JbnB1dFN0cmVhbSggZm9ybWF0LCBjaGFubmVsQ291bnQsIHNhbXBsZVJhdGUsIHN0YXR1cywgYWNvdXN0aWNzKTt9CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKSB7IHJldHVybiBtRmluYWxJbnRlcmZhY2UtPmR1bXBTdGF0ZShmZCwgYXJncyk7IH0KKworcHJvdGVjdGVkOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZG9Sb3V0aW5nKCkge3JldHVybiBtRmluYWxJbnRlcmZhY2UtPnNldFJvdXRpbmcobU1vZGUsIG1Sb3V0ZXNbbU1vZGVdKTt9CisKKyAgICBBdWRpb0hhcmR3YXJlSW50ZXJmYWNlICAqbUZpbmFsSW50ZXJmYWNlOworICAgIEF1ZGlvU3RyZWFtT3V0RHVtcCAgICAgICptU3RyZWFtT3V0OworCit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9BVURJT19EVU1QX0lOVEVSRkFDRV9ICmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0ZsaW5nZXIuY3BwIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9GbGluZ2VyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MmM0MGU5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9GbGluZ2VyLmNwcApAQCAtMCwwICsxLDI0NzQgQEAKKy8qIC8vZGV2aWNlL2luY2x1ZGUvc2VydmVyL0F1ZGlvRmxpbmdlci9BdWRpb0ZsaW5nZXIuY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKworI2RlZmluZSBMT0dfVEFHICJBdWRpb0ZsaW5nZXIiCisvLyNkZWZpbmUgTE9HX05ERUJVRyAwCisKKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8c2lnbmFsLmg+CisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKyNpbmNsdWRlIDxzeXMvcmVzb3VyY2UuaD4KKworI2luY2x1ZGUgPHV0aWxzL0lTZXJ2aWNlTWFuYWdlci5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL0lQQ1RocmVhZFN0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nMTYuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvcHJvcGVydGllcy5oPgorCisjaW5jbHVkZSA8bWVkaWEvQXVkaW9UcmFjay5oPgorI2luY2x1ZGUgPG1lZGlhL0F1ZGlvUmVjb3JkLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL21lZGlhL0F1ZGlvVHJhY2tTaGFyZWQuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlX2xlZ2FjeS9BdWRpb0hhcmR3YXJlSW50ZXJmYWNlLmg+CisKKyNpbmNsdWRlICJBdWRpb01peGVyLmgiCisjaW5jbHVkZSAiQXVkaW9GbGluZ2VyLmgiCisKKyNpZmRlZiBXSVRIX0EyRFAKKyNpbmNsdWRlICJBMmRwQXVkaW9JbnRlcmZhY2UuaCIKKyNlbmRpZgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyB0aGUgc2ltIGJ1aWxkIGRvZXNuJ3QgaGF2ZSBnZXR0aWQKKworI2lmbmRlZiBIQVZFX0dFVFRJRAorIyBkZWZpbmUgZ2V0dGlkIGdldHBpZAorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvL3N0YXRpYyBjb25zdCBuc2Vjc190IGtTdGFuZGJ5VGltZUluTnNlY3MgPSBzZWNvbmRzKDMpOworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGxvbmcga0J1ZmZlclJlY292ZXJ5SW5Vc2VjcyA9IDIwMDA7CitzdGF0aWMgY29uc3QgdW5zaWduZWQgbG9uZyBrTWF4QnVmZmVyUmVjb3ZlcnlJblVzZWNzID0gMjAwMDA7CitzdGF0aWMgY29uc3QgZmxvYXQgTUFYX0dBSU4gPSA0MDk2LjBmOworCisvLyByZXRyeSBjb3VudHMgZm9yIGJ1ZmZlciBmaWxsIHRpbWVvdXQKKy8vIDUwICogfjIwbXNlY3MgPSAxIHNlY29uZAorc3RhdGljIGNvbnN0IGludDhfdCBrTWF4VHJhY2tSZXRyaWVzID0gNTA7CitzdGF0aWMgY29uc3QgaW50OF90IGtNYXhUcmFja1N0YXJ0dXBSZXRyaWVzID0gNTA7CisKK3N0YXRpYyBjb25zdCBpbnQga1N0YXJ0U2xlZXBUaW1lID0gMzAwMDA7CitzdGF0aWMgY29uc3QgaW50IGtTdG9wU2xlZXBUaW1lID0gMzAwMDA7CisKKy8vIE1heGltdW0gbnVtYmVyIG9mIHBlbmRpbmcgYnVmZmVycyBhbGxvY2F0ZWQgYnkgT3V0cHV0VHJhY2s6OndyaXRlKCkKK3N0YXRpYyBjb25zdCB1aW50OF90IGtNYXhPdXRwdXRUcmFja0J1ZmZlcnMgPSA1OworCisKKyNkZWZpbmUgQVVESU9GTElOR0VSX1NFQ1VSSVRZX0VOQUJMRUQgMQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBib29sIHJlY29yZGluZ0FsbG93ZWQoKSB7CisjaWZuZGVmIEhBVkVfQU5EUk9JRF9PUworICAgIHJldHVybiB0cnVlOworI2VuZGlmCisjaWYgQVVESU9GTElOR0VSX1NFQ1VSSVRZX0VOQUJMRUQKKyAgICBpZiAoZ2V0cGlkKCkgPT0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1BpZCgpKSByZXR1cm4gdHJ1ZTsKKyAgICBib29sIG9rID0gY2hlY2tDYWxsaW5nUGVybWlzc2lvbihTdHJpbmcxNigiYW5kcm9pZC5wZXJtaXNzaW9uLlJFQ09SRF9BVURJTyIpKTsKKyAgICBpZiAoIW9rKSBMT0dFKCJSZXF1ZXN0IHJlcXVpcmVzIGFuZHJvaWQucGVybWlzc2lvbi5SRUNPUkRfQVVESU8iKTsKKyAgICByZXR1cm4gb2s7CisjZWxzZQorICAgIGlmICghY2hlY2tDYWxsaW5nUGVybWlzc2lvbihTdHJpbmcxNigiYW5kcm9pZC5wZXJtaXNzaW9uLlJFQ09SRF9BVURJTyIpKSkKKyAgICAgICAgTE9HVygiV0FSTklORzogTmVlZCB0byBhZGQgYW5kcm9pZC5wZXJtaXNzaW9uLlJFQ09SRF9BVURJTyB0byBtYW5pZmVzdCIpOworICAgIHJldHVybiB0cnVlOworI2VuZGlmCit9CisKK3N0YXRpYyBib29sIHNldHRpbmdzQWxsb3dlZCgpIHsKKyNpZm5kZWYgSEFWRV9BTkRST0lEX09TCisgICAgcmV0dXJuIHRydWU7CisjZW5kaWYKKyNpZiBBVURJT0ZMSU5HRVJfU0VDVVJJVFlfRU5BQkxFRAorICAgIGlmIChnZXRwaWQoKSA9PSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpIHJldHVybiB0cnVlOworICAgIGJvb2wgb2sgPSBjaGVja0NhbGxpbmdQZXJtaXNzaW9uKFN0cmluZzE2KCJhbmRyb2lkLnBlcm1pc3Npb24uTU9ESUZZX0FVRElPX1NFVFRJTkdTIikpOworICAgIGlmICghb2spIExPR0UoIlJlcXVlc3QgcmVxdWlyZXMgYW5kcm9pZC5wZXJtaXNzaW9uLk1PRElGWV9BVURJT19TRVRUSU5HUyIpOworICAgIHJldHVybiBvazsKKyNlbHNlCisgICAgaWYgKCFjaGVja0NhbGxpbmdQZXJtaXNzaW9uKFN0cmluZzE2KCJhbmRyb2lkLnBlcm1pc3Npb24uTU9ESUZZX0FVRElPX1NFVFRJTkdTIikpKQorICAgICAgICBMT0dXKCJXQVJOSU5HOiBOZWVkIHRvIGFkZCBhbmRyb2lkLnBlcm1pc3Npb24uTU9ESUZZX0FVRElPX1NFVFRJTkdTIHRvIG1hbmlmZXN0Iik7CisgICAgcmV0dXJuIHRydWU7CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBdWRpb0ZsaW5nZXI6OkF1ZGlvRmxpbmdlcigpCisgICAgOiBCbkF1ZGlvRmxpbmdlcigpLAorICAgICAgICBtQXVkaW9IYXJkd2FyZSgwKSwgbUEyZHBBdWRpb0ludGVyZmFjZSgwKSwKKyAgICAgICAgbUEyZHBFbmFibGVkKGZhbHNlKSwgbUEyZHBFbmFibGVkUmVxKGZhbHNlKSwKKyAgICAgICAgbUZvcmNlZFNwZWFrZXJDb3VudCgwKSwgbUZvcmNlZFJvdXRlKDApLCBtUm91dGVSZXN0b3JlVGltZSgwKSwgbU11c2ljTXV0ZVNhdmVkKGZhbHNlKQoreworICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0lETEU7CisgICAgbUF1ZGlvSGFyZHdhcmUgPSBBdWRpb0hhcmR3YXJlSW50ZXJmYWNlOjpjcmVhdGUoKTsKKyAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JTklUOworICAgIGlmIChtQXVkaW9IYXJkd2FyZS0+aW5pdENoZWNrKCkgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgLy8gb3BlbiAxNi1iaXQgb3V0cHV0IHN0cmVhbSBmb3Igcy93IG1peGVyCisgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX09VVFBVVF9PUEVOOworICAgICAgICBzdGF0dXNfdCBzdGF0dXM7CisgICAgICAgIEF1ZGlvU3RyZWFtT3V0ICpod091dHB1dCA9IG1BdWRpb0hhcmR3YXJlLT5vcGVuT3V0cHV0U3RyZWFtKEF1ZGlvU3lzdGVtOjpQQ01fMTZfQklULCAwLCAwLCAmc3RhdHVzKTsKKyAgICAgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICAgICAgaWYgKGh3T3V0cHV0KSB7CisgICAgICAgICAgICBtSGFyZHdhcmVNaXhlclRocmVhZCA9IG5ldyBNaXhlclRocmVhZCh0aGlzLCBod091dHB1dCwgQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9IQVJEV0FSRSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSBoYXJkd2FyZSBvdXRwdXQgc3RyZWFtLCBzdGF0dXM6ICVkIiwgc3RhdHVzKTsKKyAgICAgICAgfQorICAgICAgICAKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICAgICAgLy8gQ3JlYXRlIEEyRFAgaW50ZXJmYWNlCisgICAgICAgIG1BMmRwQXVkaW9JbnRlcmZhY2UgPSBuZXcgQTJkcEF1ZGlvSW50ZXJmYWNlKCk7CisgICAgICAgIEF1ZGlvU3RyZWFtT3V0ICphMmRwT3V0cHV0ID0gbUEyZHBBdWRpb0ludGVyZmFjZS0+b3Blbk91dHB1dFN0cmVhbShBdWRpb1N5c3RlbTo6UENNXzE2X0JJVCwgMCwgMCwgJnN0YXR1cyk7CisgICAgICAgIGlmIChhMmRwT3V0cHV0KSB7CisgICAgICAgICAgICBtQTJkcE1peGVyVGhyZWFkID0gbmV3IE1peGVyVGhyZWFkKHRoaXMsIGEyZHBPdXRwdXQsIEF1ZGlvU3lzdGVtOjpBVURJT19PVVRQVVRfQTJEUCk7CisgICAgICAgICAgICBpZiAoaHdPdXRwdXQpIHsgIAorICAgICAgICAgICAgICAgIHVpbnQzMl90IGZyYW1lQ291bnQgPSAoKGEyZHBPdXRwdXQtPmJ1ZmZlclNpemUoKS9hMmRwT3V0cHV0LT5mcmFtZVNpemUoKSkgKiBod091dHB1dC0+c2FtcGxlUmF0ZSgpKSAvIGEyZHBPdXRwdXQtPnNhbXBsZVJhdGUoKTsKKyAgICAgICAgICAgICAgICBNaXhlclRocmVhZDo6T3V0cHV0VHJhY2sgKmEyZHBPdXRUcmFjayA9IG5ldyBNaXhlclRocmVhZDo6T3V0cHV0VHJhY2sobUEyZHBNaXhlclRocmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh3T3V0cHV0LT5zYW1wbGVSYXRlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh3T3V0cHV0LT5jaGFubmVsQ291bnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lQ291bnQpOworICAgICAgICAgICAgICAgIG1IYXJkd2FyZU1peGVyVGhyZWFkLT5zZXRPdXB1dFRyYWNrKGEyZHBPdXRUcmFjayk7ICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HRSgiRmFpbGVkIHRvIGluaXRpYWxpemUgQTJEUCBvdXRwdXQgc3RyZWFtLCBzdGF0dXM6ICVkIiwgc3RhdHVzKTsKKyAgICAgICAgfQorI2VuZGlmCisgCisgICAgICAgIC8vIEZJWE1FIC0gdGhpcyBzaG91bGQgY29tZSBmcm9tIHNldHRpbmdzCisgICAgICAgIHNldFJvdXRpbmcoQXVkaW9TeXN0ZW06Ok1PREVfTk9STUFMLCBBdWRpb1N5c3RlbTo6Uk9VVEVfU1BFQUtFUiwgQXVkaW9TeXN0ZW06OlJPVVRFX0FMTCk7CisgICAgICAgIHNldFJvdXRpbmcoQXVkaW9TeXN0ZW06Ok1PREVfUklOR1RPTkUsIEF1ZGlvU3lzdGVtOjpST1VURV9TUEVBS0VSLCBBdWRpb1N5c3RlbTo6Uk9VVEVfQUxMKTsKKyAgICAgICAgc2V0Um91dGluZyhBdWRpb1N5c3RlbTo6TU9ERV9JTl9DQUxMLCBBdWRpb1N5c3RlbTo6Uk9VVEVfRUFSUElFQ0UsIEF1ZGlvU3lzdGVtOjpST1VURV9BTEwpOworICAgICAgICBzZXRNb2RlKEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCk7CisKKyAgICAgICAgc2V0TWFzdGVyVm9sdW1lKDEuMGYpOworICAgICAgICBzZXRNYXN0ZXJNdXRlKGZhbHNlKTsKKworICAgICAgICAvLyBTdGFydCByZWNvcmQgdGhyZWFkCisgICAgICAgIG1BdWRpb1JlY29yZFRocmVhZCA9IG5ldyBBdWRpb1JlY29yZFRocmVhZChtQXVkaW9IYXJkd2FyZSk7CisgICAgICAgIGlmIChtQXVkaW9SZWNvcmRUaHJlYWQgIT0gMCkgeworICAgICAgICAgICAgbUF1ZGlvUmVjb3JkVGhyZWFkLT5ydW4oIkF1ZGlvUmVjb3JkVGhyZWFkIiwgUFJJT1JJVFlfVVJHRU5UX0FVRElPKTsgICAgICAgICAgICAKKyAgICAgICAgfQorICAgICB9IGVsc2UgeworICAgICAgICBMT0dFKCJDb3VsZG4ndCBldmVuIGluaXRpYWxpemUgdGhlIHN0dWJiZWQgYXVkaW8gaGFyZHdhcmUhIik7CisgICAgfQorfQorCitBdWRpb0ZsaW5nZXI6On5BdWRpb0ZsaW5nZXIoKQoreworICAgIGlmIChtQXVkaW9SZWNvcmRUaHJlYWQgIT0gMCkgeworICAgICAgICBtQXVkaW9SZWNvcmRUaHJlYWQtPmV4aXQoKTsKKyAgICAgICAgbUF1ZGlvUmVjb3JkVGhyZWFkLmNsZWFyKCk7ICAgICAgICAKKyAgICB9CisgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQuY2xlYXIoKTsKKyAgICBkZWxldGUgbUF1ZGlvSGFyZHdhcmU7CisgICAgLy8gZGVsZXRpbmcgbUEyZHBBdWRpb0ludGVyZmFjZSBhbHNvIGRlbGV0ZXMgbUEyZHBPdXRwdXQ7CisjaWZkZWYgV0lUSF9BMkRQCisgICAgbUEyZHBNaXhlclRocmVhZC5jbGVhcigpOworICAgIGRlbGV0ZSBtQTJkcEF1ZGlvSW50ZXJmYWNlOworI2VuZGlmCit9CisKKworI2lmZGVmIFdJVEhfQTJEUAordm9pZCBBdWRpb0ZsaW5nZXI6OnNldEEyZHBFbmFibGVkKGJvb2wgZW5hYmxlKQoreworICAgIExPR1ZfSUYoZW5hYmxlLCAic2V0IG91dHB1dCB0byBBMkRQXG4iKTsKKyAgICBMT0dWX0lGKCFlbmFibGUsICJzZXQgb3V0cHV0IHRvIGhhcmR3YXJlIGF1ZGlvXG4iKTsKKworICAgIG1BMmRwRW5hYmxlZFJlcSA9IGVuYWJsZTsKKyAgICBtQTJkcE1peGVyVGhyZWFkLT53YWtlVXAoKTsKK30KKyNlbmRpZiAvLyBXSVRIX0EyRFAKKworYm9vbCBBdWRpb0ZsaW5nZXI6OnN0cmVhbUZvcmNlZFRvU3BlYWtlcihpbnQgc3RyZWFtVHlwZSkKK3sKKyAgICAvLyBOT1RFIHRoYXQgc3RyZWFtcyBsaXN0ZWQgaGVyZSBtdXN0IG5vdCBiZSByb3V0ZWQgdG8gQTJEUCBieSBkZWZhdWx0OgorICAgIC8vIEF1ZGlvU3lzdGVtOjpyb3V0ZWRUb0EyZHBPdXRwdXQoc3RyZWFtVHlwZSkgPT0gZmFsc2UKKyAgICByZXR1cm4gKHN0cmVhbVR5cGUgPT0gQXVkaW9TeXN0ZW06OlJJTkcgfHwKKyAgICAgICAgICAgIHN0cmVhbVR5cGUgPT0gQXVkaW9TeXN0ZW06OkFMQVJNIHx8CisgICAgICAgICAgICBzdHJlYW1UeXBlID09IEF1ZGlvU3lzdGVtOjpOT1RJRklDQVRJT04pOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6OmR1bXBDbGllbnRzKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKworICAgIHJlc3VsdC5hcHBlbmQoIkNsaWVudHM6XG4iKTsKKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1DbGllbnRzLnNpemUoKTsgKytpKSB7CisgICAgICAgIHdwPENsaWVudD4gd0NsaWVudCA9IG1DbGllbnRzLnZhbHVlQXQoaSk7CisgICAgICAgIGlmICh3Q2xpZW50ICE9IDApIHsKKyAgICAgICAgICAgIHNwPENsaWVudD4gY2xpZW50ID0gd0NsaWVudC5wcm9tb3RlKCk7CisgICAgICAgICAgICBpZiAoY2xpZW50ICE9IDApIHsKKyAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICIgIHBpZDogJWRcbiIsIGNsaWVudC0+cGlkKCkpOworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICB3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpkdW1wSW50ZXJuYWxzKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIkhhcmR3YXJlIHN0YXR1czogJWRcbiIsIG1IYXJkd2FyZVN0YXR1cyk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHdyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpkdW1wUGVybWlzc2lvbkRlbmlhbChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiUGVybWlzc2lvbiBEZW5pYWw6ICIKKyAgICAgICAgICAgICJjYW4ndCBkdW1wIEF1ZGlvRmxpbmdlciBmcm9tIHBpZD0lZCwgdWlkPSVkXG4iLAorICAgICAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1BpZCgpLAorICAgICAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1VpZCgpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgd3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGlmIChjaGVja0NhbGxpbmdQZXJtaXNzaW9uKFN0cmluZzE2KCJhbmRyb2lkLnBlcm1pc3Npb24uRFVNUCIpKSA9PSBmYWxzZSkgeworICAgICAgICBkdW1wUGVybWlzc2lvbkRlbmlhbChmZCwgYXJncyk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgQXV0b011dGV4IGxvY2soJm1Mb2NrKTsKKworICAgICAgICBkdW1wQ2xpZW50cyhmZCwgYXJncyk7CisgICAgICAgIGR1bXBJbnRlcm5hbHMoZmQsIGFyZ3MpOworICAgICAgICBtSGFyZHdhcmVNaXhlclRocmVhZC0+ZHVtcChmZCwgYXJncyk7CisjaWZkZWYgV0lUSF9BMkRQCisgICAgICAgIG1BMmRwTWl4ZXJUaHJlYWQtPmR1bXAoZmQsIGFyZ3MpOworI2VuZGlmCisKKyAgICAgICAgLy8gZHVtcCByZWNvcmQgY2xpZW50CisgICAgICAgIGlmIChtQXVkaW9SZWNvcmRUaHJlYWQgIT0gMCkgbUF1ZGlvUmVjb3JkVGhyZWFkLT5kdW1wKGZkLCBhcmdzKTsKKworICAgICAgICBpZiAobUF1ZGlvSGFyZHdhcmUpIHsKKyAgICAgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5kdW1wU3RhdGUoZmQsIGFyZ3MpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gSUF1ZGlvRmxpbmdlciBpbnRlcmZhY2UKKworCitzcDxJQXVkaW9UcmFjaz4gQXVkaW9GbGluZ2VyOjpjcmVhdGVUcmFjaygKKyAgICAgICAgcGlkX3QgcGlkLAorICAgICAgICBpbnQgc3RyZWFtVHlwZSwKKyAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgIHVpbnQzMl90IGZsYWdzLAorICAgICAgICBjb25zdCBzcDxJTWVtb3J5PiYgc2hhcmVkQnVmZmVyLAorICAgICAgICBzdGF0dXNfdCAqc3RhdHVzKQoreworICAgIHNwPE1peGVyVGhyZWFkOjpUcmFjaz4gdHJhY2s7CisgICAgc3A8VHJhY2tIYW5kbGU+IHRyYWNrSGFuZGxlOworICAgIHNwPENsaWVudD4gY2xpZW50OworICAgIHdwPENsaWVudD4gd2NsaWVudDsKKyAgICBzdGF0dXNfdCBsU3RhdHVzOworCisgICAgaWYgKHN0cmVhbVR5cGUgPj0gQXVkaW9TeXN0ZW06Ok5VTV9TVFJFQU1fVFlQRVMpIHsKKyAgICAgICAgTE9HRSgiaW52YWxpZCBzdHJlYW0gdHlwZSIpOworICAgICAgICBsU3RhdHVzID0gQkFEX1ZBTFVFOworICAgICAgICBnb3RvIEV4aXQ7CisgICAgfQorCisgICAgeworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworCisgICAgICAgIHdjbGllbnQgPSBtQ2xpZW50cy52YWx1ZUZvcihwaWQpOworCisgICAgICAgIGlmICh3Y2xpZW50ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGNsaWVudCA9IHdjbGllbnQucHJvbW90ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2xpZW50ID0gbmV3IENsaWVudCh0aGlzLCBwaWQpOworICAgICAgICAgICAgbUNsaWVudHMuYWRkKHBpZCwgY2xpZW50KTsKKyAgICAgICAgfQorI2lmZGVmIFdJVEhfQTJEUAorICAgICAgICBpZiAoaXNBMmRwRW5hYmxlZCgpICYmIEF1ZGlvU3lzdGVtOjpyb3V0ZWRUb0EyZHBPdXRwdXQoc3RyZWFtVHlwZSkpIHsKKyAgICAgICAgICAgIHRyYWNrID0gbUEyZHBNaXhlclRocmVhZC0+Y3JlYXRlVHJhY2soY2xpZW50LCBzdHJlYW1UeXBlLCBzYW1wbGVSYXRlLCBmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudCwgZnJhbWVDb3VudCwgc2hhcmVkQnVmZmVyLCAmbFN0YXR1cyk7ICAgICAgICAgICAgCisgICAgICAgIH0gZWxzZSAKKyNlbmRpZgorICAgICAgICB7CisgICAgICAgICAgICB0cmFjayA9IG1IYXJkd2FyZU1peGVyVGhyZWFkLT5jcmVhdGVUcmFjayhjbGllbnQsIHN0cmVhbVR5cGUsIHNhbXBsZVJhdGUsIGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50LCBmcmFtZUNvdW50LCBzaGFyZWRCdWZmZXIsICZsU3RhdHVzKTsgICAgICAgICAgICAKKyAgICAgICAgfQorICAgICAgICBpZiAodHJhY2sgIT0gTlVMTCkgeworICAgICAgICAgICAgdHJhY2tIYW5kbGUgPSBuZXcgVHJhY2tIYW5kbGUodHJhY2spOworICAgICAgICAgICAgbFN0YXR1cyA9IE5PX0VSUk9SOyAgICAgICAgICAgIAorICAgICAgICB9CisgICAgfQorCitFeGl0OgorICAgIGlmKHN0YXR1cykgeworICAgICAgICAqc3RhdHVzID0gbFN0YXR1czsKKyAgICB9CisgICAgcmV0dXJuIHRyYWNrSGFuZGxlOworfQorCit1aW50MzJfdCBBdWRpb0ZsaW5nZXI6OnNhbXBsZVJhdGUoaW50IG91dHB1dCkgY29uc3QKK3sKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICAgaWYgKG91dHB1dCA9PSBBdWRpb1N5c3RlbTo6QVVESU9fT1VUUFVUX0EyRFApIHsKKyAgICAgICAgIHJldHVybiBtQTJkcE1peGVyVGhyZWFkLT5zYW1wbGVSYXRlKCk7CisgICAgIH0KKyNlbmRpZgorICAgICByZXR1cm4gbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnNhbXBsZVJhdGUoKTsKK30KKworaW50IEF1ZGlvRmxpbmdlcjo6Y2hhbm5lbENvdW50KGludCBvdXRwdXQpIGNvbnN0Cit7CisjaWZkZWYgV0lUSF9BMkRQCisgICAgIGlmIChvdXRwdXQgPT0gQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9BMkRQKSB7CisgICAgICAgICByZXR1cm4gbUEyZHBNaXhlclRocmVhZC0+Y2hhbm5lbENvdW50KCk7CisgICAgIH0KKyNlbmRpZgorICAgICByZXR1cm4gbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPmNoYW5uZWxDb3VudCgpOworfQorCitpbnQgQXVkaW9GbGluZ2VyOjpmb3JtYXQoaW50IG91dHB1dCkgY29uc3QKK3sKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICAgaWYgKG91dHB1dCA9PSBBdWRpb1N5c3RlbTo6QVVESU9fT1VUUFVUX0EyRFApIHsKKyAgICAgICAgIHJldHVybiBtQTJkcE1peGVyVGhyZWFkLT5mb3JtYXQoKTsKKyAgICAgfQorI2VuZGlmCisgICAgIHJldHVybiBtSGFyZHdhcmVNaXhlclRocmVhZC0+Zm9ybWF0KCk7Cit9CisKK3NpemVfdCBBdWRpb0ZsaW5nZXI6OmZyYW1lQ291bnQoaW50IG91dHB1dCkgY29uc3QKK3sKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICAgaWYgKG91dHB1dCA9PSBBdWRpb1N5c3RlbTo6QVVESU9fT1VUUFVUX0EyRFApIHsKKyAgICAgICAgIHJldHVybiBtQTJkcE1peGVyVGhyZWFkLT5mcmFtZUNvdW50KCk7CisgICAgIH0KKyNlbmRpZgorICAgICByZXR1cm4gbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPmZyYW1lQ291bnQoKTsKK30KKwordWludDMyX3QgQXVkaW9GbGluZ2VyOjpsYXRlbmN5KGludCBvdXRwdXQpIGNvbnN0Cit7CisjaWZkZWYgV0lUSF9BMkRQCisgICAgIGlmIChvdXRwdXQgPT0gQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9BMkRQKSB7CisgICAgICAgICByZXR1cm4gbUEyZHBNaXhlclRocmVhZC0+bGF0ZW5jeSgpOworICAgICB9CisjZW5kaWYKKyAgICAgcmV0dXJuIG1IYXJkd2FyZU1peGVyVGhyZWFkLT5sYXRlbmN5KCk7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6c2V0TWFzdGVyVm9sdW1lKGZsb2F0IHZhbHVlKQoreworICAgIC8vIGNoZWNrIGNhbGxpbmcgcGVybWlzc2lvbnMKKyAgICBpZiAoIXNldHRpbmdzQWxsb3dlZCgpKSB7CisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICB9CisKKyAgICAvLyB3aGVuIGh3IHN1cHBvcnRzIG1hc3RlciB2b2x1bWUsIGRvbid0IHNjYWxlIGluIHN3IG1peGVyCisgICAgQXV0b011dGV4IGxvY2sobUhhcmR3YXJlTG9jayk7CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfU0VUX01BU1RFUl9WT0xVTUU7CisgICAgaWYgKG1BdWRpb0hhcmR3YXJlLT5zZXRNYXN0ZXJWb2x1bWUodmFsdWUpID09IE5PX0VSUk9SKSB7CisgICAgICAgIHZhbHVlID0gMS4wZjsKKyAgICB9CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICBtSGFyZHdhcmVNaXhlclRocmVhZC0+c2V0TWFzdGVyVm9sdW1lKHZhbHVlKTsKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICBtQTJkcE1peGVyVGhyZWFkLT5zZXRNYXN0ZXJWb2x1bWUodmFsdWUpOworI2VuZGlmCisgICAgCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6OnNldFJvdXRpbmcoaW50IG1vZGUsIHVpbnQzMl90IHJvdXRlcywgdWludDMyX3QgbWFzaykKK3sKKyAgICBzdGF0dXNfdCBlcnIgPSBOT19FUlJPUjsKKworICAgIC8vIGNoZWNrIGNhbGxpbmcgcGVybWlzc2lvbnMKKyAgICBpZiAoIXNldHRpbmdzQWxsb3dlZCgpKSB7CisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICB9CisgICAgaWYgKChtb2RlIDwgQXVkaW9TeXN0ZW06Ok1PREVfQ1VSUkVOVCkgfHwgKG1vZGUgPj0gQXVkaW9TeXN0ZW06Ok5VTV9NT0RFUykpIHsKKyAgICAgICAgTE9HVygiSWxsZWdhbCB2YWx1ZTogc2V0Um91dGluZyglZCwgJXUsICV1KSIsIG1vZGUsIHJvdXRlcywgbWFzayk7CisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisgICAgfQorCisjaWZkZWYgV0lUSF9BMkRQCisgICAgTE9HRCgic2V0Um91dGluZyAlZCAlZCAlZCwgdGlkICVkLCBjYWxsaW5nIHRpZCAlZFxuIiwgbW9kZSwgcm91dGVzLCBtYXNrLCBnZXR0aWQoKSwgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1BpZCgpKTsKKyAgICBpZiAobW9kZSA9PSBBdWRpb1N5c3RlbTo6TU9ERV9OT1JNQUwgJiYgCisgICAgICAgICAgICAobWFzayAmIEF1ZGlvU3lzdGVtOjpST1VURV9CTFVFVE9PVEhfQTJEUCkpIHsKKyAgICAgICAgQXV0b011dGV4IGxvY2soJm1Mb2NrKTsKKworICAgICAgICBib29sIGVuYWJsZUEyZHAgPSBmYWxzZTsKKyAgICAgICAgaWYgKHJvdXRlcyAmIEF1ZGlvU3lzdGVtOjpST1VURV9CTFVFVE9PVEhfQTJEUCkgeworICAgICAgICAgICAgZW5hYmxlQTJkcCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgc2V0QTJkcEVuYWJsZWQoZW5hYmxlQTJkcCk7CisgICAgICAgIExPR1YoInNldE91dHB1dCBkb25lXG4iKTsKKyAgICB9CisjZW5kaWYKKworICAgIC8vIGRvIG5vdGhpbmcgaWYgb25seSBBMkRQIHJvdXRpbmcgaXMgYWZmZWN0ZWQKKyAgICBtYXNrICY9IH5BdWRpb1N5c3RlbTo6Uk9VVEVfQkxVRVRPT1RIX0EyRFA7CisgICAgaWYgKG1hc2spIHsKKyAgICAgICAgQXV0b011dGV4IGxvY2sobUhhcmR3YXJlTG9jayk7CisgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0dFVF9ST1VUSU5HOworICAgICAgICB1aW50MzJfdCByOworICAgICAgICBlcnIgPSBtQXVkaW9IYXJkd2FyZS0+Z2V0Um91dGluZyhtb2RlLCAmcik7CisgICAgICAgIGlmIChlcnIgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgIHIgPSAociAmIH5tYXNrKSB8IChyb3V0ZXMgJiBtYXNrKTsKKyAgICAgICAgICAgIGlmIChtb2RlID09IEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCB8fCAKKyAgICAgICAgICAgICAgICAobW9kZSA9PSBBdWRpb1N5c3RlbTo6TU9ERV9DVVJSRU5UICYmIGdldE1vZGUoKSA9PSBBdWRpb1N5c3RlbTo6TU9ERV9OT1JNQUwpKSB7CisgICAgICAgICAgICAgICAgbVNhdmVkUm91dGUgPSByOworICAgICAgICAgICAgICAgIHIgfD0gbUZvcmNlZFJvdXRlOworICAgICAgICAgICAgICAgIExPR1YoInNldFJvdXRpbmcgbVNhdmVkUm91dGUgJTA4eCBtRm9yY2VkUm91dGUgJTA4eFxuIiwgbVNhdmVkUm91dGUsIG1Gb3JjZWRSb3V0ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19TRVRfUk9VVElORzsKKyAgICAgICAgICAgIGVyciA9IG1BdWRpb0hhcmR3YXJlLT5zZXRSb3V0aW5nKG1vZGUsIHIpOworICAgICAgICB9CisgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0lETEU7CisgICAgfQorICAgIHJldHVybiBlcnI7Cit9CisKK3VpbnQzMl90IEF1ZGlvRmxpbmdlcjo6Z2V0Um91dGluZyhpbnQgbW9kZSkgY29uc3QKK3sKKyAgICB1aW50MzJfdCByb3V0ZXMgPSAwOworICAgIGlmICgobW9kZSA+PSBBdWRpb1N5c3RlbTo6TU9ERV9DVVJSRU5UKSAmJiAobW9kZSA8IEF1ZGlvU3lzdGVtOjpOVU1fTU9ERVMpKSB7CisgICAgICAgIGlmIChtb2RlID09IEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCB8fCAKKyAgICAgICAgICAgIChtb2RlID09IEF1ZGlvU3lzdGVtOjpNT0RFX0NVUlJFTlQgJiYgZ2V0TW9kZSgpID09IEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCkpIHsKKyAgICAgICAgICAgIHJvdXRlcyA9IG1TYXZlZFJvdXRlOyAgICAgICAgICAgICAgICAKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0dFVF9ST1VUSU5HOworICAgICAgICAgICAgbUF1ZGlvSGFyZHdhcmUtPmdldFJvdXRpbmcobW9kZSwgJnJvdXRlcyk7CisgICAgICAgICAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JRExFOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HVygiSWxsZWdhbCB2YWx1ZTogZ2V0Um91dGluZyglZCkiLCBtb2RlKTsKKyAgICB9CisgICAgcmV0dXJuIHJvdXRlczsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpzZXRNb2RlKGludCBtb2RlKQoreworICAgIC8vIGNoZWNrIGNhbGxpbmcgcGVybWlzc2lvbnMKKyAgICBpZiAoIXNldHRpbmdzQWxsb3dlZCgpKSB7CisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICB9CisgICAgaWYgKChtb2RlIDwgMCkgfHwgKG1vZGUgPj0gQXVkaW9TeXN0ZW06Ok5VTV9NT0RFUykpIHsKKyAgICAgICAgTE9HVygiSWxsZWdhbCB2YWx1ZTogc2V0TW9kZSglZCkiLCBtb2RlKTsKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB9CisKKyAgICBBdXRvTXV0ZXggbG9jayhtSGFyZHdhcmVMb2NrKTsKKyAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19TRVRfTU9ERTsKKyAgICBzdGF0dXNfdCByZXQgPSBtQXVkaW9IYXJkd2FyZS0+c2V0TW9kZShtb2RlKTsKKyAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JRExFOworICAgIHJldHVybiByZXQ7Cit9CisKK2ludCBBdWRpb0ZsaW5nZXI6OmdldE1vZGUoKSBjb25zdAoreworICAgIGludCBtb2RlID0gQXVkaW9TeXN0ZW06Ok1PREVfSU5WQUxJRDsKKyAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19TRVRfTU9ERTsKKyAgICBtQXVkaW9IYXJkd2FyZS0+Z2V0TW9kZSgmbW9kZSk7CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICByZXR1cm4gbW9kZTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpzZXRNaWNNdXRlKGJvb2wgc3RhdGUpCit7CisgICAgLy8gY2hlY2sgY2FsbGluZyBwZXJtaXNzaW9ucworICAgIGlmICghc2V0dGluZ3NBbGxvd2VkKCkpIHsKKyAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOworICAgIH0KKworICAgIEF1dG9NdXRleCBsb2NrKG1IYXJkd2FyZUxvY2spOworICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX1NFVF9NSUNfTVVURTsKKyAgICBzdGF0dXNfdCByZXQgPSBtQXVkaW9IYXJkd2FyZS0+c2V0TWljTXV0ZShzdGF0ZSk7CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICByZXR1cm4gcmV0OworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6Z2V0TWljTXV0ZSgpIGNvbnN0Cit7CisgICAgYm9vbCBzdGF0ZSA9IEF1ZGlvU3lzdGVtOjpNT0RFX0lOVkFMSUQ7CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfR0VUX01JQ19NVVRFOworICAgIG1BdWRpb0hhcmR3YXJlLT5nZXRNaWNNdXRlKCZzdGF0ZSk7CisgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICByZXR1cm4gc3RhdGU7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6c2V0TWFzdGVyTXV0ZShib29sIG11dGVkKQoreworICAgIC8vIGNoZWNrIGNhbGxpbmcgcGVybWlzc2lvbnMKKyAgICBpZiAoIXNldHRpbmdzQWxsb3dlZCgpKSB7CisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICB9CisgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnNldE1hc3Rlck11dGUobXV0ZWQpOworI2lmZGVmIFdJVEhfQTJEUAorICAgIG1BMmRwTWl4ZXJUaHJlYWQtPnNldE1hc3Rlck11dGUobXV0ZWQpOworI2VuZGlmCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitmbG9hdCBBdWRpb0ZsaW5nZXI6Om1hc3RlclZvbHVtZSgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1IYXJkd2FyZU1peGVyVGhyZWFkLT5tYXN0ZXJWb2x1bWUoKTsKK30KKworYm9vbCBBdWRpb0ZsaW5nZXI6Om1hc3Rlck11dGUoKSBjb25zdAoreworICAgIHJldHVybiBtSGFyZHdhcmVNaXhlclRocmVhZC0+bWFzdGVyTXV0ZSgpOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6OnNldFN0cmVhbVZvbHVtZShpbnQgc3RyZWFtLCBmbG9hdCB2YWx1ZSkKK3sKKyAgICAvLyBjaGVjayBjYWxsaW5nIHBlcm1pc3Npb25zCisgICAgaWYgKCFzZXR0aW5nc0FsbG93ZWQoKSkgeworICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7CisgICAgfQorCisgICAgaWYgKHVpbnQzMl90KHN0cmVhbSkgPj0gQXVkaW9TeXN0ZW06Ok5VTV9TVFJFQU1fVFlQRVMpIHsKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB9CisKKyAgICBtSGFyZHdhcmVNaXhlclRocmVhZC0+c2V0U3RyZWFtVm9sdW1lKHN0cmVhbSwgdmFsdWUpOworI2lmZGVmIFdJVEhfQTJEUAorICAgIG1BMmRwTWl4ZXJUaHJlYWQtPnNldFN0cmVhbVZvbHVtZShzdHJlYW0sIHZhbHVlKTsKKyNlbmRpZgorCisgICAgc3RhdHVzX3QgcmV0ID0gTk9fRVJST1I7CisgICAgaWYgKHN0cmVhbSA9PSBBdWRpb1N5c3RlbTo6Vk9JQ0VfQ0FMTCB8fAorICAgICAgICBzdHJlYW0gPT0gQXVkaW9TeXN0ZW06OkJMVUVUT09USF9TQ08pIHsKKyAgICAgICAgCisgICAgICAgIGlmIChzdHJlYW0gPT0gQXVkaW9TeXN0ZW06OlZPSUNFX0NBTEwpIHsKKyAgICAgICAgICAgIHZhbHVlID0gKGZsb2F0KUF1ZGlvU3lzdGVtOjpsb2dUb0xpbmVhcih2YWx1ZSkvMTAwLjBmOworICAgICAgICB9IGVsc2UgeyAvLyAodHlwZSA9PSBBdWRpb1N5c3RlbTo6QkxVRVRPT1RIX1NDTykKKyAgICAgICAgICAgIHZhbHVlID0gMS4wZjsKKyAgICAgICAgfQorCisgICAgICAgIEF1dG9NdXRleCBsb2NrKG1IYXJkd2FyZUxvY2spOworICAgICAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19TRVRfVk9JQ0VfVk9MVU1FOworICAgICAgICByZXQgPSBtQXVkaW9IYXJkd2FyZS0+c2V0Vm9pY2VWb2x1bWUodmFsdWUpOworICAgICAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JRExFOworICAgIH0KKworICAgIHJldHVybiByZXQ7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6c2V0U3RyZWFtTXV0ZShpbnQgc3RyZWFtLCBib29sIG11dGVkKQoreworICAgIC8vIGNoZWNrIGNhbGxpbmcgcGVybWlzc2lvbnMKKyAgICBpZiAoIXNldHRpbmdzQWxsb3dlZCgpKSB7CisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICB9CisKKyAgICBpZiAodWludDMyX3Qoc3RyZWFtKSA+PSBBdWRpb1N5c3RlbTo6TlVNX1NUUkVBTV9UWVBFUykgeworICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworICAgIH0KKyAgICAKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICBtQTJkcE1peGVyVGhyZWFkLT5zZXRTdHJlYW1NdXRlKHN0cmVhbSwgbXV0ZWQpOworI2VuZGlmCisgICAgaWYgKHN0cmVhbSA9PSBBdWRpb1N5c3RlbTo6TVVTSUMpIAorICAgIHsKKyAgICAgICAgQXV0b011dGV4IGxvY2soJm1IYXJkd2FyZUxvY2spOworICAgICAgICBpZiAobUZvcmNlZFJvdXRlICE9IDApCisgICAgICAgICAgICBtTXVzaWNNdXRlU2F2ZWQgPSBtdXRlZDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnNldFN0cmVhbU11dGUoc3RyZWFtLCBtdXRlZCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnNldFN0cmVhbU11dGUoc3RyZWFtLCBtdXRlZCk7CisgICAgfQorCisgICAgCisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK2Zsb2F0IEF1ZGlvRmxpbmdlcjo6c3RyZWFtVm9sdW1lKGludCBzdHJlYW0pIGNvbnN0Cit7CisgICAgaWYgKHVpbnQzMl90KHN0cmVhbSkgPj0gQXVkaW9TeXN0ZW06Ok5VTV9TVFJFQU1fVFlQRVMpIHsKKyAgICAgICAgcmV0dXJuIDAuMGY7CisgICAgfQorICAgIHJldHVybiBtSGFyZHdhcmVNaXhlclRocmVhZC0+c3RyZWFtVm9sdW1lKHN0cmVhbSk7Cit9CisKK2Jvb2wgQXVkaW9GbGluZ2VyOjpzdHJlYW1NdXRlKGludCBzdHJlYW0pIGNvbnN0Cit7CisgICAgaWYgKHVpbnQzMl90KHN0cmVhbSkgPj0gQXVkaW9TeXN0ZW06Ok5VTV9TVFJFQU1fVFlQRVMpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIAorICAgIGlmIChzdHJlYW0gPT0gQXVkaW9TeXN0ZW06Ok1VU0lDICYmIG1Gb3JjZWRSb3V0ZSAhPSAwKSAKKyAgICB7CisgICAgICAgIHJldHVybiBtTXVzaWNNdXRlU2F2ZWQ7CisgICAgfQorICAgIHJldHVybiBtSGFyZHdhcmVNaXhlclRocmVhZC0+c3RyZWFtTXV0ZShzdHJlYW0pOworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6aXNNdXNpY0FjdGl2ZSgpIGNvbnN0Cit7CisgI2lmZGVmIFdJVEhfQTJEUAorICAgICBpZiAoaXNBMmRwRW5hYmxlZCgpKSB7CisgICAgICAgICByZXR1cm4gbUEyZHBNaXhlclRocmVhZC0+aXNNdXNpY0FjdGl2ZSgpOworICAgICB9CisgI2VuZGlmCisgICAgcmV0dXJuIG1IYXJkd2FyZU1peGVyVGhyZWFkLT5pc011c2ljQWN0aXZlKCk7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6c2V0UGFyYW1ldGVyKGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogdmFsdWUpCit7CisgICAgc3RhdHVzX3QgcmVzdWx0LCByZXN1bHQyOworICAgIEF1dG9NdXRleCBsb2NrKG1IYXJkd2FyZUxvY2spOworICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX1NFVF9QQVJBTUVURVI7CisgICAgCisgICAgTE9HVigic2V0UGFyYW1ldGVyKCkga2V5ICVzLCB2YWx1ZSAlcywgdGlkICVkLCBjYWxsaW5nIHRpZCAlZCIsIGtleSwgdmFsdWUsIGdldHRpZCgpLCBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpOworICAgIHJlc3VsdCA9IG1BdWRpb0hhcmR3YXJlLT5zZXRQYXJhbWV0ZXIoa2V5LCB2YWx1ZSk7CisgICAgaWYgKG1BMmRwQXVkaW9JbnRlcmZhY2UpIHsKKyAgICAgICAgcmVzdWx0MiA9IG1BMmRwQXVkaW9JbnRlcmZhY2UtPnNldFBhcmFtZXRlcihrZXksIHZhbHVlKTsKKyAgICAgICAgaWYgKHJlc3VsdDIpCisgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQyOworICAgIH0KKyAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JRExFOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3NpemVfdCBBdWRpb0ZsaW5nZXI6OmdldElucHV0QnVmZmVyU2l6ZSh1aW50MzJfdCBzYW1wbGVSYXRlLCBpbnQgZm9ybWF0LCBpbnQgY2hhbm5lbENvdW50KQoreworICAgIHJldHVybiBtQXVkaW9IYXJkd2FyZS0+Z2V0SW5wdXRCdWZmZXJTaXplKHNhbXBsZVJhdGUsIGZvcm1hdCwgY2hhbm5lbENvdW50KTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OnJlZ2lzdGVyQ2xpZW50KGNvbnN0IHNwPElBdWRpb0ZsaW5nZXJDbGllbnQ+JiBjbGllbnQpCit7CisgICAgCisgICAgTE9HVigicmVnaXN0ZXJDbGllbnQoKSAlcCwgdGlkICVkLCBjYWxsaW5nIHRpZCAlZCIsIGNsaWVudC5nZXQoKSwgZ2V0dGlkKCksIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSk7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKworICAgIHNwPElCaW5kZXI+IGJpbmRlciA9IGNsaWVudC0+YXNCaW5kZXIoKTsKKyAgICBpZiAobU5vdGlmaWNhdGlvbkNsaWVudHMuaW5kZXhPZihiaW5kZXIpIDwgMCkgeworICAgICAgICBMT0dWKCJBZGRpbmcgbm90aWZpY2F0aW9uIGNsaWVudCAlcCIsIGJpbmRlci5nZXQoKSk7CisgICAgICAgIGJpbmRlci0+bGlua1RvRGVhdGgodGhpcyk7CisgICAgICAgIG1Ob3RpZmljYXRpb25DbGllbnRzLmFkZChiaW5kZXIpOworICAgICAgICBjbGllbnQtPmEyZHBFbmFibGVkQ2hhbmdlZChpc0EyZHBFbmFibGVkKCkpOworICAgIH0KK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OmJpbmRlckRpZWQoY29uc3Qgd3A8SUJpbmRlcj4mIHdobykgeworICAgIAorICAgIExPR1YoImJpbmRlckRpZWQoKSAlcCwgdGlkICVkLCBjYWxsaW5nIHRpZCAlZCIsIHdoby51bnNhZmVfZ2V0KCksIGdldHRpZCgpLCBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCkpOworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisKKyAgICBJQmluZGVyICpiaW5kZXIgPSB3aG8udW5zYWZlX2dldCgpOworCisgICAgaWYgKGJpbmRlciAhPSBOVUxMKSB7CisgICAgICAgIGludCBpbmRleCA9IG1Ob3RpZmljYXRpb25DbGllbnRzLmluZGV4T2YoYmluZGVyKTsKKyAgICAgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgICAgICAgIExPR1YoIlJlbW92aW5nIG5vdGlmaWNhdGlvbiBjbGllbnQgJXAiLCBiaW5kZXIpOworICAgICAgICAgICAgbU5vdGlmaWNhdGlvbkNsaWVudHMucmVtb3ZlQXQoaW5kZXgpOworICAgICAgICB9CisgICAgfQorfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6aGFuZGxlT3V0cHV0U3dpdGNoKCkKK3sKKyAgICBpZiAobUEyZHBFbmFibGVkICE9IG1BMmRwRW5hYmxlZFJlcSkKKyAgICB7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisKKyAgICAgICAgaWYgKG1BMmRwRW5hYmxlZCAhPSBtQTJkcEVuYWJsZWRSZXEpCisgICAgICAgIHsKKyAgICAgICAgICAgIG1BMmRwRW5hYmxlZCA9IG1BMmRwRW5hYmxlZFJlcTsKKyAgICAgICAgICAgIFNvcnRlZFZlY3RvciA8IHNwPE1peGVyVGhyZWFkOjpUcmFjaz4gPiB0cmFja3M7CisgICAgICAgICAgICBTb3J0ZWRWZWN0b3IgPCB3cDxNaXhlclRocmVhZDo6VHJhY2s+ID4gYWN0aXZlVHJhY2tzOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBXZSBob2xkIG1BMmRwTWl4ZXJUaHJlYWQgbUxvY2sgYWxyZWFkeSAKKyAgICAgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtSGFyZHdhcmVNaXhlclRocmVhZC0+bUxvY2spOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBUcmFuc2ZlciB0cmFja3MgcGxheWluZyBvbiBNVVNJQyBzdHJlYW0gZnJvbSBvbmUgbWl4ZXIgdG8gdGhlIG90aGVyCisgICAgICAgICAgICBpZiAobUEyZHBFbmFibGVkKSB7CisgICAgICAgICAgICAgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPmdldFRyYWNrcyh0cmFja3MsIGFjdGl2ZVRyYWNrcyk7CisgICAgICAgICAgICAgICAgbUEyZHBNaXhlclRocmVhZC0+cHV0VHJhY2tzKHRyYWNrcywgYWN0aXZlVHJhY2tzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbUEyZHBNaXhlclRocmVhZC0+Z2V0VHJhY2tzKHRyYWNrcywgYWN0aXZlVHJhY2tzKTsKKyAgICAgICAgICAgICAgICBtSGFyZHdhcmVNaXhlclRocmVhZC0+cHV0VHJhY2tzKHRyYWNrcywgYWN0aXZlVHJhY2tzKTsKKyAgICAgICAgICAgIH0gICAgICAgICAgICAKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gTm90aWZ5IEF1ZGlvU3lzdGVtIG9mIHRoZSBBMkRQIGFjdGl2YXRpb24vZGVhY3RpdmF0aW9uCisgICAgICAgICAgICBzaXplX3Qgc2l6ZSA9IG1Ob3RpZmljYXRpb25DbGllbnRzLnNpemUoKTsKKyAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3A8SUJpbmRlcj4gYmluZGVyID0gbU5vdGlmaWNhdGlvbkNsaWVudHMuaXRlbUF0KGkpLnByb21vdGUoKTsKKyAgICAgICAgICAgICAgICBpZiAoYmluZGVyICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HVigiTm90aWZ5aW5nIG91dHB1dCBjaGFuZ2UgdG8gY2xpZW50ICVwIiwgYmluZGVyLmdldCgpKTsKKyAgICAgICAgICAgICAgICAgICAgc3A8SUF1ZGlvRmxpbmdlckNsaWVudD4gY2xpZW50ID0gaW50ZXJmYWNlX2Nhc3Q8SUF1ZGlvRmxpbmdlckNsaWVudD4gKGJpbmRlcik7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudC0+YTJkcEVuYWJsZWRDaGFuZ2VkKG1BMmRwRW5hYmxlZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBtSGFyZHdhcmVNaXhlclRocmVhZC0+d2FrZVVwKCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpyZW1vdmVDbGllbnQocGlkX3QgcGlkKQoreworICAgIExPR1YoInJlbW92ZUNsaWVudCgpIHBpZCAlZCwgdGlkICVkLCBjYWxsaW5nIHRpZCAlZCIsIHBpZCwgZ2V0dGlkKCksIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSk7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBtQ2xpZW50cy5yZW1vdmVJdGVtKHBpZCk7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjp3YWtlVXAoKQoreworICAgIG1IYXJkd2FyZU1peGVyVGhyZWFkLT53YWtlVXAoKTsKKyNpZmRlZiBXSVRIX0EyRFAKKyAgICBtQTJkcE1peGVyVGhyZWFkLT53YWtlVXAoKTsKKyNlbmRpZiAvLyBXSVRIX0EyRFAKK30KKworYm9vbCBBdWRpb0ZsaW5nZXI6OmlzQTJkcEVuYWJsZWQoKSBjb25zdAoreworICAgIHJldHVybiBtQTJkcEVuYWJsZWRSZXE7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpoYW5kbGVGb3JjZWRTcGVha2VyUm91dGUoaW50IGNvbW1hbmQpCit7CisgICAgc3dpdGNoKGNvbW1hbmQpIHsKKyAgICBjYXNlIEFDVElWRV9UUkFDS19BRERFRDoKKyAgICAgICAgeworICAgICAgICAgICAgQXV0b011dGV4IGxvY2sobUhhcmR3YXJlTG9jayk7CisgICAgICAgICAgICBpZiAobUZvcmNlZFNwZWFrZXJDb3VudCsrID09IDApIHsKKyAgICAgICAgICAgICAgICBtUm91dGVSZXN0b3JlVGltZSA9IDA7CisgICAgICAgICAgICAgICAgbU11c2ljTXV0ZVNhdmVkID0gbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnN0cmVhbU11dGUoQXVkaW9TeXN0ZW06Ok1VU0lDKTsKKyAgICAgICAgICAgICAgICBpZiAobUZvcmNlZFJvdXRlID09IDAgJiYgIShtU2F2ZWRSb3V0ZSAmIEF1ZGlvU3lzdGVtOjpST1VURV9TUEVBS0VSKSkgeworICAgICAgICAgICAgICAgICAgICBMT0dWKCJSb3V0ZSBmb3JjZWQgdG8gU3BlYWtlciBPTiAlMDh4IiwgbVNhdmVkUm91dGUgfCBBdWRpb1N5c3RlbTo6Uk9VVEVfU1BFQUtFUik7CisgICAgICAgICAgICAgICAgICAgIG1IYXJkd2FyZU1peGVyVGhyZWFkLT5zZXRTdHJlYW1NdXRlKEF1ZGlvU3lzdGVtOjpNVVNJQywgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX1NFVF9NQVNURVJfVk9MVU1FOworICAgICAgICAgICAgICAgICAgICBtQXVkaW9IYXJkd2FyZS0+c2V0TWFzdGVyVm9sdW1lKDApOworICAgICAgICAgICAgICAgICAgICB1c2xlZXAobUhhcmR3YXJlTWl4ZXJUaHJlYWQtPmxhdGVuY3koKSoxMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfU0VUX1JPVVRJTkc7CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5zZXRSb3V0aW5nKEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCwgbVNhdmVkUm91dGUgfCBBdWRpb1N5c3RlbTo6Uk9VVEVfU1BFQUtFUik7CisgICAgICAgICAgICAgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0lETEU7CisgICAgICAgICAgICAgICAgICAgIC8vIGRlbGF5IHRyYWNrIHN0YXJ0IHNvIHRoYXQgYXVkaW8gaGFyZHdhcmUgaGFzIHRpbWUgdG8gc2l3dGNoIHJvdXRlcworICAgICAgICAgICAgICAgICAgICB1c2xlZXAoa1N0YXJ0U2xlZXBUaW1lKTsKKyAgICAgICAgICAgICAgICAgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfU0VUX01BU1RFUl9WT0xVTUU7CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5zZXRNYXN0ZXJWb2x1bWUobUhhcmR3YXJlTWl4ZXJUaHJlYWQtPm1hc3RlclZvbHVtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfSURMRTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbUZvcmNlZFJvdXRlID0gQXVkaW9TeXN0ZW06OlJPVVRFX1NQRUFLRVI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBMT0dWKCJtRm9yY2VkU3BlYWtlckNvdW50IGluY3JlbWVudGVkIHRvICVkIiwgbUZvcmNlZFNwZWFrZXJDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBBQ1RJVkVfVFJBQ0tfUkVNT1ZFRDoKKyAgICAgICAgeworICAgICAgICAgICAgQXV0b011dGV4IGxvY2sobUhhcmR3YXJlTG9jayk7CisgICAgICAgICAgICBpZiAobUZvcmNlZFNwZWFrZXJDb3VudCA+IDApeworICAgICAgICAgICAgICAgIGlmICgtLW1Gb3JjZWRTcGVha2VyQ291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBtUm91dGVSZXN0b3JlVGltZSA9IHN5c3RlbVRpbWUoKSArIG1pbGxpc2Vjb25kcyhrU3RvcFNsZWVwVGltZS8xMDAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTE9HVigibUZvcmNlZFNwZWFrZXJDb3VudCBkZWNyZW1lbnRlZCB0byAlZCIsIG1Gb3JjZWRTcGVha2VyQ291bnQpOyAgICAgICAgICAgIAorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dFKCJtRm9yY2VkU3BlYWtlckNvdW50IGlzIGFscmVhZHkgemVybyIpOyAgICAgICAgICAgIAorICAgICAgICAgICAgfSAgICAgICAgICAgIAorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgQ0hFQ0tfUk9VVEVfUkVTVE9SRV9USU1FOgorICAgIGNhc2UgRk9SQ0VfUk9VVEVfUkVTVE9SRToKKyAgICAgICAgaWYgKG1Sb3V0ZVJlc3RvcmVUaW1lKSB7CisgICAgICAgICAgICBBdXRvTXV0ZXggbG9jayhtSGFyZHdhcmVMb2NrKTsKKyAgICAgICAgICAgIGlmIChtUm91dGVSZXN0b3JlVGltZSAmJiAKKyAgICAgICAgICAgICAgIChzeXN0ZW1UaW1lKCkgPiBtUm91dGVSZXN0b3JlVGltZSB8fCBjb21tYW5kID09IEZPUkNFX1JPVVRFX1JFU1RPUkUpKSB7CisgICAgICAgICAgICAgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQtPnNldFN0cmVhbU11dGUoQXVkaW9TeXN0ZW06Ok1VU0lDLCBtTXVzaWNNdXRlU2F2ZWQpOworICAgICAgICAgICAgICAgIG1Gb3JjZWRSb3V0ZSA9IDA7CisgICAgICAgICAgICAgICAgaWYgKCEobVNhdmVkUm91dGUgJiBBdWRpb1N5c3RlbTo6Uk9VVEVfU1BFQUtFUikpIHsKKyAgICAgICAgICAgICAgICAgICAgbUhhcmR3YXJlU3RhdHVzID0gQVVESU9fSFdfU0VUX1JPVVRJTkc7CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5zZXRSb3V0aW5nKEF1ZGlvU3lzdGVtOjpNT0RFX05PUk1BTCwgbVNhdmVkUm91dGUpOworICAgICAgICAgICAgICAgICAgICBtSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19JRExFOworICAgICAgICAgICAgICAgICAgICBMT0dWKCJSb3V0ZSBmb3JjZWQgdG8gU3BlYWtlciBPRkYgJTA4eCIsIG1TYXZlZFJvdXRlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbVJvdXRlUmVzdG9yZVRpbWUgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6Ok1peGVyVGhyZWFkKGNvbnN0IHNwPEF1ZGlvRmxpbmdlcj4mIGF1ZGlvRmxpbmdlciwgQXVkaW9TdHJlYW1PdXQqIG91dHB1dCwgaW50IG91dHB1dFR5cGUpCisgICAgOiAgIFRocmVhZChmYWxzZSksCisgICAgICAgIG1BdWRpb0ZsaW5nZXIoYXVkaW9GbGluZ2VyKSwgbUF1ZGlvTWl4ZXIoMCksIG1PdXRwdXQob3V0cHV0KSwgbU91dHB1dFR5cGUob3V0cHV0VHlwZSksIAorICAgICAgICBtU2FtcGxlUmF0ZSgwKSwgbUZyYW1lQ291bnQoMCksIG1DaGFubmVsQ291bnQoMCksIG1Gb3JtYXQoMCksIG1NaXhCdWZmZXIoMCksCisgICAgICAgIG1MYXN0V3JpdGVUaW1lKDApLCBtTnVtV3JpdGVzKDApLCBtTnVtRGVsYXllZFdyaXRlcygwKSwgbVN0YW5kYnkoZmFsc2UpLAorICAgICAgICBtSW5Xcml0ZShmYWxzZSkKK3sKKyAgICBtU2FtcGxlUmF0ZSA9IG91dHB1dC0+c2FtcGxlUmF0ZSgpOworICAgIG1DaGFubmVsQ291bnQgPSBvdXRwdXQtPmNoYW5uZWxDb3VudCgpOworCisgICAgLy8gRklYTUUgLSBDdXJyZW50IG1peGVyIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgc3RlcmVvIG91dHB1dAorICAgIGlmIChtQ2hhbm5lbENvdW50ID09IDEpIHsKKyAgICAgICAgTE9HRSgiSW52YWxpZCBhdWRpbyBoYXJkd2FyZSBjaGFubmVsIGNvdW50Iik7CisgICAgfQorCisgICAgbUZvcm1hdCA9IG91dHB1dC0+Zm9ybWF0KCk7CisgICAgbUZyYW1lQ291bnQgPSBvdXRwdXQtPmJ1ZmZlclNpemUoKSAvIG91dHB1dC0+Y2hhbm5lbENvdW50KCkgLyBzaXplb2YoaW50MTZfdCk7CisgICAgbUF1ZGlvTWl4ZXIgPSBuZXcgQXVkaW9NaXhlcihtRnJhbWVDb3VudCwgb3V0cHV0LT5zYW1wbGVSYXRlKCkpOworCisgICAgLy8gRklYTUUgLSBDdXJyZW50IG1peGVyIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgc3RlcmVvIG91dHB1dDogQWx3YXlzCisgICAgLy8gQWxsb2NhdGUgYSBzdGVyZW8gYnVmZmVyIGV2ZW4gaWYgSFcgb3V0cHV0IGlzIG1vbm8uCisgICAgbU1peEJ1ZmZlciA9IG5ldyBpbnQxNl90W21GcmFtZUNvdW50ICogMl07CisgICAgbWVtc2V0KG1NaXhCdWZmZXIsIDAsIG1GcmFtZUNvdW50ICogMiAqIHNpemVvZihpbnQxNl90KSk7Cit9CisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6On5NaXhlclRocmVhZCgpCit7CisgICAgZGVsZXRlIFtdIG1NaXhCdWZmZXI7CisgICAgZGVsZXRlIG1BdWRpb01peGVyOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBkdW1wSW50ZXJuYWxzKGZkLCBhcmdzKTsKKyAgICBkdW1wVHJhY2tzKGZkLCBhcmdzKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OmR1bXBUcmFja3MoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGNvbnN0IHNpemVfdCBTSVpFID0gMjU2OworICAgIGNoYXIgYnVmZmVyW1NJWkVdOworICAgIFN0cmluZzggcmVzdWx0OworCisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiT3V0cHV0ICVkIG1peGVyIHRocmVhZCB0cmFja3NcbiIsIG1PdXRwdXRUeXBlKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgcmVzdWx0LmFwcGVuZCgiICAgTmFtZSBDbGllbiBUeXAgRm10IENobiBCdWYgUyBNIEYgU1JhdGUgTGVmdFYgUmlnaFYgU2VydiBVc2VyXG4iKTsKKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1UcmFja3Muc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgd3A8VHJhY2s+IHdUcmFjayA9IG1UcmFja3NbaV07CisgICAgICAgIGlmICh3VHJhY2sgIT0gMCkgeworICAgICAgICAgICAgc3A8VHJhY2s+IHRyYWNrID0gd1RyYWNrLnByb21vdGUoKTsKKyAgICAgICAgICAgIGlmICh0cmFjayAhPSAwKSB7CisgICAgICAgICAgICAgICAgdHJhY2stPmR1bXAoYnVmZmVyLCBTSVpFKTsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJPdXRwdXQgJWQgbWl4ZXIgdGhyZWFkIGFjdGl2ZSB0cmFja3NcbiIsIG1PdXRwdXRUeXBlKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgcmVzdWx0LmFwcGVuZCgiICAgTmFtZSBDbGllbiBUeXAgRm10IENobiBCdWYgUyBNIEYgU1JhdGUgTGVmdFYgUmlnaFYgU2VydiBVc2VyXG4iKTsKKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1BY3RpdmVUcmFja3Muc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgd3A8VHJhY2s+IHdUcmFjayA9IG1UcmFja3NbaV07CisgICAgICAgIGlmICh3VHJhY2sgIT0gMCkgeworICAgICAgICAgICAgc3A8VHJhY2s+IHRyYWNrID0gd1RyYWNrLnByb21vdGUoKTsKKyAgICAgICAgICAgIGlmICh0cmFjayAhPSAwKSB7CisgICAgICAgICAgICAgICAgdHJhY2stPmR1bXAoYnVmZmVyLCBTSVpFKTsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgd3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpkdW1wSW50ZXJuYWxzKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIk91dHB1dCAlZCBtaXhlciB0aHJlYWQgaW50ZXJuYWxzXG4iLCBtT3V0cHV0VHlwZSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIkF1ZGlvTWl4ZXIgdHJhY2tzOiAlMDh4XG4iLCBtQXVkaW9NaXhlci0+dHJhY2tOYW1lcygpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAibGFzdCB3cml0ZSBvY2N1cnJlZCAobXNlY3MpOiAlbGx1XG4iLCBuczJtcyhzeXN0ZW1UaW1lKCkgLSBtTGFzdFdyaXRlVGltZSkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJ0b3RhbCB3cml0ZXM6ICVkXG4iLCBtTnVtV3JpdGVzKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiZGVsYXllZCB3cml0ZXM6ICVkXG4iLCBtTnVtRGVsYXllZFdyaXRlcyk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgImJsb2NrZWQgaW4gd3JpdGU6ICVkXG4iLCBtSW5Xcml0ZSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgInN0YW5kYnk6ICVkXG4iLCBtU3RhbmRieSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHdyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gVGhyZWFkIHZpcnR1YWxzCitib29sIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OnRocmVhZExvb3AoKQoreworICAgIHVuc2lnbmVkIGxvbmcgc2xlZXBUaW1lID0ga0J1ZmZlclJlY292ZXJ5SW5Vc2VjczsKKyAgICBpbnQxNl90KiBjdXJCdWYgPSBtTWl4QnVmZmVyOworICAgIFZlY3Rvcjwgc3A8VHJhY2s+ID4gdHJhY2tzVG9SZW1vdmU7CisgICAgc2l6ZV90IGVuYWJsZWRUcmFja3MgPSAwOworICAgIG5zZWNzX3Qgc3RhbmRieVRpbWUgPSBzeXN0ZW1UaW1lKCk7ICAgCisgICAgc2l6ZV90IG1peEJ1ZmZlclNpemUgPSBtRnJhbWVDb3VudCptQ2hhbm5lbENvdW50KnNpemVvZihpbnQxNl90KTsKKyAgICBuc2Vjc190IG1heFBlcmlvZCA9IHNlY29uZHMobUZyYW1lQ291bnQpIC8gbVNhbXBsZVJhdGUgKiAyOworCisjaWZkZWYgV0lUSF9BMkRQCisgICAgYm9vbCBvdXRwdXRUcmFja0FjdGl2ZSA9IGZhbHNlOworI2VuZGlmCisKKyAgICBkbyB7CisgICAgICAgIGVuYWJsZWRUcmFja3MgPSAwOworICAgICAgICB7IC8vIHNjb3BlIGZvciB0aGUgbUxvY2sKKyAgICAgICAgCisgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworCisjaWZkZWYgV0lUSF9BMkRQCisgICAgICAgICAgICBpZiAobU91dHB1dFR5cGUgPT0gQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9BMkRQKSB7CisgICAgICAgICAgICAgICAgbUF1ZGlvRmxpbmdlci0+aGFuZGxlT3V0cHV0U3dpdGNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobU91dHB1dFRyYWNrICE9IE5VTEwgJiYgIW1BdWRpb0ZsaW5nZXItPmlzQTJkcEVuYWJsZWQoKSkgeworICAgICAgICAgICAgICAgIGlmIChvdXRwdXRUcmFja0FjdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICBtT3V0cHV0VHJhY2stPnN0b3AoKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0VHJhY2tBY3RpdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisjZW5kaWYKKworICAgICAgICAgICAgY29uc3QgU29ydGVkVmVjdG9yPCB3cDxUcmFjaz4gPiYgYWN0aXZlVHJhY2tzID0gbUFjdGl2ZVRyYWNrczsKKworICAgICAgICAgICAgLy8gcHV0IGF1ZGlvIGhhcmR3YXJlIGludG8gc3RhbmRieSBhZnRlciBzaG9ydCBkZWxheQorICAgICAgICAgICAgaWYgVU5MSUtFTFkoIWFjdGl2ZVRyYWNrcy5zaXplKCkgJiYgc3lzdGVtVGltZSgpID4gc3RhbmRieVRpbWUpIHsKKyAgICAgICAgICAgICAgICAvLyB3YWl0IHVudGlsIHdlIGhhdmUgc29tZXRoaW5nIHRvIGRvLi4uCisgICAgICAgICAgICAgICAgTE9HVigiQXVkaW8gaGFyZHdhcmUgZW50ZXJpbmcgc3RhbmRieSwgb3V0cHV0ICVkXG4iLCBtT3V0cHV0VHlwZSk7CisvLyAgICAgICAgICAgICAgICBtQXVkaW9GbGluZ2VyLT5tSGFyZHdhcmVTdGF0dXMgPSBBVURJT19IV19TVEFOREJZOworICAgICAgICAgICAgICAgIGlmICghbVN0YW5kYnkpIHsKKyAgICAgICAgICAgICAgICAgICAgbU91dHB1dC0+c3RhbmRieSgpOworICAgICAgICAgICAgICAgICAgICBtU3RhbmRieSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIAorI2lmZGVmIFdJVEhfQTJEUAorICAgICAgICAgICAgICAgIGlmIChvdXRwdXRUcmFja0FjdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICBtT3V0cHV0VHJhY2stPnN0b3AoKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0VHJhY2tBY3RpdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgICAgICAgICBpZiAobU91dHB1dFR5cGUgPT0gQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9IQVJEV0FSRSkgeworICAgICAgICAgICAgICAgICAgICBtQXVkaW9GbGluZ2VyLT5oYW5kbGVGb3JjZWRTcGVha2VyUm91dGUoRk9SQ0VfUk9VVEVfUkVTVE9SRSk7CisgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKKy8vICAgICAgICAgICAgICAgIG1IYXJkd2FyZVN0YXR1cyA9IEFVRElPX0hXX0lETEU7CisgICAgICAgICAgICAgICAgLy8gd2UncmUgYWJvdXQgdG8gd2FpdCwgZmx1c2ggdGhlIGJpbmRlciBjb21tYW5kIGJ1ZmZlcgorICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmZsdXNoQ29tbWFuZHMoKTsKKyAgICAgICAgICAgICAgICBtV2FpdFdvcmtDVi53YWl0KG1Mb2NrKTsKKyAgICAgICAgICAgICAgICBMT0dWKCJBdWRpbyBoYXJkd2FyZSBleGl0aW5nIHN0YW5kYnksIG91dHB1dCAlZFxuIiwgbU91dHB1dFR5cGUpOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGlmIChtTWFzdGVyTXV0ZSA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICBjaGFyIHZhbHVlW1BST1BFUlRZX1ZBTFVFX01BWF07CisgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5X2dldCgicm8uYXVkaW8uc2lsZW50IiwgdmFsdWUsICIwIik7CisgICAgICAgICAgICAgICAgICAgIGlmIChhdG9pKHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgTE9HRCgiU2lsZW5jZSBpcyBnb2xkZW4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldE1hc3Rlck11dGUodHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBzdGFuZGJ5VGltZSA9IHN5c3RlbVRpbWUoKSArIGtTdGFuZGJ5VGltZUluTnNlY3M7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEZvcmNlZCByb3V0ZSB0byBzcGVha2VyIGlzIGhhbmRsZWQgYnkgaGFyZHdhcmUgbWl4ZXIgdGhyZWFkCisgICAgICAgICAgICBpZiAobU91dHB1dFR5cGUgPT0gQXVkaW9TeXN0ZW06OkFVRElPX09VVFBVVF9IQVJEV0FSRSkgeworICAgICAgICAgICAgICAgIG1BdWRpb0ZsaW5nZXItPmhhbmRsZUZvcmNlZFNwZWFrZXJSb3V0ZShDSEVDS19ST1VURV9SRVNUT1JFX1RJTUUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBmaW5kIG91dCB3aGljaCB0cmFja3MgbmVlZCB0byBiZSBwcm9jZXNzZWQKKyAgICAgICAgICAgIHNpemVfdCBjb3VudCA9IGFjdGl2ZVRyYWNrcy5zaXplKCk7CisgICAgICAgICAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3A8VHJhY2s+IHQgPSBhY3RpdmVUcmFja3NbaV0ucHJvbW90ZSgpOworICAgICAgICAgICAgICAgIGlmICh0ID09IDApIGNvbnRpbnVlOworCisgICAgICAgICAgICAgICAgVHJhY2sqIGNvbnN0IHRyYWNrID0gdC5nZXQoKTsKKyAgICAgICAgICAgICAgICBhdWRpb190cmFja19jYmxrX3QqIGNibGsgPSB0cmFjay0+Y2JsaygpOworCisgICAgICAgICAgICAgICAgLy8gVGhlIGZpcnN0IHRpbWUgYSB0cmFjayBpcyBhZGRlZCB3ZSB3YWl0CisgICAgICAgICAgICAgICAgLy8gZm9yIGFsbCBpdHMgYnVmZmVycyB0byBiZSBmaWxsZWQgYmVmb3JlIHByb2Nlc3NpbmcgaXQKKyAgICAgICAgICAgICAgICBtQXVkaW9NaXhlci0+c2V0QWN0aXZlVHJhY2sodHJhY2stPm5hbWUoKSk7CisgICAgICAgICAgICAgICAgaWYgKGNibGstPmZyYW1lc1JlYWR5KCkgJiYgKHRyYWNrLT5pc1JlYWR5KCkgfHwgdHJhY2stPmlzU3RvcHBlZCgpKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgIXRyYWNrLT5pc1BhdXNlZCgpKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgLy9MT0dWKCJ0cmFjayAlZCB1PSUwOHgsIHM9JTA4eCBbT0tdIiwgdHJhY2stPm5hbWUoKSwgY2Jsay0+dXNlciwgY2Jsay0+c2VydmVyKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBjb21wdXRlIHZvbHVtZSBmb3IgdGhpcyB0cmFjaworICAgICAgICAgICAgICAgICAgICBpbnQxNl90IGxlZnQsIHJpZ2h0OworICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2stPmlzTXV0ZWQoKSB8fCBtTWFzdGVyTXV0ZSB8fCB0cmFjay0+aXNQYXVzaW5nKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQgPSByaWdodCA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2stPmlzUGF1c2luZygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HVigicGF1c2VkKCVkKSIsIHRyYWNrLT5uYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLT5zZXRQYXVzZWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IHR5cGVWb2x1bWUgPSBtU3RyZWFtVHlwZXNbdHJhY2stPnR5cGUoKV0udm9sdW1lOworICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdiA9IG1NYXN0ZXJWb2x1bWUgKiB0eXBlVm9sdW1lOworICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdl9jbGFtcGVkID0gdiAqIGNibGstPnZvbHVtZVswXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2X2NsYW1wZWQgPiBNQVhfR0FJTikgdl9jbGFtcGVkID0gTUFYX0dBSU47CisgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0ID0gaW50MTZfdCh2X2NsYW1wZWQpOworICAgICAgICAgICAgICAgICAgICAgICAgdl9jbGFtcGVkID0gdiAqIGNibGstPnZvbHVtZVsxXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2X2NsYW1wZWQgPiBNQVhfR0FJTikgdl9jbGFtcGVkID0gTUFYX0dBSU47CisgICAgICAgICAgICAgICAgICAgICAgICByaWdodCA9IGludDE2X3Qodl9jbGFtcGVkKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIFhYWDogdGhlc2UgdGhpbmdzIERPTidUIG5lZWQgdG8gYmUgZG9uZSBlYWNoIHRpbWUKKyAgICAgICAgICAgICAgICAgICAgbUF1ZGlvTWl4ZXItPnNldEJ1ZmZlclByb3ZpZGVyKHRyYWNrKTsKKyAgICAgICAgICAgICAgICAgICAgbUF1ZGlvTWl4ZXItPmVuYWJsZShBdWRpb01peGVyOjpNSVhJTkcpOworCisgICAgICAgICAgICAgICAgICAgIGludCBwYXJhbTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCB0cmFjay0+bUZpbGxpbmdVcFN0YXR1cyA9PSBUcmFjazo6RlNfRklMTEVEKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyByYW1wIGZvciB0aGUgZmlyc3Qgdm9sdW1lIHNldHRpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLT5tRmlsbGluZ1VwU3RhdHVzID0gVHJhY2s6OkZTX0FDVElWRTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFjay0+bVN0YXRlID09IFRyYWNrQmFzZTo6UkVTVU1JTkcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay0+bVN0YXRlID0gVHJhY2tCYXNlOjpBQ1RJVkU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gPSBBdWRpb01peGVyOjpSQU1QX1ZPTFVNRTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gPSBBdWRpb01peGVyOjpWT0xVTUU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9IEF1ZGlvTWl4ZXI6OlJBTVBfVk9MVU1FOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb01peGVyLT5zZXRQYXJhbWV0ZXIocGFyYW0sIEF1ZGlvTWl4ZXI6OlZPTFVNRTAsIGxlZnQpOworICAgICAgICAgICAgICAgICAgICBtQXVkaW9NaXhlci0+c2V0UGFyYW1ldGVyKHBhcmFtLCBBdWRpb01peGVyOjpWT0xVTUUxLCByaWdodCk7CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb01peGVyLT5zZXRQYXJhbWV0ZXIoCisgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb01peGVyOjpUUkFDSywKKyAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvTWl4ZXI6OkZPUk1BVCwgdHJhY2stPmZvcm1hdCgpKTsKKyAgICAgICAgICAgICAgICAgICAgbUF1ZGlvTWl4ZXItPnNldFBhcmFtZXRlcigKKyAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvTWl4ZXI6OlRSQUNLLAorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9NaXhlcjo6Q0hBTk5FTF9DT1VOVCwgdHJhY2stPmNoYW5uZWxDb3VudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgbUF1ZGlvTWl4ZXItPnNldFBhcmFtZXRlcigKKyAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvTWl4ZXI6OlJFU0FNUExFLAorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9NaXhlcjo6U0FNUExFX1JBVEUsCisgICAgICAgICAgICAgICAgICAgICAgICBpbnQoY2Jsay0+c2FtcGxlUmF0ZSkpOworCisgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IHJldHJ5IGNvdW50CisgICAgICAgICAgICAgICAgICAgIHRyYWNrLT5tUmV0cnlDb3VudCA9IGtNYXhUcmFja1JldHJpZXM7CisgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRUcmFja3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvL0xPR1YoInRyYWNrICVkIHU9JTA4eCwgcz0lMDh4IFtOT1QgUkVBRFldIiwgdHJhY2stPm5hbWUoKSwgY2Jsay0+dXNlciwgY2Jsay0+c2VydmVyKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrLT5pc1N0b3BwZWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2stPnJlc2V0KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrLT5pc1Rlcm1pbmF0ZWQoKSB8fCB0cmFjay0+aXNTdG9wcGVkKCkgfHwgdHJhY2stPmlzUGF1c2VkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgY29uc3VtZWQgYWxsIHRoZSBidWZmZXJzIG9mIHRoaXMgdHJhY2suCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgaXQgZnJvbSB0aGUgbGlzdCBvZiBhY3RpdmUgdHJhY2tzLgorICAgICAgICAgICAgICAgICAgICAgICAgTE9HVigicmVtb3ZlKCVkKSBmcm9tIGFjdGl2ZSBsaXN0IiwgdHJhY2stPm5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFja3NUb1JlbW92ZS5hZGQodHJhY2spOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gYnVmZmVycyBmb3IgdGhpcyB0cmFjay4gR2l2ZSBpdCBhIGZldyBjaGFuY2VzIHRvCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIGEgYnVmZmVyLCB0aGVuIHJlbW92ZSBpdCBmcm9tIGFjdGl2ZSBsaXN0LgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC0tKHRyYWNrLT5tUmV0cnlDb3VudCkgPD0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR1YoIkJVRkZFUiBUSU1FT1VUOiByZW1vdmUoJWQpIGZyb20gYWN0aXZlIGxpc3QiLCB0cmFjay0+bmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFja3NUb1JlbW92ZS5hZGQodHJhY2spOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIExPR1YoImRpc2FibGUoJWQpIiwgdHJhY2stPm5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIG1BdWRpb01peGVyLT5kaXNhYmxlKEF1ZGlvTWl4ZXI6Ok1JWElORyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyByZW1vdmUgYWxsIHRoZSB0cmFja3MgdGhhdCBuZWVkIHRvIGJlLi4uCisgICAgICAgICAgICBjb3VudCA9IHRyYWNrc1RvUmVtb3ZlLnNpemUoKTsKKyAgICAgICAgICAgIGlmIChVTkxJS0VMWShjb3VudCkpIHsKKyAgICAgICAgICAgICAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPFRyYWNrPiYgdHJhY2sgPSB0cmFja3NUb1JlbW92ZVtpXTsKKyAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQWN0aXZlVHJhY2sodHJhY2spOworICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2stPmlzVGVybWluYXRlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtVHJhY2tzLnJlbW92ZSh0cmFjayk7CisgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVUcmFja05hbWUodHJhY2stPm1OYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gIAorICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmIChMSUtFTFkoZW5hYmxlZFRyYWNrcykpIHsKKyAgICAgICAgICAgIC8vIG1peCBidWZmZXJzLi4uCisgICAgICAgICAgICBtQXVkaW9NaXhlci0+cHJvY2VzcyhjdXJCdWYpOworCisjaWZkZWYgV0lUSF9BMkRQCisgICAgICAgICAgICBpZiAobU91dHB1dFRyYWNrICE9IE5VTEwgJiYgbUF1ZGlvRmxpbmdlci0+aXNBMmRwRW5hYmxlZCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFvdXRwdXRUcmFja0FjdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICBMT0dWKCJzdGFydGluZyBvdXRwdXQgdHJhY2sgaW4gbWl4ZXIgZm9yIG91dHB1dCAlZCIsIG1PdXRwdXRUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgbU91dHB1dFRyYWNrLT5zdGFydCgpOworICAgICAgICAgICAgICAgICAgICBvdXRwdXRUcmFja0FjdGl2ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1PdXRwdXRUcmFjay0+d3JpdGUoY3VyQnVmLCBtRnJhbWVDb3VudCk7CisgICAgICAgICAgICB9CisjZW5kaWYKKworICAgICAgICAgICAgLy8gb3V0cHV0IGF1ZGlvIHRvIGhhcmR3YXJlCisgICAgICAgICAgICBtTGFzdFdyaXRlVGltZSA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgICAgIG1JbldyaXRlID0gdHJ1ZTsKKyAgICAgICAgICAgIG1PdXRwdXQtPndyaXRlKGN1ckJ1ZiwgbWl4QnVmZmVyU2l6ZSk7CisgICAgICAgICAgICBtTnVtV3JpdGVzKys7CisgICAgICAgICAgICBtSW5Xcml0ZSA9IGZhbHNlOworICAgICAgICAgICAgbVN0YW5kYnkgPSBmYWxzZTsKKyAgICAgICAgICAgIG5zZWNzX3QgdGVtcCA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgICAgIHN0YW5kYnlUaW1lID0gdGVtcCArIGtTdGFuZGJ5VGltZUluTnNlY3M7CisgICAgICAgICAgICBuc2Vjc190IGRlbHRhID0gdGVtcCAtIG1MYXN0V3JpdGVUaW1lOworICAgICAgICAgICAgaWYgKGRlbHRhID4gbWF4UGVyaW9kKSB7CisgICAgICAgICAgICAgICAgTE9HVygid3JpdGUgYmxvY2tlZCBmb3IgJWxsdSBtc2VjcyIsIG5zMm1zKGRlbHRhKSk7CisgICAgICAgICAgICAgICAgbU51bURlbGF5ZWRXcml0ZXMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNsZWVwVGltZSA9IGtCdWZmZXJSZWNvdmVyeUluVXNlY3M7CisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgCisjaWZkZWYgV0lUSF9BMkRQCisgICAgICAgICAgICBpZiAobU91dHB1dFRyYWNrICE9IE5VTEwgJiYgbUF1ZGlvRmxpbmdlci0+aXNBMmRwRW5hYmxlZCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKG91dHB1dFRyYWNrQWN0aXZlKSB7CisgICAgICAgICAgICAgICAgICAgIG1PdXRwdXRUcmFjay0+d3JpdGUoY3VyQnVmLCAwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1PdXRwdXRUcmFjay0+YnVmZmVyUXVldWVFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtT3V0cHV0VHJhY2stPnN0b3AoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFRyYWNrQWN0aXZlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdGFuZGJ5VGltZSA9IHN5c3RlbVRpbWUoKSArIGtTdGFuZGJ5VGltZUluTnNlY3M7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgICAgIC8vIFRoZXJlIHdhcyBub3RoaW5nIHRvIG1peCB0aGlzIHJvdW5kLCB3aGljaCBtZWFucyBhbGwKKyAgICAgICAgICAgIC8vIGFjdGl2ZSB0cmFja3Mgd2VyZSBsYXRlLiBTbGVlcCBhIGxpdHRsZSBiaXQgdG8gZ2l2ZQorICAgICAgICAgICAgLy8gdGhlbSBhbm90aGVyIGNoYW5jZS4gSWYgd2UncmUgdG9vIGxhdGUsIHRoZSBhdWRpbworICAgICAgICAgICAgLy8gaGFyZHdhcmUgd2lsbCB6ZXJvLWZpbGwgZm9yIHVzLgorICAgICAgICAgICAgLy9MT0dWKCJubyBidWZmZXJzIC0gdXNsZWVwKCVsdSkiLCBzbGVlcFRpbWUpOworICAgICAgICAgICAgdXNsZWVwKHNsZWVwVGltZSk7CisgICAgICAgICAgICBpZiAoc2xlZXBUaW1lIDwga01heEJ1ZmZlclJlY292ZXJ5SW5Vc2VjcykgeworICAgICAgICAgICAgICAgIHNsZWVwVGltZSArPSBrQnVmZmVyUmVjb3ZlcnlJblVzZWNzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gZmluYWxseSBsZXQgZ28gb2YgYWxsIG91ciB0cmFja3MsIHdpdGhvdXQgdGhlIGxvY2sgaGVsZAorICAgICAgICAvLyBzaW5jZSB3ZSBjYW4ndCBndWFyYW50ZWUgdGhlIGRlc3RydWN0b3JzIHdvbid0IGFjcXVpcmUgdGhhdAorICAgICAgICAvLyBzYW1lIGxvY2suCisgICAgICAgIHRyYWNrc1RvUmVtb3ZlLmNsZWFyKCk7CisgICAgfSB3aGlsZSAodHJ1ZSk7CisKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OnJlYWR5VG9SdW4oKQoreworICAgIGlmIChtU2FtcGxlUmF0ZSA9PSAwKSB7CisgICAgICAgIExPR0UoIk5vIHdvcmtpbmcgYXVkaW8gZHJpdmVyIGZvdW5kLiIpOworICAgICAgICByZXR1cm4gTk9fSU5JVDsKKyAgICB9CisgICAgTE9HSSgiQXVkaW9GbGluZ2VyJ3MgdGhyZWFkIHJlYWR5IHRvIHJ1biBmb3Igb3V0cHV0ICVkIiwgbU91dHB1dFR5cGUpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpvbkZpcnN0UmVmKCkKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIk1peGVyIFRocmVhZCBmb3Igb3V0cHV0ICVkIiwgbU91dHB1dFR5cGUpOworCisgICAgcnVuKGJ1ZmZlciwgQU5EUk9JRF9QUklPUklUWV9VUkdFTlRfQVVESU8pOworfQorCisKK3NwPEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrPiAgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6Y3JlYXRlVHJhY2soCisgICAgICAgIGNvbnN0IHNwPEF1ZGlvRmxpbmdlcjo6Q2xpZW50PiYgY2xpZW50LAorICAgICAgICBpbnQgc3RyZWFtVHlwZSwKKyAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgIGNvbnN0IHNwPElNZW1vcnk+JiBzaGFyZWRCdWZmZXIsCisgICAgICAgIHN0YXR1c190ICpzdGF0dXMpCit7CisgICAgc3A8VHJhY2s+IHRyYWNrOworICAgIHN0YXR1c190IGxTdGF0dXM7CisgICAgCisgICAgLy8gUmVzYW1wbGVyIGltcGxlbWVudGF0aW9uIGxpbWl0cyBpbnB1dCBzYW1wbGluZyByYXRlIHRvIDIgeCBvdXRwdXQgc2FtcGxpbmcgcmF0ZS4KKyAgICBpZiAoc2FtcGxlUmF0ZSA+IE1BWF9TQU1QTEVfUkFURSB8fCBzYW1wbGVSYXRlID4gbVNhbXBsZVJhdGUqMikgeworICAgICAgICBMT0dFKCJTYW1wbGUgcmF0ZSBvdXQgb2YgcmFuZ2U6ICVkIG1TYW1wbGVSYXRlICVkIiwgc2FtcGxlUmF0ZSwgbVNhbXBsZVJhdGUpOworICAgICAgICBsU3RhdHVzID0gQkFEX1ZBTFVFOworICAgICAgICBnb3RvIEV4aXQ7CisgICAgfQorCisgICAgeworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworCisgICAgICAgIGlmIChtU2FtcGxlUmF0ZSA9PSAwKSB7CisgICAgICAgICAgICBMT0dFKCJBdWRpbyBkcml2ZXIgbm90IGluaXRpYWxpemVkLiIpOworICAgICAgICAgICAgbFN0YXR1cyA9IE5PX0lOSVQ7CisgICAgICAgICAgICBnb3RvIEV4aXQ7CisgICAgICAgIH0KKworICAgICAgICB0cmFjayA9IG5ldyBUcmFjayh0aGlzLCBjbGllbnQsIHN0cmVhbVR5cGUsIHNhbXBsZVJhdGUsIGZvcm1hdCwKKyAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQsIGZyYW1lQ291bnQsIHNoYXJlZEJ1ZmZlcik7CisgICAgICAgIGlmICh0cmFjay0+Z2V0Q2JsaygpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHRyYWNrLmNsZWFyKCk7CisgICAgICAgICAgICBsU3RhdHVzID0gTk9fTUVNT1JZOworICAgICAgICAgICAgZ290byBFeGl0OworICAgICAgICB9CisgICAgICAgIG1UcmFja3MuYWRkKHRyYWNrKTsKKyAgICAgICAgbFN0YXR1cyA9IE5PX0VSUk9SOworICAgIH0KKworRXhpdDoKKyAgICBpZihzdGF0dXMpIHsKKyAgICAgICAgKnN0YXR1cyA9IGxTdGF0dXM7CisgICAgfQorICAgIHJldHVybiB0cmFjazsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpnZXRUcmFja3MoCisgICAgICAgIFNvcnRlZFZlY3RvciA8IHNwPFRyYWNrPiA+JiB0cmFja3MsCisgICAgICAgIFNvcnRlZFZlY3RvciA8IHdwPFRyYWNrPiA+JiBhY3RpdmVUcmFja3MpCit7CisgICAgc2l6ZV90IHNpemUgPSBtVHJhY2tzLnNpemUoKTsKKyAgICBMT0dWICgiTWl4ZXJUaHJlYWQ6OmdldFRyYWNrcygpIGZvciBvdXRwdXQgJWQsIG1UcmFja3Muc2l6ZSAlZCwgbUFjdGl2ZVRyYWNrcy5zaXplICVkIiwgbU91dHB1dFR5cGUsICBtVHJhY2tzLnNpemUoKSwgbUFjdGl2ZVRyYWNrcy5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgIHNwPFRyYWNrPiB0ID0gbVRyYWNrc1tpXTsKKyAgICAgICAgaWYgKEF1ZGlvU3lzdGVtOjpyb3V0ZWRUb0EyZHBPdXRwdXQodC0+bVN0cmVhbVR5cGUpKSB7CisgICAgICAgICAgICB0cmFja3MuYWRkKHQpOworICAgICAgICAgICAgaW50IGogPSBtQWN0aXZlVHJhY2tzLmluZGV4T2YodCk7CisgICAgICAgICAgICBpZiAoaiA+PSAwKSB7CisgICAgICAgICAgICAgICAgdCA9IG1BY3RpdmVUcmFja3Nbal0ucHJvbW90ZSgpOworICAgICAgICAgICAgICAgIGlmICh0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWN0aXZlVHJhY2tzLmFkZCh0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgc2l6ZSA9IGFjdGl2ZVRyYWNrcy5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgcmVtb3ZlQWN0aXZlVHJhY2soYWN0aXZlVHJhY2tzW2ldKTsKKyAgICB9CisgICAgCisgICAgc2l6ZSA9IHRyYWNrcy5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgc3A8VHJhY2s+IHQgPSB0cmFja3NbaV07CisgICAgICAgIG1UcmFja3MucmVtb3ZlKHQpOworICAgICAgICBkZWxldGVUcmFja05hbWUodC0+bmFtZSgpKTsKKyAgICB9Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6cHV0VHJhY2tzKAorICAgICAgICBTb3J0ZWRWZWN0b3IgPCBzcDxUcmFjaz4gPiYgdHJhY2tzLAorICAgICAgICBTb3J0ZWRWZWN0b3IgPCB3cDxUcmFjaz4gPiYgYWN0aXZlVHJhY2tzKQoreworCisgICAgTE9HViAoIk1peGVyVGhyZWFkOjpwdXRUcmFja3MoKSBmb3Igb3V0cHV0ICVkLCB0cmFja3Muc2l6ZSAlZCwgYWN0aXZlVHJhY2tzLnNpemUgJWQiLCBtT3V0cHV0VHlwZSwgIHRyYWNrcy5zaXplKCksIGFjdGl2ZVRyYWNrcy5zaXplKCkpOworCisgICAgc2l6ZV90IHNpemUgPSB0cmFja3Muc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZSA7IGkrKykgeworICAgICAgICBzcDxUcmFjaz4gdCA9IHRyYWNrc1tpXTsKKyAgICAgICAgaW50IG5hbWUgPSBnZXRUcmFja05hbWUoKTsKKworICAgICAgICBpZiAobmFtZSA8IDApIHJldHVybjsKKyAgICAgICAgCisgICAgICAgIHQtPm1OYW1lID0gbmFtZTsKKyAgICAgICAgdC0+bU1peGVyVGhyZWFkID0gdGhpczsKKyAgICAgICAgbVRyYWNrcy5hZGQodCk7CisKKyAgICAgICAgaW50IGogPSBhY3RpdmVUcmFja3MuaW5kZXhPZih0KTsKKyAgICAgICAgaWYgKGogPj0gMCkgeworICAgICAgICAgICAgYWRkQWN0aXZlVHJhY2sodCk7CisgICAgICAgIH0gICAgICAgICAgICAKKyAgICB9Cit9CisKK3VpbnQzMl90IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OnNhbXBsZVJhdGUoKSBjb25zdAoreworICAgIHJldHVybiBtU2FtcGxlUmF0ZTsKK30KKworaW50IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OmNoYW5uZWxDb3VudCgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1DaGFubmVsQ291bnQ7Cit9CisKK2ludCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpmb3JtYXQoKSBjb25zdAoreworICAgIHJldHVybiBtRm9ybWF0OworfQorCitzaXplX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6ZnJhbWVDb3VudCgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1GcmFtZUNvdW50OworfQorCit1aW50MzJfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpsYXRlbmN5KCkgY29uc3QKK3sKKyAgICBpZiAobU91dHB1dCkgeworICAgICAgICByZXR1cm4gbU91dHB1dC0+bGF0ZW5jeSgpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpzZXRNYXN0ZXJWb2x1bWUoZmxvYXQgdmFsdWUpCit7CisgICAgbU1hc3RlclZvbHVtZSA9IHZhbHVlOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6c2V0TWFzdGVyTXV0ZShib29sIG11dGVkKQoreworICAgIG1NYXN0ZXJNdXRlID0gbXV0ZWQ7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitmbG9hdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjptYXN0ZXJWb2x1bWUoKSBjb25zdAoreworICAgIHJldHVybiBtTWFzdGVyVm9sdW1lOworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6Om1hc3Rlck11dGUoKSBjb25zdAoreworICAgIHJldHVybiBtTWFzdGVyTXV0ZTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6c2V0U3RyZWFtVm9sdW1lKGludCBzdHJlYW0sIGZsb2F0IHZhbHVlKQoreworICAgIG1TdHJlYW1UeXBlc1tzdHJlYW1dLnZvbHVtZSA9IHZhbHVlOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6c2V0U3RyZWFtTXV0ZShpbnQgc3RyZWFtLCBib29sIG11dGVkKQoreworICAgIG1TdHJlYW1UeXBlc1tzdHJlYW1dLm11dGUgPSBtdXRlZDsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK2Zsb2F0IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OnN0cmVhbVZvbHVtZShpbnQgc3RyZWFtKSBjb25zdAoreworICAgIHJldHVybiBtU3RyZWFtVHlwZXNbc3RyZWFtXS52b2x1bWU7Cit9CisKK2Jvb2wgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6c3RyZWFtTXV0ZShpbnQgc3RyZWFtKSBjb25zdAoreworICAgIHJldHVybiBtU3RyZWFtVHlwZXNbc3RyZWFtXS5tdXRlOworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OmlzTXVzaWNBY3RpdmUoKSBjb25zdAoreworICAgIHNpemVfdCBjb3VudCA9IG1BY3RpdmVUcmFja3Muc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGkgPSAwIDsgaSA8IGNvdW50IDsgKytpKSB7CisgICAgICAgIHNwPFRyYWNrPiB0ID0gbUFjdGl2ZVRyYWNrc1tpXS5wcm9tb3RlKCk7CisgICAgICAgIGlmICh0ID09IDApIGNvbnRpbnVlOworICAgICAgICBUcmFjayogY29uc3QgdHJhY2sgPSB0LmdldCgpOworICAgICAgICBpZiAodC0+bVN0cmVhbVR5cGUgPT0gQXVkaW9TeXN0ZW06Ok1VU0lDKQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6YWRkVHJhY2soY29uc3Qgc3A8VHJhY2s+JiB0cmFjaykKK3sKKyAgICBzdGF0dXNfdCBzdGF0dXMgPSBBTFJFQURZX0VYSVNUUzsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworCisgICAgLy8gaGVyZSB0aGUgdHJhY2sgY291bGQgYmUgZWl0aGVyIG5ldywgb3IgcmVzdGFydGVkCisgICAgLy8gaW4gYm90aCBjYXNlcyAidW5zdG9wIiB0aGUgdHJhY2sKKyAgICBpZiAodHJhY2stPmlzUGF1c2VkKCkpIHsKKyAgICAgICAgdHJhY2stPm1TdGF0ZSA9IFRyYWNrQmFzZTo6UkVTVU1JTkc7CisgICAgICAgIExPR1YoIlBBVVNFRCA9PiBSRVNVTUlORyAoJWQpIiwgdHJhY2stPm5hbWUoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgdHJhY2stPm1TdGF0ZSA9IFRyYWNrQmFzZTo6QUNUSVZFOworICAgICAgICBMT0dWKCI/ID0+IEFDVElWRSAoJWQpIiwgdHJhY2stPm5hbWUoKSk7CisgICAgfQorICAgIC8vIHNldCByZXRyeSBjb3VudCBmb3IgYnVmZmVyIGZpbGwKKyAgICB0cmFjay0+bVJldHJ5Q291bnQgPSBrTWF4VHJhY2tTdGFydHVwUmV0cmllczsKKyAgICBpZiAobUFjdGl2ZVRyYWNrcy5pbmRleE9mKHRyYWNrKSA8IDApIHsKKyAgICAgICAgLy8gdGhlIHRyYWNrIGlzIG5ld2x5IGFkZGVkLCBtYWtlIHN1cmUgaXQgZmlsbHMgdXAgYWxsIGl0cworICAgICAgICAvLyBidWZmZXJzIGJlZm9yZSBwbGF5aW5nLiBUaGlzIGlzIHRvIGVuc3VyZSB0aGUgY2xpZW50IHdpbGwKKyAgICAgICAgLy8gZWZmZWN0aXZlbHkgZ2V0IHRoZSBsYXRlbmN5IGl0IHJlcXVlc3RlZC4KKyAgICAgICAgdHJhY2stPm1GaWxsaW5nVXBTdGF0dXMgPSBUcmFjazo6RlNfRklMTElORzsKKyAgICAgICAgdHJhY2stPm1SZXNldERvbmUgPSBmYWxzZTsKKyAgICAgICAgYWRkQWN0aXZlVHJhY2sodHJhY2spOworICAgICAgICBzdGF0dXMgPSBOT19FUlJPUjsKKyAgICB9CisgICAgCisgICAgTE9HVigibVdhaXRXb3JrQ1YuYnJvYWRjYXN0Iik7CisgICAgbVdhaXRXb3JrQ1YuYnJvYWRjYXN0KCk7CisKKyAgICByZXR1cm4gc3RhdHVzOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OnJlbW92ZVRyYWNrKHdwPFRyYWNrPiB0cmFjaywgaW50IG5hbWUpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBzcDxUcmFjaz4gdCA9IHRyYWNrLnByb21vdGUoKTsKKyAgICBpZiAodCE9TlVMTCAmJiAodC0+bVN0YXRlIDw9IFRyYWNrQmFzZTo6U1RPUFBFRCkpIHsKKyAgICAgICAgcmVtb3ZlX3RyYWNrX2wodHJhY2ssIG5hbWUpOworICAgIH0KK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpyZW1vdmVfdHJhY2tfbCh3cDxUcmFjaz4gdHJhY2ssIGludCBuYW1lKQoreworICAgIHNwPFRyYWNrPiB0ID0gdHJhY2sucHJvbW90ZSgpOworICAgIGlmICh0IT1OVUxMKSB7CisgICAgICAgIHQtPnJlc2V0KCk7CisgICAgfQorICAgIGRlbGV0ZVRyYWNrTmFtZShuYW1lKTsKKyAgICByZW1vdmVBY3RpdmVUcmFjayh0cmFjayk7CisgICAgbVdhaXRXb3JrQ1YuYnJvYWRjYXN0KCk7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6ZGVzdHJveVRyYWNrKGNvbnN0IHNwPFRyYWNrPiYgdHJhY2spCit7CisgICAgLy8gTk9URTogV2UncmUgYWNxdWlyaW5nIGEgc3Ryb25nIHJlZmVyZW5jZSBvbiB0aGUgdHJhY2sgYmVmb3JlCisgICAgLy8gYWNxdWlyaW5nIHRoZSBsb2NrLCB0aGlzIGlzIHRvIG1ha2Ugc3VyZSByZW1vdmluZyBpdCBmcm9tCisgICAgLy8gbVRyYWNrcyB3b24ndCBjYXVzZSB0aGUgZGVzdHJ1Y3RvciB0byBiZSBjYWxsZWQgd2hpbGUgdGhlIGxvY2sgaXMKKyAgICAvLyBoZWxkIChub3RlIHRoYXQgdGVjaG5pY2FsbHksICd0cmFjaycgY291bGQgYmUgYSByZWZlcmVuY2UgdG8gYW4gaXRlbQorICAgIC8vIGluIG1UcmFja3MsIHdoaWNoIGlzIHdoeSB3ZSBuZWVkIHRvIGRvIHRoaXMpLgorICAgIHNwPFRyYWNrPiBrZWVwKHRyYWNrKTsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIHRyYWNrLT5tU3RhdGUgPSBUcmFja0Jhc2U6OlRFUk1JTkFURUQ7CisgICAgaWYgKG1BY3RpdmVUcmFja3MuaW5kZXhPZih0cmFjaykgPCAwKSB7CisgICAgICAgIExPR1YoInJlbW92ZSB0cmFjayAoJWQpIGFuZCBkZWxldGUgZnJvbSBtaXhlciIsIHRyYWNrLT5uYW1lKCkpOworICAgICAgICBtVHJhY2tzLnJlbW92ZSh0cmFjayk7CisgICAgICAgIGRlbGV0ZVRyYWNrTmFtZShrZWVwLT5uYW1lKCkpOworICAgIH0KK30KKworCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OmFkZEFjdGl2ZVRyYWNrKGNvbnN0IHdwPFRyYWNrPiYgdCkKK3sKKyAgICBtQWN0aXZlVHJhY2tzLmFkZCh0KTsKKworICAgIC8vIEZvcmNlIHJvdXRpbmcgdG8gc3BlYWtlciBmb3IgY2VydGFpbiBzdHJlYW0gdHlwZXMKKyAgICAvLyBUaGUgZm9yY2VkIHJvdXRpbmcgdG8gc3BlYWtlciBpcyBtYW5hZ2VkIGJ5IGhhcmR3YXJlIG1peGVyCisgICAgaWYgKG1PdXRwdXRUeXBlID09IEF1ZGlvU3lzdGVtOjpBVURJT19PVVRQVVRfSEFSRFdBUkUpIHsKKyAgICAgICAgc3A8VHJhY2s+IHRyYWNrID0gdC5wcm9tb3RlKCk7CisgICAgICAgIGlmICh0cmFjayA9PSBOVUxMKSByZXR1cm47CisgICAKKyAgICAgICAgaWYgKHN0cmVhbUZvcmNlZFRvU3BlYWtlcih0cmFjay0+dHlwZSgpKSkgeworICAgICAgICAgICAgbUF1ZGlvRmxpbmdlci0+aGFuZGxlRm9yY2VkU3BlYWtlclJvdXRlKEFDVElWRV9UUkFDS19BRERFRCk7CisgICAgICAgIH0gICAgICAgIAorICAgIH0KK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpyZW1vdmVBY3RpdmVUcmFjayhjb25zdCB3cDxUcmFjaz4mIHQpCit7CisgICAgbUFjdGl2ZVRyYWNrcy5yZW1vdmUodCk7CisKKyAgICAvLyBGb3JjZSByb3V0aW5nIHRvIHNwZWFrZXIgZm9yIGNlcnRhaW4gc3RyZWFtIHR5cGVzCisgICAgLy8gVGhlIGZvcmNlZCByb3V0aW5nIHRvIHNwZWFrZXIgaXMgbWFuYWdlZCBieSBoYXJkd2FyZSBtaXhlcgorICAgIGlmIChtT3V0cHV0VHlwZSA9PSBBdWRpb1N5c3RlbTo6QVVESU9fT1VUUFVUX0hBUkRXQVJFKSB7CisgICAgICAgIHNwPFRyYWNrPiB0cmFjayA9IHQucHJvbW90ZSgpOworICAgICAgICBpZiAodHJhY2sgPT0gTlVMTCkgcmV0dXJuOworCisgICAgICAgIGlmIChzdHJlYW1Gb3JjZWRUb1NwZWFrZXIodHJhY2stPnR5cGUoKSkpIHsKKyAgICAgICAgICAgIG1BdWRpb0ZsaW5nZXItPmhhbmRsZUZvcmNlZFNwZWFrZXJSb3V0ZShBQ1RJVkVfVFJBQ0tfUkVNT1ZFRCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK2ludCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpnZXRUcmFja05hbWUoKQoreworICAgIHJldHVybiBtQXVkaW9NaXhlci0+Z2V0VHJhY2tOYW1lKCk7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6ZGVsZXRlVHJhY2tOYW1lKGludCBuYW1lKQoreworICAgIG1BdWRpb01peGVyLT5kZWxldGVUcmFja05hbWUobmFtZSk7Cit9CisKK3NpemVfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpnZXRPdXRwdXRGcmFtZUNvdW50KCkgCit7CisgICAgcmV0dXJuIG1PdXRwdXQtPmJ1ZmZlclNpemUoKSAvIG1PdXRwdXQtPmNoYW5uZWxDb3VudCgpIC8gc2l6ZW9mKGludDE2X3QpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrQmFzZTo6VHJhY2tCYXNlKAorICAgICAgICAgICAgY29uc3Qgc3A8TWl4ZXJUaHJlYWQ+JiBtaXhlclRocmVhZCwKKyAgICAgICAgICAgIGNvbnN0IHNwPENsaWVudD4mIGNsaWVudCwKKyAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgICAgICB1aW50MzJfdCBmbGFncywKKyAgICAgICAgICAgIGNvbnN0IHNwPElNZW1vcnk+JiBzaGFyZWRCdWZmZXIpCisgICAgOiAgIFJlZkJhc2UoKSwKKyAgICAgICAgbU1peGVyVGhyZWFkKG1peGVyVGhyZWFkKSwKKyAgICAgICAgbUNsaWVudChjbGllbnQpLAorICAgICAgICBtU3RyZWFtVHlwZShzdHJlYW1UeXBlKSwKKyAgICAgICAgbUZyYW1lQ291bnQoMCksCisgICAgICAgIG1TdGF0ZShJRExFKSwKKyAgICAgICAgbUNsaWVudFRpZCgtMSksCisgICAgICAgIG1Gb3JtYXQoZm9ybWF0KSwKKyAgICAgICAgbUZsYWdzKGZsYWdzICYgflNZU1RFTV9GTEFHU19NQVNLKQoreworICAgIG1OYW1lID0gbWl4ZXJUaHJlYWQtPmdldFRyYWNrTmFtZSgpOworICAgIExPR1YoIlRyYWNrQmFzZSBjb250cnVjdG9yIG5hbWUgJWQsIGNhbGxpbmcgdGhyZWFkICVkIiwgbU5hbWUsIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSk7CisgICAgaWYgKG1OYW1lIDwgMCkgeworICAgICAgICBMT0dFKCJubyBtb3JlIHRyYWNrIG5hbWVzIGF2YWlsbGFibGUiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIExPR1ZfSUYoc2hhcmVkQnVmZmVyICE9IDAsICJzaGFyZWRCdWZmZXI6ICVwLCBzaXplOiAlZCIsIHNoYXJlZEJ1ZmZlci0+cG9pbnRlcigpLCBzaGFyZWRCdWZmZXItPnNpemUoKSk7CisKKyAgICAvLyBMT0dEKCJDcmVhdGluZyB0cmFjayB3aXRoICVkIGJ1ZmZlcnMgQCAlZCBieXRlcyIsIGJ1ZmZlckNvdW50LCBidWZmZXJTaXplKTsKKyAgIHNpemVfdCBzaXplID0gc2l6ZW9mKGF1ZGlvX3RyYWNrX2NibGtfdCk7CisgICBzaXplX3QgYnVmZmVyU2l6ZSA9IGZyYW1lQ291bnQqY2hhbm5lbENvdW50KnNpemVvZihpbnQxNl90KTsKKyAgIGlmIChzaGFyZWRCdWZmZXIgPT0gMCkgeworICAgICAgIHNpemUgKz0gYnVmZmVyU2l6ZTsKKyAgIH0KKworICAgaWYgKGNsaWVudCAhPSBOVUxMKSB7CisgICAgICAgIG1DYmxrTWVtb3J5ID0gY2xpZW50LT5oZWFwKCktPmFsbG9jYXRlKHNpemUpOworICAgICAgICBpZiAobUNibGtNZW1vcnkgIT0gMCkgeworICAgICAgICAgICAgbUNibGsgPSBzdGF0aWNfY2FzdDxhdWRpb190cmFja19jYmxrX3QgKj4obUNibGtNZW1vcnktPnBvaW50ZXIoKSk7CisgICAgICAgICAgICBpZiAobUNibGspIHsgLy8gY29uc3RydWN0IHRoZSBzaGFyZWQgc3RydWN0dXJlIGluLXBsYWNlLgorICAgICAgICAgICAgICAgIG5ldyhtQ2JsaykgYXVkaW9fdHJhY2tfY2Jsa190KCk7CisgICAgICAgICAgICAgICAgLy8gY2xlYXIgYWxsIGJ1ZmZlcnMKKyAgICAgICAgICAgICAgICBtQ2Jsay0+ZnJhbWVDb3VudCA9IGZyYW1lQ291bnQ7CisgICAgICAgICAgICAgICAgbUNibGstPnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlOworICAgICAgICAgICAgICAgIG1DYmxrLT5jaGFubmVscyA9IGNoYW5uZWxDb3VudDsKKyAgICAgICAgICAgICAgICBpZiAoc2hhcmVkQnVmZmVyID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbUJ1ZmZlciA9IChjaGFyKiltQ2JsayArIHNpemVvZihhdWRpb190cmFja19jYmxrX3QpOworICAgICAgICAgICAgICAgICAgICBtZW1zZXQobUJ1ZmZlciwgMCwgZnJhbWVDb3VudCpjaGFubmVsQ291bnQqc2l6ZW9mKGludDE2X3QpKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgdW5kZXJydW4gY29uZGl0aW9uIHRvIGF2b2lkIGZhbHNlIHVuZGVycnVuIGNhbGxiYWNrIHVudGlsIGZpcnN0IGRhdGEgaXMKKyAgICAgICAgICAgICAgICAgICAgLy8gd3JpdHRlbiB0byBidWZmZXIKKyAgICAgICAgICAgICAgICAgICAgbUNibGstPmZsb3dDb250cm9sRmxhZyA9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgbUJ1ZmZlciA9IHNoYXJlZEJ1ZmZlci0+cG9pbnRlcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBtQnVmZmVyRW5kID0gKHVpbnQ4X3QgKiltQnVmZmVyICsgYnVmZmVyU2l6ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0UoIm5vdCBlbm91Z2ggbWVtb3J5IGZvciBBdWRpb1RyYWNrIHNpemU9JXUiLCBzaXplKTsKKyAgICAgICAgICAgIGNsaWVudC0+aGVhcCgpLT5kdW1wKCJBdWRpb1RyYWNrIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgIH0gZWxzZSB7CisgICAgICAgbUNibGsgPSAoYXVkaW9fdHJhY2tfY2Jsa190ICopKG5ldyB1aW50OF90W3NpemVdKTsKKyAgICAgICBpZiAobUNibGspIHsgLy8gY29uc3RydWN0IHRoZSBzaGFyZWQgc3RydWN0dXJlIGluLXBsYWNlLgorICAgICAgICAgICBuZXcobUNibGspIGF1ZGlvX3RyYWNrX2NibGtfdCgpOworICAgICAgICAgICAvLyBjbGVhciBhbGwgYnVmZmVycworICAgICAgICAgICBtQ2Jsay0+ZnJhbWVDb3VudCA9IGZyYW1lQ291bnQ7CisgICAgICAgICAgIG1DYmxrLT5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTsKKyAgICAgICAgICAgbUNibGstPmNoYW5uZWxzID0gY2hhbm5lbENvdW50OworICAgICAgICAgICBtQnVmZmVyID0gKGNoYXIqKW1DYmxrICsgc2l6ZW9mKGF1ZGlvX3RyYWNrX2NibGtfdCk7CisgICAgICAgICAgIG1lbXNldChtQnVmZmVyLCAwLCBmcmFtZUNvdW50KmNoYW5uZWxDb3VudCpzaXplb2YoaW50MTZfdCkpOworICAgICAgICAgICAvLyBGb3JjZSB1bmRlcnJ1biBjb25kaXRpb24gdG8gYXZvaWQgZmFsc2UgdW5kZXJydW4gY2FsbGJhY2sgdW50aWwgZmlyc3QgZGF0YSBpcworICAgICAgICAgICAvLyB3cml0dGVuIHRvIGJ1ZmZlcgorICAgICAgICAgICBtQ2Jsay0+Zmxvd0NvbnRyb2xGbGFnID0gMTsKKyAgICAgICAgICAgbUJ1ZmZlckVuZCA9ICh1aW50OF90ICopbUJ1ZmZlciArIGJ1ZmZlclNpemU7CisgICAgICAgfQorICAgfQorfQorCitBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFja0Jhc2U6On5UcmFja0Jhc2UoKQoreworICAgIGlmIChtQ2JsaykgeworICAgICAgICBtQ2Jsay0+fmF1ZGlvX3RyYWNrX2NibGtfdCgpOyAgIC8vIGRlc3Ryb3kgb3VyIHNoYXJlZC1zdHJ1Y3R1cmUuICAgICAgICAKKyAgICB9CisgICAgbUNibGtNZW1vcnkuY2xlYXIoKTsgICAgICAgICAgICAvLyBhbmQgZnJlZSB0aGUgc2hhcmVkIG1lbW9yeQorICAgIG1DbGllbnQuY2xlYXIoKTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFja0Jhc2U6OnJlbGVhc2VCdWZmZXIoQXVkaW9CdWZmZXJQcm92aWRlcjo6QnVmZmVyKiBidWZmZXIpCit7CisgICAgYnVmZmVyLT5yYXcgPSAwOworICAgIG1GcmFtZUNvdW50ID0gYnVmZmVyLT5mcmFtZUNvdW50OworICAgIHN0ZXAoKTsKKyAgICBidWZmZXItPmZyYW1lQ291bnQgPSAwOworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrQmFzZTo6c3RlcCgpIHsKKyAgICBib29sIHJlc3VsdDsKKyAgICBhdWRpb190cmFja19jYmxrX3QqIGNibGsgPSB0aGlzLT5jYmxrKCk7CisKKyAgICByZXN1bHQgPSBjYmxrLT5zdGVwU2VydmVyKG1GcmFtZUNvdW50KTsKKyAgICBpZiAoIXJlc3VsdCkgeworICAgICAgICBMT0dWKCJzdGVwU2VydmVyIGZhaWxlZCBhY3F1aXJpbmcgY2JsayBtdXRleCIpOworICAgICAgICBtRmxhZ3MgfD0gU1RFUFNFUlZFUl9GQUlMRUQ7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2tCYXNlOjpyZXNldCgpIHsKKyAgICBhdWRpb190cmFja19jYmxrX3QqIGNibGsgPSB0aGlzLT5jYmxrKCk7CisKKyAgICBjYmxrLT51c2VyID0gMDsKKyAgICBjYmxrLT5zZXJ2ZXIgPSAwOworICAgIGNibGstPnVzZXJCYXNlID0gMDsKKyAgICBjYmxrLT5zZXJ2ZXJCYXNlID0gMDsKKyAgICBtRmxhZ3MgJj0gKHVpbnQzMl90KSh+U1lTVEVNX0ZMQUdTX01BU0spOworICAgIExPR1YoIlRyYWNrQmFzZTo6cmVzZXQiKTsKK30KKworc3A8SU1lbW9yeT4gQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2tCYXNlOjpnZXRDYmxrKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUNibGtNZW1vcnk7Cit9CisKK2ludCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFja0Jhc2U6OnNhbXBsZVJhdGUoKSBjb25zdCB7CisgICAgcmV0dXJuIG1DYmxrLT5zYW1wbGVSYXRlOworfQorCitpbnQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2tCYXNlOjpjaGFubmVsQ291bnQoKSBjb25zdCB7CisgICAgcmV0dXJuIG1DYmxrLT5jaGFubmVsczsKK30KKwordm9pZCogQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2tCYXNlOjpnZXRCdWZmZXIodWludDMyX3Qgb2Zmc2V0LCB1aW50MzJfdCBmcmFtZXMpIGNvbnN0IHsKKyAgICBhdWRpb190cmFja19jYmxrX3QqIGNibGsgPSB0aGlzLT5jYmxrKCk7CisgICAgaW50MTZfdCAqYnVmZmVyU3RhcnQgPSAoaW50MTZfdCAqKW1CdWZmZXIgKyAob2Zmc2V0LWNibGstPnNlcnZlckJhc2UpKmNibGstPmNoYW5uZWxzOworICAgIGludDE2X3QgKmJ1ZmZlckVuZCA9IGJ1ZmZlclN0YXJ0ICsgZnJhbWVzICogY2Jsay0+Y2hhbm5lbHM7CisKKyAgICAvLyBDaGVjayB2YWxpZGl0eSBvZiByZXR1cm5lZCBwb2ludGVyIGluIGNhc2UgdGhlIHRyYWNrIGNvbnRyb2wgYmxvY2sgd291bGQgaGF2ZSBiZWVuIGNvcnJ1cHRlZC4KKyAgICBpZiAoYnVmZmVyU3RhcnQgPCBtQnVmZmVyIHx8IGJ1ZmZlclN0YXJ0ID4gYnVmZmVyRW5kIHx8IGJ1ZmZlckVuZCA+IG1CdWZmZXJFbmQpIHsKKyAgICAgICAgTE9HVygiVHJhY2tCYXNlOjpnZXRCdWZmZXIgYnVmZmVyIG91dCBvZiByYW5nZTpcbiAgICBzdGFydDogJXAsIGVuZCAlcCAsIG1CdWZmZXIgJXAgbUJ1ZmZlckVuZCAlcFxuICAgIFwKKyAgICAgICAgICAgICAgICBzZXJ2ZXIgJWQsIHNlcnZlckJhc2UgJWQsIHVzZXIgJWQsIHVzZXJCYXNlICVkIiwKKyAgICAgICAgICAgICAgICBidWZmZXJTdGFydCwgYnVmZmVyRW5kLCBtQnVmZmVyLCBtQnVmZmVyRW5kLAorICAgICAgICAgICAgICAgIGNibGstPnNlcnZlciwgY2Jsay0+c2VydmVyQmFzZSwgY2Jsay0+dXNlciwgY2Jsay0+dXNlckJhc2UpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXR1cm4gYnVmZmVyU3RhcnQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2s6OlRyYWNrKAorICAgICAgICAgICAgY29uc3Qgc3A8TWl4ZXJUaHJlYWQ+JiBtaXhlclRocmVhZCwKKyAgICAgICAgICAgIGNvbnN0IHNwPENsaWVudD4mIGNsaWVudCwKKyAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgICAgICBjb25zdCBzcDxJTWVtb3J5PiYgc2hhcmVkQnVmZmVyKQorICAgIDogICBUcmFja0Jhc2UobWl4ZXJUaHJlYWQsIGNsaWVudCwgc3RyZWFtVHlwZSwgc2FtcGxlUmF0ZSwgZm9ybWF0LCBjaGFubmVsQ291bnQsIGZyYW1lQ291bnQsIDAsIHNoYXJlZEJ1ZmZlcikKK3sKKyAgICBtVm9sdW1lWzBdID0gMS4wZjsKKyAgICBtVm9sdW1lWzFdID0gMS4wZjsKKyAgICBtTXV0ZSA9IGZhbHNlOworICAgIG1TaGFyZWRCdWZmZXIgPSBzaGFyZWRCdWZmZXI7Cit9CisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrOjp+VHJhY2soKQoreworICAgIHdwPFRyYWNrPiB3ZWFrKHRoaXMpOyAvLyBuZXZlciBjcmVhdGUgYSBzdHJvbmcgcmVmIGZyb20gdGhlIGR0b3IKKyAgICBtU3RhdGUgPSBURVJNSU5BVEVEOworICAgIG1NaXhlclRocmVhZC0+cmVtb3ZlVHJhY2sod2VhaywgbU5hbWUpOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrOjpkZXN0cm95KCkKK3sKKyAgICBtTWl4ZXJUaHJlYWQtPmRlc3Ryb3lUcmFjayh0aGlzKTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjazo6ZHVtcChjaGFyKiBidWZmZXIsIHNpemVfdCBzaXplKQoreworICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZSwgIiAgJTVkICU1ZCAlM3UgJTN1ICUzdSAlM3UgJTFkICUxZCAlMWQgJTV1ICU1dSAlNXUgJTA0eCAlMDR4XG4iLAorICAgICAgICAgICAgbU5hbWUgLSBBdWRpb01peGVyOjpUUkFDSzAsCisgICAgICAgICAgICAobUNsaWVudCA9PSBOVUxMKSA/IGdldHBpZCgpIDogbUNsaWVudC0+cGlkKCksCisgICAgICAgICAgICBtU3RyZWFtVHlwZSwKKyAgICAgICAgICAgIG1Gb3JtYXQsCisgICAgICAgICAgICBtQ2Jsay0+Y2hhbm5lbHMsCisgICAgICAgICAgICBtRnJhbWVDb3VudCwKKyAgICAgICAgICAgIG1TdGF0ZSwKKyAgICAgICAgICAgIG1NdXRlLAorICAgICAgICAgICAgbUZpbGxpbmdVcFN0YXR1cywKKyAgICAgICAgICAgIG1DYmxrLT5zYW1wbGVSYXRlLAorICAgICAgICAgICAgbUNibGstPnZvbHVtZVswXSwKKyAgICAgICAgICAgIG1DYmxrLT52b2x1bWVbMV0sCisgICAgICAgICAgICBtQ2Jsay0+c2VydmVyLAorICAgICAgICAgICAgbUNibGstPnVzZXIpOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjazo6Z2V0TmV4dEJ1ZmZlcihBdWRpb0J1ZmZlclByb3ZpZGVyOjpCdWZmZXIqIGJ1ZmZlcikKK3sKKyAgICAgYXVkaW9fdHJhY2tfY2Jsa190KiBjYmxrID0gdGhpcy0+Y2JsaygpOworICAgICB1aW50MzJfdCBmcmFtZXNSZWFkeTsKKyAgICAgdWludDMyX3QgZnJhbWVzUmVxID0gYnVmZmVyLT5mcmFtZUNvdW50OworCisgICAgIC8vIENoZWNrIGlmIGxhc3Qgc3RlcFNlcnZlciBmYWlsZWQsIHRyeSB0byBzdGVwIG5vdworICAgICBpZiAobUZsYWdzICYgVHJhY2tCYXNlOjpTVEVQU0VSVkVSX0ZBSUxFRCkgeworICAgICAgICAgaWYgKCFzdGVwKCkpICBnb3RvIGdldE5leHRCdWZmZXJfZXhpdDsKKyAgICAgICAgIExPR1YoInN0ZXBTZXJ2ZXIgcmVjb3ZlcmVkIik7CisgICAgICAgICBtRmxhZ3MgJj0gflRyYWNrQmFzZTo6U1RFUFNFUlZFUl9GQUlMRUQ7CisgICAgIH0KKworICAgICBmcmFtZXNSZWFkeSA9IGNibGstPmZyYW1lc1JlYWR5KCk7CisKKyAgICAgaWYgKExJS0VMWShmcmFtZXNSZWFkeSkpIHsKKyAgICAgICAgdWludDMyX3QgcyA9IGNibGstPnNlcnZlcjsKKyAgICAgICAgdWludDMyX3QgYnVmZmVyRW5kID0gY2Jsay0+c2VydmVyQmFzZSArIGNibGstPmZyYW1lQ291bnQ7CisKKyAgICAgICAgYnVmZmVyRW5kID0gKGNibGstPmxvb3BFbmQgPCBidWZmZXJFbmQpID8gY2Jsay0+bG9vcEVuZCA6IGJ1ZmZlckVuZDsKKyAgICAgICAgaWYgKGZyYW1lc1JlcSA+IGZyYW1lc1JlYWR5KSB7CisgICAgICAgICAgICBmcmFtZXNSZXEgPSBmcmFtZXNSZWFkeTsKKyAgICAgICAgfQorICAgICAgICBpZiAocyArIGZyYW1lc1JlcSA+IGJ1ZmZlckVuZCkgeworICAgICAgICAgICAgZnJhbWVzUmVxID0gYnVmZmVyRW5kIC0gczsKKyAgICAgICAgfQorCisgICAgICAgICBidWZmZXItPnJhdyA9IGdldEJ1ZmZlcihzLCBmcmFtZXNSZXEpOworICAgICAgICAgaWYgKGJ1ZmZlci0+cmF3ID09IDApIGdvdG8gZ2V0TmV4dEJ1ZmZlcl9leGl0OworCisgICAgICAgICBidWZmZXItPmZyYW1lQ291bnQgPSBmcmFtZXNSZXE7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgfQorCitnZXROZXh0QnVmZmVyX2V4aXQ6CisgICAgIGJ1ZmZlci0+cmF3ID0gMDsKKyAgICAgYnVmZmVyLT5mcmFtZUNvdW50ID0gMDsKKyAgICAgcmV0dXJuIE5PVF9FTk9VR0hfREFUQTsKK30KKworYm9vbCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjazo6aXNSZWFkeSgpIGNvbnN0IHsKKyAgICBpZiAobUZpbGxpbmdVcFN0YXR1cyAhPSBGU19GSUxMSU5HKSByZXR1cm4gdHJ1ZTsKKworICAgIGlmIChtQ2Jsay0+ZnJhbWVzUmVhZHkoKSA+PSBtQ2Jsay0+ZnJhbWVDb3VudCB8fAorICAgICAgICBtQ2Jsay0+Zm9yY2VSZWFkeSkgeworICAgICAgICBtRmlsbGluZ1VwU3RhdHVzID0gRlNfRklMTEVEOworICAgICAgICBtQ2Jsay0+Zm9yY2VSZWFkeSA9IDA7CisgICAgICAgIExPR1YoIlRyYWNrOjppc1JlYWR5KCkgdHJhY2sgJWQgZm9yIG91dHB1dCAlZCIsIG1OYW1lLCBtTWl4ZXJUaHJlYWQtPm1PdXRwdXRUeXBlKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2s6OnN0YXJ0KCkKK3sKKyAgICBMT0dWKCJzdGFydCglZCksIGNhbGxpbmcgdGhyZWFkICVkIGZvciBvdXRwdXQgJWQiLCBtTmFtZSwgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1BpZCgpLCBtTWl4ZXJUaHJlYWQtPm1PdXRwdXRUeXBlKTsKKyAgICBtTWl4ZXJUaHJlYWQtPmFkZFRyYWNrKHRoaXMpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjazo6c3RvcCgpCit7CisgICAgTE9HVigic3RvcCglZCksIGNhbGxpbmcgdGhyZWFkICVkIGZvciBvdXRwdXQgJWQiLCBtTmFtZSwgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1BpZCgpLCBtTWl4ZXJUaHJlYWQtPm1PdXRwdXRUeXBlKTsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobU1peGVyVGhyZWFkLT5tTG9jayk7CisgICAgaWYgKG1TdGF0ZSA+IFNUT1BQRUQpIHsKKyAgICAgICAgbVN0YXRlID0gU1RPUFBFRDsKKyAgICAgICAgLy8gSWYgdGhlIHRyYWNrIGlzIG5vdCBhY3RpdmUgKFBBVVNFRCBhbmQgYnVmZmVycyBmdWxsKSwgZmx1c2ggYnVmZmVycworICAgICAgICBpZiAobU1peGVyVGhyZWFkLT5tQWN0aXZlVHJhY2tzLmluZGV4T2YodGhpcykgPCAwKSB7CisgICAgICAgICAgICByZXNldCgpOworICAgICAgICB9CisgICAgICAgIExPR1YoIig+IFNUT1BQRUQpID0+IFNUT1BQRUQgKCVkKSIsIG1OYW1lKTsKKyAgICB9Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2s6OnBhdXNlKCkKK3sKKyAgICBMT0dWKCJwYXVzZSglZCksIGNhbGxpbmcgdGhyZWFkICVkIiwgbU5hbWUsIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSk7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1NaXhlclRocmVhZC0+bUxvY2spOworICAgIGlmIChtU3RhdGUgPT0gQUNUSVZFIHx8IG1TdGF0ZSA9PSBSRVNVTUlORykgeworICAgICAgICBtU3RhdGUgPSBQQVVTSU5HOworICAgICAgICBMT0dWKCJBQ1RJVkUvUkVTVU1JTkcgPT4gUEFVU0lORyAoJWQpIiwgbU5hbWUpOworICAgIH0KK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjazo6Zmx1c2goKQoreworICAgIExPR1YoImZsdXNoKCVkKSIsIG1OYW1lKTsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobU1peGVyVGhyZWFkLT5tTG9jayk7CisgICAgaWYgKG1TdGF0ZSAhPSBTVE9QUEVEICYmIG1TdGF0ZSAhPSBQQVVTRUQgJiYgbVN0YXRlICE9IFBBVVNJTkcpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBObyBwb2ludCByZW1haW5pbmcgaW4gUEFVU0VEIHN0YXRlIGFmdGVyIGEgZmx1c2ggPT4gZ28gdG8KKyAgICAvLyBTVE9QUEVEIHN0YXRlCisgICAgbVN0YXRlID0gU1RPUFBFRDsKKworICAgIC8vIE5PVEU6IHJlc2V0KCkgd2lsbCByZXNldCBjYmxrLT51c2VyIGFuZCBjYmxrLT5zZXJ2ZXIgd2l0aAorICAgIC8vIHRoZSByaXNrIHRoYXQgYXQgdGhlIHNhbWUgdGltZSwgdGhlIEF1ZGlvTWl4ZXIgaXMgdHJ5aW5nIHRvIHJlYWQKKyAgICAvLyBkYXRhLiBJbiB0aGlzIGNhc2UsIGdldE5leHRCdWZmZXIoKSB3b3VsZCByZXR1cm4gYSBOVUxMIHBvaW50ZXIKKyAgICAvLyBhcyBhdWRpbyBidWZmZXIgPT4gdGhlIEF1ZGlvTWl4ZXIgY29kZSBNVVNUIGFsd2F5cyB0ZXN0IHRoYXQgcG9pbnRlcgorICAgIC8vIHJldHVybmVkIGJ5IGdldE5leHRCdWZmZXIoKSBpcyBub3QgTlVMTCEKKyAgICByZXNldCgpOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrOjpyZXNldCgpCit7CisgICAgLy8gRG8gbm90IHJlc2V0IHR3aWNlIHRvIGF2b2lkIGRpc2NhcmRpbmcgZGF0YSB3cml0dGVuIGp1c3QgYWZ0ZXIgYSBmbHVzaCBhbmQgYmVmb3JlCisgICAgLy8gdGhlIGF1ZGlvZmxpbmdlciB0aHJlYWQgZGV0ZWN0cyB0aGUgdHJhY2sgaXMgc3RvcHBlZC4KKyAgICBpZiAoIW1SZXNldERvbmUpIHsKKyAgICAgICAgVHJhY2tCYXNlOjpyZXNldCgpOworICAgICAgICAvLyBGb3JjZSB1bmRlcnJ1biBjb25kaXRpb24gdG8gYXZvaWQgZmFsc2UgdW5kZXJydW4gY2FsbGJhY2sgdW50aWwgZmlyc3QgZGF0YSBpcworICAgICAgICAvLyB3cml0dGVuIHRvIGJ1ZmZlcgorICAgICAgICBtQ2Jsay0+Zmxvd0NvbnRyb2xGbGFnID0gMTsKKyAgICAgICAgbUNibGstPmZvcmNlUmVhZHkgPSAwOworICAgICAgICBtRmlsbGluZ1VwU3RhdHVzID0gRlNfRklMTElORzsgICAgICAgIAorICAgICAgICBtUmVzZXREb25lID0gdHJ1ZTsKKyAgICB9Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6VHJhY2s6Om11dGUoYm9vbCBtdXRlZCkKK3sKKyAgICBtTXV0ZSA9IG11dGVkOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlRyYWNrOjpzZXRWb2x1bWUoZmxvYXQgbGVmdCwgZmxvYXQgcmlnaHQpCit7CisgICAgbVZvbHVtZVswXSA9IGxlZnQ7CisgICAgbVZvbHVtZVsxXSA9IHJpZ2h0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrOjpSZWNvcmRUcmFjaygKKyAgICAgICAgICAgIGNvbnN0IHNwPE1peGVyVGhyZWFkPiYgbWl4ZXJUaHJlYWQsCisgICAgICAgICAgICBjb25zdCBzcDxDbGllbnQ+JiBjbGllbnQsCisgICAgICAgICAgICBpbnQgc3RyZWFtVHlwZSwKKyAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgICAgIGludCBmcmFtZUNvdW50LAorICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MpCisgICAgOiAgIFRyYWNrQmFzZShtaXhlclRocmVhZCwgY2xpZW50LCBzdHJlYW1UeXBlLCBzYW1wbGVSYXRlLCBmb3JtYXQsCisgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQsIGZyYW1lQ291bnQsIGZsYWdzLCAwKSwKKyAgICAgICAgbU92ZXJmbG93KGZhbHNlKQoreworfQorCitBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpSZWNvcmRUcmFjazo6flJlY29yZFRyYWNrKCkKK3sKKyAgICBtTWl4ZXJUaHJlYWQtPmRlbGV0ZVRyYWNrTmFtZShtTmFtZSk7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrOjpnZXROZXh0QnVmZmVyKEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciogYnVmZmVyKQoreworICAgIGF1ZGlvX3RyYWNrX2NibGtfdCogY2JsayA9IHRoaXMtPmNibGsoKTsKKyAgICB1aW50MzJfdCBmcmFtZXNBdmFpbDsKKyAgICB1aW50MzJfdCBmcmFtZXNSZXEgPSBidWZmZXItPmZyYW1lQ291bnQ7CisKKyAgICAgLy8gQ2hlY2sgaWYgbGFzdCBzdGVwU2VydmVyIGZhaWxlZCwgdHJ5IHRvIHN0ZXAgbm93CisgICAgaWYgKG1GbGFncyAmIFRyYWNrQmFzZTo6U1RFUFNFUlZFUl9GQUlMRUQpIHsKKyAgICAgICAgaWYgKCFzdGVwKCkpIGdvdG8gZ2V0TmV4dEJ1ZmZlcl9leGl0OworICAgICAgICBMT0dWKCJzdGVwU2VydmVyIHJlY292ZXJlZCIpOworICAgICAgICBtRmxhZ3MgJj0gflRyYWNrQmFzZTo6U1RFUFNFUlZFUl9GQUlMRUQ7CisgICAgfQorCisgICAgZnJhbWVzQXZhaWwgPSBjYmxrLT5mcmFtZXNBdmFpbGFibGVfbCgpOworCisgICAgaWYgKExJS0VMWShmcmFtZXNBdmFpbCkpIHsKKyAgICAgICAgdWludDMyX3QgcyA9IGNibGstPnNlcnZlcjsKKyAgICAgICAgdWludDMyX3QgYnVmZmVyRW5kID0gY2Jsay0+c2VydmVyQmFzZSArIGNibGstPmZyYW1lQ291bnQ7CisKKyAgICAgICAgaWYgKGZyYW1lc1JlcSA+IGZyYW1lc0F2YWlsKSB7CisgICAgICAgICAgICBmcmFtZXNSZXEgPSBmcmFtZXNBdmFpbDsKKyAgICAgICAgfQorICAgICAgICBpZiAocyArIGZyYW1lc1JlcSA+IGJ1ZmZlckVuZCkgeworICAgICAgICAgICAgZnJhbWVzUmVxID0gYnVmZmVyRW5kIC0gczsKKyAgICAgICAgfQorCisgICAgICAgIGJ1ZmZlci0+cmF3ID0gZ2V0QnVmZmVyKHMsIGZyYW1lc1JlcSk7CisgICAgICAgIGlmIChidWZmZXItPnJhdyA9PSAwKSBnb3RvIGdldE5leHRCdWZmZXJfZXhpdDsKKworICAgICAgICBidWZmZXItPmZyYW1lQ291bnQgPSBmcmFtZXNSZXE7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisKK2dldE5leHRCdWZmZXJfZXhpdDoKKyAgICBidWZmZXItPnJhdyA9IDA7CisgICAgYnVmZmVyLT5mcmFtZUNvdW50ID0gMDsKKyAgICByZXR1cm4gTk9UX0VOT1VHSF9EQVRBOworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpSZWNvcmRUcmFjazo6c3RhcnQoKQoreworICAgIHJldHVybiBtTWl4ZXJUaHJlYWQtPm1BdWRpb0ZsaW5nZXItPnN0YXJ0UmVjb3JkKHRoaXMpOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrOjpzdG9wKCkKK3sKKyAgICBtTWl4ZXJUaHJlYWQtPm1BdWRpb0ZsaW5nZXItPnN0b3BSZWNvcmQodGhpcyk7CisgICAgVHJhY2tCYXNlOjpyZXNldCgpOworICAgIC8vIEZvcmNlIG92ZXJlcnJ1biBjb25kaXRpb24gdG8gYXZvaWQgZmFsc2Ugb3ZlcnJ1biBjYWxsYmFjayB1bnRpbCBmaXJzdCBkYXRhIGlzCisgICAgLy8gcmVhZCBmcm9tIGJ1ZmZlcgorICAgIG1DYmxrLT5mbG93Q29udHJvbEZsYWcgPSAxOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6T3V0cHV0VHJhY2s6Ok91dHB1dFRyYWNrKAorICAgICAgICAgICAgY29uc3Qgc3A8TWl4ZXJUaHJlYWQ+JiBtaXhlclRocmVhZCwKKyAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgICAgIGludCBmcmFtZUNvdW50KQorICAgIDogICBUcmFjayhtaXhlclRocmVhZCwgTlVMTCwgQXVkaW9TeXN0ZW06OlNZU1RFTSwgc2FtcGxlUmF0ZSwgZm9ybWF0LCBjaGFubmVsQ291bnQsIGZyYW1lQ291bnQsIE5VTEwpLAorICAgIG1PdXRwdXRNaXhlclRocmVhZChtaXhlclRocmVhZCkKK3sKKyAgICAgICAgICAgICAgICAKKyAgICBtQ2Jsay0+b3V0ID0gMTsKKyAgICBtQ2Jsay0+YnVmZmVycyA9IChjaGFyKiltQ2JsayArIHNpemVvZihhdWRpb190cmFja19jYmxrX3QpOworICAgIG1DYmxrLT52b2x1bWVbMF0gPSBtQ2Jsay0+dm9sdW1lWzFdID0gMHgxMDAwOworICAgIG1PdXRCdWZmZXIuZnJhbWVDb3VudCA9IDA7CisgICAgbUNibGstPmJ1ZmZlclRpbWVvdXRNcyA9IDEwOworICAgIAorICAgIExPR1YoIk91dHB1dFRyYWNrIGNvbnN0cnVjdG9yIG1DYmxrICVwLCBtQnVmZmVyICVwLCBtQ2Jsay0+YnVmZmVycyAlcCwgbUNibGstPmZyYW1lQ291bnQgJWQsIG1DYmxrLT5zYW1wbGVSYXRlICVkLCBtQ2Jsay0+Y2hhbm5lbHMgJWQgbUJ1ZmZlckVuZCAlcCIsIAorICAgICAgICAgICAgbUNibGssIG1CdWZmZXIsIG1DYmxrLT5idWZmZXJzLCBtQ2Jsay0+ZnJhbWVDb3VudCwgbUNibGstPnNhbXBsZVJhdGUsIG1DYmxrLT5jaGFubmVscywgbUJ1ZmZlckVuZCk7CisgICAgCit9CisKK0F1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6Ok91dHB1dFRyYWNrOjp+T3V0cHV0VHJhY2soKQoreworICAgIHN0b3AoKTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6T3V0cHV0VHJhY2s6OnN0YXJ0KCkKK3sKKyAgICBzdGF0dXNfdCBzdGF0dXMgPSBUcmFjazo6c3RhcnQoKTsKKyAgICAKKyAgICBtUmV0cnlDb3VudCA9IDEyNzsKKyAgICByZXR1cm4gc3RhdHVzOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6Ok91dHB1dFRyYWNrOjpzdG9wKCkKK3sKKyAgICBUcmFjazo6c3RvcCgpOworICAgIGNsZWFyQnVmZmVyUXVldWUoKTsKKyAgICBtT3V0QnVmZmVyLmZyYW1lQ291bnQgPSAwOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6Ok91dHB1dFRyYWNrOjp3cml0ZShpbnQxNl90KiBkYXRhLCB1aW50MzJfdCBmcmFtZXMpCit7CisgICAgQnVmZmVyICpwSW5CdWZmZXI7CisgICAgQnVmZmVyIGluQnVmZmVyOworICAgIHVpbnQzMl90IGNoYW5uZWxzID0gbUNibGstPmNoYW5uZWxzOworICAgICAgICAKKyAgICBpbkJ1ZmZlci5mcmFtZUNvdW50ID0gZnJhbWVzOworICAgIGluQnVmZmVyLmkxNiA9IGRhdGE7CisgICAgCisgICAgaWYgKG1DYmxrLT51c2VyID09IDApIHsKKyAgICAgICAgaWYgKG1PdXRwdXRNaXhlclRocmVhZC0+aXNNdXNpY0FjdGl2ZSgpKSB7CisgICAgICAgICAgICBtQ2Jsay0+Zm9yY2VSZWFkeSA9IDE7CisgICAgICAgICAgICBMT0dWKCJPdXRwdXRUcmFjazo6c3RhcnQoKSBmb3JjZSByZWFkeSIpOworICAgICAgICB9IGVsc2UgaWYgKG1DYmxrLT5mcmFtZUNvdW50ID4gZnJhbWVzKXsKKyAgICAgICAgICAgIGlmIChtQnVmZmVyUXVldWUuc2l6ZSgpIDwga01heE91dHB1dFRyYWNrQnVmZmVycykgeworICAgICAgICAgICAgICAgIHVpbnQzMl90IHN0YXJ0RnJhbWVzID0gKG1DYmxrLT5mcmFtZUNvdW50IC0gZnJhbWVzKTsKKyAgICAgICAgICAgICAgICBMT0dWKCJPdXRwdXRUcmFjazo6c3RhcnQoKSB3cml0ZSAlZCBmcmFtZXMiLCBzdGFydEZyYW1lcyk7CisgICAgICAgICAgICAgICAgcEluQnVmZmVyID0gbmV3IEJ1ZmZlcjsKKyAgICAgICAgICAgICAgICBwSW5CdWZmZXItPm1CdWZmZXIgPSBuZXcgaW50MTZfdFtzdGFydEZyYW1lcyAqIGNoYW5uZWxzXTsKKyAgICAgICAgICAgICAgICBwSW5CdWZmZXItPmZyYW1lQ291bnQgPSBzdGFydEZyYW1lczsKKyAgICAgICAgICAgICAgICBwSW5CdWZmZXItPmkxNiA9IHBJbkJ1ZmZlci0+bUJ1ZmZlcjsKKyAgICAgICAgICAgICAgICBtZW1zZXQocEluQnVmZmVyLT5yYXcsIDAsIHN0YXJ0RnJhbWVzICogY2hhbm5lbHMgKiBzaXplb2YoaW50MTZfdCkpOworICAgICAgICAgICAgICAgIG1CdWZmZXJRdWV1ZS5hZGQocEluQnVmZmVyKTsgICAgICAgICAgICAgICAgCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIExPR1cgKCJPdXRwdXRUcmFjazo6d3JpdGUoKSBubyBtb3JlIGJ1ZmZlcnMiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSAgICAgICAgCisgICAgfQorCisgICAgd2hpbGUgKDEpIHsgCisgICAgICAgIC8vIEZpcnN0IHdyaXRlIHBlbmRpbmcgYnVmZmVycywgdGhlbiBuZXcgZGF0YQorICAgICAgICBpZiAobUJ1ZmZlclF1ZXVlLnNpemUoKSkgeworICAgICAgICAgICAgcEluQnVmZmVyID0gbUJ1ZmZlclF1ZXVlLml0ZW1BdCgwKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBJbkJ1ZmZlciA9ICZpbkJ1ZmZlcjsKKyAgICAgICAgfQorIAorICAgICAgICBpZiAocEluQnVmZmVyLT5mcmFtZUNvdW50ID09IDApIHsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAobU91dEJ1ZmZlci5mcmFtZUNvdW50ID09IDApIHsKKyAgICAgICAgICAgIG1PdXRCdWZmZXIuZnJhbWVDb3VudCA9IHBJbkJ1ZmZlci0+ZnJhbWVDb3VudDsKKyAgICAgICAgICAgIGlmIChvYnRhaW5CdWZmZXIoJm1PdXRCdWZmZXIpID09IChzdGF0dXNfdClBdWRpb1RyYWNrOjpOT19NT1JFX0JVRkZFUlMpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgIHVpbnQzMl90IG91dEZyYW1lcyA9IHBJbkJ1ZmZlci0+ZnJhbWVDb3VudCA+IG1PdXRCdWZmZXIuZnJhbWVDb3VudCA/IG1PdXRCdWZmZXIuZnJhbWVDb3VudCA6IHBJbkJ1ZmZlci0+ZnJhbWVDb3VudDsKKyAgICAgICAgbWVtY3B5KG1PdXRCdWZmZXIucmF3LCBwSW5CdWZmZXItPnJhdywgb3V0RnJhbWVzICogY2hhbm5lbHMgKiBzaXplb2YoaW50MTZfdCkpOworICAgICAgICBtQ2Jsay0+c3RlcFVzZXIob3V0RnJhbWVzKTsKKyAgICAgICAgcEluQnVmZmVyLT5mcmFtZUNvdW50IC09IG91dEZyYW1lczsKKyAgICAgICAgcEluQnVmZmVyLT5pMTYgKz0gb3V0RnJhbWVzICogY2hhbm5lbHM7CisgICAgICAgIG1PdXRCdWZmZXIuZnJhbWVDb3VudCAtPSBvdXRGcmFtZXM7CisgICAgICAgIG1PdXRCdWZmZXIuaTE2ICs9IG91dEZyYW1lcyAqIGNoYW5uZWxzOyAgICAgICAgICAgIAorICAgICAgICAKKyAgICAgICAgaWYgKHBJbkJ1ZmZlci0+ZnJhbWVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICBpZiAobUJ1ZmZlclF1ZXVlLnNpemUoKSkgeworICAgICAgICAgICAgICAgIG1CdWZmZXJRdWV1ZS5yZW1vdmVBdCgwKTsKKyAgICAgICAgICAgICAgICBkZWxldGUgW10gcEluQnVmZmVyLT5tQnVmZmVyOworICAgICAgICAgICAgICAgIGRlbGV0ZSBwSW5CdWZmZXI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorIAorICAgIC8vIElmIHdlIGNvdWxkIG5vdCB3cml0ZSBhbGwgZnJhbWVzLCBhbGxvY2F0ZSBhIGJ1ZmZlciBhbmQgcXVldWUgaXQgZm9yIG5leHQgdGltZS4KKyAgICBpZiAoaW5CdWZmZXIuZnJhbWVDb3VudCkgeworICAgICAgICBpZiAobUJ1ZmZlclF1ZXVlLnNpemUoKSA8IGtNYXhPdXRwdXRUcmFja0J1ZmZlcnMpIHsKKyAgICAgICAgICAgIHBJbkJ1ZmZlciA9IG5ldyBCdWZmZXI7CisgICAgICAgICAgICBwSW5CdWZmZXItPm1CdWZmZXIgPSBuZXcgaW50MTZfdFtpbkJ1ZmZlci5mcmFtZUNvdW50ICogY2hhbm5lbHNdOworICAgICAgICAgICAgcEluQnVmZmVyLT5mcmFtZUNvdW50ID0gaW5CdWZmZXIuZnJhbWVDb3VudDsKKyAgICAgICAgICAgIHBJbkJ1ZmZlci0+aTE2ID0gcEluQnVmZmVyLT5tQnVmZmVyOworICAgICAgICAgICAgbWVtY3B5KHBJbkJ1ZmZlci0+cmF3LCBpbkJ1ZmZlci5yYXcsIGluQnVmZmVyLmZyYW1lQ291bnQgKiBjaGFubmVscyAqIHNpemVvZihpbnQxNl90KSk7CisgICAgICAgICAgICBtQnVmZmVyUXVldWUuYWRkKHBJbkJ1ZmZlcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dXKCJPdXRwdXRUcmFjazo6d3JpdGUoKSBubyBtb3JlIGJ1ZmZlcnMiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICAvLyBDYWxsaW5nIHdyaXRlKCkgd2l0aCBhIDAgbGVuZ3RoIGJ1ZmZlciwgbWVhbnMgdGhhdCBubyBtb3JlIGRhdGEgd2lsbCBiZSB3cml0dGVuOgorICAgIC8vIElmIG5vIG1vcmUgYnVmZmVycyBhcmUgcGVuZGluZywgZmlsbCBvdXRwdXQgdHJhY2sgYnVmZmVyIHRvIG1ha2Ugc3VyZSBpdCBpcyBzdGFydGVkIAorICAgIC8vIGJ5IG91dHB1dCBtaXhlci4KKyAgICBpZiAoZnJhbWVzID09IDAgJiYgbUJ1ZmZlclF1ZXVlLnNpemUoKSA9PSAwICYmIG1DYmxrLT51c2VyIDwgbUNibGstPmZyYW1lQ291bnQpIHsKKyAgICAgICAgZnJhbWVzID0gbUNibGstPmZyYW1lQ291bnQgLSBtQ2Jsay0+dXNlcjsKKyAgICAgICAgcEluQnVmZmVyID0gbmV3IEJ1ZmZlcjsKKyAgICAgICAgcEluQnVmZmVyLT5tQnVmZmVyID0gbmV3IGludDE2X3RbZnJhbWVzICogY2hhbm5lbHNdOworICAgICAgICBwSW5CdWZmZXItPmZyYW1lQ291bnQgPSBmcmFtZXM7CisgICAgICAgIHBJbkJ1ZmZlci0+aTE2ID0gcEluQnVmZmVyLT5tQnVmZmVyOworICAgICAgICBtZW1zZXQocEluQnVmZmVyLT5yYXcsIDAsIGZyYW1lcyAqIGNoYW5uZWxzICogc2l6ZW9mKGludDE2X3QpKTsKKyAgICAgICAgbUJ1ZmZlclF1ZXVlLmFkZChwSW5CdWZmZXIpOworICAgIH0KKworfQorCitzdGF0dXNfdCBBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpPdXRwdXRUcmFjazo6b2J0YWluQnVmZmVyKEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciogYnVmZmVyKQoreworICAgIGludCBhY3RpdmU7CisgICAgaW50IHRpbWVvdXQgPSAwOworICAgIHN0YXR1c190IHJlc3VsdDsKKyAgICBhdWRpb190cmFja19jYmxrX3QqIGNibGsgPSBtQ2JsazsKKyAgICB1aW50MzJfdCBmcmFtZXNSZXEgPSBidWZmZXItPmZyYW1lQ291bnQ7CisKKyAgICBMT0dWKCJPdXRwdXRUcmFjazo6b2J0YWluQnVmZmVyIHVzZXIgJWQsIHNlcnZlciAlZCIsIGNibGstPnVzZXIsIGNibGstPnNlcnZlcik7CisgICAgYnVmZmVyLT5mcmFtZUNvdW50ICA9IDA7CisgICAgCisgICAgdWludDMyX3QgZnJhbWVzQXZhaWwgPSBjYmxrLT5mcmFtZXNBdmFpbGFibGUoKTsKKworICAgIGlmIChmcmFtZXNBdmFpbCA9PSAwKSB7CisgICAgICAgIHJldHVybiBBdWRpb1RyYWNrOjpOT19NT1JFX0JVRkZFUlM7CisgICAgfQorCisgICAgaWYgKGZyYW1lc1JlcSA+IGZyYW1lc0F2YWlsKSB7CisgICAgICAgIGZyYW1lc1JlcSA9IGZyYW1lc0F2YWlsOworICAgIH0KKworICAgIHVpbnQzMl90IHUgPSBjYmxrLT51c2VyOworICAgIHVpbnQzMl90IGJ1ZmZlckVuZCA9IGNibGstPnVzZXJCYXNlICsgY2Jsay0+ZnJhbWVDb3VudDsKKworICAgIGlmICh1ICsgZnJhbWVzUmVxID4gYnVmZmVyRW5kKSB7CisgICAgICAgIGZyYW1lc1JlcSA9IGJ1ZmZlckVuZCAtIHU7CisgICAgfQorCisgICAgYnVmZmVyLT5mcmFtZUNvdW50ICA9IGZyYW1lc1JlcTsKKyAgICBidWZmZXItPnJhdyAgICAgICAgID0gKHZvaWQgKiljYmxrLT5idWZmZXIodSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpNaXhlclRocmVhZDo6T3V0cHV0VHJhY2s6OmNsZWFyQnVmZmVyUXVldWUoKQoreworICAgIHNpemVfdCBzaXplID0gbUJ1ZmZlclF1ZXVlLnNpemUoKTsKKyAgICBCdWZmZXIgKnBCdWZmZXI7CisgICAgCisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgcEJ1ZmZlciA9IG1CdWZmZXJRdWV1ZS5pdGVtQXQoaSk7CisgICAgICAgIGRlbGV0ZSBbXSBwQnVmZmVyLT5tQnVmZmVyOworICAgICAgICBkZWxldGUgcEJ1ZmZlcjsKKyAgICB9CisgICAgbUJ1ZmZlclF1ZXVlLmNsZWFyKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXVkaW9GbGluZ2VyOjpDbGllbnQ6OkNsaWVudChjb25zdCBzcDxBdWRpb0ZsaW5nZXI+JiBhdWRpb0ZsaW5nZXIsIHBpZF90IHBpZCkKKyAgICA6ICAgUmVmQmFzZSgpLAorICAgICAgICBtQXVkaW9GbGluZ2VyKGF1ZGlvRmxpbmdlciksCisgICAgICAgIG1NZW1vcnlEZWFsZXIobmV3IE1lbW9yeURlYWxlcigxMDI0KjEwMjQpKSwKKyAgICAgICAgbVBpZChwaWQpCit7CisgICAgLy8gMSBNQiBvZiBhZGRyZXNzIHNwYWNlIGlzIGdvb2QgZm9yIDMyIHRyYWNrcywgOCBidWZmZXJzIGVhY2gsIDQgS0IvYnVmZmVyCit9CisKK0F1ZGlvRmxpbmdlcjo6Q2xpZW50Ojp+Q2xpZW50KCkKK3sKKyAgICBtQXVkaW9GbGluZ2VyLT5yZW1vdmVDbGllbnQobVBpZCk7Cit9CisKK2NvbnN0IHNwPE1lbW9yeURlYWxlcj4mIEF1ZGlvRmxpbmdlcjo6Q2xpZW50OjpoZWFwKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbU1lbW9yeURlYWxlcjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBdWRpb0ZsaW5nZXI6OlRyYWNrSGFuZGxlOjpUcmFja0hhbmRsZShjb25zdCBzcDxBdWRpb0ZsaW5nZXI6Ok1peGVyVGhyZWFkOjpUcmFjaz4mIHRyYWNrKQorICAgIDogQm5BdWRpb1RyYWNrKCksCisgICAgICBtVHJhY2sodHJhY2spCit7Cit9CisKK0F1ZGlvRmxpbmdlcjo6VHJhY2tIYW5kbGU6On5UcmFja0hhbmRsZSgpIHsKKyAgICAvLyBqdXN0IHN0b3AgdGhlIHRyYWNrIG9uIGRlbGV0aW9uLCBhc3NvY2lhdGVkIHJlc291cmNlcworICAgIC8vIHdpbGwgYmUgZnJlZWQgZnJvbSB0aGUgbWFpbiB0aHJlYWQgb25jZSBhbGwgcGVuZGluZyBidWZmZXJzIGhhdmUKKyAgICAvLyBiZWVuIHBsYXllZC4gVW5sZXNzIGl0J3Mgbm90IGluIHRoZSBhY3RpdmUgdHJhY2sgbGlzdCwgaW4gd2hpY2gKKyAgICAvLyBjYXNlIHdlIGZyZWUgZXZlcnl0aGluZyBub3cuLi4KKyAgICBtVHJhY2stPmRlc3Ryb3koKTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpUcmFja0hhbmRsZTo6c3RhcnQoKSB7CisgICAgcmV0dXJuIG1UcmFjay0+c3RhcnQoKTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OlRyYWNrSGFuZGxlOjpzdG9wKCkgeworICAgIG1UcmFjay0+c3RvcCgpOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6VHJhY2tIYW5kbGU6OmZsdXNoKCkgeworICAgIG1UcmFjay0+Zmx1c2goKTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OlRyYWNrSGFuZGxlOjptdXRlKGJvb2wgZSkgeworICAgIG1UcmFjay0+bXV0ZShlKTsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OlRyYWNrSGFuZGxlOjpwYXVzZSgpIHsKKyAgICBtVHJhY2stPnBhdXNlKCk7Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpUcmFja0hhbmRsZTo6c2V0Vm9sdW1lKGZsb2F0IGxlZnQsIGZsb2F0IHJpZ2h0KSB7CisgICAgbVRyYWNrLT5zZXRWb2x1bWUobGVmdCwgcmlnaHQpOworfQorCitzcDxJTWVtb3J5PiBBdWRpb0ZsaW5nZXI6OlRyYWNrSGFuZGxlOjpnZXRDYmxrKCkgY29uc3QgeworICAgIHJldHVybiBtVHJhY2stPmdldENibGsoKTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpUcmFja0hhbmRsZTo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHJldHVybiBCbkF1ZGlvVHJhY2s6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzcDxJQXVkaW9SZWNvcmQ+IEF1ZGlvRmxpbmdlcjo6b3BlblJlY29yZCgKKyAgICAgICAgcGlkX3QgcGlkLAorICAgICAgICBpbnQgc3RyZWFtVHlwZSwKKyAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgIHVpbnQzMl90IGZsYWdzLAorICAgICAgICBzdGF0dXNfdCAqc3RhdHVzKQoreworICAgIHNwPEF1ZGlvUmVjb3JkVGhyZWFkPiB0aHJlYWQ7CisgICAgc3A8TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrPiByZWNvcmRUcmFjazsKKyAgICBzcDxSZWNvcmRIYW5kbGU+IHJlY29yZEhhbmRsZTsKKyAgICBzcDxDbGllbnQ+IGNsaWVudDsKKyAgICB3cDxDbGllbnQ+IHdjbGllbnQ7CisgICAgQXVkaW9TdHJlYW1JbiogaW5wdXQgPSAwOworICAgIGludCBpbkZyYW1lQ291bnQ7CisgICAgc2l6ZV90IGlucHV0QnVmZmVyU2l6ZTsKKyAgICBzdGF0dXNfdCBsU3RhdHVzOworCisgICAgLy8gY2hlY2sgY2FsbGluZyBwZXJtaXNzaW9ucworICAgIGlmICghcmVjb3JkaW5nQWxsb3dlZCgpKSB7CisgICAgICAgIGxTdGF0dXMgPSBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICAgICAgZ290byBFeGl0OworICAgIH0KKworICAgIGlmICh1aW50MzJfdChzdHJlYW1UeXBlKSA+PSBBdWRpb1JlY29yZDo6TlVNX1NUUkVBTV9UWVBFUykgeworICAgICAgICBMT0dFKCJpbnZhbGlkIHN0cmVhbSB0eXBlIik7CisgICAgICAgIGxTdGF0dXMgPSBCQURfVkFMVUU7CisgICAgICAgIGdvdG8gRXhpdDsKKyAgICB9CisKKyAgICBpZiAoc2FtcGxlUmF0ZSA+IE1BWF9TQU1QTEVfUkFURSkgeworICAgICAgICBMT0dFKCJTYW1wbGUgcmF0ZSBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgbFN0YXR1cyA9IEJBRF9WQUxVRTsKKyAgICAgICAgZ290byBFeGl0OworICAgIH0KKworICAgIGlmIChtQXVkaW9SZWNvcmRUaHJlYWQgPT0gMCkgeworICAgICAgICBMT0dFKCJBdWRpbyByZWNvcmQgdGhyZWFkIG5vdCBzdGFydGVkIik7CisgICAgICAgIGxTdGF0dXMgPSBOT19JTklUOworICAgICAgICBnb3RvIEV4aXQ7CisgICAgfQorCisKKyAgICAvLyBDaGVjayB0aGF0IGF1ZGlvIGlucHV0IHN0cmVhbSBhY2NlcHRzIHJlcXVlc3RlZCBhdWRpbyBwYXJhbWV0ZXJzIAorICAgIGlucHV0QnVmZmVyU2l6ZSA9IG1BdWRpb0hhcmR3YXJlLT5nZXRJbnB1dEJ1ZmZlclNpemUoc2FtcGxlUmF0ZSwgZm9ybWF0LCBjaGFubmVsQ291bnQpOworICAgIGlmIChpbnB1dEJ1ZmZlclNpemUgPT0gMCkgeworICAgICAgICBsU3RhdHVzID0gQkFEX1ZBTFVFOworICAgICAgICBMT0dFKCJCYWQgYXVkaW8gaW5wdXQgcGFyYW1ldGVyczogc2FtcGxpbmcgcmF0ZSAldSwgZm9ybWF0ICVkLCBjaGFubmVscyAlZCIsICBzYW1wbGVSYXRlLCBmb3JtYXQsIGNoYW5uZWxDb3VudCk7CisgICAgICAgIGdvdG8gRXhpdDsKKyAgICB9CisKKyAgICAvLyBhZGQgY2xpZW50IHRvIGxpc3QKKyAgICB7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgICAgIHdjbGllbnQgPSBtQ2xpZW50cy52YWx1ZUZvcihwaWQpOworICAgICAgICBpZiAod2NsaWVudCAhPSBOVUxMKSB7CisgICAgICAgICAgICBjbGllbnQgPSB3Y2xpZW50LnByb21vdGUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNsaWVudCA9IG5ldyBDbGllbnQodGhpcywgcGlkKTsKKyAgICAgICAgICAgIG1DbGllbnRzLmFkZChwaWQsIGNsaWVudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBmcmFtZUNvdW50IG11c3QgYmUgYSBtdWx0aXBsZSBvZiBpbnB1dCBidWZmZXIgc2l6ZQorICAgIGluRnJhbWVDb3VudCA9IGlucHV0QnVmZmVyU2l6ZS9jaGFubmVsQ291bnQvc2l6ZW9mKHNob3J0KTsKKyAgICBmcmFtZUNvdW50ID0gKChmcmFtZUNvdW50IC0gMSkvaW5GcmFtZUNvdW50ICsgMSkgKiBpbkZyYW1lQ291bnQ7CisKKyAgICAvLyBjcmVhdGUgbmV3IHJlY29yZCB0cmFjayBhbmQgcGFzcyB0byByZWNvcmQgdGhyZWFkCisgICAgcmVjb3JkVHJhY2sgPSBuZXcgTWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrKG1IYXJkd2FyZU1peGVyVGhyZWFkLCBjbGllbnQsIHN0cmVhbVR5cGUsIHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCwgY2hhbm5lbENvdW50LCBmcmFtZUNvdW50LCBmbGFncyk7CisgICAgaWYgKHJlY29yZFRyYWNrLT5nZXRDYmxrKCkgPT0gTlVMTCkgeworICAgICAgICByZWNvcmRUcmFjay5jbGVhcigpOworICAgICAgICBsU3RhdHVzID0gTk9fTUVNT1JZOworICAgICAgICBnb3RvIEV4aXQ7CisgICAgfQorCisgICAgLy8gcmV0dXJuIHRvIGhhbmRsZSB0byBjbGllbnQKKyAgICByZWNvcmRIYW5kbGUgPSBuZXcgUmVjb3JkSGFuZGxlKHJlY29yZFRyYWNrKTsKKyAgICBsU3RhdHVzID0gTk9fRVJST1I7CisKK0V4aXQ6CisgICAgaWYgKHN0YXR1cykgeworICAgICAgICAqc3RhdHVzID0gbFN0YXR1czsKKyAgICB9CisgICAgcmV0dXJuIHJlY29yZEhhbmRsZTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpzdGFydFJlY29yZChNaXhlclRocmVhZDo6UmVjb3JkVHJhY2sqIHJlY29yZFRyYWNrKSB7CisgICAgaWYgKG1BdWRpb1JlY29yZFRocmVhZCAhPSAwKSB7CisgICAgICAgIHJldHVybiBtQXVkaW9SZWNvcmRUaHJlYWQtPnN0YXJ0KHJlY29yZFRyYWNrKTsgICAgICAgIAorICAgIH0KKyAgICByZXR1cm4gTk9fSU5JVDsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OnN0b3BSZWNvcmQoTWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrKiByZWNvcmRUcmFjaykgeworICAgIGlmIChtQXVkaW9SZWNvcmRUaHJlYWQgIT0gMCkgeworICAgICAgICBtQXVkaW9SZWNvcmRUaHJlYWQtPnN0b3AocmVjb3JkVHJhY2spOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBdWRpb0ZsaW5nZXI6OlJlY29yZEhhbmRsZTo6UmVjb3JkSGFuZGxlKGNvbnN0IHNwPEF1ZGlvRmxpbmdlcjo6TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrPiYgcmVjb3JkVHJhY2spCisgICAgOiBCbkF1ZGlvUmVjb3JkKCksCisgICAgbVJlY29yZFRyYWNrKHJlY29yZFRyYWNrKQoreworfQorCitBdWRpb0ZsaW5nZXI6OlJlY29yZEhhbmRsZTo6flJlY29yZEhhbmRsZSgpIHsKKyAgICBzdG9wKCk7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6UmVjb3JkSGFuZGxlOjpzdGFydCgpIHsKKyAgICBMT0dWKCJSZWNvcmRIYW5kbGU6OnN0YXJ0KCkiKTsKKyAgICByZXR1cm4gbVJlY29yZFRyYWNrLT5zdGFydCgpOworfQorCit2b2lkIEF1ZGlvRmxpbmdlcjo6UmVjb3JkSGFuZGxlOjpzdG9wKCkgeworICAgIExPR1YoIlJlY29yZEhhbmRsZTo6c3RvcCgpIik7CisgICAgbVJlY29yZFRyYWNrLT5zdG9wKCk7Cit9CisKK3NwPElNZW1vcnk+IEF1ZGlvRmxpbmdlcjo6UmVjb3JkSGFuZGxlOjpnZXRDYmxrKCkgY29uc3QgeworICAgIHJldHVybiBtUmVjb3JkVHJhY2stPmdldENibGsoKTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpSZWNvcmRIYW5kbGU6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICByZXR1cm4gQm5BdWRpb1JlY29yZDo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvRmxpbmdlcjo6QXVkaW9SZWNvcmRUaHJlYWQ6OkF1ZGlvUmVjb3JkVGhyZWFkKEF1ZGlvSGFyZHdhcmVJbnRlcmZhY2UqIGF1ZGlvSGFyZHdhcmUpIDoKKyAgICBtQXVkaW9IYXJkd2FyZShhdWRpb0hhcmR3YXJlKSwKKyAgICBtQWN0aXZlKGZhbHNlKQoreworfQorCitBdWRpb0ZsaW5nZXI6OkF1ZGlvUmVjb3JkVGhyZWFkOjp+QXVkaW9SZWNvcmRUaHJlYWQoKQoreworfQorCitib29sIEF1ZGlvRmxpbmdlcjo6QXVkaW9SZWNvcmRUaHJlYWQ6OnRocmVhZExvb3AoKQoreworICAgIExPR1YoIkF1ZGlvUmVjb3JkVGhyZWFkOiBzdGFydCByZWNvcmQgbG9vcCIpOworICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciBidWZmZXI7CisgICAgaW50IGluQnVmZmVyU2l6ZSA9IDA7CisgICAgaW50IGluRnJhbWVDb3VudCA9IDA7CisgICAgQXVkaW9TdHJlYW1JbiogaW5wdXQgPSAwOworCisgICAgbUFjdGl2ZSA9IDA7CisgICAgCisgICAgLy8gc3RhcnQgcmVjb3JkaW5nCisgICAgd2hpbGUgKCFleGl0UGVuZGluZygpKSB7CisgICAgICAgIGlmICghbUFjdGl2ZSkgeworICAgICAgICAgICAgbUxvY2subG9jaygpOworICAgICAgICAgICAgaWYgKCFtQWN0aXZlICYmICFleGl0UGVuZGluZygpKSB7CisgICAgICAgICAgICAgICAgTE9HVigiQXVkaW9SZWNvcmRUaHJlYWQ6IGxvb3Agc3RvcHBpbmciKTsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXQpIHsKKyAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGlucHV0OworICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1SZWNvcmRUcmFjay5jbGVhcigpOworICAgICAgICAgICAgICAgIG1TdG9wcGVkLnNpZ25hbCgpOworCisgICAgICAgICAgICAgICAgbVdhaXRXb3JrQ1Yud2FpdChtTG9jayk7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBMT0dWKCJBdWRpb1JlY29yZFRocmVhZDogbG9vcCBzdGFydGluZyIpOworICAgICAgICAgICAgICAgIGlmIChtUmVjb3JkVHJhY2sgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IG1BdWRpb0hhcmR3YXJlLT5vcGVuSW5wdXRTdHJlYW0obVJlY29yZFRyYWNrLT5mb3JtYXQoKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtUmVjb3JkVHJhY2stPmNoYW5uZWxDb3VudCgpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1SZWNvcmRUcmFjay0+c2FtcGxlUmF0ZSgpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtU3RhcnRTdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQXVkaW9TeXN0ZW06OmF1ZGlvX2luX2Fjb3VzdGljcykobVJlY29yZFRyYWNrLT5tRmxhZ3MgPj4gMTYpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0ICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluQnVmZmVyU2l6ZSA9IGlucHV0LT5idWZmZXJTaXplKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpbkZyYW1lQ291bnQgPSBpbkJ1ZmZlclNpemUvaW5wdXQtPmZyYW1lU2l6ZSgpOyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgbVN0YXJ0U3RhdHVzID0gTk9fSU5JVDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG1TdGFydFN0YXR1cyAhPU5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgIExPR1coInJlY29yZCBzdGFydCBmYWlsZWQsIHN0YXR1cyAlZCIsIG1TdGFydFN0YXR1cyk7CisgICAgICAgICAgICAgICAgICAgIG1BY3RpdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgbVJlY29yZFRyYWNrLmNsZWFyKCk7ICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbVdhaXRXb3JrQ1Yuc2lnbmFsKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtTG9jay51bmxvY2soKTsKKyAgICAgICAgfSBlbHNlIGlmIChtUmVjb3JkVHJhY2sgIT0gMCkgeworCisgICAgICAgICAgICBidWZmZXIuZnJhbWVDb3VudCA9IGluRnJhbWVDb3VudDsKKyAgICAgICAgICAgIGlmIChMSUtFTFkobVJlY29yZFRyYWNrLT5nZXROZXh0QnVmZmVyKCZidWZmZXIpID09IE5PX0VSUk9SKSkgeworICAgICAgICAgICAgICAgIExPR1YoIkF1ZGlvUmVjb3JkVGhyZWFkIHJlYWQ6ICVkIGZyYW1lcyIsIGJ1ZmZlci5mcmFtZUNvdW50KTsKKyAgICAgICAgICAgICAgICBzc2l6ZV90IGJ5dGVzUmVhZCA9IGlucHV0LT5yZWFkKGJ1ZmZlci5yYXcsIGluQnVmZmVyU2l6ZSk7CisgICAgICAgICAgICAgICAgaWYgKGJ5dGVzUmVhZCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HRSgiRXJyb3IgcmVhZGluZyBhdWRpbyBpbnB1dCIpOworICAgICAgICAgICAgICAgICAgICBzbGVlcCgxKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbVJlY29yZFRyYWNrLT5yZWxlYXNlQnVmZmVyKCZidWZmZXIpOworICAgICAgICAgICAgICAgIG1SZWNvcmRUcmFjay0+b3ZlcmZsb3coKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gY2xpZW50IGlzbid0IHJldHJpZXZpbmcgYnVmZmVycyBmYXN0IGVub3VnaAorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKCFtUmVjb3JkVHJhY2stPnNldE92ZXJmbG93KCkpCisgICAgICAgICAgICAgICAgICAgIExPR1coIkF1ZGlvUmVjb3JkVGhyZWFkOiBidWZmZXIgb3ZlcmZsb3ciKTsKKyAgICAgICAgICAgICAgICAvLyBSZWxlYXNlIHRoZSBwcm9jZXNzb3IgZm9yIGEgd2hpbGUgYmVmb3JlIGFza2luZyBmb3IgYSBuZXcgYnVmZmVyLgorICAgICAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBnaXZlIHRoZSBhcHBsaWNhdGlvbiBtb3JlIGNoYW5jZSB0byByZWFkIGZyb20gdGhlIGJ1ZmZlciBhbmQKKyAgICAgICAgICAgICAgICAvLyBjbGVhciB0aGUgb3ZlcmZsb3cuCisgICAgICAgICAgICAgICAgdXNsZWVwKDUwMDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICBpZiAoaW5wdXQpIHsKKyAgICAgICAgZGVsZXRlIGlucHV0OworICAgIH0KKyAgICBtUmVjb3JkVHJhY2suY2xlYXIoKTsKKyAgICAKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXR1c190IEF1ZGlvRmxpbmdlcjo6QXVkaW9SZWNvcmRUaHJlYWQ6OnN0YXJ0KE1peGVyVGhyZWFkOjpSZWNvcmRUcmFjayogcmVjb3JkVHJhY2spCit7CisgICAgTE9HVigiQXVkaW9SZWNvcmRUaHJlYWQ6OnN0YXJ0Iik7CisgICAgQXV0b011dGV4IGxvY2soJm1Mb2NrKTsKKyAgICBtQWN0aXZlID0gdHJ1ZTsKKyAgICAvLyBJZiBzdGFydGluZyB0aGUgYWN0aXZlIHRyYWNrLCBqdXN0IHJlc2V0IG1BY3RpdmUgaW4gY2FzZSBhIHN0b3AKKyAgICAvLyB3YXMgcGVuZGluZyBhbmQgZXhpdAorICAgIGlmIChyZWNvcmRUcmFjayA9PSBtUmVjb3JkVHJhY2suZ2V0KCkpIHJldHVybiBOT19FUlJPUjsKKworICAgIGlmIChtUmVjb3JkVHJhY2sgIT0gMCkgcmV0dXJuIC1FQlVTWTsKKworICAgIG1SZWNvcmRUcmFjayA9IHJlY29yZFRyYWNrOworCisgICAgLy8gc2lnbmFsIHRocmVhZCB0byBzdGFydAorICAgIExPR1YoIlNpZ25hbCByZWNvcmQgdGhyZWFkIik7CisgICAgbVdhaXRXb3JrQ1Yuc2lnbmFsKCk7CisgICAgbVdhaXRXb3JrQ1Yud2FpdChtTG9jayk7CisgICAgTE9HVigiUmVjb3JkIHN0YXJ0ZWQsIHN0YXR1cyAlZCIsIG1TdGFydFN0YXR1cyk7CisgICAgcmV0dXJuIG1TdGFydFN0YXR1czsKK30KKwordm9pZCBBdWRpb0ZsaW5nZXI6OkF1ZGlvUmVjb3JkVGhyZWFkOjpzdG9wKE1peGVyVGhyZWFkOjpSZWNvcmRUcmFjayogcmVjb3JkVHJhY2spIHsKKyAgICBMT0dWKCJBdWRpb1JlY29yZFRocmVhZDo6c3RvcCIpOworICAgIEF1dG9NdXRleCBsb2NrKCZtTG9jayk7CisgICAgaWYgKG1BY3RpdmUgJiYgKHJlY29yZFRyYWNrID09IG1SZWNvcmRUcmFjay5nZXQoKSkpIHsKKyAgICAgICAgbUFjdGl2ZSA9IGZhbHNlOworICAgICAgICBtU3RvcHBlZC53YWl0KG1Mb2NrKTsKKyAgICB9Cit9CisKK3ZvaWQgQXVkaW9GbGluZ2VyOjpBdWRpb1JlY29yZFRocmVhZDo6ZXhpdCgpCit7CisgICAgTE9HVigiQXVkaW9SZWNvcmRUaHJlYWQ6OmV4aXQiKTsKKyAgICB7CisgICAgICAgIEF1dG9NdXRleCBsb2NrKCZtTG9jayk7CisgICAgICAgIHJlcXVlc3RFeGl0KCk7CisgICAgICAgIG1XYWl0V29ya0NWLnNpZ25hbCgpOworICAgIH0KKyAgICByZXF1ZXN0RXhpdEFuZFdhaXQoKTsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpBdWRpb1JlY29yZFRocmVhZDo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgcGlkX3QgcGlkID0gMDsKKworICAgIGlmIChtUmVjb3JkVHJhY2sgIT0gMCAmJiBtUmVjb3JkVHJhY2stPm1DbGllbnQgIT0gMCkgeworICAgICAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJSZWNvcmQgY2xpZW50IHBpZDogJWRcbiIsIG1SZWNvcmRUcmFjay0+bUNsaWVudC0+cGlkKCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiTm8gcmVjb3JkIGNsaWVudFxuIik7CisgICAgfQorICAgIHdyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9GbGluZ2VyOjpvblRyYW5zYWN0KAorICAgICAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHJldHVybiBCbkF1ZGlvRmxpbmdlcjo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit2b2lkIEF1ZGlvRmxpbmdlcjo6aW5zdGFudGlhdGUoKSB7CisgICAgZGVmYXVsdFNlcnZpY2VNYW5hZ2VyKCktPmFkZFNlcnZpY2UoCisgICAgICAgICAgICBTdHJpbmcxNigibWVkaWEuYXVkaW9fZmxpbmdlciIpLCBuZXcgQXVkaW9GbGluZ2VyKCkpOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9GbGluZ2VyLmggYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0ZsaW5nZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2YwNjRiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9GbGluZ2VyLmgKQEAgLTAsMCArMSw2MzcgQEAKKy8qIC8vZGV2aWNlL2luY2x1ZGUvc2VydmVyL0F1ZGlvRmxpbmdlci9BdWRpb0ZsaW5nZXIuaAorKioKKyoqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfQVVESU9fRkxJTkdFUl9ICisjZGVmaW5lIEFORFJPSURfQVVESU9fRkxJTkdFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPG1lZGlhL0lBdWRpb0ZsaW5nZXIuaD4KKyNpbmNsdWRlIDxtZWRpYS9JQXVkaW9GbGluZ2VyQ2xpZW50Lmg+CisjaW5jbHVkZSA8bWVkaWEvSUF1ZGlvVHJhY2suaD4KKyNpbmNsdWRlIDxtZWRpYS9JQXVkaW9SZWNvcmQuaD4KKyNpbmNsdWRlIDxtZWRpYS9BdWRpb1RyYWNrLmg+CisKKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9Tb3J0ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9WZWN0b3IuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlX2xlZ2FjeS9BdWRpb0hhcmR3YXJlSW50ZXJmYWNlLmg+CisKKyNpbmNsdWRlICJBdWRpb0J1ZmZlclByb3ZpZGVyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgYXVkaW9fdHJhY2tfY2Jsa190OworY2xhc3MgQXVkaW9NaXhlcjsKK2NsYXNzIEF1ZGlvQnVmZmVyOworCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBMSUtFTFkoIGV4cCApICAgICAgIChfX2J1aWx0aW5fZXhwZWN0KCAoZXhwKSAhPSAwLCB0cnVlICApKQorI2RlZmluZSBVTkxJS0VMWSggZXhwICkgICAgIChfX2J1aWx0aW5fZXhwZWN0KCAoZXhwKSAhPSAwLCBmYWxzZSApKQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGNvbnN0IG5zZWNzX3Qga1N0YW5kYnlUaW1lSW5Oc2VjcyA9IHNlY29uZHMoMyk7CisKK2NsYXNzIEF1ZGlvRmxpbmdlciA6IHB1YmxpYyBCbkF1ZGlvRmxpbmdlciwgcHVibGljIElCaW5kZXI6OkRlYXRoUmVjaXBpZW50IAoreworcHVibGljOgorICAgIHN0YXRpYyB2b2lkIGluc3RhbnRpYXRlKCk7CisKKyAgICB2aXJ0dWFsICAgICBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICAvLyBJQXVkaW9GbGluZ2VyIGludGVyZmFjZQorICAgIHZpcnR1YWwgc3A8SUF1ZGlvVHJhY2s+IGNyZWF0ZVRyYWNrKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWRfdCBwaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZnJhbWVDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElNZW1vcnk+JiBzaGFyZWRCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICpzdGF0dXMpOworCisgICAgdmlydHVhbCAgICAgdWludDMyX3QgICAgc2FtcGxlUmF0ZShpbnQgb3V0cHV0KSBjb25zdDsKKyAgICB2aXJ0dWFsICAgICBpbnQgICAgICAgICBjaGFubmVsQ291bnQoaW50IG91dHB1dCkgY29uc3Q7CisgICAgdmlydHVhbCAgICAgaW50ICAgICAgICAgZm9ybWF0KGludCBvdXRwdXQpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIHNpemVfdCAgICAgIGZyYW1lQ291bnQoaW50IG91dHB1dCkgY29uc3Q7CisgICAgdmlydHVhbCAgICAgdWludDMyX3QgICAgbGF0ZW5jeShpbnQgb3V0cHV0KSBjb25zdDsKKworICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldE1hc3RlclZvbHVtZShmbG9hdCB2YWx1ZSk7CisgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgc2V0TWFzdGVyTXV0ZShib29sIG11dGVkKTsKKworICAgIHZpcnR1YWwgICAgIGZsb2F0ICAgICAgIG1hc3RlclZvbHVtZSgpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIGJvb2wgICAgICAgIG1hc3Rlck11dGUoKSBjb25zdDsKKworICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldFN0cmVhbVZvbHVtZShpbnQgc3RyZWFtLCBmbG9hdCB2YWx1ZSk7CisgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgc2V0U3RyZWFtTXV0ZShpbnQgc3RyZWFtLCBib29sIG11dGVkKTsKKworICAgIHZpcnR1YWwgICAgIGZsb2F0ICAgICAgIHN0cmVhbVZvbHVtZShpbnQgc3RyZWFtKSBjb25zdDsKKyAgICB2aXJ0dWFsICAgICBib29sICAgICAgICBzdHJlYW1NdXRlKGludCBzdHJlYW0pIGNvbnN0OworCisgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgc2V0Um91dGluZyhpbnQgbW9kZSwgdWludDMyX3Qgcm91dGVzLCB1aW50MzJfdCBtYXNrKTsKKyAgICB2aXJ0dWFsICAgICB1aW50MzJfdCAgICBnZXRSb3V0aW5nKGludCBtb2RlKSBjb25zdDsKKworICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldE1vZGUoaW50IG1vZGUpOworICAgIHZpcnR1YWwgICAgIGludCAgICAgICAgIGdldE1vZGUoKSBjb25zdDsKKworICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldE1pY011dGUoYm9vbCBzdGF0ZSk7CisgICAgdmlydHVhbCAgICAgYm9vbCAgICAgICAgZ2V0TWljTXV0ZSgpIGNvbnN0OworCisgICAgdmlydHVhbCAgICAgYm9vbCAgICAgICAgaXNNdXNpY0FjdGl2ZSgpIGNvbnN0OworCisgICAgdmlydHVhbCAgICAgYm9vbCAgICAgICAgaXNBMmRwRW5hYmxlZCgpIGNvbnN0OworCisgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgc2V0UGFyYW1ldGVyKGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogdmFsdWUpOworCisgICAgdmlydHVhbCAgICAgdm9pZCAgICAgICAgcmVnaXN0ZXJDbGllbnQoY29uc3Qgc3A8SUF1ZGlvRmxpbmdlckNsaWVudD4mIGNsaWVudCk7CisgICAgCisgICAgdmlydHVhbCAgICAgc2l6ZV90ICAgICAgZ2V0SW5wdXRCdWZmZXJTaXplKHVpbnQzMl90IHNhbXBsZVJhdGUsIGludCBmb3JtYXQsIGludCBjaGFubmVsQ291bnQpOworICAgIAorICAgIHZpcnR1YWwgICAgIHZvaWQgICAgICAgIHdha2VVcCgpOworICAgIAorICAgIC8vIElCaW5kZXI6OkRlYXRoUmVjaXBpZW50CisgICAgdmlydHVhbCAgICAgdm9pZCAgICAgICAgYmluZGVyRGllZChjb25zdCB3cDxJQmluZGVyPiYgd2hvKTsKKworICAgIGVudW0gaGFyZHdhcmVfY2FsbF9zdGF0ZSB7CisgICAgICAgIEFVRElPX0hXX0lETEUgPSAwLAorICAgICAgICBBVURJT19IV19JTklULAorICAgICAgICBBVURJT19IV19PVVRQVVRfT1BFTiwKKyAgICAgICAgQVVESU9fSFdfT1VUUFVUX0NMT1NFLAorICAgICAgICBBVURJT19IV19JTlBVVF9PUEVOLAorICAgICAgICBBVURJT19IV19JTlBVVF9DTE9TRSwKKyAgICAgICAgQVVESU9fSFdfU1RBTkRCWSwKKyAgICAgICAgQVVESU9fSFdfU0VUX01BU1RFUl9WT0xVTUUsCisgICAgICAgIEFVRElPX0hXX0dFVF9ST1VUSU5HLAorICAgICAgICBBVURJT19IV19TRVRfUk9VVElORywKKyAgICAgICAgQVVESU9fSFdfR0VUX01PREUsCisgICAgICAgIEFVRElPX0hXX1NFVF9NT0RFLAorICAgICAgICBBVURJT19IV19HRVRfTUlDX01VVEUsCisgICAgICAgIEFVRElPX0hXX1NFVF9NSUNfTVVURSwKKyAgICAgICAgQVVESU9fU0VUX1ZPSUNFX1ZPTFVNRSwKKyAgICAgICAgQVVESU9fU0VUX1BBUkFNRVRFUiwKKyAgICB9OworCisgICAgLy8gcmVjb3JkIGludGVyZmFjZQorICAgIHZpcnR1YWwgc3A8SUF1ZGlvUmVjb3JkPiBvcGVuUmVjb3JkKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWRfdCBwaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZnJhbWVDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICpzdGF0dXMpOworCisgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgb25UcmFuc2FjdCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUGFyY2VsJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncyk7CisKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9GbGluZ2VyKCk7CisgICAgdmlydHVhbCAgICAgICAgICAgICAgICAgfkF1ZGlvRmxpbmdlcigpOworICAgIAorICAgIHZvaWQgICAgICAgICAgICAgICAgICAgIHNldE91dHB1dChpbnQgb3V0cHV0VHlwZSk7CisgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgZG9TZXRPdXRwdXQoaW50IG91dHB1dFR5cGUpOworCisjaWZkZWYgV0lUSF9BMkRQCisgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgc2V0QTJkcEVuYWJsZWQoYm9vbCBlbmFibGUpOworI2VuZGlmCisgICAgc3RhdGljIGJvb2wgICAgICAgICAgICAgc3RyZWFtRm9yY2VkVG9TcGVha2VyKGludCBzdHJlYW1UeXBlKTsKKyAgICAKKyAgICAvLyBNYW5hZ2VtZW50IG9mIGZvcmNlZCByb3V0ZSB0byBzcGVha2VyIGZvciBjZXJ0YWluIHRyYWNrIHR5cGVzLgorICAgIGVudW0gZm9yY2Vfc3BlYWtlcl9jb21tYW5kIHsKKyAgICAgICAgQUNUSVZFX1RSQUNLX0FEREVEID0gMCwKKyAgICAgICAgQUNUSVZFX1RSQUNLX1JFTU9WRUQsCisgICAgICAgIENIRUNLX1JPVVRFX1JFU1RPUkVfVElNRSwKKyAgICAgICAgRk9SQ0VfUk9VVEVfUkVTVE9SRQorICAgIH07CisgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgaGFuZGxlRm9yY2VkU3BlYWtlclJvdXRlKGludCBjb21tYW5kKTsKKworICAgIC8vIEludGVybmFsIGR1bXAgdXRpbGl0ZXMuCisgICAgc3RhdHVzX3QgZHVtcFBlcm1pc3Npb25EZW5pYWwoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKyAgICBzdGF0dXNfdCBkdW1wQ2xpZW50cyhpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpOworICAgIHN0YXR1c190IGR1bXBJbnRlcm5hbHMoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKworICAgIC8vIC0tLSBDbGllbnQgLS0tCisgICAgY2xhc3MgQ2xpZW50IDogcHVibGljIFJlZkJhc2UgeworICAgIHB1YmxpYzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQoY29uc3Qgc3A8QXVkaW9GbGluZ2VyPiYgYXVkaW9GbGluZ2VyLCBwaWRfdCBwaWQpOworICAgICAgICB2aXJ0dWFsICAgICAgICAgICAgIH5DbGllbnQoKTsKKyAgICAgICAgY29uc3Qgc3A8TWVtb3J5RGVhbGVyPiYgICAgIGhlYXAoKSBjb25zdDsKKyAgICAgICAgcGlkX3QgICAgICAgICAgICAgICBwaWQoKSBjb25zdCB7IHJldHVybiBtUGlkOyB9CisgICAgcHJpdmF0ZToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQoY29uc3QgQ2xpZW50Jik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpZW50JiBvcGVyYXRvciA9IChjb25zdCBDbGllbnQmKTsKKyAgICAgICAgc3A8QXVkaW9GbGluZ2VyPiAgICBtQXVkaW9GbGluZ2VyOworICAgICAgICBzcDxNZW1vcnlEZWFsZXI+ICAgIG1NZW1vcnlEZWFsZXI7CisgICAgICAgIHBpZF90ICAgICAgICAgICAgICAgbVBpZDsKKyAgICB9OworCisKKyAgICBjbGFzcyBUcmFja0hhbmRsZTsKKyAgICBjbGFzcyBSZWNvcmRIYW5kbGU7CisgICAgY2xhc3MgQXVkaW9SZWNvcmRUaHJlYWQ7CisKKyAgICAKKyAgICAvLyAtLS0gTWl4ZXJUaHJlYWQgLS0tCisgICAgY2xhc3MgTWl4ZXJUaHJlYWQgOiBwdWJsaWMgVGhyZWFkIHsKKyAgICBwdWJsaWM6CisgICAgICAgIAorICAgICAgICAvLyAtLS0gVHJhY2sgLS0tCisKKyAgICAgICAgLy8gYmFzZSBmb3IgcmVjb3JkIGFuZCBwbGF5YmFjaworICAgICAgICBjbGFzcyBUcmFja0Jhc2UgOiBwdWJsaWMgQXVkaW9CdWZmZXJQcm92aWRlciwgcHVibGljIFJlZkJhc2UgeworCisgICAgICAgIHB1YmxpYzoKKyAgICAgICAgICAgIGVudW0gdHJhY2tfc3RhdGUgeworICAgICAgICAgICAgICAgIElETEUsCisgICAgICAgICAgICAgICAgVEVSTUlOQVRFRCwKKyAgICAgICAgICAgICAgICBTVE9QUEVELAorICAgICAgICAgICAgICAgIFJFU1VNSU5HLAorICAgICAgICAgICAgICAgIEFDVElWRSwKKyAgICAgICAgICAgICAgICBQQVVTSU5HLAorICAgICAgICAgICAgICAgIFBBVVNFRAorICAgICAgICAgICAgfTsKKworICAgICAgICAgICAgZW51bSB0cmFja19mbGFncyB7CisgICAgICAgICAgICAgICAgU1RFUFNFUlZFUl9GQUlMRUQgPSAweDAxLCAvLyAgU3RlcFNlcnZlciBjb3VsZCBub3QgYWNxdWlyZSBjYmxrLT5sb2NrIG11dGV4CisgICAgICAgICAgICAgICAgU1lTVEVNX0ZMQUdTX01BU0sgPSAweDAwMDBmZmZmVUwsCisgICAgICAgICAgICAgICAgLy8gVGhlIHVwcGVyIDE2IGJpdHMgYXJlIHVzZWQgZm9yIHRyYWNrLXNwZWNpZmljIGZsYWdzLgorICAgICAgICAgICAgfTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFja0Jhc2UoY29uc3Qgc3A8TWl4ZXJUaHJlYWQ+JiBtaXhlclRocmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzcDxDbGllbnQ+JiBjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0cmVhbVR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFubmVsQ291bnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZyYW1lQ291bnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8SU1lbW9yeT4mIHNoYXJlZEJ1ZmZlcik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5UcmFja0Jhc2UoKTsKKworICAgICAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFydCgpID0gMDsKKyAgICAgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcCgpID0gMDsKKyAgICAgICAgICAgICAgICAgICAgc3A8SU1lbW9yeT4gZ2V0Q2JsaygpIGNvbnN0OworCisgICAgICAgIHByb3RlY3RlZDoKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBNaXhlclRocmVhZDsKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBSZWNvcmRIYW5kbGU7CisgICAgICAgICAgICBmcmllbmQgY2xhc3MgQXVkaW9SZWNvcmRUaHJlYWQ7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhY2tCYXNlKGNvbnN0IFRyYWNrQmFzZSYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFja0Jhc2UmIG9wZXJhdG9yID0gKGNvbnN0IFRyYWNrQmFzZSYpOworCisgICAgICAgICAgICB2aXJ0dWFsIHN0YXR1c190IGdldE5leHRCdWZmZXIoQXVkaW9CdWZmZXJQcm92aWRlcjo6QnVmZmVyKiBidWZmZXIpID0gMDsKKyAgICAgICAgICAgIHZpcnR1YWwgdm9pZCByZWxlYXNlQnVmZmVyKEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciogYnVmZmVyKTsKKworICAgICAgICAgICAgYXVkaW9fdHJhY2tfY2Jsa190KiBjYmxrKCkgY29uc3QgeworICAgICAgICAgICAgICAgIHJldHVybiBtQ2JsazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHR5cGUoKSBjb25zdCB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1TdHJlYW1UeXBlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgZm9ybWF0KCkgY29uc3QgeworICAgICAgICAgICAgICAgIHJldHVybiBtRm9ybWF0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50KCkgY29uc3QgOworCisgICAgICAgICAgICBpbnQgc2FtcGxlUmF0ZSgpIGNvbnN0OworCisgICAgICAgICAgICB2b2lkKiBnZXRCdWZmZXIodWludDMyX3Qgb2Zmc2V0LCB1aW50MzJfdCBmcmFtZXMpIGNvbnN0OworCisgICAgICAgICAgICBpbnQgbmFtZSgpIGNvbnN0IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbU5hbWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2wgaXNTdG9wcGVkKCkgY29uc3QgeworICAgICAgICAgICAgICAgIHJldHVybiBtU3RhdGUgPT0gU1RPUFBFRDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYm9vbCBpc1Rlcm1pbmF0ZWQoKSBjb25zdCB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1TdGF0ZSA9PSBURVJNSU5BVEVEOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib29sIHN0ZXAoKTsKKyAgICAgICAgICAgIHZvaWQgcmVzZXQoKTsKKworICAgICAgICAgICAgc3A8TWl4ZXJUaHJlYWQ+ICAgICBtTWl4ZXJUaHJlYWQ7CisgICAgICAgICAgICBzcDxDbGllbnQ+ICAgICAgICAgIG1DbGllbnQ7CisgICAgICAgICAgICBzcDxJTWVtb3J5PiAgICAgICAgIG1DYmxrTWVtb3J5OworICAgICAgICAgICAgYXVkaW9fdHJhY2tfY2Jsa190KiBtQ2JsazsKKyAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgbVN0cmVhbVR5cGU7CisgICAgICAgICAgICB2b2lkKiAgICAgICAgICAgICAgIG1CdWZmZXI7CisgICAgICAgICAgICB2b2lkKiAgICAgICAgICAgICAgIG1CdWZmZXJFbmQ7CisgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgICAgIG1GcmFtZUNvdW50OworICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICBtTmFtZTsKKyAgICAgICAgICAgIC8vIHdlIGRvbid0IHJlYWxseSBuZWVkIGEgbG9jayBmb3IgdGhlc2UKKyAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgbVN0YXRlOworICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICBtQ2xpZW50VGlkOworICAgICAgICAgICAgdWludDhfdCAgICAgICAgICAgICBtRm9ybWF0OworICAgICAgICAgICAgdWludDMyX3QgICAgICAgICAgICBtRmxhZ3M7CisgICAgICAgIH07CisKKyAgICAgICAgLy8gcGxheWJhY2sgdHJhY2sKKyAgICAgICAgY2xhc3MgVHJhY2sgOiBwdWJsaWMgVHJhY2tCYXNlIHsKKyAgICAgICAgcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFjayggIGNvbnN0IHNwPE1peGVyVGhyZWFkPiYgbWl4ZXJUaHJlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8Q2xpZW50PiYgY2xpZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcmFtZUNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPElNZW1vcnk+JiBzaGFyZWRCdWZmZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+VHJhY2soKTsKKworICAgICAgICAgICAgICAgICAgICB2b2lkICAgICAgICBkdW1wKGNoYXIqIGJ1ZmZlciwgc2l6ZV90IHNpemUpOworICAgICAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFydCgpOworICAgICAgICAgICAgdmlydHVhbCB2b2lkICAgICAgICBzdG9wKCk7CisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHBhdXNlKCk7CisKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgZmx1c2goKTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgZGVzdHJveSgpOworICAgICAgICAgICAgICAgICAgICB2b2lkICAgICAgICBtdXRlKGJvb2wpOworICAgICAgICAgICAgICAgICAgICB2b2lkICAgICAgICBzZXRWb2x1bWUoZmxvYXQgbGVmdCwgZmxvYXQgcmlnaHQpOworCisgICAgICAgIHByb3RlY3RlZDoKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBNaXhlclRocmVhZDsKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBBdWRpb0ZsaW5nZXI7CisgICAgICAgICAgICBmcmllbmQgY2xhc3MgQXVkaW9GbGluZ2VyOjpUcmFja0hhbmRsZTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFjayhjb25zdCBUcmFjayYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFjayYgb3BlcmF0b3IgPSAoY29uc3QgVHJhY2smKTsKKworICAgICAgICAgICAgdmlydHVhbCBzdGF0dXNfdCBnZXROZXh0QnVmZmVyKEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciogYnVmZmVyKTsKKworICAgICAgICAgICAgYm9vbCBpc011dGVkKCkgY29uc3QgeworICAgICAgICAgICAgICAgIHJldHVybiAobU11dGUgfHwgbU1peGVyVGhyZWFkLT5tU3RyZWFtVHlwZXNbbVN0cmVhbVR5cGVdLm11dGUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib29sIGlzUGF1c2luZygpIGNvbnN0IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbVN0YXRlID09IFBBVVNJTkc7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2wgaXNQYXVzZWQoKSBjb25zdCB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1TdGF0ZSA9PSBQQVVTRUQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2wgaXNSZWFkeSgpIGNvbnN0OworCisgICAgICAgICAgICB2b2lkIHNldFBhdXNlZCgpIHsgbVN0YXRlID0gUEFVU0VEOyB9CisgICAgICAgICAgICB2b2lkIHJlc2V0KCk7CisKKyAgICAgICAgICAgIC8vIHdlIGRvbid0IHJlYWxseSBuZWVkIGEgbG9jayBmb3IgdGhlc2UKKyAgICAgICAgICAgIGZsb2F0ICAgICAgICAgICAgICAgbVZvbHVtZVsyXTsKKyAgICAgICAgICAgIHZvbGF0aWxlIGJvb2wgICAgICAgbU11dGU7CisgICAgICAgICAgICAvLyBGSUxMRUQgc3RhdGUgaXMgdXNlZCBmb3Igc3VwcHJlc3Npbmcgdm9sdW1lIHJhbXAgYXQgYmVnaW4gb2YgcGxheWluZworICAgICAgICAgICAgZW51bSB7RlNfRklMTElORywgRlNfRklMTEVELCBGU19BQ1RJVkV9OworICAgICAgICAgICAgbXV0YWJsZSB1aW50OF90ICAgICBtRmlsbGluZ1VwU3RhdHVzOworICAgICAgICAgICAgaW50OF90ICAgICAgICAgICAgICBtUmV0cnlDb3VudDsKKyAgICAgICAgICAgIHNwPElNZW1vcnk+ICAgICAgICAgbVNoYXJlZEJ1ZmZlcjsKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgbVJlc2V0RG9uZTsKKyAgICAgICAgfTsgIC8vIGVuZCBvZiBUcmFjaworCisgICAgICAgIC8vIHJlY29yZCB0cmFjaworICAgICAgICBjbGFzcyBSZWNvcmRUcmFjayA6IHB1YmxpYyBUcmFja0Jhc2UgeworICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlY29yZFRyYWNrKGNvbnN0IHNwPE1peGVyVGhyZWFkPiYgbWl4ZXJUaHJlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8Q2xpZW50PiYgY2xpZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHJlYW1UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcmFtZUNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflJlY29yZFRyYWNrKCk7CisKKyAgICAgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc3RhcnQoKTsKKyAgICAgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcCgpOworCisgICAgICAgICAgICAgICAgICAgIGJvb2wgICAgICAgIG92ZXJmbG93KCkgeyBib29sIHRtcCA9IG1PdmVyZmxvdzsgbU92ZXJmbG93ID0gZmFsc2U7IHJldHVybiB0bXA7IH0KKyAgICAgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgc2V0T3ZlcmZsb3coKSB7IGJvb2wgdG1wID0gbU92ZXJmbG93OyBtT3ZlcmZsb3cgPSB0cnVlOyByZXR1cm4gdG1wOyB9CisKKyAgICAgICAgcHJpdmF0ZToKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBBdWRpb0ZsaW5nZXI7CisgICAgICAgICAgICBmcmllbmQgY2xhc3MgQXVkaW9GbGluZ2VyOjpSZWNvcmRIYW5kbGU7CisgICAgICAgICAgICBmcmllbmQgY2xhc3MgQXVkaW9GbGluZ2VyOjpBdWRpb1JlY29yZFRocmVhZDsKKyAgICAgICAgICAgIGZyaWVuZCBjbGFzcyBNaXhlclRocmVhZDsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWNvcmRUcmFjayhjb25zdCBUcmFjayYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWNvcmRUcmFjayYgb3BlcmF0b3IgPSAoY29uc3QgVHJhY2smKTsKKworICAgICAgICAgICAgdmlydHVhbCBzdGF0dXNfdCBnZXROZXh0QnVmZmVyKEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciogYnVmZmVyKTsKKworICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICBtT3ZlcmZsb3c7CisgICAgICAgIH07CisKKyAgICAgICAgLy8gcGxheWJhY2sgdHJhY2sKKyAgICAgICAgY2xhc3MgT3V0cHV0VHJhY2sgOiBwdWJsaWMgVHJhY2sgeworICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGNsYXNzIEJ1ZmZlcjogcHVibGljIEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciB7CisgICAgICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgaW50MTZfdCAqbUJ1ZmZlcjsKKyAgICAgICAgICAgIH07CisgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0VHJhY2soICBjb25zdCBzcDxNaXhlclRocmVhZD4mIG1peGVyVGhyZWFkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcmFtZUNvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfk91dHB1dFRyYWNrKCk7CisKKyAgICAgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc3RhcnQoKTsKKyAgICAgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcCgpOworICAgICAgICAgICAgICAgICAgICB2b2lkICAgICAgICB3cml0ZShpbnQxNl90KiBkYXRhLCB1aW50MzJfdCBmcmFtZXMpOworICAgICAgICAgICAgICAgICAgICBib29sICAgICAgICBidWZmZXJRdWV1ZUVtcHR5KCkgeyByZXR1cm4gKG1CdWZmZXJRdWV1ZS5zaXplKCkgPT0gMCkgPyB0cnVlIDogZmFsc2U7IH0KKworICAgICAgICBwcml2YXRlOgorCisgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgIG9idGFpbkJ1ZmZlcihBdWRpb0J1ZmZlclByb3ZpZGVyOjpCdWZmZXIqIGJ1ZmZlcik7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGNsZWFyQnVmZmVyUXVldWUoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3A8TWl4ZXJUaHJlYWQ+ICAgICAgICAgICAgIG1PdXRwdXRNaXhlclRocmVhZDsKKyAgICAgICAgICAgIFZlY3RvciA8IEJ1ZmZlciogPiAgICAgICAgICBtQnVmZmVyUXVldWU7CisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyOjpCdWZmZXIgbU91dEJ1ZmZlcjsKKyAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgICAgICBtRnJhbWVzV3JpdHRlbjsKKyAgICAgICAgICAgIAorICAgICAgICAgfTsgIC8vIGVuZCBvZiBPdXRwdXRUcmFjaworCisgICAgICAgIE1peGVyVGhyZWFkIChjb25zdCBzcDxBdWRpb0ZsaW5nZXI+JiBhdWRpb0ZsaW5nZXIsIEF1ZGlvU3RyZWFtT3V0KiBvdXRwdXQsIGludCBvdXRwdXRUeXBlKTsKKyAgICAgICAgdmlydHVhbCAgICAgICAgICAgICB+TWl4ZXJUaHJlYWQoKTsKKworICAgICAgICB2aXJ0dWFsICAgICBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICAgICAgLy8gVGhyZWFkIHZpcnR1YWxzCisgICAgICAgIHZpcnR1YWwgICAgIGJvb2wgICAgICAgIHRocmVhZExvb3AoKTsKKyAgICAgICAgdmlydHVhbCAgICAgc3RhdHVzX3QgICAgcmVhZHlUb1J1bigpOworICAgICAgICB2aXJ0dWFsICAgICB2b2lkICAgICAgICBvbkZpcnN0UmVmKCk7CisKKyAgICAgICAgdmlydHVhbCAgICAgdWludDMyX3QgICAgc2FtcGxlUmF0ZSgpIGNvbnN0OworICAgICAgICB2aXJ0dWFsICAgICBpbnQgICAgICAgICBjaGFubmVsQ291bnQoKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCAgICAgaW50ICAgICAgICAgZm9ybWF0KCkgY29uc3Q7CisgICAgICAgIHZpcnR1YWwgICAgIHNpemVfdCAgICAgIGZyYW1lQ291bnQoKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCAgICAgdWludDMyX3QgICAgbGF0ZW5jeSgpIGNvbnN0OworCisgICAgICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldE1hc3RlclZvbHVtZShmbG9hdCB2YWx1ZSk7CisgICAgICAgIHZpcnR1YWwgICAgIHN0YXR1c190ICAgIHNldE1hc3Rlck11dGUoYm9vbCBtdXRlZCk7CisKKyAgICAgICAgdmlydHVhbCAgICAgZmxvYXQgICAgICAgbWFzdGVyVm9sdW1lKCkgY29uc3Q7CisgICAgICAgIHZpcnR1YWwgICAgIGJvb2wgICAgICAgIG1hc3Rlck11dGUoKSBjb25zdDsKKworICAgICAgICB2aXJ0dWFsICAgICBzdGF0dXNfdCAgICBzZXRTdHJlYW1Wb2x1bWUoaW50IHN0cmVhbSwgZmxvYXQgdmFsdWUpOworICAgICAgICB2aXJ0dWFsICAgICBzdGF0dXNfdCAgICBzZXRTdHJlYW1NdXRlKGludCBzdHJlYW0sIGJvb2wgbXV0ZWQpOworCisgICAgICAgIHZpcnR1YWwgICAgIGZsb2F0ICAgICAgIHN0cmVhbVZvbHVtZShpbnQgc3RyZWFtKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCAgICAgYm9vbCAgICAgICAgc3RyZWFtTXV0ZShpbnQgc3RyZWFtKSBjb25zdDsKKworICAgICAgICAgICAgICAgICAgICBib29sICAgICAgICBpc011c2ljQWN0aXZlKCkgY29uc3Q7CisgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgc3A8VHJhY2s+IGNyZWF0ZVRyYWNrKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8QXVkaW9GbGluZ2VyOjpDbGllbnQ+JiBjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RyZWFtVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcmFtZUNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3A8SU1lbW9yeT4mIHNoYXJlZEJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICpzdGF0dXMpOworCisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHdha2VVcCgpIHsgbVdhaXRXb3JrQ1YuYnJvYWRjYXN0KCk7IH0KKyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIGdldFRyYWNrcyhTb3J0ZWRWZWN0b3IgPCBzcDxUcmFjaz4gPiYgdHJhY2tzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9yIDwgd3A8VHJhY2s+ID4mIGFjdGl2ZVRyYWNrcyk7CisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHB1dFRyYWNrcyhTb3J0ZWRWZWN0b3IgPCBzcDxUcmFjaz4gPiYgdHJhY2tzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9yIDwgd3A8VHJhY2s+ID4mIGFjdGl2ZVRyYWNrcyk7CisgICAgICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIHNldE91cHV0VHJhY2soT3V0cHV0VHJhY2sgKnRyYWNrKSB7IG1PdXRwdXRUcmFjayA9IHRyYWNrOyB9CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICBzdHJ1Y3QgIHN0cmVhbV90eXBlX3QgeworICAgICAgICAgICAgc3RyZWFtX3R5cGVfdCgpCisgICAgICAgICAgICAgICAgOiAgIHZvbHVtZSgxLjBmKSwKKyAgICAgICAgICAgICAgICAgICAgbXV0ZShmYWxzZSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZsb2F0ICAgICAgIHZvbHVtZTsKKyAgICAgICAgICAgIGJvb2wgICAgICAgIG11dGU7CisgICAgICAgIH07CisKKyAgICBwcml2YXRlOgorCisKKyAgICAgICAgZnJpZW5kIGNsYXNzIEF1ZGlvRmxpbmdlcjsKKyAgICAgICAgZnJpZW5kIGNsYXNzIFRyYWNrOworICAgICAgICBmcmllbmQgY2xhc3MgVHJhY2tCYXNlOworICAgICAgICBmcmllbmQgY2xhc3MgUmVjb3JkVHJhY2s7CisgICAgICAgIAorICAgICAgICBNaXhlclRocmVhZChjb25zdCBDbGllbnQmKTsKKyAgICAgICAgTWl4ZXJUaHJlYWQmIG9wZXJhdG9yID0gKGNvbnN0IE1peGVyVGhyZWFkJik7CisgIAorICAgICAgICBzdGF0dXNfdCAgICBhZGRUcmFjayhjb25zdCBzcDxUcmFjaz4mIHRyYWNrKTsKKyAgICAgICAgdm9pZCAgICAgICAgcmVtb3ZlVHJhY2sod3A8VHJhY2s+IHRyYWNrLCBpbnQgbmFtZSk7CisgICAgICAgIHZvaWQgICAgICAgIHJlbW92ZV90cmFja19sKHdwPFRyYWNrPiB0cmFjaywgaW50IG5hbWUpOworICAgICAgICB2b2lkICAgICAgICBkZXN0cm95VHJhY2soY29uc3Qgc3A8VHJhY2s+JiB0cmFjayk7CisgICAgICAgIGludCAgICAgICAgIGdldFRyYWNrTmFtZSgpOworICAgICAgICB2b2lkICAgICAgICBkZWxldGVUcmFja05hbWUoaW50IG5hbWUpOworICAgICAgICB2b2lkICAgICAgICBhZGRBY3RpdmVUcmFjayhjb25zdCB3cDxUcmFjaz4mIHQpOworICAgICAgICB2b2lkICAgICAgICByZW1vdmVBY3RpdmVUcmFjayhjb25zdCB3cDxUcmFjaz4mIHQpOworICAgICAgICBzaXplX3QgICAgICBnZXRPdXRwdXRGcmFtZUNvdW50KCk7CisKKyAgICAgICAgc3RhdHVzX3QgICAgZHVtcEludGVybmFscyhpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpOworICAgICAgICBzdGF0dXNfdCAgICBkdW1wVHJhY2tzKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisgICAgICAgIAorICAgICAgICBzcDxBdWRpb0ZsaW5nZXI+ICAgICAgICAgICAgICAgIG1BdWRpb0ZsaW5nZXI7ICAgICAgIAorICAgICAgICBtdXRhYmxlICAgICBNdXRleCAgICAgICAgICAgICAgIG1Mb2NrOworICAgICAgICBtdXRhYmxlICAgICBDb25kaXRpb24gICAgICAgICAgIG1XYWl0V29ya0NWOworICAgICAgICBTb3J0ZWRWZWN0b3I8IHdwPFRyYWNrPiA+ICAgICAgIG1BY3RpdmVUcmFja3M7CisgICAgICAgIFNvcnRlZFZlY3Rvcjwgc3A8VHJhY2s+ID4gICAgICAgbVRyYWNrczsKKyAgICAgICAgc3RyZWFtX3R5cGVfdCAgICAgICAgICAgICAgICAgICBtU3RyZWFtVHlwZXNbQXVkaW9TeXN0ZW06Ok5VTV9TVFJFQU1fVFlQRVNdOworICAgICAgICBBdWRpb01peGVyKiAgICAgICAgICAgICAgICAgICAgIG1BdWRpb01peGVyOworICAgICAgICBBdWRpb1N0cmVhbU91dCogICAgICAgICAgICAgICAgIG1PdXRwdXQ7CisgICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbU91dHB1dFR5cGU7CisgICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgbVNhbXBsZVJhdGU7CisgICAgICAgIHNpemVfdCAgICAgICAgICAgICAgICAgICAgICAgICAgbUZyYW1lQ291bnQ7CisgICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUNoYW5uZWxDb3VudDsKKyAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtRm9ybWF0OworICAgICAgICBpbnQxNl90KiAgICAgICAgICAgICAgICAgICAgICAgIG1NaXhCdWZmZXI7CisgICAgICAgIGZsb2F0ICAgICAgICAgICAgICAgICAgICAgICAgICAgbU1hc3RlclZvbHVtZTsKKyAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtTWFzdGVyTXV0ZTsKKyAgICAgICAgbnNlY3NfdCAgICAgICAgICAgICAgICAgICAgICAgICBtTGFzdFdyaXRlVGltZTsKKyAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtTnVtV3JpdGVzOworICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1OdW1EZWxheWVkV3JpdGVzOworICAgICAgICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1TdGFuZGJ5OworICAgICAgICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1JbldyaXRlOworICAgICAgICBzcCA8T3V0cHV0VHJhY2s+ICAgICAgICAgICAgICAgIG1PdXRwdXRUcmFjazsKKyAgICB9OworCisgICAgCisgICAgZnJpZW5kIGNsYXNzIEF1ZGlvQnVmZmVyOworCisgICAgY2xhc3MgVHJhY2tIYW5kbGUgOiBwdWJsaWMgYW5kcm9pZDo6Qm5BdWRpb1RyYWNrIHsKKyAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhY2tIYW5kbGUoY29uc3Qgc3A8TWl4ZXJUaHJlYWQ6OlRyYWNrPiYgdHJhY2spOworICAgICAgICB2aXJ0dWFsICAgICAgICAgICAgIH5UcmFja0hhbmRsZSgpOworICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHN0YXJ0KCk7CisgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgc3RvcCgpOworICAgICAgICB2aXJ0dWFsIHZvaWQgICAgICAgIGZsdXNoKCk7CisgICAgICAgIHZpcnR1YWwgdm9pZCAgICAgICAgbXV0ZShib29sKTsKKyAgICAgICAgdmlydHVhbCB2b2lkICAgICAgICBwYXVzZSgpOworICAgICAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHNldFZvbHVtZShmbG9hdCBsZWZ0LCBmbG9hdCByaWdodCk7CisgICAgICAgIHZpcnR1YWwgc3A8SU1lbW9yeT4gZ2V0Q2JsaygpIGNvbnN0OworICAgICAgICB2aXJ0dWFsIHN0YXR1c190IG9uVHJhbnNhY3QoCisgICAgICAgICAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKTsKKyAgICBwcml2YXRlOgorICAgICAgICBzcDxNaXhlclRocmVhZDo6VHJhY2s+IG1UcmFjazsKKyAgICB9OworCisgICAgZnJpZW5kIGNsYXNzIENsaWVudDsKKyAgICBmcmllbmQgY2xhc3MgTWl4ZXJUaHJlYWQ6OlRyYWNrOworCisKKyAgICAgICAgICAgICAgICB2b2lkICAgICAgICByZW1vdmVDbGllbnQocGlkX3QgcGlkKTsKKworCisKKyAgICBjbGFzcyBSZWNvcmRIYW5kbGUgOiBwdWJsaWMgYW5kcm9pZDo6Qm5BdWRpb1JlY29yZCB7CisgICAgcHVibGljOgorICAgICAgICBSZWNvcmRIYW5kbGUoY29uc3Qgc3A8TWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrPiYgcmVjb3JkVHJhY2spOworICAgICAgICB2aXJ0dWFsICAgICAgICAgICAgIH5SZWNvcmRIYW5kbGUoKTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFydCgpOworICAgICAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHN0b3AoKTsKKyAgICAgICAgdmlydHVhbCBzcDxJTWVtb3J5PiBnZXRDYmxrKCkgY29uc3Q7CisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3Qgb25UcmFuc2FjdCgKKyAgICAgICAgICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpOworICAgIHByaXZhdGU6CisgICAgICAgIHNwPE1peGVyVGhyZWFkOjpSZWNvcmRUcmFjaz4gbVJlY29yZFRyYWNrOworICAgIH07CisKKyAgICAvLyByZWNvcmQgdGhyZWFkCisgICAgY2xhc3MgQXVkaW9SZWNvcmRUaHJlYWQgOiBwdWJsaWMgVGhyZWFkCisgICAgeworICAgIHB1YmxpYzoKKyAgICAgICAgQXVkaW9SZWNvcmRUaHJlYWQoQXVkaW9IYXJkd2FyZUludGVyZmFjZSogYXVkaW9IYXJkd2FyZSk7CisgICAgICAgIHZpcnR1YWwgICAgICAgICAgICAgfkF1ZGlvUmVjb3JkVGhyZWFkKCk7CisgICAgICAgIHZpcnR1YWwgYm9vbCAgICAgICAgdGhyZWFkTG9vcCgpOworICAgICAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHJlYWR5VG9SdW4oKSB7IHJldHVybiBOT19FUlJPUjsgfQorICAgICAgICB2aXJ0dWFsIHZvaWQgICAgICAgIG9uRmlyc3RSZWYoKSB7fQorCisgICAgICAgICAgICAgICAgc3RhdHVzX3QgICAgc3RhcnQoTWl4ZXJUaHJlYWQ6OlJlY29yZFRyYWNrKiByZWNvcmRUcmFjayk7CisgICAgICAgICAgICAgICAgdm9pZCAgICAgICAgc3RvcChNaXhlclRocmVhZDo6UmVjb3JkVHJhY2sqIHJlY29yZFRyYWNrKTsKKyAgICAgICAgICAgICAgICB2b2lkICAgICAgICBleGl0KCk7CisgICAgICAgICAgICAgICAgc3RhdHVzX3QgICAgZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpOworCisgICAgcHJpdmF0ZToKKyAgICAgICAgICAgICAgICBBdWRpb1JlY29yZFRocmVhZCgpOworICAgICAgICAgICAgICAgIEF1ZGlvSGFyZHdhcmVJbnRlcmZhY2UgICAgICAgICAgICAgICptQXVkaW9IYXJkd2FyZTsKKyAgICAgICAgICAgICAgICBzcDxNaXhlclRocmVhZDo6UmVjb3JkVHJhY2s+ICAgICAgICBtUmVjb3JkVHJhY2s7CisgICAgICAgICAgICAgICAgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUxvY2s7CisgICAgICAgICAgICAgICAgQ29uZGl0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgbVdhaXRXb3JrQ1Y7CisgICAgICAgICAgICAgICAgQ29uZGl0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgbVN0b3BwZWQ7CisgICAgICAgICAgICAgICAgdm9sYXRpbGUgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgbUFjdGl2ZTsKKyAgICAgICAgICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtU3RhcnRTdGF0dXM7CisgICAgfTsKKworICAgIGZyaWVuZCBjbGFzcyBBdWRpb1JlY29yZFRocmVhZDsKKyAgICBmcmllbmQgY2xhc3MgTWl4ZXJUaHJlYWQ7CisKKyAgICAgICAgICAgICAgICBzdGF0dXNfdCAgICBzdGFydFJlY29yZChNaXhlclRocmVhZDo6UmVjb3JkVHJhY2sqIHJlY29yZFRyYWNrKTsKKyAgICAgICAgICAgICAgICB2b2lkICAgICAgICBzdG9wUmVjb3JkKE1peGVyVGhyZWFkOjpSZWNvcmRUcmFjayogcmVjb3JkVHJhY2spOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIHZvaWQgICAgICAgIGhhbmRsZU91dHB1dFN3aXRjaCgpOworCisgICAgbXV0YWJsZSAgICAgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtSGFyZHdhcmVMb2NrOworICAgIG11dGFibGUgICAgIE11dGV4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUxvY2s7CisgICAgICAgICAgICAgICAgRGVmYXVsdEtleWVkVmVjdG9yPCBwaWRfdCwgd3A8Q2xpZW50PiA+ICAgICBtQ2xpZW50czsKKworICAgICAgICAgICAgICAgIHNwPE1peGVyVGhyZWFkPiAgICAgICAgICAgICAgICAgICAgIG1BMmRwTWl4ZXJUaHJlYWQ7CisgICAgICAgICAgICAgICAgc3A8TWl4ZXJUaHJlYWQ+ICAgICAgICAgICAgICAgICAgICAgbUhhcmR3YXJlTWl4ZXJUaHJlYWQ7CisgICAgICAgICAgICAgICAgQXVkaW9IYXJkd2FyZUludGVyZmFjZSogICAgICAgICAgICAgbUF1ZGlvSGFyZHdhcmU7CisgICAgICAgICAgICAgICAgQXVkaW9IYXJkd2FyZUludGVyZmFjZSogICAgICAgICAgICAgbUEyZHBBdWRpb0ludGVyZmFjZTsKKyAgICAgICAgICAgICAgICBzcDxBdWRpb1JlY29yZFRocmVhZD4gICAgICAgICAgICAgICBtQXVkaW9SZWNvcmRUaHJlYWQ7CisgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUEyZHBFbmFibGVkOworICAgICAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1BMmRwRW5hYmxlZFJlcTsKKyAgICBtdXRhYmxlICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtSGFyZHdhcmVTdGF0dXM7CisgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9yPCB3cDxJQmluZGVyPiA+ICAgICAgICAgbU5vdGlmaWNhdGlvbkNsaWVudHM7CisgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUZvcmNlZFNwZWFrZXJDb3VudDsKKyAgICAgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtU2F2ZWRSb3V0ZTsKKyAgICAgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtRm9yY2VkUm91dGU7CisgICAgICAgICAgICAgICAgbnNlY3NfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbVJvdXRlUmVzdG9yZVRpbWU7CisgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbU11c2ljTXV0ZVNhdmVkOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9BVURJT19GTElOR0VSX0gKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVHZW5lcmljLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVHZW5lcmljLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmJlYWRhCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9IYXJkd2FyZUdlbmVyaWMuY3BwCkBAIC0wLDAgKzEsMzEzIEBACisvKgorKioKKyoqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPHNjaGVkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKworI2RlZmluZSBMT0dfVEFHICJBdWRpb0hhcmR3YXJlIgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKworI2luY2x1ZGUgIkF1ZGlvSGFyZHdhcmVHZW5lcmljLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGtBdWRpb0RldmljZU5hbWUgPSAiL2Rldi9lYWMiOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvSGFyZHdhcmVHZW5lcmljOjpBdWRpb0hhcmR3YXJlR2VuZXJpYygpCisgICAgOiBtT3V0cHV0KDApLCBtSW5wdXQoMCksICBtRmQoLTEpLCBtTWljTXV0ZShmYWxzZSkKK3sKKyAgICBtRmQgPSA6Om9wZW4oa0F1ZGlvRGV2aWNlTmFtZSwgT19SRFdSKTsKK30KKworQXVkaW9IYXJkd2FyZUdlbmVyaWM6On5BdWRpb0hhcmR3YXJlR2VuZXJpYygpCit7CisgICAgaWYgKG1GZCA+PSAwKSA6OmNsb3NlKG1GZCk7CisgICAgZGVsZXRlIG1PdXRwdXQ7CisgICAgZGVsZXRlIG1JbnB1dDsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUdlbmVyaWM6OmluaXRDaGVjaygpCit7CisgICAgaWYgKG1GZCA+PSAwKSB7CisgICAgICAgIGlmICg6OmFjY2VzcyhrQXVkaW9EZXZpY2VOYW1lLCBPX1JEV1IpID09IE5PX0VSUk9SKQorICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTk9fSU5JVDsKK30KKworQXVkaW9TdHJlYW1PdXQqIEF1ZGlvSGFyZHdhcmVHZW5lcmljOjpvcGVuT3V0cHV0U3RyZWFtKAorICAgICAgICBpbnQgZm9ybWF0LCBpbnQgY2hhbm5lbENvdW50LCB1aW50MzJfdCBzYW1wbGVSYXRlLCBzdGF0dXNfdCAqc3RhdHVzKQoreworICAgIEF1dG9NdXRleCBsb2NrKG1Mb2NrKTsKKworICAgIC8vIG9ubHkgb25lIG91dHB1dCBzdHJlYW0gYWxsb3dlZAorICAgIGlmIChtT3V0cHV0KSB7CisgICAgICAgIGlmIChzdGF0dXMpIHsKKyAgICAgICAgICAgICpzdGF0dXMgPSBJTlZBTElEX09QRVJBVElPTjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBjcmVhdGUgbmV3IG91dHB1dCBzdHJlYW0KKyAgICBBdWRpb1N0cmVhbU91dEdlbmVyaWMqIG91dCA9IG5ldyBBdWRpb1N0cmVhbU91dEdlbmVyaWMoKTsKKyAgICBzdGF0dXNfdCBsU3RhdHVzID0gb3V0LT5zZXQodGhpcywgbUZkLCBmb3JtYXQsIGNoYW5uZWxDb3VudCwgc2FtcGxlUmF0ZSk7CisgICAgaWYgKHN0YXR1cykgeworICAgICAgICAqc3RhdHVzID0gbFN0YXR1czsKKyAgICB9CisgICAgaWYgKGxTdGF0dXMgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgbU91dHB1dCA9IG91dDsKKyAgICB9IGVsc2UgeworICAgICAgICBkZWxldGUgb3V0OworICAgIH0KKyAgICByZXR1cm4gbU91dHB1dDsKK30KKwordm9pZCBBdWRpb0hhcmR3YXJlR2VuZXJpYzo6Y2xvc2VPdXRwdXRTdHJlYW0oQXVkaW9TdHJlYW1PdXRHZW5lcmljKiBvdXQpIHsKKyAgICBpZiAob3V0ID09IG1PdXRwdXQpIG1PdXRwdXQgPSAwOworfQorCitBdWRpb1N0cmVhbUluKiBBdWRpb0hhcmR3YXJlR2VuZXJpYzo6b3BlbklucHV0U3RyZWFtKAorICAgICAgICBpbnQgZm9ybWF0LCBpbnQgY2hhbm5lbENvdW50LCB1aW50MzJfdCBzYW1wbGVSYXRlLCBzdGF0dXNfdCAqc3RhdHVzLAorICAgICAgICBBdWRpb1N5c3RlbTo6YXVkaW9faW5fYWNvdXN0aWNzIGFjb3VzdGljcykKK3sKKyAgICBBdXRvTXV0ZXggbG9jayhtTG9jayk7CisKKyAgICAvLyBvbmx5IG9uZSBpbnB1dCBzdHJlYW0gYWxsb3dlZAorICAgIGlmIChtSW5wdXQpIHsKKyAgICAgICAgaWYgKHN0YXR1cykgeworICAgICAgICAgICAgKnN0YXR1cyA9IElOVkFMSURfT1BFUkFUSU9OOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIGNyZWF0ZSBuZXcgb3V0cHV0IHN0cmVhbQorICAgIEF1ZGlvU3RyZWFtSW5HZW5lcmljKiBpbiA9IG5ldyBBdWRpb1N0cmVhbUluR2VuZXJpYygpOworICAgIHN0YXR1c190IGxTdGF0dXMgPSBpbi0+c2V0KHRoaXMsIG1GZCwgZm9ybWF0LCBjaGFubmVsQ291bnQsIHNhbXBsZVJhdGUsIGFjb3VzdGljcyk7CisgICAgaWYgKHN0YXR1cykgeworICAgICAgICAqc3RhdHVzID0gbFN0YXR1czsKKyAgICB9CisgICAgaWYgKGxTdGF0dXMgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgbUlucHV0ID0gaW47CisgICAgfSBlbHNlIHsKKyAgICAgICAgZGVsZXRlIGluOworICAgIH0KKyAgICByZXR1cm4gbUlucHV0OworfQorCit2b2lkIEF1ZGlvSGFyZHdhcmVHZW5lcmljOjpjbG9zZUlucHV0U3RyZWFtKEF1ZGlvU3RyZWFtSW5HZW5lcmljKiBpbikgeworICAgIGlmIChpbiA9PSBtSW5wdXQpIG1JbnB1dCA9IDA7Cit9CisKK3N0YXR1c190IEF1ZGlvSGFyZHdhcmVHZW5lcmljOjpzZXRWb2ljZVZvbHVtZShmbG9hdCB2KQoreworICAgIC8vIEltcGxlbWVudDogc2V0IHZvaWNlIHZvbHVtZQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUdlbmVyaWM6OnNldE1hc3RlclZvbHVtZShmbG9hdCB2KQoreworICAgIC8vIEltcGxlbWVudDogc2V0IG1hc3RlciB2b2x1bWUKKyAgICAvLyByZXR1cm4gZXJyb3IgLSBzb2Z0d2FyZSBtaXhlciB3aWxsIGhhbmRsZSBpdAorICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUdlbmVyaWM6OnNldE1pY011dGUoYm9vbCBzdGF0ZSkKK3sKKyAgICBtTWljTXV0ZSA9IHN0YXRlOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUdlbmVyaWM6OmdldE1pY011dGUoYm9vbCogc3RhdGUpCit7CisgICAgKnN0YXRlID0gbU1pY011dGU7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlR2VuZXJpYzo6ZHVtcEludGVybmFscyhpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgcmVzdWx0LmFwcGVuZCgiQXVkaW9IYXJkd2FyZUdlbmVyaWM6OmR1bXBJbnRlcm5hbHNcbiIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0bUZkOiAlZCBtTWljTXV0ZTogJXNcbiIsICBtRmQsIG1NaWNNdXRlPyAidHJ1ZSI6ICJmYWxzZSIpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICA6OndyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUdlbmVyaWM6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGR1bXBJbnRlcm5hbHMoZmQsIGFyZ3MpOworICAgIGlmIChtSW5wdXQpIHsKKyAgICAgICAgbUlucHV0LT5kdW1wKGZkLCBhcmdzKTsKKyAgICB9CisgICAgaWYgKG1PdXRwdXQpIHsKKyAgICAgICAgbU91dHB1dC0+ZHVtcChmZCwgYXJncyk7CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0dXNfdCBBdWRpb1N0cmVhbU91dEdlbmVyaWM6OnNldCgKKyAgICAgICAgQXVkaW9IYXJkd2FyZUdlbmVyaWMgKmh3LAorICAgICAgICBpbnQgZmQsCisgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgIGludCBjaGFubmVscywKKyAgICAgICAgdWludDMyX3QgcmF0ZSkKK3sKKyAgICAvLyBmaXggdXAgZGVmYXVsdHMKKyAgICBpZiAoZm9ybWF0ID09IDApIGZvcm1hdCA9IEF1ZGlvU3lzdGVtOjpQQ01fMTZfQklUOworICAgIGlmIChjaGFubmVscyA9PSAwKSBjaGFubmVscyA9IGNoYW5uZWxDb3VudCgpOworICAgIGlmIChyYXRlID09IDApIHJhdGUgPSBzYW1wbGVSYXRlKCk7CisKKyAgICAvLyBjaGVjayB2YWx1ZXMKKyAgICBpZiAoKGZvcm1hdCAhPSBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVCkgfHwKKyAgICAgICAgICAgIChjaGFubmVscyAhPSBjaGFubmVsQ291bnQoKSkgfHwKKyAgICAgICAgICAgIChyYXRlICE9IHNhbXBsZVJhdGUoKSkpCisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisKKyAgICBtQXVkaW9IYXJkd2FyZSA9IGh3OworICAgIG1GZCA9IGZkOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworQXVkaW9TdHJlYW1PdXRHZW5lcmljOjp+QXVkaW9TdHJlYW1PdXRHZW5lcmljKCkKK3sKKyAgICBpZiAobUF1ZGlvSGFyZHdhcmUpCisgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5jbG9zZU91dHB1dFN0cmVhbSh0aGlzKTsKK30KKworc3NpemVfdCBBdWRpb1N0cmVhbU91dEdlbmVyaWM6OndyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgc2l6ZV90IGJ5dGVzKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgcmV0dXJuIHNzaXplX3QoOjp3cml0ZShtRmQsIGJ1ZmZlciwgYnl0ZXMpKTsKK30KKworc3RhdHVzX3QgQXVkaW9TdHJlYW1PdXRHZW5lcmljOjpzdGFuZGJ5KCkKK3sKKyAgICAvLyBJbXBsZW1lbnQ6IGF1ZGlvIGhhcmR3YXJlIHRvIHN0YW5kYnkgbW9kZQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9TdHJlYW1PdXRHZW5lcmljOjpkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJBdWRpb1N0cmVhbU91dEdlbmVyaWM6OmR1bXBcbiIpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdHNhbXBsZSByYXRlOiAlZFxuIiwgc2FtcGxlUmF0ZSgpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRidWZmZXIgc2l6ZTogJWRcbiIsIGJ1ZmZlclNpemUoKSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0Y2hhbm5lbCBjb3VudDogJWRcbiIsIGNoYW5uZWxDb3VudCgpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRmb3JtYXQ6ICVkXG4iLCBmb3JtYXQoKSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0bUF1ZGlvSGFyZHdhcmU6ICVwXG4iLCBtQXVkaW9IYXJkd2FyZSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0bUZkOiAlZFxuIiwgbUZkKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgOjp3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gcmVjb3JkIGZ1bmN0aW9ucworc3RhdHVzX3QgQXVkaW9TdHJlYW1JbkdlbmVyaWM6OnNldCgKKyAgICAgICAgQXVkaW9IYXJkd2FyZUdlbmVyaWMgKmh3LAorICAgICAgICBpbnQgZmQsCisgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgIGludCBjaGFubmVscywKKyAgICAgICAgdWludDMyX3QgcmF0ZSwKKyAgICAgICAgQXVkaW9TeXN0ZW06OmF1ZGlvX2luX2Fjb3VzdGljcyBhY291c3RpY3MpCit7CisgICAgLy8gRklYTUU6IHJlbW92ZSBsb2dnaW5nCisgICAgTE9HRCgiQXVkaW9TdHJlYW1JbkdlbmVyaWM6OnNldCglcCwgJWQsICVkLCAlZCwgJXUpIiwgaHcsIGZkLCBmb3JtYXQsIGNoYW5uZWxzLCByYXRlKTsKKyAgICAvLyBjaGVjayB2YWx1ZXMKKyAgICBpZiAoKGZvcm1hdCAhPSBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVCkgfHwKKyAgICAgICAgICAgIChjaGFubmVscyAhPSBjaGFubmVsQ291bnQoKSkgfHwKKyAgICAgICAgICAgIChyYXRlICE9IHNhbXBsZVJhdGUoKSkpIHsKKyAgICAgICAgTE9HRSgiRXJyb3Igb3BlbmluZyBpbnB1dCBjaGFubmVsIik7CisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisgICAgfQorCisgICAgbUF1ZGlvSGFyZHdhcmUgPSBodzsKKyAgICBtRmQgPSBmZDsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK0F1ZGlvU3RyZWFtSW5HZW5lcmljOjp+QXVkaW9TdHJlYW1JbkdlbmVyaWMoKQoreworICAgIC8vIEZJWE1FOiByZW1vdmUgbG9nZ2luZworICAgIExPR0QoIkF1ZGlvU3RyZWFtSW5HZW5lcmljIGRlc3RydWN0b3IiKTsKKyAgICBpZiAobUF1ZGlvSGFyZHdhcmUpCisgICAgICAgIG1BdWRpb0hhcmR3YXJlLT5jbG9zZUlucHV0U3RyZWFtKHRoaXMpOworfQorCitzc2l6ZV90IEF1ZGlvU3RyZWFtSW5HZW5lcmljOjpyZWFkKHZvaWQqIGJ1ZmZlciwgc3NpemVfdCBieXRlcykKK3sKKyAgICAvLyBGSVhNRTogcmVtb3ZlIGxvZ2dpbmcKKyAgICBMT0dEKCJBdWRpb1N0cmVhbUluR2VuZXJpYzo6cmVhZCglcCwgJWQpIGZyb20gZmQgJWQiLCBidWZmZXIsIGJ5dGVzLCBtRmQpOworICAgIEF1dG9NdXRleCBsb2NrKG1Mb2NrKTsKKyAgICBpZiAobUZkIDwgMCkgeworICAgICAgICBMT0dFKCJBdHRlbXB0IHRvIHJlYWQgZnJvbSB1bm9wZW5lZCBkZXZpY2UiKTsKKyAgICAgICAgcmV0dXJuIE5PX0lOSVQ7CisgICAgfQorICAgIHJldHVybiA6OnJlYWQobUZkLCBidWZmZXIsIGJ5dGVzKTsKK30KKworc3RhdHVzX3QgQXVkaW9TdHJlYW1JbkdlbmVyaWM6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGNvbnN0IHNpemVfdCBTSVpFID0gMjU2OworICAgIGNoYXIgYnVmZmVyW1NJWkVdOworICAgIFN0cmluZzggcmVzdWx0OworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIkF1ZGlvU3RyZWFtSW5HZW5lcmljOjpkdW1wXG4iKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRzYW1wbGUgcmF0ZTogJWRcbiIsIHNhbXBsZVJhdGUoKSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0YnVmZmVyIHNpemU6ICVkXG4iLCBidWZmZXJTaXplKCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdGNoYW5uZWwgY291bnQ6ICVkXG4iLCBjaGFubmVsQ291bnQoKSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0Zm9ybWF0OiAlZFxuIiwgZm9ybWF0KCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdG1BdWRpb0hhcmR3YXJlOiAlcFxuIiwgbUF1ZGlvSGFyZHdhcmUpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdG1GZDogJWRcbiIsIG1GZCk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIDo6d3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0hhcmR3YXJlR2VuZXJpYy5oIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9IYXJkd2FyZUdlbmVyaWMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTQ5YWExCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9IYXJkd2FyZUdlbmVyaWMuaApAQCAtMCwwICsxLDE0MSBAQAorLyoKKyoqCisqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2lmbmRlZiBBTkRST0lEX0FVRElPX0hBUkRXQVJFX0dFTkVSSUNfSAorI2RlZmluZSBBTkRST0lEX0FVRElPX0hBUkRXQVJFX0dFTkVSSUNfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDxoYXJkd2FyZV9sZWdhY3kvQXVkaW9IYXJkd2FyZUJhc2UuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEF1ZGlvSGFyZHdhcmVHZW5lcmljOworCitjbGFzcyBBdWRpb1N0cmVhbU91dEdlbmVyaWMgOiBwdWJsaWMgQXVkaW9TdHJlYW1PdXQgeworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9TdHJlYW1PdXRHZW5lcmljKCkgOiBtQXVkaW9IYXJkd2FyZSgwKSwgbUZkKC0xKSB7fQorICAgIHZpcnR1YWwgICAgICAgICAgICAgfkF1ZGlvU3RyZWFtT3V0R2VuZXJpYygpOworCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXQoCisgICAgICAgICAgICBBdWRpb0hhcmR3YXJlR2VuZXJpYyAqaHcsCisgICAgICAgICAgICBpbnQgbUZkLAorICAgICAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgICAgIGludCBjaGFubmVsQ291bnQsCisgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlKTsKKworICAgIHZpcnR1YWwgdWludDMyX3QgICAgc2FtcGxlUmF0ZSgpIGNvbnN0IHsgcmV0dXJuIDQ0MTAwOyB9CisgICAgdmlydHVhbCBzaXplX3QgICAgICBidWZmZXJTaXplKCkgY29uc3QgeyByZXR1cm4gNDA5NjsgfQorICAgIHZpcnR1YWwgaW50ICAgICAgICAgY2hhbm5lbENvdW50KCkgY29uc3QgeyByZXR1cm4gMjsgfQorICAgIHZpcnR1YWwgaW50ICAgICAgICAgZm9ybWF0KCkgY29uc3QgeyByZXR1cm4gQXVkaW9TeXN0ZW06OlBDTV8xNl9CSVQ7IH0KKyAgICB2aXJ0dWFsIHVpbnQzMl90ICAgIGxhdGVuY3koKSBjb25zdCB7IHJldHVybiAyMDsgfQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0Vm9sdW1lKGZsb2F0IHZvbHVtZSkgeyByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047IH0KKyAgICB2aXJ0dWFsIHNzaXplX3QgICAgIHdyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgc2l6ZV90IGJ5dGVzKTsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHN0YW5kYnkoKTsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKworcHJpdmF0ZToKKyAgICBBdWRpb0hhcmR3YXJlR2VuZXJpYyAqbUF1ZGlvSGFyZHdhcmU7CisgICAgTXV0ZXggICBtTG9jazsKKyAgICBpbnQgICAgIG1GZDsKK307CisKK2NsYXNzIEF1ZGlvU3RyZWFtSW5HZW5lcmljIDogcHVibGljIEF1ZGlvU3RyZWFtSW4geworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9TdHJlYW1JbkdlbmVyaWMoKSA6IG1BdWRpb0hhcmR3YXJlKDApLCBtRmQoLTEpIHt9CisgICAgdmlydHVhbCAgICAgICAgICAgICB+QXVkaW9TdHJlYW1JbkdlbmVyaWMoKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0KAorICAgICAgICAgICAgQXVkaW9IYXJkd2FyZUdlbmVyaWMgKmh3LAorICAgICAgICAgICAgaW50IG1GZCwKKyAgICAgICAgICAgIGludCBmb3JtYXQsCisgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50LAorICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgICAgIEF1ZGlvU3lzdGVtOjphdWRpb19pbl9hY291c3RpY3MgYWNvdXN0aWNzKTsKKworICAgIHVpbnQzMl90ICAgIHNhbXBsZVJhdGUoKSBjb25zdCB7IHJldHVybiA4MDAwOyB9CisgICAgdmlydHVhbCBzaXplX3QgICAgICBidWZmZXJTaXplKCkgY29uc3QgeyByZXR1cm4gMzIwOyB9CisgICAgdmlydHVhbCBpbnQgICAgICAgICBjaGFubmVsQ291bnQoKSBjb25zdCB7IHJldHVybiAxOyB9CisgICAgdmlydHVhbCBpbnQgICAgICAgICBmb3JtYXQoKSBjb25zdCB7IHJldHVybiBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVDsgfQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0R2FpbihmbG9hdCBnYWluKSB7IHJldHVybiBJTlZBTElEX09QRVJBVElPTjsgfQorICAgIHZpcnR1YWwgc3NpemVfdCAgICAgcmVhZCh2b2lkKiBidWZmZXIsIHNzaXplX3QgYnl0ZXMpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc3RhbmRieSgpIHsgcmV0dXJuIE5PX0VSUk9SOyB9CisKK3ByaXZhdGU6CisgICAgQXVkaW9IYXJkd2FyZUdlbmVyaWMgKm1BdWRpb0hhcmR3YXJlOworICAgIE11dGV4ICAgbUxvY2s7CisgICAgaW50ICAgICBtRmQ7Cit9OworCisKK2NsYXNzIEF1ZGlvSGFyZHdhcmVHZW5lcmljIDogcHVibGljIEF1ZGlvSGFyZHdhcmVCYXNlCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb0hhcmR3YXJlR2VuZXJpYygpOworICAgIHZpcnR1YWwgICAgICAgICAgICAgfkF1ZGlvSGFyZHdhcmVHZW5lcmljKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBpbml0Q2hlY2soKTsKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldFZvaWNlVm9sdW1lKGZsb2F0IHZvbHVtZSk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRNYXN0ZXJWb2x1bWUoZmxvYXQgdm9sdW1lKTsKKworICAgIC8vIG1pYyBtdXRlCisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRNaWNNdXRlKGJvb2wgc3RhdGUpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZ2V0TWljTXV0ZShib29sKiBzdGF0ZSk7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldFBhcmFtZXRlcihjb25zdCBjaGFyKiBrZXksIGNvbnN0IGNoYXIqIHZhbHVlKQorICAgICAgICAgICAgeyByZXR1cm4gTk9fRVJST1I7IH0KKworICAgIC8vIGNyZWF0ZSBJL08gc3RyZWFtcworICAgIHZpcnR1YWwgQXVkaW9TdHJlYW1PdXQqIG9wZW5PdXRwdXRTdHJlYW0oCisgICAgICAgICAgICBpbnQgZm9ybWF0PTAsCisgICAgICAgICAgICBpbnQgY2hhbm5lbENvdW50PTAsCisgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlPTAsCisgICAgICAgICAgICBzdGF0dXNfdCAqc3RhdHVzPTApOworCisgICAgdmlydHVhbCBBdWRpb1N0cmVhbUluKiBvcGVuSW5wdXRTdHJlYW0oCisgICAgICAgICAgICBpbnQgZm9ybWF0LAorICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgICAgIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgICAgICBzdGF0dXNfdCAqc3RhdHVzLAorICAgICAgICAgICAgQXVkaW9TeXN0ZW06OmF1ZGlvX2luX2Fjb3VzdGljcyBhY291c3RpY3MpOworCisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgY2xvc2VPdXRwdXRTdHJlYW0oQXVkaW9TdHJlYW1PdXRHZW5lcmljKiBvdXQpOworICAgICAgICAgICAgdm9pZCAgICAgICAgICAgIGNsb3NlSW5wdXRTdHJlYW0oQXVkaW9TdHJlYW1JbkdlbmVyaWMqIGluKTsKK3Byb3RlY3RlZDoKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgICAgICBkb1JvdXRpbmcoKSB7IHJldHVybiBOT19FUlJPUjsgfQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgIGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKworcHJpdmF0ZToKKyAgICBzdGF0dXNfdCAgICAgICAgICAgICAgICBkdW1wSW50ZXJuYWxzKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICBNdXRleCAgICAgICAgICAgICAgICAgICBtTG9jazsKKyAgICBBdWRpb1N0cmVhbU91dEdlbmVyaWMgICAqbU91dHB1dDsKKyAgICBBdWRpb1N0cmVhbUluR2VuZXJpYyAgICAqbUlucHV0OworICAgIGludCAgICAgICAgICAgICAgICAgICAgIG1GZDsKKyAgICBib29sICAgICAgICAgICAgICAgICAgICBtTWljTXV0ZTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfQVVESU9fSEFSRFdBUkVfR0VORVJJQ19ICmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0hhcmR3YXJlSW50ZXJmYWNlLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVJbnRlcmZhY2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjNzZhMTkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0hhcmR3YXJlSW50ZXJmYWNlLmNwcApAQCAtMCwwICsxLDI0NyBAQAorLyoKKyoqCisqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaW5jbHVkZSA8Y3V0aWxzL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworI2RlZmluZSBMT0dfVEFHICJBdWRpb0hhcmR3YXJlSW50ZXJmYWNlIgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKworI2luY2x1ZGUgIkF1ZGlvSGFyZHdhcmVTdHViLmgiCisjaW5jbHVkZSAiQXVkaW9IYXJkd2FyZUdlbmVyaWMuaCIKKworLy8jZGVmaW5lIERVTVBfRkxJTkdFUl9PVVQgICAgICAgIC8vIGlmIGRlZmluZWQgYWxsb3dzIHJlY29yZGluZyBzYW1wbGVzIGluIGEgZmlsZQorI2lmZGVmIERVTVBfRkxJTkdFUl9PVVQKKyNpbmNsdWRlICJBdWRpb0R1bXBJbnRlcmZhY2UuaCIKKyNlbmRpZgorCisKKy8vIGNoYW5nZSB0byAxIHRvIGxvZyByb3V0aW5nIGNhbGxzCisjZGVmaW5lIExPR19ST1VUSU5HX0NBTExTIDAKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisjaWYgTE9HX1JPVVRJTkdfQ0FMTFMKK3N0YXRpYyBjb25zdCBjaGFyKiByb3V0aW5nTW9kZVN0cmluZ3NbXSA9Cit7CisgICAgIk9VVCBPRiBSQU5HRSIsCisgICAgIklOVkFMSUQiLAorICAgICJDVVJSRU5UIiwKKyAgICAiTk9STUFMIiwKKyAgICAiUklOR1RPTkUiLAorICAgICJJTl9DQUxMIgorfTsKKworc3RhdGljIGNvbnN0IGNoYXIqIHJvdXRlU3RyaW5nc1tdID0KK3sKKyAgICAiRUFSUElFQ0UgIiwKKyAgICAiU1BFQUtFUiAiLAorICAgICJCTFVFVE9PVEggIiwKKyAgICAiSEVBRFNFVCAiCisgICAgIkJMVUVUT09USF9BMkRQICIKK307CitzdGF0aWMgY29uc3QgY2hhciogcm91dGVOb25lID0gIk5PTkUiOworCitzdGF0aWMgY29uc3QgY2hhciogZGlzcGxheU1vZGUoaW50IG1vZGUpCit7CisgICAgaWYgKChtb2RlIDwgLTIpIHx8IChtb2RlID4gMikpCisgICAgICAgIHJldHVybiByb3V0aW5nTW9kZVN0cmluZ3NbMF07CisgICAgcmV0dXJuIHJvdXRpbmdNb2RlU3RyaW5nc1ttb2RlKzNdOworfQorCitzdGF0aWMgY29uc3QgY2hhciogZGlzcGxheVJvdXRlcyh1aW50MzJfdCByb3V0ZXMpCit7CisgICAgc3RhdGljIGNoYXIgcm91dGVTdHJbODBdOworICAgIGlmIChyb3V0ZXMgPT0gMCkKKyAgICAgICAgcmV0dXJuIHJvdXRlTm9uZTsKKyAgICByb3V0ZVN0clswXSA9IDA7CisgICAgaW50IGJpdE1hc2sgPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgKytpLCBiaXRNYXNrIDw8PSAxKSB7CisgICAgICAgIGlmIChyb3V0ZXMgJiBiaXRNYXNrKSB7CisgICAgICAgICAgICBzdHJjYXQocm91dGVTdHIsIHJvdXRlU3RyaW5nc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcm91dGVTdHJbc3RybGVuKHJvdXRlU3RyKS0xXSA9IDA7CisgICAgcmV0dXJuIHJvdXRlU3RyOworfQorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXVkaW9IYXJkd2FyZUludGVyZmFjZSogQXVkaW9IYXJkd2FyZUludGVyZmFjZTo6Y3JlYXRlKCkKK3sKKyAgICAvKgorICAgICAqIEZJWE1FOiBUaGlzIGNvZGUgbmVlZHMgdG8gaW5zdGFudGlhdGUgdGhlIGNvcnJlY3QgYXVkaW8gZGV2aWNlCisgICAgICogaW50ZXJmYWNlLiBGb3Igbm93IC0gd2UgdXNlIGNvbXBpbGUtdGltZSBzd2l0Y2hlcy4KKyAgICAgKi8KKyAgICBBdWRpb0hhcmR3YXJlSW50ZXJmYWNlKiBodyA9IDA7CisgICAgY2hhciB2YWx1ZVtQUk9QRVJUWV9WQUxVRV9NQVhdOworCisjaWZkZWYgR0VORVJJQ19BVURJTworICAgIGh3ID0gbmV3IEF1ZGlvSGFyZHdhcmVHZW5lcmljKCk7CisjZWxzZQorICAgIC8vIGlmIHJ1bm5pbmcgaW4gZW11bGF0aW9uIC0gdXNlIHRoZSBlbXVsYXRvciBkcml2ZXIKKyAgICBpZiAocHJvcGVydHlfZ2V0KCJyby5rZXJuZWwucWVtdSIsIHZhbHVlLCAwKSkgeworICAgICAgICBMT0dEKCJSdW5uaW5nIGluIGVtdWxhdGlvbiAtIHVzaW5nIGdlbmVyaWMgYXVkaW8gZHJpdmVyIik7CisgICAgICAgIGh3ID0gbmV3IEF1ZGlvSGFyZHdhcmVHZW5lcmljKCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBMT0dWKCJDcmVhdGluZyBWZW5kb3IgU3BlY2lmaWMgQXVkaW9IYXJkd2FyZSIpOworICAgICAgICBodyA9IGNyZWF0ZUF1ZGlvSGFyZHdhcmUoKTsKKyAgICB9CisjZW5kaWYKKyAgICBpZiAoaHctPmluaXRDaGVjaygpICE9IE5PX0VSUk9SKSB7CisgICAgICAgIExPR1coIlVzaW5nIHN0dWJiZWQgYXVkaW8gaGFyZHdhcmUuIE5vIHNvdW5kIHdpbGwgYmUgcHJvZHVjZWQuIik7CisgICAgICAgIGRlbGV0ZSBodzsKKyAgICAgICAgaHcgPSBuZXcgQXVkaW9IYXJkd2FyZVN0dWIoKTsKKyAgICB9CisgICAgCisjaWZkZWYgRFVNUF9GTElOR0VSX09VVAorICAgIC8vIFRoaXMgY29kZSBhZGRzIGEgcmVjb3JkIG9mIGJ1ZmZlcnMgaW4gYSBmaWxlIHRvIHdyaXRlIGNhbGxzIG1hZGUgYnkgQXVkaW9GbGluZ2VyLgorICAgIC8vIEl0IHJlcGxhY2VzIHRoZSBjdXJyZW50IEF1ZGlvSGFyZHdhcmVJbnRlcmZhY2Ugb2JqZWN0IGJ5IGFuIGludGVybWVkaWF0ZSBvbmUgd2hpY2gKKyAgICAvLyB3aWxsIHJlY29yZCBidWZmZXJzIGluIGEgZmlsZSAoYWZ0ZXIgc2VuZGluZyB0aGVtIHRvIGhhcmR3YXJlKSBmb3IgdGVzdGluZyBwdXJwb3NlLgorICAgIC8vIFRoaXMgZmVhdHVyZSBpcyBlbmFibGVkIGJ5IGRlZmluaW5nIHN5bWJvbCBEVU1QX0ZMSU5HRVJfT1VULgorICAgIC8vIFRoZSBvdXRwdXQgZmlsZSBpcyBGTElOR0VSX0RVTVBfTkFNRS4gUGF1c2UgYXJlIG5vdCByZWNvcmRlZCBpbiB0aGUgZmlsZS4KKyAgICAKKyAgICBodyA9IG5ldyBBdWRpb0R1bXBJbnRlcmZhY2UoaHcpOyAgICAvLyByZXBsYWNlIGludGVyZmFjZQorI2VuZGlmCisgICAgcmV0dXJuIGh3OworfQorCitBdWRpb1N0cmVhbU91dDo6fkF1ZGlvU3RyZWFtT3V0KCkKK3sKK30KKworQXVkaW9TdHJlYW1Jbjo6fkF1ZGlvU3RyZWFtSW4oKSB7fQorCitBdWRpb0hhcmR3YXJlQmFzZTo6QXVkaW9IYXJkd2FyZUJhc2UoKQoreworICAgIC8vIGZvcmNlIGEgcm91dGluZyB1cGRhdGUgb24gaW5pdGlhbGl6YXRpb24KKyAgICBtZW1zZXQoJm1Sb3V0ZXMsIDAsIHNpemVvZihtUm91dGVzKSk7CisgICAgbU1vZGUgPSAwOworfQorCisvLyBnZW5lcmljcyBmb3IgYXVkaW8gcm91dGluZyAtIHRoZSByZWFsIHdvcmsgaXMgZG9uZSBpbiBkb1JvdXRpbmcKK3N0YXR1c190IEF1ZGlvSGFyZHdhcmVCYXNlOjpzZXRSb3V0aW5nKGludCBtb2RlLCB1aW50MzJfdCByb3V0ZXMpCit7CisjaWYgTE9HX1JPVVRJTkdfQ0FMTFMKKyAgICBMT0dEKCJzZXRSb3V0aW5nOiBtb2RlPSVzLCByb3V0ZXM9WyVzXSIsIGRpc3BsYXlNb2RlKG1vZGUpLCBkaXNwbGF5Um91dGVzKHJvdXRlcykpOworI2VuZGlmCisgICAgaWYgKG1vZGUgPT0gQXVkaW9TeXN0ZW06Ok1PREVfQ1VSUkVOVCkKKyAgICAgICAgbW9kZSA9IG1Nb2RlOworICAgIGlmICgobW9kZSA8IDApIHx8IChtb2RlID49IEF1ZGlvU3lzdGVtOjpOVU1fTU9ERVMpKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworICAgIHVpbnQzMl90IG9sZCA9IG1Sb3V0ZXNbbW9kZV07CisgICAgbVJvdXRlc1ttb2RlXSA9IHJvdXRlczsKKyAgICBpZiAoKG1vZGUgIT0gbU1vZGUpIHx8IChvbGQgPT0gcm91dGVzKSkKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworI2lmIExPR19ST1VUSU5HX0NBTExTCisgICAgY29uc3QgY2hhciogb2xkUm91dGVTdHIgPSBzdHJkdXAoZGlzcGxheVJvdXRlcyhvbGQpKTsKKyAgICBMT0dEKCJkb1JvdXRpbmc6IG1vZGU9JXMsIG9sZCByb3V0ZT1bJXNdLCBuZXcgcm91dGU9WyVzXSIsCisgICAgICAgICAgIGRpc3BsYXlNb2RlKG1vZGUpLCBvbGRSb3V0ZVN0ciwgZGlzcGxheVJvdXRlcyhyb3V0ZXMpKTsKKyAgICBkZWxldGUgb2xkUm91dGVTdHI7CisjZW5kaWYKKyAgICByZXR1cm4gZG9Sb3V0aW5nKCk7Cit9CisKK3N0YXR1c190IEF1ZGlvSGFyZHdhcmVCYXNlOjpnZXRSb3V0aW5nKGludCBtb2RlLCB1aW50MzJfdCogcm91dGVzKQoreworICAgIGlmIChtb2RlID09IEF1ZGlvU3lzdGVtOjpNT0RFX0NVUlJFTlQpCisgICAgICAgIG1vZGUgPSBtTW9kZTsKKyAgICBpZiAoKG1vZGUgPCAwKSB8fCAobW9kZSA+PSBBdWRpb1N5c3RlbTo6TlVNX01PREVTKSkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICAqcm91dGVzID0gbVJvdXRlc1ttb2RlXTsKKyNpZiBMT0dfUk9VVElOR19DQUxMUworICAgIExPR0QoImdldFJvdXRpbmc6IG1vZGU9JXMsIHJvdXRlcz1bJXNdIiwKKyAgICAgICAgICAgZGlzcGxheU1vZGUobW9kZSksIGRpc3BsYXlSb3V0ZXMoKnJvdXRlcykpOworI2VuZGlmCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlQmFzZTo6c2V0TW9kZShpbnQgbW9kZSkKK3sKKyNpZiBMT0dfUk9VVElOR19DQUxMUworICAgIExPR0QoInNldE1vZGUoJXMpIiwgZGlzcGxheU1vZGUobW9kZSkpOworI2VuZGlmCisgICAgaWYgKChtb2RlIDwgMCkgfHwgKG1vZGUgPj0gQXVkaW9TeXN0ZW06Ok5VTV9NT0RFUykpCisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisgICAgaWYgKG1Nb2RlID09IG1vZGUpCisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyNpZiBMT0dfUk9VVElOR19DQUxMUworICAgIExPR0QoImRvUm91dGluZzogb2xkIG1vZGU9JXMsIG5ldyBtb2RlPSVzIHJvdXRlPVslc10iLAorICAgICAgICAgICAgZGlzcGxheU1vZGUobU1vZGUpLCBkaXNwbGF5TW9kZShtb2RlKSwgZGlzcGxheVJvdXRlcyhtUm91dGVzW21vZGVdKSk7CisjZW5kaWYKKyAgICBtTW9kZSA9IG1vZGU7CisgICAgcmV0dXJuIGRvUm91dGluZygpOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlQmFzZTo6Z2V0TW9kZShpbnQqIG1vZGUpCit7CisgICAgLy8gSW1wbGVtZW50OiBzZXQgYXVkaW8gcm91dGluZworICAgICptb2RlID0gbU1vZGU7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlQmFzZTo6c2V0UGFyYW1ldGVyKGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogdmFsdWUpCit7CisgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyB0byBpZ25vcmUKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKworLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorc2l6ZV90IEF1ZGlvSGFyZHdhcmVCYXNlOjpnZXRJbnB1dEJ1ZmZlclNpemUodWludDMyX3Qgc2FtcGxlUmF0ZSwgaW50IGZvcm1hdCwgaW50IGNoYW5uZWxDb3VudCkKK3sKKyAgICBpZiAoc2FtcGxlUmF0ZSAhPSA4MDAwKSB7CisgICAgICAgIExPR1coImdldElucHV0QnVmZmVyU2l6ZSBiYWQgc2FtcGxpbmcgcmF0ZTogJWQiLCBzYW1wbGVSYXRlKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChmb3JtYXQgIT0gQXVkaW9TeXN0ZW06OlBDTV8xNl9CSVQpIHsKKyAgICAgICAgTE9HVygiZ2V0SW5wdXRCdWZmZXJTaXplIGJhZCBmb3JtYXQ6ICVkIiwgZm9ybWF0KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChjaGFubmVsQ291bnQgIT0gMSkgeworICAgICAgICBMT0dXKCJnZXRJbnB1dEJ1ZmZlclNpemUgYmFkIGNoYW5uZWwgY291bnQ6ICVkIiwgY2hhbm5lbENvdW50KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcmV0dXJuIDMyMDsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZUJhc2U6OmR1bXBTdGF0ZShpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiQXVkaW9IYXJkd2FyZUJhc2U6OmR1bXBTdGF0ZVxuIik7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0bU1vZGU6ICVkXG4iLCBtTW9kZSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIGZvciAoaW50IGkgPSAwLCBuID0gQXVkaW9TeXN0ZW06Ok5VTV9NT0RFUzsgaSA8IG47ICsraSkgeworICAgICAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdG1Sb3V0ZXNbJWRdOiAlZFxuIiwgaSwgbVJvdXRlc1tpXSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICB9CisgICAgOjp3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICBkdW1wKGZkLCBhcmdzKTsgIC8vIER1bXAgdGhlIHN0YXRlIG9mIHRoZSBjb25jcmV0ZSBjaGlsZC4KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVTdHViLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVTdHViLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTNjYjFjCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9IYXJkd2FyZVN0dWIuY3BwCkBAIC0wLDAgKzEsMTg1IEBACisvKiAvL2RldmljZS9zZXJ2ZXJzL0F1ZGlvRmxpbmdlci9BdWRpb0hhcmR3YXJlU3R1Yi5jcHAKKyoqCisqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorCisjaW5jbHVkZSAiQXVkaW9IYXJkd2FyZVN0dWIuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0F1ZGlvSGFyZHdhcmVTdHViOjpBdWRpb0hhcmR3YXJlU3R1YigpIDogbU1pY011dGUoZmFsc2UpCit7Cit9CisKK0F1ZGlvSGFyZHdhcmVTdHViOjp+QXVkaW9IYXJkd2FyZVN0dWIoKQoreworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlU3R1Yjo6aW5pdENoZWNrKCkKK3sKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK0F1ZGlvU3RyZWFtT3V0KiBBdWRpb0hhcmR3YXJlU3R1Yjo6b3Blbk91dHB1dFN0cmVhbSgKKyAgICAgICAgaW50IGZvcm1hdCwgaW50IGNoYW5uZWxDb3VudCwgdWludDMyX3Qgc2FtcGxlUmF0ZSwgc3RhdHVzX3QgKnN0YXR1cykKK3sKKyAgICBBdWRpb1N0cmVhbU91dFN0dWIqIG91dCA9IG5ldyBBdWRpb1N0cmVhbU91dFN0dWIoKTsKKyAgICBzdGF0dXNfdCBsU3RhdHVzID0gb3V0LT5zZXQoZm9ybWF0LCBjaGFubmVsQ291bnQsIHNhbXBsZVJhdGUpOworICAgIGlmIChzdGF0dXMpIHsKKyAgICAgICAgKnN0YXR1cyA9IGxTdGF0dXM7CisgICAgfQorICAgIGlmIChsU3RhdHVzID09IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gb3V0OworICAgIGRlbGV0ZSBvdXQ7CisgICAgcmV0dXJuIDA7Cit9CisKK0F1ZGlvU3RyZWFtSW4qIEF1ZGlvSGFyZHdhcmVTdHViOjpvcGVuSW5wdXRTdHJlYW0oCisgICAgICAgIGludCBmb3JtYXQsIGludCBjaGFubmVsQ291bnQsIHVpbnQzMl90IHNhbXBsZVJhdGUsCisgICAgICAgIHN0YXR1c190ICpzdGF0dXMsIEF1ZGlvU3lzdGVtOjphdWRpb19pbl9hY291c3RpY3MgYWNvdXN0aWNzKQoreworICAgIEF1ZGlvU3RyZWFtSW5TdHViKiBpbiA9IG5ldyBBdWRpb1N0cmVhbUluU3R1YigpOworICAgIHN0YXR1c190IGxTdGF0dXMgPSBpbi0+c2V0KGZvcm1hdCwgY2hhbm5lbENvdW50LCBzYW1wbGVSYXRlLCBhY291c3RpY3MpOworICAgIGlmIChzdGF0dXMpIHsKKyAgICAgICAgKnN0YXR1cyA9IGxTdGF0dXM7CisgICAgfQorICAgIGlmIChsU3RhdHVzID09IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gaW47CisgICAgZGVsZXRlIGluOworICAgIHJldHVybiAwOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlU3R1Yjo6c2V0Vm9pY2VWb2x1bWUoZmxvYXQgdm9sdW1lKQoreworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgQXVkaW9IYXJkd2FyZVN0dWI6OnNldE1hc3RlclZvbHVtZShmbG9hdCB2b2x1bWUpCit7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb0hhcmR3YXJlU3R1Yjo6ZHVtcEludGVybmFscyhpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgcmVzdWx0LmFwcGVuZCgiQXVkaW9IYXJkd2FyZVN0dWI6OmR1bXBJbnRlcm5hbHNcbiIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0bU1pY011dGU6ICVzXG4iLCBtTWljTXV0ZT8gInRydWUiOiAiZmFsc2UiKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgOjp3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IEF1ZGlvSGFyZHdhcmVTdHViOjpkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBkdW1wSW50ZXJuYWxzKGZkLCBhcmdzKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdHVzX3QgQXVkaW9TdHJlYW1PdXRTdHViOjpzZXQoaW50IGZvcm1hdCwgaW50IGNoYW5uZWxzLCB1aW50MzJfdCByYXRlKQoreworICAgIC8vIGZpeCB1cCBkZWZhdWx0cworICAgIGlmIChmb3JtYXQgPT0gMCkgZm9ybWF0ID0gQXVkaW9TeXN0ZW06OlBDTV8xNl9CSVQ7CisgICAgaWYgKGNoYW5uZWxzID09IDApIGNoYW5uZWxzID0gY2hhbm5lbENvdW50KCk7CisgICAgaWYgKHJhdGUgPT0gMCkgcmF0ZSA9IHNhbXBsZVJhdGUoKTsKKworICAgIGlmICgoZm9ybWF0ID09IEF1ZGlvU3lzdGVtOjpQQ01fMTZfQklUKSAmJgorICAgICAgICAgICAgKGNoYW5uZWxzID09IGNoYW5uZWxDb3VudCgpKSAmJgorICAgICAgICAgICAgKHJhdGUgPT0gc2FtcGxlUmF0ZSgpKSkKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIHJldHVybiBCQURfVkFMVUU7Cit9CisKK3NzaXplX3QgQXVkaW9TdHJlYW1PdXRTdHViOjp3cml0ZShjb25zdCB2b2lkKiBidWZmZXIsIHNpemVfdCBieXRlcykKK3sKKyAgICAvLyBmYWtlIHRpbWluZyBmb3IgYXVkaW8gb3V0cHV0CisgICAgdXNsZWVwKGJ5dGVzICogMTAwMDAwMCAvIHNpemVvZihpbnQxNl90KSAvIGNoYW5uZWxDb3VudCgpIC8gc2FtcGxlUmF0ZSgpKTsKKyAgICByZXR1cm4gYnl0ZXM7Cit9CisKK3N0YXR1c190IEF1ZGlvU3RyZWFtT3V0U3R1Yjo6c3RhbmRieSgpCit7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb1N0cmVhbU91dFN0dWI6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGNvbnN0IHNpemVfdCBTSVpFID0gMjU2OworICAgIGNoYXIgYnVmZmVyW1NJWkVdOworICAgIFN0cmluZzggcmVzdWx0OworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIkF1ZGlvU3RyZWFtT3V0U3R1Yjo6ZHVtcFxuIik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRzYW1wbGUgcmF0ZTogJWRcbiIsIHNhbXBsZVJhdGUoKSk7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRidWZmZXIgc2l6ZTogJWRcbiIsIGJ1ZmZlclNpemUoKSk7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRjaGFubmVsIGNvdW50OiAlZFxuIiwgY2hhbm5lbENvdW50KCkpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0Zm9ybWF0OiAlZFxuIiwgZm9ybWF0KCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICA6OndyaXRlKGZkLCByZXN1bHQuc3RyaW5nKCksIHJlc3VsdC5zaXplKCkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0dXNfdCBBdWRpb1N0cmVhbUluU3R1Yjo6c2V0KGludCBmb3JtYXQsIGludCBjaGFubmVscywgdWludDMyX3QgcmF0ZSwKKwkJCQlBdWRpb1N5c3RlbTo6YXVkaW9faW5fYWNvdXN0aWNzIGFjb3VzdGljcykKK3sKKyAgICBpZiAoKGZvcm1hdCA9PSBBdWRpb1N5c3RlbTo6UENNXzE2X0JJVCkgJiYKKyAgICAgICAgICAgIChjaGFubmVscyA9PSBjaGFubmVsQ291bnQoKSkgJiYKKyAgICAgICAgICAgIChyYXRlID09IHNhbXBsZVJhdGUoKSkpCisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICByZXR1cm4gQkFEX1ZBTFVFOworfQorCitzc2l6ZV90IEF1ZGlvU3RyZWFtSW5TdHViOjpyZWFkKHZvaWQqIGJ1ZmZlciwgc3NpemVfdCBieXRlcykKK3sKKyAgICAvLyBmYWtlIHRpbWluZyBmb3IgYXVkaW8gaW5wdXQKKyAgICB1c2xlZXAoYnl0ZXMgKiAxMDAwMDAwIC8gc2l6ZW9mKGludDE2X3QpIC8gY2hhbm5lbENvdW50KCkgLyBzYW1wbGVSYXRlKCkpOworICAgIG1lbXNldChidWZmZXIsIDAsIGJ5dGVzKTsKKyAgICByZXR1cm4gYnl0ZXM7Cit9CisKK3N0YXR1c190IEF1ZGlvU3RyZWFtSW5TdHViOjpkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncykKK3sKKyAgICBjb25zdCBzaXplX3QgU0laRSA9IDI1NjsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJBdWRpb1N0cmVhbUluU3R1Yjo6ZHVtcFxuIik7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlx0c2FtcGxlIHJhdGU6ICVkXG4iLCBzYW1wbGVSYXRlKCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdGJ1ZmZlciBzaXplOiAlZFxuIiwgYnVmZmVyU2l6ZSgpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiXHRjaGFubmVsIGNvdW50OiAlZFxuIiwgY2hhbm5lbENvdW50KCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBzbnByaW50ZihidWZmZXIsIFNJWkUsICJcdGZvcm1hdDogJWRcbiIsIGZvcm1hdCgpKTsKKyAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgOjp3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvSGFyZHdhcmVTdHViLmggYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0hhcmR3YXJlU3R1Yi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0MDY0MjQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb0hhcmR3YXJlU3R1Yi5oCkBAIC0wLDAgKzEsMTAwIEBACisvKiAvL2RldmljZS9zZXJ2ZXJzL0F1ZGlvRmxpbmdlci9BdWRpb0hhcmR3YXJlU3R1Yi5oCisqKgorKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9BVURJT19IQVJEV0FSRV9TVFVCX0gKKyNkZWZpbmUgQU5EUk9JRF9BVURJT19IQVJEV0FSRV9TVFVCX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8aGFyZHdhcmVfbGVnYWN5L0F1ZGlvSGFyZHdhcmVCYXNlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBBdWRpb1N0cmVhbU91dFN0dWIgOiBwdWJsaWMgQXVkaW9TdHJlYW1PdXQgeworcHVibGljOgorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0KGludCBmb3JtYXQsIGludCBjaGFubmVsQ291bnQsIHVpbnQzMl90IHNhbXBsZVJhdGUpOworICAgIHZpcnR1YWwgdWludDMyX3QgICAgc2FtcGxlUmF0ZSgpIGNvbnN0IHsgcmV0dXJuIDQ0MTAwOyB9CisgICAgdmlydHVhbCBzaXplX3QgICAgICBidWZmZXJTaXplKCkgY29uc3QgeyByZXR1cm4gNDA5NjsgfQorICAgIHZpcnR1YWwgaW50ICAgICAgICAgY2hhbm5lbENvdW50KCkgY29uc3QgeyByZXR1cm4gMjsgfQorICAgIHZpcnR1YWwgaW50ICAgICAgICAgZm9ybWF0KCkgY29uc3QgeyByZXR1cm4gQXVkaW9TeXN0ZW06OlBDTV8xNl9CSVQ7IH0KKyAgICB2aXJ0dWFsIHVpbnQzMl90ICAgIGxhdGVuY3koKSBjb25zdCB7IHJldHVybiAwOyB9CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRWb2x1bWUoZmxvYXQgdm9sdW1lKSB7IHJldHVybiBOT19FUlJPUjsgfQorICAgIHZpcnR1YWwgc3NpemVfdCAgICAgd3JpdGUoY29uc3Qgdm9pZCogYnVmZmVyLCBzaXplX3QgYnl0ZXMpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc3RhbmRieSgpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpOworfTsKKworY2xhc3MgQXVkaW9TdHJlYW1JblN0dWIgOiBwdWJsaWMgQXVkaW9TdHJlYW1JbiB7CitwdWJsaWM6CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXQoaW50IGZvcm1hdCwgaW50IGNoYW5uZWxDb3VudCwgdWludDMyX3Qgc2FtcGxlUmF0ZSwgQXVkaW9TeXN0ZW06OmF1ZGlvX2luX2Fjb3VzdGljcyBhY291c3RpY3MpOworICAgIHZpcnR1YWwgdWludDMyX3QgICAgc2FtcGxlUmF0ZSgpIGNvbnN0IHsgcmV0dXJuIDgwMDA7IH0KKyAgICB2aXJ0dWFsIHNpemVfdCAgICAgIGJ1ZmZlclNpemUoKSBjb25zdCB7IHJldHVybiAzMjA7IH0KKyAgICB2aXJ0dWFsIGludCAgICAgICAgIGNoYW5uZWxDb3VudCgpIGNvbnN0IHsgcmV0dXJuIDE7IH0KKyAgICB2aXJ0dWFsIGludCAgICAgICAgIGZvcm1hdCgpIGNvbnN0IHsgcmV0dXJuIEF1ZGlvU3lzdGVtOjpQQ01fMTZfQklUOyB9CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRHYWluKGZsb2F0IGdhaW4pIHsgcmV0dXJuIE5PX0VSUk9SOyB9CisgICAgdmlydHVhbCBzc2l6ZV90ICAgICByZWFkKHZvaWQqIGJ1ZmZlciwgc3NpemVfdCBieXRlcyk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzdGFuZGJ5KCkgeyByZXR1cm4gTk9fRVJST1I7IH0KK307CisKK2NsYXNzIEF1ZGlvSGFyZHdhcmVTdHViIDogcHVibGljICBBdWRpb0hhcmR3YXJlQmFzZQoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9IYXJkd2FyZVN0dWIoKTsKKyAgICB2aXJ0dWFsICAgICAgICAgICAgIH5BdWRpb0hhcmR3YXJlU3R1YigpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgaW5pdENoZWNrKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBzZXRWb2ljZVZvbHVtZShmbG9hdCB2b2x1bWUpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0TWFzdGVyVm9sdW1lKGZsb2F0IHZvbHVtZSk7CisKKyAgICAvLyBtaWMgbXV0ZQorICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgc2V0TWljTXV0ZShib29sIHN0YXRlKSB7IG1NaWNNdXRlID0gc3RhdGU7ICByZXR1cm4gIE5PX0VSUk9SOyB9CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBnZXRNaWNNdXRlKGJvb2wqIHN0YXRlKSB7ICpzdGF0ZSA9IG1NaWNNdXRlIDsgcmV0dXJuIE5PX0VSUk9SOyB9CisKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIHNldFBhcmFtZXRlcihjb25zdCBjaGFyKiBrZXksIGNvbnN0IGNoYXIqIHZhbHVlKQorICAgICAgICAgICAgeyByZXR1cm4gTk9fRVJST1I7IH0KKworICAgIC8vIGNyZWF0ZSBJL08gc3RyZWFtcworICAgIHZpcnR1YWwgQXVkaW9TdHJlYW1PdXQqIG9wZW5PdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmb3JtYXQ9MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudD0wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBzYW1wbGVSYXRlPTAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c190ICpzdGF0dXM9MCk7CisKKyAgICB2aXJ0dWFsIEF1ZGlvU3RyZWFtSW4qIG9wZW5JbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoYW5uZWxDb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3Qgc2FtcGxlUmF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX3QgKnN0YXR1cywKKwkJCQlBdWRpb1N5c3RlbTo6YXVkaW9faW5fYWNvdXN0aWNzIGFjb3VzdGljcyk7CisKK3Byb3RlY3RlZDoKKyAgICB2aXJ0dWFsIHN0YXR1c190ICAgIGRvUm91dGluZygpIHsgcmV0dXJuIE5PX0VSUk9SOyB9CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICBkdW1wKGludCBmZCwgY29uc3QgVmVjdG9yPFN0cmluZzE2PiYgYXJncyk7CisKKyAgICAgICAgICAgIGJvb2wgICAgICAgIG1NaWNNdXRlOworcHJpdmF0ZToKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIGR1bXBJbnRlcm5hbHMoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfQVVESU9fSEFSRFdBUkVfU1RVQl9ICmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb01peGVyLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvTWl4ZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwMzQ2N2YKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb01peGVyLmNwcApAQCAtMCwwICsxLDkxMyBAQAorLyogLy9kZXZpY2UvaW5jbHVkZS9zZXJ2ZXIvQXVkaW9GbGluZ2VyL0F1ZGlvTWl4ZXIuY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNkZWZpbmUgTE9HX1RBRyAiQXVkaW9NaXhlciIKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlICJBdWRpb01peGVyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGlubGluZSBpbnQxNl90IGNsYW1wMTYoaW50MzJfdCBzYW1wbGUpCit7CisgICAgaWYgKChzYW1wbGU+PjE1KSBeIChzYW1wbGU+PjMxKSkKKyAgICAgICAgc2FtcGxlID0gMHg3RkZGIF4gKHNhbXBsZT4+MzEpOworICAgIHJldHVybiBzYW1wbGU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXVkaW9NaXhlcjo6QXVkaW9NaXhlcihzaXplX3QgZnJhbWVDb3VudCwgdWludDMyX3Qgc2FtcGxlUmF0ZSkKKyAgICA6ICAgbUFjdGl2ZVRyYWNrKDApLCBtVHJhY2tOYW1lcygwKSwgbVNhbXBsZVJhdGUoc2FtcGxlUmF0ZSkKK3sKKyAgICBtU3RhdGUuZW5hYmxlZFRyYWNrcz0gMDsKKyAgICBtU3RhdGUubmVlZHNDaGFuZ2VkID0gMDsKKyAgICBtU3RhdGUuZnJhbWVDb3VudCAgID0gZnJhbWVDb3VudDsKKyAgICBtU3RhdGUub3V0cHV0VGVtcCAgID0gMDsKKyAgICBtU3RhdGUucmVzYW1wbGVUZW1wID0gMDsKKyAgICBtU3RhdGUuaG9vayAgICAgICAgID0gcHJvY2Vzc19fbm9wOworICAgIHRyYWNrX3QqIHQgPSBtU3RhdGUudHJhY2tzOworICAgIGZvciAoaW50IGk9MCA7IGk8MzIgOyBpKyspIHsKKyAgICAgICAgdC0+bmVlZHMgPSAwOworICAgICAgICB0LT52b2x1bWVbMF0gPSBVTklUWV9HQUlOOworICAgICAgICB0LT52b2x1bWVbMV0gPSBVTklUWV9HQUlOOworICAgICAgICB0LT52b2x1bWVJbmNbMF0gPSAwOworICAgICAgICB0LT52b2x1bWVJbmNbMV0gPSAwOworICAgICAgICB0LT5jaGFubmVsQ291bnQgPSAyOworICAgICAgICB0LT5lbmFibGVkID0gMDsKKyAgICAgICAgdC0+Zm9ybWF0ID0gMTY7CisgICAgICAgIHQtPmJ1ZmZlci5yYXcgPSAwOworICAgICAgICB0LT5idWZmZXJQcm92aWRlciA9IDA7CisgICAgICAgIHQtPmhvb2sgPSAwOworICAgICAgICB0LT5yZXNhbXBsZXIgPSAwOworICAgICAgICB0LT5zYW1wbGVSYXRlID0gbVNhbXBsZVJhdGU7CisgICAgICAgIHQtPmluID0gMDsKKyAgICAgICAgdCsrOworICAgIH0KK30KKworIEF1ZGlvTWl4ZXI6On5BdWRpb01peGVyKCkKKyB7CisgICAgIHRyYWNrX3QqIHQgPSBtU3RhdGUudHJhY2tzOworICAgICBmb3IgKGludCBpPTAgOyBpPDMyIDsgaSsrKSB7CisgICAgICAgICBkZWxldGUgdC0+cmVzYW1wbGVyOworICAgICAgICAgdCsrOworICAgICB9CisgICAgIGRlbGV0ZSBbXSBtU3RhdGUub3V0cHV0VGVtcDsKKyAgICAgZGVsZXRlIFtdIG1TdGF0ZS5yZXNhbXBsZVRlbXA7CisgfQorCisgaW50IEF1ZGlvTWl4ZXI6OmdldFRyYWNrTmFtZSgpCisgeworICAgIHVpbnQzMl90IG5hbWVzID0gbVRyYWNrTmFtZXM7CisgICAgdWludDMyX3QgbWFzayA9IDE7CisgICAgaW50IG4gPSAwOworICAgIHdoaWxlIChuYW1lcyAmIG1hc2spIHsKKyAgICAgICAgbWFzayA8PD0gMTsKKyAgICAgICAgbisrOworICAgIH0KKyAgICBpZiAobWFzaykgeworICAgICAgICBMT0dWKCJhZGQgdHJhY2sgKCVkKSIsIG4pOworICAgICAgICBtVHJhY2tOYW1lcyB8PSBtYXNrOworICAgICAgICByZXR1cm4gVFJBQ0swICsgbjsKKyAgICB9CisgICAgcmV0dXJuIC0xOworIH0KKworIHZvaWQgQXVkaW9NaXhlcjo6aW52YWxpZGF0ZVN0YXRlKHVpbnQzMl90IG1hc2spCisgeworICAgIGlmIChtYXNrKSB7CisgICAgICAgIG1TdGF0ZS5uZWVkc0NoYW5nZWQgfD0gbWFzazsKKyAgICAgICAgbVN0YXRlLmhvb2sgPSBwcm9jZXNzX192YWxpZGF0ZTsKKyAgICB9CisgfQorCisgdm9pZCBBdWRpb01peGVyOjpkZWxldGVUcmFja05hbWUoaW50IG5hbWUpCisgeworICAgIG5hbWUgLT0gVFJBQ0swOworICAgIGlmICh1aW50MzJfdChuYW1lKSA8IE1BWF9OVU1fVFJBQ0tTKSB7CisgICAgICAgIExPR1YoImRlbGV0ZVRyYWNrTmFtZSglZCkiLCBuYW1lKTsKKyAgICAgICAgdHJhY2tfdCYgdHJhY2sobVN0YXRlLnRyYWNrc1sgbmFtZSBdKTsKKyAgICAgICAgaWYgKHRyYWNrLmVuYWJsZWQgIT0gMCkgeworICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IDA7CisgICAgICAgICAgICBpbnZhbGlkYXRlU3RhdGUoMTw8bmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRyYWNrLnJlc2FtcGxlcikgeworICAgICAgICAgICAgLy8gZGVsZXRlICB0aGUgcmVzYW1wbGVyCisgICAgICAgICAgICBkZWxldGUgdHJhY2sucmVzYW1wbGVyOworICAgICAgICAgICAgdHJhY2sucmVzYW1wbGVyID0gMDsKKyAgICAgICAgICAgIHRyYWNrLnNhbXBsZVJhdGUgPSBtU2FtcGxlUmF0ZTsKKyAgICAgICAgICAgIGludmFsaWRhdGVTdGF0ZSgxPDxuYW1lKTsKKyAgICAgICAgfQorICAgICAgICB0cmFjay52b2x1bWVJbmNbMF0gPSAwOworICAgICAgICB0cmFjay52b2x1bWVJbmNbMV0gPSAwOworICAgICAgICBtVHJhY2tOYW1lcyAmPSB+KDE8PG5hbWUpOworICAgIH0KKyB9CisKK3N0YXR1c190IEF1ZGlvTWl4ZXI6OmVuYWJsZShpbnQgbmFtZSkKK3sKKyAgICBzd2l0Y2ggKG5hbWUpIHsKKyAgICAgICAgY2FzZSBNSVhJTkc6IHsKKyAgICAgICAgICAgIGlmIChtU3RhdGUudHJhY2tzWyBtQWN0aXZlVHJhY2sgXS5lbmFibGVkICE9IDEpIHsKKyAgICAgICAgICAgICAgICBtU3RhdGUudHJhY2tzWyBtQWN0aXZlVHJhY2sgXS5lbmFibGVkID0gMTsKKyAgICAgICAgICAgICAgICBMT0dWKCJlbmFibGUoJWQpIiwgbUFjdGl2ZVRyYWNrKTsKKyAgICAgICAgICAgICAgICBpbnZhbGlkYXRlU3RhdGUoMTw8bUFjdGl2ZVRyYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBOQU1FX05PVF9GT1VORDsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb01peGVyOjpkaXNhYmxlKGludCBuYW1lKQoreworICAgIHN3aXRjaCAobmFtZSkgeworICAgICAgICBjYXNlIE1JWElORzogeworICAgICAgICAgICAgaWYgKG1TdGF0ZS50cmFja3NbIG1BY3RpdmVUcmFjayBdLmVuYWJsZWQgIT0gMCkgeworICAgICAgICAgICAgICAgIG1TdGF0ZS50cmFja3NbIG1BY3RpdmVUcmFjayBdLmVuYWJsZWQgPSAwOworICAgICAgICAgICAgICAgIExPR1YoImRpc2FibGUoJWQpIiwgbUFjdGl2ZVRyYWNrKTsKKyAgICAgICAgICAgICAgICBpbnZhbGlkYXRlU3RhdGUoMTw8bUFjdGl2ZVRyYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBOQU1FX05PVF9GT1VORDsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb01peGVyOjpzZXRBY3RpdmVUcmFjayhpbnQgdHJhY2spCit7CisgICAgaWYgKHVpbnQzMl90KHRyYWNrLVRSQUNLMCkgPj0gTUFYX05VTV9UUkFDS1MpIHsKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB9CisgICAgbUFjdGl2ZVRyYWNrID0gdHJhY2sgLSBUUkFDSzA7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBBdWRpb01peGVyOjpzZXRQYXJhbWV0ZXIoaW50IHRhcmdldCwgaW50IG5hbWUsIGludCB2YWx1ZSkKK3sKKyAgICBzd2l0Y2ggKHRhcmdldCkgeworICAgIGNhc2UgVFJBQ0s6CisgICAgICAgIGlmIChuYW1lID09IENIQU5ORUxfQ09VTlQpIHsKKyAgICAgICAgICAgIGlmICgodWludDMyX3QodmFsdWUpIDw9IE1BWF9OVU1fQ0hBTk5FTFMpICYmICh2YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAobVN0YXRlLnRyYWNrc1sgbUFjdGl2ZVRyYWNrIF0uY2hhbm5lbENvdW50ICE9IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgIG1TdGF0ZS50cmFja3NbIG1BY3RpdmVUcmFjayBdLmNoYW5uZWxDb3VudCA9IHZhbHVlOworICAgICAgICAgICAgICAgICAgICBMT0dWKCJzZXRQYXJhbWV0ZXIoVFJBQ0ssIENIQU5ORUxfQ09VTlQsICVkKSIsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgaW52YWxpZGF0ZVN0YXRlKDE8PG1BY3RpdmVUcmFjayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICBjYXNlIFJFU0FNUExFOgorICAgICAgICBpZiAobmFtZSA9PSBTQU1QTEVfUkFURSkgeworICAgICAgICAgICAgaWYgKHZhbHVlID4gMCkgeworICAgICAgICAgICAgICAgIHRyYWNrX3QmIHRyYWNrID0gbVN0YXRlLnRyYWNrc1sgbUFjdGl2ZVRyYWNrIF07CisgICAgICAgICAgICAgICAgaWYgKHRyYWNrLnNldFJlc2FtcGxlcih1aW50MzJfdCh2YWx1ZSksIG1TYW1wbGVSYXRlKSkgeworICAgICAgICAgICAgICAgICAgICBMT0dWKCJzZXRQYXJhbWV0ZXIoUkVTQU1QTEUsIFNBTVBMRV9SQVRFLCAldSkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90KHZhbHVlKSk7CisgICAgICAgICAgICAgICAgICAgIGludmFsaWRhdGVTdGF0ZSgxPDxtQWN0aXZlVHJhY2spOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBSQU1QX1ZPTFVNRToKKyAgICBjYXNlIFZPTFVNRToKKyAgICAgICAgaWYgKCh1aW50MzJfdChuYW1lLVZPTFVNRTApIDwgTUFYX05VTV9DSEFOTkVMUykpIHsKKyAgICAgICAgICAgIHRyYWNrX3QmIHRyYWNrID0gbVN0YXRlLnRyYWNrc1sgbUFjdGl2ZVRyYWNrIF07CisgICAgICAgICAgICBpZiAodHJhY2sudm9sdW1lW25hbWUtVk9MVU1FMF0gIT0gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICB0cmFjay5wcmV2Vm9sdW1lW25hbWUtVk9MVU1FMF0gPSB0cmFjay52b2x1bWVbbmFtZS1WT0xVTUUwXSA8PCAxNjsKKyAgICAgICAgICAgICAgICB0cmFjay52b2x1bWVbbmFtZS1WT0xVTUUwXSA9IHZhbHVlOworICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgPT0gVk9MVU1FKSB7CisgICAgICAgICAgICAgICAgICAgIHRyYWNrLnByZXZWb2x1bWVbbmFtZS1WT0xVTUUwXSA9IHZhbHVlIDw8IDE2OworICAgICAgICAgICAgICAgICAgICB0cmFjay52b2x1bWVJbmNbbmFtZS1WT0xVTUUwXSA9IDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBkID0gKHZhbHVlPDwxNikgLSB0cmFjay5wcmV2Vm9sdW1lW25hbWUtVk9MVU1FMF07CisgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgdm9sSW5jID0gZCAvIGludDMyX3QobVN0YXRlLmZyYW1lQ291bnQpOworICAgICAgICAgICAgICAgICAgICB0cmFjay52b2x1bWVJbmNbbmFtZS1WT0xVTUUwXSA9IHZvbEluYzsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHZvbEluYyA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5wcmV2Vm9sdW1lW25hbWUtVk9MVU1FMF0gPSB2YWx1ZSA8PCAxNjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnZhbGlkYXRlU3RhdGUoMTw8bUFjdGl2ZVRyYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgICAgcmV0dXJuIEJBRF9WQUxVRTsKK30KKworYm9vbCBBdWRpb01peGVyOjp0cmFja190OjpzZXRSZXNhbXBsZXIodWludDMyX3QgdmFsdWUsIHVpbnQzMl90IGRldlNhbXBsZVJhdGUpCit7CisgICAgaWYgKHZhbHVlIT1kZXZTYW1wbGVSYXRlIHx8IHJlc2FtcGxlcikgeworICAgICAgICBpZiAoc2FtcGxlUmF0ZSAhPSB2YWx1ZSkgeworICAgICAgICAgICAgc2FtcGxlUmF0ZSA9IHZhbHVlOworICAgICAgICAgICAgaWYgKHJlc2FtcGxlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmVzYW1wbGVyID0gQXVkaW9SZXNhbXBsZXI6OmNyZWF0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCwgY2hhbm5lbENvdW50LCBkZXZTYW1wbGVSYXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBBdWRpb01peGVyOjp0cmFja190Ojpkb2VzUmVzYW1wbGUoKSBjb25zdAoreworICAgIHJldHVybiByZXNhbXBsZXIgIT0gMDsKK30KKworaW5saW5lCit2b2lkIEF1ZGlvTWl4ZXI6OnRyYWNrX3Q6OmFkanVzdFZvbHVtZVJhbXAoKQoreworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBpZiAoKCh2b2x1bWVJbmNbaV0+MCkgJiYgKCgocHJldlZvbHVtZVtpXSt2b2x1bWVJbmNbaV0pPj4xNikgPj0gdm9sdW1lW2ldKSkgfHwKKyAgICAgICAgICAgICgodm9sdW1lSW5jW2ldPDApICYmICgoKHByZXZWb2x1bWVbaV0rdm9sdW1lSW5jW2ldKT4+MTYpIDw9IHZvbHVtZVtpXSkpKSB7CisgICAgICAgICAgICB2b2x1bWVJbmNbaV0gPSAwOworICAgICAgICAgICAgcHJldlZvbHVtZVtpXSA9IHZvbHVtZVtpXTw8MTY7CisgICAgICAgIH0KKyAgICB9Cit9CisKKworc3RhdHVzX3QgQXVkaW9NaXhlcjo6c2V0QnVmZmVyUHJvdmlkZXIoQXVkaW9CdWZmZXJQcm92aWRlciogYnVmZmVyKQoreworICAgIG1TdGF0ZS50cmFja3NbIG1BY3RpdmVUcmFjayBdLmJ1ZmZlclByb3ZpZGVyID0gYnVmZmVyOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworCisKK3ZvaWQgQXVkaW9NaXhlcjo6cHJvY2Vzcyh2b2lkKiBvdXRwdXQpCit7CisgICAgbVN0YXRlLmhvb2soJm1TdGF0ZSwgb3V0cHV0KTsKK30KKworCit2b2lkIEF1ZGlvTWl4ZXI6OnByb2Nlc3NfX3ZhbGlkYXRlKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpCit7CisgICAgTE9HV19JRighc3RhdGUtPm5lZWRzQ2hhbmdlZCwKKyAgICAgICAgImluIHByb2Nlc3NfX3ZhbGlkYXRlKCkgYnV0IG5vdGhpbmcncyBpbnZhbGlkIik7CisKKyAgICB1aW50MzJfdCBjaGFuZ2VkID0gc3RhdGUtPm5lZWRzQ2hhbmdlZDsKKyAgICBzdGF0ZS0+bmVlZHNDaGFuZ2VkID0gMDsgLy8gY2xlYXIgdGhlIHZhbGlkYXRpb24gZmxhZworCisgICAgLy8gcmVjb21wdXRlIHdoaWNoIHRyYWNrcyBhcmUgZW5hYmxlZCAvIGRpc2FibGVkCisgICAgdWludDMyX3QgZW5hYmxlZCA9IDA7CisgICAgdWludDMyX3QgZGlzYWJsZWQgPSAwOworICAgIHdoaWxlIChjaGFuZ2VkKSB7CisgICAgICAgIGNvbnN0IGludCBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGNoYW5nZWQpOworICAgICAgICBjb25zdCB1aW50MzJfdCBtYXNrID0gMTw8aTsKKyAgICAgICAgY2hhbmdlZCAmPSB+bWFzazsKKyAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgICh0LmVuYWJsZWQgPyBlbmFibGVkIDogZGlzYWJsZWQpIHw9IG1hc2s7CisgICAgfQorICAgIHN0YXRlLT5lbmFibGVkVHJhY2tzICY9IH5kaXNhYmxlZDsKKyAgICBzdGF0ZS0+ZW5hYmxlZFRyYWNrcyB8PSAgZW5hYmxlZDsKKworICAgIC8vIGNvbXB1dGUgZXZlcnl0aGluZyB3ZSBuZWVkLi4uCisgICAgaW50IGNvdW50QWN0aXZlVHJhY2tzID0gMDsKKyAgICBpbnQgYWxsMTZCaXRzU3RlcmVvTm9SZXNhbXBsZSA9IDE7CisgICAgaW50IHJlc2FtcGxpbmcgPSAwOworICAgIGludCB2b2x1bWVSYW1wID0gMDsKKyAgICB1aW50MzJfdCBlbiA9IHN0YXRlLT5lbmFibGVkVHJhY2tzOworICAgIHdoaWxlIChlbikgeworICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gX19idWlsdGluX2Nseihlbik7CisgICAgICAgIGVuICY9IH4oMTw8aSk7CisKKyAgICAgICAgY291bnRBY3RpdmVUcmFja3MrKzsKKyAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgIHVpbnQzMl90IG4gPSAwOworICAgICAgICBuIHw9IE5FRURTX0NIQU5ORUxfMSArIHQuY2hhbm5lbENvdW50IC0gMTsKKyAgICAgICAgbiB8PSBORUVEU19GT1JNQVRfMTY7CisgICAgICAgIG4gfD0gdC5kb2VzUmVzYW1wbGUoKSA/IE5FRURTX1JFU0FNUExFX0VOQUJMRUQgOiBORUVEU19SRVNBTVBMRV9ESVNBQkxFRDsKKyAgICAgICAKKyAgICAgICAgaWYgKHQudm9sdW1lSW5jWzBdfHQudm9sdW1lSW5jWzFdKSB7CisgICAgICAgICAgICB2b2x1bWVSYW1wID0gMTsKKyAgICAgICAgfSBlbHNlIGlmICghdC5kb2VzUmVzYW1wbGUoKSAmJiB0LnZvbHVtZVJMID09IDApIHsKKyAgICAgICAgICAgIG4gfD0gTkVFRFNfTVVURV9FTkFCTEVEOworICAgICAgICB9CisgICAgICAgIHQubmVlZHMgPSBuOworCisgICAgICAgIGlmICgobiAmIE5FRURTX01VVEVfX01BU0spID09IE5FRURTX01VVEVfRU5BQkxFRCkgeworICAgICAgICAgICAgdC5ob29rID0gdHJhY2tfX25vcDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICgobiAmIE5FRURTX1JFU0FNUExFX19NQVNLKSA9PSBORUVEU19SRVNBTVBMRV9FTkFCTEVEKSB7CisgICAgICAgICAgICAgICAgYWxsMTZCaXRzU3RlcmVvTm9SZXNhbXBsZSA9IDA7CisgICAgICAgICAgICAgICAgcmVzYW1wbGluZyA9IDE7CisgICAgICAgICAgICAgICAgdC5ob29rID0gdHJhY2tfX2dlbmVyaWNSZXNhbXBsZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKChuICYgTkVFRFNfQ0hBTk5FTF9DT1VOVF9fTUFTSykgPT0gTkVFRFNfQ0hBTk5FTF8xKXsKKyAgICAgICAgICAgICAgICAgICAgdC5ob29rID0gdHJhY2tfXzE2Qml0c01vbm87CisgICAgICAgICAgICAgICAgICAgIGFsbDE2Qml0c1N0ZXJlb05vUmVzYW1wbGUgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKG4gJiBORUVEU19DSEFOTkVMX0NPVU5UX19NQVNLKSA9PSBORUVEU19DSEFOTkVMXzIpeworICAgICAgICAgICAgICAgICAgICB0Lmhvb2sgPSB0cmFja19fMTZCaXRzU3RlcmVvOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHNlbGVjdCB0aGUgcHJvY2Vzc2luZyBob29rcworICAgIHN0YXRlLT5ob29rID0gcHJvY2Vzc19fbm9wOworICAgIGlmIChjb3VudEFjdGl2ZVRyYWNrcykgeworICAgICAgICBpZiAocmVzYW1wbGluZykgeworICAgICAgICAgICAgaWYgKCFzdGF0ZS0+b3V0cHV0VGVtcCkgeworICAgICAgICAgICAgICAgIHN0YXRlLT5vdXRwdXRUZW1wID0gbmV3IGludDMyX3RbTUFYX05VTV9DSEFOTkVMUyAqIHN0YXRlLT5mcmFtZUNvdW50XTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghc3RhdGUtPnJlc2FtcGxlVGVtcCkgeworICAgICAgICAgICAgICAgIHN0YXRlLT5yZXNhbXBsZVRlbXAgPSBuZXcgaW50MzJfdFtNQVhfTlVNX0NIQU5ORUxTICogc3RhdGUtPmZyYW1lQ291bnRdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RhdGUtPmhvb2sgPSBwcm9jZXNzX19nZW5lcmljUmVzYW1wbGluZzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChzdGF0ZS0+b3V0cHV0VGVtcCkgeworICAgICAgICAgICAgICAgIGRlbGV0ZSBbXSBzdGF0ZS0+b3V0cHV0VGVtcDsKKyAgICAgICAgICAgICAgICBzdGF0ZS0+b3V0cHV0VGVtcCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3RhdGUtPnJlc2FtcGxlVGVtcCkgeworICAgICAgICAgICAgICAgIGRlbGV0ZSBbXSBzdGF0ZS0+cmVzYW1wbGVUZW1wOworICAgICAgICAgICAgICAgIHN0YXRlLT5yZXNhbXBsZVRlbXAgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RhdGUtPmhvb2sgPSBwcm9jZXNzX19nZW5lcmljTm9SZXNhbXBsaW5nOworICAgICAgICAgICAgaWYgKGFsbDE2Qml0c1N0ZXJlb05vUmVzYW1wbGUgJiYgIXZvbHVtZVJhbXApIHsKKyAgICAgICAgICAgICAgICBpZiAoY291bnRBY3RpdmVUcmFja3MgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZS0+aG9vayA9IHByb2Nlc3NfX09uZVRyYWNrMTZCaXRzU3RlcmVvTm9SZXNhbXBsaW5nOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIExPR1YoIm1peGVyIGNvbmZpZ3VyYXRpb24gY2hhbmdlOiAlZCBhY3RpdmVUcmFja3MgKCUwOHgpICIKKyAgICAgICAgImFsbDE2Qml0c1N0ZXJlb05vUmVzYW1wbGU9JWQsIHJlc2FtcGxpbmc9JWQsIHZvbHVtZVJhbXA9JWQiLAorICAgICAgICBjb3VudEFjdGl2ZVRyYWNrcywgc3RhdGUtPmVuYWJsZWRUcmFja3MsCisgICAgICAgIGFsbDE2Qml0c1N0ZXJlb05vUmVzYW1wbGUsIHJlc2FtcGxpbmcsIHZvbHVtZVJhbXApOworCisgICBzdGF0ZS0+aG9vayhzdGF0ZSwgb3V0cHV0KTsKKworICAgLy8gTm93IHRoYXQgdGhlIHZvbHVtZSByYW1wIGhhcyBiZWVuIGRvbmUsIHNldCBvcHRpbWFsIHN0YXRlIGFuZAorICAgLy8gdHJhY2sgaG9va3MgZm9yIHN1YnNlcXVlbnQgbWl4ZXIgcHJvY2VzcworICAgaWYgKGNvdW50QWN0aXZlVHJhY2tzKSB7CisgICAgICAgaW50IGFsbE11dGVkID0gMTsKKyAgICAgICB1aW50MzJfdCBlbiA9IHN0YXRlLT5lbmFibGVkVHJhY2tzOworICAgICAgIHdoaWxlIChlbikgeworICAgICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gX19idWlsdGluX2Nseihlbik7CisgICAgICAgICAgIGVuICY9IH4oMTw8aSk7CisgICAgICAgICAgIHRyYWNrX3QmIHQgPSBzdGF0ZS0+dHJhY2tzW2ldOworICAgICAgICAgICBpZiAoIXQuZG9lc1Jlc2FtcGxlKCkgJiYgdC52b2x1bWVSTCA9PSAwKQorICAgICAgICAgICB7CisgICAgICAgICAgICAgICB0Lm5lZWRzIHw9IE5FRURTX01VVEVfRU5BQkxFRDsKKyAgICAgICAgICAgICAgIHQuaG9vayA9IHRyYWNrX19ub3A7CisgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICBhbGxNdXRlZCA9IDA7CisgICAgICAgICAgIH0KKyAgICAgICB9CisgICAgICAgaWYgKGFsbE11dGVkKSB7CisgICAgICAgICAgIHN0YXRlLT5ob29rID0gcHJvY2Vzc19fbm9wOworICAgICAgIH0gZWxzZSBpZiAoIXJlc2FtcGxpbmcgJiYgYWxsMTZCaXRzU3RlcmVvTm9SZXNhbXBsZSkgeworICAgICAgICAgICBpZiAoY291bnRBY3RpdmVUcmFja3MgPT0gMSkgeworICAgICAgICAgICAgICBzdGF0ZS0+aG9vayA9IHByb2Nlc3NfX09uZVRyYWNrMTZCaXRzU3RlcmVvTm9SZXNhbXBsaW5nOworICAgICAgICAgICB9CisgICAgICAgfQorICAgfQorfQorCitzdGF0aWMgaW5saW5lCitpbnQzMl90IG11bEFkZChpbnQxNl90IGluLCBpbnQxNl90IHYsIGludDMyX3QgYSkKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICBpbnQzMl90IG91dDsKKyAgICBhc20oICJzbWxhYmIgJVtvdXRdLCAlW2luXSwgJVt2XSwgJVthXSBcbiIKKyAgICAgICAgIDogW291dF0iPXIiKG91dCkKKyAgICAgICAgIDogW2luXSIlciIoaW4pLCBbdl0iciIodiksIFthXSJyIihhKQorICAgICAgICAgOiApOworICAgIHJldHVybiBvdXQ7CisjZWxzZQorICAgIHJldHVybiBhICsgaW4gKiBpbnQzMl90KHYpOworI2VuZGlmCit9CisKK3N0YXRpYyBpbmxpbmUKK2ludDMyX3QgbXVsKGludDE2X3QgaW4sIGludDE2X3QgdikKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICBpbnQzMl90IG91dDsKKyAgICBhc20oICJzbXVsYmIgJVtvdXRdLCAlW2luXSwgJVt2XSBcbiIKKyAgICAgICAgIDogW291dF0iPXIiKG91dCkKKyAgICAgICAgIDogW2luXSIlciIoaW4pLCBbdl0iciIodikKKyAgICAgICAgIDogKTsKKyAgICByZXR1cm4gb3V0OworI2Vsc2UKKyAgICByZXR1cm4gaW4gKiBpbnQzMl90KHYpOworI2VuZGlmCit9CisKK3N0YXRpYyBpbmxpbmUKK2ludDMyX3QgbXVsQWRkUkwoaW50IGxlZnQsIHVpbnQzMl90IGluUkwsIHVpbnQzMl90IHZSTCwgaW50MzJfdCBhKQoreworI2lmIGRlZmluZWQoX19hcm1fXykgJiYgIWRlZmluZWQoX190aHVtYl9fKQorICAgIGludDMyX3Qgb3V0OworICAgIGlmIChsZWZ0KSB7CisgICAgICAgIGFzbSggInNtbGFiYiAlW291dF0sICVbaW5STF0sICVbdlJMXSwgJVthXSBcbiIKKyAgICAgICAgICAgICA6IFtvdXRdIj1yIihvdXQpCisgICAgICAgICAgICAgOiBbaW5STF0iJXIiKGluUkwpLCBbdlJMXSJyIih2UkwpLCBbYV0iciIoYSkKKyAgICAgICAgICAgICA6ICk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgYXNtKCAic21sYXR0ICVbb3V0XSwgJVtpblJMXSwgJVt2UkxdLCAlW2FdIFxuIgorICAgICAgICAgICAgIDogW291dF0iPXIiKG91dCkKKyAgICAgICAgICAgICA6IFtpblJMXSIlciIoaW5STCksIFt2UkxdInIiKHZSTCksIFthXSJyIihhKQorICAgICAgICAgICAgIDogKTsKKyAgICB9CisgICAgcmV0dXJuIG91dDsKKyNlbHNlCisgICAgaWYgKGxlZnQpIHsKKyAgICAgICAgcmV0dXJuIGEgKyBpbnQxNl90KGluUkwmMHhGRkZGKSAqIGludDE2X3QodlJMJjB4RkZGRik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGEgKyBpbnQxNl90KGluUkw+PjE2KSAqIGludDE2X3QodlJMPj4xNik7CisgICAgfQorI2VuZGlmCit9CisKK3N0YXRpYyBpbmxpbmUKK2ludDMyX3QgbXVsUkwoaW50IGxlZnQsIHVpbnQzMl90IGluUkwsIHVpbnQzMl90IHZSTCkKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICBpbnQzMl90IG91dDsKKyAgICBpZiAobGVmdCkgeworICAgICAgICBhc20oICJzbXVsYmIgJVtvdXRdLCAlW2luUkxdLCAlW3ZSTF0gXG4iCisgICAgICAgICAgICAgOiBbb3V0XSI9ciIob3V0KQorICAgICAgICAgICAgIDogW2luUkxdIiVyIihpblJMKSwgW3ZSTF0iciIodlJMKQorICAgICAgICAgICAgIDogKTsKKyAgICB9IGVsc2UgeworICAgICAgICBhc20oICJzbXVsdHQgJVtvdXRdLCAlW2luUkxdLCAlW3ZSTF0gXG4iCisgICAgICAgICAgICAgOiBbb3V0XSI9ciIob3V0KQorICAgICAgICAgICAgIDogW2luUkxdIiVyIihpblJMKSwgW3ZSTF0iciIodlJMKQorICAgICAgICAgICAgIDogKTsKKyAgICB9CisgICAgcmV0dXJuIG91dDsKKyNlbHNlCisgICAgaWYgKGxlZnQpIHsKKyAgICAgICAgcmV0dXJuIGludDE2X3QoaW5STCYweEZGRkYpICogaW50MTZfdCh2UkwmMHhGRkZGKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gaW50MTZfdChpblJMPj4xNikgKiBpbnQxNl90KHZSTD4+MTYpOworICAgIH0KKyNlbmRpZgorfQorCisKK3ZvaWQgQXVkaW9NaXhlcjo6dHJhY2tfX2dlbmVyaWNSZXNhbXBsZSh0cmFja190KiB0LCBpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LCBpbnQzMl90KiB0ZW1wKQoreworICAgIHQtPnJlc2FtcGxlci0+c2V0U2FtcGxlUmF0ZSh0LT5zYW1wbGVSYXRlKTsKKworICAgIC8vIHJhbXAgZ2FpbiAtIHJlc2FtcGxlIHRvIHRlbXAgYnVmZmVyIGFuZCBzY2FsZS9taXggaW4gMm5kIHN0ZXAKKyAgICBpZiBVTkxJS0VMWSh0LT52b2x1bWVJbmNbMF18dC0+dm9sdW1lSW5jWzFdKSB7CisgICAgICAgIHQtPnJlc2FtcGxlci0+c2V0Vm9sdW1lKFVOSVRZX0dBSU4sIFVOSVRZX0dBSU4pOworICAgICAgICBtZW1zZXQodGVtcCwgMCwgb3V0RnJhbWVDb3VudCAqIE1BWF9OVU1fQ0hBTk5FTFMgKiBzaXplb2YoaW50MzJfdCkpOworICAgICAgICB0LT5yZXNhbXBsZXItPnJlc2FtcGxlKHRlbXAsIG91dEZyYW1lQ291bnQsIHQtPmJ1ZmZlclByb3ZpZGVyKTsKKyAgICAgICAgdm9sdW1lUmFtcFN0ZXJlbyh0LCBvdXQsIG91dEZyYW1lQ291bnQsIHRlbXApOworICAgIH0KKworICAgIC8vIGNvbnN0YW50IGdhaW4KKyAgICBlbHNlIHsKKyAgICAgICAgdC0+cmVzYW1wbGVyLT5zZXRWb2x1bWUodC0+dm9sdW1lWzBdLCB0LT52b2x1bWVbMV0pOworICAgICAgICB0LT5yZXNhbXBsZXItPnJlc2FtcGxlKG91dCwgb3V0RnJhbWVDb3VudCwgdC0+YnVmZmVyUHJvdmlkZXIpOworICAgIH0KK30KKwordm9pZCBBdWRpb01peGVyOjp0cmFja19fbm9wKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsIGludDMyX3QqIHRlbXApCit7Cit9CisKK3ZvaWQgQXVkaW9NaXhlcjo6dm9sdW1lUmFtcFN0ZXJlbyh0cmFja190KiB0LCBpbnQzMl90KiBvdXQsIHNpemVfdCBmcmFtZUNvdW50LCBpbnQzMl90KiB0ZW1wKQoreworICAgIGludDMyX3QgdmwgPSB0LT5wcmV2Vm9sdW1lWzBdOworICAgIGludDMyX3QgdnIgPSB0LT5wcmV2Vm9sdW1lWzFdOworICAgIGNvbnN0IGludDMyX3QgdmxJbmMgPSB0LT52b2x1bWVJbmNbMF07CisgICAgY29uc3QgaW50MzJfdCB2ckluYyA9IHQtPnZvbHVtZUluY1sxXTsKKworICAgIC8vTE9HRCgiWzBdICVwOiBpbmM9JWYsIHYwPSVmLCB2MT0lZCwgZmluYWw9JWYsIGNvdW50PSVkIiwKKyAgICAvLyAgICAgICAgdCwgdmxJbmMvNjU1MzYuMGYsIHZsLzY1NTM2LjBmLCB0LT52b2x1bWVbMF0sCisgICAgLy8gICAgICAgKHZsICsgdmxJbmMqZnJhbWVDb3VudCkvNjU1MzYuMGYsIGZyYW1lQ291bnQpOworICAgCisgICAgLy8gcmFtcCB2b2x1bWUKKyAgICBkbyB7CisgICAgICAgICpvdXQrKyArPSAodmwgPj4gMTYpICogKCp0ZW1wKysgPj4gMTIpOworICAgICAgICAqb3V0KysgKz0gKHZyID4+IDE2KSAqICgqdGVtcCsrID4+IDEyKTsKKyAgICAgICAgdmwgKz0gdmxJbmM7CisgICAgICAgIHZyICs9IHZySW5jOworICAgIH0gd2hpbGUgKC0tZnJhbWVDb3VudCk7CisKKyAgICB0LT5wcmV2Vm9sdW1lWzBdID0gdmw7CisgICAgdC0+cHJldlZvbHVtZVsxXSA9IHZyOworICAgIHQtPmFkanVzdFZvbHVtZVJhbXAoKTsKK30KKwordm9pZCBBdWRpb01peGVyOjp0cmFja19fMTZCaXRzU3RlcmVvKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dCwgc2l6ZV90IGZyYW1lQ291bnQsIGludDMyX3QqIHRlbXApCit7CisgICAgaW50MTZfdCBjb25zdCAqaW4gPSBzdGF0aWNfY2FzdDxpbnQxNl90IGNvbnN0ICo+KHQtPmluKTsKKworICAgIC8vIHJhbXAgZ2FpbgorICAgIGlmIFVOTElLRUxZKHQtPnZvbHVtZUluY1swXXx0LT52b2x1bWVJbmNbMV0pIHsKKyAgICAgICAgaW50MzJfdCB2bCA9IHQtPnByZXZWb2x1bWVbMF07CisgICAgICAgIGludDMyX3QgdnIgPSB0LT5wcmV2Vm9sdW1lWzFdOworICAgICAgICBjb25zdCBpbnQzMl90IHZsSW5jID0gdC0+dm9sdW1lSW5jWzBdOworICAgICAgICBjb25zdCBpbnQzMl90IHZySW5jID0gdC0+dm9sdW1lSW5jWzFdOworCisgICAgICAgIC8vIExPR0QoIlsxXSAlcDogaW5jPSVmLCB2MD0lZiwgdjE9JWQsIGZpbmFsPSVmLCBjb3VudD0lZCIsCisgICAgICAgIC8vICAgICAgICB0LCB2bEluYy82NTUzNi4wZiwgdmwvNjU1MzYuMGYsIHQtPnZvbHVtZVswXSwKKyAgICAgICAgLy8gICAgICAgICh2bCArIHZsSW5jKmZyYW1lQ291bnQpLzY1NTM2LjBmLCBmcmFtZUNvdW50KTsKKworICAgICAgICBkbyB7CisgICAgICAgICAgICAqb3V0KysgKz0gKHZsID4+IDE2KSAqIChpbnQzMl90KSAqaW4rKzsKKyAgICAgICAgICAgICpvdXQrKyArPSAodnIgPj4gMTYpICogKGludDMyX3QpICppbisrOworICAgICAgICAgICAgdmwgKz0gdmxJbmM7CisgICAgICAgICAgICB2ciArPSB2ckluYzsKKyAgICAgICAgfSB3aGlsZSAoLS1mcmFtZUNvdW50KTsKKyAgICAgICAKKyAgICAgICAgdC0+cHJldlZvbHVtZVswXSA9IHZsOworICAgICAgICB0LT5wcmV2Vm9sdW1lWzFdID0gdnI7CisgICAgICAgIHQtPmFkanVzdFZvbHVtZVJhbXAoKTsKKyAgICB9CisKKyAgICAvLyBjb25zdGFudCBnYWluCisgICAgZWxzZSB7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IHZybCA9IHQtPnZvbHVtZVJMOworICAgICAgICBkbyB7CisgICAgICAgICAgICB1aW50MzJfdCBybCA9ICpyZWludGVycHJldF9jYXN0PHVpbnQzMl90IGNvbnN0ICo+KGluKTsKKyAgICAgICAgICAgIGluICs9IDI7CisgICAgICAgICAgICBvdXRbMF0gPSBtdWxBZGRSTCgxLCBybCwgdnJsLCBvdXRbMF0pOworICAgICAgICAgICAgb3V0WzFdID0gbXVsQWRkUkwoMCwgcmwsIHZybCwgb3V0WzFdKTsKKyAgICAgICAgICAgIG91dCArPSAyOworICAgICAgICB9IHdoaWxlICgtLWZyYW1lQ291bnQpOworICAgIH0KKyAgICB0LT5pbiA9IGluOworfQorCit2b2lkIEF1ZGlvTWl4ZXI6OnRyYWNrX18xNkJpdHNNb25vKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dCwgc2l6ZV90IGZyYW1lQ291bnQsIGludDMyX3QqIHRlbXApCit7CisgICAgaW50MTZfdCBjb25zdCAqaW4gPSBzdGF0aWNfY2FzdDxpbnQxNl90IGNvbnN0ICo+KHQtPmluKTsKKworICAgIC8vIHJhbXAgZ2FpbgorICAgIGlmIFVOTElLRUxZKHQtPnZvbHVtZUluY1swXXx0LT52b2x1bWVJbmNbMV0pIHsKKyAgICAgICAgaW50MzJfdCB2bCA9IHQtPnByZXZWb2x1bWVbMF07CisgICAgICAgIGludDMyX3QgdnIgPSB0LT5wcmV2Vm9sdW1lWzFdOworICAgICAgICBjb25zdCBpbnQzMl90IHZsSW5jID0gdC0+dm9sdW1lSW5jWzBdOworICAgICAgICBjb25zdCBpbnQzMl90IHZySW5jID0gdC0+dm9sdW1lSW5jWzFdOworCisgICAgICAgIC8vIExPR0QoIlsyXSAlcDogaW5jPSVmLCB2MD0lZiwgdjE9JWQsIGZpbmFsPSVmLCBjb3VudD0lZCIsCisgICAgICAgIC8vICAgICAgICAgdCwgdmxJbmMvNjU1MzYuMGYsIHZsLzY1NTM2LjBmLCB0LT52b2x1bWVbMF0sCisgICAgICAgIC8vICAgICAgICAgKHZsICsgdmxJbmMqZnJhbWVDb3VudCkvNjU1MzYuMGYsIGZyYW1lQ291bnQpOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGludDMyX3QgbCA9ICppbisrOworICAgICAgICAgICAgKm91dCsrICs9ICh2bCA+PiAxNikgKiBsOworICAgICAgICAgICAgKm91dCsrICs9ICh2ciA+PiAxNikgKiBsOworICAgICAgICAgICAgdmwgKz0gdmxJbmM7CisgICAgICAgICAgICB2ciArPSB2ckluYzsKKyAgICAgICAgfSB3aGlsZSAoLS1mcmFtZUNvdW50KTsKKyAgICAgICAKKyAgICAgICAgdC0+cHJldlZvbHVtZVswXSA9IHZsOworICAgICAgICB0LT5wcmV2Vm9sdW1lWzFdID0gdnI7CisgICAgICAgIHQtPmFkanVzdFZvbHVtZVJhbXAoKTsKKyAgICB9CisgICAgLy8gY29uc3RhbnQgZ2FpbgorICAgIGVsc2UgeworICAgICAgICBjb25zdCBpbnQxNl90IHZsID0gdC0+dm9sdW1lWzBdOworICAgICAgICBjb25zdCBpbnQxNl90IHZyID0gdC0+dm9sdW1lWzFdOworICAgICAgICBkbyB7CisgICAgICAgICAgICBpbnQxNl90IGwgPSAqaW4rKzsKKyAgICAgICAgICAgIG91dFswXSA9IG11bEFkZChsLCB2bCwgb3V0WzBdKTsKKyAgICAgICAgICAgIG91dFsxXSA9IG11bEFkZChsLCB2ciwgb3V0WzFdKTsKKyAgICAgICAgICAgIG91dCArPSAyOworICAgICAgICB9IHdoaWxlICgtLWZyYW1lQ291bnQpOworICAgIH0KKyAgICB0LT5pbiA9IGluOworfQorCitpbmxpbmUKK3ZvaWQgQXVkaW9NaXhlcjo6ZGl0aGVyQW5kQ2xhbXAoaW50MzJfdCogb3V0LCBpbnQzMl90IGNvbnN0ICpzdW1zLCBzaXplX3QgYykKK3sKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGMgOyBpKyspIHsKKyAgICAgICAgaW50MzJfdCBsID0gKnN1bXMrKzsKKyAgICAgICAgaW50MzJfdCByID0gKnN1bXMrKzsKKyAgICAgICAgaW50MzJfdCBubCA9IGwgPj4gMTI7CisgICAgICAgIGludDMyX3QgbnIgPSByID4+IDEyOworICAgICAgICBsID0gY2xhbXAxNihubCk7CisgICAgICAgIHIgPSBjbGFtcDE2KG5yKTsKKyAgICAgICAgKm91dCsrID0gKHI8PDE2KSB8IChsICYgMHhGRkZGKTsKKyAgICB9Cit9CisKKy8vIG5vLW9wIGNhc2UKK3ZvaWQgQXVkaW9NaXhlcjo6cHJvY2Vzc19fbm9wKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpCit7CisgICAgLy8gdGhpcyBhc3N1bWVzIG91dHB1dCAxNiBiaXRzIHN0ZXJlbywgbm8gcmVzYW1wbGluZworICAgIG1lbXNldChvdXRwdXQsIDAsIHN0YXRlLT5mcmFtZUNvdW50KjQpOworICAgIHVpbnQzMl90IGVuID0gc3RhdGUtPmVuYWJsZWRUcmFja3M7CisgICAgd2hpbGUgKGVuKSB7CisgICAgICAgIGNvbnN0IGludCBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGVuKTsKKyAgICAgICAgZW4gJj0gfigxPDxpKTsKKyAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgIHNpemVfdCBvdXRGcmFtZXMgPSBzdGF0ZS0+ZnJhbWVDb3VudDsKKyAgICAgICAgd2hpbGUgKG91dEZyYW1lcykgeworICAgICAgICAgICAgdC5idWZmZXIuZnJhbWVDb3VudCA9IG91dEZyYW1lczsKKyAgICAgICAgICAgIHQuYnVmZmVyUHJvdmlkZXItPmdldE5leHRCdWZmZXIoJnQuYnVmZmVyKTsKKyAgICAgICAgICAgIGlmICghdC5idWZmZXIucmF3KSBicmVhazsKKyAgICAgICAgICAgIG91dEZyYW1lcyAtPSB0LmJ1ZmZlci5mcmFtZUNvdW50OworICAgICAgICAgICAgdC5idWZmZXJQcm92aWRlci0+cmVsZWFzZUJ1ZmZlcigmdC5idWZmZXIpOworICAgICAgICB9CisgICAgfQorfQorCisvLyBnZW5lcmljIGNvZGUgd2l0aG91dCByZXNhbXBsaW5nCit2b2lkIEF1ZGlvTWl4ZXI6OnByb2Nlc3NfX2dlbmVyaWNOb1Jlc2FtcGxpbmcoc3RhdGVfdCogc3RhdGUsIHZvaWQqIG91dHB1dCkKK3sKKyAgICBpbnQzMl90IG91dFRlbXBbQkxPQ0tTSVpFICogTUFYX05VTV9DSEFOTkVMU10gX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgzMikpKTsKKworICAgIC8vIGFjcXVpcmUgZWFjaCB0cmFjaydzIGJ1ZmZlcgorICAgIHVpbnQzMl90IGVuYWJsZWRUcmFja3MgPSBzdGF0ZS0+ZW5hYmxlZFRyYWNrczsKKyAgICB1aW50MzJfdCBlbiA9IGVuYWJsZWRUcmFja3M7CisgICAgd2hpbGUgKGVuKSB7CisgICAgICAgIGNvbnN0IGludCBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGVuKTsKKyAgICAgICAgZW4gJj0gfigxPDxpKTsKKyAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgIHQuYnVmZmVyLmZyYW1lQ291bnQgPSBzdGF0ZS0+ZnJhbWVDb3VudDsKKyAgICAgICAgdC5idWZmZXJQcm92aWRlci0+Z2V0TmV4dEJ1ZmZlcigmdC5idWZmZXIpOworICAgICAgICB0LmZyYW1lQ291bnQgPSB0LmJ1ZmZlci5mcmFtZUNvdW50OworICAgICAgICB0LmluID0gdC5idWZmZXIucmF3OworICAgICAgICAvLyB0LmluID09IE5VTEwgY2FuIGhhcHBlbiBpZiB0aGUgdHJhY2sgd2FzIGZsdXNoZWQganVzdCBhZnRlciBoYXZpbmcKKyAgICAgICAgLy8gYmVlbiBlbmFibGVkIGZvciBtaXhpbmcuCisgICAgICAgIGlmICh0LmluID09IE5VTEwpCisgICAgICAgICAgICBlbmFibGVkVHJhY2tzICY9IH4oMTw8aSk7CisgICAgfQorCisgICAgLy8gdGhpcyBhc3N1bWVzIG91dHB1dCAxNiBiaXRzIHN0ZXJlbywgbm8gcmVzYW1wbGluZworICAgIGludDMyX3QqIG91dCA9IHN0YXRpY19jYXN0PGludDMyX3QqPihvdXRwdXQpOworICAgIHNpemVfdCBudW1GcmFtZXMgPSBzdGF0ZS0+ZnJhbWVDb3VudDsKKyAgICBkbyB7CisgICAgICAgIG1lbXNldChvdXRUZW1wLCAwLCBzaXplb2Yob3V0VGVtcCkpOworCisgICAgICAgIGVuID0gZW5hYmxlZFRyYWNrczsKKyAgICAgICAgd2hpbGUgKGVuKSB7CisgICAgICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gX19idWlsdGluX2Nseihlbik7CisgICAgICAgICAgICBlbiAmPSB+KDE8PGkpOworICAgICAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgICAgICBzaXplX3Qgb3V0RnJhbWVzID0gQkxPQ0tTSVpFOworICAgICAgICAgICAKKyAgICAgICAgICAgIHdoaWxlIChvdXRGcmFtZXMpIHsKKyAgICAgICAgICAgICAgICBzaXplX3QgaW5GcmFtZXMgPSAodC5mcmFtZUNvdW50ID4gb3V0RnJhbWVzKT9vdXRGcmFtZXM6dC5mcmFtZUNvdW50OworICAgICAgICAgICAgICAgIGlmIChpbkZyYW1lcykgeworICAgICAgICAgICAgICAgICAgICAodC5ob29rKSgmdCwgb3V0VGVtcCArIChCTE9DS1NJWkUtb3V0RnJhbWVzKSpNQVhfTlVNX0NIQU5ORUxTLCBpbkZyYW1lcywgc3RhdGUtPnJlc2FtcGxlVGVtcCk7CisgICAgICAgICAgICAgICAgICAgIHQuZnJhbWVDb3VudCAtPSBpbkZyYW1lczsKKyAgICAgICAgICAgICAgICAgICAgb3V0RnJhbWVzIC09IGluRnJhbWVzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodC5mcmFtZUNvdW50ID09IDAgJiYgb3V0RnJhbWVzKSB7CisgICAgICAgICAgICAgICAgICAgIHQuYnVmZmVyUHJvdmlkZXItPnJlbGVhc2VCdWZmZXIoJnQuYnVmZmVyKTsKKyAgICAgICAgICAgICAgICAgICAgdC5idWZmZXIuZnJhbWVDb3VudCA9IG51bUZyYW1lcyAtIChCTE9DS1NJWkUgLSBvdXRGcmFtZXMpOworICAgICAgICAgICAgICAgICAgICB0LmJ1ZmZlclByb3ZpZGVyLT5nZXROZXh0QnVmZmVyKCZ0LmJ1ZmZlcik7CisgICAgICAgICAgICAgICAgICAgIHQuaW4gPSB0LmJ1ZmZlci5yYXc7CisgICAgICAgICAgICAgICAgICAgIGlmICh0LmluID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRUcmFja3MgJj0gfigxPDxpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHQuZnJhbWVDb3VudCA9IHQuYnVmZmVyLmZyYW1lQ291bnQ7CisgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGRpdGhlckFuZENsYW1wKG91dCwgb3V0VGVtcCwgQkxPQ0tTSVpFKTsKKyAgICAgICAgb3V0ICs9IEJMT0NLU0laRTsKKyAgICAgICAgbnVtRnJhbWVzIC09IEJMT0NLU0laRTsKKyAgICB9IHdoaWxlIChudW1GcmFtZXMpOworCisKKyAgICAvLyByZWxlYXNlIGVhY2ggdHJhY2sncyBidWZmZXIKKyAgICBlbiA9IGVuYWJsZWRUcmFja3M7CisgICAgd2hpbGUgKGVuKSB7CisgICAgICAgIGNvbnN0IGludCBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGVuKTsKKyAgICAgICAgZW4gJj0gfigxPDxpKTsKKyAgICAgICAgdHJhY2tfdCYgdCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgICAgIHQuYnVmZmVyUHJvdmlkZXItPnJlbGVhc2VCdWZmZXIoJnQuYnVmZmVyKTsKKyAgICB9Cit9CisKKy8vIGdlbmVyaWMgY29kZSB3aXRoIHJlc2FtcGxpbmcKK3ZvaWQgQXVkaW9NaXhlcjo6cHJvY2Vzc19fZ2VuZXJpY1Jlc2FtcGxpbmcoc3RhdGVfdCogc3RhdGUsIHZvaWQqIG91dHB1dCkKK3sKKyAgICBpbnQzMl90KiBjb25zdCBvdXRUZW1wID0gc3RhdGUtPm91dHB1dFRlbXA7CisgICAgY29uc3Qgc2l6ZV90IHNpemUgPSBzaXplb2YoaW50MzJfdCkgKiBNQVhfTlVNX0NIQU5ORUxTICogc3RhdGUtPmZyYW1lQ291bnQ7CisgICAgbWVtc2V0KG91dFRlbXAsIDAsIHNpemUpOworCisgICAgaW50MzJfdCogb3V0ID0gc3RhdGljX2Nhc3Q8aW50MzJfdCo+KG91dHB1dCk7CisgICAgc2l6ZV90IG51bUZyYW1lcyA9IHN0YXRlLT5mcmFtZUNvdW50OworCisgICAgdWludDMyX3QgZW4gPSBzdGF0ZS0+ZW5hYmxlZFRyYWNrczsKKyAgICB3aGlsZSAoZW4pIHsKKyAgICAgICAgY29uc3QgaW50IGkgPSAzMSAtIF9fYnVpbHRpbl9jbHooZW4pOworICAgICAgICBlbiAmPSB+KDE8PGkpOworICAgICAgICB0cmFja190JiB0ID0gc3RhdGUtPnRyYWNrc1tpXTsKKworICAgICAgICAvLyB0aGlzIGlzIGEgbGl0dGxlIGdvb2Z5LCBvbiB0aGUgcmVzYW1wbGluZyBjYXNlIHdlIGRvbid0CisgICAgICAgIC8vIGFjcXVpcmUvcmVsZWFzZSB0aGUgYnVmZmVycyBiZWNhdXNlIGl0J3MgZG9uZSBieQorICAgICAgICAvLyB0aGUgcmVzYW1wbGVyLgorICAgICAgICBpZiAoKHQubmVlZHMgJiBORUVEU19SRVNBTVBMRV9fTUFTSykgPT0gTkVFRFNfUkVTQU1QTEVfRU5BQkxFRCkgeworICAgICAgICAgICAgKHQuaG9vaykoJnQsIG91dFRlbXAsIG51bUZyYW1lcywgc3RhdGUtPnJlc2FtcGxlVGVtcCk7CisgICAgICAgIH0gZWxzZSB7CisKKyAgICAgICAgICAgIHNpemVfdCBvdXRGcmFtZXMgPSBudW1GcmFtZXM7CisgICAgICAgICAgIAorICAgICAgICAgICAgd2hpbGUgKG91dEZyYW1lcykgeworICAgICAgICAgICAgICAgIHQuYnVmZmVyLmZyYW1lQ291bnQgPSBvdXRGcmFtZXM7CisgICAgICAgICAgICAgICAgdC5idWZmZXJQcm92aWRlci0+Z2V0TmV4dEJ1ZmZlcigmdC5idWZmZXIpOworICAgICAgICAgICAgICAgIHQuaW4gPSB0LmJ1ZmZlci5yYXc7CisgICAgICAgICAgICAgICAgLy8gdC5pbiA9PSBOVUxMIGNhbiBoYXBwZW4gaWYgdGhlIHRyYWNrIHdhcyBmbHVzaGVkIGp1c3QgYWZ0ZXIgaGF2aW5nCisgICAgICAgICAgICAgICAgLy8gYmVlbiBlbmFibGVkIGZvciBtaXhpbmcuCisgICAgICAgICAgICAgICAgaWYgKHQuaW4gPT0gTlVMTCkgYnJlYWs7CisKKyAgICAgICAgICAgICAgICAodC5ob29rKSgmdCwgb3V0VGVtcCArIChudW1GcmFtZXMtb3V0RnJhbWVzKSpNQVhfTlVNX0NIQU5ORUxTLCB0LmJ1ZmZlci5mcmFtZUNvdW50LCBzdGF0ZS0+cmVzYW1wbGVUZW1wKTsKKyAgICAgICAgICAgICAgICBvdXRGcmFtZXMgLT0gdC5idWZmZXIuZnJhbWVDb3VudDsKKyAgICAgICAgICAgICAgICB0LmJ1ZmZlclByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZ0LmJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBkaXRoZXJBbmRDbGFtcChvdXQsIG91dFRlbXAsIG51bUZyYW1lcyk7Cit9CisKKy8vIG9uZSB0cmFjaywgMTYgYml0cyBzdGVyZW8gd2l0aG91dCByZXNhbXBsaW5nIGlzIHRoZSBtb3N0IGNvbW1vbiBjYXNlCit2b2lkIEF1ZGlvTWl4ZXI6OnByb2Nlc3NfX09uZVRyYWNrMTZCaXRzU3RlcmVvTm9SZXNhbXBsaW5nKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpCit7CisgICAgY29uc3QgaW50IGkgPSAzMSAtIF9fYnVpbHRpbl9jbHooc3RhdGUtPmVuYWJsZWRUcmFja3MpOworICAgIGNvbnN0IHRyYWNrX3QmIHQgPSBzdGF0ZS0+dHJhY2tzW2ldOworCisgICAgQXVkaW9CdWZmZXJQcm92aWRlcjo6QnVmZmVyJiBiKHQuYnVmZmVyKTsKKyAgIAorICAgIGludDMyX3QqIG91dCA9IHN0YXRpY19jYXN0PGludDMyX3QqPihvdXRwdXQpOworICAgIHNpemVfdCBudW1GcmFtZXMgPSBzdGF0ZS0+ZnJhbWVDb3VudDsKKyAgCisgICAgY29uc3QgaW50MTZfdCB2bCA9IHQudm9sdW1lWzBdOworICAgIGNvbnN0IGludDE2X3QgdnIgPSB0LnZvbHVtZVsxXTsKKyAgICBjb25zdCB1aW50MzJfdCB2cmwgPSB0LnZvbHVtZVJMOworICAgIHdoaWxlIChudW1GcmFtZXMpIHsKKyAgICAgICAgYi5mcmFtZUNvdW50ID0gbnVtRnJhbWVzOworICAgICAgICB0LmJ1ZmZlclByb3ZpZGVyLT5nZXROZXh0QnVmZmVyKCZiKTsKKyAgICAgICAgaW50MTZfdCBjb25zdCAqaW4gPSBiLmkxNjsKKworICAgICAgICAvLyBpbiA9PSBOVUxMIGNhbiBoYXBwZW4gaWYgdGhlIHRyYWNrIHdhcyBmbHVzaGVkIGp1c3QgYWZ0ZXIgaGF2aW5nCisgICAgICAgIC8vIGJlZW4gZW5hYmxlZCBmb3IgbWl4aW5nLgorICAgICAgICBpZiAoaW4gPT0gTlVMTCkgeworICAgICAgICAgICAgbWVtc2V0KG91dCwgMCwgbnVtRnJhbWVzKk1BWF9OVU1fQ0hBTk5FTFMqc2l6ZW9mKGludDE2X3QpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBzaXplX3Qgb3V0RnJhbWVzID0gYi5mcmFtZUNvdW50OworICAgICAgIAorICAgICAgICBpZiAoVU5MSUtFTFkodWludDMyX3QodmwpID4gVU5JVFlfR0FJTiB8fCB1aW50MzJfdCh2cikgPiBVTklUWV9HQUlOKSkgeworICAgICAgICAgICAgLy8gdm9sdW1lIGlzIGJvb3N0ZWQsIHNvIHdlIG1pZ2h0IG5lZWQgdG8gY2xhbXAgZXZlbiB0aG91Z2gKKyAgICAgICAgICAgIC8vIHdlIHByb2Nlc3Mgb25seSBvbmUgdHJhY2suCisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgdWludDMyX3QgcmwgPSAqcmVpbnRlcnByZXRfY2FzdDx1aW50MzJfdCBjb25zdCAqPihpbik7CisgICAgICAgICAgICAgICAgaW4gKz0gMjsKKyAgICAgICAgICAgICAgICBpbnQzMl90IGwgPSBtdWxSTCgxLCBybCwgdnJsKSA+PiAxMjsKKyAgICAgICAgICAgICAgICBpbnQzMl90IHIgPSBtdWxSTCgwLCBybCwgdnJsKSA+PiAxMjsKKyAgICAgICAgICAgICAgICAvLyBjbGFtcGluZy4uLgorICAgICAgICAgICAgICAgIGwgPSBjbGFtcDE2KGwpOworICAgICAgICAgICAgICAgIHIgPSBjbGFtcDE2KHIpOworICAgICAgICAgICAgICAgICpvdXQrKyA9IChyPDwxNikgfCAobCAmIDB4RkZGRik7CisgICAgICAgICAgICB9IHdoaWxlICgtLW91dEZyYW1lcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgdWludDMyX3QgcmwgPSAqcmVpbnRlcnByZXRfY2FzdDx1aW50MzJfdCBjb25zdCAqPihpbik7CisgICAgICAgICAgICAgICAgaW4gKz0gMjsKKyAgICAgICAgICAgICAgICBpbnQzMl90IGwgPSBtdWxSTCgxLCBybCwgdnJsKSA+PiAxMjsKKyAgICAgICAgICAgICAgICBpbnQzMl90IHIgPSBtdWxSTCgwLCBybCwgdnJsKSA+PiAxMjsKKyAgICAgICAgICAgICAgICAqb3V0KysgPSAocjw8MTYpIHwgKGwgJiAweEZGRkYpOworICAgICAgICAgICAgfSB3aGlsZSAoLS1vdXRGcmFtZXMpOworICAgICAgICB9CisgICAgICAgIG51bUZyYW1lcyAtPSBiLmZyYW1lQ291bnQ7CisgICAgICAgIHQuYnVmZmVyUHJvdmlkZXItPnJlbGVhc2VCdWZmZXIoJmIpOworICAgIH0KK30KKworLy8gMiB0cmFja3MgaXMgYWxzbyBhIGNvbW1vbiBjYXNlCit2b2lkIEF1ZGlvTWl4ZXI6OnByb2Nlc3NfX1R3b1RyYWNrczE2Qml0c1N0ZXJlb05vUmVzYW1wbGluZyhzdGF0ZV90KiBzdGF0ZSwgdm9pZCogb3V0cHV0KQoreworICAgIGludCBpOworICAgIHVpbnQzMl90IGVuID0gc3RhdGUtPmVuYWJsZWRUcmFja3M7CisKKyAgICBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGVuKTsKKyAgICBjb25zdCB0cmFja190JiB0MCA9IHN0YXRlLT50cmFja3NbaV07CisgICAgQXVkaW9CdWZmZXJQcm92aWRlcjo6QnVmZmVyJiBiMCh0MC5idWZmZXIpOworCisgICAgZW4gJj0gfigxPDxpKTsKKyAgICBpID0gMzEgLSBfX2J1aWx0aW5fY2x6KGVuKTsKKyAgICBjb25zdCB0cmFja190JiB0MSA9IHN0YXRlLT50cmFja3NbaV07CisgICAgQXVkaW9CdWZmZXJQcm92aWRlcjo6QnVmZmVyJiBiMSh0MS5idWZmZXIpOworICAgCisgICAgaW50MTZfdCBjb25zdCAqaW4wOworICAgIGNvbnN0IGludDE2X3QgdmwwID0gdDAudm9sdW1lWzBdOworICAgIGNvbnN0IGludDE2X3QgdnIwID0gdDAudm9sdW1lWzFdOworICAgIHNpemVfdCBmcmFtZUNvdW50MCA9IDA7CisgIAorICAgIGludDE2X3QgY29uc3QgKmluMTsKKyAgICBjb25zdCBpbnQxNl90IHZsMSA9IHQxLnZvbHVtZVswXTsKKyAgICBjb25zdCBpbnQxNl90IHZyMSA9IHQxLnZvbHVtZVsxXTsKKyAgICBzaXplX3QgZnJhbWVDb3VudDEgPSAwOworICAgCisgICAgaW50MzJfdCogb3V0ID0gc3RhdGljX2Nhc3Q8aW50MzJfdCo+KG91dHB1dCk7CisgICAgc2l6ZV90IG51bUZyYW1lcyA9IHN0YXRlLT5mcmFtZUNvdW50OworICAgIGludDE2X3QgY29uc3QgKmJ1ZmYgPSBOVUxMOworCisgIAorICAgIHdoaWxlIChudW1GcmFtZXMpIHsKKyAgIAorICAgICAgICBpZiAoZnJhbWVDb3VudDAgPT0gMCkgeworICAgICAgICAgICAgYjAuZnJhbWVDb3VudCA9IG51bUZyYW1lczsKKyAgICAgICAgICAgIHQwLmJ1ZmZlclByb3ZpZGVyLT5nZXROZXh0QnVmZmVyKCZiMCk7CisgICAgICAgICAgICBpZiAoYjAuaTE2ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAoYnVmZiA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmYgPSBuZXcgaW50MTZfdFtNQVhfTlVNX0NIQU5ORUxTICogc3RhdGUtPmZyYW1lQ291bnRdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbjAgPSBidWZmOworICAgICAgICAgICAgICAgIGIwLmZyYW1lQ291bnQgPSBudW1GcmFtZXM7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGluMCA9IGIwLmkxNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZyYW1lQ291bnQwID0gYjAuZnJhbWVDb3VudDsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnJhbWVDb3VudDEgPT0gMCkgeworICAgICAgICAgICAgYjEuZnJhbWVDb3VudCA9IG51bUZyYW1lczsKKyAgICAgICAgICAgIHQxLmJ1ZmZlclByb3ZpZGVyLT5nZXROZXh0QnVmZmVyKCZiMSk7CisgICAgICAgICAgICBpZiAoYjEuaTE2ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAoYnVmZiA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmYgPSBuZXcgaW50MTZfdFtNQVhfTlVNX0NIQU5ORUxTICogc3RhdGUtPmZyYW1lQ291bnRdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbjEgPSBidWZmOworICAgICAgICAgICAgICAgIGIxLmZyYW1lQ291bnQgPSBudW1GcmFtZXM7CisgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGluMSA9IGIxLmkxNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZyYW1lQ291bnQxID0gYjEuZnJhbWVDb3VudDsKKyAgICAgICAgfQorICAgICAgIAorICAgICAgICBzaXplX3Qgb3V0RnJhbWVzID0gZnJhbWVDb3VudDAgPCBmcmFtZUNvdW50MT9mcmFtZUNvdW50MDpmcmFtZUNvdW50MTsKKworICAgICAgICBudW1GcmFtZXMgLT0gb3V0RnJhbWVzOworICAgICAgICBmcmFtZUNvdW50MCAtPSBvdXRGcmFtZXM7CisgICAgICAgIGZyYW1lQ291bnQxIC09IG91dEZyYW1lczsKKyAgICAgICAKKyAgICAgICAgZG8geworICAgICAgICAgICAgaW50MzJfdCBsMCA9ICppbjArKzsKKyAgICAgICAgICAgIGludDMyX3QgcjAgPSAqaW4wKys7CisgICAgICAgICAgICBsMCA9IG11bChsMCwgdmwwKTsKKyAgICAgICAgICAgIHIwID0gbXVsKHIwLCB2cjApOworICAgICAgICAgICAgaW50MzJfdCBsID0gKmluMSsrOworICAgICAgICAgICAgaW50MzJfdCByID0gKmluMSsrOworICAgICAgICAgICAgbCA9IG11bEFkZChsLCB2bDEsIGwwKSA+PiAxMjsKKyAgICAgICAgICAgIHIgPSBtdWxBZGQociwgdnIxLCByMCkgPj4gMTI7CisgICAgICAgICAgICAvLyBjbGFtcGluZy4uLgorICAgICAgICAgICAgbCA9IGNsYW1wMTYobCk7CisgICAgICAgICAgICByID0gY2xhbXAxNihyKTsKKyAgICAgICAgICAgICpvdXQrKyA9IChyPDwxNikgfCAobCAmIDB4RkZGRik7CisgICAgICAgIH0gd2hpbGUgKC0tb3V0RnJhbWVzKTsKKyAgICAgICAKKyAgICAgICAgaWYgKGZyYW1lQ291bnQwID09IDApIHsKKyAgICAgICAgICAgIHQwLmJ1ZmZlclByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZiMCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZyYW1lQ291bnQxID09IDApIHsKKyAgICAgICAgICAgIHQxLmJ1ZmZlclByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZiMSk7CisgICAgICAgIH0KKyAgICB9ICAgCisgICAgICAgCisgICAgaWYgKGJ1ZmYgIT0gTlVMTCkgeworICAgICAgICBkZWxldGUgW10gYnVmZjsgICAgICAgCisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb01peGVyLmggYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb01peGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzJjYTI4YQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvTWl4ZXIuaApAQCAtMCwwICsxLDE5MiBAQAorLyogLy9kZXZpY2UvaW5jbHVkZS9zZXJ2ZXIvQXVkaW9GbGluZ2VyL0F1ZGlvTWl4ZXIuaAorKioKKyoqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfQVVESU9fTUlYRVJfSAorI2RlZmluZSBBTkRST0lEX0FVRElPX01JWEVSX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSAiQXVkaW9CdWZmZXJQcm92aWRlci5oIgorI2luY2x1ZGUgIkF1ZGlvUmVzYW1wbGVyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQXVkaW9NaXhlcgoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1ZGlvTWl4ZXIoc2l6ZV90IGZyYW1lQ291bnQsIHVpbnQzMl90IHNhbXBsZVJhdGUpOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfkF1ZGlvTWl4ZXIoKTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBNQVhfTlVNX1RSQUNLUyA9IDMyOworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBNQVhfTlVNX0NIQU5ORUxTID0gMjsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MTZfdCBVTklUWV9HQUlOID0gMHgxMDAwOworCisgICAgZW51bSB7IC8vIG5hbWVzCisKKyAgICAgICAgLy8gdHJhY2sgdW5pdHMgKDMyIHVuaXRzKQorICAgICAgICBUUkFDSzAgICAgICAgICAgPSAweDEwMDAsCisKKyAgICAgICAgLy8gZW5hYmxlL2Rpc2FibGUKKyAgICAgICAgTUlYSU5HICAgICAgICAgID0gMHgyMDAwLAorCisgICAgICAgIC8vIHNldFBhcmFtZXRlciB0YXJnZXRzCisgICAgICAgIFRSQUNLICAgICAgICAgICA9IDB4MzAwMCwKKyAgICAgICAgUkVTQU1QTEUgICAgICAgID0gMHgzMDAxLAorICAgICAgICBSQU1QX1ZPTFVNRSAgICAgPSAweDMwMDIsIC8vIHJhbXAgdG8gbmV3IHZvbHVtZQorICAgICAgICBWT0xVTUUgICAgICAgICAgPSAweDMwMDMsIC8vIGRvbid0IHJhbXAKKworICAgICAgICAvLyBzZXQgUGFyYW1ldGVyIG5hbWVzCisgICAgICAgIC8vIGZvciB0YXJnZXQgVFJBQ0sKKyAgICAgICAgQ0hBTk5FTF9DT1VOVCAgID0gMHg0MDAwLAorICAgICAgICBGT1JNQVQgICAgICAgICAgPSAweDQwMDEsCisgICAgICAgIC8vIGZvciBUQVJHRVQgUkVTQU1QTEUKKyAgICAgICAgU0FNUExFX1JBVEUgICAgID0gMHg0MTAwLAorICAgICAgICAvLyBmb3IgVEFSR0VUIFZPTFVNRSAoOCBjaGFubmVscyBtYXgpCisgICAgICAgIFZPTFVNRTAgICAgICAgICA9IDB4NDIwMCwKKyAgICAgICAgVk9MVU1FMSAgICAgICAgID0gMHg0MjAxLAorICAgIH07CisKKworICAgIGludCAgICAgICAgIGdldFRyYWNrTmFtZSgpOworICAgIHZvaWQgICAgICAgIGRlbGV0ZVRyYWNrTmFtZShpbnQgbmFtZSk7CisKKyAgICBzdGF0dXNfdCAgICBlbmFibGUoaW50IG5hbWUpOworICAgIHN0YXR1c190ICAgIGRpc2FibGUoaW50IG5hbWUpOworCisgICAgc3RhdHVzX3QgICAgc2V0QWN0aXZlVHJhY2soaW50IHRyYWNrKTsKKyAgICBzdGF0dXNfdCAgICBzZXRQYXJhbWV0ZXIoaW50IHRhcmdldCwgaW50IG5hbWUsIGludCB2YWx1ZSk7CisKKyAgICBzdGF0dXNfdCAgICBzZXRCdWZmZXJQcm92aWRlcihBdWRpb0J1ZmZlclByb3ZpZGVyKiBidWZmZXJQcm92aWRlcik7CisgICAgdm9pZCAgICAgICAgcHJvY2Vzcyh2b2lkKiBvdXRwdXQpOworCisgICAgdWludDMyX3QgICAgdHJhY2tOYW1lcygpIGNvbnN0IHsgcmV0dXJuIG1UcmFja05hbWVzOyB9CisKK3ByaXZhdGU6CisKKyAgICBlbnVtIHsKKyAgICAgICAgTkVFRFNfQ0hBTk5FTF9DT1VOVF9fTUFTSyAgID0gMHgwMDAwMDAwMywKKyAgICAgICAgTkVFRFNfRk9STUFUX19NQVNLICAgICAgICAgID0gMHgwMDAwMDBGMCwKKyAgICAgICAgTkVFRFNfTVVURV9fTUFTSyAgICAgICAgICAgID0gMHgwMDAwMDEwMCwKKyAgICAgICAgTkVFRFNfUkVTQU1QTEVfX01BU0sgICAgICAgID0gMHgwMDAwMTAwMCwKKyAgICB9OworCisgICAgZW51bSB7CisgICAgICAgIE5FRURTX0NIQU5ORUxfMSAgICAgICAgICAgICA9IDB4MDAwMDAwMDAsCisgICAgICAgIE5FRURTX0NIQU5ORUxfMiAgICAgICAgICAgICA9IDB4MDAwMDAwMDEsCisKKyAgICAgICAgTkVFRFNfRk9STUFUXzE2ICAgICAgICAgICAgID0gMHgwMDAwMDAxMCwKKworICAgICAgICBORUVEU19NVVRFX0RJU0FCTEVEICAgICAgICAgPSAweDAwMDAwMDAwLAorICAgICAgICBORUVEU19NVVRFX0VOQUJMRUQgICAgICAgICAgPSAweDAwMDAwMTAwLAorCisgICAgICAgIE5FRURTX1JFU0FNUExFX0RJU0FCTEVEICAgICA9IDB4MDAwMDAwMDAsCisgICAgICAgIE5FRURTX1JFU0FNUExFX0VOQUJMRUQgICAgICA9IDB4MDAwMDEwMDAsCisgICAgfTsKKworICAgIHN0YXRpYyBpbmxpbmUgaW50MzJfdCBhcHBseVZvbHVtZShpbnQzMl90IGluLCBpbnQzMl90IHYpIHsKKyAgICAgICAgcmV0dXJuIGluICogdjsKKyAgICB9CisKKworICAgIHN0cnVjdCBzdGF0ZV90OworCisgICAgdHlwZWRlZiB2b2lkICgqbWl4X3QpKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpOworCisgICAgc3RhdGljIGNvbnN0IGludCBCTE9DS1NJWkUgPSAxNjsgLy8gNCBjYWNoZSBsaW5lcworCisgICAgc3RydWN0IHRyYWNrX3QgeworICAgICAgICB1aW50MzJfdCAgICBuZWVkczsKKworICAgICAgICB1bmlvbiB7CisgICAgICAgIGludDE2X3QgICAgIHZvbHVtZVsyXTsgICAgICAvLyBbMF0zLjEyIGZpeGVkIHBvaW50CisgICAgICAgIGludDMyX3QgICAgIHZvbHVtZVJMOworICAgICAgICB9OworCisgICAgICAgIGludDMyX3QgICAgIHByZXZWb2x1bWVbMl07CisKKyAgICAgICAgaW50MzJfdCAgICAgdm9sdW1lSW5jWzJdOworCisgICAgICAgIHVpbnQxNl90ICAgIGZyYW1lQ291bnQ7CisKKyAgICAgICAgdWludDhfdCAgICAgY2hhbm5lbENvdW50IDogNDsKKyAgICAgICAgdWludDhfdCAgICAgZW5hYmxlZCAgICAgIDogMTsKKyAgICAgICAgdWludDhfdCAgICAgcmVzZXJ2ZWQwICAgIDogMzsKKyAgICAgICAgdWludDhfdCAgICAgZm9ybWF0OworCisgICAgICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXIqICAgICAgICAgICAgICAgIGJ1ZmZlclByb3ZpZGVyOworICAgICAgICBtdXRhYmxlIEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciBidWZmZXI7CisKKyAgICAgICAgdm9pZCAoKmhvb2spKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dHB1dCwgc2l6ZV90IG51bU91dEZyYW1lcywgaW50MzJfdCogdGVtcCk7CisgICAgICAgIHZvaWQgY29uc3QqIGluOyAgICAgICAgICAgICAvLyBjdXJyZW50IGxvY2F0aW9uIGluIGJ1ZmZlcgorCisgICAgICAgIEF1ZGlvUmVzYW1wbGVyKiAgICAgcmVzYW1wbGVyOworICAgICAgICB1aW50MzJfdCAgICAgICAgICAgIHNhbXBsZVJhdGU7CisKKyAgICAgICAgYm9vbCAgICAgICAgc2V0UmVzYW1wbGVyKHVpbnQzMl90IHNhbXBsZVJhdGUsIHVpbnQzMl90IGRldlNhbXBsZVJhdGUpOworICAgICAgICBib29sICAgICAgICBkb2VzUmVzYW1wbGUoKSBjb25zdDsKKyAgICAgICAgdm9pZCAgICAgICAgYWRqdXN0Vm9sdW1lUmFtcCgpOworICAgIH07CisKKyAgICAvLyBwYWQgdG8gMzItYnl0ZXMgdG8gZmlsbCBjYWNoZSBsaW5lCisgICAgc3RydWN0IHN0YXRlX3QgeworICAgICAgICB1aW50MzJfdCAgICAgICAgZW5hYmxlZFRyYWNrczsKKyAgICAgICAgdWludDMyX3QgICAgICAgIG5lZWRzQ2hhbmdlZDsKKyAgICAgICAgc2l6ZV90ICAgICAgICAgIGZyYW1lQ291bnQ7CisgICAgICAgIG1peF90ICAgICAgICAgICBob29rOworICAgICAgICBpbnQzMl90ICAgICAgICAgKm91dHB1dFRlbXA7CisgICAgICAgIGludDMyX3QgICAgICAgICAqcmVzYW1wbGVUZW1wOworICAgICAgICBpbnQzMl90ICAgICAgICAgcmVzZXJ2ZWRbMl07CisgICAgICAgIHRyYWNrX3QgICAgICAgICB0cmFja3NbMzJdOyBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDMyKSkpOworICAgIH07CisKKyAgICBpbnQgICAgICAgICAgICAgbUFjdGl2ZVRyYWNrOworICAgIHVpbnQzMl90ICAgICAgICBtVHJhY2tOYW1lczsKKyAgICBjb25zdCB1aW50MzJfdCAgbVNhbXBsZVJhdGU7CisKKyAgICBzdGF0ZV90ICAgICAgICAgbVN0YXRlIF9fYXR0cmlidXRlX18oKGFsaWduZWQoMzIpKSk7CisKKyAgICB2b2lkIGludmFsaWRhdGVTdGF0ZSh1aW50MzJfdCBtYXNrKTsKKworICAgIHN0YXRpYyB2b2lkIHRyYWNrX19nZW5lcmljUmVzYW1wbGUodHJhY2tfdCogdCwgaW50MzJfdCogb3V0LCBzaXplX3QgbnVtRnJhbWVzLCBpbnQzMl90KiB0ZW1wKTsKKyAgICBzdGF0aWMgdm9pZCB0cmFja19fbm9wKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dCwgc2l6ZV90IG51bUZyYW1lcywgaW50MzJfdCogdGVtcCk7CisgICAgc3RhdGljIHZvaWQgdm9sdW1lUmFtcFN0ZXJlbyh0cmFja190KiB0LCBpbnQzMl90KiBvdXQsIHNpemVfdCBmcmFtZUNvdW50LCBpbnQzMl90KiB0ZW1wKTsKKyAgICBzdGF0aWMgdm9pZCB0cmFja19fMTZCaXRzU3RlcmVvKHRyYWNrX3QqIHQsIGludDMyX3QqIG91dCwgc2l6ZV90IG51bUZyYW1lcywgaW50MzJfdCogdGVtcCk7CisgICAgc3RhdGljIHZvaWQgdHJhY2tfXzE2Qml0c01vbm8odHJhY2tfdCogdCwgaW50MzJfdCogb3V0LCBzaXplX3QgbnVtRnJhbWVzLCBpbnQzMl90KiB0ZW1wKTsKKyAgICBzdGF0aWMgdm9pZCBkaXRoZXJBbmRDbGFtcChpbnQzMl90KiBvdXQsIGludDMyX3QgY29uc3QgKnN1bXMsIHNpemVfdCBjKTsKKworICAgIHN0YXRpYyB2b2lkIHByb2Nlc3NfX3ZhbGlkYXRlKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpOworICAgIHN0YXRpYyB2b2lkIHByb2Nlc3NfX25vcChzdGF0ZV90KiBzdGF0ZSwgdm9pZCogb3V0cHV0KTsKKyAgICBzdGF0aWMgdm9pZCBwcm9jZXNzX19nZW5lcmljTm9SZXNhbXBsaW5nKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpOworICAgIHN0YXRpYyB2b2lkIHByb2Nlc3NfX2dlbmVyaWNSZXNhbXBsaW5nKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpOworICAgIHN0YXRpYyB2b2lkIHByb2Nlc3NfX09uZVRyYWNrMTZCaXRzU3RlcmVvTm9SZXNhbXBsaW5nKHN0YXRlX3QqIHN0YXRlLCB2b2lkKiBvdXRwdXQpOworICAgIHN0YXRpYyB2b2lkIHByb2Nlc3NfX1R3b1RyYWNrczE2Qml0c1N0ZXJlb05vUmVzYW1wbGluZyhzdGF0ZV90KiBzdGF0ZSwgdm9pZCogb3V0cHV0KTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0FVRElPX01JWEVSX0gKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyLmNwcCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGFiYWNiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9SZXNhbXBsZXIuY3BwCkBAIC0wLDAgKzEsNTk1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJBdWRpb1Jlc2FtcGxlciIKKy8vI2RlZmluZSBMT0dfTkRFQlVHIDAKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKyNpbmNsdWRlIDxjdXRpbHMvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgIkF1ZGlvUmVzYW1wbGVyLmgiCisjaW5jbHVkZSAiQXVkaW9SZXNhbXBsZXJTaW5jLmgiCisjaW5jbHVkZSAiQXVkaW9SZXNhbXBsZXJDdWJpYy5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKyNpZmRlZiBfX0FSTV9BUkNIXzVFX18gIC8vIG9wdGltaXplZCBhc20gb3B0aW9uCisgICAgI2RlZmluZSBBU01fQVJNX1JFU0FNUDEgLy8gZW5hYmxlIGFzbSBvcHRpbWlzYXRpb24gZm9yIFJlc2FtcGxlck9yZGVyMQorI2VuZGlmIC8vIF9fQVJNX0FSQ0hfNUVfXworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBBdWRpb1Jlc2FtcGxlck9yZGVyMSA6IHB1YmxpYyBBdWRpb1Jlc2FtcGxlciB7CitwdWJsaWM6CisgICAgQXVkaW9SZXNhbXBsZXJPcmRlcjEoaW50IGJpdERlcHRoLCBpbnQgaW5DaGFubmVsQ291bnQsIGludDMyX3Qgc2FtcGxlUmF0ZSkgOgorICAgICAgICBBdWRpb1Jlc2FtcGxlcihiaXREZXB0aCwgaW5DaGFubmVsQ291bnQsIHNhbXBsZVJhdGUpLCBtWDBMKDApLCBtWDBSKDApIHsKKyAgICB9CisgICAgdmlydHVhbCB2b2lkIHJlc2FtcGxlKGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcik7Citwcml2YXRlOgorICAgIC8vIG51bWJlciBvZiBiaXRzIHVzZWQgaW4gaW50ZXJwb2xhdGlvbiBtdWx0aXBseSAtIDE1IGJpdHMgYXZvaWRzIG92ZXJmbG93CisgICAgc3RhdGljIGNvbnN0IGludCBrTnVtSW50ZXJwQml0cyA9IDE1OworCisgICAgLy8gYml0cyB0byBzaGlmdCB0aGUgcGhhc2UgZnJhY3Rpb24gZG93biB0byBhdm9pZCBvdmVyZmxvdworICAgIHN0YXRpYyBjb25zdCBpbnQga1ByZUludGVycFNoaWZ0ID0ga051bVBoYXNlQml0cyAtIGtOdW1JbnRlcnBCaXRzOworCisgICAgdm9pZCBpbml0KCkge30KKyAgICB2b2lkIHJlc2FtcGxlTW9ubzE2KGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcik7CisgICAgdm9pZCByZXNhbXBsZVN0ZXJlbzE2KGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcik7CisjaWZkZWYgQVNNX0FSTV9SRVNBTVAxICAvLyBhc20gb3B0aW1pc2F0aW9uIGZvciBSZXNhbXBsZXJPcmRlcjEKKyAgICB2b2lkIEFzbU1vbm8xNkxvb3AoaW50MTZfdCAqaW4sIGludDMyX3QqIG1heE91dFB0LCBpbnQzMl90IG1heEluSWR4LAorICAgICAgICAgICAgc2l6ZV90ICZvdXRwdXRJbmRleCwgaW50MzJfdCogb3V0LCBzaXplX3QgJmlucHV0SW5kZXgsIGludDMyX3QgdmwsIGludDMyX3QgdnIsCisgICAgICAgICAgICB1aW50MzJfdCAmcGhhc2VGcmFjdGlvbiwgdWludDMyX3QgcGhhc2VJbmNyZW1lbnQpOworICAgIHZvaWQgQXNtU3RlcmVvMTZMb29wKGludDE2X3QgKmluLCBpbnQzMl90KiBtYXhPdXRQdCwgaW50MzJfdCBtYXhJbklkeCwKKyAgICAgICAgICAgIHNpemVfdCAmb3V0cHV0SW5kZXgsIGludDMyX3QqIG91dCwgc2l6ZV90ICZpbnB1dEluZGV4LCBpbnQzMl90IHZsLCBpbnQzMl90IHZyLAorICAgICAgICAgICAgdWludDMyX3QgJnBoYXNlRnJhY3Rpb24sIHVpbnQzMl90IHBoYXNlSW5jcmVtZW50KTsKKyNlbmRpZiAgLy8gQVNNX0FSTV9SRVNBTVAxCisKKyAgICBzdGF0aWMgaW5saW5lIGludDMyX3QgSW50ZXJwKGludDMyX3QgeDAsIGludDMyX3QgeDEsIHVpbnQzMl90IGYpIHsKKyAgICAgICAgcmV0dXJuIHgwICsgKCgoeDEgLSB4MCkgKiAoaW50MzJfdCkoZiA+PiBrUHJlSW50ZXJwU2hpZnQpKSA+PiBrTnVtSW50ZXJwQml0cyk7CisgICAgfQorICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBBZHZhbmNlKHNpemVfdCogaW5kZXgsIHVpbnQzMl90KiBmcmFjLCB1aW50MzJfdCBpbmMpIHsKKyAgICAgICAgKmZyYWMgKz0gaW5jOworICAgICAgICAqaW5kZXggKz0gKHNpemVfdCkoKmZyYWMgPj4ga051bVBoYXNlQml0cyk7CisgICAgICAgICpmcmFjICY9IGtQaGFzZU1hc2s7CisgICAgfQorICAgIGludCBtWDBMOworICAgIGludCBtWDBSOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorQXVkaW9SZXNhbXBsZXIqIEF1ZGlvUmVzYW1wbGVyOjpjcmVhdGUoaW50IGJpdERlcHRoLCBpbnQgaW5DaGFubmVsQ291bnQsCisgICAgICAgIGludDMyX3Qgc2FtcGxlUmF0ZSwgaW50IHF1YWxpdHkpIHsKKworICAgIC8vIGNhbiBvbmx5IGNyZWF0ZSBsb3cgcXVhbGl0eSByZXNhbXBsZSBub3cKKyAgICBBdWRpb1Jlc2FtcGxlciogcmVzYW1wbGVyOworCisgICAgY2hhciB2YWx1ZVtQUk9QRVJUWV9WQUxVRV9NQVhdOworICAgIGlmIChwcm9wZXJ0eV9nZXQoImFmLnJlc2FtcGxlci5xdWFsaXR5IiwgdmFsdWUsIDApKSB7CisgICAgICAgIHF1YWxpdHkgPSBhdG9pKHZhbHVlKTsKKyAgICAgICAgTE9HRCgiZm9yY2luZyBBdWRpb1Jlc2FtcGxlciBxdWFsaXR5IHRvICVkIiwgcXVhbGl0eSk7CisgICAgfQorCisgICAgaWYgKHF1YWxpdHkgPT0gREVGQVVMVCkKKyAgICAgICAgcXVhbGl0eSA9IExPV19RVUFMSVRZOworCisgICAgc3dpdGNoIChxdWFsaXR5KSB7CisgICAgZGVmYXVsdDoKKyAgICBjYXNlIExPV19RVUFMSVRZOgorICAgICAgICBMT0dWKCJDcmVhdGUgbGluZWFyIFJlc2FtcGxlciIpOworICAgICAgICByZXNhbXBsZXIgPSBuZXcgQXVkaW9SZXNhbXBsZXJPcmRlcjEoYml0RGVwdGgsIGluQ2hhbm5lbENvdW50LCBzYW1wbGVSYXRlKTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBNRURfUVVBTElUWToKKyAgICAgICAgTE9HVigiQ3JlYXRlIGN1YmljIFJlc2FtcGxlciIpOworICAgICAgICByZXNhbXBsZXIgPSBuZXcgQXVkaW9SZXNhbXBsZXJDdWJpYyhiaXREZXB0aCwgaW5DaGFubmVsQ291bnQsIHNhbXBsZVJhdGUpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEhJR0hfUVVBTElUWToKKyAgICAgICAgTE9HVigiQ3JlYXRlIHNpbmMgUmVzYW1wbGVyIik7CisgICAgICAgIHJlc2FtcGxlciA9IG5ldyBBdWRpb1Jlc2FtcGxlclNpbmMoYml0RGVwdGgsIGluQ2hhbm5lbENvdW50LCBzYW1wbGVSYXRlKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgLy8gaW5pdGlhbGl6ZSByZXNhbXBsZXIKKyAgICByZXNhbXBsZXItPmluaXQoKTsKKyAgICByZXR1cm4gcmVzYW1wbGVyOworfQorCitBdWRpb1Jlc2FtcGxlcjo6QXVkaW9SZXNhbXBsZXIoaW50IGJpdERlcHRoLCBpbnQgaW5DaGFubmVsQ291bnQsCisgICAgICAgIGludDMyX3Qgc2FtcGxlUmF0ZSkgOgorICAgIG1CaXREZXB0aChiaXREZXB0aCksIG1DaGFubmVsQ291bnQoaW5DaGFubmVsQ291bnQpLAorICAgICAgICAgICAgbVNhbXBsZVJhdGUoc2FtcGxlUmF0ZSksIG1JblNhbXBsZVJhdGUoc2FtcGxlUmF0ZSksIG1JbnB1dEluZGV4KDApLAorICAgICAgICAgICAgbVBoYXNlRnJhY3Rpb24oMCkgeworICAgIC8vIHNhbml0eSBjaGVjayBvbiBmb3JtYXQKKyAgICBpZiAoKGJpdERlcHRoICE9IDE2KSB8fChpbkNoYW5uZWxDb3VudCA8IDEpIHx8IChpbkNoYW5uZWxDb3VudCA+IDIpKSB7CisgICAgICAgIExPR0UoIlVuc3VwcG9ydGVkIHNhbXBsZSBmb3JtYXQsICVkIGJpdHMsICVkIGNoYW5uZWxzIiwgYml0RGVwdGgsCisgICAgICAgICAgICAgICAgaW5DaGFubmVsQ291bnQpOworICAgICAgICAvLyBMT0dfQVNTRVJUKDApOworICAgIH0KKworICAgIC8vIGluaXRpYWxpemUgY29tbW9uIG1lbWJlcnMKKyAgICBtVm9sdW1lWzBdID0gbVZvbHVtZVsxXSA9IDA7CisgICAgbUJ1ZmZlci5mcmFtZUNvdW50ID0gMDsKKworICAgIC8vIHNhdmUgZm9ybWF0IGZvciBxdWljayBsb29rdXAKKyAgICBpZiAoaW5DaGFubmVsQ291bnQgPT0gMSkgeworICAgICAgICBtRm9ybWF0ID0gTU9OT18xNl9CSVQ7CisgICAgfSBlbHNlIHsKKyAgICAgICAgbUZvcm1hdCA9IFNURVJFT18xNl9CSVQ7CisgICAgfQorfQorCitBdWRpb1Jlc2FtcGxlcjo6fkF1ZGlvUmVzYW1wbGVyKCkgeworfQorCit2b2lkIEF1ZGlvUmVzYW1wbGVyOjpzZXRTYW1wbGVSYXRlKGludDMyX3QgaW5TYW1wbGVSYXRlKSB7CisgICAgbUluU2FtcGxlUmF0ZSA9IGluU2FtcGxlUmF0ZTsKKyAgICBtUGhhc2VJbmNyZW1lbnQgPSAodWludDMyX3QpKChrUGhhc2VNdWx0aXBsaWVyICogaW5TYW1wbGVSYXRlKSAvIG1TYW1wbGVSYXRlKTsKK30KKwordm9pZCBBdWRpb1Jlc2FtcGxlcjo6c2V0Vm9sdW1lKGludDE2X3QgbGVmdCwgaW50MTZfdCByaWdodCkgeworICAgIC8vIFRPRE86IEltcGxlbWVudCBhbnRpLXppcHBlciBmaWx0ZXIKKyAgICBtVm9sdW1lWzBdID0gbGVmdDsKKyAgICBtVm9sdW1lWzFdID0gcmlnaHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBBdWRpb1Jlc2FtcGxlck9yZGVyMTo6cmVzYW1wbGUoaW50MzJfdCogb3V0LCBzaXplX3Qgb3V0RnJhbWVDb3VudCwKKyAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpIHsKKworICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCB3ZSBvdmVyZmxvdyBpZiBpdCBkb2VzCisgICAgLy8gTE9HX0FTU0VSVChvdXRGcmFtZUNvdW50IDwgMzI3NjcpOworCisgICAgLy8gc2VsZWN0IHRoZSBhcHByb3ByaWF0ZSByZXNhbXBsZXIKKyAgICBzd2l0Y2ggKG1DaGFubmVsQ291bnQpIHsKKyAgICBjYXNlIDE6CisgICAgICAgIHJlc2FtcGxlTW9ubzE2KG91dCwgb3V0RnJhbWVDb3VudCwgcHJvdmlkZXIpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDI6CisgICAgICAgIHJlc2FtcGxlU3RlcmVvMTYob3V0LCBvdXRGcmFtZUNvdW50LCBwcm92aWRlcik7CisgICAgICAgIGJyZWFrOworICAgIH0KK30KKwordm9pZCBBdWRpb1Jlc2FtcGxlck9yZGVyMTo6cmVzYW1wbGVTdGVyZW8xNihpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LAorICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcikgeworCisgICAgaW50MzJfdCB2bCA9IG1Wb2x1bWVbMF07CisgICAgaW50MzJfdCB2ciA9IG1Wb2x1bWVbMV07CisKKyAgICBzaXplX3QgaW5wdXRJbmRleCA9IG1JbnB1dEluZGV4OworICAgIHVpbnQzMl90IHBoYXNlRnJhY3Rpb24gPSBtUGhhc2VGcmFjdGlvbjsKKyAgICB1aW50MzJfdCBwaGFzZUluY3JlbWVudCA9IG1QaGFzZUluY3JlbWVudDsKKyAgICBzaXplX3Qgb3V0cHV0SW5kZXggPSAwOworICAgIHNpemVfdCBvdXRwdXRTYW1wbGVDb3VudCA9IG91dEZyYW1lQ291bnQgKiAyOworICAgIHNpemVfdCBpbkZyYW1lQ291bnQgPSAob3V0RnJhbWVDb3VudCptSW5TYW1wbGVSYXRlKS9tU2FtcGxlUmF0ZTsKKworICAgIC8vIExPR0UoInN0YXJ0aW5nIHJlc2FtcGxlICVkIGZyYW1lcywgaW5wdXRJbmRleD0lZCwgcGhhc2VGcmFjdGlvbj0lZCwgcGhhc2VJbmNyZW1lbnQ9JWRcbiIsCisgICAgLy8gICAgICBvdXRGcmFtZUNvdW50LCBpbnB1dEluZGV4LCBwaGFzZUZyYWN0aW9uLCBwaGFzZUluY3JlbWVudCk7CisKKyAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCkgeworCisgICAgICAgIC8vIGJ1ZmZlciBpcyBlbXB0eSwgZmV0Y2ggYSBuZXcgb25lCisgICAgICAgIHdoaWxlIChtQnVmZmVyLmZyYW1lQ291bnQgPT0gMCkgeworICAgICAgICAgICAgbUJ1ZmZlci5mcmFtZUNvdW50ID0gaW5GcmFtZUNvdW50OworICAgICAgICAgICAgcHJvdmlkZXItPmdldE5leHRCdWZmZXIoJm1CdWZmZXIpOworICAgICAgICAgICAgaWYgKG1CdWZmZXIucmF3ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBnb3RvIHJlc2FtcGxlU3RlcmVvMTZfZXhpdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gTE9HRSgiTmV3IGJ1ZmZlciBmZXRjaGVkOiAlZCBmcmFtZXNcbiIsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgICAgICAgICBpZiAobUJ1ZmZlci5mcmFtZUNvdW50ID4gaW5wdXRJbmRleCkgYnJlYWs7CisKKyAgICAgICAgICAgIGlucHV0SW5kZXggLT0gbUJ1ZmZlci5mcmFtZUNvdW50OworICAgICAgICAgICAgbVgwTCA9IG1CdWZmZXIuaTE2W21CdWZmZXIuZnJhbWVDb3VudCoyLTJdOworICAgICAgICAgICAgbVgwUiA9IG1CdWZmZXIuaTE2W21CdWZmZXIuZnJhbWVDb3VudCoyLTFdOworICAgICAgICAgICAgcHJvdmlkZXItPnJlbGVhc2VCdWZmZXIoJm1CdWZmZXIpOworICAgICAgICAgICAgIC8vIG1CdWZmZXIuZnJhbWVDb3VudCA9PSAwIG5vdyBzbyB3ZSByZWxvYWQgYSBuZXcgYnVmZmVyCisgICAgICAgIH0KKworICAgICAgICBpbnQxNl90ICppbiA9IG1CdWZmZXIuaTE2OworCisgICAgICAgIC8vIGhhbmRsZSBib3VuZGFyeSBjYXNlCisgICAgICAgIHdoaWxlIChpbnB1dEluZGV4ID09IDApIHsKKyAgICAgICAgICAgIC8vIExPR0UoImJvdW5kYXJ5IGNhc2VcbiIpOworICAgICAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IHZsICogSW50ZXJwKG1YMEwsIGluWzBdLCBwaGFzZUZyYWN0aW9uKTsKKyAgICAgICAgICAgIG91dFtvdXRwdXRJbmRleCsrXSArPSB2ciAqIEludGVycChtWDBSLCBpblsxXSwgcGhhc2VGcmFjdGlvbik7CisgICAgICAgICAgICBBZHZhbmNlKCZpbnB1dEluZGV4LCAmcGhhc2VGcmFjdGlvbiwgcGhhc2VJbmNyZW1lbnQpOworICAgICAgICAgICAgaWYgKG91dHB1dEluZGV4ID09IG91dHB1dFNhbXBsZUNvdW50KQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgLy8gcHJvY2VzcyBpbnB1dCBzYW1wbGVzCisgICAgICAgIC8vIExPR0UoImdlbmVyYWwgY2FzZVxuIik7CisKKyNpZmRlZiBBU01fQVJNX1JFU0FNUDEgIC8vIGFzbSBvcHRpbWlzYXRpb24gZm9yIFJlc2FtcGxlck9yZGVyMQorICAgICAgICBpZiAoaW5wdXRJbmRleCArIDIgPCBtQnVmZmVyLmZyYW1lQ291bnQpIHsKKyAgICAgICAgICAgIGludDMyX3QqIG1heE91dFB0OworICAgICAgICAgICAgaW50MzJfdCBtYXhJbklkeDsKKworICAgICAgICAgICAgbWF4T3V0UHQgPSBvdXQgKyAob3V0cHV0U2FtcGxlQ291bnQgLSAyKTsgICAvLyAyIGJlY2F1c2UgMiBmcmFtZXMgcGVyIGxvb3AKKyAgICAgICAgICAgIG1heEluSWR4ID0gbUJ1ZmZlci5mcmFtZUNvdW50IC0gMjsKKyAgICAgICAgICAgIEFzbVN0ZXJlbzE2TG9vcChpbiwgbWF4T3V0UHQsIG1heEluSWR4LCBvdXRwdXRJbmRleCwgb3V0LCBpbnB1dEluZGV4LCB2bCwgdnIsCisgICAgICAgICAgICAgICAgICAgIHBoYXNlRnJhY3Rpb24sIHBoYXNlSW5jcmVtZW50KTsKKyAgICAgICAgfQorI2VuZGlmICAvLyBBU01fQVJNX1JFU0FNUDEKKworICAgICAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCAmJiBpbnB1dEluZGV4IDwgbUJ1ZmZlci5mcmFtZUNvdW50KSB7CisgICAgICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdmwgKiBJbnRlcnAoaW5baW5wdXRJbmRleCoyLTJdLAorICAgICAgICAgICAgICAgICAgICBpbltpbnB1dEluZGV4KjJdLCBwaGFzZUZyYWN0aW9uKTsKKyAgICAgICAgICAgIG91dFtvdXRwdXRJbmRleCsrXSArPSB2ciAqIEludGVycChpbltpbnB1dEluZGV4KjItMV0sCisgICAgICAgICAgICAgICAgICAgIGluW2lucHV0SW5kZXgqMisxXSwgcGhhc2VGcmFjdGlvbik7CisgICAgICAgICAgICBBZHZhbmNlKCZpbnB1dEluZGV4LCAmcGhhc2VGcmFjdGlvbiwgcGhhc2VJbmNyZW1lbnQpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTE9HRSgibG9vcCBkb25lIC0gb3V0cHV0SW5kZXg9JWQsIGlucHV0SW5kZXg9JWRcbiIsIG91dHB1dEluZGV4LCBpbnB1dEluZGV4KTsKKworICAgICAgICAvLyBpZiBkb25lIHdpdGggYnVmZmVyLCBzYXZlIHNhbXBsZXMKKyAgICAgICAgaWYgKGlucHV0SW5kZXggPj0gbUJ1ZmZlci5mcmFtZUNvdW50KSB7CisgICAgICAgICAgICBpbnB1dEluZGV4IC09IG1CdWZmZXIuZnJhbWVDb3VudDsKKworICAgICAgICAgICAgLy8gTE9HRSgiYnVmZmVyIGRvbmUsIG5ldyBpbnB1dCBpbmRleCAlZCIsIGlucHV0SW5kZXgpOworCisgICAgICAgICAgICBtWDBMID0gbUJ1ZmZlci5pMTZbbUJ1ZmZlci5mcmFtZUNvdW50KjItMl07CisgICAgICAgICAgICBtWDBSID0gbUJ1ZmZlci5pMTZbbUJ1ZmZlci5mcmFtZUNvdW50KjItMV07CisgICAgICAgICAgICBwcm92aWRlci0+cmVsZWFzZUJ1ZmZlcigmbUJ1ZmZlcik7CisKKyAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSByZWxlYXNlQnVmZmVyIHJlc2V0cyB0aGUgYnVmZmVyIGZyYW1lQ291bnQKKyAgICAgICAgICAgIC8vIExPR19BU1NFUlQobUJ1ZmZlci5mcmFtZUNvdW50ID09IDApOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gTE9HRSgib3V0cHV0IGJ1ZmZlciBmdWxsIC0gb3V0cHV0SW5kZXg9JWQsIGlucHV0SW5kZXg9JWRcbiIsIG91dHB1dEluZGV4LCBpbnB1dEluZGV4KTsKKworcmVzYW1wbGVTdGVyZW8xNl9leGl0OgorICAgIC8vIHNhdmUgc3RhdGUKKyAgICBtSW5wdXRJbmRleCA9IGlucHV0SW5kZXg7CisgICAgbVBoYXNlRnJhY3Rpb24gPSBwaGFzZUZyYWN0aW9uOworfQorCit2b2lkIEF1ZGlvUmVzYW1wbGVyT3JkZXIxOjpyZXNhbXBsZU1vbm8xNihpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LAorICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcikgeworCisgICAgaW50MzJfdCB2bCA9IG1Wb2x1bWVbMF07CisgICAgaW50MzJfdCB2ciA9IG1Wb2x1bWVbMV07CisKKyAgICBzaXplX3QgaW5wdXRJbmRleCA9IG1JbnB1dEluZGV4OworICAgIHVpbnQzMl90IHBoYXNlRnJhY3Rpb24gPSBtUGhhc2VGcmFjdGlvbjsKKyAgICB1aW50MzJfdCBwaGFzZUluY3JlbWVudCA9IG1QaGFzZUluY3JlbWVudDsKKyAgICBzaXplX3Qgb3V0cHV0SW5kZXggPSAwOworICAgIHNpemVfdCBvdXRwdXRTYW1wbGVDb3VudCA9IG91dEZyYW1lQ291bnQgKiAyOworICAgIHNpemVfdCBpbkZyYW1lQ291bnQgPSAob3V0RnJhbWVDb3VudCptSW5TYW1wbGVSYXRlKS9tU2FtcGxlUmF0ZTsKKworICAgIC8vIExPR0UoInN0YXJ0aW5nIHJlc2FtcGxlICVkIGZyYW1lcywgaW5wdXRJbmRleD0lZCwgcGhhc2VGcmFjdGlvbj0lZCwgcGhhc2VJbmNyZW1lbnQ9JWRcbiIsCisgICAgLy8gICAgICBvdXRGcmFtZUNvdW50LCBpbnB1dEluZGV4LCBwaGFzZUZyYWN0aW9uLCBwaGFzZUluY3JlbWVudCk7CisgICAgd2hpbGUgKG91dHB1dEluZGV4IDwgb3V0cHV0U2FtcGxlQ291bnQpIHsKKyAgICAgICAgLy8gYnVmZmVyIGlzIGVtcHR5LCBmZXRjaCBhIG5ldyBvbmUKKyAgICAgICAgd2hpbGUgKG1CdWZmZXIuZnJhbWVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICBtQnVmZmVyLmZyYW1lQ291bnQgPSBpbkZyYW1lQ291bnQ7CisgICAgICAgICAgICBwcm92aWRlci0+Z2V0TmV4dEJ1ZmZlcigmbUJ1ZmZlcik7CisgICAgICAgICAgICBpZiAobUJ1ZmZlci5yYXcgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIG1JbnB1dEluZGV4ID0gaW5wdXRJbmRleDsKKyAgICAgICAgICAgICAgICBtUGhhc2VGcmFjdGlvbiA9IHBoYXNlRnJhY3Rpb247CisgICAgICAgICAgICAgICAgZ290byByZXNhbXBsZU1vbm8xNl9leGl0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gTE9HRSgiTmV3IGJ1ZmZlciBmZXRjaGVkOiAlZCBmcmFtZXNcbiIsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgICAgICAgICBpZiAobUJ1ZmZlci5mcmFtZUNvdW50ID4gIGlucHV0SW5kZXgpIGJyZWFrOworCisgICAgICAgICAgICBpbnB1dEluZGV4IC09IG1CdWZmZXIuZnJhbWVDb3VudDsKKyAgICAgICAgICAgIG1YMEwgPSBtQnVmZmVyLmkxNlttQnVmZmVyLmZyYW1lQ291bnQtMV07CisgICAgICAgICAgICBwcm92aWRlci0+cmVsZWFzZUJ1ZmZlcigmbUJ1ZmZlcik7CisgICAgICAgICAgICAvLyBtQnVmZmVyLmZyYW1lQ291bnQgPT0gMCBub3cgc28gd2UgcmVsb2FkIGEgbmV3IGJ1ZmZlcgorICAgICAgICB9CisgICAgICAgIGludDE2X3QgKmluID0gbUJ1ZmZlci5pMTY7CisKKyAgICAgICAgLy8gaGFuZGxlIGJvdW5kYXJ5IGNhc2UKKyAgICAgICAgd2hpbGUgKGlucHV0SW5kZXggPT0gMCkgeworICAgICAgICAgICAgLy8gTE9HRSgiYm91bmRhcnkgY2FzZVxuIik7CisgICAgICAgICAgICBpbnQzMl90IHNhbXBsZSA9IEludGVycChtWDBMLCBpblswXSwgcGhhc2VGcmFjdGlvbik7CisgICAgICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdmwgKiBzYW1wbGU7CisgICAgICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdnIgKiBzYW1wbGU7CisgICAgICAgICAgICBBZHZhbmNlKCZpbnB1dEluZGV4LCAmcGhhc2VGcmFjdGlvbiwgcGhhc2VJbmNyZW1lbnQpOworICAgICAgICAgICAgaWYgKG91dHB1dEluZGV4ID09IG91dHB1dFNhbXBsZUNvdW50KQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgLy8gcHJvY2VzcyBpbnB1dCBzYW1wbGVzCisgICAgICAgIC8vIExPR0UoImdlbmVyYWwgY2FzZVxuIik7CisKKyNpZmRlZiBBU01fQVJNX1JFU0FNUDEgIC8vIGFzbSBvcHRpbWlzYXRpb24gZm9yIFJlc2FtcGxlck9yZGVyMQorICAgICAgICBpZiAoaW5wdXRJbmRleCArIDIgPCBtQnVmZmVyLmZyYW1lQ291bnQpIHsKKyAgICAgICAgICAgIGludDMyX3QqIG1heE91dFB0OworICAgICAgICAgICAgaW50MzJfdCBtYXhJbklkeDsKKworICAgICAgICAgICAgbWF4T3V0UHQgPSBvdXQgKyAob3V0cHV0U2FtcGxlQ291bnQgLSAyKTsKKyAgICAgICAgICAgIG1heEluSWR4ID0gKGludDMyX3QpbUJ1ZmZlci5mcmFtZUNvdW50IC0gMjsKKyAgICAgICAgICAgICAgICBBc21Nb25vMTZMb29wKGluLCBtYXhPdXRQdCwgbWF4SW5JZHgsIG91dHB1dEluZGV4LCBvdXQsIGlucHV0SW5kZXgsIHZsLCB2ciwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlRnJhY3Rpb24sIHBoYXNlSW5jcmVtZW50KTsKKyAgICAgICAgfQorI2VuZGlmICAvLyBBU01fQVJNX1JFU0FNUDEKKworICAgICAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCAmJiBpbnB1dEluZGV4IDwgbUJ1ZmZlci5mcmFtZUNvdW50KSB7CisgICAgICAgICAgICBpbnQzMl90IHNhbXBsZSA9IEludGVycChpbltpbnB1dEluZGV4LTFdLCBpbltpbnB1dEluZGV4XSwKKyAgICAgICAgICAgICAgICAgICAgcGhhc2VGcmFjdGlvbik7CisgICAgICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdmwgKiBzYW1wbGU7CisgICAgICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdnIgKiBzYW1wbGU7CisgICAgICAgICAgICBBZHZhbmNlKCZpbnB1dEluZGV4LCAmcGhhc2VGcmFjdGlvbiwgcGhhc2VJbmNyZW1lbnQpOworICAgICAgICB9CisKKworICAgICAgICAvLyBMT0dFKCJsb29wIGRvbmUgLSBvdXRwdXRJbmRleD0lZCwgaW5wdXRJbmRleD0lZFxuIiwgb3V0cHV0SW5kZXgsIGlucHV0SW5kZXgpOworCisgICAgICAgIC8vIGlmIGRvbmUgd2l0aCBidWZmZXIsIHNhdmUgc2FtcGxlcworICAgICAgICBpZiAoaW5wdXRJbmRleCA+PSBtQnVmZmVyLmZyYW1lQ291bnQpIHsKKyAgICAgICAgICAgIGlucHV0SW5kZXggLT0gbUJ1ZmZlci5mcmFtZUNvdW50OworCisgICAgICAgICAgICAvLyBMT0dFKCJidWZmZXIgZG9uZSwgbmV3IGlucHV0IGluZGV4ICVkIiwgaW5wdXRJbmRleCk7CisKKyAgICAgICAgICAgIG1YMEwgPSBtQnVmZmVyLmkxNlttQnVmZmVyLmZyYW1lQ291bnQtMV07CisgICAgICAgICAgICBwcm92aWRlci0+cmVsZWFzZUJ1ZmZlcigmbUJ1ZmZlcik7CisKKyAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSByZWxlYXNlQnVmZmVyIHJlc2V0cyB0aGUgYnVmZmVyIGZyYW1lQ291bnQKKyAgICAgICAgICAgIC8vIExPR19BU1NFUlQobUJ1ZmZlci5mcmFtZUNvdW50ID09IDApOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gTE9HRSgib3V0cHV0IGJ1ZmZlciBmdWxsIC0gb3V0cHV0SW5kZXg9JWQsIGlucHV0SW5kZXg9JWRcbiIsIG91dHB1dEluZGV4LCBpbnB1dEluZGV4KTsKKworcmVzYW1wbGVNb25vMTZfZXhpdDoKKyAgICAvLyBzYXZlIHN0YXRlCisgICAgbUlucHV0SW5kZXggPSBpbnB1dEluZGV4OworICAgIG1QaGFzZUZyYWN0aW9uID0gcGhhc2VGcmFjdGlvbjsKK30KKworI2lmZGVmIEFTTV9BUk1fUkVTQU1QMSAgLy8gYXNtIG9wdGltaXNhdGlvbiBmb3IgUmVzYW1wbGVyT3JkZXIxCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqCisqICAgQXNtTW9ubzE2TG9vcAorKiAgIGFzbSBvcHRpbWl6ZWQgbW9ub3RvbmljIGxvb3AgdmVyc2lvbjsgb25lIGxvb3AgaXMgMiBmcmFtZXMKKyogICBJbnB1dDoKKyogICAgICAgaW4gOiBwb2ludGVyIG9uIGlucHV0IHNhbXBsZXMKKyogICAgICAgbWF4T3V0UHQgOiBwb2ludGVyIG9uIGZpcnN0IG5vdCBmaWxsZWQKKyogICAgICAgbWF4SW5JZHggOiBpbmRleCBvbiBmaXJzdCBub3QgdXNlZAorKiAgICAgICBvdXRwdXRJbmRleCA6IHBvaW50ZXIgb24gY3VycmVudCBvdXRwdXQgaW5kZXgKKyogICAgICAgb3V0IDogcG9pbnRlciBvbiBvdXRwdXQgYnVmZmVyCisqICAgICAgIGlucHV0SW5kZXggOiBwb2ludGVyIG9uIGN1cnJlbnQgaW5wdXQgaW5kZXgKKyogICAgICAgdmwsIHZyIDogbGVmdCBhbmQgcmlnaHQgZ2FpbgorKiAgICAgICBwaGFzZUZyYWN0aW9uIDogcG9pbnRlciBvbiBjdXJyZW50IHBoYXNlIGZyYWN0aW9uCisqICAgICAgIHBoYXNlSW5jcmVtZW50CisqICAgT3VwdXQ6CisqICAgICAgIG91dHB1dEluZGV4IDoKKyogICAgICAgb3V0IDogdXBkYXRlZCBidWZmZXIKKyogICAgICAgaW5wdXRJbmRleCA6IGluZGV4IG9mIG5leHQgdG8gdXNlCisqICAgICAgIHBoYXNlRnJhY3Rpb24gOiBwaGFzZSBmcmFjdGlvbiBmb3IgbmV4dCBpbnRlcnBvbGF0aW9uCisqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwordm9pZCBBdWRpb1Jlc2FtcGxlck9yZGVyMTo6QXNtTW9ubzE2TG9vcChpbnQxNl90ICppbiwgaW50MzJfdCogbWF4T3V0UHQsIGludDMyX3QgbWF4SW5JZHgsCisgICAgICAgICAgICBzaXplX3QgJm91dHB1dEluZGV4LCBpbnQzMl90KiBvdXQsIHNpemVfdCAmaW5wdXRJbmRleCwgaW50MzJfdCB2bCwgaW50MzJfdCB2ciwKKyAgICAgICAgICAgIHVpbnQzMl90ICZwaGFzZUZyYWN0aW9uLCB1aW50MzJfdCBwaGFzZUluY3JlbWVudCkKK3sKKyNkZWZpbmUgTU9fUEFSQU01ICAgIjM2IiAgICAgICAgLy8gb2Zmc2V0IG9mIHBhcmFtZXRlciA1IChvdXRwdXRJbmRleCkKKworICAgIGFzbSgKKyAgICAgICAgInN0bWZkICBzcCEsIHtyNCwgcjUsIHI2LCByNywgcjgsIHI5LCByMTAsIHIxMSwgbHJ9XG4iCisgICAgICAgIC8vIGdldCBwYXJhbWV0ZXJzCisgICAgICAgICIgICBsZHIgcjYsIFtzcCwgIyIgTU9fUEFSQU01ICIgKyAyMF1cbiIgICAgLy8gJnBoYXNlRnJhY3Rpb24KKyAgICAgICAgIiAgIGxkciByNiwgW3I2XVxuIiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwaGFzZUZyYWN0aW9uCisgICAgICAgICIgICBsZHIgcjcsIFtzcCwgIyIgTU9fUEFSQU01ICIgKyA4XVxuIiAgICAgLy8gJmlucHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByNywgW3I3XVxuIiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnB1dEluZGV4CisgICAgICAgICIgICBsZHIgcjgsIFtzcCwgIyIgTU9fUEFSQU01ICIgKyA0XVxuIiAgICAgLy8gb3V0CisgICAgICAgICIgICBsZHIgcjAsIFtzcCwgIyIgTU9fUEFSQU01ICIgKyAwXVxuIiAgICAgLy8gJm91dHB1dEluZGV4CisgICAgICAgICIgICBsZHIgcjAsIFtyMF1cbiIgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIGFkZCByOCwgcjAsIGFzbCAjMlxuIiAgICAgICAgICAgICAgICAgICAvLyBjdXJPdXQKKyAgICAgICAgIiAgIGxkciByOSwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDI0XVxuIiAgICAvLyBwaGFzZUluY3JlbWVudAorICAgICAgICAiICAgbGRyIHIxMCwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDEyXVxuIiAgIC8vIHZsCisgICAgICAgICIgICBsZHIgcjExLCBbc3AsICMiIE1PX1BBUkFNNSAiICsgMTZdXG4iICAgLy8gdnIKKworICAgICAgICAvLyByMCBwaW4sIHgwLCBTYW1wCisKKyAgICAgICAgLy8gcjEgaW4KKyAgICAgICAgLy8gcjIgbWF4T3V0UHQKKyAgICAgICAgLy8gcjMgbWF4SW5JZHgKKworICAgICAgICAvLyByNCB4MSwgaTEsIGkzLCBPdXQxCisgICAgICAgIC8vIHI1IG91dDAKKworICAgICAgICAvLyByNiBmcmFjCisgICAgICAgIC8vIHI3IGlucHV0SW5kZXgKKyAgICAgICAgLy8gcjggY3VyT3V0CisKKyAgICAgICAgLy8gcjkgaW5jCisgICAgICAgIC8vIHIxMCB2bAorICAgICAgICAvLyByMTEgdnIKKworICAgICAgICAvLyByMTIKKyAgICAgICAgLy8gcjEzIHNwCisgICAgICAgIC8vIHIxNAorCisgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgbG9vcCB3b3JrcyBvbiAyIGZyYW1lcworCisgICAgICAgICIuWTRMMDE6XG4iCisgICAgICAgICIgICBjbXAgcjgsIHIyXG4iICAgICAgICAgICAgICAgICAgIC8vIGN1ck91dCAtIG1heEN1ck91dAorICAgICAgICAiICAgYmNzIC5ZNEwwMlxuIgorCisjZGVmaW5lIE1PX09ORV9GUkFNRSBcCisgICAgIiAgIGFkZCByMCwgcjEsIHI3LCBhc2wgIzFcbiIgICAgICAgLyogaW4gKyBpbnB1dEluZGV4ICovXAorICAgICIgICBsZHJzaCByNCwgW3IwXVxuIiAgICAgICAgICAgICAgIC8qIGluW2lucHV0SW5kZXhdICovXAorICAgICIgICBsZHIgcjUsIFtyOF1cbiIgICAgICAgICAgICAgICAgIC8qIG91dFtvdXRwdXRJbmRleF0gKi9cCisgICAgIiAgIGxkcnNoIHIwLCBbcjAsICMtMl1cbiIgICAgICAgICAgLyogaW5baW5wdXRJbmRleC0xXSAqL1wKKyAgICAiICAgYmljIHI2LCByNiwgIzB4QzAwMDAwMDBcbiIgICAgICAvKiBwaGFzZUZyYWN0aW9uICYgLi4uICovXAorICAgICIgICBzdWIgcjQsIHI0LCByMFxuIiAgICAgICAgICAgICAgIC8qIGluW2lucHV0SW5kZXhdIC0gaW5baW5wdXRJbmRleC0xXSAqL1wKKyAgICAiICAgbW92IHI0LCByNCwgbHNsICMyXG4iICAgICAgICAgICAvKiA8PDIgKi9cCisgICAgIiAgIHNtdWx3dCByNCwgcjQsIHI2XG4iICAgICAgICAgICAgLyogKHgxLXgwKSouLiAqL1wKKyAgICAiICAgYWRkIHI2LCByNiwgcjlcbiIgICAgICAgICAgICAgICAvKiBwaGFzZUZyYWN0aW9uICsgcGhhc2VJbmNyZW1lbnQgKi9cCisgICAgIiAgIGFkZCByMCwgcjAsIHI0XG4iICAgICAgICAgICAgICAgLyogeDAgLSAoLi4pICovXAorICAgICIgICBtbGEgcjUsIHIwLCByMTAsIHI1XG4iICAgICAgICAgIC8qIHZsKmludGVycCArIG91dFtdICovXAorICAgICIgICBsZHIgcjQsIFtyOCwgIzRdXG4iICAgICAgICAgICAgIC8qIG91dFtvdXRwdXRJbmRleCsxXSAqL1wKKyAgICAiICAgc3RyIHI1LCBbcjhdLCAjNFxuIiAgICAgICAgICAgICAvKiBvdXRbb3V0cHV0SW5kZXgrK10gPSAuLi4gKi9cCisgICAgIiAgIG1sYSByNCwgcjAsIHIxMSwgcjRcbiIgICAgICAgICAgLyogdnIqaW50ZXJwICsgb3V0W10gKi9cCisgICAgIiAgIGFkZCByNywgcjcsIHI2LCBsc3IgIzMwXG4iICAgICAgLyogaW5wdXRJbmRleCArIHBoYXNlRnJhY3Rpb24+PjMwICovXAorICAgICIgICBzdHIgcjQsIFtyOF0sICM0XG4iICAgICAgICAgICAgIC8qIG91dFtvdXRwdXRJbmRleCsrXSA9IC4uLiAqLworCisgICAgICAgIE1PX09ORV9GUkFNRSAgICAvLyBmcmFtZSAxCisgICAgICAgIE1PX09ORV9GUkFNRSAgICAvLyBmcmFtZSAyCisKKyAgICAgICAgIiAgIGNtcCByNywgcjNcbiIgICAgICAgICAgICAgICAgICAgLy8gaW5wdXRJbmRleCAtIG1heEluSWR4CisgICAgICAgICIgICBiY2MgLlk0TDAxXG4iCisgICAgICAgICIuWTRMMDI6XG4iCisKKyAgICAgICAgIiAgIGJpYyByNiwgcjYsICMweEMwMDAwMDAwXG4iICAgICAgICAgICAgIC8vIHBoYXNlRnJhY3Rpb24gJiAuLi4KKyAgICAgICAgLy8gc2F2ZSBtb2RpZmllZCB2YWx1ZXMKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDIwXVxuIiAgICAvLyAmcGhhc2VGcmFjdGlvbgorICAgICAgICAiICAgc3RyIHI2LCBbcjBdXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBoYXNlRnJhY3Rpb24KKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDhdXG4iICAgICAvLyAmaW5wdXRJbmRleAorICAgICAgICAiICAgc3RyIHI3LCBbcjBdXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlucHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDRdXG4iICAgICAvLyBvdXQKKyAgICAgICAgIiAgIHN1YiByOCwgcjBcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjdXJPdXQgLSBvdXQKKyAgICAgICAgIiAgIGFzciByOCwgIzJcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZXcgb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBNT19QQVJBTTUgIiArIDBdXG4iICAgICAvLyAmb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIHN0ciByOCwgW3IwXVxuIiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzYXZlIG91dHB1dEluZGV4CisKKyAgICAgICAgIiAgIGxkbWZkICAgc3AhLCB7cjQsIHI1LCByNiwgcjcsIHI4LCByOSwgcjEwLCByMTEsIHBjfVxuIgorICAgICk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqCisqICAgQXNtU3RlcmVvMTZMb29wCisqICAgYXNtIG9wdGltaXplZCBzdGVyZW8gbG9vcCB2ZXJzaW9uOyBvbmUgbG9vcCBpcyAyIGZyYW1lcworKiAgIElucHV0OgorKiAgICAgICBpbiA6IHBvaW50ZXIgb24gaW5wdXQgc2FtcGxlcworKiAgICAgICBtYXhPdXRQdCA6IHBvaW50ZXIgb24gZmlyc3Qgbm90IGZpbGxlZAorKiAgICAgICBtYXhJbklkeCA6IGluZGV4IG9uIGZpcnN0IG5vdCB1c2VkCisqICAgICAgIG91dHB1dEluZGV4IDogcG9pbnRlciBvbiBjdXJyZW50IG91dHB1dCBpbmRleAorKiAgICAgICBvdXQgOiBwb2ludGVyIG9uIG91dHB1dCBidWZmZXIKKyogICAgICAgaW5wdXRJbmRleCA6IHBvaW50ZXIgb24gY3VycmVudCBpbnB1dCBpbmRleAorKiAgICAgICB2bCwgdnIgOiBsZWZ0IGFuZCByaWdodCBnYWluCisqICAgICAgIHBoYXNlRnJhY3Rpb24gOiBwb2ludGVyIG9uIGN1cnJlbnQgcGhhc2UgZnJhY3Rpb24KKyogICAgICAgcGhhc2VJbmNyZW1lbnQKKyogICBPdXB1dDoKKyogICAgICAgb3V0cHV0SW5kZXggOgorKiAgICAgICBvdXQgOiB1cGRhdGVkIGJ1ZmZlcgorKiAgICAgICBpbnB1dEluZGV4IDogaW5kZXggb2YgbmV4dCB0byB1c2UKKyogICAgICAgcGhhc2VGcmFjdGlvbiA6IHBoYXNlIGZyYWN0aW9uIGZvciBuZXh0IGludGVycG9sYXRpb24KKyoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCit2b2lkIEF1ZGlvUmVzYW1wbGVyT3JkZXIxOjpBc21TdGVyZW8xNkxvb3AoaW50MTZfdCAqaW4sIGludDMyX3QqIG1heE91dFB0LCBpbnQzMl90IG1heEluSWR4LAorICAgICAgICAgICAgc2l6ZV90ICZvdXRwdXRJbmRleCwgaW50MzJfdCogb3V0LCBzaXplX3QgJmlucHV0SW5kZXgsIGludDMyX3QgdmwsIGludDMyX3QgdnIsCisgICAgICAgICAgICB1aW50MzJfdCAmcGhhc2VGcmFjdGlvbiwgdWludDMyX3QgcGhhc2VJbmNyZW1lbnQpCit7CisjZGVmaW5lIFNUX1BBUkFNNSAgICAiNDAiICAgICAvLyBvZmZzZXQgb2YgcGFyYW1ldGVyIDUgKG91dHB1dEluZGV4KQorICAgIGFzbSgKKyAgICAgICAgInN0bWZkICBzcCEsIHtyNCwgcjUsIHI2LCByNywgcjgsIHI5LCByMTAsIHIxMSwgcjEyLCBscn1cbiIKKyAgICAgICAgLy8gZ2V0IHBhcmFtZXRlcnMKKyAgICAgICAgIiAgIGxkciByNiwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDIwXVxuIiAgICAvLyAmcGhhc2VGcmFjdGlvbgorICAgICAgICAiICAgbGRyIHI2LCBbcjZdXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBoYXNlRnJhY3Rpb24KKyAgICAgICAgIiAgIGxkciByNywgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDhdXG4iICAgICAvLyAmaW5wdXRJbmRleAorICAgICAgICAiICAgbGRyIHI3LCBbcjddXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlucHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByOCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDRdXG4iICAgICAvLyBvdXQKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDBdXG4iICAgICAvLyAmb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByMCwgW3IwXVxuIiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRwdXRJbmRleAorICAgICAgICAiICAgYWRkIHI4LCByMCwgYXNsICMyXG4iICAgICAgICAgICAgICAgICAgIC8vIGN1ck91dAorICAgICAgICAiICAgbGRyIHI5LCBbc3AsICMiIFNUX1BBUkFNNSAiICsgMjRdXG4iICAgIC8vIHBoYXNlSW5jcmVtZW50CisgICAgICAgICIgICBsZHIgcjEwLCBbc3AsICMiIFNUX1BBUkFNNSAiICsgMTJdXG4iICAgLy8gdmwKKyAgICAgICAgIiAgIGxkciByMTEsIFtzcCwgIyIgU1RfUEFSQU01ICIgKyAxNl1cbiIgICAvLyB2cgorCisgICAgICAgIC8vIHIwIHBpbiwgeDAsIFNhbXAKKworICAgICAgICAvLyByMSBpbgorICAgICAgICAvLyByMiBtYXhPdXRQdAorICAgICAgICAvLyByMyBtYXhJbklkeAorCisgICAgICAgIC8vIHI0IHgxLCBpMSwgaTMsIG91dDEKKyAgICAgICAgLy8gcjUgb3V0MAorCisgICAgICAgIC8vIHI2IGZyYWMKKyAgICAgICAgLy8gcjcgaW5wdXRJbmRleAorICAgICAgICAvLyByOCBjdXJPdXQKKworICAgICAgICAvLyByOSBpbmMKKyAgICAgICAgLy8gcjEwIHZsCisgICAgICAgIC8vIHIxMSB2cgorCisgICAgICAgIC8vIHIxMiB0ZW1wb3JhcnkKKyAgICAgICAgLy8gcjEzIHNwCisgICAgICAgIC8vIHIxNAorCisgICAgICAgICIuWTVMMDE6XG4iCisgICAgICAgICIgICBjbXAgcjgsIHIyXG4iICAgICAgICAgICAgICAgICAgIC8vIGN1ck91dCAtIG1heEN1ck91dAorICAgICAgICAiICAgYmNzIC5ZNUwwMlxuIgorCisjZGVmaW5lIFNUX09ORV9GUkFNRSBcCisgICAgIiAgIGJpYyByNiwgcjYsICMweEMwMDAwMDAwXG4iICAgICAgLyogcGhhc2VGcmFjdGlvbiAmIC4uLiAqL1wKK1wKKyAgICAiICAgYWRkIHIwLCByMSwgcjcsIGFzbCAjMlxuIiAgICAgICAvKiBpbiArIDIqaW5wdXRJbmRleCAqL1wKK1wKKyAgICAiICAgbGRyc2ggcjQsIFtyMF1cbiIgICAgICAgICAgICAgICAvKiBpblsyKmlucHV0SW5kZXhdICovXAorICAgICIgICBsZHIgcjUsIFtyOF1cbiIgICAgICAgICAgICAgICAgIC8qIG91dFtvdXRwdXRJbmRleF0gKi9cCisgICAgIiAgIGxkcnNoIHIxMiwgW3IwLCAjLTRdXG4iICAgICAgICAgLyogaW5bMippbnB1dEluZGV4LTJdICovXAorICAgICIgICBzdWIgcjQsIHI0LCByMTJcbiIgICAgICAgICAgICAgIC8qIGluWzIqSW5wdXRJbmRleF0gLSBpblsyKklucHV0SW5kZXgtMl0gKi9cCisgICAgIiAgIG1vdiByNCwgcjQsIGxzbCAjMlxuIiAgICAgICAgICAgLyogPDwyICovXAorICAgICIgICBzbXVsd3QgcjQsIHI0LCByNlxuIiAgICAgICAgICAgIC8qICh4MS14MCkqLi4gKi9cCisgICAgIiAgIGFkZCByMTIsIHIxMiwgcjRcbiIgICAgICAgICAgICAgLyogeDAgLSAoLi4pICovXAorICAgICIgICBtbGEgcjUsIHIxMiwgcjEwLCByNVxuIiAgICAgICAgIC8qIHZsKmludGVycCArIG91dFtdICovXAorICAgICIgICBsZHIgcjQsIFtyOCwgIzRdXG4iICAgICAgICAgICAgIC8qIG91dFtvdXRwdXRJbmRleCsxXSAqL1wKKyAgICAiICAgc3RyIHI1LCBbcjhdLCAjNFxuIiAgICAgICAgICAgICAvKiBvdXRbb3V0cHV0SW5kZXgrK10gPSAuLi4gKi9cCitcCisgICAgIiAgIGxkcnNoIHIxMiwgW3IwLCAjKzJdXG4iICAgICAgICAgLyogaW5bMippbnB1dEluZGV4KzFdICovXAorICAgICIgICBsZHJzaCByMCwgW3IwLCAjLTJdXG4iICAgICAgICAgIC8qIGluWzIqaW5wdXRJbmRleC0xXSAqL1wKKyAgICAiICAgc3ViIHIxMiwgcjEyLCByMFxuIiAgICAgICAgICAgICAvKiBpblsyKklucHV0SW5kZXhdIC0gaW5bMipJbnB1dEluZGV4LTJdICovXAorICAgICIgICBtb3YgcjEyLCByMTIsIGxzbCAjMlxuIiAgICAgICAgIC8qIDw8MiAqL1wKKyAgICAiICAgc211bHd0IHIxMiwgcjEyLCByNlxuIiAgICAgICAgICAvKiAoeDEteDApKi4uICovXAorICAgICIgICBhZGQgcjEyLCByMCwgcjEyXG4iICAgICAgICAgICAgIC8qIHgwIC0gKC4uKSAqL1wKKyAgICAiICAgbWxhIHI0LCByMTIsIHIxMSwgcjRcbiIgICAgICAgICAvKiB2cippbnRlcnAgKyBvdXRbXSAqL1wKKyAgICAiICAgc3RyIHI0LCBbcjhdLCAjNFxuIiAgICAgICAgICAgICAvKiBvdXRbb3V0cHV0SW5kZXgrK10gPSAuLi4gKi9cCitcCisgICAgIiAgIGFkZCByNiwgcjYsIHI5XG4iICAgICAgICAgICAgICAgLyogcGhhc2VGcmFjdGlvbiArIHBoYXNlSW5jcmVtZW50ICovXAorICAgICIgICBhZGQgcjcsIHI3LCByNiwgbHNyICMzMFxuIiAgICAgIC8qIGlucHV0SW5kZXggKyBwaGFzZUZyYWN0aW9uPj4zMCAqLworCisgICAgU1RfT05FX0ZSQU1FICAgIC8vIGZyYW1lIDEKKyAgICBTVF9PTkVfRlJBTUUgICAgLy8gZnJhbWUgMQorCisgICAgICAgICIgICBjbXAgcjcsIHIzXG4iICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnB1dEluZGV4IC0gbWF4SW5JZHgKKyAgICAgICAgIiAgIGJjYyAuWTVMMDFcbiIKKyAgICAgICAgIi5ZNUwwMjpcbiIKKworICAgICAgICAiICAgYmljIHI2LCByNiwgIzB4QzAwMDAwMDBcbiIgICAgICAgICAgICAgIC8vIHBoYXNlRnJhY3Rpb24gJiAuLi4KKyAgICAgICAgLy8gc2F2ZSBtb2RpZmllZCB2YWx1ZXMKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDIwXVxuIiAgICAvLyAmcGhhc2VGcmFjdGlvbgorICAgICAgICAiICAgc3RyIHI2LCBbcjBdXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBoYXNlRnJhY3Rpb24KKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDhdXG4iICAgICAvLyAmaW5wdXRJbmRleAorICAgICAgICAiICAgc3RyIHI3LCBbcjBdXG4iICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlucHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDRdXG4iICAgICAvLyBvdXQKKyAgICAgICAgIiAgIHN1YiByOCwgcjBcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjdXJPdXQgLSBvdXQKKyAgICAgICAgIiAgIGFzciByOCwgIzJcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZXcgb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIGxkciByMCwgW3NwLCAjIiBTVF9QQVJBTTUgIiArIDBdXG4iICAgICAvLyAmb3V0cHV0SW5kZXgKKyAgICAgICAgIiAgIHN0ciByOCwgW3IwXVxuIiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzYXZlIG91dHB1dEluZGV4CisKKyAgICAgICAgIiAgIGxkbWZkICAgc3AhLCB7cjQsIHI1LCByNiwgcjcsIHI4LCByOSwgcjEwLCByMTEsIHIxMiwgcGN9XG4iCisgICAgKTsKK30KKworI2VuZGlmICAvLyBBU01fQVJNX1JFU0FNUDEKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9Cis7IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyLmggYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5NjU2YzAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlci5oCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQVVESU9fUkVTQU1QTEVSX0gKKyNkZWZpbmUgQU5EUk9JRF9BVURJT19SRVNBTVBMRVJfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlICJBdWRpb0J1ZmZlclByb3ZpZGVyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQXVkaW9SZXNhbXBsZXIgeworcHVibGljOgorICAgIC8vIERldGVybWluZXMgcXVhbGl0eSBvZiBTUkMuCisgICAgLy8gIExPV19RVUFMSVRZOiBsaW5lYXIgaW50ZXJwb2xhdG9yICgxc3Qgb3JkZXIpCisgICAgLy8gIE1FRF9RVUFMSVRZOiBjdWJpYyBpbnRlcnBvbGF0b3IgKDNyZCBvcmRlcikKKyAgICAvLyAgSElHSF9RVUFMSVRZOiBmaXhlZCBtdWx0aS10YXAgRklSIChlLmcuIDQ4S0h6LT40NC4xS0h6KQorICAgIC8vIE5PVEU6IGhpZ2ggcXVhbGl0eSBTUkMgd2lsbCBvbmx5IGJlIHN1cHBvcnRlZCBmb3IKKyAgICAvLyBjZXJ0YWluIGZpeGVkIHJhdGUgY29udmVyc2lvbnMuIFNhbXBsZSByYXRlIGNhbm5vdCBiZQorICAgIC8vIGNoYW5nZWQgZHluYW1pY2FsbHkuIAorICAgIGVudW0gc3JjX3F1YWxpdHkgeworICAgICAgICBERUZBVUxUPTAsCisgICAgICAgIExPV19RVUFMSVRZPTEsCisgICAgICAgIE1FRF9RVUFMSVRZPTIsCisgICAgICAgIEhJR0hfUVVBTElUWT0zCisgICAgfTsKKworICAgIHN0YXRpYyBBdWRpb1Jlc2FtcGxlciogY3JlYXRlKGludCBiaXREZXB0aCwgaW50IGluQ2hhbm5lbENvdW50LAorICAgICAgICAgICAgaW50MzJfdCBzYW1wbGVSYXRlLCBpbnQgcXVhbGl0eT1ERUZBVUxUKTsKKworICAgIHZpcnR1YWwgfkF1ZGlvUmVzYW1wbGVyKCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgaW5pdCgpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgc2V0U2FtcGxlUmF0ZShpbnQzMl90IGluU2FtcGxlUmF0ZSk7CisgICAgdmlydHVhbCB2b2lkIHNldFZvbHVtZShpbnQxNl90IGxlZnQsIGludDE2X3QgcmlnaHQpOworCisgICAgdmlydHVhbCB2b2lkIHJlc2FtcGxlKGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcikgPSAwOworCitwcm90ZWN0ZWQ6CisgICAgLy8gbnVtYmVyIG9mIGJpdHMgZm9yIHBoYXNlIGZyYWN0aW9uIC0gMzAgYml0cyBhbGxvd3MgbmVhcmx5IDJ4IGRvd25zYW1wbGluZworICAgIHN0YXRpYyBjb25zdCBpbnQga051bVBoYXNlQml0cyA9IDMwOworCisgICAgLy8gcGhhc2UgbWFzayBmb3IgZnJhY3Rpb24KKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3Qga1BoYXNlTWFzayA9ICgxTFU8PGtOdW1QaGFzZUJpdHMpLTE7CisKKyAgICAvLyBtdWx0aXBsaWVyIHRvIGNhbGN1bGF0ZSBmaXhlZCBwb2ludCBwaGFzZSBpbmNyZW1lbnQKKyAgICBzdGF0aWMgY29uc3QgZG91YmxlIGtQaGFzZU11bHRpcGxpZXIgPSAxTCA8PCBrTnVtUGhhc2VCaXRzOworCisgICAgZW51bSBmb3JtYXQge01PTk9fMTZfQklULCBTVEVSRU9fMTZfQklUfTsKKyAgICBBdWRpb1Jlc2FtcGxlcihpbnQgYml0RGVwdGgsIGludCBpbkNoYW5uZWxDb3VudCwgaW50MzJfdCBzYW1wbGVSYXRlKTsKKworICAgIC8vIHByZXZlbnQgY29weWluZworICAgIEF1ZGlvUmVzYW1wbGVyKGNvbnN0IEF1ZGlvUmVzYW1wbGVyJik7CisgICAgQXVkaW9SZXNhbXBsZXImIG9wZXJhdG9yPShjb25zdCBBdWRpb1Jlc2FtcGxlciYpOworCisgICAgaW50MzJfdCBtQml0RGVwdGg7CisgICAgaW50MzJfdCBtQ2hhbm5lbENvdW50OworICAgIGludDMyX3QgbVNhbXBsZVJhdGU7CisgICAgaW50MzJfdCBtSW5TYW1wbGVSYXRlOworICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXI6OkJ1ZmZlciBtQnVmZmVyOworICAgIHVuaW9uIHsKKyAgICAJaW50MTZfdCBtVm9sdW1lWzJdOworICAgIAl1aW50MzJfdCBtVm9sdW1lUkw7CisgICAgfTsKKyAgICBpbnQxNl90IG1UYXJnZXRWb2x1bWVbMl07CisgICAgZm9ybWF0IG1Gb3JtYXQ7CisgICAgc2l6ZV90IG1JbnB1dEluZGV4OworICAgIGludDMyX3QgbVBoYXNlSW5jcmVtZW50OworICAgIHVpbnQzMl90IG1QaGFzZUZyYWN0aW9uOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfQorOyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9BVURJT19SRVNBTVBMRVJfSApkaWZmIC0tZ2l0IGEvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9SZXNhbXBsZXJDdWJpYy5jcHAgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlckN1YmljLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDI0N2JkCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9SZXNhbXBsZXJDdWJpYy5jcHAKQEAgLTAsMCArMSwxODQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorCisjaW5jbHVkZSAiQXVkaW9SZXNhbXBsZXIuaCIKKyNpbmNsdWRlICJBdWRpb1Jlc2FtcGxlckN1YmljLmgiCisKKyNkZWZpbmUgTE9HX1RBRyAiQXVkaW9TUkMiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBBdWRpb1Jlc2FtcGxlckN1YmljOjppbml0KCkgeworICAgIG1lbXNldCgmbGVmdCwgMCwgc2l6ZW9mKHN0YXRlKSk7CisgICAgbWVtc2V0KCZyaWdodCwgMCwgc2l6ZW9mKHN0YXRlKSk7Cit9CisKK3ZvaWQgQXVkaW9SZXNhbXBsZXJDdWJpYzo6cmVzYW1wbGUoaW50MzJfdCogb3V0LCBzaXplX3Qgb3V0RnJhbWVDb3VudCwKKyAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpIHsKKworICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCB3ZSBvdmVyZmxvdyBpZiBpdCBkb2VzCisgICAgLy8gTE9HX0FTU0VSVChvdXRGcmFtZUNvdW50IDwgMzI3NjcpOworCisgICAgLy8gc2VsZWN0IHRoZSBhcHByb3ByaWF0ZSByZXNhbXBsZXIKKyAgICBzd2l0Y2ggKG1DaGFubmVsQ291bnQpIHsKKyAgICBjYXNlIDE6CisgICAgICAgIHJlc2FtcGxlTW9ubzE2KG91dCwgb3V0RnJhbWVDb3VudCwgcHJvdmlkZXIpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDI6CisgICAgICAgIHJlc2FtcGxlU3RlcmVvMTYob3V0LCBvdXRGcmFtZUNvdW50LCBwcm92aWRlcik7CisgICAgICAgIGJyZWFrOworICAgIH0KK30KKwordm9pZCBBdWRpb1Jlc2FtcGxlckN1YmljOjpyZXNhbXBsZVN0ZXJlbzE2KGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXIqIHByb3ZpZGVyKSB7CisKKyAgICBpbnQzMl90IHZsID0gbVZvbHVtZVswXTsKKyAgICBpbnQzMl90IHZyID0gbVZvbHVtZVsxXTsKKworICAgIHNpemVfdCBpbnB1dEluZGV4ID0gbUlucHV0SW5kZXg7CisgICAgdWludDMyX3QgcGhhc2VGcmFjdGlvbiA9IG1QaGFzZUZyYWN0aW9uOworICAgIHVpbnQzMl90IHBoYXNlSW5jcmVtZW50ID0gbVBoYXNlSW5jcmVtZW50OworICAgIHNpemVfdCBvdXRwdXRJbmRleCA9IDA7CisgICAgc2l6ZV90IG91dHB1dFNhbXBsZUNvdW50ID0gb3V0RnJhbWVDb3VudCAqIDI7CisgICAgc2l6ZV90IGluRnJhbWVDb3VudCA9IChvdXRGcmFtZUNvdW50Km1JblNhbXBsZVJhdGUpL21TYW1wbGVSYXRlOworCisgICAgLy8gZmV0Y2ggZmlyc3QgYnVmZmVyCisgICAgaWYgKG1CdWZmZXIuZnJhbWVDb3VudCA9PSAwKSB7CisgICAgICAgIG1CdWZmZXIuZnJhbWVDb3VudCA9IGluRnJhbWVDb3VudDsKKyAgICAgICAgcHJvdmlkZXItPmdldE5leHRCdWZmZXIoJm1CdWZmZXIpOworICAgICAgICBpZiAobUJ1ZmZlci5yYXcgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgLy8gTE9HVygiTmV3IGJ1ZmZlcjogb2Zmc2V0PSVwLCBmcmFtZXM9JWRuIiwgbUJ1ZmZlci5yYXcsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgfQorICAgIGludDE2X3QgKmluID0gbUJ1ZmZlci5pMTY7CisKKyAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCkgeworICAgICAgICBpbnQzMl90IHNhbXBsZTsKKyAgICAgICAgaW50MzJfdCB4OworCisgICAgICAgIC8vIGNhbGN1bGF0ZSBvdXRwdXQgc2FtcGxlCisgICAgICAgIHggPSBwaGFzZUZyYWN0aW9uID4+IGtQcmVJbnRlcnBTaGlmdDsKKyAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IHZsICogaW50ZXJwKCZsZWZ0LCB4KTsKKyAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IHZyICogaW50ZXJwKCZyaWdodCwgeCk7CisgICAgICAgIC8vIG91dFtvdXRwdXRJbmRleCsrXSArPSB2ciAqIGluW2lucHV0SW5kZXgqMl07CisKKyAgICAgICAgLy8gaW5jcmVtZW50IHBoYXNlCisgICAgICAgIHBoYXNlRnJhY3Rpb24gKz0gcGhhc2VJbmNyZW1lbnQ7CisgICAgICAgIHVpbnQzMl90IGluZGV4SW5jcmVtZW50ID0gKHBoYXNlRnJhY3Rpb24gPj4ga051bVBoYXNlQml0cyk7CisgICAgICAgIHBoYXNlRnJhY3Rpb24gJj0ga1BoYXNlTWFzazsKKworICAgICAgICAvLyB0aW1lIHRvIGZldGNoIGFub3RoZXIgc2FtcGxlCisgICAgICAgIHdoaWxlIChpbmRleEluY3JlbWVudC0tKSB7CisKKyAgICAgICAgICAgIGlucHV0SW5kZXgrKzsKKyAgICAgICAgICAgIGlmIChpbnB1dEluZGV4ID09IG1CdWZmZXIuZnJhbWVDb3VudCkgeworICAgICAgICAgICAgICAgIGlucHV0SW5kZXggPSAwOworICAgICAgICAgICAgICAgIHByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZtQnVmZmVyKTsKKyAgICAgICAgICAgICAgICBtQnVmZmVyLmZyYW1lQ291bnQgPSBpbkZyYW1lQ291bnQ7CisgICAgICAgICAgICAgICAgcHJvdmlkZXItPmdldE5leHRCdWZmZXIoJm1CdWZmZXIpOworICAgICAgICAgICAgICAgIGlmIChtQnVmZmVyLnJhdyA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIHNhdmVfc3RhdGU7ICAvLyB1Z2x5LCBidXQgZWZmaWNpZW50CisgICAgICAgICAgICAgICAgaW4gPSBtQnVmZmVyLmkxNjsKKyAgICAgICAgICAgICAgICAvLyBMT0dXKCJOZXcgYnVmZmVyOiBvZmZzZXQ9JXAsIGZyYW1lcz0lZFxuIiwgbUJ1ZmZlci5yYXcsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGFkdmFuY2Ugc2FtcGxlIHN0YXRlCisgICAgICAgICAgICBhZHZhbmNlKCZsZWZ0LCBpbltpbnB1dEluZGV4KjJdKTsKKyAgICAgICAgICAgIGFkdmFuY2UoJnJpZ2h0LCBpbltpbnB1dEluZGV4KjIrMV0pOworICAgICAgICB9CisgICAgfQorCitzYXZlX3N0YXRlOgorICAgIC8vIExPR1coIkRvbmU6IGluZGV4PSVkLCBmcmFjdGlvbj0ldSIsIGlucHV0SW5kZXgsIHBoYXNlRnJhY3Rpb24pOworICAgIG1JbnB1dEluZGV4ID0gaW5wdXRJbmRleDsKKyAgICBtUGhhc2VGcmFjdGlvbiA9IHBoYXNlRnJhY3Rpb247Cit9CisKK3ZvaWQgQXVkaW9SZXNhbXBsZXJDdWJpYzo6cmVzYW1wbGVNb25vMTYoaW50MzJfdCogb3V0LCBzaXplX3Qgb3V0RnJhbWVDb3VudCwKKyAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpIHsKKworICAgIGludDMyX3QgdmwgPSBtVm9sdW1lWzBdOworICAgIGludDMyX3QgdnIgPSBtVm9sdW1lWzFdOworCisgICAgc2l6ZV90IGlucHV0SW5kZXggPSBtSW5wdXRJbmRleDsKKyAgICB1aW50MzJfdCBwaGFzZUZyYWN0aW9uID0gbVBoYXNlRnJhY3Rpb247CisgICAgdWludDMyX3QgcGhhc2VJbmNyZW1lbnQgPSBtUGhhc2VJbmNyZW1lbnQ7CisgICAgc2l6ZV90IG91dHB1dEluZGV4ID0gMDsKKyAgICBzaXplX3Qgb3V0cHV0U2FtcGxlQ291bnQgPSBvdXRGcmFtZUNvdW50ICogMjsKKyAgICBzaXplX3QgaW5GcmFtZUNvdW50ID0gKG91dEZyYW1lQ291bnQqbUluU2FtcGxlUmF0ZSkvbVNhbXBsZVJhdGU7CisKKyAgICAvLyBmZXRjaCBmaXJzdCBidWZmZXIKKyAgICBpZiAobUJ1ZmZlci5mcmFtZUNvdW50ID09IDApIHsKKyAgICAgICAgbUJ1ZmZlci5mcmFtZUNvdW50ID0gaW5GcmFtZUNvdW50OworICAgICAgICBwcm92aWRlci0+Z2V0TmV4dEJ1ZmZlcigmbUJ1ZmZlcik7CisgICAgICAgIGlmIChtQnVmZmVyLnJhdyA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAvLyBMT0dXKCJOZXcgYnVmZmVyOiBvZmZzZXQ9JXAsIGZyYW1lcz0lZFxuIiwgbUJ1ZmZlci5yYXcsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgfQorICAgIGludDE2X3QgKmluID0gbUJ1ZmZlci5pMTY7CisKKyAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCkgeworICAgICAgICBpbnQzMl90IHNhbXBsZTsKKyAgICAgICAgaW50MzJfdCB4OworCisgICAgICAgIC8vIGNhbGN1bGF0ZSBvdXRwdXQgc2FtcGxlCisgICAgICAgIHggPSBwaGFzZUZyYWN0aW9uID4+IGtQcmVJbnRlcnBTaGlmdDsKKyAgICAgICAgc2FtcGxlID0gaW50ZXJwKCZsZWZ0LCB4KTsKKyAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IHZsICogc2FtcGxlOworICAgICAgICBvdXRbb3V0cHV0SW5kZXgrK10gKz0gdnIgKiBzYW1wbGU7CisKKyAgICAgICAgLy8gaW5jcmVtZW50IHBoYXNlCisgICAgICAgIHBoYXNlRnJhY3Rpb24gKz0gcGhhc2VJbmNyZW1lbnQ7CisgICAgICAgIHVpbnQzMl90IGluZGV4SW5jcmVtZW50ID0gKHBoYXNlRnJhY3Rpb24gPj4ga051bVBoYXNlQml0cyk7CisgICAgICAgIHBoYXNlRnJhY3Rpb24gJj0ga1BoYXNlTWFzazsKKworICAgICAgICAvLyB0aW1lIHRvIGZldGNoIGFub3RoZXIgc2FtcGxlCisgICAgICAgIHdoaWxlIChpbmRleEluY3JlbWVudC0tKSB7CisKKyAgICAgICAgICAgIGlucHV0SW5kZXgrKzsKKyAgICAgICAgICAgIGlmIChpbnB1dEluZGV4ID09IG1CdWZmZXIuZnJhbWVDb3VudCkgeworICAgICAgICAgICAgICAgIGlucHV0SW5kZXggPSAwOworICAgICAgICAgICAgICAgIHByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZtQnVmZmVyKTsKKyAgICAgICAgICAgICAgICBtQnVmZmVyLmZyYW1lQ291bnQgPSBpbkZyYW1lQ291bnQ7CisgICAgICAgICAgICAgICAgcHJvdmlkZXItPmdldE5leHRCdWZmZXIoJm1CdWZmZXIpOworICAgICAgICAgICAgICAgIGlmIChtQnVmZmVyLnJhdyA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIHNhdmVfc3RhdGU7ICAvLyB1Z2x5LCBidXQgZWZmaWNpZW50CisgICAgICAgICAgICAgICAgLy8gTE9HVygiTmV3IGJ1ZmZlcjogb2Zmc2V0PSVwLCBmcmFtZXM9JWRuIiwgbUJ1ZmZlci5yYXcsIG1CdWZmZXIuZnJhbWVDb3VudCk7CisgICAgICAgICAgICAgICAgaW4gPSBtQnVmZmVyLmkxNjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gYWR2YW5jZSBzYW1wbGUgc3RhdGUKKyAgICAgICAgICAgIGFkdmFuY2UoJmxlZnQsIGluW2lucHV0SW5kZXhdKTsKKyAgICAgICAgfQorICAgIH0KKworc2F2ZV9zdGF0ZToKKyAgICAvLyBMT0dXKCJEb25lOiBpbmRleD0lZCwgZnJhY3Rpb249JXUiLCBpbnB1dEluZGV4LCBwaGFzZUZyYWN0aW9uKTsKKyAgICBtSW5wdXRJbmRleCA9IGlucHV0SW5kZXg7CisgICAgbVBoYXNlRnJhY3Rpb24gPSBwaGFzZUZyYWN0aW9uOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9Cis7IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyQ3ViaWMuaCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyQ3ViaWMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzJiNjJhCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9hdWRpb2ZsaW5nZXIvQXVkaW9SZXNhbXBsZXJDdWJpYy5oCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQVVESU9fUkVTQU1QTEVSX0NVQklDX0gKKyNkZWZpbmUgQU5EUk9JRF9BVURJT19SRVNBTVBMRVJfQ1VCSUNfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorCisjaW5jbHVkZSAiQXVkaW9SZXNhbXBsZXIuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBBdWRpb1Jlc2FtcGxlckN1YmljIDogcHVibGljIEF1ZGlvUmVzYW1wbGVyIHsKK3B1YmxpYzoKKyAgICBBdWRpb1Jlc2FtcGxlckN1YmljKGludCBiaXREZXB0aCwgaW50IGluQ2hhbm5lbENvdW50LCBpbnQzMl90IHNhbXBsZVJhdGUpIDoKKyAgICAgICAgQXVkaW9SZXNhbXBsZXIoYml0RGVwdGgsIGluQ2hhbm5lbENvdW50LCBzYW1wbGVSYXRlKSB7CisgICAgfQorICAgIHZpcnR1YWwgdm9pZCByZXNhbXBsZShpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LAorICAgICAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpOworcHJpdmF0ZToKKyAgICAvLyBudW1iZXIgb2YgYml0cyB1c2VkIGluIGludGVycG9sYXRpb24gbXVsdGlwbHkgLSAxNCBiaXRzIGF2b2lkcyBvdmVyZmxvdworICAgIHN0YXRpYyBjb25zdCBpbnQga051bUludGVycEJpdHMgPSAxNDsKKworICAgIC8vIGJpdHMgdG8gc2hpZnQgdGhlIHBoYXNlIGZyYWN0aW9uIGRvd24gdG8gYXZvaWQgb3ZlcmZsb3cKKyAgICBzdGF0aWMgY29uc3QgaW50IGtQcmVJbnRlcnBTaGlmdCA9IGtOdW1QaGFzZUJpdHMgLSBrTnVtSW50ZXJwQml0czsKKyAgICB0eXBlZGVmIHN0cnVjdCB7CisgICAgICAgIGludDMyX3QgYSwgYiwgYywgeTAsIHkxLCB5MiwgeTM7CisgICAgfSBzdGF0ZTsKKyAgICB2b2lkIGluaXQoKTsKKyAgICB2b2lkIHJlc2FtcGxlTW9ubzE2KGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcik7CisgICAgdm9pZCByZXNhbXBsZVN0ZXJlbzE2KGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgICAgICBBdWRpb0J1ZmZlclByb3ZpZGVyKiBwcm92aWRlcik7CisgICAgc3RhdGljIGlubGluZSBpbnQzMl90IGludGVycChzdGF0ZSogcCwgaW50MzJfdCB4KSB7CisgICAgICAgIHJldHVybiAoKCgoKHAtPmEgKiB4ID4+IDE0KSArIHAtPmIpICogeCA+PiAxNCkgKyBwLT5jKSAqIHggPj4gMTQpICsgcC0+eTE7CisgICAgfQorICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBhZHZhbmNlKHN0YXRlKiBwLCBpbnQxNl90IGluKSB7CisgICAgICAgIHAtPnkwID0gcC0+eTE7CisgICAgICAgIHAtPnkxID0gcC0+eTI7CisgICAgICAgIHAtPnkyID0gcC0+eTM7CisgICAgICAgIHAtPnkzID0gaW47CisgICAgICAgIHAtPmEgPSAoMyAqIChwLT55MSAtIHAtPnkyKSAtIHAtPnkwICsgcC0+eTMpID4+IDE7ICAgICAgICAgICAgCisgICAgICAgIHAtPmIgPSAocC0+eTIgPDwgMSkgKyBwLT55MCAtICgoKDUgKiBwLT55MSArIHAtPnkzKSkgPj4gMSk7CisgICAgICAgIHAtPmMgPSAocC0+eTIgLSBwLT55MCkgPj4gMTsKKyAgICB9CisgICAgc3RhdGUgbGVmdCwgcmlnaHQ7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLypBTkRST0lEX0FVRElPX1JFU0FNUExFUl9DVUJJQ19IKi8KZGlmZiAtLWdpdCBhL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyU2luYy5jcHAgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlclNpbmMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllNWUyNTQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlclNpbmMuY3BwCkBAIC0wLDAgKzEsMzU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgIkF1ZGlvUmVzYW1wbGVyU2luYy5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworLyoKKyAqIFRoZXNlIGNvZWZpY2llbnRzIGFyZSBjb21wdXRlZCB3aXRoIHRoZSAiZmlyIiB1dGlsaXR5IGZvdW5kIGluCisgKiB0b29scy9yZXNhbXBsZXJfdG9vbHMKKyAqIFRPRE86IEEgZ29vZCBvcHRpbWl6YXRpb24gd291bGQgYmUgdG8gdHJhbnNwb3NlIHRoaXMgbWF0cml4LCB0byB0YWtlCisgKiBiZXR0ZXIgYWR2YW50YWdlIG9mIHRoZSBkYXRhLWNhY2hlLgorICovCitjb25zdCBpbnQzMl90IEF1ZGlvUmVzYW1wbGVyU2luYzo6bUZpckNvZWZzVXBbXSA9IHsKKyAgICAgICAgMHg3ZmZmZmZmZiwgMHg3ZjE1ZDA3OCwgMHg3YzVlMGRhNiwgMHg3N2VjZDg2NywgMHg3MWUyZTI1MSwgMHg2YTZjMzA0YSwgMHg2MWJlNzI2OSwgMHg1ODE3MDQxMiwgMHg0ZGI4YWIwNSwgMHg0MmU5MmVhNiwgMHgzN2VlZTIxNCwgMHgyZDBlM2JiMSwgMHgyMjg3OTM2NiwgMHgxODk1MWU5NSwgMHgwZjY5M2QwZCwgMHgwNzJkMjYyMSwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHhmOWY2NjY1NSwgMHhmNTFhNWZkNywgMHhmMTZiYmQ4NCwgMHhlZWUwZDlhYywgMHhlZDY3YTkyMiwgMHhlY2U3MGRlNiwgMHhlZDQwNTg5NywgMHhlZTUwZTUwNSwgMHhlZmYzYmUzMCwgMHhmMjAzMzcwZiwgMHhmNDVhNjc0MSwgMHhmNmQ2N2Q1MywgMHhmOTU3ZGI2NiwgMHhmYmMyZjY0NywgMHhmZTAwZjJiOSwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHgwMWIzNzIxOCwgMHgwMzEzYTBjNiwgMHgwNDFkOTMwZCwgMHgwNGQyODA1NywgMHgwNTM3MzFiMCwgMHgwNTUzNGRmZiwgMHgwNTMwOWJmZCwgMHgwNGRhNDQwZCwgMHgwNDVjMWFlZSwgMHgwM2MxZmNkZCwgMHgwMzE3M2VmNSwgMHgwMjY2M2FlOCwgMHgwMWI3ZjczNiwgMHgwMTEzZWM3OSwgMHgwMDdmZTZhOSwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHhmZjk2YjIyOSwgMHhmZjQ0Zjk5ZiwgMHhmZjBhODZiZSwgMHhmZWU1ZjgwMywgMHhmZWQ1MThmZCwgMHhmZWQ1MjFmZCwgMHhmZWUyZjRmZCwgMHhmZWZiNTRmOCwgMHhmZjFiMTU5YiwgMHhmZjNmNDIwMywgMHhmZjY1MzllMCwgMHhmZjhhYzUwMiwgMHhmZmFlMWRkZCwgMHhmZmNkZjNmOSwgMHhmZmU5Njc5OCwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHgwMDExOWRlNiwgMHgwMDFlNmI3ZSwgMHgwMDI2Y2I3YSwgMHgwMDJiNDgzMCwgMHgwMDJjODNkNiwgMHgwMDJiMmE4MiwgMHgwMDI3ZTY3YSwgMHgwMDIzNTZmOSwgMHgwMDFlMDk4ZSwgMHgwMDE4NzVlNCwgMHgwMDEyZmJiZSwgMHgwMDBkZTJkMSwgMHgwMDA5NWMxMCwgMHgwMDA1ODQxNCwgMHgwMDAyNjYzNiwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHhmZmZlNDRhOSwgMHhmZmZkMjA2ZCwgMHhmZmZjN2I3ZiwgMHhmZmZjM2M4ZiwgMHhmZmZjNGFjMiwgMHhmZmZjOGYyYiwgMHhmZmZjZjVjNCwgMHhmZmZkNmRmMywgMHhmZmZkZWFiMiwgMHhmZmZlNjI3NSwgMHhmZmZlY2VjZiwgMHhmZmZmMmMwNywgMHhmZmZmNzg4YywgMHhmZmZmYjQ3MSwgMHhmZmZmZTBmMiwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHgwMDAwMTNlNiwgMHgwMDAwMWYwMywgMHgwMDAwMjM5NiwgMHgwMDAwMjM5OSwgMHgwMDAwMjBiNiwgMHgwMDAwMWMzYywgMHgwMDAwMTcyMiwgMHgwMDAwMTIxNiwgMHgwMDAwMGQ4MSwgMHgwMDAwMDk5YywgMHgwMDAwMDY3YywgMHgwMDAwMDQxOSwgMHgwMDAwMDI1ZiwgMHgwMDAwMDEzMSwgMHgwMDAwMDA3MCwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHhmZmZmZmZjNywgMHhmZmZmZmZiMywgMHhmZmZmZmZiMywgMHhmZmZmZmZiZSwgMHhmZmZmZmZjZCwgMHhmZmZmZmZkYiwgMHhmZmZmZmZlNywgMHhmZmZmZmZmMCwgMHhmZmZmZmZmNywgMHhmZmZmZmZmYiwgMHhmZmZmZmZmZSwgMHhmZmZmZmZmZiwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwKKyAgICAgICAgMHgwMDAwMDAwMCAvLyB0aGlzIG9uZSBpcyBuZWVkZWQgZm9yIGxlcnBpbmcgdGhlIGxhc3QgY29lZmZpY2llbnQKK307CisKKy8qCisgKiBUaGVzZSBjb2VmZmljaWVudHMgYXJlIG9wdGltaXplZCBmb3IgNDhLSHogLT4gNDQuMUtIeiAoc3RvcC1iYW5kIGF0IDIyLjA1MEtIeikKKyAqIEl0J3MgcG9zc2libGUgdG8gdXNlIHRoZSBhYm92ZSBjb2VmZmljaWVudCBmb3IgYW55IGRvd24tc2FtcGxpbmcKKyAqIGF0IHRoZSBleHBlbnNlIG9mIGEgc2xvd2VyIHByb2Nlc3NpbmcgbG9vcCAod2UgY2FuIGludGVycG9sYXRlCisgKiB0aGVzZSBjb2VmZmljaWVudCBmcm9tIHRoZSBhYm92ZSBieSAiU3RyZXRjaGluZyIgdGhlbSBpbiB0aW1lKS4KKyAqLworY29uc3QgaW50MzJfdCBBdWRpb1Jlc2FtcGxlclNpbmM6Om1GaXJDb2Vmc0Rvd25bXSA9IHsKKyAgICAgICAgMHg3ZmZmZmZmZiwgMHg3ZjU1ZTQ2ZCwgMHg3ZDViNGM2MCwgMHg3YTFiNGI5OCwgMHg3NWE3ZmIxNCwgMHg3MDE5ZjBiZCwgMHg2OThmODc1YSwgMHg2MjJiZmQ1OSwgMHg1YTE2NzI1NiwgMHg1MTc4Y2M1NCwgMHg0ODdlOGU2YywgMHgzZjUzYWFlOCwgMHgzNjIzNWFkNCwgMHgyZDE3MDQ3YiwgMHgyNDU1MzlhYiwgMHgxYzAwZDU0MCwKKyAgICAgICAgMHgxNDM4M2U1NywgMHgwZDE0ZDVjYSwgMHgwNmFhOTEwYiwgMHgwMTA3YzM4YiwgMHhmYzM1MTY1NCwgMHhmODM1YWJhZSwgMHhmNTA3NmI0NSwgMHhmMmEzNzIwMiwgMHhmMGZlOWZhYSwgMHhmMDBhM2JiZCwgMHhlZmI0YWE4MSwgMHhlZmVhMmIwNSwgMHhmMDk1OTcxNiwgMHhmMWExMWU4MywgMHhmMmY2ZjdhMCwgMHhmNDgxZmZmNCwKKyAgICAgICAgMHhmNjJlNDhjZSwgMHhmN2U5OGNhNSwgMHhmOWEzOGI0YywgMHhmYjRlNGJmYSwgMHhmY2RlNDU2ZiwgMHhmZTRhNmQzMCwgMHhmZjhjMmZkZiwgMHgwMDlmNTU1NSwgMHgwMTgxZDM5MywgMHgwMjMzOTQwZiwgMHgwMmI2MmYwNiwgMHgwMzBjYTA3ZCwgMHgwMzNhZmE2MiwgMHgwMzQ2MTcyNSwgMHgwMzMzNGY4MywgMHgwMzA4MzVmYSwKKyAgICAgICAgMHgwMmNhNTljYywgMHgwMjdmMTJkMSwgMHgwMjJiNTcwZCwgMHgwMWQzOWE0OSwgMHgwMTdiYjc4ZiwgMHgwMTI2ZTQxNCwgMHgwMGQ3YWFhZiwgMHgwMDhmZWVjNywgMHgwMDUwZjU4NCwgMHgwMDFiNzNlMywgMHhmZmVmYTA2MywgMHhmZmNkNDZlZCwgMHhmZmIzZGRjZCwgMHhmZmEyOWFhYSwgMHhmZjk4ODY5MSwgMHhmZjk0OTA2NiwKKyAgICAgICAgMHhmZjk1OWQyNCwgMHhmZjlhOTU5ZSwgMHhmZmEyNzE5NSwgMHhmZmFjNDAxMSwgMHhmZmI3MmQyYiwgMHhmZmMyODU2OSwgMHhmZmNkYjcwNiwgMHhmZmQ4NTE3MSwgMHhmZmUyMDM2NCwgMHhmZmVhOTdlOSwgMHhmZmYxZjJiMiwgMHhmZmY4MGMwNiwgMHhmZmZjZWM5MiwgMHgwMDAwYTk1NSwgMHgwMDAzNWZkOCwgMHgwMDA1MzJjZiwKKyAgICAgICAgMHgwMDA2NDczNSwgMHgwMDA2YzFmOSwgMHgwMDA2YzYyZCwgMHgwMDA2NzNiYSwgMHgwMDA1ZTY4ZiwgMHgwMDA1MzYzMCwgMHgwMDA0NzVhMywgMHgwMDAzYjM5NywgMHgwMDAyZmFjMSwgMHgwMDAyNTI1NywgMHgwMDAxYmU5ZSwgMHgwMDAxNDE3YSwgMHgwMDAwZGFmZCwgMHgwMDAwODllYiwgMHgwMDAwNGMyOCwgMHgwMDAwMWYxZCwKKyAgICAgICAgMHgwMDAwMDAwMCwgMHhmZmZmZWMxMCwgMHhmZmZmZTBiZSwgMHhmZmZmZGJjNSwgMHhmZmZmZGIzOSwgMHhmZmZmZGQ4YiwgMHhmZmZmZTE4MiwgMHhmZmZmZTYzOCwgMHhmZmZmZWIwYSwgMHhmZmZmZWY4ZiwgMHhmZmZmZjM4YiwgMHhmZmZmZjZlMywgMHhmZmZmZjk5MywgMHhmZmZmZmJhNiwgMHhmZmZmZmQzMCwgMHhmZmZmZmU0YSwKKyAgICAgICAgMHhmZmZmZmYwOSwgMHhmZmZmZmY4NSwgMHhmZmZmZmZkMSwgMHhmZmZmZmZmYiwgMHgwMDAwMDAwZiwgMHgwMDAwMDAxNiwgMHgwMDAwMDAxNSwgMHgwMDAwMDAxMiwgMHgwMDAwMDAwZCwgMHgwMDAwMDAwOSwgMHgwMDAwMDAwNiwgMHgwMDAwMDAwMywgMHgwMDAwMDAwMiwgMHgwMDAwMDAwMSwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwKKyAgICAgICAgMHgwMDAwMDAwMCAvLyB0aGlzIG9uZSBpcyBuZWVkZWQgZm9yIGxlcnBpbmcgdGhlIGxhc3QgY29lZmZpY2llbnQKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGlubGluZQoraW50MzJfdCBtdWxSTChpbnQgbGVmdCwgaW50MzJfdCBpbiwgdWludDMyX3QgdlJMKQoreworI2lmIGRlZmluZWQoX19hcm1fXykgJiYgIWRlZmluZWQoX190aHVtYl9fKQorICAgIGludDMyX3Qgb3V0OworICAgIGlmIChsZWZ0KSB7CisgICAgICAgIGFzbSggInNtdWx0YiAlW291dF0sICVbaW5dLCAlW3ZSTF0gXG4iCisgICAgICAgICAgICAgOiBbb3V0XSI9ciIob3V0KQorICAgICAgICAgICAgIDogW2luXSIlciIoaW4pLCBbdlJMXSJyIih2UkwpCisgICAgICAgICAgICAgOiApOworICAgIH0gZWxzZSB7CisgICAgICAgIGFzbSggInNtdWx0dCAlW291dF0sICVbaW5dLCAlW3ZSTF0gXG4iCisgICAgICAgICAgICAgOiBbb3V0XSI9ciIob3V0KQorICAgICAgICAgICAgIDogW2luXSIlciIoaW4pLCBbdlJMXSJyIih2UkwpCisgICAgICAgICAgICAgOiApOworICAgIH0KKyAgICByZXR1cm4gb3V0OworI2Vsc2UKKyAgICBpZiAobGVmdCkgeworICAgICAgICByZXR1cm4gaW50MTZfdChpbj4+MTYpICogaW50MTZfdCh2UkwmMHhGRkZGKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gaW50MTZfdChpbj4+MTYpICogaW50MTZfdCh2Ukw+PjE2KTsKKyAgICB9CisjZW5kaWYKK30KKworc3RhdGljIGlubGluZQoraW50MzJfdCBtdWxBZGQoaW50MTZfdCBpbiwgaW50MzJfdCB2LCBpbnQzMl90IGEpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgaW50MzJfdCBvdXQ7CisgICAgYXNtKCAic21sYXdiICVbb3V0XSwgJVt2XSwgJVtpbl0sICVbYV0gXG4iCisgICAgICAgICA6IFtvdXRdIj1yIihvdXQpCisgICAgICAgICA6IFtpbl0iJXIiKGluKSwgW3ZdInIiKHYpLCBbYV0iciIoYSkKKyAgICAgICAgIDogKTsKKyAgICByZXR1cm4gb3V0OworI2Vsc2UKKyAgICByZXR1cm4gYSArIGluICogKHY+PjE2KTsKKyAgICAvLyBpbXByb3ZlZCBwcmVjaXNpb24KKyAgICAvLyByZXR1cm4gYSArIGluICogKHY+PjE2KSArICgoaW4gKiAodiAmIDB4ZmZmZikpID4+IDE2KTsKKyNlbmRpZgorfQorCitzdGF0aWMgaW5saW5lCitpbnQzMl90IG11bEFkZFJMKGludCBsZWZ0LCB1aW50MzJfdCBpblJMLCBpbnQzMl90IHYsIGludDMyX3QgYSkKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICBpbnQzMl90IG91dDsKKyAgICBpZiAobGVmdCkgeworICAgICAgICBhc20oICJzbWxhd2IgJVtvdXRdLCAlW3ZdLCAlW2luUkxdLCAlW2FdIFxuIgorICAgICAgICAgICAgIDogW291dF0iPXIiKG91dCkKKyAgICAgICAgICAgICA6IFtpblJMXSIlciIoaW5STCksIFt2XSJyIih2KSwgW2FdInIiKGEpCisgICAgICAgICAgICAgOiApOworICAgIH0gZWxzZSB7CisgICAgICAgIGFzbSggInNtbGF3dCAlW291dF0sICVbdl0sICVbaW5STF0sICVbYV0gXG4iCisgICAgICAgICAgICAgOiBbb3V0XSI9ciIob3V0KQorICAgICAgICAgICAgIDogW2luUkxdIiVyIihpblJMKSwgW3ZdInIiKHYpLCBbYV0iciIoYSkKKyAgICAgICAgICAgICA6ICk7CisgICAgfQorICAgIHJldHVybiBvdXQ7CisjZWxzZQorICAgIGlmIChsZWZ0KSB7CisgICAgICAgIHJldHVybiBhICsgKGludDE2X3QoaW5STCYweEZGRkYpICogKHY+PjE2KSk7CisgICAgICAgIC8vaW1wcm92ZWQgcHJlY2lzaW9uCisgICAgICAgIC8vIHJldHVybiBhICsgKGludDE2X3QoaW5STCYweEZGRkYpICogKHY+PjE2KSkgKyAoKGludDE2X3QoaW5STCYweEZGRkYpICogKHYgJiAweGZmZmYpKSA+PiAxNik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGEgKyAoaW50MTZfdChpblJMPj4xNikgKiAodj4+MTYpKTsKKyAgICB9CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBdWRpb1Jlc2FtcGxlclNpbmM6OkF1ZGlvUmVzYW1wbGVyU2luYyhpbnQgYml0RGVwdGgsCisgICAgICAgIGludCBpbkNoYW5uZWxDb3VudCwgaW50MzJfdCBzYW1wbGVSYXRlKQorICAgIDogQXVkaW9SZXNhbXBsZXIoYml0RGVwdGgsIGluQ2hhbm5lbENvdW50LCBzYW1wbGVSYXRlKSwKKyAgICBtU3RhdGUoMCkKK3sKKyAgICAvKgorICAgICAqIExheW91dCBvZiB0aGUgc3RhdGUgYnVmZmVyIGZvciAzMiB0YXA6CisgICAgICoKKyAgICAgKiAicHJlc2VudCIgc2FtcGxlICAgICAgICAgICAgYmVnaW5uaW5nIG9mIDJuZCBidWZmZXIKKyAgICAgKiAgICAgICAgICAgICAgICAgdiAgICAgICAgICAgICAgICB2CisgICAgICogIDAgICAgICAgICAgICAgIDAxICAgICAgICAgICAgICAgMiAgICAgICAgICAgICAgMjMgICAgICAgICAgICAgIDMKKyAgICAgKiAgMCAgICAgICAgICAgICAgRjAgICAgICAgICAgICAgICAwICAgICAgICAgICAgICBGMCAgICAgICAgICAgICAgRgorICAgICAqIFtwcHBwcHBwcHBwcHBwcHBJbm5ubm5ubm5ubm5ubm5ubnBwcHBwcHBwcHBwcHBwcElubm5ubm5ubm5ubm5ubm5uXQorICAgICAqICAgICAgICAgICAgICAgICBeICAgICAgICAgICAgICAgXiBoZWFkCisgICAgICoKKyAgICAgKiBwID0gcGFzdCBzYW1wbGVzLCBjb252b2x1dGVkIHdpdGggdGhlIChwKW9zaXRpdmUgc2lkZSBvZiBzaW5jKCkKKyAgICAgKiBuID0gZnV0dXJlIHNhbXBsZXMsIGNvbnZvbHV0ZWQgd2l0aCB0aGUgKG4pZWdhdGl2ZSBzaWRlIG9mIHNpbmMoKQorICAgICAqIHIgPSBleHRyYSBzcGFjZSBmb3IgaW1wbGVtZW50aW5nIHRoZSByaW5nIGJ1ZmZlcgorICAgICAqCisgICAgICovCisKKyAgICBjb25zdCBzaXplX3QgbnVtQ29lZnMgPSAyKmhhbGZOdW1Db2VmczsKKyAgICBjb25zdCBzaXplX3Qgc3RhdGVTaXplID0gbnVtQ29lZnMgKiBpbkNoYW5uZWxDb3VudCAqIDI7CisgICAgbVN0YXRlID0gbmV3IGludDE2X3Rbc3RhdGVTaXplXTsKKyAgICBtZW1zZXQobVN0YXRlLCAwLCBzaXplb2YoaW50MTZfdCkqc3RhdGVTaXplKTsKKyAgICBtSW1wdWxzZSA9IG1TdGF0ZSArIChoYWxmTnVtQ29lZnMtMSkqaW5DaGFubmVsQ291bnQ7CisgICAgbVJpbmdGdWxsID0gbUltcHVsc2UgKyAobnVtQ29lZnMrMSkqaW5DaGFubmVsQ291bnQ7Cit9CisKK0F1ZGlvUmVzYW1wbGVyU2luYzo6fkF1ZGlvUmVzYW1wbGVyU2luYygpCit7CisgICAgZGVsZXRlIFtdIG1TdGF0ZTsKK30KKwordm9pZCBBdWRpb1Jlc2FtcGxlclNpbmM6OmluaXQoKSB7Cit9CisKK3ZvaWQgQXVkaW9SZXNhbXBsZXJTaW5jOjpyZXNhbXBsZShpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LAorICAgICAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpCit7CisgICAgbUZpckNvZWZzID0gKG1JblNhbXBsZVJhdGUgPD0gbVNhbXBsZVJhdGUpID8gbUZpckNvZWZzVXAgOiBtRmlyQ29lZnNEb3duOworCisgICAgLy8gc2VsZWN0IHRoZSBhcHByb3ByaWF0ZSByZXNhbXBsZXIKKyAgICBzd2l0Y2ggKG1DaGFubmVsQ291bnQpIHsKKyAgICBjYXNlIDE6CisgICAgICAgIHJlc2FtcGxlPDE+KG91dCwgb3V0RnJhbWVDb3VudCwgcHJvdmlkZXIpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDI6CisgICAgICAgIHJlc2FtcGxlPDI+KG91dCwgb3V0RnJhbWVDb3VudCwgcHJvdmlkZXIpOworICAgICAgICBicmVhazsKKyAgICB9Cit9CisKKwordGVtcGxhdGU8aW50IENIQU5ORUxTPgordm9pZCBBdWRpb1Jlc2FtcGxlclNpbmM6OnJlc2FtcGxlKGludDMyX3QqIG91dCwgc2l6ZV90IG91dEZyYW1lQ291bnQsCisgICAgICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXIqIHByb3ZpZGVyKQoreworICAgIGludDE2X3QqIGltcHVsc2UgPSBtSW1wdWxzZTsKKyAgICB1aW50MzJfdCB2UkwgPSBtVm9sdW1lUkw7CisgICAgc2l6ZV90IGlucHV0SW5kZXggPSBtSW5wdXRJbmRleDsKKyAgICB1aW50MzJfdCBwaGFzZUZyYWN0aW9uID0gbVBoYXNlRnJhY3Rpb247CisgICAgdWludDMyX3QgcGhhc2VJbmNyZW1lbnQgPSBtUGhhc2VJbmNyZW1lbnQ7CisgICAgc2l6ZV90IG91dHB1dEluZGV4ID0gMDsKKyAgICBzaXplX3Qgb3V0cHV0U2FtcGxlQ291bnQgPSBvdXRGcmFtZUNvdW50ICogMjsKKyAgICBzaXplX3QgaW5GcmFtZUNvdW50ID0gKG91dEZyYW1lQ291bnQqbUluU2FtcGxlUmF0ZSkvbVNhbXBsZVJhdGU7CisKKyAgICBBdWRpb0J1ZmZlclByb3ZpZGVyOjpCdWZmZXImIGJ1ZmZlcihtQnVmZmVyKTsKKyAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCkgeworICAgICAgICAvLyBidWZmZXIgaXMgZW1wdHksIGZldGNoIGEgbmV3IG9uZQorICAgICAgICB3aGlsZSAoYnVmZmVyLmZyYW1lQ291bnQgPT0gMCkgeworICAgICAgICAgICAgYnVmZmVyLmZyYW1lQ291bnQgPSBpbkZyYW1lQ291bnQ7CisgICAgICAgICAgICBwcm92aWRlci0+Z2V0TmV4dEJ1ZmZlcigmYnVmZmVyKTsKKyAgICAgICAgICAgIGlmIChidWZmZXIucmF3ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBnb3RvIHJlc2FtcGxlX2V4aXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb25zdCB1aW50MzJfdCBwaGFzZUluZGV4ID0gcGhhc2VGcmFjdGlvbiA+PiBrTnVtUGhhc2VCaXRzOworICAgICAgICAgICAgaWYgKHBoYXNlSW5kZXggPT0gMSkgeworICAgICAgICAgICAgICAgIC8vIHJlYWQgb25lIGZyYW1lCisgICAgICAgICAgICAgICAgcmVhZDxDSEFOTkVMUz4oaW1wdWxzZSwgcGhhc2VGcmFjdGlvbiwgYnVmZmVyLmkxNiwgaW5wdXRJbmRleCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHBoYXNlSW5kZXggPT0gMikgeworICAgICAgICAgICAgICAgIC8vIHJlYWQgMiBmcmFtZXMKKyAgICAgICAgICAgICAgICByZWFkPENIQU5ORUxTPihpbXB1bHNlLCBwaGFzZUZyYWN0aW9uLCBidWZmZXIuaTE2LCBpbnB1dEluZGV4KTsKKyAgICAgICAgICAgICAgICBpbnB1dEluZGV4Kys7CisgICAgICAgICAgICAgICAgaWYgKGlucHV0SW5kZXggPj0gbUJ1ZmZlci5mcmFtZUNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIGlucHV0SW5kZXggLT0gbUJ1ZmZlci5mcmFtZUNvdW50OworICAgICAgICAgICAgICAgICAgICBwcm92aWRlci0+cmVsZWFzZUJ1ZmZlcigmYnVmZmVyKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZWFkPENIQU5ORUxTPihpbXB1bHNlLCBwaGFzZUZyYWN0aW9uLCBidWZmZXIuaTE2LCBpbnB1dEluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQxNl90ICppbiA9IGJ1ZmZlci5pMTY7CisgICAgICAgIGNvbnN0IHNpemVfdCBmcmFtZUNvdW50ID0gYnVmZmVyLmZyYW1lQ291bnQ7CisKKyAgICAgICAgLy8gQWx3YXlzIHJlYWQtaW4gdGhlIGZpcnN0IHNhbXBsZXMgZnJvbSB0aGUgaW5wdXQgYnVmZmVyCisgICAgICAgIGludDE2X3QqIGhlYWQgPSBpbXB1bHNlICsgaGFsZk51bUNvZWZzKkNIQU5ORUxTOworICAgICAgICBoZWFkWzBdID0gaW5baW5wdXRJbmRleCpDSEFOTkVMUyArIDBdOworICAgICAgICBpZiAoQ0hBTk5FTFMgPT0gMikKKyAgICAgICAgICAgIGhlYWRbMV0gPSBpbltpbnB1dEluZGV4KkNIQU5ORUxTICsgMV07CisKKyAgICAgICAgLy8gaGFuZGxlIGJvdW5kYXJ5IGNhc2UKKyAgICAgICAgaW50MzJfdCBsLCByOworICAgICAgICB3aGlsZSAob3V0cHV0SW5kZXggPCBvdXRwdXRTYW1wbGVDb3VudCkgeworICAgICAgICAgICAgZmlsdGVyQ29lZmZpY2llbnQ8Q0hBTk5FTFM+KGwsIHIsIHBoYXNlRnJhY3Rpb24sIGltcHVsc2UpOworICAgICAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IDIgKiBtdWxSTCgxLCBsLCB2UkwpOworICAgICAgICAgICAgb3V0W291dHB1dEluZGV4KytdICs9IDIgKiBtdWxSTCgwLCByLCB2UkwpOworCisgICAgICAgICAgICBwaGFzZUZyYWN0aW9uICs9IHBoYXNlSW5jcmVtZW50OworICAgICAgICAgICAgY29uc3QgdWludDMyX3QgcGhhc2VJbmRleCA9IHBoYXNlRnJhY3Rpb24gPj4ga051bVBoYXNlQml0czsKKyAgICAgICAgICAgIGlmIChwaGFzZUluZGV4ID09IDEpIHsKKyAgICAgICAgICAgICAgICBpbnB1dEluZGV4Kys7CisgICAgICAgICAgICAgICAgaWYgKGlucHV0SW5kZXggPj0gZnJhbWVDb3VudCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAvLyBuZWVkIGEgbmV3IGJ1ZmZlcgorICAgICAgICAgICAgICAgIHJlYWQ8Q0hBTk5FTFM+KGltcHVsc2UsIHBoYXNlRnJhY3Rpb24sIGluLCBpbnB1dEluZGV4KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZihwaGFzZUluZGV4ID09IDIpIHsgICAgLy8gbWF4aW11bSB2YWx1ZQorICAgICAgICAgICAgICAgIGlucHV0SW5kZXgrKzsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXRJbmRleCA+PSBmcmFtZUNvdW50KQorICAgICAgICAgICAgICAgICAgICBicmVhazsgIC8vIDAgZnJhbWUgYXZhaWxhYmxlLCAyIGZyYW1lcyBuZWVkZWQKKyAgICAgICAgICAgICAgICAvLyByZWFkIGZpcnN0IGZyYW1lCisgICAgICAgICAgICAgICAgcmVhZDxDSEFOTkVMUz4oaW1wdWxzZSwgcGhhc2VGcmFjdGlvbiwgaW4sIGlucHV0SW5kZXgpOworICAgICAgICAgICAgICAgIGlucHV0SW5kZXgrKzsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXRJbmRleCA+PSBmcmFtZUNvdW50KQorICAgICAgICAgICAgICAgICAgICBicmVhazsgIC8vIDAgZnJhbWUgYXZhaWxhYmxlLCAxIGZyYW1lIG5lZWRlZAorICAgICAgICAgICAgICAgIC8vIHJlYWQgc2Vjb25kIGZyYW1lCisgICAgICAgICAgICAgICAgcmVhZDxDSEFOTkVMUz4oaW1wdWxzZSwgcGhhc2VGcmFjdGlvbiwgaW4sIGlucHV0SW5kZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gaWYgZG9uZSB3aXRoIGJ1ZmZlciwgc2F2ZSBzYW1wbGVzCisgICAgICAgIGlmIChpbnB1dEluZGV4ID49IGZyYW1lQ291bnQpIHsKKyAgICAgICAgICAgIGlucHV0SW5kZXggLT0gZnJhbWVDb3VudDsKKyAgICAgICAgICAgIHByb3ZpZGVyLT5yZWxlYXNlQnVmZmVyKCZidWZmZXIpOworICAgICAgICB9CisgICAgfQorCityZXNhbXBsZV9leGl0OgorICAgIG1JbXB1bHNlID0gaW1wdWxzZTsKKyAgICBtSW5wdXRJbmRleCA9IGlucHV0SW5kZXg7CisgICAgbVBoYXNlRnJhY3Rpb24gPSBwaGFzZUZyYWN0aW9uOworfQorCit0ZW1wbGF0ZTxpbnQgQ0hBTk5FTFM+CisvKioqCisqIHJlYWQoKQorKgorKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIG9ubHkgb25lIGZyYW1lIGZyb20gaW5wdXQgYnVmZmVyIGFuZCB3cml0ZXMgaXQgaW4KKyogc3RhdGUgYnVmZmVyCisqCisqKi8KK3ZvaWQgQXVkaW9SZXNhbXBsZXJTaW5jOjpyZWFkKAorICAgICAgICBpbnQxNl90KiYgaW1wdWxzZSwgdWludDMyX3QmIHBoYXNlRnJhY3Rpb24sCisgICAgICAgIGludDE2X3QgY29uc3QqIGluLCBzaXplX3QgaW5wdXRJbmRleCkKK3sKKyAgICBjb25zdCB1aW50MzJfdCBwaGFzZUluZGV4ID0gcGhhc2VGcmFjdGlvbiA+PiBrTnVtUGhhc2VCaXRzOworICAgIGltcHVsc2UgKz0gQ0hBTk5FTFM7CisgICAgcGhhc2VGcmFjdGlvbiAtPSAxTFU8PGtOdW1QaGFzZUJpdHM7CisgICAgaWYgKGltcHVsc2UgPj0gbVJpbmdGdWxsKSB7CisgICAgICAgIGNvbnN0IHNpemVfdCBzdGF0ZVNpemUgPSAoaGFsZk51bUNvZWZzKjIpKkNIQU5ORUxTOworICAgICAgICBtZW1jcHkobVN0YXRlLCBtU3RhdGUrc3RhdGVTaXplLCBzaXplb2YoaW50MTZfdCkqc3RhdGVTaXplKTsKKyAgICAgICAgaW1wdWxzZSAtPSBzdGF0ZVNpemU7CisgICAgfQorICAgIGludDE2X3QqIGhlYWQgPSBpbXB1bHNlICsgaGFsZk51bUNvZWZzKkNIQU5ORUxTOworICAgIGhlYWRbMF0gPSBpbltpbnB1dEluZGV4KkNIQU5ORUxTICsgMF07CisgICAgaWYgKENIQU5ORUxTID09IDIpCisgICAgICAgIGhlYWRbMV0gPSBpbltpbnB1dEluZGV4KkNIQU5ORUxTICsgMV07Cit9CisKK3RlbXBsYXRlPGludCBDSEFOTkVMUz4KK3ZvaWQgQXVkaW9SZXNhbXBsZXJTaW5jOjpmaWx0ZXJDb2VmZmljaWVudCgKKyAgICAgICAgaW50MzJfdCYgbCwgaW50MzJfdCYgciwgdWludDMyX3QgcGhhc2UsIGludDE2X3QgY29uc3QgKnNhbXBsZXMpCit7CisgICAgLy8gY29tcHV0ZSB0aGUgaW5kZXggb2YgdGhlIGNvZWZmaWNpZW50IG9uIHRoZSBwb3NpdGl2ZSBzaWRlIGFuZAorICAgIC8vIG5lZ2F0aXZlIHNpZGUKKyAgICB1aW50MzJfdCBpbmRleFAgPSAocGhhc2UgJiBjTWFzaykgPj4gY1NoaWZ0OworICAgIHVpbnQxNl90IGxlcnBQICA9IChwaGFzZSAmIHBNYXNrKSA+PiBwU2hpZnQ7CisgICAgdWludDMyX3QgaW5kZXhOID0gKC1waGFzZSAmIGNNYXNrKSA+PiBjU2hpZnQ7CisgICAgdWludDE2X3QgbGVycE4gID0gKC1waGFzZSAmIHBNYXNrKSA+PiBwU2hpZnQ7CisgICAgaWYgKChpbmRleFAgPT0gMCkgJiYgKGxlcnBQID09IDApKSB7CisgICAgICAgIGluZGV4TiA9IGNNYXNrID4+IGNTaGlmdDsKKyAgICAgICAgbGVycE4gPSBwTWFzayA+PiBwU2hpZnQ7CisgICAgfQorCisgICAgbCA9IDA7CisgICAgciA9IDA7CisgICAgaW50MzJfdCBjb25zdCogY29lZnMgPSBtRmlyQ29lZnM7CisgICAgaW50MTZfdCBjb25zdCAqc1AgPSBzYW1wbGVzOworICAgIGludDE2X3QgY29uc3QgKnNOID0gc2FtcGxlcytDSEFOTkVMUzsKKyAgICBmb3IgKHVuc2lnbmVkIGludCBpPTAgOyBpPGhhbGZOdW1Db2Vmcy80IDsgaSsrKSB7CisgICAgICAgIGludGVycG9sYXRlPENIQU5ORUxTPihsLCByLCBjb2VmcytpbmRleFAsIGxlcnBQLCBzUCk7CisgICAgICAgIGludGVycG9sYXRlPENIQU5ORUxTPihsLCByLCBjb2VmcytpbmRleE4sIGxlcnBOLCBzTik7CisgICAgICAgIHNQIC09IENIQU5ORUxTOyBzTiArPSBDSEFOTkVMUzsgY29lZnMgKz0gMTw8Y29lZnNCaXRzOworICAgICAgICBpbnRlcnBvbGF0ZTxDSEFOTkVMUz4obCwgciwgY29lZnMraW5kZXhQLCBsZXJwUCwgc1ApOworICAgICAgICBpbnRlcnBvbGF0ZTxDSEFOTkVMUz4obCwgciwgY29lZnMraW5kZXhOLCBsZXJwTiwgc04pOworICAgICAgICBzUCAtPSBDSEFOTkVMUzsgc04gKz0gQ0hBTk5FTFM7IGNvZWZzICs9IDE8PGNvZWZzQml0czsKKyAgICAgICAgaW50ZXJwb2xhdGU8Q0hBTk5FTFM+KGwsIHIsIGNvZWZzK2luZGV4UCwgbGVycFAsIHNQKTsKKyAgICAgICAgaW50ZXJwb2xhdGU8Q0hBTk5FTFM+KGwsIHIsIGNvZWZzK2luZGV4TiwgbGVycE4sIHNOKTsKKyAgICAgICAgc1AgLT0gQ0hBTk5FTFM7IHNOICs9IENIQU5ORUxTOyBjb2VmcyArPSAxPDxjb2Vmc0JpdHM7CisgICAgICAgIGludGVycG9sYXRlPENIQU5ORUxTPihsLCByLCBjb2VmcytpbmRleFAsIGxlcnBQLCBzUCk7CisgICAgICAgIGludGVycG9sYXRlPENIQU5ORUxTPihsLCByLCBjb2VmcytpbmRleE4sIGxlcnBOLCBzTik7CisgICAgICAgIHNQIC09IENIQU5ORUxTOyBzTiArPSBDSEFOTkVMUzsgY29lZnMgKz0gMTw8Y29lZnNCaXRzOworICAgIH0KK30KKwordGVtcGxhdGU8aW50IENIQU5ORUxTPgordm9pZCBBdWRpb1Jlc2FtcGxlclNpbmM6OmludGVycG9sYXRlKAorICAgICAgICBpbnQzMl90JiBsLCBpbnQzMl90JiByLAorICAgICAgICBpbnQzMl90IGNvbnN0KiBjb2VmcywgaW50MTZfdCBsZXJwLCBpbnQxNl90IGNvbnN0KiBzYW1wbGVzKQoreworICAgIGludDMyX3QgYzAgPSBjb2Vmc1swXTsKKyAgICBpbnQzMl90IGMxID0gY29lZnNbMV07CisgICAgaW50MzJfdCBzaW5jID0gbXVsQWRkKGxlcnAsIChjMS1jMCk8PDEsIGMwKTsKKyAgICBpZiAoQ0hBTk5FTFMgPT0gMikgeworICAgICAgICB1aW50MzJfdCBybCA9ICpyZWludGVycHJldF9jYXN0PHVpbnQzMl90IGNvbnN0Kj4oc2FtcGxlcyk7CisgICAgICAgIGwgPSBtdWxBZGRSTCgxLCBybCwgc2luYywgbCk7CisgICAgICAgIHIgPSBtdWxBZGRSTCgwLCBybCwgc2luYywgcik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgciA9IGwgPSBtdWxBZGQoc2FtcGxlc1swXSwgc2luYywgbCk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlclNpbmMuaCBiL2xpYnMvYXVkaW9mbGluZ2VyL0F1ZGlvUmVzYW1wbGVyU2luYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2Y2I5MGIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL2F1ZGlvZmxpbmdlci9BdWRpb1Jlc2FtcGxlclNpbmMuaApAQCAtMCwwICsxLDg4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0FVRElPX1JFU0FNUExFUl9TSU5DX0gKKyNkZWZpbmUgQU5EUk9JRF9BVURJT19SRVNBTVBMRVJfU0lOQ19ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisKKyNpbmNsdWRlICJBdWRpb1Jlc2FtcGxlci5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQXVkaW9SZXNhbXBsZXJTaW5jIDogcHVibGljIEF1ZGlvUmVzYW1wbGVyIHsKK3B1YmxpYzoKKyAgICBBdWRpb1Jlc2FtcGxlclNpbmMoaW50IGJpdERlcHRoLCBpbnQgaW5DaGFubmVsQ291bnQsIGludDMyX3Qgc2FtcGxlUmF0ZSk7CisKKyAgICB+QXVkaW9SZXNhbXBsZXJTaW5jKCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgcmVzYW1wbGUoaW50MzJfdCogb3V0LCBzaXplX3Qgb3V0RnJhbWVDb3VudCwKKyAgICAgICAgICAgIEF1ZGlvQnVmZmVyUHJvdmlkZXIqIHByb3ZpZGVyKTsKK3ByaXZhdGU6CisgICAgdm9pZCBpbml0KCk7CisKKyAgICB0ZW1wbGF0ZTxpbnQgQ0hBTk5FTFM+CisgICAgdm9pZCByZXNhbXBsZShpbnQzMl90KiBvdXQsIHNpemVfdCBvdXRGcmFtZUNvdW50LAorICAgICAgICAgICAgQXVkaW9CdWZmZXJQcm92aWRlciogcHJvdmlkZXIpOworCisgICAgdGVtcGxhdGU8aW50IENIQU5ORUxTPgorICAgIGlubGluZSB2b2lkIGZpbHRlckNvZWZmaWNpZW50KAorICAgICAgICAgICAgaW50MzJfdCYgbCwgaW50MzJfdCYgciwgdWludDMyX3QgcGhhc2UsIGludDE2X3QgY29uc3QgKnNhbXBsZXMpOworCisgICAgdGVtcGxhdGU8aW50IENIQU5ORUxTPgorICAgIGlubGluZSB2b2lkIGludGVycG9sYXRlKAorICAgICAgICAgICAgaW50MzJfdCYgbCwgaW50MzJfdCYgciwKKyAgICAgICAgICAgIGludDMyX3QgY29uc3QqIGNvZWZzLCBpbnQxNl90IGxlcnAsIGludDE2X3QgY29uc3QqIHNhbXBsZXMpOworCisgICAgdGVtcGxhdGU8aW50IENIQU5ORUxTPgorICAgIGlubGluZSB2b2lkIHJlYWQoaW50MTZfdComIGltcHVsc2UsIHVpbnQzMl90JiBwaGFzZUZyYWN0aW9uLAorICAgICAgICAgICAgaW50MTZfdCBjb25zdCogaW4sIHNpemVfdCBpbnB1dEluZGV4KTsKKworICAgIGludDE2X3QgKm1TdGF0ZTsKKyAgICBpbnQxNl90ICptSW1wdWxzZTsKKyAgICBpbnQxNl90ICptUmluZ0Z1bGw7CisKKyAgICBpbnQzMl90IGNvbnN0ICogbUZpckNvZWZzOworICAgIHN0YXRpYyBjb25zdCBpbnQzMl90IG1GaXJDb2Vmc0Rvd25bXTsKKyAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBtRmlyQ29lZnNVcFtdOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIHN0YXRpYyBjb25zdCBpbnQzMl90IFJFU0FNUExFX0ZJUl9OVU1fQ09FRiAgICAgICA9IDg7CisgICAgc3RhdGljIGNvbnN0IGludDMyX3QgUkVTQU1QTEVfRklSX0xFUlBfSU5UX0JJVFMgID0gNDsKKworICAgIC8vIHdlIGhhdmUgMTYgY29lZnMgc2FtcGxlcyBwZXIgemVyby1jcm9zc2luZworICAgIHN0YXRpYyBjb25zdCBpbnQgY29lZnNCaXRzID0gUkVTQU1QTEVfRklSX0xFUlBfSU5UX0JJVFM7ICAgICAgICAvLyA0CisgICAgc3RhdGljIGNvbnN0IGludCBjU2hpZnQgPSBrTnVtUGhhc2VCaXRzIC0gY29lZnNCaXRzOyAgICAgICAgICAgIC8vIDI2CisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IGNNYXNrICA9ICgoMTw8Y29lZnNCaXRzKS0xKSA8PCBjU2hpZnQ7ICAgIC8vIDB4Zjw8MjYgPSAzYzAwIDAwMDAKKworICAgIC8vIGFuZCB3ZSB1c2UgMTUgYml0cyB0byBpbnRlcnBvbGF0ZSBiZXR3ZWVuIHRoZXNlIHNhbXBsZXMKKyAgICAvLyB0aGlzIGNhbm5vdCBjaGFuZ2UgYmVjYXVzZSB0aGUgbXVsIGJlbG93IHJlbHkgb24gaXQuCisgICAgc3RhdGljIGNvbnN0IGludCBwTGVycEJpdHMgPSAxNTsKKyAgICBzdGF0aWMgY29uc3QgaW50IHBTaGlmdCA9IGtOdW1QaGFzZUJpdHMgLSBjb2Vmc0JpdHMgLSBwTGVycEJpdHM7ICAgIC8vIDExCisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IHBNYXNrICA9ICgoMTw8cExlcnBCaXRzKS0xKSA8PCBwU2hpZnQ7ICAgIC8vIDB4N2ZmZiA8PCAxMQorCisgICAgLy8gbnVtYmVyIG9mIHplcm8tY3Jvc3Npbmcgb24gZWFjaCBzaWRlCisgICAgc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBoYWxmTnVtQ29lZnMgPSBSRVNBTVBMRV9GSVJfTlVNX0NPRUY7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLypBTkRST0lEX0FVRElPX1JFU0FNUExFUl9TSU5DX0gqLwpkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9BbmRyb2lkLm1rIGIvbGlicy9zdXJmYWNlZmxpbmdlci9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5NmUyNzEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0FuZHJvaWQubWsKQEAgLTAsMCArMSw0OSBAQAorTE9DQUxfUEFUSDo9ICQoY2FsbCBteS1kaXIpCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfU1JDX0ZJTEVTOj0gXAorICAgIGNsei5jcHAuYXJtIFwKKyAgICBEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmNwcCBcCisgICAgRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZUJhc2UuY3BwIFwKKyAgICBHUFVIYXJkd2FyZS9HUFVIYXJkd2FyZS5jcHAgXAorICAgIEJvb3RBbmltYXRpb24uY3BwIFwKKyAgICBCbHVyRmlsdGVyLmNwcC5hcm0gXAorICAgIENQVUdhdWdlLmNwcCBcCisgICAgTGF5ZXIuY3BwIFwKKyAgICBMYXllckJhc2UuY3BwIFwKKyAgICBMYXllckJ1ZmZlci5jcHAgXAorICAgIExheWVyQmx1ci5jcHAgXAorICAgIExheWVyQml0bWFwLmNwcCBcCisgICAgTGF5ZXJEaW0uY3BwIFwKKyAgICBMYXllck9yaWVudGF0aW9uQW5pbS5jcHAgXAorICAgIE9yaWVudGF0aW9uQW5pbWF0aW9uLmNwcCBcCisgICAgU3VyZmFjZUZsaW5nZXIuY3BwIFwKKyAgICBUb2tlbml6ZXIuY3BwIFwKKyAgICBUcmFuc2Zvcm0uY3BwIFwKKyAgICBWUmFtSGVhcC5jcHAKKworCisjIG5lZWQgIi1scnQiIG9uIExpbnV4IHNpbXVsYXRvciB0byBwaWNrIHVwIGNsb2NrX2dldHRpbWUKK2lmZXEgKCQoVEFSR0VUX1NJTVVMQVRPUiksdHJ1ZSkKKwlpZmVxICgkKEhPU1RfT1MpLGxpbnV4KQorCQlMT0NBTF9MRExJQlMgKz0gLWxydAorCWVuZGlmCitlbmRpZgorCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJoYXJkd2FyZSBcCisJbGlidXRpbHMgXAorCWxpYmN1dGlscyBcCisJbGlidWkgXAorCWxpYmNvcmVjZyBcCisJbGlic2dsIFwKKwlsaWJwaXhlbGZsaW5nZXIgXAorCWxpYkVHTCBcCisJbGliR0xFU3YxX0NNCisKK0xPQ0FMX0NfSU5DTFVERVMgOj0gXAorCSQoY2FsbCBpbmNsdWRlLXBhdGgtZm9yLCBjb3JlY2cgZ3JhcGhpY3MpCisKK0xPQ0FMX01PRFVMRTo9IGxpYnN1cmZhY2VmbGluZ2VyCisKK2luY2x1ZGUgJChCVUlMRF9TSEFSRURfTElCUkFSWSkKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvQmFycmllci5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9CYXJyaWVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTJiY2Y2YQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQmFycmllci5oCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQkFSUklFUl9ICisjZGVmaW5lIEFORFJPSURfQkFSUklFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgQmFycmllcgoreworcHVibGljOgorICAgIGlubGluZSBCYXJyaWVyKCkgOiBzdGF0ZShDTE9TRUQpIHsgfQorICAgIGlubGluZSB+QmFycmllcigpIHsgfQorICAgIHZvaWQgb3BlbigpIHsKKyAgICAgICAgLy8gZ2NjIG1lbW9yeSBiYXJyaWVyLCB0aGlzIG1ha2VzIHN1cmUgYWxsIG1lbW9yeSB3cml0ZXMKKyAgICAgICAgLy8gaGF2ZSBiZWVuIGlzc3VlZCBieSBnY2MuIE9uIGFuIFNNUCBzeXN0ZW0gd2UnZCBuZWVkIGEgcmVhbAorICAgICAgICAvLyBoL3cgYmFycmllci4KKyAgICAgICAgYXNtIHZvbGF0aWxlICgiIjo6OiJtZW1vcnkiKTsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKGxvY2spOworICAgICAgICBzdGF0ZSA9IE9QRU5FRDsKKyAgICAgICAgY3YuYnJvYWRjYXN0KCk7CisgICAgfQorICAgIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChsb2NrKTsKKyAgICAgICAgc3RhdGUgPSBDTE9TRUQ7CisgICAgfQorICAgIHZvaWQgd2FpdCgpIGNvbnN0IHsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKGxvY2spOworICAgICAgICB3aGlsZSAoc3RhdGUgPT0gQ0xPU0VEKSB7CisgICAgICAgICAgICBjdi53YWl0KGxvY2spOworICAgICAgICB9CisgICAgfQorcHJpdmF0ZToKKyAgICBlbnVtIHsgT1BFTkVELCBDTE9TRUQgfTsKKyAgICBtdXRhYmxlICAgICBNdXRleCAgICAgICBsb2NrOworICAgIG11dGFibGUgICAgIENvbmRpdGlvbiAgIGN2OworICAgIHZvbGF0aWxlICAgIGludCAgICAgICAgIHN0YXRlOworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfQkFSUklFUl9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL0JsdXJGaWx0ZXIuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9CbHVyRmlsdGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGMwYmEwCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9CbHVyRmlsdGVyLmNwcApAQCAtMCwwICsxLDMyNiBAQAorLyogCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKworI2luY2x1ZGUgPHBpeGVsZmxpbmdlci9waXhlbGZsaW5nZXIuaD4KKworI2luY2x1ZGUgImNsei5oIgorCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworI2lmIEJZVEVfT1JERVIgPT0gTElUVExFX0VORElBTgoraW5saW5lIHVpbnQzMl90IEJMVVJfUkdCQV9UT19IT1NUKHVpbnQzMl90IHYpIHsKKyAgICByZXR1cm4gdjsKK30KK2lubGluZSB1aW50MzJfdCBCTFVSX0hPU1RfVE9fUkdCQSh1aW50MzJfdCB2KSB7CisgICAgcmV0dXJuIHY7Cit9CisjZWxzZQoraW5saW5lIHVpbnQzMl90IEJMVVJfUkdCQV9UT19IT1NUKHVpbnQzMl90IHYpIHsKKyAgICByZXR1cm4gKHY8PDI0KSB8ICh2Pj4yNCkgfCAoKHY8PDgpJjB4ZmYwMDAwKSB8ICgodj4+OCkmMHhmZjAwKTsKK30KK2lubGluZSB1aW50MzJfdCBCTFVSX0hPU1RfVE9fUkdCQSh1aW50MzJfdCB2KSB7CisgICAgcmV0dXJuICh2PDwyNCkgfCAodj4+MjQpIHwgKCh2PDw4KSYweGZmMDAwMCkgfCAoKHY+PjgpJjB4ZmYwMCk7Cit9CisjZW5kaWYKKworY29uc3QgaW50IEJMVVJfRElUSEVSX0JJVFMgPSA2OyAgLy8gZGl0aGVyIHdlaWdodHMgc3RvcmVkIG9uIDYgYml0cworY29uc3QgaW50IEJMVVJfRElUSEVSX09SREVSX1NISUZUPSAzOworY29uc3QgaW50IEJMVVJfRElUSEVSX09SREVSICAgICAgPSAoMTw8QkxVUl9ESVRIRVJfT1JERVJfU0hJRlQpOworY29uc3QgaW50IEJMVVJfRElUSEVSX1NJWkUgICAgICAgPSBCTFVSX0RJVEhFUl9PUkRFUiAqIEJMVVJfRElUSEVSX09SREVSOworY29uc3QgaW50IEJMVVJfRElUSEVSX01BU0sgICAgICAgPSBCTFVSX0RJVEhFUl9PUkRFUi0xOworCitzdGF0aWMgY29uc3QgdWludDhfdCBnRGl0aGVyTWF0cml4W0JMVVJfRElUSEVSX1NJWkVdID0geworICAgICAwLCAzMiwgIDgsIDQwLCAgMiwgMzQsIDEwLCA0MiwKKyAgICA0OCwgMTYsIDU2LCAyNCwgNTAsIDE4LCA1OCwgMjYsCisgICAgMTIsIDQ0LCAgNCwgMzYsIDE0LCA0NiwgIDYsIDM4LAorICAgIDYwLCAyOCwgNTIsIDIwLCA2MiwgMzAsIDU0LCAyMiwKKyAgICAgMywgMzUsIDExLCA0MywgIDEsIDMzLCAgOSwgNDEsCisgICAgNTEsIDE5LCA1OSwgMjcsIDQ5LCAxNywgNTcsIDI1LAorICAgIDE1LCA0NywgIDcsIDM5LCAxMywgNDUsICA1LCAzNywKKyAgICA2MywgMzEsIDU1LCAyMywgNjEsIDI5LCA1MywgMjEKK307CisKKwordGVtcGxhdGUgPGludCBGQUNUT1IgPSAwPgorc3RydWN0IEJsdXJDb2xvcjU2NQoreworICAgIHR5cGVkZWYgdWludDE2X3QgdHlwZTsKKyAgICBpbnQgciwgZywgYjsgICAgCisgICAgaW5saW5lIEJsdXJDb2xvcjU2NSgpIHsgfQorICAgIGlubGluZSBCbHVyQ29sb3I1NjUodWludDE2X3QgdikgeworICAgICAgICByID0gdiA+PiAxMTsKKyAgICAgICAgZyA9ICh2ID4+IDUpICYgMHgzRTsKKyAgICAgICAgYiA9IHYgJiAweDFGOworICAgIH0KKyAgICBpbmxpbmUgdm9pZCBjbGVhcigpIHsgcj1nPWI9MDsgfQorICAgIGlubGluZSB1aW50MTZfdCB0byhpbnQgc2hpZnQsIGludCBsYXN0LCBpbnQgZGl0aGVyKSBjb25zdCB7CisgICAgICAgIGludCBSID0gcjsKKyAgICAgICAgaW50IEcgPSBnOworICAgICAgICBpbnQgQiA9IGI7CisgICAgICAgIGlmICAoVU5MSUtFTFkobGFzdCkpIHsKKyAgICAgICAgICAgIGlmIChGQUNUT1I+MCkgeworICAgICAgICAgICAgICAgIGludCBMID0gKFIrRytCKT4+MTsKKyAgICAgICAgICAgICAgICBSICs9ICgoKEw+PjEpIC0gUikgKiBGQUNUT1IpID4+IDg7CisgICAgICAgICAgICAgICAgRyArPSAoKChMICAgKSAtIEcpICogRkFDVE9SKSA+PiA4OworICAgICAgICAgICAgICAgIEIgKz0gKCgoTD4+MSkgLSBCKSAqIEZBQ1RPUikgPj4gODsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFIgKz0gKGRpdGhlciA8PCBzaGlmdCkgPj4gQkxVUl9ESVRIRVJfQklUUzsKKyAgICAgICAgICAgIEcgKz0gKGRpdGhlciA8PCBzaGlmdCkgPj4gQkxVUl9ESVRIRVJfQklUUzsKKyAgICAgICAgICAgIEIgKz0gKGRpdGhlciA8PCBzaGlmdCkgPj4gQkxVUl9ESVRIRVJfQklUUzsKKyAgICAgICAgfQorICAgICAgICBSID4+PSBzaGlmdDsKKyAgICAgICAgRyA+Pj0gc2hpZnQ7CisgICAgICAgIEIgPj49IHNoaWZ0OworICAgICAgICByZXR1cm4gKFI8PDExKSB8IChHPDw1KSB8IEI7CisgICAgfSAgICAKKyAgICBpbmxpbmUgQmx1ckNvbG9yNTY1JiBvcGVyYXRvciArPSAoY29uc3QgQmx1ckNvbG9yNTY1JiByaHMpIHsKKyAgICAgICAgciArPSByaHMucjsKKyAgICAgICAgZyArPSByaHMuZzsKKyAgICAgICAgYiArPSByaHMuYjsKKyAgICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICBpbmxpbmUgQmx1ckNvbG9yNTY1JiBvcGVyYXRvciAtPSAoY29uc3QgQmx1ckNvbG9yNTY1JiByaHMpIHsKKyAgICAgICAgciAtPSByaHMucjsKKyAgICAgICAgZyAtPSByaHMuZzsKKyAgICAgICAgYiAtPSByaHMuYjsKKyAgICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KK307CisKK3N0cnVjdCBCbHVyR3JheTU2NQoreworICAgIHR5cGVkZWYgdWludDE2X3QgdHlwZTsKKyAgICBpbnQgbDsgICAgCisgICAgaW5saW5lIEJsdXJHcmF5NTY1KCkgeyB9CisgICAgaW5saW5lIEJsdXJHcmF5NTY1KHVpbnQxNl90IHYpIHsKKyAgICAgICAgaW50IHIgPSB2ID4+IDExOworICAgICAgICBpbnQgZyA9ICh2ID4+IDUpICYgMHgzRjsKKyAgICAgICAgaW50IGIgPSB2ICYgMHgxRjsKKyAgICAgICAgbCA9IChyICsgZyArIGIgKyAxKT4+MTsKKyAgICB9CisgICAgaW5saW5lIHZvaWQgY2xlYXIoKSB7IGw9MDsgfQorICAgIGlubGluZSB1aW50MTZfdCB0byhpbnQgc2hpZnQsIGludCBsYXN0LCBpbnQgZGl0aGVyKSBjb25zdCB7CisgICAgICAgIGludCBMID0gbDsKKyAgICAgICAgaWYgIChVTkxJS0VMWShsYXN0KSkgeworICAgICAgICAgICAgTCArPSAoZGl0aGVyIDw8IHNoaWZ0KSA+PiBCTFVSX0RJVEhFUl9CSVRTOworICAgICAgICB9CisgICAgICAgIEwgPj49IHNoaWZ0OworICAgICAgICByZXR1cm4gKChMPj4xKTw8MTEpIHwgKEw8PDUpIHwgKEw+PjEpOworICAgIH0KKyAgICBpbmxpbmUgQmx1ckdyYXk1NjUmIG9wZXJhdG9yICs9IChjb25zdCBCbHVyR3JheTU2NSYgcmhzKSB7CisgICAgICAgIGwgKz0gcmhzLmw7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgaW5saW5lIEJsdXJHcmF5NTY1JiBvcGVyYXRvciAtPSAoY29uc3QgQmx1ckdyYXk1NjUmIHJocykgeworICAgICAgICBsIC09IHJocy5sOworICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorfTsKKworc3RydWN0IEJsdXJHcmF5ODg4OAoreworICAgIHR5cGVkZWYgdWludDMyX3QgdHlwZTsKKyAgICBpbnQgbCwgYTsgICAgCisgICAgaW5saW5lIEJsdXJHcmF5ODg4OCgpIHsgfQorICAgIGlubGluZSBCbHVyR3JheTg4ODgodWludDMyX3QgdikgeworICAgICAgICB2ID0gQkxVUl9SR0JBX1RPX0hPU1Qodik7CisgICAgICAgIGludCByID0gdiAmIDB4RkY7CisgICAgICAgIGludCBnID0gKHYgPj4gIDgpICYgMHhGRjsKKyAgICAgICAgaW50IGIgPSAodiA+PiAxNikgJiAweEZGOworICAgICAgICBhID0gdiA+PiAyNDsKKyAgICAgICAgbCA9IHIgKyBnICsgZyArIGI7CisgICAgfSAgICAKKyAgICBpbmxpbmUgdm9pZCBjbGVhcigpIHsgbD1hPTA7IH0KKyAgICBpbmxpbmUgdWludDMyX3QgdG8oaW50IHNoaWZ0LCBpbnQgbGFzdCwgaW50IGRpdGhlcikgY29uc3QgeworICAgICAgICBpbnQgTCA9IGw7CisgICAgICAgIGludCBBID0gYTsKKyAgICAgICAgaWYgIChVTkxJS0VMWShsYXN0KSkgeworICAgICAgICAgICAgTCArPSAoZGl0aGVyIDw8IChzaGlmdCsyKSkgPj4gQkxVUl9ESVRIRVJfQklUUzsKKyAgICAgICAgICAgIEEgKz0gKGRpdGhlciA8PCBzaGlmdCkgPj4gQkxVUl9ESVRIRVJfQklUUzsKKyAgICAgICAgfQorICAgICAgICBMID4+PSAoc2hpZnQrMik7CisgICAgICAgIEEgPj49IHNoaWZ0OworICAgICAgICByZXR1cm4gQkxVUl9IT1NUX1RPX1JHQkEoKEE8PDI0KSB8IChMPDwxNikgfCAoTDw8OCkgfCBMKTsKKyAgICB9CisgICAgaW5saW5lIEJsdXJHcmF5ODg4OCYgb3BlcmF0b3IgKz0gKGNvbnN0IEJsdXJHcmF5ODg4OCYgcmhzKSB7CisgICAgICAgIGwgKz0gcmhzLmw7CisgICAgICAgIGEgKz0gcmhzLmE7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgaW5saW5lIEJsdXJHcmF5ODg4OCYgb3BlcmF0b3IgLT0gKGNvbnN0IEJsdXJHcmF5ODg4OCYgcmhzKSB7CisgICAgICAgIGwgLT0gcmhzLmw7CisgICAgICAgIGEgLT0gcmhzLmE7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9Cit9OworCisKK3RlbXBsYXRlPHR5cGVuYW1lIFBJWEVMPgorc3RhdGljIHN0YXR1c190IGJsdXJGaWx0ZXIoCisgICAgICAgIEdHTFN1cmZhY2UgY29uc3QqIGRzdCwKKyAgICAgICAgR0dMU3VyZmFjZSBjb25zdCogc3JjLAorICAgICAgICBpbnQga2VybmVsU2l6ZVVzZXIsCisgICAgICAgIGludCByZXBlYXQpCit7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBQSVhFTDo6dHlwZSBUWVBFOworCisgICAgY29uc3QgaW50IHNoaWZ0ICAgICAgICAgICAgID0gMzEgLSBjbHooa2VybmVsU2l6ZVVzZXIpOworICAgIGNvbnN0IGludCBhcmVhU2hpZnQgICAgICAgICA9IHNoaWZ0KjI7CisgICAgY29uc3QgaW50IGtlcm5lbFNpemUgICAgICAgID0gMTw8c2hpZnQ7CisgICAgY29uc3QgaW50IGtlcm5lbEhhbGZTaXplICAgID0ga2VybmVsU2l6ZS8yOworICAgIGNvbnN0IGludCBtYXNrICAgICAgICAgICAgICA9IGtlcm5lbFNpemUtMTsKKyAgICBjb25zdCBpbnQgdyAgICAgICAgICAgICAgICAgPSBzcmMtPndpZHRoOworICAgIGNvbnN0IGludCBoICAgICAgICAgICAgICAgICA9IHNyYy0+aGVpZ2h0OworICAgIGNvbnN0IHVpbnQ4X3QqIGRpdGhlck1hdHJpeCA9IGdEaXRoZXJNYXRyaXg7CisKKyAgICAvLyB3ZSBuZWVkIGEgdGVtcG9yYXJ5IGJ1ZmZlciB0byBzdG9yZSBvbmUgbGluZSBvZiBibHVycmVkIGNvbHVtbnMKKyAgICAvLyBhcyB3ZWxsIGFzIGtlcm5lbFNpemUgbGluZXMgb2Ygc291cmNlIHBpeGVscyBvcmdhbml6ZWQgYXMgYSByaW5nIGJ1ZmZlci4KKyAgICB2b2lkKiBjb25zdCB0ZW1wb3JhcnlfYnVmZmVyID0gbWFsbG9jKAorICAgICAgICAgICAgKHcgKyBrZXJuZWxTaXplKSAqIHNpemVvZihQSVhFTCkgKworICAgICAgICAgICAgKHNyYy0+c3RyaWRlICoga2VybmVsU2l6ZSkgKiBzaXplb2YoVFlQRSkpOworICAgIGlmICghdGVtcG9yYXJ5X2J1ZmZlcikKKyAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKworICAgIFBJWEVMKiBjb25zdCBzdW1zID0gKFBJWEVMKil0ZW1wb3JhcnlfYnVmZmVyOworICAgIFRZUEUqIGNvbnN0IHNjcmF0Y2ggPSAoVFlQRSopKHN1bXMgKyB3ICsga2VybmVsU2l6ZSk7CisKKyAgICAvLyBBcHBseSB0aGUgYmx1ciAncmVwZWF0JyB0aW1lcywgdGhpcyBpcyB1c2VkIHRvIGFwcHJveGltYXRlCisgICAgLy8gZ2F1c3NpYW4gYmx1cnMuIDMgdGltZXMgZ2l2ZXMgZ29vZCByZXN1bHRzLgorICAgIGZvciAoaW50IGs9MCA7IGs8cmVwZWF0IDsgaysrKSB7CisKKyAgICAgICAgLy8gQ2xlYXIgdGhlIGNvbHVtbnMgc3VtcyBmb3IgdGhpcyByb3VuZAorICAgICAgICBtZW1zZXQoc3VtcywgMCwgKHcgKyBrZXJuZWxTaXplKSAqIHNpemVvZihQSVhFTCkpOworICAgICAgICBUWVBFKiBoZWFkOworICAgICAgICBUWVBFIHBpeGVsOworICAgICAgICBQSVhFTCBjdXJyZW50OworCisgICAgICAgIC8vIFNpbmNlIHdlJ3JlIGdvaW5nIHRvIG92ZXJyaWRlIHRoZSBzb3VyY2UgZGF0YSB3ZSBuZWVkCisgICAgICAgIC8vIHRvIGNvcHkgaXQgaW4gYSB0ZW1wb3JhcnkgYnVmZmVyLiBPbmx5IGtlcm5lbFNpemUgbGluZXMgYXJlCisgICAgICAgIC8vIHJlcXVpcmVkLiBCdXQgc2luY2Ugd2Ugc3RhcnQgaW4gdGhlIGNlbnRlciBvZiB0aGUga2VybmVsLAorICAgICAgICAvLyB3ZSBvbmx5IGNvcHkgaGFsZiBvZiB0aGUgZGF0YSwgYW5kIGZpbGwgdGhlIHJlc3Qgd2l0aCB6ZXJvcworICAgICAgICAvLyAoYXNzdW1pbmcgYmxhY2svdHJhbnNwYXJlbnQgcGl4ZWxzKS4KKyAgICAgICAgbWVtY3B5KCBzY3JhdGNoICsgc3JjLT5zdHJpZGUqa2VybmVsSGFsZlNpemUsCisgICAgICAgICAgICAgICAgc3JjLT5kYXRhLAorICAgICAgICAgICAgICAgIHNyYy0+c3RyaWRlKmtlcm5lbEhhbGZTaXplKnNpemVvZihUWVBFKSk7CisKKyAgICAgICAgLy8gc3VtIGhhbGYgb2YgZWFjaCBjb2x1bW4sIGJlY2F1c2Ugd2UgYXNzdW1lIHRoZSBmaXJzdCBoYWxmIGlzCisgICAgICAgIC8vIHplcm9zIChibGFjay90cmFuc3BhcmVudCkuCisgICAgICAgIGZvciAoaW50IHk9MCA7IHk8a2VybmVsSGFsZlNpemUgOyB5KyspIHsKKyAgICAgICAgICAgIGhlYWQgPSAoVFlQRSopc3JjLT5kYXRhICsgeSpzcmMtPnN0cmlkZTsKKyAgICAgICAgICAgIGZvciAoaW50IHg9MCA7IHg8dyA7IHgrKykKKyAgICAgICAgICAgICAgICBzdW1zW3hdICs9IFBJWEVMKCAqaGVhZCsrICk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCB5PTAgOyB5PGggOyB5KyspIHsKKyAgICAgICAgICAgIFRZUEUqIGZiID0gKFRZUEUqKWRzdC0+ZGF0YSArIHkqZHN0LT5zdHJpZGU7CisKKyAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIGRpdGhlciBtYXRyaXggbGluZQorICAgICAgICAgICAgdWludDhfdCBjb25zdCAqIGRpdGhlclkgPSBkaXRoZXJNYXRyaXgKKyAgICAgICAgICAgICAgICAgICAgKyAoeSAmIEJMVVJfRElUSEVSX01BU0spKkJMVVJfRElUSEVSX09SREVSOworCisgICAgICAgICAgICAvLyBIb3Jpem9udGFsIGJsdXIgcGFzcyBvbiB0aGUgY29sdW1ucyBzdW1zCisgICAgICAgICAgICBpbnQgY291bnQsIGRpdGhlciwgeD0wOworICAgICAgICAgICAgUElYRUwgY29uc3QgKiBvdXQ9IHN1bXM7CisgICAgICAgICAgICBQSVhFTCBjb25zdCAqIGluID0gc3VtczsKKyAgICAgICAgICAgIGN1cnJlbnQuY2xlYXIoKTsKKworICAgICAgICAgICAgY291bnQgPSBrZXJuZWxIYWxmU2l6ZTsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50ICs9ICppbjsKKyAgICAgICAgICAgICAgICBpbisrOworICAgICAgICAgICAgfSB3aGlsZSAoLS1jb3VudCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGNvdW50ID0ga2VybmVsSGFsZlNpemU7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgY3VycmVudCArPSAqaW47CisgICAgICAgICAgICAgICAgZGl0aGVyID0gKihkaXRoZXJZICsgKCh4KyspJkJMVVJfRElUSEVSX01BU0spKTsKKyAgICAgICAgICAgICAgICAqZmIrKyA9IGN1cnJlbnQudG8oYXJlYVNoaWZ0LCBrPT1yZXBlYXQtMSwgZGl0aGVyKTsKKyAgICAgICAgICAgICAgICBpbisrOworICAgICAgICAgICAgfSB3aGlsZSAoLS1jb3VudCk7CisKKyAgICAgICAgICAgIGNvdW50ID0gdy1rZXJuZWxTaXplOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGN1cnJlbnQgKz0gKmluOworICAgICAgICAgICAgICAgIGN1cnJlbnQgLT0gKm91dDsKKyAgICAgICAgICAgICAgICBkaXRoZXIgPSAqKGRpdGhlclkgKyAoKHgrKykmQkxVUl9ESVRIRVJfTUFTSykpOworICAgICAgICAgICAgICAgICpmYisrID0gY3VycmVudC50byhhcmVhU2hpZnQsIGs9PXJlcGVhdC0xLCBkaXRoZXIpOworICAgICAgICAgICAgICAgIGluKyssIG91dCsrOworICAgICAgICAgICAgfSB3aGlsZSAoLS1jb3VudCk7CisKKyAgICAgICAgICAgIGNvdW50ID0ga2VybmVsSGFsZlNpemU7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgY3VycmVudCAtPSAqb3V0OworICAgICAgICAgICAgICAgIGRpdGhlciA9ICooZGl0aGVyWSArICgoeCsrKSZCTFVSX0RJVEhFUl9NQVNLKSk7CisgICAgICAgICAgICAgICAgKmZiKysgPSBjdXJyZW50LnRvKGFyZWFTaGlmdCwgaz09cmVwZWF0LTEsIGRpdGhlcik7CisgICAgICAgICAgICAgICAgb3V0Kys7CisgICAgICAgICAgICB9IHdoaWxlICgtLWNvdW50KTsKKworICAgICAgICAgICAgLy8gdmVydGljYWwgYmx1ciBwYXNzLCBzdWJ0cmFjdCB0aGUgb2xkZXN0IGxpbmUgZnJvbSBlYWNoIGNvbHVtbnMKKyAgICAgICAgICAgIC8vIGFuZCBhZGQgYSBuZXcgbGluZS4gU3VidHJhY3Qgb3IgYWRkIHplcm9zIGF0IHRoZSB0b3AKKyAgICAgICAgICAgIC8vIGFuZCBib3R0b20gZWRnZXMuCisgICAgICAgICAgICBUWVBFKiBjb25zdCB0YWlsID0gc2NyYXRjaCArICh5ICYgbWFzaykgKiBzcmMtPnN0cmlkZTsKKyAgICAgICAgICAgIGlmICh5ID49IGtlcm5lbEhhbGZTaXplKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeD0wIDsgeDx3IDsgeCsrKQorICAgICAgICAgICAgICAgICAgICBzdW1zW3hdIC09IFBJWEVMKCB0YWlsW3hdICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoeSA8IGgta2VybmVsU2l6ZSkgeworICAgICAgICAgICAgICAgIG1lbWNweSggdGFpbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChUWVBFKilzcmMtPmRhdGEgKyAoeStrZXJuZWxIYWxmU2l6ZSkqc3JjLT5zdHJpZGUsCisgICAgICAgICAgICAgICAgICAgICAgICBzcmMtPnN0cmlkZSpzaXplb2YoVFlQRSkpOworICAgICAgICAgICAgICAgIGZvciAoaW50IHg9MCA7IHg8dyA7IHgrKykKKyAgICAgICAgICAgICAgICAgICAgc3Vtc1t4XSArPSBQSVhFTCggdGFpbFt4XSApOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlIHN1YnNlcXVlbnQgcGFzc2VzIGFyZSBhbHdheXMgZG9uZSBpbi1wbGFjZS4KKyAgICAgICAgc3JjID0gZHN0OworICAgIH0KKyAgICAKKyAgICBmcmVlKHRlbXBvcmFyeV9idWZmZXIpOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit0ZW1wbGF0ZSBzdGF0dXNfdCBibHVyRmlsdGVyPCBCbHVyQ29sb3I1NjU8MHg4MD4gPigKKyAgICAgICAgR0dMU3VyZmFjZSBjb25zdCogZHN0LAorICAgICAgICBHR0xTdXJmYWNlIGNvbnN0KiBzcmMsCisgICAgICAgIGludCBrZXJuZWxTaXplVXNlciwKKyAgICAgICAgaW50IHJlcGVhdCk7CisKK3N0YXR1c190IGJsdXJGaWx0ZXIoCisgICAgICAgIEdHTFN1cmZhY2UgY29uc3QqIGltYWdlLAorICAgICAgICBpbnQga2VybmVsU2l6ZVVzZXIsCisgICAgICAgIGludCByZXBlYXQpCit7CisgICAgcmV0dXJuIGJsdXJGaWx0ZXI8IEJsdXJDb2xvcjU2NTwweDgwPiA+KGltYWdlLCBpbWFnZSwga2VybmVsU2l6ZVVzZXIsIHJlcGVhdCk7Cit9CisKK30gLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworLy9lcnIgPSBibHVyPCBCbHVyQ29sb3I1NjU8MHg4MD4gPihkc3QsIHNyYywga2VybmVsU2l6ZVVzZXIsIHJlcGVhdCk7CisvL2VyciA9IGJsdXI8Qmx1ckdyYXk1NjU+KGRzdCwgc3JjLCBrZXJuZWxTaXplVXNlciwgcmVwZWF0KTsKKy8vZXJyID0gYmx1cjxCbHVyR3JheTg4ODg+KGRzdCwgc3JjLCBrZXJuZWxTaXplVXNlciwgcmVwZWF0KTsKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvQmx1ckZpbHRlci5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9CbHVyRmlsdGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk0ZGI0MwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQmx1ckZpbHRlci5oCkBAIC0wLDAgKzEsMzUgQEAKKy8qIAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9CTFVSX0ZJTFRFUl9ICisjZGVmaW5lIEFORFJPSURfQkxVUl9GSUxURVJfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisKKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RhdHVzX3QgYmx1ckZpbHRlcigKKyAgICAgICAgR0dMU3VyZmFjZSBjb25zdCogaW1hZ2UsCisgICAgICAgIGludCBrZXJuZWxTaXplVXNlciwKKyAgICAgICAgaW50IHJlcGVhdCk7CisKK30gLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfQkxVUl9GSUxURVJfSApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9Cb290QW5pbWF0aW9uLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQm9vdEFuaW1hdGlvbi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmIzMDMzNgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQm9vdEFuaW1hdGlvbi5jcHAKQEAgLTAsMCArMSw0MDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkJvb3RBbmltYXRpb24iCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDx1dGlscy9taXNjLmg+CisKKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvQXNzZXRNYW5hZ2VyLmg+CisKKyNpbmNsdWRlIDx1aS9QaXhlbEZvcm1hdC5oPgorI2luY2x1ZGUgPHVpL1JlY3QuaD4KKyNpbmNsdWRlIDx1aS9SZWdpb24uaD4KKyNpbmNsdWRlIDx1aS9EaXNwbGF5SW5mby5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlQ29tcG9zZXIuaD4KKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUZsaW5nZXJDbGllbnQuaD4KKyNpbmNsdWRlIDx1aS9FR0xOYXRpdmVXaW5kb3dTdXJmYWNlLmg+CisKKyNpbmNsdWRlIDxjb3JlL1NrQml0bWFwLmg+CisjaW5jbHVkZSA8aW1hZ2VzL1NrSW1hZ2VEZWNvZGVyLmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8R0xFUy9nbGV4dC5oPgorI2luY2x1ZGUgPEVHTC9lZ2xleHQuaD4KKworI2luY2x1ZGUgIkJvb3RBbmltYXRpb24uaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQm9vdEFuaW1hdGlvbjo6Qm9vdEFuaW1hdGlvbihjb25zdCBzcDxJU3VyZmFjZUNvbXBvc2VyPiYgY29tcG9zZXIpIDoKKyAgICBUaHJlYWQoZmFsc2UpIHsKKyAgICBtU2Vzc2lvbiA9IFN1cmZhY2VDb21wb3NlckNsaWVudDo6Y2xpZW50Rm9yQ29ubmVjdGlvbigKKyAgICAgICAgICAgIGNvbXBvc2VyLT5jcmVhdGVDb25uZWN0aW9uKCktPmFzQmluZGVyKCkpOworfQorCitCb290QW5pbWF0aW9uOjp+Qm9vdEFuaW1hdGlvbigpIHsKK30KKwordm9pZCBCb290QW5pbWF0aW9uOjpvbkZpcnN0UmVmKCkgeworICAgIHJ1bigiQm9vdEFuaW1hdGlvbiIsIFBSSU9SSVRZX0RJU1BMQVkpOworfQorCitjb25zdCBzcDxTdXJmYWNlQ29tcG9zZXJDbGllbnQ+JiBCb290QW5pbWF0aW9uOjpzZXNzaW9uKCkgY29uc3QgeworICAgIHJldHVybiBtU2Vzc2lvbjsKK30KKworc3RhdHVzX3QgQm9vdEFuaW1hdGlvbjo6aW5pdFRleHR1cmUoVGV4dHVyZSogdGV4dHVyZSwgQXNzZXRNYW5hZ2VyJiBhc3NldHMsCisgICAgICAgIGNvbnN0IGNoYXIqIG5hbWUpIHsKKyAgICBBc3NldCogYXNzZXQgPSBhc3NldHMub3BlbihuYW1lLCBBc3NldDo6QUNDRVNTX0JVRkZFUik7CisgICAgaWYgKCFhc3NldCkKKyAgICAgICAgcmV0dXJuIE5PX0lOSVQ7CisgICAgU2tCaXRtYXAgYml0bWFwOworICAgIFNrSW1hZ2VEZWNvZGVyOjpEZWNvZGVNZW1vcnkoYXNzZXQtPmdldEJ1ZmZlcihmYWxzZSksIGFzc2V0LT5nZXRMZW5ndGgoKSwKKyAgICAgICAgICAgICZiaXRtYXAsIFNrQml0bWFwOjprTm9fQ29uZmlnLCBTa0ltYWdlRGVjb2Rlcjo6a0RlY29kZVBpeGVsc19Nb2RlKTsKKyAgICBhc3NldC0+Y2xvc2UoKTsKKyAgICBkZWxldGUgYXNzZXQ7CisKKyAgICAvLyBlbnN1cmUgd2UgY2FuIGNhbGwgZ2V0UGl4ZWxzKCkuIE5vIG5lZWQgdG8gY2FsbCB1bmxvY2ssIHNpbmNlIHRoZQorICAgIC8vIGJpdG1hcCB3aWxsIGdvIG91dCBvZiBzY29wZSB3aGVuIHdlIHJldHVybiBmcm9tIHRoaXMgbWV0aG9kLgorICAgIGJpdG1hcC5sb2NrUGl4ZWxzKCk7CisKKyAgICBjb25zdCBpbnQgdyA9IGJpdG1hcC53aWR0aCgpOworICAgIGNvbnN0IGludCBoID0gYml0bWFwLmhlaWdodCgpOworICAgIGNvbnN0IHZvaWQqIHAgPSBiaXRtYXAuZ2V0UGl4ZWxzKCk7CisKKyAgICBHTGludCBjcm9wWzRdID0geyAwLCBoLCB3LCAtaCB9OworICAgIHRleHR1cmUtPncgPSB3OworICAgIHRleHR1cmUtPmggPSBoOworCisgICAgZ2xHZW5UZXh0dXJlcygxLCAmdGV4dHVyZS0+bmFtZSk7CisgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXh0dXJlLT5uYW1lKTsKKworICAgIHN3aXRjaCAoYml0bWFwLmdldENvbmZpZygpKSB7CisgICAgICAgIGNhc2UgU2tCaXRtYXA6OmtBOF9Db25maWc6CisgICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfQUxQSEEsIHcsIGgsIDAsIEdMX0FMUEhBLAorICAgICAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9CWVRFLCBwKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNrQml0bWFwOjprQVJHQl80NDQ0X0NvbmZpZzoKKyAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCB3LCBoLCAwLCBHTF9SR0JBLAorICAgICAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80LCBwKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNrQml0bWFwOjprQVJHQl84ODg4X0NvbmZpZzoKKyAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCB3LCBoLCAwLCBHTF9SR0JBLAorICAgICAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9CWVRFLCBwKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNrQml0bWFwOjprUkdCXzU2NV9Db25maWc6CisgICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCLCB3LCBoLCAwLCBHTF9SR0IsCisgICAgICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81LCBwKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgZ2xUZXhQYXJhbWV0ZXJpdihHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIGNyb3ApOworICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOworICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOworICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfUkVQRUFUKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX1JFUEVBVCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBCb290QW5pbWF0aW9uOjpyZWFkeVRvUnVuKCkgeworICAgIG1Bc3NldHMuYWRkRGVmYXVsdEFzc2V0cygpOworCisgICAgRGlzcGxheUluZm8gZGluZm87CisgICAgc3RhdHVzX3Qgc3RhdHVzID0gc2Vzc2lvbigpLT5nZXREaXNwbGF5SW5mbygwLCAmZGluZm8pOworICAgIGlmIChzdGF0dXMpCisgICAgICAgIHJldHVybiAtMTsKKworICAgIC8vIGNyZWF0ZSB0aGUgbmF0aXZlIHN1cmZhY2UKKyAgICBzcDxTdXJmYWNlPiBzID0gc2Vzc2lvbigpLT5jcmVhdGVTdXJmYWNlKGdldHBpZCgpLCAwLCBkaW5mby53LCBkaW5mby5oLAorICAgICAgICAgICAgUElYRUxfRk9STUFUX1JHQl81NjUpOworICAgIHNlc3Npb24oKS0+b3BlblRyYW5zYWN0aW9uKCk7CisgICAgcy0+c2V0TGF5ZXIoMHg0MDAwMDAwMCk7CisgICAgc2Vzc2lvbigpLT5jbG9zZVRyYW5zYWN0aW9uKCk7CisKKyAgICAvLyBpbml0aWFsaXplIG9wZW5nbCBhbmQgZWdsCisgICAgY29uc3QgRUdMaW50IGF0dHJpYnNbXSA9IHsgRUdMX1JFRF9TSVpFLCA1LCBFR0xfR1JFRU5fU0laRSwgNiwKKyAgICAgICAgICAgIEVHTF9CTFVFX1NJWkUsIDUsIEVHTF9ERVBUSF9TSVpFLCAwLCBFR0xfTk9ORSB9OworICAgIEVHTGludCB3LCBoLCBkdW1teTsKKyAgICBFR0xpbnQgbnVtQ29uZmlnczsKKyAgICBFR0xDb25maWcgY29uZmlnOworICAgIEVHTFN1cmZhY2Ugc3VyZmFjZTsKKyAgICBFR0xDb250ZXh0IGNvbnRleHQ7CisgICAgRUdMRGlzcGxheSBkaXNwbGF5ID0gZWdsR2V0RGlzcGxheShFR0xfREVGQVVMVF9ESVNQTEFZKTsKKyAgICBlZ2xDaG9vc2VDb25maWcoZGlzcGxheSwgYXR0cmlicywgJmNvbmZpZywgMSwgJm51bUNvbmZpZ3MpOworCisgICAgbU5hdGl2ZVdpbmRvd1N1cmZhY2UgPSBuZXcgRUdMTmF0aXZlV2luZG93U3VyZmFjZShzKTsKKyAgICBzdXJmYWNlID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShkaXNwbGF5LCBjb25maWcsIAorICAgICAgICAgICAgbU5hdGl2ZVdpbmRvd1N1cmZhY2UuZ2V0KCksIE5VTEwpOworCisgICAgY29udGV4dCA9IGVnbENyZWF0ZUNvbnRleHQoZGlzcGxheSwgY29uZmlnLCBOVUxMLCBOVUxMKTsKKyAgICBlZ2xRdWVyeVN1cmZhY2UoZGlzcGxheSwgc3VyZmFjZSwgRUdMX1dJRFRILCAmdyk7CisgICAgZWdsUXVlcnlTdXJmYWNlKGRpc3BsYXksIHN1cmZhY2UsIEVHTF9IRUlHSFQsICZoKTsKKyAgICBlZ2xNYWtlQ3VycmVudChkaXNwbGF5LCBzdXJmYWNlLCBzdXJmYWNlLCBjb250ZXh0KTsKKyAgICBtRGlzcGxheSA9IGRpc3BsYXk7CisgICAgbUNvbnRleHQgPSBjb250ZXh0OworICAgIG1TdXJmYWNlID0gc3VyZmFjZTsKKyAgICBtV2lkdGggPSB3OworICAgIG1IZWlnaHQgPSBoOworICAgIG1GbGluZ2VyU3VyZmFjZSA9IHM7CisKKyAgICAvLyBpbml0aWFsaXplIEdMCisgICAgZ2xTaGFkZU1vZGVsKEdMX0ZMQVQpOworICAgIGdsRW5hYmxlKEdMX0RJVEhFUik7CisgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CisgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKKyAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIEJvb3RBbmltYXRpb246OnJlcXVlc3RFeGl0KCkgeworICAgIG1CYXJyaWVyLm9wZW4oKTsKKyAgICBUaHJlYWQ6OnJlcXVlc3RFeGl0KCk7Cit9CisKK2Jvb2wgQm9vdEFuaW1hdGlvbjo6dGhyZWFkTG9vcCgpIHsKKyAgICBib29sIHIgPSBhbmRyb2lkKCk7CisgICAgZWdsTWFrZUN1cnJlbnQobURpc3BsYXksIEVHTF9OT19TVVJGQUNFLCBFR0xfTk9fU1VSRkFDRSwgRUdMX05PX0NPTlRFWFQpOworICAgIGVnbERlc3Ryb3lDb250ZXh0KG1EaXNwbGF5LCBtQ29udGV4dCk7CisgICAgZWdsRGVzdHJveVN1cmZhY2UobURpc3BsYXksIG1TdXJmYWNlKTsKKyAgICBtTmF0aXZlV2luZG93U3VyZmFjZS5jbGVhcigpOworICAgIHJldHVybiByOworfQorCitib29sIEJvb3RBbmltYXRpb246OmFuZHJvaWQoKSB7CisgICAgaW5pdFRleHR1cmUoJm1BbmRyb2lkWzBdLCBtQXNzZXRzLCAiaW1hZ2VzL2FuZHJvaWRfMzIweDQ4MC5wbmciKTsKKyAgICBpbml0VGV4dHVyZSgmbUFuZHJvaWRbMV0sIG1Bc3NldHMsICJpbWFnZXMvYm9vdF9yb2JvdC5wbmciKTsKKyAgICBpbml0VGV4dHVyZSgmbUFuZHJvaWRbMl0sIG1Bc3NldHMsICJpbWFnZXMvYm9vdF9yb2JvdF9nbG93LnBuZyIpOworCisgICAgLy8gZXJhc2Ugc2NyZWVuCisgICAgZ2xEaXNhYmxlKEdMX1NDSVNTT1JfVEVTVCk7CisgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtQW5kcm9pZFswXS5uYW1lKTsKKworICAgIC8vIGNsZWFyIHNjcmVlbgorICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisgICAgZWdsU3dhcEJ1ZmZlcnMobURpc3BsYXksIG1TdXJmYWNlKTsKKworICAgIC8vIHdhaXQgfjFzCisgICAgdXNsZWVwKDgwMDAwMCk7CisKKyAgICAvLyBmYWRlIGluCisgICAgZ2xFbmFibGUoR0xfQkxFTkQpOworICAgIGdsQmxlbmRGdW5jKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CisgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9NT0RVTEFURSk7CisgICAgY29uc3QgaW50IHN0ZXBzID0gODsKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IHN0ZXBzOyBpKyspIHsKKyAgICAgICAgZmxvYXQgZmFkZSA9IGkgLyBmbG9hdChzdGVwcyk7CisgICAgICAgIGdsQ29sb3I0ZigxLCAxLCAxLCBmYWRlICogZmFkZSk7CisgICAgICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisgICAgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgbUFuZHJvaWRbMF0udywgbUFuZHJvaWRbMF0uaCk7CisgICAgICAgIGVnbFN3YXBCdWZmZXJzKG1EaXNwbGF5LCBtU3VyZmFjZSk7CisgICAgfQorCisgICAgLy8gZHJhdyBsYXN0IGZyYW1lCisgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKKyAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgbUFuZHJvaWRbMF0udywgbUFuZHJvaWRbMF0uaCk7CisgICAgZWdsU3dhcEJ1ZmZlcnMobURpc3BsYXksIG1TdXJmYWNlKTsKKworICAgIC8vIHVwZGF0ZSByZWN0IGZvciB0aGUgcm9ib3QKKyAgICBjb25zdCBpbnQgeCA9IG1XaWR0aCAtIG1BbmRyb2lkWzFdLncgLSAzMzsKKyAgICBjb25zdCBpbnQgeSA9IChtSGVpZ2h0IC0gbUFuZHJvaWRbMV0uaCkgLyAyIC0gMTsKKyAgICBjb25zdCBSZWN0IHVwZGF0ZVJlY3QoeCwgeSwgeCArIG1BbmRyb2lkWzFdLncsIHkgKyBtQW5kcm9pZFsxXS5oKTsKKworICAgIC8vIGRyYXcgYW5kIHVwZGF0ZSBvbmx5IHdoYXQgd2UgbmVlZAorICAgIG1OYXRpdmVXaW5kb3dTdXJmYWNlLT5zZXRTd2FwUmVjdGFuZ2xlKHVwZGF0ZVJlY3QubGVmdCwKKyAgICAgICAgICAgIHVwZGF0ZVJlY3QudG9wLCB1cGRhdGVSZWN0LndpZHRoKCksIHVwZGF0ZVJlY3QuaGVpZ2h0KCkpOworCisgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKKyAgICBnbFNjaXNzb3IodXBkYXRlUmVjdC5sZWZ0LCBtSGVpZ2h0IC0gdXBkYXRlUmVjdC5ib3R0b20sIHVwZGF0ZVJlY3Qud2lkdGgoKSwKKyAgICAgICAgICAgIHVwZGF0ZVJlY3QuaGVpZ2h0KCkpOworCisgICAgY29uc3QgbnNlY3NfdCBzdGFydFRpbWUgPSBzeXN0ZW1UaW1lKCk7CisgICAgZG8geworICAgICAgICAvLyBnbG93IHNwZWVkIGFuZCBzaGFwZQorICAgICAgICBuc2Vjc190IHRpbWUgPSBzeXN0ZW1UaW1lKCkgLSBzdGFydFRpbWU7CisgICAgICAgIGZsb2F0IHQgPSAoKDQuMGYgLyAoMzYwLjBmICogdXMybnMoMTY2NjcpKSkgKiB0aW1lKTsKKyAgICAgICAgdCA9IHQgLSBmbG9vcmYodCk7CisgICAgICAgIGNvbnN0IGZsb2F0IGZhZGUgPSAwLjVmICsgMC41ZiAqIHNpbmYodCAqIDIgKiBNX1BJKTsKKworICAgICAgICAvLyBmYWRlIHRoZSBnbG93IGluIGFuZCBvdXQKKyAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtQW5kcm9pZFsyXS5uYW1lKTsKKyAgICAgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9NT0RVTEFURSk7CisgICAgICAgIGdsQ29sb3I0ZihmYWRlLCBmYWRlLCBmYWRlLCBmYWRlKTsKKyAgICAgICAgZ2xEcmF3VGV4aU9FUyh1cGRhdGVSZWN0LmxlZnQsIG1IZWlnaHQgLSB1cGRhdGVSZWN0LmJvdHRvbSwgMCwKKyAgICAgICAgICAgICAgICB1cGRhdGVSZWN0LndpZHRoKCksIHVwZGF0ZVJlY3QuaGVpZ2h0KCkpOworCisgICAgICAgIC8vIGRyYXcgdGhlIHJvYm90CisgICAgICAgIGdsRW5hYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtQW5kcm9pZFsxXS5uYW1lKTsKKyAgICAgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKKyAgICAgICAgZ2xEcmF3VGV4aU9FUyh1cGRhdGVSZWN0LmxlZnQsIG1IZWlnaHQgLSB1cGRhdGVSZWN0LmJvdHRvbSwgMCwKKyAgICAgICAgICAgICAgICB1cGRhdGVSZWN0LndpZHRoKCksIHVwZGF0ZVJlY3QuaGVpZ2h0KCkpOworCisgICAgICAgIC8vIG1ha2Ugc3VyZSBzbGVlcCBhIGxvdCB0byBub3QgdGFrZSB0b28gbXVjaCBDUFUgYXdheSBmcm9tIAorICAgICAgICAvLyB0aGUgYm9vdCBwcm9jZXNzLiBXaXRoIHRoaXMgImdsb3ciIGFuaW1hdGlvbiB0aGVyZSBpcyBubworICAgICAgICAvLyB2aXNpYmxlIGRpZmZlcmVuY2UuIAorICAgICAgICB1c2xlZXAoMTY2NjcgKiA0KTsKKworICAgICAgICBlZ2xTd2FwQnVmZmVycyhtRGlzcGxheSwgbVN1cmZhY2UpOworICAgIH0gd2hpbGUgKCFleGl0UGVuZGluZygpKTsKKworICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJm1BbmRyb2lkWzBdLm5hbWUpOworICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJm1BbmRyb2lkWzFdLm5hbWUpOworICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJm1BbmRyb2lkWzJdLm5hbWUpOworICAgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBCb290QW5pbWF0aW9uOjpjeWxvbigpIHsKKyAgICAvLyBpbml0aWFsaXplIHRoZSB0ZXh0dXJlcy4uLgorICAgIGluaXRUZXh0dXJlKCZtTGVmdFRyYWlsLCBtQXNzZXRzLCAiaW1hZ2VzL2N5bG9uX2xlZnQucG5nIik7CisgICAgaW5pdFRleHR1cmUoJm1SaWdodFRyYWlsLCBtQXNzZXRzLCAiaW1hZ2VzL2N5bG9uX3JpZ2h0LnBuZyIpOworICAgIGluaXRUZXh0dXJlKCZtQnJpZ2h0U3BvdCwgbUFzc2V0cywgImltYWdlcy9jeWxvbl9kb3QucG5nIik7CisKKyAgICBpbnQgdyA9IG1XaWR0aDsKKyAgICBpbnQgaCA9IG1IZWlnaHQ7CisKKyAgICBjb25zdCBQb2ludCBjKHcgLyAyLCBoIC8gMik7CisgICAgY29uc3QgR0xpbnQgYW1wbGl0dWRlID0gNjA7CisgICAgY29uc3QgaW50IHNjeCA9IGMueCAtIGFtcGxpdHVkZSAtIG1CcmlnaHRTcG90LncgLyAyOworICAgIGNvbnN0IGludCBzY3kgPSBjLnkgLSBtQnJpZ2h0U3BvdC5oIC8gMjsKKyAgICBjb25zdCBpbnQgc2N3ID0gYW1wbGl0dWRlICogMiArIG1CcmlnaHRTcG90Lnc7CisgICAgY29uc3QgaW50IHNjaCA9IG1CcmlnaHRTcG90Lmg7CisgICAgY29uc3QgUmVjdCB1cGRhdGVSZWN0KHNjeCwgaCAtIHNjeSAtIHNjaCwgc2N4ICsgc2N3LCBoIC0gc2N5KTsKKworICAgIC8vIGVyYXNlIHNjcmVlbgorICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOworICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisKKyAgICBlZ2xTd2FwQnVmZmVycyhtRGlzcGxheSwgbVN1cmZhY2UpOworCisgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKworICAgIG1OYXRpdmVXaW5kb3dTdXJmYWNlLT5zZXRTd2FwUmVjdGFuZ2xlKHVwZGF0ZVJlY3QubGVmdCwKKyAgICAgICAgICAgIHVwZGF0ZVJlY3QudG9wLCB1cGRhdGVSZWN0LndpZHRoKCksIHVwZGF0ZVJlY3QuaGVpZ2h0KCkpOworCisgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKKyAgICBnbEVuYWJsZShHTF9CTEVORCk7CisgICAgZ2xCbGVuZEZ1bmMoR0xfT05FLCBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBKTsKKworICAgIC8vIGNsZWFyIHRoZSBzY3JlZW4gdG8gd2hpdGUKKyAgICBQb2ludCBwOworICAgIGZsb2F0IHQgPSAwOworICAgIGZsb2F0IGFscGhhID0gMS4wZjsKKyAgICBjb25zdCBuc2Vjc190IHN0YXJ0VGltZSA9IHN5c3RlbVRpbWUoKTsKKyAgICBuc2Vjc190IGZhZGVUaW1lID0gMDsKKworICAgIGRvIHsKKyAgICAgICAgLy8gU2V0IHNjaXNzb3IgaW4gaW50ZXJlc3RpbmcgYXJlYQorICAgICAgICBnbFNjaXNzb3Ioc2N4LCBzY3ksIHNjdywgc2NoKTsKKworICAgICAgICAvLyBlcmFzZSBzY3JlZW4KKyAgICAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKworICAgICAgICAvLyBjb21wdXRlIHdhdmUKKyAgICAgICAgY29uc3QgZmxvYXQgYSA9ICh0ICogMiAqIE1fUEkpIC0gTV9QSSAvIDI7CisgICAgICAgIGNvbnN0IGZsb2F0IHNuID0gc2luZihhKTsKKyAgICAgICAgY29uc3QgZmxvYXQgY3MgPSBjb3NmKGEpOworICAgICAgICBHTGludCB4ID0gR0xpbnQoYW1wbGl0dWRlICogc24pOworICAgICAgICBmbG9hdCBkZXJpdmF0aXZlID0gY3M7CisKKyAgICAgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9NT0RVTEFURSk7CisKKyAgICAgICAgaWYgKGRlcml2YXRpdmUgPiAwKSB7CisgICAgICAgICAgICAvLyB2YW5pc2hpbmcgdHJhaWwuLi4KKyAgICAgICAgICAgIHAueCA9ICgtYW1wbGl0dWRlICsgYy54KSAtIG1CcmlnaHRTcG90LncgLyAyOworICAgICAgICAgICAgcC55ID0gYy55IC0gbUxlZnRUcmFpbC5oIC8gMjsKKyAgICAgICAgICAgIGZsb2F0IGZhZGUgPSAyLjBmICogKDAuNWYgLSB0KTsKKyAgICAgICAgICAgIC8vZmFkZSAqPSBmYWRlOworICAgICAgICAgICAgZ2xDb2xvcjRmKGZhZGUsIGZhZGUsIGZhZGUsIGZhZGUpOworICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtTGVmdFRyYWlsLm5hbWUpOworICAgICAgICAgICAgZ2xEcmF3VGV4aU9FUyhwLngsIHAueSwgMCwgbUxlZnRUcmFpbC53LCBtTGVmdFRyYWlsLmgpOworCisgICAgICAgICAgICAvLyB0cmFpbC4uLgorICAgICAgICAgICAgcC54ID0gKHggKyBjLngpIC0gKG1SaWdodFRyYWlsLncgKyBtQnJpZ2h0U3BvdC53IC8gMikgKyAxNjsKKyAgICAgICAgICAgIHAueSA9IGMueSAtIG1SaWdodFRyYWlsLmggLyAyOworICAgICAgICAgICAgZmFkZSA9IHQgPCAwLjI1ZiA/IHQgKiA0LjBmIDogMS4wZjsKKyAgICAgICAgICAgIGZhZGUgKj0gZmFkZTsKKyAgICAgICAgICAgIGdsQ29sb3I0ZihmYWRlLCBmYWRlLCBmYWRlLCBmYWRlKTsKKyAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgbVJpZ2h0VHJhaWwubmFtZSk7CisgICAgICAgICAgICBnbERyYXdUZXhpT0VTKHAueCwgcC55LCAwLCBtUmlnaHRUcmFpbC53LCBtUmlnaHRUcmFpbC5oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHZhbmlzaGluZyB0cmFpbC4uCisgICAgICAgICAgICBwLnggPSAoYW1wbGl0dWRlICsgYy54KSAtIChtUmlnaHRUcmFpbC53ICsgbUJyaWdodFNwb3QudyAvIDIpICsgMTY7CisgICAgICAgICAgICBwLnkgPSBjLnkgLSBtUmlnaHRUcmFpbC5oIC8gMjsKKyAgICAgICAgICAgIGZsb2F0IGZhZGUgPSAyLjBmICogKDAuNWYgLSAodCAtIDAuNWYpKTsKKyAgICAgICAgICAgIC8vZmFkZSAqPSBmYWRlOworICAgICAgICAgICAgZ2xDb2xvcjRmKGZhZGUsIGZhZGUsIGZhZGUsIGZhZGUpOworICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtUmlnaHRUcmFpbC5uYW1lKTsKKyAgICAgICAgICAgIGdsRHJhd1RleGlPRVMocC54LCBwLnksIDAsIG1SaWdodFRyYWlsLncsIG1SaWdodFRyYWlsLmgpOworCisgICAgICAgICAgICAvLyB0cmFpbC4uLgorICAgICAgICAgICAgcC54ID0gKHggKyBjLngpIC0gbUJyaWdodFNwb3QudyAvIDI7CisgICAgICAgICAgICBwLnkgPSBjLnkgLSBtTGVmdFRyYWlsLmggLyAyOworICAgICAgICAgICAgZmFkZSA9IHQgPCAwLjVmICsgMC4yNWYgPyAodCAtIDAuNWYpICogNC4wZiA6IDEuMGY7CisgICAgICAgICAgICBmYWRlICo9IGZhZGU7CisgICAgICAgICAgICBnbENvbG9yNGYoZmFkZSwgZmFkZSwgZmFkZSwgZmFkZSk7CisgICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIG1MZWZ0VHJhaWwubmFtZSk7CisgICAgICAgICAgICBnbERyYXdUZXhpT0VTKHAueCwgcC55LCAwLCBtTGVmdFRyYWlsLncsIG1MZWZ0VHJhaWwuaCk7CisgICAgICAgIH0KKworICAgICAgICBjb25zdCBQb2ludCBwKHggKyBjLnggLSBtQnJpZ2h0U3BvdC53IC8gMiwgYy55IC0gbUJyaWdodFNwb3QuaCAvIDIpOworICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIG1CcmlnaHRTcG90Lm5hbWUpOworICAgICAgICBnbENvbG9yNGYoMSwgMC41LCAwLjUsIDEpOworICAgICAgICBnbERyYXdUZXhpT0VTKHAueCwgcC55LCAwLCBtQnJpZ2h0U3BvdC53LCBtQnJpZ2h0U3BvdC5oKTsKKworICAgICAgICAvLyB1cGRhdGUgYW5pbWF0aW9uCisgICAgICAgIG5zZWNzX3QgdGltZSA9IHN5c3RlbVRpbWUoKSAtIHN0YXJ0VGltZTsKKyAgICAgICAgdCA9ICgoNC4wZiAvICgzNjAuMGYgKiB1czJucygxNjY2NykpKSAqIHRpbWUpOworICAgICAgICB0ID0gdCAtIGZsb29yZih0KTsKKworICAgICAgICBlZ2xTd2FwQnVmZmVycyhtRGlzcGxheSwgbVN1cmZhY2UpOworCisgICAgICAgIGlmIChleGl0UGVuZGluZygpKSB7CisgICAgICAgICAgICBpZiAoZmFkZVRpbWUgPT0gMCkgeworICAgICAgICAgICAgICAgIGZhZGVUaW1lID0gdGltZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRpbWUgLT0gZmFkZVRpbWU7CisgICAgICAgICAgICBhbHBoYSA9IDEuMGYgLSAoKGZsb2F0KHRpbWUpICogNi4wZikgLyBmbG9hdChzMm5zKDEpKSk7CisKKyAgICAgICAgICAgIHNlc3Npb24oKS0+b3BlblRyYW5zYWN0aW9uKCk7CisgICAgICAgICAgICBtRmxpbmdlclN1cmZhY2UtPnNldEFscGhhKGFscGhhICogYWxwaGEpOworICAgICAgICAgICAgc2Vzc2lvbigpLT5jbG9zZVRyYW5zYWN0aW9uKCk7CisgICAgICAgIH0KKyAgICB9IHdoaWxlIChhbHBoYSA+IDApOworCisgICAgLy8gY2xlYW51cAorICAgIGdsRmluaXNoKCk7CisgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmbUxlZnRUcmFpbC5uYW1lKTsKKyAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZtUmlnaHRUcmFpbC5uYW1lKTsKKyAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZtQnJpZ2h0U3BvdC5uYW1lKTsKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9Cis7IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL0Jvb3RBbmltYXRpb24uaCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQm9vdEFuaW1hdGlvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyMGNlYTAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0Jvb3RBbmltYXRpb24uaApAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0JPT1RBTklNQVRJT05fSAorI2RlZmluZSBBTkRST0lEX0JPT1RBTklNQVRJT05fSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvQXNzZXRNYW5hZ2VyLmg+CisKKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUNvbXBvc2VyLmg+CisjaW5jbHVkZSA8dWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50Lmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjaW5jbHVkZSAiQmFycmllci5oIgorCitjbGFzcyBTa0JpdG1hcDsKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBBc3NldE1hbmFnZXI7CitjbGFzcyBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgQm9vdEFuaW1hdGlvbiA6IHB1YmxpYyBUaHJlYWQKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICBCb290QW5pbWF0aW9uKGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBjb21wb3Nlcik7CisgICAgdmlydHVhbCAgICAgfkJvb3RBbmltYXRpb24oKTsKKworICAgIGNvbnN0IHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4mIHNlc3Npb24oKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgIHJlcXVlc3RFeGl0KCk7CisKK3ByaXZhdGU6CisgICAgdmlydHVhbCBib29sICAgICAgICB0aHJlYWRMb29wKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICByZWFkeVRvUnVuKCk7CisgICAgdmlydHVhbCB2b2lkICAgICAgICBvbkZpcnN0UmVmKCk7CisKKyAgICBzdHJ1Y3QgVGV4dHVyZSB7CisgICAgICAgIEdMaW50ICAgdzsKKyAgICAgICAgR0xpbnQgICBoOworICAgICAgICBHTHVpbnQgIG5hbWU7CisgICAgfTsKKworICAgIHN0YXR1c190IGluaXRUZXh0dXJlKFRleHR1cmUqIHRleHR1cmUsIEFzc2V0TWFuYWdlciYgYXNzZXQsIGNvbnN0IGNoYXIqIG5hbWUpOworICAgIGJvb2wgYW5kcm9pZCgpOworICAgIGJvb2wgY3lsb24oKTsKKworICAgIHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4gICAgICAgbVNlc3Npb247CisgICAgQXNzZXRNYW5hZ2VyIG1Bc3NldHM7CisgICAgVGV4dHVyZSBtTGVmdFRyYWlsOworICAgIFRleHR1cmUgbVJpZ2h0VHJhaWw7CisgICAgVGV4dHVyZSBtQnJpZ2h0U3BvdDsKKyAgICBUZXh0dXJlIG1BbmRyb2lkWzNdOworICAgIGludCAgICAgbVdpZHRoOworICAgIGludCAgICAgbUhlaWdodDsKKyAgICBFR0xEaXNwbGF5ICBtRGlzcGxheTsKKyAgICBFR0xEaXNwbGF5ICBtQ29udGV4dDsKKyAgICBFR0xEaXNwbGF5ICBtU3VyZmFjZTsKKyAgICBzcDxTdXJmYWNlPiBtRmxpbmdlclN1cmZhY2U7CisgICAgc3A8RUdMTmF0aXZlV2luZG93U3VyZmFjZT4gbU5hdGl2ZVdpbmRvd1N1cmZhY2U7CisgICAgQmFycmllciBtQmFycmllcjsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9CT09UQU5JTUFUSU9OX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvQ1BVR2F1Z2UuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9DUFVHYXVnZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzRhOTI3MAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQ1BVR2F1Z2UuY3BwCkBAIC0wLDAgKzEsMTcxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJDUFVHYXVnZSIKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPG1hdGguaD4KKworI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvUmVjdC5oPgorI2luY2x1ZGUgPHVpL1JlZ2lvbi5oPgorI2luY2x1ZGUgPHVpL0Rpc3BsYXlJbmZvLmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2VDb21wb3Nlci5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlRmxpbmdlckNsaWVudC5oPgorCisjaW5jbHVkZSA8cGl4ZWxmbGluZ2VyL3BpeGVsZmxpbmdlci5oPgorCisjaW5jbHVkZSAiQ1BVR2F1Z2UuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitDUFVHYXVnZTo6Q1BVR2F1Z2UoIGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBjb21wb3NlciwKKyAgICAgICAgICAgICAgICAgICAgbnNlY3NfdCBpbnRlcnZhbCwKKyAgICAgICAgICAgICAgICAgICAgaW50IGNsb2NrLAorICAgICAgICAgICAgICAgICAgICBpbnQgcmVmY2xvY2spCisgICAgOiAgIFRocmVhZChmYWxzZSksIAorICAgICAgICBtSW50ZXJ2YWwoaW50ZXJ2YWwpLCBtQ2xvY2soY2xvY2spLCBtUmVmQ2xvY2socmVmY2xvY2spLAorICAgICAgICBtUmVmZXJlbmNlVGltZSgwKSwKKyAgICAgICAgbVJlZmVyZW5jZVdvcmtpbmdUaW1lKDApLCBtQ3B1VXNhZ2UoMCksCisgICAgICAgIG1SZWZJZGxlVGltZSgwKSwgbUlkbGVUaW1lKDApCit7CisgICAgbUZkID0gZm9wZW4oIi9wcm9jL3N0YXQiLCAiciIpOworICAgIHNldHZidWYobUZkLCBOVUxMLCBfSU9OQkYsIDApOworCisgICAgbVNlc3Npb24gPSBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmNsaWVudEZvckNvbm5lY3Rpb24oCisgICAgICAgIGNvbXBvc2VyLT5jcmVhdGVDb25uZWN0aW9uKCktPmFzQmluZGVyKCkpOworfQorCitDUFVHYXVnZTo6fkNQVUdhdWdlKCkKK3sKKyAgICBmY2xvc2UobUZkKTsKK30KKworY29uc3Qgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiYgQ1BVR2F1Z2U6OnNlc3Npb24oKSBjb25zdCAKK3sKKyAgICByZXR1cm4gbVNlc3Npb247Cit9CisKK3ZvaWQgQ1BVR2F1Z2U6Om9uRmlyc3RSZWYoKQoreworICAgIHJ1bigiQ1BVIEdhdWdlIik7Cit9CisKK3N0YXR1c190IENQVUdhdWdlOjpyZWFkeVRvUnVuKCkKK3sKKyAgICBMT0dJKCJTdGFydGluZyBDUFUgZ2F1Z2UuLi4iKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK2Jvb2wgQ1BVR2F1Z2U6OnRocmVhZExvb3AoKQoreworICAgIERpc3BsYXlJbmZvIGRpbmZvOworICAgIHNlc3Npb24oKS0+Z2V0RGlzcGxheUluZm8oMCwgJmRpbmZvKTsKKyAgICBzcDxTdXJmYWNlPiBzKHNlc3Npb24oKS0+Y3JlYXRlU3VyZmFjZShnZXRwaWQoKSwgMCwgZGluZm8udywgNCwgUElYRUxfRk9STUFUX09QQVFVRSkpOworICAgIHNlc3Npb24oKS0+b3BlblRyYW5zYWN0aW9uKCk7CisgICAgcy0+c2V0TGF5ZXIoSU5UX01BWCk7CisgICAgc2Vzc2lvbigpLT5jbG9zZVRyYW5zYWN0aW9uKCk7CisgICAgCisgICAgc3RhdGljIGNvbnN0IEdHTGZpeGVkIGNvbG9yc1s0XVs0XSA9IHsKKyAgICAgICAgICAgIHsgMHgwMDAwMCwgMHgxMDAwMCwgMHgwMDAwMCwgMHgxMDAwMCB9LAorICAgICAgICAgICAgeyAweDEwMDAwLCAweDEwMDAwLCAweDAwMDAwLCAweDEwMDAwIH0sCisgICAgICAgICAgICB7IDB4MTAwMDAsIDB4MDAwMDAsIDB4MDAwMDAsIDB4MTAwMDAgfSwKKyAgICAgICAgICAgIHsgMHgwMDAwMCwgMHgwMDAwMCwgMHgwMDAwMCwgMHgxMDAwMCB9LAorICAgICAgICB9OworCisgICAgR0dMQ29udGV4dCogZ2w7CisgICAgZ2dsSW5pdCgmZ2wpOworICAgIGdsLT5hY3RpdmVUZXh0dXJlKGdsLCAwKTsKKyAgICBnbC0+ZGlzYWJsZShnbCwgR0dMX1RFWFRVUkVfMkQpOworICAgIGdsLT5kaXNhYmxlKGdsLCBHR0xfQkxFTkQpOworCisgICAgY29uc3QgaW50IHcgPSBkaW5mby53OworCisgICAgd2hpbGUoIWV4aXRQZW5kaW5nKCkpCisgICAgeworICAgICAgICBtTG9jay5sb2NrKCk7CisgICAgICAgICAgICBjb25zdCBmbG9hdCBjcHVVc2FnZSA9IHRoaXMtPmNwdVVzYWdlKCk7CisgICAgICAgICAgICBjb25zdCBmbG9hdCB0b3RhbENwdVVzYWdlID0gMS4wZiAtIGlkbGUoKTsKKyAgICAgICAgbUxvY2sudW5sb2NrKCk7CisKKyAgICAgICAgU3VyZmFjZTo6U3VyZmFjZUluZm8gaW5mbzsKKyAgICAgICAgcy0+bG9jaygmaW5mbyk7CisgICAgICAgICAgICBHR0xTdXJmYWNlIGZiOworICAgICAgICAgICAgICAgIGZiLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgICAgICAgICAgZmIud2lkdGggICA9IGluZm8udzsKKyAgICAgICAgICAgICAgICBmYi5oZWlnaHQgID0gaW5mby5oOworICAgICAgICAgICAgICAgIGZiLnN0cmlkZSAgPSBpbmZvLnc7CisgICAgICAgICAgICAgICAgZmIuZm9ybWF0ICA9IGluZm8uZm9ybWF0OworICAgICAgICAgICAgICAgIGZiLmRhdGEgPSAoR0dMdWJ5dGUqKWluZm8uYml0czsKKworICAgICAgICAgICAgZ2wtPmNvbG9yQnVmZmVyKGdsLCAmZmIpOworICAgICAgICAgICAgZ2wtPmNvbG9yNHh2KGdsLCBjb2xvcnNbM10pOworICAgICAgICAgICAgZ2wtPnJlY3RpKGdsLCAwLCAwLCB3LCA0KTsKKyAgICAgICAgICAgIGdsLT5jb2xvcjR4dihnbCwgY29sb3JzWzJdKTsgLy8gcmVkCisgICAgICAgICAgICBnbC0+cmVjdGkoZ2wsIDAsIDAsIGludCh0b3RhbENwdVVzYWdlKncpLCAyKTsKKyAgICAgICAgICAgIGdsLT5jb2xvcjR4dihnbCwgY29sb3JzWzBdKTsgLy8gZ3JlZW4KKyAgICAgICAgICAgIGdsLT5yZWN0aShnbCwgMCwgMiwgaW50KGNwdVVzYWdlKncpLCA0KTsKKyAgICAgICAgCisgICAgICAgIHMtPnVubG9ja0FuZFBvc3QoKTsgCisKKyAgICAgICAgdXNsZWVwKG5zMnVzKG1JbnRlcnZhbCkpOworICAgIH0KKworICAgIGdnbFVuaW5pdChnbCk7CisgICAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIENQVUdhdWdlOjpzYW1wbGUoKQoreworICAgIGlmIChtTG9jay50cnlMb2NrKCkgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgY29uc3QgbnNlY3NfdCBub3cgPSBzeXN0ZW1UaW1lKG1SZWZDbG9jayk7CisgICAgICAgIGNvbnN0IG5zZWNzX3QgcmVmZXJlbmNlVGltZSA9IG5vdy1tUmVmZXJlbmNlVGltZTsKKyAgICAgICAgaWYgKHJlZmVyZW5jZVRpbWUgPj0gbUludGVydmFsKSB7CisgICAgICAgICAgICBjb25zdCBmbG9hdCByZWZ0aW1lID0gMS4wZiAvIHJlZmVyZW5jZVRpbWU7CisgICAgICAgICAgICBjb25zdCBuc2Vjc190IG5vd1dvcmtpbmdUaW1lID0gc3lzdGVtVGltZShtQ2xvY2spOworICAgICAgICAgICAgCisgICAgICAgICAgICBjaGFyIGJ1ZlsyNTZdOworICAgICAgICAgICAgZmdldHMoYnVmLCAyNTYsIG1GZCk7CisgICAgICAgICAgICByZXdpbmQobUZkKTsKKyAgICAgICAgICAgIGNoYXIgKnN0ciA9IGJ1Zis1OworICAgICAgICAgICAgY2hhciBjb25zdCAqIGNvbnN0IHVzZXJtb2RlID0gc3Ryc2VwKCZzdHIsICIgIik7ICAodm9pZCl1c2VybW9kZTsKKyAgICAgICAgICAgIGNoYXIgY29uc3QgKiBjb25zdCB1c2VybmljZSA9IHN0cnNlcCgmc3RyLCAiICIpOyAgKHZvaWQpdXNlcm5pY2U7CisgICAgICAgICAgICBjaGFyIGNvbnN0ICogY29uc3Qgc3lzdGVtbW9kZSA9IHN0cnNlcCgmc3RyLCAiICIpOyh2b2lkKXN5c3RlbW1vZGU7CisgICAgICAgICAgICBjaGFyIGNvbnN0ICogY29uc3QgaWRsZSA9IHN0cnNlcCgmc3RyLCAiICIpOworICAgICAgICAgICAgY29uc3QgbnNlY3NfdCBub3dJZGxlVGltZSA9IGF0b2koaWRsZSkgKiAxMDAwMDAwMExMOworICAgICAgICAgICAgbUlkbGVUaW1lID0gZmxvYXQobm93SWRsZVRpbWUgLSBtUmVmSWRsZVRpbWUpICogcmVmdGltZTsKKyAgICAgICAgICAgIG1SZWZJZGxlVGltZSA9IG5vd0lkbGVUaW1lOworICAgICAgICAgICAgCisgICAgICAgICAgICBjb25zdCBuc2Vjc190IHdvcmtpbmdUaW1lID0gbm93V29ya2luZ1RpbWUgLSBtUmVmZXJlbmNlV29ya2luZ1RpbWU7CisgICAgICAgICAgICBjb25zdCBmbG9hdCBuZXdDcHVVc2FnZSA9IGZsb2F0KHdvcmtpbmdUaW1lKSAqIHJlZnRpbWU7CisgICAgICAgICAgICBpZiAobUNwdVVzYWdlICE9IG5ld0NwdVVzYWdlKSB7ICAgICAgICAKKyAgICAgICAgICAgICAgICBtQ3B1VXNhZ2UgPSBuZXdDcHVVc2FnZTsKKyAgICAgICAgICAgICAgICBtUmVmZXJlbmNlV29ya2luZ1RpbWUgPSBub3dXb3JraW5nVGltZTsKKyAgICAgICAgICAgICAgICBtUmVmZXJlbmNlVGltZSA9IG5vdzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBtTG9jay51bmxvY2soKTsKKyAgICB9Cit9CisKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvQ1BVR2F1Z2UuaCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvQ1BVR2F1Z2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmI1M2MwCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9DUFVHYXVnZS5oCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfQ1BVR0FVR0VfSAorI2RlZmluZSBBTkRST0lEX0NQVUdBVUdFX0gKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1RpbWVycy5oPgorCisjaW5jbHVkZSA8dWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgQ1BVR2F1Z2UgOiBwdWJsaWMgVGhyZWFkCit7CitwdWJsaWM6CisgICAgQ1BVR2F1Z2UoICAgY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIGNvbXBvc2VyLAorICAgICAgICAgICAgICAgIG5zZWNzX3QgaW50ZXJ2YWw9czJucygxKSwKKyAgICAgICAgICAgICAgICBpbnQgY2xvY2s9U1lTVEVNX1RJTUVfVEhSRUFELAorICAgICAgICAgICAgICAgIGludCByZWZjbG9jaz1TWVNURU1fVElNRV9NT05PVE9OSUMpOworICAgICAgICAgICAgICAgIAorICAgIH5DUFVHYXVnZSgpOworCisgICAgY29uc3Qgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiYgc2Vzc2lvbigpIGNvbnN0OworCisgICAgdm9pZCBzYW1wbGUoKTsKKyAKKyAgICBpbmxpbmUgZmxvYXQgY3B1VXNhZ2UoKSBjb25zdCB7IHJldHVybiBtQ3B1VXNhZ2U7IH0KKyAgICBpbmxpbmUgZmxvYXQgaWRsZSgpIGNvbnN0IHsgcmV0dXJuIG1JZGxlVGltZTsgfQorCitwcml2YXRlOgorICAgIHZpcnR1YWwgdm9pZCAgICAgICAgb25GaXJzdFJlZigpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgcmVhZHlUb1J1bigpOworICAgIHZpcnR1YWwgYm9vbCAgICAgICAgdGhyZWFkTG9vcCgpOworCisgICAgTXV0ZXggbUxvY2s7CisKKyAgICBzcDxTdXJmYWNlQ29tcG9zZXJDbGllbnQ+IG1TZXNzaW9uOworCisgICAgY29uc3QgbnNlY3NfdCBtSW50ZXJ2YWw7CisgICAgY29uc3QgaW50IG1DbG9jazsKKyAgICBjb25zdCBpbnQgbVJlZkNsb2NrOworCisgICAgbnNlY3NfdCBtUmVmZXJlbmNlVGltZTsKKyAgICBuc2Vjc190IG1SZWZlcmVuY2VXb3JraW5nVGltZTsKKyAgICBmbG9hdCBtQ3B1VXNhZ2U7CisgICAgbnNlY3NfdCBtUmVmSWRsZVRpbWU7CisgICAgZmxvYXQgbUlkbGVUaW1lOworICAgIEZJTEUqICAgbUZkOworfTsKKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9DUFVHQVVHRV9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL0Rpc3BsYXlIYXJkd2FyZS9EaXNwbGF5SGFyZHdhcmUuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTRkN2U5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmNwcApAQCAtMCwwICsxLDM1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZUZsaW5nZXIiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPG1hdGguaD4KKworI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHVpL0VHTERpc3BsYXlTdXJmYWNlLmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8RUdML2VnbGV4dC5oPgorCisKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisKKyNpbmNsdWRlIDxoYXJkd2FyZS9jb3B5Yml0Lmg+CisjaW5jbHVkZSA8aGFyZHdhcmUvb3ZlcmxheS5oPgorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK2NvbnN0IGNoYXIgKmVnbF9zdHJlcnJvcihFR0xpbnQgZXJyKQoreworICAgIHN3aXRjaCAoZXJyKXsKKyAgICAgICAgY2FzZSBFR0xfU1VDQ0VTUzogICAgICAgICAgIHJldHVybiAiRUdMX1NVQ0NFU1MiOworICAgICAgICBjYXNlIEVHTF9OT1RfSU5JVElBTElaRUQ6ICAgcmV0dXJuICJFR0xfTk9UX0lOSVRJQUxJWkVEIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX0FDQ0VTUzogICAgICAgIHJldHVybiAiRUdMX0JBRF9BQ0NFU1MiOworICAgICAgICBjYXNlIEVHTF9CQURfQUxMT0M6ICAgICAgICAgcmV0dXJuICJFR0xfQkFEX0FMTE9DIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX0FUVFJJQlVURTogICAgIHJldHVybiAiRUdMX0JBRF9BVFRSSUJVVEUiOworICAgICAgICBjYXNlIEVHTF9CQURfQ09ORklHOiAgICAgICAgcmV0dXJuICJFR0xfQkFEX0NPTkZJRyI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9DT05URVhUOiAgICAgICByZXR1cm4gIkVHTF9CQURfQ09OVEVYVCI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9DVVJSRU5UX1NVUkZBQ0U6IHJldHVybiAiRUdMX0JBRF9DVVJSRU5UX1NVUkZBQ0UiOworICAgICAgICBjYXNlIEVHTF9CQURfRElTUExBWTogICAgICAgcmV0dXJuICJFR0xfQkFEX0RJU1BMQVkiOworICAgICAgICBjYXNlIEVHTF9CQURfTUFUQ0g6ICAgICAgICAgcmV0dXJuICJFR0xfQkFEX01BVENIIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX05BVElWRV9QSVhNQVA6IHJldHVybiAiRUdMX0JBRF9OQVRJVkVfUElYTUFQIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX05BVElWRV9XSU5ET1c6IHJldHVybiAiRUdMX0JBRF9OQVRJVkVfV0lORE9XIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX1BBUkFNRVRFUjogICAgIHJldHVybiAiRUdMX0JBRF9QQVJBTUVURVIiOworICAgICAgICBjYXNlIEVHTF9CQURfU1VSRkFDRTogICAgICAgcmV0dXJuICJFR0xfQkFEX1NVUkZBQ0UiOworICAgICAgICBjYXNlIEVHTF9DT05URVhUX0xPU1Q6ICAgICAgcmV0dXJuICJFR0xfQ09OVEVYVF9MT1NUIjsKKyAgICAgICAgZGVmYXVsdDogcmV0dXJuICJVTktOT1dOIjsKKyAgICB9Cit9CisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCit2b2lkIGNoZWNrR0xFcnJvcnMoKQoreworICAgIEdMZW51bSBlcnJvciA9IGdsR2V0RXJyb3IoKTsKKyAgICBpZiAoZXJyb3IgIT0gR0xfTk9fRVJST1IpCisgICAgICAgIExPR0UoIkdMIGVycm9yIDB4JTA0eCIsIGludChlcnJvcikpOworfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBjaGVja0VHTEVycm9ycyhjb25zdCBjaGFyKiB0b2tlbikKK3sKKyAgICBFR0xpbnQgZXJyb3IgPSBlZ2xHZXRFcnJvcigpOworICAgIC8vIEdMRVNvbkdMIHNlZW1zIHRvIGJlIHJldHVybmluZyAwIHdoZW4gdGhlcmUgaXMgbm8gZXJyb3JzPworICAgIGlmIChlcnJvciAmJiBlcnJvciAhPSBFR0xfU1VDQ0VTUykKKyAgICAgICAgTE9HRSgiJXMgZXJyb3IgMHglMDR4ICglcykiLAorICAgICAgICAgICAgICAgIHRva2VuLCBpbnQoZXJyb3IpLCBlZ2xfc3RyZXJyb3IoZXJyb3IpKTsKK30KKworCisvKgorICogSW5pdGlhbGl6ZSB0aGUgZGlzcGxheSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlcy4KKyAqCisgKi8KKworRGlzcGxheUhhcmR3YXJlOjpEaXNwbGF5SGFyZHdhcmUoCisgICAgICAgIGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlciwKKyAgICAgICAgdWludDMyX3QgZHB5KQorICAgIDogRGlzcGxheUhhcmR3YXJlQmFzZShmbGluZ2VyLCBkcHkpCit7CisgICAgaW5pdChkcHkpOworfQorCitEaXNwbGF5SGFyZHdhcmU6On5EaXNwbGF5SGFyZHdhcmUoKQoreworICAgIGZpbmkoKTsKK30KKworZmxvYXQgRGlzcGxheUhhcmR3YXJlOjpnZXREcGlYKCkgY29uc3QgICAgICAgICAgeyByZXR1cm4gbURwaVg7IH0KK2Zsb2F0IERpc3BsYXlIYXJkd2FyZTo6Z2V0RHBpWSgpIGNvbnN0ICAgICAgICAgIHsgcmV0dXJuIG1EcGlZOyB9CitmbG9hdCBEaXNwbGF5SGFyZHdhcmU6OmdldERlbnNpdHkoKSBjb25zdCAgICAgICB7IHJldHVybiBtRGVuc2l0eTsgfQorZmxvYXQgRGlzcGxheUhhcmR3YXJlOjpnZXRSZWZyZXNoUmF0ZSgpIGNvbnN0ICAgeyByZXR1cm4gbVJlZnJlc2hSYXRlOyB9CitpbnQgRGlzcGxheUhhcmR3YXJlOjpnZXRXaWR0aCgpIGNvbnN0ICAgICAgICAgICB7IHJldHVybiBtV2lkdGg7IH0KK2ludCBEaXNwbGF5SGFyZHdhcmU6OmdldEhlaWdodCgpIGNvbnN0ICAgICAgICAgIHsgcmV0dXJuIG1IZWlnaHQ7IH0KK1BpeGVsRm9ybWF0IERpc3BsYXlIYXJkd2FyZTo6Z2V0Rm9ybWF0KCkgY29uc3QgIHsgcmV0dXJuIG1Gb3JtYXQ7IH0KKwordm9pZCBEaXNwbGF5SGFyZHdhcmU6OmluaXQodWludDMyX3QgZHB5KQoreworICAgIC8vIGluaXRpYWxpemUgRUdMCisgICAgY29uc3QgRUdMaW50IGF0dHJpYnNbXSA9IHsKKyAgICAgICAgICAgIEVHTF9SRURfU0laRSwgICAgICAgNSwKKyAgICAgICAgICAgIEVHTF9HUkVFTl9TSVpFLCAgICAgNiwKKyAgICAgICAgICAgIEVHTF9CTFVFX1NJWkUsICAgICAgNSwKKyAgICAgICAgICAgIEVHTF9ERVBUSF9TSVpFLCAgICAgMCwKKyAgICAgICAgICAgIEVHTF9OT05FCisgICAgfTsKKyAgICBFR0xpbnQgdywgaCwgZHVtbXk7CisgICAgRUdMaW50IG51bUNvbmZpZ3MsIG47CisgICAgRUdMQ29uZmlnIGNvbmZpZzsKKyAgICBFR0xTdXJmYWNlIHN1cmZhY2U7CisgICAgRUdMQ29udGV4dCBjb250ZXh0OworICAgIG1GbGFncyA9IDA7CisKKyAgICAvLyBUT0RPOiBhbGwgdGhlIGV4dGVuc2lvbnMgYmVsb3cgc2hvdWxkIGJlIHF1ZXJpZWQgdGhyb3VnaAorICAgIC8vIGVnbEdldFByb2NBZGRyZXNzKCkuCisKKyAgICBFR0xEaXNwbGF5IGRpc3BsYXkgPSBlZ2xHZXREaXNwbGF5KEVHTF9ERUZBVUxUX0RJU1BMQVkpOworICAgIGVnbEluaXRpYWxpemUoZGlzcGxheSwgTlVMTCwgTlVMTCk7CisgICAgZWdsR2V0Q29uZmlncyhkaXNwbGF5LCBOVUxMLCAwLCAmbnVtQ29uZmlncyk7CisgICAgZWdsQ2hvb3NlQ29uZmlnKGRpc3BsYXksIGF0dHJpYnMsICZjb25maWcsIDEsICZuKTsKKworICAgIC8qCisgICAgICogR2F0aGVyIEVHTCBleHRlbnNpb25zCisgICAgICovCisKKyAgICBjb25zdCBjaGFyKiBjb25zdCBlZ2xfZXh0ZW5zaW9ucyA9IGVnbFF1ZXJ5U3RyaW5nKAorICAgICAgICAgICAgZGlzcGxheSwgRUdMX0VYVEVOU0lPTlMpOworICAgIAorICAgIExPR0koIkVHTCBpbmZvcm1hdGlvbnM6Iik7CisgICAgTE9HSSgiIyBvZiBjb25maWdzIDogJWQiLCBudW1Db25maWdzKTsKKyAgICBMT0dJKCJ2ZW5kb3IgICAgOiAlcyIsIGVnbFF1ZXJ5U3RyaW5nKGRpc3BsYXksIEVHTF9WRU5ET1IpKTsKKyAgICBMT0dJKCJ2ZXJzaW9uICAgOiAlcyIsIGVnbFF1ZXJ5U3RyaW5nKGRpc3BsYXksIEVHTF9WRVJTSU9OKSk7CisgICAgTE9HSSgiZXh0ZW5zaW9uczogJXMiLCBlZ2xfZXh0ZW5zaW9ucyk7CisgICAgTE9HSSgiQ2xpZW50IEFQSTogJXMiLCBlZ2xRdWVyeVN0cmluZyhkaXNwbGF5LCBFR0xfQ0xJRU5UX0FQSVMpPzoiTm90IFN1cHBvcnRlZCIpOworCisgICAgLy8gVE9ETzogZ2V0IHRoaXMgZnJvbSB0aGUgZGV2ZmIgZHJpdmVyIChwcm9iYWJseSBzaG91bGQgYmUgSEFMIG1vZHVsZSkKKyAgICBtRmxhZ3MgfD0gU1dBUF9SRUNUQU5HTEVfRVhURU5TSU9OOworICAgIAorICAgIC8vIFRPRE86IGdldCB0aGUgcmVhbCAidXBkYXRlX29uX2RlbWFuZCIgYmVoYXZpb3IgKHByb2JhYmx5IHNob3VsZCBiZSBIQUwgbW9kdWxlKQorICAgIG1GbGFncyB8PSBVUERBVEVfT05fREVNQU5EOworCisgICAgaWYgKGVnbEdldENvbmZpZ0F0dHJpYihkaXNwbGF5LCBjb25maWcsIEVHTF9DT05GSUdfQ0FWRUFULCAmZHVtbXkpID09IEVHTF9UUlVFKSB7CisgICAgICAgIGlmIChkdW1teSA9PSBFR0xfU0xPV19DT05GSUcpCisgICAgICAgICAgICBtRmxhZ3MgfD0gU0xPV19DT05GSUc7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDcmVhdGUgb3VyIG1haW4gc3VyZmFjZQorICAgICAqLworCisgICAgbURpc3BsYXlTdXJmYWNlID0gbmV3IEVHTERpc3BsYXlTdXJmYWNlKCk7CisKKyAgICBzdXJmYWNlID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShkaXNwbGF5LCBjb25maWcsIG1EaXNwbGF5U3VyZmFjZS5nZXQoKSwgTlVMTCk7CisgICAgLy9jaGVja0VHTEVycm9ycygiZWdsQ3JlYXRlRGlzcGxheVN1cmZhY2VBTkRST0lEIik7CisKKyAgICBpZiAoZWdsUXVlcnlTdXJmYWNlKGRpc3BsYXksIHN1cmZhY2UsIEVHTF9TV0FQX0JFSEFWSU9SLCAmZHVtbXkpID09IEVHTF9UUlVFKSB7CisgICAgICAgIGlmIChkdW1teSA9PSBFR0xfQlVGRkVSX1BSRVNFUlZFRCkgeworICAgICAgICAgICAgbUZsYWdzIHw9IEJVRkZFUl9QUkVTRVJWRUQ7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgR0xpbnQgdmFsdWUgPSBFR0xfVU5LTk9XTjsKKyAgICBlZ2xRdWVyeVN1cmZhY2UoZGlzcGxheSwgc3VyZmFjZSwgRUdMX0hPUklaT05UQUxfUkVTT0xVVElPTiwgJnZhbHVlKTsKKyAgICBpZiAodmFsdWUgPT0gRUdMX1VOS05PV04pIHsKKyAgICAgICAgbURwaVggPSAxNjAuMGY7CisgICAgfSBlbHNlIHsKKyAgICAgICAgbURwaVggPSAyNS40ZiAqIGZsb2F0KHZhbHVlKS9FR0xfRElTUExBWV9TQ0FMSU5HOworICAgIH0KKyAgICB2YWx1ZSA9IEVHTF9VTktOT1dOOworICAgIGVnbFF1ZXJ5U3VyZmFjZShkaXNwbGF5LCBzdXJmYWNlLCBFR0xfVkVSVElDQUxfUkVTT0xVVElPTiwgJnZhbHVlKTsKKyAgICBpZiAodmFsdWUgPT0gRUdMX1VOS05PV04pIHsKKyAgICAgICAgbURwaVkgPSAxNjAuMGY7CisgICAgfSBlbHNlIHsKKyAgICAgICAgbURwaVkgPSAyNS40ZiAqIGZsb2F0KHZhbHVlKS9FR0xfRElTUExBWV9TQ0FMSU5HOworICAgIH0KKyAgICBtUmVmcmVzaFJhdGUgPSA2MC5mOyAgICAvLyBUT0RPOiBnZXQgdGhlIHJlYWwgcmVmcmVzaCByYXRlIAorICAgIAorICAgIAorICAgIGNoYXIgcHJvcGVydHlbUFJPUEVSVFlfVkFMVUVfTUFYXTsKKyAgICBpZiAocHJvcGVydHlfZ2V0KCJyby5zZi5sY2RfZGVuc2l0eSIsIHByb3BlcnR5LCBOVUxMKSA8PSAwKSB7CisgICAgICAgIExPR1coInJvLnNmLmxjZF9kZW5zaXR5IG5vdCBkZWZpbmVkLCB1c2luZyAxNjAgZHBpIGJ5IGRlZmF1bHQuIik7CisgICAgICAgIHN0cmNweShwcm9wZXJ0eSwgIjE2MCIpOworICAgIH0KKyAgICBtRGVuc2l0eSA9IGF0b2kocHJvcGVydHkpICogKDEuMGYvMTYwLjBmKTsKKworCisgICAgLyoKKyAgICAgKiBDcmVhdGUgb3VyIE9wZW5HTCBFUyBjb250ZXh0CisgICAgICovCisgICAgCisgICAgY29udGV4dCA9IGVnbENyZWF0ZUNvbnRleHQoZGlzcGxheSwgY29uZmlnLCBOVUxMLCBOVUxMKTsKKyAgICAvL2NoZWNrRUdMRXJyb3JzKCJlZ2xDcmVhdGVDb250ZXh0Iik7CisgICAgCisgICAgZWdsUXVlcnlTdXJmYWNlKGRpc3BsYXksIHN1cmZhY2UsIEVHTF9XSURUSCwgJm1XaWR0aCk7CisgICAgZWdsUXVlcnlTdXJmYWNlKGRpc3BsYXksIHN1cmZhY2UsIEVHTF9IRUlHSFQsICZtSGVpZ2h0KTsKKyAgICAKKyAgICAKKyAgICAvKgorICAgICAqIEdhdGhlciBPcGVuR0wgRVMgZXh0ZW5zaW9ucworICAgICAqLworCisgICAgZWdsTWFrZUN1cnJlbnQoZGlzcGxheSwgc3VyZmFjZSwgc3VyZmFjZSwgY29udGV4dCk7CisgICAgY29uc3QgY2hhciogY29uc3QgIGdsX2V4dGVuc2lvbnMgPSAoY29uc3QgY2hhciopZ2xHZXRTdHJpbmcoR0xfRVhURU5TSU9OUyk7CisgICAgTE9HSSgiT3BlbkdMIGluZm9ybWF0aW9uczoiKTsKKyAgICBMT0dJKCJ2ZW5kb3IgICAgOiAlcyIsIGdsR2V0U3RyaW5nKEdMX1ZFTkRPUikpOworICAgIExPR0koInJlbmRlcmVyICA6ICVzIiwgZ2xHZXRTdHJpbmcoR0xfUkVOREVSRVIpKTsKKyAgICBMT0dJKCJ2ZXJzaW9uICAgOiAlcyIsIGdsR2V0U3RyaW5nKEdMX1ZFUlNJT04pKTsKKyAgICBMT0dJKCJleHRlbnNpb25zOiAlcyIsIGdsX2V4dGVuc2lvbnMpOworCisgICAgaWYgKHN0cnN0cihnbF9leHRlbnNpb25zLCAiR0xfQVJCX3RleHR1cmVfbm9uX3Bvd2VyX29mX3R3byIpKSB7CisgICAgICAgIG1GbGFncyB8PSBOUE9UX0VYVEVOU0lPTjsKKyAgICB9CisgICAgaWYgKHN0cnN0cihnbF9leHRlbnNpb25zLCAiR0xfT0VTX2RyYXdfdGV4dHVyZSIpKSB7CisgICAgICAgIG1GbGFncyB8PSBEUkFXX1RFWFRVUkVfRVhURU5TSU9OOworICAgIH0KKyAgICBpZiAoc3Ryc3RyKGdsX2V4dGVuc2lvbnMsICJHTF9BTkRST0lEX2RpcmVjdF90ZXh0dXJlIikpIHsKKyAgICAgICAgbUZsYWdzIHw9IERJUkVDVF9URVhUVVJFOworICAgIH0KKworICAgIC8vIFVuYmluZCB0aGUgY29udGV4dCBmcm9tIHRoaXMgdGhyZWFkCisgICAgZWdsTWFrZUN1cnJlbnQoZGlzcGxheSwgRUdMX05PX1NVUkZBQ0UsIEVHTF9OT19TVVJGQUNFLCBFR0xfTk9fQ09OVEVYVCk7CisKKyAgICBtRGlzcGxheSA9IGRpc3BsYXk7CisgICAgbUNvbmZpZyAgPSBjb25maWc7CisgICAgbVN1cmZhY2UgPSBzdXJmYWNlOworICAgIG1Db250ZXh0ID0gY29udGV4dDsKKyAgICBtRm9ybWF0ICA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NTsKKyAgICAKKyAgICBod19tb2R1bGVfdCBjb25zdCogbW9kdWxlOworCisgICAgbUJsaXRFbmdpbmUgPSBOVUxMOworICAgIGlmIChod19nZXRfbW9kdWxlKENPUFlCSVRfSEFSRFdBUkVfTU9EVUxFX0lELCAmbW9kdWxlKSA9PSAwKSB7CisgICAgICAgIGNvcHliaXRfb3Blbihtb2R1bGUsICZtQmxpdEVuZ2luZSk7CisgICAgfQorCisgICAgbU92ZXJsYXlFbmdpbmUgPSBOVUxMOworICAgIGlmIChod19nZXRfbW9kdWxlKE9WRVJMQVlfSEFSRFdBUkVfTU9EVUxFX0lELCAmbW9kdWxlKSA9PSAwKSB7CisgICAgICAgIG92ZXJsYXlfY29udHJvbF9vcGVuKG1vZHVsZSwgJm1PdmVybGF5RW5naW5lKTsKKyAgICB9Cit9CisKKy8qCisgKiBDbGVhbiB1cC4gIFRocm93IG91dCBvdXIgbG9jYWwgc3RhdGUuCisgKgorICogKEl0J3MgZW50aXJlbHkgcG9zc2libGUgd2UnbGwgbmV2ZXIgZ2V0IGhlcmUsIHNpbmNlIHRoaXMgaXMgbWVhbnQKKyAqIGZvciByZWFsIGhhcmR3YXJlLCB3aGljaCBkb2Vzbid0IHJlc3RhcnQuKQorICovCisKK3ZvaWQgRGlzcGxheUhhcmR3YXJlOjpmaW5pKCkKK3sKKyAgICBlZ2xNYWtlQ3VycmVudChtRGlzcGxheSwgRUdMX05PX1NVUkZBQ0UsIEVHTF9OT19TVVJGQUNFLCBFR0xfTk9fQ09OVEVYVCk7CisgICAgZWdsVGVybWluYXRlKG1EaXNwbGF5KTsKKyAgICBjb3B5Yml0X2Nsb3NlKG1CbGl0RW5naW5lKTsKKyAgICBvdmVybGF5X2NvbnRyb2xfY2xvc2UobU92ZXJsYXlFbmdpbmUpOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6cmVsZWFzZVNjcmVlbigpIGNvbnN0Cit7CisgICAgRGlzcGxheUhhcmR3YXJlQmFzZTo6cmVsZWFzZVNjcmVlbigpOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6YWNxdWlyZVNjcmVlbigpIGNvbnN0Cit7CisgICAgRGlzcGxheUhhcmR3YXJlQmFzZTo6YWNxdWlyZVNjcmVlbigpOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6Z2V0RGlzcGxheVN1cmZhY2UoY29weWJpdF9pbWFnZV90KiBpbWcpIGNvbnN0Cit7CisgICAgaW1nLT53ICAgICAgPSBtRGlzcGxheVN1cmZhY2UtPnN0cmlkZTsKKyAgICBpbWctPmggICAgICA9IG1EaXNwbGF5U3VyZmFjZS0+aGVpZ2h0OworICAgIGltZy0+Zm9ybWF0ID0gbURpc3BsYXlTdXJmYWNlLT5mb3JtYXQ7CisgICAgaW1nLT5vZmZzZXQgPSBtRGlzcGxheVN1cmZhY2UtPm9mZnNldDsKKyAgICBpbWctPmJhc2UgICA9ICh2b2lkKiltRGlzcGxheVN1cmZhY2UtPmJhc2U7CisgICAgaW1nLT5mZCAgICAgPSBtRGlzcGxheVN1cmZhY2UtPmZkOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6Z2V0RGlzcGxheVN1cmZhY2UoR0dMU3VyZmFjZSogZmIpIGNvbnN0Cit7CisgICAgZmItPnZlcnNpb249IHNpemVvZihHR0xTdXJmYWNlKTsKKyAgICBmYi0+d2lkdGggID0gbURpc3BsYXlTdXJmYWNlLT53aWR0aDsKKyAgICBmYi0+aGVpZ2h0ID0gbURpc3BsYXlTdXJmYWNlLT5oZWlnaHQ7CisgICAgZmItPnN0cmlkZSA9IG1EaXNwbGF5U3VyZmFjZS0+c3RyaWRlOworICAgIGZiLT5mb3JtYXQgPSBtRGlzcGxheVN1cmZhY2UtPmZvcm1hdDsKKyAgICBmYi0+ZGF0YSAgID0gKEdHTHVieXRlKiltRGlzcGxheVN1cmZhY2UtPmJhc2UgKyBtRGlzcGxheVN1cmZhY2UtPm9mZnNldDsKK30KKwordWludDMyX3QgRGlzcGxheUhhcmR3YXJlOjpnZXRQYWdlRmxpcENvdW50KCkgY29uc3QgeworICAgIHJldHVybiBtRGlzcGxheVN1cmZhY2UtPmdldFBhZ2VGbGlwQ291bnQoKTsKK30KKworLyoKKyAqICJGbGlwIiB0aGUgZnJvbnQgYW5kIGJhY2sgYnVmZmVycy4KKyAqLworCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6ZmxpcChjb25zdCBSZWdpb24mIGRpcnR5KSBjb25zdAoreworICAgIGNoZWNrR0xFcnJvcnMoKTsKKworICAgIEVHTERpc3BsYXkgZHB5ID0gbURpc3BsYXk7CisgICAgRUdMU3VyZmFjZSBzdXJmYWNlID0gbVN1cmZhY2U7CisKKyAgICBSZWdpb24gbmV3RGlydHkoZGlydHkpOworICAgIG5ld0RpcnR5LmFuZFNlbGYoUmVjdChtV2lkdGgsIG1IZWlnaHQpKTsKKworICAgIGlmIChtRmxhZ3MgJiBCVUZGRVJfUFJFU0VSVkVEKSB7CisgICAgICAgIGNvbnN0IFJlZ2lvbiBjb3B5YmFjayhtRGlydHkuc3VidHJhY3QobmV3RGlydHkpKTsKKyAgICAgICAgbURpcnR5ID0gbmV3RGlydHk7CisgICAgICAgIG1EaXNwbGF5U3VyZmFjZS0+Y29weUZyb250VG9CYWNrKGNvcHliYWNrKTsKKyAgICB9IAorCisgICAgaWYgKG1GbGFncyAmIFNXQVBfUkVDVEFOR0xFX0VYVEVOU0lPTikgeworICAgICAgICBjb25zdCBSZWN0JiBiKG5ld0RpcnR5LmJvdW5kcygpKTsKKyAgICAgICAgbURpc3BsYXlTdXJmYWNlLT5zZXRTd2FwUmVjdGFuZ2xlKAorICAgICAgICAgICAgICAgIGIubGVmdCwgYi50b3AsIGIud2lkdGgoKSwgYi5oZWlnaHQoKSk7CisgICAgfQorCisgICAgZWdsU3dhcEJ1ZmZlcnMoZHB5LCBzdXJmYWNlKTsKKyAgICBjaGVja0VHTEVycm9ycygiZWdsU3dhcEJ1ZmZlcnMiKTsKKworICAgIC8vIGZvciBkZWJ1Z2dpbmcKKyAgICAvL2dsQ2xlYXJDb2xvcigxLDAsMCwwKTsKKyAgICAvL2dsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7Cit9CisKK3VpbnQzMl90IERpc3BsYXlIYXJkd2FyZTo6Z2V0RmxhZ3MoKSBjb25zdAoreworICAgIHJldHVybiBtRmxhZ3M7Cit9CisKK3ZvaWQgRGlzcGxheUhhcmR3YXJlOjptYWtlQ3VycmVudCgpIGNvbnN0Cit7CisgICAgZWdsTWFrZUN1cnJlbnQobURpc3BsYXksIG1TdXJmYWNlLCBtU3VyZmFjZSwgbUNvbnRleHQpOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZTo6Y29weUZyb250VG9JbWFnZShjb25zdCBjb3B5Yml0X2ltYWdlX3QmIGZyb250KSBjb25zdCB7CisgICAgbURpc3BsYXlTdXJmYWNlLT5jb3B5RnJvbnRUb0ltYWdlKGZyb250KTsKK30KKwordm9pZCBEaXNwbGF5SGFyZHdhcmU6OmNvcHlCYWNrVG9JbWFnZShjb25zdCBjb3B5Yml0X2ltYWdlX3QmIGZyb250KSBjb25zdCB7CisgICAgbURpc3BsYXlTdXJmYWNlLT5jb3B5QmFja1RvSW1hZ2UoZnJvbnQpOworfQpkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmggYi9saWJzL3N1cmZhY2VmbGluZ2VyL0Rpc3BsYXlIYXJkd2FyZS9EaXNwbGF5SGFyZHdhcmUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NTBhNGQxCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfRElTUExBWV9IQVJEV0FSRV9ICisjZGVmaW5lIEFORFJPSURfRElTUExBWV9IQVJEV0FSRV9ICisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvUmVnaW9uLmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlQmFzZS5oIgorCitzdHJ1Y3Qgb3ZlcmxheV9jb250cm9sX2RldmljZV90Oworc3RydWN0IGNvcHliaXRfZGV2aWNlX3Q7CitzdHJ1Y3QgY29weWJpdF9pbWFnZV90Oworc3RydWN0IGNvcHliaXRfdDsKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBFR0xEaXNwbGF5U3VyZmFjZTsKKworY2xhc3MgRGlzcGxheUhhcmR3YXJlIDogcHVibGljIERpc3BsYXlIYXJkd2FyZUJhc2UKK3sKK3B1YmxpYzoKKyAgICBlbnVtIHsKKyAgICAgICAgRElSRUNUX1RFWFRVUkUgICAgICAgICAgPSAweDAwMDAwMDAyLAorICAgICAgICBTV0FQX1JFQ1RBTkdMRV9FWFRFTlNJT049IDB4MDAwMDAwMDQsCisgICAgICAgIENPUFlfQklUU19FWFRFTlNJT04gICAgID0gMHgwMDAwMDAwOCwKKyAgICAgICAgTlBPVF9FWFRFTlNJT04gICAgICAgICAgPSAweDAwMDAwMTAwLAorICAgICAgICBEUkFXX1RFWFRVUkVfRVhURU5TSU9OICA9IDB4MDAwMDAyMDAsCisgICAgICAgIEJVRkZFUl9QUkVTRVJWRUQgICAgICAgID0gMHgwMDAxMDAwMCwKKyAgICAgICAgVVBEQVRFX09OX0RFTUFORCAgICAgICAgPSAweDAwMDIwMDAwLCAgIC8vIHZpZGVvIGRyaXZlciBmZWF0dXJlCisgICAgICAgIFNMT1dfQ09ORklHICAgICAgICAgICAgID0gMHgwMDA0MDAwMCwgICAvLyBzb2Z0d2FyZQorICAgIH07CisKKyAgICBEaXNwbGF5SGFyZHdhcmUoCisgICAgICAgICAgICBjb25zdCBzcDxTdXJmYWNlRmxpbmdlcj4mIGZsaW5nZXIsCisgICAgICAgICAgICB1aW50MzJfdCBkaXNwbGF5SW5kZXgpOworCisgICAgfkRpc3BsYXlIYXJkd2FyZSgpOworCisgICAgdm9pZCByZWxlYXNlU2NyZWVuKCkgY29uc3Q7CisgICAgdm9pZCBhY3F1aXJlU2NyZWVuKCkgY29uc3Q7CisKKyAgICAvLyBGbGlwIHRoZSBmcm9udCBhbmQgYmFjayBidWZmZXJzIGlmIHRoZSBiYWNrIGJ1ZmZlciBpcyAiZGlydHkiLiAgTWlnaHQKKyAgICAvLyBiZSBpbnN0YW50YW5lb3VzLCBtaWdodCBpbnZvbHZlIGNvcHlpbmcgdGhlIGZyYW1lIGJ1ZmZlciBhcm91bmQuCisgICAgdm9pZCBmbGlwKGNvbnN0IFJlZ2lvbiYgZGlydHkpIGNvbnN0OworCisgICAgZmxvYXQgICAgICAgZ2V0RHBpWCgpIGNvbnN0OworICAgIGZsb2F0ICAgICAgIGdldERwaVkoKSBjb25zdDsKKyAgICBmbG9hdCAgICAgICBnZXRSZWZyZXNoUmF0ZSgpIGNvbnN0OworICAgIGZsb2F0ICAgICAgIGdldERlbnNpdHkoKSBjb25zdDsKKyAgICBpbnQgICAgICAgICBnZXRXaWR0aCgpIGNvbnN0OworICAgIGludCAgICAgICAgIGdldEhlaWdodCgpIGNvbnN0OworICAgIFBpeGVsRm9ybWF0IGdldEZvcm1hdCgpIGNvbnN0OworICAgIHVpbnQzMl90ICAgIGdldEZsYWdzKCkgY29uc3Q7CisgICAgdm9pZCAgICAgICAgbWFrZUN1cnJlbnQoKSBjb25zdDsKKworICAgIHVpbnQzMl90IGdldFBhZ2VGbGlwQ291bnQoKSBjb25zdDsKKyAgICB2b2lkIGdldERpc3BsYXlTdXJmYWNlKGNvcHliaXRfaW1hZ2VfdCogaW1nKSBjb25zdDsKKyAgICB2b2lkIGdldERpc3BsYXlTdXJmYWNlKEdHTFN1cmZhY2UqIGZiKSBjb25zdDsKKyAgICBFR0xEaXNwbGF5IGdldEVHTERpc3BsYXkoKSBjb25zdCB7IHJldHVybiBtRGlzcGxheTsgfQorICAgIGNvcHliaXRfZGV2aWNlX3QqIGdldEJsaXRFbmdpbmUoKSBjb25zdCB7IHJldHVybiBtQmxpdEVuZ2luZTsgfQorICAgIG92ZXJsYXlfY29udHJvbF9kZXZpY2VfdCogZ2V0T3ZlcmxheUVuZ2luZSgpIGNvbnN0IHsgcmV0dXJuIG1PdmVybGF5RW5naW5lOyB9CisgICAgCisgICAgdm9pZCBjb3B5RnJvbnRUb0ltYWdlKGNvbnN0IGNvcHliaXRfaW1hZ2VfdCYgZnJvbnQpIGNvbnN0OworICAgIHZvaWQgY29weUJhY2tUb0ltYWdlKGNvbnN0IGNvcHliaXRfaW1hZ2VfdCYgZnJvbnQpIGNvbnN0OworICAgICAgIAorICAgIFJlY3QgYm91bmRzKCkgY29uc3QgeworICAgICAgICByZXR1cm4gUmVjdChtV2lkdGgsIG1IZWlnaHQpOworICAgIH0KKworcHJpdmF0ZToKKyAgICB2b2lkIGluaXQodWludDMyX3QgZGlzcGxheUluZGV4KSBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpOworICAgIHZvaWQgZmluaSgpIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSk7CisKKyAgICBFR0xEaXNwbGF5ICAgICAgbURpc3BsYXk7CisgICAgRUdMU3VyZmFjZSAgICAgIG1TdXJmYWNlOworICAgIEVHTENvbnRleHQgICAgICBtQ29udGV4dDsKKyAgICBFR0xDb25maWcgICAgICAgbUNvbmZpZzsKKyAgICBmbG9hdCAgICAgICAgICAgbURwaVg7CisgICAgZmxvYXQgICAgICAgICAgIG1EcGlZOworICAgIGZsb2F0ICAgICAgICAgICBtUmVmcmVzaFJhdGU7CisgICAgZmxvYXQgICAgICAgICAgIG1EZW5zaXR5OworICAgIGludCAgICAgICAgICAgICBtV2lkdGg7CisgICAgaW50ICAgICAgICAgICAgIG1IZWlnaHQ7CisgICAgUGl4ZWxGb3JtYXQgICAgIG1Gb3JtYXQ7CisgICAgdWludDMyX3QgICAgICAgIG1GbGFnczsKKyAgICBtdXRhYmxlIFJlZ2lvbiAgbURpcnR5OworICAgIHNwPEVHTERpc3BsYXlTdXJmYWNlPiBtRGlzcGxheVN1cmZhY2U7CisgICAgY29weWJpdF9kZXZpY2VfdCogICAgIG1CbGl0RW5naW5lOworICAgIG92ZXJsYXlfY29udHJvbF9kZXZpY2VfdCogbU92ZXJsYXlFbmdpbmU7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9ESVNQTEFZX0hBUkRXQVJFX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZUJhc2UuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlQmFzZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc1ZTVjMgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZUJhc2UuY3BwCkBAIC0wLDAgKzEsNDAzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c2lnbmFsLmg+CisjaW5jbHVkZSA8dGVybWlvcy5oPgorI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvcmVzb3VyY2UuaD4KKworI2luY2x1ZGUgPGxpbnV4L3VuaXN0ZC5oPgorCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlQmFzZS5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHRoZSBzaW0gYnVpbGQgZG9lc24ndCBoYXZlIGdldHRpZAorCisjaWZuZGVmIEhBVkVfR0VUVElECisjIGRlZmluZSBnZXR0aWQgZ2V0cGlkCisjZW5kaWYKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorbmFtZXNwYWNlIGFuZHJvaWQgeworCitzdGF0aWMgY2hhciBjb25zdCAqIGtTbGVlcEZpbGVOYW1lID0gIi9zeXMvcG93ZXIvd2FpdF9mb3JfZmJfc2xlZXAiOworc3RhdGljIGNoYXIgY29uc3QgKiBrV2FrZUZpbGVOYW1lID0gIi9zeXMvcG93ZXIvd2FpdF9mb3JfZmJfd2FrZSI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGtPbGRTbGVlcEZpbGVOYW1lID0gIi9zeXMvYW5kcm9pZF9wb3dlci93YWl0X2Zvcl9mYl9zbGVlcCI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGtPbGRXYWtlRmlsZU5hbWUgPSAiL3N5cy9hbmRyb2lkX3Bvd2VyL3dhaXRfZm9yX2ZiX3dha2UiOworCisvLyBUaGlzIGRpciBleGlzdHMgaWYgdGhlIGZyYW1lYnVmZmVyIGNvbnNvbGUgaXMgcHJlc2VudCwgZWl0aGVyIGJ1aWx0IGludG8KKy8vIHRoZSBrZXJuZWwgb3IgbG9hZGVkIGFzIGEgbW9kdWxlLgorc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBrRmJjb25TeXNEaXIgPSAiL3N5cy9jbGFzcy9ncmFwaGljcy9mYmNvbiI7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRGlzcGxheUhhcmR3YXJlQmFzZTo6RGlzcGxheUV2ZW50VGhyZWFkQmFzZTo6RGlzcGxheUV2ZW50VGhyZWFkQmFzZSgKKyAgICAgICAgY29uc3Qgc3A8U3VyZmFjZUZsaW5nZXI+JiBmbGluZ2VyKQorICAgIDogVGhyZWFkKGZhbHNlKSwgbUZsaW5nZXIoZmxpbmdlcikgeworfQorCitEaXNwbGF5SGFyZHdhcmVCYXNlOjpEaXNwbGF5RXZlbnRUaHJlYWRCYXNlOjp+RGlzcGxheUV2ZW50VGhyZWFkQmFzZSgpIHsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitEaXNwbGF5SGFyZHdhcmVCYXNlOjpEaXNwbGF5RXZlbnRUaHJlYWQ6OkRpc3BsYXlFdmVudFRocmVhZCgKKyAgICAgICAgY29uc3Qgc3A8U3VyZmFjZUZsaW5nZXI+JiBmbGluZ2VyKQorICAgIDogRGlzcGxheUV2ZW50VGhyZWFkQmFzZShmbGluZ2VyKQoreworfQorCitEaXNwbGF5SGFyZHdhcmVCYXNlOjpEaXNwbGF5RXZlbnRUaHJlYWQ6On5EaXNwbGF5RXZlbnRUaHJlYWQoKQoreworfQorCitib29sIERpc3BsYXlIYXJkd2FyZUJhc2U6OkRpc3BsYXlFdmVudFRocmVhZDo6dGhyZWFkTG9vcCgpCit7CisgICAgaW50IGVyciA9IDA7CisgICAgY2hhciBidWY7CisgICAgaW50IGZkOworCisgICAgZmQgPSBvcGVuKGtTbGVlcEZpbGVOYW1lLCBPX1JET05MWSwgMCk7CisgICAgZG8geworICAgICAgZXJyID0gcmVhZChmZCwgJmJ1ZiwgMSk7CisgICAgfSB3aGlsZSAoZXJyIDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisgICAgY2xvc2UoZmQpOworICAgIExPR1dfSUYoZXJyPDAsICJBTkRST0lEX1dBSVRfRk9SX0ZCX1NMRUVQIGZhaWxlZCAoJXMpIiwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICBpZiAoZXJyID49IDApIHsKKyAgICAgICAgc3A8U3VyZmFjZUZsaW5nZXI+IGZsaW5nZXIgPSBtRmxpbmdlci5wcm9tb3RlKCk7CisgICAgICAgIExPR0QoIkFib3V0IHRvIGdpdmUtdXAgc2NyZWVuLCBmbGluZ2VyID0gJXAiLCBmbGluZ2VyLmdldCgpKTsKKyAgICAgICAgaWYgKGZsaW5nZXIgIT0gMCkgeworICAgICAgICAgICAgbUJhcnJpZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIGZsaW5nZXItPnNjcmVlblJlbGVhc2VkKDApOworICAgICAgICAgICAgbUJhcnJpZXIud2FpdCgpOworICAgICAgICB9CisgICAgfQorICAgIGZkID0gb3BlbihrV2FrZUZpbGVOYW1lLCBPX1JET05MWSwgMCk7CisgICAgZG8geworICAgICAgZXJyID0gcmVhZChmZCwgJmJ1ZiwgMSk7CisgICAgfSB3aGlsZSAoZXJyIDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisgICAgY2xvc2UoZmQpOworICAgIExPR1dfSUYoZXJyPDAsICJBTkRST0lEX1dBSVRfRk9SX0ZCX1dBS0UgZmFpbGVkICglcykiLCBzdHJlcnJvcihlcnJubykpOworICAgIGlmIChlcnIgPj0gMCkgeworICAgICAgICBzcDxTdXJmYWNlRmxpbmdlcj4gZmxpbmdlciA9IG1GbGluZ2VyLnByb21vdGUoKTsKKyAgICAgICAgTE9HRCgiU2NyZWVuIGFib3V0IHRvIHJldHVybiwgZmxpbmdlciA9ICVwIiwgZmxpbmdlci5nZXQoKSk7CisgICAgICAgIGlmIChmbGluZ2VyICE9IDApCisgICAgICAgICAgICBmbGluZ2VyLT5zY3JlZW5BY3F1aXJlZCgwKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXR1c190IERpc3BsYXlIYXJkd2FyZUJhc2U6OkRpc3BsYXlFdmVudFRocmVhZDo6cmVsZWFzZVNjcmVlbigpIGNvbnN0Cit7CisgICAgbUJhcnJpZXIub3BlbigpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgRGlzcGxheUhhcmR3YXJlQmFzZTo6RGlzcGxheUV2ZW50VGhyZWFkOjpyZWFkeVRvUnVuKCkKK3sKKyAgICBpZiAoYWNjZXNzKGtTbGVlcEZpbGVOYW1lLCBSX09LKSB8fCBhY2Nlc3Moa1dha2VGaWxlTmFtZSwgUl9PSykpIHsKKyAgICAgICAgaWYgKGFjY2VzcyhrT2xkU2xlZXBGaWxlTmFtZSwgUl9PSykgfHwgYWNjZXNzKGtPbGRXYWtlRmlsZU5hbWUsIFJfT0spKSB7CisgICAgICAgICAgICBMT0dFKCJDb3VsZG4ndCBvcGVuICVzIG9yICVzIiwga1NsZWVwRmlsZU5hbWUsIGtXYWtlRmlsZU5hbWUpOworICAgICAgICAgICAgcmV0dXJuIE5PX0lOSVQ7CisgICAgICAgIH0KKyAgICAgICAga1NsZWVwRmlsZU5hbWUgPSBrT2xkU2xlZXBGaWxlTmFtZTsKKyAgICAgICAga1dha2VGaWxlTmFtZSA9IGtPbGRXYWtlRmlsZU5hbWU7CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgRGlzcGxheUhhcmR3YXJlQmFzZTo6RGlzcGxheUV2ZW50VGhyZWFkOjppbml0Q2hlY2soKSBjb25zdAoreworICAgIHJldHVybiAoKChhY2Nlc3Moa1NsZWVwRmlsZU5hbWUsIFJfT0spID09IDAgJiYKKyAgICAgICAgICAgIGFjY2VzcyhrV2FrZUZpbGVOYW1lLCBSX09LKSA9PSAwKSB8fAorICAgICAgICAgICAgKGFjY2VzcyhrT2xkU2xlZXBGaWxlTmFtZSwgUl9PSykgPT0gMCAmJgorICAgICAgICAgICAgYWNjZXNzKGtPbGRXYWtlRmlsZU5hbWUsIFJfT0spID09IDApKSAmJgorICAgICAgICAgICAgYWNjZXNzKGtGYmNvblN5c0RpciwgRl9PSykgIT0gMCkgPyBOT19FUlJPUiA6IE5PX0lOSVQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworcGlkX3QgRGlzcGxheUhhcmR3YXJlQmFzZTo6Q29uc29sZU1hbmFnZXJUaHJlYWQ6OnNTaWduYWxDYXRjaGVyUGlkID0gMDsKKworRGlzcGxheUhhcmR3YXJlQmFzZTo6Q29uc29sZU1hbmFnZXJUaHJlYWQ6OkNvbnNvbGVNYW5hZ2VyVGhyZWFkKAorICAgICAgICBjb25zdCBzcDxTdXJmYWNlRmxpbmdlcj4mIGZsaW5nZXIpCisgICAgOiBEaXNwbGF5RXZlbnRUaHJlYWRCYXNlKGZsaW5nZXIpLCBjb25zb2xlRmQoLTEpCit7ICAgCisgICAgc1NpZ25hbENhdGNoZXJQaWQgPSAwOworCisgICAgLy8gY3JlYXRlIGEgbmV3IGNvbnNvbGUKKyAgICBjaGFyIGNvbnN0ICogY29uc3QgdHR5ZGV2ID0gIi9kZXYvdHR5MCI7CisgICAgaW50IGZkID0gb3Blbih0dHlkZXYsIE9fUkRXUiB8IE9fU1lOQyk7CisgICAgaWYgKGZkPDApIHsKKyAgICAgICAgTE9HRSgiQ2FuJ3Qgb3BlbiAlcyIsIHR0eWRldik7CisgICAgICAgIHRoaXMtPmNvbnNvbGVGZCA9IC1lcnJubzsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIHRvIG1ha2Ugc3VyZSB0aGF0IHdlIGFyZSBpbiB0ZXh0IG1vZGUKKyAgICBpbnQgcmVzID0gaW9jdGwoZmQsIEtEU0VUTU9ERSwgKHZvaWQqKSBLRF9URVhUKTsKKyAgICBpZiAocmVzPDApIHsKKyAgICAgICAgTE9HRSgiaW9jdGwoJWQsIEtEU0VUTU9ERSwgLi4uKSBmYWlsZWQsIHJlcyAlZCAoJXMpIiwKKyAgICAgICAgICAgICAgICBmZCwgcmVzLCBzdHJlcnJvcihlcnJubykpOworICAgIH0KKyAgICAKKyAgICAvLyBnZXQgdGhlIGN1cnJlbnQgY29uc29sZQorICAgIHN0cnVjdCB2dF9zdGF0IHZzOworICAgIHJlcyA9IGlvY3RsKGZkLCBWVF9HRVRTVEFURSwgJnZzKTsKKyAgICBpZiAocmVzPDApIHsKKyAgICAgICAgTE9HRSgiaW9jdGwoJWQsIFZUX0dFVFNUQVRFLCAuLi4pIGZhaWxlZCwgcmVzICVkICglcykiLAorICAgICAgICAgICAgICAgIGZkLCByZXMsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIHRoaXMtPmNvbnNvbGVGZCA9IC1lcnJubzsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIHN3aXRjaCB0byBjb25zb2xlIDcgKHdoaWNoIGlzIHdoYXQgWCBub3JtYWx5IHVzZXMpCisgICAgaW50IHZ0bnVtID0gNzsKKyAgICBkbyB7CisgICAgICAgIHJlcyA9IGlvY3RsKGZkLCBWVF9BQ1RJVkFURSwgKHZvaWQqKXZ0bnVtKTsKKyAgICB9IHdoaWxlKHJlcyA8IDAgJiYgZXJybm8gPT0gRUlOVFIpOworICAgIGlmIChyZXM8MCkgeworICAgICAgICBMT0dFKCJpb2N0bCglZCwgVlRfQUNUSVZBVEUsIC4uLikgZmFpbGVkLCAlZCAoJXMpIGZvciAlZCIsCisgICAgICAgICAgICAgICAgZmQsIGVycm5vLCBzdHJlcnJvcihlcnJubyksIHZ0bnVtKTsKKyAgICAgICAgdGhpcy0+Y29uc29sZUZkID0gLWVycm5vOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgZG8geworICAgICAgICByZXMgPSBpb2N0bChmZCwgVlRfV0FJVEFDVElWRSwgKHZvaWQqKXZ0bnVtKTsKKyAgICB9IHdoaWxlKHJlcyA8IDAgJiYgZXJybm8gPT0gRUlOVFIpOworICAgIGlmIChyZXM8MCkgeworICAgICAgICBMT0dFKCJpb2N0bCglZCwgVlRfV0FJVEFDVElWRSwgLi4uKSBmYWlsZWQsICVkICVkICVzIGZvciAlZCIsCisgICAgICAgICAgICAgICAgZmQsIHJlcywgZXJybm8sIHN0cmVycm9yKGVycm5vKSwgdnRudW0pOworICAgICAgICB0aGlzLT5jb25zb2xlRmQgPSAtZXJybm87CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBvcGVuIHRoZSBuZXcgY29uc29sZQorICAgIGNsb3NlKGZkKTsKKyAgICBmZCA9IG9wZW4odHR5ZGV2LCBPX1JEV1IgfCBPX1NZTkMpOworICAgIGlmIChmZDwwKSB7CisgICAgICAgIExPR0UoIkNhbid0IG9wZW4gbmV3IGNvbnNvbGUgJXMiLCB0dHlkZXYpOworICAgICAgICB0aGlzLT5jb25zb2xlRmQgPSAtZXJybm87CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvKiBkaXNhYmxlIGNvbnNvbGUgbGluZSBidWZmZXIsIGVjaG8sIC4uLiAqLworICAgIHN0cnVjdCB0ZXJtaW9zIHR0eWFyZzsKKyAgICBpb2N0bChmZCwgVENHRVRTICwgJnR0eWFyZyk7CisgICAgdHR5YXJnLmNfaWZsYWcgPSAwOworICAgIHR0eWFyZy5jX2xmbGFnID0gMDsKKyAgICBpb2N0bChmZCwgVENTRVRTICwgJnR0eWFyZyk7CisKKyAgICAvLyBzZXQgdXAgc2lnbmFscyBzbyB3ZSdyZSBub3RpZmllZCB3aGVuIHRoZSBjb25zb2xlIGNoYW5nZXMKKyAgICAvLyB3ZSBjYW4ndCB1c2UgU0lHVVNSMSBiZWNhdXNlIGl0J3MgdXNlZCBieSB0aGUgamF2YS12bQorICAgIHZtLm1vZGUgPSBWVF9QUk9DRVNTOworICAgIHZtLndhaXR2ID0gMDsKKyAgICB2bS5yZWxzaWcgPSBTSUdVU1IyOworICAgIHZtLmFjcXNpZyA9IFNJR1VOVVNFRDsKKyAgICB2bS5mcnNpZyA9IDA7CisKKyAgICBzdHJ1Y3Qgc2lnYWN0aW9uIGFjdDsKKyAgICBzaWdlbXB0eXNldCgmYWN0LnNhX21hc2spOworICAgIGFjdC5zYV9oYW5kbGVyID0gc2lnSGFuZGxlcjsKKyAgICBhY3Quc2FfZmxhZ3MgPSAwOworICAgIHNpZ2FjdGlvbih2bS5yZWxzaWcsICZhY3QsIE5VTEwpOworCisgICAgc2lnZW1wdHlzZXQoJmFjdC5zYV9tYXNrKTsKKyAgICBhY3Quc2FfaGFuZGxlciA9IHNpZ0hhbmRsZXI7CisgICAgYWN0LnNhX2ZsYWdzID0gMDsKKyAgICBzaWdhY3Rpb24odm0uYWNxc2lnLCAmYWN0LCBOVUxMKTsKKworICAgIHNpZ3NldF90IG1hc2s7CisgICAgc2lnZW1wdHlzZXQoJm1hc2spOworICAgIHNpZ2FkZHNldCgmbWFzaywgdm0ucmVsc2lnKTsKKyAgICBzaWdhZGRzZXQoJm1hc2ssIHZtLmFjcXNpZyk7CisgICAgc2lncHJvY21hc2soU0lHX0JMT0NLLCAmbWFzaywgTlVMTCk7CisKKyAgICAvLyBzd2l0Y2ggdG8gZ3JhcGhpYyBtb2RlCisgICAgcmVzID0gaW9jdGwoZmQsIEtEU0VUTU9ERSwgKHZvaWQqKUtEX0dSQVBISUNTKTsKKyAgICBMT0dXX0lGKHJlczwwLAorICAgICAgICAgICAgImlvY3RsKCVkLCBLRFNFVE1PREUsIEtEX0dSQVBISUNTKSBmYWlsZWQsIHJlcyAlZCIsIGZkLCByZXMpOworCisgICAgdGhpcy0+cHJldl92dF9udW0gPSB2cy52X2FjdGl2ZTsKKyAgICB0aGlzLT52dF9udW0gPSB2dG51bTsKKyAgICB0aGlzLT5jb25zb2xlRmQgPSBmZDsKK30KKworRGlzcGxheUhhcmR3YXJlQmFzZTo6Q29uc29sZU1hbmFnZXJUaHJlYWQ6On5Db25zb2xlTWFuYWdlclRocmVhZCgpCit7ICAgCisgICAgaWYgKHRoaXMtPmNvbnNvbGVGZCA+PSAwKSB7CisgICAgICAgIGludCBmZCA9IHRoaXMtPmNvbnNvbGVGZDsKKyAgICAgICAgaW50IHByZXZfdnRfbnVtID0gdGhpcy0+cHJldl92dF9udW07CisgICAgICAgIGludCByZXM7CisgICAgICAgIGlvY3RsKGZkLCBLRFNFVE1PREUsICh2b2lkKilLRF9URVhUKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgcmVzID0gaW9jdGwoZmQsIFZUX0FDVElWQVRFLCAodm9pZCopcHJldl92dF9udW0pOworICAgICAgICB9IHdoaWxlKHJlcyA8IDAgJiYgZXJybm8gPT0gRUlOVFIpOworICAgICAgICBkbyB7CisgICAgICAgICAgICByZXMgPSBpb2N0bChmZCwgVlRfV0FJVEFDVElWRSwgKHZvaWQqKXByZXZfdnRfbnVtKTsKKyAgICAgICAgfSB3aGlsZShyZXMgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKyAgICAgICAgY2xvc2UoZmQpOyAgICAKKyAgICAgICAgY2hhciBjb25zdCAqIGNvbnN0IHR0eWRldiA9ICIvZGV2L3R0eTAiOworICAgICAgICBmZCA9IG9wZW4odHR5ZGV2LCBPX1JEV1IgfCBPX1NZTkMpOworICAgICAgICBpb2N0bChmZCwgVlRfRElTQUxMT0NBVEUsIDApOworICAgICAgICBjbG9zZShmZCk7CisgICAgfQorfQorCitzdGF0dXNfdCBEaXNwbGF5SGFyZHdhcmVCYXNlOjpDb25zb2xlTWFuYWdlclRocmVhZDo6cmVhZHlUb1J1bigpCit7CisgICAgaWYgKHRoaXMtPmNvbnNvbGVGZCA+PSAwKSB7CisgICAgICAgIHNTaWduYWxDYXRjaGVyUGlkID0gZ2V0dGlkKCk7CisgICAgICAgIAorICAgICAgICBzaWdzZXRfdCBtYXNrOworICAgICAgICBzaWdlbXB0eXNldCgmbWFzayk7CisgICAgICAgIHNpZ2FkZHNldCgmbWFzaywgdm0ucmVsc2lnKTsKKyAgICAgICAgc2lnYWRkc2V0KCZtYXNrLCB2bS5hY3FzaWcpOworICAgICAgICBzaWdwcm9jbWFzayhTSUdfQkxPQ0ssICZtYXNrLCBOVUxMKTsKKworICAgICAgICBpbnQgcmVzID0gaW9jdGwodGhpcy0+Y29uc29sZUZkLCBWVF9TRVRNT0RFLCAmdm0pOworICAgICAgICBpZiAocmVzPDApIHsKKyAgICAgICAgICAgIExPR0UoImlvY3RsKCVkLCBWVF9TRVRNT0RFLCAuLi4pIGZhaWxlZCwgJWQgKCVzKSIsCisgICAgICAgICAgICAgICAgICAgIHRoaXMtPmNvbnNvbGVGZCwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gdGhpcy0+Y29uc29sZUZkOworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZUJhc2U6OkNvbnNvbGVNYW5hZ2VyVGhyZWFkOjpyZXF1ZXN0RXhpdCgpCit7CisgICAgVGhyZWFkOjpyZXF1ZXN0RXhpdCgpOworICAgIGlmIChzU2lnbmFsQ2F0Y2hlclBpZCAhPSAwKSB7CisgICAgICAgIC8vIHdha2UgdGhlIHRocmVhZCB1cAorICAgICAgICBraWxsKHNTaWduYWxDYXRjaGVyUGlkLCBTSUdJTlQpOworICAgICAgICAvLyB3YWl0IGZvciBpdC4uLgorICAgIH0KK30KKwordm9pZCBEaXNwbGF5SGFyZHdhcmVCYXNlOjpDb25zb2xlTWFuYWdlclRocmVhZDo6c2lnSGFuZGxlcihpbnQgc2lnKQoreworICAgIC8vIHJlc2VuZCB0aGUgc2lnbmFsIHRvIG91ciBzaWduYWwgY2F0Y2hlciB0aHJlYWQKKyAgICBMT0dXKCJyZWNlaXZlZCBzaWduYWwgJWQgaW4gdGhyZWFkICVkLCByZXNlbmRpbmcgdG8gJWQiLAorICAgICAgICAgICAgc2lnLCBnZXR0aWQoKSwgc1NpZ25hbENhdGNoZXJQaWQpOworCisgICAgLy8gd2UgYWJzb2x1dGVseSBuZWVkIHRoZSBkZWxheXMgYmVsb3cgYmVjYXVzZSB3aXRob3V0IHRoZW0KKyAgICAvLyBvdXIgbWFpbiB0aHJlYWQgbmV2ZXIgZ2V0cyBhIGNoYW5jZSB0byBoYW5kbGUgdGhlIHNpZ25hbC4KKyAgICB1c2xlZXAoMTAwMDApOworICAgIGtpbGwoc1NpZ25hbENhdGNoZXJQaWQsIHNpZyk7CisgICAgdXNsZWVwKDEwMDAwKTsKK30KKworc3RhdHVzX3QgRGlzcGxheUhhcmR3YXJlQmFzZTo6Q29uc29sZU1hbmFnZXJUaHJlYWQ6OnJlbGVhc2VTY3JlZW4oKSBjb25zdAoreworICAgIGludCBmZCA9IHRoaXMtPmNvbnNvbGVGZDsKKyAgICBpbnQgZXJyID0gaW9jdGwoZmQsIFZUX1JFTERJU1AsICh2b2lkKikxKTsKKyAgICBMT0dFX0lGKGVycjwwLCAiaW9jdGwoJWQsIFZUX1JFTERJU1AsIDEpIGZhaWxlZCAlZCAoJXMpIiwKKyAgICAgICAgZmQsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOworICAgIHJldHVybiAoZXJyPDApID8gKC1lcnJubykgOiBzdGF0dXNfdChOT19FUlJPUik7Cit9CisKK2Jvb2wgRGlzcGxheUhhcmR3YXJlQmFzZTo6Q29uc29sZU1hbmFnZXJUaHJlYWQ6OnRocmVhZExvb3AoKQoreworICAgIHNpZ3NldF90IG1hc2s7CisgICAgc2lnZW1wdHlzZXQoJm1hc2spOworICAgIHNpZ2FkZHNldCgmbWFzaywgdm0ucmVsc2lnKTsKKyAgICBzaWdhZGRzZXQoJm1hc2ssIHZtLmFjcXNpZyk7CisKKyAgICBpbnQgc2lnID0gMDsKKyAgICBzaWd3YWl0KCZtYXNrLCAmc2lnKTsKKworICAgIGlmIChzaWcgPT0gdm0ucmVsc2lnKSB7CisgICAgICAgIHNwPFN1cmZhY2VGbGluZ2VyPiBmbGluZ2VyID0gbUZsaW5nZXIucHJvbW90ZSgpOworICAgICAgICAvL0xPR0QoIkFib3V0IHRvIGdpdmUtdXAgc2NyZWVuLCBmbGluZ2VyID0gJXAiLCBmbGluZ2VyLmdldCgpKTsKKyAgICAgICAgaWYgKGZsaW5nZXIgIT0gMCkKKyAgICAgICAgICAgIGZsaW5nZXItPnNjcmVlblJlbGVhc2VkKDApOworICAgIH0gZWxzZSBpZiAoc2lnID09IHZtLmFjcXNpZykgeworICAgICAgICBzcDxTdXJmYWNlRmxpbmdlcj4gZmxpbmdlciA9IG1GbGluZ2VyLnByb21vdGUoKTsKKyAgICAgICAgLy9MT0dEKCJTY3JlZW4gYWJvdXQgdG8gcmV0dXJuLCBmbGluZ2VyID0gJXAiLCBmbGluZ2VyLmdldCgpKTsKKyAgICAgICAgaWYgKGZsaW5nZXIgIT0gMCkgCisgICAgICAgICAgICBmbGluZ2VyLT5zY3JlZW5BY3F1aXJlZCgwKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXR1c190IERpc3BsYXlIYXJkd2FyZUJhc2U6OkNvbnNvbGVNYW5hZ2VyVGhyZWFkOjppbml0Q2hlY2soKSBjb25zdAoreworICAgIHJldHVybiBjb25zb2xlRmQgPj0gMCA/IE5PX0VSUk9SIDogTk9fSU5JVDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitEaXNwbGF5SGFyZHdhcmVCYXNlOjpEaXNwbGF5SGFyZHdhcmVCYXNlKGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlciwKKyAgICAgICAgdWludDMyX3QgZGlzcGxheUluZGV4KSAKKyAgICA6IG1DYW5EcmF3KHRydWUpCit7CisgICAgbURpc3BsYXlFdmVudFRocmVhZCA9IG5ldyBEaXNwbGF5RXZlbnRUaHJlYWQoZmxpbmdlcik7CisgICAgaWYgKG1EaXNwbGF5RXZlbnRUaHJlYWQtPmluaXRDaGVjaygpICE9IE5PX0VSUk9SKSB7CisgICAgICAgIC8vIGZhbGwtYmFjayBvbiB0aGUgY29uc29sZQorICAgICAgICBtRGlzcGxheUV2ZW50VGhyZWFkID0gbmV3IENvbnNvbGVNYW5hZ2VyVGhyZWFkKGZsaW5nZXIpOworICAgIH0KK30KKworRGlzcGxheUhhcmR3YXJlQmFzZTo6fkRpc3BsYXlIYXJkd2FyZUJhc2UoKQoreworICAgIC8vIHJlcXVlc3QgZXhpdAorICAgIG1EaXNwbGF5RXZlbnRUaHJlYWQtPnJlcXVlc3RFeGl0QW5kV2FpdCgpOworfQorCisKK2Jvb2wgRGlzcGxheUhhcmR3YXJlQmFzZTo6Y2FuRHJhdygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1DYW5EcmF3OworfQorCit2b2lkIERpc3BsYXlIYXJkd2FyZUJhc2U6OnJlbGVhc2VTY3JlZW4oKSBjb25zdAoreworICAgIHN0YXR1c190IGVyciA9IG1EaXNwbGF5RXZlbnRUaHJlYWQtPnJlbGVhc2VTY3JlZW4oKTsKKyAgICBpZiAoZXJyID49IDApIHsKKyAgICAgICAgLy9MT0dEKCJzY3JlZW4gZ2l2ZW4tdXAiKTsKKyAgICAgICAgbUNhbkRyYXcgPSBmYWxzZTsKKyAgICB9Cit9CisKK3ZvaWQgRGlzcGxheUhhcmR3YXJlQmFzZTo6YWNxdWlyZVNjcmVlbigpIGNvbnN0Cit7CisgICAgc3RhdHVzX3QgZXJyID0gbURpc3BsYXlFdmVudFRocmVhZC0+YWNxdWlyZVNjcmVlbigpOworICAgIGlmIChlcnIgPj0gMCkgeworICAgICAgICAvL0xPR0QoInNjcmVlbiByZXR1cm5lZCIpOworICAgICAgICBtQ2FuRHJhdyA9IHRydWU7CisgICAgfQorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlQmFzZS5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9EaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlQmFzZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzNjliYjgKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0Rpc3BsYXlIYXJkd2FyZS9EaXNwbGF5SGFyZHdhcmVCYXNlLmgKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9ESVNQTEFZX0hBUkRXQVJFX0JBU0VfSAorI2RlZmluZSBBTkRST0lEX0RJU1BMQVlfSEFSRFdBUkVfQkFTRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPGxpbnV4L2tkLmg+CisjaW5jbHVkZSA8bGludXgvdnQuaD4KKyNpbmNsdWRlICJCYXJyaWVyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgU3VyZmFjZUZsaW5nZXI7IAorCitjbGFzcyBEaXNwbGF5SGFyZHdhcmVCYXNlCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgRGlzcGxheUhhcmR3YXJlQmFzZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGRpc3BsYXlJbmRleCk7CisKKyAgICAgICAgICAgICAgICB+RGlzcGxheUhhcmR3YXJlQmFzZSgpOworCisgICAgLy8gY29uc29sZSBtYW5hZ21lbnQKKyAgICB2b2lkIHJlbGVhc2VTY3JlZW4oKSBjb25zdDsKKyAgICB2b2lkIGFjcXVpcmVTY3JlZW4oKSBjb25zdDsKKyAgICBib29sIGNhbkRyYXcoKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBjbGFzcyBEaXNwbGF5RXZlbnRUaHJlYWRCYXNlIDogcHVibGljIFRocmVhZCB7CisgICAgcHJvdGVjdGVkOgorICAgICAgICB3cDxTdXJmYWNlRmxpbmdlcj4gbUZsaW5nZXI7CisgICAgcHVibGljOgorICAgICAgICBEaXNwbGF5RXZlbnRUaHJlYWRCYXNlKGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlcik7CisgICAgICAgIHZpcnR1YWwgfkRpc3BsYXlFdmVudFRocmVhZEJhc2UoKTsKKyAgICAgICAgdmlydHVhbCB2b2lkIG9uRmlyc3RSZWYoKSB7CisgICAgICAgICAgICBydW4oIkRpc3BsYXlFdmVudFRocmVhZCIsIFBSSU9SSVRZX1VSR0VOVF9ESVNQTEFZKTsKKyAgICAgICAgfQorICAgICAgICB2aXJ0dWFsIHN0YXR1c190IGFjcXVpcmVTY3JlZW4oKSBjb25zdCB7IHJldHVybiBOT19FUlJPUjsgfTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCByZWxlYXNlU2NyZWVuKCkgY29uc3QgeyByZXR1cm4gTk9fRVJST1I7IH07CisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgaW5pdENoZWNrKCkgY29uc3QgPSAwOworICAgIH07CisKKyAgICBjbGFzcyBEaXNwbGF5RXZlbnRUaHJlYWQgOiBwdWJsaWMgRGlzcGxheUV2ZW50VGhyZWFkQmFzZSAKKyAgICB7CisgICAgICAgIG11dGFibGUgQmFycmllciBtQmFycmllcjsKKyAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgRGlzcGxheUV2ZW50VGhyZWFkKGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlcik7CisgICAgICAgIHZpcnR1YWwgfkRpc3BsYXlFdmVudFRocmVhZCgpOworICAgICAgICB2aXJ0dWFsIGJvb2wgdGhyZWFkTG9vcCgpOworICAgICAgICB2aXJ0dWFsIHN0YXR1c190IHJlYWR5VG9SdW4oKTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCByZWxlYXNlU2NyZWVuKCkgY29uc3Q7CisgICAgICAgIHZpcnR1YWwgc3RhdHVzX3QgaW5pdENoZWNrKCkgY29uc3Q7CisgICAgfTsKKworICAgIGNsYXNzIENvbnNvbGVNYW5hZ2VyVGhyZWFkIDogcHVibGljIERpc3BsYXlFdmVudFRocmVhZEJhc2UgCisgICAgeworICAgICAgICBpbnQgY29uc29sZUZkOworICAgICAgICBpbnQgdnRfbnVtOworICAgICAgICBpbnQgcHJldl92dF9udW07CisgICAgICAgIHZ0X21vZGUgdm07CisgICAgICAgIHN0YXRpYyB2b2lkIHNpZ0hhbmRsZXIoaW50IHNpZyk7CisgICAgICAgIHN0YXRpYyBwaWRfdCBzU2lnbmFsQ2F0Y2hlclBpZDsKKyAgICBwdWJsaWM6CisgICAgICAgICAgICAgICAgQ29uc29sZU1hbmFnZXJUaHJlYWQoY29uc3Qgc3A8U3VyZmFjZUZsaW5nZXI+JiBmbGluZ2VyKTsKKyAgICAgICAgdmlydHVhbCB+Q29uc29sZU1hbmFnZXJUaHJlYWQoKTsKKyAgICAgICAgdmlydHVhbCBib29sIHRocmVhZExvb3AoKTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCByZWFkeVRvUnVuKCk7CisgICAgICAgIHZpcnR1YWwgdm9pZCByZXF1ZXN0RXhpdCgpOworICAgICAgICB2aXJ0dWFsIHN0YXR1c190IHJlbGVhc2VTY3JlZW4oKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCBpbml0Q2hlY2soKSBjb25zdDsKKyAgICB9OworCisgICAgc3A8RGlzcGxheUV2ZW50VGhyZWFkQmFzZT4gIG1EaXNwbGF5RXZlbnRUaHJlYWQ7CisgICAgbXV0YWJsZSBpbnQgICAgICAgICAgICAgICAgIG1DYW5EcmF3OworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfRElTUExBWV9IQVJEV0FSRV9CQVNFX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvR1BVSGFyZHdhcmUvR1BVSGFyZHdhcmUuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9HUFVIYXJkd2FyZS9HUFVIYXJkd2FyZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWI3NWY5OQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvR1BVSGFyZHdhcmUvR1BVSGFyZHdhcmUuY3BwCkBAIC0wLDAgKzEsNTgxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorCisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9JQmluZGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5QmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBQbWVtLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5SGVhcEJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0b3BXYXRjaC5oPgorCisjaW5jbHVkZSA8dWkvSVN1cmZhY2VDb21wb3Nlci5oPgorCisjaW5jbHVkZSAiVlJhbUhlYXAuaCIKKyNpbmNsdWRlICJHUFVIYXJkd2FyZS5oIgorCisjaWYgSEFWRV9BTkRST0lEX09TCisjaW5jbHVkZSA8bGludXgvYW5kcm9pZF9wbWVtLmg+CisjZW5kaWYKKworI2luY2x1ZGUgIkdQVUhhcmR3YXJlL0dQVUhhcmR3YXJlLmgiCisKKworLyogCisgKiBNYW5hZ2UgdGhlIEdQVS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyB2ZXJ5IHNwZWNpZmljIHRvIHRoZSBHMS4KKyAqIFRoZXJlIGFyZSBubyBhYnN0cmFjdGlvbiBoZXJlLiAKKyAqIAorICogQWxsIHRoaXMgY29kZSB3aWxsIHNvb24gZ28tYXdheSBhbmQgYmUgcmVwbGFjZWQgYnkgYSBuZXcgYXJjaGl0ZWN0dXJlCisgKiBmb3IgbWFuYWdpbmcgZ3JhcGhpY3MgYWNjZWxlcmF0b3JzLgorICogCisgKiBJbiB0aGUgbWVhbnRpbWUsIGl0IGlzIGNvbmNlcHR1YWxseSBwb3NzaWJsZSB0byBpbnN0YW50aWF0ZSBhCisgKiBHUFVIYXJkd2FyZUludGVyZmFjZSBmb3IgYW5vdGhlciBHUFUgKHNlZSBHUFVGYWN0b3J5IGF0IHRoZSBib3R0b20KKyAqIG9mIHRoaXMgZmlsZSk7IHByYWN0aWNhbGx5Li4uIGRvdWJ0ZnVsLgorICogCisgKi8KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgR1BVQ2xpZW50SGVhcDsKK2NsYXNzIEdQVUFyZWFIZWFwOworCitjbGFzcyBHUFVIYXJkd2FyZSA6IHB1YmxpYyBHUFVIYXJkd2FyZUludGVyZmFjZSwgcHVibGljIElCaW5kZXI6OkRlYXRoUmVjaXBpZW50Cit7CitwdWJsaWM6CisgICAgc3RhdGljIGNvbnN0IGludCBHUFVfUkVTRVJWRURfU0laRTsKKyAgICBzdGF0aWMgY29uc3QgaW50IEdQVVJfU0laRTsKKworICAgICAgICAgICAgR1BVSGFyZHdhcmUoKTsKKyAgICB2aXJ0dWFsIH5HUFVIYXJkd2FyZSgpOworICAgIAorICAgIHZpcnR1YWwgdm9pZCByZXZva2UoaW50IHBpZCk7CisgICAgdmlydHVhbCBzcDxNZW1vcnlEZWFsZXI+IHJlcXVlc3QoaW50IHBpZCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCByZXF1ZXN0KGludCBwaWQsIAorICAgICAgICAgICAgY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssCisgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjpncHVfaW5mb190KiBncHUpOworCisgICAgdmlydHVhbCBzdGF0dXNfdCBmcmllbmRseVJldm9rZSgpOworICAgIHZpcnR1YWwgdm9pZCB1bmNvbmRpdGlvbmFsUmV2b2tlKCk7CisgICAgCisgICAgdmlydHVhbCBwaWRfdCBnZXRPd25lcigpIGNvbnN0IHsgcmV0dXJuIG1Pd25lcjsgfQorCisgICAgLy8gdXNlZCBmb3IgZGVidWdnaW5nIG9ubHkuLi4KKyAgICB2aXJ0dWFsIHNwPFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I+IGdldEFsbG9jYXRvcigpIGNvbnN0OworCitwcml2YXRlOgorICAgIAorICAgIAorICAgIGVudW0geworICAgICAgICBOT19PV05FUiA9IC0xLAorICAgIH07CisgICAgICAgIAorICAgIHN0cnVjdCBHUFVBcmVhIHsKKyAgICAgICAgc3A8R1BVQXJlYUhlYXA+ICAgICBoZWFwOworICAgICAgICBzcDxNZW1vcnlIZWFwUG1lbT4gIGNsaWVudEhlYXA7CisgICAgICAgIHNwPElNZW1vcnk+IG1hcCgpOworICAgIH07CisgICAgCisgICAgc3RydWN0IENsaWVudCB7CisgICAgICAgIHBpZF90ICAgICAgIHBpZDsKKyAgICAgICAgR1BVQXJlYSAgICAgc21pOworICAgICAgICBHUFVBcmVhICAgICBlYmk7CisgICAgICAgIEdQVUFyZWEgICAgIHJlZzsKKyAgICAgICAgdm9pZCBjcmVhdGVDbGllbnRIZWFwcygpOworICAgICAgICB2b2lkIHJldm9rZUFsbEhlYXBzKCk7CisgICAgfTsKKyAgICAKKyAgICBDbGllbnQmIGdldENsaWVudExvY2tlZChwaWRfdCBwaWQpOworICAgIHN0YXR1c190IHJlcXVlc3RMb2NrZWQoaW50IHBpZCk7CisgICAgdm9pZCByZWxlYXNlTG9ja2VkKCk7CisgICAgdm9pZCB0YWtlQmFja0dQVUxvY2tlZCgpOworICAgIHZvaWQgcmVnaXN0ZXJDYWxsYmFja0xvY2tlZChjb25zdCBzcDxJR1BVQ2FsbGJhY2s+JiBjYWxsYmFjaywKKyAgICAgICAgICAgIENsaWVudCYgY2xpZW50KTsKKworICAgIHZpcnR1YWwgdm9pZCBiaW5kZXJEaWVkKGNvbnN0IHdwPElCaW5kZXI+JiB3aG8pOworCisgICAgbXV0YWJsZSBNdXRleCAgICAgICAgICAgbUxvY2s7CisgICAgc3A8R1BVQXJlYUhlYXA+ICAgICAgICAgbVNNSUhlYXA7CisgICAgc3A8R1BVQXJlYUhlYXA+ICAgICAgICAgbUVCSUhlYXA7CisgICAgc3A8R1BVQXJlYUhlYXA+ICAgICAgICAgbVJFR0hlYXA7CisKKyAgICBLZXllZFZlY3RvcjxwaWRfdCwgQ2xpZW50PiBtQ2xpZW50czsKKyAgICBEZWZhdWx0S2V5ZWRWZWN0b3I8IHdwPElCaW5kZXI+LCBwaWRfdCA+IG1SZWdpc3RlcmVkQ2xpZW50czsKKyAgICAKKyAgICBwaWRfdCAgICAgICAgICAgICAgICAgICBtT3duZXI7CisKKyAgICBzcDxNZW1vcnlEZWFsZXI+ICAgICAgICBtQ3VycmVudEFsbG9jYXRvcjsKKyAgICBzcDxJR1BVQ2FsbGJhY2s+ICAgICAgICBtQ2FsbGJhY2s7CisgICAgCisgICAgc3A8U2ltcGxlQmVzdEZpdEFsbG9jYXRvcj4gIG1BbGxvY2F0b3I7CisKKyAgICBDb25kaXRpb24gICAgICAgICAgICAgICBtQ29uZGl0aW9uOworfTsKKworLy8gc2l6ZSByZXNlcnZlZCBmb3IgR1BVIHN1cmZhY2VzCisvLyAxMjAwIEtCIGZpdHMgZXhhY3RseToKKy8vICAtIHR3byAzMjAqNDgwIDE2LWJpdHMgZG91YmxlLWJ1ZmZlcmVkIHN1cmZhY2VzCisvLyAgLSBvbmUgMzIwKjQ4MCAzMi1iaXRzIGRvdWJsZS1idWZmZXJlZCBzdXJmYWNlCisvLyAgLSBvbmUgMzIwKjI0MCAxNi1iaXRzIGRvdWJsZS1idWZmZXJlZCwgNHggYW50aS1hbGlhc2VkIHN1cmZhY2UKK2NvbnN0IGludCBHUFVIYXJkd2FyZTo6R1BVX1JFU0VSVkVEX1NJWkUgID0gMTIwMCAqIDEwMjQ7Citjb25zdCBpbnQgR1BVSGFyZHdhcmU6OkdQVVJfU0laRSAgICAgICAgICA9IDEgKiAxMDI0ICogMTAyNDsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8qIAorICogR1BVSGFuZGxlIGlzIGEgc3BlY2lhbCBJTWVtb3J5IGdpdmVuIHRvIHRoZSBjbGllbnQuIEl0IHJlcHJlc2VudHMgdGhlaXIKKyAqIGhhbmRsZSB0byB0aGUgR1BVLiBPbmNlIHRoZXkgZ2l2ZSBpdCB1cCwgdGhleSBsb29zZSBHUFUgYWNjZXNzLCBvciBpZgorICogdGhleSBleHBsaWNpdGx5IHJldm9rZSB0aGVpciBhY2Nlc3MgdGhyb3VnaCB0aGUgYmluZGVyIGNvZGUgMTAwMC4KKyAqIEluIGJvdGggY2FzZXMsIHRoaXMgdHJpZ2dlcnMgYSBjYWxsYmFjayB0byByZXZva2UoKQorICogZmlyc3QsIGFuZCB0aGVuIGFjdHVhbGx5IHBvd2VycyBkb3duIHRoZSBjaGlwLgorICogCisgKiBJbiB0aGUgY2FzZSBvZiBhIG1pc2JlaGF2aW5nIGFwcCwgR1BVSGFyZHdhcmUgY2FuIGFzayBmb3IgYW4gaW1tZWRpYXRlCisgKiByZWxlYXNlIG9mIHRoZSBHUFUgdG8gdGhlIHRhcmdldCBwcm9jZXNzIHdoaWNoIHNob3VsZCBhbnN3ZXIgYnkgY2FsbGluZworICogY29kZSAxMDAwIG9uIEdQVUhhbmRsZS4gSWYgaXQgZG9lc24ndCBpbiBhIHRpbWVseSBtYW5uZXIsIHRoZSBHUFUgd2lsbAorICogYmUgcmV2b2tlZCBmcm9tIHVuZGVyIHRoZWlyIGZlZXQuCisgKiAKKyAqIFdlIHNob3VsZCBuZXZlciBob2xkIGEgc3Ryb25nIHJlZmVyZW5jZSBvbiBHUFVIYW5kbGUuIEluIHByYWN0aWNlIHRoaXMKKyAqIHNob3VsZG4ndCBiZSBhIGJpZyBpc3N1ZSB0aG91Z2ggYmVjYXVzZSBjbGllbnRzIHNob3VsZCB1c2UgY29kZSAxMDAwIGFuZAorICogbm90IHJlbHkgb24gdGhlIGR0b3IgYmVpbmcgY2FsbGVkLgorICogCisgKi8KKworY2xhc3MgR1BVQ2xpZW50SGVhcCA6IHB1YmxpYyBNZW1vcnlIZWFwUG1lbQoreworcHVibGljOgorICAgIEdQVUNsaWVudEhlYXAoY29uc3Qgd3A8R1BVSGFyZHdhcmU+JiBncHUsIAorICAgICAgICAgICAgY29uc3Qgc3A8TWVtb3J5SGVhcEJhc2U+JiBoZWFwKQorICAgICAgICA6ICBNZW1vcnlIZWFwUG1lbShoZWFwKSwgbUdQVShncHUpIHsgfQorcHJvdGVjdGVkOgorICAgIHdwPEdQVUhhcmR3YXJlPiBtR1BVOworfTsKKworY2xhc3MgR1BVQXJlYUhlYXAgOiBwdWJsaWMgTWVtb3J5SGVhcEJhc2UKK3sKK3B1YmxpYzoKKyAgICBHUFVBcmVhSGVhcChjb25zdCB3cDxHUFVIYXJkd2FyZT4mIGdwdSwKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNvbnN0IHZyYW0sIHNpemVfdCBzaXplPTAsIHNpemVfdCByZXNlcnZlZD0wKQorICAgIDogTWVtb3J5SGVhcEJhc2UodnJhbSwgc2l6ZSksIG1HUFUoZ3B1KSB7IAorICAgICAgICBpZiAoYmFzZSgpICE9IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgICAgIGlmIChyZXNlcnZlZCA9PSAwKQorICAgICAgICAgICAgICAgIHJlc2VydmVkID0gdmlydHVhbFNpemUoKTsKKyAgICAgICAgICAgIG1BbGxvY2F0b3IgPSBuZXcgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcihyZXNlcnZlZCk7CisgICAgICAgIH0KKyAgICB9CisgICAgdmlydHVhbCBzcDxNZW1vcnlIZWFwUG1lbT4gY3JlYXRlQ2xpZW50SGVhcCgpIHsKKyAgICAgICAgc3A8TWVtb3J5SGVhcEJhc2U+IHBhcmVudEhlYXAodGhpcyk7CisgICAgICAgIHJldHVybiBuZXcgR1BVQ2xpZW50SGVhcChtR1BVLCBwYXJlbnRIZWFwKTsKKyAgICB9CisgICAgdmlydHVhbCBjb25zdCBzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiYgZ2V0QWxsb2NhdG9yKCkgY29uc3QgeworICAgICAgICByZXR1cm4gbUFsbG9jYXRvcjsgCisgICAgfQorcHJpdmF0ZToKKyAgICBzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiAgbUFsbG9jYXRvcjsKK3Byb3RlY3RlZDoKKyAgICB3cDxHUFVIYXJkd2FyZT4gbUdQVTsKK307CisKK2NsYXNzIEdQVVJlZ2lzdGVySGVhcCA6IHB1YmxpYyBHUFVBcmVhSGVhcAoreworcHVibGljOgorICAgIEdQVVJlZ2lzdGVySGVhcChjb25zdCBzcDxHUFVIYXJkd2FyZT4mIGdwdSkKKyAgICAgICAgOiBHUFVBcmVhSGVhcChncHUsICIvZGV2L2h3M2QiLCBHUFVIYXJkd2FyZTo6R1BVUl9TSVpFKSB7IH0KKyAgICB2aXJ0dWFsIHNwPE1lbW9yeUhlYXBQbWVtPiBjcmVhdGVDbGllbnRIZWFwKCkgeworICAgICAgICBzcDxNZW1vcnlIZWFwQmFzZT4gcGFyZW50SGVhcCh0aGlzKTsKKyAgICAgICAgcmV0dXJuIG5ldyBNZW1vcnlIZWFwUmVncyhtR1BVLCBwYXJlbnRIZWFwKTsKKyAgICB9Citwcml2YXRlOgorICAgIGNsYXNzIE1lbW9yeUhlYXBSZWdzIDogcHVibGljIEdQVUNsaWVudEhlYXAgIHsKKyAgICBwdWJsaWM6CisgICAgICAgIE1lbW9yeUhlYXBSZWdzKGNvbnN0IHdwPEdQVUhhcmR3YXJlPiYgZ3B1LCAKKyAgICAgICAgICAgICBjb25zdCBzcDxNZW1vcnlIZWFwQmFzZT4mIGhlYXApCisgICAgICAgICAgICA6IEdQVUNsaWVudEhlYXAoZ3B1LCBoZWFwKSB7IH0KKyAgICAgICAgc3A8TWVtb3J5SGVhcFBtZW06Ok1lbW9yeVBtZW0+IGNyZWF0ZU1lbW9yeShzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSk7CisgICAgICAgIHZpcnR1YWwgdm9pZCByZXZva2UoKTsKKyAgICBwcml2YXRlOgorICAgICAgICBjbGFzcyBHUFVIYW5kbGUgOiBwdWJsaWMgTWVtb3J5SGVhcFBtZW06Ok1lbW9yeVBtZW0geworICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICBHUFVIYW5kbGUoY29uc3Qgc3A8R1BVSGFyZHdhcmU+JiBncHUsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwPE1lbW9yeUhlYXBQbWVtPiYgaGVhcCkKKyAgICAgICAgICAgICAgICA6IE1lbW9yeUhlYXBQbWVtOjpNZW1vcnlQbWVtKGhlYXApLCAKKyAgICAgICAgICAgICAgICAgIG1HUFUoZ3B1KSwgbU93bmVyKGdwdS0+Z2V0T3duZXIoKSkgeyB9CisgICAgICAgICAgICB2aXJ0dWFsIH5HUFVIYW5kbGUoKTsKKyAgICAgICAgICAgIHZpcnR1YWwgc3A8SU1lbW9yeUhlYXA+IGdldE1lbW9yeSgKKyAgICAgICAgICAgICAgICAgICAgc3NpemVfdCogb2Zmc2V0LCBzaXplX3QqIHNpemUpIGNvbnN0OworICAgICAgICAgICAgdmlydHVhbCB2b2lkIHJldm9rZSgpIHsgfTsKKyAgICAgICAgICAgIHZpcnR1YWwgc3RhdHVzX3Qgb25UcmFuc2FjdCgKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCAKKyAgICAgICAgICAgICAgICAgICAgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpOworICAgICAgICBwcml2YXRlOgorICAgICAgICAgICAgdm9pZCByZXZva2VOb3RpZmljYXRpb24oKTsKKyAgICAgICAgICAgIHdwPEdQVUhhcmR3YXJlPiBtR1BVOworICAgICAgICAgICAgcGlkX3QgbU93bmVyOworICAgICAgICB9OworICAgIH07Cit9OworCitHUFVSZWdpc3RlckhlYXA6Ok1lbW9yeUhlYXBSZWdzOjpHUFVIYW5kbGU6On5HUFVIYW5kbGUoKSB7IAorICAgIC8vTE9HRCgiR1BVSGFuZGxlICVwIHJlbGVhc2VkLCByZXZva2luZyBHUFUiLCB0aGlzKTsKKyAgICByZXZva2VOb3RpZmljYXRpb24oKTsgCit9Cit2b2lkIEdQVVJlZ2lzdGVySGVhcDo6TWVtb3J5SGVhcFJlZ3M6OkdQVUhhbmRsZTo6cmV2b2tlTm90aWZpY2F0aW9uKCkgIHsKKyAgICBzcDxHUFVIYXJkd2FyZT4gaHcobUdQVS5wcm9tb3RlKCkpOworICAgIGlmIChodyAhPSAwKSB7CisgICAgICAgIGh3LT5yZXZva2UobU93bmVyKTsKKyAgICB9Cit9CitzcDxJTWVtb3J5SGVhcD4gR1BVUmVnaXN0ZXJIZWFwOjpNZW1vcnlIZWFwUmVnczo6R1BVSGFuZGxlOjpnZXRNZW1vcnkoCisgICAgICAgIHNzaXplX3QqIG9mZnNldCwgc2l6ZV90KiBzaXplKSBjb25zdAoreworICAgIHNwPE1lbW9yeUhlYXBQbWVtPiBoZWFwID0gZ2V0SGVhcCgpOworICAgIGlmIChvZmZzZXQpICpvZmZzZXQgPSAwOworICAgIGlmIChzaXplKSAgICpzaXplID0gaGVhcCAhPTAgPyBoZWFwLT52aXJ0dWFsU2l6ZSgpIDogMDsKKyAgICByZXR1cm4gaGVhcDsKK30KK3N0YXR1c190IEdQVVJlZ2lzdGVySGVhcDo6TWVtb3J5SGVhcFJlZ3M6OkdQVUhhbmRsZTo6b25UcmFuc2FjdCgKKyAgICAgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzdGF0dXNfdCBlcnIgPSBCbk1lbW9yeTo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworICAgIGlmIChlcnIgPT0gVU5LTk9XTl9UUkFOU0FDVElPTiAmJiBjb2RlID09IDEwMDApIHsKKyAgICAgICAgaW50IGNhbGxpbmdQaWQgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCk7CisgICAgICAgIC8vTE9HRCgicGlkICVkIHZvbHVudGFyaWx5IHJldm9raW5nIGdwdSIsIGNhbGxpbmdQaWQpOworICAgICAgICBpZiAoY2FsbGluZ1BpZCA9PSBtT3duZXIpIHsKKyAgICAgICAgICAgIHJldm9rZU5vdGlmaWNhdGlvbigpOworICAgICAgICAgICAgLy8gd2UndmUgcmV2b2tlZCB0aGUgR1BVLCBkb24ndCBkbyBpdCBhZ2FpbiBsYXRlciB3aGVuIHdlCisgICAgICAgICAgICAvLyBhcmUgZGVzdHJveWVkLgorICAgICAgICAgICAgbUdQVS5jbGVhcigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HVygiJWQgcmV2b2tpbmcgc29tZW9uZSBlbHNlJ3MgZ3B1PyAob3duZXI9JWQpIiwKKyAgICAgICAgICAgICAgICAgICAgY2FsbGluZ1BpZCwgbU93bmVyKTsgICAgICAgICAgICAKKyAgICAgICAgfQorICAgICAgICBlcnIgPSBOT19FUlJPUjsKKyAgICB9CisgICAgcmV0dXJuIGVycjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworc3A8TWVtb3J5SGVhcFBtZW06Ok1lbW9yeVBtZW0+IEdQVVJlZ2lzdGVySGVhcDo6TWVtb3J5SGVhcFJlZ3M6OmNyZWF0ZU1lbW9yeSgKKyAgICAgICAgc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpCit7CisgICAgc3A8R1BVSGFuZGxlPiBtZW1vcnk7CisgICAgc3A8R1BVSGFyZHdhcmU+IGdwdSA9IG1HUFUucHJvbW90ZSgpOworICAgIGlmIChoZWFwSUQoKT4wICYmIGdwdSE9MCkgeworI2lmIEhBVkVfQU5EUk9JRF9PUworICAgICAgICAvKiB0aGlzIGlzIHdoZXJlIHRoZSBHUFUgaXMgcG93ZXJlZCBvbiBhbmQgdGhlIHJlZ2lzdGVycyBhcmUgbWFwcGVkCisgICAgICAgICAqIGluIHRoZSBjbGllbnQgKi8KKyAgICAgICAgLy9MT0dEKCJpb2N0bChIVzNEX0dSQU5UX0dQVSkiKTsKKyAgICAgICAgaW50IGVyciA9IGlvY3RsKGhlYXBJRCgpLCBIVzNEX0dSQU5UX0dQVSwgYmFzZSgpKTsKKyAgICAgICAgaWYgKGVycikgeworICAgICAgICAgICAgLy8gaXQgY2FuIGhhcHBlbiBpZiB0aGUgbWFzdGVyIGhlYXAgaGFzIGJlZW4gY2xvc2VkIGFscmVhZHkKKyAgICAgICAgICAgIC8vIGluIHdoaWNoIGNhc2UgdGhlIEdQVSBhbHJlYWR5IGlzIHJldm9rZWQgKGFwcCBjcmFzaCBmb3IKKyAgICAgICAgICAgIC8vIGluc3RhbmNlKS4KKyAgICAgICAgICAgIExPR1coIkhXM0RfR1JBTlRfR1BVIGZhaWxlZCAoJXMpLCBtRkQ9JWQsIGJhc2U9JXAiLAorICAgICAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubyksIGhlYXBJRCgpLCBiYXNlKCkpOworICAgICAgICB9CisgICAgICAgIG1lbW9yeSA9IG5ldyBHUFVIYW5kbGUoZ3B1LCB0aGlzKTsKKyNlbmRpZgorICAgIH0KKyAgICByZXR1cm4gbWVtb3J5OworfQorCit2b2lkIEdQVVJlZ2lzdGVySGVhcDo6TWVtb3J5SGVhcFJlZ3M6OnJldm9rZSgpIAoreworICAgIE1lbW9yeUhlYXBQbWVtOjpyZXZva2UoKTsKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBpZiAoaGVhcElEKCkgPiAwKSB7CisgICAgICAgIC8vTE9HRCgiaW9jdGwoSFczRF9SRVZPS0VfR1BVKSIpOworICAgICAgICBpbnQgZXJyID0gaW9jdGwoaGVhcElEKCksIEhXM0RfUkVWT0tFX0dQVSwgYmFzZSgpKTsKKyAgICAgICAgTE9HRV9JRihlcnIsICJIVzNEX1JFVk9LRV9HUFUgZmFpbGVkICglcyksIG1GRD0lZCwgYmFzZT0lcCIsCisgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pLCBoZWFwSUQoKSwgYmFzZSgpKTsKKyAgICB9CisjZW5kaWYKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitHUFVIYXJkd2FyZTo6R1BVSGFyZHdhcmUoKQorICAgIDogbU93bmVyKE5PX09XTkVSKQoreworfQorCitHUFVIYXJkd2FyZTo6fkdQVUhhcmR3YXJlKCkKK3sKK30KKworc3RhdHVzX3QgR1BVSGFyZHdhcmU6OnJlcXVlc3RMb2NrZWQoaW50IHBpZCkKK3sKKyAgICBjb25zdCBpbnQgc2VsZl9waWQgPSBnZXRwaWQoKTsKKyAgICBpZiAocGlkID09IHNlbGZfcGlkKSB7CisgICAgICAgIC8vIGNhbid0IHVzZSBHUFUgZnJvbSBzdXJmYWNlZmxpbmdlcidzIHByb2Nlc3MKKyAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOworICAgIH0KKworICAgIGlmIChtT3duZXIgIT0gcGlkKSB7CisgICAgICAgIGlmIChtUkVHSGVhcCAhPSAwKSB7CisgICAgICAgICAgICBpZiAobU93bmVyICE9IE5PX09XTkVSKSB7CisgICAgICAgICAgICAgICAgLy8gc29tZW9uZSBhbHJlYWR5IGhhcyB0aGUgZ3B1LgorICAgICAgICAgICAgICAgIHRha2VCYWNrR1BVTG9ja2VkKCk7CisgICAgICAgICAgICAgICAgcmVsZWFzZUxvY2tlZCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gZmlyc3QgdGltZSwgaW5pdGlhbGl6ZSB0aGUgc3R1ZmYuCisgICAgICAgICAgICBpZiAobVNNSUhlYXAgPT0gMCkKKyAgICAgICAgICAgICAgICBtU01JSGVhcCA9IG5ldyBHUFVBcmVhSGVhcCh0aGlzLCAiL2Rldi9wbWVtX2dwdTAiKTsKKyAgICAgICAgICAgIGlmIChtRUJJSGVhcCA9PSAwKQorICAgICAgICAgICAgICAgIG1FQklIZWFwID0gbmV3IEdQVUFyZWFIZWFwKHRoaXMsIAorICAgICAgICAgICAgICAgICAgICAgICAgIi9kZXYvcG1lbV9ncHUxIiwgMCwgR1BVX1JFU0VSVkVEX1NJWkUpOworICAgICAgICAgICAgbVJFR0hlYXAgPSBuZXcgR1BVUmVnaXN0ZXJIZWFwKHRoaXMpOworICAgICAgICAgICAgbUFsbG9jYXRvciA9IG1FQklIZWFwLT5nZXRBbGxvY2F0b3IoKTsKKyAgICAgICAgICAgIGlmIChtQWxsb2NhdG9yID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAvLyBzb21ldGhpbmcgd2VudCB0ZXJyaWJseSB3cm9uZy4KKyAgICAgICAgICAgICAgICBtU01JSGVhcC5jbGVhcigpOworICAgICAgICAgICAgICAgIG1FQklIZWFwLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgbVJFR0hlYXAuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgQ2xpZW50JiBjbGllbnQgPSBnZXRDbGllbnRMb2NrZWQocGlkKTsKKyAgICAgICAgbUN1cnJlbnRBbGxvY2F0b3IgPSBuZXcgTWVtb3J5RGVhbGVyKGNsaWVudC5lYmkuY2xpZW50SGVhcCwgbUFsbG9jYXRvcik7CisgICAgICAgIG1Pd25lciA9IHBpZDsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzcDxNZW1vcnlEZWFsZXI+IEdQVUhhcmR3YXJlOjpyZXF1ZXN0KGludCBwaWQpCit7CisgICAgc3A8TWVtb3J5RGVhbGVyPiBkZWFsZXI7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBDbGllbnQqIGNsaWVudDsKKyAgICBMT0dEKCJwaWQgJWQgcmVxdWVzdGluZyBncHUgc3VyZmFjZSAoY3VycmVudCBvd25lciA9ICVkKSIsIHBpZCwgbU93bmVyKTsKKyAgICBpZiAocmVxdWVzdExvY2tlZChwaWQpID09IE5PX0VSUk9SKSB7CisgICAgICAgIGRlYWxlciA9IG1DdXJyZW50QWxsb2NhdG9yOworICAgICAgICBMT0dEX0lGKGRlYWxlciE9MCwgImdwdSBzdXJmYWNlIGdyYW50ZWQgdG8gcGlkICVkIiwgbU93bmVyKTsKKyAgICB9CisgICAgcmV0dXJuIGRlYWxlcjsKK30KKworc3RhdHVzX3QgR1BVSGFyZHdhcmU6OnJlcXVlc3QoaW50IHBpZCwgY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssCisgICAgICAgIElTdXJmYWNlQ29tcG9zZXI6OmdwdV9pbmZvX3QqIGdwdSkKK3sKKyAgICBpZiAoY2FsbGJhY2sgPT0gMCkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKworICAgIHNwPElNZW1vcnk+IGdwdUhhbmRsZTsKKyAgICBMT0dEKCJwaWQgJWQgcmVxdWVzdGluZyBncHUgY29yZSAob3duZXIgPSAlZCkiLCBwaWQsIG1Pd25lcik7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBzdGF0dXNfdCBlcnIgPSByZXF1ZXN0TG9ja2VkKHBpZCk7CisgICAgaWYgKGVyciA9PSBOT19FUlJPUikgeworICAgICAgICAvLyBpdCdzIGd1YXJhbnRlZWQgdG8gYmUgdGhlcmUsIGJlIGNvbnN0cnVjdGlvbgorICAgICAgICBDbGllbnQmIGNsaWVudCA9IG1DbGllbnRzLmVkaXRWYWx1ZUZvcihwaWQpOworICAgICAgICByZWdpc3RlckNhbGxiYWNrTG9ja2VkKGNhbGxiYWNrLCBjbGllbnQpOworICAgICAgICBncHUtPmNvdW50ID0gMjsKKyAgICAgICAgZ3B1LT5yZWdpb25zWzBdLnJlZ2lvbiA9IGNsaWVudC5zbWkubWFwKCk7CisgICAgICAgIGdwdS0+cmVnaW9uc1sxXS5yZWdpb24gPSBjbGllbnQuZWJpLm1hcCgpOworICAgICAgICBncHUtPnJlZ3MgICAgICAgICAgICAgID0gY2xpZW50LnJlZy5tYXAoKTsKKyAgICAgICAgZ3B1LT5yZWdpb25zWzBdLnJlc2VydmVkID0gMDsKKyAgICAgICAgZ3B1LT5yZWdpb25zWzFdLnJlc2VydmVkID0gR1BVX1JFU0VSVkVEX1NJWkU7CisgICAgICAgIGlmIChncHUtPnJlZ3MgIT0gMCkgeworICAgICAgICAgICAgLy9MT0dEKCJncHUgY29yZSBncmFudGVkIHRvIHBpZCAlZCwgaGFuZGxlIGJhc2U9JXAiLAorICAgICAgICAgICAgLy8gICAgICAgIG1Pd25lciwgZ3B1LT5yZWdzLT5wb2ludGVyKCkpOworICAgICAgICB9CisgICAgICAgIG1DYWxsYmFjayA9IGNhbGxiYWNrOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR1coImNvdWxkbid0IGdyYW50IGdwdSBjb3JlIHRvIHBpZCAlZCIsIHBpZCk7CisgICAgfQorICAgIHJldHVybiBlcnI7Cit9CisKK3ZvaWQgR1BVSGFyZHdhcmU6OnJldm9rZShpbnQgcGlkKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgaWYgKG1Pd25lciA+IDApIHsKKyAgICAgICAgaWYgKHBpZCAhPSBtT3duZXIpIHsKKyAgICAgICAgICAgIExPR1coIkdQVSBvd25lZCBieSAlZCwgcmV2b2tlIGZyb20gJWQiLCBtT3duZXIsIHBpZCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgLy9MT0dEKCJyZXZva2UgcGlkPSVkLCBvd25lcj0lZCIsIHBpZCwgbU93bmVyKTsKKyAgICAgICAgLy8gbU93bmVyIGNvdWxkIGJlIDwwIGlmIHRoZSBzYW1lIHByb2Nlc3MgYWNxdWlyZWQgdGhlIEdQVQorICAgICAgICAvLyBzZXZlcmFsIHRpbWVzIHdpdGhvdXQgcmVsZWFzaW5nIGl0IGZpcnN0LgorICAgICAgICBtQ29uZGl0aW9uLnNpZ25hbCgpOworICAgICAgICByZWxlYXNlTG9ja2VkKCk7CisgICAgfQorfQorCitzdGF0dXNfdCBHUFVIYXJkd2FyZTo6ZnJpZW5kbHlSZXZva2UoKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgLy9MT0dEKCJmcmllbmRseVJldm9rZSBvd25lcj0lZCIsIG1Pd25lcik7CisgICAgdGFrZUJhY2tHUFVMb2NrZWQoKTsKKyAgICByZWxlYXNlTG9ja2VkKCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIEdQVUhhcmR3YXJlOjp0YWtlQmFja0dQVUxvY2tlZCgpCit7CisgICAgc3A8SUdQVUNhbGxiYWNrPiBjYWxsYmFjayA9IG1DYWxsYmFjazsKKyAgICBtQ2FsbGJhY2suY2xlYXIoKTsKKyAgICBpZiAoY2FsbGJhY2sgIT0gMCkgeworICAgICAgICBjYWxsYmFjay0+Z3B1TG9zdCgpOyAvLyBvbmUtd2F5CisgICAgICAgIG1Db25kaXRpb24ud2FpdFJlbGF0aXZlKG1Mb2NrLCBtczJucygyNTApKTsKKyAgICB9Cit9CisKK3ZvaWQgR1BVSGFyZHdhcmU6OnJlbGVhc2VMb2NrZWQoKQoreworICAgIC8vTE9HRCgicmV2b2tpbmcgZ3B1IGZyb20gcGlkICVkIiwgbU93bmVyKTsKKyAgICBpZiAobU93bmVyICE9IE5PX09XTkVSKSB7CisgICAgICAgIC8vIHRoaXMgbWF5IGZhaWwgYmVjYXVzZSB0aGUgY2xpZW50IG1pZ2h0IGhhdmUgZGllZCwgYW5kIGhhdmUKKyAgICAgICAgLy8gYmVlbiByZW1vdmVkIGZyb20gdGhlIGxpc3QuCisgICAgICAgIHNzaXplX3QgaW5kZXggPSBtQ2xpZW50cy5pbmRleE9mS2V5KG1Pd25lcik7CisgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICBDbGllbnQmIGNsaWVudChtQ2xpZW50cy5lZGl0VmFsdWVBdChpbmRleCkpOworICAgICAgICAgICAgY2xpZW50LnJldm9rZUFsbEhlYXBzKCk7CisgICAgICAgIH0KKyAgICAgICAgbU93bmVyID0gTk9fT1dORVI7CisgICAgICAgIG1DdXJyZW50QWxsb2NhdG9yLmNsZWFyKCk7CisgICAgICAgIG1DYWxsYmFjay5jbGVhcigpOworICAgIH0KK30KKworR1BVSGFyZHdhcmU6OkNsaWVudCYgR1BVSGFyZHdhcmU6OmdldENsaWVudExvY2tlZChwaWRfdCBwaWQpCit7CisgICAgc3NpemVfdCBpbmRleCA9IG1DbGllbnRzLmluZGV4T2ZLZXkocGlkKTsKKyAgICBpZiAoaW5kZXggPCAwKSB7CisgICAgICAgIENsaWVudCBjbGllbnQ7CisgICAgICAgIGNsaWVudC5waWQgPSBwaWQ7CisgICAgICAgIGNsaWVudC5zbWkuaGVhcCA9IG1TTUlIZWFwOworICAgICAgICBjbGllbnQuZWJpLmhlYXAgPSBtRUJJSGVhcDsKKyAgICAgICAgY2xpZW50LnJlZy5oZWFwID0gbVJFR0hlYXA7CisgICAgICAgIGluZGV4ID0gbUNsaWVudHMuYWRkKHBpZCwgY2xpZW50KTsKKyAgICB9CisgICAgQ2xpZW50JiBjbGllbnQobUNsaWVudHMuZWRpdFZhbHVlQXQoaW5kZXgpKTsKKyAgICBjbGllbnQuY3JlYXRlQ2xpZW50SGVhcHMoKTsKKyAgICByZXR1cm4gY2xpZW50OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBmb3IgZGVidWdnaW5nIC8gdGVzdGluZyAuLi4KKworc3A8U2ltcGxlQmVzdEZpdEFsbG9jYXRvcj4gR1BVSGFyZHdhcmU6OmdldEFsbG9jYXRvcigpIGNvbnN0IHsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIHJldHVybiBtQWxsb2NhdG9yOworfQorCit2b2lkIEdQVUhhcmR3YXJlOjp1bmNvbmRpdGlvbmFsUmV2b2tlKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIHJlbGVhc2VMb2NrZWQoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3NwPElNZW1vcnk+IEdQVUhhcmR3YXJlOjpHUFVBcmVhOjptYXAoKSB7CisgICAgc3A8SU1lbW9yeT4gbWVtb3J5OworICAgIGlmIChjbGllbnRIZWFwICE9IDAgJiYgaGVhcCAhPSAwKSB7CisgICAgICAgIG1lbW9yeSA9IGNsaWVudEhlYXAtPm1hcE1lbW9yeSgwLCBoZWFwLT52aXJ0dWFsU2l6ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIG1lbW9yeTsKK30KKwordm9pZCBHUFVIYXJkd2FyZTo6Q2xpZW50OjpjcmVhdGVDbGllbnRIZWFwcygpIAoreworICAgIGlmIChzbWkuY2xpZW50SGVhcCA9PSAwKQorICAgICAgICBzbWkuY2xpZW50SGVhcCA9IHNtaS5oZWFwLT5jcmVhdGVDbGllbnRIZWFwKCk7CisgICAgaWYgKGViaS5jbGllbnRIZWFwID09IDApCisgICAgICAgIGViaS5jbGllbnRIZWFwID0gZWJpLmhlYXAtPmNyZWF0ZUNsaWVudEhlYXAoKTsKKyAgICBpZiAocmVnLmNsaWVudEhlYXAgPT0gMCkKKyAgICAgICAgcmVnLmNsaWVudEhlYXAgPSByZWcuaGVhcC0+Y3JlYXRlQ2xpZW50SGVhcCgpOworfQorCit2b2lkIEdQVUhhcmR3YXJlOjpDbGllbnQ6OnJldm9rZUFsbEhlYXBzKCkgCit7CisgICAgaWYgKHNtaS5jbGllbnRIZWFwICE9IDApCisgICAgICAgIHNtaS5jbGllbnRIZWFwLT5yZXZva2UoKTsKKyAgICBpZiAoZWJpLmNsaWVudEhlYXAgIT0gMCkKKyAgICAgICAgZWJpLmNsaWVudEhlYXAtPnJldm9rZSgpOworICAgIGlmIChyZWcuY2xpZW50SGVhcCAhPSAwKQorICAgICAgICByZWcuY2xpZW50SGVhcC0+cmV2b2tlKCk7Cit9CisKK3ZvaWQgR1BVSGFyZHdhcmU6OnJlZ2lzdGVyQ2FsbGJhY2tMb2NrZWQoY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssCisgICAgICAgIENsaWVudCYgY2xpZW50KQoreworICAgIHNwPElCaW5kZXI+IGJpbmRlciA9IGNhbGxiYWNrLT5hc0JpbmRlcigpOworICAgIGlmIChtUmVnaXN0ZXJlZENsaWVudHMuYWRkKGJpbmRlciwgY2xpZW50LnBpZCkgPj0gMCkgeworICAgICAgICBiaW5kZXItPmxpbmtUb0RlYXRoKHRoaXMpOworICAgIH0KK30KKwordm9pZCBHUFVIYXJkd2FyZTo6YmluZGVyRGllZChjb25zdCB3cDxJQmluZGVyPiYgd2hvKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgcGlkX3QgcGlkID0gbVJlZ2lzdGVyZWRDbGllbnRzLnZhbHVlRm9yKHdobyk7CisgICAgaWYgKHBpZCAhPSAwKSB7CisgICAgICAgIHNzaXplX3QgaW5kZXggPSBtQ2xpZW50cy5pbmRleE9mS2V5KHBpZCk7CisgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICAvL0xPR0QoIioqKiByZW1vdmluZyBjbGllbnQgYXQgJWQiLCBpbmRleCk7CisgICAgICAgICAgICBDbGllbnQmIGNsaWVudChtQ2xpZW50cy5lZGl0VmFsdWVBdChpbmRleCkpOworICAgICAgICAgICAgY2xpZW50LnJldm9rZUFsbEhlYXBzKCk7IC8vIG5vdCByZWFsbHkgbmVlZGVkIGluIHRoZW9yeQorICAgICAgICAgICAgbUNsaWVudHMucmVtb3ZlSXRlbXNBdChpbmRleCk7CisgICAgICAgICAgICBpZiAobUNsaWVudHMuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAvL0xPR0QoIioqKiB3YXMgbGFzdCBjbGllbnQgY2xvc2luZyBldmVyeXRoaW5nIik7CisgICAgICAgICAgICAgICAgbUNhbGxiYWNrLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgbUFsbG9jYXRvci5jbGVhcigpOworICAgICAgICAgICAgICAgIG1DdXJyZW50QWxsb2NhdG9yLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgbVNNSUhlYXAuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICBtUkVHSGVhcC5jbGVhcigpOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIC8vIE5PVEU6IHdlIGNhbm5vdCBjbGVhciB0aGUgRUJJIGhlYXAgYmVjYXVzZSBzdXJmYWNlZmxpbmdlcgorICAgICAgICAgICAgICAgIC8vIGl0c2VsZiBtYXkgYmUgdXNpbmcgaXQsIHNpbmNlIHRoaXMgaXMgd2hlcmUgc3VyZmFjZXMKKyAgICAgICAgICAgICAgICAvLyBhcmUgYWxsb2NhdGVkLiBpZiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGNvbXBvc2l0aW5nIAorICAgICAgICAgICAgICAgIC8vIGEgc3VyZmFjZSAoZXZlbiBpZiBpdHMgcHJvY2VzcyBqdXN0IGRpZWQpLCB3ZSBjYW5ub3QKKyAgICAgICAgICAgICAgICAvLyByaXAgdGhlIGhlYXAgdW5kZXIgb3VyIGZlZXQuCisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgbU93bmVyID0gTk9fT1dORVI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzcDxHUFVIYXJkd2FyZUludGVyZmFjZT4gR1BVRmFjdG9yeTo6Z2V0R1BVKCkKK3sKKyAgICByZXR1cm4gbmV3IEdQVUhhcmR3YXJlKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9HUFVIYXJkd2FyZS9HUFVIYXJkd2FyZS5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9HUFVIYXJkd2FyZS9HUFVIYXJkd2FyZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzNTQ1MjgKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0dQVUhhcmR3YXJlL0dQVUhhcmR3YXJlLmgKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9HUFVfSEFSRFdBUkVfSAorI2RlZmluZSBBTkRST0lEX0dQVV9IQVJEV0FSRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKworI2luY2x1ZGUgPHVpL0lTdXJmYWNlQ29tcG9zZXIuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgSUdQVUNhbGxiYWNrOworCitjbGFzcyBHUFVIYXJkd2FyZUludGVyZmFjZSA6IHB1YmxpYyB2aXJ0dWFsIFJlZkJhc2UKK3sKK3B1YmxpYzoKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICAgICAgcmV2b2tlKGludCBwaWQpID0gMDsKKyAgICB2aXJ0dWFsIHNwPE1lbW9yeURlYWxlcj4gICAgcmVxdWVzdChpbnQgcGlkKSA9IDA7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgICAgIHJlcXVlc3QoaW50IHBpZCwgY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssCisgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjpncHVfaW5mb190KiBncHUpID0gMDsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgICAgICAgICBmcmllbmRseVJldm9rZSgpID0gMDsKKyAgICAKKyAgICAvLyB1c2VkIGZvciBkZWJ1Z2dpbmcgb25seS4uLgorICAgIHZpcnR1YWwgc3A8U2ltcGxlQmVzdEZpdEFsbG9jYXRvcj4gZ2V0QWxsb2NhdG9yKCkgY29uc3QgID0gMDsKKyAgICB2aXJ0dWFsIHBpZF90IGdldE93bmVyKCkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgdm9pZCB1bmNvbmRpdGlvbmFsUmV2b2tlKCkgPSAwOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEdQVUZhY3RvcnkKK3sgICAgCitwdWJsaWM6CisgICAgLy8gdGhlIGdwdSBmYWN0b3J5CisgICAgc3RhdGljIHNwPEdQVUhhcmR3YXJlSW50ZXJmYWNlPiBnZXRHUFUoKTsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfR1BVX0hBUkRXQVJFX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXIuY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjY1ZDY2OQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXIuY3BwCkBAIC0wLDAgKzEsNTY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8Y3V0aWxzL3Byb3BlcnRpZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0b3BXYXRjaC5oPgorCisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKyNpbmNsdWRlIDx1aS9FR0xEaXNwbGF5U3VyZmFjZS5oPgorCisjaW5jbHVkZSAiY2x6LmgiCisjaW5jbHVkZSAiTGF5ZXIuaCIKKyNpbmNsdWRlICJMYXllckJpdG1hcC5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiVlJhbUhlYXAuaCIKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisKKworI2RlZmluZSBERUJVR19SRVNJWkUgICAgMAorCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NvbnN0IHVpbnQzMl90IExheWVyOjp0eXBlSW5mbyA9IExheWVyQmFzZUNsaWVudDo6dHlwZUluZm8gfCA0OworY29uc3QgY2hhciogY29uc3QgTGF5ZXI6OnR5cGVJRCA9ICJMYXllciI7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitMYXllcjo6TGF5ZXIoU3VyZmFjZUZsaW5nZXIqIGZsaW5nZXIsIERpc3BsYXlJRCBkaXNwbGF5LCBDbGllbnQqIGMsIGludDMyX3QgaSkKKyAgICA6ICAgTGF5ZXJCYXNlQ2xpZW50KGZsaW5nZXIsIGRpc3BsYXksIGMsIGkpLAorICAgICAgICBtU2VjdXJlKGZhbHNlKSwKKyAgICAgICAgbUZyb250QnVmZmVySW5kZXgoMSksCisgICAgICAgIG1OZWVkc0JsZW5kaW5nKHRydWUpLAorICAgICAgICBtUmVzaXplVHJhbnNhY3Rpb25Eb25lKGZhbHNlKSwKKyAgICAgICAgbVRleHR1cmVOYW1lKC0xVSksIG1UZXh0dXJlV2lkdGgoMCksIG1UZXh0dXJlSGVpZ2h0KDApCit7CisgICAgLy8gbm8gT3BlbkdMIG9wZXJhdGlvbiBpcyBwb3NzaWJsZSBoZXJlLCBzaW5jZSB3ZSBtaWdodCBub3QgYmUKKyAgICAvLyBpbiB0aGUgT3BlbkdMIHRocmVhZC4KK30KKworTGF5ZXI6On5MYXllcigpCit7CisgICAgY2xpZW50LT5mcmVlKGNsaWVudEluZGV4KCkpOworICAgIC8vIHRoaXMgc2hvdWxkIGFsd2F5cyBiZSBjYWxsZWQgZnJvbSB0aGUgT3BlbkdMIHRocmVhZAorICAgIGlmIChtVGV4dHVyZU5hbWUgIT0gLTFVKSB7CisgICAgICAgIC8vZ2xEZWxldGVUZXh0dXJlcygxLCAmbVRleHR1cmVOYW1lKTsKKyAgICAgICAgZGVsZXRlZFRleHR1cmVzLmFkZChtVGV4dHVyZU5hbWUpOworICAgIH0KK30KKwordm9pZCBMYXllcjo6aW5pdFN0YXRlcyh1aW50MzJfdCB3LCB1aW50MzJfdCBoLCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBMYXllckJhc2U6OmluaXRTdGF0ZXModyxoLGZsYWdzKTsKKworICAgIGlmIChmbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVEZXN0cm95QmFja2J1ZmZlcikKKyAgICAgICAgbGNibGstPmZsYWdzIHw9IGVOb0NvcHlCYWNrOworfQorCitzcDxMYXllckJhc2VDbGllbnQ6OlN1cmZhY2U+IExheWVyOjpnZXRTdXJmYWNlKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVN1cmZhY2U7Cit9CisKK3N0YXR1c190IExheWVyOjpzZXRCdWZmZXJzKCBDbGllbnQqIGNsaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB3LCB1aW50MzJfdCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0IGZvcm1hdCwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgUGl4ZWxGb3JtYXRJbmZvIGluZm87CisgICAgc3RhdHVzX3QgZXJyID0gZ2V0UGl4ZWxGb3JtYXRJbmZvKGZvcm1hdCwgJmluZm8pOworICAgIGlmIChlcnIpIHJldHVybiBlcnI7CisKKyAgICAvLyBUT0RPOiBpZiBlSGFyZHdhcmUgaXMgZXhwbGljaXRseSByZXF1ZXN0ZWQsIHdlIHNob3VsZCBmYWlsCisgICAgLy8gb24gc3lzdGVtcyB3aGVyZSB3ZSBjYW4ndCBhbGxvY2F0ZSBtZW1vcnkgdGhhdCBjYW4gYmUgdXNlZCB3aXRoCisgICAgLy8gRE1BIGVuZ2luZXMgZm9yIGluc3RhbmNlLgorICAgIAorICAgIC8vIEZJWE1FOiB3ZSBhbHdheXMgYXNrIGZvciBoYXJkd2FyZSBmb3Igbm93ICh0aGlzIHNob3VsZCBjb21lIGZyb20gY29weWJpdCkKKyAgICBmbGFncyB8PSBJU3VyZmFjZUNvbXBvc2VyOjplSGFyZHdhcmU7CisKKyAgICBjb25zdCB1aW50MzJfdCBtZW1vcnlfZmxhZ3MgPSBmbGFncyAmIAorICAgICAgICAgICAgKElTdXJmYWNlQ29tcG9zZXI6OmVHUFUgfCAKKyAgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjplSGFyZHdhcmUgfCAKKyAgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjplU2VjdXJlKTsKKyAgICAKKyAgICAvLyBwaXhlbC1hbGlnbm1lbnQuIHRoZSBmaW5hbCBhbGlnbm1lbnQgbWF5IGJlIGJpZ2dlciBiZWNhdXNlCisgICAgLy8gd2UgYWx3YXlzIGZvcmNlIGEgNC1ieXRlIGFsaWduZWQgYnByLgorICAgIHVpbnQzMl90IGFsaWdubWVudCA9IDE7CisKKyAgICBpZiAoZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplR1BVKSB7CisgICAgICAgIC8vIEZJWE1FOiB0aGlzIHZhbHVlIHNob3VsZCBjb21lIGZyb20gdGhlIGgvdworICAgICAgICBhbGlnbm1lbnQgPSA4OyAKKyAgICAgICAgLy8gRklYTUU6IHRoaXMgaXMgbXNtNzIwMUEgc3BlY2lmaWMsIGFzIGl0cyBHUFUgb25seSBzdXBwb3J0cworICAgICAgICAvLyBCR1JBXzg4ODguCisgICAgICAgIGlmIChmb3JtYXQgPT0gUElYRUxfRk9STUFUX1JHQkFfODg4OCkgeworICAgICAgICAgICAgZm9ybWF0ID0gUElYRUxfRk9STUFUX0JHUkFfODg4ODsKKyAgICAgICAgfQorICAgIH0KKworICAgIG1TZWN1cmUgPSAoZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplU2VjdXJlKSA/IHRydWUgOiBmYWxzZTsKKyAgICBtTmVlZHNCbGVuZGluZyA9IChpbmZvLmhfYWxwaGEgLSBpbmZvLmxfYWxwaGEpID4gMDsKKyAgICBzcDxNZW1vcnlEZWFsZXI+IGFsbG9jYXRvcnNbMl07CisgICAgZm9yIChpbnQgaT0wIDsgaTwyIDsgaSsrKSB7CisgICAgICAgIGFsbG9jYXRvcnNbaV0gPSBjbGllbnQtPmNyZWF0ZUFsbG9jYXRvcihtZW1vcnlfZmxhZ3MpOworICAgICAgICBpZiAoYWxsb2NhdG9yc1tpXSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgbUJ1ZmZlcnNbaV0uaW5pdChhbGxvY2F0b3JzW2ldKTsKKyAgICAgICAgaW50IGVyciA9IG1CdWZmZXJzW2ldLnNldEJpdHModywgaCwgYWxpZ25tZW50LCBmb3JtYXQsIExheWVyQml0bWFwOjpTRUNVUkVfQklUUyk7CisgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpCisgICAgICAgICAgICByZXR1cm4gZXJyOworICAgICAgICBtQnVmZmVyc1tpXS5jbGVhcigpOyAvLyBjbGVhciB0aGUgYml0cyBmb3Igc2VjdXJpdHkKKyAgICAgICAgbUJ1ZmZlcnNbaV0uZ2V0SW5mbyhsY2Jsay0+c3VyZmFjZSArIGkpOworICAgIH0KKworICAgIG1TdXJmYWNlID0gbmV3IFN1cmZhY2UoY2xpZW50SW5kZXgoKSwKKyAgICAgICAgICAgIGFsbG9jYXRvcnNbMF0tPmdldE1lbW9yeUhlYXAoKSwKKyAgICAgICAgICAgIGFsbG9jYXRvcnNbMV0tPmdldE1lbW9yeUhlYXAoKSwKKyAgICAgICAgICAgIG1JZGVudGl0eSk7CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3ZvaWQgTGF5ZXI6OnJlbG9hZFRleHR1cmUoY29uc3QgUmVnaW9uJiBkaXJ0eSkKK3sKKyAgICBpZiAoVU5MSUtFTFkobVRleHR1cmVOYW1lID09IC0xVSkpIHsKKyAgICAgICAgLy8gY3JlYXRlIHRoZSB0ZXh0dXJlIG5hbWUgdGhlIGZpcnN0IHRpbWUKKyAgICAgICAgLy8gY2FuJ3QgZG8gdGhhdCBpbiB0aGUgY3RvciwgYmVjYXVzZSBpdCBydW5zIGluIGFub3RoZXIgdGhyZWFkLgorICAgICAgICBtVGV4dHVyZU5hbWUgPSBjcmVhdGVUZXh0dXJlKCk7CisgICAgfQorICAgIGNvbnN0IEdHTFN1cmZhY2UmIHQoZnJvbnRCdWZmZXIoKS5zdXJmYWNlKCkpOworICAgIGxvYWRUZXh0dXJlKGRpcnR5LCBtVGV4dHVyZU5hbWUsIHQsIG1UZXh0dXJlV2lkdGgsIG1UZXh0dXJlSGVpZ2h0KTsKK30KKworCit2b2lkIExheWVyOjpvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdAoreworICAgIGlmIChVTkxJS0VMWShtVGV4dHVyZU5hbWUgPT0gLTFMVSkpIHsKKyAgICAgICAgLy9MT0dXKCJMYXllciAlcCBkb2Vzbid0IGhhdmUgYSB0ZXh0dXJlIiwgdGhpcyk7CisgICAgICAgIC8vIHRoZSB0ZXh0dXJlIGhhcyBub3QgYmVlbiBjcmVhdGVkIHlldCwgdGhpcyBMYXllciBoYXMKKyAgICAgICAgLy8gaW4gZmFjdCBuZXZlciBiZWVuIGRyYXduIGludG8uIHRoaXMgaGFwcGVucyBmcmVxdWVudGx5IHdpdGgKKyAgICAgICAgLy8gU3VyZmFjZVZpZXcuCisgICAgICAgIGNsZWFyV2l0aE9wZW5HTChjbGlwKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICBjb25zdCBMYXllckJpdG1hcCYgZnJvbnQoZnJvbnRCdWZmZXIoKSk7CisgICAgY29uc3QgR0dMU3VyZmFjZSYgdChmcm9udC5zdXJmYWNlKCkpOworCisgICAgc3RhdHVzX3QgZXJyID0gTk9fRVJST1I7CisgICAgY29uc3QgaW50IGNhbl91c2VfY29weWJpdCA9IGNhblVzZUNvcHliaXQoKTsKKyAgICBpZiAoY2FuX3VzZV9jb3B5Yml0KSAgeworICAgICAgICAvLyBTdG9wV2F0Y2ggd2F0Y2goImNvcHliaXQiKTsKKyAgICAgICAgY29uc3QgU3RhdGUmIHMoZHJhd2luZ1N0YXRlKCkpOworCisgICAgICAgIGNvcHliaXRfaW1hZ2VfdCBkc3Q7CisgICAgICAgIGh3LmdldERpc3BsYXlTdXJmYWNlKCZkc3QpOworICAgICAgICBjb25zdCBjb3B5Yml0X3JlY3RfdCYgZHJlY3QKKyAgICAgICAgICAgID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjb3B5Yml0X3JlY3RfdCY+KG1UcmFuc2Zvcm1lZEJvdW5kcyk7CisKKyAgICAgICAgY29weWJpdF9pbWFnZV90IHNyYzsKKyAgICAgICAgZnJvbnQuZ2V0Qml0bWFwU3VyZmFjZSgmc3JjKTsKKyAgICAgICAgY29weWJpdF9yZWN0X3Qgc3JlY3QgPSB7IDAsIDAsIHQud2lkdGgsIHQuaGVpZ2h0IH07CisKKyAgICAgICAgY29weWJpdF9kZXZpY2VfdCogY29weWJpdCA9IG1GbGluZ2VyLT5nZXRCbGl0RW5naW5lKCk7CisgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9UUkFOU0ZPUk0sIGdldE9yaWVudGF0aW9uKCkpOworICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfUExBTkVfQUxQSEEsIHMuYWxwaGEpOworICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfRElUSEVSLAorICAgICAgICAgICAgICAgIHMuZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJEaXRoZXIgPworICAgICAgICAgICAgICAgICAgICAgICAgQ09QWUJJVF9FTkFCTEUgOiBDT1BZQklUX0RJU0FCTEUpOworCisgICAgICAgIHJlZ2lvbl9pdGVyYXRvciBpdChjbGlwKTsKKyAgICAgICAgZXJyID0gY29weWJpdC0+c3RyZXRjaChjb3B5Yml0LCAmZHN0LCAmc3JjLCAmZHJlY3QsICZzcmVjdCwgJml0KTsKKyAgICB9CisKKyAgICBpZiAoIWNhbl91c2VfY29weWJpdCB8fCBlcnIpIHsKKyAgICAgICAgZHJhd1dpdGhPcGVuR0woY2xpcCwgbVRleHR1cmVOYW1lLCB0KTsKKyAgICB9Cit9CisKK3N0YXR1c190IExheWVyOjpyZWFsbG9jYXRlQnVmZmVyKGludDMyX3QgaW5kZXgsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgpCit7CisgICAgTE9HRF9JRihERUJVR19SRVNJWkUsCisgICAgICAgICAgICAgICAgInJlYWxsb2NhdGVCdWZmZXIgKGxheWVyPSVwKSwgIgorICAgICAgICAgICAgICAgICJyZXF1ZXN0ZWQgKCVkeCVkKSwgIgorICAgICAgICAgICAgICAgICJpbmRleD0lZCwgKCVkeCVkKSwgKCVkeCVkKSIsCisgICAgICAgICAgICAgICAgdGhpcywKKyAgICAgICAgICAgICAgICBpbnQodyksIGludChoKSwKKyAgICAgICAgICAgICAgICBpbnQoaW5kZXgpLAorICAgICAgICAgICAgICAgIGludChtQnVmZmVyc1swXS53aWR0aCgpKSwgaW50KG1CdWZmZXJzWzBdLmhlaWdodCgpKSwKKyAgICAgICAgICAgICAgICBpbnQobUJ1ZmZlcnNbMV0ud2lkdGgoKSksIGludChtQnVmZmVyc1sxXS5oZWlnaHQoKSkpOworCisgICAgc3RhdHVzX3QgZXJyID0gbUJ1ZmZlcnNbaW5kZXhdLnJlc2l6ZSh3LCBoKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSB7CisgICAgICAgIG1CdWZmZXJzW2luZGV4XS5nZXRJbmZvKGxjYmxrLT5zdXJmYWNlICsgaW5kZXgpOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR0UoInJlc2l6aW5nIGJ1ZmZlciAlZCB0byAoJXUsJXUpIGZhaWxlZCBbJTA4eF0gJXMiLAorICAgICAgICAgICAgaW5kZXgsIHcsIGgsIGVyciwgc3RyZXJyb3IoZXJyKSk7CisgICAgICAgIC8vIFhYWDogd2hhdCB0byBkbywgd2hhdCB0byBkbz8gV2UgY291bGQgdHJ5IHRvIGZyZWUgc29tZQorICAgICAgICAvLyBoaWRkZW4gc3VyZmFjZXMsIGluc3RlYWQgb2Yga2lsbGluZyB0aGlzIG9uZT8KKyAgICB9CisgICAgcmV0dXJuIGVycjsKK30KKwordWludDMyX3QgTGF5ZXI6OmRvVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpCit7CisgICAgY29uc3QgTGF5ZXI6OlN0YXRlJiBmcm9udChkcmF3aW5nU3RhdGUoKSk7CisgICAgY29uc3QgTGF5ZXI6OlN0YXRlJiB0ZW1wKGN1cnJlbnRTdGF0ZSgpKTsKKworICAgIC8vIHRoZSB0ZXN0IGZyb250Lnt3fGh9ICE9IHRlbXAue3d8aH0gaXMgbm90IGVub3VnaCBiZWNhdXNlIGl0IGlzIHBvc3NpYmxlCisgICAgLy8gdGhhdCB0aGUgc2l6ZSBjaGFuZ2VkIGJhY2sgdG8gaXRzIHByZXZpb3VzIHZhbHVlIGJlZm9yZSB0aGUgYnVmZmVyCisgICAgLy8gd2FzIHJlc2l6ZWQgKGluIHRoZSBlTG9ja2VkIGNhc2UgYmVsb3cpLCBpbiB3aGljaCBjYXNlLCB3ZSBzdGlsbAorICAgIC8vIG5lZWQgdG8gZXhlY3V0ZSB0aGUgY29kZSBiZWxvdyBzbyB0aGUgY2xpZW50cyBoYXZlIGEgY2hhbmNlIHRvIGJlCisgICAgLy8gcmVsZWFzZS4gcmVzemUoKSBkZWFscyB3aXRoIHRoZSBmYWN0IHRoYXQgdGhlIHNpemUgY2FuIGJlIHRoZSBzYW1lLgorCisgICAgLyoKKyAgICAgKiAgVmFyaW91cyBzdGF0ZXMgd2UgY291bGQgYmUgaW4uLi4KKworICAgICAgICAgcmVzaXplID0gc3RhdGUgJiBlUmVzaXplUmVxdWVzdGVkOworICAgICAgICAgaWYgKGJhY2tidWZmZXJDaGFuZ2VkKSB7CisgICAgICAgICAgICAgaWYgKHJlc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgIC8vIEVSUk9SLCB0aGUgcmVzaXplZCBidWZmZXIgZG9lc24ndCBoYXZlIGl0cyByZXNpemUgZmxhZyBzZXQKKyAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc2l6ZSA9PSBtYXNrKSB7CisgICAgICAgICAgICAgICAgIC8vIEVSUk9SIG9uZSBvZiB0aGUgYnVmZmVyIGhhcyBhbHJlYWR5IGJlZW4gcmVzaXplZAorICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzaXplID09IG1hc2sgXiBlUmVzaXplUmVxdWVzdGVkKSB7CisgICAgICAgICAgICAgICAgIC8vIEVSUk9SLCB0aGUgcmVzaXplZCBidWZmZXIgZG9lc24ndCBoYXZlIGl0cyByZXNpemUgZmxhZyBzZXQKKyAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc2l6ZSA9PSBlUmVzaXplUmVxdWVzdGVkKSB7CisgICAgICAgICAgICAgICAgIC8vIE9LLCBOb3JtYWwgY2FzZSwgcHJvY2VlZCB3aXRoIHJlc2l6ZQorICAgICAgICAgICAgIH0KKyAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgaWYgKHJlc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgIC8vIE9LLCBub3RoaW5nIHNwZWNpYWwsIGRvIG5vdGhpbmcKKyAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc2l6ZSA9PSBtYXNrKSB7CisgICAgICAgICAgICAgICAgIC8vIHJlc3RhcnRlZCB0cmFuc2FjdGlvbiwgZG8gbm90aGluZworICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzaXplID09IG1hc2sgXiBlUmVzaXplUmVxdWVzdGVkKSB7CisgICAgICAgICAgICAgICAgIC8vIHJlc3RhcnRlZCB0cmFuc2FjdGlvbiwgZG8gbm90aGluZworICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzaXplID09IGVSZXNpemVSZXF1ZXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgLy8gT0ssIHNpemUgcmVzZXQgdG8gcHJldmlvdXMgdmFsdWUsIHByb2NlZWQgd2l0aCByZXNpemUKKyAgICAgICAgICAgICB9CisgICAgICAgICB9CisgICAgICovCisKKyAgICAvLyBJbmRleCBvZiB0aGUgYmFjayBidWZmZXIKKyAgICBjb25zdCBib29sIGJhY2tidWZmZXJDaGFuZ2VkID0gKGZyb250LncgIT0gdGVtcC53KSB8fCAoZnJvbnQuaCAhPSB0ZW1wLmgpOworICAgIGNvbnN0IHVpbnQzMl90IHN0YXRlID0gbGNibGstPnN3YXBTdGF0ZTsKKyAgICBjb25zdCBpbnQzMl90IGNsaWVudEJhY2tCdWZmZXJJbmRleCA9IGxheWVyX2NibGtfdDo6YmFja0J1ZmZlcihzdGF0ZSk7CisgICAgY29uc3QgdWludDMyX3QgbWFzayA9IGNsaWVudEJhY2tCdWZmZXJJbmRleCA/IGVSZXNpemVCdWZmZXIxIDogZVJlc2l6ZUJ1ZmZlcjA7CisgICAgdWludDMyX3QgcmVzaXplRmxhZ3MgPSBzdGF0ZSAmIGVSZXNpemVSZXF1ZXN0ZWQ7CisKKyAgICBpZiAoVU5MSUtFTFkoYmFja2J1ZmZlckNoYW5nZWQgJiYgKHJlc2l6ZUZsYWdzICE9IGVSZXNpemVSZXF1ZXN0ZWQpKSkgeworICAgICAgICBMT0dFKCAgICJiYWNrYnVmZmVyIHNpemUgY2hhbmdlZCwgYnV0IGJvdGggcmVzaXplIGZsYWdzIGFyZSBub3Qgc2V0ISAiCisgICAgICAgICAgICAgICAgIihsYXllcj0lcCksIHN0YXRlPSUwOHgsIHJlcXVlc3RlZCAoJWR4JWQpLCBkcmF3aW5nICglZCwlZCksICIKKyAgICAgICAgICAgICAgICAiaW5kZXg9JWQsICglZHglZCksICglZHglZCkiLAorICAgICAgICAgICAgICAgIHRoaXMsICBzdGF0ZSwKKyAgICAgICAgICAgICAgICBpbnQodGVtcC53KSwgaW50KHRlbXAuaCksCisgICAgICAgICAgICAgICAgaW50KGRyYXdpbmdTdGF0ZSgpLncpLCBpbnQoZHJhd2luZ1N0YXRlKCkuaCksCisgICAgICAgICAgICAgICAgaW50KGNsaWVudEJhY2tCdWZmZXJJbmRleCksCisgICAgICAgICAgICAgICAgaW50KG1CdWZmZXJzWzBdLndpZHRoKCkpLCBpbnQobUJ1ZmZlcnNbMF0uaGVpZ2h0KCkpLAorICAgICAgICAgICAgICAgIGludChtQnVmZmVyc1sxXS53aWR0aCgpKSwgaW50KG1CdWZmZXJzWzFdLmhlaWdodCgpKSk7CisgICAgICAgIC8vIGlmIHdlIGdldCB0aGVyZSB3ZSdyZSBwcmV0dHkgc2NyZXdlZC4gdGhlIG9ubHkgcmVhc29uYWJsZQorICAgICAgICAvLyB0aGluZyB0byBkbyBpcyB0byBwcmV0ZW5kIHdlIHNob3VsZCBkbyB0aGUgcmVzaXplIHNpbmNlCisgICAgICAgIC8vIGJhY2tidWZmZXJDaGFuZ2VkIGlzIHNldCAodGhpcyBhbHNvIHdpbGwgZ2l2ZSBhIGNoYW5jZSB0bworICAgICAgICAvLyBjbGllbnQgdG8gZ2V0IHVuYmxvY2tlZCkKKyAgICAgICAgcmVzaXplRmxhZ3MgPSBlUmVzaXplUmVxdWVzdGVkOworICAgIH0KKworICAgIGlmIChyZXNpemVGbGFncyA9PSBlUmVzaXplUmVxdWVzdGVkKSAgeworICAgICAgICAvLyBOT1RFOiBhc3NlcnRpbmcgdGhhdCBjbGllbnRCYWNrQnVmZmVySW5kZXghPW1Gcm9udEJ1ZmZlckluZGV4CisgICAgICAgIC8vIGhlcmUsIHdvdWxkIGJlIHdyb25nIGFuZCBtaXNsZWFkaW5nIGJlY2F1c2UgYnkgdGhpcyBwb2ludAorICAgICAgICAvLyBtRnJvbnRCdWZmZXJJbmRleCBoYXMgbm90IGJlZW4gdXBkYXRlZCB5ZXQuCisKKyAgICAgICAgTE9HRF9JRihERUJVR19SRVNJWkUsCisgICAgICAgICAgICAgICAgICAgICJyZXNpemUgKGxheWVyPSVwKSwgc3RhdGU9JTA4eCwgIgorICAgICAgICAgICAgICAgICAgICAicmVxdWVzdGVkICglZHglZCksICIKKyAgICAgICAgICAgICAgICAgICAgImRyYXdpbmcgKCVkLCVkKSwgIgorICAgICAgICAgICAgICAgICAgICAiaW5kZXg9JWQsICglZHglZCksICglZHglZCkiLAorICAgICAgICAgICAgICAgICAgICB0aGlzLCAgc3RhdGUsCisgICAgICAgICAgICAgICAgICAgIGludCh0ZW1wLncpLCBpbnQodGVtcC5oKSwKKyAgICAgICAgICAgICAgICAgICAgaW50KGRyYXdpbmdTdGF0ZSgpLncpLCBpbnQoZHJhd2luZ1N0YXRlKCkuaCksCisgICAgICAgICAgICAgICAgICAgIGludChjbGllbnRCYWNrQnVmZmVySW5kZXgpLAorICAgICAgICAgICAgICAgICAgICBpbnQobUJ1ZmZlcnNbMF0ud2lkdGgoKSksIGludChtQnVmZmVyc1swXS5oZWlnaHQoKSksCisgICAgICAgICAgICAgICAgICAgIGludChtQnVmZmVyc1sxXS53aWR0aCgpKSwgaW50KG1CdWZmZXJzWzFdLmhlaWdodCgpKSk7CisKKyAgICAgICAgaWYgKHN0YXRlICYgZUxvY2tlZCkgeworICAgICAgICAgICAgLy8gaWYgdGhlIGJ1ZmZlciBpcyBsb2NrZWQsIHdlIGNhbid0IHJlc2l6ZSBhbnl0aGluZyBiZWNhdXNlCisgICAgICAgICAgICAvLyAtIHRoZSBiYWNrYnVmZmVyIGlzIGN1cnJlbnRseSBpbiB1c2UgYnkgdGhlIHVzZXIKKyAgICAgICAgICAgIC8vIC0gdGhlIGZyb250IGJ1ZmZlciBpcyBiZWluZyBzaG93bgorICAgICAgICAgICAgLy8gV2UganVzdCBhY3QgYXMgaWYgdGhlIHRyYW5zYWN0aW9uIGRpZG4ndCBoYXBwZW4gYW5kIHdlCisgICAgICAgICAgICAvLyByZXNjaGVkdWxlIGl0IGxhdGVyLi4uCisgICAgICAgICAgICBmbGFncyB8PSBlUmVzdGFydFRyYW5zYWN0aW9uOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhpcyBidWZmZXIgbmVlZHMgdG8gYmUgcmVzaXplZAorICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0KKyAgICAgICAgICAgICAgICByZXNpemUoY2xpZW50QmFja0J1ZmZlckluZGV4LCB0ZW1wLncsIHRlbXAuaCwgInRyYW5zYWN0aW9uIik7CisgICAgICAgICAgICBpZiAoZXJyID09IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgY29uc3QgdWludDMyX3QgbWFzayA9IGNsaWVudEJhY2tCdWZmZXJJbmRleCA/IGVSZXNpemVCdWZmZXIxIDogZVJlc2l6ZUJ1ZmZlcjA7CisgICAgICAgICAgICAgICAgYW5kcm9pZF9hdG9taWNfYW5kKH5tYXNrLCAmKGxjYmxrLT5zd2FwU3RhdGUpKTsKKyAgICAgICAgICAgICAgICAvLyBzaW5jZSBhIGJ1ZmZlciBiZWNhbWUgYXZhaWxhYmxlLCB3ZSBjYW4gbGV0IHRoZSBjbGllbnQgZ28uLi4KKyAgICAgICAgICAgICAgICBtRmxpbmdlci0+c2NoZWR1bGVCcm9hZGNhc3QoY2xpZW50KTsKKyAgICAgICAgICAgICAgICBtUmVzaXplVHJhbnNhY3Rpb25Eb25lID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgIC8vIHdlJ3JlIGJlaW5nIHJlc2l6ZWQgYW5kIHRoZXJlIGlzIGEgZnJlZXplIGRpc3BsYXkgcmVxdWVzdCwKKyAgICAgICAgICAgICAgICAvLyBhY3F1aXJlIGEgZnJlZXplIGxvY2ssIHNvIHRoYXQgdGhlIHNjcmVlbiBzdGF5cyBwdXQKKyAgICAgICAgICAgICAgICAvLyB1bnRpbCB3ZSd2ZSByZWRyYXduIGF0IHRoZSBuZXcgc2l6ZTsgdGhpcyBpcyB0byBhdm9pZAorICAgICAgICAgICAgICAgIC8vIGdsaXRjaGVzIHVwb24gb3JpZW50YXRpb24gY2hhbmdlcy4KKyAgICAgICAgICAgICAgICBpZiAobUZsaW5nZXItPmhhc0ZyZWV6ZVJlcXVlc3QoKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgc3VyZmFjZSBpcyBoaWRkZW4sIGRvbid0IHRyeSB0byBhY3F1aXJlIHRoZQorICAgICAgICAgICAgICAgICAgICAvLyBmcmVlemUgbG9jaywgc2luY2UgaGlkZGVuIHN1cmZhY2VzIG1heSBuZXZlciByZWRyYXcKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoZnJvbnQuZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJIaWRkZW4pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtRnJlZXplTG9jayA9IG1GbGluZ2VyLT5nZXRGcmVlemVMb2NrKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaWYgKHRlbXAuc2VxdWVuY2UgIT0gZnJvbnQuc2VxdWVuY2UpIHsKKyAgICAgICAgaWYgKHRlbXAuZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJIaWRkZW4gfHwgdGVtcC5hbHBoYSA9PSAwKSB7CisgICAgICAgICAgICAvLyB0aGlzIHN1cmZhY2UgaXMgbm93IGhpZGRlbiwgc28gaXQgc2hvdWxkbid0IGhvbGQgYSBmcmVlemUgbG9jaworICAgICAgICAgICAgLy8gKGl0IG1heSBuZXZlciByZWRyYXcsIHdoaWNoIGlzIGZpbmUgaWYgaXQgaXMgaGlkZGVuKQorICAgICAgICAgICAgbUZyZWV6ZUxvY2suY2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAgICAgCisgICAgcmV0dXJuIExheWVyQmFzZTo6ZG9UcmFuc2FjdGlvbihmbGFncyk7Cit9CisKK3N0YXR1c190IExheWVyOjpyZXNpemUoCisgICAgICAgIGludDMyX3QgY2xpZW50QmFja0J1ZmZlckluZGV4LAorICAgICAgICB1aW50MzJfdCB3aWR0aCwgdWludDMyX3QgaGVpZ2h0LAorICAgICAgICBjb25zdCBjaGFyKiB3aGF0KQoreworICAgIC8qCisgICAgICogaGFuZGxlIHJlc2l6ZSAoYmFja2J1ZmZlciBhbmQgZnJvbnRidWZmZXIgcmVhbGxvY2F0aW9uKQorICAgICAqLworCisgICAgY29uc3QgTGF5ZXJCaXRtYXAmIGNsaWVudEJhY2tCdWZmZXIobUJ1ZmZlcnNbY2xpZW50QmFja0J1ZmZlckluZGV4XSk7CisKKyAgICAvLyBpZiB0aGUgbmV3ICh0cmFuc2FjdGlvbikgc2l6ZSBpcyAhPSBmcm9tIHRoZSB0aGUgYmFja2J1ZmZlcgorICAgIC8vIHRoZW4gd2UgbmVlZCB0byByZWFsbG9jYXRlIHRoZSBiYWNrYnVmZmVyCisgICAgYm9vbCBiYWNrYnVmZmVyQ2hhbmdlZCA9IChjbGllbnRCYWNrQnVmZmVyLndpZHRoKCkgICE9IHdpZHRoKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpZW50QmFja0J1ZmZlci5oZWlnaHQoKSAhPSBoZWlnaHQpOworCisgICAgTE9HRF9JRighYmFja2J1ZmZlckNoYW5nZWQsCisgICAgICAgICAgICAiKCVzKSBlUmVzaXplUmVxdWVzdGVkIChsYXllcj0lcCksIGJ1dCBzaXplIG5vdCBjaGFuZ2VkOiAiCisgICAgICAgICAgICAicmVxdWVzdGVkICglZHglZCksIGRyYXdpbmcgKCVkLCVkKSwgY3VycmVudCAoJWQsJWQpLCIKKyAgICAgICAgICAgICJzdGF0ZT0lMDhseCwgaW5kZXg9JWQsICglZHglZCksICglZHglZCkiLAorICAgICAgICAgICAgd2hhdCwgdGhpcywKKyAgICAgICAgICAgIGludCh3aWR0aCksIGludChoZWlnaHQpLAorICAgICAgICAgICAgaW50KGRyYXdpbmdTdGF0ZSgpLncpLCBpbnQoZHJhd2luZ1N0YXRlKCkuaCksCisgICAgICAgICAgICBpbnQoY3VycmVudFN0YXRlKCkudyksIGludChjdXJyZW50U3RhdGUoKS5oKSwKKyAgICAgICAgICAgIGxvbmcobGNibGstPnN3YXBTdGF0ZSksCisgICAgICAgICAgICBpbnQoY2xpZW50QmFja0J1ZmZlckluZGV4KSwKKyAgICAgICAgICAgIGludChtQnVmZmVyc1swXS53aWR0aCgpKSwgaW50KG1CdWZmZXJzWzBdLmhlaWdodCgpKSwKKyAgICAgICAgICAgIGludChtQnVmZmVyc1sxXS53aWR0aCgpKSwgaW50KG1CdWZmZXJzWzFdLmhlaWdodCgpKSk7CisKKyAgICAvLyB0aGlzIGNhbiBoYXBwZW4gd2hlbiBjaGFuZ2luZyB0aGUgc2l6ZSBiYWNrIGFuZCBmb3J0aCBxdWlja2x5CisgICAgc3RhdHVzX3QgZXJyID0gTk9fRVJST1I7CisgICAgaWYgKGJhY2tidWZmZXJDaGFuZ2VkKSB7CisgICAgICAgIGVyciA9IHJlYWxsb2NhdGVCdWZmZXIoY2xpZW50QmFja0J1ZmZlckluZGV4LCB3aWR0aCwgaGVpZ2h0KTsKKyAgICB9CisgICAgaWYgKFVOTElLRUxZKGVyciAhPSBOT19FUlJPUikpIHsKKyAgICAgICAgLy8gY291bGRuJ3QgcmVhbGxvY2F0ZSB0aGUgc3VyZmFjZQorICAgICAgICBhbmRyb2lkX2F0b21pY193cml0ZShlSW52YWxpZFN1cmZhY2UsICZsY2Jsay0+c3dhcFN0YXRlKTsKKyAgICAgICAgbWVtc2V0KGxjYmxrLT5zdXJmYWNlK2NsaWVudEJhY2tCdWZmZXJJbmRleCwgMCwgc2l6ZW9mKHN1cmZhY2VfaW5mb190KSk7CisgICAgfQorICAgIHJldHVybiBlcnI7Cit9CisKK3ZvaWQgTGF5ZXI6OnNldFNpemVDaGFuZ2VkKHVpbnQzMl90IHcsIHVpbnQzMl90IGgpCit7CisgICAgTE9HRF9JRihERUJVR19SRVNJWkUsCisgICAgICAgICAgICAic2V0U2l6ZUNoYW5nZWQgdz0lZCwgaD0lZCAob2xkOiB3PSVkLCBoPSVkKSIsCisgICAgICAgICAgICB3LCBoLCBtQ3VycmVudFN0YXRlLncsIG1DdXJyZW50U3RhdGUuaCk7CisgICAgYW5kcm9pZF9hdG9taWNfb3IoZVJlc2l6ZVJlcXVlc3RlZCwgJihsY2Jsay0+c3dhcFN0YXRlKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHBhZ2VmbGlwIGhhbmRsaW5nLi4uCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgTGF5ZXI6OmxvY2tQYWdlRmxpcChib29sJiByZWNvbXB1dGVWaXNpYmxlUmVnaW9ucykKK3sKKyAgICB1aW50MzJfdCBzdGF0ZSA9IGFuZHJvaWRfYXRvbWljX29yKGVCdXN5LCAmKGxjYmxrLT5zd2FwU3RhdGUpKTsKKyAgICAvLyBwcmVlbXB0aXZlbHkgYmxvY2sgdGhlIGNsaWVudCwgYmVjYXVzZSBoZSBtaWdodCBzZXQKKyAgICAvLyBlRmxpcFJlcXVlc3RlZCBhdCBhbnkgdGltZSBhbmQgd2FudCB0byB1c2UgdGhpcyBidWZmZXIKKyAgICAvLyBmb3IgdGhlIG5leHQgZnJhbWUuIFRoaXMgd2lsbCBiZSB1bnNldCBiZWxvdyBpZiBpdAorICAgIC8vIHR1cm5zIG91dCB3ZSBkaWRuJ3QgbmVlZCBpdC4KKworICAgIHVpbnQzMl90IG1hc2sgPSBlSW52YWxpZFN1cmZhY2UgfCBlRmxpcFJlcXVlc3RlZCB8IGVSZXNpemVSZXF1ZXN0ZWQ7CisgICAgaWYgKCEoc3RhdGUgJiBtYXNrKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgaWYgKFVOTElLRUxZKHN0YXRlICYgZUludmFsaWRTdXJmYWNlKSkgeworICAgICAgICAvLyBpZiBlSW52YWxpZFN1cmZhY2UgaXMgc2V0LCB0aGlzIG1lYW5zIHRoZSBzdXJmYWNlCisgICAgICAgIC8vIGJlY2FtZSBpbnZhbGlkIGR1cmluZyBhIHRyYW5zYWN0aW9uIChOT19NRU1PUlkgZm9yIGluc3RhbmNlKQorICAgICAgICBtRmxpbmdlci0+c2NoZWR1bGVCcm9hZGNhc3QoY2xpZW50KTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChVTkxJS0VMWShzdGF0ZSAmIGVGbGlwUmVxdWVzdGVkKSkgeworICAgICAgICB1aW50MzJfdCBvbGRTdGF0ZTsKKyAgICAgICAgbVBvc3RlZERpcnR5UmVnaW9uID0gcG9zdCgmb2xkU3RhdGUsIHJlY29tcHV0ZVZpc2libGVSZWdpb25zKTsKKyAgICAgICAgaWYgKG9sZFN0YXRlICYgZU5leHRGbGlwUGVuZGluZykgeworICAgICAgICAgICAgLy8gUHJvY2VzcyBhbm90aGVyIHJvdW5kICh3ZSBrbm93IGF0IGxlYXN0IGEgYnVmZmVyCisgICAgICAgICAgICAvLyBpcyByZWFkeSBmb3IgdGhhdCBjbGllbnQpLgorICAgICAgICAgICAgbUZsaW5nZXItPnNpZ25hbEV2ZW50KCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK1JlZ2lvbiBMYXllcjo6cG9zdCh1aW50MzJfdCogcHJldmlvdXNTYXRlLCBib29sJiByZWNvbXB1dGVWaXNpYmxlUmVnaW9ucykKK3sKKyAgICAvLyBhdG9taWNhbGx5IHN3YXAgYnVmZmVycyBhbmQgKHJlKXNldCBlRmxpcFJlcXVlc3RlZAorICAgIGludDMyX3Qgb2xkVmFsdWUsIG5ld1ZhbHVlOworICAgIGxheWVyX2NibGtfdCAqIGNvbnN0IGxjYmxrID0gdGhpcy0+bGNibGs7CisgICAgZG8geworICAgICAgICBvbGRWYWx1ZSA9IGxjYmxrLT5zd2FwU3RhdGU7CisgICAgICAgICAgICAvLyBnZXQgdGhlIGN1cnJlbnQgdmFsdWUKKworICAgICAgICBMT0dfQVNTRVJUKG9sZFZhbHVlJmVGbGlwUmVxdWVzdGVkLAorICAgICAgICAgICAgImVGbGlwUmVxdWVzdGVkIG5vdCBzZXQsIHlldCB3ZSdyZSBmbGlwcGluZyEgKHN0YXRlPTB4JTA4bHgpIiwKKyAgICAgICAgICAgIGxvbmcob2xkVmFsdWUpKTsKKworICAgICAgICBuZXdWYWx1ZSA9IChvbGRWYWx1ZSBeIGVJbmRleCk7CisgICAgICAgICAgICAvLyBzd2FwIGJ1ZmZlcnMKKworICAgICAgICBuZXdWYWx1ZSAmPSB+KGVGbGlwUmVxdWVzdGVkIHwgZU5leHRGbGlwUGVuZGluZyk7CisgICAgICAgICAgICAvLyBjbGVhciBlRmxpcFJlcXVlc3RlZCBhbmQgZU5leHRGbGlwUGVuZGluZworCisgICAgICAgIGlmIChvbGRWYWx1ZSAmIGVOZXh0RmxpcFBlbmRpbmcpCisgICAgICAgICAgICBuZXdWYWx1ZSB8PSBlRmxpcFJlcXVlc3RlZDsKKyAgICAgICAgICAgIC8vIGlmIGVOZXh0RmxpcFBlbmRpbmcgaXMgc2V0IChzZWNvbmQgYnVmZmVyIGFscmVhZHkgaGFzIHNvbWV0aGluZworICAgICAgICAgICAgLy8gaW4gaXQpIHdlIG5lZWQgdG8gcmVzZXQgZUZsaXBSZXF1ZXN0ZWQgYmVjYXVzZSB0aGUgY2xpZW50CisgICAgICAgICAgICAvLyBtaWdodCBuZXZlciBkbyBpdAorCisgICAgfSB3aGlsZShhbmRyb2lkX2F0b21pY19jbXB4Y2hnKG9sZFZhbHVlLCBuZXdWYWx1ZSwgJihsY2Jsay0+c3dhcFN0YXRlKSkpOworICAgICpwcmV2aW91c1NhdGUgPSBvbGRWYWx1ZTsKKworICAgIGNvbnN0IGludDMyX3QgaW5kZXggPSAobmV3VmFsdWUgJiBlSW5kZXgpIF4gMTsKKyAgICBtRnJvbnRCdWZmZXJJbmRleCA9IGluZGV4OworCisgICAgLy8gLi4uIHBvc3QgdGhlIG5ldyBmcm9udC1idWZmZXIKKyAgICBSZWdpb24gZGlydHkobGNibGstPnJlZ2lvbiArIGluZGV4KTsKKyAgICBkaXJ0eS5hbmRTZWxmKGZyb250QnVmZmVyKCkuYm91bmRzKCkpOworCisgICAgLy9MT0dJKCJEaWQgcG9zdCBvbGRWYWx1ZT0lMDhseCwgbmV3VmFsdWU9JTA4bHgsIG1Gcm9udEJ1ZmZlckluZGV4PSV1XG4iLAorICAgIC8vICAgIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbUZyb250QnVmZmVySW5kZXgpOworICAgIC8vZGlydHkuZHVtcCgiZGlydHkiKTsKKworICAgIGlmIChVTkxJS0VMWShvbGRWYWx1ZSAmIGVSZXNpemVSZXF1ZXN0ZWQpKSB7CisKKyAgICAgICAgTE9HRF9JRihERUJVR19SRVNJWkUsCisgICAgICAgICAgICAgICAgICAgICAicG9zdCAobGF5ZXI9JXApLCBzdGF0ZT0lMDh4LCAiCisgICAgICAgICAgICAgICAgICAgICAiaW5kZXg9JWQsICglZHglZCksICglZHglZCkiLAorICAgICAgICAgICAgICAgICAgICAgdGhpcywgIG5ld1ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgaW50KDEtaW5kZXgpLAorICAgICAgICAgICAgICAgICAgICAgaW50KG1CdWZmZXJzWzBdLndpZHRoKCkpLCBpbnQobUJ1ZmZlcnNbMF0uaGVpZ2h0KCkpLAorICAgICAgICAgICAgICAgICAgICAgaW50KG1CdWZmZXJzWzFdLndpZHRoKCkpLCBpbnQobUJ1ZmZlcnNbMV0uaGVpZ2h0KCkpKTsKKworICAgICAgICAvLyBoZXJlLCB3ZSBqdXN0IHBvc3RlZCB0aGUgc3VyZmFjZSBhbmQgd2UgaGF2ZSByZXNvbHZlZAorICAgICAgICAvLyB0aGUgZnJvbnQvYmFjayBidWZmZXIgaW5kaWNlcy4gVGhlIGNsaWVudCBpcyBibG9ja2VkLCBzbworICAgICAgICAvLyBpdCBjYW5ub3Qgc3RhcnQgdXNpbmcgdGhlIG5ldyBiYWNrYnVmZmVyLgorCisgICAgICAgIC8vIElmIHRoZSBiYWNrYnVmZmVyIHdhcyByZXNpemVkIGluIFRISVMgcm91bmQsIHdlIGFjdHVhbGx5IGNhbm5vdAorICAgICAgICAvLyByZXNpemUgdGhlIGZyb250YnVmZmVyIGJlY2F1c2UgaXQgaGFzICpqdXN0KiBiZWVuIGRyYXduIChhbmQgd2UKKyAgICAgICAgLy8gd291bGQgaGF2ZSBub3RoaW5nIHRvIGRyYXcpLiBJbiB0aGlzIGNhc2Ugd2UganVzdCBza2lwIHRoZSByZXNpemUKKyAgICAgICAgLy8gaXQnbGwgaGFwcGVuIGFmdGVyIHRoZSBuZXh0IHBhZ2UgZmxpcCBvciBkdXJpbmcgdGhlIG5leHQKKyAgICAgICAgLy8gdHJhbnNhY3Rpb24uCisKKyAgICAgICAgY29uc3QgdWludDMyX3QgbWFzayA9ICgxLWluZGV4KSA/IGVSZXNpemVCdWZmZXIxIDogZVJlc2l6ZUJ1ZmZlcjA7CisgICAgICAgIGlmIChtUmVzaXplVHJhbnNhY3Rpb25Eb25lICYmIChuZXdWYWx1ZSAmIG1hc2spKSB7CisgICAgICAgICAgICAvLyBSZXNpemUgdGhlIGxheWVyJ3Mgc2Vjb25kIGJ1ZmZlciBvbmx5IGlmIHRoZSB0cmFuc2FjdGlvbgorICAgICAgICAgICAgLy8gaGFwcGVuZWQuIEl0IG1heSBub3QgaGF2ZSBoYXBwZW5lZCB5ZXQgaWYgZVJlc2l6ZVJlcXVlc3RlZAorICAgICAgICAgICAgLy8gd2FzIHNldCBpbW1lZGlhdGVseSBhZnRlciB0aGUgInRyYW5zYWN0aW9uUmVxdWVzdGVkIiB0ZXN0LAorICAgICAgICAgICAgLy8gaW4gd2hpY2ggY2FzZSB0aGUgZHJhd2luZyBzdGF0ZSdzIHNpemUgd291bGQgYmUgd3JvbmcuCisgICAgICAgICAgICBtRnJlZXplTG9jay5jbGVhcigpOworICAgICAgICAgICAgY29uc3QgTGF5ZXI6OlN0YXRlJiBzKGRyYXdpbmdTdGF0ZSgpKTsKKyAgICAgICAgICAgIGlmIChyZXNpemUoMS1pbmRleCwgcy53LCBzLmgsICJwb3N0IikgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gbGNibGstPnN3YXBTdGF0ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChvbGRWYWx1ZSAmIGVSZXNpemVSZXF1ZXN0ZWQpID09IGVSZXNpemVSZXF1ZXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVnaCwgYW5vdGhlciByZXNpemUgd2FzIHJlcXVlc3RlZCBzaW5jZSB3ZSBwcm9jZXNzZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBidWZmZXIsIGRvbid0IGZyZWUgdGhlIGNsaWVudCwgYW5kIGxldAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG5leHQgdHJhbnNhY3Rpb24gaGFuZGxlIGV2ZXJ5dGhpbmcuCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZSA9IG9sZFZhbHVlICYgfm1hc2s7CisgICAgICAgICAgICAgICAgfSB3aGlsZShhbmRyb2lkX2F0b21pY19jbXB4Y2hnKG9sZFZhbHVlLCBuZXdWYWx1ZSwgJihsY2Jsay0+c3dhcFN0YXRlKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbVJlc2l6ZVRyYW5zYWN0aW9uRG9uZSA9IGZhbHNlOworICAgICAgICAgICAgcmVjb21wdXRlVmlzaWJsZVJlZ2lvbnMgPSB0cnVlOworICAgICAgICAgICAgdGhpcy0+Y29udGVudERpcnR5ID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJlbG9hZFRleHR1cmUoZGlydHkpOworCisgICAgcmV0dXJuIGRpcnR5OworfQorCitQb2ludCBMYXllcjo6Z2V0UGh5c2ljYWxTaXplKCkgY29uc3QKK3sKKyAgICBjb25zdCBMYXllckJpdG1hcCYgZnJvbnQoZnJvbnRCdWZmZXIoKSk7CisgICAgcmV0dXJuIFBvaW50KGZyb250LndpZHRoKCksIGZyb250LmhlaWdodCgpKTsKK30KKwordm9pZCBMYXllcjo6dW5sb2NrUGFnZUZsaXAoCisgICAgICAgIGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0sIFJlZ2lvbiYgb3V0RGlydHlSZWdpb24pCit7CisgICAgUmVnaW9uIGRpcnR5UmVnaW9uKG1Qb3N0ZWREaXJ0eVJlZ2lvbik7CisgICAgaWYgKCFkaXJ0eVJlZ2lvbi5pc0VtcHR5KCkpIHsKKyAgICAgICAgbVBvc3RlZERpcnR5UmVnaW9uLmNsZWFyKCk7CisgICAgICAgIC8vIFRoZSBkaXJ0eSByZWdpb24gaXMgZ2l2ZW4gaW4gdGhlIGxheWVyJ3MgY29vcmRpbmF0ZSBzcGFjZQorICAgICAgICAvLyB0cmFuc2Zvcm0gdGhlIGRpcnR5IHJlZ2lvbiBieSB0aGUgc3VyZmFjZSdzIHRyYW5zZm9ybWF0aW9uCisgICAgICAgIC8vIGFuZCB0aGUgZ2xvYmFsIHRyYW5zZm9ybWF0aW9uLgorICAgICAgICBjb25zdCBMYXllcjo6U3RhdGUmIHMoZHJhd2luZ1N0YXRlKCkpOworICAgICAgICBjb25zdCBUcmFuc2Zvcm0gdHIocGxhbmVUcmFuc2Zvcm0gKiBzLnRyYW5zZm9ybSk7CisgICAgICAgIGRpcnR5UmVnaW9uID0gdHIudHJhbnNmb3JtKGRpcnR5UmVnaW9uKTsKKworICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB0aGUgZGlydHkgcmVnaW9uIGlzIGluIHNjcmVlbiBzcGFjZS4KKyAgICAgICAgLy8gTWFrZSBzdXJlIGl0J3MgY29uc3RyYWluZWQgYnkgdGhlIHZpc2libGUgcmVnaW9uICh3aGljaAorICAgICAgICAvLyBpcyBpbiBzY3JlZW4gc3BhY2UgYXMgd2VsbCkuCisgICAgICAgIGRpcnR5UmVnaW9uLmFuZFNlbGYodmlzaWJsZVJlZ2lvblNjcmVlbik7CisgICAgICAgIG91dERpcnR5UmVnaW9uLm9yU2VsZihkaXJ0eVJlZ2lvbik7CisKKyAgICAgICAgLy8gY2xpZW50IGNvdWxkIGJlIGJsb2NrZWQsIHNvIHNpZ25hbCB0aGVtIHNvIHRoZXkgZ2V0IGEKKyAgICAgICAgLy8gY2hhbmNlIHRvIHJlZXZhbHVhdGUgdGhlaXIgY29uZGl0aW9uLgorICAgICAgICBtRmxpbmdlci0+c2NoZWR1bGVCcm9hZGNhc3QoY2xpZW50KTsKKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXI6OmZpbmlzaFBhZ2VGbGlwKCkKK3sKKyAgICBpZiAoTElLRUxZKCEobGNibGstPnN3YXBTdGF0ZSAmIGVJbnZhbGlkU3VyZmFjZSkpKSB7CisgICAgICAgIExPR0VfSUYoIShsY2Jsay0+c3dhcFN0YXRlICYgZUJ1c3kpLAorICAgICAgICAgICAgICAgICJsYXllciAlcCB3YXNuJ3QgbG9ja2VkISIsIHRoaXMpOworICAgICAgICBhbmRyb2lkX2F0b21pY19hbmQofmVCdXN5LCAmKGxjYmxrLT5zd2FwU3RhdGUpKTsKKyAgICB9CisgICAgbUZsaW5nZXItPnNjaGVkdWxlQnJvYWRjYXN0KGNsaWVudCk7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXIuaCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODY3ZjJiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllci5oCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0xBWUVSX0gKKyNkZWZpbmUgQU5EUk9JRF9MQVlFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3VpL1NoYXJlZFN0YXRlLmg+CisjaW5jbHVkZSA8cHJpdmF0ZS91aS9MYXllclN0YXRlLmg+CisKKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisKKyNpbmNsdWRlICJMYXllckJpdG1hcC5oIgorI2luY2x1ZGUgIkxheWVyQmFzZS5oIgorI2luY2x1ZGUgIlRyYW5zZm9ybS5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBDbGllbnQ7CitjbGFzcyBMYXllckJpdG1hcDsKK2NsYXNzIE1lbW9yeURlYWxlcjsKK2NsYXNzIEZyZWV6ZUxvY2s7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMYXllciA6IHB1YmxpYyBMYXllckJhc2VDbGllbnQKK3sKK3B1YmxpYzogICAgCisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IHR5cGVJbmZvOworICAgIHN0YXRpYyBjb25zdCBjaGFyKiBjb25zdCB0eXBlSUQ7CisgICAgdmlydHVhbCBjaGFyIGNvbnN0KiBnZXRUeXBlSUQoKSBjb25zdCB7IHJldHVybiB0eXBlSUQ7IH0KKyAgICB2aXJ0dWFsIHVpbnQzMl90IGdldFR5cGVJbmZvKCkgY29uc3QgeyByZXR1cm4gdHlwZUluZm87IH0KKworICAgICAgICAgICAgICAgICBMYXllcihTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpZW50KiBjLCBpbnQzMl90IGkpOworCisgICAgICAgIHZpcnR1YWwgfkxheWVyKCk7CisKKyAgICBpbmxpbmUgUGl4ZWxGb3JtYXQgcGl4ZWxGb3JtYXQoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBmcm9udEJ1ZmZlcigpLnBpeGVsRm9ybWF0KCk7CisgICAgfQorCisgICAgc3RhdHVzX3Qgc2V0QnVmZmVycyggICAgQ2xpZW50KiBjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdywgdWludDMyX3QgaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQsIHVpbnQzMl90IGZsYWdzPTApOworCisgICAgdmlydHVhbCB2b2lkIG9uRHJhdyhjb25zdCBSZWdpb24mIGNsaXApIGNvbnN0OworICAgIHZpcnR1YWwgdm9pZCBpbml0U3RhdGVzKHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIHVpbnQzMl90IGZsYWdzKTsKKyAgICB2aXJ0dWFsIHZvaWQgc2V0U2l6ZUNoYW5nZWQodWludDMyX3QgdywgdWludDMyX3QgaCk7CisgICAgdmlydHVhbCB1aW50MzJfdCBkb1RyYW5zYWN0aW9uKHVpbnQzMl90IHRyYW5zYWN0aW9uRmxhZ3MpOworICAgIHZpcnR1YWwgUG9pbnQgZ2V0UGh5c2ljYWxTaXplKCkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkIGxvY2tQYWdlRmxpcChib29sJiByZWNvbXB1dGVWaXNpYmxlUmVnaW9ucyk7CisgICAgdmlydHVhbCB2b2lkIHVubG9ja1BhZ2VGbGlwKGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0sIFJlZ2lvbiYgb3V0RGlydHlSZWdpb24pOworICAgIHZpcnR1YWwgdm9pZCBmaW5pc2hQYWdlRmxpcCgpOworICAgIHZpcnR1YWwgYm9vbCBuZWVkc0JsZW5kaW5nKCkgY29uc3QgICAgICB7IHJldHVybiBtTmVlZHNCbGVuZGluZzsgfQorICAgIHZpcnR1YWwgYm9vbCBpc1NlY3VyZSgpIGNvbnN0ICAgICAgICAgICB7IHJldHVybiBtU2VjdXJlOyB9CisgICAgdmlydHVhbCBHTHVpbnQgZ2V0VGV4dHVyZU5hbWUoKSBjb25zdCAgIHsgcmV0dXJuIG1UZXh0dXJlTmFtZTsgfQorICAgIHZpcnR1YWwgc3A8U3VyZmFjZT4gZ2V0U3VyZmFjZSgpIGNvbnN0OworCisgICAgY29uc3QgTGF5ZXJCaXRtYXAmIGdldEJ1ZmZlcihpbnQgaSkgY29uc3QgeyByZXR1cm4gbUJ1ZmZlcnNbaV07IH0KKyAgICAgICAgICBMYXllckJpdG1hcCYgZ2V0QnVmZmVyKGludCBpKSAgICAgICB7IHJldHVybiBtQnVmZmVyc1tpXTsgfQorCisgICAgLy8gb25seSBmb3IgZGVidWdnaW5nCisgICAgY29uc3Qgc3A8RnJlZXplTG9jaz4mICBnZXRGcmVlemVMb2NrKCkgY29uc3QgeyByZXR1cm4gbUZyZWV6ZUxvY2s7IH0KKworcHJpdmF0ZToKKyAgICBpbmxpbmUgY29uc3QgTGF5ZXJCaXRtYXAmCisgICAgICAgICAgICBmcm9udEJ1ZmZlcigpIGNvbnN0IHsgcmV0dXJuIGdldEJ1ZmZlcihtRnJvbnRCdWZmZXJJbmRleCk7IH0KKyAgICBpbmxpbmUgTGF5ZXJCaXRtYXAmCisgICAgICAgICAgICBmcm9udEJ1ZmZlcigpICAgICAgIHsgcmV0dXJuIGdldEJ1ZmZlcihtRnJvbnRCdWZmZXJJbmRleCk7IH0KKyAgICBpbmxpbmUgY29uc3QgTGF5ZXJCaXRtYXAmCisgICAgICAgICAgICBiYWNrQnVmZmVyKCkgY29uc3QgIHsgcmV0dXJuIGdldEJ1ZmZlcigxLW1Gcm9udEJ1ZmZlckluZGV4KTsgfQorICAgIGlubGluZSBMYXllckJpdG1hcCYKKyAgICAgICAgICAgIGJhY2tCdWZmZXIoKSAgICAgICAgeyByZXR1cm4gZ2V0QnVmZmVyKDEtbUZyb250QnVmZmVySW5kZXgpOyB9CisKKyAgICB2b2lkIHJlbG9hZFRleHR1cmUoY29uc3QgUmVnaW9uJiBkaXJ0eSk7CisKKyAgICBzdGF0dXNfdCByZXNpemUoaW50MzJfdCBpbmRleCwgdWludDMyX3QgdywgdWludDMyX3QgaCwgY29uc3QgY2hhciogd2hhdCk7CisgICAgUmVnaW9uIHBvc3QodWludDMyX3QqIG9sZFN0YXRlLCBib29sJiByZWNvbXB1dGVWaXNpYmxlUmVnaW9ucyk7CisgICAgc3RhdHVzX3QgcmVhbGxvY2F0ZUJ1ZmZlcihpbnQzMl90IGluZGV4LCB1aW50MzJfdCB3LCB1aW50MzJfdCBoKTsKKworICAgIHNwPFN1cmZhY2U+ICAgICAgICAgICAgIG1TdXJmYWNlOworCisgICAgICAgICAgICBib29sICAgICAgICAgICAgbVNlY3VyZTsKKyAgICAgICAgICAgIExheWVyQml0bWFwICAgICBtQnVmZmVyc1syXTsKKyAgICAgICAgICAgIGludDMyX3QgICAgICAgICBtRnJvbnRCdWZmZXJJbmRleDsKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICBtTmVlZHNCbGVuZGluZzsKKyAgICAgICAgICAgIGJvb2wgICAgICAgICAgICBtUmVzaXplVHJhbnNhY3Rpb25Eb25lOworICAgICAgICAgICAgUmVnaW9uICAgICAgICAgIG1Qb3N0ZWREaXJ0eVJlZ2lvbjsKKyAgICAgICAgICAgIHNwPEZyZWV6ZUxvY2s+ICBtRnJlZXplTG9jazsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgR0x1aW50ICAgICAgICAgIG1UZXh0dXJlTmFtZTsKKyAgICAgICAgICAgIEdMdWludCAgICAgICAgICBtVGV4dHVyZVdpZHRoOworICAgICAgICAgICAgR0x1aW50ICAgICAgICAgIG1UZXh0dXJlSGVpZ2h0OworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0xBWUVSX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCYXNlLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wY2Y1M2Y3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJhc2UuY3BwCkBAIC0wLDAgKzEsNzQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8R0xFUy9nbGV4dC5oPgorCisjaW5jbHVkZSA8aGFyZHdhcmUvaGFyZHdhcmUuaD4KKworI2luY2x1ZGUgImNsei5oIgorI2luY2x1ZGUgIkxheWVyQmFzZS5oIgorI2luY2x1ZGUgIkxheWVyQmx1ci5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZS5oIgorCisKKy8vIFdlIGRvbid0IGhvbm9yIHRoZSBwcmVtdWx0aXBsaWVkIGFscGhhIGZsYWdzLCB3aGljaCBtZWFucyB0aGF0CisvLyBwcmVtdWx0aXBsaWVkIHN1cmZhY2UgbWF5IGJlIGNvbXBvc2VkIHVzaW5nIGEgbm9uLXByZW11bHRpcGxpZWQKKy8vIGVxdWF0aW9uLiBXZSBkbyB0aGlzIGJlY2F1c2UgaXQgbWF5IGJlIGEgbG90IGZhc3RlciBvbiBzb21lIGhhcmR3YXJlCisvLyBUaGUgY29ycmVjdCB2YWx1ZSBpcyBIT05PUl9QUkVNVUxUSVBMSUVEX0FMUEhBID0gMQorI2RlZmluZSBIT05PUl9QUkVNVUxUSVBMSUVEX0FMUEhBICAgMAorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCB1aW50MzJfdCBMYXllckJhc2U6OnR5cGVJbmZvID0gMTsKK2NvbnN0IGNoYXIqIGNvbnN0IExheWVyQmFzZTo6dHlwZUlEID0gIkxheWVyQmFzZSI7CisKK2NvbnN0IHVpbnQzMl90IExheWVyQmFzZUNsaWVudDo6dHlwZUluZm8gPSBMYXllckJhc2U6OnR5cGVJbmZvIHwgMjsKK2NvbnN0IGNoYXIqIGNvbnN0IExheWVyQmFzZUNsaWVudDo6dHlwZUlEID0gIkxheWVyQmFzZUNsaWVudCI7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitWZWN0b3I8R0x1aW50PiBMYXllckJhc2U6OmRlbGV0ZWRUZXh0dXJlczsgCisKK2ludDMyX3QgTGF5ZXJCYXNlOjpzSWRlbnRpdHkgPSAwOworCitMYXllckJhc2U6OkxheWVyQmFzZShTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXkpCisgICAgOiBkcHkoZGlzcGxheSksIGNvbnRlbnREaXJ0eShmYWxzZSksCisgICAgICBtRmxpbmdlcihmbGluZ2VyKSwKKyAgICAgIG1UcmFuc2Zvcm1lZChmYWxzZSksCisgICAgICBtT3JpZW50YXRpb24oMCksCisgICAgICBtQ2FuVXNlQ29weUJpdChmYWxzZSksCisgICAgICBtVHJhbnNhY3Rpb25GbGFncygwKSwKKyAgICAgIG1QcmVtdWx0aXBsaWVkQWxwaGEodHJ1ZSksCisgICAgICBtSWRlbnRpdHkodWludDMyX3QoYW5kcm9pZF9hdG9taWNfaW5jKCZzSWRlbnRpdHkpKSksCisgICAgICBtSW52YWxpZGF0ZSgwKQoreworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZmxpbmdlci0+Z3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICBtRmxhZ3MgPSBody5nZXRGbGFncygpOworfQorCitMYXllckJhc2U6On5MYXllckJhc2UoKQoreworfQorCitjb25zdCBHcmFwaGljUGxhbmUmIExheWVyQmFzZTo6Z3JhcGhpY1BsYW5lKGludCBkcHkpIGNvbnN0Cit7IAorICAgIHJldHVybiBtRmxpbmdlci0+Z3JhcGhpY1BsYW5lKGRweSk7Cit9CisKK0dyYXBoaWNQbGFuZSYgTGF5ZXJCYXNlOjpncmFwaGljUGxhbmUoaW50IGRweSkKK3sKKyAgICByZXR1cm4gbUZsaW5nZXItPmdyYXBoaWNQbGFuZShkcHkpOyAKK30KKwordm9pZCBMYXllckJhc2U6OmluaXRTdGF0ZXModWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgdWludDMyX3QgbGF5ZXJGbGFncyA9IDA7CisgICAgaWYgKGZsYWdzICYgSVN1cmZhY2VDb21wb3Nlcjo6ZUhpZGRlbikKKyAgICAgICAgbGF5ZXJGbGFncyA9IElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckhpZGRlbjsKKworICAgIGlmIChmbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVOb25QcmVtdWx0aXBsaWVkKQorICAgICAgICBtUHJlbXVsdGlwbGllZEFscGhhID0gZmFsc2U7CisKKyAgICBtQ3VycmVudFN0YXRlLnogICAgICAgICA9IDA7CisgICAgbUN1cnJlbnRTdGF0ZS53ICAgICAgICAgPSB3OworICAgIG1DdXJyZW50U3RhdGUuaCAgICAgICAgID0gaDsKKyAgICBtQ3VycmVudFN0YXRlLmFscGhhICAgICA9IDB4RkY7CisgICAgbUN1cnJlbnRTdGF0ZS5mbGFncyAgICAgPSBsYXllckZsYWdzOworICAgIG1DdXJyZW50U3RhdGUuc2VxdWVuY2UgID0gMDsKKyAgICBtQ3VycmVudFN0YXRlLnRyYW5zZm9ybS5zZXQoMCwgMCk7CisKKyAgICAvLyBkcmF3aW5nIHN0YXRlICYgY3VycmVudCBzdGF0ZSBhcmUgaWRlbnRpY2FsCisgICAgbURyYXdpbmdTdGF0ZSA9IG1DdXJyZW50U3RhdGU7Cit9CisKK3ZvaWQgTGF5ZXJCYXNlOjpjb21taXRUcmFuc2FjdGlvbihib29sIHNraXBTaXplKSB7CisgICAgY29uc3QgdWludDMyX3QgdyA9IG1EcmF3aW5nU3RhdGUudzsKKyAgICBjb25zdCB1aW50MzJfdCBoID0gbURyYXdpbmdTdGF0ZS5oOworICAgIG1EcmF3aW5nU3RhdGUgPSBtQ3VycmVudFN0YXRlOworICAgIGlmIChza2lwU2l6ZSkgeworICAgICAgICBtRHJhd2luZ1N0YXRlLncgPSB3OworICAgICAgICBtRHJhd2luZ1N0YXRlLmggPSBoOworICAgIH0KK30KK3ZvaWQgTGF5ZXJCYXNlOjpmb3JjZVZpc2liaWxpdHlUcmFuc2FjdGlvbigpIHsKKyAgICAvLyB0aGlzIGNhbiBiZSBjYWxsZWQgd2l0aG91dCBTdXJmYWNlRmxpbmdlci5tU3RhdGVMb2NrLCBidXQgaWYgd2UKKyAgICAvLyBjYW4gYXRvbWljYWxseSBpbmNyZW1lbnQgdGhlIHNlcXVlbmNlIG51bWJlciwgaXQgZG9lc24ndCBtYXR0ZXIuCisgICAgYW5kcm9pZF9hdG9taWNfaW5jKCZtQ3VycmVudFN0YXRlLnNlcXVlbmNlKTsKKyAgICByZXF1ZXN0VHJhbnNhY3Rpb24oKTsKK30KK2Jvb2wgTGF5ZXJCYXNlOjpyZXF1ZXN0VHJhbnNhY3Rpb24oKSB7CisgICAgaW50MzJfdCBvbGQgPSBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZCk7CisgICAgcmV0dXJuICgob2xkICYgZVRyYW5zYWN0aW9uTmVlZGVkKSA9PSAwKTsKK30KK3VpbnQzMl90IExheWVyQmFzZTo6Z2V0VHJhbnNhY3Rpb25GbGFncyh1aW50MzJfdCBmbGFncykgeworICAgIHJldHVybiBhbmRyb2lkX2F0b21pY19hbmQofmZsYWdzLCAmbVRyYW5zYWN0aW9uRmxhZ3MpICYgZmxhZ3M7Cit9Cit1aW50MzJfdCBMYXllckJhc2U6OnNldFRyYW5zYWN0aW9uRmxhZ3ModWludDMyX3QgZmxhZ3MpIHsKKyAgICByZXR1cm4gYW5kcm9pZF9hdG9taWNfb3IoZmxhZ3MsICZtVHJhbnNhY3Rpb25GbGFncyk7Cit9CisKK3ZvaWQgTGF5ZXJCYXNlOjpzZXRTaXplQ2hhbmdlZCh1aW50MzJfdCB3LCB1aW50MzJfdCBoKSB7Cit9CisKK2Jvb2wgTGF5ZXJCYXNlOjpzZXRQb3NpdGlvbihpbnQzMl90IHgsIGludDMyX3QgeSkgeworICAgIGlmIChtQ3VycmVudFN0YXRlLnRyYW5zZm9ybS50eCgpID09IHggJiYgbUN1cnJlbnRTdGF0ZS50cmFuc2Zvcm0udHkoKSA9PSB5KQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgbUN1cnJlbnRTdGF0ZS5zZXF1ZW5jZSsrOworICAgIG1DdXJyZW50U3RhdGUudHJhbnNmb3JtLnNldCh4LCB5KTsKKyAgICByZXF1ZXN0VHJhbnNhY3Rpb24oKTsKKyAgICByZXR1cm4gdHJ1ZTsKK30KK2Jvb2wgTGF5ZXJCYXNlOjpzZXRMYXllcih1aW50MzJfdCB6KSB7CisgICAgaWYgKG1DdXJyZW50U3RhdGUueiA9PSB6KQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgbUN1cnJlbnRTdGF0ZS5zZXF1ZW5jZSsrOworICAgIG1DdXJyZW50U3RhdGUueiA9IHo7CisgICAgcmVxdWVzdFRyYW5zYWN0aW9uKCk7CisgICAgcmV0dXJuIHRydWU7Cit9Citib29sIExheWVyQmFzZTo6c2V0U2l6ZSh1aW50MzJfdCB3LCB1aW50MzJfdCBoKSB7CisgICAgaWYgKG1DdXJyZW50U3RhdGUudyA9PSB3ICYmIG1DdXJyZW50U3RhdGUuaCA9PSBoKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgc2V0U2l6ZUNoYW5nZWQodywgaCk7CisgICAgbUN1cnJlbnRTdGF0ZS53ID0gdzsKKyAgICBtQ3VycmVudFN0YXRlLmggPSBoOworICAgIHJlcXVlc3RUcmFuc2FjdGlvbigpOworICAgIHJldHVybiB0cnVlOworfQorYm9vbCBMYXllckJhc2U6OnNldEFscGhhKHVpbnQ4X3QgYWxwaGEpIHsKKyAgICBpZiAobUN1cnJlbnRTdGF0ZS5hbHBoYSA9PSBhbHBoYSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIG1DdXJyZW50U3RhdGUuc2VxdWVuY2UrKzsKKyAgICBtQ3VycmVudFN0YXRlLmFscGhhID0gYWxwaGE7CisgICAgcmVxdWVzdFRyYW5zYWN0aW9uKCk7CisgICAgcmV0dXJuIHRydWU7Cit9Citib29sIExheWVyQmFzZTo6c2V0TWF0cml4KGNvbnN0IGxheWVyX3N0YXRlX3Q6Om1hdHJpeDIyX3QmIG1hdHJpeCkgeworICAgIC8vIFRPRE86IGNoZWNrIHRoZSBtYXRyaXggaGFzIGNoYW5nZWQKKyAgICBtQ3VycmVudFN0YXRlLnNlcXVlbmNlKys7CisgICAgbUN1cnJlbnRTdGF0ZS50cmFuc2Zvcm0uc2V0KAorICAgICAgICAgICAgbWF0cml4LmRzZHgsIG1hdHJpeC5kc2R5LCBtYXRyaXguZHRkeCwgbWF0cml4LmR0ZHkpOworICAgIHJlcXVlc3RUcmFuc2FjdGlvbigpOworICAgIHJldHVybiB0cnVlOworfQorYm9vbCBMYXllckJhc2U6OnNldFRyYW5zcGFyZW50UmVnaW9uSGludChjb25zdCBSZWdpb24mIHRyYW5zcGFyZW50KSB7CisgICAgLy8gVE9ETzogY2hlY2sgdGhlIHJlZ2lvbiBoYXMgY2hhbmdlZAorICAgIG1DdXJyZW50U3RhdGUuc2VxdWVuY2UrKzsKKyAgICBtQ3VycmVudFN0YXRlLnRyYW5zcGFyZW50UmVnaW9uID0gdHJhbnNwYXJlbnQ7CisgICAgcmVxdWVzdFRyYW5zYWN0aW9uKCk7CisgICAgcmV0dXJuIHRydWU7Cit9Citib29sIExheWVyQmFzZTo6c2V0RmxhZ3ModWludDhfdCBmbGFncywgdWludDhfdCBtYXNrKSB7CisgICAgY29uc3QgdWludDMyX3QgbmV3RmxhZ3MgPSAobUN1cnJlbnRTdGF0ZS5mbGFncyAmIH5tYXNrKSB8IChmbGFncyAmIG1hc2spOworICAgIGlmIChtQ3VycmVudFN0YXRlLmZsYWdzID09IG5ld0ZsYWdzKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgbUN1cnJlbnRTdGF0ZS5zZXF1ZW5jZSsrOworICAgIG1DdXJyZW50U3RhdGUuZmxhZ3MgPSBuZXdGbGFnczsKKyAgICByZXF1ZXN0VHJhbnNhY3Rpb24oKTsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworUmVjdCBMYXllckJhc2U6OnZpc2libGVCb3VuZHMoKSBjb25zdAoreworICAgIHJldHVybiBtVHJhbnNmb3JtZWRCb3VuZHM7Cit9ICAgICAgCisKK3ZvaWQgTGF5ZXJCYXNlOjpzZXRWaXNpYmxlUmVnaW9uKGNvbnN0IFJlZ2lvbiYgdmlzaWJsZVJlZ2lvbikgeworICAgIC8vIGFsd2F5cyBjYWxsZWQgZnJvbSBtYWluIHRocmVhZAorICAgIHZpc2libGVSZWdpb25TY3JlZW4gPSB2aXNpYmxlUmVnaW9uOworfQorCit2b2lkIExheWVyQmFzZTo6c2V0Q292ZXJlZFJlZ2lvbihjb25zdCBSZWdpb24mIGNvdmVyZWRSZWdpb24pIHsKKyAgICAvLyBhbHdheXMgY2FsbGVkIGZyb20gbWFpbiB0aHJlYWQKKyAgICBjb3ZlcmVkUmVnaW9uU2NyZWVuID0gY292ZXJlZFJlZ2lvbjsKK30KKwordWludDMyX3QgTGF5ZXJCYXNlOjpkb1RyYW5zYWN0aW9uKHVpbnQzMl90IGZsYWdzKQoreworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgZnJvbnQoZHJhd2luZ1N0YXRlKCkpOworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgdGVtcChjdXJyZW50U3RhdGUoKSk7CisKKyAgICBpZiAodGVtcC5zZXF1ZW5jZSAhPSBmcm9udC5zZXF1ZW5jZSkgeworICAgICAgICAvLyBpbnZhbGlkYXRlIGFuZCByZWNvbXB1dGUgdGhlIHZpc2libGUgcmVnaW9ucyBpZiBuZWVkZWQKKyAgICAgICAgZmxhZ3MgfD0gZVZpc2libGVSZWdpb247CisgICAgICAgIHRoaXMtPmNvbnRlbnREaXJ0eSA9IHRydWU7CisgICAgfQorICAgIAorICAgIC8vIENvbW1pdCB0aGUgdHJhbnNhY3Rpb24KKyAgICBjb21taXRUcmFuc2FjdGlvbihmbGFncyAmIGVSZXN0YXJ0VHJhbnNhY3Rpb24pOworICAgIHJldHVybiBmbGFnczsKK30KKworUG9pbnQgTGF5ZXJCYXNlOjpnZXRQaHlzaWNhbFNpemUoKSBjb25zdAoreworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgZnJvbnQoZHJhd2luZ1N0YXRlKCkpOworICAgIHJldHVybiBQb2ludChmcm9udC53LCBmcm9udC5oKTsKK30KKwordm9pZCBMYXllckJhc2U6OnZhbGlkYXRlVmlzaWJpbGl0eShjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtKQoreworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgcyhkcmF3aW5nU3RhdGUoKSk7CisgICAgY29uc3QgVHJhbnNmb3JtIHRyKHBsYW5lVHJhbnNmb3JtICogcy50cmFuc2Zvcm0pOworICAgIGNvbnN0IGJvb2wgdHJhbnNmb3JtZWQgPSB0ci50cmFuc2Zvcm1lZCgpOworICAgCisgICAgY29uc3QgUG9pbnQgc2l6ZShnZXRQaHlzaWNhbFNpemUoKSk7CisgICAgdWludDMyX3QgdyA9IHNpemUueDsKKyAgICB1aW50MzJfdCBoID0gc2l6ZS55OyAgICAKKyAgICB0ci50cmFuc2Zvcm0obVZlcnRpY2VzWzBdLCAwLCAwKTsKKyAgICB0ci50cmFuc2Zvcm0obVZlcnRpY2VzWzFdLCAwLCBoKTsKKyAgICB0ci50cmFuc2Zvcm0obVZlcnRpY2VzWzJdLCB3LCBoKTsKKyAgICB0ci50cmFuc2Zvcm0obVZlcnRpY2VzWzNdLCB3LCAwKTsKKyAgICBpZiAoVU5MSUtFTFkodHJhbnNmb3JtZWQpKSB7CisgICAgICAgIC8vIE5PVEU6IGhlcmUgd2UgY291bGQgYWxzbyBwdW50IGlmIHdlIGhhdmUgdG9vIG1hbnkgcmVjdGFuZ2xlcworICAgICAgICAvLyBpbiB0aGUgdHJhbnNwYXJlbnQgcmVnaW9uCisgICAgICAgIGlmICh0ci5wcmVzZXJ2ZVJlY3RzKCkpIHsKKyAgICAgICAgICAgIC8vIHRyYW5zZm9ybSB0aGUgdHJhbnNwYXJlbnQgcmVnaW9uCisgICAgICAgICAgICB0cmFuc3BhcmVudFJlZ2lvblNjcmVlbiA9IHRyLnRyYW5zZm9ybShzLnRyYW5zcGFyZW50UmVnaW9uKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHRyYW5zZm9ybWF0aW9uIHRvbyBjb21wbGV4LCBjYW4ndCBkbyB0aGUgdHJhbnNwYXJlbnQgcmVnaW9uCisgICAgICAgICAgICAvLyBvcHRpbWl6YXRpb24uCisgICAgICAgICAgICB0cmFuc3BhcmVudFJlZ2lvblNjcmVlbi5jbGVhcigpOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgdHJhbnNwYXJlbnRSZWdpb25TY3JlZW4gPSBzLnRyYW5zcGFyZW50UmVnaW9uOworICAgIH0KKworICAgIC8vIGNhY2hlIGEgZmV3IHRoaW5ncy4uLgorICAgIG1PcmllbnRhdGlvbiA9IHRyLmdldE9yaWVudGF0aW9uKCk7CisgICAgbVRyYW5zZm9ybWVkQm91bmRzID0gdHIubWFrZUJvdW5kcyh3LCBoKTsKKyAgICBtVHJhbnNmb3JtZWQgPSB0cmFuc2Zvcm1lZDsKKyAgICBtTGVmdCA9IHRyLnR4KCk7CisgICAgbVRvcCAgPSB0ci50eSgpOworCisgICAgLy8gc2VlIGlmIHdlIGNhbi9zaG91bGQgdXNlIDJEIGgvdyB3aXRoIHRoZSBuZXcgY29uZmlndXJhdGlvbgorICAgIG1DYW5Vc2VDb3B5Qml0ID0gZmFsc2U7CisgICAgY29weWJpdF9kZXZpY2VfdCogY29weWJpdCA9IG1GbGluZ2VyLT5nZXRCbGl0RW5naW5lKCk7CisgICAgaWYgKGNvcHliaXQpIHsgCisgICAgICAgIGNvbnN0IGludCBzdGVwID0gY29weWJpdC0+Z2V0KGNvcHliaXQsIENPUFlCSVRfUk9UQVRJT05fU1RFUF9ERUcpOworICAgICAgICBjb25zdCBpbnQgc2NhbGVCaXRzID0gY29weWJpdC0+Z2V0KGNvcHliaXQsIENPUFlCSVRfU0NBTElOR19GUkFDX0JJVFMpOworICAgICAgICBtQ2FuVXNlQ29weUJpdCA9IHRydWU7CisgICAgICAgIGlmICgobU9yaWVudGF0aW9uIDwgMCkgJiYgKHN0ZXAgPiAxKSkgeworICAgICAgICAgICAgLy8gYXJiaXRyYXJ5IG9yaWVudGF0aW9ucyBub3Qgc3VwcG9ydGVkCisgICAgICAgICAgICBtQ2FuVXNlQ29weUJpdCA9IGZhbHNlOworICAgICAgICB9IGVsc2UgaWYgKChtT3JpZW50YXRpb24gPiAwKSAmJiAoc3RlcCA+IDkwKSkgeworICAgICAgICAgICAgLy8gOTAgZGVnIHJvdGF0aW9ucyBub3Qgc3VwcG9ydGVkCisgICAgICAgICAgICBtQ2FuVXNlQ29weUJpdCA9IGZhbHNlOworICAgICAgICB9IGVsc2UgaWYgKCh0ci5nZXRUeXBlKCkgJiBTa01hdHJpeDo6a1NjYWxlX01hc2spICYmIChzY2FsZUJpdHMgPCAxMikpIHsgCisgICAgICAgICAgICAvLyBhcmJpdHJhcnkgc2NhbGluZyBub3Qgc3VwcG9ydGVkCisgICAgICAgICAgICBtQ2FuVXNlQ29weUJpdCA9IGZhbHNlOworICAgICAgICB9CisjaWYgSE9OT1JfUFJFTVVMVElQTElFRF9BTFBIQSAKKyAgICAgICAgZWxzZSBpZiAobmVlZHNCbGVuZGluZygpICYmIG1QcmVtdWx0aXBsaWVkQWxwaGEpIHsKKyAgICAgICAgICAgIC8vIHByZS1tdWx0aXBsaWVkIGFscGhhIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgICAgIG1DYW5Vc2VDb3B5Qml0ID0gZmFsc2U7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIC8vIGhlcmUsIHdlIGRldGVybWluZWQgd2UgY2FuIHVzZSBjb3B5Yml0CisgICAgICAgICAgICBpZiAodHIuZ2V0VHlwZSgpICYgU2tNYXRyaXg6OmtTY2FsZV9NYXNrKSB7CisgICAgICAgICAgICAgICAgLy8gYW5kIHdlIGhhdmUgc2NhbGluZworICAgICAgICAgICAgICAgIGlmICghdHJhbnNwYXJlbnRSZWdpb25TY3JlZW4uaXNSZWN0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UgcHVudCBiZWNhdXNlIGJsZW5kaW5nIGlzIGNoZWFwIChoL3cpIGFuZCB0aGUgcmVnaW9uIGlzCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbXBsZXgsIHdoaWNoIG1heSBjYXVzZXMgYXJ0aWZhY3RzIHdoZW4gY29weWluZworICAgICAgICAgICAgICAgICAgICAvLyBzY2FsZWQgY29udGVudAorICAgICAgICAgICAgICAgICAgICB0cmFuc3BhcmVudFJlZ2lvblNjcmVlbi5jbGVhcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKwordm9pZCBMYXllckJhc2U6OmxvY2tQYWdlRmxpcChib29sJiByZWNvbXB1dGVWaXNpYmxlUmVnaW9ucykKK3sKK30KKwordm9pZCBMYXllckJhc2U6OnVubG9ja1BhZ2VGbGlwKAorICAgICAgICBjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtLCBSZWdpb24mIG91dERpcnR5UmVnaW9uKQoreworICAgIGlmICgoYW5kcm9pZF9hdG9taWNfYW5kKH4xLCAmbUludmFsaWRhdGUpJjEpID09IDEpIHsKKyAgICAgICAgb3V0RGlydHlSZWdpb24ub3JTZWxmKHZpc2libGVSZWdpb25TY3JlZW4pOworICAgIH0KK30KKwordm9pZCBMYXllckJhc2U6OmZpbmlzaFBhZ2VGbGlwKCkKK3sKK30KKwordm9pZCBMYXllckJhc2U6OmludmFsaWRhdGUoKQoreworICAgIGlmICgoYW5kcm9pZF9hdG9taWNfb3IoMSwgJm1JbnZhbGlkYXRlKSYxKSA9PSAwKSB7CisgICAgICAgIG1GbGluZ2VyLT5zaWduYWxFdmVudCgpOworICAgIH0KK30KKwordm9pZCBMYXllckJhc2U6OmRyYXdSZWdpb24oY29uc3QgUmVnaW9uJiByZWcpIGNvbnN0Cit7CisgICAgUmVnaW9uOjppdGVyYXRvciBpdGVyYXRvcihyZWcpOworICAgIGlmIChpdGVyYXRvcikgeworICAgICAgICBSZWN0IHI7CisgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICAgICAgY29uc3QgaW50MzJfdCBmYldpZHRoICA9IGh3LmdldFdpZHRoKCk7CisgICAgICAgIGNvbnN0IGludDMyX3QgZmJIZWlnaHQgPSBody5nZXRIZWlnaHQoKTsKKyAgICAgICAgY29uc3QgR0xzaG9ydCB2ZXJ0aWNlc1tdWzJdID0geyB7IDAsIDAgfSwgeyBmYldpZHRoLCAwIH0sIAorICAgICAgICAgICAgICAgIHsgZmJXaWR0aCwgZmJIZWlnaHQgfSwgeyAwLCBmYkhlaWdodCB9ICB9OworICAgICAgICBnbFZlcnRleFBvaW50ZXIoMiwgR0xfU0hPUlQsIDAsIHZlcnRpY2VzKTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLml0ZXJhdGUoJnIpKSB7CisgICAgICAgICAgICBjb25zdCBHTGludCBzeSA9IGZiSGVpZ2h0IC0gKHIudG9wICsgci5oZWlnaHQoKSk7CisgICAgICAgICAgICBnbFNjaXNzb3Ioci5sZWZ0LCBzeSwgci53aWR0aCgpLCByLmhlaWdodCgpKTsKKyAgICAgICAgICAgIGdsRHJhd0FycmF5cyhHTF9UUklBTkdMRV9GQU4sIDAsIDQpOyAKKyAgICAgICAgfQorICAgIH0KK30KKwordm9pZCBMYXllckJhc2U6OmRyYXcoY29uc3QgUmVnaW9uJiBpbkNsaXApIGNvbnN0Cit7CisgICAgLy8gaW52YWxpZGF0ZSB0aGUgcmVnaW9uIHdlJ2xsIHVwZGF0ZQorICAgIFJlZ2lvbiBjbGlwKGluQ2xpcCk7ICAvLyBjb3B5LW9uLXdyaXRlLCBzbyBuby1vcCBtb3N0IG9mIHRoZSB0aW1lCisKKyAgICAvLyBSZW1vdmUgdGhlIHRyYW5zcGFyZW50IGFyZWEgZnJvbSB0aGUgY2xpcHBpbmcgcmVnaW9uCisgICAgY29uc3QgU3RhdGUmIHMgPSBkcmF3aW5nU3RhdGUoKTsKKyAgICBpZiAoTElLRUxZKCFzLnRyYW5zcGFyZW50UmVnaW9uLmlzRW1wdHkoKSkpIHsKKyAgICAgICAgY2xpcC5zdWJ0cmFjdCh0cmFuc3BhcmVudFJlZ2lvblNjcmVlbik7CisgICAgICAgIGlmIChjbGlwLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgLy8gdXN1YWxseSB0aGlzIHdvbid0IGhhcHBlbiBiZWNhdXNlIHRoaXMgc2hvdWxkIGJlIHRha2VuIGNhcmUgb2YKKyAgICAgICAgICAgIC8vIGJ5IFN1cmZhY2VGbGluZ2VyOjpjb21wdXRlVmlzaWJsZVJlZ2lvbnMoKQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9ICAgICAgICAKKyAgICB9CisKKyAgICAvLyByZXNldCBHTCBzdGF0ZQorICAgIGdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCk7CisKKyAgICBvbkRyYXcoY2xpcCk7CisKKyAgICAvKgorICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKKyAgICBnbERpc2FibGUoR0xfRElUSEVSKTsKKyAgICBnbEVuYWJsZShHTF9CTEVORCk7CisgICAgZ2xCbGVuZEZ1bmMoR0xfT05FLCBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBKTsKKyAgICBnbENvbG9yNHgoMCwgMHg4MDAwLCAwLCAweDEwMDAwKTsKKyAgICBkcmF3UmVnaW9uKHRyYW5zcGFyZW50UmVnaW9uU2NyZWVuKTsKKyAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgICovCit9CisKK0dMdWludCBMYXllckJhc2U6OmNyZWF0ZVRleHR1cmUoKSBjb25zdAoreworICAgIEdMdWludCB0ZXh0dXJlTmFtZSA9IC0xOworICAgIGdsR2VuVGV4dHVyZXMoMSwgJnRleHR1cmVOYW1lKTsKKyAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVOYW1lKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QX1RPX0VER0UpOworICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVBfVE9fRURHRSk7CisgICAgaWYgKG1GbGFncyAmIERpc3BsYXlIYXJkd2FyZTo6U0xPV19DT05GSUcpIHsKKyAgICAgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CisgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOworICAgIH0gZWxzZSB7CisgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX0xJTkVBUik7CisgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX0xJTkVBUik7CisgICAgfQorICAgIHJldHVybiB0ZXh0dXJlTmFtZTsKK30KKwordm9pZCBMYXllckJhc2U6OmNsZWFyV2l0aE9wZW5HTChjb25zdCBSZWdpb24mIGNsaXApIGNvbnN0Cit7CisgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIGNvbnN0IHVpbnQzMl90IGZiSGVpZ2h0ID0gaHcuZ2V0SGVpZ2h0KCk7CisgICAgZ2xDb2xvcjR4KDAsMCwwLDApOworICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKKyAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgIGdsRGlzYWJsZShHTF9ESVRIRVIpOworICAgIFJlY3QgcjsKKyAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKGNsaXApOworICAgIGlmIChpdGVyYXRvcikgeworICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOworICAgICAgICBnbFZlcnRleFBvaW50ZXIoMiwgR0xfRklYRUQsIDAsIG1WZXJ0aWNlcyk7CisgICAgICAgIHdoaWxlIChpdGVyYXRvci5pdGVyYXRlKCZyKSkgeworICAgICAgICAgICAgY29uc3QgR0xpbnQgc3kgPSBmYkhlaWdodCAtIChyLnRvcCArIHIuaGVpZ2h0KCkpOworICAgICAgICAgICAgZ2xTY2lzc29yKHIubGVmdCwgc3ksIHIud2lkdGgoKSwgci5oZWlnaHQoKSk7CisgICAgICAgICAgICBnbERyYXdBcnJheXMoR0xfVFJJQU5HTEVfRkFOLCAwLCA0KTsgCisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXJCYXNlOjpkcmF3V2l0aE9wZW5HTChjb25zdCBSZWdpb24mIGNsaXAsCisgICAgICAgIEdMaW50IHRleHR1cmVOYW1lLCBjb25zdCBHR0xTdXJmYWNlJiB0LCBpbnQgdHJhbnNmb3JtKSBjb25zdAoreworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICBjb25zdCB1aW50MzJfdCBmYkhlaWdodCA9IGh3LmdldEhlaWdodCgpOworICAgIGNvbnN0IFN0YXRlJiBzKGRyYXdpbmdTdGF0ZSgpKTsKKworICAgIC8vIGJpbmQgb3VyIHRleHR1cmUKKyAgICB2YWxpZGF0ZVRleHR1cmUodGV4dHVyZU5hbWUpOworICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOworCisgICAgLy8gRGl0aGVyaW5nLi4uCisgICAgaWYgKHMuZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJEaXRoZXIpIHsKKyAgICAgICAgZ2xFbmFibGUoR0xfRElUSEVSKTsKKyAgICB9IGVsc2UgeworICAgICAgICBnbERpc2FibGUoR0xfRElUSEVSKTsKKyAgICB9CisKKyAgICBpZiAoVU5MSUtFTFkocy5hbHBoYSA8IDB4RkYpKSB7CisgICAgICAgIC8vIFdlIGhhdmUgYW4gYWxwaGEtbW9kdWxhdGlvbi4gV2UgbmVlZCB0byBtb2R1bGF0ZSBhbGwKKyAgICAgICAgLy8gdGV4dHVyZSBjb21wb25lbnRzIGJ5IGFscGhhIGJlY2F1c2Ugd2UncmUgYWx3YXlzIHVzaW5nIAorICAgICAgICAvLyBwcmVtdWx0aXBsaWVkIGFscGhhLgorICAgICAgICAKKyAgICAgICAgLy8gSWYgdGhlIHRleHR1cmUgZG9lc24ndCBoYXZlIGFuIGFscGhhIGNoYW5uZWwgd2UgY2FuCisgICAgICAgIC8vIHVzZSBSRVBMQUNFIGFuZCBzd2l0Y2ggdG8gbm9uIHByZW11bHRpcGxpZWQgYWxwaGEKKyAgICAgICAgLy8gYmxlbmRpbmcgKFNSQ0EvT05FX01JTlVTX1NSQ0EpLgorICAgICAgICAKKyAgICAgICAgR0xlbnVtIGVudiwgc3JjOworICAgICAgICBpZiAobmVlZHNCbGVuZGluZygpKSB7CisgICAgICAgICAgICBlbnYgPSBHTF9NT0RVTEFURTsKKyAgICAgICAgICAgIHNyYyA9IG1QcmVtdWx0aXBsaWVkQWxwaGEgPyBHTF9PTkUgOiBHTF9TUkNfQUxQSEE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBlbnYgPSBHTF9SRVBMQUNFOworICAgICAgICAgICAgc3JjID0gR0xfU1JDX0FMUEhBOworICAgICAgICB9CisgICAgICAgIGNvbnN0IEdHTGZpeGVkIGFscGhhID0gKHMuYWxwaGEgPDwgMTYpLzI1NTsKKyAgICAgICAgZ2xDb2xvcjR4KGFscGhhLCBhbHBoYSwgYWxwaGEsIGFscGhhKTsKKyAgICAgICAgZ2xFbmFibGUoR0xfQkxFTkQpOworICAgICAgICBnbEJsZW5kRnVuYyhzcmMsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOworICAgICAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIGVudik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKKyAgICAgICAgZ2xDb2xvcjR4KDB4MTAwMDAsIDB4MTAwMDAsIDB4MTAwMDAsIDB4MTAwMDApOworICAgICAgICBpZiAobmVlZHNCbGVuZGluZygpKSB7CisgICAgICAgICAgICBHTGVudW0gc3JjID0gbVByZW11bHRpcGxpZWRBbHBoYSA/IEdMX09ORSA6IEdMX1NSQ19BTFBIQTsKKyAgICAgICAgICAgIGdsRW5hYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgICAgIGdsQmxlbmRGdW5jKHNyYywgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKFVOTElLRUxZKHRyYW5zZm9ybWVkKCkKKyAgICAgICAgICAgIHx8ICEobUZsYWdzICYgRGlzcGxheUhhcmR3YXJlOjpEUkFXX1RFWFRVUkVfRVhURU5TSU9OKSApKSAKKyAgICB7CisgICAgICAgIC8vU3RvcFdhdGNoIHdhdGNoKCJHTCB0cmFuc2Zvcm1lZCIpOworICAgICAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKGNsaXApOworICAgICAgICBpZiAoaXRlcmF0b3IpIHsKKyAgICAgICAgICAgIC8vIGFsd2F5cyB1c2UgaGlnaC1xdWFsaXR5IGZpbHRlcmluZyB3aXRoIGZhc3QgY29uZmlndXJhdGlvbnMKKyAgICAgICAgICAgIGJvb2wgZmFzdCA9ICEobUZsYWdzICYgRGlzcGxheUhhcmR3YXJlOjpTTE9XX0NPTkZJRyk7CisgICAgICAgICAgICBpZiAoIWZhc3QgJiYgcy5mbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckZpbHRlcikgeworICAgICAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX0xJTkVBUik7CisgICAgICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTElORUFSKTsKKyAgICAgICAgICAgIH0gICAgICAgICAgICAKKyAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgdGV4Q29vcmRzWzRdWzJdID0geworICAgICAgICAgICAgICAgICAgICB7IDAsICAgICAgICAwIH0sCisgICAgICAgICAgICAgICAgICAgIHsgMCwgICAgICAgIDB4MTAwMDAgfSwKKyAgICAgICAgICAgICAgICAgICAgeyAweDEwMDAwLCAgMHgxMDAwMCB9LAorICAgICAgICAgICAgICAgICAgICB7IDB4MTAwMDAsICAwIH0KKyAgICAgICAgICAgIH07CisKKyAgICAgICAgICAgIGdsTWF0cml4TW9kZShHTF9URVhUVVJFKTsKKyAgICAgICAgICAgIGdsTG9hZElkZW50aXR5KCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGlmICh0cmFuc2Zvcm0gPT0gSEFMX1RSQU5TRk9STV9ST1RfOTApIHsKKyAgICAgICAgICAgICAgICBnbFRyYW5zbGF0ZWYoMCwgMSwgMCk7CisgICAgICAgICAgICAgICAgZ2xSb3RhdGVmKC05MCwgMCwgMCwgMSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghKG1GbGFncyAmIERpc3BsYXlIYXJkd2FyZTo6TlBPVF9FWFRFTlNJT04pKSB7CisgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgc21hbGxlc3QgcG93ZXItb2YtdHdvIHRoYXQgd2lsbCBhY2NvbW1vZGF0ZSBvdXIgc3VyZmFjZQorICAgICAgICAgICAgICAgIEdMdWludCB0dyA9IDEgPDwgKDMxIC0gY2x6KHQud2lkdGgpKTsKKyAgICAgICAgICAgICAgICBHTHVpbnQgdGggPSAxIDw8ICgzMSAtIGNseih0LmhlaWdodCkpOworICAgICAgICAgICAgICAgIGlmICh0dyA8IHQud2lkdGgpICB0dyA8PD0gMTsKKyAgICAgICAgICAgICAgICBpZiAodGggPCB0LmhlaWdodCkgdGggPDw9IDE7CisgICAgICAgICAgICAgICAgLy8gdGhpcyBkaXZpZGUgc2hvdWxkIGJlIHJlbGF0aXZlbHkgZmFzdCBiZWNhdXNlIGl0J3MKKyAgICAgICAgICAgICAgICAvLyBhIHBvd2VyLW9mLXR3byAob3B0aW1pemVkIHBhdGggaW4gbGliZ2NjKQorICAgICAgICAgICAgICAgIEdMZmxvYXQgd3MgPSBHTGZsb2F0KHQud2lkdGgpIC90dzsKKyAgICAgICAgICAgICAgICBHTGZsb2F0IGhzID0gR0xmbG9hdCh0LmhlaWdodCkvdGg7CisgICAgICAgICAgICAgICAgZ2xTY2FsZWYod3MsIGhzLCAxLjBmKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZ2xFbmFibGVDbGllbnRTdGF0ZShHTF9URVhUVVJFX0NPT1JEX0FSUkFZKTsKKyAgICAgICAgICAgIGdsVmVydGV4UG9pbnRlcigyLCBHTF9GSVhFRCwgMCwgbVZlcnRpY2VzKTsKKyAgICAgICAgICAgIGdsVGV4Q29vcmRQb2ludGVyKDIsIEdMX0ZJWEVELCAwLCB0ZXhDb29yZHMpOworCisgICAgICAgICAgICBSZWN0IHI7CisgICAgICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBHTGludCBzeSA9IGZiSGVpZ2h0IC0gKHIudG9wICsgci5oZWlnaHQoKSk7CisgICAgICAgICAgICAgICAgZ2xTY2lzc29yKHIubGVmdCwgc3ksIHIud2lkdGgoKSwgci5oZWlnaHQoKSk7CisgICAgICAgICAgICAgICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFX0ZBTiwgMCwgNCk7IAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIWZhc3QgJiYgcy5mbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckZpbHRlcikgeworICAgICAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOworICAgICAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZ2xEaXNhYmxlQ2xpZW50U3RhdGUoR0xfVEVYVFVSRV9DT09SRF9BUlJBWSk7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKGNsaXApOworICAgICAgICBpZiAoaXRlcmF0b3IpIHsKKyAgICAgICAgICAgIFJlY3QgcjsKKyAgICAgICAgICAgIEdMaW50IGNyb3BbNF0gPSB7IDAsIHQuaGVpZ2h0LCB0LndpZHRoLCAtdC5oZWlnaHQgfTsKKyAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgICAgIGludCB4ID0gdHgoKTsKKyAgICAgICAgICAgIGludCB5ID0gdHkoKTsKKyAgICAgICAgICAgIHkgPSBmYkhlaWdodCAtICh5ICsgdC5oZWlnaHQpOworICAgICAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLml0ZXJhdGUoJnIpKSB7CisgICAgICAgICAgICAgICAgY29uc3QgR0xpbnQgc3kgPSBmYkhlaWdodCAtIChyLnRvcCArIHIuaGVpZ2h0KCkpOworICAgICAgICAgICAgICAgIGdsU2Npc3NvcihyLmxlZnQsIHN5LCByLndpZHRoKCksIHIuaGVpZ2h0KCkpOworICAgICAgICAgICAgICAgIGdsRHJhd1RleGlPRVMoeCwgeSwgMCwgdC53aWR0aCwgdC5oZWlnaHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCit2b2lkIExheWVyQmFzZTo6dmFsaWRhdGVUZXh0dXJlKEdMaW50IHRleHR1cmVOYW1lKSBjb25zdAoreworICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4dHVyZU5hbWUpOworICAgIC8vIFRPRE86IHJlbG9hZCB0aGUgdGV4dHVyZSBpZiBuZWVkZWQKKyAgICAvLyB0aGlzIGlzIGN1cnJlbnRseSBkb25lIGluIGxvYWRUZXh0dXJlKCkgYmVsb3cKK30KKwordm9pZCBMYXllckJhc2U6OmxvYWRUZXh0dXJlKGNvbnN0IFJlZ2lvbiYgZGlydHksCisgICAgICAgIEdMaW50IHRleHR1cmVOYW1lLCBjb25zdCBHR0xTdXJmYWNlJiB0LAorICAgICAgICBHTHVpbnQmIHRleHR1cmVXaWR0aCwgR0x1aW50JiB0ZXh0dXJlSGVpZ2h0KSBjb25zdAoreworICAgIC8vIFRPRE86IGRlZmVyIHRoZSBhY3R1YWwgdGV4dHVyZSByZWxvYWQgdW50aWwgTGF5ZXJCYXNlOjp2YWxpZGF0ZVRleHR1cmUKKyAgICAvLyBpcyBjYWxsZWQuCisKKyAgICB1aW50MzJfdCBmbGFncyA9IG1GbGFnczsKKyAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVOYW1lKTsKKworICAgIEdMdWludCB0dyA9IHQud2lkdGg7CisgICAgR0x1aW50IHRoID0gdC5oZWlnaHQ7CisKKyAgICAvKgorICAgICAqIEluIE9wZW5HTCBFUyB3ZSBjYW4ndCBzcGVjaWZ5IGEgc3RyaWRlIHdpdGggZ2xUZXhJbWFnZTJEIChob3dldmVyLAorICAgICAqIEdMX1VOUEFDS19BTElHTk1FTlQgaXMgNCwgd2hpY2ggaW4gZXNzZW5jZSBhbGxvd3MgYSBsaW1pdGVkIGZvcm0gb2YKKyAgICAgKiBzdHJpZGUpLgorICAgICAqIFNvIGlmIHRoZSBzdHJpZGUgaGVyZSBpc24ndCByZXByZXNlbnRhYmxlIHdpdGggR0xfVU5QQUNLX0FMSUdOTUVOVCwgd2UKKyAgICAgKiBuZWVkIHRvIGRvIHNvbWV0aGluZyByZWFzb25hYmxlIChoZXJlIGNyZWF0aW5nIGEgYmlnZ2VyIHRleHR1cmUpLgorICAgICAqIAorICAgICAqIGV4dHJhIHBpeGVscyA9ICgoKHN0cmlkZSAtIHdpZHRoKSAqIHBpeGVsc2l6ZSkgLyBHTF9VTlBBQ0tfQUxJR05NRU5UKTsKKyAgICAgKiAKKyAgICAgKiBUaGlzIHNpdHVhdGlvbiBkb2Vzbid0IGhhcHBlbiBvZnRlbiwgYnV0IHNvbWUgaC93IGhhdmUgYSBsaW1pdGF0aW9uCisgICAgICogZm9yIHRoZWlyIGZyYW1lYnVmZmVyIChlZzogbXVzdCBiZSBtdWx0aXBsZSBvZiA4IHBpeGVscyksIGFuZAorICAgICAqIHdlIG5lZWQgdG8gdGFrZSB0aGF0IGludG8gYWNjb3VudCB3aGVuIHVzaW5nIHRoZXNlIGJ1ZmZlcnMgYXMKKyAgICAgKiB0ZXh0dXJlcy4KKyAgICAgKgorICAgICAqIFRoaXMgc2hvdWxkIG5ldmVyIGJlIGEgcHJvYmxlbSB3aXRoIFBPVCB0ZXh0dXJlcworICAgICAqLworCisgICAgdHcgKz0gKCgodC5zdHJpZGUgLSB0dykgKiBieXRlc1BlclBpeGVsKHQuZm9ybWF0KSkgLyA0KTsKKworICAgIC8qCisgICAgICogcm91bmQgdG8gUE9UIGlmIG5lZWRlZCAKKyAgICAgKi8KKyAgICAKKyAgICBHTHVpbnQgdGV4dHVyZV93ID0gdHc7CisgICAgR0x1aW50IHRleHR1cmVfaCA9IHRoOworICAgIGlmICghKGZsYWdzICYgRGlzcGxheUhhcmR3YXJlOjpOUE9UX0VYVEVOU0lPTikpIHsKKyAgICAgICAgLy8gZmluZCB0aGUgc21hbGxlc3QgcG93ZXItb2YtdHdvIHRoYXQgd2lsbCBhY2NvbW1vZGF0ZSBvdXIgc3VyZmFjZQorICAgICAgICB0ZXh0dXJlX3cgPSAxIDw8ICgzMSAtIGNseih0LndpZHRoKSk7CisgICAgICAgIHRleHR1cmVfaCA9IDEgPDwgKDMxIC0gY2x6KHQuaGVpZ2h0KSk7CisgICAgICAgIGlmICh0ZXh0dXJlX3cgPCB0LndpZHRoKSAgdGV4dHVyZV93IDw8PSAxOworICAgICAgICBpZiAodGV4dHVyZV9oIDwgdC5oZWlnaHQpIHRleHR1cmVfaCA8PD0gMTsKKyAgICAgICAgaWYgKHRleHR1cmVfdyAhPSB0dyB8fCB0ZXh0dXJlX2ggIT0gdGgpIHsKKyAgICAgICAgICAgIC8vIHdlIGNhbid0IHVzZSBESVJFQ1RfVEVYVFVSRSBzaW5jZSB3ZSBjaGFuZ2VkIHRoZSBzaXplCisgICAgICAgICAgICAvLyBvZiB0aGUgdGV4dHVyZQorICAgICAgICAgICAgZmxhZ3MgJj0gfkRpc3BsYXlIYXJkd2FyZTo6RElSRUNUX1RFWFRVUkU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoZmxhZ3MgJiBEaXNwbGF5SGFyZHdhcmU6OkRJUkVDVF9URVhUVVJFKSB7CisgICAgICAgIC8vIGhlcmUgd2UncmUgZ3VhcmFudGVlZCB0aGF0IHRleHR1cmVfe3d8aH0gPT0gdHt3fGh9CisgICAgICAgIGlmICh0LmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1JHQl81NjUpIHsKKyAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9ESVJFQ1RfVEVYVFVSRV8yRF9RVUFMQ09NTSwgMCwKKyAgICAgICAgICAgICAgICAgICAgR0xfUkdCLCB0dywgdGgsIDAsCisgICAgICAgICAgICAgICAgICAgIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIHQuZGF0YSk7CisgICAgICAgIH0gZWxzZSBpZiAodC5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzQ0NDQpIHsKKyAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9ESVJFQ1RfVEVYVFVSRV8yRF9RVUFMQ09NTSwgMCwKKyAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwgdHcsIHRoLCAwLAorICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80LCB0LmRhdGEpOworICAgICAgICB9IGVsc2UgaWYgKHQuZm9ybWF0ID09IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4KSB7CisgICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfRElSRUNUX1RFWFRVUkVfMkRfUVVBTENPTU0sIDAsCisgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIHR3LCB0aCwgMCwKKyAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwgR0xfVU5TSUdORURfQllURSwgdC5kYXRhKTsKKyAgICAgICAgfSBlbHNlIGlmICh0LmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX0JHUkFfODg4OCkgeworICAgICAgICAgICAgLy8gVE9ETzogYWRkIEdMX0JHUkEgZXh0ZW5zaW9uCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBvb3BzLCB3ZSBkb24ndCBoYW5kbGUgdGhpcyBmb3JtYXQsIHRyeSB0aGUgcmVndWxhciBwYXRoCisgICAgICAgICAgICBnb3RvIHJlZ3VsYXI7CisgICAgICAgIH0KKyAgICAgICAgdGV4dHVyZVdpZHRoID0gdHc7CisgICAgICAgIHRleHR1cmVIZWlnaHQgPSB0aDsKKyAgICB9IGVsc2UgeworcmVndWxhcjoKKyAgICAgICAgUmVjdCBib3VuZHMoZGlydHkuYm91bmRzKCkpOworICAgICAgICBHTHZvaWQqIGRhdGEgPSAwOworICAgICAgICBpZiAodGV4dHVyZV93IT10ZXh0dXJlV2lkdGggfHwgdGV4dHVyZV9oIT10ZXh0dXJlSGVpZ2h0KSB7CisgICAgICAgICAgICAvLyB0ZXh0dXJlIHNpemUgY2hhbmdlZCwgd2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgb25lCisKKyAgICAgICAgICAgIGlmICghdGV4dHVyZVdpZHRoIHx8ICF0ZXh0dXJlSGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0aGUgZmlyc3QgdGltZSwgbG9hZCB0aGUgd2hvbGUgdGV4dHVyZQorICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlX3c9PXR3ICYmIHRleHR1cmVfaD09dGgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UgY2FuIGRvIGl0IG9uZSBwYXNzCisgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB0LmRhdGE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UgaGF2ZSB0byBjcmVhdGUgdGhlIHRleHR1cmUgZmlyc3QgYmVjYXVzZSBpdAorICAgICAgICAgICAgICAgICAgICAvLyBkb2Vzbid0IG1hdGNoIHRoZSBzaXplIG9mIHRoZSBidWZmZXIKKyAgICAgICAgICAgICAgICAgICAgYm91bmRzLnNldChSZWN0KHR3LCB0aCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKHQuZm9ybWF0ID09IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NSkgeworICAgICAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCLCB0ZXh0dXJlX3csIHRleHR1cmVfaCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIGRhdGEpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0LmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1JHQkFfNDQ0NCkgeworICAgICAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwgdGV4dHVyZV93LCB0ZXh0dXJlX2gsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80LCBkYXRhKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodC5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzg4ODgpIHsKKyAgICAgICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIHRleHR1cmVfdywgdGV4dHVyZV9oLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwgR0xfVU5TSUdORURfQllURSwgZGF0YSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCB0LmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1lDYkNyXzQyMl9TUCB8fAorICAgICAgICAgICAgICAgICAgICAgICAgdC5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9ZQ2JDcl80MjBfU1ApIHsKKyAgICAgICAgICAgICAgICAvLyBqdXN0IHNob3cgdGhlIFkgcGxhbmUgb2YgWVVWIGJ1ZmZlcnMKKyAgICAgICAgICAgICAgICBkYXRhID0gdC5kYXRhOworICAgICAgICAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xfTFVNSU5BTkNFLCB0ZXh0dXJlX3csIHRleHR1cmVfaCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMX0xVTUlOQU5DRSwgR0xfVU5TSUdORURfQllURSwgZGF0YSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIG9vcHMsIHdlIGRvbid0IGhhbmRsZSB0aGlzIGZvcm1hdCEKKyAgICAgICAgICAgICAgICBMT0dFKCJsYXllciAlcCwgdGV4dHVyZT0lZCwgdXNpbmcgZm9ybWF0ICVkLCB3aGljaCBpcyBub3QgIgorICAgICAgICAgICAgICAgICAgICAgInN1cHBvcnRlZCBieSB0aGUgR0wiLCB0aGlzLCB0ZXh0dXJlTmFtZSwgdC5mb3JtYXQpOworICAgICAgICAgICAgICAgIHRleHR1cmVOYW1lID0gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0ZXh0dXJlV2lkdGggPSB0ZXh0dXJlX3c7CisgICAgICAgICAgICB0ZXh0dXJlSGVpZ2h0ID0gdGV4dHVyZV9oOworICAgICAgICB9CisgICAgICAgIGlmICghZGF0YSAmJiB0ZXh0dXJlTmFtZT49MCkgeworICAgICAgICAgICAgaWYgKHQuZm9ybWF0ID09IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NSkgeworICAgICAgICAgICAgICAgIGdsVGV4U3ViSW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgMCwgYm91bmRzLnRvcCwgdC53aWR0aCwgYm91bmRzLmhlaWdodCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCLCBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHQuZGF0YSArIGJvdW5kcy50b3AqdC53aWR0aCoyKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodC5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzQ0NDQpIHsKKyAgICAgICAgICAgICAgICBnbFRleFN1YkltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDAsIGJvdW5kcy50b3AsIHQud2lkdGgsIGJvdW5kcy5oZWlnaHQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQsCisgICAgICAgICAgICAgICAgICAgICAgICB0LmRhdGEgKyBib3VuZHMudG9wKnQud2lkdGgqMik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHQuZm9ybWF0ID09IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4KSB7CisgICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAwLCBib3VuZHMudG9wLCB0LndpZHRoLCBib3VuZHMuaGVpZ2h0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgdC5kYXRhICsgYm91bmRzLnRvcCp0LndpZHRoKjQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCitib29sIExheWVyQmFzZTo6Y2FuVXNlQ29weWJpdCgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1DYW5Vc2VDb3B5Qml0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTGF5ZXJCYXNlQ2xpZW50OjpMYXllckJhc2VDbGllbnQoU3VyZmFjZUZsaW5nZXIqIGZsaW5nZXIsIERpc3BsYXlJRCBkaXNwbGF5LAorICAgICAgICBDbGllbnQqIGMsIGludDMyX3QgaSkKKyAgICA6IExheWVyQmFzZShmbGluZ2VyLCBkaXNwbGF5KSwgY2xpZW50KGMpLAorICAgICAgbGNibGsoIGMgPyAmKGMtPmN0cmxibGstPmxheWVyc1tpXSkgOiAwICksCisgICAgICBtSW5kZXgoaSkKK3sKKyAgICBpZiAoY2xpZW50KSB7CisgICAgICAgIGNsaWVudC0+YmluZExheWVyKHRoaXMsIGkpOworCisgICAgICAgIC8vIEluaXRpYWxpemUgdGhpcyBsYXllcidzIGNvbnRyb2wgYmxvY2sKKyAgICAgICAgbWVtc2V0KHRoaXMtPmxjYmxrLCAwLCBzaXplb2YobGF5ZXJfY2Jsa190KSk7CisgICAgICAgIHRoaXMtPmxjYmxrLT5pZGVudGl0eSA9IG1JZGVudGl0eTsKKyAgICAgICAgUmVnaW9uOjp3cml0ZUVtcHR5KCYodGhpcy0+bGNibGstPnJlZ2lvblswXSksIHNpemVvZihmbGF0X3JlZ2lvbl90KSk7CisgICAgICAgIFJlZ2lvbjo6d3JpdGVFbXB0eSgmKHRoaXMtPmxjYmxrLT5yZWdpb25bMV0pLCBzaXplb2YoZmxhdF9yZWdpb25fdCkpOworICAgIH0KK30KKworTGF5ZXJCYXNlQ2xpZW50Ojp+TGF5ZXJCYXNlQ2xpZW50KCkKK3sKKyAgICBpZiAoY2xpZW50KSB7CisgICAgICAgIGNsaWVudC0+ZnJlZShtSW5kZXgpOworICAgIH0KK30KKworaW50MzJfdCBMYXllckJhc2VDbGllbnQ6OnNlcnZlckluZGV4KCkgY29uc3QgeworICAgIGlmIChjbGllbnQpIHsKKyAgICAgICAgcmV0dXJuIChjbGllbnQtPmNpZDw8MTYpfG1JbmRleDsKKyAgICB9CisgICAgcmV0dXJuIDB4RkZGRjAwMDAgfCBtSW5kZXg7Cit9CisKK3NwPExheWVyQmFzZUNsaWVudDo6U3VyZmFjZT4gTGF5ZXJCYXNlQ2xpZW50OjpnZXRTdXJmYWNlKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbmV3IFN1cmZhY2UoY2xpZW50SW5kZXgoKSwgbUlkZW50aXR5KTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCYXNlLmggYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQmFzZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwMjBmNDQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQmFzZS5oCkBAIC0wLDAgKzEsMzU2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0xBWUVSX0JBU0VfSAorI2RlZmluZSBBTkRST0lEX0xBWUVSX0JBU0VfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3VpL0xheWVyU3RhdGUuaD4KKworI2luY2x1ZGUgPHVpL1JlZ2lvbi5oPgorI2luY2x1ZGUgPHVpL092ZXJsYXkuaD4KKworI2luY2x1ZGUgPHBpeGVsZmxpbmdlci9waXhlbGZsaW5nZXIuaD4KKworI2luY2x1ZGUgIlRyYW5zZm9ybS5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBTdXJmYWNlRmxpbmdlcjsKK2NsYXNzIERpc3BsYXlIYXJkd2FyZTsKK2NsYXNzIEdyYXBoaWNQbGFuZTsKK2NsYXNzIENsaWVudDsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExheWVyQmFzZQoreworICAgIC8vIHBvb3IgbWFuJ3MgZHluYW1pY19jYXN0IGJlbG93CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgICBzdHJ1Y3QgZ2V0VHlwZUluZm9PZkFueVR5cGUgeworICAgICAgICBzdGF0aWMgdWludDMyX3QgZ2V0KCkgeyByZXR1cm4gVDo6dHlwZUluZm87IH0KKyAgICB9OworCisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgICBzdHJ1Y3QgZ2V0VHlwZUluZm9PZkFueVR5cGU8VCo+IHsKKyAgICAgICAgc3RhdGljIHVpbnQzMl90IGdldCgpIHsgcmV0dXJuIGdldFR5cGVJbmZvT2ZBbnlUeXBlPFQ+OjpnZXQoKTsgfQorICAgIH07CisKK3B1YmxpYzoKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgdHlwZUluZm87CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHR5cGVJRDsKKyAgICB2aXJ0dWFsIGNoYXIgY29uc3QqIGdldFR5cGVJRCgpIGNvbnN0IHsgcmV0dXJuIHR5cGVJRDsgfQorICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VHlwZUluZm8oKSBjb25zdCB7IHJldHVybiB0eXBlSW5mbzsgfQorICAgIAorICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgICAgc3RhdGljIFQgZHluYW1pY0Nhc3QoTGF5ZXJCYXNlKiBiYXNlKSB7CisgICAgICAgIHVpbnQzMl90IG1vc3REZXJpdmVkSW5mbyA9IGJhc2UtPmdldFR5cGVJbmZvKCk7CisgICAgICAgIHVpbnQzMl90IGNhc3RUb0luZm8gPSBnZXRUeXBlSW5mb09mQW55VHlwZTxUPjo6Z2V0KCk7CisgICAgICAgIGlmICgobW9zdERlcml2ZWRJbmZvICYgY2FzdFRvSW5mbykgPT0gY2FzdFRvSW5mbykKKyAgICAgICAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUPihiYXNlKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgCisgICAgc3RhdGljIFZlY3RvcjxHTHVpbnQ+IGRlbGV0ZWRUZXh0dXJlczsgCisKKyAgICBMYXllckJhc2UoU3VyZmFjZUZsaW5nZXIqIGZsaW5nZXIsIERpc3BsYXlJRCBkaXNwbGF5KTsKKyAgICB2aXJ0dWFsIH5MYXllckJhc2UoKTsKKyAgICAKKyAgICBEaXNwbGF5SUQgICAgICAgICAgIGRweTsKKyAgICBtdXRhYmxlIGJvb2wgICAgICAgIGNvbnRlbnREaXJ0eTsKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgIHZpc2libGVSZWdpb25TY3JlZW47CisgICAgICAgICAgICBSZWdpb24gICAgICB0cmFuc3BhcmVudFJlZ2lvblNjcmVlbjsKKyAgICAgICAgICAgIFJlZ2lvbiAgICAgIGNvdmVyZWRSZWdpb25TY3JlZW47CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHN0cnVjdCBTdGF0ZSB7CisgICAgICAgICAgICAgICAgdWludDMyX3QgICAgICAgIHc7CisgICAgICAgICAgICAgICAgdWludDMyX3QgICAgICAgIGg7CisgICAgICAgICAgICAgICAgdWludDMyX3QgICAgICAgIHo7CisgICAgICAgICAgICAgICAgdWludDhfdCAgICAgICAgIGFscGhhOworICAgICAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICBmbGFnczsKKyAgICAgICAgICAgICAgICB1aW50OF90ICAgICAgICAgcmVzZXJ2ZWRbMl07CisgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgIHNlcXVlbmNlOyAgIC8vIGNoYW5nZXMgd2hlbiB2aXNpYmxlIHJlZ2lvbnMgY2FuIGNoYW5nZQorICAgICAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICB0aW50OworICAgICAgICAgICAgICAgIFRyYW5zZm9ybSAgICAgICB0cmFuc2Zvcm07CisgICAgICAgICAgICAgICAgUmVnaW9uICAgICAgICAgIHRyYW5zcGFyZW50UmVnaW9uOworICAgICAgICAgICAgfTsKKworICAgICAgICAgICAgLy8gbW9kaWZ5IGN1cnJlbnQgc3RhdGUKKyAgICAgICAgICAgIGJvb2wgc2V0UG9zaXRpb24oaW50MzJfdCB4LCBpbnQzMl90IHkpOworICAgICAgICAgICAgYm9vbCBzZXRMYXllcih1aW50MzJfdCB6KTsKKyAgICAgICAgICAgIGJvb2wgc2V0U2l6ZSh1aW50MzJfdCB3LCB1aW50MzJfdCBoKTsKKyAgICAgICAgICAgIGJvb2wgc2V0QWxwaGEodWludDhfdCBhbHBoYSk7CisgICAgICAgICAgICBib29sIHNldE1hdHJpeChjb25zdCBsYXllcl9zdGF0ZV90OjptYXRyaXgyMl90JiBtYXRyaXgpOworICAgICAgICAgICAgYm9vbCBzZXRUcmFuc3BhcmVudFJlZ2lvbkhpbnQoY29uc3QgUmVnaW9uJiBvcGFxdWUpOworICAgICAgICAgICAgYm9vbCBzZXRGbGFncyh1aW50OF90IGZsYWdzLCB1aW50OF90IG1hc2spOworICAgICAgICAgICAgCisgICAgICAgICAgICB2b2lkIGNvbW1pdFRyYW5zYWN0aW9uKGJvb2wgc2tpcFNpemUpOworICAgICAgICAgICAgYm9vbCByZXF1ZXN0VHJhbnNhY3Rpb24oKTsKKyAgICAgICAgICAgIHZvaWQgZm9yY2VWaXNpYmlsaXR5VHJhbnNhY3Rpb24oKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgdWludDMyX3QgZ2V0VHJhbnNhY3Rpb25GbGFncyh1aW50MzJfdCBmbGFncyk7CisgICAgICAgICAgICB1aW50MzJfdCBzZXRUcmFuc2FjdGlvbkZsYWdzKHVpbnQzMl90IGZsYWdzKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgUmVjdCB2aXNpYmxlQm91bmRzKCkgY29uc3Q7CisgICAgICAgICAgICB2b2lkIGRyYXdSZWdpb24oY29uc3QgUmVnaW9uJiByZWcpIGNvbnN0OworCisgICAgICAgICAgICB2b2lkIGludmFsaWRhdGUoKTsKKyAgICAgICAgICAgIAorICAgIC8qKgorICAgICAqIGRyYXcgLSBwZXJmb3JtcyBzb21lIGdsb2JhbCBjbGlwcGluZyBvcHRpbWl6YXRpb25zCisgICAgICogYW5kIGNhbGxzIG9uRHJhdygpLgorICAgICAqIFR5cGljYWxseSB0aGlzIG1ldGhvZCBpcyBub3Qgb3ZlcnJpZGRlbiwgaW5zdGVhZCBpbXBsZW1lbnQgb25EcmF3KCkKKyAgICAgKiB0byBwZXJmb3JtIHRoZSBhY3R1YWwgZHJhd2luZy4gIAorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCBkcmF3KGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3Q7CisgICAgCisgICAgLyoqCisgICAgICogb25EcmF3IC0gZHJhd3MgdGhlIHN1cmZhY2UuCisgICAgICovCisgICAgdmlydHVhbCB2b2lkIG9uRHJhdyhjb25zdCBSZWdpb24mIGNsaXApIGNvbnN0ID0gMDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBpbml0U3RhdGVzIC0gY2FsbGVkIGp1c3QgYWZ0ZXIgY29uc3RydWN0aW9uCisgICAgICovCisgICAgdmlydHVhbCB2b2lkIGluaXRTdGF0ZXModWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgZmxhZ3MpOworICAgIAorICAgIC8qKgorICAgICAqIHNldFNpemVDaGFuZ2VkIC0gY2FsbGVkIHdoZW4gdGhlICpjdXJyZW50KiBzdGF0ZSdzIHNpemUgaXMgY2hhbmdlZC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHZvaWQgc2V0U2l6ZUNoYW5nZWQodWludDMyX3QgdywgdWludDMyX3QgaCk7CisgICAgCisgICAgLyoqCisgICAgICogZG9UcmFuc2FjdGlvbiAtIHByb2Nlc3MgdGhlIHRyYW5zYWN0aW9uLiBUaGlzIGlzIGEgZ29vZCBwbGFjZSB0byBmaWd1cmUKKyAgICAgKiBvdXQgd2hpY2ggYXR0cmlidXRlcyBvZiB0aGUgc3VyZmFjZSBoYXZlIGNoYW5nZWQuCisgICAgICovCisgICAgdmlydHVhbCB1aW50MzJfdCBkb1RyYW5zYWN0aW9uKHVpbnQzMl90IHRyYW5zYWN0aW9uRmxhZ3MpOworICAgIAorICAgIC8qKgorICAgICAqIHNldFZpc2libGVSZWdpb24gLSBjYWxsZWQgdG8gc2V0IHRoZSBuZXcgdmlzaWJsZSByZWdpb24uIFRoaXMgZ2l2ZXMKKyAgICAgKiBhIGNoYW5jZSB0byB1cGRhdGUgdGhlIG5ldyB2aXNpYmxlIHJlZ2lvbiBvciByZWNvcmQgdGhlIGZhY3QgaXQgY2hhbmdlZC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHZvaWQgc2V0VmlzaWJsZVJlZ2lvbihjb25zdCBSZWdpb24mIHZpc2libGVSZWdpb24pOworICAgIAorICAgIC8qKgorICAgICAqIHNldENvdmVyZWRSZWdpb24gLSBjYWxsZWQgd2hlbiB0aGUgY292ZXJlZCByZWdpb24gY2hhbmdlcy4gVGhlIGNvdmVyZWQKKyAgICAgKiByZWdpb24gY29ycmVzcG9uZCB0byBhbnkgYXJlYSBvZiB0aGUgc3VyZmFjZSB0aGF0IGlzIGNvdmVyZWQgCisgICAgICogKHRyYW5zcGFyZW50bHkgb3Igbm90KSBieSBhbm90aGVyIHN1cmZhY2UuCisgICAgICovCisgICAgdmlydHVhbCB2b2lkIHNldENvdmVyZWRSZWdpb24oY29uc3QgUmVnaW9uJiBjb3ZlcmVkUmVnaW9uKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBnZXRQaHlzaWNhbFNpemUgLSByZXR1cm5zIHRoZSBwaHlzaWNhbCBzaXplIG9mIHRoZSBkcmF3aW5nIHN0YXRlIG9mCisgICAgICogdGhlIHN1cmZhY2UuIElmIHRoZSBzdXJmYWNlIGlzIGJhY2tlZCBieSBhIGJpdG1hcCwgdGhpcyBpcyB0aGUgc2l6ZSBvZgorICAgICAqIHRoZSBiaXRtYXAgKGFzIG9wcG9zZWQgdG8gdGhlIHNpemUgb2YgdGhlIGRyYXdpbmcgc3RhdGUpLgorICAgICAqLworICAgIHZpcnR1YWwgUG9pbnQgZ2V0UGh5c2ljYWxTaXplKCkgY29uc3Q7CisKKyAgICAvKioKKyAgICAgKiB2YWxpZGF0ZVZpc2liaWxpdHkgLSBjYWNoZSBhIGJ1bmNoIG9mIHRoaW5ncworICAgICAqLworICAgIHZpcnR1YWwgdm9pZCB2YWxpZGF0ZVZpc2liaWxpdHkoY29uc3QgVHJhbnNmb3JtJiBnbG9iYWxUcmFuc2Zvcm0pOworCisgICAgLyoqCisgICAgICogbG9ja1BhZ2VGbGlwIC0gY2FsbGVkIGVhY2ggdGltZSB0aGUgc2NyZWVuIGlzIHJlZHJhd24gYW5kIHJldHVybnMgd2hldGhlcgorICAgICAqIHRoZSB2aXNpYmxlIHJlZ2lvbnMgbmVlZCB0byBiZSByZWNvbXB1dGVkICh0aGlzIGlzIGEgZmFpcmx5IGhlYXZ5CisgICAgICogb3BlcmF0aW9uLCBzbyB0aGlzIHNob3VsZCBiZSBzZXQgb25seSBpZiBuZWVkZWQpLiBUeXBpY2FsbHkgdGhpcyBpcyB1c2VkCisgICAgICogdG8gZmlndXJlIG91dCBpZiB0aGUgY29udGVudCBvciBzaXplIG9mIGEgc3VyZmFjZSBoYXMgY2hhbmdlZC4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHZvaWQgbG9ja1BhZ2VGbGlwKGJvb2wmIHJlY29tcHV0ZVZpc2libGVSZWdpb25zKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiB1bmxvY2tQYWdlRmxpcCAtIGNhbGxlZCBlYWNoIHRpbWUgdGhlIHNjcmVlbiBpcyByZWRyYXduLiB1cGRhdGVzIHRoZQorICAgICAqIGZpbmFsIGRpcnR5IHJlZ2lvbiB3cnQgdGhlIHBsYW5lVHJhbnNmb3JtLgorICAgICAqIEF0IHRoaXMgcG9pbnQsIGFsbCB2aXNpYmxlIHJlZ2lvbnMsIHN1cmZhY2UgcG9zaXRpb24gYW5kIHNpemUsIGV0Yy4uLiBhcmUKKyAgICAgKiBjb3JyZWN0LgorICAgICAqLworICAgIHZpcnR1YWwgdm9pZCB1bmxvY2tQYWdlRmxpcChjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtLCBSZWdpb24mIG91dERpcnR5UmVnaW9uKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBmaW5pc2hQYWdlRmxpcCAtIGNhbGxlZCBhZnRlciBhbGwgc3VyZmFjZXMgaGF2ZSBkcmF3bi4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIHZvaWQgZmluaXNoUGFnZUZsaXAoKTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBuZWVkc0JsZW5kaW5nIC0gdHJ1ZSBpZiB0aGlzIHN1cmZhY2UgbmVlZHMgYmxlbmRpbmcKKyAgICAgKi8KKyAgICB2aXJ0dWFsIGJvb2wgbmVlZHNCbGVuZGluZygpIGNvbnN0ICB7IHJldHVybiBmYWxzZTsgfQorCisgICAgLyoqCisgICAgICogdHJhbnNmb3JtZWQgLS0gdHJ1ZSBpcyB0aGlzIHN1cmZhY2UgbmVlZHMgYSB0byBiZSB0cmFuc2Zvcm1lZAorICAgICAqLworICAgIHZpcnR1YWwgYm9vbCB0cmFuc2Zvcm1lZCgpIGNvbnN0ICAgIHsgcmV0dXJuIG1UcmFuc2Zvcm1lZDsgfQorCisgICAgLyoqCisgICAgICogaXNTZWN1cmUgLSB0cnVlIGlmIHRoaXMgc3VyZmFjZSBpcyBzZWN1cmUsIHRoYXQgaXMgaWYgaXQgcHJldmVudHMKKyAgICAgKiBzY3JlZW5zaG90cyBvciB2bnMgc2VydmVycy4KKyAgICAgKi8KKyAgICB2aXJ0dWFsIGJvb2wgaXNTZWN1cmUoKSBjb25zdCAgICAgICB7IHJldHVybiBmYWxzZTsgfQorCisgICAgICAgICAgICBlbnVtIHsgLy8gZmxhZ3MgZm9yIGRvVHJhbnNhY3Rpb24oKQorICAgICAgICAgICAgICAgIGVWaXNpYmxlUmVnaW9uICAgICAgPSAweDAwMDAwMDAyLAorICAgICAgICAgICAgICAgIGVSZXN0YXJ0VHJhbnNhY3Rpb24gPSAweDAwMDAwMDA4CisgICAgICAgICAgICB9OworCisKKyAgICBpbmxpbmUgIGNvbnN0IFN0YXRlJiAgICBkcmF3aW5nU3RhdGUoKSBjb25zdCAgICB7IHJldHVybiBtRHJhd2luZ1N0YXRlOyB9CisgICAgaW5saW5lICBjb25zdCBTdGF0ZSYgICAgY3VycmVudFN0YXRlKCkgY29uc3QgICAgeyByZXR1cm4gbUN1cnJlbnRTdGF0ZTsgfQorICAgIGlubGluZSAgU3RhdGUmICAgICAgICAgIGN1cnJlbnRTdGF0ZSgpICAgICAgICAgIHsgcmV0dXJuIG1DdXJyZW50U3RhdGU7IH0KKworICAgIHN0YXRpYyBpbnQgY29tcGFyZUN1cnJlbnRTdGF0ZVooTGF5ZXJCYXNlKmNvbnN0KiBsYXllckEsIExheWVyQmFzZSpjb25zdCogbGF5ZXJCKSB7CisgICAgICAgIHJldHVybiBsYXllckFbMF0tPmN1cnJlbnRTdGF0ZSgpLnogLSBsYXllckJbMF0tPmN1cnJlbnRTdGF0ZSgpLno7CisgICAgfQorCisgICAgaW50MzJfdCAgZ2V0T3JpZW50YXRpb24oKSBjb25zdCB7IHJldHVybiBtT3JpZW50YXRpb247IH0KKyAgICBpbnQgIHR4KCkgY29uc3QgICAgICAgICAgICAgeyByZXR1cm4gbUxlZnQ7IH0KKyAgICBpbnQgIHR5KCkgY29uc3QgICAgICAgICAgICAgeyByZXR1cm4gbVRvcDsgfQorICAgIAorcHJvdGVjdGVkOgorICAgIGNvbnN0IEdyYXBoaWNQbGFuZSYgZ3JhcGhpY1BsYW5lKGludCBkcHkpIGNvbnN0OworICAgICAgICAgIEdyYXBoaWNQbGFuZSYgZ3JhcGhpY1BsYW5lKGludCBkcHkpOworCisgICAgICAgICAgR0x1aW50IGNyZWF0ZVRleHR1cmUoKSBjb25zdDsKKyAgICAKKyAgICAgICAgICB2b2lkIGRyYXdXaXRoT3BlbkdMKGNvbnN0IFJlZ2lvbiYgY2xpcCwKKyAgICAgICAgICAgICAgICAgIEdMaW50IHRleHR1cmVOYW1lLAorICAgICAgICAgICAgICAgICAgY29uc3QgR0dMU3VyZmFjZSYgc3VyZmFjZSwKKyAgICAgICAgICAgICAgICAgIGludCB0cmFuc2Zvcm0gPSAwKSBjb25zdDsKKworICAgICAgICAgIHZvaWQgY2xlYXJXaXRoT3BlbkdMKGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3Q7CisKKyAgICAgICAgICB2b2lkIGxvYWRUZXh0dXJlKGNvbnN0IFJlZ2lvbiYgZGlydHksCisgICAgICAgICAgICAgICAgICBHTGludCB0ZXh0dXJlTmFtZSwgY29uc3QgR0dMU3VyZmFjZSYgdCwKKyAgICAgICAgICAgICAgICAgIEdMdWludCYgdGV4dHVyZVdpZHRoLCBHTHVpbnQmIHRleHR1cmVIZWlnaHQpIGNvbnN0OworCisgICAgICAgICAgYm9vbCBjYW5Vc2VDb3B5Yml0KCkgY29uc3Q7CisgICAgICAgICAgCisgICAgICAgICAgICAgICAgU3VyZmFjZUZsaW5nZXIqIG1GbGluZ2VyOworICAgICAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICBtRmxhZ3M7CisKKyAgICAgICAgICAgICAgICAvLyBjYWNoZWQgZHVyaW5nIHZhbGlkYXRlVmlzaWJpbGl0eSgpCisgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgICAgIG1UcmFuc2Zvcm1lZDsKKyAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgbU9yaWVudGF0aW9uOworICAgICAgICAgICAgICAgIEdMZml4ZWQgICAgICAgICBtVmVydGljZXNbNF1bMl07CisgICAgICAgICAgICAgICAgUmVjdCAgICAgICAgICAgIG1UcmFuc2Zvcm1lZEJvdW5kczsKKyAgICAgICAgICAgICAgICBib29sICAgICAgICAgICAgbUNhblVzZUNvcHlCaXQ7CisgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgIG1MZWZ0OworICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICBtVG9wOworICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgLy8gdGhlc2UgYXJlIHByb3RlY3RlZCBieSBhbiBleHRlcm5hbCBsb2NrCisgICAgICAgICAgICAgICAgU3RhdGUgICAgICAgICAgIG1DdXJyZW50U3RhdGU7CisgICAgICAgICAgICAgICAgU3RhdGUgICAgICAgICAgIG1EcmF3aW5nU3RhdGU7CisgICAgdm9sYXRpbGUgICAgaW50MzJfdCAgICAgICAgIG1UcmFuc2FjdGlvbkZsYWdzOworCisgICAgICAgICAgICAgICAgLy8gZG9uJ3QgY2hhbmdlLCBkb24ndCBuZWVkIGEgbG9jaworICAgICAgICAgICAgICAgIGJvb2wgICAgICAgICAgICBtUHJlbXVsdGlwbGllZEFscGhhOworCisgICAgICAgICAgICAgICAgLy8gb25seSByZWFkCisgICAgY29uc3QgICAgICAgdWludDMyX3QgICAgICAgIG1JZGVudGl0eTsKKyAgICAgCisgICAgICAgICAgICAgICAgLy8gYXRvbWljCisgICAgdm9sYXRpbGUgICAgaW50MzJfdCAgICAgICAgIG1JbnZhbGlkYXRlOworICAgICAgICAgICAgICAgIAorCitwcml2YXRlOgorICAgICAgICAgICAgICAgIHZvaWQgdmFsaWRhdGVUZXh0dXJlKEdMaW50IHRleHR1cmVOYW1lKSBjb25zdDsKKyAgICBzdGF0aWMgICAgICBpbnQzMl90ICAgICAgICAgc0lkZW50aXR5OworfTsKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTGF5ZXJCYXNlQ2xpZW50IDogcHVibGljIExheWVyQmFzZQoreworcHVibGljOgorICAgIGNsYXNzIFN1cmZhY2U7CisgICBzdGF0aWMgY29uc3QgdWludDMyX3QgdHlwZUluZm87CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHR5cGVJRDsKKyAgICB2aXJ0dWFsIGNoYXIgY29uc3QqIGdldFR5cGVJRCgpIGNvbnN0IHsgcmV0dXJuIHR5cGVJRDsgfQorICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VHlwZUluZm8oKSBjb25zdCB7IHJldHVybiB0eXBlSW5mbzsgfQorCisgICAgTGF5ZXJCYXNlQ2xpZW50KFN1cmZhY2VGbGluZ2VyKiBmbGluZ2VyLCBEaXNwbGF5SUQgZGlzcGxheSwgCisgICAgICAgICAgICBDbGllbnQqIGNsaWVudCwgaW50MzJfdCBpKTsKKyAgICB2aXJ0dWFsIH5MYXllckJhc2VDbGllbnQoKTsKKworCisgICAgQ2xpZW50KiAgICAgICAgICAgICBjb25zdCBjbGllbnQ7CisgICAgbGF5ZXJfY2Jsa190KiAgICAgICBjb25zdCBsY2JsazsKKworICAgIGlubGluZSAgaW50MzJfdCAgICAgY2xpZW50SW5kZXgoKSBjb25zdCB7IHJldHVybiBtSW5kZXg7IH0KKyAgICAgICAgICAgIGludDMyX3QgICAgIHNlcnZlckluZGV4KCkgY29uc3Q7CisKKyAgICB2aXJ0dWFsIHNwPFN1cmZhY2U+IGdldFN1cmZhY2UoKSBjb25zdDsKKyAgIAorICAgICAgICAgICAgdWludDMyX3QgICAgZ2V0SWRlbnRpdHkoKSBjb25zdCB7IHJldHVybiBtSWRlbnRpdHk7IH0KKworICAgIGNsYXNzIFN1cmZhY2UgOiBwdWJsaWMgQm5TdXJmYWNlIAorICAgIHsKKyAgICBwdWJsaWM6CisgICAgICAgIFN1cmZhY2UoU3VyZmFjZUlEIGlkLCBpbnQgaWRlbnRpdHkpIHsgCisgICAgICAgICAgICBtUGFyYW1zLnRva2VuID0gaWQ7CisgICAgICAgICAgICBtUGFyYW1zLmlkZW50aXR5ID0gaWRlbnRpdHk7CisgICAgICAgIH0KKyAgICAgICAgU3VyZmFjZShTdXJmYWNlSUQgaWQsIAorICAgICAgICAgICAgICAgIGNvbnN0IHNwPElNZW1vcnlIZWFwPiYgaGVhcDAsCisgICAgICAgICAgICAgICAgY29uc3Qgc3A8SU1lbW9yeUhlYXA+JiBoZWFwMSwKKyAgICAgICAgICAgICAgICBpbnQgaWRlbnRpdHkpCisgICAgICAgIHsKKyAgICAgICAgICAgIG1QYXJhbXMudG9rZW4gPSBpZDsKKyAgICAgICAgICAgIG1QYXJhbXMuaWRlbnRpdHkgPSBpZGVudGl0eTsKKyAgICAgICAgICAgIG1QYXJhbXMuaGVhcFswXSA9IGhlYXAwOworICAgICAgICAgICAgbVBhcmFtcy5oZWFwWzFdID0gaGVhcDE7CisgICAgICAgIH0KKyAgICAgICAgdmlydHVhbCB+U3VyZmFjZSgpIHsKKyAgICAgICAgICAgIC8vIFRPRE86IFdlIG5vdyBoYXZlIGEgcG9pbnQgaGVyZSB3ZXJlIHdlIGNhbiBjbGVhbi11cCB0aGUKKyAgICAgICAgICAgIC8vIGNsaWVudCdzIG1lc3MuCisgICAgICAgICAgICAvLyBUaGlzIGlzIGFsc28gd2hlcmUgc3VyZmFjZSBpZCBzaG91bGQgYmUgcmVjeWNsZWQuCisgICAgICAgICAgICAvL0xPR0QoIlN1cmZhY2UgJWQsIGhlYXBzPXslcCwgJXB9IGRlc3Ryb3llZCIsCisgICAgICAgICAgICAvLyAgICAgICAgbUlkLCBtSGVhcFswXS5nZXQoKSwgbUhlYXBbMV0uZ2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgdmlydHVhbCB2b2lkIGdldFN1cmZhY2VEYXRhKAorICAgICAgICAgICAgICAgIElTdXJmYWNlRmxpbmdlckNsaWVudDo6c3VyZmFjZV9kYXRhX3QqIHBhcmFtcykgY29uc3QgeworICAgICAgICAgICAgKnBhcmFtcyA9IG1QYXJhbXM7CisgICAgICAgIH0KKworICAgICAgICB2aXJ0dWFsIHN0YXR1c190IHJlZ2lzdGVyQnVmZmVycyhjb25zdCBJU3VyZmFjZTo6QnVmZmVySGVhcCYgYnVmZmVycykgCisgICAgICAgICAgICAgICAgeyByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047IH0KKyAgICAgICAgdmlydHVhbCB2b2lkIHBvc3RCdWZmZXIoc3NpemVfdCBvZmZzZXQpIHsgfQorICAgICAgICB2aXJ0dWFsIHZvaWQgdW5yZWdpc3RlckJ1ZmZlcnMoKSB7IH07CisgICAgICAgIHZpcnR1YWwgc3A8T3ZlcmxheVJlZj4gY3JlYXRlT3ZlcmxheSgKKyAgICAgICAgICAgICAgICB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGZvcm1hdCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH07CisKKyAgICBwcml2YXRlOgorICAgICAgICBJU3VyZmFjZUZsaW5nZXJDbGllbnQ6OnN1cmZhY2VfZGF0YV90IG1QYXJhbXM7CisgICAgfTsKKworcHJpdmF0ZToKKyAgICBpbnQzMl90IG1JbmRleDsKKworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX0xBWUVSX0JBU0VfSApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJpdG1hcC5jcHAgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQml0bWFwLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODQ0MzUwCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJpdG1hcC5jcHAKQEAgLTAsMCArMSwxODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN1cmZhY2VGbGluZ2VyIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvbWVtb3J5Lmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8cGl4ZWxmbGluZ2VyL3BpeGVsZmxpbmdlci5oPgorCisjaW5jbHVkZSAiTGF5ZXJCaXRtYXAuaCIKKyNpbmNsdWRlICJTdXJmYWNlRmxpbmdlci5oIgorI2luY2x1ZGUgIlZSYW1IZWFwLmgiCisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTGF5ZXJCaXRtYXA6OkxheWVyQml0bWFwKCkKKyAgICA6IG1BbGxvY0ZsYWdzKDApLCBtT2Zmc2V0KDApLCBtU2l6ZSgtMVUpLCBtQWxpZ25tZW50KDIpCit7CisgICAgbWVtc2V0KCZtU3VyZmFjZSwgMCwgc2l6ZW9mKG1TdXJmYWNlKSk7Cit9CisKK0xheWVyQml0bWFwOjp+TGF5ZXJCaXRtYXAoKQoreworICAgIG1TdXJmYWNlLmRhdGEgPSAwOworfQorCitzdGF0dXNfdCBMYXllckJpdG1hcDo6aW5pdChjb25zdCBzcDxNZW1vcnlEZWFsZXI+JiBhbGxvY2F0b3IpCit7CisgICAgaWYgKG1BbGxvY2F0b3IgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICBtQWxsb2NhdG9yID0gYWxsb2NhdG9yOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgTGF5ZXJCaXRtYXA6OnNldEJpdHModWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgYWxpZ25tZW50LCAKKyAgICAgICAgUGl4ZWxGb3JtYXQgZm9ybWF0LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBjb25zdCBzcDxNZW1vcnlEZWFsZXI+JiBhbGxvY2F0b3IobUFsbG9jYXRvcik7CisgICAgaWYgKGFsbG9jYXRvciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTk9fSU5JVDsKKworICAgIGlmIChVTkxJS0VMWSh3ID09IG1TdXJmYWNlLndpZHRoICYmIGggPT0gbVN1cmZhY2UuaGVpZ2h0ICYmCisgICAgICAgICAgICBmb3JtYXQgPT0gbVN1cmZhY2UuZm9ybWF0KSkKKyAgICB7IC8vIHNhbWUgZm9ybWF0IGFuZCBzaXplLCBkbyBub3RoaW5nLgorICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgUGl4ZWxGb3JtYXRJbmZvIGluZm87CisgICAgZ2V0UGl4ZWxGb3JtYXRJbmZvKGZvcm1hdCwgJmluZm8pOworCisgICAgdWludDMyX3QgYWxsb2NGbGFncyA9IE1lbW9yeURlYWxlcjo6UEFHRV9BTElHTkVEOworICAgIGNvbnN0IHVpbnQzMl90IGFsaWduID0gNDsgLy8gbXVzdCBtYXRjaCBHTF9VTlBBQ0tfQUxJR05NRU5UCisgICAgY29uc3QgdWludDMyX3QgQnBwID0gaW5mby5ieXRlc1BlclBpeGVsOworICAgIHVpbnQzMl90IHN0cmlkZSA9ICh3ICsgKGFsaWdubWVudC0xKSkgJiB+KGFsaWdubWVudC0xKTsKKyAgICBzdHJpZGUgPSAoKHN0cmlkZSAqIEJwcCArIChhbGlnbi0xKSkgJiB+KGFsaWduLTEpKSAvIEJwcDsKKyAgICBzaXplX3Qgc2l6ZSA9IGluZm8uZ2V0U2NhbmxpbmVTaXplKHN0cmlkZSkgKiBoOworICAgIGlmIChhbGxvY0ZsYWdzICYgTWVtb3J5RGVhbGVyOjpQQUdFX0FMSUdORUQpIHsKKyAgICAgICAgc2l6ZV90IHBhZ2VzaXplID0gZ2V0cGFnZXNpemUoKTsKKyAgICAgICAgc2l6ZSA9IChzaXplICsgKHBhZ2VzaXplLTEpKSAmIH4ocGFnZXNpemUtMSk7CisgICAgfQorCisgICAgLyogRklYTUU6IHdlIHNob3VsZCBiZSBhYmxlIHRvIGhhdmUgYSBoL3Ygc3RyaWRlIGJlY2F1c2UgdGhlIHVzZXIgb2YgdGhlCisgICAgICogc3VyZmFjZSBtaWdodCBoYXZlIHN0cmlkZSBsaW1pdGF0aW9uIChmb3IgaW5zdGFuY2UgaC93IGNvZGVjcyBvZnRlbiBkbykKKyAgICAgKi8KKyAgICBpbnQzMl90IHZzdHJpZGUgPSAwOworCisgICAgbUFsaWdubWVudCA9IGFsaWdubWVudDsKKyAgICBtQWxsb2NGbGFncyA9IGFsbG9jRmxhZ3M7CisgICAgbU9mZnNldCA9IDA7CisgICAgaWYgKG1TaXplICE9IHNpemUpIHsKKyAgICAgICAgLy8gd291bGQgYmUgbmljZSB0byBoYXZlIGEgcmVhbGxvY2F0ZSgpIGFwaQorICAgICAgICBtQml0c01lbW9yeS5jbGVhcigpOyAvLyBmcmVlLW1lbW9yeQorICAgICAgICBtQml0c01lbW9yeSA9IGFsbG9jYXRvci0+YWxsb2NhdGUoc2l6ZSwgYWxsb2NGbGFncyk7CisgICAgICAgIG1TaXplID0gc2l6ZTsKKyAgICB9IGVsc2UgeworICAgICAgICAvLyBkb24ndCBlcmFzZSBtZW1vcnkgaWYgd2UgZGlkbid0IGhhdmUgdG8gcmVhbGxvY2F0ZQorICAgICAgICBmbGFncyAmPSB+U0VDVVJFX0JJVFM7CisgICAgfQorICAgIGlmIChtQml0c01lbW9yeSAhPSAwKSB7CisgICAgICAgIG1PZmZzZXQgPSBtQml0c01lbW9yeS0+b2Zmc2V0KCk7CisgICAgICAgIG1TdXJmYWNlLmRhdGEgPSBzdGF0aWNfY2FzdDxHR0x1Ynl0ZSo+KG1CaXRzTWVtb3J5LT5wb2ludGVyKCkpOworICAgICAgICBtU3VyZmFjZS52ZXJzaW9uID0gc2l6ZW9mKEdHTFN1cmZhY2UpOworICAgICAgICBtU3VyZmFjZS53aWR0aCAgPSB3OworICAgICAgICBtU3VyZmFjZS5oZWlnaHQgPSBoOworICAgICAgICBtU3VyZmFjZS5zdHJpZGUgPSBzdHJpZGU7CisgICAgICAgIG1TdXJmYWNlLnZzdHJpZGUgPSB2c3RyaWRlOworICAgICAgICBtU3VyZmFjZS5mb3JtYXQgPSBmb3JtYXQ7CisgICAgICAgIGlmIChmbGFncyAmIFNFQ1VSRV9CSVRTKQorICAgICAgICAgICAgY2xlYXIoKTsKKyAgICB9CisKKyAgICBpZiAobUJpdHNNZW1vcnk9PTAgfHwgbVN1cmZhY2UuZGF0YT09MCkgeworICAgICAgICBMT0dFKCJub3QgZW5vdWdoIG1lbW9yeSBmb3IgbGF5ZXIgYml0bWFwIHNpemU9JXUiLCBzaXplKTsKKyAgICAgICAgYWxsb2NhdG9yLT5kdW1wKCJMYXllckJpdG1hcCIpOworICAgICAgICBtU3VyZmFjZS5kYXRhID0gMDsKKyAgICAgICAgbVNpemUgPSAtMVU7CisgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBMYXllckJpdG1hcDo6Y2xlYXIoKQoreworICAgIC8vIE5PVEU6IHRoaXMgbWVtc2V0IHNob3VsZCBub3QgYmUgbmVjZXNzYXJ5LCBhdCBsZWFzdCBmb3IKKyAgICAvLyBvcGFxdWUgc3VyZmFjZS4gSG93ZXZlciwgZm9yIHNlY3VyaXR5IHJlYXNvbnMgaXQncyBiZXR0ZXIgdG8ga2VlcCBpdAorICAgIC8vIChpbiB0aGUgY2FzZSBvZiBwbWVtLCBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIG1lbW9yeSBjb250YWlucyBvbGQKKyAgICAvLyBkYXRhKQorICAgIGlmIChtU3VyZmFjZS5kYXRhKSB7CisgICAgICAgIG1lbXNldChtU3VyZmFjZS5kYXRhLCAwLCBtU2l6ZSk7CisgICAgICAgIC8vaWYgKGJ5dGVzUGVyUGl4ZWwobVN1cmZhY2UuZm9ybWF0KSA9PSA0KSB7CisgICAgICAgIC8vICAgIGFuZHJvaWRfbWVtc2V0MzIoKHVpbnQzMl90KiltU3VyZmFjZS5kYXRhLCAweEZGMDAwMEZGLCBtU2l6ZSk7CisgICAgICAgIC8vfSBlbHNlICB7CisgICAgICAgIC8vICAgIGFuZHJvaWRfbWVtc2V0MTYoKHVpbnQxNl90KiltU3VyZmFjZS5kYXRhLCAweEY4MDAsIG1TaXplKTsKKyAgICAgICAgLy99CisgICAgfQorfQorCitzdGF0dXNfdCBMYXllckJpdG1hcDo6Z2V0SW5mbyhzdXJmYWNlX2luZm9fdCogaW5mbykgY29uc3QKK3sKKyAgICBpZiAobVN1cmZhY2UuZGF0YSA9PSAwKSB7CisgICAgICAgIG1lbXNldChpbmZvLCAwLCBzaXplb2Yoc3VyZmFjZV9pbmZvX3QpKTsKKyAgICAgICAgaW5mby0+Yml0c19vZmZzZXQgPSBOT19NRU1PUlk7CisgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgfQorICAgIGluZm8tPncgICAgID0gdWludDE2X3Qod2lkdGgoKSk7CisgICAgaW5mby0+aCAgICAgPSB1aW50MTZfdChoZWlnaHQoKSk7CisgICAgaW5mby0+c3RyaWRlPSB1aW50MTZfdChzdHJpZGUoKSk7CisgICAgaW5mby0+YnByICAgPSB1aW50MTZfdChzdHJpZGUoKSAqIGJ5dGVzUGVyUGl4ZWwocGl4ZWxGb3JtYXQoKSkpOworICAgIGluZm8tPmZvcm1hdD0gdWludDhfdChwaXhlbEZvcm1hdCgpKTsKKyAgICBpbmZvLT5mbGFncyA9IHN1cmZhY2VfaW5mb190OjplQnVmZmVyRGlydHk7CisgICAgaW5mby0+Yml0c19vZmZzZXQgPSBzc2l6ZV90KG1PZmZzZXQpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgTGF5ZXJCaXRtYXA6OnJlc2l6ZSh1aW50MzJfdCB3LCB1aW50MzJfdCBoKQoreworICAgIGludCBlcnIgPSBzZXRCaXRzKHcsIGgsIG1BbGlnbm1lbnQsIHBpeGVsRm9ybWF0KCksIFNFQ1VSRV9CSVRTKTsKKyAgICByZXR1cm4gZXJyOworfQorCitzaXplX3QgTGF5ZXJCaXRtYXA6OnNpemUoKSBjb25zdAoreworICAgIHJldHVybiBtU2l6ZTsKK30KKwordm9pZCBMYXllckJpdG1hcDo6Z2V0Qml0bWFwU3VyZmFjZShjb3B5Yml0X2ltYWdlX3QqIGltZykgY29uc3QKK3sKKyAgICBjb25zdCBzcDxJTWVtb3J5SGVhcD4mIG1oKGdldEFsbG9jYXRvcigpLT5nZXRNZW1vcnlIZWFwKCkpOworICAgIHZvaWQqIHNiYXNlID0gbWgtPmJhc2UoKTsKKyAgICBjb25zdCBHR0xTdXJmYWNlJiB0KHN1cmZhY2UoKSk7CisgICAgaW1nLT53ID0gdC5zdHJpZGUgID86IHQud2lkdGg7CisgICAgaW1nLT5oID0gdC52c3RyaWRlID86IHQuaGVpZ2h0OworICAgIGltZy0+Zm9ybWF0ID0gdC5mb3JtYXQ7CisgICAgaW1nLT5vZmZzZXQgPSBpbnRwdHJfdCh0LmRhdGEpIC0gaW50cHRyX3Qoc2Jhc2UpOworICAgIGltZy0+YmFzZSA9IHNiYXNlOworICAgIGltZy0+ZmQgPSBtaC0+aGVhcElEKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJpdG1hcC5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJpdG1hcC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhZDY0YzQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQml0bWFwLmgKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9MQVlFUl9CSVRNQVBfSAorI2RlZmluZSBBTkRST0lEX0xBWUVSX0JJVE1BUF9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0F0b21pYy5oPgorI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8dWkvUmVjdC5oPgorI2luY2x1ZGUgPHByaXZhdGUvdWkvU2hhcmVkU3RhdGUuaD4KKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisKK2NsYXNzIGNvcHliaXRfaW1hZ2VfdDsKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgSU1lbW9yeTsKK2NsYXNzIE1lbW9yeURlYWxlcjsKK2NsYXNzIExheWVyQml0bWFwOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTGF5ZXJCaXRtYXAKK3sKK3B1YmxpYzoKKworICAgIGVudW0geworICAgICAgICAvLyBlcmFzZSBtZW1vcnkgdG8gZW5zdXJlIHNlY3VyaXR5IHdoZW4gbmVjZXNzYXJ5CisgICAgICAgIFNFQ1VSRV9CSVRTID0gMHgwMDAwMDAwMQorICAgIH07CisKKyAgICAgICAgICAgICAgICBMYXllckJpdG1hcCgpOworICAgICAgICAgICAgICAgIH5MYXllckJpdG1hcCgpOworICAgIHN0YXR1c190ICAgIGluaXQoY29uc3Qgc3A8TWVtb3J5RGVhbGVyPiYgYWxsb2NhdG9yKTsKKworICAgIHN0YXR1c190ICAgIHNldEJpdHModWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgYWxpZ25tZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXQgZm9ybWF0LCB1aW50MzJfdCBmbGFncyA9IDApOworICAgIHZvaWQgICAgICAgIGNsZWFyKCk7CisKKyAgICBzdGF0dXNfdCAgICBnZXRJbmZvKHN1cmZhY2VfaW5mb190KiBpbmZvKSBjb25zdDsKKyAgICBzdGF0dXNfdCAgICByZXNpemUodWludDMyX3QgdywgdWludDMyX3QgaCk7CisKKyAgICBjb25zdCBHR0xTdXJmYWNlJiBzdXJmYWNlKCkgY29uc3QgICB7IHJldHVybiBtU3VyZmFjZTsgfQorICAgIFJlY3QgYm91bmRzKCkgY29uc3QgICAgICAgICAgICAgICAgIHsgcmV0dXJuIFJlY3Qod2lkdGgoKSwgaGVpZ2h0KCkpOyB9CisgICAgdWludDMyX3Qgd2lkdGgoKSBjb25zdCAgICAgICAgICAgICAgeyByZXR1cm4gc3VyZmFjZSgpLndpZHRoOyB9CisgICAgdWludDMyX3QgaGVpZ2h0KCkgY29uc3QgICAgICAgICAgICAgeyByZXR1cm4gc3VyZmFjZSgpLmhlaWdodDsgfQorICAgIHVpbnQzMl90IHN0cmlkZSgpIGNvbnN0ICAgICAgICAgICAgIHsgcmV0dXJuIHN1cmZhY2UoKS5zdHJpZGU7IH0KKyAgICBQaXhlbEZvcm1hdCBwaXhlbEZvcm1hdCgpIGNvbnN0ICAgICB7IHJldHVybiBzdXJmYWNlKCkuZm9ybWF0OyB9CisgICAgdm9pZCogc2VydmVyQml0cygpIGNvbnN0ICAgICAgICAgICAgeyByZXR1cm4gc3VyZmFjZSgpLmRhdGE7IH0KKyAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0OworICAgIGNvbnN0IHNwPE1lbW9yeURlYWxlcj4mIGdldEFsbG9jYXRvcigpIGNvbnN0IHsgcmV0dXJuIG1BbGxvY2F0b3I7IH0KKyAgICB2b2lkIGdldEJpdG1hcFN1cmZhY2UoY29weWJpdF9pbWFnZV90KiBpbWcpIGNvbnN0OworCitwcml2YXRlOgorICAgIHNwPE1lbW9yeURlYWxlcj4gICAgICAgIG1BbGxvY2F0b3I7CisgICAgc3A8SU1lbW9yeT4gICAgICAgICAgICAgbUJpdHNNZW1vcnk7CisgICAgdWludDMyX3QgICAgICAgICAgICAgICAgbUFsbG9jRmxhZ3M7CisgICAgc3NpemVfdCAgICAgICAgICAgICAgICAgbU9mZnNldDsKKyAgICBHR0xTdXJmYWNlICAgICAgICAgICAgICBtU3VyZmFjZTsKKyAgICBzaXplX3QgICAgICAgICAgICAgICAgICBtU2l6ZTsKKyAgICB1aW50MzJfdCAgICAgICAgICAgICAgICBtQWxpZ25tZW50OworfTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfTEFZRVJfQklUTUFQX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCbHVyLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCbHVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2U0NTZmCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJsdXIuY3BwCkBAIC0wLDAgKzEsMjM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8R0xFUy9nbGV4dC5oPgorCisjaW5jbHVkZSAiQmx1ckZpbHRlci5oIgorI2luY2x1ZGUgIkxheWVyQmx1ci5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZS5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgdWludDMyX3QgTGF5ZXJCbHVyOjp0eXBlSW5mbyA9IExheWVyQmFzZUNsaWVudDo6dHlwZUluZm8gfCA4OworY29uc3QgY2hhciogY29uc3QgTGF5ZXJCbHVyOjp0eXBlSUQgPSAiTGF5ZXJCbHVyIjsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xheWVyQmx1cjo6TGF5ZXJCbHVyKFN1cmZhY2VGbGluZ2VyKiBmbGluZ2VyLCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgQ2xpZW50KiBjbGllbnQsIGludDMyX3QgaSkKKyAgICAgOiBMYXllckJhc2VDbGllbnQoZmxpbmdlciwgZGlzcGxheSwgY2xpZW50LCBpKSwgbUNhY2hlRGlydHkodHJ1ZSksCisgICAgIG1SZWZyZXNoQ2FjaGUodHJ1ZSksIG1DYWNoZUFnZSgwKSwgbVRleHR1cmVOYW1lKC0xVSkKK3sKK30KKworTGF5ZXJCbHVyOjp+TGF5ZXJCbHVyKCkKK3sKKyAgICBpZiAobVRleHR1cmVOYW1lICE9IC0xVSkgeworICAgICAgICAvL2dsRGVsZXRlVGV4dHVyZXMoMSwgJm1UZXh0dXJlTmFtZSk7CisgICAgICAgIGRlbGV0ZWRUZXh0dXJlcy5hZGQobVRleHR1cmVOYW1lKTsKKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXJCbHVyOjpzZXRWaXNpYmxlUmVnaW9uKGNvbnN0IFJlZ2lvbiYgdmlzaWJsZVJlZ2lvbikKK3sKKyAgICBMYXllckJhc2VDbGllbnQ6OnNldFZpc2libGVSZWdpb24odmlzaWJsZVJlZ2lvbik7CisgICAgaWYgKHZpc2libGVSZWdpb25TY3JlZW4uaXNFbXB0eSgpKSB7CisgICAgICAgIGlmIChtVGV4dHVyZU5hbWUgIT0gLTFVKSB7CisgICAgICAgICAgICAvLyBXZSdyZSBub3QgdmlzaWJsZSwgZnJlZSB0aGUgdGV4dHVyZSB1cC4KKyAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CisgICAgICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZtVGV4dHVyZU5hbWUpOworICAgICAgICAgICAgbVRleHR1cmVOYW1lID0gLTFVOworICAgICAgICB9CisgICAgfQorfQorCit1aW50MzJfdCBMYXllckJsdXI6OmRvVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpCit7CisgICAgLy8gd2UncmUgZG9pbmcgYSB0cmFuc2FjdGlvbiwgcmVmcmVzaCB0aGUgY2FjaGUhCisgICAgaWYgKCFtRmxpbmdlci0+aXNGcm96ZW4oKSkgeworICAgICAgICBtUmVmcmVzaENhY2hlID0gdHJ1ZTsKKyAgICAgICAgbUNhY2hlRGlydHkgPSB0cnVlOworICAgICAgICBmbGFncyB8PSBlVmlzaWJsZVJlZ2lvbjsKKyAgICAgICAgdGhpcy0+Y29udGVudERpcnR5ID0gdHJ1ZTsKKyAgICB9CisgICAgcmV0dXJuIExheWVyQmFzZTo6ZG9UcmFuc2FjdGlvbihmbGFncyk7ICAgIAorfQorCit2b2lkIExheWVyQmx1cjo6dW5sb2NrUGFnZUZsaXAoY29uc3QgVHJhbnNmb3JtJiBwbGFuZVRyYW5zZm9ybSwgUmVnaW9uJiBvdXREaXJ0eVJlZ2lvbikKK3sKKyAgICAvLyB0aGlzIGNvZGUtcGF0aCBtdXN0IGJlIGFzIHRpZ2h0IGFzIHBvc3NpYmxlLCBpdCdzIGNhbGxlZCBlYWNoIHRpbWUKKyAgICAvLyB0aGUgc2NyZWVuIGlzIGNvbXBvc2l0ZWQuCisgICAgaWYgKFVOTElLRUxZKCF2aXNpYmxlUmVnaW9uU2NyZWVuLmlzRW1wdHkoKSkpIHsKKyAgICAgICAgLy8gaWYgYW55dGhpbmcgdmlzaWJsZSBiZWxvdyB1cyBpcyBpbnZhbGlkYXRlZCwgdGhlIGNhY2hlIGJlY29tZXMgZGlydHkKKyAgICAgICAgaWYgKCFtQ2FjaGVEaXJ0eSAmJiAKKyAgICAgICAgICAgICAgICAhdmlzaWJsZVJlZ2lvblNjcmVlbi5pbnRlcnNlY3Qob3V0RGlydHlSZWdpb24pLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgbUNhY2hlRGlydHkgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChtQ2FjaGVEaXJ0eSkgeworICAgICAgICAgICAgaWYgKCFtRmxpbmdlci0+aXNGcm96ZW4oKSkgeworICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBldmVyeXRoaW5nIGJlbG93IHVzIHRoYXQgaXMgdmlzaWJsZQorICAgICAgICAgICAgICAgIG91dERpcnR5UmVnaW9uLm9yU2VsZih2aXNpYmxlUmVnaW9uU2NyZWVuKTsKKyAgICAgICAgICAgICAgICBuc2Vjc190IG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgICAgICAgICBpZiAoKG5vdyAtIG1DYWNoZUFnZSkgPj0gbXMybnMoNTAwKSkgeworICAgICAgICAgICAgICAgICAgICBtQ2FjaGVBZ2UgPSBub3c7CisgICAgICAgICAgICAgICAgICAgIG1SZWZyZXNoQ2FjaGUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBtQ2FjaGVEaXJ0eSA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghbUF1dG9SZWZyZXNoUGVuZGluZykgeworICAgICAgICAgICAgICAgICAgICAgICAgbUZsaW5nZXItPnNpZ25hbERlbGF5ZWRFdmVudChtczJucyg1MDApKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1BdXRvUmVmcmVzaFBlbmRpbmcgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIExheWVyQmFzZTo6dW5sb2NrUGFnZUZsaXAocGxhbmVUcmFuc2Zvcm0sIG91dERpcnR5UmVnaW9uKTsKK30KKwordm9pZCBMYXllckJsdXI6Om9uRHJhdyhjb25zdCBSZWdpb24mIGNsaXApIGNvbnN0Cit7CisgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIGNvbnN0IHVpbnQzMl90IGZiSGVpZ2h0ID0gaHcuZ2V0SGVpZ2h0KCk7CisgICAgaW50IHggPSBtVHJhbnNmb3JtZWRCb3VuZHMubGVmdDsKKyAgICBpbnQgeSA9IG1UcmFuc2Zvcm1lZEJvdW5kcy50b3A7CisgICAgaW50IHcgPSBtVHJhbnNmb3JtZWRCb3VuZHMud2lkdGgoKTsKKyAgICBpbnQgaCA9IG1UcmFuc2Zvcm1lZEJvdW5kcy5oZWlnaHQoKTsKKyAgICBHTGludCBYID0geDsKKyAgICBHTGludCBZID0gZmJIZWlnaHQgLSAoeSArIGgpOworICAgIGlmIChYIDwgMCkgeworICAgICAgICB3ICs9IFg7CisgICAgICAgIFggPSAwOworICAgIH0KKyAgICBpZiAoWSA8IDApIHsKKyAgICAgICAgaCArPSBZOworICAgICAgICBZID0gMDsKKyAgICB9CisgICAgaWYgKHc8MCB8fCBoPDApIHsKKyAgICAgICAgLy8gd2UncmUgb3V0c2lkZSBvZiB0aGUgZnJhbWVidWZmZXIKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChtVGV4dHVyZU5hbWUgPT0gLTFVKSB7CisgICAgICAgIC8vIGNyZWF0ZSB0aGUgdGV4dHVyZSBuYW1lIHRoZSBmaXJzdCB0aW1lCisgICAgICAgIC8vIGNhbid0IGRvIHRoYXQgaW4gdGhlIGN0b3IsIGJlY2F1c2UgaXQgcnVucyBpbiBhbm90aGVyIHRocmVhZC4KKyAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmbVRleHR1cmVOYW1lKTsKKyAgICB9CisKKyAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKGNsaXApOworICAgIGlmIChpdGVyYXRvcikgeworICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKKyAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtVGV4dHVyZU5hbWUpOworICAgIAorICAgICAgICBpZiAobVJlZnJlc2hDYWNoZSkgeworICAgICAgICAgICAgbVJlZnJlc2hDYWNoZSA9IGZhbHNlOworICAgICAgICAgICAgbUF1dG9SZWZyZXNoUGVuZGluZyA9IGZhbHNlOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBhbGxvY2F0ZSBlbm91Z2ggbWVtb3J5IGZvciA0LWJ5dGVzICgyIHBpeGVscykgYWxpZ25lZCBkYXRhCisgICAgICAgICAgICBjb25zdCBpbnQzMl90IHMgPSAodyArIDEpICYgfjE7CisgICAgICAgICAgICB1aW50MTZfdCogY29uc3QgcGl4ZWxzID0gKHVpbnQxNl90KiltYWxsb2MocypoKjIpOworCisgICAgICAgICAgICAvLyBUaGlzIHJlYWRzIHRoZSBmcmFtZS1idWZmZXIsIHNvIGEgaC93IEdMIHdvdWxkIGhhdmUgdG8KKyAgICAgICAgICAgIC8vIGZpbmlzaCgpIGl0cyByZW5kZXJpbmcgZmlyc3QuIHdlIGRvbid0IHdhbnQgdG8gZG8gdGhhdAorICAgICAgICAgICAgLy8gdG9vIG9mdGVuLiBSZWFkIGRhdGEgaXMgNC1ieXRlcyBhbGlnbmVkLgorICAgICAgICAgICAgZ2xSZWFkUGl4ZWxzKFgsIFksIHcsIGgsIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIHBpeGVscyk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIGJsdXIgdGhhdCB0ZXh0dXJlLgorICAgICAgICAgICAgR0dMU3VyZmFjZSBibDsKKyAgICAgICAgICAgIGJsLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgICAgICBibC53aWR0aCA9IHc7CisgICAgICAgICAgICBibC5oZWlnaHQgPSBoOworICAgICAgICAgICAgYmwuc3RyaWRlID0gczsKKyAgICAgICAgICAgIGJsLmZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NTsKKyAgICAgICAgICAgIGJsLmRhdGEgPSAoR0dMdWJ5dGUqKXBpeGVsczsgICAgICAgICAgICAKKyAgICAgICAgICAgIGJsdXJGaWx0ZXIoJmJsLCA4LCAyKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gTk9URTogdGhpcyB3b3JrcyBvbmx5IGJlY2F1c2Ugd2UgaGF2ZSBQT1QuIHdlJ2QgaGF2ZSB0byByb3VuZCB0aGUKKyAgICAgICAgICAgIC8vIHRleHR1cmUgc2l6ZSB1cCwgb3RoZXJ3aXNlLgorICAgICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQiwgdywgaCwgMCwKKyAgICAgICAgICAgICAgICAgICAgR0xfUkdCLCBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSwgcGl4ZWxzKTsKKworICAgICAgICAgICAgZnJlZSgodm9pZCopcGl4ZWxzKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgY29uc3QgU3RhdGUmIHMgPSBkcmF3aW5nU3RhdGUoKTsKKyAgICAgICAgaWYgKFVOTElLRUxZKHMuYWxwaGEgPCAweEZGKSkgeworICAgICAgICAgICAgY29uc3QgR0dMZml4ZWQgYWxwaGEgPSAocy5hbHBoYSA8PCAxNikvMjU1OworICAgICAgICAgICAgZ2xDb2xvcjR4KDAsIDAsIDAsIGFscGhhKTsKKyAgICAgICAgICAgIGdsRW5hYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgICAgIGdsQmxlbmRGdW5jKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CisgICAgICAgICAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgfQorCisgICAgICAgIGdsRGlzYWJsZShHTF9ESVRIRVIpOworICAgICAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOworICAgICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKKyAgICAgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CisKKyAgICAgICAgaWYgKFVOTElLRUxZKHRyYW5zZm9ybWVkKCkKKyAgICAgICAgICAgICAgICB8fCAhKG1GbGFncyAmIERpc3BsYXlIYXJkd2FyZTo6RFJBV19URVhUVVJFX0VYVEVOU0lPTikgKSkgeworICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHZlcnkgcmFyZSBzY2VuYXJpby4KKyAgICAgICAgICAgIGdsTWF0cml4TW9kZShHTF9URVhUVVJFKTsKKyAgICAgICAgICAgIGdsTG9hZElkZW50aXR5KCk7CisgICAgICAgICAgICBnbFNjYWxlZigxLjBmL3csIC0xLjBmL2gsIDEpOworICAgICAgICAgICAgZ2xUcmFuc2xhdGVmKC14LCAteSwgMCk7CisgICAgICAgICAgICBnbEVuYWJsZUNsaWVudFN0YXRlKEdMX1RFWFRVUkVfQ09PUkRfQVJSQVkpOworICAgICAgICAgICAgZ2xWZXJ0ZXhQb2ludGVyKDIsIEdMX0ZJWEVELCAwLCBtVmVydGljZXMpOworICAgICAgICAgICAgZ2xUZXhDb29yZFBvaW50ZXIoMiwgR0xfRklYRUQsIDAsIG1WZXJ0aWNlcyk7CisgICAgICAgICAgICBSZWN0IHI7CisgICAgICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBHTGludCBzeSA9IGZiSGVpZ2h0IC0gKHIudG9wICsgci5oZWlnaHQoKSk7CisgICAgICAgICAgICAgICAgZ2xTY2lzc29yKHIubGVmdCwgc3ksIHIud2lkdGgoKSwgci5oZWlnaHQoKSk7CisgICAgICAgICAgICAgICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFX0ZBTiwgMCwgNCk7IAorICAgICAgICAgICAgfSAgICAgICAKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFJlZ2lvbjo6aXRlcmF0b3IgaXRlcmF0b3IoY2xpcCk7CisgICAgICAgICAgICBpZiAoaXRlcmF0b3IpIHsKKyAgICAgICAgICAgICAgICAvLyBOT1RFOiB0aGlzIGlzIG1hcmdpbmFsbHkgZmFzdGVyIHdpdGggdGhlIHNvZnR3YXJlIGdsLCBiZWNhdXNlCisgICAgICAgICAgICAgICAgLy8gZ2xSZWFkUGl4ZWxzKCkgcmVhZHMgdGhlIGZiIGJvdHRvbS10by10b3AsIGhvd2V2ZXIgd2UnbGwKKyAgICAgICAgICAgICAgICAvLyBza2lwIGFsbCB0aGUgamFjY29iaWFuIGNvbXB1dGF0aW9ucy4KKyAgICAgICAgICAgICAgICBSZWN0IHI7CisgICAgICAgICAgICAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgMCwgdywgaCB9OworICAgICAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgICAgICAgICB5ID0gZmJIZWlnaHQgLSAoeSArIGgpOworICAgICAgICAgICAgICAgIHdoaWxlIChpdGVyYXRvci5pdGVyYXRlKCZyKSkgeworICAgICAgICAgICAgICAgICAgICBjb25zdCBHTGludCBzeSA9IGZiSGVpZ2h0IC0gKHIudG9wICsgci5oZWlnaHQoKSk7CisgICAgICAgICAgICAgICAgICAgIGdsU2Npc3NvcihyLmxlZnQsIHN5LCByLndpZHRoKCksIHIuaGVpZ2h0KCkpOworICAgICAgICAgICAgICAgICAgICBnbERyYXdUZXhpT0VTKHgsIHksIDAsIHcsIGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGdsRGlzYWJsZUNsaWVudFN0YXRlKEdMX1RFWFRVUkVfQ09PUkRfQVJSQVkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCbHVyLmggYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQmx1ci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0YjExNTYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQmx1ci5oCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfTEFZRVJfQkxVUl9ICisjZGVmaW5lIEFORFJPSURfTEFZRVJfQkxVUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdWkvTGF5ZXJTdGF0ZS5oPgorCisjaW5jbHVkZSA8dWkvUmVnaW9uLmg+CisKKyNpbmNsdWRlICJMYXllckJhc2UuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTGF5ZXJCbHVyIDogcHVibGljIExheWVyQmFzZUNsaWVudAoreworcHVibGljOiAgICAKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgdHlwZUluZm87CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHR5cGVJRDsKKyAgICB2aXJ0dWFsIGNoYXIgY29uc3QqIGdldFR5cGVJRCgpIGNvbnN0IHsgcmV0dXJuIHR5cGVJRDsgfQorICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VHlwZUluZm8oKSBjb25zdCB7IHJldHVybiB0eXBlSW5mbzsgfQorICAgIAorICAgICAgICAgICAgICAgIExheWVyQmx1cihTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQqIGNsaWVudCwgaW50MzJfdCBpKTsKKyAgICAgICAgdmlydHVhbCB+TGF5ZXJCbHVyKCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgb25EcmF3KGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3Q7CisgICAgdmlydHVhbCBib29sIG5lZWRzQmxlbmRpbmcoKSBjb25zdCAgeyByZXR1cm4gdHJ1ZTsgfQorICAgIHZpcnR1YWwgYm9vbCBpc1NlY3VyZSgpIGNvbnN0ICAgICAgIHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgICB2aXJ0dWFsIHVpbnQzMl90IGRvVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpOworICAgIHZpcnR1YWwgdm9pZCBzZXRWaXNpYmxlUmVnaW9uKGNvbnN0IFJlZ2lvbiYgdmlzaWJsZVJlZ2lvbik7CisgICAgdmlydHVhbCB2b2lkIHVubG9ja1BhZ2VGbGlwKGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0sIFJlZ2lvbiYgb3V0RGlydHlSZWdpb24pOworCitwcml2YXRlOgorICAgICAgICAgICAgYm9vbCAgICBtQ2FjaGVEaXJ0eTsKKyAgICBtdXRhYmxlIGJvb2wgICAgbVJlZnJlc2hDYWNoZTsKKyAgICBtdXRhYmxlIGJvb2wgICAgbUF1dG9SZWZyZXNoUGVuZGluZzsKKyAgICAgICAgICAgIG5zZWNzX3QgbUNhY2hlQWdlOworICAgIG11dGFibGUgR0x1aW50ICBtVGV4dHVyZU5hbWU7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfTEFZRVJfQkxVUl9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQnVmZmVyLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJCdWZmZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwZmFiNzAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQnVmZmVyLmNwcApAQCAtMCwwICsxLDY1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZUZsaW5nZXIiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKyNpbmNsdWRlIDx1dGlscy9TdG9wV2F0Y2guaD4KKworI2luY2x1ZGUgPHV0aWxzL0lQQ1RocmVhZFN0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmg+CisKKyNpbmNsdWRlIDx1aS9QaXhlbEZvcm1hdC5oPgorI2luY2x1ZGUgPHVpL0VHTERpc3BsYXlTdXJmYWNlLmg+CisKKyNpbmNsdWRlICJMYXllckJ1ZmZlci5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiVlJhbUhlYXAuaCIKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgdWludDMyX3QgTGF5ZXJCdWZmZXI6OnR5cGVJbmZvID0gTGF5ZXJCYXNlQ2xpZW50Ojp0eXBlSW5mbyB8IDB4MjA7Citjb25zdCBjaGFyKiBjb25zdCBMYXllckJ1ZmZlcjo6dHlwZUlEID0gIkxheWVyQnVmZmVyIjsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xheWVyQnVmZmVyOjpMYXllckJ1ZmZlcihTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgIENsaWVudCogY2xpZW50LCBpbnQzMl90IGkpCisgICAgOiBMYXllckJhc2VDbGllbnQoZmxpbmdlciwgZGlzcGxheSwgY2xpZW50LCBpKSwKKyAgICAgIG1OZWVkc0JsZW5kaW5nKGZhbHNlKQoreworfQorCitMYXllckJ1ZmZlcjo6fkxheWVyQnVmZmVyKCkKK3sKKyAgICBzcDxTdXJmYWNlQnVmZmVyPiBzKGdldENsaWVudFN1cmZhY2UoKSk7CisgICAgaWYgKHMgIT0gMCkgeworICAgICAgICBzLT5kaXNvd24oKTsKKyAgICAgICAgbUNsaWVudFN1cmZhY2UuY2xlYXIoKTsKKyAgICB9Cit9CisKK3NwPExheWVyQnVmZmVyOjpTdXJmYWNlQnVmZmVyPiBMYXllckJ1ZmZlcjo6Z2V0Q2xpZW50U3VyZmFjZSgpIGNvbnN0Cit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICByZXR1cm4gbUNsaWVudFN1cmZhY2UucHJvbW90ZSgpOworfQorCitzcDxMYXllckJhc2VDbGllbnQ6OlN1cmZhY2U+IExheWVyQnVmZmVyOjpnZXRTdXJmYWNlKCkgY29uc3QKK3sKKyAgICBzcDxTdXJmYWNlQnVmZmVyPiBzOworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgcyA9IG1DbGllbnRTdXJmYWNlLnByb21vdGUoKTsKKyAgICBpZiAocyA9PSAwKSB7CisgICAgICAgIHMgPSBuZXcgU3VyZmFjZUJ1ZmZlcihjbGllbnRJbmRleCgpLAorICAgICAgICAgICAgICAgIGNvbnN0X2Nhc3Q8TGF5ZXJCdWZmZXIgKj4odGhpcykpOworICAgICAgICBtQ2xpZW50U3VyZmFjZSA9IHM7CisgICAgfQorICAgIHJldHVybiBzOworfQorCitib29sIExheWVyQnVmZmVyOjpuZWVkc0JsZW5kaW5nKCkgY29uc3QgeworICAgIHJldHVybiBtTmVlZHNCbGVuZGluZzsKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6c2V0TmVlZHNCbGVuZGluZyhib29sIGJsZW5kaW5nKSB7CisgICAgbU5lZWRzQmxlbmRpbmcgPSBibGVuZGluZzsKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6cG9zdEJ1ZmZlcihzc2l6ZV90IG9mZnNldCkKK3sKKyAgICBzcDxTb3VyY2U+IHNvdXJjZShnZXRTb3VyY2UoKSk7CisgICAgaWYgKHNvdXJjZSAhPSAwKQorICAgICAgICBzb3VyY2UtPnBvc3RCdWZmZXIob2Zmc2V0KTsKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6dW5yZWdpc3RlckJ1ZmZlcnMoKQoreworICAgIHNwPFNvdXJjZT4gc291cmNlKGNsZWFyU291cmNlKCkpOworICAgIGlmIChzb3VyY2UgIT0gMCkKKyAgICAgICAgc291cmNlLT51bnJlZ2lzdGVyQnVmZmVycygpOworfQorCit1aW50MzJfdCBMYXllckJ1ZmZlcjo6ZG9UcmFuc2FjdGlvbih1aW50MzJfdCBmbGFncykKK3sKKyAgICBzcDxTb3VyY2U+IHNvdXJjZShnZXRTb3VyY2UoKSk7CisgICAgaWYgKHNvdXJjZSAhPSAwKQorICAgICAgICBzb3VyY2UtPm9uVHJhbnNhY3Rpb24oZmxhZ3MpOworICAgIHJldHVybiBMYXllckJhc2U6OmRvVHJhbnNhY3Rpb24oZmxhZ3MpOyAgICAKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6dW5sb2NrUGFnZUZsaXAoY29uc3QgVHJhbnNmb3JtJiBwbGFuZVRyYW5zZm9ybSwKKyAgICAgICAgUmVnaW9uJiBvdXREaXJ0eVJlZ2lvbikKK3sKKyAgICAvLyB0aGlzIGNvZGUtcGF0aCBtdXN0IGJlIGFzIHRpZ2h0IGFzIHBvc3NpYmxlLCBpdCdzIGNhbGxlZCBlYWNoIHRpbWUKKyAgICAvLyB0aGUgc2NyZWVuIGlzIGNvbXBvc2l0ZWQuCisgICAgc3A8U291cmNlPiBzb3VyY2UoZ2V0U291cmNlKCkpOworICAgIGlmIChzb3VyY2UgIT0gMCkKKyAgICAgICAgc291cmNlLT5vblZpc2liaWxpdHlSZXNvbHZlZChwbGFuZVRyYW5zZm9ybSk7CisgICAgTGF5ZXJCYXNlOjp1bmxvY2tQYWdlRmxpcChwbGFuZVRyYW5zZm9ybSwgb3V0RGlydHlSZWdpb24pOyAgICAKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6b25EcmF3KGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3QKK3sKKyAgICBzcDxTb3VyY2U+IHNvdXJjZShnZXRTb3VyY2UoKSk7CisgICAgaWYgKExJS0VMWShzb3VyY2UgIT0gMCkpIHsKKyAgICAgICAgc291cmNlLT5vbkRyYXcoY2xpcCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgY2xlYXJXaXRoT3BlbkdMKGNsaXApOworICAgIH0KK30KKworYm9vbCBMYXllckJ1ZmZlcjo6dHJhbnNmb3JtZWQoKSBjb25zdAoreworICAgIHNwPFNvdXJjZT4gc291cmNlKGdldFNvdXJjZSgpKTsKKyAgICBpZiAoTElLRUxZKHNvdXJjZSAhPSAwKSkKKyAgICAgICAgcmV0dXJuIHNvdXJjZS0+dHJhbnNmb3JtZWQoKTsKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogVGhpcyBjcmVhdGVzIGEgImJ1ZmZlciIgc291cmNlIGZvciB0aGlzIHN1cmZhY2UKKyAqLworc3RhdHVzX3QgTGF5ZXJCdWZmZXI6OnJlZ2lzdGVyQnVmZmVycyhjb25zdCBJU3VyZmFjZTo6QnVmZmVySGVhcCYgYnVmZmVycykKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIGlmIChtU291cmNlICE9IDApCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKworICAgIHNwPEJ1ZmZlclNvdXJjZT4gc291cmNlID0gbmV3IEJ1ZmZlclNvdXJjZSgqdGhpcywgYnVmZmVycyk7CisKKyAgICBzdGF0dXNfdCByZXN1bHQgPSBzb3VyY2UtPmdldFN0YXR1cygpOworICAgIGlmIChyZXN1bHQgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgbVNvdXJjZSA9IHNvdXJjZTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30gICAgCisKKy8qKgorICogVGhpcyBjcmVhdGVzIGFuICJvdmVybGF5IiBzb3VyY2UgZm9yIHRoaXMgc3VyZmFjZQorICovCitzcDxPdmVybGF5UmVmPiBMYXllckJ1ZmZlcjo6Y3JlYXRlT3ZlcmxheSh1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGYpCit7CisgICAgc3A8T3ZlcmxheVJlZj4gcmVzdWx0OworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgaWYgKG1Tb3VyY2UgIT0gMCkKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKworICAgIHNwPE92ZXJsYXlTb3VyY2U+IHNvdXJjZSA9IG5ldyBPdmVybGF5U291cmNlKCp0aGlzLCAmcmVzdWx0LCB3LCBoLCBmKTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgbVNvdXJjZSA9IHNvdXJjZTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3A8TGF5ZXJCdWZmZXI6OlNvdXJjZT4gTGF5ZXJCdWZmZXI6OmdldFNvdXJjZSgpIGNvbnN0IHsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIHJldHVybiBtU291cmNlOworfQorCitzcDxMYXllckJ1ZmZlcjo6U291cmNlPiBMYXllckJ1ZmZlcjo6Y2xlYXJTb3VyY2UoKSB7CisgICAgc3A8U291cmNlPiBzb3VyY2U7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBzb3VyY2UgPSBtU291cmNlOworICAgIG1Tb3VyY2UuY2xlYXIoKTsKKyAgICByZXR1cm4gc291cmNlOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBMYXllckJ1ZmZlcjo6U3VyZmFjZUJ1ZmZlcgorLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMYXllckJ1ZmZlcjo6U3VyZmFjZUJ1ZmZlcjo6U3VyZmFjZUJ1ZmZlcihTdXJmYWNlSUQgaWQsIExheWVyQnVmZmVyKiBvd25lcikKKzogTGF5ZXJCYXNlQ2xpZW50OjpTdXJmYWNlKGlkLCBvd25lci0+Z2V0SWRlbnRpdHkoKSksIG1Pd25lcihvd25lcikKK3sKK30KKworTGF5ZXJCdWZmZXI6OlN1cmZhY2VCdWZmZXI6On5TdXJmYWNlQnVmZmVyKCkKK3sKKyAgICB1bnJlZ2lzdGVyQnVmZmVycygpOworICAgIG1Pd25lciA9IDA7Cit9CisKK3N0YXR1c190IExheWVyQnVmZmVyOjpTdXJmYWNlQnVmZmVyOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgUkVHSVNURVJfQlVGRkVSUzoKKyAgICAgICAgY2FzZSBVTlJFR0lTVEVSX0JVRkZFUlM6CisgICAgICAgIGNhc2UgQ1JFQVRFX09WRVJMQVk6CisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIGNvZGVzIHRoYXQgcmVxdWlyZSBwZXJtaXNzaW9uIGNoZWNrCisgICAgICAgICAgICBJUENUaHJlYWRTdGF0ZSogaXBjID0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKTsKKyAgICAgICAgICAgIGNvbnN0IGludCBwaWQgPSBpcGMtPmdldENhbGxpbmdQaWQoKTsKKyAgICAgICAgICAgIGNvbnN0IGludCBzZWxmX3BpZCA9IGdldHBpZCgpOworICAgICAgICAgICAgaWYgKExJS0VMWShwaWQgIT0gc2VsZl9waWQpKSB7CisgICAgICAgICAgICAgICAgLy8gd2UncmUgY2FsbGVkIGZyb20gYSBkaWZmZXJlbnQgcHJvY2VzcywgZG8gdGhlIHJlYWwgY2hlY2sKKyAgICAgICAgICAgICAgICBpZiAoIWNoZWNrQ2FsbGluZ1Blcm1pc3Npb24oCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcxNigiYW5kcm9pZC5wZXJtaXNzaW9uLkFDQ0VTU19TVVJGQUNFX0ZMSU5HRVIiKSkpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgdWlkID0gaXBjLT5nZXRDYWxsaW5nVWlkKCk7CisgICAgICAgICAgICAgICAgICAgIExPR0UoIlBlcm1pc3Npb24gRGVuaWFsOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IGFjY2VzcyBTdXJmYWNlRmxpbmdlciBwaWQ9JWQsIHVpZD0lZCIsIHBpZCwgdWlkKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTGF5ZXJCYXNlQ2xpZW50OjpTdXJmYWNlOjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7Cit9CisKK3N0YXR1c190IExheWVyQnVmZmVyOjpTdXJmYWNlQnVmZmVyOjpyZWdpc3RlckJ1ZmZlcnMoY29uc3QgSVN1cmZhY2U6OkJ1ZmZlckhlYXAmIGJ1ZmZlcnMpCit7CisgICAgTGF5ZXJCdWZmZXIqIG93bmVyKGdldE93bmVyKCkpOworICAgIGlmIChvd25lcikKKyAgICAgICAgcmV0dXJuIG93bmVyLT5yZWdpc3RlckJ1ZmZlcnMoYnVmZmVycyk7CisgICAgcmV0dXJuIE5PX0lOSVQ7Cit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6OlN1cmZhY2VCdWZmZXI6OnBvc3RCdWZmZXIoc3NpemVfdCBvZmZzZXQpCit7CisgICAgTGF5ZXJCdWZmZXIqIG93bmVyKGdldE93bmVyKCkpOworICAgIGlmIChvd25lcikKKyAgICAgICAgb3duZXItPnBvc3RCdWZmZXIob2Zmc2V0KTsKK30KKwordm9pZCBMYXllckJ1ZmZlcjo6U3VyZmFjZUJ1ZmZlcjo6dW5yZWdpc3RlckJ1ZmZlcnMoKQoreworICAgIExheWVyQnVmZmVyKiBvd25lcihnZXRPd25lcigpKTsKKyAgICBpZiAob3duZXIpCisgICAgICAgIG93bmVyLT51bnJlZ2lzdGVyQnVmZmVycygpOworfQorCitzcDxPdmVybGF5UmVmPiBMYXllckJ1ZmZlcjo6U3VyZmFjZUJ1ZmZlcjo6Y3JlYXRlT3ZlcmxheSgKKyAgICAgICAgdWludDMyX3QgdywgdWludDMyX3QgaCwgaW50MzJfdCBmb3JtYXQpIHsKKyAgICBzcDxPdmVybGF5UmVmPiByZXN1bHQ7CisgICAgTGF5ZXJCdWZmZXIqIG93bmVyKGdldE93bmVyKCkpOworICAgIGlmIChvd25lcikKKyAgICAgICAgcmVzdWx0ID0gb3duZXItPmNyZWF0ZU92ZXJsYXkodywgaCwgZm9ybWF0KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIExheWVyQnVmZmVyOjpTdXJmYWNlQnVmZmVyOjpkaXNvd24oKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgbU93bmVyID0gMDsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gTGF5ZXJCdWZmZXI6OkJ1ZmZlcgorLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMYXllckJ1ZmZlcjo6QnVmZmVyOjpCdWZmZXIoY29uc3QgSVN1cmZhY2U6OkJ1ZmZlckhlYXAmIGJ1ZmZlcnMsIHNzaXplX3Qgb2Zmc2V0KQorICAgIDogbUJ1ZmZlckhlYXAoYnVmZmVycykKK3sKKyAgICBOYXRpdmVCdWZmZXImIHNyYyhtTmF0aXZlQnVmZmVyKTsKKyAgICBzcmMuY3JvcC5sID0gMDsKKyAgICBzcmMuY3JvcC50ID0gMDsKKyAgICBzcmMuY3JvcC5yID0gYnVmZmVycy53OworICAgIHNyYy5jcm9wLmIgPSBidWZmZXJzLmg7CisgICAgc3JjLmltZy53ID0gYnVmZmVycy5ob3Jfc3RyaWRlID86IGJ1ZmZlcnMudzsKKyAgICBzcmMuaW1nLmggPSBidWZmZXJzLnZlcl9zdHJpZGUgPzogYnVmZmVycy5oOworICAgIHNyYy5pbWcuZm9ybWF0ID0gYnVmZmVycy5mb3JtYXQ7CisgICAgc3JjLmltZy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgc3JjLmltZy5iYXNlICAgPSBidWZmZXJzLmhlYXAtPmJhc2UoKTsKKyAgICBzcmMuaW1nLmZkICAgICA9IGJ1ZmZlcnMuaGVhcC0+aGVhcElEKCk7Cit9CisKK0xheWVyQnVmZmVyOjpCdWZmZXI6On5CdWZmZXIoKQoreworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBMYXllckJ1ZmZlcjo6U291cmNlCisvLyBMYXllckJ1ZmZlcjo6QnVmZmVyU291cmNlCisvLyBMYXllckJ1ZmZlcjo6T3ZlcmxheVNvdXJjZQorLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMYXllckJ1ZmZlcjo6U291cmNlOjpTb3VyY2UoTGF5ZXJCdWZmZXImIGxheWVyKQorICAgIDogbUxheWVyKGxheWVyKQoreyAgICAKK30KK0xheWVyQnVmZmVyOjpTb3VyY2U6On5Tb3VyY2UoKSB7ICAgIAorfQordm9pZCBMYXllckJ1ZmZlcjo6U291cmNlOjpvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdCB7Cit9Cit2b2lkIExheWVyQnVmZmVyOjpTb3VyY2U6Om9uVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpIHsKK30KK3ZvaWQgTGF5ZXJCdWZmZXI6OlNvdXJjZTo6b25WaXNpYmlsaXR5UmVzb2x2ZWQoCisgICAgICAgIGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0pIHsKK30KK3ZvaWQgTGF5ZXJCdWZmZXI6OlNvdXJjZTo6cG9zdEJ1ZmZlcihzc2l6ZV90IG9mZnNldCkgeworfQordm9pZCBMYXllckJ1ZmZlcjo6U291cmNlOjp1bnJlZ2lzdGVyQnVmZmVycygpIHsKK30KK2Jvb2wgTGF5ZXJCdWZmZXI6OlNvdXJjZTo6dHJhbnNmb3JtZWQoKSBjb25zdCB7CisgICAgcmV0dXJuIG1MYXllci5tVHJhbnNmb3JtZWQ7IAorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTGF5ZXJCdWZmZXI6OkJ1ZmZlclNvdXJjZTo6QnVmZmVyU291cmNlKExheWVyQnVmZmVyJiBsYXllciwKKyAgICAgICAgY29uc3QgSVN1cmZhY2U6OkJ1ZmZlckhlYXAmIGJ1ZmZlcnMpCisgICAgOiBTb3VyY2UobGF5ZXIpLCBtU3RhdHVzKE5PX0VSUk9SKSwgCisgICAgICBtQnVmZmVyU2l6ZSgwKSwgbVRleHR1cmVOYW1lKC0xVSkKK3sKKyAgICBpZiAoYnVmZmVycy5oZWFwID09IE5VTEwpIHsKKyAgICAgICAgLy8gdGhpcyBpcyBhbGxvd2VkLCBidXQgaW4gdGhpcyBjYXNlLCBpdCBpcyBpbGxlZ2FsIHRvIHJlY2VpdmUKKyAgICAgICAgLy8gcG9zdEJ1ZmZlcigpLiBUaGUgc3VyZmFjZSBqdXN0IGVyYXNlcyB0aGUgZnJhbWVidWZmZXIgd2l0aAorICAgICAgICAvLyBmdWxseSB0cmFuc3BhcmVudCBwaXhlbHMuCisgICAgICAgIG1CdWZmZXJIZWFwID0gYnVmZmVyczsKKyAgICAgICAgbUxheWVyLnNldE5lZWRzQmxlbmRpbmcoZmFsc2UpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgc3RhdHVzX3QgZXJyID0gKGJ1ZmZlcnMuaGVhcC0+aGVhcElEKCkgPj0gMCkgPyBOT19FUlJPUiA6IE5PX0lOSVQ7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICBMT0dFKCJMYXllckJ1ZmZlcjo6QnVmZmVyU291cmNlOiBpbnZhbGlkIGhlYXAgKCVzKSIsIHN0cmVycm9yKGVycikpOworICAgICAgICBtU3RhdHVzID0gZXJyOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIFBpeGVsRm9ybWF0SW5mbyBpbmZvOworICAgIGVyciA9IGdldFBpeGVsRm9ybWF0SW5mbyhidWZmZXJzLmZvcm1hdCwgJmluZm8pOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgTE9HRSgiTGF5ZXJCdWZmZXI6OkJ1ZmZlclNvdXJjZTogaW52YWxpZCBmb3JtYXQgJWQgKCVzKSIsCisgICAgICAgICAgICAgICAgYnVmZmVycy5mb3JtYXQsIHN0cmVycm9yKGVycikpOworICAgICAgICBtU3RhdHVzID0gZXJyOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKGJ1ZmZlcnMuaG9yX3N0cmlkZTwwIHx8IGJ1ZmZlcnMudmVyX3N0cmlkZTwwKSB7CisgICAgICAgIExPR0UoIkxheWVyQnVmZmVyOjpCdWZmZXJTb3VyY2U6IGludmFsaWQgcGFyYW1ldGVycyAiCisgICAgICAgICAgICAgIih3PSVkLCBoPSVkLCB4cz0lZCwgeXM9JWQpIiwgCisgICAgICAgICAgICAgYnVmZmVycy53LCBidWZmZXJzLmgsIGJ1ZmZlcnMuaG9yX3N0cmlkZSwgYnVmZmVycy52ZXJfc3RyaWRlKTsKKyAgICAgICAgbVN0YXR1cyA9IEJBRF9WQUxVRTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIG1CdWZmZXJIZWFwID0gYnVmZmVyczsKKyAgICBtTGF5ZXIuc2V0TmVlZHNCbGVuZGluZygoaW5mby5oX2FscGhhIC0gaW5mby5sX2FscGhhKSA+IDApOyAgICAKKyAgICBtQnVmZmVyU2l6ZSA9IGluZm8uZ2V0U2NhbmxpbmVTaXplKGJ1ZmZlcnMuaG9yX3N0cmlkZSkqYnVmZmVycy52ZXJfc3RyaWRlOworICAgIG1MYXllci5mb3JjZVZpc2liaWxpdHlUcmFuc2FjdGlvbigpOworICAgIAorfQorCitMYXllckJ1ZmZlcjo6QnVmZmVyU291cmNlOjp+QnVmZmVyU291cmNlKCkKK3sgICAgCisgICAgaWYgKG1UZXh0dXJlTmFtZSAhPSAtMVUpIHsKKyAgICAgICAgTGF5ZXJCYXNlOjpkZWxldGVkVGV4dHVyZXMuYWRkKG1UZXh0dXJlTmFtZSk7CisgICAgfQorfQorCit2b2lkIExheWVyQnVmZmVyOjpCdWZmZXJTb3VyY2U6OnBvc3RCdWZmZXIoc3NpemVfdCBvZmZzZXQpCit7ICAgIAorICAgIElTdXJmYWNlOjpCdWZmZXJIZWFwIGJ1ZmZlcnM7CisgICAgeyAvLyBzY29wZSBmb3IgdGhlIGxvY2sKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgYnVmZmVycyA9IG1CdWZmZXJIZWFwOworICAgICAgICBpZiAoYnVmZmVycy5oZWFwICE9IDApIHsKKyAgICAgICAgICAgIGNvbnN0IHNpemVfdCBtZW1vcnlTaXplID0gYnVmZmVycy5oZWFwLT5nZXRTaXplKCk7CisgICAgICAgICAgICBpZiAoKHNpemVfdChvZmZzZXQpICsgbUJ1ZmZlclNpemUpID4gbWVtb3J5U2l6ZSkgeworICAgICAgICAgICAgICAgIExPR0UoIkxheWVyQnVmZmVyOjpCdWZmZXJTb3VyY2U6OnBvc3RCdWZmZXIoKSAiCisgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBidWZmZXIgKG9mZnNldD0lZCwgc2l6ZT0lZCwgaGVhcC1zaXplPSVkIiwKKyAgICAgICAgICAgICAgICAgICAgIGludChvZmZzZXQpLCBpbnQobUJ1ZmZlclNpemUpLCBpbnQobWVtb3J5U2l6ZSkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHNwPEJ1ZmZlcj4gYnVmZmVyOworICAgIGlmIChidWZmZXJzLmhlYXAgIT0gMCkgeworICAgICAgICBidWZmZXIgPSBuZXcgTGF5ZXJCdWZmZXI6OkJ1ZmZlcihidWZmZXJzLCBvZmZzZXQpOworICAgICAgICBpZiAoYnVmZmVyLT5nZXRTdGF0dXMoKSAhPSBOT19FUlJPUikKKyAgICAgICAgICAgIGJ1ZmZlci5jbGVhcigpOworICAgICAgICBzZXRCdWZmZXIoYnVmZmVyKTsKKyAgICAgICAgbUxheWVyLmludmFsaWRhdGUoKTsKKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6OkJ1ZmZlclNvdXJjZTo6dW5yZWdpc3RlckJ1ZmZlcnMoKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgbUJ1ZmZlckhlYXAuaGVhcC5jbGVhcigpOworICAgIG1CdWZmZXIuY2xlYXIoKTsKKyAgICBtTGF5ZXIuaW52YWxpZGF0ZSgpOworfQorCitzcDxMYXllckJ1ZmZlcjo6QnVmZmVyPiBMYXllckJ1ZmZlcjo6QnVmZmVyU291cmNlOjpnZXRCdWZmZXIoKSBjb25zdAoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgcmV0dXJuIG1CdWZmZXI7Cit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6OkJ1ZmZlclNvdXJjZTo6c2V0QnVmZmVyKGNvbnN0IHNwPExheWVyQnVmZmVyOjpCdWZmZXI+JiBidWZmZXIpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBtQnVmZmVyID0gYnVmZmVyOworfQorCitib29sIExheWVyQnVmZmVyOjpCdWZmZXJTb3VyY2U6OnRyYW5zZm9ybWVkKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUJ1ZmZlckhlYXAudHJhbnNmb3JtID8gdHJ1ZSA6IFNvdXJjZTo6dHJhbnNmb3JtZWQoKTsgCit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6OkJ1ZmZlclNvdXJjZTo6b25EcmF3KGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3QgCit7CisgICAgc3A8QnVmZmVyPiBidWZmZXIoZ2V0QnVmZmVyKCkpOworICAgIGlmIChVTkxJS0VMWShidWZmZXIgPT0gMCkpICB7CisgICAgICAgIC8vIG5vdGhpbmcgdG8gZG8sIHdlIGRvbid0IGhhdmUgYSBidWZmZXIKKyAgICAgICAgbUxheWVyLmNsZWFyV2l0aE9wZW5HTChjbGlwKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHN0YXR1c190IGVyciA9IE5PX0VSUk9SOworICAgIE5hdGl2ZUJ1ZmZlciBzcmMoYnVmZmVyLT5nZXRCdWZmZXIoKSk7CisgICAgY29uc3QgUmVjdCYgdHJhbnNmb3JtZWRCb3VuZHMgPSBtTGF5ZXIuZ2V0VHJhbnNmb3JtZWRCb3VuZHMoKTsKKyAgICBjb25zdCBpbnQgY2FuX3VzZV9jb3B5Yml0ID0gbUxheWVyLmNhblVzZUNvcHliaXQoKTsKKworICAgIGlmIChjYW5fdXNlX2NvcHliaXQpICB7CisgICAgICAgIGNvbnN0IGludCBzcmNfd2lkdGggID0gc3JjLmNyb3AuciAtIHNyYy5jcm9wLmw7CisgICAgICAgIGNvbnN0IGludCBzcmNfaGVpZ2h0ID0gc3JjLmNyb3AuYiAtIHNyYy5jcm9wLnQ7CisgICAgICAgIGludCBXID0gdHJhbnNmb3JtZWRCb3VuZHMud2lkdGgoKTsKKyAgICAgICAgaW50IEggPSB0cmFuc2Zvcm1lZEJvdW5kcy5oZWlnaHQoKTsKKyAgICAgICAgaWYgKG1MYXllci5nZXRPcmllbnRhdGlvbigpICYgVHJhbnNmb3JtOjpST1RfOTApIHsKKyAgICAgICAgICAgIGludCB0KFcpOyBXPUg7IEg9dDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFdpdGggTGF5ZXJCdWZmZXIsIGl0IGlzIGxpa2VseSB0aGF0IHdlJ2xsIGhhdmUgdG8gcmVzY2FsZSB0aGUKKyAgICAgICAgICogc3VyZmFjZSwgYmVjYXVzZSB0aGlzIGlzIG9mdGVuIHVzZWQgZm9yIHZpZGVvIHBsYXliYWNrIG9yCisgICAgICAgICAqIGNhbWVyYS1wcmV2aWV3LiBTaW5jZSB3ZSB3YW50IHRoZXNlIG9wZXJhdGlvbiBhcyBmYXN0IGFzIHBvc3NpYmxlCisgICAgICAgICAqIHdlIG1ha2Ugc3VyZSB3ZSBjYW4gdXNlIHRoZSAyRCBIL1cgZXZlbiBpZiBpdCBkb2Vzbid0IHN1cHBvcnQKKyAgICAgICAgICogdGhlIHJlcXVlc3RlZCBzY2FsZSBmYWN0b3IsIGluIHdoaWNoIGNhc2Ugd2UgcGVyZm9ybSB0aGUgc2NhbGluZworICAgICAgICAgKiBpbiBzZXZlcmFsIHBhc3Nlcy4gKi8KKworICAgICAgICBjb3B5Yml0X2RldmljZV90KiBjb3B5Yml0ID0gbUxheWVyLm1GbGluZ2VyLT5nZXRCbGl0RW5naW5lKCk7CisgICAgICAgIGNvbnN0IGZsb2F0IG1pbiA9IGNvcHliaXQtPmdldChjb3B5Yml0LCBDT1BZQklUX01JTklGSUNBVElPTl9MSU1JVCk7CisgICAgICAgIGNvbnN0IGZsb2F0IG1hZyA9IGNvcHliaXQtPmdldChjb3B5Yml0LCBDT1BZQklUX01BR05JRklDQVRJT05fTElNSVQpOworCisgICAgICAgIGZsb2F0IHhzY2FsZSA9IDEuMGY7CisgICAgICAgIGlmIChzcmNfd2lkdGggPiBXKm1pbikgICAgICAgICAgeHNjYWxlID0gMS4wZiAvIG1pbjsKKyAgICAgICAgZWxzZSBpZiAoc3JjX3dpZHRoKm1hZyA8IFcpICAgICB4c2NhbGUgPSBtYWc7CisKKyAgICAgICAgZmxvYXQgeXNjYWxlID0gMS4wZjsKKyAgICAgICAgaWYgKHNyY19oZWlnaHQgPiBIKm1pbikgICAgICAgICB5c2NhbGUgPSAxLjBmIC8gbWluOworICAgICAgICBlbHNlIGlmIChzcmNfaGVpZ2h0Km1hZyA8IEgpICAgIHlzY2FsZSA9IG1hZzsKKworICAgICAgICBpZiAoVU5MSUtFTFkoeHNjYWxlIT0xLjBmIHx8IHlzY2FsZSE9MS4wZikpIHsKKyAgICAgICAgICAgIGlmIChVTkxJS0VMWShtVGVtcG9yYXJ5RGVhbGVyID09IDApKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb2NhdGUgYSBtZW1vcnktZGVhbGVyIGZvciB0aGlzIHRoZSBmaXJzdCB0aW1lCisgICAgICAgICAgICAgICAgbVRlbXBvcmFyeURlYWxlciA9IG1MYXllci5tRmxpbmdlci0+Z2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCkKKyAgICAgICAgICAgICAgICAgICAgLT5jcmVhdGVIZWFwKElTdXJmYWNlQ29tcG9zZXI6OmVIYXJkd2FyZSk7CisgICAgICAgICAgICAgICAgbVRlbXBCaXRtYXAuaW5pdChtVGVtcG9yYXJ5RGVhbGVyKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY29uc3QgaW50IHRtcF93ID0gZmxvb3JmKHNyY193aWR0aCAgKiB4c2NhbGUpOworICAgICAgICAgICAgY29uc3QgaW50IHRtcF9oID0gZmxvb3JmKHNyY19oZWlnaHQgKiB5c2NhbGUpOworICAgICAgICAgICAgZXJyID0gbVRlbXBCaXRtYXAuc2V0Qml0cyh0bXBfdywgdG1wX2gsIDEsIHNyYy5pbWcuZm9ybWF0KTsKKworICAgICAgICAgICAgaWYgKExJS0VMWShlcnIgPT0gTk9fRVJST1IpKSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQnVmZmVyIHRtcDsKKyAgICAgICAgICAgICAgICBtVGVtcEJpdG1hcC5nZXRCaXRtYXBTdXJmYWNlKCZ0bXAuaW1nKTsKKyAgICAgICAgICAgICAgICB0bXAuY3JvcC5sID0gMDsKKyAgICAgICAgICAgICAgICB0bXAuY3JvcC50ID0gMDsKKyAgICAgICAgICAgICAgICB0bXAuY3JvcC5yID0gdG1wLmltZy53OworICAgICAgICAgICAgICAgIHRtcC5jcm9wLmIgPSB0bXAuaW1nLmg7CisKKyAgICAgICAgICAgICAgICByZWdpb25faXRlcmF0b3IgdG1wX2l0KFJlZ2lvbihSZWN0KHRtcC5jcm9wLnIsIHRtcC5jcm9wLmIpKSk7CisgICAgICAgICAgICAgICAgY29weWJpdC0+c2V0X3BhcmFtZXRlcihjb3B5Yml0LCBDT1BZQklUX1RSQU5TRk9STSwgMCk7CisgICAgICAgICAgICAgICAgY29weWJpdC0+c2V0X3BhcmFtZXRlcihjb3B5Yml0LCBDT1BZQklUX1BMQU5FX0FMUEhBLCAweEZGKTsKKyAgICAgICAgICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfRElUSEVSLCBDT1BZQklUX0RJU0FCTEUpOworICAgICAgICAgICAgICAgIGVyciA9IGNvcHliaXQtPnN0cmV0Y2goY29weWJpdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICZ0bXAuaW1nLCAmc3JjLmltZywgJnRtcC5jcm9wLCAmc3JjLmNyb3AsICZ0bXBfaXQpOworICAgICAgICAgICAgICAgIHNyYyA9IHRtcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcobUxheWVyLmdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKSk7CisgICAgICAgIGNvcHliaXRfaW1hZ2VfdCBkc3Q7CisgICAgICAgIGh3LmdldERpc3BsYXlTdXJmYWNlKCZkc3QpOworICAgICAgICBjb25zdCBjb3B5Yml0X3JlY3RfdCYgZHJlY3QKKyAgICAgICAgICAgID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjb3B5Yml0X3JlY3RfdCY+KHRyYW5zZm9ybWVkQm91bmRzKTsKKyAgICAgICAgY29uc3QgU3RhdGUmIHMobUxheWVyLmRyYXdpbmdTdGF0ZSgpKTsKKyAgICAgICAgcmVnaW9uX2l0ZXJhdG9yIGl0KGNsaXApOworICAgICAgICAKKyAgICAgICAgLy8gcGljayB0aGUgcmlnaHQgb3JpZW50YXRpb24gZm9yIHRoaXMgYnVmZmVyCisgICAgICAgIGludCBvcmllbnRhdGlvbiA9IG1MYXllci5nZXRPcmllbnRhdGlvbigpOworICAgICAgICBpZiAoVU5MSUtFTFkobUJ1ZmZlckhlYXAudHJhbnNmb3JtKSkgeworICAgICAgICAgICAgVHJhbnNmb3JtIHJvdDkwOworICAgICAgICAgICAgR3JhcGhpY1BsYW5lOjpvcmllbnRhdGlvblRvVHJhbnNmcm9tKAorICAgICAgICAgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjplT3JpZW50YXRpb245MCwgMCwgMCwgJnJvdDkwKTsKKyAgICAgICAgICAgIGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0obUxheWVyLmdyYXBoaWNQbGFuZSgwKS50cmFuc2Zvcm0oKSk7CisgICAgICAgICAgICBjb25zdCBMYXllcjo6U3RhdGUmIHMobUxheWVyLmRyYXdpbmdTdGF0ZSgpKTsKKyAgICAgICAgICAgIFRyYW5zZm9ybSB0cihwbGFuZVRyYW5zZm9ybSAqIHMudHJhbnNmb3JtICogcm90OTApOworICAgICAgICAgICAgb3JpZW50YXRpb24gPSB0ci5nZXRPcmllbnRhdGlvbigpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfVFJBTlNGT1JNLCBvcmllbnRhdGlvbik7CisgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9QTEFORV9BTFBIQSwgcy5hbHBoYSk7CisgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9ESVRIRVIsIENPUFlCSVRfRU5BQkxFKTsKKworICAgICAgICBlcnIgPSBjb3B5Yml0LT5zdHJldGNoKGNvcHliaXQsCisgICAgICAgICAgICAgICAgJmRzdCwgJnNyYy5pbWcsICZkcmVjdCwgJnNyYy5jcm9wLCAmaXQpOworICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICBMT0dFKCJjb3B5Yml0IGZhaWxlZCAoJXMpIiwgc3RyZXJyb3IoZXJyKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIWNhbl91c2VfY29weWJpdCB8fCBlcnIpIHsKKyAgICAgICAgaWYgKFVOTElLRUxZKG1UZXh0dXJlTmFtZSA9PSAtMUxVKSkgeworICAgICAgICAgICAgbVRleHR1cmVOYW1lID0gbUxheWVyLmNyZWF0ZVRleHR1cmUoKTsKKyAgICAgICAgfQorICAgICAgICBHTHVpbnQgdyA9IDA7CisgICAgICAgIEdMdWludCBoID0gMDsKKyAgICAgICAgR0dMU3VyZmFjZSB0OworICAgICAgICB0LnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgIHQud2lkdGggID0gc3JjLmNyb3AucjsKKyAgICAgICAgdC5oZWlnaHQgPSBzcmMuY3JvcC5iOworICAgICAgICB0LnN0cmlkZSA9IHNyYy5pbWcudzsKKyAgICAgICAgdC52c3RyaWRlPSBzcmMuaW1nLmg7CisgICAgICAgIHQuZm9ybWF0ID0gc3JjLmltZy5mb3JtYXQ7CisgICAgICAgIHQuZGF0YSA9IChHR0x1Ynl0ZSopKGludHB0cl90KHNyYy5pbWcuYmFzZSkgKyBzcmMuaW1nLm9mZnNldCk7CisgICAgICAgIGNvbnN0IFJlZ2lvbiBkaXJ0eShSZWN0KHQud2lkdGgsIHQuaGVpZ2h0KSk7CisgICAgICAgIG1MYXllci5sb2FkVGV4dHVyZShkaXJ0eSwgbVRleHR1cmVOYW1lLCB0LCB3LCBoKTsKKyAgICAgICAgbUxheWVyLmRyYXdXaXRoT3BlbkdMKGNsaXAsIG1UZXh0dXJlTmFtZSwgdCwgbUJ1ZmZlckhlYXAudHJhbnNmb3JtKTsKKyAgICB9Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xheWVyQnVmZmVyOjpPdmVybGF5U291cmNlOjpPdmVybGF5U291cmNlKExheWVyQnVmZmVyJiBsYXllciwKKyAgICAgICAgc3A8T3ZlcmxheVJlZj4qIG92ZXJsYXlSZWYsIAorICAgICAgICB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGZvcm1hdCkKKyAgICA6IFNvdXJjZShsYXllciksIG1WaXNpYmlsaXR5Q2hhbmdlZChmYWxzZSksCisgICAgbU92ZXJsYXkoMCksIG1PdmVybGF5SGFuZGxlKDApLCBtT3ZlcmxheURldmljZSgwKQoreworICAgIG92ZXJsYXlfY29udHJvbF9kZXZpY2VfdCogb3ZlcmxheV9kZXYgPSBtTGF5ZXIubUZsaW5nZXItPmdldE92ZXJsYXlFbmdpbmUoKTsKKyAgICBpZiAob3ZlcmxheV9kZXYgPT0gTlVMTCkgeworICAgICAgICAvLyBvdmVybGF5cyBub3Qgc3VwcG9ydGVkCisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBtT3ZlcmxheURldmljZSA9IG92ZXJsYXlfZGV2OworICAgIG92ZXJsYXlfdCogb3ZlcmxheSA9IG92ZXJsYXlfZGV2LT5jcmVhdGVPdmVybGF5KG92ZXJsYXlfZGV2LCB3LCBoLCBmb3JtYXQpOworICAgIGlmIChvdmVybGF5ID09IE5VTEwpIHsKKyAgICAgICAgLy8gY291bGRuJ3QgY3JlYXRlIHRoZSBvdmVybGF5IChubyBtZW1vcnk/IG5vIG1vcmUgb3ZlcmxheXM/KQorICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gZW5hYmxlIGRpdGhlcmluZy4uLgorICAgIG92ZXJsYXlfZGV2LT5zZXRQYXJhbWV0ZXIob3ZlcmxheV9kZXYsIG92ZXJsYXksIAorICAgICAgICAgICAgT1ZFUkxBWV9ESVRIRVIsIE9WRVJMQVlfRU5BQkxFKTsKKworICAgIG1PdmVybGF5ID0gb3ZlcmxheTsKKyAgICBtV2lkdGggPSBvdmVybGF5LT53OworICAgIG1IZWlnaHQgPSBvdmVybGF5LT5oOworICAgIG1Gb3JtYXQgPSBvdmVybGF5LT5mb3JtYXQ7IAorICAgIG1XaWR0aFN0cmlkZSA9IG92ZXJsYXktPndfc3RyaWRlOworICAgIG1IZWlnaHRTdHJpZGUgPSBvdmVybGF5LT5oX3N0cmlkZTsKKworICAgIG1PdmVybGF5SGFuZGxlID0gb3ZlcmxheS0+Z2V0SGFuZGxlUmVmKG92ZXJsYXkpOworICAgIAorICAgIC8vIE5PVEU6IGhlcmUgaXQncyBva2F5IHRvIGFjcXVpcmUgYSByZWZlcmVuY2UgdG8gInRoaXMibSBhcyBsb25nIGFzCisgICAgLy8gdGhlIHJlZmVyZW5jZSBpcyBub3QgcmVsZWFzZWQgYmVmb3JlIHdlIGxlYXZlIHRoZSBjdG9yLgorICAgIHNwPE92ZXJsYXlDaGFubmVsPiBjaGFubmVsID0gbmV3IE92ZXJsYXlDaGFubmVsKHRoaXMpOworCisgICAgKm92ZXJsYXlSZWYgPSBuZXcgT3ZlcmxheVJlZihtT3ZlcmxheUhhbmRsZSwgY2hhbm5lbCwKKyAgICAgICAgICAgIG1XaWR0aCwgbUhlaWdodCwgbUZvcm1hdCwgbVdpZHRoU3RyaWRlLCBtSGVpZ2h0U3RyaWRlKTsKK30KKworTGF5ZXJCdWZmZXI6Ok92ZXJsYXlTb3VyY2U6On5PdmVybGF5U291cmNlKCkKK3sKKyAgICBpZiAobU92ZXJsYXkgJiYgbU92ZXJsYXlEZXZpY2UpIHsKKyAgICAgICAgb3ZlcmxheV9jb250cm9sX2RldmljZV90KiBvdmVybGF5X2RldiA9IG1PdmVybGF5RGV2aWNlOworICAgICAgICBvdmVybGF5X2Rldi0+ZGVzdHJveU92ZXJsYXkob3ZlcmxheV9kZXYsIG1PdmVybGF5KTsKKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6Ok92ZXJsYXlTb3VyY2U6Om9uVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpCit7CisgICAgY29uc3QgTGF5ZXI6OlN0YXRlJiBmcm9udChtTGF5ZXIuZHJhd2luZ1N0YXRlKCkpOworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgdGVtcChtTGF5ZXIuY3VycmVudFN0YXRlKCkpOworICAgIGlmICh0ZW1wLnNlcXVlbmNlICE9IGZyb250LnNlcXVlbmNlKSB7CisgICAgICAgIG1WaXNpYmlsaXR5Q2hhbmdlZCA9IHRydWU7CisgICAgfQorfQorCit2b2lkIExheWVyQnVmZmVyOjpPdmVybGF5U291cmNlOjpvblZpc2liaWxpdHlSZXNvbHZlZCgKKyAgICAgICAgY29uc3QgVHJhbnNmb3JtJiBwbGFuZVRyYW5zZm9ybSkKK3sKKyAgICAvLyB0aGlzIGNvZGUtcGF0aCBtdXN0IGJlIGFzIHRpZ2h0IGFzIHBvc3NpYmxlLCBpdCdzIGNhbGxlZCBlYWNoIHRpbWUKKyAgICAvLyB0aGUgc2NyZWVuIGlzIGNvbXBvc2l0ZWQuCisgICAgaWYgKFVOTElLRUxZKG1PdmVybGF5ICE9IDApKSB7CisgICAgICAgIGlmIChtVmlzaWJpbGl0eUNoYW5nZWQpIHsKKyAgICAgICAgICAgIG1WaXNpYmlsaXR5Q2hhbmdlZCA9IGZhbHNlOworICAgICAgICAgICAgY29uc3QgUmVjdCYgYm91bmRzID0gbUxheWVyLmdldFRyYW5zZm9ybWVkQm91bmRzKCk7CisgICAgICAgICAgICBpbnQgeCA9IGJvdW5kcy5sZWZ0OworICAgICAgICAgICAgaW50IHkgPSBib3VuZHMudG9wOworICAgICAgICAgICAgaW50IHcgPSBib3VuZHMud2lkdGgoKTsKKyAgICAgICAgICAgIGludCBoID0gYm91bmRzLmhlaWdodCgpOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyB3ZSBuZWVkIGEgbG9jayBoZXJlIHRvIHByb3RlY3QgImRlc3Ryb3kiCisgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgICAgICAgICAgaWYgKG1PdmVybGF5KSB7CisgICAgICAgICAgICAgICAgb3ZlcmxheV9jb250cm9sX2RldmljZV90KiBvdmVybGF5X2RldiA9IG1PdmVybGF5RGV2aWNlOworICAgICAgICAgICAgICAgIG92ZXJsYXlfZGV2LT5zZXRQb3NpdGlvbihvdmVybGF5X2RldiwgbU92ZXJsYXksIHgseSx3LGgpOworICAgICAgICAgICAgICAgIG92ZXJsYXlfZGV2LT5zZXRQYXJhbWV0ZXIob3ZlcmxheV9kZXYsIG1PdmVybGF5LCAKKyAgICAgICAgICAgICAgICAgICAgICAgIE9WRVJMQVlfVFJBTlNGT1JNLCBtTGF5ZXIuZ2V0T3JpZW50YXRpb24oKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgTGF5ZXJCdWZmZXI6Ok92ZXJsYXlTb3VyY2U6OnNlcnZlckRlc3Ryb3koKSAKK3sKKyAgICBtTGF5ZXIuY2xlYXJTb3VyY2UoKTsKKyAgICBkZXN0cm95T3ZlcmxheSgpOworfQorCit2b2lkIExheWVyQnVmZmVyOjpPdmVybGF5U291cmNlOjpkZXN0cm95T3ZlcmxheSgpIAoreworICAgIC8vIHdlIG5lZWQgYSBsb2NrIGhlcmUgdG8gcHJvdGVjdCAib25WaXNpYmlsaXR5UmVzb2x2ZWQiCisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBpZiAobU92ZXJsYXkpIHsKKyAgICAgICAgb3ZlcmxheV9jb250cm9sX2RldmljZV90KiBvdmVybGF5X2RldiA9IG1PdmVybGF5RGV2aWNlOworICAgICAgICBvdmVybGF5X2Rldi0+ZGVzdHJveU92ZXJsYXkob3ZlcmxheV9kZXYsIG1PdmVybGF5KTsKKyAgICAgICAgbU92ZXJsYXkgPSAwOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJ1ZmZlci5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckJ1ZmZlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkYzc3ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyQnVmZmVyLmgKQEAgLTAsMCArMSwyMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfTEFZRVJfQlVGRkVSX0gKKyNkZWZpbmUgQU5EUk9JRF9MQVlFUl9CVUZGRVJfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisjaW5jbHVkZSA8cHJpdmF0ZS91aS9MYXllclN0YXRlLmg+CisjaW5jbHVkZSA8RUdML2VnbG5hdGl2ZXMuaD4KKworI2luY2x1ZGUgIkxheWVyQmFzZS5oIgorI2luY2x1ZGUgIkxheWVyQml0bWFwLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIE1lbW9yeURlYWxlcjsKK2NsYXNzIFJlZ2lvbjsKK2NsYXNzIE92ZXJsYXlSZWY7CisKK2NsYXNzIExheWVyQnVmZmVyIDogcHVibGljIExheWVyQmFzZUNsaWVudAoreworICAgIGNsYXNzIFNvdXJjZSA6IHB1YmxpYyBMaWdodFJlZkJhc2U8U291cmNlPiB7CisgICAgcHVibGljOgorICAgICAgICBTb3VyY2UoTGF5ZXJCdWZmZXImIGxheWVyKTsKKyAgICAgICAgdmlydHVhbCB+U291cmNlKCk7CisgICAgICAgIHZpcnR1YWwgdm9pZCBvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCB2b2lkIG9uVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpOworICAgICAgICB2aXJ0dWFsIHZvaWQgb25WaXNpYmlsaXR5UmVzb2x2ZWQoY29uc3QgVHJhbnNmb3JtJiBwbGFuZVRyYW5zZm9ybSk7CisgICAgICAgIHZpcnR1YWwgdm9pZCBwb3N0QnVmZmVyKHNzaXplX3Qgb2Zmc2V0KTsKKyAgICAgICAgdmlydHVhbCB2b2lkIHVucmVnaXN0ZXJCdWZmZXJzKCk7CisgICAgICAgIHZpcnR1YWwgYm9vbCB0cmFuc2Zvcm1lZCgpIGNvbnN0OworICAgIHByb3RlY3RlZDoKKyAgICAgICAgTGF5ZXJCdWZmZXImIG1MYXllcjsKKyAgICB9OworCisKK3B1YmxpYzoKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgdHlwZUluZm87CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHR5cGVJRDsKKyAgICB2aXJ0dWFsIGNoYXIgY29uc3QqIGdldFR5cGVJRCgpIGNvbnN0IHsgcmV0dXJuIHR5cGVJRDsgfQorICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VHlwZUluZm8oKSBjb25zdCB7IHJldHVybiB0eXBlSW5mbzsgfQorCisgICAgICAgICAgICBMYXllckJ1ZmZlcihTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICBDbGllbnQqIGNsaWVudCwgaW50MzJfdCBpKTsKKyAgICAgICAgdmlydHVhbCB+TGF5ZXJCdWZmZXIoKTsKKworICAgIHZpcnR1YWwgYm9vbCBuZWVkc0JsZW5kaW5nKCkgY29uc3Q7CisKKyAgICB2aXJ0dWFsIHNwPExheWVyQmFzZUNsaWVudDo6U3VyZmFjZT4gZ2V0U3VyZmFjZSgpIGNvbnN0OworICAgIHZpcnR1YWwgdm9pZCBvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdDsKKyAgICB2aXJ0dWFsIHVpbnQzMl90IGRvVHJhbnNhY3Rpb24odWludDMyX3QgZmxhZ3MpOworICAgIHZpcnR1YWwgdm9pZCB1bmxvY2tQYWdlRmxpcChjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtLCBSZWdpb24mIG91dERpcnR5UmVnaW9uKTsKKyAgICB2aXJ0dWFsIGJvb2wgdHJhbnNmb3JtZWQoKSBjb25zdDsKKworICAgIHN0YXR1c190IHJlZ2lzdGVyQnVmZmVycyhjb25zdCBJU3VyZmFjZTo6QnVmZmVySGVhcCYgYnVmZmVycyk7CisgICAgdm9pZCBwb3N0QnVmZmVyKHNzaXplX3Qgb2Zmc2V0KTsKKyAgICB2b2lkIHVucmVnaXN0ZXJCdWZmZXJzKCk7CisgICAgc3A8T3ZlcmxheVJlZj4gY3JlYXRlT3ZlcmxheSh1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGZvcm1hdCk7CisgICAgCisgICAgc3A8U291cmNlPiBnZXRTb3VyY2UoKSBjb25zdDsKKyAgICBzcDxTb3VyY2U+IGNsZWFyU291cmNlKCk7CisgICAgdm9pZCBzZXROZWVkc0JsZW5kaW5nKGJvb2wgYmxlbmRpbmcpOworICAgIGNvbnN0IFJlY3QmIGdldFRyYW5zZm9ybWVkQm91bmRzKCkgY29uc3QgeworICAgICAgICByZXR1cm4gbVRyYW5zZm9ybWVkQm91bmRzOworICAgIH0KKworcHJpdmF0ZToKKyAgICBzdHJ1Y3QgTmF0aXZlQnVmZmVyIHsKKyAgICAgICAgY29weWJpdF9pbWFnZV90ICAgaW1nOworICAgICAgICBjb3B5Yml0X3JlY3RfdCAgICBjcm9wOworICAgIH07CisKKyAgICBjbGFzcyBCdWZmZXIgOiBwdWJsaWMgTGlnaHRSZWZCYXNlPEJ1ZmZlcj4geworICAgIHB1YmxpYzoKKyAgICAgICAgQnVmZmVyKGNvbnN0IElTdXJmYWNlOjpCdWZmZXJIZWFwJiBidWZmZXJzLCBzc2l6ZV90IG9mZnNldCk7CisgICAgICAgIGlubGluZSBzdGF0dXNfdCBnZXRTdGF0dXMoKSBjb25zdCB7CisgICAgICAgICAgICByZXR1cm4gbUJ1ZmZlckhlYXAuaGVhcCE9MCA/IE5PX0VSUk9SIDogTk9fSU5JVDsKKyAgICAgICAgfQorICAgICAgICBpbmxpbmUgY29uc3QgTmF0aXZlQnVmZmVyJiBnZXRCdWZmZXIoKSBjb25zdCB7CisgICAgICAgICAgICByZXR1cm4gbU5hdGl2ZUJ1ZmZlcjsKKyAgICAgICAgfQorICAgIHByb3RlY3RlZDoKKyAgICAgICAgZnJpZW5kIGNsYXNzIExpZ2h0UmVmQmFzZTxCdWZmZXI+OworICAgICAgICBCdWZmZXImIG9wZXJhdG9yID0gKGNvbnN0IEJ1ZmZlciYgcmhzKTsKKyAgICAgICAgQnVmZmVyKGNvbnN0IEJ1ZmZlciYgcmhzKTsKKyAgICAgICAgfkJ1ZmZlcigpOworICAgIHByaXZhdGU6CisgICAgICAgIElTdXJmYWNlOjpCdWZmZXJIZWFwICAgIG1CdWZmZXJIZWFwOworICAgICAgICBOYXRpdmVCdWZmZXIgICAgICAgICAgICBtTmF0aXZlQnVmZmVyOworICAgIH07CisKKyAgICBjbGFzcyBCdWZmZXJTb3VyY2UgOiBwdWJsaWMgU291cmNlIHsKKyAgICBwdWJsaWM6CisgICAgICAgIEJ1ZmZlclNvdXJjZShMYXllckJ1ZmZlciYgbGF5ZXIsIGNvbnN0IElTdXJmYWNlOjpCdWZmZXJIZWFwJiBidWZmZXJzKTsKKyAgICAgICAgdmlydHVhbCB+QnVmZmVyU291cmNlKCk7CisKKyAgICAgICAgc3RhdHVzX3QgZ2V0U3RhdHVzKCkgY29uc3QgeyByZXR1cm4gbVN0YXR1czsgfQorICAgICAgICBzcDxCdWZmZXI+IGdldEJ1ZmZlcigpIGNvbnN0OworICAgICAgICB2b2lkIHNldEJ1ZmZlcihjb25zdCBzcDxCdWZmZXI+JiBidWZmZXIpOworCisgICAgICAgIHZpcnR1YWwgdm9pZCBvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdDsKKyAgICAgICAgdmlydHVhbCB2b2lkIHBvc3RCdWZmZXIoc3NpemVfdCBvZmZzZXQpOworICAgICAgICB2aXJ0dWFsIHZvaWQgdW5yZWdpc3RlckJ1ZmZlcnMoKTsKKyAgICAgICAgdmlydHVhbCBib29sIHRyYW5zZm9ybWVkKCkgY29uc3Q7CisgICAgcHJpdmF0ZToKKyAgICAgICAgbXV0YWJsZSBNdXRleCAgIG1Mb2NrOworICAgICAgICBzcDxCdWZmZXI+ICAgICAgbUJ1ZmZlcjsKKyAgICAgICAgc3RhdHVzX3QgICAgICAgIG1TdGF0dXM7CisgICAgICAgIElTdXJmYWNlOjpCdWZmZXJIZWFwIG1CdWZmZXJIZWFwOworICAgICAgICBzaXplX3QgICAgICAgICAgbUJ1ZmZlclNpemU7CisgICAgICAgIG11dGFibGUgc3A8TWVtb3J5RGVhbGVyPiBtVGVtcG9yYXJ5RGVhbGVyOworICAgICAgICBtdXRhYmxlIExheWVyQml0bWFwIG1UZW1wQml0bWFwOworICAgICAgICBtdXRhYmxlIEdMdWludCAgbVRleHR1cmVOYW1lOworICAgIH07CisgICAgCisgICAgY2xhc3MgT3ZlcmxheVNvdXJjZSA6IHB1YmxpYyBTb3VyY2UgeworICAgIHB1YmxpYzoKKyAgICAgICAgT3ZlcmxheVNvdXJjZShMYXllckJ1ZmZlciYgbGF5ZXIsCisgICAgICAgICAgICAgICAgc3A8T3ZlcmxheVJlZj4qIG92ZXJsYXlSZWYsIAorICAgICAgICAgICAgICAgIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIGludDMyX3QgZm9ybWF0KTsKKyAgICAgICAgdmlydHVhbCB+T3ZlcmxheVNvdXJjZSgpOworICAgICAgICB2aXJ0dWFsIHZvaWQgb25UcmFuc2FjdGlvbih1aW50MzJfdCBmbGFncyk7CisgICAgICAgIHZpcnR1YWwgdm9pZCBvblZpc2liaWxpdHlSZXNvbHZlZChjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtKTsKKyAgICBwcml2YXRlOgorICAgICAgICB2b2lkIHNlcnZlckRlc3Ryb3koKTsgCisgICAgICAgIHZvaWQgZGVzdHJveU92ZXJsYXkoKTsgCisgICAgICAgIGNsYXNzIE92ZXJsYXlDaGFubmVsIDogcHVibGljIEJuT3ZlcmxheSB7CisgICAgICAgICAgICBtdXRhYmxlIE11dGV4IG1Mb2NrOworICAgICAgICAgICAgc3A8T3ZlcmxheVNvdXJjZT4gbVNvdXJjZTsKKyAgICAgICAgICAgIHZpcnR1YWwgdm9pZCBkZXN0cm95KCkgeworICAgICAgICAgICAgICAgIHNwPE92ZXJsYXlTb3VyY2U+IHNvdXJjZTsKKyAgICAgICAgICAgICAgICB7IC8vIHNjb3BlIGZvciB0aGUgbG9jazsKKyAgICAgICAgICAgICAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgc291cmNlID0gbVNvdXJjZTsKKyAgICAgICAgICAgICAgICAgICAgbVNvdXJjZS5jbGVhcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc291cmNlICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgc291cmNlLT5zZXJ2ZXJEZXN0cm95KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICBwdWJsaWM6CisgICAgICAgICAgICBPdmVybGF5Q2hhbm5lbChjb25zdCBzcDxPdmVybGF5U291cmNlPiYgc291cmNlKQorICAgICAgICAgICAgICAgIDogbVNvdXJjZShzb3VyY2UpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgZnJpZW5kIGNsYXNzIE92ZXJsYXlDaGFubmVsOworICAgICAgICBib29sIG1WaXNpYmlsaXR5Q2hhbmdlZDsKKworICAgICAgICBvdmVybGF5X3QqIG1PdmVybGF5OyAgICAgICAgCisgICAgICAgIG92ZXJsYXlfaGFuZGxlX3QgbU92ZXJsYXlIYW5kbGU7CisgICAgICAgIG92ZXJsYXlfY29udHJvbF9kZXZpY2VfdCogbU92ZXJsYXlEZXZpY2U7CisgICAgICAgIHVpbnQzMl90IG1XaWR0aDsKKyAgICAgICAgdWludDMyX3QgbUhlaWdodDsKKyAgICAgICAgaW50MzJfdCBtRm9ybWF0OworICAgICAgICBpbnQzMl90IG1XaWR0aFN0cmlkZTsKKyAgICAgICAgaW50MzJfdCBtSGVpZ2h0U3RyaWRlOworICAgICAgICBtdXRhYmxlIE11dGV4IG1Mb2NrOworICAgIH07CisKKworICAgIGNsYXNzIFN1cmZhY2VCdWZmZXIgOiBwdWJsaWMgTGF5ZXJCYXNlQ2xpZW50OjpTdXJmYWNlCisgICAgeworICAgIHB1YmxpYzoKKyAgICAgICAgICAgICAgICBTdXJmYWNlQnVmZmVyKFN1cmZhY2VJRCBpZCwgTGF5ZXJCdWZmZXIqIG93bmVyKTsKKyAgICAgICAgdmlydHVhbCB+U3VyZmFjZUJ1ZmZlcigpOworICAgICAgICB2aXJ0dWFsIHN0YXR1c190IG9uVHJhbnNhY3QoCisgICAgICAgICAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKTsKKyAgICAgICAgdmlydHVhbCBzdGF0dXNfdCByZWdpc3RlckJ1ZmZlcnMoY29uc3QgSVN1cmZhY2U6OkJ1ZmZlckhlYXAmIGJ1ZmZlcnMpOworICAgICAgICB2aXJ0dWFsIHZvaWQgcG9zdEJ1ZmZlcihzc2l6ZV90IG9mZnNldCk7CisgICAgICAgIHZpcnR1YWwgdm9pZCB1bnJlZ2lzdGVyQnVmZmVycygpOworICAgICAgICB2aXJ0dWFsIHNwPE92ZXJsYXlSZWY+IGNyZWF0ZU92ZXJsYXkoCisgICAgICAgICAgICAgICAgdWludDMyX3QgdywgdWludDMyX3QgaCwgaW50MzJfdCBmb3JtYXQpOworICAgICAgIHZvaWQgZGlzb3duKCk7CisgICAgcHJpdmF0ZToKKyAgICAgICAgTGF5ZXJCdWZmZXIqIGdldE93bmVyKCkgY29uc3QgeworICAgICAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgICAgIHJldHVybiBtT3duZXI7CisgICAgICAgIH0KKyAgICAgICAgbXV0YWJsZSBNdXRleCAgIG1Mb2NrOworICAgICAgICBMYXllckJ1ZmZlciogICAgbU93bmVyOworICAgIH07CisKKyAgICBmcmllbmQgY2xhc3MgU3VyZmFjZUZsaW5nZXI7CisgICAgc3A8U3VyZmFjZUJ1ZmZlcj4gICBnZXRDbGllbnRTdXJmYWNlKCkgY29uc3Q7CisKKyAgICBtdXRhYmxlIE11dGV4ICAgbUxvY2s7CisgICAgc3A8U291cmNlPiAgICAgIG1Tb3VyY2U7CisKKyAgICBib29sICAgICAgICAgICAgbUludmFsaWRhdGU7CisgICAgYm9vbCAgICAgICAgICAgIG1OZWVkc0JsZW5kaW5nOworICAgIG11dGFibGUgd3A8U3VyZmFjZUJ1ZmZlcj4gbUNsaWVudFN1cmZhY2U7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfTEFZRVJfQlVGRkVSX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJEaW0uY3BwIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckRpbS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGMzNDdjYwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJEaW0uY3BwCkBAIC0wLDAgKzEsMTEzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlICJMYXllckRpbS5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiVlJhbUhlYXAuaCIKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCB1aW50MzJfdCBMYXllckRpbTo6dHlwZUluZm8gPSBMYXllckJhc2VDbGllbnQ6OnR5cGVJbmZvIHwgMHgxMDsKK2NvbnN0IGNoYXIqIGNvbnN0IExheWVyRGltOjp0eXBlSUQgPSAiTGF5ZXJEaW0iOworc3A8TWVtb3J5RGVhbGVyPiBMYXllckRpbTo6bURpbW1lckRlYWxlcjsKK0xheWVyQml0bWFwIExheWVyRGltOjptRGltbWVyQml0bWFwOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTGF5ZXJEaW06OkxheWVyRGltKFN1cmZhY2VGbGluZ2VyKiBmbGluZ2VyLCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgQ2xpZW50KiBjbGllbnQsIGludDMyX3QgaSkKKyAgICAgOiBMYXllckJhc2VDbGllbnQoZmxpbmdlciwgZGlzcGxheSwgY2xpZW50LCBpKQoreworfQorCit2b2lkIExheWVyRGltOjppbml0RGltbWVyKFN1cmZhY2VGbGluZ2VyKiBmbGluZ2VyLCB1aW50MzJfdCB3LCB1aW50MzJfdCBoKQoreworICAgIC8vIG11c3Qgb25seSBiZSBjYWxsZWQgb25jZS4KKyAgICBtRGltbWVyRGVhbGVyID0gZmxpbmdlci0+Z2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCkKKyAgICAgICAgICAgIC0+Y3JlYXRlSGVhcChJU3VyZmFjZUNvbXBvc2VyOjplSGFyZHdhcmUpOworICAgIGlmIChtRGltbWVyRGVhbGVyICE9IDApIHsKKyAgICAgICAgbURpbW1lckJpdG1hcC5pbml0KG1EaW1tZXJEZWFsZXIpOworICAgICAgICBtRGltbWVyQml0bWFwLnNldEJpdHModywgaCwgMSwgUElYRUxfRk9STUFUX1JHQl81NjUpOworICAgICAgICBtRGltbWVyQml0bWFwLmNsZWFyKCk7CisgICAgfQorfQorCitMYXllckRpbTo6fkxheWVyRGltKCkKK3sKK30KKwordm9pZCBMYXllckRpbTo6b25EcmF3KGNvbnN0IFJlZ2lvbiYgY2xpcCkgY29uc3QKK3sKKyAgICBjb25zdCBTdGF0ZSYgcyhkcmF3aW5nU3RhdGUoKSk7CisKKyAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKGNsaXApOworICAgIGlmIChzLmFscGhhPjAgJiYgaXRlcmF0b3IpIHsKKyAgICAgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworCisgICAgICAgIHN0YXR1c190IGVyciA9IE5PX0VSUk9SOworICAgICAgICBjb25zdCBpbnQgY2FuX3VzZV9jb3B5Yml0ID0gY2FuVXNlQ29weWJpdCgpOworICAgICAgICBpZiAoY2FuX3VzZV9jb3B5Yml0KSAgeworICAgICAgICAgICAgLy8gU3RvcFdhdGNoIHdhdGNoKCJjb3B5Yml0Iik7CisgICAgICAgICAgICBjb3B5Yml0X2ltYWdlX3QgZHN0OworICAgICAgICAgICAgaHcuZ2V0RGlzcGxheVN1cmZhY2UoJmRzdCk7CisgICAgICAgICAgICBjb25zdCBjb3B5Yml0X3JlY3RfdCYgZHJlY3QKKyAgICAgICAgICAgICAgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY29weWJpdF9yZWN0X3QmPihtVHJhbnNmb3JtZWRCb3VuZHMpOworCisgICAgICAgICAgICBjb3B5Yml0X2ltYWdlX3Qgc3JjOworICAgICAgICAgICAgbURpbW1lckJpdG1hcC5nZXRCaXRtYXBTdXJmYWNlKCZzcmMpOworICAgICAgICAgICAgY29uc3QgY29weWJpdF9yZWN0X3QmIHNyZWN0KGRyZWN0KTsKKworICAgICAgICAgICAgY29weWJpdF9kZXZpY2VfdCogY29weWJpdCA9IG1GbGluZ2VyLT5nZXRCbGl0RW5naW5lKCk7CisgICAgICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfVFJBTlNGT1JNLCAwKTsKKyAgICAgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9QTEFORV9BTFBIQSwgcy5hbHBoYSk7CisgICAgICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfRElUSEVSLCBDT1BZQklUX0VOQUJMRSk7CisgICAgICAgICAgICByZWdpb25faXRlcmF0b3IgaXQoY2xpcCk7CisgICAgICAgICAgICBlcnIgPSBjb3B5Yml0LT5zdHJldGNoKGNvcHliaXQsICZkc3QsICZzcmMsICZkcmVjdCwgJnNyZWN0LCAmaXQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFjYW5fdXNlX2NvcHliaXQgfHwgZXJyKSB7CisgICAgICAgICAgICBjb25zdCBHR0xmaXhlZCBhbHBoYSA9IChzLmFscGhhIDw8IDE2KS8yNTU7CisgICAgICAgICAgICBjb25zdCB1aW50MzJfdCBmYkhlaWdodCA9IGh3LmdldEhlaWdodCgpOworICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOworICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgICAgICAgICBnbEVuYWJsZShHTF9CTEVORCk7CisgICAgICAgICAgICBnbEJsZW5kRnVuYyhHTF9PTkUsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOworICAgICAgICAgICAgZ2xDb2xvcjR4KDAsIDAsIDAsIGFscGhhKTsKKyAgICAgICAgICAgIGdsVmVydGV4UG9pbnRlcigyLCBHTF9GSVhFRCwgMCwgbVZlcnRpY2VzKTsKKyAgICAgICAgICAgIFJlY3QgcjsKKyAgICAgICAgICAgIHdoaWxlIChpdGVyYXRvci5pdGVyYXRlKCZyKSkgeworICAgICAgICAgICAgICAgIGNvbnN0IEdMaW50IHN5ID0gZmJIZWlnaHQgLSAoci50b3AgKyByLmhlaWdodCgpKTsKKyAgICAgICAgICAgICAgICBnbFNjaXNzb3Ioci5sZWZ0LCBzeSwgci53aWR0aCgpLCByLmhlaWdodCgpKTsKKyAgICAgICAgICAgICAgICBnbERyYXdBcnJheXMoR0xfVFJJQU5HTEVfRkFOLCAwLCA0KTsgCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckRpbS5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllckRpbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlMzdhNDcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyRGltLmgKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9MQVlFUl9ESU1fSAorI2RlZmluZSBBTkRST0lEX0xBWUVSX0RJTV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgIkxheWVyQmFzZS5oIgorI2luY2x1ZGUgIkxheWVyQml0bWFwLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExheWVyRGltIDogcHVibGljIExheWVyQmFzZUNsaWVudAoreworcHVibGljOiAgICAKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgdHlwZUluZm87CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHR5cGVJRDsKKyAgICB2aXJ0dWFsIGNoYXIgY29uc3QqIGdldFR5cGVJRCgpIGNvbnN0IHsgcmV0dXJuIHR5cGVJRDsgfQorICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VHlwZUluZm8oKSBjb25zdCB7IHJldHVybiB0eXBlSW5mbzsgfQorICAgIAorICAgICAgICAgICAgICAgIExheWVyRGltKFN1cmZhY2VGbGluZ2VyKiBmbGluZ2VyLCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgICAgICAgICAgICAgICAgIENsaWVudCogY2xpZW50LCBpbnQzMl90IGkpOworICAgICAgICB2aXJ0dWFsIH5MYXllckRpbSgpOworCisgICAgdmlydHVhbCB2b2lkIG9uRHJhdyhjb25zdCBSZWdpb24mIGNsaXApIGNvbnN0OworICAgIHZpcnR1YWwgYm9vbCBuZWVkc0JsZW5kaW5nKCkgY29uc3QgIHsgcmV0dXJuIHRydWU7IH0KKyAgICB2aXJ0dWFsIGJvb2wgaXNTZWN1cmUoKSBjb25zdCAgICAgICB7IHJldHVybiBmYWxzZTsgfQorCisgICAgc3RhdGljIHZvaWQgaW5pdERpbW1lcihTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgdWludDMyX3QgdywgdWludDMyX3QgaCk7CisKK3ByaXZhdGU6CisgICAgc3RhdGljIHNwPE1lbW9yeURlYWxlcj4gbURpbW1lckRlYWxlcjsKKyAgICBzdGF0aWMgTGF5ZXJCaXRtYXAgbURpbW1lckJpdG1hcDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9MQVlFUl9ESU1fSApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllck9yaWVudGF0aW9uQW5pbS5jcHAgYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyT3JpZW50YXRpb25BbmltLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjcyZDdjCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9MYXllck9yaWVudGF0aW9uQW5pbS5jcHAKQEAgLTAsMCArMSwyODcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN1cmZhY2VGbGluZ2VyIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPGNvcmUvU2tCaXRtYXAuaD4KKworI2luY2x1ZGUgPHVpL0VHTERpc3BsYXlTdXJmYWNlLmg+CisKKyNpbmNsdWRlICJMYXllckJhc2UuaCIKKyNpbmNsdWRlICJMYXllck9yaWVudGF0aW9uQW5pbS5oIgorI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisjaW5jbHVkZSAiRGlzcGxheUhhcmR3YXJlL0Rpc3BsYXlIYXJkd2FyZS5oIgorI2luY2x1ZGUgIk9yaWVudGF0aW9uQW5pbWF0aW9uLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCB1aW50MzJfdCBMYXllck9yaWVudGF0aW9uQW5pbTo6dHlwZUluZm8gPSBMYXllckJhc2U6OnR5cGVJbmZvIHwgMHg4MDsKK2NvbnN0IGNoYXIqIGNvbnN0IExheWVyT3JpZW50YXRpb25BbmltOjp0eXBlSUQgPSAiTGF5ZXJPcmllbnRhdGlvbkFuaW0iOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTGF5ZXJPcmllbnRhdGlvbkFuaW06OkxheWVyT3JpZW50YXRpb25BbmltKAorICAgICAgICBTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksIAorICAgICAgICBPcmllbnRhdGlvbkFuaW1hdGlvbiogYW5pbSwgCisgICAgICAgIGNvbnN0IExheWVyQml0bWFwJiBiaXRtYXAsCisgICAgICAgIGNvbnN0IExheWVyQml0bWFwJiBiaXRtYXBJbikKKyAgICA6IExheWVyQmFzZShmbGluZ2VyLCBkaXNwbGF5KSwgbUFuaW0oYW5pbSksIAorICAgICAgbUJpdG1hcChiaXRtYXApLCBtQml0bWFwSW4oYml0bWFwSW4pLCAKKyAgICAgIG1UZXh0dXJlTmFtZSgtMSksIG1UZXh0dXJlTmFtZUluKC0xKQoreworICAgIG1TdGFydFRpbWUgPSBzeXN0ZW1UaW1lKCk7CisgICAgbUZpbmlzaFRpbWUgPSAwOworICAgIG1PcmllbnRhdGlvbkNvbXBsZXRlZCA9IGZhbHNlOworICAgIG1GaXJzdFJlZHJhdyA9IGZhbHNlOworICAgIG1MYXN0Tm9ybWFsaXplZFRpbWUgPSAwOworICAgIG1MYXN0U2NhbGUgPSAwOworICAgIG1OZWVkc0JsZW5kaW5nID0gZmFsc2U7Cit9CisKK0xheWVyT3JpZW50YXRpb25BbmltOjp+TGF5ZXJPcmllbnRhdGlvbkFuaW0oKQoreworICAgIGlmIChtVGV4dHVyZU5hbWUgIT0gLTFVKSB7CisgICAgICAgIExheWVyQmFzZTo6ZGVsZXRlZFRleHR1cmVzLmFkZChtVGV4dHVyZU5hbWUpOworICAgIH0KKyAgICBpZiAobVRleHR1cmVOYW1lSW4gIT0gLTFVKSB7CisgICAgICAgIExheWVyQmFzZTo6ZGVsZXRlZFRleHR1cmVzLmFkZChtVGV4dHVyZU5hbWVJbik7CisgICAgfQorfQorCitib29sIExheWVyT3JpZW50YXRpb25BbmltOjpuZWVkc0JsZW5kaW5nKCkgY29uc3QgCit7CisgICAgcmV0dXJuIG1OZWVkc0JsZW5kaW5nOyAKK30KKworUG9pbnQgTGF5ZXJPcmllbnRhdGlvbkFuaW06OmdldFBoeXNpY2FsU2l6ZSgpIGNvbnN0Cit7CisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiBwbGFuZShncmFwaGljUGxhbmUoMCkpOworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcocGxhbmUuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIHJldHVybiBQb2ludChody5nZXRXaWR0aCgpLCBody5nZXRIZWlnaHQoKSk7Cit9CisKK3ZvaWQgTGF5ZXJPcmllbnRhdGlvbkFuaW06OnZhbGlkYXRlVmlzaWJpbGl0eShjb25zdCBUcmFuc2Zvcm0mKQoreworICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgcyhkcmF3aW5nU3RhdGUoKSk7CisgICAgY29uc3QgVHJhbnNmb3JtIHRyKHMudHJhbnNmb3JtKTsKKyAgICBjb25zdCBQb2ludCBzaXplKGdldFBoeXNpY2FsU2l6ZSgpKTsKKyAgICB1aW50MzJfdCB3ID0gc2l6ZS54OworICAgIHVpbnQzMl90IGggPSBzaXplLnk7CisgICAgbVRyYW5zZm9ybWVkQm91bmRzID0gdHIubWFrZUJvdW5kcyh3LCBoKTsKKyAgICBtTGVmdCA9IHRyLnR4KCk7CisgICAgbVRvcCAgPSB0ci50eSgpOworICAgIHRyYW5zcGFyZW50UmVnaW9uU2NyZWVuLmNsZWFyKCk7CisgICAgbVRyYW5zZm9ybWVkID0gdHJ1ZTsKKyAgICBtQ2FuVXNlQ29weUJpdCA9IGZhbHNlOworICAgIGNvcHliaXRfZGV2aWNlX3QqIGNvcHliaXQgPSBtRmxpbmdlci0+Z2V0QmxpdEVuZ2luZSgpOworICAgIGlmIChjb3B5Yml0KSB7IAorICAgICAgICBtQ2FuVXNlQ29weUJpdCA9IHRydWU7CisgICAgfQorfQorCit2b2lkIExheWVyT3JpZW50YXRpb25BbmltOjpvbk9yaWVudGF0aW9uQ29tcGxldGVkKCkKK3sKKyAgICBtRmluaXNoVGltZSA9IHN5c3RlbVRpbWUoKTsKKyAgICBtT3JpZW50YXRpb25Db21wbGV0ZWQgPSB0cnVlOworICAgIG1GaXJzdFJlZHJhdyA9IHRydWU7CisgICAgbU5lZWRzQmxlbmRpbmcgPSB0cnVlOworICAgIG1GbGluZ2VyLT5pbnZhbGlkYXRlTGF5ZXJWaXNpYmlsaXR5KHRoaXMpOworfQorCit2b2lkIExheWVyT3JpZW50YXRpb25BbmltOjpvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdAoreworICAgIC8vIEFuaW1hdGlvbi4uLgorICAgIGNvbnN0IGZsb2F0IE1JTl9TQ0FMRSA9IDAuNWY7CisgICAgY29uc3QgZmxvYXQgRFVSQVRJT04gPSBtczJucygyMDApOworICAgIGNvbnN0IGZsb2F0IEJPVU5DRVNfUEVSX1NFQ09ORCA9IDEuNjE4ZjsKKyAgICBjb25zdCBmbG9hdCBCT1VOQ0VTX0FNUExJVFVERSA9IDEuMGYvMzIuMGY7CisKKyAgICBjb25zdCBuc2Vjc190IG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICBmbG9hdCBzY2FsZSwgYWxwaGE7CisgICAgCisgICAgaWYgKG1PcmllbnRhdGlvbkNvbXBsZXRlZCkgeworICAgICAgICBpZiAobUZpcnN0UmVkcmF3KSB7CisgICAgICAgICAgICBtRmlyc3RSZWRyYXcgPSBmYWxzZTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gbWFrZSBhIGNvcHkgb2Ygd2hhdCdzIG9uIHNjcmVlbgorICAgICAgICAgICAgY29weWJpdF9pbWFnZV90IGltYWdlOworICAgICAgICAgICAgbUJpdG1hcEluLmdldEJpdG1hcFN1cmZhY2UoJmltYWdlKTsKKyAgICAgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICAgICAgICAgIGh3LmNvcHlCYWNrVG9JbWFnZShpbWFnZSk7CisKKyAgICAgICAgICAgIC8vIGFuZCBlcmFzZSB0aGUgc2NyZWVuIGZvciB0aGlzIHJvdW5kCisgICAgICAgICAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKKyAgICAgICAgICAgIGdsQ2xlYXJDb2xvcigwLDAsMCwwKTsKKyAgICAgICAgICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIEZJWE1FOiBjb2RlIGJlbG93IGlzIGdyb3NzCisgICAgICAgICAgICBtTmVlZHNCbGVuZGluZyA9IGZhbHNlOworICAgICAgICAgICAgTGF5ZXJPcmllbnRhdGlvbkFuaW0qIHNlbGYoY29uc3RfY2FzdDxMYXllck9yaWVudGF0aW9uQW5pbSo+KHRoaXMpKTsKKyAgICAgICAgICAgIG1GbGluZ2VyLT5pbnZhbGlkYXRlTGF5ZXJWaXNpYmlsaXR5KHNlbGYpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbWFrZSBzdXJlIHBpY2stdXAgd2hlcmUgd2UgbGVmdCBvZmYKKyAgICAgICAgY29uc3QgZmxvYXQgZHVyYXRpb24gPSBEVVJBVElPTiAqIG1MYXN0Tm9ybWFsaXplZFRpbWU7CisgICAgICAgIGNvbnN0IGZsb2F0IG5vcm1hbGl6ZWRUaW1lID0gKGZsb2F0KG5vdyAtIG1GaW5pc2hUaW1lKSAvIGR1cmF0aW9uKTsKKyAgICAgICAgaWYgKG5vcm1hbGl6ZWRUaW1lIDw9IDEuMGYpIHsKKyAgICAgICAgICAgIGNvbnN0IGZsb2F0IHNxdWFyZWRUaW1lID0gbm9ybWFsaXplZFRpbWUqbm9ybWFsaXplZFRpbWU7CisgICAgICAgICAgICBzY2FsZSA9ICgxLjBmIC0gbUxhc3RTY2FsZSkqc3F1YXJlZFRpbWUgKyBtTGFzdFNjYWxlOworICAgICAgICAgICAgYWxwaGEgPSAoMS4wZiAtIG5vcm1hbGl6ZWRUaW1lKTsKKyAgICAgICAgICAgIGFscGhhICo9IGFscGhhOworICAgICAgICAgICAgYWxwaGEgKj0gYWxwaGE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtQW5pbS0+b25BbmltYXRpb25GaW5pc2hlZCgpOworICAgICAgICAgICAgc2NhbGUgPSAxLjBmOworICAgICAgICAgICAgYWxwaGEgPSAwLjBmOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgZmxvYXQgbm9ybWFsaXplZFRpbWUgPSBmbG9hdChub3cgLSBtU3RhcnRUaW1lKSAvIERVUkFUSU9OOworICAgICAgICBpZiAobm9ybWFsaXplZFRpbWUgPD0gMS4wZikgeworICAgICAgICAgICAgbUxhc3ROb3JtYWxpemVkVGltZSA9IG5vcm1hbGl6ZWRUaW1lOworICAgICAgICAgICAgY29uc3QgZmxvYXQgc3F1YXJlZFRpbWUgPSBub3JtYWxpemVkVGltZSpub3JtYWxpemVkVGltZTsKKyAgICAgICAgICAgIHNjYWxlID0gKE1JTl9TQ0FMRS0xLjBmKSpzcXVhcmVkVGltZSArIDEuMGY7CisgICAgICAgICAgICBhbHBoYSA9IDEuMGY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtTGFzdE5vcm1hbGl6ZWRUaW1lID0gMS4wZjsKKyAgICAgICAgICAgIGNvbnN0IGZsb2F0IHRvX3NlY29uZHMgPSBEVVJBVElPTiAvIHNlY29uZHMoMSk7CisgICAgICAgICAgICBjb25zdCBmbG9hdCBwaGkgPSBCT1VOQ0VTX1BFUl9TRUNPTkQgKiAKKyAgICAgICAgICAgICAgICAgICAgKCgobm9ybWFsaXplZFRpbWUgLSAxLjBmKSAqIHRvX3NlY29uZHMpKk1fUEkqMik7CisgICAgICAgICAgICBzY2FsZSA9IE1JTl9TQ0FMRSArIEJPVU5DRVNfQU1QTElUVURFICogKDEuMGYgLSBjb3NmKHBoaSkpOworICAgICAgICAgICAgYWxwaGEgPSAxLjBmOworICAgICAgICB9CisgICAgICAgIG1MYXN0U2NhbGUgPSBzY2FsZTsKKyAgICB9CisgICAgZHJhd1NjYWxlZChzY2FsZSwgYWxwaGEpOworfQorCit2b2lkIExheWVyT3JpZW50YXRpb25BbmltOjpkcmF3U2NhbGVkKGZsb2F0IGYsIGZsb2F0IGFscGhhKSBjb25zdAoreworICAgIGNvcHliaXRfaW1hZ2VfdCBkc3Q7CisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiBwbGFuZShncmFwaGljUGxhbmUoMCkpOworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcocGxhbmUuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIGh3LmdldERpc3BsYXlTdXJmYWNlKCZkc3QpOworCisgICAgLy8gY2xlYXIgc2NyZWVuCisgICAgLy8gVE9ETzogd2l0aCB1cGRhdGUgb24gZGVtYW5kLCB3ZSBtYXkgYmUgYWJsZSAKKyAgICAvLyB0byBub3QgZXJhc2UgdGhlIHNjcmVlbiBhdCBhbGwgZHVyaW5nIHRoZSBhbmltYXRpb24gCisgICAgaWYgKCFtT3JpZW50YXRpb25Db21wbGV0ZWQpIHsKKyAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKKyAgICAgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOworICAgICAgICBnbENsZWFyQ29sb3IoMCwwLDAsMCk7CisgICAgICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisgICAgfQorICAgIAorICAgIGNvbnN0IGludCB3ID0gZHN0LncqZjsgCisgICAgY29uc3QgaW50IGggPSBkc3QuaCpmOyAKKyAgICBjb25zdCBpbnQgeGMgPSB1aW50MzJfdChkc3Qudy13KS8yOworICAgIGNvbnN0IGludCB5YyA9IHVpbnQzMl90KGRzdC5oLWgpLzI7CisgICAgY29uc3QgY29weWJpdF9yZWN0X3QgZHJlY3QgPSB7IHhjLCB5YywgeGMrdywgeWMraCB9OyAKKworICAgIGNvcHliaXRfaW1hZ2VfdCBzcmM7CisgICAgbUJpdG1hcC5nZXRCaXRtYXBTdXJmYWNlKCZzcmMpOworICAgIGNvbnN0IGNvcHliaXRfcmVjdF90IHNyZWN0ID0geyAwLCAwLCBzcmMudywgc3JjLmggfTsKKworICAgIGludCBlcnIgPSBOT19FUlJPUjsKKyAgICBjb25zdCBpbnQgY2FuX3VzZV9jb3B5Yml0ID0gY2FuVXNlQ29weWJpdCgpOworICAgIGlmIChjYW5fdXNlX2NvcHliaXQpICB7CisgICAgICAgIGNvcHliaXRfZGV2aWNlX3QqIGNvcHliaXQgPSBtRmxpbmdlci0+Z2V0QmxpdEVuZ2luZSgpOworICAgICAgICBjb3B5Yml0LT5zZXRfcGFyYW1ldGVyKGNvcHliaXQsIENPUFlCSVRfVFJBTlNGT1JNLCAwKTsKKyAgICAgICAgY29weWJpdC0+c2V0X3BhcmFtZXRlcihjb3B5Yml0LCBDT1BZQklUX0RJVEhFUiwgQ09QWUJJVF9FTkFCTEUpOworCisgICAgICAgIGlmIChhbHBoYSA8IDEuMGYpIHsKKyAgICAgICAgICAgIGNvcHliaXRfaW1hZ2VfdCBzcmNJbjsKKyAgICAgICAgICAgIG1CaXRtYXBJbi5nZXRCaXRtYXBTdXJmYWNlKCZzcmNJbik7CisgICAgICAgICAgICByZWdpb25faXRlcmF0b3IgaXQoUmVnaW9uKFJlY3QoIGRyZWN0LmwsIGRyZWN0LnQsIGRyZWN0LnIsIGRyZWN0LmIgKSkpOworICAgICAgICAgICAgY29weWJpdC0+c2V0X3BhcmFtZXRlcihjb3B5Yml0LCBDT1BZQklUX1BMQU5FX0FMUEhBLCAweEZGKTsKKyAgICAgICAgICAgIGVyciA9IGNvcHliaXQtPnN0cmV0Y2goY29weWJpdCwgJmRzdCwgJnNyY0luLCAmZHJlY3QsICZzcmVjdCwgJml0KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghZXJyICYmIGFscGhhID4gMC4wZikgeworICAgICAgICAgICAgcmVnaW9uX2l0ZXJhdG9yIGl0KFJlZ2lvbihSZWN0KCBkcmVjdC5sLCBkcmVjdC50LCBkcmVjdC5yLCBkcmVjdC5iICkpKTsKKyAgICAgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9QTEFORV9BTFBIQSwgaW50KGFscGhhKjI1NSkpOworICAgICAgICAgICAgZXJyID0gY29weWJpdC0+c3RyZXRjaChjb3B5Yml0LCAmZHN0LCAmc3JjLCAmZHJlY3QsICZzcmVjdCwgJml0KTsKKyAgICAgICAgfQorICAgICAgICBMT0dFX0lGKGVyciAhPSBOT19FUlJPUiwgImNvcHliaXQgZmFpbGVkICglcykiLCBzdHJlcnJvcihlcnIpKTsKKyAgICB9CisgICAgaWYgKCFjYW5fdXNlX2NvcHliaXQgfHwgZXJyKSB7ICAgCisgICAgICAgIEdHTFN1cmZhY2UgdDsKKyAgICAgICAgdC52ZXJzaW9uID0gc2l6ZW9mKEdHTFN1cmZhY2UpOworICAgICAgICB0LndpZHRoICA9IHNyYy53OworICAgICAgICB0LmhlaWdodCA9IHNyYy5oOworICAgICAgICB0LnN0cmlkZSA9IHNyYy53OworICAgICAgICB0LnZzdHJpZGU9IHNyYy5oOworICAgICAgICB0LmZvcm1hdCA9IHNyYy5mb3JtYXQ7CisgICAgICAgIHQuZGF0YSA9IChHR0x1Ynl0ZSopKGludHB0cl90KHNyYy5iYXNlKSArIHNyYy5vZmZzZXQpOworCisgICAgICAgIFRyYW5zZm9ybSB0cjsKKyAgICAgICAgdHIuc2V0KGYsMCwwLGYpOworICAgICAgICB0ci5zZXQoeGMsIHljKTsKKyAgICAgICAgCisgICAgICAgIC8vIEZJWE1FOiB3ZSBzaG91bGQgbm90IGFjY2VzcyBtVmVydGljZXMgYW5kIG1EcmF3aW5nU3RhdGUgbGlrZSB0aGF0LAorICAgICAgICAvLyBidXQgc2luY2Ugd2UgY29udHJvbCB0aGUgYW5pbWF0aW9uLCB3ZSBrbm93IGl0J3MgZ29pbmcgdG8gd29yayBva2F5LgorICAgICAgICAvLyBldmVudHVhbGx5IHdlJ2QgbmVlZCBhIG1vcmUgZm9ybWFsIHdheSBvZiBkb2luZyB0aGluZ3MgbGlrZSB0aGlzLgorICAgICAgICBMYXllck9yaWVudGF0aW9uQW5pbSYgc2VsZihjb25zdF9jYXN0PExheWVyT3JpZW50YXRpb25BbmltJj4oKnRoaXMpKTsKKyAgICAgICAgdHIudHJhbnNmb3JtKHNlbGYubVZlcnRpY2VzWzBdLCAwLCAwKTsKKyAgICAgICAgdHIudHJhbnNmb3JtKHNlbGYubVZlcnRpY2VzWzFdLCAwLCBzcmMuaCk7CisgICAgICAgIHRyLnRyYW5zZm9ybShzZWxmLm1WZXJ0aWNlc1syXSwgc3JjLncsIHNyYy5oKTsKKyAgICAgICAgdHIudHJhbnNmb3JtKHNlbGYubVZlcnRpY2VzWzNdLCBzcmMudywgMCk7CisgICAgICAgIGlmICghKG1GbGFncyAmIERpc3BsYXlIYXJkd2FyZTo6U0xPV19DT05GSUcpKSB7CisgICAgICAgICAgICAvLyBUb28gc2xvdyB0byBkbyB0aGlzIGluIHNvZnR3YXJlCisgICAgICAgICAgICBzZWxmLm1EcmF3aW5nU3RhdGUuZmxhZ3MgfD0gSVN1cmZhY2VDb21wb3Nlcjo6ZUxheWVyRmlsdGVyOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGFscGhhIDwgMS4wZikgeworICAgICAgICAgICAgY29weWJpdF9pbWFnZV90IHNyYzsKKyAgICAgICAgICAgIG1CaXRtYXBJbi5nZXRCaXRtYXBTdXJmYWNlKCZzcmMpOworICAgICAgICAgICAgdC5kYXRhID0gKEdHTHVieXRlKikoaW50cHRyX3Qoc3JjLmJhc2UpICsgc3JjLm9mZnNldCk7CisgICAgICAgICAgICBpZiAoVU5MSUtFTFkobVRleHR1cmVOYW1lSW4gPT0gLTFMVSkpIHsKKyAgICAgICAgICAgICAgICBtVGV4dHVyZU5hbWVJbiA9IGNyZWF0ZVRleHR1cmUoKTsKKyAgICAgICAgICAgICAgICBHTHVpbnQgdz0wLCBoPTA7CisgICAgICAgICAgICAgICAgY29uc3QgUmVnaW9uIGRpcnR5KFJlY3QodC53aWR0aCwgdC5oZWlnaHQpKTsKKyAgICAgICAgICAgICAgICBsb2FkVGV4dHVyZShkaXJ0eSwgbVRleHR1cmVOYW1lSW4sIHQsIHcsIGgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2VsZi5tRHJhd2luZ1N0YXRlLmFscGhhID0gMjU1OworICAgICAgICAgICAgY29uc3QgUmVnaW9uIGNsaXAoUmVjdCggZHJlY3QubCwgZHJlY3QudCwgZHJlY3QuciwgZHJlY3QuYiApKTsKKyAgICAgICAgICAgIGRyYXdXaXRoT3BlbkdMKGNsaXAsIG1UZXh0dXJlTmFtZSwgdCk7CisgICAgICAgIH0KKworICAgICAgICB0LmRhdGEgPSAoR0dMdWJ5dGUqKShpbnRwdHJfdChzcmMuYmFzZSkgKyBzcmMub2Zmc2V0KTsKKyAgICAgICAgaWYgKFVOTElLRUxZKG1UZXh0dXJlTmFtZSA9PSAtMUxVKSkgeworICAgICAgICAgICAgbVRleHR1cmVOYW1lID0gY3JlYXRlVGV4dHVyZSgpOworICAgICAgICAgICAgR0x1aW50IHc9MCwgaD0wOworICAgICAgICAgICAgY29uc3QgUmVnaW9uIGRpcnR5KFJlY3QodC53aWR0aCwgdC5oZWlnaHQpKTsKKyAgICAgICAgICAgIGxvYWRUZXh0dXJlKGRpcnR5LCBtVGV4dHVyZU5hbWUsIHQsIHcsIGgpOworICAgICAgICB9CisgICAgICAgIHNlbGYubURyYXdpbmdTdGF0ZS5hbHBoYSA9IGludChhbHBoYSoyNTUpOworICAgICAgICBjb25zdCBSZWdpb24gY2xpcChSZWN0KCBkcmVjdC5sLCBkcmVjdC50LCBkcmVjdC5yLCBkcmVjdC5iICkpOworICAgICAgICBkcmF3V2l0aE9wZW5HTChjbGlwLCBtVGV4dHVyZU5hbWUsIHQpOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyT3JpZW50YXRpb25BbmltLmggYi9saWJzL3N1cmZhY2VmbGluZ2VyL0xheWVyT3JpZW50YXRpb25BbmltLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzM2NzY4NQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTGF5ZXJPcmllbnRhdGlvbkFuaW0uaApAQCAtMCwwICsxLDc1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0xBWUVSX09SSUVOVEFUSU9OX0FOSU1fSAorI2RlZmluZSBBTkRST0lEX0xBWUVSX09SSUVOVEFUSU9OX0FOSU1fSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorCisjaW5jbHVkZSAiTGF5ZXJCYXNlLmgiCisjaW5jbHVkZSAiTGF5ZXJCaXRtYXAuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2NsYXNzIE9yaWVudGF0aW9uQW5pbWF0aW9uOworCitjbGFzcyBMYXllck9yaWVudGF0aW9uQW5pbSA6IHB1YmxpYyBMYXllckJhc2UKK3sKK3B1YmxpYzogICAgCisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IHR5cGVJbmZvOworICAgIHN0YXRpYyBjb25zdCBjaGFyKiBjb25zdCB0eXBlSUQ7CisgICAgdmlydHVhbCBjaGFyIGNvbnN0KiBnZXRUeXBlSUQoKSBjb25zdCB7IHJldHVybiB0eXBlSUQ7IH0KKyAgICB2aXJ0dWFsIHVpbnQzMl90IGdldFR5cGVJbmZvKCkgY29uc3QgeyByZXR1cm4gdHlwZUluZm87IH0KKyAgICAKKyAgICAgICAgICAgICAgICBMYXllck9yaWVudGF0aW9uQW5pbShTdXJmYWNlRmxpbmdlciogZmxpbmdlciwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICBPcmllbnRhdGlvbkFuaW1hdGlvbiogYW5pbSwgCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMYXllckJpdG1hcCYgem9vbU91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExheWVyQml0bWFwJiB6b29tSW4pOworICAgICAgICB2aXJ0dWFsIH5MYXllck9yaWVudGF0aW9uQW5pbSgpOworCisgICAgICAgICAgICB2b2lkIG9uT3JpZW50YXRpb25Db21wbGV0ZWQoKTsKKworICAgIHZpcnR1YWwgdm9pZCBvbkRyYXcoY29uc3QgUmVnaW9uJiBjbGlwKSBjb25zdDsKKyAgICB2aXJ0dWFsIFBvaW50IGdldFBoeXNpY2FsU2l6ZSgpIGNvbnN0OworICAgIHZpcnR1YWwgdm9pZCB2YWxpZGF0ZVZpc2liaWxpdHkoY29uc3QgVHJhbnNmb3JtJiBnbG9iYWxUcmFuc2Zvcm0pOworICAgIHZpcnR1YWwgYm9vbCBuZWVkc0JsZW5kaW5nKCkgY29uc3Q7CisgICAgdmlydHVhbCBib29sIGlzU2VjdXJlKCkgY29uc3QgICAgICAgeyByZXR1cm4gZmFsc2U7IH0KK3ByaXZhdGU6CisgICAgdm9pZCBkcmF3U2NhbGVkKGZsb2F0IHNjYWxlLCBmbG9hdCBhbHBoYSkgY29uc3Q7CisKKyAgICBPcmllbnRhdGlvbkFuaW1hdGlvbiogbUFuaW07CisgICAgTGF5ZXJCaXRtYXAgbUJpdG1hcDsKKyAgICBMYXllckJpdG1hcCBtQml0bWFwSW47CisgICAgbnNlY3NfdCBtU3RhcnRUaW1lOworICAgIG5zZWNzX3QgbUZpbmlzaFRpbWU7CisgICAgYm9vbCBtT3JpZW50YXRpb25Db21wbGV0ZWQ7CisgICAgbXV0YWJsZSBib29sIG1GaXJzdFJlZHJhdzsKKyAgICBtdXRhYmxlIGZsb2F0IG1MYXN0Tm9ybWFsaXplZFRpbWU7CisgICAgbXV0YWJsZSBmbG9hdCBtTGFzdFNjYWxlOworICAgIG11dGFibGUgR0x1aW50ICBtVGV4dHVyZU5hbWU7CisgICAgbXV0YWJsZSBHTHVpbnQgIG1UZXh0dXJlTmFtZUluOworICAgIG11dGFibGUgYm9vbCBtTmVlZHNCbGVuZGluZzsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9MQVlFUl9PUklFTlRBVElPTl9BTklNX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMiBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL09yaWVudGF0aW9uQW5pbWF0aW9uLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvT3JpZW50YXRpb25BbmltYXRpb24uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2ZjEzMjYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL09yaWVudGF0aW9uQW5pbWF0aW9uLmNwcApAQCAtMCwwICsxLDE1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZUZsaW5nZXIiCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxsaW1pdHMuaD4KKworI2luY2x1ZGUgIkxheWVyT3JpZW50YXRpb25BbmltLmgiCisjaW5jbHVkZSAiT3JpZW50YXRpb25BbmltYXRpb24uaCIKKyNpbmNsdWRlICJTdXJmYWNlRmxpbmdlci5oIgorI2luY2x1ZGUgIlZSYW1IZWFwLmgiCisKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK09yaWVudGF0aW9uQW5pbWF0aW9uOjpPcmllbnRhdGlvbkFuaW1hdGlvbihjb25zdCBzcDxTdXJmYWNlRmxpbmdlcj4mIGZsaW5nZXIpCisgICAgOiBtRmxpbmdlcihmbGluZ2VyKSwgbUxheWVyT3JpZW50YXRpb25BbmltKE5VTEwpLCBtU3RhdGUoRE9ORSkKK3sKKyAgICAvLyBhbGxvY2F0ZSBhIG1lbW9yeS1kZWFsZXIgZm9yIHRoaXMgdGhlIGZpcnN0IHRpbWUKKyAgICBtVGVtcG9yYXJ5RGVhbGVyID0gbUZsaW5nZXItPmdldFN1cmZhY2VIZWFwTWFuYWdlcigpLT5jcmVhdGVIZWFwKAorICAgICAgICAgICAgSVN1cmZhY2VDb21wb3Nlcjo6ZUhhcmR3YXJlKTsKK30KKworT3JpZW50YXRpb25BbmltYXRpb246On5PcmllbnRhdGlvbkFuaW1hdGlvbigpCit7Cit9CisKK3ZvaWQgT3JpZW50YXRpb25BbmltYXRpb246Om9uT3JpZW50YXRpb25DaGFuZ2VkKCkKK3sKKyAgICBpZiAobVN0YXRlID09IERPTkUpCisgICAgICAgIG1TdGF0ZSA9IFBSRVBBUkU7Cit9CisKK3ZvaWQgT3JpZW50YXRpb25BbmltYXRpb246Om9uQW5pbWF0aW9uRmluaXNoZWQoKQoreworICAgIGlmIChtU3RhdGUgIT0gRE9ORSkKKyAgICAgICAgbVN0YXRlID0gRklOSVNIOworfQorCitib29sIE9yaWVudGF0aW9uQW5pbWF0aW9uOjpydW5faW1wbCgpCit7CisgICAgYm9vbCBza2lwX2ZyYW1lOworICAgIHN3aXRjaCAobVN0YXRlKSB7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgIGNhc2UgRE9ORToKKyAgICAgICAgICAgIHNraXBfZnJhbWUgPSBkb25lKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQUkVQQVJFOgorICAgICAgICAgICAgc2tpcF9mcmFtZSA9IHByZXBhcmUoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBIQVNFMToKKyAgICAgICAgICAgIHNraXBfZnJhbWUgPSBwaGFzZTEoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBIQVNFMjoKKyAgICAgICAgICAgIHNraXBfZnJhbWUgPSBwaGFzZTIoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZJTklTSDoKKyAgICAgICAgICAgIHNraXBfZnJhbWUgPSBmaW5pc2hlZCgpOworICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiBza2lwX2ZyYW1lOworfQorCitib29sIE9yaWVudGF0aW9uQW5pbWF0aW9uOjpkb25lKCkKK3sKKyAgICBpZiAobUZsaW5nZXItPmlzRnJvemVuKCkpIHsKKyAgICAgICAgLy8gd2UgYXJlIG5vdCBhbGxvd2VkIHRvIGRyYXcsIGJ1dCBwYXVzZSBhIGJpdCB0byBtYWtlIHN1cmUKKyAgICAgICAgLy8gYXBwcyBkb24ndCBlbmQgdXAgdXNpbmcgdGhlIHdob2xlIENQVSwgaWYgdGhleSBkZXBlbmQgb24KKyAgICAgICAgLy8gc3VyZmFjZWZsaW5nZXIgZm9yIHN5bmNocm9uaXphdGlvbi4KKyAgICAgICAgdXNsZWVwKDgzMzMpOyAvLyA4LjNtcyB+IDEyMGZwcworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworfQorCitib29sIE9yaWVudGF0aW9uQW5pbWF0aW9uOjpwcmVwYXJlKCkKK3sKKyAgICBtU3RhdGUgPSBQSEFTRTE7CisgICAgCisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiBwbGFuZShtRmxpbmdlci0+Z3JhcGhpY1BsYW5lKDApKTsKKyAgICBjb25zdCBEaXNwbGF5SGFyZHdhcmUmIGh3KHBsYW5lLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICBjb25zdCB1aW50MzJfdCB3ID0gaHcuZ2V0V2lkdGgoKTsKKyAgICBjb25zdCB1aW50MzJfdCBoID0gaHcuZ2V0SGVpZ2h0KCk7CisKKyAgICBMYXllckJpdG1hcCBiaXRtYXA7CisgICAgYml0bWFwLmluaXQobVRlbXBvcmFyeURlYWxlcik7CisgICAgYml0bWFwLnNldEJpdHModywgaCwgMSwgaHcuZ2V0Rm9ybWF0KCkpOworCisgICAgTGF5ZXJCaXRtYXAgYml0bWFwSW47CisgICAgYml0bWFwSW4uaW5pdChtVGVtcG9yYXJ5RGVhbGVyKTsKKyAgICBiaXRtYXBJbi5zZXRCaXRzKHcsIGgsIDEsIGh3LmdldEZvcm1hdCgpKTsKKworICAgIGNvcHliaXRfaW1hZ2VfdCBmcm9udDsKKyAgICBiaXRtYXAuZ2V0Qml0bWFwU3VyZmFjZSgmZnJvbnQpOworICAgIGh3LmNvcHlGcm9udFRvSW1hZ2UoZnJvbnQpOworCisgICAgTGF5ZXJPcmllbnRhdGlvbkFuaW0qIGwgPSBuZXcgTGF5ZXJPcmllbnRhdGlvbkFuaW0oCisgICAgICAgICAgICBtRmxpbmdlci5nZXQoKSwgMCwgdGhpcywgYml0bWFwLCBiaXRtYXBJbik7CisgICAgbC0+aW5pdFN0YXRlcyh3LCBoLCAwKTsKKyAgICBsLT5zZXRMYXllcihJTlRfTUFYLTEpOworICAgIG1GbGluZ2VyLT5hZGRMYXllcihsKTsKKyAgICBtTGF5ZXJPcmllbnRhdGlvbkFuaW0gPSBsOworICAgIHJldHVybiB0cnVlOworfQorCitib29sIE9yaWVudGF0aW9uQW5pbWF0aW9uOjpwaGFzZTEoKQoreworICAgIGlmIChtRmxpbmdlci0+aXNGcm96ZW4oKSA9PSBmYWxzZSkgeworICAgICAgICAvLyBzdGFydCBwaGFzZSAyCisgICAgICAgIG1TdGF0ZSA9IFBIQVNFMjsKKyAgICAgICAgbUxheWVyT3JpZW50YXRpb25BbmltLT5vbk9yaWVudGF0aW9uQ29tcGxldGVkKCk7CisgICAgICAgIG1MYXllck9yaWVudGF0aW9uQW5pbS0+aW52YWxpZGF0ZSgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgCisgICAgfQorICAgIG1MYXllck9yaWVudGF0aW9uQW5pbS0+aW52YWxpZGF0ZSgpOworICAgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBPcmllbnRhdGlvbkFuaW1hdGlvbjo6cGhhc2UyKCkKK3sKKyAgICAvLyBkbyB0aGUgMm5kIHBoYXNlIG9mIHRoZSBhbmltYXRpb24KKyAgICBtTGF5ZXJPcmllbnRhdGlvbkFuaW0tPmludmFsaWRhdGUoKTsKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgT3JpZW50YXRpb25BbmltYXRpb246OmZpbmlzaGVkKCkKK3sKKyAgICBtU3RhdGUgPSBET05FOworICAgIG1GbGluZ2VyLT5yZW1vdmVMYXllcihtTGF5ZXJPcmllbnRhdGlvbkFuaW0pOworICAgIG1MYXllck9yaWVudGF0aW9uQW5pbSA9IE5VTEw7CisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9PcmllbnRhdGlvbkFuaW1hdGlvbi5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9PcmllbnRhdGlvbkFuaW1hdGlvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhMzNmY2UKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL09yaWVudGF0aW9uQW5pbWF0aW9uLmgKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9PUklFTlRBVElPTl9BTklNQVRJT05fSAorI2RlZmluZSBBTkRST0lEX09SSUVOVEFUSU9OX0FOSU1BVElPTl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgIlN1cmZhY2VGbGluZ2VyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIFN1cmZhY2VGbGluZ2VyOworY2xhc3MgTWVtb3J5RGVhbGVyOworY2xhc3MgTGF5ZXJPcmllbnRhdGlvbkFuaW07CisKK2NsYXNzIE9yaWVudGF0aW9uQW5pbWF0aW9uCit7CitwdWJsaWM6ICAgIAorICAgICAgICAgICAgICAgICBPcmllbnRhdGlvbkFuaW1hdGlvbihjb25zdCBzcDxTdXJmYWNlRmxpbmdlcj4mIGZsaW5nZXIpOworICAgICAgICB2aXJ0dWFsIH5PcmllbnRhdGlvbkFuaW1hdGlvbigpOworCisgICB2b2lkIG9uT3JpZW50YXRpb25DaGFuZ2VkKCk7CisgICB2b2lkIG9uQW5pbWF0aW9uRmluaXNoZWQoKTsKKyAgIGlubGluZSBib29sIHJ1bigpIHsKKyAgICAgICBpZiAoTElLRUxZKG1TdGF0ZSA9PSBET05FKSkKKyAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgIHJldHVybiBydW5faW1wbCgpOworICAgfQorCitwcml2YXRlOgorICAgIGVudW0geworICAgICAgICBET05FID0gMCwKKyAgICAgICAgUFJFUEFSRSwKKyAgICAgICAgUEhBU0UxLAorICAgICAgICBQSEFTRTIsCisgICAgICAgIEZJTklTSAorICAgIH07CisKKyAgICBib29sIHJ1bl9pbXBsKCk7CisgICAgYm9vbCBkb25lKCk7CisgICAgYm9vbCBwcmVwYXJlKCk7CisgICAgYm9vbCBwaGFzZTEoKTsKKyAgICBib29sIHBoYXNlMigpOworICAgIGJvb2wgZmluaXNoZWQoKTsKKworICAgIHNwPFN1cmZhY2VGbGluZ2VyPiBtRmxpbmdlcjsKKyAgICBzcDxNZW1vcnlEZWFsZXI+IG1UZW1wb3JhcnlEZWFsZXI7CisgICAgTGF5ZXJPcmllbnRhdGlvbkFuaW0qIG1MYXllck9yaWVudGF0aW9uQW5pbTsKKyAgICBpbnQgbVN0YXRlOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09SSUVOVEFUSU9OX0FOSU1BVElPTl9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1N1cmZhY2VGbGluZ2VyLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvU3VyZmFjZUZsaW5nZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwMDI4MmEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL1N1cmZhY2VGbGluZ2VyLmNwcApAQCAtMCwwICsxLDE4NDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN1cmZhY2VGbGluZ2VyIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisjaW5jbHVkZSA8Y3V0aWxzL3Byb3BlcnRpZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0lQQ1RocmVhZFN0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5QmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorI2luY2x1ZGUgPHV0aWxzL1N0b3BXYXRjaC5oPgorCisjaW5jbHVkZSA8dWkvUGl4ZWxGb3JtYXQuaD4KKyNpbmNsdWRlIDx1aS9EaXNwbGF5SW5mby5oPgorI2luY2x1ZGUgPHVpL0VHTERpc3BsYXlTdXJmYWNlLmg+CisKKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjaW5jbHVkZSAiY2x6LmgiCisjaW5jbHVkZSAiQ1BVR2F1Z2UuaCIKKyNpbmNsdWRlICJMYXllci5oIgorI2luY2x1ZGUgIkxheWVyQmx1ci5oIgorI2luY2x1ZGUgIkxheWVyQnVmZmVyLmgiCisjaW5jbHVkZSAiTGF5ZXJEaW0uaCIKKyNpbmNsdWRlICJMYXllckJpdG1hcC5oIgorI2luY2x1ZGUgIkxheWVyT3JpZW50YXRpb25BbmltLmgiCisjaW5jbHVkZSAiT3JpZW50YXRpb25BbmltYXRpb24uaCIKKyNpbmNsdWRlICJTdXJmYWNlRmxpbmdlci5oIgorI2luY2x1ZGUgIlZSYW1IZWFwLmgiCisKKyNpbmNsdWRlICJEaXNwbGF5SGFyZHdhcmUvRGlzcGxheUhhcmR3YXJlLmgiCisjaW5jbHVkZSAiR1BVSGFyZHdhcmUvR1BVSGFyZHdhcmUuaCIKKworCisjZGVmaW5lIERJU1BMQVlfQ09VTlQgICAgICAgMQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjppbnN0YW50aWF0ZSgpIHsKKyAgICBkZWZhdWx0U2VydmljZU1hbmFnZXIoKS0+YWRkU2VydmljZSgKKyAgICAgICAgICAgIFN0cmluZzE2KCJTdXJmYWNlRmxpbmdlciIpLCBuZXcgU3VyZmFjZUZsaW5nZXIoKSk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OnNodXRkb3duKCkgeworICAgIC8vIHdlIHNob3VsZCB1bnJlZ2lzdGVyIGhlcmUsIGJ1dCBub3QgcmVhbGx5IGJlY2F1c2UKKyAgICAvLyB3aGVuIChpZikgdGhlIHNlcnZpY2UgbWFuYWdlciBnb2VzIGF3YXksIGFsbCB0aGUgc2VydmljZXMKKyAgICAvLyBpdCBoYXMgYSByZWZlcmVuY2UgdG8gd2lsbCBsZWF2ZSB0b28uCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTdXJmYWNlRmxpbmdlcjo6TGF5ZXJWZWN0b3I6OkxheWVyVmVjdG9yKGNvbnN0IFN1cmZhY2VGbGluZ2VyOjpMYXllclZlY3RvciYgcmhzKQorICAgIDogbG9va3VwKHJocy5sb29rdXApLCBsYXllcnMocmhzLmxheWVycykKK3sKK30KKworc3NpemVfdCBTdXJmYWNlRmxpbmdlcjo6TGF5ZXJWZWN0b3I6OmluZGV4T2YoCisgICAgICAgIExheWVyQmFzZSoga2V5LCBzaXplX3QgZ3Vlc3MpIGNvbnN0Cit7CisgICAgaWYgKGd1ZXNzPHNpemUoKSAmJiBsb29rdXAua2V5QXQoZ3Vlc3MpID09IGtleSkKKyAgICAgICAgcmV0dXJuIGd1ZXNzOworICAgIGNvbnN0IHNzaXplX3QgaSA9IGxvb2t1cC5pbmRleE9mS2V5KGtleSk7CisgICAgaWYgKGk+PTApIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IGlkeCA9IGxvb2t1cC52YWx1ZUF0KGkpOworICAgICAgICBMT0dfQVNTRVJUKGxheWVyc1tpZHhdPT1rZXksCisgICAgICAgICAgICAiTGF5ZXJWZWN0b3JbJXBdOiBsYXllcnNbJWRdPSVwLCBrZXk9JXAiLAorICAgICAgICAgICAgdGhpcywgaW50KGlkeCksIGxheWVyc1tpZHhdLCBrZXkpOworICAgICAgICByZXR1cm4gaWR4OworICAgIH0KKyAgICByZXR1cm4gaTsKK30KKworc3NpemVfdCBTdXJmYWNlRmxpbmdlcjo6TGF5ZXJWZWN0b3I6OmFkZCgKKyAgICAgICAgTGF5ZXJCYXNlKiBsYXllciwKKyAgICAgICAgVmVjdG9yPExheWVyQmFzZSo+Ojpjb21wYXJfdCBjbXApCit7CisgICAgc2l6ZV90IGNvdW50ID0gbGF5ZXJzLnNpemUoKTsKKyAgICBzc2l6ZV90IGwgPSAwOworICAgIHNzaXplX3QgaCA9IGNvdW50LTE7CisgICAgc3NpemVfdCBtaWQ7CisgICAgTGF5ZXJCYXNlKiBjb25zdCogYSA9IGxheWVycy5hcnJheSgpOworICAgIHdoaWxlIChsIDw9IGgpIHsKKyAgICAgICAgbWlkID0gbCArIChoIC0gbCkvMjsKKyAgICAgICAgY29uc3QgaW50IGMgPSBjbXAoYSttaWQsICZsYXllcik7CisgICAgICAgIGlmIChjID09IDApICAgICB7IGwgPSBtaWQ7IGJyZWFrOyB9CisgICAgICAgIGVsc2UgaWYgKGM8MCkgICB7IGwgPSBtaWQrMTsgfQorICAgICAgICBlbHNlICAgICAgICAgICAgeyBoID0gbWlkLTE7IH0KKyAgICB9CisgICAgc2l6ZV90IG9yZGVyID0gbDsKKyAgICB3aGlsZSAob3JkZXI8Y291bnQgJiYgIWNtcCgmbGF5ZXIsIGErb3JkZXIpKSB7CisgICAgICAgIG9yZGVyKys7CisgICAgfQorICAgIGNvdW50ID0gbG9va3VwLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgIGlmIChsb29rdXAudmFsdWVBdChpKSA+PSBvcmRlcikgeworICAgICAgICAgICAgbG9va3VwLmVkaXRWYWx1ZUF0KGkpKys7CisgICAgICAgIH0KKyAgICB9CisgICAgbGF5ZXJzLmluc2VydEF0KGxheWVyLCBvcmRlcik7CisgICAgbG9va3VwLmFkZChsYXllciwgb3JkZXIpOworICAgIHJldHVybiBvcmRlcjsKK30KKworc3NpemVfdCBTdXJmYWNlRmxpbmdlcjo6TGF5ZXJWZWN0b3I6OnJlbW92ZShMYXllckJhc2UqIGxheWVyKQoreworICAgIGNvbnN0IHNzaXplX3Qga2V5SW5kZXggPSBsb29rdXAuaW5kZXhPZktleShsYXllcik7CisgICAgaWYgKGtleUluZGV4ID49IDApIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IGluZGV4ID0gbG9va3VwLnZhbHVlQXQoa2V5SW5kZXgpOworICAgICAgICBMT0dfQVNTRVJUKGxheWVyc1tpbmRleF09PWxheWVyLAorICAgICAgICAgICAgICAgICJMYXllclZlY3RvclslcF06IGxheWVyc1sldV09JXAsIGxheWVyPSVwIiwKKyAgICAgICAgICAgICAgICB0aGlzLCBpbnQoaW5kZXgpLCBsYXllcnNbaW5kZXhdLCBsYXllcik7CisgICAgICAgIGxheWVycy5yZW1vdmVJdGVtc0F0KGluZGV4KTsKKyAgICAgICAgbG9va3VwLnJlbW92ZUl0ZW1zQXQoa2V5SW5kZXgpOworICAgICAgICBjb25zdCBzaXplX3QgY291bnQgPSBsb29rdXAuc2l6ZSgpOworICAgICAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICBpZiAobG9va3VwLnZhbHVlQXQoaSkgPj0gc2l6ZV90KGluZGV4KSkgeworICAgICAgICAgICAgICAgIGxvb2t1cC5lZGl0VmFsdWVBdChpKS0tOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpbmRleDsKKyAgICB9CisgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworfQorCitzc2l6ZV90IFN1cmZhY2VGbGluZ2VyOjpMYXllclZlY3Rvcjo6cmVvcmRlcigKKyAgICAgICAgTGF5ZXJCYXNlKiBsYXllciwKKyAgICAgICAgVmVjdG9yPExheWVyQmFzZSo+Ojpjb21wYXJfdCBjbXApCit7CisgICAgLy8gWFhYOiBpdCdzIGEgbGl0dGxlIGxhbWUuIGJ1dCBvaCB3ZWxsLi4uCisgICAgc3NpemVfdCBlcnIgPSByZW1vdmUobGF5ZXIpOworICAgIGlmIChlcnIgPj0wKQorICAgICAgICBlcnIgPSBhZGQobGF5ZXIsIGNtcCk7CisgICAgcmV0dXJuIGVycjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCitTdXJmYWNlRmxpbmdlcjo6U3VyZmFjZUZsaW5nZXIoKQorICAgIDogICBCblN1cmZhY2VDb21wb3NlcigpLCBUaHJlYWQoZmFsc2UpLAorICAgICAgICBtVHJhbnNhY3Rpb25GbGFncygwKSwKKyAgICAgICAgbVRyYW5zYWN0aW9uQ291bnQoMCksCisgICAgICAgIG1Cb290VGltZShzeXN0ZW1UaW1lKCkpLAorICAgICAgICBtTGFzdFNjaGVkdWxlZEJyb2FkY2FzdChOVUxMKSwKKyAgICAgICAgbVZpc2libGVSZWdpb25zRGlydHkoZmFsc2UpLAorICAgICAgICBtRGVmZXJSZWxlYXNlQ29uc29sZShmYWxzZSksCisgICAgICAgIG1GcmVlemVEaXNwbGF5KGZhbHNlKSwKKyAgICAgICAgbUZyZWV6ZUNvdW50KDApLAorICAgICAgICBtRGVidWdSZWdpb24oMCksCisgICAgICAgIG1EZWJ1Z0NwdSgwKSwKKyAgICAgICAgbURlYnVnRnBzKDApLAorICAgICAgICBtRGVidWdCYWNrZ3JvdW5kKDApLAorICAgICAgICBtRGVidWdOb0Jvb3RBbmltYXRpb24oMCksCisgICAgICAgIG1TeW5jT2JqZWN0KCksCisgICAgICAgIG1EZXBsYXllZFRyYW5zYWN0aW9uUGVuZGluZygwKSwKKyAgICAgICAgbUNvbnNvbGVTaWduYWxzKDApLAorICAgICAgICBtU2VjdXJlRnJhbWVCdWZmZXIoMCkKK3sKKyAgICBpbml0KCk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmluaXQoKQoreworICAgIExPR0koIlN1cmZhY2VGbGluZ2VyIGlzIHN0YXJ0aW5nIik7CisKKyAgICAvLyBkZWJ1Z2dpbmcgc3R1ZmYuLi4KKyAgICBjaGFyIHZhbHVlW1BST1BFUlRZX1ZBTFVFX01BWF07CisgICAgcHJvcGVydHlfZ2V0KCJkZWJ1Zy5zZi5zaG93dXBkYXRlcyIsIHZhbHVlLCAiMCIpOworICAgIG1EZWJ1Z1JlZ2lvbiA9IGF0b2kodmFsdWUpOworICAgIHByb3BlcnR5X2dldCgiZGVidWcuc2Yuc2hvd2NwdSIsIHZhbHVlLCAiMCIpOworICAgIG1EZWJ1Z0NwdSA9IGF0b2kodmFsdWUpOworICAgIHByb3BlcnR5X2dldCgiZGVidWcuc2Yuc2hvd2JhY2tncm91bmQiLCB2YWx1ZSwgIjAiKTsKKyAgICBtRGVidWdCYWNrZ3JvdW5kID0gYXRvaSh2YWx1ZSk7CisgICAgcHJvcGVydHlfZ2V0KCJkZWJ1Zy5zZi5zaG93ZnBzIiwgdmFsdWUsICIwIik7CisgICAgbURlYnVnRnBzID0gYXRvaSh2YWx1ZSk7CisgICAgcHJvcGVydHlfZ2V0KCJkZWJ1Zy5zZi5ub2Jvb3RhbmltYXRpb24iLCB2YWx1ZSwgIjAiKTsKKyAgICBtRGVidWdOb0Jvb3RBbmltYXRpb24gPSBhdG9pKHZhbHVlKTsKKworICAgIExPR0lfSUYobURlYnVnUmVnaW9uLCAgICAgICAgICAgInNob3d1cGRhdGVzIGVuYWJsZWQiKTsKKyAgICBMT0dJX0lGKG1EZWJ1Z0NwdSwgICAgICAgICAgICAgICJzaG93Y3B1IGVuYWJsZWQiKTsKKyAgICBMT0dJX0lGKG1EZWJ1Z0JhY2tncm91bmQsICAgICAgICJzaG93YmFja2dyb3VuZCBlbmFibGVkIik7CisgICAgTE9HSV9JRihtRGVidWdGcHMsICAgICAgICAgICAgICAic2hvd2ZwcyBlbmFibGVkIik7CisgICAgTE9HSV9JRihtRGVidWdOb0Jvb3RBbmltYXRpb24sICAiYm9vdCBhbmltYXRpb24gZGlzYWJsZWQiKTsKK30KKworU3VyZmFjZUZsaW5nZXI6On5TdXJmYWNlRmxpbmdlcigpCit7CisgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmbVdvcm1ob2xlVGV4TmFtZSk7CisgICAgZGVsZXRlIG1PcmllbnRhdGlvbkFuaW1hdGlvbjsKK30KKworY29weWJpdF9kZXZpY2VfdCogU3VyZmFjZUZsaW5nZXI6OmdldEJsaXRFbmdpbmUoKSBjb25zdAoreworICAgIHJldHVybiBncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkuZ2V0QmxpdEVuZ2luZSgpOworfQorCitvdmVybGF5X2NvbnRyb2xfZGV2aWNlX3QqIFN1cmZhY2VGbGluZ2VyOjpnZXRPdmVybGF5RW5naW5lKCkgY29uc3QKK3sKKyAgICByZXR1cm4gZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpLmdldE92ZXJsYXlFbmdpbmUoKTsKK30KKworc3A8SU1lbW9yeT4gU3VyZmFjZUZsaW5nZXI6OmdldENibGsoKSBjb25zdAoreworICAgIHJldHVybiBtU2VydmVyQ2Jsa01lbW9yeTsKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXI6OnJlcXVlc3RHUFUoY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssCisgICAgICAgIGdwdV9pbmZvX3QqIGdwdSkKK3sKKyAgICBJUENUaHJlYWRTdGF0ZSogaXBjID0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKTsKKyAgICBjb25zdCBpbnQgcGlkID0gaXBjLT5nZXRDYWxsaW5nUGlkKCk7CisgICAgc3RhdHVzX3QgZXJyID0gbUdQVS0+cmVxdWVzdChwaWQsIGNhbGxiYWNrLCBncHUpOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjpyZXZva2VHUFUoKQoreworICAgIHJldHVybiBtR1BVLT5mcmllbmRseVJldm9rZSgpOworfQorCitzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+IFN1cmZhY2VGbGluZ2VyOjpjcmVhdGVDb25uZWN0aW9uKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgdWludDMyX3QgdG9rZW4gPSBtVG9rZW5zLmFjcXVpcmUoKTsKKworICAgIENsaWVudCogY2xpZW50ID0gbmV3IENsaWVudCh0b2tlbiwgdGhpcyk7CisgICAgaWYgKChjbGllbnQgPT0gMCkgfHwgKGNsaWVudC0+Y3RybGJsayA9PSAwKSkgeworICAgICAgICBtVG9rZW5zLnJlbGVhc2UodG9rZW4pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgc3RhdHVzX3QgZXJyID0gbUNsaWVudHNNYXAuYWRkKHRva2VuLCBjbGllbnQpOworICAgIGlmIChlcnIgPCAwKSB7CisgICAgICAgIGRlbGV0ZSBjbGllbnQ7CisgICAgICAgIG1Ub2tlbnMucmVsZWFzZSh0b2tlbik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBzcDxCQ2xpZW50PiBiY2xpZW50ID0KKyAgICAgICAgbmV3IEJDbGllbnQodGhpcywgdG9rZW4sIGNsaWVudC0+Y29udHJvbEJsb2NrTWVtb3J5KCkpOworICAgIHJldHVybiBiY2xpZW50OworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpkZXN0cm95Q29ubmVjdGlvbihDbGllbnRJRCBjaWQpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1TdGF0ZUxvY2spOworICAgIENsaWVudCogY29uc3QgY2xpZW50ID0gbUNsaWVudHNNYXAudmFsdWVGb3IoY2lkKTsKKyAgICBpZiAoY2xpZW50KSB7CisgICAgICAgIC8vIGZyZWUgYWxsIHRoZSBsYXllcnMgdGhpcyBjbGllbnQgb3ducworICAgICAgICBjb25zdCBWZWN0b3I8TGF5ZXJCYXNlQ2xpZW50Kj4mIGxheWVycyA9IGNsaWVudC0+Z2V0TGF5ZXJzKCk7CisgICAgICAgIGNvbnN0IHNpemVfdCBjb3VudCA9IGxheWVycy5zaXplKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyBpKyspIHsKKyAgICAgICAgICAgIExheWVyQmFzZUNsaWVudCogY29uc3QgbGF5ZXIgPSBsYXllcnNbaV07CisgICAgICAgICAgICByZW1vdmVMYXllcl9sKGxheWVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY2xpZW50IHdpbGwgYmUgZnJlZWQKKyAgICAgICAgLy8gZHVyaW5nIHRoZSBuZXh0IHRyYW5zYWN0aW9uLCBhZnRlciB0aGVzZSBzdXJmYWNlcyBoYXZlIGJlZW4KKyAgICAgICAgLy8gcHJvcGVybHkgcmVtb3ZlZCBmcm9tIHRoZSBzY3JlZW4KKworICAgICAgICAvLyByZW1vdmUgdGhpcyBjbGllbnQgZnJvbSBvdXIgQ2xpZW50SUQtPkNsaWVudCBtYXBwaW5nLgorICAgICAgICBtQ2xpZW50c01hcC5yZW1vdmVJdGVtKGNpZCk7CisKKyAgICAgICAgLy8gYW5kIGFkZCBpdCB0byB0aGUgbGlzdCBvZiBkaXNjb25uZWN0ZWQgY2xpZW50cworICAgICAgICBtRGlzY29ubmVjdGVkQ2xpZW50cy5hZGQoY2xpZW50KTsKKworICAgICAgICAvLyByZXF1ZXN0IGEgdHJhbnNhY3Rpb24KKyAgICAgICAgc2V0VHJhbnNhY3Rpb25GbGFncyhlVHJhbnNhY3Rpb25OZWVkZWQpOworICAgIH0KK30KKworY29uc3QgR3JhcGhpY1BsYW5lJiBTdXJmYWNlRmxpbmdlcjo6Z3JhcGhpY1BsYW5lKGludCBkcHkpIGNvbnN0Cit7CisgICAgTE9HRV9JRih1aW50MzJfdChkcHkpID49IERJU1BMQVlfQ09VTlQsICJJbnZhbGlkIERpc3BsYXlJRCAlZCIsIGRweSk7CisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiBwbGFuZShtR3JhcGhpY1BsYW5lc1tkcHldKTsKKyAgICByZXR1cm4gcGxhbmU7Cit9CisKK0dyYXBoaWNQbGFuZSYgU3VyZmFjZUZsaW5nZXI6OmdyYXBoaWNQbGFuZShpbnQgZHB5KQoreworICAgIHJldHVybiBjb25zdF9jYXN0PEdyYXBoaWNQbGFuZSY+KAorICAgICAgICBjb25zdF9jYXN0PFN1cmZhY2VGbGluZ2VyIGNvbnN0ICo+KHRoaXMpLT5ncmFwaGljUGxhbmUoZHB5KSk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmJvb3RGaW5pc2hlZCgpCit7CisgICAgY29uc3QgbnNlY3NfdCBub3cgPSBzeXN0ZW1UaW1lKCk7CisgICAgY29uc3QgbnNlY3NfdCBkdXJhdGlvbiA9IG5vdyAtIG1Cb290VGltZTsKKyAgICBMT0dJKCJCb290IGlzIGZpbmlzaGVkICglbGQgbXMpIiwgbG9uZyhuczJtcyhkdXJhdGlvbikpICk7CisgICAgaWYgKG1Cb290QW5pbWF0aW9uICE9IDApIHsKKyAgICAgICAgbUJvb3RBbmltYXRpb24tPnJlcXVlc3RFeGl0KCk7CisgICAgICAgIG1Cb290QW5pbWF0aW9uLmNsZWFyKCk7CisgICAgfQorfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpvbkZpcnN0UmVmKCkKK3sKKyAgICBydW4oIlN1cmZhY2VGbGluZ2VyIiwgUFJJT1JJVFlfVVJHRU5UX0RJU1BMQVkpOworCisgICAgLy8gV2FpdCBmb3IgdGhlIG1haW4gdGhyZWFkIHRvIGJlIGRvbmUgd2l0aCBpdHMgaW5pdGlhbGl6YXRpb24KKyAgICBtUmVhZHlUb1J1bkJhcnJpZXIud2FpdCgpOworfQorCisKK3N0YXRpYyBpbmxpbmUgdWludDE2X3QgcGFjazU2NShpbnQgciwgaW50IGcsIGludCBiKSB7CisgICAgcmV0dXJuIChyPDwxMSl8KGc8PDUpfGI7Cit9CisKKy8vIHRoaXMgaXMgZGVmaW5lZCBpbiBsaWJHTEVTX0NNLnNvCitleHRlcm4gSVN1cmZhY2VDb21wb3NlciogR0xFU19sb2NhbFN1cmZhY2VNYW5hZ2VyOworCitzdGF0dXNfdCBTdXJmYWNlRmxpbmdlcjo6cmVhZHlUb1J1bigpCit7CisgICAgTE9HSSggICAiU3VyZmFjZUZsaW5nZXIncyBtYWluIHRocmVhZCByZWFkeSB0byBydW4uICIKKyAgICAgICAgICAgICJJbml0aWFsaXppbmcgZ3JhcGhpY3MgSC9XLi4uIik7CisKKyAgICAvLyBjcmVhdGUgdGhlIHNoYXJlZCBjb250cm9sLWJsb2NrCisgICAgbVNlcnZlckhlYXAgPSBuZXcgTWVtb3J5RGVhbGVyKDQwOTYsIE1lbW9yeURlYWxlcjo6UkVBRF9PTkxZKTsKKyAgICBMT0dFX0lGKG1TZXJ2ZXJIZWFwPT0wLCAiY2FuJ3QgY3JlYXRlIHNoYXJlZCBtZW1vcnkgZGVhbGVyIik7CisKKyAgICBtU2VydmVyQ2Jsa01lbW9yeSA9IG1TZXJ2ZXJIZWFwLT5hbGxvY2F0ZSg0MDk2KTsKKyAgICBMT0dFX0lGKG1TZXJ2ZXJDYmxrTWVtb3J5PT0wLCAiY2FuJ3QgY3JlYXRlIHNoYXJlZCBjb250cm9sIGJsb2NrIik7CisKKyAgICBtU2VydmVyQ2JsayA9IHN0YXRpY19jYXN0PHN1cmZhY2VfZmxpbmdlcl9jYmxrX3QgKj4obVNlcnZlckNibGtNZW1vcnktPnBvaW50ZXIoKSk7CisgICAgTE9HRV9JRihtU2VydmVyQ2Jsaz09MCwgImNhbid0IGdldCB0byBzaGFyZWQgY29udHJvbCBibG9jaydzIGFkZHJlc3MiKTsKKyAgICBuZXcobVNlcnZlckNibGspIHN1cmZhY2VfZmxpbmdlcl9jYmxrX3Q7CisKKyAgICAvLyBnZXQgYSByZWZlcmVuY2UgdG8gdGhlIEdQVSBpZiB3ZSBoYXZlIG9uZQorICAgIG1HUFUgPSBHUFVGYWN0b3J5OjpnZXRHUFUoKTsKKworICAgIC8vIGNyZWF0ZSB0aGUgc3VyZmFjZSBIZWFwIG1hbmFnZXIsIHdoaWNoIG1hbmFnZXMgdGhlIGhlYXBzCisgICAgLy8gKGJlIGl0IGluIFJBTSBvciBWUkFNKSB3aGVyZSBzdXJmYWNlcyBhcmUgYWxsb2NhdGVkCisgICAgLy8gV2UgZ2l2ZSA4IE1CIHBlciBjbGllbnQuCisgICAgbVN1cmZhY2VIZWFwTWFuYWdlciA9IG5ldyBTdXJmYWNlSGVhcE1hbmFnZXIodGhpcywgOCA8PCAyMCk7CisKKyAgICAKKyAgICBHTEVTX2xvY2FsU3VyZmFjZU1hbmFnZXIgPSBzdGF0aWNfY2FzdDxJU3VyZmFjZUNvbXBvc2VyKj4odGhpcyk7CisKKyAgICAvLyB3ZSBvbmx5IHN1cHBvcnQgb25lIGRpc3BsYXkgY3VycmVudGx5CisgICAgaW50IGRweSA9IDA7CisKKyAgICB7CisgICAgICAgIC8vIGluaXRpYWxpemUgdGhlIG1haW4gZGlzcGxheQorICAgICAgICBHcmFwaGljUGxhbmUmIHBsYW5lKGdyYXBoaWNQbGFuZShkcHkpKTsKKyAgICAgICAgRGlzcGxheUhhcmR3YXJlKiBjb25zdCBodyA9IG5ldyBEaXNwbGF5SGFyZHdhcmUodGhpcywgZHB5KTsKKyAgICAgICAgcGxhbmUuc2V0RGlzcGxheUhhcmR3YXJlKGh3KTsKKyAgICB9CisKKyAgICAvLyBpbml0aWFsaXplIHByaW1hcnkgc2NyZWVuCisgICAgLy8gKG90aGVyIGRpc3BsYXkgc2hvdWxkIGJlIGluaXRpYWxpemVkIGluIHRoZSBzYW1lIG1hbm5lciwgYnV0CisgICAgLy8gYXN5bmNocm9ub3VzbHksIGFzIHRoZXkgY291bGQgY29tZSBhbmQgZ28uIE5vbmUgb2YgdGhpcyBpcyBzdXBwb3J0ZWQKKyAgICAvLyB5ZXQpLgorICAgIGNvbnN0IEdyYXBoaWNQbGFuZSYgcGxhbmUoZ3JhcGhpY1BsYW5lKGRweSkpOworICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcgPSBwbGFuZS5kaXNwbGF5SGFyZHdhcmUoKTsKKyAgICBjb25zdCB1aW50MzJfdCB3ID0gaHcuZ2V0V2lkdGgoKTsKKyAgICBjb25zdCB1aW50MzJfdCBoID0gaHcuZ2V0SGVpZ2h0KCk7CisgICAgY29uc3QgdWludDMyX3QgZiA9IGh3LmdldEZvcm1hdCgpOworICAgIGh3Lm1ha2VDdXJyZW50KCk7CisKKyAgICAvLyBpbml0aWFsaXplIHRoZSBzaGFyZWQgY29udHJvbCBibG9jaworICAgIG1TZXJ2ZXJDYmxrLT5jb25uZWN0ZWQgfD0gMTw8ZHB5OworICAgIGRpc3BsYXlfY2Jsa190KiBkY2JsayA9IG1TZXJ2ZXJDYmxrLT5kaXNwbGF5cyArIGRweTsKKyAgICBtZW1zZXQoZGNibGssIDAsIHNpemVvZihkaXNwbGF5X2NibGtfdCkpOworICAgIGRjYmxrLT53ICAgICAgICAgICAgPSB3OworICAgIGRjYmxrLT5oICAgICAgICAgICAgPSBoOworICAgIGRjYmxrLT5mb3JtYXQgICAgICAgPSBmOworICAgIGRjYmxrLT5vcmllbnRhdGlvbiAgPSBJU3VyZmFjZUNvbXBvc2VyOjplT3JpZW50YXRpb25EZWZhdWx0OworICAgIGRjYmxrLT54ZHBpICAgICAgICAgPSBody5nZXREcGlYKCk7CisgICAgZGNibGstPnlkcGkgICAgICAgICA9IGh3LmdldERwaVkoKTsKKyAgICBkY2Jsay0+ZnBzICAgICAgICAgID0gaHcuZ2V0UmVmcmVzaFJhdGUoKTsKKyAgICBkY2Jsay0+ZGVuc2l0eSAgICAgID0gaHcuZ2V0RGVuc2l0eSgpOworICAgIGFzbSB2b2xhdGlsZSAoIiI6OjoibWVtb3J5Iik7CisKKyAgICAvLyBJbml0aWFsaXplIE9wZW5HTHxFUworICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMCk7CisgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QX1RPX0VER0UpOworICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVBfVE9fRURHRSk7CisgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CisgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CisgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKKyAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19BTElHTk1FTlQsIDQpOworICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19BTElHTk1FTlQsIDQpOyAKKyAgICBnbEVuYWJsZUNsaWVudFN0YXRlKEdMX1ZFUlRFWF9BUlJBWSk7CisgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKKyAgICBnbFNoYWRlTW9kZWwoR0xfRkxBVCk7CisgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CisKKyAgICBjb25zdCB1aW50MTZfdCBnMCA9IHBhY2s1NjUoMHgwRiwweDFGLDB4MEYpOworICAgIGNvbnN0IHVpbnQxNl90IGcxID0gcGFjazU2NSgweDE3LDB4MmYsMHgxNyk7CisgICAgY29uc3QgdWludDE2X3QgdGV4dHVyZURhdGFbNF0gPSB7IGcwLCBnMSwgZzEsIGcwIH07CisgICAgZ2xHZW5UZXh0dXJlcygxLCAmbVdvcm1ob2xlVGV4TmFtZSk7CisgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBtV29ybWhvbGVUZXhOYW1lKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX1JFUEVBVCk7CisgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9ULCBHTF9SRVBFQVQpOworICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0IsIDIsIDIsIDAsCisgICAgICAgICAgICBHTF9SR0IsIEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81LCB0ZXh0dXJlRGF0YSk7CisKKyAgICBnbFZpZXdwb3J0KDAsIDAsIHcsIGgpOworICAgIGdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKTsKKyAgICBnbExvYWRJZGVudGl0eSgpOworICAgIGdsT3J0aG9mKDAsIHcsIGgsIDAsIDAsIDEpOworCisgICBMYXllckRpbTo6aW5pdERpbW1lcih0aGlzLCB3LCBoKTsKKworICAgIG1SZWFkeVRvUnVuQmFycmllci5vcGVuKCk7CisKKyAgICAvKgorICAgICAqICBXZSdyZSBub3cgcmVhZHkgdG8gYWNjZXB0IGNsaWVudHMuLi4KKyAgICAgKi8KKworICAgIG1PcmllbnRhdGlvbkFuaW1hdGlvbiA9IG5ldyBPcmllbnRhdGlvbkFuaW1hdGlvbih0aGlzKTsKKyAgICAKKyAgICAvLyBzdGFydCBDUFUgZ2F1Z2UgZGlzcGxheQorICAgIGlmIChtRGVidWdDcHUpCisgICAgICAgIG1DcHVHYXVnZSA9IG5ldyBDUFVHYXVnZSh0aGlzLCBtczJucyg1MDApKTsKKworICAgIC8vIHRoZSBib290IGFuaW1hdGlvbiEKKyAgICBpZiAobURlYnVnTm9Cb290QW5pbWF0aW9uID09IGZhbHNlKQorICAgICAgICBtQm9vdEFuaW1hdGlvbiA9IG5ldyBCb290QW5pbWF0aW9uKHRoaXMpOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBFdmVudHMgSGFuZGxlcgorI2VuZGlmCisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OndhaXRGb3JFdmVudCgpCit7CisgICAgLy8gd2FpdCBmb3Igc29tZXRoaW5nIHRvIGRvCisgICAgaWYgKFVOTElLRUxZKGlzRnJvemVuKCkpKSB7CisgICAgICAgIC8vIHdhaXQgNSBzZWNvbmRzCisgICAgICAgIGludCBlcnIgPSBtU3luY09iamVjdC53YWl0KG1zMm5zKDUwMDApKTsKKyAgICAgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgaWYgKGlzRnJvemVuKCkpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSB0aW1lZCBvdXQgYW5kIGFyZSBzdGlsbCBmcm96ZW4KKyAgICAgICAgICAgICAgICBMT0dXKCJ0aW1lb3V0IGV4cGlyZWQgbUZyZWV6ZURpc3BsYXk9JWQsIG1GcmVlemVDb3VudD0lZCIsCisgICAgICAgICAgICAgICAgICAgICAgICBtRnJlZXplRGlzcGxheSwgbUZyZWV6ZUNvdW50KTsKKyAgICAgICAgICAgICAgICBtRnJlZXplQ291bnQgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgbVN5bmNPYmplY3Qud2FpdCgpOworICAgIH0KK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6c2lnbmFsRXZlbnQoKSB7CisgICAgbVN5bmNPYmplY3Qub3BlbigpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpzaWduYWwoKSBjb25zdCB7CisgICAgbVN5bmNPYmplY3Qub3BlbigpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpzaWduYWxEZWxheWVkRXZlbnQobnNlY3NfdCBkZWxheSkKK3sKKyAgICBpZiAoYW5kcm9pZF9hdG9taWNfb3IoMSwgJm1EZXBsYXllZFRyYW5zYWN0aW9uUGVuZGluZykgPT0gMCkgeworICAgICAgICBzcDxEZWxheWVkVHJhbnNhY3Rpb24+IGRlbGF5ZWRFdmVudChuZXcgRGVsYXllZFRyYW5zYWN0aW9uKHRoaXMsIGRlbGF5KSk7CisgICAgICAgIGRlbGF5ZWRFdmVudC0+cnVuKCJEZWxheWVkZUV2ZW50IiwgUFJJT1JJVFlfVVJHRU5UX0RJU1BMQVkpOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgTWFpbiBsb29wCisjZW5kaWYKKworYm9vbCBTdXJmYWNlRmxpbmdlcjo6dGhyZWFkTG9vcCgpCit7CisgICAgd2FpdEZvckV2ZW50KCk7CisKKyAgICAvLyBjaGVjayBmb3IgdHJhbnNhY3Rpb25zCisgICAgaWYgKFVOTElLRUxZKG1Db25zb2xlU2lnbmFscykpIHsKKyAgICAgICAgaGFuZGxlQ29uc29sZUV2ZW50cygpOworICAgIH0KKworICAgIGlmIChMSUtFTFkobVRyYW5zYWN0aW9uQ291bnQgPT0gMCkpIHsKKyAgICAgICAgLy8gaWYgd2UncmUgaW4gYSBnbG9iYWwgdHJhbnNhY3Rpb24sIGRvbid0IGRvIGFueXRoaW5nLgorICAgICAgICBjb25zdCB1aW50MzJfdCBtYXNrID0gZVRyYW5zYWN0aW9uTmVlZGVkIHwgZVRyYXZlcnNhbE5lZWRlZDsKKyAgICAgICAgdWludDMyX3QgdHJhbnNhY3Rpb25GbGFncyA9IGdldFRyYW5zYWN0aW9uRmxhZ3MobWFzayk7CisgICAgICAgIGlmIChMSUtFTFkodHJhbnNhY3Rpb25GbGFncykpIHsKKyAgICAgICAgICAgIGhhbmRsZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uRmxhZ3MpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gcG9zdCBzdXJmYWNlcyAoaWYgbmVlZGVkKQorICAgIGhhbmRsZVBhZ2VGbGlwKCk7CisKKyAgICBjb25zdCBEaXNwbGF5SGFyZHdhcmUmIGh3KGdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKSk7CisgICAgaWYgKExJS0VMWShody5jYW5EcmF3KCkpKSB7CisgICAgICAgIC8vIHJlcGFpbnQgdGhlIGZyYW1lYnVmZmVyIChpZiBuZWVkZWQpCisgICAgICAgIGhhbmRsZVJlcGFpbnQoKTsKKworICAgICAgICAvLyByZWxlYXNlIHRoZSBjbGllbnRzIGJlZm9yZSB3ZSBmbGlwICgnY2F1c2UgZmxpcCBtaWdodCBibG9jaykKKyAgICAgICAgdW5sb2NrQ2xpZW50cygpOworICAgICAgICBleGVjdXRlU2NoZWR1bGVkQnJvYWRjYXN0cygpOworCisgICAgICAgIC8vIHNhbXBsZSB0aGUgY3B1IGdhdWdlCisgICAgICAgIGlmIChVTkxJS0VMWShtRGVidWdDcHUpKSB7CisgICAgICAgICAgICBoYW5kbGVEZWJ1Z0NwdSgpOworICAgICAgICB9CisKKyAgICAgICAgcG9zdEZyYW1lYnVmZmVyKCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gcHJldGVuZCB3ZSBkaWQgdGhlIHBvc3QKKyAgICAgICAgdW5sb2NrQ2xpZW50cygpOworICAgICAgICBleGVjdXRlU2NoZWR1bGVkQnJvYWRjYXN0cygpOworICAgICAgICB1c2xlZXAoMTY2NjcpOyAvLyA2MCBmcHMgcGVyaW9kCisgICAgfQorICAgIHJldHVybiB0cnVlOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpwb3N0RnJhbWVidWZmZXIoKQoreworICAgIGNvbnN0IGJvb2wgc2tpcCA9IG1PcmllbnRhdGlvbkFuaW1hdGlvbi0+cnVuKCk7CisgICAgaWYgKFVOTElLRUxZKHNraXApKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoIW1JbnZhbGlkUmVnaW9uLmlzRW1wdHkoKSkgeworICAgICAgICBjb25zdCBEaXNwbGF5SGFyZHdhcmUmIGh3KGdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKSk7CisKKyAgICAgICAgaWYgKFVOTElLRUxZKG1EZWJ1Z0ZwcykpIHsKKyAgICAgICAgICAgIGRlYnVnU2hvd0ZQUygpOworICAgICAgICB9CisKKyAgICAgICAgaHcuZmxpcChtSW52YWxpZFJlZ2lvbik7CisKKyAgICAgICAgbUludmFsaWRSZWdpb24uY2xlYXIoKTsKKworICAgICAgICBpZiAoTGF5ZXI6OmRlbGV0ZWRUZXh0dXJlcy5zaXplKCkpIHsKKyAgICAgICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoCisgICAgICAgICAgICAgICAgICAgIExheWVyOjpkZWxldGVkVGV4dHVyZXMuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICBMYXllcjo6ZGVsZXRlZFRleHR1cmVzLmFycmF5KCkpOworICAgICAgICAgICAgTGF5ZXI6OmRlbGV0ZWRUZXh0dXJlcy5jbGVhcigpOworICAgICAgICB9CisgICAgfQorfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpoYW5kbGVDb25zb2xlRXZlbnRzKCkKK3sKKyAgICAvLyBzb21ldGhpbmcgdG8gZG8gd2l0aCB0aGUgY29uc29sZQorICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcgPSBncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCk7CisKKyAgICBpbnQgd2hhdCA9IGFuZHJvaWRfYXRvbWljX2FuZCgwLCAmbUNvbnNvbGVTaWduYWxzKTsKKyAgICBpZiAod2hhdCAmIGVDb25zb2xlQWNxdWlyZWQpIHsKKyAgICAgICAgaHcuYWNxdWlyZVNjcmVlbigpOworICAgIH0KKworICAgIGlmIChtRGVmZXJSZWxlYXNlQ29uc29sZSAmJiBody5jYW5EcmF3KCkpIHsKKyAgICAgICAgLy8gV2UgZ290IHRoZSByZWxlYXNlIHNpZ25hbCBiZWZvcmUgdGhlIGFxdWlyZSBzaWduYWwKKyAgICAgICAgbURlZmVyUmVsZWFzZUNvbnNvbGUgPSBmYWxzZTsKKyAgICAgICAgcmV2b2tlR1BVKCk7CisgICAgICAgIGh3LnJlbGVhc2VTY3JlZW4oKTsKKyAgICB9CisKKyAgICBpZiAod2hhdCAmIGVDb25zb2xlUmVsZWFzZWQpIHsKKyAgICAgICAgaWYgKGh3LmNhbkRyYXcoKSkgeworICAgICAgICAgICAgcmV2b2tlR1BVKCk7CisgICAgICAgICAgICBody5yZWxlYXNlU2NyZWVuKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtRGVmZXJSZWxlYXNlQ29uc29sZSA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBtRGlydHlSZWdpb24uc2V0KGh3LmJvdW5kcygpKTsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6aGFuZGxlVHJhbnNhY3Rpb24odWludDMyX3QgdHJhbnNhY3Rpb25GbGFncykKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisKKyAgICBjb25zdCBMYXllclZlY3RvciYgY3VycmVudExheWVycyA9IG1DdXJyZW50U3RhdGUubGF5ZXJzU29ydGVkQnlaOworICAgIGNvbnN0IHNpemVfdCBjb3VudCA9IGN1cnJlbnRMYXllcnMuc2l6ZSgpOworCisgICAgLyoKKyAgICAgKiBUcmF2ZXJzYWwgb2YgdGhlIGNoaWxkcmVuCisgICAgICogKHBlcmZvcm0gdGhlIHRyYW5zYWN0aW9uIGZvciBlYWNoIG9mIHRoZW0gaWYgbmVlZGVkKQorICAgICAqLworCisgICAgY29uc3QgYm9vbCBsYXllcnNOZWVkVHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvbkZsYWdzICYgZVRyYXZlcnNhbE5lZWRlZDsKKyAgICBpZiAobGF5ZXJzTmVlZFRyYW5zYWN0aW9uKSB7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyBpKyspIHsKKyAgICAgICAgICAgIExheWVyQmFzZSogY29uc3QgbGF5ZXIgPSBjdXJyZW50TGF5ZXJzW2ldOworICAgICAgICAgICAgdWludDMyX3QgdHJGbGFncyA9IGxheWVyLT5nZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZCk7CisgICAgICAgICAgICBpZiAoIXRyRmxhZ3MpIGNvbnRpbnVlOworCisgICAgICAgICAgICBjb25zdCB1aW50MzJfdCBmbGFncyA9IGxheWVyLT5kb1RyYW5zYWN0aW9uKDApOworICAgICAgICAgICAgaWYgKGZsYWdzICYgTGF5ZXI6OmVWaXNpYmxlUmVnaW9uKQorICAgICAgICAgICAgICAgIG1WaXNpYmxlUmVnaW9uc0RpcnR5ID0gdHJ1ZTsKKworICAgICAgICAgICAgaWYgKGZsYWdzICYgTGF5ZXI6OmVSZXN0YXJ0VHJhbnNhY3Rpb24pIHsKKyAgICAgICAgICAgICAgICAvLyByZXN0YXJ0IHRoZSB0cmFuc2FjdGlvbiwgYnV0IGJhY2stb2ZmIGEgbGl0dGxlCisgICAgICAgICAgICAgICAgbGF5ZXItPnNldFRyYW5zYWN0aW9uRmxhZ3MoZVRyYW5zYWN0aW9uTmVlZGVkKTsKKyAgICAgICAgICAgICAgICBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmF2ZXJzYWxOZWVkZWQsIG1zMm5zKDgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogUGVyZm9ybSBvdXIgb3duIHRyYW5zYWN0aW9uIGlmIG5lZWRlZAorICAgICAqLworCisgICAgaWYgKHRyYW5zYWN0aW9uRmxhZ3MgJiBlVHJhbnNhY3Rpb25OZWVkZWQpIHsKKyAgICAgICAgaWYgKG1DdXJyZW50U3RhdGUub3JpZW50YXRpb24gIT0gbURyYXdpbmdTdGF0ZS5vcmllbnRhdGlvbikgeworICAgICAgICAgICAgLy8gdGhlIG9yaWVudGF0aW9uIGhhcyBjaGFuZ2VkLCByZWNvbXB1dGUgYWxsIHZpc2libGUgcmVnaW9ucworICAgICAgICAgICAgLy8gYW5kIGludmFsaWRhdGUgZXZlcnl0aGluZy4KKworICAgICAgICAgICAgY29uc3QgaW50IGRweSA9IDA7CisgICAgICAgICAgICBjb25zdCBpbnQgb3JpZW50YXRpb24gPSBtQ3VycmVudFN0YXRlLm9yaWVudGF0aW9uOworICAgICAgICAgICAgR3JhcGhpY1BsYW5lJiBwbGFuZShncmFwaGljUGxhbmUoZHB5KSk7CisgICAgICAgICAgICBwbGFuZS5zZXRPcmllbnRhdGlvbihvcmllbnRhdGlvbik7CisKKyAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgc2hhcmVkIGNvbnRyb2wgYmxvY2sKKyAgICAgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcocGxhbmUuZGlzcGxheUhhcmR3YXJlKCkpOworICAgICAgICAgICAgdm9sYXRpbGUgZGlzcGxheV9jYmxrX3QqIGRjYmxrID0gbVNlcnZlckNibGstPmRpc3BsYXlzICsgZHB5OworICAgICAgICAgICAgZGNibGstPm9yaWVudGF0aW9uID0gb3JpZW50YXRpb247CisgICAgICAgICAgICBpZiAob3JpZW50YXRpb24gJiBlT3JpZW50YXRpb25Td2FwTWFzaykgeworICAgICAgICAgICAgICAgIC8vIDkwIG9yIDI3MCBkZWdyZWVzIG9yaWVudGF0aW9uCisgICAgICAgICAgICAgICAgZGNibGstPncgPSBody5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgICAgICBkY2Jsay0+aCA9IGh3LmdldFdpZHRoKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRjYmxrLT53ID0gaHcuZ2V0V2lkdGgoKTsKKyAgICAgICAgICAgICAgICBkY2Jsay0+aCA9IGh3LmdldEhlaWdodCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBtVmlzaWJsZVJlZ2lvbnNEaXJ0eSA9IHRydWU7CisgICAgICAgICAgICBtRGlydHlSZWdpb24uc2V0KGh3LmJvdW5kcygpKTsKKworICAgICAgICAgICAgbU9yaWVudGF0aW9uQW5pbWF0aW9uLT5vbk9yaWVudGF0aW9uQ2hhbmdlZCgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG1DdXJyZW50U3RhdGUuZnJlZXplRGlzcGxheSAhPSBtRHJhd2luZ1N0YXRlLmZyZWV6ZURpc3BsYXkpIHsKKyAgICAgICAgICAgIC8vIGZyZWV6aW5nIG9yIHVuZnJlZXppbmcgdGhlIGRpc3BsYXkgLT4gdHJpZ2dlciBhbmltYXRpb24gaWYgbmVlZGVkCisgICAgICAgICAgICBtRnJlZXplRGlzcGxheSA9IG1DdXJyZW50U3RhdGUuZnJlZXplRGlzcGxheTsKKyAgICAgICAgICAgIGNvbnN0IG5zZWNzX3Qgbm93ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgICAgaWYgKG1GcmVlemVEaXNwbGF5KSB7CisgICAgICAgICAgICAgICAgbUZyZWV6ZURpc3BsYXlUaW1lID0gbm93OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvL0xPR0QoIlNjcmVlbiB3YXMgZnJvemVuIGZvciAlbGx1IHVzIiwKKyAgICAgICAgICAgICAgICAvLyAgICAgICAgbnMydXMobm93LW1GcmVlemVEaXNwbGF5VGltZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc29tZSBsYXllcnMgbWlnaHQgaGF2ZSBiZWVuIHJlbW92ZWQsIHNvCisgICAgICAgIC8vIHdlIG5lZWQgdG8gdXBkYXRlIHRoZSByZWdpb25zIHRoZXkncmUgZXhwb3NpbmcuCisgICAgICAgIHNpemVfdCBjID0gbVJlbW92ZWRMYXllcnMuc2l6ZSgpOworICAgICAgICBpZiAoYykgeworICAgICAgICAgICAgbVZpc2libGVSZWdpb25zRGlydHkgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgY29uc3QgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMgPSBtQ3VycmVudFN0YXRlLmxheWVyc1NvcnRlZEJ5WjsKKyAgICAgICAgaWYgKGN1cnJlbnRMYXllcnMuc2l6ZSgpID4gbURyYXdpbmdTdGF0ZS5sYXllcnNTb3J0ZWRCeVouc2l6ZSgpKSB7CisgICAgICAgICAgICAvLyBsYXllcnMgaGF2ZSBiZWVuIGFkZGVkCisgICAgICAgICAgICBtVmlzaWJsZVJlZ2lvbnNEaXJ0eSA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBnZXQgcmlkIG9mIGFsbCByZXNvdXJjZXMgd2UgZG9uJ3QgbmVlZCBhbnltb3JlCisgICAgICAgIC8vIChsYXllcnMgYW5kIGNsaWVudHMpCisgICAgICAgIGZyZWVfcmVzb3VyY2VzX2woKTsKKyAgICB9CisKKyAgICBjb21taXRUcmFuc2FjdGlvbigpOworfQorCitzcDxGcmVlemVMb2NrPiBTdXJmYWNlRmxpbmdlcjo6Z2V0RnJlZXplTG9jaygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG5ldyBGcmVlemVMb2NrKGNvbnN0X2Nhc3Q8U3VyZmFjZUZsaW5nZXIgKj4odGhpcykpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpjb21wdXRlVmlzaWJsZVJlZ2lvbnMoCisgICAgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMsIFJlZ2lvbiYgZGlydHlSZWdpb24sIFJlZ2lvbiYgb3BhcXVlUmVnaW9uKQoreworICAgIGNvbnN0IEdyYXBoaWNQbGFuZSYgcGxhbmUoZ3JhcGhpY1BsYW5lKDApKTsKKyAgICBjb25zdCBUcmFuc2Zvcm0mIHBsYW5lVHJhbnNmb3JtKHBsYW5lLnRyYW5zZm9ybSgpKTsKKworICAgIFJlZ2lvbiBhYm92ZU9wYXF1ZUxheWVyczsKKyAgICBSZWdpb24gYWJvdmVDb3ZlcmVkTGF5ZXJzOworICAgIFJlZ2lvbiBkaXJ0eTsKKworICAgIGJvb2wgc2VjdXJlRnJhbWVCdWZmZXIgPSBmYWxzZTsKKworICAgIHNpemVfdCBpID0gY3VycmVudExheWVycy5zaXplKCk7CisgICAgd2hpbGUgKGktLSkgeworICAgICAgICBMYXllckJhc2UqIGNvbnN0IGxheWVyID0gY3VycmVudExheWVyc1tpXTsKKyAgICAgICAgbGF5ZXItPnZhbGlkYXRlVmlzaWJpbGl0eShwbGFuZVRyYW5zZm9ybSk7CisKKyAgICAgICAgLy8gc3RhcnQgd2l0aCB0aGUgd2hvbGUgc3VyZmFjZSBhdCBpdHMgY3VycmVudCBsb2NhdGlvbgorICAgICAgICBjb25zdCBMYXllcjo6U3RhdGUmIHMgPSBsYXllci0+ZHJhd2luZ1N0YXRlKCk7CisgICAgICAgIGNvbnN0IFJlY3QgYm91bmRzKGxheWVyLT52aXNpYmxlQm91bmRzKCkpOworCisgICAgICAgIC8vIGhhbmRsZSBoaWRkZW4gc3VyZmFjZXMgYnkgc2V0dGluZyB0aGUgdmlzaWJsZSByZWdpb24gdG8gZW1wdHkKKyAgICAgICAgUmVnaW9uIG9wYXF1ZVJlZ2lvbjsKKyAgICAgICAgUmVnaW9uIHZpc2libGVSZWdpb247CisgICAgICAgIFJlZ2lvbiBjb3ZlcmVkUmVnaW9uOworICAgICAgICBpZiAoVU5MSUtFTFkoKHMuZmxhZ3MgJiBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJIaWRkZW4pIHx8ICFzLmFscGhhKSkgeworICAgICAgICAgICAgdmlzaWJsZVJlZ2lvbi5jbGVhcigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29uc3QgYm9vbCB0cmFuc2x1Y2VudCA9IGxheWVyLT5uZWVkc0JsZW5kaW5nKCk7CisgICAgICAgICAgICB2aXNpYmxlUmVnaW9uLnNldChib3VuZHMpOworICAgICAgICAgICAgY292ZXJlZFJlZ2lvbiA9IHZpc2libGVSZWdpb247CisKKyAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgdHJhbnNwYXJlbnQgYXJlYSBmcm9tIHRoZSB2aXNpYmxlIHJlZ2lvbgorICAgICAgICAgICAgaWYgKHRyYW5zbHVjZW50KSB7CisgICAgICAgICAgICAgICAgdmlzaWJsZVJlZ2lvbi5zdWJ0cmFjdFNlbGYobGF5ZXItPnRyYW5zcGFyZW50UmVnaW9uU2NyZWVuKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgb3BhcXVlIHJlZ2lvbgorICAgICAgICAgICAgaWYgKHMuYWxwaGE9PTI1NSAmJiAhdHJhbnNsdWNlbnQgJiYgbGF5ZXItPmdldE9yaWVudGF0aW9uKCk+PTApIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgb3BhcXVlIHJlZ2lvbiBpcyB0aGUgdmlzaWJsZSByZWdpb24KKyAgICAgICAgICAgICAgICBvcGFxdWVSZWdpb24gPSB2aXNpYmxlUmVnaW9uOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc3VidHJhY3QgdGhlIG9wYXF1ZSByZWdpb24gY292ZXJlZCBieSB0aGUgbGF5ZXJzIGFib3ZlIHVzCisgICAgICAgIHZpc2libGVSZWdpb24uc3VidHJhY3RTZWxmKGFib3ZlT3BhcXVlTGF5ZXJzKTsKKyAgICAgICAgY292ZXJlZFJlZ2lvbi5hbmRTZWxmKGFib3ZlQ292ZXJlZExheWVycyk7CisKKyAgICAgICAgLy8gY29tcHV0ZSB0aGlzIGxheWVyJ3MgZGlydHkgcmVnaW9uCisgICAgICAgIGlmIChsYXllci0+Y29udGVudERpcnR5KSB7CisgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGludmFsaWRhdGUgdGhlIHdob2xlIHJlZ2lvbgorICAgICAgICAgICAgZGlydHkgPSB2aXNpYmxlUmVnaW9uOworICAgICAgICAgICAgLy8gYXMgd2VsbCwgYXMgdGhlIG9sZCB2aXNpYmxlIHJlZ2lvbgorICAgICAgICAgICAgZGlydHkub3JTZWxmKGxheWVyLT52aXNpYmxlUmVnaW9uU2NyZWVuKTsKKyAgICAgICAgICAgIGxheWVyLT5jb250ZW50RGlydHkgPSBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIGV4cG9zZWQgcmVnaW9uCisgICAgICAgICAgICAvLyBkaXJ0eSA9IHdoYXQncyB2aXNpYmxlIG5vdyAtIHdoYXQncyB3YXNuJ3QgY292ZXJlZCBiZWZvcmUKKyAgICAgICAgICAgIC8vICAgICAgID0gd2hhdCdzIHZpc2libGUgbm93ICYgd2hhdCdzIHdhcyBjb3ZlcmVkIGJlZm9yZQorICAgICAgICAgICAgZGlydHkgPSB2aXNpYmxlUmVnaW9uLmludGVyc2VjdChsYXllci0+Y292ZXJlZFJlZ2lvblNjcmVlbik7ICAgICAgICAgICAgCisgICAgICAgIH0KKyAgICAgICAgZGlydHkuc3VidHJhY3RTZWxmKGFib3ZlT3BhcXVlTGF5ZXJzKTsKKworICAgICAgICAvLyBhY2N1bXVsYXRlIHRvIHRoZSBzY3JlZW4gZGlydHkgcmVnaW9uCisgICAgICAgIGRpcnR5UmVnaW9uLm9yU2VsZihkaXJ0eSk7CisKKyAgICAgICAgLy8gdXBkYWRlIGFib3ZlT3BhcXVlTGF5ZXJzL2Fib3ZlQ292ZXJlZExheWVycyBmb3IgbmV4dCAobG93ZXIpIGxheWVyCisgICAgICAgIGFib3ZlT3BhcXVlTGF5ZXJzLm9yU2VsZihvcGFxdWVSZWdpb24pOworICAgICAgICBhYm92ZUNvdmVyZWRMYXllcnMub3JTZWxmKGJvdW5kcyk7CisgICAgICAgIAorICAgICAgICAvLyBTdG9yZSB0aGUgdmlzaWJsZSByZWdpb24gaXMgc2NyZWVuIHNwYWNlCisgICAgICAgIGxheWVyLT5zZXRWaXNpYmxlUmVnaW9uKHZpc2libGVSZWdpb24pOworICAgICAgICBsYXllci0+c2V0Q292ZXJlZFJlZ2lvbihjb3ZlcmVkUmVnaW9uKTsKKworICAgICAgICAvLyBJZiBhIHNlY3VyZSBsYXllciBpcyBwYXJ0aWFsbHkgdmlzaWJsZSwgbG9ja2Rvd24gdGhlIHNjcmVlbiEKKyAgICAgICAgaWYgKGxheWVyLT5pc1NlY3VyZSgpICYmICF2aXNpYmxlUmVnaW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgc2VjdXJlRnJhbWVCdWZmZXIgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgbVNlY3VyZUZyYW1lQnVmZmVyID0gc2VjdXJlRnJhbWVCdWZmZXI7CisgICAgb3BhcXVlUmVnaW9uID0gYWJvdmVPcGFxdWVMYXllcnM7Cit9CisKKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6Y29tbWl0VHJhbnNhY3Rpb24oKQoreworICAgIG1EcmF3aW5nU3RhdGUgPSBtQ3VycmVudFN0YXRlOworICAgIG1UcmFuc2FjdGlvbkNWLnNpZ25hbCgpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpoYW5kbGVQYWdlRmxpcCgpCit7CisgICAgYm9vbCB2aXNpYmxlUmVnaW9ucyA9IG1WaXNpYmxlUmVnaW9uc0RpcnR5OworICAgIExheWVyVmVjdG9yJiBjdXJyZW50TGF5ZXJzID0gY29uc3RfY2FzdDxMYXllclZlY3RvciY+KG1EcmF3aW5nU3RhdGUubGF5ZXJzU29ydGVkQnlaKTsKKyAgICB2aXNpYmxlUmVnaW9ucyB8PSBsb2NrUGFnZUZsaXAoY3VycmVudExheWVycyk7CisKKyAgICAgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyA9IGdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKTsKKyAgICAgICAgY29uc3QgUmVnaW9uIHNjcmVlblJlZ2lvbihody5ib3VuZHMoKSk7CisgICAgICAgIGlmICh2aXNpYmxlUmVnaW9ucykgeworICAgICAgICAgICAgUmVnaW9uIG9wYXF1ZVJlZ2lvbjsKKyAgICAgICAgICAgIGNvbXB1dGVWaXNpYmxlUmVnaW9ucyhjdXJyZW50TGF5ZXJzLCBtRGlydHlSZWdpb24sIG9wYXF1ZVJlZ2lvbik7CisgICAgICAgICAgICBtV29ybWhvbGVSZWdpb24gPSBzY3JlZW5SZWdpb24uc3VidHJhY3Qob3BhcXVlUmVnaW9uKTsKKyAgICAgICAgICAgIG1WaXNpYmxlUmVnaW9uc0RpcnR5ID0gZmFsc2U7CisgICAgICAgIH0KKworICAgIHVubG9ja1BhZ2VGbGlwKGN1cnJlbnRMYXllcnMpOworICAgIG1EaXJ0eVJlZ2lvbi5hbmRTZWxmKHNjcmVlblJlZ2lvbik7Cit9CisKK2Jvb2wgU3VyZmFjZUZsaW5nZXI6OmxvY2tQYWdlRmxpcChjb25zdCBMYXllclZlY3RvciYgY3VycmVudExheWVycykKK3sKKyAgICBib29sIHJlY29tcHV0ZVZpc2libGVSZWdpb25zID0gZmFsc2U7CisgICAgc2l6ZV90IGNvdW50ID0gY3VycmVudExheWVycy5zaXplKCk7CisgICAgTGF5ZXJCYXNlKiBjb25zdCogbGF5ZXJzID0gY3VycmVudExheWVycy5hcnJheSgpOworICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyBpKyspIHsKKyAgICAgICAgTGF5ZXJCYXNlKiBjb25zdCBsYXllciA9IGxheWVyc1tpXTsKKyAgICAgICAgbGF5ZXItPmxvY2tQYWdlRmxpcChyZWNvbXB1dGVWaXNpYmxlUmVnaW9ucyk7CisgICAgfQorICAgIHJldHVybiByZWNvbXB1dGVWaXNpYmxlUmVnaW9uczsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6dW5sb2NrUGFnZUZsaXAoY29uc3QgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMpCit7CisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiBwbGFuZShncmFwaGljUGxhbmUoMCkpOworICAgIGNvbnN0IFRyYW5zZm9ybSYgcGxhbmVUcmFuc2Zvcm0ocGxhbmUudHJhbnNmb3JtKCkpOworICAgIHNpemVfdCBjb3VudCA9IGN1cnJlbnRMYXllcnMuc2l6ZSgpOworICAgIExheWVyQmFzZSogY29uc3QqIGxheWVycyA9IGN1cnJlbnRMYXllcnMuYXJyYXkoKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgIExheWVyQmFzZSogY29uc3QgbGF5ZXIgPSBsYXllcnNbaV07CisgICAgICAgIGxheWVyLT51bmxvY2tQYWdlRmxpcChwbGFuZVRyYW5zZm9ybSwgbURpcnR5UmVnaW9uKTsKKyAgICB9Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmhhbmRsZVJlcGFpbnQoKQoreworICAgIC8vIHNldCB0aGUgZnJhbWUgYnVmZmVyCisgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIGdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOworICAgIGdsTG9hZElkZW50aXR5KCk7CisKKyAgICBpZiAoVU5MSUtFTFkobURlYnVnUmVnaW9uKSkgeworICAgICAgICBkZWJ1Z0ZsYXNoUmVnaW9ucygpOworICAgIH0KKworICAgIC8vIGNvbXB1dGUgdGhlIGludmFsaWQgcmVnaW9uCisgICAgbUludmFsaWRSZWdpb24ub3JTZWxmKG1EaXJ0eVJlZ2lvbik7CisKKyAgICB1aW50MzJfdCBmbGFncyA9IGh3LmdldEZsYWdzKCk7CisgICAgaWYgKGZsYWdzICYgRGlzcGxheUhhcmR3YXJlOjpCVUZGRVJfUFJFU0VSVkVEKSB7CisgICAgICAgIC8vIGhlcmUgd2UgYXNzdW1lIERpc3BsYXlIYXJkd2FyZTo6ZmxpcCgpJ3MgIGltcGxlbWVudGF0aW9uCisgICAgICAgIC8vIHBlcmZvcm1zIHRoZSBjb3B5LWJhY2sgb3B0aW1pemF0aW9uLgorICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChmbGFncyAmIERpc3BsYXlIYXJkd2FyZTo6VVBEQVRFX09OX0RFTUFORCkgeworICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBmdWxseSByZWRyYXcgdGhlIHBhcnQgdGhhdCB3aWxsIGJlIHVwZGF0ZWQKKyAgICAgICAgICAgIG1EaXJ0eVJlZ2lvbi5zZXQobUludmFsaWRSZWdpb24uYm91bmRzKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gd2UgbmVlZCB0byByZWRyYXcgZXZlcnl0aGluZworICAgICAgICAgICAgbURpcnR5UmVnaW9uLnNldChody5ib3VuZHMoKSk7CisgICAgICAgICAgICBtSW52YWxpZFJlZ2lvbiA9IG1EaXJ0eVJlZ2lvbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGNvbXBvc2UgYWxsIHN1cmZhY2VzCisgICAgY29tcG9zZVN1cmZhY2VzKG1EaXJ0eVJlZ2lvbik7CisKKyAgICAvLyBjbGVhciB0aGUgZGlydHkgcmVnaW9ucworICAgIG1EaXJ0eVJlZ2lvbi5jbGVhcigpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpjb21wb3NlU3VyZmFjZXMoY29uc3QgUmVnaW9uJiBkaXJ0eSkKK3sKKyAgICBpZiAoVU5MSUtFTFkoIW1Xb3JtaG9sZVJlZ2lvbi5pc0VtcHR5KCkpKSB7CisgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4gdW5sZXNzIHRoZSB3aW5kb3cgbWFuYWdlciBoYXMgYSBidWcKKyAgICAgICAgLy8gZHJhdyBzb21ldGhpbmcuLi4KKyAgICAgICAgZHJhd1dvcm1ob2xlKCk7CisgICAgfQorICAgIGNvbnN0IFN1cmZhY2VGbGluZ2VyJiBmbGluZ2VyKCp0aGlzKTsKKyAgICBjb25zdCBMYXllclZlY3RvciYgZHJhd2luZ0xheWVycyhtRHJhd2luZ1N0YXRlLmxheWVyc1NvcnRlZEJ5Wik7CisgICAgY29uc3Qgc2l6ZV90IGNvdW50ID0gZHJhd2luZ0xheWVycy5zaXplKCk7CisgICAgTGF5ZXJCYXNlIGNvbnN0KiBjb25zdCogY29uc3QgbGF5ZXJzID0gZHJhd2luZ0xheWVycy5hcnJheSgpOworICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyArK2kpIHsKKyAgICAgICAgTGF5ZXJCYXNlIGNvbnN0ICogY29uc3QgbGF5ZXIgPSBsYXllcnNbaV07CisgICAgICAgIGNvbnN0IFJlZ2lvbiYgdmlzaWJsZVJlZ2lvbihsYXllci0+dmlzaWJsZVJlZ2lvblNjcmVlbik7CisgICAgICAgIGlmICghdmlzaWJsZVJlZ2lvbi5pc0VtcHR5KCkpICB7CisgICAgICAgICAgICBjb25zdCBSZWdpb24gY2xpcChkaXJ0eS5pbnRlcnNlY3QodmlzaWJsZVJlZ2lvbikpOworICAgICAgICAgICAgaWYgKCFjbGlwLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIGxheWVyLT5kcmF3KGNsaXApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjp1bmxvY2tDbGllbnRzKCkKK3sKKyAgICBjb25zdCBMYXllclZlY3RvciYgZHJhd2luZ0xheWVycyhtRHJhd2luZ1N0YXRlLmxheWVyc1NvcnRlZEJ5Wik7CisgICAgY29uc3Qgc2l6ZV90IGNvdW50ID0gZHJhd2luZ0xheWVycy5zaXplKCk7CisgICAgTGF5ZXJCYXNlKiBjb25zdCogY29uc3QgbGF5ZXJzID0gZHJhd2luZ0xheWVycy5hcnJheSgpOworICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyArK2kpIHsKKyAgICAgICAgTGF5ZXJCYXNlKiBjb25zdCBsYXllciA9IGxheWVyc1tpXTsKKyAgICAgICAgbGF5ZXItPmZpbmlzaFBhZ2VGbGlwKCk7CisgICAgfQorfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpzY2hlZHVsZUJyb2FkY2FzdChDbGllbnQqIGNsaWVudCkKK3sKKyAgICBpZiAobUxhc3RTY2hlZHVsZWRCcm9hZGNhc3QgIT0gY2xpZW50KSB7CisgICAgICAgIG1MYXN0U2NoZWR1bGVkQnJvYWRjYXN0ID0gY2xpZW50OworICAgICAgICBtU2NoZWR1bGVkQnJvYWRjYXN0cy5hZGQoY2xpZW50KTsKKyAgICB9Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmV4ZWN1dGVTY2hlZHVsZWRCcm9hZGNhc3RzKCkKK3sKKyAgICBTb3J0ZWRWZWN0b3I8Q2xpZW50Kj4mIGxpc3QgPSBtU2NoZWR1bGVkQnJvYWRjYXN0czsKKyAgICBzaXplX3QgY291bnQgPSBsaXN0LnNpemUoKTsKKyAgICB3aGlsZSAoY291bnQtLSkgeworICAgICAgICBwZXJfY2xpZW50X2NibGtfdCogY29uc3QgY2JsayA9IGxpc3RbY291bnRdLT5jdHJsYmxrOworICAgICAgICBpZiAoY2Jsay0+bG9jay50cnlMb2NrKCkgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgIGNibGstPmN2LmJyb2FkY2FzdCgpOworICAgICAgICAgICAgbGlzdC5yZW1vdmVBdChjb3VudCk7CisgICAgICAgICAgICBjYmxrLT5sb2NrLnVubG9jaygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gc2NoZWR1bGUgYW5vdGhlciByb3VuZAorICAgICAgICAgICAgTE9HVygiZXhlY3V0ZVNjaGVkdWxlZEJyb2FkY2FzdHMoKSBza2lwcGVkLCAiCisgICAgICAgICAgICAgICAgImNvbnRlbnRpb24gb24gdGhlIGNsaWVudC4gV2UnbGwgdHJ5IGFnYWluIGxhdGVyLi4uIik7CisgICAgICAgICAgICBzaWduYWxEZWxheWVkRXZlbnQobXMybnMoNCkpOworICAgICAgICB9CisgICAgfQorICAgIG1MYXN0U2NoZWR1bGVkQnJvYWRjYXN0ID0gMDsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6aGFuZGxlRGVidWdDcHUoKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtRGVidWdMb2NrKTsKKyAgICBpZiAobUNwdUdhdWdlICE9IDApCisgICAgICAgIG1DcHVHYXVnZS0+c2FtcGxlKCk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmRlYnVnRmxhc2hSZWdpb25zKCkKK3sKKyAgICBpZiAoVU5MSUtFTFkoIW1EaXJ0eVJlZ2lvbi5pc1JlY3QoKSkpIHsKKyAgICAgICAgLy8gVE9ETzogZG8gdGhpcyBvbmx5IGlmIHdlIGRvbid0IGhhdmUgcHJlc2VydmluZworICAgICAgICAvLyBzd2FwQnVmZmVyLiBJZiB3ZSBkb24ndCBoYXZlIHVwZGF0ZS1vbi1kZW1hbmQsCisgICAgICAgIC8vIHJlZHJhdyBldmVyeXRoaW5nLgorICAgICAgICBjb21wb3NlU3VyZmFjZXMoUmVnaW9uKG1EaXJ0eVJlZ2lvbi5ib3VuZHMoKSkpOworICAgIH0KKworICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKKyAgICBnbERpc2FibGUoR0xfQkxFTkQpOworICAgIGdsRGlzYWJsZShHTF9ESVRIRVIpOworICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOworCisgICAgZ2xDb2xvcjR4KDB4MTAwMDAsIDAsIDB4MTAwMDAsIDB4MTAwMDApOworCisgICAgUmVjdCByOworICAgIFJlZ2lvbjo6aXRlcmF0b3IgaXRlcmF0b3IobURpcnR5UmVnaW9uKTsKKyAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgR0xmbG9hdCB2ZXJ0aWNlc1tdWzJdID0geworICAgICAgICAgICAgICAgIHsgci5sZWZ0LCAgci50b3AgfSwKKyAgICAgICAgICAgICAgICB7IHIubGVmdCwgIHIuYm90dG9tIH0sCisgICAgICAgICAgICAgICAgeyByLnJpZ2h0LCByLmJvdHRvbSB9LAorICAgICAgICAgICAgICAgIHsgci5yaWdodCwgci50b3AgfQorICAgICAgICB9OworICAgICAgICBnbFZlcnRleFBvaW50ZXIoMiwgR0xfRkxPQVQsIDAsIHZlcnRpY2VzKTsKKyAgICAgICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFX0ZBTiwgMCwgNCk7CisgICAgfQorCisgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworICAgIGh3LmZsaXAobURpcnR5UmVnaW9uLm1lcmdlKG1JbnZhbGlkUmVnaW9uKSk7CisgICAgbUludmFsaWRSZWdpb24uY2xlYXIoKTsKKworICAgIGlmIChtRGVidWdSZWdpb24gPiAxKQorICAgICAgIHVzbGVlcChtRGVidWdSZWdpb24gKiAxMDAwKTsKKworICAgIGdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCk7CisgICAgLy9tRGlydHlSZWdpb24uZHVtcCgibURpcnR5UmVnaW9uIik7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmRyYXdXb3JtaG9sZSgpIGNvbnN0Cit7CisgICAgY29uc3QgUmVnaW9uIHJlZ2lvbihtV29ybWhvbGVSZWdpb24uaW50ZXJzZWN0KG1EaXJ0eVJlZ2lvbikpOworICAgIGlmIChyZWdpb24uaXNFbXB0eSgpKQorICAgICAgICByZXR1cm47CisKKyAgICBjb25zdCBEaXNwbGF5SGFyZHdhcmUmIGh3KGdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKSk7CisgICAgY29uc3QgaW50MzJfdCB3aWR0aCA9IGh3LmdldFdpZHRoKCk7CisgICAgY29uc3QgaW50MzJfdCBoZWlnaHQgPSBody5nZXRIZWlnaHQoKTsKKworICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CisgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisKKyAgICBpZiAoTElLRUxZKCFtRGVidWdCYWNrZ3JvdW5kKSkgeworICAgICAgICBnbENsZWFyQ29sb3J4KDAsMCwwLDApOworICAgICAgICBSZWN0IHI7CisgICAgICAgIFJlZ2lvbjo6aXRlcmF0b3IgaXRlcmF0b3IocmVnaW9uKTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLml0ZXJhdGUoJnIpKSB7CisgICAgICAgICAgICBjb25zdCBHTGludCBzeSA9IGhlaWdodCAtIChyLnRvcCArIHIuaGVpZ2h0KCkpOworICAgICAgICAgICAgZ2xTY2lzc29yKHIubGVmdCwgc3ksIHIud2lkdGgoKSwgci5oZWlnaHQoKSk7CisgICAgICAgICAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgR0xzaG9ydCB2ZXJ0aWNlc1tdWzJdID0geyB7IDAsIDAgfSwgeyB3aWR0aCwgMCB9LAorICAgICAgICAgICAgICAgIHsgd2lkdGgsIGhlaWdodCB9LCB7IDAsIGhlaWdodCB9ICB9OworICAgICAgICBjb25zdCBHTHNob3J0IHRjb29yZHNbXVsyXSA9IHsgeyAwLCAwIH0sIHsgMSwgMCB9LCAgeyAxLCAxIH0sIHsgMCwgMSB9IH07CisgICAgICAgIGdsVmVydGV4UG9pbnRlcigyLCBHTF9TSE9SVCwgMCwgdmVydGljZXMpOworICAgICAgICBnbFRleENvb3JkUG9pbnRlcigyLCBHTF9TSE9SVCwgMCwgdGNvb3Jkcyk7CisgICAgICAgIGdsRW5hYmxlQ2xpZW50U3RhdGUoR0xfVEVYVFVSRV9DT09SRF9BUlJBWSk7CisgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOworICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIG1Xb3JtaG9sZVRleE5hbWUpOworICAgICAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOworICAgICAgICBnbE1hdHJpeE1vZGUoR0xfVEVYVFVSRSk7CisgICAgICAgIGdsTG9hZElkZW50aXR5KCk7CisgICAgICAgIGdsU2NhbGVmKHdpZHRoKigxLjBmLzMyLjBmKSwgaGVpZ2h0KigxLjBmLzMyLjBmKSwgMSk7CisgICAgICAgIFJlY3QgcjsKKyAgICAgICAgUmVnaW9uOjppdGVyYXRvciBpdGVyYXRvcihyZWdpb24pOworICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgICAgIGNvbnN0IEdMaW50IHN5ID0gaGVpZ2h0IC0gKHIudG9wICsgci5oZWlnaHQoKSk7CisgICAgICAgICAgICBnbFNjaXNzb3Ioci5sZWZ0LCBzeSwgci53aWR0aCgpLCByLmhlaWdodCgpKTsKKyAgICAgICAgICAgIGdsRHJhd0FycmF5cyhHTF9UUklBTkdMRV9GQU4sIDAsIDQpOworICAgICAgICB9CisgICAgICAgIGdsRGlzYWJsZUNsaWVudFN0YXRlKEdMX1RFWFRVUkVfQ09PUkRfQVJSQVkpOworICAgIH0KK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6ZGVidWdTaG93RlBTKCkgY29uc3QKK3sKKyAgICBzdGF0aWMgaW50IG1GcmFtZUNvdW50OworICAgIHN0YXRpYyBpbnQgbUxhc3RGcmFtZUNvdW50ID0gMDsKKyAgICBzdGF0aWMgbnNlY3NfdCBtTGFzdEZwc1RpbWUgPSAwOworICAgIHN0YXRpYyBmbG9hdCBtRnBzID0gMDsKKyAgICBtRnJhbWVDb3VudCsrOworICAgIG5zZWNzX3Qgbm93ID0gc3lzdGVtVGltZSgpOworICAgIG5zZWNzX3QgZGlmZiA9IG5vdyAtIG1MYXN0RnBzVGltZTsKKyAgICBpZiAoZGlmZiA+IG1zMm5zKDI1MCkpIHsKKyAgICAgICAgbUZwcyA9ICAoKG1GcmFtZUNvdW50IC0gbUxhc3RGcmFtZUNvdW50KSAqIGZsb2F0KHMybnMoMSkpKSAvIGRpZmY7CisgICAgICAgIG1MYXN0RnBzVGltZSA9IG5vdzsKKyAgICAgICAgbUxhc3RGcmFtZUNvdW50ID0gbUZyYW1lQ291bnQ7CisgICAgfQorICAgIC8vIFhYWDogbUZQUyBoYXMgdGhlIHZhbHVlIHdlIHdhbnQKKyB9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjphZGRMYXllcihMYXllckJhc2UqIGxheWVyKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtU3RhdGVMb2NrKTsKKyAgICBhZGRMYXllcl9sKGxheWVyKTsKKyAgICBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZHxlVHJhdmVyc2FsTmVlZGVkKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjpyZW1vdmVMYXllcihMYXllckJhc2UqIGxheWVyKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtU3RhdGVMb2NrKTsKKyAgICByZW1vdmVMYXllcl9sKGxheWVyKTsKKyAgICBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlRmxpbmdlcjo6aW52YWxpZGF0ZUxheWVyVmlzaWJpbGl0eShMYXllckJhc2UqIGxheWVyKQoreworICAgIGxheWVyLT5mb3JjZVZpc2liaWxpdHlUcmFuc2FjdGlvbigpOworICAgIHNldFRyYW5zYWN0aW9uRmxhZ3MoZVRyYXZlcnNhbE5lZWRlZCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlRmxpbmdlcjo6YWRkTGF5ZXJfbChMYXllckJhc2UqIGxheWVyKQoreworICAgIHNzaXplX3QgaSA9IG1DdXJyZW50U3RhdGUubGF5ZXJzU29ydGVkQnlaLmFkZCgKKyAgICAgICAgICAgICAgICBsYXllciwgJkxheWVyQmFzZTo6Y29tcGFyZUN1cnJlbnRTdGF0ZVopOworICAgIExheWVyQmFzZUNsaWVudCogbGJjID0gTGF5ZXJCYXNlOjpkeW5hbWljQ2FzdDxMYXllckJhc2VDbGllbnQqPihsYXllcik7CisgICAgaWYgKGxiYykgeworICAgICAgICBtTGF5ZXJNYXAuYWRkKGxiYy0+c2VydmVySW5kZXgoKSwgbGJjKTsKKyAgICB9CisgICAgbVJlbW92ZWRMYXllcnMucmVtb3ZlKGxheWVyKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjpyZW1vdmVMYXllcl9sKExheWVyQmFzZSogbGF5ZXJCYXNlKQoreworICAgIHNzaXplX3QgaW5kZXggPSBtQ3VycmVudFN0YXRlLmxheWVyc1NvcnRlZEJ5Wi5yZW1vdmUobGF5ZXJCYXNlKTsKKyAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICBtUmVtb3ZlZExheWVycy5hZGQobGF5ZXJCYXNlKTsKKyAgICAgICAgTGF5ZXJCYXNlQ2xpZW50KiBsYXllciA9IExheWVyQmFzZTo6ZHluYW1pY0Nhc3Q8TGF5ZXJCYXNlQ2xpZW50Kj4obGF5ZXJCYXNlKTsKKyAgICAgICAgaWYgKGxheWVyKSB7CisgICAgICAgICAgICBtTGF5ZXJNYXAucmVtb3ZlSXRlbShsYXllci0+c2VydmVySW5kZXgoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgd2UgZG9uJ3QgZmluZCBhIGxheWVyLCBiZWNhdXNlIGl0IG1pZ2h0CisgICAgLy8gaGF2ZSBiZWVuIGRlc3Ryb3llZCBhbHJlYWR5IC0tIHRoaXMgaXMgbm90IHRlY2huaWNhbGx5IGFuIGVycm9yCisgICAgLy8gZnJvbSB0aGUgdXNlciBiZWNhdXNlIHRoZXJlIGlzIGEgcmFjZSBiZXR3ZWVuIGRlc3Ryb3lTdXJmYWNlLAorICAgIC8vIGRlc3Ryb3ljbGllbnQgYW5kIGRlc3Ryb3lTdXJmYWNlLWZyb20tYS10cmFuc2FjdGlvbi4KKyAgICByZXR1cm4gKGluZGV4ID09IE5BTUVfTk9UX0ZPVU5EKSA/IHN0YXR1c190KE5PX0VSUk9SKSA6IGluZGV4OworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpmcmVlX3Jlc291cmNlc19sKCkKK3sKKyAgICAvLyBEZXN0cm95IGxheWVycyB0aGF0IHdlcmUgcmVtb3ZlZAorICAgIGRlc3Ryb3lfYWxsX3JlbW92ZWRfbGF5ZXJzX2woKTsKKworICAgIC8vIGZyZWUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCBkaXNjb25uZWN0ZWQgY2xpZW50cworICAgIFNvcnRlZFZlY3RvcjxDbGllbnQqPiYgc2NoZWR1bGVkQnJvYWRjYXN0cyhtU2NoZWR1bGVkQnJvYWRjYXN0cyk7CisgICAgVmVjdG9yPENsaWVudCo+JiBkaXNjb25uZWN0ZWRDbGllbnRzKG1EaXNjb25uZWN0ZWRDbGllbnRzKTsKKyAgICBjb25zdCBzaXplX3QgY291bnQgPSBkaXNjb25uZWN0ZWRDbGllbnRzLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgIENsaWVudCogY2xpZW50ID0gZGlzY29ubmVjdGVkQ2xpZW50c1tpXTsKKyAgICAgICAgLy8gaWYgdGhpcyBjbGllbnQgaXMgdGhlIHNjaGVkdWxlZCBicm9hZGNhc3QgbGlzdCwKKyAgICAgICAgLy8gcmVtb3ZlIGl0IGZyb20gdGhlcmUgKGFuZCB3ZSBkb24ndCBuZWVkIHRvIHNpZ25hbCBpdAorICAgICAgICAvLyBzaW5jZSBpdCBpcyBkZWFkKS4KKyAgICAgICAgaW50MzJfdCBpbmRleCA9IHNjaGVkdWxlZEJyb2FkY2FzdHMuaW5kZXhPZihjbGllbnQpOworICAgICAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICAgICAgc2NoZWR1bGVkQnJvYWRjYXN0cy5yZW1vdmVJdGVtc0F0KGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBtVG9rZW5zLnJlbGVhc2UoY2xpZW50LT5jaWQpOworICAgICAgICBkZWxldGUgY2xpZW50OworICAgIH0KKyAgICBkaXNjb25uZWN0ZWRDbGllbnRzLmNsZWFyKCk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OmRlc3Ryb3lfYWxsX3JlbW92ZWRfbGF5ZXJzX2woKQoreworICAgIHNpemVfdCBjID0gbVJlbW92ZWRMYXllcnMuc2l6ZSgpOworICAgIHdoaWxlIChjLS0pIHsKKyAgICAgICAgTGF5ZXJCYXNlKiBjb25zdCByZW1vdmVkX2xheWVyID0gbVJlbW92ZWRMYXllcnNbY107CisKKyAgICAgICAgTE9HRV9JRihtQ3VycmVudFN0YXRlLmxheWVyc1NvcnRlZEJ5Wi5pbmRleE9mKHJlbW92ZWRfbGF5ZXIpID49IDAsCisgICAgICAgICAgICAibGF5ZXIgJXAgcmVtb3ZlZCBidXQgc3RpbGwgaW4gdGhlIGN1cnJlbnQgc3RhdGUgbGlzdCIsCisgICAgICAgICAgICByZW1vdmVkX2xheWVyKTsKKworICAgICAgICBkZWxldGUgcmVtb3ZlZF9sYXllcjsKKyAgICB9CisgICAgbVJlbW92ZWRMYXllcnMuY2xlYXIoKTsKK30KKworCit1aW50MzJfdCBTdXJmYWNlRmxpbmdlcjo6Z2V0VHJhbnNhY3Rpb25GbGFncyh1aW50MzJfdCBmbGFncykKK3sKKyAgICByZXR1cm4gYW5kcm9pZF9hdG9taWNfYW5kKH5mbGFncywgJm1UcmFuc2FjdGlvbkZsYWdzKSAmIGZsYWdzOworfQorCit1aW50MzJfdCBTdXJmYWNlRmxpbmdlcjo6c2V0VHJhbnNhY3Rpb25GbGFncyh1aW50MzJfdCBmbGFncywgbnNlY3NfdCBkZWxheSkKK3sKKyAgICB1aW50MzJfdCBvbGQgPSBhbmRyb2lkX2F0b21pY19vcihmbGFncywgJm1UcmFuc2FjdGlvbkZsYWdzKTsKKyAgICBpZiAoKG9sZCAmIGZsYWdzKT09MCkgeyAvLyB3YWtlIHRoZSBzZXJ2ZXIgdXAKKyAgICAgICAgaWYgKGRlbGF5ID4gMCkgeworICAgICAgICAgICAgc2lnbmFsRGVsYXllZEV2ZW50KGRlbGF5KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNpZ25hbEV2ZW50KCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG9sZDsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6b3Blbkdsb2JhbFRyYW5zYWN0aW9uKCkKK3sKKyAgICBhbmRyb2lkX2F0b21pY19pbmMoJm1UcmFuc2FjdGlvbkNvdW50KTsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlcjo6Y2xvc2VHbG9iYWxUcmFuc2FjdGlvbigpCit7CisgICAgaWYgKGFuZHJvaWRfYXRvbWljX2RlYygmbVRyYW5zYWN0aW9uQ291bnQpID09IDEpIHsKKyAgICAgICAgc2lnbmFsRXZlbnQoKTsKKyAgICB9Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjpmcmVlemVEaXNwbGF5KERpc3BsYXlJRCBkcHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIGlmIChVTkxJS0VMWSh1aW50MzJfdChkcHkpID49IERJU1BMQVlfQ09VTlQpKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1TdGF0ZUxvY2spOworICAgIG1DdXJyZW50U3RhdGUuZnJlZXplRGlzcGxheSA9IDE7CisgICAgc2V0VHJhbnNhY3Rpb25GbGFncyhlVHJhbnNhY3Rpb25OZWVkZWQpOworCisgICAgLy8gZmxhZ3MgaXMgaW50ZW5kZWQgdG8gY29tbXVuaWNhdGUgc29tZSBzb3J0IG9mIGFuaW1hdGlvbiBiZWhhdmlvcgorICAgIC8vIChmb3IgaW5zdGFuY2UgZmFkZGluZykKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjp1bmZyZWV6ZURpc3BsYXkoRGlzcGxheUlEIGRweSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgaWYgKFVOTElLRUxZKHVpbnQzMl90KGRweSkgPj0gRElTUExBWV9DT1VOVCkpCisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgbUN1cnJlbnRTdGF0ZS5mcmVlemVEaXNwbGF5ID0gMDsKKyAgICBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZCk7CisKKyAgICAvLyBmbGFncyBpcyBpbnRlbmRlZCB0byBjb21tdW5pY2F0ZSBzb21lIHNvcnQgb2YgYW5pbWF0aW9uIGJlaGF2aW9yCisgICAgLy8gKGZvciBpbnN0YW5jZSBmYWRkaW5nKQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworaW50IFN1cmZhY2VGbGluZ2VyOjpzZXRPcmllbnRhdGlvbihEaXNwbGF5SUQgZHB5LCBpbnQgb3JpZW50YXRpb24pCit7CisgICAgaWYgKFVOTElLRUxZKHVpbnQzMl90KGRweSkgPj0gRElTUExBWV9DT1VOVCkpCisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgaWYgKG1DdXJyZW50U3RhdGUub3JpZW50YXRpb24gIT0gb3JpZW50YXRpb24pIHsKKyAgICAgICAgaWYgKHVpbnQzMl90KG9yaWVudGF0aW9uKTw9ZU9yaWVudGF0aW9uMjcwIHx8IG9yaWVudGF0aW9uPT00MikgeworICAgICAgICAgICAgbUN1cnJlbnRTdGF0ZS5vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uOworICAgICAgICAgICAgc2V0VHJhbnNhY3Rpb25GbGFncyhlVHJhbnNhY3Rpb25OZWVkZWQpOworICAgICAgICAgICAgbVRyYW5zYWN0aW9uQ1Yud2FpdChtU3RhdGVMb2NrKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG9yaWVudGF0aW9uID0gQkFEX1ZBTFVFOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBvcmllbnRhdGlvbjsKK30KKworc3A8SVN1cmZhY2U+IFN1cmZhY2VGbGluZ2VyOjpjcmVhdGVTdXJmYWNlKENsaWVudElEIGNsaWVudElkLCBpbnQgcGlkLAorICAgICAgICBJU3VyZmFjZUZsaW5nZXJDbGllbnQ6OnN1cmZhY2VfZGF0YV90KiBwYXJhbXMsCisgICAgICAgIERpc3BsYXlJRCBkLCB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBQaXhlbEZvcm1hdCBmb3JtYXQsCisgICAgICAgIHVpbnQzMl90IGZsYWdzKQoreworICAgIExheWVyQmFzZUNsaWVudCogbGF5ZXIgPSAwOworICAgIHNwPExheWVyQmFzZUNsaWVudDo6U3VyZmFjZT4gc3VyZmFjZUhhbmRsZTsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgQ2xpZW50KiBjb25zdCBjID0gbUNsaWVudHNNYXAudmFsdWVGb3IoY2xpZW50SWQpOworICAgIGlmIChVTkxJS0VMWSghYykpIHsKKyAgICAgICAgTE9HRSgiY3JlYXRlU3VyZmFjZSgpIGZhaWxlZCwgY2xpZW50IG5vdCBmb3VuZCAoaWQ9JWQpIiwgY2xpZW50SWQpOworICAgICAgICByZXR1cm4gc3VyZmFjZUhhbmRsZTsKKyAgICB9CisKKyAgICAvL0xPR0QoImNyZWF0ZVN1cmZhY2UgZm9yIHBpZCAlZCAoJWQgeCAlZCkiLCBwaWQsIHcsIGgpOworICAgIGludDMyX3QgaWQgPSBjLT5nZW5lcmF0ZUlkKHBpZCk7CisgICAgaWYgKHVpbnQzMl90KGlkKSA+PSBOVU1fTEFZRVJTX01BWCkgeworICAgICAgICBMT0dFKCJjcmVhdGVTdXJmYWNlKCkgZmFpbGVkLCBnZW5lcmF0ZUlkID0gJWQiLCBpZCk7CisgICAgICAgIHJldHVybiBzdXJmYWNlSGFuZGxlOworICAgIH0KKworICAgIHN3aXRjaCAoZmxhZ3MgJiBlRlhTdXJmYWNlTWFzaykgeworICAgICAgICBjYXNlIGVGWFN1cmZhY2VOb3JtYWw6CisgICAgICAgICAgICBpZiAoVU5MSUtFTFkoZmxhZ3MgJiBlUHVzaEJ1ZmZlcnMpKSB7CisgICAgICAgICAgICAgICAgbGF5ZXIgPSBjcmVhdGVQdXNoQnVmZmVyc1N1cmZhY2VMb2NrZWQoYywgZCwgaWQsIHcsIGgsIGZsYWdzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbGF5ZXIgPSBjcmVhdGVOb3JtYWxTdXJmYWNlTG9ja2VkKGMsIGQsIGlkLCB3LCBoLCBmb3JtYXQsIGZsYWdzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIGVGWFN1cmZhY2VCbHVyOgorICAgICAgICAgICAgbGF5ZXIgPSBjcmVhdGVCbHVyU3VyZmFjZUxvY2tlZChjLCBkLCBpZCwgdywgaCwgZmxhZ3MpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgZUZYU3VyZmFjZURpbToKKyAgICAgICAgICAgIGxheWVyID0gY3JlYXRlRGltU3VyZmFjZUxvY2tlZChjLCBkLCBpZCwgdywgaCwgZmxhZ3MpOworICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgaWYgKGxheWVyKSB7CisgICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZ3MoZVRyYW5zYWN0aW9uTmVlZGVkKTsKKyAgICAgICAgc3VyZmFjZUhhbmRsZSA9IGxheWVyLT5nZXRTdXJmYWNlKCk7CisgICAgICAgIGlmIChzdXJmYWNlSGFuZGxlICE9IDApCisgICAgICAgICAgICBzdXJmYWNlSGFuZGxlLT5nZXRTdXJmYWNlRGF0YShwYXJhbXMpOworICAgIH0KKworICAgIHJldHVybiBzdXJmYWNlSGFuZGxlOworfQorCitMYXllckJhc2VDbGllbnQqIFN1cmZhY2VGbGluZ2VyOjpjcmVhdGVOb3JtYWxTdXJmYWNlTG9ja2VkKAorICAgICAgICBDbGllbnQqIGNsaWVudCwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgIGludDMyX3QgaWQsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIFBpeGVsRm9ybWF0IGZvcm1hdCwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgLy8gaW5pdGlhbGl6ZSB0aGUgc3VyZmFjZXMKKyAgICBzd2l0Y2ggKGZvcm1hdCkgeyAvLyBUT0RPOiB0YWtlIGgvdyBpbnRvIGFjY291bnQKKyAgICBjYXNlIFBJWEVMX0ZPUk1BVF9UUkFOU1BBUkVOVDoKKyAgICBjYXNlIFBJWEVMX0ZPUk1BVF9UUkFOU0xVQ0VOVDoKKyAgICAgICAgZm9ybWF0ID0gUElYRUxfRk9STUFUX1JHQkFfODg4ODsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBQSVhFTF9GT1JNQVRfT1BBUVVFOgorICAgICAgICBmb3JtYXQgPSBQSVhFTF9GT1JNQVRfUkdCXzU2NTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgTGF5ZXIqIGxheWVyID0gbmV3IExheWVyKHRoaXMsIGRpc3BsYXksIGNsaWVudCwgaWQpOworICAgIHN0YXR1c190IGVyciA9IGxheWVyLT5zZXRCdWZmZXJzKGNsaWVudCwgdywgaCwgZm9ybWF0LCBmbGFncyk7CisgICAgaWYgKExJS0VMWShlcnIgPT0gTk9fRVJST1IpKSB7CisgICAgICAgIGxheWVyLT5pbml0U3RhdGVzKHcsIGgsIGZsYWdzKTsKKyAgICAgICAgYWRkTGF5ZXJfbChsYXllcik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HRSgiY3JlYXRlTm9ybWFsU3VyZmFjZUxvY2tlZCgpIGZhaWxlZCAoJXMpIiwgc3RyZXJyb3IoLWVycikpOworICAgICAgICBkZWxldGUgbGF5ZXI7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gbGF5ZXI7Cit9CisKK0xheWVyQmFzZUNsaWVudCogU3VyZmFjZUZsaW5nZXI6OmNyZWF0ZUJsdXJTdXJmYWNlTG9ja2VkKAorICAgICAgICBDbGllbnQqIGNsaWVudCwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgIGludDMyX3QgaWQsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIHVpbnQzMl90IGZsYWdzKQoreworICAgIExheWVyQmx1ciogbGF5ZXIgPSBuZXcgTGF5ZXJCbHVyKHRoaXMsIGRpc3BsYXksIGNsaWVudCwgaWQpOworICAgIGxheWVyLT5pbml0U3RhdGVzKHcsIGgsIGZsYWdzKTsKKyAgICBhZGRMYXllcl9sKGxheWVyKTsKKyAgICByZXR1cm4gbGF5ZXI7Cit9CisKK0xheWVyQmFzZUNsaWVudCogU3VyZmFjZUZsaW5nZXI6OmNyZWF0ZURpbVN1cmZhY2VMb2NrZWQoCisgICAgICAgIENsaWVudCogY2xpZW50LCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgaW50MzJfdCBpZCwgdWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgTGF5ZXJEaW0qIGxheWVyID0gbmV3IExheWVyRGltKHRoaXMsIGRpc3BsYXksIGNsaWVudCwgaWQpOworICAgIGxheWVyLT5pbml0U3RhdGVzKHcsIGgsIGZsYWdzKTsKKyAgICBhZGRMYXllcl9sKGxheWVyKTsKKyAgICByZXR1cm4gbGF5ZXI7Cit9CisKK0xheWVyQmFzZUNsaWVudCogU3VyZmFjZUZsaW5nZXI6OmNyZWF0ZVB1c2hCdWZmZXJzU3VyZmFjZUxvY2tlZCgKKyAgICAgICAgQ2xpZW50KiBjbGllbnQsIERpc3BsYXlJRCBkaXNwbGF5LAorICAgICAgICBpbnQzMl90IGlkLCB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBMYXllckJ1ZmZlciogbGF5ZXIgPSBuZXcgTGF5ZXJCdWZmZXIodGhpcywgZGlzcGxheSwgY2xpZW50LCBpZCk7CisgICAgbGF5ZXItPmluaXRTdGF0ZXModywgaCwgZmxhZ3MpOworICAgIGFkZExheWVyX2wobGF5ZXIpOworICAgIHJldHVybiBsYXllcjsKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXI6OmRlc3Ryb3lTdXJmYWNlKFN1cmZhY2VJRCBpbmRleCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgTGF5ZXJCYXNlQ2xpZW50KiBjb25zdCBsYXllciA9IGdldExheWVyVXNlcl9sKGluZGV4KTsKKyAgICBzdGF0dXNfdCBlcnIgPSByZW1vdmVMYXllcl9sKGxheWVyKTsKKyAgICBpZiAoZXJyIDwgMCkKKyAgICAgICAgcmV0dXJuIGVycjsKKyAgICBzZXRUcmFuc2FjdGlvbkZsYWdzKGVUcmFuc2FjdGlvbk5lZWRlZCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlRmxpbmdlcjo6c2V0Q2xpZW50U3RhdGUoCisgICAgICAgIENsaWVudElEIGNpZCwKKyAgICAgICAgaW50MzJfdCBjb3VudCwKKyAgICAgICAgY29uc3QgbGF5ZXJfc3RhdGVfdCogc3RhdGVzKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtU3RhdGVMb2NrKTsKKyAgICB1aW50MzJfdCBmbGFncyA9IDA7CisgICAgY2lkIDw8PSAxNjsKKyAgICBmb3IgKGludCBpPTAgOyBpPGNvdW50IDsgaSsrKSB7CisgICAgICAgIGNvbnN0IGxheWVyX3N0YXRlX3QmIHMgPSBzdGF0ZXNbaV07CisgICAgICAgIExheWVyQmFzZUNsaWVudCogbGF5ZXIgPSBnZXRMYXllclVzZXJfbChzLnN1cmZhY2UgfCBjaWQpOworICAgICAgICBpZiAobGF5ZXIpIHsKKyAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90IHdoYXQgPSBzLndoYXQ7CisgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBoYXMgYmVlbiBkZXN0cm95ZWQgZmlyc3QKKyAgICAgICAgICAgIGlmICh3aGF0ICYgZURlc3Ryb3llZCkgeworICAgICAgICAgICAgICAgIGlmIChyZW1vdmVMYXllcl9sKGxheWVyKSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgICAgICBmbGFncyB8PSBlVHJhbnNhY3Rpb25OZWVkZWQ7CisgICAgICAgICAgICAgICAgICAgIC8vIHdlIHNraXAgZXZlcnl0aGluZyBlbHNlLi4uIHdlbGwsIG5vLCBub3QgcmVhbGx5CisgICAgICAgICAgICAgICAgICAgIC8vIHdlIHNraXAgT05MWSB0aGF0IHRyYW5zYWN0aW9uLgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod2hhdCAmIGVQb3NpdGlvbkNoYW5nZWQpIHsKKyAgICAgICAgICAgICAgICBpZiAobGF5ZXItPnNldFBvc2l0aW9uKHMueCwgcy55KSkKKyAgICAgICAgICAgICAgICAgICAgZmxhZ3MgfD0gZVRyYXZlcnNhbE5lZWRlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh3aGF0ICYgZUxheWVyQ2hhbmdlZCkgeworICAgICAgICAgICAgICAgIGlmIChsYXllci0+c2V0TGF5ZXIocy56KSkgeworICAgICAgICAgICAgICAgICAgICBtQ3VycmVudFN0YXRlLmxheWVyc1NvcnRlZEJ5Wi5yZW9yZGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyLCAmTGF5ZXI6OmNvbXBhcmVDdXJyZW50U3RhdGVaKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0cmF2ZXJzYWwgKHN0YXRlIGNoYW5nZWQpCisgICAgICAgICAgICAgICAgICAgIC8vIEFORCB0cmFuc2FjdGlvbiAobGlzdCBjaGFuZ2VkKQorICAgICAgICAgICAgICAgICAgICBmbGFncyB8PSBlVHJhbnNhY3Rpb25OZWVkZWR8ZVRyYXZlcnNhbE5lZWRlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod2hhdCAmIGVTaXplQ2hhbmdlZCkgeworICAgICAgICAgICAgICAgIGlmIChsYXllci0+c2V0U2l6ZShzLncsIHMuaCkpCisgICAgICAgICAgICAgICAgICAgIGZsYWdzIHw9IGVUcmF2ZXJzYWxOZWVkZWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod2hhdCAmIGVBbHBoYUNoYW5nZWQpIHsKKyAgICAgICAgICAgICAgICBpZiAobGF5ZXItPnNldEFscGhhKHVpbnQ4X3QoMjU1LjBmKnMuYWxwaGErMC41ZikpKQorICAgICAgICAgICAgICAgICAgICBmbGFncyB8PSBlVHJhdmVyc2FsTmVlZGVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHdoYXQgJiBlTWF0cml4Q2hhbmdlZCkgeworICAgICAgICAgICAgICAgIGlmIChsYXllci0+c2V0TWF0cml4KHMubWF0cml4KSkKKyAgICAgICAgICAgICAgICAgICAgZmxhZ3MgfD0gZVRyYXZlcnNhbE5lZWRlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh3aGF0ICYgZVRyYW5zcGFyZW50UmVnaW9uQ2hhbmdlZCkgeworICAgICAgICAgICAgICAgIGlmIChsYXllci0+c2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KHMudHJhbnNwYXJlbnRSZWdpb24pKQorICAgICAgICAgICAgICAgICAgICBmbGFncyB8PSBlVHJhdmVyc2FsTmVlZGVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHdoYXQgJiBlVmlzaWJpbGl0eUNoYW5nZWQpIHsKKyAgICAgICAgICAgICAgICBpZiAobGF5ZXItPnNldEZsYWdzKHMuZmxhZ3MsIHMubWFzaykpCisgICAgICAgICAgICAgICAgICAgIGZsYWdzIHw9IGVUcmF2ZXJzYWxOZWVkZWQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGZsYWdzKSB7CisgICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZ3MoZmxhZ3MpOworICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK0xheWVyQmFzZUNsaWVudCogU3VyZmFjZUZsaW5nZXI6OmdldExheWVyVXNlcl9sKFN1cmZhY2VJRCBzKSBjb25zdAoreworICAgIHJldHVybiBtTGF5ZXJNYXAudmFsdWVGb3Iocyk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXI6OnNjcmVlblJlbGVhc2VkKGludCBkcHkpCit7CisgICAgLy8gdGhpcyBtYXkgYmUgY2FsbGVkIGJ5IGEgc2lnbmFsIGhhbmRsZXIsIHdlIGNhbid0IGRvIHRvbyBtdWNoIGluIGhlcmUKKyAgICBhbmRyb2lkX2F0b21pY19vcihlQ29uc29sZVJlbGVhc2VkLCAmbUNvbnNvbGVTaWduYWxzKTsKKyAgICBzaWduYWxFdmVudCgpOworfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyOjpzY3JlZW5BY3F1aXJlZChpbnQgZHB5KQoreworICAgIC8vIHRoaXMgbWF5IGJlIGNhbGxlZCBieSBhIHNpZ25hbCBoYW5kbGVyLCB3ZSBjYW4ndCBkbyB0b28gbXVjaCBpbiBoZXJlCisgICAgYW5kcm9pZF9hdG9taWNfb3IoZUNvbnNvbGVBY3F1aXJlZCwgJm1Db25zb2xlU2lnbmFscyk7CisgICAgc2lnbmFsRXZlbnQoKTsKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXI6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIGNvbnN0IHNpemVfdCBTSVpFID0gMTAyNDsKKyAgICBjaGFyIGJ1ZmZlcltTSVpFXTsKKyAgICBTdHJpbmc4IHJlc3VsdDsKKyAgICBpZiAoY2hlY2tDYWxsaW5nUGVybWlzc2lvbigKKyAgICAgICAgICAgIFN0cmluZzE2KCJhbmRyb2lkLnBlcm1pc3Npb24uRFVNUCIpKSA9PSBmYWxzZSkKKyAgICB7IC8vIG5vdCBhbGxvd2VkCisgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIlBlcm1pc3Npb24gRGVuaWFsOiAiCisgICAgICAgICAgICAgICAgImNhbid0IGR1bXAgU3VyZmFjZUZsaW5nZXIgZnJvbSBwaWQ9JWQsIHVpZD0lZFxuIiwKKyAgICAgICAgICAgICAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5nZXRDYWxsaW5nUGlkKCksCisgICAgICAgICAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1VpZCgpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgIH0gZWxzZSB7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtU3RhdGVMb2NrKTsKKyAgICAgICAgc2l6ZV90IHMgPSBtQ2xpZW50c01hcC5zaXplKCk7CisgICAgICAgIGNoYXIgbmFtZVs2NF07CisgICAgICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8cyA7IGkrKykgeworICAgICAgICAgICAgQ2xpZW50KiBjbGllbnQgPSBtQ2xpZW50c01hcC52YWx1ZUF0KGkpOworICAgICAgICAgICAgc3ByaW50ZihuYW1lLCAiICBDbGllbnQgKGlkPTB4JTA4eCkiLCBjbGllbnQtPmNpZCk7CisgICAgICAgICAgICBjbGllbnQtPmR1bXAobmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgY29uc3QgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMgPSBtQ3VycmVudFN0YXRlLmxheWVyc1NvcnRlZEJ5WjsKKyAgICAgICAgY29uc3Qgc2l6ZV90IGNvdW50ID0gY3VycmVudExheWVycy5zaXplKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8Y291bnQgOyBpKyspIHsKKyAgICAgICAgICAgIC8qKiogTGF5ZXJCYXNlICoqKi8KKyAgICAgICAgICAgIExheWVyQmFzZSBjb25zdCAqIGNvbnN0IGxheWVyID0gY3VycmVudExheWVyc1tpXTsKKyAgICAgICAgICAgIGNvbnN0IExheWVyOjpTdGF0ZSYgcyA9IGxheWVyLT5kcmF3aW5nU3RhdGUoKTsKKyAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwKKyAgICAgICAgICAgICAgICAgICAgIisgJXMgJXBcbiIKKyAgICAgICAgICAgICAgICAgICAgIiAgICAgICIKKyAgICAgICAgICAgICAgICAgICAgIno9JTlkLCBwb3M9KCU0ZCwlNGQpLCBzaXplPSglNGQsJTRkKSwgIgorICAgICAgICAgICAgICAgICAgICAibmVlZHNCbGVuZGluZz0lMWQsIGludmFsaWRhdGU9JTFkLCAiCisgICAgICAgICAgICAgICAgICAgICJhbHBoYT0weCUwMngsIGZsYWdzPTB4JTA4eCwgdHI9WyUuMmYsICUuMmZdWyUuMmYsICUuMmZdXG4iLAorICAgICAgICAgICAgICAgICAgICBsYXllci0+Z2V0VHlwZUlEKCksIGxheWVyLAorICAgICAgICAgICAgICAgICAgICBzLnosIGxheWVyLT50eCgpLCBsYXllci0+dHkoKSwgcy53LCBzLmgsCisgICAgICAgICAgICAgICAgICAgIGxheWVyLT5uZWVkc0JsZW5kaW5nKCksIGxheWVyLT5jb250ZW50RGlydHksCisgICAgICAgICAgICAgICAgICAgIHMuYWxwaGEsIHMuZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgIHMudHJhbnNmb3JtWzBdLCBzLnRyYW5zZm9ybVsxXSwKKyAgICAgICAgICAgICAgICAgICAgcy50cmFuc2Zvcm1bMl0sIHMudHJhbnNmb3JtWzNdKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICAgICAgICAgIGJ1ZmZlclswXSA9IDA7CisgICAgICAgICAgICAvKioqIExheWVyQmFzZUNsaWVudCAqKiovCisgICAgICAgICAgICBMYXllckJhc2VDbGllbnQqIGNvbnN0IGxiYyA9CisgICAgICAgICAgICAgICAgTGF5ZXJCYXNlOjpkeW5hbWljQ2FzdDxMYXllckJhc2VDbGllbnQqPigoTGF5ZXJCYXNlKilsYXllcik7CisgICAgICAgICAgICBpZiAobGJjKSB7CisgICAgICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLAorICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAgICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJpZD0weCUwOHgsIGNsaWVudD0weCUwOHgsIGlkZW50aXR5PSV1XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgbGJjLT5jbGllbnRJbmRleCgpLCBsYmMtPmNsaWVudCA/IGxiYy0+Y2xpZW50LT5jaWQgOiAwLAorICAgICAgICAgICAgICAgICAgICAgICAgbGJjLT5nZXRJZGVudGl0eSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICAgICAgICAgIGJ1ZmZlclswXSA9IDA7CisgICAgICAgICAgICAvKioqIExheWVyICoqKi8KKyAgICAgICAgICAgIExheWVyKiBjb25zdCBsID0gTGF5ZXJCYXNlOjpkeW5hbWljQ2FzdDxMYXllcio+KChMYXllckJhc2UqKWxheWVyKTsKKyAgICAgICAgICAgIGlmIChsKSB7CisgICAgICAgICAgICAgICAgY29uc3QgTGF5ZXJCaXRtYXAmIGJ1ZjAobC0+Z2V0QnVmZmVyKDApKTsKKyAgICAgICAgICAgICAgICBjb25zdCBMYXllckJpdG1hcCYgYnVmMShsLT5nZXRCdWZmZXIoMSkpOworICAgICAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICIgICAgICAiCisgICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0PSUyZCwgWyUzdXglM3U6JTN1XSBbJTN1eCUzdTolM3VdLCBtVGV4dHVyZU5hbWU9JWQsIgorICAgICAgICAgICAgICAgICAgICAgICAgIiBmcmVlemVMb2NrPSVwLCBzd2FwU3RhdGU9MHglMDh4XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgbC0+cGl4ZWxGb3JtYXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZjAud2lkdGgoKSwgYnVmMC5oZWlnaHQoKSwgYnVmMC5zdHJpZGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZjEud2lkdGgoKSwgYnVmMS5oZWlnaHQoKSwgYnVmMS5zdHJpZGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGwtPmdldFRleHR1cmVOYW1lKCksIGwtPmdldEZyZWV6ZUxvY2soKS5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGwtPmxjYmxrLT5zd2FwU3RhdGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworICAgICAgICAgICAgYnVmZmVyWzBdID0gMDsKKyAgICAgICAgICAgIHMudHJhbnNwYXJlbnRSZWdpb24uZHVtcChyZXN1bHQsICJ0cmFuc3BhcmVudFJlZ2lvbiIpOworICAgICAgICAgICAgbGF5ZXItPnRyYW5zcGFyZW50UmVnaW9uU2NyZWVuLmR1bXAocmVzdWx0LCAidHJhbnNwYXJlbnRSZWdpb25TY3JlZW4iKTsKKyAgICAgICAgICAgIGxheWVyLT52aXNpYmxlUmVnaW9uU2NyZWVuLmR1bXAocmVzdWx0LCAidmlzaWJsZVJlZ2lvblNjcmVlbiIpOworICAgICAgICB9CisgICAgICAgIG1Xb3JtaG9sZVJlZ2lvbi5kdW1wKHJlc3VsdCwgIldvcm1ob2xlUmVnaW9uIik7CisgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgaHcoZ3JhcGhpY1BsYW5lKDApLmRpc3BsYXlIYXJkd2FyZSgpKTsKKyAgICAgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLAorICAgICAgICAgICAgICAgICIgIGRpc3BsYXkgZnJvemVuOiAlcywgZnJlZXplQ291bnQ9JWQsIG9yaWVudGF0aW9uPSVkLCBjYW5EcmF3PSVkXG4iLAorICAgICAgICAgICAgICAgIG1GcmVlemVEaXNwbGF5PyJ5ZXMiOiJubyIsIG1GcmVlemVDb3VudCwKKyAgICAgICAgICAgICAgICBtQ3VycmVudFN0YXRlLm9yaWVudGF0aW9uLCBody5jYW5EcmF3KCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisKKyAgICAgICAgc3A8QWxsb2NhdG9ySW50ZXJmYWNlPiBhbGxvY2F0b3I7CisgICAgICAgIGlmIChtR1BVICE9IDApIHsKKyAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIiAgR1BVIG93bmVyOiAlZFxuIiwgbUdQVS0+Z2V0T3duZXIoKSk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgICAgICBhbGxvY2F0b3IgPSBtR1BVLT5nZXRBbGxvY2F0b3IoKTsKKyAgICAgICAgICAgIGlmIChhbGxvY2F0b3IgIT0gMCkgeworICAgICAgICAgICAgICAgIGFsbG9jYXRvci0+ZHVtcChyZXN1bHQsICJHUFUgQWxsb2NhdG9yIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYWxsb2NhdG9yID0gbVN1cmZhY2VIZWFwTWFuYWdlci0+Z2V0QWxsb2NhdG9yKE5BVElWRV9NRU1PUllfVFlQRV9QTUVNKTsKKyAgICAgICAgaWYgKGFsbG9jYXRvciAhPSAwKSB7CisgICAgICAgICAgICBhbGxvY2F0b3ItPmR1bXAocmVzdWx0LCAiUE1FTSBBbGxvY2F0b3IiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICB3cml0ZShmZCwgcmVzdWx0LnN0cmluZygpLCByZXN1bHQuc2l6ZSgpKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgQ1JFQVRFX0NPTk5FQ1RJT046CisgICAgICAgIGNhc2UgT1BFTl9HTE9CQUxfVFJBTlNBQ1RJT046CisgICAgICAgIGNhc2UgQ0xPU0VfR0xPQkFMX1RSQU5TQUNUSU9OOgorICAgICAgICBjYXNlIFNFVF9PUklFTlRBVElPTjoKKyAgICAgICAgY2FzZSBGUkVFWkVfRElTUExBWToKKyAgICAgICAgY2FzZSBVTkZSRUVaRV9ESVNQTEFZOgorICAgICAgICBjYXNlIEJPT1RfRklOSVNIRUQ6CisgICAgICAgIGNhc2UgUkVWT0tFX0dQVToKKyAgICAgICAgeworICAgICAgICAgICAgLy8gY29kZXMgdGhhdCByZXF1aXJlIHBlcm1pc3Npb24gY2hlY2sKKyAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlKiBpcGMgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpOworICAgICAgICAgICAgY29uc3QgaW50IHBpZCA9IGlwYy0+Z2V0Q2FsbGluZ1BpZCgpOworICAgICAgICAgICAgY29uc3QgaW50IHNlbGZfcGlkID0gZ2V0cGlkKCk7CisgICAgICAgICAgICBpZiAoVU5MSUtFTFkocGlkICE9IHNlbGZfcGlkKSkgeworICAgICAgICAgICAgICAgIC8vIHdlJ3JlIGNhbGxlZCBmcm9tIGEgZGlmZmVyZW50IHByb2Nlc3MsIGRvIHRoZSByZWFsIGNoZWNrCisgICAgICAgICAgICAgICAgaWYgKCFjaGVja0NhbGxpbmdQZXJtaXNzaW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYoImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfU1VSRkFDRV9GTElOR0VSIikpKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IHVpZCA9IGlwYy0+Z2V0Q2FsbGluZ1VpZCgpOworICAgICAgICAgICAgICAgICAgICBMT0dFKCJQZXJtaXNzaW9uIERlbmlhbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYW4ndCBhY2Nlc3MgU3VyZmFjZUZsaW5nZXIgcGlkPSVkLCB1aWQ9JWQiLCBwaWQsIHVpZCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0dXNfdCBlcnIgPSBCblN1cmZhY2VDb21wb3Nlcjo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworICAgIGlmIChlcnIgPT0gVU5LTk9XTl9UUkFOU0FDVElPTiB8fCBlcnIgPT0gUEVSTUlTU0lPTl9ERU5JRUQpIHsKKyAgICAgICAgLy8gSEFSRFdBUkVfVEVTVCBzdHVmZi4uLgorICAgICAgICBpZiAoVU5MSUtFTFkoY2hlY2tDYWxsaW5nUGVybWlzc2lvbigKKyAgICAgICAgICAgICAgICBTdHJpbmcxNigiYW5kcm9pZC5wZXJtaXNzaW9uLkhBUkRXQVJFX1RFU1QiKSkgPT0gZmFsc2UpKQorICAgICAgICB7IC8vIG5vdCBhbGxvd2VkCisgICAgICAgICAgICBMT0dFKCJQZXJtaXNzaW9uIERlbmlhbDogcGlkPSVkLCB1aWQ9JWRcbiIsCisgICAgICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmdldENhbGxpbmdQaWQoKSwKKyAgICAgICAgICAgICAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Z2V0Q2FsbGluZ1VpZCgpKTsKKyAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICAgICAgfQorICAgICAgICBpbnQgbjsKKyAgICAgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgICAgICBjYXNlIDEwMDA6IC8vIFNIT1dfQ1BVCisgICAgICAgICAgICAgICAgbiA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICAgICAgbURlYnVnQ3B1ID0gbiA/IDEgOiAwOworICAgICAgICAgICAgICAgIGlmIChtRGVidWdDcHUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1DcHVHYXVnZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtQ3B1R2F1Z2UgPSBuZXcgQ1BVR2F1Z2UodGhpcywgbXMybnMoNTAwKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAobUNwdUdhdWdlICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1DcHVHYXVnZS0+cmVxdWVzdEV4aXRBbmRXYWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobURlYnVnTG9jayk7CisgICAgICAgICAgICAgICAgICAgICAgICBtQ3B1R2F1Z2UuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgICAgICBjYXNlIDEwMDE6ICAvLyBTSE9XX0ZQUworICAgICAgICAgICAgICAgIG4gPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgICAgIG1EZWJ1Z0ZwcyA9IG4gPyAxIDogMDsKKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgICAgICBjYXNlIDEwMDI6ICAvLyBTSE9XX1VQREFURVMKKyAgICAgICAgICAgICAgICBuID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgICAgICBtRGVidWdSZWdpb24gPSBuID8gbiA6IChtRGVidWdSZWdpb24gPyAwIDogMSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICAgICAgY2FzZSAxMDAzOiAgLy8gU0hPV19CQUNLR1JPVU5ECisgICAgICAgICAgICAgICAgbiA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICAgICAgbURlYnVnQmFja2dyb3VuZCA9IG4gPyAxIDogMDsKKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgICAgICBjYXNlIDEwMDQ6eyAvLyByZXBhaW50IGV2ZXJ5dGhpbmcKKyAgICAgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobVN0YXRlTG9jayk7CisgICAgICAgICAgICAgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhncmFwaGljUGxhbmUoMCkuZGlzcGxheUhhcmR3YXJlKCkpOworICAgICAgICAgICAgICAgIG1EaXJ0eVJlZ2lvbi5zZXQoaHcuYm91bmRzKCkpOyAvLyBjYXJlZnVsIHRoYXQncyBub3QgdGhyZWFkLXNhZmUKKyAgICAgICAgICAgICAgICBzaWduYWxFdmVudCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICAgICAgY2FzZSAxMDA1OiAvLyBhc2sgR1BVIHJldm9rZQorICAgICAgICAgICAgICAgIG1HUFUtPmZyaWVuZGx5UmV2b2tlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICAgICAgY2FzZSAxMDA2OiAvLyByZXZva2UgR1BVCisgICAgICAgICAgICAgICAgbUdQVS0+dW5jb25kaXRpb25hbFJldm9rZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgIGNhc2UgMTAwNzogLy8gc2V0IG1GcmVlemVDb3VudAorICAgICAgICAgICAgICAgIG1GcmVlemVDb3VudCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICAgICAgY2FzZSAxMDEwOiAgLy8gaW50ZXJyb2dhdGUuCisgICAgICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIobURlYnVnQ3B1KTsKKyAgICAgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMigwKTsKKyAgICAgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihtRGVidWdSZWdpb24pOworICAgICAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKG1EZWJ1Z0JhY2tncm91bmQpOworICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgIGNhc2UgMTAxMzogeworICAgICAgICAgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtU3RhdGVMb2NrKTsKKyAgICAgICAgICAgICAgICBjb25zdCBEaXNwbGF5SGFyZHdhcmUmIGh3KGdyYXBoaWNQbGFuZSgwKS5kaXNwbGF5SGFyZHdhcmUoKSk7CisgICAgICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoaHcuZ2V0UGFnZUZsaXBDb3VudCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZXJyOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK0NsaWVudDo6Q2xpZW50KENsaWVudElEIGNsaWVudElELCBjb25zdCBzcDxTdXJmYWNlRmxpbmdlcj4mIGZsaW5nZXIpCisgICAgOiBjdHJsYmxrKDApLCBjaWQoY2xpZW50SUQpLCBtUGlkKDApLCBtQml0bWFwKDApLCBtRmxpbmdlcihmbGluZ2VyKQoreworICAgIG1TaGFyZWRIZWFwQWxsb2NhdG9yID0gZ2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCktPmNyZWF0ZUhlYXAoKTsKKyAgICBjb25zdCBpbnQgcGdzaXplID0gZ2V0cGFnZXNpemUoKTsKKyAgICBjb25zdCBpbnQgY2Jsa3NpemU9KChzaXplb2YocGVyX2NsaWVudF9jYmxrX3QpKyhwZ3NpemUtMSkpJn4ocGdzaXplLTEpKTsKKyAgICBtQ2Jsa0hlYXAgPSBuZXcgTWVtb3J5RGVhbGVyKGNibGtzaXplKTsKKyAgICBtQ2Jsa01lbW9yeSA9IG1DYmxrSGVhcC0+YWxsb2NhdGUoY2Jsa3NpemUpOworICAgIGlmIChtQ2Jsa01lbW9yeSAhPSAwKSB7CisgICAgICAgIGN0cmxibGsgPSBzdGF0aWNfY2FzdDxwZXJfY2xpZW50X2NibGtfdCAqPihtQ2Jsa01lbW9yeS0+cG9pbnRlcigpKTsKKyAgICAgICAgaWYgKGN0cmxibGspIHsgLy8gY29uc3RydWN0IHRoZSBzaGFyZWQgc3RydWN0dXJlIGluLXBsYWNlLgorICAgICAgICAgICAgbmV3KGN0cmxibGspIHBlcl9jbGllbnRfY2Jsa190OworICAgICAgICB9CisgICAgfQorfQorCitDbGllbnQ6On5DbGllbnQoKSB7CisgICAgaWYgKGN0cmxibGspIHsKKyAgICAgICAgY29uc3QgaW50IHBnc2l6ZSA9IGdldHBhZ2VzaXplKCk7CisgICAgICAgIGN0cmxibGstPn5wZXJfY2xpZW50X2NibGtfdCgpOyAgLy8gZGVzdHJveSBvdXIgc2hhcmVkLXN0cnVjdHVyZS4KKyAgICB9Cit9CisKK2NvbnN0IHNwPFN1cmZhY2VIZWFwTWFuYWdlcj4mIENsaWVudDo6Z2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCkgY29uc3QgeworICAgIHJldHVybiBtRmxpbmdlci0+Z2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCk7Cit9CisKK2ludDMyX3QgQ2xpZW50OjpnZW5lcmF0ZUlkKGludCBwaWQpCit7CisgICAgY29uc3QgdWludDMyX3QgaSA9IGNseiggfm1CaXRtYXAgKTsKKyAgICBpZiAoaSA+PSBOVU1fTEFZRVJTX01BWCkgeworICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgIH0KKyAgICBtUGlkID0gcGlkOworICAgIG1JblVzZS5hZGQodWludDhfdChpKSk7CisgICAgbUJpdG1hcCB8PSAxPDwoMzEtaSk7CisgICAgcmV0dXJuIGk7Cit9CitzdGF0dXNfdCBDbGllbnQ6OmJpbmRMYXllcihMYXllckJhc2VDbGllbnQqIGxheWVyLCBpbnQzMl90IGlkKQoreworICAgIHNzaXplX3QgaWR4ID0gbUluVXNlLmluZGV4T2YoaWQpOworICAgIGlmIChpZHggPCAwKQorICAgICAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7CisgICAgcmV0dXJuIG1MYXllcnMuaW5zZXJ0QXQobGF5ZXIsIGlkeCk7Cit9Cit2b2lkIENsaWVudDo6ZnJlZShpbnQzMl90IGlkKQoreworICAgIHNzaXplX3QgaWR4ID0gbUluVXNlLnJlbW92ZSh1aW50OF90KGlkKSk7CisgICAgaWYgKGlkeCA+PSAwKSB7CisgICAgICAgIG1CaXRtYXAgJj0gfigxPDwoMzEtaWQpKTsKKyAgICAgICAgbUxheWVycy5yZW1vdmVJdGVtc0F0KGlkeCk7CisgICAgfQorfQorCitzcDxNZW1vcnlEZWFsZXI+IENsaWVudDo6Y3JlYXRlQWxsb2NhdG9yKHVpbnQzMl90IGZsYWdzKQoreworICAgIHNwPE1lbW9yeURlYWxlcj4gYWxsb2NhdG9yOworICAgIGFsbG9jYXRvciA9IGdldFN1cmZhY2VIZWFwTWFuYWdlcigpLT5jcmVhdGVIZWFwKAorICAgICAgICAgICAgZmxhZ3MsIGdldENsaWVudFBpZCgpLCBtU2hhcmVkSGVhcEFsbG9jYXRvcik7CisgICAgcmV0dXJuIGFsbG9jYXRvcjsKK30KKworYm9vbCBDbGllbnQ6OmlzVmFsaWQoaW50MzJfdCBpKSBjb25zdCB7CisgICAgcmV0dXJuICh1aW50MzJfdChpKTxOVU1fTEFZRVJTX01BWCkgJiYgKG1CaXRtYXAgJiAoMTw8KDMxLWkpKSk7Cit9Citjb25zdCB1aW50OF90KiBDbGllbnQ6OmluVXNlQXJyYXkoKSBjb25zdCB7CisgICAgcmV0dXJuIG1JblVzZS5hcnJheSgpOworfQorc2l6ZV90IENsaWVudDo6bnVtQWN0aXZlTGF5ZXJzKCkgY29uc3QgeworICAgIHJldHVybiBtSW5Vc2Uuc2l6ZSgpOworfQorTGF5ZXJCYXNlQ2xpZW50KiBDbGllbnQ6OmdldExheWVyVXNlcihpbnQzMl90IGkpIGNvbnN0IHsKKyAgICBzc2l6ZV90IGlkeCA9IG1JblVzZS5pbmRleE9mKHVpbnQ4X3QoaSkpOworICAgIGlmIChpZHg8MCkgcmV0dXJuIDA7CisgICAgcmV0dXJuIG1MYXllcnNbaWR4XTsKK30KKwordm9pZCBDbGllbnQ6OmR1bXAoY29uc3QgY2hhciogd2hhdCkKK3sKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCitCQ2xpZW50OjpCQ2xpZW50KFN1cmZhY2VGbGluZ2VyICpmbGluZ2VyLCBDbGllbnRJRCBjaWQsIGNvbnN0IHNwPElNZW1vcnk+JiBjYmxrKQorICAgIDogbUlkKGNpZCksIG1GbGluZ2VyKGZsaW5nZXIpLCBtQ2JsayhjYmxrKQoreworfQorCitCQ2xpZW50Ojp+QkNsaWVudCgpIHsKKyAgICAvLyBkZXN0cm95IGFsbCByZXNvdXJjZXMgYXR0YWNoZWQgdG8gdGhpcyBjbGllbnQKKyAgICBtRmxpbmdlci0+ZGVzdHJveUNvbm5lY3Rpb24obUlkKTsKK30KKwordm9pZCBCQ2xpZW50OjpnZXRDb250cm9sQmxvY2tzKHNwPElNZW1vcnk+KiBjdHJsKSBjb25zdCB7CisgICAgKmN0cmwgPSBtQ2JsazsKK30KKworc3A8SVN1cmZhY2U+IEJDbGllbnQ6OmNyZWF0ZVN1cmZhY2UoCisgICAgICAgIElTdXJmYWNlRmxpbmdlckNsaWVudDo6c3VyZmFjZV9kYXRhX3QqIHBhcmFtcywgaW50IHBpZCwKKyAgICAgICAgRGlzcGxheUlEIGRpc3BsYXksIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIFBpeGVsRm9ybWF0IGZvcm1hdCwKKyAgICAgICAgdWludDMyX3QgZmxhZ3MpCit7CisgICAgcmV0dXJuIG1GbGluZ2VyLT5jcmVhdGVTdXJmYWNlKG1JZCwgcGlkLCBwYXJhbXMsIGRpc3BsYXksIHcsIGgsIGZvcm1hdCwgZmxhZ3MpOworfQorCitzdGF0dXNfdCBCQ2xpZW50OjpkZXN0cm95U3VyZmFjZShTdXJmYWNlSUQgc2lkKQoreworICAgIHNpZCB8PSAobUlkIDw8IDE2KTsgLy8gYWRkIHRoZSBjbGllbnQtcGFydCB0byBpZAorICAgIHJldHVybiBtRmxpbmdlci0+ZGVzdHJveVN1cmZhY2Uoc2lkKTsKK30KKworc3RhdHVzX3QgQkNsaWVudDo6c2V0U3RhdGUoaW50MzJfdCBjb3VudCwgY29uc3QgbGF5ZXJfc3RhdGVfdCogc3RhdGVzKQoreworICAgIHJldHVybiBtRmxpbmdlci0+c2V0Q2xpZW50U3RhdGUobUlkLCBjb3VudCwgc3RhdGVzKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0dyYXBoaWNQbGFuZTo6R3JhcGhpY1BsYW5lKCkKKyAgICA6IG1IdygwKQoreworfQorCitHcmFwaGljUGxhbmU6On5HcmFwaGljUGxhbmUoKSB7CisgICAgZGVsZXRlIG1IdzsKK30KKworYm9vbCBHcmFwaGljUGxhbmU6OmluaXRpYWxpemVkKCkgY29uc3QgeworICAgIHJldHVybiBtSHcgPyB0cnVlIDogZmFsc2U7Cit9CisKK3ZvaWQgR3JhcGhpY1BsYW5lOjpzZXREaXNwbGF5SGFyZHdhcmUoRGlzcGxheUhhcmR3YXJlICpodykgeworICAgIG1IdyA9IGh3OworfQorCit2b2lkIEdyYXBoaWNQbGFuZTo6c2V0VHJhbnNmb3JtKGNvbnN0IFRyYW5zZm9ybSYgdHIpIHsKKyAgICBtVHJhbnNmb3JtID0gdHI7CisgICAgbUdsb2JhbFRyYW5zZm9ybSA9IG1PcmllbnRhdGlvblRyYW5zZm9ybSAqIG1UcmFuc2Zvcm07Cit9CisKK3N0YXR1c190IEdyYXBoaWNQbGFuZTo6b3JpZW50YXRpb25Ub1RyYW5zZnJvbSgKKyAgICAgICAgaW50IG9yaWVudGF0aW9uLCBpbnQgdywgaW50IGgsIFRyYW5zZm9ybSogdHIpCit7ICAgIAorICAgIGZsb2F0IGEsIGIsIGMsIGQsIHgsIHk7CisgICAgc3dpdGNoIChvcmllbnRhdGlvbikgeworICAgIGNhc2UgSVN1cmZhY2VDb21wb3Nlcjo6ZU9yaWVudGF0aW9uRGVmYXVsdDoKKyAgICAgICAgYT0xOyBiPTA7IGM9MDsgZD0xOyB4PTA7IHk9MDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBJU3VyZmFjZUNvbXBvc2VyOjplT3JpZW50YXRpb245MDoKKyAgICAgICAgYT0wOyBiPS0xOyBjPTE7IGQ9MDsgeD13OyB5PTA7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgSVN1cmZhY2VDb21wb3Nlcjo6ZU9yaWVudGF0aW9uMTgwOgorICAgICAgICBhPS0xOyBiPTA7IGM9MDsgZD0tMTsgeD13OyB5PWg7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgSVN1cmZhY2VDb21wb3Nlcjo6ZU9yaWVudGF0aW9uMjcwOgorICAgICAgICBhPTA7IGI9MTsgYz0tMTsgZD0wOyB4PTA7IHk9aDsKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB9CisgICAgdHItPnNldChhLCBiLCBjLCBkKTsKKyAgICB0ci0+c2V0KHgsIHkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgR3JhcGhpY1BsYW5lOjpzZXRPcmllbnRhdGlvbihpbnQgb3JpZW50YXRpb24pCit7CisgICAgY29uc3QgRGlzcGxheUhhcmR3YXJlJiBodyhkaXNwbGF5SGFyZHdhcmUoKSk7CisgICAgY29uc3QgZmxvYXQgdyA9IGh3LmdldFdpZHRoKCk7CisgICAgY29uc3QgZmxvYXQgaCA9IGh3LmdldEhlaWdodCgpOworCisgICAgaWYgKG9yaWVudGF0aW9uID09IElTdXJmYWNlQ29tcG9zZXI6OmVPcmllbnRhdGlvbkRlZmF1bHQpIHsKKyAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBkZWZhdWx0IG9yaWVudGF0aW9uIGlzIG9wdGltYWwKKyAgICAgICAgbU9yaWVudGF0aW9uVHJhbnNmb3JtLnJlc2V0KCk7CisgICAgICAgIG1HbG9iYWxUcmFuc2Zvcm0gPSBtVHJhbnNmb3JtOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgLy8gSWYgdGhlIHJvdGF0aW9uIGNhbiBiZSBoYW5kbGVkIGluIGhhcmR3YXJlLCB0aGlzIGlzIHdoZXJlCisgICAgLy8gdGhlIG1hZ2ljIHNob3VsZCBoYXBwZW4uCisgICAgaWYgKFVOTElLRUxZKG9yaWVudGF0aW9uID09IDQyKSkgeworICAgICAgICBmbG9hdCBhLCBiLCBjLCBkLCB4LCB5OworICAgICAgICBjb25zdCBmbG9hdCByID0gKDMuMTQxNTkyNjVmIC8gMTgwLjBmKSAqIDQyLjBmOworICAgICAgICBjb25zdCBmbG9hdCBzaSA9IHNpbmYocik7CisgICAgICAgIGNvbnN0IGZsb2F0IGNvID0gY29zZihyKTsKKyAgICAgICAgYT1jbzsgYj0tc2k7IGM9c2k7IGQ9Y287CisgICAgICAgIHggPSBzaSooaCowLjVmKSArICgxLWNvKSoodyowLjVmKTsKKyAgICAgICAgeSA9LXNpKih3KjAuNWYpICsgKDEtY28pKihoKjAuNWYpOworICAgICAgICBtT3JpZW50YXRpb25UcmFuc2Zvcm0uc2V0KGEsIGIsIGMsIGQpOworICAgICAgICBtT3JpZW50YXRpb25UcmFuc2Zvcm0uc2V0KHgsIHkpOworICAgIH0gZWxzZSB7CisgICAgICAgIEdyYXBoaWNQbGFuZTo6b3JpZW50YXRpb25Ub1RyYW5zZnJvbShvcmllbnRhdGlvbiwgdywgaCwKKyAgICAgICAgICAgICAgICAmbU9yaWVudGF0aW9uVHJhbnNmb3JtKTsKKyAgICB9CisgICAgCisgICAgbUdsb2JhbFRyYW5zZm9ybSA9IG1PcmllbnRhdGlvblRyYW5zZm9ybSAqIG1UcmFuc2Zvcm07CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitjb25zdCBEaXNwbGF5SGFyZHdhcmUmIEdyYXBoaWNQbGFuZTo6ZGlzcGxheUhhcmR3YXJlKCkgY29uc3QgeworICAgIHJldHVybiAqbUh3OworfQorCitjb25zdCBUcmFuc2Zvcm0mIEdyYXBoaWNQbGFuZTo6dHJhbnNmb3JtKCkgY29uc3QgeworICAgIHJldHVybiBtR2xvYmFsVHJhbnNmb3JtOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvU3VyZmFjZUZsaW5nZXIuaCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvU3VyZmFjZUZsaW5nZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mN2Q3NzY0Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9TdXJmYWNlRmxpbmdlci5oCkBAIC0wLDAgKzEsNDM1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1NVUkZBQ0VfRkxJTkdFUl9ICisjZGVmaW5lIEFORFJPSURfU1VSRkFDRV9GTElOR0VSX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvU29ydGVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisKKyNpbmNsdWRlIDx1aS9QaXhlbEZvcm1hdC5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlQ29tcG9zZXIuaD4KKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUZsaW5nZXJDbGllbnQuaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdWkvU2hhcmVkU3RhdGUuaD4KKyNpbmNsdWRlIDxwcml2YXRlL3VpL0xheWVyU3RhdGUuaD4KKyNpbmNsdWRlIDxwcml2YXRlL3VpL1N1cmZhY2VGbGluZ2VyU3luY2hyby5oPgorCisjaW5jbHVkZSAiQmFycmllci5oIgorI2luY2x1ZGUgIkJvb3RBbmltYXRpb24uaCIKKyNpbmNsdWRlICJDUFVHYXVnZS5oIgorI2luY2x1ZGUgIkxheWVyLmgiCisjaW5jbHVkZSAiVG9rZW5pemVyLmgiCisKK3N0cnVjdCBjb3B5Yml0X2RldmljZV90Oworc3RydWN0IG92ZXJsYXlfZGV2aWNlX3Q7CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIENsaWVudDsKK2NsYXNzIEJDbGllbnQ7CitjbGFzcyBEaXNwbGF5SGFyZHdhcmU7CitjbGFzcyBGcmVlemVMb2NrOworY2xhc3MgR1BVSGFyZHdhcmVJbnRlcmZhY2U7CitjbGFzcyBJR1BVQ2FsbGJhY2s7CitjbGFzcyBMYXllcjsKK2NsYXNzIExheWVyQnVmZmVyOworY2xhc3MgTGF5ZXJPcmllbnRhdGlvbkFuaW07CitjbGFzcyBPcmllbnRhdGlvbkFuaW1hdGlvbjsKK2NsYXNzIFN1cmZhY2VIZWFwTWFuYWdlcjsKKwordHlwZWRlZiBpbnQzMl90IENsaWVudElEOworCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBDbGllbnQKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgIENsaWVudChDbGllbnRJRCBjaWQsIGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlcik7CisgICAgICAgICAgICB+Q2xpZW50KCk7CisKKyAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgIGdlbmVyYXRlSWQoaW50IHBpZCk7CisgICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgICAgICBmcmVlKGludDMyX3QgaWQpOworICAgICAgICAgICAgc3RhdHVzX3QgICAgICAgICAgICAgICAgYmluZExheWVyKExheWVyQmFzZUNsaWVudCogbGF5ZXIsIGludDMyX3QgaWQpOworICAgICAgICAgICAgc3A8TWVtb3J5RGVhbGVyPiAgICAgICAgY3JlYXRlQWxsb2NhdG9yKHVpbnQzMl90IG1lbW9yeV90eXBlKTsKKworICAgIGlubGluZSAgYm9vbCAgICAgICAgICAgICAgICAgICAgaXNWYWxpZChpbnQzMl90IGkpIGNvbnN0OworICAgIGlubGluZSAgY29uc3QgdWludDhfdCogICAgICAgICAgaW5Vc2VBcnJheSgpIGNvbnN0OworICAgIGlubGluZSAgc2l6ZV90ICAgICAgICAgICAgICAgICAgbnVtQWN0aXZlTGF5ZXJzKCkgY29uc3Q7CisgICAgTGF5ZXJCYXNlQ2xpZW50KiAgICAgICAgICAgICAgICBnZXRMYXllclVzZXIoaW50MzJfdCBpKSBjb25zdDsKKyAgICBjb25zdCBWZWN0b3I8TGF5ZXJCYXNlQ2xpZW50Kj4mIGdldExheWVycygpIGNvbnN0IHsgcmV0dXJuIG1MYXllcnM7IH0KKyAgICBjb25zdCBzcDxJTWVtb3J5PiYgICAgICAgICAgICAgIGNvbnRyb2xCbG9ja01lbW9yeSgpIGNvbnN0IHsgcmV0dXJuIG1DYmxrTWVtb3J5OyB9CisgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdW1wKGNvbnN0IGNoYXIqIHdoYXQpOworICAgIGNvbnN0IHNwPFN1cmZhY2VIZWFwTWFuYWdlcj4mICAgZ2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCkgY29uc3Q7CisgICAgCisgICAgLy8gcG9pbnRlciB0byB0aGlzIGNsaWVudCdzIGNvbnRyb2wgYmxvY2sKKyAgICBwZXJfY2xpZW50X2NibGtfdCogICAgICBjdHJsYmxrOworICAgIENsaWVudElEICAgICAgICAgICAgICAgIGNpZDsKKworICAgIAorcHJpdmF0ZToKKyAgICBpbnQgICAgICAgICAgICAgICAgICAgICBnZXRDbGllbnRQaWQoKSBjb25zdCB7IHJldHVybiBtUGlkOyB9CisgICAgICAgIAorICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICBtUGlkOworICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgICAgICBtQml0bWFwOworICAgIFNvcnRlZFZlY3Rvcjx1aW50OF90PiAgICAgICBtSW5Vc2U7CisgICAgVmVjdG9yPExheWVyQmFzZUNsaWVudCo+ICAgIG1MYXllcnM7CisgICAgc3A8TWVtb3J5RGVhbGVyPiAgICAgICAgICAgIG1DYmxrSGVhcDsKKyAgICBzcDxTdXJmYWNlRmxpbmdlcj4gICAgICAgICAgbUZsaW5nZXI7CisgICAgc3A8TWVtb3J5RGVhbGVyPiAgICAgICAgICAgIG1TaGFyZWRIZWFwQWxsb2NhdG9yOworICAgIHNwPE1lbW9yeURlYWxlcj4gICAgICAgICAgICBtUE1lbUFsbG9jYXRvcjsKKyAgICBzcDxJTWVtb3J5PiAgICAgICAgICAgICAgICAgbUNibGtNZW1vcnk7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgR3JhcGhpY1BsYW5lCit7CitwdWJsaWM6CisgICAgc3RhdGljIHN0YXR1c190IG9yaWVudGF0aW9uVG9UcmFuc2Zyb20oaW50IG9yaWVudGF0aW9uLCBpbnQgdywgaW50IGgsCisgICAgICAgICAgICBUcmFuc2Zvcm0qIHRyKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHcmFwaGljUGxhbmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfkdyYXBoaWNQbGFuZSgpOworCisgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgICAgIGluaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgc2V0RGlzcGxheUhhcmR3YXJlKERpc3BsYXlIYXJkd2FyZSAqKTsKKyAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgc2V0VHJhbnNmb3JtKGNvbnN0IFRyYW5zZm9ybSYgdHIpOworICAgICAgICBzdGF0dXNfdCAgICAgICAgICAgICAgICBzZXRPcmllbnRhdGlvbihpbnQgb3JpZW50YXRpb24pOworCisgICAgICAgIGNvbnN0IERpc3BsYXlIYXJkd2FyZSYgIGRpc3BsYXlIYXJkd2FyZSgpIGNvbnN0OworICAgICAgICBjb25zdCBUcmFuc2Zvcm0mICAgICAgICB0cmFuc2Zvcm0oKSBjb25zdDsKK3ByaXZhdGU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdyYXBoaWNQbGFuZShjb25zdCBHcmFwaGljUGxhbmUmKTsKKyAgICAgICAgR3JhcGhpY1BsYW5lICAgICAgICAgICAgb3BlcmF0b3IgPSAoY29uc3QgR3JhcGhpY1BsYW5lJik7CisKKyAgICAgICAgRGlzcGxheUhhcmR3YXJlKiAgICAgICAgbUh3OworICAgICAgICBUcmFuc2Zvcm0gICAgICAgICAgICAgICBtVHJhbnNmb3JtOworICAgICAgICBUcmFuc2Zvcm0gICAgICAgICAgICAgICBtT3JpZW50YXRpb25UcmFuc2Zvcm07CisgICAgICAgIFRyYW5zZm9ybSAgICAgICAgICAgICAgIG1HbG9iYWxUcmFuc2Zvcm07Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworZW51bSB7CisgICAgZVRyYW5zYWN0aW9uTmVlZGVkICAgICAgPSAweDAxLAorICAgIGVUcmF2ZXJzYWxOZWVkZWQgICAgICAgID0gMHgwMgorfTsKKworY2xhc3MgU3VyZmFjZUZsaW5nZXIgOiBwdWJsaWMgQm5TdXJmYWNlQ29tcG9zZXIsIHByb3RlY3RlZCBUaHJlYWQKK3sKK3B1YmxpYzoKKyAgICBzdGF0aWMgdm9pZCBpbnN0YW50aWF0ZSgpOworICAgIHN0YXRpYyB2b2lkIHNodXRkb3duKCk7CisKKyAgICAgICAgICAgICAgICAgICAgU3VyZmFjZUZsaW5nZXIoKTsKKyAgICB2aXJ0dWFsICAgICAgICAgflN1cmZhY2VGbGluZ2VyKCk7CisgICAgICAgICAgICB2b2lkICAgIGluaXQoKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3Qgb25UcmFuc2FjdCgKKyAgICAgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncyk7CisKKyAgICB2aXJ0dWFsIHN0YXR1c190IGR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKTsKKworICAgIC8vIElTdXJmYWNlQ29tcG9zZXIgaW50ZXJmYWNlCisgICAgdmlydHVhbCBzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+ICAgY3JlYXRlQ29ubmVjdGlvbigpOworICAgIHZpcnR1YWwgc3A8SU1lbW9yeT4gICAgICAgICAgICAgICAgIGdldENibGsoKSBjb25zdDsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBib290RmluaXNoZWQoKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBvcGVuR2xvYmFsVHJhbnNhY3Rpb24oKTsKKyAgICB2aXJ0dWFsIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZUdsb2JhbFRyYW5zYWN0aW9uKCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgICAgICAgICAgICAgZnJlZXplRGlzcGxheShEaXNwbGF5SUQgZHB5LCB1aW50MzJfdCBmbGFncyk7CisgICAgdmlydHVhbCBzdGF0dXNfdCAgICAgICAgICAgICAgICAgICAgdW5mcmVlemVEaXNwbGF5KERpc3BsYXlJRCBkcHksIHVpbnQzMl90IGZsYWdzKTsKKyAgICB2aXJ0dWFsIGludCAgICAgICAgICAgICAgICAgICAgICAgICBzZXRPcmllbnRhdGlvbihEaXNwbGF5SUQgZHB5LCBpbnQgb3JpZW50YXRpb24pOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hbCgpIGNvbnN0OworICAgIHZpcnR1YWwgc3RhdHVzX3QgcmVxdWVzdEdQVShjb25zdCBzcDxJR1BVQ2FsbGJhY2s+JiBjYWxsYmFjaywgCisgICAgICAgICAgICBncHVfaW5mb190KiBncHUpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgcmV2b2tlR1BVKCk7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWxlYXNlZChEaXNwbGF5SUQgZHB5KTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5BY3F1aXJlZChEaXNwbGF5SUQgZHB5KTsKKworICAgICAgICAgICAgY29uc3Qgc3A8U3VyZmFjZUhlYXBNYW5hZ2VyPiYgZ2V0U3VyZmFjZUhlYXBNYW5hZ2VyKCkgY29uc3QgeyAKKyAgICAgICAgICAgICAgICByZXR1cm4gbVN1cmZhY2VIZWFwTWFuYWdlcjsgCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNvbnN0IHNwPEdQVUhhcmR3YXJlSW50ZXJmYWNlPiYgZ2V0R1BVKCkgY29uc3QgeworICAgICAgICAgICAgICAgIHJldHVybiBtR1BVOyAKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY29weWJpdF9kZXZpY2VfdCogZ2V0QmxpdEVuZ2luZSgpIGNvbnN0OworICAgICAgICAgICAgb3ZlcmxheV9jb250cm9sX2RldmljZV90KiBnZXRPdmVybGF5RW5naW5lKCkgY29uc3Q7CisKKyAgICAgICAgICAgIAorICAgIHN0YXR1c190IHJlbW92ZUxheWVyKExheWVyQmFzZSogbGF5ZXIpOworICAgIHN0YXR1c190IGFkZExheWVyKExheWVyQmFzZSogbGF5ZXIpOworICAgIHN0YXR1c190IGludmFsaWRhdGVMYXllclZpc2liaWxpdHkoTGF5ZXJCYXNlKiBsYXllcik7CisgICAgCitwcml2YXRlOgorICAgIGZyaWVuZCBjbGFzcyBCQ2xpZW50OworICAgIGZyaWVuZCBjbGFzcyBMYXllckJhc2U7CisgICAgZnJpZW5kIGNsYXNzIExheWVyQnVmZmVyOworICAgIGZyaWVuZCBjbGFzcyBMYXllckJhc2VDbGllbnQ7CisgICAgZnJpZW5kIGNsYXNzIExheWVyOworICAgIGZyaWVuZCBjbGFzcyBMYXllckJsdXI7CisKKyAgICBzcDxJU3VyZmFjZT4gY3JlYXRlU3VyZmFjZShDbGllbnRJRCBjbGllbnQsIGludCBwaWQsIAorICAgICAgICAgICAgSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpzdXJmYWNlX2RhdGFfdCogcGFyYW1zLAorICAgICAgICAgICAgRGlzcGxheUlEIGRpc3BsYXksIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIFBpeGVsRm9ybWF0IGZvcm1hdCwKKyAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzKTsKKworICAgIExheWVyQmFzZUNsaWVudCogY3JlYXRlTm9ybWFsU3VyZmFjZUxvY2tlZChDbGllbnQqIGNsaWVudCwgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICBpbnQzMl90IGlkLCB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBQaXhlbEZvcm1hdCBmb3JtYXQsIHVpbnQzMl90IGZsYWdzKTsKKworICAgIExheWVyQmFzZUNsaWVudCogY3JlYXRlQmx1clN1cmZhY2VMb2NrZWQoQ2xpZW50KiBjbGllbnQsIERpc3BsYXlJRCBkaXNwbGF5LAorICAgICAgICAgICAgaW50MzJfdCBpZCwgdWludDMyX3QgdywgdWludDMyX3QgaCwgdWludDMyX3QgZmxhZ3MpOworCisgICAgTGF5ZXJCYXNlQ2xpZW50KiBjcmVhdGVEaW1TdXJmYWNlTG9ja2VkKENsaWVudCogY2xpZW50LCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgICAgIGludDMyX3QgaWQsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIHVpbnQzMl90IGZsYWdzKTsKKworICAgIExheWVyQmFzZUNsaWVudCogY3JlYXRlUHVzaEJ1ZmZlcnNTdXJmYWNlTG9ja2VkKENsaWVudCogY2xpZW50LCBEaXNwbGF5SUQgZGlzcGxheSwKKyAgICAgICAgICAgIGludDMyX3QgaWQsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgsIHVpbnQzMl90IGZsYWdzKTsKKworICAgIHN0YXR1c190ICAgIGRlc3Ryb3lTdXJmYWNlKFN1cmZhY2VJRCBzdXJmYWNlX2lkKTsKKyAgICBzdGF0dXNfdCAgICBzZXRDbGllbnRTdGF0ZShDbGllbnRJRCBjaWQsIGludDMyX3QgY291bnQsIGNvbnN0IGxheWVyX3N0YXRlX3QqIHN0YXRlcyk7CisKKworICAgIGNsYXNzIExheWVyVmVjdG9yIHsKKyAgICBwdWJsaWM6CisgICAgICAgIGlubGluZSAgICAgICAgICAgICAgTGF5ZXJWZWN0b3IoKSB7IH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXllclZlY3Rvcihjb25zdCBMYXllclZlY3RvciYpOworICAgICAgICBpbmxpbmUgc2l6ZV90ICAgICAgIHNpemUoKSBjb25zdCB7IHJldHVybiBsYXllcnMuc2l6ZSgpOyB9CisgICAgICAgIGlubGluZSBMYXllckJhc2UqY29uc3QqIGFycmF5KCkgY29uc3QgeyByZXR1cm4gbGF5ZXJzLmFycmF5KCk7IH0KKyAgICAgICAgc3NpemVfdCAgICAgICAgICAgICBhZGQoTGF5ZXJCYXNlKiwgVmVjdG9yPExheWVyQmFzZSo+Ojpjb21wYXJfdCk7CisgICAgICAgIHNzaXplX3QgICAgICAgICAgICAgcmVtb3ZlKExheWVyQmFzZSopOworICAgICAgICBzc2l6ZV90ICAgICAgICAgICAgIHJlb3JkZXIoTGF5ZXJCYXNlKiwgVmVjdG9yPExheWVyQmFzZSo+Ojpjb21wYXJfdCk7CisgICAgICAgIHNzaXplX3QgICAgICAgICAgICAgaW5kZXhPZihMYXllckJhc2UqIGtleSwgc2l6ZV90IGd1ZXNzPTApIGNvbnN0OworICAgICAgICBpbmxpbmUgTGF5ZXJCYXNlKiAgIG9wZXJhdG9yIFtdIChzaXplX3QgaSkgY29uc3QgeyByZXR1cm4gbGF5ZXJzW2ldOyB9CisgICAgcHJpdmF0ZToKKyAgICAgICAgS2V5ZWRWZWN0b3I8TGF5ZXJCYXNlKiwgc2l6ZV90PiBsb29rdXA7CisgICAgICAgIFZlY3RvcjxMYXllckJhc2UqPiAgICAgICAgICAgICAgbGF5ZXJzOworICAgIH07CisKKyAgICBzdHJ1Y3QgU3RhdGUgeworICAgICAgICBTdGF0ZSgpIHsKKyAgICAgICAgICAgIG9yaWVudGF0aW9uID0gSVN1cmZhY2VDb21wb3Nlcjo6ZU9yaWVudGF0aW9uRGVmYXVsdDsKKyAgICAgICAgICAgIGZyZWV6ZURpc3BsYXkgPSAwOworICAgICAgICB9CisgICAgICAgIExheWVyVmVjdG9yICAgICBsYXllcnNTb3J0ZWRCeVo7CisgICAgICAgIHVpbnQ4X3QgICAgICAgICBvcmllbnRhdGlvbjsKKyAgICAgICAgdWludDhfdCAgICAgICAgIGZyZWV6ZURpc3BsYXk7CisgICAgfTsKKworICAgIGNsYXNzIERlbGF5ZWRUcmFuc2FjdGlvbiA6IHB1YmxpYyBUaHJlYWQKKyAgICB7CisgICAgICAgIGZyaWVuZCBjbGFzcyBTdXJmYWNlRmxpbmdlcjsKKyAgICAgICAgc3A8U3VyZmFjZUZsaW5nZXI+ICBtRmxpbmdlcjsKKyAgICAgICAgbnNlY3NfdCAgICAgICAgICAgICBtRGVsYXk7CisgICAgcHVibGljOgorICAgICAgICBEZWxheWVkVHJhbnNhY3Rpb24oY29uc3Qgc3A8U3VyZmFjZUZsaW5nZXI+JiBmbGluZ2VyLCBuc2Vjc190IGRlbGF5KQorICAgICAgICAgICAgOiBUaHJlYWQoZmFsc2UpLCBtRmxpbmdlcihmbGluZ2VyKSwgbURlbGF5KGRlbGF5KSB7CisgICAgICAgIH0KKyAgICAgICAgdmlydHVhbCBib29sIHRocmVhZExvb3AoKSB7CisgICAgICAgICAgICB1c2xlZXAobURlbGF5IC8gMTAwMCk7CisgICAgICAgICAgICBpZiAoYW5kcm9pZF9hdG9taWNfYW5kKH4xLAorICAgICAgICAgICAgICAgICAgICAmbUZsaW5nZXItPm1EZXBsYXllZFRyYW5zYWN0aW9uUGVuZGluZykgPT0gMSkgeworICAgICAgICAgICAgICAgIG1GbGluZ2VyLT5zaWduYWxFdmVudCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfTsKKworICAgIHZpcnR1YWwgYm9vbCAgICAgICAgdGhyZWFkTG9vcCgpOworICAgIHZpcnR1YWwgc3RhdHVzX3QgICAgcmVhZHlUb1J1bigpOworICAgIHZpcnR1YWwgdm9pZCAgICAgICAgb25GaXJzdFJlZigpOworCisgICAgY29uc3QgR3JhcGhpY1BsYW5lJiAgICAgZ3JhcGhpY1BsYW5lKGludCBkcHkpIGNvbnN0OworICAgICAgICAgIEdyYXBoaWNQbGFuZSYgICAgIGdyYXBoaWNQbGFuZShpbnQgZHB5KTsKKworICAgICAgICAgICAgdm9pZCAgICAgICAgd2FpdEZvckV2ZW50KCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBzaWduYWxFdmVudCgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgc2lnbmFsRGVsYXllZEV2ZW50KG5zZWNzX3QgZGVsYXkpOworCisgICAgICAgICAgICB2b2lkICAgICAgICBoYW5kbGVDb25zb2xlRXZlbnRzKCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBoYW5kbGVUcmFuc2FjdGlvbih1aW50MzJfdCB0cmFuc2FjdGlvbkZsYWdzKTsKKworICAgICAgICAgICAgdm9pZCAgICAgICAgY29tcHV0ZVZpc2libGVSZWdpb25zKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIExheWVyVmVjdG9yJiBjdXJyZW50TGF5ZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ2lvbiYgZGlydHlSZWdpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnaW9uJiB3b3JtaG9sZVJlZ2lvbik7CisKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGhhbmRsZVBhZ2VGbGlwKCk7CisgICAgICAgICAgICBib29sICAgICAgICBsb2NrUGFnZUZsaXAoY29uc3QgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMpOworICAgICAgICAgICAgdm9pZCAgICAgICAgdW5sb2NrUGFnZUZsaXAoY29uc3QgTGF5ZXJWZWN0b3ImIGN1cnJlbnRMYXllcnMpOworICAgICAgICAgICAgdm9pZCAgICAgICAgaGFuZGxlUmVwYWludCgpOworICAgICAgICAgICAgdm9pZCAgICAgICAgaGFuZGxlRGVidWdDcHUoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHNjaGVkdWxlQnJvYWRjYXN0KENsaWVudCogY2xpZW50KTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGV4ZWN1dGVTY2hlZHVsZWRCcm9hZGNhc3RzKCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBwb3N0RnJhbWVidWZmZXIoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGNvbXBvc2VTdXJmYWNlcyhjb25zdCBSZWdpb24mIGRpcnR5KTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIHVubG9ja0NsaWVudHMoKTsKKworCisgICAgICAgICAgICB2b2lkICAgICAgICBkZXN0cm95Q29ubmVjdGlvbihDbGllbnRJRCBjaWQpOworICAgICAgICAgICAgTGF5ZXJCYXNlQ2xpZW50KiBnZXRMYXllclVzZXJfbChTdXJmYWNlSUQgaW5kZXgpIGNvbnN0OworICAgICAgICAgICAgc3RhdHVzX3QgICAgYWRkTGF5ZXJfbChMYXllckJhc2UqIGxheWVyKTsKKyAgICAgICAgICAgIHN0YXR1c190ICAgIHJlbW92ZUxheWVyX2woTGF5ZXJCYXNlKiBsYXllcik7CisgICAgICAgICAgICB2b2lkICAgICAgICBkZXN0cm95X2FsbF9yZW1vdmVkX2xheWVyc19sKCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBmcmVlX3Jlc291cmNlc19sKCk7CisKKyAgICAgICAgICAgIHVpbnQzMl90ICAgIGdldFRyYW5zYWN0aW9uRmxhZ3ModWludDMyX3QgZmxhZ3MpOworICAgICAgICAgICAgdWludDMyX3QgICAgc2V0VHJhbnNhY3Rpb25GbGFncyh1aW50MzJfdCBmbGFncywgbnNlY3NfdCBkZWxheSA9IDApOworICAgICAgICAgICAgdm9pZCAgICAgICAgY29tbWl0VHJhbnNhY3Rpb24oKTsKKworCisgICAgICAgICAgICBmcmllbmQgY2xhc3MgRnJlZXplTG9jazsKKyAgICAgICAgICAgIHNwPEZyZWV6ZUxvY2s+IGdldEZyZWV6ZUxvY2soKSBjb25zdDsKKyAgICAgICAgICAgIGlubGluZSB2b2lkIGluY0ZyZWV6ZUNvdW50KCkgeyBtRnJlZXplQ291bnQrKzsgfQorICAgICAgICAgICAgaW5saW5lIHZvaWQgZGVjRnJlZXplQ291bnQoKSB7IGlmIChtRnJlZXplQ291bnQgPiAwKSBtRnJlZXplQ291bnQtLTsgfQorICAgICAgICAgICAgaW5saW5lIGJvb2wgaGFzRnJlZXplUmVxdWVzdCgpIGNvbnN0IHsgcmV0dXJuIG1GcmVlemVEaXNwbGF5OyB9CisgICAgICAgICAgICBpbmxpbmUgYm9vbCBpc0Zyb3plbigpIGNvbnN0IHsgCisgICAgICAgICAgICAgICAgcmV0dXJuIG1GcmVlemVEaXNwbGF5IHx8IG1GcmVlemVDb3VudD4wOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGRlYnVnRmxhc2hSZWdpb25zKCk7CisgICAgICAgICAgICB2b2lkICAgICAgICBkZWJ1Z1Nob3dGUFMoKSBjb25zdDsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGRyYXdXb3JtaG9sZSgpIGNvbnN0OworICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAvLyBhY2Nlc3MgbXVzdCBiZSBwcm90ZWN0ZWQgYnkgbVN0YXRlTG9jaworICAgIG11dGFibGUgICAgIE11dGV4ICAgICAgICAgICAgICAgICAgIG1TdGF0ZUxvY2s7CisgICAgICAgICAgICAgICAgU3RhdGUgICAgICAgICAgICAgICAgICAgbUN1cnJlbnRTdGF0ZTsKKyAgICAgICAgICAgICAgICBTdGF0ZSAgICAgICAgICAgICAgICAgICBtRHJhd2luZ1N0YXRlOworICAgIHZvbGF0aWxlICAgIGludDMyX3QgICAgICAgICAgICAgICAgIG1UcmFuc2FjdGlvbkZsYWdzOworICAgIHZvbGF0aWxlICAgIGludDMyX3QgICAgICAgICAgICAgICAgIG1UcmFuc2FjdGlvbkNvdW50OworICAgICAgICAgICAgICAgIENvbmRpdGlvbiAgICAgICAgICAgICAgIG1UcmFuc2FjdGlvbkNWOworCisgICAgICAgICAgICAgICAgLy8gcHJvdGVjdGVkIGJ5IG1TdGF0ZUxvY2sgKGJ1dCB3ZSBjb3VsZCB1c2UgYW5vdGhlciBsb2NrKQorICAgICAgICAgICAgICAgIFRva2VuaXplciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtVG9rZW5zOworICAgICAgICAgICAgICAgIERlZmF1bHRLZXllZFZlY3RvcjxDbGllbnRJRCwgQ2xpZW50Kj4gICBtQ2xpZW50c01hcDsKKyAgICAgICAgICAgICAgICBEZWZhdWx0S2V5ZWRWZWN0b3I8U3VyZmFjZUlELCBMYXllckJhc2VDbGllbnQqPiAgIG1MYXllck1hcDsKKyAgICAgICAgICAgICAgICBHcmFwaGljUGxhbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUdyYXBoaWNQbGFuZXNbMV07CisgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9yPExheWVyQmFzZSo+ICAgICAgICAgICAgICAgIG1SZW1vdmVkTGF5ZXJzOworICAgICAgICAgICAgICAgIFZlY3RvcjxDbGllbnQqPiAgICAgICAgICAgICAgICAgICAgICAgICBtRGlzY29ubmVjdGVkQ2xpZW50czsKKworICAgICAgICAgICAgICAgIC8vIGNvbnN0YW50IG1lbWJlcnMgKG5vIHN5bmNocm9uaXphdGlvbiBuZWVkZWQgZm9yIGFjY2VzcykKKyAgICAgICAgICAgICAgICBzcDxNZW1vcnlEZWFsZXI+ICAgICAgICAgICAgbVNlcnZlckhlYXA7CisgICAgICAgICAgICAgICAgc3A8SU1lbW9yeT4gICAgICAgICAgICAgICAgIG1TZXJ2ZXJDYmxrTWVtb3J5OworICAgICAgICAgICAgICAgIHN1cmZhY2VfZmxpbmdlcl9jYmxrX3QqICAgICBtU2VydmVyQ2JsazsKKyAgICAgICAgICAgICAgICBzcDxTdXJmYWNlSGVhcE1hbmFnZXI+ICAgICAgbVN1cmZhY2VIZWFwTWFuYWdlcjsKKyAgICAgICAgICAgICAgICBzcDxHUFVIYXJkd2FyZUludGVyZmFjZT4gICAgbUdQVTsKKyAgICAgICAgICAgICAgICBHTHVpbnQgICAgICAgICAgICAgICAgICAgICAgbVdvcm1ob2xlVGV4TmFtZTsKKyAgICAgICAgICAgICAgICBzcDxCb290QW5pbWF0aW9uPiAgICAgICAgICAgbUJvb3RBbmltYXRpb247CisgICAgICAgICAgICAgICAgbnNlY3NfdCAgICAgICAgICAgICAgICAgICAgIG1Cb290VGltZTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAvLyBDYW4gb25seSBhY2Nlc3NlZCBmcm9tIHRoZSBtYWluIHRocmVhZCwgdGhlc2UgbWVtYmVycworICAgICAgICAgICAgICAgIC8vIGRvbid0IG5lZWQgc3luY2hyb25pemF0aW9uCisgICAgICAgICAgICAgICAgUmVnaW9uICAgICAgICAgICAgICAgICAgICAgIG1EaXJ0eVJlZ2lvbjsKKyAgICAgICAgICAgICAgICBSZWdpb24gICAgICAgICAgICAgICAgICAgICAgbUludmFsaWRSZWdpb247CisgICAgICAgICAgICAgICAgUmVnaW9uICAgICAgICAgICAgICAgICAgICAgIG1Xb3JtaG9sZVJlZ2lvbjsKKyAgICAgICAgICAgICAgICBDbGllbnQqICAgICAgICAgICAgICAgICAgICAgbUxhc3RTY2hlZHVsZWRCcm9hZGNhc3Q7CisgICAgICAgICAgICAgICAgU29ydGVkVmVjdG9yPENsaWVudCo+ICAgICAgIG1TY2hlZHVsZWRCcm9hZGNhc3RzOworICAgICAgICAgICAgICAgIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICBtVmlzaWJsZVJlZ2lvbnNEaXJ0eTsKKyAgICAgICAgICAgICAgICBib29sICAgICAgICAgICAgICAgICAgICAgICAgbURlZmVyUmVsZWFzZUNvbnNvbGU7CisgICAgICAgICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgIG1GcmVlemVEaXNwbGF5OworICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICBtRnJlZXplQ291bnQ7CisgICAgICAgICAgICAgICAgbnNlY3NfdCAgICAgICAgICAgICAgICAgICAgIG1GcmVlemVEaXNwbGF5VGltZTsKKyAgICAgICAgICAgICAgICBmcmllbmQgY2xhc3MgT3JpZW50YXRpb25BbmltYXRpb247CisgICAgICAgICAgICAgICAgT3JpZW50YXRpb25BbmltYXRpb24qICAgICAgIG1PcmllbnRhdGlvbkFuaW1hdGlvbjsKKworICAgICAgICAgICAgICAgIC8vIGFjY2VzcyBwcm90ZWN0ZWQgYnkgbURlYnVnTG9jaworICAgIG11dGFibGUgICAgIE11dGV4ICAgICAgICAgICAgICAgICAgICAgICBtRGVidWdMb2NrOworICAgICAgICAgICAgICAgIHNwPENQVUdhdWdlPiAgICAgICAgICAgICAgICBtQ3B1R2F1Z2U7CisKKyAgICAgICAgICAgICAgICAvLyBkb24ndCB1c2UgYSBsb2NrIGZvciB0aGVzZSwgd2UgZG9uJ3QgY2FyZQorICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICBtRGVidWdSZWdpb247CisgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgIG1EZWJ1Z0NwdTsKKyAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgbURlYnVnRnBzOworICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICBtRGVidWdCYWNrZ3JvdW5kOworICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICBtRGVidWdOb0Jvb3RBbmltYXRpb247CisKKyAgICAgICAgICAgICAgICAvLyB0aGVzZSBhcmUgdGhyZWFkIHNhZmUKKyAgICBtdXRhYmxlICAgICBCYXJyaWVyICAgICAgICAgICAgICAgICAgICAgbVJlYWR5VG9SdW5CYXJyaWVyOworICAgIG11dGFibGUgICAgIFN1cmZhY2VGbGluZ2VyU3luY2hybyAgICAgICBtU3luY09iamVjdDsKKyAgICB2b2xhdGlsZSAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgbURlcGxheWVkVHJhbnNhY3Rpb25QZW5kaW5nOworCisgICAgICAgICAgICAgICAgLy8gYXRvbWljIHZhcmlhYmxlcworICAgICAgICAgICAgICAgIGVudW0geworICAgICAgICAgICAgICAgICAgICBlQ29uc29sZVJlbGVhc2VkID0gMSwKKyAgICAgICAgICAgICAgICAgICAgZUNvbnNvbGVBY3F1aXJlZCA9IDIKKyAgICAgICAgICAgICAgICB9OworICAgdm9sYXRpbGUgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICBtQ29uc29sZVNpZ25hbHM7CisKKyAgIC8vIG9ubHkgd3JpdHRlbiBpbiB0aGUgbWFpbiB0aHJlYWQsIG9ubHkgcmVhZCBpbiBvdGhlciB0aHJlYWRzCisgICB2b2xhdGlsZSAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgIG1TZWN1cmVGcmFtZUJ1ZmZlcjsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBGcmVlemVMb2NrIDogcHVibGljIExpZ2h0UmVmQmFzZTxGcmVlemVMb2NrPiB7CisgICAgU3VyZmFjZUZsaW5nZXIqIG1GbGluZ2VyOworcHVibGljOgorICAgIEZyZWV6ZUxvY2soU3VyZmFjZUZsaW5nZXIqIGZsaW5nZXIpCisgICAgICAgIDogbUZsaW5nZXIoZmxpbmdlcikgeworICAgICAgICBtRmxpbmdlci0+aW5jRnJlZXplQ291bnQoKTsKKyAgICB9CisgICAgfkZyZWV6ZUxvY2soKSB7CisgICAgICAgIG1GbGluZ2VyLT5kZWNGcmVlemVDb3VudCgpOworICAgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBCQ2xpZW50IDogcHVibGljIEJuU3VyZmFjZUZsaW5nZXJDbGllbnQKK3sKK3B1YmxpYzoKKyAgICBCQ2xpZW50KFN1cmZhY2VGbGluZ2VyICpmbGluZ2VyLCBDbGllbnRJRCBjaWQsCisgICAgICAgICAgICBjb25zdCBzcDxJTWVtb3J5PiYgY2Jsayk7CisgICAgfkJDbGllbnQoKTsKKworICAgIC8vIElTdXJmYWNlRmxpbmdlckNsaWVudCBpbnRlcmZhY2UKKyAgICB2aXJ0dWFsIHZvaWQgZ2V0Q29udHJvbEJsb2NrcyhzcDxJTWVtb3J5PiogY3RybCkgY29uc3Q7CisKKyAgICB2aXJ0dWFsIHNwPElTdXJmYWNlPiBjcmVhdGVTdXJmYWNlKAorICAgICAgICAgICAgc3VyZmFjZV9kYXRhX3QqIHBhcmFtcywgaW50IHBpZCwKKyAgICAgICAgICAgIERpc3BsYXlJRCBkaXNwbGF5LCB1aW50MzJfdCB3LCB1aW50MzJfdCBoLFBpeGVsRm9ybWF0IGZvcm1hdCwKKyAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzKTsKKworICAgIHZpcnR1YWwgc3RhdHVzX3QgZGVzdHJveVN1cmZhY2UoU3VyZmFjZUlEIHN1cmZhY2VJZCk7CisgICAgdmlydHVhbCBzdGF0dXNfdCBzZXRTdGF0ZShpbnQzMl90IGNvdW50LCBjb25zdCBsYXllcl9zdGF0ZV90KiBzdGF0ZXMpOworCitwcml2YXRlOgorICAgIENsaWVudElEICAgICAgICAgICAgbUlkOworICAgIFN1cmZhY2VGbGluZ2VyKiAgICAgbUZsaW5nZXI7CisgICAgc3A8SU1lbW9yeT4gICAgICAgICBtQ2JsazsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfU1VSRkFDRV9GTElOR0VSX0gKZGlmZiAtLWdpdCBhL2xpYnMvc3VyZmFjZWZsaW5nZXIvVG9rZW5pemVyLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvVG9rZW5pemVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZjUxZDZhCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9Ub2tlbml6ZXIuY3BwCkBAIC0wLDAgKzEsMTcyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpbmNsdWRlICJUb2tlbml6ZXIuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK0FORFJPSURfQkFTSUNfVFlQRVNfVFJBSVRTKFRva2VuaXplcjo6cnVuX3QpCisKK1Rva2VuaXplcjo6VG9rZW5pemVyKCkKK3sKK30KKworVG9rZW5pemVyOjpUb2tlbml6ZXIoY29uc3QgVG9rZW5pemVyJiBvdGhlcikKKyAgICA6IG1SYW5nZXMob3RoZXIubVJhbmdlcykKK3sKK30KKworVG9rZW5pemVyOjp+VG9rZW5pemVyKCkKK3sKK30KKwordWludDMyX3QgVG9rZW5pemVyOjphY3F1aXJlKCkKK3sKKyAgICBpZiAoIW1SYW5nZXMuc2l6ZSgpIHx8IG1SYW5nZXNbMF0uZmlyc3QpIHsKKyAgICAgICAgX2luc2VydFRva2VuQXQoMCwwKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIAorICAgIC8vIGp1c3QgZXh0ZW5kIHRoZSBmaXJzdCBydW4KKyAgICBjb25zdCBydW5fdCYgcnVuID0gbVJhbmdlc1swXTsKKyAgICB1aW50MzJfdCB0b2tlbiA9IHJ1bi5maXJzdCArIHJ1bi5sZW5ndGg7CisgICAgX2luc2VydFRva2VuQXQodG9rZW4sIDEpOworICAgIHJldHVybiB0b2tlbjsKK30KKworYm9vbCBUb2tlbml6ZXI6OmlzQWNxdWlyZWQodWludDMyX3QgdG9rZW4pIGNvbnN0Cit7CisgICAgcmV0dXJuIChfaW5kZXhPcmRlck9mKHRva2VuKSA+PSAwKTsKK30KKworc3RhdHVzX3QgVG9rZW5pemVyOjpyZXNlcnZlKHVpbnQzMl90IHRva2VuKQoreworICAgIHNpemVfdCBvOworICAgIGNvbnN0IHNzaXplX3QgaSA9IF9pbmRleE9yZGVyT2YodG9rZW4sICZvKTsKKyAgICBpZiAoaSA+PSAwKSB7CisgICAgICAgIHJldHVybiBCQURfVkFMVUU7IC8vIHRoaXMgdG9rZW4gaXMgYWxyZWFkeSB0YWtlbgorICAgIH0KKyAgICBzc2l6ZV90IGVyciA9IF9pbnNlcnRUb2tlbkF0KHRva2VuLCBvKTsKKyAgICByZXR1cm4gKGVycjwwKSA/IGVyciA6IHN0YXR1c190KE5PX0VSUk9SKTsKK30KKworc3RhdHVzX3QgVG9rZW5pemVyOjpyZWxlYXNlKHVpbnQzMl90IHRva2VuKQoreworICAgIGNvbnN0IHNzaXplX3QgaSA9IF9pbmRleE9yZGVyT2YodG9rZW4pOworICAgIGlmIChpID49IDApIHsKKyAgICAgICAgY29uc3QgcnVuX3QmIHJ1biA9IG1SYW5nZXNbaV07CisgICAgICAgIGlmICgodG9rZW4gPj0gcnVuLmZpcnN0KSAmJiAodG9rZW4gPCBydW4uZmlyc3QrcnVuLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIC8vIHRva2VuIGluIHRoaXMgcmFuZ2UsIHdlIG5lZWQgdG8gc3BsaXQKKyAgICAgICAgICAgIHJ1bl90JiBydW4gPSBtUmFuZ2VzLmVkaXRJdGVtQXQoaSk7CisgICAgICAgICAgICBpZiAoKHRva2VuID09IHJ1bi5maXJzdCkgfHwgKHRva2VuID09IHJ1bi5maXJzdCtydW4ubGVuZ3RoLTEpKSB7CisgICAgICAgICAgICAgICAgaWYgKHRva2VuID09IHJ1bi5maXJzdCkgeworICAgICAgICAgICAgICAgICAgICBydW4uZmlyc3QgKz0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcnVuLmxlbmd0aCAtPSAxOworICAgICAgICAgICAgICAgIGlmIChydW4ubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gWFhYOiBzaG91bGQgd2Ugc3lzdGVtYXRpY2FsbHkgcmVtb3ZlIGEgcnVuIHRoYXQncyBlbXB0eT8KKyAgICAgICAgICAgICAgICAgICAgbVJhbmdlcy5yZW1vdmVJdGVtc0F0KGkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gc3BsaXQgdGhlIHJ1bgorICAgICAgICAgICAgICAgIHJ1bl90IG5ld19ydW47CisgICAgICAgICAgICAgICAgbmV3X3J1bi5maXJzdCA9IHRva2VuKzE7CisgICAgICAgICAgICAgICAgbmV3X3J1bi5sZW5ndGggPSBydW4uZmlyc3QrcnVuLmxlbmd0aCAtIG5ld19ydW4uZmlyc3Q7CisgICAgICAgICAgICAgICAgcnVuLmxlbmd0aCA9IHRva2VuIC0gcnVuLmZpcnN0OworICAgICAgICAgICAgICAgIG1SYW5nZXMuaW5zZXJ0QXQobmV3X3J1biwgaSsxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7Cit9CisKK3NzaXplX3QgVG9rZW5pemVyOjpfaW5kZXhPcmRlck9mKHVpbnQzMl90IHRva2VuLCBzaXplX3QqIG9yZGVyKSBjb25zdAoreworICAgIC8vIGJpbmFyeSBzZWFyY2gKKyAgICBzc2l6ZV90IGVyciA9IE5BTUVfTk9UX0ZPVU5EOworICAgIHNzaXplX3QgbCA9IDA7CisgICAgc3NpemVfdCBoID0gbVJhbmdlcy5zaXplKCktMTsKKyAgICBzc2l6ZV90IG1pZDsKKyAgICBjb25zdCBydW5fdCogYSA9IG1SYW5nZXMuYXJyYXkoKTsKKyAgICB3aGlsZSAobCA8PSBoKSB7CisgICAgICAgIG1pZCA9IGwgKyAoaCAtIGwpLzI7CisgICAgICAgIGNvbnN0IHJ1bl90KiBjb25zdCBjdXJyID0gYSArIG1pZDsKKyAgICAgICAgaW50IGMgPSAwOworICAgICAgICBpZiAodG9rZW4gPCBjdXJyLT5maXJzdCkgICAgICAgICAgICAgICAgICAgICAgICBjID0gMTsKKyAgICAgICAgZWxzZSBpZiAodG9rZW4gPj0gY3Vyci0+Zmlyc3QrY3Vyci0+bGVuZ3RoKSAgICAgYyA9IC0xOworICAgICAgICBpZiAoYyA9PSAwKSB7CisgICAgICAgICAgICBlcnIgPSBsID0gbWlkOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0gZWxzZSBpZiAoYyA8IDApIHsKKyAgICAgICAgICAgIGwgPSBtaWQgKyAxOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaCA9IG1pZCAtIDE7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKG9yZGVyKSAqb3JkZXIgPSBsOworICAgIHJldHVybiBlcnI7Cit9CisKK3NzaXplX3QgVG9rZW5pemVyOjpfaW5zZXJ0VG9rZW5BdCh1aW50MzJfdCB0b2tlbiwgc2l6ZV90IGluZGV4KQoreworICAgIGNvbnN0IHNpemVfdCBjID0gbVJhbmdlcy5zaXplKCk7CisKKyAgICBpZiAoaW5kZXggPj0gMSkgeworICAgICAgICAvLyBkbyB3ZSBuZWVkIHRvIG1lcmdlIHdpdGggdGhlIHByZXZpb3VzIHJ1bj8KKyAgICAgICAgcnVuX3QmIHAgPSBtUmFuZ2VzLmVkaXRJdGVtQXQoaW5kZXgtMSk7CisgICAgICAgIGlmIChwLmZpcnN0K3AubGVuZ3RoID09IHRva2VuKSB7CisgICAgICAgICAgICBwLmxlbmd0aCArPSAxOworICAgICAgICAgICAgaWYgKGluZGV4IDwgYykgeworICAgICAgICAgICAgICAgIGNvbnN0IHJ1bl90JiBuID0gbVJhbmdlc1tpbmRleF07CisgICAgICAgICAgICAgICAgaWYgKHRva2VuKzEgPT0gbi5maXJzdCkgeworICAgICAgICAgICAgICAgICAgICBwLmxlbmd0aCArPSBuLmxlbmd0aDsKKyAgICAgICAgICAgICAgICAgICAgbVJhbmdlcy5yZW1vdmVJdGVtc0F0KGluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaWYgKGluZGV4IDwgYykgeworICAgICAgICAvLyBkbyB3ZSBuZWVkIHRvIG1lcmdlIHdpdGggdGhlIG5leHQgcnVuPworICAgICAgICBydW5fdCYgbiA9IG1SYW5nZXMuZWRpdEl0ZW1BdChpbmRleCk7CisgICAgICAgIGlmICh0b2tlbisxID09IG4uZmlyc3QpIHsKKyAgICAgICAgICAgIG4uZmlyc3QgLT0gMTsKKyAgICAgICAgICAgIG4ubGVuZ3RoICs9IDE7CisgICAgICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gbVJhbmdlcy5pbnNlcnRBdChydW5fdCh0b2tlbiwxKSwgaW5kZXgpOworfQorCit2b2lkIFRva2VuaXplcjo6ZHVtcCgpIGNvbnN0Cit7CisgICAgY29uc3QgcnVuX3QqIHJhbmdlcyA9IG1SYW5nZXMuYXJyYXkoKTsKKyAgICBjb25zdCBzaXplX3QgYyA9IG1SYW5nZXMuc2l6ZSgpOworICAgIHByaW50ZigiVG9rZW5pemVyICglcCwgc2l6ZSA9ICVsdSlcbiIsIHRoaXMsIGMpOworICAgIGZvciAoc2l6ZV90IGk9MCA7IGk8YyA7IGkrKykgeworICAgICAgICBwcmludGYoIiVsdTogKCV1LCAldSlcbiIsIGksIHJhbmdlc1tpXS5maXJzdCwgcmFuZ2VzW2ldLmxlbmd0aCk7CisgICAgfQorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1Rva2VuaXplci5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9Ub2tlbml6ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjMwNTdkCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9Ub2tlbml6ZXIuaApAQCAtMCwwICsxLDU3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1RPS0VOSVpFUl9ICisjZGVmaW5lIEFORFJPSURfVE9LRU5JWkVSX0gKKworI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgVG9rZW5pemVyCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgVG9rZW5pemVyKCk7CisgICAgICAgICAgICAgICAgVG9rZW5pemVyKGNvbnN0IFRva2VuaXplciYgb3RoZXIpOworICAgICAgICAgICAgICAgIH5Ub2tlbml6ZXIoKTsKKworICAgIHVpbnQzMl90ICAgIGFjcXVpcmUoKTsKKyAgICBzdGF0dXNfdCAgICByZXNlcnZlKHVpbnQzMl90IHRva2VuKTsKKyAgICBzdGF0dXNfdCAgICByZWxlYXNlKHVpbnQzMl90IHRva2VuKTsKKyAgICBib29sICAgICAgICBpc0FjcXVpcmVkKHVpbnQzMl90IHRva2VuKSBjb25zdDsKKworICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgc3RydWN0IHJ1bl90IHsKKyAgICAgICAgcnVuX3QoKSB7fTsKKyAgICAgICAgcnVuX3QodWludDMyX3QgZiwgdWludDMyX3QgbCkgOiBmaXJzdChmKSwgbGVuZ3RoKGwpIHt9CisgICAgICAgIHVpbnQzMl90ICAgIGZpcnN0OworICAgICAgICB1aW50MzJfdCAgICBsZW5ndGg7CisgICAgfTsKK3ByaXZhdGU6CisgICAgc3NpemVfdCBfaW5kZXhPcmRlck9mKHVpbnQzMl90IHRva2VuLCBzaXplX3QqIG9yZGVyPTApIGNvbnN0OworICAgIHNzaXplX3QgX2luc2VydFRva2VuQXQodWludDMyX3QgdG9rZW4sIHNpemVfdCBpbmRleCk7CisgICAgVmVjdG9yPHJ1bl90PiAgIG1SYW5nZXM7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvLyBBTkRST0lEX1RPS0VOSVpFUl9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1RyYW5zZm9ybS5jcHAgYi9saWJzL3N1cmZhY2VmbGluZ2VyL1RyYW5zZm9ybS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmVjN2E2NAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvVHJhbnNmb3JtLmNwcApAQCAtMCwwICsxLDIwNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDx1aS9SZWdpb24uaD4KKworI2luY2x1ZGUgPHByaXZhdGUvcGl4ZWxmbGluZ2VyL2dnbF9maXhlZC5oPgorCisjaW5jbHVkZSAiVHJhbnNmb3JtLmgiCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUcmFuc2Zvcm06OlRyYW5zZm9ybSgpCisgICAgOiBtVHlwZSgwKQoreworICAgIG1UcmFuc2Zvcm0ucmVzZXQoKTsKK30KKworVHJhbnNmb3JtOjpUcmFuc2Zvcm0oY29uc3QgVHJhbnNmb3JtJiAgb3RoZXIpCisgICAgOiBtVHJhbnNmb3JtKG90aGVyLm1UcmFuc2Zvcm0pLCBtVHlwZShvdGhlci5tVHlwZSkKK3sKK30KKworVHJhbnNmb3JtOjp+VHJhbnNmb3JtKCkgeworfQorCitUcmFuc2Zvcm0gVHJhbnNmb3JtOjpvcGVyYXRvciAqIChjb25zdCBUcmFuc2Zvcm0mIHJocykgY29uc3QKK3sKKyAgICBpZiAoTElLRUxZKG1UeXBlID09IDApKQorICAgICAgICByZXR1cm4gcmhzOworCisgICAgVHJhbnNmb3JtIHIoKnRoaXMpOworICAgIHIubVRyYW5zZm9ybS5wcmVDb25jYXQocmhzLm1UcmFuc2Zvcm0pOworICAgIHIubVR5cGUgfD0gcmhzLm1UeXBlOworICAgIHJldHVybiByOworfQorCitmbG9hdCBUcmFuc2Zvcm06Om9wZXJhdG9yIFtdIChpbnQgaSkgY29uc3QKK3sKKyAgICBmbG9hdCByID0gMDsKKyAgICBzd2l0Y2goaSkgeworICAgICAgICBjYXNlIDA6IHIgPSBTa1NjYWxhclRvRmxvYXQoIG1UcmFuc2Zvcm1bU2tNYXRyaXg6OmtNU2NhbGVYXSApOyAgYnJlYWs7CisgICAgICAgIGNhc2UgMTogciA9IFNrU2NhbGFyVG9GbG9hdCggbVRyYW5zZm9ybVtTa01hdHJpeDo6a01Ta2V3WF0gKTsgICBicmVhazsKKyAgICAgICAgY2FzZSAyOiByID0gU2tTY2FsYXJUb0Zsb2F0KCBtVHJhbnNmb3JtW1NrTWF0cml4OjprTVNrZXdZXSApOyAgIGJyZWFrOworICAgICAgICBjYXNlIDM6IHIgPSBTa1NjYWxhclRvRmxvYXQoIG1UcmFuc2Zvcm1bU2tNYXRyaXg6OmtNU2NhbGVZXSApOyAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiByOworfQorCit1aW50OF90IFRyYW5zZm9ybTo6dHlwZSgpIGNvbnN0Cit7CisgICAgaWYgKFVOTElLRUxZKG1UeXBlICYgMHg4MDAwMDAwMCkpIHsKKyAgICAgICAgbVR5cGUgPSBtVHJhbnNmb3JtLmdldFR5cGUoKTsKKyAgICB9CisgICAgcmV0dXJuIHVpbnQ4X3QobVR5cGUgJiAweEZGKTsKK30KKworYm9vbCBUcmFuc2Zvcm06OnRyYW5zZm9ybWVkKCkgY29uc3QgeworICAgIHJldHVybiB0eXBlKCkgPiBTa01hdHJpeDo6a1RyYW5zbGF0ZV9NYXNrOworfQorCitpbnQgVHJhbnNmb3JtOjp0eCgpIGNvbnN0IHsKKyAgICByZXR1cm4gU2tTY2FsYXJSb3VuZCggbVRyYW5zZm9ybVtTa01hdHJpeDo6a01UcmFuc1hdICk7Cit9CisKK2ludCBUcmFuc2Zvcm06OnR5KCkgY29uc3QgeworICAgIHJldHVybiBTa1NjYWxhclJvdW5kKCBtVHJhbnNmb3JtW1NrTWF0cml4OjprTVRyYW5zWV0gKTsKK30KKwordm9pZCBUcmFuc2Zvcm06OnJlc2V0KCkgeworICAgIG1UcmFuc2Zvcm0ucmVzZXQoKTsKKyAgICBtVHlwZSA9IDA7Cit9CisKK3ZvaWQgVHJhbnNmb3JtOjpzZXQoIGZsb2F0IHh4LCBmbG9hdCB4eSwKKyAgICAgICAgICAgICAgICAgICAgIGZsb2F0IHl4LCBmbG9hdCB5eSkKK3sKKyAgICBtVHJhbnNmb3JtLnNldChTa01hdHJpeDo6a01TY2FsZVgsIFNrRmxvYXRUb1NjYWxhcih4eCkpOworICAgIG1UcmFuc2Zvcm0uc2V0KFNrTWF0cml4OjprTVNrZXdYLCBTa0Zsb2F0VG9TY2FsYXIoeHkpKTsKKyAgICBtVHJhbnNmb3JtLnNldChTa01hdHJpeDo6a01Ta2V3WSwgU2tGbG9hdFRvU2NhbGFyKHl4KSk7CisgICAgbVRyYW5zZm9ybS5zZXQoU2tNYXRyaXg6OmtNU2NhbGVZLCBTa0Zsb2F0VG9TY2FsYXIoeXkpKTsKKyAgICBtVHlwZSB8PSAweDgwMDAwMDAwOworfQorCit2b2lkIFRyYW5zZm9ybTo6c2V0KGludCB0eCwgaW50IHR5KQoreworICAgIGlmICh0eCB8IHR5KSB7CisgICAgICAgIG1UcmFuc2Zvcm0uc2V0KFNrTWF0cml4OjprTVRyYW5zWCwgU2tJbnRUb1NjYWxhcih0eCkpOworICAgICAgICBtVHJhbnNmb3JtLnNldChTa01hdHJpeDo6a01UcmFuc1ksIFNrSW50VG9TY2FsYXIodHkpKTsKKyAgICAgICAgbVR5cGUgfD0gU2tNYXRyaXg6OmtUcmFuc2xhdGVfTWFzazsKKyAgICB9IGVsc2UgeworICAgICAgICBtVHJhbnNmb3JtLnNldChTa01hdHJpeDo6a01UcmFuc1gsIDApOworICAgICAgICBtVHJhbnNmb3JtLnNldChTa01hdHJpeDo6a01UcmFuc1ksIDApOworICAgICAgICBtVHlwZSAmPSB+U2tNYXRyaXg6OmtUcmFuc2xhdGVfTWFzazsKKyAgICB9Cit9CisKK3ZvaWQgVHJhbnNmb3JtOjp0cmFuc2Zvcm0oR0xmaXhlZCogcG9pbnQsIGludCB4LCBpbnQgeSkgY29uc3QKK3sKKyAgICBTa1BvaW50IHM7CisgICAgbVRyYW5zZm9ybS5tYXBYWShTa0ludFRvU2NhbGFyKHgpLCBTa0ludFRvU2NhbGFyKHkpLCAmcyk7CisgICAgcG9pbnRbMF0gPSBTa1NjYWxhclRvRml4ZWQocy5mWCk7CisgICAgcG9pbnRbMV0gPSBTa1NjYWxhclRvRml4ZWQocy5mWSk7Cit9CisKK1JlY3QgVHJhbnNmb3JtOjptYWtlQm91bmRzKGludCB3LCBpbnQgaCkgY29uc3QKK3sKKyAgICBSZWN0IHI7CisgICAgU2tSZWN0IGQsIHM7CisgICAgcy5zZXQoMCwgMCwgU2tJbnRUb1NjYWxhcih3KSwgU2tJbnRUb1NjYWxhcihoKSk7CisgICAgbVRyYW5zZm9ybS5tYXBSZWN0KCZkLCBzKTsKKyAgICByLmxlZnQgICA9IFNrU2NhbGFyUm91bmQoIGQuZkxlZnQgKTsKKyAgICByLnRvcCAgICA9IFNrU2NhbGFyUm91bmQoIGQuZlRvcCApOworICAgIHIucmlnaHQgID0gU2tTY2FsYXJSb3VuZCggZC5mUmlnaHQgKTsKKyAgICByLmJvdHRvbSA9IFNrU2NhbGFyUm91bmQoIGQuZkJvdHRvbSApOworICAgIHJldHVybiByOworfQorCitSZWN0IFRyYW5zZm9ybTo6dHJhbnNmb3JtKGNvbnN0IFJlY3QmIGJvdW5kcykgY29uc3QKK3sKKyAgICBSZWN0IHI7CisgICAgU2tSZWN0IGQsIHM7CisgICAgcy5zZXQoICBTa0ludFRvU2NhbGFyKCBib3VuZHMubGVmdCApLAorICAgICAgICAgICAgU2tJbnRUb1NjYWxhciggYm91bmRzLnRvcCApLAorICAgICAgICAgICAgU2tJbnRUb1NjYWxhciggYm91bmRzLnJpZ2h0ICksCisgICAgICAgICAgICBTa0ludFRvU2NhbGFyKCBib3VuZHMuYm90dG9tICkpOworICAgIG1UcmFuc2Zvcm0ubWFwUmVjdCgmZCwgcyk7CisgICAgci5sZWZ0ICAgPSBTa1NjYWxhclJvdW5kKCBkLmZMZWZ0ICk7CisgICAgci50b3AgICAgPSBTa1NjYWxhclJvdW5kKCBkLmZUb3AgKTsKKyAgICByLnJpZ2h0ICA9IFNrU2NhbGFyUm91bmQoIGQuZlJpZ2h0ICk7CisgICAgci5ib3R0b20gPSBTa1NjYWxhclJvdW5kKCBkLmZCb3R0b20gKTsKKyAgICByZXR1cm4gcjsKK30KKworUmVnaW9uIFRyYW5zZm9ybTo6dHJhbnNmb3JtKGNvbnN0IFJlZ2lvbiYgcmVnKSBjb25zdAoreworICAgIFJlZ2lvbiBvdXQ7CisgICAgaWYgKFVOTElLRUxZKHRyYW5zZm9ybWVkKCkpKSB7CisgICAgICAgIGlmIChMSUtFTFkocHJlc2VydmVSZWN0cygpKSkgeworICAgICAgICAgICAgUmVjdCByOworICAgICAgICAgICAgUmVnaW9uOjppdGVyYXRvciBpdGVyYXRvcihyZWcpOworICAgICAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLml0ZXJhdGUoJnIpKSB7CisgICAgICAgICAgICAgICAgb3V0Lm9yU2VsZih0cmFuc2Zvcm0ocikpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb3V0LnNldCh0cmFuc2Zvcm0ocmVnLmJvdW5kcygpKSk7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBvdXQgPSByZWcudHJhbnNsYXRlKHR4KCksIHR5KCkpOworICAgIH0KKyAgICByZXR1cm4gb3V0OworfQorCitpbnQzMl90IFRyYW5zZm9ybTo6Z2V0T3JpZW50YXRpb24oKSBjb25zdAoreworICAgIHVpbnQzMl90IGZsYWdzID0gMDsKKyAgICBpZiAoVU5MSUtFTFkodHJhbnNmb3JtZWQoKSkpIHsKKyAgICAgICAgU2tTY2FsYXIgYSA9IG1UcmFuc2Zvcm1bU2tNYXRyaXg6OmtNU2NhbGVYXTsKKyAgICAgICAgU2tTY2FsYXIgYiA9IG1UcmFuc2Zvcm1bU2tNYXRyaXg6OmtNU2tld1hdOworICAgICAgICBTa1NjYWxhciBjID0gbVRyYW5zZm9ybVtTa01hdHJpeDo6a01Ta2V3WV07CisgICAgICAgIFNrU2NhbGFyIGQgPSBtVHJhbnNmb3JtW1NrTWF0cml4OjprTVNjYWxlWV07CisgICAgICAgIGlmIChiPT0wICYmIGM9PTAgJiYgYSAmJiBkKSB7CisgICAgICAgICAgICBpZiAoYTwwKSAgICBmbGFncyB8PSBGTElQX0g7CisgICAgICAgICAgICBpZiAoZDwwKSAgICBmbGFncyB8PSBGTElQX1Y7CisgICAgICAgIH0gZWxzZSBpZiAoYiAmJiBjICYmIGE9PTAgJiYgZD09MCkgeworICAgICAgICAgICAgZmxhZ3MgfD0gUk9UXzkwOworICAgICAgICAgICAgaWYgKGI+MCkgICAgZmxhZ3MgfD0gRkxJUF9IOworICAgICAgICAgICAgaWYgKGM8MCkgICAgZmxhZ3MgfD0gRkxJUF9WOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmxhZ3MgPSAweDgwMDAwMDAwOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBmbGFnczsKK30KKworYm9vbCBUcmFuc2Zvcm06OnByZXNlcnZlUmVjdHMoKSBjb25zdAoreworICAgIHJldHVybiBtVHJhbnNmb3JtLnJlY3RTdGF5c1JlY3QoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1RyYW5zZm9ybS5oIGIvbGlicy9zdXJmYWNlZmxpbmdlci9UcmFuc2Zvcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjQ4MzVlCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy9zdXJmYWNlZmxpbmdlci9UcmFuc2Zvcm0uaApAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1RSQU5TRk9STV9ICisjZGVmaW5lIEFORFJPSURfVFJBTlNGT1JNX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dWkvUG9pbnQuaD4KKyNpbmNsdWRlIDx1aS9SZWN0Lmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisKKyNpbmNsdWRlIDxjb3JlL1NrTWF0cml4Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgUmVnaW9uOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgVHJhbnNmb3JtCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybSgpOworICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0oY29uc3QgVHJhbnNmb3JtJiAgb3RoZXIpOworICAgICAgICAgICAgICAgICAgICB+VHJhbnNmb3JtKCk7CisKKyAgICAgICAgICAgIGVudW0gb3JpZW50YXRpb25fZmxhZ3MgeworICAgICAgICAgICAgICAgIFJPVF8wICAgPSAweDAwMDAwMDAwLAorICAgICAgICAgICAgICAgIEZMSVBfSCAgPSAweDAwMDAwMDAxLAorICAgICAgICAgICAgICAgIEZMSVBfViAgPSAweDAwMDAwMDAyLAorICAgICAgICAgICAgICAgIFJPVF85MCAgPSAweDAwMDAwMDA0LAorICAgICAgICAgICAgICAgIFJPVF8xODAgPSBGTElQX0h8RkxJUF9WLAorICAgICAgICAgICAgICAgIFJPVF8yNzAgPSBST1RfMTgwfFJPVF85MCwKKyAgICAgICAgICAgICAgICBST1RfSU5WQUxJRCA9IDB4ODAwMDAwMDAKKyAgICAgICAgICAgIH07CisKKyAgICAgICAgICAgIGJvb2wgICAgdHJhbnNmb3JtZWQoKSBjb25zdDsKKyAgICAgICAgICAgIGludDMyX3QgZ2V0T3JpZW50YXRpb24oKSBjb25zdDsKKyAgICAgICAgICAgIGJvb2wgICAgcHJlc2VydmVSZWN0cygpIGNvbnN0OworICAgICAgICAgICAgCisgICAgICAgICAgICBpbnQgICAgIHR4KCkgY29uc3Q7CisgICAgICAgICAgICBpbnQgICAgIHR5KCkgY29uc3Q7CisgICAgICAgIAorICAgICAgICAgICAgdm9pZCAgICByZXNldCgpOworICAgICAgICAgICAgdm9pZCAgICBzZXQoZmxvYXQgeHgsIGZsb2F0IHh5LCBmbG9hdCB5eCwgZmxvYXQgeXkpOworICAgICAgICAgICAgdm9pZCAgICBzZXQoaW50IHR4LCBpbnQgdHkpOworCisgICAgICAgICAgICBSZWN0ICAgIG1ha2VCb3VuZHMoaW50IHcsIGludCBoKSBjb25zdDsKKyAgICAgICAgICAgIHZvaWQgICAgdHJhbnNmb3JtKEdMZml4ZWQqIHBvaW50LCBpbnQgeCwgaW50IHkpIGNvbnN0OworICAgICAgICAgICAgUmVnaW9uICB0cmFuc2Zvcm0oY29uc3QgUmVnaW9uJiByZWcpIGNvbnN0OworICAgICAgICAgICAgUmVjdCAgICB0cmFuc2Zvcm0oY29uc3QgUmVjdCYgYm91bmRzKSBjb25zdDsKKworICAgICAgICAgICAgVHJhbnNmb3JtIG9wZXJhdG9yICogKGNvbnN0IFRyYW5zZm9ybSYgcmhzKSBjb25zdDsKKyAgICAgICAgICAgIGZsb2F0IG9wZXJhdG9yIFtdIChpbnQgaSkgY29uc3Q7CisKKyAgICBpbmxpbmUgdWludDMyX3QgZ2V0VHlwZSgpIGNvbnN0IHsgcmV0dXJuIHR5cGUoKTsgfQorICAgICAgICAgICAgCisgICAgaW5saW5lIFRyYW5zZm9ybShib29sKSA6IG1UeXBlKDB4RkYpIHsgfTsKKworcHJpdmF0ZToKKyAgICB1aW50OF90ICAgICB0eXBlKCkgY29uc3Q7CisKK3ByaXZhdGU6CisgICAgICAgICAgICBTa01hdHJpeCAgICBtVHJhbnNmb3JtOworICAgIG11dGFibGUgdWludDMyX3QgICAgbVR5cGU7ICAgICAgCit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvKiBBTkRST0lEX1RSQU5TRk9STV9IICovCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1ZSYW1IZWFwLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvVlJhbUhlYXAuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjY2Q3MWYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL1ZSYW1IZWFwLmNwcApAQCAtMCwwICsxLDE3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZUZsaW5nZXIiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKworI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKyNpbmNsdWRlIDxjdXRpbHMvcHJvcGVydGllcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5RGVhbGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5QmFzZS5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBQbWVtLmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5SGVhcEJhc2UuaD4KKworI2luY2x1ZGUgIkdQVUhhcmR3YXJlL0dQVUhhcmR3YXJlLmgiCisjaW5jbHVkZSAiU3VyZmFjZUZsaW5nZXIuaCIKKyNpbmNsdWRlICJWUmFtSGVhcC5oIgorCisjaWYgSEFWRV9BTkRST0lEX09TCisjaW5jbHVkZSA8bGludXgvYW5kcm9pZF9wbWVtLmg+CisjZW5kaWYKKworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvKgorICogQW1vdW50IG9mIG1lbW9yeSB3ZSByZXNlcnZlIGZvciBzdXJmYWNlLCBwZXIgY2xpZW50IGluIFBNRU0KKyAqIChQTUVNIGlzIHVzZWQgZm9yIDJEIGFjY2VsZXJhdGlvbikKKyAqIDggTUIgb2YgYWRkcmVzcyBzcGFjZSBwZXIgY2xpZW50IHNob3VsZCBiZSBlbm91Z2guCisgKi8KK3N0YXRpYyBjb25zdCBpbnQgUE1FTV9TSVpFID0gaW50KDggKiAxMDI0ICogMTAyNCk7CisKK2ludCBTdXJmYWNlSGVhcE1hbmFnZXI6Omdsb2JhbF9wbWVtX2hlYXAgPSAwOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU3VyZmFjZUhlYXBNYW5hZ2VyOjpTdXJmYWNlSGVhcE1hbmFnZXIoY29uc3Qgc3A8U3VyZmFjZUZsaW5nZXI+JiBmbGluZ2VyLCAKKyAgICAgICAgc2l6ZV90IGNsaWVudEhlYXBTaXplKQorICAgIDogbUZsaW5nZXIoZmxpbmdlciksIG1DbGllbnRIZWFwU2l6ZShjbGllbnRIZWFwU2l6ZSkKK3sKKyAgICBTdXJmYWNlSGVhcE1hbmFnZXI6Omdsb2JhbF9wbWVtX2hlYXAgPSAxOworfQorCitTdXJmYWNlSGVhcE1hbmFnZXI6On5TdXJmYWNlSGVhcE1hbmFnZXIoKQoreworfQorCit2b2lkIFN1cmZhY2VIZWFwTWFuYWdlcjo6b25GaXJzdFJlZigpCit7CisgICAgaWYgKGdsb2JhbF9wbWVtX2hlYXApIHsKKyAgICAgICAgY29uc3QgY2hhciogZGV2aWNlID0gIi9kZXYvcG1lbSI7CisgICAgICAgIG1QTWVtSGVhcCA9IG5ldyBQTWVtSGVhcChkZXZpY2UsIFBNRU1fU0laRSk7CisgICAgICAgIGlmIChtUE1lbUhlYXAtPmJhc2UoKSA9PSBNQVBfRkFJTEVEKSB7CisgICAgICAgICAgICBtUE1lbUhlYXAuY2xlYXIoKTsKKyAgICAgICAgICAgIGdsb2JhbF9wbWVtX2hlYXAgPSAwOworICAgICAgICB9CisgICAgfQorfQorCitzcDxNZW1vcnlEZWFsZXI+IFN1cmZhY2VIZWFwTWFuYWdlcjo6Y3JlYXRlSGVhcCgKKyAgICAgICAgdWludDMyX3QgZmxhZ3MsCisgICAgICAgIHBpZF90IGNsaWVudF9waWQsCisgICAgICAgIGNvbnN0IHNwPE1lbW9yeURlYWxlcj4mIGRlZmF1bHRBbGxvY2F0b3IpCit7CisgICAgc3A8TWVtb3J5RGVhbGVyPiBkZWFsZXI7IAorCisgICAgaWYgKGZsYWdzICYgSVN1cmZhY2VDb21wb3Nlcjo6ZUdQVSkgeworICAgICAgICAvLyBkb24ndCBncmFudCBHUFUgbWVtb3J5IGlmIEdQVSBpcyBkaXNhYmxlZAorICAgICAgICBjaGFyIHZhbHVlW1BST1BFUlRZX1ZBTFVFX01BWF07CisgICAgICAgIHByb3BlcnR5X2dldCgiZGVidWcuZWdsLmh3IiwgdmFsdWUsICIxIik7CisgICAgICAgIGlmIChhdG9pKHZhbHVlKSA9PSAwKSB7CisgICAgICAgICAgICBmbGFncyAmPSB+SVN1cmZhY2VDb21wb3Nlcjo6ZUdQVTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChmbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVHUFUpIHsKKyAgICAgICAgLy8gRklYTUU6IHRoaXMgaXMgbXNtNzIwMUEgc3BlY2lmaWMsIHdoZXJlIGdwdSBzdXJmYWNlcyBtYXkgbm90IGJlIHNlY3VyZQorICAgICAgICBpZiAoIShmbGFncyAmIElTdXJmYWNlQ29tcG9zZXI6OmVTZWN1cmUpKSB7CisgICAgICAgICAgICAvLyBpZiBHUFUgZG9lc24ndCB3b3JrLCB3ZSB0cnkgZUhhcmR3YXJlCisgICAgICAgICAgICBmbGFncyB8PSBJU3VyZmFjZUNvbXBvc2VyOjplSGFyZHdhcmU7CisgICAgICAgICAgICAvLyBhc2tlZCBmb3IgR1BVIG1lbW9yeSwgdHJ5IHRoYXQgZmlyc3QKKyAgICAgICAgICAgIGRlYWxlciA9IG1GbGluZ2VyLT5nZXRHUFUoKS0+cmVxdWVzdChjbGllbnRfcGlkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChkZWFsZXIgPT0gTlVMTCkgeworICAgICAgICBpZiAoZGVmYXVsdEFsbG9jYXRvciAhPSBOVUxMKQorICAgICAgICAgICAgLy8gaWYgYSBkZWZhdWx0IGFsbG9jYXRvciBpcyBnaXZlbiwgdXNlIHRoYXQKKyAgICAgICAgICAgIGRlYWxlciA9IGRlZmF1bHRBbGxvY2F0b3I7CisgICAgfQorICAgIAorICAgIGlmIChkZWFsZXIgPT0gTlVMTCkgeworICAgICAgICAvLyBhbHdheXMgdHJ5IGgvdyBhY2NlbGVyYXRlZCBtZW1vcnkgZmlyc3QKKyAgICAgICAgaWYgKGdsb2JhbF9wbWVtX2hlYXApIHsKKyAgICAgICAgICAgIGNvbnN0IHNwPFBNZW1IZWFwPiYgaGVhcChtUE1lbUhlYXApOworICAgICAgICAgICAgaWYgKGRlYWxlciA9PSBOVUxMICYmIGhlYXAgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGRlYWxlciA9IG5ldyBNZW1vcnlEZWFsZXIoIAorICAgICAgICAgICAgICAgICAgICAgICAgaGVhcC0+Y3JlYXRlQ2xpZW50SGVhcCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgaGVhcC0+Z2V0QWxsb2NhdG9yKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGRlYWxlciA9PSBOVUxMKSB7CisgICAgICAgIC8vIHJldHVybiB0aGUgYXNobWVtIGFsbG9jYXRvciAoc29mdHdhcmUgcmVuZGVyaW5nKQorICAgICAgICBkZWFsZXIgPSBuZXcgTWVtb3J5RGVhbGVyKG1DbGllbnRIZWFwU2l6ZSwgMCwgIlNGTmF0aXZlSGVhcCIpOworICAgIH0KKyAgICByZXR1cm4gZGVhbGVyOworfQorCitzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiBTdXJmYWNlSGVhcE1hbmFnZXI6OmdldEFsbG9jYXRvcihpbnQgdHlwZSkgY29uc3QgCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiBhbGxvY2F0b3I7CisKKyAgICAvLyB0aGlzIGlzIG9ubHkgdXNlZCBmb3IgZGVidWdnaW5nCisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAgIGNhc2UgTkFUSVZFX01FTU9SWV9UWVBFX1BNRU06CisgICAgICAgICAgICBpZiAobVBNZW1IZWFwICE9IDApIHsKKyAgICAgICAgICAgICAgICBhbGxvY2F0b3IgPSBtUE1lbUhlYXAtPmdldEFsbG9jYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiBhbGxvY2F0b3I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitQTWVtSGVhcDo6UE1lbUhlYXAoY29uc3QgY2hhciogY29uc3QgZGV2aWNlLCBzaXplX3Qgc2l6ZSwgc2l6ZV90IHJlc2VydmVkKQorICAgIDogTWVtb3J5SGVhcEJhc2UoZGV2aWNlLCBzaXplKQoreworICAgIC8vTE9HRCgiJXMsICVwLCBtRkQ9JWQiLCBfX1BSRVRUWV9GVU5DVElPTl9fLCB0aGlzLCBoZWFwSUQoKSk7CisgICAgaWYgKGJhc2UoKSAhPSBNQVBfRkFJTEVEKSB7CisgICAgICAgIC8vTE9HRCgiJXMsICV1IGJ5dGVzIiwgZGV2aWNlLCB2aXJ0dWFsU2l6ZSgpKTsKKyAgICAgICAgaWYgKHJlc2VydmVkID09IDApCisgICAgICAgICAgICByZXNlcnZlZCA9IHZpcnR1YWxTaXplKCk7CisgICAgICAgIG1BbGxvY2F0b3IgPSBuZXcgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcihyZXNlcnZlZCk7CisgICAgfQorfQorCitQTWVtSGVhcDo6flBNZW1IZWFwKCkgeworICAgIC8vTE9HRCgiJXMsICVwLCBtRkQ9JWQiLCBfX1BSRVRUWV9GVU5DVElPTl9fLCB0aGlzLCBoZWFwSUQoKSk7Cit9CisKK3NwPE1lbW9yeUhlYXBQbWVtPiBQTWVtSGVhcDo6Y3JlYXRlQ2xpZW50SGVhcCgpIHsKKyAgICBzcDxNZW1vcnlIZWFwQmFzZT4gcGFyZW50SGVhcCh0aGlzKTsKKyAgICByZXR1cm4gbmV3IE1lbW9yeUhlYXBQbWVtKHBhcmVudEhlYXApOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL1ZSYW1IZWFwLmggYi9saWJzL3N1cmZhY2VmbGluZ2VyL1ZSYW1IZWFwLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTE0MDE2NwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvVlJhbUhlYXAuaApAQCAtMCwwICsxLDc4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX1ZSQU1fSEVBUF9ICisjZGVmaW5lIEFORFJPSURfVlJBTV9IRUFQX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeURlYWxlci5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBQTWVtSGVhcDsKK2NsYXNzIE1lbW9yeUhlYXBQbWVtOworY2xhc3MgU3VyZmFjZUZsaW5nZXI7IAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgU3VyZmFjZUhlYXBNYW5hZ2VyICA6IHB1YmxpYyBSZWZCYXNlCit7CitwdWJsaWM6CisgICAgU3VyZmFjZUhlYXBNYW5hZ2VyKGNvbnN0IHNwPFN1cmZhY2VGbGluZ2VyPiYgZmxpbmdlciwgc2l6ZV90IGNsaWVudEhlYXBTaXplKTsKKyAgICB2aXJ0dWFsIH5TdXJmYWNlSGVhcE1hbmFnZXIoKTsKKyAgICB2aXJ0dWFsIHZvaWQgb25GaXJzdFJlZigpOworICAgIC8qIHVzZSBJU3VyZmFjZUNvbXBvc2VyIGZsYWdzIGVHUFV8ZUhBcmR3YXJlfGVTZWN1cmUgKi8KKyAgICBzcDxNZW1vcnlEZWFsZXI+IGNyZWF0ZUhlYXAodWludDMyX3QgZmxhZ3M9MCwgcGlkX3QgY2xpZW50X3BpZCA9IDAsCisgICAgICAgICAgICBjb25zdCBzcDxNZW1vcnlEZWFsZXI+JiBkZWZhdWx0QWxsb2NhdG9yID0gMCk7CisgICAgCisgICAgLy8gdXNlZCBmb3IgZGVidWdnaW5nIG9ubHkuLi4KKyAgICBzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiBnZXRBbGxvY2F0b3IoaW50IHR5cGUpIGNvbnN0OworCitwcml2YXRlOgorICAgIHNwPFBNZW1IZWFwPiBnZXRIZWFwKGludCB0eXBlKSBjb25zdDsKKworICAgIHNwPFN1cmZhY2VGbGluZ2VyPiBtRmxpbmdlcjsKKyAgICBtdXRhYmxlIE11dGV4ICAgbUxvY2s7CisgICAgc2l6ZV90ICAgICAgICAgIG1DbGllbnRIZWFwU2l6ZTsKKyAgICBzcDxQTWVtSGVhcD4gICAgbVBNZW1IZWFwOworICAgIHN0YXRpYyBpbnQgZ2xvYmFsX3BtZW1faGVhcDsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBQTWVtSGVhcCA6IHB1YmxpYyBNZW1vcnlIZWFwQmFzZQoreworcHVibGljOgorICAgICAgICAgICAgICAgIFBNZW1IZWFwKGNvbnN0IGNoYXIqIGNvbnN0IHZyYW0sCisgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZT0wLCBzaXplX3QgcmVzZXJ2ZWQ9MCk7CisgICAgdmlydHVhbCAgICAgflBNZW1IZWFwKCk7CisgICAgCisgICAgdmlydHVhbCBjb25zdCBzcDxTaW1wbGVCZXN0Rml0QWxsb2NhdG9yPiYgZ2V0QWxsb2NhdG9yKCkgY29uc3QgeworICAgICAgICByZXR1cm4gbUFsbG9jYXRvcjsgCisgICAgfQorICAgIHZpcnR1YWwgc3A8TWVtb3J5SGVhcFBtZW0+IGNyZWF0ZUNsaWVudEhlYXAoKTsKKyAgICAKK3ByaXZhdGU6CisgICAgc3A8U2ltcGxlQmVzdEZpdEFsbG9jYXRvcj4gIG1BbGxvY2F0b3I7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX1ZSQU1fSEVBUF9ICmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL2Nsei5jcHAgYi9saWJzL3N1cmZhY2VmbGluZ2VyL2Nsei5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQ1NmI4NgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvY2x6LmNwcApAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgImNsei5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2ludCBjbHpfaW1wbChpbnQzMl90IHgpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgcmV0dXJuIF9fYnVpbHRpbl9jbHooeCk7CisjZWxzZQorICAgIGlmICgheCkgcmV0dXJuIDMyOworICAgIGludCBlID0gMzE7CisgICAgaWYgKHgmMHhGRkZGMDAwMCkgICB7IGUgLT0xNjsgeCA+Pj0xNjsgfQorICAgIGlmICh4JjB4MDAwMEZGMDApICAgeyBlIC09IDg7IHggPj49IDg7IH0KKyAgICBpZiAoeCYweDAwMDAwMEYwKSAgIHsgZSAtPSA0OyB4ID4+PSA0OyB9CisgICAgaWYgKHgmMHgwMDAwMDAwQykgICB7IGUgLT0gMjsgeCA+Pj0gMjsgfQorICAgIGlmICh4JjB4MDAwMDAwMDIpICAgeyBlIC09IDE7IH0KKyAgICByZXR1cm4gZTsKKyNlbmRpZgorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci9jbHouaCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvY2x6LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGRkZjk4NgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvY2x6LmgKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9TVVJGQUNFX0ZMSU5HRVJfQ0xaX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2ludCBjbHpfaW1wbChpbnQzMl90IHgpOworCitpbnQgaW5saW5lIGNseihpbnQzMl90IHgpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgcmV0dXJuIF9fYnVpbHRpbl9jbHooeCk7CisjZWxzZQorICAgIHJldHVybiBjbHpfaW1wbCh4KTsKKyNlbmRpZgorfQorCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvKiBBTkRST0lEX1NVUkZBQ0VfRkxJTkdFUl9DTFpfSCAqLwpkaWZmIC0tZ2l0IGEvbGlicy9zdXJmYWNlZmxpbmdlci90ZXN0cy9BbmRyb2lkLm1rIGIvbGlicy9zdXJmYWNlZmxpbmdlci90ZXN0cy9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwNTNlN2QKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL3Rlc3RzL0FuZHJvaWQubWsKQEAgLTAsMCArMSBAQAoraW5jbHVkZSAkKGNhbGwgYWxsLXN1YmRpci1tYWtlZmlsZXMpCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL3Rlc3RzL292ZXJsYXlzL0FuZHJvaWQubWsgYi9saWJzL3N1cmZhY2VmbGluZ2VyL3Rlc3RzL292ZXJsYXlzL0FuZHJvaWQubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM0N2U0NQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvdGVzdHMvb3ZlcmxheXMvQW5kcm9pZC5tawpAQCAtMCwwICsxLDE2IEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVM6PSBcCisJb3ZlcmxheXMuY3BwCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgOj0gXAorCWxpYmN1dGlscyBcCisJbGlidXRpbHMgXAorICAgIGxpYnVpCisKK0xPQ0FMX01PRFVMRTo9IHRlc3Qtb3ZlcmxheXMKKworTE9DQUxfTU9EVUxFX1RBR1MgOj0gdGVzdHMKKworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCmRpZmYgLS1naXQgYS9saWJzL3N1cmZhY2VmbGluZ2VyL3Rlc3RzL292ZXJsYXlzL292ZXJsYXlzLmNwcCBiL2xpYnMvc3VyZmFjZWZsaW5nZXIvdGVzdHMvb3ZlcmxheXMvb3ZlcmxheXMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzYzA0NmYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3N1cmZhY2VmbGluZ2VyL3Rlc3RzL292ZXJsYXlzL292ZXJsYXlzLmNwcApAQCAtMCwwICsxLDU4IEBACisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Qcm9jZXNzU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHVpL1N1cmZhY2UuaD4KKyNpbmNsdWRlIDx1aS9JU3VyZmFjZS5oPgorI2luY2x1ZGUgPHVpL092ZXJsYXkuaD4KKyNpbmNsdWRlIDx1aS9TdXJmYWNlQ29tcG9zZXJDbGllbnQuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKK2NsYXNzIFRlc3QgeworcHVibGljOgorICAgIHN0YXRpYyBjb25zdCBzcDxJU3VyZmFjZT4mIGdldElTdXJmYWNlKGNvbnN0IHNwPFN1cmZhY2U+JiBzKSB7CisgICAgICAgIHJldHVybiBzLT5nZXRJU3VyZmFjZSgpOworICAgIH0KK307Cit9OworCitpbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpCit7CisgICAgLy8gc2V0IHVwIHRoZSB0aHJlYWQtcG9vbAorICAgIHNwPFByb2Nlc3NTdGF0ZT4gcHJvYyhQcm9jZXNzU3RhdGU6OnNlbGYoKSk7CisgICAgUHJvY2Vzc1N0YXRlOjpzZWxmKCktPnN0YXJ0VGhyZWFkUG9vbCgpOworCisgICAgLy8gY3JlYXRlIGEgY2xpZW50IHRvIHN1cmZhY2VmbGluZ2VyCisgICAgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiBjbGllbnQgPSBuZXcgU3VyZmFjZUNvbXBvc2VyQ2xpZW50KCk7CisgICAgCisgICAgLy8gY3JlYXRlIHB1c2hidWZmZXIgc3VyZmFjZQorICAgIHNwPFN1cmZhY2U+IHN1cmZhY2UgPSBjbGllbnQtPmNyZWF0ZVN1cmZhY2UoZ2V0cGlkKCksIDAsIDMyMCwgMjQwLCAKKyAgICAgICAgICAgIFBJWEVMX0ZPUk1BVF9VTktOT1dOLCBJU3VyZmFjZUNvbXBvc2VyOjplUHVzaEJ1ZmZlcnMpOworCisgICAgLy8gZ2V0IHRvIHRoZSBpc3VyZmFjZQorICAgIHNwPElTdXJmYWNlPiBpc3VyZmFjZSA9IFRlc3Q6OmdldElTdXJmYWNlKHN1cmZhY2UpOworICAgIHByaW50ZigiaXN1cmZhY2UgPSAlcFxuIiwgaXN1cmZhY2UuZ2V0KCkpOworICAgIAorICAgIC8vIG5vdyByZXF1ZXN0IGFuIG92ZXJsYXkKKyAgICBzcDxPdmVybGF5UmVmPiByZWYgPSBpc3VyZmFjZS0+Y3JlYXRlT3ZlcmxheSgzMjAsIDI0MCwgUElYRUxfRk9STUFUX1JHQl81NjUpOworICAgIHNwPE92ZXJsYXk+IG92ZXJsYXkgPSBuZXcgT3ZlcmxheShyZWYpOworICAgIAorCisgICAgLyoKKyAgICAgKiBoZXJlIHdlIGNhbiB1c2UgdGhlIG92ZXJsYXkgQVBJIAorICAgICAqLworICAgIAorICAgIG92ZXJsYXlfYnVmZmVyX3QgYnVmZmVyOyAKKyAgICBvdmVybGF5LT5kZXF1ZXVlQnVmZmVyKCZidWZmZXIpOworICAgIHByaW50ZigiYnVmZmVyID0gJXBcbiIsIGJ1ZmZlcik7CisgICAgCisgICAgdm9pZCogYWRkcmVzcyA9IG92ZXJsYXktPmdldEJ1ZmZlckFkZHJlc3MoYnVmZmVyKTsKKyAgICBwcmludGYoImFkZHJlc3MgPSAlcFxuIiwgYWRkcmVzcyk7CisKKyAgICBvdmVybGF5LT5xdWV1ZUJ1ZmZlcihidWZmZXIpOworCisgICAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9saWJzL3VpL0FuZHJvaWQubWsgYi9saWJzL3VpL0FuZHJvaWQubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk0NDM1NwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvQW5kcm9pZC5tawpAQCAtMCwwICsxLDQxIEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVM6PSBcCisJQ2FtZXJhLmNwcCBcCisJQ2FtZXJhUGFyYW1ldGVycy5jcHAgXAorCUVHTERpc3BsYXlTdXJmYWNlLmNwcCBcCisJRUdMTmF0aXZlV2luZG93U3VyZmFjZS5jcHAgXAorCUV2ZW50SHViLmNwcCBcCisJRXZlbnRSZWN1cnJlbmNlLmNwcCBcCisJS2V5TGF5b3V0TWFwLmNwcCBcCisJS2V5Q2hhcmFjdGVyTWFwLmNwcCBcCisJSUNhbWVyYS5jcHAgXAorCUlDYW1lcmFDbGllbnQuY3BwIFwKKwlJQ2FtZXJhU2VydmljZS5jcHAgXAorCUlPdmVybGF5LmNwcCBcCisJSVN1cmZhY2VDb21wb3Nlci5jcHAgXAorCUlTdXJmYWNlLmNwcCBcCisJSVN1cmZhY2VGbGluZ2VyQ2xpZW50LmNwcCBcCisJTGF5ZXJTdGF0ZS5jcHAgXAorCU92ZXJsYXkuY3BwIFwKKwlQaXhlbEZvcm1hdC5jcHAgXAorCVBvaW50LmNwcCBcCisJUmVjdC5jcHAgXAorCVJlZ2lvbi5jcHAgXAorCVN1cmZhY2UuY3BwIFwKKwlTdXJmYWNlQ29tcG9zZXJDbGllbnQuY3BwIFwKKwlTdXJmYWNlRmxpbmdlclN5bmNocm8uY3BwIFwKKwlUaW1lLmNwcAorCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJjb3JlY2cgXAorCWxpYmN1dGlscyBcCisJbGlidXRpbHMgXAorCWxpYnBpeGVsZmxpbmdlciBcCisJbGliaGFyZHdhcmUgXAorCWxpYmhhcmR3YXJlX2xlZ2FjeQorCitMT0NBTF9NT0RVTEU6PSBsaWJ1aQorCitpbmNsdWRlICQoQlVJTERfU0hBUkVEX0xJQlJBUlkpCmRpZmYgLS1naXQgYS9saWJzL3VpL0NhbWVyYS5jcHAgYi9saWJzL3VpL0NhbWVyYS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjNjYmRhMQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvQ2FtZXJhLmNwcApAQCAtMCwwICsxLDQwOCBAQAorLyoKKyoqCisqKiBDb3B5cmlnaHQgKEMpIDIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqIENvcHlyaWdodCAoQykgMjAwOCBIVEMgSW5jLgorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8jZGVmaW5lIExPR19OREVCVUcgMAorI2RlZmluZSBMT0dfVEFHICJDYW1lcmEiCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1aS9TdXJmYWNlLmg+CisjaW5jbHVkZSA8dWkvQ2FtZXJhLmg+CisjaW5jbHVkZSA8dWkvSUNhbWVyYVNlcnZpY2UuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyBjbGllbnQgc2luZ2xldG9uIGZvciBjYW1lcmEgc2VydmljZSBiaW5kZXIgaW50ZXJmYWNlCitNdXRleCBDYW1lcmE6Om1Mb2NrOworc3A8SUNhbWVyYVNlcnZpY2U+IENhbWVyYTo6bUNhbWVyYVNlcnZpY2U7CitzcDxDYW1lcmE6OkRlYXRoTm90aWZpZXI+IENhbWVyYTo6bURlYXRoTm90aWZpZXI7CisKKy8vIGVzdGFibGlzaCBiaW5kZXIgaW50ZXJmYWNlIHRvIGNhbWVyYSBzZXJ2aWNlCitjb25zdCBzcDxJQ2FtZXJhU2VydmljZT4mIENhbWVyYTo6Z2V0Q2FtZXJhU2VydmljZSgpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBpZiAobUNhbWVyYVNlcnZpY2UuZ2V0KCkgPT0gMCkgeworICAgICAgICBzcDxJU2VydmljZU1hbmFnZXI+IHNtID0gZGVmYXVsdFNlcnZpY2VNYW5hZ2VyKCk7CisgICAgICAgIHNwPElCaW5kZXI+IGJpbmRlcjsKKyAgICAgICAgZG8geworICAgICAgICAgICAgYmluZGVyID0gc20tPmdldFNlcnZpY2UoU3RyaW5nMTYoIm1lZGlhLmNhbWVyYSIpKTsKKyAgICAgICAgICAgIGlmIChiaW5kZXIgIT0gMCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIExPR1coIkNhbWVyYVNlcnZpY2Ugbm90IHB1Ymxpc2hlZCwgd2FpdGluZy4uLiIpOworICAgICAgICAgICAgdXNsZWVwKDUwMDAwMCk7IC8vIDAuNSBzCisgICAgICAgIH0gd2hpbGUodHJ1ZSk7CisgICAgICAgIGlmIChtRGVhdGhOb3RpZmllciA9PSBOVUxMKSB7CisgICAgICAgICAgICBtRGVhdGhOb3RpZmllciA9IG5ldyBEZWF0aE5vdGlmaWVyKCk7CisgICAgICAgIH0KKyAgICAgICAgYmluZGVyLT5saW5rVG9EZWF0aChtRGVhdGhOb3RpZmllcik7CisgICAgICAgIG1DYW1lcmFTZXJ2aWNlID0gaW50ZXJmYWNlX2Nhc3Q8SUNhbWVyYVNlcnZpY2U+KGJpbmRlcik7CisgICAgfQorICAgIExPR0VfSUYobUNhbWVyYVNlcnZpY2U9PTAsICJubyBDYW1lcmFTZXJ2aWNlIT8iKTsKKyAgICByZXR1cm4gbUNhbWVyYVNlcnZpY2U7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitDYW1lcmE6OkNhbWVyYSgpCit7CisgICAgaW5pdCgpOworfQorCitDYW1lcmE6OkNhbWVyYShjb25zdCBzcDxJQ2FtZXJhPiYgY2FtZXJhKQoreworICAgIGluaXQoKTsKKyAgICAvLyBjb25uZWN0IHRoaXMgY2xpZW50IHRvIGV4aXN0aW5nIGNhbWVyYSByZW1vdGUKKyAgICBpZiAoY2FtZXJhLT5jb25uZWN0KHRoaXMpID09IE5PX0VSUk9SKSB7CisgICAgICAgIG1TdGF0dXMgPSBOT19FUlJPUjsKKyAgICAgICAgbUNhbWVyYSA9IGNhbWVyYTsKKyAgICAgICAgY2FtZXJhLT5hc0JpbmRlcigpLT5saW5rVG9EZWF0aCh0aGlzKTsKKyAgICB9Cit9CisKK3ZvaWQgQ2FtZXJhOjppbml0KCkKK3sKKyAgICBtU3RhdHVzID0gVU5LTk9XTl9FUlJPUjsKKyAgICBtU2h1dHRlckNhbGxiYWNrID0gMDsKKyAgICBtU2h1dHRlckNhbGxiYWNrQ29va2llID0gMDsKKyAgICBtUmF3Q2FsbGJhY2sgPSAwOworICAgIG1SYXdDYWxsYmFja0Nvb2tpZSA9IDA7CisgICAgbUpwZWdDYWxsYmFjayA9IDA7CisgICAgbUpwZWdDYWxsYmFja0Nvb2tpZSA9IDA7CisgICAgbVByZXZpZXdDYWxsYmFjayA9IDA7CisgICAgbVByZXZpZXdDYWxsYmFja0Nvb2tpZSA9IDA7CisgICAgbVJlY29yZGluZ0NhbGxiYWNrID0gMDsKKyAgICBtUmVjb3JkaW5nQ2FsbGJhY2tDb29raWUgPSAwOworICAgIG1FcnJvckNhbGxiYWNrID0gMDsKKyAgICBtRXJyb3JDYWxsYmFja0Nvb2tpZSA9IDA7CisgICAgbUF1dG9Gb2N1c0NhbGxiYWNrID0gMDsKKyAgICBtQXV0b0ZvY3VzQ2FsbGJhY2tDb29raWUgPSAwOworfQorCitDYW1lcmE6On5DYW1lcmEoKQoreworICAgIGRpc2Nvbm5lY3QoKTsKK30KKworc3A8Q2FtZXJhPiBDYW1lcmE6OmNvbm5lY3QoKQoreworICAgIExPR1YoImNvbm5lY3QiKTsKKyAgICBzcDxDYW1lcmE+IGMgPSBuZXcgQ2FtZXJhKCk7CisgICAgY29uc3Qgc3A8SUNhbWVyYVNlcnZpY2U+JiBjcyA9IGdldENhbWVyYVNlcnZpY2UoKTsKKyAgICBpZiAoY3MgIT0gMCkgeworICAgICAgICBjLT5tQ2FtZXJhID0gY3MtPmNvbm5lY3QoYyk7CisgICAgfQorICAgIGlmIChjLT5tQ2FtZXJhICE9IDApIHsKKyAgICAgICAgYy0+bUNhbWVyYS0+YXNCaW5kZXIoKS0+bGlua1RvRGVhdGgoYyk7CisgICAgICAgIGMtPm1TdGF0dXMgPSBOT19FUlJPUjsKKyAgICB9IGVsc2UgeworICAgICAgICBjLmNsZWFyKCk7CisgICAgfQorICAgIHJldHVybiBjOworfQorCit2b2lkIENhbWVyYTo6ZGlzY29ubmVjdCgpCit7CisgICAgTE9HVigiZGlzY29ubmVjdCIpOworICAgIGlmIChtQ2FtZXJhICE9IDApIHsKKyAgICAgICAgbUVycm9yQ2FsbGJhY2sgPSAwOworICAgICAgICBtQ2FtZXJhLT5kaXNjb25uZWN0KCk7CisgICAgICAgIG1DYW1lcmEgPSAwOworICAgIH0KK30KKworc3RhdHVzX3QgQ2FtZXJhOjpyZWNvbm5lY3QoKQoreworICAgIExPR1YoInJlY29ubmVjdCIpOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm4gTk9fSU5JVDsKKyAgICByZXR1cm4gYy0+Y29ubmVjdCh0aGlzKTsKK30KKworc3A8SUNhbWVyYT4gQ2FtZXJhOjpyZW1vdGUoKQoreworICAgIHJldHVybiBtQ2FtZXJhOworfQorCitzdGF0dXNfdCBDYW1lcmE6OmxvY2soKQoreworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm4gTk9fSU5JVDsKKyAgICByZXR1cm4gYy0+bG9jaygpOworfQorCitzdGF0dXNfdCBDYW1lcmE6OnVubG9jaygpCit7CisgICAgc3AgPElDYW1lcmE+IGMgPSBtQ2FtZXJhOworICAgIGlmIChjID09IDApIHJldHVybiBOT19JTklUOworICAgIHJldHVybiBjLT51bmxvY2soKTsKK30KKworLy8gcGFzcyB0aGUgYnVmZmVyZWQgSVN1cmZhY2UgdG8gdGhlIGNhbWVyYSBzZXJ2aWNlCitzdGF0dXNfdCBDYW1lcmE6OnNldFByZXZpZXdEaXNwbGF5KGNvbnN0IHNwPFN1cmZhY2U+JiBzdXJmYWNlKQoreworICAgIExPR1YoInNldFByZXZpZXdEaXNwbGF5Iik7CisgICAgaWYgKHN1cmZhY2UgPT0gMCkgeworICAgICAgICBMT0dFKCJhcHAgcGFzc2VkIE5VTEwgc3VyZmFjZSIpOworICAgICAgICByZXR1cm4gTk9fSU5JVDsKKyAgICB9CisgICAgc3AgPElDYW1lcmE+IGMgPSBtQ2FtZXJhOworICAgIGlmIChjID09IDApIHJldHVybiBOT19JTklUOworICAgIHJldHVybiBjLT5zZXRQcmV2aWV3RGlzcGxheShzdXJmYWNlLT5nZXRJU3VyZmFjZSgpKTsKK30KKworc3RhdHVzX3QgQ2FtZXJhOjpzZXRQcmV2aWV3RGlzcGxheShjb25zdCBzcDxJU3VyZmFjZT4mIHN1cmZhY2UpCit7CisgICAgTE9HVigic2V0UHJldmlld0Rpc3BsYXkiKTsKKyAgICBpZiAoc3VyZmFjZSA9PSAwKSB7CisgICAgICAgIExPR0UoImFwcCBwYXNzZWQgTlVMTCBzdXJmYWNlIik7CisgICAgICAgIHJldHVybiBOT19JTklUOworICAgIH0KKyAgICBzcCA8SUNhbWVyYT4gYyA9IG1DYW1lcmE7CisgICAgaWYgKGMgPT0gMCkgcmV0dXJuIE5PX0lOSVQ7CisgICAgcmV0dXJuIGMtPnNldFByZXZpZXdEaXNwbGF5KHN1cmZhY2UpOworfQorCisKKy8vIHN0YXJ0IHByZXZpZXcgbW9kZSwgbXVzdCBjYWxsIHNldFByZXZpZXdEaXNwbGF5IGZpcnN0CitzdGF0dXNfdCBDYW1lcmE6OnN0YXJ0UHJldmlldygpCit7CisgICAgTE9HVigic3RhcnRQcmV2aWV3Iik7CisgICAgc3AgPElDYW1lcmE+IGMgPSBtQ2FtZXJhOworICAgIGlmIChjID09IDApIHJldHVybiBOT19JTklUOworICAgIHJldHVybiBjLT5zdGFydFByZXZpZXcoKTsKK30KKworLy8gc3RhcnQgcmVjb3JkaW5nIG1vZGUsIG11c3QgY2FsbCBzZXRQcmV2aWV3RGlzcGxheSBmaXJzdAorc3RhdHVzX3QgQ2FtZXJhOjpzdGFydFJlY29yZGluZygpCit7CisgICAgTE9HVigic3RhcnRSZWNvcmRpbmciKTsKKyAgICBzcCA8SUNhbWVyYT4gYyA9IG1DYW1lcmE7CisgICAgaWYgKGMgPT0gMCkgcmV0dXJuIE5PX0lOSVQ7CisgICAgcmV0dXJuIGMtPnN0YXJ0UmVjb3JkaW5nKCk7Cit9CisKKy8vIHN0b3AgcHJldmlldyBtb2RlCit2b2lkIENhbWVyYTo6c3RvcFByZXZpZXcoKQoreworICAgIExPR1YoInN0b3BQcmV2aWV3Iik7CisgICAgc3AgPElDYW1lcmE+IGMgPSBtQ2FtZXJhOworICAgIGlmIChjID09IDApIHJldHVybjsKKyAgICBjLT5zdG9wUHJldmlldygpOworfQorCisvLyBzdG9wIHJlY29yZGluZyBtb2RlCit2b2lkIENhbWVyYTo6c3RvcFJlY29yZGluZygpCit7CisgICAgTE9HVigic3RvcFJlY29yZGluZyIpOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm47CisgICAgYy0+c3RvcFJlY29yZGluZygpOworfQorCisvLyByZWxlYXNlIGEgcmVjb3JkaW5nIGZyYW1lCit2b2lkIENhbWVyYTo6cmVsZWFzZVJlY29yZGluZ0ZyYW1lKGNvbnN0IHNwPElNZW1vcnk+JiBtZW0pCit7CisgICAgTE9HVigicmVsZWFzZVJlY29yZGluZ0ZyYW1lIik7CisgICAgc3AgPElDYW1lcmE+IGMgPSBtQ2FtZXJhOworICAgIGlmIChjID09IDApIHJldHVybjsKKyAgICBjLT5yZWxlYXNlUmVjb3JkaW5nRnJhbWUobWVtKTsKK30KKworLy8gZ2V0IHByZXZpZXcgc3RhdGUKK2Jvb2wgQ2FtZXJhOjpwcmV2aWV3RW5hYmxlZCgpCit7CisgICAgTE9HVigicHJldmlld0VuYWJsZWQiKTsKKyAgICBzcCA8SUNhbWVyYT4gYyA9IG1DYW1lcmE7CisgICAgaWYgKGMgPT0gMCkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBjLT5wcmV2aWV3RW5hYmxlZCgpOworfQorCisvLyBnZXQgcmVjb3JkaW5nIHN0YXRlCitib29sIENhbWVyYTo6cmVjb3JkaW5nRW5hYmxlZCgpCit7CisgICAgTE9HVigicmVjb3JkaW5nRW5hYmxlZCIpOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIGMtPnJlY29yZGluZ0VuYWJsZWQoKTsKK30KKworc3RhdHVzX3QgQ2FtZXJhOjphdXRvRm9jdXMoKQoreworICAgIExPR1YoImF1dG9Gb2N1cyIpOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm4gTk9fSU5JVDsKKyAgICByZXR1cm4gYy0+YXV0b0ZvY3VzKCk7Cit9CisKKy8vIHRha2UgYSBwaWN0dXJlCitzdGF0dXNfdCBDYW1lcmE6OnRha2VQaWN0dXJlKCkKK3sKKyAgICBMT0dWKCJ0YWtlUGljdHVyZSIpOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyA9PSAwKSByZXR1cm4gTk9fSU5JVDsKKyAgICByZXR1cm4gYy0+dGFrZVBpY3R1cmUoKTsKK30KKworLy8gc2V0IHByZXZpZXcvY2FwdHVyZSBwYXJhbWV0ZXJzIC0ga2V5L3ZhbHVlIHBhaXJzCitzdGF0dXNfdCBDYW1lcmE6OnNldFBhcmFtZXRlcnMoY29uc3QgU3RyaW5nOCYgcGFyYW1zKQoreworICAgIExPR1YoInNldFBhcmFtZXRlcnMiKTsKKyAgICBzcCA8SUNhbWVyYT4gYyA9IG1DYW1lcmE7CisgICAgaWYgKGMgPT0gMCkgcmV0dXJuIE5PX0lOSVQ7CisgICAgcmV0dXJuIGMtPnNldFBhcmFtZXRlcnMocGFyYW1zKTsKK30KKworLy8gZ2V0IHByZXZpZXcvY2FwdHVyZSBwYXJhbWV0ZXJzIC0ga2V5L3ZhbHVlIHBhaXJzCitTdHJpbmc4IENhbWVyYTo6Z2V0UGFyYW1ldGVycygpIGNvbnN0Cit7CisgICAgTE9HVigiZ2V0UGFyYW1ldGVycyIpOworICAgIFN0cmluZzggcGFyYW1zOworICAgIHNwIDxJQ2FtZXJhPiBjID0gbUNhbWVyYTsKKyAgICBpZiAoYyAhPSAwKSBwYXJhbXMgPSBtQ2FtZXJhLT5nZXRQYXJhbWV0ZXJzKCk7CisgICAgcmV0dXJuIHBhcmFtczsKK30KKwordm9pZCBDYW1lcmE6OnNldEF1dG9Gb2N1c0NhbGxiYWNrKGF1dG9mb2N1c19jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKQoreworICAgIExPR1YoInNldEF1dG9Gb2N1c0NhbGxiYWNrIik7CisgICAgbUF1dG9Gb2N1c0NhbGxiYWNrID0gY2I7CisgICAgbUF1dG9Gb2N1c0NhbGxiYWNrQ29va2llID0gY29va2llOworfQorCit2b2lkIENhbWVyYTo6c2V0U2h1dHRlckNhbGxiYWNrKHNodXR0ZXJfY2FsbGJhY2sgY2IsIHZvaWQgKmNvb2tpZSkKK3sKKyAgICBMT0dWKCJzZXRTaHV0dGVyQ2FsbGJhY2siKTsKKyAgICBtU2h1dHRlckNhbGxiYWNrID0gY2I7CisgICAgbVNodXR0ZXJDYWxsYmFja0Nvb2tpZSA9IGNvb2tpZTsKK30KKwordm9pZCBDYW1lcmE6OnNldFJhd0NhbGxiYWNrKGZyYW1lX2NhbGxiYWNrIGNiLCB2b2lkICpjb29raWUpCit7CisgICAgTE9HVigic2V0UmF3Q2FsbGJhY2siKTsKKyAgICBtUmF3Q2FsbGJhY2sgPSBjYjsKKyAgICBtUmF3Q2FsbGJhY2tDb29raWUgPSBjb29raWU7Cit9CisKK3ZvaWQgQ2FtZXJhOjpzZXRKcGVnQ2FsbGJhY2soZnJhbWVfY2FsbGJhY2sgY2IsIHZvaWQgKmNvb2tpZSkKK3sKKyAgICBMT0dWKCJzZXRKcGVnQ2FsbGJhY2siKTsKKyAgICBtSnBlZ0NhbGxiYWNrID0gY2I7CisgICAgbUpwZWdDYWxsYmFja0Nvb2tpZSA9IGNvb2tpZTsKK30KKwordm9pZCBDYW1lcmE6OnNldFByZXZpZXdDYWxsYmFjayhmcmFtZV9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llLCBpbnQgZmxhZykKK3sKKyAgICBMT0dWKCJzZXRQcmV2aWV3Q2FsbGJhY2siKTsKKyAgICBtUHJldmlld0NhbGxiYWNrID0gY2I7CisgICAgbVByZXZpZXdDYWxsYmFja0Nvb2tpZSA9IGNvb2tpZTsKKyAgICBzcCA8SUNhbWVyYT4gYyA9IG1DYW1lcmE7CisgICAgaWYgKGMgPT0gMCkgcmV0dXJuOworICAgIG1DYW1lcmEtPnNldFByZXZpZXdDYWxsYmFja0ZsYWcoZmxhZyk7Cit9CisKK3ZvaWQgQ2FtZXJhOjpzZXRSZWNvcmRpbmdDYWxsYmFjayhmcmFtZV9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKQoreworICAgIExPR1YoInNldFJlY29yZGluZ0NhbGxiYWNrIik7CisgICAgbVJlY29yZGluZ0NhbGxiYWNrID0gY2I7CisgICAgbVJlY29yZGluZ0NhbGxiYWNrQ29va2llID0gY29va2llOworfQorCit2b2lkIENhbWVyYTo6c2V0RXJyb3JDYWxsYmFjayhlcnJvcl9jYWxsYmFjayBjYiwgdm9pZCAqY29va2llKQoreworICAgIExPR1YoInNldEVycm9yQ2FsbGJhY2siKTsKKyAgICBtRXJyb3JDYWxsYmFjayA9IGNiOworICAgIG1FcnJvckNhbGxiYWNrQ29va2llID0gY29va2llOworfQorCit2b2lkIENhbWVyYTo6YXV0b0ZvY3VzQ2FsbGJhY2soYm9vbCBmb2N1c2VkKQoreworICAgIExPR1YoImF1dG9Gb2N1c0NhbGxiYWNrIik7CisgICAgaWYgKG1BdXRvRm9jdXNDYWxsYmFjaykgeworICAgICAgICBtQXV0b0ZvY3VzQ2FsbGJhY2soZm9jdXNlZCwgbUF1dG9Gb2N1c0NhbGxiYWNrQ29va2llKTsKKyAgICB9Cit9CisKK3ZvaWQgQ2FtZXJhOjpzaHV0dGVyQ2FsbGJhY2soKQoreworICAgIExPR1YoInNodXR0ZXJDYWxsYmFjayIpOworICAgIGlmIChtU2h1dHRlckNhbGxiYWNrKSB7CisgICAgICAgIG1TaHV0dGVyQ2FsbGJhY2sobVNodXR0ZXJDYWxsYmFja0Nvb2tpZSk7CisgICAgfQorfQorCit2b2lkIENhbWVyYTo6cmF3Q2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIHBpY3R1cmUpCit7CisgICAgTE9HVigicmF3Q2FsbGJhY2siKTsKKyAgICBpZiAobVJhd0NhbGxiYWNrKSB7CisgICAgICAgIG1SYXdDYWxsYmFjayhwaWN0dXJlLCBtUmF3Q2FsbGJhY2tDb29raWUpOworICAgIH0KK30KKworLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB3aGVuIGltYWdlIGlzIHJlYWR5Cit2b2lkIENhbWVyYTo6anBlZ0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBwaWN0dXJlKQoreworICAgIExPR1YoImpwZWdDYWxsYmFjayIpOworICAgIGlmIChtSnBlZ0NhbGxiYWNrKSB7CisgICAgICAgIG1KcGVnQ2FsbGJhY2socGljdHVyZSwgbUpwZWdDYWxsYmFja0Nvb2tpZSk7CisgICAgfQorfQorCisvLyBjYWxsYmFjayBmcm9tIGNhbWVyYSBzZXJ2aWNlIHdoZW4gcHJldmlldyBmcmFtZSBpcyByZWFkeQordm9pZCBDYW1lcmE6OnByZXZpZXdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgZnJhbWUpCit7CisgICAgTE9HVigiZnJhbWVDYWxsYmFjayIpOworICAgIGlmIChtUHJldmlld0NhbGxiYWNrKSB7CisgICAgICAgIG1QcmV2aWV3Q2FsbGJhY2soZnJhbWUsIG1QcmV2aWV3Q2FsbGJhY2tDb29raWUpOworICAgIH0KK30KKworLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB3aGVuIGEgcmVjb3JkaW5nIGZyYW1lIGlzIHJlYWR5Cit2b2lkIENhbWVyYTo6cmVjb3JkaW5nQ2FsbGJhY2soY29uc3Qgc3A8SU1lbW9yeT4mIGZyYW1lKQoreworICAgIExPR1YoInJlY29yZGluZ0NhbGxiYWNrIik7CisgICAgaWYgKG1SZWNvcmRpbmdDYWxsYmFjaykgeworICAgICAgICBtUmVjb3JkaW5nQ2FsbGJhY2soZnJhbWUsIG1SZWNvcmRpbmdDYWxsYmFja0Nvb2tpZSk7CisgICAgfQorfQorCisvLyBjYWxsYmFjayBmcm9tIGNhbWVyYSBzZXJ2aWNlIHdoZW4gYW4gZXJyb3Igb2NjdXJzIGluIHByZXZpZXcgb3IgdGFrZVBpY3R1cmUKK3ZvaWQgQ2FtZXJhOjplcnJvckNhbGxiYWNrKHN0YXR1c190IGVycm9yKQoreworICAgIExPR1YoImVycm9yQ2FsbGJhY2siKTsKKyAgICBpZiAobUVycm9yQ2FsbGJhY2spIHsKKyAgICAgICAgbUVycm9yQ2FsbGJhY2soZXJyb3IsIG1FcnJvckNhbGxiYWNrQ29va2llKTsKKyAgICB9Cit9CisKK3ZvaWQgQ2FtZXJhOjpiaW5kZXJEaWVkKGNvbnN0IHdwPElCaW5kZXI+JiB3aG8pIHsKKyAgICBMT0dXKCJJQ2FtZXJhIGRpZWQiKTsKKyAgICBpZiAobUVycm9yQ2FsbGJhY2spIHsKKyAgICAgICAgbUVycm9yQ2FsbGJhY2soREVBRF9PQkpFQ1QsIG1FcnJvckNhbGxiYWNrQ29va2llKTsKKyAgICB9Cit9CisKK3ZvaWQgQ2FtZXJhOjpEZWF0aE5vdGlmaWVyOjpiaW5kZXJEaWVkKGNvbnN0IHdwPElCaW5kZXI+JiB3aG8pIHsKKyAgICBMT0dWKCJiaW5kZXJEaWVkIik7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKENhbWVyYTo6bUxvY2spOworICAgIENhbWVyYTo6bUNhbWVyYVNlcnZpY2UuY2xlYXIoKTsKKyAgICBMT0dXKCJDYW1lcmEgc2VydmVyIGRpZWQhIik7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdWkvQ2FtZXJhUGFyYW1ldGVycy5jcHAgYi9saWJzL3VpL0NhbWVyYVBhcmFtZXRlcnMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjMjU4MzYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL0NhbWVyYVBhcmFtZXRlcnMuY3BwCkBAIC0wLDAgKzEsMjczIEBACisvKgorKioKKyoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNkZWZpbmUgTE9HX1RBRyAiQ2FtZXJhUGFyYW1zIgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8dWkvQ2FtZXJhUGFyYW1ldGVycy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0YXRpYyBjb25zdCBjaGFyKiBwb3J0cmFpdCA9ICJwb3J0cmFpdCI7CitzdGF0aWMgY29uc3QgY2hhciogbGFuZHNjYXBlID0gImxhbmRzY2FwZSI7CisKK0NhbWVyYVBhcmFtZXRlcnM6OkNhbWVyYVBhcmFtZXRlcnMoKQorICAgICAgICAgICAgICAgIDogbU1hcCgpCit7Cit9CisKK0NhbWVyYVBhcmFtZXRlcnM6On5DYW1lcmFQYXJhbWV0ZXJzKCkKK3sKK30KKworU3RyaW5nOCBDYW1lcmFQYXJhbWV0ZXJzOjpmbGF0dGVuKCkgY29uc3QKK3sKKyAgICBTdHJpbmc4IGZsYXR0ZW5lZCgiIik7CisgICAgc2l6ZV90IHNpemUgPSBtTWFwLnNpemUoKTsKKworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgIFN0cmluZzggaywgdjsKKyAgICAgICAgayA9IG1NYXAua2V5QXQoaSk7CisgICAgICAgIHYgPSBtTWFwLnZhbHVlQXQoaSk7CisKKyAgICAgICAgZmxhdHRlbmVkICs9IGs7CisgICAgICAgIGZsYXR0ZW5lZCArPSAiPSI7CisgICAgICAgIGZsYXR0ZW5lZCArPSB2OworICAgICAgICBpZiAoaSAhPSBzaXplLTEpCisgICAgICAgICAgICBmbGF0dGVuZWQgKz0gIjsiOworICAgIH0KKworICAgIHJldHVybiBmbGF0dGVuZWQ7Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6dW5mbGF0dGVuKGNvbnN0IFN0cmluZzggJnBhcmFtcykKK3sKKyAgICBjb25zdCBjaGFyICphID0gcGFyYW1zLnN0cmluZygpOworICAgIGNvbnN0IGNoYXIgKmI7CisKKyAgICBtTWFwLmNsZWFyKCk7CisKKyAgICBmb3IgKDs7KSB7CisgICAgICAgIC8vIEZpbmQgdGhlIGJvdW5kcyBvZiB0aGUga2V5IG5hbWUuCisgICAgICAgIGIgPSBzdHJjaHIoYSwgJz0nKTsKKyAgICAgICAgaWYgKGIgPT0gMCkKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIC8vIENyZWF0ZSB0aGUga2V5IHN0cmluZy4KKyAgICAgICAgU3RyaW5nOCBrKGEsIChzaXplX3QpKGItYSkpOworCisgICAgICAgIC8vIEZpbmQgdGhlIHZhbHVlLgorICAgICAgICBhID0gYisxOworICAgICAgICBiID0gc3RyY2hyKGEsICc7Jyk7CisgICAgICAgIGlmIChiID09IDApIHsKKyAgICAgICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gc2VtaWNvbG9uLCB0aGlzIGlzIHRoZSBsYXN0IGl0ZW0uCisgICAgICAgICAgICBTdHJpbmc4IHYoYSk7CisgICAgICAgICAgICBtTWFwLmFkZChrLCB2KTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nOCB2KGEsIChzaXplX3QpKGItYSkpOworICAgICAgICBtTWFwLmFkZChrLCB2KTsKKyAgICAgICAgYSA9IGIrMTsKKyAgICB9Cit9CisKKwordm9pZCBDYW1lcmFQYXJhbWV0ZXJzOjpzZXQoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKK3sKKyAgICAvLyBYWFggaSB0aGluayBpIGNhbiBkbyB0aGlzIHdpdGggc3Ryc3BuKCkgCisgICAgaWYgKHN0cmNocihrZXksICc9JykgfHwgc3RyY2hyKGtleSwgJzsnKSkgeworICAgICAgICAvL1hYWCBMT0dFKCJLZXkgXCIlc1wiY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXIgKD0gb3IgOykiLCBrZXkpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKHN0cmNocih2YWx1ZSwgJz0nKSB8fCBzdHJjaHIoa2V5LCAnOycpKSB7CisgICAgICAgIC8vWFhYIExPR0UoIlZhbHVlIFwiJXNcImNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyICg9IG9yIDspIiwgdmFsdWUpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgbU1hcC5yZXBsYWNlVmFsdWVGb3IoU3RyaW5nOChrZXkpLCBTdHJpbmc4KHZhbHVlKSk7Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6c2V0KGNvbnN0IGNoYXIgKmtleSwgaW50IHZhbHVlKQoreworICAgIGNoYXIgc3RyWzE2XTsKKyAgICBzcHJpbnRmKHN0ciwgIiVkIiwgdmFsdWUpOworICAgIHNldChrZXksIHN0cik7Cit9CisKK2NvbnN0IGNoYXIgKkNhbWVyYVBhcmFtZXRlcnM6OmdldChjb25zdCBjaGFyICprZXkpIGNvbnN0Cit7CisgICAgU3RyaW5nOCB2ID0gbU1hcC52YWx1ZUZvcihTdHJpbmc4KGtleSkpOworICAgIGlmICh2Lmxlbmd0aCgpID09IDApCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiB2LnN0cmluZygpOworfQorCitpbnQgQ2FtZXJhUGFyYW1ldGVyczo6Z2V0SW50KGNvbnN0IGNoYXIgKmtleSkgY29uc3QKK3sKKyAgICBjb25zdCBjaGFyICp2ID0gZ2V0KGtleSk7CisgICAgaWYgKHYgPT0gMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiBzdHJ0b2wodiwgMCwgMCk7Cit9CisKK3N0YXRpYyBpbnQgcGFyc2Vfc2l6ZShjb25zdCBjaGFyICpzdHIsIGludCAmd2lkdGgsIGludCAmaGVpZ2h0KQoreworICAgIC8vIEZpbmQgdGhlIHdpZHRoLgorICAgIGNoYXIgKmVuZDsKKyAgICBpbnQgdyA9IChpbnQpc3RydG9sKHN0ciwgJmVuZCwgMTApOworICAgIC8vIElmIGFuICd4JyBkb2VzIG5vdCBpbW1lZGlhdGVseSBmb2xsb3csIGdpdmUgdXAuCisgICAgaWYgKCplbmQgIT0gJ3gnKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICAvLyBGaW5kIHRoZSBoZWlnaHQsIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSAneCcuCisgICAgaW50IGggPSAoaW50KXN0cnRvbChlbmQrMSwgMCwgMTApOworCisgICAgd2lkdGggPSB3OworICAgIGhlaWdodCA9IGg7CisKKyAgICByZXR1cm4gMDsKK30KKwordm9pZCBDYW1lcmFQYXJhbWV0ZXJzOjpzZXRQcmV2aWV3U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpCit7CisgICAgY2hhciBzdHJbMzJdOworICAgIHNwcmludGYoc3RyLCAiJWR4JWQiLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICBzZXQoInByZXZpZXctc2l6ZSIsIHN0cik7Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6Z2V0UHJldmlld1NpemUoaW50ICp3aWR0aCwgaW50ICpoZWlnaHQpIGNvbnN0Cit7CisgICAgKndpZHRoID0gLTE7CisgICAgKmhlaWdodCA9IC0xOworCisgICAgLy8gR2V0IHRoZSBjdXJyZW50IHN0cmluZywgaWYgaXQgZG9lc24ndCBleGlzdCwgbGVhdmUgdGhlIC0xeC0xCisgICAgY29uc3QgY2hhciAqcCA9IGdldCgicHJldmlldy1zaXplIik7CisgICAgaWYgKHAgPT0gMCkKKyAgICAgICAgcmV0dXJuOworCisgICAgaW50IHcsIGg7CisgICAgaWYgKHBhcnNlX3NpemUocCwgdywgaCkgPT0gMCkgeworICAgICAgICAqd2lkdGggPSB3OworICAgICAgICAqaGVpZ2h0ID0gaDsKKyAgICB9Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6c2V0UHJldmlld0ZyYW1lUmF0ZShpbnQgZnBzKQoreworICAgIHNldCgicHJldmlldy1mcmFtZS1yYXRlIiwgZnBzKTsKK30KKworaW50IENhbWVyYVBhcmFtZXRlcnM6OmdldFByZXZpZXdGcmFtZVJhdGUoKSBjb25zdAoreworICAgIHJldHVybiBnZXRJbnQoInByZXZpZXctZnJhbWUtcmF0ZSIpOworfQorCit2b2lkIENhbWVyYVBhcmFtZXRlcnM6OnNldFByZXZpZXdGb3JtYXQoY29uc3QgY2hhciAqZm9ybWF0KQoreworICAgIHNldCgicHJldmlldy1mb3JtYXQiLCBmb3JtYXQpOworfQorCitpbnQgQ2FtZXJhUGFyYW1ldGVyczo6Z2V0T3JpZW50YXRpb24oKSBjb25zdAoreworICAgIGNvbnN0IGNoYXIqIG9yaWVudGF0aW9uID0gZ2V0KCJvcmllbnRhdGlvbiIpOworICAgIGlmIChvcmllbnRhdGlvbiAmJiAhc3RyY21wKG9yaWVudGF0aW9uLCBwb3J0cmFpdCkpCisgICAgICAgIHJldHVybiBDQU1FUkFfT1JJRU5UQVRJT05fUE9SVFJBSVQ7CisgICAgcmV0dXJuIENBTUVSQV9PUklFTlRBVElPTl9MQU5EU0NBUEU7Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6c2V0T3JpZW50YXRpb24oaW50IG9yaWVudGF0aW9uKQoreworICAgIGlmIChvcmllbnRhdGlvbiA9PSBDQU1FUkFfT1JJRU5UQVRJT05fUE9SVFJBSVQpIHsKKyAgICAgICAgc2V0KCJwcmV2aWV3LWZvcm1hdCIsIHBvcnRyYWl0KTsKKyAgICB9IGVsc2UgeworICAgICAgICBzZXQoInByZXZpZXctZm9ybWF0IiwgbGFuZHNjYXBlKTsKKyAgICB9Cit9CisKK2NvbnN0IGNoYXIgKkNhbWVyYVBhcmFtZXRlcnM6OmdldFByZXZpZXdGb3JtYXQoKSBjb25zdAoreworICAgIHJldHVybiBnZXQoInByZXZpZXctZm9ybWF0Iik7Cit9CisKK3ZvaWQgQ2FtZXJhUGFyYW1ldGVyczo6c2V0UGljdHVyZVNpemUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KQoreworICAgIGNoYXIgc3RyWzMyXTsKKyAgICBzcHJpbnRmKHN0ciwgIiVkeCVkIiwgd2lkdGgsIGhlaWdodCk7CisgICAgc2V0KCJwaWN0dXJlLXNpemUiLCBzdHIpOworfQorCit2b2lkIENhbWVyYVBhcmFtZXRlcnM6OmdldFBpY3R1cmVTaXplKGludCAqd2lkdGgsIGludCAqaGVpZ2h0KSBjb25zdAoreworICAgICp3aWR0aCA9IC0xOworICAgICpoZWlnaHQgPSAtMTsKKworICAgIC8vIEdldCB0aGUgY3VycmVudCBzdHJpbmcsIGlmIGl0IGRvZXNuJ3QgZXhpc3QsIGxlYXZlIHRoZSAtMXgtMQorICAgIGNvbnN0IGNoYXIgKnAgPSBnZXQoInBpY3R1cmUtc2l6ZSIpOworICAgIGlmIChwID09IDApCisgICAgICAgIHJldHVybjsKKworICAgIGludCB3LCBoOworICAgIGlmIChwYXJzZV9zaXplKHAsIHcsIGgpID09IDApIHsKKyAgICAgICAgKndpZHRoID0gdzsKKyAgICAgICAgKmhlaWdodCA9IGg7CisgICAgfQorfQorCit2b2lkIENhbWVyYVBhcmFtZXRlcnM6OnNldFBpY3R1cmVGb3JtYXQoY29uc3QgY2hhciAqZm9ybWF0KQoreworICAgIHNldCgicGljdHVyZS1mb3JtYXQiLCBmb3JtYXQpOworfQorCitjb25zdCBjaGFyICpDYW1lcmFQYXJhbWV0ZXJzOjpnZXRQaWN0dXJlRm9ybWF0KCkgY29uc3QKK3sKKyAgICByZXR1cm4gZ2V0KCJwaWN0dXJlLWZvcm1hdCIpOworfQorCit2b2lkIENhbWVyYVBhcmFtZXRlcnM6OmR1bXAoKSBjb25zdAoreworICAgIExPR0QoImR1bXA6IG1NYXAuc2l6ZSA9ICVkIiwgbU1hcC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbU1hcC5zaXplKCk7IGkrKykgeworICAgICAgICBTdHJpbmc4IGssIHY7CisgICAgICAgIGsgPSBtTWFwLmtleUF0KGkpOworICAgICAgICB2ID0gbU1hcC52YWx1ZUF0KGkpOworICAgICAgICBMT0dEKCIlczogJXNcbiIsIGsuc3RyaW5nKCksIHYuc3RyaW5nKCkpOworICAgIH0KK30KKworc3RhdHVzX3QgQ2FtZXJhUGFyYW1ldGVyczo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpIGNvbnN0Cit7CisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgU3RyaW5nOCByZXN1bHQ7CisgICAgc25wcmludGYoYnVmZmVyLCAyNTUsICJDYW1lcmFQYXJhbWV0ZXJzOjpkdW1wOiBtTWFwLnNpemUgPSAlZFxuIiwgbU1hcC5zaXplKCkpOworICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1NYXAuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgU3RyaW5nOCBrLCB2OworICAgICAgICBrID0gbU1hcC5rZXlBdChpKTsKKyAgICAgICAgdiA9IG1NYXAudmFsdWVBdChpKTsKKyAgICAgICAgc25wcmludGYoYnVmZmVyLCAyNTUsICJcdCVzOiAlc1xuIiwgay5zdHJpbmcoKSwgdi5zdHJpbmcoKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICB9CisgICAgd3JpdGUoZmQsIHJlc3VsdC5zdHJpbmcoKSwgcmVzdWx0LnNpemUoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91aS9FR0xEaXNwbGF5U3VyZmFjZS5jcHAgYi9saWJzL3VpL0VHTERpc3BsYXlTdXJmYWNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDZjOThiCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9FR0xEaXNwbGF5U3VyZmFjZS5jcHAKQEAgLTAsMCArMSw1MTkgQEAKKy8qCisgKioKKyAqKiBDb3B5cmlnaHQgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKioKKyAqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAodGhlICJMaWNlbnNlIik7CisgKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoqCisgKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoqCisgKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nIHNvZnR3YXJlCisgKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUworICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5EIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiRUdMRGlzcGxheVN1cmZhY2UiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL21tYW4uaD4KKworI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKyNpbmNsdWRlIDxjdXRpbHMvYXRvbWljLmg+CisjaW5jbHVkZSA8Y3V0aWxzL3Byb3BlcnRpZXMuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlL2NvcHliaXQuaD4KKworI2luY2x1ZGUgPHVpL1N1cmZhY2VDb21wb3NlckNsaWVudC5oPgorI2luY2x1ZGUgPHVpL0Rpc3BsYXlJbmZvLmg+CisjaW5jbHVkZSA8dWkvUmVjdC5oPgorI2luY2x1ZGUgPHVpL1JlZ2lvbi5oPgorI2luY2x1ZGUgPHVpL0VHTERpc3BsYXlTdXJmYWNlLmg+CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyNpbmNsdWRlIDxsaW51eC9tc21fbWRwLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKworI2luY2x1ZGUgPHBpeGVsZmxpbmdlci9mb3JtYXQuaD4KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2VnbF9uYXRpdmVfd2luZG93X3QqIGFuZHJvaWRfY3JlYXRlRGlzcGxheVN1cmZhY2UoKQoreworICAgIGVnbF9uYXRpdmVfd2luZG93X3QqIHMgPSBuZXcgYW5kcm9pZDo6RUdMRGlzcGxheVN1cmZhY2UoKTsKKyAgICBzLT5tZW1vcnlfdHlwZSA9IE5BVElWRV9NRU1PUllfVFlQRV9HUFU7CisgICAgcmV0dXJuIHM7Cit9CisKKyNkZWZpbmUgTElLRUxZKCBleHAgKSAgICAgICAoX19idWlsdGluX2V4cGVjdCggKGV4cCkgIT0gMCwgdHJ1ZSAgKSkKKyNkZWZpbmUgVU5MSUtFTFkoIGV4cCApICAgICAoX19idWlsdGluX2V4cGVjdCggKGV4cCkgIT0gMCwgZmFsc2UgKSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xEaXNwbGF5U3VyZmFjZTo6RUdMRGlzcGxheVN1cmZhY2UoKQorICAgIDogRUdMTmF0aXZlU3VyZmFjZTxFR0xEaXNwbGF5U3VyZmFjZT4oKQoreworICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnZlcnNpb24gPSBzaXplb2YoZWdsX25hdGl2ZV93aW5kb3dfdCk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6aWRlbnQgPSAwOworICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmluY1JlZiA9ICZFR0xEaXNwbGF5U3VyZmFjZTo6aG9va19pbmNSZWY7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6ZGVjUmVmID0gJkVHTERpc3BsYXlTdXJmYWNlOjpob29rX2RlY1JlZjsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojpzd2FwQnVmZmVycyA9ICZFR0xEaXNwbGF5U3VyZmFjZTo6aG9va19zd2FwQnVmZmVyczsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojpjb25uZWN0ID0gMDsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpkaXNjb25uZWN0ID0gMDsKKworICAgIG1GYlswXS5kYXRhID0gMDsKKyAgICBtRmJbMV0uZGF0YSA9IDA7CisgICAgbUJsaXRFbmdpbmUgPSAwOworICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZkID0gbWFwRnJhbWVCdWZmZXIoKTsKKyAgICBpZiAoZWdsX25hdGl2ZV93aW5kb3dfdDo6ZmQgPj0gMCkgeworICAgICAgICAKKyAgICAgICAgaHdfbW9kdWxlX3QgY29uc3QqIG1vZHVsZTsKKyAgICAgICAgaWYgKGh3X2dldF9tb2R1bGUoQ09QWUJJVF9IQVJEV0FSRV9NT0RVTEVfSUQsICZtb2R1bGUpID09IDApIHsKKyAgICAgICAgICAgIGNvcHliaXRfb3Blbihtb2R1bGUsICZtQmxpdEVuZ2luZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGNvbnN0IGZsb2F0IGluMm1tID0gMjUuNGY7CisgICAgICAgIGZsb2F0IHJlZnJlc2hSYXRlID0gMTAwMDAwMDAwMDAwMDAwMExMVSAvICgKKyAgICAgICAgICAgICAgICBmbG9hdCggbUluZm8udXBwZXJfbWFyZ2luICsgbUluZm8ubG93ZXJfbWFyZ2luICsgbUluZm8ueXJlcyApCisgICAgICAgICAgICAgICAgKiAoIG1JbmZvLmxlZnRfbWFyZ2luICArIG1JbmZvLnJpZ2h0X21hcmdpbiArIG1JbmZvLnhyZXMgKQorICAgICAgICAgICAgICAgICogbUluZm8ucGl4Y2xvY2spOworCisgICAgICAgIGNvbnN0IEdHTFN1cmZhY2UmIGJ1ZmZlciA9IG1GYlsxIC0gbUluZGV4XTsKKyAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGggID0gYnVmZmVyLndpZHRoOworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQgPSBidWZmZXIuaGVpZ2h0OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpzdHJpZGUgPSBidWZmZXIuc3RyaWRlOworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojpmb3JtYXQgPSBidWZmZXIuZm9ybWF0OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpiYXNlICAgPSBpbnRwdHJfdChtRmJbMF0uZGF0YSk7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om9mZnNldCA9CisgICAgICAgICAgICBpbnRwdHJfdChidWZmZXIuZGF0YSkgLSBlZ2xfbmF0aXZlX3dpbmRvd190OjpiYXNlOworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpmbGFncyAgPSAwOworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojp4ZHBpID0gKG1JbmZvLnhyZXMgKiBpbjJtbSkgLyBtSW5mby53aWR0aDsKKyAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6eWRwaSA9IChtSW5mby55cmVzICogaW4ybW0pIC8gbUluZm8uaGVpZ2h0OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpmcHMgID0gcmVmcmVzaFJhdGU7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om1lbW9yeV90eXBlID0gTkFUSVZFX01FTU9SWV9UWVBFX0ZCOworICAgICAgICAvLyBubyBlcnJvciwgc2V0IHRoZSBtYWdpYyB3b3JkCisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om1hZ2ljID0gMHg2MDA5MTM7CisgICAgfQorICAgIG1Td2FwQ291bnQgPSAtMTsKKyAgICBtUGFnZUZsaXBDb3VudCA9IDA7Cit9CisKK0VHTERpc3BsYXlTdXJmYWNlOjp+RUdMRGlzcGxheVN1cmZhY2UoKQoreworICAgIG1hZ2ljID0gMDsKKyAgICBjb3B5Yml0X2Nsb3NlKG1CbGl0RW5naW5lKTsKKyAgICBtQmxpdEVuZ2luZSA9IDA7CisgICAgY2xvc2UoZWdsX25hdGl2ZV93aW5kb3dfdDo6ZmQpOworICAgIG11bm1hcChtRmJbMF0uZGF0YSwgbVNpemUpOworICAgIGlmICghKG1GbGFncyAmIFBBR0VfRkxJUCkpCisgICAgICAgIGZyZWUoKHZvaWQqKW1GYlsxXS5kYXRhKTsKK30KKwordm9pZCBFR0xEaXNwbGF5U3VyZmFjZTo6aG9va19pbmNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpIHsKKyAgICBFR0xEaXNwbGF5U3VyZmFjZSogdGhhdCA9IHN0YXRpY19jYXN0PEVHTERpc3BsYXlTdXJmYWNlKj4od2luZG93KTsKKyAgICB0aGF0LT5pbmNTdHJvbmcodGhhdCk7Cit9Cit2b2lkIEVHTERpc3BsYXlTdXJmYWNlOjpob29rX2RlY1JlZihOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdykgeworICAgIEVHTERpc3BsYXlTdXJmYWNlKiB0aGF0ID0gc3RhdGljX2Nhc3Q8RUdMRGlzcGxheVN1cmZhY2UqPih3aW5kb3cpOworICAgIHRoYXQtPmRlY1N0cm9uZyh0aGF0KTsKK30KK3VpbnQzMl90IEVHTERpc3BsYXlTdXJmYWNlOjpob29rX3N3YXBCdWZmZXJzKE5hdGl2ZVdpbmRvd1R5cGUgd2luZG93KSB7CisgICAgRUdMRGlzcGxheVN1cmZhY2UqIHRoYXQgPSBzdGF0aWNfY2FzdDxFR0xEaXNwbGF5U3VyZmFjZSo+KHdpbmRvdyk7CisgICAgcmV0dXJuIHRoYXQtPnN3YXBCdWZmZXJzKCk7Cit9CisKK3ZvaWQgRUdMRGlzcGxheVN1cmZhY2U6OnNldFN3YXBSZWN0YW5nbGUoaW50IGwsIGludCB0LCBpbnQgdywgaW50IGgpCit7CisgICAgbUluZm8ucmVzZXJ2ZWRbMF0gPSAweDU0NDQ1MDU1OyAvLyAiVVBEVCI7CisgICAgbUluZm8ucmVzZXJ2ZWRbMV0gPSAodWludDE2X3QpbCB8ICgodWludDMyX3QpdCA8PCAxNik7CisgICAgbUluZm8ucmVzZXJ2ZWRbMl0gPSAodWludDE2X3QpKGwrdykgfCAoKHVpbnQzMl90KSh0K2gpIDw8IDE2KTsKK30KKwordWludDMyX3QgRUdMRGlzcGxheVN1cmZhY2U6OnN3YXBCdWZmZXJzKCkKK3sKKyNkZWZpbmUgU0hPV19GUFMgMAorI2lmIFNIT1dfRlBTCisgICAgbnNlY3NfdCBub3cgPSBzeXN0ZW1UaW1lKCk7CisgICAgaWYgKG1Td2FwQ291bnQgPT0gLTEpIHsKKyAgICAgICAgbVRpbWUgPSBub3c7CisgICAgICAgIG1Td2FwQ291bnQgPSAwOworICAgICAgICBtU2xlZXAgPSAwOworICAgIH0gZWxzZSB7CisgICAgICAgIG5zZWNzX3QgZCA9IG5vdy1tVGltZTsKKyAgICAgICAgaWYgKGQgPj0gc2Vjb25kcygxKSkgeworICAgICAgICAgICAgZG91YmxlIGZwcyA9IChtU3dhcENvdW50ICogZG91YmxlKHNlY29uZHMoMSkpKSAvIGRvdWJsZShkKTsKKyAgICAgICAgICAgIExPR0QoIiVmIGZwcywgc2xlZXA9JWQgLyBmcmFtZSIsCisgICAgICAgICAgICAgICAgICAgIGZwcywgKGludCluczJ1cyhtU2xlZXAgLyBtU3dhcENvdW50KSk7CisgICAgICAgICAgICBtU3dhcENvdW50ID0gMDsKKyAgICAgICAgICAgIG1UaW1lID0gbm93OworICAgICAgICAgICAgbVNsZWVwID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1Td2FwQ291bnQrKzsKKyAgICAgICAgfQorICAgIH0KKyNlbmRpZgorICAgIC8qIElmIHdlIGNhbid0IGRvIHRoZSBwYWdlX2ZsaXAsIGp1c3QgY29weSB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250ICovCisgICAgaWYgKCEobUZsYWdzICYgUEFHRV9GTElQKSkgeworICAgICAgICBtZW1jcHkobUZiWzBdLmRhdGEsIG1GYlsxXS5kYXRhLCBtSW5mby54cmVzKm1JbmZvLnlyZXMqMik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIGRvIHRoZSBhY3R1YWwgZmxpcAorICAgIG1JbmRleCA9IDEgLSBtSW5kZXg7CisgICAgbUluZm8uYWN0aXZhdGUgPSBGQl9BQ1RJVkFURV9WQkw7CisgICAgbUluZm8ueW9mZnNldCA9IG1JbmRleCA/IG1JbmZvLnlyZXMgOiAwOworICAgIGlmIChpb2N0bChlZ2xfbmF0aXZlX3dpbmRvd190OjpmZCwgRkJJT1BVVF9WU0NSRUVOSU5GTywgJm1JbmZvKSA9PSAtMSkgeworICAgICAgICBMT0dFKCJGQklPUFVUX1ZTQ1JFRU5JTkZPIGZhaWxlZCIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHRoaXMgaXMgYSBtb25zdHJvdXMgaGFjazogQmVjYXVzZSB0aGUgaC93IGFjY2VsZXJhdG9yIGlzIG5vdCBhYmxlCisgICAgICogdG8gcmVuZGVyIGRpcmVjdGx5IGludG8gdGhlIGZyYW1lYnVmZmVyLCB3ZSBuZWVkIHRvIGNvcHkgaXRzCisgICAgICogaW50ZXJuYWwgZnJhbWVidWZmZXIgb3V0IHRvIHRoZSBmYi4KKyAgICAgKiBvZW1bMF0gaXMgdXNlZCB0byBhY2Nlc3MgdGhlIGZkIG9mIGludGVybmFsIGZiLgorICAgICAqIEFsbCB0aGlzIGlzIG5lZWRlZCBvbmx5IGluIHN0YW5kYWxvbmUgbW9kZSwgaW4gU3VyZmFjZUZsaW5nZXIgbW9kZQorICAgICAqIHdlIGNvbnRyb2wgd2hlcmUgdGhlIEdQVSByZW5kZXJzLgorICAgICAqIFdlIGRvIHRoaXMgb25seSBpZiB3ZSBoYXZlIGNvcHliaXQsIHNpbmNlIHRoaXMgaGFjayBpcyBuZWVkZWQgb25seQorICAgICAqIHdpdGggbXNtN2suCisgICAgICovCisgICAgaWYgKGVnbF9uYXRpdmVfd2luZG93X3Q6Om1lbW9yeV90eXBlID09IE5BVElWRV9NRU1PUllfVFlQRV9HUFUgJiYgb2VtWzBdICYmIG1CbGl0RW5naW5lKSB7CisgICAgICAgIGNvcHliaXRfZGV2aWNlX3QgKmNvcHliaXQgPSBtQmxpdEVuZ2luZTsKKyAgICAgICAgY29weWJpdF9yZWN0X3Qgc2RyZWN0ID0geyAwLCAwLAorICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OndpZHRoLCBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQgfTsKKyAgICAgICAgY29weWJpdF9pbWFnZV90IGRzdCA9IHsKKyAgICAgICAgICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojp3aWR0aCwKKyAgICAgICAgICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQsCisgICAgICAgICAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6Zm9ybWF0LAorICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om9mZnNldCwKKyAgICAgICAgICAgICAgICAodm9pZCopZWdsX25hdGl2ZV93aW5kb3dfdDo6YmFzZSwKKyAgICAgICAgICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpmZAorICAgICAgICB9OworICAgICAgICBjb3B5Yml0X2ltYWdlX3Qgc3JjID0geworICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OndpZHRoLAorICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmhlaWdodCwKKyAgICAgICAgICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojpmb3JtYXQsIC8vIFhYWDogdXNlIHByb3BlciBmb3JtYXQKKyAgICAgICAgICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpvZmZzZXQsCisgICAgICAgICAgICAgICAgKHZvaWQqKWVnbF9uYXRpdmVfd2luZG93X3Q6OmJhc2UsICAvLyBYWFg6IHVzZSBwcm9wZXIgYmFzZQorICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om9lbVswXQorICAgICAgICB9OworICAgICAgICByZWdpb25faXRlcmF0b3IgaXQoUmVnaW9uKFJlY3QoCisgICAgICAgICAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGgsIGVnbF9uYXRpdmVfd2luZG93X3Q6OmhlaWdodCkpKTsKKyAgICAgICAgY29weWJpdC0+c2V0X3BhcmFtZXRlcihjb3B5Yml0LCBDT1BZQklUX1RSQU5TRk9STSwgMCk7CisgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9QTEFORV9BTFBIQSwgMHhGRik7CisgICAgICAgIGNvcHliaXQtPnNldF9wYXJhbWV0ZXIoY29weWJpdCwgQ09QWUJJVF9ESVRIRVIsIENPUFlCSVRfRElTQUJMRSk7CisgICAgICAgIGNvcHliaXQtPnN0cmV0Y2goY29weWJpdCwgJmRzdCwgJnNyYywgJnNkcmVjdCwgJnNkcmVjdCwgJml0KTsKKyAgICB9CisKKyAgICAvLyB1cGRhdGUgdGhlIGFkZHJlc3Mgb2YgdGhlIGJ1ZmZlciB0byBkcmF3IHRvIG5leHQKKyAgICBjb25zdCBHR0xTdXJmYWNlJiBidWZmZXIgPSBtRmJbMSAtIG1JbmRleF07CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6b2Zmc2V0ID0KKyAgICAgICAgaW50cHRyX3QoYnVmZmVyLmRhdGEpIC0gZWdsX25hdGl2ZV93aW5kb3dfdDo6YmFzZTsKKworI2lmIFNIT1dfRlBTCisgICAgbVNsZWVwICs9IHN5c3RlbVRpbWUoKS1ub3c7CisjZW5kaWYKKworICAgIG1QYWdlRmxpcENvdW50Kys7CisKKyAgICAvLyBXZSBkb24ndCBzdXBwb3J0IHNjcmVlbi1zaXplIGNoYW5nZXMgZm9yIG5vdworICAgIHJldHVybiAwOworfQorCitpbnQzMl90IEVHTERpc3BsYXlTdXJmYWNlOjpnZXRQYWdlRmxpcENvdW50KCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVBhZ2VGbGlwQ291bnQ7Cit9CisKK3ZvaWQgRUdMRGlzcGxheVN1cmZhY2U6OmNvcHlGcm9udFRvQmFjayhjb25zdCBSZWdpb24mIGNvcHliYWNrKQoreworI2lmIEhBVkVfQU5EUk9JRF9PUworICAgIGlmIChtQmxpdEVuZ2luZSkgeworICAgICAgICBjb3B5Yml0X2ltYWdlX3QgZHN0ID0geworICAgICAgICAgICAgICAgIHc6ICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6c3RyaWRlLAorICAgICAgICAgICAgICAgIGg6ICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6aGVpZ2h0LAorICAgICAgICAgICAgICAgIGZvcm1hdDogZWdsX25hdGl2ZV93aW5kb3dfdDo6Zm9ybWF0LAorICAgICAgICAgICAgICAgIG9mZnNldDogbUZiWzEtbUluZGV4XS5kYXRhIC0gbUZiWzBdLmRhdGEsCisgICAgICAgICAgICAgICAgYmFzZTogICAodm9pZCopZWdsX25hdGl2ZV93aW5kb3dfdDo6YmFzZSwKKyAgICAgICAgICAgICAgICBmZDogICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZkCisgICAgICAgIH07CisgICAgICAgIGNvcHliaXRfaW1hZ2VfdCBzcmMgPSB7CisgICAgICAgICAgICAgICAgdzogICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpzdHJpZGUsCisgICAgICAgICAgICAgICAgaDogICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQsCisgICAgICAgICAgICAgICAgZm9ybWF0OiBlZ2xfbmF0aXZlX3dpbmRvd190Ojpmb3JtYXQsCisgICAgICAgICAgICAgICAgb2Zmc2V0OiBtRmJbbUluZGV4XS5kYXRhIC0gbUZiWzBdLmRhdGEsCisgICAgICAgICAgICAgICAgYmFzZTogICAodm9pZCopZWdsX25hdGl2ZV93aW5kb3dfdDo6YmFzZSwKKyAgICAgICAgICAgICAgICBmZDogICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZkCisgICAgICAgIH07CisgICAgICAgIHJlZ2lvbl9pdGVyYXRvciBpdChjb3B5YmFjayk7CisgICAgICAgIG1CbGl0RW5naW5lLT5ibGl0KG1CbGl0RW5naW5lLCAmZHN0LCAmc3JjLCAmaXQpOworICAgIH0gZWxzZQorI2VuZGlmCisgICAgeworICAgICAgICAvKiBubyBleHRyYSBjb3B5IG5lZWRlZCBzaW5jZSB3ZSBjb3BpZWQgYmFjayB0byBmcm9udCBpbnN0ZWFkIG9mCisgICAgICAgICAqIGZsaXBwaW5nICovCisgICAgICAgIGlmICghKG1GbGFncyAmIFBBR0VfRkxJUCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFJlZ2lvbjo6aXRlcmF0b3IgaXRlcmF0b3IoY29weWJhY2spOworICAgICAgICBpZiAoaXRlcmF0b3IpIHsKKyAgICAgICAgICAgIFJlY3QgcjsKKyAgICAgICAgICAgIHVpbnQ4X3QqIGNvbnN0IHNjcmVlbl9zcmMgPSBtRmJbICBtSW5kZXhdLmRhdGE7CisgICAgICAgICAgICB1aW50OF90KiBjb25zdCBzY3JlZW5fZHN0ID0gbUZiWzEtbUluZGV4XS5kYXRhOworICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGJwcCA9IGJ5dGVzUGVyUGl4ZWwoZWdsX25hdGl2ZV93aW5kb3dfdDo6Zm9ybWF0KTsKKyAgICAgICAgICAgIGNvbnN0IHNpemVfdCBicHIgPSBlZ2xfbmF0aXZlX3dpbmRvd190OjpzdHJpZGUgKiBicHA7CisgICAgICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgICAgICAgICBzc2l6ZV90IGggPSByLmJvdHRvbSAtIHIudG9wOworICAgICAgICAgICAgICAgIGlmIChoKSB7CisgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplID0gKHIucmlnaHQgLSByLmxlZnQpICogYnBwOworICAgICAgICAgICAgICAgICAgICBzaXplX3QgbyA9IChyLmxlZnQgKyBlZ2xfbmF0aXZlX3dpbmRvd190OjpzdHJpZGUgKiByLnRvcCkgKiBicHA7CisgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QqIHMgPSBzY3JlZW5fc3JjICsgbzsKKyAgICAgICAgICAgICAgICAgICAgdWludDhfdCogZCA9IHNjcmVlbl9kc3QgKyBvOworICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZSA9PSBicHIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgKj0gaDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGggPSAxOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkLCBzLCBzaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGQgKz0gYnByOworICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBicHI7CisgICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0taCA+IDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKwordm9pZCBFR0xEaXNwbGF5U3VyZmFjZTo6Y29weUZyb250VG9JbWFnZShjb25zdCBjb3B5Yml0X2ltYWdlX3QmIGRzdCkKK3sKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBpZiAobUJsaXRFbmdpbmUpIHsKKyAgICAgICAgY29weWJpdF9pbWFnZV90IHNyYyA9IHsKKyAgICAgICAgICAgICAgICB3OiAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnN0cmlkZSwKKyAgICAgICAgICAgICAgICBoOiAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmhlaWdodCwKKyAgICAgICAgICAgICAgICBmb3JtYXQ6IGVnbF9uYXRpdmVfd2luZG93X3Q6OmZvcm1hdCwKKyAgICAgICAgICAgICAgICBvZmZzZXQ6IG1GYlttSW5kZXhdLmRhdGEgLSBtRmJbMF0uZGF0YSwKKyAgICAgICAgICAgICAgICBiYXNlOiAgICh2b2lkKillZ2xfbmF0aXZlX3dpbmRvd190OjpiYXNlLAorICAgICAgICAgICAgICAgIGZkOiAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6ZmQKKyAgICAgICAgfTsKKyAgICAgICAgcmVnaW9uX2l0ZXJhdG9yIGl0KFJlZ2lvbihSZWN0KAorICAgICAgICAgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OndpZHRoLCBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQpKSk7CisgICAgICAgIG1CbGl0RW5naW5lLT5ibGl0KG1CbGl0RW5naW5lLCAmZHN0LCAmc3JjLCAmaXQpOworICAgIH0gZWxzZQorI2VuZGlmCisgICAgeworICAgICAgICB1aW50OF90KiBjb25zdCBzY3JlZW5fc3JjID0gbUZiWyAgbUluZGV4XS5kYXRhOworICAgICAgICBjb25zdCBzaXplX3QgYnBwID0gYnl0ZXNQZXJQaXhlbChlZ2xfbmF0aXZlX3dpbmRvd190Ojpmb3JtYXQpOworICAgICAgICBjb25zdCBzaXplX3QgYnByID0gZWdsX25hdGl2ZV93aW5kb3dfdDo6c3RyaWRlICogYnBwOworICAgICAgICBtZW1jcHkoKGNoYXIqKWRzdC5iYXNlICsgZHN0Lm9mZnNldCwgc2NyZWVuX3NyYywKKyAgICAgICAgICAgICAgICBicHIqZWdsX25hdGl2ZV93aW5kb3dfdDo6aGVpZ2h0KTsKKyAgICB9Cit9CisKK3ZvaWQgRUdMRGlzcGxheVN1cmZhY2U6OmNvcHlCYWNrVG9JbWFnZShjb25zdCBjb3B5Yml0X2ltYWdlX3QmIGRzdCkKK3sKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBpZiAobUJsaXRFbmdpbmUpIHsKKyAgICAgICAgY29weWJpdF9pbWFnZV90IHNyYyA9IHsKKyAgICAgICAgICAgICAgICB3OiAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnN0cmlkZSwKKyAgICAgICAgICAgICAgICBoOiAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmhlaWdodCwKKyAgICAgICAgICAgICAgICBmb3JtYXQ6IGVnbF9uYXRpdmVfd2luZG93X3Q6OmZvcm1hdCwKKyAgICAgICAgICAgICAgICBvZmZzZXQ6IG1GYlsxLW1JbmRleF0uZGF0YSAtIG1GYlswXS5kYXRhLAorICAgICAgICAgICAgICAgIGJhc2U6ICAgKHZvaWQqKWVnbF9uYXRpdmVfd2luZG93X3Q6OmJhc2UsCisgICAgICAgICAgICAgICAgZmQ6ICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpmZAorICAgICAgICB9OworICAgICAgICByZWdpb25faXRlcmF0b3IgaXQoUmVnaW9uKFJlY3QoCisgICAgICAgICAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGgsIGVnbF9uYXRpdmVfd2luZG93X3Q6OmhlaWdodCkpKTsKKyAgICAgICAgbUJsaXRFbmdpbmUtPmJsaXQobUJsaXRFbmdpbmUsICZkc3QsICZzcmMsICZpdCk7CisgICAgfSBlbHNlCisjZW5kaWYKKyAgICB7CisgICAgICAgIHVpbnQ4X3QqIGNvbnN0IHNjcmVlbl9zcmMgPSBtRmJbMS1tSW5kZXhdLmRhdGE7CisgICAgICAgIGNvbnN0IHNpemVfdCBicHAgPSBieXRlc1BlclBpeGVsKGVnbF9uYXRpdmVfd2luZG93X3Q6OmZvcm1hdCk7CisgICAgICAgIGNvbnN0IHNpemVfdCBicHIgPSBlZ2xfbmF0aXZlX3dpbmRvd190OjpzdHJpZGUgKiBicHA7CisgICAgICAgIG1lbWNweSgoY2hhciopZHN0LmJhc2UgKyBkc3Qub2Zmc2V0LCBzY3JlZW5fc3JjLAorICAgICAgICAgICAgICAgIGJwciplZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQpOworICAgIH0KK30KKworCitzdGF0dXNfdCBFR0xEaXNwbGF5U3VyZmFjZTo6bWFwRnJhbWVCdWZmZXIoKQoreworICAgIGNoYXIgY29uc3QgKiBjb25zdCBkZXZpY2VfdGVtcGxhdGVbXSA9IHsKKyAgICAgICAgICAgICIvZGV2L2dyYXBoaWNzL2ZiJXUiLAorICAgICAgICAgICAgIi9kZXYvZmIldSIsCisgICAgICAgICAgICAwIH07CisgICAgaW50IGZkID0gLTE7CisgICAgaW50IGk9MDsKKyAgICBjaGFyIG5hbWVbNjRdOworICAgIHdoaWxlICgoZmQ9PS0xKSAmJiBkZXZpY2VfdGVtcGxhdGVbaV0pIHsKKyAgICAgICAgc25wcmludGYobmFtZSwgNjQsIGRldmljZV90ZW1wbGF0ZVtpXSwgMCk7CisgICAgICAgIGZkID0gb3BlbihuYW1lLCBPX1JEV1IsIDApOworICAgICAgICBpKys7CisgICAgfQorICAgIGlmIChmZCA8IDApCisgICAgICAgIHJldHVybiAtZXJybm87CisKKyAgICBzdHJ1Y3QgZmJfZml4X3NjcmVlbmluZm8gZmluZm87CisgICAgaWYgKGlvY3RsKGZkLCBGQklPR0VUX0ZTQ1JFRU5JTkZPLCAmZmluZm8pID09IC0xKQorICAgICAgICByZXR1cm4gLWVycm5vOworCisgICAgc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvIGluZm87CisgICAgaWYgKGlvY3RsKGZkLCBGQklPR0VUX1ZTQ1JFRU5JTkZPLCAmaW5mbykgPT0gLTEpCisgICAgICAgIHJldHVybiAtZXJybm87CisKKyAgICBpbmZvLnJlc2VydmVkWzBdID0gMDsKKyAgICBpbmZvLnJlc2VydmVkWzFdID0gMDsKKyAgICBpbmZvLnJlc2VydmVkWzJdID0gMDsKKyAgICBpbmZvLnhvZmZzZXQgPSAwOworICAgIGluZm8ueW9mZnNldCA9IDA7CisgICAgaW5mby55cmVzX3ZpcnR1YWwgPSBpbmZvLnlyZXMgKiAyOworICAgIGluZm8uYml0c19wZXJfcGl4ZWwgPSAxNjsKKyAgICAvKiBFeHBsaWNpdGx5IHJlcXVlc3QgNS82LzUgKi8KKyAgICBpbmZvLnJlZC5vZmZzZXQgPSAxMTsKKyAgICBpbmZvLnJlZC5sZW5ndGggPSA1OworICAgIGluZm8uZ3JlZW4ub2Zmc2V0ID0gNTsKKyAgICBpbmZvLmdyZWVuLmxlbmd0aCA9IDY7CisgICAgaW5mby5ibHVlLm9mZnNldCA9IDA7CisgICAgaW5mby5ibHVlLmxlbmd0aCA9IDU7CisgICAgaW5mby50cmFuc3Aub2Zmc2V0ID0gMDsKKyAgICBpbmZvLnRyYW5zcC5sZW5ndGggPSAwOworICAgIGluZm8uYWN0aXZhdGUgPSBGQl9BQ1RJVkFURV9OT1c7CisKKyAgICB1aW50MzJfdCBmbGFncyA9IFBBR0VfRkxJUDsKKyAgICBpZiAoaW9jdGwoZmQsIEZCSU9QVVRfVlNDUkVFTklORk8sICZpbmZvKSA9PSAtMSkgeworICAgICAgICBpbmZvLnlyZXNfdmlydHVhbCA9IGluZm8ueXJlczsKKyAgICAgICAgZmxhZ3MgJj0gflBBR0VfRkxJUDsKKyAgICAgICAgTE9HVygiRkJJT1BVVF9WU0NSRUVOSU5GTyBmYWlsZWQsIHBhZ2UgZmxpcHBpbmcgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIGlmIChpbmZvLnlyZXNfdmlydHVhbCA8IGluZm8ueXJlcyAqIDIpIHsKKyAgICAgICAgaW5mby55cmVzX3ZpcnR1YWwgPSBpbmZvLnlyZXM7CisgICAgICAgIGZsYWdzICY9IH5QQUdFX0ZMSVA7CisgICAgICAgIExPR1coInBhZ2UgZmxpcHBpbmcgbm90IHN1cHBvcnRlZCAoeXJlc192aXJ0dWFsPSVkLCByZXF1ZXN0ZWQ9JWQpIiwKKyAgICAgICAgICAgICAgICBpbmZvLnlyZXNfdmlydHVhbCwgaW5mby55cmVzKjIpOworICAgIH0KKworICAgIGlmIChpb2N0bChmZCwgRkJJT0dFVF9WU0NSRUVOSU5GTywgJmluZm8pID09IC0xKQorICAgICAgICByZXR1cm4gLWVycm5vOworCisgICAgaW50IHJlZnJlc2hSYXRlID0gMTAwMDAwMDAwMDAwMDAwMExMVSAvCisgICAgKAorICAgICAgICAgICAgdWludDY0X3QoIGluZm8udXBwZXJfbWFyZ2luICsgaW5mby5sb3dlcl9tYXJnaW4gKyBpbmZvLnlyZXMgKQorICAgICAgICAgICAgKiAoIGluZm8ubGVmdF9tYXJnaW4gICsgaW5mby5yaWdodF9tYXJnaW4gKyBpbmZvLnhyZXMgKQorICAgICAgICAgICAgKiBpbmZvLnBpeGNsb2NrCisgICAgKTsKKworICAgIGlmIChyZWZyZXNoUmF0ZSA9PSAwKSB7CisgICAgICAgIC8vIGJsZWFnaCwgYmFkIGluZm8gZnJvbSB0aGUgZHJpdmVyCisgICAgICAgIHJlZnJlc2hSYXRlID0gNjAqMTAwMDsgIC8vIDYwIEh6CisgICAgfQorICAgIGlmIChpbnQoaW5mby53aWR0aCkgPD0gMCB8fCBpbnQoaW5mby5oZWlnaHQpIDw9IDApIHsKKyAgICAgICAgLy8gdGhlIGRyaXZlciBkb2Vzbid0IHJldHVybiB0aGF0IGluZm9ybWF0aW9uCisgICAgICAgIC8vIGRlZmF1bHQgdG8gMTYwIGRwaQorICAgICAgICBpbmZvLndpZHRoICA9ICgoaW5mby54cmVzICogMjUuNGYpLzE2MC4wZiArIDAuNWYpOworICAgICAgICBpbmZvLmhlaWdodCA9ICgoaW5mby55cmVzICogMjUuNGYpLzE2MC4wZiArIDAuNWYpOworICAgIH0KKworICAgIGZsb2F0IHhkcGkgPSAoaW5mby54cmVzICogMjUuNGYpIC8gaW5mby53aWR0aDsKKyAgICBmbG9hdCB5ZHBpID0gKGluZm8ueXJlcyAqIDI1LjRmKSAvIGluZm8uaGVpZ2h0OworICAgIGZsb2F0IGZwcyAgPSByZWZyZXNoUmF0ZSAvIDEwMDAuMGY7CisKKyAgICBMT0dJKCAgICJ1c2luZyAoZmQ9JWQpXG4iCisgICAgICAgICAgICAiaWQgICAgICAgICAgID0gJXNcbiIKKyAgICAgICAgICAgICJ4cmVzICAgICAgICAgPSAlZCBweFxuIgorICAgICAgICAgICAgInlyZXMgICAgICAgICA9ICVkIHB4XG4iCisgICAgICAgICAgICAieHJlc192aXJ0dWFsID0gJWQgcHhcbiIKKyAgICAgICAgICAgICJ5cmVzX3ZpcnR1YWwgPSAlZCBweFxuIgorICAgICAgICAgICAgImJwcCAgICAgICAgICA9ICVkXG4iCisgICAgICAgICAgICAiciAgICAgICAgICAgID0gJTJ1OiV1XG4iCisgICAgICAgICAgICAiZyAgICAgICAgICAgID0gJTJ1OiV1XG4iCisgICAgICAgICAgICAiYiAgICAgICAgICAgID0gJTJ1OiV1XG4iLAorICAgICAgICAgICAgZmQsCisgICAgICAgICAgICBmaW5mby5pZCwKKyAgICAgICAgICAgIGluZm8ueHJlcywKKyAgICAgICAgICAgIGluZm8ueXJlcywKKyAgICAgICAgICAgIGluZm8ueHJlc192aXJ0dWFsLAorICAgICAgICAgICAgaW5mby55cmVzX3ZpcnR1YWwsCisgICAgICAgICAgICBpbmZvLmJpdHNfcGVyX3BpeGVsLAorICAgICAgICAgICAgaW5mby5yZWQub2Zmc2V0LCBpbmZvLnJlZC5sZW5ndGgsCisgICAgICAgICAgICBpbmZvLmdyZWVuLm9mZnNldCwgaW5mby5ncmVlbi5sZW5ndGgsCisgICAgICAgICAgICBpbmZvLmJsdWUub2Zmc2V0LCBpbmZvLmJsdWUubGVuZ3RoCisgICAgKTsKKworICAgIExPR0koICAgIndpZHRoICAgICAgICA9ICVkIG1tICglZiBkcGkpXG4iCisgICAgICAgICAgICAiaGVpZ2h0ICAgICAgID0gJWQgbW0gKCVmIGRwaSlcbiIKKyAgICAgICAgICAgICJyZWZyZXNoIHJhdGUgPSAlLjJmIEh6XG4iLAorICAgICAgICAgICAgaW5mby53aWR0aCwgIHhkcGksCisgICAgICAgICAgICBpbmZvLmhlaWdodCwgeWRwaSwKKyAgICAgICAgICAgIGZwcworICAgICk7CisKKworICAgIGlmIChpb2N0bChmZCwgRkJJT0dFVF9GU0NSRUVOSU5GTywgJmZpbmZvKSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC1lcnJubzsKKworICAgIGlmIChmaW5mby5zbWVtX2xlbiA8PSAwKQorICAgICAgICByZXR1cm4gLWVycm5vOworCisgICAgLyoKKyAgICAgKiBPcGVuIGFuZCBtYXAgdGhlIGRpc3BsYXkuCisgICAgICovCisKKyAgICB2b2lkKiBidWZmZXIgID0gKHVpbnQxNl90KikgbW1hcCgKKyAgICAgICAgICAgIDAsIGZpbmZvLnNtZW1fbGVuLAorICAgICAgICAgICAgUFJPVF9SRUFEIHwgUFJPVF9XUklURSwKKyAgICAgICAgICAgIE1BUF9TSEFSRUQsCisgICAgICAgICAgICBmZCwgMCk7CisKKyAgICBpZiAoYnVmZmVyID09IE1BUF9GQUlMRUQpCisgICAgICAgIHJldHVybiAtZXJybm87CisKKyAgICAvLyBhdCBsZWFzdCBmb3Igbm93LCBhbHdheXMgY2xlYXIgdGhlIGZiCisgICAgbWVtc2V0KGJ1ZmZlciwgMCwgZmluZm8uc21lbV9sZW4pOworCisgICAgdWludDhfdCogb2Zmc2NyZWVuWzJdOworICAgIG9mZnNjcmVlblswXSA9ICh1aW50OF90KilidWZmZXI7CisgICAgaWYgKGZsYWdzICYgUEFHRV9GTElQKSB7CisgICAgICAgIG9mZnNjcmVlblsxXSA9ICh1aW50OF90KilidWZmZXIgKyBmaW5mby5saW5lX2xlbmd0aCppbmZvLnlyZXM7CisgICAgfSBlbHNlIHsKKyAgICAgICAgb2Zmc2NyZWVuWzFdID0gKHVpbnQ4X3QqKW1hbGxvYyhmaW5mby5zbWVtX2xlbik7CisgICAgICAgIGlmIChvZmZzY3JlZW5bMV0gPT0gMCkgeworICAgICAgICAgICAgbXVubWFwKGJ1ZmZlciwgZmluZm8uc21lbV9sZW4pOworICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgfQorICAgIH0KKworICAgIG1GbGFncyA9IGZsYWdzOworICAgIG1JbmZvID0gaW5mbzsKKyAgICBtRmluZm8gPSBmaW5mbzsKKyAgICBtU2l6ZSA9IGZpbmZvLnNtZW1fbGVuOworICAgIG1JbmRleCA9IDA7CisgICAgZm9yIChpbnQgaT0wIDsgaTwyIDsgaSsrKSB7CisgICAgICAgIG1GYltpXS52ZXJzaW9uID0gc2l6ZW9mKEdHTFN1cmZhY2UpOworICAgICAgICBtRmJbaV0ud2lkdGggICA9IGluZm8ueHJlczsKKyAgICAgICAgbUZiW2ldLmhlaWdodCAgPSBpbmZvLnlyZXM7CisgICAgICAgIG1GYltpXS5zdHJpZGUgID0gZmluZm8ubGluZV9sZW5ndGggLyAoaW5mby5iaXRzX3Blcl9waXhlbCA+PiAzKTsKKyAgICAgICAgbUZiW2ldLmRhdGEgICAgPSAoR0dMdWJ5dGUqKShvZmZzY3JlZW5baV0pOworICAgICAgICBtRmJbaV0uZm9ybWF0ICA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NTsKKyAgICB9CisgICAgcmV0dXJuIGZkOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkaWZmIC0tZ2l0IGEvbGlicy91aS9FR0xOYXRpdmVXaW5kb3dTdXJmYWNlLmNwcCBiL2xpYnMvdWkvRUdMTmF0aXZlV2luZG93U3VyZmFjZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjEwNzFjZgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvRUdMTmF0aXZlV2luZG93U3VyZmFjZS5jcHAKQEAgLTAsMCArMSwxNjEgQEAKKy8qIAorKioKKyoqIENvcHlyaWdodCAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNkZWZpbmUgTE9HX1RBRyAiRUdMTmF0aXZlV2luZG93U3VyZmFjZSIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisjaW5jbHVkZSA8Y3V0aWxzL2F0b21pYy5oPgorCisjaW5jbHVkZSA8dWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50Lmg+CisjaW5jbHVkZSA8dWkvRGlzcGxheUluZm8uaD4KKyNpbmNsdWRlIDx1aS9SZWN0Lmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisKKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvZm9ybWF0Lmg+CisKKyNpbmNsdWRlIDx1aS9FR0xOYXRpdmVXaW5kb3dTdXJmYWNlLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6RUdMTmF0aXZlV2luZG93U3VyZmFjZShjb25zdCBzcDxTdXJmYWNlPiYgc3VyZmFjZSkKKyAgICA6IEVHTE5hdGl2ZVN1cmZhY2U8RUdMTmF0aXZlV2luZG93U3VyZmFjZT4oKSwKKyAgICBtU3VyZmFjZShzdXJmYWNlKSwgbUNvbm5lY3RlZChmYWxzZSkKK3sKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjptYWdpYyA9IDB4NjAwOTEzOworICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnZlcnNpb24gPSBzaXplb2YoZWdsX25hdGl2ZV93aW5kb3dfdCk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6aWRlbnQgPSAwOworICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmluY1JlZiA9ICZFR0xOYXRpdmVXaW5kb3dTdXJmYWNlOjpob29rX2luY1JlZjsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpkZWNSZWYgPSAmRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6aG9va19kZWNSZWY7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6c3dhcEJ1ZmZlcnMgPSAmRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6aG9va19zd2FwQnVmZmVyczsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190Ojpjb25uZWN0ID0gJkVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6Omhvb2tfY29ubmVjdDsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpkaXNjb25uZWN0ID0gJkVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6Omhvb2tfZGlzY29ubmVjdDsKKyAgICAKKyAgICBEaXNwbGF5SW5mbyBkaW5mbzsKKyAgICBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmdldERpc3BsYXlJbmZvKDAsICZkaW5mbyk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6eGRwaSA9IGRpbmZvLnhkcGk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6eWRwaSA9IGRpbmZvLnlkcGk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6ZnBzICA9IGRpbmZvLmZwczsKKyAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpmbGFncz0gRUdMX05BVElWRVNfRkxBR19ERVNUUk9ZX0JBQ0tCVUZGRVI7Cit9CisKK0VHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6On5FR0xOYXRpdmVXaW5kb3dTdXJmYWNlKCkKK3sKKyAgICBkaXNjb25uZWN0KCk7CisgICAgbVN1cmZhY2UuY2xlYXIoKTsKKyAgICBtYWdpYyA9IDA7Cit9CisKK3ZvaWQgRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6aG9va19pbmNSZWYoTmF0aXZlV2luZG93VHlwZSB3aW5kb3cpCit7CisgICAgRUdMTmF0aXZlV2luZG93U3VyZmFjZSogdGhhdCA9IHN0YXRpY19jYXN0PEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2UqPih3aW5kb3cpOworICAgIHRoYXQtPmluY1N0cm9uZyh0aGF0KTsKK30KKwordm9pZCBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlOjpob29rX2RlY1JlZihOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdykKK3sKKyAgICBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlKiB0aGF0ID0gc3RhdGljX2Nhc3Q8RUdMTmF0aXZlV2luZG93U3VyZmFjZSo+KHdpbmRvdyk7CisgICAgdGhhdC0+ZGVjU3Ryb25nKHRoYXQpOworfQorCit2b2lkIEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6Omhvb2tfY29ubmVjdChOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdykKK3sKKyAgICBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlKiB0aGF0ID0gc3RhdGljX2Nhc3Q8RUdMTmF0aXZlV2luZG93U3VyZmFjZSo+KHdpbmRvdyk7CisgICAgdGhhdC0+Y29ubmVjdCgpOworfQorCit2b2lkIEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6Omhvb2tfZGlzY29ubmVjdChOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdykKK3sKKyAgICBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlKiB0aGF0ID0gc3RhdGljX2Nhc3Q8RUdMTmF0aXZlV2luZG93U3VyZmFjZSo+KHdpbmRvdyk7CisgICAgdGhhdC0+ZGlzY29ubmVjdCgpOworfQorCit1aW50MzJfdCBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlOjpob29rX3N3YXBCdWZmZXJzKE5hdGl2ZVdpbmRvd1R5cGUgd2luZG93KQoreworICAgIEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2UqIHRoYXQgPSBzdGF0aWNfY2FzdDxFR0xOYXRpdmVXaW5kb3dTdXJmYWNlKj4od2luZG93KTsKKyAgICByZXR1cm4gdGhhdC0+c3dhcEJ1ZmZlcnMoKTsKK30KKwordm9pZCBFR0xOYXRpdmVXaW5kb3dTdXJmYWNlOjpzZXRTd2FwUmVjdGFuZ2xlKGludCBsLCBpbnQgdCwgaW50IHcsIGludCBoKQoreworICAgIG1TdXJmYWNlLT5zZXRTd2FwUmVjdGFuZ2xlKFJlY3QobCwgdCwgbCt3LCB0K2gpKTsKK30KKwordWludDMyX3QgRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6c3dhcEJ1ZmZlcnMoKQoreworICAgIGNvbnN0IGludCB3ID0gZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGg7CisgICAgY29uc3QgaW50IGggPSBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQ7CisgICAgY29uc3Qgc3A8U3VyZmFjZT4mIHN1cmZhY2UobVN1cmZhY2UpOworICAgIFN1cmZhY2U6OlN1cmZhY2VJbmZvIGluZm87CisgICAgc3VyZmFjZS0+dW5sb2NrQW5kUG9zdCgpOworICAgIHN1cmZhY2UtPmxvY2soJmluZm8pOworICAgIC8vIHVwZGF0ZSB0aGUgYWRkcmVzcyBvZiB0aGUgYnVmZmVyIHRvIGRyYXcgdG8gbmV4dAorICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmJhc2UgICA9IGludHB0cl90KGluZm8uYmFzZSk7CisgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6b2Zmc2V0ID0gaW50cHRyX3QoaW5mby5iaXRzKSAtIGludHB0cl90KGluZm8uYmFzZSk7CisgICAgCisgICAgLy8gdXBkYXRlIHNpemUgaWYgaXQgY2hhbmdlZAorICAgIGlmICh3ICE9IGludChpbmZvLncpIHx8IGggIT0gaW50KGluZm8uaCkpIHsKKyAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGggID0gaW5mby53OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQgPSBpbmZvLmg7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnN0cmlkZSA9IGluZm8uYnByIC8gYnl0ZXNQZXJQaXhlbChpbmZvLmZvcm1hdCk7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZvcm1hdCA9IGluZm8uZm9ybWF0OworICAgICAgICByZXR1cm4gRUdMX05BVElWRVNfRkxBR19TSVpFX0NIQU5HRUQ7CisgICAgfQorICAgIHJldHVybiAwOworfQorCit2b2lkIEVHTE5hdGl2ZVdpbmRvd1N1cmZhY2U6OmNvbm5lY3QoKQoreyAgIAorICAgIGlmICghbUNvbm5lY3RlZCkgeworICAgICAgICBTdXJmYWNlOjpTdXJmYWNlSW5mbyBpbmZvOworICAgICAgICBtU3VyZmFjZS0+bG9jaygmaW5mbyk7CisgICAgICAgIG1TdXJmYWNlLT5zZXRTd2FwUmVjdGFuZ2xlKFJlY3QoaW5mby53LCBpbmZvLmgpKTsKKyAgICAgICAgbUNvbm5lY3RlZCA9IHRydWU7CisKKyAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdDo6d2lkdGggID0gaW5mby53OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpoZWlnaHQgPSBpbmZvLmg7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OnN0cmlkZSA9IGluZm8uYnByIC8gYnl0ZXNQZXJQaXhlbChpbmZvLmZvcm1hdCk7CisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZvcm1hdCA9IGluZm8uZm9ybWF0OworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpiYXNlICAgPSBpbnRwdHJfdChpbmZvLmJhc2UpOworICAgICAgICBlZ2xfbmF0aXZlX3dpbmRvd190OjpvZmZzZXQgPSBpbnRwdHJfdChpbmZvLmJpdHMpIC0gaW50cHRyX3QoaW5mby5iYXNlKTsKKyAgICAgICAgLy8gRklYTUU6IGVnbF9uYXRpdmVfd2luZG93X3Q6Om1lbW9yeV90eXBlIHVzZWQgdG8gYmUgc2V0IGZyb20KKyAgICAgICAgLy8gbVN1cmZhY2UsIGJ1dCB3ZSB3YW50ZWQgdG8gYnJlYWsgdGhpcyBkZXBlbmRlbmN5LiBXZSBzZXQgaXQgdG8KKyAgICAgICAgLy8gR1BVIGJlY2F1c2UgdGhlIHNvZnR3YXJlIHJlbmRlcmVkIGRvZXNuJ3QgY2FyZSwgYnV0IHRoZSBoL3cKKyAgICAgICAgLy8gYWNjZWxlcmF0b3IgbmVlZHMgaXQuIEV2ZW50dWFsbHksIHRoaXMgdmFsdWUgc2hvdWxkIGdvIGF3YXkKKyAgICAgICAgLy8gY29tcGxldGVseSwgc2luY2UgbWVtb3J5IHdpbGwgYmUgbWFuYWdlZCBieSBPcGVuR0wuCisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6Om1lbW9yeV90eXBlID0gTkFUSVZFX01FTU9SWV9UWVBFX0dQVTsgCisgICAgICAgIGVnbF9uYXRpdmVfd2luZG93X3Q6OmZkID0gMDsKKyAgICB9Cit9CisKK3ZvaWQgRUdMTmF0aXZlV2luZG93U3VyZmFjZTo6ZGlzY29ubmVjdCgpCit7CisgICAgaWYgKG1Db25uZWN0ZWQpIHsKKyAgICAgICAgbVN1cmZhY2UtPnVubG9jaygpOworICAgICAgICBtQ29ubmVjdGVkID0gZmFsc2U7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkaWZmIC0tZ2l0IGEvbGlicy91aS9FdmVudEh1Yi5jcHAgYi9saWJzL3VpL0V2ZW50SHViLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYjI5YjA5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9FdmVudEh1Yi5jcHAKQEAgLTAsMCArMSw3OTMgQEAKKy8vCisvLyBDb3B5cmlnaHQgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisvLworLy8gSGFuZGxlIGV2ZW50cywgbGlrZSBrZXkgaW5wdXQgYW5kIHZzeW5jLgorLy8KKy8vIFRoZSBnb2FsIGlzIHRvIHByb3ZpZGUgYW4gb3B0aW1pemVkIHNvbHV0aW9uIGZvciBMaW51eCwgbm90IGFuCisvLyBpbXBsZW1lbnRhdGlvbiB0aGF0IHdvcmtzIHdlbGwgYWNyb3NzIGFsbCBwbGF0Zm9ybXMuICBXZSBleHBlY3QKKy8vIGV2ZW50cyB0byBhcnJpdmUgb24gZmlsZSBkZXNjcmlwdG9ycywgc28gdGhhdCB3ZSBjYW4gdXNlIGEgc2VsZWN0KCkKKy8vIHNlbGVjdCgpIGNhbGwgdG8gc2xlZXAuCisvLworLy8gV2UgY2FuJ3Qgc2VsZWN0KCkgb24gYW55dGhpbmcgYnV0IG5ldHdvcmsgc29ja2V0cyBpbiBXaW5kb3dzLCBzbyB3ZQorLy8gcHJvdmlkZSBhbiBhbHRlcm5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBvZiB3YWl0RXZlbnQgZm9yIHRoYXQgcGxhdGZvcm0uCisvLworI2RlZmluZSBMT0dfVEFHICJFdmVudEh1YiIKKworLy8jZGVmaW5lIExPR19OREVCVUcgMAorCisjaW5jbHVkZSA8dWkvRXZlbnRIdWIuaD4KKyNpbmNsdWRlIDxoYXJkd2FyZV9sZWdhY3kvcG93ZXIuaD4KKworI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvVGltZXJzLmg+CisjaW5jbHVkZSA8dXRpbHMuaD4KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxtZW1vcnkuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGFzc2VydC5oPgorCisjaW5jbHVkZSAiS2V5TGF5b3V0TWFwLmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxkaXJlbnQuaD4KKyNpZmRlZiBIQVZFX0lOT1RJRlkKKyMgaW5jbHVkZSA8c3lzL2lub3RpZnkuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfQU5EUk9JRF9PUworIyBpbmNsdWRlIDxzeXMvbGltaXRzLmg+ICAgICAgICAvKiBub3QgcGFydCBvZiBMaW51eCAqLworI2VuZGlmCisjaW5jbHVkZSA8c3lzL3BvbGwuaD4KKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKworLyogdGhpcyBtYWNybyBpcyB1c2VkIHRvIHRlbGwgaWYgImJpdCIgaXMgc2V0IGluICJhcnJheSIKKyAqIGl0IHNlbGVjdHMgYSBieXRlIGZyb20gdGhlIGFycmF5LCBhbmQgZG9lcyBhIGJvb2xlYW4gQU5ECisgKiBvcGVyYXRpb24gd2l0aCBhIGJ5dGUgdGhhdCBvbmx5IGhhcyB0aGUgcmVsZXZhbnQgYml0IHNldC4KKyAqIGVnLiB0byBjaGVjayBmb3IgdGhlIDEydGggYml0LCB3ZSBkbyAoYXJyYXlbMV0gJiAxPDw0KQorICovCisjZGVmaW5lIHRlc3RfYml0KGJpdCwgYXJyYXkpICAgIChhcnJheVtiaXQvOF0gJiAoMTw8KGJpdCU4KSkpCisKKyNkZWZpbmUgSURfTUFTSyAgMHgwMDAwZmZmZgorI2RlZmluZSBTRVFfTUFTSyAweDdmZmYwMDAwCisjZGVmaW5lIFNFUV9TSElGVCAxNgorI2RlZmluZSBpZF90b19pbmRleChpZCkgICAgICAgICAoKGlkJklEX01BU0spKzEpCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RhdGljIGNvbnN0IGNoYXIgKldBS0VfTE9DS19JRCA9ICJLZXlFdmVudHMiOworc3RhdGljIGNvbnN0IGNoYXIgKmRldmljZV9wYXRoID0gIi9kZXYvaW5wdXQiOworCisvKiByZXR1cm4gdGhlIGxhcmdlciBpbnRlZ2VyICovCitzdGF0aWMgaW5saW5lIGludCBtYXgoaW50IHYxLCBpbnQgdjIpCit7CisgICAgcmV0dXJuICh2MSA+IHYyKSA/IHYxIDogdjI7Cit9CisKK0V2ZW50SHViOjpkZXZpY2VfdDo6ZGV2aWNlX3QoaW50MzJfdCBfaWQsIGNvbnN0IGNoYXIqIF9wYXRoKQorICAgIDogaWQoX2lkKSwgcGF0aChfcGF0aCksIGNsYXNzZXMoMCkKKyAgICAsIGtleUJpdG1hc2soTlVMTCksIGxheW91dE1hcChuZXcgS2V5TGF5b3V0TWFwKCkpLCBuZXh0KE5VTEwpIHsKK30KKworRXZlbnRIdWI6OmRldmljZV90Ojp+ZGV2aWNlX3QoKSB7CisgICAgZGVsZXRlIFtdIGtleUJpdG1hc2s7CisgICAgZGVsZXRlIGxheW91dE1hcDsKK30KKworRXZlbnRIdWI6OkV2ZW50SHViKHZvaWQpCisgICAgOiBtRXJyb3IoTk9fSU5JVCksIG1IYXZlRmlyc3RLZXlib2FyZChmYWxzZSksIG1GaXJzdEtleWJvYXJkSWQoMCkKKyAgICAsIG1EZXZpY2VzQnlJZCgwKSwgbU51bURldmljZXNCeUlkKDApCisgICAgLCBtT3BlbmluZ0RldmljZXMoMCksIG1DbG9zaW5nRGV2aWNlcygwKQorICAgICwgbURldmljZXMoMCksIG1GRHMoMCksIG1GRENvdW50KDApCit7CisgICAgYWNxdWlyZV93YWtlX2xvY2soUEFSVElBTF9XQUtFX0xPQ0ssIFdBS0VfTE9DS19JRCk7CisjaWZkZWYgRVZfU1cKKyAgICBtZW1zZXQobVN3aXRjaGVzLCAwLCBzaXplb2YobVN3aXRjaGVzKSk7CisjZW5kaWYKK30KKworLyoKKyAqIENsZWFuIHVwLgorICovCitFdmVudEh1Yjo6fkV2ZW50SHViKHZvaWQpCit7CisgICAgcmVsZWFzZV93YWtlX2xvY2soV0FLRV9MT0NLX0lEKTsKKyAgICAvLyB3ZSBzaG91bGQgZnJlZSBzdHVmZiBoZXJlLi4uCit9CisKK3ZvaWQgRXZlbnRIdWI6Om9uRmlyc3RSZWYoKQoreworICAgIG1FcnJvciA9IG9wZW5QbGF0Zm9ybUlucHV0KCkgPyBOT19FUlJPUiA6IFVOS05PV05fRVJST1I7Cit9CisKK3N0YXR1c190IEV2ZW50SHViOjplcnJvckNoZWNrKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUVycm9yOworfQorCitTdHJpbmc4IEV2ZW50SHViOjpnZXREZXZpY2VOYW1lKGludDMyX3QgZGV2aWNlSWQpIGNvbnN0Cit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICBkZXZpY2VfdCogZGV2aWNlID0gZ2V0RGV2aWNlKGRldmljZUlkKTsKKyAgICBpZiAoZGV2aWNlID09IE5VTEwpIHJldHVybiBTdHJpbmc4KCk7CisgICAgcmV0dXJuIGRldmljZS0+bmFtZTsKK30KKwordWludDMyX3QgRXZlbnRIdWI6OmdldERldmljZUNsYXNzZXMoaW50MzJfdCBkZXZpY2VJZCkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIGRldmljZV90KiBkZXZpY2UgPSBnZXREZXZpY2UoZGV2aWNlSWQpOworICAgIGlmIChkZXZpY2UgPT0gTlVMTCkgcmV0dXJuIDA7CisgICAgcmV0dXJuIGRldmljZS0+Y2xhc3NlczsKK30KKworaW50IEV2ZW50SHViOjpnZXRBYnNvbHV0ZUluZm8oaW50MzJfdCBkZXZpY2VJZCwgaW50IGF4aXMsIGludCAqb3V0TWluVmFsdWUsCisgICAgICAgIGludCogb3V0TWF4VmFsdWUsIGludCogb3V0RmxhdCwgaW50KiBvdXRGdXp6KSBjb25zdAoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgZGV2aWNlX3QqIGRldmljZSA9IGdldERldmljZShkZXZpY2VJZCk7CisgICAgaWYgKGRldmljZSA9PSBOVUxMKSByZXR1cm4gLTE7CisKKyAgICBzdHJ1Y3QgaW5wdXRfYWJzaW5mbyBpbmZvOworCisgICAgaWYoaW9jdGwobUZEc1tpZF90b19pbmRleChkZXZpY2UtPmlkKV0uZmQsIEVWSU9DR0FCUyhheGlzKSwgJmluZm8pKSB7CisgICAgICAgIExPR0UoIkVycm9yIHJlYWRpbmcgYWJzb2x1dGUgY29udHJvbGxlciAlZCBmb3IgZGV2aWNlICVzIGZkICVkXG4iLAorICAgICAgICAgICAgIGF4aXMsIGRldmljZS0+bmFtZS5zdHJpbmcoKSwgbUZEc1tpZF90b19pbmRleChkZXZpY2UtPmlkKV0uZmQpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgICpvdXRNaW5WYWx1ZSA9IGluZm8ubWluaW11bTsKKyAgICAqb3V0TWF4VmFsdWUgPSBpbmZvLm1heGltdW07CisgICAgKm91dEZsYXQgPSBpbmZvLmZsYXQ7CisgICAgKm91dEZ1enogPSBpbmZvLmZ1eno7CisgICAgcmV0dXJuIDA7Cit9CisKK2ludCBFdmVudEh1Yjo6Z2V0U3dpdGNoU3RhdGUoaW50IHN3KSBjb25zdAoreworI2lmZGVmIEVWX1NXCisgICAgaWYgKHN3ID49IDAgJiYgc3cgPD0gU1dfTUFYKSB7CisgICAgICAgIGludDMyX3QgZGV2aWQgPSBtU3dpdGNoZXNbc3ddOworICAgICAgICBpZiAoZGV2aWQgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN3aXRjaFN0YXRlKGRldmlkLCBzdyk7CisgICAgICAgIH0KKyAgICB9CisjZW5kaWYKKyAgICByZXR1cm4gLTE7Cit9CisKK2ludCBFdmVudEh1Yjo6Z2V0U3dpdGNoU3RhdGUoaW50MzJfdCBkZXZpY2VJZCwgaW50IHN3KSBjb25zdAoreworI2lmZGVmIEVWX1NXCisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICBkZXZpY2VfdCogZGV2aWNlID0gZ2V0RGV2aWNlKGRldmljZUlkKTsKKyAgICBpZiAoZGV2aWNlID09IE5VTEwpIHJldHVybiAtMTsKKyAgICAKKyAgICBpZiAoc3cgPj0gMCAmJiBzdyA8PSBTV19NQVgpIHsKKyAgICAgICAgdWludDhfdCBzd19iaXRtYXNrWyhTV19NQVgrMSkvOF07CisgICAgICAgIG1lbXNldChzd19iaXRtYXNrLCAwLCBzaXplb2Yoc3dfYml0bWFzaykpOworICAgICAgICBpZiAoaW9jdGwobUZEc1tpZF90b19pbmRleChkZXZpY2UtPmlkKV0uZmQsCisgICAgICAgICAgICAgICAgICAgRVZJT0NHU1coc2l6ZW9mKHN3X2JpdG1hc2spKSwgc3dfYml0bWFzaykgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRlc3RfYml0KHN3LCBzd19iaXRtYXNrKSA/IDEgOiAwOworICAgICAgICB9CisgICAgfQorI2VuZGlmCisgICAgCisgICAgcmV0dXJuIC0xOworfQorCitpbnQgRXZlbnRIdWI6OmdldFNjYW5jb2RlU3RhdGUoaW50IGNvZGUpIGNvbnN0Cit7CisgICAgcmV0dXJuIGdldFNjYW5jb2RlU3RhdGUobUZpcnN0S2V5Ym9hcmRJZCwgY29kZSk7Cit9CisKK2ludCBFdmVudEh1Yjo6Z2V0U2NhbmNvZGVTdGF0ZShpbnQzMl90IGRldmljZUlkLCBpbnQgY29kZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIGRldmljZV90KiBkZXZpY2UgPSBnZXREZXZpY2UoZGV2aWNlSWQpOworICAgIGlmIChkZXZpY2UgPT0gTlVMTCkgcmV0dXJuIC0xOworICAgIAorICAgIGlmIChjb2RlID49IDAgJiYgY29kZSA8PSBLRVlfTUFYKSB7CisgICAgICAgIHVpbnQ4X3Qga2V5X2JpdG1hc2tbKEtFWV9NQVgrMSkvOF07CisgICAgICAgIG1lbXNldChrZXlfYml0bWFzaywgMCwgc2l6ZW9mKGtleV9iaXRtYXNrKSk7CisgICAgICAgIGlmIChpb2N0bChtRkRzW2lkX3RvX2luZGV4KGRldmljZS0+aWQpXS5mZCwKKyAgICAgICAgICAgICAgICAgICBFVklPQ0dLRVkoc2l6ZW9mKGtleV9iaXRtYXNrKSksIGtleV9iaXRtYXNrKSA+PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGVzdF9iaXQoY29kZSwga2V5X2JpdG1hc2spID8gMSA6IDA7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcmV0dXJuIC0xOworfQorCitpbnQgRXZlbnRIdWI6OmdldEtleWNvZGVTdGF0ZShpbnQgY29kZSkgY29uc3QKK3sKKyAgICByZXR1cm4gZ2V0S2V5Y29kZVN0YXRlKG1GaXJzdEtleWJvYXJkSWQsIGNvZGUpOworfQorCitpbnQgRXZlbnRIdWI6OmdldEtleWNvZGVTdGF0ZShpbnQzMl90IGRldmljZUlkLCBpbnQgY29kZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIGRldmljZV90KiBkZXZpY2UgPSBnZXREZXZpY2UoZGV2aWNlSWQpOworICAgIGlmIChkZXZpY2UgPT0gTlVMTCB8fCBkZXZpY2UtPmxheW91dE1hcCA9PSBOVUxMKSByZXR1cm4gLTE7CisgICAgCisgICAgVmVjdG9yPGludDMyX3Q+IHNjYW5Db2RlczsKKyAgICBkZXZpY2UtPmxheW91dE1hcC0+ZmluZFNjYW5jb2Rlcyhjb2RlLCAmc2NhbkNvZGVzKTsKKyAgICAKKyAgICB1aW50OF90IGtleV9iaXRtYXNrWyhLRVlfTUFYKzEpLzhdOworICAgIG1lbXNldChrZXlfYml0bWFzaywgMCwgc2l6ZW9mKGtleV9iaXRtYXNrKSk7CisgICAgaWYgKGlvY3RsKG1GRHNbaWRfdG9faW5kZXgoZGV2aWNlLT5pZCldLmZkLAorICAgICAgICAgICAgICAgRVZJT0NHS0VZKHNpemVvZihrZXlfYml0bWFzaykpLCBrZXlfYml0bWFzaykgPj0gMCkgeworICAgICAgICAjaWYgMAorICAgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8PUtFWV9NQVg7IGkrKykgeworICAgICAgICAgICAgTE9HSSgiKFNjYW4gY29kZSAlZDogZG93bj0lZCkiLCBpLCB0ZXN0X2JpdChpLCBrZXlfYml0bWFzaykpOworICAgICAgICB9CisgICAgICAgICNlbmRpZgorICAgICAgICBjb25zdCBzaXplX3QgTiA9IHNjYW5Db2Rlcy5zaXplKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOICYmIGk8PUtFWV9NQVg7IGkrKykgeworICAgICAgICAgICAgaW50MzJfdCBzYyA9IHNjYW5Db2Rlcy5pdGVtQXQoaSk7CisgICAgICAgICAgICAvL0xPR0koIkNvZGUgJWQ6IGRvd249JWQiLCBzYywgdGVzdF9iaXQoc2MsIGtleV9iaXRtYXNrKSk7CisgICAgICAgICAgICBpZiAoc2MgPj0gMCAmJiBzYyA8PSBLRVlfTUFYICYmIHRlc3RfYml0KHNjLCBrZXlfYml0bWFzaykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICByZXR1cm4gMDsKK30KKworRXZlbnRIdWI6OmRldmljZV90KiBFdmVudEh1Yjo6Z2V0RGV2aWNlKGludDMyX3QgZGV2aWNlSWQpIGNvbnN0Cit7CisgICAgaWYgKGRldmljZUlkID09IDApIGRldmljZUlkID0gbUZpcnN0S2V5Ym9hcmRJZDsKKyAgICBpbnQzMl90IGlkID0gZGV2aWNlSWQgJiBJRF9NQVNLOworICAgIGlmIChpZCA+PSBtTnVtRGV2aWNlc0J5SWQgfHwgaWQgPCAwKSByZXR1cm4gTlVMTDsKKyAgICBkZXZpY2VfdCogZGV2ID0gbURldmljZXNCeUlkW2lkXS5kZXZpY2U7CisgICAgaWYgKGRldi0+aWQgPT0gZGV2aWNlSWQpIHsKKyAgICAgICAgcmV0dXJuIGRldjsKKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK2Jvb2wgRXZlbnRIdWI6OmdldEV2ZW50KGludDMyX3QqIG91dERldmljZUlkLCBpbnQzMl90KiBvdXRUeXBlLAorICAgICAgICBpbnQzMl90KiBvdXRTY2FuY29kZSwgaW50MzJfdCogb3V0S2V5Y29kZSwgdWludDMyX3QgKm91dEZsYWdzLAorICAgICAgICBpbnQzMl90KiBvdXRWYWx1ZSwgbnNlY3NfdCogb3V0V2hlbikKK3sKKyAgICAqb3V0RGV2aWNlSWQgPSAwOworICAgICpvdXRUeXBlID0gMDsKKyAgICAqb3V0U2NhbmNvZGUgPSAwOworICAgICpvdXRLZXljb2RlID0gMDsKKyAgICAqb3V0RmxhZ3MgPSAwOworICAgICpvdXRWYWx1ZSA9IDA7CisgICAgKm91dFdoZW4gPSAwOworCisgICAgc3RhdHVzX3QgZXJyOworCisgICAgZmRfc2V0IHJlYWRmZHM7CisgICAgaW50IG1heEZkID0gLTE7CisgICAgaW50IGNjOworICAgIGludCBpOworICAgIGludCByZXM7CisgICAgaW50IHBvbGxyZXM7CisgICAgc3RydWN0IGlucHV0X2V2ZW50IGlldjsKKworICAgIC8vIE5vdGUgdGhhdCB3ZSBvbmx5IGFsbG93IG9uZSBjYWxsZXIgdG8gZ2V0RXZlbnQoKSwgc28gZG9uJ3QgbmVlZAorICAgIC8vIHRvIGRvIGxvY2tpbmcgaGVyZS4uLiAgb25seSB3aGVuIGFkZGluZy9yZW1vdmluZyBkZXZpY2VzLgorICAgIAorICAgIHdoaWxlKDEpIHsKKworICAgICAgICAvLyBGaXJzdCwgcmVwb3J0IGFueSBkZXZpY2VzIHRoYXQgaGFkIGxhc3QgYmVlbiBhZGRlZC9yZW1vdmVkLgorICAgICAgICBpZiAobUNsb3NpbmdEZXZpY2VzICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGRldmljZV90KiBkZXZpY2UgPSBtQ2xvc2luZ0RldmljZXM7CisgICAgICAgICAgICBMT0dWKCJSZXBvcnRpbmcgZGV2aWNlIGNsb3NlZDogaWQ9MHgleCwgbmFtZT0lc1xuIiwKKyAgICAgICAgICAgICAgICAgZGV2aWNlLT5pZCwgZGV2aWNlLT5wYXRoLnN0cmluZygpKTsKKyAgICAgICAgICAgIG1DbG9zaW5nRGV2aWNlcyA9IGRldmljZS0+bmV4dDsKKyAgICAgICAgICAgICpvdXREZXZpY2VJZCA9IGRldmljZS0+aWQ7CisgICAgICAgICAgICBpZiAoKm91dERldmljZUlkID09IG1GaXJzdEtleWJvYXJkSWQpICpvdXREZXZpY2VJZCA9IDA7CisgICAgICAgICAgICAqb3V0VHlwZSA9IERFVklDRV9SRU1PVkVEOworICAgICAgICAgICAgZGVsZXRlIGRldmljZTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChtT3BlbmluZ0RldmljZXMgIT0gTlVMTCkgeworICAgICAgICAgICAgZGV2aWNlX3QqIGRldmljZSA9IG1PcGVuaW5nRGV2aWNlczsKKyAgICAgICAgICAgIExPR1YoIlJlcG9ydGluZyBkZXZpY2Ugb3BlbmVkOiBpZD0weCV4LCBuYW1lPSVzXG4iLAorICAgICAgICAgICAgICAgICBkZXZpY2UtPmlkLCBkZXZpY2UtPnBhdGguc3RyaW5nKCkpOworICAgICAgICAgICAgbU9wZW5pbmdEZXZpY2VzID0gZGV2aWNlLT5uZXh0OworICAgICAgICAgICAgKm91dERldmljZUlkID0gZGV2aWNlLT5pZDsKKyAgICAgICAgICAgIGlmICgqb3V0RGV2aWNlSWQgPT0gbUZpcnN0S2V5Ym9hcmRJZCkgKm91dERldmljZUlkID0gMDsKKyAgICAgICAgICAgICpvdXRUeXBlID0gREVWSUNFX0FEREVEOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICByZWxlYXNlX3dha2VfbG9jayhXQUtFX0xPQ0tfSUQpOworCisgICAgICAgIHBvbGxyZXMgPSBwb2xsKG1GRHMsIG1GRENvdW50LCAtMSk7CisKKyAgICAgICAgYWNxdWlyZV93YWtlX2xvY2soUEFSVElBTF9XQUtFX0xPQ0ssIFdBS0VfTE9DS19JRCk7CisKKyAgICAgICAgaWYgKHBvbGxyZXMgPD0gMCkgeworICAgICAgICAgICAgaWYgKGVycm5vICE9IEVJTlRSKSB7CisgICAgICAgICAgICAgICAgTE9HVygic2VsZWN0IGZhaWxlZCAoZXJybm89JWQpXG4iLCBlcnJubyk7CisgICAgICAgICAgICAgICAgdXNsZWVwKDEwMDAwMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vcHJpbnRmKCJwb2xsICVkLCByZXR1cm5lZCAlZFxuIiwgbUZEQ291bnQsIHBvbGxyZXMpOworCisgICAgICAgIC8vIG1GRHNbMF0gaXMgdXNlZCBmb3IgaW5vdGlmeSwgc28gcHJvY2VzcyByZWd1bGFyIGV2ZW50cyBzdGFydGluZyBhdCBtRkRzWzFdCisgICAgICAgIGZvcihpID0gMTsgaSA8IG1GRENvdW50OyBpKyspIHsKKyAgICAgICAgICAgIGlmKG1GRHNbaV0ucmV2ZW50cykgeworICAgICAgICAgICAgICAgIExPR1YoInJldmVudHMgZm9yICVkID0gMHglMDh4IiwgaSwgbUZEc1tpXS5yZXZlbnRzKTsKKyAgICAgICAgICAgICAgICBpZihtRkRzW2ldLnJldmVudHMgJiBQT0xMSU4pIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVhZChtRkRzW2ldLmZkLCAmaWV2LCBzaXplb2YoaWV2KSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPT0gc2l6ZW9mKGlldikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIExPR1YoIiVzIGdvdDogdDA9JWQsIHQxPSVkLCB0eXBlPSVkLCBjb2RlPSVkLCB2PSVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbURldmljZXNbaV0tPnBhdGguc3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpIGlldi50aW1lLnR2X3NlYywgKGludCkgaWV2LnRpbWUudHZfdXNlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWV2LnR5cGUsIGlldi5jb2RlLCBpZXYudmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgKm91dERldmljZUlkID0gbURldmljZXNbaV0tPmlkOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCpvdXREZXZpY2VJZCA9PSBtRmlyc3RLZXlib2FyZElkKSAqb3V0RGV2aWNlSWQgPSAwOworICAgICAgICAgICAgICAgICAgICAgICAgKm91dFR5cGUgPSBpZXYudHlwZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXRTY2FuY29kZSA9IGlldi5jb2RlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlldi50eXBlID09IEVWX0tFWSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IG1EZXZpY2VzW2ldLT5sYXlvdXRNYXAtPm1hcChpZXYuY29kZSwgb3V0S2V5Y29kZSwgb3V0RmxhZ3MpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR1YoImlldi5jb2RlPSVkIG91dEtleWNvZGU9JWQgb3V0RmxhZ3M9MHglMDh4IGVycj0lZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWV2LmNvZGUsICpvdXRLZXljb2RlLCAqb3V0RmxhZ3MsIGVycik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVyciAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvdXRLZXljb2RlID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm91dEZsYWdzID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvdXRLZXljb2RlID0gaWV2LmNvZGU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAqb3V0VmFsdWUgPSBpZXYudmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICAqb3V0V2hlbiA9IHMybnMoaWV2LnRpbWUudHZfc2VjKSArIHVzMm5zKGlldi50aW1lLnR2X3VzZWMpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzPDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0dXKCJjb3VsZCBub3QgZ2V0IGV2ZW50IChlcnJubz0lZCkiLCBlcnJubyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR0UoImNvdWxkIG5vdCBnZXQgZXZlbnQgKHdyb25nIHNpemU6ICVkKSIsIHJlcyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gcmVhZF9ub3RpZnkoKSB3aWxsIG1vZGlmeSBtRkRzIGFuZCBtRkRDb3VudCwgc28gdGhpcyBtdXN0IGJlIGRvbmUgYWZ0ZXIKKyAgICAgICAgLy8gcHJvY2Vzc2luZyBhbGwgb3RoZXIgZXZlbnRzLgorICAgICAgICBpZihtRkRzWzBdLnJldmVudHMgJiBQT0xMSU4pIHsKKyAgICAgICAgICAgIHJlYWRfbm90aWZ5KG1GRHNbMF0uZmQpOworICAgICAgICB9CisgICAgfQorfQorCisvKgorICogT3BlbiB0aGUgcGxhdGZvcm0tc3BlY2lmaWMgaW5wdXQgZGV2aWNlLgorICovCitib29sIEV2ZW50SHViOjpvcGVuUGxhdGZvcm1JbnB1dCh2b2lkKQoreworICAgIC8qCisgICAgICogT3BlbiBwbGF0Zm9ybS1zcGVjaWZpYyBpbnB1dCBkZXZpY2UocykuCisgICAgICovCisgICAgaW50IHJlczsKKworICAgIG1GRENvdW50ID0gMTsKKyAgICBtRkRzID0gKHBvbGxmZCAqKWNhbGxvYygxLCBzaXplb2YobUZEc1swXSkpOworICAgIG1EZXZpY2VzID0gKGRldmljZV90ICoqKWNhbGxvYygxLCBzaXplb2YobURldmljZXNbMF0pKTsKKyAgICBtRkRzWzBdLmV2ZW50cyA9IFBPTExJTjsKKyAgICBtRGV2aWNlc1swXSA9IE5VTEw7CisjaWZkZWYgSEFWRV9JTk9USUZZCisgICAgbUZEc1swXS5mZCA9IGlub3RpZnlfaW5pdCgpOworICAgIHJlcyA9IGlub3RpZnlfYWRkX3dhdGNoKG1GRHNbMF0uZmQsIGRldmljZV9wYXRoLCBJTl9ERUxFVEUgfCBJTl9DUkVBVEUpOworICAgIGlmKHJlcyA8IDApIHsKKyAgICAgICAgTE9HRSgiY291bGQgbm90IGFkZCB3YXRjaCBmb3IgJXMsICVzXG4iLCBkZXZpY2VfcGF0aCwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICB9CisjZWxzZQorICAgIC8qCisgICAgICogVGhlIGNvZGUgaW4gRXZlbnRIdWI6OmdldEV2ZW50IGFzc3VtZXMgdGhhdCBtRkRzWzBdIGlzIGFuIGlub3RpZnkgZmQuCisgICAgICogV2UgYWxsb2NhdGUgc3BhY2UgZm9yIGl0IGFuZCBzZXQgaXQgdG8gc29tZXRoaW5nIGludmFsaWQuCisgICAgICovCisgICAgbUZEc1swXS5mZCA9IC0xOworI2VuZGlmCisKKyAgICByZXMgPSBzY2FuX2RpcihkZXZpY2VfcGF0aCk7CisgICAgaWYocmVzIDwgMCkgeworICAgICAgICBMT0dFKCJzY2FuIGRpciBmYWlsZWQgZm9yICVzXG4iLCBkZXZpY2VfcGF0aCk7CisgICAgICAgIC8vb3Blbl9kZXZpY2UoIi9kZXYvaW5wdXQvZXZlbnQwIik7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8qCisgKiBJbnNwZWN0IHRoZSBrbm93biBkZXZpY2VzIHRvIGRldGVybWluZSB3aGV0aGVyIHBoeXNpY2FsIGtleXMgZXhpc3QgZm9yIHRoZSBnaXZlbgorICogZnJhbWV3b3JrLWRvbWFpbiBrZXkgY29kZXMuCisgKi8KK2Jvb2wgRXZlbnRIdWI6Omhhc0tleXMoc2l6ZV90IG51bUNvZGVzLCBpbnQzMl90KiBrZXlDb2RlcywgdWludDhfdCogb3V0RmxhZ3MpIHsKKyAgICBmb3IgKHNpemVfdCBjb2RlSW5kZXggPSAwOyBjb2RlSW5kZXggPCBudW1Db2RlczsgY29kZUluZGV4KyspIHsKKyAgICAgICAgb3V0RmxhZ3NbY29kZUluZGV4XSA9IDA7CisKKyAgICAgICAgLy8gY2hlY2sgZWFjaCBhdmFpbGFibGUgaGFyZHdhcmUgZGV2aWNlIGZvciBzdXBwb3J0IGZvciB0aGlzIGtleWNvZGUKKyAgICAgICAgVmVjdG9yPGludDMyX3Q+IHNjYW5Db2RlczsKKyAgICAgICAgZm9yIChpbnQgbiA9IDA7IChuIDwgbUZEQ291bnQpICYmIChvdXRGbGFnc1tjb2RlSW5kZXhdID09IDApOyBuKyspIHsKKyAgICAgICAgICAgIGlmIChtRGV2aWNlc1tuXSkgeworICAgICAgICAgICAgICAgIHN0YXR1c190IGVyciA9IG1EZXZpY2VzW25dLT5sYXlvdXRNYXAtPmZpbmRTY2FuY29kZXMoa2V5Q29kZXNbY29kZUluZGV4XSwgJnNjYW5Db2Rlcyk7CisgICAgICAgICAgICAgICAgaWYgKCFlcnIpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhlIHBvc3NpYmxlIHNjYW4gY29kZXMgaWRlbnRpZmllZCBieSB0aGUgbGF5b3V0IG1hcCBhZ2FpbnN0IHRoZQorICAgICAgICAgICAgICAgICAgICAvLyBtYXAgb2YgY29kZXMgYWN0dWFsbHkgZW1pdHRlZCBieSB0aGUgZHJpdmVyCisgICAgICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IHNjID0gMDsgc2MgPCBzY2FuQ29kZXMuc2l6ZSgpOyBzYysrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVzdF9iaXQoc2NhbkNvZGVzW3NjXSwgbURldmljZXNbbl0tPmtleUJpdG1hc2spKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0RmxhZ3NbY29kZUluZGV4XSA9IDE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbnQgRXZlbnRIdWI6Om9wZW5fZGV2aWNlKGNvbnN0IGNoYXIgKmRldmljZU5hbWUpCit7CisgICAgaW50IHZlcnNpb247CisgICAgaW50IGZkOworICAgIHN0cnVjdCBwb2xsZmQgKm5ld19tRkRzOworICAgIGRldmljZV90ICoqbmV3X2RldmljZXM7CisgICAgY2hhciAqKm5ld19kZXZpY2VfbmFtZXM7CisgICAgY2hhciBuYW1lWzgwXTsKKyAgICBjaGFyIGxvY2F0aW9uWzgwXTsKKyAgICBjaGFyIGlkc3RyWzgwXTsKKyAgICBzdHJ1Y3QgaW5wdXRfaWQgaWQ7CisKKyAgICBMT0dWKCJPcGVuaW5nIGRldmljZTogJXMiLCBkZXZpY2VOYW1lKTsKKworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgCisgICAgZmQgPSBvcGVuKGRldmljZU5hbWUsIE9fUkRXUik7CisgICAgaWYoZmQgPCAwKSB7CisgICAgICAgIExPR0UoImNvdWxkIG5vdCBvcGVuICVzLCAlc1xuIiwgZGV2aWNlTmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmKGlvY3RsKGZkLCBFVklPQ0dWRVJTSU9OLCAmdmVyc2lvbikpIHsKKyAgICAgICAgTE9HRSgiY291bGQgbm90IGdldCBkcml2ZXIgdmVyc2lvbiBmb3IgJXMsICVzXG4iLCBkZXZpY2VOYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmKGlvY3RsKGZkLCBFVklPQ0dJRCwgJmlkKSkgeworICAgICAgICBMT0dFKCJjb3VsZCBub3QgZ2V0IGRyaXZlciBpZCBmb3IgJXMsICVzXG4iLCBkZXZpY2VOYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIG5hbWVbc2l6ZW9mKG5hbWUpIC0gMV0gPSAnXDAnOworICAgIGxvY2F0aW9uW3NpemVvZihsb2NhdGlvbikgLSAxXSA9ICdcMCc7CisgICAgaWRzdHJbc2l6ZW9mKGlkc3RyKSAtIDFdID0gJ1wwJzsKKyAgICBpZihpb2N0bChmZCwgRVZJT0NHTkFNRShzaXplb2YobmFtZSkgLSAxKSwgJm5hbWUpIDwgMSkgeworICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiY291bGQgbm90IGdldCBkZXZpY2UgbmFtZSBmb3IgJXMsICVzXG4iLCBkZXZpY2VOYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICBuYW1lWzBdID0gJ1wwJzsKKyAgICB9CisgICAgaWYoaW9jdGwoZmQsIEVWSU9DR1BIWVMoc2l6ZW9mKGxvY2F0aW9uKSAtIDEpLCAmbG9jYXRpb24pIDwgMSkgeworICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiY291bGQgbm90IGdldCBsb2NhdGlvbiBmb3IgJXMsICVzXG4iLCBkZXZpY2VOYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICBsb2NhdGlvblswXSA9ICdcMCc7CisgICAgfQorICAgIGlmKGlvY3RsKGZkLCBFVklPQ0dVTklRKHNpemVvZihpZHN0cikgLSAxKSwgJmlkc3RyKSA8IDEpIHsKKyAgICAgICAgLy9mcHJpbnRmKHN0ZGVyciwgImNvdWxkIG5vdCBnZXQgaWRzdHJpbmcgZm9yICVzLCAlc1xuIiwgZGV2aWNlTmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgaWRzdHJbMF0gPSAnXDAnOworICAgIH0KKworICAgIGludCBkZXZpZCA9IDA7CisgICAgd2hpbGUgKGRldmlkIDwgbU51bURldmljZXNCeUlkKSB7CisgICAgICAgIGlmIChtRGV2aWNlc0J5SWRbZGV2aWRdLmRldmljZSA9PSBOVUxMKSB7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBkZXZpZCsrOworICAgIH0KKyAgICBpZiAoZGV2aWQgPj0gbU51bURldmljZXNCeUlkKSB7CisgICAgICAgIGRldmljZV9lbnQqIG5ld19kZXZpZHMgPSAoZGV2aWNlX2VudCopcmVhbGxvYyhtRGV2aWNlc0J5SWQsCisgICAgICAgICAgICAgICAgc2l6ZW9mKG1EZXZpY2VzQnlJZFswXSkgKiAoZGV2aWQgKyAxKSk7CisgICAgICAgIGlmIChuZXdfZGV2aWRzID09IE5VTEwpIHsKKyAgICAgICAgICAgIExPR0UoIm91dCBvZiBtZW1vcnkiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBtRGV2aWNlc0J5SWQgPSBuZXdfZGV2aWRzOworICAgICAgICBtTnVtRGV2aWNlc0J5SWQgPSBkZXZpZCsxOworICAgICAgICBtRGV2aWNlc0J5SWRbZGV2aWRdLmRldmljZSA9IE5VTEw7CisgICAgICAgIG1EZXZpY2VzQnlJZFtkZXZpZF0uc2VxID0gMDsKKyAgICB9CisKKyAgICBtRGV2aWNlc0J5SWRbZGV2aWRdLnNlcSA9IChtRGV2aWNlc0J5SWRbZGV2aWRdLnNlcSsoMTw8U0VRX1NISUZUKSkmU0VRX01BU0s7CisgICAgaWYgKG1EZXZpY2VzQnlJZFtkZXZpZF0uc2VxID09IDApIHsKKyAgICAgICAgbURldmljZXNCeUlkW2RldmlkXS5zZXEgPSAxPDxTRVFfU0hJRlQ7CisgICAgfQorCisgICAgbmV3X21GRHMgPSAocG9sbGZkKilyZWFsbG9jKG1GRHMsIHNpemVvZihtRkRzWzBdKSAqIChtRkRDb3VudCArIDEpKTsKKyAgICBuZXdfZGV2aWNlcyA9IChkZXZpY2VfdCoqKXJlYWxsb2MobURldmljZXMsIHNpemVvZihtRGV2aWNlc1swXSkgKiAobUZEQ291bnQgKyAxKSk7CisgICAgaWYgKG5ld19tRkRzID09IE5VTEwgfHwgbmV3X2RldmljZXMgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCJvdXQgb2YgbWVtb3J5Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgbUZEcyA9IG5ld19tRkRzOworICAgIG1EZXZpY2VzID0gbmV3X2RldmljZXM7CisKKyNpZiAwCisgICAgTE9HSSgiYWRkIGRldmljZSAlZDogJXNcbiIsIG1GRENvdW50LCBkZXZpY2VOYW1lKTsKKyAgICBMT0dJKCIgIGJ1czogICAgICAlMDR4XG4iCisgICAgICAgICAiICB2ZW5kb3IgICAgJTA0eFxuIgorICAgICAgICAgIiAgcHJvZHVjdCAgICUwNHhcbiIKKyAgICAgICAgICIgIHZlcnNpb24gICAlMDR4XG4iLAorICAgICAgICBpZC5idXN0eXBlLCBpZC52ZW5kb3IsIGlkLnByb2R1Y3QsIGlkLnZlcnNpb24pOworICAgIExPR0koIiAgbmFtZTogICAgIFwiJXNcIlxuIiwgbmFtZSk7CisgICAgTE9HSSgiICBsb2NhdGlvbjogXCIlc1wiXG4iCisgICAgICAgICAiICBpZDogICAgICAgXCIlc1wiXG4iLCBsb2NhdGlvbiwgaWRzdHIpOworICAgIExPR0koIiAgdmVyc2lvbjogICVkLiVkLiVkXG4iLAorICAgICAgICB2ZXJzaW9uID4+IDE2LCAodmVyc2lvbiA+PiA4KSAmIDB4ZmYsIHZlcnNpb24gJiAweGZmKTsKKyNlbmRpZgorCisgICAgZGV2aWNlX3QqIGRldmljZSA9IG5ldyBkZXZpY2VfdChkZXZpZHxtRGV2aWNlc0J5SWRbZGV2aWRdLnNlcSwgZGV2aWNlTmFtZSk7CisgICAgaWYgKGRldmljZSA9PSBOVUxMKSB7CisgICAgICAgIExPR0UoIm91dCBvZiBtZW1vcnkiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIG1GRHNbbUZEQ291bnRdLmZkID0gZmQ7CisgICAgbUZEc1ttRkRDb3VudF0uZXZlbnRzID0gUE9MTElOOworCisgICAgLy8gZmlndXJlIG91dCB0aGUga2luZHMgb2YgZXZlbnRzIHRoZSBkZXZpY2UgcmVwb3J0cworICAgIHVpbnQ4X3Qga2V5X2JpdG1hc2tbKEtFWV9NQVgrMSkvOF07CisgICAgbWVtc2V0KGtleV9iaXRtYXNrLCAwLCBzaXplb2Yoa2V5X2JpdG1hc2spKTsKKyAgICBMT0dWKCJHZXR0aW5nIGtleXMuLi4iKTsKKyAgICBpZiAoaW9jdGwoZmQsIEVWSU9DR0JJVChFVl9LRVksIHNpemVvZihrZXlfYml0bWFzaykpLCBrZXlfYml0bWFzaykgPj0gMCkgeworICAgICAgICAvL0xPR0koIk1BUFxuIik7CisgICAgICAgIC8vZm9yIChpbnQgaT0wOyBpPCgoS0VZX01BWCsxKS84KTsgaSsrKSB7CisgICAgICAgIC8vICAgIExPR0koIiVkOiAweCUwMnhcbiIsIGksIGtleV9iaXRtYXNrW2ldKTsKKyAgICAgICAgLy99CisgICAgICAgIGZvciAoaW50IGk9MDsgaTwoKEJUTl9NSVNDKzcpLzgpOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChrZXlfYml0bWFza1tpXSAhPSAwKSB7CisgICAgICAgICAgICAgICAgZGV2aWNlLT5jbGFzc2VzIHw9IENMQVNTX0tFWUJPQVJEOworICAgICAgICAgICAgICAgIC8vICdRJyBrZXkgc3VwcG9ydCA9IGNoZWFwIHRlc3Qgb2Ygd2hldGhlciB0aGlzIGlzIGFuIGFscGhhLWNhcGFibGUga2JkCisgICAgICAgICAgICAgICAgaWYgKHRlc3RfYml0KEtFWV9RLCBrZXlfYml0bWFzaykpIHsKKyAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5jbGFzc2VzIHw9IENMQVNTX0FMUEhBS0VZOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoKGRldmljZS0+Y2xhc3NlcyAmIENMQVNTX0tFWUJPQVJEKSAhPSAwKSB7CisgICAgICAgICAgICBkZXZpY2UtPmtleUJpdG1hc2sgPSBuZXcgdWludDhfdFsoS0VZX01BWCsxKS84XTsKKyAgICAgICAgICAgIGlmIChkZXZpY2UtPmtleUJpdG1hc2sgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIG1lbWNweShkZXZpY2UtPmtleUJpdG1hc2ssIGtleV9iaXRtYXNrLCBzaXplb2Yoa2V5X2JpdG1hc2spKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGVsZXRlIGRldmljZTsKKyAgICAgICAgICAgICAgICBMT0dFKCJvdXQgb2YgbWVtb3J5IGFsbG9jYXRpbmcga2V5IGJpdG1hc2siKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKHRlc3RfYml0KEJUTl9NT1VTRSwga2V5X2JpdG1hc2spKSB7CisgICAgICAgIHVpbnQ4X3QgcmVsX2JpdG1hc2tbKFJFTF9NQVgrMSkvOF07CisgICAgICAgIG1lbXNldChyZWxfYml0bWFzaywgMCwgc2l6ZW9mKHJlbF9iaXRtYXNrKSk7CisgICAgICAgIExPR1YoIkdldHRpbmcgcmVsYXRpdmUgY29udHJvbGxlcnMuLi4iKTsKKyAgICAgICAgaWYgKGlvY3RsKGZkLCBFVklPQ0dCSVQoRVZfUkVMLCBzaXplb2YocmVsX2JpdG1hc2spKSwgcmVsX2JpdG1hc2spID49IDApCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmICh0ZXN0X2JpdChSRUxfWCwgcmVsX2JpdG1hc2spICYmIHRlc3RfYml0KFJFTF9ZLCByZWxfYml0bWFzaykpIHsKKyAgICAgICAgICAgICAgICBkZXZpY2UtPmNsYXNzZXMgfD0gQ0xBU1NfVFJBQ0tCQUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGlmICh0ZXN0X2JpdChCVE5fVE9VQ0gsIGtleV9iaXRtYXNrKSkgeworICAgICAgICB1aW50OF90IGFic19iaXRtYXNrWyhBQlNfTUFYKzEpLzhdOworICAgICAgICBtZW1zZXQoYWJzX2JpdG1hc2ssIDAsIHNpemVvZihhYnNfYml0bWFzaykpOworICAgICAgICBMT0dWKCJHZXR0aW5nIGFic29sdXRlIGNvbnRyb2xsZXJzLi4uIik7CisgICAgICAgIGlmIChpb2N0bChmZCwgRVZJT0NHQklUKEVWX0FCUywgc2l6ZW9mKGFic19iaXRtYXNrKSksIGFic19iaXRtYXNrKSA+PSAwKQorICAgICAgICB7CisgICAgICAgICAgICBpZiAodGVzdF9iaXQoQUJTX1gsIGFic19iaXRtYXNrKSAmJiB0ZXN0X2JpdChBQlNfWSwgYWJzX2JpdG1hc2spKSB7CisgICAgICAgICAgICAgICAgZGV2aWNlLT5jbGFzc2VzIHw9IENMQVNTX1RPVUNIU0NSRUVOOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisjaWZkZWYgRVZfU1cKKyAgICAvLyBmaWd1cmUgb3V0IHRoZSBzd2l0Y2hlcyB0aGlzIGRldmljZSByZXBvcnRzCisgICAgdWludDhfdCBzd19iaXRtYXNrWyhTV19NQVgrMSkvOF07CisgICAgbWVtc2V0KHN3X2JpdG1hc2ssIDAsIHNpemVvZihzd19iaXRtYXNrKSk7CisgICAgaWYgKGlvY3RsKGZkLCBFVklPQ0dCSVQoRVZfU1csIHNpemVvZihzd19iaXRtYXNrKSksIHN3X2JpdG1hc2spID49IDApIHsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPEVWX1NXOyBpKyspIHsKKyAgICAgICAgICAgIC8vTE9HSSgiRGV2aWNlIDB4JXggc3cgJWQ6IGhhcz0lZCIsIGRldmljZS0+aWQsIGksIHRlc3RfYml0KGksIHN3X2JpdG1hc2spKTsKKyAgICAgICAgICAgIGlmICh0ZXN0X2JpdChpLCBzd19iaXRtYXNrKSkgeworICAgICAgICAgICAgICAgIGlmIChtU3dpdGNoZXNbaV0gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBtU3dpdGNoZXNbaV0gPSBkZXZpY2UtPmlkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyNlbmRpZgorCisgICAgTE9HSSgiTmV3IGRldmljZTogcGF0aD0lcyBuYW1lPSVzIGlkPTB4JXggKG9mIDB4JXgpIGluZGV4PSVkIGZkPSVkIGNsYXNzZXM9MHgleFxuIiwKKyAgICAgICAgIGRldmljZU5hbWUsIG5hbWUsIGRldmljZS0+aWQsIG1OdW1EZXZpY2VzQnlJZCwgbUZEQ291bnQsIGZkLCBkZXZpY2UtPmNsYXNzZXMpOworCisgICAgaWYgKChkZXZpY2UtPmNsYXNzZXMmQ0xBU1NfS0VZQk9BUkQpICE9IDApIHsKKyAgICAgICAgY2hhciBkZXZuYW1lWzEwMV07CisgICAgICAgIGNoYXIgdG1wZm5bMTAxXTsKKyAgICAgICAgY2hhciBrZXlsYXlvdXRGaWxlbmFtZVszMDBdOworCisgICAgICAgIC8vIGEgbW9yZSBkZXNjcmlwdGl2ZSBuYW1lCisgICAgICAgIGlvY3RsKG1GRHNbbUZEQ291bnRdLmZkLCBFVklPQ0dOQU1FKHNpemVvZihkZXZuYW1lKS0xKSwgZGV2bmFtZSk7CisgICAgICAgIGRldm5hbWVbc2l6ZW9mKGRldm5hbWUpLTFdID0gMDsKKyAgICAgICAgZGV2aWNlLT5uYW1lID0gZGV2bmFtZTsKKworICAgICAgICAvLyByZXBsYWNlIGFsbCB0aGUgc3BhY2VzIHdpdGggdW5kZXJzY29yZXMKKyAgICAgICAgc3RyY3B5KHRtcGZuLCBkZXZuYW1lKTsKKyAgICAgICAgZm9yIChjaGFyICpwID0gc3RyY2hyKHRtcGZuLCAnICcpOyBwICYmICpwOyBwID0gc3RyY2hyKHRtcGZuLCAnICcpKQorICAgICAgICAgICAgKnAgPSAnXyc7CisKKyAgICAgICAgLy8gZmluZCB0aGUgLmtsIGZpbGUgd2UgbmVlZCBmb3IgdGhpcyBkZXZpY2UKKyAgICAgICAgY29uc3QgY2hhciogcm9vdCA9IGdldGVudigiQU5EUk9JRF9ST09UIik7CisgICAgICAgIHNucHJpbnRmKGtleWxheW91dEZpbGVuYW1lLCBzaXplb2Yoa2V5bGF5b3V0RmlsZW5hbWUpLAorICAgICAgICAgICAgICAgICAiJXMvdXNyL2tleWxheW91dC8lcy5rbCIsIHJvb3QsIHRtcGZuKTsKKyAgICAgICAgYm9vbCBkZWZhdWx0S2V5bWFwID0gZmFsc2U7CisgICAgICAgIGlmIChhY2Nlc3Moa2V5bGF5b3V0RmlsZW5hbWUsIFJfT0spKSB7CisgICAgICAgICAgICBzbnByaW50ZihrZXlsYXlvdXRGaWxlbmFtZSwgc2l6ZW9mKGtleWxheW91dEZpbGVuYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgICIlcy91c3Iva2V5bGF5b3V0LyVzIiwgcm9vdCwgInF3ZXJ0eS5rbCIpOworICAgICAgICAgICAgZGVmYXVsdEtleW1hcCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgZGV2aWNlLT5sYXlvdXRNYXAtPmxvYWQoa2V5bGF5b3V0RmlsZW5hbWUpOworCisgICAgICAgIC8vIHRlbGwgdGhlIHdvcmxkIGFib3V0IHRoZSBkZXZuYW1lICh0aGUgZGVzY3JpcHRpdmUgbmFtZSkKKyAgICAgICAgaW50MzJfdCBwdWJsaWNJRDsKKyAgICAgICAgaWYgKCFtSGF2ZUZpcnN0S2V5Ym9hcmQgJiYgIWRlZmF1bHRLZXltYXApIHsKKyAgICAgICAgICAgIHB1YmxpY0lEID0gMDsKKyAgICAgICAgICAgIC8vIHRoZSBidWlsdC1pbiBrZXlib2FyZCBoYXMgYSB3ZWxsLWtub3duIGRldmljZSBJRCBvZiAwLAorICAgICAgICAgICAgLy8gdGhpcyBkZXZpY2UgYmV0dGVyIG5vdCBnbyBhd2F5LgorICAgICAgICAgICAgbUhhdmVGaXJzdEtleWJvYXJkID0gdHJ1ZTsKKyAgICAgICAgICAgIG1GaXJzdEtleWJvYXJkSWQgPSBkZXZpY2UtPmlkOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHVibGljSUQgPSBkZXZpY2UtPmlkOworICAgICAgICAgICAgLy8gZW5zdXJlIG1GaXJzdEtleWJvYXJkSWQgaXMgc2V0IHRvIC1zb21ldGhpbmctLgorICAgICAgICAgICAgaWYgKG1GaXJzdEtleWJvYXJkSWQgPT0gMCkgeworICAgICAgICAgICAgICAgIG1GaXJzdEtleWJvYXJkSWQgPSBkZXZpY2UtPmlkOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNoYXIgcHJvcE5hbWVbMTAwXTsKKyAgICAgICAgc3ByaW50Zihwcm9wTmFtZSwgImh3LmtleWJvYXJkcy4ldS5kZXZuYW1lIiwgcHVibGljSUQpOworICAgICAgICBwcm9wZXJ0eV9zZXQocHJvcE5hbWUsIGRldm5hbWUpOworCisgICAgICAgIExPR0koIk5ldyBrZXlib2FyZDogcHVibGljSUQ9JWQgZGV2aWNlLT5pZD0lZCBkZXZuYW1lPSclcycgcHJvcE5hbWU9JyVzJyBrZXlsYXlvdXQ9JyVzJ1xuIiwKKyAgICAgICAgICAgICAgICBwdWJsaWNJRCwgZGV2aWNlLT5pZCwgZGV2bmFtZSwgcHJvcE5hbWUsIGtleWxheW91dEZpbGVuYW1lKTsKKyAgICB9CisKKyAgICBMT0dWKCJBZGRpbmcgZGV2aWNlICVzICVwIGF0ICVkLCBpZCA9ICVkLCBjbGFzc2VzID0gMHgleFxuIiwKKyAgICAgICAgIGRldmljZU5hbWUsIGRldmljZSwgbUZEQ291bnQsIGRldmlkLCBkZXZpY2UtPmNsYXNzZXMpOworCisgICAgbURldmljZXNCeUlkW2RldmlkXS5kZXZpY2UgPSBkZXZpY2U7CisgICAgZGV2aWNlLT5uZXh0ID0gbU9wZW5pbmdEZXZpY2VzOworICAgIG1PcGVuaW5nRGV2aWNlcyA9IGRldmljZTsKKyAgICBtRGV2aWNlc1ttRkRDb3VudF0gPSBkZXZpY2U7CisKKyAgICBtRkRDb3VudCsrOworICAgIHJldHVybiAwOworfQorCitpbnQgRXZlbnRIdWI6OmNsb3NlX2RldmljZShjb25zdCBjaGFyICpkZXZpY2VOYW1lKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgCisgICAgaW50IGk7CisgICAgZm9yKGkgPSAxOyBpIDwgbUZEQ291bnQ7IGkrKykgeworICAgICAgICBpZihzdHJjbXAobURldmljZXNbaV0tPnBhdGguc3RyaW5nKCksIGRldmljZU5hbWUpID09IDApIHsKKyAgICAgICAgICAgIC8vTE9HRCgicmVtb3ZlIGRldmljZSAlZDogJXNcbiIsIGksIGRldmljZU5hbWUpOworICAgICAgICAgICAgZGV2aWNlX3QqIGRldmljZSA9IG1EZXZpY2VzW2ldOworICAgICAgICAgICAgaW50IGNvdW50ID0gbUZEQ291bnQgLSBpIC0gMTsKKyAgICAgICAgICAgIGludCBpbmRleCA9IChkZXZpY2UtPmlkJklEX01BU0spOworICAgICAgICAgICAgbURldmljZXNCeUlkW2luZGV4XS5kZXZpY2UgPSBOVUxMOworICAgICAgICAgICAgbWVtbW92ZShtRGV2aWNlcyArIGksIG1EZXZpY2VzICsgaSArIDEsIHNpemVvZihtRGV2aWNlc1swXSkgKiBjb3VudCk7CisgICAgICAgICAgICBtZW1tb3ZlKG1GRHMgKyBpLCBtRkRzICsgaSArIDEsIHNpemVvZihtRkRzWzBdKSAqIGNvdW50KTsKKworI2lmZGVmIEVWX1NXCisgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8RVZfU1c7IGorKykgeworICAgICAgICAgICAgICAgIGlmIChtU3dpdGNoZXNbal0gPT0gZGV2aWNlLT5pZCkgeworICAgICAgICAgICAgICAgICAgICBtU3dpdGNoZXNbal0gPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAgICAgCisgICAgICAgICAgICBkZXZpY2UtPm5leHQgPSBtQ2xvc2luZ0RldmljZXM7CisgICAgICAgICAgICBtQ2xvc2luZ0RldmljZXMgPSBkZXZpY2U7CisKKyAgICAgICAgICAgIG1GRENvdW50LS07CisKKyAgICAgICAgICAgIHVpbnQzMl90IHB1YmxpY0lEOworICAgICAgICAgICAgaWYgKGRldmljZS0+aWQgPT0gbUZpcnN0S2V5Ym9hcmRJZCkgeworICAgICAgICAgICAgICAgIExPR1coImJ1aWx0LWluIGtleWJvYXJkIGRldmljZSAlcyAoaWQ9JWQpIGlzIGNsb3NpbmchIHRoZSBhcHBzIHdpbGwgbm90IGxpa2UgdGhpcyIsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnBhdGguc3RyaW5nKCksIG1GaXJzdEtleWJvYXJkSWQpOworICAgICAgICAgICAgICAgIG1GaXJzdEtleWJvYXJkSWQgPSAwOworICAgICAgICAgICAgICAgIHB1YmxpY0lEID0gMDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHVibGljSUQgPSBkZXZpY2UtPmlkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gY2xlYXIgdGhlIHByb3BlcnR5CisgICAgICAgICAgICBjaGFyIHByb3BOYW1lWzEwMF07CisgICAgICAgICAgICBzcHJpbnRmKHByb3BOYW1lLCAiaHcua2V5Ym9hcmRzLiV1LmRldm5hbWUiLCBwdWJsaWNJRCk7CisgICAgICAgICAgICBwcm9wZXJ0eV9zZXQocHJvcE5hbWUsIE5VTEwpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisgICAgTE9HRSgicmVtb3RlIGRldmljZTogJXMgbm90IGZvdW5kXG4iLCBkZXZpY2VOYW1lKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK2ludCBFdmVudEh1Yjo6cmVhZF9ub3RpZnkoaW50IG5mZCkKK3sKKyNpZmRlZiBIQVZFX0lOT1RJRlkKKyAgICBpbnQgcmVzOworICAgIGNoYXIgZGV2bmFtZVtQQVRIX01BWF07CisgICAgY2hhciAqZmlsZW5hbWU7CisgICAgY2hhciBldmVudF9idWZbNTEyXTsKKyAgICBpbnQgZXZlbnRfc2l6ZTsKKyAgICBpbnQgZXZlbnRfcG9zID0gMDsKKyAgICBzdHJ1Y3QgaW5vdGlmeV9ldmVudCAqZXZlbnQ7CisKKyAgICByZXMgPSByZWFkKG5mZCwgZXZlbnRfYnVmLCBzaXplb2YoZXZlbnRfYnVmKSk7CisgICAgaWYocmVzIDwgKGludClzaXplb2YoKmV2ZW50KSkgeworICAgICAgICBpZihlcnJubyA9PSBFSU5UUikKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICBMT0dXKCJjb3VsZCBub3QgZ2V0IGV2ZW50LCAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIC8vcHJpbnRmKCJnb3QgJWQgYnl0ZXMgb2YgZXZlbnQgaW5mb3JtYXRpb25cbiIsIHJlcyk7CisKKyAgICBzdHJjcHkoZGV2bmFtZSwgZGV2aWNlX3BhdGgpOworICAgIGZpbGVuYW1lID0gZGV2bmFtZSArIHN0cmxlbihkZXZuYW1lKTsKKyAgICAqZmlsZW5hbWUrKyA9ICcvJzsKKworICAgIHdoaWxlKHJlcyA+PSAoaW50KXNpemVvZigqZXZlbnQpKSB7CisgICAgICAgIGV2ZW50ID0gKHN0cnVjdCBpbm90aWZ5X2V2ZW50ICopKGV2ZW50X2J1ZiArIGV2ZW50X3Bvcyk7CisgICAgICAgIC8vcHJpbnRmKCIlZDogJTA4eCBcIiVzXCJcbiIsIGV2ZW50LT53ZCwgZXZlbnQtPm1hc2ssIGV2ZW50LT5sZW4gPyBldmVudC0+bmFtZSA6ICIiKTsKKyAgICAgICAgaWYoZXZlbnQtPmxlbikgeworICAgICAgICAgICAgc3RyY3B5KGZpbGVuYW1lLCBldmVudC0+bmFtZSk7CisgICAgICAgICAgICBpZihldmVudC0+bWFzayAmIElOX0NSRUFURSkgeworICAgICAgICAgICAgICAgIG9wZW5fZGV2aWNlKGRldm5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgY2xvc2VfZGV2aWNlKGRldm5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGV2ZW50X3NpemUgPSBzaXplb2YoKmV2ZW50KSArIGV2ZW50LT5sZW47CisgICAgICAgIHJlcyAtPSBldmVudF9zaXplOworICAgICAgICBldmVudF9wb3MgKz0gZXZlbnRfc2l6ZTsKKyAgICB9CisjZW5kaWYKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQgRXZlbnRIdWI6OnNjYW5fZGlyKGNvbnN0IGNoYXIgKmRpcm5hbWUpCit7CisgICAgY2hhciBkZXZuYW1lW1BBVEhfTUFYXTsKKyAgICBjaGFyICpmaWxlbmFtZTsKKyAgICBESVIgKmRpcjsKKyAgICBzdHJ1Y3QgZGlyZW50ICpkZTsKKyAgICBkaXIgPSBvcGVuZGlyKGRpcm5hbWUpOworICAgIGlmKGRpciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgc3RyY3B5KGRldm5hbWUsIGRpcm5hbWUpOworICAgIGZpbGVuYW1lID0gZGV2bmFtZSArIHN0cmxlbihkZXZuYW1lKTsKKyAgICAqZmlsZW5hbWUrKyA9ICcvJzsKKyAgICB3aGlsZSgoZGUgPSByZWFkZGlyKGRpcikpKSB7CisgICAgICAgIGlmKGRlLT5kX25hbWVbMF0gPT0gJy4nICYmCisgICAgICAgICAgIChkZS0+ZF9uYW1lWzFdID09ICdcMCcgfHwKKyAgICAgICAgICAgIChkZS0+ZF9uYW1lWzFdID09ICcuJyAmJiBkZS0+ZF9uYW1lWzJdID09ICdcMCcpKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBzdHJjcHkoZmlsZW5hbWUsIGRlLT5kX25hbWUpOworICAgICAgICBvcGVuX2RldmljZShkZXZuYW1lKTsKKyAgICB9CisgICAgY2xvc2VkaXIoZGlyKTsKKyAgICByZXR1cm4gMDsKK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvdWkvRXZlbnRSZWN1cnJlbmNlLmNwcCBiL2xpYnMvdWkvRXZlbnRSZWN1cnJlbmNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDM2YjUwCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9FdmVudFJlY3VycmVuY2UuY3BwCkBAIC0wLDAgKzEsNDg0IEBACisvKgorICogIENvcHlyaWdodCAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqLworCisjaW5jbHVkZSA8cGltL0V2ZW50UmVjdXJyZW5jZS5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKyNkZWZpbmUgRkFJTF9IRVJFKCkgZG8geyBcCisgICAgICAgICAgICBwcmludGYoIlBhcnNpbmcgZmFpbGVkIGF0IGxpbmUgJWRcbiIsIF9fTElORV9fKTsgXAorICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7IFwKKyAgICAgICAgfSB3aGlsZSgwKQorCitFdmVudFJlY3VycmVuY2U6OkV2ZW50UmVjdXJyZW5jZSgpCisgICAgOmZyZXEoKGZyZXFfdCkwKSwKKyAgICAgdW50aWwoKSwKKyAgICAgY291bnQoMCksCisgICAgIGludGVydmFsKDApLAorICAgICBieXNlY29uZCgwKSwKKyAgICAgYnlzZWNvbmRDb3VudCgwKSwKKyAgICAgYnltaW51dGUoMCksCisgICAgIGJ5bWludXRlQ291bnQoMCksCisgICAgIGJ5aG91cigwKSwKKyAgICAgYnlob3VyQ291bnQoMCksCisgICAgIGJ5ZGF5KDApLAorICAgICBieWRheU51bSgwKSwKKyAgICAgYnlkYXlDb3VudCgwKSwKKyAgICAgYnltb250aGRheSgwKSwKKyAgICAgYnltb250aGRheUNvdW50KDApLAorICAgICBieXllYXJkYXkoMCksCisgICAgIGJ5eWVhcmRheUNvdW50KDApLAorICAgICBieXdlZWtubygwKSwKKyAgICAgYnl3ZWVrbm9Db3VudCgwKSwKKyAgICAgYnltb250aCgwKSwKKyAgICAgYnltb250aENvdW50KDApLAorICAgICBieXNldHBvcygwKSwKKyAgICAgYnlzZXRwb3NDb3VudCgwKSwKKyAgICAgd2tzdCgwKQoreworfQorCitFdmVudFJlY3VycmVuY2U6On5FdmVudFJlY3VycmVuY2UoKQoreworICAgIGRlbGV0ZVtdIGJ5c2Vjb25kOworICAgIGRlbGV0ZVtdIGJ5bWludXRlOworICAgIGRlbGV0ZVtdIGJ5aG91cjsKKyAgICBkZWxldGVbXSBieWRheTsKKyAgICBkZWxldGVbXSBieWRheU51bTsKKyAgICBkZWxldGVbXSBieXllYXJkYXk7CisgICAgZGVsZXRlW10gYnltb250aGRheTsKKyAgICBkZWxldGVbXSBieXdlZWtubzsKKyAgICBkZWxldGVbXSBieW1vbnRoOworICAgIGRlbGV0ZVtdIGJ5c2V0cG9zOworfQorCitlbnVtIExIUyB7CisgICAgTk9ORV9MSFMgPSAwLAorICAgIEZSRVEsCisgICAgVU5USUwsCisgICAgQ09VTlQsCisgICAgSU5URVJWQUwsCisgICAgQllTRUNPTkQsCisgICAgQllNSU5VVEUsCisgICAgQllIT1VSLAorICAgIEJZREFZLAorICAgIEJZTU9OVEhEQVksCisgICAgQllZRUFSREFZLAorICAgIEJZV0VFS05PLAorICAgIEJZTU9OVEgsCisgICAgQllTRVRQT1MsCisgICAgV0tTVAorfTsKKworc3RydWN0IExIU1Byb2MKK3sKKyAgICBjb25zdCBjaGFyMTZfdCogdGV4dDsKKyAgICBzaXplX3QgdGV4dFNpemU7CisgICAgdWludDMyX3QgdmFsdWU7Cit9OworCitjb25zdCBjaGFyMTZfdCBGUkVRX3RleHRbXSA9IHsgJ0YnLCAnUicsICdFJywgJ1EnIH07Citjb25zdCBjaGFyMTZfdCBVTlRJTF90ZXh0W10gPSB7ICdVJywgJ04nLCAnVCcsICdJJywgJ0wnIH07Citjb25zdCBjaGFyMTZfdCBDT1VOVF90ZXh0W10gPSB7ICdDJywgJ08nLCAnVScsICdOJywgJ1QnIH07Citjb25zdCBjaGFyMTZfdCBJTlRFUlZBTF90ZXh0W10gPSB7ICdJJywgJ04nLCAnVCcsICdFJywgJ1InLCAnVicsICdBJywgJ0wnfTsKK2NvbnN0IGNoYXIxNl90IEJZU0VDT05EX3RleHRbXSA9IHsgJ0InLCAnWScsICdTJywgJ0UnLCAnQycsICdPJywgJ04nLCAnRCcgfTsKK2NvbnN0IGNoYXIxNl90IEJZTUlOVVRFX3RleHRbXSA9IHsgJ0InLCAnWScsICdNJywgJ0knLCAnTicsICdVJywgJ1QnLCAnRScgfTsKK2NvbnN0IGNoYXIxNl90IEJZSE9VUl90ZXh0W10gPSB7ICdCJywgJ1knLCAnSCcsICdPJywgJ1UnLCAnUicgfTsKK2NvbnN0IGNoYXIxNl90IEJZREFZX3RleHRbXSA9IHsgJ0InLCAnWScsICdEJywgJ0EnLCAnWScgfTsKK2NvbnN0IGNoYXIxNl90IEJZTU9OVEhEQVlfdGV4dFtdID0geyAnQicsJ1knLCdNJywnTycsJ04nLCdUJywnSCcsJ0QnLCdBJywnWScgfTsKK2NvbnN0IGNoYXIxNl90IEJZWUVBUkRBWV90ZXh0W10gPSB7ICdCJywnWScsJ1knLCdFJywnQScsJ1InLCdEJywnQScsJ1knIH07Citjb25zdCBjaGFyMTZfdCBCWVdFRUtOT190ZXh0W10gPSB7ICdCJywgJ1knLCAnVycsICdFJywgJ0UnLCAnSycsICdOJywgJ08nIH07Citjb25zdCBjaGFyMTZfdCBCWU1PTlRIX3RleHRbXSA9IHsgJ0InLCAnWScsICdNJywgJ08nLCAnTicsICdUJywgJ0gnIH07Citjb25zdCBjaGFyMTZfdCBCWVNFVFBPU190ZXh0W10gPSB7ICdCJywgJ1knLCAnUycsICdFJywgJ1QnLCAnUCcsICdPJywgJ1MnIH07Citjb25zdCBjaGFyMTZfdCBXS1NUX3RleHRbXSA9IHsgJ1cnLCAnSycsICdTJywgJ1QnIH07CisKKyNkZWZpbmUgU0laKHgpIChzaXplb2YoeCkvc2l6ZW9mKHhbMF0pKQorCitjb25zdCBMSFNQcm9jIExIU1BST0NbXSA9IHsKKyAgICB7IEZSRVFfdGV4dCwgU0laKEZSRVFfdGV4dCksIEZSRVEgfSwKKyAgICB7IFVOVElMX3RleHQsIFNJWihVTlRJTF90ZXh0KSwgVU5USUwgfSwKKyAgICB7IENPVU5UX3RleHQsIFNJWihDT1VOVF90ZXh0KSwgQ09VTlQgfSwKKyAgICB7IElOVEVSVkFMX3RleHQsIFNJWihJTlRFUlZBTF90ZXh0KSwgSU5URVJWQUwgfSwKKyAgICB7IEJZU0VDT05EX3RleHQsIFNJWihCWVNFQ09ORF90ZXh0KSwgQllTRUNPTkQgfSwKKyAgICB7IEJZTUlOVVRFX3RleHQsIFNJWihCWU1JTlVURV90ZXh0KSwgQllNSU5VVEUgfSwKKyAgICB7IEJZSE9VUl90ZXh0LCBTSVooQllIT1VSX3RleHQpLCBCWUhPVVIgfSwKKyAgICB7IEJZREFZX3RleHQsIFNJWihCWURBWV90ZXh0KSwgQllEQVkgfSwKKyAgICB7IEJZTU9OVEhEQVlfdGV4dCwgU0laKEJZTU9OVEhEQVlfdGV4dCksIEJZTU9OVEhEQVkgfSwKKyAgICB7IEJZWUVBUkRBWV90ZXh0LCBTSVooQllZRUFSREFZX3RleHQpLCBCWVlFQVJEQVkgfSwKKyAgICB7IEJZV0VFS05PX3RleHQsIFNJWihCWVdFRUtOT190ZXh0KSwgQllXRUVLTk8gfSwKKyAgICB7IEJZTU9OVEhfdGV4dCwgU0laKEJZTU9OVEhfdGV4dCksIEJZTU9OVEggfSwKKyAgICB7IEJZU0VUUE9TX3RleHQsIFNJWihCWVNFVFBPU190ZXh0KSwgQllTRVRQT1MgfSwKKyAgICB7IFdLU1RfdGV4dCwgU0laKFdLU1RfdGV4dCksIFdLU1QgfSwKKyAgICB7IE5VTEwsIDAsIE5PTkVfTEhTIH0sCit9OworCitjb25zdCBjaGFyMTZfdCBTRUNPTkRMWV90ZXh0W10gPSB7ICdTJywnRScsJ0MnLCdPJywnTicsJ0QnLCdMJywnWScgfTsKK2NvbnN0IGNoYXIxNl90IE1JTlVURUxZX3RleHRbXSA9IHsgJ00nLCdJJywnTicsJ1UnLCdUJywnRScsJ0wnLCdZJyB9OworY29uc3QgY2hhcjE2X3QgSE9VUkxZX3RleHRbXSA9IHsgJ0gnLCdPJywnVScsJ1InLCdMJywnWScgfTsKK2NvbnN0IGNoYXIxNl90IERBSUxZX3RleHRbXSA9IHsgJ0QnLCdBJywnSScsJ0wnLCdZJyB9OworY29uc3QgY2hhcjE2X3QgV0VFS0xZX3RleHRbXSA9IHsgJ1cnLCdFJywnRScsJ0snLCdMJywnWScgfTsKK2NvbnN0IGNoYXIxNl90IE1PTlRITFlfdGV4dFtdID0geyAnTScsJ08nLCdOJywnVCcsJ0gnLCdMJywnWScgfTsKK2NvbnN0IGNoYXIxNl90IFlFQVJMWV90ZXh0W10gPSB7ICdZJywnRScsJ0EnLCdSJywnTCcsJ1knIH07CisKK3R5cGVkZWYgTEhTUHJvYyBGcmVxUHJvYzsKKworY29uc3QgRnJlcVByb2MgRlJFUVBST0NbXSA9IHsKKyAgICB7IFNFQ09ORExZX3RleHQsIFNJWihTRUNPTkRMWV90ZXh0KSwgRXZlbnRSZWN1cnJlbmNlOjpTRUNPTkRMWSB9LAorICAgIHsgTUlOVVRFTFlfdGV4dCwgU0laKE1JTlVURUxZX3RleHQpLCBFdmVudFJlY3VycmVuY2U6Ok1JTlVURUxZIH0sCisgICAgeyBIT1VSTFlfdGV4dCwgU0laKEhPVVJMWV90ZXh0KSwgRXZlbnRSZWN1cnJlbmNlOjpIT1VSTFkgfSwKKyAgICB7IERBSUxZX3RleHQsIFNJWihEQUlMWV90ZXh0KSwgRXZlbnRSZWN1cnJlbmNlOjpEQUlMWSB9LAorICAgIHsgV0VFS0xZX3RleHQsIFNJWihXRUVLTFlfdGV4dCksIEV2ZW50UmVjdXJyZW5jZTo6V0VFS0xZIH0sCisgICAgeyBNT05USExZX3RleHQsIFNJWihNT05USExZX3RleHQpLCBFdmVudFJlY3VycmVuY2U6Ok1PTlRITFkgfSwKKyAgICB7IFlFQVJMWV90ZXh0LCBTSVooWUVBUkxZX3RleHQpLCBFdmVudFJlY3VycmVuY2U6OllFQVJMWSB9LAorICAgIHsgTlVMTCwgMCwgTk9ORV9MSFMgfSwKK307CisKK2NvbnN0IGNoYXIxNl90IFNVX3RleHRbXSA9IHsgJ1MnLCdVJyB9OworY29uc3QgY2hhcjE2X3QgTU9fdGV4dFtdID0geyAnTScsJ08nIH07Citjb25zdCBjaGFyMTZfdCBUVV90ZXh0W10gPSB7ICdUJywnVScgfTsKK2NvbnN0IGNoYXIxNl90IFdFX3RleHRbXSA9IHsgJ1cnLCdFJyB9OworY29uc3QgY2hhcjE2X3QgVEhfdGV4dFtdID0geyAnVCcsJ0gnIH07Citjb25zdCBjaGFyMTZfdCBGUl90ZXh0W10gPSB7ICdGJywnUicgfTsKK2NvbnN0IGNoYXIxNl90IFNBX3RleHRbXSA9IHsgJ1MnLCdBJyB9OworCitjb25zdCBGcmVxUHJvYyBXRUVLREFZUFJPQ1tdID0geworICAgIHsgU1VfdGV4dCwgU0laKFNVX3RleHQpLCBFdmVudFJlY3VycmVuY2U6OlNVIH0sCisgICAgeyBNT190ZXh0LCBTSVooTU9fdGV4dCksIEV2ZW50UmVjdXJyZW5jZTo6TU8gfSwKKyAgICB7IFRVX3RleHQsIFNJWihUVV90ZXh0KSwgRXZlbnRSZWN1cnJlbmNlOjpUVSB9LAorICAgIHsgV0VfdGV4dCwgU0laKFdFX3RleHQpLCBFdmVudFJlY3VycmVuY2U6OldFIH0sCisgICAgeyBUSF90ZXh0LCBTSVooVEhfdGV4dCksIEV2ZW50UmVjdXJyZW5jZTo6VEggfSwKKyAgICB7IEZSX3RleHQsIFNJWihGUl90ZXh0KSwgRXZlbnRSZWN1cnJlbmNlOjpGUiB9LAorICAgIHsgU0FfdGV4dCwgU0laKFNBX3RleHQpLCBFdmVudFJlY3VycmVuY2U6OlNBIH0sCisgICAgeyBOVUxMLCAwLCBOT05FX0xIUyB9LAorfTsKKworLy8gcmV0dXJucyB0aGUgaW5kZXggaW50byBMSFNQUk9DIGZvciB0aGUgbWF0Y2ggb3IgLTEgaWYgbm90IGZvdW5kCitpbmxpbmUgc3RhdGljIGludAorbWF0Y2hfcHJvYyhjb25zdCBMSFNQcm9jKiBwLCBjb25zdCBjaGFyMTZfdCogc3RyLCBzaXplX3QgbGVuKQoreworICAgIGludCBpID0gMDsKKyAgICB3aGlsZSAocC0+dGV4dCAhPSBOVUxMKSB7CisgICAgICAgIGlmIChwLT50ZXh0U2l6ZSA9PSBsZW4pIHsKKyAgICAgICAgICAgIGlmICgwID09IG1lbWNtcChwLT50ZXh0LCBzdHIsIGxlbipzaXplb2YoY2hhcjE2X3QpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHArKzsKKyAgICAgICAgaSsrOworICAgIH0KKyAgICByZXR1cm4gLTE7Cit9CisKKy8vIHJhbmdlTWluIGFuZCByYW5nZU1heCBhcmUgaW5jbHVzaXZlCitzdGF0aWMgc3RhdHVzX3QKK3BhcnNlX2ludChjb25zdCBjaGFyMTZfdCogc3RyLCBzaXplX3QgbGVuLCBpbnQqIG91dCwKKyAgICAgICAgICAgIGludCByYW5nZU1pbiwgaW50IHJhbmdlTWF4LCBib29sIHplcm9PSykKK3sKKyAgICBjaGFyMTZfdCBjOworICAgIHNpemVfdCBpPTA7CisKKyAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgRkFJTF9IRVJFKCk7CisgICAgfQorICAgIGJvb2wgbmVnYXRpdmUgPSBmYWxzZTsKKyAgICBjID0gc3RyWzBdOworICAgIGlmIChjID09ICctJyApIHsKKyAgICAgICAgbmVnYXRpdmUgPSB0cnVlOworICAgICAgICBpKys7CisgICAgfQorICAgIGVsc2UgaWYgKGMgPT0gJysnKSB7CisgICAgICAgIGkrKzsKKyAgICB9CisgICAgaW50IG4gPSAwOworICAgIGZvciAoOyBpPGxlbjsgaSsrKSB7CisgICAgICAgIGMgPSBzdHJbaV07CisgICAgICAgIGlmIChjIDwgJzAnIHx8IGMgPiAnOScpIHsKKyAgICAgICAgICAgIEZBSUxfSEVSRSgpOworICAgICAgICB9CisgICAgICAgIGludCBwcmV2ID0gbjsKKyAgICAgICAgbiAqPSAxMDsKKyAgICAgICAgLy8gdGhlIHNwZWMgZG9lc24ndCBhZGRyZXNzIGhvdyBiaWcgdGhlc2UgbnVtYmVycyBjYW4gYmUsCisgICAgICAgIC8vIHNvIHdlJ3JlIG5vdCBnb2luZyB0byB3b3JyeSBhYm91dCBub3QgYmVpbmcgYWJsZSB0byByZXByZXNlbnQKKyAgICAgICAgLy8gSU5UX01JTiwgYW5kIGlmIHdlJ3JlIGdvaW5nIHRvIHdyYXAsIHdlJ2xsIGp1c3QgY2xhbXAgdG8KKyAgICAgICAgLy8gSU5UX01BWCBpbnN0ZWFkCisgICAgICAgIGlmIChuIDwgcHJldikgeworICAgICAgICAgICAgbiA9IElOVF9NQVg7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuICs9IGMgLSAnMCc7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKG5lZ2F0aXZlKSB7CisgICAgICAgIG4gPSAtbjsKKyAgICB9CisgICAgaWYgKG4gPCByYW5nZU1pbiB8fCBuID4gcmFuZ2VNYXgpIHsKKyAgICAgICAgRkFJTF9IRVJFKCk7CisgICAgfQorICAgIGlmICghemVyb09LICYmIG4gPT0gMCkgeworICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICB9CisgICAgKm91dCA9IG47CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0aWMgc3RhdHVzX3QKK3BhcnNlX2ludF9saXN0KGNvbnN0IGNoYXIxNl90KiBzdHIsIHNpemVfdCBsZW4sIGludCogY291bnRPdXQsIGludCoqIGxpc3RPdXQsCisgICAgICAgICAgaW50IHJhbmdlTWluLCBpbnQgcmFuZ2VNYXgsIGJvb2wgemVyb09LLAorICAgICAgICAgIHN0YXR1c190ICgqZnVuYykoY29uc3QgY2hhcjE2X3QqLHNpemVfdCxpbnQqLGludCxpbnQsYm9vbCk9cGFyc2VfaW50KQoreworICAgIHN0YXR1c190IGVycjsKKworICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICAqY291bnRPdXQgPSAwOworICAgICAgICAqbGlzdE91dCA9IE5VTEw7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisKKyAgICAvLyBtYWtlIG9uZSBwYXNzIHRocm91Z2ggbG9va2luZyBmb3IgY29tbWFzIHNvIHdlIGtub3cgaG93IGJpZyB0byBtYWtlIG91cgorICAgIC8vIG91dCBhcnJheS4KKyAgICBpbnQgY291bnQgPSAxOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxsZW47IGkrKykgeworICAgICAgICBpZiAoc3RyW2ldID09ICcsJykgeworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgfQorICAgIH0KKworICAgIGludCogbGlzdCA9IG5ldyBpbnRbY291bnRdOworICAgIGNvbnN0IGNoYXIxNl90KiBwID0gc3RyOworICAgIGludCBjb21tYUluZGV4ID0gMDsKKyAgICBzaXplX3QgaTsKKworICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKSB7CisgICAgICAgIGlmIChzdHJbaV0gPT0gJywnKSB7CisgICAgICAgICAgICBlcnIgPSBmdW5jKHAsIChzdHIraS1wKSwgbGlzdCtjb21tYUluZGV4LCByYW5nZU1pbiwKKyAgICAgICAgICAgICAgICAgICAgcmFuZ2VNYXgsIHplcm9PSyk7CisgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29tbWFJbmRleCsrOworICAgICAgICAgICAgcCA9IHN0citpKzE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBlcnIgPSBmdW5jKHAsIChzdHIraS1wKSwgbGlzdCtjb21tYUluZGV4LCByYW5nZU1pbiwgcmFuZ2VNYXgsIHplcm9PSyk7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorICAgIGNvbW1hSW5kZXgrKzsKKworICAgICpjb3VudE91dCA9IGNvdW50OworICAgICpsaXN0T3V0ID0gbGlzdDsKKworICAgIHJldHVybiBOT19FUlJPUjsKKworYmFpbDoKKyAgICBkZWxldGVbXSBsaXN0OworICAgIEZBSUxfSEVSRSgpOworfQorCisvLyB0aGUgbnVtYmVycyBoZXJlIGFyZSBzbWFsbCwgc28gd2UgcGFjayB0aGVtIGJvdGggaW50byBvbmUgdmFsdWUsIGFuZCB0aGVuCisvLyBzcGxpdCBpdCBvdXQgbGF0ZXIuICBpdCBsZXRzIHVzIHJldXNlIGFsbCB0aGUgY29tbWEgc2VwYXJhdGVkIGxpc3QgY29kZS4KK3N0YXRpYyBzdGF0dXNfdAorcGFyc2VfYnlkYXkoY29uc3QgY2hhcjE2X3QqIHMsIHNpemVfdCBsZW4sIGludCogb3V0LAorICAgICAgICAgICAgaW50IHJhbmdlTWluLCBpbnQgcmFuZ2VNYXgsIGJvb2wgemVyb09LKQoreworICAgIHN0YXR1c190IGVycjsKKyAgICBpbnQgbiA9IDA7CisgICAgY29uc3QgY2hhcjE2X3QqIHAgPSBzOworICAgIHNpemVfdCBwbGVuID0gbGVuOworCisgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgY2hhcjE2X3QgYyA9IHNbMF07CisgICAgICAgIGlmIChjID09ICctJyB8fCBjID09ICcrJyB8fCAoYyA+PSAnMCcgJiYgYyA8PSAnOScpKSB7CisgICAgICAgICAgICBpZiAobGVuID4gMSkgeworICAgICAgICAgICAgICAgIHNpemVfdCBubGVuID0gMDsKKyAgICAgICAgICAgICAgICBjID0gc1tubGVuXTsKKyAgICAgICAgICAgICAgICB3aGlsZSAobmxlbiA8IGxlbgorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGMgPT0gJy0nIHx8IGMgPT0gJysnIHx8IChjID49ICcwJyAmJiBjIDw9ICc5JykpKSB7CisgICAgICAgICAgICAgICAgICAgIGMgPSBzW25sZW5dOworICAgICAgICAgICAgICAgICAgICBubGVuKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChubGVuID4gMCkgeworICAgICAgICAgICAgICAgICAgICBubGVuLS07CisgICAgICAgICAgICAgICAgICAgIGVyciA9IHBhcnNlX2ludChzLCBubGVuLCAmbiwgcmFuZ2VNaW4sIHJhbmdlTWF4LCB6ZXJvT0spOworICAgICAgICAgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwICs9IG5sZW47CisgICAgICAgICAgICAgICAgICAgIHBsZW4gLT0gbmxlbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSBtYXRjaF9wcm9jKFdFRUtEQVlQUk9DLCBwLCBwbGVuKTsKKyAgICAgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgICAgICAgICpvdXQgPSAoMHhmZmZmMDAwMCAmIFdFRUtEQVlQUk9DW2luZGV4XS52YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgfCAoMHgwMDAwZmZmZiAmIG4pOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworfQorCitzdGF0aWMgdm9pZAorcG9zdHByb2Nlc3NfYnlkYXkoaW50IGNvdW50LCBpbnQqIGJ5ZGF5LCBpbnQqKiBieWRheU51bSkKK3sKKyAgICBpbnQqIGJkbiA9IG5ldyBpbnRbY291bnRdOworICAgICpieWRheU51bSA9IGJkbjsKKyAgICBmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgeworICAgICAgICB1aW50MzJfdCB2ID0gYnlkYXlbaV07CisgICAgICAgIGludDE2X3QgbnVtID0gdiAmIDB4MDAwMGZmZmY7CisgICAgICAgIGJ5ZGF5W2ldID0gdiAmIDB4ZmZmZjAwMDA7ICAKKyAgICAgICAgLy8gd2lsbCBzaWduIGV4dGVuZDoKKyAgICAgICAgYmRuW2ldID0gbnVtOworICAgIH0KK30KKworI2RlZmluZSBQQVJTRV9JTlRfTElTVF9DSEVDS0VEKG5hbWUsIHJhbmdlTWluLCByYW5nZU1heCwgemVyb09LKSBcCisgICAgaWYgKG5hbWUjI0NvdW50ICE9IDAgfHwgTk9fRVJST1IgIT0gcGFyc2VfaW50X2xpc3Qocywgc2xlbiwgXAorICAgICAgICAgICAgICAgICAgICAgICAgICZuYW1lIyNDb3VudCwgJm5hbWUsIHJhbmdlTWluLCByYW5nZU1heCwgemVyb09LKSkgeyBcCisgICAgICAgIEZBSUxfSEVSRSgpOyBcCisgICAgfQorc3RhdHVzX3QKK0V2ZW50UmVjdXJyZW5jZTo6cGFyc2UoY29uc3QgU3RyaW5nMTYmIHN0cikKK3sKKyAgICBjaGFyMTZfdCBjb25zdCogd29yayA9IHN0ci5zdHJpbmcoKTsKKyAgICBzaXplX3QgbGVuID0gc3RyLnNpemUoKTsKKworICAgIGludCBsaHNJbmRleCA9IE5PTkVfTEhTOworICAgIGludCBpbmRleDsKKyAgICAKKyAgICBzaXplX3Qgc3RhcnQgPSAwOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxsZW47IGkrKykgeworICAgICAgICBjaGFyMTZfdCBjID0gd29ya1tpXTsKKyAgICAgICAgaWYgKGMgIT0gJzsnICYmIGkgPT0gbGVuLTEpIHsKKyAgICAgICAgICAgIGMgPSAnOyc7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMgPT0gJzsnIHx8IGMgPT0gJz0nKSB7CisgICAgICAgICAgICBpZiAoaSAhPSBzdGFydCkgeworICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzID0gd29yaytzdGFydDsKKyAgICAgICAgICAgICAgICBjb25zdCBzaXplX3Qgc2xlbiA9IGktc3RhcnQ7CisKKyAgICAgICAgICAgICAgICBTdHJpbmc4IHRoZXN0cmluZyhTdHJpbmcxNihzLCBzbGVuKSk7CisKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBjYXNlICc9JzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaHNJbmRleCA9PSBOT05FX0xIUykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxoc0luZGV4ID0gbWF0Y2hfcHJvYyhMSFNQUk9DLCBzLCBzbGVuKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGhzSW5kZXggPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnOyc6CisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoTEhTUFJPQ1tsaHNJbmRleF0udmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBGUkVROgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy0+ZnJlcSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IG1hdGNoX3Byb2MoRlJFUVBST0MsIHMsIHNsZW4pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy0+ZnJlcSA9IChmcmVxX3QpRlJFUVBST0NbaW5kZXhdLnZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVU5USUw6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhYWCBzaG91bGQgY2hlY2sgdGhhdCB0aGlzIGlzIGEgdmFsaWQgdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnRpbC5zZXRUbyhTdHJpbmcxNihzLCBzbGVuKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ09VTlQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCAhPSAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgTk9fRVJST1IgIT0gcGFyc2VfaW50KHMsIHNsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY291bnQsIElOVF9NSU4sIElOVF9NQVgsIHRydWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOVEVSVkFMOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50ZXJ2YWwgIT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IE5PX0VSUk9SICE9IHBhcnNlX2ludChzLCBzbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaW50ZXJ2YWwsIElOVF9NSU4sIElOVF9NQVgsIGZhbHNlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFJTF9IRVJFKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBCWVNFQ09ORDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFSU0VfSU5UX0xJU1RfQ0hFQ0tFRChieXNlY29uZCwgMCwgNTksIHRydWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQllNSU5VVEU6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUlNFX0lOVF9MSVNUX0NIRUNLRUQoYnltaW51dGUsIDAsIDU5LCB0cnVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJZSE9VUjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFSU0VfSU5UX0xJU1RfQ0hFQ0tFRChieWhvdXIsIDAsIDIzLCB0cnVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJZREFZOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnlkYXlDb3VudCAhPSAwIHx8IE5PX0VSUk9SICE9IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX2ludF9saXN0KHMsIHNsZW4sICZieWRheUNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZieWRheSwgLTUzLCA1MywgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VfYnlkYXkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3N0cHJvY2Vzc19ieWRheShieWRheUNvdW50LCBieWRheSwgJmJ5ZGF5TnVtKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBCWU1PTlRIREFZOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVJTRV9JTlRfTElTVF9DSEVDS0VEKGJ5bW9udGhkYXksIC0zMSwgMzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJZWUVBUkRBWToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFSU0VfSU5UX0xJU1RfQ0hFQ0tFRChieXllYXJkYXksIC0zNjYsIDM2NiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQllXRUVLTk86CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUlNFX0lOVF9MSVNUX0NIRUNLRUQoYnl3ZWVrbm8sIC01MywgNTMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJZTU9OVEg6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUlNFX0lOVF9MSVNUX0NIRUNLRUQoYnltb250aCwgMSwgMTIsIGZhbHNlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJZU0VUUE9TOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVJTRV9JTlRfTElTVF9DSEVDS0VEKGJ5c2V0cG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfTUlOLCBJTlRfTUFYLCB0cnVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFdLU1Q6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLT53a3N0ICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBSUxfSEVSRSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gbWF0Y2hfcHJvYyhXRUVLREFZUFJPQywgcywgc2xlbik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLT53a3N0ID0gKGludClXRUVLREFZUFJPQ1tpbmRleF0udmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFJTF9IRVJFKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBsaHNJbmRleCA9IE5PTkVfTEhTOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBzdGFydCA9IGkrMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGVuZm9yY2UgdGhhdCB0aGVyZSB3YXMgYSBGUkVRCisgICAgaWYgKGZyZXEgPT0gMCkgeworICAgICAgICBGQUlMX0hFUkUoKTsKKyAgICB9CisKKyAgICAvLyBkZWZhdWx0IHdrc3QgdG8gTU8gaWYgaXQgd2Fzbid0IHNwZWNpZmllZAorICAgIGlmICh3a3N0ID09IDApIHsKKyAgICAgICAgd2tzdCA9IE1POworICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisKZGlmZiAtLWdpdCBhL2xpYnMvdWkvSUNhbWVyYS5jcHAgYi9saWJzL3VpL0lDYW1lcmEuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMGZlZjEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL0lDYW1lcmEuY3BwCkBAIC0wLDAgKzEsMzQ2IEBACisvKgorKioKKyoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisvLyNkZWZpbmUgTE9HX05ERUJVRyAwCisjZGVmaW5lIExPR19UQUcgIklDYW1lcmEiCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisjaW5jbHVkZSA8dWkvSUNhbWVyYS5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2VudW0geworICAgIERJU0NPTk5FQ1QgPSBJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OLAorICAgIFNFVF9QUkVWSUVXX0RJU1BMQVksCisgICAgU0VUX1BSRVZJRVdfQ0FMTEJBQ0tfRkxBRywKKyAgICBTVEFSVF9QUkVWSUVXLAorICAgIFNUT1BfUFJFVklFVywKKyAgICBBVVRPX0ZPQ1VTLAorICAgIFRBS0VfUElDVFVSRSwKKyAgICBTRVRfUEFSQU1FVEVSUywKKyAgICBHRVRfUEFSQU1FVEVSUywKKyAgICBDT05ORUNULAorICAgIExPQ0ssCisgICAgVU5MT0NLLAorICAgIFBSRVZJRVdfRU5BQkxFRCwKKyAgICBTVEFSVF9SRUNPUkRJTkcsCisgICAgU1RPUF9SRUNPUkRJTkcsCisgICAgUkVDT1JESU5HX0VOQUJMRUQsCisgICAgUkVMRUFTRV9SRUNPUkRJTkdfRlJBTUUsCit9OworCitjbGFzcyBCcENhbWVyYTogcHVibGljIEJwSW50ZXJmYWNlPElDYW1lcmE+Cit7CitwdWJsaWM6CisgICAgQnBDYW1lcmEoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SUNhbWVyYT4oaW1wbCkKKyAgICB7CisgICAgfQorCisgICAgLy8gZGlzY29ubmVjdCBmcm9tIGNhbWVyYSBzZXJ2aWNlCisgICAgdm9pZCBkaXNjb25uZWN0KCkKKyAgICB7CisgICAgICAgIExPR1YoImRpc2Nvbm5lY3QiKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KERJU0NPTk5FQ1QsIGRhdGEsICZyZXBseSk7CisgICAgfQorCisgICAgLy8gcGFzcyB0aGUgYnVmZmVyZWQgSVN1cmZhY2UgdG8gdGhlIGNhbWVyYSBzZXJ2aWNlCisgICAgc3RhdHVzX3Qgc2V0UHJldmlld0Rpc3BsYXkoY29uc3Qgc3A8SVN1cmZhY2U+JiBzdXJmYWNlKQorICAgIHsKKyAgICAgICAgTE9HVigic2V0UHJldmlld0Rpc3BsYXkiKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihzdXJmYWNlLT5hc0JpbmRlcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFNFVF9QUkVWSUVXX0RJU1BMQVksIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisKKyAgICAvLyBzZXQgdGhlIHByZXZpZXcgY2FsbGJhY2sgZmxhZyB0byBhZmZlY3QgaG93IHRoZSByZWNlaXZlZCBmcmFtZXMgZnJvbQorICAgIC8vIHByZXZpZXcgYXJlIGhhbmRsZWQuIFNlZSBDYW1lcmEuaCBmb3IgZGV0YWlscy4KKyAgICB2b2lkIHNldFByZXZpZXdDYWxsYmFja0ZsYWcoaW50IGZsYWcpCisgICAgeworICAgICAgICBMT0dWKCJzZXRQcmV2aWV3Q2FsbGJhY2tGbGFnKCVkKSIsIGZsYWcpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoZmxhZyk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChTRVRfUFJFVklFV19DQUxMQkFDS19GTEFHLCBkYXRhLCAmcmVwbHkpOworICAgIH0KKworICAgIC8vIHN0YXJ0IHByZXZpZXcgbW9kZSwgbXVzdCBjYWxsIHNldFByZXZpZXdEaXNwbGF5IGZpcnN0CisgICAgc3RhdHVzX3Qgc3RhcnRQcmV2aWV3KCkKKyAgICB7CisgICAgICAgIExPR1YoInN0YXJ0UHJldmlldyIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoU1RBUlRfUFJFVklFVywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRJbnQzMigpOworICAgIH0KKworICAgIC8vIHN0YXJ0IHJlY29yZGluZyBtb2RlLCBtdXN0IGNhbGwgc2V0UHJldmlld0Rpc3BsYXkgZmlyc3QKKyAgICBzdGF0dXNfdCBzdGFydFJlY29yZGluZygpCisgICAgeworICAgICAgICBMT0dWKCJzdGFydFJlY29yZGluZyIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoU1RBUlRfUkVDT1JESU5HLCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gcmVwbHkucmVhZEludDMyKCk7CisgICAgfQorCisgICAgLy8gc3RvcCBwcmV2aWV3IG1vZGUKKyAgICB2b2lkIHN0b3BQcmV2aWV3KCkKKyAgICB7CisgICAgICAgIExPR1YoInN0b3BQcmV2aWV3Iik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChTVE9QX1BSRVZJRVcsIGRhdGEsICZyZXBseSk7CisgICAgfQorCisgICAgLy8gc3RvcCByZWNvcmRpbmcgbW9kZQorICAgIHZvaWQgc3RvcFJlY29yZGluZygpCisgICAgeworICAgICAgICBMT0dWKCJzdG9wUmVjb3JkaW5nIik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChTVE9QX1JFQ09SRElORywgZGF0YSwgJnJlcGx5KTsKKyAgICB9CisKKyAgICB2b2lkIHJlbGVhc2VSZWNvcmRpbmdGcmFtZShjb25zdCBzcDxJTWVtb3J5PiYgbWVtKQorICAgIHsKKyAgICAgICAgTE9HVigicmVsZWFzZVJlY29yZGluZ0ZyYW1lIik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVTdHJvbmdCaW5kZXIobWVtLT5hc0JpbmRlcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFJFTEVBU0VfUkVDT1JESU5HX0ZSQU1FLCBkYXRhLCAmcmVwbHkpOworICAgIH0KKworICAgIC8vIGNoZWNrIHByZXZpZXcgc3RhdGUKKyAgICBib29sIHByZXZpZXdFbmFibGVkKCkKKyAgICB7CisgICAgICAgIExPR1YoInByZXZpZXdFbmFibGVkIik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChQUkVWSUVXX0VOQUJMRUQsIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisKKyAgICAvLyBjaGVjayByZWNvcmRpbmcgc3RhdGUKKyAgICBib29sIHJlY29yZGluZ0VuYWJsZWQoKQorICAgIHsKKyAgICAgICAgTE9HVigicmVjb3JkaW5nRW5hYmxlZCIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoUkVDT1JESU5HX0VOQUJMRUQsIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisKKyAgICAvLyBhdXRvIGZvY3VzCisgICAgc3RhdHVzX3QgYXV0b0ZvY3VzKCkKKyAgICB7CisgICAgICAgIExPR1YoImF1dG9Gb2N1cyIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQVVUT19GT0NVUywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgc3RhdHVzX3QgcmV0ID0gcmVwbHkucmVhZEludDMyKCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLy8gdGFrZSBhIHBpY3R1cmUgLSByZXR1cm5zIGFuIElNZW1vcnkgKHJlZi1jb3VudGVkIG1tYXApCisgICAgc3RhdHVzX3QgdGFrZVBpY3R1cmUoKQorICAgIHsKKyAgICAgICAgTE9HVigidGFrZVBpY3R1cmUiKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFRBS0VfUElDVFVSRSwgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgc3RhdHVzX3QgcmV0ID0gcmVwbHkucmVhZEludDMyKCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLy8gc2V0IHByZXZpZXcvY2FwdHVyZSBwYXJhbWV0ZXJzIC0ga2V5L3ZhbHVlIHBhaXJzCisgICAgc3RhdHVzX3Qgc2V0UGFyYW1ldGVycyhjb25zdCBTdHJpbmc4JiBwYXJhbXMpCisgICAgeworICAgICAgICBMT0dWKCJzZXRQYXJhbWV0ZXJzIik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVTdHJpbmc4KHBhcmFtcyk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChTRVRfUEFSQU1FVEVSUywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRJbnQzMigpOworICAgIH0KKworICAgIC8vIGdldCBwcmV2aWV3L2NhcHR1cmUgcGFyYW1ldGVycyAtIGtleS92YWx1ZSBwYWlycworICAgIFN0cmluZzggZ2V0UGFyYW1ldGVycygpIGNvbnN0CisgICAgeworICAgICAgICBMT0dWKCJnZXRQYXJhbWV0ZXJzIik7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElDYW1lcmE6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChHRVRfUEFSQU1FVEVSUywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRTdHJpbmc4KCk7CisgICAgfQorICAgIHZpcnR1YWwgc3RhdHVzX3QgY29ubmVjdChjb25zdCBzcDxJQ2FtZXJhQ2xpZW50PiYgY2FtZXJhQ2xpZW50KQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihjYW1lcmFDbGllbnQtPmFzQmluZGVyKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQ09OTkVDVCwgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRJbnQzMigpOworICAgIH0KKyAgICB2aXJ0dWFsIHN0YXR1c190IGxvY2soKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KExPQ0ssIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisgICAgdmlydHVhbCBzdGF0dXNfdCB1bmxvY2soKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFVOTE9DSywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRJbnQzMigpOworICAgIH0KK307CisKK0lNUExFTUVOVF9NRVRBX0lOVEVSRkFDRShDYW1lcmEsICJhbmRyb2lkLmhhcmR3YXJlLklDYW1lcmEiKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIENIRUNLX0lOVEVSRkFDRShpbnRlcmZhY2UsIGRhdGEsIHJlcGx5KSBcCisgICAgICAgIGRvIHsgaWYgKCFkYXRhLmVuZm9yY2VJbnRlcmZhY2UoaW50ZXJmYWNlOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpKSB7IFwKKyAgICAgICAgICAgIExPR1coIkNhbGwgaW5jb3JyZWN0bHkgcm91dGVkIHRvICIgI2ludGVyZmFjZSk7IFwKKyAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsgXAorICAgICAgICB9IH0gd2hpbGUgKDApCisKK3N0YXR1c190IEJuQ2FtZXJhOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3dpdGNoKGNvZGUpIHsKKyAgICAgICAgY2FzZSBESVNDT05ORUNUOiB7CisgICAgICAgICAgICBMT0dWKCJESVNDT05ORUNUIik7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgZGlzY29ubmVjdCgpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFNFVF9QUkVWSUVXX0RJU1BMQVk6IHsKKyAgICAgICAgICAgIExPR1YoIlNFVF9QUkVWSUVXX0RJU1BMQVkiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzcDxJU3VyZmFjZT4gc3VyZmFjZSA9IGludGVyZmFjZV9jYXN0PElTdXJmYWNlPihkYXRhLnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihzZXRQcmV2aWV3RGlzcGxheShzdXJmYWNlKSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgU0VUX1BSRVZJRVdfQ0FMTEJBQ0tfRkxBRzogeworICAgICAgICAgICAgTE9HVigiU0VUX1BSRVZJRVdfQ0FMTEJBQ0tfVFlQRSIpOworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmEsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIGludCBjYWxsYmFja19mbGFnID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHNldFByZXZpZXdDYWxsYmFja0ZsYWcoY2FsbGJhY2tfZmxhZyk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgU1RBUlRfUFJFVklFVzogeworICAgICAgICAgICAgTE9HVigiU1RBUlRfUFJFVklFVyIpOworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmEsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKHN0YXJ0UHJldmlldygpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBTVEFSVF9SRUNPUkRJTkc6IHsKKyAgICAgICAgICAgIExPR1YoIlNUQVJUX1JFQ09SRElORyIpOworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmEsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKHN0YXJ0UmVjb3JkaW5nKCkpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFNUT1BfUFJFVklFVzogeworICAgICAgICAgICAgTE9HVigiU1RPUF9QUkVWSUVXIik7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgc3RvcFByZXZpZXcoKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBTVE9QX1JFQ09SRElORzogeworICAgICAgICAgICAgTE9HVigiU1RPUF9SRUNPUkRJTkciKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzdG9wUmVjb3JkaW5nKCk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgUkVMRUFTRV9SRUNPUkRJTkdfRlJBTUU6IHsKKyAgICAgICAgICAgIExPR1YoIlJFTEVBU0VfUkVDT1JESU5HX0ZSQU1FIik7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgc3A8SU1lbW9yeT4gbWVtID0gaW50ZXJmYWNlX2Nhc3Q8SU1lbW9yeT4oZGF0YS5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgICAgICAgICAgcmVsZWFzZVJlY29yZGluZ0ZyYW1lKG1lbSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgUFJFVklFV19FTkFCTEVEOiB7CisgICAgICAgICAgICBMT0dWKCJQUkVWSUVXX0VOQUJMRUQiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihwcmV2aWV3RW5hYmxlZCgpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBSRUNPUkRJTkdfRU5BQkxFRDogeworICAgICAgICAgICAgTE9HVigiUkVDT1JESU5HX0VOQUJMRUQiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihyZWNvcmRpbmdFbmFibGVkKCkpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIEFVVE9fRk9DVVM6IHsKKyAgICAgICAgICAgIExPR1YoIkFVVE9fRk9DVVMiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihhdXRvRm9jdXMoKSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgVEFLRV9QSUNUVVJFOiB7CisgICAgICAgICAgICBMT0dWKCJUQUtFX1BJQ1RVUkUiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMih0YWtlUGljdHVyZSgpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBTRVRfUEFSQU1FVEVSUzogeworICAgICAgICAgICAgTE9HVigiU0VUX1BBUkFNRVRFUlMiKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBTdHJpbmc4IHBhcmFtcyhkYXRhLnJlYWRTdHJpbmc4KCkpOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoc2V0UGFyYW1ldGVycyhwYXJhbXMpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgR0VUX1BBUkFNRVRFUlM6IHsKKyAgICAgICAgICAgIExPR1YoIkdFVF9QQVJBTUVURVJTIik7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgIHJlcGx5LT53cml0ZVN0cmluZzgoZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgQ09OTkVDVDogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmEsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHNwPElDYW1lcmFDbGllbnQ+IGNhbWVyYUNsaWVudCA9IGludGVyZmFjZV9jYXN0PElDYW1lcmFDbGllbnQ+KGRhdGEucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKGNvbm5lY3QoY2FtZXJhQ2xpZW50KSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgTE9DSzogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmEsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKGxvY2soKSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgVU5MT0NLOiB7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIodW5sb2NrKCkpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJCaW5kZXI6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvbGlicy91aS9JQ2FtZXJhQ2xpZW50LmNwcCBiL2xpYnMvdWkvSUNhbWVyYUNsaWVudC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGJlYzlkMgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvSUNhbWVyYUNsaWVudC5jcHAKQEAgLTAsMCArMSwxODUgQEAKKy8qCisqKgorKiogQ29weXJpZ2h0IDIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8jZGVmaW5lIExPR19OREVCVUcgMAorI2RlZmluZSBMT0dfVEFHICJJQ2FtZXJhQ2xpZW50IgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHVpL0lDYW1lcmFDbGllbnQuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitlbnVtIHsKKyAgICBTSFVUVEVSX0NBTExCQUNLID0gSUJpbmRlcjo6RklSU1RfQ0FMTF9UUkFOU0FDVElPTiwKKyAgICBSQVdfQ0FMTEJBQ0ssCisgICAgSlBFR19DQUxMQkFDSywKKyAgICBQUkVWSUVXX0NBTExCQUNLLAorICAgIEVSUk9SX0NBTExCQUNLLAorICAgIEFVVE9GT0NVU19DQUxMQkFDSywKKyAgICBSRUNPUkRJTkdfQ0FMTEJBQ0ssCit9OworCitjbGFzcyBCcENhbWVyYUNsaWVudDogcHVibGljIEJwSW50ZXJmYWNlPElDYW1lcmFDbGllbnQ+Cit7CitwdWJsaWM6CisgICAgQnBDYW1lcmFDbGllbnQoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SUNhbWVyYUNsaWVudD4oaW1wbCkKKyAgICB7CisgICAgfQorCisgICAgLy8gY2FsbGJhY2sgdG8gbGV0IHRoZSBhcHAga25vdyB0aGUgc2h1dHRlciBoYXMgY2xvc2VkLCBpZGVhbCBmb3IgcGxheWluZyB0aGUgc2h1dHRlciBzb3VuZAorICAgIHZvaWQgc2h1dHRlckNhbGxiYWNrKCkKKyAgICB7CisgICAgICAgIExPR1YoInNodXR0ZXJDYWxsYmFjayIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoU0hVVFRFUl9DQUxMQkFDSywgZGF0YSwgJnJlcGx5LCBJQmluZGVyOjpGTEFHX09ORVdBWSk7CisgICAgfQorCisgICAgLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB0byBhcHAgd2l0aCBwaWN0dXJlIGRhdGEKKyAgICB2b2lkIHJhd0NhbGxiYWNrKGNvbnN0IHNwPElNZW1vcnk+JiBwaWN0dXJlKQorICAgIHsKKyAgICAgICAgTE9HVigicmF3Q2FsbGJhY2siKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYUNsaWVudDo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihwaWN0dXJlLT5hc0JpbmRlcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFJBV19DQUxMQkFDSywgZGF0YSwgJnJlcGx5LCBJQmluZGVyOjpGTEFHX09ORVdBWSk7CisgICAgfQorCisgICAgLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB0byBhcHAgd2l0aCBwaWN0dXJlIGRhdGEKKyAgICB2b2lkIGpwZWdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgcGljdHVyZSkKKyAgICB7CisgICAgICAgIExPR1YoImpwZWdDYWxsYmFjayIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlU3Ryb25nQmluZGVyKHBpY3R1cmUtPmFzQmluZGVyKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoSlBFR19DQUxMQkFDSywgZGF0YSwgJnJlcGx5LCBJQmluZGVyOjpGTEFHX09ORVdBWSk7CisgICAgfQorCisgICAgLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB0byBhcHAgd2l0aCBwcmV2aWV3IGZyYW1lIGRhdGEKKyAgICB2b2lkIHByZXZpZXdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgZnJhbWUpCisgICAgeworICAgICAgICBMT0dWKCJwcmV2aWV3Q2FsbGJhY2siKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYUNsaWVudDo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihmcmFtZS0+YXNCaW5kZXIoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChQUkVWSUVXX0NBTExCQUNLLCBkYXRhLCAmcmVwbHksIElCaW5kZXI6OkZMQUdfT05FV0FZKTsKKyAgICB9CisKKyAgICAvLyBjYWxsYmFjayBmcm9tIGNhbWVyYSBzZXJ2aWNlIHRvIGFwcCB3aXRoIHJlY29yZGluZyBmcmFtZSBkYXRhCisgICAgdm9pZCByZWNvcmRpbmdDYWxsYmFjayhjb25zdCBzcDxJTWVtb3J5PiYgZnJhbWUpCisgICAgeworICAgICAgICBMT0dWKCJyZWNvcmRpbmdDYWxsYmFjayIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlU3Ryb25nQmluZGVyKGZyYW1lLT5hc0JpbmRlcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFJFQ09SRElOR19DQUxMQkFDSywgZGF0YSwgJnJlcGx5LCBJQmluZGVyOjpGTEFHX09ORVdBWSk7CisgICAgfQorCisgICAgLy8gY2FsbGJhY2sgZnJvbSBjYW1lcmEgc2VydmljZSB0byBhcHAgdG8gcmVwb3J0IGVycm9yCisgICAgdm9pZCBlcnJvckNhbGxiYWNrKHN0YXR1c190IGVycm9yKQorICAgIHsKKyAgICAgICAgTE9HVigiZXJyb3JDYWxsYmFjayIpOworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoZXJyb3IpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoRVJST1JfQ0FMTEJBQ0ssIGRhdGEsICZyZXBseSwgSUJpbmRlcjo6RkxBR19PTkVXQVkpOworICAgIH0KKworICAgIC8vIGNhbGxiYWNrIGZyb20gY2FtZXJhIHNlcnZpY2UgdG8gYXBwIHRvIHJlcG9ydCBhdXRvZm9jdXMgY29tcGxldGlvbgorICAgIHZvaWQgYXV0b0ZvY3VzQ2FsbGJhY2soYm9vbCBmb2N1c2VkKQorICAgIHsKKyAgICAgICAgTE9HVigiYXV0b0ZvY3VzQ2FsbGJhY2siKTsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSUNhbWVyYUNsaWVudDo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKGZvY3VzZWQpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQVVUT0ZPQ1VTX0NBTExCQUNLLCBkYXRhLCAmcmVwbHksIElCaW5kZXI6OkZMQUdfT05FV0FZKTsKKyAgICB9Cit9OworCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoQ2FtZXJhQ2xpZW50LCAiYW5kcm9pZC5oYXJkd2FyZS5JQ2FtZXJhQ2xpZW50Iik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBDSEVDS19JTlRFUkZBQ0UoaW50ZXJmYWNlLCBkYXRhLCByZXBseSkgXAorICAgICAgICBkbyB7IGlmICghZGF0YS5lbmZvcmNlSW50ZXJmYWNlKGludGVyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKSkgeyBcCisgICAgICAgICAgICBMT0dXKCJDYWxsIGluY29ycmVjdGx5IHJvdXRlZCB0byAiICNpbnRlcmZhY2UpOyBcCisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7IFwKKyAgICAgICAgfSB9IHdoaWxlICgwKQorCitzdGF0dXNfdCBCbkNhbWVyYUNsaWVudDo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHN3aXRjaChjb2RlKSB7CisgICAgICAgIGNhc2UgU0hVVFRFUl9DQUxMQkFDSzogeworICAgICAgICAgICAgTE9HVigiU0hVVFRFUl9DQUxMQkFDSyIpOworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmFDbGllbnQsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHNodXR0ZXJDYWxsYmFjaygpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFJBV19DQUxMQkFDSzogeworICAgICAgICAgICAgTE9HVigiUkFXX0NBTExCQUNLIik7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSUNhbWVyYUNsaWVudCwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgc3A8SU1lbW9yeT4gcGljdHVyZSA9IGludGVyZmFjZV9jYXN0PElNZW1vcnk+KGRhdGEucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICAgICAgICAgIHJhd0NhbGxiYWNrKHBpY3R1cmUpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIEpQRUdfQ0FMTEJBQ0s6IHsKKyAgICAgICAgICAgIExPR1YoIkpQRUdfQ0FMTEJBQ0siKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhQ2xpZW50LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzcDxJTWVtb3J5PiBwaWN0dXJlID0gaW50ZXJmYWNlX2Nhc3Q8SU1lbW9yeT4oZGF0YS5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgICAgICAgICAganBlZ0NhbGxiYWNrKHBpY3R1cmUpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFBSRVZJRVdfQ0FMTEJBQ0s6IHsKKyAgICAgICAgICAgIExPR1YoIlBSRVZJRVdfQ0FMTEJBQ0siKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhQ2xpZW50LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzcDxJTWVtb3J5PiBmcmFtZSA9IGludGVyZmFjZV9jYXN0PElNZW1vcnk+KGRhdGEucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICAgICAgICAgIHByZXZpZXdDYWxsYmFjayhmcmFtZSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgUkVDT1JESU5HX0NBTExCQUNLOiB7CisgICAgICAgICAgICBMT0dWKCJSRUNPUkRJTkdfQ0FMTEJBQ0siKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhQ2xpZW50LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzcDxJTWVtb3J5PiBmcmFtZSA9IGludGVyZmFjZV9jYXN0PElNZW1vcnk+KGRhdGEucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICAgICAgICAgIHJlY29yZGluZ0NhbGxiYWNrKGZyYW1lKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBFUlJPUl9DQUxMQkFDSzogeworICAgICAgICAgICAgTE9HVigiRVJST1JfQ0FMTEJBQ0siKTsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJQ2FtZXJhQ2xpZW50LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzdGF0dXNfdCBlcnJvciA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBlcnJvckNhbGxiYWNrKGVycm9yKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBBVVRPRk9DVVNfQ0FMTEJBQ0s6IHsKKyAgICAgICAgICAgIExPR1YoIkFVVE9GT0NVU19DQUxMQkFDSyIpOworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmFDbGllbnQsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIGJvb2wgZm9jdXNlZCA9IChib29sKWRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBhdXRvRm9jdXNDYWxsYmFjayhmb2N1c2VkKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBCQmluZGVyOjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdWkvSUNhbWVyYVNlcnZpY2UuY3BwIGIvbGlicy91aS9JQ2FtZXJhU2VydmljZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTU2ODdmZQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvSUNhbWVyYVNlcnZpY2UuY3BwCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisqKgorKiogQ29weXJpZ2h0IDIwMDgsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKworI2luY2x1ZGUgPHVpL0lDYW1lcmFTZXJ2aWNlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgQnBDYW1lcmFTZXJ2aWNlOiBwdWJsaWMgQnBJbnRlcmZhY2U8SUNhbWVyYVNlcnZpY2U+Cit7CitwdWJsaWM6CisgICAgQnBDYW1lcmFTZXJ2aWNlKGNvbnN0IHNwPElCaW5kZXI+JiBpbXBsKQorICAgICAgICA6IEJwSW50ZXJmYWNlPElDYW1lcmFTZXJ2aWNlPihpbXBsKQorICAgIHsKKyAgICB9CisKKyAgICAvLyBjb25uZWN0IHRvIGNhbWVyYSBzZXJ2aWNlCisgICAgdmlydHVhbCBzcDxJQ2FtZXJhPiBjb25uZWN0KGNvbnN0IHNwPElDYW1lcmFDbGllbnQ+JiBjYW1lcmFDbGllbnQpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJQ2FtZXJhU2VydmljZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihjYW1lcmFDbGllbnQtPmFzQmluZGVyKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5DYW1lcmFTZXJ2aWNlOjpDT05ORUNULCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gaW50ZXJmYWNlX2Nhc3Q8SUNhbWVyYT4ocmVwbHkucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICB9Cit9OworCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoQ2FtZXJhU2VydmljZSwgImFuZHJvaWQuaGFyZHdhcmUuSUNhbWVyYVNlcnZpY2UiKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIENIRUNLX0lOVEVSRkFDRShpbnRlcmZhY2UsIGRhdGEsIHJlcGx5KSBcCisgICAgICAgIGRvIHsgaWYgKCFkYXRhLmVuZm9yY2VJbnRlcmZhY2UoaW50ZXJmYWNlOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpKSB7IFwKKyAgICAgICAgICAgIExPR1coIkNhbGwgaW5jb3JyZWN0bHkgcm91dGVkIHRvICIgI2ludGVyZmFjZSk7IFwKKyAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsgXAorICAgICAgICB9IH0gd2hpbGUgKDApCisKK3N0YXR1c190IEJuQ2FtZXJhU2VydmljZTo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHN3aXRjaChjb2RlKSB7CisgICAgICAgIGNhc2UgQ09OTkVDVDogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElDYW1lcmFTZXJ2aWNlLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzcDxJQ2FtZXJhQ2xpZW50PiBjYW1lcmFDbGllbnQgPSBpbnRlcmZhY2VfY2FzdDxJQ2FtZXJhQ2xpZW50PihkYXRhLnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgICAgICAgICBzcDxJQ2FtZXJhPiBjYW1lcmEgPSBjb25uZWN0KGNhbWVyYUNsaWVudCk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVTdHJvbmdCaW5kZXIoY2FtZXJhLT5hc0JpbmRlcigpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBCQmluZGVyOjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdWkvSU92ZXJsYXkuY3BwIGIvbGlicy91aS9JT3ZlcmxheS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmVkNDdjMgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvSU92ZXJsYXkuY3BwCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL0lJbnRlcmZhY2UuaD4KKworI2luY2x1ZGUgPHVpL0lPdmVybGF5Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworZW51bSB7CisgICAgREVTVFJPWSA9IElCaW5kZXI6OkZJUlNUX0NBTExfVFJBTlNBQ1RJT04sIC8vIG9uZS13YXkgdHJhbnNhY3Rpb24KK307CisKK2NsYXNzIEJwT3ZlcmxheSA6IHB1YmxpYyBCcEludGVyZmFjZTxJT3ZlcmxheT4KK3sKK3B1YmxpYzoKKyAgICBCcE92ZXJsYXkoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SU92ZXJsYXk+KGltcGwpCisgICAgeworICAgIH0KKworICAgIHZpcnR1YWwgdm9pZCBkZXN0cm95KCkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElPdmVybGF5OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoREVTVFJPWSwgZGF0YSwgJnJlcGx5LCBJQmluZGVyOjpGTEFHX09ORVdBWSk7CisgICAgfQorfTsKKworSU1QTEVNRU5UX01FVEFfSU5URVJGQUNFKE92ZXJsYXksICJhbmRyb2lkLnVpLklPdmVybGF5Iik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBDSEVDS19JTlRFUkZBQ0UoaW50ZXJmYWNlLCBkYXRhLCByZXBseSkgXAorICAgICAgICBkbyB7IGlmICghZGF0YS5lbmZvcmNlSW50ZXJmYWNlKGludGVyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKSkgeyBcCisgICAgICAgICAgICBMT0dXKCJDYWxsIGluY29ycmVjdGx5IHJvdXRlZCB0byAiICNpbnRlcmZhY2UpOyBcCisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7IFwKKyAgICAgICAgfSB9IHdoaWxlICgwKQorCitzdGF0dXNfdCBCbk92ZXJsYXk6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIERFU1RST1k6IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJT3ZlcmxheSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgZGVzdHJveSgpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJCaW5kZXI6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKKyAgICB9Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3VpL0lTdXJmYWNlLmNwcCBiL2xpYnMvdWkvSVN1cmZhY2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1ZTlmODEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL0lTdXJmYWNlLmNwcApAQCAtMCwwICsxLDE2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorCisjaW5jbHVkZSA8dWkvSVN1cmZhY2UuaD4KKyNpbmNsdWRlIDx1aS9PdmVybGF5Lmg+CisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitJU3VyZmFjZTo6QnVmZmVySGVhcDo6QnVmZmVySGVhcCgpIAorICAgIDogdygwKSwgaCgwKSwgaG9yX3N0cmlkZSgwKSwgdmVyX3N0cmlkZSgwKSwgZm9ybWF0KDApLAorICAgIHRyYW5zZm9ybSgwKSwgZmxhZ3MoMCkgCit7ICAgICAKK30KKworSVN1cmZhY2U6OkJ1ZmZlckhlYXA6OkJ1ZmZlckhlYXAodWludDMyX3QgdywgdWludDMyX3QgaCwKKyAgICAgICAgaW50MzJfdCBob3Jfc3RyaWRlLCBpbnQzMl90IHZlcl9zdHJpZGUsCisgICAgICAgIFBpeGVsRm9ybWF0IGZvcm1hdCwgY29uc3Qgc3A8SU1lbW9yeUhlYXA+JiBoZWFwKQorICAgIDogdyh3KSwgaChoKSwgaG9yX3N0cmlkZShob3Jfc3RyaWRlKSwgdmVyX3N0cmlkZSh2ZXJfc3RyaWRlKSwKKyAgICAgIGZvcm1hdChmb3JtYXQpLCB0cmFuc2Zvcm0oMCksIGZsYWdzKDApLCBoZWFwKGhlYXApIAoreworfQorCitJU3VyZmFjZTo6QnVmZmVySGVhcDo6QnVmZmVySGVhcCh1aW50MzJfdCB3LCB1aW50MzJfdCBoLAorICAgICAgICBpbnQzMl90IGhvcl9zdHJpZGUsIGludDMyX3QgdmVyX3N0cmlkZSwKKyAgICAgICAgUGl4ZWxGb3JtYXQgZm9ybWF0LCB1aW50MzJfdCB0cmFuc2Zvcm0sIHVpbnQzMl90IGZsYWdzLAorICAgICAgICBjb25zdCBzcDxJTWVtb3J5SGVhcD4mIGhlYXApCisgICAgICAgIDogdyh3KSwgaChoKSwgaG9yX3N0cmlkZShob3Jfc3RyaWRlKSwgdmVyX3N0cmlkZSh2ZXJfc3RyaWRlKSwKKyAgICAgICAgICBmb3JtYXQoZm9ybWF0KSwgdHJhbnNmb3JtKHRyYW5zZm9ybSksIGZsYWdzKGZsYWdzKSwgaGVhcChoZWFwKSAKK3sKK30KKworCitJU3VyZmFjZTo6QnVmZmVySGVhcDo6fkJ1ZmZlckhlYXAoKSAKK3sgICAgIAorfQorCitjbGFzcyBCcFN1cmZhY2UgOiBwdWJsaWMgQnBJbnRlcmZhY2U8SVN1cmZhY2U+Cit7CitwdWJsaWM6CisgICAgQnBTdXJmYWNlKGNvbnN0IHNwPElCaW5kZXI+JiBpbXBsKQorICAgICAgICA6IEJwSW50ZXJmYWNlPElTdXJmYWNlPihpbXBsKQorICAgIHsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHN0YXR1c190IHJlZ2lzdGVyQnVmZmVycyhjb25zdCBCdWZmZXJIZWFwJiBidWZmZXJzKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihidWZmZXJzLncpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoYnVmZmVycy5oKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKGJ1ZmZlcnMuaG9yX3N0cmlkZSk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihidWZmZXJzLnZlcl9zdHJpZGUpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoYnVmZmVycy5mb3JtYXQpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoYnVmZmVycy50cmFuc2Zvcm0pOworICAgICAgICBkYXRhLndyaXRlSW50MzIoYnVmZmVycy5mbGFncyk7CisgICAgICAgIGRhdGEud3JpdGVTdHJvbmdCaW5kZXIoYnVmZmVycy5oZWFwLT5hc0JpbmRlcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFJFR0lTVEVSX0JVRkZFUlMsIGRhdGEsICZyZXBseSk7CisgICAgICAgIHN0YXR1c190IHJlc3VsdCA9IHJlcGx5LnJlYWRJbnQzMigpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHZpcnR1YWwgdm9pZCBwb3N0QnVmZmVyKHNzaXplX3Qgb2Zmc2V0KQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihvZmZzZXQpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoUE9TVF9CVUZGRVIsIGRhdGEsICZyZXBseSwgSUJpbmRlcjo6RkxBR19PTkVXQVkpOworICAgIH0KKworICAgIHZpcnR1YWwgdm9pZCB1bnJlZ2lzdGVyQnVmZmVycygpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KFVOUkVHSVNURVJfQlVGRkVSUywgZGF0YSwgJnJlcGx5KTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHNwPE92ZXJsYXlSZWY+IGNyZWF0ZU92ZXJsYXkoCisgICAgICAgICAgICAgdWludDMyX3QgdywgdWludDMyX3QgaCwgaW50MzJfdCBmb3JtYXQpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKHcpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoaCk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihmb3JtYXQpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQ1JFQVRFX09WRVJMQVksIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiBPdmVybGF5UmVmOjpyZWFkRnJvbVBhcmNlbChyZXBseSk7CisgICAgfQorfTsKKworSU1QTEVNRU5UX01FVEFfSU5URVJGQUNFKFN1cmZhY2UsICJhbmRyb2lkLnVpLklTdXJmYWNlIik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBDSEVDS19JTlRFUkZBQ0UoaW50ZXJmYWNlLCBkYXRhLCByZXBseSkgXAorICAgICAgICBkbyB7IGlmICghZGF0YS5lbmZvcmNlSW50ZXJmYWNlKGludGVyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKSkgeyBcCisgICAgICAgICAgICBMT0dXKCJDYWxsIGluY29ycmVjdGx5IHJvdXRlZCB0byAiICNpbnRlcmZhY2UpOyBcCisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7IFwKKyAgICAgICAgfSB9IHdoaWxlICgwKQorCitzdGF0dXNfdCBCblN1cmZhY2U6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIFJFR0lTVEVSX0JVRkZFUlM6IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJU3VyZmFjZSwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgQnVmZmVySGVhcCBidWZmZXI7CisgICAgICAgICAgICBidWZmZXIudyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBidWZmZXIuaCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBidWZmZXIuaG9yX3N0cmlkZSA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBidWZmZXIudmVyX3N0cmlkZT0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIGJ1ZmZlci5mb3JtYXQgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgYnVmZmVyLnRyYW5zZm9ybSA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBidWZmZXIuZmxhZ3MgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgYnVmZmVyLmhlYXAgPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5SGVhcD4oZGF0YS5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0gcmVnaXN0ZXJCdWZmZXJzKGJ1ZmZlcik7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihlcnIpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFVOUkVHSVNURVJfQlVGRkVSUzogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElTdXJmYWNlLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICB1bnJlZ2lzdGVyQnVmZmVycygpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFBPU1RfQlVGRkVSOiB7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSVN1cmZhY2UsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHNzaXplX3Qgb2Zmc2V0ID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHBvc3RCdWZmZXIob2Zmc2V0KTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBDUkVBVEVfT1ZFUkxBWTogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElTdXJmYWNlLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBpbnQgdyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBpbnQgaCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBpbnQgZiA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBzcDxPdmVybGF5UmVmPiBvID0gY3JlYXRlT3ZlcmxheSh3LCBoLCBmKTsKKyAgICAgICAgICAgIHJldHVybiBPdmVybGF5UmVmOjp3cml0ZVRvUGFyY2VsKHJlcGx5LCBvKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBCQmluZGVyOjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgfQorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91aS9JU3VyZmFjZUNvbXBvc2VyLmNwcCBiL2xpYnMvdWkvSVN1cmZhY2VDb21wb3Nlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZlYTZmOQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvSVN1cmZhY2VDb21wb3Nlci5jcHAKQEAgLTAsMCArMSwyNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyB0YWcgYXMgc3VyZmFjZWZsaW5nZXIKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZUZsaW5nZXIiCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL0lTZXJ2aWNlTWFuYWdlci5oPgorCisjaW5jbHVkZSA8dWkvSVN1cmZhY2VDb21wb3Nlci5oPgorI2luY2x1ZGUgPHVpL0Rpc3BsYXlJbmZvLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIEJwU3VyZmFjZUNvbXBvc2VyIDogcHVibGljIEJwSW50ZXJmYWNlPElTdXJmYWNlQ29tcG9zZXI+Cit7CitwdWJsaWM6CisgICAgQnBTdXJmYWNlQ29tcG9zZXIoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SVN1cmZhY2VDb21wb3Nlcj4oaW1wbCkKKyAgICB7CisgICAgfQorCisgICAgdmlydHVhbCBzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+IGNyZWF0ZUNvbm5lY3Rpb24oKQorICAgIHsKKyAgICAgICAgdWludDMyX3QgbjsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VDb21wb3Nlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KEJuU3VyZmFjZUNvbXBvc2VyOjpDUkVBVEVfQ09OTkVDVElPTiwgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIGludGVyZmFjZV9jYXN0PElTdXJmYWNlRmxpbmdlckNsaWVudD4ocmVwbHkucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHNwPElNZW1vcnk+IGdldENibGsoKSBjb25zdAorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VDb21wb3Nlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KEJuU3VyZmFjZUNvbXBvc2VyOjpHRVRfQ0JMSywgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIGludGVyZmFjZV9jYXN0PElNZW1vcnk+KHJlcGx5LnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgfQorCisgICAgdmlydHVhbCB2b2lkIG9wZW5HbG9iYWxUcmFuc2FjdGlvbigpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZUNvbXBvc2VyOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5TdXJmYWNlQ29tcG9zZXI6Ok9QRU5fR0xPQkFMX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworICAgIH0KKworICAgIHZpcnR1YWwgdm9pZCBjbG9zZUdsb2JhbFRyYW5zYWN0aW9uKCkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTdXJmYWNlQ29tcG9zZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChCblN1cmZhY2VDb21wb3Nlcjo6Q0xPU0VfR0xPQkFMX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworICAgIH0KKworICAgIHZpcnR1YWwgc3RhdHVzX3QgZnJlZXplRGlzcGxheShEaXNwbGF5SUQgZHB5LCB1aW50MzJfdCBmbGFncykKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTdXJmYWNlQ29tcG9zZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihkcHkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoZmxhZ3MpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5TdXJmYWNlQ29tcG9zZXI6OkZSRUVaRV9ESVNQTEFZLCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gcmVwbHkucmVhZEludDMyKCk7CisgICAgfQorCisgICAgdmlydHVhbCBzdGF0dXNfdCB1bmZyZWV6ZURpc3BsYXkoRGlzcGxheUlEIGRweSwgdWludDMyX3QgZmxhZ3MpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZUNvbXBvc2VyOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoZHB5KTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKGZsYWdzKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KEJuU3VyZmFjZUNvbXBvc2VyOjpVTkZSRUVaRV9ESVNQTEFZLCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gcmVwbHkucmVhZEludDMyKCk7CisgICAgfQorCisgICAgdmlydHVhbCBpbnQgc2V0T3JpZW50YXRpb24oRGlzcGxheUlEIGRweSwgaW50IG9yaWVudGF0aW9uKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VDb21wb3Nlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKGRweSk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihvcmllbnRhdGlvbik7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChCblN1cmZhY2VDb21wb3Nlcjo6U0VUX09SSUVOVEFUSU9OLCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gcmVwbHkucmVhZEludDMyKCk7CisgICAgfQorCisgICAgdmlydHVhbCB2b2lkIGJvb3RGaW5pc2hlZCgpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZUNvbXBvc2VyOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5TdXJmYWNlQ29tcG9zZXI6OkJPT1RfRklOSVNIRUQsIGRhdGEsICZyZXBseSk7CisgICAgfQorCisgICAgdmlydHVhbCBzdGF0dXNfdCByZXF1ZXN0R1BVKAorICAgICAgICAgICAgY29uc3Qgc3A8SUdQVUNhbGxiYWNrPiYgY2FsbGJhY2ssIGdwdV9pbmZvX3QqIGdwdSkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTdXJmYWNlQ29tcG9zZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVTdHJvbmdCaW5kZXIoY2FsbGJhY2stPmFzQmluZGVyKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5TdXJmYWNlQ29tcG9zZXI6OlJFUVVFU1RfR1BVLCBkYXRhLCAmcmVwbHkpOworICAgICAgICBncHUtPnJlZ3MgPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5PihyZXBseS5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgICAgICBncHUtPmNvdW50ID0gcmVwbHkucmVhZEludDMyKCk7CisKKyAgICAgICAgLy8gRklYTUU6IGZvciBub3csIHdlIGRvbid0IGR5bmFtaWNhbGx5IGFsbG9jYXRlIHRoZSByZWdpb25zIGFycmF5CisgICAgICAgIHNpemVfdCBtYXhDb3VudCA9IHNpemVvZihncHUtPnJlZ2lvbnMpL3NpemVvZigqZ3B1LT5yZWdpb25zKTsKKyAgICAgICAgaWYgKGdwdS0+Y291bnQgPiBtYXhDb3VudCkKKyAgICAgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisKKyAgICAgICAgZm9yIChzaXplX3QgaT0wIDsgaTxncHUtPmNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICBncHUtPnJlZ2lvbnNbaV0ucmVnaW9uID0gaW50ZXJmYWNlX2Nhc3Q8SU1lbW9yeT4ocmVwbHkucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICAgICAgICAgIGdwdS0+cmVnaW9uc1tpXS5yZXNlcnZlZCA9IHJlcGx5LnJlYWRJbnQzMigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHN0YXR1c190IHJldm9rZUdQVSgpCisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU3VyZmFjZUNvbXBvc2VyOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQm5TdXJmYWNlQ29tcG9zZXI6OlJFVk9LRV9HUFUsIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHZvaWQgc2lnbmFsKCkgY29uc3QKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTdXJmYWNlQ29tcG9zZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChCblN1cmZhY2VDb21wb3Nlcjo6U0lHTkFMLCBkYXRhLCAmcmVwbHksIElCaW5kZXI6OkZMQUdfT05FV0FZKTsKKyAgICB9Cit9OworCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoU3VyZmFjZUNvbXBvc2VyLCAiYW5kcm9pZC51aS5JU3VyZmFjZUNvbXBvc2VyIik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBDSEVDS19JTlRFUkZBQ0UoaW50ZXJmYWNlLCBkYXRhLCByZXBseSkgXAorICAgICAgICBkbyB7IGlmICghZGF0YS5lbmZvcmNlSW50ZXJmYWNlKGludGVyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKSkgeyBcCisgICAgICAgICAgICBMT0dXKCJDYWxsIGluY29ycmVjdGx5IHJvdXRlZCB0byAiICNpbnRlcmZhY2UpOyBcCisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7IFwKKyAgICAgICAgfSB9IHdoaWxlICgwKQorCitzdGF0dXNfdCBCblN1cmZhY2VDb21wb3Nlcjo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHN0YXR1c190IGVyciA9IEJuSW50ZXJmYWNlPElTdXJmYWNlQ29tcG9zZXI+OjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgaWYgKGVyciA9PSBOT19FUlJPUikKKyAgICAgICAgcmV0dXJuIGVycjsKKworICAgIENIRUNLX0lOVEVSRkFDRShJU3VyZmFjZUNvbXBvc2VyLCBkYXRhLCByZXBseSk7CisKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIENSRUFURV9DT05ORUNUSU9OOiB7CisgICAgICAgICAgICBzcDxJQmluZGVyPiBiID0gY3JlYXRlQ29ubmVjdGlvbigpLT5hc0JpbmRlcigpOworICAgICAgICAgICAgcmVwbHktPndyaXRlU3Ryb25nQmluZGVyKGIpOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIE9QRU5fR0xPQkFMX1RSQU5TQUNUSU9OOiB7CisgICAgICAgICAgICBvcGVuR2xvYmFsVHJhbnNhY3Rpb24oKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBDTE9TRV9HTE9CQUxfVFJBTlNBQ1RJT046IHsKKyAgICAgICAgICAgIGNsb3NlR2xvYmFsVHJhbnNhY3Rpb24oKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBTRVRfT1JJRU5UQVRJT046IHsKKyAgICAgICAgICAgIERpc3BsYXlJRCBkcHkgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgaW50IG9yaWVudGF0aW9uID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKCBzZXRPcmllbnRhdGlvbihkcHksIG9yaWVudGF0aW9uKSApOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIEZSRUVaRV9ESVNQTEFZOiB7CisgICAgICAgICAgICBEaXNwbGF5SUQgZHB5ID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHVpbnQzMl90IGZsYWdzID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKCBmcmVlemVEaXNwbGF5KGRweSwgZmxhZ3MpICk7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgVU5GUkVFWkVfRElTUExBWTogeworICAgICAgICAgICAgRGlzcGxheUlEIGRweSA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICB1aW50MzJfdCBmbGFncyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMiggdW5mcmVlemVEaXNwbGF5KGRweSwgZmxhZ3MpICk7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgQk9PVF9GSU5JU0hFRDogeworICAgICAgICAgICAgYm9vdEZpbmlzaGVkKCk7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgUkVWT0tFX0dQVTogeworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoIHJldm9rZUdQVSgpICk7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgU0lHTkFMOiB7CisgICAgICAgICAgICBzaWduYWwoKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBHRVRfQ0JMSzogeworICAgICAgICAgICAgc3A8SUJpbmRlcj4gYiA9IGdldENibGsoKS0+YXNCaW5kZXIoKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZVN0cm9uZ0JpbmRlcihiKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBSRVFVRVNUX0dQVTogeworICAgICAgICAgICAgLy8gVE9ETzogdGhpcyBzaG91bGQgYmUgcHJvdGVjdGVkIGJ5IGEgcGVybWlzc2lvbgorICAgICAgICAgICAgZ3B1X2luZm9fdCBpbmZvOworICAgICAgICAgICAgc3A8SUdQVUNhbGxiYWNrPiBjYWxsYmFjaworICAgICAgICAgICAgICAgID0gaW50ZXJmYWNlX2Nhc3Q8SUdQVUNhbGxiYWNrPihkYXRhLnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgICAgICAgICBzdGF0dXNfdCByZXMgPSByZXF1ZXN0R1BVKGNhbGxiYWNrLCAmaW5mbyk7CisKKyAgICAgICAgICAgIC8vIEZJWE1FOiBmb3Igbm93LCB3ZSBkb24ndCBkeW5hbWljYWxseSBhbGxvY2F0ZSB0aGUgcmVnaW9ucyBhcnJheQorICAgICAgICAgICAgc2l6ZV90IG1heENvdW50ID0gc2l6ZW9mKGluZm8ucmVnaW9ucykvc2l6ZW9mKCppbmZvLnJlZ2lvbnMpOworICAgICAgICAgICAgaWYgKGluZm8uY291bnQgPiBtYXhDb3VudCkKKyAgICAgICAgICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworCisgICAgICAgICAgICByZXBseS0+d3JpdGVTdHJvbmdCaW5kZXIoaW5mby5yZWdzLT5hc0JpbmRlcigpKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKGluZm8uY291bnQpOworICAgICAgICAgICAgZm9yIChzaXplX3QgaT0wIDsgaTxpbmZvLmNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVwbHktPndyaXRlU3Ryb25nQmluZGVyKGluZm8ucmVnaW9uc1tpXS5yZWdpb24tPmFzQmluZGVyKCkpOworICAgICAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKGluZm8ucmVnaW9uc1tpXS5yZXNlcnZlZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihyZXMpOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fVFJBTlNBQ1RJT047CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitlbnVtIHsKKyAgICAvLyBOb3RlOiBCT09UX0ZJTklTSEVEIG11c3QgcmVtYWluIHRoaXMgdmFsdWUsIGl0IGlzIGNhbGxlZCBieSBBY3Rpdml0eU1hbmFnZXJTZXJ2aWNlLgorICAgIEdQVV9MT1NUID0gSUJpbmRlcjo6RklSU1RfQ0FMTF9UUkFOU0FDVElPTgorfTsKKworY2xhc3MgQnBHUFVDYWxsYmFjayA6IHB1YmxpYyBCcEludGVyZmFjZTxJR1BVQ2FsbGJhY2s+Cit7CitwdWJsaWM6CisgICAgQnBHUFVDYWxsYmFjayhjb25zdCBzcDxJQmluZGVyPiYgaW1wbCkKKyAgICAgICAgOiBCcEludGVyZmFjZTxJR1BVQ2FsbGJhY2s+KGltcGwpCisgICAgeworICAgIH0KKworICAgIHZpcnR1YWwgdm9pZCBncHVMb3N0KCkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElHUFVDYWxsYmFjazo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KEdQVV9MT1NULCBkYXRhLCAmcmVwbHksIElCaW5kZXI6OkZMQUdfT05FV0FZKTsKKyAgICB9Cit9OworCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoR1BVQ2FsbGJhY2ssICJhbmRyb2lkLnVpLklHUFVDYWxsYmFjayIpOworCitzdGF0dXNfdCBCbkdQVUNhbGxiYWNrOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3dpdGNoKGNvZGUpIHsKKyAgICAgICAgY2FzZSBHUFVfTE9TVDogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElHUFVDYWxsYmFjaywgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgZ3B1TG9zdCgpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJCaW5kZXI6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKKyAgICB9Cit9CisKK307CmRpZmYgLS1naXQgYS9saWJzL3VpL0lTdXJmYWNlRmxpbmdlckNsaWVudC5jcHAgYi9saWJzL3VpL0lTdXJmYWNlRmxpbmdlckNsaWVudC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGQ2YTc5OAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvSVN1cmZhY2VGbGluZ2VyQ2xpZW50LmNwcApAQCAtMCwwICsxLDIwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vIHRhZyBhcyBzdXJmYWNlZmxpbmdlcgorI2RlZmluZSBMT0dfVEFHICJTdXJmYWNlRmxpbmdlciIKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9QYXJjZWwuaD4KKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKworI2luY2x1ZGUgPHVpL0lTdXJmYWNlLmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2VGbGluZ2VyQ2xpZW50Lmg+CisjaW5jbHVkZSA8dWkvUG9pbnQuaD4KKyNpbmNsdWRlIDx1aS9SZWN0Lmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3VpL0xheWVyU3RhdGUuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgTElLRUxZKCBleHAgKSAgICAgICAoX19idWlsdGluX2V4cGVjdCggKGV4cCkgIT0gMCwgdHJ1ZSAgKSkKKyNkZWZpbmUgVU5MSUtFTFkoIGV4cCApICAgICAoX19idWlsdGluX2V4cGVjdCggKGV4cCkgIT0gMCwgZmFsc2UgKSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworZW51bSB7CisgICAgR0VUX0NCTEsgPSBJQmluZGVyOjpGSVJTVF9DQUxMX1RSQU5TQUNUSU9OLAorICAgIENSRUFURV9TVVJGQUNFLAorICAgIERFU1RST1lfU1VSRkFDRSwKKyAgICBTRVRfU1RBVEUKK307CisKK2NsYXNzIEJwU3VyZmFjZUZsaW5nZXJDbGllbnQgOiBwdWJsaWMgQnBJbnRlcmZhY2U8SVN1cmZhY2VGbGluZ2VyQ2xpZW50PgoreworcHVibGljOgorICAgIEJwU3VyZmFjZUZsaW5nZXJDbGllbnQoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SVN1cmZhY2VGbGluZ2VyQ2xpZW50PihpbXBsKQorICAgIHsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHZvaWQgZ2V0Q29udHJvbEJsb2NrcyhzcDxJTWVtb3J5PiogY3RsKSBjb25zdAorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoR0VUX0NCTEssIGRhdGEsICZyZXBseSk7CisgICAgICAgICpjdGwgID0gaW50ZXJmYWNlX2Nhc3Q8SU1lbW9yeT4ocmVwbHkucmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHNwPElTdXJmYWNlPiBjcmVhdGVTdXJmYWNlKCBzdXJmYWNlX2RhdGFfdCogcGFyYW1zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlzcGxheUlEIGRpc3BsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0IGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBmbGFncykKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTdXJmYWNlRmxpbmdlckNsaWVudDo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKHBpZCk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihkaXNwbGF5KTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKHcpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoaCk7CisgICAgICAgIGRhdGEud3JpdGVJbnQzMihmb3JtYXQpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoZmxhZ3MpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoQ1JFQVRFX1NVUkZBQ0UsIGRhdGEsICZyZXBseSk7CisgICAgICAgIHBhcmFtcy0+cmVhZEZyb21QYXJjZWwocmVwbHkpOworICAgICAgICByZXR1cm4gaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2U+KHJlcGx5LnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgdmlydHVhbCBzdGF0dXNfdCBkZXN0cm95U3VyZmFjZShTdXJmYWNlSUQgc2lkKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoc2lkKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KERFU1RST1lfU1VSRkFDRSwgZGF0YSwgJnJlcGx5KTsKKyAgICAgICAgcmV0dXJuIHJlcGx5LnJlYWRJbnQzMigpOworICAgIH0KKworICAgIHZpcnR1YWwgc3RhdHVzX3Qgc2V0U3RhdGUoaW50MzJfdCBjb3VudCwgY29uc3QgbGF5ZXJfc3RhdGVfdCogc3RhdGVzKQorICAgIHsKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpOworICAgICAgICBkYXRhLndyaXRlSW50MzIoY291bnQpOworICAgICAgICBmb3IgKGludCBpPTAgOyBpPGNvdW50IDsgaSsrKQorICAgICAgICAgICAgc3RhdGVzW2ldLndyaXRlKGRhdGEpOworICAgICAgICByZW1vdGUoKS0+dHJhbnNhY3QoU0VUX1NUQVRFLCBkYXRhLCAmcmVwbHkpOworICAgICAgICByZXR1cm4gcmVwbHkucmVhZEludDMyKCk7CisgICAgfQorfTsKKworSU1QTEVNRU5UX01FVEFfSU5URVJGQUNFKFN1cmZhY2VGbGluZ2VyQ2xpZW50LCAiYW5kcm9pZC51aS5JU3VyZmFjZUZsaW5nZXJDbGllbnQiKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIENIRUNLX0lOVEVSRkFDRShpbnRlcmZhY2UsIGRhdGEsIHJlcGx5KSBcCisgICAgICAgIGRvIHsgaWYgKCFkYXRhLmVuZm9yY2VJbnRlcmZhY2UoaW50ZXJmYWNlOjpnZXRJbnRlcmZhY2VEZXNjcmlwdG9yKCkpKSB7IFwKKyAgICAgICAgICAgIExPR1coIkNhbGwgaW5jb3JyZWN0bHkgcm91dGVkIHRvICIgI2ludGVyZmFjZSk7IFwKKyAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsgXAorICAgICAgICB9IH0gd2hpbGUgKDApCisKK3N0YXR1c190IEJuU3VyZmFjZUZsaW5nZXJDbGllbnQ6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICAvLyBjb2RlcyB0aGF0IGRvbid0IHJlcXVpcmUgcGVybWlzc2lvbiBjaGVjaworCisgICAgc3dpdGNoKGNvZGUpIHsKKyAgICAgICAgY2FzZSBHRVRfQ0JMSzogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElTdXJmYWNlRmxpbmdlckNsaWVudCwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgc3A8SU1lbW9yeT4gY3RsOworICAgICAgICAgICAgZ2V0Q29udHJvbEJsb2NrcygmY3RsKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZVN0cm9uZ0JpbmRlcihjdGwtPmFzQmluZGVyKCkpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgIH0KKworICAgIC8vIHRoZXNlIG11c3QgYmUgY2hlY2tlZAorICAgICAKKyAgICAgSVBDVGhyZWFkU3RhdGUqIGlwYyA9IElQQ1RocmVhZFN0YXRlOjpzZWxmKCk7CisgICAgIGNvbnN0IGludCBwaWQgPSBpcGMtPmdldENhbGxpbmdQaWQoKTsKKyAgICAgY29uc3QgaW50IHNlbGZfcGlkICAgID0gZ2V0cGlkKCk7CisgICAgIGlmIChVTkxJS0VMWShwaWQgIT0gc2VsZl9waWQpKSB7CisgICAgICAgICAvLyB3ZSdyZSBjYWxsZWQgZnJvbSBhIGRpZmZlcmVudCBwcm9jZXNzLCBkbyB0aGUgcmVhbCBjaGVjaworICAgICAgICAgaWYgKCFjaGVja0NhbGxpbmdQZXJtaXNzaW9uKAorICAgICAgICAgICAgICAgICBTdHJpbmcxNigiYW5kcm9pZC5wZXJtaXNzaW9uLkFDQ0VTU19TVVJGQUNFX0ZMSU5HRVIiKSkpCisgICAgICAgICB7CisgICAgICAgICAgICAgY29uc3QgaW50IHVpZCA9IGlwYy0+Z2V0Q2FsbGluZ1VpZCgpOworICAgICAgICAgICAgIExPR0UoIlBlcm1pc3Npb24gRGVuaWFsOiAiCisgICAgICAgICAgICAgICAgICAgICAiY2FuJ3Qgb3Blbkdsb2JhbFRyYW5zYWN0aW9uIHBpZD0lZCwgdWlkPSVkIiwgcGlkLCB1aWQpOworICAgICAgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICAgICAgIH0KKyAgICAgfQorICAgCisgICAgIHN3aXRjaChjb2RlKSB7CisgICAgICAgIGNhc2UgQ1JFQVRFX1NVUkZBQ0U6IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJU3VyZmFjZUZsaW5nZXJDbGllbnQsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIHN1cmZhY2VfZGF0YV90IHBhcmFtczsKKyAgICAgICAgICAgIGludDMyX3QgcGlkID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIERpc3BsYXlJRCBkaXNwbGF5ID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHVpbnQzMl90IHcgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgdWludDMyX3QgaCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgdWludDMyX3QgZmxhZ3MgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICAgICAgc3A8SVN1cmZhY2U+IHMgPSBjcmVhdGVTdXJmYWNlKCZwYXJhbXMsIHBpZCwgZGlzcGxheSwgdywgaCwgZm9ybWF0LCBmbGFncyk7CisgICAgICAgICAgICBwYXJhbXMud3JpdGVUb1BhcmNlbChyZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVTdHJvbmdCaW5kZXIocy0+YXNCaW5kZXIoKSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGNhc2UgREVTVFJPWV9TVVJGQUNFOiB7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSVN1cmZhY2VGbGluZ2VyQ2xpZW50LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMiggZGVzdHJveVN1cmZhY2UoIGRhdGEucmVhZEludDMyKCkgKSApOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIFNFVF9TVEFURTogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElTdXJmYWNlRmxpbmdlckNsaWVudCwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgaW50MzJfdCBjb3VudCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBsYXllcl9zdGF0ZV90KiBzdGF0ZXMgPSBuZXcgbGF5ZXJfc3RhdGVfdFtjb3VudF07CisgICAgICAgICAgICBmb3IgKGludCBpPTAgOyBpPGNvdW50IDsgaSsrKQorICAgICAgICAgICAgICAgIHN0YXRlc1tpXS5yZWFkKGRhdGEpOworICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0gc2V0U3RhdGUoY291bnQsIHN0YXRlcyk7CisgICAgICAgICAgICBkZWxldGUgW10gc3RhdGVzOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoZXJyKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBCQmluZGVyOjpvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXR1c190IElTdXJmYWNlRmxpbmdlckNsaWVudDo6c3VyZmFjZV9kYXRhX3Q6OnJlYWRGcm9tUGFyY2VsKGNvbnN0IFBhcmNlbCYgcGFyY2VsKQoreworICAgIHRva2VuID0gcGFyY2VsLnJlYWRJbnQzMigpOworICAgIGlkZW50aXR5ICA9IHBhcmNlbC5yZWFkSW50MzIoKTsKKyAgICBoZWFwWzBdID0gaW50ZXJmYWNlX2Nhc3Q8SU1lbW9yeUhlYXA+KHBhcmNlbC5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgIGhlYXBbMV0gPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5SGVhcD4ocGFyY2VsLnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBJU3VyZmFjZUZsaW5nZXJDbGllbnQ6OnN1cmZhY2VfZGF0YV90Ojp3cml0ZVRvUGFyY2VsKFBhcmNlbCogcGFyY2VsKSBjb25zdAoreworICAgIHBhcmNlbC0+d3JpdGVJbnQzMih0b2tlbik7CisgICAgcGFyY2VsLT53cml0ZUludDMyKGlkZW50aXR5KTsKKyAgICBwYXJjZWwtPndyaXRlU3Ryb25nQmluZGVyKGhlYXBbMF0hPTAgPyBoZWFwWzBdLT5hc0JpbmRlcigpIDogTlVMTCk7CisgICAgcGFyY2VsLT53cml0ZVN0cm9uZ0JpbmRlcihoZWFwWzFdIT0wID8gaGVhcFsxXS0+YXNCaW5kZXIoKSA6IE5VTEwpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvdWkvS2V5Q2hhcmFjdGVyTWFwLmNwcCBiL2xpYnMvdWkvS2V5Q2hhcmFjdGVyTWFwLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODkxMTgxCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9LZXlDaGFyYWN0ZXJNYXAuY3BwCkBAIC0wLDAgKzEsMjYzIEBACisjZGVmaW5lIExPR19UQUcgIktleUNoYXJhY3Rlck1hcCIKKworI2luY2x1ZGUgPHVpL0tleUNoYXJhY3Rlck1hcC5oPgorI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCitzdHJ1Y3QgSGVhZGVyCit7CisgICAgY2hhciBtYWdpY1s4XTsKKyAgICB1bnNpZ25lZCBpbnQgZW5kaWFuOworICAgIHVuc2lnbmVkIGludCB2ZXJzaW9uOworICAgIHVuc2lnbmVkIGludCBrZXljb3VudDsKKyAgICB1bnNpZ25lZCBjaGFyIGtiZHR5cGU7CisgICAgY2hhciBwYWRkaW5nWzExXTsKK307CisKK0tleUNoYXJhY3Rlck1hcDo6S2V5Q2hhcmFjdGVyTWFwKCkKK3sKK30KKworS2V5Q2hhcmFjdGVyTWFwOjp+S2V5Q2hhcmFjdGVyTWFwKCkKK3sKKyAgICBmcmVlKG1fa2V5cyk7Cit9CisKK3Vuc2lnbmVkIHNob3J0CitLZXlDaGFyYWN0ZXJNYXA6OmdldChpbnQga2V5Y29kZSwgaW50IG1ldGEpCit7CisgICAgS2V5KiBrID0gZmluZF9rZXkoa2V5Y29kZSk7CisgICAgaWYgKGsgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gay0+ZGF0YVttZXRhICYgTUVUQV9NQVNLXTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3Vuc2lnbmVkIHNob3J0CitLZXlDaGFyYWN0ZXJNYXA6OmdldE51bWJlcihpbnQga2V5Y29kZSkKK3sKKyAgICBLZXkqIGsgPSBmaW5kX2tleShrZXljb2RlKTsKKyAgICBpZiAoayAhPSBOVUxMKSB7CisgICAgICAgIHJldHVybiBrLT5udW1iZXI7CisgICAgfQorICAgIHJldHVybiAwOworfQorCit1bnNpZ25lZCBzaG9ydAorS2V5Q2hhcmFjdGVyTWFwOjpnZXRNYXRjaChpbnQga2V5Y29kZSwgY29uc3QgdW5zaWduZWQgc2hvcnQqIGNoYXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcnNpemUsIHVpbnQzMl90IG1vZGlmaWVycykKK3sKKyAgICBLZXkqIGsgPSBmaW5kX2tleShrZXljb2RlKTsKKyAgICBtb2RpZmllcnMgJj0gMzsgLy8gaWdub3JlIHRoZSBTWU0ga2V5IGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBrZXltYXAgZW50cmllcyBmb3IgaXQKKyAgICBpZiAoayAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IHVpbnQxNl90KiBkYXRhID0gay0+ZGF0YTsKKyAgICAgICAgZm9yIChpbnQgaj0wOyBqPGNoYXJzaXplOyBqKyspIHsKKyAgICAgICAgICAgIHVpbnQxNl90IGMgPSBjaGFyc1tqXTsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTwoTUVUQV9NQVNLICsgMSk7IGkrKykgeworICAgICAgICAgICAgICAgIGlmICgobW9kaWZpZXJzID09IDApIHx8ICgobW9kaWZpZXJzICYgaSkgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gZGF0YVtpXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3Vuc2lnbmVkIHNob3J0CitLZXlDaGFyYWN0ZXJNYXA6OmdldERpc3BsYXlMYWJlbChpbnQga2V5Y29kZSkKK3sKKyAgICBLZXkqIGsgPSBmaW5kX2tleShrZXljb2RlKTsKKyAgICBpZiAoayAhPSBOVUxMKSB7CisgICAgICAgIHJldHVybiBrLT5kaXNwbGF5X2xhYmVsOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworYm9vbAorS2V5Q2hhcmFjdGVyTWFwOjpnZXRLZXlEYXRhKGludCBrZXljb2RlLCB1bnNpZ25lZCBzaG9ydCAqZGlzcGxheUxhYmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0ICpudW1iZXIsIHVuc2lnbmVkIHNob3J0KiByZXN1bHRzKQoreworICAgIEtleSogayA9IGZpbmRfa2V5KGtleWNvZGUpOworICAgIGlmIChrICE9IE5VTEwpIHsKKyAgICAgICAgbWVtY3B5KHJlc3VsdHMsIGstPmRhdGEsIHNpemVvZihzaG9ydCkqKE1FVEFfTUFTSyArIDEpKTsKKyAgICAgICAgKm51bWJlciA9IGstPm51bWJlcjsKKyAgICAgICAgKmRpc3BsYXlMYWJlbCA9IGstPmRpc3BsYXlfbGFiZWw7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CisKK2Jvb2wKK0tleUNoYXJhY3Rlck1hcDo6ZmluZF9jaGFyKHVpbnQxNl90IGMsIHVpbnQzMl90KiBrZXksIHVpbnQzMl90KiBtb2RzKQoreworICAgIHVpbnQzMl90IE4gPSBtX2tleUNvdW50OworICAgIGZvciAoaW50IGo9MDsgajwoTUVUQV9NQVNLICsgMSk7IGorKykgeworICAgICAgICBLZXkgY29uc3QqIGtleXMgPSBtX2tleXM7CisgICAgICAgIGZvciAodWludDMyX3QgaT0wOyBpPE47IGkrKykgeworICAgICAgICAgICAgaWYgKGtleXMtPmRhdGFbal0gPT0gYykgeworICAgICAgICAgICAgICAgICprZXkgPSBrZXlzLT5rZXljb2RlOworICAgICAgICAgICAgICAgICptb2RzID0gajsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleXMrKzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wKK0tleUNoYXJhY3Rlck1hcDo6Z2V0RXZlbnRzKHVpbnQxNl90KiBjaGFycywgc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvcjxpbnQzMl90Pioga2V5cywgVmVjdG9yPHVpbnQzMl90PiogbW9kaWZpZXJzKQoreworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxsZW47IGkrKykgeworICAgICAgICB1aW50MzJfdCBrLCBtb2RzOworICAgICAgICBpZiAoZmluZF9jaGFyKGNoYXJzW2ldLCAmaywgJm1vZHMpKSB7CisgICAgICAgICAgICBrZXlzLT5hZGQoayk7CisgICAgICAgICAgICBtb2RpZmllcnMtPmFkZChtb2RzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKK30KKworS2V5Q2hhcmFjdGVyTWFwOjpLZXkqCitLZXlDaGFyYWN0ZXJNYXA6OmZpbmRfa2V5KGludCBrZXljb2RlKQoreworICAgIEtleSoga2V5cyA9IG1fa2V5czsKKyAgICBpbnQgbG93ID0gMDsKKyAgICBpbnQgaGlnaCA9IG1fa2V5Q291bnQgLSAxOworICAgIGludCBtaWQ7CisgICAgaW50IG47CisgICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7CisgICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSAvIDI7CisgICAgICAgIG4gPSBrZXlzW21pZF0ua2V5Y29kZTsKKyAgICAgICAgaWYgKGtleWNvZGUgPCBuKSB7CisgICAgICAgICAgICBoaWdoID0gbWlkIC0gMTsKKyAgICAgICAgfSBlbHNlIGlmIChrZXljb2RlID4gbikgeworICAgICAgICAgICAgbG93ID0gbWlkICsgMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBrZXlzICsgbWlkOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCitLZXlDaGFyYWN0ZXJNYXAqCitLZXlDaGFyYWN0ZXJNYXA6OmxvYWQoaW50IGlkKQoreworICAgIEtleUNoYXJhY3Rlck1hcCogcnYgPSBOVUxMOworICAgIGNoYXIgcGF0aFtQQVRIX01BWF07CisgICAgY2hhciBwcm9wTmFtZVsxMDBdOworICAgIGNoYXIgZGV2W1BST1BFUlRZX1ZBTFVFX01BWF07CisgICAgY2hhciB0bXBmbltQUk9QRVJUWV9WQUxVRV9NQVhdOworICAgIGludCBlcnI7CisgICAgY29uc3QgY2hhciogcm9vdCA9IGdldGVudigiQU5EUk9JRF9ST09UIik7CisKKyAgICBzcHJpbnRmKHByb3BOYW1lLCAiaHcua2V5Ym9hcmRzLiV1LmRldm5hbWUiLCBpZCk7CisgICAgZXJyID0gcHJvcGVydHlfZ2V0KHByb3BOYW1lLCBkZXYsICIiKTsKKyAgICBpZiAoZXJyID4gMCkgeworICAgICAgICAvLyByZXBsYWNlIGFsbCB0aGUgc3BhY2VzIHdpdGggdW5kZXJzY29yZXMKKyAgICAgICAgc3RyY3B5KHRtcGZuLCBkZXYpOworICAgICAgICBmb3IgKGNoYXIgKnAgPSBzdHJjaHIodG1wZm4sICcgJyk7IHAgJiYgKnA7IHAgPSBzdHJjaHIodG1wZm4sICcgJykpCisgICAgICAgICAgICAqcCA9ICdfJzsKKyAgICAgICAgc25wcmludGYocGF0aCwgc2l6ZW9mKHBhdGgpLCAiJXMvdXNyL2tleWNoYXJzLyVzLmtjbS5iaW4iLCByb290LCB0bXBmbik7CisgICAgICAgIC8vTE9HRCgibG9hZDogZGV2PSclcycgcGF0aD0nJXMnXG4iLCBkZXYsIHBhdGgpOworICAgICAgICBydiA9IHRyeV9maWxlKHBhdGgpOworICAgICAgICBpZiAocnYgIT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIHJ2OworICAgICAgICB9CisgICAgICAgIExPR1coIkVycm9yIGxvYWRpbmcga2V5Y2hhcm1hcCBmaWxlICclcycuICVzPSclcyciLCBwYXRoLCBwcm9wTmFtZSwgZGV2KTsKKyAgICB9IGVsc2UgeworICAgICAgICBMT0dXKCJObyBrZXlib2FyZCBmb3IgaWQgJWQiLCBpZCk7CisgICAgfQorCisgICAgc25wcmludGYocGF0aCwgc2l6ZW9mKHBhdGgpLCAiJXMvdXNyL2tleWNoYXJzL3F3ZXJ0eS5rY20uYmluIiwgcm9vdCk7CisgICAgcnYgPSB0cnlfZmlsZShwYXRoKTsKKyAgICBpZiAocnYgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCJDYW4ndCBmaW5kIGFueSBrZXljaGFybWFwcyAoYWxzbyB0cmllZCAlcykiLCBwYXRoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIExPR1coIlVzaW5nIGRlZmF1bHQga2V5bWFwOiAlcyIsIHBhdGgpOworCisgICAgcmV0dXJuIHJ2OworfQorCitLZXlDaGFyYWN0ZXJNYXAqCitLZXlDaGFyYWN0ZXJNYXA6OnRyeV9maWxlKGNvbnN0IGNoYXIqIGZpbGVuYW1lKQoreworICAgIEtleUNoYXJhY3Rlck1hcCogcnYgPSBOVUxMOworICAgIEtleSoga2V5czsKKyAgICBpbnQgZmQ7CisgICAgb2ZmX3QgZmlsZXNpemU7CisgICAgSGVhZGVyIGhlYWRlcjsKKyAgICBpbnQgZXJyOworICAgIAorICAgIGZkID0gb3BlbihmaWxlbmFtZSwgT19SRE9OTFkpOworICAgIGlmIChmZCA9PSAtMSkgeworICAgICAgICBMT0dXKCJDYW4ndCBvcGVuIGtleWNoYXJtYXAgZmlsZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBmaWxlc2l6ZSA9IGxzZWVrKGZkLCAwLCBTRUVLX0VORCk7CisgICAgbHNlZWsoZmQsIDAsIFNFRUtfU0VUKTsKKworICAgIC8vIHZhbGlkYXRlIHRoZSBoZWFkZXIKKyAgICBpZiAoZmlsZXNpemUgPD0gKG9mZl90KXNpemVvZihoZWFkZXIpKSB7CisgICAgICAgIExPR1coIkJhZCBrZXljaGFybWFwIC0gZmlsZXNpemU9JWRcbiIsIChpbnQpZmlsZXNpemUpOworICAgICAgICBnb3RvIGNsZWFudXAxOworICAgIH0KKworICAgIGVyciA9IHJlYWQoZmQsICZoZWFkZXIsIHNpemVvZihoZWFkZXIpKTsKKyAgICBpZiAoZXJyID09IC0xKSB7CisgICAgICAgIExPR1coIkVycm9yIHJlYWRpbmcga2V5Y2hhcm1hcCBmaWxlIik7CisgICAgICAgIGdvdG8gY2xlYW51cDE7CisgICAgfQorCisgICAgaWYgKDAgIT0gbWVtY21wKGhlYWRlci5tYWdpYywgImtleWNoYXIiLCA4KSkgeworICAgICAgICBMT0dXKCJCYWQga2V5Y2hhcm1hcCBtYWdpYyB0b2tlbiIpOworICAgICAgICBnb3RvIGNsZWFudXAxOworICAgIH0KKyAgICBpZiAoaGVhZGVyLmVuZGlhbiAhPSAweDEyMzQ1Njc4KSB7CisgICAgICAgIExPR1coIkJhZCBrZXljaGFybWFwIGVuZGlhbnMiKTsKKyAgICAgICAgZ290byBjbGVhbnVwMTsKKyAgICB9CisgICAgaWYgKChoZWFkZXIudmVyc2lvbiAmIDB4ZmYpICE9IDIpIHsKKyAgICAgICAgTE9HVygiT25seSBzdXBwb3J0IGtleWNoYXJtYXAgdmVyc2lvbiAyIChnb3QgMHglMDh4KSIsIGhlYWRlci52ZXJzaW9uKTsKKyAgICAgICAgZ290byBjbGVhbnVwMTsKKyAgICB9CisgICAgaWYgKGZpbGVzaXplIDwgKG9mZl90KShzaXplb2YoSGVhZGVyKSsoc2l6ZW9mKEtleSkqaGVhZGVyLmtleWNvdW50KSkpIHsKKyAgICAgICAgTE9HVygiQmFkIGtleWNoYXJtYXAgZmlsZSBzaXplXG4iKTsKKyAgICAgICAgZ290byBjbGVhbnVwMTsKKyAgICB9CisKKyAgICAvLyByZWFkIHRoZSBrZXkgZGF0YQorICAgIGtleXMgPSAoS2V5KiltYWxsb2Moc2l6ZW9mKEtleSkqaGVhZGVyLmtleWNvdW50KTsKKyAgICBlcnIgPSByZWFkKGZkLCBrZXlzLCBzaXplb2YoS2V5KSpoZWFkZXIua2V5Y291bnQpOworICAgIGlmIChlcnIgPT0gLTEpIHsKKyAgICAgICAgTE9HVygiRXJyb3IgcmVhZGluZyBrZXljaGFybWFwIGZpbGUiKTsKKyAgICAgICAgZnJlZShrZXlzKTsKKyAgICAgICAgZ290byBjbGVhbnVwMTsKKyAgICB9CisKKyAgICAvLyByZXR1cm4gdGhlIG9iamVjdAorICAgIHJ2ID0gbmV3IEtleUNoYXJhY3Rlck1hcDsKKyAgICBydi0+bV9rZXlDb3VudCA9IGhlYWRlci5rZXljb3VudDsKKyAgICBydi0+bV9rZXlzID0ga2V5czsKKyAgICBydi0+bV90eXBlID0gaGVhZGVyLmtiZHR5cGU7CisKK2NsZWFudXAxOgorICAgIGNsb3NlKGZkKTsKKworICAgIHJldHVybiBydjsKK30KZGlmZiAtLWdpdCBhL2xpYnMvdWkvS2V5TGF5b3V0TWFwLmNwcCBiL2xpYnMvdWkvS2V5TGF5b3V0TWFwLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNWFlNTRjCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9LZXlMYXlvdXRNYXAuY3BwCkBAIC0wLDAgKzEsMjM1IEBACisjZGVmaW5lIExPR19UQUcgIktleUxheW91dE1hcCIKKworI2luY2x1ZGUgIktleUxheW91dE1hcC5oIgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDx1aS9LZXljb2RlTGFiZWxzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworS2V5TGF5b3V0TWFwOjpLZXlMYXlvdXRNYXAoKQorICAgIDptX3N0YXR1cyhOT19JTklUKSwKKyAgICAgbV9rZXlzKCkKK3sKK30KKworS2V5TGF5b3V0TWFwOjp+S2V5TGF5b3V0TWFwKCkKK3sKK30KKworc3RhdGljIFN0cmluZzgKK25leHRfdG9rZW4oY2hhciBjb25zdCoqIHAsIGludCAqbGluZSkKK3sKKyAgICBib29sIGJlZ3VuID0gZmFsc2U7CisgICAgY29uc3QgY2hhciogYmVnaW4gPSAqcDsKKyAgICBjb25zdCBjaGFyKiBlbmQgPSAqcDsKKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICBpZiAoKmVuZCA9PSAnXG4nKSB7CisgICAgICAgICAgICAoKmxpbmUpKys7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoICgqZW5kKQorICAgICAgICB7CisgICAgICAgICAgICBjYXNlICcjJzoKKyAgICAgICAgICAgICAgICBpZiAoYmVndW4pIHsKKyAgICAgICAgICAgICAgICAgICAgKnAgPSBlbmQ7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmc4KGJlZ2luLCBlbmQtYmVnaW4pOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luKys7CisgICAgICAgICAgICAgICAgICAgICAgICBlbmQrKzsKKyAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoKmJlZ2luICE9ICdcMCcgJiYgKmJlZ2luICE9ICdcbicpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgJ1wwJzoKKyAgICAgICAgICAgIGNhc2UgJyAnOgorICAgICAgICAgICAgY2FzZSAnXG4nOgorICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgY2FzZSAnXHQnOgorICAgICAgICAgICAgICAgIGlmIChiZWd1biB8fCAoKmVuZCA9PSAnXDAnKSkgeworICAgICAgICAgICAgICAgICAgICAqcCA9IGVuZDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZzgoYmVnaW4sIGVuZC1iZWdpbik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYmVnaW4rKzsKKyAgICAgICAgICAgICAgICAgICAgZW5kKys7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgZW5kKys7CisgICAgICAgICAgICAgICAgYmVndW4gPSB0cnVlOworICAgICAgICB9CisgICAgfQorfQorCitzdGF0aWMgaW50MzJfdAordG9rZW5fdG9fdmFsdWUoY29uc3QgY2hhciAqbGl0ZXJhbCwgY29uc3QgS2V5Y29kZUxhYmVsICpsaXN0KQoreworICAgIHdoaWxlIChsaXN0LT5saXRlcmFsKSB7CisgICAgICAgIGlmICgwID09IHN0cmNtcChsaXRlcmFsLCBsaXN0LT5saXRlcmFsKSkgeworICAgICAgICAgICAgcmV0dXJuIGxpc3QtPnZhbHVlOworICAgICAgICB9CisgICAgICAgIGxpc3QrKzsKKyAgICB9CisgICAgcmV0dXJuIGxpc3QtPnZhbHVlOworfQorCitzdGF0dXNfdAorS2V5TGF5b3V0TWFwOjpsb2FkKGNvbnN0IGNoYXIqIGZpbGVuYW1lKQoreworICAgIGludCBmZCA9IG9wZW4oZmlsZW5hbWUsIE9fUkRPTkxZKTsKKyAgICBpZiAoZmQgPCAwKSB7CisgICAgICAgIExPR0UoImVycm9yIG9wZW5pbmcgZmlsZT0lcyBlcnI9JXNcbiIsIGZpbGVuYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICBtX3N0YXR1cyA9IGVycm5vOworICAgICAgICByZXR1cm4gZXJybm87CisgICAgfQorCisgICAgb2ZmX3QgbGVuID0gbHNlZWsoZmQsIDAsIFNFRUtfRU5EKTsKKyAgICBvZmZfdCBlcnJsZW4gPSBsc2VlayhmZCwgMCwgU0VFS19TRVQpOworICAgIGlmIChsZW4gPCAwIHx8IGVycmxlbiA8IDApIHsKKyAgICAgICAgY2xvc2UoZmQpOworICAgICAgICBMT0dFKCJlcnJvciBzZWVraW5nIGZpbGU9JXMgZXJyPSVzXG4iLCBmaWxlbmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgbV9zdGF0dXMgPSBlcnJubzsKKyAgICAgICAgcmV0dXJuIGVycm5vOworICAgIH0KKworICAgIGNoYXIqIGJ1ZiA9IChjaGFyKiltYWxsb2MobGVuKzEpOworICAgIGlmIChyZWFkKGZkLCBidWYsIGxlbikgIT0gbGVuKSB7CisgICAgICAgIExPR0UoImVycm9yIHJlYWRpbmcgZmlsZT0lcyBlcnI9JXNcbiIsIGZpbGVuYW1lLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICBtX3N0YXR1cyA9IGVycm5vICE9IDAgPyBlcnJubyA6ICgoaW50KU5PVF9FTk9VR0hfREFUQSk7CisgICAgICAgIHJldHVybiBlcnJubyAhPSAwID8gZXJybm8gOiAoKGludClOT1RfRU5PVUdIX0RBVEEpOworICAgIH0KKyAgICBlcnJubyA9IDA7CisgICAgYnVmW2xlbl0gPSAnXDAnOworCisgICAgaW50MzJfdCBzY2FuY29kZSA9IC0xOworICAgIGludDMyX3Qga2V5Y29kZSA9IC0xOworICAgIHVpbnQzMl90IGZsYWdzID0gMDsKKyAgICB1aW50MzJfdCB0bXA7CisgICAgY2hhciogZW5kOworICAgIHN0YXR1c190IGVyciA9IE5PX0VSUk9SOworICAgIGludCBsaW5lID0gMTsKKyAgICBjaGFyIGNvbnN0KiBwID0gYnVmOworICAgIGVudW0geyBCRUdJTiwgU0NBTkNPREUsIEtFWUNPREUsIEZMQUcgfSBzdGF0ZSA9IEJFR0lOOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIFN0cmluZzggdG9rZW4gPSBuZXh0X3Rva2VuKCZwLCAmbGluZSk7CisgICAgICAgIGlmICgqcCA9PSAnXDAnKSB7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKHN0YXRlKQorICAgICAgICB7CisgICAgICAgICAgICBjYXNlIEJFR0lOOgorICAgICAgICAgICAgICAgIGlmICh0b2tlbiA9PSAia2V5IikgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IFNDQU5DT0RFOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIExPR0UoIiVzOiVkOiBleHBlY3RlZCBrZXksIGdvdCAnJXMnXG4iLCBmaWxlbmFtZSwgbGluZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbi5zdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIGVyciA9IEJBRF9WQUxVRTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgU0NBTkNPREU6CisgICAgICAgICAgICAgICAgc2NhbmNvZGUgPSBzdHJ0b2wodG9rZW4uc3RyaW5nKCksICZlbmQsIDApOworICAgICAgICAgICAgICAgIGlmICgqZW5kICE9ICdcMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HRSgiJXM6JWQ6IGV4cGVjdGVkIHNjYW5jb2RlIChhIG51bWJlciksIGdvdCAnJXMnXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLCBsaW5lLCB0b2tlbi5zdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy9MT0dJKCIlczolZDogZ290IHNjYW5jb2RlICVkXG4iLCBmaWxlbmFtZSwgbGluZSwgc2NhbmNvZGUgKTsKKyAgICAgICAgICAgICAgICBzdGF0ZSA9IEtFWUNPREU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEtFWUNPREU6CisgICAgICAgICAgICAgICAga2V5Y29kZSA9IHRva2VuX3RvX3ZhbHVlKHRva2VuLnN0cmluZygpLCBLRVlDT0RFUyk7CisgICAgICAgICAgICAgICAgLy9MT0dJKCIlczolZDogZ290IGtleWNvZGUgJWQgZm9yICVzXG4iLCBmaWxlbmFtZSwgbGluZSwga2V5Y29kZSwgdG9rZW4uc3RyaW5nKCkgKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5Y29kZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIExPR0UoIiVzOiVkOiBleHBlY3RlZCBrZXljb2RlLCBnb3QgJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZSwgdG9rZW4uc3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN0YXRlID0gRkxBRzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRkxBRzoKKyAgICAgICAgICAgICAgICBpZiAodG9rZW4gPT0gImtleSIpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNjYW5jb2RlICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvL0xPR0koImdvdCBrZXkgZGVjbCBzY2FuY29kZT0lZCBrZXljb2RlPSVkIgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIiBmbGFncz0weCUwOHhcbiIsIHNjYW5jb2RlLCBrZXljb2RlLCBmbGFncyk7CisgICAgICAgICAgICAgICAgICAgICAgICBLZXkgayA9IHsga2V5Y29kZSwgZmxhZ3MgfTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1fa2V5cy5hZGQoc2NhbmNvZGUsIGspOworICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBTQ0FOQ09ERTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5jb2RlID0gLTE7CisgICAgICAgICAgICAgICAgICAgICAgICBrZXljb2RlID0gLTE7CisgICAgICAgICAgICAgICAgICAgICAgICBmbGFncyA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0bXAgPSB0b2tlbl90b192YWx1ZSh0b2tlbi5zdHJpbmcoKSwgRkxBR1MpOworICAgICAgICAgICAgICAgIC8vTE9HSSgiJXM6JWQ6IGdvdCBmbGFncyAleCBmb3IgJXNcbiIsIGZpbGVuYW1lLCBsaW5lLCB0bXAsIHRva2VuLnN0cmluZygpICk7CisgICAgICAgICAgICAgICAgaWYgKHRtcCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIExPR0UoIiVzOiVkOiBleHBlY3RlZCBmbGFnLCBnb3QgJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZSwgdG9rZW4uc3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZsYWdzIHw9IHRtcDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoc3RhdGUgPT0gRkxBRyAmJiBzY2FuY29kZSAhPSAtMSApIHsKKyAgICAgICAgLy9MT0dJKCJnb3Qga2V5IGRlY2wgc2NhbmNvZGU9JWQga2V5Y29kZT0lZCIKKyAgICAgICAgLy8gICAgICAgIiBmbGFncz0weCUwOHhcbiIsIHNjYW5jb2RlLCBrZXljb2RlLCBmbGFncyk7CisgICAgICAgIEtleSBrID0geyBrZXljb2RlLCBmbGFncyB9OworICAgICAgICBtX2tleXMuYWRkKHNjYW5jb2RlLCBrKTsKKyAgICB9CisKK2RvbmU6CisgICAgZnJlZShidWYpOworICAgIGNsb3NlKGZkKTsKKworICAgIG1fc3RhdHVzID0gZXJyOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190CitLZXlMYXlvdXRNYXA6Om1hcChpbnQzMl90IHNjYW5jb2RlLCBpbnQzMl90ICprZXljb2RlLCB1aW50MzJfdCAqZmxhZ3MpIGNvbnN0Cit7CisgICAgaWYgKG1fc3RhdHVzICE9IE5PX0VSUk9SKSB7CisgICAgICAgIHJldHVybiBtX3N0YXR1czsKKyAgICB9CisKKyAgICBzc2l6ZV90IGluZGV4ID0gbV9rZXlzLmluZGV4T2ZLZXkoc2NhbmNvZGUpOworICAgIGlmIChpbmRleCA8IDApIHsKKyAgICAgICAgLy9MT0dXKCJjb3VsZG4ndCBtYXAgc2NhbmNvZGU9JWRcbiIsIHNjYW5jb2RlKTsKKyAgICAgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworICAgIH0KKworICAgIGNvbnN0IEtleSYgayA9IG1fa2V5cy52YWx1ZUF0KGluZGV4KTsKKworICAgICprZXljb2RlID0gay5rZXljb2RlOworICAgICpmbGFncyA9IGsuZmxhZ3M7CisKKyAgICAvL0xPR0QoIm1hcHBlZCBzY2FuY29kZT0lZCB0byBrZXljb2RlPSVkIGZsYWdzPTB4JTA4eFxuIiwgc2NhbmNvZGUsCisgICAgLy8gICAgICAgIGtleWNvZGUsIGZsYWdzKTsKKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QKK0tleUxheW91dE1hcDo6ZmluZFNjYW5jb2RlcyhpbnQzMl90IGtleWNvZGUsIFZlY3RvcjxpbnQzMl90Piogb3V0U2NhbmNvZGVzKSBjb25zdAoreworICAgIGlmIChtX3N0YXR1cyAhPSBOT19FUlJPUikgeworICAgICAgICByZXR1cm4gbV9zdGF0dXM7CisgICAgfQorICAgIAorICAgIGNvbnN0IHNpemVfdCBOID0gbV9rZXlzLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgIGlmIChtX2tleXMudmFsdWVBdChpKS5rZXljb2RlID09IGtleWNvZGUpIHsKKyAgICAgICAgICAgIG91dFNjYW5jb2Rlcy0+YWRkKG1fa2V5cy5rZXlBdChpKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit9OwpkaWZmIC0tZ2l0IGEvbGlicy91aS9LZXlMYXlvdXRNYXAuaCBiL2xpYnMvdWkvS2V5TGF5b3V0TWFwLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDNmODRjZQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvS2V5TGF5b3V0TWFwLmgKQEAgLTAsMCArMSwzMSBAQAorI2lmbmRlZiBLRVlMQVlPVVRNQVBfSAorI2RlZmluZSBLRVlMQVlPVVRNQVBfSAorCisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitjbGFzcyBLZXlMYXlvdXRNYXAKK3sKK3B1YmxpYzoKKyAgICBLZXlMYXlvdXRNYXAoKTsKKyAgICB+S2V5TGF5b3V0TWFwKCk7CisKKyAgICBzdGF0dXNfdCBsb2FkKGNvbnN0IGNoYXIqIGZpbGVuYW1lKTsKKworICAgIHN0YXR1c190IG1hcChpbnQzMl90IHNjYW5jb2RlLCBpbnQzMl90ICprZXljb2RlLCB1aW50MzJfdCAqZmxhZ3MpIGNvbnN0OworICAgIHN0YXR1c190IGZpbmRTY2FuY29kZXMoaW50MzJfdCBrZXljb2RlLCBWZWN0b3I8aW50MzJfdD4qIG91dFNjYW5jb2RlcykgY29uc3Q7CisKK3ByaXZhdGU6CisgICAgc3RydWN0IEtleSB7CisgICAgICAgIGludDMyX3Qga2V5Y29kZTsKKyAgICAgICAgdWludDMyX3QgZmxhZ3M7CisgICAgfTsKKworICAgIHN0YXR1c190IG1fc3RhdHVzOworICAgIEtleWVkVmVjdG9yPGludDMyX3QsS2V5PiBtX2tleXM7Cit9OworCit9OworCisjZW5kaWYgLy8gS0VZTEFZT1VUTUFQX0gKZGlmZiAtLWdpdCBhL2xpYnMvdWkvTGF5ZXJTdGF0ZS5jcHAgYi9saWJzL3VpL0xheWVyU3RhdGUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiNjM3NGIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL0xheWVyU3RhdGUuY3BwCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisjaW5jbHVkZSA8cHJpdmF0ZS91aS9MYXllclN0YXRlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RhdHVzX3QgbGF5ZXJfc3RhdGVfdDo6d3JpdGUoUGFyY2VsJiBvdXRwdXQpIGNvbnN0Cit7CisgICAgc2l6ZV90IHNpemUgPSBzaXplb2YobGF5ZXJfc3RhdGVfdCk7CisKKyAgICAvL291dHB1dC53cml0ZVN0cm9uZ0JpbmRlcihzdXJmYWNlLT5hc0JpbmRlcigpKTsKKyAgICAvL3NpemUgLT0gc2l6ZW9mKHN1cmZhY2UpOworCisgICAgdHJhbnNwYXJlbnRSZWdpb24ud3JpdGUob3V0cHV0KTsKKyAgICBzaXplIC09IHNpemVvZih0cmFuc3BhcmVudFJlZ2lvbik7CisgICAgCisgICAgb3V0cHV0LndyaXRlKHRoaXMsIHNpemUpOworICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgbGF5ZXJfc3RhdGVfdDo6cmVhZChjb25zdCBQYXJjZWwmIGlucHV0KQoreworICAgIHNpemVfdCBzaXplID0gc2l6ZW9mKGxheWVyX3N0YXRlX3QpOworCisgICAgLy9zdXJmYWNlID0gaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2U+KGlucHV0LnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgLy9zaXplIC09IHNpemVvZihzdXJmYWNlKTsKKworICAgIHRyYW5zcGFyZW50UmVnaW9uLnJlYWQoaW5wdXQpOworICAgIHNpemUgLT0gc2l6ZW9mKHRyYW5zcGFyZW50UmVnaW9uKTsKKworICAgIGlucHV0LnJlYWQodGhpcywgc2l6ZSk7CisgICAgCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91aS9NT0RVTEVfTElDRU5TRV9BUEFDSEUyIGIvbGlicy91aS9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIKZGlmZiAtLWdpdCBhL2xpYnMvdWkvTk9USUNFIGIvbGlicy91aS9OT1RJQ0UKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzViMWVmYQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvTk9USUNFCkBAIC0wLDAgKzEsMTkwIEBACisKKyAgIENvcHlyaWdodCAoYykgMjAwNS0yMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisKKyAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKwpkaWZmIC0tZ2l0IGEvbGlicy91aS9PdmVybGF5LmNwcCBiL2xpYnMvdWkvT3ZlcmxheS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjIzNmVkYwotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvT3ZlcmxheS5jcHAKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBCYXNlLmg+CisKKyNpbmNsdWRlIDx1aS9JT3ZlcmxheS5oPgorI2luY2x1ZGUgPHVpL092ZXJsYXkuaD4KKworI2luY2x1ZGUgPGhhcmR3YXJlL292ZXJsYXkuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitPdmVybGF5OjpPdmVybGF5KGNvbnN0IHNwPE92ZXJsYXlSZWY+JiBvdmVybGF5UmVmKQorICAgIDogbU92ZXJsYXlSZWYob3ZlcmxheVJlZiksIG1PdmVybGF5RGF0YSgwKSwgbVN0YXR1cyhOT19JTklUKQoreworICAgIG1PdmVybGF5RGF0YSA9IE5VTEw7CisgICAgaHdfbW9kdWxlX3QgY29uc3QqIG1vZHVsZTsKKyAgICBpZiAob3ZlcmxheVJlZiAhPSAwKSB7CisgICAgICAgIGlmIChod19nZXRfbW9kdWxlKE9WRVJMQVlfSEFSRFdBUkVfTU9EVUxFX0lELCAmbW9kdWxlKSA9PSAwKSB7CisgICAgICAgICAgICBpZiAob3ZlcmxheV9kYXRhX29wZW4obW9kdWxlLCAmbU92ZXJsYXlEYXRhKSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgIG1TdGF0dXMgPSBtT3ZlcmxheURhdGEtPmluaXRpYWxpemUobU92ZXJsYXlEYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxheVJlZi0+bU92ZXJsYXlIYW5kbGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCitPdmVybGF5Ojp+T3ZlcmxheSgpIHsKKyAgICBpZiAobU92ZXJsYXlEYXRhKSB7CisgICAgICAgIG92ZXJsYXlfZGF0YV9jbG9zZShtT3ZlcmxheURhdGEpOworICAgIH0KK30KKworc3RhdHVzX3QgT3ZlcmxheTo6ZGVxdWV1ZUJ1ZmZlcihvdmVybGF5X2J1ZmZlcl90KiBidWZmZXIpCit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiBtU3RhdHVzOworICAgIHJldHVybiAgbU92ZXJsYXlEYXRhLT5kZXF1ZXVlQnVmZmVyKG1PdmVybGF5RGF0YSwgYnVmZmVyKTsKK30KKworc3RhdHVzX3QgT3ZlcmxheTo6cXVldWVCdWZmZXIob3ZlcmxheV9idWZmZXJfdCBidWZmZXIpCit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiBtU3RhdHVzOworICAgIHJldHVybiBtT3ZlcmxheURhdGEtPnF1ZXVlQnVmZmVyKG1PdmVybGF5RGF0YSwgYnVmZmVyKTsKK30KKworaW50MzJfdCBPdmVybGF5OjpnZXRCdWZmZXJDb3VudCgpIGNvbnN0Cit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiBtU3RhdHVzOworICAgIHJldHVybiBtT3ZlcmxheURhdGEtPmdldEJ1ZmZlckNvdW50KG1PdmVybGF5RGF0YSk7Cit9CisKK3ZvaWQqIE92ZXJsYXk6OmdldEJ1ZmZlckFkZHJlc3Mob3ZlcmxheV9idWZmZXJfdCBidWZmZXIpCit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiBOVUxMOworICAgIHJldHVybiBtT3ZlcmxheURhdGEtPmdldEJ1ZmZlckFkZHJlc3MobU92ZXJsYXlEYXRhLCBidWZmZXIpOworfQorCit2b2lkIE92ZXJsYXk6OmRlc3Ryb3koKSB7ICAKKyAgICBpZiAobVN0YXR1cyAhPSBOT19FUlJPUikgcmV0dXJuOworICAgIG1PdmVybGF5UmVmLT5tT3ZlcmxheUNoYW5uZWwtPmRlc3Ryb3koKTsKK30KKworc3RhdHVzX3QgT3ZlcmxheTo6Z2V0U3RhdHVzKCkgY29uc3QgeworICAgIHJldHVybiBtU3RhdHVzOworfQorCitvdmVybGF5X2hhbmRsZV90IE92ZXJsYXk6OmdldEhhbmRsZVJlZigpIGNvbnN0IHsKKyAgICBpZiAobVN0YXR1cyAhPSBOT19FUlJPUikgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIG1PdmVybGF5UmVmLT5tT3ZlcmxheUhhbmRsZTsKK30KKwordWludDMyX3QgT3ZlcmxheTo6Z2V0V2lkdGgoKSBjb25zdCB7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiAwOworICAgIHJldHVybiBtT3ZlcmxheVJlZi0+bVdpZHRoOworfQorCit1aW50MzJfdCBPdmVybGF5OjpnZXRIZWlnaHQoKSBjb25zdCB7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiAwOworICAgIHJldHVybiBtT3ZlcmxheVJlZi0+bUhlaWdodDsKK30KKworaW50MzJfdCBPdmVybGF5OjpnZXRGb3JtYXQoKSBjb25zdCB7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiAtMTsKKyAgICByZXR1cm4gbU92ZXJsYXlSZWYtPm1Gb3JtYXQ7Cit9CisKK2ludDMyX3QgT3ZlcmxheTo6Z2V0V2lkdGhTdHJpZGUoKSBjb25zdCB7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpIHJldHVybiAwOworICAgIHJldHVybiBtT3ZlcmxheVJlZi0+bVdpZHRoU3RyaWRlOworfQorCitpbnQzMl90IE92ZXJsYXk6OmdldEhlaWdodFN0cmlkZSgpIGNvbnN0IHsKKyAgICBpZiAobVN0YXR1cyAhPSBOT19FUlJPUikgcmV0dXJuIDA7CisgICAgcmV0dXJuIG1PdmVybGF5UmVmLT5tSGVpZ2h0U3RyaWRlOworfQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitPdmVybGF5UmVmOjpPdmVybGF5UmVmKCkgCisgOiBtT3ZlcmxheUhhbmRsZSgwKSwKKyAgICBtV2lkdGgoMCksIG1IZWlnaHQoMCksIG1Gb3JtYXQoMCksIG1XaWR0aFN0cmlkZSgwKSwgbUhlaWdodFN0cmlkZSgwKSwKKyAgICBtT3duSGFuZGxlKHRydWUpCit7ICAgIAorfQorCitPdmVybGF5UmVmOjpPdmVybGF5UmVmKG92ZXJsYXlfaGFuZGxlX3QgaGFuZGxlLCBjb25zdCBzcDxJT3ZlcmxheT4mIGNoYW5uZWwsCisgICAgICAgICB1aW50MzJfdCB3LCB1aW50MzJfdCBoLCBpbnQzMl90IGYsIHVpbnQzMl90IHdzLCB1aW50MzJfdCBocykKKyAgICA6IG1PdmVybGF5SGFuZGxlKGhhbmRsZSksIG1PdmVybGF5Q2hhbm5lbChjaGFubmVsKSwKKyAgICBtV2lkdGgodyksIG1IZWlnaHQoaCksIG1Gb3JtYXQoZiksIG1XaWR0aFN0cmlkZSh3cyksIG1IZWlnaHRTdHJpZGUoaHMpLAorICAgIG1Pd25IYW5kbGUoZmFsc2UpCit7Cit9CisKK092ZXJsYXlSZWY6On5PdmVybGF5UmVmKCkKK3sKKyAgICBpZiAobU93bkhhbmRsZSkgeworICAgICAgICAvKiBGSVhNRTogaGFuZGxlcyBzaG91bGQgYmUgcHJvbW90ZWQgdG8gInJlYWwiIEFQSSBhbmQgYmUgaGFuZGxlZCBieSAKKyAgICAgICAgICogdGhlIGZyYW1ld29yayAqLworICAgICAgICBmb3IgKGludCBpPTAgOyBpPG1PdmVybGF5SGFuZGxlLT5udW1GZHMgOyBpKyspIHsKKyAgICAgICAgICAgIGNsb3NlKG1PdmVybGF5SGFuZGxlLT5kYXRhW2ldKTsKKyAgICAgICAgfQorICAgICAgICBmcmVlKCh2b2lkKiltT3ZlcmxheUhhbmRsZSk7CisgICAgfQorfQorCitzcDxPdmVybGF5UmVmPiBPdmVybGF5UmVmOjpyZWFkRnJvbVBhcmNlbChjb25zdCBQYXJjZWwmIGRhdGEpIHsKKyAgICBzcDxPdmVybGF5UmVmPiByZXN1bHQ7CisgICAgc3A8SU92ZXJsYXk+IG92ZXJsYXkgPSBJT3ZlcmxheTo6YXNJbnRlcmZhY2UoZGF0YS5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgIGlmIChvdmVybGF5ICE9IE5VTEwpIHsKKyAgICAgICAgdWludDMyX3QgdyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgIHVpbnQzMl90IGggPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICB1aW50MzJfdCBmID0gZGF0YS5yZWFkSW50MzIoKTsKKyAgICAgICAgdWludDMyX3Qgd3MgPSBkYXRhLnJlYWRJbnQzMigpOworICAgICAgICB1aW50MzJfdCBocyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgIG5hdGl2ZV9oYW5kbGUqIGhhbmRsZSA9IGRhdGEucmVhZE5hdGl2ZUhhbmRsZShOVUxMLCBOVUxMKTsKKworICAgICAgICByZXN1bHQgPSBuZXcgT3ZlcmxheVJlZigpOworICAgICAgICByZXN1bHQtPm1PdmVybGF5SGFuZGxlID0gaGFuZGxlOworICAgICAgICByZXN1bHQtPm1PdmVybGF5Q2hhbm5lbCA9IG92ZXJsYXk7CisgICAgICAgIHJlc3VsdC0+bVdpZHRoID0gdzsKKyAgICAgICAgcmVzdWx0LT5tSGVpZ2h0ID0gaDsKKyAgICAgICAgcmVzdWx0LT5tRm9ybWF0ID0gZjsKKyAgICAgICAgcmVzdWx0LT5tV2lkdGhTdHJpZGUgPSB3czsKKyAgICAgICAgcmVzdWx0LT5tSGVpZ2h0U3RyaWRlID0gaHM7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXR1c190IE92ZXJsYXlSZWY6OndyaXRlVG9QYXJjZWwoUGFyY2VsKiByZXBseSwgY29uc3Qgc3A8T3ZlcmxheVJlZj4mIG8pIHsKKyAgICBpZiAobyAhPSBOVUxMKSB7CisgICAgICAgIHJlcGx5LT53cml0ZVN0cm9uZ0JpbmRlcihvLT5tT3ZlcmxheUNoYW5uZWwtPmFzQmluZGVyKCkpOworICAgICAgICByZXBseS0+d3JpdGVJbnQzMihvLT5tV2lkdGgpOworICAgICAgICByZXBseS0+d3JpdGVJbnQzMihvLT5tSGVpZ2h0KTsKKyAgICAgICAgcmVwbHktPndyaXRlSW50MzIoby0+bUZvcm1hdCk7CisgICAgICAgIHJlcGx5LT53cml0ZUludDMyKG8tPm1XaWR0aFN0cmlkZSk7CisgICAgICAgIHJlcGx5LT53cml0ZUludDMyKG8tPm1IZWlnaHRTdHJpZGUpOworICAgICAgICByZXBseS0+d3JpdGVOYXRpdmVIYW5kbGUoKihvLT5tT3ZlcmxheUhhbmRsZSkpOworICAgIH0gZWxzZSB7CisgICAgICAgIHJlcGx5LT53cml0ZVN0cm9uZ0JpbmRlcihOVUxMKTsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3VpL1BpeGVsRm9ybWF0LmNwcCBiL2xpYnMvdWkvUGl4ZWxGb3JtYXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NWVkOTcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL1BpeGVsRm9ybWF0LmNwcApAQCAtMCwwICsxLDk3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHVpL1BpeGVsRm9ybWF0Lmg+CisjaW5jbHVkZSA8cGl4ZWxmbGluZ2VyL2Zvcm1hdC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3NpemVfdCBQaXhlbEZvcm1hdEluZm86OmdldFNjYW5saW5lU2l6ZSh1bnNpZ25lZCBpbnQgd2lkdGgpIGNvbnN0Cit7CisgICAgc2l6ZV90IHNpemU7CisgICAgaWYgKChjb21wb25lbnRzID49IDYpICYmIChjb21wb25lbnRzIDw9IDgpKSB7CisgICAgICAgIC8vIFlDYkNyIGZvcm1hdHMgYXJlIGRpZmZlcmVudHMuCisgICAgICAgIHNpemUgPSAod2lkdGggKiBiaXRzUGVyUGl4ZWwpPj4zOworICAgIH0gZWxzZSB7CisgICAgICAgIHNpemUgPSB3aWR0aCAqIGJ5dGVzUGVyUGl4ZWw7CisgICAgfQorICAgIHJldHVybiBzaXplOworfQorCitzc2l6ZV90IGJ5dGVzUGVyUGl4ZWwoUGl4ZWxGb3JtYXQgZm9ybWF0KQoreworICAgIFBpeGVsRm9ybWF0SW5mbyBpbmZvOworICAgIHN0YXR1c190IGVyciA9IGdldFBpeGVsRm9ybWF0SW5mbyhmb3JtYXQsICZpbmZvKTsKKyAgICByZXR1cm4gKGVyciA8IDApID8gZXJyIDogaW5mby5ieXRlc1BlclBpeGVsOworfQorCitzc2l6ZV90IGJpdHNQZXJQaXhlbChQaXhlbEZvcm1hdCBmb3JtYXQpCit7CisgICAgUGl4ZWxGb3JtYXRJbmZvIGluZm87CisgICAgc3RhdHVzX3QgZXJyID0gZ2V0UGl4ZWxGb3JtYXRJbmZvKGZvcm1hdCwgJmluZm8pOworICAgIHJldHVybiAoZXJyIDwgMCkgPyBlcnIgOiBpbmZvLmJpdHNQZXJQaXhlbDsKK30KKworc3RhdHVzX3QgZ2V0UGl4ZWxGb3JtYXRJbmZvKFBpeGVsRm9ybWF0IGZvcm1hdCwgUGl4ZWxGb3JtYXRJbmZvKiBpbmZvKQoreworICAgIGlmIChmb3JtYXQgPCAwKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworCisgICAgaWYgKGluZm8tPnZlcnNpb24gIT0gc2l6ZW9mKFBpeGVsRm9ybWF0SW5mbykpCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKworICAgIHNpemVfdCBudW1FbnRyaWVzOworICAgIGNvbnN0IEdHTEZvcm1hdCAqaSA9IGdnbEdldFBpeGVsRm9ybWF0VGFibGUoJm51bUVudHJpZXMpICsgZm9ybWF0OworICAgIGJvb2wgdmFsaWQgPSB1aW50MzJfdChmb3JtYXQpIDwgbnVtRW50cmllczsKKyAgICBpZiAoIXZhbGlkKSB7CisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgfQorICAgIAorICAgICNkZWZpbmUgQ09NUE9ORU5UKG5hbWUpIFwgCisgICAgICAgIGNhc2UgR0dMXyMjbmFtZTogaW5mby0+Y29tcG9uZW50cyA9IFBpeGVsRm9ybWF0SW5mbzo6bmFtZTsgYnJlYWs7CisgICAgCisgICAgc3dpdGNoIChpLT5jb21wb25lbnRzKSB7CisgICAgICAgIENPTVBPTkVOVChBTFBIQSkKKyAgICAgICAgQ09NUE9ORU5UKFJHQikKKyAgICAgICAgQ09NUE9ORU5UKFJHQkEpCisgICAgICAgIENPTVBPTkVOVChMVU1JTkFOQ0UpCisgICAgICAgIENPTVBPTkVOVChMVU1JTkFOQ0VfQUxQSEEpCisgICAgICAgIENPTVBPTkVOVChZX0NCX0NSX1NQKQorICAgICAgICBDT01QT05FTlQoWV9DQl9DUl9QKQorICAgICAgICBDT01QT05FTlQoWV9DQl9DUl9JKQorICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJBRF9JTkRFWDsKKyAgICB9CisgICAgCisgICAgI3VuZGVmIENPTVBPTkVOVAorICAgIAorICAgIGluZm8tPmZvcm1hdCA9IGZvcm1hdDsKKyAgICBpbmZvLT5ieXRlc1BlclBpeGVsID0gaS0+c2l6ZTsKKyAgICBpbmZvLT5iaXRzUGVyUGl4ZWwgID0gaS0+Yml0c1BlclBpeGVsOworICAgIGluZm8tPmhfYWxwaGEgICAgICAgPSBpLT5haDsKKyAgICBpbmZvLT5sX2FscGhhICAgICAgID0gaS0+YWw7CisgICAgaW5mby0+aF9yZWQgICAgICAgICA9IGktPnJoOworICAgIGluZm8tPmxfcmVkICAgICAgICAgPSBpLT5ybDsKKyAgICBpbmZvLT5oX2dyZWVuICAgICAgID0gaS0+Z2g7CisgICAgaW5mby0+bF9ncmVlbiAgICAgICA9IGktPmdsOworICAgIGluZm8tPmhfYmx1ZSAgICAgICAgPSBpLT5iaDsKKyAgICBpbmZvLT5sX2JsdWUgICAgICAgID0gaS0+Ymw7CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdWkvUG9pbnQuY3BwIGIvbGlicy91aS9Qb2ludC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDM4ZDQ5ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvUG9pbnQuY3BwCkBAIC0wLDAgKzEsMTEgQEAKKy8qCisgKiAgUG9pbnQuY3BwCisgKiAgQW5kcm9pZAorICoKKyAqICBDcmVhdGVkIG9uIDExLzE2LzIwMDYuCisgKiAgQ29weXJpZ2h0IDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqLworCisjaW5jbHVkZSA8dWkvUG9pbnQuaD4KKwpkaWZmIC0tZ2l0IGEvbGlicy91aS9SZWN0LmNwcCBiL2xpYnMvdWkvUmVjdC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTllNjhiYgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvUmVjdC5jcHAKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBSZWN0LmNwcAorICogIEFuZHJvaWQKKyAqCisgKiAgQ3JlYXRlZCBvbiAxMC8xNC8wNS4KKyAqICBDb3B5cmlnaHQgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICovCisKKyNpbmNsdWRlIDx1aS9SZWN0Lmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworaW5saW5lIGludCBtaW4oaW50IGEsIGludCBiKSB7CisgICAgcmV0dXJuIChhPGIpID8gYSA6IGI7Cit9CisKK2lubGluZSBpbnQgbWF4KGludCBhLCBpbnQgYikgeworICAgIHJldHVybiAoYT5iKSA/IGEgOiBiOworfQorCit2b2lkIFJlY3Q6Om1ha2VJbnZhbGlkKCkgeworICAgIGxlZnQgPSAwOworICAgIHRvcCA9IDA7CisgICAgcmlnaHQgPSAtMTsKKyAgICBib3R0b20gPSAtMTsKK30KKworYm9vbCBSZWN0OjpvcGVyYXRvciA8IChjb25zdCBSZWN0JiByaHMpIGNvbnN0Cit7CisgICAgaWYgKHRvcDxyaHMudG9wKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSBpZiAodG9wID09IHJocy50b3ApIHsKKyAgICAgICAgaWYgKGxlZnQgPCByaHMubGVmdCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAobGVmdCA9PSByaHMubGVmdCkgeworICAgICAgICAgICAgaWYgKGJvdHRvbTxyaHMuYm90dG9tKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGJvdHRvbSA9PSByaHMuYm90dG9tKSB7CisgICAgICAgICAgICAgICAgaWYgKHJpZ2h0PHJocy5yaWdodCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworfQorCitSZWN0JiBSZWN0OjpvZmZzZXRUbyhpbnQgeCwgaW50IHkpCit7CisgICAgcmlnaHQgLT0gbGVmdCAtIHg7CisgICAgYm90dG9tIC09IHRvcCAtIHk7CisgICAgbGVmdCA9IHg7CisgICAgdG9wID0geTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK1JlY3QmIFJlY3Q6Om9mZnNldEJ5KGludCB4LCBpbnQgeSkKK3sKKyAgICBsZWZ0ICs9IHg7CisgICAgdG9wICArPSB5OworICAgIHJpZ2h0Kz0geDsKKyAgICBib3R0b20rPXk7CisgICAgcmV0dXJuICp0aGlzOworfQorCitSZWN0IFJlY3Q6Om9wZXJhdG9yICsgKGNvbnN0IFBvaW50JiByaHMpIGNvbnN0Cit7CisgICAgcmV0dXJuIFJlY3QobGVmdCtyaHMueCwgdG9wK3Jocy55LCByaWdodCtyaHMueCwgYm90dG9tK3Jocy55KTsgCit9CisKK1JlY3QgUmVjdDo6b3BlcmF0b3IgLSAoY29uc3QgUG9pbnQmIHJocykgY29uc3QKK3sKKyAgICByZXR1cm4gUmVjdChsZWZ0LXJocy54LCB0b3AtcmhzLnksIHJpZ2h0LXJocy54LCBib3R0b20tcmhzLnkpOyAKK30KKworYm9vbCBSZWN0OjppbnRlcnNlY3QoY29uc3QgUmVjdCYgd2l0aCwgUmVjdCogcmVzdWx0KSBjb25zdAoreworICAgIHJlc3VsdC0+bGVmdCAgICA9IG1heChsZWZ0LCB3aXRoLmxlZnQpOworICAgIHJlc3VsdC0+dG9wICAgICA9IG1heCh0b3AsIHdpdGgudG9wKTsKKyAgICByZXN1bHQtPnJpZ2h0ICAgPSBtaW4ocmlnaHQsIHdpdGgucmlnaHQpOworICAgIHJlc3VsdC0+Ym90dG9tICA9IG1pbihib3R0b20sIHdpdGguYm90dG9tKTsKKyAgICByZXR1cm4gIShyZXN1bHQtPmlzRW1wdHkoKSk7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3VpL1JlZ2lvbi5jcHAgYi9saWJzL3VpL1JlZ2lvbi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjZlNjk0YQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvUmVnaW9uLmNwcApAQCAtMCwwICsxLDMxMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiUmVnaW9uIgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9EZWJ1Zy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1aS9SZWdpb24uaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1JlZ2lvbjo6UmVnaW9uKCkKK3sKK30KKworUmVnaW9uOjpSZWdpb24oY29uc3QgUmVnaW9uJiByaHMpCisgICAgOiBtUmVnaW9uKHJocy5tUmVnaW9uKQoreworfQorCitSZWdpb246OlJlZ2lvbihjb25zdCBTa1JlZ2lvbiYgcmhzKQorICAgIDogbVJlZ2lvbihyaHMpCit7Cit9CisKK1JlZ2lvbjo6flJlZ2lvbigpCit7Cit9CisKK1JlZ2lvbjo6UmVnaW9uKGNvbnN0IFJlY3QmIHJocykKK3sKKyAgICBzZXQocmhzKTsKK30KKworUmVnaW9uOjpSZWdpb24oY29uc3QgUGFyY2VsJiBwYXJjZWwpCit7CisgICAgcmVhZChwYXJjZWwpOworfQorCitSZWdpb246OlJlZ2lvbihjb25zdCB2b2lkKiBidWZmZXIpCit7CisgICAgcmVhZChidWZmZXIpOworfQorCitSZWdpb24mIFJlZ2lvbjo6b3BlcmF0b3IgPSAoY29uc3QgUmVnaW9uJiByaHMpCit7CisgICAgbVJlZ2lvbiA9IHJocy5tUmVnaW9uOworICAgIHJldHVybiAqdGhpczsKK30KKworY29uc3QgU2tSZWdpb24mIFJlZ2lvbjo6dG9Ta1JlZ2lvbigpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1SZWdpb247Cit9CisKK1JlY3QgUmVnaW9uOjpib3VuZHMoKSBjb25zdAoreworICAgIGNvbnN0IFNrSVJlY3QmIGIobVJlZ2lvbi5nZXRCb3VuZHMoKSk7CisgICAgcmV0dXJuIFJlY3QoYi5mTGVmdCwgYi5mVG9wLCBiLmZSaWdodCwgYi5mQm90dG9tKTsKK30KKwordm9pZCBSZWdpb246OmNsZWFyKCkKK3sKKyAgICBtUmVnaW9uLnNldEVtcHR5KCk7Cit9CisKK3ZvaWQgUmVnaW9uOjpzZXQoY29uc3QgUmVjdCYgcikKK3sKKyAgICBTa0lSZWN0IGlyOworICAgIGlyLnNldChyLmxlZnQsIHIudG9wLCByLnJpZ2h0LCByLmJvdHRvbSk7CisgICAgbVJlZ2lvbi5zZXRSZWN0KGlyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZWdpb24mIFJlZ2lvbjo6b3JTZWxmKGNvbnN0IFJlY3QmIHIpCit7CisgICAgU2tJUmVjdCBpcjsKKyAgICBpci5zZXQoci5sZWZ0LCByLnRvcCwgci5yaWdodCwgci5ib3R0b20pOworICAgIG1SZWdpb24ub3AoaXIsIFNrUmVnaW9uOjprVW5pb25fT3ApOworICAgIHJldHVybiAqdGhpczsKK30KKworUmVnaW9uJiBSZWdpb246OmFuZFNlbGYoY29uc3QgUmVjdCYgcikKK3sKKyAgICBTa0lSZWN0IGlyOworICAgIGlyLnNldChyLmxlZnQsIHIudG9wLCByLnJpZ2h0LCByLmJvdHRvbSk7CisgICAgbVJlZ2lvbi5vcChpciwgU2tSZWdpb246OmtJbnRlcnNlY3RfT3ApOworICAgIHJldHVybiAqdGhpczsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZWdpb24mIFJlZ2lvbjo6b3JTZWxmKGNvbnN0IFJlZ2lvbiYgcmhzKSB7CisgICAgbVJlZ2lvbi5vcChyaHMubVJlZ2lvbiwgU2tSZWdpb246OmtVbmlvbl9PcCk7CisgICAgcmV0dXJuICp0aGlzOworfQorCitSZWdpb24mIFJlZ2lvbjo6YW5kU2VsZihjb25zdCBSZWdpb24mIHJocykgeworICAgIG1SZWdpb24ub3AocmhzLm1SZWdpb24sIFNrUmVnaW9uOjprSW50ZXJzZWN0X09wKTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK1JlZ2lvbiYgUmVnaW9uOjpzdWJ0cmFjdFNlbGYoY29uc3QgUmVnaW9uJiByaHMpIHsKKyAgICBtUmVnaW9uLm9wKHJocy5tUmVnaW9uLCBTa1JlZ2lvbjo6a0RpZmZlcmVuY2VfT3ApOworICAgIHJldHVybiAqdGhpczsKK30KKworUmVnaW9uJiBSZWdpb246OnRyYW5zbGF0ZVNlbGYoaW50IHgsIGludCB5KSB7CisgICAgaWYgKHh8eSkgbVJlZ2lvbi50cmFuc2xhdGUoeCwgeSk7CisgICAgcmV0dXJuICp0aGlzOworfQorCitSZWdpb24gUmVnaW9uOjptZXJnZShjb25zdCBSZWdpb24mIHJocykgY29uc3QgeworICAgIFJlZ2lvbiByZXN1bHQ7CisgICAgcmVzdWx0Lm1SZWdpb24ub3AobVJlZ2lvbiwgcmhzLm1SZWdpb24sIFNrUmVnaW9uOjprVW5pb25fT3ApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1JlZ2lvbiBSZWdpb246OmludGVyc2VjdChjb25zdCBSZWdpb24mIHJocykgY29uc3QgeworICAgIFJlZ2lvbiByZXN1bHQ7CisgICAgcmVzdWx0Lm1SZWdpb24ub3AobVJlZ2lvbiwgcmhzLm1SZWdpb24sIFNrUmVnaW9uOjprSW50ZXJzZWN0X09wKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitSZWdpb24gUmVnaW9uOjpzdWJ0cmFjdChjb25zdCBSZWdpb24mIHJocykgY29uc3QgeworICAgIFJlZ2lvbiByZXN1bHQ7CisgICAgcmVzdWx0Lm1SZWdpb24ub3AobVJlZ2lvbiwgcmhzLm1SZWdpb24sIFNrUmVnaW9uOjprRGlmZmVyZW5jZV9PcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUmVnaW9uIFJlZ2lvbjo6dHJhbnNsYXRlKGludCB4LCBpbnQgeSkgY29uc3QgeworICAgIFJlZ2lvbiByZXN1bHQ7CisgICAgbVJlZ2lvbi50cmFuc2xhdGUoeCwgeSwgJnJlc3VsdC5tUmVnaW9uKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1JlZ2lvbiYgUmVnaW9uOjpvclNlbGYoY29uc3QgUmVnaW9uJiByaHMsIGludCBkeCwgaW50IGR5KSB7CisgICAgU2tSZWdpb24gcihyaHMubVJlZ2lvbik7CisgICAgci50cmFuc2xhdGUoZHgsIGR5KTsKKyAgICBtUmVnaW9uLm9wKHIsIFNrUmVnaW9uOjprVW5pb25fT3ApOworICAgIHJldHVybiAqdGhpczsKK30KKworUmVnaW9uJiBSZWdpb246OmFuZFNlbGYoY29uc3QgUmVnaW9uJiByaHMsIGludCBkeCwgaW50IGR5KSB7CisgICAgU2tSZWdpb24gcihyaHMubVJlZ2lvbik7CisgICAgci50cmFuc2xhdGUoZHgsIGR5KTsKKyAgICBtUmVnaW9uLm9wKHIsIFNrUmVnaW9uOjprSW50ZXJzZWN0X09wKTsKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKK1JlZ2lvbiYgUmVnaW9uOjpzdWJ0cmFjdFNlbGYoY29uc3QgUmVnaW9uJiByaHMsIGludCBkeCwgaW50IGR5KSB7CisgICAgU2tSZWdpb24gcihyaHMubVJlZ2lvbik7CisgICAgci50cmFuc2xhdGUoZHgsIGR5KTsKKyAgICBtUmVnaW9uLm9wKHIsIFNrUmVnaW9uOjprRGlmZmVyZW5jZV9PcCk7CisgICAgcmV0dXJuICp0aGlzOworfQorCitSZWdpb24gUmVnaW9uOjptZXJnZShjb25zdCBSZWdpb24mIHJocywgaW50IGR4LCBpbnQgZHkpIGNvbnN0IHsKKyAgICBSZWdpb24gcmVzdWx0OworICAgIFNrUmVnaW9uIHIocmhzLm1SZWdpb24pOworICAgIHIudHJhbnNsYXRlKGR4LCBkeSk7CisgICAgcmVzdWx0Lm1SZWdpb24ub3AobVJlZ2lvbiwgciwgU2tSZWdpb246OmtVbmlvbl9PcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUmVnaW9uIFJlZ2lvbjo6aW50ZXJzZWN0KGNvbnN0IFJlZ2lvbiYgcmhzLCBpbnQgZHgsIGludCBkeSkgY29uc3QgeworICAgIFJlZ2lvbiByZXN1bHQ7CisgICAgU2tSZWdpb24gcihyaHMubVJlZ2lvbik7CisgICAgci50cmFuc2xhdGUoZHgsIGR5KTsKKyAgICByZXN1bHQubVJlZ2lvbi5vcChtUmVnaW9uLCByLCBTa1JlZ2lvbjo6a0ludGVyc2VjdF9PcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUmVnaW9uIFJlZ2lvbjo6c3VidHJhY3QoY29uc3QgUmVnaW9uJiByaHMsIGludCBkeCwgaW50IGR5KSBjb25zdCB7CisgICAgUmVnaW9uIHJlc3VsdDsKKyAgICBTa1JlZ2lvbiByKHJocy5tUmVnaW9uKTsKKyAgICByLnRyYW5zbGF0ZShkeCwgZHkpOworICAgIHJlc3VsdC5tUmVnaW9uLm9wKG1SZWdpb24sIHIsIFNrUmVnaW9uOjprRGlmZmVyZW5jZV9PcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZWdpb246Oml0ZXJhdG9yOjppdGVyYXRvcihjb25zdCBSZWdpb24mIHIpCisgICAgOiBtSXQoci5tUmVnaW9uKQoreworfQorCitpbnQgUmVnaW9uOjppdGVyYXRvcjo6aXRlcmF0ZShSZWN0KiByZWN0KQoreworICAgIGlmIChtSXQuZG9uZSgpKQorICAgICAgICByZXR1cm4gMDsKKyAgICBjb25zdCBTa0lSZWN0JiByKG1JdC5yZWN0KCkpOworICAgIHJlY3QtPmxlZnQgID0gci5mTGVmdDsKKyAgICByZWN0LT50b3AgICA9IHIuZlRvcDsKKyAgICByZWN0LT5yaWdodCA9IHIuZlJpZ2h0OworICAgIHJlY3QtPmJvdHRvbT0gci5mQm90dG9tOworICAgIG1JdC5uZXh0KCk7CisgICAgcmV0dXJuIDE7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gd2Ugd3JpdGUgYSA0Ynl0ZSBzaXplIGFoZWFkIG9mIHRoZSBhY3R1YWwgcmVnaW9uLCBzbyB3ZSBrbm93IGhvdyBtdWNoIHdlJ2xsIG5lZWQgZm9yIHJlYWRpbmcKKworc3RhdHVzX3QgUmVnaW9uOjp3cml0ZShQYXJjZWwmIHBhcmNlbCkgY29uc3QKK3sKKyAgICBpbnQzMl90IHNpemUgPSBtUmVnaW9uLmZsYXR0ZW4oTlVMTCk7CisgICAgcGFyY2VsLndyaXRlSW50MzIoc2l6ZSk7CisgICAgbVJlZ2lvbi5mbGF0dGVuKHBhcmNlbC53cml0ZUlucGxhY2Uoc2l6ZSkpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgUmVnaW9uOjpyZWFkKGNvbnN0IFBhcmNlbCYgcGFyY2VsKQoreworICAgIHNpemVfdCBzaXplID0gcGFyY2VsLnJlYWRJbnQzMigpOworICAgIG1SZWdpb24udW5mbGF0dGVuKHBhcmNlbC5yZWFkSW5wbGFjZShzaXplKSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzc2l6ZV90IFJlZ2lvbjo6d3JpdGUodm9pZCogYnVmZmVyLCBzaXplX3Qgc2l6ZSkgY29uc3QKK3sKKyAgICBzaXplX3Qgc2l6ZU5lZWRlZCA9IG1SZWdpb24uZmxhdHRlbihOVUxMKTsKKyAgICBpZiAoc2l6ZU5lZWRlZCA+IHNpemUpIHJldHVybiBOT19NRU1PUlk7CisgICAgcmV0dXJuIG1SZWdpb24uZmxhdHRlbihidWZmZXIpOworfQorCitzc2l6ZV90IFJlZ2lvbjo6cmVhZChjb25zdCB2b2lkKiBidWZmZXIpCit7CisgICAgcmV0dXJuIG1SZWdpb24udW5mbGF0dGVuKGJ1ZmZlcik7Cit9CisKK3NzaXplX3QgUmVnaW9uOjp3cml0ZUVtcHR5KHZvaWQqIGJ1ZmZlciwgc2l6ZV90IHNpemUpCit7CisgICAgaWYgKHNpemUgPCA0KSByZXR1cm4gTk9fTUVNT1JZOworICAgIC8vIHRoaXMgbmVlZHMgdG8gc3RheSBpbiBzeW5jIHdpdGggU2tSZWdpb24KKyAgICAqc3RhdGljX2Nhc3Q8aW50MzJfdCo+KGJ1ZmZlcikgPSAtMTsKKyAgICByZXR1cm4gNDsKK30KKworYm9vbCBSZWdpb246OmlzRW1wdHkodm9pZCogYnVmZmVyKQoreworICAgIC8vIHRoaXMgbmVlZHMgdG8gc3RheSBpbiBzeW5jIHdpdGggU2tSZWdpb24KKyAgICByZXR1cm4gKnN0YXRpY19jYXN0PGludDMyX3QqPihidWZmZXIpID09IC0xOworfQorCitzaXplX3QgUmVnaW9uOjpyZWN0cyhWZWN0b3I8UmVjdD4mIHJlY3RMaXN0KSBjb25zdAoreworICAgIHJlY3RMaXN0LmNsZWFyKCk7CisgICAgaWYgKCFpc0VtcHR5KCkpIHsKKyAgICAgICAgU2tSZWdpb246Okl0ZXJhdG9yIGl0ZXJhdG9yKG1SZWdpb24pOworICAgICAgICB3aGlsZSggIWl0ZXJhdG9yLmRvbmUoKSApIHsKKyAgICAgICAgICAgIGNvbnN0IFNrSVJlY3QmIGlyKGl0ZXJhdG9yLnJlY3QoKSk7CisgICAgICAgICAgICByZWN0TGlzdC5wdXNoKFJlY3QoaXIuZkxlZnQsIGlyLmZUb3AsIGlyLmZSaWdodCwgaXIuZkJvdHRvbSkpOworICAgICAgICAgICAgaXRlcmF0b3IubmV4dCgpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZWN0TGlzdC5zaXplKCk7Cit9CisKK3ZvaWQgUmVnaW9uOjpkdW1wKFN0cmluZzgmIG91dCwgY29uc3QgY2hhciogd2hhdCwgdWludDMyX3QgZmxhZ3MpIGNvbnN0Cit7CisgICAgKHZvaWQpZmxhZ3M7CisgICAgVmVjdG9yPFJlY3Q+IHI7CisgICAgcmVjdHMocik7CisgICAgCisgICAgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgCisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiICBSZWdpb24gJXMgKHRoaXM9JXAsIGNvdW50PSVkKVxuIiwgd2hhdCwgdGhpcywgci5zaXplKCkpOworICAgIG91dC5hcHBlbmQoYnVmZmVyKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPHIuc2l6ZSgpIDsgaSsrKSB7CisgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIiAgICBbJTNkLCAlM2QsICUzZCwgJTNkXVxuIiwKKyAgICAgICAgICAgIHJbaV0ubGVmdCwgcltpXS50b3AscltpXS5yaWdodCxyW2ldLmJvdHRvbSk7CisgICAgICAgIG91dC5hcHBlbmQoYnVmZmVyKTsKKyAgICB9Cit9CisKK3ZvaWQgUmVnaW9uOjpkdW1wKGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzKSBjb25zdAoreworICAgICh2b2lkKWZsYWdzOworICAgIFZlY3RvcjxSZWN0PiByOworICAgIHJlY3RzKHIpOworICAgIExPR0QoIiAgUmVnaW9uICVzICh0aGlzPSVwLCBjb3VudD0lZClcbiIsIHdoYXQsIHRoaXMsIHIuc2l6ZSgpKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPHIuc2l6ZSgpIDsgaSsrKSB7CisgICAgICAgIExPR0QoIiAgICBbJTNkLCAlM2QsICUzZCwgJTNkXVxuIiwKKyAgICAgICAgICAgIHJbaV0ubGVmdCwgcltpXS50b3AscltpXS5yaWdodCxyW2ldLmJvdHRvbSk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3VpL1N1cmZhY2UuY3BwIGIvbGlicy91aS9TdXJmYWNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWE5YWUyCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9TdXJmYWNlLmNwcApAQCAtMCwwICsxLDI1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3VyZmFjZSIKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0lQQ1RocmVhZFN0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvSU1lbW9yeS5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8dWkvSVN1cmZhY2UuaD4KKyNpbmNsdWRlIDx1aS9TdXJmYWNlLmg+CisjaW5jbHVkZSA8dWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50Lmg+CisjaW5jbHVkZSA8dWkvUmVjdC5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91aS9TaGFyZWRTdGF0ZS5oPgorI2luY2x1ZGUgPHByaXZhdGUvdWkvTGF5ZXJTdGF0ZS5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTdXJmYWNlOjpTdXJmYWNlKGNvbnN0IHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4mIGNsaWVudCwgCisgICAgICAgIGNvbnN0IHNwPElTdXJmYWNlPiYgc3VyZmFjZSwKKyAgICAgICAgY29uc3QgSVN1cmZhY2VGbGluZ2VyQ2xpZW50OjpzdXJmYWNlX2RhdGFfdCYgZGF0YSwKKyAgICAgICAgdWludDMyX3QgdywgdWludDMyX3QgaCwgUGl4ZWxGb3JtYXQgZm9ybWF0LCB1aW50MzJfdCBmbGFncywKKyAgICAgICAgYm9vbCBvd25lcikKKyAgICA6IG1DbGllbnQoY2xpZW50KSwgbVN1cmZhY2Uoc3VyZmFjZSksCisgICAgICBtVG9rZW4oZGF0YS50b2tlbiksIG1JZGVudGl0eShkYXRhLmlkZW50aXR5KSwKKyAgICAgIG1Gb3JtYXQoZm9ybWF0KSwgbUZsYWdzKGZsYWdzKSwgbU93bmVyKG93bmVyKQoreworICAgIG1Td2FwUmVjdGFuZ2xlLm1ha2VJbnZhbGlkKCk7CisgICAgbVN1cmZhY2VIZWFwQmFzZVswXSA9IDA7CisgICAgbVN1cmZhY2VIZWFwQmFzZVsxXSA9IDA7CisgICAgbUhlYXBbMF0gPSBkYXRhLmhlYXBbMF07IAorICAgIG1IZWFwWzFdID0gZGF0YS5oZWFwWzFdOworfQorCitTdXJmYWNlOjpTdXJmYWNlKFN1cmZhY2UgY29uc3QqIHJocykKKyAgICA6IG1Pd25lcihmYWxzZSkKK3sKKyAgICBtVG9rZW4gICA9IHJocy0+bVRva2VuOworICAgIG1JZGVudGl0eT0gcmhzLT5tSWRlbnRpdHk7CisgICAgbUNsaWVudCAgPSByaHMtPm1DbGllbnQ7CisgICAgbVN1cmZhY2UgPSByaHMtPm1TdXJmYWNlOworICAgIG1IZWFwWzBdID0gcmhzLT5tSGVhcFswXTsKKyAgICBtSGVhcFsxXSA9IHJocy0+bUhlYXBbMV07CisgICAgbUZvcm1hdCAgPSByaHMtPm1Gb3JtYXQ7CisgICAgbUZsYWdzICAgPSByaHMtPm1GbGFnczsKKyAgICBtU3VyZmFjZUhlYXBCYXNlWzBdID0gcmhzLT5tU3VyZmFjZUhlYXBCYXNlWzBdOworICAgIG1TdXJmYWNlSGVhcEJhc2VbMV0gPSByaHMtPm1TdXJmYWNlSGVhcEJhc2VbMV07CisgICAgbVN3YXBSZWN0YW5nbGUubWFrZUludmFsaWQoKTsKK30KKworU3VyZmFjZTo6flN1cmZhY2UoKQoreworICAgIGlmIChtT3duZXIgJiYgbVRva2VuPj0wICYmIG1DbGllbnQhPTApIHsKKyAgICAgICAgbUNsaWVudC0+ZGVzdHJveVN1cmZhY2UobVRva2VuKTsKKyAgICB9CisgICAgbUNsaWVudC5jbGVhcigpOworICAgIG1TdXJmYWNlLmNsZWFyKCk7CisgICAgbUhlYXBbMF0uY2xlYXIoKTsKKyAgICBtSGVhcFsxXS5jbGVhcigpOworICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmZsdXNoQ29tbWFuZHMoKTsKK30KKworc3A8U3VyZmFjZT4gU3VyZmFjZTo6ZHVwKCkgY29uc3QKK3sKKyAgICBTdXJmYWNlIGNvbnN0ICogciA9IHRoaXM7CisgICAgaWYgKHRoaXMgJiYgbU93bmVyKSB7CisgICAgICAgIC8vIHRoZSBvbmx5IHJlYXNvbiB3ZSBuZWVkIHRvIGRvIHRoaXMgaXMgYmVjYXVzZSBvZiBKYXZhJ3MgZ2FyYmFnZQorICAgICAgICAvLyBjb2xsZWN0b3I6IGJlY2F1c2Ugd2UncmUgY3JlYXRpbmcgYSBjb3B5IG9mIHRoZSBTdXJmYWNlCisgICAgICAgIC8vIGluc3RlYWQgb2YgYSByZWZlcmVuY2UsIHdlIGNhbiBnYXJhbnRlZSB0aGF0IHdoZW4gb3VyIGxhc3QKKyAgICAgICAgLy8gcmVmZXJlbmNlIGdvZXMgYXdheSwgdGhlIHJlYWwgc3VyZmFjZSB3aWxsIGJlIGRlbGV0ZWQuCisgICAgICAgIC8vIFdpdGhvdXQgdGhpcyBoYWNrICh0aGUgY29kZSBpcyBjb3JyZWN0IHRvbyksIHdlJ2QgaGF2ZSB0bworICAgICAgICAvLyB3YWl0IGZvciBhIEdDIGZvciB0aGUgc3VyZmFjZSB0byBnbyBhd2F5LgorICAgICAgICByID0gbmV3IFN1cmZhY2UodGhpcyk7ICAgICAgICAKKyAgICB9CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8U3VyZmFjZSo+KHIpOworfQorCitzdGF0dXNfdCBTdXJmYWNlOjpuZXh0QnVmZmVyKFN1cmZhY2VJbmZvKiBpbmZvKSB7CisgICAgcmV0dXJuIG1DbGllbnQtPm5leHRCdWZmZXIodGhpcywgaW5mbyk7Cit9CisKK3N0YXR1c190IFN1cmZhY2U6OmxvY2soU3VyZmFjZUluZm8qIGluZm8sIGJvb2wgYmxvY2tpbmcpIHsKKyAgICByZXR1cm4gU3VyZmFjZTo6bG9jayhpbmZvLCBOVUxMLCBibG9ja2luZyk7Cit9CisKK3N0YXR1c190IFN1cmZhY2U6OmxvY2soU3VyZmFjZUluZm8qIGluZm8sIFJlZ2lvbiogZGlydHksIGJvb2wgYmxvY2tpbmcpIHsKKyAgICBpZiAoaGVhcEJhc2UoMCkgPT0gMCkgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworICAgIGlmIChoZWFwQmFzZSgxKSA9PSAwKSByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgcmV0dXJuIG1DbGllbnQtPmxvY2tTdXJmYWNlKHRoaXMsIGluZm8sIGRpcnR5LCBibG9ja2luZyk7Cit9CisKK3N0YXR1c190IFN1cmZhY2U6OnVubG9ja0FuZFBvc3QoKSB7CisgICAgaWYgKGhlYXBCYXNlKDApID09IDApIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICBpZiAoaGVhcEJhc2UoMSkgPT0gMCkgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworICAgIHJldHVybiBtQ2xpZW50LT51bmxvY2tBbmRQb3N0U3VyZmFjZSh0aGlzKTsKK30KKworc3RhdHVzX3QgU3VyZmFjZTo6dW5sb2NrKCkgeworICAgIGlmIChoZWFwQmFzZSgwKSA9PSAwKSByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgaWYgKGhlYXBCYXNlKDEpID09IDApIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICByZXR1cm4gbUNsaWVudC0+dW5sb2NrU3VyZmFjZSh0aGlzKTsKK30KKworc3RhdHVzX3QgU3VyZmFjZTo6c2V0TGF5ZXIoaW50MzJfdCBsYXllcikgeworICAgIHJldHVybiBtQ2xpZW50LT5zZXRMYXllcih0aGlzLCBsYXllcik7Cit9CitzdGF0dXNfdCBTdXJmYWNlOjpzZXRQb3NpdGlvbihpbnQzMl90IHgsIGludDMyX3QgeSkgeworICAgIHJldHVybiBtQ2xpZW50LT5zZXRQb3NpdGlvbih0aGlzLCB4LCB5KTsKK30KK3N0YXR1c190IFN1cmZhY2U6OnNldFNpemUodWludDMyX3QgdywgdWludDMyX3QgaCkgeworICAgIHJldHVybiBtQ2xpZW50LT5zZXRTaXplKHRoaXMsIHcsIGgpOworfQorc3RhdHVzX3QgU3VyZmFjZTo6aGlkZSgpIHsKKyAgICByZXR1cm4gbUNsaWVudC0+aGlkZSh0aGlzKTsKK30KK3N0YXR1c190IFN1cmZhY2U6OnNob3coaW50MzJfdCBsYXllcikgeworICAgIHJldHVybiBtQ2xpZW50LT5zaG93KHRoaXMsIGxheWVyKTsKK30KK3N0YXR1c190IFN1cmZhY2U6OmZyZWV6ZSgpIHsKKyAgICByZXR1cm4gbUNsaWVudC0+ZnJlZXplKHRoaXMpOworfQorc3RhdHVzX3QgU3VyZmFjZTo6dW5mcmVlemUoKSB7CisgICAgcmV0dXJuIG1DbGllbnQtPnVuZnJlZXplKHRoaXMpOworfQorc3RhdHVzX3QgU3VyZmFjZTo6c2V0RmxhZ3ModWludDMyX3QgZmxhZ3MsIHVpbnQzMl90IG1hc2spIHsKKyAgICByZXR1cm4gbUNsaWVudC0+c2V0RmxhZ3ModGhpcywgZmxhZ3MsIG1hc2spOworfQorc3RhdHVzX3QgU3VyZmFjZTo6c2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KGNvbnN0IFJlZ2lvbiYgdHJhbnNwYXJlbnQpIHsKKyAgICByZXR1cm4gbUNsaWVudC0+c2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KHRoaXMsIHRyYW5zcGFyZW50KTsKK30KK3N0YXR1c190IFN1cmZhY2U6OnNldEFscGhhKGZsb2F0IGFscGhhKSB7CisgICAgcmV0dXJuIG1DbGllbnQtPnNldEFscGhhKHRoaXMsIGFscGhhKTsKK30KK3N0YXR1c190IFN1cmZhY2U6OnNldE1hdHJpeChmbG9hdCBkc2R4LCBmbG9hdCBkdGR4LCBmbG9hdCBkc2R5LCBmbG9hdCBkdGR5KSB7CisgICAgcmV0dXJuIG1DbGllbnQtPnNldE1hdHJpeCh0aGlzLCBkc2R4LCBkdGR4LCBkc2R5LCBkdGR5KTsKK30KK3N0YXR1c190IFN1cmZhY2U6OnNldEZyZWV6ZVRpbnQodWludDMyX3QgdGludCkgeworICAgIHJldHVybiBtQ2xpZW50LT5zZXRGcmVlemVUaW50KHRoaXMsIHRpbnQpOworfQorCitSZWdpb24gU3VyZmFjZTo6ZGlydHlSZWdpb24oKSBjb25zdCAgeworICAgIHJldHVybiBtRGlydHlSZWdpb247IAorfQordm9pZCBTdXJmYWNlOjpzZXREaXJ0eVJlZ2lvbihjb25zdCBSZWdpb24mIHJlZ2lvbikgY29uc3QgeworICAgIG1EaXJ0eVJlZ2lvbiA9IHJlZ2lvbjsKK30KK2NvbnN0IFJlY3QmIFN1cmZhY2U6OnN3YXBSZWN0YW5nbGUoKSBjb25zdCB7CisgICAgcmV0dXJuIG1Td2FwUmVjdGFuZ2xlOworfQordm9pZCBTdXJmYWNlOjpzZXRTd2FwUmVjdGFuZ2xlKGNvbnN0IFJlY3QmIHIpIHsKKyAgICBtU3dhcFJlY3RhbmdsZSA9IHI7Cit9CisKK3NwPFN1cmZhY2U+IFN1cmZhY2U6OnJlYWRGcm9tUGFyY2VsKFBhcmNlbCogcGFyY2VsKQoreworICAgIHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4gY2xpZW50OworICAgIElTdXJmYWNlRmxpbmdlckNsaWVudDo6c3VyZmFjZV9kYXRhX3QgZGF0YTsKKyAgICBzcDxJQmluZGVyPiBjbGllbnRCaW5kZXI9IHBhcmNlbC0+cmVhZFN0cm9uZ0JpbmRlcigpOworICAgIHNwPElTdXJmYWNlPiBzdXJmYWNlICAgID0gaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2U+KHBhcmNlbC0+cmVhZFN0cm9uZ0JpbmRlcigpKTsKKyAgICBkYXRhLmhlYXBbMF0gICAgICAgICAgICA9IGludGVyZmFjZV9jYXN0PElNZW1vcnlIZWFwPihwYXJjZWwtPnJlYWRTdHJvbmdCaW5kZXIoKSk7CisgICAgZGF0YS5oZWFwWzFdICAgICAgICAgICAgPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5SGVhcD4ocGFyY2VsLT5yZWFkU3Ryb25nQmluZGVyKCkpOworICAgIGRhdGEudG9rZW4gICAgICAgICAgICAgID0gcGFyY2VsLT5yZWFkSW50MzIoKTsKKyAgICBkYXRhLmlkZW50aXR5ICAgICAgICAgICA9IHBhcmNlbC0+cmVhZEludDMyKCk7CisgICAgUGl4ZWxGb3JtYXQgZm9ybWF0ICAgICAgPSBwYXJjZWwtPnJlYWRJbnQzMigpOworICAgIHVpbnQzMl90IGZsYWdzICAgICAgICAgID0gcGFyY2VsLT5yZWFkSW50MzIoKTsKKworICAgIGlmIChjbGllbnRCaW5kZXIgIT0gTlVMTCkKKyAgICAgICAgY2xpZW50ID0gU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpjbGllbnRGb3JDb25uZWN0aW9uKGNsaWVudEJpbmRlcik7CisKKyAgICByZXR1cm4gbmV3IFN1cmZhY2UoY2xpZW50LCBzdXJmYWNlLCBkYXRhLCAwLCAwLCBmb3JtYXQsIGZsYWdzLCBmYWxzZSk7Cit9CisKK3N0YXR1c190IFN1cmZhY2U6OndyaXRlVG9QYXJjZWwoY29uc3Qgc3A8U3VyZmFjZT4mIHN1cmZhY2UsIFBhcmNlbCogcGFyY2VsKQoreworICAgIHVpbnQzMl90IGZsYWdzPTA7CisgICAgdWludDMyX3QgZm9ybWF0PTA7CisgICAgU3VyZmFjZUlEIHRva2VuID0gLTE7CisgICAgdWludDMyX3QgaWRlbnRpdHkgPSAwOworICAgIHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4gY2xpZW50OworICAgIHNwPElTdXJmYWNlPiBzdXI7CisgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXBbMl07CisgICAgaWYgKHN1cmZhY2UtPmlzVmFsaWQoKSkgeworICAgICAgICB0b2tlbiA9IHN1cmZhY2UtPm1Ub2tlbjsKKyAgICAgICAgaWRlbnRpdHkgPSBzdXJmYWNlLT5tSWRlbnRpdHk7CisgICAgICAgIGNsaWVudCA9IHN1cmZhY2UtPm1DbGllbnQ7CisgICAgICAgIHN1ciA9IHN1cmZhY2UtPm1TdXJmYWNlOworICAgICAgICBoZWFwWzBdID0gc3VyZmFjZS0+bUhlYXBbMF07CisgICAgICAgIGhlYXBbMV0gPSBzdXJmYWNlLT5tSGVhcFsxXTsKKyAgICAgICAgZm9ybWF0ID0gc3VyZmFjZS0+bUZvcm1hdDsKKyAgICAgICAgZmxhZ3MgPSBzdXJmYWNlLT5tRmxhZ3M7CisgICAgfQorICAgIHBhcmNlbC0+d3JpdGVTdHJvbmdCaW5kZXIoY2xpZW50IT0wICA/IGNsaWVudC0+Y29ubmVjdGlvbigpIDogTlVMTCk7CisgICAgcGFyY2VsLT53cml0ZVN0cm9uZ0JpbmRlcihzdXIhPTAgICAgID8gc3VyLT5hc0JpbmRlcigpICAgICAgOiBOVUxMKTsKKyAgICBwYXJjZWwtPndyaXRlU3Ryb25nQmluZGVyKGhlYXBbMF0hPTAgPyBoZWFwWzBdLT5hc0JpbmRlcigpICA6IE5VTEwpOworICAgIHBhcmNlbC0+d3JpdGVTdHJvbmdCaW5kZXIoaGVhcFsxXSE9MCA/IGhlYXBbMV0tPmFzQmluZGVyKCkgIDogTlVMTCk7CisgICAgcGFyY2VsLT53cml0ZUludDMyKHRva2VuKTsKKyAgICBwYXJjZWwtPndyaXRlSW50MzIoaWRlbnRpdHkpOworICAgIHBhcmNlbC0+d3JpdGVJbnQzMihmb3JtYXQpOworICAgIHBhcmNlbC0+d3JpdGVJbnQzMihmbGFncyk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitib29sIFN1cmZhY2U6OmlzU2FtZVN1cmZhY2UoY29uc3Qgc3A8U3VyZmFjZT4mIGxocywgY29uc3Qgc3A8U3VyZmFjZT4mIHJocykgCit7CisgICAgaWYgKGxocyA9PSAwIHx8IHJocyA9PSAwKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIGxocy0+bVN1cmZhY2UtPmFzQmluZGVyKCkgPT0gcmhzLT5tU3VyZmFjZS0+YXNCaW5kZXIoKTsKK30KKwordm9pZCogU3VyZmFjZTo6aGVhcEJhc2UoaW50IGkpIGNvbnN0IAoreworICAgIHZvaWQqIGhlYXBCYXNlID0gbVN1cmZhY2VIZWFwQmFzZVtpXTsKKyAgICAvLyBtYXAgbGF6aWx5IHNvIGl0IGRvZXNuJ3QgZ2V0IG1hcHBlZCBpbiBjbGllbnRzIHRoYXQgZG9uJ3QgbmVlZCBpdAorICAgIGlmIChoZWFwQmFzZSA9PSAwKSB7CisgICAgICAgIGNvbnN0IHNwPElNZW1vcnlIZWFwPiYgaGVhcChtSGVhcFtpXSk7CisgICAgICAgIGlmIChoZWFwICE9IDApIHsKKyAgICAgICAgICAgIGhlYXBCYXNlID0gc3RhdGljX2Nhc3Q8dWludDhfdCo+KGhlYXAtPmJhc2UoKSk7CisgICAgICAgICAgICBpZiAoaGVhcEJhc2UgPT0gTUFQX0ZBSUxFRCkgeworICAgICAgICAgICAgICAgIGhlYXBCYXNlID0gTlVMTDsKKyAgICAgICAgICAgICAgICBMT0dFKCJDb3VsZG4ndCBtYXAgU3VyZmFjZSdzIGhlYXAgKGJpbmRlcj0lcCwgaGVhcD0lcCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgaGVhcC0+YXNCaW5kZXIoKS5nZXQoKSwgaGVhcC5nZXQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtU3VyZmFjZUhlYXBCYXNlW2ldID0gaGVhcEJhc2U7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGhlYXBCYXNlOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL3VpL1N1cmZhY2VDb21wb3NlckNsaWVudC5jcHAgYi9saWJzL3VpL1N1cmZhY2VDb21wb3NlckNsaWVudC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTM1NGE3YQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdWkvU3VyZmFjZUNvbXBvc2VyQ2xpZW50LmNwcApAQCAtMCwwICsxLDEwMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN1cmZhY2VDb21wb3NlckNsaWVudCIKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorCisjaW5jbHVkZSA8Y3V0aWxzL21lbW9yeS5oPgorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0tleWVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDx1aS9JU3VyZmFjZUNvbXBvc2VyLmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2VGbGluZ2VyQ2xpZW50Lmg+CisjaW5jbHVkZSA8dWkvSVN1cmZhY2UuaD4KKyNpbmNsdWRlIDx1aS9TdXJmYWNlQ29tcG9zZXJDbGllbnQuaD4KKyNpbmNsdWRlIDx1aS9EaXNwbGF5SW5mby5oPgorI2luY2x1ZGUgPHVpL1JlY3QuaD4KKyNpbmNsdWRlIDx1aS9Qb2ludC5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91aS9TaGFyZWRTdGF0ZS5oPgorI2luY2x1ZGUgPHByaXZhdGUvdWkvTGF5ZXJTdGF0ZS5oPgorI2luY2x1ZGUgPHByaXZhdGUvdWkvU3VyZmFjZUZsaW5nZXJTeW5jaHJvLmg+CisKKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisKKyNpbmNsdWRlIDx1dGlscy9CcEJpbmRlci5oPgorCisjZGVmaW5lIFZFUkJPU0UoLi4uKQkoKHZvaWQpMCkKKy8vI2RlZmluZSBWRVJCT1NFCQkJTE9HRAorCisjZGVmaW5lIExJS0VMWSggZXhwICkgICAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIHRydWUgICkpCisjZGVmaW5lIFVOTElLRUxZKCBleHAgKSAgICAgKF9fYnVpbHRpbl9leHBlY3QoIChleHApICE9IDAsIGZhbHNlICkpCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE11c3Qgbm90IGJlIGhvbGRpbmcgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjptTG9jayB3aGVuIGFjcXVpcmluZyBnTG9jayBoZXJlLgorc3RhdGljIE11dGV4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ0xvY2s7CitzdGF0aWMgc3A8SVN1cmZhY2VDb21wb3Nlcj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnU3VyZmFjZU1hbmFnZXI7CitzdGF0aWMgRGVmYXVsdEtleWVkVmVjdG9yPCBzcDxJQmluZGVyPiwgc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiA+IGdBY3RpdmVDb25uZWN0aW9uczsKK3N0YXRpYyBTb3J0ZWRWZWN0b3I8c3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PiA+ICAgICAgICAgICAgIGdPcGVuVHJhbnNhY3Rpb25zOworc3RhdGljIHNwPElNZW1vcnk+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ1NlcnZlckNibGtNZW1vcnk7CitzdGF0aWMgdm9sYXRpbGUgc3VyZmFjZV9mbGluZ2VyX2NibGtfdCogICAgICAgICAgICAgICAgICAgICBnU2VydmVyQ2JsazsKKworY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIF9nZXRfc3VyZmFjZV9tYW5hZ2VyKCkKK3sKKyAgICBpZiAoZ1N1cmZhY2VNYW5hZ2VyICE9IDApIHsKKyAgICAgICAgcmV0dXJuIGdTdXJmYWNlTWFuYWdlcjsKKyAgICB9CisKKyAgICBzcDxJQmluZGVyPiBiaW5kZXI7CisgICAgc3A8SVNlcnZpY2VNYW5hZ2VyPiBzbSA9IGRlZmF1bHRTZXJ2aWNlTWFuYWdlcigpOworICAgIGRvIHsKKyAgICAgICAgYmluZGVyID0gc20tPmdldFNlcnZpY2UoU3RyaW5nMTYoIlN1cmZhY2VGbGluZ2VyIikpOworICAgICAgICBpZiAoYmluZGVyID09IDApIHsKKyAgICAgICAgICAgIExPR1coIlN1cmZhY2VGbGluZ2VyIG5vdCBwdWJsaXNoZWQsIHdhaXRpbmcuLi4iKTsKKyAgICAgICAgICAgIHVzbGVlcCg1MDAwMDApOyAvLyAwLjUgcworICAgICAgICB9CisgICAgfSB3aGlsZShiaW5kZXIgPT0gMCk7CisgICAgc3A8SVN1cmZhY2VDb21wb3Nlcj4gc2MoaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2VDb21wb3Nlcj4oYmluZGVyKSk7CisKKyAgICBNdXRleDo6QXV0b2xvY2sgX2woZ0xvY2spOworICAgIGlmIChnU3VyZmFjZU1hbmFnZXIgPT0gMCkgeworICAgICAgICBnU3VyZmFjZU1hbmFnZXIgPSBzYzsKKyAgICB9CisgICAgcmV0dXJuIGdTdXJmYWNlTWFuYWdlcjsKK30KKworc3RhdGljIHZvbGF0aWxlIHN1cmZhY2VfZmxpbmdlcl9jYmxrX3QgY29uc3QgKiBnZXRfY2JsaygpCit7CisgICAgaWYgKGdTZXJ2ZXJDYmxrID09IDApIHsKKyAgICAgICAgY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIHNtKF9nZXRfc3VyZmFjZV9tYW5hZ2VyKCkpOworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2woZ0xvY2spOworICAgICAgICBpZiAoZ1NlcnZlckNibGsgPT0gMCkgeworICAgICAgICAgICAgZ1NlcnZlckNibGtNZW1vcnkgPSBzbS0+Z2V0Q2JsaygpOworICAgICAgICAgICAgTE9HRV9JRihnU2VydmVyQ2Jsa01lbW9yeT09MCwgIkNhbid0IGdldCBzZXJ2ZXIgY29udHJvbCBibG9jayIpOworICAgICAgICAgICAgZ1NlcnZlckNibGsgPSAoc3VyZmFjZV9mbGluZ2VyX2NibGtfdCAqKWdTZXJ2ZXJDYmxrTWVtb3J5LT5wb2ludGVyKCk7CisgICAgICAgICAgICBMT0dFX0lGKGdTZXJ2ZXJDYmxrPT0wLCAiQ2FuJ3QgZ2V0IHNlcnZlciBjb250cm9sIGJsb2NrIGFkZHJlc3MiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZ1NlcnZlckNibGs7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBjb3B5Qmx0KGNvbnN0IEdHTFN1cmZhY2UmIGRzdCwKKyAgICAgICAgY29uc3QgR0dMU3VyZmFjZSYgc3JjLCBjb25zdCBSZWdpb24mIHJlZykKK3sKKyAgICBSZWdpb246Oml0ZXJhdG9yIGl0ZXJhdG9yKHJlZyk7CisgICAgaWYgKGl0ZXJhdG9yKSB7CisgICAgICAgIC8vIE5PVEU6IGRzdCBhbmQgc3JjIG11c3QgYmUgdGhlIHNhbWUgZm9ybWF0CisgICAgICAgIFJlY3QgcjsKKyAgICAgICAgY29uc3Qgc2l6ZV90IGJwcCA9IGJ5dGVzUGVyUGl4ZWwoc3JjLmZvcm1hdCk7CisgICAgICAgIGNvbnN0IHNpemVfdCBkYnByID0gZHN0LnN0cmlkZSAqIGJwcDsKKyAgICAgICAgY29uc3Qgc2l6ZV90IHNicHIgPSBzcmMuc3RyaWRlICogYnBwOworICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaXRlcmF0ZSgmcikpIHsKKyAgICAgICAgICAgIHNzaXplX3QgaCA9IHIuYm90dG9tIC0gci50b3A7CisgICAgICAgICAgICBpZiAoaCkgeworICAgICAgICAgICAgICAgIHNpemVfdCBzaXplID0gKHIucmlnaHQgLSByLmxlZnQpICogYnBwOworICAgICAgICAgICAgICAgIHVpbnQ4X3QqIHMgPSBzcmMuZGF0YSArIChyLmxlZnQgKyBzcmMuc3RyaWRlICogci50b3ApICogYnBwOworICAgICAgICAgICAgICAgIHVpbnQ4X3QqIGQgPSBkc3QuZGF0YSArIChyLmxlZnQgKyBkc3Quc3RyaWRlICogci50b3ApICogYnBwOworICAgICAgICAgICAgICAgIGlmIChkYnByPT1zYnByICYmIHNpemU9PXNicHIpIHsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZSAqPSBoOworICAgICAgICAgICAgICAgICAgICBoID0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZCwgcywgc2l6ZSk7CisgICAgICAgICAgICAgICAgICAgIGQgKz0gZGJwcjsKKyAgICAgICAgICAgICAgICAgICAgcyArPSBzYnByOworICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0taCA+IDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3VyZmFjZV9mbGluZ2VyX2NibGtfdDo6c3VyZmFjZV9mbGluZ2VyX2NibGtfdCgpCit7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitwZXJfY2xpZW50X2NibGtfdDo6cGVyX2NsaWVudF9jYmxrX3QoKQoreworfQorCisvLyB0aGVzZSBmdW5jdGlvbnMgYXJlIHVzZWQgYnkgdGhlIGNsaWVudHMKK2lubGluZSBzdGF0dXNfdCBwZXJfY2xpZW50X2NibGtfdDo6dmFsaWRhdGUoc2l6ZV90IGkpIGNvbnN0IHsKKyAgICBpZiAodWludDMyX3QoaSkgPj0gTlVNX0xBWUVSU19NQVgpCisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgaWYgKGxheWVyc1tpXS5zd2FwU3RhdGUgJiBlSW52YWxpZFN1cmZhY2UpCisgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitpbnQzMl90IHBlcl9jbGllbnRfY2Jsa190Ojpsb2NrX2xheWVyKHNpemVfdCBpLCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBpbnQzMl90IGluZGV4OworICAgIHVpbnQzMl90IHN0YXRlOworICAgIGludCB0aW1lb3V0ID0gMDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisgICAgbGF5ZXJfY2Jsa190ICogY29uc3QgbGF5ZXIgPSBsYXllcnMgKyBpOworICAgIGNvbnN0IGJvb2wgYmxvY2tpbmcgPSBmbGFncyAmIEJMT0NLSU5HOworICAgIGNvbnN0IGJvb2wgaW5zcGVjdCAgPSBmbGFncyAmIElOU1BFQ1Q7CisKKyAgICBkbyB7CisgICAgICAgIHN0YXRlID0gbGF5ZXItPnN3YXBTdGF0ZTsKKworICAgICAgICBpZiAoVU5MSUtFTFkoKHN0YXRlJihlRmxpcFJlcXVlc3RlZHxlTmV4dEZsaXBQZW5kaW5nKSkgPT0gZU5leHRGbGlwUGVuZGluZykpIHsKKyAgICAgICAgICAgIExPR0UoImVOZXh0RmxpcFBlbmRpbmcgc2V0IGJ1dCBlRmxpcFJlcXVlc3RlZCBub3Qgc2V0LCAiCisgICAgICAgICAgICAgICAgICJsYXllcj0lZCAobGNibGs9JXApLCBzdGF0ZT0lMDh4IiwKKyAgICAgICAgICAgICAgICAgaW50KGkpLCBsYXllciwgaW50KHN0YXRlKSk7CisgICAgICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgICAgIH0KKworICAgICAgICBpZiAoVU5MSUtFTFkoc3RhdGUmZUxvY2tlZCkpIHsKKyAgICAgICAgICAgIExPR0UoImVMb2NrZWQgc2V0IHdoZW4gZW50ZXJpbmcgbG9ja19sYXllcigpLCAiCisgICAgICAgICAgICAgICAgICJsYXllcj0lZCAobGNibGs9JXApLCBzdGF0ZT0lMDh4IiwKKyAgICAgICAgICAgICAgICAgaW50KGkpLCBsYXllciwgaW50KHN0YXRlKSk7CisgICAgICAgICAgICByZXR1cm4gV09VTERfQkxPQ0s7CisgICAgICAgIH0KKworCisJICAgIGlmIChzdGF0ZSAmIChlRmxpcFJlcXVlc3RlZCB8IGVOZXh0RmxpcFBlbmRpbmcgfCBlUmVzaXplUmVxdWVzdGVkCisgICAgICAgICAgICAgICAgICAgICAgICB8IGVJbnZhbGlkU3VyZmFjZSkpCisgICAgICAgIHsKKwkgICAgICAgIGludDMyX3QgcmVzaXplSW5kZXg7CisJICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobG9jayk7CisJICAgICAgICAgICAgLy8gbWlnaHQgYmxvY2sgZm9yIGEgdmVyeSBzaG9ydCBhbW91bnQgb2YgdGltZQorCSAgICAgICAgICAgIC8vIHdpbGwgbmV2ZXIgY2F1c2UgdGhlIHNlcnZlciB0byBibG9jayAodHJ5bG9jaygpKQorCisJICAgICAgICBnb3RvIHN0YXJ0X2xvb3BfaGVyZTsKKworCSAgICAgICAgLy8gV2UgYmxvY2sgdGhlIGNsaWVudCBpZjoKKwkgICAgICAgIC8vIGVOZXh0RmxpcFBlbmRpbmc6ICB3ZSd2ZSB1c2VkIGJvdGggYnVmZmVycyBhbHJlYWR5LCBzbyB3ZSBuZWVkIHRvCisJICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgd2FpdCBmb3Igb25lIHRvIGJlY29tZSBhdmFpbGxhYmxlLgorCSAgICAgICAgLy8gZVJlc2l6ZVJlcXVlc3RlZDogIHRoZSBidWZmZXIgd2UncmUgZ29pbmcgdG8gYWNxdWlyZSBpcyBiZWluZworCSAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIHJlc2l6ZWQuIEJsb2NrIHVudGlsIGl0IGlzIGRvbmUuCisJICAgICAgICAvLyBlRmxpcFJlcXVlc3RlZCAmJiBlQnVzeTogdGhlIGJ1ZmZlciB3ZSdyZSBnb2luZyB0byBhY3F1aXJlIGlzCisJICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgY3VycmVudGx5IGluIHVzZSBieSB0aGUgc2VydmVyLgorCSAgICAgICAgLy8gZUludmFsaWRTdXJmYWNlOiAgIHRoaXMgaXMgYSBzcGVjaWFsIGNhc2UsIHdlIGRvbid0IGJsb2NrIGluIHRoaXMKKwkgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICBjYXNlLCB3ZSBqdXN0IHJldHVybiBhbiBlcnJvci4KKworCSAgICAgICAgd2hpbGUoKHN0YXRlICYgKGVOZXh0RmxpcFBlbmRpbmd8ZUludmFsaWRTdXJmYWNlKSkgfHwKKwkgICAgICAgICAgICAgIChzdGF0ZSAmICgocmVzaXplSW5kZXgpID8gZVJlc2l6ZUJ1ZmZlcjEgOiBlUmVzaXplQnVmZmVyMCkpIHx8CisJICAgICAgICAgICAgICAoKHN0YXRlICYgKGVGbGlwUmVxdWVzdGVkfGVCdXN5KSkgPT0gKGVGbGlwUmVxdWVzdGVkfGVCdXN5KSkgKQorCSAgICAgICAgeworCSAgICAgICAgICAgIGlmIChzdGF0ZSAmIGVJbnZhbGlkU3VyZmFjZSkKKwkgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKworCSAgICAgICAgICAgIGlmICghYmxvY2tpbmcpCisJICAgICAgICAgICAgICAgIHJldHVybiBXT1VMRF9CTE9DSzsKKworICAgICAgICAgICAgICAgIHRpbWVvdXQgPSAwOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGN2LndhaXRSZWxhdGl2ZShsb2NrLCBzZWNvbmRzKDEpKTsKKwkgICAgICAgICAgICBpZiAoX19idWlsdGluX2V4cGVjdChyZXN1bHQhPU5PX0VSUk9SLCBmYWxzZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG5ld1N0YXRlID0gbGF5ZXItPnN3YXBTdGF0ZTsKKyAgICAgICAgICAgICAgICAgICAgTE9HVyggICAibG9ja19sYXllciB0aW1lZCBvdXQgKGlzIHRoZSBDUFUgcGVnZ2VkPykgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsYXllcj0lZCwgbGNibGs9JXAsIHN0YXRlPSUwOHggKHdhcyAlMDh4KSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KGkpLCBsYXllciwgbmV3U3RhdGUsIGludChzdGF0ZSkpOworICAgICAgICAgICAgICAgICAgICB0aW1lb3V0ID0gbmV3U3RhdGUgIT0gaW50KHN0YXRlKTsKKyAgICAgICAgICAgICAgICB9CisKKwkgICAgICAgIHN0YXJ0X2xvb3BfaGVyZToKKwkgICAgICAgICAgICBzdGF0ZSA9IGxheWVyLT5zd2FwU3RhdGU7CisJICAgICAgICAgICAgcmVzaXplSW5kZXggPSAoc3RhdGUmZUluZGV4KSBeICgoc3RhdGUmZUZsaXBSZXF1ZXN0ZWQpPj4xKTsKKwkgICAgICAgIH0KKworICAgICAgICAgICAgTE9HV19JRih0aW1lb3V0LAorICAgICAgICAgICAgICAgICAgICAibG9ja19sYXllcigpIHRpbWVkIG91dCBidXQgZGlkbid0IGFwcGVhciB0byBuZWVkICIKKyAgICAgICAgICAgICAgICAgICAgInRvIGJlIGxvY2tlZCBhbmQgd2UgcmVjb3ZlcmVkICIKKyAgICAgICAgICAgICAgICAgICAgIihsYXllcj0lZCwgbGNibGs9JXAsIHN0YXRlPSUwOHgpIiwKKyAgICAgICAgICAgICAgICAgICAgaW50KGkpLCBsYXllciwgaW50KHN0YXRlKSk7CisJICAgIH0KKworCSAgICAvLyBlRmxpcFJlcXVlc3RlZCBpcyBub3Qgc2V0IGFuZCBjYW5ub3QgYmUgc2V0IGJ5IGFub3RoZXIgdGhyZWFkOiBpdCdzCisJICAgIC8vIHNhZmUgdG8gdXNlIHRoZSBmaXJzdCBidWZmZXIgd2l0aG91dCBzeW5jaHJvbml6YXRpb24uCisKKyAgICAgICAgLy8gQ2hvb3NlIHRoZSBpbmRleCBkZXBlbmRpbmcgb24gZUZsaXBSZXF1ZXN0ZWQuCisgICAgICAgIC8vIFdoZW4gaXQncyBzZXQsIGNob29zZSB0aGUgJ290aGVyJyBidWZmZXIuCisgICAgICAgIGluZGV4ID0gKHN0YXRlJmVJbmRleCkgXiAoKHN0YXRlJmVGbGlwUmVxdWVzdGVkKT4+MSk7CisKKwkgICAgLy8gbWFrZSBzdXJlIHRoaXMgYnVmZmVyIGlzIHZhbGlkCisJICAgIGlmIChsYXllci0+c3VyZmFjZVtpbmRleF0uYml0c19vZmZzZXQgPCAwKSB7CisJICAgICAgICByZXR1cm4gc3RhdHVzX3QobGF5ZXItPnN1cmZhY2VbaW5kZXhdLmJpdHNfb2Zmc2V0KTsKKwkgICAgfQorCisgICAgICAgIGlmIChpbnNwZWN0KSB7CisgICAgICAgICAgICAvLyB3ZSBqdXN0IHdhbnQgdG8gaW5zcGVjdCB0aGlzIGxheWVyLiBkb24ndCBsb2NrIGl0LgorICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisKKwkgICAgLy8gbGFzdCB0aGluZyBiZWZvcmUgd2UncmUgZG9uZSwgd2UgbmVlZCB0byBhdG9taWNhbGx5IGxvY2sgdGhlIHN0YXRlCisgICAgfSB3aGlsZSAoYW5kcm9pZF9hdG9taWNfY21weGNoZyhzdGF0ZSwgc3RhdGV8ZUxvY2tlZCwgJihsYXllci0+c3dhcFN0YXRlKSkpOworCisgICAgVkVSQk9TRSgibG9ja2VkIGxheWVyPSVkIChsY2Jsaz0lcCksIGJ1ZmZlcj0lZCwgc3RhdGU9MHglMDh4IiwKKyAgICAgICAgIGludChpKSwgbGF5ZXIsIGludChpbmRleCksIGludChzdGF0ZSkpOworCisgICAgLy8gc3RvcmUgdGhlIGluZGV4IG9mIHRoZSBsb2NrZWQgYnVmZmVyIChmb3IgY2xpZW50IHVzZSBvbmx5KQorICAgIGxheWVyLT5mbGFncyAmPSB+ZUJ1ZmZlckluZGV4OworICAgIGxheWVyLT5mbGFncyB8PSAoKGluZGV4IDw8IGVCdWZmZXJJbmRleFNoaWZ0KSAmIGVCdWZmZXJJbmRleCk7CisKK2RvbmU6CisgICAgcmV0dXJuIGluZGV4OworfQorCit1aW50MzJfdCBwZXJfY2xpZW50X2NibGtfdDo6dW5sb2NrX2xheWVyX2FuZF9wb3N0KHNpemVfdCBpKQoreworICAgIC8vIGF0b21pY2FsbHkgc2V0IGVGbGlwUmVxdWVzdGVkIGFuZCBjbGVhciBlTG9ja2VkIGFuZCBvcHRpb25uYWx5CisgICAgLy8gc2V0IGVOZXh0RmxpcFBlbmRpbmcgaWYgZUZsaXBSZXF1ZXN0ZWQgd2FzIGFscmVhZHkgc2V0CisKKyAgICBsYXllcl9jYmxrX3QgKiBjb25zdCBsYXllciA9IGxheWVycyArIGk7CisgICAgaW50MzJfdCBvbGR2YWx1ZSwgbmV3dmFsdWU7CisgICAgZG8geworICAgICAgICBvbGR2YWx1ZSA9IGxheWVyLT5zd2FwU3RhdGU7CisgICAgICAgICAgICAvLyBnZXQgY3VycmVudCB2YWx1ZQorCisgICAgICAgIG5ld3ZhbHVlID0gb2xkdmFsdWUgJiB+ZUxvY2tlZDsKKyAgICAgICAgICAgIC8vIGNsZWFyIGVMb2NrZWQKKworICAgICAgICBuZXd2YWx1ZSB8PSBlRmxpcFJlcXVlc3RlZDsKKyAgICAgICAgICAgIC8vIHNldCBlRmxpcFJlcXVlc3RlZAorCisgICAgICAgIGlmIChvbGR2YWx1ZSAmIGVGbGlwUmVxdWVzdGVkKQorICAgICAgICAgICAgbmV3dmFsdWUgfD0gZU5leHRGbGlwUGVuZGluZzsKKyAgICAgICAgICAgIC8vIGlmIGVGbGlwUmVxdWVzdGVkIHdhcyBhbHJlYWQgc2V0LCBzZXQgZU5leHRGbGlwUGVuZGluZworCisgICAgfSB3aGlsZSAoYW5kcm9pZF9hdG9taWNfY21weGNoZyhvbGR2YWx1ZSwgbmV3dmFsdWUsICYobGF5ZXItPnN3YXBTdGF0ZSkpKTsKKworICAgIFZFUkJPU0UoInJlcXVlc3QgcGFnZWZsaXAgZm9yIGxheWVyPSVkLCBidWZmZXI9JWQsIHN0YXRlPTB4JTA4eCIsCisgICAgICAgICAgICBpbnQoaSksIGludCgobGF5ZXItPmZsYWdzICYgZUJ1ZmZlckluZGV4KSA+PiBlQnVmZmVySW5kZXhTaGlmdCksCisgICAgICAgICAgICBpbnQobmV3dmFsdWUpKTsKKworICAgIC8vIGZyb20gdGhpcyBwb2ludCwgdGhlIHNlcnZlciBjYW4ga2ljayBpbiBhdCBhbnl0aW1lIGFuZCB1c2UgdGhlIGZpcnN0CisgICAgLy8gYnVmZmVyLCBzbyB3ZSBjYW5ub3QgdXNlIGl0IGFueW1vcmUsIGFuZCB3ZSBtdXN0IHVzZSB0aGUgJ290aGVyJworICAgIC8vIGJ1ZmZlciBpbnN0ZWFkIChvciB3YWl0IGlmIGl0IGlzIG5vdCBhdmFpbGxhYmxlIHlldCwgc2VlIGxvY2tfbGF5ZXIpLgorCisgICAgcmV0dXJuIG5ld3ZhbHVlOworfQorCit2b2lkIHBlcl9jbGllbnRfY2Jsa190Ojp1bmxvY2tfbGF5ZXIoc2l6ZV90IGkpCit7CisgICAgbGF5ZXJfY2Jsa190ICogY29uc3QgbGF5ZXIgPSBsYXllcnMgKyBpOworICAgIGFuZHJvaWRfYXRvbWljX2FuZCh+ZUxvY2tlZCwgJmxheWVyLT5zd2FwU3RhdGUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGlubGluZSBpbnQgY29tcGFyZV90eXBlKCBjb25zdCBsYXllcl9zdGF0ZV90JiBsaHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxheWVyX3N0YXRlX3QmIHJocykgeworICAgIGlmIChsaHMuc3VyZmFjZSA8IHJocy5zdXJmYWNlKSAgcmV0dXJuIC0xOworICAgIGlmIChsaHMuc3VyZmFjZSA+IHJocy5zdXJmYWNlKSAgcmV0dXJuIDE7CisgICAgcmV0dXJuIDA7Cit9CisKK1N1cmZhY2VDb21wb3NlckNsaWVudDo6U3VyZmFjZUNvbXBvc2VyQ2xpZW50KCkKK3sKKyAgICBjb25zdCBzcDxJU3VyZmFjZUNvbXBvc2VyPiYgc20oX2dldF9zdXJmYWNlX21hbmFnZXIoKSk7CisgICAgaWYgKHNtID09IDApIHsKKyAgICAgICAgX2luaXQoMCwgMCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBfaW5pdChzbSwgc20tPmNyZWF0ZUNvbm5lY3Rpb24oKSk7CisKKyAgICBpZiAobUNsaWVudCAhPSAwKSB7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChnTG9jayk7CisgICAgICAgIFZFUkJPU0UoIkFkZGluZyBjbGllbnQgJXAgdG8gbWFwIiwgdGhpcyk7CisgICAgICAgIGdBY3RpdmVDb25uZWN0aW9ucy5hZGQobUNsaWVudC0+YXNCaW5kZXIoKSwgdGhpcyk7CisgICAgfQorfQorCitTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OlN1cmZhY2VDb21wb3NlckNsaWVudCgKKyAgICAgICAgY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIHNtLCBjb25zdCBzcDxJQmluZGVyPiYgY29ubikKK3sKKyAgICBfaW5pdChzbSwgaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2VGbGluZ2VyQ2xpZW50Pihjb25uKSk7Cit9CisKK3ZvaWQgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpfaW5pdCgKKyAgICAgICAgY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIHNtLCBjb25zdCBzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+JiBjb25uKQoreworICAgIFZFUkJPU0UoIkNyZWF0aW5nIGNsaWVudCAlcCwgY29ubiAlcCIsIHRoaXMsIGNvbm4uZ2V0KCkpOworCisgICAgbVNpZ25hbFNlcnZlciA9IDA7CisgICAgbVByZWJ1aWx0TGF5ZXJTdGF0ZSA9IDA7CisgICAgbVRyYW5zYWN0aW9uT3BlbiA9IDA7CisgICAgbVN0YXR1cyA9IE5PX0VSUk9SOworICAgIG1Db250cm9sID0gMDsKKworICAgIG1DbGllbnQgPSBjb25uOworICAgIGlmIChtQ2xpZW50ID09IDApIHsKKyAgICAgICAgbVN0YXR1cyA9IE5PX0lOSVQ7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBtQ2xpZW50LT5nZXRDb250cm9sQmxvY2tzKCZtQ29udHJvbE1lbW9yeSk7CisgICAgbVNpZ25hbFNlcnZlciA9IG5ldyBTdXJmYWNlRmxpbmdlclN5bmNocm8oc20pOworICAgIG1Db250cm9sID0gc3RhdGljX2Nhc3Q8cGVyX2NsaWVudF9jYmxrX3QgKj4obUNvbnRyb2xNZW1vcnktPnBvaW50ZXIoKSk7Cit9CisKK1N1cmZhY2VDb21wb3NlckNsaWVudDo6flN1cmZhY2VDb21wb3NlckNsaWVudCgpCit7CisgICAgVkVSQk9TRSgiRGVzdHJveWluZyBjbGllbnQgJXAsIGNvbm4gJXAiLCB0aGlzLCBtQ2xpZW50LmdldCgpKTsKKyAgICBkaXNwb3NlKCk7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6aW5pdENoZWNrKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVN0YXR1czsKK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50Ojp2YWxpZGF0ZVN1cmZhY2UoCisgICAgICAgIHBlcl9jbGllbnRfY2Jsa190IGNvbnN0KiBjYmxrLCBTdXJmYWNlIGNvbnN0ICogc3VyZmFjZSkKK3sKKyAgICBTdXJmYWNlSUQgaW5kZXggPSBzdXJmYWNlLT5JRCgpOworICAgIGlmIChjYmxrID09IDApIHsKKyAgICAgICAgTE9HRSgiY2JsayBpcyBudWxsIChzdXJmYWNlIGlkPSVkLCBpZGVudGl0eT0ldSkiLAorICAgICAgICAgICAgICAgIGluZGV4LCBzdXJmYWNlLT5nZXRJZGVudGl0eSgpKTsKKyAgICAgICAgcmV0dXJuIE5PX0lOSVQ7CisgICAgfQorCisgICAgc3RhdHVzX3QgZXJyID0gY2Jsay0+dmFsaWRhdGUoaW5kZXgpOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgTE9HRSgic3VyZmFjZSAoaWQ9JWQsIGlkZW50aXR5PSV1KSBpcyBpbnZhbGlkLCBlcnI9JWQgKCVzKSIsCisgICAgICAgICAgICAgICAgaW5kZXgsIHN1cmZhY2UtPmdldElkZW50aXR5KCksIGVyciwgc3RyZXJyb3IoLWVycikpOworICAgICAgICByZXR1cm4gZXJyOworICAgIH0KKworICAgIGlmIChzdXJmYWNlLT5nZXRJZGVudGl0eSgpICE9IHVpbnQzMl90KGNibGstPmxheWVyc1tpbmRleF0uaWRlbnRpdHkpKSB7CisgICAgICAgIExPR0UoInVzaW5nIGFuIGludmFsaWQgc3VyZmFjZSBpZD0lZCwgaWRlbnRpdHk9JXUgc2hvdWxkIGJlICVkIiwKKyAgICAgICAgICAgICAgICBpbmRleCwgc3VyZmFjZS0+Z2V0SWRlbnRpdHkoKSwgY2Jsay0+bGF5ZXJzW2luZGV4XS5pZGVudGl0eSk7CisgICAgICAgIHJldHVybiBOT19JTklUOworICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3A8SUJpbmRlcj4gU3VyZmFjZUNvbXBvc2VyQ2xpZW50Ojpjb25uZWN0aW9uKCkgY29uc3QKK3sKKyAgICByZXR1cm4gKG1DbGllbnQgIT0gMCkgPyBtQ2xpZW50LT5hc0JpbmRlcigpIDogMDsKK30KKworc3A8U3VyZmFjZUNvbXBvc2VyQ2xpZW50PgorU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpjbGllbnRGb3JDb25uZWN0aW9uKGNvbnN0IHNwPElCaW5kZXI+JiBjb25uKQoreworICAgIHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4gY2xpZW50OworCisgICAgeyAvLyBzY29wZSBmb3IgbG9jaworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2woZ0xvY2spOworICAgICAgICBjbGllbnQgPSBnQWN0aXZlQ29ubmVjdGlvbnMudmFsdWVGb3IoY29ubik7CisgICAgfQorCisgICAgaWYgKGNsaWVudCA9PSAwKSB7CisgICAgICAgIC8vIE5lZWQgdG8gbWFrZSBhIG5ldyBjbGllbnQuCisgICAgICAgIGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBzbShfZ2V0X3N1cmZhY2VfbWFuYWdlcigpKTsKKyAgICAgICAgY2xpZW50ID0gbmV3IFN1cmZhY2VDb21wb3NlckNsaWVudChzbSwgY29ubik7CisgICAgICAgIGlmIChjbGllbnQgIT0gMCAmJiBjbGllbnQtPmluaXRDaGVjaygpID09IE5PX0VSUk9SKSB7CisgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2woZ0xvY2spOworICAgICAgICAgICAgZ0FjdGl2ZUNvbm5lY3Rpb25zLmFkZChjb25uLCBjbGllbnQpOworICAgICAgICAgICAgLy9MT0dEKCJ3ZSBoYXZlICVkIGNvbm5lY3Rpb25zIiwgZ0FjdGl2ZUNvbm5lY3Rpb25zLnNpemUoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjbGllbnQuY2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBjbGllbnQ7Cit9CisKK3ZvaWQgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpkaXNwb3NlKCkKK3sKKyAgICAvLyB0aGlzIGNhbiBiZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2UuCisKKyAgICBzcDxJTWVtb3J5PiAgICAgICAgICAgICAgICAgY29udHJvbE1lbW9yeTsKKyAgICBzcDxJU3VyZmFjZUZsaW5nZXJDbGllbnQ+ICAgY2xpZW50OworICAgIHNwPElNZW1vcnlIZWFwPiAgICAgICAgICAgICBzdXJmYWNlSGVhcDsKKworICAgIHsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sZyhnTG9jayk7CisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbG0obUxvY2spOworCisgICAgICAgIGRlbGV0ZSBtU2lnbmFsU2VydmVyOworICAgICAgICBtU2lnbmFsU2VydmVyID0gMDsKKworICAgICAgICBpZiAobUNsaWVudCAhPSAwKSB7CisgICAgICAgICAgICBjbGllbnQgPSBtQ2xpZW50OworICAgICAgICAgICAgbUNsaWVudC5jbGVhcigpOworCisgICAgICAgICAgICBzc2l6ZV90IGkgPSBnQWN0aXZlQ29ubmVjdGlvbnMuaW5kZXhPZktleShjbGllbnQtPmFzQmluZGVyKCkpOworICAgICAgICAgICAgaWYgKGkgPj0gMCAmJiBnQWN0aXZlQ29ubmVjdGlvbnMudmFsdWVBdChpKSA9PSB0aGlzKSB7CisgICAgICAgICAgICAgICAgVkVSQk9TRSgiUmVtb3ZpbmcgY2xpZW50ICVwIGZyb20gbWFwIGF0ICVkIiwgdGhpcywgaW50KGkpKTsKKyAgICAgICAgICAgICAgICBnQWN0aXZlQ29ubmVjdGlvbnMucmVtb3ZlSXRlbXNBdChpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGRlbGV0ZSBtUHJlYnVpbHRMYXllclN0YXRlOworICAgICAgICBtUHJlYnVpbHRMYXllclN0YXRlID0gMDsKKyAgICAgICAgY29udHJvbE1lbW9yeSA9IG1Db250cm9sTWVtb3J5OworICAgICAgICBzdXJmYWNlSGVhcCA9IG1TdXJmYWNlSGVhcDsKKyAgICAgICAgbUNvbnRyb2xNZW1vcnkuY2xlYXIoKTsKKyAgICAgICAgbVN1cmZhY2VIZWFwLmNsZWFyKCk7CisgICAgICAgIG1Db250cm9sID0gMDsKKyAgICAgICAgbVN0YXR1cyA9IE5PX0lOSVQ7CisgICAgfQorfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmdldERpc3BsYXlJbmZvKAorICAgICAgICBEaXNwbGF5SUQgZHB5LCBEaXNwbGF5SW5mbyogaW5mbykKK3sKKyAgICBpZiAodWludDMyX3QoZHB5KT49TlVNX0RJU1BMQVlfTUFYKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworCisgICAgdm9sYXRpbGUgc3VyZmFjZV9mbGluZ2VyX2NibGtfdCBjb25zdCAqIGNibGsgPSBnZXRfY2JsaygpOworICAgIHZvbGF0aWxlIGRpc3BsYXlfY2Jsa190IGNvbnN0ICogZGNibGsgPSBjYmxrLT5kaXNwbGF5cyArIGRweTsKKworICAgIGluZm8tPncgICAgICAgICAgICAgID0gZGNibGstPnc7CisgICAgaW5mby0+aCAgICAgICAgICAgICAgPSBkY2Jsay0+aDsKKyAgICBpbmZvLT5vcmllbnRhdGlvbiAgICA9IGRjYmxrLT5vcmllbnRhdGlvbjsKKyAgICBpbmZvLT54ZHBpICAgICAgICAgICA9IGRjYmxrLT54ZHBpOworICAgIGluZm8tPnlkcGkgICAgICAgICAgID0gZGNibGstPnlkcGk7CisgICAgaW5mby0+ZnBzICAgICAgICAgICAgPSBkY2Jsay0+ZnBzOworICAgIGluZm8tPmRlbnNpdHkgICAgICAgID0gZGNibGstPmRlbnNpdHk7CisgICAgcmV0dXJuIGdldFBpeGVsRm9ybWF0SW5mbyhkY2Jsay0+Zm9ybWF0LCAmKGluZm8tPnBpeGVsRm9ybWF0SW5mbykpOworfQorCitzc2l6ZV90IFN1cmZhY2VDb21wb3NlckNsaWVudDo6Z2V0RGlzcGxheVdpZHRoKERpc3BsYXlJRCBkcHkpCit7CisgICAgaWYgKHVpbnQzMl90KGRweSk+PU5VTV9ESVNQTEFZX01BWCkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB2b2xhdGlsZSBzdXJmYWNlX2ZsaW5nZXJfY2Jsa190IGNvbnN0ICogY2JsayA9IGdldF9jYmxrKCk7CisgICAgdm9sYXRpbGUgZGlzcGxheV9jYmxrX3QgY29uc3QgKiBkY2JsayA9IGNibGstPmRpc3BsYXlzICsgZHB5OworICAgIHJldHVybiBkY2Jsay0+dzsKK30KKworc3NpemVfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmdldERpc3BsYXlIZWlnaHQoRGlzcGxheUlEIGRweSkKK3sKKyAgICBpZiAodWludDMyX3QoZHB5KT49TlVNX0RJU1BMQVlfTUFYKQorICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworICAgIHZvbGF0aWxlIHN1cmZhY2VfZmxpbmdlcl9jYmxrX3QgY29uc3QgKiBjYmxrID0gZ2V0X2NibGsoKTsKKyAgICB2b2xhdGlsZSBkaXNwbGF5X2NibGtfdCBjb25zdCAqIGRjYmxrID0gY2Jsay0+ZGlzcGxheXMgKyBkcHk7CisgICAgcmV0dXJuIGRjYmxrLT5oOworfQorCitzc2l6ZV90IFN1cmZhY2VDb21wb3NlckNsaWVudDo6Z2V0RGlzcGxheU9yaWVudGF0aW9uKERpc3BsYXlJRCBkcHkpCit7CisgICAgaWYgKHVpbnQzMl90KGRweSk+PU5VTV9ESVNQTEFZX01BWCkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgICB2b2xhdGlsZSBzdXJmYWNlX2ZsaW5nZXJfY2Jsa190IGNvbnN0ICogY2JsayA9IGdldF9jYmxrKCk7CisgICAgdm9sYXRpbGUgZGlzcGxheV9jYmxrX3QgY29uc3QgKiBkY2JsayA9IGNibGstPmRpc3BsYXlzICsgZHB5OworICAgIHJldHVybiBkY2Jsay0+b3JpZW50YXRpb247Cit9CisKK3NzaXplX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpnZXROdW1iZXJPZkRpc3BsYXlzKCkKK3sKKyAgICB2b2xhdGlsZSBzdXJmYWNlX2ZsaW5nZXJfY2Jsa190IGNvbnN0ICogY2JsayA9IGdldF9jYmxrKCk7CisgICAgdWludDMyX3QgY29ubmVjdGVkID0gY2Jsay0+Y29ubmVjdGVkOworICAgIGludCBuID0gMDsKKyAgICB3aGlsZSAoY29ubmVjdGVkKSB7CisgICAgICAgIGlmIChjb25uZWN0ZWQmMSkgbisrOworICAgICAgICBjb25uZWN0ZWQgPj49IDE7CisgICAgfQorICAgIHJldHVybiBuOworfQorCitzcDxTdXJmYWNlPiBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmNyZWF0ZVN1cmZhY2UoCisgICAgICAgIGludCBwaWQsCisgICAgICAgIERpc3BsYXlJRCBkaXNwbGF5LAorICAgICAgICB1aW50MzJfdCB3LAorICAgICAgICB1aW50MzJfdCBoLAorICAgICAgICBQaXhlbEZvcm1hdCBmb3JtYXQsCisgICAgICAgIHVpbnQzMl90IGZsYWdzKQoreworICAgIHNwPFN1cmZhY2U+IHJlc3VsdDsKKyAgICBpZiAobVN0YXR1cyA9PSBOT19FUlJPUikgeworICAgICAgICBJU3VyZmFjZUZsaW5nZXJDbGllbnQ6OnN1cmZhY2VfZGF0YV90IGRhdGE7CisgICAgICAgIHNwPElTdXJmYWNlPiBzdXJmYWNlID0gbUNsaWVudC0+Y3JlYXRlU3VyZmFjZSgmZGF0YSwgcGlkLAorICAgICAgICAgICAgICAgIGRpc3BsYXksIHcsIGgsIGZvcm1hdCwgZmxhZ3MpOworICAgICAgICBpZiAoc3VyZmFjZSAhPSAwKSB7CisgICAgICAgICAgICBpZiAodWludDMyX3QoZGF0YS50b2tlbikgPCBOVU1fTEFZRVJTX01BWCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTdXJmYWNlKHRoaXMsIHN1cmZhY2UsIGRhdGEsIHcsIGgsIGZvcm1hdCwgZmxhZ3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6ZGVzdHJveVN1cmZhY2UoU3VyZmFjZUlEIHNpZCkKK3sKKyAgICBpZiAobVN0YXR1cyAhPSBOT19FUlJPUikKKyAgICAgICAgcmV0dXJuIG1TdGF0dXM7CisKKyAgICAvLyBpdCdzIG9rYXkgdG8gZGVzdHJveSBhIHN1cmZhY2Ugd2hpbGUgYSB0cmFuc2FjdGlvbiBpcyBvcGVuLAorICAgIC8vICh0cmFuc2FjdGlvbnMgcmVhbGx5IGFyZSBhIGNsaWVudC1zaWRlIGNvbmNlcHQpCisgICAgLy8gaG93ZXZlciwgdGhpcyBpbmRpY2F0ZXMgcHJvYmFibHkgYSBtaXN1c2Ugb2YgdGhlIEFQSSBvciBhIGJ1ZworICAgIC8vIGluIHRoZSBjbGllbnQgY29kZS4KKyAgICBMT0dXX0lGKG1UcmFuc2FjdGlvbk9wZW4sCisgICAgICAgICAiRGVzdHJveWluZyBzdXJmYWNlIHdoaWxlIGEgdHJhbnNhY3Rpb24gaXMgb3Blbi4gIgorICAgICAgICAgIkNsaWVudCAlcDogZGVzdHJveWluZyBzdXJmYWNlICVkLCBtVHJhbnNhY3Rpb25PcGVuPSVkIiwKKyAgICAgICAgIHRoaXMsIHNpZCwgbVRyYW5zYWN0aW9uT3Blbik7CisKKyAgICBzdGF0dXNfdCBlcnIgPSBtQ2xpZW50LT5kZXN0cm95U3VyZmFjZShzaWQpOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6bmV4dEJ1ZmZlcihTdXJmYWNlKiBzdXJmYWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgU3VyZmFjZTo6U3VyZmFjZUluZm8qIGluZm8pCit7CisgICAgU3VyZmFjZUlEIGluZGV4ID0gc3VyZmFjZS0+SUQoKTsKKyAgICBwZXJfY2xpZW50X2NibGtfdCogY29uc3QgY2JsayA9IG1Db250cm9sOworICAgIHN0YXR1c190IGVyciA9IHZhbGlkYXRlU3VyZmFjZShjYmxrLCBzdXJmYWNlKTsKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gZXJyOworCisgICAgaW50MzJfdCBiYWNrSWR4ID0gc3VyZmFjZS0+bUJhY2tidWZmZXJJbmRleDsKKyAgICBsYXllcl9jYmxrX3QqIGNvbnN0IGxjYmxrID0gJihjYmxrLT5sYXllcnNbaW5kZXhdKTsKKyAgICBjb25zdCBzdXJmYWNlX2luZm9fdCogY29uc3QgZnJvbnQgPSBsY2Jsay0+c3VyZmFjZSArICgxLWJhY2tJZHgpOworICAgICAgICBpbmZvLT53ICAgICAgPSBmcm9udC0+dzsKKyAgICAgICAgaW5mby0+aCAgICAgID0gZnJvbnQtPmg7CisgICAgICAgIGluZm8tPmZvcm1hdCA9IGZyb250LT5mb3JtYXQ7CisgICAgICAgIGluZm8tPmJhc2UgICA9IHN1cmZhY2UtPmhlYXBCYXNlKDEtYmFja0lkeCk7CisgICAgICAgIGluZm8tPmJpdHMgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KGludHB0cl90KGluZm8tPmJhc2UpICsgZnJvbnQtPmJpdHNfb2Zmc2V0KTsKKyAgICAgICAgaW5mby0+YnByICAgID0gZnJvbnQtPmJwcjsKKworICAgIHJldHVybiAwOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmxvY2tTdXJmYWNlKAorICAgICAgICBTdXJmYWNlKiBzdXJmYWNlLAorICAgICAgICBTdXJmYWNlOjpTdXJmYWNlSW5mbyogb3RoZXIsCisgICAgICAgIFJlZ2lvbiogZGlydHksCisgICAgICAgIGJvb2wgYmxvY2tpbmcpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKHN1cmZhY2UtPmdldExvY2soKSk7CisKKyAgICBTdXJmYWNlSUQgaW5kZXggPSBzdXJmYWNlLT5JRCgpOworICAgIHBlcl9jbGllbnRfY2Jsa190KiBjb25zdCBjYmxrID0gbUNvbnRyb2w7CisgICAgc3RhdHVzX3QgZXJyID0gdmFsaWRhdGVTdXJmYWNlKGNibGssIHN1cmZhY2UpOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiBlcnI7CisKKyAgICBpbnQzMl90IGJhY2tJZHggPSBjYmxrLT5sb2NrX2xheWVyKHNpemVfdChpbmRleCksCisgICAgICAgICAgICBwZXJfY2xpZW50X2NibGtfdDo6QkxPQ0tJTkcpOworICAgIGlmIChiYWNrSWR4ID49IDApIHsKKyAgICAgICAgc3VyZmFjZS0+bUJhY2tidWZmZXJJbmRleCA9IGJhY2tJZHg7CisgICAgICAgIGxheWVyX2NibGtfdCogY29uc3QgbGNibGsgPSAmKGNibGstPmxheWVyc1tpbmRleF0pOworICAgICAgICBjb25zdCBzdXJmYWNlX2luZm9fdCogY29uc3QgYmFjayA9IGxjYmxrLT5zdXJmYWNlICsgYmFja0lkeDsKKyAgICAgICAgY29uc3Qgc3VyZmFjZV9pbmZvX3QqIGNvbnN0IGZyb250ID0gbGNibGstPnN1cmZhY2UgKyAoMS1iYWNrSWR4KTsKKyAgICAgICAgICAgIG90aGVyLT53ICAgICAgPSBiYWNrLT53OworICAgICAgICAgICAgb3RoZXItPmggICAgICA9IGJhY2stPmg7CisgICAgICAgICAgICBvdGhlci0+Zm9ybWF0ID0gYmFjay0+Zm9ybWF0OworICAgICAgICAgICAgb3RoZXItPmJhc2UgICA9IHN1cmZhY2UtPmhlYXBCYXNlKGJhY2tJZHgpOworICAgICAgICAgICAgb3RoZXItPmJpdHMgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KGludHB0cl90KG90aGVyLT5iYXNlKSArIGJhY2stPmJpdHNfb2Zmc2V0KTsKKyAgICAgICAgICAgIG90aGVyLT5icHIgICAgPSBiYWNrLT5icHI7CisKKyAgICAgICAgY29uc3QgUmVjdCBib3VuZHMob3RoZXItPncsIG90aGVyLT5oKTsKKyAgICAgICAgUmVnaW9uIG5ld0RpcnR5UmVnaW9uOworCisgICAgICAgIGlmIChiYWNrLT5mbGFncyAmIHN1cmZhY2VfaW5mb190OjplQnVmZmVyRGlydHkpIHsKKyAgICAgICAgICAgIC8qIGl0IGlzIHNhZmUgdG8gd3JpdGUgKmJhY2sgaGVyZSwgYmVjYXVzZSB3ZSdyZSBndWFyYW50ZWVkCisgICAgICAgICAgICAgKiBTdXJmYWNlRmxpbmdlciBpcyBub3QgdG91Y2hpbmcgaXQgKHNpbmNlIGl0IGp1c3QgZ3JhbnRlZAorICAgICAgICAgICAgICogYWNjZXNzIHRvIHVzKSAqLworICAgICAgICAgICAgY29uc3RfY2FzdDxzdXJmYWNlX2luZm9fdCo+KGJhY2spLT5mbGFncyAmPQorICAgICAgICAgICAgICAgICAgICB+c3VyZmFjZV9pbmZvX3Q6OmVCdWZmZXJEaXJ0eTsKKworICAgICAgICAgICAgLy8gY29udGVudCBpcyBtZWFuaW5nbGVzcyBpbiB0aGlzIGNhc2UgYW5kIHRoZSB3aG9sZSBzdXJmYWNlCisgICAgICAgICAgICAvLyBuZWVkcyB0byBiZSByZWRyYXduLgorCisgICAgICAgICAgICBuZXdEaXJ0eVJlZ2lvbi5zZXQoYm91bmRzKTsKKyAgICAgICAgICAgIGlmIChkaXJ0eSkgeworICAgICAgICAgICAgICAgICpkaXJ0eSA9IG5ld0RpcnR5UmVnaW9uOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL2lmIChieXRlc1BlclBpeGVsKG90aGVyLT5mb3JtYXQpID09IDQpIHsKKyAgICAgICAgICAgIC8vICAgIGFuZHJvaWRfbWVtc2V0MzIoCisgICAgICAgICAgICAvLyAgICAgICAgKHVpbnQzMl90KilvdGhlci0+Yml0cywgMHhGRjAwRkYwMCwgb3RoZXItPmggKiBvdGhlci0+YnByKTsKKyAgICAgICAgICAgIC8vfSBlbHNlIHsKKyAgICAgICAgICAgIC8vICAgIGFuZHJvaWRfbWVtc2V0MTYoIC8vIGZpbGwgd2l0aCBncmVlbgorICAgICAgICAgICAgLy8gICAgICAgICh1aW50MTZfdCopb3RoZXItPmJpdHMsIDB4N0UwLCBvdGhlci0+aCAqIG90aGVyLT5icHIpOworICAgICAgICAgICAgLy99CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgICBpZiAoZGlydHkpIHsKKyAgICAgICAgICAgICAgICBkaXJ0eS0+YW5kU2VsZihSZWdpb24oYm91bmRzKSk7CisgICAgICAgICAgICAgICAgbmV3RGlydHlSZWdpb24gPSAqZGlydHk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5ld0RpcnR5UmVnaW9uLnNldChib3VuZHMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBSZWdpb24gY29weWJhY2s7CisgICAgICAgICAgICBpZiAoIShsY2Jsay0+ZmxhZ3MgJiBlTm9Db3B5QmFjaykpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBSZWdpb24gcHJldmlvdXNEaXJ0eVJlZ2lvbihzdXJmYWNlLT5kaXJ0eVJlZ2lvbigpKTsKKyAgICAgICAgICAgICAgICBjb3B5YmFjayA9IHByZXZpb3VzRGlydHlSZWdpb24uc3VidHJhY3QobmV3RGlydHlSZWdpb24pOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIWNvcHliYWNrLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIC8vIGNvcHkgZnJvbnQgdG8gYmFjaworICAgICAgICAgICAgICAgIEdHTFN1cmZhY2UgY2I7CisgICAgICAgICAgICAgICAgICAgIGNiLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgICAgICAgICAgICAgIGNiLndpZHRoID0gYmFjay0+dzsKKyAgICAgICAgICAgICAgICAgICAgY2IuaGVpZ2h0ID0gYmFjay0+aDsKKyAgICAgICAgICAgICAgICAgICAgY2Iuc3RyaWRlID0gYmFjay0+c3RyaWRlOworICAgICAgICAgICAgICAgICAgICBjYi5kYXRhID0gKEdHTHVieXRlKilzdXJmYWNlLT5oZWFwQmFzZShiYWNrSWR4KTsKKyAgICAgICAgICAgICAgICAgICAgY2IuZGF0YSArPSBiYWNrLT5iaXRzX29mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgY2IuZm9ybWF0ID0gYmFjay0+Zm9ybWF0OworCisgICAgICAgICAgICAgICAgR0dMU3VyZmFjZSB0OworICAgICAgICAgICAgICAgICAgICB0LnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgICAgICAgICAgICAgIHQud2lkdGggPSBmcm9udC0+dzsKKyAgICAgICAgICAgICAgICAgICAgdC5oZWlnaHQgPSBmcm9udC0+aDsKKyAgICAgICAgICAgICAgICAgICAgdC5zdHJpZGUgPSBmcm9udC0+c3RyaWRlOworICAgICAgICAgICAgICAgICAgICB0LmRhdGEgPSAoR0dMdWJ5dGUqKXN1cmZhY2UtPmhlYXBCYXNlKDEtYmFja0lkeCk7CisgICAgICAgICAgICAgICAgICAgIHQuZGF0YSArPSBmcm9udC0+Yml0c19vZmZzZXQ7CisgICAgICAgICAgICAgICAgICAgIHQuZm9ybWF0ID0gZnJvbnQtPmZvcm1hdDsKKworICAgICAgICAgICAgICAgIC8vY29uc3QgUmVnaW9uIGNvcHliYWNrKGxjYmxrLT5yZWdpb24gKyAxLWJhY2tJZHgpOworICAgICAgICAgICAgICAgIGNvcHlCbHQoY2IsIHQsIGNvcHliYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHVwZGF0ZSBkaXJ0eSByZWdpb24KKyAgICAgICAgc3VyZmFjZS0+c2V0RGlydHlSZWdpb24obmV3RGlydHlSZWdpb24pOworICAgIH0KKyAgICByZXR1cm4gKGJhY2tJZHggPCAwKSA/IHN0YXR1c190KGJhY2tJZHgpIDogc3RhdHVzX3QoTk9fRVJST1IpOworfQorCit2b2lkIFN1cmZhY2VDb21wb3NlckNsaWVudDo6X3NpZ25hbF9zZXJ2ZXIoKQoreworICAgIG1TaWduYWxTZXJ2ZXItPnNpZ25hbCgpOworfQorCit2b2lkIFN1cmZhY2VDb21wb3NlckNsaWVudDo6X3NlbmRfZGlydHlfcmVnaW9uKAorICAgICAgICBsYXllcl9jYmxrX3QqIGxjYmxrLCBjb25zdCBSZWdpb24mIGRpcnR5KQoreworICAgIGNvbnN0IGludDMyX3QgaW5kZXggPSAobGNibGstPmZsYWdzICYgZUJ1ZmZlckluZGV4KSA+PiBlQnVmZmVySW5kZXhTaGlmdDsKKyAgICBmbGF0X3JlZ2lvbl90KiBmbGF0X3JlZ2lvbiA9IGxjYmxrLT5yZWdpb24gKyBpbmRleDsKKyAgICBzdGF0dXNfdCBlcnIgPSBkaXJ0eS53cml0ZShmbGF0X3JlZ2lvbiwgc2l6ZW9mKGZsYXRfcmVnaW9uX3QpKTsKKyAgICBpZiAoZXJyIDwgTk9fRVJST1IpIHsKKyAgICAgICAgLy8gcmVnaW9uIGRvZXNuJ3QgZml0LCB1c2UgdGhlIGJvdW5kcworICAgICAgICBjb25zdCBSZWdpb24gcmVnKGRpcnR5LmJvdW5kcygpKTsKKyAgICAgICAgcmVnLndyaXRlKGZsYXRfcmVnaW9uLCBzaXplb2YoZmxhdF9yZWdpb25fdCkpOworICAgIH0KK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50Ojp1bmxvY2tBbmRQb3N0U3VyZmFjZShTdXJmYWNlKiBzdXJmYWNlKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChzdXJmYWNlLT5nZXRMb2NrKCkpOworCisgICAgU3VyZmFjZUlEIGluZGV4ID0gc3VyZmFjZS0+SUQoKTsKKyAgICBwZXJfY2xpZW50X2NibGtfdCogY29uc3QgY2JsayA9IG1Db250cm9sOworICAgIHN0YXR1c190IGVyciA9IHZhbGlkYXRlU3VyZmFjZShjYmxrLCBzdXJmYWNlKTsKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gZXJyOworCisgICAgUmVnaW9uIGRpcnR5KHN1cmZhY2UtPmRpcnR5UmVnaW9uKCkpOworICAgIGNvbnN0IFJlY3QmIHN3YXBSZWN0KHN1cmZhY2UtPnN3YXBSZWN0YW5nbGUoKSk7CisgICAgaWYgKHN3YXBSZWN0LmlzVmFsaWQoKSkgeworICAgICAgICBkaXJ0eS5zZXQoc3dhcFJlY3QpOworICAgIH0KKworICAgIC8vIHRyYW5zbWl0IHRoZSBkaXJ0eSByZWdpb24KKyAgICBsYXllcl9jYmxrX3QqIGNvbnN0IGxjYmxrID0gJihjYmxrLT5sYXllcnNbaW5kZXhdKTsKKyAgICBfc2VuZF9kaXJ0eV9yZWdpb24obGNibGssIGRpcnR5KTsKKyAgICB1aW50MzJfdCBuZXdzdGF0ZSA9IGNibGstPnVubG9ja19sYXllcl9hbmRfcG9zdChzaXplX3QoaW5kZXgpKTsKKyAgICBpZiAoIShuZXdzdGF0ZSAmIGVOZXh0RmxpcFBlbmRpbmcpKQorICAgICAgICBfc2lnbmFsX3NlcnZlcigpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50Ojp1bmxvY2tTdXJmYWNlKFN1cmZhY2UqIHN1cmZhY2UpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKHN1cmZhY2UtPmdldExvY2soKSk7CisKKyAgICBTdXJmYWNlSUQgaW5kZXggPSBzdXJmYWNlLT5JRCgpOworICAgIHBlcl9jbGllbnRfY2Jsa190KiBjb25zdCBjYmxrID0gbUNvbnRyb2w7CisgICAgc3RhdHVzX3QgZXJyID0gdmFsaWRhdGVTdXJmYWNlKGNibGssIHN1cmZhY2UpOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiBlcnI7CisKKyAgICBsYXllcl9jYmxrX3QqIGNvbnN0IGxjYmxrID0gJihjYmxrLT5sYXllcnNbaW5kZXhdKTsKKyAgICBjYmxrLT51bmxvY2tfbGF5ZXIoc2l6ZV90KGluZGV4KSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIFN1cmZhY2VDb21wb3NlckNsaWVudDo6b3Blbkdsb2JhbFRyYW5zYWN0aW9uKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2woZ0xvY2spOworCisgICAgaWYgKGdPcGVuVHJhbnNhY3Rpb25zLnNpemUoKSkgeworICAgICAgICBMT0dFKCJvcGVuR2xvYmFsVHJhbnNhY3Rpb24oKSBjYWxsZWQgbW9yZSB0aGFuIG9uY2UuIHNraXBwaW5nLiIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgY29uc3Qgc2l6ZV90IE4gPSBnQWN0aXZlQ29ubmVjdGlvbnMuc2l6ZSgpOworICAgIFZFUkJPU0UoIm9wZW5HbG9iYWxUcmFuc2FjdGlvbiAoJWxkIGNsaWVudHMpIiwgTik7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPE47IGkrKykgeworICAgICAgICBzcDxTdXJmYWNlQ29tcG9zZXJDbGllbnQ+IGNsaWVudChnQWN0aXZlQ29ubmVjdGlvbnMudmFsdWVBdChpKSk7CisgICAgICAgIGlmIChnT3BlblRyYW5zYWN0aW9ucy5pbmRleE9mKGNsaWVudCkgPCAwKSB7CisgICAgICAgICAgICBpZiAoY2xpZW50LT5vcGVuVHJhbnNhY3Rpb24oKSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgIGlmIChnT3BlblRyYW5zYWN0aW9ucy5hZGQoY2xpZW50KSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gT29vcHMhCisgICAgICAgICAgICAgICAgICAgIExPR0UoICAgIlVuYWJsZSB0byBhZGQgYSBTdXJmYWNlQ29tcG9zZXJDbGllbnQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0byB0aGUgZ2xvYmFsIHRyYW5zYWN0aW9uIHNldCAob3V0IG9mIG1lbW9yeT8pIik7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudC0+Y2xvc2VUcmFuc2FjdGlvbigpOworICAgICAgICAgICAgICAgICAgICAvLyBsZXQgaXQgZ28sIGl0J2xsIGZhaWwgbGF0ZXIgd2hlbiB0aGUgdXNlcgorICAgICAgICAgICAgICAgICAgICAvLyB0cmllcyB0byBkbyBzb21ldGhpbmcgd2l0aCB0aGUgdHJhbnNhY3Rpb24KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIExPR0UoIm9wZW5UcmFuc2FjdGlvbiBvbiBjbGllbnQgJXAgZmFpbGVkIiwgY2xpZW50LmdldCgpKTsKKyAgICAgICAgICAgICAgICAvLyBsZXQgaXQgZ28sIGl0J2xsIGZhaWwgbGF0ZXIgd2hlbiB0aGUgdXNlcgorICAgICAgICAgICAgICAgIC8vIHRyaWVzIHRvIGRvIHNvbWV0aGluZyB3aXRoIHRoZSB0cmFuc2FjdGlvbgorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCit2b2lkIFN1cmZhY2VDb21wb3NlckNsaWVudDo6Y2xvc2VHbG9iYWxUcmFuc2FjdGlvbigpCit7CisgICAgZ0xvY2subG9jaygpOworICAgICAgICBTb3J0ZWRWZWN0b3I8IHNwPFN1cmZhY2VDb21wb3NlckNsaWVudD4gPiBjbGllbnRzKGdPcGVuVHJhbnNhY3Rpb25zKTsKKyAgICAgICAgZ09wZW5UcmFuc2FjdGlvbnMuY2xlYXIoKTsKKyAgICBnTG9jay51bmxvY2soKTsKKworICAgIGNvbnN0IHNpemVfdCBOID0gY2xpZW50cy5zaXplKCk7CisgICAgVkVSQk9TRSgiY2xvc2VHbG9iYWxUcmFuc2FjdGlvbiAoJWxkIGNsaWVudHMpIiwgTik7CisgICAgaWYgKE4gPT0gMSkgeworICAgICAgICBjbGllbnRzWzBdLT5jbG9zZVRyYW5zYWN0aW9uKCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIHNtKF9nZXRfc3VyZmFjZV9tYW5hZ2VyKCkpOworICAgICAgICBzbS0+b3Blbkdsb2JhbFRyYW5zYWN0aW9uKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgICAgIGNsaWVudHNbaV0tPmNsb3NlVHJhbnNhY3Rpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzbS0+Y2xvc2VHbG9iYWxUcmFuc2FjdGlvbigpOworICAgIH0KK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpmcmVlemVEaXNwbGF5KERpc3BsYXlJRCBkcHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBzbShfZ2V0X3N1cmZhY2VfbWFuYWdlcigpKTsKKyAgICByZXR1cm4gc20tPmZyZWV6ZURpc3BsYXkoZHB5LCBmbGFncyk7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6dW5mcmVlemVEaXNwbGF5KERpc3BsYXlJRCBkcHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBzbShfZ2V0X3N1cmZhY2VfbWFuYWdlcigpKTsKKyAgICByZXR1cm4gc20tPnVuZnJlZXplRGlzcGxheShkcHksIGZsYWdzKTsKK30KKworaW50IFN1cmZhY2VDb21wb3NlckNsaWVudDo6c2V0T3JpZW50YXRpb24oRGlzcGxheUlEIGRweSwgaW50IG9yaWVudGF0aW9uKQoreworICAgIGNvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBzbShfZ2V0X3N1cmZhY2VfbWFuYWdlcigpKTsKKyAgICByZXR1cm4gc20tPnNldE9yaWVudGF0aW9uKGRweSwgb3JpZW50YXRpb24pOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6Om9wZW5UcmFuc2FjdGlvbigpCit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiBtU3RhdHVzOworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgVkVSQk9TRSggICAib3BlblRyYW5zYWN0aW9uIChjbGllbnQgJXAsIG1UcmFuc2FjdGlvbk9wZW49JWQpIiwKKyAgICAgICAgICAgIHRoaXMsIG1UcmFuc2FjdGlvbk9wZW4pOworICAgIG1UcmFuc2FjdGlvbk9wZW4rKzsKKyAgICBpZiAobVByZWJ1aWx0TGF5ZXJTdGF0ZSA9PSAwKSB7CisgICAgICAgIG1QcmVidWlsdExheWVyU3RhdGUgPSBuZXcgbGF5ZXJfc3RhdGVfdDsKKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6Y2xvc2VUcmFuc2FjdGlvbigpCit7CisgICAgaWYgKG1TdGF0dXMgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiBtU3RhdHVzOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKworICAgIFZFUkJPU0UoICAgImNsb3NlVHJhbnNhY3Rpb24gKGNsaWVudCAlcCwgbVRyYW5zYWN0aW9uT3Blbj0lZCkiLAorICAgICAgICAgICAgdGhpcywgbVRyYW5zYWN0aW9uT3Blbik7CisKKyAgICBpZiAobVRyYW5zYWN0aW9uT3BlbiA8PSAwKSB7CisgICAgICAgIExPR0UoICAgImNsb3NlVHJhbnNhY3Rpb24gKGNsaWVudCAlcCwgbVRyYW5zYWN0aW9uT3Blbj0lZCkgIgorICAgICAgICAgICAgICAgICJjYWxsZWQgbW9yZSB0aW1lcyB0aGFuIG9wZW5UcmFuc2FjdGlvbigpIiwKKyAgICAgICAgICAgICAgICB0aGlzLCBtVHJhbnNhY3Rpb25PcGVuKTsKKyAgICAgICAgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworICAgIH0KKworICAgIGlmIChtVHJhbnNhY3Rpb25PcGVuID49IDIpIHsKKyAgICAgICAgbVRyYW5zYWN0aW9uT3Blbi0tOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgbVRyYW5zYWN0aW9uT3BlbiA9IDA7CisgICAgY29uc3Qgc3NpemVfdCBjb3VudCA9IG1TdGF0ZXMuc2l6ZSgpOworICAgIGlmIChjb3VudCkgeworICAgICAgICBtQ2xpZW50LT5zZXRTdGF0ZShjb3VudCwgbVN0YXRlcy5hcnJheSgpKTsKKyAgICAgICAgbVN0YXRlcy5jbGVhcigpOworICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK2xheWVyX3N0YXRlX3QqIFN1cmZhY2VDb21wb3NlckNsaWVudDo6X2dldF9zdGF0ZV9sKGNvbnN0IHNwPFN1cmZhY2U+JiBzdXJmYWNlKQoreworICAgIFN1cmZhY2VJRCBpbmRleCA9IHN1cmZhY2UtPklEKCk7CisgICAgcGVyX2NsaWVudF9jYmxrX3QqIGNvbnN0IGNibGsgPSBtQ29udHJvbDsKKyAgICBzdGF0dXNfdCBlcnIgPSB2YWxpZGF0ZVN1cmZhY2UoY2Jsaywgc3VyZmFjZS5nZXQoKSk7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAvLyBBUEkgdXNhZ2UgZXJyb3IsIGRvIG5vdGhpbmcuCisgICAgaWYgKG1UcmFuc2FjdGlvbk9wZW48PTApIHsKKyAgICAgICAgTE9HRSgiTm90IGluIHRyYW5zYWN0aW9uIChjbGllbnQ9JXAsIFN1cmZhY2VJRD0lZCwgbVRyYW5zYWN0aW9uT3Blbj0lZCIsCisgICAgICAgICAgICAgICAgdGhpcywgaW50KGluZGV4KSwgbVRyYW5zYWN0aW9uT3Blbik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIHVzZSBtUHJlYnVpbHRMYXllclN0YXRlIGp1c3QgdG8gZmluZCBvdXQgaWYgd2UgYWxyZWFkeSBoYXZlIGl0CisgICAgbGF5ZXJfc3RhdGVfdCYgZHVtbXkgPSAqbVByZWJ1aWx0TGF5ZXJTdGF0ZTsKKyAgICBkdW1teS5zdXJmYWNlID0gaW5kZXg7CisgICAgc3NpemVfdCBpID0gbVN0YXRlcy5pbmRleE9mKGR1bW15KTsKKyAgICBpZiAoaSA8IDApIHsKKyAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSBpdCwgYWRkIGFuIGluaXRpYWxpemVkIGxheWVyX3N0YXRlIHRvIG91ciBsaXN0CisgICAgICAgIGkgPSBtU3RhdGVzLmFkZChkdW1teSk7CisgICAgfQorICAgIHJldHVybiBtU3RhdGVzLmVkaXRBcnJheSgpICsgaTsKK30KKworbGF5ZXJfc3RhdGVfdCogU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpfbG9ja0xheWVyU3RhdGUoY29uc3Qgc3A8U3VyZmFjZT4mIHN1cmZhY2UpCit7CisgICAgbGF5ZXJfc3RhdGVfdCogczsKKyAgICBtTG9jay5sb2NrKCk7CisgICAgcyA9IF9nZXRfc3RhdGVfbChzdXJmYWNlKTsKKyAgICBpZiAoIXMpIG1Mb2NrLnVubG9jaygpOworICAgIHJldHVybiBzOworfQorCit2b2lkIFN1cmZhY2VDb21wb3NlckNsaWVudDo6X3VubG9ja0xheWVyU3RhdGUoKQoreworICAgIG1Mb2NrLnVubG9jaygpOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OnNldFBvc2l0aW9uKFN1cmZhY2UqIHN1cmZhY2UsIGludDMyX3QgeCwgaW50MzJfdCB5KQoreworICAgIGxheWVyX3N0YXRlX3QqIHMgPSBfbG9ja0xheWVyU3RhdGUoc3VyZmFjZSk7CisgICAgaWYgKCFzKSByZXR1cm4gQkFEX0lOREVYOworICAgIHMtPndoYXQgfD0gSVN1cmZhY2VDb21wb3Nlcjo6ZVBvc2l0aW9uQ2hhbmdlZDsKKyAgICBzLT54ID0geDsKKyAgICBzLT55ID0geTsKKyAgICBfdW5sb2NrTGF5ZXJTdGF0ZSgpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpzZXRTaXplKFN1cmZhY2UqIHN1cmZhY2UsIHVpbnQzMl90IHcsIHVpbnQzMl90IGgpCit7CisgICAgbGF5ZXJfc3RhdGVfdCogcyA9IF9sb2NrTGF5ZXJTdGF0ZShzdXJmYWNlKTsKKyAgICBpZiAoIXMpIHJldHVybiBCQURfSU5ERVg7CisgICAgcy0+d2hhdCB8PSBJU3VyZmFjZUNvbXBvc2VyOjplU2l6ZUNoYW5nZWQ7CisgICAgcy0+dyA9IHc7CisgICAgcy0+aCA9IGg7CisgICAgX3VubG9ja0xheWVyU3RhdGUoKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6c2V0TGF5ZXIoU3VyZmFjZSogc3VyZmFjZSwgaW50MzJfdCB6KQoreworICAgIGxheWVyX3N0YXRlX3QqIHMgPSBfbG9ja0xheWVyU3RhdGUoc3VyZmFjZSk7CisgICAgaWYgKCFzKSByZXR1cm4gQkFEX0lOREVYOworICAgIHMtPndoYXQgfD0gSVN1cmZhY2VDb21wb3Nlcjo6ZUxheWVyQ2hhbmdlZDsKKyAgICBzLT56ID0gejsKKyAgICBfdW5sb2NrTGF5ZXJTdGF0ZSgpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgU3VyZmFjZUNvbXBvc2VyQ2xpZW50OjpoaWRlKFN1cmZhY2UqIHN1cmZhY2UpCit7CisgICAgcmV0dXJuIHNldEZsYWdzKHN1cmZhY2UsIElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckhpZGRlbiwKKyAgICAgICAgICAgIElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckhpZGRlbik7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6c2hvdyhTdXJmYWNlKiBzdXJmYWNlLCBpbnQzMl90KQoreworICAgIHJldHVybiBzZXRGbGFncyhzdXJmYWNlLCAwLCBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJIaWRkZW4pOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OmZyZWV6ZShTdXJmYWNlKiBzdXJmYWNlKQoreworICAgIHJldHVybiBzZXRGbGFncyhzdXJmYWNlLCBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJGcm96ZW4sCisgICAgICAgICAgICBJU3VyZmFjZUNvbXBvc2VyOjplTGF5ZXJGcm96ZW4pOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OnVuZnJlZXplKFN1cmZhY2UqIHN1cmZhY2UpCit7CisgICAgcmV0dXJuIHNldEZsYWdzKHN1cmZhY2UsIDAsIElTdXJmYWNlQ29tcG9zZXI6OmVMYXllckZyb3plbik7Cit9CisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6c2V0RmxhZ3MoU3VyZmFjZSogc3VyZmFjZSwKKyAgICAgICAgdWludDMyX3QgZmxhZ3MsIHVpbnQzMl90IG1hc2spCit7CisgICAgbGF5ZXJfc3RhdGVfdCogcyA9IF9sb2NrTGF5ZXJTdGF0ZShzdXJmYWNlKTsKKyAgICBpZiAoIXMpIHJldHVybiBCQURfSU5ERVg7CisgICAgcy0+d2hhdCB8PSBJU3VyZmFjZUNvbXBvc2VyOjplVmlzaWJpbGl0eUNoYW5nZWQ7CisgICAgcy0+ZmxhZ3MgJj0gfm1hc2s7CisgICAgcy0+ZmxhZ3MgfD0gKGZsYWdzICYgbWFzayk7CisgICAgcy0+bWFzayB8PSBtYXNrOworICAgIF91bmxvY2tMYXllclN0YXRlKCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisKK3N0YXR1c190IFN1cmZhY2VDb21wb3NlckNsaWVudDo6c2V0VHJhbnNwYXJlbnRSZWdpb25IaW50KAorICAgICAgICBTdXJmYWNlKiBzdXJmYWNlLCBjb25zdCBSZWdpb24mIHRyYW5zcGFyZW50UmVnaW9uKQoreworICAgIGxheWVyX3N0YXRlX3QqIHMgPSBfbG9ja0xheWVyU3RhdGUoc3VyZmFjZSk7CisgICAgaWYgKCFzKSByZXR1cm4gQkFEX0lOREVYOworICAgIHMtPndoYXQgfD0gSVN1cmZhY2VDb21wb3Nlcjo6ZVRyYW5zcGFyZW50UmVnaW9uQ2hhbmdlZDsKKyAgICBzLT50cmFuc3BhcmVudFJlZ2lvbiA9IHRyYW5zcGFyZW50UmVnaW9uOworICAgIF91bmxvY2tMYXllclN0YXRlKCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OnNldEFscGhhKFN1cmZhY2UqIHN1cmZhY2UsIGZsb2F0IGFscGhhKQoreworICAgIGxheWVyX3N0YXRlX3QqIHMgPSBfbG9ja0xheWVyU3RhdGUoc3VyZmFjZSk7CisgICAgaWYgKCFzKSByZXR1cm4gQkFEX0lOREVYOworICAgIHMtPndoYXQgfD0gSVN1cmZhY2VDb21wb3Nlcjo6ZUFscGhhQ2hhbmdlZDsKKyAgICBzLT5hbHBoYSA9IGFscGhhOworICAgIF91bmxvY2tMYXllclN0YXRlKCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OnNldE1hdHJpeCgKKyAgICAgICAgU3VyZmFjZSogc3VyZmFjZSwKKyAgICAgICAgZmxvYXQgZHNkeCwgZmxvYXQgZHRkeCwKKyAgICAgICAgZmxvYXQgZHNkeSwgZmxvYXQgZHRkeSApCit7CisgICAgbGF5ZXJfc3RhdGVfdCogcyA9IF9sb2NrTGF5ZXJTdGF0ZShzdXJmYWNlKTsKKyAgICBpZiAoIXMpIHJldHVybiBCQURfSU5ERVg7CisgICAgcy0+d2hhdCB8PSBJU3VyZmFjZUNvbXBvc2VyOjplTWF0cml4Q2hhbmdlZDsKKyAgICBsYXllcl9zdGF0ZV90OjptYXRyaXgyMl90IG1hdHJpeDsKKyAgICBtYXRyaXguZHNkeCA9IGRzZHg7CisgICAgbWF0cml4LmR0ZHggPSBkdGR4OworICAgIG1hdHJpeC5kc2R5ID0gZHNkeTsKKyAgICBtYXRyaXguZHRkeSA9IGR0ZHk7CisgICAgcy0+bWF0cml4ID0gbWF0cml4OworICAgIF91bmxvY2tMYXllclN0YXRlKCk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdXJmYWNlQ29tcG9zZXJDbGllbnQ6OnNldEZyZWV6ZVRpbnQoU3VyZmFjZSogc3VyZmFjZSwgdWludDMyX3QgdGludCkKK3sKKyAgICBsYXllcl9zdGF0ZV90KiBzID0gX2xvY2tMYXllclN0YXRlKHN1cmZhY2UpOworICAgIGlmICghcykgcmV0dXJuIEJBRF9JTkRFWDsKKyAgICBzLT53aGF0IHw9IElTdXJmYWNlQ29tcG9zZXI6OmVGcmVlemVUaW50Q2hhbmdlZDsKKyAgICBzLT50aW50ID0gdGludDsKKyAgICBfdW5sb2NrTGF5ZXJTdGF0ZSgpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvbGlicy91aS9TdXJmYWNlRmxpbmdlclN5bmNocm8uY3BwIGIvbGlicy91aS9TdXJmYWNlRmxpbmdlclN5bmNocm8uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjZDk3NTUKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3VpL1N1cmZhY2VGbGluZ2VyU3luY2hyby5jcHAKQEAgLTAsMCArMSwxMjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN1cmZhY2VGbGluZ2VyU3luY2hybyIKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorCisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdWkvU3VyZmFjZUZsaW5nZXJTeW5jaHJvLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1N1cmZhY2VGbGluZ2VyU3luY2hybzo6QmFycmllcjo6QmFycmllcigpCisgICAgOiBzdGF0ZShDTE9TRUQpIHsgCit9CisKK1N1cmZhY2VGbGluZ2VyU3luY2hybzo6QmFycmllcjo6fkJhcnJpZXIoKSB7IAorfQorCit2b2lkIFN1cmZhY2VGbGluZ2VyU3luY2hybzo6QmFycmllcjo6b3BlbigpIHsKKyAgICBhc20gdm9sYXRpbGUgKCIiOjo6Im1lbW9yeSIpOworICAgIE11dGV4OjpBdXRvbG9jayBfbChsb2NrKTsKKyAgICBzdGF0ZSA9IE9QRU5FRDsKKyAgICBjdi5icm9hZGNhc3QoKTsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlclN5bmNocm86OkJhcnJpZXI6OmNsb3NlKCkgeworICAgIE11dGV4OjpBdXRvbG9jayBfbChsb2NrKTsKKyAgICBzdGF0ZSA9IENMT1NFRDsKK30KKwordm9pZCBTdXJmYWNlRmxpbmdlclN5bmNocm86OkJhcnJpZXI6OndhaXRBbmRDbG9zZSgpIAoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChsb2NrKTsKKyAgICB3aGlsZSAoc3RhdGUgPT0gQ0xPU0VEKSB7CisgICAgICAgIC8vIHdlJ3JlIGFib3V0IHRvIHdhaXQsIGZsdXNoIHRoZSBiaW5kZXIgY29tbWFuZCBidWZmZXIKKyAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNlbGYoKS0+Zmx1c2hDb21tYW5kcygpOworICAgICAgICBjdi53YWl0KGxvY2spOworICAgIH0KKyAgICBzdGF0ZSA9IENMT1NFRDsKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjpCYXJyaWVyOjp3YWl0QW5kQ2xvc2UobnNlY3NfdCB0aW1lb3V0KSAKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobG9jayk7CisgICAgd2hpbGUgKHN0YXRlID09IENMT1NFRCkgeworICAgICAgICAvLyB3ZSdyZSBhYm91dCB0byB3YWl0LCBmbHVzaCB0aGUgYmluZGVyIGNvbW1hbmQgYnVmZmVyCisgICAgICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmZsdXNoQ29tbWFuZHMoKTsKKyAgICAgICAgaW50IGVyciA9IGN2LndhaXRSZWxhdGl2ZShsb2NrLCB0aW1lb3V0KTsKKyAgICAgICAgaWYgKGVyciAhPSAwKQorICAgICAgICAgICAgcmV0dXJuIGVycjsKKyAgICB9CisgICAgc3RhdGUgPSBDTE9TRUQ7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjpTdXJmYWNlRmxpbmdlclN5bmNocm8oY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIGZsaW5nZXIpCisgICAgOiBtU3VyZmFjZUNvbXBvc2VyKGZsaW5nZXIpCit7Cit9CisKK1N1cmZhY2VGbGluZ2VyU3luY2hybzo6U3VyZmFjZUZsaW5nZXJTeW5jaHJvKCkKK3sKK30KKworU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjp+U3VyZmFjZUZsaW5nZXJTeW5jaHJvKCkKK3sKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjpzaWduYWwoKQoreworICAgIG1TdXJmYWNlQ29tcG9zZXItPnNpZ25hbCgpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjp3YWl0KCkKK3sKKyAgICBtQmFycmllci53YWl0QW5kQ2xvc2UoKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN1cmZhY2VGbGluZ2VyU3luY2hybzo6d2FpdChuc2Vjc190IHRpbWVvdXQpCit7CisgICAgaWYgKHRpbWVvdXQgPT0gMCkKKyAgICAgICAgcmV0dXJuIFN1cmZhY2VGbGluZ2VyU3luY2hybzo6d2FpdCgpOworICAgIHJldHVybiBtQmFycmllci53YWl0QW5kQ2xvc2UodGltZW91dCk7Cit9CisKK3ZvaWQgU3VyZmFjZUZsaW5nZXJTeW5jaHJvOjpvcGVuKCkKK3sKKyAgICBtQmFycmllci5vcGVuKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL3VpL1RpbWUuY3BwIGIvbGlicy91aS9UaW1lLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTUzOTEzCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91aS9UaW1lLmNwcApAQCAtMCwwICsxLDE5OSBAQAorI2luY2x1ZGUgPHV0aWxzL1RpbWVVdGlscy5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8Y3V0aWxzL3R6dGltZS5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0YXRpYyB2b2lkCitkdW1wKGNvbnN0IFRpbWUmIHQpCit7CisgICAgI2lmZGVmIEhBVkVfVE1fR01UT0ZGCisgICAgICAgIGxvbmcgdG1fZ210b2ZmID0gdC50LnRtX2dtdG9mZjsKKyAgICAjZWxzZQorICAgICAgICBsb25nIHRtX2dtdG9mZiA9IDA7CisgICAgI2VuZGlmCisgICAgcHJpbnRmKCIlMDRkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCAoJWQsJWxkLCVkLCVkKVxuIiwKKyAgICAgICAgICAgIHQudC50bV95ZWFyKzE5MDAsIHQudC50bV9tb24rMSwgdC50LnRtX21kYXksCisgICAgICAgICAgICB0LnQudG1faG91ciwgdC50LnRtX21pbiwgdC50LnRtX3NlYywKKyAgICAgICAgICAgIHQudC50bV9pc2RzdCwgdG1fZ210b2ZmLCB0LnQudG1fd2RheSwgdC50LnRtX3lkYXkpOworfQorCitUaW1lOjpUaW1lKCkKK3sKKyAgICB0LnRtX3NlYyA9IDA7CisgICAgdC50bV9taW4gPSAwOworICAgIHQudG1faG91ciA9IDA7CisgICAgdC50bV9tZGF5ID0gMDsKKyAgICB0LnRtX21vbiA9IDA7CisgICAgdC50bV95ZWFyID0gMDsKKyAgICB0LnRtX3dkYXkgPSAwOworICAgIHQudG1feWRheSA9IDA7CisgICAgdC50bV9pc2RzdCA9IC0xOyAvLyB3ZSBkb24ndCBrbm93LCBzbyBsZXQgdGhlIEMgbGlicmFyeSBkZXRlcm1pbmUKKyAgICAjaWZkZWYgSEFWRV9UTV9HTVRPRkYKKyAgICAgICAgdC50bV9nbXRvZmYgPSAwOworICAgICNlbmRpZgorfQorCisKKyNkZWZpbmUgQ09NUEFSRV9GSUVMRChmaWVsZCkgZG8geyBcCisgICAgICAgIGludCBkaWZmID0gYS50LmZpZWxkIC0gYi50LmZpZWxkOyBcCisgICAgICAgIGlmIChkaWZmICE9IDApIHJldHVybiBkaWZmOyBcCisgICAgfSB3aGlsZSgwKQorCitpbnQKK1RpbWU6OmNvbXBhcmUoVGltZSYgYSwgVGltZSYgYikKK3sKKyAgICBpZiAoMCA9PSBzdHJjbXAoYS50aW1lem9uZSwgYi50aW1lem9uZSkpIHsKKyAgICAgICAgLy8gaWYgdGhlIHRpbWV6b25lcyBhcmUgdGhlIHNhbWUsIHdlIGNhbiBlYXNpbHkgY29tcGFyZSB0aGUgdHdvCisgICAgICAgIC8vIHRpbWVzLiAgT3RoZXJ3aXNlLCBjb252ZXJ0IHRvIG1pbGxpc2Vjb25kcyBhbmQgY29tcGFyZSB0aGF0LgorICAgICAgICAvLyBUaGlzIHJlcXVpcmVzIHRoYXQgb2JqZWN0IGJlIG5vcm1hbGl6ZWQuCisgICAgICAgIENPTVBBUkVfRklFTEQodG1feWVhcik7CisgICAgICAgIENPTVBBUkVfRklFTEQodG1fbW9uKTsKKyAgICAgICAgQ09NUEFSRV9GSUVMRCh0bV9tZGF5KTsKKyAgICAgICAgQ09NUEFSRV9GSUVMRCh0bV9ob3VyKTsKKyAgICAgICAgQ09NUEFSRV9GSUVMRCh0bV9taW4pOworICAgICAgICBDT01QQVJFX0ZJRUxEKHRtX3NlYyk7CisgICAgICAgIHJldHVybiAwOworICAgIH0gZWxzZSB7CisgICAgICAgIGludDY0X3QgYW0gPSBhLnRvTWlsbGlzKGZhbHNlIC8qIHVzZSBpc0RzdCAqLyk7CisgICAgICAgIGludDY0X3QgYm0gPSBiLnRvTWlsbGlzKGZhbHNlIC8qIHVzZSBpc0RzdCAqLyk7CisgICAgICAgIGludDY0X3QgZGlmZiA9IGFtLWJtOworICAgICAgICByZXR1cm4gKGRpZmYgPCAwKSA/IC0xIDogKChkaWZmID4gMCkgPyAxIDogMCk7CisgICAgfQorfQorCitzdGF0aWMgY29uc3QgaW50IERBWVNfUEVSX01PTlRIW10gPSB7CisgICAgICAgICAgICAgICAgICAgICAgICAzMSwgMjgsIDMxLCAzMCwgMzEsIDMwLCAzMSwgMzEsIDMwLCAzMSwgMzAsIDMxCisgICAgICAgICAgICAgICAgICAgIH07CisKK3N0YXRpYyBpbmxpbmUgaW50IGRheXNfdGhpc19tb250aChpbnQgeWVhciwgaW50IG1vbnRoKQoreworICAgIGludCBuID0gREFZU19QRVJfTU9OVEhbbW9udGhdOworICAgIGlmIChuICE9IDI4KSB7CisgICAgICAgIHJldHVybiBuOworICAgIH0gZWxzZSB7CisgICAgICAgIGludCB5ID0geWVhcjsKKyAgICAgICAgcmV0dXJuICgoeSU0KT09MCYmKCh5JTEwMCkhPTB8fCh5JTQwMCk9PTApKSA/IDI5IDogMjg7CisgICAgfQorfQorCit2b2lkIAorVGltZTo6c3dpdGNoVGltZXpvbmUoY29uc3QgY2hhciogdGltZXpvbmUpCit7CisgICAgdGltZV90IHNlY29uZHMgPSBta3RpbWVfdHooJih0aGlzLT50KSwgdGhpcy0+dGltZXpvbmUpOworICAgIGxvY2FsdGltZV90eigmc2Vjb25kcywgJih0aGlzLT50KSwgdGltZXpvbmUpOworfQorCitTdHJpbmc4IAorVGltZTo6Zm9ybWF0KGNvbnN0IGNoYXIgKmZvcm1hdCwgY29uc3Qgc3RydWN0IHN0cmZ0aW1lX2xvY2FsZSAqbG9jYWxlKSBjb25zdAoreworICAgIGNoYXIgYnVmWzI1N107CisgICAgaW50IG4gPSBzdHJmdGltZV90eihidWYsIDI1NywgZm9ybWF0LCAmKHRoaXMtPnQpLCBsb2NhbGUpOworICAgIGlmIChuID4gMCkgeworICAgICAgICByZXR1cm4gU3RyaW5nOChidWYpOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTdHJpbmc4KCk7CisgICAgfQorfQorCitzdGF0aWMgaW5saW5lIHNob3J0Cit0b2NoYXIoaW50IG4pCit7CisgICAgcmV0dXJuIChuID49IDAgJiYgbiA8PSA5KSA/ICgnMCcrbikgOiAnICc7Cit9CisKK3N0YXRpYyBpbmxpbmUgc2hvcnQKK25leHRfY2hhcihpbnQgKm0sIGludCBrKQoreworICAgIGludCBuID0gKm0gLyBrOworICAgICptID0gKm0gJSBrOworICAgIHJldHVybiB0b2NoYXIobik7Cit9CisKK3ZvaWQKK1RpbWU6OmZvcm1hdDI0NDUoc2hvcnQqIGJ1ZiwgYm9vbCBoYXNUaW1lKSBjb25zdAoreworICAgIGludCBuOworCisgICAgbiA9IHQudG1feWVhcisxOTAwOworICAgIGJ1ZlswXSA9IG5leHRfY2hhcigmbiwgMTAwMCk7CisgICAgYnVmWzFdID0gbmV4dF9jaGFyKCZuLCAxMDApOworICAgIGJ1ZlsyXSA9IG5leHRfY2hhcigmbiwgMTApOworICAgIGJ1ZlszXSA9IHRvY2hhcihuKTsKKworICAgIG4gPSB0LnRtX21vbisxOworICAgIGJ1Zls0XSA9IG5leHRfY2hhcigmbiwgMTApOworICAgIGJ1Zls1XSA9IHRvY2hhcihuKTsKKworICAgIG4gPSB0LnRtX21kYXk7CisgICAgYnVmWzZdID0gbmV4dF9jaGFyKCZuLCAxMCk7CisgICAgYnVmWzddID0gdG9jaGFyKG4pOworCisgICAgaWYgKGhhc1RpbWUpIHsKKyAgICAgIGJ1Zls4XSA9ICdUJzsKKworICAgICAgbiA9IHQudG1faG91cjsKKyAgICAgIGJ1Zls5XSA9IG5leHRfY2hhcigmbiwgMTApOworICAgICAgYnVmWzEwXSA9IHRvY2hhcihuKTsKKyAgICAgIAorICAgICAgbiA9IHQudG1fbWluOworICAgICAgYnVmWzExXSA9IG5leHRfY2hhcigmbiwgMTApOworICAgICAgYnVmWzEyXSA9IHRvY2hhcihuKTsKKyAgICAgIAorICAgICAgbiA9IHQudG1fc2VjOworICAgICAgYnVmWzEzXSA9IG5leHRfY2hhcigmbiwgMTApOworICAgICAgYnVmWzE0XSA9IHRvY2hhcihuKTsKKyAgICAgIGJvb2wgaW5VdGMgPSBzdHJjbXAoIlVUQyIsIHRpbWV6b25lKSA9PSAwOworICAgICAgaWYgKGluVXRjKSB7CisgICAgICAgICAgYnVmWzE1XSA9ICdaJzsKKyAgICAgIH0KKyAgICB9Cit9CisKK1N0cmluZzggCitUaW1lOjp0b1N0cmluZygpIGNvbnN0Cit7CisgICAgU3RyaW5nOCBzdHI7CisgICAgY2hhciogcyA9IHN0ci5sb2NrQnVmZmVyKDE1MCk7CisgICAgI2lmZGVmIEhBVkVfVE1fR01UT0ZGCisgICAgICAgIGxvbmcgdG1fZ210b2ZmID0gdC50bV9nbXRvZmY7CisgICAgI2Vsc2UKKyAgICAgICAgbG9uZyB0bV9nbXRvZmYgPSAwOworICAgICNlbmRpZgorICAgIHNwcmludGYocywgIiUwNGQlMDJkJTAyZFQlMDJkJTAyZCUwMmQlcyglZCwlZCwlbGQsJWQsJWQpIiwgCisgICAgICAgICAgICB0LnRtX3llYXIrMTkwMCwgdC50bV9tb24rMSwgdC50bV9tZGF5LCB0LnRtX2hvdXIsIHQudG1fbWluLAorICAgICAgICAgICAgdC50bV9zZWMsIHRpbWV6b25lLCB0LnRtX3dkYXksIHQudG1feWRheSwgdG1fZ210b2ZmLCB0LnRtX2lzZHN0LAorICAgICAgICAgICAgKGludCkoKChUaW1lKil0aGlzKS0+dG9NaWxsaXMoZmFsc2UgLyogdXNlIGlzRHN0ICovKS8xMDAwKSk7CisgICAgc3RyLnVubG9ja0J1ZmZlcigpOworICAgIHJldHVybiBzdHI7Cit9CisKK3ZvaWQgCitUaW1lOjpzZXRUb05vdygpCit7CisgICAgdGltZV90IHNlY29uZHM7CisgICAgdGltZSgmc2Vjb25kcyk7CisgICAgbG9jYWx0aW1lX3R6KCZzZWNvbmRzLCAmKHRoaXMtPnQpLCB0aGlzLT50aW1lem9uZSk7Cit9CisKK2ludDY0X3QgCitUaW1lOjp0b01pbGxpcyhib29sIGlnbm9yZURzdCkKK3sKKyAgICBpZiAoaWdub3JlRHN0KSB7CisgICAgICAgIHRoaXMtPnQudG1faXNkc3QgPSAtMTsKKyAgICB9CisgICAgaW50NjRfdCByID0gbWt0aW1lX3R6KCYodGhpcy0+dCksIHRoaXMtPnRpbWV6b25lKTsKKyAgICBpZiAociA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiByICogMTAwMDsKK30KKwordm9pZCAKK1RpbWU6OnNldChpbnQ2NF90IG1pbGxpcykKK3sKKyAgICB0aW1lX3Qgc2Vjb25kcyA9IG1pbGxpcyAvIDEwMDA7CisgICAgbG9jYWx0aW1lX3R6KCZzZWNvbmRzLCAmKHRoaXMtPnQpLCB0aGlzLT50aW1lem9uZSk7Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvQW5kcm9pZC5tayBiL2xpYnMvdXRpbHMvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZGI4Y2EyCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsMTU2IEBACisjIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKKworIyBsaWJ1dGlscyBpcyBhIGxpdHRsZSB1bmlxdWU6IEl0J3MgYnVpbHQgdHdpY2UsIG9uY2UgZm9yIHRoZSBob3N0CisjIGFuZCBvbmNlIGZvciB0aGUgZGV2aWNlLgorCitjb21tb25Tb3VyY2VzOj0gXAorCUFzc2V0LmNwcCBcCisJQXNzZXREaXIuY3BwIFwKKwlBc3NldE1hbmFnZXIuY3BwIFwKKwlCdWZmZXJlZFRleHRPdXRwdXQuY3BwIFwKKwlDYWxsU3RhY2suY3BwIFwKKwlEZWJ1Zy5jcHAgXAorCUZpbGVNYXAuY3BwIFwKKwlSZWZCYXNlLmNwcCBcCisJUmVzb3VyY2VUeXBlcy5jcHAgXAorCVNoYXJlZEJ1ZmZlci5jcHAgXAorCVN0YXRpYy5jcHAgXAorCVN0b3BXYXRjaC5jcHAgXAorCVN0cmluZzguY3BwIFwKKwlTdHJpbmcxNi5jcHAgXAorCVN5c3RlbUNsb2NrLmNwcCBcCisJVGV4dE91dHB1dC5jcHAgXAorCVRocmVhZHMuY3BwIFwKKwlUaW1lclByb2JlLmNwcCBcCisJVGltZXJzLmNwcCBcCisJVmVjdG9ySW1wbC5jcHAgXAorICAgIFppcEZpbGVDUk8uY3BwIFwKKwlaaXBGaWxlUk8uY3BwIFwKKwlaaXBVdGlscy5jcHAgXAorCW1pc2MuY3BwIFwKKwlwb3J0ZWQuY3BwIFwKKwlMb2dTb2NrZXQuY3BwCisKKyMKKyMgVGhlIGNwcCBmaWxlcyBsaXN0ZWQgaGVyZSBkbyBub3QgYmVsb25nIGluIHRoZSBkZXZpY2UKKyMgYnVpbGQuICBDb25zdWx0IHdpdGggdGhlIHN3ZXRsYW5kIGJlZm9yZSBldmVuIHRoaW5raW5nIGFib3V0CisjIHB1dHRpbmcgdGhlbSBpbiBjb21tb25Tb3VyY2VzLgorIworIyBUaGV5J3JlIHVzZWQgYnkgdGhlIHNpbXVsYXRvciBydW50aW1lIGFuZCBieSBob3N0LXNpZGUgdG9vbHMgbGlrZQorIyBhYXB0IGFuZCB0aGUgc2ltdWxhdG9yIGZyb250LWVuZC4KKyMKK2hvc3RTb3VyY2VzOj0gXAorCUluZXRBZGRyZXNzLmNwcCBcCisJUGlwZS5jcHAgXAorCVNvY2tldC5jcHAgXAorCVppcEVudHJ5LmNwcCBcCisJWmlwRmlsZS5jcHAKKworIyBGb3IgdGhlIGhvc3QKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9ICQoY29tbW9uU291cmNlcykgJChob3N0U291cmNlcykKKworaWZlcSAoJChIT1NUX09TKSxsaW51eCkKKyMgVXNlIHRoZSBmdXRleCBiYXNlZCBtdXRleCBhbmQgY29uZGl0aW9uIHZhcmlhYmxlCisjIGltcGxlbWVudGF0aW9uIGZyb20gYW5kcm9pZC1hcm0gYmVjYXVzZSBpdCdzIHNoYXJlZCBtZW0gc2FmZQorCUxPQ0FMX1NSQ19GSUxFUyArPSBcCisJCWZ1dGV4X3N5bmNocm8uYyBcCisJCWV4ZWN1dGFibGVwYXRoX2xpbnV4LmNwcAorZW5kaWYKK2lmZXEgKCQoSE9TVF9PUyksZGFyd2luKQorCUxPQ0FMX1NSQ19GSUxFUyArPSBcCisJCWV4ZWN1dGFibGVwYXRoX2Rhcndpbi5jcHAKK2VuZGlmCisKK0xPQ0FMX01PRFVMRTo9IGxpYnV0aWxzCisKK0xPQ0FMX0NGTEFHUyArPSAtRExJQlVUSUxTX05BVElWRT0xICQoVE9PTF9DRkxBR1MpCitMT0NBTF9DX0lOQ0xVREVTICs9IGV4dGVybmFsL3psaWIKKworaWZlcSAoJChIT1NUX09TKSx3aW5kb3dzKQoraWZlcSAoJChzdHJpcCAkKFVTRV9DWUdXSU4pLCksKQorIyBVbmRlciBNaW5HVywgY3R5cGUuaCBkb2Vzbid0IG5lZWQgbXVsdGktYnl0ZSBzdXBwb3J0CitMT0NBTF9DRkxBR1MgKz0gLURNQl9DVVJfTUFYPTEKK2VuZGlmCitlbmRpZgorCitpbmNsdWRlICQoQlVJTERfSE9TVF9TVEFUSUNfTElCUkFSWSkKKworCisKKyMgRm9yIHRoZSBkZXZpY2UKKyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCisKKyMgd2UgaGF2ZSB0aGUgY29tbW9uIHNvdXJjZXMsIHBsdXMgc29tZSBkZXZpY2Utc3BlY2lmaWMgc3R1ZmYKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKwkkKGNvbW1vblNvdXJjZXMpIFwKKwlCaW5kZXIuY3BwIFwKKwlCcEJpbmRlci5jcHAgXAorCUlJbnRlcmZhY2UuY3BwIFwKKwlJTWVtb3J5LmNwcCBcCisJSVBDVGhyZWFkU3RhdGUuY3BwIFwKKwlNZW1vcnlEZWFsZXIuY3BwIFwKKyAgICBNZW1vcnlCYXNlLmNwcCBcCisgICAgTWVtb3J5SGVhcEJhc2UuY3BwIFwKKyAgICBNZW1vcnlIZWFwUG1lbS5jcHAgXAorCVBhcmNlbC5jcHAgXAorCVByb2Nlc3NTdGF0ZS5jcHAgXAorCUlQZXJtaXNzaW9uQ29udHJvbGxlci5jcHAgXAorCUlTZXJ2aWNlTWFuYWdlci5jcHAgXAorCVVuaWNvZGUuY3BwCisKK2lmZXEgKCQoVEFSR0VUX1NJTVVMQVRPUiksdHJ1ZSkKK0xPQ0FMX1NSQ19GSUxFUyArPSAkKGhvc3RTb3VyY2VzKQorZW5kaWYKKworaWZlcSAoJChUQVJHRVRfT1MpLGxpbnV4KQorIyBVc2UgdGhlIGZ1dGV4IGJhc2VkIG11dGV4IGFuZCBjb25kaXRpb24gdmFyaWFibGUKKyMgaW1wbGVtZW50YXRpb24gZnJvbSBhbmRyb2lkLWFybSBiZWNhdXNlIGl0J3Mgc2hhcmVkIG1lbSBzYWZlCitMT0NBTF9TUkNfRklMRVMgKz0gZnV0ZXhfc3luY2hyby5jCitMT0NBTF9MRExJQlMgKz0gLWxydCAtbGRsCitlbmRpZgorCitMT0NBTF9DX0lOQ0xVREVTICs9IFwKKwkJZXh0ZXJuYWwvemxpYiBcCisJCWV4dGVybmFsL2ljdTRjL2NvbW1vbgorTE9DQUxfTERMSUJTICs9IC1scHRocmVhZAorCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJ6IFwKKwlsaWJsb2cgXAorCWxpYmN1dGlscworCitpZm5lcSAoJChUQVJHRVRfU0lNVUxBVE9SKSx0cnVlKQoraWZlcSAoJChUQVJHRVRfT1MpLSQoVEFSR0VUX0FSQ0gpLGxpbnV4LXg4NikKKyMgVGhpcyBpcyBuZWVkZWQgb24geDg2IHRvIGJyaW5nIGluIGRsX2l0ZXJhdGVfcGhkciBmb3IgQ2FsbFN0YWNrLmNwcAorTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBcCisJbGliZGwKK2VuZGlmICMgbGludXgteDg2CitlbmRpZiAjIHNpbQorCitMT0NBTF9NT0RVTEU6PSBsaWJ1dGlscworCisjTE9DQUxfQ0ZMQUdTKz0KKyNMT0NBTF9MREZMQUdTOj0KKworaW5jbHVkZSAkKEJVSUxEX1NIQVJFRF9MSUJSQVJZKQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL0Fzc2V0LmNwcCBiL2xpYnMvdXRpbHMvQXNzZXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMjAzZGQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0Fzc2V0LmNwcApAQCAtMCwwICsxLDgxMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBQcm92aWRlIGFjY2VzcyB0byBhIHJlYWQtb25seSBhc3NldC4KKy8vCisKKyNkZWZpbmUgTE9HX1RBRyAiYXNzZXQiCisvLyNkZWZpbmUgTkRFQlVHIDAKKworI2luY2x1ZGUgPHV0aWxzL0Fzc2V0Lmg+CisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvRmlsZU1hcC5oPgorI2luY2x1ZGUgPHV0aWxzL1ppcFV0aWxzLmg+CisjaW5jbHVkZSA8dXRpbHMvWmlwRmlsZVJPLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxtZW1vcnkuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisjaWZuZGVmIE9fQklOQVJZCisjIGRlZmluZSBPX0JJTkFSWSAwCisjZW5kaWYKKworc3RhdGljIHZvbGF0aWxlIGludDMyX3QgZ0NvdW50ID0gMDsKKworaW50MzJfdCBBc3NldDo6Z2V0R2xvYmFsQ291bnQoKQoreworICAgIHJldHVybiBnQ291bnQ7Cit9CisKK0Fzc2V0OjpBc3NldCh2b2lkKQorICAgIDogbUFjY2Vzc01vZGUoQUNDRVNTX1VOS05PV04pCit7CisgICAgaW50IGNvdW50ID0gYW5kcm9pZF9hdG9taWNfaW5jKCZnQ291bnQpKzE7CisgICAgLy9MT0dJKCJDcmVhdGluZyBBc3NldCAlcCAjJWRcbiIsIHRoaXMsIGNvdW50KTsKK30KKworQXNzZXQ6On5Bc3NldCh2b2lkKQoreworICAgIGludCBjb3VudCA9IGFuZHJvaWRfYXRvbWljX2RlYygmZ0NvdW50KTsKKyAgICAvL0xPR0koIkRlc3Ryb3lpbmcgQXNzZXQgaW4gJXAgIyVkXG4iLCB0aGlzLCBjb3VudCk7Cit9CisKKy8qCisgKiBDcmVhdGUgYSBuZXcgQXNzZXQgZnJvbSBhIGZpbGUgb24gZGlzay4gIFRoZXJlIGlzIGEgZmFpciBjaGFuY2UgdGhhdAorICogdGhlIGZpbGUgZG9lc24ndCBhY3R1YWxseSBleGlzdC4KKyAqCisgKiBXZSBjYW4gdXNlICJtb2RlIiB0byBkZWNpZGUgaG93IHdlIHdhbnQgdG8gZ28gYWJvdXQgaXQuCisgKi8KKy8qc3RhdGljKi8gQXNzZXQqIEFzc2V0OjpjcmVhdGVGcm9tRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIF9GaWxlQXNzZXQqIHBBc3NldDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisgICAgb2ZmX3QgbGVuZ3RoOworICAgIGludCBmZDsKKworICAgIGZkID0gb3BlbihmaWxlTmFtZSwgT19SRE9OTFkgfCBPX0JJTkFSWSk7CisgICAgaWYgKGZkIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKgorICAgICAqIFVuZGVyIExpbnV4LCB0aGUgbHNlZWsgZmFpbHMgaWYgd2UgYWN0dWFsbHkgb3BlbmVkIGEgZGlyZWN0b3J5LiAgVG8KKyAgICAgKiBiZSBjb3JyZWN0IHdlIHNob3VsZCB0ZXN0IHRoZSBmaWxlIHR5cGUgZXhwbGljaXRseSwgYnV0IHNpbmNlIHdlCisgICAgICogYWx3YXlzIG9wZW4gdGhpbmdzIHJlYWQtb25seSBpdCBkb2Vzbid0IHJlYWxseSBtYXR0ZXIsIHNvIHRoZXJlJ3MKKyAgICAgKiBubyB2YWx1ZSBpbiBpbmN1cnJpbmcgdGhlIGV4dHJhIG92ZXJoZWFkIG9mIGFuIGZzdGF0KCkgY2FsbC4KKyAgICAgKi8KKyAgICBsZW5ndGggPSBsc2VlayhmZCwgMCwgU0VFS19FTkQpOworICAgIGlmIChsZW5ndGggPCAwKSB7CisgICAgICAgIDo6Y2xvc2UoZmQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgKHZvaWQpIGxzZWVrKGZkLCAwLCBTRUVLX1NFVCk7CisKKyAgICBwQXNzZXQgPSBuZXcgX0ZpbGVBc3NldDsKKyAgICByZXN1bHQgPSBwQXNzZXQtPm9wZW5DaHVuayhmaWxlTmFtZSwgZmQsIDAsIGxlbmd0aCk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgeworICAgICAgICBkZWxldGUgcEFzc2V0OworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBwQXNzZXQtPm1BY2Nlc3NNb2RlID0gbW9kZTsKKyAgICByZXR1cm4gcEFzc2V0OworfQorCisKKy8qCisgKiBDcmVhdGUgYSBuZXcgQXNzZXQgZnJvbSBhIGNvbXByZXNzZWQgZmlsZSBvbiBkaXNrLiAgVGhlcmUgaXMgYSBmYWlyIGNoYW5jZQorICogdGhhdCB0aGUgZmlsZSBkb2Vzbid0IGFjdHVhbGx5IGV4aXN0LgorICoKKyAqIFdlIGN1cnJlbnRseSBzdXBwb3J0IGd6aXAgZmlsZXMuICBXZSBtaWdodCB3YW50IHRvIGhhbmRsZSAuYnoyIHNvbWVkYXkuCisgKi8KKy8qc3RhdGljKi8gQXNzZXQqIEFzc2V0OjpjcmVhdGVGcm9tQ29tcHJlc3NlZEZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUsCisgICAgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIF9Db21wcmVzc2VkQXNzZXQqIHBBc3NldDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisgICAgb2ZmX3QgZmlsZUxlbjsKKyAgICBib29sIHNjYW5SZXN1bHQ7CisgICAgbG9uZyBvZmZzZXQ7CisgICAgaW50IG1ldGhvZDsKKyAgICBsb25nIHVuY29tcHJlc3NlZExlbiwgY29tcHJlc3NlZExlbjsKKyAgICBpbnQgZmQ7CisKKyAgICBmZCA9IG9wZW4oZmlsZU5hbWUsIE9fUkRPTkxZIHwgT19CSU5BUlkpOworICAgIGlmIChmZCA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgZmlsZUxlbiA9IGxzZWVrKGZkLCAwLCBTRUVLX0VORCk7CisgICAgaWYgKGZpbGVMZW4gPCAwKSB7CisgICAgICAgIDo6Y2xvc2UoZmQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgKHZvaWQpIGxzZWVrKGZkLCAwLCBTRUVLX1NFVCk7CisKKyAgICAvKiB3YW50IGJ1ZmZlcmVkIEkvTyBmb3IgdGhlIGZpbGUgc2NhbjsgbXVzdCBkdXAgc28gZmNsb3NlKCkgaXMgc2FmZSAqLworICAgIEZJTEUqIGZwID0gZmRvcGVuKGR1cChmZCksICJyYiIpOworICAgIGlmIChmcCA9PSBOVUxMKSB7CisgICAgICAgIDo6Y2xvc2UoZmQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICB1bnNpZ25lZCBsb25nIGNyYzMyOworICAgIHNjYW5SZXN1bHQgPSBaaXBVdGlsczo6ZXhhbWluZUd6aXAoZnAsICZtZXRob2QsICZ1bmNvbXByZXNzZWRMZW4sCisgICAgICAgICAgICAgICAgICAgICZjb21wcmVzc2VkTGVuLCAmY3JjMzIpOworICAgIG9mZnNldCA9IGZ0ZWxsKGZwKTsKKyAgICBmY2xvc2UoZnApOworICAgIGlmICghc2NhblJlc3VsdCkgeworICAgICAgICBMT0dEKCJGaWxlICclcycgaXMgbm90IGluIGd6aXAgZm9ybWF0XG4iLCBmaWxlTmFtZSk7CisgICAgICAgIDo6Y2xvc2UoZmQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBwQXNzZXQgPSBuZXcgX0NvbXByZXNzZWRBc3NldDsKKyAgICByZXN1bHQgPSBwQXNzZXQtPm9wZW5DaHVuayhmZCwgb2Zmc2V0LCBtZXRob2QsIHVuY29tcHJlc3NlZExlbiwKKyAgICAgICAgICAgICAgICBjb21wcmVzc2VkTGVuKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSB7CisgICAgICAgIGRlbGV0ZSBwQXNzZXQ7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHBBc3NldC0+bUFjY2Vzc01vZGUgPSBtb2RlOworICAgIHJldHVybiBwQXNzZXQ7Cit9CisKKworI2lmIDAKKy8qCisgKiBDcmVhdGUgYSBuZXcgQXNzZXQgZnJvbSBwYXJ0IG9mIGFuIG9wZW4gZmlsZS4KKyAqLworLypzdGF0aWMqLyBBc3NldCogQXNzZXQ6OmNyZWF0ZUZyb21GaWxlU2VnbWVudChpbnQgZmQsIG9mZl90IG9mZnNldCwKKyAgICBzaXplX3QgbGVuZ3RoLCBBY2Nlc3NNb2RlIG1vZGUpCit7CisgICAgX0ZpbGVBc3NldCogcEFzc2V0OworICAgIHN0YXR1c190IHJlc3VsdDsKKworICAgIHBBc3NldCA9IG5ldyBfRmlsZUFzc2V0OworICAgIHJlc3VsdCA9IHBBc3NldC0+b3BlbkNodW5rKE5VTEwsIGZkLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwQXNzZXQtPm1BY2Nlc3NNb2RlID0gbW9kZTsKKyAgICByZXR1cm4gcEFzc2V0OworfQorCisvKgorICogQ3JlYXRlIGEgbmV3IEFzc2V0IGZyb20gY29tcHJlc3NlZCBkYXRhIGluIGFuIG9wZW4gZmlsZS4KKyAqLworLypzdGF0aWMqLyBBc3NldCogQXNzZXQ6OmNyZWF0ZUZyb21Db21wcmVzc2VkRGF0YShpbnQgZmQsIG9mZl90IG9mZnNldCwKKyAgICBpbnQgY29tcHJlc3Npb25NZXRob2QsIHNpemVfdCB1bmNvbXByZXNzZWRMZW4sIHNpemVfdCBjb21wcmVzc2VkTGVuLAorICAgIEFjY2Vzc01vZGUgbW9kZSkKK3sKKyAgICBfQ29tcHJlc3NlZEFzc2V0KiBwQXNzZXQ7CisgICAgc3RhdHVzX3QgcmVzdWx0OworCisgICAgcEFzc2V0ID0gbmV3IF9Db21wcmVzc2VkQXNzZXQ7CisgICAgcmVzdWx0ID0gcEFzc2V0LT5vcGVuQ2h1bmsoZmQsIG9mZnNldCwgY29tcHJlc3Npb25NZXRob2QsCisgICAgICAgICAgICAgICAgdW5jb21wcmVzc2VkTGVuLCBjb21wcmVzc2VkTGVuKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHBBc3NldC0+bUFjY2Vzc01vZGUgPSBtb2RlOworICAgIHJldHVybiBwQXNzZXQ7Cit9CisjZW5kaWYKKworLyoKKyAqIENyZWF0ZSBhIG5ldyBBc3NldCBmcm9tIGEgbWVtb3J5IG1hcHBpbmcuCisgKi8KKy8qc3RhdGljKi8gQXNzZXQqIEFzc2V0OjpjcmVhdGVGcm9tVW5jb21wcmVzc2VkTWFwKEZpbGVNYXAqIGRhdGFNYXAsCisgICAgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIF9GaWxlQXNzZXQqIHBBc3NldDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisKKyAgICBwQXNzZXQgPSBuZXcgX0ZpbGVBc3NldDsKKyAgICByZXN1bHQgPSBwQXNzZXQtPm9wZW5DaHVuayhkYXRhTWFwKTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHBBc3NldC0+bUFjY2Vzc01vZGUgPSBtb2RlOworICAgIHJldHVybiBwQXNzZXQ7Cit9CisKKy8qCisgKiBDcmVhdGUgYSBuZXcgQXNzZXQgZnJvbSBjb21wcmVzc2VkIGRhdGEgaW4gYSBtZW1vcnkgbWFwcGluZy4KKyAqLworLypzdGF0aWMqLyBBc3NldCogQXNzZXQ6OmNyZWF0ZUZyb21Db21wcmVzc2VkTWFwKEZpbGVNYXAqIGRhdGFNYXAsCisgICAgaW50IG1ldGhvZCwgc2l6ZV90IHVuY29tcHJlc3NlZExlbiwgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIF9Db21wcmVzc2VkQXNzZXQqIHBBc3NldDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisKKyAgICBwQXNzZXQgPSBuZXcgX0NvbXByZXNzZWRBc3NldDsKKyAgICByZXN1bHQgPSBwQXNzZXQtPm9wZW5DaHVuayhkYXRhTWFwLCBtZXRob2QsIHVuY29tcHJlc3NlZExlbik7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwQXNzZXQtPm1BY2Nlc3NNb2RlID0gbW9kZTsKKyAgICByZXR1cm4gcEFzc2V0OworfQorCisKKy8qCisgKiBEbyBnZW5lcmljIHNlZWsoKSBob3VzZWtlZXBpbmcuICBQYXNzIGluIHRoZSBvZmZzZXQvd2hlbmNlIHZhbHVlcyBmcm9tCisgKiB0aGUgc2VlayByZXF1ZXN0LCBhbG9uZyB3aXRoIHRoZSBjdXJyZW50IGNodW5rIG9mZnNldCBhbmQgdGhlIGNodW5rCisgKiBsZW5ndGguCisgKgorICogUmV0dXJucyB0aGUgbmV3IGNodW5rIG9mZnNldCwgb3IgLTEgaWYgdGhlIHNlZWsgaXMgaWxsZWdhbC4KKyAqLworb2ZmX3QgQXNzZXQ6OmhhbmRsZVNlZWsob2ZmX3Qgb2Zmc2V0LCBpbnQgd2hlbmNlLCBvZmZfdCBjdXJQb3NuLCBvZmZfdCBtYXhQb3NuKQoreworICAgIG9mZl90IG5ld09mZnNldDsKKworICAgIHN3aXRjaCAod2hlbmNlKSB7CisgICAgY2FzZSBTRUVLX1NFVDoKKyAgICAgICAgbmV3T2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICBicmVhazsKKyAgICBjYXNlIFNFRUtfQ1VSOgorICAgICAgICBuZXdPZmZzZXQgPSBjdXJQb3NuICsgb2Zmc2V0OworICAgICAgICBicmVhazsKKyAgICBjYXNlIFNFRUtfRU5EOgorICAgICAgICBuZXdPZmZzZXQgPSBtYXhQb3NuICsgb2Zmc2V0OworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBMT0dXKCJ1bmV4cGVjdGVkIHdoZW5jZSAlZFxuIiwgd2hlbmNlKTsKKyAgICAgICAgLy8gdGhpcyB3YXMgaGFwcGVuaW5nIGR1ZSB0byBhbiBvZmZfdCBzaXplIG1pc21hdGNoCisgICAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICAgIHJldHVybiAob2ZmX3QpIC0xOworICAgIH0KKworICAgIGlmIChuZXdPZmZzZXQgPCAwIHx8IG5ld09mZnNldCA+IG1heFBvc24pIHsKKyAgICAgICAgTE9HVygic2VlayBvdXQgb2YgcmFuZ2U6IHdhbnQgJWxkLCBlbmQ9JWxkXG4iLAorICAgICAgICAgICAgKGxvbmcpIG5ld09mZnNldCwgKGxvbmcpIG1heFBvc24pOworICAgICAgICByZXR1cm4gKG9mZl90KSAtMTsKKyAgICB9CisKKyAgICByZXR1cm4gbmV3T2Zmc2V0OworfQorCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgX0ZpbGVBc3NldAorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworLyoKKyAqIENvbnN0cnVjdG9yLgorICovCitfRmlsZUFzc2V0OjpfRmlsZUFzc2V0KHZvaWQpCisgICAgOiBtU3RhcnQoMCksIG1MZW5ndGgoMCksIG1PZmZzZXQoMCksIG1GcChOVUxMKSwgbUZpbGVOYW1lKE5VTEwpLCBtTWFwKE5VTEwpLCBtQnVmKE5VTEwpCit7Cit9CisKKy8qCisgKiBEZXN0cnVjdG9yLiAgUmVsZWFzZSByZXNvdXJjZXMuCisgKi8KK19GaWxlQXNzZXQ6On5fRmlsZUFzc2V0KHZvaWQpCit7CisgICAgY2xvc2UoKTsKK30KKworLyoKKyAqIE9wZXJhdGUgb24gYSBjaHVuayBvZiBhbiB1bmNvbXByZXNzZWQgZmlsZS4KKyAqCisgKiBaZXJvLWxlbmd0aCBjaHVua3MgYXJlIGFsbG93ZWQuCisgKi8KK3N0YXR1c190IF9GaWxlQXNzZXQ6Om9wZW5DaHVuayhjb25zdCBjaGFyKiBmaWxlTmFtZSwgaW50IGZkLCBvZmZfdCBvZmZzZXQsIHNpemVfdCBsZW5ndGgpCit7CisgICAgYXNzZXJ0KG1GcCA9PSBOVUxMKTsgICAgLy8gbm8gcmVvcGVuCisgICAgYXNzZXJ0KG1NYXAgPT0gTlVMTCk7CisgICAgYXNzZXJ0KGZkID49IDApOworICAgIGFzc2VydChvZmZzZXQgPj0gMCk7CisKKyAgICAvKgorICAgICAqIFNlZWsgdG8gZW5kIHRvIGdldCBmaWxlIGxlbmd0aC4KKyAgICAgKi8KKyAgICBvZmZfdCBmaWxlTGVuZ3RoOworICAgIGZpbGVMZW5ndGggPSBsc2VlayhmZCwgMCwgU0VFS19FTkQpOworICAgIGlmIChmaWxlTGVuZ3RoID09IChvZmZfdCkgLTEpIHsKKyAgICAgICAgLy8gcHJvYmFibHkgYSBiYWQgZmlsZSBkZXNjcmlwdG9yCisgICAgICAgIExPR0QoImZhaWxlZCBsc2VlayAoZXJybm89JWQpXG4iLCBlcnJubyk7CisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIGlmICgob2ZmX3QpIChvZmZzZXQgKyBsZW5ndGgpID4gZmlsZUxlbmd0aCkgeworICAgICAgICBMT0dEKCJzdGFydCAoJWxkKSArIGxlbiAoJWxkKSA+IGVuZCAoJWxkKVxuIiwKKyAgICAgICAgICAgIChsb25nKSBvZmZzZXQsIChsb25nKSBsZW5ndGgsIChsb25nKSBmaWxlTGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIEJBRF9JTkRFWDsKKyAgICB9CisKKyAgICAvKiBhZnRlciBmZG9wZW4sIHRoZSBmZCB3aWxsIGJlIGNsb3NlZCBvbiBmY2xvc2UoKSAqLworICAgIG1GcCA9IGZkb3BlbihmZCwgInJiIik7CisgICAgaWYgKG1GcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKworICAgIG1TdGFydCA9IG9mZnNldDsKKyAgICBtTGVuZ3RoID0gbGVuZ3RoOworICAgIGFzc2VydChtT2Zmc2V0ID09IDApOworCisgICAgLyogc2VlayB0aGUgRklMRSogdG8gdGhlIHN0YXJ0IG9mIGNodW5rICovCisgICAgaWYgKGZzZWVrKG1GcCwgbVN0YXJ0LCBTRUVLX1NFVCkgIT0gMCkgeworICAgICAgICBhc3NlcnQoZmFsc2UpOworICAgIH0KKworICAgIG1GaWxlTmFtZSA9IGZpbGVOYW1lICE9IE5VTEwgPyBzdHJkdXAoZmlsZU5hbWUpIDogTlVMTDsKKyAgICAKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBDcmVhdGUgdGhlIGNodW5rIGZyb20gdGhlIG1hcC4KKyAqLworc3RhdHVzX3QgX0ZpbGVBc3NldDo6b3BlbkNodW5rKEZpbGVNYXAqIGRhdGFNYXApCit7CisgICAgYXNzZXJ0KG1GcCA9PSBOVUxMKTsgICAgLy8gbm8gcmVvcGVuCisgICAgYXNzZXJ0KG1NYXAgPT0gTlVMTCk7CisgICAgYXNzZXJ0KGRhdGFNYXAgIT0gTlVMTCk7CisKKyAgICBtTWFwID0gZGF0YU1hcDsKKyAgICBtU3RhcnQgPSAtMTsgICAgICAgICAgICAvLyBub3QgdXNlZAorICAgIG1MZW5ndGggPSBkYXRhTWFwLT5nZXREYXRhTGVuZ3RoKCk7CisgICAgYXNzZXJ0KG1PZmZzZXQgPT0gMCk7CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBSZWFkIGEgY2h1bmsgb2YgZGF0YS4KKyAqLworc3NpemVfdCBfRmlsZUFzc2V0OjpyZWFkKHZvaWQqIGJ1Ziwgc2l6ZV90IGNvdW50KQoreworICAgIHNpemVfdCBtYXhMZW47CisgICAgc2l6ZV90IGFjdHVhbDsKKworICAgIGFzc2VydChtT2Zmc2V0ID49IDAgJiYgbU9mZnNldCA8PSBtTGVuZ3RoKTsKKworICAgIGlmIChnZXRBY2Nlc3NNb2RlKCkgPT0gQUNDRVNTX0JVRkZFUikgeworICAgICAgICAvKgorICAgICAgICAgKiBPbiBmaXJzdCBhY2Nlc3MsIHJlYWQgb3IgbWFwIHRoZSBlbnRpcmUgZmlsZS4gIFRoZSBjYWxsZXIgaGFzCisgICAgICAgICAqIHJlcXVlc3RlZCBidWZmZXIgYWNjZXNzLCBlaXRoZXIgYmVjYXVzZSB0aGV5J3JlIGdvaW5nIHRvIGJlCisgICAgICAgICAqIHVzaW5nIHRoZSBidWZmZXIgb3IgYmVjYXVzZSB3aGF0IHRoZXkncmUgZG9pbmcgaGFzIGFwcHJvcHJpYXRlCisgICAgICAgICAqIHBlcmZvcm1hbmNlIG5lZWRzIGFuZCBhY2Nlc3MgcGF0dGVybnMuCisgICAgICAgICAqLworICAgICAgICBpZiAobUJ1ZiA9PSBOVUxMKQorICAgICAgICAgICAgZ2V0QnVmZmVyKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKiBhZGp1c3QgY291bnQgaWYgd2UncmUgbmVhciBFT0YgKi8KKyAgICBtYXhMZW4gPSBtTGVuZ3RoIC0gbU9mZnNldDsKKyAgICBpZiAoY291bnQgPiBtYXhMZW4pCisgICAgICAgIGNvdW50ID0gbWF4TGVuOworCisgICAgaWYgKCFjb3VudCkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBpZiAobU1hcCAhPSBOVUxMKSB7CisgICAgICAgIC8qIGNvcHkgZnJvbSBtYXBwZWQgYXJlYSAqLworICAgICAgICAvL3ByaW50ZigibWFwIHJlYWRcbiIpOworICAgICAgICBtZW1jcHkoYnVmLCAoY2hhciopbU1hcC0+Z2V0RGF0YVB0cigpICsgbU9mZnNldCwgY291bnQpOworICAgICAgICBhY3R1YWwgPSBjb3VudDsKKyAgICB9IGVsc2UgaWYgKG1CdWYgIT0gTlVMTCkgeworICAgICAgICAvKiBjb3B5IGZyb20gYnVmZmVyICovCisgICAgICAgIC8vcHJpbnRmKCJidWYgcmVhZFxuIik7CisgICAgICAgIG1lbWNweShidWYsIChjaGFyKiltQnVmICsgbU9mZnNldCwgY291bnQpOworICAgICAgICBhY3R1YWwgPSBjb3VudDsKKyAgICB9IGVsc2UgeworICAgICAgICAvKiByZWFkIGZyb20gdGhlIGZpbGUgKi8KKyAgICAgICAgLy9wcmludGYoImZpbGUgcmVhZFxuIik7CisgICAgICAgIGlmIChmdGVsbChtRnApICE9IG1TdGFydCArIG1PZmZzZXQpIHsKKyAgICAgICAgICAgIExPR0UoIkhvc2VkOiAlbGQgIT0gJWxkKyVsZFxuIiwKKyAgICAgICAgICAgICAgICBmdGVsbChtRnApLCAobG9uZykgbVN0YXJ0LCAobG9uZykgbU9mZnNldCk7CisgICAgICAgICAgICBhc3NlcnQoZmFsc2UpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhpcyByZXR1cm5zIDAgb24gZXJyb3Igb3IgZW9mLiAgV2UgbmVlZCB0byB1c2UgZmVycm9yKCkgb3IgZmVvZigpCisgICAgICAgICAqIHRvIHRlbGwgdGhlIGRpZmZlcmVuY2UsIGJ1dCB3ZSBkb24ndCBjdXJyZW50bHkgaGF2ZSB0aG9zZSBvbiB0aGUKKyAgICAgICAgICogZGV2aWNlLiAgSG93ZXZlciwgd2Uga25vdyBob3cgbXVjaCBkYXRhIGlzICpzdXBwb3NlZCogdG8gYmUgaW4gdGhlCisgICAgICAgICAqIGZpbGUsIHNvIGlmIHdlIGRvbid0IHJlYWQgdGhlIGZ1bGwgYW1vdW50IHdlIGtub3cgc29tZXRoaW5nIGlzCisgICAgICAgICAqIGhvc2VkLgorICAgICAgICAgKi8KKyAgICAgICAgYWN0dWFsID0gZnJlYWQoYnVmLCAxLCBjb3VudCwgbUZwKTsKKyAgICAgICAgaWYgKGFjdHVhbCA9PSAwKSAgICAgICAgLy8gc29tZXRoaW5nIGZhaWxlZCAtLSBJL08gZXJyb3I/CisgICAgICAgICAgICByZXR1cm4gLTE7CisKKyAgICAgICAgYXNzZXJ0KGFjdHVhbCA9PSBjb3VudCk7CisgICAgfQorCisgICAgbU9mZnNldCArPSBhY3R1YWw7CisgICAgcmV0dXJuIGFjdHVhbDsKK30KKworLyoKKyAqIFNlZWsgdG8gYSBuZXcgcG9zaXRpb24uCisgKi8KK29mZl90IF9GaWxlQXNzZXQ6OnNlZWsob2ZmX3Qgb2Zmc2V0LCBpbnQgd2hlbmNlKQoreworICAgIG9mZl90IG5ld1Bvc247CisgICAgbG9uZyBhY3R1YWxPZmZzZXQ7CisKKyAgICAvLyBjb21wdXRlIG5ldyBwb3NpdGlvbiB3aXRoaW4gY2h1bmsKKyAgICBuZXdQb3NuID0gaGFuZGxlU2VlayhvZmZzZXQsIHdoZW5jZSwgbU9mZnNldCwgbUxlbmd0aCk7CisgICAgaWYgKG5ld1Bvc24gPT0gKG9mZl90KSAtMSkKKyAgICAgICAgcmV0dXJuIG5ld1Bvc247CisKKyAgICBhY3R1YWxPZmZzZXQgPSAobG9uZykgKG1TdGFydCArIG5ld1Bvc24pOworCisgICAgaWYgKG1GcCAhPSBOVUxMKSB7CisgICAgICAgIGlmIChmc2VlayhtRnAsIChsb25nKSBhY3R1YWxPZmZzZXQsIFNFRUtfU0VUKSAhPSAwKQorICAgICAgICAgICAgcmV0dXJuIChvZmZfdCkgLTE7CisgICAgfQorCisgICAgbU9mZnNldCA9IGFjdHVhbE9mZnNldCAtIG1TdGFydDsKKyAgICByZXR1cm4gbU9mZnNldDsKK30KKworLyoKKyAqIENsb3NlIHRoZSBhc3NldC4KKyAqLwordm9pZCBfRmlsZUFzc2V0OjpjbG9zZSh2b2lkKQoreworICAgIGlmIChtTWFwICE9IE5VTEwpIHsKKyAgICAgICAgbU1hcC0+cmVsZWFzZSgpOworICAgICAgICBtTWFwID0gTlVMTDsKKyAgICB9CisgICAgaWYgKG1CdWYgIT0gTlVMTCkgeworICAgICAgICBkZWxldGVbXSBtQnVmOworICAgICAgICBtQnVmID0gTlVMTDsKKyAgICB9CisKKyAgICBpZiAobUZpbGVOYW1lICE9IE5VTEwpIHsKKyAgICAgICAgZnJlZShtRmlsZU5hbWUpOworICAgICAgICBtRmlsZU5hbWUgPSBOVUxMOworICAgIH0KKyAgICAKKyAgICBpZiAobUZwICE9IE5VTEwpIHsKKyAgICAgICAgLy8gY2FuIG9ubHkgYmUgTlVMTCB3aGVuIGNhbGxlZCBmcm9tIGRlc3RydWN0b3IKKyAgICAgICAgLy8gKG90aGVyd2lzZSB3ZSB3b3VsZCBuZXZlciByZXR1cm4gdGhpcyBvYmplY3QpCisgICAgICAgIGZjbG9zZShtRnApOworICAgICAgICBtRnAgPSBOVUxMOworICAgIH0KK30KKworLyoKKyAqIFJldHVybiBhIHJlYWQtb25seSBwb2ludGVyIHRvIGEgYnVmZmVyLgorICoKKyAqIFdlIGNhbiBlaXRoZXIgcmVhZCB0aGUgd2hvbGUgdGhpbmcgaW4gb3IgbWFwIHRoZSByZWxldmFudCBwaWVjZSBvZgorICogdGhlIHNvdXJjZSBmaWxlLiAgSWRlYWxseSBhIG1hcCB3b3VsZCBiZSBlc3RhYmxpc2hlZCBhdCBhIGhpZ2hlcgorICogbGV2ZWwgYW5kIHdlJ2QgYmUgdXNpbmcgYSBkaWZmZXJlbnQgb2JqZWN0LCBidXQgd2UgZGlkbid0LCBzbyB3ZQorICogZGVhbCB3aXRoIGl0IGhlcmUuCisgKi8KK2NvbnN0IHZvaWQqIF9GaWxlQXNzZXQ6OmdldEJ1ZmZlcihib29sIHdvcmRBbGlnbmVkKQoreworICAgIC8qIHN1YnNlcXVlbnQgcmVxdWVzdHMganVzdCB1c2Ugd2hhdCB3ZSBkaWQgcHJldmlvdXNseSAqLworICAgIGlmIChtQnVmICE9IE5VTEwpCisgICAgICAgIHJldHVybiBtQnVmOworICAgIGlmIChtTWFwICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKCF3b3JkQWxpZ25lZCkgeworICAgICAgICAgICAgcmV0dXJuICBtTWFwLT5nZXREYXRhUHRyKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuc3VyZUFsaWdubWVudChtTWFwKTsKKyAgICB9CisKKyAgICBhc3NlcnQobUZwICE9IE5VTEwpOworCisgICAgaWYgKG1MZW5ndGggPCBrUmVhZFZzTWFwVGhyZXNob2xkKSB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIqIGJ1ZjsKKyAgICAgICAgbG9uZyBhbGxvY0xlbjsKKworICAgICAgICAvKiB6ZXJvLWxlbmd0aCBmaWxlcyBhcmUgYWxsb3dlZDsgbm90IHN1cmUgYWJvdXQgemVyby1sZW4gYWxsb2NzICovCisgICAgICAgIC8qICh3b3JrcyBmaW5lIHdpdGggZ2NjICsgeDg2bGludXgpICovCisgICAgICAgIGFsbG9jTGVuID0gbUxlbmd0aDsKKyAgICAgICAgaWYgKG1MZW5ndGggPT0gMCkKKyAgICAgICAgICAgIGFsbG9jTGVuID0gMTsKKworICAgICAgICBidWYgPSBuZXcgdW5zaWduZWQgY2hhclthbGxvY0xlbl07CisgICAgICAgIGlmIChidWYgPT0gTlVMTCkgeworICAgICAgICAgICAgTE9HRSgiYWxsb2Mgb2YgJWxkIGJ5dGVzIGZhaWxlZFxuIiwgKGxvbmcpIGFsbG9jTGVuKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisKKyAgICAgICAgTE9HVigiQXNzZXQgJXAgYWxsb2NhdGluZyBidWZmZXIgc2l6ZSAlZCAoc21hbGxlciB0aGFuIHRocmVzaG9sZCkiLCB0aGlzLCAoaW50KWFsbG9jTGVuKTsKKyAgICAgICAgaWYgKG1MZW5ndGggPiAwKSB7CisgICAgICAgICAgICBsb25nIG9sZFBvc24gPSBmdGVsbChtRnApOworICAgICAgICAgICAgZnNlZWsobUZwLCBtU3RhcnQsIFNFRUtfU0VUKTsKKyAgICAgICAgICAgIGlmIChmcmVhZChidWYsIDEsIG1MZW5ndGgsIG1GcCkgIT0gKHNpemVfdCkgbUxlbmd0aCkgeworICAgICAgICAgICAgICAgIExPR0UoImZhaWxlZCByZWFkaW5nICVsZCBieXRlc1xuIiwgKGxvbmcpIG1MZW5ndGgpOworICAgICAgICAgICAgICAgIGRlbGV0ZVtdIGJ1ZjsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZzZWVrKG1GcCwgb2xkUG9zbiwgU0VFS19TRVQpOworICAgICAgICB9CisKKyAgICAgICAgTE9HVigiIGdldEJ1ZmZlcjogbG9hZGVkIGludG8gYnVmZmVyXG4iKTsKKworICAgICAgICBtQnVmID0gYnVmOworICAgICAgICByZXR1cm4gbUJ1ZjsKKyAgICB9IGVsc2UgeworICAgICAgICBGaWxlTWFwKiBtYXA7CisKKyAgICAgICAgbWFwID0gbmV3IEZpbGVNYXA7CisgICAgICAgIGlmICghbWFwLT5jcmVhdGUoTlVMTCwgZmlsZW5vKG1GcCksIG1TdGFydCwgbUxlbmd0aCwgdHJ1ZSkpIHsKKyAgICAgICAgICAgIG1hcC0+cmVsZWFzZSgpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBMT0dWKCIgZ2V0QnVmZmVyOiBtYXBwZWRcbiIpOworCisgICAgICAgIG1NYXAgPSBtYXA7CisgICAgICAgIGlmICghd29yZEFsaWduZWQpIHsKKyAgICAgICAgICAgIHJldHVybiAgbU1hcC0+Z2V0RGF0YVB0cigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbnN1cmVBbGlnbm1lbnQobU1hcCk7CisgICAgfQorfQorCitpbnQgX0ZpbGVBc3NldDo6b3BlbkZpbGVEZXNjcmlwdG9yKG9mZl90KiBvdXRTdGFydCwgb2ZmX3QqIG91dExlbmd0aCkgY29uc3QKK3sKKyAgICBpZiAobU1hcCAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IGNoYXIqIGZuYW1lID0gbU1hcC0+Z2V0RmlsZU5hbWUoKTsKKyAgICAgICAgaWYgKGZuYW1lID09IE5VTEwpIHsKKyAgICAgICAgICAgIGZuYW1lID0gbUZpbGVOYW1lOworICAgICAgICB9CisgICAgICAgIGlmIChmbmFtZSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgKm91dFN0YXJ0ID0gbU1hcC0+Z2V0RGF0YU9mZnNldCgpOworICAgICAgICAqb3V0TGVuZ3RoID0gbU1hcC0+Z2V0RGF0YUxlbmd0aCgpOworICAgICAgICByZXR1cm4gb3BlbihmbmFtZSwgT19SRE9OTFkgfCBPX0JJTkFSWSk7CisgICAgfQorICAgIGlmIChtRmlsZU5hbWUgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgICpvdXRTdGFydCA9IG1TdGFydDsKKyAgICAqb3V0TGVuZ3RoID0gbUxlbmd0aDsKKyAgICByZXR1cm4gb3BlbihtRmlsZU5hbWUsIE9fUkRPTkxZIHwgT19CSU5BUlkpOworfQorCitjb25zdCB2b2lkKiBfRmlsZUFzc2V0OjplbnN1cmVBbGlnbm1lbnQoRmlsZU1hcCogbWFwKQoreworICAgIHZvaWQqIGRhdGEgPSBtYXAtPmdldERhdGFQdHIoKTsKKyAgICBpZiAoKCgoc2l6ZV90KWRhdGEpJjB4MykgPT0gMCkgeworICAgICAgICAvLyBXZSBjYW4gcmV0dXJuIHRoaXMgZGlyZWN0bHkgaWYgaXQgaXMgYWxpZ25lZCBvbiBhIHdvcmQKKyAgICAgICAgLy8gYm91bmRhcnkuCisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKyAgICAvLyBJZiBub3QgYWxpZ25lZCBvbiBhIHdvcmQgYm91bmRhcnksIHRoZW4gd2UgbmVlZCB0byBjb3B5IGl0IGludG8KKyAgICAvLyBvdXIgb3duIGJ1ZmZlci4KKyAgICBMT0dWKCJDb3B5aW5nIEZpbGVBc3NldCAlcCB0byBidWZmZXIgc2l6ZSAlZCB0byBtYWtlIGl0IGFsaWduZWQuIiwgdGhpcywgKGludCltTGVuZ3RoKTsKKyAgICB1bnNpZ25lZCBjaGFyKiBidWYgPSBuZXcgdW5zaWduZWQgY2hhclttTGVuZ3RoXTsKKyAgICBpZiAoYnVmID09IE5VTEwpIHsKKyAgICAgICAgTE9HRSgiYWxsb2Mgb2YgJWxkIGJ5dGVzIGZhaWxlZFxuIiwgKGxvbmcpIG1MZW5ndGgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbWVtY3B5KGJ1ZiwgZGF0YSwgbUxlbmd0aCk7CisgICAgbUJ1ZiA9IGJ1ZjsKKyAgICByZXR1cm4gYnVmOworfQorCisvKgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiAgICAgIF9Db21wcmVzc2VkQXNzZXQKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICovCisKKy8qCisgKiBDb25zdHJ1Y3Rvci4KKyAqLworX0NvbXByZXNzZWRBc3NldDo6X0NvbXByZXNzZWRBc3NldCh2b2lkKQorICAgIDogbVN0YXJ0KDApLCBtQ29tcHJlc3NlZExlbigwKSwgbVVuY29tcHJlc3NlZExlbigwKSwgbU9mZnNldCgwKSwKKyAgICAgIG1NYXAoTlVMTCksIG1GZCgtMSksIG1CdWYoTlVMTCkKK3sKK30KKworLyoKKyAqIERlc3RydWN0b3IuICBSZWxlYXNlIHJlc291cmNlcy4KKyAqLworX0NvbXByZXNzZWRBc3NldDo6fl9Db21wcmVzc2VkQXNzZXQodm9pZCkKK3sKKyAgICBjbG9zZSgpOworfQorCisvKgorICogT3BlbiBhIGNodW5rIG9mIGNvbXByZXNzZWQgZGF0YSBpbnNpZGUgYSBmaWxlLgorICoKKyAqIFRoaXMgY3VycmVudGx5IGp1c3Qgc2V0cyB1cCBzb21lIHZhbHVlcyBhbmQgcmV0dXJucy4gIE9uIHRoZSBmaXJzdAorICogcmVhZCwgd2UgZXhwYW5kIHRoZSBlbnRpcmUgZmlsZSBpbnRvIGEgYnVmZmVyIGFuZCByZXR1cm4gZGF0YSBmcm9tIGl0LgorICovCitzdGF0dXNfdCBfQ29tcHJlc3NlZEFzc2V0OjpvcGVuQ2h1bmsoaW50IGZkLCBvZmZfdCBvZmZzZXQsCisgICAgaW50IGNvbXByZXNzaW9uTWV0aG9kLCBzaXplX3QgdW5jb21wcmVzc2VkTGVuLCBzaXplX3QgY29tcHJlc3NlZExlbikKK3sKKyAgICBhc3NlcnQobUZkIDwgMCk7ICAgICAgICAvLyBubyByZS1vcGVuCisgICAgYXNzZXJ0KG1NYXAgPT0gTlVMTCk7CisgICAgYXNzZXJ0KGZkID49IDApOworICAgIGFzc2VydChvZmZzZXQgPj0gMCk7CisgICAgYXNzZXJ0KGNvbXByZXNzZWRMZW4gPiAwKTsKKworICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCAhPSBaaXBGaWxlUk86OmtDb21wcmVzc0RlZmxhdGVkKSB7CisgICAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIG1TdGFydCA9IG9mZnNldDsKKyAgICBtQ29tcHJlc3NlZExlbiA9IGNvbXByZXNzZWRMZW47CisgICAgbVVuY29tcHJlc3NlZExlbiA9IHVuY29tcHJlc3NlZExlbjsKKyAgICBhc3NlcnQobU9mZnNldCA9PSAwKTsKKyAgICBtRmQgPSBmZDsKKyAgICBhc3NlcnQobUJ1ZiA9PSBOVUxMKTsKKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLyoKKyAqIE9wZW4gYSBjaHVuayBvZiBjb21wcmVzc2VkIGRhdGEgaW4gYSBtYXBwZWQgcmVnaW9uLgorICoKKyAqIE5vdGhpbmcgaXMgZXhwYW5kZWQgdW50aWwgdGhlIGZpcnN0IHJlYWQgY2FsbC4KKyAqLworc3RhdHVzX3QgX0NvbXByZXNzZWRBc3NldDo6b3BlbkNodW5rKEZpbGVNYXAqIGRhdGFNYXAsIGludCBjb21wcmVzc2lvbk1ldGhvZCwKKyAgICBzaXplX3QgdW5jb21wcmVzc2VkTGVuKQoreworICAgIGFzc2VydChtRmQgPCAwKTsgICAgICAgIC8vIG5vIHJlLW9wZW4KKyAgICBhc3NlcnQobU1hcCA9PSBOVUxMKTsKKyAgICBhc3NlcnQoZGF0YU1hcCAhPSBOVUxMKTsKKworICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCAhPSBaaXBGaWxlUk86OmtDb21wcmVzc0RlZmxhdGVkKSB7CisgICAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIG1NYXAgPSBkYXRhTWFwOworICAgIG1TdGFydCA9IC0xOyAgICAgICAgLy8gbm90IHVzZWQKKyAgICBtQ29tcHJlc3NlZExlbiA9IGRhdGFNYXAtPmdldERhdGFMZW5ndGgoKTsKKyAgICBtVW5jb21wcmVzc2VkTGVuID0gdW5jb21wcmVzc2VkTGVuOworICAgIGFzc2VydChtT2Zmc2V0ID09IDApOworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvKgorICogUmVhZCBkYXRhIGZyb20gYSBjaHVuayBvZiBjb21wcmVzc2VkIGRhdGEuCisgKgorICogW0ZvciBub3csIHRoYXQncyBqdXN0IGNvcHlpbmcgZGF0YSBvdXQgb2YgYSBidWZmZXIuXQorICovCitzc2l6ZV90IF9Db21wcmVzc2VkQXNzZXQ6OnJlYWQodm9pZCogYnVmLCBzaXplX3QgY291bnQpCit7CisgICAgc2l6ZV90IG1heExlbjsKKyAgICBzaXplX3QgYWN0dWFsOworCisgICAgYXNzZXJ0KG1PZmZzZXQgPj0gMCAmJiBtT2Zmc2V0IDw9IG1VbmNvbXByZXNzZWRMZW4pOworCisgICAgLy8gVE9ETzogaWYgbUFjY2Vzc01vZGUgPT0gQUNDRVNTX1NUUkVBTUlORywgdXNlIHpsaWIgbW9yZSBjbGV2ZXJseQorCisgICAgaWYgKG1CdWYgPT0gTlVMTCkgeworICAgICAgICBpZiAoZ2V0QnVmZmVyKGZhbHNlKSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBhc3NlcnQobUJ1ZiAhPSBOVUxMKTsKKworICAgIC8qIGFkanVzdCBjb3VudCBpZiB3ZSdyZSBuZWFyIEVPRiAqLworICAgIG1heExlbiA9IG1VbmNvbXByZXNzZWRMZW4gLSBtT2Zmc2V0OworICAgIGlmIChjb3VudCA+IG1heExlbikKKyAgICAgICAgY291bnQgPSBtYXhMZW47CisKKyAgICBpZiAoIWNvdW50KQorICAgICAgICByZXR1cm4gMDsKKworICAgIC8qIGNvcHkgZnJvbSBidWZmZXIgKi8KKyAgICAvL3ByaW50ZigiY29tcCBidWYgcmVhZFxuIik7CisgICAgbWVtY3B5KGJ1ZiwgKGNoYXIqKW1CdWYgKyBtT2Zmc2V0LCBjb3VudCk7CisgICAgYWN0dWFsID0gY291bnQ7CisKKyAgICBtT2Zmc2V0ICs9IGFjdHVhbDsKKyAgICByZXR1cm4gYWN0dWFsOworfQorCisvKgorICogSGFuZGxlIGEgc2VlayByZXF1ZXN0LgorICoKKyAqIElmIHdlJ3JlIHdvcmtpbmcgaW4gYSBzdHJlYW1pbmcgbW9kZSwgdGhpcyBpcyBnb2luZyB0byBiZSBmYWlybHkKKyAqIGV4cGVuc2l2ZSwgYmVjYXVzZSBpdCByZXF1aXJlcyBwbG93aW5nIHRocm91Z2ggYSBidW5jaCBvZiBjb21wcmVzc2VkCisgKiBkYXRhLgorICovCitvZmZfdCBfQ29tcHJlc3NlZEFzc2V0OjpzZWVrKG9mZl90IG9mZnNldCwgaW50IHdoZW5jZSkKK3sKKyAgICBvZmZfdCBuZXdQb3NuOworCisgICAgLy8gY29tcHV0ZSBuZXcgcG9zaXRpb24gd2l0aGluIGNodW5rCisgICAgbmV3UG9zbiA9IGhhbmRsZVNlZWsob2Zmc2V0LCB3aGVuY2UsIG1PZmZzZXQsIG1VbmNvbXByZXNzZWRMZW4pOworICAgIGlmIChuZXdQb3NuID09IChvZmZfdCkgLTEpCisgICAgICAgIHJldHVybiBuZXdQb3NuOworCisgICAgbU9mZnNldCA9IG5ld1Bvc247CisgICAgcmV0dXJuIG1PZmZzZXQ7Cit9CisKKy8qCisgKiBDbG9zZSB0aGUgYXNzZXQuCisgKi8KK3ZvaWQgX0NvbXByZXNzZWRBc3NldDo6Y2xvc2Uodm9pZCkKK3sKKyAgICBpZiAobU1hcCAhPSBOVUxMKSB7CisgICAgICAgIG1NYXAtPnJlbGVhc2UoKTsKKyAgICAgICAgbU1hcCA9IE5VTEw7CisgICAgfQorICAgIGlmIChtQnVmICE9IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlW10gbUJ1ZjsKKyAgICAgICAgbUJ1ZiA9IE5VTEw7CisgICAgfQorCisgICAgaWYgKG1GZCA+IDApIHsKKyAgICAgICAgOjpjbG9zZShtRmQpOworICAgICAgICBtRmQgPSAtMTsKKyAgICB9Cit9CisKKy8qCisgKiBHZXQgYSBwb2ludGVyIHRvIGEgcmVhZC1vbmx5IGJ1ZmZlciBvZiBkYXRhLgorICoKKyAqIFRoZSBmaXJzdCB0aW1lIHRoaXMgaXMgY2FsbGVkLCB3ZSBleHBhbmQgdGhlIGNvbXByZXNzZWQgZGF0YSBpbnRvIGEKKyAqIGJ1ZmZlci4KKyAqLworY29uc3Qgdm9pZCogX0NvbXByZXNzZWRBc3NldDo6Z2V0QnVmZmVyKGJvb2wgd29yZEFsaWduZWQpCit7CisgICAgdW5zaWduZWQgY2hhciogYnVmID0gTlVMTDsKKworICAgIGlmIChtQnVmICE9IE5VTEwpCisgICAgICAgIHJldHVybiBtQnVmOworCisgICAgaWYgKG1VbmNvbXByZXNzZWRMZW4gPiBVTkNPTVBSRVNTX0RBVEFfTUFYKSB7CisgICAgICAgIExPR0QoIkRhdGEgZXhjZWVkcyBVTkNPTVBSRVNTX0RBVEFfTUFYICglbGQgdnMgJWQpXG4iLAorICAgICAgICAgICAgKGxvbmcpIG1VbmNvbXByZXNzZWRMZW4sIFVOQ09NUFJFU1NfREFUQV9NQVgpOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBbGxvY2F0ZSBhIGJ1ZmZlciBhbmQgcmVhZCB0aGUgZmlsZSBpbnRvIGl0LgorICAgICAqLworICAgIGJ1ZiA9IG5ldyB1bnNpZ25lZCBjaGFyW21VbmNvbXByZXNzZWRMZW5dOworICAgIGlmIChidWYgPT0gTlVMTCkgeworICAgICAgICBMT0dXKCJhbGxvYyAlbGQgYnl0ZXMgZmFpbGVkXG4iLCAobG9uZykgbVVuY29tcHJlc3NlZExlbik7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICBpZiAobU1hcCAhPSBOVUxMKSB7CisgICAgICAgIGlmICghWmlwRmlsZVJPOjppbmZsYXRlQnVmZmVyKGJ1ZiwgbU1hcC0+Z2V0RGF0YVB0cigpLAorICAgICAgICAgICAgICAgIG1VbmNvbXByZXNzZWRMZW4sIG1Db21wcmVzc2VkTGVuKSkKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9IGVsc2UgeworICAgICAgICBhc3NlcnQobUZkID49IDApOworCisgICAgICAgIC8qCisgICAgICAgICAqIFNlZWsgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjb21wcmVzc2VkIGRhdGEuCisgICAgICAgICAqLworICAgICAgICBpZiAobHNlZWsobUZkLCBtU3RhcnQsIFNFRUtfU0VUKSAhPSBtU3RhcnQpCisgICAgICAgICAgICBnb3RvIGJhaWw7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRXhwYW5kIHRoZSBkYXRhIGludG8gaXQuCisgICAgICAgICAqLworICAgICAgICBpZiAoIVppcFV0aWxzOjppbmZsYXRlVG9CdWZmZXIobUZkLCBidWYsIG1VbmNvbXByZXNzZWRMZW4sCisgICAgICAgICAgICAgICAgbUNvbXByZXNzZWRMZW4pKQorICAgICAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qIHN1Y2Nlc3MhICovCisgICAgbUJ1ZiA9IGJ1ZjsKKyAgICBidWYgPSBOVUxMOworCitiYWlsOgorICAgIGRlbGV0ZVtdIGJ1ZjsKKyAgICByZXR1cm4gbUJ1ZjsKK30KKwpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9Bc3NldERpci5jcHAgYi9saWJzL3V0aWxzL0Fzc2V0RGlyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNWY2NjRlCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9Bc3NldERpci5jcHAKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBQcm92aWRlIGFjY2VzcyB0byBhIHZpcnR1YWwgZGlyZWN0b3J5IGluICJhc3NldCBzcGFjZSIuICBNb3N0IG9mIHRoZQorLy8gaW1wbGVtZW50YXRpb24gaXMgaW4gdGhlIGhlYWRlciBmaWxlIG9yIGluIGZyaWVuZCBmdW5jdGlvbnMgaW4KKy8vIEFzc2V0TWFuYWdlci4KKy8vCisjaW5jbHVkZSA8dXRpbHMvQXNzZXREaXIuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKworLyoKKyAqIEZpbmQgYSBtYXRjaGluZyBlbnRyeSBpbiBhIHZlY3RvciBvZiBGaWxlSW5mby4gIEJlY2F1c2UgaXQncyBzb3J0ZWQsIHdlCisgKiBjYW4gdXNlIGEgYmluYXJ5IHNlYXJjaC4KKyAqCisgKiBBc3N1bWVzIHRoZSB2ZWN0b3IgaXMgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlci4KKyAqLworLypzdGF0aWMqLyBpbnQgQXNzZXREaXI6OkZpbGVJbmZvOjpmaW5kRW50cnkoY29uc3QgU29ydGVkVmVjdG9yPEZpbGVJbmZvPiogcFZlY3RvciwKKyAgICBjb25zdCBTdHJpbmc4JiBmaWxlTmFtZSkKK3sKKyAgICBGaWxlSW5mbyB0bXBJbmZvOworCisgICAgdG1wSW5mby5zZXRGaWxlTmFtZShmaWxlTmFtZSk7CisgICAgcmV0dXJuIHBWZWN0b3ItPmluZGV4T2YodG1wSW5mbyk7CisKKyNpZiAwICAvLyBkb24ndCBuZWVkIHRoaXMgYWZ0ZXIgYWxsICh1c2VzIDEvMiBjb21wYXJlcyBvZiBTb3J0ZWRWZWN0b3IgdGhvdWdoKQorICAgIGludCBsbywgaGksIGN1cjsKKworICAgIGxvID0gMDsKKyAgICBoaSA9IHBWZWN0b3ItPnNpemUoKSAtMTsKKyAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgaW50IGNtcDsKKworICAgICAgICBjdXIgPSAoaGkgKyBsbykgLyAyOworICAgICAgICBjbXAgPSBzdHJjbXAocFZlY3Rvci0+aXRlbUF0KGN1cikuZ2V0RmlsZU5hbWUoKSwgZmlsZU5hbWUpOworICAgICAgICBpZiAoY21wID09IDApIHsKKyAgICAgICAgICAgIC8qIG1hdGNoLCBiYWlsICovCisgICAgICAgICAgICByZXR1cm4gY3VyOworICAgICAgICB9IGVsc2UgaWYgKGNtcCA8IDApIHsKKyAgICAgICAgICAgIC8qIHRvbyBsb3cgKi8KKyAgICAgICAgICAgIGxvID0gY3VyICsgMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qIHRvbyBoaWdoICovCisgICAgICAgICAgICBoaSA9IGN1ciAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiAtMTsKKyNlbmRpZgorfQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL0Fzc2V0TWFuYWdlci5jcHAgYi9saWJzL3V0aWxzL0Fzc2V0TWFuYWdlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ3YjgwMQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvQXNzZXRNYW5hZ2VyLmNwcApAQCAtMCwwICsxLDE2MzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gUHJvdmlkZSBhY2Nlc3MgdG8gcmVhZC1vbmx5IGFzc2V0cy4KKy8vCisKKyNkZWZpbmUgTE9HX1RBRyAiYXNzZXQiCisvLyNkZWZpbmUgTE9HX05ERUJVRyAwCisKKyNpbmNsdWRlIDx1dGlscy9Bc3NldE1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9Bc3NldERpci5oPgorI2luY2x1ZGUgPHV0aWxzL0Fzc2V0Lmg+CisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorI2luY2x1ZGUgPHV0aWxzL1Jlc291cmNlVHlwZXMuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvWmlwRmlsZVJPLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvVGltZXJzLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8ZGlyZW50Lmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxhc3NlcnQuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKy8qCisgKiBOYW1lcyBmb3IgZGVmYXVsdCBhcHAsIGxvY2FsZSwgYW5kIHZlbmRvci4gIFdlIG1pZ2h0IHdhbnQgdG8gY2hhbmdlCisgKiB0aGVzZSB0byBiZSBhbiBhY3R1YWwgbG9jYWxlLCBlLmcuIGFsd2F5cyB1c2UgZW4tVVMgYXMgdGhlIGRlZmF1bHQuCisgKi8KK3N0YXRpYyBjb25zdCBjaGFyKiBrRGVmYXVsdExvY2FsZSA9ICJkZWZhdWx0IjsKK3N0YXRpYyBjb25zdCBjaGFyKiBrRGVmYXVsdFZlbmRvciA9ICJkZWZhdWx0IjsKK3N0YXRpYyBjb25zdCBjaGFyKiBrQXNzZXRzUm9vdCA9ICJhc3NldHMiOworc3RhdGljIGNvbnN0IGNoYXIqIGtBcHBaaXBOYW1lID0gTlVMTDsgLy8iY2xhc3Nlcy5qYXIiOworc3RhdGljIGNvbnN0IGNoYXIqIGtTeXN0ZW1Bc3NldHMgPSAiZnJhbWV3b3JrL2ZyYW1ld29yay1yZXMuYXBrIjsKKworc3RhdGljIGNvbnN0IGNoYXIqIGtFeGNsdWRlRXh0ZW5zaW9uID0gIi5FWENMVURFIjsKKworc3RhdGljIEFzc2V0KiBjb25zdCBrRXhjbHVkZWRBc3NldCA9IChBc3NldCopIDB4ZDAwMDAwMGQ7CisKK3N0YXRpYyB2b2xhdGlsZSBpbnQzMl90IGdDb3VudCA9IDA7CisKKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBBc3NldE1hbmFnZXIKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICovCisKK2ludDMyX3QgQXNzZXRNYW5hZ2VyOjpnZXRHbG9iYWxDb3VudCgpCit7CisgICAgcmV0dXJuIGdDb3VudDsKK30KKworQXNzZXRNYW5hZ2VyOjpBc3NldE1hbmFnZXIoQ2FjaGVNb2RlIGNhY2hlTW9kZSkKKyAgICA6IG1Mb2NhbGUoTlVMTCksIG1WZW5kb3IoTlVMTCksCisgICAgICBtUmVzb3VyY2VzKE5VTEwpLCBtQ29uZmlnKG5ldyBSZXNUYWJsZV9jb25maWcpLAorICAgICAgbUNhY2hlTW9kZShjYWNoZU1vZGUpLCBtQ2FjaGVWYWxpZChmYWxzZSkKK3sKKyAgICBpbnQgY291bnQgPSBhbmRyb2lkX2F0b21pY19pbmMoJmdDb3VudCkrMTsKKyAgICAvL0xPR0koIkNyZWF0aW5nIEFzc2V0TWFuYWdlciAlcCAjJWRcbiIsIHRoaXMsIGNvdW50KTsKKyAgICBtZW1zZXQobUNvbmZpZywgMCwgc2l6ZW9mKFJlc1RhYmxlX2NvbmZpZykpOworfQorCitBc3NldE1hbmFnZXI6On5Bc3NldE1hbmFnZXIodm9pZCkKK3sKKyAgICBpbnQgY291bnQgPSBhbmRyb2lkX2F0b21pY19kZWMoJmdDb3VudCk7CisgICAgLy9MT0dJKCJEZXN0cm95aW5nIEFzc2V0TWFuYWdlciBpbiAlcCAjJWRcbiIsIHRoaXMsIGNvdW50KTsKKworICAgIGRlbGV0ZSBtQ29uZmlnOworICAgIGRlbGV0ZSBtUmVzb3VyY2VzOworCisgICAgLy8gZG9uJ3QgaGF2ZSBhIFN0cmluZyBjbGFzcyB5ZXQsIHNvIG1ha2Ugc3VyZSB3ZSBjbGVhbiB1cAorICAgIGRlbGV0ZVtdIG1Mb2NhbGU7CisgICAgZGVsZXRlW10gbVZlbmRvcjsKK30KKworYm9vbCBBc3NldE1hbmFnZXI6OmFkZEFzc2V0UGF0aChjb25zdCBTdHJpbmc4JiBwYXRoLCB2b2lkKiogY29va2llKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBhc3NldF9wYXRoIGFwOworCisgICAgU3RyaW5nOCByZWFsUGF0aChwYXRoKTsKKyAgICBpZiAoa0FwcFppcE5hbWUpIHsKKyAgICAgICAgcmVhbFBhdGguYXBwZW5kUGF0aChrQXBwWmlwTmFtZSk7CisgICAgfQorICAgIGFwLnR5cGUgPSA6OmdldEZpbGVUeXBlKHJlYWxQYXRoLnN0cmluZygpKTsKKyAgICBpZiAoYXAudHlwZSA9PSBrRmlsZVR5cGVSZWd1bGFyKSB7CisgICAgICAgIGFwLnBhdGggPSByZWFsUGF0aDsKKyAgICB9IGVsc2UgeworICAgICAgICBhcC5wYXRoID0gcGF0aDsKKyAgICAgICAgYXAudHlwZSA9IDo6Z2V0RmlsZVR5cGUocGF0aC5zdHJpbmcoKSk7CisgICAgICAgIGlmIChhcC50eXBlICE9IGtGaWxlVHlwZURpcmVjdG9yeSAmJiBhcC50eXBlICE9IGtGaWxlVHlwZVJlZ3VsYXIpIHsKKyAgICAgICAgICAgIExPR1coIkFzc2V0IHBhdGggJXMgaXMgbmVpdGhlciBhIGRpcmVjdG9yeSBub3IgZmlsZSAodHlwZT0lZCkuIiwKKyAgICAgICAgICAgICAgICAgcGF0aC5zdHJpbmcoKSwgKGludClhcC50eXBlKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFNraXAgaWYgd2UgaGF2ZSBpdCBhbHJlYWR5LgorICAgIGZvciAoc2l6ZV90IGk9MDsgaTxtQXNzZXRQYXRocy5zaXplKCk7IGkrKykgeworICAgICAgICBpZiAobUFzc2V0UGF0aHNbaV0ucGF0aCA9PSBhcC5wYXRoKSB7CisgICAgICAgICAgICBpZiAoY29va2llKSB7CisgICAgICAgICAgICAgICAgKmNvb2tpZSA9ICh2b2lkKikoaSsxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIExPR1YoIkluICVwIEFzc2V0ICVzIHBhdGg6ICVzIiwgdGhpcywKKyAgICAgICAgIGFwLnR5cGUgPT0ga0ZpbGVUeXBlRGlyZWN0b3J5ID8gImRpciIgOiAiemlwIiwgYXAucGF0aC5zdHJpbmcoKSk7CisKKyAgICBtQXNzZXRQYXRocy5hZGQoYXApOworCisgICAgLy8gbmV3IHBhdGhzIGFyZSBhbHdheXMgYWRkZWQgYXQgdGhlIGVuZAorICAgIGlmIChjb29raWUpIHsKKyAgICAgICAgKmNvb2tpZSA9ICh2b2lkKiltQXNzZXRQYXRocy5zaXplKCk7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQXNzZXRNYW5hZ2VyOjphZGREZWZhdWx0QXNzZXRzKCkKK3sKKyAgICBjb25zdCBjaGFyKiByb290ID0gZ2V0ZW52KCJBTkRST0lEX1JPT1QiKTsKKyAgICBMT0dfQUxXQVlTX0ZBVEFMX0lGKHJvb3QgPT0gTlVMTCwgIkFORFJPSURfUk9PVCBub3Qgc2V0Iik7CisKKyAgICBTdHJpbmc4IHBhdGgocm9vdCk7CisgICAgcGF0aC5hcHBlbmRQYXRoKGtTeXN0ZW1Bc3NldHMpOworCisgICAgcmV0dXJuIGFkZEFzc2V0UGF0aChwYXRoLCBOVUxMKTsKK30KKwordm9pZCogQXNzZXRNYW5hZ2VyOjpuZXh0QXNzZXRQYXRoKHZvaWQqIGNvb2tpZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIHNpemVfdCBuZXh0ID0gKChzaXplX3QpY29va2llKSsxOworICAgIHJldHVybiBuZXh0ID4gbUFzc2V0UGF0aHMuc2l6ZSgpID8gTlVMTCA6ICh2b2lkKiluZXh0OworfQorCitTdHJpbmc4IEFzc2V0TWFuYWdlcjo6Z2V0QXNzZXRQYXRoKHZvaWQqIGNvb2tpZSkgY29uc3QKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIGNvbnN0IHNpemVfdCB3aGljaCA9ICgoc2l6ZV90KWNvb2tpZSktMTsKKyAgICBpZiAod2hpY2ggPCBtQXNzZXRQYXRocy5zaXplKCkpIHsKKyAgICAgICAgcmV0dXJuIG1Bc3NldFBhdGhzW3doaWNoXS5wYXRoOworICAgIH0KKyAgICByZXR1cm4gU3RyaW5nOCgpOworfQorCisvKgorICogU2V0IHRoZSBjdXJyZW50IGxvY2FsZS4gIFVzZSBOVUxMIHRvIGluZGljYXRlIG5vIGxvY2FsZS4KKyAqCisgKiBDbG9zZSBhbmQgcmVvcGVuIFppcCBhcmNoaXZlcyBhcyBhcHByb3ByaWF0ZSwgYW5kIHJlc2V0IGNhY2hlZAorICogaW5mb3JtYXRpb24gaW4gdGhlIGxvY2FsZS1zcGVjaWZpYyBzZWN0aW9ucyBvZiB0aGUgdHJlZS4KKyAqLwordm9pZCBBc3NldE1hbmFnZXI6OnNldExvY2FsZShjb25zdCBjaGFyKiBsb2NhbGUpCit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICBzZXRMb2NhbGVMb2NrZWQobG9jYWxlKTsKK30KKwordm9pZCBBc3NldE1hbmFnZXI6OnNldExvY2FsZUxvY2tlZChjb25zdCBjaGFyKiBsb2NhbGUpCit7CisgICAgaWYgKG1Mb2NhbGUgIT0gTlVMTCkgeworICAgICAgICAvKiBwcmV2aW91c2x5IHNldCwgcHVyZ2UgY2FjaGVkIGRhdGEgKi8KKyAgICAgICAgcHVyZ2VGaWxlTmFtZUNhY2hlTG9ja2VkKCk7CisgICAgICAgIC8vbVppcFNldC5wdXJnZUxvY2FsZSgpOworICAgICAgICBkZWxldGVbXSBtTG9jYWxlOworICAgIH0KKyAgICBtTG9jYWxlID0gc3RyZHVwTmV3KGxvY2FsZSk7CisgICAgCisgICAgdXBkYXRlUmVzb3VyY2VQYXJhbXNMb2NrZWQoKTsKK30KKworLyoKKyAqIFNldCB0aGUgY3VycmVudCB2ZW5kb3IuICBVc2UgTlVMTCB0byBpbmRpY2F0ZSBubyB2ZW5kb3IuCisgKgorICogQ2xvc2UgYW5kIHJlb3BlbiBaaXAgYXJjaGl2ZXMgYXMgYXBwcm9wcmlhdGUsIGFuZCByZXNldCBjYWNoZWQKKyAqIGluZm9ybWF0aW9uIGluIHRoZSB2ZW5kb3Itc3BlY2lmaWMgc2VjdGlvbnMgb2YgdGhlIHRyZWUuCisgKi8KK3ZvaWQgQXNzZXRNYW5hZ2VyOjpzZXRWZW5kb3IoY29uc3QgY2hhciogdmVuZG9yKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBpZiAobVZlbmRvciAhPSBOVUxMKSB7CisgICAgICAgIC8qIHByZXZpb3VzbHkgc2V0LCBwdXJnZSBjYWNoZWQgZGF0YSAqLworICAgICAgICBwdXJnZUZpbGVOYW1lQ2FjaGVMb2NrZWQoKTsKKyAgICAgICAgLy9tWmlwU2V0LnB1cmdlVmVuZG9yKCk7CisgICAgICAgIGRlbGV0ZVtdIG1WZW5kb3I7CisgICAgfQorICAgIG1WZW5kb3IgPSBzdHJkdXBOZXcodmVuZG9yKTsKK30KKwordm9pZCBBc3NldE1hbmFnZXI6OnNldENvbmZpZ3VyYXRpb24oY29uc3QgUmVzVGFibGVfY29uZmlnJiBjb25maWcsIGNvbnN0IGNoYXIqIGxvY2FsZSkKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgICptQ29uZmlnID0gY29uZmlnOworICAgIGlmIChsb2NhbGUpIHsKKyAgICAgICAgc2V0TG9jYWxlTG9ja2VkKGxvY2FsZSk7CisgICAgfSBlbHNlIGlmIChjb25maWcubGFuZ3VhZ2VbMF0gIT0gMCkgeworICAgICAgICBjaGFyIHNwZWNbOV07CisgICAgICAgIHNwZWNbMF0gPSBjb25maWcubGFuZ3VhZ2VbMF07CisgICAgICAgIHNwZWNbMV0gPSBjb25maWcubGFuZ3VhZ2VbMV07CisgICAgICAgIGlmIChjb25maWcuY291bnRyeVswXSAhPSAwKSB7CisgICAgICAgICAgICBzcGVjWzJdID0gJ18nOworICAgICAgICAgICAgc3BlY1szXSA9IGNvbmZpZy5jb3VudHJ5WzBdOworICAgICAgICAgICAgc3BlY1s0XSA9IGNvbmZpZy5jb3VudHJ5WzFdOworICAgICAgICAgICAgc3BlY1s1XSA9IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzcGVjWzNdID0gMDsKKyAgICAgICAgfQorICAgICAgICBzZXRMb2NhbGVMb2NrZWQoc3BlYyk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgdXBkYXRlUmVzb3VyY2VQYXJhbXNMb2NrZWQoKTsKKyAgICB9Cit9CisKKy8qCisgKiBPcGVuIGFuIGFzc2V0LgorICoKKyAqIFRoZSBkYXRhIGNvdWxkIGJlOworICogIC0gSW4gYSBmaWxlIG9uIGRpc2sgKGFzc2V0QmFzZSArIGZpbGVOYW1lKS4KKyAqICAtIEluIGEgY29tcHJlc3NlZCBmaWxlIG9uIGRpc2sgKGFzc2V0QmFzZSArIGZpbGVOYW1lLmd6KS4KKyAqICAtIEluIGEgWmlwIGFyY2hpdmUsIHVuY29tcHJlc3NlZCBvciBjb21wcmVzc2VkLgorICoKKyAqIEl0IGNhbiBiZSBpbiBhIG51bWJlciBvZiBkaWZmZXJlbnQgZGlyZWN0b3JpZXMgYW5kIFppcCBhcmNoaXZlcy4KKyAqIFRoZSBzZWFyY2ggb3JkZXIgaXM6CisgKiAgLSBbYXBwbmFtZV0KKyAqICAgIC0gbG9jYWxlICsgdmVuZG9yCisgKiAgICAtICJkZWZhdWx0IiArIHZlbmRvcgorICogICAgLSBsb2NhbGUgKyAiZGVmYXVsdCIKKyAqICAgIC0gImRlZmF1bHQgKyAiZGVmYXVsdCIKKyAqICAtICJjb21tb24iCisgKiAgICAtIChzYW1lIGFzIGFib3ZlKQorICoKKyAqIFRvIGZpbmQgYSBwYXJ0aWN1bGFyIGZpbGUsIHdlIGhhdmUgdG8gdHJ5IHVwIHRvIGVpZ2h0IHBhdGhzIHdpdGgKKyAqIGFsbCB0aHJlZSBmb3JtcyBvZiBkYXRhLgorICoKKyAqIFdlIHNob3VsZCBwcm9iYWJseSByZWplY3QgcmVxdWVzdHMgZm9yICJpbGxlZ2FsIiBmaWxlbmFtZXMsIGUuZy4gdGhvc2UKKyAqIHdpdGggaWxsZWdhbCBjaGFyYWN0ZXJzIG9yICIuLi8iIGJhY2t3YXJkIHJlbGF0aXZlIHBhdGhzLgorICovCitBc3NldCogQXNzZXRNYW5hZ2VyOjpvcGVuKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBBY2Nlc3NNb2RlIG1vZGUpCit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKworICAgIExPR19GQVRBTF9JRihtQXNzZXRQYXRocy5zaXplKCkgPT0gMCwgIk5vIGFzc2V0cyBhZGRlZCB0byBBc3NldE1hbmFnZXIiKTsKKworCisgICAgaWYgKG1DYWNoZU1vZGUgIT0gQ0FDSEVfT0ZGICYmICFtQ2FjaGVWYWxpZCkKKyAgICAgICAgbG9hZEZpbGVOYW1lQ2FjaGVMb2NrZWQoKTsKKworICAgIFN0cmluZzggYXNzZXROYW1lKGtBc3NldHNSb290KTsKKyAgICBhc3NldE5hbWUuYXBwZW5kUGF0aChmaWxlTmFtZSk7CisKKyAgICAvKgorICAgICAqIEZvciBlYWNoIHRvcC1sZXZlbCBhc3NldCBwYXRoLCBzZWFyY2ggZm9yIHRoZSBhc3NldC4KKyAgICAgKi8KKworICAgIHNpemVfdCBpID0gbUFzc2V0UGF0aHMuc2l6ZSgpOworICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICBpLS07CisgICAgICAgIExPR1YoIkxvb2tpbmcgZm9yIGFzc2V0ICclcycgaW4gJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICBhc3NldE5hbWUuc3RyaW5nKCksIG1Bc3NldFBhdGhzLml0ZW1BdChpKS5wYXRoLnN0cmluZygpKTsKKyAgICAgICAgQXNzZXQqIHBBc3NldCA9IG9wZW5Ob25Bc3NldEluUGF0aExvY2tlZChhc3NldE5hbWUuc3RyaW5nKCksIG1vZGUsIG1Bc3NldFBhdGhzLml0ZW1BdChpKSk7CisgICAgICAgIGlmIChwQXNzZXQgIT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIHBBc3NldCAhPSBrRXhjbHVkZWRBc3NldCA/IHBBc3NldCA6IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoKKyAqIE9wZW4gYSBub24tYXNzZXQgZmlsZSBhcyBpZiBpdCB3ZXJlIGFuIGFzc2V0LgorICoKKyAqIFRoZSAiZmlsZU5hbWUiIGlzIHRoZSBwYXJ0aWFsIHBhdGggc3RhcnRpbmcgZnJvbSB0aGUgYXBwbGljYXRpb24KKyAqIG5hbWUuCisgKi8KK0Fzc2V0KiBBc3NldE1hbmFnZXI6Om9wZW5Ob25Bc3NldChjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBMT0dfRkFUQUxfSUYobUFzc2V0UGF0aHMuc2l6ZSgpID09IDAsICJObyBhc3NldHMgYWRkZWQgdG8gQXNzZXRNYW5hZ2VyIik7CisKKworICAgIGlmIChtQ2FjaGVNb2RlICE9IENBQ0hFX09GRiAmJiAhbUNhY2hlVmFsaWQpCisgICAgICAgIGxvYWRGaWxlTmFtZUNhY2hlTG9ja2VkKCk7CisKKyAgICAvKgorICAgICAqIEZvciBlYWNoIHRvcC1sZXZlbCBhc3NldCBwYXRoLCBzZWFyY2ggZm9yIHRoZSBhc3NldC4KKyAgICAgKi8KKworICAgIHNpemVfdCBpID0gbUFzc2V0UGF0aHMuc2l6ZSgpOworICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICBpLS07CisgICAgICAgIExPR1YoIkxvb2tpbmcgZm9yIG5vbi1hc3NldCAnJXMnIGluICclcydcbiIsIGZpbGVOYW1lLCBtQXNzZXRQYXRocy5pdGVtQXQoaSkucGF0aC5zdHJpbmcoKSk7CisgICAgICAgIEFzc2V0KiBwQXNzZXQgPSBvcGVuTm9uQXNzZXRJblBhdGhMb2NrZWQoCisgICAgICAgICAgICBmaWxlTmFtZSwgbW9kZSwgbUFzc2V0UGF0aHMuaXRlbUF0KGkpKTsKKyAgICAgICAgaWYgKHBBc3NldCAhPSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gcEFzc2V0ICE9IGtFeGNsdWRlZEFzc2V0ID8gcEFzc2V0IDogTlVMTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBOVUxMOworfQorCitBc3NldCogQXNzZXRNYW5hZ2VyOjpvcGVuTm9uQXNzZXQodm9pZCogY29va2llLCBjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlKQoreworICAgIGNvbnN0IHNpemVfdCB3aGljaCA9ICgoc2l6ZV90KWNvb2tpZSktMTsKKworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBMT0dfRkFUQUxfSUYobUFzc2V0UGF0aHMuc2l6ZSgpID09IDAsICJObyBhc3NldHMgYWRkZWQgdG8gQXNzZXRNYW5hZ2VyIik7CisKKworICAgIGlmIChtQ2FjaGVNb2RlICE9IENBQ0hFX09GRiAmJiAhbUNhY2hlVmFsaWQpCisgICAgICAgIGxvYWRGaWxlTmFtZUNhY2hlTG9ja2VkKCk7CisKKyAgICBpZiAod2hpY2ggPCBtQXNzZXRQYXRocy5zaXplKCkpIHsKKyAgICAgICAgTE9HVigiTG9va2luZyBmb3Igbm9uLWFzc2V0ICclcycgaW4gJyVzJ1xuIiwgZmlsZU5hbWUsCisgICAgICAgICAgICAgICAgbUFzc2V0UGF0aHMuaXRlbUF0KHdoaWNoKS5wYXRoLnN0cmluZygpKTsKKyAgICAgICAgQXNzZXQqIHBBc3NldCA9IG9wZW5Ob25Bc3NldEluUGF0aExvY2tlZCgKKyAgICAgICAgICAgIGZpbGVOYW1lLCBtb2RlLCBtQXNzZXRQYXRocy5pdGVtQXQod2hpY2gpKTsKKyAgICAgICAgaWYgKHBBc3NldCAhPSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gcEFzc2V0ICE9IGtFeGNsdWRlZEFzc2V0ID8gcEFzc2V0IDogTlVMTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBOVUxMOworfQorCisvKgorICogR2V0IHRoZSB0eXBlIG9mIGEgZmlsZSBpbiB0aGUgYXNzZXQgbmFtZXNwYWNlLgorICoKKyAqIFRoaXMgY3VycmVudGx5IG9ubHkgd29ya3MgZm9yIHJlZ3VsYXIgZmlsZXMuICBBbGwgb3RoZXJzIChpbmNsdWRpbmcKKyAqIGRpcmVjdG9yaWVzKSB3aWxsIHJldHVybiBrRmlsZVR5cGVOb25leGlzdGVudC4KKyAqLworRmlsZVR5cGUgQXNzZXRNYW5hZ2VyOjpnZXRGaWxlVHlwZShjb25zdCBjaGFyKiBmaWxlTmFtZSkKK3sKKyAgICBBc3NldCogcEFzc2V0ID0gTlVMTDsKKworICAgIC8qCisgICAgICogT3BlbiB0aGUgYXNzZXQuICBUaGlzIGlzIGxlc3MgZWZmaWNpZW50IHRoYW4gc2ltcGx5IGZpbmRpbmcgdGhlCisgICAgICogZmlsZSwgYnV0IGl0J3Mgbm90IHRvbyBiYWQgKHdlIGRvbid0IHVuY29tcHJlc3Mgb3IgbW1hcCBkYXRhIHVudGlsCisgICAgICogdGhlIGZpcnN0IHJlYWQoKSBjYWxsKS4KKyAgICAgKi8KKyAgICBwQXNzZXQgPSBvcGVuKGZpbGVOYW1lLCBBc3NldDo6QUNDRVNTX1NUUkVBTUlORyk7CisgICAgZGVsZXRlIHBBc3NldDsKKworICAgIGlmIChwQXNzZXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGtGaWxlVHlwZU5vbmV4aXN0ZW50OworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIGtGaWxlVHlwZVJlZ3VsYXI7Cit9CisKK2NvbnN0IFJlc1RhYmxlKiBBc3NldE1hbmFnZXI6OmdldFJlc1RhYmxlKGJvb2wgcmVxdWlyZWQpIGNvbnN0Cit7CisgICAgUmVzVGFibGUqIHJ0ID0gbVJlc291cmNlczsKKyAgICBpZiAocnQpIHsKKyAgICAgICAgcmV0dXJuIHJ0OworICAgIH0KKworICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgYXNzZXQgcGFja2FnZXMsIGNvbGxlY3RpbmcgcmVzb3VyY2VzIGZyb20gZWFjaC4KKworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBpZiAobVJlc291cmNlcyAhPSBOVUxMKSB7CisgICAgICAgIHJldHVybiBtUmVzb3VyY2VzOworICAgIH0KKworICAgIGlmIChyZXF1aXJlZCkgeworICAgICAgICBMT0dfRkFUQUxfSUYobUFzc2V0UGF0aHMuc2l6ZSgpID09IDAsICJObyBhc3NldHMgYWRkZWQgdG8gQXNzZXRNYW5hZ2VyIik7CisgICAgfQorCisgICAgaWYgKG1DYWNoZU1vZGUgIT0gQ0FDSEVfT0ZGICYmICFtQ2FjaGVWYWxpZCkKKyAgICAgICAgY29uc3RfY2FzdDxBc3NldE1hbmFnZXIqPih0aGlzKS0+bG9hZEZpbGVOYW1lQ2FjaGVMb2NrZWQoKTsKKworICAgIGNvbnN0IHNpemVfdCBOID0gbUFzc2V0UGF0aHMuc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgQXNzZXQqIGFzcyA9IE5VTEw7CisgICAgICAgIGJvb2wgc2hhcmVkID0gdHJ1ZTsKKyAgICAgICAgY29uc3QgYXNzZXRfcGF0aCYgYXAgPSBtQXNzZXRQYXRocy5pdGVtQXQoaSk7CisgICAgICAgIExPR1YoIkxvb2tpbmcgZm9yIHJlc291cmNlIGFzc2V0IGluICclcydcbiIsIGFwLnBhdGguc3RyaW5nKCkpOworICAgICAgICBpZiAoYXAudHlwZSAhPSBrRmlsZVR5cGVEaXJlY3RvcnkpIHsKKyAgICAgICAgICAgIGFzcyA9IGNvbnN0X2Nhc3Q8QXNzZXRNYW5hZ2VyKj4odGhpcyktPgorICAgICAgICAgICAgICAgIG1aaXBTZXQuZ2V0WmlwUmVzb3VyY2VUYWJsZShhcC5wYXRoKTsKKyAgICAgICAgICAgIGlmIChhc3MgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIExPR1YoImxvYWRpbmcgcmVzb3VyY2UgdGFibGUgJXNcbiIsIGFwLnBhdGguc3RyaW5nKCkpOworICAgICAgICAgICAgICAgIGFzcyA9IGNvbnN0X2Nhc3Q8QXNzZXRNYW5hZ2VyKj4odGhpcyktPgorICAgICAgICAgICAgICAgICAgICBvcGVuTm9uQXNzZXRJblBhdGhMb2NrZWQoInJlc291cmNlcy5hcnNjIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2V0OjpBQ0NFU1NfQlVGRkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXApOworICAgICAgICAgICAgICAgIGlmIChhc3MgIT0gTlVMTCAmJiBhc3MgIT0ga0V4Y2x1ZGVkQXNzZXQpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzID0gY29uc3RfY2FzdDxBc3NldE1hbmFnZXIqPih0aGlzKS0+CisgICAgICAgICAgICAgICAgICAgICAgICBtWmlwU2V0LnNldFppcFJlc291cmNlVGFibGUoYXAucGF0aCwgYXNzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dWKCJsb2FkaW5nIHJlc291cmNlIHRhYmxlICVzXG4iLCBhcC5wYXRoLnN0cmluZygpKTsKKyAgICAgICAgICAgIEFzc2V0KiBhc3MgPSBjb25zdF9jYXN0PEFzc2V0TWFuYWdlcio+KHRoaXMpLT4KKyAgICAgICAgICAgICAgICBvcGVuTm9uQXNzZXRJblBhdGhMb2NrZWQoInJlc291cmNlcy5hcnNjIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXQ6OkFDQ0VTU19CVUZGRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwKTsKKyAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChhc3MgIT0gTlVMTCAmJiBhc3MgIT0ga0V4Y2x1ZGVkQXNzZXQpIHsKKyAgICAgICAgICAgIGlmIChydCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgbVJlc291cmNlcyA9IHJ0ID0gbmV3IFJlc1RhYmxlKCk7CisgICAgICAgICAgICAgICAgdXBkYXRlUmVzb3VyY2VQYXJhbXNMb2NrZWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExPR1YoIkluc3RhbGxpbmcgcmVzb3VyY2UgYXNzZXQgJXAgaW4gdG8gdGFibGUgJXBcbiIsIGFzcywgbVJlc291cmNlcyk7CisgICAgICAgICAgICBydC0+YWRkKGFzcywgKHZvaWQqKShpKzEpLCAhc2hhcmVkKTsKKworICAgICAgICAgICAgaWYgKCFzaGFyZWQpIHsKKyAgICAgICAgICAgICAgICBkZWxldGUgYXNzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKHJlcXVpcmVkICYmICFydCkgTE9HVygiVW5hYmxlIHRvIGZpbmQgcmVzb3VyY2VzIGZpbGUgcmVzb3VyY2VzLmFyc2MiKTsKKyAgICBpZiAoIXJ0KSB7CisgICAgICAgIG1SZXNvdXJjZXMgPSBydCA9IG5ldyBSZXNUYWJsZSgpOworICAgIH0KKyAgICByZXR1cm4gcnQ7Cit9CisKK3ZvaWQgQXNzZXRNYW5hZ2VyOjp1cGRhdGVSZXNvdXJjZVBhcmFtc0xvY2tlZCgpIGNvbnN0Cit7CisgICAgUmVzVGFibGUqIHJlcyA9IG1SZXNvdXJjZXM7CisgICAgaWYgKCFyZXMpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHNpemVfdCBsbGVuID0gbUxvY2FsZSA/IHN0cmxlbihtTG9jYWxlKSA6IDA7CisgICAgbUNvbmZpZy0+bGFuZ3VhZ2VbMF0gPSAwOworICAgIG1Db25maWctPmxhbmd1YWdlWzFdID0gMDsKKyAgICBtQ29uZmlnLT5jb3VudHJ5WzBdID0gMDsKKyAgICBtQ29uZmlnLT5jb3VudHJ5WzFdID0gMDsKKyAgICBpZiAobGxlbiA+PSAyKSB7CisgICAgICAgIG1Db25maWctPmxhbmd1YWdlWzBdID0gbUxvY2FsZVswXTsKKyAgICAgICAgbUNvbmZpZy0+bGFuZ3VhZ2VbMV0gPSBtTG9jYWxlWzFdOworICAgIH0KKyAgICBpZiAobGxlbiA+PSA1KSB7CisgICAgICAgIG1Db25maWctPmNvdW50cnlbMF0gPSBtTG9jYWxlWzNdOworICAgICAgICBtQ29uZmlnLT5jb3VudHJ5WzFdID0gbUxvY2FsZVs0XTsKKyAgICB9CisgICAgbUNvbmZpZy0+c2l6ZSA9IHNpemVvZigqbUNvbmZpZyk7CisKKyAgICByZXMtPnNldFBhcmFtZXRlcnMobUNvbmZpZyk7Cit9CisKK2NvbnN0IFJlc1RhYmxlJiBBc3NldE1hbmFnZXI6OmdldFJlc291cmNlcyhib29sIHJlcXVpcmVkKSBjb25zdAoreworICAgIGNvbnN0IFJlc1RhYmxlKiBydCA9IGdldFJlc1RhYmxlKHJlcXVpcmVkKTsKKyAgICByZXR1cm4gKnJ0OworfQorCitib29sIEFzc2V0TWFuYWdlcjo6aXNVcFRvRGF0ZSgpCit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICByZXR1cm4gbVppcFNldC5pc1VwVG9EYXRlKCk7Cit9CisKK3ZvaWQgQXNzZXRNYW5hZ2VyOjpnZXRMb2NhbGVzKFZlY3RvcjxTdHJpbmc4PiogbG9jYWxlcykgY29uc3QKK3sKKyAgICBSZXNUYWJsZSogcmVzID0gbVJlc291cmNlczsKKyAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgcmVzLT5nZXRMb2NhbGVzKGxvY2FsZXMpOworICAgIH0KK30KKworLyoKKyAqIE9wZW4gYSBub24tYXNzZXQgZmlsZSBhcyBpZiBpdCB3ZXJlIGFuIGFzc2V0LCBzZWFyY2hpbmcgZm9yIGl0IGluIHRoZQorICogc3BlY2lmaWVkIGFwcC4KKyAqCisgKiBQYXNzIGluIGEgTlVMTCB2YWx1ZXMgZm9yICJhcHBOYW1lIiBpZiB0aGUgY29tbW9uIGFwcCBkaXJlY3Rvcnkgc2hvdWxkCisgKiBiZSB1c2VkLgorICovCitBc3NldCogQXNzZXRNYW5hZ2VyOjpvcGVuTm9uQXNzZXRJblBhdGhMb2NrZWQoY29uc3QgY2hhciogZmlsZU5hbWUsIEFjY2Vzc01vZGUgbW9kZSwKKyAgICBjb25zdCBhc3NldF9wYXRoJiBhcCkKK3sKKyAgICBBc3NldCogcEFzc2V0ID0gTlVMTDsKKworICAgIC8qIGxvb2sgYXQgdGhlIGZpbGVzeXN0ZW0gb24gZGlzayAqLworICAgIGlmIChhcC50eXBlID09IGtGaWxlVHlwZURpcmVjdG9yeSkgeworICAgICAgICBTdHJpbmc4IHBhdGgoYXAucGF0aCk7CisgICAgICAgIHBhdGguYXBwZW5kUGF0aChmaWxlTmFtZSk7CisKKyAgICAgICAgcEFzc2V0ID0gb3BlbkFzc2V0RnJvbUZpbGVMb2NrZWQocGF0aCwgbW9kZSk7CisKKyAgICAgICAgaWYgKHBBc3NldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAvKiB0cnkgYWdhaW4sIHRoaXMgdGltZSB3aXRoICIuZ3oiICovCisgICAgICAgICAgICBwYXRoLmFwcGVuZCgiLmd6Iik7CisgICAgICAgICAgICBwQXNzZXQgPSBvcGVuQXNzZXRGcm9tRmlsZUxvY2tlZChwYXRoLCBtb2RlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwQXNzZXQgIT0gTlVMTCkgeworICAgICAgICAgICAgLy9wcmludGYoIkZPVU5EIE5BICclcycgb24gZGlza1xuIiwgZmlsZU5hbWUpOworICAgICAgICAgICAgcEFzc2V0LT5zZXRBc3NldFNvdXJjZShwYXRoKTsKKyAgICAgICAgfQorCisgICAgLyogbG9vayBpbnNpZGUgdGhlIHppcCBmaWxlICovCisgICAgfSBlbHNlIHsKKyAgICAgICAgU3RyaW5nOCBwYXRoKGZpbGVOYW1lKTsKKworICAgICAgICAvKiBjaGVjayB0aGUgYXBwcm9wcmlhdGUgWmlwIGZpbGUgKi8KKyAgICAgICAgWmlwRmlsZVJPKiBwWmlwOworICAgICAgICBaaXBFbnRyeVJPIGVudHJ5OworCisgICAgICAgIHBaaXAgPSBnZXRaaXBGaWxlTG9ja2VkKGFwKTsKKyAgICAgICAgaWYgKHBaaXAgIT0gTlVMTCkgeworICAgICAgICAgICAgLy9wcmludGYoIkdPVCB6aXAsIGNoZWNraW5nIE5BICclcydcbiIsIChjb25zdCBjaGFyKikgcGF0aCk7CisgICAgICAgICAgICBlbnRyeSA9IHBaaXAtPmZpbmRFbnRyeUJ5TmFtZShwYXRoLnN0cmluZygpKTsKKyAgICAgICAgICAgIGlmIChlbnRyeSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgLy9wcmludGYoIkZPVU5EIE5BIGluIFppcCBmaWxlIGZvciAlc1xuIiwgYXBwTmFtZSA/IGFwcE5hbWUgOiBrQXBwQ29tbW9uKTsKKyAgICAgICAgICAgICAgICBwQXNzZXQgPSBvcGVuQXNzZXRGcm9tWmlwTG9ja2VkKHBaaXAsIGVudHJ5LCBtb2RlLCBwYXRoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChwQXNzZXQgIT0gTlVMTCkgeworICAgICAgICAgICAgLyogY3JlYXRlIGEgInNvdXJjZSIgbmFtZSwgZm9yIGRlYnVnL2Rpc3BsYXkgKi8KKyAgICAgICAgICAgIHBBc3NldC0+c2V0QXNzZXRTb3VyY2UoCisgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVppcFNvdXJjZU5hbWVMb2NrZWQoWmlwU2V0OjpnZXRQYXRoTmFtZShhcC5wYXRoLnN0cmluZygpKSwgU3RyaW5nOCgiIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KGZpbGVOYW1lKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHBBc3NldDsKK30KKworLyoKKyAqIE9wZW4gYW4gYXNzZXQsIHNlYXJjaGluZyBmb3IgaXQgaW4gdGhlIGRpcmVjdG9yeSBoaWVyYXJjaHkgZm9yIHRoZQorICogc3BlY2lmaWVkIGFwcC4KKyAqCisgKiBQYXNzIGluIGEgTlVMTCB2YWx1ZXMgZm9yICJhcHBOYW1lIiBpZiB0aGUgY29tbW9uIGFwcCBkaXJlY3Rvcnkgc2hvdWxkCisgKiBiZSB1c2VkLgorICovCitBc3NldCogQXNzZXRNYW5hZ2VyOjpvcGVuSW5QYXRoTG9ja2VkKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBBY2Nlc3NNb2RlIG1vZGUsCisgICAgY29uc3QgYXNzZXRfcGF0aCYgYXApCit7CisgICAgQXNzZXQqIHBBc3NldCA9IE5VTEw7CisKKyAgICAvKgorICAgICAqIFRyeSB2YXJpb3VzIGNvbWJpbmF0aW9ucyBvZiBsb2NhbGUgYW5kIHZlbmRvci4KKyAgICAgKi8KKyAgICBpZiAobUxvY2FsZSAhPSBOVUxMICYmIG1WZW5kb3IgIT0gTlVMTCkKKyAgICAgICAgcEFzc2V0ID0gb3BlbkluTG9jYWxlVmVuZG9yTG9ja2VkKGZpbGVOYW1lLCBtb2RlLCBhcCwgbUxvY2FsZSwgbVZlbmRvcik7CisgICAgaWYgKHBBc3NldCA9PSBOVUxMICYmIG1WZW5kb3IgIT0gTlVMTCkKKyAgICAgICAgcEFzc2V0ID0gb3BlbkluTG9jYWxlVmVuZG9yTG9ja2VkKGZpbGVOYW1lLCBtb2RlLCBhcCwgTlVMTCwgbVZlbmRvcik7CisgICAgaWYgKHBBc3NldCA9PSBOVUxMICYmIG1Mb2NhbGUgIT0gTlVMTCkKKyAgICAgICAgcEFzc2V0ID0gb3BlbkluTG9jYWxlVmVuZG9yTG9ja2VkKGZpbGVOYW1lLCBtb2RlLCBhcCwgbUxvY2FsZSwgTlVMTCk7CisgICAgaWYgKHBBc3NldCA9PSBOVUxMKQorICAgICAgICBwQXNzZXQgPSBvcGVuSW5Mb2NhbGVWZW5kb3JMb2NrZWQoZmlsZU5hbWUsIG1vZGUsIGFwLCBOVUxMLCBOVUxMKTsKKworICAgIHJldHVybiBwQXNzZXQ7Cit9CisKKy8qCisgKiBPcGVuIGFuIGFzc2V0LCBzZWFyY2hpbmcgZm9yIGl0IGluIHRoZSBkaXJlY3RvcnkgaGllcmFyY2h5IGZvciB0aGUKKyAqIHNwZWNpZmllZCBsb2NhbGUgYW5kIHZlbmRvci4KKyAqCisgKiBXZSBhbHNvIHNlYXJjaCBpbiAiYXBwLmphciIuCisgKgorICogUGFzcyBpbiBOVUxMIHZhbHVlcyBmb3IgImFwcE5hbWUiLCAibG9jYWxlIiwgYW5kICJ2ZW5kb3IiIGlmIHRoZQorICogZGVmYXVsdHMgc2hvdWxkIGJlIHVzZWQuCisgKi8KK0Fzc2V0KiBBc3NldE1hbmFnZXI6Om9wZW5JbkxvY2FsZVZlbmRvckxvY2tlZChjb25zdCBjaGFyKiBmaWxlTmFtZSwgQWNjZXNzTW9kZSBtb2RlLAorICAgIGNvbnN0IGFzc2V0X3BhdGgmIGFwLCBjb25zdCBjaGFyKiBsb2NhbGUsIGNvbnN0IGNoYXIqIHZlbmRvcikKK3sKKyAgICBBc3NldCogcEFzc2V0ID0gTlVMTDsKKworICAgIGlmIChhcC50eXBlID09IGtGaWxlVHlwZURpcmVjdG9yeSkgeworICAgICAgICBpZiAobUNhY2hlTW9kZSA9PSBDQUNIRV9PRkYpIHsKKyAgICAgICAgICAgIC8qIGxvb2sgYXQgdGhlIGZpbGVzeXN0ZW0gb24gZGlzayAqLworICAgICAgICAgICAgU3RyaW5nOCBwYXRoKGNyZWF0ZVBhdGhOYW1lTG9ja2VkKGFwLCBsb2NhbGUsIHZlbmRvcikpOworICAgICAgICAgICAgcGF0aC5hcHBlbmRQYXRoKGZpbGVOYW1lKTsKKyAgICAKKyAgICAgICAgICAgIFN0cmluZzggZXhjbHVkZU5hbWUocGF0aCk7CisgICAgICAgICAgICBleGNsdWRlTmFtZS5hcHBlbmQoa0V4Y2x1ZGVFeHRlbnNpb24pOworICAgICAgICAgICAgaWYgKDo6Z2V0RmlsZVR5cGUoZXhjbHVkZU5hbWUuc3RyaW5nKCkpICE9IGtGaWxlVHlwZU5vbmV4aXN0ZW50KSB7CisgICAgICAgICAgICAgICAgLyogc2F5IG5vIG1vcmUgKi8KKyAgICAgICAgICAgICAgICAvL3ByaW50ZigiKysrIGV4Y2x1ZGluZyAnJXMnXG4iLCAoY29uc3QgY2hhciopIGV4Y2x1ZGVOYW1lKTsKKyAgICAgICAgICAgICAgICByZXR1cm4ga0V4Y2x1ZGVkQXNzZXQ7CisgICAgICAgICAgICB9CisgICAgCisgICAgICAgICAgICBwQXNzZXQgPSBvcGVuQXNzZXRGcm9tRmlsZUxvY2tlZChwYXRoLCBtb2RlKTsKKyAgICAKKyAgICAgICAgICAgIGlmIChwQXNzZXQgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIC8qIHRyeSBhZ2FpbiwgdGhpcyB0aW1lIHdpdGggIi5neiIgKi8KKyAgICAgICAgICAgICAgICBwYXRoLmFwcGVuZCgiLmd6Iik7CisgICAgICAgICAgICAgICAgcEFzc2V0ID0gb3BlbkFzc2V0RnJvbUZpbGVMb2NrZWQocGF0aCwgbW9kZSk7CisgICAgICAgICAgICB9CisgICAgCisgICAgICAgICAgICBpZiAocEFzc2V0ICE9IE5VTEwpCisgICAgICAgICAgICAgICAgcEFzc2V0LT5zZXRBc3NldFNvdXJjZShwYXRoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qIGZpbmQgaW4gY2FjaGUgKi8KKyAgICAgICAgICAgIFN0cmluZzggcGF0aChjcmVhdGVQYXRoTmFtZUxvY2tlZChhcCwgbG9jYWxlLCB2ZW5kb3IpKTsKKyAgICAgICAgICAgIHBhdGguYXBwZW5kUGF0aChmaWxlTmFtZSk7CisgICAgCisgICAgICAgICAgICBBc3NldERpcjo6RmlsZUluZm8gdG1wSW5mbzsKKyAgICAgICAgICAgIGJvb2wgZm91bmQgPSBmYWxzZTsKKyAgICAKKyAgICAgICAgICAgIFN0cmluZzggZXhjbHVkZU5hbWUocGF0aCk7CisgICAgICAgICAgICBleGNsdWRlTmFtZS5hcHBlbmQoa0V4Y2x1ZGVFeHRlbnNpb24pOworICAgIAorICAgICAgICAgICAgaWYgKG1DYWNoZS5pbmRleE9mKGV4Y2x1ZGVOYW1lKSAhPSBOQU1FX05PVF9GT1VORCkgeworICAgICAgICAgICAgICAgIC8qIGdvIG5vIGZhcnRoZXIgKi8KKyAgICAgICAgICAgICAgICAvL3ByaW50ZigiKysrIEV4Y2x1ZGluZyAnJXMnXG4iLCAoY29uc3QgY2hhciopIGV4Y2x1ZGVOYW1lKTsKKyAgICAgICAgICAgICAgICByZXR1cm4ga0V4Y2x1ZGVkQXNzZXQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBGaWxlIGNvbXByZXNzaW9uIGV4dGVuc2lvbnMgKCIuZ3oiKSBkb24ndCBnZXQgc3RvcmVkIGluIHRoZQorICAgICAgICAgICAgICogbmFtZSBjYWNoZSwgc28gd2UgaGF2ZSB0byB0cnkgYm90aCBoZXJlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAobUNhY2hlLmluZGV4T2YocGF0aCkgIT0gTkFNRV9OT1RfRk9VTkQpIHsKKyAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CisgICAgICAgICAgICAgICAgcEFzc2V0ID0gb3BlbkFzc2V0RnJvbUZpbGVMb2NrZWQocGF0aCwgbW9kZSk7CisgICAgICAgICAgICAgICAgaWYgKHBBc3NldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIHRyeSBhZ2FpbiwgdGhpcyB0aW1lIHdpdGggIi5neiIgKi8KKyAgICAgICAgICAgICAgICAgICAgcGF0aC5hcHBlbmQoIi5neiIpOworICAgICAgICAgICAgICAgICAgICBwQXNzZXQgPSBvcGVuQXNzZXRGcm9tRmlsZUxvY2tlZChwYXRoLCBtb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChwQXNzZXQgIT0gTlVMTCkKKyAgICAgICAgICAgICAgICBwQXNzZXQtPnNldEFzc2V0U291cmNlKHBhdGgpOworCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRG9uJ3QgY29udGludWUgdGhlIHNlYXJjaCBpbnRvIHRoZSBaaXAgZmlsZXMuICBPdXIgY2FjaGVkIGluZm8KKyAgICAgICAgICAgICAqIHNhaWQgaXQgd2FzIGEgZmlsZSBvbiBkaXNrOyB0byBiZSBjb25zaXN0ZW50IHdpdGggb3BlbkRpcigpCisgICAgICAgICAgICAgKiB3ZSB3YW50IHRvIHJldHVybiB0aGUgbG9vc2UgYXNzZXQuICBJZiB0aGUgY2FjaGVkIGZpbGUgZ2V0cworICAgICAgICAgICAgICogcmVtb3ZlZCwgd2UgZmFpbC4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBUaGUgYWx0ZXJuYXRpdmUgaXMgdG8gdXBkYXRlIG91ciBjYWNoZSB3aGVuIGZpbGVzIGdldCBkZWxldGVkLAorICAgICAgICAgICAgICogb3IgbWFrZSBzb21lIHNvcnQgb2YgImJlc3QgZWZmb3J0IiBwcm9taXNlLCBidXQgZm9yIG5vdyBJJ20KKyAgICAgICAgICAgICAqIHRha2luZyB0aGUgaGFyZCBsaW5lLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoZm91bmQpIHsKKyAgICAgICAgICAgICAgICBpZiAocEFzc2V0ID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIExPR0QoIkV4cGVjdGVkIGZpbGUgbm90IGZvdW5kOiAnJXMnXG4iLCBwYXRoLnN0cmluZygpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcEFzc2V0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBFaXRoZXIgaXQgd2Fzbid0IGZvdW5kIG9uIGRpc2sgb3Igb24gdGhlIGNhY2hlZCB2aWV3IG9mIHRoZSBkaXNrLgorICAgICAqIERpZyB0aHJvdWdoIHRoZSBjdXJyZW50bHktb3BlbmVkIHNldCBvZiBaaXAgZmlsZXMuICBJZiBjYWNoaW5nCisgICAgICogaXMgZGlzYWJsZWQsIHRoZSBaaXAgZmlsZSBtYXkgZ2V0IHJlb3BlbmVkLgorICAgICAqLworICAgIGlmIChwQXNzZXQgPT0gTlVMTCAmJiBhcC50eXBlID09IGtGaWxlVHlwZVJlZ3VsYXIpIHsKKyAgICAgICAgU3RyaW5nOCBwYXRoOworCisgICAgICAgIHBhdGguYXBwZW5kUGF0aCgobG9jYWxlICE9IE5VTEwpID8gbG9jYWxlIDoga0RlZmF1bHRMb2NhbGUpOworICAgICAgICBwYXRoLmFwcGVuZFBhdGgoKHZlbmRvciAhPSBOVUxMKSA/IHZlbmRvciA6IGtEZWZhdWx0VmVuZG9yKTsKKyAgICAgICAgcGF0aC5hcHBlbmRQYXRoKGZpbGVOYW1lKTsKKworICAgICAgICAvKiBjaGVjayB0aGUgYXBwcm9wcmlhdGUgWmlwIGZpbGUgKi8KKyAgICAgICAgWmlwRmlsZVJPKiBwWmlwOworICAgICAgICBaaXBFbnRyeVJPIGVudHJ5OworCisgICAgICAgIHBaaXAgPSBnZXRaaXBGaWxlTG9ja2VkKGFwKTsKKyAgICAgICAgaWYgKHBaaXAgIT0gTlVMTCkgeworICAgICAgICAgICAgLy9wcmludGYoIkdPVCB6aXAsIGNoZWNraW5nICclcydcbiIsIChjb25zdCBjaGFyKikgcGF0aCk7CisgICAgICAgICAgICBlbnRyeSA9IHBaaXAtPmZpbmRFbnRyeUJ5TmFtZShwYXRoLnN0cmluZygpKTsKKyAgICAgICAgICAgIGlmIChlbnRyeSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgLy9wcmludGYoIkZPVU5EIGluIFppcCBmaWxlIGZvciAlcy8lcy0lc1xuIiwKKyAgICAgICAgICAgICAgICAvLyAgICBhcHBOYW1lLCBsb2NhbGUsIHZlbmRvcik7CisgICAgICAgICAgICAgICAgcEFzc2V0ID0gb3BlbkFzc2V0RnJvbVppcExvY2tlZChwWmlwLCBlbnRyeSwgbW9kZSwgcGF0aCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAocEFzc2V0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIC8qIGNyZWF0ZSBhICJzb3VyY2UiIG5hbWUsIGZvciBkZWJ1Zy9kaXNwbGF5ICovCisgICAgICAgICAgICBwQXNzZXQtPnNldEFzc2V0U291cmNlKGNyZWF0ZVppcFNvdXJjZU5hbWVMb2NrZWQoWmlwU2V0OjpnZXRQYXRoTmFtZShhcC5wYXRoLnN0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KCIiKSwgU3RyaW5nOChmaWxlTmFtZSkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBwQXNzZXQ7Cit9CisKKy8qCisgKiBDcmVhdGUgYSAic291cmNlIG5hbWUiIGZvciBhIGZpbGUgZnJvbSBhIFppcCBhcmNoaXZlLgorICovCitTdHJpbmc4IEFzc2V0TWFuYWdlcjo6Y3JlYXRlWmlwU291cmNlTmFtZUxvY2tlZChjb25zdCBTdHJpbmc4JiB6aXBGaWxlTmFtZSwKKyAgICBjb25zdCBTdHJpbmc4JiBkaXJOYW1lLCBjb25zdCBTdHJpbmc4JiBmaWxlTmFtZSkKK3sKKyAgICBTdHJpbmc4IHNvdXJjZU5hbWUoInppcDoiKTsKKyAgICBzb3VyY2VOYW1lLmFwcGVuZCh6aXBGaWxlTmFtZSk7CisgICAgc291cmNlTmFtZS5hcHBlbmQoIjoiKTsKKyAgICBpZiAoZGlyTmFtZS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgc291cmNlTmFtZS5hcHBlbmRQYXRoKGRpck5hbWUpOworICAgIH0KKyAgICBzb3VyY2VOYW1lLmFwcGVuZFBhdGgoZmlsZU5hbWUpOworICAgIHJldHVybiBzb3VyY2VOYW1lOworfQorCisvKgorICogQ3JlYXRlIGEgcGF0aCB0byBhIGxvb3NlIGFzc2V0IChhc3NldC1iYXNlL2FwcC9sb2NhbGUvdmVuZG9yKS4KKyAqLworU3RyaW5nOCBBc3NldE1hbmFnZXI6OmNyZWF0ZVBhdGhOYW1lTG9ja2VkKGNvbnN0IGFzc2V0X3BhdGgmIGFwLCBjb25zdCBjaGFyKiBsb2NhbGUsCisgICAgY29uc3QgY2hhciogdmVuZG9yKQoreworICAgIFN0cmluZzggcGF0aChhcC5wYXRoKTsKKyAgICBwYXRoLmFwcGVuZFBhdGgoKGxvY2FsZSAhPSBOVUxMKSA/IGxvY2FsZSA6IGtEZWZhdWx0TG9jYWxlKTsKKyAgICBwYXRoLmFwcGVuZFBhdGgoKHZlbmRvciAhPSBOVUxMKSA/IHZlbmRvciA6IGtEZWZhdWx0VmVuZG9yKTsKKyAgICByZXR1cm4gcGF0aDsKK30KKworLyoKKyAqIENyZWF0ZSBhIHBhdGggdG8gYSBsb29zZSBhc3NldCAoYXNzZXQtYmFzZS9hcHAvcm9vdERpcikuCisgKi8KK1N0cmluZzggQXNzZXRNYW5hZ2VyOjpjcmVhdGVQYXRoTmFtZUxvY2tlZChjb25zdCBhc3NldF9wYXRoJiBhcCwgY29uc3QgY2hhciogcm9vdERpcikKK3sKKyAgICBTdHJpbmc4IHBhdGgoYXAucGF0aCk7CisgICAgaWYgKHJvb3REaXIgIT0gTlVMTCkgcGF0aC5hcHBlbmRQYXRoKHJvb3REaXIpOworICAgIHJldHVybiBwYXRoOworfQorCisvKgorICogUmV0dXJuIGEgcG9pbnRlciB0byBvbmUgb2Ygb3VyIG9wZW4gWmlwIGFyY2hpdmVzLiAgUmV0dXJucyBOVUxMIGlmIG5vCisgKiBtYXRjaGluZyBaaXAgZmlsZSBleGlzdHMuCisgKgorICogUmlnaHQgbm93IHdlIGhhdmUgMiBwb3NzaWJsZSBaaXAgZmlsZXMgKDEgZWFjaCBpbiBhcHAvImNvbW1vbiIpLgorICoKKyAqIElmIGNhY2hpbmcgaXMgc2V0IHRvIENBQ0hFX09GRiwgdG8gZ2V0IHRoZSBleHBlY3RlZCBiZWhhdmlvciB3ZQorICogbmVlZCB0byByZW9wZW4gdGhlIFppcCBmaWxlIG9uIGV2ZXJ5IHJlcXVlc3QuICBUaGF0IHdvdWxkIGJlIHNpbGx5CisgKiBhbmQgZXhwZW5zaXZlLCBzbyBpbnN0ZWFkIHdlIGp1c3QgY2hlY2sgdGhlIGZpbGUgbW9kaWZpY2F0aW9uIGRhdGUuCisgKgorICogUGFzcyBpbiBOVUxMIHZhbHVlcyBmb3IgImFwcE5hbWUiLCAibG9jYWxlIiwgYW5kICJ2ZW5kb3IiIGlmIHRoZQorICogZ2VuZXJpY3Mgc2hvdWxkIGJlIHVzZWQuCisgKi8KK1ppcEZpbGVSTyogQXNzZXRNYW5hZ2VyOjpnZXRaaXBGaWxlTG9ja2VkKGNvbnN0IGFzc2V0X3BhdGgmIGFwKQoreworICAgIExPR1YoImdldFppcEZpbGVMb2NrZWQoKSBpbiAlcFxuIiwgdGhpcyk7CisKKyAgICByZXR1cm4gbVppcFNldC5nZXRaaXAoYXAucGF0aCk7Cit9CisKKy8qCisgKiBUcnkgdG8gb3BlbiBhbiBhc3NldCBmcm9tIGEgZmlsZSBvbiBkaXNrLgorICoKKyAqIElmIHRoZSBmaWxlIGlzIGNvbXByZXNzZWQgd2l0aCBnemlwLCB3ZSBzZWVrIHRvIHRoZSBzdGFydCBvZiB0aGUKKyAqIGRlZmxhdGVkIGRhdGEgYW5kIHBhc3MgdGhhdCBpbiAoanVzdCBsaWtlIHdlIHdvdWxkIGZvciBhIFppcCBhcmNoaXZlKS4KKyAqCisgKiBGb3IgdW5jb21wcmVzc2VkIGRhdGEsIHdlIG1heSBhbHJlYWR5IGhhdmUgYW4gbW1hcCgpZWQgdmVyc2lvbiBzaXR0aW5nCisgKiBhcm91bmQuICBJZiBzbywgd2Ugd2FudCB0byBoYW5kIHRoYXQgdG8gdGhlIEFzc2V0IGluc3RlYWQuCisgKgorICogVGhpcyByZXR1cm5zIE5VTEwgaWYgdGhlIGZpbGUgZG9lc24ndCBleGlzdCwgY291bGRuJ3QgYmUgb3BlbmVkLCBvcgorICogY2xhaW1zIHRvIGJlIGEgIi5neiIgYnV0IGlzbid0LgorICovCitBc3NldCogQXNzZXRNYW5hZ2VyOjpvcGVuQXNzZXRGcm9tRmlsZUxvY2tlZChjb25zdCBTdHJpbmc4JiBwYXRoTmFtZSwKKyAgICBBY2Nlc3NNb2RlIG1vZGUpCit7CisgICAgQXNzZXQqIHBBc3NldCA9IE5VTEw7CisKKyAgICBpZiAoc3RyY2FzZWNtcChwYXRoTmFtZS5nZXRQYXRoRXh0ZW5zaW9uKCkuc3RyaW5nKCksICIuZ3oiKSA9PSAwKSB7CisgICAgICAgIC8vcHJpbnRmKCJUUllJTkcgJyVzJ1xuIiwgKGNvbnN0IGNoYXIqKSBwYXRoTmFtZSk7CisgICAgICAgIHBBc3NldCA9IEFzc2V0OjpjcmVhdGVGcm9tQ29tcHJlc3NlZEZpbGUocGF0aE5hbWUuc3RyaW5nKCksIG1vZGUpOworICAgIH0gZWxzZSB7CisgICAgICAgIC8vcHJpbnRmKCJUUllJTkcgJyVzJ1xuIiwgKGNvbnN0IGNoYXIqKSBwYXRoTmFtZSk7CisgICAgICAgIHBBc3NldCA9IEFzc2V0OjpjcmVhdGVGcm9tRmlsZShwYXRoTmFtZS5zdHJpbmcoKSwgbW9kZSk7CisgICAgfQorCisgICAgcmV0dXJuIHBBc3NldDsKK30KKworLyoKKyAqIEdpdmVuIGFuIGVudHJ5IGluIGEgWmlwIGFyY2hpdmUsIGNyZWF0ZSBhIG5ldyBBc3NldCBvYmplY3QuCisgKgorICogSWYgdGhlIGVudHJ5IGlzIHVuY29tcHJlc3NlZCwgd2UgbWF5IHdhbnQgdG8gY3JlYXRlIG9yIHNoYXJlIGEKKyAqIHNsaWNlIG9mIHNoYXJlZCBtZW1vcnkuCisgKi8KK0Fzc2V0KiBBc3NldE1hbmFnZXI6Om9wZW5Bc3NldEZyb21aaXBMb2NrZWQoY29uc3QgWmlwRmlsZVJPKiBwWmlwRmlsZSwKKyAgICBjb25zdCBaaXBFbnRyeVJPIGVudHJ5LCBBY2Nlc3NNb2RlIG1vZGUsIGNvbnN0IFN0cmluZzgmIGVudHJ5TmFtZSkKK3sKKyAgICBBc3NldCogcEFzc2V0ID0gTlVMTDsKKworICAgIC8vIFRPRE86IGxvb2sgZm9yIHByZXZpb3VzbHktY3JlYXRlZCBzaGFyZWQgbWVtb3J5IHNsaWNlPworICAgIGludCBtZXRob2Q7CisgICAgbG9uZyB1bmNvbXByZXNzZWRMZW47CisKKyAgICAvL3ByaW50ZigiVVNJTkcgWmlwICclcydcbiIsIHBFbnRyeS0+Z2V0RmlsZU5hbWUoKSk7CisKKyAgICAvL3BaaXBGaWxlLT5nZXRFbnRyeUluZm8oZW50cnksICZtZXRob2QsICZ1bmNvbXByZXNzZWRMZW4sICZjb21wcmVzc2VkTGVuLAorICAgIC8vICAgICZvZmZzZXQpOworICAgIGlmICghcFppcEZpbGUtPmdldEVudHJ5SW5mbyhlbnRyeSwgJm1ldGhvZCwgJnVuY29tcHJlc3NlZExlbiwgTlVMTCwgTlVMTCwKKyAgICAgICAgICAgIE5VTEwsIE5VTEwpKQorICAgIHsKKyAgICAgICAgTE9HVygiZ2V0RW50cnlJbmZvIGZhaWxlZFxuIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIEZpbGVNYXAqIGRhdGFNYXAgPSBwWmlwRmlsZS0+Y3JlYXRlRW50cnlGaWxlTWFwKGVudHJ5KTsKKyAgICBpZiAoZGF0YU1hcCA9PSBOVUxMKSB7CisgICAgICAgIExPR1coImNyZWF0ZSBtYXAgZnJvbSBlbnRyeSBmYWlsZWRcbiIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAobWV0aG9kID09IFppcEZpbGVSTzo6a0NvbXByZXNzU3RvcmVkKSB7CisgICAgICAgIHBBc3NldCA9IEFzc2V0OjpjcmVhdGVGcm9tVW5jb21wcmVzc2VkTWFwKGRhdGFNYXAsIG1vZGUpOworICAgICAgICBMT0dWKCJPcGVuZWQgdW5jb21wcmVzc2VkIGVudHJ5ICVzIGluIHppcCAlcyBtb2RlICVkOiAlcCIsIGVudHJ5TmFtZS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICBkYXRhTWFwLT5nZXRGaWxlTmFtZSgpLCBtb2RlLCBwQXNzZXQpOworICAgIH0gZWxzZSB7CisgICAgICAgIHBBc3NldCA9IEFzc2V0OjpjcmVhdGVGcm9tQ29tcHJlc3NlZE1hcChkYXRhTWFwLCBtZXRob2QsCisgICAgICAgICAgICB1bmNvbXByZXNzZWRMZW4sIG1vZGUpOworICAgICAgICBMT0dWKCJPcGVuZWQgY29tcHJlc3NlZCBlbnRyeSAlcyBpbiB6aXAgJXMgbW9kZSAlZDogJXAiLCBlbnRyeU5hbWUuc3RyaW5nKCksCisgICAgICAgICAgICAgICAgZGF0YU1hcC0+Z2V0RmlsZU5hbWUoKSwgbW9kZSwgcEFzc2V0KTsKKyAgICB9CisgICAgaWYgKHBBc3NldCA9PSBOVUxMKSB7CisgICAgICAgIC8qIHVuZXhwZWN0ZWQgKi8KKyAgICAgICAgTE9HVygiY3JlYXRlIGZyb20gc2VnbWVudCBmYWlsZWRcbiIpOworICAgIH0KKworICAgIHJldHVybiBwQXNzZXQ7Cit9CisKKworCisvKgorICogT3BlbiBhIGRpcmVjdG9yeSBpbiB0aGUgYXNzZXQgbmFtZXNwYWNlLgorICoKKyAqIEFuICJhc3NldCBkaXJlY3RvcnkiIGlzIHNpbXBseSB0aGUgY29tYmluYXRpb24gb2YgYWxsIGZpbGVzIGluIGFsbAorICogbG9jYXRpb25zLCB3aXRoICIuZ3oiIHN0cmlwcGVkIGZvciBsb29zZSBmaWxlcy4gIFdpdGggYXBwLCBsb2NhbGUsIGFuZAorICogdmVuZG9yIGRlZmluZWQsIHdlIGhhdmUgOCBkaXJlY3RvcmllcyBhbmQgMiBaaXAgYXJjaGl2ZXMgdG8gc2Nhbi4KKyAqCisgKiBQYXNzIGluICIiIGZvciB0aGUgcm9vdCBkaXIuCisgKi8KK0Fzc2V0RGlyKiBBc3NldE1hbmFnZXI6Om9wZW5EaXIoY29uc3QgY2hhciogZGlyTmFtZSkKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworCisgICAgQXNzZXREaXIqIHBEaXIgPSBOVUxMOworICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbyA9IE5VTEw7CisKKyAgICBMT0dfRkFUQUxfSUYobUFzc2V0UGF0aHMuc2l6ZSgpID09IDAsICJObyBhc3NldHMgYWRkZWQgdG8gQXNzZXRNYW5hZ2VyIik7CisgICAgYXNzZXJ0KGRpck5hbWUgIT0gTlVMTCk7CisKKyAgICAvL3ByaW50ZigiKysrIG9wZW5EaXIoJXMpIGluICclcydcbiIsIGRpck5hbWUsIChjb25zdCBjaGFyKikgbUFzc2V0QmFzZSk7CisKKyAgICBpZiAobUNhY2hlTW9kZSAhPSBDQUNIRV9PRkYgJiYgIW1DYWNoZVZhbGlkKQorICAgICAgICBsb2FkRmlsZU5hbWVDYWNoZUxvY2tlZCgpOworCisgICAgcERpciA9IG5ldyBBc3NldERpcjsKKworICAgIC8qCisgICAgICogU2NhbiB0aGUgdmFyaW91cyBkaXJlY3RvcmllcywgbWVyZ2luZyB3aGF0IHdlIGZpbmQgaW50byBhIHNpbmdsZQorICAgICAqIHZlY3Rvci4gIFdlIHdhbnQgdG8gc2NhbiB0aGVtIGluIHJldmVyc2UgcHJpb3JpdHkgb3JkZXIgc28gdGhhdAorICAgICAqIHRoZSAiLkVYQ0xVREUiIHByb2Nlc3Npbmcgd29ya3MgY29ycmVjdGx5LiAgQWxzbywgaWYgd2UgZGVjaWRlIHdlCisgICAgICogd2FudCB0byByZW1lbWJlciB3aGVyZSB0aGUgZmlsZSBpcyBjb21pbmcgZnJvbSwgd2UnbGwgZ2V0IHRoZSByaWdodAorICAgICAqIHZlcnNpb24uCisgICAgICoKKyAgICAgKiBXZSBzdGFydCB3aXRoIFppcCBhcmNoaXZlcywgdGhlbiBkbyBsb29zZSBmaWxlcy4KKyAgICAgKi8KKyAgICBwTWVyZ2VkSW5mbyA9IG5ldyBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPjsKKworICAgIHNpemVfdCBpID0gbUFzc2V0UGF0aHMuc2l6ZSgpOworICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICBpLS07CisgICAgICAgIGNvbnN0IGFzc2V0X3BhdGgmIGFwID0gbUFzc2V0UGF0aHMuaXRlbUF0KGkpOworICAgICAgICBpZiAoYXAudHlwZSA9PSBrRmlsZVR5cGVSZWd1bGFyKSB7CisgICAgICAgICAgICBMT0dWKCJBZGRpbmcgZGlyZWN0b3J5ICVzIGZyb20gemlwICVzIiwgZGlyTmFtZSwgYXAucGF0aC5zdHJpbmcoKSk7CisgICAgICAgICAgICBzY2FuQW5kTWVyZ2VaaXBMb2NrZWQocE1lcmdlZEluZm8sIGFwLCBrQXNzZXRzUm9vdCwgZGlyTmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dWKCJBZGRpbmcgZGlyZWN0b3J5ICVzIGZyb20gZGlyICVzIiwgZGlyTmFtZSwgYXAucGF0aC5zdHJpbmcoKSk7CisgICAgICAgICAgICBzY2FuQW5kTWVyZ2VEaXJMb2NrZWQocE1lcmdlZEluZm8sIGFwLCBrQXNzZXRzUm9vdCwgZGlyTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyNpZiAwCisgICAgcHJpbnRmKCJGSUxFIExJU1Q6XG4iKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgKHNpemVfdCkgcE1lcmdlZEluZm8tPnNpemUoKTsgaSsrKSB7CisgICAgICAgIHByaW50ZigiICVkOiAoJWQpICclcydcbiIsIGksCisgICAgICAgICAgICBwTWVyZ2VkSW5mby0+aXRlbUF0KGkpLmdldEZpbGVUeXBlKCksCisgICAgICAgICAgICAoY29uc3QgY2hhciopIHBNZXJnZWRJbmZvLT5pdGVtQXQoaSkuZ2V0RmlsZU5hbWUoKSk7CisgICAgfQorI2VuZGlmCisKKyAgICBwRGlyLT5zZXRGaWxlTGlzdChwTWVyZ2VkSW5mbyk7CisgICAgcmV0dXJuIHBEaXI7Cit9CisKKy8qCisgKiBTY2FuIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeSBhbmQgbWVyZ2UgdGhlbSBpbnRvIHRoZQorICogInBNZXJnZWRJbmZvIiB2ZWN0b3IsIHJlbW92aW5nIHByZXZpb3VzIGVudHJpZXMgaWYgd2UgZmluZCAiZXhjbHVkZSIKKyAqIGRpcmVjdGl2ZXMuCisgKgorICogUmV0dXJucyAiZmFsc2UiIGlmIHdlIGZvdW5kIG5vdGhpbmcgdG8gY29udHJpYnV0ZS4KKyAqLworYm9vbCBBc3NldE1hbmFnZXI6OnNjYW5BbmRNZXJnZURpckxvY2tlZChTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcE1lcmdlZEluZm8sCisgICAgY29uc3QgYXNzZXRfcGF0aCYgYXAsIGNvbnN0IGNoYXIqIHJvb3REaXIsIGNvbnN0IGNoYXIqIGRpck5hbWUpCit7CisgICAgU29ydGVkVmVjdG9yPEFzc2V0RGlyOjpGaWxlSW5mbz4qIHBDb250ZW50czsKKyAgICBTdHJpbmc4IHBhdGg7CisKKyAgICBhc3NlcnQocE1lcmdlZEluZm8gIT0gTlVMTCk7CisKKyAgICAvL3ByaW50Zigic2NhbkFuZE1lcmdlRGlyOiAlcyAlcyAlcyAlc1xuIiwgYXBwTmFtZSwgbG9jYWxlLCB2ZW5kb3IsZGlyTmFtZSk7CisKKyAgICBpZiAobUNhY2hlVmFsaWQpIHsKKyAgICAgICAgaW50IGksIHN0YXJ0LCBjb3VudDsKKworICAgICAgICBwQ29udGVudHMgPSBuZXcgU29ydGVkVmVjdG9yPEFzc2V0RGlyOjpGaWxlSW5mbz47CisKKyAgICAgICAgLyoKKyAgICAgICAgICogR2V0IHRoZSBiYXNpYyBwYXJ0aWFsIHBhdGggYW5kIGZpbmQgaXQgaW4gdGhlIGNhY2hlLiAgVGhhdCdzCisgICAgICAgICAqIHRoZSBzdGFydCBwb2ludCBmb3IgdGhlIHNlYXJjaC4KKyAgICAgICAgICovCisgICAgICAgIHBhdGggPSBjcmVhdGVQYXRoTmFtZUxvY2tlZChhcCwgcm9vdERpcik7CisgICAgICAgIGlmIChkaXJOYW1lWzBdICE9ICdcMCcpCisgICAgICAgICAgICBwYXRoLmFwcGVuZFBhdGgoZGlyTmFtZSk7CisKKyAgICAgICAgc3RhcnQgPSBtQ2FjaGUuaW5kZXhPZihwYXRoKTsKKyAgICAgICAgaWYgKHN0YXJ0ID09IE5BTUVfTk9UX0ZPVU5EKSB7CisgICAgICAgICAgICAvL3ByaW50ZigiKysrIG5vdCBmb3VuZCBpbiBjYWNoZTogZGlyICclcydcbiIsIChjb25zdCBjaGFyKikgcGF0aCk7CisgICAgICAgICAgICBkZWxldGUgcENvbnRlbnRzOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIG1hdGNoIHN0cmluZyBsb29rcyBsaWtlICJjb21tb24vZGVmYXVsdC9kZWZhdWx0L2Zvby9iYXIvIi4KKyAgICAgICAgICogVGhlICcvJyBvbiB0aGUgZW5kIGVuc3VyZXMgdGhhdCB3ZSBkb24ndCBtYXRjaCBvbiB0aGUgZGlyZWN0b3J5CisgICAgICAgICAqIGl0c2VsZiBvciBvbiAiLi4uL2Zvby9iYXJmeS8iLgorICAgICAgICAgKi8KKyAgICAgICAgcGF0aC5hcHBlbmQoIi8iKTsKKworICAgICAgICBjb3VudCA9IG1DYWNoZS5zaXplKCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUGljayBvdXQgdGhlIHN0dWZmIGluIHRoZSBjdXJyZW50IGRpciBieSBleGFtaW5pbmcgdGhlIHBhdGhuYW1lLgorICAgICAgICAgKiBJdCBuZWVkcyB0byBtYXRjaCB0aGUgcGFydGlhbCBwYXRobmFtZSBwcmVmaXgsIGFuZCBub3QgaGF2ZSBhICcvJworICAgICAgICAgKiAoZnNzZXApIGFueXdoZXJlIGFmdGVyIHRoZSBwcmVmaXguCisgICAgICAgICAqLworICAgICAgICBmb3IgKGkgPSBzdGFydCsxOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgaWYgKG1DYWNoZVtpXS5nZXRGaWxlTmFtZSgpLmxlbmd0aCgpID4gcGF0aC5sZW5ndGgoKSAmJgorICAgICAgICAgICAgICAgIHN0cm5jbXAobUNhY2hlW2ldLmdldEZpbGVOYW1lKCkuc3RyaW5nKCksIHBhdGguc3RyaW5nKCksIHBhdGgubGVuZ3RoKCkpID09IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbmFtZSA9IG1DYWNoZVtpXS5nZXRGaWxlTmFtZSgpLnN0cmluZygpOworICAgICAgICAgICAgICAgIC8vIFhYWCBUSElTIElTIEJST0tFTiEgIExvb2tzIGxpa2Ugd2UgbmVlZCB0byBzdG9yZSB0aGUgZnVsbAorICAgICAgICAgICAgICAgIC8vIHBhdGggcHJlZml4IHNlcGFyYXRlbHkgZnJvbSB0aGUgZmlsZSBwYXRoLgorICAgICAgICAgICAgICAgIGlmIChzdHJjaHIobmFtZSArIHBhdGgubGVuZ3RoKCksICcvJykgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICAvKiBncmFiIGl0LCByZWR1Y2luZyBwYXRoIHRvIGp1c3QgdGhlIGZpbGVuYW1lIGNvbXBvbmVudCAqLworICAgICAgICAgICAgICAgICAgICBBc3NldERpcjo6RmlsZUluZm8gdG1wID0gbUNhY2hlW2ldOworICAgICAgICAgICAgICAgICAgICB0bXAuc2V0RmlsZU5hbWUodG1wLmdldEZpbGVOYW1lKCkuZ2V0UGF0aExlYWYoKSk7CisgICAgICAgICAgICAgICAgICAgIHBDb250ZW50cy0+YWRkKHRtcCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiBubyBsb25nZXIgaW4gdGhlIGRpciBvciBpdHMgc3ViZGlycyAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBwYXRoID0gY3JlYXRlUGF0aE5hbWVMb2NrZWQoYXAsIHJvb3REaXIpOworICAgICAgICBpZiAoZGlyTmFtZVswXSAhPSAnXDAnKQorICAgICAgICAgICAgcGF0aC5hcHBlbmRQYXRoKGRpck5hbWUpOworICAgICAgICBwQ29udGVudHMgPSBzY2FuRGlyTG9ja2VkKHBhdGgpOworICAgICAgICBpZiAocENvbnRlbnRzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gaWYgd2Ugd2FudGVkIHRvIGRvIGFuIGluY3JlbWVudGFsIGNhY2hlIGZpbGwsIHdlIHdvdWxkIGRvIGl0IGhlcmUKKworICAgIC8qCisgICAgICogUHJvY2VzcyAiZXhjbHVkZSIgZGlyZWN0aXZlcy4gIElmIHdlIGZpbmQgYSBmaWxlbmFtZSB0aGF0IGVuZHMgd2l0aAorICAgICAqICIuRVhDTFVERSIsIHdlIGxvb2sgZm9yIGEgbWF0Y2hpbmcgZW50cnkgaW4gdGhlICJtZXJnZWQiIHNldCwgYW5kCisgICAgICogcmVtb3ZlIGl0IGlmIHdlIGZpbmQgaXQuICBXZSBhbHNvIGRlbGV0ZSB0aGUgImV4Y2x1ZGUiIGVudHJ5LgorICAgICAqLworICAgIGludCBpLCBjb3VudCwgZXhjbEV4dExlbjsKKworICAgIGNvdW50ID0gcENvbnRlbnRzLT5zaXplKCk7CisgICAgZXhjbEV4dExlbiA9IHN0cmxlbihrRXhjbHVkZUV4dGVuc2lvbik7CisgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgY29uc3QgY2hhciogbmFtZTsKKyAgICAgICAgaW50IG5hbWVMZW47CisKKyAgICAgICAgbmFtZSA9IHBDb250ZW50cy0+aXRlbUF0KGkpLmdldEZpbGVOYW1lKCkuc3RyaW5nKCk7CisgICAgICAgIG5hbWVMZW4gPSBzdHJsZW4obmFtZSk7CisgICAgICAgIGlmIChuYW1lTGVuID4gZXhjbEV4dExlbiAmJgorICAgICAgICAgICAgc3RyY21wKG5hbWUgKyAobmFtZUxlbiAtIGV4Y2xFeHRMZW4pLCBrRXhjbHVkZUV4dGVuc2lvbikgPT0gMCkKKyAgICAgICAgeworICAgICAgICAgICAgU3RyaW5nOCBtYXRjaChuYW1lLCBuYW1lTGVuIC0gZXhjbEV4dExlbik7CisgICAgICAgICAgICBpbnQgbWF0Y2hJZHg7CisKKyAgICAgICAgICAgIG1hdGNoSWR4ID0gQXNzZXREaXI6OkZpbGVJbmZvOjpmaW5kRW50cnkocE1lcmdlZEluZm8sIG1hdGNoKTsKKyAgICAgICAgICAgIGlmIChtYXRjaElkeCA+IDApIHsKKyAgICAgICAgICAgICAgICBMT0dWKCJFeGNsdWRpbmcgJyVzJyBbJXNdXG4iLAorICAgICAgICAgICAgICAgICAgICBwTWVyZ2VkSW5mby0+aXRlbUF0KG1hdGNoSWR4KS5nZXRGaWxlTmFtZSgpLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICBwTWVyZ2VkSW5mby0+aXRlbUF0KG1hdGNoSWR4KS5nZXRTb3VyY2VOYW1lKCkuc3RyaW5nKCkpOworICAgICAgICAgICAgICAgIHBNZXJnZWRJbmZvLT5yZW1vdmVBdChtYXRjaElkeCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vcHJpbnRmKCIrKysgbm8gbWF0Y2ggb24gJyVzJ1xuIiwgKGNvbnN0IGNoYXIqKSBtYXRjaCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIExPR0QoIkhFWTogc2l6ZT0lZCByZW1vdmluZyAlZFxuIiwgKGludClwQ29udGVudHMtPnNpemUoKSwgaSk7CisgICAgICAgICAgICBwQ29udGVudHMtPnJlbW92ZUF0KGkpOworICAgICAgICAgICAgaS0tOyAgICAgICAgLy8gYWRqdXN0ICJmb3IiIGxvb3AKKyAgICAgICAgICAgIGNvdW50LS07ICAgIC8vICBhbmQgbG9vcCBsaW1pdAorICAgICAgICB9CisgICAgfQorCisgICAgbWVyZ2VJbmZvTG9ja2VkKHBNZXJnZWRJbmZvLCBwQ29udGVudHMpOworCisgICAgZGVsZXRlIHBDb250ZW50czsKKworICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogU2NhbiB0aGUgY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBkaXJlY3RvcnksIGFuZCBzdHVmZiB3aGF0IHdlIGZpbmQKKyAqIGludG8gYSBuZXdseS1hbGxvY2F0ZWQgdmVjdG9yLgorICoKKyAqIEZpbGVzIGVuZGluZyBpbiAiLmd6IiB3aWxsIGhhdmUgdGhlaXIgZXh0ZW5zaW9ucyByZW1vdmVkLgorICoKKyAqIFdlIHNob3VsZCBwcm9iYWJseSB0aGluayBhYm91dCBza2lwcGluZyBmaWxlcyB3aXRoICJpbGxlZ2FsIiBuYW1lcywKKyAqIGUuZy4gaWxsZWdhbCBjaGFyYWN0ZXJzICgvXDopIG9yIGV4Y2Vzc2l2ZSBsZW5ndGguCisgKgorICogUmV0dXJucyBOVUxMIGlmIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGRvZXNuJ3QgZXhpc3QuCisgKi8KK1NvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBBc3NldE1hbmFnZXI6OnNjYW5EaXJMb2NrZWQoY29uc3QgU3RyaW5nOCYgcGF0aCkKK3sKKyAgICBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcENvbnRlbnRzID0gTlVMTDsKKyAgICBESVIqIGRpcjsKKyAgICBzdHJ1Y3QgZGlyZW50KiBlbnRyeTsKKyAgICBGaWxlVHlwZSBmaWxlVHlwZTsKKworICAgIExPR1YoIlNjYW5uaW5nIGRpciAnJXMnXG4iLCBwYXRoLnN0cmluZygpKTsKKworICAgIGRpciA9IG9wZW5kaXIocGF0aC5zdHJpbmcoKSk7CisgICAgaWYgKGRpciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHBDb250ZW50cyA9IG5ldyBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPjsKKworICAgIHdoaWxlICgxKSB7CisgICAgICAgIGVudHJ5ID0gcmVhZGRpcihkaXIpOworICAgICAgICBpZiAoZW50cnkgPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGlmIChzdHJjbXAoZW50cnktPmRfbmFtZSwgIi4iKSA9PSAwIHx8CisgICAgICAgICAgICBzdHJjbXAoZW50cnktPmRfbmFtZSwgIi4uIikgPT0gMCkKKyAgICAgICAgICAgIGNvbnRpbnVlOworCisjaWZkZWYgX0RJUkVOVF9IQVZFX0RfVFlQRQorICAgICAgICBpZiAoZW50cnktPmRfdHlwZSA9PSBEVF9SRUcpCisgICAgICAgICAgICBmaWxlVHlwZSA9IGtGaWxlVHlwZVJlZ3VsYXI7CisgICAgICAgIGVsc2UgaWYgKGVudHJ5LT5kX3R5cGUgPT0gRFRfRElSKQorICAgICAgICAgICAgZmlsZVR5cGUgPSBrRmlsZVR5cGVEaXJlY3Rvcnk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGZpbGVUeXBlID0ga0ZpbGVUeXBlVW5rbm93bjsKKyNlbHNlCisgICAgICAgIC8vIHN0YXQgdGhlIGZpbGUKKyAgICAgICAgZmlsZVR5cGUgPSA6OmdldEZpbGVUeXBlKHBhdGguYXBwZW5kUGF0aENvcHkoZW50cnktPmRfbmFtZSkuc3RyaW5nKCkpOworI2VuZGlmCisKKyAgICAgICAgaWYgKGZpbGVUeXBlICE9IGtGaWxlVHlwZVJlZ3VsYXIgJiYgZmlsZVR5cGUgIT0ga0ZpbGVUeXBlRGlyZWN0b3J5KQorICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgQXNzZXREaXI6OkZpbGVJbmZvIGluZm87CisgICAgICAgIGluZm8uc2V0KFN0cmluZzgoZW50cnktPmRfbmFtZSksIGZpbGVUeXBlKTsKKyAgICAgICAgaWYgKHN0cmNhc2VjbXAoaW5mby5nZXRGaWxlTmFtZSgpLmdldFBhdGhFeHRlbnNpb24oKS5zdHJpbmcoKSwgIi5neiIpID09IDApCisgICAgICAgICAgICBpbmZvLnNldEZpbGVOYW1lKGluZm8uZ2V0RmlsZU5hbWUoKS5nZXRCYXNlUGF0aCgpKTsKKyAgICAgICAgaW5mby5zZXRTb3VyY2VOYW1lKHBhdGguYXBwZW5kUGF0aENvcHkoaW5mby5nZXRGaWxlTmFtZSgpKSk7CisgICAgICAgIHBDb250ZW50cy0+YWRkKGluZm8pOworICAgIH0KKworICAgIGNsb3NlZGlyKGRpcik7CisgICAgcmV0dXJuIHBDb250ZW50czsKK30KKworLyoKKyAqIFNjYW4gdGhlIGNvbnRlbnRzIG91dCBvZiB0aGUgc3BlY2lmaWVkIFppcCBhcmNoaXZlLCBhbmQgbWVyZ2Ugd2hhdCB3ZQorICogZmluZCBpbnRvICJwTWVyZ2VkSW5mbyIuICBJZiB0aGUgWmlwIGFyY2hpdmUgaW4gcXVlc3Rpb24gZG9lc24ndCBleGlzdCwKKyAqIHdlIHJldHVybiBpbW1lZGlhdGVseS4KKyAqCisgKiBSZXR1cm5zICJmYWxzZSIgaWYgd2UgZm91bmQgbm90aGluZyB0byBjb250cmlidXRlLgorICovCitib29sIEFzc2V0TWFuYWdlcjo6c2NhbkFuZE1lcmdlWmlwTG9ja2VkKFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbywKKyAgICBjb25zdCBhc3NldF9wYXRoJiBhcCwgY29uc3QgY2hhciogcm9vdERpciwgY29uc3QgY2hhciogYmFzZURpck5hbWUpCit7CisgICAgWmlwRmlsZVJPKiBwWmlwOworICAgIFZlY3RvcjxTdHJpbmc4PiBkaXJzOworICAgIEFzc2V0RGlyOjpGaWxlSW5mbyBpbmZvOworICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+IGNvbnRlbnRzOworICAgIFN0cmluZzggc291cmNlTmFtZSwgemlwTmFtZSwgZGlyTmFtZTsKKworICAgIHBaaXAgPSBtWmlwU2V0LmdldFppcChhcC5wYXRoKTsKKyAgICBpZiAocFppcCA9PSBOVUxMKSB7CisgICAgICAgIExPR1coIkZhaWx1cmUgb3BlbmluZyB6aXAgJXNcbiIsIGFwLnBhdGguc3RyaW5nKCkpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgemlwTmFtZSA9IFppcFNldDo6Z2V0UGF0aE5hbWUoYXAucGF0aC5zdHJpbmcoKSk7CisKKyAgICAvKiBjb252ZXJ0ICJzb3VuZHMiIHRvICJyb290RGlyL3NvdW5kcyIgKi8KKyAgICBpZiAocm9vdERpciAhPSBOVUxMKSBkaXJOYW1lID0gcm9vdERpcjsKKyAgICBkaXJOYW1lLmFwcGVuZFBhdGgoYmFzZURpck5hbWUpOworCisgICAgLyoKKyAgICAgKiBTY2FuIHRocm91Z2ggdGhlIGxpc3Qgb2YgZmlsZXMsIGxvb2tpbmcgZm9yIGEgbWF0Y2guICBUaGUgZmlsZXMgaW4KKyAgICAgKiB0aGUgWmlwIHRhYmxlIG9mIGNvbnRlbnRzIGFyZSBub3QgaW4gc29ydGVkIG9yZGVyLCBzbyB3ZSBoYXZlIHRvCisgICAgICogcHJvY2VzcyB0aGUgZW50aXJlIGxpc3QuICBXZSdyZSBsb29raW5nIGZvciBhIHN0cmluZyB0aGF0IGJlZ2lucworICAgICAqIHdpdGggdGhlIGNoYXJhY3RlcnMgaW4gImRpck5hbWUiLCBpcyBmb2xsb3dlZCBieSBhICcvJywgYW5kIGhhcyBubworICAgICAqIHN1YnNlcXVlbnQgJy8nIGluIHRoZSBzdHVmZiB0aGF0IGZvbGxvd3MuCisgICAgICoKKyAgICAgKiBXaGF0IG1ha2VzIHRoaXMgZXNwZWNpYWxseSBmdW4gaXMgdGhhdCBkaXJlY3RvcmllcyBhcmUgbm90IHN0b3JlZAorICAgICAqIGV4cGxpY2l0bHkgaW4gWmlwIGFyY2hpdmVzLCBzbyB3ZSBoYXZlIHRvIGluZmVyIHRoZW0gZnJvbSBjb250ZXh0LgorICAgICAqIFdoZW4gd2Ugc2VlICJzb3VuZHMvZm9vLndhdiIgd2UgaGF2ZSB0byBsZWF2ZSBhIG5vdGUgdG8gb3Vyc2VsdmVzCisgICAgICogdG8gaW5zZXJ0IGEgZGlyZWN0b3J5IGNhbGxlZCAic291bmRzIiBpbnRvIHRoZSBsaXN0LiAgV2Ugc3RvcmUKKyAgICAgKiB0aGVzZSBpbiB0ZW1wb3JhcnkgdmVjdG9yIHNvIHRoYXQgd2Ugb25seSByZXR1cm4gZWFjaCBvbmUgb25jZS4KKyAgICAgKgorICAgICAqIE5hbWUgY29tcGFyaXNvbnMgYXJlIGNhc2Utc2Vuc2l0aXZlIHRvIG1hdGNoIFVOSVggZmlsZXN5c3RlbQorICAgICAqIHNlbWFudGljcy4KKyAgICAgKi8KKyAgICBpbnQgZGlyTmFtZUxlbiA9IGRpck5hbWUubGVuZ3RoKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwWmlwLT5nZXROdW1FbnRyaWVzKCk7IGkrKykgeworICAgICAgICBaaXBFbnRyeVJPIGVudHJ5OworICAgICAgICBjaGFyIG5hbWVCdWZbMjU2XTsKKworICAgICAgICBlbnRyeSA9IHBaaXAtPmZpbmRFbnRyeUJ5SW5kZXgoaSk7CisgICAgICAgIGlmIChwWmlwLT5nZXRFbnRyeUZpbGVOYW1lKGVudHJ5LCBuYW1lQnVmLCBzaXplb2YobmFtZUJ1ZikpICE9IDApIHsKKyAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0aGlzIGlmIHdlIGV4cGVjdCB0byBoYXZlIGxvbmcgbmFtZXMKKyAgICAgICAgICAgIExPR0UoIkFSR0g6IG5hbWUgdG9vIGxvbmc/XG4iKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGlmIChkaXJOYW1lTGVuID09IDAgfHwKKyAgICAgICAgICAgIChzdHJuY21wKG5hbWVCdWYsIGRpck5hbWUuc3RyaW5nKCksIGRpck5hbWVMZW4pID09IDAgJiYKKyAgICAgICAgICAgICBuYW1lQnVmW2Rpck5hbWVMZW5dID09ICcvJykpCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNwOworICAgICAgICAgICAgY29uc3QgY2hhciogbmV4dFNsYXNoOworCisgICAgICAgICAgICBjcCA9IG5hbWVCdWYgKyBkaXJOYW1lTGVuOworICAgICAgICAgICAgaWYgKGRpck5hbWVMZW4gIT0gMCkKKyAgICAgICAgICAgICAgICBjcCsrOyAgICAgICAvLyBhZHZhbmNlIHBhc3QgdGhlICcvJworCisgICAgICAgICAgICBuZXh0U2xhc2ggPSBzdHJjaHIoY3AsICcvJyk7CisvL3h4eCB0aGlzIG1heSBicmVhayBpZiB0aGVyZSBhcmUgYmFyZSBkaXJlY3RvcnkgZW50cmllcworICAgICAgICAgICAgaWYgKG5leHRTbGFzaCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgLyogdGhpcyBpcyBhIGZpbGUgaW4gdGhlIHJlcXVlc3RlZCBkaXJlY3RvcnkgKi8KKworICAgICAgICAgICAgICAgIGluZm8uc2V0KFN0cmluZzgobmFtZUJ1ZikuZ2V0UGF0aExlYWYoKSwga0ZpbGVUeXBlUmVndWxhcik7CisKKyAgICAgICAgICAgICAgICBpbmZvLnNldFNvdXJjZU5hbWUoCisgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVppcFNvdXJjZU5hbWVMb2NrZWQoemlwTmFtZSwgZGlyTmFtZSwgaW5mby5nZXRGaWxlTmFtZSgpKSk7CisKKyAgICAgICAgICAgICAgICBjb250ZW50cy5hZGQoaW5mbyk7CisgICAgICAgICAgICAgICAgLy9wcmludGYoIkZPVU5EOiBmaWxlICclcydcbiIsIChjb25zdCBjaGFyKikgaW5mby5tRmlsZU5hbWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiB0aGlzIGlzIGEgc3ViZGlyOyBhZGQgaXQgaWYgd2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGl0Ki8KKyAgICAgICAgICAgICAgICBTdHJpbmc4IHN1YmRpck5hbWUoY3AsIG5leHRTbGFzaCAtIGNwKTsKKyAgICAgICAgICAgICAgICBzaXplX3QgajsKKyAgICAgICAgICAgICAgICBzaXplX3QgTiA9IGRpcnMuc2l6ZSgpOworCisgICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IE47IGorKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoc3ViZGlyTmFtZSA9PSBkaXJzW2pdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaiA9PSBOKSB7CisgICAgICAgICAgICAgICAgICAgIGRpcnMuYWRkKHN1YmRpck5hbWUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vcHJpbnRmKCJGT1VORDogZGlyICclcydcbiIsIChjb25zdCBjaGFyKikgc3ViZGlyTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEFkZCB0aGUgc2V0IG9mIHVuaXF1ZSBkaXJlY3Rvcmllcy4KKyAgICAgKi8KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IChpbnQpIGRpcnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgaW5mby5zZXQoZGlyc1tpXSwga0ZpbGVUeXBlRGlyZWN0b3J5KTsKKyAgICAgICAgaW5mby5zZXRTb3VyY2VOYW1lKAorICAgICAgICAgICAgY3JlYXRlWmlwU291cmNlTmFtZUxvY2tlZCh6aXBOYW1lLCBkaXJOYW1lLCBpbmZvLmdldEZpbGVOYW1lKCkpKTsKKyAgICAgICAgY29udGVudHMuYWRkKGluZm8pOworICAgIH0KKworICAgIG1lcmdlSW5mb0xvY2tlZChwTWVyZ2VkSW5mbywgJmNvbnRlbnRzKTsKKworICAgIHJldHVybiB0cnVlOworfQorCisKKy8qCisgKiBNZXJnZSB0d28gdmVjdG9ycyBvZiBGaWxlSW5mby4KKyAqCisgKiBUaGUgbWVyZ2VkIGNvbnRlbnRzIHdpbGwgYmUgc3R1ZmZlZCBpbnRvICpwTWVyZ2VkSW5mby4KKyAqCisgKiBJZiBhbiBlbnRyeSBmb3IgYSBmaWxlIGV4aXN0cyBpbiBib3RoICJwTWVyZ2VkSW5mbyIgYW5kICJwQ29udGVudHMiLAorICogd2UgdXNlIHRoZSBuZXdlciAicENvbnRlbnRzIiBlbnRyeS4KKyAqLwordm9pZCBBc3NldE1hbmFnZXI6Om1lcmdlSW5mb0xvY2tlZChTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcE1lcmdlZEluZm8sCisgICAgY29uc3QgU29ydGVkVmVjdG9yPEFzc2V0RGlyOjpGaWxlSW5mbz4qIHBDb250ZW50cykKK3sKKyAgICAvKgorICAgICAqIE1lcmdlIHdoYXQgd2UgZm91bmQgaW4gdGhpcyBkaXJlY3Rvcnkgd2l0aCB3aGF0IHdlIGZvdW5kIGluCisgICAgICogb3RoZXIgcGxhY2VzLgorICAgICAqCisgICAgICogVHdvIGJhc2ljIGFwcHJvYWNoZXM6CisgICAgICogKDEpIENyZWF0ZSBhIG5ldyBhcnJheSB0aGF0IGhvbGRzIHRoZSB1bmlxdWUgdmFsdWVzIG9mIHRoZSB0d28KKyAgICAgKiAgICAgYXJyYXlzLgorICAgICAqICgyKSBUYWtlIHRoZSBlbGVtZW50cyBmcm9tIHBDb250ZW50cyBhbmQgc2hvdmUgdGhlbSBpbnRvIHBNZXJnZWRJbmZvLgorICAgICAqCisgICAgICogQmVjYXVzZSB0aGVzZSBhcmUgdmVjdG9ycyBvZiBjb21wbGV4IG9iamVjdHMsIG1vdmluZyBlbGVtZW50cyBhcm91bmQKKyAgICAgKiBpbnNpZGUgdGhlIHZlY3RvciByZXF1aXJlcyBjb25zdHJ1Y3RpbmcgbmV3IG9iamVjdHMgYW5kIGFsbG9jYXRpbmcKKyAgICAgKiBzdG9yYWdlIGZvciBtZW1iZXJzLiAgV2l0aCBhcHByb2FjaCAjMSwgd2UncmUgYWx3YXlzIGFkZGluZyB0byB0aGUKKyAgICAgKiBlbmQsIHdoZXJlYXMgd2l0aCAjMiB3ZSBjb3VsZCBiZSBpbnNlcnRpbmcgbXVsdGlwbGUgZWxlbWVudHMgYXQgdGhlCisgICAgICogZnJvbnQgb2YgdGhlIHZlY3Rvci4gIEFwcHJvYWNoICMxIHJlcXVpcmVzIGEgZnVsbCBjb3B5IG9mIHRoZQorICAgICAqIGNvbnRlbnRzIG9mIHBNZXJnZWRJbmZvLCBidXQgYXBwcm9hY2ggIzIgcmVxdWlyZXMgdGhlIHNhbWUgY29weSBmb3IKKyAgICAgKiBldmVyeSBpbnNlcnRpb24gYXQgdGhlIGZyb250IG9mIHBNZXJnZWRJbmZvLgorICAgICAqCisgICAgICogKFdlIHNob3VsZCBwcm9iYWJseSB1c2UgYSBTb3J0ZWRWZWN0b3IgaW50ZXJmYWNlIHRoYXQgYWxsb3dzIHVzIHRvCisgICAgICoganVzdCBzdHVmZiBpdGVtcyBpbiwgdHJ1c3RpbmcgdXMgdG8gbWFpbnRhaW4gdGhlIHNvcnQgb3JkZXIuKQorICAgICAqLworICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTmV3U29ydGVkOworICAgIGludCBtZXJnZU1heCwgY29udE1heDsKKyAgICBpbnQgbWVyZ2VJZHgsIGNvbnRJZHg7CisKKyAgICBwTmV3U29ydGVkID0gbmV3IFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+OworICAgIG1lcmdlTWF4ID0gcE1lcmdlZEluZm8tPnNpemUoKTsKKyAgICBjb250TWF4ID0gcENvbnRlbnRzLT5zaXplKCk7CisgICAgbWVyZ2VJZHggPSBjb250SWR4ID0gMDsKKworICAgIHdoaWxlIChtZXJnZUlkeCA8IG1lcmdlTWF4IHx8IGNvbnRJZHggPCBjb250TWF4KSB7CisgICAgICAgIGlmIChtZXJnZUlkeCA9PSBtZXJnZU1heCkgeworICAgICAgICAgICAgLyogaGl0IGVuZCBvZiAibWVyZ2UiIGxpc3QsIGNvcHkgcmVzdCBvZiAiY29udGVudHMiICovCisgICAgICAgICAgICBwTmV3U29ydGVkLT5hZGQocENvbnRlbnRzLT5pdGVtQXQoY29udElkeCkpOworICAgICAgICAgICAgY29udElkeCsrOworICAgICAgICB9IGVsc2UgaWYgKGNvbnRJZHggPT0gY29udE1heCkgeworICAgICAgICAgICAgLyogaGl0IGVuZCBvZiAiY29udCIgbGlzdCwgY29weSByZXN0IG9mICJtZXJnZSIgKi8KKyAgICAgICAgICAgIHBOZXdTb3J0ZWQtPmFkZChwTWVyZ2VkSW5mby0+aXRlbUF0KG1lcmdlSWR4KSk7CisgICAgICAgICAgICBtZXJnZUlkeCsrOworICAgICAgICB9IGVsc2UgaWYgKHBNZXJnZWRJbmZvLT5pdGVtQXQobWVyZ2VJZHgpID09IHBDb250ZW50cy0+aXRlbUF0KGNvbnRJZHgpKQorICAgICAgICB7CisgICAgICAgICAgICAvKiBpdGVtcyBhcmUgaWRlbnRpY2FsLCBhZGQgbmV3ZXIgYW5kIGFkdmFuY2UgYm90aCBpbmRpY2VzICovCisgICAgICAgICAgICBwTmV3U29ydGVkLT5hZGQocENvbnRlbnRzLT5pdGVtQXQoY29udElkeCkpOworICAgICAgICAgICAgbWVyZ2VJZHgrKzsKKyAgICAgICAgICAgIGNvbnRJZHgrKzsKKyAgICAgICAgfSBlbHNlIGlmIChwTWVyZ2VkSW5mby0+aXRlbUF0KG1lcmdlSWR4KSA8IHBDb250ZW50cy0+aXRlbUF0KGNvbnRJZHgpKQorICAgICAgICB7CisgICAgICAgICAgICAvKiAibWVyZ2UiIGlzIGxvd2VyLCBhZGQgdGhhdCBvbmUgKi8KKyAgICAgICAgICAgIHBOZXdTb3J0ZWQtPmFkZChwTWVyZ2VkSW5mby0+aXRlbUF0KG1lcmdlSWR4KSk7CisgICAgICAgICAgICBtZXJnZUlkeCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLyogImNvbnQiIGlzIGxvd2VyLCBhZGQgdGhhdCBvbmUgKi8KKyAgICAgICAgICAgIGFzc2VydChwQ29udGVudHMtPml0ZW1BdChjb250SWR4KSA8IHBNZXJnZWRJbmZvLT5pdGVtQXQobWVyZ2VJZHgpKTsKKyAgICAgICAgICAgIHBOZXdTb3J0ZWQtPmFkZChwQ29udGVudHMtPml0ZW1BdChjb250SWR4KSk7CisgICAgICAgICAgICBjb250SWR4Kys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIE92ZXJ3cml0ZSB0aGUgIm1lcmdlZCIgbGlzdCB3aXRoIHRoZSBuZXcgc3R1ZmYuCisgICAgICovCisgICAgKnBNZXJnZWRJbmZvID0gKnBOZXdTb3J0ZWQ7CisgICAgZGVsZXRlIHBOZXdTb3J0ZWQ7CisKKyNpZiAwICAgICAgIC8vIGZvciBWZWN0b3IsIHJhdGhlciB0aGFuIFNvcnRlZFZlY3RvcgorICAgIGludCBpLCBqOworICAgIGZvciAoaSA9IHBDb250ZW50cy0+c2l6ZSgpIC0xOyBpID49IDA7IGktLSkgeworICAgICAgICBib29sIGFkZCA9IHRydWU7CisKKyAgICAgICAgZm9yIChqID0gcE1lcmdlZEluZm8tPnNpemUoKSAtMTsgaiA+PSAwOyBqLS0pIHsKKyAgICAgICAgICAgIC8qIGNhc2Utc2Vuc2l0aXZlIGNvbXBhcmlzb25zLCB0byBiZWhhdmUgbGlrZSBVTklYIGZzICovCisgICAgICAgICAgICBpZiAoc3RyY21wKHBDb250ZW50cy0+aXRlbUF0KGkpLm1GaWxlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgcE1lcmdlZEluZm8tPml0ZW1BdChqKS5tRmlsZU5hbWUpID09IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgLyogbWF0Y2gsIGRvbid0IGFkZCB0aGlzIGVudHJ5ICovCisgICAgICAgICAgICAgICAgYWRkID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoYWRkKQorICAgICAgICAgICAgcE1lcmdlZEluZm8tPmFkZChwQ29udGVudHMtPml0ZW1BdChpKSk7CisgICAgfQorI2VuZGlmCit9CisKKworLyoKKyAqIExvYWQgYWxsIGZpbGVzIGludG8gdGhlIGZpbGUgbmFtZSBjYWNoZS4gIFdlIHdhbnQgdG8gZG8gdGhpcyBhY3Jvc3MKKyAqIGFsbCBjb21iaW5hdGlvbnMgb2YgeyBhcHBuYW1lLCBsb2NhbGUsIHZlbmRvciB9LCBwZXJmb3JtaW5nIGEgcmVjdXJzaXZlCisgKiBkaXJlY3RvcnkgdHJhdmVyc2FsLgorICoKKyAqIFRoaXMgaXMgbm90IHRoZSBtb3N0IGVmZmljaWVudCBkYXRhIHN0cnVjdHVyZS4gIEFsc28sIGdhdGhlcmluZyB0aGUKKyAqIGluZm9ybWF0aW9uIGFzIHdlIG5lZWRlZCBpdCAoZmlsZS1ieS1maWxlIG9yIGRpcmVjdG9yeS1ieS1kaXJlY3RvcnkpCisgKiB3b3VsZCBiZSBmYXN0ZXIuICBIb3dldmVyLCBvbiB0aGUgYWN0dWFsIGRldmljZSwgOTklIG9mIHRoZSBmaWxlcyB3aWxsCisgKiBsaXZlIGluIFppcCBhcmNoaXZlcywgc28gdGhpcyBsaXN0IHdpbGwgYmUgdmVyeSBzbWFsbC4gIFRoZSB0cm91YmxlCisgKiBpcyB0aGF0IHdlIGhhdmUgdG8gY2hlY2sgdGhlICJsb29zZSIgZmlsZXMgZmlyc3QsIHNvIGl0J3MgaW1wb3J0YW50CisgKiB0aGF0IHdlIGRvbid0IGJlYXQgdGhlIGZpbGVzeXN0ZW0gc2lsbHkgbG9va2luZyBmb3IgZmlsZXMgdGhhdCBhcmVuJ3QKKyAqIHRoZXJlLgorICoKKyAqIE5vdGUgb24gdGhyZWFkIHNhZmV0eTogdGhpcyBpcyB0aGUgb25seSBmdW5jdGlvbiB0aGF0IGNhdXNlcyB1cGRhdGVzCisgKiB0byBtQ2FjaGUsIGFuZCBhbnlib2R5IHdobyB0cmllcyB0byB1c2UgaXQgd2lsbCBjYWxsIGhlcmUgaWYgIW1DYWNoZVZhbGlkLAorICogc28gd2UgbmVlZCB0byBlbXBsb3kgYSBtdXRleCBoZXJlLgorICovCit2b2lkIEFzc2V0TWFuYWdlcjo6bG9hZEZpbGVOYW1lQ2FjaGVMb2NrZWQodm9pZCkKK3sKKyAgICBhc3NlcnQoIW1DYWNoZVZhbGlkKTsKKyAgICBhc3NlcnQobUNhY2hlLnNpemUoKSA9PSAwKTsKKworI2lmZGVmIERPX1RJTUlOR1MgICAvLyBuZWVkIHRvIGxpbmsgYWdhaW5zdCAtbHJ0IGZvciB0aGlzIG5vdworICAgIER1cmF0aW9uVGltZXIgdGltZXI7CisgICAgdGltZXIuc3RhcnQoKTsKKyNlbmRpZgorCisgICAgZm5jU2NhbkxvY2tlZCgmbUNhY2hlLCAiIik7CisKKyNpZmRlZiBET19USU1JTkdTCisgICAgdGltZXIuc3RvcCgpOworICAgIExPR0QoIkNhY2hlIHNjYW4gdG9vayAlLjNmbXNcbiIsCisgICAgICAgIHRpbWVyLmR1cmF0aW9uVXNlY3MoKSAvIDEwMDAuMCk7CisjZW5kaWYKKworI2lmIDAKKyAgICBpbnQgaTsKKyAgICBwcmludGYoIkNBQ0hFRCBGSUxFIExJU1QgKCVkIGVudHJpZXMpOlxuIiwgbUNhY2hlLnNpemUoKSk7CisgICAgZm9yIChpID0gMDsgaSA8IChpbnQpIG1DYWNoZS5zaXplKCk7IGkrKykgeworICAgICAgICBwcmludGYoIiAlZDogKCVkKSAnJXMnXG4iLCBpLAorICAgICAgICAgICAgbUNhY2hlLml0ZW1BdChpKS5nZXRGaWxlVHlwZSgpLAorICAgICAgICAgICAgKGNvbnN0IGNoYXIqKSBtQ2FjaGUuaXRlbUF0KGkpLmdldEZpbGVOYW1lKCkpOworICAgIH0KKyNlbmRpZgorCisgICAgbUNhY2hlVmFsaWQgPSB0cnVlOworfQorCisvKgorICogU2NhbiB1cCB0byA4IHZlcnNpb25zIG9mIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5LgorICovCit2b2lkIEFzc2V0TWFuYWdlcjo6Zm5jU2NhbkxvY2tlZChTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcE1lcmdlZEluZm8sCisgICAgY29uc3QgY2hhciogZGlyTmFtZSkKK3sKKyAgICBzaXplX3QgaSA9IG1Bc3NldFBhdGhzLnNpemUoKTsKKyAgICB3aGlsZSAoaSA+IDApIHsKKyAgICAgICAgaS0tOworICAgICAgICBjb25zdCBhc3NldF9wYXRoJiBhcCA9IG1Bc3NldFBhdGhzLml0ZW1BdChpKTsKKyAgICAgICAgZm5jU2NhbkFuZE1lcmdlRGlyTG9ja2VkKHBNZXJnZWRJbmZvLCBhcCwgTlVMTCwgTlVMTCwgZGlyTmFtZSk7CisgICAgICAgIGlmIChtTG9jYWxlICE9IE5VTEwpCisgICAgICAgICAgICBmbmNTY2FuQW5kTWVyZ2VEaXJMb2NrZWQocE1lcmdlZEluZm8sIGFwLCBtTG9jYWxlLCBOVUxMLCBkaXJOYW1lKTsKKyAgICAgICAgaWYgKG1WZW5kb3IgIT0gTlVMTCkKKyAgICAgICAgICAgIGZuY1NjYW5BbmRNZXJnZURpckxvY2tlZChwTWVyZ2VkSW5mbywgYXAsIE5VTEwsIG1WZW5kb3IsIGRpck5hbWUpOworICAgICAgICBpZiAobUxvY2FsZSAhPSBOVUxMICYmIG1WZW5kb3IgIT0gTlVMTCkKKyAgICAgICAgICAgIGZuY1NjYW5BbmRNZXJnZURpckxvY2tlZChwTWVyZ2VkSW5mbywgYXAsIG1Mb2NhbGUsIG1WZW5kb3IsIGRpck5hbWUpOworICAgIH0KK30KKworLyoKKyAqIFJlY3Vyc2l2ZWx5IHNjYW4gdGhpcyBkaXJlY3RvcnkgYW5kIGFsbCBzdWJkaXJzLgorICoKKyAqIFRoaXMgaXMgc2ltaWxhciB0byBzY2FuQW5kTWVyZ2VEaXIsIGJ1dCB3ZSBkb24ndCByZW1vdmUgdGhlIC5FWENMVURFCisgKiBmaWxlcywgYW5kIHdlIHByZXBlbmQgdGhlIGV4dGVuZGVkIHBhcnRpYWwgcGF0aCB0byB0aGUgZmlsZW5hbWVzLgorICovCitib29sIEFzc2V0TWFuYWdlcjo6Zm5jU2NhbkFuZE1lcmdlRGlyTG9ja2VkKAorICAgIFNvcnRlZFZlY3RvcjxBc3NldERpcjo6RmlsZUluZm8+KiBwTWVyZ2VkSW5mbywKKyAgICBjb25zdCBhc3NldF9wYXRoJiBhcCwgY29uc3QgY2hhciogbG9jYWxlLCBjb25zdCBjaGFyKiB2ZW5kb3IsCisgICAgY29uc3QgY2hhciogZGlyTmFtZSkKK3sKKyAgICBTb3J0ZWRWZWN0b3I8QXNzZXREaXI6OkZpbGVJbmZvPiogcENvbnRlbnRzOworICAgIFN0cmluZzggcGFydGlhbFBhdGg7CisgICAgU3RyaW5nOCBmdWxsUGF0aDsKKworICAgIC8vIFhYWCBUaGlzIGlzIGJyb2tlbiAtLSB0aGUgZmlsZW5hbWUgY2FjaGUgbmVlZHMgdG8gaG9sZCB0aGUgYmFzZQorICAgIC8vIGFzc2V0IHBhdGggc2VwYXJhdGVseSBmcm9tIGl0cyBmaWxlbmFtZS4KKyAgICAKKyAgICBwYXJ0aWFsUGF0aCA9IGNyZWF0ZVBhdGhOYW1lTG9ja2VkKGFwLCBsb2NhbGUsIHZlbmRvcik7CisgICAgaWYgKGRpck5hbWVbMF0gIT0gJ1wwJykgeworICAgICAgICBwYXJ0aWFsUGF0aC5hcHBlbmRQYXRoKGRpck5hbWUpOworICAgIH0KKworICAgIGZ1bGxQYXRoID0gcGFydGlhbFBhdGg7CisgICAgcENvbnRlbnRzID0gc2NhbkRpckxvY2tlZChmdWxsUGF0aCk7CisgICAgaWYgKHBDb250ZW50cyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsgICAgICAgLy8gZGlyZWN0b3J5IGRpZCBub3QgZXhpc3QKKyAgICB9CisKKyAgICAvKgorICAgICAqIFNjYW4gYWxsIHN1YmRpcmVjdG9yaWVzIG9mIHRoZSBjdXJyZW50IGRpciwgbWVyZ2luZyB3aGF0IHdlIGZpbmQKKyAgICAgKiBpbnRvICJwTWVyZ2VkSW5mbyIuCisgICAgICovCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAoaW50KSBwQ29udGVudHMtPnNpemUoKTsgaSsrKSB7CisgICAgICAgIGlmIChwQ29udGVudHMtPml0ZW1BdChpKS5nZXRGaWxlVHlwZSgpID09IGtGaWxlVHlwZURpcmVjdG9yeSkgeworICAgICAgICAgICAgU3RyaW5nOCBzdWJkaXIoZGlyTmFtZSk7CisgICAgICAgICAgICBzdWJkaXIuYXBwZW5kUGF0aChwQ29udGVudHMtPml0ZW1BdChpKS5nZXRGaWxlTmFtZSgpKTsKKworICAgICAgICAgICAgZm5jU2NhbkFuZE1lcmdlRGlyTG9ja2VkKHBNZXJnZWRJbmZvLCBhcCwgbG9jYWxlLCB2ZW5kb3IsIHN1YmRpci5zdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRvIGJlIGNvbnNpc3RlbnQsIHdlIHdhbnQgZW50cmllcyBmb3IgdGhlIHJvb3QgZGlyZWN0b3J5LiAgSWYKKyAgICAgKiB3ZSdyZSB0aGUgcm9vdCwgYWRkIG9uZSBub3cuCisgICAgICovCisgICAgaWYgKGRpck5hbWVbMF0gPT0gJ1wwJykgeworICAgICAgICBBc3NldERpcjo6RmlsZUluZm8gdG1wSW5mbzsKKworICAgICAgICB0bXBJbmZvLnNldChTdHJpbmc4KCIiKSwga0ZpbGVUeXBlRGlyZWN0b3J5KTsKKyAgICAgICAgdG1wSW5mby5zZXRTb3VyY2VOYW1lKGNyZWF0ZVBhdGhOYW1lTG9ja2VkKGFwLCBsb2NhbGUsIHZlbmRvcikpOworICAgICAgICBwQ29udGVudHMtPmFkZCh0bXBJbmZvKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFdlIHdhbnQgdG8gcHJlcGVuZCB0aGUgZXh0ZW5kZWQgcGFydGlhbCBwYXRoIHRvIGV2ZXJ5IGVudHJ5IGluCisgICAgICogInBDb250ZW50cyIuICBJdCdzIHRoZSBzYW1lIHZhbHVlIGZvciBlYWNoIGVudHJ5LCBzbyB0aGlzIHdpbGwKKyAgICAgKiBub3QgY2hhbmdlIHRoZSBzb3J0aW5nIG9yZGVyIG9mIHRoZSB2ZWN0b3IgY29udGVudHMuCisgICAgICovCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAoaW50KSBwQ29udGVudHMtPnNpemUoKTsgaSsrKSB7CisgICAgICAgIGNvbnN0IEFzc2V0RGlyOjpGaWxlSW5mbyYgaW5mbyA9IHBDb250ZW50cy0+aXRlbUF0KGkpOworICAgICAgICBwQ29udGVudHMtPmVkaXRJdGVtQXQoaSkuc2V0RmlsZU5hbWUocGFydGlhbFBhdGguYXBwZW5kUGF0aENvcHkoaW5mby5nZXRGaWxlTmFtZSgpKSk7CisgICAgfQorCisgICAgbWVyZ2VJbmZvTG9ja2VkKHBNZXJnZWRJbmZvLCBwQ29udGVudHMpOworICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogVHJhc2ggdGhlIGNhY2hlLgorICovCit2b2lkIEFzc2V0TWFuYWdlcjo6cHVyZ2VGaWxlTmFtZUNhY2hlTG9ja2VkKHZvaWQpCit7CisgICAgbUNhY2hlVmFsaWQgPSBmYWxzZTsKKyAgICBtQ2FjaGUuY2xlYXIoKTsKK30KKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBBc3NldE1hbmFnZXI6OlNoYXJlZFppcAorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworCitNdXRleCBBc3NldE1hbmFnZXI6OlNoYXJlZFppcDo6Z0xvY2s7CitEZWZhdWx0S2V5ZWRWZWN0b3I8U3RyaW5nOCwgd3A8QXNzZXRNYW5hZ2VyOjpTaGFyZWRaaXA+ID4gQXNzZXRNYW5hZ2VyOjpTaGFyZWRaaXA6OmdPcGVuOworCitBc3NldE1hbmFnZXI6OlNoYXJlZFppcDo6U2hhcmVkWmlwKGNvbnN0IFN0cmluZzgmIHBhdGgsIHRpbWVfdCBtb2RXaGVuKQorICAgIDogbVBhdGgocGF0aCksIG1aaXBGaWxlKE5VTEwpLCBtTW9kV2hlbihtb2RXaGVuKSwgbVJlc291cmNlVGFibGVBc3NldChOVUxMKQoreworICAgIC8vTE9HSSgiQ3JlYXRpbmcgU2hhcmVkWmlwICVwICVzXG4iLCB0aGlzLCAoY29uc3QgY2hhciopbVBhdGgpOworICAgIG1aaXBGaWxlID0gbmV3IFppcEZpbGVSTzsKKyAgICBMT0dWKCIrKysgb3BlbmluZyB6aXAgJyVzJ1xuIiwgbVBhdGguc3RyaW5nKCkpOworICAgIGlmIChtWmlwRmlsZS0+b3BlbihtUGF0aC5zdHJpbmcoKSkgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgTE9HRCgiZmFpbGVkIHRvIG9wZW4gWmlwIGFyY2hpdmUgJyVzJ1xuIiwgbVBhdGguc3RyaW5nKCkpOworICAgICAgICBkZWxldGUgbVppcEZpbGU7CisgICAgICAgIG1aaXBGaWxlID0gTlVMTDsKKyAgICB9Cit9CisKK3NwPEFzc2V0TWFuYWdlcjo6U2hhcmVkWmlwPiBBc3NldE1hbmFnZXI6OlNoYXJlZFppcDo6Z2V0KGNvbnN0IFN0cmluZzgmIHBhdGgpCit7CisgICAgQXV0b011dGV4IF9sKGdMb2NrKTsKKyAgICB0aW1lX3QgbW9kV2hlbiA9IGdldEZpbGVNb2REYXRlKHBhdGgpOworICAgIHNwPFNoYXJlZFppcD4gemlwID0gZ09wZW4udmFsdWVGb3IocGF0aCkucHJvbW90ZSgpOworICAgIGlmICh6aXAgIT0gTlVMTCAmJiB6aXAtPm1Nb2RXaGVuID09IG1vZFdoZW4pIHsKKyAgICAgICAgcmV0dXJuIHppcDsKKyAgICB9CisgICAgemlwID0gbmV3IFNoYXJlZFppcChwYXRoLCBtb2RXaGVuKTsKKyAgICBnT3Blbi5hZGQocGF0aCwgemlwKTsKKyAgICByZXR1cm4gemlwOworCit9CisKK1ppcEZpbGVSTyogQXNzZXRNYW5hZ2VyOjpTaGFyZWRaaXA6OmdldFppcCgpCit7CisgICAgcmV0dXJuIG1aaXBGaWxlOworfQorCitBc3NldCogQXNzZXRNYW5hZ2VyOjpTaGFyZWRaaXA6OmdldFJlc291cmNlVGFibGVBc3NldCgpCit7CisgICAgTE9HVigiR2V0dGluZyBmcm9tIFNoYXJlZFppcCAlcCByZXNvdXJjZSBhc3NldCAlcFxuIiwgdGhpcywgbVJlc291cmNlVGFibGVBc3NldCk7CisgICAgcmV0dXJuIG1SZXNvdXJjZVRhYmxlQXNzZXQ7Cit9CisKK0Fzc2V0KiBBc3NldE1hbmFnZXI6OlNoYXJlZFppcDo6c2V0UmVzb3VyY2VUYWJsZUFzc2V0KEFzc2V0KiBhc3NldCkKK3sKKyAgICB7CisgICAgICAgIEF1dG9NdXRleCBfbChnTG9jayk7CisgICAgICAgIGlmIChtUmVzb3VyY2VUYWJsZUFzc2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIG1SZXNvdXJjZVRhYmxlQXNzZXQgPSBhc3NldDsKKyAgICAgICAgICAgIC8vIFRoaXMgaXMgbm90IHRocmVhZCBzYWZlIHRoZSBmaXJzdCB0aW1lIGl0IGlzIGNhbGxlZCwgc28KKyAgICAgICAgICAgIC8vIGRvIGl0IGhlcmUgd2l0aCB0aGUgZ2xvYmFsIGxvY2sgaGVsZC4KKyAgICAgICAgICAgIGFzc2V0LT5nZXRCdWZmZXIodHJ1ZSk7CisgICAgICAgICAgICByZXR1cm4gYXNzZXQ7CisgICAgICAgIH0KKyAgICB9CisgICAgZGVsZXRlIGFzc2V0OworICAgIHJldHVybiBtUmVzb3VyY2VUYWJsZUFzc2V0OworfQorCitib29sIEFzc2V0TWFuYWdlcjo6U2hhcmVkWmlwOjppc1VwVG9EYXRlKCkKK3sKKyAgICB0aW1lX3QgbW9kV2hlbiA9IGdldEZpbGVNb2REYXRlKG1QYXRoLnN0cmluZygpKTsKKyAgICByZXR1cm4gbU1vZFdoZW4gPT0gbW9kV2hlbjsKK30KKworQXNzZXRNYW5hZ2VyOjpTaGFyZWRaaXA6On5TaGFyZWRaaXAoKQoreworICAgIC8vTE9HSSgiRGVzdHJveWluZyBTaGFyZWRaaXAgJXAgJXNcbiIsIHRoaXMsIChjb25zdCBjaGFyKiltUGF0aCk7CisgICAgaWYgKG1SZXNvdXJjZVRhYmxlQXNzZXQgIT0gTlVMTCkgeworICAgICAgICBkZWxldGUgbVJlc291cmNlVGFibGVBc3NldDsKKyAgICB9CisgICAgaWYgKG1aaXBGaWxlICE9IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlIG1aaXBGaWxlOworICAgICAgICBMT0dWKCJDbG9zZWQgJyVzJ1xuIiwgbVBhdGguc3RyaW5nKCkpOworICAgIH0KK30KKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBBc3NldE1hbmFnZXI6OlppcFNldAorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworLyoKKyAqIENvbnN0cnVjdG9yLgorICovCitBc3NldE1hbmFnZXI6OlppcFNldDo6WmlwU2V0KHZvaWQpCit7Cit9CisKKy8qCisgKiBEZXN0cnVjdG9yLiAgQ2xvc2UgYW55IG9wZW4gYXJjaGl2ZXMuCisgKi8KK0Fzc2V0TWFuYWdlcjo6WmlwU2V0Ojp+WmlwU2V0KHZvaWQpCit7CisgICAgc2l6ZV90IE4gPSBtWmlwRmlsZS5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBOOyBpKyspCisgICAgICAgIGNsb3NlWmlwKGkpOworfQorCisvKgorICogQ2xvc2UgYSBaaXAgZmlsZSBhbmQgcmVzZXQgdGhlIGVudHJ5LgorICovCit2b2lkIEFzc2V0TWFuYWdlcjo6WmlwU2V0OjpjbG9zZVppcChpbnQgaWR4KQoreworICAgIG1aaXBGaWxlLmVkaXRJdGVtQXQoaWR4KSA9IE5VTEw7Cit9CisKKworLyoKKyAqIFJldHJpZXZlIHRoZSBhcHByb3ByaWF0ZSBaaXAgZmlsZSBmcm9tIHRoZSBzZXQuCisgKi8KK1ppcEZpbGVSTyogQXNzZXRNYW5hZ2VyOjpaaXBTZXQ6OmdldFppcChjb25zdCBTdHJpbmc4JiBwYXRoKQoreworICAgIGludCBpZHggPSBnZXRJbmRleChwYXRoKTsKKyAgICBzcDxTaGFyZWRaaXA+IHppcCA9IG1aaXBGaWxlW2lkeF07CisgICAgaWYgKHppcCA9PSBOVUxMKSB7CisgICAgICAgIHppcCA9IFNoYXJlZFppcDo6Z2V0KHBhdGgpOworICAgICAgICBtWmlwRmlsZS5lZGl0SXRlbUF0KGlkeCkgPSB6aXA7CisgICAgfQorICAgIHJldHVybiB6aXAtPmdldFppcCgpOworfQorCitBc3NldCogQXNzZXRNYW5hZ2VyOjpaaXBTZXQ6OmdldFppcFJlc291cmNlVGFibGUoY29uc3QgU3RyaW5nOCYgcGF0aCkKK3sKKyAgICBpbnQgaWR4ID0gZ2V0SW5kZXgocGF0aCk7CisgICAgc3A8U2hhcmVkWmlwPiB6aXAgPSBtWmlwRmlsZVtpZHhdOworICAgIGlmICh6aXAgPT0gTlVMTCkgeworICAgICAgICB6aXAgPSBTaGFyZWRaaXA6OmdldChwYXRoKTsKKyAgICAgICAgbVppcEZpbGUuZWRpdEl0ZW1BdChpZHgpID0gemlwOworICAgIH0KKyAgICByZXR1cm4gemlwLT5nZXRSZXNvdXJjZVRhYmxlQXNzZXQoKTsKK30KKworQXNzZXQqIEFzc2V0TWFuYWdlcjo6WmlwU2V0OjpzZXRaaXBSZXNvdXJjZVRhYmxlKGNvbnN0IFN0cmluZzgmIHBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXQqIGFzc2V0KQoreworICAgIGludCBpZHggPSBnZXRJbmRleChwYXRoKTsKKyAgICBzcDxTaGFyZWRaaXA+IHppcCA9IG1aaXBGaWxlW2lkeF07CisgICAgLy8gZG9lc24ndCBtYWtlIHNlbnNlIHRvIGNhbGwgYmVmb3JlIHByZXZpb3VzbHkgYWNjZXNzaW5nLgorICAgIHJldHVybiB6aXAtPnNldFJlc291cmNlVGFibGVBc3NldChhc3NldCk7Cit9CisKKy8qCisgKiBHZW5lcmF0ZSB0aGUgcGFydGlhbCBwYXRobmFtZSBmb3IgdGhlIHNwZWNpZmllZCBhcmNoaXZlLiAgVGhlIGNhbGxlcgorICogZ2V0cyB0byBwcmVwZW5kIHRoZSBhc3NldCByb290IGRpcmVjdG9yeS4KKyAqCisgKiBSZXR1cm5zIHNvbWV0aGluZyBsaWtlICJjb21tb24vZW4tVVMtbm9vZ2xlLmphciIuCisgKi8KKy8qc3RhdGljKi8gU3RyaW5nOCBBc3NldE1hbmFnZXI6OlppcFNldDo6Z2V0UGF0aE5hbWUoY29uc3QgY2hhciogemlwUGF0aCkKK3sKKyAgICByZXR1cm4gU3RyaW5nOCh6aXBQYXRoKTsKK30KKworYm9vbCBBc3NldE1hbmFnZXI6OlppcFNldDo6aXNVcFRvRGF0ZSgpCit7CisgICAgY29uc3Qgc2l6ZV90IE4gPSBtWmlwRmlsZS5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPE47IGkrKykgeworICAgICAgICBpZiAobVppcEZpbGVbaV0gIT0gTlVMTCAmJiAhbVppcEZpbGVbaV0tPmlzVXBUb0RhdGUoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogQ29tcHV0ZSB0aGUgemlwIGZpbGUncyBpbmRleC4KKyAqCisgKiAiYXBwTmFtZSIsICJsb2NhbGUiLCBhbmQgInZlbmRvciIgc2hvdWxkIGJlIHNldCB0byBOVUxMIHRvIGluZGljYXRlIHRoZQorICogZGVmYXVsdCBkaXJlY3RvcnkuCisgKi8KK2ludCBBc3NldE1hbmFnZXI6OlppcFNldDo6Z2V0SW5kZXgoY29uc3QgU3RyaW5nOCYgemlwKSBjb25zdAoreworICAgIGNvbnN0IHNpemVfdCBOID0gbVppcFBhdGguc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgaWYgKG1aaXBQYXRoW2ldID09IHppcCkgeworICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBtWmlwUGF0aC5hZGQoemlwKTsKKyAgICBtWmlwRmlsZS5hZGQoTlVMTCk7CisKKyAgICByZXR1cm4gbVppcFBhdGguc2l6ZSgpLTE7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvQmluZGVyLmNwcCBiL2xpYnMvdXRpbHMvQmluZGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2U0Njg1Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9CaW5kZXIuY3BwCkBAIC0wLDAgKzEsMjQyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHV0aWxzL0JpbmRlci5oPgorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvQnBCaW5kZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9JSW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisKKyNpbmNsdWRlIDxzdGRpby5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzcDxJSW50ZXJmYWNlPiAgSUJpbmRlcjo6cXVlcnlMb2NhbEludGVyZmFjZShjb25zdCBTdHJpbmcxNiYgZGVzY3JpcHRvcikKK3sKKyAgICByZXR1cm4gTlVMTDsKK30KKworQkJpbmRlciogSUJpbmRlcjo6bG9jYWxCaW5kZXIoKQoreworICAgIHJldHVybiBOVUxMOworfQorCitCcEJpbmRlciogSUJpbmRlcjo6cmVtb3RlQmluZGVyKCkKK3sKKyAgICByZXR1cm4gTlVMTDsKK30KKworYm9vbCBJQmluZGVyOjpjaGVja1N1YmNsYXNzKGNvbnN0IHZvaWQqIC8qc3ViY2xhc3NJRCovKSBjb25zdAoreworICAgIHJldHVybiBmYWxzZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEJCaW5kZXI6OkV4dHJhcworeworcHVibGljOgorICAgIE11dGV4IG1Mb2NrOworICAgIEJwQmluZGVyOjpPYmplY3RNYW5hZ2VyIG1PYmplY3RzOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0JCaW5kZXI6OkJCaW5kZXIoKQorICAgIDogbUV4dHJhcyhOVUxMKQoreworfQorCitib29sIEJCaW5kZXI6OmlzQmluZGVyQWxpdmUoKSBjb25zdAoreworICAgIHJldHVybiB0cnVlOworfQorCitzdGF0dXNfdCBCQmluZGVyOjpwaW5nQmluZGVyKCkKK3sKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK1N0cmluZzE2IEJCaW5kZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSBjb25zdAoreworICAgIExPR1coInJlYWNoZWQgQkJpbmRlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvciAodGhpcz0lcCkiLCB0aGlzKTsKKyAgICByZXR1cm4gU3RyaW5nMTYoKTsKK30KKworc3RhdHVzX3QgQkJpbmRlcjo6dHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBkYXRhLnNldERhdGFQb3NpdGlvbigwKTsKKworICAgIHN0YXR1c190IGVyciA9IE5PX0VSUk9SOworICAgIHN3aXRjaCAoY29kZSkgeworICAgICAgICBjYXNlIFBJTkdfVFJBTlNBQ1RJT046CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihwaW5nQmluZGVyKCkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBlcnIgPSBvblRyYW5zYWN0KGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBpZiAocmVwbHkgIT0gTlVMTCkgeworICAgICAgICByZXBseS0+c2V0RGF0YVBvc2l0aW9uKDApOworICAgIH0KKworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IEJCaW5kZXI6OmxpbmtUb0RlYXRoKAorICAgIGNvbnN0IHNwPERlYXRoUmVjaXBpZW50PiYgcmVjaXBpZW50LCB2b2lkKiBjb29raWUsIHVpbnQzMl90IGZsYWdzKQoreworICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKK30KKworc3RhdHVzX3QgQkJpbmRlcjo6dW5saW5rVG9EZWF0aCgKKyAgICBjb25zdCB3cDxEZWF0aFJlY2lwaWVudD4mIHJlY2lwaWVudCwgdm9pZCogY29va2llLCB1aW50MzJfdCBmbGFncywKKyAgICB3cDxEZWF0aFJlY2lwaWVudD4qIG91dFJlY2lwaWVudCkKK3sKKyAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047Cit9CisKK3N0YXR1c190IEJCaW5kZXI6OmR1bXAoaW50IGZkLCBjb25zdCBWZWN0b3I8U3RyaW5nMTY+JiBhcmdzKQoreworICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBCQmluZGVyOjphdHRhY2hPYmplY3QoCisgICAgY29uc3Qgdm9pZCogb2JqZWN0SUQsIHZvaWQqIG9iamVjdCwgdm9pZCogY2xlYW51cENvb2tpZSwKKyAgICBvYmplY3RfY2xlYW51cF9mdW5jIGZ1bmMpCit7CisgICAgRXh0cmFzKiBlID0gbUV4dHJhczsKKworICAgIGlmICghZSkgeworICAgICAgICBlID0gbmV3IEV4dHJhczsKKyAgICAgICAgaWYgKGFuZHJvaWRfYXRvbWljX2NtcHhjaGcoMCwgcmVpbnRlcnByZXRfY2FzdDxpbnQzMl90PihlKSwKKyAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGludDMyX3QqPigmbUV4dHJhcykpICE9IDApIHsKKyAgICAgICAgICAgIGRlbGV0ZSBlOworICAgICAgICAgICAgZSA9IG1FeHRyYXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGUgPT0gMCkgcmV0dXJuOyAvLyBvdXQgb2YgbWVtb3J5CisgICAgfQorCisgICAgQXV0b011dGV4IF9sKGUtPm1Mb2NrKTsKKyAgICBlLT5tT2JqZWN0cy5hdHRhY2gob2JqZWN0SUQsIG9iamVjdCwgY2xlYW51cENvb2tpZSwgZnVuYyk7Cit9CisKK3ZvaWQqIEJCaW5kZXI6OmZpbmRPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpIGNvbnN0Cit7CisgICAgRXh0cmFzKiBlID0gbUV4dHJhczsKKyAgICBpZiAoIWUpIHJldHVybiBOVUxMOworCisgICAgQXV0b011dGV4IF9sKGUtPm1Mb2NrKTsKKyAgICByZXR1cm4gZS0+bU9iamVjdHMuZmluZChvYmplY3RJRCk7Cit9CisKK3ZvaWQgQkJpbmRlcjo6ZGV0YWNoT2JqZWN0KGNvbnN0IHZvaWQqIG9iamVjdElEKQoreworICAgIEV4dHJhcyogZSA9IG1FeHRyYXM7CisgICAgaWYgKCFlKSByZXR1cm47CisKKyAgICBBdXRvTXV0ZXggX2woZS0+bUxvY2spOworICAgIGUtPm1PYmplY3RzLmRldGFjaChvYmplY3RJRCk7Cit9CisKK0JCaW5kZXIqIEJCaW5kZXI6OmxvY2FsQmluZGVyKCkKK3sKKyAgICByZXR1cm4gdGhpczsKK30KKworQkJpbmRlcjo6fkJCaW5kZXIoKQoreworICAgIGlmIChtRXh0cmFzKSBkZWxldGUgbUV4dHJhczsKK30KKworCitzdGF0dXNfdCBCQmluZGVyOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgSU5URVJGQUNFX1RSQU5TQUNUSU9OOgorICAgICAgICAgICAgcmVwbHktPndyaXRlU3RyaW5nMTYoZ2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKworICAgICAgICBjYXNlIERVTVBfVFJBTlNBQ1RJT046IHsKKyAgICAgICAgICAgIGludCBmZCA9IGRhdGEucmVhZEZpbGVEZXNjcmlwdG9yKCk7CisgICAgICAgICAgICBpbnQgYXJnYyA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBWZWN0b3I8U3RyaW5nMTY+IGFyZ3M7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ2MgJiYgZGF0YS5kYXRhQXZhaWwoKSA+IDA7IGkrKykgeworICAgICAgICAgICAgICAgYXJncy5hZGQoZGF0YS5yZWFkU3RyaW5nMTYoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZHVtcChmZCwgYXJncyk7CisgICAgICAgIH0KKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBVTktOT1dOX1RSQU5TQUNUSU9OOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2VudW0geworICAgIC8vIFRoaXMgaXMgdXNlZCB0byB0cmFuc2ZlciBvd25lcnNoaXAgb2YgdGhlIHJlbW90ZSBiaW5kZXIgZnJvbQorICAgIC8vIHRoZSBCcFJlZkJhc2Ugb2JqZWN0IGhvbGRpbmcgaXQgKHdoZW4gaXQgaXMgY29uc3RydWN0ZWQpLCB0byB0aGUKKyAgICAvLyBvd25lciBvZiB0aGUgQnBSZWZCYXNlIG9iamVjdCB3aGVuIGl0IGZpcnN0IGFjcXVpcmVzIHRoYXQgQnBSZWZCYXNlLgorICAgIGtSZW1vdGVBY3F1aXJlZCA9IDB4MDAwMDAwMDEKK307CisKK0JwUmVmQmFzZTo6QnBSZWZCYXNlKGNvbnN0IHNwPElCaW5kZXI+JiBvKQorICAgIDogbVJlbW90ZShvLmdldCgpKSwgbVJlZnMoTlVMTCksIG1TdGF0ZSgwKQoreworICAgIGV4dGVuZE9iamVjdExpZmV0aW1lKE9CSkVDVF9MSUZFVElNRV9XRUFLKTsKKworICAgIGlmIChtUmVtb3RlKSB7CisgICAgICAgIG1SZW1vdGUtPmluY1N0cm9uZyh0aGlzKTsgICAgICAgICAgIC8vIFJlbW92ZWQgb24gZmlyc3QgSW5jU3Ryb25nKCkuCisgICAgICAgIG1SZWZzID0gbVJlbW90ZS0+Y3JlYXRlV2Vhayh0aGlzKTsgIC8vIEhlbGQgZm9yIG91ciBlbnRpcmUgbGlmZXRpbWUuCisgICAgfQorfQorCitCcFJlZkJhc2U6On5CcFJlZkJhc2UoKQoreworICAgIGlmIChtUmVtb3RlKSB7CisgICAgICAgIGlmICghKG1TdGF0ZSZrUmVtb3RlQWNxdWlyZWQpKSB7CisgICAgICAgICAgICBtUmVtb3RlLT5kZWNTdHJvbmcodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgbVJlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgfQorfQorCit2b2lkIEJwUmVmQmFzZTo6b25GaXJzdFJlZigpCit7CisgICAgYW5kcm9pZF9hdG9taWNfb3Ioa1JlbW90ZUFjcXVpcmVkLCAmbVN0YXRlKTsKK30KKwordm9pZCBCcFJlZkJhc2U6Om9uTGFzdFN0cm9uZ1JlZihjb25zdCB2b2lkKiBpZCkKK3sKKyAgICBpZiAobVJlbW90ZSkgeworICAgICAgICBtUmVtb3RlLT5kZWNTdHJvbmcodGhpcyk7CisgICAgfQorfQorCitib29sIEJwUmVmQmFzZTo6b25JbmNTdHJvbmdBdHRlbXB0ZWQodWludDMyX3QgZmxhZ3MsIGNvbnN0IHZvaWQqIGlkKQoreworICAgIHJldHVybiBtUmVtb3RlID8gbVJlZnMtPmF0dGVtcHRJbmNTdHJvbmcodGhpcykgOiBmYWxzZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL0JwQmluZGVyLmNwcCBiL2xpYnMvdXRpbHMvQnBCaW5kZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5YWIxOTUKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0JwQmluZGVyLmNwcApAQCAtMCwwICsxLDM0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiQnBCaW5kZXIiCisvLyNkZWZpbmUgTE9HX05ERUJVRyAwCisKKyNpbmNsdWRlIDx1dGlscy9CcEJpbmRlci5oPgorCisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisKKy8vI3VuZGVmIExPR1YKKy8vI2RlZmluZSBMT0dWKC4uLikgZnByaW50ZihzdGRlcnIsIF9fVkFfQVJHU19fKQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitCcEJpbmRlcjo6T2JqZWN0TWFuYWdlcjo6T2JqZWN0TWFuYWdlcigpCit7Cit9CisKK0JwQmluZGVyOjpPYmplY3RNYW5hZ2VyOjp+T2JqZWN0TWFuYWdlcigpCit7CisgICAga2lsbCgpOworfQorCit2b2lkIEJwQmluZGVyOjpPYmplY3RNYW5hZ2VyOjphdHRhY2goCisgICAgY29uc3Qgdm9pZCogb2JqZWN0SUQsIHZvaWQqIG9iamVjdCwgdm9pZCogY2xlYW51cENvb2tpZSwKKyAgICBJQmluZGVyOjpvYmplY3RfY2xlYW51cF9mdW5jIGZ1bmMpCit7CisgICAgZW50cnlfdCBlOworICAgIGUub2JqZWN0ID0gb2JqZWN0OworICAgIGUuY2xlYW51cENvb2tpZSA9IGNsZWFudXBDb29raWU7CisgICAgZS5mdW5jID0gZnVuYzsKKworICAgIGlmIChtT2JqZWN0cy5pbmRleE9mS2V5KG9iamVjdElEKSA+PSAwKSB7CisgICAgICAgIExPR0UoIlRyeWluZyB0byBhdHRhY2ggb2JqZWN0IElEICVwIHRvIGJpbmRlciBPYmplY3RNYW5hZ2VyICVwIHdpdGggb2JqZWN0ICVwLCBidXQgb2JqZWN0IElEIGFscmVhZHkgaW4gdXNlIiwKKyAgICAgICAgICAgICAgICBvYmplY3RJRCwgdGhpcywgIG9iamVjdCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBtT2JqZWN0cy5hZGQob2JqZWN0SUQsIGUpOworfQorCit2b2lkKiBCcEJpbmRlcjo6T2JqZWN0TWFuYWdlcjo6ZmluZChjb25zdCB2b2lkKiBvYmplY3RJRCkgY29uc3QKK3sKKyAgICBjb25zdCBzc2l6ZV90IGkgPSBtT2JqZWN0cy5pbmRleE9mS2V5KG9iamVjdElEKTsKKyAgICBpZiAoaSA8IDApIHJldHVybiBOVUxMOworICAgIHJldHVybiBtT2JqZWN0cy52YWx1ZUF0KGkpLm9iamVjdDsKK30KKwordm9pZCBCcEJpbmRlcjo6T2JqZWN0TWFuYWdlcjo6ZGV0YWNoKGNvbnN0IHZvaWQqIG9iamVjdElEKQoreworICAgIG1PYmplY3RzLnJlbW92ZUl0ZW0ob2JqZWN0SUQpOworfQorCit2b2lkIEJwQmluZGVyOjpPYmplY3RNYW5hZ2VyOjpraWxsKCkKK3sKKyAgICBjb25zdCBzaXplX3QgTiA9IG1PYmplY3RzLnNpemUoKTsKKyAgICBMT0dWKCJLaWxsaW5nICVkIG9iamVjdHMgaW4gbWFuYWdlciAlcCIsIE4sIHRoaXMpOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgY29uc3QgZW50cnlfdCYgZSA9IG1PYmplY3RzLnZhbHVlQXQoaSk7CisgICAgICAgIGlmIChlLmZ1bmMgIT0gTlVMTCkgeworICAgICAgICAgICAgZS5mdW5jKG1PYmplY3RzLmtleUF0KGkpLCBlLm9iamVjdCwgZS5jbGVhbnVwQ29va2llKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIG1PYmplY3RzLmNsZWFyKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitCcEJpbmRlcjo6QnBCaW5kZXIoaW50MzJfdCBoYW5kbGUpCisgICAgOiBtSGFuZGxlKGhhbmRsZSkKKyAgICAsIG1BbGl2ZSgxKQorICAgICwgbU9iaXRzU2VudCgwKQorICAgICwgbU9iaXR1YXJpZXMoTlVMTCkKK3sKKyAgICBMT0dWKCJDcmVhdGluZyBCcEJpbmRlciAlcCBoYW5kbGUgJWRcbiIsIHRoaXMsIG1IYW5kbGUpOworCisgICAgZXh0ZW5kT2JqZWN0TGlmZXRpbWUoT0JKRUNUX0xJRkVUSU1FX1dFQUspOworICAgIElQQ1RocmVhZFN0YXRlOjpzZWxmKCktPmluY1dlYWtIYW5kbGUoaGFuZGxlKTsKK30KKworU3RyaW5nMTYgQnBCaW5kZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSBjb25zdAoreworICAgIFN0cmluZzE2IHJlczsKKyAgICBQYXJjZWwgc2VuZCwgcmVwbHk7CisgICAgc3RhdHVzX3QgZXJyID0gY29uc3RfY2FzdDxCcEJpbmRlcio+KHRoaXMpLT50cmFuc2FjdCgKKyAgICAgICAgICAgIElOVEVSRkFDRV9UUkFOU0FDVElPTiwgc2VuZCwgJnJlcGx5KTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSB7CisgICAgICAgIHJlcyA9IHJlcGx5LnJlYWRTdHJpbmcxNigpOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCitib29sIEJwQmluZGVyOjppc0JpbmRlckFsaXZlKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUFsaXZlICE9IDA7Cit9CisKK3N0YXR1c190IEJwQmluZGVyOjpwaW5nQmluZGVyKCkKK3sKKyAgICBQYXJjZWwgc2VuZDsKKyAgICBQYXJjZWwgcmVwbHk7CisgICAgc3RhdHVzX3QgZXJyID0gdHJhbnNhY3QoUElOR19UUkFOU0FDVElPTiwgc2VuZCwgJnJlcGx5KTsKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSByZXR1cm4gZXJyOworICAgIGlmIChyZXBseS5kYXRhU2l6ZSgpIDwgc2l6ZW9mKHN0YXR1c190KSkgcmV0dXJuIE5PVF9FTk9VR0hfREFUQTsKKyAgICByZXR1cm4gKHN0YXR1c190KXJlcGx5LnJlYWRJbnQzMigpOworfQorCitzdGF0dXNfdCBCcEJpbmRlcjo6ZHVtcChpbnQgZmQsIGNvbnN0IFZlY3RvcjxTdHJpbmcxNj4mIGFyZ3MpCit7CisgICAgUGFyY2VsIHNlbmQ7CisgICAgUGFyY2VsIHJlcGx5OworICAgIHNlbmQud3JpdGVGaWxlRGVzY3JpcHRvcihmZCk7CisgICAgY29uc3Qgc2l6ZV90IG51bUFyZ3MgPSBhcmdzLnNpemUoKTsKKyAgICBzZW5kLndyaXRlSW50MzIobnVtQXJncyk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBudW1BcmdzOyBpKyspIHsKKyAgICAgICAgc2VuZC53cml0ZVN0cmluZzE2KGFyZ3NbaV0pOworICAgIH0KKyAgICBzdGF0dXNfdCBlcnIgPSB0cmFuc2FjdChEVU1QX1RSQU5TQUNUSU9OLCBzZW5kLCAmcmVwbHkpOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IEJwQmluZGVyOjp0cmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIC8vIE9uY2UgYSBiaW5kZXIgaGFzIGRpZWQsIGl0IHdpbGwgbmV2ZXIgY29tZSBiYWNrIHRvIGxpZmUuCisgICAgaWYgKG1BbGl2ZSkgeworICAgICAgICBzdGF0dXNfdCBzdGF0dXMgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT50cmFuc2FjdCgKKyAgICAgICAgICAgIG1IYW5kbGUsIGNvZGUsIGRhdGEsIHJlcGx5LCBmbGFncyk7CisgICAgICAgIGlmIChzdGF0dXMgPT0gREVBRF9PQkpFQ1QpIG1BbGl2ZSA9IDA7CisgICAgICAgIHJldHVybiBzdGF0dXM7CisgICAgfQorCisgICAgcmV0dXJuIERFQURfT0JKRUNUOworfQorCitzdGF0dXNfdCBCcEJpbmRlcjo6bGlua1RvRGVhdGgoCisgICAgY29uc3Qgc3A8RGVhdGhSZWNpcGllbnQ+JiByZWNpcGllbnQsIHZvaWQqIGNvb2tpZSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgT2JpdHVhcnkgb2I7CisgICAgb2IucmVjaXBpZW50ID0gcmVjaXBpZW50OworICAgIG9iLmNvb2tpZSA9IGNvb2tpZTsKKyAgICBvYi5mbGFncyA9IGZsYWdzOworCisgICAgTE9HX0FMV0FZU19GQVRBTF9JRihyZWNpcGllbnQgPT0gTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsaW5rVG9EZWF0aCgpOiByZWNpcGllbnQgbXVzdCBiZSBub24tTlVMTCIpOworCisgICAgeworICAgICAgICBBdXRvTXV0ZXggX2wobUxvY2spOworCisgICAgICAgIGlmICghbU9iaXRzU2VudCkgeworICAgICAgICAgICAgaWYgKCFtT2JpdHVhcmllcykgeworICAgICAgICAgICAgICAgIG1PYml0dWFyaWVzID0gbmV3IFZlY3RvcjxPYml0dWFyeT47CisgICAgICAgICAgICAgICAgaWYgKCFtT2JpdHVhcmllcykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMT0dWKCJSZXF1ZXN0aW5nIGRlYXRoIG5vdGlmaWNhdGlvbjogJXAgaGFuZGxlICVkXG4iLCB0aGlzLCBtSGFuZGxlKTsKKyAgICAgICAgICAgICAgICBnZXRXZWFrUmVmcygpLT5pbmNXZWFrKHRoaXMpOworICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlKiBzZWxmID0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKTsKKyAgICAgICAgICAgICAgICBzZWxmLT5yZXF1ZXN0RGVhdGhOb3RpZmljYXRpb24obUhhbmRsZSwgdGhpcyk7CisgICAgICAgICAgICAgICAgc2VsZi0+Zmx1c2hDb21tYW5kcygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3NpemVfdCByZXMgPSBtT2JpdHVhcmllcy0+YWRkKG9iKTsKKyAgICAgICAgICAgIHJldHVybiByZXMgPj0gKHNzaXplX3QpTk9fRVJST1IgPyAoc3RhdHVzX3QpTk9fRVJST1IgOiByZXM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gREVBRF9PQkpFQ1Q7Cit9CisKK3N0YXR1c190IEJwQmluZGVyOjp1bmxpbmtUb0RlYXRoKAorICAgIGNvbnN0IHdwPERlYXRoUmVjaXBpZW50PiYgcmVjaXBpZW50LCB2b2lkKiBjb29raWUsIHVpbnQzMl90IGZsYWdzLAorICAgIHdwPERlYXRoUmVjaXBpZW50Piogb3V0UmVjaXBpZW50KQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisKKyAgICBpZiAobU9iaXRzU2VudCkgeworICAgICAgICByZXR1cm4gREVBRF9PQkpFQ1Q7CisgICAgfQorCisgICAgY29uc3Qgc2l6ZV90IE4gPSBtT2JpdHVhcmllcyA/IG1PYml0dWFyaWVzLT5zaXplKCkgOiAwOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgY29uc3QgT2JpdHVhcnkmIG9iaXQgPSBtT2JpdHVhcmllcy0+aXRlbUF0KGkpOworICAgICAgICBpZiAoKG9iaXQucmVjaXBpZW50ID09IHJlY2lwaWVudAorICAgICAgICAgICAgICAgICAgICB8fCAocmVjaXBpZW50ID09IE5VTEwgJiYgb2JpdC5jb29raWUgPT0gY29va2llKSkKKyAgICAgICAgICAgICAgICAmJiBvYml0LmZsYWdzID09IGZsYWdzKSB7CisgICAgICAgICAgICBjb25zdCB1aW50MzJfdCBhbGxGbGFncyA9IG9iaXQuZmxhZ3N8ZmxhZ3M7CisgICAgICAgICAgICBpZiAob3V0UmVjaXBpZW50ICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAqb3V0UmVjaXBpZW50ID0gbU9iaXR1YXJpZXMtPml0ZW1BdChpKS5yZWNpcGllbnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtT2JpdHVhcmllcy0+cmVtb3ZlQXQoaSk7CisgICAgICAgICAgICBpZiAobU9iaXR1YXJpZXMtPnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgTE9HVigiQ2xlYXJpbmcgZGVhdGggbm90aWZpY2F0aW9uOiAlcCBoYW5kbGUgJWRcbiIsIHRoaXMsIG1IYW5kbGUpOworICAgICAgICAgICAgICAgIElQQ1RocmVhZFN0YXRlKiBzZWxmID0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKTsKKyAgICAgICAgICAgICAgICBzZWxmLT5jbGVhckRlYXRoTm90aWZpY2F0aW9uKG1IYW5kbGUsIHRoaXMpOworICAgICAgICAgICAgICAgIHNlbGYtPmZsdXNoQ29tbWFuZHMoKTsKKyAgICAgICAgICAgICAgICBkZWxldGUgbU9iaXR1YXJpZXM7CisgICAgICAgICAgICAgICAgbU9iaXR1YXJpZXMgPSBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworfQorCit2b2lkIEJwQmluZGVyOjpzZW5kT2JpdHVhcnkoKQoreworICAgIExPR1YoIlNlbmRpbmcgb2JpdHVhcnkgZm9yIHByb3h5ICVwIGhhbmRsZSAlZCwgbU9iaXRzU2VudD0lc1xuIiwKKyAgICAgICAgdGhpcywgbUhhbmRsZSwgbU9iaXRzU2VudCA/ICJ0cnVlIiA6ICJmYWxzZSIpOworCisgICAgbUFsaXZlID0gMDsKKyAgICBpZiAobU9iaXRzU2VudCkgcmV0dXJuOworCisgICAgbUxvY2subG9jaygpOworICAgIFZlY3RvcjxPYml0dWFyeT4qIG9iaXRzID0gbU9iaXR1YXJpZXM7CisgICAgaWYob2JpdHMgIT0gTlVMTCkgeworICAgICAgICBMT0dWKCJDbGVhcmluZyBzZW50IGRlYXRoIG5vdGlmaWNhdGlvbjogJXAgaGFuZGxlICVkXG4iLCB0aGlzLCBtSGFuZGxlKTsKKyAgICAgICAgSVBDVGhyZWFkU3RhdGUqIHNlbGYgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpOworICAgICAgICBzZWxmLT5jbGVhckRlYXRoTm90aWZpY2F0aW9uKG1IYW5kbGUsIHRoaXMpOworICAgICAgICBzZWxmLT5mbHVzaENvbW1hbmRzKCk7CisgICAgICAgIG1PYml0dWFyaWVzID0gTlVMTDsKKyAgICB9CisgICAgbU9iaXRzU2VudCA9IDE7CisgICAgbUxvY2sudW5sb2NrKCk7CisKKyAgICBMT0dWKCJSZXBvcnRpbmcgZGVhdGggb2YgcHJveHkgJXAgZm9yICVkIHJlY2lwaWVudHNcbiIsCisgICAgICAgIHRoaXMsIG9iaXRzID8gb2JpdHMtPnNpemUoKSA6IDApOworCisgICAgaWYgKG9iaXRzICE9IE5VTEwpIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IE4gPSBvYml0cy0+c2l6ZSgpOworICAgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgICAgICByZXBvcnRPbmVEZWF0aChvYml0cy0+aXRlbUF0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGRlbGV0ZSBvYml0czsKKyAgICB9Cit9CisKK3ZvaWQgQnBCaW5kZXI6OnJlcG9ydE9uZURlYXRoKGNvbnN0IE9iaXR1YXJ5JiBvYml0KQoreworICAgIHNwPERlYXRoUmVjaXBpZW50PiByZWNpcGllbnQgPSBvYml0LnJlY2lwaWVudC5wcm9tb3RlKCk7CisgICAgTE9HVigiUmVwb3J0aW5nIGRlYXRoIHRvIHJlY2lwaWVudDogJXBcbiIsIHJlY2lwaWVudC5nZXQoKSk7CisgICAgaWYgKHJlY2lwaWVudCA9PSBOVUxMKSByZXR1cm47CisKKyAgICByZWNpcGllbnQtPmJpbmRlckRpZWQodGhpcyk7Cit9CisKKwordm9pZCBCcEJpbmRlcjo6YXR0YWNoT2JqZWN0KAorICAgIGNvbnN0IHZvaWQqIG9iamVjdElELCB2b2lkKiBvYmplY3QsIHZvaWQqIGNsZWFudXBDb29raWUsCisgICAgb2JqZWN0X2NsZWFudXBfZnVuYyBmdW5jKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgTE9HVigiQXR0YWNoaW5nIG9iamVjdCAlcCB0byBiaW5kZXIgJXAgKG1hbmFnZXI9JXApIiwgb2JqZWN0LCB0aGlzLCAmbU9iamVjdHMpOworICAgIG1PYmplY3RzLmF0dGFjaChvYmplY3RJRCwgb2JqZWN0LCBjbGVhbnVwQ29va2llLCBmdW5jKTsKK30KKwordm9pZCogQnBCaW5kZXI6OmZpbmRPYmplY3QoY29uc3Qgdm9pZCogb2JqZWN0SUQpIGNvbnN0Cit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICByZXR1cm4gbU9iamVjdHMuZmluZChvYmplY3RJRCk7Cit9CisKK3ZvaWQgQnBCaW5kZXI6OmRldGFjaE9iamVjdChjb25zdCB2b2lkKiBvYmplY3RJRCkKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIG1PYmplY3RzLmRldGFjaChvYmplY3RJRCk7Cit9CisKK0JwQmluZGVyKiBCcEJpbmRlcjo6cmVtb3RlQmluZGVyKCkKK3sKKyAgICByZXR1cm4gdGhpczsKK30KKworQnBCaW5kZXI6On5CcEJpbmRlcigpCit7CisgICAgTE9HVigiRGVzdHJveWluZyBCcEJpbmRlciAlcCBoYW5kbGUgJWRcbiIsIHRoaXMsIG1IYW5kbGUpOworCisgICAgSVBDVGhyZWFkU3RhdGUqIGlwYyA9IElQQ1RocmVhZFN0YXRlOjpzZWxmKCk7CisKKyAgICBtTG9jay5sb2NrKCk7CisgICAgVmVjdG9yPE9iaXR1YXJ5Piogb2JpdHMgPSBtT2JpdHVhcmllczsKKyAgICBpZihvYml0cyAhPSBOVUxMKSB7CisgICAgICAgIGlmIChpcGMpIGlwYy0+Y2xlYXJEZWF0aE5vdGlmaWNhdGlvbihtSGFuZGxlLCB0aGlzKTsKKyAgICAgICAgbU9iaXR1YXJpZXMgPSBOVUxMOworICAgIH0KKyAgICBtTG9jay51bmxvY2soKTsKKworICAgIGlmIChvYml0cyAhPSBOVUxMKSB7CisgICAgICAgIC8vIFhYWCBTaG91bGQgd2UgdGVsbCBhbnkgcmVtYWluaW5nIERlYXRoUmVjaXBpZW50CisgICAgICAgIC8vIG9iamVjdHMgdGhhdCB0aGUgbGFzdCBzdHJvbmcgcmVmIGhhcyBnb25lIGF3YXksIHNvIHRoZXkKKyAgICAgICAgLy8gYXJlIG5vIGxvbmdlciBsaW5rZWQ/CisgICAgICAgIGRlbGV0ZSBvYml0czsKKyAgICB9CisKKyAgICBpZiAoaXBjKSB7CisgICAgICAgIGlwYy0+ZXhwdW5nZUhhbmRsZShtSGFuZGxlLCB0aGlzKTsKKyAgICAgICAgaXBjLT5kZWNXZWFrSGFuZGxlKG1IYW5kbGUpOworICAgIH0KK30KKwordm9pZCBCcEJpbmRlcjo6b25GaXJzdFJlZigpCit7CisgICAgTE9HVigib25GaXJzdFJlZiBCcEJpbmRlciAlcCBoYW5kbGUgJWRcbiIsIHRoaXMsIG1IYW5kbGUpOworICAgIElQQ1RocmVhZFN0YXRlKiBpcGMgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpOworICAgIGlmIChpcGMpIGlwYy0+aW5jU3Ryb25nSGFuZGxlKG1IYW5kbGUpOworfQorCit2b2lkIEJwQmluZGVyOjpvbkxhc3RTdHJvbmdSZWYoY29uc3Qgdm9pZCogaWQpCit7CisgICAgTE9HVigib25MYXN0U3Ryb25nUmVmIEJwQmluZGVyICVwIGhhbmRsZSAlZFxuIiwgdGhpcywgbUhhbmRsZSk7CisgICAgSUZfTE9HVigpIHsKKyAgICAgICAgcHJpbnRSZWZzKCk7CisgICAgfQorICAgIElQQ1RocmVhZFN0YXRlKiBpcGMgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpOworICAgIGlmIChpcGMpIGlwYy0+ZGVjU3Ryb25nSGFuZGxlKG1IYW5kbGUpOworfQorCitib29sIEJwQmluZGVyOjpvbkluY1N0cm9uZ0F0dGVtcHRlZCh1aW50MzJfdCBmbGFncywgY29uc3Qgdm9pZCogaWQpCit7CisgICAgTE9HVigib25JbmNTdHJvbmdBdHRlbXB0ZWQgQnBCaW5kZXIgJXAgaGFuZGxlICVkXG4iLCB0aGlzLCBtSGFuZGxlKTsKKyAgICBJUENUaHJlYWRTdGF0ZSogaXBjID0gSVBDVGhyZWFkU3RhdGU6OnNlbGYoKTsKKyAgICByZXR1cm4gaXBjID8gaXBjLT5hdHRlbXB0SW5jU3Ryb25nSGFuZGxlKG1IYW5kbGUpID09IE5PX0VSUk9SIDogZmFsc2U7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9CdWZmZXJlZFRleHRPdXRwdXQuY3BwIGIvbGlicy91dGlscy9CdWZmZXJlZFRleHRPdXRwdXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4OTY2MmUKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0J1ZmZlcmVkVGV4dE91dHB1dC5jcHAKQEAgLTAsMCArMSwyNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvQnVmZmVyZWRUZXh0T3V0cHV0Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9EZWJ1Zy5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9WZWN0b3IuaD4KKyNpbmNsdWRlIDxjdXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9TdGF0aWMuaD4KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0cnVjdCBCdWZmZXJlZFRleHRPdXRwdXQ6OkJ1ZmZlclN0YXRlIDogcHVibGljIFJlZkJhc2UKK3sKKyAgICBCdWZmZXJTdGF0ZShpbnQzMl90IF9zZXEpCisgICAgICAgIDogc2VxKF9zZXEpCisgICAgICAgICwgYnVmZmVyKE5VTEwpCisgICAgICAgICwgYnVmZmVyUG9zKDApCisgICAgICAgICwgYnVmZmVyU2l6ZSgwKQorICAgICAgICAsIGF0RnJvbnQodHJ1ZSkKKyAgICAgICAgLCBpbmRlbnQoMCkKKyAgICAgICAgLCBidW5kbGUoMCkgeworICAgIH0KKyAgICB+QnVmZmVyU3RhdGUoKSB7CisgICAgICAgIGZyZWUoYnVmZmVyKTsKKyAgICB9CisgICAgCisgICAgc3RhdHVzX3QgYXBwZW5kKGNvbnN0IGNoYXIqIHR4dCwgc2l6ZV90IGxlbikgeworICAgICAgICBpZiAoKGxlbitidWZmZXJQb3MpID4gYnVmZmVyU2l6ZSkgeworICAgICAgICAgICAgdm9pZCogYiA9IHJlYWxsb2MoYnVmZmVyLCAoKGxlbitidWZmZXJQb3MpKjMpLzIpOworICAgICAgICAgICAgaWYgKCFiKSByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICAgICAgYnVmZmVyID0gKGNoYXIqKWI7CisgICAgICAgIH0KKyAgICAgICAgbWVtY3B5KGJ1ZmZlcitidWZmZXJQb3MsIHR4dCwgbGVuKTsKKyAgICAgICAgYnVmZmVyUG9zICs9IGxlbjsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICAKKyAgICB2b2lkIHJlc3RhcnQoKSB7CisgICAgICAgIGJ1ZmZlclBvcyA9IDA7CisgICAgICAgIGF0RnJvbnQgPSB0cnVlOworICAgICAgICBpZiAoYnVmZmVyU2l6ZSA+IDI1NikgeworICAgICAgICAgICAgdm9pZCogYiA9IHJlYWxsb2MoYnVmZmVyLCAyNTYpOworICAgICAgICAgICAgaWYgKGIpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIgPSAoY2hhciopYjsKKyAgICAgICAgICAgICAgICBidWZmZXJTaXplID0gMjU2OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIAorICAgIGNvbnN0IGludDMyX3Qgc2VxOworICAgIGNoYXIqIGJ1ZmZlcjsKKyAgICBzaXplX3QgYnVmZmVyUG9zOworICAgIHNpemVfdCBidWZmZXJTaXplOworICAgIGJvb2wgYXRGcm9udDsKKyAgICBpbnQzMl90IGluZGVudDsKKyAgICBpbnQzMl90IGJ1bmRsZTsKK307CisKK3N0cnVjdCBCdWZmZXJlZFRleHRPdXRwdXQ6OlRocmVhZFN0YXRlCit7CisgICAgVmVjdG9yPHNwPEJ1ZmZlcmVkVGV4dE91dHB1dDo6QnVmZmVyU3RhdGU+ID4gc3RhdGVzOworfTsKKworc3RhdGljIG11dGV4X3QgICAgICAgICAgZ011dGV4OworCitzdGF0aWMgdGhyZWFkX3N0b3JlX3QgICB0bHM7CisKK0J1ZmZlcmVkVGV4dE91dHB1dDo6VGhyZWFkU3RhdGUqIEJ1ZmZlcmVkVGV4dE91dHB1dDo6Z2V0VGhyZWFkU3RhdGUoKQoreworICAgIFRocmVhZFN0YXRlKiAgdHMgPSAoVGhyZWFkU3RhdGUqKSB0aHJlYWRfc3RvcmVfZ2V0KCAmdGxzICk7CisgICAgaWYgKHRzKSByZXR1cm4gdHM7CisgICAgdHMgPSBuZXcgVGhyZWFkU3RhdGU7CisgICAgdGhyZWFkX3N0b3JlX3NldCggJnRscywgdHMsIHRocmVhZERlc3RydWN0b3IgKTsKKyAgICByZXR1cm4gdHM7Cit9CisKK3ZvaWQgQnVmZmVyZWRUZXh0T3V0cHV0Ojp0aHJlYWREZXN0cnVjdG9yKHZvaWQgKnN0KQoreworICAgIGRlbGV0ZSAoKFRocmVhZFN0YXRlKilzdCk7Cit9CisKK3N0YXRpYyB2b2xhdGlsZSBpbnQzMl90IGdTZXF1ZW5jZSA9IDA7CisKK3N0YXRpYyB2b2xhdGlsZSBpbnQzMl90IGdGcmVlQnVmZmVySW5kZXggPSAtMTsKKworc3RhdGljIGludDMyX3QgYWxsb2NCdWZmZXJJbmRleCgpCit7CisgICAgaW50MzJfdCByZXMgPSAtMTsKKyAgICAKKyAgICBtdXRleF9sb2NrKCZnTXV0ZXgpOworICAgIAorICAgIGlmIChnRnJlZUJ1ZmZlckluZGV4ID49IDApIHsKKyAgICAgICAgcmVzID0gZ0ZyZWVCdWZmZXJJbmRleDsKKyAgICAgICAgZ0ZyZWVCdWZmZXJJbmRleCA9IGdUZXh0QnVmZmVyc1tyZXNdOworICAgICAgICBnVGV4dEJ1ZmZlcnMuZWRpdEl0ZW1BdChyZXMpID0gLTE7CisKKyAgICB9IGVsc2UgeworICAgICAgICByZXMgPSBnVGV4dEJ1ZmZlcnMuc2l6ZSgpOworICAgICAgICBnVGV4dEJ1ZmZlcnMuYWRkKC0xKTsKKyAgICB9CisKKyAgICBtdXRleF91bmxvY2soJmdNdXRleCk7CisgICAgCisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIHZvaWQgZnJlZUJ1ZmZlckluZGV4KGludDMyX3QgaWR4KQoreworICAgIG11dGV4X2xvY2soJmdNdXRleCk7CisgICAgZ1RleHRCdWZmZXJzLmVkaXRJdGVtQXQoaWR4KSA9IGdGcmVlQnVmZmVySW5kZXg7CisgICAgZ0ZyZWVCdWZmZXJJbmRleCA9IGlkeDsKKyAgICBtdXRleF91bmxvY2soJmdNdXRleCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitCdWZmZXJlZFRleHRPdXRwdXQ6OkJ1ZmZlcmVkVGV4dE91dHB1dCh1aW50MzJfdCBmbGFncykKKyAgICA6IG1GbGFncyhmbGFncykKKyAgICAsIG1TZXEoYW5kcm9pZF9hdG9taWNfaW5jKCZnU2VxdWVuY2UpKQorICAgICwgbUluZGV4KGFsbG9jQnVmZmVySW5kZXgoKSkKK3sKKyAgICBtR2xvYmFsU3RhdGUgPSBuZXcgQnVmZmVyU3RhdGUobVNlcSk7CisgICAgaWYgKG1HbG9iYWxTdGF0ZSkgbUdsb2JhbFN0YXRlLT5pbmNTdHJvbmcodGhpcyk7Cit9CisgICAgCitCdWZmZXJlZFRleHRPdXRwdXQ6On5CdWZmZXJlZFRleHRPdXRwdXQoKQoreworICAgIGlmIChtR2xvYmFsU3RhdGUpIG1HbG9iYWxTdGF0ZS0+ZGVjU3Ryb25nKHRoaXMpOworICAgIGZyZWVCdWZmZXJJbmRleChtSW5kZXgpOworfQorCitzdGF0dXNfdCBCdWZmZXJlZFRleHRPdXRwdXQ6OnByaW50KGNvbnN0IGNoYXIqIHR4dCwgc2l6ZV90IGxlbikKK3sKKyAgICAvL3ByaW50ZigiQnVmZmVyZWRUZXh0T3V0cHV0OiBwcmludGluZyAlZFxuIiwgbGVuKTsKKyAgICAKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIEJ1ZmZlclN0YXRlKiBiID0gZ2V0QnVmZmVyKCk7CisgICAgCisgICAgY29uc3QgY2hhciogY29uc3QgZW5kID0gdHh0K2xlbjsKKyAgICAKKyAgICBzdGF0dXNfdCBlcnI7CisKKyAgICB3aGlsZSAodHh0IDwgZW5kKSB7CisgICAgICAgIC8vIEZpbmQgdGhlIG5leHQgbGluZS4KKyAgICAgICAgY29uc3QgY2hhciogZmlyc3QgPSB0eHQ7CisgICAgICAgIHdoaWxlICh0eHQgPCBlbmQgJiYgKnR4dCAhPSAnXG4nKSB0eHQrKzsKKyAgICAgICAgCisgICAgICAgIC8vIEluY2x1ZGUgdGhpcyBhbmQgYWxsIGZvbGxvd2luZyBlbXB0eSBsaW5lcy4KKyAgICAgICAgd2hpbGUgKHR4dCA8IGVuZCAmJiAqdHh0ID09ICdcbicpIHR4dCsrOworICAgICAgICAKKyAgICAgICAgLy8gU3BlY2lhbCBjYXNlcyBmb3IgZmlyc3QgZGF0YSBvbiBhIGxpbmUuCisgICAgICAgIGlmIChiLT5hdEZyb250KSB7CisgICAgICAgICAgICBpZiAoYi0+aW5kZW50ID4gMCkgeworICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHN0YXJ0IG9mIGEgbGluZSwgYWRkIHRoZSBpbmRlbnQuCisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogcHJlZml4ID0gc3RyaW5nRm9ySW5kZW50KGItPmluZGVudCk7CisgICAgICAgICAgICAgICAgZXJyID0gYi0+YXBwZW5kKHByZWZpeCwgc3RybGVuKHByZWZpeCkpOworICAgICAgICAgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHJldHVybiBlcnI7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICB9IGVsc2UgaWYgKCoodHh0LTEpID09ICdcbicgJiYgIWItPmJ1bmRsZSkgeworICAgICAgICAgICAgICAgIC8vIEZhc3QgcGF0aDogaWYgd2UgYXJlIG5vdCBpbmRlbnRpbmcgb3IgYnVuZGxpbmcsIGFuZAorICAgICAgICAgICAgICAgIC8vIGhhdmUgYmVlbiBnaXZlbiBvbmUgb3IgbW9yZSBjb21wbGV0ZSBsaW5lcywganVzdCB3cml0ZQorICAgICAgICAgICAgICAgIC8vIHRoZW0gb3V0IHdpdGhvdXQgZ29pbmcgdGhyb3VnaCB0aGUgYnVmZmVyLgorICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIC8vIFNsdXJwIHVwIGFsbCBvZiB0aGUgbGluZXMuCisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbGFzdExpbmUgPSB0eHQrMTsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHh0IDwgZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgqdHh0KysgPT0gJ1xuJykgbGFzdExpbmUgPSB0eHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN0cnVjdCBpb3ZlYyB2ZWM7CisgICAgICAgICAgICAgICAgdmVjLmlvdl9iYXNlID0gKHZvaWQqKWZpcnN0OworICAgICAgICAgICAgICAgIHZlYy5pb3ZfbGVuID0gbGFzdExpbmUtZmlyc3Q7CisgICAgICAgICAgICAgICAgLy9wcmludGYoIldyaXRpbmcgJWQgYnl0ZXMgb2YgZGF0YSFcbiIsIHZlYy5pb3ZfbGVuKTsKKyAgICAgICAgICAgICAgICB3cml0ZUxpbmVzKHZlYywgMSk7CisgICAgICAgICAgICAgICAgdHh0ID0gbGFzdExpbmU7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIC8vIEFwcGVuZCB0aGUgbmV3IHRleHQgdG8gdGhlIGJ1ZmZlci4KKyAgICAgICAgZXJyID0gYi0+YXBwZW5kKGZpcnN0LCB0eHQtZmlyc3QpOworICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSByZXR1cm4gZXJyOworICAgICAgICBiLT5hdEZyb250ID0gKih0eHQtMSkgPT0gJ1xuJzsKKyAgICAgICAgCisgICAgICAgIC8vIElmIHdlIGhhdmUgZmluaXNoZWQgYSBsaW5lIGFuZCBhcmUgbm90IGJ1bmRsaW5nLCB3cml0ZQorICAgICAgICAvLyBpdCBvdXQuCisgICAgICAgIC8vcHJpbnRmKCJCdWZmZXIgaXMgbm93ICVkIGJ5dGVzXG4iLCBiLT5idWZmZXJQb3MpOworICAgICAgICBpZiAoYi0+YXRGcm9udCAmJiAhYi0+YnVuZGxlKSB7CisgICAgICAgICAgICBzdHJ1Y3QgaW92ZWMgdmVjOworICAgICAgICAgICAgdmVjLmlvdl9iYXNlID0gYi0+YnVmZmVyOworICAgICAgICAgICAgdmVjLmlvdl9sZW4gPSBiLT5idWZmZXJQb3M7CisgICAgICAgICAgICAvL3ByaW50ZigiV3JpdGluZyAlZCBieXRlcyBvZiBkYXRhIVxuIiwgdmVjLmlvdl9sZW4pOworICAgICAgICAgICAgd3JpdGVMaW5lcyh2ZWMsIDEpOworICAgICAgICAgICAgYi0+cmVzdGFydCgpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBCdWZmZXJlZFRleHRPdXRwdXQ6Om1vdmVJbmRlbnQoaW50IGRlbHRhKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgQnVmZmVyU3RhdGUqIGIgPSBnZXRCdWZmZXIoKTsKKyAgICBiLT5pbmRlbnQgKz0gZGVsdGE7CisgICAgaWYgKGItPmluZGVudCA8IDApIGItPmluZGVudCA9IDA7Cit9CisKK3ZvaWQgQnVmZmVyZWRUZXh0T3V0cHV0OjpwdXNoQnVuZGxlKCkKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIEJ1ZmZlclN0YXRlKiBiID0gZ2V0QnVmZmVyKCk7CisgICAgYi0+YnVuZGxlKys7Cit9CisKK3ZvaWQgQnVmZmVyZWRUZXh0T3V0cHV0Ojpwb3BCdW5kbGUoKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgQnVmZmVyU3RhdGUqIGIgPSBnZXRCdWZmZXIoKTsKKyAgICBiLT5idW5kbGUtLTsKKyAgICBMT0dfRkFUQUxfSUYoYi0+YnVuZGxlIDwgMCwKKyAgICAgICAgIlRleHRPdXRwdXQ6OnBvcEJ1bmRsZSgpIGNhbGxlZCBtb3JlIHRpbWVzIHRoYW4gcHVzaEJ1bmRsZSgpIik7CisgICAgaWYgKGItPmJ1bmRsZSA8IDApIGItPmJ1bmRsZSA9IDA7CisgICAgCisgICAgaWYgKGItPmJ1bmRsZSA9PSAwKSB7CisgICAgICAgIC8vIExhc3QgYnVuZGxlLCB3cml0ZSBvdXQgZGF0YSBpZiBpdCBpcyBjb21wbGV0ZS4gIElmIGl0IGlzIG5vdAorICAgICAgICAvLyBjb21wbGV0ZSwgZG9uJ3Qgd3JpdGUgdW50aWwgdGhlIGxhc3QgbGluZSBpcyBkb25lLi4uIHRoaXMgbWF5CisgICAgICAgIC8vIG9yIG1heSBub3QgYmUgdGhlIHdyaXRlIHRoaW5nIHRvIGRvLCBidXQgaXQncyB0aGUgZWFzaWVzdC4KKyAgICAgICAgaWYgKGItPmJ1ZmZlclBvcyA+IDAgJiYgYi0+YXRGcm9udCkgeworICAgICAgICAgICAgc3RydWN0IGlvdmVjIHZlYzsKKyAgICAgICAgICAgIHZlYy5pb3ZfYmFzZSA9IGItPmJ1ZmZlcjsKKyAgICAgICAgICAgIHZlYy5pb3ZfbGVuID0gYi0+YnVmZmVyUG9zOworICAgICAgICAgICAgd3JpdGVMaW5lcyh2ZWMsIDEpOworICAgICAgICAgICAgYi0+cmVzdGFydCgpOworICAgICAgICB9CisgICAgfQorfQorCitCdWZmZXJlZFRleHRPdXRwdXQ6OkJ1ZmZlclN0YXRlKiBCdWZmZXJlZFRleHRPdXRwdXQ6OmdldEJ1ZmZlcigpIGNvbnN0Cit7CisgICAgaWYgKChtRmxhZ3MmTVVMVElUSFJFQURFRCkgIT0gMCkgeworICAgICAgICBUaHJlYWRTdGF0ZSogdHMgPSBnZXRUaHJlYWRTdGF0ZSgpOworICAgICAgICBpZiAodHMpIHsKKyAgICAgICAgICAgIHdoaWxlICh0cy0+c3RhdGVzLnNpemUoKSA8PSAoc2l6ZV90KW1JbmRleCkgdHMtPnN0YXRlcy5hZGQoTlVMTCk7CisgICAgICAgICAgICBCdWZmZXJTdGF0ZSogYnMgPSB0cy0+c3RhdGVzW21JbmRleF0uZ2V0KCk7CisgICAgICAgICAgICBpZiAoYnMgIT0gTlVMTCAmJiBicy0+c2VxID09IG1TZXEpIHJldHVybiBiczsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgdHMtPnN0YXRlcy5lZGl0SXRlbUF0KG1JbmRleCkgPSBuZXcgQnVmZmVyU3RhdGUobUluZGV4KTsKKyAgICAgICAgICAgIGJzID0gdHMtPnN0YXRlc1ttSW5kZXhdLmdldCgpOworICAgICAgICAgICAgaWYgKGJzICE9IE5VTEwpIHJldHVybiBiczsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICByZXR1cm4gbUdsb2JhbFN0YXRlOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9DYWxsU3RhY2suY3BwIGIvbGlicy91dGlscy9DYWxsU3RhY2suY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI2ZmIyMmEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0NhbGxTdGFjay5jcHAKQEAgLTAsMCArMSwzMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkNhbGxTdGFjayIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpZiBIQVZFX0RMQUREUgorI2luY2x1ZGUgPGRsZmNuLmg+CisjZW5kaWYKKworI2lmIEhBVkVfQ1hYQUJJCisjaW5jbHVkZSA8Y3h4YWJpLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPHVud2luZC5oPgorCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvQ2FsbFN0YWNrLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KK25hbWVzcGFjZSBhbmRyb2lkIHsKKworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgc2l6ZV90IGNvdW50OworICAgIHNpemVfdCBpZ25vcmU7CisgICAgY29uc3Qgdm9pZCoqIGFkZHJzOworfSBzdGFja19jcmF3bF9zdGF0ZV90OworCitzdGF0aWMKK19VbndpbmRfUmVhc29uX0NvZGUgdHJhY2VfZnVuY3Rpb24oX1Vud2luZF9Db250ZXh0ICpjb250ZXh0LCB2b2lkICphcmcpCit7CisgICAgc3RhY2tfY3Jhd2xfc3RhdGVfdCogc3RhdGUgPSAoc3RhY2tfY3Jhd2xfc3RhdGVfdCopYXJnOworICAgIGlmIChzdGF0ZS0+Y291bnQpIHsKKyAgICAgICAgdm9pZCogaXAgPSAodm9pZCopX1Vud2luZF9HZXRJUChjb250ZXh0KTsKKyAgICAgICAgaWYgKGlwKSB7CisgICAgICAgICAgICBpZiAoc3RhdGUtPmlnbm9yZSkgeworICAgICAgICAgICAgICAgIHN0YXRlLT5pZ25vcmUtLTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc3RhdGUtPmFkZHJzWzBdID0gaXA7IAorICAgICAgICAgICAgICAgIHN0YXRlLT5hZGRycysrOworICAgICAgICAgICAgICAgIHN0YXRlLT5jb3VudC0tOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBfVVJDX05PX1JFQVNPTjsKK30KKworc3RhdGljCitpbnQgYmFja3RyYWNlKGNvbnN0IHZvaWQqKiBhZGRycywgc2l6ZV90IGlnbm9yZSwgc2l6ZV90IHNpemUpCit7CisgICAgc3RhY2tfY3Jhd2xfc3RhdGVfdCBzdGF0ZTsKKyAgICBzdGF0ZS5jb3VudCA9IHNpemU7CisgICAgc3RhdGUuaWdub3JlID0gaWdub3JlOworICAgIHN0YXRlLmFkZHJzID0gYWRkcnM7CisgICAgX1Vud2luZF9CYWNrdHJhY2UodHJhY2VfZnVuY3Rpb24sICh2b2lkKikmc3RhdGUpOworICAgIHJldHVybiBzaXplIC0gc3RhdGUuY291bnQ7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIAorY29uc3QgY2hhciAqbG9va3VwX3N5bWJvbChjb25zdCB2b2lkKiBhZGRyLCB2b2lkICoqb2Zmc2V0LCBjaGFyKiBuYW1lLCBzaXplX3QgYnVmU2l6ZSkKK3sKKyNpZiBIQVZFX0RMQUREUgorICAgIERsX2luZm8gaW5mbzsKKyAgICBpZiAoZGxhZGRyKGFkZHIsICZpbmZvKSkgeworICAgICAgICAqb2Zmc2V0ID0gaW5mby5kbGlfc2FkZHI7CisgICAgICAgIHJldHVybiBpbmZvLmRsaV9zbmFtZTsKKyAgICB9CisjZW5kaWYKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIAoraW50MzJfdCBsaW51eF9nY2NfZGVtYW5nbGVyKGNvbnN0IGNoYXIgKm1hbmdsZWRfbmFtZSwgY2hhciAqdW5tYW5nbGVkX25hbWUsIHNpemVfdCBidWZmZXJzaXplKQoreworICAgIHNpemVfdCBvdXRfbGVuID0gMDsKKyNpZiBIQVZFX0NYWEFCSQorICAgIGludCBzdGF0dXMgPSAwOworICAgIGNoYXIgKmRlbWFuZ2xlZCA9IGFiaTo6X19jeGFfZGVtYW5nbGUobWFuZ2xlZF9uYW1lLCAwLCAmb3V0X2xlbiwgJnN0YXR1cyk7CisgICAgaWYgKHN0YXR1cyA9PSAwKSB7CisgICAgICAgIC8vIE9LCisgICAgICAgIGlmIChvdXRfbGVuIDwgYnVmZmVyc2l6ZSkgbWVtY3B5KHVubWFuZ2xlZF9uYW1lLCBkZW1hbmdsZWQsIG91dF9sZW4pOworICAgICAgICBlbHNlIG91dF9sZW4gPSAwOworICAgICAgICBmcmVlKGRlbWFuZ2xlZCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0X2xlbiA9IDA7CisgICAgfQorI2VuZGlmCisgICAgcmV0dXJuIG91dF9sZW47Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworY2xhc3MgTWFwSW5mbyB7CisgICAgc3RydWN0IG1hcGluZm8geworICAgICAgICBzdHJ1Y3QgbWFwaW5mbyAqbmV4dDsKKyAgICAgICAgdWludDY0X3Qgc3RhcnQ7CisgICAgICAgIHVpbnQ2NF90IGVuZDsKKyAgICAgICAgY2hhciBuYW1lW107CisgICAgfTsKKworICAgIGNvbnN0IGNoYXIgKm1hcF90b19uYW1lKHVpbnQ2NF90IHBjLCBjb25zdCBjaGFyKiBkZWYpIHsKKyAgICAgICAgbWFwaW5mbyogbWkgPSBnZXRNYXBJbmZvTGlzdCgpOworICAgICAgICB3aGlsZShtaSkgeworICAgICAgICAgICAgaWYgKChwYyA+PSBtaS0+c3RhcnQpICYmIChwYyA8IG1pLT5lbmQpKQorICAgICAgICAgICAgICAgIHJldHVybiBtaS0+bmFtZTsKKyAgICAgICAgICAgIG1pID0gbWktPm5leHQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZjsKKyAgICB9CisKKyAgICBtYXBpbmZvICpwYXJzZV9tYXBzX2xpbmUoY2hhciAqbGluZSkgeworICAgICAgICBtYXBpbmZvICptaTsKKyAgICAgICAgaW50IGxlbiA9IHN0cmxlbihsaW5lKTsKKyAgICAgICAgaWYgKGxlbiA8IDEpIHJldHVybiAwOworICAgICAgICBsaW5lWy0tbGVuXSA9IDA7CisgICAgICAgIGlmIChsZW4gPCA1MCkgcmV0dXJuIDA7CisgICAgICAgIGlmIChsaW5lWzIwXSAhPSAneCcpIHJldHVybiAwOworICAgICAgICBtaSA9IChtYXBpbmZvKiltYWxsb2Moc2l6ZW9mKG1hcGluZm8pICsgKGxlbiAtIDQ3KSk7CisgICAgICAgIGlmIChtaSA9PSAwKSByZXR1cm4gMDsKKyAgICAgICAgbWktPnN0YXJ0ID0gc3RydG91bGwobGluZSwgMCwgMTYpOworICAgICAgICBtaS0+ZW5kID0gc3RydG91bGwobGluZSArIDksIDAsIDE2KTsKKyAgICAgICAgbWktPm5leHQgPSAwOworICAgICAgICBzdHJjcHkobWktPm5hbWUsIGxpbmUgKyA0OSk7CisgICAgICAgIHJldHVybiBtaTsKKyAgICB9CisKKyAgICBtYXBpbmZvKiBnZXRNYXBJbmZvTGlzdCgpIHsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgaWYgKG1pbGlzdCA9PSAwKSB7CisgICAgICAgICAgICBjaGFyIGRhdGFbMTAyNF07CisgICAgICAgICAgICBGSUxFICpmcDsKKyAgICAgICAgICAgIHNwcmludGYoZGF0YSwgIi9wcm9jLyVkL21hcHMiLCBnZXRwaWQoKSk7CisgICAgICAgICAgICBmcCA9IGZvcGVuKGRhdGEsICJyIik7CisgICAgICAgICAgICBpZiAoZnApIHsKKyAgICAgICAgICAgICAgICB3aGlsZShmZ2V0cyhkYXRhLCAxMDI0LCBmcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFwaW5mbyAqbWkgPSBwYXJzZV9tYXBzX2xpbmUoZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIGlmKG1pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtaS0+bmV4dCA9IG1pbGlzdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1pbGlzdCA9IG1pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZjbG9zZShmcCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1pbGlzdDsKKyAgICB9CisgICAgbWFwaW5mbyogICAgbWlsaXN0OworICAgIE11dGV4ICAgICAgIG1Mb2NrOworICAgIHN0YXRpYyBNYXBJbmZvIHNNYXBJbmZvOworCitwdWJsaWM6CisgICAgTWFwSW5mbygpCisgICAgIDogbWlsaXN0KDApIHsKKyAgICB9CisKKyAgICB+TWFwSW5mbygpIHsKKyAgICAgICAgd2hpbGUgKG1pbGlzdCkgeworICAgICAgICAgICAgbWFwaW5mbyAqbmV4dCA9IG1pbGlzdC0+bmV4dDsKKyAgICAgICAgICAgIGZyZWUobWlsaXN0KTsKKyAgICAgICAgICAgIG1pbGlzdCA9IG5leHQ7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgc3RhdGljIGNvbnN0IGNoYXIgKm1hcEFkZHJlc3NUb05hbWUoY29uc3Qgdm9pZCogcGMsIGNvbnN0IGNoYXIqIGRlZikgeworICAgICAgICByZXR1cm4gc01hcEluZm8ubWFwX3RvX25hbWUoKHVpbnQ2NF90KXBjLCBkZWYpOworICAgIH0KKworfTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitNYXBJbmZvIE1hcEluZm86OnNNYXBJbmZvOworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK0NhbGxTdGFjazo6Q2FsbFN0YWNrKCkKKyAgICA6IG1Db3VudCgwKQoreworfQorCitDYWxsU3RhY2s6OkNhbGxTdGFjayhjb25zdCBDYWxsU3RhY2smIHJocykKKyAgICA6IG1Db3VudChyaHMubUNvdW50KQoreworICAgIGlmIChtQ291bnQpIHsKKyAgICAgICAgbWVtY3B5KG1TdGFjaywgcmhzLm1TdGFjaywgbUNvdW50KnNpemVvZih2b2lkKikpOworICAgIH0KK30KKworQ2FsbFN0YWNrOjp+Q2FsbFN0YWNrKCkKK3sKK30KKworQ2FsbFN0YWNrJiBDYWxsU3RhY2s6Om9wZXJhdG9yID0gKGNvbnN0IENhbGxTdGFjayYgcmhzKQoreworICAgIG1Db3VudCA9IHJocy5tQ291bnQ7CisgICAgaWYgKG1Db3VudCkgeworICAgICAgICBtZW1jcHkobVN0YWNrLCByaHMubVN0YWNrLCBtQ291bnQqc2l6ZW9mKHZvaWQqKSk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKK30KKworYm9vbCBDYWxsU3RhY2s6Om9wZXJhdG9yID09IChjb25zdCBDYWxsU3RhY2smIHJocykgY29uc3QgeworICAgIGlmIChtQ291bnQgIT0gcmhzLm1Db3VudCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiAhbUNvdW50IHx8IChtZW1jbXAobVN0YWNrLCByaHMubVN0YWNrLCBtQ291bnQqc2l6ZW9mKHZvaWQqKSkgPT0gMCk7Cit9CisKK2Jvb2wgQ2FsbFN0YWNrOjpvcGVyYXRvciAhPSAoY29uc3QgQ2FsbFN0YWNrJiByaHMpIGNvbnN0IHsKKyAgICByZXR1cm4gIW9wZXJhdG9yID09IChyaHMpOworfQorCitib29sIENhbGxTdGFjazo6b3BlcmF0b3IgPCAoY29uc3QgQ2FsbFN0YWNrJiByaHMpIGNvbnN0IHsKKyAgICBpZiAobUNvdW50ICE9IHJocy5tQ291bnQpCisgICAgICAgIHJldHVybiBtQ291bnQgPCByaHMubUNvdW50OworICAgIHJldHVybiBtZW1jbXAobVN0YWNrLCByaHMubVN0YWNrLCBtQ291bnQqc2l6ZW9mKHZvaWQqKSkgPCAwOworfQorCitib29sIENhbGxTdGFjazo6b3BlcmF0b3IgPj0gKGNvbnN0IENhbGxTdGFjayYgcmhzKSBjb25zdCB7CisgICAgcmV0dXJuICFvcGVyYXRvciA8IChyaHMpOworfQorCitib29sIENhbGxTdGFjazo6b3BlcmF0b3IgPiAoY29uc3QgQ2FsbFN0YWNrJiByaHMpIGNvbnN0IHsKKyAgICBpZiAobUNvdW50ICE9IHJocy5tQ291bnQpCisgICAgICAgIHJldHVybiBtQ291bnQgPiByaHMubUNvdW50OworICAgIHJldHVybiBtZW1jbXAobVN0YWNrLCByaHMubVN0YWNrLCBtQ291bnQqc2l6ZW9mKHZvaWQqKSkgPiAwOworfQorCitib29sIENhbGxTdGFjazo6b3BlcmF0b3IgPD0gKGNvbnN0IENhbGxTdGFjayYgcmhzKSBjb25zdCB7CisgICAgcmV0dXJuICFvcGVyYXRvciA+IChyaHMpOworfQorCitjb25zdCB2b2lkKiBDYWxsU3RhY2s6Om9wZXJhdG9yIFtdIChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgICBpZiAoaW5kZXggPj0gaW50KG1Db3VudCkpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBtU3RhY2tbaW5kZXhdOworfQorCisKK3ZvaWQgQ2FsbFN0YWNrOjpjbGVhcigpCit7CisgICAgbUNvdW50ID0gMDsKK30KKwordm9pZCBDYWxsU3RhY2s6OnVwZGF0ZShpbnQzMl90IGlnbm9yZURlcHRoLCBpbnQzMl90IG1heERlcHRoKQoreworICAgIGlmIChtYXhEZXB0aCA+IE1BWF9ERVBUSCkKKyAgICAgICAgbWF4RGVwdGggPSBNQVhfREVQVEg7CisgICAgbUNvdW50ID0gYmFja3RyYWNlKG1TdGFjaywgaWdub3JlRGVwdGgsIG1heERlcHRoKTsKK30KKworLy8gUmV0dXJuIHRoZSBzdGFjayBmcmFtZSBuYW1lIG9uIHRoZSBkZXNpZ25hdGVkIGxldmVsCitTdHJpbmc4IENhbGxTdGFjazo6dG9TdHJpbmdTaW5nbGVMZXZlbChjb25zdCBjaGFyKiBwcmVmaXgsIGludDMyX3QgbGV2ZWwpIGNvbnN0Cit7CisgICAgU3RyaW5nOCByZXM7CisgICAgY2hhciBuYW1lYnVmWzEwMjRdOworICAgIGNoYXIgdG1wWzI1Nl07CisgICAgY2hhciB0bXAxWzMyXTsKKyAgICBjaGFyIHRtcDJbMzJdOworICAgIHZvaWQgKm9mZnM7CisKKyAgICBjb25zdCB2b2lkKiBpcCA9IG1TdGFja1tsZXZlbF07CisgICAgaWYgKCFpcCkgcmV0dXJuIHJlczsKKworICAgIGlmIChwcmVmaXgpIHJlcy5hcHBlbmQocHJlZml4KTsKKyAgICBzbnByaW50Zih0bXAxLCAzMiwgIiMlMDJkICAiLCBsZXZlbCk7CisgICAgcmVzLmFwcGVuZCh0bXAxKTsKKworICAgIGNvbnN0IGNoYXIqIG5hbWUgPSBsb29rdXBfc3ltYm9sKGlwLCAmb2ZmcywgbmFtZWJ1Ziwgc2l6ZW9mKG5hbWVidWYpKTsKKyAgICBpZiAobmFtZSkgeworICAgICAgICBpZiAobGludXhfZ2NjX2RlbWFuZ2xlcihuYW1lLCB0bXAsIDI1NikgIT0gMCkKKyAgICAgICAgICAgIG5hbWUgPSB0bXA7CisgICAgICAgIHNucHJpbnRmKHRtcDEsIDMyLCAiMHglcDogPCIsIGlwKTsKKyAgICAgICAgc25wcmludGYodG1wMiwgMzIsICI+KzB4JXAiLCBvZmZzKTsKKyAgICAgICAgcmVzLmFwcGVuZCh0bXAxKTsKKyAgICAgICAgcmVzLmFwcGVuZChuYW1lKTsKKyAgICAgICAgcmVzLmFwcGVuZCh0bXAyKTsKKyAgICB9IGVsc2UgeyAKKyAgICAgICAgbmFtZSA9IE1hcEluZm86Om1hcEFkZHJlc3NUb05hbWUoaXAsICI8dW5rbm93bj4iKTsKKyAgICAgICAgc25wcmludGYodG1wLCAyNTYsICJwYyAlcCAgJXMiLCBpcCwgbmFtZSk7CisgICAgICAgIHJlcy5hcHBlbmQodG1wKTsKKyAgICB9CisgICAgcmVzLmFwcGVuZCgiXG4iKTsKKworICAgIHJldHVybiByZXM7Cit9CisKKy8vIER1bXAgYSBzdGFjayB0cmFjZSB0byB0aGUgbG9nCit2b2lkIENhbGxTdGFjazo6ZHVtcChjb25zdCBjaGFyKiBwcmVmaXgpIGNvbnN0Cit7CisgICAgLyogCisgICAgICogU2VuZGluZyBhIHNpbmdsZSBsb25nIGxvZyBtYXkgYmUgdHJ1bmNhdGVkIHNpbmNlIHRoZSBzdGFjayBsZXZlbHMgY2FuCisgICAgICogZ2V0IHZlcnkgZGVlcC4gU28gd2UgcmVxdWVzdCBmdW5jdGlvbiBuYW1lcyBvZiBlYWNoIGZyYW1lIGluZGl2aWR1YWxseS4KKyAgICAgKi8KKyAgICBmb3IgKGludCBpPTA7IGk8aW50KG1Db3VudCk7IGkrKykgeworICAgICAgICBMT0dEKCIlcyIsIHRvU3RyaW5nU2luZ2xlTGV2ZWwocHJlZml4LCBpKS5zdHJpbmcoKSk7CisgICAgfQorfQorCisvLyBSZXR1cm4gYSBzdHJpbmcgKHBvc3NpYmx5IHZlcnkgbG9uZykgY29udGFpbmluZyB0aGUgY29tcGxldGUgc3RhY2sgdHJhY2UKK1N0cmluZzggQ2FsbFN0YWNrOjp0b1N0cmluZyhjb25zdCBjaGFyKiBwcmVmaXgpIGNvbnN0Cit7CisgICAgU3RyaW5nOCByZXM7CisKKyAgICBmb3IgKGludCBpPTA7IGk8aW50KG1Db3VudCk7IGkrKykgeworICAgICAgICByZXMuYXBwZW5kKHRvU3RyaW5nU2luZ2xlTGV2ZWwocHJlZml4LCBpKS5zdHJpbmcoKSk7CisgICAgfQorCisgICAgcmV0dXJuIHJlczsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9EZWJ1Zy5jcHAgYi9saWJzL3V0aWxzL0RlYnVnLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzk4OGVjCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9EZWJ1Zy5jcHAKQEAgLTAsMCArMSwzMTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKworI2luY2x1ZGUgPHV0aWxzL21pc2MuaD4KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8Y3R5cGUuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGNvbnN0IGNoYXIgaW5kZW50U3RyW10gPQorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7CisKK2NvbnN0IGNoYXIqIHN0cmluZ0ZvckluZGVudChpbnQzMl90IGluZGVudExldmVsKQoreworICAgIHNzaXplX3Qgb2ZmID0gc2l6ZW9mKGluZGVudFN0ciktMS0oaW5kZW50TGV2ZWwqMik7CisgICAgcmV0dXJuIGluZGVudFN0ciArIChvZmYgPCAwID8gMCA6IG9mZik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBkZWZhdWx0UHJpbnRGdW5jKHZvaWQqIGNvb2tpZSwgY29uc3QgY2hhciogdHh0KQoreworICAgIHByaW50ZigiJXMiLCB0eHQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGlubGluZSBpbnQgaXNpZGVudChpbnQgYykKK3sKKyAgICByZXR1cm4gaXNhbG51bShjKSB8fCBjID09ICdfJzsKK30KKworc3RhdGljIGlubGluZSBib29sIGlzYXNjaWl0eXBlKGNoYXIgYykKK3sKKyAgICBpZiggYyA+PSAnICcgJiYgYyA8IDEyNyAmJiBjICE9ICdcJycgJiYgYyAhPSAnXFwnICkgcmV0dXJuIHRydWU7CisgICAgcmV0dXJuIGZhbHNlOworfQorCitzdGF0aWMgaW5saW5lIGNoYXIgbWFrZWhleGRpZ2l0KHVpbnQzMl90IHZhbCkKK3sKKyAgICByZXR1cm4gIjAxMjM0NTY3ODlhYmNkZWYiW3ZhbCYweEZdOworfQorCitzdGF0aWMgY2hhciogYXBwZW5kaGV4bnVtKHVpbnQzMl90IHZhbCwgY2hhciogb3V0KQoreworICAgIGZvciggaW50MzJfdCBpPTI4OyBpPj0wOyBpLT00ICkgeworICAgICAgICAqb3V0KysgPSBtYWtlaGV4ZGlnaXQoIHZhbD4+aSApOworICAgIH0KKyAgICAqb3V0ID0gMDsKKyAgICByZXR1cm4gb3V0OworfQorCitzdGF0aWMgaW5saW5lIGNoYXIgbWFrZXVwcGVyaGV4ZGlnaXQodWludDMyX3QgdmFsKQoreworICAgIHJldHVybiAiMDEyMzQ1Njc4OUFCQ0RFRiJbdmFsJjB4Rl07Cit9CisKK3N0YXRpYyBjaGFyKiBhcHBlbmR1cHBlcmhleG51bSh1aW50MzJfdCB2YWwsIGNoYXIqIG91dCkKK3sKKyAgICBmb3IoIGludDMyX3QgaT0yODsgaT49MDsgaS09NCApIHsKKyAgICAgICAgKm91dCsrID0gbWFrZXVwcGVyaGV4ZGlnaXQoIHZhbD4+aSApOworICAgIH0KKyAgICAqb3V0ID0gMDsKKyAgICByZXR1cm4gb3V0OworfQorCitzdGF0aWMgY2hhciogYXBwZW5kY2hhcm9ybnVtKGNoYXIgYywgY2hhciogb3V0LCBib29sIHNraXB6ZXJvID0gdHJ1ZSkKK3sKKyAgICBpZiAoc2tpcHplcm8gJiYgYyA9PSAwKSByZXR1cm4gb3V0OworCisgICAgaWYgKGlzYXNjaWl0eXBlKGMpKSB7CisgICAgICAgICpvdXQrKyA9IGM7CisgICAgICAgIHJldHVybiBvdXQ7CisgICAgfQorCisgICAgKm91dCsrID0gJ1xcJzsKKyAgICAqb3V0KysgPSAneCc7CisgICAgKm91dCsrID0gbWFrZWhleGRpZ2l0KGM+PjQpOworICAgICpvdXQrKyA9IG1ha2VoZXhkaWdpdChjKTsKKyAgICByZXR1cm4gb3V0OworfQorCitzdGF0aWMgY2hhciogdHlwZXRvc3RyaW5nKHVpbnQzMl90IHR5cGUsIGNoYXIqIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBmdWxsQ29udGV4dCA9IHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc3RyaWN0ID0gZmFsc2UpCit7CisgICAgY2hhciogcG9zID0gb3V0OworICAgIGNoYXIgY1s0XTsKKyAgICBjWzBdID0gKGNoYXIpKCh0eXBlPj4yNCkmMHhGRik7CisgICAgY1sxXSA9IChjaGFyKSgodHlwZT4+MTYpJjB4RkYpOworICAgIGNbMl0gPSAoY2hhcikoKHR5cGU+PjgpJjB4RkYpOworICAgIGNbM10gPSAoY2hhcikodHlwZSYweEZGKTsKKyAgICBib29sIHZhbGlkOworICAgIGlmKCAhc3RyaWN0ICkgeworICAgICAgICAvLyBub3cgZXZlbiBsZXNzIHN0cmljdCEKKyAgICAgICAgLy8gdmFsaWQgPSBpc2FzY2lpdHlwZShjWzNdKTsKKyAgICAgICAgdmFsaWQgPSB0cnVlOworICAgICAgICBpbnQzMl90IGkgPSAwOworICAgICAgICBib29sIHplcm8gPSB0cnVlOworICAgICAgICB3aGlsZSAodmFsaWQgJiYgaTwzKSB7CisgICAgICAgICAgICBpZiAoY1tpXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKCF6ZXJvKSB2YWxpZCA9IGZhbHNlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB6ZXJvID0gZmFsc2U7CisgICAgICAgICAgICAgICAgLy9pZiAoIWlzYXNjaWl0eXBlKGNbaV0pKSB2YWxpZCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIC8vIGlmIGFsbCB6ZXJvcywgbm90IGEgdmFsaWQgdHlwZSBjb2RlLgorICAgICAgICBpZiAoemVybykgdmFsaWQgPSBmYWxzZTsKKyAgICB9IGVsc2UgeworICAgICAgICB2YWxpZCA9IGlzaWRlbnQoY1szXSkgPyB0cnVlIDogZmFsc2U7CisgICAgICAgIGludDMyX3QgaSA9IDA7CisgICAgICAgIGJvb2wgemVybyA9IHRydWU7CisgICAgICAgIHdoaWxlICh2YWxpZCAmJiBpPDMpIHsKKyAgICAgICAgICAgIGlmIChjW2ldID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoIXplcm8pIHZhbGlkID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHplcm8gPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAoIWlzaWRlbnQoY1tpXSkpIHZhbGlkID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYoIHZhbGlkICYmICghZnVsbENvbnRleHQgfHwgY1swXSAhPSAnMCcgfHwgY1sxXSAhPSAneCcpICkgeworICAgICAgICBpZiggZnVsbENvbnRleHQgKSAqcG9zKysgPSAnXCcnOworICAgICAgICBwb3MgPSBhcHBlbmRjaGFyb3JudW0oY1swXSwgcG9zKTsKKyAgICAgICAgcG9zID0gYXBwZW5kY2hhcm9ybnVtKGNbMV0sIHBvcyk7CisgICAgICAgIHBvcyA9IGFwcGVuZGNoYXJvcm51bShjWzJdLCBwb3MpOworICAgICAgICBwb3MgPSBhcHBlbmRjaGFyb3JudW0oY1szXSwgcG9zKTsKKyAgICAgICAgaWYoIGZ1bGxDb250ZXh0ICkgKnBvcysrID0gJ1wnJzsKKyAgICAgICAgKnBvcyA9IDA7CisgICAgICAgIHJldHVybiBwb3M7CisgICAgfQorICAgIAorICAgIGlmKCBmdWxsQ29udGV4dCApIHsKKyAgICAgICAgKnBvcysrID0gJzAnOworICAgICAgICAqcG9zKysgPSAneCc7CisgICAgfQorICAgIHJldHVybiBhcHBlbmRoZXhudW0odHlwZSwgcG9zKTsKK30KKwordm9pZCBwcmludFR5cGVDb2RlKHVpbnQzMl90IHR5cGVDb2RlLCBkZWJ1Z1ByaW50RnVuYyBmdW5jLCB2b2lkKiBjb29raWUpCit7CisgICAgY2hhciBidWZmZXJbMzJdOworICAgIGNoYXIqIGVuZCA9IHR5cGV0b3N0cmluZyh0eXBlQ29kZSwgYnVmZmVyKTsKKyAgICAqZW5kID0gMDsKKyAgICBmdW5jID8gKCpmdW5jKShjb29raWUsIGJ1ZmZlcikgOiBkZWZhdWx0UHJpbnRGdW5jKGNvb2tpZSwgYnVmZmVyKTsKK30KKwordm9pZCBwcmludEhleERhdGEoaW50MzJfdCBpbmRlbnQsIGNvbnN0IHZvaWQgKmJ1Ziwgc2l6ZV90IGxlbmd0aCwKKyAgICBzaXplX3QgYnl0ZXNQZXJMaW5lLCBpbnQzMl90IHNpbmdsZUxpbmVCeXRlc0N1dG9mZiwKKyAgICBzaXplX3QgYWxpZ25tZW50LCBib29sIGNTdHlsZSwKKyAgICBkZWJ1Z1ByaW50RnVuYyBmdW5jLCB2b2lkKiBjb29raWUpCit7CisgICAgaWYgKGFsaWdubWVudCA9PSAwKSB7CisgICAgICAgIGlmIChieXRlc1BlckxpbmUgPj0gMTYpIGFsaWdubWVudCA9IDQ7CisgICAgICAgIGVsc2UgaWYgKGJ5dGVzUGVyTGluZSA+PSA4KSBhbGlnbm1lbnQgPSAyOworICAgICAgICBlbHNlIGFsaWdubWVudCA9IDE7CisgICAgfQorICAgIGlmIChmdW5jID09IE5VTEwpIGZ1bmMgPSBkZWZhdWx0UHJpbnRGdW5jOworCisgICAgc2l6ZV90IG9mZnNldDsKKyAgICAKKyAgICB1bnNpZ25lZCBjaGFyICpwb3MgPSAodW5zaWduZWQgY2hhciAqKWJ1ZjsKKyAgICAKKyAgICBpZiAocG9zID09IE5VTEwpIHsKKyAgICAgICAgaWYgKHNpbmdsZUxpbmVCeXRlc0N1dG9mZiA8IDApIGZ1bmMoY29va2llLCAiXG4iKTsKKyAgICAgICAgZnVuYyhjb29raWUsICIoTlVMTCkiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAKKyAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgaWYgKHNpbmdsZUxpbmVCeXRlc0N1dG9mZiA8IDApIGZ1bmMoY29va2llLCAiXG4iKTsKKyAgICAgICAgZnVuYyhjb29raWUsICIoZW1wdHkpIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgCisgICAgaWYgKChpbnQzMl90KWxlbmd0aCA8IDApIHsKKyAgICAgICAgaWYgKHNpbmdsZUxpbmVCeXRlc0N1dG9mZiA8IDApIGZ1bmMoY29va2llLCAiXG4iKTsKKyAgICAgICAgY2hhciBidWZbNjRdOworICAgICAgICBzcHJpbnRmKGJ1ZiwgIihiYWQgbGVuZ3RoOiAlZCkiLCBsZW5ndGgpOworICAgICAgICBmdW5jKGNvb2tpZSwgYnVmKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAKKyAgICBjaGFyIGJ1ZmZlclsyNTZdOworICAgIHN0YXRpYyBjb25zdCBzaXplX3QgbWF4Qnl0ZXNQZXJMaW5lID0gKHNpemVvZihidWZmZXIpLTEtMTEtNCkvKDMrMSk7CisgICAgCisgICAgaWYgKGJ5dGVzUGVyTGluZSA+IG1heEJ5dGVzUGVyTGluZSkgYnl0ZXNQZXJMaW5lID0gbWF4Qnl0ZXNQZXJMaW5lOworICAgIAorICAgIGNvbnN0IGJvb2wgb25lTGluZSA9IChpbnQzMl90KWxlbmd0aCA8PSBzaW5nbGVMaW5lQnl0ZXNDdXRvZmY7CisgICAgYm9vbCBuZXdMaW5lID0gZmFsc2U7CisgICAgaWYgKGNTdHlsZSkgeworICAgICAgICBpbmRlbnQrKzsKKyAgICAgICAgZnVuYyhjb29raWUsICJ7XG4iKTsKKyAgICAgICAgbmV3TGluZSA9IHRydWU7CisgICAgfSBlbHNlIGlmICghb25lTGluZSkgeworICAgICAgICBmdW5jKGNvb2tpZSwgIlxuIik7CisgICAgICAgIG5ld0xpbmUgPSB0cnVlOworICAgIH0KKyAgICAKKyAgICBmb3IgKG9mZnNldCA9IDA7IDsgb2Zmc2V0ICs9IGJ5dGVzUGVyTGluZSwgcG9zICs9IGJ5dGVzUGVyTGluZSkgeworICAgICAgICBsb25nIHJlbWFpbiA9IGxlbmd0aDsKKworICAgICAgICBjaGFyKiBjID0gYnVmZmVyOworICAgICAgICBpZiAoIW9uZUxpbmUgJiYgIWNTdHlsZSkgeworICAgICAgICAgICAgc3ByaW50ZihjLCAiMHglMDh4OiAiLCAoaW50KW9mZnNldCk7CisgICAgICAgICAgICBjICs9IDEyOworICAgICAgICB9CisKKyAgICAgICAgc2l6ZV90IGluZGV4OworICAgICAgICBzaXplX3Qgd29yZDsKKyAgICAgICAgCisgICAgICAgIGZvciAod29yZCA9IDA7IHdvcmQgPCBieXRlc1BlckxpbmU7ICkgeworCisjaWZkZWYgSEFWRV9MSVRUTEVfRU5ESUFOCisgICAgICAgICAgICBjb25zdCBzaXplX3Qgc3RhcnRJbmRleCA9IHdvcmQrKGFsaWdubWVudC0oYWxpZ25tZW50PzE6MCkpOworICAgICAgICAgICAgY29uc3Qgc3NpemVfdCBkaXIgPSAtMTsKKyNlbHNlCisgICAgICAgICAgICBjb25zdCBzaXplX3Qgc3RhcnRJbmRleCA9IHdvcmQ7CisgICAgICAgICAgICBjb25zdCBzc2l6ZV90IGRpciA9IDE7CisjZW5kaWYKKworICAgICAgICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgYWxpZ25tZW50IHx8IChhbGlnbm1lbnQgPT0gMCAmJiBpbmRleCA8IGJ5dGVzUGVyTGluZSk7IGluZGV4KyspIHsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGlmICghY1N0eWxlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PSAwICYmIHdvcmQgPiAwICYmIGFsaWdubWVudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSAnICc7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlbWFpbi0tID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciB2YWwgPSAqKHBvcytzdGFydEluZGV4KyhpbmRleCpkaXIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSBtYWtlaGV4ZGlnaXQodmFsPj40KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSBtYWtlaGV4ZGlnaXQodmFsKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghb25lTGluZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgKmMrKyA9ICcgJzsKKyAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSAnICc7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAocmVtYWluID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IDAgJiYgd29yZCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqYysrID0gJywnOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSAnICc7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICpjKysgPSAnMCc7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmMrKyA9ICd4JzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgdmFsID0gKihwb3Mrc3RhcnRJbmRleCsoaW5kZXgqZGlyKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAqYysrID0gbWFrZWhleGRpZ2l0KHZhbD4+NCk7CisgICAgICAgICAgICAgICAgICAgICAgICAqYysrID0gbWFrZWhleGRpZ2l0KHZhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZW1haW4tLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgd29yZCArPSBpbmRleDsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghY1N0eWxlKSB7CisgICAgICAgICAgICByZW1haW4gPSBsZW5ndGg7CisgICAgICAgICAgICAqYysrID0gJyAnOworICAgICAgICAgICAgKmMrKyA9ICdcJyc7CisgICAgICAgICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBieXRlc1BlckxpbmU7IGluZGV4KyspIHsKKworICAgICAgICAgICAgICAgIGlmIChyZW1haW4tLSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciB2YWwgPSBwb3NbaW5kZXhdOworICAgICAgICAgICAgICAgICAgICAqYysrID0gKHZhbCA+PSAnICcgJiYgdmFsIDwgMTI3KSA/IHZhbCA6ICcuJzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFvbmVMaW5lKSB7CisgICAgICAgICAgICAgICAgICAgICpjKysgPSAnICc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICAqYysrID0gJ1wnJzsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPiBieXRlc1BlckxpbmUpICpjKysgPSAnXG4nOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHJlbWFpbiA+IDApICpjKysgPSAnLCc7CisgICAgICAgICAgICAqYysrID0gJ1xuJzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZXdMaW5lICYmIGluZGVudCkgZnVuYyhjb29raWUsIHN0cmluZ0ZvckluZGVudChpbmRlbnQpKTsKKyAgICAgICAgKmMgPSAwOworICAgICAgICBmdW5jKGNvb2tpZSwgYnVmZmVyKTsKKyAgICAgICAgbmV3TGluZSA9IHRydWU7CisgICAgICAgIAorICAgICAgICBpZiAobGVuZ3RoIDw9IGJ5dGVzUGVyTGluZSkgYnJlYWs7CisgICAgICAgIGxlbmd0aCAtPSBieXRlc1BlckxpbmU7CisgICAgfQorCisgICAgaWYgKGNTdHlsZSkgeworICAgICAgICBpZiAoaW5kZW50ID4gMCkgZnVuYyhjb29raWUsIHN0cmluZ0ZvckluZGVudChpbmRlbnQtMSkpOworICAgICAgICBmdW5jKGNvb2tpZSwgIn07Iik7CisgICAgfQorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL0ZpbGVNYXAuY3BwIGIvbGlicy91dGlscy9GaWxlTWFwLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWJhOWIyCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9GaWxlTWFwLmNwcApAQCAtMCwwICsxLDIyMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBTaGFyZWQgZmlsZSBtYXBwaW5nIGNsYXNzLgorLy8KKworI2RlZmluZSBMT0dfVEFHICJmaWxlbWFwIgorCisjaW5jbHVkZSA8dXRpbHMvRmlsZU1hcC5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworI2lmZGVmIEhBVkVfUE9TSVhfRklMRU1BUAorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPG1lbW9yeS5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisvKnN0YXRpYyovIGxvbmcgRmlsZU1hcDo6bVBhZ2VTaXplID0gLTE7CisKKworLyoKKyAqIENvbnN0cnVjdG9yLiAgQ3JlYXRlIGFuIGVtcHR5IG9iamVjdC4KKyAqLworRmlsZU1hcDo6RmlsZU1hcCh2b2lkKQorICAgIDogbVJlZkNvdW50KDEpLCBtRmlsZU5hbWUoTlVMTCksIG1CYXNlUHRyKE5VTEwpLCBtQmFzZUxlbmd0aCgwKSwKKyAgICAgIG1EYXRhUHRyKE5VTEwpLCBtRGF0YUxlbmd0aCgwKQoreworfQorCisvKgorICogRGVzdHJ1Y3Rvci4KKyAqLworRmlsZU1hcDo6fkZpbGVNYXAodm9pZCkKK3sKKyAgICBhc3NlcnQobVJlZkNvdW50ID09IDApOworCisgICAgLy9wcmludGYoIisrKyByZW1vdmluZyBGaWxlTWFwICVwICV1XG4iLCBtRGF0YVB0ciwgbURhdGFMZW5ndGgpOworCisgICAgbVJlZkNvdW50ID0gLTEwMDsgICAgICAgLy8gaGVscCBjYXRjaCBkb3VibGUtZnJlZQorICAgIGlmIChtRmlsZU5hbWUgIT0gTlVMTCkgeworICAgICAgICBmcmVlKG1GaWxlTmFtZSk7CisgICAgfQorI2lmZGVmIEhBVkVfUE9TSVhfRklMRU1BUCAgICAKKyAgICBpZiAobXVubWFwKG1CYXNlUHRyLCBtQmFzZUxlbmd0aCkgIT0gMCkgeworICAgICAgICBMT0dEKCJtdW5tYXAoJXAsICVkKSBmYWlsZWRcbiIsIG1CYXNlUHRyLCAoaW50KSBtQmFzZUxlbmd0aCk7CisgICAgfQorI2VuZGlmCisjaWZkZWYgSEFWRV9XSU4zMl9GSUxFTUFQCisgICAgaWYgKCBVbm1hcFZpZXdPZkZpbGUobUJhc2VQdHIpID09IDApIHsKKyAgICAgICAgTE9HRCgiVW5tYXBWaWV3T2ZGaWxlKCVwKSBmYWlsZWQsIGVycm9yID0gJWxkXG4iLCBtQmFzZVB0ciwgCisgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CisgICAgfQorICAgIENsb3NlSGFuZGxlKG1GaWxlTWFwcGluZyk7CisgICAgQ2xvc2VIYW5kbGUobUZpbGVIYW5kbGUpOworI2VuZGlmCit9CisKKworLyoKKyAqIENyZWF0ZSBhIG5ldyBtYXBwaW5nIG9uIGFuIG9wZW4gZmlsZS4KKyAqCisgKiBDbG9zaW5nIHRoZSBmaWxlIGRlc2NyaXB0b3IgZG9lcyBub3QgdW5tYXAgdGhlIHBhZ2VzLCBzbyB3ZSBkb24ndAorICogY2xhaW0gb3duZXJzaGlwIG9mIHRoZSBmZC4KKyAqCisgKiBSZXR1cm5zICJmYWxzZSIgb24gZmFpbHVyZS4KKyAqLworYm9vbCBGaWxlTWFwOjpjcmVhdGUoY29uc3QgY2hhciogb3JpZ0ZpbGVOYW1lLCBpbnQgZmQsIG9mZl90IG9mZnNldCwgc2l6ZV90IGxlbmd0aCwgYm9vbCByZWFkT25seSkKK3sKKyNpZmRlZiBIQVZFX1dJTjMyX0ZJTEVNQVAKKyAgICBpbnQgICAgIGFkanVzdDsKKyAgICBvZmZfdCAgIGFkak9mZnNldDsKKyAgICBzaXplX3QgIGFkakxlbmd0aDsKKworICAgIGlmIChtUGFnZVNpemUgPT0gLTEpIHsKKyAgICAgICAgU1lTVEVNX0lORk8gIHNpOworICAgICAgICAKKyAgICAgICAgR2V0U3lzdGVtSW5mbyggJnNpICk7CisgICAgICAgIG1QYWdlU2l6ZSA9IHNpLmR3QWxsb2NhdGlvbkdyYW51bGFyaXR5OworICAgIH0KKworICAgIERXT1JEICBwcm90ZWN0ID0gcmVhZE9ubHkgPyBQQUdFX1JFQURPTkxZIDogUEFHRV9SRUFEV1JJVEU7CisgICAgCisgICAgbUZpbGVIYW5kbGUgID0gKEhBTkRMRSkgX2dldF9vc2ZoYW5kbGUoZmQpOworICAgIG1GaWxlTWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nKCBtRmlsZUhhbmRsZSwgTlVMTCwgcHJvdGVjdCwgMCwgMCwgTlVMTCk7CisgICAgaWYgKG1GaWxlTWFwcGluZyA9PSBOVUxMKSB7CisgICAgICAgIExPR0UoIkNyZWF0ZUZpbGVNYXBwaW5nKCVwLCAlbHgpIGZhaWxlZCB3aXRoIGVycm9yICVsZFxuIiwKKyAgICAgICAgICAgICAgbUZpbGVIYW5kbGUsIHByb3RlY3QsIEdldExhc3RFcnJvcigpICk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgCisgICAgYWRqdXN0ICAgID0gb2Zmc2V0ICUgbVBhZ2VTaXplOworICAgIGFkak9mZnNldCA9IG9mZnNldCAtIGFkanVzdDsKKyAgICBhZGpMZW5ndGggPSBsZW5ndGggKyBhZGp1c3Q7CisgICAgCisgICAgbUJhc2VQdHIgPSBNYXBWaWV3T2ZGaWxlKCBtRmlsZU1hcHBpbmcsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZE9ubHkgPyBGSUxFX01BUF9SRUFEIDogRklMRV9NQVBfQUxMX0FDQ0VTUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRFdPUkQpKGFkak9mZnNldCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGpMZW5ndGggKTsKKyAgICBpZiAobUJhc2VQdHIgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCJNYXBWaWV3T2ZGaWxlKCVsZCwgJWxkKSBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsCisgICAgICAgICAgICAgIGFkak9mZnNldCwgYWRqTGVuZ3RoLCBHZXRMYXN0RXJyb3IoKSApOworICAgICAgICBDbG9zZUhhbmRsZShtRmlsZU1hcHBpbmcpOworICAgICAgICBtRmlsZU1hcHBpbmcgPSBJTlZBTElEX0hBTkRMRV9WQUxVRTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyNlbmRpZgorI2lmZGVmIEhBVkVfUE9TSVhfRklMRU1BUAorICAgIGludCAgICAgcHJvdCwgZmxhZ3MsIGFkanVzdDsKKyAgICBvZmZfdCAgIGFkak9mZnNldDsKKyAgICBzaXplX3QgIGFkakxlbmd0aDsKKworICAgIHZvaWQqIHB0cjsKKworICAgIGFzc2VydChtUmVmQ291bnQgPT0gMSk7CisgICAgYXNzZXJ0KGZkID49IDApOworICAgIGFzc2VydChvZmZzZXQgPj0gMCk7CisgICAgYXNzZXJ0KGxlbmd0aCA+IDApOworCisgICAgLyogaW5pdCBvbiBmaXJzdCB1c2UgKi8KKyAgICBpZiAobVBhZ2VTaXplID09IC0xKSB7CisjaWYgTk9UX1VTSU5HX0tMSUJDCisgICAgICAgIG1QYWdlU2l6ZSA9IHN5c2NvbmYoX1NDX1BBR0VTSVpFKTsKKyAgICAgICAgaWYgKG1QYWdlU2l6ZSA9PSAtMSkgeworICAgICAgICAgICAgTE9HRSgiY291bGQgbm90IGdldCBfU0NfUEFHRVNJWkVcbiIpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisjZWxzZQorICAgICAgICAvKiB0aGlzIGhvbGRzIGZvciBMaW51eCwgRGFyd2luLCBDeWd3aW4sIGFuZCBkb2Vzbid0IHBhaW4gdGhlIEFSTSAqLworICAgICAgICBtUGFnZVNpemUgPSA0MDk2OworI2VuZGlmCisgICAgfQorCisgICAgYWRqdXN0ICAgPSBvZmZzZXQgJSBtUGFnZVNpemU7Cit0cnlfYWdhaW46CisgICAgYWRqT2Zmc2V0ID0gb2Zmc2V0IC0gYWRqdXN0OworICAgIGFkakxlbmd0aCA9IGxlbmd0aCArIGFkanVzdDsKKworICAgIGZsYWdzID0gTUFQX1NIQVJFRDsKKyAgICBwcm90ID0gUFJPVF9SRUFEOworICAgIGlmICghcmVhZE9ubHkpCisgICAgICAgIHByb3QgfD0gUFJPVF9XUklURTsKKworICAgIHB0ciA9IG1tYXAoTlVMTCwgYWRqTGVuZ3RoLCBwcm90LCBmbGFncywgZmQsIGFkak9mZnNldCk7CisgICAgaWYgKHB0ciA9PSBNQVBfRkFJTEVEKSB7CisgICAgCS8vIEN5Z3dpbiBkb2VzIG5vdCBzZWVtIHRvIGxpa2UgZmlsZSBtYXBwaW5nIGZpbGVzIGZyb20gYW4gb2Zmc2V0LgorICAgIAkvLyBTbyBpZiB3ZSBmYWlsLCB0cnkgYWdhaW4gd2l0aCBvZmZzZXQgemVybworICAgIAlpZiAoYWRqT2Zmc2V0ID4gMCkgeworICAgIAkJYWRqdXN0ID0gb2Zmc2V0OworICAgIAkJZ290byB0cnlfYWdhaW47CisgICAgCX0KKyAgICAKKyAgICAgICAgTE9HRSgibW1hcCglbGQsJWxkKSBmYWlsZWQ6ICVzXG4iLAorICAgICAgICAgICAgKGxvbmcpIGFkak9mZnNldCwgKGxvbmcpIGFkakxlbmd0aCwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBtQmFzZVB0ciA9IHB0cjsKKyNlbmRpZiAvKiBIQVZFX1BPU0lYX0ZJTEVNQVAgKi8KKworICAgIG1GaWxlTmFtZSA9IG9yaWdGaWxlTmFtZSAhPSBOVUxMID8gc3RyZHVwKG9yaWdGaWxlTmFtZSkgOiBOVUxMOworICAgIG1CYXNlTGVuZ3RoID0gYWRqTGVuZ3RoOworICAgIG1EYXRhT2Zmc2V0ID0gb2Zmc2V0OworICAgIG1EYXRhUHRyID0gKGNoYXIqKSBtQmFzZVB0ciArIGFkanVzdDsKKyAgICBtRGF0YUxlbmd0aCA9IGxlbmd0aDsKKworICAgIGFzc2VydChtQmFzZVB0ciAhPSBOVUxMKTsKKworICAgIExPR1YoIk1BUDogYmFzZSAlcC8lZCBkYXRhICVwLyVkXG4iLAorICAgICAgICBtQmFzZVB0ciwgKGludCkgbUJhc2VMZW5ndGgsIG1EYXRhUHRyLCAoaW50KSBtRGF0YUxlbmd0aCk7CisKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIFByb3ZpZGUgZ3VpZGFuY2UgdG8gdGhlIHN5c3RlbS4KKyAqLworaW50IEZpbGVNYXA6OmFkdmlzZShNYXBBZHZpY2UgYWR2aWNlKQoreworI2lmIEhBVkVfTUFEVklTRQorICAgIGludCBjYywgc3lzQWR2aWNlOworCisgICAgc3dpdGNoIChhZHZpY2UpIHsKKyAgICAgICAgY2FzZSBOT1JNQUw6ICAgICAgICBzeXNBZHZpY2UgPSBNQURWX05PUk1BTDsgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFJBTkRPTTogICAgICAgIHN5c0FkdmljZSA9IE1BRFZfUkFORE9NOyAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU0VRVUVOVElBTDogICAgc3lzQWR2aWNlID0gTUFEVl9TRVFVRU5USUFMOyAgICBicmVhazsKKyAgICAgICAgY2FzZSBXSUxMTkVFRDogICAgICBzeXNBZHZpY2UgPSBNQURWX1dJTExORUVEOyAgICAgIGJyZWFrOworICAgICAgICBjYXNlIERPTlRORUVEOiAgICAgIHN5c0FkdmljZSA9IE1BRFZfRE9OVE5FRUQ7ICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0KGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgY2MgPSBtYWR2aXNlKG1CYXNlUHRyLCBtQmFzZUxlbmd0aCwgc3lzQWR2aWNlKTsKKyAgICBpZiAoY2MgIT0gMCkKKyAgICAgICAgTE9HVygibWFkdmlzZSglZCkgZmFpbGVkOiAlc1xuIiwgc3lzQWR2aWNlLCBzdHJlcnJvcihlcnJubykpOworICAgIHJldHVybiBjYzsKKyNlbHNlCisJcmV0dXJuIC0xOworI2VuZGlmIC8vIEhBVkVfTUFEVklTRQorfQpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9JRGF0YUNvbm5lY3Rpb24uY3BwIGIvbGlicy91dGlscy9JRGF0YUNvbm5lY3Rpb24uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ZDQ5YWEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0lEYXRhQ29ubmVjdGlvbi5jcHAKQEAgLTAsMCArMSw4OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorCisjaW5jbHVkZSA8dXRpbHMvSURhdGFDb25uZWN0aW9uLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2VudW0KK3sKKyAgICBDT05ORUNUX1RSQU5TQUNUSU9OID0gSUJpbmRlcjo6RklSU1RfQ0FMTF9UUkFOU0FDVElPTiwKKyAgICBESVNDT05ORUNUX1RSQU5TQUNUSU9OID0gSUJpbmRlcjo6RklSU1RfQ0FMTF9UUkFOU0FDVElPTiArIDEKK307CisKK2NsYXNzIEJwRGF0YUNvbm5lY3Rpb24gOiBwdWJsaWMgQnBJbnRlcmZhY2U8SURhdGFDb25uZWN0aW9uPgoreworcHVibGljOgorICAgIEJwRGF0YUNvbm5lY3Rpb246OkJwRGF0YUNvbm5lY3Rpb24oY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SURhdGFDb25uZWN0aW9uPihpbXBsKQorICAgIHsKKyAgICB9CisKKwl2aXJ0dWFsIHZvaWQgY29ubmVjdCgpCisJeworCQlQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJRGF0YUNvbm5lY3Rpb246OmRlc2NyaXB0b3IoKSk7CisJCXJlbW90ZSgpLT50cmFuc2FjdChDT05ORUNUX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworCX0KKwkKKwl2aXJ0dWFsIHZvaWQgZGlzY29ubmVjdCgpCisJeworCQlQYXJjZWwgZGF0YSwgcmVwbHk7CisJCXJlbW90ZSgpLT50cmFuc2FjdChESVNDT05ORUNUX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworCX0KK307CisKK0lNUExFTUVOVF9NRVRBX0lOVEVSRkFDRShEYXRhQ29ubmVjdGlvbiwgImFuZHJvaWQudXRpbHMuSURhdGFDb25uZWN0aW9uIik7CisKKyNkZWZpbmUgQ0hFQ0tfSU5URVJGQUNFKGludGVyZmFjZSwgZGF0YSwgcmVwbHkpIFwKKyAgICAgICAgZG8geyBpZiAoIWRhdGEuZW5mb3JjZUludGVyZmFjZShpbnRlcmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSkpIHsgXAorICAgICAgICAgICAgTE9HVygiQ2FsbCBpbmNvcnJlY3RseSByb3V0ZWQgdG8gIiAjaW50ZXJmYWNlKTsgXAorICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOyBcCisgICAgICAgIH0gfSB3aGlsZSAoMCkKKworc3RhdHVzX3QgQm5EYXRhQ29ubmVjdGlvbjo6b25UcmFuc2FjdCh1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIHN3aXRjaChjb2RlKQorICAgIHsKKwkJY2FzZSBDT05ORUNUX1RSQU5TQUNUSU9OOgorCQl7ICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElEYXRhQ29ubmVjdGlvbiwgZGF0YSwgcmVwbHkpOworCQkJY29ubmVjdCgpOworCQkJcmV0dXJuIE5PX0VSUk9SOworCQl9ICAgIAorCQkKKwkJY2FzZSBESVNDT05ORUNUX1RSQU5TQUNUSU9OOgorCQl7ICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElEYXRhQ29ubmVjdGlvbiwgZGF0YSwgcmVwbHkpOworCQkJZGlzY29ubmVjdCgpOworCQkJcmV0dXJuIE5PX0VSUk9SOworCQl9CisgICAgICAgCisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gQkJpbmRlcjo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9JSW50ZXJmYWNlLmNwcCBiL2xpYnMvdXRpbHMvSUludGVyZmFjZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmVhODE3OAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvSUludGVyZmFjZS5jcHAKQEAgLTAsMCArMSwzNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDx1dGlscy9JSW50ZXJmYWNlLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3NwPElCaW5kZXI+IElJbnRlcmZhY2U6OmFzQmluZGVyKCkKK3sKKyAgICByZXR1cm4gdGhpcyA/IG9uQXNCaW5kZXIoKSA6IE5VTEw7Cit9CisKK3NwPGNvbnN0IElCaW5kZXI+IElJbnRlcmZhY2U6OmFzQmluZGVyKCkgY29uc3QKK3sKKyAgICByZXR1cm4gdGhpcyA/IGNvbnN0X2Nhc3Q8SUludGVyZmFjZSo+KHRoaXMpLT5vbkFzQmluZGVyKCkgOiBOVUxMOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvSU1lbW9yeS5jcHAgYi9saWJzL3V0aWxzL0lNZW1vcnkuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyOWJjMmIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0lNZW1vcnkuY3BwCkBAIC0wLDAgKzEsNDg2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJJTWVtb3J5IgorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL21tYW4uaD4KKworI2luY2x1ZGUgPHV0aWxzL0lNZW1vcnkuaD4KKyNpbmNsdWRlIDx1dGlscy9LZXllZFZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9QYXJjZWwuaD4KKyNpbmNsdWRlIDx1dGlscy9DYWxsU3RhY2suaD4KKworI2RlZmluZSBWRVJCT1NFICAgMAorCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgSGVhcENhY2hlIDogcHVibGljIElCaW5kZXI6OkRlYXRoUmVjaXBpZW50Cit7CitwdWJsaWM6CisgICAgSGVhcENhY2hlKCk7CisgICAgdmlydHVhbCB+SGVhcENhY2hlKCk7CisgICAgCisgICAgdmlydHVhbCB2b2lkIGJpbmRlckRpZWQoY29uc3Qgd3A8SUJpbmRlcj4mIHdobyk7CisKKyAgICBzcDxJTWVtb3J5SGVhcD4gZmluZF9oZWFwKGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIpOyAKKyAgICB2b2lkIHBpbl9oZWFwKGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIpOyAKKyAgICB2b2lkIGZyZWVfaGVhcChjb25zdCBzcDxJQmluZGVyPiYgYmluZGVyKTsgCisgICAgc3A8SU1lbW9yeUhlYXA+IGdldF9oZWFwKGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIpOworICAgIHZvaWQgZHVtcF9oZWFwcygpOworCitwcml2YXRlOgorICAgIC8vIEZvciBJTWVtb3J5LmNwcAorICAgIHN0cnVjdCBoZWFwX2luZm9fdCB7CisgICAgICAgIHNwPElNZW1vcnlIZWFwPiBoZWFwOworICAgICAgICBpbnQzMl90ICAgICAgICAgY291bnQ7CisgICAgfTsKKworICAgIHZvaWQgZnJlZV9oZWFwKGNvbnN0IHdwPElCaW5kZXI+JiBiaW5kZXIpOyAKKworICAgIE11dGV4IG1IZWFwQ2FjaGVMb2NrOworICAgIEtleWVkVmVjdG9yPCB3cDxJQmluZGVyPiwgaGVhcF9pbmZvX3QgPiBtSGVhcENhY2hlOworfTsKKworc3RhdGljIHNwPEhlYXBDYWNoZT4gZ0hlYXBDYWNoZSA9IG5ldyBIZWFwQ2FjaGUoKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworZW51bSB7CisgICAgSEVBUF9JRCA9IElCaW5kZXI6OkZJUlNUX0NBTExfVFJBTlNBQ1RJT04KK307CisKK2NsYXNzIEJwTWVtb3J5SGVhcCA6IHB1YmxpYyBCcEludGVyZmFjZTxJTWVtb3J5SGVhcD4KK3sKK3B1YmxpYzoKKyAgICBCcE1lbW9yeUhlYXAoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpOworICAgIHZpcnR1YWwgfkJwTWVtb3J5SGVhcCgpOworCisgICAgdmlydHVhbCBpbnQgZ2V0SGVhcElEKCkgY29uc3Q7CisgICAgdmlydHVhbCB2b2lkKiBnZXRCYXNlKCkgY29uc3Q7CisgICAgdmlydHVhbCBzaXplX3QgZ2V0U2l6ZSgpIGNvbnN0OworICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0RmxhZ3MoKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBmcmllbmQgY2xhc3MgSU1lbW9yeTsKKyAgICBmcmllbmQgY2xhc3MgSGVhcENhY2hlOworICAgIAorICAgIC8vIGZvciBkZWJ1Z2dpbmcgaW4gdGhpcyBtb2R1bGUKKyAgICBzdGF0aWMgaW5saW5lIHNwPElNZW1vcnlIZWFwPiBmaW5kX2hlYXAoY29uc3Qgc3A8SUJpbmRlcj4mIGJpbmRlcikgeworICAgICAgICByZXR1cm4gZ0hlYXBDYWNoZS0+ZmluZF9oZWFwKGJpbmRlcik7CisgICAgfQorICAgIHN0YXRpYyBpbmxpbmUgdm9pZCBmcmVlX2hlYXAoY29uc3Qgc3A8SUJpbmRlcj4mIGJpbmRlcikgeworICAgICAgICBnSGVhcENhY2hlLT5mcmVlX2hlYXAoYmluZGVyKTsKKyAgICB9CisgICAgc3RhdGljIGlubGluZSBzcDxJTWVtb3J5SGVhcD4gZ2V0X2hlYXAoY29uc3Qgc3A8SUJpbmRlcj4mIGJpbmRlcikgeworICAgICAgICByZXR1cm4gZ0hlYXBDYWNoZS0+Z2V0X2hlYXAoYmluZGVyKTsKKyAgICB9CisgICAgc3RhdGljIGlubGluZSB2b2lkIGR1bXBfaGVhcHMoKSB7CisgICAgICAgIGdIZWFwQ2FjaGUtPmR1bXBfaGVhcHMoKTsgICAgICAgCisgICAgfQorICAgIHZvaWQgaW5saW5lIHBpbl9oZWFwKCkgY29uc3QgeworICAgICAgICBnSGVhcENhY2hlLT5waW5faGVhcChjb25zdF9jYXN0PEJwTWVtb3J5SGVhcCo+KHRoaXMpLT5hc0JpbmRlcigpKTsKKyAgICB9CisKKyAgICB2b2lkIGFzc2VydE1hcHBlZCgpIGNvbnN0OworICAgIHZvaWQgYXNzZXJ0UmVhbGx5TWFwcGVkKCkgY29uc3Q7CisgICAgdm9pZCBwaW5IZWFwKCkgY29uc3Q7CisKKyAgICBtdXRhYmxlIHZvbGF0aWxlIGludDMyX3QgbUhlYXBJZDsKKyAgICBtdXRhYmxlIHZvaWQqICAgICAgIG1CYXNlOworICAgIG11dGFibGUgc2l6ZV90ICAgICAgbVNpemU7CisgICAgbXV0YWJsZSB1aW50MzJfdCAgICBtRmxhZ3M7CisgICAgbXV0YWJsZSBib29sICAgICAgICBtUmVhbEhlYXA7CisgICAgbXV0YWJsZSBNdXRleCAgICAgICBtTG9jazsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworZW51bSB7CisgICAgR0VUX01FTU9SWSA9IElCaW5kZXI6OkZJUlNUX0NBTExfVFJBTlNBQ1RJT04KK307CisKK2NsYXNzIEJwTWVtb3J5IDogcHVibGljIEJwSW50ZXJmYWNlPElNZW1vcnk+Cit7CitwdWJsaWM6CisgICAgQnBNZW1vcnkoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpOworICAgIHZpcnR1YWwgfkJwTWVtb3J5KCk7CisgICAgdmlydHVhbCBzcDxJTWVtb3J5SGVhcD4gZ2V0TWVtb3J5KHNzaXplX3QqIG9mZnNldD0wLCBzaXplX3QqIHNpemU9MCkgY29uc3Q7CisgICAgCitwcml2YXRlOgorICAgIG11dGFibGUgc3A8SU1lbW9yeUhlYXA+IG1IZWFwOworICAgIG11dGFibGUgc3NpemVfdCBtT2Zmc2V0OworICAgIG11dGFibGUgc2l6ZV90IG1TaXplOworfTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordm9pZCogSU1lbW9yeTo6ZmFzdFBvaW50ZXIoY29uc3Qgc3A8SUJpbmRlcj4mIGJpbmRlciwgc3NpemVfdCBvZmZzZXQpIGNvbnN0Cit7CisgICAgc3A8SU1lbW9yeUhlYXA+IHJlYWxIZWFwID0gQnBNZW1vcnlIZWFwOjpnZXRfaGVhcChiaW5kZXIpOworICAgIHZvaWQqIGNvbnN0IGJhc2UgPSByZWFsSGVhcC0+YmFzZSgpOworICAgIGlmIChiYXNlID09IE1BUF9GQUlMRUQpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjaGFyKj4oYmFzZSkgKyBvZmZzZXQ7Cit9CisKK3ZvaWQqIElNZW1vcnk6OnBvaW50ZXIoKSBjb25zdCB7CisgICAgc3NpemVfdCBvZmZzZXQ7CisgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXAgPSBnZXRNZW1vcnkoJm9mZnNldCk7CisgICAgdm9pZCogY29uc3QgYmFzZSA9IGhlYXAhPTAgPyBoZWFwLT5iYXNlKCkgOiBNQVBfRkFJTEVEOworICAgIGlmIChiYXNlID09IE1BUF9GQUlMRUQpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjaGFyKj4oYmFzZSkgKyBvZmZzZXQ7Cit9CisKK3NpemVfdCBJTWVtb3J5OjpzaXplKCkgY29uc3QgeworICAgIHNpemVfdCBzaXplOworICAgIGdldE1lbW9yeShOVUxMLCAmc2l6ZSk7CisgICAgcmV0dXJuIHNpemU7Cit9CisKK3NzaXplX3QgSU1lbW9yeTo6b2Zmc2V0KCkgY29uc3QgeworICAgIHNzaXplX3Qgb2Zmc2V0OworICAgIGdldE1lbW9yeSgmb2Zmc2V0KTsKKyAgICByZXR1cm4gb2Zmc2V0OworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitCcE1lbW9yeTo6QnBNZW1vcnkoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgOiBCcEludGVyZmFjZTxJTWVtb3J5PihpbXBsKSwgbU9mZnNldCgwKSwgbVNpemUoMCkKK3sKK30KKworQnBNZW1vcnk6On5CcE1lbW9yeSgpCit7Cit9CisKK3NwPElNZW1vcnlIZWFwPiBCcE1lbW9yeTo6Z2V0TWVtb3J5KHNzaXplX3QqIG9mZnNldCwgc2l6ZV90KiBzaXplKSBjb25zdAoreworICAgIGlmIChtSGVhcCA9PSAwKSB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElNZW1vcnk6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGlmIChyZW1vdGUoKS0+dHJhbnNhY3QoR0VUX01FTU9SWSwgZGF0YSwgJnJlcGx5KSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgc3A8SUJpbmRlcj4gaGVhcCA9IHJlcGx5LnJlYWRTdHJvbmdCaW5kZXIoKTsKKyAgICAgICAgICAgIHNzaXplX3QgbyA9IHJlcGx5LnJlYWRJbnQzMigpOworICAgICAgICAgICAgc2l6ZV90IHMgPSByZXBseS5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIGlmIChoZWFwICE9IDApIHsKKyAgICAgICAgICAgICAgICBtSGVhcCA9IGludGVyZmFjZV9jYXN0PElNZW1vcnlIZWFwPihoZWFwKTsKKyAgICAgICAgICAgICAgICBpZiAobUhlYXAgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBtT2Zmc2V0ID0gbzsKKyAgICAgICAgICAgICAgICAgICAgbVNpemUgPSBzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAob2Zmc2V0KSAqb2Zmc2V0ID0gbU9mZnNldDsKKyAgICBpZiAoc2l6ZSkgKnNpemUgPSBtU2l6ZTsKKyAgICByZXR1cm4gbUhlYXA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoTWVtb3J5LCAiYW5kcm9pZC51dGlscy5JTWVtb3J5Iik7CisKKyNkZWZpbmUgQ0hFQ0tfSU5URVJGQUNFKGludGVyZmFjZSwgZGF0YSwgcmVwbHkpIFwKKyAgICAgICAgZG8geyBpZiAoIWRhdGEuZW5mb3JjZUludGVyZmFjZShpbnRlcmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSkpIHsgXAorICAgICAgICAgICAgTE9HVygiQ2FsbCBpbmNvcnJlY3RseSByb3V0ZWQgdG8gIiAjaW50ZXJmYWNlKTsgXAorICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOyBcCisgICAgICAgIH0gfSB3aGlsZSAoMCkKKworc3RhdHVzX3QgQm5NZW1vcnk6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIEdFVF9NRU1PUlk6IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJTWVtb3J5LCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBzc2l6ZV90IG9mZnNldDsKKyAgICAgICAgICAgIHNpemVfdCBzaXplOworICAgICAgICAgICAgcmVwbHktPndyaXRlU3Ryb25nQmluZGVyKCBnZXRNZW1vcnkoJm9mZnNldCwgJnNpemUpLT5hc0JpbmRlcigpICk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihvZmZzZXQpOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoc2l6ZSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gQkJpbmRlcjo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworICAgIH0KK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitCcE1lbW9yeUhlYXA6OkJwTWVtb3J5SGVhcChjb25zdCBzcDxJQmluZGVyPiYgaW1wbCkKKyAgICA6IEJwSW50ZXJmYWNlPElNZW1vcnlIZWFwPihpbXBsKSwKKyAgICAgICAgbUhlYXBJZCgtMSksIG1CYXNlKE1BUF9GQUlMRUQpLCBtU2l6ZSgwKSwgbUZsYWdzKDApLCBtUmVhbEhlYXAoZmFsc2UpCit7Cit9CisKK0JwTWVtb3J5SGVhcDo6fkJwTWVtb3J5SGVhcCgpIHsKKyAgICBpZiAobUhlYXBJZCAhPSAtMSkgeworICAgICAgICBjbG9zZShtSGVhcElkKTsKKyAgICAgICAgaWYgKG1SZWFsSGVhcCkgeworICAgICAgICAgICAgLy8gYnkgY29uc3RydWN0aW9uIHdlJ3JlIHRoZSBsYXN0IG9uZQorICAgICAgICAgICAgaWYgKG1CYXNlICE9IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgICAgICAgICBzcDxJQmluZGVyPiBiaW5kZXIgPSBjb25zdF9jYXN0PEJwTWVtb3J5SGVhcCo+KHRoaXMpLT5hc0JpbmRlcigpOworCisgICAgICAgICAgICAgICAgaWYgKFZFUkJPU0UpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HRCgiVU5NQVBQSU5HIGJpbmRlcj0lcCwgaGVhcD0lcCwgc2l6ZT0lZCwgZmQ9JWQiLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5kZXIuZ2V0KCksIHRoaXMsIG1TaXplLCBtSGVhcElkKTsKKyAgICAgICAgICAgICAgICAgICAgQ2FsbFN0YWNrIHN0YWNrOworICAgICAgICAgICAgICAgICAgICBzdGFjay51cGRhdGUoKTsKKyAgICAgICAgICAgICAgICAgICAgc3RhY2suZHVtcCgiY2FsbHN0YWNrIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgbXVubWFwKG1CYXNlLCBtU2l6ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyByZW1vdmUgZnJvbSBsaXN0IG9ubHkgaWYgaXQgd2FzIG1hcHBlZCBiZWZvcmUKKyAgICAgICAgICAgIHNwPElCaW5kZXI+IGJpbmRlciA9IGNvbnN0X2Nhc3Q8QnBNZW1vcnlIZWFwKj4odGhpcyktPmFzQmluZGVyKCk7CisgICAgICAgICAgICBmcmVlX2hlYXAoYmluZGVyKTsKKyAgICAgICAgfQorICAgIH0KK30KKwordm9pZCBCcE1lbW9yeUhlYXA6OmFzc2VydE1hcHBlZCgpIGNvbnN0Cit7CisgICAgaWYgKG1IZWFwSWQgPT0gLTEpIHsKKyAgICAgICAgc3A8SUJpbmRlcj4gYmluZGVyKGNvbnN0X2Nhc3Q8QnBNZW1vcnlIZWFwKj4odGhpcyktPmFzQmluZGVyKCkpOworICAgICAgICBzcDxCcE1lbW9yeUhlYXA+IGhlYXAoc3RhdGljX2Nhc3Q8QnBNZW1vcnlIZWFwKj4oZmluZF9oZWFwKGJpbmRlcikuZ2V0KCkpKTsKKyAgICAgICAgaGVhcC0+YXNzZXJ0UmVhbGx5TWFwcGVkKCk7CisgICAgICAgIGlmIChoZWFwLT5tQmFzZSAhPSBNQVBfRkFJTEVEKSB7CisgICAgICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgICAgICAgICAgaWYgKG1IZWFwSWQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBtQmFzZSAgID0gaGVhcC0+bUJhc2U7CisgICAgICAgICAgICAgICAgbVNpemUgICA9IGhlYXAtPm1TaXplOworICAgICAgICAgICAgICAgIGFuZHJvaWRfYXRvbWljX3dyaXRlKCBkdXAoIGhlYXAtPm1IZWFwSWQgKSwgJm1IZWFwSWQgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nCisgICAgICAgICAgICBmcmVlX2hlYXAoYmluZGVyKTsKKyAgICAgICAgfQorICAgIH0KK30KKwordm9pZCBCcE1lbW9yeUhlYXA6OmFzc2VydFJlYWxseU1hcHBlZCgpIGNvbnN0Cit7CisgICAgaWYgKG1IZWFwSWQgPT0gLTEpIHsKKworICAgICAgICAvLyByZW1vdGUgY2FsbCB3aXRob3V0IG1Mb2NrIGhlbGQsIHdvcnNlIGNhc2Ugc2NlbmFyaW8sIHdlIGVuZCB1cAorICAgICAgICAvLyBjYWxsaW5nIHRyYW5zYWN0KCkgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLCBidXQgdGhhdCdzIG5vdCBhIHByb2JsZW0sCisgICAgICAgIC8vIG9ubHkgbW1hcCBiZWxvdyBtdXN0IGJlIGluIHRoZSBjcml0aWNhbCBzZWN0aW9uLgorICAgICAgICAKKyAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICBkYXRhLndyaXRlSW50ZXJmYWNlVG9rZW4oSU1lbW9yeUhlYXA6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIHN0YXR1c190IGVyciA9IHJlbW90ZSgpLT50cmFuc2FjdChIRUFQX0lELCBkYXRhLCAmcmVwbHkpOworICAgICAgICBpbnQgcGFyY2VsX2ZkID0gcmVwbHkucmVhZEZpbGVEZXNjcmlwdG9yKCk7CisgICAgICAgIHNzaXplX3Qgc2l6ZSA9IHJlcGx5LnJlYWRJbnQzMigpOworICAgICAgICB1aW50MzJfdCBmbGFncyA9IHJlcGx5LnJlYWRJbnQzMigpOworCisgICAgICAgIExPR0VfSUYoZXJyLCAiYmluZGVyPSVwIHRyYW5zYWN0aW9uIGZhaWxlZCBmZD0lZCwgc2l6ZT0lZCwgZXJyPSVkICglcykiLAorICAgICAgICAgICAgICAgIGFzQmluZGVyKCkuZ2V0KCksIHBhcmNlbF9mZCwgc2l6ZSwgZXJyLCBzdHJlcnJvcigtZXJyKSk7CisKKyAgICAgICAgaW50IGZkID0gZHVwKCBwYXJjZWxfZmQgKTsKKyAgICAgICAgTE9HRV9JRihmZD09LTEsICJjYW5ub3QgZHVwIGZkPSVkLCBzaXplPSVkLCBlcnI9JWQgKCVzKSIsCisgICAgICAgICAgICAgICAgcGFyY2VsX2ZkLCBzaXplLCBlcnIsIHN0cmVycm9yKGVycm5vKSk7CisKKyAgICAgICAgaW50IGFjY2VzcyA9IFBST1RfUkVBRDsKKyAgICAgICAgaWYgKCEoZmxhZ3MgJiBSRUFEX09OTFkpKSB7CisgICAgICAgICAgICBhY2Nlc3MgfD0gUFJPVF9XUklURTsKKyAgICAgICAgfQorCisgICAgICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgICAgIGlmIChtSGVhcElkID09IC0xKSB7CisgICAgICAgICAgICBtUmVhbEhlYXAgPSB0cnVlOworICAgICAgICAgICAgbUJhc2UgPSBtbWFwKDAsIHNpemUsIGFjY2VzcywgTUFQX1NIQVJFRCwgZmQsIDApOworICAgICAgICAgICAgaWYgKG1CYXNlID09IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgICAgICAgICBMT0dFKCJjYW5ub3QgbWFwIEJwTWVtb3J5SGVhcCAoYmluZGVyPSVwKSwgc2l6ZT0lZCwgZmQ9JWQgKCVzKSIsCisgICAgICAgICAgICAgICAgICAgICAgICBhc0JpbmRlcigpLmdldCgpLCBzaXplLCBmZCwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgICAgICAgICBjbG9zZShmZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChmbGFncyAmIE1BUF9PTkNFKSB7CisgICAgICAgICAgICAgICAgICAgIC8vTE9HRCgicGlubmluZyBoZWFwIChiaW5kZXI9JXAsIHNpemU9JWQsIGZkPSVkIiwKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIGFzQmluZGVyKCkuZ2V0KCksIHNpemUsIGZkKTsKKyAgICAgICAgICAgICAgICAgICAgcGluX2hlYXAoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbVNpemUgPSBzaXplOworICAgICAgICAgICAgICAgIG1GbGFncyA9IGZsYWdzOworICAgICAgICAgICAgICAgIGFuZHJvaWRfYXRvbWljX3dyaXRlKGZkLCAmbUhlYXBJZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKK2ludCBCcE1lbW9yeUhlYXA6OmdldEhlYXBJRCgpIGNvbnN0IHsKKyAgICBhc3NlcnRNYXBwZWQoKTsKKyAgICByZXR1cm4gbUhlYXBJZDsKK30KKwordm9pZCogQnBNZW1vcnlIZWFwOjpnZXRCYXNlKCkgY29uc3QgeworICAgIGFzc2VydE1hcHBlZCgpOworICAgIHJldHVybiBtQmFzZTsKK30KKworc2l6ZV90IEJwTWVtb3J5SGVhcDo6Z2V0U2l6ZSgpIGNvbnN0IHsKKyAgICBhc3NlcnRNYXBwZWQoKTsKKyAgICByZXR1cm4gbVNpemU7Cit9CisKK3VpbnQzMl90IEJwTWVtb3J5SGVhcDo6Z2V0RmxhZ3MoKSBjb25zdCB7CisgICAgYXNzZXJ0TWFwcGVkKCk7CisgICAgcmV0dXJuIG1GbGFnczsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0lNUExFTUVOVF9NRVRBX0lOVEVSRkFDRShNZW1vcnlIZWFwLCAiYW5kcm9pZC51dGlscy5JTWVtb3J5SGVhcCIpOworCitzdGF0dXNfdCBCbk1lbW9yeUhlYXA6Om9uVHJhbnNhY3QoCisgICAgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgIGNhc2UgSEVBUF9JRDogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElNZW1vcnlIZWFwLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVGaWxlRGVzY3JpcHRvcihnZXRIZWFwSUQoKSk7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihnZXRTaXplKCkpOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIoZ2V0RmxhZ3MoKSk7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gQkJpbmRlcjo6b25UcmFuc2FjdChjb2RlLCBkYXRhLCByZXBseSwgZmxhZ3MpOworICAgIH0KK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitIZWFwQ2FjaGU6OkhlYXBDYWNoZSgpCisgICAgOiBEZWF0aFJlY2lwaWVudCgpCit7Cit9CisKK0hlYXBDYWNoZTo6fkhlYXBDYWNoZSgpCit7Cit9CisKK3ZvaWQgSGVhcENhY2hlOjpiaW5kZXJEaWVkKGNvbnN0IHdwPElCaW5kZXI+JiBiaW5kZXIpCit7CisgICAgLy9MT0dEKCJiaW5kZXJEaWVkIGJpbmRlcj0lcCIsIGJpbmRlci51bnNhZmVfZ2V0KCkpOworICAgIGZyZWVfaGVhcChiaW5kZXIpOyAKK30KKworc3A8SU1lbW9yeUhlYXA+IEhlYXBDYWNoZTo6ZmluZF9oZWFwKGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIpIAoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtSGVhcENhY2hlTG9jayk7CisgICAgc3NpemVfdCBpID0gbUhlYXBDYWNoZS5pbmRleE9mS2V5KGJpbmRlcik7CisgICAgaWYgKGk+PTApIHsKKyAgICAgICAgaGVhcF9pbmZvX3QmIGluZm8gPSBtSGVhcENhY2hlLmVkaXRWYWx1ZUF0KGkpOworICAgICAgICBMT0dEX0lGKFZFUkJPU0UsCisgICAgICAgICAgICAgICAgImZvdW5kIGJpbmRlcj0lcCwgaGVhcD0lcCwgc2l6ZT0lZCwgZmQ9JWQsIGNvdW50PSVkIiwgCisgICAgICAgICAgICAgICAgYmluZGVyLmdldCgpLCBpbmZvLmhlYXAuZ2V0KCksCisgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8QnBNZW1vcnlIZWFwKj4oaW5mby5oZWFwLmdldCgpKS0+bVNpemUsCisgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8QnBNZW1vcnlIZWFwKj4oaW5mby5oZWFwLmdldCgpKS0+bUhlYXBJZCwKKyAgICAgICAgICAgICAgICBpbmZvLmNvdW50KTsKKyAgICAgICAgYW5kcm9pZF9hdG9taWNfaW5jKCZpbmZvLmNvdW50KTsKKyAgICAgICAgcmV0dXJuIGluZm8uaGVhcDsKKyAgICB9IGVsc2UgeworICAgICAgICBoZWFwX2luZm9fdCBpbmZvOworICAgICAgICBpbmZvLmhlYXAgPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5SGVhcD4oYmluZGVyKTsKKyAgICAgICAgaW5mby5jb3VudCA9IDE7CisgICAgICAgIC8vTE9HRCgiYWRkaW5nIGJpbmRlcj0lcCwgaGVhcD0lcCwgY291bnQ9JWQiLAorICAgICAgICAvLyAgICAgIGJpbmRlci5nZXQoKSwgaW5mby5oZWFwLmdldCgpLCBpbmZvLmNvdW50KTsKKyAgICAgICAgbUhlYXBDYWNoZS5hZGQoYmluZGVyLCBpbmZvKTsKKyAgICAgICAgcmV0dXJuIGluZm8uaGVhcDsKKyAgICB9Cit9CisKK3ZvaWQgSGVhcENhY2hlOjpwaW5faGVhcChjb25zdCBzcDxJQmluZGVyPiYgYmluZGVyKSAKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUhlYXBDYWNoZUxvY2spOworICAgIHNzaXplX3QgaSA9IG1IZWFwQ2FjaGUuaW5kZXhPZktleShiaW5kZXIpOworICAgIGlmIChpPj0wKSB7CisgICAgICAgIGhlYXBfaW5mb190JiBpbmZvKG1IZWFwQ2FjaGUuZWRpdFZhbHVlQXQoaSkpOworICAgICAgICBhbmRyb2lkX2F0b21pY19pbmMoJmluZm8uY291bnQpOworICAgICAgICBiaW5kZXItPmxpbmtUb0RlYXRoKHRoaXMpOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR0UoInBpbl9oZWFwIGJpbmRlcj0lcCBub3QgZm91bmQhISEiLCBiaW5kZXIuZ2V0KCkpOworICAgIH0gICAgCit9CisKK3ZvaWQgSGVhcENhY2hlOjpmcmVlX2hlYXAoY29uc3Qgc3A8SUJpbmRlcj4mIGJpbmRlcikgIHsKKyAgICBmcmVlX2hlYXAoIHdwPElCaW5kZXI+KGJpbmRlcikgKTsKK30KKwordm9pZCBIZWFwQ2FjaGU6OmZyZWVfaGVhcChjb25zdCB3cDxJQmluZGVyPiYgYmluZGVyKSAKK3sKKyAgICBzcDxJTWVtb3J5SGVhcD4gcmVsOworICAgIHsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1IZWFwQ2FjaGVMb2NrKTsKKyAgICAgICAgc3NpemVfdCBpID0gbUhlYXBDYWNoZS5pbmRleE9mS2V5KGJpbmRlcik7CisgICAgICAgIGlmIChpPj0wKSB7CisgICAgICAgICAgICBoZWFwX2luZm9fdCYgaW5mbyhtSGVhcENhY2hlLmVkaXRWYWx1ZUF0KGkpKTsKKyAgICAgICAgICAgIGludDMyX3QgYyA9IGFuZHJvaWRfYXRvbWljX2RlYygmaW5mby5jb3VudCk7CisgICAgICAgICAgICBpZiAoYyA9PSAxKSB7CisgICAgICAgICAgICAgICAgTE9HRF9JRihWRVJCT1NFLAorICAgICAgICAgICAgICAgICAgICAgICAgInJlbW92aW5nIGJpbmRlcj0lcCwgaGVhcD0lcCwgc2l6ZT0lZCwgZmQ9JWQsIGNvdW50PSVkIiwgCisgICAgICAgICAgICAgICAgICAgICAgICBiaW5kZXIudW5zYWZlX2dldCgpLCBpbmZvLmhlYXAuZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxCcE1lbW9yeUhlYXAqPihpbmZvLmhlYXAuZ2V0KCkpLT5tU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PEJwTWVtb3J5SGVhcCo+KGluZm8uaGVhcC5nZXQoKSktPm1IZWFwSWQsCisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmNvdW50KTsKKyAgICAgICAgICAgICAgICByZWwgPSBtSGVhcENhY2hlLnZhbHVlQXQoaSkuaGVhcDsKKyAgICAgICAgICAgICAgICBtSGVhcENhY2hlLnJlbW92ZUl0ZW1zQXQoaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJmcmVlX2hlYXAgYmluZGVyPSVwIG5vdCBmb3VuZCEhISIsIGJpbmRlci51bnNhZmVfZ2V0KCkpOworICAgICAgICB9CisgICAgfQorfQorCitzcDxJTWVtb3J5SGVhcD4gSGVhcENhY2hlOjpnZXRfaGVhcChjb25zdCBzcDxJQmluZGVyPiYgYmluZGVyKQoreworICAgIHNwPElNZW1vcnlIZWFwPiByZWFsSGVhcDsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUhlYXBDYWNoZUxvY2spOworICAgIHNzaXplX3QgaSA9IG1IZWFwQ2FjaGUuaW5kZXhPZktleShiaW5kZXIpOworICAgIGlmIChpPj0wKSAgIHJlYWxIZWFwID0gbUhlYXBDYWNoZS52YWx1ZUF0KGkpLmhlYXA7CisgICAgZWxzZSAgICAgICAgcmVhbEhlYXAgPSBpbnRlcmZhY2VfY2FzdDxJTWVtb3J5SGVhcD4oYmluZGVyKTsKKyAgICByZXR1cm4gcmVhbEhlYXA7Cit9CisKK3ZvaWQgSGVhcENhY2hlOjpkdW1wX2hlYXBzKCkgCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1IZWFwQ2FjaGVMb2NrKTsKKyAgICBpbnQgYyA9IG1IZWFwQ2FjaGUuc2l6ZSgpOworICAgIGZvciAoaW50IGk9MCA7IGk8YyA7IGkrKykgeworICAgICAgICBjb25zdCBoZWFwX2luZm9fdCYgaW5mbyA9IG1IZWFwQ2FjaGUudmFsdWVBdChpKTsKKyAgICAgICAgQnBNZW1vcnlIZWFwIGNvbnN0KiBoKHN0YXRpY19jYXN0PEJwTWVtb3J5SGVhcCBjb25zdCAqPihpbmZvLmhlYXAuZ2V0KCkpKTsKKyAgICAgICAgTE9HRCgiaGV5PSVwLCBoZWFwPSVwLCBjb3VudD0lZCwgKGZkPSVkLCBiYXNlPSVwLCBzaXplPSVkKSIsCisgICAgICAgICAgICAgICAgbUhlYXBDYWNoZS5rZXlBdChpKS51bnNhZmVfZ2V0KCksCisgICAgICAgICAgICAgICAgaW5mby5oZWFwLmdldCgpLCBpbmZvLmNvdW50LCAKKyAgICAgICAgICAgICAgICBoLT5tSGVhcElkLCBoLT5tQmFzZSwgaC0+bVNpemUpOworICAgIH0KK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL0lQQ1RocmVhZFN0YXRlLmNwcCBiL2xpYnMvdXRpbHMvSVBDVGhyZWFkU3RhdGUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0YWUxNDIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0lQQ1RocmVhZFN0YXRlLmNwcApAQCAtMCwwICsxLDEwMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKworI2luY2x1ZGUgPHV0aWxzL0JpbmRlci5oPgorI2luY2x1ZGUgPHV0aWxzL0JwQmluZGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKyNpbmNsdWRlIDx1dGlscy9UZXh0T3V0cHV0Lmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9iaW5kZXJfbW9kdWxlLmg+CisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9TdGF0aWMuaD4KKworI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorI2luY2x1ZGUgPHNpZ25hbC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworI2lmZGVmIEhBVkVfUFRIUkVBRFMKKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisjaW5jbHVkZSA8c2NoZWQuaD4KKyNpbmNsdWRlIDxzeXMvcmVzb3VyY2UuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfV0lOMzJfVEhSRUFEUworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCisKKyNpZiBMT0dfTkRFQlVHCisKKyNkZWZpbmUgSUZfTE9HX1RSQU5TQUNUSU9OUygpIGlmIChmYWxzZSkKKyNkZWZpbmUgSUZfTE9HX0NPTU1BTkRTKCkgaWYgKGZhbHNlKQorI2RlZmluZSBMT0dfUkVNT1RFUkVGUyguLi4pIAorI2RlZmluZSBJRl9MT0dfUkVNT1RFUkVGUygpIGlmIChmYWxzZSkKKyNkZWZpbmUgTE9HX1RIUkVBRFBPT0woLi4uKSAKKyNkZWZpbmUgTE9HX09ORVdBWSguLi4pIAorCisjZWxzZQorCisjZGVmaW5lIElGX0xPR19UUkFOU0FDVElPTlMoKSBJRl9MT0coTE9HX1ZFUkJPU0UsICJ0cmFuc2FjdCIpCisjZGVmaW5lIElGX0xPR19DT01NQU5EUygpIElGX0xPRyhMT0dfVkVSQk9TRSwgImlwYyIpCisjZGVmaW5lIExPR19SRU1PVEVSRUZTKC4uLikgTE9HKExPR19ERUJVRywgInJlbW90ZXJlZnMiLCBfX1ZBX0FSR1NfXykKKyNkZWZpbmUgSUZfTE9HX1JFTU9URVJFRlMoKSBJRl9MT0coTE9HX0RFQlVHLCAicmVtb3RlcmVmcyIpCisjZGVmaW5lIExPR19USFJFQURQT09MKC4uLikgTE9HKExPR19ERUJVRywgInRocmVhZHBvb2wiLCBfX1ZBX0FSR1NfXykKKyNkZWZpbmUgTE9HX09ORVdBWSguLi4pIExPRyhMT0dfREVCVUcsICJpcGMiLCBfX1ZBX0FSR1NfXykKKworI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0YXRpYyBjb25zdCBjaGFyKiBnZXRSZXR1cm5TdHJpbmcoc2l6ZV90IGlkeCk7CitzdGF0aWMgY29uc3QgY2hhciogZ2V0Q29tbWFuZFN0cmluZyhzaXplX3QgaWR4KTsKK3N0YXRpYyBjb25zdCB2b2lkKiBwcmludFJldHVybkNvbW1hbmQoVGV4dE91dHB1dCYgb3V0LCBjb25zdCB2b2lkKiBfY21kKTsKK3N0YXRpYyBjb25zdCB2b2lkKiBwcmludENvbW1hbmQoVGV4dE91dHB1dCYgb3V0LCBjb25zdCB2b2lkKiBfY21kKTsKKworLy8gVGhpcyB3aWxsIHJlc3VsdCBpbiBhIG1pc3Npbmcgc3ltYm9sIGZhaWx1cmUgaWYgdGhlIElGX0xPR19DT01NQU5EUygpCisvLyBjb25kaXRpb25hbHMgZG9uJ3QgZ2V0IHN0cmlwcGVkLi4uICBidXQgdGhhdCBpcyBwcm9iYWJseSB3aGF0IHdlIHdhbnQuCisjaWYgIUxPR19OREVCVUcKK3N0YXRpYyBjb25zdCBjaGFyICprUmV0dXJuU3RyaW5nc1tdID0geworI2lmIDEgLyogVE9ETzogZXJyb3IgdXBkYXRlIHN0cmluZ3MgKi8KKyAgICAidW5rbm93biIsCisjZWxzZQorICAgICJCUl9PSyIsCisgICAgIkJSX1RJTUVPVVQiLAorICAgICJCUl9XQUtFVVAiLAorICAgICJCUl9UUkFOU0FDVElPTiIsCisgICAgIkJSX1JFUExZIiwKKyAgICAiQlJfQUNRVUlSRV9SRVNVTFQiLAorICAgICJCUl9ERUFEX1JFUExZIiwKKyAgICAiQlJfVFJBTlNBQ1RJT05fQ09NUExFVEUiLAorICAgICJCUl9JTkNSRUZTIiwKKyAgICAiQlJfQUNRVUlSRSIsCisgICAgIkJSX1JFTEVBU0UiLAorICAgICJCUl9ERUNSRUZTIiwKKyAgICAiQlJfQVRURU1QVF9BQ1FVSVJFIiwKKyAgICAiQlJfRVZFTlRfT0NDVVJSRUQiLAorICAgICJCUl9OT09QIiwKKyAgICAiQlJfU1BBV05fTE9PUEVSIiwKKyAgICAiQlJfRklOSVNIRUQiLAorICAgICJCUl9ERUFEX0JJTkRFUiIsCisgICAgIkJSX0NMRUFSX0RFQVRIX05PVElGSUNBVElPTl9ET05FIgorI2VuZGlmCit9OworCitzdGF0aWMgY29uc3QgY2hhciAqa0NvbW1hbmRTdHJpbmdzW10gPSB7CisjaWYgMSAvKiBUT0RPOiBlcnJvciB1cGRhdGUgc3RyaW5ncyAqLworICAgICJ1bmtub3duIiwKKyNlbHNlCisgICAgIkJDX05PT1AiLAorICAgICJCQ19UUkFOU0FDVElPTiIsCisgICAgIkJDX1JFUExZIiwKKyAgICAiQkNfQUNRVUlSRV9SRVNVTFQiLAorICAgICJCQ19GUkVFX0JVRkZFUiIsCisgICAgIkJDX1RSQU5TQUNUSU9OX0NPTVBMRVRFIiwKKyAgICAiQkNfSU5DUkVGUyIsCisgICAgIkJDX0FDUVVJUkUiLAorICAgICJCQ19SRUxFQVNFIiwKKyAgICAiQkNfREVDUkVGUyIsCisgICAgIkJDX0lOQ1JFRlNfRE9ORSIsCisgICAgIkJDX0FDUVVJUkVfRE9ORSIsCisgICAgIkJDX0FUVEVNUFRfQUNRVUlSRSIsCisgICAgIkJDX1JFVFJJRVZFX1JPT1RfT0JKRUNUIiwKKyAgICAiQkNfU0VUX1RIUkVBRF9FTlRSWSIsCisgICAgIkJDX1JFR0lTVEVSX0xPT1BFUiIsCisgICAgIkJDX0VOVEVSX0xPT1BFUiIsCisgICAgIkJDX0VYSVRfTE9PUEVSIiwKKyAgICAiQkNfU1lOQyIsCisgICAgIkJDX1NUT1BfUFJPQ0VTUyIsCisgICAgIkJDX1NUT1BfU0VMRiIsCisgICAgIkJDX1JFUVVFU1RfREVBVEhfTk9USUZJQ0FUSU9OIiwKKyAgICAiQkNfQ0xFQVJfREVBVEhfTk9USUZJQ0FUSU9OIiwKKyAgICAiQkNfREVBRF9CSU5ERVJfRE9ORSIKKyNlbmRpZgorfTsKKworc3RhdGljIGNvbnN0IGNoYXIqIGdldFJldHVyblN0cmluZyhzaXplX3QgaWR4KQoreworICAgIGlmIChpZHggPCBzaXplb2Yoa1JldHVyblN0cmluZ3MpIC8gc2l6ZW9mKGtSZXR1cm5TdHJpbmdzWzBdKSkKKyAgICAgICAgcmV0dXJuIGtSZXR1cm5TdHJpbmdzW2lkeF07CisgICAgZWxzZQorICAgICAgICByZXR1cm4gInVua25vd24iOworfQorCitzdGF0aWMgY29uc3QgY2hhciogZ2V0Q29tbWFuZFN0cmluZyhzaXplX3QgaWR4KQoreworICAgIGlmIChpZHggPCBzaXplb2Yoa0NvbW1hbmRTdHJpbmdzKSAvIHNpemVvZihrQ29tbWFuZFN0cmluZ3NbMF0pKQorICAgICAgICByZXR1cm4ga0NvbW1hbmRTdHJpbmdzW2lkeF07CisgICAgZWxzZQorICAgICAgICByZXR1cm4gInVua25vd24iOworfQorCitzdGF0aWMgY29uc3Qgdm9pZCogcHJpbnRCaW5kZXJUcmFuc2FjdGlvbkRhdGEoVGV4dE91dHB1dCYgb3V0LCBjb25zdCB2b2lkKiBkYXRhKQoreworICAgIGNvbnN0IGJpbmRlcl90cmFuc2FjdGlvbl9kYXRhKiBidGQgPQorICAgICAgICAoY29uc3QgYmluZGVyX3RyYW5zYWN0aW9uX2RhdGEqKWRhdGE7CisgICAgb3V0IDw8ICJ0YXJnZXQ9IiA8PCBidGQtPnRhcmdldC5wdHIgPDwgIiAoY29va2llICIgPDwgYnRkLT5jb29raWUgPDwgIikiIDw8IGVuZGwKKyAgICAgICAgPDwgImNvZGU9IiA8PCBUeXBlQ29kZShidGQtPmNvZGUpIDw8ICIsIGZsYWdzPSIgPDwgKHZvaWQqKWJ0ZC0+ZmxhZ3MgPDwgZW5kbAorICAgICAgICA8PCAiZGF0YT0iIDw8IGJ0ZC0+ZGF0YS5wdHIuYnVmZmVyIDw8ICIgKCIgPDwgKHZvaWQqKWJ0ZC0+ZGF0YV9zaXplCisgICAgICAgIDw8ICIgYnl0ZXMpIiA8PCBlbmRsCisgICAgICAgIDw8ICJvZmZzZXRzPSIgPDwgYnRkLT5kYXRhLnB0ci5vZmZzZXRzIDw8ICIgKCIgPDwgKHZvaWQqKWJ0ZC0+b2Zmc2V0c19zaXplCisgICAgICAgIDw8ICIgYnl0ZXMpIiA8PCBlbmRsOworICAgIHJldHVybiBidGQrMTsKK30KKworc3RhdGljIGNvbnN0IHZvaWQqIHByaW50UmV0dXJuQ29tbWFuZChUZXh0T3V0cHV0JiBvdXQsIGNvbnN0IHZvaWQqIF9jbWQpCit7CisgICAgc3RhdGljIGNvbnN0IGludDMyX3QgTiA9IHNpemVvZihrUmV0dXJuU3RyaW5ncykvc2l6ZW9mKGtSZXR1cm5TdHJpbmdzWzBdKTsKKyAgICAKKyAgICBjb25zdCBpbnQzMl90KiBjbWQgPSAoY29uc3QgaW50MzJfdCopX2NtZDsKKyAgICBpbnQzMl90IGNvZGUgPSAqY21kKys7CisgICAgaWYgKGNvZGUgPT0gQlJfRVJST1IpIHsKKyAgICAgICAgb3V0IDw8ICJCUl9FUlJPUjogIiA8PCAodm9pZCopKCpjbWQrKykgPDwgZW5kbDsKKyAgICAgICAgcmV0dXJuIGNtZDsKKyAgICB9IGVsc2UgaWYgKGNvZGUgPCAwIHx8IGNvZGUgPj0gTikgeworICAgICAgICBvdXQgPDwgIlVua25vd24gcmVwbHk6ICIgPDwgY29kZSA8PCBlbmRsOworICAgICAgICByZXR1cm4gY21kOworICAgIH0KKyAgICAKKyAgICBvdXQgPDwga1JldHVyblN0cmluZ3NbY29kZV07CisgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgQlJfVFJBTlNBQ1RJT046CisgICAgICAgIGNhc2UgQlJfUkVQTFk6IHsKKyAgICAgICAgICAgIG91dCA8PCAiOiAiIDw8IGluZGVudDsKKyAgICAgICAgICAgIGNtZCA9IChjb25zdCBpbnQzMl90ICopcHJpbnRCaW5kZXJUcmFuc2FjdGlvbkRhdGEob3V0LCBjbWQpOworICAgICAgICAgICAgb3V0IDw8IGRlZGVudDsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgCisgICAgICAgIGNhc2UgQlJfQUNRVUlSRV9SRVNVTFQ6IHsKKyAgICAgICAgICAgIGNvbnN0IGludDMyX3QgcmVzID0gKmNtZCsrOworICAgICAgICAgICAgb3V0IDw8ICI6ICIgPDwgcmVzIDw8IChyZXMgPyAiIChTVUNDRVNTKSIgOiAiIChGQUlMVVJFKSIpOworICAgICAgICB9IGJyZWFrOworICAgICAgICAKKyAgICAgICAgY2FzZSBCUl9JTkNSRUZTOgorICAgICAgICBjYXNlIEJSX0FDUVVJUkU6CisgICAgICAgIGNhc2UgQlJfUkVMRUFTRToKKyAgICAgICAgY2FzZSBCUl9ERUNSRUZTOiB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGIgPSAqY21kKys7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGMgPSAqY21kKys7CisgICAgICAgICAgICBvdXQgPDwgIjogdGFyZ2V0PSIgPDwgKHZvaWQqKWIgPDwgIiAoY29va2llICIgPDwgKHZvaWQqKWMgPDwgIikiOworICAgICAgICB9IGJyZWFrOworICAgIAorICAgICAgICBjYXNlIEJSX0FUVEVNUFRfQUNRVUlSRTogeworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBwID0gKmNtZCsrOworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBiID0gKmNtZCsrOworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBjID0gKmNtZCsrOworICAgICAgICAgICAgb3V0IDw8ICI6IHRhcmdldD0iIDw8ICh2b2lkKiliIDw8ICIgKGNvb2tpZSAiIDw8ICh2b2lkKiljCisgICAgICAgICAgICAgICAgPDwgIiksIHByaT0iIDw8IHA7CisgICAgICAgIH0gYnJlYWs7CisKKyAgICAgICAgY2FzZSBCUl9ERUFEX0JJTkRFUjoKKyAgICAgICAgY2FzZSBCUl9DTEVBUl9ERUFUSF9OT1RJRklDQVRJT05fRE9ORTogeworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBjID0gKmNtZCsrOworICAgICAgICAgICAgb3V0IDw8ICI6IGRlYXRoIGNvb2tpZSAiIDw8ICh2b2lkKiljOworICAgICAgICB9IGJyZWFrOworICAgIH0KKyAgICAKKyAgICBvdXQgPDwgZW5kbDsKKyAgICByZXR1cm4gY21kOworfQorCitzdGF0aWMgY29uc3Qgdm9pZCogcHJpbnRDb21tYW5kKFRleHRPdXRwdXQmIG91dCwgY29uc3Qgdm9pZCogX2NtZCkKK3sKKyAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBOID0gc2l6ZW9mKGtDb21tYW5kU3RyaW5ncykvc2l6ZW9mKGtDb21tYW5kU3RyaW5nc1swXSk7CisgICAgCisgICAgY29uc3QgaW50MzJfdCogY21kID0gKGNvbnN0IGludDMyX3QqKV9jbWQ7CisgICAgaW50MzJfdCBjb2RlID0gKmNtZCsrOworICAgIGlmIChjb2RlIDwgMCB8fCBjb2RlID49IE4pIHsKKyAgICAgICAgb3V0IDw8ICJVbmtub3duIGNvbW1hbmQ6ICIgPDwgY29kZSA8PCBlbmRsOworICAgICAgICByZXR1cm4gY21kOworICAgIH0KKyAgICAKKyAgICBvdXQgPDwga0NvbW1hbmRTdHJpbmdzW2NvZGVdOworICAgIHN3aXRjaCAoY29kZSkgeworICAgICAgICBjYXNlIEJDX1RSQU5TQUNUSU9OOgorICAgICAgICBjYXNlIEJDX1JFUExZOiB7CisgICAgICAgICAgICBvdXQgPDwgIjogIiA8PCBpbmRlbnQ7CisgICAgICAgICAgICBjbWQgPSAoY29uc3QgaW50MzJfdCAqKXByaW50QmluZGVyVHJhbnNhY3Rpb25EYXRhKG91dCwgY21kKTsKKyAgICAgICAgICAgIG91dCA8PCBkZWRlbnQ7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIAorICAgICAgICBjYXNlIEJDX0FDUVVJUkVfUkVTVUxUOiB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IHJlcyA9ICpjbWQrKzsKKyAgICAgICAgICAgIG91dCA8PCAiOiAiIDw8IHJlcyA8PCAocmVzID8gIiAoU1VDQ0VTUykiIDogIiAoRkFJTFVSRSkiKTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgCisgICAgICAgIGNhc2UgQkNfRlJFRV9CVUZGRVI6IHsKKyAgICAgICAgICAgIGNvbnN0IGludDMyX3QgYnVmID0gKmNtZCsrOworICAgICAgICAgICAgb3V0IDw8ICI6IGJ1ZmZlcj0iIDw8ICh2b2lkKilidWY7CisgICAgICAgIH0gYnJlYWs7CisgICAgICAgIAorICAgICAgICBjYXNlIEJDX0lOQ1JFRlM6CisgICAgICAgIGNhc2UgQkNfQUNRVUlSRToKKyAgICAgICAgY2FzZSBCQ19SRUxFQVNFOgorICAgICAgICBjYXNlIEJDX0RFQ1JFRlM6IHsKKyAgICAgICAgICAgIGNvbnN0IGludDMyX3QgZCA9ICpjbWQrKzsKKyAgICAgICAgICAgIG91dCA8PCAiOiBkZXNjcmlwdG9yPSIgPDwgKHZvaWQqKWQ7CisgICAgICAgIH0gYnJlYWs7CisgICAgCisgICAgICAgIGNhc2UgQkNfSU5DUkVGU19ET05FOgorICAgICAgICBjYXNlIEJDX0FDUVVJUkVfRE9ORTogeworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBiID0gKmNtZCsrOworICAgICAgICAgICAgY29uc3QgaW50MzJfdCBjID0gKmNtZCsrOworICAgICAgICAgICAgb3V0IDw8ICI6IHRhcmdldD0iIDw8ICh2b2lkKiliIDw8ICIgKGNvb2tpZSAiIDw8ICh2b2lkKiljIDw8ICIpIjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgCisgICAgICAgIGNhc2UgQkNfQVRURU1QVF9BQ1FVSVJFOiB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IHAgPSAqY21kKys7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGQgPSAqY21kKys7CisgICAgICAgICAgICBvdXQgPDwgIjogZGVjcmlwdG9yPSIgPDwgKHZvaWQqKWQgPDwgIiwgcHJpPSIgPDwgcDsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgCisgICAgICAgIGNhc2UgQkNfUkVRVUVTVF9ERUFUSF9OT1RJRklDQVRJT046CisgICAgICAgIGNhc2UgQkNfQ0xFQVJfREVBVEhfTk9USUZJQ0FUSU9OOiB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGggPSAqY21kKys7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGMgPSAqY21kKys7CisgICAgICAgICAgICBvdXQgPDwgIjogaGFuZGxlPSIgPDwgaCA8PCAiIChkZWF0aCBjb29raWUgIiA8PCAodm9pZCopYyA8PCAiKSI7CisgICAgICAgIH0gYnJlYWs7CisKKyAgICAgICAgY2FzZSBCQ19ERUFEX0JJTkRFUl9ET05FOiB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGMgPSAqY21kKys7CisgICAgICAgICAgICBvdXQgPDwgIjogZGVhdGggY29va2llICIgPDwgKHZvaWQqKWM7CisgICAgICAgIH0gYnJlYWs7CisgICAgfQorICAgIAorICAgIG91dCA8PCBlbmRsOworICAgIHJldHVybiBjbWQ7Cit9CisjZW5kaWYKKworc3RhdGljIHB0aHJlYWRfbXV0ZXhfdCBnVExTTXV0ZXggPSBQVEhSRUFEX01VVEVYX0lOSVRJQUxJWkVSOworc3RhdGljIGJvb2wgZ0hhdmVUTFMgPSBmYWxzZTsKK3N0YXRpYyBwdGhyZWFkX2tleV90IGdUTFMgPSAwOworc3RhdGljIGJvb2wgZ1NodXRkb3duID0gZmFsc2U7CisKK0lQQ1RocmVhZFN0YXRlKiBJUENUaHJlYWRTdGF0ZTo6c2VsZigpCit7CisgICAgaWYgKGdIYXZlVExTKSB7CityZXN0YXJ0OgorICAgICAgICBjb25zdCBwdGhyZWFkX2tleV90IGsgPSBnVExTOworICAgICAgICBJUENUaHJlYWRTdGF0ZSogc3QgPSAoSVBDVGhyZWFkU3RhdGUqKXB0aHJlYWRfZ2V0c3BlY2lmaWMoayk7CisgICAgICAgIGlmIChzdCkgcmV0dXJuIHN0OworICAgICAgICByZXR1cm4gbmV3IElQQ1RocmVhZFN0YXRlOworICAgIH0KKyAgICAKKyAgICBpZiAoZ1NodXRkb3duKSByZXR1cm4gTlVMTDsKKyAgICAKKyAgICBwdGhyZWFkX211dGV4X2xvY2soJmdUTFNNdXRleCk7CisgICAgaWYgKCFnSGF2ZVRMUykgeworICAgICAgICBpZiAocHRocmVhZF9rZXlfY3JlYXRlKCZnVExTLCB0aHJlYWREZXN0cnVjdG9yKSAhPSAwKSB7CisgICAgICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ1RMU011dGV4KTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGdIYXZlVExTID0gdHJ1ZTsKKyAgICB9CisgICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdUTFNNdXRleCk7CisgICAgZ290byByZXN0YXJ0OworfQorCit2b2lkIElQQ1RocmVhZFN0YXRlOjpzaHV0ZG93bigpCit7CisgICAgZ1NodXRkb3duID0gdHJ1ZTsKKyAgICAKKyAgICBpZiAoZ0hhdmVUTFMpIHsKKyAgICAgICAgLy8gWFhYIE5lZWQgdG8gd2FpdCBmb3IgYWxsIHRocmVhZCBwb29sIHRocmVhZHMgdG8gZXhpdCEKKyAgICAgICAgSVBDVGhyZWFkU3RhdGUqIHN0ID0gKElQQ1RocmVhZFN0YXRlKilwdGhyZWFkX2dldHNwZWNpZmljKGdUTFMpOworICAgICAgICBpZiAoc3QpIHsKKyAgICAgICAgICAgIGRlbGV0ZSBzdDsKKyAgICAgICAgICAgIHB0aHJlYWRfc2V0c3BlY2lmaWMoZ1RMUywgTlVMTCk7CisgICAgICAgIH0KKyAgICAgICAgZ0hhdmVUTFMgPSBmYWxzZTsKKyAgICB9Cit9CisKK3NwPFByb2Nlc3NTdGF0ZT4gSVBDVGhyZWFkU3RhdGU6OnByb2Nlc3MoKQoreworICAgIHJldHVybiBtUHJvY2VzczsKK30KKworc3RhdHVzX3QgSVBDVGhyZWFkU3RhdGU6OmNsZWFyTGFzdEVycm9yKCkKK3sKKyAgICBjb25zdCBzdGF0dXNfdCBlcnIgPSBtTGFzdEVycm9yOworICAgIG1MYXN0RXJyb3IgPSBOT19FUlJPUjsKKyAgICByZXR1cm4gZXJyOworfQorCitpbnQgSVBDVGhyZWFkU3RhdGU6OmdldENhbGxpbmdQaWQoKQoreworICAgIHJldHVybiBtQ2FsbGluZ1BpZDsKK30KKworaW50IElQQ1RocmVhZFN0YXRlOjpnZXRDYWxsaW5nVWlkKCkKK3sKKyAgICByZXR1cm4gbUNhbGxpbmdVaWQ7Cit9CisKK2ludDY0X3QgSVBDVGhyZWFkU3RhdGU6OmNsZWFyQ2FsbGluZ0lkZW50aXR5KCkKK3sKKyAgICBpbnQ2NF90IHRva2VuID0gKChpbnQ2NF90KW1DYWxsaW5nVWlkPDwzMikgfCBtQ2FsbGluZ1BpZDsKKyAgICBjbGVhckNhbGxlcigpOworICAgIHJldHVybiB0b2tlbjsKK30KKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6cmVzdG9yZUNhbGxpbmdJZGVudGl0eShpbnQ2NF90IHRva2VuKQoreworICAgIG1DYWxsaW5nVWlkID0gKGludCkodG9rZW4+PjMyKTsKKyAgICBtQ2FsbGluZ1BpZCA9IChpbnQpdG9rZW47Cit9CisKK3ZvaWQgSVBDVGhyZWFkU3RhdGU6OmNsZWFyQ2FsbGVyKCkKK3sKKyAgICBpZiAobVByb2Nlc3MtPnN1cHBvcnRzUHJvY2Vzc2VzKCkpIHsKKyAgICAgICAgbUNhbGxpbmdQaWQgPSBnZXRwaWQoKTsKKyAgICAgICAgbUNhbGxpbmdVaWQgPSBnZXR1aWQoKTsKKyAgICB9IGVsc2UgeworICAgICAgICBtQ2FsbGluZ1BpZCA9IC0xOworICAgICAgICBtQ2FsbGluZ1VpZCA9IC0xOworICAgIH0KK30KKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6Zmx1c2hDb21tYW5kcygpCit7CisgICAgaWYgKG1Qcm9jZXNzLT5tRHJpdmVyRkQgPD0gMCkKKyAgICAgICAgcmV0dXJuOworICAgIHRhbGtXaXRoRHJpdmVyKGZhbHNlKTsKK30KKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6am9pblRocmVhZFBvb2woYm9vbCBpc01haW4pCit7CisgICAgTE9HX1RIUkVBRFBPT0woIioqKiogVEhSRUFEICVwIChQSUQgJWQpIElTIEpPSU5JTkcgVEhFIFRIUkVBRCBQT09MXG4iLCAodm9pZCopcHRocmVhZF9zZWxmKCksIGdldHBpZCgpKTsKKworICAgIG1PdXQud3JpdGVJbnQzMihpc01haW4gPyBCQ19FTlRFUl9MT09QRVIgOiBCQ19SRUdJU1RFUl9MT09QRVIpOworICAgIAorICAgIHN0YXR1c190IHJlc3VsdDsKKyAgICBkbyB7CisgICAgICAgIGludDMyX3QgY21kOworICAgICAgICAKKyAgICAgICAgLy8gV2hlbiB3ZSd2ZSBjbGVhcmVkIHRoZSBpbmNvbWluZyBjb21tYW5kIHF1ZXVlLCBwcm9jZXNzIGFueSBwZW5kaW5nIGRlcmVmcworICAgICAgICBpZiAobUluLmRhdGFQb3NpdGlvbigpID49IG1Jbi5kYXRhU2l6ZSgpKSB7CisgICAgICAgICAgICBzaXplX3QgbnVtUGVuZGluZyA9IG1QZW5kaW5nV2Vha0RlcmVmcy5zaXplKCk7CisgICAgICAgICAgICBpZiAobnVtUGVuZGluZyA+IDApIHsKKyAgICAgICAgICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG51bVBlbmRpbmc7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqIHJlZnMgPSBtUGVuZGluZ1dlYWtEZXJlZnNbaV07CisgICAgICAgICAgICAgICAgICAgIHJlZnMtPmRlY1dlYWsobVByb2Nlc3MuZ2V0KCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBtUGVuZGluZ1dlYWtEZXJlZnMuY2xlYXIoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbnVtUGVuZGluZyA9IG1QZW5kaW5nU3Ryb25nRGVyZWZzLnNpemUoKTsKKyAgICAgICAgICAgIGlmIChudW1QZW5kaW5nID4gMCkgeworICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbnVtUGVuZGluZzsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIEJCaW5kZXIqIG9iaiA9IG1QZW5kaW5nU3Ryb25nRGVyZWZzW2ldOworICAgICAgICAgICAgICAgICAgICBvYmotPmRlY1N0cm9uZyhtUHJvY2Vzcy5nZXQoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1QZW5kaW5nU3Ryb25nRGVyZWZzLmNsZWFyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBub3cgZ2V0IHRoZSBuZXh0IGNvbW1hbmQgdG8gYmUgcHJvY2Vzc2VkLCB3YWl0aW5nIGlmIG5lY2Vzc2FyeQorICAgICAgICByZXN1bHQgPSB0YWxrV2l0aERyaXZlcigpOworICAgICAgICBpZiAocmVzdWx0ID49IE5PX0VSUk9SKSB7CisgICAgICAgICAgICBzaXplX3QgSU4gPSBtSW4uZGF0YUF2YWlsKCk7CisgICAgICAgICAgICBpZiAoSU4gPCBzaXplb2YoaW50MzJfdCkpIGNvbnRpbnVlOworICAgICAgICAgICAgY21kID0gbUluLnJlYWRJbnQzMigpOworICAgICAgICAgICAgSUZfTE9HX0NPTU1BTkRTKCkgeworICAgICAgICAgICAgICAgIGFsb2cgPDwgIlByb2Nlc3NpbmcgdG9wLWxldmVsIENvbW1hbmQ6ICIKKyAgICAgICAgICAgICAgICAgICAgPDwgZ2V0UmV0dXJuU3RyaW5nKGNtZCkgPDwgZW5kbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdCA9IGV4ZWN1dGVDb21tYW5kKGNtZCk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIC8vIExldCB0aGlzIHRocmVhZCBleGl0IHRoZSB0aHJlYWQgcG9vbCBpZiBpdCBpcyBubyBsb25nZXIKKyAgICAgICAgLy8gbmVlZGVkIGFuZCBpdCBpcyBub3QgdGhlIG1haW4gcHJvY2VzcyB0aHJlYWQuCisgICAgICAgIGlmKHJlc3VsdCA9PSBUSU1FRF9PVVQgJiYgIWlzTWFpbikgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9IHdoaWxlIChyZXN1bHQgIT0gLUVDT05OUkVGVVNFRCAmJiByZXN1bHQgIT0gLUVCQURGKTsKKworICAgIExPR19USFJFQURQT09MKCIqKioqIFRIUkVBRCAlcCAoUElEICVkKSBJUyBMRUFWSU5HIFRIRSBUSFJFQUQgUE9PTCBlcnI9JXBcbiIsCisgICAgICAgICh2b2lkKilwdGhyZWFkX3NlbGYoKSwgZ2V0cGlkKCksICh2b2lkKilyZXN1bHQpOworICAgIAorICAgIG1PdXQud3JpdGVJbnQzMihCQ19FWElUX0xPT1BFUik7CisgICAgdGFsa1dpdGhEcml2ZXIoZmFsc2UpOworfQorCit2b2lkIElQQ1RocmVhZFN0YXRlOjpzdG9wUHJvY2Vzcyhib29sIGltbWVkaWF0ZSkKK3sKKyAgICAvL0xPR0koIioqKiogU1RPUFBJTkcgUFJPQ0VTUyIpOworICAgIGZsdXNoQ29tbWFuZHMoKTsKKyAgICBpbnQgZmQgPSBtUHJvY2Vzcy0+bURyaXZlckZEOworICAgIG1Qcm9jZXNzLT5tRHJpdmVyRkQgPSAtMTsKKyAgICBjbG9zZShmZCk7CisgICAgLy9raWxsKGdldHBpZCgpLCBTSUdLSUxMKTsKK30KKworc3RhdHVzX3QgSVBDVGhyZWFkU3RhdGU6OnRyYW5zYWN0KGludDMyX3QgaGFuZGxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJjZWwqIHJlcGx5LCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBzdGF0dXNfdCBlcnIgPSBkYXRhLmVycm9yQ2hlY2soKTsKKworICAgIGZsYWdzIHw9IFRGX0FDQ0VQVF9GRFM7CisKKyAgICBJRl9MT0dfVFJBTlNBQ1RJT05TKCkgeworICAgICAgICBUZXh0T3V0cHV0OjpCdW5kbGUgX2IoYWxvZyk7CisgICAgICAgIGFsb2cgPDwgIkJDX1RSQU5TQUNUSU9OIHRociAiIDw8ICh2b2lkKilwdGhyZWFkX3NlbGYoKSA8PCAiIC8gaGFuZCAiCisgICAgICAgICAgICA8PCBoYW5kbGUgPDwgIiAvIGNvZGUgIiA8PCBUeXBlQ29kZShjb2RlKSA8PCAiOiAiCisgICAgICAgICAgICA8PCBpbmRlbnQgPDwgZGF0YSA8PCBkZWRlbnQgPDwgZW5kbDsKKyAgICB9CisgICAgCisgICAgaWYgKGVyciA9PSBOT19FUlJPUikgeworICAgICAgICBMT0dfT05FV0FZKCI+Pj4+IFNFTkQgZnJvbSBwaWQgJWQgdWlkICVkICVzIiwgZ2V0cGlkKCksIGdldHVpZCgpLAorICAgICAgICAgICAgKGZsYWdzICYgVEZfT05FX1dBWSkgPT0gMCA/ICJSRUFEIFJFUExZIiA6ICJPTkUgV0FZIik7CisgICAgICAgIGVyciA9IHdyaXRlVHJhbnNhY3Rpb25EYXRhKEJDX1RSQU5TQUNUSU9OLCBmbGFncywgaGFuZGxlLCBjb2RlLCBkYXRhLCBOVUxMKTsKKyAgICB9CisgICAgCisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICBpZiAocmVwbHkpIHJlcGx5LT5zZXRFcnJvcihlcnIpOworICAgICAgICByZXR1cm4gKG1MYXN0RXJyb3IgPSBlcnIpOworICAgIH0KKyAgICAKKyAgICBpZiAoKGZsYWdzICYgVEZfT05FX1dBWSkgPT0gMCkgeworICAgICAgICBpZiAocmVwbHkpIHsKKyAgICAgICAgICAgIGVyciA9IHdhaXRGb3JSZXNwb25zZShyZXBseSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBQYXJjZWwgZmFrZVJlcGx5OworICAgICAgICAgICAgZXJyID0gd2FpdEZvclJlc3BvbnNlKCZmYWtlUmVwbHkpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBJRl9MT0dfVFJBTlNBQ1RJT05TKCkgeworICAgICAgICAgICAgVGV4dE91dHB1dDo6QnVuZGxlIF9iKGFsb2cpOworICAgICAgICAgICAgYWxvZyA8PCAiQlJfUkVQTFkgdGhyICIgPDwgKHZvaWQqKXB0aHJlYWRfc2VsZigpIDw8ICIgLyBoYW5kICIKKyAgICAgICAgICAgICAgICA8PCBoYW5kbGUgPDwgIjogIjsKKyAgICAgICAgICAgIGlmIChyZXBseSkgYWxvZyA8PCBpbmRlbnQgPDwgKnJlcGx5IDw8IGRlZGVudCA8PCBlbmRsOworICAgICAgICAgICAgZWxzZSBhbG9nIDw8ICIobm9uZSByZXF1ZXN0ZWQpIiA8PCBlbmRsOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgZXJyID0gd2FpdEZvclJlc3BvbnNlKE5VTEwsIE5VTEwpOworICAgIH0KKyAgICAKKyAgICByZXR1cm4gZXJyOworfQorCit2b2lkIElQQ1RocmVhZFN0YXRlOjppbmNTdHJvbmdIYW5kbGUoaW50MzJfdCBoYW5kbGUpCit7CisgICAgTE9HX1JFTU9URVJFRlMoIklQQ1RocmVhZFN0YXRlOjppbmNTdHJvbmdIYW5kbGUoJWQpXG4iLCBoYW5kbGUpOworICAgIG1PdXQud3JpdGVJbnQzMihCQ19BQ1FVSVJFKTsKKyAgICBtT3V0LndyaXRlSW50MzIoaGFuZGxlKTsKK30KKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6ZGVjU3Ryb25nSGFuZGxlKGludDMyX3QgaGFuZGxlKQoreworICAgIExPR19SRU1PVEVSRUZTKCJJUENUaHJlYWRTdGF0ZTo6ZGVjU3Ryb25nSGFuZGxlKCVkKVxuIiwgaGFuZGxlKTsKKyAgICBtT3V0LndyaXRlSW50MzIoQkNfUkVMRUFTRSk7CisgICAgbU91dC53cml0ZUludDMyKGhhbmRsZSk7Cit9CisKK3ZvaWQgSVBDVGhyZWFkU3RhdGU6OmluY1dlYWtIYW5kbGUoaW50MzJfdCBoYW5kbGUpCit7CisgICAgTE9HX1JFTU9URVJFRlMoIklQQ1RocmVhZFN0YXRlOjppbmNXZWFrSGFuZGxlKCVkKVxuIiwgaGFuZGxlKTsKKyAgICBtT3V0LndyaXRlSW50MzIoQkNfSU5DUkVGUyk7CisgICAgbU91dC53cml0ZUludDMyKGhhbmRsZSk7Cit9CisKK3ZvaWQgSVBDVGhyZWFkU3RhdGU6OmRlY1dlYWtIYW5kbGUoaW50MzJfdCBoYW5kbGUpCit7CisgICAgTE9HX1JFTU9URVJFRlMoIklQQ1RocmVhZFN0YXRlOjpkZWNXZWFrSGFuZGxlKCVkKVxuIiwgaGFuZGxlKTsKKyAgICBtT3V0LndyaXRlSW50MzIoQkNfREVDUkVGUyk7CisgICAgbU91dC53cml0ZUludDMyKGhhbmRsZSk7Cit9CisKK3N0YXR1c190IElQQ1RocmVhZFN0YXRlOjphdHRlbXB0SW5jU3Ryb25nSGFuZGxlKGludDMyX3QgaGFuZGxlKQoreworICAgIG1PdXQud3JpdGVJbnQzMihCQ19BVFRFTVBUX0FDUVVJUkUpOworICAgIG1PdXQud3JpdGVJbnQzMigwKTsgLy8geHh4IHdhcyB0aHJlYWQgcHJpb3JpdHkKKyAgICBtT3V0LndyaXRlSW50MzIoaGFuZGxlKTsKKyAgICBzdGF0dXNfdCByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgIAorICAgIHdhaXRGb3JSZXNwb25zZShOVUxMLCAmcmVzdWx0KTsKKyAgICAKKyNpZiBMT0dfUkVGQ09VTlRTCisgICAgcHJpbnRmKCJJUENUaHJlYWRTdGF0ZTo6YXR0ZW1wdEluY1N0cm9uZ0hhbmRsZSglbGQpID0gJXNcbiIsCisgICAgICAgIGhhbmRsZSwgcmVzdWx0ID09IE5PX0VSUk9SID8gIlNVQ0NFU1MiIDogIkZBSUxVUkUiKTsKKyNlbmRpZgorICAgIAorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgSVBDVGhyZWFkU3RhdGU6OmV4cHVuZ2VIYW5kbGUoaW50MzJfdCBoYW5kbGUsIElCaW5kZXIqIGJpbmRlcikKK3sKKyNpZiBMT0dfUkVGQ09VTlRTCisgICAgcHJpbnRmKCJJUENUaHJlYWRTdGF0ZTo6ZXhwdW5nZUhhbmRsZSglbGQpXG4iLCBoYW5kbGUpOworI2VuZGlmCisgICAgc2VsZigpLT5tUHJvY2Vzcy0+ZXhwdW5nZUhhbmRsZShoYW5kbGUsIGJpbmRlcik7Cit9CisKK3N0YXR1c190IElQQ1RocmVhZFN0YXRlOjpyZXF1ZXN0RGVhdGhOb3RpZmljYXRpb24oaW50MzJfdCBoYW5kbGUsIEJwQmluZGVyKiBwcm94eSkKK3sKKyAgICBtT3V0LndyaXRlSW50MzIoQkNfUkVRVUVTVF9ERUFUSF9OT1RJRklDQVRJT04pOworICAgIG1PdXQud3JpdGVJbnQzMigoaW50MzJfdCloYW5kbGUpOworICAgIG1PdXQud3JpdGVJbnQzMigoaW50MzJfdClwcm94eSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBJUENUaHJlYWRTdGF0ZTo6Y2xlYXJEZWF0aE5vdGlmaWNhdGlvbihpbnQzMl90IGhhbmRsZSwgQnBCaW5kZXIqIHByb3h5KQoreworICAgIG1PdXQud3JpdGVJbnQzMihCQ19DTEVBUl9ERUFUSF9OT1RJRklDQVRJT04pOworICAgIG1PdXQud3JpdGVJbnQzMigoaW50MzJfdCloYW5kbGUpOworICAgIG1PdXQud3JpdGVJbnQzMigoaW50MzJfdClwcm94eSk7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitJUENUaHJlYWRTdGF0ZTo6SVBDVGhyZWFkU3RhdGUoKQorICAgIDogbVByb2Nlc3MoUHJvY2Vzc1N0YXRlOjpzZWxmKCkpCit7CisgICAgcHRocmVhZF9zZXRzcGVjaWZpYyhnVExTLCB0aGlzKTsKKyAgICAgICAgY2xlYXJDYWxsZXIoKTsKKyAgICBtSW4uc2V0RGF0YUNhcGFjaXR5KDI1Nik7CisgICAgbU91dC5zZXREYXRhQ2FwYWNpdHkoMjU2KTsKK30KKworSVBDVGhyZWFkU3RhdGU6On5JUENUaHJlYWRTdGF0ZSgpCit7Cit9CisKK3N0YXR1c190IElQQ1RocmVhZFN0YXRlOjpzZW5kUmVwbHkoY29uc3QgUGFyY2VsJiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3RhdHVzX3QgZXJyOworICAgIHN0YXR1c190IHN0YXR1c0J1ZmZlcjsKKyAgICBlcnIgPSB3cml0ZVRyYW5zYWN0aW9uRGF0YShCQ19SRVBMWSwgZmxhZ3MsIC0xLCAwLCByZXBseSwgJnN0YXR1c0J1ZmZlcik7CisgICAgaWYgKGVyciA8IE5PX0VSUk9SKSByZXR1cm4gZXJyOworICAgIAorICAgIHJldHVybiB3YWl0Rm9yUmVzcG9uc2UoTlVMTCwgTlVMTCk7Cit9CisKK3N0YXR1c190IElQQ1RocmVhZFN0YXRlOjp3YWl0Rm9yUmVzcG9uc2UoUGFyY2VsICpyZXBseSwgc3RhdHVzX3QgKmFjcXVpcmVSZXN1bHQpCit7CisgICAgaW50MzJfdCBjbWQ7CisgICAgaW50MzJfdCBlcnI7CisKKyAgICB3aGlsZSAoMSkgeworICAgICAgICBpZiAoKGVycj10YWxrV2l0aERyaXZlcigpKSA8IE5PX0VSUk9SKSBicmVhazsKKyAgICAgICAgZXJyID0gbUluLmVycm9yQ2hlY2soKTsKKyAgICAgICAgaWYgKGVyciA8IE5PX0VSUk9SKSBicmVhazsKKyAgICAgICAgaWYgKG1Jbi5kYXRhQXZhaWwoKSA9PSAwKSBjb250aW51ZTsKKyAgICAgICAgCisgICAgICAgIGNtZCA9IG1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgCisgICAgICAgIElGX0xPR19DT01NQU5EUygpIHsKKyAgICAgICAgICAgIGFsb2cgPDwgIlByb2Nlc3Npbmcgd2FpdEZvclJlc3BvbnNlIENvbW1hbmQ6ICIKKyAgICAgICAgICAgICAgICA8PCBnZXRSZXR1cm5TdHJpbmcoY21kKSA8PCBlbmRsOworICAgICAgICB9CisKKyAgICAgICAgc3dpdGNoIChjbWQpIHsKKyAgICAgICAgY2FzZSBCUl9UUkFOU0FDVElPTl9DT01QTEVURToKKyAgICAgICAgICAgIGlmICghcmVwbHkgJiYgIWFjcXVpcmVSZXN1bHQpIGdvdG8gZmluaXNoOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgICAgICBjYXNlIEJSX0RFQURfUkVQTFk6CisgICAgICAgICAgICBlcnIgPSBERUFEX09CSkVDVDsKKyAgICAgICAgICAgIGdvdG8gZmluaXNoOworCisgICAgICAgIGNhc2UgQlJfRkFJTEVEX1JFUExZOgorICAgICAgICAgICAgZXJyID0gRkFJTEVEX1RSQU5TQUNUSU9OOworICAgICAgICAgICAgZ290byBmaW5pc2g7CisgICAgICAgIAorICAgICAgICBjYXNlIEJSX0FDUVVJUkVfUkVTVUxUOgorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIExPR19BU1NFUlQoYWNxdWlyZVJlc3VsdCAhPSBOVUxMLCAiVW5leHBlY3RlZCBickFDUVVJUkVfUkVTVUxUIik7CisgICAgICAgICAgICAgICAgY29uc3QgaW50MzJfdCByZXN1bHQgPSBtSW4ucmVhZEludDMyKCk7CisgICAgICAgICAgICAgICAgaWYgKCFhY3F1aXJlUmVzdWx0KSBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAqYWNxdWlyZVJlc3VsdCA9IHJlc3VsdCA/IE5PX0VSUk9SIDogSU5WQUxJRF9PUEVSQVRJT047CisgICAgICAgICAgICB9CisgICAgICAgICAgICBnb3RvIGZpbmlzaDsKKyAgICAgICAgCisgICAgICAgIGNhc2UgQlJfUkVQTFk6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgYmluZGVyX3RyYW5zYWN0aW9uX2RhdGEgdHI7CisgICAgICAgICAgICAgICAgZXJyID0gbUluLnJlYWQoJnRyLCBzaXplb2YodHIpKTsKKyAgICAgICAgICAgICAgICBMT0dfQVNTRVJUKGVyciA9PSBOT19FUlJPUiwgIk5vdCBlbm91Z2ggY29tbWFuZCBkYXRhIGZvciBiclJFUExZIik7CisgICAgICAgICAgICAgICAgaWYgKGVyciAhPSBOT19FUlJPUikgZ290byBmaW5pc2g7CisKKyAgICAgICAgICAgICAgICBpZiAocmVwbHkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCh0ci5mbGFncyAmIFRGX1NUQVRVU19DT0RFKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXBseS0+aXBjU2V0RGF0YVJlZmVyZW5jZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4X3QqPih0ci5kYXRhLnB0ci5idWZmZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyLmRhdGFfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHNpemVfdCo+KHRyLmRhdGEucHRyLm9mZnNldHMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyLm9mZnNldHNfc2l6ZS9zaXplb2Yoc2l6ZV90KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlQnVmZmVyLCB0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9ICpzdGF0aWNfY2FzdDxjb25zdCBzdGF0dXNfdCo+KHRyLmRhdGEucHRyLmJ1ZmZlcik7CisgICAgICAgICAgICAgICAgICAgICAgICBmcmVlQnVmZmVyKE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OF90Kj4odHIuZGF0YS5wdHIuYnVmZmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ci5kYXRhX3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBzaXplX3QqPih0ci5kYXRhLnB0ci5vZmZzZXRzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ci5vZmZzZXRzX3NpemUvc2l6ZW9mKHNpemVfdCksIHRoaXMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZnJlZUJ1ZmZlcihOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OF90Kj4odHIuZGF0YS5wdHIuYnVmZmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyLmRhdGFfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3Qgc2l6ZV90Kj4odHIuZGF0YS5wdHIub2Zmc2V0cyksCisgICAgICAgICAgICAgICAgICAgICAgICB0ci5vZmZzZXRzX3NpemUvc2l6ZW9mKHNpemVfdCksIHRoaXMpOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBnb3RvIGZpbmlzaDsKKworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgZXJyID0gZXhlY3V0ZUNvbW1hbmQoY21kKTsKKyAgICAgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIGdvdG8gZmluaXNoOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKK2ZpbmlzaDoKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgIGlmIChhY3F1aXJlUmVzdWx0KSAqYWNxdWlyZVJlc3VsdCA9IGVycjsKKyAgICAgICAgaWYgKHJlcGx5KSByZXBseS0+c2V0RXJyb3IoZXJyKTsKKyAgICAgICAgbUxhc3RFcnJvciA9IGVycjsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGVycjsKK30KKworc3RhdHVzX3QgSVBDVGhyZWFkU3RhdGU6OnRhbGtXaXRoRHJpdmVyKGJvb2wgZG9SZWNlaXZlKQoreworICAgIExPR19BU1NFUlQobVByb2Nlc3MtPm1Ecml2ZXJGRCA+PSAwLCAiQmluZGVyIGRyaXZlciBpcyBub3Qgb3BlbmVkIik7CisgICAgCisgICAgYmluZGVyX3dyaXRlX3JlYWQgYndyOworICAgIAorICAgIC8vIElzIHRoZSByZWFkIGJ1ZmZlciBlbXB0eT8KKyAgICBjb25zdCBib29sIG5lZWRSZWFkID0gbUluLmRhdGFQb3NpdGlvbigpID49IG1Jbi5kYXRhU2l6ZSgpOworICAgIAorICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gd3JpdGUgYW55dGhpbmcgaWYgd2UgYXJlIHN0aWxsIHJlYWRpbmcKKyAgICAvLyBmcm9tIGRhdGEgbGVmdCBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZCB0aGUgY2FsbGVyCisgICAgLy8gaGFzIHJlcXVlc3RlZCB0byByZWFkIHRoZSBuZXh0IGRhdGEuCisgICAgY29uc3Qgc2l6ZV90IG91dEF2YWlsID0gKCFkb1JlY2VpdmUgfHwgbmVlZFJlYWQpID8gbU91dC5kYXRhU2l6ZSgpIDogMDsKKyAgICAKKyAgICBid3Iud3JpdGVfc2l6ZSA9IG91dEF2YWlsOworICAgIGJ3ci53cml0ZV9idWZmZXIgPSAobG9uZyB1bnNpZ25lZCBpbnQpbU91dC5kYXRhKCk7CisKKyAgICAvLyBUaGlzIGlzIHdoYXQgd2UnbGwgcmVhZC4KKyAgICBpZiAoZG9SZWNlaXZlICYmIG5lZWRSZWFkKSB7CisgICAgICAgIGJ3ci5yZWFkX3NpemUgPSBtSW4uZGF0YUNhcGFjaXR5KCk7CisgICAgICAgIGJ3ci5yZWFkX2J1ZmZlciA9IChsb25nIHVuc2lnbmVkIGludCltSW4uZGF0YSgpOworICAgIH0gZWxzZSB7CisgICAgICAgIGJ3ci5yZWFkX3NpemUgPSAwOworICAgIH0KKyAgICAKKyAgICBJRl9MT0dfQ09NTUFORFMoKSB7CisgICAgICAgIFRleHRPdXRwdXQ6OkJ1bmRsZSBfYihhbG9nKTsKKyAgICAgICAgaWYgKG91dEF2YWlsICE9IDApIHsKKyAgICAgICAgICAgIGFsb2cgPDwgIlNlbmRpbmcgY29tbWFuZHMgdG8gZHJpdmVyOiAiIDw8IGluZGVudDsKKyAgICAgICAgICAgIGNvbnN0IHZvaWQqIGNtZHMgPSAoY29uc3Qgdm9pZCopYndyLndyaXRlX2J1ZmZlcjsKKyAgICAgICAgICAgIGNvbnN0IHZvaWQqIGVuZCA9ICgoY29uc3QgdWludDhfdCopY21kcykrYndyLndyaXRlX3NpemU7CisgICAgICAgICAgICBhbG9nIDw8IEhleER1bXAoY21kcywgYndyLndyaXRlX3NpemUpIDw8IGVuZGw7CisgICAgICAgICAgICB3aGlsZSAoY21kcyA8IGVuZCkgY21kcyA9IHByaW50Q29tbWFuZChhbG9nLCBjbWRzKTsKKyAgICAgICAgICAgIGFsb2cgPDwgZGVkZW50OworICAgICAgICB9CisgICAgICAgIGFsb2cgPDwgIlNpemUgb2YgcmVjZWl2ZSBidWZmZXI6ICIgPDwgYndyLnJlYWRfc2l6ZQorICAgICAgICAgICAgPDwgIiwgbmVlZFJlYWQ6ICIgPDwgbmVlZFJlYWQgPDwgIiwgZG9SZWNlaXZlOiAiIDw8IGRvUmVjZWl2ZSA8PCBlbmRsOworICAgIH0KKyAgICAKKyAgICAvLyBSZXR1cm4gaW1tZWRpYXRlbHkgaWYgdGhlcmUgaXMgbm90aGluZyB0byBkby4KKyAgICBpZiAoKGJ3ci53cml0ZV9zaXplID09IDApICYmIChid3IucmVhZF9zaXplID09IDApKSByZXR1cm4gTk9fRVJST1I7CisgICAgCisgICAgYndyLndyaXRlX2NvbnN1bWVkID0gMDsKKyAgICBid3IucmVhZF9jb25zdW1lZCA9IDA7CisgICAgc3RhdHVzX3QgZXJyOworICAgIGRvIHsKKyAgICAgICAgSUZfTE9HX0NPTU1BTkRTKCkgeworICAgICAgICAgICAgYWxvZyA8PCAiQWJvdXQgdG8gcmVhZC93cml0ZSwgd3JpdGUgc2l6ZSA9ICIgPDwgbU91dC5kYXRhU2l6ZSgpIDw8IGVuZGw7CisgICAgICAgIH0KKyNpZiBkZWZpbmVkKEhBVkVfQU5EUk9JRF9PUykKKyAgICAgICAgaWYgKGlvY3RsKG1Qcm9jZXNzLT5tRHJpdmVyRkQsIEJJTkRFUl9XUklURV9SRUFELCAmYndyKSA+PSAwKQorICAgICAgICAgICAgZXJyID0gTk9fRVJST1I7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGVyciA9IC1lcnJubzsKKyNlbHNlCisgICAgICAgIGVyciA9IElOVkFMSURfT1BFUkFUSU9OOworI2VuZGlmCisgICAgICAgIElGX0xPR19DT01NQU5EUygpIHsKKyAgICAgICAgICAgIGFsb2cgPDwgIkZpbmlzaGVkIHJlYWQvd3JpdGUsIHdyaXRlIHNpemUgPSAiIDw8IG1PdXQuZGF0YVNpemUoKSA8PCBlbmRsOworICAgICAgICB9CisgICAgfSB3aGlsZSAoZXJyID09IC1FSU5UUik7CisgICAgCisgICAgSUZfTE9HX0NPTU1BTkRTKCkgeworICAgICAgICBhbG9nIDw8ICJPdXIgZXJyOiAiIDw8ICh2b2lkKillcnIgPDwgIiwgd3JpdGUgY29uc3VtZWQ6ICIKKyAgICAgICAgICAgIDw8IGJ3ci53cml0ZV9jb25zdW1lZCA8PCAiIChvZiAiIDw8IG1PdXQuZGF0YVNpemUoKQorCQkJPDwgIiksIHJlYWQgY29uc3VtZWQ6ICIgPDwgYndyLnJlYWRfY29uc3VtZWQgPDwgZW5kbDsKKyAgICB9CisKKyAgICBpZiAoZXJyID49IE5PX0VSUk9SKSB7CisgICAgICAgIGlmIChid3Iud3JpdGVfY29uc3VtZWQgPiAwKSB7CisgICAgICAgICAgICBpZiAoYndyLndyaXRlX2NvbnN1bWVkIDwgKHNzaXplX3QpbU91dC5kYXRhU2l6ZSgpKQorICAgICAgICAgICAgICAgIG1PdXQucmVtb3ZlKDAsIGJ3ci53cml0ZV9jb25zdW1lZCk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgbU91dC5zZXREYXRhU2l6ZSgwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYndyLnJlYWRfY29uc3VtZWQgPiAwKSB7CisgICAgICAgICAgICBtSW4uc2V0RGF0YVNpemUoYndyLnJlYWRfY29uc3VtZWQpOworICAgICAgICAgICAgbUluLnNldERhdGFQb3NpdGlvbigwKTsKKyAgICAgICAgfQorICAgICAgICBJRl9MT0dfQ09NTUFORFMoKSB7CisgICAgICAgICAgICBUZXh0T3V0cHV0OjpCdW5kbGUgX2IoYWxvZyk7CisgICAgICAgICAgICBhbG9nIDw8ICJSZW1haW5pbmcgZGF0YSBzaXplOiAiIDw8IG1PdXQuZGF0YVNpemUoKSA8PCBlbmRsOworICAgICAgICAgICAgYWxvZyA8PCAiUmVjZWl2ZWQgY29tbWFuZHMgZnJvbSBkcml2ZXI6ICIgPDwgaW5kZW50OworICAgICAgICAgICAgY29uc3Qgdm9pZCogY21kcyA9IG1Jbi5kYXRhKCk7CisgICAgICAgICAgICBjb25zdCB2b2lkKiBlbmQgPSBtSW4uZGF0YSgpICsgbUluLmRhdGFTaXplKCk7CisgICAgICAgICAgICBhbG9nIDw8IEhleER1bXAoY21kcywgbUluLmRhdGFTaXplKCkpIDw8IGVuZGw7CisgICAgICAgICAgICB3aGlsZSAoY21kcyA8IGVuZCkgY21kcyA9IHByaW50UmV0dXJuQ29tbWFuZChhbG9nLCBjbWRzKTsKKyAgICAgICAgICAgIGFsb2cgPDwgZGVkZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGVycjsKK30KKworc3RhdHVzX3QgSVBDVGhyZWFkU3RhdGU6OndyaXRlVHJhbnNhY3Rpb25EYXRhKGludDMyX3QgY21kLCB1aW50MzJfdCBiaW5kZXJGbGFncywKKyAgICBpbnQzMl90IGhhbmRsZSwgdWludDMyX3QgY29kZSwgY29uc3QgUGFyY2VsJiBkYXRhLCBzdGF0dXNfdCogc3RhdHVzQnVmZmVyKQoreworICAgIGJpbmRlcl90cmFuc2FjdGlvbl9kYXRhIHRyOworCisgICAgdHIudGFyZ2V0LmhhbmRsZSA9IGhhbmRsZTsKKyAgICB0ci5jb2RlID0gY29kZTsKKyAgICB0ci5mbGFncyA9IGJpbmRlckZsYWdzOworICAgIAorICAgIGNvbnN0IHN0YXR1c190IGVyciA9IGRhdGEuZXJyb3JDaGVjaygpOworICAgIGlmIChlcnIgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgdHIuZGF0YV9zaXplID0gZGF0YS5pcGNEYXRhU2l6ZSgpOworICAgICAgICB0ci5kYXRhLnB0ci5idWZmZXIgPSBkYXRhLmlwY0RhdGEoKTsKKyAgICAgICAgdHIub2Zmc2V0c19zaXplID0gZGF0YS5pcGNPYmplY3RzQ291bnQoKSpzaXplb2Yoc2l6ZV90KTsKKyAgICAgICAgdHIuZGF0YS5wdHIub2Zmc2V0cyA9IGRhdGEuaXBjT2JqZWN0cygpOworICAgIH0gZWxzZSBpZiAoc3RhdHVzQnVmZmVyKSB7CisgICAgICAgIHRyLmZsYWdzIHw9IFRGX1NUQVRVU19DT0RFOworICAgICAgICAqc3RhdHVzQnVmZmVyID0gZXJyOworICAgICAgICB0ci5kYXRhX3NpemUgPSBzaXplb2Yoc3RhdHVzX3QpOworICAgICAgICB0ci5kYXRhLnB0ci5idWZmZXIgPSBzdGF0dXNCdWZmZXI7CisgICAgICAgIHRyLm9mZnNldHNfc2l6ZSA9IDA7CisgICAgICAgIHRyLmRhdGEucHRyLm9mZnNldHMgPSBOVUxMOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAobUxhc3RFcnJvciA9IGVycik7CisgICAgfQorICAgIAorICAgIG1PdXQud3JpdGVJbnQzMihjbWQpOworICAgIG1PdXQud3JpdGUoJnRyLCBzaXplb2YodHIpKTsKKyAgICAKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3NwPEJCaW5kZXI+IHRoZV9jb250ZXh0X29iamVjdDsKKwordm9pZCBzZXRUaGVDb250ZXh0T2JqZWN0KHNwPEJCaW5kZXI+IG9iaikKK3sKKyAgICB0aGVfY29udGV4dF9vYmplY3QgPSBvYmo7Cit9CisKK3N0YXR1c190IElQQ1RocmVhZFN0YXRlOjpleGVjdXRlQ29tbWFuZChpbnQzMl90IGNtZCkKK3sKKyAgICBCQmluZGVyKiBvYmo7CisgICAgUmVmQmFzZTo6d2Vha3JlZl90eXBlKiByZWZzOworICAgIHN0YXR1c190IHJlc3VsdCA9IE5PX0VSUk9SOworICAgIAorICAgIHN3aXRjaCAoY21kKSB7CisgICAgY2FzZSBCUl9FUlJPUjoKKyAgICAgICAgcmVzdWx0ID0gbUluLnJlYWRJbnQzMigpOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBCUl9PSzoKKyAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgIGNhc2UgQlJfQUNRVUlSRToKKyAgICAgICAgcmVmcyA9IChSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgb2JqID0gKEJCaW5kZXIqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgTE9HX0FTU0VSVChyZWZzLT5yZWZCYXNlKCkgPT0gb2JqLAorICAgICAgICAgICAgICAgICAgICJCUl9BQ1FVSVJFOiBvYmplY3QgJXAgZG9lcyBub3QgbWF0Y2ggY29va2llICVwIChleHBlY3RlZCAlcCkiLAorICAgICAgICAgICAgICAgICAgIHJlZnMsIG9iaiwgcmVmcy0+cmVmQmFzZSgpKTsKKyAgICAgICAgb2JqLT5pbmNTdHJvbmcobVByb2Nlc3MuZ2V0KCkpOworICAgICAgICBJRl9MT0dfUkVNT1RFUkVGUygpIHsKKyAgICAgICAgICAgIExPR19SRU1PVEVSRUZTKCJCUl9BQ1FVSVJFIGZyb20gZHJpdmVyIG9uICVwIiwgb2JqKTsKKyAgICAgICAgICAgIG9iai0+cHJpbnRSZWZzKCk7CisgICAgICAgIH0KKyAgICAgICAgbU91dC53cml0ZUludDMyKEJDX0FDUVVJUkVfRE9ORSk7CisgICAgICAgIG1PdXQud3JpdGVJbnQzMigoaW50MzJfdClyZWZzKTsKKyAgICAgICAgbU91dC53cml0ZUludDMyKChpbnQzMl90KW9iaik7CisgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICBjYXNlIEJSX1JFTEVBU0U6CisgICAgICAgIHJlZnMgPSAoUmVmQmFzZTo6d2Vha3JlZl90eXBlKiltSW4ucmVhZEludDMyKCk7CisgICAgICAgIG9iaiA9IChCQmluZGVyKiltSW4ucmVhZEludDMyKCk7CisgICAgICAgIExPR19BU1NFUlQocmVmcy0+cmVmQmFzZSgpID09IG9iaiwKKyAgICAgICAgICAgICAgICAgICAiQlJfUkVMRUFTRTogb2JqZWN0ICVwIGRvZXMgbm90IG1hdGNoIGNvb2tpZSAlcCAoZXhwZWN0ZWQgJXApIiwKKyAgICAgICAgICAgICAgICAgICByZWZzLCBvYmosIHJlZnMtPnJlZkJhc2UoKSk7CisgICAgICAgIElGX0xPR19SRU1PVEVSRUZTKCkgeworICAgICAgICAgICAgTE9HX1JFTU9URVJFRlMoIkJSX1JFTEVBU0UgZnJvbSBkcml2ZXIgb24gJXAiLCBvYmopOworICAgICAgICAgICAgb2JqLT5wcmludFJlZnMoKTsKKyAgICAgICAgfQorICAgICAgICBtUGVuZGluZ1N0cm9uZ0RlcmVmcy5wdXNoKG9iaik7CisgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICBjYXNlIEJSX0lOQ1JFRlM6CisgICAgICAgIHJlZnMgPSAoUmVmQmFzZTo6d2Vha3JlZl90eXBlKiltSW4ucmVhZEludDMyKCk7CisgICAgICAgIG9iaiA9IChCQmluZGVyKiltSW4ucmVhZEludDMyKCk7CisgICAgICAgIHJlZnMtPmluY1dlYWsobVByb2Nlc3MuZ2V0KCkpOworICAgICAgICBtT3V0LndyaXRlSW50MzIoQkNfSU5DUkVGU19ET05FKTsKKyAgICAgICAgbU91dC53cml0ZUludDMyKChpbnQzMl90KXJlZnMpOworICAgICAgICBtT3V0LndyaXRlSW50MzIoKGludDMyX3Qpb2JqKTsKKyAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgIGNhc2UgQlJfREVDUkVGUzoKKyAgICAgICAgcmVmcyA9IChSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgb2JqID0gKEJCaW5kZXIqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgLy8gTk9URTogVGhpcyBhc3NlcnRpb24gaXMgbm90IHZhbGlkLCBiZWNhdXNlIHRoZSBvYmplY3QgbWF5IG5vCisgICAgICAgIC8vIGxvbmdlciBleGlzdCAodGh1cyB0aGUgKEJCaW5kZXIqKWNhc3QgYWJvdmUgcmVzdWx0aW5nIGluIGEgZGlmZmVyZW50CisgICAgICAgIC8vIG1lbW9yeSBhZGRyZXNzKS4KKyAgICAgICAgLy9MT0dfQVNTRVJUKHJlZnMtPnJlZkJhc2UoKSA9PSBvYmosCisgICAgICAgIC8vICAgICAgICAgICAiQlJfREVDUkVGUzogb2JqZWN0ICVwIGRvZXMgbm90IG1hdGNoIGNvb2tpZSAlcCAoZXhwZWN0ZWQgJXApIiwKKyAgICAgICAgLy8gICAgICAgICAgIHJlZnMsIG9iaiwgcmVmcy0+cmVmQmFzZSgpKTsKKyAgICAgICAgbVBlbmRpbmdXZWFrRGVyZWZzLnB1c2gocmVmcyk7CisgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICBjYXNlIEJSX0FUVEVNUFRfQUNRVUlSRToKKyAgICAgICAgcmVmcyA9IChSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgb2JqID0gKEJCaW5kZXIqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgIAorICAgICAgICB7CisgICAgICAgICAgICBjb25zdCBib29sIHN1Y2Nlc3MgPSByZWZzLT5hdHRlbXB0SW5jU3Ryb25nKG1Qcm9jZXNzLmdldCgpKTsKKyAgICAgICAgICAgIExPR19BU1NFUlQoc3VjY2VzcyAmJiByZWZzLT5yZWZCYXNlKCkgPT0gb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAiQlJfQVRURU1QVF9BQ1FVSVJFOiBvYmplY3QgJXAgZG9lcyBub3QgbWF0Y2ggY29va2llICVwIChleHBlY3RlZCAlcCkiLAorICAgICAgICAgICAgICAgICAgICAgICByZWZzLCBvYmosIHJlZnMtPnJlZkJhc2UoKSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIG1PdXQud3JpdGVJbnQzMihCQ19BQ1FVSVJFX1JFU1VMVCk7CisgICAgICAgICAgICBtT3V0LndyaXRlSW50MzIoKGludDMyX3Qpc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgCisgICAgY2FzZSBCUl9UUkFOU0FDVElPTjoKKyAgICAgICAgeworICAgICAgICAgICAgYmluZGVyX3RyYW5zYWN0aW9uX2RhdGEgdHI7CisgICAgICAgICAgICByZXN1bHQgPSBtSW4ucmVhZCgmdHIsIHNpemVvZih0cikpOworICAgICAgICAgICAgTE9HX0FTU0VSVChyZXN1bHQgPT0gTk9fRVJST1IsCisgICAgICAgICAgICAgICAgIk5vdCBlbm91Z2ggY29tbWFuZCBkYXRhIGZvciBiclRSQU5TQUNUSU9OIik7CisgICAgICAgICAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSBicmVhazsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgUGFyY2VsIGJ1ZmZlcjsKKyAgICAgICAgICAgIGJ1ZmZlci5pcGNTZXREYXRhUmVmZXJlbmNlKAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDhfdCo+KHRyLmRhdGEucHRyLmJ1ZmZlciksCisgICAgICAgICAgICAgICAgdHIuZGF0YV9zaXplLAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3Qgc2l6ZV90Kj4odHIuZGF0YS5wdHIub2Zmc2V0cyksCisgICAgICAgICAgICAgICAgdHIub2Zmc2V0c19zaXplL3NpemVvZihzaXplX3QpLCBmcmVlQnVmZmVyLCB0aGlzKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgY29uc3QgcGlkX3Qgb3JpZ1BpZCA9IG1DYWxsaW5nUGlkOworICAgICAgICAgICAgY29uc3QgdWlkX3Qgb3JpZ1VpZCA9IG1DYWxsaW5nVWlkOworICAgICAgICAgICAgCisgICAgICAgICAgICBtQ2FsbGluZ1BpZCA9IHRyLnNlbmRlcl9waWQ7CisgICAgICAgICAgICBtQ2FsbGluZ1VpZCA9IHRyLnNlbmRlcl9ldWlkOworICAgICAgICAgICAgCisgICAgICAgICAgICAvL0xPR0koIj4+Pj4gVFJBTlNBQ1QgZnJvbSBwaWQgJWQgdWlkICVkXG4iLCBtQ2FsbGluZ1BpZCwgbUNhbGxpbmdVaWQpOworICAgICAgICAgICAgCisgICAgICAgICAgICBQYXJjZWwgcmVwbHk7CisgICAgICAgICAgICBJRl9MT0dfVFJBTlNBQ1RJT05TKCkgeworICAgICAgICAgICAgICAgIFRleHRPdXRwdXQ6OkJ1bmRsZSBfYihhbG9nKTsKKyAgICAgICAgICAgICAgICBhbG9nIDw8ICJCUl9UUkFOU0FDVElPTiB0aHIgIiA8PCAodm9pZCopcHRocmVhZF9zZWxmKCkKKyAgICAgICAgICAgICAgICAgICAgPDwgIiAvIG9iaiAiIDw8IHRyLnRhcmdldC5wdHIgPDwgIiAvIGNvZGUgIgorICAgICAgICAgICAgICAgICAgICA8PCBUeXBlQ29kZSh0ci5jb2RlKSA8PCAiOiAiIDw8IGluZGVudCA8PCBidWZmZXIKKyAgICAgICAgICAgICAgICAgICAgPDwgZGVkZW50IDw8IGVuZGwKKyAgICAgICAgICAgICAgICAgICAgPDwgIkRhdGEgYWRkciA9ICIKKyAgICAgICAgICAgICAgICAgICAgPDwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OF90Kj4odHIuZGF0YS5wdHIuYnVmZmVyKQorICAgICAgICAgICAgICAgICAgICA8PCAiLCBvZmZzZXRzIGFkZHI9IgorICAgICAgICAgICAgICAgICAgICA8PCByZWludGVycHJldF9jYXN0PGNvbnN0IHNpemVfdCo+KHRyLmRhdGEucHRyLm9mZnNldHMpIDw8IGVuZGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodHIudGFyZ2V0LnB0cikgeworICAgICAgICAgICAgICAgIHNwPEJCaW5kZXI+IGIoKEJCaW5kZXIqKXRyLmNvb2tpZSk7CisgICAgICAgICAgICAgICAgY29uc3Qgc3RhdHVzX3QgZXJyb3IgPSBiLT50cmFuc2FjdCh0ci5jb2RlLCBidWZmZXIsICZyZXBseSwgMCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yIDwgTk9fRVJST1IpIHJlcGx5LnNldEVycm9yKGVycm9yKTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29uc3Qgc3RhdHVzX3QgZXJyb3IgPSB0aGVfY29udGV4dF9vYmplY3QtPnRyYW5zYWN0KHRyLmNvZGUsIGJ1ZmZlciwgJnJlcGx5LCAwKTsKKyAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBOT19FUlJPUikgcmVwbHkuc2V0RXJyb3IoZXJyb3IpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICAvL0xPR0koIjw8PDwgVFJBTlNBQ1QgZnJvbSBwaWQgJWQgcmVzdG9yZSBwaWQgJWQgdWlkICVkXG4iLAorICAgICAgICAgICAgLy8gICAgIG1DYWxsaW5nUGlkLCBvcmlnUGlkLCBvcmlnVWlkKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKCh0ci5mbGFncyAmIFRGX09ORV9XQVkpID09IDApIHsKKyAgICAgICAgICAgICAgICBMT0dfT05FV0FZKCJTZW5kaW5nIHJlcGx5IHRvICVkISIsIG1DYWxsaW5nUGlkKTsKKyAgICAgICAgICAgICAgICBzZW5kUmVwbHkocmVwbHksIDApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dfT05FV0FZKCJOT1Qgc2VuZGluZyByZXBseSB0byAlZCEiLCBtQ2FsbGluZ1BpZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIG1DYWxsaW5nUGlkID0gb3JpZ1BpZDsKKyAgICAgICAgICAgIG1DYWxsaW5nVWlkID0gb3JpZ1VpZDsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgSUZfTE9HX1RSQU5TQUNUSU9OUygpIHsKKyAgICAgICAgICAgICAgICBUZXh0T3V0cHV0OjpCdW5kbGUgX2IoYWxvZyk7CisgICAgICAgICAgICAgICAgYWxvZyA8PCAiQkNfUkVQTFkgdGhyICIgPDwgKHZvaWQqKXB0aHJlYWRfc2VsZigpIDw8ICIgLyBvYmogIgorICAgICAgICAgICAgICAgICAgICA8PCB0ci50YXJnZXQucHRyIDw8ICI6ICIgPDwgaW5kZW50IDw8IHJlcGx5IDw8IGRlZGVudCA8PCBlbmRsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgCisgICAgY2FzZSBCUl9ERUFEX0JJTkRFUjoKKyAgICAgICAgeworICAgICAgICAgICAgQnBCaW5kZXIgKnByb3h5ID0gKEJwQmluZGVyKiltSW4ucmVhZEludDMyKCk7CisgICAgICAgICAgICBwcm94eS0+c2VuZE9iaXR1YXJ5KCk7CisgICAgICAgICAgICBtT3V0LndyaXRlSW50MzIoQkNfREVBRF9CSU5ERVJfRE9ORSk7CisgICAgICAgICAgICBtT3V0LndyaXRlSW50MzIoKGludDMyX3QpcHJveHkpOworICAgICAgICB9IGJyZWFrOworICAgICAgICAKKyAgICBjYXNlIEJSX0NMRUFSX0RFQVRIX05PVElGSUNBVElPTl9ET05FOgorICAgICAgICB7CisgICAgICAgICAgICBCcEJpbmRlciAqcHJveHkgPSAoQnBCaW5kZXIqKW1Jbi5yZWFkSW50MzIoKTsKKyAgICAgICAgICAgIHByb3h5LT5nZXRXZWFrUmVmcygpLT5kZWNXZWFrKHByb3h5KTsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBCUl9GSU5JU0hFRDoKKyAgICAgICAgcmVzdWx0ID0gVElNRURfT1VUOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBCUl9OT09QOgorICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBCUl9TUEFXTl9MT09QRVI6CisgICAgICAgIG1Qcm9jZXNzLT5zcGF3blBvb2xlZFRocmVhZChmYWxzZSk7CisgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICBkZWZhdWx0OgorICAgICAgICBwcmludGYoIioqKiBCQUQgQ09NTUFORCAlZCByZWNlaXZlZCBmcm9tIEJpbmRlciBkcml2ZXJcbiIsIGNtZCk7CisgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgbUxhc3RFcnJvciA9IHJlc3VsdDsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6dGhyZWFkRGVzdHJ1Y3Rvcih2b2lkICpzdCkKK3sKKwlJUENUaHJlYWRTdGF0ZSogY29uc3Qgc2VsZiA9IHN0YXRpY19jYXN0PElQQ1RocmVhZFN0YXRlKj4oc3QpOworCWlmIChzZWxmKSB7CisJCXNlbGYtPmZsdXNoQ29tbWFuZHMoKTsKKyNpZiBkZWZpbmVkKEhBVkVfQU5EUk9JRF9PUykKKyAgICAgICAgaW9jdGwoc2VsZi0+bVByb2Nlc3MtPm1Ecml2ZXJGRCwgQklOREVSX1RIUkVBRF9FWElULCAwKTsKKyNlbmRpZgorCQlkZWxldGUgc2VsZjsKKwl9Cit9CisKKwordm9pZCBJUENUaHJlYWRTdGF0ZTo6ZnJlZUJ1ZmZlcihQYXJjZWwqIHBhcmNlbCwgY29uc3QgdWludDhfdCogZGF0YSwgc2l6ZV90IGRhdGFTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXplX3QqIG9iamVjdHMsIHNpemVfdCBvYmplY3RzU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY29va2llKQoreworICAgIC8vTE9HSSgiRnJlZWluZyBwYXJjZWwgJXAiLCAmcGFyY2VsKTsKKyAgICBJRl9MT0dfQ09NTUFORFMoKSB7CisgICAgICAgIGFsb2cgPDwgIldyaXRpbmcgQkNfRlJFRV9CVUZGRVIgZm9yICIgPDwgZGF0YSA8PCBlbmRsOworICAgIH0KKyAgICBMT0dfQVNTRVJUKGRhdGEgIT0gTlVMTCwgIkNhbGxlZCB3aXRoIE5VTEwgZGF0YSIpOworICAgIGlmIChwYXJjZWwgIT0gTlVMTCkgcGFyY2VsLT5jbG9zZUZpbGVEZXNjcmlwdG9ycygpOworICAgIElQQ1RocmVhZFN0YXRlKiBzdGF0ZSA9IHNlbGYoKTsKKyAgICBzdGF0ZS0+bU91dC53cml0ZUludDMyKEJDX0ZSRUVfQlVGRkVSKTsKKyAgICBzdGF0ZS0+bU91dC53cml0ZUludDMyKChpbnQzMl90KWRhdGEpOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuY3BwIGIvbGlicy91dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMWQzOGYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL0lQZXJtaXNzaW9uQ29udHJvbGxlci5jcHAKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiUGVybWlzc2lvbkNvbnRyb2xsZXIiCisKKyNpbmNsdWRlIDx1dGlscy9JUGVybWlzc2lvbkNvbnRyb2xsZXIuaD4KKworI2luY2x1ZGUgPHV0aWxzL0RlYnVnLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9TdGF0aWMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEJwUGVybWlzc2lvbkNvbnRyb2xsZXIgOiBwdWJsaWMgQnBJbnRlcmZhY2U8SVBlcm1pc3Npb25Db250cm9sbGVyPgoreworcHVibGljOgorICAgIEJwUGVybWlzc2lvbkNvbnRyb2xsZXIoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SVBlcm1pc3Npb25Db250cm9sbGVyPihpbXBsKQorICAgIHsKKyAgICB9CisgICAgICAgIAorICAgIHZpcnR1YWwgYm9vbCBjaGVja1Blcm1pc3Npb24oY29uc3QgU3RyaW5nMTYmIHBlcm1pc3Npb24sIGludDMyX3QgcGlkLCBpbnQzMl90IHVpZCkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElQZXJtaXNzaW9uQ29udHJvbGxlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cmluZzE2KHBlcm1pc3Npb24pOworICAgICAgICBkYXRhLndyaXRlSW50MzIocGlkKTsKKyAgICAgICAgZGF0YS53cml0ZUludDMyKHVpZCk7CisgICAgICAgIHJlbW90ZSgpLT50cmFuc2FjdChDSEVDS19QRVJNSVNTSU9OX1RSQU5TQUNUSU9OLCBkYXRhLCAmcmVwbHkpOworICAgICAgICAvLyBmYWlsIG9uIGV4Y2VwdGlvbgorICAgICAgICBpZiAocmVwbHkucmVhZEludDMyKCkgIT0gMCkgcmV0dXJuIDA7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkSW50MzIoKSAhPSAwOworICAgIH0KK307CisKK0lNUExFTUVOVF9NRVRBX0lOVEVSRkFDRShQZXJtaXNzaW9uQ29udHJvbGxlciwgImFuZHJvaWQub3MuSVBlcm1pc3Npb25Db250cm9sbGVyIik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBDSEVDS19JTlRFUkZBQ0UoaW50ZXJmYWNlLCBkYXRhLCByZXBseSkgXAorICAgICAgICBkbyB7IGlmICghZGF0YS5lbmZvcmNlSW50ZXJmYWNlKGludGVyZmFjZTo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKSkgeyBcCisgICAgICAgICAgICBMT0dXKCJDYWxsIGluY29ycmVjdGx5IHJvdXRlZCB0byAiICNpbnRlcmZhY2UpOyBcCisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9ERU5JRUQ7IFwKKyAgICAgICAgfSB9IHdoaWxlICgwKQorCitzdGF0dXNfdCBCblBlcm1pc3Npb25Db250cm9sbGVyOjpvblRyYW5zYWN0KAorICAgIHVpbnQzMl90IGNvZGUsIGNvbnN0IFBhcmNlbCYgZGF0YSwgUGFyY2VsKiByZXBseSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgLy9wcmludGYoIlBlcm1pc3Npb25Db250cm9sbGVyIHJlY2VpdmVkOiAiKTsgZGF0YS5wcmludCgpOworICAgIHN3aXRjaChjb2RlKSB7CisgICAgICAgIGNhc2UgQ0hFQ0tfUEVSTUlTU0lPTl9UUkFOU0FDVElPTjogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElQZXJtaXNzaW9uQ29udHJvbGxlciwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgU3RyaW5nMTYgcGVybWlzc2lvbiA9IGRhdGEucmVhZFN0cmluZzE2KCk7CisgICAgICAgICAgICBpbnQzMl90IHBpZCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBpbnQzMl90IHVpZCA9IGRhdGEucmVhZEludDMyKCk7CisgICAgICAgICAgICBib29sIHJlcyA9IGNoZWNrUGVybWlzc2lvbihwZXJtaXNzaW9uLCBwaWQsIHVpZCk7CisgICAgICAgICAgICAvLyB3cml0ZSBleGNlcHRpb24KKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKDApOworICAgICAgICAgICAgcmVwbHktPndyaXRlSW50MzIocmVzID8gMSA6IDApOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJCaW5kZXI6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKKyAgICB9Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmNwcCBiL2xpYnMvdXRpbHMvSVNlcnZpY2VNYW5hZ2VyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmVlYWRkCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9JU2VydmljZU1hbmFnZXIuY3BwCkBAIC0wLDAgKzEsMjMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTZXJ2aWNlTWFuYWdlciIKKworI2luY2x1ZGUgPHV0aWxzL0lTZXJ2aWNlTWFuYWdlci5oPgorCisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1BhcmNlbC5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1dGlscy9TeXN0ZW1DbG9jay5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9TdGF0aWMuaD4KKworI2luY2x1ZGUgPHVuaXN0ZC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3NwPElTZXJ2aWNlTWFuYWdlcj4gZGVmYXVsdFNlcnZpY2VNYW5hZ2VyKCkKK3sKKyAgICBpZiAoZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlciAhPSBOVUxMKSByZXR1cm4gZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlcjsKKyAgICAKKyAgICB7CisgICAgICAgIEF1dG9NdXRleCBfbChnRGVmYXVsdFNlcnZpY2VNYW5hZ2VyTG9jayk7CisgICAgICAgIGlmIChnRGVmYXVsdFNlcnZpY2VNYW5hZ2VyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGdEZWZhdWx0U2VydmljZU1hbmFnZXIgPSBpbnRlcmZhY2VfY2FzdDxJU2VydmljZU1hbmFnZXI+KAorICAgICAgICAgICAgICAgIFByb2Nlc3NTdGF0ZTo6c2VsZigpLT5nZXRDb250ZXh0T2JqZWN0KE5VTEwpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICByZXR1cm4gZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlcjsKK30KKworYm9vbCBjaGVja0NhbGxpbmdQZXJtaXNzaW9uKGNvbnN0IFN0cmluZzE2JiBwZXJtaXNzaW9uKQoreworICAgIHJldHVybiBjaGVja0NhbGxpbmdQZXJtaXNzaW9uKHBlcm1pc3Npb24sIE5VTEwsIE5VTEwpOworfQorCitzdGF0aWMgU3RyaW5nMTYgX3Blcm1pc3Npb24oInBlcm1pc3Npb24iKTsKKworYm9vbCBjaGVja0NhbGxpbmdQZXJtaXNzaW9uKGNvbnN0IFN0cmluZzE2JiBwZXJtaXNzaW9uLCBpbnQzMl90KiBvdXRQaWQsIGludDMyX3QqIG91dFVpZCkKK3sKKyAgICBJUENUaHJlYWRTdGF0ZSogaXBjU3RhdGUgPSBJUENUaHJlYWRTdGF0ZTo6c2VsZigpOworICAgIGludDMyX3QgcGlkID0gaXBjU3RhdGUtPmdldENhbGxpbmdQaWQoKTsKKyAgICBpbnQzMl90IHVpZCA9IGlwY1N0YXRlLT5nZXRDYWxsaW5nVWlkKCk7CisgICAgaWYgKG91dFBpZCkgKm91dFBpZCA9IHBpZDsKKyAgICBpZiAob3V0VWlkKSAqb3V0VWlkPSB1aWQ7CisgICAgCisgICAgc3A8SVBlcm1pc3Npb25Db250cm9sbGVyPiBwYzsKKyAgICBnRGVmYXVsdFNlcnZpY2VNYW5hZ2VyTG9jay5sb2NrKCk7CisgICAgcGMgPSBnUGVybWlzc2lvbkNvbnRyb2xsZXI7CisgICAgZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlckxvY2sudW5sb2NrKCk7CisgICAgCisgICAgaW50NjRfdCBzdGFydFRpbWUgPSAwOworCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgaWYgKHBjICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGJvb2wgcmVzID0gcGMtPmNoZWNrUGVybWlzc2lvbihwZXJtaXNzaW9uLCBwaWQsIHVpZCk7CisgICAgICAgICAgICBpZiAocmVzKSB7CisgICAgICAgICAgICAgICAgaWYgKHN0YXJ0VGltZSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIExPR0koIkNoZWNrIHBhc3NlZCBhZnRlciAlZCBzZWNvbmRzIGZvciAlcyBmcm9tIHVpZD0lZCBwaWQ9JWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpKCh1cHRpbWVNaWxsaXMoKS1zdGFydFRpbWUpLzEwMDApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocGVybWlzc2lvbikuc3RyaW5nKCksIHVpZCwgcGlkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gSXMgdGhpcyBhIHBlcm1pc3Npb24gZmFpbHVyZSwgb3IgZGlkIHRoZSBjb250cm9sbGVyIGdvIGF3YXk/CisgICAgICAgICAgICBpZiAocGMtPmFzQmluZGVyKCktPmlzQmluZGVyQWxpdmUoKSkgeworICAgICAgICAgICAgICAgIExPR1coIlBlcm1pc3Npb24gZmFpbHVyZTogJXMgZnJvbSB1aWQ9JWQgcGlkPSVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocGVybWlzc2lvbikuc3RyaW5nKCksIHVpZCwgcGlkKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIE9iamVjdCBpcyBkZWFkIQorICAgICAgICAgICAgZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlckxvY2subG9jaygpOworICAgICAgICAgICAgaWYgKGdQZXJtaXNzaW9uQ29udHJvbGxlciA9PSBwYykgeworICAgICAgICAgICAgICAgIGdQZXJtaXNzaW9uQ29udHJvbGxlciA9IE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBnRGVmYXVsdFNlcnZpY2VNYW5hZ2VyTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIAorICAgICAgICAvLyBOZWVkIHRvIHJldHJpZXZlIHRoZSBwZXJtaXNzaW9uIGNvbnRyb2xsZXIuCisgICAgICAgIHNwPElCaW5kZXI+IGJpbmRlciA9IGRlZmF1bHRTZXJ2aWNlTWFuYWdlcigpLT5jaGVja1NlcnZpY2UoX3Blcm1pc3Npb24pOworICAgICAgICBpZiAoYmluZGVyID09IE5VTEwpIHsKKyAgICAgICAgICAgIC8vIFdhaXQgZm9yIHRoZSBwZXJtaXNzaW9uIGNvbnRyb2xsZXIgdG8gY29tZSBiYWNrLi4uCisgICAgICAgICAgICBpZiAoc3RhcnRUaW1lID09IDApIHsKKyAgICAgICAgICAgICAgICBzdGFydFRpbWUgPSB1cHRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgICAgICBMT0dJKCJXYWl0aW5nIHRvIGNoZWNrIHBlcm1pc3Npb24gJXMgZnJvbSB1aWQ9JWQgcGlkPSVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocGVybWlzc2lvbikuc3RyaW5nKCksIHVpZCwgcGlkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNsZWVwKDEpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcGMgPSBpbnRlcmZhY2VfY2FzdDxJUGVybWlzc2lvbkNvbnRyb2xsZXI+KGJpbmRlcik7CisgICAgICAgICAgICAvLyBJbnN0YWxsIHRoZSBuZXcgcGVybWlzc2lvbiBjb250cm9sbGVyLCBhbmQgdHJ5IGFnYWluLiAgICAgICAgCisgICAgICAgICAgICBnRGVmYXVsdFNlcnZpY2VNYW5hZ2VyTG9jay5sb2NrKCk7CisgICAgICAgICAgICBnUGVybWlzc2lvbkNvbnRyb2xsZXIgPSBwYzsKKyAgICAgICAgICAgIGdEZWZhdWx0U2VydmljZU1hbmFnZXJMb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIEJwU2VydmljZU1hbmFnZXIgOiBwdWJsaWMgQnBJbnRlcmZhY2U8SVNlcnZpY2VNYW5hZ2VyPgoreworcHVibGljOgorICAgIEJwU2VydmljZU1hbmFnZXIoY29uc3Qgc3A8SUJpbmRlcj4mIGltcGwpCisgICAgICAgIDogQnBJbnRlcmZhY2U8SVNlcnZpY2VNYW5hZ2VyPihpbXBsKQorICAgIHsKKyAgICB9CisgICAgICAgIAorICAgIHZpcnR1YWwgc3A8SUJpbmRlcj4gZ2V0U2VydmljZShjb25zdCBTdHJpbmcxNiYgbmFtZSkgY29uc3QKKyAgICB7CisgICAgICAgIHVuc2lnbmVkIG47CisgICAgICAgIGZvciAobiA9IDA7IG4gPCA1OyBuKyspeworICAgICAgICAgICAgc3A8SUJpbmRlcj4gc3ZjID0gY2hlY2tTZXJ2aWNlKG5hbWUpOworICAgICAgICAgICAgaWYgKHN2YyAhPSBOVUxMKSByZXR1cm4gc3ZjOworICAgICAgICAgICAgTE9HSSgiV2FpdGluZyBmb3Igc2V2aWNlICVzLi4uXG4iLCBTdHJpbmc4KG5hbWUpLnN0cmluZygpKTsKKyAgICAgICAgICAgIHNsZWVwKDEpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAKKyAgICB2aXJ0dWFsIHNwPElCaW5kZXI+IGNoZWNrU2VydmljZSggY29uc3QgU3RyaW5nMTYmIG5hbWUpIGNvbnN0CisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIGRhdGEud3JpdGVJbnRlcmZhY2VUb2tlbihJU2VydmljZU1hbmFnZXI6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGRhdGEud3JpdGVTdHJpbmcxNihuYW1lKTsKKyAgICAgICAgcmVtb3RlKCktPnRyYW5zYWN0KENIRUNLX1NFUlZJQ0VfVFJBTlNBQ1RJT04sIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiByZXBseS5yZWFkU3Ryb25nQmluZGVyKCk7CisgICAgfQorCisgICAgdmlydHVhbCBzdGF0dXNfdCBhZGRTZXJ2aWNlKGNvbnN0IFN0cmluZzE2JiBuYW1lLCBjb25zdCBzcDxJQmluZGVyPiYgc2VydmljZSkKKyAgICB7CisgICAgICAgIFBhcmNlbCBkYXRhLCByZXBseTsKKyAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTZXJ2aWNlTWFuYWdlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cmluZzE2KG5hbWUpOworICAgICAgICBkYXRhLndyaXRlU3Ryb25nQmluZGVyKHNlcnZpY2UpOworICAgICAgICBzdGF0dXNfdCBlcnIgPSByZW1vdGUoKS0+dHJhbnNhY3QoQUREX1NFUlZJQ0VfVFJBTlNBQ1RJT04sIGRhdGEsICZyZXBseSk7CisgICAgICAgIHJldHVybiBlcnIgPT0gTk9fRVJST1IgPyByZXBseS5yZWFkSW50MzIoKSA6IGVycjsKKyAgICB9CisKKyAgICB2aXJ0dWFsIFZlY3RvcjxTdHJpbmcxNj4gbGlzdFNlcnZpY2VzKCkKKyAgICB7CisgICAgICAgIFZlY3RvcjxTdHJpbmcxNj4gcmVzOworICAgICAgICBpbnQgbiA9IDA7CisKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgUGFyY2VsIGRhdGEsIHJlcGx5OworICAgICAgICAgICAgZGF0YS53cml0ZUludGVyZmFjZVRva2VuKElTZXJ2aWNlTWFuYWdlcjo6Z2V0SW50ZXJmYWNlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgICAgIGRhdGEud3JpdGVJbnQzMihuKyspOworICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0gcmVtb3RlKCktPnRyYW5zYWN0KExJU1RfU0VSVklDRVNfVFJBTlNBQ1RJT04sIGRhdGEsICZyZXBseSk7CisgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgcmVzLmFkZChyZXBseS5yZWFkU3RyaW5nMTYoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9OworCitJTVBMRU1FTlRfTUVUQV9JTlRFUkZBQ0UoU2VydmljZU1hbmFnZXIsICJhbmRyb2lkLm9zLklTZXJ2aWNlTWFuYWdlciIpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgQ0hFQ0tfSU5URVJGQUNFKGludGVyZmFjZSwgZGF0YSwgcmVwbHkpIFwKKyAgICAgICAgZG8geyBpZiAoIWRhdGEuZW5mb3JjZUludGVyZmFjZShpbnRlcmZhY2U6OmdldEludGVyZmFjZURlc2NyaXB0b3IoKSkpIHsgXAorICAgICAgICAgICAgTE9HVygiQ2FsbCBpbmNvcnJlY3RseSByb3V0ZWQgdG8gIiAjaW50ZXJmYWNlKTsgXAorICAgICAgICAgICAgcmV0dXJuIFBFUk1JU1NJT05fREVOSUVEOyBcCisgICAgICAgIH0gfSB3aGlsZSAoMCkKKworc3RhdHVzX3QgQm5TZXJ2aWNlTWFuYWdlcjo6b25UcmFuc2FjdCgKKyAgICB1aW50MzJfdCBjb2RlLCBjb25zdCBQYXJjZWwmIGRhdGEsIFBhcmNlbCogcmVwbHksIHVpbnQzMl90IGZsYWdzKQoreworICAgIC8vcHJpbnRmKCJTZXJ2aWNlTWFuYWdlciByZWNlaXZlZDogIik7IGRhdGEucHJpbnQoKTsKKyAgICBzd2l0Y2goY29kZSkgeworICAgICAgICBjYXNlIEdFVF9TRVJWSUNFX1RSQU5TQUNUSU9OOiB7CisgICAgICAgICAgICBDSEVDS19JTlRFUkZBQ0UoSVNlcnZpY2VNYW5hZ2VyLCBkYXRhLCByZXBseSk7CisgICAgICAgICAgICBTdHJpbmcxNiB3aGljaCA9IGRhdGEucmVhZFN0cmluZzE2KCk7CisgICAgICAgICAgICBzcDxJQmluZGVyPiBiID0gY29uc3RfY2FzdDxCblNlcnZpY2VNYW5hZ2VyKj4odGhpcyktPmdldFNlcnZpY2Uod2hpY2gpOworICAgICAgICAgICAgcmVwbHktPndyaXRlU3Ryb25nQmluZGVyKGIpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIENIRUNLX1NFUlZJQ0VfVFJBTlNBQ1RJT046IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJU2VydmljZU1hbmFnZXIsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIFN0cmluZzE2IHdoaWNoID0gZGF0YS5yZWFkU3RyaW5nMTYoKTsKKyAgICAgICAgICAgIHNwPElCaW5kZXI+IGIgPSBjb25zdF9jYXN0PEJuU2VydmljZU1hbmFnZXIqPih0aGlzKS0+Y2hlY2tTZXJ2aWNlKHdoaWNoKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZVN0cm9uZ0JpbmRlcihiKTsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfSBicmVhazsKKyAgICAgICAgY2FzZSBBRERfU0VSVklDRV9UUkFOU0FDVElPTjogeworICAgICAgICAgICAgQ0hFQ0tfSU5URVJGQUNFKElTZXJ2aWNlTWFuYWdlciwgZGF0YSwgcmVwbHkpOworICAgICAgICAgICAgU3RyaW5nMTYgd2hpY2ggPSBkYXRhLnJlYWRTdHJpbmcxNigpOworICAgICAgICAgICAgc3A8SUJpbmRlcj4gYiA9IGRhdGEucmVhZFN0cm9uZ0JpbmRlcigpOworICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0gYWRkU2VydmljZSh3aGljaCwgYik7CisgICAgICAgICAgICByZXBseS0+d3JpdGVJbnQzMihlcnIpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIExJU1RfU0VSVklDRVNfVFJBTlNBQ1RJT046IHsKKyAgICAgICAgICAgIENIRUNLX0lOVEVSRkFDRShJU2VydmljZU1hbmFnZXIsIGRhdGEsIHJlcGx5KTsKKyAgICAgICAgICAgIFZlY3RvcjxTdHJpbmcxNj4gbGlzdCA9IGxpc3RTZXJ2aWNlcygpOworICAgICAgICAgICAgY29uc3Qgc2l6ZV90IE4gPSBsaXN0LnNpemUoKTsKKyAgICAgICAgICAgIHJlcGx5LT53cml0ZUludDMyKE4pOworICAgICAgICAgICAgZm9yIChzaXplX3QgaT0wOyBpPE47IGkrKykgeworICAgICAgICAgICAgICAgIHJlcGx5LT53cml0ZVN0cmluZzE2KGxpc3RbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIEJCaW5kZXI6Om9uVHJhbnNhY3QoY29kZSwgZGF0YSwgcmVwbHksIGZsYWdzKTsKKyAgICB9Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvSW5ldEFkZHJlc3MuY3BwIGIvbGlicy91dGlscy9JbmV0QWRkcmVzcy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzlhMGE2OAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvSW5ldEFkZHJlc3MuY3BwCkBAIC0wLDAgKzEsMjM2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIEludGVybmV0IGFkZHJlc3MgY2xhc3MuCisvLworI2lmZGVmIEhBVkVfV0lOU09DSworIyBpbmNsdWRlIDx3aW5zb2NrMi5oPgorI2Vsc2UKKyMgaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjIGluY2x1ZGUgPHN5cy9zb2NrZXQuaD4KKyMgaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorLy8jIGluY2x1ZGUgPGFycGEvaW5ldC5oPgorIyBpbmNsdWRlIDxuZXRkYi5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDx1dGlscy9pbmV0X2FkZHJlc3MuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgSW5ldEFkZHJlc3MKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICovCisKKy8vIGxvY2sgZm9yIHRoZSBuZXh0IGNvdXBsZSBvZiBmdW5jdGlvbnM7IGNvdWxkIHR1Y2sgaW50byBJbmV0QWRkcmVzcworc3RhdGljIE11dGV4KiAgIGdHSEJOTG9jazsKKworLyoKKyAqIExvY2svdW5sb2NrIGFjY2VzcyB0byB0aGUgaG9zdGVudCBzdHJ1Y3QgcmV0dXJuZWQgYnkgZ2V0aG9zdGJ5bmFtZSgpLgorICovCitzdGF0aWMgaW5saW5lIHZvaWQgbG9ja19nZXRob3N0YnluYW1lKHZvaWQpCit7CisgICAgaWYgKGdHSEJOTG9jayA9PSBOVUxMKQorICAgICAgICBnR0hCTkxvY2sgPSBuZXcgTXV0ZXg7CisgICAgZ0dIQk5Mb2NrLT5sb2NrKCk7Cit9CitzdGF0aWMgaW5saW5lIHZvaWQgdW5sb2NrX2dldGhvc3RieW5hbWUodm9pZCkKK3sKKyAgICBhc3NlcnQoZ0dIQk5Mb2NrICE9IE5VTEwpOworICAgIGdHSEJOTG9jay0+dW5sb2NrKCk7Cit9CisKKworLyoKKyAqIENvbnN0cnVjdG9yIC0tIGp1c3QgaW5pdCBtZW1iZXJzLiAgVGhpcyBpcyBwcml2YXRlIHNvIHRoYXQgY2FsbGVycworICogYXJlIHJlcXVpcmVkIHRvIHVzZSBnZXRCeU5hbWUoKS4KKyAqLworSW5ldEFkZHJlc3M6OkluZXRBZGRyZXNzKHZvaWQpCisgICAgOiBtQWRkcmVzcyhOVUxMKSwgbUxlbmd0aCgtMSksIG1OYW1lKE5VTEwpCit7Cit9CisKKy8qCisgKiBEZXN0cnVjdG9yIC0tIGZyZWUgYWRkcmVzcyBzdG9yYWdlLgorICovCitJbmV0QWRkcmVzczo6fkluZXRBZGRyZXNzKHZvaWQpCit7CisgICAgZGVsZXRlW10gKGNoYXIqKSBtQWRkcmVzczsKKyAgICBkZWxldGVbXSBtTmFtZTsKK30KKworLyoKKyAqIENvcHkgY29uc3RydWN0b3IuCisgKi8KK0luZXRBZGRyZXNzOjpJbmV0QWRkcmVzcyhjb25zdCBJbmV0QWRkcmVzcyYgb3JpZykKK3sKKyAgICAqdGhpcyA9IG9yaWc7ICAgLy8gdXNlIGFzc2lnbm1lbnQgY29kZQorfQorCisvKgorICogQXNzaWdubWVudCBvcGVyYXRvci4KKyAqLworSW5ldEFkZHJlc3MmIEluZXRBZGRyZXNzOjpvcGVyYXRvcj0oY29uc3QgSW5ldEFkZHJlc3MmIGFkZHIpCit7CisgICAgLy8gaGFuZGxlIHNlbGYtYXNzaWdubWVudAorICAgIGlmICh0aGlzID09ICZhZGRyKQorICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgLy8gY29weSBtTGVuZ3RoIGFuZCBtQWRkcmVzcworICAgIG1MZW5ndGggPSBhZGRyLm1MZW5ndGg7CisgICAgaWYgKG1MZW5ndGggPiAwKSB7CisgICAgICAgIG1BZGRyZXNzID0gbmV3IGNoYXJbbUxlbmd0aF07CisgICAgICAgIG1lbWNweShtQWRkcmVzcywgYWRkci5tQWRkcmVzcywgbUxlbmd0aCk7CisgICAgICAgIExPRyhMT0dfREVCVUcsICJzb2NrZXQiLAorICAgICAgICAgICAgIkhFWTogY29waWVkICVkIGJ5dGVzIGluIGFzc2lnbm1lbnQgb3BlcmF0b3JcbiIsIG1MZW5ndGgpOworICAgIH0gZWxzZSB7CisgICAgICAgIG1BZGRyZXNzID0gTlVMTDsKKyAgICB9CisgICAgLy8gY29weSBtTmFtZQorICAgIG1OYW1lID0gbmV3IGNoYXJbc3RybGVuKGFkZHIubU5hbWUpKzFdOworICAgIHN0cmNweShtTmFtZSwgYWRkci5tTmFtZSk7CisKKyAgICByZXR1cm4gKnRoaXM7Cit9CisKKy8qCisgKiBDcmVhdGUgYSBuZXcgb2JqZWN0IGZyb20gYSBuYW1lIG9yIGEgZG90dGVkLW51bWJlciBJUCBub3RhdGlvbi4KKyAqCisgKiBSZXR1cm5zIE5VTEwgb24gZmFpbHVyZS4KKyAqLworSW5ldEFkZHJlc3MqCitJbmV0QWRkcmVzczo6Z2V0QnlOYW1lKGNvbnN0IGNoYXIqIGhvc3QpCit7CisgICAgSW5ldEFkZHJlc3MqIG5ld0FkZHIgPSBOVUxMOworICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZGRyOworICAgIHN0cnVjdCBob3N0ZW50KiBoZTsKKyAgICBEdXJhdGlvblRpbWVyIGhvc3RUaW1lciwgbG9ja1RpbWVyOworCisgICAgLy8gZ2V0aG9zdGJ5bmFtZSgpIGlzbid0IHJlZW50cmFudCwgc28gd2UgbmVlZCB0byBsb2NrIHRoaW5ncyB1bnRpbAorICAgIC8vIHdlIGNhbiBjb3B5IHRoZSBkYXRhIG91dC4KKyAgICBsb2NrVGltZXIuc3RhcnQoKTsKKyAgICBsb2NrX2dldGhvc3RieW5hbWUoKTsKKyAgICBob3N0VGltZXIuc3RhcnQoKTsKKworICAgIGhlID0gZ2V0aG9zdGJ5bmFtZShob3N0KTsKKyAgICBpZiAoaGUgPT0gTlVMTCkgeworICAgICAgICBMT0coTE9HX1dBUk4sICJzb2NrZXQiLCAiV0FSTklORzogY2Fubm90IHJlc29sdmUgaG9zdCAlc1xuIiwgaG9zdCk7CisgICAgICAgIHVubG9ja19nZXRob3N0YnluYW1lKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG1lbWNweSgmYWRkci5zaW5fYWRkciwgaGUtPmhfYWRkciwgaGUtPmhfbGVuZ3RoKTsKKyAgICBhZGRyLnNpbl9mYW1pbHkgPSBoZS0+aF9hZGRydHlwZTsKKyAgICBhZGRyLnNpbl9wb3J0ID0gMDsKKworICAgIC8vIGdvdCBpdCwgdW5sb2NrIHVzCisgICAgaG9zdFRpbWVyLnN0b3AoKTsKKyAgICBoZSA9IE5VTEw7CisgICAgdW5sb2NrX2dldGhvc3RieW5hbWUoKTsKKworICAgIGxvY2tUaW1lci5zdG9wKCk7CisgICAgaWYgKChsb25nKSBsb2NrVGltZXIuZHVyYXRpb25Vc2VjcygpID4gMTAwMDAwKSB7CisgICAgICAgIGxvbmcgbG9ja1RpbWUgPSAobG9uZykgbG9ja1RpbWVyLmR1cmF0aW9uVXNlY3MoKTsKKyAgICAgICAgbG9uZyBob3N0VGltZSA9IChsb25nKSBob3N0VGltZXIuZHVyYXRpb25Vc2VjcygpOworICAgICAgICBMT0coTE9HX0RFQlVHLCAic29ja2V0IiwKKyAgICAgICAgICAgICJMb29rdXAgb2YgJXMgdG9vayAlLjNmcyAoZ2V0aG9zdGJ5bmFtZT0lLjNmcyBsb2NrPSUuM2ZzKVxuIiwKKyAgICAgICAgICAgIGhvc3QsIGxvY2tUaW1lIC8gMTAwMDAwMC4wLCBob3N0VGltZSAvIDEwMDAwMDAuMCwKKyAgICAgICAgICAgIChsb2NrVGltZSAtIGhvc3RUaW1lKSAvIDEwMDAwMDAuMCk7CisgICAgfQorCisgICAgLy8gQWxsb2Mgc3RvcmFnZSBhbmQgY29weSBpdCBvdmVyLgorICAgIG5ld0FkZHIgPSBuZXcgSW5ldEFkZHJlc3MoKTsKKyAgICBpZiAobmV3QWRkciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIG5ld0FkZHItPm1MZW5ndGggPSBzaXplb2Yoc3RydWN0IHNvY2thZGRyX2luKTsKKyAgICBuZXdBZGRyLT5tQWRkcmVzcyA9IG5ldyBjaGFyW3NpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pXTsKKyAgICBpZiAobmV3QWRkci0+bUFkZHJlc3MgPT0gTlVMTCkgeworICAgICAgICBkZWxldGUgbmV3QWRkcjsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG1lbWNweShuZXdBZGRyLT5tQWRkcmVzcywgJmFkZHIsIG5ld0FkZHItPm1MZW5ndGgpOworCisgICAgLy8gS2VlcCB0aGlzIGZvciBkZWJ1ZyBtZXNzYWdlcy4KKyAgICBuZXdBZGRyLT5tTmFtZSA9IG5ldyBjaGFyW3N0cmxlbihob3N0KSsxXTsKKyAgICBpZiAobmV3QWRkci0+bU5hbWUgPT0gTlVMTCkgeworICAgICAgICBkZWxldGUgbmV3QWRkcjsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHN0cmNweShuZXdBZGRyLT5tTmFtZSwgaG9zdCk7CisKKyAgICByZXR1cm4gbmV3QWRkcjsKK30KKworCisvKgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiAgICAgIEluZXRTb2NrZXRBZGRyZXNzCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqLworCisvKgorICogQ3JlYXRlIGFuIGFkZHJlc3Mgd2l0aCB0aGUgaG9zdCB3aWxkY2FyZCAoSU5BRERSX0FOWSkuCisgKi8KK2Jvb2wgSW5ldFNvY2tldEFkZHJlc3M6OmNyZWF0ZShpbnQgcG9ydCkKK3sKKyAgICBhc3NlcnQobUFkZHJlc3MgPT0gTlVMTCk7CisKKyAgICBtQWRkcmVzcyA9IEluZXRBZGRyZXNzOjpnZXRCeU5hbWUoIjAuMC4wLjAiKTsKKyAgICBpZiAobUFkZHJlc3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIG1Qb3J0ID0gcG9ydDsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIENyZWF0ZSBhZGRyZXNzIHdpdGggaG9zdCBhbmQgcG9ydCBzcGVjaWZpZWQuCisgKi8KK2Jvb2wgSW5ldFNvY2tldEFkZHJlc3M6OmNyZWF0ZShjb25zdCBJbmV0QWRkcmVzcyogYWRkciwgaW50IHBvcnQpCit7CisgICAgYXNzZXJ0KG1BZGRyZXNzID09IE5VTEwpOworCisgICAgbUFkZHJlc3MgPSBuZXcgSW5ldEFkZHJlc3MoKmFkZHIpOyAgLy8gbWFrZSBhIGNvcHkKKyAgICBpZiAobUFkZHJlc3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIG1Qb3J0ID0gcG9ydDsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIENyZWF0ZSBhZGRyZXNzIHdpdGggaG9zdCBhbmQgcG9ydCBzcGVjaWZpZWQuCisgKi8KK2Jvb2wgSW5ldFNvY2tldEFkZHJlc3M6OmNyZWF0ZShjb25zdCBjaGFyKiBob3N0LCBpbnQgcG9ydCkKK3sKKyAgICBhc3NlcnQobUFkZHJlc3MgPT0gTlVMTCk7CisKKyAgICBtQWRkcmVzcyA9IEluZXRBZGRyZXNzOjpnZXRCeU5hbWUoaG9zdCk7CisgICAgaWYgKG1BZGRyZXNzID09IE5VTEwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICBtUG9ydCA9IHBvcnQ7CisgICAgcmV0dXJuIHRydWU7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvTG9nU29ja2V0LmNwcCBiL2xpYnMvdXRpbHMvTG9nU29ja2V0LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWMxYjk5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9Mb2dTb2NrZXQuY3BwCkBAIC0wLDAgKzEsMTI5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCisjaWZuZGVmIEhBVkVfV0lOU09DSworLy8jZGVmaW5lIFNPQ0tFVExPRworI2VuZGlmCisKKyNpZmRlZiBTT0NLRVRMT0cKKworI2RlZmluZSBMT0dfVEFHICJTT0NLRVRMT0ciCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisjaW5jbHVkZSAidXRpbHMvTG9nU29ja2V0LmgiCisjaW5jbHVkZSAidXRpbHMvbG9nZ2VyLmgiCisjaW5jbHVkZSAiY3V0aWxzL2hhc2htYXAuaCIKKworLy8gZGVmaW5lZCBpbiAvL2RldmljZS9kYXRhL2V0Yy9ldmVudC1sb2ctdGFncworI2RlZmluZSBTT0NLRVRfQ0xPU0VfTE9HIDUxMDAwCisKK3N0YXRpYyBIYXNobWFwKiBzdGF0c01hcCA9IE5VTEw7CisKKyNkZWZpbmUgTE9HX0xJU1RfTlVNQkVSIDUKKwordHlwZWRlZiBzdHJ1Y3QgU29ja2V0U3RhdHMgeworICAgIGludCBmZDsKKyAgICB1bnNpZ25lZCBpbnQgc2VuZDsKKyAgICB1bnNpZ25lZCBpbnQgcmVjdjsKKyAgICB1bnNpZ25lZCBpbnQgaXA7CisgICAgdW5zaWduZWQgc2hvcnQgcG9ydDsKKyAgICBzaG9ydCByZWFzb247Cit9U29ja2V0U3RhdHM7CisKK1NvY2tldFN0YXRzICpnZXRfc29ja2V0X3N0YXRzKGludCBmZCkgeworICAgIGlmIChzdGF0c01hcCA9PSBOVUxMKSB7CisgICAgICAgIHN0YXRzTWFwID0gaGFzaG1hcENyZWF0ZSg4LCAmaGFzaG1hcEludEhhc2gsICZoYXNobWFwSW50RXF1YWxzKTsKKyAgICB9CisKKyAgICBTb2NrZXRTdGF0cyAqcyA9IChTb2NrZXRTdGF0cyopIGhhc2htYXBHZXQoc3RhdHNNYXAsICZmZCk7CisgICAgaWYgKHMgPT0gTlVMTCkgeworICAgICAgICAvLyBMT0dEKCJjcmVhdGUgU29ja2V0U3RhdHMgZm9yIGZkICVkIiwgZmQpOworICAgICAgICBzID0gKFNvY2tldFN0YXRzKikgbWFsbG9jKHNpemVvZihTb2NrZXRTdGF0cykpOworICAgICAgICBtZW1zZXQocywgMCwgc2l6ZW9mKFNvY2tldFN0YXRzKSk7CisgICAgICAgIHMtPmZkID0gZmQ7CisgICAgICAgIGhhc2htYXBQdXQoc3RhdHNNYXAsICZzLT5mZCwgcyk7CisgICAgfQorICAgIHJldHVybiBzOworfQorCit2b2lkIGxvZ19zb2NrZXRfY29ubmVjdChpbnQgZmQsIHVuc2lnbmVkIGludCBpcCwgdW5zaWduZWQgc2hvcnQgcG9ydCkgeworICAgIC8vIExPR0QoImxvZ19zb2NrZXRfY29ubmVjdCBmb3IgZmQgJWQgaXAgJWQgcG9ydCVkIiwgZmQsIGlwLCBwb3J0KTsKKyAgICBTb2NrZXRTdGF0cyAqcyA9IGdldF9zb2NrZXRfc3RhdHMoZmQpOworICAgIHMtPmlwID0gaXA7CisgICAgcy0+cG9ydCA9IHBvcnQ7Cit9CisKK3ZvaWQgYWRkX3NlbmRfc3RhdHMoaW50IGZkLCBpbnQgc2VuZCkgeworICAgIGlmIChzZW5kIDw9MCkgeworICAgICAgICBMT0dFKCJhZGRfc2VuZF9zdGF0cyBzZW5kICVkIiwgc2VuZCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU29ja2V0U3RhdHMgKnMgPSBnZXRfc29ja2V0X3N0YXRzKGZkKTsKKyAgICBzLT5zZW5kICs9IHNlbmQ7CisgICAgLy8gTE9HRCgiYWRkX3NlbmRfc3RhdHMgZm9yIGZkICVkIGlwICVkIHBvcnQlZCIsIGZkLCBzLT5pcCwgcy0+cG9ydCk7Cit9CisKK3ZvaWQgYWRkX3JlY3Zfc3RhdHMoaW50IGZkLCBpbnQgcmVjdikgeworICAgIGlmIChyZWN2IDw9MCkgeworICAgICAgICBMT0dFKCJhZGRfcmVjdl9zdGF0cyByZWN2ICVkIiwgcmVjdik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU29ja2V0U3RhdHMgKnMgPSBnZXRfc29ja2V0X3N0YXRzKGZkKTsKKyAgICBzLT5yZWN2ICs9IHJlY3Y7CisgICAgLy8gTE9HRCgiYWRkX3JlY3Zfc3RhdHMgZm9yIGZkICVkIGlwICVkIHBvcnQlZCIsIGZkLCBzLT5pcCwgcy0+cG9ydCk7Cit9CisKK2NoYXIqIHB1dF9pbnQoY2hhciogYnVmLCBpbnQgdmFsdWUpIHsKKyAgICAqYnVmID0gRVZFTlRfVFlQRV9JTlQ7CisgICAgYnVmKys7CisgICAgbWVtY3B5KGJ1ZiwgJnZhbHVlLCBzaXplb2YoaW50KSk7CisgICAgcmV0dXJuIGJ1ZiArIHNpemVvZihpbnQpOworfQorCit2b2lkIGxvZ19zb2NrZXRfY2xvc2UoaW50IGZkLCBzaG9ydCByZWFzb24pIHsKKyAgICBpZiAoc3RhdHNNYXApIHsKKyAgICAgICAgU29ja2V0U3RhdHMgKnMgPSAoU29ja2V0U3RhdHMqKSBoYXNobWFwR2V0KHN0YXRzTWFwLCAmZmQpOworICAgICAgICBpZiAocyAhPSBOVUxMKSB7CisgICAgICAgICAgICBpZiAocy0+c2VuZCAhPSAwIHx8IHMtPnJlY3YgIT0gMCkgeworICAgICAgICAgICAgICAgIHMtPnJlYXNvbiA9IHJlYXNvbjsKKyAgICAgICAgICAgICAgICAvLyA1IGludCArIGxpc3QgdHlwZSBuZWVkIDIgYnl0ZXMKKyAgICAgICAgICAgICAgICBjaGFyIGJ1ZltMT0dfTElTVF9OVU1CRVIgKiA1ICsgMl07CisgICAgICAgICAgICAgICAgYnVmWzBdID0gRVZFTlRfVFlQRV9MSVNUOworICAgICAgICAgICAgICAgIGJ1ZlsxXSA9IExPR19MSVNUX05VTUJFUjsKKyAgICAgICAgICAgICAgICBjaGFyKiB3cml0ZVBvcyA9IGJ1ZiArIDI7CisgICAgICAgICAgICAgICAgd3JpdGVQb3MgPSBwdXRfaW50KHdyaXRlUG9zLCBzLT5zZW5kKTsKKyAgICAgICAgICAgICAgICB3cml0ZVBvcyA9IHB1dF9pbnQod3JpdGVQb3MsIHMtPnJlY3YpOworICAgICAgICAgICAgICAgIHdyaXRlUG9zID0gcHV0X2ludCh3cml0ZVBvcywgcy0+aXApOworICAgICAgICAgICAgICAgIHdyaXRlUG9zID0gcHV0X2ludCh3cml0ZVBvcywgcy0+cG9ydCk7CisgICAgICAgICAgICAgICAgd3JpdGVQb3MgPSBwdXRfaW50KHdyaXRlUG9zLCBzLT5yZWFzb24pOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGFuZHJvaWRfYldyaXRlTG9nKFNPQ0tFVF9DTE9TRV9MT0csIGJ1Ziwgc2l6ZW9mKGJ1ZikpOworICAgICAgICAgICAgICAgIC8vIExPR0QoInNlbmQgJWQgcmVjdiAlZCByZWFzb24gJWQiLCBzLT5zZW5kLCBzLT5yZWN2LCBzLT5yZWFzb24pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaGFzaG1hcFJlbW92ZShzdGF0c01hcCwgJnMtPmZkKTsKKyAgICAgICAgICAgIGZyZWUocyk7CisgICAgICAgIH0KKyAgICB9Cit9CisKKyNlbHNlCit2b2lkIGFkZF9zZW5kX3N0YXRzKGludCBmZCwgaW50IHNlbmQpIHt9IAordm9pZCBhZGRfcmVjdl9zdGF0cyhpbnQgZmQsIGludCByZWN2KSB7fQordm9pZCBsb2dfc29ja2V0X2Nsb3NlKGludCBmZCwgc2hvcnQgcmVhc29uKSB7fQordm9pZCBsb2dfc29ja2V0X2Nvbm5lY3QoaW50IGZkLCB1bnNpZ25lZCBpbnQgaXAsIHVuc2lnbmVkIHNob3J0IHBvcnQpIHt9CisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMiBiL2xpYnMvdXRpbHMvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL01lbW9yeUJhc2UuY3BwIGIvbGlicy91dGlscy9NZW1vcnlCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjVlMTFjCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9NZW1vcnlCYXNlLmNwcApAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9NZW1vcnlCYXNlLmg+CisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTWVtb3J5QmFzZTo6TWVtb3J5QmFzZShjb25zdCBzcDxJTWVtb3J5SGVhcD4mIGhlYXAsCisgICAgICAgIHNzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSkKKyAgICA6IG1TaXplKHNpemUpLCBtT2Zmc2V0KG9mZnNldCksIG1IZWFwKGhlYXApCit7Cit9CisKK3NwPElNZW1vcnlIZWFwPiBNZW1vcnlCYXNlOjpnZXRNZW1vcnkoc3NpemVfdCogb2Zmc2V0LCBzaXplX3QqIHNpemUpIGNvbnN0Cit7CisgICAgaWYgKG9mZnNldCkgKm9mZnNldCA9IG1PZmZzZXQ7CisgICAgaWYgKHNpemUpICAgKnNpemUgPSBtU2l6ZTsKKyAgICByZXR1cm4gbUhlYXA7Cit9CisKK01lbW9yeUJhc2U6On5NZW1vcnlCYXNlKCkKK3sKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9NZW1vcnlEZWFsZXIuY3BwIGIvbGlicy91dGlscy9NZW1vcnlEZWFsZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmODIwMWIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL01lbW9yeURlYWxlci5jcHAKQEAgLTAsMCArMSw0MDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk1lbW9yeURlYWxlciIKKworI2luY2x1ZGUgPHV0aWxzL01lbW9yeURlYWxlci5oPgorCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvSVBDVGhyZWFkU3RhdGUuaD4KKyNpbmNsdWRlIDx1dGlscy9Tb3J0ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvTWVtb3J5QmFzZS5oPgorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisjaW5jbHVkZSA8c3lzL2ZpbGUuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgU2ltcGxlTWVtb3J5IDogcHVibGljIE1lbW9yeUJhc2UgeworcHVibGljOgorICAgIFNpbXBsZU1lbW9yeShjb25zdCBzcDxJTWVtb3J5SGVhcD4mIGhlYXAsIHNzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSk7CisgICAgdmlydHVhbCB+U2ltcGxlTWVtb3J5KCk7Cit9OworCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTWVtb3J5RGVhbGVyOjpBbGxvY2F0aW9uOjpBbGxvY2F0aW9uKAorICAgICAgICBjb25zdCBzcDxNZW1vcnlEZWFsZXI+JiBkZWFsZXIsIHNzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSwKKyAgICAgICAgY29uc3Qgc3A8SU1lbW9yeT4mIG1lbW9yeSkKKyAgICA6IG1EZWFsZXIoZGVhbGVyKSwgbU9mZnNldChvZmZzZXQpLCBtU2l6ZShzaXplKSwgbU1lbW9yeShtZW1vcnkpIAoreworfQorCitNZW1vcnlEZWFsZXI6OkFsbG9jYXRpb246On5BbGxvY2F0aW9uKCkKK3sKKyAgICBpZiAobVNpemUpIHsKKyAgICAgICAgLyogTk9URTogaXQncyBWRVJZIGltcG9ydGFudCB0byBub3QgZnJlZSBhbGxvY2F0aW9ucyBvZiBzaXplIDAgYmVjYXVzZQorICAgICAgICAgKiB0aGV5J3JlIHNwZWNpYWwgYXMgdGhleSBkb24ndCBoYXZlIGFueSByZWNvcmQgaW4gdGhlIGFsbG9jYXRvcgorICAgICAgICAgKiBhbmQgY291bGQgYWxpYXMgc29tZSByZWFsIGFsbG9jYXRpb24gKHRoZWlyIG9mZnNldCBpcyB6ZXJvKS4gKi8KKyAgICAgICAgbURlYWxlci0+ZGVhbGxvY2F0ZShtT2Zmc2V0KTsKKyAgICB9Cit9CisKK3NwPElNZW1vcnlIZWFwPiBNZW1vcnlEZWFsZXI6OkFsbG9jYXRpb246OmdldE1lbW9yeSgKKyAgICBzc2l6ZV90KiBvZmZzZXQsIHNpemVfdCogc2l6ZSkgY29uc3QKK3sKKyAgICByZXR1cm4gbU1lbW9yeS0+Z2V0TWVtb3J5KG9mZnNldCwgc2l6ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTWVtb3J5RGVhbGVyOjpNZW1vcnlEZWFsZXIoc2l6ZV90IHNpemUsIHVpbnQzMl90IGZsYWdzLCBjb25zdCBjaGFyKiBuYW1lKQorICAgIDogbUhlYXAobmV3IFNoYXJlZEhlYXAoc2l6ZSwgZmxhZ3MsIG5hbWUpKSwKKyAgICBtQWxsb2NhdG9yKG5ldyBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yKHNpemUpKQoreyAgICAKK30KKworTWVtb3J5RGVhbGVyOjpNZW1vcnlEZWFsZXIoY29uc3Qgc3A8SGVhcEludGVyZmFjZT4mIGhlYXApCisgICAgOiBtSGVhcChoZWFwKSwKKyAgICBtQWxsb2NhdG9yKG5ldyBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yKGhlYXAtPnZpcnR1YWxTaXplKCkpKQoreworfQorCitNZW1vcnlEZWFsZXI6Ok1lbW9yeURlYWxlciggY29uc3Qgc3A8SGVhcEludGVyZmFjZT4mIGhlYXAsCisgICAgICAgIGNvbnN0IHNwPEFsbG9jYXRvckludGVyZmFjZT4mIGFsbG9jYXRvcikKKyAgICA6IG1IZWFwKGhlYXApLCBtQWxsb2NhdG9yKGFsbG9jYXRvcikKK3sKK30KKworTWVtb3J5RGVhbGVyOjp+TWVtb3J5RGVhbGVyKCkKK3sKK30KKworc3A8SU1lbW9yeT4gTWVtb3J5RGVhbGVyOjphbGxvY2F0ZShzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MpCit7CisgICAgc3A8SU1lbW9yeT4gbWVtb3J5OworICAgIGNvbnN0IHNzaXplX3Qgb2Zmc2V0ID0gYWxsb2NhdG9yKCktPmFsbG9jYXRlKHNpemUsIGZsYWdzKTsKKyAgICBpZiAob2Zmc2V0ID49IDApIHsKKyAgICAgICAgc3A8SU1lbW9yeT4gbmV3X21lbW9yeSA9IGhlYXAoKS0+bWFwTWVtb3J5KG9mZnNldCwgc2l6ZSk7CisgICAgICAgIGlmIChuZXdfbWVtb3J5ICE9IDApIHsKKyAgICAgICAgICAgIG1lbW9yeSA9IG5ldyBBbGxvY2F0aW9uKHRoaXMsIG9mZnNldCwgc2l6ZSwgbmV3X21lbW9yeSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJjb3VsZG4ndCBtYXAgWyU4eCwgJWRdIiwgb2Zmc2V0LCBzaXplKTsKKyAgICAgICAgICAgIGlmIChzaXplKSB7CisgICAgICAgICAgICAgICAgLyogTk9URTogaXQncyBWRVJZIGltcG9ydGFudCB0byBub3QgZnJlZSBhbGxvY2F0aW9ucyBvZiBzaXplIDAKKyAgICAgICAgICAgICAgICAgKiBiZWNhdXNlIHRoZXkncmUgc3BlY2lhbCBhcyB0aGV5IGRvbid0IGhhdmUgYW55IHJlY29yZCBpbiB0aGUgCisgICAgICAgICAgICAgICAgICogYWxsb2NhdG9yIGFuZCBjb3VsZCBhbGlhcyBzb21lIHJlYWwgYWxsb2NhdGlvbiAKKyAgICAgICAgICAgICAgICAgKiAodGhlaXIgb2Zmc2V0IGlzIHplcm8pLiAqLworICAgICAgICAgICAgICAgIGFsbG9jYXRvcigpLT5kZWFsbG9jYXRlKG9mZnNldCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gICAgICAgIAorICAgIH0KKyAgICByZXR1cm4gbWVtb3J5OworfQorCit2b2lkIE1lbW9yeURlYWxlcjo6ZGVhbGxvY2F0ZShzaXplX3Qgb2Zmc2V0KQoreworICAgIGFsbG9jYXRvcigpLT5kZWFsbG9jYXRlKG9mZnNldCk7Cit9CisKK3ZvaWQgTWVtb3J5RGVhbGVyOjpkdW1wKGNvbnN0IGNoYXIqIHdoYXQsIHVpbnQzMl90IGZsYWdzKSBjb25zdAoreworICAgIGFsbG9jYXRvcigpLT5kdW1wKHdoYXQsIGZsYWdzKTsKK30KKworY29uc3Qgc3A8SGVhcEludGVyZmFjZT4mIE1lbW9yeURlYWxlcjo6aGVhcCgpIGNvbnN0IHsKKyAgICByZXR1cm4gbUhlYXA7Cit9CisKK2NvbnN0IHNwPEFsbG9jYXRvckludGVyZmFjZT4mIE1lbW9yeURlYWxlcjo6YWxsb2NhdG9yKCkgY29uc3QgeworICAgIHJldHVybiBtQWxsb2NhdG9yOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIGFsaWduIGFsbCB0aGUgbWVtb3J5IGJsb2NrcyBvbiBhIGNhY2hlLWxpbmUgYm91bmRhcnkKK2NvbnN0IGludCBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yOjprTWVtb3J5QWxpZ24gPSAzMjsKKworU2ltcGxlQmVzdEZpdEFsbG9jYXRvcjo6U2ltcGxlQmVzdEZpdEFsbG9jYXRvcihzaXplX3Qgc2l6ZSkKK3sKKyAgICBzaXplX3QgcGFnZXNpemUgPSBnZXRwYWdlc2l6ZSgpOworICAgIG1IZWFwU2l6ZSA9ICgoc2l6ZSArIHBhZ2VzaXplLTEpICYgfihwYWdlc2l6ZS0xKSk7CisKKyAgICBjaHVua190KiBub2RlID0gbmV3IGNodW5rX3QoMCwgbUhlYXBTaXplIC8ga01lbW9yeUFsaWduKTsKKyAgICBtTGlzdC5pbnNlcnRIZWFkKG5vZGUpOworfQorCitTaW1wbGVCZXN0Rml0QWxsb2NhdG9yOjp+U2ltcGxlQmVzdEZpdEFsbG9jYXRvcigpCit7CisgICAgd2hpbGUoIW1MaXN0LmlzRW1wdHkoKSkgeworICAgICAgICBkZWxldGUgbUxpc3QucmVtb3ZlKG1MaXN0LmhlYWQoKSk7CisgICAgfQorfQorCitzaXplX3QgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcjo6c2l6ZSgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1IZWFwU2l6ZTsKK30KKworc2l6ZV90IFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I6OmFsbG9jYXRlKHNpemVfdCBzaXplLCB1aW50MzJfdCBmbGFncykKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIHNzaXplX3Qgb2Zmc2V0ID0gYWxsb2Moc2l6ZSwgZmxhZ3MpOworICAgIHJldHVybiBvZmZzZXQ7Cit9CisKK3N0YXR1c190IFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I6OmRlYWxsb2NhdGUoc2l6ZV90IG9mZnNldCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIGNodW5rX3QgY29uc3QgKiBjb25zdCBmcmVlZCA9IGRlYWxsb2Mob2Zmc2V0KTsKKyAgICBpZiAoZnJlZWQpIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7Cit9CisKK3NzaXplX3QgU2ltcGxlQmVzdEZpdEFsbG9jYXRvcjo6YWxsb2Moc2l6ZV90IHNpemUsIHVpbnQzMl90IGZsYWdzKQoreworICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHNpemUgPSAoc2l6ZSArIGtNZW1vcnlBbGlnbi0xKSAvIGtNZW1vcnlBbGlnbjsKKyAgICBjaHVua190KiBmcmVlX2NodW5rID0gMDsKKyAgICBjaHVua190KiBjdXIgPSBtTGlzdC5oZWFkKCk7CisKKyAgICBzaXplX3QgcGFnZXNpemUgPSBnZXRwYWdlc2l6ZSgpOworICAgIHdoaWxlIChjdXIpIHsKKyAgICAgICAgaW50IGV4dHJhID0gMDsKKyAgICAgICAgaWYgKGZsYWdzICYgUEFHRV9BTElHTkVEKQorICAgICAgICAgICAgZXh0cmEgPSAoIC1jdXItPnN0YXJ0ICYgKChwYWdlc2l6ZS9rTWVtb3J5QWxpZ24pLTEpICkgOworCisgICAgICAgIC8vIGJlc3QgZml0CisgICAgICAgIGlmIChjdXItPmZyZWUgJiYgKGN1ci0+c2l6ZSA+PSAoc2l6ZStleHRyYSkpKSB7CisgICAgICAgICAgICBpZiAoKCFmcmVlX2NodW5rKSB8fCAoY3VyLT5zaXplIDwgZnJlZV9jaHVuay0+c2l6ZSkpIHsKKyAgICAgICAgICAgICAgICBmcmVlX2NodW5rID0gY3VyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGN1ci0+c2l6ZSA9PSBzaXplKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY3VyID0gY3VyLT5uZXh0OworICAgIH0KKworICAgIGlmIChmcmVlX2NodW5rKSB7CisgICAgICAgIGNvbnN0IHNpemVfdCBmcmVlX3NpemUgPSBmcmVlX2NodW5rLT5zaXplOworICAgICAgICBmcmVlX2NodW5rLT5mcmVlID0gMDsKKyAgICAgICAgZnJlZV9jaHVuay0+c2l6ZSA9IHNpemU7CisgICAgICAgIGlmIChmcmVlX3NpemUgPiBzaXplKSB7CisgICAgICAgICAgICBpbnQgZXh0cmEgPSAwOworICAgICAgICAgICAgaWYgKGZsYWdzICYgUEFHRV9BTElHTkVEKQorICAgICAgICAgICAgICAgIGV4dHJhID0gKCAtZnJlZV9jaHVuay0+c3RhcnQgJiAoKHBhZ2VzaXplL2tNZW1vcnlBbGlnbiktMSkgKSA7CisgICAgICAgICAgICBpZiAoZXh0cmEpIHsKKyAgICAgICAgICAgICAgICBjaHVua190KiBzcGxpdCA9IG5ldyBjaHVua190KGZyZWVfY2h1bmstPnN0YXJ0LCBleHRyYSk7CisgICAgICAgICAgICAgICAgZnJlZV9jaHVuay0+c3RhcnQgKz0gZXh0cmE7CisgICAgICAgICAgICAgICAgbUxpc3QuaW5zZXJ0QmVmb3JlKGZyZWVfY2h1bmssIHNwbGl0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTE9HRV9JRigoZmxhZ3MmUEFHRV9BTElHTkVEKSAmJiAKKyAgICAgICAgICAgICAgICAgICAgKChmcmVlX2NodW5rLT5zdGFydCprTWVtb3J5QWxpZ24pJihwYWdlc2l6ZS0xKSksCisgICAgICAgICAgICAgICAgICAgICJQQUdFX0FMSUdORUQgcmVxdWVzdGVkLCBidXQgcGFnZSBpcyBub3QgYWxpZ25lZCEhISIpOworCisgICAgICAgICAgICBjb25zdCBzc2l6ZV90IHRhaWxfZnJlZSA9IGZyZWVfc2l6ZSAtIChzaXplK2V4dHJhKTsKKyAgICAgICAgICAgIGlmICh0YWlsX2ZyZWUgPiAwKSB7CisgICAgICAgICAgICAgICAgY2h1bmtfdCogc3BsaXQgPSBuZXcgY2h1bmtfdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVfY2h1bmstPnN0YXJ0ICsgZnJlZV9jaHVuay0+c2l6ZSwgdGFpbF9mcmVlKTsKKyAgICAgICAgICAgICAgICBtTGlzdC5pbnNlcnRBZnRlcihmcmVlX2NodW5rLCBzcGxpdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChmcmVlX2NodW5rLT5zdGFydCkqa01lbW9yeUFsaWduOworICAgIH0KKyAgICByZXR1cm4gTk9fTUVNT1JZOworfQorCitTaW1wbGVCZXN0Rml0QWxsb2NhdG9yOjpjaHVua190KiBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yOjpkZWFsbG9jKHNpemVfdCBzdGFydCkKK3sKKyAgICBzdGFydCA9IHN0YXJ0IC8ga01lbW9yeUFsaWduOworICAgIGNodW5rX3QqIGN1ciA9IG1MaXN0LmhlYWQoKTsKKyAgICB3aGlsZSAoY3VyKSB7CisgICAgICAgIGlmIChjdXItPnN0YXJ0ID09IHN0YXJ0KSB7CisgICAgICAgICAgICBMT0dfRkFUQUxfSUYoY3VyLT5mcmVlLAorICAgICAgICAgICAgICAgICJibG9jayBhdCBvZmZzZXQgMHglMDhsWCBvZiBzaXplIDB4JTA4bFggYWxyZWFkeSBmcmVlZCIsCisgICAgICAgICAgICAgICAgY3VyLT5zdGFydCprTWVtb3J5QWxpZ24sIGN1ci0+c2l6ZSprTWVtb3J5QWxpZ24pOworCisgICAgICAgICAgICAvLyBtZXJnZSBmcmVlZCBibG9ja3MgdG9nZXRoZXIKKyAgICAgICAgICAgIGNodW5rX3QqIGZyZWVkID0gY3VyOworICAgICAgICAgICAgY3VyLT5mcmVlID0gMTsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBjaHVua190KiBjb25zdCBwID0gY3VyLT5wcmV2OworICAgICAgICAgICAgICAgIGNodW5rX3QqIGNvbnN0IG4gPSBjdXItPm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKHAgJiYgKHAtPmZyZWUgfHwgIWN1ci0+c2l6ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZnJlZWQgPSBwOworICAgICAgICAgICAgICAgICAgICBwLT5zaXplICs9IGN1ci0+c2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgbUxpc3QucmVtb3ZlKGN1cik7CisgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjdXI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGN1ciA9IG47CisgICAgICAgICAgICB9IHdoaWxlIChjdXIgJiYgY3VyLT5mcmVlKTsKKworICAgICAgICAgICAgI2lmbmRlZiBOREVCVUcKKyAgICAgICAgICAgICAgICBpZiAoIWZyZWVkLT5mcmVlKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXBfbCgiZGVhbGxvYyAoIWZyZWVkLT5mcmVlKSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICNlbmRpZgorICAgICAgICAgICAgTE9HX0ZBVEFMX0lGKCFmcmVlZC0+ZnJlZSwKKyAgICAgICAgICAgICAgICAiZnJlZWQgYmxvY2sgYXQgb2Zmc2V0IDB4JTA4bFggb2Ygc2l6ZSAweCUwOGxYIGlzIG5vdCBmcmVlISIsCisgICAgICAgICAgICAgICAgZnJlZWQtPnN0YXJ0ICoga01lbW9yeUFsaWduLCBmcmVlZC0+c2l6ZSAqIGtNZW1vcnlBbGlnbik7CisKKyAgICAgICAgICAgIHJldHVybiBmcmVlZDsKKyAgICAgICAgfQorICAgICAgICBjdXIgPSBjdXItPm5leHQ7CisgICAgfQorICAgIHJldHVybiAwOworfQorCit2b2lkIFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I6OmR1bXAoY29uc3QgY2hhciogd2hhdCwgdWludDMyX3QgZmxhZ3MpIGNvbnN0Cit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBkdW1wX2wod2hhdCwgZmxhZ3MpOworfQorCit2b2lkIFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I6OmR1bXBfbChjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncykgY29uc3QKK3sKKyAgICBTdHJpbmc4IHJlc3VsdDsKKyAgICBkdW1wX2wocmVzdWx0LCB3aGF0LCBmbGFncyk7CisgICAgTE9HRCgiJXMiLCByZXN1bHQuc3RyaW5nKCkpOworfQorCit2b2lkIFNpbXBsZUJlc3RGaXRBbGxvY2F0b3I6OmR1bXAoU3RyaW5nOCYgcmVzdWx0LAorICAgICAgICBjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncykgY29uc3QKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIGR1bXBfbChyZXN1bHQsIHdoYXQsIGZsYWdzKTsKK30KKwordm9pZCBTaW1wbGVCZXN0Rml0QWxsb2NhdG9yOjpkdW1wX2woU3RyaW5nOCYgcmVzdWx0LAorICAgICAgICBjb25zdCBjaGFyKiB3aGF0LCB1aW50MzJfdCBmbGFncykgY29uc3QKK3sKKyAgICBzaXplX3Qgc2l6ZSA9IDA7CisgICAgaW50MzJfdCBpID0gMDsKKyAgICBjaHVua190IGNvbnN0KiBjdXIgPSBtTGlzdC5oZWFkKCk7CisgICAgCisgICAgY29uc3Qgc2l6ZV90IFNJWkUgPSAyNTY7CisgICAgY2hhciBidWZmZXJbU0laRV07CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiICAlcyAoJXAsIHNpemU9JXUpXG4iLAorICAgICAgICAgICAgd2hhdCwgdGhpcywgKHVuc2lnbmVkIGludCltSGVhcFNpemUpOworICAgIAorICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKyAgICAgICAgICAgIAorICAgIHdoaWxlIChjdXIpIHsKKyAgICAgICAgY29uc3QgY2hhciogZXJyc1tdID0geyIiLCAifCBsaW5rIGJvZ3VzIE5QIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAifCBsaW5rIGJvZ3VzIFBOIiwgInwgbGluayBib2d1cyBOUCtQTiIgfTsKKyAgICAgICAgaW50IG5wID0gKChjdXItPm5leHQpICYmIGN1ci0+bmV4dC0+cHJldiAhPSBjdXIpID8gMSA6IDA7CisgICAgICAgIGludCBwbiA9ICgoY3VyLT5wcmV2KSAmJiBjdXItPnByZXYtPm5leHQgIT0gY3VyKSA/IDIgOiAwOworCisgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgU0laRSwgIiAgJTN1OiAlMDh4IHwgMHglMDhYIHwgMHglMDhYIHwgJXMgJXNcbiIsCisgICAgICAgICAgICBpLCBpbnQoY3VyKSwgaW50KGN1ci0+c3RhcnQqa01lbW9yeUFsaWduKSwKKyAgICAgICAgICAgIGludChjdXItPnNpemUqa01lbW9yeUFsaWduKSwKKyAgICAgICAgICAgICAgICAgICAgaW50KGN1ci0+ZnJlZSkgPyAiRiIgOiAiQSIsCisgICAgICAgICAgICAgICAgICAgIGVycnNbbnB8cG5dKTsKKyAgICAgICAgCisgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyKTsKKworICAgICAgICBpZiAoIWN1ci0+ZnJlZSkKKyAgICAgICAgICAgIHNpemUgKz0gY3VyLT5zaXplKmtNZW1vcnlBbGlnbjsKKworICAgICAgICBpKys7CisgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgc25wcmludGYoYnVmZmVyLCBTSVpFLCAiICBzaXplIGFsbG9jYXRlZDogJXUgKCV1IEtCKVxuIiwgaW50KHNpemUpLCBpbnQoc2l6ZS8xMDI0KSk7CisgICAgcmVzdWx0LmFwcGVuZChidWZmZXIpOworfQorICAgICAgICAKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworCitTaGFyZWRIZWFwOjpTaGFyZWRIZWFwKHNpemVfdCBzaXplLCB1aW50MzJfdCBmbGFncywgY2hhciBjb25zdCAqIG5hbWUpCisgICAgOiBNZW1vcnlIZWFwQmFzZShzaXplLCBmbGFncywgbmFtZSkKK3sKK30KKworU2hhcmVkSGVhcDo6flNoYXJlZEhlYXAoKQoreworfQorCitzcDxJTWVtb3J5PiBTaGFyZWRIZWFwOjptYXBNZW1vcnkoc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpCit7CisgICAgcmV0dXJuIG5ldyBTaW1wbGVNZW1vcnkodGhpcywgb2Zmc2V0LCBzaXplKTsKK30KKyAKKworU2ltcGxlTWVtb3J5OjpTaW1wbGVNZW1vcnkoY29uc3Qgc3A8SU1lbW9yeUhlYXA+JiBoZWFwLAorICAgICAgICBzc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpCisgICAgOiBNZW1vcnlCYXNlKGhlYXAsIG9mZnNldCwgc2l6ZSkKK3sKKyNpZm5kZWYgTkRFQlVHCisgICAgdm9pZCogY29uc3Qgc3RhcnRfcHRyID0gKHZvaWQqKShpbnRwdHJfdChoZWFwLT5iYXNlKCkpICsgb2Zmc2V0KTsKKyAgICBtZW1zZXQoc3RhcnRfcHRyLCAweGRhLCBzaXplKTsKKyNlbmRpZgorfQorCitTaW1wbGVNZW1vcnk6On5TaW1wbGVNZW1vcnkoKQoreworICAgIHNpemVfdCBmcmVlZE9mZnNldCA9IGdldE9mZnNldCgpOworICAgIHNpemVfdCBmcmVlZFNpemUgICA9IGdldFNpemUoKTsKKworICAgIC8vIGtlZXAgdGhlIHNpemUgdG8gdW5tYXAgaW4gZXhjZXNzCisgICAgc2l6ZV90IHBhZ2VzaXplID0gZ2V0cGFnZXNpemUoKTsKKyAgICBzaXplX3Qgc3RhcnQgPSBmcmVlZE9mZnNldDsKKyAgICBzaXplX3QgZW5kID0gc3RhcnQgKyBmcmVlZFNpemU7CisgICAgc3RhcnQgJj0gfihwYWdlc2l6ZS0xKTsKKyAgICBlbmQgPSAoZW5kICsgcGFnZXNpemUtMSkgJiB+KHBhZ2VzaXplLTEpOworCisgICAgLy8gZ2l2ZSBiYWNrIHRvIHRoZSBrZXJuZWwgdGhlIHBhZ2VzIHdlIGRvbid0IG5lZWQKKyAgICBzaXplX3QgZnJlZV9zdGFydCA9IGZyZWVkT2Zmc2V0OworICAgIHNpemVfdCBmcmVlX2VuZCA9IGZyZWVfc3RhcnQgKyBmcmVlZFNpemU7CisgICAgaWYgKHN0YXJ0IDwgZnJlZV9zdGFydCkKKyAgICAgICAgc3RhcnQgPSBmcmVlX3N0YXJ0OworICAgIGlmIChlbmQgPiBmcmVlX2VuZCkKKyAgICAgICAgZW5kID0gZnJlZV9lbmQ7CisgICAgc3RhcnQgPSAoc3RhcnQgKyBwYWdlc2l6ZS0xKSAmIH4ocGFnZXNpemUtMSk7CisgICAgZW5kICY9IH4ocGFnZXNpemUtMSk7ICAgIAorCisgICAgaWYgKHN0YXJ0IDwgZW5kKSB7CisgICAgICAgIHZvaWQqIGNvbnN0IHN0YXJ0X3B0ciA9ICh2b2lkKikoaW50cHRyX3QoZ2V0SGVhcCgpLT5iYXNlKCkpICsgc3RhcnQpOworICAgICAgICBzaXplX3Qgc2l6ZSA9IGVuZC1zdGFydDsKKworI2lmbmRlZiBOREVCVUcKKyAgICAgICAgbWVtc2V0KHN0YXJ0X3B0ciwgMHhkZiwgc2l6ZSk7CisjZW5kaWYKKworICAgICAgICAvLyBNQURWX1JFTU9WRSBpcyBub3QgZGVmaW5lZCBvbiBEYXBwZXIgYmFzZWQgR29vYnVudHUgCisjaWZkZWYgTUFEVl9SRU1PVkUgCisgICAgICAgIGlmIChzaXplKSB7CisgICAgICAgICAgICBpbnQgZXJyID0gbWFkdmlzZShzdGFydF9wdHIsIHNpemUsIE1BRFZfUkVNT1ZFKTsKKyAgICAgICAgICAgIExPR1dfSUYoZXJyLCAibWFkdmlzZSglcCwgJXUsIE1BRFZfUkVNT1ZFKSByZXR1cm5lZCAlcyIsCisgICAgICAgICAgICAgICAgICAgIHN0YXJ0X3B0ciwgc2l6ZSwgZXJyPDAgPyBzdHJlcnJvcihlcnJubykgOiAiT2siKTsKKyAgICAgICAgfQorI2VuZGlmCisgICAgfQorfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9NZW1vcnlIZWFwQmFzZS5jcHAgYi9saWJzL3V0aWxzL01lbW9yeUhlYXBCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjUxNzI4Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9NZW1vcnlIZWFwQmFzZS5jcHAKQEAgLTAsMCArMSwxODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk1lbW9yeUhlYXBCYXNlIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisjaW5jbHVkZSA8Y3V0aWxzL2FzaG1lbS5oPgorI2luY2x1ZGUgPGN1dGlscy9hdG9taWMuaD4KKworI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBCYXNlLmg+CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyNpbmNsdWRlIDxsaW51eC9hbmRyb2lkX3BtZW0uaD4KKyNlbmRpZgorCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK01lbW9yeUhlYXBCYXNlOjpNZW1vcnlIZWFwQmFzZSgpIAorICAgIDogbUZEKC0xKSwgbVNpemUoMCksIG1CYXNlKE1BUF9GQUlMRUQpLAorICAgICAgbURldmljZShOVUxMKSwgbU5lZWRVbm1hcChmYWxzZSkgCit7Cit9CisKK01lbW9yeUhlYXBCYXNlOjpNZW1vcnlIZWFwQmFzZShzaXplX3Qgc2l6ZSwgdWludDMyX3QgZmxhZ3MsIGNoYXIgY29uc3QgKiBuYW1lKQorICAgIDogbUZEKC0xKSwgbVNpemUoMCksIG1CYXNlKE1BUF9GQUlMRUQpLCBtRmxhZ3MoZmxhZ3MpLAorICAgICAgbURldmljZSgwKSwgbU5lZWRVbm1hcChmYWxzZSkKK3sKKyAgICBjb25zdCBzaXplX3QgcGFnZXNpemUgPSBnZXRwYWdlc2l6ZSgpOworICAgIHNpemUgPSAoKHNpemUgKyBwYWdlc2l6ZS0xKSAmIH4ocGFnZXNpemUtMSkpOworICAgIGludCBmZCA9IGFzaG1lbV9jcmVhdGVfcmVnaW9uKG5hbWUgPT0gTlVMTCA/ICJNZW1vcnlIZWFwQmFzZSIgOiBuYW1lLCBzaXplKTsKKyAgICBMT0dFX0lGKGZkPDAsICJlcnJvciBjcmVhdGluZyBhc2htZW0gcmVnaW9uOiAlcyIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgaWYgKGZkID49IDApIHsKKyAgICAgICAgaWYgKG1hcGZkKGZkLCBzaXplKSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgaWYgKGZsYWdzICYgUkVBRF9PTkxZKSB7CisgICAgICAgICAgICAgICAgYXNobWVtX3NldF9wcm90X3JlZ2lvbihmZCwgUFJPVF9SRUFEKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKworTWVtb3J5SGVhcEJhc2U6Ok1lbW9yeUhlYXBCYXNlKGNvbnN0IGNoYXIqIGRldmljZSwgc2l6ZV90IHNpemUsIHVpbnQzMl90IGZsYWdzKQorICAgIDogbUZEKC0xKSwgbVNpemUoMCksIG1CYXNlKE1BUF9GQUlMRUQpLCBtRmxhZ3MoZmxhZ3MpLAorICAgICAgbURldmljZSgwKSwgbU5lZWRVbm1hcChmYWxzZSkKK3sKKyAgICBpbnQgZmQgPSBvcGVuKGRldmljZSwgT19SRFdSKTsKKyAgICBMT0dFX0lGKGZkPDAsICJlcnJvciBvcGVuaW5nICVzOiAlcyIsIGRldmljZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICBpZiAoZmQgPj0gMCkgeworICAgICAgICBjb25zdCBzaXplX3QgcGFnZXNpemUgPSBnZXRwYWdlc2l6ZSgpOworICAgICAgICBzaXplID0gKChzaXplICsgcGFnZXNpemUtMSkgJiB+KHBhZ2VzaXplLTEpKTsKKyAgICAgICAgaWYgKG1hcGZkKGZkLCBzaXplKSA9PSBOT19FUlJPUikgeworICAgICAgICAgICAgbURldmljZSA9IGRldmljZTsKKyAgICAgICAgfQorICAgIH0KK30KKworTWVtb3J5SGVhcEJhc2U6Ok1lbW9yeUhlYXBCYXNlKGludCBmZCwgc2l6ZV90IHNpemUsIHVpbnQzMl90IGZsYWdzKQorICAgIDogbUZEKC0xKSwgbVNpemUoMCksIG1CYXNlKE1BUF9GQUlMRUQpLCBtRmxhZ3MoZmxhZ3MpLAorICAgICAgbURldmljZSgwKSwgbU5lZWRVbm1hcChmYWxzZSkKK3sKKyAgICBjb25zdCBzaXplX3QgcGFnZXNpemUgPSBnZXRwYWdlc2l6ZSgpOworICAgIHNpemUgPSAoKHNpemUgKyBwYWdlc2l6ZS0xKSAmIH4ocGFnZXNpemUtMSkpOworICAgIG1hcGZkKGR1cChmZCksIHNpemUpOworfQorCitzdGF0dXNfdCBNZW1vcnlIZWFwQmFzZTo6aW5pdChpbnQgZmQsIHZvaWQgKmJhc2UsIGludCBzaXplLCBpbnQgZmxhZ3MsIGNvbnN0IGNoYXIqIGRldmljZSkKK3sKKyAgICBpZiAobUZEICE9IC0xKSB7CisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICB9CisgICAgbUZEID0gZmQ7CisgICAgbUJhc2UgPSBiYXNlOworICAgIG1TaXplID0gc2l6ZTsKKyAgICBtRmxhZ3MgPSBmbGFnczsKKyAgICBtRGV2aWNlID0gZGV2aWNlOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgTWVtb3J5SGVhcEJhc2U6Om1hcGZkKGludCBmZCwgc2l6ZV90IHNpemUpCit7CisgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgICAvLyB0cnkgdG8gZmlndXJlIG91dCB0aGUgc2l6ZSBhdXRvbWF0aWNhbGx5CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgICAgIC8vIGZpcnN0IHRyeSB0aGUgUE1FTSBpb2N0bAorICAgICAgICBwbWVtX3JlZ2lvbiByZWc7CisgICAgICAgIGludCBlcnIgPSBpb2N0bChmZCwgUE1FTV9HRVRfVE9UQUxfU0laRSwgJnJlZyk7CisgICAgICAgIGlmIChlcnIgPT0gMCkKKyAgICAgICAgICAgIHNpemUgPSByZWcubGVuOworI2VuZGlmCisgICAgICAgIGlmIChzaXplID09IDApIHsgLy8gdHJ5IGZzdGF0CisgICAgICAgICAgICBzdHJ1Y3Qgc3RhdCBzYjsKKyAgICAgICAgICAgIGlmIChmc3RhdChmZCwgJnNiKSA9PSAwKQorICAgICAgICAgICAgICAgIHNpemUgPSBzYi5zdF9zaXplOworICAgICAgICB9CisgICAgICAgIC8vIGlmIGl0IGRpZG4ndCB3b3JrLCBsZXQgbW1hcCgpIGZhaWwuCisgICAgfQorCisgICAgaWYgKChtRmxhZ3MgJiBET05UX01BUF9MT0NBTExZKSA9PSAwKSB7CisgICAgICAgIHZvaWQqIGJhc2UgPSAodWludDhfdCopbW1hcCgwLCBzaXplLAorICAgICAgICAgICAgICAgIFBST1RfUkVBRHxQUk9UX1dSSVRFLCBNQVBfU0hBUkVELCBmZCwgMCk7CisgICAgICAgIGlmIChiYXNlID09IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgICAgIExPR0UoIm1tYXAoZmQ9JWQsIHNpemU9JXUpIGZhaWxlZCAoJXMpIiwKKyAgICAgICAgICAgICAgICAgICAgZmQsIHVpbnQzMl90KHNpemUpLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICAgICAgY2xvc2UoZmQpOworICAgICAgICAgICAgcmV0dXJuIC1lcnJubzsKKyAgICAgICAgfQorICAgICAgICAvL0xPR0QoIm1tYXAoZmQ9JWQsIGJhc2U9JXAsIHNpemU9JWx1KSIsIGZkLCBiYXNlLCBzaXplKTsKKyAgICAgICAgbUJhc2UgPSBiYXNlOworICAgICAgICBtTmVlZFVubWFwID0gdHJ1ZTsKKyAgICB9IGVsc2UgIHsKKyAgICAgICAgbUJhc2UgPSAwOyAvLyBub3QgTUFQX0ZBSUxFRAorICAgICAgICBtTmVlZFVubWFwID0gZmFsc2U7CisgICAgfQorICAgIG1GRCA9IGZkOworICAgIG1TaXplID0gc2l6ZTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK01lbW9yeUhlYXBCYXNlOjp+TWVtb3J5SGVhcEJhc2UoKQoreworICAgIGRpc3Bvc2UoKTsKK30KKwordm9pZCBNZW1vcnlIZWFwQmFzZTo6ZGlzcG9zZSgpCit7CisgICAgaW50IGZkID0gYW5kcm9pZF9hdG9taWNfb3IoLTEsICZtRkQpOworICAgIGlmIChmZCA+PSAwKSB7CisgICAgICAgIGlmIChtTmVlZFVubWFwKSB7CisgICAgICAgICAgICAvL0xPR0QoIm11bm1hcChmZD0lZCwgYmFzZT0lcCwgc2l6ZT0lbHUpIiwgZmQsIG1CYXNlLCBtU2l6ZSk7CisgICAgICAgICAgICBtdW5tYXAobUJhc2UsIG1TaXplKTsKKyAgICAgICAgfQorICAgICAgICBtQmFzZSA9IDA7CisgICAgICAgIG1TaXplID0gMDsKKyAgICAgICAgY2xvc2UoZmQpOworICAgIH0KK30KKworaW50IE1lbW9yeUhlYXBCYXNlOjpnZXRIZWFwSUQoKSBjb25zdCB7CisgICAgcmV0dXJuIG1GRDsKK30KKwordm9pZCogTWVtb3J5SGVhcEJhc2U6OmdldEJhc2UoKSBjb25zdCB7CisgICAgcmV0dXJuIG1CYXNlOworfQorCitzaXplX3QgTWVtb3J5SGVhcEJhc2U6OmdldFNpemUoKSBjb25zdCB7CisgICAgcmV0dXJuIG1TaXplOworfQorCit1aW50MzJfdCBNZW1vcnlIZWFwQmFzZTo6Z2V0RmxhZ3MoKSBjb25zdCB7CisgICAgcmV0dXJuIG1GbGFnczsKK30KKworY29uc3QgY2hhciogTWVtb3J5SGVhcEJhc2U6OmdldERldmljZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gbURldmljZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9NZW1vcnlIZWFwUG1lbS5jcHAgYi9saWJzL3V0aWxzL01lbW9yeUhlYXBQbWVtLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYmEyYjMwCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9NZW1vcnlIZWFwUG1lbS5jcHAKQEAgLTAsMCArMSwyNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk1lbW9yeUhlYXBQbWVtIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisKKyNpbmNsdWRlIDxjdXRpbHMvbG9nLmg+CisKKyNpbmNsdWRlIDx1dGlscy9NZW1vcnlIZWFwUG1lbS5oPgorI2luY2x1ZGUgPHV0aWxzL01lbW9yeUhlYXBCYXNlLmg+CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyNpbmNsdWRlIDxsaW51eC9hbmRyb2lkX3BtZW0uaD4KKyNlbmRpZgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitNZW1vcnlIZWFwUG1lbTo6TWVtb3J5UG1lbTo6TWVtb3J5UG1lbShjb25zdCBzcDxNZW1vcnlIZWFwUG1lbT4mIGhlYXApCisgICAgOiBCbk1lbW9yeSgpLCBtQ2xpZW50SGVhcChoZWFwKQoreworfQorCitNZW1vcnlIZWFwUG1lbTo6TWVtb3J5UG1lbTo6fk1lbW9yeVBtZW0oKSB7CisgICAgaWYgKG1DbGllbnRIZWFwICE9IE5VTEwpIHsKKyAgICAgICAgbUNsaWVudEhlYXAtPnJlbW92ZSh0aGlzKTsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBTdWJSZWdpb25NZW1vcnkgOiBwdWJsaWMgTWVtb3J5SGVhcFBtZW06Ok1lbW9yeVBtZW0geworcHVibGljOgorICAgIFN1YlJlZ2lvbk1lbW9yeShjb25zdCBzcDxNZW1vcnlIZWFwUG1lbT4mIGhlYXAsIHNzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSk7CisgICAgdmlydHVhbCB+U3ViUmVnaW9uTWVtb3J5KCk7CisgICAgdmlydHVhbCBzcDxJTWVtb3J5SGVhcD4gZ2V0TWVtb3J5KHNzaXplX3QqIG9mZnNldCwgc2l6ZV90KiBzaXplKSBjb25zdDsKK3ByaXZhdGU6CisgICAgZnJpZW5kIGNsYXNzIE1lbW9yeUhlYXBQbWVtOworICAgIHZvaWQgcmV2b2tlKCk7CisgICAgc2l6ZV90ICAgICAgICAgICAgICBtU2l6ZTsKKyAgICBzc2l6ZV90ICAgICAgICAgICAgIG1PZmZzZXQ7Cit9OworCitTdWJSZWdpb25NZW1vcnk6OlN1YlJlZ2lvbk1lbW9yeShjb25zdCBzcDxNZW1vcnlIZWFwUG1lbT4mIGhlYXAsCisgICAgICAgIHNzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSkKKyAgICA6IE1lbW9yeUhlYXBQbWVtOjpNZW1vcnlQbWVtKGhlYXApLCBtU2l6ZShzaXplKSwgbU9mZnNldChvZmZzZXQpCit7CisjaWZuZGVmIE5ERUJVRworICAgIHZvaWQqIGNvbnN0IHN0YXJ0X3B0ciA9ICh2b2lkKikoaW50cHRyX3QoZ2V0SGVhcCgpLT5iYXNlKCkpICsgb2Zmc2V0KTsKKyAgICBtZW1zZXQoc3RhcnRfcHRyLCAweGRhLCBzaXplKTsKKyNlbmRpZgorCisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgIGNvbnN0IHNpemVfdCBwYWdlc2l6ZSA9IGdldHBhZ2VzaXplKCk7CisgICAgICAgIHNpemUgPSAoc2l6ZSArIHBhZ2VzaXplLTEpICYgfihwYWdlc2l6ZS0xKTsKKyAgICAgICAgaW50IG91cl9mZCA9IGhlYXAtPmhlYXBJRCgpOworICAgICAgICBzdHJ1Y3QgcG1lbV9yZWdpb24gc3ViID0geyBvZmZzZXQsIHNpemUgfTsKKyAgICAgICAgaW50IGVyciA9IGlvY3RsKG91cl9mZCwgUE1FTV9NQVAsICZzdWIpOworICAgICAgICBMT0dFX0lGKGVycjwwLCAiUE1FTV9NQVAgZmFpbGVkICglcyksICIKKyAgICAgICAgICAgICAgICAibUZEPSVkLCBzdWIub2Zmc2V0PSVsdSwgc3ViLnNpemU9JWx1IiwKKyAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubyksIG91cl9mZCwgc3ViLm9mZnNldCwgc3ViLmxlbik7Cit9CisjZW5kaWYKK30KKworc3A8SU1lbW9yeUhlYXA+IFN1YlJlZ2lvbk1lbW9yeTo6Z2V0TWVtb3J5KHNzaXplX3QqIG9mZnNldCwgc2l6ZV90KiBzaXplKSBjb25zdAoreworICAgIGlmIChvZmZzZXQpICpvZmZzZXQgPSBtT2Zmc2V0OworICAgIGlmIChzaXplKSAgICpzaXplID0gbVNpemU7CisgICAgcmV0dXJuIGdldEhlYXAoKTsKK30KKworU3ViUmVnaW9uTWVtb3J5Ojp+U3ViUmVnaW9uTWVtb3J5KCkKK3sKKyAgICByZXZva2UoKTsKK30KKworCit2b2lkIFN1YlJlZ2lvbk1lbW9yeTo6cmV2b2tlKCkKK3sKKyAgICAvLyBOT1RFOiByZXZva2UoKSBkb2Vzbid0IG5lZWQgdG8gYmUgcHJvdGVjdGVkIGJ5IGEgbG9jayBiZWNhdXNlIGl0CisgICAgLy8gY2FuIG9ubHkgYmUgY2FsbGVkIGZyb20gTWVtb3J5SGVhcFBtZW06OnJldm9rZSgpLCB3aGljaCBtZWFucworICAgIC8vIHRoYXQgd2UgY2FuJ3QgYmUgaW4gflN1YlJlZ2lvbk1lbW9yeSgpLCBvciBpbiB+U3ViUmVnaW9uTWVtb3J5KCksCisgICAgLy8gd2hpY2ggbWVhbnMgTWVtb3J5SGVhcFBtZW06OnJldm9rZSgpIHdvdWxkbid0IGhhdmUgYmVlbiBhYmxlIHRvIAorICAgIC8vIHByb21vdGUoKSBpdC4KKyAgICAKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBpZiAobVNpemUgIT0gTlVMTCkgeworICAgICAgICBjb25zdCBzcDxNZW1vcnlIZWFwUG1lbT4mIGhlYXAoZ2V0SGVhcCgpKTsKKyAgICAgICAgaW50IG91cl9mZCA9IGhlYXAtPmhlYXBJRCgpOworICAgICAgICBzdHJ1Y3QgcG1lbV9yZWdpb24gc3ViOworICAgICAgICBzdWIub2Zmc2V0ID0gbU9mZnNldDsKKyAgICAgICAgc3ViLmxlbiA9IG1TaXplOworICAgICAgICBpbnQgZXJyID0gaW9jdGwob3VyX2ZkLCBQTUVNX1VOTUFQLCAmc3ViKTsKKyAgICAgICAgTE9HRV9JRihlcnI8MCwgIlBNRU1fVU5NQVAgZmFpbGVkICglcyksICIKKyAgICAgICAgICAgICAgICAibUZEPSVkLCBzdWIub2Zmc2V0PSVsdSwgc3ViLnNpemU9JWx1IiwKKyAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubyksIG91cl9mZCwgc3ViLm9mZnNldCwgc3ViLmxlbik7CisgICAgICAgIG1TaXplID0gMDsKKyAgICB9CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK01lbW9yeUhlYXBQbWVtOjpNZW1vcnlIZWFwUG1lbShjb25zdCBzcDxNZW1vcnlIZWFwQmFzZT4mIHBtZW1IZWFwLAorICAgICAgICB1aW50MzJfdCBmbGFncykKKyAgICA6IEhlYXBJbnRlcmZhY2UoKSwgTWVtb3J5SGVhcEJhc2UoKQoreworICAgIGNoYXIgY29uc3QgKiBjb25zdCBkZXZpY2UgPSBwbWVtSGVhcC0+Z2V0RGV2aWNlKCk7CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgaWYgKGRldmljZSkgeworICAgICAgICBpbnQgZmQgPSBvcGVuKGRldmljZSwgT19SRFdSKTsKKyAgICAgICAgTE9HRV9JRihmZDwwLCAiY291bGRuJ3Qgb3BlbiAlcyAoJXMpIiwgZGV2aWNlLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICBpZiAoZmQgPj0gMCkgeworICAgICAgICAgICAgaW50IGVyciA9IGlvY3RsKGZkLCBQTUVNX0NPTk5FQ1QsIHBtZW1IZWFwLT5oZWFwSUQoKSk7CisgICAgICAgICAgICBpZiAoZXJyIDwgMCkgeworICAgICAgICAgICAgICAgIExPR0UoIlBNRU1fQ09OTkVDVCBmYWlsZWQgKCVzKSwgbUZEPSVkLCBzdWItZmQ9JWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pLCBmZCwgcG1lbUhlYXAtPmhlYXBJRCgpKTsKKyAgICAgICAgICAgICAgICBjbG9zZShmZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIGV2ZXJ5dGhpbmcgd2VudCB3ZWxsLi4uCisgICAgICAgICAgICAgICAgbVBhcmVudEhlYXAgPSBwbWVtSGVhcDsKKyAgICAgICAgICAgICAgICBNZW1vcnlIZWFwQmFzZTo6aW5pdChmZCwgCisgICAgICAgICAgICAgICAgICAgICAgICBwbWVtSGVhcC0+Z2V0QmFzZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgcG1lbUhlYXAtPmdldFNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBtZW1IZWFwLT5nZXRGbGFncygpIHwgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorI2Vsc2UKKyAgICBtUGFyZW50SGVhcCA9IHBtZW1IZWFwOworICAgIE1lbW9yeUhlYXBCYXNlOjppbml0KCAKKyAgICAgICAgICAgIGR1cChwbWVtSGVhcC0+aGVhcElEKCkpLAorICAgICAgICAgICAgcG1lbUhlYXAtPmdldEJhc2UoKSwKKyAgICAgICAgICAgIHBtZW1IZWFwLT5nZXRTaXplKCksCisgICAgICAgICAgICBwbWVtSGVhcC0+Z2V0RmxhZ3MoKSB8IGZsYWdzLAorICAgICAgICAgICAgZGV2aWNlKTsKKyNlbmRpZgorfQorCitNZW1vcnlIZWFwUG1lbTo6fk1lbW9yeUhlYXBQbWVtKCkKK3sKK30KKworc3A8SU1lbW9yeT4gTWVtb3J5SGVhcFBtZW06Om1hcE1lbW9yeShzaXplX3Qgb2Zmc2V0LCBzaXplX3Qgc2l6ZSkKK3sKKyAgICBzcDxNZW1vcnlQbWVtPiBtZW1vcnkgPSBjcmVhdGVNZW1vcnkob2Zmc2V0LCBzaXplKTsKKyAgICBpZiAobWVtb3J5ICE9IDApIHsKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICAgICAgbUFsbG9jYXRpb25zLmFkZChtZW1vcnkpOworICAgIH0KKyAgICByZXR1cm4gbWVtb3J5OworfQorCitzcDxNZW1vcnlIZWFwUG1lbTo6TWVtb3J5UG1lbT4gTWVtb3J5SGVhcFBtZW06OmNyZWF0ZU1lbW9yeSgKKyAgICAgICAgc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpCit7CisgICAgc3A8U3ViUmVnaW9uTWVtb3J5PiBtZW1vcnk7CisgICAgaWYgKGhlYXBJRCgpID4gMCkgCisgICAgICAgIG1lbW9yeSA9IG5ldyBTdWJSZWdpb25NZW1vcnkodGhpcywgb2Zmc2V0LCBzaXplKTsKKyAgICByZXR1cm4gbWVtb3J5OworfQorCitzdGF0dXNfdCBNZW1vcnlIZWFwUG1lbTo6c2xhcCgpCit7CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgc2l6ZV90IHNpemUgPSBnZXRTaXplKCk7CisgICAgY29uc3Qgc2l6ZV90IHBhZ2VzaXplID0gZ2V0cGFnZXNpemUoKTsKKyAgICBzaXplID0gKHNpemUgKyBwYWdlc2l6ZS0xKSAmIH4ocGFnZXNpemUtMSk7CisgICAgaW50IG91cl9mZCA9IGdldEhlYXBJRCgpOworICAgIHN0cnVjdCBwbWVtX3JlZ2lvbiBzdWIgPSB7IDAsIHNpemUgfTsKKyAgICBpbnQgZXJyID0gaW9jdGwob3VyX2ZkLCBQTUVNX01BUCwgJnN1Yik7CisgICAgTE9HRV9JRihlcnI8MCwgIlBNRU1fTUFQIGZhaWxlZCAoJXMpLCAiCisgICAgICAgICAgICAibUZEPSVkLCBzdWIub2Zmc2V0PSVsdSwgc3ViLnNpemU9JWx1IiwKKyAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSwgb3VyX2ZkLCBzdWIub2Zmc2V0LCBzdWIubGVuKTsKKyAgICByZXR1cm4gLWVycm5vOworI2Vsc2UKKyAgICByZXR1cm4gTk9fRVJST1I7CisjZW5kaWYKK30KKworc3RhdHVzX3QgTWVtb3J5SGVhcFBtZW06OnVuc2xhcCgpCit7CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgc2l6ZV90IHNpemUgPSBnZXRTaXplKCk7CisgICAgY29uc3Qgc2l6ZV90IHBhZ2VzaXplID0gZ2V0cGFnZXNpemUoKTsKKyAgICBzaXplID0gKHNpemUgKyBwYWdlc2l6ZS0xKSAmIH4ocGFnZXNpemUtMSk7CisgICAgaW50IG91cl9mZCA9IGdldEhlYXBJRCgpOworICAgIHN0cnVjdCBwbWVtX3JlZ2lvbiBzdWIgPSB7IDAsIHNpemUgfTsKKyAgICBpbnQgZXJyID0gaW9jdGwob3VyX2ZkLCBQTUVNX1VOTUFQLCAmc3ViKTsKKyAgICBMT0dFX0lGKGVycjwwLCAiUE1FTV9VTk1BUCBmYWlsZWQgKCVzKSwgIgorICAgICAgICAgICAgIm1GRD0lZCwgc3ViLm9mZnNldD0lbHUsIHN1Yi5zaXplPSVsdSIsCisgICAgICAgICAgICBzdHJlcnJvcihlcnJubyksIG91cl9mZCwgc3ViLm9mZnNldCwgc3ViLmxlbik7CisgICAgcmV0dXJuIC1lcnJubzsKKyNlbHNlCisgICAgcmV0dXJuIE5PX0VSUk9SOworI2VuZGlmCit9CisKK3ZvaWQgTWVtb3J5SGVhcFBtZW06OnJldm9rZSgpCit7CisgICAgU29ydGVkVmVjdG9yPCB3cDxNZW1vcnlQbWVtPiA+IGFsbG9jYXRpb25zOworCisgICAgeyAvLyBzY29wZSBmb3IgbG9jaworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgICAgICBhbGxvY2F0aW9ucyA9IG1BbGxvY2F0aW9uczsKKyAgICB9CisgICAgCisgICAgc3NpemVfdCBjb3VudCA9IGFsbG9jYXRpb25zLnNpemUoKTsKKyAgICBmb3IgKHNzaXplX3QgaT0wIDsgaTxjb3VudCA7IGkrKykgeworICAgICAgICBzcDxNZW1vcnlQbWVtPiBtZW1vcnkoYWxsb2NhdGlvbnNbaV0ucHJvbW90ZSgpKTsKKyAgICAgICAgaWYgKG1lbW9yeSAhPSAwKQorICAgICAgICAgICAgbWVtb3J5LT5yZXZva2UoKTsKKyAgICB9Cit9CisKK3ZvaWQgTWVtb3J5SGVhcFBtZW06OnJlbW92ZShjb25zdCB3cDxNZW1vcnlQbWVtPiYgbWVtb3J5KQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgbUFsbG9jYXRpb25zLnJlbW92ZShtZW1vcnkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL05PVElDRSBiL2xpYnMvdXRpbHMvTk9USUNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1YjFlZmEKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL05PVElDRQpAQCAtMCwwICsxLDE5MCBAQAorCisgICBDb3B5cmlnaHQgKGMpIDIwMDUtMjAwOCwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorCisgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBhY2hlIExpY2Vuc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKKyAgICAgICAgICAgICAgICAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8KKworICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCisKKyAgIDEuIERlZmluaXRpb25zLgorCisgICAgICAiTGljZW5zZSIgc2hhbGwgbWVhbiB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLAorICAgICAgYW5kIGRpc3RyaWJ1dGlvbiBhcyBkZWZpbmVkIGJ5IFNlY3Rpb25zIDEgdGhyb3VnaCA5IG9mIHRoaXMgZG9jdW1lbnQuCisKKyAgICAgICJMaWNlbnNvciIgc2hhbGwgbWVhbiB0aGUgY29weXJpZ2h0IG93bmVyIG9yIGVudGl0eSBhdXRob3JpemVkIGJ5CisgICAgICB0aGUgY29weXJpZ2h0IG93bmVyIHRoYXQgaXMgZ3JhbnRpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgICJMZWdhbCBFbnRpdHkiIHNoYWxsIG1lYW4gdGhlIHVuaW9uIG9mIHRoZSBhY3RpbmcgZW50aXR5IGFuZCBhbGwKKyAgICAgIG90aGVyIGVudGl0aWVzIHRoYXQgY29udHJvbCwgYXJlIGNvbnRyb2xsZWQgYnksIG9yIGFyZSB1bmRlciBjb21tb24KKyAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCisgICAgICAiY29udHJvbCIgbWVhbnMgKGkpIHRoZSBwb3dlciwgZGlyZWN0IG9yIGluZGlyZWN0LCB0byBjYXVzZSB0aGUKKyAgICAgIGRpcmVjdGlvbiBvciBtYW5hZ2VtZW50IG9mIHN1Y2ggZW50aXR5LCB3aGV0aGVyIGJ5IGNvbnRyYWN0IG9yCisgICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKKyAgICAgIG91dHN0YW5kaW5nIHNoYXJlcywgb3IgKGlpaSkgYmVuZWZpY2lhbCBvd25lcnNoaXAgb2Ygc3VjaCBlbnRpdHkuCisKKyAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKKyAgICAgIGV4ZXJjaXNpbmcgcGVybWlzc2lvbnMgZ3JhbnRlZCBieSB0aGlzIExpY2Vuc2UuCisKKyAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAorICAgICAgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBzb2Z0d2FyZSBzb3VyY2UgY29kZSwgZG9jdW1lbnRhdGlvbgorICAgICAgc291cmNlLCBhbmQgY29uZmlndXJhdGlvbiBmaWxlcy4KKworICAgICAgIk9iamVjdCIgZm9ybSBzaGFsbCBtZWFuIGFueSBmb3JtIHJlc3VsdGluZyBmcm9tIG1lY2hhbmljYWwKKyAgICAgIHRyYW5zZm9ybWF0aW9uIG9yIHRyYW5zbGF0aW9uIG9mIGEgU291cmNlIGZvcm0sIGluY2x1ZGluZyBidXQKKyAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKKyAgICAgIGFuZCBjb252ZXJzaW9ucyB0byBvdGhlciBtZWRpYSB0eXBlcy4KKworICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKKyAgICAgIE9iamVjdCBmb3JtLCBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgTGljZW5zZSwgYXMgaW5kaWNhdGVkIGJ5IGEKKyAgICAgIGNvcHlyaWdodCBub3RpY2UgdGhhdCBpcyBpbmNsdWRlZCBpbiBvciBhdHRhY2hlZCB0byB0aGUgd29yaworICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KKworICAgICAgIkRlcml2YXRpdmUgV29ya3MiIHNoYWxsIG1lYW4gYW55IHdvcmssIHdoZXRoZXIgaW4gU291cmNlIG9yIE9iamVjdAorICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQorICAgICAgZWRpdG9yaWFsIHJldmlzaW9ucywgYW5ub3RhdGlvbnMsIGVsYWJvcmF0aW9ucywgb3Igb3RoZXIgbW9kaWZpY2F0aW9ucworICAgICAgcmVwcmVzZW50LCBhcyBhIHdob2xlLCBhbiBvcmlnaW5hbCB3b3JrIG9mIGF1dGhvcnNoaXAuIEZvciB0aGUgcHVycG9zZXMKKyAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgorICAgICAgc2VwYXJhYmxlIGZyb20sIG9yIG1lcmVseSBsaW5rIChvciBiaW5kIGJ5IG5hbWUpIHRvIHRoZSBpbnRlcmZhY2VzIG9mLAorICAgICAgdGhlIFdvcmsgYW5kIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZi4KKworICAgICAgIkNvbnRyaWJ1dGlvbiIgc2hhbGwgbWVhbiBhbnkgd29yayBvZiBhdXRob3JzaGlwLCBpbmNsdWRpbmcKKyAgICAgIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoZSBXb3JrIGFuZCBhbnkgbW9kaWZpY2F0aW9ucyBvciBhZGRpdGlvbnMKKyAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQorICAgICAgc3VibWl0dGVkIHRvIExpY2Vuc29yIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsgYnkgdGhlIGNvcHlyaWdodCBvd25lcgorICAgICAgb3IgYnkgYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkgYXV0aG9yaXplZCB0byBzdWJtaXQgb24gYmVoYWxmIG9mCisgICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKKyAgICAgIG1lYW5zIGFueSBmb3JtIG9mIGVsZWN0cm9uaWMsIHZlcmJhbCwgb3Igd3JpdHRlbiBjb21tdW5pY2F0aW9uIHNlbnQKKyAgICAgIHRvIHRoZSBMaWNlbnNvciBvciBpdHMgcmVwcmVzZW50YXRpdmVzLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvCisgICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAorICAgICAgYW5kIGlzc3VlIHRyYWNraW5nIHN5c3RlbXMgdGhhdCBhcmUgbWFuYWdlZCBieSwgb3Igb24gYmVoYWxmIG9mLCB0aGUKKyAgICAgIExpY2Vuc29yIGZvciB0aGUgcHVycG9zZSBvZiBkaXNjdXNzaW5nIGFuZCBpbXByb3ZpbmcgdGhlIFdvcmssIGJ1dAorICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKKyAgICAgIGRlc2lnbmF0ZWQgaW4gd3JpdGluZyBieSB0aGUgY29weXJpZ2h0IG93bmVyIGFzICJOb3QgYSBDb250cmlidXRpb24uIgorCisgICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgb24gYmVoYWxmIG9mIHdob20gYSBDb250cmlidXRpb24gaGFzIGJlZW4gcmVjZWl2ZWQgYnkgTGljZW5zb3IgYW5kCisgICAgICBzdWJzZXF1ZW50bHkgaW5jb3Jwb3JhdGVkIHdpdGhpbiB0aGUgV29yay4KKworICAgMi4gR3JhbnQgb2YgQ29weXJpZ2h0IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgY29weXJpZ2h0IGxpY2Vuc2UgdG8gcmVwcm9kdWNlLCBwcmVwYXJlIERlcml2YXRpdmUgV29ya3Mgb2YsCisgICAgICBwdWJsaWNseSBkaXNwbGF5LCBwdWJsaWNseSBwZXJmb3JtLCBzdWJsaWNlbnNlLCBhbmQgZGlzdHJpYnV0ZSB0aGUKKyAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCisKKyAgIDMuIEdyYW50IG9mIFBhdGVudCBMaWNlbnNlLiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAorICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKKyAgICAgIChleGNlcHQgYXMgc3RhdGVkIGluIHRoaXMgc2VjdGlvbikgcGF0ZW50IGxpY2Vuc2UgdG8gbWFrZSwgaGF2ZSBtYWRlLAorICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCisgICAgICB3aGVyZSBzdWNoIGxpY2Vuc2UgYXBwbGllcyBvbmx5IHRvIHRob3NlIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZQorICAgICAgYnkgc3VjaCBDb250cmlidXRvciB0aGF0IGFyZSBuZWNlc3NhcmlseSBpbmZyaW5nZWQgYnkgdGhlaXIKKyAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKKyAgICAgIHdpdGggdGhlIFdvcmsgdG8gd2hpY2ggc3VjaCBDb250cmlidXRpb24ocykgd2FzIHN1Ym1pdHRlZC4gSWYgWW91CisgICAgICBpbnN0aXR1dGUgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhbnkgZW50aXR5IChpbmNsdWRpbmcgYQorICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yaworICAgICAgb3IgYSBDb250cmlidXRpb24gaW5jb3Jwb3JhdGVkIHdpdGhpbiB0aGUgV29yayBjb25zdGl0dXRlcyBkaXJlY3QKKyAgICAgIG9yIGNvbnRyaWJ1dG9yeSBwYXRlbnQgaW5mcmluZ2VtZW50LCB0aGVuIGFueSBwYXRlbnQgbGljZW5zZXMKKyAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQorICAgICAgYXMgb2YgdGhlIGRhdGUgc3VjaCBsaXRpZ2F0aW9uIGlzIGZpbGVkLgorCisgICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQorICAgICAgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YgaW4gYW55IG1lZGl1bSwgd2l0aCBvciB3aXRob3V0CisgICAgICBtb2RpZmljYXRpb25zLCBhbmQgaW4gU291cmNlIG9yIE9iamVjdCBmb3JtLCBwcm92aWRlZCB0aGF0IFlvdQorICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisKKyAgICAgIChhKSBZb3UgbXVzdCBnaXZlIGFueSBvdGhlciByZWNpcGllbnRzIG9mIHRoZSBXb3JrIG9yCisgICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKKworICAgICAgKGIpIFlvdSBtdXN0IGNhdXNlIGFueSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcworICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAorCisgICAgICAoYykgWW91IG11c3QgcmV0YWluLCBpbiB0aGUgU291cmNlIGZvcm0gb2YgYW55IERlcml2YXRpdmUgV29ya3MKKyAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCisgICAgICAgICAgYXR0cmlidXRpb24gbm90aWNlcyBmcm9tIHRoZSBTb3VyY2UgZm9ybSBvZiB0aGUgV29yaywKKyAgICAgICAgICBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdCBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mCisgICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAorCisgICAgICAoZCkgSWYgdGhlIFdvcmsgaW5jbHVkZXMgYSAiTk9USUNFIiB0ZXh0IGZpbGUgYXMgcGFydCBvZiBpdHMKKyAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CisgICAgICAgICAgaW5jbHVkZSBhIHJlYWRhYmxlIGNvcHkgb2YgdGhlIGF0dHJpYnV0aW9uIG5vdGljZXMgY29udGFpbmVkCisgICAgICAgICAgd2l0aGluIHN1Y2ggTk9USUNFIGZpbGUsIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90CisgICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCisgICAgICAgICAgb2YgdGhlIGZvbGxvd2luZyBwbGFjZXM6IHdpdGhpbiBhIE5PVElDRSB0ZXh0IGZpbGUgZGlzdHJpYnV0ZWQKKyAgICAgICAgICBhcyBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyB3aXRoaW4gdGhlIFNvdXJjZSBmb3JtIG9yCisgICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCisgICAgICAgICAgd2l0aGluIGEgZGlzcGxheSBnZW5lcmF0ZWQgYnkgdGhlIERlcml2YXRpdmUgV29ya3MsIGlmIGFuZAorICAgICAgICAgIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgbm90aWNlcyBub3JtYWxseSBhcHBlYXIuIFRoZSBjb250ZW50cworICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKKyAgICAgICAgICBkbyBub3QgbW9kaWZ5IHRoZSBMaWNlbnNlLiBZb3UgbWF5IGFkZCBZb3VyIG93biBhdHRyaWJ1dGlvbgorICAgICAgICAgIG5vdGljZXMgd2l0aGluIERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSwgYWxvbmdzaWRlCisgICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCisgICAgICAgICAgdGhhdCBzdWNoIGFkZGl0aW9uYWwgYXR0cmlidXRpb24gbm90aWNlcyBjYW5ub3QgYmUgY29uc3RydWVkCisgICAgICAgICAgYXMgbW9kaWZ5aW5nIHRoZSBMaWNlbnNlLgorCisgICAgICBZb3UgbWF5IGFkZCBZb3VyIG93biBjb3B5cmlnaHQgc3RhdGVtZW50IHRvIFlvdXIgbW9kaWZpY2F0aW9ucyBhbmQKKyAgICAgIG1heSBwcm92aWRlIGFkZGl0aW9uYWwgb3IgZGlmZmVyZW50IGxpY2Vuc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMKKyAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKKyAgICAgIGZvciBhbnkgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGFzIGEgd2hvbGUsIHByb3ZpZGVkIFlvdXIgdXNlLAorICAgICAgcmVwcm9kdWN0aW9uLCBhbmQgZGlzdHJpYnV0aW9uIG9mIHRoZSBXb3JrIG90aGVyd2lzZSBjb21wbGllcyB3aXRoCisgICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgorCisgICA1LiBTdWJtaXNzaW9uIG9mIENvbnRyaWJ1dGlvbnMuIFVubGVzcyBZb3UgZXhwbGljaXRseSBzdGF0ZSBvdGhlcndpc2UsCisgICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKKyAgICAgIGJ5IFlvdSB0byB0aGUgTGljZW5zb3Igc2hhbGwgYmUgdW5kZXIgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIHdpdGhvdXQgYW55IGFkZGl0aW9uYWwgdGVybXMgb3IgY29uZGl0aW9ucy4KKyAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKKyAgICAgIHRoZSB0ZXJtcyBvZiBhbnkgc2VwYXJhdGUgbGljZW5zZSBhZ3JlZW1lbnQgeW91IG1heSBoYXZlIGV4ZWN1dGVkCisgICAgICB3aXRoIExpY2Vuc29yIHJlZ2FyZGluZyBzdWNoIENvbnRyaWJ1dGlvbnMuCisKKyAgIDYuIFRyYWRlbWFya3MuIFRoaXMgTGljZW5zZSBkb2VzIG5vdCBncmFudCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgdHJhZGUKKyAgICAgIG5hbWVzLCB0cmFkZW1hcmtzLCBzZXJ2aWNlIG1hcmtzLCBvciBwcm9kdWN0IG5hbWVzIG9mIHRoZSBMaWNlbnNvciwKKyAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQorICAgICAgb3JpZ2luIG9mIHRoZSBXb3JrIGFuZCByZXByb2R1Y2luZyB0aGUgY29udGVudCBvZiB0aGUgTk9USUNFIGZpbGUuCisKKyAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgorICAgICAgYWdyZWVkIHRvIGluIHdyaXRpbmcsIExpY2Vuc29yIHByb3ZpZGVzIHRoZSBXb3JrIChhbmQgZWFjaAorICAgICAgQ29udHJpYnV0b3IgcHJvdmlkZXMgaXRzIENvbnRyaWJ1dGlvbnMpIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKKyAgICAgIGltcGxpZWQsIGluY2x1ZGluZywgd2l0aG91dCBsaW1pdGF0aW9uLCBhbnkgd2FycmFudGllcyBvciBjb25kaXRpb25zCisgICAgICBvZiBUSVRMRSwgTk9OLUlORlJJTkdFTUVOVCwgTUVSQ0hBTlRBQklMSVRZLCBvciBGSVRORVNTIEZPUiBBCisgICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKKyAgICAgIGFwcHJvcHJpYXRlbmVzcyBvZiB1c2luZyBvciByZWRpc3RyaWJ1dGluZyB0aGUgV29yayBhbmQgYXNzdW1lIGFueQorICAgICAgcmlza3MgYXNzb2NpYXRlZCB3aXRoIFlvdXIgZXhlcmNpc2Ugb2YgcGVybWlzc2lvbnMgdW5kZXIgdGhpcyBMaWNlbnNlLgorCisgICA4LiBMaW1pdGF0aW9uIG9mIExpYWJpbGl0eS4gSW4gbm8gZXZlbnQgYW5kIHVuZGVyIG5vIGxlZ2FsIHRoZW9yeSwKKyAgICAgIHdoZXRoZXIgaW4gdG9ydCAoaW5jbHVkaW5nIG5lZ2xpZ2VuY2UpLCBjb250cmFjdCwgb3Igb3RoZXJ3aXNlLAorICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKKyAgICAgIG5lZ2xpZ2VudCBhY3RzKSBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc2hhbGwgYW55IENvbnRyaWJ1dG9yIGJlCisgICAgICBsaWFibGUgdG8gWW91IGZvciBkYW1hZ2VzLCBpbmNsdWRpbmcgYW55IGRpcmVjdCwgaW5kaXJlY3QsIHNwZWNpYWwsCisgICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKKyAgICAgIHJlc3VsdCBvZiB0aGlzIExpY2Vuc2Ugb3Igb3V0IG9mIHRoZSB1c2Ugb3IgaW5hYmlsaXR5IHRvIHVzZSB0aGUKKyAgICAgIFdvcmsgKGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gZGFtYWdlcyBmb3IgbG9zcyBvZiBnb29kd2lsbCwKKyAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCisgICAgICBvdGhlciBjb21tZXJjaWFsIGRhbWFnZXMgb3IgbG9zc2VzKSwgZXZlbiBpZiBzdWNoIENvbnRyaWJ1dG9yCisgICAgICBoYXMgYmVlbiBhZHZpc2VkIG9mIHRoZSBwb3NzaWJpbGl0eSBvZiBzdWNoIGRhbWFnZXMuCisKKyAgIDkuIEFjY2VwdGluZyBXYXJyYW50eSBvciBBZGRpdGlvbmFsIExpYWJpbGl0eS4gV2hpbGUgcmVkaXN0cmlidXRpbmcKKyAgICAgIHRoZSBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgWW91IG1heSBjaG9vc2UgdG8gb2ZmZXIsCisgICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAorICAgICAgb3Igb3RoZXIgbGlhYmlsaXR5IG9ibGlnYXRpb25zIGFuZC9vciByaWdodHMgY29uc2lzdGVudCB3aXRoIHRoaXMKKyAgICAgIExpY2Vuc2UuIEhvd2V2ZXIsIGluIGFjY2VwdGluZyBzdWNoIG9ibGlnYXRpb25zLCBZb3UgbWF5IGFjdCBvbmx5CisgICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgorICAgICAgb2YgYW55IG90aGVyIENvbnRyaWJ1dG9yLCBhbmQgb25seSBpZiBZb3UgYWdyZWUgdG8gaW5kZW1uaWZ5LAorICAgICAgZGVmZW5kLCBhbmQgaG9sZCBlYWNoIENvbnRyaWJ1dG9yIGhhcm1sZXNzIGZvciBhbnkgbGlhYmlsaXR5CisgICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCisgICAgICBvZiB5b3VyIGFjY2VwdGluZyBhbnkgc3VjaCB3YXJyYW50eSBvciBhZGRpdGlvbmFsIGxpYWJpbGl0eS4KKworICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvUGFyY2VsLmNwcCBiL2xpYnMvdXRpbHMvUGFyY2VsLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjRiNjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9QYXJjZWwuY3BwCkBAIC0wLDAgKzEsMTM3NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiUGFyY2VsIgorLy8jZGVmaW5lIExPR19OREVCVUcgMAorCisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisKKyNpbmNsdWRlIDx1dGlscy9CaW5kZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9CcEJpbmRlci5oPgorI2luY2x1ZGUgPHV0aWxzL0RlYnVnLmg+CisjaW5jbHVkZSA8dXRpbHMvUHJvY2Vzc1N0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzE2Lmg+CisjaW5jbHVkZSA8dXRpbHMvVGV4dE91dHB1dC5oPgorI2luY2x1ZGUgPHV0aWxzL21pc2MuaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdXRpbHMvYmluZGVyX21vZHVsZS5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKworI2lmbmRlZiBJTlQzMl9NQVgKKyNkZWZpbmUgSU5UMzJfTUFYICgoaW50MzJfdCkoMjE0NzQ4MzY0NykpCisjZW5kaWYKKworI2RlZmluZSBMT0dfUkVGUyguLi4pCisvLyNkZWZpbmUgTE9HX1JFRlMoLi4uKSBMT0coTE9HX0RFQlVHLCAiUGFyY2VsIiwgX19WQV9BUkdTX18pCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZGVmaW5lIFBBRF9TSVpFKHMpICgoKHMpKzMpJn4zKQorCisvLyBYWFggVGhpcyBjYW4gYmUgbWFkZSBwdWJsaWMgaWYgd2Ugd2FudCB0byBwcm92aWRlCisvLyBzdXBwb3J0IGZvciB0eXBlZCBkYXRhLgorc3RydWN0IHNtYWxsX2ZsYXRfZGF0YQoreworICAgIHVpbnQzMl90IHR5cGU7CisgICAgdWludDMyX3QgZGF0YTsKK307CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKwordm9pZCBhY3F1aXJlX29iamVjdChjb25zdCBzcDxQcm9jZXNzU3RhdGU+JiBwcm9jLAorICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCYgb2JqLCBjb25zdCB2b2lkKiB3aG8pCit7CisgICAgc3dpdGNoIChvYmoudHlwZSkgeworICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX0JJTkRFUjoKKyAgICAgICAgICAgIGlmIChvYmouYmluZGVyKSB7CisgICAgICAgICAgICAgICAgTE9HX1JFRlMoIlBhcmNlbCAlcCBhY3F1aXJpbmcgcmVmZXJlbmNlIG9uIGxvY2FsICVwIiwgd2hvLCBvYmouY29va2llKTsKKyAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxJQmluZGVyKj4ob2JqLmNvb2tpZSktPmluY1N0cm9uZyh3aG8pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX1dFQUtfQklOREVSOgorICAgICAgICAgICAgaWYgKG9iai5iaW5kZXIpCisgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8UmVmQmFzZTo6d2Vha3JlZl90eXBlKj4ob2JqLmJpbmRlciktPmluY1dlYWsod2hvKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBCSU5ERVJfVFlQRV9IQU5ETEU6IHsKKyAgICAgICAgICAgIGNvbnN0IHNwPElCaW5kZXI+IGIgPSBwcm9jLT5nZXRTdHJvbmdQcm94eUZvckhhbmRsZShvYmouaGFuZGxlKTsKKyAgICAgICAgICAgIGlmIChiICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBMT0dfUkVGUygiUGFyY2VsICVwIGFjcXVpcmluZyByZWZlcmVuY2Ugb24gcmVtb3RlICVwIiwgd2hvLCBiLmdldCgpKTsKKyAgICAgICAgICAgICAgICBiLT5pbmNTdHJvbmcod2hvKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX1dFQUtfSEFORExFOiB7CisgICAgICAgICAgICBjb25zdCB3cDxJQmluZGVyPiBiID0gcHJvYy0+Z2V0V2Vha1Byb3h5Rm9ySGFuZGxlKG9iai5oYW5kbGUpOworICAgICAgICAgICAgaWYgKGIgIT0gTlVMTCkgYi5nZXRfcmVmcygpLT5pbmNXZWFrKHdobyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY2FzZSBCSU5ERVJfVFlQRV9GRDogeworICAgICAgICAgICAgLy8gaW50ZW50aW9uYWxseSBibGFuayAtLSBub3RoaW5nIHRvIGRvIHRvIGFjcXVpcmUgdGhpcywgYnV0IHdlIGRvCisgICAgICAgICAgICAvLyByZWNvZ25pemUgaXQgYXMgYSBsZWdpdGltYXRlIG9iamVjdCB0eXBlLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorCisgICAgTE9HRCgiSW52YWxpZCBvYmplY3QgdHlwZSAweCUwOGx4Iiwgb2JqLnR5cGUpOworfQorCit2b2lkIHJlbGVhc2Vfb2JqZWN0KGNvbnN0IHNwPFByb2Nlc3NTdGF0ZT4mIHByb2MsCisgICAgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0JiBvYmosIGNvbnN0IHZvaWQqIHdobykKK3sKKyAgICBzd2l0Y2ggKG9iai50eXBlKSB7CisgICAgICAgIGNhc2UgQklOREVSX1RZUEVfQklOREVSOgorICAgICAgICAgICAgaWYgKG9iai5iaW5kZXIpIHsKKyAgICAgICAgICAgICAgICBMT0dfUkVGUygiUGFyY2VsICVwIHJlbGVhc2luZyByZWZlcmVuY2Ugb24gbG9jYWwgJXAiLCB3aG8sIG9iai5jb29raWUpOworICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PElCaW5kZXIqPihvYmouY29va2llKS0+ZGVjU3Ryb25nKHdobyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGNhc2UgQklOREVSX1RZUEVfV0VBS19CSU5ERVI6CisgICAgICAgICAgICBpZiAob2JqLmJpbmRlcikKKyAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqPihvYmouYmluZGVyKS0+ZGVjV2Vhayh3aG8pOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX0hBTkRMRTogeworICAgICAgICAgICAgY29uc3Qgc3A8SUJpbmRlcj4gYiA9IHByb2MtPmdldFN0cm9uZ1Byb3h5Rm9ySGFuZGxlKG9iai5oYW5kbGUpOworICAgICAgICAgICAgaWYgKGIgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIExPR19SRUZTKCJQYXJjZWwgJXAgcmVsZWFzaW5nIHJlZmVyZW5jZSBvbiByZW1vdGUgJXAiLCB3aG8sIGIuZ2V0KCkpOworICAgICAgICAgICAgICAgIGItPmRlY1N0cm9uZyh3aG8pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNhc2UgQklOREVSX1RZUEVfV0VBS19IQU5ETEU6IHsKKyAgICAgICAgICAgIGNvbnN0IHdwPElCaW5kZXI+IGIgPSBwcm9jLT5nZXRXZWFrUHJveHlGb3JIYW5kbGUob2JqLmhhbmRsZSk7CisgICAgICAgICAgICBpZiAoYiAhPSBOVUxMKSBiLmdldF9yZWZzKCktPmRlY1dlYWsod2hvKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX0ZEOiB7CisgICAgICAgICAgICBpZiAob2JqLmNvb2tpZSAhPSAodm9pZCopMCkgY2xvc2Uob2JqLmhhbmRsZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBMT0dFKCJJbnZhbGlkIG9iamVjdCB0eXBlIDB4JTA4bHgiLCBvYmoudHlwZSk7Cit9CisKK2lubGluZSBzdGF0aWMgc3RhdHVzX3QgZmluaXNoX2ZsYXR0ZW5fYmluZGVyKAorICAgIGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIsIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCYgZmxhdCwgUGFyY2VsKiBvdXQpCit7CisgICAgcmV0dXJuIG91dC0+d3JpdGVPYmplY3QoZmxhdCwgZmFsc2UpOworfQorCitzdGF0dXNfdCBmbGF0dGVuX2JpbmRlcihjb25zdCBzcDxQcm9jZXNzU3RhdGU+JiBwcm9jLAorICAgIGNvbnN0IHNwPElCaW5kZXI+JiBiaW5kZXIsIFBhcmNlbCogb3V0KQoreworICAgIGZsYXRfYmluZGVyX29iamVjdCBvYmo7CisgICAgCisgICAgb2JqLmZsYWdzID0gMHg3ZiB8IEZMQVRfQklOREVSX0ZMQUdfQUNDRVBUU19GRFM7CisgICAgaWYgKGJpbmRlciAhPSBOVUxMKSB7CisgICAgICAgIElCaW5kZXIgKmxvY2FsID0gYmluZGVyLT5sb2NhbEJpbmRlcigpOworICAgICAgICBpZiAoIWxvY2FsKSB7CisgICAgICAgICAgICBCcEJpbmRlciAqcHJveHkgPSBiaW5kZXItPnJlbW90ZUJpbmRlcigpOworICAgICAgICAgICAgaWYgKHByb3h5ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBMT0dFKCJudWxsIHByb3h5Iik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IGhhbmRsZSA9IHByb3h5ID8gcHJveHktPmhhbmRsZSgpIDogMDsKKyAgICAgICAgICAgIG9iai50eXBlID0gQklOREVSX1RZUEVfSEFORExFOworICAgICAgICAgICAgb2JqLmhhbmRsZSA9IGhhbmRsZTsKKyAgICAgICAgICAgIG9iai5jb29raWUgPSBOVUxMOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb2JqLnR5cGUgPSBCSU5ERVJfVFlQRV9CSU5ERVI7CisgICAgICAgICAgICBvYmouYmluZGVyID0gbG9jYWwtPmdldFdlYWtSZWZzKCk7CisgICAgICAgICAgICBvYmouY29va2llID0gbG9jYWw7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBvYmoudHlwZSA9IEJJTkRFUl9UWVBFX0JJTkRFUjsKKyAgICAgICAgb2JqLmJpbmRlciA9IE5VTEw7CisgICAgICAgIG9iai5jb29raWUgPSBOVUxMOworICAgIH0KKyAgICAKKyAgICByZXR1cm4gZmluaXNoX2ZsYXR0ZW5fYmluZGVyKGJpbmRlciwgb2JqLCBvdXQpOworfQorCitzdGF0dXNfdCBmbGF0dGVuX2JpbmRlcihjb25zdCBzcDxQcm9jZXNzU3RhdGU+JiBwcm9jLAorICAgIGNvbnN0IHdwPElCaW5kZXI+JiBiaW5kZXIsIFBhcmNlbCogb3V0KQoreworICAgIGZsYXRfYmluZGVyX29iamVjdCBvYmo7CisgICAgCisgICAgb2JqLmZsYWdzID0gMHg3ZiB8IEZMQVRfQklOREVSX0ZMQUdfQUNDRVBUU19GRFM7CisgICAgaWYgKGJpbmRlciAhPSBOVUxMKSB7CisgICAgICAgIHNwPElCaW5kZXI+IHJlYWwgPSBiaW5kZXIucHJvbW90ZSgpOworICAgICAgICBpZiAocmVhbCAhPSBOVUxMKSB7CisgICAgICAgICAgICBJQmluZGVyICpsb2NhbCA9IHJlYWwtPmxvY2FsQmluZGVyKCk7CisgICAgICAgICAgICBpZiAoIWxvY2FsKSB7CisgICAgICAgICAgICAgICAgQnBCaW5kZXIgKnByb3h5ID0gcmVhbC0+cmVtb3RlQmluZGVyKCk7CisgICAgICAgICAgICAgICAgaWYgKHByb3h5ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HRSgibnVsbCBwcm94eSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb25zdCBpbnQzMl90IGhhbmRsZSA9IHByb3h5ID8gcHJveHktPmhhbmRsZSgpIDogMDsKKyAgICAgICAgICAgICAgICBvYmoudHlwZSA9IEJJTkRFUl9UWVBFX1dFQUtfSEFORExFOworICAgICAgICAgICAgICAgIG9iai5oYW5kbGUgPSBoYW5kbGU7CisgICAgICAgICAgICAgICAgb2JqLmNvb2tpZSA9IE5VTEw7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG9iai50eXBlID0gQklOREVSX1RZUEVfV0VBS19CSU5ERVI7CisgICAgICAgICAgICAgICAgb2JqLmJpbmRlciA9IGJpbmRlci5nZXRfcmVmcygpOworICAgICAgICAgICAgICAgIG9iai5jb29raWUgPSBiaW5kZXIudW5zYWZlX2dldCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZpbmlzaF9mbGF0dGVuX2JpbmRlcihyZWFsLCBvYmosIG91dCk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIC8vIFhYWCBIb3cgdG8gZGVhbD8gIEluIG9yZGVyIHRvIGZsYXR0ZW4gdGhlIGdpdmVuIGJpbmRlciwKKyAgICAgICAgLy8gd2UgbmVlZCB0byBwcm9iZSBpdCBmb3IgaW5mb3JtYXRpb24sIHdoaWNoIHJlcXVpcmVzIGEgcHJpbWFyeQorICAgICAgICAvLyByZWZlcmVuY2UuLi4gIGJ1dCB3ZSBkb24ndCBoYXZlIG9uZS4KKyAgICAgICAgLy8KKyAgICAgICAgLy8gVGhlIE9wZW5CaW5kZXIgaW1wbGVtZW50YXRpb24gdXNlcyBhIGR5bmFtaWNfY2FzdDw+IGhlcmUsCisgICAgICAgIC8vIGJ1dCB3ZSBjYW4ndCBkbyB0aGF0IHdpdGggdGhlIGRpZmZlcmVudCByZWZlcmVuY2UgY291bnRpbmcKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gd2UgYXJlIHVzaW5nLgorICAgICAgICBMT0dFKCJVbmFibGUgdG8gdW5mbGF0dGVuIEJpbmRlciB3ZWFrIHJlZmVyZW5jZSEiKTsKKyAgICAgICAgb2JqLnR5cGUgPSBCSU5ERVJfVFlQRV9CSU5ERVI7CisgICAgICAgIG9iai5iaW5kZXIgPSBOVUxMOworICAgICAgICBvYmouY29va2llID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIGZpbmlzaF9mbGF0dGVuX2JpbmRlcihOVUxMLCBvYmosIG91dCk7CisgICAgCisgICAgfSBlbHNlIHsKKyAgICAgICAgb2JqLnR5cGUgPSBCSU5ERVJfVFlQRV9CSU5ERVI7CisgICAgICAgIG9iai5iaW5kZXIgPSBOVUxMOworICAgICAgICBvYmouY29va2llID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIGZpbmlzaF9mbGF0dGVuX2JpbmRlcihOVUxMLCBvYmosIG91dCk7CisgICAgfQorfQorCitpbmxpbmUgc3RhdGljIHN0YXR1c190IGZpbmlzaF91bmZsYXR0ZW5fYmluZGVyKAorICAgIEJwQmluZGVyKiBwcm94eSwgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0JiBmbGF0LCBjb25zdCBQYXJjZWwmIGluKQoreworICAgIHJldHVybiBOT19FUlJPUjsKK30KKyAgICAKK3N0YXR1c190IHVuZmxhdHRlbl9iaW5kZXIoY29uc3Qgc3A8UHJvY2Vzc1N0YXRlPiYgcHJvYywKKyAgICBjb25zdCBQYXJjZWwmIGluLCBzcDxJQmluZGVyPiogb3V0KQoreworICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCogZmxhdCA9IGluLnJlYWRPYmplY3QoZmFsc2UpOworICAgIAorICAgIGlmIChmbGF0KSB7CisgICAgICAgIHN3aXRjaCAoZmxhdC0+dHlwZSkgeworICAgICAgICAgICAgY2FzZSBCSU5ERVJfVFlQRV9CSU5ERVI6CisgICAgICAgICAgICAgICAgKm91dCA9IHN0YXRpY19jYXN0PElCaW5kZXIqPihmbGF0LT5jb29raWUpOworICAgICAgICAgICAgICAgIHJldHVybiBmaW5pc2hfdW5mbGF0dGVuX2JpbmRlcihOVUxMLCAqZmxhdCwgaW4pOworICAgICAgICAgICAgY2FzZSBCSU5ERVJfVFlQRV9IQU5ETEU6CisgICAgICAgICAgICAgICAgKm91dCA9IHByb2MtPmdldFN0cm9uZ1Byb3h5Rm9ySGFuZGxlKGZsYXQtPmhhbmRsZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmlzaF91bmZsYXR0ZW5fYmluZGVyKAorICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxCcEJpbmRlcio+KG91dC0+Z2V0KCkpLCAqZmxhdCwgaW4pOworICAgICAgICB9ICAgICAgICAKKyAgICB9CisgICAgcmV0dXJuIEJBRF9UWVBFOworfQorCitzdGF0dXNfdCB1bmZsYXR0ZW5fYmluZGVyKGNvbnN0IHNwPFByb2Nlc3NTdGF0ZT4mIHByb2MsCisgICAgY29uc3QgUGFyY2VsJiBpbiwgd3A8SUJpbmRlcj4qIG91dCkKK3sKKyAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIGZsYXQgPSBpbi5yZWFkT2JqZWN0KGZhbHNlKTsKKyAgICAKKyAgICBpZiAoZmxhdCkgeworICAgICAgICBzd2l0Y2ggKGZsYXQtPnR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgQklOREVSX1RZUEVfQklOREVSOgorICAgICAgICAgICAgICAgICpvdXQgPSBzdGF0aWNfY2FzdDxJQmluZGVyKj4oZmxhdC0+Y29va2llKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmluaXNoX3VuZmxhdHRlbl9iaW5kZXIoTlVMTCwgKmZsYXQsIGluKTsKKyAgICAgICAgICAgIGNhc2UgQklOREVSX1RZUEVfV0VBS19CSU5ERVI6CisgICAgICAgICAgICAgICAgaWYgKGZsYXQtPmJpbmRlciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIG91dC0+c2V0X29iamVjdF9hbmRfcmVmcygKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PElCaW5kZXIqPihmbGF0LT5jb29raWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8UmVmQmFzZTo6d2Vha3JlZl90eXBlKj4oZmxhdC0+YmluZGVyKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgKm91dCA9IE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBmaW5pc2hfdW5mbGF0dGVuX2JpbmRlcihOVUxMLCAqZmxhdCwgaW4pOworICAgICAgICAgICAgY2FzZSBCSU5ERVJfVFlQRV9IQU5ETEU6CisgICAgICAgICAgICBjYXNlIEJJTkRFUl9UWVBFX1dFQUtfSEFORExFOgorICAgICAgICAgICAgICAgICpvdXQgPSBwcm9jLT5nZXRXZWFrUHJveHlGb3JIYW5kbGUoZmxhdC0+aGFuZGxlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmluaXNoX3VuZmxhdHRlbl9iaW5kZXIoCisgICAgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PEJwQmluZGVyKj4ob3V0LT51bnNhZmVfZ2V0KCkpLCAqZmxhdCwgaW4pOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBCQURfVFlQRTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1BhcmNlbDo6UGFyY2VsKCkKK3sKKyAgICBpbml0U3RhdGUoKTsKK30KKworUGFyY2VsOjp+UGFyY2VsKCkKK3sKKyAgICBmcmVlRGF0YU5vSW5pdCgpOworfQorCitjb25zdCB1aW50OF90KiBQYXJjZWw6OmRhdGEoKSBjb25zdAoreworICAgIHJldHVybiBtRGF0YTsKK30KKworc2l6ZV90IFBhcmNlbDo6ZGF0YVNpemUoKSBjb25zdAoreworICAgIHJldHVybiAobURhdGFTaXplID4gbURhdGFQb3MgPyBtRGF0YVNpemUgOiBtRGF0YVBvcyk7Cit9CisKK3NpemVfdCBQYXJjZWw6OmRhdGFBdmFpbCgpIGNvbnN0Cit7CisgICAgLy8gVE9ETzogZGVjaWRlIHdoYXQgdG8gZG8gYWJvdXQgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhpcyBjYW4KKyAgICAvLyByZXBvcnQgYW4gYXZhaWxhYmxlLWRhdGEgc2l6ZSB0aGF0IGV4Y2VlZHMgYSBKYXZhIGludCdzIG1heAorICAgIC8vIHBvc2l0aXZlIHZhbHVlLCBjYXVzaW5nIGhhdm9jLiAgRm9ydHVuYXRlbHkgdGhpcyB3aWxsIG9ubHkKKyAgICAvLyBoYXBwZW4gaWYgc29tZW9uZSBjb25zdHJ1Y3RzIGEgUGFyY2VsIGNvbnRhaW5pbmcgbW9yZSB0aGFuIHR3bworICAgIC8vIGdpZ2FieXRlcyBvZiBkYXRhLCB3aGljaCBvbiB0eXBpY2FsIHBob25lIGhhcmR3YXJlIGlzIHNpbXBseQorICAgIC8vIG5vdCBwb3NzaWJsZS4KKyAgICByZXR1cm4gZGF0YVNpemUoKSAtIGRhdGFQb3NpdGlvbigpOworfQorCitzaXplX3QgUGFyY2VsOjpkYXRhUG9zaXRpb24oKSBjb25zdAoreworICAgIHJldHVybiBtRGF0YVBvczsKK30KKworc2l6ZV90IFBhcmNlbDo6ZGF0YUNhcGFjaXR5KCkgY29uc3QKK3sKKyAgICByZXR1cm4gbURhdGFDYXBhY2l0eTsKK30KKworc3RhdHVzX3QgUGFyY2VsOjpzZXREYXRhU2l6ZShzaXplX3Qgc2l6ZSkKK3sKKyAgICBzdGF0dXNfdCBlcnI7CisgICAgZXJyID0gY29udGludWVXcml0ZShzaXplKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSB7CisgICAgICAgIG1EYXRhU2l6ZSA9IHNpemU7CisgICAgICAgIExPR1YoInNldERhdGFTaXplIFNldHRpbmcgZGF0YSBzaXplIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVNpemUpOworICAgIH0KKyAgICByZXR1cm4gZXJyOworfQorCit2b2lkIFBhcmNlbDo6c2V0RGF0YVBvc2l0aW9uKHNpemVfdCBwb3MpIGNvbnN0Cit7CisgICAgbURhdGFQb3MgPSBwb3M7CisgICAgbU5leHRPYmplY3RIaW50ID0gMDsKK30KKworc3RhdHVzX3QgUGFyY2VsOjpzZXREYXRhQ2FwYWNpdHkoc2l6ZV90IHNpemUpCit7CisgICAgaWYgKHNpemUgPiBtRGF0YVNpemUpIHJldHVybiBjb250aW51ZVdyaXRlKHNpemUpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjpzZXREYXRhKGNvbnN0IHVpbnQ4X3QqIGJ1ZmZlciwgc2l6ZV90IGxlbikKK3sKKyAgICBzdGF0dXNfdCBlcnIgPSByZXN0YXJ0V3JpdGUobGVuKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSB7CisgICAgICAgIG1lbWNweShjb25zdF9jYXN0PHVpbnQ4X3QqPihkYXRhKCkpLCBidWZmZXIsIGxlbik7CisgICAgICAgIG1EYXRhU2l6ZSA9IGxlbjsKKyAgICAgICAgbUZkc0tub3duID0gZmFsc2U7CisgICAgfQorICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6YXBwZW5kRnJvbShQYXJjZWwgKnBhcmNlbCwgc2l6ZV90IG9mZnNldCwgc2l6ZV90IGxlbikKK3sKKyAgICBjb25zdCBzcDxQcm9jZXNzU3RhdGU+IHByb2MoUHJvY2Vzc1N0YXRlOjpzZWxmKCkpOworICAgIHN0YXR1c190IGVycjsKKyAgICB1aW50OF90ICpkYXRhID0gcGFyY2VsLT5tRGF0YTsKKyAgICBzaXplX3QgKm9iamVjdHMgPSBwYXJjZWwtPm1PYmplY3RzOworICAgIHNpemVfdCBzaXplID0gcGFyY2VsLT5tT2JqZWN0c1NpemU7CisgICAgaW50IHN0YXJ0UG9zID0gbURhdGFQb3M7CisgICAgaW50IGZpcnN0SW5kZXggPSAtMSwgbGFzdEluZGV4ID0gLTI7CisKKyAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKworICAgIC8vIHJhbmdlIGNoZWNrcyBhZ2FpbnN0IHRoZSBzb3VyY2UgcGFyY2VsIHNpemUKKyAgICBpZiAoKG9mZnNldCA+IHBhcmNlbC0+bURhdGFTaXplKQorICAgICAgICAgICAgfHwgKGxlbiA+IHBhcmNlbC0+bURhdGFTaXplKQorICAgICAgICAgICAgfHwgKG9mZnNldCArIGxlbiA+IHBhcmNlbC0+bURhdGFTaXplKSkgeworICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOworICAgIH0KKworICAgIC8vIENvdW50IG9iamVjdHMgaW4gcmFuZ2UKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IChpbnQpIHNpemU7IGkrKykgeworICAgICAgICBzaXplX3Qgb2ZmID0gb2JqZWN0c1tpXTsKKyAgICAgICAgaWYgKChvZmYgPj0gb2Zmc2V0KSAmJiAob2ZmIDwgb2Zmc2V0ICsgbGVuKSkgeworICAgICAgICAgICAgaWYgKGZpcnN0SW5kZXggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBmaXJzdEluZGV4ID0gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxhc3RJbmRleCA9IGk7CisgICAgICAgIH0KKyAgICB9CisgICAgaW50IG51bU9iamVjdHMgPSBsYXN0SW5kZXggLSBmaXJzdEluZGV4ICsgMTsKKworICAgIC8vIGdyb3cgZGF0YQorICAgIGVyciA9IGdyb3dEYXRhKGxlbik7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICByZXR1cm4gZXJyOworICAgIH0KKworICAgIC8vIGFwcGVuZCBkYXRhCisgICAgbWVtY3B5KG1EYXRhICsgbURhdGFQb3MsIGRhdGEgKyBvZmZzZXQsIGxlbik7CisgICAgbURhdGFQb3MgKz0gbGVuOworICAgIG1EYXRhU2l6ZSArPSBsZW47CisKKyAgICBpZiAobnVtT2JqZWN0cyA+IDApIHsKKyAgICAgICAgLy8gZ3JvdyBvYmplY3RzCisgICAgICAgIGlmIChtT2JqZWN0c0NhcGFjaXR5IDwgbU9iamVjdHNTaXplICsgbnVtT2JqZWN0cykgeworICAgICAgICAgICAgaW50IG5ld1NpemUgPSAoKG1PYmplY3RzU2l6ZSArIG51bU9iamVjdHMpKjMpLzI7CisgICAgICAgICAgICBzaXplX3QgKm9iamVjdHMgPQorICAgICAgICAgICAgICAgIChzaXplX3QqKXJlYWxsb2MobU9iamVjdHMsIG5ld1NpemUqc2l6ZW9mKHNpemVfdCkpOworICAgICAgICAgICAgaWYgKG9iamVjdHMgPT0gKHNpemVfdCopMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtT2JqZWN0cyA9IG9iamVjdHM7CisgICAgICAgICAgICBtT2JqZWN0c0NhcGFjaXR5ID0gbmV3U2l6ZTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gYXBwZW5kIGFuZCBhY3F1aXJlIG9iamVjdHMKKyAgICAgICAgaW50IGlkeCA9IG1PYmplY3RzU2l6ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IGZpcnN0SW5kZXg7IGkgPD0gbGFzdEluZGV4OyBpKyspIHsKKyAgICAgICAgICAgIHNpemVfdCBvZmYgPSBvYmplY3RzW2ldIC0gb2Zmc2V0ICsgc3RhcnRQb3M7CisgICAgICAgICAgICBtT2JqZWN0c1tpZHgrK10gPSBvZmY7CisgICAgICAgICAgICBtT2JqZWN0c1NpemUrKzsKKworICAgICAgICAgICAgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0KiBmbGF0CisgICAgICAgICAgICAgICAgPSByZWludGVycHJldF9jYXN0PGZsYXRfYmluZGVyX29iamVjdCo+KG1EYXRhICsgb2ZmKTsKKyAgICAgICAgICAgIGFjcXVpcmVfb2JqZWN0KHByb2MsICpmbGF0LCB0aGlzKTsKKworICAgICAgICAgICAgLy8gdGFrZSBub3RlIGlmIHRoZSBvYmplY3QgaXMgYSBmaWxlIGRlc2NyaXB0b3IKKyAgICAgICAgICAgIGlmIChmbGF0LT50eXBlID09IEJJTkRFUl9UWVBFX0ZEKSB7CisgICAgICAgICAgICAgICAgbUhhc0ZkcyA9IG1GZHNLbm93biA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK2Jvb2wgUGFyY2VsOjpoYXNGaWxlRGVzY3JpcHRvcnMoKSBjb25zdAoreworICAgIGlmICghbUZkc0tub3duKSB7CisgICAgICAgIHNjYW5Gb3JGZHMoKTsKKyAgICB9CisgICAgcmV0dXJuIG1IYXNGZHM7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGVJbnRlcmZhY2VUb2tlbihjb25zdCBTdHJpbmcxNiYgaW50ZXJmYWNlKQoreworICAgIC8vIGN1cnJlbnRseSB0aGUgaW50ZXJmYWNlIGlkZW50aWZpY2F0aW9uIHRva2VuIGlzIGp1c3QgaXRzIG5hbWUgYXMgYSBzdHJpbmcKKyAgICByZXR1cm4gd3JpdGVTdHJpbmcxNihpbnRlcmZhY2UpOworfQorCitib29sIFBhcmNlbDo6ZW5mb3JjZUludGVyZmFjZShjb25zdCBTdHJpbmcxNiYgaW50ZXJmYWNlKSBjb25zdAoreworICAgIFN0cmluZzE2IHN0ciA9IHJlYWRTdHJpbmcxNigpOworICAgIGlmIChzdHIgPT0gaW50ZXJmYWNlKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR1coIioqKiogZW5mb3JjZUludGVyZmFjZSgpIGV4cGVjdGVkICclcycgYnV0IHJlYWQgJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICBTdHJpbmc4KGludGVyZmFjZSkuc3RyaW5nKCksIFN0cmluZzgoc3RyKS5zdHJpbmcoKSk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9IAorCitjb25zdCBzaXplX3QqIFBhcmNlbDo6b2JqZWN0cygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1PYmplY3RzOworfQorCitzaXplX3QgUGFyY2VsOjpvYmplY3RzQ291bnQoKSBjb25zdAoreworICAgIHJldHVybiBtT2JqZWN0c1NpemU7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6ZXJyb3JDaGVjaygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1FcnJvcjsKK30KKwordm9pZCBQYXJjZWw6OnNldEVycm9yKHN0YXR1c190IGVycikKK3sKKyAgICBtRXJyb3IgPSBlcnI7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6ZmluaXNoV3JpdGUoc2l6ZV90IGxlbikKK3sKKyAgICAvL3ByaW50ZigiRmluaXNoIHdyaXRlIG9mICVkXG4iLCBsZW4pOworICAgIG1EYXRhUG9zICs9IGxlbjsKKyAgICBMT0dWKCJmaW5pc2hXcml0ZSBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgaWYgKG1EYXRhUG9zID4gbURhdGFTaXplKSB7CisgICAgICAgIG1EYXRhU2l6ZSA9IG1EYXRhUG9zOworICAgICAgICBMT0dWKCJmaW5pc2hXcml0ZSBTZXR0aW5nIGRhdGEgc2l6ZSBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFTaXplKTsKKyAgICB9CisgICAgLy9wcmludGYoIk5ldyBwb3M9JWQsIHNpemU9JWRcbiIsIG1EYXRhUG9zLCBtRGF0YVNpemUpOworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZVVucGFkZGVkKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBsZW4pCit7CisgICAgc2l6ZV90IGVuZCA9IG1EYXRhUG9zICsgbGVuOworICAgIGlmIChlbmQgPCBtRGF0YVBvcykgeworICAgICAgICAvLyBpbnRlZ2VyIG92ZXJmbG93CisgICAgICAgIHJldHVybiBCQURfVkFMVUU7CisgICAgfQorCisgICAgaWYgKGVuZCA8PSBtRGF0YUNhcGFjaXR5KSB7CityZXN0YXJ0X3dyaXRlOgorICAgICAgICBtZW1jcHkobURhdGErbURhdGFQb3MsIGRhdGEsIGxlbik7CisgICAgICAgIHJldHVybiBmaW5pc2hXcml0ZShsZW4pOworICAgIH0KKworICAgIHN0YXR1c190IGVyciA9IGdyb3dEYXRhKGxlbik7CisgICAgaWYgKGVyciA9PSBOT19FUlJPUikgZ290byByZXN0YXJ0X3dyaXRlOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGUoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IGxlbikKK3sKKyAgICB2b2lkKiBjb25zdCBkID0gd3JpdGVJbnBsYWNlKGxlbik7CisgICAgaWYgKGQpIHsKKyAgICAgICAgbWVtY3B5KGQsIGRhdGEsIGxlbik7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgcmV0dXJuIG1FcnJvcjsKK30KKwordm9pZCogUGFyY2VsOjp3cml0ZUlucGxhY2Uoc2l6ZV90IGxlbikKK3sKKyAgICBjb25zdCBzaXplX3QgcGFkZGVkID0gUEFEX1NJWkUobGVuKTsKKworICAgIC8vIHNhbml0eSBjaGVjayBmb3IgaW50ZWdlciBvdmVyZmxvdworICAgIGlmIChtRGF0YVBvcytwYWRkZWQgPCBtRGF0YVBvcykgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoKG1EYXRhUG9zK3BhZGRlZCkgPD0gbURhdGFDYXBhY2l0eSkgeworcmVzdGFydF93cml0ZToKKyAgICAgICAgLy9wcmludGYoIldyaXRpbmcgJWxkIGJ5dGVzLCBwYWRkZWQgdG8gJWxkXG4iLCBsZW4sIHBhZGRlZCk7CisgICAgICAgIHVpbnQ4X3QqIGNvbnN0IGRhdGEgPSBtRGF0YSttRGF0YVBvczsKKworICAgICAgICAvLyBOZWVkIHRvIHBhZCBhdCBlbmQ/CisgICAgICAgIGlmIChwYWRkZWQgIT0gbGVuKSB7CisjaWYgQllURV9PUkRFUiA9PSBCSUdfRU5ESUFOCisgICAgICAgICAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgbWFza1s0XSA9IHsKKyAgICAgICAgICAgICAgICAweDAwMDAwMDAwLCAweGZmZmZmZjAwLCAweGZmZmYwMDAwLCAweGZmMDAwMDAwCisgICAgICAgICAgICB9OworI2VuZGlmCisjaWYgQllURV9PUkRFUiA9PSBMSVRUTEVfRU5ESUFOCisgICAgICAgICAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgbWFza1s0XSA9IHsKKyAgICAgICAgICAgICAgICAweDAwMDAwMDAwLCAweDAwZmZmZmZmLCAweDAwMDBmZmZmLCAweDAwMDAwMGZmCisgICAgICAgICAgICB9OworI2VuZGlmCisgICAgICAgICAgICAvL3ByaW50ZigiQXBwbHlpbmcgcGFkIG1hc2s6ICVwIHRvICVwXG4iLCAodm9pZCopbWFza1twYWRkZWQtbGVuXSwKKyAgICAgICAgICAgIC8vICAgICpyZWludGVycHJldF9jYXN0PHZvaWQqKj4oZGF0YStwYWRkZWQtNCkpOworICAgICAgICAgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyX3QqPihkYXRhK3BhZGRlZC00KSAmPSBtYXNrW3BhZGRlZC1sZW5dOworICAgICAgICB9CisKKyAgICAgICAgZmluaXNoV3JpdGUocGFkZGVkKTsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgc3RhdHVzX3QgZXJyID0gZ3Jvd0RhdGEocGFkZGVkKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSBnb3RvIHJlc3RhcnRfd3JpdGU7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGVJbnQzMihpbnQzMl90IHZhbCkKK3sKKyAgICBpZiAoKG1EYXRhUG9zK3NpemVvZih2YWwpKSA8PSBtRGF0YUNhcGFjaXR5KSB7CityZXN0YXJ0X3dyaXRlOgorICAgICAgICAqcmVpbnRlcnByZXRfY2FzdDxpbnQzMl90Kj4obURhdGErbURhdGFQb3MpID0gdmFsOworICAgICAgICByZXR1cm4gZmluaXNoV3JpdGUoc2l6ZW9mKHZhbCkpOworICAgIH0KKworICAgIHN0YXR1c190IGVyciA9IGdyb3dEYXRhKHNpemVvZih2YWwpKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSBnb3RvIHJlc3RhcnRfd3JpdGU7CisgICAgcmV0dXJuIGVycjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZUludDY0KGludDY0X3QgdmFsKQoreworICAgIGlmICgobURhdGFQb3Mrc2l6ZW9mKHZhbCkpIDw9IG1EYXRhQ2FwYWNpdHkpIHsKK3Jlc3RhcnRfd3JpdGU6CisgICAgICAgICpyZWludGVycHJldF9jYXN0PGludDY0X3QqPihtRGF0YSttRGF0YVBvcykgPSB2YWw7CisgICAgICAgIHJldHVybiBmaW5pc2hXcml0ZShzaXplb2YodmFsKSk7CisgICAgfQorCisgICAgc3RhdHVzX3QgZXJyID0gZ3Jvd0RhdGEoc2l6ZW9mKHZhbCkpOworICAgIGlmIChlcnIgPT0gTk9fRVJST1IpIGdvdG8gcmVzdGFydF93cml0ZTsKKyAgICByZXR1cm4gZXJyOworfQorCitzdGF0dXNfdCBQYXJjZWw6OndyaXRlRmxvYXQoZmxvYXQgdmFsKQoreworICAgIGlmICgobURhdGFQb3Mrc2l6ZW9mKHZhbCkpIDw9IG1EYXRhQ2FwYWNpdHkpIHsKK3Jlc3RhcnRfd3JpdGU6CisgICAgICAgICpyZWludGVycHJldF9jYXN0PGZsb2F0Kj4obURhdGErbURhdGFQb3MpID0gdmFsOworICAgICAgICByZXR1cm4gZmluaXNoV3JpdGUoc2l6ZW9mKHZhbCkpOworICAgIH0KKworICAgIHN0YXR1c190IGVyciA9IGdyb3dEYXRhKHNpemVvZih2YWwpKTsKKyAgICBpZiAoZXJyID09IE5PX0VSUk9SKSBnb3RvIHJlc3RhcnRfd3JpdGU7CisgICAgcmV0dXJuIGVycjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZURvdWJsZShkb3VibGUgdmFsKQoreworICAgIGlmICgobURhdGFQb3Mrc2l6ZW9mKHZhbCkpIDw9IG1EYXRhQ2FwYWNpdHkpIHsKK3Jlc3RhcnRfd3JpdGU6CisgICAgICAgICpyZWludGVycHJldF9jYXN0PGRvdWJsZSo+KG1EYXRhK21EYXRhUG9zKSA9IHZhbDsKKyAgICAgICAgcmV0dXJuIGZpbmlzaFdyaXRlKHNpemVvZih2YWwpKTsKKyAgICB9CisKKyAgICBzdGF0dXNfdCBlcnIgPSBncm93RGF0YShzaXplb2YodmFsKSk7CisgICAgaWYgKGVyciA9PSBOT19FUlJPUikgZ290byByZXN0YXJ0X3dyaXRlOworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGVDU3RyaW5nKGNvbnN0IGNoYXIqIHN0cikKK3sKKyAgICByZXR1cm4gd3JpdGUoc3RyLCBzdHJsZW4oc3RyKSsxKTsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZVN0cmluZzgoY29uc3QgU3RyaW5nOCYgc3RyKQoreworICAgIHN0YXR1c190IGVyciA9IHdyaXRlSW50MzIoc3RyLmJ5dGVzKCkpOworICAgIGlmIChlcnIgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgZXJyID0gd3JpdGUoc3RyLnN0cmluZygpLCBzdHIuYnl0ZXMoKSsxKTsKKyAgICB9CisgICAgcmV0dXJuIGVycjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZVN0cmluZzE2KGNvbnN0IFN0cmluZzE2JiBzdHIpCit7CisgICAgcmV0dXJuIHdyaXRlU3RyaW5nMTYoc3RyLnN0cmluZygpLCBzdHIuc2l6ZSgpKTsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZVN0cmluZzE2KGNvbnN0IGNoYXIxNl90KiBzdHIsIHNpemVfdCBsZW4pCit7CisgICAgaWYgKHN0ciA9PSBOVUxMKSByZXR1cm4gd3JpdGVJbnQzMigtMSk7CisgICAgCisgICAgc3RhdHVzX3QgZXJyID0gd3JpdGVJbnQzMihsZW4pOworICAgIGlmIChlcnIgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgbGVuICo9IHNpemVvZihjaGFyMTZfdCk7CisgICAgICAgIHVpbnQ4X3QqIGRhdGEgPSAodWludDhfdCopd3JpdGVJbnBsYWNlKGxlbitzaXplb2YoY2hhcjE2X3QpKTsKKyAgICAgICAgaWYgKGRhdGEpIHsKKyAgICAgICAgICAgIG1lbWNweShkYXRhLCBzdHIsIGxlbik7CisgICAgICAgICAgICAqcmVpbnRlcnByZXRfY2FzdDxjaGFyMTZfdCo+KGRhdGErbGVuKSA9IDA7CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0KKyAgICAgICAgZXJyID0gbUVycm9yOworICAgIH0KKyAgICByZXR1cm4gZXJyOworfQorCitzdGF0dXNfdCBQYXJjZWw6OndyaXRlU3Ryb25nQmluZGVyKGNvbnN0IHNwPElCaW5kZXI+JiB2YWwpCit7CisgICAgcmV0dXJuIGZsYXR0ZW5fYmluZGVyKFByb2Nlc3NTdGF0ZTo6c2VsZigpLCB2YWwsIHRoaXMpOworfQorCitzdGF0dXNfdCBQYXJjZWw6OndyaXRlV2Vha0JpbmRlcihjb25zdCB3cDxJQmluZGVyPiYgdmFsKQoreworICAgIHJldHVybiBmbGF0dGVuX2JpbmRlcihQcm9jZXNzU3RhdGU6OnNlbGYoKSwgdmFsLCB0aGlzKTsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZU5hdGl2ZUhhbmRsZShjb25zdCBuYXRpdmVfaGFuZGxlJiBoYW5kbGUpCit7CisgICAgaWYgKGhhbmRsZS52ZXJzaW9uICE9IHNpemVvZihuYXRpdmVfaGFuZGxlKSkKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworCisgICAgc3RhdHVzX3QgZXJyOworICAgIGVyciA9IHdyaXRlSW50MzIoaGFuZGxlLm51bUZkcyk7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgcmV0dXJuIGVycjsKKworICAgIGVyciA9IHdyaXRlSW50MzIoaGFuZGxlLm51bUludHMpOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHJldHVybiBlcnI7CisKKyAgICBmb3IgKGludCBpPTAgOyBlcnI9PU5PX0VSUk9SICYmIGk8aGFuZGxlLm51bUZkcyA7IGkrKykKKyAgICAgICAgZXJyID0gd3JpdGVEdXBGaWxlRGVzY3JpcHRvcihoYW5kbGUuZGF0YVtpXSk7CisKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgIExPR0QoIndyaXRlIG5hdGl2ZSBoYW5kbGUsIHdyaXRlIGR1cCBmZCBmYWlsZWQiKTsKKyAgICAgICAgcmV0dXJuIGVycjsKKyAgICB9CisKKyAgICBlcnIgPSB3cml0ZShoYW5kbGUuZGF0YSArIGhhbmRsZS5udW1GZHMsIHNpemVvZihpbnQpKmhhbmRsZS5udW1JbnRzKTsKKworICAgIHJldHVybiBlcnI7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGVGaWxlRGVzY3JpcHRvcihpbnQgZmQpCit7CisgICAgZmxhdF9iaW5kZXJfb2JqZWN0IG9iajsKKyAgICBvYmoudHlwZSA9IEJJTkRFUl9UWVBFX0ZEOworICAgIG9iai5mbGFncyA9IDB4N2YgfCBGTEFUX0JJTkRFUl9GTEFHX0FDQ0VQVFNfRkRTOworICAgIG9iai5oYW5kbGUgPSBmZDsKKyAgICBvYmouY29va2llID0gKHZvaWQqKTA7CisgICAgcmV0dXJuIHdyaXRlT2JqZWN0KG9iaiwgdHJ1ZSk7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6d3JpdGVEdXBGaWxlRGVzY3JpcHRvcihpbnQgZmQpCit7CisgICAgZmxhdF9iaW5kZXJfb2JqZWN0IG9iajsKKyAgICBvYmoudHlwZSA9IEJJTkRFUl9UWVBFX0ZEOworICAgIG9iai5mbGFncyA9IDB4N2YgfCBGTEFUX0JJTkRFUl9GTEFHX0FDQ0VQVFNfRkRTOworICAgIG9iai5oYW5kbGUgPSBkdXAoZmQpOworICAgIG9iai5jb29raWUgPSAodm9pZCopMTsKKyAgICByZXR1cm4gd3JpdGVPYmplY3Qob2JqLCB0cnVlKTsKK30KKworc3RhdHVzX3QgUGFyY2VsOjp3cml0ZU9iamVjdChjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QmIHZhbCwgYm9vbCBudWxsTWV0YURhdGEpCit7CisgICAgY29uc3QgYm9vbCBlbm91Z2hEYXRhID0gKG1EYXRhUG9zK3NpemVvZih2YWwpKSA8PSBtRGF0YUNhcGFjaXR5OworICAgIGNvbnN0IGJvb2wgZW5vdWdoT2JqZWN0cyA9IG1PYmplY3RzU2l6ZSA8IG1PYmplY3RzQ2FwYWNpdHk7CisgICAgaWYgKGVub3VnaERhdGEgJiYgZW5vdWdoT2JqZWN0cykgeworcmVzdGFydF93cml0ZToKKyAgICAgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8ZmxhdF9iaW5kZXJfb2JqZWN0Kj4obURhdGErbURhdGFQb3MpID0gdmFsOworICAgICAgICAKKyAgICAgICAgLy8gTmVlZCB0byB3cml0ZSBtZXRhLWRhdGE/CisgICAgICAgIGlmIChudWxsTWV0YURhdGEgfHwgdmFsLmJpbmRlciAhPSBOVUxMKSB7CisgICAgICAgICAgICBtT2JqZWN0c1ttT2JqZWN0c1NpemVdID0gbURhdGFQb3M7CisgICAgICAgICAgICBhY3F1aXJlX29iamVjdChQcm9jZXNzU3RhdGU6OnNlbGYoKSwgdmFsLCB0aGlzKTsKKyAgICAgICAgICAgIG1PYmplY3RzU2l6ZSsrOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvLyByZW1lbWJlciBpZiBpdCdzIGEgZmlsZSBkZXNjcmlwdG9yCisgICAgICAgIGlmICh2YWwudHlwZSA9PSBCSU5ERVJfVFlQRV9GRCkgeworICAgICAgICAgICAgbUhhc0ZkcyA9IG1GZHNLbm93biA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmluaXNoV3JpdGUoc2l6ZW9mKGZsYXRfYmluZGVyX29iamVjdCkpOworICAgIH0KKworICAgIGlmICghZW5vdWdoRGF0YSkgeworICAgICAgICBjb25zdCBzdGF0dXNfdCBlcnIgPSBncm93RGF0YShzaXplb2YodmFsKSk7CisgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHJldHVybiBlcnI7CisgICAgfQorICAgIGlmICghZW5vdWdoT2JqZWN0cykgeworICAgICAgICBzaXplX3QgbmV3U2l6ZSA9ICgobU9iamVjdHNTaXplKzIpKjMpLzI7CisgICAgICAgIHNpemVfdCogb2JqZWN0cyA9IChzaXplX3QqKXJlYWxsb2MobU9iamVjdHMsIG5ld1NpemUqc2l6ZW9mKHNpemVfdCkpOworICAgICAgICBpZiAob2JqZWN0cyA9PSBOVUxMKSByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICBtT2JqZWN0cyA9IG9iamVjdHM7CisgICAgICAgIG1PYmplY3RzQ2FwYWNpdHkgPSBuZXdTaXplOworICAgIH0KKyAgICAKKyAgICBnb3RvIHJlc3RhcnRfd3JpdGU7Cit9CisKKwordm9pZCBQYXJjZWw6OnJlbW92ZShzaXplX3Qgc3RhcnQsIHNpemVfdCBhbXQpCit7CisgICAgTE9HX0FMV0FZU19GQVRBTCgiUGFyY2VsOjpyZW1vdmUoKSBub3QgeWV0IGltcGxlbWVudGVkISIpOworfQorCitzdGF0dXNfdCBQYXJjZWw6OnJlYWQodm9pZCogb3V0RGF0YSwgc2l6ZV90IGxlbikgY29uc3QKK3sKKyAgICBpZiAoKG1EYXRhUG9zK1BBRF9TSVpFKGxlbikpID49IG1EYXRhUG9zICYmIChtRGF0YVBvcytQQURfU0laRShsZW4pKSA8PSBtRGF0YVNpemUpIHsKKyAgICAgICAgbWVtY3B5KG91dERhdGEsIG1EYXRhK21EYXRhUG9zLCBsZW4pOworICAgICAgICBtRGF0YVBvcyArPSBQQURfU0laRShsZW4pOworICAgICAgICBMT0dWKCJyZWFkIFNldHRpbmcgZGF0YSBwb3Mgb2YgJXAgdG8gJWRcbiIsIHRoaXMsIG1EYXRhUG9zKTsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTk9UX0VOT1VHSF9EQVRBOworfQorCitjb25zdCB2b2lkKiBQYXJjZWw6OnJlYWRJbnBsYWNlKHNpemVfdCBsZW4pIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytQQURfU0laRShsZW4pKSA+PSBtRGF0YVBvcyAmJiAobURhdGFQb3MrUEFEX1NJWkUobGVuKSkgPD0gbURhdGFTaXplKSB7CisgICAgICAgIGNvbnN0IHZvaWQqIGRhdGEgPSBtRGF0YSttRGF0YVBvczsKKyAgICAgICAgbURhdGFQb3MgKz0gUEFEX1NJWkUobGVuKTsKKyAgICAgICAgTE9HVigicmVhZElucGxhY2UgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6cmVhZEludDMyKGludDMyX3QgKnBBcmcpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoaW50MzJfdCkpIDw9IG1EYXRhU2l6ZSkgeworICAgICAgICBjb25zdCB2b2lkKiBkYXRhID0gbURhdGErbURhdGFQb3M7CisgICAgICAgIG1EYXRhUG9zICs9IHNpemVvZihpbnQzMl90KTsKKyAgICAgICAgKnBBcmcgPSAgKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgaW50MzJfdCo+KGRhdGEpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIE5PVF9FTk9VR0hfREFUQTsKKyAgICB9Cit9CisKK2ludDMyX3QgUGFyY2VsOjpyZWFkSW50MzIoKSBjb25zdAoreworICAgIGlmICgobURhdGFQb3Mrc2l6ZW9mKGludDMyX3QpKSA8PSBtRGF0YVNpemUpIHsKKyAgICAgICAgY29uc3Qgdm9pZCogZGF0YSA9IG1EYXRhK21EYXRhUG9zOworICAgICAgICBtRGF0YVBvcyArPSBzaXplb2YoaW50MzJfdCk7CisgICAgICAgIExPR1YoInJlYWRJbnQzMiBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBpbnQzMl90Kj4oZGF0YSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisKK3N0YXR1c190IFBhcmNlbDo6cmVhZEludDY0KGludDY0X3QgKnBBcmcpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoaW50NjRfdCkpIDw9IG1EYXRhU2l6ZSkgeworICAgICAgICBjb25zdCB2b2lkKiBkYXRhID0gbURhdGErbURhdGFQb3M7CisgICAgICAgIG1EYXRhUG9zICs9IHNpemVvZihpbnQ2NF90KTsKKyAgICAgICAgKnBBcmcgPSAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBpbnQ2NF90Kj4oZGF0YSk7CisgICAgICAgIExPR1YoInJlYWRJbnQ2NCBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gTk9UX0VOT1VHSF9EQVRBOworICAgIH0KK30KKworCitpbnQ2NF90IFBhcmNlbDo6cmVhZEludDY0KCkgY29uc3QKK3sKKyAgICBpZiAoKG1EYXRhUG9zK3NpemVvZihpbnQ2NF90KSkgPD0gbURhdGFTaXplKSB7CisgICAgICAgIGNvbnN0IHZvaWQqIGRhdGEgPSBtRGF0YSttRGF0YVBvczsKKyAgICAgICAgbURhdGFQb3MgKz0gc2l6ZW9mKGludDY0X3QpOworICAgICAgICBMT0dWKCJyZWFkSW50NjQgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgaW50NjRfdCo+KGRhdGEpOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdHVzX3QgUGFyY2VsOjpyZWFkRmxvYXQoZmxvYXQgKnBBcmcpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoZmxvYXQpKSA8PSBtRGF0YVNpemUpIHsKKyAgICAgICAgY29uc3Qgdm9pZCogZGF0YSA9IG1EYXRhK21EYXRhUG9zOworICAgICAgICBtRGF0YVBvcyArPSBzaXplb2YoZmxvYXQpOworICAgICAgICBMT0dWKCJyZWFkRmxvYXQgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICAqcEFyZyA9ICpyZWludGVycHJldF9jYXN0PGNvbnN0IGZsb2F0Kj4oZGF0YSk7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gTk9UX0VOT1VHSF9EQVRBOworICAgIH0KK30KKworCitmbG9hdCBQYXJjZWw6OnJlYWRGbG9hdCgpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoZmxvYXQpKSA8PSBtRGF0YVNpemUpIHsKKyAgICAgICAgY29uc3Qgdm9pZCogZGF0YSA9IG1EYXRhK21EYXRhUG9zOworICAgICAgICBtRGF0YVBvcyArPSBzaXplb2YoZmxvYXQpOworICAgICAgICBMT0dWKCJyZWFkRmxvYXQgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgZmxvYXQqPihkYXRhKTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6cmVhZERvdWJsZShkb3VibGUgKnBBcmcpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoZG91YmxlKSkgPD0gbURhdGFTaXplKSB7CisgICAgICAgIGNvbnN0IHZvaWQqIGRhdGEgPSBtRGF0YSttRGF0YVBvczsKKyAgICAgICAgbURhdGFQb3MgKz0gc2l6ZW9mKGRvdWJsZSk7CisgICAgICAgIExPR1YoInJlYWREb3VibGUgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICAqcEFyZyA9ICpyZWludGVycHJldF9jYXN0PGNvbnN0IGRvdWJsZSo+KGRhdGEpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIE5PVF9FTk9VR0hfREFUQTsKKyAgICB9Cit9CisKKworZG91YmxlIFBhcmNlbDo6cmVhZERvdWJsZSgpIGNvbnN0Cit7CisgICAgaWYgKChtRGF0YVBvcytzaXplb2YoZG91YmxlKSkgPD0gbURhdGFTaXplKSB7CisgICAgICAgIGNvbnN0IHZvaWQqIGRhdGEgPSBtRGF0YSttRGF0YVBvczsKKyAgICAgICAgbURhdGFQb3MgKz0gc2l6ZW9mKGRvdWJsZSk7CisgICAgICAgIExPR1YoInJlYWREb3VibGUgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgZG91YmxlKj4oZGF0YSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisKK2NvbnN0IGNoYXIqIFBhcmNlbDo6cmVhZENTdHJpbmcoKSBjb25zdAoreworICAgIGNvbnN0IHNpemVfdCBhdmFpbCA9IG1EYXRhU2l6ZS1tRGF0YVBvczsKKyAgICBpZiAoYXZhaWwgPiAwKSB7CisgICAgICAgIGNvbnN0IGNoYXIqIHN0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KG1EYXRhK21EYXRhUG9zKTsKKyAgICAgICAgLy8gaXMgdGhlIHN0cmluZydzIHRyYWlsaW5nIE5VTCB3aXRoaW4gdGhlIHBhcmNlbCdzIHZhbGlkIGJvdW5kcz8KKyAgICAgICAgY29uc3QgY2hhciogZW9zID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4obWVtY2hyKHN0ciwgMCwgYXZhaWwpKTsKKyAgICAgICAgaWYgKGVvcykgeworICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGxlbiA9IGVvcyAtIHN0cjsKKyAgICAgICAgICAgIG1EYXRhUG9zICs9IFBBRF9TSVpFKGxlbisxKTsKKyAgICAgICAgICAgIExPR1YoInJlYWRDU3RyaW5nIFNldHRpbmcgZGF0YSBwb3Mgb2YgJXAgdG8gJWRcbiIsIHRoaXMsIG1EYXRhUG9zKTsKKyAgICAgICAgICAgIHJldHVybiBzdHI7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1N0cmluZzggUGFyY2VsOjpyZWFkU3RyaW5nOCgpIGNvbnN0Cit7CisgICAgaW50MzJfdCBzaXplID0gcmVhZEludDMyKCk7CisgICAgLy8gd2F0Y2ggZm9yIHBvdGVudGlhbCBpbnQgb3ZlcmZsb3cgYWRkaW5nIDEgZm9yIHRyYWlsaW5nIE5VTAorICAgIGlmIChzaXplID4gMCAmJiBzaXplIDwgSU5UMzJfTUFYKSB7CisgICAgICAgIGNvbnN0IGNoYXIqIHN0ciA9IChjb25zdCBjaGFyKilyZWFkSW5wbGFjZShzaXplKzEpOworICAgICAgICBpZiAoc3RyKSByZXR1cm4gU3RyaW5nOChzdHIsIHNpemUpOworICAgIH0KKyAgICByZXR1cm4gU3RyaW5nOCgpOworfQorCitTdHJpbmcxNiBQYXJjZWw6OnJlYWRTdHJpbmcxNigpIGNvbnN0Cit7CisgICAgc2l6ZV90IGxlbjsKKyAgICBjb25zdCBjaGFyMTZfdCogc3RyID0gcmVhZFN0cmluZzE2SW5wbGFjZSgmbGVuKTsKKyAgICBpZiAoc3RyKSByZXR1cm4gU3RyaW5nMTYoc3RyLCBsZW4pOworICAgIExPR0UoIlJlYWRpbmcgYSBOVUxMIHN0cmluZyBub3Qgc3VwcG9ydGVkIGhlcmUuIik7CisgICAgcmV0dXJuIFN0cmluZzE2KCk7Cit9CisKK2NvbnN0IGNoYXIxNl90KiBQYXJjZWw6OnJlYWRTdHJpbmcxNklucGxhY2Uoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBzaXplID0gcmVhZEludDMyKCk7CisgICAgLy8gd2F0Y2ggZm9yIHBvdGVudGlhbCBpbnQgb3ZlcmZsb3cgZnJvbSBzaXplKzEKKyAgICBpZiAoc2l6ZSA+PSAwICYmIHNpemUgPCBJTlQzMl9NQVgpIHsKKyAgICAgICAgKm91dExlbiA9IHNpemU7CisgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzdHIgPSAoY29uc3QgY2hhcjE2X3QqKXJlYWRJbnBsYWNlKChzaXplKzEpKnNpemVvZihjaGFyMTZfdCkpOworICAgICAgICBpZiAoc3RyICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBzdHI7CisgICAgICAgIH0KKyAgICB9CisgICAgKm91dExlbiA9IDA7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3NwPElCaW5kZXI+IFBhcmNlbDo6cmVhZFN0cm9uZ0JpbmRlcigpIGNvbnN0Cit7CisgICAgc3A8SUJpbmRlcj4gdmFsOworICAgIHVuZmxhdHRlbl9iaW5kZXIoUHJvY2Vzc1N0YXRlOjpzZWxmKCksICp0aGlzLCAmdmFsKTsKKyAgICByZXR1cm4gdmFsOworfQorCit3cDxJQmluZGVyPiBQYXJjZWw6OnJlYWRXZWFrQmluZGVyKCkgY29uc3QKK3sKKyAgICB3cDxJQmluZGVyPiB2YWw7CisgICAgdW5mbGF0dGVuX2JpbmRlcihQcm9jZXNzU3RhdGU6OnNlbGYoKSwgKnRoaXMsICZ2YWwpOworICAgIHJldHVybiB2YWw7Cit9CisKKworbmF0aXZlX2hhbmRsZSogUGFyY2VsOjpyZWFkTmF0aXZlSGFuZGxlKG5hdGl2ZV9oYW5kbGUqICgqYWxsb2MpKHZvaWQqLCBpbnQsIGludCksIHZvaWQqIGNvb2tpZSkgY29uc3QKK3sKKyAgICBpbnQgbnVtRmRzLCBudW1JbnRzOworICAgIHN0YXR1c190IGVycjsKKyAgICBlcnIgPSByZWFkSW50MzIoJm51bUZkcyk7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgcmV0dXJuIDA7CisgICAgZXJyID0gcmVhZEludDMyKCZudW1JbnRzKTsKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSByZXR1cm4gMDsKKworICAgIG5hdGl2ZV9oYW5kbGUqIGg7CisgICAgaWYgKGFsbG9jID09IDApIHsKKyAgICAgICAgc2l6ZV90IHNpemUgPSBzaXplb2YobmF0aXZlX2hhbmRsZSkgKyBzaXplb2YoaW50KSoobnVtRmRzICsgbnVtSW50cyk7CisgICAgICAgIGggPSAobmF0aXZlX2hhbmRsZSopbWFsbG9jKHNpemUpOyAKKyAgICAgICAgaC0+dmVyc2lvbiA9IHNpemVvZihuYXRpdmVfaGFuZGxlKTsKKyAgICAgICAgaC0+bnVtRmRzID0gbnVtRmRzOworICAgICAgICBoLT5udW1JbnRzID0gbnVtSW50czsKKyAgICB9IGVsc2UgeworICAgICAgICBoID0gYWxsb2MoY29va2llLCBudW1GZHMsIG51bUludHMpOworICAgICAgICBpZiAoaC0+dmVyc2lvbiAhPSBzaXplb2YobmF0aXZlX2hhbmRsZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIGZvciAoaW50IGk9MCA7IGVycj09Tk9fRVJST1IgJiYgaTxudW1GZHMgOyBpKyspIHsKKyAgICAgICAgaC0+ZGF0YVtpXSA9IGR1cChyZWFkRmlsZURlc2NyaXB0b3IoKSk7CisgICAgICAgIGlmIChoLT5kYXRhW2ldIDwgMCkgZXJyID0gQkFEX1ZBTFVFOworICAgIH0KKyAgICAKKyAgICBlcnIgPSByZWFkKGgtPmRhdGEgKyBudW1GZHMsIHNpemVvZihpbnQpKm51bUludHMpOworICAgIAorICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgaWYgKGFsbG9jID09IDApIHsKKyAgICAgICAgICAgIGZyZWUoaCk7CisgICAgICAgIH0KKyAgICAgICAgaCA9IDA7CisgICAgfQorICAgIHJldHVybiBoOworfQorCisKK2ludCBQYXJjZWw6OnJlYWRGaWxlRGVzY3JpcHRvcigpIGNvbnN0Cit7CisgICAgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0KiBmbGF0ID0gcmVhZE9iamVjdCh0cnVlKTsKKyAgICBpZiAoZmxhdCkgeworICAgICAgICBzd2l0Y2ggKGZsYXQtPnR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgQklOREVSX1RZUEVfRkQ6CisgICAgICAgICAgICAgICAgLy9MT0dJKCJSZXR1cm5pbmcgZmlsZSBkZXNjcmlwdG9yICVsZCBmcm9tIHBhcmNlbCAlcFxuIiwgZmxhdC0+aGFuZGxlLCB0aGlzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmxhdC0+aGFuZGxlOworICAgICAgICB9ICAgICAgICAKKyAgICB9CisgICAgcmV0dXJuIEJBRF9UWVBFOworfQorCitjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIFBhcmNlbDo6cmVhZE9iamVjdChib29sIG51bGxNZXRhRGF0YSkgY29uc3QKK3sKKyAgICBjb25zdCBzaXplX3QgRFBPUyA9IG1EYXRhUG9zOworICAgIGlmICgoRFBPUytzaXplb2YoZmxhdF9iaW5kZXJfb2JqZWN0KSkgPD0gbURhdGFTaXplKSB7CisgICAgICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCogb2JqCisgICAgICAgICAgICAgICAgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCo+KG1EYXRhK0RQT1MpOworICAgICAgICBtRGF0YVBvcyA9IERQT1MgKyBzaXplb2YoZmxhdF9iaW5kZXJfb2JqZWN0KTsKKyAgICAgICAgaWYgKCFudWxsTWV0YURhdGEgJiYgKG9iai0+Y29va2llID09IE5VTEwgJiYgb2JqLT5iaW5kZXIgPT0gTlVMTCkpIHsKKyAgICAgICAgICAgIC8vIFdoZW4gdHJhbnNmZXJyaW5nIGEgTlVMTCBvYmplY3QsIHdlIGRvbid0IHdyaXRlIGl0IGludG8KKyAgICAgICAgICAgIC8vIHRoZSBvYmplY3QgbGlzdCwgc28gd2UgZG9uJ3Qgd2FudCB0byBjaGVjayBmb3IgaXQgd2hlbgorICAgICAgICAgICAgLy8gcmVhZGluZy4KKyAgICAgICAgICAgIExPR1YoInJlYWRPYmplY3QgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICAgICAgcmV0dXJuIG9iajsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhpcyBvYmplY3QgaXMgdmFsaWQuLi4KKyAgICAgICAgc2l6ZV90KiBjb25zdCBPQkpTID0gbU9iamVjdHM7CisgICAgICAgIGNvbnN0IHNpemVfdCBOID0gbU9iamVjdHNTaXplOworICAgICAgICBzaXplX3Qgb3BvcyA9IG1OZXh0T2JqZWN0SGludDsKKyAgICAgICAgCisgICAgICAgIGlmIChOID4gMCkgeworICAgICAgICAgICAgTE9HVigiUGFyY2VsICVwIGxvb2tpbmcgZm9yIG9iaiBhdCAlZCwgaGludD0lZFxuIiwKKyAgICAgICAgICAgICAgICAgdGhpcywgRFBPUywgb3Bvcyk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIFN0YXJ0IGF0IHRoZSBjdXJyZW50IGhpbnQgcG9zaXRpb24sIGxvb2tpbmcgZm9yIGFuIG9iamVjdCBhdAorICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgZGF0YSBwb3NpdGlvbi4KKyAgICAgICAgICAgIGlmIChvcG9zIDwgTikgeworICAgICAgICAgICAgICAgIHdoaWxlIChvcG9zIDwgKE4tMSkgJiYgT0JKU1tvcG9zXSA8IERQT1MpIHsKKyAgICAgICAgICAgICAgICAgICAgb3BvcysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3BvcyA9IE4tMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChPQkpTW29wb3NdID09IERQT1MpIHsKKyAgICAgICAgICAgICAgICAvLyBGb3VuZCBpdCEKKyAgICAgICAgICAgICAgICBMT0dWKCJQYXJjZWwgZm91bmQgb2JqICVkIGF0IGluZGV4ICVkIHdpdGggZm9yd2FyZCBzZWFyY2giLAorICAgICAgICAgICAgICAgICAgICAgdGhpcywgRFBPUywgb3Bvcyk7CisgICAgICAgICAgICAgICAgbU5leHRPYmplY3RIaW50ID0gb3BvcysxOworICAgICAgICAgICAgICAgIExPR1YoInJlYWRPYmplY3QgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICAgICAgICAgIHJldHVybiBvYmo7CisgICAgICAgICAgICB9CisgICAgICAgIAorICAgICAgICAgICAgLy8gTG9vayBiYWNrd2FyZHMgZm9yIGl0Li4uCisgICAgICAgICAgICB3aGlsZSAob3BvcyA+IDAgJiYgT0JKU1tvcG9zXSA+IERQT1MpIHsKKyAgICAgICAgICAgICAgICBvcG9zLS07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoT0JKU1tvcG9zXSA9PSBEUE9TKSB7CisgICAgICAgICAgICAgICAgLy8gRm91bmQgaXQhCisgICAgICAgICAgICAgICAgTE9HVigiUGFyY2VsIGZvdW5kIG9iaiAlZCBhdCBpbmRleCAlZCB3aXRoIGJhY2t3YXJkIHNlYXJjaCIsCisgICAgICAgICAgICAgICAgICAgICB0aGlzLCBEUE9TLCBvcG9zKTsKKyAgICAgICAgICAgICAgICBtTmV4dE9iamVjdEhpbnQgPSBvcG9zKzE7CisgICAgICAgICAgICAgICAgTE9HVigicmVhZE9iamVjdCBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBMT0dXKCJBdHRlbXB0IHRvIHJlYWQgb2JqZWN0IGZyb20gUGFyY2VsICVwIGF0IG9mZnNldCAlZCB0aGF0IGlzIG5vdCBpbiB0aGUgb2JqZWN0IGxpc3QiLAorICAgICAgICAgICAgIHRoaXMsIERQT1MpOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKwordm9pZCBQYXJjZWw6OmNsb3NlRmlsZURlc2NyaXB0b3JzKCkKK3sKKyAgICBzaXplX3QgaSA9IG1PYmplY3RzU2l6ZTsKKyAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgLy9MT0dJKCJDbG9zaW5nIGZpbGUgZGVzY3JpcHRvcnMgZm9yICVkIG9iamVjdHMuLi4iLCBtT2JqZWN0c1NpemUpOworICAgIH0KKyAgICB3aGlsZSAoaSA+IDApIHsKKyAgICAgICAgaS0tOworICAgICAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIGZsYXQKKyAgICAgICAgICAgID0gcmVpbnRlcnByZXRfY2FzdDxmbGF0X2JpbmRlcl9vYmplY3QqPihtRGF0YSttT2JqZWN0c1tpXSk7CisgICAgICAgIGlmIChmbGF0LT50eXBlID09IEJJTkRFUl9UWVBFX0ZEKSB7CisgICAgICAgICAgICAvL0xPR0koIkNsb3NpbmcgZmQ6ICVsZFxuIiwgZmxhdC0+aGFuZGxlKTsKKyAgICAgICAgICAgIGNsb3NlKGZsYXQtPmhhbmRsZSk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK2NvbnN0IHVpbnQ4X3QqIFBhcmNlbDo6aXBjRGF0YSgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1EYXRhOworfQorCitzaXplX3QgUGFyY2VsOjppcGNEYXRhU2l6ZSgpIGNvbnN0Cit7CisgICAgcmV0dXJuIChtRGF0YVNpemUgPiBtRGF0YVBvcyA/IG1EYXRhU2l6ZSA6IG1EYXRhUG9zKTsKK30KKworY29uc3Qgc2l6ZV90KiBQYXJjZWw6OmlwY09iamVjdHMoKSBjb25zdAoreworICAgIHJldHVybiBtT2JqZWN0czsKK30KKworc2l6ZV90IFBhcmNlbDo6aXBjT2JqZWN0c0NvdW50KCkgY29uc3QKK3sKKyAgICByZXR1cm4gbU9iamVjdHNTaXplOworfQorCit2b2lkIFBhcmNlbDo6aXBjU2V0RGF0YVJlZmVyZW5jZShjb25zdCB1aW50OF90KiBkYXRhLCBzaXplX3QgZGF0YVNpemUsCisgICAgY29uc3Qgc2l6ZV90KiBvYmplY3RzLCBzaXplX3Qgb2JqZWN0c0NvdW50LCByZWxlYXNlX2Z1bmMgcmVsRnVuYywgdm9pZCogcmVsQ29va2llKQoreworICAgIGZyZWVEYXRhTm9Jbml0KCk7CisgICAgbUVycm9yID0gTk9fRVJST1I7CisgICAgbURhdGEgPSBjb25zdF9jYXN0PHVpbnQ4X3QqPihkYXRhKTsKKyAgICBtRGF0YVNpemUgPSBtRGF0YUNhcGFjaXR5ID0gZGF0YVNpemU7CisgICAgLy9MT0dJKCJzZXREYXRhUmVmZXJlbmNlIFNldHRpbmcgZGF0YSBzaXplIG9mICVwIHRvICVsdSAocGlkPSVkKVxuIiwgdGhpcywgbURhdGFTaXplLCBnZXRwaWQoKSk7CisgICAgbURhdGFQb3MgPSAwOworICAgIExPR1YoInNldERhdGFSZWZlcmVuY2UgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgIG1PYmplY3RzID0gY29uc3RfY2FzdDxzaXplX3QqPihvYmplY3RzKTsKKyAgICBtT2JqZWN0c1NpemUgPSBtT2JqZWN0c0NhcGFjaXR5ID0gb2JqZWN0c0NvdW50OworICAgIG1OZXh0T2JqZWN0SGludCA9IDA7CisgICAgbU93bmVyID0gcmVsRnVuYzsKKyAgICBtT3duZXJDb29raWUgPSByZWxDb29raWU7CisgICAgc2NhbkZvckZkcygpOworfQorCit2b2lkIFBhcmNlbDo6cHJpbnQoVGV4dE91dHB1dCYgdG8sIHVpbnQzMl90IGZsYWdzKSBjb25zdAoreworICAgIHRvIDw8ICJQYXJjZWwoIjsKKyAgICAKKyAgICBpZiAoZXJyb3JDaGVjaygpICE9IE5PX0VSUk9SKSB7CisgICAgICAgIGNvbnN0IHN0YXR1c190IGVyciA9IGVycm9yQ2hlY2soKTsKKyAgICAgICAgdG8gPDwgIkVycm9yOiAiIDw8ICh2b2lkKillcnIgPDwgIiBcIiIgPDwgc3RyZXJyb3IoLWVycikgPDwgIlwiIjsKKyAgICB9IGVsc2UgaWYgKGRhdGFTaXplKCkgPiAwKSB7CisgICAgICAgIGNvbnN0IHVpbnQ4X3QqIERBVEEgPSBkYXRhKCk7CisgICAgICAgIHRvIDw8IGluZGVudCA8PCBIZXhEdW1wKERBVEEsIGRhdGFTaXplKCkpIDw8IGRlZGVudDsKKyAgICAgICAgY29uc3Qgc2l6ZV90KiBPQkpTID0gb2JqZWN0cygpOworICAgICAgICBjb25zdCBzaXplX3QgTiA9IG9iamVjdHNDb3VudCgpOworICAgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgICAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIGZsYXQKKyAgICAgICAgICAgICAgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0Kj4oREFUQStPQkpTW2ldKTsKKyAgICAgICAgICAgIHRvIDw8IGVuZGwgPDwgIk9iamVjdCAjIiA8PCBpIDw8ICIgQCAiIDw8ICh2b2lkKilPQkpTW2ldIDw8ICI6ICIKKyAgICAgICAgICAgICAgICA8PCBUeXBlQ29kZShmbGF0LT50eXBlICYgMHg3ZjdmN2YwMCkKKyAgICAgICAgICAgICAgICA8PCAiID0gIiA8PCBmbGF0LT5iaW5kZXI7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICB0byA8PCAiTlVMTCI7CisgICAgfQorICAgIAorICAgIHRvIDw8ICIpIjsKK30KKwordm9pZCBQYXJjZWw6OnJlbGVhc2VPYmplY3RzKCkKK3sKKyAgICBjb25zdCBzcDxQcm9jZXNzU3RhdGU+IHByb2MoUHJvY2Vzc1N0YXRlOjpzZWxmKCkpOworICAgIHNpemVfdCBpID0gbU9iamVjdHNTaXplOworICAgIHVpbnQ4X3QqIGNvbnN0IGRhdGEgPSBtRGF0YTsKKyAgICBzaXplX3QqIGNvbnN0IG9iamVjdHMgPSBtT2JqZWN0czsKKyAgICB3aGlsZSAoaSA+IDApIHsKKyAgICAgICAgaS0tOworICAgICAgICBjb25zdCBmbGF0X2JpbmRlcl9vYmplY3QqIGZsYXQKKyAgICAgICAgICAgID0gcmVpbnRlcnByZXRfY2FzdDxmbGF0X2JpbmRlcl9vYmplY3QqPihkYXRhK29iamVjdHNbaV0pOworICAgICAgICByZWxlYXNlX29iamVjdChwcm9jLCAqZmxhdCwgdGhpcyk7CisgICAgfQorfQorCit2b2lkIFBhcmNlbDo6YWNxdWlyZU9iamVjdHMoKQoreworICAgIGNvbnN0IHNwPFByb2Nlc3NTdGF0ZT4gcHJvYyhQcm9jZXNzU3RhdGU6OnNlbGYoKSk7CisgICAgc2l6ZV90IGkgPSBtT2JqZWN0c1NpemU7CisgICAgdWludDhfdCogY29uc3QgZGF0YSA9IG1EYXRhOworICAgIHNpemVfdCogY29uc3Qgb2JqZWN0cyA9IG1PYmplY3RzOworICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICBpLS07CisgICAgICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCogZmxhdAorICAgICAgICAgICAgPSByZWludGVycHJldF9jYXN0PGZsYXRfYmluZGVyX29iamVjdCo+KGRhdGErb2JqZWN0c1tpXSk7CisgICAgICAgIGFjcXVpcmVfb2JqZWN0KHByb2MsICpmbGF0LCB0aGlzKTsKKyAgICB9Cit9CisKK3ZvaWQgUGFyY2VsOjpmcmVlRGF0YSgpCit7CisgICAgZnJlZURhdGFOb0luaXQoKTsKKyAgICBpbml0U3RhdGUoKTsKK30KKwordm9pZCBQYXJjZWw6OmZyZWVEYXRhTm9Jbml0KCkKK3sKKyAgICBpZiAobU93bmVyKSB7CisgICAgICAgIC8vTE9HSSgiRnJlZWluZyBkYXRhIHJlZiBvZiAlcCAocGlkPSVkKVxuIiwgdGhpcywgZ2V0cGlkKCkpOworICAgICAgICBtT3duZXIodGhpcywgbURhdGEsIG1EYXRhU2l6ZSwgbU9iamVjdHMsIG1PYmplY3RzU2l6ZSwgbU93bmVyQ29va2llKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZWxlYXNlT2JqZWN0cygpOworICAgICAgICBpZiAobURhdGEpIGZyZWUobURhdGEpOworICAgICAgICBpZiAobU9iamVjdHMpIGZyZWUobU9iamVjdHMpOworICAgIH0KK30KKworc3RhdHVzX3QgUGFyY2VsOjpncm93RGF0YShzaXplX3QgbGVuKQoreworICAgIHNpemVfdCBuZXdTaXplID0gKChtRGF0YVNpemUrbGVuKSozKS8yOworICAgIHJldHVybiAobmV3U2l6ZSA8PSBtRGF0YVNpemUpCisgICAgICAgICAgICA/IChzdGF0dXNfdCkgTk9fTUVNT1JZCisgICAgICAgICAgICA6IGNvbnRpbnVlV3JpdGUobmV3U2l6ZSk7Cit9CisKK3N0YXR1c190IFBhcmNlbDo6cmVzdGFydFdyaXRlKHNpemVfdCBkZXNpcmVkKQoreworICAgIGlmIChtT3duZXIpIHsKKyAgICAgICAgZnJlZURhdGEoKTsKKyAgICAgICAgcmV0dXJuIGNvbnRpbnVlV3JpdGUoZGVzaXJlZCk7CisgICAgfQorICAgIAorICAgIHVpbnQ4X3QqIGRhdGEgPSAodWludDhfdCopcmVhbGxvYyhtRGF0YSwgZGVzaXJlZCk7CisgICAgaWYgKCFkYXRhICYmIGRlc2lyZWQgPiBtRGF0YUNhcGFjaXR5KSB7CisgICAgICAgIG1FcnJvciA9IE5PX01FTU9SWTsKKyAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICB9CisgICAgCisgICAgcmVsZWFzZU9iamVjdHMoKTsKKyAgICAKKyAgICBpZiAoZGF0YSkgeworICAgICAgICBtRGF0YSA9IGRhdGE7CisgICAgICAgIG1EYXRhQ2FwYWNpdHkgPSBkZXNpcmVkOworICAgIH0KKyAgICAKKyAgICBtRGF0YVNpemUgPSBtRGF0YVBvcyA9IDA7CisgICAgTE9HVigicmVzdGFydFdyaXRlIFNldHRpbmcgZGF0YSBzaXplIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVNpemUpOworICAgIExPR1YoInJlc3RhcnRXcml0ZSBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgICAgIAorICAgIGZyZWUobU9iamVjdHMpOworICAgIG1PYmplY3RzID0gTlVMTDsKKyAgICBtT2JqZWN0c1NpemUgPSBtT2JqZWN0c0NhcGFjaXR5ID0gMDsKKyAgICBtTmV4dE9iamVjdEhpbnQgPSAwOworICAgIG1IYXNGZHMgPSBmYWxzZTsKKyAgICBtRmRzS25vd24gPSB0cnVlOworICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgUGFyY2VsOjpjb250aW51ZVdyaXRlKHNpemVfdCBkZXNpcmVkKQoreworICAgIC8vIElmIHNocmlua2luZywgZmlyc3QgYWRqdXN0IGZvciBhbnkgb2JqZWN0cyB0aGF0IGFwcGVhcgorICAgIC8vIGFmdGVyIHRoZSBuZXcgZGF0YSBzaXplLgorICAgIHNpemVfdCBvYmplY3RzU2l6ZSA9IG1PYmplY3RzU2l6ZTsKKyAgICBpZiAoZGVzaXJlZCA8IG1EYXRhU2l6ZSkgeworICAgICAgICBpZiAoZGVzaXJlZCA9PSAwKSB7CisgICAgICAgICAgICBvYmplY3RzU2l6ZSA9IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3aGlsZSAob2JqZWN0c1NpemUgPiAwKSB7CisgICAgICAgICAgICAgICAgaWYgKG1PYmplY3RzW29iamVjdHNTaXplLTFdIDwgZGVzaXJlZCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgb2JqZWN0c1NpemUtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICBpZiAobU93bmVyKSB7CisgICAgICAgIC8vIElmIHRoZSBzaXplIGlzIGdvaW5nIHRvIHplcm8sIGp1c3QgcmVsZWFzZSB0aGUgb3duZXIncyBkYXRhLgorICAgICAgICBpZiAoZGVzaXJlZCA9PSAwKSB7CisgICAgICAgICAgICBmcmVlRGF0YSgpOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBkaWZmZXJlbnQgb3duZXIsIHdlIG5lZWQgdG8gdGFrZQorICAgICAgICAvLyBwb3Nlc3Npb24uCisgICAgICAgIHVpbnQ4X3QqIGRhdGEgPSAodWludDhfdCopbWFsbG9jKGRlc2lyZWQpOworICAgICAgICBpZiAoIWRhdGEpIHsKKyAgICAgICAgICAgIG1FcnJvciA9IE5PX01FTU9SWTsKKyAgICAgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgIH0KKyAgICAgICAgc2l6ZV90KiBvYmplY3RzID0gTlVMTDsKKyAgICAgICAgCisgICAgICAgIGlmIChvYmplY3RzU2l6ZSkgeworICAgICAgICAgICAgb2JqZWN0cyA9IChzaXplX3QqKW1hbGxvYyhvYmplY3RzU2l6ZSpzaXplb2Yoc2l6ZV90KSk7CisgICAgICAgICAgICBpZiAoIW9iamVjdHMpIHsKKyAgICAgICAgICAgICAgICBtRXJyb3IgPSBOT19NRU1PUlk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gTGl0dGxlIGhhY2sgdG8gb25seSBhY3F1aXJlIHJlZmVyZW5jZXMgb24gb2JqZWN0cworICAgICAgICAgICAgLy8gd2Ugd2lsbCBiZSBrZWVwaW5nLgorICAgICAgICAgICAgc2l6ZV90IG9sZE9iamVjdHNTaXplID0gbU9iamVjdHNTaXplOworICAgICAgICAgICAgbU9iamVjdHNTaXplID0gb2JqZWN0c1NpemU7CisgICAgICAgICAgICBhY3F1aXJlT2JqZWN0cygpOworICAgICAgICAgICAgbU9iamVjdHNTaXplID0gb2xkT2JqZWN0c1NpemU7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmIChtRGF0YSkgeworICAgICAgICAgICAgbWVtY3B5KGRhdGEsIG1EYXRhLCBtRGF0YVNpemUgPCBkZXNpcmVkID8gbURhdGFTaXplIDogZGVzaXJlZCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdHMgJiYgbU9iamVjdHMpIHsKKyAgICAgICAgICAgIG1lbWNweShvYmplY3RzLCBtT2JqZWN0cywgb2JqZWN0c1NpemUqc2l6ZW9mKHNpemVfdCkpOworICAgICAgICB9CisgICAgICAgIC8vTE9HSSgiRnJlZWluZyBkYXRhIHJlZiBvZiAlcCAocGlkPSVkKVxuIiwgdGhpcywgZ2V0cGlkKCkpOworICAgICAgICBtT3duZXIodGhpcywgbURhdGEsIG1EYXRhU2l6ZSwgbU9iamVjdHMsIG1PYmplY3RzU2l6ZSwgbU93bmVyQ29va2llKTsKKyAgICAgICAgbU93bmVyID0gTlVMTDsKKworICAgICAgICBtRGF0YSA9IGRhdGE7CisgICAgICAgIG1PYmplY3RzID0gb2JqZWN0czsKKyAgICAgICAgbURhdGFTaXplID0gKG1EYXRhU2l6ZSA8IGRlc2lyZWQpID8gbURhdGFTaXplIDogZGVzaXJlZDsKKyAgICAgICAgTE9HVigiY29udGludWVXcml0ZSBTZXR0aW5nIGRhdGEgc2l6ZSBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFTaXplKTsKKyAgICAgICAgbURhdGFDYXBhY2l0eSA9IGRlc2lyZWQ7CisgICAgICAgIG1PYmplY3RzU2l6ZSA9IG1PYmplY3RzQ2FwYWNpdHkgPSBvYmplY3RzU2l6ZTsKKyAgICAgICAgbU5leHRPYmplY3RIaW50ID0gMDsKKworICAgIH0gZWxzZSBpZiAobURhdGEpIHsKKyAgICAgICAgaWYgKG9iamVjdHNTaXplIDwgbU9iamVjdHNTaXplKSB7CisgICAgICAgICAgICAvLyBOZWVkIHRvIHJlbGVhc2UgcmVmcyBvbiBhbnkgb2JqZWN0cyB3ZSBhcmUgZHJvcHBpbmcuCisgICAgICAgICAgICBjb25zdCBzcDxQcm9jZXNzU3RhdGU+IHByb2MoUHJvY2Vzc1N0YXRlOjpzZWxmKCkpOworICAgICAgICAgICAgZm9yIChzaXplX3QgaT1vYmplY3RzU2l6ZTsgaTxtT2JqZWN0c1NpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGNvbnN0IGZsYXRfYmluZGVyX29iamVjdCogZmxhdAorICAgICAgICAgICAgICAgICAgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8ZmxhdF9iaW5kZXJfb2JqZWN0Kj4obURhdGErbU9iamVjdHNbaV0pOworICAgICAgICAgICAgICAgIGlmIChmbGF0LT50eXBlID09IEJJTkRFUl9UWVBFX0ZEKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgbmVlZCB0byByZXNjYW4gYmVjYXVzZSB3ZSBtYXkgaGF2ZSBsb3BwZWQgb2ZmIHRoZSBvbmx5IEZEcworICAgICAgICAgICAgICAgICAgICBtRmRzS25vd24gPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVsZWFzZV9vYmplY3QocHJvYywgKmZsYXQsIHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2l6ZV90KiBvYmplY3RzID0KKyAgICAgICAgICAgICAgICAoc2l6ZV90KilyZWFsbG9jKG1PYmplY3RzLCBvYmplY3RzU2l6ZSpzaXplb2Yoc2l6ZV90KSk7CisgICAgICAgICAgICBpZiAob2JqZWN0cykgeworICAgICAgICAgICAgICAgIG1PYmplY3RzID0gb2JqZWN0czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1PYmplY3RzU2l6ZSA9IG9iamVjdHNTaXplOworICAgICAgICAgICAgbU5leHRPYmplY3RIaW50ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlIG93biB0aGUgZGF0YSwgc28gd2UgY2FuIGp1c3QgZG8gYSByZWFsbG9jKCkuCisgICAgICAgIGlmIChkZXNpcmVkID4gbURhdGFDYXBhY2l0eSkgeworICAgICAgICAgICAgdWludDhfdCogZGF0YSA9ICh1aW50OF90KilyZWFsbG9jKG1EYXRhLCBkZXNpcmVkKTsKKyAgICAgICAgICAgIGlmIChkYXRhKSB7CisgICAgICAgICAgICAgICAgbURhdGEgPSBkYXRhOworICAgICAgICAgICAgICAgIG1EYXRhQ2FwYWNpdHkgPSBkZXNpcmVkOworICAgICAgICAgICAgfSBlbHNlIGlmIChkZXNpcmVkID4gbURhdGFDYXBhY2l0eSkgeworICAgICAgICAgICAgICAgIG1FcnJvciA9IE5PX01FTU9SWTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbURhdGFTaXplID0gZGVzaXJlZDsKKyAgICAgICAgICAgIExPR1YoImNvbnRpbnVlV3JpdGUgU2V0dGluZyBkYXRhIHNpemUgb2YgJXAgdG8gJWRcbiIsIHRoaXMsIG1EYXRhU2l6ZSk7CisgICAgICAgICAgICBpZiAobURhdGFQb3MgPiBkZXNpcmVkKSB7CisgICAgICAgICAgICAgICAgbURhdGFQb3MgPSBkZXNpcmVkOworICAgICAgICAgICAgICAgIExPR1YoImNvbnRpbnVlV3JpdGUgU2V0dGluZyBkYXRhIHBvcyBvZiAlcCB0byAlZFxuIiwgdGhpcywgbURhdGFQb3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIAorICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGRhdGEuICBFYXN5IQorICAgICAgICB1aW50OF90KiBkYXRhID0gKHVpbnQ4X3QqKW1hbGxvYyhkZXNpcmVkKTsKKyAgICAgICAgaWYgKCFkYXRhKSB7CisgICAgICAgICAgICBtRXJyb3IgPSBOT19NRU1PUlk7CisgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZighKG1EYXRhQ2FwYWNpdHkgPT0gMCAmJiBtT2JqZWN0cyA9PSBOVUxMCisgICAgICAgICAgICAgJiYgbU9iamVjdHNDYXBhY2l0eSA9PSAwKSkgeworICAgICAgICAgICAgTE9HRSgiY29udGludWVXcml0ZTogJWQvJXAvJWQvJWQiLCBtRGF0YUNhcGFjaXR5LCBtT2JqZWN0cywgbU9iamVjdHNDYXBhY2l0eSwgZGVzaXJlZCk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIG1EYXRhID0gZGF0YTsKKyAgICAgICAgbURhdGFTaXplID0gbURhdGFQb3MgPSAwOworICAgICAgICBMT0dWKCJjb250aW51ZVdyaXRlIFNldHRpbmcgZGF0YSBzaXplIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVNpemUpOworICAgICAgICBMT0dWKCJjb250aW51ZVdyaXRlIFNldHRpbmcgZGF0YSBwb3Mgb2YgJXAgdG8gJWRcbiIsIHRoaXMsIG1EYXRhUG9zKTsKKyAgICAgICAgbURhdGFDYXBhY2l0eSA9IGRlc2lyZWQ7CisgICAgfQorCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIFBhcmNlbDo6aW5pdFN0YXRlKCkKK3sKKyAgICBtRXJyb3IgPSBOT19FUlJPUjsKKyAgICBtRGF0YSA9IDA7CisgICAgbURhdGFTaXplID0gMDsKKyAgICBtRGF0YUNhcGFjaXR5ID0gMDsKKyAgICBtRGF0YVBvcyA9IDA7CisgICAgTE9HVigiaW5pdFN0YXRlIFNldHRpbmcgZGF0YSBzaXplIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVNpemUpOworICAgIExPR1YoImluaXRTdGF0ZSBTZXR0aW5nIGRhdGEgcG9zIG9mICVwIHRvICVkXG4iLCB0aGlzLCBtRGF0YVBvcyk7CisgICAgbU9iamVjdHMgPSBOVUxMOworICAgIG1PYmplY3RzU2l6ZSA9IDA7CisgICAgbU9iamVjdHNDYXBhY2l0eSA9IDA7CisgICAgbU5leHRPYmplY3RIaW50ID0gMDsKKyAgICBtSGFzRmRzID0gZmFsc2U7CisgICAgbUZkc0tub3duID0gdHJ1ZTsKKyAgICBtT3duZXIgPSBOVUxMOworfQorCit2b2lkIFBhcmNlbDo6c2NhbkZvckZkcygpIGNvbnN0Cit7CisgICAgYm9vbCBoYXNGZHMgPSBmYWxzZTsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8bU9iamVjdHNTaXplOyBpKyspIHsKKyAgICAgICAgY29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0KiBmbGF0CisgICAgICAgICAgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgZmxhdF9iaW5kZXJfb2JqZWN0Kj4obURhdGEgKyBtT2JqZWN0c1tpXSk7CisgICAgICAgIGlmIChmbGF0LT50eXBlID09IEJJTkRFUl9UWVBFX0ZEKSB7CisgICAgICAgICAgICBoYXNGZHMgPSB0cnVlOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgbUhhc0ZkcyA9IGhhc0ZkczsKKyAgICBtRmRzS25vd24gPSB0cnVlOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9QaXBlLmNwcCBiL2xpYnMvdXRpbHMvUGlwZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjEzOTA2YgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvUGlwZS5jcHAKQEAgLTAsMCArMSw0NjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gVW5pZGlyZWN0aW9uYWwgcGlwZS4KKy8vCisKKyNpbmNsdWRlIDx1dGlscy9QaXBlLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpZiBkZWZpbmVkKEhBVkVfV0lOMzJfSVBDKQorIyBpbmNsdWRlIDx3aW5kb3dzLmg+CisjZWxzZQorIyBpbmNsdWRlIDxmY250bC5oPgorIyBpbmNsdWRlIDx1bmlzdGQuaD4KKyMgaW5jbHVkZSA8ZXJybm8uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKK2NvbnN0IHVuc2lnbmVkIGxvbmcga0ludmFsaWRIYW5kbGUgPSAodW5zaWduZWQgbG9uZykgLTE7CisKKworLyoKKyAqIENvbnN0cnVjdG9yLiAgRG8gbGl0dGxlLgorICovCitQaXBlOjpQaXBlKHZvaWQpCisgICAgOiBtUmVhZE5vbkJsb2NraW5nKGZhbHNlKSwgbVJlYWRIYW5kbGUoa0ludmFsaWRIYW5kbGUpLAorICAgICAgbVdyaXRlSGFuZGxlKGtJbnZhbGlkSGFuZGxlKQoreworfQorCisvKgorICogRGVzdHJ1Y3Rvci4gIFVzZSB0aGUgc3lzdGVtLWFwcHJvcHJpYXRlIGNsb3NlIGNhbGwuCisgKi8KK1BpcGU6On5QaXBlKHZvaWQpCit7CisjaWYgZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICBpZiAobVJlYWRIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpIHsKKyAgICAgICAgaWYgKCFDbG9zZUhhbmRsZSgoSEFORExFKW1SZWFkSGFuZGxlKSkKKyAgICAgICAgICAgIExPRyhMT0dfV0FSTiwgInBpcGUiLCAiZmFpbGVkIGNsb3NpbmcgcmVhZCBoYW5kbGUgKCVsZClcbiIsCisgICAgICAgICAgICAgICAgbVJlYWRIYW5kbGUpOworICAgIH0KKyAgICBpZiAobVdyaXRlSGFuZGxlICE9IGtJbnZhbGlkSGFuZGxlKSB7CisgICAgICAgIEZsdXNoRmlsZUJ1ZmZlcnMoKEhBTkRMRSltV3JpdGVIYW5kbGUpOworICAgICAgICBpZiAoIUNsb3NlSGFuZGxlKChIQU5ETEUpbVdyaXRlSGFuZGxlKSkKKyAgICAgICAgICAgIExPRyhMT0dfV0FSTiwgInBpcGUiLCAiZmFpbGVkIGNsb3Npbmcgd3JpdGUgaGFuZGxlICglbGQpXG4iLAorICAgICAgICAgICAgICAgIG1Xcml0ZUhhbmRsZSk7CisgICAgfQorI2Vsc2UKKyAgICBpZiAobVJlYWRIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpIHsKKyAgICAgICAgaWYgKGNsb3NlKChpbnQpIG1SZWFkSGFuZGxlKSAhPSAwKQorICAgICAgICAgICAgTE9HKExPR19XQVJOLCAicGlwZSIsICJmYWlsZWQgY2xvc2luZyByZWFkIGZkICglZClcbiIsCisgICAgICAgICAgICAgICAgKGludCkgbVJlYWRIYW5kbGUpOworICAgIH0KKyAgICBpZiAobVdyaXRlSGFuZGxlICE9IGtJbnZhbGlkSGFuZGxlKSB7CisgICAgICAgIGlmIChjbG9zZSgoaW50KSBtV3JpdGVIYW5kbGUpICE9IDApCisgICAgICAgICAgICBMT0coTE9HX1dBUk4sICJwaXBlIiwgImZhaWxlZCBjbG9zaW5nIHdyaXRlIGZkICglZClcbiIsCisgICAgICAgICAgICAgICAgKGludCkgbVdyaXRlSGFuZGxlKTsKKyAgICB9CisjZW5kaWYKK30KKworLyoKKyAqIENyZWF0ZSB0aGUgcGlwZS4KKyAqCisgKiBVc2UgdGhlIFBPU0lYIHN0dWZmIGZvciBldmVyeXRoaW5nIGJ1dCBXaW5kb3dzLgorICovCitib29sIFBpcGU6OmNyZWF0ZSh2b2lkKQoreworICAgIGFzc2VydChtUmVhZEhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSk7CisgICAgYXNzZXJ0KG1Xcml0ZUhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSk7CisKKyNpZiBkZWZpbmVkKEhBVkVfV0lOMzJfSVBDKQorICAgIC8qIHdlIHVzZSB0aGlzIGFjcm9zcyBwcm9jZXNzZXMsIHNvIHRoZXkgbmVlZCB0byBiZSBpbmhlcml0YWJsZSAqLworICAgIEhBTkRMRSBoYW5kbGVzWzJdOworICAgIFNFQ1VSSVRZX0FUVFJJQlVURVMgc2FBdHRyOworCisgICAgc2FBdHRyLm5MZW5ndGggPSBzaXplb2YoU0VDVVJJVFlfQVRUUklCVVRFUyk7CisgICAgc2FBdHRyLmJJbmhlcml0SGFuZGxlID0gVFJVRTsKKyAgICBzYUF0dHIubHBTZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOworCisgICAgaWYgKCFDcmVhdGVQaXBlKCZoYW5kbGVzWzBdLCAmaGFuZGxlc1sxXSwgJnNhQXR0ciwgMCkpIHsKKyAgICAgICAgTE9HKExPR19FUlJPUiwgInBpcGUiLCAidW5hYmxlIHRvIGNyZWF0ZSBwaXBlXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBtUmVhZEhhbmRsZSA9ICh1bnNpZ25lZCBsb25nKSBoYW5kbGVzWzBdOworICAgIG1Xcml0ZUhhbmRsZSA9ICh1bnNpZ25lZCBsb25nKSBoYW5kbGVzWzFdOworICAgIHJldHVybiB0cnVlOworI2Vsc2UKKyAgICBpbnQgZmRzWzJdOworCisgICAgaWYgKHBpcGUoZmRzKSAhPSAwKSB7CisgICAgICAgIExPRyhMT0dfRVJST1IsICJwaXBlIiwgInVuYWJsZSB0byBjcmVhdGUgcGlwZVxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgbVJlYWRIYW5kbGUgPSBmZHNbMF07CisgICAgbVdyaXRlSGFuZGxlID0gZmRzWzFdOworICAgIHJldHVybiB0cnVlOworI2VuZGlmCit9CisKKy8qCisgKiBDcmVhdGUgYSAiaGFsZiBwaXBlIi4gIFBsZWFzZSwgbm8gU2Vnd2F5IHJpZGluZy4KKyAqLworYm9vbCBQaXBlOjpjcmVhdGVSZWFkZXIodW5zaWduZWQgbG9uZyBoYW5kbGUpCit7CisgICAgbVJlYWRIYW5kbGUgPSBoYW5kbGU7CisgICAgYXNzZXJ0KG1Xcml0ZUhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSk7CisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8qCisgKiBDcmVhdGUgYSAiaGFsZiBwaXBlIiBmb3Igd3JpdGluZy4KKyAqLworYm9vbCBQaXBlOjpjcmVhdGVXcml0ZXIodW5zaWduZWQgbG9uZyBoYW5kbGUpCit7CisgICAgbVdyaXRlSGFuZGxlID0gaGFuZGxlOworICAgIGFzc2VydChtUmVhZEhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSk7CisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8qCisgKiBSZXR1cm4gInRydWUiIGlmIGNyZWF0ZSgpIGhhcyBiZWVuIGNhbGxlZCBzdWNjZXNzZnVsbHkuCisgKi8KK2Jvb2wgUGlwZTo6aXNDcmVhdGVkKHZvaWQpCit7CisgICAgLy8gb25lIG9yIHRoZSBvdGhlciBzaG91bGQgYmUgb3BlbgorICAgIHJldHVybiAobVJlYWRIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUgfHwgbVdyaXRlSGFuZGxlICE9IGtJbnZhbGlkSGFuZGxlKTsKK30KKworCisvKgorICogUmVhZCBkYXRhIGZyb20gdGhlIHBpcGUuCisgKgorICogRm9yIExpbnV4IGFuZCBEYXJ3aW4sIGp1c3QgY2FsbCByZWFkKCkuICBGb3IgV2luZG93cywgaW1wbGVtZW50CisgKiBub24tYmxvY2tpbmcgcmVhZHMgYnkgY2FsbGluZyBQZWVrTmFtZWRQaXBlIGZpcnN0LgorICovCitpbnQgUGlwZTo6cmVhZCh2b2lkKiBidWYsIGludCBjb3VudCkKK3sKKyAgICBhc3NlcnQobVJlYWRIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpOworCisjaWYgZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICBEV09SRCB0b3RhbEJ5dGVzQXZhaWwgPSBjb3VudDsKKyAgICBEV09SRCBieXRlc1JlYWQ7CisKKyAgICBpZiAobVJlYWROb25CbG9ja2luZykgeworICAgICAgICAvLyB1c2UgUGVla05hbWVkUGlwZSB0byBhZGp1c3QgcmVhZCBjb3VudCBleHBlY3RhdGlvbnMKKyAgICAgICAgaWYgKCFQZWVrTmFtZWRQaXBlKChIQU5ETEUpIG1SZWFkSGFuZGxlLCBOVUxMLCAwLCBOVUxMLAorICAgICAgICAgICAgICAgICZ0b3RhbEJ5dGVzQXZhaWwsIE5VTEwpKQorICAgICAgICB7CisgICAgICAgICAgICBMT0coTE9HX0VSUk9SLCAicGlwZSIsICJQZWVrTmFtZWRQaXBlIGZhaWxlZFxuIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAodG90YWxCeXRlc0F2YWlsID09IDApCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIVJlYWRGaWxlKChIQU5ETEUpIG1SZWFkSGFuZGxlLCBidWYsIHRvdGFsQnl0ZXNBdmFpbCwgJmJ5dGVzUmVhZCwKKyAgICAgICAgICAgIE5VTEwpKQorICAgIHsKKyAgICAgICAgRFdPUkQgZXJyID0gR2V0TGFzdEVycm9yKCk7CisgICAgICAgIGlmIChlcnIgPT0gRVJST1JfSEFORExFX0VPRiB8fCBlcnIgPT0gRVJST1JfQlJPS0VOX1BJUEUpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgTE9HKExPR19FUlJPUiwgInBpcGUiLCAiUmVhZEZpbGUgZmFpbGVkIChlcnI9JWxkKVxuIiwgZXJyKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHJldHVybiAoaW50KSBieXRlc1JlYWQ7CisjZWxzZQorICAgIGludCBjYzsKKyAgICBjYyA9IDo6cmVhZChtUmVhZEhhbmRsZSwgYnVmLCBjb3VudCk7CisgICAgaWYgKGNjIDwgMCAmJiBlcnJubyA9PSBFQUdBSU4pCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBjYzsKKyNlbmRpZgorfQorCisvKgorICogV3JpdGUgZGF0YSB0byB0aGUgcGlwZS4KKyAqCisgKiBQT1NJWCBzeXN0ZW1zIGFyZSB0cml2aWFsLCBXaW5kb3dzIHVzZXMgYSBkaWZmZXJlbnQgY2FsbCBhbmQgZG9lc24ndAorICogaGFuZGxlIG5vbi1ibG9ja2luZyB3cml0ZXMuCisgKgorICogSWYgd2UgYWRkIG5vbi1ibG9ja2luZyBzdXBwb3J0IGhlcmUsIHdlIHByb2JhYmx5IHdhbnQgdG8gbWFrZSBpdCBhbgorICogYWxsLW9yLW5vdGhpbmcgd3JpdGUuCisgKgorICogRE8gTk9UIHVzZSBMT0coKSBoZXJlLCB3ZSBjb3VsZCBiZSB3cml0aW5nIGEgbG9nIG1lc3NhZ2UuCisgKi8KK2ludCBQaXBlOjp3cml0ZShjb25zdCB2b2lkKiBidWYsIGludCBjb3VudCkKK3sKKyAgICBhc3NlcnQobVdyaXRlSGFuZGxlICE9IGtJbnZhbGlkSGFuZGxlKTsKKworI2lmIGRlZmluZWQoSEFWRV9XSU4zMl9JUEMpCisgICAgRFdPUkQgYnl0ZXNXcml0dGVuOworCisgICAgaWYgKG1Xcml0ZU5vbkJsb2NraW5nKSB7CisgICAgICAgIC8vIEJVRzogY2FuJ3QgdXNlIFBlZWtOYW1lZFBpcGUoKSB0byBnZXQgdGhlIGFtb3VudCBvZiBzcGFjZQorICAgICAgICAvLyBsZWZ0LiAgTG9va3MgbGlrZSB3ZSBuZWVkIHRvIHVzZSAib3ZlcmxhcHBlZCBJL08iIGZ1bmN0aW9ucy4KKyAgICAgICAgLy8gSSBqdXN0IGRvbid0IGNhcmUgdGhhdCBtdWNoLgorICAgIH0KKworICAgIGlmICghV3JpdGVGaWxlKChIQU5ETEUpIG1Xcml0ZUhhbmRsZSwgYnVmLCBjb3VudCwgJmJ5dGVzV3JpdHRlbiwgTlVMTCkpIHsKKyAgICAgICAgLy8gY2FuJ3QgTE9HLCB1c2Ugc3RkZXJyCisgICAgICAgIGZwcmludGYoc3RkZXJyLCAiV3JpdGVGaWxlIGZhaWxlZCAoZXJyPSVsZClcbiIsIEdldExhc3RFcnJvcigpKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHJldHVybiAoaW50KSBieXRlc1dyaXR0ZW47CisjZWxzZQorICAgIGludCBjYzsKKyAgICBjYyA9IDo6d3JpdGUobVdyaXRlSGFuZGxlLCBidWYsIGNvdW50KTsKKyAgICBpZiAoY2MgPCAwICYmIGVycm5vID09IEVBR0FJTikKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIGNjOworI2VuZGlmCit9CisKKy8qCisgKiBGaWd1cmUgb3V0IGlmIHRoZXJlIGlzIGRhdGEgYXZhaWxhYmxlIG9uIHRoZSByZWFkIGZkLgorICoKKyAqIFdlIHJldHVybiAidHJ1ZSIgb24gZXJyb3IgYmVjYXVzZSB3ZSB3YW50IHRoZSBjYWxsZXIgdG8gdHJ5IHRvIHJlYWQKKyAqIGZyb20gdGhlIHBpcGUuICBUaGV5J2xsIG5vdGljZSB0aGUgcmVhZCBmYWlsdXJlIGFuZCBkbyBzb21ldGhpbmcKKyAqIGFwcHJvcHJpYXRlLgorICovCitib29sIFBpcGU6OnJlYWRSZWFkeSh2b2lkKQoreworICAgIGFzc2VydChtUmVhZEhhbmRsZSAhPSBrSW52YWxpZEhhbmRsZSk7CisKKyNpZiBkZWZpbmVkKEhBVkVfV0lOMzJfSVBDKQorICAgIERXT1JEIHRvdGFsQnl0ZXNBdmFpbDsKKworICAgIGlmICghUGVla05hbWVkUGlwZSgoSEFORExFKSBtUmVhZEhhbmRsZSwgTlVMTCwgMCwgTlVMTCwKKyAgICAgICAgICAgICZ0b3RhbEJ5dGVzQXZhaWwsIE5VTEwpKQorICAgIHsKKyAgICAgICAgTE9HKExPR19FUlJPUiwgInBpcGUiLCAiUGVla05hbWVkUGlwZSBmYWlsZWRcbiIpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gKHRvdGFsQnl0ZXNBdmFpbCAhPSAwKTsKKyNlbHNlCisgICAgZXJybm8gPSAwOworICAgIGZkX3NldCByZWFkZmRzOworICAgIHN0cnVjdCB0aW1ldmFsIHR2ID0geyAwLCAwIH07CisgICAgaW50IGNjOworCisgICAgRkRfWkVSTygmcmVhZGZkcyk7CisgICAgRkRfU0VUKG1SZWFkSGFuZGxlLCAmcmVhZGZkcyk7CisKKyAgICBjYyA9IHNlbGVjdChtUmVhZEhhbmRsZSsxLCAmcmVhZGZkcywgTlVMTCwgTlVMTCwgJnR2KTsKKyAgICBpZiAoY2MgPCAwKSB7CisgICAgICAgIExPRyhMT0dfRVJST1IsICJwaXBlIiwgInNlbGVjdCgpIGZhaWxlZFxuIik7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSBpZiAoY2MgPT0gMCkgeworICAgICAgICAvKiB0aW1lZCBvdXQsIG5vdGhpbmcgYXZhaWxhYmxlICovCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKGNjID09IDEpIHsKKyAgICAgICAgLyogb3VyIGZkIGlzIHJlYWR5ICovCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAgIExPRyhMT0dfRVJST1IsICJwaXBlIiwgIkhVSD8gc2VsZWN0KCkgcmV0dXJuZWQgPiAxXG4iKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorI2VuZGlmCit9CisKKy8qCisgKiBFbmFibGUgb3IgZGlzYWJsZSBub24tYmxvY2tpbmcgbW9kZSBmb3IgdGhlIHJlYWQgZGVzY3JpcHRvci4KKyAqCisgKiBOT1RFOiB0aGUgY2FsbHMgc3VjY2VlZCB1bmRlciBNYWMgT1MgWCwgYnV0IHRoZSBwaXBlIGRvZXNuJ3QgYXBwZWFyIHRvCisgKiBhY3R1YWxseSBiZSBpbiBub24tYmxvY2tpbmcgbW9kZS4gIElmIHRoaXMgbWF0dGVycyAtLSBpLmUuIHlvdSdyZSBub3QKKyAqIHVzaW5nIGEgc2VsZWN0KCkgY2FsbCAtLSBwdXQgYSBjYWxsIHRvIHJlYWRSZWFkeSgpIGluIGZyb250IG9mIHRoZQorICogOjpyZWFkKCkgY2FsbCwgd2l0aCBhIFBJUEVfTk9OQkxPQ0tfQlJPS0VOICNpZmRlZiBpbiB0aGUgTWFrZWZpbGUgZm9yCisgKiBEYXJ3aW4uCisgKi8KK2Jvb2wgUGlwZTo6c2V0UmVhZE5vbkJsb2NraW5nKGJvb2wgdmFsKQoreworICAgIGFzc2VydChtUmVhZEhhbmRsZSAhPSBrSW52YWxpZEhhbmRsZSk7CisKKyNpZiBkZWZpbmVkKEhBVkVfV0lOMzJfSVBDKQorICAgIC8vIG5vdGhpbmcgdG8gZG8KKyNlbHNlCisgICAgaW50IGZsYWdzOworCisgICAgaWYgKGZjbnRsKG1SZWFkSGFuZGxlLCBGX0dFVEZMLCAmZmxhZ3MpID09IC0xKSB7CisgICAgICAgIExPRyhMT0dfRVJST1IsICJwaXBlIiwgImNvdWxkbid0IGdldCBmbGFncyBmb3IgcGlwZSByZWFkIGZkXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodmFsKQorICAgICAgICBmbGFncyB8PSBPX05PTkJMT0NLOworICAgIGVsc2UKKyAgICAgICAgZmxhZ3MgJj0gfihPX05PTkJMT0NLKTsKKyAgICBpZiAoZmNudGwobVJlYWRIYW5kbGUsIEZfU0VURkwsICZmbGFncykgPT0gLTEpIHsKKyAgICAgICAgTE9HKExPR19FUlJPUiwgInBpcGUiLCAiY291bGRuJ3Qgc2V0IGZsYWdzIGZvciBwaXBlIHJlYWQgZmRcbiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorI2VuZGlmCisKKyAgICBtUmVhZE5vbkJsb2NraW5nID0gdmFsOworICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogRW5hYmxlIG9yIGRpc2FibGUgbm9uLWJsb2NraW5nIG1vZGUgZm9yIHRoZSB3cml0ZSBkZXNjcmlwdG9yLgorICoKKyAqIEFzIHdpdGggc2V0UmVhZE5vbkJsb2NraW5nKCksIHRoaXMgZG9lcyBub3Qgd29yayBvbiB0aGUgTWFjLgorICovCitib29sIFBpcGU6OnNldFdyaXRlTm9uQmxvY2tpbmcoYm9vbCB2YWwpCit7CisgICAgYXNzZXJ0KG1Xcml0ZUhhbmRsZSAhPSBrSW52YWxpZEhhbmRsZSk7CisKKyNpZiBkZWZpbmVkKEhBVkVfV0lOMzJfSVBDKQorICAgIC8vIG5vdGhpbmcgdG8gZG8KKyNlbHNlCisgICAgaW50IGZsYWdzOworCisgICAgaWYgKGZjbnRsKG1Xcml0ZUhhbmRsZSwgRl9HRVRGTCwgJmZsYWdzKSA9PSAtMSkgeworICAgICAgICBMT0coTE9HX1dBUk4sICJwaXBlIiwKKyAgICAgICAgICAgICJXYXJuaW5nOiBjb3VsZG4ndCBnZXQgZmxhZ3MgZm9yIHBpcGUgd3JpdGUgZmQgKGVycm5vPSVkKVxuIiwKKyAgICAgICAgICAgIGVycm5vKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodmFsKQorICAgICAgICBmbGFncyB8PSBPX05PTkJMT0NLOworICAgIGVsc2UKKyAgICAgICAgZmxhZ3MgJj0gfihPX05PTkJMT0NLKTsKKyAgICBpZiAoZmNudGwobVdyaXRlSGFuZGxlLCBGX1NFVEZMLCAmZmxhZ3MpID09IC0xKSB7CisgICAgICAgIExPRyhMT0dfV0FSTiwgInBpcGUiLAorICAgICAgICAgICAgIldhcm5pbmc6IGNvdWxkbid0IHNldCBmbGFncyBmb3IgcGlwZSB3cml0ZSBmZCAoZXJybm89JWQpXG4iLAorICAgICAgICAgICAgZXJybm8pOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorI2VuZGlmCisKKyAgICBtV3JpdGVOb25CbG9ja2luZyA9IHZhbDsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIFNwZWNpZnkgd2hldGhlciBhIGZpbGUgZGVzY3JpcHRvciBjYW4gYmUgaW5oZXJpdGVkIGJ5IGEgY2hpbGQgcHJvY2Vzcy4KKyAqIFVuZGVyIExpbnV4IHRoaXMgbWVhbnMgc2V0dGluZyB0aGUgY2xvc2Utb24tZXhlYyBmbGFnLCB1bmRlciBXaW5kb3dzCisgKiB0aGlzIGlzIFNldEhhbmRsZUluZm9ybWF0aW9uKEhBTkRMRV9GTEFHX0lOSEVSSVQpLgorICovCitib29sIFBpcGU6OmRpc2FsbG93UmVhZEluaGVyaXQodm9pZCkKK3sKKyAgICBpZiAobVJlYWRIYW5kbGUgPT0ga0ludmFsaWRIYW5kbGUpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworI2lmIGRlZmluZWQoSEFWRV9XSU4zMl9JUEMpCisgICAgaWYgKFNldEhhbmRsZUluZm9ybWF0aW9uKChIQU5ETEUpIG1SZWFkSGFuZGxlLCBIQU5ETEVfRkxBR19JTkhFUklULCAwKSA9PSAwKQorICAgICAgICByZXR1cm4gZmFsc2U7CisjZWxzZQorICAgIGlmIChmY250bCgoaW50KSBtUmVhZEhhbmRsZSwgRl9TRVRGRCwgRkRfQ0xPRVhFQykgIT0gMCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworI2VuZGlmCisgICAgcmV0dXJuIHRydWU7Cit9Citib29sIFBpcGU6OmRpc2FsbG93V3JpdGVJbmhlcml0KHZvaWQpCit7CisgICAgaWYgKG1Xcml0ZUhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisjaWYgZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICBpZiAoU2V0SGFuZGxlSW5mb3JtYXRpb24oKEhBTkRMRSkgbVdyaXRlSGFuZGxlLCBIQU5ETEVfRkxBR19JTkhFUklULCAwKSA9PSAwKQorICAgICAgICByZXR1cm4gZmFsc2U7CisjZWxzZQorICAgIGlmIChmY250bCgoaW50KSBtV3JpdGVIYW5kbGUsIEZfU0VURkQsIEZEX0NMT0VYRUMpICE9IDApCisgICAgICAgIHJldHVybiBmYWxzZTsKKyNlbmRpZgorICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogQ2xvc2UgcmVhZCBkZXNjcmlwdG9yLgorICovCitib29sIFBpcGU6OmNsb3NlUmVhZCh2b2lkKQoreworICAgIGlmIChtUmVhZEhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisjaWYgZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICBpZiAobVJlYWRIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpIHsKKyAgICAgICAgaWYgKCFDbG9zZUhhbmRsZSgoSEFORExFKW1SZWFkSGFuZGxlKSkgeworICAgICAgICAgICAgTE9HKExPR19XQVJOLCAicGlwZSIsICJmYWlsZWQgY2xvc2luZyByZWFkIGhhbmRsZVxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisjZWxzZQorICAgIGlmIChtUmVhZEhhbmRsZSAhPSBrSW52YWxpZEhhbmRsZSkgeworICAgICAgICBpZiAoY2xvc2UoKGludCkgbVJlYWRIYW5kbGUpICE9IDApIHsKKyAgICAgICAgICAgIExPRyhMT0dfV0FSTiwgInBpcGUiLCAiZmFpbGVkIGNsb3NpbmcgcmVhZCBmZFxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisjZW5kaWYKKyAgICBtUmVhZEhhbmRsZSA9IGtJbnZhbGlkSGFuZGxlOworICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogQ2xvc2Ugd3JpdGUgZGVzY3JpcHRvci4KKyAqLworYm9vbCBQaXBlOjpjbG9zZVdyaXRlKHZvaWQpCit7CisgICAgaWYgKG1Xcml0ZUhhbmRsZSA9PSBrSW52YWxpZEhhbmRsZSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisjaWYgZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICBpZiAobVdyaXRlSGFuZGxlICE9IGtJbnZhbGlkSGFuZGxlKSB7CisgICAgICAgIGlmICghQ2xvc2VIYW5kbGUoKEhBTkRMRSltV3JpdGVIYW5kbGUpKSB7CisgICAgICAgICAgICBMT0coTE9HX1dBUk4sICJwaXBlIiwgImZhaWxlZCBjbG9zaW5nIHdyaXRlIGhhbmRsZVxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisjZWxzZQorICAgIGlmIChtV3JpdGVIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpIHsKKyAgICAgICAgaWYgKGNsb3NlKChpbnQpIG1Xcml0ZUhhbmRsZSkgIT0gMCkgeworICAgICAgICAgICAgTE9HKExPR19XQVJOLCAicGlwZSIsICJmYWlsZWQgY2xvc2luZyB3cml0ZSBmZFxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisjZW5kaWYKKyAgICBtV3JpdGVIYW5kbGUgPSBrSW52YWxpZEhhbmRsZTsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIEdldCB0aGUgcmVhZCBoYW5kbGUuCisgKi8KK3Vuc2lnbmVkIGxvbmcgUGlwZTo6Z2V0UmVhZEhhbmRsZSh2b2lkKQoreworICAgIGFzc2VydChtUmVhZEhhbmRsZSAhPSBrSW52YWxpZEhhbmRsZSk7CisKKyAgICByZXR1cm4gbVJlYWRIYW5kbGU7Cit9CisKKy8qCisgKiBHZXQgdGhlIHdyaXRlIGhhbmRsZS4KKyAqLwordW5zaWduZWQgbG9uZyBQaXBlOjpnZXRXcml0ZUhhbmRsZSh2b2lkKQoreworICAgIGFzc2VydChtV3JpdGVIYW5kbGUgIT0ga0ludmFsaWRIYW5kbGUpOworCisgICAgcmV0dXJuIG1Xcml0ZUhhbmRsZTsKK30KKwpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9Qcm9jZXNzU3RhdGUuY3BwIGIvbGlicy91dGlscy9Qcm9jZXNzU3RhdGUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1NjdkZjYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1Byb2Nlc3NTdGF0ZS5jcHAKQEAgLTAsMCArMSwzOTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlByb2Nlc3NTdGF0ZSIKKworI2luY2x1ZGUgPGN1dGlscy9wcm9jZXNzX25hbWUuaD4KKworI2luY2x1ZGUgPHV0aWxzL1Byb2Nlc3NTdGF0ZS5oPgorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvQnBCaW5kZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKyNpbmNsdWRlIDx1dGlscy9JU2VydmljZU1hbmFnZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9iaW5kZXJfbW9kdWxlLmg+CisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9TdGF0aWMuaD4KKworI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKworI2RlZmluZSBCSU5ERVJfVk1fU0laRSAoMSoxMDI0KjEwMjQpCisKK3N0YXRpYyBib29sIGdTaW5nbGVQcm9jZXNzID0gZmFsc2U7CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKyAKKy8vIEdsb2JhbCB2YXJpYWJsZXMKK2ludCAgICAgICAgICAgICAgICAgbUFyZ0M7Citjb25zdCBjaGFyKiBjb25zdCogIG1BcmdWOworaW50ICAgICAgICAgICAgICAgICBtQXJnTGVuOworCitjbGFzcyBQb29sVGhyZWFkIDogcHVibGljIFRocmVhZAoreworcHVibGljOgorICAgIFBvb2xUaHJlYWQoYm9vbCBpc01haW4pCisgICAgICAgIDogbUlzTWFpbihpc01haW4pCisgICAgeworICAgIH0KKyAgICAKK3Byb3RlY3RlZDoKKyAgICB2aXJ0dWFsIGJvb2wgdGhyZWFkTG9vcCgpCisgICAgeworICAgICAgICBJUENUaHJlYWRTdGF0ZTo6c2VsZigpLT5qb2luVGhyZWFkUG9vbChtSXNNYWluKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAKKyAgICBjb25zdCBib29sIG1Jc01haW47Cit9OworCitzcDxQcm9jZXNzU3RhdGU+IFByb2Nlc3NTdGF0ZTo6c2VsZigpCit7CisgICAgaWYgKGdQcm9jZXNzICE9IE5VTEwpIHJldHVybiBnUHJvY2VzczsKKyAgICAKKyAgICBBdXRvTXV0ZXggX2woZ1Byb2Nlc3NNdXRleCk7CisgICAgaWYgKGdQcm9jZXNzID09IE5VTEwpIGdQcm9jZXNzID0gbmV3IFByb2Nlc3NTdGF0ZTsKKyAgICByZXR1cm4gZ1Byb2Nlc3M7Cit9CisKK3ZvaWQgUHJvY2Vzc1N0YXRlOjpzZXRTaW5nbGVQcm9jZXNzKGJvb2wgc2luZ2xlUHJvY2VzcykKK3sKKyAgICBnU2luZ2xlUHJvY2VzcyA9IHNpbmdsZVByb2Nlc3M7Cit9CisKKwordm9pZCBQcm9jZXNzU3RhdGU6OnNldENvbnRleHRPYmplY3QoY29uc3Qgc3A8SUJpbmRlcj4mIG9iamVjdCkKK3sKKyAgICBzZXRDb250ZXh0T2JqZWN0KG9iamVjdCwgU3RyaW5nMTYoImRlZmF1bHQiKSk7Cit9CisKK3NwPElCaW5kZXI+IFByb2Nlc3NTdGF0ZTo6Z2V0Q29udGV4dE9iamVjdChjb25zdCBzcDxJQmluZGVyPiYgY2FsbGVyKQoreworICAgIGlmIChzdXBwb3J0c1Byb2Nlc3NlcygpKSB7CisgICAgICAgIHJldHVybiBnZXRTdHJvbmdQcm94eUZvckhhbmRsZSgwKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE9iamVjdChTdHJpbmcxNigiZGVmYXVsdCIpLCBjYWxsZXIpOworICAgIH0KK30KKwordm9pZCBQcm9jZXNzU3RhdGU6OnNldENvbnRleHRPYmplY3QoY29uc3Qgc3A8SUJpbmRlcj4mIG9iamVjdCwgY29uc3QgU3RyaW5nMTYmIG5hbWUpCit7CisgICAgQXV0b011dGV4IF9sKG1Mb2NrKTsKKyAgICBtQ29udGV4dHMuYWRkKG5hbWUsIG9iamVjdCk7Cit9CisKK3NwPElCaW5kZXI+IFByb2Nlc3NTdGF0ZTo6Z2V0Q29udGV4dE9iamVjdChjb25zdCBTdHJpbmcxNiYgbmFtZSwgY29uc3Qgc3A8SUJpbmRlcj4mIGNhbGxlcikKK3sKKyAgICBtTG9jay5sb2NrKCk7CisgICAgc3A8SUJpbmRlcj4gb2JqZWN0KAorICAgICAgICBtQ29udGV4dHMuaW5kZXhPZktleShuYW1lKSA+PSAwID8gbUNvbnRleHRzLnZhbHVlRm9yKG5hbWUpIDogTlVMTCk7CisgICAgbUxvY2sudW5sb2NrKCk7CisgICAgCisgICAgLy9wcmludGYoIkdldHRpbmcgY29udGV4dCBvYmplY3QgJXMgZm9yICVwXG4iLCBTdHJpbmc4KG5hbWUpLnN0cmluZygpLCBjYWxsZXIuZ2V0KCkpOworICAgIAorICAgIGlmIChvYmplY3QgIT0gTlVMTCkgcmV0dXJuIG9iamVjdDsKKworICAgIC8vIERvbid0IGF0dGVtcHQgdG8gcmV0cmlldmUgY29udGV4dHMgaWYgd2UgbWFuYWdlIHRoZW0KKyAgICBpZiAobU1hbmFnZXNDb250ZXh0cykgeworICAgICAgICBMT0dFKCJnZXRDb250ZXh0T2JqZWN0KCVzKSBmYWlsZWQsIGJ1dCB3ZSBtYW5hZ2UgdGhlIGNvbnRleHRzIVxuIiwKKyAgICAgICAgICAgIFN0cmluZzgobmFtZSkuc3RyaW5nKCkpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgCisgICAgSVBDVGhyZWFkU3RhdGUqIGlwYyA9IElQQ1RocmVhZFN0YXRlOjpzZWxmKCk7CisgICAgeworICAgICAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgICAgIC8vIG5vIGludGVyZmFjZSB0b2tlbiBvbiB0aGlzIG1hZ2ljIHRyYW5zYWN0aW9uCisgICAgICAgIGRhdGEud3JpdGVTdHJpbmcxNihuYW1lKTsKKyAgICAgICAgZGF0YS53cml0ZVN0cm9uZ0JpbmRlcihjYWxsZXIpOworICAgICAgICBzdGF0dXNfdCByZXN1bHQgPSBpcGMtPnRyYW5zYWN0KDAgLyptYWdpYyovLCAwLCBkYXRhLCAmcmVwbHksIDApOworICAgICAgICBpZiAocmVzdWx0ID09IE5PX0VSUk9SKSB7CisgICAgICAgICAgICBvYmplY3QgPSByZXBseS5yZWFkU3Ryb25nQmluZGVyKCk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaXBjLT5mbHVzaENvbW1hbmRzKCk7CisgICAgCisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSBzZXRDb250ZXh0T2JqZWN0KG9iamVjdCwgbmFtZSk7CisgICAgcmV0dXJuIG9iamVjdDsKK30KKworYm9vbCBQcm9jZXNzU3RhdGU6OnN1cHBvcnRzUHJvY2Vzc2VzKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbURyaXZlckZEID49IDA7Cit9CisKK3ZvaWQgUHJvY2Vzc1N0YXRlOjpzdGFydFRocmVhZFBvb2woKQoreworICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgaWYgKCFtVGhyZWFkUG9vbFN0YXJ0ZWQpIHsKKyAgICAgICAgbVRocmVhZFBvb2xTdGFydGVkID0gdHJ1ZTsKKyAgICAgICAgc3Bhd25Qb29sZWRUaHJlYWQodHJ1ZSk7CisgICAgfQorfQorCitib29sIFByb2Nlc3NTdGF0ZTo6aXNDb250ZXh0TWFuYWdlcih2b2lkKSBjb25zdAoreworICAgIHJldHVybiBtTWFuYWdlc0NvbnRleHRzOworfQorCitib29sIFByb2Nlc3NTdGF0ZTo6YmVjb21lQ29udGV4dE1hbmFnZXIoY29udGV4dF9jaGVja19mdW5jIGNoZWNrRnVuYywgdm9pZCogdXNlckRhdGEpCit7CisgICAgaWYgKCFtTWFuYWdlc0NvbnRleHRzKSB7CisgICAgICAgIEF1dG9NdXRleCBfbChtTG9jayk7CisgICAgICAgIG1CaW5kZXJDb250ZXh0Q2hlY2tGdW5jID0gY2hlY2tGdW5jOworICAgICAgICBtQmluZGVyQ29udGV4dFVzZXJEYXRhID0gdXNlckRhdGE7CisgICAgICAgIGlmIChtRHJpdmVyRkQgPj0gMCkgeworICAgICAgICAgICAgaW50IGR1bW15ID0gMDsKKyNpZiBkZWZpbmVkKEhBVkVfQU5EUk9JRF9PUykKKyAgICAgICAgICAgIHN0YXR1c190IHJlc3VsdCA9IGlvY3RsKG1Ecml2ZXJGRCwgQklOREVSX1NFVF9DT05URVhUX01HUiwgJmR1bW15KTsKKyNlbHNlCisgICAgICAgICAgICBzdGF0dXNfdCByZXN1bHQgPSBJTlZBTElEX09QRVJBVElPTjsKKyNlbmRpZgorICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgbU1hbmFnZXNDb250ZXh0cyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgICAgIG1CaW5kZXJDb250ZXh0Q2hlY2tGdW5jID0gTlVMTDsKKyAgICAgICAgICAgICAgICBtQmluZGVyQ29udGV4dFVzZXJEYXRhID0gTlVMTDsKKyAgICAgICAgICAgICAgICBMT0dFKCJCaW5kZXIgaW9jdGwgdG8gYmVjb21lIGNvbnRleHQgbWFuYWdlciBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gZHJpdmVyLCBvdXIgb25seSB3b3JsZCBpcyB0aGUgbG9jYWwKKyAgICAgICAgICAgIC8vIHByb2Nlc3Mgc28gd2UgY2FuIGFsd2F5cyBiZWNvbWUgdGhlIGNvbnRleHQgbWFuYWdlciB0aGVyZS4KKyAgICAgICAgICAgIG1NYW5hZ2VzQ29udGV4dHMgPSB0cnVlOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBtTWFuYWdlc0NvbnRleHRzOworfQorCitQcm9jZXNzU3RhdGU6OmhhbmRsZV9lbnRyeSogUHJvY2Vzc1N0YXRlOjpsb29rdXBIYW5kbGVMb2NrZWQoaW50MzJfdCBoYW5kbGUpCit7CisgICAgY29uc3Qgc2l6ZV90IE49bUhhbmRsZVRvT2JqZWN0LnNpemUoKTsKKyAgICBpZiAoTiA8PSAoc2l6ZV90KWhhbmRsZSkgeworICAgICAgICBoYW5kbGVfZW50cnkgZTsKKyAgICAgICAgZS5iaW5kZXIgPSBOVUxMOworICAgICAgICBlLnJlZnMgPSBOVUxMOworICAgICAgICBzdGF0dXNfdCBlcnIgPSBtSGFuZGxlVG9PYmplY3QuaW5zZXJ0QXQoZSwgTiwgaGFuZGxlKzEtTik7CisgICAgICAgIGlmIChlcnIgPCBOT19FUlJPUikgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAmbUhhbmRsZVRvT2JqZWN0LmVkaXRJdGVtQXQoaGFuZGxlKTsKK30KKworc3A8SUJpbmRlcj4gUHJvY2Vzc1N0YXRlOjpnZXRTdHJvbmdQcm94eUZvckhhbmRsZShpbnQzMl90IGhhbmRsZSkKK3sKKyAgICBzcDxJQmluZGVyPiByZXN1bHQ7CisKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworCisgICAgaGFuZGxlX2VudHJ5KiBlID0gbG9va3VwSGFuZGxlTG9ja2VkKGhhbmRsZSk7CisKKyAgICBpZiAoZSAhPSBOVUxMKSB7CisgICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IEJwQmluZGVyIGlmIHRoZXJlIGlzbid0IGN1cnJlbnRseSBvbmUsIE9SIHdlCisgICAgICAgIC8vIGFyZSB1bmFibGUgdG8gYWNxdWlyZSBhIHdlYWsgcmVmZXJlbmNlIG9uIHRoaXMgY3VycmVudCBvbmUuICBTZWUgY29tbWVudAorICAgICAgICAvLyBpbiBnZXRXZWFrUHJveHlGb3JIYW5kbGUoKSBmb3IgbW9yZSBpbmZvIGFib3V0IHRoaXMuCisgICAgICAgIElCaW5kZXIqIGIgPSBlLT5iaW5kZXI7CisgICAgICAgIGlmIChiID09IE5VTEwgfHwgIWUtPnJlZnMtPmF0dGVtcHRJbmNXZWFrKHRoaXMpKSB7CisgICAgICAgICAgICBiID0gbmV3IEJwQmluZGVyKGhhbmRsZSk7IAorICAgICAgICAgICAgZS0+YmluZGVyID0gYjsKKyAgICAgICAgICAgIGlmIChiKSBlLT5yZWZzID0gYi0+Z2V0V2Vha1JlZnMoKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IGI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBUaGlzIGxpdHRsZSBiaXQgb2YgbmFzdHluZXNzIGlzIHRvIGFsbG93IHVzIHRvIGFkZCBhIHByaW1hcnkKKyAgICAgICAgICAgIC8vIHJlZmVyZW5jZSB0byB0aGUgcmVtb3RlIHByb3h5IHdoZW4gdGhpcyB0ZWFtIGRvZXNuJ3QgaGF2ZSBvbmUKKyAgICAgICAgICAgIC8vIGJ1dCBhbm90aGVyIHRlYW0gaXMgc2VuZGluZyB0aGUgaGFuZGxlIHRvIHVzLgorICAgICAgICAgICAgcmVzdWx0LmZvcmNlX3NldChiKTsKKyAgICAgICAgICAgIGUtPnJlZnMtPmRlY1dlYWsodGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCit3cDxJQmluZGVyPiBQcm9jZXNzU3RhdGU6OmdldFdlYWtQcm94eUZvckhhbmRsZShpbnQzMl90IGhhbmRsZSkKK3sKKyAgICB3cDxJQmluZGVyPiByZXN1bHQ7CisKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworCisgICAgaGFuZGxlX2VudHJ5KiBlID0gbG9va3VwSGFuZGxlTG9ja2VkKGhhbmRsZSk7CisKKyAgICBpZiAoZSAhPSBOVUxMKSB7ICAgICAgICAKKyAgICAgICAgLy8gV2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgQnBCaW5kZXIgaWYgdGhlcmUgaXNuJ3QgY3VycmVudGx5IG9uZSwgT1Igd2UKKyAgICAgICAgLy8gYXJlIHVuYWJsZSB0byBhY3F1aXJlIGEgd2VhayByZWZlcmVuY2Ugb24gdGhpcyBjdXJyZW50IG9uZS4gIFRoZQorICAgICAgICAvLyBhdHRlbXB0SW5jV2VhaygpIGlzIHNhZmUgYmVjYXVzZSB3ZSBrbm93IHRoZSBCcEJpbmRlciBkZXN0cnVjdG9yIHdpbGwgYWx3YXlzCisgICAgICAgIC8vIGNhbGwgZXhwdW5nZUhhbmRsZSgpLCB3aGljaCBhY3F1aXJlcyB0aGUgc2FtZSBsb2NrIHdlIGFyZSBob2xkaW5nIG5vdy4KKyAgICAgICAgLy8gV2UgbmVlZCB0byBkbyB0aGlzIGJlY2F1c2UgdGhlcmUgaXMgYSByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuIHNvbWVvbmUKKyAgICAgICAgLy8gcmVsZWFzaW5nIGEgcmVmZXJlbmNlIG9uIHRoaXMgQnBCaW5kZXIsIGFuZCBhIG5ldyByZWZlcmVuY2Ugb24gaXRzIGhhbmRsZQorICAgICAgICAvLyBhcnJpdmluZyBmcm9tIHRoZSBkcml2ZXIuCisgICAgICAgIElCaW5kZXIqIGIgPSBlLT5iaW5kZXI7CisgICAgICAgIGlmIChiID09IE5VTEwgfHwgIWUtPnJlZnMtPmF0dGVtcHRJbmNXZWFrKHRoaXMpKSB7CisgICAgICAgICAgICBiID0gbmV3IEJwQmluZGVyKGhhbmRsZSk7CisgICAgICAgICAgICByZXN1bHQgPSBiOworICAgICAgICAgICAgZS0+YmluZGVyID0gYjsKKyAgICAgICAgICAgIGlmIChiKSBlLT5yZWZzID0gYi0+Z2V0V2Vha1JlZnMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGI7CisgICAgICAgICAgICBlLT5yZWZzLT5kZWNXZWFrKHRoaXMpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBQcm9jZXNzU3RhdGU6OmV4cHVuZ2VIYW5kbGUoaW50MzJfdCBoYW5kbGUsIElCaW5kZXIqIGJpbmRlcikKK3sKKyAgICBBdXRvTXV0ZXggX2wobUxvY2spOworICAgIAorICAgIGhhbmRsZV9lbnRyeSogZSA9IGxvb2t1cEhhbmRsZUxvY2tlZChoYW5kbGUpOworCisgICAgLy8gVGhpcyBoYW5kbGUgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIHJlcGxhY2VkIHdpdGggYSBuZXcgQnBCaW5kZXIKKyAgICAvLyAoaWYgc29tZW9uZSBmYWlsZWQgdGhlIEF0dGVtcHRJbmNXZWFrKCkgYWJvdmUpOyB3ZSBkb24ndCB3YW50CisgICAgLy8gdG8gb3ZlcndyaXRlIGl0LgorICAgIGlmIChlICYmIGUtPmJpbmRlciA9PSBiaW5kZXIpIGUtPmJpbmRlciA9IE5VTEw7Cit9CisKK3ZvaWQgUHJvY2Vzc1N0YXRlOjpzZXRBcmdzKGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pCit7CisgICAgbUFyZ0MgPSBhcmdjOworICAgIG1BcmdWID0gKGNvbnN0IGNoYXIgKiopYXJndjsKKworICAgIG1BcmdMZW4gPSAwOworICAgIGZvciAoaW50IGk9MDsgaTxhcmdjOyBpKyspIHsKKyAgICAgICAgbUFyZ0xlbiArPSBzdHJsZW4oYXJndltpXSkgKyAxOworICAgIH0KKyAgICBtQXJnTGVuLS07Cit9CisKK2ludCBQcm9jZXNzU3RhdGU6OmdldEFyZ0MoKSBjb25zdAoreworICAgIHJldHVybiBtQXJnQzsKK30KKworY29uc3QgY2hhciogY29uc3QqIFByb2Nlc3NTdGF0ZTo6Z2V0QXJnVigpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1BcmdWOworfQorCit2b2lkIFByb2Nlc3NTdGF0ZTo6c2V0QXJnVjAoY29uc3QgY2hhciogdHh0KQoreworICAgIGlmIChtQXJnViAhPSBOVUxMKSB7CisgICAgICAgIHN0cm5jcHkoKGNoYXIqKW1BcmdWWzBdLCB0eHQsIG1BcmdMZW4pOworICAgICAgICBzZXRfcHJvY2Vzc19uYW1lKHR4dCk7CisgICAgfQorfQorCit2b2lkIFByb2Nlc3NTdGF0ZTo6c3Bhd25Qb29sZWRUaHJlYWQoYm9vbCBpc01haW4pCit7CisgICAgaWYgKG1UaHJlYWRQb29sU3RhcnRlZCkgeworICAgICAgICBpbnQzMl90IHMgPSBhbmRyb2lkX2F0b21pY19hZGQoMSwgJm1UaHJlYWRQb29sU2VxKTsKKyAgICAgICAgY2hhciBidWZbMzJdOworICAgICAgICBzcHJpbnRmKGJ1ZiwgIkJpbmRlciBUaHJlYWQgIyVkIiwgcyk7CisgICAgICAgIExPR1YoIlNwYXduaW5nIG5ldyBwb29sZWQgdGhyZWFkLCBuYW1lPSVzXG4iLCBidWYpOworICAgICAgICBzcDxUaHJlYWQ+IHQgPSBuZXcgUG9vbFRocmVhZChpc01haW4pOworICAgICAgICB0LT5ydW4oYnVmKTsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQgb3Blbl9kcml2ZXIoKQoreworICAgIGlmIChnU2luZ2xlUHJvY2VzcykgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaW50IGZkID0gb3BlbigiL2Rldi9iaW5kZXIiLCBPX1JEV1IpOworICAgIGlmIChmZCA+PSAwKSB7CisgICAgICAgIGZjbnRsKGZkLCBGX1NFVEZELCBGRF9DTE9FWEVDKTsKKyAgICAgICAgaW50IHZlcnM7CisjaWYgZGVmaW5lZChIQVZFX0FORFJPSURfT1MpCisgICAgICAgIHN0YXR1c190IHJlc3VsdCA9IGlvY3RsKGZkLCBCSU5ERVJfVkVSU0lPTiwgJnZlcnMpOworI2Vsc2UKKyAgICAgICAgc3RhdHVzX3QgcmVzdWx0ID0gLTE7CisgICAgICAgIGVycm5vID0gRVBFUk07CisjZW5kaWYKKyAgICAgICAgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgTE9HRSgiQmluZGVyIGlvY3RsIHRvIG9idGFpbiB2ZXJzaW9uIGZhaWxlZDogJXMiLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICAgICAgY2xvc2UoZmQpOworICAgICAgICAgICAgZmQgPSAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVzdWx0ICE9IDAgfHwgdmVycyAhPSBCSU5ERVJfQ1VSUkVOVF9QUk9UT0NPTF9WRVJTSU9OKSB7CisgICAgICAgICAgICBMT0dFKCJCaW5kZXIgZHJpdmVyIHByb3RvY29sIGRvZXMgbm90IG1hdGNoIHVzZXIgc3BhY2UgcHJvdG9jb2whIik7CisgICAgICAgICAgICBjbG9zZShmZCk7CisgICAgICAgICAgICBmZCA9IC0xOworICAgICAgICB9CisjaWYgZGVmaW5lZChIQVZFX0FORFJPSURfT1MpCisgICAgICAgIHNpemVfdCBtYXhUaHJlYWRzID0gMTU7CisgICAgICAgIHJlc3VsdCA9IGlvY3RsKGZkLCBCSU5ERVJfU0VUX01BWF9USFJFQURTLCAmbWF4VGhyZWFkcyk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgICAgIExPR0UoIkJpbmRlciBpb2N0bCB0byBzZXQgbWF4IHRocmVhZHMgZmFpbGVkOiAlcyIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgICBMT0dXKCJPcGVuaW5nICcvZGV2L2JpbmRlcicgZmFpbGVkOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICB9CisgICAgcmV0dXJuIGZkOworfQorCitQcm9jZXNzU3RhdGU6OlByb2Nlc3NTdGF0ZSgpCisgICAgOiBtRHJpdmVyRkQob3Blbl9kcml2ZXIoKSkKKyAgICAsIG1WTVN0YXJ0KE1BUF9GQUlMRUQpCisgICAgLCBtTWFuYWdlc0NvbnRleHRzKGZhbHNlKQorICAgICwgbUJpbmRlckNvbnRleHRDaGVja0Z1bmMoTlVMTCkKKyAgICAsIG1CaW5kZXJDb250ZXh0VXNlckRhdGEoTlVMTCkKKyAgICAsIG1UaHJlYWRQb29sU3RhcnRlZChmYWxzZSkKKyAgICAsIG1UaHJlYWRQb29sU2VxKDEpCit7CisgICAgaWYgKG1Ecml2ZXJGRCA+PSAwKSB7CisgICAgICAgIC8vIFhYWCBJZGVhbGx5LCB0aGVyZSBzaG91bGQgYmUgYSBzcGVjaWZpYyBkZWZpbmUgZm9yIHdoZXRoZXIgd2UKKyAgICAgICAgLy8gaGF2ZSBtbWFwIChvciB3aGV0aGVyIHdlIGNvdWxkIHBvc3NpYmx5IGhhdmUgdGhlIGtlcm5lbCBtb2R1bGUKKyAgICAgICAgLy8gYXZhaWxhYmxhKS4KKyNpZiAhZGVmaW5lZChIQVZFX1dJTjMyX0lQQykKKyAgICAgICAgLy8gbW1hcCB0aGUgYmluZGVyLCBwcm92aWRpbmcgYSBjaHVuayBvZiB2aXJ0dWFsIGFkZHJlc3Mgc3BhY2UgdG8gcmVjZWl2ZSB0cmFuc2FjdGlvbnMuCisgICAgICAgIG1WTVN0YXJ0ID0gbW1hcCgwLCBCSU5ERVJfVk1fU0laRSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSB8IE1BUF9OT1JFU0VSVkUsIG1Ecml2ZXJGRCwgMCk7CisgICAgICAgIGlmIChtVk1TdGFydCA9PSBNQVBfRkFJTEVEKSB7CisgICAgICAgICAgICAvLyAqc2lnaCoKKyAgICAgICAgICAgIExPR0UoIlVzaW5nIC9kZXYvYmluZGVyIGZhaWxlZDogdW5hYmxlIHRvIG1tYXAgdHJhbnNhY3Rpb24gbWVtb3J5LlxuIik7CisgICAgICAgICAgICBjbG9zZShtRHJpdmVyRkQpOworICAgICAgICAgICAgbURyaXZlckZEID0gLTE7CisgICAgICAgIH0KKyNlbHNlCisgICAgICAgIG1Ecml2ZXJGRCA9IC0xOworI2VuZGlmCisgICAgfQorICAgIGlmIChtRHJpdmVyRkQgPCAwKSB7CisgICAgICAgIC8vIE5lZWQgdG8gcnVuIHdpdGhvdXQgdGhlIGRyaXZlciwgc3RhcnRpbmcgb3VyIG93biB0aHJlYWQgcG9vbC4KKyAgICB9Cit9CisKK1Byb2Nlc3NTdGF0ZTo6flByb2Nlc3NTdGF0ZSgpCit7Cit9CisgICAgICAgIAorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvUkVBRE1FIGIvbGlicy91dGlscy9SRUFETUUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZhNzA2ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvUkVBRE1FCkBAIC0wLDAgKzEsMTQgQEAKK0FuZHJvaWQgVXRpbGl0eSBGdW5jdGlvbiBMaWJyYXJ5CisKK0lmIHlvdSBuZWVkIGEgZmVhdHVyZSB0aGF0IGlzIG5hdGl2ZSB0byBMaW51eCBidXQgbm90IHByZXNlbnQgb24gb3RoZXIKK3BsYXRmb3JtcywgY29uc3RydWN0IGEgcGxhdGZvcm0tZGVwZW5kZW50IGltcGxlbWVudGF0aW9uIHRoYXQgc2hhcmVzCit0aGUgTGludXggaW50ZXJmYWNlLiAgVGhhdCB3YXkgdGhlIGFjdHVhbCBkZXZpY2UgcnVucyBhcyAibGlnaHQiIGFzCitwb3NzaWJsZS4KKworSWYgdGhhdCBpc24ndCBmZWFzaWJsZSwgY3JlYXRlIGEgc3lzdGVtLWluZGVwZW5kZW50IGludGVyZmFjZSBhbmQgaGlkZQordGhlIGRldGFpbHMuCisKK1RoZSB1bHRpbWF0ZSBnb2FsIGlzICpub3QqIHRvIGNyZWF0ZSBhIHN1cGVyLWR1cGVyIHBsYXRmb3JtIGFic3RyYWN0aW9uCitsYXllci4gIFRoZSBnb2FsIGlzIHRvIHByb3ZpZGUgYW4gb3B0aW1pemVkIHNvbHV0aW9uIGZvciBMaW51eCB3aXRoCityZWFzb25hYmxlIGltcGxlbWVudGF0aW9ucyBmb3Igb3RoZXIgcGxhdGZvcm1zLgorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1JlZkJhc2UuY3BwIGIvbGlicy91dGlscy9SZWZCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYmQxYWY0Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9SZWZCYXNlLmNwcApAQCAtMCwwICsxLDUzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiUmVmQmFzZSIKKworI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKworI2luY2x1ZGUgPHV0aWxzL0F0b21pYy5oPgorI2luY2x1ZGUgPHV0aWxzL0NhbGxTdGFjay5oPgorI2luY2x1ZGUgPHV0aWxzL0tleWVkVmVjdG9yLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDx0eXBlaW5mbz4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisKKy8vIGNvbXBpbGUgd2l0aCByZWZjb3VudGluZyBkZWJ1Z2dpbmcgZW5hYmxlZAorI2RlZmluZSBERUJVR19SRUZTICAgICAgICAgICAgICAgICAgICAgIDAKKyNkZWZpbmUgREVCVUdfUkVGU19FTkFCTEVEX0JZX0RFRkFVTFQgICAxCisjZGVmaW5lIERFQlVHX1JFRlNfQ0FMTFNUQUNLX0VOQUJMRUQgICAgMQorCisvLyBsb2cgYWxsIHJlZmVyZW5jZSBjb3VudGluZyBvcGVyYXRpb25zCisjZGVmaW5lIFBSSU5UX1JFRlMgICAgICAgICAgICAgICAgICAgICAgMAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisjZGVmaW5lIElOSVRJQUxfU1RST05HX1ZBTFVFICgxPDwyOCkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIFJlZkJhc2U6OndlYWtyZWZfaW1wbCA6IHB1YmxpYyBSZWZCYXNlOjp3ZWFrcmVmX3R5cGUKK3sKK3B1YmxpYzoKKyAgICB2b2xhdGlsZSBpbnQzMl90ICAgIG1TdHJvbmc7CisgICAgdm9sYXRpbGUgaW50MzJfdCAgICBtV2VhazsKKyAgICBSZWZCYXNlKiBjb25zdCAgICAgIG1CYXNlOworICAgIHZvbGF0aWxlIGludDMyX3QgICAgbUZsYWdzOworCisKKyNpZiAhREVCVUdfUkVGUworCisgICAgd2Vha3JlZl9pbXBsKFJlZkJhc2UqIGJhc2UpCisgICAgICAgIDogbVN0cm9uZyhJTklUSUFMX1NUUk9OR19WQUxVRSkKKyAgICAgICAgLCBtV2VhaygwKQorICAgICAgICAsIG1CYXNlKGJhc2UpCisgICAgICAgICwgbUZsYWdzKDApCisgICAgeworICAgIH0KKworICAgIHZvaWQgYWRkU3Ryb25nUmVmKGNvbnN0IHZvaWQqIC8qaWQqLykgeyB9CisgICAgdm9pZCByZW1vdmVTdHJvbmdSZWYoY29uc3Qgdm9pZCogLyppZCovKSB7IH0KKyAgICB2b2lkIGFkZFdlYWtSZWYoY29uc3Qgdm9pZCogLyppZCovKSB7IH0KKyAgICB2b2lkIHJlbW92ZVdlYWtSZWYoY29uc3Qgdm9pZCogLyppZCovKSB7IH0KKyAgICB2b2lkIHByaW50UmVmcygpIGNvbnN0IHsgfQorICAgIHZvaWQgdHJhY2tNZShib29sLCBib29sKSB7IH0KKworI2Vsc2UKKworICAgIHdlYWtyZWZfaW1wbChSZWZCYXNlKiBiYXNlKQorICAgICAgICA6IG1TdHJvbmcoSU5JVElBTF9TVFJPTkdfVkFMVUUpCisgICAgICAgICwgbVdlYWsoMCkKKyAgICAgICAgLCBtQmFzZShiYXNlKQorICAgICAgICAsIG1GbGFncygwKQorICAgICAgICAsIG1TdHJvbmdSZWZzKE5VTEwpCisgICAgICAgICwgbVdlYWtSZWZzKE5VTEwpCisgICAgICAgICwgbVRyYWNrRW5hYmxlZCghIURFQlVHX1JFRlNfRU5BQkxFRF9CWV9ERUZBVUxUKQorICAgICAgICAsIG1SZXRhaW4oZmFsc2UpCisgICAgeworICAgICAgICAvL0xPR0koIk5FVyB3ZWFrcmVmX2ltcGwgJXAgZm9yIFJlZkJhc2UgJXAiLCB0aGlzLCBiYXNlKTsKKyAgICB9CisgICAgCisgICAgfndlYWtyZWZfaW1wbCgpCisgICAgeworICAgICAgICBMT0dfQUxXQVlTX0ZBVEFMX0lGKCFtUmV0YWluICYmIG1TdHJvbmdSZWZzICE9IE5VTEwsICJTdHJvbmcgcmVmZXJlbmNlcyByZW1haW4hIik7CisgICAgICAgIExPR19BTFdBWVNfRkFUQUxfSUYoIW1SZXRhaW4gJiYgbVdlYWtSZWZzICE9IE5VTEwsICJXZWFrIHJlZmVyZW5jZXMgcmVtYWluISIpOworICAgIH0KKworICAgIHZvaWQgYWRkU3Ryb25nUmVmKGNvbnN0IHZvaWQqIGlkKQorICAgIHsKKyAgICAgICAgYWRkUmVmKCZtU3Ryb25nUmVmcywgaWQsIG1TdHJvbmcpOworICAgIH0KKworICAgIHZvaWQgcmVtb3ZlU3Ryb25nUmVmKGNvbnN0IHZvaWQqIGlkKQorICAgIHsKKyAgICAgICAgaWYgKCFtUmV0YWluKQorICAgICAgICAgICAgcmVtb3ZlUmVmKCZtU3Ryb25nUmVmcywgaWQpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBhZGRSZWYoJm1TdHJvbmdSZWZzLCBpZCwgLW1TdHJvbmcpOworICAgIH0KKworICAgIHZvaWQgYWRkV2Vha1JlZihjb25zdCB2b2lkKiBpZCkKKyAgICB7CisgICAgICAgIGFkZFJlZigmbVdlYWtSZWZzLCBpZCwgbVdlYWspOworICAgIH0KKworICAgIHZvaWQgcmVtb3ZlV2Vha1JlZihjb25zdCB2b2lkKiBpZCkKKyAgICB7CisgICAgICAgIGlmICghbVJldGFpbikKKyAgICAgICAgICAgIHJlbW92ZVJlZigmbVdlYWtSZWZzLCBpZCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGFkZFJlZigmbVdlYWtSZWZzLCBpZCwgLW1XZWFrKTsKKyAgICB9CisKKyAgICB2b2lkIHRyYWNrTWUoYm9vbCB0cmFjaywgYm9vbCByZXRhaW4pCisgICAgeyAKKyAgICAgICAgbVRyYWNrRW5hYmxlZCA9IHRyYWNrOworICAgICAgICBtUmV0YWluID0gcmV0YWluOworICAgIH0KKworICAgIHZvaWQgcHJpbnRSZWZzKCkgY29uc3QKKyAgICB7CisgICAgICAgIFN0cmluZzggdGV4dDsKKworICAgICAgICB7CisgICAgICAgICAgICBBdXRvTXV0ZXggX2woY29uc3RfY2FzdDx3ZWFrcmVmX2ltcGwqPih0aGlzKS0+bU11dGV4KTsKKyAgICAKKyAgICAgICAgICAgIGNoYXIgYnVmWzEyOF07CisgICAgICAgICAgICBzcHJpbnRmKGJ1ZiwgIlN0cm9uZyByZWZlcmVuY2VzIG9uIFJlZkJhc2UgJXAgKHdlYWtyZWZfdHlwZSAlcCk6XG4iLCBtQmFzZSwgdGhpcyk7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZChidWYpOworICAgICAgICAgICAgcHJpbnRSZWZzTG9ja2VkKCZ0ZXh0LCBtU3Ryb25nUmVmcyk7CisgICAgICAgICAgICBzcHJpbnRmKGJ1ZiwgIldlYWsgcmVmZXJlbmNlcyBvbiBSZWZCYXNlICVwICh3ZWFrcmVmX3R5cGUgJXApOlxuIiwgbUJhc2UsIHRoaXMpOworICAgICAgICAgICAgdGV4dC5hcHBlbmQoYnVmKTsKKyAgICAgICAgICAgIHByaW50UmVmc0xvY2tlZCgmdGV4dCwgbVdlYWtSZWZzKTsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICAgIGNoYXIgbmFtZVsxMDBdOworICAgICAgICAgICAgc25wcmludGYobmFtZSwgMTAwLCAiL2RhdGEvJXAuc3RhY2siLCB0aGlzKTsKKyAgICAgICAgICAgIGludCByYyA9IG9wZW4obmFtZSwgT19SRFdSIHwgT19DUkVBVCB8IE9fQVBQRU5EKTsKKyAgICAgICAgICAgIGlmIChyYyA+PSAwKSB7CisgICAgICAgICAgICAgICAgd3JpdGUocmMsIHRleHQuc3RyaW5nKCksIHRleHQubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGNsb3NlKHJjKTsKKyAgICAgICAgICAgICAgICBMT0dEKCJTVEFDSyBUUkFDRSBmb3IgJXAgc2F2ZWQgaW4gJXMiLCB0aGlzLCBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgTE9HRSgiRkFJTEVEIFRPIFBSSU5UIFNUQUNLIFRSQUNFIGZvciAlcCBpbiAlczogJXMiLCB0aGlzLAorICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIH0KKyAgICB9CisKK3ByaXZhdGU6CisgICAgc3RydWN0IHJlZl9lbnRyeQorICAgIHsKKyAgICAgICAgcmVmX2VudHJ5KiBuZXh0OworICAgICAgICBjb25zdCB2b2lkKiBpZDsKKyNpZiBERUJVR19SRUZTX0NBTExTVEFDS19FTkFCTEVECisgICAgICAgIENhbGxTdGFjayBzdGFjazsKKyNlbmRpZgorICAgICAgICBpbnQzMl90IHJlZjsKKyAgICB9OworCisgICAgdm9pZCBhZGRSZWYocmVmX2VudHJ5KiogcmVmcywgY29uc3Qgdm9pZCogaWQsIGludDMyX3QgbVJlZikKKyAgICB7CisgICAgICAgIGlmIChtVHJhY2tFbmFibGVkKSB7CisgICAgICAgICAgICBBdXRvTXV0ZXggX2wobU11dGV4KTsKKyAgICAgICAgICAgIHJlZl9lbnRyeSogcmVmID0gbmV3IHJlZl9lbnRyeTsKKyAgICAgICAgICAgIC8vIFJlZmVyZW5jZSBjb3VudCBhdCB0aGUgdGltZSBvZiB0aGUgc25hcHNob3QsIGJ1dCBiZWZvcmUgdGhlCisgICAgICAgICAgICAvLyB1cGRhdGUuICBQb3NpdGl2ZSB2YWx1ZSBtZWFucyB3ZSBpbmNyZW1lbnQsIG5lZ2F0aXZlLS13ZQorICAgICAgICAgICAgLy8gZGVjcmVtZW50IHRoZSByZWZlcmVuY2UgY291bnQuCisgICAgICAgICAgICByZWYtPnJlZiA9IG1SZWY7CisgICAgICAgICAgICByZWYtPmlkID0gaWQ7CisjaWYgREVCVUdfUkVGU19DQUxMU1RBQ0tfRU5BQkxFRAorICAgICAgICAgICAgcmVmLT5zdGFjay51cGRhdGUoMik7CisjZW5kaWYKKyAgICAgICAgICAgIAorICAgICAgICAgICAgcmVmLT5uZXh0ID0gKnJlZnM7CisgICAgICAgICAgICAqcmVmcyA9IHJlZjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgcmVtb3ZlUmVmKHJlZl9lbnRyeSoqIHJlZnMsIGNvbnN0IHZvaWQqIGlkKQorICAgIHsKKyAgICAgICAgaWYgKG1UcmFja0VuYWJsZWQpIHsKKyAgICAgICAgICAgIEF1dG9NdXRleCBfbChtTXV0ZXgpOworICAgICAgICAgICAgCisgICAgICAgICAgICByZWZfZW50cnkqIHJlZiA9ICpyZWZzOworICAgICAgICAgICAgd2hpbGUgKHJlZiAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlZi0+aWQgPT0gaWQpIHsKKyAgICAgICAgICAgICAgICAgICAgKnJlZnMgPSByZWYtPm5leHQ7CisgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZWY7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgcmVmcyA9ICZyZWYtPm5leHQ7CisgICAgICAgICAgICAgICAgcmVmID0gKnJlZnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIExPR19BTFdBWVNfRkFUQUwoIlJlZkJhc2U6IHJlbW92aW5nIGlkICVwIG9uIFJlZkJhc2UgJXAgKHdlYWtyZWZfdHlwZSAlcCkgdGhhdCBkb2Vzbid0IGV4aXN0ISIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkLCBtQmFzZSwgdGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHByaW50UmVmc0xvY2tlZChTdHJpbmc4KiBvdXQsIGNvbnN0IHJlZl9lbnRyeSogcmVmcykgY29uc3QKKyAgICB7CisgICAgICAgIGNoYXIgYnVmWzEyOF07CisgICAgICAgIHdoaWxlIChyZWZzKSB7CisgICAgICAgICAgICBjaGFyIGluYyA9IHJlZnMtPnJlZiA+PSAwID8gJysnIDogJy0nOworICAgICAgICAgICAgc3ByaW50ZihidWYsICJcdCVjIElEICVwIChyZWYgJWQpOlxuIiwgCisgICAgICAgICAgICAgICAgICAgIGluYywgcmVmcy0+aWQsIHJlZnMtPnJlZik7CisgICAgICAgICAgICBvdXQtPmFwcGVuZChidWYpOworI2lmIERFQlVHX1JFRlNfQ0FMTFNUQUNLX0VOQUJMRUQKKyAgICAgICAgICAgIG91dC0+YXBwZW5kKHJlZnMtPnN0YWNrLnRvU3RyaW5nKCJcdFx0IikpOworI2Vsc2UKKyAgICAgICAgICAgIG91dC0+YXBwZW5kKCJcdFx0KGNhbGwgc3RhY2tzIGRpc2FibGVkKSIpOworI2VuZGlmCisgICAgICAgICAgICByZWZzID0gcmVmcy0+bmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIE11dGV4IG1NdXRleDsKKyAgICByZWZfZW50cnkqIG1TdHJvbmdSZWZzOworICAgIHJlZl9lbnRyeSogbVdlYWtSZWZzOworCisgICAgYm9vbCBtVHJhY2tFbmFibGVkOworICAgIC8vIENvbGxlY3Qgc3RhY2sgdHJhY2VzIG9uIGFkZHJlZiBhbmQgcmVtb3ZlcmVmLCBpbnN0ZWFkIG9mIGRlbGV0aW5nIHRoZSBzdGFjayByZWZlcmVuY2VzCisgICAgLy8gb24gcmVtb3ZlcmVmIHRoYXQgbWF0Y2ggdGhlIGFkZHJlc3Mgb25lcy4KKyAgICBib29sIG1SZXRhaW47CisKKyNpZiAwCisgICAgdm9pZCBhZGRSZWYoS2V5ZWRWZWN0b3I8Y29uc3Qgdm9pZCosIGludDMyX3Q+KiByZWZzLCBjb25zdCB2b2lkKiBpZCkKKyAgICB7CisgICAgICAgIEF1dG9NdXRleCBfbChtTXV0ZXgpOworICAgICAgICBzc2l6ZV90IGkgPSByZWZzLT5pbmRleE9mS2V5KGlkKTsKKyAgICAgICAgaWYgKGkgPj0gMCkgeworICAgICAgICAgICAgKysocmVmcy0+ZWRpdFZhbHVlQXQoaSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaSA9IHJlZnMtPmFkZChpZCwgMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHJlbW92ZVJlZihLZXllZFZlY3Rvcjxjb25zdCB2b2lkKiwgaW50MzJfdD4qIHJlZnMsIGNvbnN0IHZvaWQqIGlkKQorICAgIHsKKyAgICAgICAgQXV0b011dGV4IF9sKG1NdXRleCk7CisgICAgICAgIHNzaXplX3QgaSA9IHJlZnMtPmluZGV4T2ZLZXkoaWQpOworICAgICAgICBMT0dfQUxXQVlTX0ZBVEFMX0lGKGkgPCAwLCAiUmVmQmFzZTogcmVtb3ZpbmcgaWQgJXAgdGhhdCBkb2Vzbid0IGV4aXN0ISIsIGlkKTsKKyAgICAgICAgaWYgKGkgPj0gMCkgeworICAgICAgICAgICAgaW50MzJfdCB2YWwgPSAtLShyZWZzLT5lZGl0VmFsdWVBdChpKSk7CisgICAgICAgICAgICBpZiAodmFsID09IDApIHsKKyAgICAgICAgICAgICAgICByZWZzLT5yZW1vdmVJdGVtc0F0KGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgdm9pZCBwcmludFJlZnMoY29uc3QgS2V5ZWRWZWN0b3I8Y29uc3Qgdm9pZCosIGludDMyX3Q+JiByZWZzKQorICAgIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IE49cmVmcy5zaXplKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgICAgIHByaW50ZigiXHRJRCAlcDogJWQgcmVtYWluXG4iLCByZWZzLmtleUF0KGkpLCByZWZzLnZhbHVlQXQoaSkpOworICAgICAgICB9CisgICAgfQorCisgICAgbXV0YWJsZSBNdXRleCBtTXV0ZXg7CisgICAgS2V5ZWRWZWN0b3I8Y29uc3Qgdm9pZCosIGludDMyX3Q+IG1TdHJvbmdSZWZzOworICAgIEtleWVkVmVjdG9yPGNvbnN0IHZvaWQqLCBpbnQzMl90PiBtV2Vha1JlZnM7CisjZW5kaWYKKworI2VuZGlmCit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBSZWZCYXNlOjppbmNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0Cit7CisgICAgd2Vha3JlZl9pbXBsKiBjb25zdCByZWZzID0gbVJlZnM7CisgICAgcmVmcy0+YWRkV2Vha1JlZihpZCk7CisgICAgcmVmcy0+aW5jV2VhayhpZCk7CisgICAgCisgICAgcmVmcy0+YWRkU3Ryb25nUmVmKGlkKTsKKyAgICBjb25zdCBpbnQzMl90IGMgPSBhbmRyb2lkX2F0b21pY19pbmMoJnJlZnMtPm1TdHJvbmcpOworICAgIExPR19BU1NFUlQoYyA+IDAsICJpbmNTdHJvbmcoKSBjYWxsZWQgb24gJXAgYWZ0ZXIgbGFzdCBzdHJvbmcgcmVmIiwgcmVmcyk7CisjaWYgUFJJTlRfUkVGUworICAgIExPR0QoImluY1N0cm9uZyBvZiAlcCBmcm9tICVwOiBjbnQ9JWRcbiIsIHRoaXMsIGlkLCBjKTsKKyNlbmRpZgorICAgIGlmIChjICE9IElOSVRJQUxfU1RST05HX1ZBTFVFKSAgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgYW5kcm9pZF9hdG9taWNfYWRkKC1JTklUSUFMX1NUUk9OR19WQUxVRSwgJnJlZnMtPm1TdHJvbmcpOworICAgIGNvbnN0X2Nhc3Q8UmVmQmFzZSo+KHRoaXMpLT5vbkZpcnN0UmVmKCk7Cit9CisKK3ZvaWQgUmVmQmFzZTo6ZGVjU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdAoreworICAgIHdlYWtyZWZfaW1wbCogY29uc3QgcmVmcyA9IG1SZWZzOworICAgIHJlZnMtPnJlbW92ZVN0cm9uZ1JlZihpZCk7CisgICAgY29uc3QgaW50MzJfdCBjID0gYW5kcm9pZF9hdG9taWNfZGVjKCZyZWZzLT5tU3Ryb25nKTsKKyNpZiBQUklOVF9SRUZTCisgICAgTE9HRCgiZGVjU3Ryb25nIG9mICVwIGZyb20gJXA6IGNudD0lZFxuIiwgdGhpcywgaWQsIGMpOworI2VuZGlmCisgICAgTE9HX0FTU0VSVChjID49IDEsICJkZWNTdHJvbmcoKSBjYWxsZWQgb24gJXAgdG9vIG1hbnkgdGltZXMiLCByZWZzKTsKKyAgICBpZiAoYyA9PSAxKSB7CisgICAgICAgIGNvbnN0X2Nhc3Q8UmVmQmFzZSo+KHRoaXMpLT5vbkxhc3RTdHJvbmdSZWYoaWQpOworICAgICAgICBpZiAoKHJlZnMtPm1GbGFncyZPQkpFQ1RfTElGRVRJTUVfV0VBSykgIT0gT0JKRUNUX0xJRkVUSU1FX1dFQUspIHsKKyAgICAgICAgICAgIGRlbGV0ZSB0aGlzOworICAgICAgICB9CisgICAgfQorICAgIHJlZnMtPnJlbW92ZVdlYWtSZWYoaWQpOworICAgIHJlZnMtPmRlY1dlYWsoaWQpOworfQorCit2b2lkIFJlZkJhc2U6OmZvcmNlSW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdAoreworICAgIHdlYWtyZWZfaW1wbCogY29uc3QgcmVmcyA9IG1SZWZzOworICAgIHJlZnMtPmFkZFdlYWtSZWYoaWQpOworICAgIHJlZnMtPmluY1dlYWsoaWQpOworICAgIAorICAgIHJlZnMtPmFkZFN0cm9uZ1JlZihpZCk7CisgICAgY29uc3QgaW50MzJfdCBjID0gYW5kcm9pZF9hdG9taWNfaW5jKCZyZWZzLT5tU3Ryb25nKTsKKyAgICBMT0dfQVNTRVJUKGMgPj0gMCwgImZvcmNlSW5jU3Ryb25nIGNhbGxlZCBvbiAlcCBhZnRlciByZWYgY291bnQgdW5kZXJmbG93IiwKKyAgICAgICAgICAgICAgIHJlZnMpOworI2lmIFBSSU5UX1JFRlMKKyAgICBMT0dEKCJmb3JjZUluY1N0cm9uZyBvZiAlcCBmcm9tICVwOiBjbnQ9JWRcbiIsIHRoaXMsIGlkLCBjKTsKKyNlbmRpZgorCisgICAgc3dpdGNoIChjKSB7CisgICAgY2FzZSBJTklUSUFMX1NUUk9OR19WQUxVRToKKyAgICAgICAgYW5kcm9pZF9hdG9taWNfYWRkKC1JTklUSUFMX1NUUk9OR19WQUxVRSwgJnJlZnMtPm1TdHJvbmcpOworICAgICAgICAvLyBmYWxsIHRocm91Z2guLi4KKyAgICBjYXNlIDA6CisgICAgICAgIGNvbnN0X2Nhc3Q8UmVmQmFzZSo+KHRoaXMpLT5vbkZpcnN0UmVmKCk7CisgICAgfQorfQorCitpbnQzMl90IFJlZkJhc2U6OmdldFN0cm9uZ0NvdW50KCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVJlZnMtPm1TdHJvbmc7Cit9CisKKworCitSZWZCYXNlKiBSZWZCYXNlOjp3ZWFrcmVmX3R5cGU6OnJlZkJhc2UoKSBjb25zdAoreworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCB3ZWFrcmVmX2ltcGwqPih0aGlzKS0+bUJhc2U7Cit9CisKK3ZvaWQgUmVmQmFzZTo6d2Vha3JlZl90eXBlOjppbmNXZWFrKGNvbnN0IHZvaWQqIGlkKQoreworICAgIHdlYWtyZWZfaW1wbCogY29uc3QgaW1wbCA9IHN0YXRpY19jYXN0PHdlYWtyZWZfaW1wbCo+KHRoaXMpOworICAgIGltcGwtPmFkZFdlYWtSZWYoaWQpOworICAgIGNvbnN0IGludDMyX3QgYyA9IGFuZHJvaWRfYXRvbWljX2luYygmaW1wbC0+bVdlYWspOworICAgIExPR19BU1NFUlQoYyA+PSAwLCAiaW5jV2VhayBjYWxsZWQgb24gJXAgYWZ0ZXIgbGFzdCB3ZWFrIHJlZiIsIHRoaXMpOworfQorCit2b2lkIFJlZkJhc2U6OndlYWtyZWZfdHlwZTo6ZGVjV2Vhayhjb25zdCB2b2lkKiBpZCkKK3sKKyAgICB3ZWFrcmVmX2ltcGwqIGNvbnN0IGltcGwgPSBzdGF0aWNfY2FzdDx3ZWFrcmVmX2ltcGwqPih0aGlzKTsKKyAgICBpbXBsLT5yZW1vdmVXZWFrUmVmKGlkKTsKKyAgICBjb25zdCBpbnQzMl90IGMgPSBhbmRyb2lkX2F0b21pY19kZWMoJmltcGwtPm1XZWFrKTsKKyAgICBMT0dfQVNTRVJUKGMgPj0gMSwgImRlY1dlYWsgY2FsbGVkIG9uICVwIHRvbyBtYW55IHRpbWVzIiwgdGhpcyk7CisgICAgaWYgKGMgIT0gMSkgcmV0dXJuOworICAgIAorICAgIGlmICgoaW1wbC0+bUZsYWdzJk9CSkVDVF9MSUZFVElNRV9XRUFLKSAhPSBPQkpFQ1RfTElGRVRJTUVfV0VBSykgeworICAgICAgICBpZiAoaW1wbC0+bVN0cm9uZyA9PSBJTklUSUFMX1NUUk9OR19WQUxVRSkKKyAgICAgICAgICAgIGRlbGV0ZSBpbXBsLT5tQmFzZTsKKyAgICAgICAgZWxzZSB7CisvLyAgICAgICAgICAgIExPR1YoIkZyZWVpbmcgcmVmcyAlcCBvZiBvbGQgUmVmQmFzZSAlcFxuIiwgdGhpcywgaW1wbC0+bUJhc2UpOworICAgICAgICAgICAgZGVsZXRlIGltcGw7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBpbXBsLT5tQmFzZS0+b25MYXN0V2Vha1JlZihpZCk7CisgICAgICAgIGlmICgoaW1wbC0+bUZsYWdzJk9CSkVDVF9MSUZFVElNRV9GT1JFVkVSKSAhPSBPQkpFQ1RfTElGRVRJTUVfRk9SRVZFUikgeworICAgICAgICAgICAgZGVsZXRlIGltcGwtPm1CYXNlOworICAgICAgICB9CisgICAgfQorfQorCitib29sIFJlZkJhc2U6OndlYWtyZWZfdHlwZTo6YXR0ZW1wdEluY1N0cm9uZyhjb25zdCB2b2lkKiBpZCkKK3sKKyAgICBpbmNXZWFrKGlkKTsKKyAgICAKKyAgICB3ZWFrcmVmX2ltcGwqIGNvbnN0IGltcGwgPSBzdGF0aWNfY2FzdDx3ZWFrcmVmX2ltcGwqPih0aGlzKTsKKyAgICAKKyAgICBpbnQzMl90IGN1ckNvdW50ID0gaW1wbC0+bVN0cm9uZzsKKyAgICBMT0dfQVNTRVJUKGN1ckNvdW50ID49IDAsICJhdHRlbXB0SW5jU3Ryb25nIGNhbGxlZCBvbiAlcCBhZnRlciB1bmRlcmZsb3ciLAorICAgICAgICAgICAgICAgdGhpcyk7CisgICAgd2hpbGUgKGN1ckNvdW50ID4gMCAmJiBjdXJDb3VudCAhPSBJTklUSUFMX1NUUk9OR19WQUxVRSkgeworICAgICAgICBpZiAoYW5kcm9pZF9hdG9taWNfY21weGNoZyhjdXJDb3VudCwgY3VyQ291bnQrMSwgJmltcGwtPm1TdHJvbmcpID09IDApIHsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGN1ckNvdW50ID0gaW1wbC0+bVN0cm9uZzsKKyAgICB9CisgICAgCisgICAgaWYgKGN1ckNvdW50IDw9IDAgfHwgY3VyQ291bnQgPT0gSU5JVElBTF9TVFJPTkdfVkFMVUUpIHsKKyAgICAgICAgYm9vbCBhbGxvdzsKKyAgICAgICAgaWYgKGN1ckNvdW50ID09IElOSVRJQUxfU1RST05HX1ZBTFVFKSB7CisgICAgICAgICAgICAvLyBBdHRlbXB0aW5nIHRvIGFjcXVpcmUgZmlyc3Qgc3Ryb25nIHJlZmVyZW5jZS4uLiAgdGhpcyBpcyBhbGxvd2VkCisgICAgICAgICAgICAvLyBpZiB0aGUgb2JqZWN0IGRvZXMgTk9UIGhhdmUgYSBsb25nZXIgbGlmZXRpbWUgKG1lYW5pbmcgdGhlCisgICAgICAgICAgICAvLyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IG5lZWQgdG8gc2VlIHRoaXMpLCBvciBpZiB0aGUgaW1wbGVtZW50YXRpb24KKyAgICAgICAgICAgIC8vIGFsbG93cyBpdCB0byBoYXBwZW4uCisgICAgICAgICAgICBhbGxvdyA9IChpbXBsLT5tRmxhZ3MmT0JKRUNUX0xJRkVUSU1FX1dFQUspICE9IE9CSkVDVF9MSUZFVElNRV9XRUFLCisgICAgICAgICAgICAgICAgICB8fCBpbXBsLT5tQmFzZS0+b25JbmNTdHJvbmdBdHRlbXB0ZWQoRklSU1RfSU5DX1NUUk9ORywgaWQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gQXR0ZW1wdGluZyB0byByZXZpdmUgdGhlIG9iamVjdC4uLiAgdGhpcyBpcyBhbGxvd2VkCisgICAgICAgICAgICAvLyBpZiB0aGUgb2JqZWN0IERPRVMgaGF2ZSBhIGxvbmdlciBsaWZldGltZSAoc28gd2UgY2FuIHNhZmVseQorICAgICAgICAgICAgLy8gY2FsbCB0aGUgb2JqZWN0IHdpdGggb25seSBhIHdlYWsgcmVmKSBhbmQgdGhlIGltcGxlbWVudGF0aW9uCisgICAgICAgICAgICAvLyBhbGxvd3MgaXQgdG8gaGFwcGVuLgorICAgICAgICAgICAgYWxsb3cgPSAoaW1wbC0+bUZsYWdzJk9CSkVDVF9MSUZFVElNRV9XRUFLKSA9PSBPQkpFQ1RfTElGRVRJTUVfV0VBSworICAgICAgICAgICAgICAgICAgJiYgaW1wbC0+bUJhc2UtPm9uSW5jU3Ryb25nQXR0ZW1wdGVkKEZJUlNUX0lOQ19TVFJPTkcsIGlkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWFsbG93KSB7CisgICAgICAgICAgICBkZWNXZWFrKGlkKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBjdXJDb3VudCA9IGFuZHJvaWRfYXRvbWljX2luYygmaW1wbC0+bVN0cm9uZyk7CisKKyAgICAgICAgLy8gSWYgdGhlIHN0cm9uZyByZWZlcmVuY2UgY291bnQgaGFzIGFscmVhZHkgYmVlbiBpbmNyZW1lbnRlZCBieQorICAgICAgICAvLyBzb21lb25lIGVsc2UsIHRoZSBpbXBsZW1lbnRvciBvZiBvbkluY1N0cm9uZ0F0dGVtcHRlZCgpIGlzIGhvbGRpbmcKKyAgICAgICAgLy8gYW4gdW5uZWVkZWQgcmVmZXJlbmNlLiAgU28gY2FsbCBvbkxhc3RTdHJvbmdSZWYoKSBoZXJlIHRvIHJlbW92ZSBpdC4KKyAgICAgICAgLy8gKE5vLCB0aGlzIGlzIG5vdCBwcmV0dHkuKSAgTm90ZSB0aGF0IHdlIE1VU1QgTk9UIGRvIHRoaXMgaWYgd2UKKyAgICAgICAgLy8gYXJlIGluIGZhY3QgYWNxdWlyaW5nIHRoZSBmaXJzdCByZWZlcmVuY2UuCisgICAgICAgIGlmIChjdXJDb3VudCA+IDAgJiYgY3VyQ291bnQgPCBJTklUSUFMX1NUUk9OR19WQUxVRSkgeworICAgICAgICAgICAgaW1wbC0+bUJhc2UtPm9uTGFzdFN0cm9uZ1JlZihpZCk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaW1wbC0+YWRkV2Vha1JlZihpZCk7CisgICAgaW1wbC0+YWRkU3Ryb25nUmVmKGlkKTsKKworI2lmIFBSSU5UX1JFRlMKKyAgICBMT0dEKCJhdHRlbXB0SW5jU3Ryb25nIG9mICVwIGZyb20gJXA6IGNudD0lZFxuIiwgdGhpcywgaWQsIGN1ckNvdW50KTsKKyNlbmRpZgorCisgICAgaWYgKGN1ckNvdW50ID09IElOSVRJQUxfU1RST05HX1ZBTFVFKSB7CisgICAgICAgIGFuZHJvaWRfYXRvbWljX2FkZCgtSU5JVElBTF9TVFJPTkdfVkFMVUUsICZpbXBsLT5tU3Ryb25nKTsKKyAgICAgICAgaW1wbC0+bUJhc2UtPm9uRmlyc3RSZWYoKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUmVmQmFzZTo6d2Vha3JlZl90eXBlOjphdHRlbXB0SW5jV2Vhayhjb25zdCB2b2lkKiBpZCkKK3sKKyAgICB3ZWFrcmVmX2ltcGwqIGNvbnN0IGltcGwgPSBzdGF0aWNfY2FzdDx3ZWFrcmVmX2ltcGwqPih0aGlzKTsKKyAgICAKKyAgICBpbnQzMl90IGN1ckNvdW50ID0gaW1wbC0+bVdlYWs7CisgICAgTE9HX0FTU0VSVChjdXJDb3VudCA+PSAwLCAiYXR0ZW1wdEluY1dlYWsgY2FsbGVkIG9uICVwIGFmdGVyIHVuZGVyZmxvdyIsCisgICAgICAgICAgICAgICB0aGlzKTsKKyAgICB3aGlsZSAoY3VyQ291bnQgPiAwKSB7CisgICAgICAgIGlmIChhbmRyb2lkX2F0b21pY19jbXB4Y2hnKGN1ckNvdW50LCBjdXJDb3VudCsxLCAmaW1wbC0+bVdlYWspID09IDApIHsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGN1ckNvdW50ID0gaW1wbC0+bVdlYWs7CisgICAgfQorCisgICAgaWYgKGN1ckNvdW50ID4gMCkgeworICAgICAgICBpbXBsLT5hZGRXZWFrUmVmKGlkKTsKKyAgICB9CisKKyAgICByZXR1cm4gY3VyQ291bnQgPiAwOworfQorCitpbnQzMl90IFJlZkJhc2U6OndlYWtyZWZfdHlwZTo6Z2V0V2Vha0NvdW50KCkgY29uc3QKK3sKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3Qgd2Vha3JlZl9pbXBsKj4odGhpcyktPm1XZWFrOworfQorCit2b2lkIFJlZkJhc2U6OndlYWtyZWZfdHlwZTo6cHJpbnRSZWZzKCkgY29uc3QKK3sKKyAgICBzdGF0aWNfY2FzdDxjb25zdCB3ZWFrcmVmX2ltcGwqPih0aGlzKS0+cHJpbnRSZWZzKCk7Cit9CisKK3ZvaWQgUmVmQmFzZTo6d2Vha3JlZl90eXBlOjp0cmFja01lKGJvb2wgZW5hYmxlLCBib29sIHJldGFpbikKK3sKKyAgICBzdGF0aWNfY2FzdDxjb25zdCB3ZWFrcmVmX2ltcGwqPih0aGlzKS0+dHJhY2tNZShlbmFibGUsIHJldGFpbik7Cit9CisKK1JlZkJhc2U6OndlYWtyZWZfdHlwZSogUmVmQmFzZTo6Y3JlYXRlV2Vhayhjb25zdCB2b2lkKiBpZCkgY29uc3QKK3sKKyAgICBtUmVmcy0+aW5jV2VhayhpZCk7CisgICAgcmV0dXJuIG1SZWZzOworfQorCitSZWZCYXNlOjp3ZWFrcmVmX3R5cGUqIFJlZkJhc2U6OmdldFdlYWtSZWZzKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVJlZnM7Cit9CisKK1JlZkJhc2U6OlJlZkJhc2UoKQorICAgIDogbVJlZnMobmV3IHdlYWtyZWZfaW1wbCh0aGlzKSkKK3sKKy8vICAgIExPR1YoIkNyZWF0aW5nIHJlZnMgJXAgd2l0aCBSZWZCYXNlICVwXG4iLCBtUmVmcywgdGhpcyk7Cit9CisKK1JlZkJhc2U6On5SZWZCYXNlKCkKK3sKKy8vICAgIExPR1YoIkRlc3Ryb3lpbmcgUmVmQmFzZSAlcCAocmVmcyAlcClcbiIsIHRoaXMsIG1SZWZzKTsKKyAgICBpZiAobVJlZnMtPm1XZWFrID09IDApIHsKKy8vICAgICAgICBMT0dWKCJGcmVlaW5nIHJlZnMgJXAgb2Ygb2xkIFJlZkJhc2UgJXBcbiIsIG1SZWZzLCB0aGlzKTsKKyAgICAgICAgZGVsZXRlIG1SZWZzOworICAgIH0KK30KKwordm9pZCBSZWZCYXNlOjpleHRlbmRPYmplY3RMaWZldGltZShpbnQzMl90IG1vZGUpCit7CisgICAgYW5kcm9pZF9hdG9taWNfb3IobW9kZSwgJm1SZWZzLT5tRmxhZ3MpOworfQorCit2b2lkIFJlZkJhc2U6Om9uRmlyc3RSZWYoKQoreworfQorCit2b2lkIFJlZkJhc2U6Om9uTGFzdFN0cm9uZ1JlZihjb25zdCB2b2lkKiAvKmlkKi8pCit7Cit9CisKK2Jvb2wgUmVmQmFzZTo6b25JbmNTdHJvbmdBdHRlbXB0ZWQodWludDMyX3QgZmxhZ3MsIGNvbnN0IHZvaWQqIGlkKQoreworICAgIHJldHVybiAoZmxhZ3MmRklSU1RfSU5DX1NUUk9ORykgPyB0cnVlIDogZmFsc2U7Cit9CisKK3ZvaWQgUmVmQmFzZTo6b25MYXN0V2Vha1JlZihjb25zdCB2b2lkKiAvKmlkKi8pCit7Cit9CisgICAgICAgIAorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvUmVzb3VyY2VUeXBlcy5jcHAgYi9saWJzL3V0aWxzL1Jlc291cmNlVHlwZXMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZTdjZDcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1Jlc291cmNlVHlwZXMuY3BwCkBAIC0wLDAgKzEsMzk4MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiUmVzb3VyY2VUeXBlIgorLy8jZGVmaW5lIExPR19OREVCVUcgMAorCisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8dXRpbHMvQnl0ZU9yZGVyLmg+CisjaW5jbHVkZSA8dXRpbHMvRGVidWcuaD4KKyNpbmNsdWRlIDx1dGlscy9SZXNvdXJjZVR5cGVzLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nMTYuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisjaW5jbHVkZSA8dXRpbHMvVGV4dE91dHB1dC5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8bWVtb3J5Lmg+CisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKworI2lmbmRlZiBJTlQzMl9NQVgKKyNkZWZpbmUgSU5UMzJfTUFYICgoaW50MzJfdCkoMjE0NzQ4MzY0NykpCisjZW5kaWYKKworI2RlZmluZSBQT09MX05PSVNZKHgpIC8veAorI2RlZmluZSBYTUxfTk9JU1koeCkgLy94CisjZGVmaW5lIFRBQkxFX05PSVNZKHgpIC8veAorI2RlZmluZSBUQUJMRV9HRVRFTlRSWSh4KSAvL3gKKyNkZWZpbmUgVEFCTEVfU1VQRVJfTk9JU1koeCkgLy94CisjZGVmaW5lIExPQURfVEFCTEVfTk9JU1koeCkgLy94CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworI2lmZGVmIEhBVkVfV0lOU09DSworI3VuZGVmICBuaHRvbAorI3VuZGVmICBodG9ubAorCisjaWZkZWYgSEFWRV9MSVRUTEVfRU5ESUFOCisjZGVmaW5lIG50b2hsKHgpICAgICggKCh4KSA8PCAyNCkgfCAoKCh4KSA+PiAyNCkgJiAyNTUpIHwgKCgoeCkgPDwgOCkgJiAweGZmMDAwMCkgfCAoKCh4KSA+PiA4KSAmIDB4ZmYwMCkgKQorI2RlZmluZSBodG9ubCh4KSAgICBudG9obCh4KQorI2RlZmluZSBudG9ocyh4KSAgICAoICgoKHgpIDw8IDgpICYgMHhmZjAwKSB8ICgoKHgpID4+IDgpICYgMjU1KSApCisjZGVmaW5lIGh0b25zKHgpICAgIG50b2hzKHgpCisjZWxzZQorI2RlZmluZSBudG9obCh4KSAgICAoeCkKKyNkZWZpbmUgaHRvbmwoeCkgICAgKHgpCisjZGVmaW5lIG50b2hzKHgpICAgICh4KQorI2RlZmluZSBodG9ucyh4KSAgICAoeCkKKyNlbmRpZgorI2VuZGlmCisKK3N0YXRpYyB2b2lkIHByaW50VG9Mb2dGdW5jKHZvaWQqIGNvb2tpZSwgY29uc3QgY2hhciogdHh0KQoreworICAgIExPR1YoIiVzIiwgdHh0KTsKK30KKworLy8gU3RhbmRhcmQgQyBpc3NwYWNlKCkgaXMgb25seSByZXF1aXJlZCB0byBsb29rIGF0IHRoZSBsb3cgYnl0ZSBvZiBpdHMgaW5wdXQsIHNvCisvLyBwcm9kdWNlcyBpbmNvcnJlY3QgcmVzdWx0cyBmb3IgVVRGLTE2IGNoYXJhY3RlcnMuICBGb3Igc2FmZXR5J3Mgc2FrZSwgYXNzdW1lIHRoYXQKKy8vIGFueSBoaWdoLWJ5dGUgVVRGLTE2IGNvZGUgcG9pbnQgaXMgbm90IHdoaXRlc3BhY2UuCitpbmxpbmUgaW50IGlzc3BhY2UxNihjaGFyMTZfdCBjKSB7CisgICAgcmV0dXJuIChjIDwgMHgwMDgwICYmIGlzc3BhY2UoYykpOworfQorCisvLyByYW5nZSBjaGVja2VkOyBndWFyYW50ZWVkIHRvIE5VTC10ZXJtaW5hdGUgd2l0aGluIHRoZSBzdGF0ZWQgbnVtYmVyIG9mIGF2YWlsYWJsZSBzbG90cworLy8gTk9URTogaWYgdGhpcyB0cnVuY2F0ZXMgdGhlIGRzdCBzdHJpbmcgZHVlIHRvIHJ1bm5pbmcgb3V0IG9mIHNwYWNlLCBubyBhdHRlbXB0IGlzCisvLyBtYWRlIHRvIGF2b2lkIHNwbGl0dGluZyBzdXJyb2dhdGUgcGFpcnMuCitzdGF0aWMgdm9pZCBzdHJjcHkxNl9kdG9oKHVpbnQxNl90KiBkc3QsIGNvbnN0IHVpbnQxNl90KiBzcmMsIHNpemVfdCBhdmFpbCkKK3sKKyAgICB1aW50MTZfdCogbGFzdCA9IGRzdCArIGF2YWlsIC0gMTsKKyAgICB3aGlsZSAoKnNyYyAmJiAoZHN0IDwgbGFzdCkpIHsKKyAgICAgICAgY2hhcjE2X3QgcyA9IGR0b2hzKCpzcmMpOworICAgICAgICAqZHN0KysgPSBzOworICAgICAgICBzcmMrKzsKKyAgICB9CisgICAgKmRzdCA9IDA7Cit9CisKK3N0YXRpYyBzdGF0dXNfdCB2YWxpZGF0ZV9jaHVuayhjb25zdCBSZXNDaHVua19oZWFkZXIqIGNodW5rLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBtaW5TaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QqIGRhdGFFbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbmFtZSkKK3sKKyAgICBjb25zdCB1aW50MTZfdCBoZWFkZXJTaXplID0gZHRvaHMoY2h1bmstPmhlYWRlclNpemUpOworICAgIGNvbnN0IHVpbnQzMl90IHNpemUgPSBkdG9obChjaHVuay0+c2l6ZSk7CisKKyAgICBpZiAoaGVhZGVyU2l6ZSA+PSBtaW5TaXplKSB7CisgICAgICAgIGlmIChoZWFkZXJTaXplIDw9IHNpemUpIHsKKyAgICAgICAgICAgIGlmICgoKGhlYWRlclNpemV8c2l6ZSkmMHgzKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKChzc2l6ZV90KXNpemUgPD0gKGRhdGFFbmQtKChjb25zdCB1aW50OF90KiljaHVuaykpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTE9HVygiJXMgZGF0YSBzaXplICVwIGV4dGVuZHMgYmV5b25kIHJlc291cmNlIGVuZCAlcC4iLAorICAgICAgICAgICAgICAgICAgICAgbmFtZSwgKHZvaWQqKXNpemUsCisgICAgICAgICAgICAgICAgICAgICAodm9pZCopKGRhdGFFbmQtKChjb25zdCB1aW50OF90KiljaHVuaykpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gQkFEX1RZUEU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBMT0dXKCIlcyBzaXplIDB4JXggb3IgaGVhZGVyU2l6ZSAweCV4IGlzIG5vdCBvbiBhbiBpbnRlZ2VyIGJvdW5kYXJ5LiIsCisgICAgICAgICAgICAgICAgIG5hbWUsIChpbnQpc2l6ZSwgKGludCloZWFkZXJTaXplKTsKKyAgICAgICAgICAgIHJldHVybiBCQURfVFlQRTsKKyAgICAgICAgfQorICAgICAgICBMT0dXKCIlcyBzaXplICVwIGlzIHNtYWxsZXIgdGhhbiBoZWFkZXIgc2l6ZSAlcC4iLAorICAgICAgICAgICAgIG5hbWUsICh2b2lkKilzaXplLCAodm9pZCopKGludCloZWFkZXJTaXplKTsKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworICAgIH0KKyAgICBMT0dXKCIlcyBoZWFkZXIgc2l6ZSAlcCBpcyB0b28gc21hbGwuIiwKKyAgICAgICAgIG5hbWUsICh2b2lkKikoaW50KWhlYWRlclNpemUpOworICAgIHJldHVybiBCQURfVFlQRTsKK30KKworaW5saW5lIHZvaWQgUmVzX3ZhbHVlOjpjb3B5RnJvbV9kdG9oKGNvbnN0IFJlc192YWx1ZSYgc3JjKQoreworICAgIHNpemUgPSBkdG9ocyhzcmMuc2l6ZSk7CisgICAgcmVzMCA9IHNyYy5yZXMwOworICAgIGRhdGFUeXBlID0gc3JjLmRhdGFUeXBlOworICAgIGRhdGEgPSBkdG9obChzcmMuZGF0YSk7Cit9CisKK3ZvaWQgUmVzX3BuZ185cGF0Y2g6OmRldmljZVRvRmlsZSgpCit7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1YRGl2czsgaSsrKSB7CisgICAgICAgIHhEaXZzW2ldID0gaHRvbmwoeERpdnNbaV0pOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVlEaXZzOyBpKyspIHsKKyAgICAgICAgeURpdnNbaV0gPSBodG9ubCh5RGl2c1tpXSk7CisgICAgfQorICAgIHBhZGRpbmdMZWZ0ID0gaHRvbmwocGFkZGluZ0xlZnQpOworICAgIHBhZGRpbmdSaWdodCA9IGh0b25sKHBhZGRpbmdSaWdodCk7CisgICAgcGFkZGluZ1RvcCA9IGh0b25sKHBhZGRpbmdUb3ApOworICAgIHBhZGRpbmdCb3R0b20gPSBodG9ubChwYWRkaW5nQm90dG9tKTsKKyAgICBmb3IgKGludCBpPTA7IGk8bnVtQ29sb3JzOyBpKyspIHsKKyAgICAgICAgY29sb3JzW2ldID0gaHRvbmwoY29sb3JzW2ldKTsKKyAgICB9Cit9CisKK3ZvaWQgUmVzX3BuZ185cGF0Y2g6OmZpbGVUb0RldmljZSgpCit7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1YRGl2czsgaSsrKSB7CisgICAgICAgIHhEaXZzW2ldID0gbnRvaGwoeERpdnNbaV0pOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVlEaXZzOyBpKyspIHsKKyAgICAgICAgeURpdnNbaV0gPSBudG9obCh5RGl2c1tpXSk7CisgICAgfQorICAgIHBhZGRpbmdMZWZ0ID0gbnRvaGwocGFkZGluZ0xlZnQpOworICAgIHBhZGRpbmdSaWdodCA9IG50b2hsKHBhZGRpbmdSaWdodCk7CisgICAgcGFkZGluZ1RvcCA9IG50b2hsKHBhZGRpbmdUb3ApOworICAgIHBhZGRpbmdCb3R0b20gPSBudG9obChwYWRkaW5nQm90dG9tKTsKKyAgICBmb3IgKGludCBpPTA7IGk8bnVtQ29sb3JzOyBpKyspIHsKKyAgICAgICAgY29sb3JzW2ldID0gbnRvaGwoY29sb3JzW2ldKTsKKyAgICB9Cit9CisKK3NpemVfdCBSZXNfcG5nXzlwYXRjaDo6c2VyaWFsaXplZFNpemUoKQoreworICAgIC8vIFRoZSBzaXplIG9mIHRoaXMgc3RydWN0IGlzIDMyIGJ5dGVzIG9uIHRoZSAzMi1iaXQgdGFyZ2V0IHN5c3RlbQorICAgIC8vIDQgKiBpbnQ4X3QKKyAgICAvLyA0ICogaW50MzJfdAorICAgIC8vIDMgKiBwb2ludGVyCisgICAgcmV0dXJuIDMyCisgICAgICAgICAgICArIG51bVhEaXZzICogc2l6ZW9mKGludDMyX3QpCisgICAgICAgICAgICArIG51bVlEaXZzICogc2l6ZW9mKGludDMyX3QpCisgICAgICAgICAgICArIG51bUNvbG9ycyAqIHNpemVvZih1aW50MzJfdCk7Cit9CisKK3ZvaWQqIFJlc19wbmdfOXBhdGNoOjpzZXJpYWxpemUoKQoreworICAgIHZvaWQqIG5ld0RhdGEgPSBtYWxsb2Moc2VyaWFsaXplZFNpemUoKSk7CisgICAgc2VyaWFsaXplKG5ld0RhdGEpOworICAgIHJldHVybiBuZXdEYXRhOworfQorCit2b2lkIFJlc19wbmdfOXBhdGNoOjpzZXJpYWxpemUodm9pZCAqIG91dERhdGEpCit7CisgICAgY2hhciogZGF0YSA9IChjaGFyKikgb3V0RGF0YTsKKyAgICBtZW1tb3ZlKGRhdGEsICZ3YXNEZXNlcmlhbGl6ZWQsIDQpOyAgICAgLy8gY29weSAgd2FzRGVzZXJpYWxpemVkLCBudW1YRGl2cywgbnVtWURpdnMsIG51bUNvbG9ycworICAgIG1lbW1vdmUoZGF0YSArIDEyLCAmcGFkZGluZ0xlZnQsIDE2KTsgICAvLyBjb3B5IHBhZGRpbmdYWFhYCisgICAgZGF0YSArPSAzMjsKKworICAgIG1lbW1vdmUoZGF0YSwgdGhpcy0+eERpdnMsIG51bVhEaXZzICogc2l6ZW9mKGludDMyX3QpKTsKKyAgICBkYXRhICs9ICBudW1YRGl2cyAqIHNpemVvZihpbnQzMl90KTsKKyAgICBtZW1tb3ZlKGRhdGEsIHRoaXMtPnlEaXZzLCBudW1ZRGl2cyAqIHNpemVvZihpbnQzMl90KSk7CisgICAgZGF0YSArPSAgbnVtWURpdnMgKiBzaXplb2YoaW50MzJfdCk7CisgICAgbWVtbW92ZShkYXRhLCB0aGlzLT5jb2xvcnMsIG51bUNvbG9ycyAqIHNpemVvZih1aW50MzJfdCkpOworfQorCitzdGF0aWMgdm9pZCBkZXNlcmlhbGl6ZUludGVybmFsKGNvbnN0IHZvaWQqIGluRGF0YSwgUmVzX3BuZ185cGF0Y2gqIG91dERhdGEpIHsKKyAgICBjaGFyKiBwYXRjaCA9IChjaGFyKikgaW5EYXRhOworICAgIGlmIChpbkRhdGEgIT0gb3V0RGF0YSkgeworICAgICAgICBtZW1tb3ZlKCZvdXREYXRhLT53YXNEZXNlcmlhbGl6ZWQsIHBhdGNoLCA0KTsgICAgIC8vIGNvcHkgIHdhc0Rlc2VyaWFsaXplZCwgbnVtWERpdnMsIG51bVlEaXZzLCBudW1Db2xvcnMKKyAgICAgICAgbWVtbW92ZSgmb3V0RGF0YS0+cGFkZGluZ0xlZnQsIHBhdGNoICsgMTIsIDQpOyAgICAgLy8gY29weSAgd2FzRGVzZXJpYWxpemVkLCBudW1YRGl2cywgbnVtWURpdnMsIG51bUNvbG9ycworICAgIH0KKyAgICBvdXREYXRhLT53YXNEZXNlcmlhbGl6ZWQgPSB0cnVlOworICAgIGNoYXIqIGRhdGEgPSAoY2hhciopb3V0RGF0YTsKKyAgICBkYXRhICs9ICBzaXplb2YoUmVzX3BuZ185cGF0Y2gpOworICAgIG91dERhdGEtPnhEaXZzID0gKGludDMyX3QqKSBkYXRhOworICAgIGRhdGEgKz0gIG91dERhdGEtPm51bVhEaXZzICogc2l6ZW9mKGludDMyX3QpOworICAgIG91dERhdGEtPnlEaXZzID0gKGludDMyX3QqKSBkYXRhOworICAgIGRhdGEgKz0gIG91dERhdGEtPm51bVlEaXZzICogc2l6ZW9mKGludDMyX3QpOworICAgIG91dERhdGEtPmNvbG9ycyA9ICh1aW50MzJfdCopIGRhdGE7Cit9CisKK1Jlc19wbmdfOXBhdGNoKiBSZXNfcG5nXzlwYXRjaDo6ZGVzZXJpYWxpemUoY29uc3Qgdm9pZCogaW5EYXRhKQoreworICAgIGlmIChzaXplb2Yodm9pZCopICE9IHNpemVvZihpbnQzMl90KSkgeworICAgICAgICBMT0dFKCJDYW5ub3QgZGVzZXJpYWxpemUgb24gbm9uIDMyLWJpdCBzeXN0ZW1cbiIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZGVzZXJpYWxpemVJbnRlcm5hbChpbkRhdGEsIChSZXNfcG5nXzlwYXRjaCopIGluRGF0YSk7CisgICAgcmV0dXJuIChSZXNfcG5nXzlwYXRjaCopIGluRGF0YTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZXNTdHJpbmdQb29sOjpSZXNTdHJpbmdQb29sKCkKKyAgICA6IG1FcnJvcihOT19JTklUKSwgbU93bmVkRGF0YShOVUxMKQoreworfQorCitSZXNTdHJpbmdQb29sOjpSZXNTdHJpbmdQb29sKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCBib29sIGNvcHlEYXRhKQorICAgIDogbUVycm9yKE5PX0lOSVQpLCBtT3duZWREYXRhKE5VTEwpCit7CisgICAgc2V0VG8oZGF0YSwgc2l6ZSwgY29weURhdGEpOworfQorCitSZXNTdHJpbmdQb29sOjp+UmVzU3RyaW5nUG9vbCgpCit7CisgICAgdW5pbml0KCk7Cit9CisKK3N0YXR1c190IFJlc1N0cmluZ1Bvb2w6OnNldFRvKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCBib29sIGNvcHlEYXRhKQoreworICAgIGlmICghZGF0YSB8fCAhc2l6ZSkgeworICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgfQorCisgICAgdW5pbml0KCk7CisKKyAgICBjb25zdCBib29sIG5vdERldmljZUVuZGlhbiA9IGh0b2RzKDB4ZjApICE9IDB4ZjA7CisKKyAgICBpZiAoY29weURhdGEgfHwgbm90RGV2aWNlRW5kaWFuKSB7CisgICAgICAgIG1Pd25lZERhdGEgPSBtYWxsb2Moc2l6ZSk7CisgICAgICAgIGlmIChtT3duZWREYXRhID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiAobUVycm9yPU5PX01FTU9SWSk7CisgICAgICAgIH0KKyAgICAgICAgbWVtY3B5KG1Pd25lZERhdGEsIGRhdGEsIHNpemUpOworICAgICAgICBkYXRhID0gbU93bmVkRGF0YTsKKyAgICB9CisKKyAgICBtSGVhZGVyID0gKGNvbnN0IFJlc1N0cmluZ1Bvb2xfaGVhZGVyKilkYXRhOworCisgICAgaWYgKG5vdERldmljZUVuZGlhbikgeworICAgICAgICBSZXNTdHJpbmdQb29sX2hlYWRlciogaCA9IGNvbnN0X2Nhc3Q8UmVzU3RyaW5nUG9vbF9oZWFkZXIqPihtSGVhZGVyKTsKKyAgICAgICAgaC0+aGVhZGVyLmhlYWRlclNpemUgPSBkdG9ocyhtSGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSk7CisgICAgICAgIGgtPmhlYWRlci50eXBlID0gZHRvaHMobUhlYWRlci0+aGVhZGVyLnR5cGUpOworICAgICAgICBoLT5oZWFkZXIuc2l6ZSA9IGR0b2hsKG1IZWFkZXItPmhlYWRlci5zaXplKTsKKyAgICAgICAgaC0+c3RyaW5nQ291bnQgPSBkdG9obChtSGVhZGVyLT5zdHJpbmdDb3VudCk7CisgICAgICAgIGgtPnN0eWxlQ291bnQgPSBkdG9obChtSGVhZGVyLT5zdHlsZUNvdW50KTsKKyAgICAgICAgaC0+ZmxhZ3MgPSBkdG9obChtSGVhZGVyLT5mbGFncyk7CisgICAgICAgIGgtPnN0cmluZ3NTdGFydCA9IGR0b2hsKG1IZWFkZXItPnN0cmluZ3NTdGFydCk7CisgICAgICAgIGgtPnN0eWxlc1N0YXJ0ID0gZHRvaGwobUhlYWRlci0+c3R5bGVzU3RhcnQpOworICAgIH0KKworICAgIGlmIChtSGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSA+IG1IZWFkZXItPmhlYWRlci5zaXplCisgICAgICAgICAgICB8fCBtSGVhZGVyLT5oZWFkZXIuc2l6ZSA+IHNpemUpIHsKKyAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogaGVhZGVyIHNpemUgJWQgb3IgdG90YWwgc2l6ZSAlZCBpcyBsYXJnZXIgdGhhbiBkYXRhIHNpemUgJWRcbiIsCisgICAgICAgICAgICAgICAgKGludCltSGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSwgKGludCltSGVhZGVyLT5oZWFkZXIuc2l6ZSwgKGludClzaXplKTsKKyAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgIH0KKyAgICBtU2l6ZSA9IG1IZWFkZXItPmhlYWRlci5zaXplOworICAgIG1FbnRyaWVzID0gKGNvbnN0IHVpbnQzMl90KikKKyAgICAgICAgKCgoY29uc3QgdWludDhfdCopZGF0YSkrbUhlYWRlci0+aGVhZGVyLmhlYWRlclNpemUpOworCisgICAgaWYgKG1IZWFkZXItPnN0cmluZ0NvdW50ID4gMCkgeworICAgICAgICBpZiAoKG1IZWFkZXItPnN0cmluZ0NvdW50KnNpemVvZih1aW50MzJfdCkgPCBtSGVhZGVyLT5zdHJpbmdDb3VudCkgIC8vIHVpbnQzMiBvdmVyZmxvdz8KKyAgICAgICAgICAgIHx8IChtSGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSsobUhlYWRlci0+c3RyaW5nQ291bnQqc2l6ZW9mKHVpbnQzMl90KSkpCisgICAgICAgICAgICAgICAgPiBzaXplKSB7CisgICAgICAgICAgICBMT0dXKCJCYWQgc3RyaW5nIGJsb2NrOiBlbnRyeSBvZiAlZCBpdGVtcyBleHRlbmRzIHBhc3QgZGF0YSBzaXplICVkXG4iLAorICAgICAgICAgICAgICAgICAgICAoaW50KShtSGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSsobUhlYWRlci0+c3RyaW5nQ291bnQqc2l6ZW9mKHVpbnQzMl90KSkpLAorICAgICAgICAgICAgICAgICAgICAoaW50KXNpemUpOworICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgICAgICB9CisgICAgICAgIG1TdHJpbmdzID0gKGNvbnN0IGNoYXIxNl90KikKKyAgICAgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKWRhdGEpK21IZWFkZXItPnN0cmluZ3NTdGFydCk7CisgICAgICAgIGlmIChtSGVhZGVyLT5zdHJpbmdzU3RhcnQgPj0gKG1IZWFkZXItPmhlYWRlci5zaXplLXNpemVvZih1aW50MTZfdCkpKSB7CisgICAgICAgICAgICBMT0dXKCJCYWQgc3RyaW5nIGJsb2NrOiBzdHJpbmcgcG9vbCBzdGFydHMgYXQgJWQsIGFmdGVyIHRvdGFsIHNpemUgJWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChpbnQpbUhlYWRlci0+c3RyaW5nc1N0YXJ0LCAoaW50KW1IZWFkZXItPmhlYWRlci5zaXplKTsKKyAgICAgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobUhlYWRlci0+c3R5bGVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICBtU3RyaW5nUG9vbFNpemUgPQorICAgICAgICAgICAgICAgIChtSGVhZGVyLT5oZWFkZXIuc2l6ZS1tSGVhZGVyLT5zdHJpbmdzU3RhcnQpL3NpemVvZih1aW50MTZfdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBjaGVjayBpbnZhcmlhbnQ6IHN0eWxlcyBmb2xsb3cgdGhlIHN0cmluZ3MKKyAgICAgICAgICAgIGlmIChtSGVhZGVyLT5zdHlsZXNTdGFydCA8PSBtSGVhZGVyLT5zdHJpbmdzU3RhcnQpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJCYWQgc3R5bGUgYmxvY2s6IHN0eWxlIGJsb2NrIHN0YXJ0cyBhdCAlZCwgYmVmb3JlIHN0cmluZ3MgYXQgJWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChpbnQpbUhlYWRlci0+c3R5bGVzU3RhcnQsIChpbnQpbUhlYWRlci0+c3RyaW5nc1N0YXJ0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtU3RyaW5nUG9vbFNpemUgPQorICAgICAgICAgICAgICAgIChtSGVhZGVyLT5zdHlsZXNTdGFydC1tSGVhZGVyLT5zdHJpbmdzU3RhcnQpL3NpemVvZih1aW50MTZfdCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjaGVjayBpbnZhcmlhbnQ6IHN0cmluZ0NvdW50ID4gMCByZXF1aXJlcyBhIHN0cmluZyBwb29sIHRvIGV4aXN0CisgICAgICAgIGlmIChtU3RyaW5nUG9vbFNpemUgPT0gMCkgeworICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogc3RyaW5nQ291bnQgaXMgJWQgYnV0IHBvb2wgc2l6ZSBpcyAwXG4iLCAoaW50KW1IZWFkZXItPnN0cmluZ0NvdW50KTsKKyAgICAgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChub3REZXZpY2VFbmRpYW4pIHsKKyAgICAgICAgICAgIHNpemVfdCBpOworICAgICAgICAgICAgdWludDMyX3QqIGUgPSBjb25zdF9jYXN0PHVpbnQzMl90Kj4obUVudHJpZXMpOworICAgICAgICAgICAgZm9yIChpPTA7IGk8bUhlYWRlci0+c3RyaW5nQ291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgIGVbaV0gPSBkdG9obChtRW50cmllc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaGFyMTZfdCogcyA9IGNvbnN0X2Nhc3Q8Y2hhcjE2X3QqPihtU3RyaW5ncyk7CisgICAgICAgICAgICBmb3IgKGk9MDsgaTxtU3RyaW5nUG9vbFNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIHNbaV0gPSBkdG9ocyhtU3RyaW5nc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAobVN0cmluZ3NbbVN0cmluZ1Bvb2xTaXplLTFdICE9IDApIHsKKyAgICAgICAgICAgIExPR1coIkJhZCBzdHJpbmcgYmxvY2s6IGxhc3Qgc3RyaW5nIGlzIG5vdCAwLXRlcm1pbmF0ZWRcbiIpOworICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgbVN0cmluZ3MgPSBOVUxMOworICAgICAgICBtU3RyaW5nUG9vbFNpemUgPSAwOworICAgIH0KKworICAgIGlmIChtSGVhZGVyLT5zdHlsZUNvdW50ID4gMCkgeworICAgICAgICBtRW50cnlTdHlsZXMgPSBtRW50cmllcyArIG1IZWFkZXItPnN0cmluZ0NvdW50OworICAgICAgICAvLyBpbnZhcmlhbnQ6IGludGVnZXIgb3ZlcmZsb3cgaW4gY2FsY3VsYXRpbmcgbUVudHJ5U3R5bGVzCisgICAgICAgIGlmIChtRW50cnlTdHlsZXMgPCBtRW50cmllcykgeworICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogaW50ZWdlciBvdmVyZmxvdyBmaW5kaW5nIHN0eWxlc1xuIik7CisgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKChjb25zdCB1aW50OF90KiltRW50cnlTdHlsZXMtKGNvbnN0IHVpbnQ4X3QqKW1IZWFkZXIpID4gKGludClzaXplKSB7CisgICAgICAgICAgICBMT0dXKCJCYWQgc3RyaW5nIGJsb2NrOiBlbnRyeSBvZiAlZCBzdHlsZXMgZXh0ZW5kcyBwYXN0IGRhdGEgc2l6ZSAlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgKGludCkoKGNvbnN0IHVpbnQ4X3QqKW1FbnRyeVN0eWxlcy0oY29uc3QgdWludDhfdCopbUhlYWRlciksCisgICAgICAgICAgICAgICAgICAgIChpbnQpc2l6ZSk7CisgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgIH0KKyAgICAgICAgbVN0eWxlcyA9IChjb25zdCB1aW50MzJfdCopCisgICAgICAgICAgICAoKChjb25zdCB1aW50OF90KilkYXRhKSttSGVhZGVyLT5zdHlsZXNTdGFydCk7CisgICAgICAgIGlmIChtSGVhZGVyLT5zdHlsZXNTdGFydCA+PSBtSGVhZGVyLT5oZWFkZXIuc2l6ZSkgeworICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogc3R5bGUgcG9vbCBzdGFydHMgJWQsIGFmdGVyIHRvdGFsIHNpemUgJWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChpbnQpbUhlYWRlci0+c3R5bGVzU3RhcnQsIChpbnQpbUhlYWRlci0+aGVhZGVyLnNpemUpOworICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgICAgICB9CisgICAgICAgIG1TdHlsZVBvb2xTaXplID0KKyAgICAgICAgICAgIChtSGVhZGVyLT5oZWFkZXIuc2l6ZS1tSGVhZGVyLT5zdHlsZXNTdGFydCkvc2l6ZW9mKHVpbnQzMl90KTsKKworICAgICAgICBpZiAobm90RGV2aWNlRW5kaWFuKSB7CisgICAgICAgICAgICBzaXplX3QgaTsKKyAgICAgICAgICAgIHVpbnQzMl90KiBlID0gY29uc3RfY2FzdDx1aW50MzJfdCo+KG1FbnRyeVN0eWxlcyk7CisgICAgICAgICAgICBmb3IgKGk9MDsgaTxtSGVhZGVyLT5zdHlsZUNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBlW2ldID0gZHRvaGwobUVudHJ5U3R5bGVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHVpbnQzMl90KiBzID0gY29uc3RfY2FzdDx1aW50MzJfdCo+KG1TdHlsZXMpOworICAgICAgICAgICAgZm9yIChpPTA7IGk8bVN0eWxlUG9vbFNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIHNbaV0gPSBkdG9obChtU3R5bGVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNvbnN0IFJlc1N0cmluZ1Bvb2xfc3BhbiBlbmRTcGFuID0geworICAgICAgICAgICAgeyBodG9kbChSZXNTdHJpbmdQb29sX3NwYW46OkVORCkgfSwKKyAgICAgICAgICAgIGh0b2RsKFJlc1N0cmluZ1Bvb2xfc3Bhbjo6RU5EKSwgaHRvZGwoUmVzU3RyaW5nUG9vbF9zcGFuOjpFTkQpCisgICAgICAgIH07CisgICAgICAgIGlmIChtZW1jbXAoJm1TdHlsZXNbbVN0eWxlUG9vbFNpemUtKHNpemVvZihlbmRTcGFuKS9zaXplb2YodWludDMyX3QpKV0sCisgICAgICAgICAgICAgICAgICAgJmVuZFNwYW4sIHNpemVvZihlbmRTcGFuKSkgIT0gMCkgeworICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogbGFzdCBzdHlsZSBpcyBub3QgMHhGRkZGRkZGRi10ZXJtaW5hdGVkXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIG1FbnRyeVN0eWxlcyA9IE5VTEw7CisgICAgICAgIG1TdHlsZXMgPSBOVUxMOworICAgICAgICBtU3R5bGVQb29sU2l6ZSA9IDA7CisgICAgfQorCisgICAgcmV0dXJuIChtRXJyb3I9Tk9fRVJST1IpOworfQorCitzdGF0dXNfdCBSZXNTdHJpbmdQb29sOjpnZXRFcnJvcigpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1FcnJvcjsKK30KKwordm9pZCBSZXNTdHJpbmdQb29sOjp1bmluaXQoKQoreworICAgIG1FcnJvciA9IE5PX0lOSVQ7CisgICAgaWYgKG1Pd25lZERhdGEpIHsKKyAgICAgICAgZnJlZShtT3duZWREYXRhKTsKKyAgICAgICAgbU93bmVkRGF0YSA9IE5VTEw7CisgICAgfQorfQorCitjb25zdCB1aW50MTZfdCogUmVzU3RyaW5nUG9vbDo6c3RyaW5nQXQoc2l6ZV90IGlkeCwgc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaWYgKG1FcnJvciA9PSBOT19FUlJPUiAmJiBpZHggPCBtSGVhZGVyLT5zdHJpbmdDb3VudCkgeworICAgICAgICBjb25zdCB1aW50MzJfdCBvZmYgPSAobUVudHJpZXNbaWR4XS9zaXplb2YodWludDE2X3QpKTsKKyAgICAgICAgaWYgKG9mZiA8IChtU3RyaW5nUG9vbFNpemUtMSkpIHsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzdHIgPSBtU3RyaW5ncytvZmY7CisgICAgICAgICAgICAqb3V0TGVuID0gKnN0cjsKKyAgICAgICAgICAgIGlmICgoKnN0cikmMHg4MDAwKSB7CisgICAgICAgICAgICAgICAgc3RyKys7CisgICAgICAgICAgICAgICAgKm91dExlbiA9ICgoKCpvdXRMZW4pJjB4N2ZmZik8PDE2KSArICpzdHI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKHVpbnQzMl90KShzdHIrMSsqb3V0TGVuLW1TdHJpbmdzKSA8IG1TdHJpbmdQb29sU2l6ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdHIrMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogc3RyaW5nICMlZCBleHRlbmRzIHRvICVkLCBwYXN0IGVuZCBhdCAlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpaWR4LCAoaW50KShzdHIrMSsqb3V0TGVuLW1TdHJpbmdzKSwgKGludCltU3RyaW5nUG9vbFNpemUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HVygiQmFkIHN0cmluZyBibG9jazogc3RyaW5nICMlZCBlbnRyeSBpcyBhdCAlZCwgcGFzdCBlbmQgYXQgJWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChpbnQpaWR4LCAoaW50KShvZmYqc2l6ZW9mKHVpbnQxNl90KSksCisgICAgICAgICAgICAgICAgICAgIChpbnQpKG1TdHJpbmdQb29sU2l6ZSpzaXplb2YodWludDE2X3QpKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IFJlc1N0cmluZ1Bvb2xfc3BhbiogUmVzU3RyaW5nUG9vbDo6c3R5bGVBdChjb25zdCBSZXNTdHJpbmdQb29sX3JlZiYgcmVmKSBjb25zdAoreworICAgIHJldHVybiBzdHlsZUF0KHJlZi5pbmRleCk7Cit9CisKK2NvbnN0IFJlc1N0cmluZ1Bvb2xfc3BhbiogUmVzU3RyaW5nUG9vbDo6c3R5bGVBdChzaXplX3QgaWR4KSBjb25zdAoreworICAgIGlmIChtRXJyb3IgPT0gTk9fRVJST1IgJiYgaWR4IDwgbUhlYWRlci0+c3R5bGVDb3VudCkgeworICAgICAgICBjb25zdCB1aW50MzJfdCBvZmYgPSAobUVudHJ5U3R5bGVzW2lkeF0vc2l6ZW9mKHVpbnQzMl90KSk7CisgICAgICAgIGlmIChvZmYgPCBtU3R5bGVQb29sU2l6ZSkgeworICAgICAgICAgICAgcmV0dXJuIChjb25zdCBSZXNTdHJpbmdQb29sX3NwYW4qKShtU3R5bGVzK29mZik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dXKCJCYWQgc3RyaW5nIGJsb2NrOiBzdHlsZSAjJWQgZW50cnkgaXMgYXQgJWQsIHBhc3QgZW5kIGF0ICVkXG4iLAorICAgICAgICAgICAgICAgICAgICAoaW50KWlkeCwgKGludCkob2ZmKnNpemVvZih1aW50MzJfdCkpLAorICAgICAgICAgICAgICAgICAgICAoaW50KShtU3R5bGVQb29sU2l6ZSpzaXplb2YodWludDMyX3QpKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3NzaXplX3QgUmVzU3RyaW5nUG9vbDo6aW5kZXhPZlN0cmluZyhjb25zdCBjaGFyMTZfdCogc3RyLCBzaXplX3Qgc3RyTGVuKSBjb25zdAoreworICAgIGlmIChtRXJyb3IgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgcmV0dXJuIG1FcnJvcjsKKyAgICB9CisKKyAgICBzaXplX3QgbGVuOworCisgICAgaWYgKG1IZWFkZXItPmZsYWdzJlJlc1N0cmluZ1Bvb2xfaGVhZGVyOjpTT1JURURfRkxBRykgeworICAgICAgICAvLyBEbyBhIGJpbmFyeSBzZWFyY2ggZm9yIHRoZSBzdHJpbmcuLi4KKyAgICAgICAgc3NpemVfdCBsID0gMDsKKyAgICAgICAgc3NpemVfdCBoID0gbUhlYWRlci0+c3RyaW5nQ291bnQtMTsKKworICAgICAgICBzc2l6ZV90IG1pZDsKKyAgICAgICAgd2hpbGUgKGwgPD0gaCkgeworICAgICAgICAgICAgbWlkID0gbCArIChoIC0gbCkvMjsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzID0gc3RyaW5nQXQobWlkLCAmbGVuKTsKKyAgICAgICAgICAgIGludCBjID0gcyA/IHN0cnpjbXAxNihzLCBsZW4sIHN0ciwgc3RyTGVuKSA6IC0xOworICAgICAgICAgICAgUE9PTF9OT0lTWShwcmludGYoIkxvb2tpbmcgZm9yICVzLCBhdCAlcywgY21wPSVkLCBsL21pZC9oPSVkLyVkLyVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgoc3RyKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHMpLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGMsIChpbnQpbCwgKGludCltaWQsIChpbnQpaCkpOworICAgICAgICAgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPCAwKSB7CisgICAgICAgICAgICAgICAgbCA9IG1pZCArIDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGggPSBtaWQgLSAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gSXQgaXMgdW51c3VhbCB0byBnZXQgdGhlIElEIGZyb20gYW4gdW5zb3J0ZWQgc3RyaW5nIGJsb2NrLi4uCisgICAgICAgIC8vIG1vc3Qgb2Z0ZW4gdGhpcyBoYXBwZW5zIGJlY2F1c2Ugd2Ugd2FudCB0byBnZXQgSURzIGZvciBzdHlsZQorICAgICAgICAvLyBzcGFuIHRhZ3M7IHNpbmNlIHRob3NlIGFsd2F5cyBhcHBlYXIgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nCisgICAgICAgIC8vIGJsb2NrLCBzdGFydCBzZWFyY2hpbmcgYXQgdGhlIGJhY2suCisgICAgICAgIGZvciAoaW50IGk9bUhlYWRlci0+c3RyaW5nQ291bnQtMTsgaT49MDsgaS0tKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyMTZfdCogcyA9IHN0cmluZ0F0KGksICZsZW4pOworICAgICAgICAgICAgUE9PTF9OT0lTWShwcmludGYoIkxvb2tpbmcgZm9yICVzLCBhdCAlcywgaT0lZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHN0ciwgc3RyTGVuKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHMpLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGkpKTsKKyAgICAgICAgICAgIGlmIChzICYmIHN0cnpjbXAxNihzLCBsZW4sIHN0ciwgc3RyTGVuKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7Cit9CisKK3NpemVfdCBSZXNTdHJpbmdQb29sOjpzaXplKCkgY29uc3QKK3sKKyAgICByZXR1cm4gKG1FcnJvciA9PSBOT19FUlJPUikgPyBtSGVhZGVyLT5zdHJpbmdDb3VudCA6IDA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworUmVzWE1MUGFyc2VyOjpSZXNYTUxQYXJzZXIoY29uc3QgUmVzWE1MVHJlZSYgdHJlZSkKKyAgICA6IG1UcmVlKHRyZWUpLCBtRXZlbnRDb2RlKEJBRF9ET0NVTUVOVCkKK3sKK30KKwordm9pZCBSZXNYTUxQYXJzZXI6OnJlc3RhcnQoKQoreworICAgIG1DdXJOb2RlID0gTlVMTDsKKyAgICBtRXZlbnRDb2RlID0gbVRyZWUubUVycm9yID09IE5PX0VSUk9SID8gU1RBUlRfRE9DVU1FTlQgOiBCQURfRE9DVU1FTlQ7Cit9CisKK1Jlc1hNTFBhcnNlcjo6ZXZlbnRfY29kZV90IFJlc1hNTFBhcnNlcjo6Z2V0RXZlbnRUeXBlKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUV2ZW50Q29kZTsKK30KKworUmVzWE1MUGFyc2VyOjpldmVudF9jb2RlX3QgUmVzWE1MUGFyc2VyOjpuZXh0KCkKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9ET0NVTUVOVCkgeworICAgICAgICBtQ3VyTm9kZSA9IG1UcmVlLm1Sb290Tm9kZTsKKyAgICAgICAgbUN1ckV4dCA9IG1UcmVlLm1Sb290RXh0OworICAgICAgICByZXR1cm4gKG1FdmVudENvZGU9bVRyZWUubVJvb3RDb2RlKTsKKyAgICB9IGVsc2UgaWYgKG1FdmVudENvZGUgPj0gRklSU1RfQ0hVTktfQ09ERSkgeworICAgICAgICByZXR1cm4gbmV4dE5vZGUoKTsKKyAgICB9CisgICAgcmV0dXJuIG1FdmVudENvZGU7Cit9CisKK2NvbnN0IGludDMyX3QgUmVzWE1MUGFyc2VyOjpnZXRDb21tZW50SUQoKSBjb25zdAoreworICAgIHJldHVybiBtQ3VyTm9kZSAhPSBOVUxMID8gZHRvaGwobUN1ck5vZGUtPmNvbW1lbnQuaW5kZXgpIDogLTE7Cit9CisKK2NvbnN0IHVpbnQxNl90KiBSZXNYTUxQYXJzZXI6OmdldENvbW1lbnQoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldENvbW1lbnRJRCgpOworICAgIHJldHVybiBpZCA+PSAwID8gbVRyZWUubVN0cmluZ3Muc3RyaW5nQXQoaWQsIG91dExlbikgOiBOVUxMOworfQorCitjb25zdCB1aW50MzJfdCBSZXNYTUxQYXJzZXI6OmdldExpbmVOdW1iZXIoKSBjb25zdAoreworICAgIHJldHVybiBtQ3VyTm9kZSAhPSBOVUxMID8gZHRvaGwobUN1ck5vZGUtPmxpbmVOdW1iZXIpIDogLTE7Cit9CisKK2NvbnN0IGludDMyX3QgUmVzWE1MUGFyc2VyOjpnZXRUZXh0SUQoKSBjb25zdAoreworICAgIGlmIChtRXZlbnRDb2RlID09IFRFWFQpIHsKKyAgICAgICAgcmV0dXJuIGR0b2hsKCgoY29uc3QgUmVzWE1MVHJlZV9jZGF0YUV4dCopbUN1ckV4dCktPmRhdGEuaW5kZXgpOworICAgIH0KKyAgICByZXR1cm4gLTE7Cit9CisKK2NvbnN0IHVpbnQxNl90KiBSZXNYTUxQYXJzZXI6OmdldFRleHQoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldFRleHRJRCgpOworICAgIHJldHVybiBpZCA+PSAwID8gbVRyZWUubVN0cmluZ3Muc3RyaW5nQXQoaWQsIG91dExlbikgOiBOVUxMOworfQorCitzc2l6ZV90IFJlc1hNTFBhcnNlcjo6Z2V0VGV4dFZhbHVlKFJlc192YWx1ZSogb3V0VmFsdWUpIGNvbnN0Cit7CisgICAgaWYgKG1FdmVudENvZGUgPT0gVEVYVCkgeworICAgICAgICBvdXRWYWx1ZS0+Y29weUZyb21fZHRvaCgoKGNvbnN0IFJlc1hNTFRyZWVfY2RhdGFFeHQqKW1DdXJFeHQpLT50eXBlZERhdGEpOworICAgICAgICByZXR1cm4gc2l6ZW9mKFJlc192YWx1ZSk7CisgICAgfQorICAgIHJldHVybiBCQURfVFlQRTsKK30KKworY29uc3QgaW50MzJfdCBSZXNYTUxQYXJzZXI6OmdldE5hbWVzcGFjZVByZWZpeElEKCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9OQU1FU1BBQ0UgfHwgbUV2ZW50Q29kZSA9PSBFTkRfTkFNRVNQQUNFKSB7CisgICAgICAgIHJldHVybiBkdG9obCgoKGNvbnN0IFJlc1hNTFRyZWVfbmFtZXNwYWNlRXh0KiltQ3VyRXh0KS0+cHJlZml4LmluZGV4KTsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCitjb25zdCB1aW50MTZfdCogUmVzWE1MUGFyc2VyOjpnZXROYW1lc3BhY2VQcmVmaXgoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldE5hbWVzcGFjZVByZWZpeElEKCk7CisgICAgLy9wcmludGYoInByZWZpeD0lZCAgZXZlbnQ9JXBcbiIsIGlkLCBtRXZlbnRDb2RlKTsKKyAgICByZXR1cm4gaWQgPj0gMCA/IG1UcmVlLm1TdHJpbmdzLnN0cmluZ0F0KGlkLCBvdXRMZW4pIDogTlVMTDsKK30KKworY29uc3QgaW50MzJfdCBSZXNYTUxQYXJzZXI6OmdldE5hbWVzcGFjZVVyaUlEKCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9OQU1FU1BBQ0UgfHwgbUV2ZW50Q29kZSA9PSBFTkRfTkFNRVNQQUNFKSB7CisgICAgICAgIHJldHVybiBkdG9obCgoKGNvbnN0IFJlc1hNTFRyZWVfbmFtZXNwYWNlRXh0KiltQ3VyRXh0KS0+dXJpLmluZGV4KTsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCitjb25zdCB1aW50MTZfdCogUmVzWE1MUGFyc2VyOjpnZXROYW1lc3BhY2VVcmkoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldE5hbWVzcGFjZVVyaUlEKCk7CisgICAgLy9wcmludGYoInVyaT0lZCAgZXZlbnQ9JXBcbiIsIGlkLCBtRXZlbnRDb2RlKTsKKyAgICByZXR1cm4gaWQgPj0gMCA/IG1UcmVlLm1TdHJpbmdzLnN0cmluZ0F0KGlkLCBvdXRMZW4pIDogTlVMTDsKK30KKworY29uc3QgaW50MzJfdCBSZXNYTUxQYXJzZXI6OmdldEVsZW1lbnROYW1lc3BhY2VJRCgpIGNvbnN0Cit7CisgICAgaWYgKG1FdmVudENvZGUgPT0gU1RBUlRfVEFHKSB7CisgICAgICAgIHJldHVybiBkdG9obCgoKGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCopbUN1ckV4dCktPm5zLmluZGV4KTsKKyAgICB9CisgICAgaWYgKG1FdmVudENvZGUgPT0gRU5EX1RBRykgeworICAgICAgICByZXR1cm4gZHRvaGwoKChjb25zdCBSZXNYTUxUcmVlX2VuZEVsZW1lbnRFeHQqKW1DdXJFeHQpLT5ucy5pbmRleCk7CisgICAgfQorICAgIHJldHVybiAtMTsKK30KKworY29uc3QgdWludDE2X3QqIFJlc1hNTFBhcnNlcjo6Z2V0RWxlbWVudE5hbWVzcGFjZShzaXplX3QqIG91dExlbikgY29uc3QKK3sKKyAgICBpbnQzMl90IGlkID0gZ2V0RWxlbWVudE5hbWVzcGFjZUlEKCk7CisgICAgcmV0dXJuIGlkID49IDAgPyBtVHJlZS5tU3RyaW5ncy5zdHJpbmdBdChpZCwgb3V0TGVuKSA6IE5VTEw7Cit9CisKK2NvbnN0IGludDMyX3QgUmVzWE1MUGFyc2VyOjpnZXRFbGVtZW50TmFtZUlEKCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgcmV0dXJuIGR0b2hsKCgoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0KS0+bmFtZS5pbmRleCk7CisgICAgfQorICAgIGlmIChtRXZlbnRDb2RlID09IEVORF9UQUcpIHsKKyAgICAgICAgcmV0dXJuIGR0b2hsKCgoY29uc3QgUmVzWE1MVHJlZV9lbmRFbGVtZW50RXh0KiltQ3VyRXh0KS0+bmFtZS5pbmRleCk7CisgICAgfQorICAgIHJldHVybiAtMTsKK30KKworY29uc3QgdWludDE2X3QqIFJlc1hNTFBhcnNlcjo6Z2V0RWxlbWVudE5hbWUoc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldEVsZW1lbnROYW1lSUQoKTsKKyAgICByZXR1cm4gaWQgPj0gMCA/IG1UcmVlLm1TdHJpbmdzLnN0cmluZ0F0KGlkLCBvdXRMZW4pIDogTlVMTDsKK30KKworc2l6ZV90IFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlQ291bnQoKSBjb25zdAoreworICAgIGlmIChtRXZlbnRDb2RlID09IFNUQVJUX1RBRykgeworICAgICAgICByZXR1cm4gZHRvaHMoKChjb25zdCBSZXNYTUxUcmVlX2F0dHJFeHQqKW1DdXJFeHQpLT5hdHRyaWJ1dGVDb3VudCk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitjb25zdCBpbnQzMl90IFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlTmFtZXNwYWNlSUQoc2l6ZV90IGlkeCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiB0YWcgPSAoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0OworICAgICAgICBpZiAoaWR4IDwgZHRvaHModGFnLT5hdHRyaWJ1dGVDb3VudCkpIHsKKyAgICAgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKiBhdHRyID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKikKKyAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90Kil0YWcpCisgICAgICAgICAgICAgICAgICsgZHRvaHModGFnLT5hdHRyaWJ1dGVTdGFydCkKKyAgICAgICAgICAgICAgICAgKyAoZHRvaHModGFnLT5hdHRyaWJ1dGVTaXplKSppZHgpKTsKKyAgICAgICAgICAgIHJldHVybiBkdG9obChhdHRyLT5ucy5pbmRleCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIC0yOworfQorCitjb25zdCB1aW50MTZfdCogUmVzWE1MUGFyc2VyOjpnZXRBdHRyaWJ1dGVOYW1lc3BhY2Uoc2l6ZV90IGlkeCwgc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldEF0dHJpYnV0ZU5hbWVzcGFjZUlEKGlkeCk7CisgICAgLy9wcmludGYoImF0dHJpYnV0ZSBuYW1lc3BhY2U9JWQgIGlkeD0lZCAgZXZlbnQ9JXBcbiIsIGlkLCBpZHgsIG1FdmVudENvZGUpOworICAgIC8vWE1MX05PSVNZKHByaW50ZigiZ2V0QXR0cmlidXRlTmFtZXNwYWNlIDB4JXg9MHgleFxuIiwgaWR4LCBpZCkpOworICAgIHJldHVybiBpZCA+PSAwID8gbVRyZWUubVN0cmluZ3Muc3RyaW5nQXQoaWQsIG91dExlbikgOiBOVUxMOworfQorCitjb25zdCBpbnQzMl90IFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlTmFtZUlEKHNpemVfdCBpZHgpIGNvbnN0Cit7CisgICAgaWYgKG1FdmVudENvZGUgPT0gU1RBUlRfVEFHKSB7CisgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCogdGFnID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCopbUN1ckV4dDsKKyAgICAgICAgaWYgKGlkeCA8IGR0b2hzKHRhZy0+YXR0cmlidXRlQ291bnQpKSB7CisgICAgICAgICAgICBjb25zdCBSZXNYTUxUcmVlX2F0dHJpYnV0ZSogYXR0ciA9IChjb25zdCBSZXNYTUxUcmVlX2F0dHJpYnV0ZSopCisgICAgICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopdGFnKQorICAgICAgICAgICAgICAgICArIGR0b2hzKHRhZy0+YXR0cmlidXRlU3RhcnQpCisgICAgICAgICAgICAgICAgICsgKGR0b2hzKHRhZy0+YXR0cmlidXRlU2l6ZSkqaWR4KSk7CisgICAgICAgICAgICByZXR1cm4gZHRvaGwoYXR0ci0+bmFtZS5pbmRleCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCitjb25zdCB1aW50MTZfdCogUmVzWE1MUGFyc2VyOjpnZXRBdHRyaWJ1dGVOYW1lKHNpemVfdCBpZHgsIHNpemVfdCogb3V0TGVuKSBjb25zdAoreworICAgIGludDMyX3QgaWQgPSBnZXRBdHRyaWJ1dGVOYW1lSUQoaWR4KTsKKyAgICAvL3ByaW50ZigiYXR0cmlidXRlIG5hbWU9JWQgIGlkeD0lZCAgZXZlbnQ9JXBcbiIsIGlkLCBpZHgsIG1FdmVudENvZGUpOworICAgIC8vWE1MX05PSVNZKHByaW50ZigiZ2V0QXR0cmlidXRlTmFtZSAweCV4PTB4JXhcbiIsIGlkeCwgaWQpKTsKKyAgICByZXR1cm4gaWQgPj0gMCA/IG1UcmVlLm1TdHJpbmdzLnN0cmluZ0F0KGlkLCBvdXRMZW4pIDogTlVMTDsKK30KKworY29uc3QgdWludDMyX3QgUmVzWE1MUGFyc2VyOjpnZXRBdHRyaWJ1dGVOYW1lUmVzSUQoc2l6ZV90IGlkeCkgY29uc3QKK3sKKyAgICBpbnQzMl90IGlkID0gZ2V0QXR0cmlidXRlTmFtZUlEKGlkeCk7CisgICAgaWYgKGlkID49IDAgJiYgKHNpemVfdClpZCA8IG1UcmVlLm1OdW1SZXNJZHMpIHsKKyAgICAgICAgcmV0dXJuIGR0b2hsKG1UcmVlLm1SZXNJZHNbaWRdKTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK2NvbnN0IGludDMyX3QgUmVzWE1MUGFyc2VyOjpnZXRBdHRyaWJ1dGVWYWx1ZVN0cmluZ0lEKHNpemVfdCBpZHgpIGNvbnN0Cit7CisgICAgaWYgKG1FdmVudENvZGUgPT0gU1RBUlRfVEFHKSB7CisgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCogdGFnID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCopbUN1ckV4dDsKKyAgICAgICAgaWYgKGlkeCA8IGR0b2hzKHRhZy0+YXR0cmlidXRlQ291bnQpKSB7CisgICAgICAgICAgICBjb25zdCBSZXNYTUxUcmVlX2F0dHJpYnV0ZSogYXR0ciA9IChjb25zdCBSZXNYTUxUcmVlX2F0dHJpYnV0ZSopCisgICAgICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopdGFnKQorICAgICAgICAgICAgICAgICArIGR0b2hzKHRhZy0+YXR0cmlidXRlU3RhcnQpCisgICAgICAgICAgICAgICAgICsgKGR0b2hzKHRhZy0+YXR0cmlidXRlU2l6ZSkqaWR4KSk7CisgICAgICAgICAgICByZXR1cm4gZHRvaGwoYXR0ci0+cmF3VmFsdWUuaW5kZXgpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAtMTsKK30KKworY29uc3QgdWludDE2X3QqIFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlU3RyaW5nVmFsdWUoc2l6ZV90IGlkeCwgc2l6ZV90KiBvdXRMZW4pIGNvbnN0Cit7CisgICAgaW50MzJfdCBpZCA9IGdldEF0dHJpYnV0ZVZhbHVlU3RyaW5nSUQoaWR4KTsKKyAgICAvL1hNTF9OT0lTWShwcmludGYoImdldEF0dHJpYnV0ZVZhbHVlIDB4JXg9MHgleFxuIiwgaWR4LCBpZCkpOworICAgIHJldHVybiBpZCA+PSAwID8gbVRyZWUubVN0cmluZ3Muc3RyaW5nQXQoaWQsIG91dExlbikgOiBOVUxMOworfQorCitpbnQzMl90IFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlRGF0YVR5cGUoc2l6ZV90IGlkeCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiB0YWcgPSAoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0OworICAgICAgICBpZiAoaWR4IDwgZHRvaHModGFnLT5hdHRyaWJ1dGVDb3VudCkpIHsKKyAgICAgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKiBhdHRyID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKikKKyAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90Kil0YWcpCisgICAgICAgICAgICAgICAgICsgZHRvaHModGFnLT5hdHRyaWJ1dGVTdGFydCkKKyAgICAgICAgICAgICAgICAgKyAoZHRvaHModGFnLT5hdHRyaWJ1dGVTaXplKSppZHgpKTsKKyAgICAgICAgICAgIHJldHVybiBhdHRyLT50eXBlZFZhbHVlLmRhdGFUeXBlOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBSZXNfdmFsdWU6OlRZUEVfTlVMTDsKK30KKworaW50MzJfdCBSZXNYTUxQYXJzZXI6OmdldEF0dHJpYnV0ZURhdGEoc2l6ZV90IGlkeCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiB0YWcgPSAoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0OworICAgICAgICBpZiAoaWR4IDwgZHRvaHModGFnLT5hdHRyaWJ1dGVDb3VudCkpIHsKKyAgICAgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKiBhdHRyID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKikKKyAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90Kil0YWcpCisgICAgICAgICAgICAgICAgICsgZHRvaHModGFnLT5hdHRyaWJ1dGVTdGFydCkKKyAgICAgICAgICAgICAgICAgKyAoZHRvaHModGFnLT5hdHRyaWJ1dGVTaXplKSppZHgpKTsKKyAgICAgICAgICAgIHJldHVybiBkdG9obChhdHRyLT50eXBlZFZhbHVlLmRhdGEpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzc2l6ZV90IFJlc1hNTFBhcnNlcjo6Z2V0QXR0cmlidXRlVmFsdWUoc2l6ZV90IGlkeCwgUmVzX3ZhbHVlKiBvdXRWYWx1ZSkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiB0YWcgPSAoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0OworICAgICAgICBpZiAoaWR4IDwgZHRvaHModGFnLT5hdHRyaWJ1dGVDb3VudCkpIHsKKyAgICAgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKiBhdHRyID0gKGNvbnN0IFJlc1hNTFRyZWVfYXR0cmlidXRlKikKKyAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90Kil0YWcpCisgICAgICAgICAgICAgICAgICsgZHRvaHModGFnLT5hdHRyaWJ1dGVTdGFydCkKKyAgICAgICAgICAgICAgICAgKyAoZHRvaHModGFnLT5hdHRyaWJ1dGVTaXplKSppZHgpKTsKKyAgICAgICAgICAgIG91dFZhbHVlLT5jb3B5RnJvbV9kdG9oKGF0dHItPnR5cGVkVmFsdWUpOworICAgICAgICAgICAgcmV0dXJuIHNpemVvZihSZXNfdmFsdWUpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBCQURfVFlQRTsKK30KKworc3NpemVfdCBSZXNYTUxQYXJzZXI6OmluZGV4T2ZBdHRyaWJ1dGUoY29uc3QgY2hhciogbnMsIGNvbnN0IGNoYXIqIGF0dHIpIGNvbnN0Cit7CisgICAgU3RyaW5nMTYgbnNTdHIobnMgIT0gTlVMTCA/IG5zIDogIiIpOworICAgIFN0cmluZzE2IGF0dHJTdHIoYXR0cik7CisgICAgcmV0dXJuIGluZGV4T2ZBdHRyaWJ1dGUobnMgPyBuc1N0ci5zdHJpbmcoKSA6IE5VTEwsIG5zID8gbnNTdHIuc2l6ZSgpIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyU3RyLnN0cmluZygpLCBhdHRyU3RyLnNpemUoKSk7Cit9CisKK3NzaXplX3QgUmVzWE1MUGFyc2VyOjppbmRleE9mQXR0cmlidXRlKGNvbnN0IGNoYXIxNl90KiBucywgc2l6ZV90IG5zTGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIGF0dHIsIHNpemVfdCBhdHRyTGVuKSBjb25zdAoreworICAgIGlmIChtRXZlbnRDb2RlID09IFNUQVJUX1RBRykgeworICAgICAgICBjb25zdCBzaXplX3QgTiA9IGdldEF0dHJpYnV0ZUNvdW50KCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgICAgIHNpemVfdCBjdXJOc0xlbiwgY3VyQXR0ckxlbjsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBjdXJOcyA9IGdldEF0dHJpYnV0ZU5hbWVzcGFjZShpLCAmY3VyTnNMZW4pOworICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIGN1ckF0dHIgPSBnZXRBdHRyaWJ1dGVOYW1lKGksICZjdXJBdHRyTGVuKTsKKyAgICAgICAgICAgIC8vcHJpbnRmKCIlZDogbnM9JXAgYXR0cj0lcCBjdXJOcz0lcCBjdXJBdHRyPSVwXG4iLAorICAgICAgICAgICAgLy8gICAgICAgaSwgbnMsIGF0dHIsIGN1ck5zLCBjdXJBdHRyKTsKKyAgICAgICAgICAgIC8vcHJpbnRmKCIgLS0+IGF0dHI9JXMsIGN1ckF0dHI9JXNcbiIsCisgICAgICAgICAgICAvLyAgICAgICBTdHJpbmc4KGF0dHIpLnN0cmluZygpLCBTdHJpbmc4KGN1ckF0dHIpLnN0cmluZygpKTsKKyAgICAgICAgICAgIGlmIChhdHRyICYmIGN1ckF0dHIgJiYgKHN0cnpjbXAxNihhdHRyLCBhdHRyTGVuLCBjdXJBdHRyLCBjdXJBdHRyTGVuKSA9PSAwKSkgeworICAgICAgICAgICAgICAgIGlmIChucyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJOcyA9PSBOVUxMKSByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ck5zICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy9wcmludGYoIiAtLT4gbnM9JXMsIGN1ck5zPSVzXG4iLAorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBTdHJpbmc4KG5zKS5zdHJpbmcoKSwgU3RyaW5nOChjdXJOcykuc3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAoc3RyemNtcDE2KG5zLCBuc0xlbiwgY3VyTnMsIGN1ck5zTGVuKSA9PSAwKSByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7Cit9CisKK3NzaXplX3QgUmVzWE1MUGFyc2VyOjppbmRleE9mSUQoKSBjb25zdAoreworICAgIGlmIChtRXZlbnRDb2RlID09IFNUQVJUX1RBRykgeworICAgICAgICBjb25zdCBzc2l6ZV90IGlkeCA9IGR0b2hzKCgoY29uc3QgUmVzWE1MVHJlZV9hdHRyRXh0KiltQ3VyRXh0KS0+aWRJbmRleCk7CisgICAgICAgIGlmIChpZHggPiAwKSByZXR1cm4gKGlkeC0xKTsKKyAgICB9CisgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworfQorCitzc2l6ZV90IFJlc1hNTFBhcnNlcjo6aW5kZXhPZkNsYXNzKCkgY29uc3QKK3sKKyAgICBpZiAobUV2ZW50Q29kZSA9PSBTVEFSVF9UQUcpIHsKKyAgICAgICAgY29uc3Qgc3NpemVfdCBpZHggPSBkdG9ocygoKGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCopbUN1ckV4dCktPmNsYXNzSW5kZXgpOworICAgICAgICBpZiAoaWR4ID4gMCkgcmV0dXJuIChpZHgtMSk7CisgICAgfQorICAgIHJldHVybiBOQU1FX05PVF9GT1VORDsKK30KKworc3NpemVfdCBSZXNYTUxQYXJzZXI6OmluZGV4T2ZTdHlsZSgpIGNvbnN0Cit7CisgICAgaWYgKG1FdmVudENvZGUgPT0gU1RBUlRfVEFHKSB7CisgICAgICAgIGNvbnN0IHNzaXplX3QgaWR4ID0gZHRvaHMoKChjb25zdCBSZXNYTUxUcmVlX2F0dHJFeHQqKW1DdXJFeHQpLT5zdHlsZUluZGV4KTsKKyAgICAgICAgaWYgKGlkeCA+IDApIHJldHVybiAoaWR4LTEpOworICAgIH0KKyAgICByZXR1cm4gTkFNRV9OT1RfRk9VTkQ7Cit9CisKK1Jlc1hNTFBhcnNlcjo6ZXZlbnRfY29kZV90IFJlc1hNTFBhcnNlcjo6bmV4dE5vZGUoKQoreworICAgIGlmIChtRXZlbnRDb2RlIDwgMCkgeworICAgICAgICByZXR1cm4gbUV2ZW50Q29kZTsKKyAgICB9CisKKyAgICBkbyB7CisgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfbm9kZSogbmV4dCA9IChjb25zdCBSZXNYTUxUcmVlX25vZGUqKQorICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopbUN1ck5vZGUpICsgZHRvaGwobUN1ck5vZGUtPmhlYWRlci5zaXplKSk7CisgICAgICAgIC8vTE9HVygiTmV4dCBub2RlOiBwcmV2PSVwLCBuZXh0PSVwXG4iLCBtQ3VyTm9kZSwgbmV4dCk7CisgICAgICAgIAorICAgICAgICBpZiAoKChjb25zdCB1aW50OF90KiluZXh0KSA+PSBtVHJlZS5tRGF0YUVuZCkgeworICAgICAgICAgICAgbUN1ck5vZGUgPSBOVUxMOworICAgICAgICAgICAgcmV0dXJuIChtRXZlbnRDb2RlPUVORF9ET0NVTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobVRyZWUudmFsaWRhdGVOb2RlKG5leHQpICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICBtQ3VyTm9kZSA9IE5VTEw7CisgICAgICAgICAgICByZXR1cm4gKG1FdmVudENvZGU9QkFEX0RPQ1VNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIG1DdXJOb2RlID0gbmV4dDsKKyAgICAgICAgY29uc3QgdWludDE2X3QgaGVhZGVyU2l6ZSA9IGR0b2hzKG5leHQtPmhlYWRlci5oZWFkZXJTaXplKTsKKyAgICAgICAgY29uc3QgdWludDMyX3QgdG90YWxTaXplID0gZHRvaGwobmV4dC0+aGVhZGVyLnNpemUpOworICAgICAgICBtQ3VyRXh0ID0gKChjb25zdCB1aW50OF90KiluZXh0KSArIGhlYWRlclNpemU7CisgICAgICAgIHNpemVfdCBtaW5FeHRTaXplID0gMDsKKyAgICAgICAgZXZlbnRfY29kZV90IGV2ZW50Q29kZSA9IChldmVudF9jb2RlX3QpZHRvaHMobmV4dC0+aGVhZGVyLnR5cGUpOworICAgICAgICBzd2l0Y2ggKChtRXZlbnRDb2RlPWV2ZW50Q29kZSkpIHsKKyAgICAgICAgICAgIGNhc2UgUkVTX1hNTF9TVEFSVF9OQU1FU1BBQ0VfVFlQRToKKyAgICAgICAgICAgIGNhc2UgUkVTX1hNTF9FTkRfTkFNRVNQQUNFX1RZUEU6CisgICAgICAgICAgICAgICAgbWluRXh0U2l6ZSA9IHNpemVvZihSZXNYTUxUcmVlX25hbWVzcGFjZUV4dCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFJFU19YTUxfU1RBUlRfRUxFTUVOVF9UWVBFOgorICAgICAgICAgICAgICAgIG1pbkV4dFNpemUgPSBzaXplb2YoUmVzWE1MVHJlZV9hdHRyRXh0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUkVTX1hNTF9FTkRfRUxFTUVOVF9UWVBFOgorICAgICAgICAgICAgICAgIG1pbkV4dFNpemUgPSBzaXplb2YoUmVzWE1MVHJlZV9lbmRFbGVtZW50RXh0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUkVTX1hNTF9DREFUQV9UWVBFOgorICAgICAgICAgICAgICAgIG1pbkV4dFNpemUgPSBzaXplb2YoUmVzWE1MVHJlZV9jZGF0YUV4dCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIExPR1coIlVua25vd24gWE1MIGJsb2NrOiBoZWFkZXIgdHlwZSAlZCBpbiBub2RlIGF0ICVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgKGludClkdG9ocyhuZXh0LT5oZWFkZXIudHlwZSksCisgICAgICAgICAgICAgICAgICAgICAoaW50KSgoKGNvbnN0IHVpbnQ4X3QqKW5leHQpLSgoY29uc3QgdWludDhfdCopbVRyZWUubUhlYWRlcikpKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaWYgKCh0b3RhbFNpemUtaGVhZGVyU2l6ZSkgPCBtaW5FeHRTaXplKSB7CisgICAgICAgICAgICBMT0dXKCJCYWQgWE1MIGJsb2NrOiBoZWFkZXIgdHlwZSAweCV4IGluIG5vZGUgYXQgMHgleCBoYXMgc2l6ZSAlZCwgbmVlZCAlZFxuIiwKKyAgICAgICAgICAgICAgICAgKGludClkdG9ocyhuZXh0LT5oZWFkZXIudHlwZSksCisgICAgICAgICAgICAgICAgIChpbnQpKCgoY29uc3QgdWludDhfdCopbmV4dCktKChjb25zdCB1aW50OF90KiltVHJlZS5tSGVhZGVyKSksCisgICAgICAgICAgICAgICAgIChpbnQpKHRvdGFsU2l6ZS1oZWFkZXJTaXplKSwgKGludCltaW5FeHRTaXplKTsKKyAgICAgICAgICAgIHJldHVybiAobUV2ZW50Q29kZT1CQURfRE9DVU1FTlQpOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvL3ByaW50ZigiQ3VyTm9kZT0lcCwgQ3VyRXh0PSVwLCBoZWFkZXJTaXplPSVkLCBtaW5FeHRTaXplPSVkXG4iLAorICAgICAgICAvLyAgICAgICBtQ3VyTm9kZSwgbUN1ckV4dCwgaGVhZGVyU2l6ZSwgbWluRXh0U2l6ZSk7CisgICAgICAgIAorICAgICAgICByZXR1cm4gZXZlbnRDb2RlOworICAgIH0gd2hpbGUgKHRydWUpOworfQorCit2b2lkIFJlc1hNTFBhcnNlcjo6Z2V0UG9zaXRpb24oUmVzWE1MUGFyc2VyOjpSZXNYTUxQb3NpdGlvbiogcG9zKSBjb25zdAoreworICAgIHBvcy0+ZXZlbnRDb2RlID0gbUV2ZW50Q29kZTsKKyAgICBwb3MtPmN1ck5vZGUgPSBtQ3VyTm9kZTsKKyAgICBwb3MtPmN1ckV4dCA9IG1DdXJFeHQ7Cit9CisKK3ZvaWQgUmVzWE1MUGFyc2VyOjpzZXRQb3NpdGlvbihjb25zdCBSZXNYTUxQYXJzZXI6OlJlc1hNTFBvc2l0aW9uJiBwb3MpCit7CisgICAgbUV2ZW50Q29kZSA9IHBvcy5ldmVudENvZGU7CisgICAgbUN1ck5vZGUgPSBwb3MuY3VyTm9kZTsKKyAgICBtQ3VyRXh0ID0gcG9zLmN1ckV4dDsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9sYXRpbGUgaW50MzJfdCBnQ291bnQgPSAwOworCitSZXNYTUxUcmVlOjpSZXNYTUxUcmVlKCkKKyAgICA6IFJlc1hNTFBhcnNlcigqdGhpcykKKyAgICAsIG1FcnJvcihOT19JTklUKSwgbU93bmVkRGF0YShOVUxMKQoreworICAgIC8vTE9HSSgiQ3JlYXRpbmcgUmVzWE1MVHJlZSAlcCAjJWRcbiIsIHRoaXMsIGFuZHJvaWRfYXRvbWljX2luYygmZ0NvdW50KSsxKTsKKyAgICByZXN0YXJ0KCk7Cit9CisKK1Jlc1hNTFRyZWU6OlJlc1hNTFRyZWUoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIGJvb2wgY29weURhdGEpCisgICAgOiBSZXNYTUxQYXJzZXIoKnRoaXMpCisgICAgLCBtRXJyb3IoTk9fSU5JVCksIG1Pd25lZERhdGEoTlVMTCkKK3sKKyAgICAvL0xPR0koIkNyZWF0aW5nIFJlc1hNTFRyZWUgJXAgIyVkXG4iLCB0aGlzLCBhbmRyb2lkX2F0b21pY19pbmMoJmdDb3VudCkrMSk7CisgICAgc2V0VG8oZGF0YSwgc2l6ZSwgY29weURhdGEpOworfQorCitSZXNYTUxUcmVlOjp+UmVzWE1MVHJlZSgpCit7CisgICAgLy9MT0dJKCJEZXN0cm95aW5nIFJlc1hNTFRyZWUgaW4gJXAgIyVkXG4iLCB0aGlzLCBhbmRyb2lkX2F0b21pY19kZWMoJmdDb3VudCktMSk7CisgICAgdW5pbml0KCk7Cit9CisKK3N0YXR1c190IFJlc1hNTFRyZWU6OnNldFRvKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBzaXplLCBib29sIGNvcHlEYXRhKQoreworICAgIHVuaW5pdCgpOworICAgIG1FdmVudENvZGUgPSBTVEFSVF9ET0NVTUVOVDsKKworICAgIGlmIChjb3B5RGF0YSkgeworICAgICAgICBtT3duZWREYXRhID0gbWFsbG9jKHNpemUpOworICAgICAgICBpZiAobU93bmVkRGF0YSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1OT19NRU1PUlkpOworICAgICAgICB9CisgICAgICAgIG1lbWNweShtT3duZWREYXRhLCBkYXRhLCBzaXplKTsKKyAgICAgICAgZGF0YSA9IG1Pd25lZERhdGE7CisgICAgfQorCisgICAgbUhlYWRlciA9IChjb25zdCBSZXNYTUxUcmVlX2hlYWRlciopZGF0YTsKKyAgICBtU2l6ZSA9IGR0b2hsKG1IZWFkZXItPmhlYWRlci5zaXplKTsKKyAgICBpZiAoZHRvaHMobUhlYWRlci0+aGVhZGVyLmhlYWRlclNpemUpID4gbVNpemUgfHwgbVNpemUgPiBzaXplKSB7CisgICAgICAgIExPR1coIkJhZCBYTUwgYmxvY2s6IGhlYWRlciBzaXplICVkIG9yIHRvdGFsIHNpemUgJWQgaXMgbGFyZ2VyIHRoYW4gZGF0YSBzaXplICVkXG4iLAorICAgICAgICAgICAgIChpbnQpZHRvaHMobUhlYWRlci0+aGVhZGVyLmhlYWRlclNpemUpLAorICAgICAgICAgICAgIChpbnQpZHRvaGwobUhlYWRlci0+aGVhZGVyLnNpemUpLCAoaW50KXNpemUpOworICAgICAgICBtRXJyb3IgPSBCQURfVFlQRTsKKyAgICAgICAgcmVzdGFydCgpOworICAgICAgICByZXR1cm4gbUVycm9yOworICAgIH0KKyAgICBtRGF0YUVuZCA9ICgoY29uc3QgdWludDhfdCopbUhlYWRlcikgKyBtU2l6ZTsKKworICAgIG1TdHJpbmdzLnVuaW5pdCgpOworICAgIG1Sb290Tm9kZSA9IE5VTEw7CisgICAgbVJlc0lkcyA9IE5VTEw7CisgICAgbU51bVJlc0lkcyA9IDA7CisKKyAgICAvLyBGaXJzdCBsb29rIGZvciBhIGNvdXBsZSBpbnRlcmVzdGluZyBjaHVua3M6IHRoZSBzdHJpbmcgYmxvY2sKKyAgICAvLyBhbmQgZmlyc3QgWE1MIG5vZGUuCisgICAgY29uc3QgUmVzQ2h1bmtfaGVhZGVyKiBjaHVuayA9CisgICAgICAgIChjb25zdCBSZXNDaHVua19oZWFkZXIqKSgoKGNvbnN0IHVpbnQ4X3QqKW1IZWFkZXIpICsgZHRvaHMobUhlYWRlci0+aGVhZGVyLmhlYWRlclNpemUpKTsKKyAgICBjb25zdCBSZXNDaHVua19oZWFkZXIqIGxhc3RDaHVuayA9IGNodW5rOworICAgIHdoaWxlICgoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSA8IChtRGF0YUVuZC1zaXplb2YoUmVzQ2h1bmtfaGVhZGVyKSkgJiYKKyAgICAgICAgICAgKChjb25zdCB1aW50OF90KiljaHVuaykgPCAobURhdGFFbmQtZHRvaGwoY2h1bmstPnNpemUpKSkgeworICAgICAgICBzdGF0dXNfdCBlcnIgPSB2YWxpZGF0ZV9jaHVuayhjaHVuaywgc2l6ZW9mKFJlc0NodW5rX2hlYWRlciksIG1EYXRhRW5kLCAiWE1MIik7CisgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgIG1FcnJvciA9IGVycjsKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgfQorICAgICAgICBjb25zdCB1aW50MTZfdCB0eXBlID0gZHRvaHMoY2h1bmstPnR5cGUpOworICAgICAgICBjb25zdCBzaXplX3Qgc2l6ZSA9IGR0b2hsKGNodW5rLT5zaXplKTsKKyAgICAgICAgWE1MX05PSVNZKHByaW50ZigiU2Nhbm5pbmcgQCAlcDogdHlwZT0weCV4LCBzaXplPTB4JXhcbiIsCisgICAgICAgICAgICAgICAgICAgICAodm9pZCopKCgodWludDMyX3QpY2h1bmspLSgodWludDMyX3QpbUhlYWRlcikpLCB0eXBlLCBzaXplKSk7CisgICAgICAgIGlmICh0eXBlID09IFJFU19TVFJJTkdfUE9PTF9UWVBFKSB7CisgICAgICAgICAgICBtU3RyaW5ncy5zZXRUbyhjaHVuaywgc2l6ZSk7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBSRVNfWE1MX1JFU09VUkNFX01BUF9UWVBFKSB7CisgICAgICAgICAgICBtUmVzSWRzID0gKGNvbnN0IHVpbnQzMl90KikKKyAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90KiljaHVuaykrZHRvaHMoY2h1bmstPmhlYWRlclNpemUpKTsKKyAgICAgICAgICAgIG1OdW1SZXNJZHMgPSAoZHRvaGwoY2h1bmstPnNpemUpLWR0b2hzKGNodW5rLT5oZWFkZXJTaXplKSkvc2l6ZW9mKHVpbnQzMl90KTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID49IFJFU19YTUxfRklSU1RfQ0hVTktfVFlQRQorICAgICAgICAgICAgICAgICAgICYmIHR5cGUgPD0gUkVTX1hNTF9MQVNUX0NIVU5LX1RZUEUpIHsKKyAgICAgICAgICAgIGlmICh2YWxpZGF0ZU5vZGUoKGNvbnN0IFJlc1hNTFRyZWVfbm9kZSopY2h1bmspICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgbUVycm9yID0gQkFEX1RZUEU7CisgICAgICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbUN1ck5vZGUgPSAoY29uc3QgUmVzWE1MVHJlZV9ub2RlKilsYXN0Q2h1bms7CisgICAgICAgICAgICBpZiAobmV4dE5vZGUoKSA9PSBCQURfRE9DVU1FTlQpIHsKKyAgICAgICAgICAgICAgICBtRXJyb3IgPSBCQURfVFlQRTsKKyAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtUm9vdE5vZGUgPSBtQ3VyTm9kZTsKKyAgICAgICAgICAgIG1Sb290RXh0ID0gbUN1ckV4dDsKKyAgICAgICAgICAgIG1Sb290Q29kZSA9IG1FdmVudENvZGU7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFhNTF9OT0lTWShwcmludGYoIlNraXBwaW5nIHVua25vd24gY2h1bmshXG4iKSk7CisgICAgICAgIH0KKyAgICAgICAgbGFzdENodW5rID0gY2h1bms7CisgICAgICAgIGNodW5rID0gKGNvbnN0IFJlc0NodW5rX2hlYWRlciopCisgICAgICAgICAgICAoKChjb25zdCB1aW50OF90KiljaHVuaykgKyBzaXplKTsKKyAgICB9CisKKyAgICBpZiAobVJvb3ROb2RlID09IE5VTEwpIHsKKyAgICAgICAgTE9HVygiQmFkIFhNTCBibG9jazogbm8gcm9vdCBlbGVtZW50IG5vZGUgZm91bmRcbiIpOworICAgICAgICBtRXJyb3IgPSBCQURfVFlQRTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIG1FcnJvciA9IG1TdHJpbmdzLmdldEVycm9yKCk7CisKK2RvbmU6CisgICAgcmVzdGFydCgpOworICAgIHJldHVybiBtRXJyb3I7Cit9CisKK3N0YXR1c190IFJlc1hNTFRyZWU6OmdldEVycm9yKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbUVycm9yOworfQorCit2b2lkIFJlc1hNTFRyZWU6OnVuaW5pdCgpCit7CisgICAgbUVycm9yID0gTk9fSU5JVDsKKyAgICBpZiAobU93bmVkRGF0YSkgeworICAgICAgICBmcmVlKG1Pd25lZERhdGEpOworICAgICAgICBtT3duZWREYXRhID0gTlVMTDsKKyAgICB9CisgICAgcmVzdGFydCgpOworfQorCitjb25zdCBSZXNTdHJpbmdQb29sJiBSZXNYTUxUcmVlOjpnZXRTdHJpbmdzKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbVN0cmluZ3M7Cit9CisKK3N0YXR1c190IFJlc1hNTFRyZWU6OnZhbGlkYXRlTm9kZShjb25zdCBSZXNYTUxUcmVlX25vZGUqIG5vZGUpIGNvbnN0Cit7CisgICAgY29uc3QgdWludDE2X3QgZXZlbnRDb2RlID0gZHRvaHMobm9kZS0+aGVhZGVyLnR5cGUpOworCisgICAgc3RhdHVzX3QgZXJyID0gdmFsaWRhdGVfY2h1bmsoCisgICAgICAgICZub2RlLT5oZWFkZXIsIHNpemVvZihSZXNYTUxUcmVlX25vZGUpLAorICAgICAgICBtRGF0YUVuZCwgIlJlc1hNTFRyZWVfbm9kZSIpOworCisgICAgaWYgKGVyciA+PSBOT19FUlJPUikgeworICAgICAgICAvLyBPbmx5IHBlcmZvcm0gYWRkaXRpb25hbCB2YWxpZGF0aW9uIG9uIFNUQVJUIG5vZGVzCisgICAgICAgIGlmIChldmVudENvZGUgIT0gUkVTX1hNTF9TVEFSVF9FTEVNRU5UX1RZUEUpIHsKKyAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgfQorCisgICAgICAgIGNvbnN0IHVpbnQxNl90IGhlYWRlclNpemUgPSBkdG9ocyhub2RlLT5oZWFkZXIuaGVhZGVyU2l6ZSk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IHNpemUgPSBkdG9obChub2RlLT5oZWFkZXIuc2l6ZSk7CisgICAgICAgIGNvbnN0IFJlc1hNTFRyZWVfYXR0ckV4dCogYXR0ckV4dCA9IChjb25zdCBSZXNYTUxUcmVlX2F0dHJFeHQqKQorICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopbm9kZSkgKyBoZWFkZXJTaXplKTsKKyAgICAgICAgLy8gY2hlY2sgZm9yIHNlbnNpY2FsIHZhbHVlcyBwdWxsZWQgb3V0IG9mIHRoZSBzdHJlYW0gc28gZmFyLi4uCisgICAgICAgIGlmICgoc2l6ZSA+PSBoZWFkZXJTaXplICsgc2l6ZW9mKFJlc1hNTFRyZWVfYXR0ckV4dCkpCisgICAgICAgICAgICAgICAgJiYgKCh2b2lkKilhdHRyRXh0ID4gKHZvaWQqKW5vZGUpKSB7CisgICAgICAgICAgICBjb25zdCBzaXplX3QgYXR0clNpemUgPSAoKHNpemVfdClkdG9ocyhhdHRyRXh0LT5hdHRyaWJ1dGVTaXplKSkKKyAgICAgICAgICAgICAgICAqIGR0b2hzKGF0dHJFeHQtPmF0dHJpYnV0ZUNvdW50KTsKKyAgICAgICAgICAgIGlmICgoZHRvaHMoYXR0ckV4dC0+YXR0cmlidXRlU3RhcnQpK2F0dHJTaXplKSA8PSAoc2l6ZS1oZWFkZXJTaXplKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExPR1coIkJhZCBYTUwgYmxvY2s6IG5vZGUgYXR0cmlidXRlcyB1c2UgMHgleCBieXRlcywgb25seSBoYXZlIDB4JXggYnl0ZXNcbiIsCisgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpKGR0b2hzKGF0dHJFeHQtPmF0dHJpYnV0ZVN0YXJ0KSthdHRyU2l6ZSksCisgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpKHNpemUtaGVhZGVyU2l6ZSkpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgTE9HVygiQmFkIFhNTCBzdGFydCBibG9jazogbm9kZSBoZWFkZXIgc2l6ZSAweCV4LCBzaXplIDB4JXhcbiIsCisgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGludCloZWFkZXJTaXplLCAodW5zaWduZWQgaW50KXNpemUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBCQURfVFlQRTsKKyAgICB9CisKKyAgICByZXR1cm4gZXJyOworCisjaWYgMAorICAgIGNvbnN0IGJvb2wgaXNTdGFydCA9IGR0b2hzKG5vZGUtPmhlYWRlci50eXBlKSA9PSBSRVNfWE1MX1NUQVJUX0VMRU1FTlRfVFlQRTsKKworICAgIGNvbnN0IHVpbnQxNl90IGhlYWRlclNpemUgPSBkdG9ocyhub2RlLT5oZWFkZXIuaGVhZGVyU2l6ZSk7CisgICAgY29uc3QgdWludDMyX3Qgc2l6ZSA9IGR0b2hsKG5vZGUtPmhlYWRlci5zaXplKTsKKworICAgIGlmIChoZWFkZXJTaXplID49IChpc1N0YXJ0ID8gc2l6ZW9mKFJlc1hNTFRyZWVfYXR0ck5vZGUpIDogc2l6ZW9mKFJlc1hNTFRyZWVfbm9kZSkpKSB7CisgICAgICAgIGlmIChzaXplID49IGhlYWRlclNpemUpIHsKKyAgICAgICAgICAgIGlmICgoKGNvbnN0IHVpbnQ4X3QqKW5vZGUpIDw9IChtRGF0YUVuZC1zaXplKSkgeworICAgICAgICAgICAgICAgIGlmICghaXNTdGFydCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICgoKChzaXplX3QpZHRvaHMobm9kZS0+YXR0cmlidXRlU2l6ZSkpKmR0b2hzKG5vZGUtPmF0dHJpYnV0ZUNvdW50KSkKKyAgICAgICAgICAgICAgICAgICAgICAgIDw9IChzaXplLWhlYWRlclNpemUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTE9HVygiQmFkIFhNTCBibG9jazogbm9kZSBhdHRyaWJ1dGVzIHVzZSAweCV4IGJ5dGVzLCBvbmx5IGhhdmUgMHgleCBieXRlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICgoaW50KWR0b2hzKG5vZGUtPmF0dHJpYnV0ZVNpemUpKSpkdG9ocyhub2RlLT5hdHRyaWJ1dGVDb3VudCksCisgICAgICAgICAgICAgICAgICAgICAgICAoaW50KShzaXplLWhlYWRlclNpemUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gQkFEX1RZUEU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBMT0dXKCJCYWQgWE1MIGJsb2NrOiBub2RlIGF0IDB4JXggZXh0ZW5kcyBiZXlvbmQgZGF0YSBlbmQgMHgleFxuIiwKKyAgICAgICAgICAgICAgICAgICAgKGludCkoKChjb25zdCB1aW50OF90Kilub2RlKS0oKGNvbnN0IHVpbnQ4X3QqKW1IZWFkZXIpKSwgKGludCltU2l6ZSk7CisgICAgICAgICAgICByZXR1cm4gQkFEX1RZUEU7CisgICAgICAgIH0KKyAgICAgICAgTE9HVygiQmFkIFhNTCBibG9jazogbm9kZSBhdCAweCV4IGhlYWRlciBzaXplIDB4JXggc21hbGxlciB0aGFuIHRvdGFsIHNpemUgMHgleFxuIiwKKyAgICAgICAgICAgICAgICAoaW50KSgoKGNvbnN0IHVpbnQ4X3QqKW5vZGUpLSgoY29uc3QgdWludDhfdCopbUhlYWRlcikpLAorICAgICAgICAgICAgICAgIChpbnQpaGVhZGVyU2l6ZSwgKGludClzaXplKTsKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworICAgIH0KKyAgICBMT0dXKCJCYWQgWE1MIGJsb2NrOiBub2RlIGF0IDB4JXggaGVhZGVyIHNpemUgMHgleCB0b28gc21hbGxcbiIsCisgICAgICAgICAgICAoaW50KSgoKGNvbnN0IHVpbnQ4X3QqKW5vZGUpLSgoY29uc3QgdWludDhfdCopbUhlYWRlcikpLAorICAgICAgICAgICAgKGludCloZWFkZXJTaXplKTsKKyAgICByZXR1cm4gQkFEX1RZUEU7CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgUmVzVGFibGU6OkhlYWRlcgoreworICAgIEhlYWRlcigpIDogb3duZWREYXRhKE5VTEwpLCBoZWFkZXIoTlVMTCkgeyB9CisKKyAgICB2b2lkKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG93bmVkRGF0YTsKKyAgICBjb25zdCBSZXNUYWJsZV9oZWFkZXIqICAgICAgICAgIGhlYWRlcjsKKyAgICBzaXplX3QgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU7CisgICAgY29uc3QgdWludDhfdCogICAgICAgICAgICAgICAgICBkYXRhRW5kOworICAgIHNpemVfdCAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg7CisgICAgdm9pZCogICAgICAgICAgICAgICAgICAgICAgICAgICBjb29raWU7CisKKyAgICBSZXNTdHJpbmdQb29sICAgICAgICAgICAgICAgICAgIHZhbHVlczsKK307CisKK3N0cnVjdCBSZXNUYWJsZTo6VHlwZQoreworICAgIFR5cGUoY29uc3QgSGVhZGVyKiBfaGVhZGVyLCBjb25zdCBQYWNrYWdlKiBfcGFja2FnZSwgc2l6ZV90IGNvdW50KQorICAgICAgICA6IGhlYWRlcihfaGVhZGVyKSwgcGFja2FnZShfcGFja2FnZSksIGVudHJ5Q291bnQoY291bnQpLAorICAgICAgICAgIHR5cGVTcGVjKE5VTEwpLCB0eXBlU3BlY0ZsYWdzKE5VTEwpIHsgfQorICAgIGNvbnN0IEhlYWRlciogY29uc3QgICAgICAgICAgICAgaGVhZGVyOworICAgIGNvbnN0IFBhY2thZ2UqIGNvbnN0ICAgICAgICAgICAgcGFja2FnZTsKKyAgICBjb25zdCBzaXplX3QgICAgICAgICAgICAgICAgICAgIGVudHJ5Q291bnQ7CisgICAgY29uc3QgUmVzVGFibGVfdHlwZVNwZWMqICAgICAgICB0eXBlU3BlYzsKKyAgICBjb25zdCB1aW50MzJfdCogICAgICAgICAgICAgICAgIHR5cGVTcGVjRmxhZ3M7CisgICAgVmVjdG9yPGNvbnN0IFJlc1RhYmxlX3R5cGUqPiAgICBjb25maWdzOworfTsKKworc3RydWN0IFJlc1RhYmxlOjpQYWNrYWdlCit7CisgICAgUGFja2FnZShjb25zdCBIZWFkZXIqIF9oZWFkZXIsIGNvbnN0IFJlc1RhYmxlX3BhY2thZ2UqIF9wYWNrYWdlKQorICAgICAgICA6IGhlYWRlcihfaGVhZGVyKSwgcGFja2FnZShfcGFja2FnZSkgeyB9CisgICAgflBhY2thZ2UoKQorICAgIHsKKyAgICAgICAgc2l6ZV90IGkgPSB0eXBlcy5zaXplKCk7CisgICAgICAgIHdoaWxlIChpID4gMCkgeworICAgICAgICAgICAgaS0tOworICAgICAgICAgICAgZGVsZXRlIHR5cGVzW2ldOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIGNvbnN0IEhlYWRlciogY29uc3QgICAgICAgICAgICAgaGVhZGVyOworICAgIGNvbnN0IFJlc1RhYmxlX3BhY2thZ2UqIGNvbnN0ICAgcGFja2FnZTsKKyAgICBWZWN0b3I8VHlwZSo+ICAgICAgICAgICAgICAgICAgIHR5cGVzOworCisgICAgY29uc3QgVHlwZSogZ2V0VHlwZShzaXplX3QgaWR4KSBjb25zdCB7CisgICAgICAgIHJldHVybiBpZHggPCB0eXBlcy5zaXplKCkgPyB0eXBlc1tpZHhdIDogTlVMTDsKKyAgICB9Cit9OworCisvLyBBIGdyb3VwIG9mIG9iamVjdHMgZGVzY3JpYmluZyBhIHBhcnRpY3VsYXIgcmVzb3VyY2UgcGFja2FnZS4KKy8vIFRoZSBmaXJzdCBpbiAncGFja2FnZScgaXMgYWx3YXlzIHRoZSByb290IG9iamVjdCAoZnJvbSB0aGUgcmVzb3VyY2UKKy8vIHRhYmxlIHRoYXQgZGVmaW5lZCB0aGUgcGFja2FnZSk7IHRoZSBvbmVzIGFmdGVyIGFyZSBza2lucyBvbiB0b3Agb2YgaXQuCitzdHJ1Y3QgUmVzVGFibGU6OlBhY2thZ2VHcm91cAoreworICAgIFBhY2thZ2VHcm91cChjb25zdCBTdHJpbmcxNiYgX25hbWUsIHVpbnQzMl90IF9pZCkKKyAgICAgICAgOiBuYW1lKF9uYW1lKSwgaWQoX2lkKSwgdHlwZUNvdW50KDApLCBiYWdzKE5VTEwpIHsgfQorICAgIH5QYWNrYWdlR3JvdXAoKSB7CisgICAgICAgIGNsZWFyQmFnQ2FjaGUoKTsKKyAgICAgICAgY29uc3Qgc2l6ZV90IE4gPSBwYWNrYWdlcy5zaXplKCk7CisgICAgICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgICAgIGRlbGV0ZSBwYWNrYWdlc1tpXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgY2xlYXJCYWdDYWNoZSgpIHsKKyAgICAgICAgaWYgKGJhZ3MpIHsKKyAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiYmFncz0lcFxuIiwgYmFncykpOworICAgICAgICAgICAgUGFja2FnZSogcGtnID0gcGFja2FnZXNbMF07CisgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoInR5cGVDb3VudD0leFxuIiwgdHlwZUNvdW50KSk7CisgICAgICAgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8dHlwZUNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoInR5cGU9JWRcbiIsIGkpKTsKKyAgICAgICAgICAgICAgICBjb25zdCBUeXBlKiB0eXBlID0gcGtnLT5nZXRUeXBlKGkpOworICAgICAgICAgICAgICAgIGlmICh0eXBlICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgYmFnX3NldCoqIHR5cGVCYWdzID0gYmFnc1tpXTsKKyAgICAgICAgICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJ0eXBlQmFncz0lcFxuIiwgdHlwZUJhZ3MpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVCYWdzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoInR5cGUtPmVudHJ5Q291bnQ9JXhcbiIsIHR5cGUtPmVudHJ5Q291bnQpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCBOID0gdHlwZS0+ZW50cnlDb3VudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IGo9MDsgajxOOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZUJhZ3Nbal0gJiYgdHlwZUJhZ3Nbal0gIT0gKGJhZ19zZXQqKTB4RkZGRkZGRkYpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWUodHlwZUJhZ3Nbal0pOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZnJlZSh0eXBlQmFncyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmcmVlKGJhZ3MpOworICAgICAgICAgICAgYmFncyA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgU3RyaW5nMTYgY29uc3QgICAgICAgICAgICAgICAgICBuYW1lOworICAgIHVpbnQzMl90IGNvbnN0ICAgICAgICAgICAgICAgICAgaWQ7CisgICAgVmVjdG9yPFBhY2thZ2UqPiAgICAgICAgICAgICAgICBwYWNrYWdlczsKKworICAgIC8vIFRha2VuIGZyb20gdGhlIHJvb3QgcGFja2FnZS4KKyAgICBSZXNTdHJpbmdQb29sICAgICAgICAgICAgICAgICAgIHR5cGVTdHJpbmdzOworICAgIFJlc1N0cmluZ1Bvb2wgICAgICAgICAgICAgICAgICAga2V5U3RyaW5nczsKKyAgICBzaXplX3QgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVDb3VudDsKKworICAgIC8vIENvbXB1dGVkIGF0dHJpYnV0ZSBiYWdzLCBmaXJzdCBpbmRleGVkIGJ5IHRoZSB0eXBlIGFuZCBzZWNvbmQKKyAgICAvLyBieSB0aGUgZW50cnkgaW4gdGhhdCB0eXBlLgorICAgIGJhZ19zZXQqKiogICAgICAgICAgICAgICAgICAgICAgYmFnczsKK307CisKK3N0cnVjdCBSZXNUYWJsZTo6YmFnX3NldAoreworICAgIHNpemVfdCBudW1BdHRyczsgICAgLy8gbnVtYmVyIGluIGFycmF5CisgICAgc2l6ZV90IGF2YWlsQXR0cnM7ICAvLyB0b3RhbCBzcGFjZSBpbiBhcnJheQorICAgIHVpbnQzMl90IHR5cGVTcGVjRmxhZ3M7CisgICAgLy8gRm9sbG93ZWQgYnkgJ251bUF0dHInIGJhZ19lbnRyeSBzdHJ1Y3R1cmVzLgorfTsKKworUmVzVGFibGU6OlRoZW1lOjpUaGVtZShjb25zdCBSZXNUYWJsZSYgdGFibGUpCisgICAgOiBtVGFibGUodGFibGUpCit7CisgICAgbWVtc2V0KG1QYWNrYWdlcywgMCwgc2l6ZW9mKG1QYWNrYWdlcykpOworfQorCitSZXNUYWJsZTo6VGhlbWU6On5UaGVtZSgpCit7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPFJlc19NQVhQQUNLQUdFOyBpKyspIHsKKyAgICAgICAgcGFja2FnZV9pbmZvKiBwaSA9IG1QYWNrYWdlc1tpXTsKKyAgICAgICAgaWYgKHBpICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGZyZWVfcGFja2FnZShwaSk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgUmVzVGFibGU6OlRoZW1lOjpmcmVlX3BhY2thZ2UocGFja2FnZV9pbmZvKiBwaSkKK3sKKyAgICBmb3IgKHNpemVfdCBqPTA7IGo8cGktPm51bVR5cGVzOyBqKyspIHsKKyAgICAgICAgdGhlbWVfZW50cnkqIHRlID0gcGktPnR5cGVzW2pdLmVudHJpZXM7CisgICAgICAgIGlmICh0ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICBmcmVlKHRlKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBmcmVlKHBpKTsKK30KKworUmVzVGFibGU6OlRoZW1lOjpwYWNrYWdlX2luZm8qIFJlc1RhYmxlOjpUaGVtZTo6Y29weV9wYWNrYWdlKHBhY2thZ2VfaW5mbyogcGkpCit7CisgICAgcGFja2FnZV9pbmZvKiBuZXdwaSA9IChwYWNrYWdlX2luZm8qKW1hbGxvYygKKyAgICAgICAgc2l6ZW9mKHBhY2thZ2VfaW5mbykgKyAocGktPm51bVR5cGVzKnNpemVvZih0eXBlX2luZm8pKSk7CisgICAgbmV3cGktPm51bVR5cGVzID0gcGktPm51bVR5cGVzOworICAgIGZvciAoc2l6ZV90IGo9MDsgajxuZXdwaS0+bnVtVHlwZXM7IGorKykgeworICAgICAgICBzaXplX3QgY250ID0gcGktPnR5cGVzW2pdLm51bUVudHJpZXM7CisgICAgICAgIG5ld3BpLT50eXBlc1tqXS5udW1FbnRyaWVzID0gY250OworICAgICAgICB0aGVtZV9lbnRyeSogdGUgPSBwaS0+dHlwZXNbal0uZW50cmllczsKKyAgICAgICAgaWYgKHRlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHRoZW1lX2VudHJ5KiBuZXd0ZSA9ICh0aGVtZV9lbnRyeSopbWFsbG9jKGNudCpzaXplb2YodGhlbWVfZW50cnkpKTsKKyAgICAgICAgICAgIG5ld3BpLT50eXBlc1tqXS5lbnRyaWVzID0gbmV3dGU7CisgICAgICAgICAgICBtZW1jcHkobmV3dGUsIHRlLCBjbnQqc2l6ZW9mKHRoZW1lX2VudHJ5KSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuZXdwaS0+dHlwZXNbal0uZW50cmllcyA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG5ld3BpOworfQorCitzdGF0dXNfdCBSZXNUYWJsZTo6VGhlbWU6OmFwcGx5U3R5bGUodWludDMyX3QgcmVzSUQsIGJvb2wgZm9yY2UpCit7CisgICAgY29uc3QgYmFnX2VudHJ5KiBiYWc7CisgICAgdWludDMyX3QgYmFnVHlwZVNwZWNGbGFncyA9IDA7CisgICAgbVRhYmxlLmxvY2soKTsKKyAgICBjb25zdCBzc2l6ZV90IE4gPSBtVGFibGUuZ2V0QmFnTG9ja2VkKHJlc0lELCAmYmFnLCAmYmFnVHlwZVNwZWNGbGFncyk7CisgICAgVEFCTEVfTk9JU1koTE9HVigiQXBwbHlpbmcgc3R5bGUgMHglMDh4IHRvIHRoZW1lICVwLCBjb3VudD0lZCIsIHJlc0lELCB0aGlzLCBOKSk7CisgICAgaWYgKE4gPCAwKSB7CisgICAgICAgIG1UYWJsZS51bmxvY2soKTsKKyAgICAgICAgcmV0dXJuIE47CisgICAgfQorCisgICAgdWludDMyX3QgY3VyUGFja2FnZSA9IDB4ZmZmZmZmZmY7CisgICAgc3NpemVfdCBjdXJQYWNrYWdlSW5kZXggPSAwOworICAgIHBhY2thZ2VfaW5mbyogY3VyUEkgPSBOVUxMOworICAgIHVpbnQzMl90IGN1clR5cGUgPSAweGZmZmZmZmZmOworICAgIHNpemVfdCBudW1FbnRyaWVzID0gMDsKKyAgICB0aGVtZV9lbnRyeSogY3VyRW50cmllcyA9IE5VTEw7CisKKyAgICBjb25zdCBiYWdfZW50cnkqIGVuZCA9IGJhZyArIE47CisgICAgd2hpbGUgKGJhZyA8IGVuZCkgeworICAgICAgICBjb25zdCB1aW50MzJfdCBhdHRyUmVzID0gYmFnLT5tYXAubmFtZS5pZGVudDsKKyAgICAgICAgY29uc3QgdWludDMyX3QgcCA9IFJlc19HRVRQQUNLQUdFKGF0dHJSZXMpOworICAgICAgICBjb25zdCB1aW50MzJfdCB0ID0gUmVzX0dFVFRZUEUoYXR0clJlcyk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IGUgPSBSZXNfR0VURU5UUlkoYXR0clJlcyk7CisKKyAgICAgICAgaWYgKGN1clBhY2thZ2UgIT0gcCkgeworICAgICAgICAgICAgY29uc3Qgc3NpemVfdCBwaWR4ID0gbVRhYmxlLmdldFJlc291cmNlUGFja2FnZUluZGV4KGF0dHJSZXMpOworICAgICAgICAgICAgaWYgKHBpZHggPCAwKSB7CisgICAgICAgICAgICAgICAgTE9HRSgiU3R5bGUgY29udGFpbnMga2V5IHdpdGggYmFkIHBhY2thZ2U6IDB4JTA4eFxuIiwgYXR0clJlcyk7CisgICAgICAgICAgICAgICAgYmFnKys7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJQYWNrYWdlID0gcDsKKyAgICAgICAgICAgIGN1clBhY2thZ2VJbmRleCA9IHBpZHg7CisgICAgICAgICAgICBjdXJQSSA9IG1QYWNrYWdlc1twaWR4XTsKKyAgICAgICAgICAgIGlmIChjdXJQSSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUGFja2FnZUdyb3VwKiBjb25zdCBncnAgPSBtVGFibGUubVBhY2thZ2VHcm91cHNbcGlkeF07CisgICAgICAgICAgICAgICAgaW50IGNudCA9IGdycC0+dHlwZUNvdW50OworICAgICAgICAgICAgICAgIGN1clBJID0gKHBhY2thZ2VfaW5mbyopbWFsbG9jKAorICAgICAgICAgICAgICAgICAgICBzaXplb2YocGFja2FnZV9pbmZvKSArIChjbnQqc2l6ZW9mKHR5cGVfaW5mbykpKTsKKyAgICAgICAgICAgICAgICBjdXJQSS0+bnVtVHlwZXMgPSBjbnQ7CisgICAgICAgICAgICAgICAgbWVtc2V0KGN1clBJLT50eXBlcywgMCwgY250KnNpemVvZih0eXBlX2luZm8pKTsKKyAgICAgICAgICAgICAgICBtUGFja2FnZXNbcGlkeF0gPSBjdXJQSTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGN1clR5cGUgPSAweGZmZmZmZmZmOworICAgICAgICB9CisgICAgICAgIGlmIChjdXJUeXBlICE9IHQpIHsKKyAgICAgICAgICAgIGlmICh0ID49IGN1clBJLT5udW1UeXBlcykgeworICAgICAgICAgICAgICAgIExPR0UoIlN0eWxlIGNvbnRhaW5zIGtleSB3aXRoIGJhZCB0eXBlOiAweCUwOHhcbiIsIGF0dHJSZXMpOworICAgICAgICAgICAgICAgIGJhZysrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3VyVHlwZSA9IHQ7CisgICAgICAgICAgICBjdXJFbnRyaWVzID0gY3VyUEktPnR5cGVzW3RdLmVudHJpZXM7CisgICAgICAgICAgICBpZiAoY3VyRW50cmllcyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUGFja2FnZUdyb3VwKiBjb25zdCBncnAgPSBtVGFibGUubVBhY2thZ2VHcm91cHNbY3VyUGFja2FnZUluZGV4XTsKKyAgICAgICAgICAgICAgICBjb25zdCBUeXBlKiB0eXBlID0gZ3JwLT5wYWNrYWdlc1swXS0+Z2V0VHlwZSh0KTsKKyAgICAgICAgICAgICAgICBpbnQgY250ID0gdHlwZSAhPSBOVUxMID8gdHlwZS0+ZW50cnlDb3VudCA6IDA7CisgICAgICAgICAgICAgICAgY3VyRW50cmllcyA9ICh0aGVtZV9lbnRyeSopbWFsbG9jKGNudCpzaXplb2YodGhlbWVfZW50cnkpKTsKKyAgICAgICAgICAgICAgICBtZW1zZXQoY3VyRW50cmllcywgUmVzX3ZhbHVlOjpUWVBFX05VTEwsIGNudCpzaXplb2YodGhlbWVfZW50cnkpKTsKKyAgICAgICAgICAgICAgICBjdXJQSS0+dHlwZXNbdF0ubnVtRW50cmllcyA9IGNudDsKKyAgICAgICAgICAgICAgICBjdXJQSS0+dHlwZXNbdF0uZW50cmllcyA9IGN1ckVudHJpZXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBudW1FbnRyaWVzID0gY3VyUEktPnR5cGVzW3RdLm51bUVudHJpZXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGUgPj0gbnVtRW50cmllcykgeworICAgICAgICAgICAgTE9HRSgiU3R5bGUgY29udGFpbnMga2V5IHdpdGggYmFkIGVudHJ5OiAweCUwOHhcbiIsIGF0dHJSZXMpOworICAgICAgICAgICAgYmFnKys7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICB0aGVtZV9lbnRyeSogY3VyRW50cnkgPSBjdXJFbnRyaWVzICsgZTsKKyAgICAgICAgVEFCTEVfTk9JU1koTE9HVigiQXR0ciAweCUwOHg6IHR5cGU9MHgleCwgZGF0YT0weCUwOHg7IGN1clR5cGU9MHgleCIsCisgICAgICAgICAgICAgICAgICAgYXR0clJlcywgYmFnLT5tYXAudmFsdWUuZGF0YVR5cGUsIGJhZy0+bWFwLnZhbHVlLmRhdGEsCisgICAgICAgICAgICAgY3VyRW50cnktPnZhbHVlLmRhdGFUeXBlKSk7CisgICAgICAgIGlmIChmb3JjZSB8fCBjdXJFbnRyeS0+dmFsdWUuZGF0YVR5cGUgPT0gUmVzX3ZhbHVlOjpUWVBFX05VTEwpIHsKKyAgICAgICAgICAgIGN1ckVudHJ5LT5zdHJpbmdCbG9jayA9IGJhZy0+c3RyaW5nQmxvY2s7CisgICAgICAgICAgICBjdXJFbnRyeS0+dHlwZVNwZWNGbGFncyB8PSBiYWdUeXBlU3BlY0ZsYWdzOworICAgICAgICAgICAgY3VyRW50cnktPnZhbHVlID0gYmFnLT5tYXAudmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBiYWcrKzsKKyAgICB9CisKKyAgICBtVGFibGUudW5sb2NrKCk7CisKKyAgICAvL0xPR0koIkFwcGx5aW5nIHN0eWxlIDB4JTA4eCAoZm9yY2U9JWQpICB0aGVtZSAlcC4uLlxuIiwgcmVzSUQsIGZvcmNlLCB0aGlzKTsKKyAgICAvL2R1bXBUb0xvZygpOworICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3RhdHVzX3QgUmVzVGFibGU6OlRoZW1lOjpzZXRUbyhjb25zdCBUaGVtZSYgb3RoZXIpCit7CisgICAgLy9MT0dJKCJTZXR0aW5nIHRoZW1lICVwIGZyb20gdGhlbWUgJXAuLi5cbiIsIHRoaXMsICZvdGhlcik7CisgICAgLy9kdW1wVG9Mb2coKTsKKyAgICAvL290aGVyLmR1bXBUb0xvZygpOworICAgIAorICAgIGlmICgmbVRhYmxlID09ICZvdGhlci5tVGFibGUpIHsKKyAgICAgICAgZm9yIChzaXplX3QgaT0wOyBpPFJlc19NQVhQQUNLQUdFOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChtUGFja2FnZXNbaV0gIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGZyZWVfcGFja2FnZShtUGFja2FnZXNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG90aGVyLm1QYWNrYWdlc1tpXSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgbVBhY2thZ2VzW2ldID0gY29weV9wYWNrYWdlKG90aGVyLm1QYWNrYWdlc1tpXSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG1QYWNrYWdlc1tpXSA9IE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICAvLyBAdG9kbzogbmVlZCB0byByZWFsbHkgaW1wbGVtZW50IHRoaXMsIG5vdCBqdXN0IGNvcHkKKyAgICAgICAgLy8gdGhlIHN5c3RlbSBwYWNrYWdlICh3aGljaCBpcyBzdGlsbCB3cm9uZyBiZWNhdXNlIGl0IGlzbid0CisgICAgICAgIC8vIGZpeGluZyB1cCByZXNvdXJjZSByZWZlcmVuY2VzKS4KKyAgICAgICAgZm9yIChzaXplX3QgaT0wOyBpPFJlc19NQVhQQUNLQUdFOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChtUGFja2FnZXNbaV0gIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGZyZWVfcGFja2FnZShtUGFja2FnZXNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gMCAmJiBvdGhlci5tUGFja2FnZXNbaV0gIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIG1QYWNrYWdlc1tpXSA9IGNvcHlfcGFja2FnZShvdGhlci5tUGFja2FnZXNbaV0pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBtUGFja2FnZXNbaV0gPSBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy9MT0dJKCJGaW5hbCB0aGVtZToiKTsKKyAgICAvL2R1bXBUb0xvZygpOworICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworc3NpemVfdCBSZXNUYWJsZTo6VGhlbWU6OmdldEF0dHJpYnV0ZSh1aW50MzJfdCByZXNJRCwgUmVzX3ZhbHVlKiBvdXRWYWx1ZSwKKyAgICAgICAgdWludDMyX3QqIG91dFR5cGVTcGVjRmxhZ3MpIGNvbnN0Cit7CisgICAgaW50IGNudCA9IDIwOworCisgICAgaWYgKG91dFR5cGVTcGVjRmxhZ3MgIT0gTlVMTCkgKm91dFR5cGVTcGVjRmxhZ3MgPSAwOworICAgIAorICAgIGRvIHsKKyAgICAgICAgY29uc3Qgc3NpemVfdCBwID0gbVRhYmxlLmdldFJlc291cmNlUGFja2FnZUluZGV4KHJlc0lEKTsKKyAgICAgICAgY29uc3QgdWludDMyX3QgdCA9IFJlc19HRVRUWVBFKHJlc0lEKTsKKyAgICAgICAgY29uc3QgdWludDMyX3QgZSA9IFJlc19HRVRFTlRSWShyZXNJRCk7CisKKyAgICAgICAgVEFCTEVfTk9JU1koTE9HVigiTG9va2luZyB1cCBhdHRyIDB4JTA4eCBpbiB0aGVtZSAlcCIsIHJlc0lELCB0aGlzKSk7CisKKyAgICAgICAgaWYgKHAgPj0gMCkgeworICAgICAgICAgICAgY29uc3QgcGFja2FnZV9pbmZvKiBjb25zdCBwaSA9IG1QYWNrYWdlc1twXTsKKyAgICAgICAgICAgIGlmIChwaSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgaWYgKHQgPCBwaS0+bnVtVHlwZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZV9pbmZvJiB0aSA9IHBpLT50eXBlc1t0XTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGUgPCB0aS5udW1FbnRyaWVzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGVtZV9lbnRyeSYgdGUgPSB0aS5lbnRyaWVzW2VdOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRUeXBlU3BlY0ZsYWdzICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm91dFR5cGVTcGVjRmxhZ3MgfD0gdGUudHlwZVNwZWNGbGFnczsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90IHR5cGUgPSB0ZS52YWx1ZS5kYXRhVHlwZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFJlc192YWx1ZTo6VFlQRV9BVFRSSUJVVEUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY250ID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbnQtLTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzSUQgPSB0ZS52YWx1ZS5kYXRhOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HVygiVG9vIG1hbnkgYXR0cmlidXRlIHJlZmVyZW5jZXMsIHN0b3BwZWQgYXQ6IDB4JTA4eFxuIiwgcmVzSUQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgIT0gUmVzX3ZhbHVlOjpUWVBFX05VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0VmFsdWUgPSB0ZS52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGUuc3RyaW5nQmxvY2s7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQkFEX0lOREVYOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgfSB3aGlsZSAodHJ1ZSk7CisKKyAgICByZXR1cm4gQkFEX0lOREVYOworfQorCitzc2l6ZV90IFJlc1RhYmxlOjpUaGVtZTo6cmVzb2x2ZUF0dHJpYnV0ZVJlZmVyZW5jZShSZXNfdmFsdWUqIGluT3V0VmFsdWUsCisgICAgICAgIHNzaXplX3QgYmxvY2tJbmRleCwgdWludDMyX3QqIG91dExhc3RSZWYsCisgICAgICAgIHVpbnQzMl90KiBpbm91dFR5cGVTcGVjRmxhZ3MpIGNvbnN0Cit7CisgICAgLy9wcmludGYoIlJlc29sdmluZyB0eXBlPTB4JXhcbiIsIGluT3V0VmFsdWUtPmRhdGFUeXBlKTsKKyAgICBpZiAoaW5PdXRWYWx1ZS0+ZGF0YVR5cGUgPT0gUmVzX3ZhbHVlOjpUWVBFX0FUVFJJQlVURSkgeworICAgICAgICB1aW50MzJfdCBuZXdUeXBlU3BlY0ZsYWdzOworICAgICAgICBibG9ja0luZGV4ID0gZ2V0QXR0cmlidXRlKGluT3V0VmFsdWUtPmRhdGEsIGluT3V0VmFsdWUsICZuZXdUeXBlU3BlY0ZsYWdzKTsKKyAgICAgICAgaWYgKGlub3V0VHlwZVNwZWNGbGFncyAhPSBOVUxMKSAqaW5vdXRUeXBlU3BlY0ZsYWdzIHw9IG5ld1R5cGVTcGVjRmxhZ3M7CisgICAgICAgIC8vcHJpbnRmKCJSZXRyaWV2ZWQgYXR0cmlidXRlIG5ldyB0eXBlPTB4JXhcbiIsIGluT3V0VmFsdWUtPmRhdGFUeXBlKTsKKyAgICAgICAgaWYgKGJsb2NrSW5kZXggPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gYmxvY2tJbmRleDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbVRhYmxlLnJlc29sdmVSZWZlcmVuY2UoaW5PdXRWYWx1ZSwgYmxvY2tJbmRleCwgb3V0TGFzdFJlZik7Cit9CisKK3ZvaWQgUmVzVGFibGU6OlRoZW1lOjpkdW1wVG9Mb2coKSBjb25zdAoreworICAgIExPR0koIlRoZW1lICVwOlxuIiwgdGhpcyk7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPFJlc19NQVhQQUNLQUdFOyBpKyspIHsKKyAgICAgICAgcGFja2FnZV9pbmZvKiBwaSA9IG1QYWNrYWdlc1tpXTsKKyAgICAgICAgaWYgKHBpID09IE5VTEwpIGNvbnRpbnVlOworICAgICAgICAKKyAgICAgICAgTE9HSSgiICBQYWNrYWdlICMweCUwMng6XG4iLCAoaW50KShpKzEpKTsKKyAgICAgICAgZm9yIChzaXplX3Qgaj0wOyBqPHBpLT5udW1UeXBlczsgaisrKSB7CisgICAgICAgICAgICB0eXBlX2luZm8mIHRpID0gcGktPnR5cGVzW2pdOworICAgICAgICAgICAgaWYgKHRpLm51bUVudHJpZXMgPT0gMCkgY29udGludWU7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIExPR0koIiAgICBUeXBlICMweCUwMng6XG4iLCAoaW50KShqKzEpKTsKKyAgICAgICAgICAgIGZvciAoc2l6ZV90IGs9MDsgazx0aS5udW1FbnRyaWVzOyBrKyspIHsKKyAgICAgICAgICAgICAgICB0aGVtZV9lbnRyeSYgdGUgPSB0aS5lbnRyaWVzW2tdOworICAgICAgICAgICAgICAgIGlmICh0ZS52YWx1ZS5kYXRhVHlwZSA9PSBSZXNfdmFsdWU6OlRZUEVfTlVMTCkgY29udGludWU7CisgICAgICAgICAgICAgICAgTE9HSSgiICAgICAgMHglMDh4OiB0PTB4JXgsIGQ9MHglMDh4IChibG9jaz0lZClcbiIsCisgICAgICAgICAgICAgICAgICAgICAoaW50KVJlc19NQUtFSUQoaSwgaiwgayksCisgICAgICAgICAgICAgICAgICAgICB0ZS52YWx1ZS5kYXRhVHlwZSwgKGludCl0ZS52YWx1ZS5kYXRhLCAoaW50KXRlLnN0cmluZ0Jsb2NrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKworUmVzVGFibGU6OlJlc1RhYmxlKCkKKyAgICA6IG1FcnJvcihOT19JTklUKQoreworICAgIG1lbXNldCgmbVBhcmFtcywgMCwgc2l6ZW9mKG1QYXJhbXMpKTsKKyAgICBtZW1zZXQobVBhY2thZ2VNYXAsIDAsIHNpemVvZihtUGFja2FnZU1hcCkpOworICAgIC8vTE9HSSgiQ3JlYXRpbmcgUmVzVGFibGUgJXBcbiIsIHRoaXMpOworfQorCitSZXNUYWJsZTo6UmVzVGFibGUoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIHZvaWQqIGNvb2tpZSwgYm9vbCBjb3B5RGF0YSkKKyAgICA6IG1FcnJvcihOT19JTklUKQoreworICAgIG1lbXNldCgmbVBhcmFtcywgMCwgc2l6ZW9mKG1QYXJhbXMpKTsKKyAgICBtZW1zZXQobVBhY2thZ2VNYXAsIDAsIHNpemVvZihtUGFja2FnZU1hcCkpOworICAgIGFkZChkYXRhLCBzaXplLCBjb29raWUsIGNvcHlEYXRhKTsKKyAgICBMT0dfRkFUQUxfSUYobUVycm9yICE9IE5PX0VSUk9SLCAiRXJyb3IgcGFyc2luZyByZXNvdXJjZSB0YWJsZSIpOworICAgIC8vTE9HSSgiQ3JlYXRpbmcgUmVzVGFibGUgJXBcbiIsIHRoaXMpOworfQorCitSZXNUYWJsZTo6flJlc1RhYmxlKCkKK3sKKyAgICAvL0xPR0koIkRlc3Ryb3lpbmcgUmVzVGFibGUgaW4gJXBcbiIsIHRoaXMpOworICAgIHVuaW5pdCgpOworfQorCitpbmxpbmUgc3NpemVfdCBSZXNUYWJsZTo6Z2V0UmVzb3VyY2VQYWNrYWdlSW5kZXgodWludDMyX3QgcmVzSUQpIGNvbnN0Cit7CisgICAgcmV0dXJuICgoc3NpemVfdCltUGFja2FnZU1hcFtSZXNfR0VUUEFDS0FHRShyZXNJRCkrMV0pLTE7Cit9CisKK3N0YXR1c190IFJlc1RhYmxlOjphZGQoY29uc3Qgdm9pZCogZGF0YSwgc2l6ZV90IHNpemUsIHZvaWQqIGNvb2tpZSwgYm9vbCBjb3B5RGF0YSkKK3sKKyAgICByZXR1cm4gYWRkKGRhdGEsIHNpemUsIGNvb2tpZSwgTlVMTCwgY29weURhdGEpOworfQorCitzdGF0dXNfdCBSZXNUYWJsZTo6YWRkKEFzc2V0KiBhc3NldCwgdm9pZCogY29va2llLCBib29sIGNvcHlEYXRhKQoreworICAgIGNvbnN0IHZvaWQqIGRhdGEgPSBhc3NldC0+Z2V0QnVmZmVyKHRydWUpOworICAgIGlmIChkYXRhID09IE5VTEwpIHsKKyAgICAgICAgTE9HVygiVW5hYmxlIHRvIGdldCBidWZmZXIgb2YgcmVzb3VyY2UgYXNzZXQgZmlsZSIpOworICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisgICAgc2l6ZV90IHNpemUgPSAoc2l6ZV90KWFzc2V0LT5nZXRMZW5ndGgoKTsKKyAgICByZXR1cm4gYWRkKGRhdGEsIHNpemUsIGNvb2tpZSwgYXNzZXQsIGNvcHlEYXRhKTsKK30KKworc3RhdHVzX3QgUmVzVGFibGU6OmFkZChjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgdm9pZCogY29va2llLAorICAgICAgICAgICAgICAgICAgICAgICBBc3NldCogYXNzZXQsIGJvb2wgY29weURhdGEpCit7CisgICAgaWYgKCFkYXRhKSByZXR1cm4gTk9fRVJST1I7CisgICAgSGVhZGVyKiBoZWFkZXIgPSBuZXcgSGVhZGVyOworICAgIGhlYWRlci0+aW5kZXggPSBtSGVhZGVycy5zaXplKCk7CisgICAgaGVhZGVyLT5jb29raWUgPSBjb29raWU7CisgICAgbUhlYWRlcnMuYWRkKGhlYWRlcik7CisKKyAgICBjb25zdCBib29sIG5vdERldmljZUVuZGlhbiA9IGh0b2RzKDB4ZjApICE9IDB4ZjA7CisKKyAgICBMT0FEX1RBQkxFX05PSVNZKAorICAgICAgICBMT0dWKCJBZGRpbmcgcmVzb3VyY2VzIHRvIFJlc1RhYmxlOiBkYXRhPSVwLCBzaXplPTB4JXgsIGNvb2tpZT0lcCwgYXNzZXQ9JXAsIGNvcHk9JWRcbiIsCisgICAgICAgICAgICAgZGF0YSwgc2l6ZSwgY29va2llLCBhc3NldCwgY29weURhdGEpKTsKKyAgICAKKyAgICBpZiAoY29weURhdGEgfHwgbm90RGV2aWNlRW5kaWFuKSB7CisgICAgICAgIGhlYWRlci0+b3duZWREYXRhID0gbWFsbG9jKHNpemUpOworICAgICAgICBpZiAoaGVhZGVyLT5vd25lZERhdGEgPT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9Tk9fTUVNT1JZKTsKKyAgICAgICAgfQorICAgICAgICBtZW1jcHkoaGVhZGVyLT5vd25lZERhdGEsIGRhdGEsIHNpemUpOworICAgICAgICBkYXRhID0gaGVhZGVyLT5vd25lZERhdGE7CisgICAgfQorCisgICAgaGVhZGVyLT5oZWFkZXIgPSAoY29uc3QgUmVzVGFibGVfaGVhZGVyKilkYXRhOworICAgIGhlYWRlci0+c2l6ZSA9IGR0b2hsKGhlYWRlci0+aGVhZGVyLT5oZWFkZXIuc2l6ZSk7CisgICAgLy9MT0dJKCJHb3Qgc2l6ZSAweCV4LCBhZ2FpbiBzaXplIDB4JXgsIHJhdyBzaXplIDB4JXhcbiIsIGhlYWRlci0+c2l6ZSwKKyAgICAvLyAgICAgZHRvaGwoaGVhZGVyLT5oZWFkZXItPmhlYWRlci5zaXplKSwgaGVhZGVyLT5oZWFkZXItPmhlYWRlci5zaXplKTsKKyAgICBMT0FEX1RBQkxFX05PSVNZKExPR1YoIkxvYWRpbmcgUmVzVGFibGUgQCVwOlxuIiwgaGVhZGVyLT5oZWFkZXIpKTsKKyAgICBMT0FEX1RBQkxFX05PSVNZKHByaW50SGV4RGF0YSgyLCBoZWFkZXItPmhlYWRlciwgaGVhZGVyLT5zaXplIDwgMjU2ID8gaGVhZGVyLT5zaXplIDogMjU2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE2LCAxNiwgMCwgZmFsc2UsIHByaW50VG9Mb2dGdW5jKSk7CisgICAgaWYgKGR0b2hzKGhlYWRlci0+aGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSkgPiBoZWFkZXItPnNpemUKKyAgICAgICAgICAgIHx8IGhlYWRlci0+c2l6ZSA+IHNpemUpIHsKKyAgICAgICAgTE9HVygiQmFkIHJlc291cmNlIHRhYmxlOiBoZWFkZXIgc2l6ZSAweCV4IG9yIHRvdGFsIHNpemUgMHgleCBpcyBsYXJnZXIgdGhhbiBkYXRhIHNpemUgMHgleFxuIiwKKyAgICAgICAgICAgICAoaW50KWR0b2hzKGhlYWRlci0+aGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSksCisgICAgICAgICAgICAgKGludCloZWFkZXItPnNpemUsIChpbnQpc2l6ZSk7CisgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICB9CisgICAgaWYgKCgoZHRvaHMoaGVhZGVyLT5oZWFkZXItPmhlYWRlci5oZWFkZXJTaXplKXxoZWFkZXItPnNpemUpJjB4MykgIT0gMCkgeworICAgICAgICBMT0dXKCJCYWQgcmVzb3VyY2UgdGFibGU6IGhlYWRlciBzaXplIDB4JXggb3IgdG90YWwgc2l6ZSAweCV4IGlzIG5vdCBvbiBhbiBpbnRlZ2VyIGJvdW5kYXJ5XG4iLAorICAgICAgICAgICAgIChpbnQpZHRvaHMoaGVhZGVyLT5oZWFkZXItPmhlYWRlci5oZWFkZXJTaXplKSwKKyAgICAgICAgICAgICAoaW50KWhlYWRlci0+c2l6ZSk7CisgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICB9CisgICAgaGVhZGVyLT5kYXRhRW5kID0gKChjb25zdCB1aW50OF90KiloZWFkZXItPmhlYWRlcikgKyBoZWFkZXItPnNpemU7CisKKyAgICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIGNodW5rcy4KKyAgICBzaXplX3QgY3VyUGFja2FnZSA9IDA7CisKKyAgICBjb25zdCBSZXNDaHVua19oZWFkZXIqIGNodW5rID0KKyAgICAgICAgKGNvbnN0IFJlc0NodW5rX2hlYWRlciopKCgoY29uc3QgdWludDhfdCopaGVhZGVyLT5oZWFkZXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGR0b2hzKGhlYWRlci0+aGVhZGVyLT5oZWFkZXIuaGVhZGVyU2l6ZSkpOworICAgIHdoaWxlICgoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSA8PSAoaGVhZGVyLT5kYXRhRW5kLXNpemVvZihSZXNDaHVua19oZWFkZXIpKSAmJgorICAgICAgICAgICAoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSA8PSAoaGVhZGVyLT5kYXRhRW5kLWR0b2hsKGNodW5rLT5zaXplKSkpIHsKKyAgICAgICAgc3RhdHVzX3QgZXJyID0gdmFsaWRhdGVfY2h1bmsoY2h1bmssIHNpemVvZihSZXNDaHVua19oZWFkZXIpLCBoZWFkZXItPmRhdGFFbmQsICJSZXNUYWJsZSIpOworICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1lcnIpOworICAgICAgICB9CisgICAgICAgIFRBQkxFX05PSVNZKExPR1YoIkNodW5rOiB0eXBlPTB4JXgsIGhlYWRlclNpemU9MHgleCwgc2l6ZT0weCV4LCBwb3M9JXBcbiIsCisgICAgICAgICAgICAgICAgICAgICBkdG9ocyhjaHVuay0+dHlwZSksIGR0b2hzKGNodW5rLT5oZWFkZXJTaXplKSwgZHRvaGwoY2h1bmstPnNpemUpLAorICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKSgoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSAtICgoY29uc3QgdWludDhfdCopaGVhZGVyLT5oZWFkZXIpKSkpOworICAgICAgICBjb25zdCBzaXplX3QgY3NpemUgPSBkdG9obChjaHVuay0+c2l6ZSk7CisgICAgICAgIGNvbnN0IHVpbnQxNl90IGN0eXBlID0gZHRvaHMoY2h1bmstPnR5cGUpOworICAgICAgICBpZiAoY3R5cGUgPT0gUkVTX1NUUklOR19QT09MX1RZUEUpIHsKKyAgICAgICAgICAgIGlmIChoZWFkZXItPnZhbHVlcy5nZXRFcnJvcigpICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgLy8gT25seSB1c2UgdGhlIGZpcnN0IHN0cmluZyBjaHVuazsgaWdub3JlIGFueSBvdGhlcnMgdGhhdAorICAgICAgICAgICAgICAgIC8vIG1heSBhcHBlYXIuCisgICAgICAgICAgICAgICAgc3RhdHVzX3QgZXJyID0gaGVhZGVyLT52YWx1ZXMuc2V0VG8oY2h1bmssIGNzaXplKTsKKyAgICAgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAobUVycm9yPWVycik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJNdWx0aXBsZSBzdHJpbmcgY2h1bmtzIGZvdW5kIGluIHJlc291cmNlIHRhYmxlLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGN0eXBlID09IFJFU19UQUJMRV9QQUNLQUdFX1RZUEUpIHsKKyAgICAgICAgICAgIGlmIChjdXJQYWNrYWdlID49IGR0b2hsKGhlYWRlci0+aGVhZGVyLT5wYWNrYWdlQ291bnQpKSB7CisgICAgICAgICAgICAgICAgTE9HVygiTW9yZSBwYWNrYWdlIGNodW5rcyB3ZXJlIGZvdW5kIHRoYW4gdGhlICVkIGRlY2xhcmVkIGluIHRoZSBoZWFkZXIuIiwKKyAgICAgICAgICAgICAgICAgICAgIGR0b2hsKGhlYWRlci0+aGVhZGVyLT5wYWNrYWdlQ291bnQpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocGFyc2VQYWNrYWdlKChSZXNUYWJsZV9wYWNrYWdlKiljaHVuaywgaGVhZGVyKSAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgIHJldHVybiBtRXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJQYWNrYWdlKys7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dXKCJVbmtub3duIGNodW5rIHR5cGUgJXAgaW4gdGFibGUgYXQgJXAuXG4iLAorICAgICAgICAgICAgICAgICAodm9pZCopKGludCkoY3R5cGUpLAorICAgICAgICAgICAgICAgICAodm9pZCopKCgoY29uc3QgdWludDhfdCopY2h1bmspIC0gKChjb25zdCB1aW50OF90KiloZWFkZXItPmhlYWRlcikpKTsKKyAgICAgICAgfQorICAgICAgICBjaHVuayA9IChjb25zdCBSZXNDaHVua19oZWFkZXIqKQorICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopY2h1bmspICsgY3NpemUpOworICAgIH0KKworICAgIGlmIChjdXJQYWNrYWdlIDwgZHRvaGwoaGVhZGVyLT5oZWFkZXItPnBhY2thZ2VDb3VudCkpIHsKKyAgICAgICAgTE9HVygiRmV3ZXIgcGFja2FnZSBjaHVua3MgKCVkKSB3ZXJlIGZvdW5kIHRoYW4gdGhlICVkIGRlY2xhcmVkIGluIHRoZSBoZWFkZXIuIiwKKyAgICAgICAgICAgICAoaW50KWN1clBhY2thZ2UsIGR0b2hsKGhlYWRlci0+aGVhZGVyLT5wYWNrYWdlQ291bnQpKTsKKyAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgIH0KKyAgICBtRXJyb3IgPSBoZWFkZXItPnZhbHVlcy5nZXRFcnJvcigpOworICAgIGlmIChtRXJyb3IgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgTE9HVygiTm8gc3RyaW5nIHZhbHVlcyBmb3VuZCBpbiByZXNvdXJjZSB0YWJsZSEiKTsKKyAgICB9CisgICAgVEFCTEVfTk9JU1koTE9HVigiUmV0dXJuaW5nIGZyb20gYWRkIHdpdGggbUVycm9yPSVkXG4iLCBtRXJyb3IpKTsKKyAgICByZXR1cm4gbUVycm9yOworfQorCitzdGF0dXNfdCBSZXNUYWJsZTo6Z2V0RXJyb3IoKSBjb25zdAoreworICAgIHJldHVybiBtRXJyb3I7Cit9CisKK3ZvaWQgUmVzVGFibGU6OnVuaW5pdCgpCit7CisgICAgbUVycm9yID0gTk9fSU5JVDsKKyAgICBzaXplX3QgTiA9IG1QYWNrYWdlR3JvdXBzLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgIFBhY2thZ2VHcm91cCogZyA9IG1QYWNrYWdlR3JvdXBzW2ldOworICAgICAgICBkZWxldGUgZzsKKyAgICB9CisgICAgTiA9IG1IZWFkZXJzLnNpemUoKTsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgIEhlYWRlciogaGVhZGVyID0gbUhlYWRlcnNbaV07CisgICAgICAgIGlmIChoZWFkZXItPm93bmVkRGF0YSkgeworICAgICAgICAgICAgZnJlZShoZWFkZXItPm93bmVkRGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgZGVsZXRlIGhlYWRlcjsKKyAgICB9CisKKyAgICBtUGFja2FnZUdyb3Vwcy5jbGVhcigpOworICAgIG1IZWFkZXJzLmNsZWFyKCk7Cit9CisKK2Jvb2wgUmVzVGFibGU6OmdldFJlc291cmNlTmFtZSh1aW50MzJfdCByZXNJRCwgcmVzb3VyY2VfbmFtZSogb3V0TmFtZSkgY29uc3QKK3sKKyAgICBpZiAobUVycm9yICE9IE5PX0VSUk9SKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCBzc2l6ZV90IHAgPSBnZXRSZXNvdXJjZVBhY2thZ2VJbmRleChyZXNJRCk7CisgICAgY29uc3QgaW50IHQgPSBSZXNfR0VUVFlQRShyZXNJRCk7CisgICAgY29uc3QgaW50IGUgPSBSZXNfR0VURU5UUlkocmVzSUQpOworCisgICAgaWYgKHAgPCAwKSB7CisgICAgICAgIExPR1coIk5vIHBhY2thZ2UgaWRlbnRpZmllciB3aGVuIGdldHRpbmcgbmFtZSBmb3IgcmVzb3VyY2UgbnVtYmVyIDB4JTA4eCIsIHJlc0lEKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodCA8IDApIHsKKyAgICAgICAgTE9HVygiTm8gdHlwZSBpZGVudGlmaWVyIHdoZW4gZ2V0dGluZyBuYW1lIGZvciByZXNvdXJjZSBudW1iZXIgMHglMDh4IiwgcmVzSUQpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgY29uc3QgUGFja2FnZUdyb3VwKiBjb25zdCBncnAgPSBtUGFja2FnZUdyb3Vwc1twXTsKKyAgICBpZiAoZ3JwID09IE5VTEwpIHsKKyAgICAgICAgTE9HVygiQmFkIGlkZW50aWZpZXIgd2hlbiBnZXR0aW5nIG5hbWUgZm9yIHJlc291cmNlIG51bWJlciAweCUwOHgiLCByZXNJRCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGdycC0+cGFja2FnZXMuc2l6ZSgpID4gMCkgeworICAgICAgICBjb25zdCBQYWNrYWdlKiBjb25zdCBwYWNrYWdlID0gZ3JwLT5wYWNrYWdlc1swXTsKKworICAgICAgICBjb25zdCBSZXNUYWJsZV90eXBlKiB0eXBlOworICAgICAgICBjb25zdCBSZXNUYWJsZV9lbnRyeSogZW50cnk7CisgICAgICAgIHNzaXplX3Qgb2Zmc2V0ID0gZ2V0RW50cnkocGFja2FnZSwgdCwgZSwgTlVMTCwgJnR5cGUsICZlbnRyeSwgTlVMTCk7CisgICAgICAgIGlmIChvZmZzZXQgPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgb3V0TmFtZS0+cGFja2FnZSA9IGdycC0+bmFtZS5zdHJpbmcoKTsKKyAgICAgICAgb3V0TmFtZS0+cGFja2FnZUxlbiA9IGdycC0+bmFtZS5zaXplKCk7CisgICAgICAgIG91dE5hbWUtPnR5cGUgPSBncnAtPnR5cGVTdHJpbmdzLnN0cmluZ0F0KHQsICZvdXROYW1lLT50eXBlTGVuKTsKKyAgICAgICAgb3V0TmFtZS0+bmFtZSA9IGdycC0+a2V5U3RyaW5ncy5zdHJpbmdBdCgKKyAgICAgICAgICAgIGR0b2hsKGVudHJ5LT5rZXkuaW5kZXgpLCAmb3V0TmFtZS0+bmFtZUxlbik7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHJldHVybiBmYWxzZTsKK30KKworc3NpemVfdCBSZXNUYWJsZTo6Z2V0UmVzb3VyY2UodWludDMyX3QgcmVzSUQsIFJlc192YWx1ZSogb3V0VmFsdWUsIGJvb2wgbWF5QmVCYWcsCisgICAgICAgIHVpbnQzMl90KiBvdXRTcGVjRmxhZ3MsIFJlc1RhYmxlX2NvbmZpZyogb3V0Q29uZmlnKSBjb25zdAoreworICAgIGlmIChtRXJyb3IgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgcmV0dXJuIG1FcnJvcjsKKyAgICB9CisKKyAgICBjb25zdCBzc2l6ZV90IHAgPSBnZXRSZXNvdXJjZVBhY2thZ2VJbmRleChyZXNJRCk7CisgICAgY29uc3QgaW50IHQgPSBSZXNfR0VUVFlQRShyZXNJRCk7CisgICAgY29uc3QgaW50IGUgPSBSZXNfR0VURU5UUlkocmVzSUQpOworCisgICAgaWYgKHAgPCAwKSB7CisgICAgICAgIExPR1coIk5vIHBhY2thZ2UgaWRlbnRpZmllciB3aGVuIGdldHRpbmcgdmFsdWUgZm9yIHJlc291cmNlIG51bWJlciAweCUwOHgiLCByZXNJRCk7CisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgfQorICAgIGlmICh0IDwgMCkgeworICAgICAgICBMT0dXKCJObyB0eXBlIGlkZW50aWZpZXIgd2hlbiBnZXR0aW5nIHZhbHVlIGZvciByZXNvdXJjZSBudW1iZXIgMHglMDh4IiwgcmVzSUQpOworICAgICAgICByZXR1cm4gQkFEX0lOREVYOworICAgIH0KKworICAgIGNvbnN0IFJlc192YWx1ZSogYmVzdFZhbHVlID0gTlVMTDsKKyAgICBjb25zdCBQYWNrYWdlKiBiZXN0UGFja2FnZSA9IE5VTEw7CisgICAgUmVzVGFibGVfY29uZmlnIGJlc3RJdGVtOworICAgIG1lbXNldCgmYmVzdEl0ZW0sIDAsIHNpemVvZihiZXN0SXRlbSkpOyAvLyBtYWtlIHRoZSBjb21waWxlciBzaHV0IHVwCisKKyAgICBpZiAob3V0U3BlY0ZsYWdzICE9IE5VTEwpICpvdXRTcGVjRmxhZ3MgPSAwOworICAgIAorICAgIC8vIExvb2sgdGhyb3VnaCBhbGwgcmVzb3VyY2UgcGFja2FnZXMsIHN0YXJ0aW5nIHdpdGggdGhlIG1vc3QKKyAgICAvLyByZWNlbnRseSBhZGRlZC4KKyAgICBjb25zdCBQYWNrYWdlR3JvdXAqIGNvbnN0IGdycCA9IG1QYWNrYWdlR3JvdXBzW3BdOworICAgIGlmIChncnAgPT0gTlVMTCkgeworICAgICAgICBMT0dXKCJCYWQgaWRlbnRpZmllciB3aGVuIGdldHRpbmcgdmFsdWUgZm9yIHJlc291cmNlIG51bWJlciAweCUwOHgiLCByZXNJRCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgc2l6ZV90IGlwID0gZ3JwLT5wYWNrYWdlcy5zaXplKCk7CisgICAgd2hpbGUgKGlwID4gMCkgeworICAgICAgICBpcC0tOworCisgICAgICAgIGNvbnN0IFBhY2thZ2UqIGNvbnN0IHBhY2thZ2UgPSBncnAtPnBhY2thZ2VzW2lwXTsKKworICAgICAgICBjb25zdCBSZXNUYWJsZV90eXBlKiB0eXBlOworICAgICAgICBjb25zdCBSZXNUYWJsZV9lbnRyeSogZW50cnk7CisgICAgICAgIGNvbnN0IFR5cGUqIHR5cGVDbGFzczsKKyAgICAgICAgc3NpemVfdCBvZmZzZXQgPSBnZXRFbnRyeShwYWNrYWdlLCB0LCBlLCAmbVBhcmFtcywgJnR5cGUsICZlbnRyeSwgJnR5cGVDbGFzcyk7CisgICAgICAgIGlmIChvZmZzZXQgPD0gMCkgeworICAgICAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJGYWlsdXJlIGdldHRpbmcgZW50cnkgZm9yIDB4JTA4eCAodD0lZCBlPSVkKSBpbiBwYWNrYWdlICVkOiAweCUwOHhcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICByZXNJRCwgdCwgZSwgKGludClpcCwgKGludClvZmZzZXQpOworICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoZHRvaHMoZW50cnktPmZsYWdzKSZlbnRyeS0+RkxBR19DT01QTEVYKSAhPSAwKSB7CisgICAgICAgICAgICBpZiAoIW1heUJlQmFnKSB7CisgICAgICAgICAgICAgICAgTE9HVygiUmVxdWVzdGluZyByZXNvdXJjZSAlcCBmYWlsZWQgYmVjYXVzZSBpdCBpcyBjb21wbGV4XG4iLAorICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKXJlc0lEKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgVEFCTEVfTk9JU1koYW91dCA8PCAiUmVzb3VyY2UgdHlwZSBkYXRhOiAiCisgICAgICAgICAgICAgIDw8IEhleER1bXAodHlwZSwgZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpKSA8PCBlbmRsKTsKKyAgICAgICAgCisgICAgICAgIGlmICgoc2l6ZV90KW9mZnNldCA+IChkdG9obCh0eXBlLT5oZWFkZXIuc2l6ZSktc2l6ZW9mKFJlc192YWx1ZSkpKSB7CisgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV9pdGVtIGF0ICVkIGlzIGJleW9uZCB0eXBlIGNodW5rIGRhdGEgJWQiLAorICAgICAgICAgICAgICAgICAoaW50KW9mZnNldCwgZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpKTsKKyAgICAgICAgICAgIHJldHVybiBCQURfVFlQRTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgY29uc3QgUmVzX3ZhbHVlKiBpdGVtID0KKyAgICAgICAgICAgIChjb25zdCBSZXNfdmFsdWUqKSgoKGNvbnN0IHVpbnQ4X3QqKXR5cGUpICsgb2Zmc2V0KTsKKyAgICAgICAgUmVzVGFibGVfY29uZmlnIHRoaXNDb25maWc7CisgICAgICAgIHRoaXNDb25maWcuY29weUZyb21EdG9IKHR5cGUtPmNvbmZpZyk7CisKKyAgICAgICAgaWYgKG91dFNwZWNGbGFncyAhPSBOVUxMKSB7CisgICAgICAgICAgICBpZiAodHlwZUNsYXNzLT50eXBlU3BlY0ZsYWdzICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAqb3V0U3BlY0ZsYWdzIHw9IGR0b2hsKHR5cGVDbGFzcy0+dHlwZVNwZWNGbGFnc1tlXSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICpvdXRTcGVjRmxhZ3MgPSAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaWYgKGJlc3RQYWNrYWdlICE9IE5VTEwgJiYgYmVzdEl0ZW0uaXNCZXR0ZXJUaGFuKHRoaXNDb25maWcpKSB7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgYmVzdEl0ZW0gPSB0aGlzQ29uZmlnOworICAgICAgICBiZXN0VmFsdWUgPSBpdGVtOworICAgICAgICBiZXN0UGFja2FnZSA9IHBhY2thZ2U7CisgICAgfQorCisgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJGb3VuZCByZXN1bHQ6IHBhY2thZ2UgJXBcbiIsIGJlc3RQYWNrYWdlKSk7CisKKyAgICBpZiAoYmVzdFZhbHVlKSB7CisgICAgICAgIG91dFZhbHVlLT5zaXplID0gZHRvaHMoYmVzdFZhbHVlLT5zaXplKTsKKyAgICAgICAgb3V0VmFsdWUtPnJlczAgPSBiZXN0VmFsdWUtPnJlczA7CisgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IGJlc3RWYWx1ZS0+ZGF0YVR5cGU7CisgICAgICAgIG91dFZhbHVlLT5kYXRhID0gZHRvaGwoYmVzdFZhbHVlLT5kYXRhKTsKKyAgICAgICAgaWYgKG91dENvbmZpZyAhPSBOVUxMKSB7CisgICAgICAgICAgICAqb3V0Q29uZmlnID0gYmVzdEl0ZW07CisgICAgICAgIH0KKyAgICAgICAgVEFCTEVfTk9JU1koc2l6ZV90IGxlbjsKKyAgICAgICAgICAgICAgcHJpbnRmKCJGb3VuZCB2YWx1ZTogcGtnPSVkLCB0eXBlPSVkLCBzdHI9JXMsIGludD0lZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgIGJlc3RQYWNrYWdlLT5oZWFkZXItPmluZGV4LAorICAgICAgICAgICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlLAorICAgICAgICAgICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID09IGJlc3RWYWx1ZS0+VFlQRV9TVFJJTkcKKyAgICAgICAgICAgICAgICAgICAgID8gU3RyaW5nOChiZXN0UGFja2FnZS0+aGVhZGVyLT52YWx1ZXMuc3RyaW5nQXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGEsICZsZW4pKS5zdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgOiAiIiwKKyAgICAgICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhKSk7CisgICAgICAgIHJldHVybiBiZXN0UGFja2FnZS0+aGVhZGVyLT5pbmRleDsKKyAgICB9CisKKyAgICByZXR1cm4gQkFEX0lOREVYOworfQorCitzc2l6ZV90IFJlc1RhYmxlOjpyZXNvbHZlUmVmZXJlbmNlKFJlc192YWx1ZSogdmFsdWUsIHNzaXplX3QgYmxvY2tJbmRleCwKKyAgICAgICAgdWludDMyX3QqIG91dExhc3RSZWYsIHVpbnQzMl90KiBpbm91dFR5cGVTcGVjRmxhZ3MpIGNvbnN0Cit7CisgICAgaW50IGNvdW50PTA7CisgICAgd2hpbGUgKGJsb2NrSW5kZXggPj0gMCAmJiB2YWx1ZS0+ZGF0YVR5cGUgPT0gdmFsdWUtPlRZUEVfUkVGRVJFTkNFCisgICAgICAgICAgICYmIHZhbHVlLT5kYXRhICE9IDAgJiYgY291bnQgPCAyMCkgeworICAgICAgICBpZiAob3V0TGFzdFJlZikgKm91dExhc3RSZWYgPSB2YWx1ZS0+ZGF0YTsKKyAgICAgICAgdWludDMyX3QgbGFzdFJlZiA9IHZhbHVlLT5kYXRhOworICAgICAgICB1aW50MzJfdCBuZXdGbGFncyA9IDA7CisgICAgICAgIGNvbnN0IHNzaXplX3QgbmV3SW5kZXggPSBnZXRSZXNvdXJjZSh2YWx1ZS0+ZGF0YSwgdmFsdWUsIHRydWUsICZuZXdGbGFncyk7CisgICAgICAgIC8vTE9HSSgiUmVzb2x2aW5nIHJlZmVyZW5jZSBkPSVwOiBuZXdJbmRleD0lZCwgdD0weCUwMngsIGQ9JXBcbiIsCisgICAgICAgIC8vICAgICAodm9pZCopbGFzdFJlZiwgKGludCluZXdJbmRleCwgKGludCl2YWx1ZS0+ZGF0YVR5cGUsICh2b2lkKil2YWx1ZS0+ZGF0YSk7CisgICAgICAgIC8vcHJpbnRmKCJHZXR0aW5nIHJlZmVyZW5jZSAweCUwOHg6IG5ld0luZGV4PSVkXG4iLCB2YWx1ZS0+ZGF0YSwgbmV3SW5kZXgpOworICAgICAgICBpZiAoaW5vdXRUeXBlU3BlY0ZsYWdzICE9IE5VTEwpICppbm91dFR5cGVTcGVjRmxhZ3MgfD0gbmV3RmxhZ3M7CisgICAgICAgIGlmIChuZXdJbmRleCA8IDApIHsKKyAgICAgICAgICAgIC8vIFRoaXMgY2FuIGZhaWwgaWYgdGhlIHJlc291cmNlIGJlaW5nIHJlZmVyZW5jZWQgaXMgYSBzdHlsZS4uLgorICAgICAgICAgICAgLy8gaW4gdGhpcyBjYXNlLCBqdXN0IHJldHVybiB0aGUgcmVmZXJlbmNlLCBhbmQgZXhwZWN0IHRoZQorICAgICAgICAgICAgLy8gY2FsbGVyIHRvIGRlYWwgd2l0aC4KKyAgICAgICAgICAgIHJldHVybiBibG9ja0luZGV4OworICAgICAgICB9CisgICAgICAgIGJsb2NrSW5kZXggPSBuZXdJbmRleDsKKyAgICAgICAgY291bnQrKzsKKyAgICB9CisgICAgcmV0dXJuIGJsb2NrSW5kZXg7Cit9CisKK2NvbnN0IGNoYXIxNl90KiBSZXNUYWJsZTo6dmFsdWVUb1N0cmluZygKKyAgICBjb25zdCBSZXNfdmFsdWUqIHZhbHVlLCBzaXplX3Qgc3RyaW5nQmxvY2ssCisgICAgY2hhcjE2X3QgdG1wQnVmZmVyW1RNUF9CVUZGRVJfU0laRV0sIHNpemVfdCogb3V0TGVuKQoreworICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICh2YWx1ZS0+ZGF0YVR5cGUgPT0gdmFsdWUtPlRZUEVfU1RSSU5HKSB7CisgICAgICAgIHJldHVybiBnZXRUYWJsZVN0cmluZ0Jsb2NrKHN0cmluZ0Jsb2NrKS0+c3RyaW5nQXQodmFsdWUtPmRhdGEsIG91dExlbik7CisgICAgfQorICAgIC8vIFhYWCBkbyBpbnQgdG8gc3RyaW5nIGNvbnZlcnNpb25zLgorICAgIHJldHVybiBOVUxMOworfQorCitzc2l6ZV90IFJlc1RhYmxlOjpsb2NrQmFnKHVpbnQzMl90IHJlc0lELCBjb25zdCBiYWdfZW50cnkqKiBvdXRCYWcpIGNvbnN0Cit7CisgICAgbUxvY2subG9jaygpOworICAgIHNzaXplX3QgZXJyID0gZ2V0QmFnTG9ja2VkKHJlc0lELCBvdXRCYWcpOworICAgIGlmIChlcnIgPCBOT19FUlJPUikgeworICAgICAgICAvL3ByaW50ZigiKioqIGdldCBmYWlsZWQhICB1bmxvY2tpbmdcbiIpOworICAgICAgICBtTG9jay51bmxvY2soKTsKKyAgICB9CisgICAgcmV0dXJuIGVycjsKK30KKwordm9pZCBSZXNUYWJsZTo6dW5sb2NrQmFnKGNvbnN0IGJhZ19lbnRyeSogYmFnKSBjb25zdAoreworICAgIC8vcHJpbnRmKCI8PDwgdW5sb2NrQmFnICVwXG4iLCB0aGlzKTsKKyAgICBtTG9jay51bmxvY2soKTsKK30KKwordm9pZCBSZXNUYWJsZTo6bG9jaygpIGNvbnN0Cit7CisgICAgbUxvY2subG9jaygpOworfQorCit2b2lkIFJlc1RhYmxlOjp1bmxvY2soKSBjb25zdAoreworICAgIG1Mb2NrLnVubG9jaygpOworfQorCitzc2l6ZV90IFJlc1RhYmxlOjpnZXRCYWdMb2NrZWQodWludDMyX3QgcmVzSUQsIGNvbnN0IGJhZ19lbnRyeSoqIG91dEJhZywKKyAgICAgICAgdWludDMyX3QqIG91dFR5cGVTcGVjRmxhZ3MpIGNvbnN0Cit7CisgICAgaWYgKG1FcnJvciAhPSBOT19FUlJPUikgeworICAgICAgICByZXR1cm4gbUVycm9yOworICAgIH0KKworICAgIGNvbnN0IHNzaXplX3QgcCA9IGdldFJlc291cmNlUGFja2FnZUluZGV4KHJlc0lEKTsKKyAgICBjb25zdCBpbnQgdCA9IFJlc19HRVRUWVBFKHJlc0lEKTsKKyAgICBjb25zdCBpbnQgZSA9IFJlc19HRVRFTlRSWShyZXNJRCk7CisKKyAgICBpZiAocCA8IDApIHsKKyAgICAgICAgTE9HVygiSW52YWxpZCBwYWNrYWdlIGlkZW50aWZpZXIgd2hlbiBnZXR0aW5nIGJhZyBmb3IgcmVzb3VyY2UgbnVtYmVyIDB4JTA4eCIsIHJlc0lEKTsKKyAgICAgICAgcmV0dXJuIEJBRF9JTkRFWDsKKyAgICB9CisgICAgaWYgKHQgPCAwKSB7CisgICAgICAgIExPR1coIk5vIHR5cGUgaWRlbnRpZmllciB3aGVuIGdldHRpbmcgYmFnIGZvciByZXNvdXJjZSBudW1iZXIgMHglMDh4IiwgcmVzSUQpOworICAgICAgICByZXR1cm4gQkFEX0lOREVYOworICAgIH0KKworICAgIC8vcHJpbnRmKCJHZXQgYmFnOiBpZD0weCUwOHgsIHA9JWQsIHQ9JWRcbiIsIHJlc0lELCBwLCB0KTsKKyAgICBQYWNrYWdlR3JvdXAqIGNvbnN0IGdycCA9IG1QYWNrYWdlR3JvdXBzW3BdOworICAgIGlmIChncnAgPT0gTlVMTCkgeworICAgICAgICBMT0dXKCJCYWQgaWRlbnRpZmllciB3aGVuIGdldHRpbmcgYmFnIGZvciByZXNvdXJjZSBudW1iZXIgMHglMDh4IiwgcmVzSUQpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKHQgPj0gKGludClncnAtPnR5cGVDb3VudCkgeworICAgICAgICBMT0dXKCJUeXBlIGlkZW50aWZpZXIgMHgleCBpcyBsYXJnZXIgdGhhbiB0eXBlIGNvdW50IDB4JXgiLAorICAgICAgICAgICAgIHQrMSwgKGludClncnAtPnR5cGVDb3VudCk7CisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgfQorCisgICAgY29uc3QgUGFja2FnZSogY29uc3QgYmFzZVBhY2thZ2UgPSBncnAtPnBhY2thZ2VzWzBdOworCisgICAgY29uc3QgVHlwZSogY29uc3QgdHlwZUNvbmZpZ3MgPSBiYXNlUGFja2FnZS0+Z2V0VHlwZSh0KTsKKworICAgIGNvbnN0IHNpemVfdCBORU5UUlkgPSB0eXBlQ29uZmlncy0+ZW50cnlDb3VudDsKKyAgICBpZiAoZSA+PSAoaW50KU5FTlRSWSkgeworICAgICAgICBMT0dXKCJFbnRyeSBpZGVudGlmaWVyIDB4JXggaXMgbGFyZ2VyIHRoYW4gZW50cnkgY291bnQgMHgleCIsCisgICAgICAgICAgICAgZSwgKGludCl0eXBlQ29uZmlncy0+ZW50cnlDb3VudCk7CisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgfQorCisgICAgLy8gRmlyc3Qgc2VlIGlmIHdlJ3ZlIGFscmVhZHkgY29tcHV0ZWQgdGhpcyBiYWcuLi4KKyAgICBpZiAoZ3JwLT5iYWdzKSB7CisgICAgICAgIGJhZ19zZXQqKiB0eXBlU2V0ID0gZ3JwLT5iYWdzW3RdOworICAgICAgICBpZiAodHlwZVNldCkgeworICAgICAgICAgICAgYmFnX3NldCogc2V0ID0gdHlwZVNldFtlXTsKKyAgICAgICAgICAgIGlmIChzZXQpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2V0ICE9IChiYWdfc2V0KikweEZGRkZGRkZGKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChvdXRUeXBlU3BlY0ZsYWdzICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXRUeXBlU3BlY0ZsYWdzID0gc2V0LT50eXBlU3BlY0ZsYWdzOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICpvdXRCYWcgPSAoYmFnX2VudHJ5Kikoc2V0KzEpOworICAgICAgICAgICAgICAgICAgICAvL0xPR0koIkZvdW5kIGV4aXN0aW5nIGJhZyBmb3I6ICVwXG4iLCAodm9pZCopcmVzSUQpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2V0LT5udW1BdHRyczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTE9HVygiQXR0ZW1wdCB0byByZXRyaWV2ZSBiYWcgMHglMDh4IHdoaWNoIGlzIGludmFsaWQgb3IgaW4gYSBjeWNsZS4iLAorICAgICAgICAgICAgICAgICAgICAgcmVzSUQpOworICAgICAgICAgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBCYWcgbm90IGZvdW5kLCB3ZSBuZWVkIHRvIGNvbXB1dGUgaXQhCisgICAgaWYgKCFncnAtPmJhZ3MpIHsKKyAgICAgICAgZ3JwLT5iYWdzID0gKGJhZ19zZXQqKiopbWFsbG9jKHNpemVvZihiYWdfc2V0KikqZ3JwLT50eXBlQ291bnQpOworICAgICAgICBpZiAoIWdycC0+YmFncykgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgbWVtc2V0KGdycC0+YmFncywgMCwgc2l6ZW9mKGJhZ19zZXQqKSpncnAtPnR5cGVDb3VudCk7CisgICAgfQorCisgICAgYmFnX3NldCoqIHR5cGVTZXQgPSBncnAtPmJhZ3NbdF07CisgICAgaWYgKCF0eXBlU2V0KSB7CisgICAgICAgIHR5cGVTZXQgPSAoYmFnX3NldCoqKW1hbGxvYyhzaXplb2YoYmFnX3NldCopKk5FTlRSWSk7CisgICAgICAgIGlmICghdHlwZVNldCkgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgbWVtc2V0KHR5cGVTZXQsIDAsIHNpemVvZihiYWdfc2V0KikqTkVOVFJZKTsKKyAgICAgICAgZ3JwLT5iYWdzW3RdID0gdHlwZVNldDsKKyAgICB9CisKKyAgICAvLyBNYXJrIHRoYXQgd2UgYXJlIGN1cnJlbnRseSB3b3JraW5nIG9uIHRoaXMgb25lLgorICAgIHR5cGVTZXRbZV0gPSAoYmFnX3NldCopMHhGRkZGRkZGRjsKKworICAgIC8vIFRoaXMgaXMgd2hhdCB3ZSBhcmUgYnVpbGRpbmcuCisgICAgYmFnX3NldCogc2V0ID0gTlVMTDsKKworICAgIFRBQkxFX05PSVNZKExPR0koIkJ1aWxkaW5nIGJhZzogJXBcbiIsICh2b2lkKilyZXNJRCkpOworICAgIAorICAgIC8vIE5vdyBjb2xsZWN0IGFsbCBiYWcgYXR0cmlidXRlcyBmcm9tIGFsbCBwYWNrYWdlcy4KKyAgICBzaXplX3QgaXAgPSBncnAtPnBhY2thZ2VzLnNpemUoKTsKKyAgICB3aGlsZSAoaXAgPiAwKSB7CisgICAgICAgIGlwLS07CisKKyAgICAgICAgY29uc3QgUGFja2FnZSogY29uc3QgcGFja2FnZSA9IGdycC0+cGFja2FnZXNbaXBdOworCisgICAgICAgIGNvbnN0IFJlc1RhYmxlX3R5cGUqIHR5cGU7CisgICAgICAgIGNvbnN0IFJlc1RhYmxlX2VudHJ5KiBlbnRyeTsKKyAgICAgICAgY29uc3QgVHlwZSogdHlwZUNsYXNzOworICAgICAgICBMT0dWKCJHZXR0aW5nIGVudHJ5IHBrZz0lcCwgdD0lZCwgZT0lZFxuIiwgcGFja2FnZSwgdCwgZSk7CisgICAgICAgIHNzaXplX3Qgb2Zmc2V0ID0gZ2V0RW50cnkocGFja2FnZSwgdCwgZSwgJm1QYXJhbXMsICZ0eXBlLCAmZW50cnksICZ0eXBlQ2xhc3MpOworICAgICAgICBMT0dWKCJSZXN1bHRpbmcgb2Zmc2V0PSVkXG4iLCBvZmZzZXQpOworICAgICAgICBpZiAob2Zmc2V0IDw9IDApIHsKKyAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICAgICAgaWYgKHNldCkgZnJlZShzZXQpOworICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoZHRvaHMoZW50cnktPmZsYWdzKSZlbnRyeS0+RkxBR19DT01QTEVYKSA9PSAwKSB7CisgICAgICAgICAgICBMT0dXKCJTa2lwcGluZyBlbnRyeSAlcCBpbiBwYWNrYWdlIHRhYmxlICVkIGJlY2F1c2UgaXQgaXMgbm90IGNvbXBsZXghXG4iLAorICAgICAgICAgICAgICAgICAodm9pZCopcmVzSUQsIChpbnQpaXApOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBjb25zdCB1aW50MTZfdCBlbnRyeVNpemUgPSBkdG9ocyhlbnRyeS0+c2l6ZSk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IHBhcmVudCA9IGVudHJ5U2l6ZSA+PSBzaXplb2YoUmVzVGFibGVfbWFwX2VudHJ5KQorICAgICAgICAgICAgPyBkdG9obCgoKGNvbnN0IFJlc1RhYmxlX21hcF9lbnRyeSopZW50cnkpLT5wYXJlbnQuaWRlbnQpIDogMDsKKyAgICAgICAgY29uc3QgdWludDMyX3QgY291bnQgPSBlbnRyeVNpemUgPj0gc2l6ZW9mKFJlc1RhYmxlX21hcF9lbnRyeSkKKyAgICAgICAgICAgID8gZHRvaGwoKChjb25zdCBSZXNUYWJsZV9tYXBfZW50cnkqKWVudHJ5KS0+Y291bnQpIDogMDsKKyAgICAgICAgCisgICAgICAgIHNpemVfdCBOID0gY291bnQ7CisKKyAgICAgICAgVEFCTEVfTk9JU1koTE9HSSgiRm91bmQgbWFwOiBzaXplPSVwIHBhcmVudD0lcCBjb3VudD0lZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeVNpemUsIHBhcmVudCwgY291bnQpKTsKKworICAgICAgICBpZiAoc2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIC8vIElmIHRoaXMgbWFwIGluaGVyaXRzIGZyb20gYW5vdGhlciwgd2UgbmVlZCB0byBzdGFydAorICAgICAgICAgICAgLy8gd2l0aCBpdHMgcGFyZW50J3MgdmFsdWVzLiAgT3RoZXJ3aXNlIHN0YXJ0IG91dCBlbXB0eS4KKyAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiQ3JlYXRpbmcgbmV3IGJhZywgZW50cnlTaXplPTB4JTA4eCwgcGFyZW50PTB4JTA4eFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeVNpemUsIHBhcmVudCkpOworICAgICAgICAgICAgaWYgKHBhcmVudCkgeworICAgICAgICAgICAgICAgIGNvbnN0IGJhZ19lbnRyeSogcGFyZW50QmFnOworICAgICAgICAgICAgICAgIHVpbnQzMl90IHBhcmVudFR5cGVTcGVjRmxhZ3MgPSAwOworICAgICAgICAgICAgICAgIGNvbnN0IHNzaXplX3QgTlAgPSBnZXRCYWdMb2NrZWQocGFyZW50LCAmcGFyZW50QmFnLCAmcGFyZW50VHlwZVNwZWNGbGFncyk7CisgICAgICAgICAgICAgICAgY29uc3Qgc2l6ZV90IE5UID0gKChOUCA+PSAwKSA/IE5QIDogMCkgKyBOOworICAgICAgICAgICAgICAgIHNldCA9IChiYWdfc2V0KiltYWxsb2Moc2l6ZW9mKGJhZ19zZXQpK3NpemVvZihiYWdfZW50cnkpKk5UKTsKKyAgICAgICAgICAgICAgICBpZiAoc2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKE5QID4gMCkgeworICAgICAgICAgICAgICAgICAgICBtZW1jcHkoc2V0KzEsIHBhcmVudEJhZywgTlAqc2l6ZW9mKGJhZ19lbnRyeSkpOworICAgICAgICAgICAgICAgICAgICBzZXQtPm51bUF0dHJzID0gTlA7CisgICAgICAgICAgICAgICAgICAgIFRBQkxFX05PSVNZKExPR0koIkluaXRpYWxpemVkIG5ldyBiYWcgd2l0aCAlZCBpbmhlcml0ZWQgYXR0cmlidXRlcy5cbiIsIE5QKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgVEFCTEVfTk9JU1koTE9HSSgiSW5pdGlhbGl6ZWQgbmV3IGJhZyB3aXRoIG5vIGluaGVyaXRlZCBhdHRyaWJ1dGVzLlxuIikpOworICAgICAgICAgICAgICAgICAgICBzZXQtPm51bUF0dHJzID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2V0LT5hdmFpbEF0dHJzID0gTlQ7CisgICAgICAgICAgICAgICAgc2V0LT50eXBlU3BlY0ZsYWdzID0gcGFyZW50VHlwZVNwZWNGbGFnczsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2V0ID0gKGJhZ19zZXQqKW1hbGxvYyhzaXplb2YoYmFnX3NldCkrc2l6ZW9mKGJhZ19lbnRyeSkqTik7CisgICAgICAgICAgICAgICAgaWYgKHNldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNldC0+bnVtQXR0cnMgPSAwOworICAgICAgICAgICAgICAgIHNldC0+YXZhaWxBdHRycyA9IE47CisgICAgICAgICAgICAgICAgc2V0LT50eXBlU3BlY0ZsYWdzID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh0eXBlQ2xhc3MtPnR5cGVTcGVjRmxhZ3MgIT0gTlVMTCkgeworICAgICAgICAgICAgc2V0LT50eXBlU3BlY0ZsYWdzIHw9IGR0b2hsKHR5cGVDbGFzcy0+dHlwZVNwZWNGbGFnc1tlXSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXQtPnR5cGVTcGVjRmxhZ3MgPSAtMTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gTm93IG1lcmdlIGluIHRoZSBuZXcgYXR0cmlidXRlcy4uLgorICAgICAgICBzc2l6ZV90IGN1ck9mZiA9IG9mZnNldDsKKyAgICAgICAgY29uc3QgUmVzVGFibGVfbWFwKiBtYXA7CisgICAgICAgIGJhZ19lbnRyeSogZW50cmllcyA9IChiYWdfZW50cnkqKShzZXQrMSk7CisgICAgICAgIHNpemVfdCBjdXJFbnRyeSA9IDA7CisgICAgICAgIHVpbnQzMl90IHBvcyA9IDA7CisgICAgICAgIFRBQkxFX05PSVNZKExPR0koIlN0YXJ0aW5nIHdpdGggc2V0ICVwLCBlbnRyaWVzPSVwLCBhdmFpbD0lZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgIHNldCwgZW50cmllcywgc2V0LT5hdmFpbEF0dHJzKSk7CisgICAgICAgIHdoaWxlIChwb3MgPCBjb3VudCkgeworICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJOb3cgYXQgJXBcbiIsICh2b2lkKiljdXJPZmYpKTsKKworICAgICAgICAgICAgaWYgKChzaXplX3QpY3VyT2ZmID4gKGR0b2hsKHR5cGUtPmhlYWRlci5zaXplKS1zaXplb2YoUmVzVGFibGVfbWFwKSkpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV9tYXAgYXQgJWQgaXMgYmV5b25kIHR5cGUgY2h1bmsgZGF0YSAlZCIsCisgICAgICAgICAgICAgICAgICAgICAoaW50KWN1ck9mZiwgZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gQkFEX1RZUEU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtYXAgPSAoY29uc3QgUmVzVGFibGVfbWFwKikoKChjb25zdCB1aW50OF90Kil0eXBlKSArIGN1ck9mZik7CisgICAgICAgICAgICBOKys7CisKKyAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90IG5ld05hbWUgPSBodG9kbChtYXAtPm5hbWUuaWRlbnQpOworICAgICAgICAgICAgYm9vbCBpc0luc2lkZTsKKyAgICAgICAgICAgIHVpbnQzMl90IG9sZE5hbWUgPSAwOworICAgICAgICAgICAgd2hpbGUgKChpc0luc2lkZT0oY3VyRW50cnkgPCBzZXQtPm51bUF0dHJzKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgKG9sZE5hbWU9ZW50cmllc1tjdXJFbnRyeV0ubWFwLm5hbWUuaWRlbnQpIDwgbmV3TmFtZSkgeworICAgICAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiIyVkOiBLZWVwaW5nIGV4aXN0aW5nIGF0dHJpYnV0ZTogMHglMDh4XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJFbnRyeSwgZW50cmllc1tjdXJFbnRyeV0ubWFwLm5hbWUuaWRlbnQpKTsKKyAgICAgICAgICAgICAgICBjdXJFbnRyeSsrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoKCFpc0luc2lkZSkgfHwgb2xkTmFtZSAhPSBuZXdOYW1lKSB7CisgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIG5ldyBhdHRyaWJ1dGUuLi4gIGZpZ3VyZSBvdXQgd2hhdCB0byBkbyB3aXRoIGl0LgorICAgICAgICAgICAgICAgIGlmIChzZXQtPm51bUF0dHJzID49IHNldC0+YXZhaWxBdHRycykgeworICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIGFsbG9jIG1vcmUgbWVtb3J5Li4uCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCBuZXdBdmFpbCA9IHNldC0+YXZhaWxBdHRycytOOworICAgICAgICAgICAgICAgICAgICBzZXQgPSAoYmFnX3NldCopcmVhbGxvYyhzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihiYWdfc2V0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNpemVvZihiYWdfZW50cnkpKm5ld0F2YWlsKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNldC0+YXZhaWxBdHRycyA9IG5ld0F2YWlsOworICAgICAgICAgICAgICAgICAgICBlbnRyaWVzID0gKGJhZ19lbnRyeSopKHNldCsxKTsKKyAgICAgICAgICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJSZWFsbG9jYXRlZCBzZXQgJXAsIGVudHJpZXM9JXAsIGF2YWlsPSVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0LCBlbnRyaWVzLCBzZXQtPmF2YWlsQXR0cnMpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGlzSW5zaWRlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEdvaW5nIGluIHRoZSBtaWRkbGUsIG5lZWQgdG8gbWFrZSBzcGFjZS4KKyAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShlbnRyaWVzK2N1ckVudHJ5KzEsIGVudHJpZXMrY3VyRW50cnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGJhZ19lbnRyeSkqKHNldC0+bnVtQXR0cnMtY3VyRW50cnkpKTsKKyAgICAgICAgICAgICAgICAgICAgc2V0LT5udW1BdHRycysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoIiMlZDogSW5zZXJ0aW5nIG5ldyBhdHRyaWJ1dGU6IDB4JTA4eFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyRW50cnksIG5ld05hbWUpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCIjJWQ6IFJlcGxhY2luZyBleGlzdGluZyBhdHRyaWJ1dGU6IDB4JTA4eFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyRW50cnksIG9sZE5hbWUpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYmFnX2VudHJ5KiBjdXIgPSBlbnRyaWVzK2N1ckVudHJ5OworCisgICAgICAgICAgICBjdXItPnN0cmluZ0Jsb2NrID0gcGFja2FnZS0+aGVhZGVyLT5pbmRleDsKKyAgICAgICAgICAgIGN1ci0+bWFwLm5hbWUuaWRlbnQgPSBuZXdOYW1lOworICAgICAgICAgICAgY3VyLT5tYXAudmFsdWUuY29weUZyb21fZHRvaChtYXAtPnZhbHVlKTsKKyAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiU2V0dGluZyBlbnRyeSAjJWQgJXA6IGJsb2NrPSVkLCBuYW1lPTB4JTA4eCwgdHlwZT0lZCwgZGF0YT0weCUwOHhcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgY3VyRW50cnksIGN1ciwgY3VyLT5zdHJpbmdCbG9jaywgY3VyLT5tYXAubmFtZS5pZGVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjdXItPm1hcC52YWx1ZS5kYXRhVHlwZSwgY3VyLT5tYXAudmFsdWUuZGF0YSkpOworCisgICAgICAgICAgICAvLyBPbiB0byB0aGUgbmV4dCEKKyAgICAgICAgICAgIGN1ckVudHJ5Kys7CisgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgIGNvbnN0IHNpemVfdCBzaXplID0gZHRvaHMobWFwLT52YWx1ZS5zaXplKTsKKyAgICAgICAgICAgIGN1ck9mZiArPSBzaXplICsgc2l6ZW9mKCptYXApLXNpemVvZihtYXAtPnZhbHVlKTsKKyAgICAgICAgfTsKKyAgICAgICAgaWYgKGN1ckVudHJ5ID4gc2V0LT5udW1BdHRycykgeworICAgICAgICAgICAgc2V0LT5udW1BdHRycyA9IGN1ckVudHJ5OworICAgICAgICB9CisgICAgfQorCisgICAgLy8gQW5kIHRoaXMgaXMgaXQuLi4KKyAgICB0eXBlU2V0W2VdID0gc2V0OworICAgIGlmIChzZXQpIHsKKyAgICAgICAgaWYgKG91dFR5cGVTcGVjRmxhZ3MgIT0gTlVMTCkgeworICAgICAgICAgICAgKm91dFR5cGVTcGVjRmxhZ3MgPSBzZXQtPnR5cGVTcGVjRmxhZ3M7CisgICAgICAgIH0KKyAgICAgICAgKm91dEJhZyA9IChiYWdfZW50cnkqKShzZXQrMSk7CisgICAgICAgIFRBQkxFX05PSVNZKExPR0koIlJldHVybmluZyAlZCBhdHRyc1xuIiwgc2V0LT5udW1BdHRycykpOworICAgICAgICByZXR1cm4gc2V0LT5udW1BdHRyczsKKyAgICB9CisgICAgcmV0dXJuIEJBRF9JTkRFWDsKK30KKwordm9pZCBSZXNUYWJsZTo6c2V0UGFyYW1ldGVycyhjb25zdCBSZXNUYWJsZV9jb25maWcqIHBhcmFtcykKK3sKKyAgICBtTG9jay5sb2NrKCk7CisgICAgVEFCTEVfR0VURU5UUlkoTE9HSSgiU2V0dGluZyBwYXJhbWV0ZXJzOiBpbXNpOiVkLyVkIGxhbmc6JWMlYyBjbnQ6JWMlYyAiCisgICAgICAgICAgICAgICAgICAgICAgICAib3JpZW46JWQgdG91Y2g6JWQgZGVuc2l0eTolZCBrZXk6JWQgaW5wOiVkIG5hdjolZCB3OiVkIGg6JWRcbiIsCisgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+bWNjLCBwYXJhbXMtPm1uYywKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5sYW5ndWFnZVswXSA/IHBhcmFtcy0+bGFuZ3VhZ2VbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+bGFuZ3VhZ2VbMV0gPyBwYXJhbXMtPmxhbmd1YWdlWzFdIDogJy0nLAorICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmNvdW50cnlbMF0gPyBwYXJhbXMtPmNvdW50cnlbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+Y291bnRyeVsxXSA/IHBhcmFtcy0+Y291bnRyeVsxXSA6ICctJywKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5vcmllbnRhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT50b3VjaHNjcmVlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5kZW5zaXR5LAorICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmtleWJvYXJkLAorICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmlucHV0RmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+bmF2aWdhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5zY3JlZW5XaWR0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5zY3JlZW5IZWlnaHQpKTsKKyAgICBtUGFyYW1zID0gKnBhcmFtczsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8bVBhY2thZ2VHcm91cHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgVEFCTEVfTk9JU1koTE9HSSgiQ0xFQVJJTkcgQkFHUyBGT1IgR1JPVVAgJWQhIiwgaSkpOworICAgICAgICBtUGFja2FnZUdyb3Vwc1tpXS0+Y2xlYXJCYWdDYWNoZSgpOworICAgIH0KKyAgICBtTG9jay51bmxvY2soKTsKK30KKwordm9pZCBSZXNUYWJsZTo6Z2V0UGFyYW1ldGVycyhSZXNUYWJsZV9jb25maWcqIHBhcmFtcykgY29uc3QKK3sKKyAgICBtTG9jay5sb2NrKCk7CisgICAgKnBhcmFtcyA9IG1QYXJhbXM7CisgICAgbUxvY2sudW5sb2NrKCk7Cit9CisKK3N0cnVjdCBpZF9uYW1lX21hcCB7CisgICAgdWludDMyX3QgaWQ7CisgICAgc2l6ZV90IGxlbjsKKyAgICBjaGFyMTZfdCBuYW1lWzZdOworfTsKKworY29uc3Qgc3RhdGljIGlkX25hbWVfbWFwIElEX05BTUVTW10gPSB7CisgICAgeyBSZXNUYWJsZV9tYXA6OkFUVFJfVFlQRSwgIDUsIHsgJ14nLCAndCcsICd5JywgJ3AnLCAnZScgfSB9LAorICAgIHsgUmVzVGFibGVfbWFwOjpBVFRSX0wxME4sICA1LCB7ICdeJywgJ2wnLCAnMScsICcwJywgJ24nIH0gfSwKKyAgICB7IFJlc1RhYmxlX21hcDo6QVRUUl9NSU4sICAgNCwgeyAnXicsICdtJywgJ2knLCAnbicgfSB9LAorICAgIHsgUmVzVGFibGVfbWFwOjpBVFRSX01BWCwgICA0LCB7ICdeJywgJ20nLCAnYScsICd4JyB9IH0sCisgICAgeyBSZXNUYWJsZV9tYXA6OkFUVFJfT1RIRVIsIDYsIHsgJ14nLCAnbycsICd0JywgJ2gnLCAnZScsICdyJyB9IH0sCisgICAgeyBSZXNUYWJsZV9tYXA6OkFUVFJfWkVSTywgIDUsIHsgJ14nLCAneicsICdlJywgJ3InLCAnbycgfSB9LAorICAgIHsgUmVzVGFibGVfbWFwOjpBVFRSX09ORSwgICA0LCB7ICdeJywgJ28nLCAnbicsICdlJyB9IH0sCisgICAgeyBSZXNUYWJsZV9tYXA6OkFUVFJfVFdPLCAgIDQsIHsgJ14nLCAndCcsICd3JywgJ28nIH0gfSwKKyAgICB7IFJlc1RhYmxlX21hcDo6QVRUUl9GRVcsICAgNCwgeyAnXicsICdmJywgJ2UnLCAndycgfSB9LAorICAgIHsgUmVzVGFibGVfbWFwOjpBVFRSX01BTlksICA1LCB7ICdeJywgJ20nLCAnYScsICduJywgJ3knIH0gfSwKK307CisKK3VpbnQzMl90IFJlc1RhYmxlOjppZGVudGlmaWVyRm9yTmFtZShjb25zdCBjaGFyMTZfdCogbmFtZSwgc2l6ZV90IG5hbWVMZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIHR5cGUsIHNpemVfdCB0eXBlTGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBwYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBwYWNrYWdlTGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90KiBvdXRUeXBlU3BlY0ZsYWdzKSBjb25zdAoreworICAgIFRBQkxFX1NVUEVSX05PSVNZKHByaW50ZigiSWRlbnRpZmllciBmb3IgbmFtZTogZXJyb3I9JWRcbiIsIG1FcnJvcikpOworCisgICAgLy8gQ2hlY2sgZm9yIGludGVybmFsIHJlc291cmNlIGlkZW50aWZpZXIgYXMgdGhlIHZlcnkgZmlyc3QgdGhpbmcsIHNvCisgICAgLy8gdGhhdCB3ZSB3aWxsIGFsd2F5cyBmaW5kIHRoZW0gZXZlbiB3aGVuIHRoZXJlIGFyZSBubyByZXNvdXJjZXMuCisgICAgaWYgKG5hbWVbMF0gPT0gJ14nKSB7CisgICAgICAgIGNvbnN0IGludCBOID0gKHNpemVvZihJRF9OQU1FUykvc2l6ZW9mKElEX05BTUVTWzBdKSk7CisgICAgICAgIHNpemVfdCBsZW47CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgICAgIGNvbnN0IGlkX25hbWVfbWFwKiBtID0gSURfTkFNRVMgKyBpOworICAgICAgICAgICAgbGVuID0gbS0+bGVuOworICAgICAgICAgICAgaWYgKGxlbiAhPSBuYW1lTGVuKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKHNpemVfdCBqPTE7IGo8bGVuOyBqKyspIHsKKyAgICAgICAgICAgICAgICBpZiAobS0+bmFtZVtqXSAhPSBuYW1lW2pdKSB7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gbm9wZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbS0+aWQ7Citub3BlOgorICAgICAgICAgICAgOworICAgICAgICB9CisgICAgICAgIGlmIChuYW1lTGVuID4gNykgeworICAgICAgICAgICAgaWYgKG5hbWVbMV0gPT0gJ2knICYmIG5hbWVbMl0gPT0gJ24nCisgICAgICAgICAgICAgICAgJiYgbmFtZVszXSA9PSAnZCcgJiYgbmFtZVs0XSA9PSAnZScgJiYgbmFtZVs1XSA9PSAneCcKKyAgICAgICAgICAgICAgICAmJiBuYW1lWzZdID09ICdfJykgeworICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGF0b2koU3RyaW5nOChuYW1lICsgNywgbmFtZUxlbiAtIDcpLnN0cmluZygpKTsKKyAgICAgICAgICAgICAgICBpZiAoUmVzX0NIRUNLSUQoaW5kZXgpKSB7CisgICAgICAgICAgICAgICAgICAgIExPR1coIkFycmF5IHJlc291cmNlIGluZGV4OiAlZCBpcyB0b28gbGFyZ2UuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gIFJlc19NQUtFQVJSQVkoaW5kZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmIChtRXJyb3IgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gRmlndXJlIG91dCB0aGUgcGFja2FnZSBhbmQgdHlwZSB3ZSBhcmUgbG9va2luZyBpbi4uLgorCisgICAgY29uc3QgY2hhcjE2X3QqIHBhY2thZ2VFbmQgPSBOVUxMOworICAgIGNvbnN0IGNoYXIxNl90KiB0eXBlRW5kID0gTlVMTDsKKyAgICBjb25zdCBjaGFyMTZfdCogY29uc3QgbmFtZUVuZCA9IG5hbWUrbmFtZUxlbjsKKyAgICBjb25zdCBjaGFyMTZfdCogcCA9IG5hbWU7CisgICAgd2hpbGUgKHAgPCBuYW1lRW5kKSB7CisgICAgICAgIGlmICgqcCA9PSAnOicpIHBhY2thZ2VFbmQgPSBwOworICAgICAgICBlbHNlIGlmICgqcCA9PSAnLycpIHR5cGVFbmQgPSBwOworICAgICAgICBwKys7CisgICAgfQorICAgIGlmICgqbmFtZSA9PSAnQCcpIG5hbWUrKzsKKyAgICBpZiAobmFtZSA+PSBuYW1lRW5kKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmIChwYWNrYWdlRW5kKSB7CisgICAgICAgIHBhY2thZ2UgPSBuYW1lOworICAgICAgICBwYWNrYWdlTGVuID0gcGFja2FnZUVuZC1uYW1lOworICAgICAgICBuYW1lID0gcGFja2FnZUVuZCsxOworICAgIH0gZWxzZSBpZiAoIXBhY2thZ2UpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKHR5cGVFbmQpIHsKKyAgICAgICAgdHlwZSA9IG5hbWU7CisgICAgICAgIHR5cGVMZW4gPSB0eXBlRW5kLW5hbWU7CisgICAgICAgIG5hbWUgPSB0eXBlRW5kKzE7CisgICAgfSBlbHNlIGlmICghdHlwZSkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAobmFtZSA+PSBuYW1lRW5kKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBuYW1lTGVuID0gbmFtZUVuZC1uYW1lOworCisgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJMb29raW5nIGZvciBpZGVudGlmaWVyOiB0eXBlPSVzLCBuYW1lPSVzLCBwYWNrYWdlPSVzXG4iLAorICAgICAgICAgICAgICAgICBTdHJpbmc4KHR5cGUsIHR5cGVMZW4pLnN0cmluZygpLAorICAgICAgICAgICAgICAgICBTdHJpbmc4KG5hbWUsIG5hbWVMZW4pLnN0cmluZygpLAorICAgICAgICAgICAgICAgICBTdHJpbmc4KHBhY2thZ2UsIHBhY2thZ2VMZW4pLnN0cmluZygpKSk7CisKKyAgICBjb25zdCBzaXplX3QgTkcgPSBtUGFja2FnZUdyb3Vwcy5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaWc9MDsgaWc8Tkc7IGlnKyspIHsKKyAgICAgICAgY29uc3QgUGFja2FnZUdyb3VwKiBncm91cCA9IG1QYWNrYWdlR3JvdXBzW2lnXTsKKworICAgICAgICBpZiAoc3RyemNtcDE2KHBhY2thZ2UsIHBhY2thZ2VMZW4sCisgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAtPm5hbWUuc3RyaW5nKCksIGdyb3VwLT5uYW1lLnNpemUoKSkpIHsKKyAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiU2tpcHBpbmcgcGFja2FnZSBncm91cDogJXNcbiIsIFN0cmluZzgoZ3JvdXAtPm5hbWUpLnN0cmluZygpKSk7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGNvbnN0IHNzaXplX3QgdGkgPSBncm91cC0+dHlwZVN0cmluZ3MuaW5kZXhPZlN0cmluZyh0eXBlLCB0eXBlTGVuKTsKKyAgICAgICAgaWYgKHRpIDwgMCkgeworICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJUeXBlIG5vdCBmb3VuZCBpbiBwYWNrYWdlICVzXG4iLCBTdHJpbmc4KGdyb3VwLT5uYW1lKS5zdHJpbmcoKSkpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBjb25zdCBzc2l6ZV90IGVpID0gZ3JvdXAtPmtleVN0cmluZ3MuaW5kZXhPZlN0cmluZyhuYW1lLCBuYW1lTGVuKTsKKyAgICAgICAgaWYgKGVpIDwgMCkgeworICAgICAgICAgICAgVEFCTEVfTk9JU1kocHJpbnRmKCJOYW1lIG5vdCBmb3VuZCBpbiBwYWNrYWdlICVzXG4iLCBTdHJpbmc4KGdyb3VwLT5uYW1lKS5zdHJpbmcoKSkpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoIlNlYXJjaCBpbmRpY2VzOiB0eXBlPSVkLCBuYW1lPSVkXG4iLCB0aSwgZWkpKTsKKworICAgICAgICBjb25zdCBUeXBlKiBjb25zdCB0eXBlQ29uZmlncyA9IGdyb3VwLT5wYWNrYWdlc1swXS0+Z2V0VHlwZSh0aSk7CisgICAgICAgIGlmICh0eXBlQ29uZmlncyA9PSBOVUxMIHx8IHR5cGVDb25maWdzLT5jb25maWdzLnNpemUoKSA8PSAwKSB7CisgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoIkV4cGVjdGVkIHR5cGUgc3RydWN0dXJlIG5vdCBmb3VuZCBpbiBwYWNrYWdlICVzIGZvciBpZG5leCAlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KGdyb3VwLT5uYW1lKS5zdHJpbmcoKSwgdGkpKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgc2l6ZV90IE5UQyA9IHR5cGVDb25maWdzLT5jb25maWdzLnNpemUoKTsKKyAgICAgICAgZm9yIChzaXplX3QgdGNpPTA7IHRjaTxOVEM7IHRjaSsrKSB7CisgICAgICAgICAgICBjb25zdCBSZXNUYWJsZV90eXBlKiBjb25zdCB0eSA9IHR5cGVDb25maWdzLT5jb25maWdzW3RjaV07CisgICAgICAgICAgICBjb25zdCB1aW50MzJfdCB0eXBlT2Zmc2V0ID0gZHRvaGwodHktPmVudHJpZXNTdGFydCk7CisKKyAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QqIGNvbnN0IGVuZCA9ICgoY29uc3QgdWludDhfdCopdHkpICsgZHRvaGwodHktPmhlYWRlci5zaXplKTsKKyAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90KiBjb25zdCBlaW5kZXggPSAoY29uc3QgdWludDMyX3QqKQorICAgICAgICAgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKXR5KSArIGR0b2hzKHR5LT5oZWFkZXIuaGVhZGVyU2l6ZSkpOworCisgICAgICAgICAgICBjb25zdCBzaXplX3QgTkUgPSBkdG9obCh0eS0+ZW50cnlDb3VudCk7CisgICAgICAgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8TkU7IGkrKykgeworICAgICAgICAgICAgICAgIHVpbnQzMl90IG9mZnNldCA9IGR0b2hsKGVpbmRleFtpXSk7CisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA9PSBSZXNUYWJsZV90eXBlOjpOT19FTlRSWSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IHR5cGVPZmZzZXQ7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IChkdG9obCh0eS0+aGVhZGVyLnNpemUpLXNpemVvZihSZXNUYWJsZV9lbnRyeSkpKSB7CisgICAgICAgICAgICAgICAgICAgIExPR1coIlJlc1RhYmxlX2VudHJ5IGF0ICVkIGlzIGJleW9uZCB0eXBlIGNodW5rIGRhdGEgJWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCwgZHRvaGwodHktPmhlYWRlci5zaXplKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKG9mZnNldCYweDMpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HVygiUmVzVGFibGVfZW50cnkgYXQgJWQgKHBrZz0lZCB0eXBlPSVkIGVudD0lZCkgaXMgbm90IG9uIGFuIGludGVnZXIgYm91bmRhcnkgd2hlbiBsb29raW5nIGZvciAlczolcy8lcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgKGludClvZmZzZXQsIChpbnQpZ3JvdXAtPmlkLCAoaW50KXRpKzEsIChpbnQpaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHBhY2thZ2UsIHBhY2thZ2VMZW4pLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgodHlwZSwgdHlwZUxlbikuc3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nOChuYW1lLCBuYW1lTGVuKS5zdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBjb25zdCBSZXNUYWJsZV9lbnRyeSogY29uc3QgZW50cnkgPSAoY29uc3QgUmVzVGFibGVfZW50cnkqKQorICAgICAgICAgICAgICAgICAgICAoKChjb25zdCB1aW50OF90Kil0eSkgKyBvZmZzZXQpOworICAgICAgICAgICAgICAgIGlmIChkdG9ocyhlbnRyeS0+c2l6ZSkgPCBzaXplb2YoKmVudHJ5KSkgeworICAgICAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV9lbnRyeSBzaXplICVkIGlzIHRvbyBzbWFsbCIsIGR0b2hzKGVudHJ5LT5zaXplKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBCQURfVFlQRTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBUQUJMRV9TVVBFUl9OT0lTWShwcmludGYoIkxvb2tpbmcgYXQgZW50cnkgIyVkOiB3YW50IHN0ciAlZCwgaGF2ZSAlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSwgZWksIGR0b2hsKGVudHJ5LT5rZXkuaW5kZXgpKSk7CisgICAgICAgICAgICAgICAgaWYgKGR0b2hsKGVudHJ5LT5rZXkuaW5kZXgpID09IChzaXplX3QpZWkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG91dFR5cGVTcGVjRmxhZ3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXRUeXBlU3BlY0ZsYWdzID0gdHlwZUNvbmZpZ3MtPnR5cGVTcGVjRmxhZ3NbaV07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlc19NQUtFSUQoZ3JvdXAtPmlkLTEsIHRpLCBpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworYm9vbCBSZXNUYWJsZTo6ZXhwYW5kUmVzb3VyY2VSZWYoY29uc3QgdWludDE2X3QqIHJlZlN0ciwgc2l6ZV90IHJlZkxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzE2KiBvdXRQYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nMTYqIG91dFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcxNiogb3V0TmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFN0cmluZzE2KiBkZWZUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nMTYqIGRlZlBhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiogb3V0RXJyb3JNc2cpCit7CisgICAgY29uc3QgY2hhcjE2X3QqIHBhY2thZ2VFbmQgPSBOVUxMOworICAgIGNvbnN0IGNoYXIxNl90KiB0eXBlRW5kID0gTlVMTDsKKyAgICBjb25zdCBjaGFyMTZfdCogcCA9IHJlZlN0cjsKKyAgICBjb25zdCBjaGFyMTZfdCogY29uc3QgZW5kID0gcCArIHJlZkxlbjsKKyAgICB3aGlsZSAocCA8IGVuZCkgeworICAgICAgICBpZiAoKnAgPT0gJzonKSBwYWNrYWdlRW5kID0gcDsKKyAgICAgICAgZWxzZSBpZiAoKnAgPT0gJy8nKSB7CisgICAgICAgICAgICB0eXBlRW5kID0gcDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHArKzsKKyAgICB9CisgICAgcCA9IHJlZlN0cjsKKyAgICBpZiAoKnAgPT0gJ0AnKSBwKys7CisKKyAgICBpZiAocGFja2FnZUVuZCkgeworICAgICAgICAqb3V0UGFja2FnZSA9IFN0cmluZzE2KHAsIHBhY2thZ2VFbmQtcCk7CisgICAgICAgIHAgPSBwYWNrYWdlRW5kKzE7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKCFkZWZQYWNrYWdlKSB7CisgICAgICAgICAgICBpZiAob3V0RXJyb3JNc2cpIHsKKyAgICAgICAgICAgICAgICAqb3V0RXJyb3JNc2cgPSAiTm8gcmVzb3VyY2UgcGFja2FnZSBzcGVjaWZpZWQiOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgICpvdXRQYWNrYWdlID0gKmRlZlBhY2thZ2U7CisgICAgfQorICAgIGlmICh0eXBlRW5kKSB7CisgICAgICAgICpvdXRUeXBlID0gU3RyaW5nMTYocCwgdHlwZUVuZC1wKTsKKyAgICAgICAgcCA9IHR5cGVFbmQrMTsKKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoIWRlZlR5cGUpIHsKKyAgICAgICAgICAgIGlmIChvdXRFcnJvck1zZykgeworICAgICAgICAgICAgICAgICpvdXRFcnJvck1zZyA9ICJObyByZXNvdXJjZSB0eXBlIHNwZWNpZmllZCI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgKm91dFR5cGUgPSAqZGVmVHlwZTsKKyAgICB9CisgICAgKm91dE5hbWUgPSBTdHJpbmcxNihwLCBlbmQtcCk7CisgICAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB1aW50MzJfdCBnZXRfaGV4KGNoYXIgYywgYm9vbCogb3V0RXJyb3IpCit7CisgICAgaWYgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB7CisgICAgICAgIHJldHVybiBjIC0gJzAnOworICAgIH0gZWxzZSBpZiAoYyA+PSAnYScgJiYgYyA8PSAnZicpIHsKKyAgICAgICAgcmV0dXJuIGMgLSAnYScgKyAweGE7CisgICAgfSBlbHNlIGlmIChjID49ICdBJyAmJiBjIDw9ICdGJykgeworICAgICAgICByZXR1cm4gYyAtICdBJyArIDB4YTsKKyAgICB9CisgICAgKm91dEVycm9yID0gdHJ1ZTsKKyAgICByZXR1cm4gMDsKK30KKworc3RydWN0IHVuaXRfZW50cnkKK3sKKyAgICBjb25zdCBjaGFyKiBuYW1lOworICAgIHNpemVfdCBsZW47CisgICAgdWludDhfdCB0eXBlOworICAgIHVpbnQzMl90IHVuaXQ7CisgICAgZmxvYXQgc2NhbGU7Cit9OworCitzdGF0aWMgY29uc3QgdW5pdF9lbnRyeSB1bml0TmFtZXNbXSA9IHsKKyAgICB7ICJweCIsIHN0cmxlbigicHgiKSwgUmVzX3ZhbHVlOjpUWVBFX0RJTUVOU0lPTiwgUmVzX3ZhbHVlOjpDT01QTEVYX1VOSVRfUFgsIDEuMGYgfSwKKyAgICB7ICJkaXAiLCBzdHJsZW4oImRpcCIpLCBSZXNfdmFsdWU6OlRZUEVfRElNRU5TSU9OLCBSZXNfdmFsdWU6OkNPTVBMRVhfVU5JVF9ESVAsIDEuMGYgfSwKKyAgICB7ICJkcCIsIHN0cmxlbigiZHAiKSwgUmVzX3ZhbHVlOjpUWVBFX0RJTUVOU0lPTiwgUmVzX3ZhbHVlOjpDT01QTEVYX1VOSVRfRElQLCAxLjBmIH0sCisgICAgeyAic3AiLCBzdHJsZW4oInNwIiksIFJlc192YWx1ZTo6VFlQRV9ESU1FTlNJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX1NQLCAxLjBmIH0sCisgICAgeyAicHQiLCBzdHJsZW4oInB0IiksIFJlc192YWx1ZTo6VFlQRV9ESU1FTlNJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX1BULCAxLjBmIH0sCisgICAgeyAiaW4iLCBzdHJsZW4oImluIiksIFJlc192YWx1ZTo6VFlQRV9ESU1FTlNJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX0lOLCAxLjBmIH0sCisgICAgeyAibW0iLCBzdHJsZW4oIm1tIiksIFJlc192YWx1ZTo6VFlQRV9ESU1FTlNJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX01NLCAxLjBmIH0sCisgICAgeyAiJSIsIHN0cmxlbigiJSIpLCBSZXNfdmFsdWU6OlRZUEVfRlJBQ1RJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX0ZSQUNUSU9OLCAxLjBmLzEwMCB9LAorICAgIHsgIiVwIiwgc3RybGVuKCIlcCIpLCBSZXNfdmFsdWU6OlRZUEVfRlJBQ1RJT04sIFJlc192YWx1ZTo6Q09NUExFWF9VTklUX0ZSQUNUSU9OX1BBUkVOVCwgMS4wZi8xMDAgfSwKKyAgICB7IE5VTEwsIDAsIDAsIDAsIDAgfQorfTsKKworc3RhdGljIGJvb2wgcGFyc2VfdW5pdChjb25zdCBjaGFyKiBzdHIsIFJlc192YWx1ZSogb3V0VmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0KiBvdXRTY2FsZSwgY29uc3QgY2hhcioqIG91dEVuZCkKK3sKKyAgICBjb25zdCBjaGFyKiBlbmQgPSBzdHI7CisgICAgd2hpbGUgKCplbmQgIT0gMCAmJiAhaXNzcGFjZSgodW5zaWduZWQgY2hhcikqZW5kKSkgeworICAgICAgICBlbmQrKzsKKyAgICB9CisgICAgY29uc3Qgc2l6ZV90IGxlbiA9IGVuZC1zdHI7CisKKyAgICBjb25zdCBjaGFyKiByZWFsRW5kID0gZW5kOworICAgIHdoaWxlICgqcmVhbEVuZCAhPSAwICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnJlYWxFbmQpKSB7CisgICAgICAgIHJlYWxFbmQrKzsKKyAgICB9CisgICAgaWYgKCpyZWFsRW5kICE9IDApIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAKKyAgICBjb25zdCB1bml0X2VudHJ5KiBjdXIgPSB1bml0TmFtZXM7CisgICAgd2hpbGUgKGN1ci0+bmFtZSkgeworICAgICAgICBpZiAobGVuID09IGN1ci0+bGVuICYmIHN0cm5jbXAoY3VyLT5uYW1lLCBzdHIsIGxlbikgPT0gMCkgeworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gY3VyLT50eXBlOworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGEgPSBjdXItPnVuaXQgPDwgUmVzX3ZhbHVlOjpDT01QTEVYX1VOSVRfU0hJRlQ7CisgICAgICAgICAgICAqb3V0U2NhbGUgPSBjdXItPnNjYWxlOworICAgICAgICAgICAgKm91dEVuZCA9IGVuZDsKKyAgICAgICAgICAgIC8vcHJpbnRmKCJGb3VuZCB1bml0ICVzIGZvciAlc1xuIiwgY3VyLT5uYW1lLCBzdHIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgY3VyKys7CisgICAgfQorCisgICAgcmV0dXJuIGZhbHNlOworfQorCisKK2Jvb2wgUmVzVGFibGU6OnN0cmluZ1RvSW50KGNvbnN0IGNoYXIxNl90KiBzLCBzaXplX3QgbGVuLCBSZXNfdmFsdWUqIG91dFZhbHVlKQoreworICAgIHdoaWxlIChsZW4gPiAwICYmIGlzc3BhY2UxNigqcykpIHsKKyAgICAgICAgcysrOworICAgICAgICBsZW4tLTsKKyAgICB9CisKKyAgICBpZiAobGVuIDw9IDApIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHNpemVfdCBpID0gMDsKKyAgICBpbnQzMl90IHZhbCA9IDA7CisgICAgYm9vbCBuZWcgPSBmYWxzZTsKKworICAgIGlmICgqcyA9PSAnLScpIHsKKyAgICAgICAgbmVnID0gdHJ1ZTsKKyAgICAgICAgaSsrOworICAgIH0KKworICAgIGlmIChzW2ldIDwgJzAnIHx8IHNbaV0gPiAnOScpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vIERlY2ltYWwgb3IgaGV4PworICAgIGlmIChzW2ldID09ICcwJyAmJiBzW2krMV0gPT0gJ3gnKSB7CisgICAgICAgIGlmIChvdXRWYWx1ZSkKKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IG91dFZhbHVlLT5UWVBFX0lOVF9IRVg7CisgICAgICAgIGkgKz0gMjsKKyAgICAgICAgYm9vbCBlcnJvciA9IGZhbHNlOworICAgICAgICB3aGlsZSAoaSA8IGxlbiAmJiAhZXJyb3IpIHsKKyAgICAgICAgICAgIHZhbCA9ICh2YWwqMTYpICsgZ2V0X2hleChzW2ldLCAmZXJyb3IpOworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvcikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKG91dFZhbHVlKQorICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfSU5UX0RFQzsKKyAgICAgICAgd2hpbGUgKGkgPCBsZW4pIHsKKyAgICAgICAgICAgIGlmIChzW2ldIDwgJzAnIHx8IHNbaV0gPiAnOScpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2YWwgPSAodmFsKjEwKSArIHNbaV0tJzAnOworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKG5lZykgdmFsID0gLXZhbDsKKworICAgIHdoaWxlIChpIDwgbGVuICYmIGlzc3BhY2UxNihzW2ldKSkgeworICAgICAgICBpKys7CisgICAgfQorCisgICAgaWYgKGkgPT0gbGVuKSB7CisgICAgICAgIGlmIChvdXRWYWx1ZSkKKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gdmFsOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgUmVzVGFibGU6OnN0cmluZ1RvRmxvYXQoY29uc3QgY2hhcjE2X3QqIHMsIHNpemVfdCBsZW4sIFJlc192YWx1ZSogb3V0VmFsdWUpCit7CisgICAgd2hpbGUgKGxlbiA+IDAgJiYgaXNzcGFjZTE2KCpzKSkgeworICAgICAgICBzKys7CisgICAgICAgIGxlbi0tOworICAgIH0KKworICAgIGlmIChsZW4gPD0gMCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgY2hhciBidWZbMTI4XTsKKyAgICBpbnQgaT0wOworICAgIHdoaWxlIChsZW4gPiAwICYmICpzICE9IDAgJiYgaSA8IDEyNikgeworICAgICAgICBpZiAoKnMgPiAyNTUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBidWZbaSsrXSA9ICpzKys7CisgICAgICAgIGxlbi0tOworICAgIH0KKworICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGJ1ZlswXSA8ICcwJyAmJiBidWZbMF0gPiAnOScgJiYgYnVmWzBdICE9ICcuJykgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYnVmW2ldID0gMDsKKyAgICBjb25zdCBjaGFyKiBlbmQ7CisgICAgZmxvYXQgZiA9IHN0cnRvZihidWYsIChjaGFyKiopJmVuZCk7CisKKyAgICBpZiAoKmVuZCAhPSAwICYmICFpc3NwYWNlKCh1bnNpZ25lZCBjaGFyKSplbmQpKSB7CisgICAgICAgIC8vIE1pZ2h0IGJlIGEgdW5pdC4uLgorICAgICAgICBmbG9hdCBzY2FsZTsKKyAgICAgICAgaWYgKHBhcnNlX3VuaXQoZW5kLCBvdXRWYWx1ZSwgJnNjYWxlLCAmZW5kKSkgeworICAgICAgICAgICAgZiAqPSBzY2FsZTsKKyAgICAgICAgICAgIGNvbnN0IGJvb2wgbmVnID0gZiA8IDA7CisgICAgICAgICAgICBpZiAobmVnKSBmID0gLWY7CisgICAgICAgICAgICB1aW50NjRfdCBiaXRzID0gKHVpbnQ2NF90KShmKigxPDwyMykrLjVmKTsKKyAgICAgICAgICAgIHVpbnQzMl90IHJhZGl4OworICAgICAgICAgICAgdWludDMyX3Qgc2hpZnQ7CisgICAgICAgICAgICBpZiAoKGJpdHMmMHg3ZmZmZmYpID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBBbHdheXMgdXNlIDIzcDAgaWYgdGhlcmUgaXMgbm8gZnJhY3Rpb24sIGp1c3QgdG8gbWFrZQorICAgICAgICAgICAgICAgIC8vIHRoaW5ncyBlYXNpZXIgdG8gcmVhZC4KKyAgICAgICAgICAgICAgICByYWRpeCA9IFJlc192YWx1ZTo6Q09NUExFWF9SQURJWF8yM3AwOworICAgICAgICAgICAgICAgIHNoaWZ0ID0gMjM7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChiaXRzJjB4ZmZmZmZmZmZmZjgwMDAwMExMKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gTWFnbml0dWRlIGlzIHplcm8gLS0gY2FuIGZpdCBpbiAwIGJpdHMgb2YgcHJlY2lzaW9uLgorICAgICAgICAgICAgICAgIHJhZGl4ID0gUmVzX3ZhbHVlOjpDT01QTEVYX1JBRElYXzBwMjM7CisgICAgICAgICAgICAgICAgc2hpZnQgPSAwOworICAgICAgICAgICAgfSBlbHNlIGlmICgoYml0cyYweGZmZmZmZmZmODAwMDAwMDBMTCkgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIE1hZ25pdHVkZSBjYW4gZml0IGluIDggYml0cyBvZiBwcmVjaXNpb24uCisgICAgICAgICAgICAgICAgcmFkaXggPSBSZXNfdmFsdWU6OkNPTVBMRVhfUkFESVhfOHAxNTsKKyAgICAgICAgICAgICAgICBzaGlmdCA9IDg7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChiaXRzJjB4ZmZmZmZmODAwMDAwMDAwMExMKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gTWFnbml0dWRlIGNhbiBmaXQgaW4gMTYgYml0cyBvZiBwcmVjaXNpb24uCisgICAgICAgICAgICAgICAgcmFkaXggPSBSZXNfdmFsdWU6OkNPTVBMRVhfUkFESVhfMTZwNzsKKyAgICAgICAgICAgICAgICBzaGlmdCA9IDE2OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBNYWduaXR1ZGUgbmVlZHMgZW50aXJlIHJhbmdlLCBzbyBubyBmcmFjdGlvbmFsIHBhcnQuCisgICAgICAgICAgICAgICAgcmFkaXggPSBSZXNfdmFsdWU6OkNPTVBMRVhfUkFESVhfMjNwMDsKKyAgICAgICAgICAgICAgICBzaGlmdCA9IDIzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50MzJfdCBtYW50aXNzYSA9IChpbnQzMl90KSgKKyAgICAgICAgICAgICAgICAoYml0cz4+c2hpZnQpICYgUmVzX3ZhbHVlOjpDT01QTEVYX01BTlRJU1NBX01BU0spOworICAgICAgICAgICAgaWYgKG5lZykgeworICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gKC1tYW50aXNzYSkgJiBSZXNfdmFsdWU6OkNPTVBMRVhfTUFOVElTU0FfTUFTSzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhIHw9IAorICAgICAgICAgICAgICAgIChyYWRpeDw8UmVzX3ZhbHVlOjpDT01QTEVYX1JBRElYX1NISUZUKQorICAgICAgICAgICAgICAgIHwgKG1hbnRpc3NhPDxSZXNfdmFsdWU6OkNPTVBMRVhfTUFOVElTU0FfU0hJRlQpOworICAgICAgICAgICAgLy9wcmludGYoIklucHV0IHZhbHVlOiAlZiAweCUwMTZMeCwgbXVsdDogJWYsIHJhZGl4OiAlZCwgc2hpZnQ6ICVkLCBmaW5hbDogMHglMDh4XG4iLAorICAgICAgICAgICAgLy8gICAgICAgZiAqIChuZWcgPyAtMSA6IDEpLCBiaXRzLCBmKigxPDwyMyksCisgICAgICAgICAgICAvLyAgICAgICByYWRpeCwgc2hpZnQsIG91dFZhbHVlLT5kYXRhKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB3aGlsZSAoKmVuZCAhPSAwICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKmVuZCkpIHsKKyAgICAgICAgZW5kKys7CisgICAgfQorCisgICAgaWYgKCplbmQgPT0gMCkgeworICAgICAgICBpZiAob3V0VmFsdWUpIHsKKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IG91dFZhbHVlLT5UWVBFX0ZMT0FUOworICAgICAgICAgICAgKihmbG9hdCopKCZvdXRWYWx1ZS0+ZGF0YSkgPSBmOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgUmVzVGFibGU6OnN0cmluZ1RvVmFsdWUoUmVzX3ZhbHVlKiBvdXRWYWx1ZSwgU3RyaW5nMTYqIG91dFN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIHMsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcHJlc2VydmVTcGFjZXMsIGJvb2wgY29lcmNlVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgYXR0cklELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTdHJpbmcxNiogZGVmVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nMTYqIGRlZlBhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc29yKiBhY2Nlc3NvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogYWNjZXNzb3JDb29raWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGF0dHJUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGVuZm9yY2VQcml2YXRlKSBjb25zdAoreworICAgIGJvb2wgbG9jYWxpemF0aW9uU2V0dGluZyA9IGFjY2Vzc29yICE9IE5VTEwgJiYgYWNjZXNzb3ItPmdldExvY2FsaXphdGlvblNldHRpbmcoKTsKKyAgICBjb25zdCBjaGFyKiBlcnJvck1zZyA9IE5VTEw7CisKKyAgICBvdXRWYWx1ZS0+c2l6ZSA9IHNpemVvZihSZXNfdmFsdWUpOworICAgIG91dFZhbHVlLT5yZXMwID0gMDsKKworICAgIC8vIEZpcnN0IHN0cmlwIGxlYWRpbmcvdHJhaWxpbmcgd2hpdGVzcGFjZS4gIERvIHRoaXMgYmVmb3JlIGhhbmRsaW5nCisgICAgLy8gZXNjYXBlcywgc28gdGhleSBjYW4gYmUgdXNlZCB0byBmb3JjZSB3aGl0ZXNwYWNlIGludG8gdGhlIHN0cmluZy4KKyAgICBpZiAoIXByZXNlcnZlU3BhY2VzKSB7CisgICAgICAgIHdoaWxlIChsZW4gPiAwICYmIGlzc3BhY2UxNigqcykpIHsKKyAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgIGxlbi0tOworICAgICAgICB9CisgICAgICAgIHdoaWxlIChsZW4gPiAwICYmIGlzc3BhY2UxNihzW2xlbi0xXSkpIHsKKyAgICAgICAgICAgIGxlbi0tOworICAgICAgICB9CisgICAgICAgIC8vIElmIHRoZSBzdHJpbmcgZW5kcyB3aXRoICdcJywgdGhlbiB3ZSBrZWVwIHRoZSBzcGFjZSBhZnRlciBpdC4KKyAgICAgICAgaWYgKGxlbiA+IDAgJiYgc1tsZW4tMV0gPT0gJ1xcJyAmJiBzW2xlbl0gIT0gMCkgeworICAgICAgICAgICAgbGVuKys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvL3ByaW50ZigiVmFsdWUgZm9yOiAlc1xuIiwgU3RyaW5nOChzLCBsZW4pLnN0cmluZygpKTsKKworICAgIHVpbnQzMl90IGwxMG5SZXEgPSBSZXNUYWJsZV9tYXA6OkwxME5fTk9UX1JFUVVJUkVEOworICAgIHVpbnQzMl90IGF0dHJNaW4gPSAweDgwMDAwMDAwLCBhdHRyTWF4ID0gMHg3ZmZmZmZmZjsKKyAgICBib29sIGZyb21BY2Nlc3NvciA9IGZhbHNlOworICAgIGlmIChhdHRySUQgIT0gMCAmJiAhUmVzX0lOVEVSTkFMSUQoYXR0cklEKSkgeworICAgICAgICBjb25zdCBzc2l6ZV90IHAgPSBnZXRSZXNvdXJjZVBhY2thZ2VJbmRleChhdHRySUQpOworICAgICAgICBjb25zdCBiYWdfZW50cnkqIGJhZzsKKyAgICAgICAgc3NpemVfdCBjbnQgPSBwID49IDAgPyBsb2NrQmFnKGF0dHJJRCwgJmJhZykgOiAtMTsKKyAgICAgICAgLy9wcmludGYoIkZvciBhdHRyIDB4JTA4eCBnb3QgYmFnIG9mICVkXG4iLCBhdHRySUQsIGNudCk7CisgICAgICAgIGlmIChjbnQgPj0gMCkgeworICAgICAgICAgICAgd2hpbGUgKGNudCA+IDApIHsKKyAgICAgICAgICAgICAgICAvL3ByaW50ZigiRW50cnkgMHglMDh4ID0gMHglMDh4XG4iLCBiYWctPm1hcC5uYW1lLmlkZW50LCBiYWctPm1hcC52YWx1ZS5kYXRhKTsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGJhZy0+bWFwLm5hbWUuaWRlbnQpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFJlc1RhYmxlX21hcDo6QVRUUl9UWVBFOgorICAgICAgICAgICAgICAgICAgICBhdHRyVHlwZSA9IGJhZy0+bWFwLnZhbHVlLmRhdGE7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUmVzVGFibGVfbWFwOjpBVFRSX01JTjoKKyAgICAgICAgICAgICAgICAgICAgYXR0ck1pbiA9IGJhZy0+bWFwLnZhbHVlLmRhdGE7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUmVzVGFibGVfbWFwOjpBVFRSX01BWDoKKyAgICAgICAgICAgICAgICAgICAgYXR0ck1heCA9IGJhZy0+bWFwLnZhbHVlLmRhdGE7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUmVzVGFibGVfbWFwOjpBVFRSX0wxME46CisgICAgICAgICAgICAgICAgICAgIGwxMG5SZXEgPSBiYWctPm1hcC52YWx1ZS5kYXRhOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYmFnKys7CisgICAgICAgICAgICAgICAgY250LS07CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1bmxvY2tCYWcoYmFnKTsKKyAgICAgICAgfSBlbHNlIGlmIChhY2Nlc3NvciAmJiBhY2Nlc3Nvci0+Z2V0QXR0cmlidXRlVHlwZShhdHRySUQsICZhdHRyVHlwZSkpIHsKKyAgICAgICAgICAgIGZyb21BY2Nlc3NvciA9IHRydWU7CisgICAgICAgICAgICBpZiAoYXR0clR5cGUgPT0gUmVzVGFibGVfbWFwOjpUWVBFX0VOVU0KKyAgICAgICAgICAgICAgICAgICAgfHwgYXR0clR5cGUgPT0gUmVzVGFibGVfbWFwOjpUWVBFX0ZMQUdTCisgICAgICAgICAgICAgICAgICAgIHx8IGF0dHJUeXBlID09IFJlc1RhYmxlX21hcDo6VFlQRV9JTlRFR0VSKSB7CisgICAgICAgICAgICAgICAgYWNjZXNzb3ItPmdldEF0dHJpYnV0ZU1pbihhdHRySUQsICZhdHRyTWluKTsKKyAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+Z2V0QXR0cmlidXRlTWF4KGF0dHJJRCwgJmF0dHJNYXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGxvY2FsaXphdGlvblNldHRpbmcpIHsKKyAgICAgICAgICAgICAgICBsMTBuUmVxID0gYWNjZXNzb3ItPmdldEF0dHJpYnV0ZUwxME4oYXR0cklEKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGNvbnN0IGJvb2wgY2FuU3RyaW5nQ29lcmNlID0KKyAgICAgICAgY29lcmNlVHlwZSAmJiAoYXR0clR5cGUmUmVzVGFibGVfbWFwOjpUWVBFX1NUUklORykgIT0gMDsKKworICAgIGlmICgqcyA9PSAnQCcpIHsKKyAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfUkVGRVJFTkNFOworCisgICAgICAgIC8vIE5vdGU6IHdlIGRvbid0IGNoZWNrIGF0dHJUeXBlIGhlcmUgYmVjYXVzZSB0aGUgcmVmZXJlbmNlIGNhbgorICAgICAgICAvLyBiZSB0byBhbnkgb3RoZXIgdHlwZTsgd2UganVzdCBuZWVkIHRvIGNvdW50IG9uIHRoZSBjbGllbnQgbWFraW5nCisgICAgICAgIC8vIHN1cmUgdGhlIHJlZmVyZW5jZWQgdHlwZSBpcyBjb3JyZWN0LgorICAgICAgICAKKyAgICAgICAgLy9wcmludGYoIkxvb2tpbmcgdXAgcmVmOiAlc1xuIiwgU3RyaW5nOChzLCBsZW4pLnN0cmluZygpKTsKKworICAgICAgICAvLyBJdCdzIGEgcmVmZXJlbmNlIQorICAgICAgICBpZiAobGVuID09IDUgJiYgc1sxXT09J24nICYmIHNbMl09PSd1JyAmJiBzWzNdPT0nbCcgJiYgc1s0XT09J2wnKSB7CisgICAgICAgICAgICBvdXRWYWx1ZS0+ZGF0YSA9IDA7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJvb2wgY3JlYXRlSWZOb3RGb3VuZCA9IGZhbHNlOworICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIHJlc291cmNlUmVmTmFtZTsKKyAgICAgICAgICAgIGludCByZXNvdXJjZU5hbWVMZW47CisgICAgICAgICAgICBpZiAobGVuID4gMiAmJiBzWzFdID09ICcrJykgeworICAgICAgICAgICAgICAgIGNyZWF0ZUlmTm90Rm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIHJlc291cmNlUmVmTmFtZSA9IHMgKyAyOworICAgICAgICAgICAgICAgIHJlc291cmNlTmFtZUxlbiA9IGxlbiAtIDI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGxlbiA+IDIgJiYgc1sxXSA9PSAnKicpIHsKKyAgICAgICAgICAgICAgICBlbmZvcmNlUHJpdmF0ZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIHJlc291cmNlUmVmTmFtZSA9IHMgKyAyOworICAgICAgICAgICAgICAgIHJlc291cmNlTmFtZUxlbiA9IGxlbiAtIDI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNyZWF0ZUlmTm90Rm91bmQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICByZXNvdXJjZVJlZk5hbWUgPSBzICsgMTsKKyAgICAgICAgICAgICAgICByZXNvdXJjZU5hbWVMZW4gPSBsZW4gLSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nMTYgcGFja2FnZSwgdHlwZSwgbmFtZTsKKyAgICAgICAgICAgIGlmICghZXhwYW5kUmVzb3VyY2VSZWYocmVzb3VyY2VSZWZOYW1lLHJlc291cmNlTmFtZUxlbiwgJnBhY2thZ2UsICZ0eXBlLCAmbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmVHlwZSwgZGVmUGFja2FnZSwgJmVycm9yTXNnKSkgeworICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgZXJyb3JNc2cpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHVpbnQzMl90IHNwZWNGbGFncyA9IDA7CisgICAgICAgICAgICB1aW50MzJfdCByaWQgPSBpZGVudGlmaWVyRm9yTmFtZShuYW1lLnN0cmluZygpLCBuYW1lLnNpemUoKSwgdHlwZS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgdHlwZS5zaXplKCksIHBhY2thZ2Uuc3RyaW5nKCksIHBhY2thZ2Uuc2l6ZSgpLCAmc3BlY0ZsYWdzKTsKKyAgICAgICAgICAgIGlmIChyaWQgIT0gMCkgeworICAgICAgICAgICAgICAgIGlmIChlbmZvcmNlUHJpdmF0ZSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoKHNwZWNGbGFncyZSZXNUYWJsZV90eXBlU3BlYzo6U1BFQ19QVUJMSUMpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiUmVzb3VyY2UgaXMgbm90IHB1YmxpYy4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIWFjY2Vzc29yKSB7CisgICAgICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gcmlkOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmlkID0gUmVzX01BS0VJRCgKKyAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPmdldFJlbWFwcGVkUGFja2FnZShSZXNfR0VUUEFDS0FHRShyaWQpKSwKKyAgICAgICAgICAgICAgICAgICAgUmVzX0dFVFRZUEUocmlkKSwgUmVzX0dFVEVOVFJZKHJpZCkpOworICAgICAgICAgICAgICAgIFRBQkxFX05PSVNZKHByaW50ZigiSW5jbCAlczolcy8lczogMHglMDh4XG4iLAorICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHBhY2thZ2UpLnN0cmluZygpLCBTdHJpbmc4KHR5cGUpLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KG5hbWUpLnN0cmluZygpLCByaWQpKTsKKyAgICAgICAgICAgICAgICBvdXRWYWx1ZS0+ZGF0YSA9IHJpZDsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGFjY2Vzc29yKSB7CisgICAgICAgICAgICAgICAgdWludDMyX3QgcmlkID0gYWNjZXNzb3ItPmdldEN1c3RvbVJlc291cmNlV2l0aENyZWF0aW9uKHBhY2thZ2UsIHR5cGUsIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUlmTm90Rm91bmQpOworICAgICAgICAgICAgICAgIGlmIChyaWQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBUQUJMRV9OT0lTWShwcmludGYoIlBja2cgJXM6JXMvJXM6IDB4JTA4eFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocGFja2FnZSkuc3RyaW5nKCksIFN0cmluZzgodHlwZSkuc3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KG5hbWUpLnN0cmluZygpLCByaWQpKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGEgPSByaWQ7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsICJObyByZXNvdXJjZSBmb3VuZCB0aGF0IG1hdGNoZXMgdGhlIGdpdmVuIG5hbWUiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gaWYgd2UgZ290IHRvIGhlcmUsIGFuZCBsb2NhbGl6YXRpb24gaXMgcmVxdWlyZWQgYW5kIGl0J3Mgbm90IGEgcmVmZXJlbmNlLAorICAgIC8vIGNvbXBsYWluIGFuZCBiYWlsLgorICAgIGlmIChsMTBuUmVxID09IFJlc1RhYmxlX21hcDo6TDEwTl9TVUdHRVNURUQpIHsKKyAgICAgICAgaWYgKGxvY2FsaXphdGlvblNldHRpbmcpIHsKKyAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiVGhpcyBhdHRyaWJ1dGUgbXVzdCBiZSBsb2NhbGl6ZWQuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaWYgKCpzID09ICcjJykgeworICAgICAgICAvLyBJdCdzIGEgY29sb3IhICBDb252ZXJ0IHRvIGFuIGludGVnZXIgb2YgdGhlIGZvcm0gMHhhYXJyZ2diYi4KKyAgICAgICAgdWludDMyX3QgY29sb3IgPSAwOworICAgICAgICBib29sIGVycm9yID0gZmFsc2U7CisgICAgICAgIGlmIChsZW4gPT0gNCkgeworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfSU5UX0NPTE9SX1JHQjQ7CisgICAgICAgICAgICBjb2xvciB8PSAweEZGMDAwMDAwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDIwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDE2OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDEyOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDg7CisgICAgICAgICAgICBjb2xvciB8PSBnZXRfaGV4KHNbM10sICZlcnJvcikgPDwgNDsKKyAgICAgICAgICAgIGNvbG9yIHw9IGdldF9oZXgoc1szXSwgJmVycm9yKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPT0gNSkgeworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfSU5UX0NPTE9SX0FSR0I0OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDI4OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDI0OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDIwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDE2OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzNdLCAmZXJyb3IpIDw8IDEyOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzNdLCAmZXJyb3IpIDw8IDg7CisgICAgICAgICAgICBjb2xvciB8PSBnZXRfaGV4KHNbNF0sICZlcnJvcikgPDwgNDsKKyAgICAgICAgICAgIGNvbG9yIHw9IGdldF9oZXgoc1s0XSwgJmVycm9yKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPT0gNykgeworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfSU5UX0NPTE9SX1JHQjg7CisgICAgICAgICAgICBjb2xvciB8PSAweEZGMDAwMDAwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDIwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDE2OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzNdLCAmZXJyb3IpIDw8IDEyOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzRdLCAmZXJyb3IpIDw8IDg7CisgICAgICAgICAgICBjb2xvciB8PSBnZXRfaGV4KHNbNV0sICZlcnJvcikgPDwgNDsKKyAgICAgICAgICAgIGNvbG9yIHw9IGdldF9oZXgoc1s2XSwgJmVycm9yKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPT0gOSkgeworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfSU5UX0NPTE9SX0FSR0I4OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzFdLCAmZXJyb3IpIDw8IDI4OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzJdLCAmZXJyb3IpIDw8IDI0OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzNdLCAmZXJyb3IpIDw8IDIwOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzRdLCAmZXJyb3IpIDw8IDE2OworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzVdLCAmZXJyb3IpIDw8IDEyOworICAgICAgICAgICAgY29sb3IgfD0gZ2V0X2hleChzWzZdLCAmZXJyb3IpIDw8IDg7CisgICAgICAgICAgICBjb2xvciB8PSBnZXRfaGV4KHNbN10sICZlcnJvcikgPDwgNDsKKyAgICAgICAgICAgIGNvbG9yIHw9IGdldF9oZXgoc1s4XSwgJmVycm9yKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVycm9yID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWVycm9yKSB7CisgICAgICAgICAgICBpZiAoKGF0dHJUeXBlJlJlc1RhYmxlX21hcDo6VFlQRV9DT0xPUikgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmICghY2FuU3RyaW5nQ29lcmNlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb2xvciB0eXBlcyBub3QgYWxsb3dlZCIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gY29sb3I7CisgICAgICAgICAgICAgICAgLy9wcmludGYoIkNvbG9yIGlucHV0PSVzLCBvdXRwdXQ9MHgleFxuIiwgU3RyaW5nOChzLCBsZW4pLnN0cmluZygpLCBjb2xvcik7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoKGF0dHJUeXBlJlJlc1RhYmxlX21hcDo6VFlQRV9DT0xPUikgIT0gMCkgeworICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgIkNvbG9yIHZhbHVlIG5vdCB2YWxpZCAtLSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG11c3QgYmUgI3JnYiwgI2FyZ2IsICNycmdnYmIsIG9yICNhYXJyZ2diYiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAjaWYgMAorICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiJXM6IENvbG9yIElEICVzIHZhbHVlICVzIGlzIG5vdCB2YWxpZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJSZXNvdXJjZSBGaWxlIiwgLy8oY29uc3QgY2hhciopaW4tPmdldFByaW50YWJsZVNvdXJjZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nOCgqY3VyVGFnKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocywgbGVuKS5zdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgI2VuZGlmCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCpzID09ICc/JykgeworICAgICAgICBvdXRWYWx1ZS0+ZGF0YVR5cGUgPSBvdXRWYWx1ZS0+VFlQRV9BVFRSSUJVVEU7CisKKyAgICAgICAgLy8gTm90ZTogd2UgZG9uJ3QgY2hlY2sgYXR0clR5cGUgaGVyZSBiZWNhdXNlIHRoZSByZWZlcmVuY2UgY2FuCisgICAgICAgIC8vIGJlIHRvIGFueSBvdGhlciB0eXBlOyB3ZSBqdXN0IG5lZWQgdG8gY291bnQgb24gdGhlIGNsaWVudCBtYWtpbmcKKyAgICAgICAgLy8gc3VyZSB0aGUgcmVmZXJlbmNlZCB0eXBlIGlzIGNvcnJlY3QuCisKKyAgICAgICAgLy9wcmludGYoIkxvb2tpbmcgdXAgYXR0cjogJXNcbiIsIFN0cmluZzgocywgbGVuKS5zdHJpbmcoKSk7CisKKyAgICAgICAgc3RhdGljIGNvbnN0IFN0cmluZzE2IGF0dHIxNigiYXR0ciIpOworICAgICAgICBTdHJpbmcxNiBwYWNrYWdlLCB0eXBlLCBuYW1lOworICAgICAgICBpZiAoIWV4cGFuZFJlc291cmNlUmVmKHMrMSwgbGVuLTEsICZwYWNrYWdlLCAmdHlwZSwgJm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIxNiwgZGVmUGFja2FnZSwgJmVycm9yTXNnKSkgeworICAgICAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsIGVycm9yTXNnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vcHJpbnRmKCJQa2c6ICVzLCBUeXBlOiAlcywgTmFtZTogJXNcbiIsCisgICAgICAgIC8vICAgICAgIFN0cmluZzgocGFja2FnZSkuc3RyaW5nKCksIFN0cmluZzgodHlwZSkuc3RyaW5nKCksCisgICAgICAgIC8vICAgICAgIFN0cmluZzgobmFtZSkuc3RyaW5nKCkpOworICAgICAgICB1aW50MzJfdCBzcGVjRmxhZ3MgPSAwOworICAgICAgICB1aW50MzJfdCByaWQgPSAKKyAgICAgICAgICAgIGlkZW50aWZpZXJGb3JOYW1lKG5hbWUuc3RyaW5nKCksIG5hbWUuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS5zdHJpbmcoKSwgdHlwZS5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlLnN0cmluZygpLCBwYWNrYWdlLnNpemUoKSwgJnNwZWNGbGFncyk7CisgICAgICAgIGlmIChyaWQgIT0gMCkgeworICAgICAgICAgICAgaWYgKGVuZm9yY2VQcml2YXRlKSB7CisgICAgICAgICAgICAgICAgaWYgKChzcGVjRmxhZ3MmUmVzVGFibGVfdHlwZVNwZWM6OlNQRUNfUFVCTElDKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsICJBdHRyaWJ1dGUgaXMgbm90IHB1YmxpYy4iKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFhY2Nlc3NvcikgeworICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gcmlkOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmlkID0gUmVzX01BS0VJRCgKKyAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+Z2V0UmVtYXBwZWRQYWNrYWdlKFJlc19HRVRQQUNLQUdFKHJpZCkpLAorICAgICAgICAgICAgICAgIFJlc19HRVRUWVBFKHJpZCksIFJlc19HRVRFTlRSWShyaWQpKTsKKyAgICAgICAgICAgIC8vcHJpbnRmKCJJbmNsICVzOiVzLyVzOiAweCUwOHhcbiIsCisgICAgICAgICAgICAvLyAgICAgICBTdHJpbmc4KHBhY2thZ2UpLnN0cmluZygpLCBTdHJpbmc4KHR5cGUpLnN0cmluZygpLAorICAgICAgICAgICAgLy8gICAgICAgU3RyaW5nOChuYW1lKS5zdHJpbmcoKSwgcmlkKTsKKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gcmlkOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYWNjZXNzb3IpIHsKKyAgICAgICAgICAgIHVpbnQzMl90IHJpZCA9IGFjY2Vzc29yLT5nZXRDdXN0b21SZXNvdXJjZShwYWNrYWdlLCB0eXBlLCBuYW1lKTsKKyAgICAgICAgICAgIGlmIChyaWQgIT0gMCkgeworICAgICAgICAgICAgICAgIC8vcHJpbnRmKCJNaW5lICVzOiVzLyVzOiAweCUwOHhcbiIsCisgICAgICAgICAgICAgICAgLy8gICAgICAgU3RyaW5nOChwYWNrYWdlKS5zdHJpbmcoKSwgU3RyaW5nOCh0eXBlKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAvLyAgICAgICBTdHJpbmc4KG5hbWUpLnN0cmluZygpLCByaWQpOworICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gcmlkOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgIk5vIHJlc291cmNlIGZvdW5kIHRoYXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbmFtZSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoc3RyaW5nVG9JbnQocywgbGVuLCBvdXRWYWx1ZSkpIHsKKyAgICAgICAgaWYgKChhdHRyVHlwZSZSZXNUYWJsZV9tYXA6OlRZUEVfSU5URUdFUikgPT0gMCkgeworICAgICAgICAgICAgLy8gSWYgdGhpcyB0eXBlIGRvZXMgbm90IGFsbG93IGludGVnZXJzLCBidXQgZG9lcyBhbGxvdyBmbG9hdHMsCisgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2ggb24gdGhpcyBlcnJvciBjYXNlIGJlY2F1c2UgdGhlIGZsb2F0IHR5cGUgc2hvdWxkCisgICAgICAgICAgICAvLyBiZSBhYmxlIHRvIGFjY2VwdCBhbnkgaW50ZWdlciB2YWx1ZS4KKyAgICAgICAgICAgIGlmICghY2FuU3RyaW5nQ29lcmNlICYmIChhdHRyVHlwZSZSZXNUYWJsZV9tYXA6OlRZUEVfRkxPQVQpID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3IgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsICJJbnRlZ2VyIHR5cGVzIG5vdCBhbGxvd2VkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICgoKGludDMyX3Qpb3V0VmFsdWUtPmRhdGEpIDwgKChpbnQzMl90KWF0dHJNaW4pCisgICAgICAgICAgICAgICAgICAgIHx8ICgoaW50MzJfdClvdXRWYWx1ZS0+ZGF0YSkgPiAoKGludDMyX3QpYXR0ck1heCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3IgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+cmVwb3J0RXJyb3IoYWNjZXNzb3JDb29raWUsICJJbnRlZ2VyIHZhbHVlIG91dCBvZiByYW5nZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChzdHJpbmdUb0Zsb2F0KHMsIGxlbiwgb3V0VmFsdWUpKSB7CisgICAgICAgIGlmIChvdXRWYWx1ZS0+ZGF0YVR5cGUgPT0gUmVzX3ZhbHVlOjpUWVBFX0RJTUVOU0lPTikgeworICAgICAgICAgICAgaWYgKChhdHRyVHlwZSZSZXNUYWJsZV9tYXA6OlRZUEVfRElNRU5TSU9OKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWNhblN0cmluZ0NvZXJjZSkgeworICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvciAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgIkRpbWVuc2lvbiB0eXBlcyBub3QgYWxsb3dlZCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAob3V0VmFsdWUtPmRhdGFUeXBlID09IFJlc192YWx1ZTo6VFlQRV9GUkFDVElPTikgeworICAgICAgICAgICAgaWYgKChhdHRyVHlwZSZSZXNUYWJsZV9tYXA6OlRZUEVfRlJBQ1RJT04pICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghY2FuU3RyaW5nQ29lcmNlKSB7CisgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiRnJhY3Rpb24gdHlwZXMgbm90IGFsbG93ZWQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKChhdHRyVHlwZSZSZXNUYWJsZV9tYXA6OlRZUEVfRkxPQVQpID09IDApIHsKKyAgICAgICAgICAgIGlmICghY2FuU3RyaW5nQ29lcmNlKSB7CisgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiRmxvYXQgdHlwZXMgbm90IGFsbG93ZWQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAobGVuID09IDQpIHsKKyAgICAgICAgaWYgKChzWzBdID09ICd0JyB8fCBzWzBdID09ICdUJykgJiYKKyAgICAgICAgICAgIChzWzFdID09ICdyJyB8fCBzWzFdID09ICdSJykgJiYKKyAgICAgICAgICAgIChzWzJdID09ICd1JyB8fCBzWzJdID09ICdVJykgJiYKKyAgICAgICAgICAgIChzWzNdID09ICdlJyB8fCBzWzNdID09ICdFJykpIHsKKyAgICAgICAgICAgIGlmICgoYXR0clR5cGUmUmVzVGFibGVfbWFwOjpUWVBFX0JPT0xFQU4pID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoIWNhblN0cmluZ0NvZXJjZSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3IgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiQm9vbGVhbiB0eXBlcyBub3QgYWxsb3dlZCIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IG91dFZhbHVlLT5UWVBFX0lOVF9CT09MRUFOOworICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gKHVpbnQzMl90KS0xOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGxlbiA9PSA1KSB7CisgICAgICAgIGlmICgoc1swXSA9PSAnZicgfHwgc1swXSA9PSAnRicpICYmCisgICAgICAgICAgICAoc1sxXSA9PSAnYScgfHwgc1sxXSA9PSAnQScpICYmCisgICAgICAgICAgICAoc1syXSA9PSAnbCcgfHwgc1syXSA9PSAnTCcpICYmCisgICAgICAgICAgICAoc1szXSA9PSAncycgfHwgc1szXSA9PSAnUycpICYmCisgICAgICAgICAgICAoc1s0XSA9PSAnZScgfHwgc1s0XSA9PSAnRScpKSB7CisgICAgICAgICAgICBpZiAoKGF0dHJUeXBlJlJlc1RhYmxlX21hcDo6VFlQRV9CT09MRUFOKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKCFjYW5TdHJpbmdDb2VyY2UpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgIkJvb2xlYW4gdHlwZXMgbm90IGFsbG93ZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXRWYWx1ZS0+ZGF0YVR5cGUgPSBvdXRWYWx1ZS0+VFlQRV9JTlRfQk9PTEVBTjsKKyAgICAgICAgICAgICAgICBvdXRWYWx1ZS0+ZGF0YSA9IDA7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoKGF0dHJUeXBlJlJlc1RhYmxlX21hcDo6VFlQRV9FTlVNKSAhPSAwKSB7CisgICAgICAgIGNvbnN0IHNzaXplX3QgcCA9IGdldFJlc291cmNlUGFja2FnZUluZGV4KGF0dHJJRCk7CisgICAgICAgIGNvbnN0IGJhZ19lbnRyeSogYmFnOworICAgICAgICBzc2l6ZV90IGNudCA9IHAgPj0gMCA/IGxvY2tCYWcoYXR0cklELCAmYmFnKSA6IC0xOworICAgICAgICAvL3ByaW50ZigiR290ICVkIGZvciBlbnVtXG4iLCBjbnQpOworICAgICAgICBpZiAoY250ID49IDApIHsKKyAgICAgICAgICAgIHJlc291cmNlX25hbWUgcm5hbWU7CisgICAgICAgICAgICB3aGlsZSAoY250ID4gMCkgeworICAgICAgICAgICAgICAgIGlmICghUmVzX0lOVEVSTkFMSUQoYmFnLT5tYXAubmFtZS5pZGVudCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy9wcmludGYoIlRyeWluZyBhdHRyICMlMDh4XG4iLCBiYWctPm1hcC5uYW1lLmlkZW50KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdldFJlc291cmNlTmFtZShiYWctPm1hcC5uYW1lLmlkZW50LCAmcm5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAjaWYgMAorICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJNYXRjaGluZyAlcyBhZ2FpbnN0ICVzICgweCUwOHgpXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocywgbGVuKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHJuYW1lLm5hbWUsIHJuYW1lLm5hbWVMZW4pLnN0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhZy0+bWFwLm5hbWUuaWRlbnQpOworICAgICAgICAgICAgICAgICAgICAgICAgI2VuZGlmCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyemNtcDE2KHMsIGxlbiwgcm5hbWUubmFtZSwgcm5hbWUubmFtZUxlbikgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IGJhZy0+bWFwLnZhbHVlLmRhdGFUeXBlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhID0gYmFnLT5tYXAudmFsdWUuZGF0YTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxvY2tCYWcoYmFnKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgIAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBiYWcrKzsKKyAgICAgICAgICAgICAgICBjbnQtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHVubG9ja0JhZyhiYWcpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZyb21BY2Nlc3NvcikgeworICAgICAgICAgICAgaWYgKGFjY2Vzc29yLT5nZXRBdHRyaWJ1dGVFbnVtKGF0dHJJRCwgcywgbGVuLCBvdXRWYWx1ZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGlmICgoYXR0clR5cGUmUmVzVGFibGVfbWFwOjpUWVBFX0ZMQUdTKSAhPSAwKSB7CisgICAgICAgIGNvbnN0IHNzaXplX3QgcCA9IGdldFJlc291cmNlUGFja2FnZUluZGV4KGF0dHJJRCk7CisgICAgICAgIGNvbnN0IGJhZ19lbnRyeSogYmFnOworICAgICAgICBzc2l6ZV90IGNudCA9IHAgPj0gMCA/IGxvY2tCYWcoYXR0cklELCAmYmFnKSA6IC0xOworICAgICAgICAvL3ByaW50ZigiR290ICVkIGZvciBmbGFnc1xuIiwgY250KTsKKyAgICAgICAgaWYgKGNudCA+PSAwKSB7CisgICAgICAgICAgICBib29sIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgcmVzb3VyY2VfbmFtZSBybmFtZTsKKyAgICAgICAgICAgIG91dFZhbHVlLT5kYXRhVHlwZSA9IFJlc192YWx1ZTo6VFlQRV9JTlRfSEVYOworICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGEgPSAwOworICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIGVuZCA9IHMgKyBsZW47CisgICAgICAgICAgICBjb25zdCBjaGFyMTZfdCogcG9zID0gczsKKyAgICAgICAgICAgIHdoaWxlIChwb3MgPCBlbmQgJiYgIWZhaWxlZCkgeworICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIxNl90KiBzdGFydCA9IHBvczsKKyAgICAgICAgICAgICAgICBlbmQrKzsKKyAgICAgICAgICAgICAgICB3aGlsZSAocG9zIDwgZW5kICYmICpwb3MgIT0gJ3wnKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIH0KKwkJCQkvL3ByaW50ZigiTG9va2luZyBmb3I6ICVzXG4iLCBTdHJpbmc4KHN0YXJ0LCBwb3Mtc3RhcnQpLnN0cmluZygpKTsKKyAgICAgICAgICAgICAgICBjb25zdCBiYWdfZW50cnkqIGJhZ2kgPSBiYWc7CisJCQkJc3NpemVfdCBpOworICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPGNudDsgaSsrLCBiYWdpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFSZXNfSU5URVJOQUxJRChiYWdpLT5tYXAubmFtZS5pZGVudCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vcHJpbnRmKCJUcnlpbmcgYXR0ciAjJTA4eFxuIiwgYmFnaS0+bWFwLm5hbWUuaWRlbnQpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldFJlc291cmNlTmFtZShiYWdpLT5tYXAubmFtZS5pZGVudCwgJnJuYW1lKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICNpZiAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJNYXRjaGluZyAlcyBhZ2FpbnN0ICVzICgweCUwOHgpXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc4KHN0YXJ0LHBvcy1zdGFydCkuc3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZzgocm5hbWUubmFtZSwgcm5hbWUubmFtZUxlbikuc3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhZ2ktPm1hcC5uYW1lLmlkZW50KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZW5kaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyemNtcDE2KHN0YXJ0LCBwb3Mtc3RhcnQsIHJuYW1lLm5hbWUsIHJuYW1lLm5hbWVMZW4pID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0VmFsdWUtPmRhdGEgfD0gYmFnaS0+bWFwLnZhbHVlLmRhdGE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaSA+PSBjbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gRGlkbid0IGZpbmQgdGhpcyBmbGFnIGlkZW50aWZpZXIuCisgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChwb3MgPCBlbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdW5sb2NrQmFnKGJhZyk7CisgICAgICAgICAgICBpZiAoIWZhaWxlZCkgeworCQkJCS8vcHJpbnRmKCJGaW5hbCBmbGFnIHZhbHVlOiAweCVseFxuIiwgb3V0VmFsdWUtPmRhdGEpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKworICAgICAgICBpZiAoZnJvbUFjY2Vzc29yKSB7CisgICAgICAgICAgICBpZiAoYWNjZXNzb3ItPmdldEF0dHJpYnV0ZUZsYWdzKGF0dHJJRCwgcywgbGVuLCBvdXRWYWx1ZSkpIHsKKwkJCQkvL3ByaW50ZigiRmluYWwgZmxhZyB2YWx1ZTogMHglbHhcbiIsIG91dFZhbHVlLT5kYXRhKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGlmICgoYXR0clR5cGUmUmVzVGFibGVfbWFwOjpUWVBFX1NUUklORykgPT0gMCkgeworICAgICAgICBpZiAoYWNjZXNzb3IgIT0gTlVMTCkgeworICAgICAgICAgICAgYWNjZXNzb3ItPnJlcG9ydEVycm9yKGFjY2Vzc29yQ29va2llLCAiU3RyaW5nIHR5cGVzIG5vdCBhbGxvd2VkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vIEdlbmVyaWMgc3RyaW5nIGhhbmRsaW5nLi4uCisgICAgb3V0VmFsdWUtPmRhdGFUeXBlID0gb3V0VmFsdWUtPlRZUEVfU1RSSU5HOworICAgIGlmIChvdXRTdHJpbmcpIHsKKyAgICAgICAgYm9vbCBmYWlsZWQgPSBjb2xsZWN0U3RyaW5nKG91dFN0cmluZywgcywgbGVuLCBwcmVzZXJ2ZVNwYWNlcywgJmVycm9yTXNnKTsKKyAgICAgICAgaWYgKGFjY2Vzc29yICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGFjY2Vzc29yLT5yZXBvcnRFcnJvcihhY2Nlc3NvckNvb2tpZSwgZXJyb3JNc2cpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWlsZWQ7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUmVzVGFibGU6OmNvbGxlY3RTdHJpbmcoU3RyaW5nMTYqIG91dFN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcjE2X3QqIHMsIHNpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcHJlc2VydmVTcGFjZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqKiBvdXRFcnJvck1zZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBhcHBlbmQpCit7CisgICAgU3RyaW5nMTYgdG1wOworCisgICAgY2hhciBxdW90ZWQgPSAwOworICAgIGNvbnN0IGNoYXIxNl90KiBwID0gczsKKyAgICB3aGlsZSAocCA8IChzK2xlbikpIHsKKyAgICAgICAgd2hpbGUgKHAgPCAocytsZW4pKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyMTZfdCBjID0gKnA7CisgICAgICAgICAgICBpZiAoYyA9PSAnXFwnKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXByZXNlcnZlU3BhY2VzKSB7CisgICAgICAgICAgICAgICAgaWYgKHF1b3RlZCA9PSAwICYmIGlzc3BhY2UxNihjKQorICAgICAgICAgICAgICAgICAgICAmJiAoYyAhPSAnICcgfHwgaXNzcGFjZTE2KCoocCsxKSkpKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnIicgJiYgKHF1b3RlZCA9PSAwIHx8IHF1b3RlZCA9PSAnIicpKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnXCcnICYmIChxdW90ZWQgPT0gMCB8fCBxdW90ZWQgPT0gJ1wnJykpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcCsrOworICAgICAgICB9CisgICAgICAgIGlmIChwIDwgKHMrbGVuKSkgeworICAgICAgICAgICAgaWYgKHAgPiBzKSB7CisgICAgICAgICAgICAgICAgdG1wLmFwcGVuZChTdHJpbmcxNihzLCBwLXMpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcHJlc2VydmVTcGFjZXMgJiYgKCpwID09ICciJyB8fCAqcCA9PSAnXCcnKSkgeworICAgICAgICAgICAgICAgIGlmIChxdW90ZWQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBxdW90ZWQgPSAqcDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBxdW90ZWQgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwKys7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCFwcmVzZXJ2ZVNwYWNlcyAmJiBpc3NwYWNlMTYoKnApKSB7CisgICAgICAgICAgICAgICAgLy8gU3BhY2Ugb3V0c2lkZSBvZiBhIHF1b3RlIC0tIGNvbnN1bWUgYWxsIHNwYWNlcyBhbmQKKyAgICAgICAgICAgICAgICAvLyBsZWF2ZSBhIHNpbmdsZSBwbGFpbiBzcGFjZSBjaGFyLgorICAgICAgICAgICAgICAgIHRtcC5hcHBlbmQoU3RyaW5nMTYoIiAiKSk7CisgICAgICAgICAgICAgICAgcCsrOworICAgICAgICAgICAgICAgIHdoaWxlIChwIDwgKHMrbGVuKSAmJiBpc3NwYWNlMTYoKnApKSB7CisgICAgICAgICAgICAgICAgICAgIHArKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKCpwID09ICdcXCcpIHsKKyAgICAgICAgICAgICAgICBwKys7CisgICAgICAgICAgICAgICAgaWYgKHAgPCAocytsZW4pKSB7CisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoKnApIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CisgICAgICAgICAgICAgICAgICAgICAgICB0bXAuYXBwZW5kKFN0cmluZzE2KCJcdCIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlICduJzoKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5hcHBlbmQoU3RyaW5nMTYoIlxuIikpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgJyMnOgorICAgICAgICAgICAgICAgICAgICAgICAgdG1wLmFwcGVuZChTdHJpbmcxNigiIyIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlICdAJzoKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5hcHBlbmQoU3RyaW5nMTYoIkAiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnPyc6CisgICAgICAgICAgICAgICAgICAgICAgICB0bXAuYXBwZW5kKFN0cmluZzE2KCI/IikpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgJyInOgorICAgICAgICAgICAgICAgICAgICAgICAgdG1wLmFwcGVuZChTdHJpbmcxNigiXCIiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnXCcnOgorICAgICAgICAgICAgICAgICAgICAgICAgdG1wLmFwcGVuZChTdHJpbmcxNigiJyIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgICAgICAgICB0bXAuYXBwZW5kKFN0cmluZzE2KCJcXCIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlICd1JzoKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgY2hhcjE2X3QgY2hyID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpIDwgNCAmJiBwWzFdICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwKys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgqcCA+PSAnMCcgJiYgKnAgPD0gJzknKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAqcCAtICcwJzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCpwID49ICdhJyAmJiAqcCA8PSAnZicpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyA9ICpwIC0gJ2EnICsgMTA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgqcCA+PSAnQScgJiYgKnAgPD0gJ0YnKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAqcCAtICdBJyArIDEwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRFcnJvck1zZykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm91dEVycm9yTXNnID0gIkJhZCBjaGFyYWN0ZXIgaW4gXFx1IHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNociA9IChjaHI8PDQpIHwgYzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5hcHBlbmQoU3RyaW5nMTYoJmNociwgMSkpOworICAgICAgICAgICAgICAgICAgICB9IGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHVua25vd24gZXNjYXBlIGNoYXJzLgorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxlbiAtPSAocC1zKTsKKyAgICAgICAgICAgIHMgPSBwOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKHRtcC5zaXplKCkgIT0gMCkgeworICAgICAgICBpZiAobGVuID4gMCkgeworICAgICAgICAgICAgdG1wLmFwcGVuZChTdHJpbmcxNihzLCBsZW4pKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXBwZW5kKSB7CisgICAgICAgICAgICBvdXRTdHJpbmctPmFwcGVuZCh0bXApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb3V0U3RyaW5nLT5zZXRUbyh0bXApOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGFwcGVuZCkgeworICAgICAgICAgICAgb3V0U3RyaW5nLT5hcHBlbmQoU3RyaW5nMTYocywgbGVuKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvdXRTdHJpbmctPnNldFRvKHMsIGxlbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworc2l6ZV90IFJlc1RhYmxlOjpnZXRCYXNlUGFja2FnZUNvdW50KCkgY29uc3QKK3sKKyAgICBpZiAobUVycm9yICE9IE5PX0VSUk9SKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gbVBhY2thZ2VHcm91cHMuc2l6ZSgpOworfQorCitjb25zdCBjaGFyMTZfdCogUmVzVGFibGU6OmdldEJhc2VQYWNrYWdlTmFtZShzaXplX3QgaWR4KSBjb25zdAoreworICAgIGlmIChtRXJyb3IgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIExPR19GQVRBTF9JRihpZHggPj0gbVBhY2thZ2VHcm91cHMuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAiUmVxdWVzdGVkIHBhY2thZ2UgaW5kZXggJWQgcGFzdCBwYWNrYWdlIGNvdW50ICVkIiwKKyAgICAgICAgICAgICAgICAgKGludClpZHgsIChpbnQpbVBhY2thZ2VHcm91cHMuc2l6ZSgpKTsKKyAgICByZXR1cm4gbVBhY2thZ2VHcm91cHNbaWR4XS0+bmFtZS5zdHJpbmcoKTsKK30KKwordWludDMyX3QgUmVzVGFibGU6OmdldEJhc2VQYWNrYWdlSWQoc2l6ZV90IGlkeCkgY29uc3QKK3sKKyAgICBpZiAobUVycm9yICE9IE5PX0VSUk9SKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBMT0dfRkFUQUxfSUYoaWR4ID49IG1QYWNrYWdlR3JvdXBzLnNpemUoKSwKKyAgICAgICAgICAgICAgICAgIlJlcXVlc3RlZCBwYWNrYWdlIGluZGV4ICVkIHBhc3QgcGFja2FnZSBjb3VudCAlZCIsCisgICAgICAgICAgICAgICAgIChpbnQpaWR4LCAoaW50KW1QYWNrYWdlR3JvdXBzLnNpemUoKSk7CisgICAgcmV0dXJuIG1QYWNrYWdlR3JvdXBzW2lkeF0tPmlkOworfQorCitzaXplX3QgUmVzVGFibGU6OmdldFRhYmxlQ291bnQoKSBjb25zdAoreworICAgIHJldHVybiBtSGVhZGVycy5zaXplKCk7Cit9CisKK2NvbnN0IFJlc1N0cmluZ1Bvb2wqIFJlc1RhYmxlOjpnZXRUYWJsZVN0cmluZ0Jsb2NrKHNpemVfdCBpbmRleCkgY29uc3QKK3sKKyAgICByZXR1cm4gJm1IZWFkZXJzW2luZGV4XS0+dmFsdWVzOworfQorCit2b2lkKiBSZXNUYWJsZTo6Z2V0VGFibGVDb29raWUoc2l6ZV90IGluZGV4KSBjb25zdAoreworICAgIHJldHVybiBtSGVhZGVyc1tpbmRleF0tPmNvb2tpZTsKK30KKwordm9pZCBSZXNUYWJsZTo6Z2V0Q29uZmlndXJhdGlvbnMoVmVjdG9yPFJlc1RhYmxlX2NvbmZpZz4qIGNvbmZpZ3MpIGNvbnN0Cit7CisgICAgY29uc3Qgc2l6ZV90IEkgPSBtUGFja2FnZUdyb3Vwcy5zaXplKCk7CisgICAgZm9yIChzaXplX3QgaT0wOyBpPEk7IGkrKykgeworICAgICAgICBjb25zdCBQYWNrYWdlR3JvdXAqIHBhY2thZ2VHcm91cCA9IG1QYWNrYWdlR3JvdXBzW2ldOworICAgICAgICBjb25zdCBzaXplX3QgSiA9IHBhY2thZ2VHcm91cC0+cGFja2FnZXMuc2l6ZSgpOworICAgICAgICBmb3IgKHNpemVfdCBqPTA7IGo8SjsgaisrKSB7CisgICAgICAgICAgICBjb25zdCBQYWNrYWdlKiBwYWNrYWdlID0gcGFja2FnZUdyb3VwLT5wYWNrYWdlc1tqXTsKKyAgICAgICAgICAgIGNvbnN0IHNpemVfdCBLID0gcGFja2FnZS0+dHlwZXMuc2l6ZSgpOworICAgICAgICAgICAgZm9yIChzaXplX3Qgaz0wOyBrPEs7IGsrKykgeworICAgICAgICAgICAgICAgIGNvbnN0IFR5cGUqIHR5cGUgPSBwYWNrYWdlLT50eXBlc1trXTsKKyAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBOVUxMKSBjb250aW51ZTsKKyAgICAgICAgICAgICAgICBjb25zdCBzaXplX3QgTCA9IHR5cGUtPmNvbmZpZ3Muc2l6ZSgpOworICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IGw9MDsgbDxMOyBsKyspIHsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVzVGFibGVfdHlwZSogY29uZmlnID0gdHlwZS0+Y29uZmlnc1tsXTsKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVzVGFibGVfY29uZmlnKiBjZmcgPSAmY29uZmlnLT5jb25maWc7CisgICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgaW5zZXJ0IHVuaXF1ZQorICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXplX3QgTSA9IGNvbmZpZ3MtPnNpemUoKTsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG07CisgICAgICAgICAgICAgICAgICAgIGZvciAobT0wOyBtPE07IG0rKykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gKCpjb25maWdzKVttXS5jb21wYXJlKCpjZmcpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgZGlkbid0IGZpbmQgaXQKKyAgICAgICAgICAgICAgICAgICAgaWYgKG0gPT0gTSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlncy0+YWRkKCpjZmcpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCit2b2lkIFJlc1RhYmxlOjpnZXRMb2NhbGVzKFZlY3RvcjxTdHJpbmc4PiogbG9jYWxlcykgY29uc3QKK3sKKyAgICBWZWN0b3I8UmVzVGFibGVfY29uZmlnPiBjb25maWdzOworICAgIExPR0QoImNhbGxpbmcgZ2V0Q29uZmlndXJhdGlvbnMiKTsKKyAgICBnZXRDb25maWd1cmF0aW9ucygmY29uZmlncyk7CisgICAgTE9HRCgiY2FsbGVkIGdldENvbmZpZ3VyYXRpb25zIHNpemU9JWQiLCAoaW50KWNvbmZpZ3Muc2l6ZSgpKTsKKyAgICBjb25zdCBzaXplX3QgSSA9IGNvbmZpZ3Muc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxJOyBpKyspIHsKKyAgICAgICAgY2hhciBsb2NhbGVbNl07CisgICAgICAgIGNvbmZpZ3NbaV0uZ2V0TG9jYWxlKGxvY2FsZSk7CisgICAgICAgIGNvbnN0IHNpemVfdCBKID0gbG9jYWxlcy0+c2l6ZSgpOworICAgICAgICBzaXplX3QgajsKKyAgICAgICAgZm9yIChqPTA7IGo8SjsgaisrKSB7CisgICAgICAgICAgICBpZiAoMCA9PSBzdHJjbXAobG9jYWxlLCAoKmxvY2FsZXMpW2pdLnN0cmluZygpKSkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChqID09IEopIHsKKyAgICAgICAgICAgIGxvY2FsZXMtPmFkZChTdHJpbmc4KGxvY2FsZSkpOworICAgICAgICB9CisgICAgfQorfQorCitzc2l6ZV90IFJlc1RhYmxlOjpnZXRFbnRyeSgKKyAgICBjb25zdCBQYWNrYWdlKiBwYWNrYWdlLCBpbnQgdHlwZUluZGV4LCBpbnQgZW50cnlJbmRleCwKKyAgICBjb25zdCBSZXNUYWJsZV9jb25maWcqIGNvbmZpZywKKyAgICBjb25zdCBSZXNUYWJsZV90eXBlKiogb3V0VHlwZSwgY29uc3QgUmVzVGFibGVfZW50cnkqKiBvdXRFbnRyeSwKKyAgICBjb25zdCBUeXBlKiogb3V0VHlwZUNsYXNzKSBjb25zdAoreworICAgIExPR1YoIkdldHRpbmcgZW50cnkgZnJvbSBwYWNrYWdlICVwXG4iLCBwYWNrYWdlKTsKKyAgICBjb25zdCBSZXNUYWJsZV9wYWNrYWdlKiBjb25zdCBwa2cgPSBwYWNrYWdlLT5wYWNrYWdlOworCisgICAgY29uc3QgVHlwZSogYWxsVHlwZXMgPSBwYWNrYWdlLT5nZXRUeXBlKHR5cGVJbmRleCk7CisgICAgTE9HVigiYWxsVHlwZXM9JXBcbiIsIGFsbFR5cGVzKTsKKyAgICBpZiAoYWxsVHlwZXMgPT0gTlVMTCkgeworICAgICAgICBMT0dWKCJTa2lwcGluZyBlbnRyeSB0eXBlIGluZGV4IDB4JTAyeCBiZWNhdXNlIHR5cGUgaXMgTlVMTCFcbiIsIHR5cGVJbmRleCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICgoc2l6ZV90KWVudHJ5SW5kZXggPj0gYWxsVHlwZXMtPmVudHJ5Q291bnQpIHsKKyAgICAgICAgTE9HVygiZ2V0RW50cnkgZmFpbGluZyBiZWNhdXNlIGVudHJ5SW5kZXggJWQgaXMgYmV5b25kIHR5cGUgZW50cnlDb3VudCAlZCIsCisgICAgICAgICAgICBlbnRyeUluZGV4LCAoaW50KWFsbFR5cGVzLT5lbnRyeUNvdW50KTsKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworICAgIH0KKyAgICAgICAgCisgICAgY29uc3QgUmVzVGFibGVfdHlwZSogdHlwZSA9IE5VTEw7CisgICAgdWludDMyX3Qgb2Zmc2V0ID0gUmVzVGFibGVfdHlwZTo6Tk9fRU5UUlk7CisgICAgUmVzVGFibGVfY29uZmlnIGJlc3RDb25maWc7CisgICAgbWVtc2V0KCZiZXN0Q29uZmlnLCAwLCBzaXplb2YoYmVzdENvbmZpZykpOyAvLyBtYWtlIHRoZSBjb21waWxlciBzaHV0IHVwCisgICAgCisgICAgY29uc3Qgc2l6ZV90IE5UID0gYWxsVHlwZXMtPmNvbmZpZ3Muc2l6ZSgpOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOVDsgaSsrKSB7CisgICAgICAgIGNvbnN0IFJlc1RhYmxlX3R5cGUqIGNvbnN0IHRoaXNUeXBlID0gYWxsVHlwZXMtPmNvbmZpZ3NbaV07CisgICAgICAgIGlmICh0aGlzVHlwZSA9PSBOVUxMKSBjb250aW51ZTsKKyAgICAgICAgCisgICAgICAgIFJlc1RhYmxlX2NvbmZpZyB0aGlzQ29uZmlnOworICAgICAgICB0aGlzQ29uZmlnLmNvcHlGcm9tRHRvSCh0aGlzVHlwZS0+Y29uZmlnKTsKKworICAgICAgICBUQUJMRV9HRVRFTlRSWShMT0dJKCJNYXRjaCBlbnRyeSAweCV4IGluIHR5cGUgMHgleCAoc3ogMHgleCk6IGltc2k6JWQvJWQ9JWQvJWQgbGFuZzolYyVjPSVjJWMgY250OiVjJWM9JWMlYyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yaWVuOiVkPSVkIHRvdWNoOiVkPSVkIGRlbnNpdHk6JWQ9JWQga2V5OiVkPSVkIGlucDolZD0lZCBuYXY6JWQ9JWQgdzolZD0lZCBoOiVkPSVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnlJbmRleCwgdHlwZUluZGV4KzEsIGR0b2hsKHRoaXNUeXBlLT5jb25maWcuc2l6ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLm1jYywgdGhpc0NvbmZpZy5tbmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgPyBjb25maWctPm1jYyA6IDAsIGNvbmZpZyA/IGNvbmZpZy0+bW5jIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcubGFuZ3VhZ2VbMF0gPyB0aGlzQ29uZmlnLmxhbmd1YWdlWzBdIDogJy0nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5sYW5ndWFnZVsxXSA/IHRoaXNDb25maWcubGFuZ3VhZ2VbMV0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgJiYgY29uZmlnLT5sYW5ndWFnZVswXSA/IGNvbmZpZy0+bGFuZ3VhZ2VbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgJiYgY29uZmlnLT5sYW5ndWFnZVsxXSA/IGNvbmZpZy0+bGFuZ3VhZ2VbMV0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLmNvdW50cnlbMF0gPyB0aGlzQ29uZmlnLmNvdW50cnlbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLmNvdW50cnlbMV0gPyB0aGlzQ29uZmlnLmNvdW50cnlbMV0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgJiYgY29uZmlnLT5jb3VudHJ5WzBdID8gY29uZmlnLT5jb3VudHJ5WzBdIDogJy0nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnICYmIGNvbmZpZy0+Y291bnRyeVsxXSA/IGNvbmZpZy0+Y291bnRyeVsxXSA6ICctJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcub3JpZW50YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgPyBjb25maWctPm9yaWVudGF0aW9uIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcudG91Y2hzY3JlZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgPyBjb25maWctPnRvdWNoc2NyZWVuIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcuZGVuc2l0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyA/IGNvbmZpZy0+ZGVuc2l0eSA6IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLmtleWJvYXJkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnID8gY29uZmlnLT5rZXlib2FyZCA6IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLmlucHV0RmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgPyBjb25maWctPmlucHV0RmxhZ3MgOiAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5uYXZpZ2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnID8gY29uZmlnLT5uYXZpZ2F0aW9uIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcuc2NyZWVuV2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcgPyBjb25maWctPnNjcmVlbldpZHRoIDogMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcuc2NyZWVuSGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnID8gY29uZmlnLT5zY3JlZW5IZWlnaHQgOiAwKSk7CisgICAgICAgIAorICAgICAgICAvLyBDaGVjayB0byBtYWtlIHN1cmUgdGhpcyBvbmUgaXMgdmFsaWQgZm9yIHRoZSBjdXJyZW50IHBhcmFtZXRlcnMuCisgICAgICAgIGlmIChjb25maWcgJiYgIXRoaXNDb25maWcubWF0Y2goKmNvbmZpZykpIHsKKyAgICAgICAgICAgIFRBQkxFX0dFVEVOVFJZKExPR0koIkRvZXMgbm90IG1hdGNoIGNvbmZpZyFcbiIpKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyB0aGUgZGVzaXJlZCBlbnRyeSBpbiB0aGlzIHR5cGUuCisgICAgICAgIAorICAgICAgICBjb25zdCB1aW50OF90KiBjb25zdCBlbmQgPSAoKGNvbnN0IHVpbnQ4X3QqKXRoaXNUeXBlKQorICAgICAgICAgICAgKyBkdG9obCh0aGlzVHlwZS0+aGVhZGVyLnNpemUpOworICAgICAgICBjb25zdCB1aW50MzJfdCogY29uc3QgZWluZGV4ID0gKGNvbnN0IHVpbnQzMl90KikKKyAgICAgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKXRoaXNUeXBlKSArIGR0b2hzKHRoaXNUeXBlLT5oZWFkZXIuaGVhZGVyU2l6ZSkpOworICAgICAgICAKKyAgICAgICAgdWludDMyX3QgdGhpc09mZnNldCA9IGR0b2hsKGVpbmRleFtlbnRyeUluZGV4XSk7CisgICAgICAgIGlmICh0aGlzT2Zmc2V0ID09IFJlc1RhYmxlX3R5cGU6Ok5PX0VOVFJZKSB7CisgICAgICAgICAgICBUQUJMRV9HRVRFTlRSWShMT0dJKCJTa2lwcGluZyBiZWNhdXNlIGl0IGlzIG5vdCBkZWZpbmVkIVxuIikpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmICh0eXBlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgb25lIGlzIGxlc3Mgc3BlY2lmaWMgdGhhbiB0aGUgbGFzdCBmb3VuZC4gIElmIHNvLAorICAgICAgICAgICAgLy8gd2Ugd2lsbCBza2lwIGl0LiAgV2UgY2hlY2sgc3RhcnRpbmcgd2l0aCB0aGluZ3Mgd2UgbW9zdCBjYXJlCisgICAgICAgICAgICAvLyBhYm91dCB0byB0aG9zZSB3ZSBsZWFzdCBjYXJlIGFib3V0LgorICAgICAgICAgICAgaWYgKCF0aGlzQ29uZmlnLmlzQmV0dGVyVGhhbihiZXN0Q29uZmlnLCBjb25maWcpKSB7CisgICAgICAgICAgICAgICAgVEFCTEVfR0VURU5UUlkoTE9HSSgiVGhpcyBjb25maWcgaXMgd29yc2UgdGhhbiBsYXN0IVxuIikpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIAorICAgICAgICB0eXBlID0gdGhpc1R5cGU7CisgICAgICAgIG9mZnNldCA9IHRoaXNPZmZzZXQ7CisgICAgICAgIGJlc3RDb25maWcgPSB0aGlzQ29uZmlnOworICAgICAgICBUQUJMRV9HRVRFTlRSWShMT0dJKCJCZXN0IGVudHJ5IHNvIGZhciAtLSB1c2luZyBpdCFcbiIpKTsKKyAgICAgICAgaWYgKCFjb25maWcpIGJyZWFrOworICAgIH0KKyAgICAKKyAgICBpZiAodHlwZSA9PSBOVUxMKSB7CisgICAgICAgIFRBQkxFX0dFVEVOVFJZKExPR0koIk5vIHZhbHVlIGZvdW5kIGZvciByZXF1ZXN0ZWQgZW50cnkhXG4iKSk7CisgICAgICAgIHJldHVybiBCQURfSU5ERVg7CisgICAgfQorICAgIAorICAgIG9mZnNldCArPSBkdG9obCh0eXBlLT5lbnRyaWVzU3RhcnQpOworICAgIFRBQkxFX05PSVNZKGFvdXQgPDwgIkxvb2tpbmcgaW4gcmVzb3VyY2UgdGFibGUgIiA8PCBwYWNrYWdlLT5oZWFkZXItPmhlYWRlcgorICAgICAgICAgIDw8ICIsIHR5cGVPZmY9IgorICAgICAgICAgIDw8ICh2b2lkKikoKChjb25zdCBjaGFyKil0eXBlKS0oKGNvbnN0IGNoYXIqKXBhY2thZ2UtPmhlYWRlci0+aGVhZGVyKSkKKyAgICAgICAgICA8PCAiLCBvZmZzZXQ9IiA8PCAodm9pZCopb2Zmc2V0IDw8IGVuZGwpOworCisgICAgaWYgKG9mZnNldCA+IChkdG9obCh0eXBlLT5oZWFkZXIuc2l6ZSktc2l6ZW9mKFJlc1RhYmxlX2VudHJ5KSkpIHsKKyAgICAgICAgTE9HVygiUmVzVGFibGVfZW50cnkgYXQgMHgleCBpcyBiZXlvbmQgdHlwZSBjaHVuayBkYXRhIDB4JXgiLAorICAgICAgICAgICAgIG9mZnNldCwgZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpKTsKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworICAgIH0KKyAgICBpZiAoKG9mZnNldCYweDMpICE9IDApIHsKKyAgICAgICAgTE9HVygiUmVzVGFibGVfZW50cnkgYXQgMHgleCBpcyBub3Qgb24gYW4gaW50ZWdlciBib3VuZGFyeSIsCisgICAgICAgICAgICAgb2Zmc2V0KTsKKyAgICAgICAgcmV0dXJuIEJBRF9UWVBFOworICAgIH0KKworICAgIGNvbnN0IFJlc1RhYmxlX2VudHJ5KiBjb25zdCBlbnRyeSA9IChjb25zdCBSZXNUYWJsZV9lbnRyeSopCisgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKXR5cGUpICsgb2Zmc2V0KTsKKyAgICBpZiAoZHRvaHMoZW50cnktPnNpemUpIDwgc2l6ZW9mKCplbnRyeSkpIHsKKyAgICAgICAgTE9HVygiUmVzVGFibGVfZW50cnkgc2l6ZSAweCV4IGlzIHRvbyBzbWFsbCIsIGR0b2hzKGVudHJ5LT5zaXplKSk7CisgICAgICAgIHJldHVybiBCQURfVFlQRTsKKyAgICB9CisKKyAgICAqb3V0VHlwZSA9IHR5cGU7CisgICAgKm91dEVudHJ5ID0gZW50cnk7CisgICAgaWYgKG91dFR5cGVDbGFzcyAhPSBOVUxMKSB7CisgICAgICAgICpvdXRUeXBlQ2xhc3MgPSBhbGxUeXBlczsKKyAgICB9CisgICAgcmV0dXJuIG9mZnNldCArIGR0b2hzKGVudHJ5LT5zaXplKTsKK30KKworc3RhdHVzX3QgUmVzVGFibGU6OnBhcnNlUGFja2FnZShjb25zdCBSZXNUYWJsZV9wYWNrYWdlKiBjb25zdCBwa2csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEhlYWRlciogY29uc3QgaGVhZGVyKQoreworICAgIGNvbnN0IHVpbnQ4X3QqIGJhc2UgPSAoY29uc3QgdWludDhfdCopcGtnOworICAgIHN0YXR1c190IGVyciA9IHZhbGlkYXRlX2NodW5rKCZwa2ctPmhlYWRlciwgc2l6ZW9mKCpwa2cpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci0+ZGF0YUVuZCwgIlJlc1RhYmxlX3BhY2thZ2UiKTsKKyAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgIHJldHVybiAobUVycm9yPWVycik7CisgICAgfQorCisgICAgY29uc3Qgc2l6ZV90IHBrZ1NpemUgPSBkdG9obChwa2ctPmhlYWRlci5zaXplKTsKKworICAgIGlmIChkdG9obChwa2ctPnR5cGVTdHJpbmdzKSA+PSBwa2dTaXplKSB7CisgICAgICAgIExPR1coIlJlc1RhYmxlX3BhY2thZ2UgdHlwZSBzdHJpbmdzIGF0ICVwIGFyZSBwYXN0IGNodW5rIHNpemUgJXAuIiwKKyAgICAgICAgICAgICAodm9pZCopZHRvaGwocGtnLT50eXBlU3RyaW5ncyksICh2b2lkKilwa2dTaXplKTsKKyAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgIH0KKyAgICBpZiAoKGR0b2hsKHBrZy0+dHlwZVN0cmluZ3MpJjB4MykgIT0gMCkgeworICAgICAgICBMT0dXKCJSZXNUYWJsZV9wYWNrYWdlIHR5cGUgc3RyaW5ncyBhdCAlcCBpcyBub3Qgb24gYW4gaW50ZWdlciBib3VuZGFyeS4iLAorICAgICAgICAgICAgICh2b2lkKilkdG9obChwa2ctPnR5cGVTdHJpbmdzKSk7CisgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICB9CisgICAgaWYgKGR0b2hsKHBrZy0+a2V5U3RyaW5ncykgPj0gcGtnU2l6ZSkgeworICAgICAgICBMT0dXKCJSZXNUYWJsZV9wYWNrYWdlIGtleSBzdHJpbmdzIGF0ICVwIGFyZSBwYXN0IGNodW5rIHNpemUgJXAuIiwKKyAgICAgICAgICAgICAodm9pZCopZHRvaGwocGtnLT5rZXlTdHJpbmdzKSwgKHZvaWQqKXBrZ1NpemUpOworICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgfQorICAgIGlmICgoZHRvaGwocGtnLT5rZXlTdHJpbmdzKSYweDMpICE9IDApIHsKKyAgICAgICAgTE9HVygiUmVzVGFibGVfcGFja2FnZSBrZXkgc3RyaW5ncyBhdCAlcCBpcyBub3Qgb24gYW4gaW50ZWdlciBib3VuZGFyeS4iLAorICAgICAgICAgICAgICh2b2lkKilkdG9obChwa2ctPmtleVN0cmluZ3MpKTsKKyAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgIH0KKyAgICAKKyAgICBQYWNrYWdlKiBwYWNrYWdlID0gTlVMTDsKKyAgICBQYWNrYWdlR3JvdXAqIGdyb3VwID0gTlVMTDsKKyAgICB1aW50MzJfdCBpZCA9IGR0b2hsKHBrZy0+aWQpOworICAgIGlmIChpZCAhPSAwICYmIGlkIDwgMjU2KSB7CisgICAgICAgIHNpemVfdCBpZHggPSBtUGFja2FnZU1hcFtpZF07CisgICAgICAgIGlmIChpZHggPT0gMCkgeworICAgICAgICAgICAgaWR4ID0gbVBhY2thZ2VHcm91cHMuc2l6ZSgpKzE7CisKKyAgICAgICAgICAgIGNoYXIxNl90IHRtcE5hbWVbc2l6ZW9mKHBrZy0+bmFtZSkvc2l6ZW9mKGNoYXIxNl90KV07CisgICAgICAgICAgICBzdHJjcHkxNl9kdG9oKHRtcE5hbWUsIHBrZy0+bmFtZSwgc2l6ZW9mKHBrZy0+bmFtZSkvc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgICAgICAgICBncm91cCA9IG5ldyBQYWNrYWdlR3JvdXAoU3RyaW5nMTYodG1wTmFtZSksIGlkKTsKKyAgICAgICAgICAgIGlmIChncm91cCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9Tk9fTUVNT1JZKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZXJyID0gZ3JvdXAtPnR5cGVTdHJpbmdzLnNldFRvKGJhc2UrZHRvaGwocGtnLT50eXBlU3RyaW5ncyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLT5kYXRhRW5kLShiYXNlK2R0b2hsKHBrZy0+dHlwZVN0cmluZ3MpKSk7CisgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9ZXJyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVyciA9IGdyb3VwLT5rZXlTdHJpbmdzLnNldFRvKGJhc2UrZHRvaGwocGtnLT5rZXlTdHJpbmdzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci0+ZGF0YUVuZC0oYmFzZStkdG9obChwa2ctPmtleVN0cmluZ3MpKSk7CisgICAgICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9ZXJyKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy9wcmludGYoIkFkZGluZyBuZXcgcGFja2FnZSBpZCAlZCBhdCBpbmRleCAlZFxuIiwgaWQsIGlkeCk7CisgICAgICAgICAgICBlcnIgPSBtUGFja2FnZUdyb3Vwcy5hZGQoZ3JvdXApOworICAgICAgICAgICAgaWYgKGVyciA8IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9ZXJyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1QYWNrYWdlTWFwW2lkXSA9ICh1aW50OF90KWlkeDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdyb3VwID0gbVBhY2thZ2VHcm91cHMuaXRlbUF0KGlkeC0xKTsKKyAgICAgICAgICAgIGlmIChncm91cCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9VU5LTk9XTl9FUlJPUik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcGFja2FnZSA9IG5ldyBQYWNrYWdlKGhlYWRlciwgcGtnKTsKKyAgICAgICAgaWYgKHBhY2thZ2UgPT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9Tk9fTUVNT1JZKTsKKyAgICAgICAgfQorICAgICAgICBlcnIgPSBncm91cC0+cGFja2FnZXMuYWRkKHBhY2thZ2UpOworICAgICAgICBpZiAoZXJyIDwgTk9fRVJST1IpIHsKKyAgICAgICAgICAgIHJldHVybiAobUVycm9yPWVycik7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBMT0dfQUxXQVlTX0ZBVEFMKCJTa2lucyBub3Qgc3VwcG9ydGVkISIpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgCisgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBjaHVua3MuCisgICAgc2l6ZV90IGN1clBhY2thZ2UgPSAwOworICAgIAorICAgIGNvbnN0IFJlc0NodW5rX2hlYWRlciogY2h1bmsgPQorICAgICAgICAoY29uc3QgUmVzQ2h1bmtfaGVhZGVyKikoKChjb25zdCB1aW50OF90Kilwa2cpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGR0b2hzKHBrZy0+aGVhZGVyLmhlYWRlclNpemUpKTsKKyAgICBjb25zdCB1aW50OF90KiBlbmRQb3MgPSAoKGNvbnN0IHVpbnQ4X3QqKXBrZykgKyBkdG9ocyhwa2ctPmhlYWRlci5zaXplKTsKKyAgICB3aGlsZSAoKChjb25zdCB1aW50OF90KiljaHVuaykgPD0gKGVuZFBvcy1zaXplb2YoUmVzQ2h1bmtfaGVhZGVyKSkgJiYKKyAgICAgICAgICAgKChjb25zdCB1aW50OF90KiljaHVuaykgPD0gKGVuZFBvcy1kdG9obChjaHVuay0+c2l6ZSkpKSB7CisgICAgICAgIFRBQkxFX05PSVNZKExPR1YoIlBhY2thZ2VDaHVuazogdHlwZT0weCV4LCBoZWFkZXJTaXplPTB4JXgsIHNpemU9MHgleCwgcG9zPSVwXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hzKGNodW5rLT50eXBlKSwgZHRvaHMoY2h1bmstPmhlYWRlclNpemUpLCBkdG9obChjaHVuay0+c2l6ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKSgoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSAtICgoY29uc3QgdWludDhfdCopaGVhZGVyLT5oZWFkZXIpKSkpOworICAgICAgICBjb25zdCBzaXplX3QgY3NpemUgPSBkdG9obChjaHVuay0+c2l6ZSk7CisgICAgICAgIGNvbnN0IHVpbnQxNl90IGN0eXBlID0gZHRvaHMoY2h1bmstPnR5cGUpOworICAgICAgICBpZiAoY3R5cGUgPT0gUkVTX1RBQkxFX1RZUEVfU1BFQ19UWVBFKSB7CisgICAgICAgICAgICBjb25zdCBSZXNUYWJsZV90eXBlU3BlYyogdHlwZVNwZWMgPSAoY29uc3QgUmVzVGFibGVfdHlwZVNwZWMqKShjaHVuayk7CisgICAgICAgICAgICBlcnIgPSB2YWxpZGF0ZV9jaHVuaygmdHlwZVNwZWMtPmhlYWRlciwgc2l6ZW9mKCp0eXBlU3BlYyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQb3MsICJSZXNUYWJsZV90eXBlU3BlYyIpOworICAgICAgICAgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgIHJldHVybiAobUVycm9yPWVycik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGNvbnN0IHNpemVfdCB0eXBlU3BlY1NpemUgPSBkdG9obCh0eXBlU3BlYy0+aGVhZGVyLnNpemUpOworICAgICAgICAgICAgCisgICAgICAgICAgICBMT0FEX1RBQkxFX05PSVNZKHByaW50ZigiVHlwZVNwZWMgb2ZmICVwOiB0eXBlPTB4JXgsIGhlYWRlclNpemU9MHgleCwgc2l6ZT0lcFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKikoYmFzZS0oY29uc3QgdWludDhfdCopY2h1bmspLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRvaHModHlwZVNwZWMtPmhlYWRlci50eXBlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hzKHR5cGVTcGVjLT5oZWFkZXIuaGVhZGVyU2l6ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopdHlwZVNpemUpKTsKKyAgICAgICAgICAgIC8vIGxvb2sgZm9yIGJsb2NrIG92ZXJydW4gb3IgaW50IG92ZXJmbG93IHdoZW4gbXVsdGlwbHlpbmcgYnkgNAorICAgICAgICAgICAgaWYgKChkdG9obCh0eXBlU3BlYy0+ZW50cnlDb3VudCkgPiAoSU5UMzJfTUFYL3NpemVvZih1aW50MzJfdCkpCisgICAgICAgICAgICAgICAgICAgIHx8IGR0b2hzKHR5cGVTcGVjLT5oZWFkZXIuaGVhZGVyU2l6ZSkrKHNpemVvZih1aW50MzJfdCkqZHRvaGwodHlwZVNwZWMtPmVudHJ5Q291bnQpKQorICAgICAgICAgICAgICAgICAgICA+IHR5cGVTcGVjU2l6ZSkpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV90eXBlU3BlYyBlbnRyeSBpbmRleCB0byAlcCBleHRlbmRzIGJleW9uZCBjaHVuayBlbmQgJXAuIiwKKyAgICAgICAgICAgICAgICAgICAgICh2b2lkKikoZHRvaHModHlwZVNwZWMtPmhlYWRlci5oZWFkZXJTaXplKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICArKHNpemVvZih1aW50MzJfdCkqZHRvaGwodHlwZVNwZWMtPmVudHJ5Q291bnQpKSksCisgICAgICAgICAgICAgICAgICAgICAodm9pZCopdHlwZVNwZWNTaXplKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGlmICh0eXBlU3BlYy0+aWQgPT0gMCkgeworICAgICAgICAgICAgICAgIExPR1coIlJlc1RhYmxlX3R5cGUgaGFzIGFuIGlkIG9mIDAuIik7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICB3aGlsZSAocGFja2FnZS0+dHlwZXMuc2l6ZSgpIDwgdHlwZVNwZWMtPmlkKSB7CisgICAgICAgICAgICAgICAgcGFja2FnZS0+dHlwZXMuYWRkKE5VTEwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgVHlwZSogdCA9IHBhY2thZ2UtPnR5cGVzW3R5cGVTcGVjLT5pZC0xXTsKKyAgICAgICAgICAgIGlmICh0ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICB0ID0gbmV3IFR5cGUoaGVhZGVyLCBwYWNrYWdlLCBkdG9obCh0eXBlU3BlYy0+ZW50cnlDb3VudCkpOworICAgICAgICAgICAgICAgIHBhY2thZ2UtPnR5cGVzLmVkaXRJdGVtQXQodHlwZVNwZWMtPmlkLTEpID0gdDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZHRvaGwodHlwZVNwZWMtPmVudHJ5Q291bnQpICE9IHQtPmVudHJ5Q291bnQpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV90eXBlU3BlYyBlbnRyeSBjb3VudCBpbmNvbnNpc3RlbnQ6IGdpdmVuICVkLCBwcmV2aW91c2x5ICVkIiwKKyAgICAgICAgICAgICAgICAgICAgKGludClkdG9obCh0eXBlU3BlYy0+ZW50cnlDb3VudCksIChpbnQpdC0+ZW50cnlDb3VudCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChtRXJyb3I9QkFEX1RZUEUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdC0+dHlwZVNwZWNGbGFncyA9IChjb25zdCB1aW50MzJfdCopKAorICAgICAgICAgICAgICAgICAgICAoKGNvbnN0IHVpbnQ4X3QqKXR5cGVTcGVjKSArIGR0b2hzKHR5cGVTcGVjLT5oZWFkZXIuaGVhZGVyU2l6ZSkpOworICAgICAgICAgICAgdC0+dHlwZVNwZWMgPSB0eXBlU3BlYzsKKyAgICAgICAgICAgIAorICAgICAgICB9IGVsc2UgaWYgKGN0eXBlID09IFJFU19UQUJMRV9UWVBFX1RZUEUpIHsKKyAgICAgICAgICAgIGNvbnN0IFJlc1RhYmxlX3R5cGUqIHR5cGUgPSAoY29uc3QgUmVzVGFibGVfdHlwZSopKGNodW5rKTsKKyAgICAgICAgICAgIGVyciA9IHZhbGlkYXRlX2NodW5rKCZ0eXBlLT5oZWFkZXIsIHNpemVvZigqdHlwZSktc2l6ZW9mKFJlc1RhYmxlX2NvbmZpZykrNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBvcywgIlJlc1RhYmxlX3R5cGUiKTsKKyAgICAgICAgICAgIGlmIChlcnIgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1lcnIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICBjb25zdCBzaXplX3QgdHlwZVNpemUgPSBkdG9obCh0eXBlLT5oZWFkZXIuc2l6ZSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIExPQURfVEFCTEVfTk9JU1kocHJpbnRmKCJUeXBlIG9mZiAlcDogdHlwZT0weCV4LCBoZWFkZXJTaXplPTB4JXgsIHNpemU9JXBcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopKGJhc2UtKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hzKHR5cGUtPmhlYWRlci50eXBlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hzKHR5cGUtPmhlYWRlci5oZWFkZXJTaXplKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKil0eXBlU2l6ZSkpOworICAgICAgICAgICAgaWYgKGR0b2hzKHR5cGUtPmhlYWRlci5oZWFkZXJTaXplKSsoc2l6ZW9mKHVpbnQzMl90KSpkdG9obCh0eXBlLT5lbnRyeUNvdW50KSkKKyAgICAgICAgICAgICAgICA+IHR5cGVTaXplKSB7CisgICAgICAgICAgICAgICAgTE9HVygiUmVzVGFibGVfdHlwZSBlbnRyeSBpbmRleCB0byAlcCBleHRlbmRzIGJleW9uZCBjaHVuayBlbmQgJXAuIiwKKyAgICAgICAgICAgICAgICAgICAgICh2b2lkKikoZHRvaHModHlwZS0+aGVhZGVyLmhlYWRlclNpemUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsoc2l6ZW9mKHVpbnQzMl90KSpkdG9obCh0eXBlLT5lbnRyeUNvdW50KSkpLAorICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKXR5cGVTaXplKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZHRvaGwodHlwZS0+ZW50cnlDb3VudCkgIT0gMAorICAgICAgICAgICAgICAgICYmIGR0b2hsKHR5cGUtPmVudHJpZXNTdGFydCkgPiAodHlwZVNpemUtc2l6ZW9mKFJlc1RhYmxlX2VudHJ5KSkpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV90eXBlIGVudHJpZXNTdGFydCBhdCAlcCBleHRlbmRzIGJleW9uZCBjaHVuayBlbmQgJXAuIiwKKyAgICAgICAgICAgICAgICAgICAgICh2b2lkKilkdG9obCh0eXBlLT5lbnRyaWVzU3RhcnQpLCAodm9pZCopdHlwZVNpemUpOworICAgICAgICAgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0eXBlLT5pZCA9PSAwKSB7CisgICAgICAgICAgICAgICAgTE9HVygiUmVzVGFibGVfdHlwZSBoYXMgYW4gaWQgb2YgMC4iKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKG1FcnJvcj1CQURfVFlQRSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHdoaWxlIChwYWNrYWdlLT50eXBlcy5zaXplKCkgPCB0eXBlLT5pZCkgeworICAgICAgICAgICAgICAgIHBhY2thZ2UtPnR5cGVzLmFkZChOVUxMKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFR5cGUqIHQgPSBwYWNrYWdlLT50eXBlc1t0eXBlLT5pZC0xXTsKKyAgICAgICAgICAgIGlmICh0ID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICB0ID0gbmV3IFR5cGUoaGVhZGVyLCBwYWNrYWdlLCBkdG9obCh0eXBlLT5lbnRyeUNvdW50KSk7CisgICAgICAgICAgICAgICAgcGFja2FnZS0+dHlwZXMuZWRpdEl0ZW1BdCh0eXBlLT5pZC0xKSA9IHQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGR0b2hsKHR5cGUtPmVudHJ5Q291bnQpICE9IHQtPmVudHJ5Q291bnQpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJSZXNUYWJsZV90eXBlIGVudHJ5IGNvdW50IGluY29uc2lzdGVudDogZ2l2ZW4gJWQsIHByZXZpb3VzbHkgJWQiLAorICAgICAgICAgICAgICAgICAgICAoaW50KWR0b2hsKHR5cGUtPmVudHJ5Q291bnQpLCAoaW50KXQtPmVudHJ5Q291bnQpOworICAgICAgICAgICAgICAgIHJldHVybiAobUVycm9yPUJBRF9UWVBFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgVEFCTEVfR0VURU5UUlkoCisgICAgICAgICAgICAgICAgUmVzVGFibGVfY29uZmlnIHRoaXNDb25maWc7CisgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5jb3B5RnJvbUR0b0godHlwZS0+Y29uZmlnKTsKKyAgICAgICAgICAgICAgICBMT0dJKCJBZGRpbmcgY29uZmlnIHRvIHR5cGUgJWQ6IGltc2k6JWQvJWQgbGFuZzolYyVjIGNudDolYyVjICIKKyAgICAgICAgICAgICAgICAgICAgICJvcmllbjolZCB0b3VjaDolZCBkZW5zaXR5OiVkIGtleTolZCBpbnA6JWQgbmF2OiVkIHc6JWQgaDolZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5pZCwKKyAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLm1jYywgdGhpc0NvbmZpZy5tbmMsCisgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5sYW5ndWFnZVswXSA/IHRoaXNDb25maWcubGFuZ3VhZ2VbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5sYW5ndWFnZVsxXSA/IHRoaXNDb25maWcubGFuZ3VhZ2VbMV0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5jb3VudHJ5WzBdID8gdGhpc0NvbmZpZy5jb3VudHJ5WzBdIDogJy0nLAorICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcuY291bnRyeVsxXSA/IHRoaXNDb25maWcuY291bnRyeVsxXSA6ICctJywKKyAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLm9yaWVudGF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcudG91Y2hzY3JlZW4sCisgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5kZW5zaXR5LAorICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcua2V5Ym9hcmQsCisgICAgICAgICAgICAgICAgICAgICAgdGhpc0NvbmZpZy5pbnB1dEZsYWdzLAorICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcubmF2aWdhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29uZmlnLnNjcmVlbldpZHRoLAorICAgICAgICAgICAgICAgICAgICAgIHRoaXNDb25maWcuc2NyZWVuSGVpZ2h0KSk7CisgICAgICAgICAgICB0LT5jb25maWdzLmFkZCh0eXBlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN0YXR1c190IGVyciA9IHZhbGlkYXRlX2NodW5rKGNodW5rLCBzaXplb2YoUmVzQ2h1bmtfaGVhZGVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBvcywgIlJlc1RhYmxlX3BhY2thZ2U6dW5rbm93biIpOworICAgICAgICAgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgICAgIHJldHVybiAobUVycm9yPWVycik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2h1bmsgPSAoY29uc3QgUmVzQ2h1bmtfaGVhZGVyKikKKyAgICAgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKWNodW5rKSArIGNzaXplKTsKKyAgICB9CisKKyAgICBpZiAoZ3JvdXAtPnR5cGVDb3VudCA9PSAwKSB7CisgICAgICAgIGdyb3VwLT50eXBlQ291bnQgPSBwYWNrYWdlLT50eXBlcy5zaXplKCk7CisgICAgfQorICAgIAorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworI2lmbmRlZiBIQVZFX0FORFJPSURfT1MKKyNkZWZpbmUgQ0hBUjE2X1RPX0NTVFIoYzE2LCBsZW4pIChTdHJpbmc4KFN0cmluZzE2KGMxNixsZW4pKS5zdHJpbmcoKSkKKworI2RlZmluZSBDSEFSMTZfQVJSQVlfRVEoY29uc3RhbnQsIHZhciwgbGVuKSBcCisgICAgICAgICgobGVuID09IChzaXplb2YoY29uc3RhbnQpL3NpemVvZihjb25zdGFudFswXSkpKSAmJiAoMCA9PSBtZW1jbXAoKHZhciksIChjb25zdGFudCksIChsZW4pKSkpCisKK3ZvaWQgUmVzVGFibGU6OnByaW50KCkgY29uc3QKK3sKKyAgICBwcmludGYoIm1FcnJvcj0weCV4ICglcylcbiIsIG1FcnJvciwgc3RyZXJyb3IobUVycm9yKSk7CisjaWYgMAorICAgIHByaW50ZigibVBhcmFtcz0lYyVjLSVjJWMsXG4iLAorICAgICAgICAgICAgbVBhcmFtcy5sYW5ndWFnZVswXSwgbVBhcmFtcy5sYW5ndWFnZVsxXSwKKyAgICAgICAgICAgIG1QYXJhbXMuY291bnRyeVswXSwgbVBhcmFtcy5jb3VudHJ5WzFdKTsKKyNlbmRpZgorICAgIHNpemVfdCBwZ0NvdW50ID0gbVBhY2thZ2VHcm91cHMuc2l6ZSgpOworICAgIHByaW50ZigiUGFja2FnZSBHcm91cHMgKCVkKVxuIiwgKGludClwZ0NvdW50KTsKKyAgICBmb3IgKHNpemVfdCBwZ0luZGV4PTA7IHBnSW5kZXg8cGdDb3VudDsgcGdJbmRleCsrKSB7CisgICAgICAgIGNvbnN0IFBhY2thZ2VHcm91cCogcGcgPSBtUGFja2FnZUdyb3Vwc1twZ0luZGV4XTsKKyAgICAgICAgcHJpbnRmKCJQYWNrYWdlIEdyb3VwICVkIGlkPSVkIHBhY2thZ2VDb3VudD0lZCBuYW1lPSVzXG4iLAorICAgICAgICAgICAgICAgIChpbnQpcGdJbmRleCwgcGctPmlkLCAoaW50KXBnLT5wYWNrYWdlcy5zaXplKCksCisgICAgICAgICAgICAgICAgU3RyaW5nOChwZy0+bmFtZSkuc3RyaW5nKCkpOworICAgICAgICAKKyAgICAgICAgc2l6ZV90IHBrZ0NvdW50ID0gcGctPnBhY2thZ2VzLnNpemUoKTsKKyAgICAgICAgZm9yIChzaXplX3QgcGtnSW5kZXg9MDsgcGtnSW5kZXg8cGtnQ291bnQ7IHBrZ0luZGV4KyspIHsKKyAgICAgICAgICAgIGNvbnN0IFBhY2thZ2UqIHBrZyA9IHBnLT5wYWNrYWdlc1twa2dJbmRleF07CisgICAgICAgICAgICBzaXplX3QgdHlwZUNvdW50ID0gcGtnLT50eXBlcy5zaXplKCk7CisgICAgICAgICAgICBwcmludGYoIiAgUGFja2FnZSAlZCBpZD0lZCBuYW1lPSVzIHR5cGVDb3VudD0lZFxuIiwgKGludClwa2dJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgcGtnLT5wYWNrYWdlLT5pZCwgU3RyaW5nOChTdHJpbmcxNihwa2ctPnBhY2thZ2UtPm5hbWUpKS5zdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGludCl0eXBlQ291bnQpOworICAgICAgICAgICAgZm9yIChzaXplX3QgdHlwZUluZGV4PTA7IHR5cGVJbmRleDx0eXBlQ291bnQ7IHR5cGVJbmRleCsrKSB7CisgICAgICAgICAgICAgICAgY29uc3QgVHlwZSogdHlwZUNvbmZpZ3MgPSBwa2ctPmdldFR5cGUodHlwZUluZGV4KTsKKyAgICAgICAgICAgICAgICBpZiAodHlwZUNvbmZpZ3MgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAgICB0eXBlICVkIE5VTExcbiIsIChpbnQpdHlwZUluZGV4KTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCBOVEMgPSB0eXBlQ29uZmlncy0+Y29uZmlncy5zaXplKCk7CisgICAgICAgICAgICAgICAgcHJpbnRmKCIgICAgdHlwZSAlZCBjb25maWdDb3VudD0lZCBlbnRyeUNvdW50PSVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAoaW50KXR5cGVJbmRleCwgKGludClOVEMsIChpbnQpdHlwZUNvbmZpZ3MtPmVudHJ5Q291bnQpOworICAgICAgICAgICAgICAgIGlmICh0eXBlQ29uZmlncy0+dHlwZVNwZWNGbGFncyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IGVudHJ5SW5kZXg9MDsgZW50cnlJbmRleDx0eXBlQ29uZmlncy0+ZW50cnlDb3VudDsgZW50cnlJbmRleCsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByZXNJRCA9ICgweGZmMDAwMDAwICYgKChwa2ctPnBhY2thZ2UtPmlkKTw8MjQpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAoMHgwMGZmMDAwMCAmICgodHlwZUluZGV4KzEpPDwxNikpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICgweDAwMDBmZmZmICYgKGVudHJ5SW5kZXgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlX25hbWUgcmVzTmFtZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMtPmdldFJlc291cmNlTmFtZShyZXNJRCwgJnJlc05hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgICAgICBzcGVjIHJlc291cmNlIDB4JTA4eCAlczolcy8lczogZmxhZ3M9MHglMDh4XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0lELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQVIxNl9UT19DU1RSKHJlc05hbWUucGFja2FnZSwgcmVzTmFtZS5wYWNrYWdlTGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFSMTZfVE9fQ1NUUihyZXNOYW1lLnR5cGUsIHJlc05hbWUudHlwZUxlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUjE2X1RPX0NTVFIocmVzTmFtZS5uYW1lLCByZXNOYW1lLm5hbWVMZW4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hsKHR5cGVDb25maWdzLT50eXBlU3BlY0ZsYWdzW2VudHJ5SW5kZXhdKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChzaXplX3QgY29uZmlnSW5kZXg9MDsgY29uZmlnSW5kZXg8TlRDOyBjb25maWdJbmRleCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlc1RhYmxlX3R5cGUqIHR5cGUgPSB0eXBlQ29uZmlncy0+Y29uZmlnc1tjb25maWdJbmRleF07CisgICAgICAgICAgICAgICAgICAgIGlmICgoKCh1aW50NjRfdCl0eXBlKSYweDMpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiICAgICAgTk9OLUlOVEVHRVIgUmVzVGFibGVfdHlwZSBBRERSRVNTOiAlcFxuIiwgdHlwZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAgICAgIGNvbmZpZyAlZCBsYW5nPSVjJWMgY250PSVjJWMgb3JpZW49JWQgdG91Y2g9JWQgZGVuc2l0eT0lZCBrZXk9JWQgaW5mbD0lZCBuYXY9JWQgdz0lZCBoPSVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludCljb25maWdJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbmZpZy5sYW5ndWFnZVswXSA/IHR5cGUtPmNvbmZpZy5sYW5ndWFnZVswXSA6ICctJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbmZpZy5sYW5ndWFnZVsxXSA/IHR5cGUtPmNvbmZpZy5sYW5ndWFnZVsxXSA6ICctJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbmZpZy5jb3VudHJ5WzBdID8gdHlwZS0+Y29uZmlnLmNvdW50cnlbMF0gOiAnLScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5jb25maWcuY291bnRyeVsxXSA/IHR5cGUtPmNvbmZpZy5jb3VudHJ5WzFdIDogJy0nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29uZmlnLm9yaWVudGF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29uZmlnLnRvdWNoc2NyZWVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRvaHModHlwZS0+Y29uZmlnLmRlbnNpdHkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29uZmlnLmtleWJvYXJkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29uZmlnLmlucHV0RmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5jb25maWcubmF2aWdhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0b2hzKHR5cGUtPmNvbmZpZy5zY3JlZW5XaWR0aCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBkdG9ocyh0eXBlLT5jb25maWcuc2NyZWVuSGVpZ2h0KSk7CisgICAgICAgICAgICAgICAgICAgIHNpemVfdCBlbnRyeUNvdW50ID0gZHRvaGwodHlwZS0+ZW50cnlDb3VudCk7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGVudHJpZXNTdGFydCA9IGR0b2hsKHR5cGUtPmVudHJpZXNTdGFydCk7CisgICAgICAgICAgICAgICAgICAgIGlmICgoZW50cmllc1N0YXJ0JjB4MykgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgICAgICBOT04tSU5URUdFUiBSZXNUYWJsZV90eXBlIGVudHJpZXNTdGFydCBPRkZTRVQ6ICVwXG4iLCAodm9pZCopZW50cmllc1N0YXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHR5cGVTaXplID0gZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpOworICAgICAgICAgICAgICAgICAgICBpZiAoKHR5cGVTaXplJjB4MykgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgICAgICBOT04tSU5URUdFUiBSZXNUYWJsZV90eXBlIGhlYWRlci5zaXplOiAlcFxuIiwgKHZvaWQqKXR5cGVTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZvciAoc2l6ZV90IGVudHJ5SW5kZXg9MDsgZW50cnlJbmRleDxlbnRyeUNvdW50OyBlbnRyeUluZGV4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCogY29uc3QgZW5kID0gKChjb25zdCB1aW50OF90Kil0eXBlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZHRvaGwodHlwZS0+aGVhZGVyLnNpemUpOworICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDMyX3QqIGNvbnN0IGVpbmRleCA9IChjb25zdCB1aW50MzJfdCopCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopdHlwZSkgKyBkdG9ocyh0eXBlLT5oZWFkZXIuaGVhZGVyU2l6ZSkpOworICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0aGlzT2Zmc2V0ID0gZHRvaGwoZWluZGV4W2VudHJ5SW5kZXhdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzT2Zmc2V0ID09IFJlc1RhYmxlX3R5cGU6Ok5PX0VOVFJZKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHJlc0lEID0gKDB4ZmYwMDAwMDAgJiAoKHBrZy0+cGFja2FnZS0+aWQpPDwyNCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICgweDAwZmYwMDAwICYgKCh0eXBlSW5kZXgrMSk8PDE2KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKDB4MDAwMGZmZmYgJiAoZW50cnlJbmRleCkpOworICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VfbmFtZSByZXNOYW1lOworICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy0+Z2V0UmVzb3VyY2VOYW1lKHJlc0lELCAmcmVzTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAgICAgICAgcmVzb3VyY2UgMHglMDh4ICVzOiVzLyVzOiAiLCByZXNJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUjE2X1RPX0NTVFIocmVzTmFtZS5wYWNrYWdlLCByZXNOYW1lLnBhY2thZ2VMZW4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFSMTZfVE9fQ1NUUihyZXNOYW1lLnR5cGUsIHJlc05hbWUudHlwZUxlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQVIxNl9UT19DU1RSKHJlc05hbWUubmFtZSwgcmVzTmFtZS5uYW1lTGVuKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRoaXNPZmZzZXQmMHgzKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJOT04tSU5URUdFUiBPRkZTRVQ6ICVwXG4iLCAodm9pZCopdGhpc09mZnNldCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRoaXNPZmZzZXQrc2l6ZW9mKFJlc1RhYmxlX2VudHJ5KSkgPiB0eXBlU2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiT0ZGU0VUIE9VVCBPRiBCT1VORFM6ICVwKyVwIChzaXplIGlzICVwKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKWVudHJpZXNTdGFydCwgKHZvaWQqKXRoaXNPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKil0eXBlU2l6ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlc1RhYmxlX2VudHJ5KiBlbnQgPSAoY29uc3QgUmVzVGFibGVfZW50cnkqKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKGNvbnN0IHVpbnQ4X3QqKXR5cGUpICsgZW50cmllc1N0YXJ0ICsgdGhpc09mZnNldCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChlbnRyaWVzU3RhcnQgKyB0aGlzT2Zmc2V0KSYweDMpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIk5PTi1JTlRFR0VSIFJlc1RhYmxlX2VudHJ5IE9GRlNFVDogJXBcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopKGVudHJpZXNTdGFydCArIHRoaXNPZmZzZXQpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZHRvaHMoZW50LT5mbGFncykmUmVzVGFibGVfZW50cnk6OkZMQUdfQ09NUExFWCkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiPGJhZz4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDE2X3QgZXNpemUgPSBkdG9ocyhlbnQtPnNpemUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZXNpemUmMHgzKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiTk9OLUlOVEVHRVIgUmVzVGFibGVfZW50cnkgU0laRTogJXBcbiIsICh2b2lkKillc2l6ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRoaXNPZmZzZXQrZXNpemUpID4gdHlwZVNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJSZXNUYWJsZV9lbnRyeSBPVVQgT0YgQk9VTkRTOiAlcCslcCslcCAoc2l6ZSBpcyAlcClcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopZW50cmllc1N0YXJ0LCAodm9pZCopdGhpc09mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKillc2l6ZSwgKHZvaWQqKXR5cGVTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlc192YWx1ZSogdmFsdWUgPSAoY29uc3QgUmVzX3ZhbHVlKikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCgoY29uc3QgdWludDhfdCopZW50KSArIGVzaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoInQ9MHglMDJ4IGQ9MHglMDh4IChzPTB4JTA0eCByPTB4JTAyeCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXZhbHVlLT5kYXRhVHlwZSwgKGludClkdG9obCh2YWx1ZS0+ZGF0YSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpZHRvaHModmFsdWUtPnNpemUpLCAoaW50KXZhbHVlLT5yZXMwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChkdG9ocyhlbnQtPmZsYWdzKSZSZXNUYWJsZV9lbnRyeTo6RkxBR19QVUJMSUMpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAoUFVCTElDKSIpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJcbiIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCisjZW5kaWYgLy8gSEFWRV9BTkRST0lEX09TCisKK30gICAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9TaGFyZWRCdWZmZXIuY3BwIGIvbGlicy91dGlscy9TaGFyZWRCdWZmZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1NTVmYjcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1NoYXJlZEJ1ZmZlci5jcHAKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDx1dGlscy9TaGFyZWRCdWZmZXIuaD4KKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworU2hhcmVkQnVmZmVyKiBTaGFyZWRCdWZmZXI6OmFsbG9jKHNpemVfdCBzaXplKQoreworICAgIFNoYXJlZEJ1ZmZlciogc2IgPSBzdGF0aWNfY2FzdDxTaGFyZWRCdWZmZXIgKj4obWFsbG9jKHNpemVvZihTaGFyZWRCdWZmZXIpICsgc2l6ZSkpOworICAgIGlmIChzYikgeworICAgICAgICBzYi0+bVJlZnMgPSAxOworICAgICAgICBzYi0+bVNpemUgPSBzaXplOworICAgIH0KKyAgICByZXR1cm4gc2I7Cit9CisKKworc3NpemVfdCBTaGFyZWRCdWZmZXI6OmRlYWxsb2MoY29uc3QgU2hhcmVkQnVmZmVyKiByZWxlYXNlZCkKK3sKKyAgICBpZiAocmVsZWFzZWQtPm1SZWZzICE9IDApIHJldHVybiAtMTsgLy8gWFhYOiBpbnZhbGlkIG9wZXJhdGlvbgorICAgIGZyZWUoY29uc3RfY2FzdDxTaGFyZWRCdWZmZXIqPihyZWxlYXNlZCkpOworICAgIHJldHVybiAwOworfQorCitTaGFyZWRCdWZmZXIqIFNoYXJlZEJ1ZmZlcjo6ZWRpdCgpIGNvbnN0Cit7CisgICAgaWYgKG9ubHlPd25lcigpKSB7CisgICAgICAgIHJldHVybiBjb25zdF9jYXN0PFNoYXJlZEJ1ZmZlcio+KHRoaXMpOworICAgIH0KKyAgICBTaGFyZWRCdWZmZXIqIHNiID0gYWxsb2MobVNpemUpOworICAgIGlmIChzYikgeworICAgICAgICBtZW1jcHkoc2ItPmRhdGEoKSwgZGF0YSgpLCBzaXplKCkpOworICAgICAgICByZWxlYXNlKCk7CisgICAgfQorICAgIHJldHVybiBzYjsgICAgCit9CisKK1NoYXJlZEJ1ZmZlciogU2hhcmVkQnVmZmVyOjplZGl0UmVzaXplKHNpemVfdCBuZXdTaXplKSBjb25zdAoreworICAgIGlmIChvbmx5T3duZXIoKSkgeworICAgICAgICBTaGFyZWRCdWZmZXIqIGJ1ZiA9IGNvbnN0X2Nhc3Q8U2hhcmVkQnVmZmVyKj4odGhpcyk7CisgICAgICAgIGlmIChidWYtPm1TaXplID09IG5ld1NpemUpIHJldHVybiBidWY7CisgICAgICAgIGJ1ZiA9IChTaGFyZWRCdWZmZXIqKXJlYWxsb2MoYnVmLCBzaXplb2YoU2hhcmVkQnVmZmVyKSArIG5ld1NpemUpOworICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGJ1Zi0+bVNpemUgPSBuZXdTaXplOworICAgICAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICAgICAgfQorICAgIH0KKyAgICBTaGFyZWRCdWZmZXIqIHNiID0gYWxsb2MobmV3U2l6ZSk7CisgICAgaWYgKHNiKSB7CisgICAgICAgIGNvbnN0IHNpemVfdCBteVNpemUgPSBtU2l6ZTsKKyAgICAgICAgbWVtY3B5KHNiLT5kYXRhKCksIGRhdGEoKSwgbmV3U2l6ZSA8IG15U2l6ZSA/IG5ld1NpemUgOiBteVNpemUpOworICAgICAgICByZWxlYXNlKCk7CisgICAgfQorICAgIHJldHVybiBzYjsgICAgCit9CisKK1NoYXJlZEJ1ZmZlciogU2hhcmVkQnVmZmVyOjphdHRlbXB0RWRpdCgpIGNvbnN0Cit7CisgICAgaWYgKG9ubHlPd25lcigpKSB7CisgICAgICAgIHJldHVybiBjb25zdF9jYXN0PFNoYXJlZEJ1ZmZlcio+KHRoaXMpOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworU2hhcmVkQnVmZmVyKiBTaGFyZWRCdWZmZXI6OnJlc2V0KHNpemVfdCBuZXdfc2l6ZSkgY29uc3QKK3sKKyAgICAvLyBjaGVhcC1vLXJlc2V0LgorICAgIFNoYXJlZEJ1ZmZlciogc2IgPSBhbGxvYyhuZXdfc2l6ZSk7CisgICAgaWYgKHNiKSB7CisgICAgICAgIHJlbGVhc2UoKTsKKyAgICB9CisgICAgcmV0dXJuIHNiOworfQorCit2b2lkIFNoYXJlZEJ1ZmZlcjo6YWNxdWlyZSgpIGNvbnN0IHsKKyAgICBhbmRyb2lkX2F0b21pY19pbmMoJm1SZWZzKTsKK30KKworaW50MzJfdCBTaGFyZWRCdWZmZXI6OnJlbGVhc2UodWludDMyX3QgZmxhZ3MpIGNvbnN0Cit7CisgICAgaW50MzJfdCBwcmV2ID0gMTsKKyAgICBpZiAob25seU93bmVyKCkgfHwgKChwcmV2ID0gYW5kcm9pZF9hdG9taWNfZGVjKCZtUmVmcykpID09IDEpKSB7CisgICAgICAgIG1SZWZzID0gMDsKKyAgICAgICAgaWYgKChmbGFncyAmIGVLZWVwU3RvcmFnZSkgPT0gMCkgeworICAgICAgICAgICAgZnJlZShjb25zdF9jYXN0PFNoYXJlZEJ1ZmZlcio+KHRoaXMpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcHJldjsKK30KKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9Tb2NrZXQuY3BwIGIvbGlicy91dGlscy9Tb2NrZXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxNTA5YTMKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1NvY2tldC5jcHAKQEAgLTAsMCArMSwzODggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gSW50ZXJuZXQgYWRkcmVzcyBjbGFzcy4KKy8vCisKKyNpZmRlZiBIQVZFX1dJTlNPQ0sKKy8vIFRoaXMgbmVlZHMgdG8gY29tZSBmaXJzdCwgb3IgQ3lnd2luIGdldHMgY29uY2VybmVkIGFib3V0IGEgcG90ZW50aWFsCisvLyBjbGFzaCBiZXR3ZWVuIFdpblNvY2sgYW5kIDxzeXMvdHlwZXMuaD4uCisjIGluY2x1ZGUgPHdpbnNvY2syLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPHV0aWxzL1NvY2tldC5oPgorI2luY2x1ZGUgPHV0aWxzL2luZXRfYWRkcmVzcy5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL1RpbWVycy5oPgorCisjaWZuZGVmIEhBVkVfV0lOU09DSworIyBpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyMgaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorIyBpbmNsdWRlIDxuZXRpbmV0L2luLmg+CisjIGluY2x1ZGUgPGFycGEvaW5ldC5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgU29ja2V0CisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqLworCisjaWZuZGVmIElOVkFMSURfU09DS0VUCisjIGRlZmluZSBJTlZBTElEX1NPQ0tFVCAoLTEpCisjZW5kaWYKKyNkZWZpbmUgVU5ERUZfU09DS0VUICAgKCh1bnNpZ25lZCBsb25nKSBJTlZBTElEX1NPQ0tFVCkKKworLypzdGF0aWMqLyBib29sIFNvY2tldDo6bUJvb3RJbml0aWFsaXplZCA9IGZhbHNlOworCisvKgorICogRXh0cmFjdCBzeXN0ZW0tZGVwZW5kZW50IGVycm9yIGNvZGUuCisgKi8KK3N0YXRpYyBpbmxpbmUgaW50IGdldFNvY2tldEVycm9yKHZvaWQpIHsKKyNpZmRlZiBIQVZFX1dJTlNPQ0sKKyAgICByZXR1cm4gV1NBR2V0TGFzdEVycm9yKCk7CisjZWxzZQorICAgIHJldHVybiBlcnJubzsKKyNlbmRpZgorfQorCisvKgorICogT25lLXRpbWUgaW5pdGlhbGl6YXRpb24gZm9yIHNvY2tldCBjb2RlLgorICovCisvKnN0YXRpYyovIGJvb2wgU29ja2V0Ojpib290SW5pdCh2b2lkKQoreworI2lmZGVmIEhBVkVfV0lOU09DSworICAgIFdTQURBVEEgd3NhRGF0YTsKKyAgICBpbnQgZXJyOworCisgICAgZXJyID0gV1NBU3RhcnR1cChNQUtFV09SRCgyLCAwKSwgJndzYURhdGEpOworICAgIGlmIChlcnIgIT0gMCkgeworICAgICAgICBMT0coTE9HX0VSUk9SLCAic29ja2V0IiwgIlVuYWJsZSB0byBzdGFydCBXaW5Tb2NrXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIExPRyhMT0dfSU5GTywgInNvY2tldCIsICJVc2luZyBXaW5Tb2NrIHYlZC4lZFxuIiwKKyAgICAgICAgTE9CWVRFKHdzYURhdGEud1ZlcnNpb24pLCBISUJZVEUod3NhRGF0YS53VmVyc2lvbikpOworI2VuZGlmCisKKyAgICBtQm9vdEluaXRpYWxpemVkID0gdHJ1ZTsKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIE9uZS10aW1lIHNodXRkb3duIGZvciBzb2NrZXQgY29kZS4KKyAqLworLypzdGF0aWMqLyB2b2lkIFNvY2tldDo6ZmluYWxTaHV0ZG93bih2b2lkKQoreworI2lmZGVmIEhBVkVfV0lOU09DSworICAgIFdTQUNsZWFudXAoKTsKKyNlbmRpZgorICAgIG1Cb290SW5pdGlhbGl6ZWQgPSBmYWxzZTsKK30KKworCisvKgorICogU2ltcGxlIGNvbnN0cnVjdG9yLiAgQWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGNyZWF0ZSB1cyBhbmQgdGhlbiBtYWtlCisgKiBiaW5kL2Nvbm5lY3QgY2FsbHMuCisgKi8KK1NvY2tldDo6U29ja2V0KHZvaWQpCisgICAgOiBtU29jayhVTkRFRl9TT0NLRVQpCit7CisgICAgaWYgKCFtQm9vdEluaXRpYWxpemVkKQorICAgICAgICBMT0coTE9HX1dBUk4sICJzb2NrZXQiLCAiV0FSTklORzogc29ja2V0cyBub3QgaW5pdGlhbGl6ZWRcbiIpOworfQorCisvKgorICogRGVzdHJ1Y3Rvci4gIENsb3NlcyB0aGUgc29ja2V0IGFuZCByZXNldHMgb3VyIHN0b3JhZ2UuCisgKi8KK1NvY2tldDo6flNvY2tldCh2b2lkKQoreworICAgIGNsb3NlKCk7Cit9CisKKworLyoKKyAqIENyZWF0ZSBhIHNvY2tldCBhbmQgY29ubmVjdCB0byB0aGUgc3BlY2lmaWVkIGhvc3QgYW5kIHBvcnQuCisgKi8KK2ludCBTb2NrZXQ6OmNvbm5lY3QoY29uc3QgY2hhciogaG9zdCwgaW50IHBvcnQpCit7CisgICAgaWYgKG1Tb2NrICE9IFVOREVGX1NPQ0tFVCkgeworICAgICAgICBMT0coTE9HX1dBUk4sICJzb2NrZXQiLCAiU29ja2V0IGFscmVhZHkgY29ubmVjdGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIEluZXRTb2NrZXRBZGRyZXNzIHNvY2tBZGRyOworICAgIGlmICghc29ja0FkZHIuY3JlYXRlKGhvc3QsIHBvcnQpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICAvL3JldHVybiBkb0Nvbm5lY3Qoc29ja0FkZHIpOworICAgIGludCBmb287CisgICAgZm9vID0gZG9Db25uZWN0KHNvY2tBZGRyKTsKKyAgICByZXR1cm4gZm9vOworfQorCisvKgorICogQ3JlYXRlIGEgc29ja2V0IGFuZCBjb25uZWN0IHRvIHRoZSBzcGVjaWZpZWQgaG9zdCBhbmQgcG9ydC4KKyAqLworaW50IFNvY2tldDo6Y29ubmVjdChjb25zdCBJbmV0QWRkcmVzcyogYWRkciwgaW50IHBvcnQpCit7CisgICAgaWYgKG1Tb2NrICE9IFVOREVGX1NPQ0tFVCkgeworICAgICAgICBMT0coTE9HX1dBUk4sICJzb2NrZXQiLCAiU29ja2V0IGFscmVhZHkgY29ubmVjdGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIEluZXRTb2NrZXRBZGRyZXNzIHNvY2tBZGRyOworICAgIGlmICghc29ja0FkZHIuY3JlYXRlKGFkZHIsIHBvcnQpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICByZXR1cm4gZG9Db25uZWN0KHNvY2tBZGRyKTsKK30KKworLyoKKyAqIEZpbmlzaCBjcmVhdGluZyBhIHNvY2tldCBieSBjb25uZWN0aW5nIHRvIHRoZSByZW1vdGUgaG9zdC4KKyAqCisgKiBSZXR1cm5zIDAgb24gc3VjY2Vzcy4KKyAqLworaW50IFNvY2tldDo6ZG9Db25uZWN0KGNvbnN0IEluZXRTb2NrZXRBZGRyZXNzJiBzb2NrQWRkcikKK3sKKyNpZmRlZiBIQVZFX1dJTlNPQ0sKKyAgICBTT0NLRVQgc29jazsKKyNlbHNlCisgICAgaW50IHNvY2s7CisjZW5kaWYKKyAgICBjb25zdCBJbmV0QWRkcmVzcyogYWRkciA9IHNvY2tBZGRyLmdldEFkZHJlc3MoKTsKKyAgICBpbnQgcG9ydCA9IHNvY2tBZGRyLmdldFBvcnQoKTsKKyAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gaW5hZGRyOworICAgIER1cmF0aW9uVGltZXIgY29ubmVjdFRpbWVyOworCisgICAgYXNzZXJ0KHNpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pID09IGFkZHItPmdldEFkZHJlc3NMZW5ndGgoKSk7CisgICAgbWVtY3B5KCZpbmFkZHIsIGFkZHItPmdldEFkZHJlc3MoKSwgYWRkci0+Z2V0QWRkcmVzc0xlbmd0aCgpKTsKKyAgICBpbmFkZHIuc2luX3BvcnQgPSBodG9ucyhwb3J0KTsKKworICAgIC8vZnByaW50ZihzdGRlcnIsICItLS0gY29ubmVjdGluZyB0byAlczolZFxuIiwKKyAgICAvLyAgICBzb2NrQWRkci5nZXRIb3N0TmFtZSgpLCBwb3J0KTsKKworICAgIHNvY2sgPSA6OnNvY2tldChQRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApOworICAgIGlmIChzb2NrID09IElOVkFMSURfU09DS0VUKSB7CisgICAgICAgIGludCBlcnIgPSBnZXRTb2NrZXRFcnJvcigpOworICAgICAgICBMT0coTE9HX0VSUk9SLCAic29ja2V0IiwgIlVuYWJsZSB0byBjcmVhdGUgc29ja2V0IChlcnI9JWQpXG4iLCBlcnIpOworICAgICAgICByZXR1cm4gKGVyciAhPSAwKSA/IGVyciA6IC0xOworICAgIH0KKworICAgIGNvbm5lY3RUaW1lci5zdGFydCgpOworCisgICAgaWYgKDo6Y29ubmVjdChzb2NrLCAoc3RydWN0IHNvY2thZGRyKikgJmluYWRkciwgc2l6ZW9mKGluYWRkcikpICE9IDApIHsKKyAgICAgICAgaW50IGVyciA9IGdldFNvY2tldEVycm9yKCk7CisgICAgICAgIExPRyhMT0dfV0FSTiwgInNvY2tldCIsICJDb25uZWN0IHRvICVzOiVkIGZhaWxlZDogJWRcbiIsCisgICAgICAgICAgICBzb2NrQWRkci5nZXRIb3N0TmFtZSgpLCBwb3J0LCBlcnIpOworICAgICAgICByZXR1cm4gKGVyciAhPSAwKSA/IGVyciA6IC0xOworICAgIH0KKworICAgIGNvbm5lY3RUaW1lci5zdG9wKCk7CisgICAgaWYgKChsb25nKSBjb25uZWN0VGltZXIuZHVyYXRpb25Vc2VjcygpID4gMTAwMDAwKSB7CisgICAgICAgIExPRyhMT0dfSU5GTywgInNvY2tldCIsCisgICAgICAgICAgICAiQ29ubmVjdCB0byAlczolZCB0b29rICUuM2ZzXG4iLCBzb2NrQWRkci5nZXRIb3N0TmFtZSgpLAorICAgICAgICAgICAgcG9ydCwgKChsb25nKSBjb25uZWN0VGltZXIuZHVyYXRpb25Vc2VjcygpKSAvIDEwMDAwMDAuMCk7CisgICAgfQorCisgICAgbVNvY2sgPSAodW5zaWduZWQgbG9uZykgc29jazsKKyAgICBMT0coTE9HX1ZFUkJPU0UsICJzb2NrZXQiLAorICAgICAgICAiLS0tIGNvbm5lY3RlZCB0byAlczolZFxuIiwgc29ja0FkZHIuZ2V0SG9zdE5hbWUoKSwgcG9ydCk7CisgICAgcmV0dXJuIDA7Cit9CisKKworLyoKKyAqIENsb3NlIHRoZSBzb2NrZXQgaWYgaXQgbmVlZHMgY2xvc2luZy4KKyAqLworYm9vbCBTb2NrZXQ6OmNsb3NlKHZvaWQpCit7CisgICAgaWYgKG1Tb2NrICE9IFVOREVGX1NPQ0tFVCkgeworICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiLS0tIGNsb3Npbmcgc29ja2V0ICVsdVxuIiwgbVNvY2spOworI2lmZGVmIEhBVkVfV0lOU09DSworICAgICAgICBpZiAoOjpjbG9zZXNvY2tldCgoU09DS0VUKSBtU29jaykgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyNlbHNlCisgICAgICAgIGlmICg6OmNsb3NlKChpbnQpIG1Tb2NrKSAhPSAwKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworI2VuZGlmCisgICAgfQorCisgICAgbVNvY2sgPSBVTkRFRl9TT0NLRVQ7CisKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIFJlYWQgZGF0YSBmcm9tIHNvY2tldC4KKyAqCisgKiBTdGFuZGFyZCBzZW1hbnRpY3M6IHJlYWQgdXAgdG8gImxlbiIgYnl0ZXMgaW50byAiYnVmIi4gIFJldHVybnMgdGhlCisgKiBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgbGVzcyB0aGFuIHplcm8gb24gZXJyb3IuCisgKi8KK2ludCBTb2NrZXQ6OnJlYWQodm9pZCogYnVmLCBzc2l6ZV90IGxlbikgY29uc3QKK3sKKyAgICBpZiAobVNvY2sgPT0gVU5ERUZfU09DS0VUKSB7CisgICAgICAgIExPRyhMT0dfRVJST1IsICJzb2NrZXQiLCAiRVJST1I6IHJlYWQgb24gaW52YWxpZCBzb2NrZXRcbiIpOworICAgICAgICByZXR1cm4gLTUwMDsKKyAgICB9CisKKyNpZmRlZiBIQVZFX1dJTlNPQ0sKKyAgICBTT0NLRVQgc29jayA9IChTT0NLRVQpIG1Tb2NrOworI2Vsc2UKKyAgICBpbnQgc29jayA9IChpbnQpIG1Tb2NrOworI2VuZGlmCisgICAgaW50IGNjOworCisgICAgY2MgPSByZWN2KHNvY2ssIChjaGFyKilidWYsIGxlbiwgMCk7CisgICAgaWYgKGNjIDwgMCkgeworICAgICAgICBpbnQgZXJyID0gZ2V0U29ja2V0RXJyb3IoKTsKKyAgICAgICAgcmV0dXJuIChlcnIgPiAwKSA/IC1lcnIgOiAtMTsKKyAgICB9CisKKyAgICByZXR1cm4gY2M7Cit9CisKKy8qCisgKiBXcml0ZSBkYXRhIHRvIGEgc29ja2V0LgorICoKKyAqIFN0YW5kYXJkIHNlbWFudGljczogd3JpdGUgdXAgdG8gImxlbiIgYnl0ZXMgaW50byAiYnVmIi4gIFJldHVybnMgdGhlCisgKiBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiwgb3IgbGVzcyB0aGFuIHplcm8gb24gZXJyb3IuCisgKi8KK2ludCBTb2NrZXQ6OndyaXRlKGNvbnN0IHZvaWQqIGJ1Ziwgc3NpemVfdCBsZW4pIGNvbnN0Cit7CisgICAgaWYgKG1Tb2NrID09IFVOREVGX1NPQ0tFVCkgeworICAgICAgICBMT0coTE9HX0VSUk9SLCAic29ja2V0IiwgIkVSUk9SOiB3cml0ZSBvbiBpbnZhbGlkIHNvY2tldFxuIik7CisgICAgICAgIHJldHVybiAtNTAwOworICAgIH0KKworI2lmZGVmIEhBVkVfV0lOU09DSworICAgIFNPQ0tFVCBzb2NrID0gKFNPQ0tFVCkgbVNvY2s7CisjZWxzZQorICAgIGludCBzb2NrID0gKGludCkgbVNvY2s7CisjZW5kaWYKKyAgICBpbnQgY2M7CisKKyAgICBjYyA9IHNlbmQoc29jaywgKGNvbnN0IGNoYXIqKWJ1ZiwgbGVuLCAwKTsKKyAgICBpZiAoY2MgPCAwKSB7CisgICAgICAgIGludCBlcnIgPSBnZXRTb2NrZXRFcnJvcigpOworICAgICAgICByZXR1cm4gKGVyciA+IDApID8gLWVyciA6IC0xOworICAgIH0KKworICAgIHJldHVybiBjYzsKK30KKworCisvKgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiAgICAgIFNvY2tldCB0ZXN0cworICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworLyoKKyAqIFJlYWQgYWxsIGRhdGEgZnJvbSB0aGUgc29ja2V0LiAgVGhlIGRhdGEgaXMgcmVhZCBpbnRvIGEgYnVmZmVyIHRoYXQKKyAqIGV4cGFuZHMgYXMgbmVlZGVkLgorICoKKyAqIE9uIGV4aXQsIHRoZSBidWZmZXIgaXMgcmV0dXJuZWQsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGlzIHN0b3JlZAorICogaW4gIipzeiIuICBBIG51bGwgYnl0ZSBpcyBhZGRlZCB0byB0aGUgZW5kLCBidXQgaXMgbm90IGluY2x1ZGVkIGluCisgKiB0aGUgbGVuZ3RoLgorICovCitzdGF0aWMgY2hhciogc29ja2V0UmVhZEFsbChjb25zdCBTb2NrZXQmIHMsIGludCAqc3opCit7CisgICAgaW50IG1heCwgcjsKKyAgICBjaGFyICpkYXRhLCAqcHRyLCAqdG1wOworCisgICAgZGF0YSA9IChjaGFyKikgbWFsbG9jKG1heCA9IDMyNzY4KTsKKyAgICBpZiAoZGF0YSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHB0ciA9IGRhdGE7CisgICAgCisgICAgZm9yICg7OykgeworICAgICAgICBpZiAoKHB0ciAtIGRhdGEpID09IG1heCkgeworICAgICAgICAgICAgdG1wID0gKGNoYXIqKSByZWFsbG9jKGRhdGEsIG1heCAqPSAyKTsKKyAgICAgICAgICAgIGlmKHRtcCA9PSAwKSB7CisgICAgICAgICAgICAgICAgZnJlZShkYXRhKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByID0gcy5yZWFkKHB0ciwgbWF4IC0gKHB0ciAtIGRhdGEpKTsKKyAgICAgICAgaWYgKHIgPT0gMCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBpZiAociA8IDApIHsKKyAgICAgICAgICAgIExPRyhMT0dfV0FSTiwgInNvY2tldCIsICJXQVJOSU5HOiBzb2NrZXQgcmVhZCBmYWlsZWQgKHJlcz0lZClcbiIscik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBwdHIgKz0gcjsKKyAgICB9CisKKyAgICBpZiAoKHB0ciAtIGRhdGEpID09IG1heCkgeworICAgICAgICB0bXAgPSAoY2hhciopIHJlYWxsb2MoZGF0YSwgbWF4ICsgMSk7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkgeworICAgICAgICAgICAgZnJlZShkYXRhKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgICpwdHIgPSAnXDAnOworICAgICpzeiA9IChwdHIgLSBkYXRhKTsKKyAgICByZXR1cm4gZGF0YTsKK30KKworLyoKKyAqIEV4ZXJjaXNlIHRoZSBTb2NrZXQgY2xhc3MuCisgKi8KK3ZvaWQgYW5kcm9pZDo6VGVzdFNvY2tldHModm9pZCkKK3sKKyAgICBwcmludGYoIi0tLS0tIFNPQ0tFVCBURVNUIC0tLS0tLVxuIik7CisgICAgU29ja2V0Ojpib290SW5pdCgpOworCisgICAgY2hhciogYnVmID0gTlVMTDsKKyAgICBpbnQgbGVuLCBjYzsKKyAgICBjb25zdCBjaGFyKiBrVGVzdFN0ciA9CisgICAgICAgICJHRVQgLyBIVFRQLzEuMFxuIgorICAgICAgICAiQ29ubmVjdGlvbjogY2xvc2VcbiIKKyAgICAgICAgIlxuIjsKKworICAgIFNvY2tldCBzb2NrOworICAgIGlmIChzb2NrLmNvbm5lY3QoInd3dy5nb29nbGUuY29tIiwgODApICE9IDApIHsKKyAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgY29ubmVjdGVkIGZhaWxlZFxuIik7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICBjYyA9IHNvY2sud3JpdGUoa1Rlc3RTdHIsIHN0cmxlbihrVGVzdFN0cikpOworICAgIGlmIChjYyAhPSAoaW50KSBzdHJsZW4oa1Rlc3RTdHIpKSB7CisgICAgICAgIGZwcmludGYoc3RkZXJyLCAid3JpdGUgZmFpbGVkLCByZXM9JWRcbiIsIGNjKTsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKyAgICBidWYgPSBzb2NrZXRSZWFkQWxsKHNvY2ssICZsZW4pOworCisgICAgcHJpbnRmKCJHT1QgJyVzJ1xuIiwgYnVmKTsKKworYmFpbDoKKyAgICBzb2NrLmNsb3NlKCk7CisgICAgZnJlZShidWYpOworfQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1N0YXRpYy5jcHAgYi9saWJzL3V0aWxzL1N0YXRpYy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTNmN2U0ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvU3RhdGljLmNwcApAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vIEFsbCBzdGF0aWMgdmFyaWFibGVzIGdvIGhlcmUsIHRvIGNvbnRyb2wgaW5pdGlhbGl6YXRpb24gYW5kCisvLyBkZXN0cnVjdGlvbiBvcmRlciBpbiB0aGUgbGlicmFyeS4KKworI2luY2x1ZGUgPHByaXZhdGUvdXRpbHMvU3RhdGljLmg+CisKKyNpbmNsdWRlIDx1dGlscy9CdWZmZXJlZFRleHRPdXRwdXQuaD4KKyNpbmNsdWRlIDx1dGlscy9JUENUaHJlYWRTdGF0ZS5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NsYXNzIExpYlV0aWxzRmlyc3RTdGF0aWNzCit7CitwdWJsaWM6CisgICAgTGliVXRpbHNGaXJzdFN0YXRpY3MoKQorICAgIHsKKyAgICAgICAgaW5pdGlhbGl6ZV9zdHJpbmc4KCk7CisgICAgICAgIGluaXRpYWxpemVfc3RyaW5nMTYoKTsKKyAgICB9CisgICAgCisgICAgfkxpYlV0aWxzRmlyc3RTdGF0aWNzKCkKKyAgICB7CisgICAgICAgIHRlcm1pbmF0ZV9zdHJpbmcxNigpOworICAgICAgICB0ZXJtaW5hdGVfc3RyaW5nOCgpOworICAgIH0KK307CisKK3N0YXRpYyBMaWJVdGlsc0ZpcnN0U3RhdGljcyBnRmlyc3RTdGF0aWNzOworaW50IGdEYXJ3aW5DYW50TG9hZEFsbE9iamVjdHMgPSAxOworCisvLyAtLS0tLS0tLS0tLS0gVGV4dCBvdXRwdXQgc3RyZWFtcworCitWZWN0b3I8aW50MzJfdD4gZ1RleHRCdWZmZXJzOworCitjbGFzcyBMb2dUZXh0T3V0cHV0IDogcHVibGljIEJ1ZmZlcmVkVGV4dE91dHB1dAoreworcHVibGljOgorICAgIExvZ1RleHRPdXRwdXQoKSA6IEJ1ZmZlcmVkVGV4dE91dHB1dChNVUxUSVRIUkVBREVEKSB7IH0KKyAgICB2aXJ0dWFsIH5Mb2dUZXh0T3V0cHV0KCkgeyB9OworCitwcm90ZWN0ZWQ6CisgICAgdmlydHVhbCBzdGF0dXNfdCB3cml0ZUxpbmVzKGNvbnN0IHN0cnVjdCBpb3ZlYyYgdmVjLCBzaXplX3QgTikKKyAgICB7CisgICAgICAgIGFuZHJvaWRfd3JpdGV2TG9nKCZ2ZWMsIE4pOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorfTsKKworY2xhc3MgRmRUZXh0T3V0cHV0IDogcHVibGljIEJ1ZmZlcmVkVGV4dE91dHB1dAoreworcHVibGljOgorICAgIEZkVGV4dE91dHB1dChpbnQgZmQpIDogQnVmZmVyZWRUZXh0T3V0cHV0KE1VTFRJVEhSRUFERUQpLCBtRkQoZmQpIHsgfQorICAgIHZpcnR1YWwgfkZkVGV4dE91dHB1dCgpIHsgfTsKKworcHJvdGVjdGVkOgorICAgIHZpcnR1YWwgc3RhdHVzX3Qgd3JpdGVMaW5lcyhjb25zdCBzdHJ1Y3QgaW92ZWMmIHZlYywgc2l6ZV90IE4pCisgICAgeworICAgICAgICB3cml0ZXYobUZELCAmdmVjLCBOKTsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKworcHJpdmF0ZToKKyAgICBpbnQgbUZEOworfTsKKworc3RhdGljIExvZ1RleHRPdXRwdXQgZ0xvZ1RleHRPdXRwdXQ7CitzdGF0aWMgRmRUZXh0T3V0cHV0IGdTdGRvdXRUZXh0T3V0cHV0KFNURE9VVF9GSUxFTk8pOworc3RhdGljIEZkVGV4dE91dHB1dCBnU3RkZXJyVGV4dE91dHB1dChTVERFUlJfRklMRU5PKTsKKworVGV4dE91dHB1dCYgYWxvZyhnTG9nVGV4dE91dHB1dCk7CitUZXh0T3V0cHV0JiBhb3V0KGdTdGRvdXRUZXh0T3V0cHV0KTsKK1RleHRPdXRwdXQmIGFlcnIoZ1N0ZGVyclRleHRPdXRwdXQpOworCisjaWZuZGVmIExJQlVUSUxTX05BVElWRQorCisvLyAtLS0tLS0tLS0tLS0gUHJvY2Vzc1N0YXRlLmNwcAorCitNdXRleCBnUHJvY2Vzc011dGV4Oworc3A8UHJvY2Vzc1N0YXRlPiBnUHJvY2VzczsKKworY2xhc3MgTGliVXRpbHNJUEN0U3RhdGljcworeworcHVibGljOgorICAgIExpYlV0aWxzSVBDdFN0YXRpY3MoKQorICAgIHsKKyAgICB9CisgICAgCisgICAgfkxpYlV0aWxzSVBDdFN0YXRpY3MoKQorICAgIHsKKyAgICAgICAgSVBDVGhyZWFkU3RhdGU6OnNodXRkb3duKCk7CisgICAgfQorfTsKKworc3RhdGljIExpYlV0aWxzSVBDdFN0YXRpY3MgZ0lQQ1N0YXRpY3M7CisKKy8vIC0tLS0tLS0tLS0tLSBTZXJ2aWNlTWFuYWdlci5jcHAKKworTXV0ZXggZ0RlZmF1bHRTZXJ2aWNlTWFuYWdlckxvY2s7CitzcDxJU2VydmljZU1hbmFnZXI+IGdEZWZhdWx0U2VydmljZU1hbmFnZXI7CitzcDxJUGVybWlzc2lvbkNvbnRyb2xsZXI+IGdQZXJtaXNzaW9uQ29udHJvbGxlcjsKKworI2VuZGlmCisKK30gICAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9TdG9wV2F0Y2guY3BwIGIvbGlicy91dGlscy9TdG9wV2F0Y2guY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4YTFjNTIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1N0b3BXYXRjaC5jcHAKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3RvcFdhdGNoIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKworI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorI2luY2x1ZGUgPHV0aWxzL1N0b3BXYXRjaC5oPgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworCitTdG9wV2F0Y2g6OlN0b3BXYXRjaChjb25zdCBjaGFyICpuYW1lLCBpbnQgY2xvY2ssIHVpbnQzMl90IGZsYWdzKQorICAgIDogICBtTmFtZShuYW1lKSwgbUNsb2NrKGNsb2NrKSwgbUZsYWdzKGZsYWdzKSwKKyAgICAgICAgbVN0YXJ0VGltZSgwKSwgbU51bUxhcHMoMCkKK3sKKyAgICBtU3RhcnRUaW1lID0gc3lzdGVtVGltZShtQ2xvY2spOworfQorCitTdG9wV2F0Y2g6On5TdG9wV2F0Y2goKQoreworICAgIG5zZWNzX3QgZWxhcHNlZCA9IGVsYXBzZWRUaW1lKCk7CisgICAgY29uc3QgaW50IG4gPSBtTnVtTGFwczsKKyAgICBMT0dEKCJTdG9wV2F0Y2ggJXMgKHVzKTogJWxsZCAiLCBtTmFtZSwgbnMydXMoZWxhcHNlZCkpOworICAgIGZvciAoaW50IGk9MCA7IGk8biA7IGkrKykgeworICAgICAgICBjb25zdCBuc2Vjc190IHNvRmFyID0gbUxhcHNbaV0uc29GYXI7CisgICAgICAgIGNvbnN0IG5zZWNzX3QgdGhpc0xhcCA9IG1MYXBzW2ldLnRoaXNMYXA7CisgICAgICAgIExPR0QoIiBbJWQ6ICVsbGQsICVsbGRdIiwgaSwgbnMydXMoc29GYXIpLCBuczJ1cyh0aGlzTGFwKSk7CisgICAgfQorfQorCitjb25zdCBjaGFyKiBTdG9wV2F0Y2g6Om5hbWUoKSBjb25zdAoreworICAgIHJldHVybiBtTmFtZTsKK30KKworbnNlY3NfdCBTdG9wV2F0Y2g6OmxhcCgpCit7CisgICAgbnNlY3NfdCBlbGFwc2VkID0gZWxhcHNlZFRpbWUoKTsKKyAgICBpZiAobU51bUxhcHMgPj0gOCkgeworICAgICAgICBlbGFwc2VkID0gMDsKKyAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBpbnQgbiA9IG1OdW1MYXBzOworICAgICAgICBtTGFwc1tuXS5zb0ZhciAgID0gZWxhcHNlZDsKKyAgICAgICAgbUxhcHNbbl0udGhpc0xhcCA9IG4gPyAoZWxhcHNlZCAtIG1MYXBzW24tMV0uc29GYXIpIDogZWxhcHNlZDsKKyAgICAgICAgbU51bUxhcHMgPSBuKzE7CisgICAgfQorICAgIHJldHVybiBlbGFwc2VkOworfQorCituc2Vjc190IFN0b3BXYXRjaDo6ZWxhcHNlZFRpbWUoKSBjb25zdAoreworICAgIHJldHVybiBzeXN0ZW1UaW1lKG1DbG9jaykgLSBtU3RhcnRUaW1lOworfQorCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9TdHJpbmcxNi5jcHAgYi9saWJzL3V0aWxzL1N0cmluZzE2LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjgxY2FkCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9TdHJpbmcxNi5jcHAKQEAgLTAsMCArMSw2MDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDUgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nMTYuaD4KKworI2luY2x1ZGUgPHV0aWxzL0RlYnVnLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvU3RyaW5nOC5oPgorI2luY2x1ZGUgPHV0aWxzL1RleHRPdXRwdXQuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3V0aWxzL1N0YXRpYy5oPgorCisjaWZkZWYgSEFWRV9XSU5TT0NLCisjIHVuZGVmICBuaHRvbAorIyB1bmRlZiAgaHRvbmwKKyMgdW5kZWYgIG5odG9zCisjIHVuZGVmICBodG9ucworCisjIGlmZGVmIEhBVkVfTElUVExFX0VORElBTgorIyAgZGVmaW5lIG50b2hsKHgpICAgICggKCh4KSA8PCAyNCkgfCAoKCh4KSA+PiAyNCkgJiAyNTUpIHwgKCgoeCkgPDwgOCkgJiAweGZmMDAwMCkgfCAoKCh4KSA+PiA4KSAmIDB4ZmYwMCkgKQorIyAgZGVmaW5lIGh0b25sKHgpICAgIG50b2hsKHgpCisjICBkZWZpbmUgbnRvaHMoeCkgICAgKCAoKCh4KSA8PCA4KSAmIDB4ZmYwMCkgfCAoKCh4KSA+PiA4KSAmIDI1NSkgKQorIyAgZGVmaW5lIGh0b25zKHgpICAgIG50b2hzKHgpCisjIGVsc2UKKyMgIGRlZmluZSBudG9obCh4KSAgICAoeCkKKyMgIGRlZmluZSBodG9ubCh4KSAgICAoeCkKKyMgIGRlZmluZSBudG9ocyh4KSAgICAoeCkKKyMgIGRlZmluZSBodG9ucyh4KSAgICAoeCkKKyMgZW5kaWYKKyNlbHNlCisjIGluY2x1ZGUgPG5ldGluZXQvaW4uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8bWVtb3J5Lmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxjdHlwZS5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworaW50IHN0cmNtcDE2KGNvbnN0IGNoYXIxNl90ICpzMSwgY29uc3QgY2hhcjE2X3QgKnMyKQoreworICBjaGFyMTZfdCBjaDsKKyAgaW50IGQgPSAwOworCisgIHdoaWxlICggMSApIHsKKyAgICBkID0gKGludCkoY2ggPSAqczErKykgLSAoaW50KSpzMisrOworICAgIGlmICggZCB8fCAhY2ggKQorICAgICAgYnJlYWs7CisgIH0KKworICByZXR1cm4gZDsKK30KKworaW50IHN0cm5jbXAxNihjb25zdCBjaGFyMTZfdCAqczEsIGNvbnN0IGNoYXIxNl90ICpzMiwgc2l6ZV90IG4pCit7CisgIGNoYXIxNl90IGNoOworICBpbnQgZCA9IDA7CisKKyAgd2hpbGUgKCBuLS0gKSB7CisgICAgZCA9IChpbnQpKGNoID0gKnMxKyspIC0gKGludCkqczIrKzsKKyAgICBpZiAoIGQgfHwgIWNoICkKKyAgICAgIGJyZWFrOworICB9CisKKyAgcmV0dXJuIGQ7Cit9CisKK2NoYXIxNl90ICpzdHJjcHkxNihjaGFyMTZfdCAqZHN0LCBjb25zdCBjaGFyMTZfdCAqc3JjKQoreworICBjaGFyMTZfdCAqcSA9IGRzdDsKKyAgY29uc3QgY2hhcjE2X3QgKnAgPSBzcmM7CisgIGNoYXIxNl90IGNoOworCisgIGRvIHsKKyAgICAqcSsrID0gY2ggPSAqcCsrOworICB9IHdoaWxlICggY2ggKTsKKworICByZXR1cm4gZHN0OworfQorCitzaXplX3Qgc3RybGVuMTYoY29uc3QgY2hhcjE2X3QgKnMpCit7CisgIGNvbnN0IGNoYXIxNl90ICpzcyA9IHM7CisgIHdoaWxlICggKnNzICkKKyAgICBzcysrOworICByZXR1cm4gc3MtczsKK30KKworCitjaGFyMTZfdCAqc3RybmNweTE2KGNoYXIxNl90ICpkc3QsIGNvbnN0IGNoYXIxNl90ICpzcmMsIHNpemVfdCBuKQoreworICBjaGFyMTZfdCAqcSA9IGRzdDsKKyAgY29uc3QgY2hhcjE2X3QgKnAgPSBzcmM7CisgIGNoYXIgY2g7CisKKyAgd2hpbGUgKG4pIHsKKyAgICBuLS07CisgICAgKnErKyA9IGNoID0gKnArKzsKKyAgICBpZiAoICFjaCApCisgICAgICBicmVhazsKKyAgfQorCisgICpxID0gMDsKKworICByZXR1cm4gZHN0OworfQorCitzaXplX3Qgc3RybmxlbjE2KGNvbnN0IGNoYXIxNl90ICpzLCBzaXplX3QgbWF4bGVuKQoreworICBjb25zdCBjaGFyMTZfdCAqc3MgPSBzOworCisgIC8qIEltcG9ydGFudDogdGhlIG1heGxlbiB0ZXN0IG11c3QgcHJlY2VkZSB0aGUgcmVmZXJlbmNlIHRocm91Z2ggc3M7CisgICAgIHNpbmNlIHRoZSBieXRlIGJleW9uZCB0aGUgbWF4aW11bSBtYXkgc2VnZmF1bHQgKi8KKyAgd2hpbGUgKChtYXhsZW4gPiAwKSAmJiAqc3MpIHsKKyAgICBzcysrOworICAgIG1heGxlbi0tOworICB9CisgIHJldHVybiBzcy1zOworfQorCitpbnQgc3RyemNtcDE2KGNvbnN0IGNoYXIxNl90ICpzMSwgc2l6ZV90IG4xLCBjb25zdCBjaGFyMTZfdCAqczIsIHNpemVfdCBuMikKK3sKKyAgICBjb25zdCBjaGFyMTZfdCogZTEgPSBzMStuMTsKKyAgICBjb25zdCBjaGFyMTZfdCogZTIgPSBzMituMjsKKworICAgIHdoaWxlIChzMSA8IGUxICYmIHMyIDwgZTIpIHsKKyAgICAgICAgY29uc3QgaW50IGQgPSAoaW50KSpzMSsrIC0gKGludCkqczIrKzsKKyAgICAgICAgaWYgKGQpIHsKKyAgICAgICAgICAgIHJldHVybiBkOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIG4xIDwgbjIKKyAgICAgICAgPyAoMCAtIChpbnQpKnMyKQorICAgICAgICA6IChuMSA+IG4yCisgICAgICAgICAgID8gKChpbnQpKnMxIC0gMCkKKyAgICAgICAgICAgOiAwKTsKK30KKworaW50IHN0cnpjbXAxNl9oX24oY29uc3QgY2hhcjE2X3QgKnMxSCwgc2l6ZV90IG4xLCBjb25zdCBjaGFyMTZfdCAqczJOLCBzaXplX3QgbjIpCit7CisgICAgY29uc3QgY2hhcjE2X3QqIGUxID0gczFIK24xOworICAgIGNvbnN0IGNoYXIxNl90KiBlMiA9IHMyTituMjsKKworICAgIHdoaWxlIChzMUggPCBlMSAmJiBzMk4gPCBlMikgeworICAgICAgICBjb25zdCBjaGFyMTZfdCBjMiA9IG50b2hzKCpzMk4pOworICAgICAgICBjb25zdCBpbnQgZCA9IChpbnQpKnMxSCsrIC0gKGludCljMjsKKyAgICAgICAgczJOKys7CisgICAgICAgIGlmIChkKSB7CisgICAgICAgICAgICByZXR1cm4gZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBuMSA8IG4yCisgICAgICAgID8gKDAgLSAoaW50KW50b2hzKCpzMk4pKQorICAgICAgICA6IChuMSA+IG4yCisgICAgICAgICAgID8gKChpbnQpKnMxSCAtIDApCisgICAgICAgICAgIDogMCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3N0YXRpYyBpbmxpbmUgc2l6ZV90Cit1dGY4X2NoYXJfbGVuKHVpbnQ4X3QgY2gpCit7CisgICAgcmV0dXJuICgoMHhlNTAwMDAwMCA+PiAoKGNoID4+IDMpICYgMHgxZSkpICYgMykgKyAxOworfQorCisjZGVmaW5lIFVURjhfU0hJRlRfQU5EX01BU0sodW5pY29kZSwgYnl0ZSkgICh1bmljb2RlKTw8PTY7ICh1bmljb2RlKSB8PSAoMHgzZiAmIChieXRlKSk7CisKK3N0YXRpYyBpbmxpbmUgdWludDMyX3QKK3V0ZjhfdG9fdXRmMzIoY29uc3QgdWludDhfdCAqc3JjLCBzaXplX3QgbGVuZ3RoKQoreworICAgIHVpbnQzMl90IHVuaWNvZGU7CisKKyAgICBzd2l0Y2ggKGxlbmd0aCkKKyAgICB7CisgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIHJldHVybiBzcmNbMF07CisgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIHVuaWNvZGUgPSBzcmNbMF0gJiAweDFmOworICAgICAgICAgICAgVVRGOF9TSElGVF9BTkRfTUFTSyh1bmljb2RlLCBzcmNbMV0pCisgICAgICAgICAgICByZXR1cm4gdW5pY29kZTsKKyAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgdW5pY29kZSA9IHNyY1swXSAmIDB4MGY7CisgICAgICAgICAgICBVVEY4X1NISUZUX0FORF9NQVNLKHVuaWNvZGUsIHNyY1sxXSkKKyAgICAgICAgICAgIFVURjhfU0hJRlRfQU5EX01BU0sodW5pY29kZSwgc3JjWzJdKQorICAgICAgICAgICAgcmV0dXJuIHVuaWNvZGU7CisgICAgICAgIGNhc2UgNDoKKyAgICAgICAgICAgIHVuaWNvZGUgPSBzcmNbMF0gJiAweDA3OworICAgICAgICAgICAgVVRGOF9TSElGVF9BTkRfTUFTSyh1bmljb2RlLCBzcmNbMV0pCisgICAgICAgICAgICBVVEY4X1NISUZUX0FORF9NQVNLKHVuaWNvZGUsIHNyY1syXSkKKyAgICAgICAgICAgIFVURjhfU0hJRlRfQU5EX01BU0sodW5pY29kZSwgc3JjWzNdKQorICAgICAgICAgICAgcmV0dXJuIHVuaWNvZGU7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gMHhmZmZmOworICAgIH0KKyAgICAKKyAgICAvL3ByaW50ZigiQ2hhciBhdCAlcDogbGVuPSVkLCB1dGYtMTY9JXBcbiIsIHNyYywgbGVuZ3RoLCAodm9pZCopcmVzdWx0KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBTaGFyZWRCdWZmZXIqIGdFbXB0eVN0cmluZ0J1ZiA9IE5VTEw7CitzdGF0aWMgY2hhcjE2X3QqIGdFbXB0eVN0cmluZyA9IE5VTEw7CisKK3N0YXRpYyBpbmxpbmUgY2hhcjE2X3QqIGdldEVtcHR5U3RyaW5nKCkKK3sKKyAgICBnRW1wdHlTdHJpbmdCdWYtPmFjcXVpcmUoKTsKKyAgIHJldHVybiBnRW1wdHlTdHJpbmc7Cit9CisKK3ZvaWQgaW5pdGlhbGl6ZV9zdHJpbmcxNigpCit7CisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmFsbG9jKHNpemVvZihjaGFyMTZfdCkpOworICAgIGNoYXIxNl90KiBzdHIgPSAoY2hhcjE2X3QqKWJ1Zi0+ZGF0YSgpOworICAgICpzdHIgPSAwOworICAgIGdFbXB0eVN0cmluZ0J1ZiA9IGJ1ZjsKKyAgICBnRW1wdHlTdHJpbmcgPSBzdHI7Cit9CisKK3ZvaWQgdGVybWluYXRlX3N0cmluZzE2KCkKK3sKKyAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKGdFbXB0eVN0cmluZyktPnJlbGVhc2UoKTsKKyAgICBnRW1wdHlTdHJpbmdCdWYgPSBOVUxMOworICAgIGdFbXB0eVN0cmluZyA9IE5VTEw7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBOb3RlOiBub3QgZGVhbGluZyB3aXRoIGdlbmVyYXRpbmcgc3Vycm9nYXRlIHBhaXJzLgorc3RhdGljIGNoYXIxNl90KiBhbGxvY0Zyb21VVEY4KGNvbnN0IGNoYXIqIGluLCBzaXplX3QgbGVuKQoreworICAgIGlmIChsZW4gPT0gMCkgcmV0dXJuIGdldEVtcHR5U3RyaW5nKCk7CisgICAgCisgICAgc2l6ZV90IGNoYXJzID0gMDsKKyAgICBjb25zdCBjaGFyKiBlbmQgPSBpbitsZW47CisgICAgY29uc3QgY2hhciogcCA9IGluOworICAgIAorICAgIHdoaWxlIChwIDwgZW5kKSB7CisgICAgICAgIGNoYXJzKys7CisgICAgICAgIHAgKz0gdXRmOF9jaGFyX2xlbigqcCk7CisgICAgfQorICAgIAorICAgIFNoYXJlZEJ1ZmZlciogYnVmID0gU2hhcmVkQnVmZmVyOjphbGxvYygoY2hhcnMrMSkqc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgaWYgKGJ1ZikgeworICAgICAgICBwID0gaW47CisgICAgICAgIGNoYXIxNl90KiBzdHIgPSAoY2hhcjE2X3QqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBjaGFyMTZfdCogZCA9IHN0cjsKKyAgICAgICAgd2hpbGUgKHAgPCBlbmQpIHsKKyAgICAgICAgICAgIHNpemVfdCBsZW4gPSB1dGY4X2NoYXJfbGVuKCpwKTsKKyAgICAgICAgICAgICpkKysgPSAoY2hhcjE2X3QpdXRmOF90b191dGYzMigoY29uc3QgdWludDhfdCopcCwgbGVuKTsKKyAgICAgICAgICAgIHAgKz0gbGVuOworICAgICAgICB9CisgICAgICAgICpkID0gMDsKKyAgICAgICAgCisgICAgICAgIC8vcHJpbnRmKCJDcmVhdGVkIFVURi0xNiBzdHJpbmcgZnJvbSBVVEYtOCBcIiVzXCI6IiwgaW4pOworICAgICAgICAvL3ByaW50SGV4RGF0YSgxLCBzdHIsIGJ1Zi0+c2l6ZSgpLCAxNiwgMSk7CisgICAgICAgIC8vcHJpbnRmKCJcbiIpOworICAgICAgICAKKyAgICAgICAgcmV0dXJuIHN0cjsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGdldEVtcHR5U3RyaW5nKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTdHJpbmcxNjo6U3RyaW5nMTYoKQorICAgIDogbVN0cmluZyhnZXRFbXB0eVN0cmluZygpKQoreworfQorCitTdHJpbmcxNjo6U3RyaW5nMTYoY29uc3QgU3RyaW5nMTYmIG8pCisgICAgOiBtU3RyaW5nKG8ubVN0cmluZykKK3sKKyAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5hY3F1aXJlKCk7Cit9CisKK1N0cmluZzE2OjpTdHJpbmcxNihjb25zdCBTdHJpbmcxNiYgbywgc2l6ZV90IGxlbiwgc2l6ZV90IGJlZ2luKQorICAgIDogbVN0cmluZyhnZXRFbXB0eVN0cmluZygpKQoreworICAgIHNldFRvKG8sIGxlbiwgYmVnaW4pOworfQorCitTdHJpbmcxNjo6U3RyaW5nMTYoY29uc3QgY2hhcjE2X3QqIG8pCit7CisgICAgc2l6ZV90IGxlbiA9IHN0cmxlbjE2KG8pOworICAgIFNoYXJlZEJ1ZmZlciogYnVmID0gU2hhcmVkQnVmZmVyOjphbGxvYygobGVuKzEpKnNpemVvZihjaGFyMTZfdCkpOworICAgIExPR19BU1NFUlQoYnVmLCAiVW5hYmxlIHRvIGFsbG9jYXRlIHNoYXJlZCBidWZmZXIiKTsKKyAgICBpZiAoYnVmKSB7CisgICAgICAgIGNoYXIxNl90KiBzdHIgPSAoY2hhcjE2X3QqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBzdHJjcHkxNihzdHIsIG8pOworICAgICAgICBtU3RyaW5nID0gc3RyOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworfQorCitTdHJpbmcxNjo6U3RyaW5nMTYoY29uc3QgY2hhcjE2X3QqIG8sIHNpemVfdCBsZW4pCit7CisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmFsbG9jKChsZW4rMSkqc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgTE9HX0FTU0VSVChidWYsICJVbmFibGUgdG8gYWxsb2NhdGUgc2hhcmVkIGJ1ZmZlciIpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhcjE2X3QqIHN0ciA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgIG1lbWNweShzdHIsIG8sIGxlbipzaXplb2YoY2hhcjE2X3QpKTsKKyAgICAgICAgc3RyW2xlbl0gPSAwOworICAgICAgICBtU3RyaW5nID0gc3RyOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworfQorCitTdHJpbmcxNjo6U3RyaW5nMTYoY29uc3QgU3RyaW5nOCYgbykKKyAgICA6IG1TdHJpbmcoYWxsb2NGcm9tVVRGOChvLnN0cmluZygpLCBvLnNpemUoKSkpCit7Cit9CisKK1N0cmluZzE2OjpTdHJpbmcxNihjb25zdCBjaGFyKiBvKQorICAgIDogbVN0cmluZyhhbGxvY0Zyb21VVEY4KG8sIHN0cmxlbihvKSkpCit7Cit9CisKK1N0cmluZzE2OjpTdHJpbmcxNihjb25zdCBjaGFyKiBvLCBzaXplX3QgbGVuKQorICAgIDogbVN0cmluZyhhbGxvY0Zyb21VVEY4KG8sIGxlbikpCit7Cit9CisKK1N0cmluZzE2Ojp+U3RyaW5nMTYoKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZyktPnJlbGVhc2UoKTsKK30KKwordm9pZCBTdHJpbmcxNjo6c2V0VG8oY29uc3QgU3RyaW5nMTYmIG90aGVyKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEob3RoZXIubVN0cmluZyktPmFjcXVpcmUoKTsKKyAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5yZWxlYXNlKCk7CisgICAgbVN0cmluZyA9IG90aGVyLm1TdHJpbmc7Cit9CisKK3N0YXR1c190IFN0cmluZzE2OjpzZXRUbyhjb25zdCBTdHJpbmcxNiYgb3RoZXIsIHNpemVfdCBsZW4sIHNpemVfdCBiZWdpbikKK3sKKyAgICBjb25zdCBzaXplX3QgTiA9IG90aGVyLnNpemUoKTsKKyAgICBpZiAoYmVnaW4gPj0gTikgeworICAgICAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5yZWxlYXNlKCk7CisgICAgICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorICAgIGlmICgoYmVnaW4rbGVuKSA+IE4pIGxlbiA9IE4tYmVnaW47CisgICAgaWYgKGJlZ2luID09IDAgJiYgbGVuID09IE4pIHsKKyAgICAgICAgc2V0VG8ob3RoZXIpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgaWYgKCZvdGhlciA9PSB0aGlzKSB7CisgICAgICAgIExPR19BTFdBWVNfRkFUQUwoIk5vdCBpbXBsZW1lbnRlZCIpOworICAgIH0KKworICAgIHJldHVybiBzZXRUbyhvdGhlci5zdHJpbmcoKStiZWdpbiwgbGVuKTsKK30KKworc3RhdHVzX3QgU3RyaW5nMTY6OnNldFRvKGNvbnN0IGNoYXIxNl90KiBvdGhlcikKK3sKKyAgICByZXR1cm4gc2V0VG8ob3RoZXIsIHN0cmxlbjE2KG90aGVyKSk7Cit9CisKK3N0YXR1c190IFN0cmluZzE2OjpzZXRUbyhjb25zdCBjaGFyMTZfdCogb3RoZXIsIHNpemVfdCBsZW4pCit7CisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpCisgICAgICAgIC0+ZWRpdFJlc2l6ZSgobGVuKzEpKnNpemVvZihjaGFyMTZfdCkpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhcjE2X3QqIHN0ciA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgIG1lbWNweShzdHIsIG90aGVyLCBsZW4qc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgICAgIHN0cltsZW5dID0gMDsKKyAgICAgICAgbVN0cmluZyA9IHN0cjsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTk9fTUVNT1JZOworfQorCitzdGF0dXNfdCBTdHJpbmcxNjo6YXBwZW5kKGNvbnN0IFN0cmluZzE2JiBvdGhlcikKK3sKKyAgICBjb25zdCBzaXplX3QgbXlMZW4gPSBzaXplKCk7CisgICAgY29uc3Qgc2l6ZV90IG90aGVyTGVuID0gb3RoZXIuc2l6ZSgpOworICAgIGlmIChteUxlbiA9PSAwKSB7CisgICAgICAgIHNldFRvKG90aGVyKTsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0gZWxzZSBpZiAob3RoZXJMZW4gPT0gMCkgeworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorICAgIAorICAgIFNoYXJlZEJ1ZmZlciogYnVmID0gU2hhcmVkQnVmZmVyOjpidWZmZXJGcm9tRGF0YShtU3RyaW5nKQorICAgICAgICAtPmVkaXRSZXNpemUoKG15TGVuK290aGVyTGVuKzEpKnNpemVvZihjaGFyMTZfdCkpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhcjE2X3QqIHN0ciA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgIG1lbWNweShzdHIrbXlMZW4sIG90aGVyLCAob3RoZXJMZW4rMSkqc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgICAgIG1TdHJpbmcgPSBzdHI7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgcmV0dXJuIE5PX01FTU9SWTsKK30KKworc3RhdHVzX3QgU3RyaW5nMTY6OmFwcGVuZChjb25zdCBjaGFyMTZfdCogY2hycywgc2l6ZV90IG90aGVyTGVuKQoreworICAgIGNvbnN0IHNpemVfdCBteUxlbiA9IHNpemUoKTsKKyAgICBpZiAobXlMZW4gPT0gMCkgeworICAgICAgICBzZXRUbyhjaHJzLCBvdGhlckxlbik7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9IGVsc2UgaWYgKG90aGVyTGVuID09IDApIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICAKKyAgICBTaGFyZWRCdWZmZXIqIGJ1ZiA9IFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZykKKyAgICAgICAgLT5lZGl0UmVzaXplKChteUxlbitvdGhlckxlbisxKSpzaXplb2YoY2hhcjE2X3QpKTsKKyAgICBpZiAoYnVmKSB7CisgICAgICAgIGNoYXIxNl90KiBzdHIgPSAoY2hhcjE2X3QqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBtZW1jcHkoc3RyK215TGVuLCBjaHJzLCBvdGhlckxlbipzaXplb2YoY2hhcjE2X3QpKTsKKyAgICAgICAgc3RyW215TGVuK290aGVyTGVuXSA9IDA7CisgICAgICAgIG1TdHJpbmcgPSBzdHI7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisgICAgcmV0dXJuIE5PX01FTU9SWTsKK30KKworc3RhdHVzX3QgU3RyaW5nMTY6Omluc2VydChzaXplX3QgcG9zLCBjb25zdCBjaGFyMTZfdCogY2hycykKK3sKKyAgICByZXR1cm4gaW5zZXJ0KHBvcywgY2hycywgc3RybGVuMTYoY2hycykpOworfQorCitzdGF0dXNfdCBTdHJpbmcxNjo6aW5zZXJ0KHNpemVfdCBwb3MsIGNvbnN0IGNoYXIxNl90KiBjaHJzLCBzaXplX3QgbGVuKQoreworICAgIGNvbnN0IHNpemVfdCBteUxlbiA9IHNpemUoKTsKKyAgICBpZiAobXlMZW4gPT0gMCkgeworICAgICAgICByZXR1cm4gc2V0VG8oY2hycywgbGVuKTsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0gZWxzZSBpZiAobGVuID09IDApIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKworICAgIGlmIChwb3MgPiBteUxlbikgcG9zID0gbXlMZW47CisKKyAgICAjaWYgMAorICAgIHByaW50ZigiSW5zZXJ0IGluIHRvICVzOiBwb3M9JWQsIGxlbj0lZCwgbXlMZW49JWQsIGNocnM9JXNcbiIsCisgICAgICAgICAgIFN0cmluZzgoKnRoaXMpLnN0cmluZygpLCBwb3MsCisgICAgICAgICAgIGxlbiwgbXlMZW4sIFN0cmluZzgoY2hycywgbGVuKS5zdHJpbmcoKSk7CisgICAgI2VuZGlmCisKKyAgICBTaGFyZWRCdWZmZXIqIGJ1ZiA9IFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZykKKyAgICAgICAgLT5lZGl0UmVzaXplKChteUxlbitsZW4rMSkqc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgaWYgKGJ1ZikgeworICAgICAgICBjaGFyMTZfdCogc3RyID0gKGNoYXIxNl90KilidWYtPmRhdGEoKTsKKyAgICAgICAgaWYgKHBvcyA8IG15TGVuKSB7CisgICAgICAgICAgICBtZW1tb3ZlKHN0citwb3MrbGVuLCBzdHIrcG9zLCAobXlMZW4tcG9zKSpzaXplb2YoY2hhcjE2X3QpKTsKKyAgICAgICAgfQorICAgICAgICBtZW1jcHkoc3RyK3BvcywgY2hycywgbGVuKnNpemVvZihjaGFyMTZfdCkpOworICAgICAgICBzdHJbbXlMZW4rbGVuXSA9IDA7CisgICAgICAgIG1TdHJpbmcgPSBzdHI7CisgICAgICAgICNpZiAwCisgICAgICAgIHByaW50ZigiUmVzdWx0ICglZCBjaHJzKTogJXNcbiIsIHNpemUoKSwgU3RyaW5nOCgqdGhpcykuc3RyaW5nKCkpOworICAgICAgICAjZW5kaWYKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTk9fTUVNT1JZOworfQorCitzc2l6ZV90IFN0cmluZzE2OjpmaW5kRmlyc3QoY2hhcjE2X3QgYykgY29uc3QKK3sKKyAgICBjb25zdCBjaGFyMTZfdCogc3RyID0gc3RyaW5nKCk7CisgICAgY29uc3QgY2hhcjE2X3QqIHAgPSBzdHI7CisgICAgY29uc3QgY2hhcjE2X3QqIGUgPSBwICsgc2l6ZSgpOworICAgIHdoaWxlIChwIDwgZSkgeworICAgICAgICBpZiAoKnAgPT0gYykgeworICAgICAgICAgICAgcmV0dXJuIHAtc3RyOworICAgICAgICB9CisgICAgICAgIHArKzsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCitzc2l6ZV90IFN0cmluZzE2OjpmaW5kTGFzdChjaGFyMTZfdCBjKSBjb25zdAoreworICAgIGNvbnN0IGNoYXIxNl90KiBzdHIgPSBzdHJpbmcoKTsKKyAgICBjb25zdCBjaGFyMTZfdCogcCA9IHN0cjsKKyAgICBjb25zdCBjaGFyMTZfdCogZSA9IHAgKyBzaXplKCk7CisgICAgd2hpbGUgKHAgPCBlKSB7CisgICAgICAgIGUtLTsKKyAgICAgICAgaWYgKCplID09IGMpIHsKKyAgICAgICAgICAgIHJldHVybiBlLXN0cjsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gLTE7Cit9CisKK2Jvb2wgU3RyaW5nMTY6OnN0YXJ0c1dpdGgoY29uc3QgU3RyaW5nMTYmIHByZWZpeCkgY29uc3QKK3sKKyAgICBjb25zdCBzaXplX3QgcHMgPSBwcmVmaXguc2l6ZSgpOworICAgIGlmIChwcyA+IHNpemUoKSkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBzdHJ6Y21wMTYobVN0cmluZywgcHMsIHByZWZpeC5zdHJpbmcoKSwgcHMpID09IDA7Cit9CisKK2Jvb2wgU3RyaW5nMTY6OnN0YXJ0c1dpdGgoY29uc3QgY2hhcjE2X3QqIHByZWZpeCkgY29uc3QKK3sKKyAgICBjb25zdCBzaXplX3QgcHMgPSBzdHJsZW4xNihwcmVmaXgpOworICAgIGlmIChwcyA+IHNpemUoKSkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBzdHJuY21wMTYobVN0cmluZywgcHJlZml4LCBwcykgPT0gMDsKK30KKworc3RhdHVzX3QgU3RyaW5nMTY6Om1ha2VMb3dlcigpCit7CisgICAgY29uc3Qgc2l6ZV90IE4gPSBzaXplKCk7CisgICAgY29uc3QgY2hhcjE2X3QqIHN0ciA9IHN0cmluZygpOworICAgIGNoYXIxNl90KiBlZGl0ID0gTlVMTDsKKyAgICBmb3IgKHNpemVfdCBpPTA7IGk8TjsgaSsrKSB7CisgICAgICAgIGNvbnN0IGNoYXIxNl90IHYgPSBzdHJbaV07CisgICAgICAgIGlmICh2ID49ICdBJyAmJiB2IDw9ICdaJykgeworICAgICAgICAgICAgaWYgKCFlZGl0KSB7CisgICAgICAgICAgICAgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5lZGl0KCk7CisgICAgICAgICAgICAgICAgaWYgKCFidWYpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWRpdCA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgICAgICAgICAgbVN0cmluZyA9IHN0ciA9IGVkaXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlZGl0W2ldID0gdG9sb3dlcigoY2hhcil2KTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IFN0cmluZzE2OjpyZXBsYWNlQWxsKGNoYXIxNl90IHJlcGxhY2VUaGlzLCBjaGFyMTZfdCB3aXRoVGhpcykKK3sKKyAgICBjb25zdCBzaXplX3QgTiA9IHNpemUoKTsKKyAgICBjb25zdCBjaGFyMTZfdCogc3RyID0gc3RyaW5nKCk7CisgICAgY2hhcjE2X3QqIGVkaXQgPSBOVUxMOworICAgIGZvciAoc2l6ZV90IGk9MDsgaTxOOyBpKyspIHsKKyAgICAgICAgaWYgKHN0cltpXSA9PSByZXBsYWNlVGhpcykgeworICAgICAgICAgICAgaWYgKCFlZGl0KSB7CisgICAgICAgICAgICAgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5lZGl0KCk7CisgICAgICAgICAgICAgICAgaWYgKCFidWYpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWRpdCA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgICAgICAgICAgbVN0cmluZyA9IHN0ciA9IGVkaXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlZGl0W2ldID0gd2l0aFRoaXM7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBTdHJpbmcxNjo6cmVtb3ZlKHNpemVfdCBsZW4sIHNpemVfdCBiZWdpbikKK3sKKyAgICBjb25zdCBzaXplX3QgTiA9IHNpemUoKTsKKyAgICBpZiAoYmVnaW4gPj0gTikgeworICAgICAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5yZWxlYXNlKCk7CisgICAgICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorICAgIGlmICgoYmVnaW4rbGVuKSA+IE4pIGxlbiA9IE4tYmVnaW47CisgICAgaWYgKGJlZ2luID09IDAgJiYgbGVuID09IE4pIHsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKworICAgIGlmIChiZWdpbiA+IDApIHsKKyAgICAgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpCisgICAgICAgICAgICAtPmVkaXRSZXNpemUoKE4rMSkqc2l6ZW9mKGNoYXIxNl90KSk7CisgICAgICAgIGlmICghYnVmKSB7CisgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICB9CisgICAgICAgIGNoYXIxNl90KiBzdHIgPSAoY2hhcjE2X3QqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBtZW1tb3ZlKHN0ciwgc3RyK2JlZ2luLCAoTi1iZWdpbisxKSpzaXplb2YoY2hhcjE2X3QpKTsKKyAgICAgICAgbVN0cmluZyA9IHN0cjsKKyAgICB9CisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpCisgICAgICAgIC0+ZWRpdFJlc2l6ZSgobGVuKzEpKnNpemVvZihjaGFyMTZfdCkpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhcjE2X3QqIHN0ciA9IChjaGFyMTZfdCopYnVmLT5kYXRhKCk7CisgICAgICAgIHN0cltsZW5dID0gMDsKKyAgICAgICAgbVN0cmluZyA9IHN0cjsKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgIH0KKyAgICByZXR1cm4gTk9fTUVNT1JZOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCBTdHJpbmcxNiYgdmFsKQoreworICAgIHRvIDw8IFN0cmluZzgodmFsKS5zdHJpbmcoKTsKKyAgICByZXR1cm4gdG87Cit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1N0cmluZzguY3BwIGIvbGlicy91dGlscy9TdHJpbmc4LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTBkMzQzCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9TdHJpbmc4LmNwcApAQCAtMCwwICsxLDYwNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDx1dGlscy9TdHJpbmc4Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKyNpbmNsdWRlIDx1dGlscy9TdHJpbmcxNi5oPgorI2luY2x1ZGUgPHV0aWxzL1RleHRPdXRwdXQuaD4KKyNpbmNsdWRlIDx1dGlscy90aHJlYWRzLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3V0aWxzL1N0YXRpYy5oPgorCisjaW5jbHVkZSA8Y3R5cGUuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIGNvbnN0IHVpbnQzMl90IGtCeXRlTWFzayA9IDB4MDAwMDAwQkY7CitzdGF0aWMgY29uc3QgdWludDMyX3Qga0J5dGVNYXJrID0gMHgwMDAwMDA4MDsKKworLy8gU3Vycm9nYXRlcyBhcmVuJ3QgdmFsaWQgZm9yIFVURi0zMiBjaGFyYWN0ZXJzLCBzbyBkZWZpbmUgc29tZQorLy8gY29uc3RhbnRzIHRoYXQgd2lsbCBsZXQgdXMgc2NyZWVuIHRoZW0gb3V0Lgorc3RhdGljIGNvbnN0IHVpbnQzMl90IGtVbmljb2RlU3Vycm9nYXRlSGlnaFN0YXJ0ICA9IDB4MDAwMEQ4MDA7CitzdGF0aWMgY29uc3QgdWludDMyX3Qga1VuaWNvZGVTdXJyb2dhdGVIaWdoRW5kICAgID0gMHgwMDAwREJGRjsKK3N0YXRpYyBjb25zdCB1aW50MzJfdCBrVW5pY29kZVN1cnJvZ2F0ZUxvd1N0YXJ0ICAgPSAweDAwMDBEQzAwOworc3RhdGljIGNvbnN0IHVpbnQzMl90IGtVbmljb2RlU3Vycm9nYXRlTG93RW5kICAgICA9IDB4MDAwMERGRkY7CitzdGF0aWMgY29uc3QgdWludDMyX3Qga1VuaWNvZGVTdXJyb2dhdGVTdGFydCAgICAgID0ga1VuaWNvZGVTdXJyb2dhdGVIaWdoU3RhcnQ7CitzdGF0aWMgY29uc3QgdWludDMyX3Qga1VuaWNvZGVTdXJyb2dhdGVFbmQgICAgICAgID0ga1VuaWNvZGVTdXJyb2dhdGVMb3dFbmQ7CisKKy8vIE1hc2sgdXNlZCB0byBzZXQgYXBwcm9wcmlhdGUgYml0cyBpbiBmaXJzdCBieXRlIG9mIFVURi04IHNlcXVlbmNlLAorLy8gaW5kZXhlZCBieSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIHNlcXVlbmNlLgorc3RhdGljIGNvbnN0IHVpbnQzMl90IGtGaXJzdEJ5dGVNYXJrW10gPSB7CisgICAgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDBDMCwgMHgwMDAwMDBFMCwgMHgwMDAwMDBGMAorfTsKKworLy8gU2VwYXJhdG9yIHVzZWQgYnkgcmVzb3VyY2UgcGF0aHMuIFRoaXMgaXMgbm90IHBsYXRmb3JtIGRlcGVuZGVudCBjb250cmFyeQorLy8gdG8gT1NfUEFUSF9TRVBBUkFUT1IuCisjZGVmaW5lIFJFU19QQVRIX1NFUEFSQVRPUiAnLycKKworLy8gUmV0dXJuIG51bWJlciBvZiB1dGY4IGJ5dGVzIHJlcXVpcmVkIGZvciB0aGUgY2hhcmFjdGVyLgorc3RhdGljIHNpemVfdCB1dGYzMl90b191dGY4X2J5dGVzKHVpbnQzMl90IHNyY0NoYXIpCit7CisgICAgc2l6ZV90IGJ5dGVzVG9Xcml0ZTsKKworICAgIC8vIEZpZ3VyZSBvdXQgaG93IG1hbnkgYnl0ZXMgdGhlIHJlc3VsdCB3aWxsIHJlcXVpcmUuCisgICAgaWYgKHNyY0NoYXIgPCAweDAwMDAwMDgwKQorICAgIHsKKyAgICAgICAgYnl0ZXNUb1dyaXRlID0gMTsKKyAgICB9CisgICAgZWxzZSBpZiAoc3JjQ2hhciA8IDB4MDAwMDA4MDApCisgICAgeworICAgICAgICBieXRlc1RvV3JpdGUgPSAyOworICAgIH0KKyAgICBlbHNlIGlmIChzcmNDaGFyIDwgMHgwMDAxMDAwMCkKKyAgICB7CisgICAgICAgIGlmICgoc3JjQ2hhciA8IGtVbmljb2RlU3Vycm9nYXRlU3RhcnQpCisgICAgICAgICB8fCAoc3JjQ2hhciA+IGtVbmljb2RlU3Vycm9nYXRlRW5kKSkKKyAgICAgICAgeworICAgICAgICAgICAgYnl0ZXNUb1dyaXRlID0gMzsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFN1cnJvZ2F0ZXMgYXJlIGludmFsaWQgVVRGLTMyIGNoYXJhY3RlcnMuCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKyAgICAvLyBNYXggY29kZSBwb2ludCBmb3IgVW5pY29kZSBpcyAweDAwMTBGRkZGLgorICAgIGVsc2UgaWYgKHNyY0NoYXIgPCAweDAwMTEwMDAwKQorICAgIHsKKyAgICAgICAgYnl0ZXNUb1dyaXRlID0gNDsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgICAgLy8gSW52YWxpZCBVVEYtMzIgY2hhcmFjdGVyLgorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXR1cm4gYnl0ZXNUb1dyaXRlOworfQorCisvLyBXcml0ZSBvdXQgdGhlIHNvdXJjZSBjaGFyYWN0ZXIgdG8gPGRzdFA+LgorCitzdGF0aWMgdm9pZCB1dGYzMl90b191dGY4KHVpbnQ4X3QqIGRzdFAsIHVpbnQzMl90IHNyY0NoYXIsIHNpemVfdCBieXRlcykKK3sKKyAgICBkc3RQICs9IGJ5dGVzOworICAgIHN3aXRjaCAoYnl0ZXMpCisgICAgeyAgIC8qIG5vdGU6IGV2ZXJ5dGhpbmcgZmFsbHMgdGhyb3VnaC4gKi8KKyAgICAgICAgY2FzZSA0OiAqLS1kc3RQID0gKHVpbnQ4X3QpKChzcmNDaGFyIHwga0J5dGVNYXJrKSAmIGtCeXRlTWFzayk7IHNyY0NoYXIgPj49IDY7CisgICAgICAgIGNhc2UgMzogKi0tZHN0UCA9ICh1aW50OF90KSgoc3JjQ2hhciB8IGtCeXRlTWFyaykgJiBrQnl0ZU1hc2spOyBzcmNDaGFyID4+PSA2OworICAgICAgICBjYXNlIDI6ICotLWRzdFAgPSAodWludDhfdCkoKHNyY0NoYXIgfCBrQnl0ZU1hcmspICYga0J5dGVNYXNrKTsgc3JjQ2hhciA+Pj0gNjsKKyAgICAgICAgY2FzZSAxOiAqLS1kc3RQID0gKHVpbnQ4X3QpKHNyY0NoYXIgfCBrRmlyc3RCeXRlTWFya1tieXRlc10pOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBTaGFyZWRCdWZmZXIqIGdFbXB0eVN0cmluZ0J1ZiA9IE5VTEw7CitzdGF0aWMgY2hhciogZ0VtcHR5U3RyaW5nID0gTlVMTDsKKworZXh0ZXJuIGludCBnRGFyd2luQ2FudExvYWRBbGxPYmplY3RzOworaW50IGdEYXJ3aW5Jc1JlYWxseUFubm95aW5nOworCitzdGF0aWMgaW5saW5lIGNoYXIqIGdldEVtcHR5U3RyaW5nKCkKK3sKKyAgICBnRW1wdHlTdHJpbmdCdWYtPmFjcXVpcmUoKTsKKyAgICByZXR1cm4gZ0VtcHR5U3RyaW5nOworfQorCit2b2lkIGluaXRpYWxpemVfc3RyaW5nOCgpCit7CisjaWZkZWYgTElCVVRJTFNfTkFUSVZFCisJICAvLyBCaXRlIG1lLCBEYXJ3aW4hCisJCWdEYXJ3aW5Jc1JlYWxseUFubm95aW5nID0gZ0RhcndpbkNhbnRMb2FkQWxsT2JqZWN0czsKKyNlbmRpZgorCQkJCisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmFsbG9jKDEpOworICAgIGNoYXIqIHN0ciA9IChjaGFyKilidWYtPmRhdGEoKTsKKyAgICAqc3RyID0gMDsKKyAgICBnRW1wdHlTdHJpbmdCdWYgPSBidWY7CisgICAgZ0VtcHR5U3RyaW5nID0gc3RyOworfQorCit2b2lkIHRlcm1pbmF0ZV9zdHJpbmc4KCkKK3sKKyAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKGdFbXB0eVN0cmluZyktPnJlbGVhc2UoKTsKKyAgICBnRW1wdHlTdHJpbmdCdWYgPSBOVUxMOworICAgIGdFbXB0eVN0cmluZyA9IE5VTEw7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgY2hhciogYWxsb2NGcm9tVVRGOChjb25zdCBjaGFyKiBpbiwgc2l6ZV90IGxlbikKK3sKKyAgICBpZiAobGVuID4gMCkgeworICAgICAgICBTaGFyZWRCdWZmZXIqIGJ1ZiA9IFNoYXJlZEJ1ZmZlcjo6YWxsb2MobGVuKzEpOworICAgICAgICBMT0dfQVNTRVJUKGJ1ZiwgIlVuYWJsZSB0byBhbGxvY2F0ZSBzaGFyZWQgYnVmZmVyIik7CisgICAgICAgIGlmIChidWYpIHsKKyAgICAgICAgICAgIGNoYXIqIHN0ciA9IChjaGFyKilidWYtPmRhdGEoKTsKKyAgICAgICAgICAgIG1lbWNweShzdHIsIGluLCBsZW4pOworICAgICAgICAgICAgc3RyW2xlbl0gPSAwOworICAgICAgICAgICAgcmV0dXJuIHN0cjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gZ2V0RW1wdHlTdHJpbmcoKTsKK30KKworLy8gTm90ZTogbm90IGRlYWxpbmcgd2l0aCBleHBhbmRpbmcgc3Vycm9nYXRlIHBhaXJzLgorc3RhdGljIGNoYXIqIGFsbG9jRnJvbVVURjE2KGNvbnN0IGNoYXIxNl90KiBpbiwgc2l6ZV90IGxlbikKK3sKKyAgICBpZiAobGVuID09IDApIHJldHVybiBnZXRFbXB0eVN0cmluZygpOworICAgIAorICAgIHNpemVfdCBieXRlcyA9IDA7CisgICAgY29uc3QgY2hhcjE2X3QqIGVuZCA9IGluK2xlbjsKKyAgICBjb25zdCBjaGFyMTZfdCogcCA9IGluOworICAgIAorICAgIHdoaWxlIChwIDwgZW5kKSB7CisgICAgICAgIGJ5dGVzICs9IHV0ZjMyX3RvX3V0ZjhfYnl0ZXMoKnApOworICAgICAgICBwKys7CisgICAgfQorICAgIAorICAgIFNoYXJlZEJ1ZmZlciogYnVmID0gU2hhcmVkQnVmZmVyOjphbGxvYyhieXRlcysxKTsKKyAgICBMT0dfQVNTRVJUKGJ1ZiwgIlVuYWJsZSB0byBhbGxvY2F0ZSBzaGFyZWQgYnVmZmVyIik7CisgICAgaWYgKGJ1ZikgeworICAgICAgICBwID0gaW47CisgICAgICAgIGNoYXIqIHN0ciA9IChjaGFyKilidWYtPmRhdGEoKTsKKyAgICAgICAgY2hhciogZCA9IHN0cjsKKyAgICAgICAgd2hpbGUgKHAgPCBlbmQpIHsKKyAgICAgICAgICAgIHVpbnQzMl90IGMgPSAqcCsrOworICAgICAgICAgICAgc2l6ZV90IGxlbiA9IHV0ZjMyX3RvX3V0ZjhfYnl0ZXMoYyk7CisgICAgICAgICAgICB1dGYzMl90b191dGY4KCh1aW50OF90KilkLCBjLCBsZW4pOworICAgICAgICAgICAgZCArPSBsZW47CisgICAgICAgIH0KKyAgICAgICAgKmQgPSAwOworICAgICAgICAKKyAgICAgICAgcmV0dXJuIHN0cjsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGdldEVtcHR5U3RyaW5nKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTdHJpbmc4OjpTdHJpbmc4KCkKKyAgICA6IG1TdHJpbmcoZ2V0RW1wdHlTdHJpbmcoKSkKK3sKK30KKworU3RyaW5nODo6U3RyaW5nOChjb25zdCBTdHJpbmc4JiBvKQorICAgIDogbVN0cmluZyhvLm1TdHJpbmcpCit7CisgICAgU2hhcmVkQnVmZmVyOjpidWZmZXJGcm9tRGF0YShtU3RyaW5nKS0+YWNxdWlyZSgpOworfQorCitTdHJpbmc4OjpTdHJpbmc4KGNvbnN0IGNoYXIqIG8pCisgICAgOiBtU3RyaW5nKGFsbG9jRnJvbVVURjgobywgc3RybGVuKG8pKSkKK3sKKyAgICBpZiAobVN0cmluZyA9PSBOVUxMKSB7CisgICAgICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworICAgIH0KK30KKworU3RyaW5nODo6U3RyaW5nOChjb25zdCBjaGFyKiBvLCBzaXplX3QgbGVuKQorICAgIDogbVN0cmluZyhhbGxvY0Zyb21VVEY4KG8sIGxlbikpCit7CisgICAgaWYgKG1TdHJpbmcgPT0gTlVMTCkgeworICAgICAgICBtU3RyaW5nID0gZ2V0RW1wdHlTdHJpbmcoKTsKKyAgICB9Cit9CisKK1N0cmluZzg6OlN0cmluZzgoY29uc3QgU3RyaW5nMTYmIG8pCisgICAgOiBtU3RyaW5nKGFsbG9jRnJvbVVURjE2KG8uc3RyaW5nKCksIG8uc2l6ZSgpKSkKK3sKK30KKworU3RyaW5nODo6U3RyaW5nOChjb25zdCBjaGFyMTZfdCogbykKKyAgICA6IG1TdHJpbmcoYWxsb2NGcm9tVVRGMTYobywgc3RybGVuMTYobykpKQoreworfQorCitTdHJpbmc4OjpTdHJpbmc4KGNvbnN0IGNoYXIxNl90KiBvLCBzaXplX3QgbGVuKQorICAgIDogbVN0cmluZyhhbGxvY0Zyb21VVEYxNihvLCBsZW4pKQoreworfQorCitTdHJpbmc4Ojp+U3RyaW5nOCgpCit7CisgICAgU2hhcmVkQnVmZmVyOjpidWZmZXJGcm9tRGF0YShtU3RyaW5nKS0+cmVsZWFzZSgpOworfQorCit2b2lkIFN0cmluZzg6OnNldFRvKGNvbnN0IFN0cmluZzgmIG90aGVyKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEob3RoZXIubVN0cmluZyktPmFjcXVpcmUoKTsKKyAgICBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpLT5yZWxlYXNlKCk7CisgICAgbVN0cmluZyA9IG90aGVyLm1TdHJpbmc7Cit9CisKK3N0YXR1c190IFN0cmluZzg6OnNldFRvKGNvbnN0IGNoYXIqIG90aGVyKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZyktPnJlbGVhc2UoKTsKKyAgICBtU3RyaW5nID0gYWxsb2NGcm9tVVRGOChvdGhlciwgc3RybGVuKG90aGVyKSk7CisgICAgaWYgKG1TdHJpbmcpIHJldHVybiBOT19FUlJPUjsKKworICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworICAgIHJldHVybiBOT19NRU1PUlk7Cit9CisKK3N0YXR1c190IFN0cmluZzg6OnNldFRvKGNvbnN0IGNoYXIqIG90aGVyLCBzaXplX3QgbGVuKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZyktPnJlbGVhc2UoKTsKKyAgICBtU3RyaW5nID0gYWxsb2NGcm9tVVRGOChvdGhlciwgbGVuKTsKKyAgICBpZiAobVN0cmluZykgcmV0dXJuIE5PX0VSUk9SOworCisgICAgbVN0cmluZyA9IGdldEVtcHR5U3RyaW5nKCk7CisgICAgcmV0dXJuIE5PX01FTU9SWTsKK30KKworc3RhdHVzX3QgU3RyaW5nODo6c2V0VG8oY29uc3QgY2hhcjE2X3QqIG90aGVyLCBzaXplX3QgbGVuKQoreworICAgIFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZyktPnJlbGVhc2UoKTsKKyAgICBtU3RyaW5nID0gYWxsb2NGcm9tVVRGMTYob3RoZXIsIGxlbik7CisgICAgaWYgKG1TdHJpbmcpIHJldHVybiBOT19FUlJPUjsKKworICAgIG1TdHJpbmcgPSBnZXRFbXB0eVN0cmluZygpOworICAgIHJldHVybiBOT19NRU1PUlk7Cit9CisKK3N0YXR1c190IFN0cmluZzg6OmFwcGVuZChjb25zdCBTdHJpbmc4JiBvdGhlcikKK3sKKyAgICBjb25zdCBzaXplX3Qgb3RoZXJMZW4gPSBvdGhlci5ieXRlcygpOworICAgIGlmIChieXRlcygpID09IDApIHsKKyAgICAgICAgc2V0VG8ob3RoZXIpOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfSBlbHNlIGlmIChvdGhlckxlbiA9PSAwKSB7CisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKyAgICB9CisKKyAgICByZXR1cm4gcmVhbF9hcHBlbmQob3RoZXIuc3RyaW5nKCksIG90aGVyTGVuKTsKK30KKworc3RhdHVzX3QgU3RyaW5nODo6YXBwZW5kKGNvbnN0IGNoYXIqIG90aGVyKQoreworICAgIHJldHVybiBhcHBlbmQob3RoZXIsIHN0cmxlbihvdGhlcikpOworfQorCitzdGF0dXNfdCBTdHJpbmc4OjphcHBlbmQoY29uc3QgY2hhciogb3RoZXIsIHNpemVfdCBvdGhlckxlbikKK3sKKyAgICBpZiAoYnl0ZXMoKSA9PSAwKSB7CisgICAgICAgIHJldHVybiBzZXRUbyhvdGhlciwgb3RoZXJMZW4pOworICAgIH0gZWxzZSBpZiAob3RoZXJMZW4gPT0gMCkgeworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorCisgICAgcmV0dXJuIHJlYWxfYXBwZW5kKG90aGVyLCBvdGhlckxlbik7Cit9CisKK3N0YXR1c190IFN0cmluZzg6OnJlYWxfYXBwZW5kKGNvbnN0IGNoYXIqIG90aGVyLCBzaXplX3Qgb3RoZXJMZW4pCit7CisgICAgY29uc3Qgc2l6ZV90IG15TGVuID0gYnl0ZXMoKTsKKyAgICAKKyAgICBTaGFyZWRCdWZmZXIqIGJ1ZiA9IFNoYXJlZEJ1ZmZlcjo6YnVmZmVyRnJvbURhdGEobVN0cmluZykKKyAgICAgICAgLT5lZGl0UmVzaXplKG15TGVuK290aGVyTGVuKzEpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhciogc3RyID0gKGNoYXIqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBtU3RyaW5nID0gc3RyOworICAgICAgICBzdHIgKz0gbXlMZW47CisgICAgICAgIG1lbWNweShzdHIsIG90aGVyLCBvdGhlckxlbik7CisgICAgICAgIHN0cltvdGhlckxlbl0gPSAnXDAnOworICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgfQorICAgIHJldHVybiBOT19NRU1PUlk7Cit9CisKK2NoYXIqIFN0cmluZzg6OmxvY2tCdWZmZXIoc2l6ZV90IHNpemUpCit7CisgICAgU2hhcmVkQnVmZmVyKiBidWYgPSBTaGFyZWRCdWZmZXI6OmJ1ZmZlckZyb21EYXRhKG1TdHJpbmcpCisgICAgICAgIC0+ZWRpdFJlc2l6ZShzaXplKzEpOworICAgIGlmIChidWYpIHsKKyAgICAgICAgY2hhciogc3RyID0gKGNoYXIqKWJ1Zi0+ZGF0YSgpOworICAgICAgICBtU3RyaW5nID0gc3RyOworICAgICAgICByZXR1cm4gc3RyOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKwordm9pZCBTdHJpbmc4Ojp1bmxvY2tCdWZmZXIoKQoreworICAgIHVubG9ja0J1ZmZlcihzdHJsZW4obVN0cmluZykpOworfQorCitzdGF0dXNfdCBTdHJpbmc4Ojp1bmxvY2tCdWZmZXIoc2l6ZV90IHNpemUpCit7CisgICAgaWYgKHNpemUgIT0gdGhpcy0+c2l6ZSgpKSB7CisgICAgICAgIFNoYXJlZEJ1ZmZlciogYnVmID0gU2hhcmVkQnVmZmVyOjpidWZmZXJGcm9tRGF0YShtU3RyaW5nKQorICAgICAgICAgICAgLT5lZGl0UmVzaXplKHNpemUrMSk7CisgICAgICAgIGlmIChidWYpIHsKKyAgICAgICAgICAgIGNoYXIqIHN0ciA9IChjaGFyKilidWYtPmRhdGEoKTsKKyAgICAgICAgICAgIHN0cltzaXplXSA9IDA7CisgICAgICAgICAgICBtU3RyaW5nID0gc3RyOworICAgICAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHJldHVybiBOT19NRU1PUlk7Cit9CisKK3NzaXplX3QgU3RyaW5nODo6ZmluZChjb25zdCBjaGFyKiBvdGhlciwgc2l6ZV90IHN0YXJ0KSBjb25zdAoreworICAgIHNpemVfdCBsZW4gPSBzaXplKCk7CisgICAgaWYgKHN0YXJ0ID49IGxlbikgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGNvbnN0IGNoYXIqIHMgPSBtU3RyaW5nK3N0YXJ0OworICAgIGNvbnN0IGNoYXIqIHAgPSBzdHJzdHIocywgb3RoZXIpOworICAgIHJldHVybiBwID8gcC1tU3RyaW5nIDogLTE7Cit9CisKK3ZvaWQgU3RyaW5nODo6dG9Mb3dlcigpCit7CisgICAgdG9Mb3dlcigwLCBzaXplKCkpOworfQorCit2b2lkIFN0cmluZzg6OnRvTG93ZXIoc2l6ZV90IHN0YXJ0LCBzaXplX3QgbGVuZ3RoKQoreworICAgIGNvbnN0IHNpemVfdCBsZW4gPSBzaXplKCk7CisgICAgaWYgKHN0YXJ0ID49IGxlbikgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChzdGFydCtsZW5ndGggPiBsZW4pIHsKKyAgICAgICAgbGVuZ3RoID0gbGVuLXN0YXJ0OworICAgIH0KKyAgICBjaGFyKiBidWYgPSBsb2NrQnVmZmVyKGxlbik7CisgICAgYnVmICs9IHN0YXJ0OworICAgIHdoaWxlIChsZW5ndGggPiAwKSB7CisgICAgICAgICpidWYgPSB0b2xvd2VyKCpidWYpOworICAgICAgICBidWYrKzsKKyAgICAgICAgbGVuZ3RoLS07CisgICAgfQorICAgIHVubG9ja0J1ZmZlcihsZW4pOworfQorCit2b2lkIFN0cmluZzg6OnRvVXBwZXIoKQoreworICAgIHRvVXBwZXIoMCwgc2l6ZSgpKTsKK30KKwordm9pZCBTdHJpbmc4Ojp0b1VwcGVyKHNpemVfdCBzdGFydCwgc2l6ZV90IGxlbmd0aCkKK3sKKyAgICBjb25zdCBzaXplX3QgbGVuID0gc2l6ZSgpOworICAgIGlmIChzdGFydCA+PSBsZW4pIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoc3RhcnQrbGVuZ3RoID4gbGVuKSB7CisgICAgICAgIGxlbmd0aCA9IGxlbi1zdGFydDsKKyAgICB9CisgICAgY2hhciogYnVmID0gbG9ja0J1ZmZlcihsZW4pOworICAgIGJ1ZiArPSBzdGFydDsKKyAgICB3aGlsZSAobGVuZ3RoID4gMCkgeworICAgICAgICAqYnVmID0gdG91cHBlcigqYnVmKTsKKyAgICAgICAgYnVmKys7CisgICAgICAgIGxlbmd0aC0tOworICAgIH0KKyAgICB1bmxvY2tCdWZmZXIobGVuKTsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3QgU3RyaW5nOCYgdmFsKQoreworICAgIHRvIDw8IHZhbC5zdHJpbmcoKTsKKyAgICByZXR1cm4gdG87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUGF0aCBmdW5jdGlvbnMKKworCit2b2lkIFN0cmluZzg6OnNldFBhdGhOYW1lKGNvbnN0IGNoYXIqIG5hbWUpCit7CisgICAgc2V0UGF0aE5hbWUobmFtZSwgc3RybGVuKG5hbWUpKTsKK30KKwordm9pZCBTdHJpbmc4OjpzZXRQYXRoTmFtZShjb25zdCBjaGFyKiBuYW1lLCBzaXplX3QgbGVuKQoreworICAgIGNoYXIqIGJ1ZiA9IGxvY2tCdWZmZXIobGVuKTsKKworICAgIG1lbWNweShidWYsIG5hbWUsIGxlbik7CisKKyAgICAvLyByZW1vdmUgdHJhaWxpbmcgcGF0aCBzZXBhcmF0b3IsIGlmIHByZXNlbnQKKyAgICBpZiAobGVuID4gMCAmJiBidWZbbGVuLTFdID09IE9TX1BBVEhfU0VQQVJBVE9SKQorICAgICAgICBsZW4tLTsKKworICAgIGJ1ZltsZW5dID0gJ1wwJzsKKworICAgIHVubG9ja0J1ZmZlcihsZW4pOworfQorCitTdHJpbmc4IFN0cmluZzg6OmdldFBhdGhMZWFmKHZvaWQpIGNvbnN0Cit7CisgICAgY29uc3QgY2hhciogY3A7CisgICAgY29uc3QgY2hhcipjb25zdCBidWYgPSBtU3RyaW5nOworCisgICAgY3AgPSBzdHJyY2hyKGJ1ZiwgT1NfUEFUSF9TRVBBUkFUT1IpOworICAgIGlmIChjcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gU3RyaW5nOCgqdGhpcyk7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gU3RyaW5nOChjcCsxKTsKK30KKworU3RyaW5nOCBTdHJpbmc4OjpnZXRQYXRoRGlyKHZvaWQpIGNvbnN0Cit7CisgICAgY29uc3QgY2hhciogY3A7CisgICAgY29uc3QgY2hhcipjb25zdCBzdHIgPSBtU3RyaW5nOworCisgICAgY3AgPSBzdHJyY2hyKHN0ciwgT1NfUEFUSF9TRVBBUkFUT1IpOworICAgIGlmIChjcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gU3RyaW5nOCgiIik7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gU3RyaW5nOChzdHIsIGNwIC0gc3RyKTsKK30KKworU3RyaW5nOCBTdHJpbmc4Ojp3YWxrUGF0aChTdHJpbmc4KiBvdXRSZW1haW5zKSBjb25zdAoreworICAgIGNvbnN0IGNoYXIqIGNwOworICAgIGNvbnN0IGNoYXIqY29uc3Qgc3RyID0gbVN0cmluZzsKKyAgICBjb25zdCBjaGFyKiBidWYgPSBzdHI7CisKKyAgICBjcCA9IHN0cmNocihidWYsIE9TX1BBVEhfU0VQQVJBVE9SKTsKKyAgICBpZiAoY3AgPT0gYnVmKSB7CisgICAgICAgIC8vIGRvbid0IGluY2x1ZGUgYSBsZWFkaW5nICcvJy4KKyAgICAgICAgYnVmID0gYnVmKzE7CisgICAgICAgIGNwID0gc3RyY2hyKGJ1ZiwgT1NfUEFUSF9TRVBBUkFUT1IpOworICAgIH0KKworICAgIGlmIChjcCA9PSBOVUxMKSB7CisgICAgICAgIFN0cmluZzggcmVzID0gYnVmICE9IHN0ciA/IFN0cmluZzgoYnVmKSA6ICp0aGlzOworICAgICAgICBpZiAob3V0UmVtYWlucykgKm91dFJlbWFpbnMgPSBTdHJpbmc4KCIiKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBTdHJpbmc4IHJlcyhidWYsIGNwLWJ1Zik7CisgICAgaWYgKG91dFJlbWFpbnMpICpvdXRSZW1haW5zID0gU3RyaW5nOChjcCsxKTsKKyAgICByZXR1cm4gcmVzOworfQorCisvKgorICogSGVscGVyIGZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBzdGFydCBvZiBhbiBleHRlbnNpb24gaW4gYSBwYXRobmFtZS4KKyAqCisgKiBSZXR1cm5zIGEgcG9pbnRlciBpbnNpZGUgbVN0cmluZywgb3IgTlVMTCBpZiBubyBleHRlbnNpb24gd2FzIGZvdW5kLgorICovCitjaGFyKiBTdHJpbmc4OjpmaW5kX2V4dGVuc2lvbih2b2lkKSBjb25zdAoreworICAgIGNvbnN0IGNoYXIqIGxhc3RTbGFzaDsKKyAgICBjb25zdCBjaGFyKiBsYXN0RG90OworICAgIGludCBleHRMZW47CisgICAgY29uc3QgY2hhciogY29uc3Qgc3RyID0gbVN0cmluZzsKKworICAgIC8vIG9ubHkgbG9vayBhdCB0aGUgZmlsZW5hbWUKKyAgICBsYXN0U2xhc2ggPSBzdHJyY2hyKHN0ciwgT1NfUEFUSF9TRVBBUkFUT1IpOworICAgIGlmIChsYXN0U2xhc2ggPT0gTlVMTCkKKyAgICAgICAgbGFzdFNsYXNoID0gc3RyOworICAgIGVsc2UKKyAgICAgICAgbGFzdFNsYXNoKys7CisKKyAgICAvLyBmaW5kIHRoZSBsYXN0IGRvdAorICAgIGxhc3REb3QgPSBzdHJyY2hyKGxhc3RTbGFzaCwgJy4nKTsKKyAgICBpZiAobGFzdERvdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8vIGxvb2tzIGdvb2QsIHNoaXAgaXQKKyAgICByZXR1cm4gY29uc3RfY2FzdDxjaGFyKj4obGFzdERvdCk7Cit9CisKK1N0cmluZzggU3RyaW5nODo6Z2V0UGF0aEV4dGVuc2lvbih2b2lkKSBjb25zdAoreworICAgIGNoYXIqIGV4dDsKKworICAgIGV4dCA9IGZpbmRfZXh0ZW5zaW9uKCk7CisgICAgaWYgKGV4dCAhPSBOVUxMKQorICAgICAgICByZXR1cm4gU3RyaW5nOChleHQpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoIiIpOworfQorCitTdHJpbmc4IFN0cmluZzg6OmdldEJhc2VQYXRoKHZvaWQpIGNvbnN0Cit7CisgICAgY2hhciogZXh0OworICAgIGNvbnN0IGNoYXIqIGNvbnN0IHN0ciA9IG1TdHJpbmc7CisKKyAgICBleHQgPSBmaW5kX2V4dGVuc2lvbigpOworICAgIGlmIChleHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoKnRoaXMpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoc3RyLCBleHQgLSBzdHIpOworfQorCitTdHJpbmc4JiBTdHJpbmc4OjphcHBlbmRQYXRoKGNvbnN0IGNoYXIqIG5hbWUpCit7CisgICAgLy8gVE9ETzogVGhlIHRlc3QgYmVsb3cgd2lsbCBmYWlsIGZvciBXaW4zMiBwYXRocy4gRml4IGxhdGVyIG9yIGlnbm9yZS4KKyAgICBpZiAobmFtZVswXSAhPSBPU19QQVRIX1NFUEFSQVRPUikgeworICAgICAgICBpZiAoKm5hbWUgPT0gJ1wwJykgeworICAgICAgICAgICAgLy8gbm90aGluZyB0byBkbworICAgICAgICAgICAgcmV0dXJuICp0aGlzOworICAgICAgICB9CisKKyAgICAgICAgc2l6ZV90IGxlbiA9IGxlbmd0aCgpOworICAgICAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgICAgIC8vIG5vIGV4aXN0aW5nIGZpbGVuYW1lLCBqdXN0IHVzZSB0aGUgbmV3IG9uZQorICAgICAgICAgICAgc2V0UGF0aE5hbWUobmFtZSk7CisgICAgICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvLyBtYWtlIHJvb20gZm9yIG9sZFBhdGggKyAnLycgKyBuZXdQYXRoCisgICAgICAgIGludCBuZXdsZW4gPSBzdHJsZW4obmFtZSk7CisKKyAgICAgICAgY2hhciogYnVmID0gbG9ja0J1ZmZlcihsZW4rMStuZXdsZW4pOworCisgICAgICAgIC8vIGluc2VydCBhICcvJyBpZiBuZWVkZWQKKyAgICAgICAgaWYgKGJ1ZltsZW4tMV0gIT0gT1NfUEFUSF9TRVBBUkFUT1IpCisgICAgICAgICAgICBidWZbbGVuKytdID0gT1NfUEFUSF9TRVBBUkFUT1I7CisKKyAgICAgICAgbWVtY3B5KGJ1ZitsZW4sIG5hbWUsIG5ld2xlbisxKTsKKyAgICAgICAgbGVuICs9IG5ld2xlbjsKKworICAgICAgICB1bmxvY2tCdWZmZXIobGVuKTsKKworICAgICAgICByZXR1cm4gKnRoaXM7CisgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0UGF0aE5hbWUobmFtZSk7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9Cit9CisKK1N0cmluZzgmIFN0cmluZzg6OmNvbnZlcnRUb1Jlc1BhdGgoKQoreworI2lmIE9TX1BBVEhfU0VQQVJBVE9SICE9IFJFU19QQVRIX1NFUEFSQVRPUgorICAgIHNpemVfdCBsZW4gPSBsZW5ndGgoKTsKKyAgICBpZiAobGVuID4gMCkgeworICAgICAgICBjaGFyICogYnVmID0gbG9ja0J1ZmZlcihsZW4pOworICAgICAgICBmb3IgKGNoYXIgKiBlbmQgPSBidWYgKyBsZW47IGJ1ZiA8IGVuZDsgKytidWYpIHsKKyAgICAgICAgICAgIGlmICgqYnVmID09IE9TX1BBVEhfU0VQQVJBVE9SKQorICAgICAgICAgICAgICAgICpidWYgPSBSRVNfUEFUSF9TRVBBUkFUT1I7CisgICAgICAgIH0KKyAgICAgICAgdW5sb2NrQnVmZmVyKGxlbik7CisgICAgfQorI2VuZGlmCisgICAgcmV0dXJuICp0aGlzOworfQorCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1N5c3RlbUNsb2NrLmNwcCBiL2xpYnMvdXRpbHMvU3lzdGVtQ2xvY2suY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZGMwY2UKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1N5c3RlbUNsb2NrLmNwcApAQCAtMCwwICsxLDEzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworLyoKKyAqIFN5c3RlbSBjbG9jayBmdW5jdGlvbnMuCisgKi8KKworI2lmIEhBVkVfQU5EUk9JRF9PUworI2luY2x1ZGUgPGxpbnV4L2lvY3RsLmg+CisjaW5jbHVkZSA8bGludXgvcnRjLmg+CisjaW5jbHVkZSA8dXRpbHMvQXRvbWljLmg+CisjaW5jbHVkZSA8bGludXgvYW5kcm9pZF9hbGFybS5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgPHV0aWxzL1N5c3RlbUNsb2NrLmg+CisjaW5jbHVkZSA8dXRpbHMvVGltZXJzLmg+CisKKyNkZWZpbmUgTE9HX1RBRyAiU3lzdGVtQ2xvY2siCisjaW5jbHVkZSAidXRpbHMvTG9nLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqIFNldCB0aGUgY3VycmVudCB0aW1lLiAgVGhpcyBvbmx5IHdvcmtzIHdoZW4gcnVubmluZyBhcyByb290LgorICovCitpbnQgc2V0Q3VycmVudFRpbWVNaWxsaXMoaW50NjRfdCBtaWxsaXMpCit7CisjaWYgV0lOMzIKKyAgICAvLyBub3QgaW1wbGVtZW50ZWQKKyAgICByZXR1cm4gLTE7CisjZWxzZQorICAgIHN0cnVjdCB0aW1ldmFsIHR2OworI2lmIEhBVkVfQU5EUk9JRF9PUworICAgIHN0cnVjdCB0aW1lc3BlYyB0czsKKyAgICBpbnQgZmQ7CisgICAgaW50IHJlczsKKyNlbmRpZgorICAgIGludCByZXQgPSAwOworCisgICAgaWYgKG1pbGxpcyA8PSAwIHx8IG1pbGxpcyAvIDEwMDBMTCA+PSBJTlRfTUFYKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICB0di50dl9zZWMgPSAodGltZV90KSAobWlsbGlzIC8gMTAwMExMKTsKKyAgICB0di50dl91c2VjID0gKHN1c2Vjb25kc190KSAoKG1pbGxpcyAlIDEwMDBMTCkgKiAxMDAwTEwpOworCisgICAgTE9HRCgiU2V0dGluZyB0aW1lIG9mIGRheSB0byBzZWM9JWRcbiIsIChpbnQpIHR2LnR2X3NlYyk7CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBmZCA9IG9wZW4oIi9kZXYvYWxhcm0iLCBPX1JEV1IpOworICAgIGlmKGZkIDwgMCkgeworICAgICAgICBMT0dXKCJVbmFibGUgdG8gb3BlbiBhbGFybSBkcml2ZXI6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHRzLnR2X3NlYyA9IHR2LnR2X3NlYzsKKyAgICB0cy50dl9uc2VjID0gdHYudHZfdXNlYyAqIDEwMDA7CisgICAgcmVzID0gaW9jdGwoZmQsIEFORFJPSURfQUxBUk1fU0VUX1JUQywgJnRzKTsKKyAgICBpZihyZXMgPCAwKSB7CisgICAgICAgIExPR1coIlVuYWJsZSB0byBzZXQgcnRjIHRvICVsZDogJXNcbiIsIHR2LnR2X3NlYywgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgcmV0ID0gLTE7CisgICAgfQorICAgIGNsb3NlKGZkKTsKKyNlbHNlCisgICAgaWYgKHNldHRpbWVvZmRheSgmdHYsIE5VTEwpICE9IDApIHsKKyAgICAgICAgTE9HVygiVW5hYmxlIHRvIHNldCBjbG9jayB0byAlZC4lZDogJXNcbiIsCisgICAgICAgICAgICAoaW50KSB0di50dl9zZWMsIChpbnQpIHR2LnR2X3VzZWMsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIHJldCA9IC0xOworICAgIH0KKyNlbmRpZgorCisgICAgcmV0dXJuIHJldDsKKyNlbmRpZiAvLyBXSU4zMgorfQorCisvKgorICogbmF0aXZlIHB1YmxpYyBzdGF0aWMgbG9uZyB1cHRpbWVNaWxsaXMoKTsKKyAqLworaW50NjRfdCB1cHRpbWVNaWxsaXMoKQoreworICAgIGludDY0X3Qgd2hlbiA9IHN5c3RlbVRpbWUoU1lTVEVNX1RJTUVfTU9OT1RPTklDKTsKKyAgICByZXR1cm4gKGludDY0X3QpIG5hbm9zZWNvbmRzX3RvX21pbGxpc2Vjb25kcyh3aGVuKTsKK30KKworLyoKKyAqIG5hdGl2ZSBwdWJsaWMgc3RhdGljIGxvbmcgZWxhcHNlZFJlYWx0aW1lKCk7CisgKi8KK2ludDY0X3QgZWxhcHNlZFJlYWx0aW1lKCkKK3sKKyNpZiBIQVZFX0FORFJPSURfT1MKKyAgICBzdGF0aWMgaW50IHNfZmQgPSAtMTsKKworICAgIGlmIChzX2ZkID09IC0xKSB7CisgICAgICAgIGludCBmZCA9IG9wZW4oIi9kZXYvYWxhcm0iLCBPX1JET05MWSk7CisgICAgICAgIGlmIChhbmRyb2lkX2F0b21pY19jbXB4Y2hnKC0xLCBmZCwgJnNfZmQpKSB7CisgICAgICAgICAgICBjbG9zZShmZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdHJ1Y3QgdGltZXNwZWMgdHM7CisgICAgaW50IHJlc3VsdCA9IGlvY3RsKHNfZmQsCisgICAgICAgICAgICBBTkRST0lEX0FMQVJNX0dFVF9USU1FKEFORFJPSURfQUxBUk1fRUxBUFNFRF9SRUFMVElNRSksICZ0cyk7CisKKyAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgICAgaW50NjRfdCB3aGVuID0gc2Vjb25kc190b19uYW5vc2Vjb25kcyh0cy50dl9zZWMpICsgdHMudHZfbnNlYzsKKyAgICAgICAgcmV0dXJuIChpbnQ2NF90KSBuYW5vc2Vjb25kc190b19taWxsaXNlY29uZHMod2hlbik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gWFhYOiB0aGVyZSB3YXMgYW4gZXJyb3IsIHByb2JhYmx5IGJlY2F1c2UgdGhlIGRyaXZlciBkaWRuJ3QKKyAgICAgICAgLy8gZXhpc3QgLi4uIHRoaXMgc2hvdWxkIHJldHVybgorICAgICAgICAvLyBhIHJlYWwgZXJyb3IsIGxpa2UgYW4gZXhjZXB0aW9uIQorICAgICAgICBpbnQ2NF90IHdoZW4gPSBzeXN0ZW1UaW1lKFNZU1RFTV9USU1FX01PTk9UT05JQyk7CisgICAgICAgIHJldHVybiAoaW50NjRfdCkgbmFub3NlY29uZHNfdG9fbWlsbGlzZWNvbmRzKHdoZW4pOworICAgIH0KKyNlbHNlCisgICAgaW50NjRfdCB3aGVuID0gc3lzdGVtVGltZShTWVNURU1fVElNRV9NT05PVE9OSUMpOworICAgIHJldHVybiAoaW50NjRfdCkgbmFub3NlY29uZHNfdG9fbWlsbGlzZWNvbmRzKHdoZW4pOworI2VuZGlmCit9CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1RleHRPdXRwdXQuY3BwIGIvbGlicy91dGlscy9UZXh0T3V0cHV0LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZWJlZTk5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9UZXh0T3V0cHV0LmNwcApAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDx1dGlscy9UZXh0T3V0cHV0Lmg+CisKKyNpbmNsdWRlIDx1dGlscy9EZWJ1Zy5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgYm9vbCB2YWwpCit7CisgICAgaWYgKHZhbCkgdG8ucHJpbnQoInRydWUiLCA0KTsKKyAgICBlbHNlIHRvLnByaW50KCJmYWxzZSIsIDUpOworICAgIHJldHVybiB0bzsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgaW50IHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlsxNl07CisgICAgc3ByaW50ZihidWYsICIlZCIsIHZhbCk7CisgICAgdG8ucHJpbnQoYnVmLCBzdHJsZW4oYnVmKSk7CisgICAgcmV0dXJuIHRvOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBsb25nIHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlsxNl07CisgICAgc3ByaW50ZihidWYsICIlbGQiLCB2YWwpOworICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgdW5zaWduZWQgaW50IHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlsxNl07CisgICAgc3ByaW50ZihidWYsICIldSIsIHZhbCk7CisgICAgdG8ucHJpbnQoYnVmLCBzdHJsZW4oYnVmKSk7CisgICAgcmV0dXJuIHRvOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCB1bnNpZ25lZCBsb25nIHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlsxNl07CisgICAgc3ByaW50ZihidWYsICIlbHUiLCB2YWwpOworICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgbG9uZyBsb25nIHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlszMl07CisgICAgc3ByaW50ZihidWYsICIlTGQiLCB2YWwpOworICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgdW5zaWduZWQgbG9uZyBsb25nIHZhbCkKK3sKKyAgICBjaGFyIGJ1ZlszMl07CisgICAgc3ByaW50ZihidWYsICIlTHUiLCB2YWwpOworICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworc3RhdGljIFRleHRPdXRwdXQmIHByaW50X2Zsb2F0KFRleHRPdXRwdXQmIHRvLCBkb3VibGUgdmFsdWUpCit7CisgICAgY2hhciBidWZbNjRdOworICAgIHNwcmludGYoYnVmLCAiJWciLCB2YWx1ZSk7CisgICAgaWYoICFzdHJjaHIoYnVmLCAnLicpICYmICFzdHJjaHIoYnVmLCAnZScpICYmCisgICAgICAgICFzdHJjaHIoYnVmLCAnRScpICkgeworICAgICAgICBzdHJuY2F0KGJ1ZiwgIi4wIiwgc2l6ZW9mKGJ1ZiktMSk7CisgICAgfQorICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgZmxvYXQgdmFsKQoreworICAgIHJldHVybiBwcmludF9mbG9hdCh0byx2YWwpOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBkb3VibGUgdmFsKQoreworICAgIHJldHVybiBwcmludF9mbG9hdCh0byx2YWwpOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCB2b2lkKiB2YWwpCit7CisgICAgY2hhciBidWZbMTZdOworICAgIHNwcmludGYoYnVmLCAiJXAiLCB2YWwpOworICAgIHRvLnByaW50KGJ1Ziwgc3RybGVuKGJ1ZikpOworICAgIHJldHVybiB0bzsKK30KKworc3RhdGljIHZvaWQgdGV4dE91dHB1dFByaW50ZXIodm9pZCogY29va2llLCBjb25zdCBjaGFyKiB0eHQpCit7CisgICAgKChUZXh0T3V0cHV0Kiljb29raWUpLT5wcmludCh0eHQsIHN0cmxlbih0eHQpKTsKK30KKworVGV4dE91dHB1dCYgb3BlcmF0b3I8PChUZXh0T3V0cHV0JiB0bywgY29uc3QgVHlwZUNvZGUmIHZhbCkKK3sKKyAgICBwcmludFR5cGVDb2RlKHZhbC50eXBlQ29kZSgpLCB0ZXh0T3V0cHV0UHJpbnRlciwgKHZvaWQqKSZ0byk7CisgICAgcmV0dXJuIHRvOworfQorCitIZXhEdW1wOjpIZXhEdW1wKGNvbnN0IHZvaWQgKmJ1Ziwgc2l6ZV90IHNpemUsIHNpemVfdCBieXRlc1BlckxpbmUpCisgICAgOiBtQnVmZmVyKGJ1ZikKKyAgICAsIG1TaXplKHNpemUpCisgICAgLCBtQnl0ZXNQZXJMaW5lKGJ5dGVzUGVyTGluZSkKKyAgICAsIG1TaW5nbGVMaW5lQ3V0b2ZmKDE2KQorICAgICwgbUFsaWdubWVudCg0KQorICAgICwgbUNBcnJheVN0eWxlKGZhbHNlKQoreworICAgIGlmIChieXRlc1BlckxpbmUgPj0gMTYpIG1BbGlnbm1lbnQgPSA0OworICAgIGVsc2UgaWYgKGJ5dGVzUGVyTGluZSA+PSA4KSBtQWxpZ25tZW50ID0gMjsKKyAgICBlbHNlIG1BbGlnbm1lbnQgPSAxOworfQorCitUZXh0T3V0cHV0JiBvcGVyYXRvcjw8KFRleHRPdXRwdXQmIHRvLCBjb25zdCBIZXhEdW1wJiB2YWwpCit7CisgICAgcHJpbnRIZXhEYXRhKDAsIHZhbC5idWZmZXIoKSwgdmFsLnNpemUoKSwgdmFsLmJ5dGVzUGVyTGluZSgpLAorICAgICAgICB2YWwuc2luZ2xlTGluZUN1dG9mZigpLCB2YWwuYWxpZ25tZW50KCksIHZhbC5jYXJyYXlTdHlsZSgpLAorICAgICAgICB0ZXh0T3V0cHV0UHJpbnRlciwgKHZvaWQqKSZ0byk7CisgICAgcmV0dXJuIHRvOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9UaHJlYWRzLmNwcCBiL2xpYnMvdXRpbHMvVGhyZWFkcy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWY0MDdhOQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvVGhyZWFkcy5jcHAKQEAgLTAsMCArMSwxMTI4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJsaWJ1dGlscy50aHJlYWRzIgorCisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0xvZy5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxtZW1vcnkuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCisjaWYgZGVmaW5lZChIQVZFX1BUSFJFQURTKQorIyBpbmNsdWRlIDxwdGhyZWFkLmg+CisjIGluY2x1ZGUgPHNjaGVkLmg+CisjIGluY2x1ZGUgPHN5cy9yZXNvdXJjZS5oPgorI2VsaWYgZGVmaW5lZChIQVZFX1dJTjMyX1RIUkVBRFMpCisjIGluY2x1ZGUgPHdpbmRvd3MuaD4KKyMgaW5jbHVkZSA8c3RkaW50Lmg+CisjIGluY2x1ZGUgPHByb2Nlc3MuaD4KKyMgZGVmaW5lIEhBVkVfQ1JFQVRFVEhSRUFEICAvLyBDeWd3aW4sIHZzLiBIQVZFX19CRUdJTlRIUkVBREVYIGZvciBNaW5HVworI2VuZGlmCisKKyNpZiBkZWZpbmVkKEhBVkVfRlVURVgpCisjaW5jbHVkZSA8cHJpdmF0ZS91dGlscy9mdXRleF9zeW5jaHJvLmg+CisjZW5kaWYKKworI2lmIGRlZmluZWQoSEFWRV9QUkNUTCkKKyNpbmNsdWRlIDxzeXMvcHJjdGwuaD4KKyNlbmRpZgorCisvKgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiAgICAgIFRocmVhZCB3cmFwcGVycworICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiBkZWZpbmVkKEhBVkVfUFRIUkVBRFMpCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBQVEhSRUFECisjZW5kaWYKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLyoKKyAqIENyZWF0ZSBhbmQgcnVuIGEgbmV3IHRoZWFkLgorICoKKyAqIFdlIGNyZWF0ZSBpdCAiZGV0YWNoZWQiLCBzbyBpdCBjbGVhbnMgdXAgYWZ0ZXIgaXRzZWxmLgorICovCisKK3R5cGVkZWYgdm9pZCogKCphbmRyb2lkX3B0aHJlYWRfZW50cnkpKHZvaWQqKTsKKworc3RydWN0IHRocmVhZF9kYXRhX3QgeworICAgIHRocmVhZF9mdW5jX3QgICBlbnRyeUZ1bmN0aW9uOworICAgIHZvaWQqICAgICAgICAgICB1c2VyRGF0YTsKKyAgICBpbnQgICAgICAgICAgICAgcHJpb3JpdHk7CisgICAgY2hhciAqICAgICAgICAgIHRocmVhZE5hbWU7CisKKyAgICAvLyB3ZSB1c2UgdGhpcyB0cmFtcG9saW5lIHdoZW4gd2UgbmVlZCB0byBzZXQgdGhlIHByaW9yaXR5IHdpdGgKKyAgICAvLyBuaWNlL3NldHByaW9yaXR5LgorICAgIHN0YXRpYyBpbnQgdHJhbXBvbGluZShjb25zdCB0aHJlYWRfZGF0YV90KiB0KSB7CisgICAgICAgIHRocmVhZF9mdW5jX3QgZiA9IHQtPmVudHJ5RnVuY3Rpb247CisgICAgICAgIHZvaWQqIHUgPSB0LT51c2VyRGF0YTsKKyAgICAgICAgaW50IHByaW8gPSB0LT5wcmlvcml0eTsKKyAgICAgICAgY2hhciAqIG5hbWUgPSB0LT50aHJlYWROYW1lOworICAgICAgICBkZWxldGUgdDsKKyAgICAgICAgc2V0cHJpb3JpdHkoUFJJT19QUk9DRVNTLCAwLCBwcmlvKTsKKyAgICAgICAgaWYgKG5hbWUpIHsKKyNpZiBkZWZpbmVkKEhBVkVfUFJDVEwpCisgICAgICAgICAgICAvLyBNYWMgT1MgZG9lc24ndCBoYXZlIHRoaXMsIGFuZCB3ZSBidWlsZCBsaWJ1dGlsIGZvciB0aGUgaG9zdCB0b28KKyAgICAgICAgICAgIGludCBoYXNBdCA9IDA7CisgICAgICAgICAgICBpbnQgaGFzRG90ID0gMDsKKyAgICAgICAgICAgIGNoYXIgKnMgPSBuYW1lOworICAgICAgICAgICAgd2hpbGUgKCpzKSB7CisgICAgICAgICAgICAgICAgaWYgKCpzID09ICcuJykgaGFzRG90ID0gMTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmICgqcyA9PSAnQCcpIGhhc0F0ID0gMTsKKyAgICAgICAgICAgICAgICBzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgbGVuID0gcyAtIG5hbWU7CisgICAgICAgICAgICBpZiAobGVuIDwgMTUgfHwgaGFzQXQgfHwgIWhhc0RvdCkgeworICAgICAgICAgICAgICAgIHMgPSBuYW1lOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzID0gbmFtZSArIGxlbiAtIDE1OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJjdGwoUFJfU0VUX05BTUUsICh1bnNpZ25lZCBsb25nKSBzLCAwLCAwLCAwKTsKKyNlbmRpZgorICAgICAgICAgICAgZnJlZShuYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZih1KTsKKyAgICB9Cit9OworCitpbnQgYW5kcm9pZENyZWF0ZVJhd1RocmVhZEV0YyhhbmRyb2lkX3RocmVhZF9mdW5jX3QgZW50cnlGdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp1c2VyRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB0aHJlYWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGhyZWFkUHJpb3JpdHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRocmVhZFN0YWNrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkX3RocmVhZF9pZF90ICp0aHJlYWRJZCkKK3sKKyAgICBwdGhyZWFkX2F0dHJfdCBhdHRyOyAKKyAgICBwdGhyZWFkX2F0dHJfaW5pdCgmYXR0cik7CisgICAgcHRocmVhZF9hdHRyX3NldGRldGFjaHN0YXRlKCZhdHRyLCBQVEhSRUFEX0NSRUFURV9ERVRBQ0hFRCk7CisKKyNpZmRlZiBIQVZFX0FORFJPSURfT1MgIC8qIHZhbGdyaW5kIGlzIHJlamVjdGluZyBSVC1wcmlvcml0eSBjcmVhdGUgcmVxcyAqLworICAgIGlmICh0aHJlYWRQcmlvcml0eSAhPSBQUklPUklUWV9ERUZBVUxUIHx8IHRocmVhZE5hbWUgIT0gTlVMTCkgeworICAgICAgICAvLyBXZSBjb3VsZCBhdm9pZCB0aGUgdHJhbXBvbGluZSBpZiB0aGVyZSB3YXMgYSB3YXkgdG8gZ2V0IHRvIHRoZQorICAgICAgICAvLyBhbmRyb2lkX3RocmVhZF9pZF90IChwaWQpIGZyb20gcHRocmVhZF90CisgICAgICAgIHRocmVhZF9kYXRhX3QqIHQgPSBuZXcgdGhyZWFkX2RhdGFfdDsKKyAgICAgICAgdC0+cHJpb3JpdHkgPSB0aHJlYWRQcmlvcml0eTsKKyAgICAgICAgdC0+dGhyZWFkTmFtZSA9IHRocmVhZE5hbWUgPyBzdHJkdXAodGhyZWFkTmFtZSkgOiBOVUxMOworICAgICAgICB0LT5lbnRyeUZ1bmN0aW9uID0gZW50cnlGdW5jdGlvbjsKKyAgICAgICAgdC0+dXNlckRhdGEgPSB1c2VyRGF0YTsKKyAgICAgICAgZW50cnlGdW5jdGlvbiA9IChhbmRyb2lkX3RocmVhZF9mdW5jX3QpJnRocmVhZF9kYXRhX3Q6OnRyYW1wb2xpbmU7CisgICAgICAgIHVzZXJEYXRhID0gdDsgICAgICAgICAgICAKKyAgICB9CisjZW5kaWYKKworICAgIGlmICh0aHJlYWRTdGFja1NpemUpIHsKKyAgICAgICAgcHRocmVhZF9hdHRyX3NldHN0YWNrc2l6ZSgmYXR0ciwgdGhyZWFkU3RhY2tTaXplKTsKKyAgICB9CisgICAgCisgICAgZXJybm8gPSAwOworICAgIHB0aHJlYWRfdCB0aHJlYWQ7CisgICAgaW50IHJlc3VsdCA9IHB0aHJlYWRfY3JlYXRlKCZ0aHJlYWQsICZhdHRyLAorICAgICAgICAgICAgICAgICAgICAoYW5kcm9pZF9wdGhyZWFkX2VudHJ5KWVudHJ5RnVuY3Rpb24sIHVzZXJEYXRhKTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgTE9HRSgiYW5kcm9pZENyZWF0ZVJhd1RocmVhZEV0YyBmYWlsZWQgKGVudHJ5PSVwLCByZXM9JWQsIGVycm5vPSVkKVxuIgorICAgICAgICAgICAgICIoYW5kcm9pZCB0aHJlYWRQcmlvcml0eT0lZCkiLAorICAgICAgICAgICAgZW50cnlGdW5jdGlvbiwgcmVzdWx0LCBlcnJubywgdGhyZWFkUHJpb3JpdHkpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAodGhyZWFkSWQgIT0gTlVMTCkgeworICAgICAgICAqdGhyZWFkSWQgPSAoYW5kcm9pZF90aHJlYWRfaWRfdCl0aHJlYWQ7IC8vIFhYWDogdGhpcyBpcyBub3QgcG9ydGFibGUKKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKK2FuZHJvaWRfdGhyZWFkX2lkX3QgYW5kcm9pZEdldFRocmVhZElkKCkKK3sKKyAgICByZXR1cm4gKGFuZHJvaWRfdGhyZWFkX2lkX3QpcHRocmVhZF9zZWxmKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNlbGlmIGRlZmluZWQoSEFWRV9XSU4zMl9USFJFQURTKQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgV0lOMzJfVEhSRUFEUworI2VuZGlmCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8qCisgKiBUcmFtcG9saW5lIHRvIG1ha2UgdXMgX19zdGRjYWxsLWNvbXBsaWFudC4KKyAqCisgKiBXZSdyZSBleHBlY3RlZCB0byBkZWxldGUgInZEZXRhaWxzIiB3aGVuIHdlJ3JlIGRvbmUuCisgKi8KK3N0cnVjdCB0aHJlYWREZXRhaWxzIHsKKyAgICBpbnQgKCpmdW5jKSh2b2lkKik7CisgICAgdm9pZCogYXJnOworfTsKK3N0YXRpYyBfX3N0ZGNhbGwgdW5zaWduZWQgaW50IHRocmVhZEludGVybWVkaWFyeSh2b2lkKiB2RGV0YWlscykKK3sKKyAgICBzdHJ1Y3QgdGhyZWFkRGV0YWlscyogcERldGFpbHMgPSAoc3RydWN0IHRocmVhZERldGFpbHMqKSB2RGV0YWlsczsKKyAgICBpbnQgcmVzdWx0OworCisgICAgcmVzdWx0ID0gKCoocERldGFpbHMtPmZ1bmMpKShwRGV0YWlscy0+YXJnKTsKKworICAgIGRlbGV0ZSBwRGV0YWlsczsKKworICAgIExPRyhMT0dfVkVSQk9TRSwgInRocmVhZCIsICJ0aHJlYWQgZXhpdGluZ1xuIik7CisgICAgcmV0dXJuICh1bnNpZ25lZCBpbnQpIHJlc3VsdDsKK30KKworLyoKKyAqIENyZWF0ZSBhbmQgcnVuIGEgbmV3IHRocmVhZC4KKyAqLworc3RhdGljIGJvb2wgZG9DcmVhdGVUaHJlYWQoYW5kcm9pZF90aHJlYWRfZnVuY190IGZuLCB2b2lkKiBhcmcsIGFuZHJvaWRfdGhyZWFkX2lkX3QgKmlkKQoreworICAgIEhBTkRMRSBoVGhyZWFkOworICAgIHN0cnVjdCB0aHJlYWREZXRhaWxzKiBwRGV0YWlscyA9IG5ldyB0aHJlYWREZXRhaWxzOyAvLyBtdXN0IGJlIG9uIGhlYXAKKyAgICB1bnNpZ25lZCBpbnQgdGhyZGFkZHI7CisKKyAgICBwRGV0YWlscy0+ZnVuYyA9IGZuOworICAgIHBEZXRhaWxzLT5hcmcgPSBhcmc7CisKKyNpZiBkZWZpbmVkKEhBVkVfX0JFR0lOVEhSRUFERVgpCisgICAgaFRocmVhZCA9IChIQU5ETEUpIF9iZWdpbnRocmVhZGV4KE5VTEwsIDAsIHRocmVhZEludGVybWVkaWFyeSwgcERldGFpbHMsIDAsCisgICAgICAgICAgICAgICAgICAgICZ0aHJkYWRkcik7CisgICAgaWYgKGhUaHJlYWQgPT0gMCkKKyNlbGlmIGRlZmluZWQoSEFWRV9DUkVBVEVUSFJFQUQpCisgICAgaFRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLAorICAgICAgICAgICAgICAgICAgICAoTFBUSFJFQURfU1RBUlRfUk9VVElORSkgdGhyZWFkSW50ZXJtZWRpYXJ5LAorICAgICAgICAgICAgICAgICAgICAodm9pZCopIHBEZXRhaWxzLCAwLCAoRFdPUkQqKSAmdGhyZGFkZHIpOworICAgIGlmIChoVGhyZWFkID09IE5VTEwpCisjZW5kaWYKKyAgICB7CisgICAgICAgIExPRyhMT0dfV0FSTiwgInRocmVhZCIsICJXQVJOSU5HOiB0aHJlYWQgY3JlYXRlIGZhaWxlZFxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyNpZiBkZWZpbmVkKEhBVkVfQ1JFQVRFVEhSRUFEKQorICAgIC8qIGNsb3NlIHRoZSBtYW5hZ2VtZW50IGhhbmRsZSAqLworICAgIENsb3NlSGFuZGxlKGhUaHJlYWQpOworI2VuZGlmCisKKyAgICBpZiAoaWQgIT0gTlVMTCkgeworICAgICAgCSppZCA9IChhbmRyb2lkX3RocmVhZF9pZF90KXRocmRhZGRyOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworfQorCitpbnQgYW5kcm9pZENyZWF0ZVJhd1RocmVhZEV0YyhhbmRyb2lkX3RocmVhZF9mdW5jX3QgZm4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdXNlckRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdGhyZWFkTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRocmVhZFByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0aHJlYWRTdGFja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kcm9pZF90aHJlYWRfaWRfdCAqdGhyZWFkSWQpCit7CisgICAgcmV0dXJuIGRvQ3JlYXRlVGhyZWFkKCAgZm4sIHVzZXJEYXRhLCB0aHJlYWRJZCk7Cit9CisKK2FuZHJvaWRfdGhyZWFkX2lkX3QgYW5kcm9pZEdldFRocmVhZElkKCkKK3sKKyAgICByZXR1cm4gKGFuZHJvaWRfdGhyZWFkX2lkX3QpR2V0Q3VycmVudFRocmVhZElkKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNlbHNlCisjZXJyb3IgIlRocmVhZHMgbm90IHN1cHBvcnRlZCIKKyNlbmRpZgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIENvbW1vbiBUaHJlYWQgZnVuY3Rpb25zCisjZW5kaWYKKworaW50IGFuZHJvaWRDcmVhdGVUaHJlYWQoYW5kcm9pZF90aHJlYWRfZnVuY190IGZuLCB2b2lkKiBhcmcpCit7CisgICAgcmV0dXJuIGNyZWF0ZVRocmVhZEV0YyhmbiwgYXJnKTsKK30KKworaW50IGFuZHJvaWRDcmVhdGVUaHJlYWRHZXRJRChhbmRyb2lkX3RocmVhZF9mdW5jX3QgZm4sIHZvaWQgKmFyZywgYW5kcm9pZF90aHJlYWRfaWRfdCAqaWQpCit7CisgICAgcmV0dXJuIGNyZWF0ZVRocmVhZEV0YyhmbiwgYXJnLCAiYW5kcm9pZDp1bm5hbWVkX3RocmVhZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQUklPUklUWV9ERUZBVUxULCAwLCBpZCk7Cit9CisKK3N0YXRpYyBhbmRyb2lkX2NyZWF0ZV90aHJlYWRfZm4gZ0NyZWF0ZVRocmVhZEZuID0gYW5kcm9pZENyZWF0ZVJhd1RocmVhZEV0YzsKKworaW50IGFuZHJvaWRDcmVhdGVUaHJlYWRFdGMoYW5kcm9pZF90aHJlYWRfZnVuY190IGVudHJ5RnVuY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdXNlckRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdGhyZWFkTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRocmVhZFByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0aHJlYWRTdGFja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kcm9pZF90aHJlYWRfaWRfdCAqdGhyZWFkSWQpCit7CisgICAgcmV0dXJuIGdDcmVhdGVUaHJlYWRGbihlbnRyeUZ1bmN0aW9uLCB1c2VyRGF0YSwgdGhyZWFkTmFtZSwKKyAgICAgICAgdGhyZWFkUHJpb3JpdHksIHRocmVhZFN0YWNrU2l6ZSwgdGhyZWFkSWQpOworfQorCit2b2lkIGFuZHJvaWRTZXRDcmVhdGVUaHJlYWRGdW5jKGFuZHJvaWRfY3JlYXRlX3RocmVhZF9mbiBmdW5jKQoreworICAgIGdDcmVhdGVUaHJlYWRGbiA9IGZ1bmM7Cit9CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBNdXRleCBjbGFzcworICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgTXV0ZXgKKyNlbmRpZgorCisjaWYgZGVmaW5lZChIQVZFX1BUSFJFQURTKSAmJiAhZGVmaW5lZChIQVZFX0ZVVEVYKQorLyoKKyAqIFNpbXBsZSBwdGhyZWFkIHdyYXBwZXIuCisgKi8KKworTXV0ZXg6Ok11dGV4KCkKK3sKKyAgICBfaW5pdCgpOworfQorCitNdXRleDo6TXV0ZXgoY29uc3QgY2hhciogbmFtZSkKK3sKKyAgICAvLyBYWFg6IG5hbWUgbm90IHVzZWQgZm9yIG5vdworICAgIF9pbml0KCk7Cit9CisKK3ZvaWQgTXV0ZXg6Ol9pbml0KCkKK3sKKyAgICBwdGhyZWFkX211dGV4X3QqIHBNdXRleCA9IG5ldyBwdGhyZWFkX211dGV4X3Q7CisgICAgcHRocmVhZF9tdXRleF9pbml0KHBNdXRleCwgTlVMTCk7CisgICAgbVN0YXRlID0gcE11dGV4OworfQorCitNdXRleDo6fk11dGV4KCkKK3sKKyAgICBkZWxldGUgKHB0aHJlYWRfbXV0ZXhfdCopIG1TdGF0ZTsKK30KKworc3RhdHVzX3QgTXV0ZXg6OmxvY2soKQoreworICAgIGludCByZXM7CisgICAgd2hpbGUgKChyZXM9cHRocmVhZF9tdXRleF9sb2NrKChwdGhyZWFkX211dGV4X3QqKSBtU3RhdGUpKSA9PSBFSU5UUikgOworICAgIHJldHVybiAtcmVzOworfQorCit2b2lkIE11dGV4Ojp1bmxvY2soKQoreworICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKChwdGhyZWFkX211dGV4X3QqKSBtU3RhdGUpOworfQorCitzdGF0dXNfdCBNdXRleDo6dHJ5TG9jaygpCit7CisgICAgaW50IHJlczsKKyAgICB3aGlsZSAoKHJlcz1wdGhyZWFkX211dGV4X3RyeWxvY2soKHB0aHJlYWRfbXV0ZXhfdCopIG1TdGF0ZSkpID09IEVJTlRSKSA7CisgICAgcmV0dXJuIC1yZXM7Cit9CisKKyNlbGlmIGRlZmluZWQoSEFWRV9GVVRFWCkKKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKKyNkZWZpbmUgU1RBVEUgKChmdXRleF9tdXRleF90KikgKCZtU3RhdGUpKQorCitNdXRleDo6TXV0ZXgoKQoreworICAgIF9pbml0KCk7Cit9CisKK011dGV4OjpNdXRleChjb25zdCBjaGFyKiBuYW1lKQoreworICAgIF9pbml0KCk7Cit9CisKK3ZvaWQKK011dGV4OjpfaW5pdCgpCit7CisgICAgZnV0ZXhfbXV0ZXhfaW5pdChTVEFURSk7Cit9CisKK011dGV4Ojp+TXV0ZXgoKQoreworfQorCitzdGF0dXNfdCBNdXRleDo6bG9jaygpCit7CisgICAgaW50IHJlczsKKyAgICB3aGlsZSAoKHJlcz1mdXRleF9tdXRleF9sb2NrKFNUQVRFLCBGVVRFWF9XQUlUX0lORklOSVRFKSkgPT0gRUlOVFIpIDsKKyAgICByZXR1cm4gLXJlczsKK30KKwordm9pZCBNdXRleDo6dW5sb2NrKCkKK3sKKyAgICBmdXRleF9tdXRleF91bmxvY2soU1RBVEUpOworfQorCitzdGF0dXNfdCBNdXRleDo6dHJ5TG9jaygpCit7CisgICAgaW50IHJlczsKKyAgICB3aGlsZSAoKHJlcz1mdXRleF9tdXRleF90cnlsb2NrKFNUQVRFKSkgPT0gRUlOVFIpIDsKKyAgICByZXR1cm4gLXJlczsKK30KKyN1bmRlZiBTVEFURQorCisjZWxpZiBkZWZpbmVkKEhBVkVfV0lOMzJfVEhSRUFEUykKKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK011dGV4OjpNdXRleCgpCit7CisgICAgSEFORExFIGhNdXRleDsKKworICAgIGFzc2VydChzaXplb2YoaE11dGV4KSA9PSBzaXplb2YobVN0YXRlKSk7CisKKyAgICBoTXV0ZXggPSBDcmVhdGVNdXRleChOVUxMLCBGQUxTRSwgTlVMTCk7CisgICAgbVN0YXRlID0gKHZvaWQqKSBoTXV0ZXg7Cit9CisKK011dGV4OjpNdXRleChjb25zdCBjaGFyKiBuYW1lKQoreworICAgIC8vIFhYWDogbmFtZSBub3QgdXNlZCBmb3Igbm93CisgICAgSEFORExFIGhNdXRleDsKKworICAgIGhNdXRleCA9IENyZWF0ZU11dGV4KE5VTEwsIEZBTFNFLCBOVUxMKTsKKyAgICBtU3RhdGUgPSAodm9pZCopIGhNdXRleDsKK30KKworTXV0ZXg6On5NdXRleCgpCit7CisgICAgQ2xvc2VIYW5kbGUoKEhBTkRMRSkgbVN0YXRlKTsKK30KKworc3RhdHVzX3QgTXV0ZXg6OmxvY2soKQoreworICAgIERXT1JEIGR3V2FpdFJlc3VsdDsKKyAgICBkd1dhaXRSZXN1bHQgPSBXYWl0Rm9yU2luZ2xlT2JqZWN0KChIQU5ETEUpIG1TdGF0ZSwgSU5GSU5JVEUpOworICAgIHJldHVybiBkd1dhaXRSZXN1bHQgIT0gV0FJVF9PQkpFQ1RfMCA/IC0xIDogTk9fRVJST1I7Cit9CisKK3ZvaWQgTXV0ZXg6OnVubG9jaygpCit7CisgICAgaWYgKCFSZWxlYXNlTXV0ZXgoKEhBTkRMRSkgbVN0YXRlKSkKKyAgICAgICAgTE9HKExPR19XQVJOLCAidGhyZWFkIiwgIldBUk5JTkc6IGJhZCByZXN1bHQgZnJvbSB1bmxvY2tpbmcgbXV0ZXhcbiIpOworfQorCitzdGF0dXNfdCBNdXRleDo6dHJ5TG9jaygpCit7CisgICAgRFdPUkQgZHdXYWl0UmVzdWx0OworCisgICAgZHdXYWl0UmVzdWx0ID0gV2FpdEZvclNpbmdsZU9iamVjdCgoSEFORExFKSBtU3RhdGUsIDApOworICAgIGlmIChkd1dhaXRSZXN1bHQgIT0gV0FJVF9PQkpFQ1RfMCAmJiBkd1dhaXRSZXN1bHQgIT0gV0FJVF9USU1FT1VUKQorICAgICAgICBMT0coTE9HX1dBUk4sICJ0aHJlYWQiLCAiV0FSTklORzogYmFkIHJlc3VsdCBmcm9tIHRyeS1sb2NraW5nIG11dGV4XG4iKTsKKyAgICByZXR1cm4gKGR3V2FpdFJlc3VsdCA9PSBXQUlUX09CSkVDVF8wKSA/IDAgOiAtMTsKK30KKworI2Vsc2UKKyNlcnJvciAiU29tZWJvZHkgZm9yZ290IHRvIGltcGxlbWVudCB0aHJlYWRzIGZvciB0aGlzIHBsYXRmb3JtLiIKKyNlbmRpZgorCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgQ29uZGl0aW9uIGNsYXNzCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqLworCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBDb25kaXRpb24KKyNlbmRpZgorCisjaWYgZGVmaW5lZChIQVZFX1BUSFJFQURTKSAmJiAhZGVmaW5lZChIQVZFX0ZVVEVYKQorCisvKgorICogQ29uc3RydWN0b3IuICBUaGlzIGlzIGEgc2ltcGxlIHB0aHJlYWQgd3JhcHBlci4KKyAqLworQ29uZGl0aW9uOjpDb25kaXRpb24oKQoreworICAgIHB0aHJlYWRfY29uZF90KiBwQ29uZCA9IG5ldyBwdGhyZWFkX2NvbmRfdDsKKworICAgIHB0aHJlYWRfY29uZF9pbml0KHBDb25kLCBOVUxMKTsKKyAgICBtU3RhdGUgPSBwQ29uZDsKK30KKworLyoKKyAqIERlc3RydWN0b3IuCisgKi8KK0NvbmRpdGlvbjo6fkNvbmRpdGlvbigpCit7CisgICAgcHRocmVhZF9jb25kX2Rlc3Ryb3koKHB0aHJlYWRfY29uZF90KikgbVN0YXRlKTsKKyAgICBkZWxldGUgKHB0aHJlYWRfY29uZF90KikgbVN0YXRlOworfQorCisvKgorICogV2FpdCBvbiBhIGNvbmRpdGlvbiB2YXJpYWJsZS4gIExvY2sgdGhlIG11dGV4IGJlZm9yZSBjYWxsaW5nLgorICovCisKK3N0YXR1c190IENvbmRpdGlvbjo6d2FpdChNdXRleCYgbXV0ZXgpCit7CisgICAgYXNzZXJ0KG11dGV4Lm1TdGF0ZSAhPSBOVUxMKTsKKworICAgIGludCBjYzsKKyAgICB3aGlsZSAoKGNjID0gcHRocmVhZF9jb25kX3dhaXQoKHB0aHJlYWRfY29uZF90KiltU3RhdGUsCisgICAgICAgICAgICAgICAgKHB0aHJlYWRfbXV0ZXhfdCopIG11dGV4Lm1TdGF0ZSkpID09IEVJTlRSKSA7CisgICAgcmV0dXJuIC1jYzsKK30KKworc3RhdHVzX3QgQ29uZGl0aW9uOjp3YWl0KE11dGV4JiBtdXRleCwgbnNlY3NfdCBhYnN0aW1lKQoreworICAgIGFzc2VydChtdXRleC5tU3RhdGUgIT0gTlVMTCk7CisKKyAgICBzdHJ1Y3QgdGltZXNwZWMgdHM7CisgICAgdHMudHZfc2VjID0gYWJzdGltZS8xMDAwMDAwMDAwOworICAgIHRzLnR2X25zZWMgPSBhYnN0aW1lLSh0cy50dl9zZWMqMTAwMDAwMDAwMCk7CisgICAgCisgICAgaW50IGNjOworICAgIHdoaWxlICgoY2MgPSBwdGhyZWFkX2NvbmRfdGltZWR3YWl0KChwdGhyZWFkX2NvbmRfdCopbVN0YXRlLAorICAgICAgICAgICAgKHB0aHJlYWRfbXV0ZXhfdCopIG11dGV4Lm1TdGF0ZSwgJnRzKSkgPT0gRUlOVFIpIDsKKyAgICByZXR1cm4gLWNjOworfQorCitzdGF0dXNfdCBDb25kaXRpb246OndhaXRSZWxhdGl2ZShNdXRleCYgbXV0ZXgsIG5zZWNzX3QgcmVsdGltZSkKK3sKKyAgICByZXR1cm4gd2FpdChtdXRleCwgc3lzdGVtVGltZSgpK3JlbHRpbWUpOworfQorCisvKgorICogU2lnbmFsIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGFsbG93aW5nIG9uZSB0aHJlYWQgdG8gY29udGludWUuCisgKi8KK3ZvaWQgQ29uZGl0aW9uOjpzaWduYWwoKQoreworICAgIHB0aHJlYWRfY29uZF9zaWduYWwoKHB0aHJlYWRfY29uZF90KikgbVN0YXRlKTsKK30KKworLyoKKyAqIFNpZ25hbCB0aGUgY29uZGl0aW9uIHZhcmlhYmxlLCBhbGxvd2luZyBhbGwgdGhyZWFkcyB0byBjb250aW51ZS4KKyAqLwordm9pZCBDb25kaXRpb246OmJyb2FkY2FzdCgpCit7CisgICAgcHRocmVhZF9jb25kX2Jyb2FkY2FzdCgocHRocmVhZF9jb25kX3QqKSBtU3RhdGUpOworfQorCisjZWxpZiBkZWZpbmVkKEhBVkVfRlVURVgpCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCisjZGVmaW5lIFNUQVRFICgoZnV0ZXhfY29uZF90KikgKCZtU3RhdGUpKQorCisvKgorICogQ29uc3RydWN0b3IuICBUaGlzIGlzIGEgc2ltcGxlIHB0aHJlYWQgd3JhcHBlci4KKyAqLworQ29uZGl0aW9uOjpDb25kaXRpb24oKQoreworICAgIGZ1dGV4X2NvbmRfaW5pdChTVEFURSk7Cit9CisKKy8qCisgKiBEZXN0cnVjdG9yLgorICovCitDb25kaXRpb246On5Db25kaXRpb24oKQoreworfQorCisvKgorICogV2FpdCBvbiBhIGNvbmRpdGlvbiB2YXJpYWJsZS4gIExvY2sgdGhlIG11dGV4IGJlZm9yZSBjYWxsaW5nLgorICovCisKK3N0YXR1c190IENvbmRpdGlvbjo6d2FpdChNdXRleCYgbXV0ZXgpCit7CisgICAgYXNzZXJ0KG11dGV4Lm1TdGF0ZSAhPSBOVUxMKTsKKworICAgIGludCByZXM7CisgICAgd2hpbGUgKChyZXMgPSBmdXRleF9jb25kX3dhaXQoU1RBVEUsCisgICAgICAgIChmdXRleF9tdXRleF90KikoJm11dGV4Lm1TdGF0ZSksIEZVVEVYX1dBSVRfSU5GSU5JVEUpKSA9PSAtRUlOVFIpIDsKKworICAgIHJldHVybiAtcmVzOworfQorCitzdGF0dXNfdCBDb25kaXRpb246OndhaXQoTXV0ZXgmIG11dGV4LCBuc2Vjc190IGFic3RpbWUpCit7CisgICAgbnNlY3NfdCByZWx0aW1lID0gYWJzdGltZSAtIHN5c3RlbVRpbWUoKTsKKyAgICBpZiAocmVsdGltZSA8PSAwKSByZXR1cm4gdHJ1ZTsKKyAgICByZXR1cm4gd2FpdFJlbGF0aXZlKG11dGV4LCByZWx0aW1lKTsKK30KKworc3RhdHVzX3QgQ29uZGl0aW9uOjp3YWl0UmVsYXRpdmUoTXV0ZXgmIG11dGV4LCBuc2Vjc190IHJlbHRpbWUpCit7CisgICAgYXNzZXJ0KG11dGV4Lm1TdGF0ZSAhPSBOVUxMKTsKKyAgICBpbnQgcmVzOworICAgIHVuc2lnbmVkIG1zZWMgPSBuczJtcyhyZWx0aW1lKTsKKyAgICBpZihtc2VjID09IDApCisgICAgICAgIHJldHVybiB0cnVlOworICAgIC8vIFRoaXMgY29kZSB3aWxsIG5vdCB0aW1lIG91dCBhdCB0aGUgY29ycmVjdCB0aW1lIGlmIGludGVycnVwdGVkIGJ5IHNpZ25hbHMKKyAgICB3aGlsZSAoKHJlcyA9IGZ1dGV4X2NvbmRfd2FpdChTVEFURSwKKyAgICAgICAgKGZ1dGV4X211dGV4X3QqKSgmbXV0ZXgubVN0YXRlKSwgbXNlYykpID09IC1FSU5UUikgOworICAgIHJldHVybiByZXM7Cit9CisKKy8qCisgKiBTaWduYWwgdGhlIGNvbmRpdGlvbiB2YXJpYWJsZSwgYWxsb3dpbmcgb25lIHRocmVhZCB0byBjb250aW51ZS4KKyAqLwordm9pZCBDb25kaXRpb246OnNpZ25hbCgpCit7CisgICAgZnV0ZXhfY29uZF9zaWduYWwoU1RBVEUpOworfQorCisvKgorICogU2lnbmFsIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGFsbG93aW5nIGFsbCB0aHJlYWRzIHRvIGNvbnRpbnVlLgorICovCit2b2lkIENvbmRpdGlvbjo6YnJvYWRjYXN0KCkKK3sKKyAgICBmdXRleF9jb25kX2Jyb2FkY2FzdChTVEFURSk7Cit9CisKKyN1bmRlZiBTVEFURQorCisjZWxpZiBkZWZpbmVkKEhBVkVfV0lOMzJfVEhSRUFEUykKKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKKy8qCisgKiBXaW5kb3dzIGRvZXNuJ3QgaGF2ZSBhIGNvbmRpdGlvbiB2YXJpYWJsZSBzb2x1dGlvbi4gIEl0J3MgcG9zc2libGUKKyAqIHRvIGNyZWF0ZSBvbmUsIGJ1dCBpdCdzIGVhc3kgdG8gZ2V0IGl0IHdyb25nLiAgRm9yIGEgZGlzY3Vzc2lvbiwgYW5kCisgKiB0aGUgb3JpZ2luIG9mIHRoaXMgaW1wbGVtZW50YXRpb24sIHNlZToKKyAqCisgKiAgaHR0cDovL3d3dy5jcy53dXN0bC5lZHUvfnNjaG1pZHQvd2luMzItY3YtMS5odG1sCisgKgorICogVGhlIGltcGxlbWVudGF0aW9uIHNob3duIG9uIHRoZSBwYWdlIGRvZXMgTk9UIGZvbGxvdyBQT1NJWCBzZW1hbnRpY3MuCisgKiBBcyBhbiBvcHRpbWl6YXRpb24gdGhleSByZXF1aXJlIGFjcXVpcmluZyB0aGUgZXh0ZXJuYWwgbXV0ZXggYmVmb3JlCisgKiBjYWxsaW5nIHNpZ25hbCgpIGFuZCBicm9hZGNhc3QoKSwgd2hlcmVhcyBQT1NJWCBvbmx5IHJlcXVpcmVzIGdyYWJiaW5nCisgKiBpdCBiZWZvcmUgY2FsbGluZyB3YWl0KCkuICBUaGUgaW1wbGVtZW50YXRpb24gaGVyZSBoYXMgYmVlbiB1bi1vcHRpbWl6ZWQKKyAqIHRvIGhhdmUgdGhlIGNvcnJlY3QgYmVoYXZpb3IuCisgKi8KK3R5cGVkZWYgc3RydWN0IFdpbkNvbmRpdGlvbiB7CisgICAgLy8gTnVtYmVyIG9mIHdhaXRpbmcgdGhyZWFkcy4KKyAgICBpbnQgICAgICAgICAgICAgICAgIHdhaXRlcnNDb3VudDsKKworICAgIC8vIFNlcmlhbGl6ZSBhY2Nlc3MgdG8gd2FpdGVyc0NvdW50LgorICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgd2FpdGVyc0NvdW50TG9jazsKKworICAgIC8vIFNlbWFwaG9yZSB1c2VkIHRvIHF1ZXVlIHVwIHRocmVhZHMgd2FpdGluZyBmb3IgdGhlIGNvbmRpdGlvbiB0bworICAgIC8vIGJlY29tZSBzaWduYWxlZC4KKyAgICBIQU5ETEUgICAgICAgICAgICAgIHNlbWE7CisKKyAgICAvLyBBbiBhdXRvLXJlc2V0IGV2ZW50IHVzZWQgYnkgdGhlIGJyb2FkY2FzdC9zaWduYWwgdGhyZWFkIHRvIHdhaXQKKyAgICAvLyBmb3IgYWxsIHRoZSB3YWl0aW5nIHRocmVhZChzKSB0byB3YWtlIHVwIGFuZCBiZSByZWxlYXNlZCBmcm9tCisgICAgLy8gdGhlIHNlbWFwaG9yZS4KKyAgICBIQU5ETEUgICAgICAgICAgICAgIHdhaXRlcnNEb25lOworCisgICAgLy8gVGhpcyBtdXRleCB3b3VsZG4ndCBiZSBuZWNlc3NhcnkgaWYgd2UgcmVxdWlyZWQgdGhhdCB0aGUgY2FsbGVyCisgICAgLy8gbG9jayB0aGUgZXh0ZXJuYWwgbXV0ZXggYmVmb3JlIGNhbGxpbmcgc2lnbmFsKCkgYW5kIGJyb2FkY2FzdCgpLgorICAgIC8vIEknbSB0cnlpbmcgdG8gbWltaWMgcHRocmVhZCBzZW1hbnRpY3MgdGhvdWdoLgorICAgIEhBTkRMRSAgICAgICAgICAgICAgaW50ZXJuYWxNdXRleDsKKworICAgIC8vIEtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgd2Ugd2VyZSBicm9hZGNhc3Rpbmcgb3Igc2lnbmFsaW5nLiAgVGhpcworICAgIC8vIGFsbG93cyB1cyB0byBvcHRpbWl6ZSB0aGUgY29kZSBpZiB3ZSdyZSBqdXN0IHNpZ25hbGluZy4KKyAgICBib29sICAgICAgICAgICAgICAgIHdhc0Jyb2FkY2FzdDsKKworICAgIHN0YXR1c190IHdhaXQoV2luQ29uZGl0aW9uKiBjb25kU3RhdGUsIEhBTkRMRSBoTXV0ZXgsIG5zZWNzX3QqIGFic3RpbWUpCisgICAgeworICAgICAgICAvLyBJbmNyZW1lbnQgdGhlIHdhaXQgY291bnQsIGF2b2lkaW5nIHJhY2UgY29uZGl0aW9ucy4KKyAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50TG9jayk7CisgICAgICAgIGNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50Kys7CisgICAgICAgIC8vcHJpbnRmKCIrKysgd2FpdDogaW5jciB3YWl0ZXJzQ291bnQgdG8gJWQgKHRpZD0lbGQpXG4iLAorICAgICAgICAvLyAgICBjb25kU3RhdGUtPndhaXRlcnNDb3VudCwgZ2V0VGhyZWFkSWQoKSk7CisgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjb25kU3RhdGUtPndhaXRlcnNDb3VudExvY2spOworICAgIAorICAgICAgICBEV09SRCB0aW1lb3V0ID0gSU5GSU5JVEU7CisgICAgICAgIGlmIChhYnN0aW1lKSB7CisgICAgICAgICAgICBuc2Vjc190IHJlbHRpbWUgPSAqYWJzdGltZSAtIHN5c3RlbVRpbWUoKTsKKyAgICAgICAgICAgIGlmIChyZWx0aW1lIDwgMCkKKyAgICAgICAgICAgICAgICByZWx0aW1lID0gMDsKKyAgICAgICAgICAgIHRpbWVvdXQgPSByZWx0aW1lLzEwMDAwMDA7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIC8vIEF0b21pY2FsbHkgcmVsZWFzZSB0aGUgZXh0ZXJuYWwgbXV0ZXggYW5kIHdhaXQgb24gdGhlIHNlbWFwaG9yZS4KKyAgICAgICAgRFdPUkQgcmVzID0KKyAgICAgICAgICAgIFNpZ25hbE9iamVjdEFuZFdhaXQoaE11dGV4LCBjb25kU3RhdGUtPnNlbWEsIHRpbWVvdXQsIEZBTFNFKTsKKyAgICAKKyAgICAgICAgLy9wcmludGYoIisrKyB3YWl0OiBhd2FrZSAodGlkPSVsZClcbiIsIGdldFRocmVhZElkKCkpOworICAgIAorICAgICAgICAvLyBSZWFjcXVpcmUgbG9jayB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMuCisgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjb25kU3RhdGUtPndhaXRlcnNDb3VudExvY2spOworICAgIAorICAgICAgICAvLyBObyBsb25nZXIgd2FpdGluZy4KKyAgICAgICAgY29uZFN0YXRlLT53YWl0ZXJzQ291bnQtLTsKKyAgICAKKyAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHdlJ3JlIHRoZSBsYXN0IHdhaXRlciBhZnRlciBhIGJyb2FkY2FzdC4KKyAgICAgICAgYm9vbCBsYXN0V2FpdGVyID0gKGNvbmRTdGF0ZS0+d2FzQnJvYWRjYXN0ICYmIGNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50ID09IDApOworICAgIAorICAgICAgICAvL3ByaW50ZigiKysrIHdhaXQ6IGxhc3RXYWl0ZXI9JWQgKHdhc0JjPSVkIHdjPSVkKVxuIiwKKyAgICAgICAgLy8gICAgbGFzdFdhaXRlciwgY29uZFN0YXRlLT53YXNCcm9hZGNhc3QsIGNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50KTsKKyAgICAKKyAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50TG9jayk7CisgICAgCisgICAgICAgIC8vIElmIHdlJ3JlIHRoZSBsYXN0IHdhaXRlciB0aHJlYWQgZHVyaW5nIHRoaXMgcGFydGljdWxhciBicm9hZGNhc3QKKyAgICAgICAgLy8gdGhlbiBzaWduYWwgYnJvYWRjYXN0KCkgdGhhdCB3ZSdyZSBhbGwgYXdha2UuICBJdCdsbCBkcm9wIHRoZQorICAgICAgICAvLyBpbnRlcm5hbCBtdXRleC4KKyAgICAgICAgaWYgKGxhc3RXYWl0ZXIpIHsKKyAgICAgICAgICAgIC8vIEF0b21pY2FsbHkgc2lnbmFsIHRoZSAid2FpdGVyc0RvbmUiIGV2ZW50IGFuZCB3YWl0IHVudGlsIHdlCisgICAgICAgICAgICAvLyBjYW4gYWNxdWlyZSB0aGUgaW50ZXJuYWwgbXV0ZXguICBXZSB3YW50IHRvIGRvIHRoaXMgaW4gb25lIHN0ZXAKKyAgICAgICAgICAgIC8vIGJlY2F1c2UgaXQgZW5zdXJlcyB0aGF0IGV2ZXJ5Ym9keSBpcyBpbiB0aGUgbXV0ZXggRklGTyBiZWZvcmUKKyAgICAgICAgICAgIC8vIGFueSB0aHJlYWQgaGFzIGEgY2hhbmNlIHRvIHJ1bi4gIFdpdGhvdXQgaXQsIGFub3RoZXIgdGhyZWFkCisgICAgICAgICAgICAvLyBjb3VsZCB3YWtlIHVwLCBkbyB3b3JrLCBhbmQgaG9wIGJhY2sgaW4gYWhlYWQgb2YgdXMuCisgICAgICAgICAgICBTaWduYWxPYmplY3RBbmRXYWl0KGNvbmRTdGF0ZS0+d2FpdGVyc0RvbmUsIGNvbmRTdGF0ZS0+aW50ZXJuYWxNdXRleCwKKyAgICAgICAgICAgICAgICBJTkZJTklURSwgRkFMU0UpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gR3JhYiB0aGUgaW50ZXJuYWwgbXV0ZXguCisgICAgICAgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGNvbmRTdGF0ZS0+aW50ZXJuYWxNdXRleCwgSU5GSU5JVEUpOworICAgICAgICB9CisgICAgCisgICAgICAgIC8vIFJlbGVhc2UgdGhlIGludGVybmFsIGFuZCBncmFiIHRoZSBleHRlcm5hbC4KKyAgICAgICAgUmVsZWFzZU11dGV4KGNvbmRTdGF0ZS0+aW50ZXJuYWxNdXRleCk7CisgICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoaE11dGV4LCBJTkZJTklURSk7CisgICAgCisgICAgICAgIHJldHVybiByZXMgPT0gV0FJVF9PQkpFQ1RfMCA/IE5PX0VSUk9SIDogLTE7CisgICAgfQorfSBXaW5Db25kaXRpb247CisKKy8qCisgKiBDb25zdHJ1Y3Rvci4gIFNldCB1cCB0aGUgV2luQ29uZGl0aW9uIHN0dWZmLgorICovCitDb25kaXRpb246OkNvbmRpdGlvbigpCit7CisgICAgV2luQ29uZGl0aW9uKiBjb25kU3RhdGUgPSBuZXcgV2luQ29uZGl0aW9uOworCisgICAgY29uZFN0YXRlLT53YWl0ZXJzQ291bnQgPSAwOworICAgIGNvbmRTdGF0ZS0+d2FzQnJvYWRjYXN0ID0gZmFsc2U7CisgICAgLy8gc2VtYXBob3JlOiBubyBzZWN1cml0eSwgaW5pdGlhbCB2YWx1ZSBvZiAwCisgICAgY29uZFN0YXRlLT5zZW1hID0gQ3JlYXRlU2VtYXBob3JlKE5VTEwsIDAsIDB4N2ZmZmZmZmYsIE5VTEwpOworICAgIEluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50TG9jayk7CisgICAgLy8gYXV0by1yZXNldCBldmVudCwgbm90IHNpZ25hbGVkIGluaXRpYWxseQorICAgIGNvbmRTdGF0ZS0+d2FpdGVyc0RvbmUgPSBDcmVhdGVFdmVudChOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOworICAgIC8vIHVzZWQgc28gd2UgZG9uJ3QgaGF2ZSB0byBsb2NrIGV4dGVybmFsIG11dGV4IG9uIHNpZ25hbC9icm9hZGNhc3QKKyAgICBjb25kU3RhdGUtPmludGVybmFsTXV0ZXggPSBDcmVhdGVNdXRleChOVUxMLCBGQUxTRSwgTlVMTCk7CisKKyAgICBtU3RhdGUgPSBjb25kU3RhdGU7Cit9CisKKy8qCisgKiBEZXN0cnVjdG9yLiAgRnJlZSBXaW5kb3dzIHJlc291cmNlcyBhcyB3ZWxsIGFzIG91ciBhbGxvY2F0ZWQgc3RvcmFnZS4KKyAqLworQ29uZGl0aW9uOjp+Q29uZGl0aW9uKCkKK3sKKyAgICBXaW5Db25kaXRpb24qIGNvbmRTdGF0ZSA9IChXaW5Db25kaXRpb24qKSBtU3RhdGU7CisgICAgaWYgKGNvbmRTdGF0ZSAhPSBOVUxMKSB7CisgICAgICAgIENsb3NlSGFuZGxlKGNvbmRTdGF0ZS0+c2VtYSk7CisgICAgICAgIENsb3NlSGFuZGxlKGNvbmRTdGF0ZS0+d2FpdGVyc0RvbmUpOworICAgICAgICBkZWxldGUgY29uZFN0YXRlOworICAgIH0KK30KKworCitzdGF0dXNfdCBDb25kaXRpb246OndhaXQoTXV0ZXgmIG11dGV4KQoreworICAgIFdpbkNvbmRpdGlvbiogY29uZFN0YXRlID0gKFdpbkNvbmRpdGlvbiopIG1TdGF0ZTsKKyAgICBIQU5ETEUgaE11dGV4ID0gKEhBTkRMRSkgbXV0ZXgubVN0YXRlOworICAgIAorICAgIHJldHVybiAoKFdpbkNvbmRpdGlvbiopbVN0YXRlKS0+d2FpdChjb25kU3RhdGUsIGhNdXRleCwgTlVMTCk7Cit9CisKK3N0YXR1c190IENvbmRpdGlvbjo6d2FpdChNdXRleCYgbXV0ZXgsIG5zZWNzX3QgYWJzdGltZSkKK3sKKyAgICBXaW5Db25kaXRpb24qIGNvbmRTdGF0ZSA9IChXaW5Db25kaXRpb24qKSBtU3RhdGU7CisgICAgSEFORExFIGhNdXRleCA9IChIQU5ETEUpIG11dGV4Lm1TdGF0ZTsKKworICAgIHJldHVybiAoKFdpbkNvbmRpdGlvbiopbVN0YXRlKS0+d2FpdChjb25kU3RhdGUsIGhNdXRleCwgJmFic3RpbWUpOworfQorCitzdGF0dXNfdCBDb25kaXRpb246OndhaXRSZWxhdGl2ZShNdXRleCYgbXV0ZXgsIG5zZWNzX3QgcmVsdGltZSkKK3sKKyAgICByZXR1cm4gd2FpdChtdXRleCwgc3lzdGVtVGltZSgpK3JlbHRpbWUpOworfQorCisvKgorICogU2lnbmFsIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGFsbG93aW5nIG9uZSB0aHJlYWQgdG8gY29udGludWUuCisgKi8KK3ZvaWQgQ29uZGl0aW9uOjpzaWduYWwoKQoreworICAgIFdpbkNvbmRpdGlvbiogY29uZFN0YXRlID0gKFdpbkNvbmRpdGlvbiopIG1TdGF0ZTsKKworICAgIC8vIExvY2sgdGhlIGludGVybmFsIG11dGV4LiAgVGhpcyBlbnN1cmVzIHRoYXQgd2UgZG9uJ3QgY2xhc2ggd2l0aAorICAgIC8vIGJyb2FkY2FzdCgpLgorICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoY29uZFN0YXRlLT5pbnRlcm5hbE11dGV4LCBJTkZJTklURSk7CisKKyAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29uZFN0YXRlLT53YWl0ZXJzQ291bnRMb2NrKTsKKyAgICBib29sIGhhdmVXYWl0ZXJzID0gKGNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50ID4gMCk7CisgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50TG9jayk7CisKKyAgICAvLyBJZiBubyB3YWl0ZXJzLCB0aGVuIHRoaXMgaXMgYSBuby1vcC4gIE90aGVyd2lzZSwga25vY2sgdGhlIHNlbWFwaG9yZQorICAgIC8vIGRvd24gYSBub3RjaC4KKyAgICBpZiAoaGF2ZVdhaXRlcnMpCisgICAgICAgIFJlbGVhc2VTZW1hcGhvcmUoY29uZFN0YXRlLT5zZW1hLCAxLCAwKTsKKworICAgIC8vIFJlbGVhc2UgaW50ZXJuYWwgbXV0ZXguCisgICAgUmVsZWFzZU11dGV4KGNvbmRTdGF0ZS0+aW50ZXJuYWxNdXRleCk7Cit9CisKKy8qCisgKiBTaWduYWwgdGhlIGNvbmRpdGlvbiB2YXJpYWJsZSwgYWxsb3dpbmcgYWxsIHRocmVhZHMgdG8gY29udGludWUuCisgKgorICogRmlyc3Qgd2UgaGF2ZSB0byB3YWtlIHVwIGFsbCB0aHJlYWRzIHdhaXRpbmcgb24gdGhlIHNlbWFwaG9yZSwgdGhlbgorICogd2Ugd2FpdCB1bnRpbCBhbGwgb2YgdGhlIHRocmVhZHMgaGF2ZSBhY3R1YWxseSBiZWVuIHdva2VuIGJlZm9yZQorICogcmVsZWFzaW5nIHRoZSBpbnRlcm5hbCBtdXRleC4gIFRoaXMgZW5zdXJlcyB0aGF0IGFsbCB0aHJlYWRzIGFyZSB3b2tlbi4KKyAqLwordm9pZCBDb25kaXRpb246OmJyb2FkY2FzdCgpCit7CisgICAgV2luQ29uZGl0aW9uKiBjb25kU3RhdGUgPSAoV2luQ29uZGl0aW9uKikgbVN0YXRlOworCisgICAgLy8gTG9jayB0aGUgaW50ZXJuYWwgbXV0ZXguICBUaGlzIGtlZXBzIHRoZSBndXlzIHdlJ3JlIHdha2luZyB1cAorICAgIC8vIGZyb20gZ2V0dGluZyB0b28gZmFyLgorICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoY29uZFN0YXRlLT5pbnRlcm5hbE11dGV4LCBJTkZJTklURSk7CisKKyAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29uZFN0YXRlLT53YWl0ZXJzQ291bnRMb2NrKTsKKyAgICBib29sIGhhdmVXYWl0ZXJzID0gZmFsc2U7CisKKyAgICBpZiAoY29uZFN0YXRlLT53YWl0ZXJzQ291bnQgPiAwKSB7CisgICAgICAgIGhhdmVXYWl0ZXJzID0gdHJ1ZTsKKyAgICAgICAgY29uZFN0YXRlLT53YXNCcm9hZGNhc3QgPSB0cnVlOworICAgIH0KKworICAgIGlmIChoYXZlV2FpdGVycykgeworICAgICAgICAvLyBXYWtlIHVwIGFsbCB0aGUgd2FpdGVycy4KKyAgICAgICAgUmVsZWFzZVNlbWFwaG9yZShjb25kU3RhdGUtPnNlbWEsIGNvbmRTdGF0ZS0+d2FpdGVyc0NvdW50LCAwKTsKKworICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29uZFN0YXRlLT53YWl0ZXJzQ291bnRMb2NrKTsKKworICAgICAgICAvLyBXYWl0IGZvciBhbGwgYXdha2VuZWQgdGhyZWFkcyB0byBhY3F1aXJlIHRoZSBjb3VudGluZyBzZW1hcGhvcmUuCisgICAgICAgIC8vIFRoZSBsYXN0IGd1eSB3aG8gd2FzIHdhaXRpbmcgc2V0cyB0aGlzLgorICAgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGNvbmRTdGF0ZS0+d2FpdGVyc0RvbmUsIElORklOSVRFKTsKKworICAgICAgICAvLyBSZXNldCB3YXNCcm9hZGNhc3QuICAoTm8gY3JpdCBzZWN0aW9uIG5lZWRlZCBiZWNhdXNlIG5vYm9keQorICAgICAgICAvLyBlbHNlIGNhbiB3YWtlIHVwIHRvIHBva2UgYXQgaXQuKQorICAgICAgICBjb25kU3RhdGUtPndhc0Jyb2FkY2FzdCA9IDA7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gbm90aGluZyB0byBkbworICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29uZFN0YXRlLT53YWl0ZXJzQ291bnRMb2NrKTsKKyAgICB9CisKKyAgICAvLyBSZWxlYXNlIGludGVybmFsIG11dGV4LgorICAgIFJlbGVhc2VNdXRleChjb25kU3RhdGUtPmludGVybmFsTXV0ZXgpOworfQorCisjZWxzZQorI2Vycm9yICJjb25kaXRpb24gdmFyaWFibGVzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSIKKyNlbmRpZgorCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgUmVhZFdyaXRlTG9jayBjbGFzcworICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgUmVhZFdyaXRlTG9jaworI2VuZGlmCisKKy8qCisgKiBBZGQgYSByZWFkZXIuICBSZWFkZXJzIGFyZSBuaWNlLiAgVGhleSBzaGFyZS4KKyAqLwordm9pZCBSZWFkV3JpdGVMb2NrOjpsb2NrRm9yUmVhZCgpCit7CisgICAgbUxvY2subG9jaygpOworICAgIHdoaWxlIChtTnVtV3JpdGVycyA+IDApIHsKKyAgICAgICAgTE9HKExPR19ERUJVRywgInRocmVhZCIsICIrKysgbG9ja0ZvclJlYWQ6IHdhaXRpbmdcbiIpOworICAgICAgICBtUmVhZFdhaXRlci53YWl0KG1Mb2NrKTsKKyAgICB9CisgICAgYXNzZXJ0KG1OdW1Xcml0ZXJzID09IDApOworICAgIG1OdW1SZWFkZXJzKys7CisjaWYgZGVmaW5lZChQUklOVF9SRU5ERVJfVElNRVMpCisgICAgaWYgKG1OdW1SZWFkZXJzID09IDEpCisgICAgICAgIG1EZWJ1Z1RpbWVyLnN0YXJ0KCk7CisjZW5kaWYKKyAgICBtTG9jay51bmxvY2soKTsKK30KKworLyoKKyAqIFRyeSB0byBhZGQgYSByZWFkZXIuICBJZiBpdCBkb2Vzbid0IHdvcmsgcmlnaHQgYXdheSwgcmV0dXJuICJmYWxzZSIuCisgKi8KK2Jvb2wgUmVhZFdyaXRlTG9jazo6dHJ5TG9ja0ZvclJlYWQoKQoreworICAgIG1Mb2NrLmxvY2soKTsKKyAgICBpZiAobU51bVdyaXRlcnMgPiAwKSB7CisgICAgICAgIG1Mb2NrLnVubG9jaygpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGFzc2VydChtTnVtV3JpdGVycyA9PSAwKTsKKyAgICBtTnVtUmVhZGVycysrOworI2lmIGRlZmluZWQoUFJJTlRfUkVOREVSX1RJTUVTKQorICAgIGlmIChtTnVtUmVhZGVycyA9PSAxKQorICAgICAgICBtRGVidWdUaW1lci5zdGFydCgpOworI2VuZGlmCisgICAgbUxvY2sudW5sb2NrKCk7CisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8qCisgKiBSZW1vdmUgYSByZWFkZXIuCisgKi8KK3ZvaWQgUmVhZFdyaXRlTG9jazo6dW5sb2NrRm9yUmVhZCgpCit7CisgICAgbUxvY2subG9jaygpOworICAgIGlmIChtTnVtUmVhZGVycyA9PSAwKSB7CisgICAgICAgIG1Mb2NrLnVubG9jaygpOworICAgICAgICBMT0coTE9HX1dBUk4sICJ0aHJlYWQiLAorICAgICAgICAgICAgIldBUk5JTkc6IHVubG9ja0ZvclJlYWQgcmVxdWVzdGVkLCBidXQgbm90IGxvY2tlZFxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYXNzZXJ0KG1OdW1SZWFkZXJzID4gMCk7CisgICAgYXNzZXJ0KG1OdW1Xcml0ZXJzID09IDApOworICAgIG1OdW1SZWFkZXJzLS07CisgICAgaWYgKG1OdW1SZWFkZXJzID09IDApIHsgICAgICAgICAgIC8vIGxhc3QgcmVhZGVyPworI2lmIGRlZmluZWQoUFJJTlRfUkVOREVSX1RJTUVTKQorICAgICAgICBtRGVidWdUaW1lci5zdG9wKCk7CisgICAgICAgIHByaW50ZigiIHJkbGsgaGVsZCAlLjNmIG1zZWNcbiIsCisgICAgICAgICAgICAoZG91YmxlKSBtRGVidWdUaW1lci5kdXJhdGlvblVzZWNzKCkgLyAxMDAwLjApOworI2VuZGlmCisgICAgICAgIC8vcHJpbnRmKCIrKysgc2lnbmFsaW5nIHdyaXRlcnMgKGlmIGFueSlcbiIpOworICAgICAgICBtV3JpdGVXYWl0ZXIuc2lnbmFsKCk7ICAgICAgLy8gd2FrZSBvbmUgd3JpdGVyIChpZiBhbnkpCisgICAgfQorICAgIG1Mb2NrLnVubG9jaygpOworfQorCisvKgorICogQWRkIGEgd3JpdGVyLiAgVGhpcyByZXF1aXJlcyBleGNsdXNpdmUgYWNjZXNzIHRvIHRoZSBvYmplY3QuCisgKi8KK3ZvaWQgUmVhZFdyaXRlTG9jazo6bG9ja0ZvcldyaXRlKCkKK3sKKyAgICBtTG9jay5sb2NrKCk7CisgICAgd2hpbGUgKG1OdW1SZWFkZXJzID4gMCB8fCBtTnVtV3JpdGVycyA+IDApIHsKKyAgICAgICAgTE9HKExPR19ERUJVRywgInRocmVhZCIsICIrKysgbG9ja0ZvcldyaXRlOiB3YWl0aW5nXG4iKTsKKyAgICAgICAgbVdyaXRlV2FpdGVyLndhaXQobUxvY2spOworICAgIH0KKyAgICBhc3NlcnQobU51bVJlYWRlcnMgPT0gMCk7CisgICAgYXNzZXJ0KG1OdW1Xcml0ZXJzID09IDApOworICAgIG1OdW1Xcml0ZXJzKys7CisjaWYgZGVmaW5lZChQUklOVF9SRU5ERVJfVElNRVMpCisgICAgbURlYnVnVGltZXIuc3RhcnQoKTsKKyNlbmRpZgorICAgIG1Mb2NrLnVubG9jaygpOworfQorCisvKgorICogVHJ5IHRvIGFkZCBhIHdyaXRlci4gIElmIGl0IGRvZXNuJ3Qgd29yayByaWdodCBhd2F5LCByZXR1cm4gImZhbHNlIi4KKyAqLworYm9vbCBSZWFkV3JpdGVMb2NrOjp0cnlMb2NrRm9yV3JpdGUoKQoreworICAgIG1Mb2NrLmxvY2soKTsKKyAgICBpZiAobU51bVJlYWRlcnMgPiAwIHx8IG1OdW1Xcml0ZXJzID4gMCkgeworICAgICAgICBtTG9jay51bmxvY2soKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBhc3NlcnQobU51bVJlYWRlcnMgPT0gMCk7CisgICAgYXNzZXJ0KG1OdW1Xcml0ZXJzID09IDApOworICAgIG1OdW1Xcml0ZXJzKys7CisjaWYgZGVmaW5lZChQUklOVF9SRU5ERVJfVElNRVMpCisgICAgbURlYnVnVGltZXIuc3RhcnQoKTsKKyNlbmRpZgorICAgIG1Mb2NrLnVubG9jaygpOworICAgIHJldHVybiB0cnVlOworfQorCisvKgorICogUmVtb3ZlIGEgd3JpdGVyLgorICovCit2b2lkIFJlYWRXcml0ZUxvY2s6OnVubG9ja0ZvcldyaXRlKCkKK3sKKyAgICBtTG9jay5sb2NrKCk7CisgICAgaWYgKG1OdW1Xcml0ZXJzID09IDApIHsKKyAgICAgICAgbUxvY2sudW5sb2NrKCk7CisgICAgICAgIExPRyhMT0dfV0FSTiwgInRocmVhZCIsCisgICAgICAgICAgICAiV0FSTklORzogdW5sb2NrRm9yV3JpdGUgcmVxdWVzdGVkLCBidXQgbm90IGxvY2tlZFxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYXNzZXJ0KG1OdW1Xcml0ZXJzID09IDEpOworICAgIG1OdW1Xcml0ZXJzLS07CisjaWYgZGVmaW5lZChQUklOVF9SRU5ERVJfVElNRVMpCisgICAgbURlYnVnVGltZXIuc3RvcCgpOworICAgIC8vcHJpbnRmKCIgd3JsayBoZWxkICUuM2YgbXNlY1xuIiwKKyAgICAvLyAgICAoZG91YmxlKSBtRGVidWdUaW1lci5kdXJhdGlvblVzZWNzKCkgLyAxMDAwLjApOworI2VuZGlmCisgICAgbVdyaXRlV2FpdGVyLnNpZ25hbCgpOyAgICAgICAgIC8vIHNob3VsZCBvdGhlciB3cml0ZXJzIGdldCBmaXJzdCBkaWJzPworICAgIC8vcHJpbnRmKCIrKysgc2lnbmFsaW5nIHJlYWRlcnMgKGlmIGFueSlcbiIpOworICAgIG1SZWFkV2FpdGVyLmJyb2FkY2FzdCgpOyAgICAgICAgLy8gd2FrZSBhbGwgcmVhZGVycyAoaWYgYW55KQorICAgIG1Mb2NrLnVubG9jaygpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIFRocmVhZDo6VGhyZWFkCisjZW5kaWYKKworLyoKKyAqIFRoaXMgaXMgb3VyIHRocmVhZCBvYmplY3QhCisgKi8KKworVGhyZWFkOjpUaHJlYWQoYm9vbCBjYW5DYWxsSmF2YSkKKyAgICA6ICAgbUNhbkNhbGxKYXZhKGNhbkNhbGxKYXZhKSwKKyAgICAgICAgbVRocmVhZCh0aHJlYWRfaWRfdCgtMSkpLAorICAgICAgICBtTG9jaygiVGhyZWFkOjptTG9jayIpLAorICAgICAgICBtU3RhdHVzKE5PX0VSUk9SKSwKKyAgICAgICAgbUV4aXRQZW5kaW5nKGZhbHNlKSwgbVJ1bm5pbmcoZmFsc2UpCit7Cit9CisKK1RocmVhZDo6flRocmVhZCgpCit7Cit9CisKK3N0YXR1c190IFRocmVhZDo6cmVhZHlUb1J1bigpCit7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCitzdGF0dXNfdCBUaHJlYWQ6OnJ1bihjb25zdCBjaGFyKiBuYW1lLCBpbnQzMl90IHByaW9yaXR5LCBzaXplX3Qgc3RhY2spCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKworICAgIGlmIChtUnVubmluZykgeworICAgICAgICAvLyB0aHJlYWQgYWxyZWFkeSBzdGFydGVkCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICB9CisKKyAgICAvLyByZXNldCBzdGF0dXMgYW5kIGV4aXRQZW5kaW5nIHRvIHRoZWlyIGRlZmF1bHQgdmFsdWUsIHNvIHdlIGNhbgorICAgIC8vIHRyeSBhZ2FpbiBhZnRlciBhbiBlcnJvciBoYXBwZW5lZCAoZWl0aGVyIGJlbG93LCBvciBpbiByZWFkeVRvUnVuKCkpCisgICAgbVN0YXR1cyA9IE5PX0VSUk9SOworICAgIG1FeGl0UGVuZGluZyA9IGZhbHNlOworICAgIG1UaHJlYWQgPSB0aHJlYWRfaWRfdCgtMSk7CisgICAgCisgICAgLy8gaG9sZCBhIHN0cm9uZyByZWZlcmVuY2Ugb24gb3Vyc2VsZgorICAgIG1Ib2xkU2VsZiA9IHRoaXM7CisKKyAgICBib29sIHJlczsKKyAgICBpZiAobUNhbkNhbGxKYXZhKSB7CisgICAgICAgIHJlcyA9IGNyZWF0ZVRocmVhZEV0YyhfdGhyZWFkTG9vcCwKKyAgICAgICAgICAgICAgICB0aGlzLCBuYW1lLCBwcmlvcml0eSwgc3RhY2ssICZtVGhyZWFkKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXMgPSBhbmRyb2lkQ3JlYXRlUmF3VGhyZWFkRXRjKF90aHJlYWRMb29wLAorICAgICAgICAgICAgICAgIHRoaXMsIG5hbWUsIHByaW9yaXR5LCBzdGFjaywgJm1UaHJlYWQpOworICAgIH0KKyAgICAKKyAgICBpZiAocmVzID09IGZhbHNlKSB7CisgICAgICAgIG1TdGF0dXMgPSBVTktOT1dOX0VSUk9SOyAgIC8vIHNvbWV0aGluZyBoYXBwZW5lZCEKKyAgICAgICAgbVJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgbVRocmVhZCA9IHRocmVhZF9pZF90KC0xKTsKKyAgICB9CisgICAgCisgICAgaWYgKG1TdGF0dXMgPCAwKSB7CisgICAgICAgIC8vIHNvbWV0aGluZyBoYXBwZW5lZCwgZG9uJ3QgbGVhaworICAgICAgICBtSG9sZFNlbGYuY2xlYXIoKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIG1TdGF0dXM7Cit9CisKK2ludCBUaHJlYWQ6Ol90aHJlYWRMb29wKHZvaWQqIHVzZXIpCit7CisgICAgVGhyZWFkKiBjb25zdCBzZWxmID0gc3RhdGljX2Nhc3Q8VGhyZWFkKj4odXNlcik7CisgICAgc3A8VGhyZWFkPiBzdHJvbmcoc2VsZi0+bUhvbGRTZWxmKTsKKyAgICB3cDxUaHJlYWQ+IHdlYWsoc3Ryb25nKTsKKyAgICBzZWxmLT5tSG9sZFNlbGYuY2xlYXIoKTsKKworICAgIC8vIHdlJ3JlIGFib3V0IHRvIHJ1bi4uLgorICAgIHNlbGYtPm1TdGF0dXMgPSBzZWxmLT5yZWFkeVRvUnVuKCk7CisgICAgaWYgKHNlbGYtPm1TdGF0dXMhPU5PX0VSUk9SIHx8IHNlbGYtPm1FeGl0UGVuZGluZykgeworICAgICAgICAvLyBwcmV0ZW5kIHRoZSB0aHJlYWQgbmV2ZXIgc3RhcnRlZC4uLgorICAgICAgICBzZWxmLT5tRXhpdFBlbmRpbmcgPSBmYWxzZTsKKyAgICAgICAgc2VsZi0+bVJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIAorICAgIC8vIHRocmVhZCBpcyBydW5uaW5nIG5vdworICAgIHNlbGYtPm1SdW5uaW5nID0gdHJ1ZTsKKworICAgIGRvIHsKKyAgICAgICAgYm9vbCByZXN1bHQgPSBzZWxmLT50aHJlYWRMb29wKCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gZmFsc2UgfHwgc2VsZi0+bUV4aXRQZW5kaW5nKSB7CisgICAgICAgICAgICBzZWxmLT5tRXhpdFBlbmRpbmcgPSB0cnVlOworICAgICAgICAgICAgc2VsZi0+bUxvY2subG9jaygpOworICAgICAgICAgICAgc2VsZi0+bVJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgIHNlbGYtPm1UaHJlYWRFeGl0ZWRDb25kaXRpb24uc2lnbmFsKCk7CisgICAgICAgICAgICBzZWxmLT5tTG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvLyBSZWxlYXNlIG91ciBzdHJvbmcgcmVmZXJlbmNlLCB0byBsZXQgYSBjaGFuY2UgdG8gdGhlIHRocmVhZAorICAgICAgICAvLyB0byBkaWUgYSBwZWFjZWZ1bCBkZWF0aC4KKyAgICAgICAgc3Ryb25nLmNsZWFyKCk7CisgICAgICAgIC8vIEFuZCBpbW1lZGlhdGVseSwgcmVhY3F1aXJlIGEgc3Ryb25nIHJlZmVyZW5jZSBmb3IgdGhlIG5leHQgbG9vcAorICAgICAgICBzdHJvbmcgPSB3ZWFrLnByb21vdGUoKTsKKyAgICB9IHdoaWxlKHN0cm9uZyAhPSAwKTsKKyAgICAKKyAgICByZXR1cm4gMDsKK30KKwordm9pZCBUaHJlYWQ6OnJlcXVlc3RFeGl0KCkKK3sKKyAgICBtRXhpdFBlbmRpbmcgPSB0cnVlOworfQorCitzdGF0dXNfdCBUaHJlYWQ6OnJlcXVlc3RFeGl0QW5kV2FpdCgpCit7CisgICAgaWYgKG1TdGF0dXMgPT0gT0spIHsKKworICAgICAgICBpZiAobVRocmVhZCA9PSBnZXRUaHJlYWRJZCgpKSB7CisgICAgICAgICAgICBMT0dXKAorICAgICAgICAgICAgIlRocmVhZCAodGhpcz0lcCk6IGRvbid0IGNhbGwgd2FpdEZvckV4aXQoKSBmcm9tIHRoaXMgIgorICAgICAgICAgICAgIlRocmVhZCBvYmplY3QncyB0aHJlYWQuIEl0J3MgYSBndWFyYW50ZWVkIGRlYWRsb2NrISIsCisgICAgICAgICAgICB0aGlzKTsKKyAgICAgICAgICAgIHJldHVybiBXT1VMRF9CTE9DSzsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcmVxdWVzdEV4aXQoKTsKKworICAgICAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgICAgICB3aGlsZSAobVJ1bm5pbmcgPT0gdHJ1ZSkgeworICAgICAgICAgICAgbVRocmVhZEV4aXRlZENvbmRpdGlvbi53YWl0KG1Mb2NrKTsKKyAgICAgICAgfQorICAgICAgICBtRXhpdFBlbmRpbmcgPSBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIG1TdGF0dXM7Cit9CisKK2Jvb2wgVGhyZWFkOjpleGl0UGVuZGluZygpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1FeGl0UGVuZGluZzsKK30KKworCisKK307ICAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9UaW1lclByb2JlLmNwcCBiL2xpYnMvdXRpbHMvVGltZXJQcm9iZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM1NDgwZAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvVGltZXJQcm9iZS5jcHAKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvVGltZXJQcm9iZS5oPgorIAorI2lmIEVOQUJMRV9USU1FUl9QUk9CRQorCisjaWZkZWYgTE9HX1RBRworI3VuZGVmIExPR19UQUcKKyNlbmRpZgorI2RlZmluZSBMT0dfVEFHICJ0aW1lIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK1ZlY3RvcjxUaW1lclByb2JlOjpCdWNrZXQ+IFRpbWVyUHJvYmU6OmdCdWNrZXRzOworVGltZXJQcm9iZSogVGltZXJQcm9iZTo6Z0V4ZWN1dGVDaGFpbjsKK2ludCBUaW1lclByb2JlOjpnSW5kZW50OwordGltZXNwZWMgVGltZXJQcm9iZTo6Z1JlYWxCYXNlOworCitUaW1lclByb2JlOjpUaW1lclByb2JlKGNvbnN0IGNoYXIgdGFnW10sIGludCogc2xvdCkgOiBtVGFnKHRhZykKK3sKKyAgICBtTmV4dCA9IGdFeGVjdXRlQ2hhaW47CisgICAgZ0V4ZWN1dGVDaGFpbiA9IHRoaXM7CisgICAgbUluZGVudCA9IGdJbmRlbnQ7CisgICAgZ0luZGVudCArPSAxOworICAgIGlmIChtSW5kZW50ID4gMCkgeworICAgICAgICBpZiAoKnNsb3QgPT0gMCkgeworICAgICAgICAgICAgaW50IGNvdW50ID0gZ0J1Y2tldHMuYWRkKCk7CisgICAgICAgICAgICAqc2xvdCA9IGNvdW50OworICAgICAgICAgICAgQnVja2V0JiBidWNrZXQgPSBnQnVja2V0cy5lZGl0SXRlbUF0KGNvdW50KTsKKyAgICAgICAgICAgIG1lbXNldCgmYnVja2V0LCAwLCBzaXplb2YoQnVja2V0KSk7CisgICAgICAgICAgICBidWNrZXQubVRhZyA9IHRhZzsKKyAgICAgICAgICAgIGJ1Y2tldC5tU2xvdFB0ciA9IHNsb3Q7CisgICAgICAgICAgICBidWNrZXQubUluZGVudCA9IG1JbmRlbnQ7CisgICAgICAgIH0KKyAgICAgICAgbUJ1Y2tldCA9ICpzbG90OworICAgIH0KKyAgICBjbG9ja19nZXR0aW1lKENMT0NLX1JFQUxUSU1FLCAmbVJlYWxTdGFydCk7CisgICAgaWYgKGdSZWFsQmFzZS50dl9zZWMgPT0gMCkKKyAgICAgICAgZ1JlYWxCYXNlID0gbVJlYWxTdGFydDsKKyAgICBjbG9ja19nZXR0aW1lKENMT0NLX1BST0NFU1NfQ1BVVElNRV9JRCwgJm1QU3RhcnQpOworICAgIGNsb2NrX2dldHRpbWUoQ0xPQ0tfVEhSRUFEX0NQVVRJTUVfSUQsICZtVFN0YXJ0KTsKK30KKwordm9pZCBUaW1lclByb2JlOjplbmQoKQoreworICAgIHRpbWVzcGVjIHJlYWxFbmQsIHBFbmQsIHRFbmQ7CisgICAgY2xvY2tfZ2V0dGltZShDTE9DS19SRUFMVElNRSwgJnJlYWxFbmQpOworICAgIGNsb2NrX2dldHRpbWUoQ0xPQ0tfUFJPQ0VTU19DUFVUSU1FX0lELCAmcEVuZCk7CisgICAgY2xvY2tfZ2V0dGltZShDTE9DS19USFJFQURfQ1BVVElNRV9JRCwgJnRFbmQpOworICAgIHByaW50KHJlYWxFbmQsIHBFbmQsIHRFbmQpOworICAgIG1UYWcgPSBOVUxMOworfQorCitUaW1lclByb2JlOjp+VGltZXJQcm9iZSgpCit7CisgICAgaWYgKG1UYWcgIT0gTlVMTCkKKyAgICAgICAgZW5kKCk7CisgICAgZ0V4ZWN1dGVDaGFpbiA9IG1OZXh0OworICAgIGdJbmRlbnQtLTsKK30KKworCit1aW50MzJfdCBUaW1lclByb2JlOjpFbGFwc2VkVGltZShjb25zdCB0aW1lc3BlYyYgc3RhcnQsIGNvbnN0IHRpbWVzcGVjJiBlbmQpCit7CisgICAgaW50IHNlYyA9IGVuZC50dl9zZWMgLSBzdGFydC50dl9zZWM7CisgICAgaW50IG5zZWMgPSBlbmQudHZfbnNlYyAtIHN0YXJ0LnR2X25zZWM7CisgICAgaWYgKG5zZWMgPCAwKSB7CisgICAgICAgIHNlYy0tOworICAgICAgICBuc2VjICs9IDEwMDAwMDAwMDA7CisgICAgfQorICAgIHJldHVybiBzZWMgKiAxMDAwMDAwICsgbnNlYyAvIDEwMDA7Cit9CisKK3ZvaWQgVGltZXJQcm9iZTo6cHJpbnQoY29uc3QgdGltZXNwZWMmIHIsIGNvbnN0IHRpbWVzcGVjJiBwLAorICAgICAgICBjb25zdCB0aW1lc3BlYyYgdCkgY29uc3QKK3sKKyAgICB1aW50MzJfdCBlcyA9IEVsYXBzZWRUaW1lKGdSZWFsQmFzZSwgbVJlYWxTdGFydCk7CisgICAgdWludDMyX3QgZXIgPSBFbGFwc2VkVGltZShtUmVhbFN0YXJ0LCByKTsKKyAgICB1aW50MzJfdCBlcCA9IEVsYXBzZWRUaW1lKG1QU3RhcnQsIHApOworICAgIHVpbnQzMl90IGV0ID0gRWxhcHNlZFRpbWUobVRTdGFydCwgdCk7CisgICAgaWYgKG1JbmRlbnQgPiAwKSB7CisgICAgICAgIEJ1Y2tldCYgYnVja2V0ID0gZ0J1Y2tldHMuZWRpdEl0ZW1BdChtQnVja2V0KTsKKyAgICAgICAgaWYgKGJ1Y2tldC5tU3RhcnQgPT0gMCkKKyAgICAgICAgICAgIGJ1Y2tldC5tU3RhcnQgPSBlczsKKyAgICAgICAgYnVja2V0Lm1SZWFsICs9IGVyOworICAgICAgICBidWNrZXQubVByb2Nlc3MgKz0gZXA7CisgICAgICAgIGJ1Y2tldC5tVGhyZWFkICs9IGV0OworICAgICAgICBidWNrZXQubUNvdW50Kys7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW50IGluZGV4ID0gMDsKKyAgICBpbnQgYnVja2V0cyA9IGdCdWNrZXRzLnNpemUoKTsKKyAgICBpbnQgY291bnQgPSAxOworICAgIGNvbnN0IGNoYXIqIHRhZyA9IG1UYWc7CisgICAgaW50IGluZGVudCA9IG1JbmRlbnQ7CisgICAgZG8geworICAgICAgICBMT0dEKCIlLTMwLjMwczogKCUzZCkgJS01LipzIHRpbWU9JS0xMC4zZiByZWFsPSU3ZHVzIHByb2Nlc3M9JTdkdXMgKCUzZCUlKSB0aHJlYWQ9JTdkdXMgKCUzZCUlKVxuIiwgCisgICAgICAgICAgICB0YWcsIGNvdW50LCBpbmRlbnQgPiA1ID8gNSA6IGluZGVudCwgIisrKysrIiwgZXMgLyAxMDAwMDAwLjAsCisgICAgICAgICAgICBlciwgZXAsIGVwICogMTAwIC8gZXIsIGV0LCBldCAqIDEwMCAvIGVyKTsKKyAgICAgICAgaWYgKGluZGV4ID49IGJ1Y2tldHMpCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgQnVja2V0JiBidWNrZXQgPSBnQnVja2V0cy5lZGl0SXRlbUF0KGluZGV4KTsKKyAgICAgICAgY291bnQgPSBidWNrZXQubUNvdW50OworICAgICAgICBlcyA9IGJ1Y2tldC5tU3RhcnQ7CisgICAgICAgIGVyID0gYnVja2V0Lm1SZWFsOworICAgICAgICBlcCA9IGJ1Y2tldC5tUHJvY2VzczsKKyAgICAgICAgZXQgPSBidWNrZXQubVRocmVhZDsKKyAgICAgICAgdGFnID0gYnVja2V0Lm1UYWc7CisgICAgICAgIGluZGVudCA9IGJ1Y2tldC5tSW5kZW50OworICAgICAgICAqYnVja2V0Lm1TbG90UHRyID0gMDsKKyAgICB9IHdoaWxlICgrK2luZGV4KTsgLy8gYWx3YXlzIHRydWUKKyAgICBnQnVja2V0cy5jbGVhcigpOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvVGltZXJzLmNwcCBiL2xpYnMvdXRpbHMvVGltZXJzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYWJjODExCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9UaW1lcnMuY3BwCkBAIC0wLDAgKzEsMjQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIFRpbWVyIGZ1bmN0aW9ucy4KKy8vCisjaW5jbHVkZSA8dXRpbHMvVGltZXJzLmg+CisjaW5jbHVkZSA8dXRpbHMvcG9ydGVkLmg+ICAgICAvLyBtYXkgbmVlZCB1c2xlZXAKKyNpbmNsdWRlIDx1dGlscy9Mb2cuaD4KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKyNpbmNsdWRlIDx0aW1lLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKworI2lmZGVmIEhBVkVfV0lOMzJfVEhSRUFEUworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCituc2Vjc190IHN5c3RlbVRpbWUoaW50IGNsb2NrKQoreworI2lmIGRlZmluZWQoSEFWRV9QT1NJWF9DTE9DS1MpCisgICAgc3RhdGljIGNvbnN0IGNsb2NraWRfdCBjbG9ja3NbXSA9IHsKKyAgICAgICAgICAgIENMT0NLX1JFQUxUSU1FLAorICAgICAgICAgICAgQ0xPQ0tfTU9OT1RPTklDLAorICAgICAgICAgICAgQ0xPQ0tfUFJPQ0VTU19DUFVUSU1FX0lELAorICAgICAgICAgICAgQ0xPQ0tfVEhSRUFEX0NQVVRJTUVfSUQKKyAgICB9OworICAgIHN0cnVjdCB0aW1lc3BlYyB0OworICAgIHQudHZfc2VjID0gdC50dl9uc2VjID0gMDsKKyAgICBjbG9ja19nZXR0aW1lKGNsb2Nrc1tjbG9ja10sICZ0KTsKKyAgICByZXR1cm4gbnNlY3NfdCh0LnR2X3NlYykqMTAwMDAwMDAwMExMICsgdC50dl9uc2VjOworI2Vsc2UKKyAgICAvLyB3ZSBkb24ndCBzdXBwb3J0IHRoZSBjbG9ja3MgaGVyZS4KKyAgICBzdHJ1Y3QgdGltZXZhbCB0OworICAgIHQudHZfc2VjID0gdC50dl91c2VjID0gMDsKKyAgICBnZXR0aW1lb2ZkYXkoJnQsIE5VTEwpOworICAgIHJldHVybiBuc2Vjc190KHQudHZfc2VjKSoxMDAwMDAwMDAwTEwgKyBuc2Vjc190KHQudHZfdXNlYykqMTAwMExMOworI2VuZGlmCit9CisKKy8vI2RlZmluZSBNT05JVE9SX1VTTEVFUAorCisvKgorICogU2xlZXAgbG9uZyBlbm91Z2ggdGhhdCB3ZSdsbCB3YWtlIHVwICJpbnRlcnZhbCIgbWlsbGlzZWNvbmRzIGFmdGVyCisgKiB0aGUgcHJldmlvdXMgc25vb3plLgorICoKKyAqIFRoZSAibmV4dFRpY2siIGFyZ3VtZW50IGlzIHVwZGF0ZWQgb24gZWFjaCBjYWxsLCBhbmQgc2hvdWxkIGJlIHBhc3NlZAorICogaW4gZXZlcnkgdGltZS4gIFNldCBpdHMgZmllbGRzIHRvIHplcm8gb24gdGhlIGZpcnN0IGNhbGwuCisgKgorICogUmV0dXJucyB0aGUgI29mIGludGVydmFscyB3ZSBoYXZlIG92ZXJzbGVwdCwgd2hpY2ggd2lsbCBiZSB6ZXJvIGlmIHdlJ3JlCisgKiBvbiB0aW1lLiAgW0N1cnJlbnRseSBqdXN0IHJldHVybnMgMCBvciAxLl0KKyAqLworaW50IHNsZWVwRm9ySW50ZXJ2YWwobG9uZyBpbnRlcnZhbCwgc3RydWN0IHRpbWV2YWwqIHBOZXh0VGljaykKK3sKKyAgICBzdHJ1Y3QgdGltZXZhbCBub3c7CisgICAgbG9uZyBsb25nIHRpbWVCZWZvcmVOZXh0OworICAgIGxvbmcgc2xlZXBUaW1lID0gMDsKKyAgICBib29sIG92ZXJTbGVwdCA9IGZhbHNlOworICAgIC8vaW50IHVzbGVlcEJpYXMgPSAwOworCisjaWZkZWYgVVNMRUVQX0JJQVMKKyAgICAvKgorICAgICAqIExpbnV4IGxpa2VzIHRvIGFkZCA5MDAwbXMgb3Igc28uCisgICAgICogW25vdCB1c2luZyB0aGlzIGZvciBub3ddCisgICAgICovCisgICAgLy91c2xlZXBCaWFzID0gVVNMRUVQX0JJQVM7CisjZW5kaWYKKworICAgIGdldHRpbWVvZmRheSgmbm93LCBOVUxMKTsKKworICAgIGlmIChwTmV4dFRpY2stPnR2X3NlYyA9PSAwKSB7CisgICAgICAgIC8qIHNwZWNpYWwtY2FzZSBmb3IgZmlyc3QgdGltZSB0aHJvdWdoICovCisgICAgICAgICpwTmV4dFRpY2sgPSBub3c7CisgICAgICAgIHNsZWVwVGltZSA9IGludGVydmFsOworICAgICAgICBhbmRyb2lkOjpEdXJhdGlvblRpbWVyOjphZGRUb1RpbWV2YWwocE5leHRUaWNrLCBpbnRlcnZhbCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogQ29tcHV0ZSBob3cgbXVjaCB0aW1lIHRoZXJlIGlzIGJlZm9yZSB0aGUgbmV4dCB0aWNrLiAgSWYgdGhpcworICAgICAgICAgKiB2YWx1ZSBpcyBuZWdhdGl2ZSwgd2UndmUgcnVuIG92ZXIuICBJZiB3ZSd2ZSBydW4gb3ZlciBhIGxpdHRsZQorICAgICAgICAgKiBiaXQgd2UgY2FuIHNob3J0ZW4gdGhlIG5leHQgZnJhbWUgdG8ga2VlcCB0aGUgcGFjZSBzdGVhZHksIGJ1dAorICAgICAgICAgKiBpZiB3ZSd2ZSBkcmFtYXRpY2FsbHkgb3ZlcnNob3Qgd2UgbmVlZCB0byByZS1zeW5jLgorICAgICAgICAgKi8KKyAgICAgICAgdGltZUJlZm9yZU5leHQgPSBhbmRyb2lkOjpEdXJhdGlvblRpbWVyOjpzdWJ0cmFjdFRpbWV2YWxzKHBOZXh0VGljaywgJm5vdyk7CisgICAgICAgIC8vcHJpbnRmKCJUT1A6IG5vdz0lbGQuJWxkIG5leHQ9JWxkLiVsZCBkaWZmPSVsZFxuIiwKKyAgICAgICAgLy8gICAgbm93LnR2X3NlYywgbm93LnR2X3VzZWMsIHBOZXh0VGljay0+dHZfc2VjLCBwTmV4dFRpY2stPnR2X3VzZWMsCisgICAgICAgIC8vICAgIChsb25nKSB0aW1lQmVmb3JlTmV4dCk7CisgICAgICAgIGlmICh0aW1lQmVmb3JlTmV4dCA8IC1pbnRlcnZhbCkgeworICAgICAgICAgICAgLyogd2F5IG92ZXIgKi8KKyAgICAgICAgICAgIG92ZXJTbGVwdCA9IHRydWU7CisgICAgICAgICAgICBzbGVlcFRpbWUgPSAwOworICAgICAgICAgICAgKnBOZXh0VGljayA9IG5vdzsKKyAgICAgICAgfSBlbHNlIGlmICh0aW1lQmVmb3JlTmV4dCA8PSAwKSB7CisgICAgICAgICAgICAvKiBzbGlnaHRseSBvdmVyLCBrZWVwIHRoZSBwYWNlIHN0ZWFkeSAqLworICAgICAgICAgICAgb3ZlclNsZXB0ID0gdHJ1ZTsKKyAgICAgICAgICAgIHNsZWVwVGltZSA9IDA7CisgICAgICAgIH0gZWxzZSBpZiAodGltZUJlZm9yZU5leHQgPD0gaW50ZXJ2YWwpIHsKKyAgICAgICAgICAgIC8qIHJpZ2h0IG9uIHNjaGVkdWxlICovCisgICAgICAgICAgICBzbGVlcFRpbWUgPSB0aW1lQmVmb3JlTmV4dDsKKyAgICAgICAgfSBlbHNlIGlmICh0aW1lQmVmb3JlTmV4dCA+IGludGVydmFsICYmIHRpbWVCZWZvcmVOZXh0IDw9IDIqaW50ZXJ2YWwpIHsKKyAgICAgICAgICAgIC8qIHNsZWVwIGNhbGwgcmV0dXJuZWQgZWFybHk7IGRvIGEgbG9uZ2VyIHNsZWVwIHRoaXMgdGltZSAqLworICAgICAgICAgICAgc2xlZXBUaW1lID0gdGltZUJlZm9yZU5leHQ7CisgICAgICAgIH0gZWxzZSBpZiAodGltZUJlZm9yZU5leHQgPiBpbnRlcnZhbCkgeworICAgICAgICAgICAgLyogd2Ugd2VudCBiYWNrIGluIHRpbWUgLS0gc29tZWJvZHkgdXBkYXRlZCBzeXN0ZW0gY2xvY2s/ICovCisgICAgICAgICAgICAvKiAoY291bGQgYWxzbyBiZSBhICpzZXJpb3VzbHkqIGJyb2tlbiB1c2xlZXAoKSkgKi8KKyAgICAgICAgICAgIExPRyhMT0dfREVCVUcsICIiLAorICAgICAgICAgICAgICAgICIgSW1wb3NzaWJsZTogdGltZUJlZm9yZU5leHQgPSAlbGRcbiIsIChsb25nKXRpbWVCZWZvcmVOZXh0KTsKKyAgICAgICAgICAgIHNsZWVwVGltZSA9IDA7CisgICAgICAgICAgICAqcE5leHRUaWNrID0gbm93OworICAgICAgICB9CisgICAgICAgIGFuZHJvaWQ6OkR1cmF0aW9uVGltZXI6OmFkZFRvVGltZXZhbChwTmV4dFRpY2ssIGludGVydmFsKTsKKyAgICB9CisgICAgLy9wcmludGYoIiBCZWZvcmUgc2xlZXA6IG5vdz0lbGQuJWxkIG5leHQ9JWxkLiVsZCBzbGVlcFRpbWU9JWxkXG4iLAorICAgIC8vICAgIG5vdy50dl9zZWMsIG5vdy50dl91c2VjLCBwTmV4dFRpY2stPnR2X3NlYywgcE5leHRUaWNrLT50dl91c2VjLAorICAgIC8vICAgIHNsZWVwVGltZSk7CisKKyAgICAvKgorICAgICAqIFNsZWVwIGZvciB0aGUgZGVzaWduYXRlZCBwZXJpb2Qgb2YgdGltZS4KKyAgICAgKgorICAgICAqIExpbnV4IHRlbmRzIHRvIHNsZWVwIGZvciBsb25nZXIgdGhhbiByZXF1ZXN0ZWQsIG9mdGVuIGJ5IDE3LTE4bXMuCisgICAgICogTWluR1cgdGVuZHMgdG8gc2xlZXAgZm9yIGxlc3MgdGhhbiByZXF1ZXN0ZWQsIGJ5IGFzIG11Y2ggYXMgMTRtcywKKyAgICAgKiBidXQgb2NjYXNpb25hbGx5IG92ZXJzbGVlcHMgZm9yIDQwK21zIChsb29rcyBsaWtlIHNvbWUgZXh0ZXJuYWwKKyAgICAgKiBmYWN0b3JzIHBsdXMgcm91bmQtb2ZmIG9uIGEgNjRIeiBjbG9jaykuICBDeWd3aW4gaXMgcHJldHR5IHN0ZWFkeS4KKyAgICAgKgorICAgICAqIElmIHlvdSBzdGFydCB0aGUgTWluR1cgdmVyc2lvbiwgYW5kIHRoZW4gbGF1bmNoIHRoZSBDeWd3aW4gdmVyc2lvbiwKKyAgICAgKiB0aGUgTWluR1cgY2xvY2sgYmVjb21lcyBtb3JlIGVycmF0aWMuICBOb3QgZW50aXJlbHkgc3VyZSB3aHkuCisgICAgICoKKyAgICAgKiAoVGhlcmUncyBhIGxvdCBvZiBzdHVmZiBoZXJlOyBpdCdzIHJlYWxseSBqdXN0IGEgdXNsZWVwKCkgY2FsbCB3aXRoCisgICAgICogYSBidW5jaCBvZiBpbnN0cnVtZW50YXRpb24uKQorICAgICAqLworICAgIGlmIChzbGVlcFRpbWUgPiAwKSB7CisjaWYgZGVmaW5lZChNT05JVE9SX1VTTEVFUCkKKyAgICAgICAgc3RydWN0IHRpbWV2YWwgYmVmb3JlLCBhZnRlcjsKKyAgICAgICAgbG9uZyBsb25nIGFjdHVhbDsKKworICAgICAgICBnZXR0aW1lb2ZkYXkoJmJlZm9yZSwgTlVMTCk7CisgICAgICAgIHVzbGVlcCgobG9uZykgc2xlZXBUaW1lKTsKKyAgICAgICAgZ2V0dGltZW9mZGF5KCZhZnRlciwgTlVMTCk7CisKKyAgICAgICAgLyogY2hlY2sgdXNsZWVwKCkgYWNjdXJhY3k7IGRlZmF1bHQgTGludXggdGhyZWFkcyBhcmUgcHJldHR5IHNsb3BweSAqLworICAgICAgICBhY3R1YWwgPSBhbmRyb2lkOjpEdXJhdGlvblRpbWVyOjpzdWJ0cmFjdFRpbWV2YWxzKCZhZnRlciwgJmJlZm9yZSk7CisgICAgICAgIGlmICgobG9uZykgYWN0dWFsIDwgc2xlZXBUaW1lIC0gMTQwMDAgLyooc2xlZXBUaW1lLzEwKSovIHx8CisgICAgICAgICAgICAobG9uZykgYWN0dWFsID4gc2xlZXBUaW1lICsgMjAwMDAgLyooc2xlZXBUaW1lLzEwKSovKQorICAgICAgICB7CisgICAgICAgICAgICBMT0coTE9HX0RFQlVHLCAiIiwgIiBPZGQgdXNsZWVwOiByZXE9JWxkLCBhY3R1YWw9JWxkXG4iLCBzbGVlcFRpbWUsCisgICAgICAgICAgICAgICAgKGxvbmcpIGFjdHVhbCk7CisgICAgICAgIH0KKyNlbHNlCisjaWZkZWYgSEFWRV9XSU4zMl9USFJFQURTCisgICAgICAgIFNsZWVwKCBzbGVlcFRpbWUvMTAwMCApOworI2Vsc2UgICAgICAgIAorICAgICAgICB1c2xlZXAoKGxvbmcpIHNsZWVwVGltZSk7CisjZW5kaWYgICAgICAgIAorI2VuZGlmCisgICAgfQorCisgICAgLy9wcmludGYoInNsZXB0ICVkXG4iLCBzbGVlcFRpbWUpOworCisgICAgaWYgKG92ZXJTbGVwdCkKKyAgICAgICAgcmV0dXJuIDE7ICAgICAgIC8vIGNsb3NlIGVub3VnaAorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIDA7Cit9CisKKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBEdXJhdGlvblRpbWVyCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqLworCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworLy8gU3RhcnQgdGhlIHRpbWVyLgordm9pZCBEdXJhdGlvblRpbWVyOjpzdGFydCh2b2lkKQoreworICAgIGdldHRpbWVvZmRheSgmbVN0YXJ0V2hlbiwgTlVMTCk7Cit9CisKKy8vIFN0b3AgdGhlIHRpbWVyLgordm9pZCBEdXJhdGlvblRpbWVyOjpzdG9wKHZvaWQpCit7CisgICAgZ2V0dGltZW9mZGF5KCZtU3RvcFdoZW4sIE5VTEwpOworfQorCisvLyBHZXQgdGhlIGR1cmF0aW9uIGluIG1pY3Jvc2Vjb25kcy4KK2xvbmcgbG9uZyBEdXJhdGlvblRpbWVyOjpkdXJhdGlvblVzZWNzKHZvaWQpIGNvbnN0Cit7CisgICAgcmV0dXJuIChsb25nKSBzdWJ0cmFjdFRpbWV2YWxzKCZtU3RvcFdoZW4sICZtU3RhcnRXaGVuKTsKK30KKworLy8gU3VidHJhY3QgdHdvIHRpbWV2YWxzLiAgUmV0dXJucyB0aGUgZGlmZmVyZW5jZSAocHR2MS1wdHYyKSBpbgorLy8gbWljcm9zZWNvbmRzLgorLypzdGF0aWMqLyBsb25nIGxvbmcgRHVyYXRpb25UaW1lcjo6c3VidHJhY3RUaW1ldmFscyhjb25zdCBzdHJ1Y3QgdGltZXZhbCogcHR2MSwKKyAgICBjb25zdCBzdHJ1Y3QgdGltZXZhbCogcHR2MikKK3sKKyAgICBsb25nIGxvbmcgc3RvcCAgPSAoKGxvbmcgbG9uZykgcHR2MS0+dHZfc2VjKSAqIDEwMDAwMDBMTCArCisgICAgICAgICAgICAgICAgICAgICAgKChsb25nIGxvbmcpIHB0djEtPnR2X3VzZWMpOworICAgIGxvbmcgbG9uZyBzdGFydCA9ICgobG9uZyBsb25nKSBwdHYyLT50dl9zZWMpICogMTAwMDAwMExMICsKKyAgICAgICAgICAgICAgICAgICAgICAoKGxvbmcgbG9uZykgcHR2Mi0+dHZfdXNlYyk7CisgICAgcmV0dXJuIHN0b3AgLSBzdGFydDsKK30KKworLy8gQWRkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWUgdG8gdGhlIHRpbWV2YWwuCisvKnN0YXRpYyovIHZvaWQgRHVyYXRpb25UaW1lcjo6YWRkVG9UaW1ldmFsKHN0cnVjdCB0aW1ldmFsKiBwdHYsIGxvbmcgdXNlYykKK3sKKyAgICBpZiAodXNlYyA8IDApIHsKKyAgICAgICAgTE9HKExPR19XQVJOLCAiIiwgIk5lZ2F0aXZlIHZhbHVlcyBub3Qgc3VwcG9ydGVkIGluIGFkZFRvVGltZXZhbFxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBub3JtYWxpemUgdHZfdXNlYyBpZiBuZWNlc3NhcnkKKyAgICBpZiAocHR2LT50dl91c2VjID49IDEwMDAwMDApIHsKKyAgICAgICAgcHR2LT50dl9zZWMgKz0gcHR2LT50dl91c2VjIC8gMTAwMDAwMDsKKyAgICAgICAgcHR2LT50dl91c2VjICU9IDEwMDAwMDA7CisgICAgfQorCisgICAgcHR2LT50dl91c2VjICs9IHVzZWMgJSAxMDAwMDAwOworICAgIGlmIChwdHYtPnR2X3VzZWMgPj0gMTAwMDAwMCkgeworICAgICAgICBwdHYtPnR2X3VzZWMgLT0gMTAwMDAwMDsKKyAgICAgICAgcHR2LT50dl9zZWMrKzsKKyAgICB9CisgICAgcHR2LT50dl9zZWMgKz0gdXNlYyAvIDEwMDAwMDA7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvVW5pY29kZS5jcHAgYi9saWJzL3V0aWxzL1VuaWNvZGUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzZjUzNWYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1VuaWNvZGUuY3BwCkBAIC0wLDAgKzEsMTkzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgInV0aWxzL0FuZHJvaWRVbmljb2RlLmgiCisjaW5jbHVkZSAiY2hhcmFjdGVyRGF0YS5oIgorCisjZGVmaW5lIExPR19UQUcgIlVuaWNvZGUiCisjaW5jbHVkZSAidXRpbHMvTG9nLmgiCisKKy8vIElDVSBoZWFkZXJzIGZvciB1c2luZyBtYWNyb3MKKyNpbmNsdWRlIDx1bmljb2RlL3V0ZjE2Lmg+CisKKyNkZWZpbmUgTUlOX1JBRElYIDIKKyNkZWZpbmUgTUFYX1JBRElYIDM2CisKKyNkZWZpbmUgVFlQRV9TSElGVCAwCisjZGVmaW5lIFRZUEVfTUFTSyAoKDE8PDUpLTEpCisKKyNkZWZpbmUgRElSRUNUSU9OX1NISUZUIChUWVBFX1NISUZUKzUpCisjZGVmaW5lIERJUkVDVElPTl9NQVNLICgoMTw8NSktMSkKKworI2RlZmluZSBNSVJST1JFRF9TSElGVCAoRElSRUNUSU9OX1NISUZUKzUpCisjZGVmaW5lIE1JUlJPUkVEX01BU0sgKCgxPDwxKS0xKQorCisjZGVmaW5lIFRPVVBQRVJfU0hJRlQgKE1JUlJPUkVEX1NISUZUKzEpCisjZGVmaW5lIFRPVVBQRVJfTUFTSyAoKDE8PDYpLTEpCisKKyNkZWZpbmUgVE9MT1dFUl9TSElGVCAoVE9VUFBFUl9TSElGVCs2KQorI2RlZmluZSBUT0xPV0VSX01BU0sgKCgxPDw2KS0xKQorCisjZGVmaW5lIFRPVElUTEVfU0hJRlQgKFRPTE9XRVJfU0hJRlQrNikKKyNkZWZpbmUgVE9USVRMRV9NQVNLICgoMTw8MiktMSkKKworI2RlZmluZSBNSVJST1JfU0hJRlQgKFRPVElUTEVfU0hJRlQrMikKKyNkZWZpbmUgTUlSUk9SX01BU0sgKCgxPDw1KS0xKQorCisjZGVmaW5lIE5VTUVSSUNfU0hJRlQgKFRPVElUTEVfU0hJRlQrMikKKyNkZWZpbmUgTlVNRVJJQ19NQVNLICgoMTw8NyktMSkKKworI2RlZmluZSBERUNPTVBPU0lUSU9OX1NISUZUICgxMSkKKyNkZWZpbmUgREVDT01QT1NJVElPTl9NQVNLICgoMTw8NSktMSkKKworLyoKKyAqIFJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBpbiB0aGUgQ2hhcmFjdGVyRGF0YSB0YWJsZXMgdGhhdCBjb250YWlucworICogYW4gaW5kZXggaW50byB0aGUgcGFja2VkIGRhdGEgdGFibGUgYW5kIHRoZSBkZWNvbXBvc2l0aW9uIHR5cGUuCisgKi8KK3N0YXRpYyB1aW50MTZfdCBmaW5kQ2hhcmFjdGVyVmFsdWUoVUNoYXIzMiBjKQoreworICAgIExPR19BU1NFUlQoYyA+PSAwICYmIGMgPD0gMHgxMEZGRkYsICJmaW5kQ2hhcmFjdGVyVmFsdWUgcmVjZWl2ZWQgYW4gaW52YWxpZCBjb2RlcG9pbnQiKTsKKyAgICBpZiAoYyA8IDI1NikKKyAgICAgICAgcmV0dXJuIENoYXJhY3RlckRhdGE6OkxBVElOMV9EQVRBW2NdOworCisgICAgLy8gUm90YXRlIHRoZSBiaXRzIGJlY2F1c2UgdGhlIHRhYmxlcyBhcmUgc2VwYXJhdGVkIGludG8gZXZlbiBhbmQgb2RkIGNvZGVwb2ludHMKKyAgICBjID0gKGMgPj4gMSkgfCAoKGMgJiAxKSA8PCAyMCk7CisKKyAgICBDaGFyYWN0ZXJEYXRhOjpSYW5nZSBzZWFyY2ggPSBDaGFyYWN0ZXJEYXRhOjpGVUxMX0RBVEFbYyA+PiAxNl07CisgICAgY29uc3QgdWludDMyX3QqIGFycmF5ID0gc2VhcmNoLmFycmF5OworIAorICAgIC8vIFRoaXMgdHJpY2sgaXMgc28gdGhhdCB0aGF0IGNvbXBhcmUgaW4gdGhlIHdoaWxlIGxvb3AgZG9lcyBub3QKKyAgICAvLyBuZWVkIHRvIHNoaWZ0IHRoZSBhcnJheSBlbnRyeSBkb3duIGJ5IDE2CisgICAgYyA8PD0gMTY7CisgICAgYyB8PSAweEZGRkY7CisKKyAgICBpbnQgaGlnaCA9IChpbnQpc2VhcmNoLmxlbmd0aCAtIDE7CisgICAgaW50IGxvdyA9IDA7CisKKyAgICBpZiAoaGlnaCA8IDApCisgICAgICAgIHJldHVybiAwOworICAgIAorICAgIHdoaWxlIChsb3cgPCBoaWdoIC0gMSkKKyAgICB7CisgICAgICAgIGludCBwcm9iZSA9IChoaWdoICsgbG93KSA+PiAxOworCisgICAgICAgIC8vIFRoZSBlbnRyaWVzIGNvbnRhaW4gdGhlIGNvZGVwb2ludCBpbiB0aGUgaGlnaCAxNiBiaXRzIGFuZCB0aGUgaW5kZXgKKyAgICAgICAgLy8gaW50byBQQUNLRURfREFUQSBpbiB0aGUgbG93IDE2LgorICAgICAgICBpZiAoYXJyYXlbcHJvYmVdID4gKHVuc2lnbmVkKWMpCisgICAgICAgICAgICBoaWdoID0gcHJvYmU7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGxvdyA9IHByb2JlOworICAgIH0KKworICAgIExPR19BU1NFUlQoKGFycmF5W2xvd10gPD0gKHVuc2lnbmVkKWMpLCAiQSBzdWl0YWJsZSByYW5nZSB3YXMgbm90IGZvdW5kIik7CisgICAgcmV0dXJuIGFycmF5W2xvd10gJiAweEZGRkY7Cit9CisKK3VpbnQzMl90IGFuZHJvaWQ6OlVuaWNvZGU6OmdldFBhY2tlZERhdGEoVUNoYXIzMiBjKQoreworICAgIC8vIGZpbmRDaGFyYWN0ZXJWYWx1ZSByZXR1cm5zIGEgMTYtYml0IHZhbHVlIHdpdGggdGhlIHRvcCA1IGJpdHMgY29udGFpbmluZyBhIGRlY29tcG9zaXRpb24gdHlwZQorICAgIC8vIGFuZCB0aGUgcmVtYWluaW5nIGJpdHMgY29udGFpbmluZyBhbiBpbmRleC4KKyAgICByZXR1cm4gQ2hhcmFjdGVyRGF0YTo6UEFDS0VEX0RBVEFbZmluZENoYXJhY3RlclZhbHVlKGMpICYgMHg3RkZdOworfQorCithbmRyb2lkOjpVbmljb2RlOjpDaGFyVHlwZSBhbmRyb2lkOjpVbmljb2RlOjpnZXRUeXBlKFVDaGFyMzIgYykKK3sKKyAgICBpZiAoYyA8IDAgfHwgYyA+PSAweDEwRkZGRikKKyAgICAgICAgcmV0dXJuIENIQVJUWVBFX1VOQVNTSUdORUQ7CisgICAgcmV0dXJuIChDaGFyVHlwZSkoKGdldFBhY2tlZERhdGEoYykgPj4gVFlQRV9TSElGVCkgJiBUWVBFX01BU0spOworfQorCithbmRyb2lkOjpVbmljb2RlOjpEZWNvbXBvc2l0aW9uVHlwZSBhbmRyb2lkOjpVbmljb2RlOjpnZXREZWNvbXBvc2l0aW9uVHlwZShVQ2hhcjMyIGMpCit7CisgICAgLy8gZmluZENoYXJhY3RlclZhbHVlIHJldHVybnMgYSAxNi1iaXQgdmFsdWUgd2l0aCB0aGUgdG9wIDUgYml0cyBjb250YWluaW5nIGEgZGVjb21wb3NpdGlvbiB0eXBlCisgICAgLy8gYW5kIHRoZSByZW1haW5pbmcgYml0cyBjb250YWluaW5nIGFuIGluZGV4LgorICAgIHJldHVybiAoRGVjb21wb3NpdGlvblR5cGUpKChmaW5kQ2hhcmFjdGVyVmFsdWUoYykgPj4gREVDT01QT1NJVElPTl9TSElGVCkgJiBERUNPTVBPU0lUSU9OX01BU0spOworfQorCitpbnQgYW5kcm9pZDo6VW5pY29kZTo6Z2V0RGlnaXRWYWx1ZShVQ2hhcjMyIGMsIGludCByYWRpeCkKK3sKKyAgICBpZiAocmFkaXggPCBNSU5fUkFESVggfHwgcmFkaXggPiBNQVhfUkFESVgpCisgICAgICAgIHJldHVybiAtMTsKKworICAgIGludCB0ZW1wVmFsdWUgPSByYWRpeDsKKyAgICAKKyAgICBpZiAoYyA+PSAnMCcgJiYgYyA8PSAnOScpCisgICAgICAgIHRlbXBWYWx1ZSA9IGMgLSAnMCc7CisgICAgZWxzZSBpZiAoYyA+PSAnYScgJiYgYyA8PSAneicpCisgICAgICAgIHRlbXBWYWx1ZSA9IGMgLSAnYScgKyAxMDsKKyAgICBlbHNlIGlmIChjID49ICdBJyAmJiBjIDw9ICdaJykKKyAgICAgICAgdGVtcFZhbHVlID0gYyAtICdBJyArIDEwOworICAgIAorICAgIHJldHVybiB0ZW1wVmFsdWUgPCByYWRpeCA/IHRlbXBWYWx1ZSA6IC0xOworfQorCitpbnQgYW5kcm9pZDo6VW5pY29kZTo6Z2V0TnVtZXJpY1ZhbHVlKFVDaGFyMzIgYykKK3sKKyAgICBpZiAoaXNNaXJyb3JlZChjKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIAorICAgIHJldHVybiAoaW50KSBDaGFyYWN0ZXJEYXRhOjpOVU1FUklDU1soKGdldFBhY2tlZERhdGEoYykgPj4gTlVNRVJJQ19TSElGVCkgJiBOVU1FUklDX01BU0spXTsKK30KKworVUNoYXIzMiBhbmRyb2lkOjpVbmljb2RlOjp0b0xvd2VyKFVDaGFyMzIgYykKK3sKKyAgICByZXR1cm4gYyArIENoYXJhY3RlckRhdGE6OkxDRElGRlsoZ2V0UGFja2VkRGF0YShjKSA+PiBUT0xPV0VSX1NISUZUKSAmIFRPTE9XRVJfTUFTS107Cit9CisKK1VDaGFyMzIgYW5kcm9pZDo6VW5pY29kZTo6dG9VcHBlcihVQ2hhcjMyIGMpCit7CisgICAgcmV0dXJuIGMgKyBDaGFyYWN0ZXJEYXRhOjpVQ0RJRkZbKGdldFBhY2tlZERhdGEoYykgPj4gVE9VUFBFUl9TSElGVCkgJiBUT1VQUEVSX01BU0tdOworfQorCithbmRyb2lkOjpVbmljb2RlOjpEaXJlY3Rpb24gYW5kcm9pZDo6VW5pY29kZTo6Z2V0RGlyZWN0aW9uYWxpdHkoVUNoYXIzMiBjKQoreworICAgIHVpbnQzMl90IGRhdGEgPSBnZXRQYWNrZWREYXRhKGMpOworCisgICAgaWYgKDAgPT0gZGF0YSkKKyAgICAgICAgcmV0dXJuIERJUkVDVElPTkFMSVRZX1VOREVGSU5FRDsKKworICAgIERpcmVjdGlvbiBkID0gKERpcmVjdGlvbikgKChkYXRhID4+IERJUkVDVElPTl9TSElGVCkgJiBESVJFQ1RJT05fTUFTSyk7CisKKyAgICBpZiAoRElSRUNUSU9OX01BU0sgPT0gZCkKKyAgICAgICAgcmV0dXJuIERJUkVDVElPTkFMSVRZX1VOREVGSU5FRDsKKyAgICAKKyAgICByZXR1cm4gZDsKK30KKworYm9vbCBhbmRyb2lkOjpVbmljb2RlOjppc01pcnJvcmVkKFVDaGFyMzIgYykKK3sKKyAgICByZXR1cm4gKChnZXRQYWNrZWREYXRhKGMpID4+IE1JUlJPUkVEX1NISUZUKSAmIE1JUlJPUkVEX01BU0spICE9IDA7Cit9CisKK1VDaGFyMzIgYW5kcm9pZDo6VW5pY29kZTo6dG9NaXJyb3IoVUNoYXIzMiBjKQoreworICAgIGlmICghaXNNaXJyb3JlZChjKSkKKyAgICAgICAgcmV0dXJuIGM7CisKKyAgICByZXR1cm4gYyArIENoYXJhY3RlckRhdGE6Ok1JUlJPUl9ESUZGWyhnZXRQYWNrZWREYXRhKGMpID4+IE1JUlJPUl9TSElGVCkgJiBNSVJST1JfTUFTS107Cit9CisKK1VDaGFyMzIgYW5kcm9pZDo6VW5pY29kZTo6dG9UaXRsZShVQ2hhcjMyIGMpCit7CisgICAgaW50MzJfdCBkaWZmID0gQ2hhcmFjdGVyRGF0YTo6VENESUZGWyhnZXRQYWNrZWREYXRhKGMpID4+IFRPVElUTEVfU0hJRlQpICYgVE9USVRMRV9NQVNLXTsKKworICAgIGlmIChUT1RJVExFX01BU0sgPT0gZGlmZikKKyAgICAgICAgcmV0dXJuIHRvVXBwZXIoYyk7CisgICAgCisgICAgcmV0dXJuIGMgKyBkaWZmOworfQorCisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvVmVjdG9ySW1wbC5jcHAgYi9saWJzL3V0aWxzL1ZlY3RvckltcGwuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjMmQ2NjcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1ZlY3RvckltcGwuY3BwCkBAIC0wLDAgKzEsNjExIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJWZWN0b3IiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorCisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisjaW5jbHVkZSA8dXRpbHMvRXJyb3JzLmg+CisjaW5jbHVkZSA8dXRpbHMvU2hhcmVkQnVmZmVyLmg+CisjaW5jbHVkZSA8dXRpbHMvVmVjdG9ySW1wbC5oPgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NvbnN0IHNpemVfdCBrTWluVmVjdG9yQ2FwYWNpdHkgPSA0OworCitzdGF0aWMgaW5saW5lIHNpemVfdCBtYXgoc2l6ZV90IGEsIHNpemVfdCBiKSB7CisgICAgcmV0dXJuIGE+YiA/IGEgOiBiOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1ZlY3RvckltcGw6OlZlY3RvckltcGwoc2l6ZV90IGl0ZW1TaXplLCB1aW50MzJfdCBmbGFncykKKyAgICA6IG1TdG9yYWdlKDApLCBtQ291bnQoMCksIG1GbGFncyhmbGFncyksIG1JdGVtU2l6ZShpdGVtU2l6ZSkKK3sKK30KKworVmVjdG9ySW1wbDo6VmVjdG9ySW1wbChjb25zdCBWZWN0b3JJbXBsJiByaHMpCisgICAgOiAgIG1TdG9yYWdlKHJocy5tU3RvcmFnZSksIG1Db3VudChyaHMubUNvdW50KSwKKyAgICAgICAgbUZsYWdzKHJocy5tRmxhZ3MpLCBtSXRlbVNpemUocmhzLm1JdGVtU2l6ZSkKK3sKKyAgICBpZiAobVN0b3JhZ2UpIHsKKyAgICAgICAgU2hhcmVkQnVmZmVyOjpzaGFyZWRCdWZmZXIobVN0b3JhZ2UpLT5hY3F1aXJlKCk7CisgICAgfQorfQorCitWZWN0b3JJbXBsOjp+VmVjdG9ySW1wbCgpCit7CisgICAgTE9HX0FTU0VSVCghbUNvdW50LAorICAgICAgICAiWyVwXSAiCisgICAgICAgICJzdWJjbGFzc2VzIG9mIFZlY3RvckltcGwgbXVzdCBjYWxsIGZpbmlzaF92ZWN0b3IoKSIKKyAgICAgICAgIiBpbiB0aGVpciBkZXN0cnVjdG9yLiBMZWFraW5nICVkIGJ5dGVzLiIsCisgICAgICAgIHRoaXMsIChpbnQpKG1Db3VudCptSXRlbVNpemUpKTsKKyAgICAvLyBXZSBjYW4ndCBjYWxsIF9kb19kZXN0cm95KCkgaGVyZSBiZWNhdXNlIHRoZSB2dGFibGUgaXMgYWxyZWFkeSBnb25lLiAKK30KKworVmVjdG9ySW1wbCYgVmVjdG9ySW1wbDo6b3BlcmF0b3IgPSAoY29uc3QgVmVjdG9ySW1wbCYgcmhzKQoreworICAgIExPR19BU1NFUlQobUl0ZW1TaXplID09IHJocy5tSXRlbVNpemUsCisgICAgICAgICJWZWN0b3I8PiBoYXZlIGRpZmZlcmVudCB0eXBlcyAodGhpcz0lcCwgcmhzPSVwKSIsIHRoaXMsICZyaHMpOworICAgIGlmICh0aGlzICE9ICZyaHMpIHsKKyAgICAgICAgcmVsZWFzZV9zdG9yYWdlKCk7CisgICAgICAgIGlmIChyaHMubUNvdW50KSB7CisgICAgICAgICAgICBtU3RvcmFnZSA9IHJocy5tU3RvcmFnZTsKKyAgICAgICAgICAgIG1Db3VudCA9IHJocy5tQ291bnQ7CisgICAgICAgICAgICBTaGFyZWRCdWZmZXI6OnNoYXJlZEJ1ZmZlcihtU3RvcmFnZSktPmFjcXVpcmUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1TdG9yYWdlID0gMDsKKyAgICAgICAgICAgIG1Db3VudCA9IDA7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuICp0aGlzOworfQorCit2b2lkKiBWZWN0b3JJbXBsOjplZGl0QXJyYXlJbXBsKCkKK3sKKyAgICBpZiAobVN0b3JhZ2UpIHsKKyAgICAgICAgU2hhcmVkQnVmZmVyKiBzYiA9IFNoYXJlZEJ1ZmZlcjo6c2hhcmVkQnVmZmVyKG1TdG9yYWdlKS0+YXR0ZW1wdEVkaXQoKTsKKyAgICAgICAgaWYgKHNiID09IDApIHsKKyAgICAgICAgICAgIHNiID0gU2hhcmVkQnVmZmVyOjphbGxvYyhjYXBhY2l0eSgpICogbUl0ZW1TaXplKTsKKyAgICAgICAgICAgIGlmIChzYikgeworICAgICAgICAgICAgICAgIF9kb19jb3B5KHNiLT5kYXRhKCksIG1TdG9yYWdlLCBtQ291bnQpOworICAgICAgICAgICAgICAgIHJlbGVhc2Vfc3RvcmFnZSgpOworICAgICAgICAgICAgICAgIG1TdG9yYWdlID0gc2ItPmRhdGEoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbVN0b3JhZ2U7Cit9CisKK3NpemVfdCBWZWN0b3JJbXBsOjpjYXBhY2l0eSgpIGNvbnN0Cit7CisgICAgaWYgKG1TdG9yYWdlKSB7CisgICAgICAgIHJldHVybiBTaGFyZWRCdWZmZXI6OnNoYXJlZEJ1ZmZlcihtU3RvcmFnZSktPnNpemUoKSAvIG1JdGVtU2l6ZTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3NzaXplX3QgVmVjdG9ySW1wbDo6aW5zZXJ0VmVjdG9yQXQoY29uc3QgVmVjdG9ySW1wbCYgdmVjdG9yLCBzaXplX3QgaW5kZXgpCit7CisgICAgaWYgKGluZGV4ID4gc2l6ZSgpKQorICAgICAgICByZXR1cm4gQkFEX0lOREVYOworICAgIHZvaWQqIHdoZXJlID0gX2dyb3coaW5kZXgsIHZlY3Rvci5zaXplKCkpOworICAgIGlmICh3aGVyZSkgeworICAgICAgICBfZG9fY29weSh3aGVyZSwgdmVjdG9yLmFycmF5SW1wbCgpLCB2ZWN0b3Iuc2l6ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHdoZXJlID8gaW5kZXggOiAoc3NpemVfdClOT19NRU1PUlk7Cit9CisKK3NzaXplX3QgVmVjdG9ySW1wbDo6YXBwZW5kVmVjdG9yKGNvbnN0IFZlY3RvckltcGwmIHZlY3RvcikKK3sKKyAgICByZXR1cm4gaW5zZXJ0VmVjdG9yQXQodmVjdG9yLCBzaXplKCkpOworfQorCitzc2l6ZV90IFZlY3RvckltcGw6Omluc2VydEF0KHNpemVfdCBpbmRleCwgc2l6ZV90IG51bUl0ZW1zKQoreworICAgIHJldHVybiBpbnNlcnRBdCgwLCBpbmRleCwgbnVtSXRlbXMpOworfQorCitzc2l6ZV90IFZlY3RvckltcGw6Omluc2VydEF0KGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCBpbmRleCwgc2l6ZV90IG51bUl0ZW1zKQoreworICAgIGlmIChpbmRleCA+IHNpemUoKSkKKyAgICAgICAgcmV0dXJuIEJBRF9JTkRFWDsKKyAgICB2b2lkKiB3aGVyZSA9IF9ncm93KGluZGV4LCBudW1JdGVtcyk7CisgICAgaWYgKHdoZXJlKSB7CisgICAgICAgIGlmIChpdGVtKSB7CisgICAgICAgICAgICBfZG9fc3BsYXQod2hlcmUsIGl0ZW0sIG51bUl0ZW1zKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIF9kb19jb25zdHJ1Y3Qod2hlcmUsIG51bUl0ZW1zKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gd2hlcmUgPyBpbmRleCA6IChzc2l6ZV90KU5PX01FTU9SWTsKK30KKworc3RhdGljIGludCBzb3J0UHJveHkoY29uc3Qgdm9pZCogbGhzLCBjb25zdCB2b2lkKiByaHMsIHZvaWQqIGZ1bmMpCit7CisgICAgcmV0dXJuICgqKFZlY3RvckltcGw6OmNvbXBhcl90KWZ1bmMpKGxocywgcmhzKTsKK30KKworc3RhdHVzX3QgVmVjdG9ySW1wbDo6c29ydChWZWN0b3JJbXBsOjpjb21wYXJfdCBjbXApCit7CisgICAgcmV0dXJuIHNvcnQoc29ydFByb3h5LCAodm9pZCopY21wKTsKK30KKworc3RhdHVzX3QgVmVjdG9ySW1wbDo6c29ydChWZWN0b3JJbXBsOjpjb21wYXJfcl90IGNtcCwgdm9pZCogc3RhdGUpCit7CisgICAgLy8gdGhlIHNvcnQgbXVzdCBiZSBzdGFibGUuIHdlJ3JlIHVzaW5nIGluc2VydGlvbiBzb3J0IHdoaWNoCisgICAgLy8gaXMgd2VsbCBzdWl0ZWQgZm9yIHNtYWxsIGFuZCBhbHJlYWR5IHNvcnRlZCBhcnJheXMKKyAgICAvLyBmb3IgYmlnIGFycmF5cywgaXQgY291bGQgYmUgYmV0dGVyIHRvIHVzZSBtZXJnZXNvcnQKKyAgICBjb25zdCBzc2l6ZV90IGNvdW50ID0gc2l6ZSgpOworICAgIGlmIChjb3VudCA+IDEpIHsKKyAgICAgICAgdm9pZCogYXJyYXkgPSBjb25zdF9jYXN0PHZvaWQqPihhcnJheUltcGwoKSk7CisgICAgICAgIHZvaWQqIHRlbXAgPSAwOworICAgICAgICBzc2l6ZV90IGkgPSAxOworICAgICAgICB3aGlsZSAoaSA8IGNvdW50KSB7CisgICAgICAgICAgICB2b2lkKiBpdGVtID0gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oYXJyYXkpICsgbUl0ZW1TaXplKihpKTsKKyAgICAgICAgICAgIHZvaWQqIGN1cnIgPSByZWludGVycHJldF9jYXN0PGNoYXIqPihhcnJheSkgKyBtSXRlbVNpemUqKGktMSk7CisgICAgICAgICAgICBpZiAoY21wKGN1cnIsIGl0ZW0sIHN0YXRlKSA+IDApIHsKKworICAgICAgICAgICAgICAgIGlmICghdGVtcCkgeworICAgICAgICAgICAgICAgICAgICAvLyB3ZSdyZSBnb2luZyB0byBoYXZlIHRvIG1vZGlmeSB0aGUgYXJyYXkuLi4KKyAgICAgICAgICAgICAgICAgICAgYXJyYXkgPSBlZGl0QXJyYXlJbXBsKCk7CisgICAgICAgICAgICAgICAgICAgIGlmICghYXJyYXkpIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBtYWxsb2MobUl0ZW1TaXplKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZW1wKSByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICAgICAgICAgICAgICBfZG9fY29uc3RydWN0KHRlbXAsIDEpOworICAgICAgICAgICAgICAgICAgICBpdGVtID0gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oYXJyYXkpICsgbUl0ZW1TaXplKihpKTsKKyAgICAgICAgICAgICAgICAgICAgY3VyciA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGFycmF5KSArIG1JdGVtU2l6ZSooaS0xKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBfZG9fY29weSh0ZW1wLCBpdGVtLCAxKTsKKworICAgICAgICAgICAgICAgIHNzaXplX3QgaiA9IGktMTsKKyAgICAgICAgICAgICAgICB2b2lkKiBuZXh0ID0gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oYXJyYXkpICsgbUl0ZW1TaXplKihpKTsgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgX2RvX2NvcHkobmV4dCwgY3VyciwgMSk7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSBjdXJyOworICAgICAgICAgICAgICAgICAgICAtLWo7CisgICAgICAgICAgICAgICAgICAgIGN1cnIgPSByZWludGVycHJldF9jYXN0PGNoYXIqPihhcnJheSkgKyBtSXRlbVNpemUqKGopOyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgfSB3aGlsZSAoaj49MCAmJiAoY21wKGN1cnIsIHRlbXAsIHN0YXRlKSA+IDApKTsKKworICAgICAgICAgICAgICAgIF9kb19jb3B5KG5leHQsIHRlbXAsIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAodGVtcCkgeworICAgICAgICAgICAgX2RvX2Rlc3Ryb3kodGVtcCwgMSk7CisgICAgICAgICAgICBmcmVlKHRlbXApOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKwordm9pZCBWZWN0b3JJbXBsOjpwb3AoKQoreworICAgIGlmIChzaXplKCkpCisgICAgICAgIHJlbW92ZUl0ZW1zQXQoc2l6ZSgpLTEsIDEpOworfQorCit2b2lkIFZlY3RvckltcGw6OnB1c2goKQoreworICAgIHB1c2goMCk7Cit9CisKK3ZvaWQgVmVjdG9ySW1wbDo6cHVzaChjb25zdCB2b2lkKiBpdGVtKQoreworICAgIGluc2VydEF0KGl0ZW0sIHNpemUoKSk7Cit9CisKK3NzaXplX3QgVmVjdG9ySW1wbDo6YWRkKCkKK3sKKyAgICByZXR1cm4gYWRkKDApOworfQorCitzc2l6ZV90IFZlY3RvckltcGw6OmFkZChjb25zdCB2b2lkKiBpdGVtKQoreworICAgIHJldHVybiBpbnNlcnRBdChpdGVtLCBzaXplKCkpOworfQorCitzc2l6ZV90IFZlY3RvckltcGw6OnJlcGxhY2VBdChzaXplX3QgaW5kZXgpCit7CisgICAgcmV0dXJuIHJlcGxhY2VBdCgwLCBpbmRleCk7Cit9CisKK3NzaXplX3QgVmVjdG9ySW1wbDo6cmVwbGFjZUF0KGNvbnN0IHZvaWQqIHByb3RvdHlwZSwgc2l6ZV90IGluZGV4KQoreworICAgIExPR19BU1NFUlQoaW5kZXg8c2l6ZSgpLAorICAgICAgICAiWyVwXSByZXBsYWNlOiBpbmRleD0lZCwgc2l6ZT0lZCIsIHRoaXMsIChpbnQpaW5kZXgsIChpbnQpc2l6ZSgpKTsKKworICAgIHZvaWQqIGl0ZW0gPSBlZGl0SXRlbUxvY2F0aW9uKGluZGV4KTsKKyAgICBpZiAoaXRlbSA9PSAwKQorICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgIF9kb19kZXN0cm95KGl0ZW0sIDEpOworICAgIGlmIChwcm90b3R5cGUgPT0gMCkgeworICAgICAgICBfZG9fY29uc3RydWN0KGl0ZW0sIDEpOworICAgIH0gZWxzZSB7CisgICAgICAgIF9kb19jb3B5KGl0ZW0sIHByb3RvdHlwZSwgMSk7CisgICAgfQorICAgIHJldHVybiBzc2l6ZV90KGluZGV4KTsKK30KKworc3NpemVfdCBWZWN0b3JJbXBsOjpyZW1vdmVJdGVtc0F0KHNpemVfdCBpbmRleCwgc2l6ZV90IGNvdW50KQoreworICAgIExPR19BU1NFUlQoKGluZGV4K2NvdW50KTw9c2l6ZSgpLAorICAgICAgICAiWyVwXSByZW1vdmU6IGluZGV4PSVkLCBjb3VudD0lZCwgc2l6ZT0lZCIsCisgICAgICAgICAgICAgICB0aGlzLCAoaW50KWluZGV4LCAoaW50KWNvdW50LCAoaW50KXNpemUoKSk7CisKKyAgICBpZiAoKGluZGV4K2NvdW50KSA+IHNpemUoKSkKKyAgICAgICAgcmV0dXJuIEJBRF9WQUxVRTsKKyAgIF9zaHJpbmsoaW5kZXgsIGNvdW50KTsKKyAgIHJldHVybiBpbmRleDsKK30KKwordm9pZCBWZWN0b3JJbXBsOjpmaW5pc2hfdmVjdG9yKCkKK3sKKyAgICByZWxlYXNlX3N0b3JhZ2UoKTsKKyAgICBtU3RvcmFnZSA9IDA7CisgICAgbUNvdW50ID0gMDsKK30KKwordm9pZCBWZWN0b3JJbXBsOjpjbGVhcigpCit7CisgICAgX3NocmluaygwLCBtQ291bnQpOworfQorCit2b2lkKiBWZWN0b3JJbXBsOjplZGl0SXRlbUxvY2F0aW9uKHNpemVfdCBpbmRleCkKK3sKKyAgICBMT0dfQVNTRVJUKGluZGV4PGNhcGFjaXR5KCksCisgICAgICAgICJbJXBdIGl0ZW1Mb2NhdGlvbjogaW5kZXg9JWQsIGNhcGFjaXR5PSVkLCBjb3VudD0lZCIsCisgICAgICAgIHRoaXMsIChpbnQpaW5kZXgsIChpbnQpY2FwYWNpdHkoKSwgKGludCltQ291bnQpOworICAgICAgICAgICAgCisgICAgdm9pZCogYnVmZmVyID0gZWRpdEFycmF5SW1wbCgpOworICAgIGlmIChidWZmZXIpCisgICAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNoYXIqPihidWZmZXIpICsgaW5kZXgqbUl0ZW1TaXplOworICAgIHJldHVybiAwOworfQorCitjb25zdCB2b2lkKiBWZWN0b3JJbXBsOjppdGVtTG9jYXRpb24oc2l6ZV90IGluZGV4KSBjb25zdAoreworICAgIExPR19BU1NFUlQoaW5kZXg8Y2FwYWNpdHkoKSwKKyAgICAgICAgIlslcF0gZWRpdEl0ZW1Mb2NhdGlvbjogaW5kZXg9JWQsIGNhcGFjaXR5PSVkLCBjb3VudD0lZCIsCisgICAgICAgIHRoaXMsIChpbnQpaW5kZXgsIChpbnQpY2FwYWNpdHkoKSwgKGludCltQ291bnQpOworCisgICAgY29uc3QgIHZvaWQqIGJ1ZmZlciA9IGFycmF5SW1wbCgpOworICAgIGlmIChidWZmZXIpCisgICAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihidWZmZXIpICsgaW5kZXgqbUl0ZW1TaXplOworICAgIHJldHVybiAwOworfQorCitzc2l6ZV90IFZlY3RvckltcGw6OnNldENhcGFjaXR5KHNpemVfdCBuZXdfY2FwYWNpdHkpCit7CisgICAgc2l6ZV90IGN1cnJlbnRfY2FwYWNpdHkgPSBjYXBhY2l0eSgpOworICAgIHNzaXplX3QgYW1vdW50ID0gbmV3X2NhcGFjaXR5IC0gc2l6ZSgpOworICAgIGlmIChhbW91bnQgPD0gMCkgeworICAgICAgICAvLyB3ZSBjYW4ndCByZWR1Y2UgdGhlIGNhcGFjaXR5CisgICAgICAgIHJldHVybiBjdXJyZW50X2NhcGFjaXR5OworICAgIH0gCisgICAgU2hhcmVkQnVmZmVyKiBzYiA9IFNoYXJlZEJ1ZmZlcjo6YWxsb2MobmV3X2NhcGFjaXR5ICogbUl0ZW1TaXplKTsKKyAgICBpZiAoc2IpIHsKKyAgICAgICAgdm9pZCogYXJyYXkgPSBzYi0+ZGF0YSgpOworICAgICAgICBfZG9fY29weShhcnJheSwgbVN0b3JhZ2UsIHNpemUoKSk7CisgICAgICAgIHJlbGVhc2Vfc3RvcmFnZSgpOworICAgICAgICBtU3RvcmFnZSA9IGNvbnN0X2Nhc3Q8dm9pZCo+KGFycmF5KTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgIH0KKyAgICByZXR1cm4gbmV3X2NhcGFjaXR5OworfQorCit2b2lkIFZlY3RvckltcGw6OnJlbGVhc2Vfc3RvcmFnZSgpCit7CisgICAgaWYgKG1TdG9yYWdlKSB7CisgICAgICAgIGNvbnN0IFNoYXJlZEJ1ZmZlciogc2IgPSBTaGFyZWRCdWZmZXI6OnNoYXJlZEJ1ZmZlcihtU3RvcmFnZSk7CisgICAgICAgIGlmIChzYi0+cmVsZWFzZShTaGFyZWRCdWZmZXI6OmVLZWVwU3RvcmFnZSkgPT0gMSkgeworICAgICAgICAgICAgX2RvX2Rlc3Ryb3kobVN0b3JhZ2UsIG1Db3VudCk7CisgICAgICAgICAgICBTaGFyZWRCdWZmZXI6OmRlYWxsb2Moc2IpOworICAgICAgICB9IAorICAgIH0KK30KKwordm9pZCogVmVjdG9ySW1wbDo6X2dyb3coc2l6ZV90IHdoZXJlLCBzaXplX3QgYW1vdW50KQoreworLy8gICAgTE9HVigiX2dyb3codGhpcz0lcCwgd2hlcmU9JWQsIGFtb3VudD0lZCkgY291bnQ9JWQsIGNhcGFjaXR5PSVkIiwKKy8vICAgICAgICB0aGlzLCAoaW50KXdoZXJlLCAoaW50KWFtb3VudCwgKGludCltQ291bnQsIChpbnQpY2FwYWNpdHkoKSk7CisKKyAgICBpZiAod2hlcmUgPiBtQ291bnQpCisgICAgICAgIHdoZXJlID0gbUNvdW50OworICAgICAgCisgICAgY29uc3Qgc2l6ZV90IG5ld19zaXplID0gbUNvdW50ICsgYW1vdW50OworICAgIGlmIChjYXBhY2l0eSgpIDwgbmV3X3NpemUpIHsKKyAgICAgICAgY29uc3Qgc2l6ZV90IG5ld19jYXBhY2l0eSA9IG1heChrTWluVmVjdG9yQ2FwYWNpdHksICgobmV3X3NpemUqMykrMSkvMik7CisvLyAgICAgICAgTE9HVigiZ3JvdyB2ZWN0b3IgJXAsIG5ld19jYXBhY2l0eT0lZCIsIHRoaXMsIChpbnQpbmV3X2NhcGFjaXR5KTsKKyAgICAgICAgaWYgKChtU3RvcmFnZSkgJiYKKyAgICAgICAgICAgIChtQ291bnQ9PXdoZXJlKSAmJgorICAgICAgICAgICAgKG1GbGFncyAmIEhBU19UUklWSUFMX0NPUFkpICYmCisgICAgICAgICAgICAobUZsYWdzICYgSEFTX1RSSVZJQUxfRFRPUikpCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvbnN0IFNoYXJlZEJ1ZmZlciogY3VyX3NiID0gU2hhcmVkQnVmZmVyOjpzaGFyZWRCdWZmZXIobVN0b3JhZ2UpOworICAgICAgICAgICAgU2hhcmVkQnVmZmVyKiBzYiA9IGN1cl9zYi0+ZWRpdFJlc2l6ZShuZXdfY2FwYWNpdHkgKiBtSXRlbVNpemUpOworICAgICAgICAgICAgbVN0b3JhZ2UgPSBzYi0+ZGF0YSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgU2hhcmVkQnVmZmVyKiBzYiA9IFNoYXJlZEJ1ZmZlcjo6YWxsb2MobmV3X2NhcGFjaXR5ICogbUl0ZW1TaXplKTsKKyAgICAgICAgICAgIGlmIChzYikgeworICAgICAgICAgICAgICAgIHZvaWQqIGFycmF5ID0gc2ItPmRhdGEoKTsKKyAgICAgICAgICAgICAgICBpZiAod2hlcmU+MCkgeworICAgICAgICAgICAgICAgICAgICBfZG9fY29weShhcnJheSwgbVN0b3JhZ2UsIHdoZXJlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG1Db3VudD53aGVyZSkgeworICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBmcm9tID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OF90ICo+KG1TdG9yYWdlKSArIHdoZXJlKm1JdGVtU2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgdm9pZCogZGVzdCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCAqPihhcnJheSkgKyAod2hlcmUrYW1vdW50KSptSXRlbVNpemU7CisgICAgICAgICAgICAgICAgICAgIF9kb19jb3B5KGRlc3QsIGZyb20sIG1Db3VudC13aGVyZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlbGVhc2Vfc3RvcmFnZSgpOworICAgICAgICAgICAgICAgIG1TdG9yYWdlID0gY29uc3RfY2FzdDx2b2lkKj4oYXJyYXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgc3NpemVfdCBzID0gbUNvdW50LXdoZXJlOworICAgICAgICBpZiAocz4wKSB7CisgICAgICAgICAgICB2b2lkKiBhcnJheSA9IGVkaXRBcnJheUltcGwoKTsgICAgCisgICAgICAgICAgICB2b2lkKiB0byA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCAqPihhcnJheSkgKyAod2hlcmUrYW1vdW50KSptSXRlbVNpemU7CisgICAgICAgICAgICBjb25zdCB2b2lkKiBmcm9tID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OF90ICo+KGFycmF5KSArIHdoZXJlKm1JdGVtU2l6ZTsKKyAgICAgICAgICAgIF9kb19tb3ZlX2ZvcndhcmQodG8sIGZyb20sIHMpOworICAgICAgICB9CisgICAgfQorICAgIG1Db3VudCArPSBhbW91bnQ7CisgICAgdm9pZCogZnJlZV9zcGFjZSA9IGNvbnN0X2Nhc3Q8dm9pZCo+KGl0ZW1Mb2NhdGlvbih3aGVyZSkpOworICAgIHJldHVybiBmcmVlX3NwYWNlOworfQorCit2b2lkIFZlY3RvckltcGw6Ol9zaHJpbmsoc2l6ZV90IHdoZXJlLCBzaXplX3QgYW1vdW50KQoreworICAgIGlmICghbVN0b3JhZ2UpCisgICAgICAgIHJldHVybjsKKworLy8gICAgTE9HVigiX3Nocmluayh0aGlzPSVwLCB3aGVyZT0lZCwgYW1vdW50PSVkKSBjb3VudD0lZCwgY2FwYWNpdHk9JWQiLAorLy8gICAgICAgIHRoaXMsIChpbnQpd2hlcmUsIChpbnQpYW1vdW50LCAoaW50KW1Db3VudCwgKGludCljYXBhY2l0eSgpKTsKKworICAgIGlmICh3aGVyZSA+PSBtQ291bnQpCisgICAgICAgIHdoZXJlID0gbUNvdW50IC0gYW1vdW50OworCisgICAgY29uc3Qgc2l6ZV90IG5ld19zaXplID0gbUNvdW50IC0gYW1vdW50OworICAgIGlmIChuZXdfc2l6ZSozIDwgY2FwYWNpdHkoKSkgeworICAgICAgICBjb25zdCBzaXplX3QgbmV3X2NhcGFjaXR5ID0gbWF4KGtNaW5WZWN0b3JDYXBhY2l0eSwgbmV3X3NpemUqMik7CisvLyAgICAgICAgTE9HVigic2hyaW5rIHZlY3RvciAlcCwgbmV3X2NhcGFjaXR5PSVkIiwgdGhpcywgKGludCluZXdfY2FwYWNpdHkpOworICAgICAgICBpZiAoKHdoZXJlID09IG1Db3VudC1hbW91bnQpICYmCisgICAgICAgICAgICAobUZsYWdzICYgSEFTX1RSSVZJQUxfQ09QWSkgJiYKKyAgICAgICAgICAgIChtRmxhZ3MgJiBIQVNfVFJJVklBTF9EVE9SKSkKKyAgICAgICAgeworICAgICAgICAgICAgY29uc3QgU2hhcmVkQnVmZmVyKiBjdXJfc2IgPSBTaGFyZWRCdWZmZXI6OnNoYXJlZEJ1ZmZlcihtU3RvcmFnZSk7CisgICAgICAgICAgICBTaGFyZWRCdWZmZXIqIHNiID0gY3VyX3NiLT5lZGl0UmVzaXplKG5ld19jYXBhY2l0eSAqIG1JdGVtU2l6ZSk7CisgICAgICAgICAgICBtU3RvcmFnZSA9IHNiLT5kYXRhKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTaGFyZWRCdWZmZXIqIHNiID0gU2hhcmVkQnVmZmVyOjphbGxvYyhuZXdfY2FwYWNpdHkgKiBtSXRlbVNpemUpOworICAgICAgICAgICAgaWYgKHNiKSB7CisgICAgICAgICAgICAgICAgdm9pZCogYXJyYXkgPSBzYi0+ZGF0YSgpOworICAgICAgICAgICAgICAgIGlmICh3aGVyZT4wKSB7CisgICAgICAgICAgICAgICAgICAgIF9kb19jb3B5KGFycmF5LCBtU3RvcmFnZSwgd2hlcmUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobUNvdW50ID4gd2hlcmUrYW1vdW50KSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGZyb20gPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4X3QgKj4obVN0b3JhZ2UpICsgKHdoZXJlK2Ftb3VudCkqbUl0ZW1TaXplOworICAgICAgICAgICAgICAgICAgICB2b2lkKiBkZXN0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OF90ICo+KGFycmF5KSArIHdoZXJlKm1JdGVtU2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgX2RvX2NvcHkoZGVzdCwgZnJvbSwgbUNvdW50LSh3aGVyZSthbW91bnQpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVsZWFzZV9zdG9yYWdlKCk7CisgICAgICAgICAgICAgICAgbVN0b3JhZ2UgPSBjb25zdF9jYXN0PHZvaWQqPihhcnJheSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICB2b2lkKiBhcnJheSA9IGVkaXRBcnJheUltcGwoKTsgICAgCisgICAgICAgIHZvaWQqIHRvID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OF90ICo+KGFycmF5KSArIHdoZXJlKm1JdGVtU2l6ZTsKKyAgICAgICAgX2RvX2Rlc3Ryb3kodG8sIGFtb3VudCk7CisgICAgICAgIHNzaXplX3QgcyA9IG1Db3VudC0od2hlcmUrYW1vdW50KTsKKyAgICAgICAgaWYgKHM+MCkgeworICAgICAgICAgICAgY29uc3Qgdm9pZCogZnJvbSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCAqPihhcnJheSkgKyAod2hlcmUrYW1vdW50KSptSXRlbVNpemU7CisgICAgICAgICAgICBfZG9fbW92ZV9iYWNrd2FyZCh0bywgZnJvbSwgcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBhZGp1c3QgdGhlIG51bWJlciBvZiBpdGVtcy4uLgorICAgIG1Db3VudCAtPSBhbW91bnQ7Cit9CisKK3NpemVfdCBWZWN0b3JJbXBsOjppdGVtU2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gbUl0ZW1TaXplOworfQorCit2b2lkIFZlY3RvckltcGw6Ol9kb19jb25zdHJ1Y3Qodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QKK3sKKyAgICBpZiAoIShtRmxhZ3MgJiBIQVNfVFJJVklBTF9DVE9SKSkgeworICAgICAgICBkb19jb25zdHJ1Y3Qoc3RvcmFnZSwgbnVtKTsKKyAgICB9Cit9CisKK3ZvaWQgVmVjdG9ySW1wbDo6X2RvX2Rlc3Ryb3kodm9pZCogc3RvcmFnZSwgc2l6ZV90IG51bSkgY29uc3QKK3sKKyAgICBpZiAoIShtRmxhZ3MgJiBIQVNfVFJJVklBTF9EVE9SKSkgeworICAgICAgICBkb19kZXN0cm95KHN0b3JhZ2UsIG51bSk7CisgICAgfQorfQorCit2b2lkIFZlY3RvckltcGw6Ol9kb19jb3B5KHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGZyb20sIHNpemVfdCBudW0pIGNvbnN0Cit7CisgICAgaWYgKCEobUZsYWdzICYgSEFTX1RSSVZJQUxfQ09QWSkpIHsKKyAgICAgICAgZG9fY29weShkZXN0LCBmcm9tLCBudW0pOworICAgIH0gZWxzZSB7CisgICAgICAgIG1lbWNweShkZXN0LCBmcm9tLCBudW0qaXRlbVNpemUoKSk7CisgICAgfQorfQorCit2b2lkIFZlY3RvckltcGw6Ol9kb19zcGxhdCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBpdGVtLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgZG9fc3BsYXQoZGVzdCwgaXRlbSwgbnVtKTsKK30KKwordm9pZCBWZWN0b3JJbXBsOjpfZG9fbW92ZV9mb3J3YXJkKHZvaWQqIGRlc3QsIGNvbnN0IHZvaWQqIGZyb20sIHNpemVfdCBudW0pIGNvbnN0IHsKKyAgICBkb19tb3ZlX2ZvcndhcmQoZGVzdCwgZnJvbSwgbnVtKTsKK30KKwordm9pZCBWZWN0b3JJbXBsOjpfZG9fbW92ZV9iYWNrd2FyZCh2b2lkKiBkZXN0LCBjb25zdCB2b2lkKiBmcm9tLCBzaXplX3QgbnVtKSBjb25zdCB7CisgICAgZG9fbW92ZV9iYWNrd2FyZChkZXN0LCBmcm9tLCBudW0pOworfQorCit2b2lkIFZlY3RvckltcGw6OnJlc2VydmVkVmVjdG9ySW1wbDEoKSB7IH0KK3ZvaWQgVmVjdG9ySW1wbDo6cmVzZXJ2ZWRWZWN0b3JJbXBsMigpIHsgfQordm9pZCBWZWN0b3JJbXBsOjpyZXNlcnZlZFZlY3RvckltcGwzKCkgeyB9Cit2b2lkIFZlY3RvckltcGw6OnJlc2VydmVkVmVjdG9ySW1wbDQoKSB7IH0KK3ZvaWQgVmVjdG9ySW1wbDo6cmVzZXJ2ZWRWZWN0b3JJbXBsNSgpIHsgfQordm9pZCBWZWN0b3JJbXBsOjpyZXNlcnZlZFZlY3RvckltcGw2KCkgeyB9Cit2b2lkIFZlY3RvckltcGw6OnJlc2VydmVkVmVjdG9ySW1wbDcoKSB7IH0KK3ZvaWQgVmVjdG9ySW1wbDo6cmVzZXJ2ZWRWZWN0b3JJbXBsOCgpIHsgfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK1NvcnRlZFZlY3RvckltcGw6OlNvcnRlZFZlY3RvckltcGwoc2l6ZV90IGl0ZW1TaXplLCB1aW50MzJfdCBmbGFncykKKyAgICA6IFZlY3RvckltcGwoaXRlbVNpemUsIGZsYWdzKQoreworfQorCitTb3J0ZWRWZWN0b3JJbXBsOjpTb3J0ZWRWZWN0b3JJbXBsKGNvbnN0IFZlY3RvckltcGwmIHJocykKKzogVmVjdG9ySW1wbChyaHMpCit7Cit9CisKK1NvcnRlZFZlY3RvckltcGw6On5Tb3J0ZWRWZWN0b3JJbXBsKCkKK3sKK30KKworU29ydGVkVmVjdG9ySW1wbCYgU29ydGVkVmVjdG9ySW1wbDo6b3BlcmF0b3IgPSAoY29uc3QgU29ydGVkVmVjdG9ySW1wbCYgcmhzKQoreworICAgIHJldHVybiBzdGF0aWNfY2FzdDxTb3J0ZWRWZWN0b3JJbXBsJj4oIFZlY3RvckltcGw6Om9wZXJhdG9yID0gKHN0YXRpY19jYXN0PGNvbnN0IFZlY3RvckltcGwmPihyaHMpKSApOworfQorCitzc2l6ZV90IFNvcnRlZFZlY3RvckltcGw6OmluZGV4T2YoY29uc3Qgdm9pZCogaXRlbSkgY29uc3QKK3sKKyAgICByZXR1cm4gX2luZGV4T3JkZXJPZihpdGVtKTsKK30KKworc2l6ZV90IFNvcnRlZFZlY3RvckltcGw6Om9yZGVyT2YoY29uc3Qgdm9pZCogaXRlbSkgY29uc3QKK3sKKyAgICBzaXplX3QgbzsKKyAgICBfaW5kZXhPcmRlck9mKGl0ZW0sICZvKTsKKyAgICByZXR1cm4gbzsKK30KKworc3NpemVfdCBTb3J0ZWRWZWN0b3JJbXBsOjpfaW5kZXhPcmRlck9mKGNvbnN0IHZvaWQqIGl0ZW0sIHNpemVfdCogb3JkZXIpIGNvbnN0Cit7CisgICAgLy8gYmluYXJ5IHNlYXJjaAorICAgIHNzaXplX3QgZXJyID0gTkFNRV9OT1RfRk9VTkQ7CisgICAgc3NpemVfdCBsID0gMDsKKyAgICBzc2l6ZV90IGggPSBzaXplKCktMTsKKyAgICBzc2l6ZV90IG1pZDsKKyAgICBjb25zdCB2b2lkKiBhID0gYXJyYXlJbXBsKCk7CisgICAgY29uc3Qgc2l6ZV90IHMgPSBpdGVtU2l6ZSgpOworICAgIHdoaWxlIChsIDw9IGgpIHsKKyAgICAgICAgbWlkID0gbCArIChoIC0gbCkvMjsKKyAgICAgICAgY29uc3Qgdm9pZCogY29uc3QgY3VyciA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhciAqPihhKSArIChtaWQqcyk7CisgICAgICAgIGNvbnN0IGludCBjID0gZG9fY29tcGFyZShjdXJyLCBpdGVtKTsKKyAgICAgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAgICAgZXJyID0gbCA9IG1pZDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9IGVsc2UgaWYgKGMgPCAwKSB7CisgICAgICAgICAgICBsID0gbWlkICsgMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGggPSBtaWQgLSAxOworICAgICAgICB9CisgICAgfQorICAgIGlmIChvcmRlcikgKm9yZGVyID0gbDsKKyAgICByZXR1cm4gZXJyOworfQorCitzc2l6ZV90IFNvcnRlZFZlY3RvckltcGw6OmFkZChjb25zdCB2b2lkKiBpdGVtKQoreworICAgIHNpemVfdCBvcmRlcjsKKyAgICBzc2l6ZV90IGluZGV4ID0gX2luZGV4T3JkZXJPZihpdGVtLCAmb3JkZXIpOworICAgIGlmIChpbmRleCA8IDApIHsKKyAgICAgICAgaW5kZXggPSBWZWN0b3JJbXBsOjppbnNlcnRBdChpdGVtLCBvcmRlciwgMSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaW5kZXggPSBWZWN0b3JJbXBsOjpyZXBsYWNlQXQoaXRlbSwgaW5kZXgpOworICAgIH0KKyAgICByZXR1cm4gaW5kZXg7Cit9CisKK3NzaXplX3QgU29ydGVkVmVjdG9ySW1wbDo6bWVyZ2UoY29uc3QgVmVjdG9ySW1wbCYgdmVjdG9yKQoreworICAgIC8vIG5haXZlIG1lcmdlLi4uCisgICAgaWYgKCF2ZWN0b3IuaXNFbXB0eSgpKSB7CisgICAgICAgIGNvbnN0IHZvaWQqIGJ1ZmZlciA9IHZlY3Rvci5hcnJheUltcGwoKTsKKyAgICAgICAgY29uc3Qgc2l6ZV90IGlzID0gaXRlbVNpemUoKTsKKyAgICAgICAgc2l6ZV90IHMgPSB2ZWN0b3Iuc2l6ZSgpOworICAgICAgICBmb3IgKHNpemVfdCBpPTAgOyBpPHMgOyBpKyspIHsKKyAgICAgICAgICAgIHNzaXplX3QgZXJyID0gYWRkKCByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihidWZmZXIpICsgaSppcyApOworICAgICAgICAgICAgaWYgKGVycjwwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGVycjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3NzaXplX3QgU29ydGVkVmVjdG9ySW1wbDo6bWVyZ2UoY29uc3QgU29ydGVkVmVjdG9ySW1wbCYgdmVjdG9yKQoreworICAgIC8vIHdlJ3ZlIG1lcmdpbmcgYSBzb3J0ZWQgdmVjdG9yLi4uIG5pY2UhCisgICAgc3NpemVfdCBlcnIgPSBOT19FUlJPUjsKKyAgICBpZiAoIXZlY3Rvci5pc0VtcHR5KCkpIHsKKyAgICAgICAgLy8gZmlyc3QgdGFrZSBjYXJlIG9mIHRoZSBjYXNlIHdoZXJlIHRoZSB2ZWN0b3JzIGFyZSBzb3J0ZWQgdG9nZXRoZXIKKyAgICAgICAgaWYgKGRvX2NvbXBhcmUodmVjdG9yLml0ZW1Mb2NhdGlvbih2ZWN0b3Iuc2l6ZSgpLTEpLCBhcnJheUltcGwoKSkgPD0gMCkgeworICAgICAgICAgICAgZXJyID0gVmVjdG9ySW1wbDo6aW5zZXJ0VmVjdG9yQXQoc3RhdGljX2Nhc3Q8Y29uc3QgVmVjdG9ySW1wbCY+KHZlY3RvciksIDApOworICAgICAgICB9IGVsc2UgaWYgKGRvX2NvbXBhcmUodmVjdG9yLmFycmF5SW1wbCgpLCBpdGVtTG9jYXRpb24oc2l6ZSgpLTEpKSA+PSAwKSB7CisgICAgICAgICAgICBlcnIgPSBWZWN0b3JJbXBsOjphcHBlbmRWZWN0b3Ioc3RhdGljX2Nhc3Q8Y29uc3QgVmVjdG9ySW1wbCY+KHZlY3RvcikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gdGhpcyBjb3VsZCBiZSBtYWRlIGEgbGl0dGxlIGJldHRlcgorICAgICAgICAgICAgZXJyID0gbWVyZ2Uoc3RhdGljX2Nhc3Q8Y29uc3QgVmVjdG9ySW1wbCY+KHZlY3RvcikpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBlcnI7Cit9CisKK3NzaXplX3QgU29ydGVkVmVjdG9ySW1wbDo6cmVtb3ZlKGNvbnN0IHZvaWQqIGl0ZW0pCit7CisgICAgc3NpemVfdCBpID0gaW5kZXhPZihpdGVtKTsKKyAgICBpZiAoaT49MCkgeworICAgICAgICBWZWN0b3JJbXBsOjpyZW1vdmVJdGVtc0F0KGksIDEpOworICAgIH0KKyAgICByZXR1cm4gaTsKK30KKwordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGwxKCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGwyKCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGwzKCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGw0KCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGw1KCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGw2KCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGw3KCkgeyB9Owordm9pZCBTb3J0ZWRWZWN0b3JJbXBsOjpyZXNlcnZlZFNvcnRlZFZlY3RvckltcGw4KCkgeyB9OworCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9aaXBFbnRyeS5jcHAgYi9saWJzL3V0aWxzL1ppcEVudHJ5LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYmM5ZTY3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9aaXBFbnRyeS5jcHAKQEAgLTAsMCArMSw2OTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gQWNjZXNzIHRvIGVudHJpZXMgaW4gYSBaaXAgYXJjaGl2ZS4KKy8vCisKKyNkZWZpbmUgTE9HX1RBRyAiemlwIgorCisjaW5jbHVkZSAidXRpbHMvWmlwRW50cnkuaCIKKyNpbmNsdWRlICJ1dGlscy9Mb2cuaCIKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisvKgorICogSW5pdGlhbGl6ZSBhIG5ldyBaaXBFbnRyeSBzdHJ1Y3R1cmUgZnJvbSBhIEZJTEUqIHBvc2l0aW9uZWQgYXQgYQorICogQ2VudHJhbERpcmVjdG9yeUVudHJ5LgorICoKKyAqIE9uIGV4aXQsIHRoZSBmaWxlIHBvaW50ZXIgd2lsbCBiZSBhdCB0aGUgc3RhcnQgb2YgdGhlIG5leHQgQ0RFIG9yCisgKiBhdCB0aGUgRU9DRC4KKyAqLworc3RhdHVzX3QgWmlwRW50cnk6OmluaXRGcm9tQ0RFKEZJTEUqIGZwKQoreworICAgIHN0YXR1c190IHJlc3VsdDsKKyAgICBsb25nIHBvc247CisgICAgYm9vbCBoYXNERDsKKworICAgIC8vTE9HVigiaW5pdEZyb21DREUgLS0tXG4iKTsKKworICAgIC8qIHJlYWQgdGhlIENERSAqLworICAgIHJlc3VsdCA9IG1DREUucmVhZChmcCk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgeworICAgICAgICBMT0dEKCJtQ0RFLnJlYWQgZmFpbGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvL21DREUuZHVtcCgpOworCisgICAgLyogdXNpbmcgdGhlIGluZm8gaW4gdGhlIENERSwgZ28gbG9hZCB1cCB0aGUgTEZIICovCisgICAgcG9zbiA9IGZ0ZWxsKGZwKTsKKyAgICBpZiAoZnNlZWsoZnAsIG1DREUubUxvY2FsSGVhZGVyUmVsT2Zmc2V0LCBTRUVLX1NFVCkgIT0gMCkgeworICAgICAgICBMT0dEKCJsb2NhbCBoZWFkZXIgc2VlayBmYWlsZWQgKCVsZClcbiIsCisgICAgICAgICAgICBtQ0RFLm1Mb2NhbEhlYWRlclJlbE9mZnNldCk7CisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIHJlc3VsdCA9IG1MRkgucmVhZChmcCk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgeworICAgICAgICBMT0dEKCJtTEZILnJlYWQgZmFpbGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBpZiAoZnNlZWsoZnAsIHBvc24sIFNFRUtfU0VUKSAhPSAwKQorICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKworICAgIC8vbUxGSC5kdW1wKCk7CisKKyAgICAvKgorICAgICAqIFdlICptaWdodCogbmVlZCB0byByZWFkIHRoZSBEYXRhIERlc2NyaXB0b3IgYXQgdGhpcyBwb2ludCBhbmQKKyAgICAgKiBpbnRlZ3JhdGUgaXQgaW50byB0aGUgTEZILiAgSWYgdGhpcyBiaXQgaXMgc2V0LCB0aGUgQ1JDLTMyLAorICAgICAqIGNvbXByZXNzZWQgc2l6ZSwgYW5kIHVuY29tcHJlc3NlZCBzaXplIHdpbGwgYmUgemVyby4gIEluIHByYWN0aWNlCisgICAgICogdGhlc2Ugc2VlbSB0byBiZSByYXJlLgorICAgICAqLworICAgIGhhc0REID0gKG1MRkgubUdQQml0RmxhZyAmIGtVc2VzRGF0YURlc2NyKSAhPSAwOworICAgIGlmIChoYXNERCkgeworICAgICAgICAvLyBkbyBzb21ldGhpbmcgY2xldmVyCisgICAgICAgIC8vTE9HRCgiKysrIGhhcyBkYXRhIGRlc2NyaXB0b3JcbiIpOworICAgIH0KKworICAgIC8qCisgICAgICogU2FuaXR5LWNoZWNrIHRoZSBMRkguICBOb3RlIHRoYXQgdGhpcyB3aWxsIGZhaWwgaWYgdGhlICJrVXNlc0RhdGFEZXNjciIKKyAgICAgKiBmbGFnIGlzIHNldCwgYmVjYXVzZSB0aGUgTEZIIGlzIGluY29tcGxldGUuICAoTm90IGEgcHJvYmxlbSwgc2luY2Ugd2UKKyAgICAgKiBwcmVmZXIgdGhlIENERSB2YWx1ZXMuKQorICAgICAqLworICAgIGlmICghaGFzREQgJiYgIWNvbXBhcmVIZWFkZXJzKCkpIHsKKyAgICAgICAgTE9HVygiV0FSTklORzogaGVhZGVyIG1pc21hdGNoXG4iKTsKKyAgICAgICAgLy8ga2VlcCBnb2luZz8KKyAgICB9CisKKyAgICAvKgorICAgICAqIElmIHRoZSBtVmVyc2lvblRvRXh0cmFjdCBpcyBncmVhdGVyIHRoYW4gMjAsIHdlIG1heSBoYXZlIGFuCisgICAgICogaXNzdWUgdW5wYWNraW5nIHRoZSByZWNvcmQgLS0gY291bGQgYmUgZW5jcnlwdGVkLCBjb21wcmVzc2VkCisgICAgICogd2l0aCBzb21ldGhpbmcgd2UgZG9uJ3Qgc3VwcG9ydCwgb3IgdXNlIFppcDY0IGV4dGVuc2lvbnMuICBXZQorICAgICAqIGNhbiBkZWZlciB3b3JyeWluZyBhYm91dCB0aGF0IHRvIHdoZW4gd2UncmUgZXh0cmFjdGluZyBkYXRhLgorICAgICAqLworCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvKgorICogSW5pdGlhbGl6ZSBhIG5ldyBlbnRyeS4gIFBhc3MgaW4gdGhlIGZpbGUgbmFtZSBhbmQgYW4gb3B0aW9uYWwgY29tbWVudC4KKyAqCisgKiBJbml0aWFsaXplcyB0aGUgQ0RFIGFuZCB0aGUgTEZILgorICovCit2b2lkIFppcEVudHJ5Ojppbml0TmV3KGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBjb25zdCBjaGFyKiBjb21tZW50KQoreworICAgIGFzc2VydChmaWxlTmFtZSAhPSBOVUxMICYmICpmaWxlTmFtZSAhPSAnXDAnKTsgIC8vIG5hbWUgcmVxdWlyZWQKKworICAgIC8qIG1vc3QgZmllbGRzIGFyZSBwcm9wZXJseSBpbml0aWFsaXplZCBieSBjb25zdHJ1Y3RvciAqLworICAgIG1DREUubVZlcnNpb25NYWRlQnkgPSBrRGVmYXVsdE1hZGVCeTsKKyAgICBtQ0RFLm1WZXJzaW9uVG9FeHRyYWN0ID0ga0RlZmF1bHRWZXJzaW9uOworICAgIG1DREUubUNvbXByZXNzaW9uTWV0aG9kID0ga0NvbXByZXNzU3RvcmVkOworICAgIG1DREUubUZpbGVOYW1lTGVuZ3RoID0gc3RybGVuKGZpbGVOYW1lKTsKKyAgICBpZiAoY29tbWVudCAhPSBOVUxMKQorICAgICAgICBtQ0RFLm1GaWxlQ29tbWVudExlbmd0aCA9IHN0cmxlbihjb21tZW50KTsKKyAgICBtQ0RFLm1FeHRlcm5hbEF0dHJzID0gMHg4MWI2MDAyMDsgICAvLyBtYXRjaGVzIHdoYXQgV2luWmlwIGRvZXMKKworICAgIGlmIChtQ0RFLm1GaWxlTmFtZUxlbmd0aCA+IDApIHsKKyAgICAgICAgbUNERS5tRmlsZU5hbWUgPSBuZXcgdW5zaWduZWQgY2hhclttQ0RFLm1GaWxlTmFtZUxlbmd0aCsxXTsKKyAgICAgICAgc3RyY3B5KChjaGFyKikgbUNERS5tRmlsZU5hbWUsIGZpbGVOYW1lKTsKKyAgICB9CisgICAgaWYgKG1DREUubUZpbGVDb21tZW50TGVuZ3RoID4gMCkgeworICAgICAgICAvKiBUT0RPOiBzdG9wIGFzc3VtaW5nIG51bGwtdGVybWluYXRlZCBBU0NJSSBoZXJlPyAqLworICAgICAgICBtQ0RFLm1GaWxlQ29tbWVudCA9IG5ldyB1bnNpZ25lZCBjaGFyW21DREUubUZpbGVDb21tZW50TGVuZ3RoKzFdOworICAgICAgICBzdHJjcHkoKGNoYXIqKSBtQ0RFLm1GaWxlQ29tbWVudCwgY29tbWVudCk7CisgICAgfQorCisgICAgY29weUNERXRvTEZIKCk7Cit9CisKKy8qCisgKiBJbml0aWFsaXplIGEgbmV3IGVudHJ5LCBzdGFydGluZyB3aXRoIHRoZSBaaXBFbnRyeSBmcm9tIGEgZGlmZmVyZW50CisgKiBhcmNoaXZlLgorICoKKyAqIEluaXRpYWxpemVzIHRoZSBDREUgYW5kIHRoZSBMRkguCisgKi8KK3N0YXR1c190IFppcEVudHJ5Ojppbml0RnJvbUV4dGVybmFsKGNvbnN0IFppcEZpbGUqIHBaaXBGaWxlLAorICAgIGNvbnN0IFppcEVudHJ5KiBwRW50cnkpCit7CisgICAgLyoKKyAgICAgKiBDb3B5IGV2ZXJ5dGhpbmcgaW4gdGhlIENERSBvdmVyLCB0aGVuIGZpeCB1cCB0aGUgaGFpcnkgYml0cy4KKyAgICAgKi8KKyAgICBtZW1jcHkoJm1DREUsICZwRW50cnktPm1DREUsIHNpemVvZihtQ0RFKSk7CisKKyAgICBpZiAobUNERS5tRmlsZU5hbWVMZW5ndGggPiAwKSB7CisgICAgICAgIG1DREUubUZpbGVOYW1lID0gbmV3IHVuc2lnbmVkIGNoYXJbbUNERS5tRmlsZU5hbWVMZW5ndGgrMV07CisgICAgICAgIGlmIChtQ0RFLm1GaWxlTmFtZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgc3RyY3B5KChjaGFyKikgbUNERS5tRmlsZU5hbWUsIChjaGFyKilwRW50cnktPm1DREUubUZpbGVOYW1lKTsKKyAgICB9CisgICAgaWYgKG1DREUubUZpbGVDb21tZW50TGVuZ3RoID4gMCkgeworICAgICAgICBtQ0RFLm1GaWxlQ29tbWVudCA9IG5ldyB1bnNpZ25lZCBjaGFyW21DREUubUZpbGVDb21tZW50TGVuZ3RoKzFdOworICAgICAgICBpZiAobUNERS5tRmlsZUNvbW1lbnQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgIHN0cmNweSgoY2hhciopIG1DREUubUZpbGVDb21tZW50LCAoY2hhciopcEVudHJ5LT5tQ0RFLm1GaWxlQ29tbWVudCk7CisgICAgfQorICAgIGlmIChtQ0RFLm1FeHRyYUZpZWxkTGVuZ3RoID4gMCkgeworICAgICAgICAvKiB3ZSBudWxsLXRlcm1pbmF0ZSB0aGlzLCB0aG91Z2ggaXQgbWF5IG5vdCBiZSBhIHN0cmluZyAqLworICAgICAgICBtQ0RFLm1FeHRyYUZpZWxkID0gbmV3IHVuc2lnbmVkIGNoYXJbbUNERS5tRXh0cmFGaWVsZExlbmd0aCsxXTsKKyAgICAgICAgaWYgKG1DREUubUV4dHJhRmllbGQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisgICAgICAgIG1lbWNweShtQ0RFLm1FeHRyYUZpZWxkLCBwRW50cnktPm1DREUubUV4dHJhRmllbGQsCisgICAgICAgICAgICBtQ0RFLm1FeHRyYUZpZWxkTGVuZ3RoKzEpOworICAgIH0KKworICAgIC8qIGNvbnN0cnVjdCB0aGUgTEZIIGZyb20gdGhlIENERSAqLworICAgIGNvcHlDREV0b0xGSCgpOworCisgICAgLyoKKyAgICAgKiBUaGUgTEZIICJleHRyYSIgZmllbGQgaXMgaW5kZXBlbmRlbnQgb2YgdGhlIENERSAiZXh0cmEiLCBzbyB3ZQorICAgICAqIGhhbmRsZSBpdCBoZXJlLgorICAgICAqLworICAgIGFzc2VydChtTEZILm1FeHRyYUZpZWxkID09IE5VTEwpOworICAgIG1MRkgubUV4dHJhRmllbGRMZW5ndGggPSBwRW50cnktPm1MRkgubUV4dHJhRmllbGRMZW5ndGg7CisgICAgaWYgKG1MRkgubUV4dHJhRmllbGRMZW5ndGggPiAwKSB7CisgICAgICAgIG1MRkgubUV4dHJhRmllbGQgPSBuZXcgdW5zaWduZWQgY2hhclttTEZILm1FeHRyYUZpZWxkTGVuZ3RoKzFdOworICAgICAgICBpZiAobUxGSC5tRXh0cmFGaWVsZCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgbWVtY3B5KG1MRkgubUV4dHJhRmllbGQsIHBFbnRyeS0+bUxGSC5tRXh0cmFGaWVsZCwKKyAgICAgICAgICAgIG1MRkgubUV4dHJhRmllbGRMZW5ndGgrMSk7CisgICAgfQorCisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvKgorICogSW5zZXJ0IHBhZCBieXRlcyBpbiB0aGUgTEZIIGJ5IHR3ZWFraW5nIHRoZSAiZXh0cmEiIGZpZWxkLiAgVGhpcyB3aWxsCisgKiBwb3RlbnRpYWxseSBjb25mdXNlIHNvbWV0aGluZyB0aGF0IHB1dCAiZXh0cmEiIGRhdGEgaW4gaGVyZSBlYXJsaWVyLAorICogYnV0IEkgY2FuJ3QgZmluZCBhbiBhY3R1YWwgcHJvYmxlbS4KKyAqLworc3RhdHVzX3QgWmlwRW50cnk6OmFkZFBhZGRpbmcoaW50IHBhZGRpbmcpCit7CisgICAgaWYgKHBhZGRpbmcgPD0gMCkKKyAgICAgICAgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworCisgICAgLy9MT0dJKCJIRVk6IGFkZGluZyAlZCBwYWQgYnl0ZXMgdG8gZXhpc3RpbmcgJWQgaW4gJXNcbiIsCisgICAgLy8gICAgcGFkZGluZywgbUxGSC5tRXh0cmFGaWVsZExlbmd0aCwgbUNERS5tRmlsZU5hbWUpOworCisgICAgaWYgKG1MRkgubUV4dHJhRmllbGRMZW5ndGggPiAwKSB7CisgICAgICAgIC8qIGV4dGVuZCBleGlzdGluZyBmaWVsZCAqLworICAgICAgICB1bnNpZ25lZCBjaGFyKiBuZXdFeHRyYTsKKworICAgICAgICBuZXdFeHRyYSA9IG5ldyB1bnNpZ25lZCBjaGFyW21MRkgubUV4dHJhRmllbGRMZW5ndGggKyBwYWRkaW5nXTsKKyAgICAgICAgaWYgKG5ld0V4dHJhID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICBtZW1zZXQobmV3RXh0cmEgKyBtTEZILm1FeHRyYUZpZWxkTGVuZ3RoLCAwLCBwYWRkaW5nKTsKKyAgICAgICAgbWVtY3B5KG5ld0V4dHJhLCBtTEZILm1FeHRyYUZpZWxkLCBtTEZILm1FeHRyYUZpZWxkTGVuZ3RoKTsKKworICAgICAgICBkZWxldGVbXSBtTEZILm1FeHRyYUZpZWxkOworICAgICAgICBtTEZILm1FeHRyYUZpZWxkID0gbmV3RXh0cmE7CisgICAgICAgIG1MRkgubUV4dHJhRmllbGRMZW5ndGggKz0gcGFkZGluZzsKKyAgICB9IGVsc2UgeworICAgICAgICAvKiBjcmVhdGUgbmV3IGZpZWxkICovCisgICAgICAgIG1MRkgubUV4dHJhRmllbGQgPSBuZXcgdW5zaWduZWQgY2hhcltwYWRkaW5nXTsKKyAgICAgICAgbWVtc2V0KG1MRkgubUV4dHJhRmllbGQsIDAsIHBhZGRpbmcpOworICAgICAgICBtTEZILm1FeHRyYUZpZWxkTGVuZ3RoID0gcGFkZGluZzsKKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBTZXQgdGhlIGZpZWxkcyBpbiB0aGUgTEZIIGVxdWFsIHRvIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkcyBpbiB0aGUgQ0RFLgorICoKKyAqIFRoaXMgZG9lcyBub3QgdG91Y2ggdGhlIExGSCAiZXh0cmEiIGZpZWxkLgorICovCit2b2lkIFppcEVudHJ5Ojpjb3B5Q0RFdG9MRkgodm9pZCkKK3sKKyAgICBtTEZILm1WZXJzaW9uVG9FeHRyYWN0ICA9IG1DREUubVZlcnNpb25Ub0V4dHJhY3Q7CisgICAgbUxGSC5tR1BCaXRGbGFnICAgICAgICAgPSBtQ0RFLm1HUEJpdEZsYWc7CisgICAgbUxGSC5tQ29tcHJlc3Npb25NZXRob2QgPSBtQ0RFLm1Db21wcmVzc2lvbk1ldGhvZDsKKyAgICBtTEZILm1MYXN0TW9kRmlsZVRpbWUgICA9IG1DREUubUxhc3RNb2RGaWxlVGltZTsKKyAgICBtTEZILm1MYXN0TW9kRmlsZURhdGUgICA9IG1DREUubUxhc3RNb2RGaWxlRGF0ZTsKKyAgICBtTEZILm1DUkMzMiAgICAgICAgICAgICA9IG1DREUubUNSQzMyOworICAgIG1MRkgubUNvbXByZXNzZWRTaXplICAgID0gbUNERS5tQ29tcHJlc3NlZFNpemU7CisgICAgbUxGSC5tVW5jb21wcmVzc2VkU2l6ZSAgPSBtQ0RFLm1VbmNvbXByZXNzZWRTaXplOworICAgIG1MRkgubUZpbGVOYW1lTGVuZ3RoICAgID0gbUNERS5tRmlsZU5hbWVMZW5ndGg7CisgICAgLy8gdGhlICJleHRyYSBmaWVsZCIgaXMgaW5kZXBlbmRlbnQKKworICAgIGRlbGV0ZVtdIG1MRkgubUZpbGVOYW1lOworICAgIGlmIChtTEZILm1GaWxlTmFtZUxlbmd0aCA+IDApIHsKKyAgICAgICAgbUxGSC5tRmlsZU5hbWUgPSBuZXcgdW5zaWduZWQgY2hhclttTEZILm1GaWxlTmFtZUxlbmd0aCsxXTsKKyAgICAgICAgc3RyY3B5KChjaGFyKikgbUxGSC5tRmlsZU5hbWUsIChjb25zdCBjaGFyKikgbUNERS5tRmlsZU5hbWUpOworICAgIH0gZWxzZSB7CisgICAgICAgIG1MRkgubUZpbGVOYW1lID0gTlVMTDsKKyAgICB9Cit9CisKKy8qCisgKiBTZXQgc29tZSBpbmZvcm1hdGlvbiBhYm91dCBhIGZpbGUgYWZ0ZXIgd2UgYWRkIGl0LgorICovCit2b2lkIFppcEVudHJ5OjpzZXREYXRhSW5mbyhsb25nIHVuY29tcExlbiwgbG9uZyBjb21wTGVuLCB1bnNpZ25lZCBsb25nIGNyYzMyLAorICAgIGludCBjb21wcmVzc2lvbk1ldGhvZCkKK3sKKyAgICBtQ0RFLm1Db21wcmVzc2lvbk1ldGhvZCA9IGNvbXByZXNzaW9uTWV0aG9kOworICAgIG1DREUubUNSQzMyID0gY3JjMzI7CisgICAgbUNERS5tQ29tcHJlc3NlZFNpemUgPSBjb21wTGVuOworICAgIG1DREUubVVuY29tcHJlc3NlZFNpemUgPSB1bmNvbXBMZW47CisgICAgbUNERS5tQ29tcHJlc3Npb25NZXRob2QgPSBjb21wcmVzc2lvbk1ldGhvZDsKKyAgICBpZiAoY29tcHJlc3Npb25NZXRob2QgPT0ga0NvbXByZXNzRGVmbGF0ZWQpIHsKKyAgICAgICAgbUNERS5tR1BCaXRGbGFnIHw9IDB4MDAwMjsgICAgICAvLyBpbmRpY2F0ZXMgbWF4aW11bSBjb21wcmVzc2lvbiB1c2VkCisgICAgfQorICAgIGNvcHlDREV0b0xGSCgpOworfQorCisvKgorICogU2VlIGlmIHRoZSBkYXRhIGluIG1DREUgYW5kIG1MRkggbWF0Y2ggdXAuICBUaGlzIGlzIG1vc3RseSB1c2VmdWwgZm9yCisgKiBkZWJ1Z2dpbmcgdGhlc2UgY2xhc3NlcywgYnV0IGl0IGNhbiBiZSB1c2VkIHRvIGlkZW50aWZ5IGRhbWFnZWQKKyAqIGFyY2hpdmVzLgorICoKKyAqIFJldHVybnMgImZhbHNlIiBpZiB0aGV5IGRpZmZlci4KKyAqLworYm9vbCBaaXBFbnRyeTo6Y29tcGFyZUhlYWRlcnModm9pZCkgY29uc3QKK3sKKyAgICBpZiAobUNERS5tVmVyc2lvblRvRXh0cmFjdCAhPSBtTEZILm1WZXJzaW9uVG9FeHRyYWN0KSB7CisgICAgICAgIExPR1YoImNtcDogVmVyc2lvblRvRXh0cmFjdFxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKG1DREUubUdQQml0RmxhZyAhPSBtTEZILm1HUEJpdEZsYWcpIHsKKyAgICAgICAgTE9HVigiY21wOiBHUEJpdEZsYWdcbiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChtQ0RFLm1Db21wcmVzc2lvbk1ldGhvZCAhPSBtTEZILm1Db21wcmVzc2lvbk1ldGhvZCkgeworICAgICAgICBMT0dWKCJjbXA6IENvbXByZXNzaW9uTWV0aG9kXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAobUNERS5tTGFzdE1vZEZpbGVUaW1lICE9IG1MRkgubUxhc3RNb2RGaWxlVGltZSkgeworICAgICAgICBMT0dWKCJjbXA6IExhc3RNb2RGaWxlVGltZVxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKG1DREUubUxhc3RNb2RGaWxlRGF0ZSAhPSBtTEZILm1MYXN0TW9kRmlsZURhdGUpIHsKKyAgICAgICAgTE9HVigiY21wOiBMYXN0TW9kRmlsZURhdGVcbiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChtQ0RFLm1DUkMzMiAhPSBtTEZILm1DUkMzMikgeworICAgICAgICBMT0dWKCJjbXA6IENSQzMyXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAobUNERS5tQ29tcHJlc3NlZFNpemUgIT0gbUxGSC5tQ29tcHJlc3NlZFNpemUpIHsKKyAgICAgICAgTE9HVigiY21wOiBDb21wcmVzc2VkU2l6ZVxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKG1DREUubVVuY29tcHJlc3NlZFNpemUgIT0gbUxGSC5tVW5jb21wcmVzc2VkU2l6ZSkgeworICAgICAgICBMT0dWKCJjbXA6IFVuY29tcHJlc3NlZFNpemVcbiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChtQ0RFLm1GaWxlTmFtZUxlbmd0aCAhPSBtTEZILm1GaWxlTmFtZUxlbmd0aCkgeworICAgICAgICBMT0dWKCJjbXA6IEZpbGVOYW1lTGVuZ3RoXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyNpZiAwICAgICAgIC8vIHRoaXMgc2VlbXMgdG8gYmUgdXNlZCBmb3IgcGFkZGluZywgbm90IHJlYWwgZGF0YQorICAgIGlmIChtQ0RFLm1FeHRyYUZpZWxkTGVuZ3RoICE9IG1MRkgubUV4dHJhRmllbGRMZW5ndGgpIHsKKyAgICAgICAgTE9HVigiY21wOiBFeHRyYUZpZWxkTGVuZ3RoXG4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyNlbmRpZgorICAgIGlmIChtQ0RFLm1GaWxlTmFtZSAhPSBOVUxMKSB7CisgICAgICAgIGlmIChzdHJjbXAoKGNoYXIqKSBtQ0RFLm1GaWxlTmFtZSwgKGNoYXIqKSBtTEZILm1GaWxlTmFtZSkgIT0gMCkgeworICAgICAgICAgICAgTE9HVigiY21wOiBGaWxlTmFtZVxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKK30KKworCisvKgorICogQ29udmVydCB0aGUgRE9TIGRhdGUvdGltZSBzdGFtcCBpbnRvIGEgVU5JWCB0aW1lIHN0YW1wLgorICovCit0aW1lX3QgWmlwRW50cnk6OmdldE1vZFdoZW4odm9pZCkgY29uc3QKK3sKKyAgICBzdHJ1Y3QgdG0gcGFydHM7CisKKyAgICBwYXJ0cy50bV9zZWMgPSAobUNERS5tTGFzdE1vZEZpbGVUaW1lICYgMHgwMDFmKSA8PCAxOworICAgIHBhcnRzLnRtX21pbiA9IChtQ0RFLm1MYXN0TW9kRmlsZVRpbWUgJiAweDA3ZTApID4+IDU7CisgICAgcGFydHMudG1faG91ciA9IChtQ0RFLm1MYXN0TW9kRmlsZVRpbWUgJiAweGY4MDApID4+IDExOworICAgIHBhcnRzLnRtX21kYXkgPSAobUNERS5tTGFzdE1vZEZpbGVEYXRlICYgMHgwMDFmKTsKKyAgICBwYXJ0cy50bV9tb24gPSAoKG1DREUubUxhc3RNb2RGaWxlRGF0ZSAmIDB4MDFlMCkgPj4gNSkgLTE7CisgICAgcGFydHMudG1feWVhciA9ICgobUNERS5tTGFzdE1vZEZpbGVEYXRlICYgMHhmZTAwKSA+PiA5KSArIDgwOworICAgIHBhcnRzLnRtX3dkYXkgPSBwYXJ0cy50bV95ZGF5ID0gMDsKKyAgICBwYXJ0cy50bV9pc2RzdCA9IC0xOyAgICAgICAgLy8gRFNUIGluZm8gIm5vdCBhdmFpbGFibGUiCisKKyAgICByZXR1cm4gbWt0aW1lKCZwYXJ0cyk7Cit9CisKKy8qCisgKiBTZXQgdGhlIENERS9MRkggdGltZXN0YW1wIGZyb20gVU5JWCB0aW1lLgorICovCit2b2lkIFppcEVudHJ5OjpzZXRNb2RXaGVuKHRpbWVfdCB3aGVuKQoreworI2lmZGVmIEhBVkVfTE9DQUxUSU1FX1IKKyAgICBzdHJ1Y3QgdG0gdG1SZXN1bHQ7CisjZW5kaWYKKyAgICB0aW1lX3QgZXZlbjsKKyAgICB1bnNpZ25lZCBzaG9ydCB6ZGF0ZSwgenRpbWU7CisKKyAgICBzdHJ1Y3QgdG0qIHB0bTsKKworICAgIC8qIHJvdW5kIHVwIHRvIGFuIGV2ZW4gbnVtYmVyIG9mIHNlY29uZHMgKi8KKyAgICBldmVuID0gKHRpbWVfdCkoKCh1bnNpZ25lZCBsb25nKSh3aGVuKSArIDEpICYgKH4xKSk7CisKKyAgICAvKiBleHBhbmQgKi8KKyNpZmRlZiBIQVZFX0xPQ0FMVElNRV9SCisgICAgcHRtID0gbG9jYWx0aW1lX3IoJmV2ZW4sICZ0bVJlc3VsdCk7CisjZWxzZQorICAgIHB0bSA9IGxvY2FsdGltZSgmZXZlbik7CisjZW5kaWYKKworICAgIGludCB5ZWFyOworICAgIHllYXIgPSBwdG0tPnRtX3llYXI7CisgICAgaWYgKHllYXIgPCA4MCkKKyAgICAgICAgeWVhciA9IDgwOworCisgICAgemRhdGUgPSAoeWVhciAtIDgwKSA8PCA5IHwgKHB0bS0+dG1fbW9uKzEpIDw8IDUgfCBwdG0tPnRtX21kYXk7CisgICAgenRpbWUgPSBwdG0tPnRtX2hvdXIgPDwgMTEgfCBwdG0tPnRtX21pbiA8PCA1IHwgcHRtLT50bV9zZWMgPj4gMTsKKworICAgIG1DREUubUxhc3RNb2RGaWxlVGltZSA9IG1MRkgubUxhc3RNb2RGaWxlVGltZSA9IHp0aW1lOworICAgIG1DREUubUxhc3RNb2RGaWxlRGF0ZSA9IG1MRkgubUxhc3RNb2RGaWxlRGF0ZSA9IHpkYXRlOworfQorCisKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqICAgICAgWmlwRW50cnk6OkxvY2FsRmlsZUhlYWRlcgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworLyoKKyAqIFJlYWQgYSBsb2NhbCBmaWxlIGhlYWRlci4KKyAqCisgKiBPbiBlbnRyeSwgImZwIiBwb2ludHMgdG8gdGhlIHNpZ25hdHVyZSBhdCB0aGUgc3RhcnQgb2YgdGhlIGhlYWRlci4KKyAqIE9uIGV4aXQsICJmcCIgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiBkYXRhLgorICovCitzdGF0dXNfdCBaaXBFbnRyeTo6TG9jYWxGaWxlSGVhZGVyOjpyZWFkKEZJTEUqIGZwKQoreworICAgIHN0YXR1c190IHJlc3VsdCA9IE5PX0VSUk9SOworICAgIHVuc2lnbmVkIGNoYXIgYnVmW2tMRkhMZW5dOworCisgICAgYXNzZXJ0KG1GaWxlTmFtZSA9PSBOVUxMKTsKKyAgICBhc3NlcnQobUV4dHJhRmllbGQgPT0gTlVMTCk7CisKKyAgICBpZiAoZnJlYWQoYnVmLCAxLCBrTEZITGVuLCBmcCkgIT0ga0xGSExlbikgeworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgaWYgKFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDAwXSkgIT0ga1NpZ25hdHVyZSkgeworICAgICAgICBMT0dEKCJ3aG9vcHM6IGRpZG4ndCBmaW5kIGV4cGVjdGVkIHNpZ25hdHVyZVxuIik7CisgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICBtVmVyc2lvblRvRXh0cmFjdCA9IFppcEVudHJ5OjpnZXRTaG9ydExFKCZidWZbMHgwNF0pOworICAgIG1HUEJpdEZsYWcgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDZdKTsKKyAgICBtQ29tcHJlc3Npb25NZXRob2QgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDhdKTsKKyAgICBtTGFzdE1vZEZpbGVUaW1lID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDBhXSk7CisgICAgbUxhc3RNb2RGaWxlRGF0ZSA9IFppcEVudHJ5OjpnZXRTaG9ydExFKCZidWZbMHgwY10pOworICAgIG1DUkMzMiA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDBlXSk7CisgICAgbUNvbXByZXNzZWRTaXplID0gWmlwRW50cnk6OmdldExvbmdMRSgmYnVmWzB4MTJdKTsKKyAgICBtVW5jb21wcmVzc2VkU2l6ZSA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDE2XSk7CisgICAgbUZpbGVOYW1lTGVuZ3RoID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDFhXSk7CisgICAgbUV4dHJhRmllbGRMZW5ndGggPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MWNdKTsKKworICAgIC8vIFRPRE86IHZhbGlkYXRlIHNpemVzCisKKyAgICAvKiBncmFiIGZpbGVuYW1lICovCisgICAgaWYgKG1GaWxlTmFtZUxlbmd0aCAhPSAwKSB7CisgICAgICAgIG1GaWxlTmFtZSA9IG5ldyB1bnNpZ25lZCBjaGFyW21GaWxlTmFtZUxlbmd0aCsxXTsKKyAgICAgICAgaWYgKG1GaWxlTmFtZSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXN1bHQgPSBOT19NRU1PUlk7CisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZyZWFkKG1GaWxlTmFtZSwgMSwgbUZpbGVOYW1lTGVuZ3RoLCBmcCkgIT0gbUZpbGVOYW1lTGVuZ3RoKSB7CisgICAgICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisgICAgICAgIG1GaWxlTmFtZVttRmlsZU5hbWVMZW5ndGhdID0gJ1wwJzsKKyAgICB9CisKKyAgICAvKiBncmFiIGV4dHJhIGZpZWxkICovCisgICAgaWYgKG1FeHRyYUZpZWxkTGVuZ3RoICE9IDApIHsKKyAgICAgICAgbUV4dHJhRmllbGQgPSBuZXcgdW5zaWduZWQgY2hhclttRXh0cmFGaWVsZExlbmd0aCsxXTsKKyAgICAgICAgaWYgKG1FeHRyYUZpZWxkID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IE5PX01FTU9SWTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnJlYWQobUV4dHJhRmllbGQsIDEsIG1FeHRyYUZpZWxkTGVuZ3RoLCBmcCkgIT0gbUV4dHJhRmllbGRMZW5ndGgpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgIH0KKyAgICAgICAgbUV4dHJhRmllbGRbbUV4dHJhRmllbGRMZW5ndGhdID0gJ1wwJzsKKyAgICB9CisKK2JhaWw6CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAqIFdyaXRlIGEgbG9jYWwgZmlsZSBoZWFkZXIuCisgKi8KK3N0YXR1c190IFppcEVudHJ5OjpMb2NhbEZpbGVIZWFkZXI6OndyaXRlKEZJTEUqIGZwKQoreworICAgIHVuc2lnbmVkIGNoYXIgYnVmW2tMRkhMZW5dOworCisgICAgWmlwRW50cnk6OnB1dExvbmdMRSgmYnVmWzB4MDBdLCBrU2lnbmF0dXJlKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MDRdLCBtVmVyc2lvblRvRXh0cmFjdCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDA2XSwgbUdQQml0RmxhZyk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDA4XSwgbUNvbXByZXNzaW9uTWV0aG9kKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MGFdLCBtTGFzdE1vZEZpbGVUaW1lKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MGNdLCBtTGFzdE1vZEZpbGVEYXRlKTsKKyAgICBaaXBFbnRyeTo6cHV0TG9uZ0xFKCZidWZbMHgwZV0sIG1DUkMzMik7CisgICAgWmlwRW50cnk6OnB1dExvbmdMRSgmYnVmWzB4MTJdLCBtQ29tcHJlc3NlZFNpemUpOworICAgIFppcEVudHJ5OjpwdXRMb25nTEUoJmJ1ZlsweDE2XSwgbVVuY29tcHJlc3NlZFNpemUpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgxYV0sIG1GaWxlTmFtZUxlbmd0aCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDFjXSwgbUV4dHJhRmllbGRMZW5ndGgpOworCisgICAgaWYgKGZ3cml0ZShidWYsIDEsIGtMRkhMZW4sIGZwKSAhPSBrTEZITGVuKQorICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKworICAgIC8qIHdyaXRlIGZpbGVuYW1lICovCisgICAgaWYgKG1GaWxlTmFtZUxlbmd0aCAhPSAwKSB7CisgICAgICAgIGlmIChmd3JpdGUobUZpbGVOYW1lLCAxLCBtRmlsZU5hbWVMZW5ndGgsIGZwKSAhPSBtRmlsZU5hbWVMZW5ndGgpCisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisKKyAgICAvKiB3cml0ZSAiZXh0cmEgZmllbGQiICovCisgICAgaWYgKG1FeHRyYUZpZWxkTGVuZ3RoICE9IDApIHsKKyAgICAgICAgaWYgKGZ3cml0ZShtRXh0cmFGaWVsZCwgMSwgbUV4dHJhRmllbGRMZW5ndGgsIGZwKSAhPSBtRXh0cmFGaWVsZExlbmd0aCkKKyAgICAgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworCisvKgorICogRHVtcCB0aGUgY29udGVudHMgb2YgYSBMb2NhbEZpbGVIZWFkZXIgb2JqZWN0LgorICovCit2b2lkIFppcEVudHJ5OjpMb2NhbEZpbGVIZWFkZXI6OmR1bXAodm9pZCkgY29uc3QKK3sKKyAgICBMT0dEKCIgTG9jYWxGaWxlSGVhZGVyIGNvbnRlbnRzOlxuIik7CisgICAgTE9HRCgiICB2ZXJzVG9FeHQ9JXUgZ3BCaXRzPTB4JTA0eCBjb21wcmVzc2lvbj0ldVxuIiwKKyAgICAgICAgbVZlcnNpb25Ub0V4dHJhY3QsIG1HUEJpdEZsYWcsIG1Db21wcmVzc2lvbk1ldGhvZCk7CisgICAgTE9HRCgiICBtb2RUaW1lPTB4JTA0eCBtb2REYXRlPTB4JTA0eCBjcmMzMj0weCUwOGx4XG4iLAorICAgICAgICBtTGFzdE1vZEZpbGVUaW1lLCBtTGFzdE1vZEZpbGVEYXRlLCBtQ1JDMzIpOworICAgIExPR0QoIiAgY29tcHJlc3NlZFNpemU9JWx1IHVuY29tcHJlc3NlZFNpemU9JWx1XG4iLAorICAgICAgICBtQ29tcHJlc3NlZFNpemUsIG1VbmNvbXByZXNzZWRTaXplKTsKKyAgICBMT0dEKCIgIGZpbGVuYW1lTGVuPSV1IGV4dHJhTGVuPSV1XG4iLAorICAgICAgICBtRmlsZU5hbWVMZW5ndGgsIG1FeHRyYUZpZWxkTGVuZ3RoKTsKKyAgICBpZiAobUZpbGVOYW1lICE9IE5VTEwpCisgICAgICAgIExPR0QoIiAgZmlsZW5hbWU6ICclcydcbiIsIG1GaWxlTmFtZSk7Cit9CisKKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogICAgICBaaXBFbnRyeTo6Q2VudHJhbERpckVudHJ5CisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqLworCisvKgorICogUmVhZCB0aGUgY2VudHJhbCBkaXIgZW50cnkgdGhhdCBhcHBlYXJzIG5leHQgaW4gdGhlIGZpbGUuCisgKgorICogT24gZW50cnksICJmcCIgc2hvdWxkIGJlIHBvc2l0aW9uZWQgb24gdGhlIHNpZ25hdHVyZSBieXRlcyBmb3IgdGhlCisgKiBlbnRyeS4gIE9uIGV4aXQsICJmcCIgd2lsbCBwb2ludCBhdCB0aGUgc2lnbmF0dXJlIHdvcmQgZm9yIHRoZSBuZXh0CisgKiBlbnRyeSBvciBmb3IgdGhlIEVPQ0QuCisgKi8KK3N0YXR1c190IFppcEVudHJ5OjpDZW50cmFsRGlyRW50cnk6OnJlYWQoRklMRSogZnApCit7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gTk9fRVJST1I7CisgICAgdW5zaWduZWQgY2hhciBidWZba0NERUxlbl07CisKKyAgICAvKiBubyByZS11c2UgKi8KKyAgICBhc3NlcnQobUZpbGVOYW1lID09IE5VTEwpOworICAgIGFzc2VydChtRXh0cmFGaWVsZCA9PSBOVUxMKTsKKyAgICBhc3NlcnQobUZpbGVDb21tZW50ID09IE5VTEwpOworCisgICAgaWYgKGZyZWFkKGJ1ZiwgMSwga0NERUxlbiwgZnApICE9IGtDREVMZW4pIHsKKyAgICAgICAgcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIGlmIChaaXBFbnRyeTo6Z2V0TG9uZ0xFKCZidWZbMHgwMF0pICE9IGtTaWduYXR1cmUpIHsKKyAgICAgICAgTE9HRCgiV2hvb3BzOiBkaWRuJ3QgZmluZCBleHBlY3RlZCBzaWduYXR1cmVcbiIpOworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgbVZlcnNpb25NYWRlQnkgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDRdKTsKKyAgICBtVmVyc2lvblRvRXh0cmFjdCA9IFppcEVudHJ5OjpnZXRTaG9ydExFKCZidWZbMHgwNl0pOworICAgIG1HUEJpdEZsYWcgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDhdKTsKKyAgICBtQ29tcHJlc3Npb25NZXRob2QgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MGFdKTsKKyAgICBtTGFzdE1vZEZpbGVUaW1lID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDBjXSk7CisgICAgbUxhc3RNb2RGaWxlRGF0ZSA9IFppcEVudHJ5OjpnZXRTaG9ydExFKCZidWZbMHgwZV0pOworICAgIG1DUkMzMiA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDEwXSk7CisgICAgbUNvbXByZXNzZWRTaXplID0gWmlwRW50cnk6OmdldExvbmdMRSgmYnVmWzB4MTRdKTsKKyAgICBtVW5jb21wcmVzc2VkU2l6ZSA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDE4XSk7CisgICAgbUZpbGVOYW1lTGVuZ3RoID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDFjXSk7CisgICAgbUV4dHJhRmllbGRMZW5ndGggPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MWVdKTsKKyAgICBtRmlsZUNvbW1lbnRMZW5ndGggPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MjBdKTsKKyAgICBtRGlza051bWJlclN0YXJ0ID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDIyXSk7CisgICAgbUludGVybmFsQXR0cnMgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MjRdKTsKKyAgICBtRXh0ZXJuYWxBdHRycyA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDI2XSk7CisgICAgbUxvY2FsSGVhZGVyUmVsT2Zmc2V0ID0gWmlwRW50cnk6OmdldExvbmdMRSgmYnVmWzB4MmFdKTsKKworICAgIC8vIFRPRE86IHZhbGlkYXRlIHNpemVzIGFuZCBvZmZzZXRzCisKKyAgICAvKiBncmFiIGZpbGVuYW1lICovCisgICAgaWYgKG1GaWxlTmFtZUxlbmd0aCAhPSAwKSB7CisgICAgICAgIG1GaWxlTmFtZSA9IG5ldyB1bnNpZ25lZCBjaGFyW21GaWxlTmFtZUxlbmd0aCsxXTsKKyAgICAgICAgaWYgKG1GaWxlTmFtZSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXN1bHQgPSBOT19NRU1PUlk7CisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZyZWFkKG1GaWxlTmFtZSwgMSwgbUZpbGVOYW1lTGVuZ3RoLCBmcCkgIT0gbUZpbGVOYW1lTGVuZ3RoKSB7CisgICAgICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisgICAgICAgIG1GaWxlTmFtZVttRmlsZU5hbWVMZW5ndGhdID0gJ1wwJzsKKyAgICB9CisKKyAgICAvKiByZWFkICJleHRyYSBmaWVsZCIgKi8KKyAgICBpZiAobUV4dHJhRmllbGRMZW5ndGggIT0gMCkgeworICAgICAgICBtRXh0cmFGaWVsZCA9IG5ldyB1bnNpZ25lZCBjaGFyW21FeHRyYUZpZWxkTGVuZ3RoKzFdOworICAgICAgICBpZiAobUV4dHJhRmllbGQgPT0gTlVMTCkgeworICAgICAgICAgICAgcmVzdWx0ID0gTk9fTUVNT1JZOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisgICAgICAgIGlmIChmcmVhZChtRXh0cmFGaWVsZCwgMSwgbUV4dHJhRmllbGRMZW5ndGgsIGZwKSAhPSBtRXh0cmFGaWVsZExlbmd0aCkgeworICAgICAgICAgICAgcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgICAgICBtRXh0cmFGaWVsZFttRXh0cmFGaWVsZExlbmd0aF0gPSAnXDAnOworICAgIH0KKworCisgICAgLyogZ3JhYiBjb21tZW50LCBpZiBhbnkgKi8KKyAgICBpZiAobUZpbGVDb21tZW50TGVuZ3RoICE9IDApIHsKKyAgICAgICAgbUZpbGVDb21tZW50ID0gbmV3IHVuc2lnbmVkIGNoYXJbbUZpbGVDb21tZW50TGVuZ3RoKzFdOworICAgICAgICBpZiAobUZpbGVDb21tZW50ID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IE5PX01FTU9SWTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnJlYWQobUZpbGVDb21tZW50LCAxLCBtRmlsZUNvbW1lbnRMZW5ndGgsIGZwKSAhPSBtRmlsZUNvbW1lbnRMZW5ndGgpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgIH0KKyAgICAgICAgbUZpbGVDb21tZW50W21GaWxlQ29tbWVudExlbmd0aF0gPSAnXDAnOworICAgIH0KKworYmFpbDoKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKgorICogV3JpdGUgYSBjZW50cmFsIGRpciBlbnRyeS4KKyAqLworc3RhdHVzX3QgWmlwRW50cnk6OkNlbnRyYWxEaXJFbnRyeTo6d3JpdGUoRklMRSogZnApCit7CisgICAgdW5zaWduZWQgY2hhciBidWZba0NERUxlbl07CisKKyAgICBaaXBFbnRyeTo6cHV0TG9uZ0xFKCZidWZbMHgwMF0sIGtTaWduYXR1cmUpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgwNF0sIG1WZXJzaW9uTWFkZUJ5KTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MDZdLCBtVmVyc2lvblRvRXh0cmFjdCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDA4XSwgbUdQQml0RmxhZyk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDBhXSwgbUNvbXByZXNzaW9uTWV0aG9kKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MGNdLCBtTGFzdE1vZEZpbGVUaW1lKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MGVdLCBtTGFzdE1vZEZpbGVEYXRlKTsKKyAgICBaaXBFbnRyeTo6cHV0TG9uZ0xFKCZidWZbMHgxMF0sIG1DUkMzMik7CisgICAgWmlwRW50cnk6OnB1dExvbmdMRSgmYnVmWzB4MTRdLCBtQ29tcHJlc3NlZFNpemUpOworICAgIFppcEVudHJ5OjpwdXRMb25nTEUoJmJ1ZlsweDE4XSwgbVVuY29tcHJlc3NlZFNpemUpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgxY10sIG1GaWxlTmFtZUxlbmd0aCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDFlXSwgbUV4dHJhRmllbGRMZW5ndGgpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgyMF0sIG1GaWxlQ29tbWVudExlbmd0aCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDIyXSwgbURpc2tOdW1iZXJTdGFydCk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDI0XSwgbUludGVybmFsQXR0cnMpOworICAgIFppcEVudHJ5OjpwdXRMb25nTEUoJmJ1ZlsweDI2XSwgbUV4dGVybmFsQXR0cnMpOworICAgIFppcEVudHJ5OjpwdXRMb25nTEUoJmJ1ZlsweDJhXSwgbUxvY2FsSGVhZGVyUmVsT2Zmc2V0KTsKKworICAgIGlmIChmd3JpdGUoYnVmLCAxLCBrQ0RFTGVuLCBmcCkgIT0ga0NERUxlbikKKyAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisKKyAgICAvKiB3cml0ZSBmaWxlbmFtZSAqLworICAgIGlmIChtRmlsZU5hbWVMZW5ndGggIT0gMCkgeworICAgICAgICBpZiAoZndyaXRlKG1GaWxlTmFtZSwgMSwgbUZpbGVOYW1lTGVuZ3RoLCBmcCkgIT0gbUZpbGVOYW1lTGVuZ3RoKQorICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgfQorCisgICAgLyogd3JpdGUgImV4dHJhIGZpZWxkIiAqLworICAgIGlmIChtRXh0cmFGaWVsZExlbmd0aCAhPSAwKSB7CisgICAgICAgIGlmIChmd3JpdGUobUV4dHJhRmllbGQsIDEsIG1FeHRyYUZpZWxkTGVuZ3RoLCBmcCkgIT0gbUV4dHJhRmllbGRMZW5ndGgpCisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisKKyAgICAvKiB3cml0ZSBjb21tZW50ICovCisgICAgaWYgKG1GaWxlQ29tbWVudExlbmd0aCAhPSAwKSB7CisgICAgICAgIGlmIChmd3JpdGUobUZpbGVDb21tZW50LCAxLCBtRmlsZUNvbW1lbnRMZW5ndGgsIGZwKSAhPSBtRmlsZUNvbW1lbnRMZW5ndGgpCisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBEdW1wIHRoZSBjb250ZW50cyBvZiBhIENlbnRyYWxEaXJFbnRyeSBvYmplY3QuCisgKi8KK3ZvaWQgWmlwRW50cnk6OkNlbnRyYWxEaXJFbnRyeTo6ZHVtcCh2b2lkKSBjb25zdAoreworICAgIExPR0QoIiBDZW50cmFsRGlyRW50cnkgY29udGVudHM6XG4iKTsKKyAgICBMT0dEKCIgIHZlcnNNYWRlQnk9JXUgdmVyc1RvRXh0PSV1IGdwQml0cz0weCUwNHggY29tcHJlc3Npb249JXVcbiIsCisgICAgICAgIG1WZXJzaW9uTWFkZUJ5LCBtVmVyc2lvblRvRXh0cmFjdCwgbUdQQml0RmxhZywgbUNvbXByZXNzaW9uTWV0aG9kKTsKKyAgICBMT0dEKCIgIG1vZFRpbWU9MHglMDR4IG1vZERhdGU9MHglMDR4IGNyYzMyPTB4JTA4bHhcbiIsCisgICAgICAgIG1MYXN0TW9kRmlsZVRpbWUsIG1MYXN0TW9kRmlsZURhdGUsIG1DUkMzMik7CisgICAgTE9HRCgiICBjb21wcmVzc2VkU2l6ZT0lbHUgdW5jb21wcmVzc2VkU2l6ZT0lbHVcbiIsCisgICAgICAgIG1Db21wcmVzc2VkU2l6ZSwgbVVuY29tcHJlc3NlZFNpemUpOworICAgIExPR0QoIiAgZmlsZW5hbWVMZW49JXUgZXh0cmFMZW49JXUgY29tbWVudExlbj0ldVxuIiwKKyAgICAgICAgbUZpbGVOYW1lTGVuZ3RoLCBtRXh0cmFGaWVsZExlbmd0aCwgbUZpbGVDb21tZW50TGVuZ3RoKTsKKyAgICBMT0dEKCIgIGRpc2tOdW1TdGFydD0ldSBpbnRBdHRyPTB4JTA0eCBleHRBdHRyPTB4JTA4bHggcmVsT2Zmc2V0PSVsdVxuIiwKKyAgICAgICAgbURpc2tOdW1iZXJTdGFydCwgbUludGVybmFsQXR0cnMsIG1FeHRlcm5hbEF0dHJzLAorICAgICAgICBtTG9jYWxIZWFkZXJSZWxPZmZzZXQpOworCisgICAgaWYgKG1GaWxlTmFtZSAhPSBOVUxMKQorICAgICAgICBMT0dEKCIgIGZpbGVuYW1lOiAnJXMnXG4iLCBtRmlsZU5hbWUpOworICAgIGlmIChtRmlsZUNvbW1lbnQgIT0gTlVMTCkKKyAgICAgICAgTE9HRCgiICBjb21tZW50OiAnJXMnXG4iLCBtRmlsZUNvbW1lbnQpOworfQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL1ppcEZpbGUuY3BwIGIvbGlicy91dGlscy9aaXBGaWxlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWFhODc0Ci0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9aaXBGaWxlLmNwcApAQCAtMCwwICsxLDEyOTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gQWNjZXNzIHRvIFppcCBhcmNoaXZlcy4KKy8vCisKKyNkZWZpbmUgTE9HX1RBRyAiemlwIgorCisjaW5jbHVkZSAidXRpbHMvWmlwRmlsZS5oIgorI2luY2x1ZGUgInV0aWxzL1ppcFV0aWxzLmgiCisjaW5jbHVkZSAidXRpbHMvTG9nLmgiCisKKyNpbmNsdWRlIDx6bGliLmg+CisjZGVmaW5lIERFRl9NRU1fTEVWRUwgOCAgICAgICAgICAgICAgICAvLyBub3JtYWxseSBpbiB6dXRpbC5oPworCisjaW5jbHVkZSA8bWVtb3J5Lmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGFzc2VydC5oPgorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworLyoKKyAqIFNvbWUgZW52aXJvbm1lbnRzIHJlcXVpcmUgdGhlICJiIiwgc29tZSBjaG9rZSBvbiBpdC4KKyAqLworI2RlZmluZSBGSUxFX09QRU5fUk8gICAgICAgICJyYiIKKyNkZWZpbmUgRklMRV9PUEVOX1JXICAgICAgICAicitiIgorI2RlZmluZSBGSUxFX09QRU5fUldfQ1JFQVRFICJ3K2IiCisKKy8qIHNob3VsZCBsaXZlIHNvbWV3aGVyZSBlbHNlPyAqLworc3RhdGljIHN0YXR1c190IGVycm5vVG9TdGF0dXMoaW50IGVycikKK3sKKyAgICBpZiAoZXJyID09IEVOT0VOVCkKKyAgICAgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworICAgIGVsc2UgaWYgKGVyciA9PSBFQUNDRVMpCisgICAgICAgIHJldHVybiBQRVJNSVNTSU9OX0RFTklFRDsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworfQorCisvKgorICogT3BlbiBhIGZpbGUgYW5kIHBhcnNlIGl0cyBndXRzLgorICovCitzdGF0dXNfdCBaaXBGaWxlOjpvcGVuKGNvbnN0IGNoYXIqIHppcEZpbGVOYW1lLCBpbnQgZmxhZ3MpCit7CisgICAgYm9vbCBuZXdBcmNoaXZlID0gZmFsc2U7CisKKyAgICBhc3NlcnQobVppcEZwID09IE5VTEwpOyAgICAgLy8gbm8gcmVvcGVuCisKKyAgICBpZiAoKGZsYWdzICYga09wZW5UcnVuY2F0ZSkpCisgICAgICAgIGZsYWdzIHw9IGtPcGVuQ3JlYXRlOyAgICAgICAgICAgLy8gdHJ1bmMgaW1wbGllcyBjcmVhdGUKKworICAgIGlmICgoZmxhZ3MgJiBrT3BlblJlYWRPbmx5KSAmJiAoZmxhZ3MgJiBrT3BlblJlYWRXcml0ZSkpCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsgICAgICAgLy8gbm90IGJvdGgKKyAgICBpZiAoISgoZmxhZ3MgJiBrT3BlblJlYWRPbmx5KSB8fCAoZmxhZ3MgJiBrT3BlblJlYWRXcml0ZSkpKQorICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047ICAgICAgIC8vIG5vdCBuZWl0aGVyCisgICAgaWYgKChmbGFncyAmIGtPcGVuQ3JlYXRlKSAmJiAhKGZsYWdzICYga09wZW5SZWFkV3JpdGUpKQorICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047ICAgICAgIC8vIGNyZWF0ZSByZXF1aXJlcyB3cml0ZQorCisgICAgaWYgKGZsYWdzICYga09wZW5UcnVuY2F0ZSkgeworICAgICAgICBuZXdBcmNoaXZlID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgICBuZXdBcmNoaXZlID0gKGFjY2Vzcyh6aXBGaWxlTmFtZSwgRl9PSykgIT0gMCk7CisgICAgICAgIGlmICghKGZsYWdzICYga09wZW5DcmVhdGUpICYmIG5ld0FyY2hpdmUpIHsKKyAgICAgICAgICAgIC8qIG5vdCBjcmVhdGluZywgbXVzdCBhbHJlYWR5IGV4aXN0ICovCisgICAgICAgICAgICBMT0dEKCJGaWxlICVzIGRvZXMgbm90IGV4aXN0IiwgemlwRmlsZU5hbWUpOworICAgICAgICAgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworICAgICAgICB9CisgICAgfQorCisgICAgLyogb3BlbiB0aGUgZmlsZSAqLworICAgIGNvbnN0IGNoYXIqIG9wZW5mbGFnczsKKyAgICBpZiAoZmxhZ3MgJiBrT3BlblJlYWRXcml0ZSkgeworICAgICAgICBpZiAobmV3QXJjaGl2ZSkKKyAgICAgICAgICAgIG9wZW5mbGFncyA9IEZJTEVfT1BFTl9SV19DUkVBVEU7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG9wZW5mbGFncyA9IEZJTEVfT1BFTl9SVzsKKyAgICB9IGVsc2UgeworICAgICAgICBvcGVuZmxhZ3MgPSBGSUxFX09QRU5fUk87CisgICAgfQorICAgIG1aaXBGcCA9IGZvcGVuKHppcEZpbGVOYW1lLCBvcGVuZmxhZ3MpOworICAgIGlmIChtWmlwRnAgPT0gTlVMTCkgeworCQlpbnQgZXJyID0gZXJybm87CisJCUxPR0QoImZvcGVuIGZhaWxlZDogJWRcbiIsIGVycik7CisgICAgICAgIHJldHVybiBlcnJub1RvU3RhdHVzKGVycik7CisJfQorCisgICAgc3RhdHVzX3QgcmVzdWx0OworICAgIGlmICghbmV3QXJjaGl2ZSkgeworICAgICAgICAvKgorICAgICAgICAgKiBMb2FkIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4gIElmIHRoYXQgZmFpbHMsIHRoZW4gdGhpcyBwcm9iYWJseQorICAgICAgICAgKiBpc24ndCBhIFppcCBhcmNoaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgcmVzdWx0ID0gcmVhZENlbnRyYWxEaXIoKTsKKyAgICB9IGVsc2UgeworICAgICAgICAvKgorICAgICAgICAgKiBOZXdseS1jcmVhdGVkLiAgVGhlIEVuZE9mQ2VudHJhbERpciBjb25zdHJ1Y3RvciBhY3R1YWxseQorICAgICAgICAgKiBzZXRzIGV2ZXJ5dGhpbmcgdG8gYmUgdGhlIHdheSB3ZSB3YW50IGl0IChhbGwgemVyb2VzKS4gIFdlCisgICAgICAgICAqIHNldCBtTmVlZENEUmV3cml0ZSBzbyB0aGF0IHdlIGNyZWF0ZSAqc29tZXRoaW5nKiBpZiB0aGUKKyAgICAgICAgICogY2FsbGVyIGRvZXNuJ3QgYWRkIGFueSBmaWxlcy4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdW5saW5rCisgICAgICAgICAqIHRoZSBmaWxlIGlmIGl0J3MgYnJhbmQgbmV3IGFuZCBub3RoaW5nIHdhcyBhZGRlZCwgYnV0IHRoYXQncworICAgICAgICAgKiBwcm9iYWJseSBkb2luZyBtb3JlIHRoYW4gd2UgcmVhbGx5IHNob3VsZCAtLSB0aGUgdXNlciBtaWdodAorICAgICAgICAgKiBoYXZlIGEgbmVlZCBmb3IgZW1wdHkgemlwIGZpbGVzLikKKyAgICAgICAgICovCisgICAgICAgIG1OZWVkQ0RSZXdyaXRlID0gdHJ1ZTsKKyAgICAgICAgcmVzdWx0ID0gTk9fRVJST1I7CisgICAgfQorCisgICAgaWYgKGZsYWdzICYga09wZW5SZWFkT25seSkKKyAgICAgICAgbVJlYWRPbmx5ID0gdHJ1ZTsKKyAgICBlbHNlCisgICAgICAgIGFzc2VydCghbVJlYWRPbmx5KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBSZXR1cm4gdGhlIE50aCBlbnRyeSBpbiB0aGUgYXJjaGl2ZS4KKyAqLworWmlwRW50cnkqIFppcEZpbGU6OmdldEVudHJ5QnlJbmRleChpbnQgaWR4KSBjb25zdAoreworICAgIGlmIChpZHggPCAwIHx8IGlkeCA+PSAoaW50KSBtRW50cmllcy5zaXplKCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmV0dXJuIG1FbnRyaWVzW2lkeF07Cit9CisKKy8qCisgKiBGaW5kIGFuIGVudHJ5IGJ5IG5hbWUuCisgKi8KK1ppcEVudHJ5KiBaaXBGaWxlOjpnZXRFbnRyeUJ5TmFtZShjb25zdCBjaGFyKiBmaWxlTmFtZSkgY29uc3QKK3sKKyAgICAvKgorICAgICAqIERvIGEgc3R1cGlkIGxpbmVhciBzdHJpbmctY29tcGFyZSBzZWFyY2guCisgICAgICoKKyAgICAgKiBUaGVyZSBhcmUgdmFyaW91cyB3YXlzIHRvIHNwZWVkIHRoaXMgdXAsIGVzcGVjaWFsbHkgc2luY2UgaXQncyByYXJlCisgICAgICogdG8gaW50ZXJtaW5nbGUgY2hhbmdlcyB0byB0aGUgYXJjaGl2ZSB3aXRoICJnZXQgYnkgbmFtZSIgY2FsbHMuICBXZQorICAgICAqIGRvbid0IHdhbnQgdG8gc29ydCB0aGUgbUVudHJpZXMgdmVjdG9yIGl0c2VsZiwgaG93ZXZlciwgYmVjYXVzZQorICAgICAqIGl0J3MgdXNlZCB0byByZWNyZWF0ZSB0aGUgQ2VudHJhbCBEaXJlY3RvcnkuCisgICAgICoKKyAgICAgKiAoSGFzaCB0YWJsZSB3b3JrcywgcGFyYWxsZWwgbGlzdCBvZiBwb2ludGVycyBpbiBzb3J0ZWQgb3JkZXIgaXMgZ29vZC4pCisgICAgICovCisgICAgaW50IGlkeDsKKworICAgIGZvciAoaWR4ID0gbUVudHJpZXMuc2l6ZSgpLTE7IGlkeCA+PSAwOyBpZHgtLSkgeworICAgICAgICBaaXBFbnRyeSogcEVudHJ5ID0gbUVudHJpZXNbaWR4XTsKKyAgICAgICAgaWYgKCFwRW50cnktPmdldERlbGV0ZWQoKSAmJgorICAgICAgICAgICAgc3RyY21wKGZpbGVOYW1lLCBwRW50cnktPmdldEZpbGVOYW1lKCkpID09IDApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBwRW50cnk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoKKyAqIEVtcHR5IHRoZSBtRW50cmllcyB2ZWN0b3IuCisgKi8KK3ZvaWQgWmlwRmlsZTo6ZGlzY2FyZEVudHJpZXModm9pZCkKK3sKKyAgICBpbnQgY291bnQgPSBtRW50cmllcy5zaXplKCk7CisKKyAgICB3aGlsZSAoLS1jb3VudCA+PSAwKQorICAgICAgICBkZWxldGUgbUVudHJpZXNbY291bnRdOworCisgICAgbUVudHJpZXMuY2xlYXIoKTsKK30KKworCisvKgorICogRmluZCB0aGUgY2VudHJhbCBkaXJlY3RvcnkgYW5kIHJlYWQgdGhlIGNvbnRlbnRzLgorICoKKyAqIFRoZSBmdW4gdGhpbmcgYWJvdXQgWklQIGFyY2hpdmVzIGlzIHRoYXQgdGhleSBtYXkgb3IgbWF5IG5vdCBiZQorICogcmVhZGFibGUgZnJvbSBzdGFydCB0byBlbmQuICBJbiBzb21lIGNhc2VzLCBub3RhYmx5IGZvciBhcmNoaXZlcworICogdGhhdCB3ZXJlIHdyaXR0ZW4gdG8gc3Rkb3V0LCB0aGUgb25seSBsZW5ndGggaW5mb3JtYXRpb24gaXMgaW4gdGhlCisgKiBjZW50cmFsIGRpcmVjdG9yeSBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlLgorICoKKyAqIE9mIGNvdXJzZSwgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGNhbiBiZSBmb2xsb3dlZCBieSBhIHZhcmlhYmxlLWxlbmd0aAorICogY29tbWVudCBmaWVsZCwgc28gd2UgaGF2ZSB0byBzY2FuIHRocm91Z2ggaXQgYmFja3dhcmRzLiAgVGhlIGNvbW1lbnQKKyAqIGlzIGF0IG1vc3QgNjRLLCBwbHVzIHdlIGhhdmUgMTggYnl0ZXMgZm9yIHRoZSBlbmQtb2YtY2VudHJhbC1kaXIgc3R1ZmYKKyAqIGl0c2VsZiwgcGx1cyBhcHBhcmVudGx5IHNvbWV0aW1lcyBwZW9wbGUgdGhyb3cgcmFuZG9tIGp1bmsgb24gdGhlIGVuZAorICoganVzdCBmb3IgdGhlIGZ1biBvZiBpdC4KKyAqCisgKiBUaGlzIGlzIGFsbCBhIGxpdHRsZSB3b2JibHkuICBJZiB0aGUgd3JvbmcgdmFsdWUgZW5kcyB1cCBpbiB0aGUgRU9DRAorICogYXJlYSwgd2UncmUgaG9zZWQuICBUaGlzIGFwcGVhcnMgdG8gYmUgdGhlIHdheSB0aGF0IGV2ZXJib2R5IGhhbmRsZXMKKyAqIGl0IHRob3VnaCwgc28gd2UncmUgaW4gcHJldHR5IGdvb2QgY29tcGFueSBpZiB0aGlzIGZhaWxzLgorICovCitzdGF0dXNfdCBaaXBGaWxlOjpyZWFkQ2VudHJhbERpcih2b2lkKQoreworICAgIHN0YXR1c190IHJlc3VsdCA9IE5PX0VSUk9SOworICAgIHVuc2lnbmVkIGNoYXIqIGJ1ZiA9IE5VTEw7CisgICAgb2ZmX3QgZmlsZUxlbmd0aCwgc2Vla1N0YXJ0OworICAgIGxvbmcgcmVhZEFtb3VudDsKKyAgICBpbnQgaTsKKworICAgIGZzZWVrKG1aaXBGcCwgMCwgU0VFS19FTkQpOworICAgIGZpbGVMZW5ndGggPSBmdGVsbChtWmlwRnApOworICAgIHJld2luZChtWmlwRnApOworCisgICAgLyogdG9vIHNtYWxsIHRvIGJlIGEgWklQIGFyY2hpdmU/ICovCisgICAgaWYgKGZpbGVMZW5ndGggPCBFbmRPZkNlbnRyYWxEaXI6OmtFT0NETGVuKSB7CisgICAgICAgIExPR0QoIkxlbmd0aCBpcyAlbGQgLS0gdG9vIHNtYWxsXG4iLCAobG9uZylmaWxlTGVuZ3RoKTsKKyAgICAgICAgcmVzdWx0ID0gSU5WQUxJRF9PUEVSQVRJT047CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICBidWYgPSBuZXcgdW5zaWduZWQgY2hhcltFbmRPZkNlbnRyYWxEaXI6OmtNYXhFT0NEU2VhcmNoXTsKKyAgICBpZiAoYnVmID09IE5VTEwpIHsKKwkJTE9HRCgiRmFpbHVyZSBhbGxvY2F0aW5nICVkIGJ5dGVzIGZvciBFT0NEIHNlYXJjaCIsCisJCQkgRW5kT2ZDZW50cmFsRGlyOjprTWF4RU9DRFNlYXJjaCk7CisgICAgICAgIHJlc3VsdCA9IE5PX01FTU9SWTsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIGlmIChmaWxlTGVuZ3RoID4gRW5kT2ZDZW50cmFsRGlyOjprTWF4RU9DRFNlYXJjaCkgeworICAgICAgICBzZWVrU3RhcnQgPSBmaWxlTGVuZ3RoIC0gRW5kT2ZDZW50cmFsRGlyOjprTWF4RU9DRFNlYXJjaDsKKyAgICAgICAgcmVhZEFtb3VudCA9IEVuZE9mQ2VudHJhbERpcjo6a01heEVPQ0RTZWFyY2g7CisgICAgfSBlbHNlIHsKKyAgICAgICAgc2Vla1N0YXJ0ID0gMDsKKyAgICAgICAgcmVhZEFtb3VudCA9IChsb25nKSBmaWxlTGVuZ3RoOworICAgIH0KKyAgICBpZiAoZnNlZWsobVppcEZwLCBzZWVrU3RhcnQsIFNFRUtfU0VUKSAhPSAwKSB7CisJCUxPR0QoIkZhaWx1cmUgc2Vla2luZyB0byBlbmQgb2YgemlwIGF0ICVsZCIsIChsb25nKSBzZWVrU3RhcnQpOworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyogcmVhZCB0aGUgbGFzdCBwYXJ0IG9mIHRoZSBmaWxlIGludG8gdGhlIGJ1ZmZlciAqLworICAgIGlmIChmcmVhZChidWYsIDEsIHJlYWRBbW91bnQsIG1aaXBGcCkgIT0gKHNpemVfdCkgcmVhZEFtb3VudCkgeworICAgICAgICBMT0dEKCJzaG9ydCBmaWxlPyB3YW50ZWQgJWxkXG4iLCByZWFkQW1vdW50KTsKKyAgICAgICAgcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qIGZpbmQgdGhlIGVuZC1vZi1jZW50cmFsLWRpciBtYWdpYyAqLworICAgIGZvciAoaSA9IHJlYWRBbW91bnQgLSA0OyBpID49IDA7IGktLSkgeworICAgICAgICBpZiAoYnVmW2ldID09IDB4NTAgJiYKKyAgICAgICAgICAgIFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZltpXSkgPT0gRW5kT2ZDZW50cmFsRGlyOjprU2lnbmF0dXJlKQorICAgICAgICB7CisgICAgICAgICAgICBMT0dWKCIrKysgRm91bmQgRU9DRCBhdCBidWYrJWRcbiIsIGkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGkgPCAwKSB7CisgICAgICAgIExPR0QoIkVPQ0Qgbm90IGZvdW5kLCBub3QgWmlwXG4iKTsKKyAgICAgICAgcmVzdWx0ID0gSU5WQUxJRF9PUEVSQVRJT047CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICAvKiBleHRyYWN0IGVvY2QgdmFsdWVzICovCisgICAgcmVzdWx0ID0gbUVPQ0QucmVhZEJ1ZihidWYgKyBpLCByZWFkQW1vdW50IC0gaSk7CisgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgeworCQlMT0dEKCJGYWlsdXJlIHJlYWRpbmcgJWxkIGJ5dGVzIG9mIEVPQ0QgdmFsdWVzIiwgcmVhZEFtb3VudCAtIGkpOworICAgICAgICBnb3RvIGJhaWw7CisJfQorICAgIC8vbUVPQ0QuZHVtcCgpOworCisgICAgaWYgKG1FT0NELm1EaXNrTnVtYmVyICE9IDAgfHwgbUVPQ0QubURpc2tXaXRoQ2VudHJhbERpciAhPSAwIHx8CisgICAgICAgIG1FT0NELm1OdW1FbnRyaWVzICE9IG1FT0NELm1Ub3RhbE51bUVudHJpZXMpCisgICAgeworICAgICAgICBMT0dEKCJBcmNoaXZlIHNwYW5uaW5nIG5vdCBzdXBwb3J0ZWRcbiIpOworICAgICAgICByZXN1bHQgPSBJTlZBTElEX09QRVJBVElPTjsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qCisgICAgICogU28gZmFyIHNvIGdvb2QuICAibUNlbnRyYWxEaXJTaXplIiBpcyB0aGUgc2l6ZSBpbiBieXRlcyBvZiB0aGUKKyAgICAgKiBjZW50cmFsIGRpcmVjdG9yeSwgc28gd2UgY2FuIGp1c3Qgc2VlayBiYWNrIHRoYXQgZmFyIHRvIGZpbmQgaXQuCisgICAgICogV2UgY2FuIGFsc28gc2VlayBmb3J3YXJkIG1DZW50cmFsRGlyT2Zmc2V0IGJ5dGVzIGZyb20gdGhlCisgICAgICogc3RhcnQgb2YgdGhlIGZpbGUuCisgICAgICoKKyAgICAgKiBXZSdyZSBub3QgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSByZXN0IG9mIHRoZSBjZW50cmFsIGRpciBpbiB0aGUKKyAgICAgKiBidWZmZXIsIG5vciBhcmUgd2UgZ3VhcmFudGVlZCB0aGF0IHRoZSBjZW50cmFsIGRpciB3aWxsIGhhdmUgYW55CisgICAgICogc29ydCBvZiBjb252ZW5pZW50IHNpemUuICBXZSBuZWVkIHRvIHNraXAgdG8gdGhlIHN0YXJ0IG9mIGl0IGFuZAorICAgICAqIHJlYWQgdGhlIGhlYWRlciwgdGhlbiB0aGUgb3RoZXIgZ29vZGllcy4KKyAgICAgKgorICAgICAqIFRoZSBvbmx5IHRoaW5nIHdlIHJlYWxseSBuZWVkIHJpZ2h0IG5vdyBpcyB0aGUgZmlsZSBjb21tZW50LCB3aGljaAorICAgICAqIHdlJ3JlIGhvcGluZyB0byBwcmVzZXJ2ZS4KKyAgICAgKi8KKyAgICBpZiAoZnNlZWsobVppcEZwLCBtRU9DRC5tQ2VudHJhbERpck9mZnNldCwgU0VFS19TRVQpICE9IDApIHsKKwkJTE9HRCgiRmFpbHVyZSBzZWVraW5nIHRvIGNlbnRyYWwgZGlyIG9mZnNldCAlbGRcbiIsCisJCQkgbUVPQ0QubUNlbnRyYWxEaXJPZmZzZXQpOworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBMb29wIHRocm91Z2ggYW5kIHJlYWQgdGhlIGNlbnRyYWwgZGlyIGVudHJpZXMuCisgICAgICovCisgICAgTE9HVigiU2Nhbm5pbmcgJWQgZW50cmllcy4uLlxuIiwgbUVPQ0QubVRvdGFsTnVtRW50cmllcyk7CisgICAgaW50IGVudHJ5OworICAgIGZvciAoZW50cnkgPSAwOyBlbnRyeSA8IG1FT0NELm1Ub3RhbE51bUVudHJpZXM7IGVudHJ5KyspIHsKKyAgICAgICAgWmlwRW50cnkqIHBFbnRyeSA9IG5ldyBaaXBFbnRyeTsKKworICAgICAgICByZXN1bHQgPSBwRW50cnktPmluaXRGcm9tQ0RFKG1aaXBGcCk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgIExPR0QoImluaXRGcm9tQ0RFIGZhaWxlZFxuIik7CisgICAgICAgICAgICBkZWxldGUgcEVudHJ5OworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisKKyAgICAgICAgbUVudHJpZXMuYWRkKHBFbnRyeSk7CisgICAgfQorCisKKyAgICAvKgorICAgICAqIElmIGFsbCB3ZW50IHdlbGwsIHdlIHNob3VsZCBub3cgYmUgYmFjayBhdCB0aGUgRU9DRC4KKyAgICAgKi8KKyAgICB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIgY2hlY2tCdWZbNF07CisgICAgICAgIGlmIChmcmVhZChjaGVja0J1ZiwgMSwgNCwgbVppcEZwKSAhPSA0KSB7CisgICAgICAgICAgICBMT0dEKCJFT0NEIGNoZWNrIHJlYWQgZmFpbGVkXG4iKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IElOVkFMSURfT1BFUkFUSU9OOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisgICAgICAgIGlmIChaaXBFbnRyeTo6Z2V0TG9uZ0xFKGNoZWNrQnVmKSAhPSBFbmRPZkNlbnRyYWxEaXI6OmtTaWduYXR1cmUpIHsKKyAgICAgICAgICAgIExPR0QoIkVPQ0QgcmVhZCBjaGVjayBmYWlsZWRcbiIpOworICAgICAgICAgICAgcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgICAgICBMT0dWKCIrKysgRU9DRCByZWFkIGNoZWNrIHBhc3NlZFxuIik7CisgICAgfQorCitiYWlsOgorICAgIGRlbGV0ZVtdIGJ1ZjsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisKKy8qCisgKiBBZGQgYSBuZXcgZmlsZSB0byB0aGUgYXJjaGl2ZS4KKyAqCisgKiBUaGlzIHJlcXVpcmVzIGNyZWF0aW5nIGFuZCBwb3B1bGF0aW5nIGEgWmlwRW50cnkgc3RydWN0dXJlLCBhbmQgY29weWluZworICogdGhlIGRhdGEgaW50byB0aGUgZmlsZSBhdCB0aGUgYXBwcm9wcmlhdGUgcG9zaXRpb24uICBUaGUgImFwcHJvcHJpYXRlCisgKiBwb3NpdGlvbiIgaXMgdGhlIGN1cnJlbnQgbG9jYXRpb24gb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5LCB3aGljaCB3ZQorICogY2FzdWFsbHkgb3ZlcndyaXRlICh3ZSBjYW4gcHV0IGl0IGJhY2sgbGF0ZXIpLgorICoKKyAqIElmIHdlIHdlcmUgY29uY2VybmVkIGFib3V0IHNhZmV0eSwgd2Ugd291bGQgd2FudCB0byBtYWtlIGFsbCBjaGFuZ2VzCisgKiBpbiBhIHRlbXAgZmlsZSBhbmQgdGhlbiBvdmVyd3JpdGUgdGhlIG9yaWdpbmFsIGFmdGVyIGV2ZXJ5dGhpbmcgd2FzCisgKiBzYWZlbHkgd3JpdHRlbi4gIE5vdCByZWFsbHkgYSBjb25jZXJuIGZvciB1cy4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6YWRkQ29tbW9uKGNvbnN0IGNoYXIqIGZpbGVOYW1lLCBjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwKKyAgICBjb25zdCBjaGFyKiBzdG9yYWdlTmFtZSwgaW50IHNvdXJjZVR5cGUsIGludCBjb21wcmVzc2lvbk1ldGhvZCwKKyAgICBaaXBFbnRyeSoqIHBwRW50cnkpCit7CisgICAgWmlwRW50cnkqIHBFbnRyeSA9IE5VTEw7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gTk9fRVJST1I7CisgICAgbG9uZyBsZmhQb3NuLCBzdGFydFBvc24sIGVuZFBvc24sIHVuY29tcHJlc3NlZExlbjsKKyAgICBGSUxFKiBpbnB1dEZwID0gTlVMTDsKKyAgICB1bnNpZ25lZCBsb25nIGNyYzsKKyAgICB0aW1lX3QgbW9kV2hlbjsKKworICAgIGlmIChtUmVhZE9ubHkpCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKworICAgIGFzc2VydChjb21wcmVzc2lvbk1ldGhvZCA9PSBaaXBFbnRyeTo6a0NvbXByZXNzRGVmbGF0ZWQgfHwKKyAgICAgICAgICAgY29tcHJlc3Npb25NZXRob2QgPT0gWmlwRW50cnk6OmtDb21wcmVzc1N0b3JlZCk7CisKKyAgICAvKiBtYWtlIHN1cmUgd2UncmUgaW4gYSByZWFzb25hYmxlIHN0YXRlICovCisgICAgYXNzZXJ0KG1aaXBGcCAhPSBOVUxMKTsKKyAgICBhc3NlcnQobUVudHJpZXMuc2l6ZSgpID09IG1FT0NELm1Ub3RhbE51bUVudHJpZXMpOworCisgICAgLyogbWFrZSBzdXJlIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdCAqLworICAgIGlmIChnZXRFbnRyeUJ5TmFtZShzdG9yYWdlTmFtZSkgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIEFMUkVBRFlfRVhJU1RTOworCisgICAgaWYgKCFkYXRhKSB7CisgICAgICAgIGlucHV0RnAgPSBmb3BlbihmaWxlTmFtZSwgRklMRV9PUEVOX1JPKTsKKyAgICAgICAgaWYgKGlucHV0RnAgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBlcnJub1RvU3RhdHVzKGVycm5vKTsKKyAgICB9CisKKyAgICBpZiAoZnNlZWsobVppcEZwLCBtRU9DRC5tQ2VudHJhbERpck9mZnNldCwgU0VFS19TRVQpICE9IDApIHsKKyAgICAgICAgcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIHBFbnRyeSA9IG5ldyBaaXBFbnRyeTsKKyAgICBwRW50cnktPmluaXROZXcoc3RvcmFnZU5hbWUsIE5VTEwpOworCisgICAgLyoKKyAgICAgKiBGcm9tIGhlcmUgb24gb3V0LCBmYWlsdXJlcyBhcmUgbW9yZSBpbnRlcmVzdGluZy4KKyAgICAgKi8KKyAgICBtTmVlZENEUmV3cml0ZSA9IHRydWU7CisKKyAgICAvKgorICAgICAqIFdyaXRlIHRoZSBMRkgsIGV2ZW4gdGhvdWdoIGl0J3Mgc3RpbGwgbW9zdGx5IGJsYW5rLiAgV2UgbmVlZCBpdAorICAgICAqIGFzIGEgcGxhY2UtaG9sZGVyLiAgSW4gdGhlb3J5IHRoZSBMRkggaXNuJ3QgbmVjZXNzYXJ5LCBidXQgaW4KKyAgICAgKiBwcmFjdGljZSBzb21lIHV0aWxpdGllcyBkZW1hbmQgaXQuCisgICAgICovCisgICAgbGZoUG9zbiA9IGZ0ZWxsKG1aaXBGcCk7CisgICAgcEVudHJ5LT5tTEZILndyaXRlKG1aaXBGcCk7CisgICAgc3RhcnRQb3NuID0gZnRlbGwobVppcEZwKTsKKworICAgIC8qCisgICAgICogQ29weSB0aGUgZGF0YSBpbiwgcG9zc2libHkgY29tcHJlc3NpbmcgaXQgYXMgd2UgZ28uCisgICAgICovCisgICAgaWYgKHNvdXJjZVR5cGUgPT0gWmlwRW50cnk6OmtDb21wcmVzc1N0b3JlZCkgeworICAgICAgICBpZiAoY29tcHJlc3Npb25NZXRob2QgPT0gWmlwRW50cnk6OmtDb21wcmVzc0RlZmxhdGVkKSB7CisgICAgICAgICAgICBib29sIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgcmVzdWx0ID0gY29tcHJlc3NGcFRvRnAobVppcEZwLCBpbnB1dEZwLCBkYXRhLCBzaXplLCAmY3JjKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgICAgICBMT0dEKCJjb21wcmVzc2lvbiBmYWlsZWQsIHN0b3JpbmdcbiIpOworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogTWFrZSBzdXJlIGl0IGhhcyBjb21wcmVzc2VkICJlbm91Z2giLiAgVGhpcyBwcm9iYWJseSBvdWdodAorICAgICAgICAgICAgICAgICAqIHRvIGJlIHNldCB0aHJvdWdoIGFuIEFQSSBjYWxsLCBidXQgSSBkb24ndCBleHBlY3Qgb3VyCisgICAgICAgICAgICAgICAgICogY3JpdGVyaWEgdG8gY2hhbmdlIG92ZXIgdGltZS4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBsb25nIHNyYyA9IGlucHV0RnAgPyBmdGVsbChpbnB1dEZwKSA6IHNpemU7CisgICAgICAgICAgICAgICAgbG9uZyBkc3QgPSBmdGVsbChtWmlwRnApIC0gc3RhcnRQb3NuOworICAgICAgICAgICAgICAgIGlmIChkc3QgKyAoZHN0IC8gMTApID4gc3JjKSB7CisgICAgICAgICAgICAgICAgICAgIExPR0QoImluc3VmZmljaWVudCBjb21wcmVzc2lvbiAoc3JjPSVsZCBkc3Q9JWxkKSwgc3RvcmluZ1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNyYywgZHN0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChmYWlsZWQpIHsKKyAgICAgICAgICAgICAgICBjb21wcmVzc2lvbk1ldGhvZCA9IFppcEVudHJ5OjprQ29tcHJlc3NTdG9yZWQ7CisgICAgICAgICAgICAgICAgaWYgKGlucHV0RnApIHJld2luZChpbnB1dEZwKTsKKyAgICAgICAgICAgICAgICBmc2VlayhtWmlwRnAsIHN0YXJ0UG9zbiwgU0VFS19TRVQpOworICAgICAgICAgICAgICAgIC8qIGZhbGwgdGhyb3VnaCB0byBrQ29tcHJlc3NTdG9yZWQgY2FzZSAqLworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8qIGhhbmRsZSAibm8gY29tcHJlc3Npb24iIHJlcXVlc3QsIG9yIGZhaWxlZCBjb21wcmVzc2lvbiBmcm9tIGFib3ZlICovCisgICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSBaaXBFbnRyeTo6a0NvbXByZXNzU3RvcmVkKSB7CisgICAgICAgICAgICBpZiAoaW5wdXRGcCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvcHlGcFRvRnAobVppcEZwLCBpbnB1dEZwLCAmY3JjKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gY29weURhdGFUb0ZwKG1aaXBGcCwgZGF0YSwgc2l6ZSwgJmNyYyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byB0cnVuY2F0ZTsgaGFwcGVucyBpbiBDREUgcmV3cml0ZQorICAgICAgICAgICAgICAgIExPR0QoImZhaWxlZCBjb3B5aW5nIGRhdGEgaW5cbiIpOworICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGN1cnJlbnRseSBzZWVrZWQgdG8gZW5kIG9mIGZpbGUKKyAgICAgICAgdW5jb21wcmVzc2VkTGVuID0gaW5wdXRGcCA/IGZ0ZWxsKGlucHV0RnApIDogc2l6ZTsKKyAgICB9IGVsc2UgaWYgKHNvdXJjZVR5cGUgPT0gWmlwRW50cnk6OmtDb21wcmVzc0RlZmxhdGVkKSB7CisgICAgICAgIC8qIHdlIHNob3VsZCBzdXBwb3J0IHVuY29tcHJlc3NlZC1mcm9tLWNvbXByZXNzZWQsIGJ1dCBpdCdzIG5vdAorICAgICAgICAgKiBpbXBvcnRhbnQgcmlnaHQgbm93ICovCisgICAgICAgIGFzc2VydChjb21wcmVzc2lvbk1ldGhvZCA9PSBaaXBFbnRyeTo6a0NvbXByZXNzRGVmbGF0ZWQpOworCisgICAgICAgIGJvb2wgc2NhblJlc3VsdDsKKyAgICAgICAgaW50IG1ldGhvZDsKKyAgICAgICAgbG9uZyBjb21wcmVzc2VkTGVuOworCisgICAgICAgIHNjYW5SZXN1bHQgPSBaaXBVdGlsczo6ZXhhbWluZUd6aXAoaW5wdXRGcCwgJm1ldGhvZCwgJnVuY29tcHJlc3NlZExlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICZjb21wcmVzc2VkTGVuLCAmY3JjKTsKKyAgICAgICAgaWYgKCFzY2FuUmVzdWx0IHx8IG1ldGhvZCAhPSBaaXBFbnRyeTo6a0NvbXByZXNzRGVmbGF0ZWQpIHsKKyAgICAgICAgICAgIExPR0QoInRoaXMgaXNuJ3QgYSBkZWZsYXRlZCBnemlwIGZpbGU/Iik7CisgICAgICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisKKyAgICAgICAgcmVzdWx0ID0gY29weVBhcnRpYWxGcFRvRnAobVppcEZwLCBpbnB1dEZwLCBjb21wcmVzc2VkTGVuLCBOVUxMKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBOT19FUlJPUikgeworICAgICAgICAgICAgTE9HRCgiZmFpbGVkIGNvcHlpbmcgZ3ppcCBkYXRhIGluXG4iKTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFdlIGNvdWxkIHdyaXRlIHRoZSAiRGF0YSBEZXNjcmlwdG9yIiwgYnV0IHRoZXJlIGRvZXNuJ3Qgc2VlbSB0bworICAgICAqIGJlIGFueSBwb2ludCBzaW5jZSB3ZSdyZSBnb2luZyB0byBnbyBiYWNrIGFuZCB3cml0ZSB0aGUgTEZILgorICAgICAqCisgICAgICogVXBkYXRlIGZpbGUgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBlbmRQb3NuID0gZnRlbGwobVppcEZwKTsgICAgICAgICAgICAvLyBzZWVrZWQgdG8gZW5kIG9mIGNvbXByZXNzZWQgZGF0YQorCisgICAgLyoKKyAgICAgKiBTdWNjZXNzISAgRmlsbCBvdXQgbmV3IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwRW50cnktPnNldERhdGFJbmZvKHVuY29tcHJlc3NlZExlbiwgZW5kUG9zbiAtIHN0YXJ0UG9zbiwgY3JjLAorICAgICAgICBjb21wcmVzc2lvbk1ldGhvZCk7CisgICAgbW9kV2hlbiA9IGdldE1vZFRpbWUoaW5wdXRGcCA/IGZpbGVubyhpbnB1dEZwKSA6IGZpbGVubyhtWmlwRnApKTsKKyAgICBwRW50cnktPnNldE1vZFdoZW4obW9kV2hlbik7CisgICAgcEVudHJ5LT5zZXRMRkhPZmZzZXQobGZoUG9zbik7CisgICAgbUVPQ0QubU51bUVudHJpZXMrKzsKKyAgICBtRU9DRC5tVG90YWxOdW1FbnRyaWVzKys7CisgICAgbUVPQ0QubUNlbnRyYWxEaXJTaXplID0gMDsgICAgICAvLyBtYXJrIGludmFsaWQ7IHNldCBieSBmbHVzaCgpCisgICAgbUVPQ0QubUNlbnRyYWxEaXJPZmZzZXQgPSBlbmRQb3NuOworCisgICAgLyoKKyAgICAgKiBHbyBiYWNrIGFuZCB3cml0ZSB0aGUgTEZILgorICAgICAqLworICAgIGlmIChmc2VlayhtWmlwRnAsIGxmaFBvc24sIFNFRUtfU0VUKSAhPSAwKSB7CisgICAgICAgIHJlc3VsdCA9IFVOS05PV05fRVJST1I7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisgICAgcEVudHJ5LT5tTEZILndyaXRlKG1aaXBGcCk7CisKKyAgICAvKgorICAgICAqIEFkZCBwRW50cnkgdG8gdGhlIGxpc3QuCisgICAgICovCisgICAgbUVudHJpZXMuYWRkKHBFbnRyeSk7CisgICAgaWYgKHBwRW50cnkgIT0gTlVMTCkKKyAgICAgICAgKnBwRW50cnkgPSBwRW50cnk7CisgICAgcEVudHJ5ID0gTlVMTDsKKworYmFpbDoKKyAgICBpZiAoaW5wdXRGcCAhPSBOVUxMKQorICAgICAgICBmY2xvc2UoaW5wdXRGcCk7CisgICAgZGVsZXRlIHBFbnRyeTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKgorICogQWRkIGFuIGVudHJ5IGJ5IGNvcHlpbmcgaXQgZnJvbSBhbm90aGVyIHppcCBmaWxlLiAgSWYgInBhZGRpbmciIGlzCisgKiBub256ZXJvLCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSAiZXh0cmEiCisgKiBmaWVsZCBpbiB0aGUgaGVhZGVyLgorICoKKyAqIElmICJwcEVudHJ5IiBpcyBub24tTlVMTCwgYSBwb2ludGVyIHRvIHRoZSBuZXcgZW50cnkgd2lsbCBiZSByZXR1cm5lZC4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6YWRkKGNvbnN0IFppcEZpbGUqIHBTb3VyY2VaaXAsIGNvbnN0IFppcEVudHJ5KiBwU291cmNlRW50cnksCisgICAgaW50IHBhZGRpbmcsIFppcEVudHJ5KiogcHBFbnRyeSkKK3sKKyAgICBaaXBFbnRyeSogcEVudHJ5ID0gTlVMTDsKKyAgICBzdGF0dXNfdCByZXN1bHQ7CisgICAgbG9uZyBsZmhQb3NuLCBlbmRQb3NuOworCisgICAgaWYgKG1SZWFkT25seSkKKyAgICAgICAgcmV0dXJuIElOVkFMSURfT1BFUkFUSU9OOworCisgICAgLyogbWFrZSBzdXJlIHdlJ3JlIGluIGEgcmVhc29uYWJsZSBzdGF0ZSAqLworICAgIGFzc2VydChtWmlwRnAgIT0gTlVMTCk7CisgICAgYXNzZXJ0KG1FbnRyaWVzLnNpemUoKSA9PSBtRU9DRC5tVG90YWxOdW1FbnRyaWVzKTsKKworICAgIGlmIChmc2VlayhtWmlwRnAsIG1FT0NELm1DZW50cmFsRGlyT2Zmc2V0LCBTRUVLX1NFVCkgIT0gMCkgeworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgcEVudHJ5ID0gbmV3IFppcEVudHJ5OworICAgIGlmIChwRW50cnkgPT0gTlVMTCkgeworICAgICAgICByZXN1bHQgPSBOT19NRU1PUlk7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICByZXN1bHQgPSBwRW50cnktPmluaXRGcm9tRXh0ZXJuYWwocFNvdXJjZVppcCwgcFNvdXJjZUVudHJ5KTsKKyAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKQorICAgICAgICBnb3RvIGJhaWw7CisgICAgaWYgKHBhZGRpbmcgIT0gMCkgeworICAgICAgICByZXN1bHQgPSBwRW50cnktPmFkZFBhZGRpbmcocGFkZGluZyk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpCisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGcm9tIGhlcmUgb24gb3V0LCBmYWlsdXJlcyBhcmUgbW9yZSBpbnRlcmVzdGluZy4KKyAgICAgKi8KKyAgICBtTmVlZENEUmV3cml0ZSA9IHRydWU7CisKKyAgICAvKgorICAgICAqIFdyaXRlIHRoZSBMRkguICBTaW5jZSB3ZSdyZSBub3QgcmVjb21wcmVzc2luZyB0aGUgZGF0YSwgd2UgYWxyZWFkeQorICAgICAqIGhhdmUgYWxsIG9mIHRoZSBmaWVsZHMgZmlsbGVkIG91dC4KKyAgICAgKi8KKyAgICBsZmhQb3NuID0gZnRlbGwobVppcEZwKTsKKyAgICBwRW50cnktPm1MRkgud3JpdGUobVppcEZwKTsKKworICAgIC8qCisgICAgICogQ29weSB0aGUgZGF0YSBvdmVyLgorICAgICAqCisgICAgICogSWYgdGhlICJoYXMgZGF0YSBkZXNjcmlwdG9yIiBmbGFnIGlzIHNldCwgd2Ugd2FudCB0byBjb3B5IHRoZSBERAorICAgICAqIGZpZWxkcyBhcyB3ZWxsLiAgVGhpcyBpcyBhIGZpeGVkLXNpemUgYXJlYSBpbW1lZGlhdGVseSBmb2xsb3dpbmcKKyAgICAgKiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBpZiAoZnNlZWsocFNvdXJjZVppcC0+bVppcEZwLCBwU291cmNlRW50cnktPmdldEZpbGVPZmZzZXQoKSwgU0VFS19TRVQpICE9IDApCisgICAgeworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgb2ZmX3QgY29weUxlbjsKKyAgICBjb3B5TGVuID0gcFNvdXJjZUVudHJ5LT5nZXRDb21wcmVzc2VkTGVuKCk7CisgICAgaWYgKChwU291cmNlRW50cnktPm1MRkgubUdQQml0RmxhZyAmIFppcEVudHJ5OjprVXNlc0RhdGFEZXNjcikgIT0gMCkKKyAgICAgICAgY29weUxlbiArPSBaaXBFbnRyeTo6a0RhdGFEZXNjcmlwdG9yTGVuOworCisgICAgaWYgKGNvcHlQYXJ0aWFsRnBUb0ZwKG1aaXBGcCwgcFNvdXJjZVppcC0+bVppcEZwLCBjb3B5TGVuLCBOVUxMKQorICAgICAgICAhPSBOT19FUlJPUikKKyAgICB7CisgICAgICAgIExPR1coImNvcHkgb2YgJyVzJyBmYWlsZWRcbiIsIHBFbnRyeS0+bUNERS5tRmlsZU5hbWUpOworICAgICAgICByZXN1bHQgPSBVTktOT1dOX0VSUk9SOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBVcGRhdGUgZmlsZSBvZmZzZXRzLgorICAgICAqLworICAgIGVuZFBvc24gPSBmdGVsbChtWmlwRnApOworCisgICAgLyoKKyAgICAgKiBTdWNjZXNzISAgRmlsbCBvdXQgbmV3IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwRW50cnktPnNldExGSE9mZnNldChsZmhQb3NuKTsgICAgICAvLyBzZXRzIG1DREUubUxvY2FsSGVhZGVyUmVsT2Zmc2V0CisgICAgbUVPQ0QubU51bUVudHJpZXMrKzsKKyAgICBtRU9DRC5tVG90YWxOdW1FbnRyaWVzKys7CisgICAgbUVPQ0QubUNlbnRyYWxEaXJTaXplID0gMDsgICAgICAvLyBtYXJrIGludmFsaWQ7IHNldCBieSBmbHVzaCgpCisgICAgbUVPQ0QubUNlbnRyYWxEaXJPZmZzZXQgPSBlbmRQb3NuOworCisgICAgLyoKKyAgICAgKiBBZGQgcEVudHJ5IHRvIHRoZSBsaXN0LgorICAgICAqLworICAgIG1FbnRyaWVzLmFkZChwRW50cnkpOworICAgIGlmIChwcEVudHJ5ICE9IE5VTEwpCisgICAgICAgICpwcEVudHJ5ID0gcEVudHJ5OworICAgIHBFbnRyeSA9IE5VTEw7CisKKyAgICByZXN1bHQgPSBOT19FUlJPUjsKKworYmFpbDoKKyAgICBkZWxldGUgcEVudHJ5OworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBDb3B5IGFsbCBvZiB0aGUgYnl0ZXMgaW4gInNyYyIgdG8gImRzdCIuCisgKgorICogT24gZXhpdCwgInNyY0ZwIiB3aWxsIGJlIHNlZWtlZCB0byB0aGUgZW5kIG9mIHRoZSBmaWxlLCBhbmQgImRzdEZwIgorICogd2lsbCBiZSBzZWVrZWQgaW1tZWRpYXRlbHkgcGFzdCB0aGUgZGF0YS4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6Y29weUZwVG9GcChGSUxFKiBkc3RGcCwgRklMRSogc3JjRnAsIHVuc2lnbmVkIGxvbmcqIHBDUkMzMikKK3sKKyAgICB1bnNpZ25lZCBjaGFyIHRtcEJ1ZlszMjc2OF07CisgICAgc2l6ZV90IGNvdW50OworCisgICAgKnBDUkMzMiA9IGNyYzMyKDBMLCBaX05VTEwsIDApOworCisgICAgd2hpbGUgKDEpIHsKKyAgICAgICAgY291bnQgPSBmcmVhZCh0bXBCdWYsIDEsIHNpemVvZih0bXBCdWYpLCBzcmNGcCk7CisgICAgICAgIGlmIChmZXJyb3Ioc3JjRnApIHx8IGZlcnJvcihkc3RGcCkpCisgICAgICAgICAgICByZXR1cm4gZXJybm9Ub1N0YXR1cyhlcnJubyk7CisgICAgICAgIGlmIChjb3VudCA9PSAwKQorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgKnBDUkMzMiA9IGNyYzMyKCpwQ1JDMzIsIHRtcEJ1ZiwgY291bnQpOworCisgICAgICAgIGlmIChmd3JpdGUodG1wQnVmLCAxLCBjb3VudCwgZHN0RnApICE9IGNvdW50KSB7CisgICAgICAgICAgICBMT0dEKCJmd3JpdGUgJWQgYnl0ZXMgZmFpbGVkXG4iLCAoaW50KSBjb3VudCk7CisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLyoKKyAqIENvcHkgYWxsIG9mIHRoZSBieXRlcyBpbiAic3JjIiB0byAiZHN0Ii4KKyAqCisgKiBPbiBleGl0LCAiZHN0RnAiIHdpbGwgYmUgc2Vla2VkIGltbWVkaWF0ZWx5IHBhc3QgdGhlIGRhdGEuCisgKi8KK3N0YXR1c190IFppcEZpbGU6OmNvcHlEYXRhVG9GcChGSUxFKiBkc3RGcCwKKyAgICBjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgdW5zaWduZWQgbG9uZyogcENSQzMyKQoreworICAgIHNpemVfdCBjb3VudDsKKworICAgICpwQ1JDMzIgPSBjcmMzMigwTCwgWl9OVUxMLCAwKTsKKyAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgKnBDUkMzMiA9IGNyYzMyKCpwQ1JDMzIsIChjb25zdCB1bnNpZ25lZCBjaGFyKilkYXRhLCBzaXplKTsKKyAgICAgICAgaWYgKGZ3cml0ZShkYXRhLCAxLCBzaXplLCBkc3RGcCkgIT0gc2l6ZSkgeworICAgICAgICAgICAgTE9HRCgiZndyaXRlICVkIGJ5dGVzIGZhaWxlZFxuIiwgKGludCkgc2l6ZSk7CisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLyoKKyAqIENvcHkgc29tZSBvZiB0aGUgYnl0ZXMgaW4gInNyYyIgdG8gImRzdCIuCisgKgorICogSWYgInBDUkMzMiIgaXMgTlVMTCwgdGhlIENSQyB3aWxsIG5vdCBiZSBjb21wdXRlZC4KKyAqCisgKiBPbiBleGl0LCAic3JjRnAiIHdpbGwgYmUgc2Vla2VkIHRvIHRoZSBlbmQgb2YgdGhlIGZpbGUsIGFuZCAiZHN0RnAiCisgKiB3aWxsIGJlIHNlZWtlZCBpbW1lZGlhdGVseSBwYXN0IHRoZSBkYXRhIGp1c3Qgd3JpdHRlbi4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6Y29weVBhcnRpYWxGcFRvRnAoRklMRSogZHN0RnAsIEZJTEUqIHNyY0ZwLCBsb25nIGxlbmd0aCwKKyAgICB1bnNpZ25lZCBsb25nKiBwQ1JDMzIpCit7CisgICAgdW5zaWduZWQgY2hhciB0bXBCdWZbMzI3NjhdOworICAgIHNpemVfdCBjb3VudDsKKworICAgIGlmIChwQ1JDMzIgIT0gTlVMTCkKKyAgICAgICAgKnBDUkMzMiA9IGNyYzMyKDBMLCBaX05VTEwsIDApOworCisgICAgd2hpbGUgKGxlbmd0aCkgeworICAgICAgICBsb25nIHJlYWRTaXplOworICAgICAgICAKKyAgICAgICAgcmVhZFNpemUgPSBzaXplb2YodG1wQnVmKTsKKyAgICAgICAgaWYgKHJlYWRTaXplID4gbGVuZ3RoKQorICAgICAgICAgICAgcmVhZFNpemUgPSBsZW5ndGg7CisKKyAgICAgICAgY291bnQgPSBmcmVhZCh0bXBCdWYsIDEsIHJlYWRTaXplLCBzcmNGcCk7CisgICAgICAgIGlmICgobG9uZykgY291bnQgIT0gcmVhZFNpemUpIHsgICAgIC8vIGVycm9yIG9yIHVuZXhwZWN0ZWQgRU9GCisgICAgICAgICAgICBMT0dEKCJmcmVhZCAlZCBieXRlcyBmYWlsZWRcbiIsIChpbnQpIHJlYWRTaXplKTsKKyAgICAgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBDUkMzMiAhPSBOVUxMKQorICAgICAgICAgICAgKnBDUkMzMiA9IGNyYzMyKCpwQ1JDMzIsIHRtcEJ1ZiwgY291bnQpOworCisgICAgICAgIGlmIChmd3JpdGUodG1wQnVmLCAxLCBjb3VudCwgZHN0RnApICE9IGNvdW50KSB7CisgICAgICAgICAgICBMT0dEKCJmd3JpdGUgJWQgYnl0ZXMgZmFpbGVkXG4iLCAoaW50KSBjb3VudCk7CisgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgfQorCisgICAgICAgIGxlbmd0aCAtPSByZWFkU2l6ZTsKKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBDb21wcmVzcyBhbGwgb2YgdGhlIGRhdGEgaW4gInNyY0ZwIiBhbmQgd3JpdGUgaXQgdG8gImRzdEZwIi4KKyAqCisgKiBPbiBleGl0LCAic3JjRnAiIHdpbGwgYmUgc2Vla2VkIHRvIHRoZSBlbmQgb2YgdGhlIGZpbGUsIGFuZCAiZHN0RnAiCisgKiB3aWxsIGJlIHNlZWtlZCBpbW1lZGlhdGVseSBwYXN0IHRoZSBjb21wcmVzc2VkIGRhdGEuCisgKi8KK3N0YXR1c190IFppcEZpbGU6OmNvbXByZXNzRnBUb0ZwKEZJTEUqIGRzdEZwLCBGSUxFKiBzcmNGcCwKKyAgICBjb25zdCB2b2lkKiBkYXRhLCBzaXplX3Qgc2l6ZSwgdW5zaWduZWQgbG9uZyogcENSQzMyKQoreworICAgIHN0YXR1c190IHJlc3VsdCA9IE5PX0VSUk9SOworCWNvbnN0IHNpemVfdCBrQnVmU2l6ZSA9IDMyNzY4OworCXVuc2lnbmVkIGNoYXIqIGluQnVmID0gTlVMTDsKKwl1bnNpZ25lZCBjaGFyKiBvdXRCdWYgPSBOVUxMOworCXpfc3RyZWFtIHpzdHJlYW07CisgICAgYm9vbCBhdEVvZiA9IGZhbHNlOyAgICAgLy8gbm8gZmVvZigpIGF2aWFpbGFibGUgeWV0CisJdW5zaWduZWQgbG9uZyBjcmM7CisJaW50IHplcnI7CisKKwkvKgorCSAqIENyZWF0ZSBhbiBpbnB1dCBidWZmZXIgYW5kIGFuIG91dHB1dCBidWZmZXIuCisJICovCisJaW5CdWYgPSBuZXcgdW5zaWduZWQgY2hhcltrQnVmU2l6ZV07CisJb3V0QnVmID0gbmV3IHVuc2lnbmVkIGNoYXJba0J1ZlNpemVdOworCWlmIChpbkJ1ZiA9PSBOVUxMIHx8IG91dEJ1ZiA9PSBOVUxMKSB7CisJCXJlc3VsdCA9IE5PX01FTU9SWTsKKwkJZ290byBiYWlsOworCX0KKworCS8qCisJICogSW5pdGlhbGl6ZSB0aGUgemxpYiBzdHJlYW0uCisJICovCisJbWVtc2V0KCZ6c3RyZWFtLCAwLCBzaXplb2YoenN0cmVhbSkpOworCXpzdHJlYW0uemFsbG9jID0gWl9OVUxMOworCXpzdHJlYW0uemZyZWUgPSBaX05VTEw7CisJenN0cmVhbS5vcGFxdWUgPSBaX05VTEw7CisJenN0cmVhbS5uZXh0X2luID0gTlVMTDsKKwl6c3RyZWFtLmF2YWlsX2luID0gMDsKKwl6c3RyZWFtLm5leHRfb3V0ID0gb3V0QnVmOworCXpzdHJlYW0uYXZhaWxfb3V0ID0ga0J1ZlNpemU7CisJenN0cmVhbS5kYXRhX3R5cGUgPSBaX1VOS05PV047CisKKwl6ZXJyID0gZGVmbGF0ZUluaXQyKCZ6c3RyZWFtLCBaX0JFU1RfQ09NUFJFU1NJT04sCisJCVpfREVGTEFURUQsIC1NQVhfV0JJVFMsIERFRl9NRU1fTEVWRUwsIFpfREVGQVVMVF9TVFJBVEVHWSk7CisJaWYgKHplcnIgIT0gWl9PSykgeworCQlyZXN1bHQgPSBVTktOT1dOX0VSUk9SOworCQlpZiAoemVyciA9PSBaX1ZFUlNJT05fRVJST1IpIHsKKwkJCUxPR0UoIkluc3RhbGxlZCB6bGliIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggbGlua2VkIHZlcnNpb24gKCVzKVxuIiwKKwkJCQlaTElCX1ZFUlNJT04pOworCQl9IGVsc2UgeworCQkJTE9HRCgiQ2FsbCB0byBkZWZsYXRlSW5pdDIgZmFpbGVkICh6ZXJyPSVkKVxuIiwgemVycik7CisJCX0KKwkJZ290byBiYWlsOworCX0KKworIAljcmMgPSBjcmMzMigwTCwgWl9OVUxMLCAwKTsKKworCS8qCisJICogTG9vcCB3aGlsZSB3ZSBoYXZlIGRhdGEuCisJICovCisJZG8geworCQlzaXplX3QgZ2V0U2l6ZTsKKwkJaW50IGZsdXNoOworCisJCS8qIG9ubHkgcmVhZCBpZiB0aGUgaW5wdXQgYnVmZmVyIGlzIGVtcHR5ICovCisJCWlmICh6c3RyZWFtLmF2YWlsX2luID09IDAgJiYgIWF0RW9mKSB7CisgICAgICAgICAgICBMT0dWKCIrKysgcmVhZGluZyAlZCBieXRlc1xuIiwgKGludClrQnVmU2l6ZSk7CisgICAgICAgICAgICBpZiAoZGF0YSkgeworICAgICAgICAgICAgICAgIGdldFNpemUgPSBzaXplID4ga0J1ZlNpemUgPyBrQnVmU2l6ZSA6IHNpemU7CisgICAgICAgICAgICAgICAgbWVtY3B5KGluQnVmLCBkYXRhLCBnZXRTaXplKTsKKyAgICAgICAgICAgICAgICBkYXRhID0gKChjb25zdCBjaGFyKilkYXRhKSArIGdldFNpemU7CisgICAgICAgICAgICAgICAgc2l6ZSAtPSBnZXRTaXplOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBnZXRTaXplID0gZnJlYWQoaW5CdWYsIDEsIGtCdWZTaXplLCBzcmNGcCk7CisgICAgICAgICAgICAgICAgaWYgKGZlcnJvcihzcmNGcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HRCgiZGVmbGF0ZSByZWFkIGZhaWxlZCAoZXJybm89JWQpXG4iLCBlcnJubyk7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChnZXRTaXplIDwga0J1ZlNpemUpIHsKKyAgICAgICAgICAgICAgICBMT0dWKCIrKysgIGdvdCAlZCBieXRlcywgRU9GIHJlYWNoZWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChpbnQpZ2V0U2l6ZSk7CisgICAgICAgICAgICAgICAgYXRFb2YgPSB0cnVlOworICAgICAgICAgICAgfQorCisJCQljcmMgPSBjcmMzMihjcmMsIGluQnVmLCBnZXRTaXplKTsKKworCQkJenN0cmVhbS5uZXh0X2luID0gaW5CdWY7CisJCQl6c3RyZWFtLmF2YWlsX2luID0gZ2V0U2l6ZTsKKwkJfQorCisJCWlmIChhdEVvZikKKwkJCWZsdXNoID0gWl9GSU5JU0g7ICAgICAgIC8qIHRlbGwgemxpYiB0aGF0IHdlJ3JlIGRvbmUgKi8KKwkJZWxzZQorCQkJZmx1c2ggPSBaX05PX0ZMVVNIOyAgICAgLyogbW9yZSB0byBjb21lISAqLworCisJCXplcnIgPSBkZWZsYXRlKCZ6c3RyZWFtLCBmbHVzaCk7CisJCWlmICh6ZXJyICE9IFpfT0sgJiYgemVyciAhPSBaX1NUUkVBTV9FTkQpIHsKKwkJCUxPR0QoInpsaWIgZGVmbGF0ZSBjYWxsIGZhaWxlZCAoemVycj0lZClcbiIsIHplcnIpOworCQkJcmVzdWx0ID0gVU5LTk9XTl9FUlJPUjsKKwkJCWdvdG8gel9iYWlsOworCQl9CisKKwkJLyogd3JpdGUgd2hlbiB3ZSdyZSBmdWxsIG9yIHdoZW4gd2UncmUgZG9uZSAqLworCQlpZiAoenN0cmVhbS5hdmFpbF9vdXQgPT0gMCB8fAorCQkJKHplcnIgPT0gWl9TVFJFQU1fRU5EICYmIHpzdHJlYW0uYXZhaWxfb3V0ICE9ICh1SW50KSBrQnVmU2l6ZSkpCisJCXsKKwkJCUxPR1YoIisrKyB3cml0aW5nICVkIGJ5dGVzXG4iLCAoaW50KSAoenN0cmVhbS5uZXh0X291dCAtIG91dEJ1ZikpOworICAgICAgICAgICAgaWYgKGZ3cml0ZShvdXRCdWYsIDEsIHpzdHJlYW0ubmV4dF9vdXQgLSBvdXRCdWYsIGRzdEZwKSAhPQorICAgICAgICAgICAgICAgIChzaXplX3QpKHpzdHJlYW0ubmV4dF9vdXQgLSBvdXRCdWYpKQorICAgICAgICAgICAgeworCQkJCUxPR0QoIndyaXRlICVkIGZhaWxlZCBpbiBkZWZsYXRlXG4iLAorICAgICAgICAgICAgICAgICAgICAoaW50KSAoenN0cmVhbS5uZXh0X291dCAtIG91dEJ1ZikpOworCQkJCWdvdG8gel9iYWlsOworCQkJfQorCisJCQl6c3RyZWFtLm5leHRfb3V0ID0gb3V0QnVmOworCQkJenN0cmVhbS5hdmFpbF9vdXQgPSBrQnVmU2l6ZTsKKwkJfQorCX0gd2hpbGUgKHplcnIgPT0gWl9PSyk7CisKKwlhc3NlcnQoemVyciA9PSBaX1NUUkVBTV9FTkQpOyAgICAgICAvKiBvdGhlciBlcnJvcnMgc2hvdWxkJ3ZlIGJlZW4gY2F1Z2h0ICovCisKKwkqcENSQzMyID0gY3JjOworCit6X2JhaWw6CisJZGVmbGF0ZUVuZCgmenN0cmVhbSk7ICAgICAgICAvKiBmcmVlIHVwIGFueSBhbGxvY2F0ZWQgc3RydWN0dXJlcyAqLworCitiYWlsOgorCWRlbGV0ZVtdIGluQnVmOworCWRlbGV0ZVtdIG91dEJ1ZjsKKworCXJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBNYXJrIGFuIGVudHJ5IGFzIGRlbGV0ZWQuCisgKgorICogV2Ugd2lsbCBldmVudHVhbGx5IG5lZWQgdG8gY3J1bmNoIHRoZSBmaWxlIGRvd24sIGJ1dCBpZiBzZXZlcmFsIGZpbGVzCisgKiBhcmUgYmVpbmcgcmVtb3ZlZCAocGVyaGFwcyBhcyBwYXJ0IG9mIGFuICJ1cGRhdGUiIHByb2Nlc3MpIHdlIGNhbiBtYWtlCisgKiB0aGluZ3MgY29uc2lkZXJhYmx5IGZhc3RlciBieSBkZWZlcnJpbmcgdGhlIHJlbW92YWwgdG8gImZsdXNoIiB0aW1lLgorICovCitzdGF0dXNfdCBaaXBGaWxlOjpyZW1vdmUoWmlwRW50cnkqIHBFbnRyeSkKK3sKKyAgICAvKgorICAgICAqIFNob3VsZCB2ZXJpZnkgdGhhdCBwRW50cnkgaXMgYWN0dWFsbHkgcGFydCBvZiB0aGlzIGFyY2hpdmUsIGFuZAorICAgICAqIG5vdCBzb21lIHN0cmF5IFppcEVudHJ5IGZyb20gYSBkaWZmZXJlbnQgZmlsZS4KKyAgICAgKi8KKworICAgIC8qIG1hcmsgZW50cnkgYXMgZGVsZXRlZCwgYW5kIG1hcmsgYXJjaGl2ZSBhcyBkaXJ0eSAqLworICAgIHBFbnRyeS0+c2V0RGVsZXRlZCgpOworICAgIG1OZWVkQ0RSZXdyaXRlID0gdHJ1ZTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBGbHVzaCBhbnkgcGVuZGluZyB3cml0ZXMuCisgKgorICogSW4gcGFydGljdWxhciwgdGhpcyB3aWxsIGNydW5jaCBvdXQgZGVsZXRlZCBlbnRyaWVzLCBhbmQgd3JpdGUgdGhlCisgKiBDZW50cmFsIERpcmVjdG9yeSBhbmQgRU9DRCBpZiB3ZSBoYXZlIHN0b21wZWQgb24gdGhlbS4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6Zmx1c2godm9pZCkKK3sKKyAgICBzdGF0dXNfdCByZXN1bHQgPSBOT19FUlJPUjsKKyAgICBsb25nIGVvY2RQb3NuOworICAgIGludCBpLCBjb3VudDsKKworICAgIGlmIChtUmVhZE9ubHkpCisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICBpZiAoIW1OZWVkQ0RSZXdyaXRlKQorICAgICAgICByZXR1cm4gTk9fRVJST1I7CisKKyAgICBhc3NlcnQobVppcEZwICE9IE5VTEwpOworCisgICAgcmVzdWx0ID0gY3J1bmNoQXJjaGl2ZSgpOworICAgIGlmIChyZXN1bHQgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiByZXN1bHQ7CisKKyAgICBpZiAoZnNlZWsobVppcEZwLCBtRU9DRC5tQ2VudHJhbERpck9mZnNldCwgU0VFS19TRVQpICE9IDApCisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworCisgICAgY291bnQgPSBtRW50cmllcy5zaXplKCk7CisgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgWmlwRW50cnkqIHBFbnRyeSA9IG1FbnRyaWVzW2ldOworICAgICAgICBwRW50cnktPm1DREUud3JpdGUobVppcEZwKTsKKyAgICB9CisKKyAgICBlb2NkUG9zbiA9IGZ0ZWxsKG1aaXBGcCk7CisgICAgbUVPQ0QubUNlbnRyYWxEaXJTaXplID0gZW9jZFBvc24gLSBtRU9DRC5tQ2VudHJhbERpck9mZnNldDsKKworICAgIG1FT0NELndyaXRlKG1aaXBGcCk7CisKKyAgICAvKgorICAgICAqIElmIHdlIGhhZCBzb21lIHN0dWZmIGJsb2F0IHVwIGR1cmluZyBjb21wcmVzc2lvbiBhbmQgZ2V0IHJlcGxhY2VkCisgICAgICogd2l0aCBwbGFpbiBmaWxlcywgb3IgaWYgd2UgZGVsZXRlZCBzb21lIGVudHJpZXMsIHRoZXJlJ3MgYSBsb3QKKyAgICAgKiBvZiB3YXN0ZWQgc3BhY2UgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZS4gIFJlbW92ZSBpdCBub3cuCisgICAgICovCisgICAgaWYgKGZ0cnVuY2F0ZShmaWxlbm8obVppcEZwKSwgZnRlbGwobVppcEZwKSkgIT0gMCkgeworICAgICAgICBMT0dXKCJmdHJ1bmNhdGUgZmFpbGVkICVsZDogJXNcbiIsIGZ0ZWxsKG1aaXBGcCksIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIC8vIG5vdCBmYXRhbAorICAgIH0KKworICAgIC8qIHNob3VsZCB3ZSBjbGVhciB0aGUgIm5ld2x5IGFkZGVkIiBmbGFnIGluIGFsbCBlbnRyaWVzIG5vdz8gKi8KKworICAgIG1OZWVkQ0RSZXdyaXRlID0gZmFsc2U7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCisvKgorICogQ3J1bmNoIGRlbGV0ZWQgZmlsZXMgb3V0IG9mIGFuIGFyY2hpdmUgYnkgc2hpZnRpbmcgdGhlIGxhdGVyIGZpbGVzIGRvd24uCisgKgorICogQmVjYXVzZSB3ZSdyZSBub3QgdXNpbmcgYSB0ZW1wIGZpbGUsIHdlIGRvIHRoZSBvcGVyYXRpb24gaW5zaWRlIHRoZQorICogY3VycmVudCBmaWxlLgorICovCitzdGF0dXNfdCBaaXBGaWxlOjpjcnVuY2hBcmNoaXZlKHZvaWQpCit7CisgICAgc3RhdHVzX3QgcmVzdWx0ID0gTk9fRVJST1I7CisgICAgaW50IGksIGNvdW50OworICAgIGxvbmcgZGVsQ291bnQsIGFkanVzdDsKKworI2lmIDAKKyAgICBwcmludGYoIkNPTlRFTlRTOlxuIik7CisgICAgZm9yIChpID0gMDsgaSA8IChpbnQpIG1FbnRyaWVzLnNpemUoKTsgaSsrKSB7CisgICAgICAgIHByaW50ZigiICVkOiBsZmhPZmY9JWxkIGRlbD0lZFxuIiwKKyAgICAgICAgICAgIGksIG1FbnRyaWVzW2ldLT5nZXRMRkhPZmZzZXQoKSwgbUVudHJpZXNbaV0tPmdldERlbGV0ZWQoKSk7CisgICAgfQorICAgIHByaW50ZigiICBFTkQgaXMgJWxkXG4iLCAobG9uZykgbUVPQ0QubUNlbnRyYWxEaXJPZmZzZXQpOworI2VuZGlmCisKKyAgICAvKgorICAgICAqIFJvbGwgdGhyb3VnaCB0aGUgc2V0IG9mIGZpbGVzLCBzaGlmdGluZyB0aGVtIGFzIGFwcHJvcHJpYXRlLiAgV2UKKyAgICAgKiBjb3VsZCBwcm9iYWJseSBnZXQgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQgYnkgc2xpZGluZworICAgICAqIG11bHRpcGxlIGZpbGVzIGRvd24gYXQgb25jZSAoYmVjYXVzZSB3ZSBjb3VsZCB1c2UgbGFyZ2VyIHJlYWRzCisgICAgICogd2hlbiBvcGVyYXRpbmcgb24gYmF0Y2hlcyBvZiBzbWFsbCBmaWxlcyksIGJ1dCBpdCdzIG5vdCB0aGF0IHVzZWZ1bC4KKyAgICAgKi8KKyAgICBjb3VudCA9IG1FbnRyaWVzLnNpemUoKTsKKyAgICBkZWxDb3VudCA9IGFkanVzdCA9IDA7CisgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgWmlwRW50cnkqIHBFbnRyeSA9IG1FbnRyaWVzW2ldOworICAgICAgICBsb25nIHNwYW47CisKKyAgICAgICAgaWYgKHBFbnRyeS0+Z2V0TEZIT2Zmc2V0KCkgIT0gMCkgeworICAgICAgICAgICAgbG9uZyBuZXh0T2Zmc2V0OworCisgICAgICAgICAgICAvKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGlzIGVudHJ5IGJ5IGZpbmRpbmcgdGhlIG9mZnNldAorICAgICAgICAgICAgICogb2YgdGhlIG5leHQgZW50cnkuICBEaXJlY3RvcnkgZW50cmllcyBkb24ndCBoYXZlCisgICAgICAgICAgICAgKiBmaWxlIG9mZnNldHMsIHNvIHdlIG5lZWQgdG8gZmluZCB0aGUgbmV4dCBub24tZGlyZWN0b3J5CisgICAgICAgICAgICAgKiBlbnRyeS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgbmV4dE9mZnNldCA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpaSA9IGkrMTsgbmV4dE9mZnNldCA9PSAwICYmIGlpIDwgY291bnQ7IGlpKyspCisgICAgICAgICAgICAgICAgbmV4dE9mZnNldCA9IG1FbnRyaWVzW2lpXS0+Z2V0TEZIT2Zmc2V0KCk7CisgICAgICAgICAgICBpZiAobmV4dE9mZnNldCA9PSAwKQorICAgICAgICAgICAgICAgIG5leHRPZmZzZXQgPSBtRU9DRC5tQ2VudHJhbERpck9mZnNldDsKKyAgICAgICAgICAgIHNwYW4gPSBuZXh0T2Zmc2V0IC0gcEVudHJ5LT5nZXRMRkhPZmZzZXQoKTsKKworICAgICAgICAgICAgYXNzZXJ0KHNwYW4gPj0gWmlwRW50cnk6OkxvY2FsRmlsZUhlYWRlcjo6a0xGSExlbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvKiBUaGlzIGlzIGEgZGlyZWN0b3J5IGVudHJ5LiAgSXQgZG9lc24ndCBoYXZlCisgICAgICAgICAgICAgKiBhbnkgYWN0dWFsIGZpbGUgY29udGVudHMsIHNvIHRoZXJlJ3Mgbm8gbmVlZCB0bworICAgICAgICAgICAgICogbW92ZSBhbnl0aGluZy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgc3BhbiA9IDA7CisgICAgICAgIH0KKworICAgICAgICAvL3ByaW50ZigiKysrICVkOiBvZmY9JWxkIHNwYW49JWxkIGRlbD0lZCBbY291bnQ9JWRdXG4iLAorICAgICAgICAvLyAgICBpLCBwRW50cnktPmdldExGSE9mZnNldCgpLCBzcGFuLCBwRW50cnktPmdldERlbGV0ZWQoKSwgY291bnQpOworCisgICAgICAgIGlmIChwRW50cnktPmdldERlbGV0ZWQoKSkgeworICAgICAgICAgICAgYWRqdXN0ICs9IHNwYW47CisgICAgICAgICAgICBkZWxDb3VudCsrOworCisgICAgICAgICAgICBkZWxldGUgcEVudHJ5OworICAgICAgICAgICAgbUVudHJpZXMucmVtb3ZlQXQoaSk7CisKKyAgICAgICAgICAgIC8qIGFkanVzdCBsb29wIGNvbnRyb2wgKi8KKyAgICAgICAgICAgIGNvdW50LS07CisgICAgICAgICAgICBpLS07CisgICAgICAgIH0gZWxzZSBpZiAoc3BhbiAhPSAwICYmIGFkanVzdCA+IDApIHsKKyAgICAgICAgICAgIC8qIHNodWZmbGUgdGhpcyBlbnRyeSBiYWNrICovCisgICAgICAgICAgICAvL3ByaW50ZigiKysrIFNodWZmbGluZyAnJXMnIGJhY2sgJWxkXG4iLAorICAgICAgICAgICAgLy8gICAgcEVudHJ5LT5nZXRGaWxlTmFtZSgpLCBhZGp1c3QpOworICAgICAgICAgICAgcmVzdWx0ID0gZmlsZW1vdmUobVppcEZwLCBwRW50cnktPmdldExGSE9mZnNldCgpIC0gYWRqdXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgcEVudHJ5LT5nZXRMRkhPZmZzZXQoKSwgc3Bhbik7CisgICAgICAgICAgICBpZiAocmVzdWx0ICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgLyogdGhpcyBpcyB3aHkgeW91IHVzZSBhIHRlbXAgZmlsZSAqLworICAgICAgICAgICAgICAgIExPR0UoImVycm9yIGR1cmluZyBjcnVuY2ggLSBhcmNoaXZlIGlzIHRvYXN0XG4iKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwRW50cnktPnNldExGSE9mZnNldChwRW50cnktPmdldExGSE9mZnNldCgpIC0gYWRqdXN0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogRml4IEVPQ0QgaW5mby4gIFdlIGhhdmUgdG8gd2FpdCB1bnRpbCB0aGUgZW5kIHRvIGRvIHNvbWUgb2YgdGhpcworICAgICAqIGJlY2F1c2Ugd2UgdXNlIG1DZW50cmFsRGlyT2Zmc2V0IHRvIGRldGVybWluZSAic3BhbiIgZm9yIHRoZQorICAgICAqIGxhc3QgZW50cnkuCisgICAgICovCisgICAgbUVPQ0QubUNlbnRyYWxEaXJPZmZzZXQgLT0gYWRqdXN0OworICAgIG1FT0NELm1OdW1FbnRyaWVzIC09IGRlbENvdW50OworICAgIG1FT0NELm1Ub3RhbE51bUVudHJpZXMgLT0gZGVsQ291bnQ7CisgICAgbUVPQ0QubUNlbnRyYWxEaXJTaXplID0gMDsgIC8vIG1hcmsgaW52YWxpZDsgc2V0IGJ5IGZsdXNoKCkKKworICAgIGFzc2VydChtRU9DRC5tTnVtRW50cmllcyA9PSBtRU9DRC5tVG90YWxOdW1FbnRyaWVzKTsKKyAgICBhc3NlcnQobUVPQ0QubU51bUVudHJpZXMgPT0gY291bnQpOworCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAqIFdvcmtzIGxpa2UgbWVtbW92ZSgpLCBidXQgb24gcGllY2VzIG9mIGEgZmlsZS4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6ZmlsZW1vdmUoRklMRSogZnAsIG9mZl90IGRzdCwgb2ZmX3Qgc3JjLCBzaXplX3QgbikKK3sKKyAgICBpZiAoZHN0ID09IHNyYyB8fCBuIDw9IDApCisgICAgICAgIHJldHVybiBOT19FUlJPUjsKKworICAgIHVuc2lnbmVkIGNoYXIgcmVhZEJ1ZlszMjc2OF07CisKKyAgICBpZiAoZHN0IDwgc3JjKSB7CisgICAgICAgIC8qIHNoaWZ0IHN0dWZmIHRvd2FyZCBzdGFydCBvZiBmaWxlOyBtdXN0IHJlYWQgZnJvbSBzdGFydCAqLworICAgICAgICB3aGlsZSAobiAhPSAwKSB7CisgICAgICAgICAgICBzaXplX3QgZ2V0U2l6ZSA9IHNpemVvZihyZWFkQnVmKTsKKyAgICAgICAgICAgIGlmIChnZXRTaXplID4gbikKKyAgICAgICAgICAgICAgICBnZXRTaXplID0gbjsKKworICAgICAgICAgICAgaWYgKGZzZWVrKGZwLCAobG9uZykgc3JjLCBTRUVLX1NFVCkgIT0gMCkgeworICAgICAgICAgICAgICAgIExPR0QoImZpbGVtb3ZlIHNyYyBzZWVrICVsZCBmYWlsZWRcbiIsIChsb25nKSBzcmMpOworICAgICAgICAgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZnJlYWQocmVhZEJ1ZiwgMSwgZ2V0U2l6ZSwgZnApICE9IGdldFNpemUpIHsKKyAgICAgICAgICAgICAgICBMT0dEKCJmaWxlbW92ZSByZWFkICVsZCBvZmY9JWxkIGZhaWxlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgKGxvbmcpIGdldFNpemUsIChsb25nKSBzcmMpOworICAgICAgICAgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZnNlZWsoZnAsIChsb25nKSBkc3QsIFNFRUtfU0VUKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgTE9HRCgiZmlsZW1vdmUgZHN0IHNlZWsgJWxkIGZhaWxlZFxuIiwgKGxvbmcpIGRzdCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChmd3JpdGUocmVhZEJ1ZiwgMSwgZ2V0U2l6ZSwgZnApICE9IGdldFNpemUpIHsKKyAgICAgICAgICAgICAgICBMT0dEKCJmaWxlbW92ZSB3cml0ZSAlbGQgb2ZmPSVsZCBmYWlsZWRcbiIsCisgICAgICAgICAgICAgICAgICAgIChsb25nKSBnZXRTaXplLCAobG9uZykgZHN0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3JjICs9IGdldFNpemU7CisgICAgICAgICAgICBkc3QgKz0gZ2V0U2l6ZTsKKyAgICAgICAgICAgIG4gLT0gZ2V0U2l6ZTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8qIHNoaWZ0IHN0dWZmIHRvd2FyZCBlbmQgb2YgZmlsZTsgbXVzdCByZWFkIGZyb20gZW5kICovCisgICAgICAgIGFzc2VydChmYWxzZSk7ICAgICAgLy8gd3JpdGUgdGhpcyBzb21lZGF5LCBtYXliZQorICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKworLyoKKyAqIEdldCB0aGUgbW9kaWZpY2F0aW9uIHRpbWUgZnJvbSBhIGZpbGUgZGVzY3JpcHRvci4KKyAqLwordGltZV90IFppcEZpbGU6OmdldE1vZFRpbWUoaW50IGZkKQoreworICAgIHN0cnVjdCBzdGF0IHNiOworCisgICAgaWYgKGZzdGF0KGZkLCAmc2IpIDwgMCkgeworICAgICAgICBMT0dEKCJIRVk6IGZzdGF0IG9uIGZkICVkIGZhaWxlZFxuIiwgZmQpOworICAgICAgICByZXR1cm4gKHRpbWVfdCkgLTE7CisgICAgfQorCisgICAgcmV0dXJuIHNiLnN0X210aW1lOworfQorCisKKyNpZiAwICAgICAgIC8qIHRoaXMgaXMgYSBiYWQgaWRlYSAqLworLyoKKyAqIEdldCBhIGNvcHkgb2YgdGhlIFppcCBmaWxlIGRlc2NyaXB0b3IuCisgKgorICogV2UgZG9uJ3QgYWxsb3cgdGhpcyBpZiB0aGUgZmlsZSB3YXMgb3BlbmVkIHJlYWQtd3JpdGUgYmVjYXVzZSB3ZSB0ZW5kCisgKiB0byBsZWF2ZSB0aGUgZmlsZSBjb250ZW50cyBpbiBhbiB1bmNlcnRhaW4gc3RhdGUgYmV0d2VlbiBjYWxscyB0bworICogZmx1c2goKS4gIFRoZSBkdXBsaWNhdGVkIGZpbGUgZGVzY3JpcHRvciBzaG91bGQgb25seSBiZSB2YWxpZCBmb3IgcmVhZHMuCisgKi8KK2ludCBaaXBGaWxlOjpnZXRaaXBGZCh2b2lkKSBjb25zdAoreworICAgIGlmICghbVJlYWRPbmx5KQorICAgICAgICByZXR1cm4gSU5WQUxJRF9PUEVSQVRJT047CisgICAgYXNzZXJ0KG1aaXBGcCAhPSBOVUxMKTsKKworICAgIGludCBmZDsKKyAgICBmZCA9IGR1cChmaWxlbm8obVppcEZwKSk7CisgICAgaWYgKGZkIDwgMCkgeworICAgICAgICBMT0dEKCJkaWRuJ3Qgd29yaywgZXJybm89JWRcbiIsIGVycm5vKTsKKyAgICB9CisKKyAgICByZXR1cm4gZmQ7Cit9CisjZW5kaWYKKworCisjaWYgMAorLyoKKyAqIEV4cGFuZCBkYXRhLgorICovCitib29sIFppcEZpbGU6OnVuY29tcHJlc3MoY29uc3QgWmlwRW50cnkqIHBFbnRyeSwgdm9pZCogYnVmKSBjb25zdAoreworICAgIHJldHVybiBmYWxzZTsKK30KKyNlbmRpZgorCisvLyBmcmVlIHRoZSBtZW1vcnkgd2hlbiB5b3UncmUgZG9uZQordm9pZCogWmlwRmlsZTo6dW5jb21wcmVzcyhjb25zdCBaaXBFbnRyeSogZW50cnkpCit7CisgICAgc2l6ZV90IHVubGVuID0gZW50cnktPmdldFVuY29tcHJlc3NlZExlbigpOworICAgIHNpemVfdCBjbGVuID0gZW50cnktPmdldENvbXByZXNzZWRMZW4oKTsKKworICAgIHZvaWQqIGJ1ZiA9IG1hbGxvYyh1bmxlbik7CisgICAgaWYgKGJ1ZiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGZzZWVrKG1aaXBGcCwgMCwgU0VFS19TRVQpOworCisgICAgb2ZmX3Qgb2Zmc2V0ID0gZW50cnktPmdldEZpbGVPZmZzZXQoKTsKKyAgICBpZiAoZnNlZWsobVppcEZwLCBvZmZzZXQsIFNFRUtfU0VUKSAhPSAwKSB7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICBzd2l0Y2ggKGVudHJ5LT5nZXRDb21wcmVzc2lvbk1ldGhvZCgpKQorICAgIHsKKyAgICAgICAgY2FzZSBaaXBFbnRyeTo6a0NvbXByZXNzU3RvcmVkOiB7CisgICAgICAgICAgICBzc2l6ZV90IGFtdCA9IGZyZWFkKGJ1ZiwgMSwgdW5sZW4sIG1aaXBGcCk7CisgICAgICAgICAgICBpZiAoYW10ICE9IChzc2l6ZV90KXVubGVuKSB7CisgICAgICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICAgICAgfQorI2lmIDAKKyAgICAgICAgICAgIHByaW50ZigiZGF0YS4uLlxuIik7CisgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBwID0gKHVuc2lnbmVkIGNoYXIqKWJ1ZjsKKyAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIGVuZCA9IHArdW5sZW47CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8MzIgJiYgcCA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcHJpbnRmKCIweCUwOHggIiwgKGludCkob2Zmc2V0KyhpKjB4MTApKSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaj0wOyBqPDB4MTAgJiYgcCA8IGVuZDsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHByaW50ZigiICUwMngiLCAqcCk7CisgICAgICAgICAgICAgICAgICAgIHArKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcHJpbnRmKCJcbiIpOworICAgICAgICAgICAgfQorI2VuZGlmCisKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFppcEVudHJ5OjprQ29tcHJlc3NEZWZsYXRlZDogeworICAgICAgICAgICAgaWYgKCFaaXBVdGlsczo6aW5mbGF0ZVRvQnVmZmVyKG1aaXBGcCwgYnVmLCB1bmxlbiwgY2xlbikpIHsKKyAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisgICAgcmV0dXJuIGJ1ZjsKKworYmFpbDoKKyAgICBmcmVlKGJ1Zik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKworLyoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICoJCVppcEZpbGU6OkVuZE9mQ2VudHJhbERpcgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKi8KKworLyoKKyAqIFJlYWQgdGhlIGVuZC1vZi1jZW50cmFsLWRpciBmaWVsZHMuCisgKgorICogImJ1ZiIgc2hvdWxkIGJlIHBvc2l0aW9uZWQgYXQgdGhlIEVPQ0Qgc2lnbmF0dXJlLCBhbmQgc2hvdWxkIGNvbnRhaW4KKyAqIHRoZSBlbnRpcmUgRU9DRCBhcmVhIGluY2x1ZGluZyB0aGUgY29tbWVudC4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6RW5kT2ZDZW50cmFsRGlyOjpyZWFkQnVmKGNvbnN0IHVuc2lnbmVkIGNoYXIqIGJ1ZiwgaW50IGxlbikKK3sKKyAgICAvKiBkb24ndCBhbGxvdyByZS11c2UgKi8KKyAgICBhc3NlcnQobUNvbW1lbnQgPT0gTlVMTCk7CisKKyAgICBpZiAobGVuIDwga0VPQ0RMZW4pIHsKKyAgICAgICAgLyogbG9va3MgbGlrZSBaSVAgZmlsZSBnb3QgdHJ1bmNhdGVkICovCisgICAgICAgIExPR0QoIiBaaXAgRU9DRDogZXhwZWN0ZWQgPj0gJWQgYnl0ZXMsIGZvdW5kICVkXG4iLAorICAgICAgICAgICAga0VPQ0RMZW4sIGxlbik7CisgICAgICAgIHJldHVybiBJTlZBTElEX09QRVJBVElPTjsKKyAgICB9CisKKyAgICAvKiB0aGlzIHNob3VsZCBwcm9iYWJseSBiZSBhbiBhc3NlcnQoKSAqLworICAgIGlmIChaaXBFbnRyeTo6Z2V0TG9uZ0xFKCZidWZbMHgwMF0pICE9IGtTaWduYXR1cmUpCisgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworCisgICAgbURpc2tOdW1iZXIgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDRdKTsKKyAgICBtRGlza1dpdGhDZW50cmFsRGlyID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDA2XSk7CisgICAgbU51bUVudHJpZXMgPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MDhdKTsKKyAgICBtVG90YWxOdW1FbnRyaWVzID0gWmlwRW50cnk6OmdldFNob3J0TEUoJmJ1ZlsweDBhXSk7CisgICAgbUNlbnRyYWxEaXJTaXplID0gWmlwRW50cnk6OmdldExvbmdMRSgmYnVmWzB4MGNdKTsKKyAgICBtQ2VudHJhbERpck9mZnNldCA9IFppcEVudHJ5OjpnZXRMb25nTEUoJmJ1ZlsweDEwXSk7CisgICAgbUNvbW1lbnRMZW4gPSBaaXBFbnRyeTo6Z2V0U2hvcnRMRSgmYnVmWzB4MTRdKTsKKworICAgIC8vIFRPRE86IHZhbGlkYXRlIG1DZW50cmFsRGlyT2Zmc2V0CisKKyAgICBpZiAobUNvbW1lbnRMZW4gPiAwKSB7CisgICAgICAgIGlmIChrRU9DRExlbiArIG1Db21tZW50TGVuID4gbGVuKSB7CisgICAgICAgICAgICBMT0dEKCJFT0NEKCVkKSArIGNvbW1lbnQoJWQpIGV4Y2VlZHMgbGVuICglZClcbiIsCisgICAgICAgICAgICAgICAga0VPQ0RMZW4sIG1Db21tZW50TGVuLCBsZW4pOworICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgICAgIH0KKyAgICAgICAgbUNvbW1lbnQgPSBuZXcgdW5zaWduZWQgY2hhclttQ29tbWVudExlbl07CisgICAgICAgIG1lbWNweShtQ29tbWVudCwgYnVmICsga0VPQ0RMZW4sIG1Db21tZW50TGVuKTsKKyAgICB9CisKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKKy8qCisgKiBXcml0ZSBhbiBlbmQtb2YtY2VudHJhbC1kaXJlY3Rvcnkgc2VjdGlvbi4KKyAqLworc3RhdHVzX3QgWmlwRmlsZTo6RW5kT2ZDZW50cmFsRGlyOjp3cml0ZShGSUxFKiBmcCkKK3sKKyAgICB1bnNpZ25lZCBjaGFyIGJ1ZltrRU9DRExlbl07CisKKyAgICBaaXBFbnRyeTo6cHV0TG9uZ0xFKCZidWZbMHgwMF0sIGtTaWduYXR1cmUpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgwNF0sIG1EaXNrTnVtYmVyKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MDZdLCBtRGlza1dpdGhDZW50cmFsRGlyKTsKKyAgICBaaXBFbnRyeTo6cHV0U2hvcnRMRSgmYnVmWzB4MDhdLCBtTnVtRW50cmllcyk7CisgICAgWmlwRW50cnk6OnB1dFNob3J0TEUoJmJ1ZlsweDBhXSwgbVRvdGFsTnVtRW50cmllcyk7CisgICAgWmlwRW50cnk6OnB1dExvbmdMRSgmYnVmWzB4MGNdLCBtQ2VudHJhbERpclNpemUpOworICAgIFppcEVudHJ5OjpwdXRMb25nTEUoJmJ1ZlsweDEwXSwgbUNlbnRyYWxEaXJPZmZzZXQpOworICAgIFppcEVudHJ5OjpwdXRTaG9ydExFKCZidWZbMHgxNF0sIG1Db21tZW50TGVuKTsKKworICAgIGlmIChmd3JpdGUoYnVmLCAxLCBrRU9DRExlbiwgZnApICE9IGtFT0NETGVuKQorICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICBpZiAobUNvbW1lbnRMZW4gPiAwKSB7CisgICAgICAgIGFzc2VydChtQ29tbWVudCAhPSBOVUxMKTsKKyAgICAgICAgaWYgKGZ3cml0ZShtQ29tbWVudCwgbUNvbW1lbnRMZW4sIDEsIGZwKSAhPSBtQ29tbWVudExlbikKKyAgICAgICAgICAgIHJldHVybiBVTktOT1dOX0VSUk9SOworICAgIH0KKworICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLyoKKyAqIER1bXAgdGhlIGNvbnRlbnRzIG9mIGFuIEVuZE9mQ2VudHJhbERpciBvYmplY3QuCisgKi8KK3ZvaWQgWmlwRmlsZTo6RW5kT2ZDZW50cmFsRGlyOjpkdW1wKHZvaWQpIGNvbnN0Cit7CisgICAgTE9HRCgiIEVuZE9mQ2VudHJhbERpciBjb250ZW50czpcbiIpOworICAgIExPR0QoIiAgZGlza051bT0ldSBkaXNrV0NEPSV1IG51bUVudD0ldSB0b3RhbE51bUVudD0ldVxuIiwKKyAgICAgICAgbURpc2tOdW1iZXIsIG1EaXNrV2l0aENlbnRyYWxEaXIsIG1OdW1FbnRyaWVzLCBtVG90YWxOdW1FbnRyaWVzKTsKKyAgICBMT0dEKCIgIGNlbnREaXJTaXplPSVsdSBjZW50RGlyT2ZmPSVsdSBjb21tZW50TGVuPSV1XG4iLAorICAgICAgICBtQ2VudHJhbERpclNpemUsIG1DZW50cmFsRGlyT2Zmc2V0LCBtQ29tbWVudExlbik7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvWmlwRmlsZUNSTy5jcHAgYi9saWJzL3V0aWxzL1ppcEZpbGVDUk8uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzMTJkYWYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1ppcEZpbGVDUk8uY3BwCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSAidXRpbHMvWmlwRmlsZUNSTy5oIgorI2luY2x1ZGUgInV0aWxzL1ppcEZpbGVSTy5oIgorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworWmlwRmlsZUNSTyBaaXBGaWxlWFJPX29wZW4oY29uc3QgY2hhciogcGF0aCkgeworICAgIFppcEZpbGVSTyogemlwID0gbmV3IFppcEZpbGVSTygpOworICAgIGlmICh6aXAtPm9wZW4ocGF0aCkgPT0gTk9fRVJST1IpIHsKKyAgICAgICAgcmV0dXJuIChaaXBGaWxlQ1JPKXppcDsKKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgWmlwRmlsZUNST19kZXN0cm95KFppcEZpbGVDUk8gemlwVG9rZW4pIHsKKyAgICBaaXBGaWxlUk8qIHppcCA9IChaaXBGaWxlUk8qKXppcFRva2VuOworICAgIGRlbGV0ZSB6aXA7Cit9CisKK1ppcEVudHJ5Q1JPIFppcEZpbGVDUk9fZmluZEVudHJ5QnlOYW1lKFppcEZpbGVDUk8gemlwVG9rZW4sCisgICAgICAgIGNvbnN0IGNoYXIqIGZpbGVOYW1lKSB7CisgICAgWmlwRmlsZVJPKiB6aXAgPSAoWmlwRmlsZVJPKil6aXBUb2tlbjsKKyAgICByZXR1cm4gKFppcEVudHJ5Q1JPKXppcC0+ZmluZEVudHJ5QnlOYW1lKGZpbGVOYW1lKTsKK30KKworYm9vbCBaaXBGaWxlQ1JPX2dldEVudHJ5SW5mbyhaaXBGaWxlQ1JPIHppcFRva2VuLCBaaXBFbnRyeVJPIGVudHJ5VG9rZW4sCisgICAgICAgIGludCogcE1ldGhvZCwgbG9uZyogcFVuY29tcExlbiwKKyAgICAgICAgbG9uZyogcENvbXBMZW4sIG9mZl90KiBwT2Zmc2V0LCBsb25nKiBwTW9kV2hlbiwgbG9uZyogcENyYzMyKSB7CisgICAgWmlwRmlsZVJPKiB6aXAgPSAoWmlwRmlsZVJPKil6aXBUb2tlbjsKKyAgICBaaXBFbnRyeVJPIGVudHJ5ID0gKFppcEVudHJ5Uk8pZW50cnlUb2tlbjsKKyAgICByZXR1cm4gemlwLT5nZXRFbnRyeUluZm8oZW50cnksIHBNZXRob2QsIHBVbmNvbXBMZW4sIHBDb21wTGVuLCBwT2Zmc2V0LAorICAgICAgICAgICAgcE1vZFdoZW4sIHBDcmMzMik7Cit9CisKK2Jvb2wgWmlwRmlsZUNST191bmNvbXByZXNzRW50cnkoWmlwRmlsZUNSTyB6aXBUb2tlbiwgWmlwRW50cnlSTyBlbnRyeVRva2VuLCBpbnQgZmQpIHsKKyAgICBaaXBGaWxlUk8qIHppcCA9IChaaXBGaWxlUk8qKXppcFRva2VuOworICAgIFppcEVudHJ5Uk8gZW50cnkgPSAoWmlwRW50cnlSTyllbnRyeVRva2VuOworICAgIHJldHVybiB6aXAtPnVuY29tcHJlc3NFbnRyeShlbnRyeSwgZmQpOworfQpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9aaXBGaWxlUk8uY3BwIGIvbGlicy91dGlscy9aaXBGaWxlUk8uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlOGM3MTkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL1ppcEZpbGVSTy5jcHAKQEAgLTAsMCArMSw3MjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gUmVhZC1vbmx5IGFjY2VzcyB0byBaaXAgYXJjaGl2ZXMsIHdpdGggbWluaW1hbCBoZWFwIGFsbG9jYXRpb24uCisvLworI2RlZmluZSBMT0dfVEFHICJ6aXBybyIKKy8vI2RlZmluZSBMT0dfTkRFQlVHIDAKKyNpbmNsdWRlICJ1dGlscy9aaXBGaWxlUk8uaCIKKyNpbmNsdWRlICJ1dGlscy9Mb2cuaCIKKyNpbmNsdWRlICJ1dGlscy9taXNjLmgiCisKKyNpbmNsdWRlIDx6bGliLmg+CisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisvKgorICogWmlwIGZpbGUgY29uc3RhbnRzLgorICovCisjZGVmaW5lIGtFT0NEU2lnbmF0dXJlICAgICAgMHgwNjA1NGI1MAorI2RlZmluZSBrRU9DRExlbiAgICAgICAgICAgIDIyCisjZGVmaW5lIGtFT0NETnVtRW50cmllcyAgICAgOCAgICAgICAgICAgICAgIC8vIG9mZnNldCB0byAjb2YgZW50cmllcyBpbiBmaWxlCisjZGVmaW5lIGtFT0NERmlsZU9mZnNldCAgICAgMTYgICAgICAgICAgICAgIC8vIG9mZnNldCB0byBjZW50cmFsIGRpcmVjdG9yeQorCisjZGVmaW5lIGtNYXhDb21tZW50TGVuICAgICAgNjU1MzUgICAgICAgICAgIC8vIGxvbmdlc3QgcG9zc2libGUgaW4gdXNob3J0CisjZGVmaW5lIGtNYXhFT0NEU2VhcmNoICAgICAgKGtNYXhDb21tZW50TGVuICsga0VPQ0RMZW4pCisKKyNkZWZpbmUga0xGSFNpZ25hdHVyZSAgICAgICAweDA0MDM0YjUwCisjZGVmaW5lIGtMRkhMZW4gICAgICAgICAgICAgMzAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGluZyB2YXJpYWJsZS1sZW4gZmllbGRzCisjZGVmaW5lIGtMRkhOYW1lTGVuICAgICAgICAgMjYgICAgICAgICAgICAgIC8vIG9mZnNldCB0byBmaWxlbmFtZSBsZW5ndGgKKyNkZWZpbmUga0xGSEV4dHJhTGVuICAgICAgICAyOCAgICAgICAgICAgICAgLy8gb2Zmc2V0IHRvIGV4dHJhIGxlbmd0aAorCisjZGVmaW5lIGtDREVTaWduYXR1cmUgICAgICAgMHgwMjAxNGI1MAorI2RlZmluZSBrQ0RFTGVuICAgICAgICAgICAgIDQ2ICAgICAgICAgICAgICAvLyBleGNsdWRpbmcgdmFyaWFibGUtbGVuIGZpZWxkcworI2RlZmluZSBrQ0RFTWV0aG9kICAgICAgICAgIDEwICAgICAgICAgICAgICAvLyBvZmZzZXQgdG8gY29tcHJlc3Npb24gbWV0aG9kCisjZGVmaW5lIGtDREVNb2RXaGVuICAgICAgICAgMTIgICAgICAgICAgICAgIC8vIG9mZnNldCB0byBtb2RpZmljYXRpb24gdGltZXN0YW1wCisjZGVmaW5lIGtDREVDUkMgICAgICAgICAgICAgMTYgICAgICAgICAgICAgIC8vIG9mZnNldCB0byBlbnRyeSBDUkMKKyNkZWZpbmUga0NERUNvbXBMZW4gICAgICAgICAyMCAgICAgICAgICAgICAgLy8gb2Zmc2V0IHRvIGNvbXByZXNzZWQgbGVuZ3RoCisjZGVmaW5lIGtDREVVbmNvbXBMZW4gICAgICAgMjQgICAgICAgICAgICAgIC8vIG9mZnNldCB0byB1bmNvbXByZXNzZWQgbGVuZ3RoCisjZGVmaW5lIGtDREVOYW1lTGVuICAgICAgICAgMjggICAgICAgICAgICAgIC8vIG9mZnNldCB0byBmaWxlbmFtZSBsZW5ndGgKKyNkZWZpbmUga0NERUV4dHJhTGVuICAgICAgICAzMCAgICAgICAgICAgICAgLy8gb2Zmc2V0IHRvIGV4dHJhIGxlbmd0aAorI2RlZmluZSBrQ0RFQ29tbWVudExlbiAgICAgIDMyICAgICAgICAgICAgICAvLyBvZmZzZXQgdG8gY29tbWVudCBsZW5ndGgKKyNkZWZpbmUga0NERUxvY2FsT2Zmc2V0ICAgICA0MiAgICAgICAgICAgICAgLy8gb2Zmc2V0IHRvIGxvY2FsIGhkcgorCisvKgorICogVGhlIHZhbHVlcyB3ZSByZXR1cm4gZm9yIFppcEVudHJ5Uk8gdXNlIDAgYXMgYW4gaW52YWxpZCB2YWx1ZSwgc28gd2UKKyAqIHdhbnQgdG8gYWRqdXN0IHRoZSBoYXNoIHRhYmxlIGluZGV4IGJ5IGEgZml4ZWQgYW1vdW50LiAgVXNpbmcgYSBsYXJnZQorICogdmFsdWUgaGVscHMgaW5zdXJlIHRoYXQgcGVvcGxlIGRvbid0IG1peCAmIG1hdGNoIGFyZ3VtZW50cywgZS5nLiB0bworICogZmluZEVudHJ5QnlJbmRleCgpLgorICovCisjZGVmaW5lIGtaaXBFbnRyeUFkaiAgICAgICAgMTAwMDAKKworLyoKKyAqIENvbnZlcnQgYSBaaXBFbnRyeVJPIHRvIGEgaGFzaCB0YWJsZSBpbmRleCwgdmVyaWZ5aW5nIHRoYXQgaXQncyBpbiBhCisgKiB2YWxpZCByYW5nZS4KKyAqLworaW50IFppcEZpbGVSTzo6ZW50cnlUb0luZGV4KGNvbnN0IFppcEVudHJ5Uk8gZW50cnkpIGNvbnN0Cit7CisgICAgbG9uZyBlbnQgPSAoKGxvbmcpIGVudHJ5KSAtIGtaaXBFbnRyeUFkajsKKyAgICBpZiAoZW50IDwgMCB8fCBlbnQgPj0gbUhhc2hUYWJsZVNpemUgfHwgbUhhc2hUYWJsZVtlbnRdLm5hbWUgPT0gTlVMTCkgeworICAgICAgICBMT0dXKCJJbnZhbGlkIFppcEVudHJ5Uk8gJXAgKCVsZClcbiIsIGVudHJ5LCBlbnQpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiBlbnQ7Cit9CisKKworLyoKKyAqIE9wZW4gdGhlIHNwZWNpZmllZCBmaWxlIHJlYWQtb25seS4gIFdlIG1lbW9yeS1tYXAgdGhlIGVudGlyZSB0aGluZyBhbmQKKyAqIGNsb3NlIHRoZSBmaWxlIGJlZm9yZSByZXR1cm5pbmcuCisgKi8KK3N0YXR1c190IFppcEZpbGVSTzo6b3Blbihjb25zdCBjaGFyKiB6aXBGaWxlTmFtZSkKK3sKKyAgICBpbnQgZmQgPSAtMTsKKyAgICBvZmZfdCBsZW5ndGg7CisKKyAgICBhc3NlcnQobUZpbGVNYXAgPT0gTlVMTCk7CisKKyAgICAvKgorICAgICAqIE9wZW4gYW5kIG1hcCB0aGUgc3BlY2lmaWVkIGZpbGUuCisgICAgICovCisgICAgZmQgPSA6Om9wZW4oemlwRmlsZU5hbWUsIE9fUkRPTkxZKTsKKyAgICBpZiAoZmQgPCAwKSB7CisgICAgICAgIExPR1coIlVuYWJsZSB0byBvcGVuIHppcCAnJXMnOiAlc1xuIiwgemlwRmlsZU5hbWUsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgIHJldHVybiBOQU1FX05PVF9GT1VORDsKKyAgICB9CisKKyAgICBsZW5ndGggPSBsc2VlayhmZCwgMCwgU0VFS19FTkQpOworICAgIGlmIChsZW5ndGggPCAwKSB7CisgICAgICAgIGNsb3NlKGZkKTsKKyAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgfQorCisgICAgbUZpbGVNYXAgPSBuZXcgRmlsZU1hcCgpOworICAgIGlmIChtRmlsZU1hcCA9PSBOVUxMKSB7CisgICAgICAgIGNsb3NlKGZkKTsKKyAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICB9CisgICAgaWYgKCFtRmlsZU1hcC0+Y3JlYXRlKHppcEZpbGVOYW1lLCBmZCwgMCwgbGVuZ3RoLCB0cnVlKSkgeworICAgICAgICBMT0dXKCJVbmFibGUgdG8gbWFwICclcyc6ICVzXG4iLCB6aXBGaWxlTmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICAgICAgY2xvc2UoZmQpOworICAgICAgICByZXR1cm4gVU5LTk9XTl9FUlJPUjsKKyAgICB9CisKKyAgICBtRmQgPSBmZDsKKworICAgIC8qCisgICAgICogR290IGl0IG1hcHBlZCwgdmVyaWZ5IGl0IGFuZCBjcmVhdGUgZGF0YSBzdHJ1Y3R1cmVzIGZvciBmYXN0IGFjY2Vzcy4KKyAgICAgKi8KKyAgICBpZiAoIXBhcnNlWmlwQXJjaGl2ZSgpKSB7CisgICAgICAgIG1GaWxlTWFwLT5yZWxlYXNlKCk7CisgICAgICAgIG1GaWxlTWFwID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIFVOS05PV05fRVJST1I7CisgICAgfQorCisgICAgcmV0dXJuIE9LOworfQorCisvKgorICogUGFyc2UgdGhlIFppcCBhcmNoaXZlLCB2ZXJpZnlpbmcgaXRzIGNvbnRlbnRzIGFuZCBpbml0aWFsaXppbmcgaW50ZXJuYWwKKyAqIGRhdGEgc3RydWN0dXJlcy4KKyAqLworYm9vbCBaaXBGaWxlUk86OnBhcnNlWmlwQXJjaGl2ZSh2b2lkKQoreworI2RlZmluZSBDSEVDS19PRkZTRVQoX29mZikgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKCh1bnNpZ25lZCBpbnQpIChfb2ZmKSA+PSBtYXhPZmZzZXQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBMT0dFKCJFUlJPUjogYmFkIG9mZnNldCAldSAobWF4ICVkKTogJXNcbiIsICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpIChfb2ZmKSwgbWF4T2Zmc2V0LCAjX29mZik7ICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGdvdG8gYmFpbDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBiYXNlUHRyID0gKGNvbnN0IHVuc2lnbmVkIGNoYXIqKW1GaWxlTWFwLT5nZXREYXRhUHRyKCk7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciogcHRyOworICAgIHNpemVfdCBsZW5ndGggPSBtRmlsZU1hcC0+Z2V0RGF0YUxlbmd0aCgpOworICAgIGJvb2wgcmVzdWx0ID0gZmFsc2U7CisgICAgdW5zaWduZWQgaW50IGksIG51bUVudHJpZXMsIGNkT2Zmc2V0OworICAgIHVuc2lnbmVkIGludCB2YWw7CisKKyAgICAvKgorICAgICAqIFRoZSBmaXJzdCA0IGJ5dGVzIG9mIHRoZSBmaWxlIHdpbGwgZWl0aGVyIGJlIHRoZSBsb2NhbCBoZWFkZXIKKyAgICAgKiBzaWduYXR1cmUgZm9yIHRoZSBmaXJzdCBmaWxlIChrTEZIU2lnbmF0dXJlKSBvciwgaWYgdGhlIGFyY2hpdmUgZG9lc24ndAorICAgICAqIGhhdmUgYW55IGZpbGVzIGluIGl0LCB0aGUgZW5kLW9mLWNlbnRyYWwtZGlyZWN0b3J5IHNpZ25hdHVyZQorICAgICAqIChrRU9DRFNpZ25hdHVyZSkuCisgICAgICovCisgICAgdmFsID0gZ2V0NExFKGJhc2VQdHIpOworICAgIGlmICh2YWwgPT0ga0VPQ0RTaWduYXR1cmUpIHsKKyAgICAgICAgTE9HSSgiRm91bmQgWmlwIGFyY2hpdmUsIGJ1dCBpdCBsb29rcyBlbXB0eVxuIik7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9IGVsc2UgaWYgKHZhbCAhPSBrTEZIU2lnbmF0dXJlKSB7CisgICAgICAgIExPR1YoIk5vdCBhIFppcCBhcmNoaXZlIChmb3VuZCAweCUwOHgpXG4iLCB2YWwpOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGaW5kIHRoZSBFT0NELiAgV2UnbGwgZmluZCBpdCBpbW1lZGlhdGVseSB1bmxlc3MgdGhleSBoYXZlIGEgZmlsZQorICAgICAqIGNvbW1lbnQuCisgICAgICovCisgICAgcHRyID0gYmFzZVB0ciArIGxlbmd0aCAtIGtFT0NETGVuOworCisgICAgd2hpbGUgKHB0ciA+PSBiYXNlUHRyKSB7CisgICAgICAgIGlmICgqcHRyID09IChrRU9DRFNpZ25hdHVyZSAmIDB4ZmYpICYmIGdldDRMRShwdHIpID09IGtFT0NEU2lnbmF0dXJlKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIHB0ci0tOworICAgIH0KKyAgICBpZiAocHRyIDwgYmFzZVB0cikgeworICAgICAgICBMT0dJKCJDb3VsZCBub3QgZmluZCBlbmQtb2YtY2VudHJhbC1kaXJlY3RvcnkgaW4gWmlwXG4iKTsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qCisgICAgICogVGhlcmUgYXJlIHR3byBpbnRlcmVzdGluZyBpdGVtcyBpbiB0aGUgRU9DRCBibG9jazogdGhlIG51bWJlciBvZgorICAgICAqIGVudHJpZXMgaW4gdGhlIGZpbGUsIGFuZCB0aGUgZmlsZSBvZmZzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZQorICAgICAqIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogKFRoZXJlJ3MgYWN0dWFsbHkgYSBjb3VudCBvZiB0aGUgI29mIGVudHJpZXMgaW4gdGhpcyBmaWxlLCBhbmQgZm9yCisgICAgICogYWxsIGZpbGVzIHdoaWNoIGNvbXByaXNlIGEgc3Bhbm5lZCBhcmNoaXZlLCBidXQgZm9yIG91ciBwdXJwb3NlcworICAgICAqIHdlJ3JlIG9ubHkgaW50ZXJlc3RlZCBpbiB0aGUgY3VycmVudCBmaWxlLiAgQmVzaWRlcywgd2UgZXhwZWN0IHRoZQorICAgICAqIHR3byB0byBiZSBlcXVpdmFsZW50IGZvciBvdXIgc3R1ZmYuKQorICAgICAqLworICAgIG51bUVudHJpZXMgPSBnZXQyTEUocHRyICsga0VPQ0ROdW1FbnRyaWVzKTsKKyAgICBjZE9mZnNldCA9IGdldDRMRShwdHIgKyBrRU9DREZpbGVPZmZzZXQpOworCisgICAgLyogdmFsaWQgb2Zmc2V0cyBhcmUgWzAsRU9DRF0gKi8KKyAgICB1bnNpZ25lZCBpbnQgbWF4T2Zmc2V0OworICAgIG1heE9mZnNldCA9IChwdHIgLSBiYXNlUHRyKSArMTsKKworICAgIExPR1YoIisrKyBudW1FbnRyaWVzPSVkIGNkT2Zmc2V0PSVkXG4iLCBudW1FbnRyaWVzLCBjZE9mZnNldCk7CisgICAgaWYgKG51bUVudHJpZXMgPT0gMCB8fCBjZE9mZnNldCA+PSBsZW5ndGgpIHsKKyAgICAgICAgTE9HVygiSW52YWxpZCBlbnRyaWVzPSVkIG9mZnNldD0lZCAobGVuPSV6ZClcbiIsCisgICAgICAgICAgICBudW1FbnRyaWVzLCBjZE9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIGhhc2ggdGFibGUuICBXZSBoYXZlIGEgbWluaW11bSA3NSUgbG9hZCBmYWN0b3IsIHBvc3NpYmx5IGFzCisgICAgICogbG93IGFzIDUwJSBhZnRlciB3ZSByb3VuZCBvZmYgdG8gYSBwb3dlciBvZiAyLgorICAgICAqLworICAgIG1OdW1FbnRyaWVzID0gbnVtRW50cmllczsKKyAgICBtSGFzaFRhYmxlU2l6ZSA9IHJvdW5kVXBQb3dlcjIoMSArICgobnVtRW50cmllcyAqIDQpIC8gMykpOworICAgIG1IYXNoVGFibGUgPSAoSGFzaEVudHJ5KikgY2FsbG9jKDEsIHNpemVvZihIYXNoRW50cnkpICogbUhhc2hUYWJsZVNpemUpOworCisgICAgLyoKKyAgICAgKiBXYWxrIHRocm91Z2ggdGhlIGNlbnRyYWwgZGlyZWN0b3J5LCBhZGRpbmcgZW50cmllcyB0byB0aGUgaGFzaAorICAgICAqIHRhYmxlLgorICAgICAqLworICAgIHB0ciA9IGJhc2VQdHIgKyBjZE9mZnNldDsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbnVtRW50cmllczsgaSsrKSB7CisgICAgICAgIHVuc2lnbmVkIGludCBmaWxlTmFtZUxlbiwgZXh0cmFMZW4sIGNvbW1lbnRMZW4sIGxvY2FsSGRyT2Zmc2V0OworICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBsb2NhbEhkcjsKKyAgICAgICAgdW5zaWduZWQgaW50IGhhc2g7CisKKyAgICAgICAgaWYgKGdldDRMRShwdHIpICE9IGtDREVTaWduYXR1cmUpIHsKKyAgICAgICAgICAgIExPR1coIk1pc3NlZCBhIGNlbnRyYWwgZGlyIHNpZyAoYXQgJWQpXG4iLCBpKTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorICAgICAgICBpZiAocHRyICsga0NERUxlbiA+IGJhc2VQdHIgKyBsZW5ndGgpIHsKKyAgICAgICAgICAgIExPR1coIlJhbiBvZmYgdGhlIGVuZCAoYXQgJWQpXG4iLCBpKTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfQorCisgICAgICAgIGxvY2FsSGRyT2Zmc2V0ID0gZ2V0NExFKHB0ciArIGtDREVMb2NhbE9mZnNldCk7CisgICAgICAgIENIRUNLX09GRlNFVChsb2NhbEhkck9mZnNldCk7CisgICAgICAgIGZpbGVOYW1lTGVuID0gZ2V0MkxFKHB0ciArIGtDREVOYW1lTGVuKTsKKyAgICAgICAgZXh0cmFMZW4gPSBnZXQyTEUocHRyICsga0NERUV4dHJhTGVuKTsKKyAgICAgICAgY29tbWVudExlbiA9IGdldDJMRShwdHIgKyBrQ0RFQ29tbWVudExlbik7CisKKyAgICAgICAgLy9MT0dWKCIrKysgJWQ6IGxvY2FsSGRyPSVkIGZubD0lZCBlbD0lZCBjbD0lZFxuIiwKKyAgICAgICAgLy8gICAgaSwgbG9jYWxIZHJPZmZzZXQsIGZpbGVOYW1lTGVuLCBleHRyYUxlbiwgY29tbWVudExlbik7CisgICAgICAgIC8vTE9HVigiICclLipzJ1xuIiwgZmlsZU5hbWVMZW4sIHB0ciArIGtDREVMZW4pOworCisgICAgICAgIC8qIGFkZCB0aGUgQ0RFIGZpbGVuYW1lIHRvIHRoZSBoYXNoIHRhYmxlICovCisgICAgICAgIGhhc2ggPSBjb21wdXRlSGFzaCgoY29uc3QgY2hhciopcHRyICsga0NERUxlbiwgZmlsZU5hbWVMZW4pOworICAgICAgICBhZGRUb0hhc2goKGNvbnN0IGNoYXIqKXB0ciArIGtDREVMZW4sIGZpbGVOYW1lTGVuLCBoYXNoKTsKKworICAgICAgICBsb2NhbEhkciA9IGJhc2VQdHIgKyBsb2NhbEhkck9mZnNldDsKKyAgICAgICAgaWYgKGdldDRMRShsb2NhbEhkcikgIT0ga0xGSFNpZ25hdHVyZSkgeworICAgICAgICAgICAgTE9HVygiQmFkIG9mZnNldCB0byBsb2NhbCBoZWFkZXI6ICVkIChhdCAlZClcbiIsCisgICAgICAgICAgICAgICAgbG9jYWxIZHJPZmZzZXQsIGkpOworICAgICAgICAgICAgZ290byBiYWlsOworICAgICAgICB9CisKKyAgICAgICAgcHRyICs9IGtDREVMZW4gKyBmaWxlTmFtZUxlbiArIGV4dHJhTGVuICsgY29tbWVudExlbjsKKyAgICAgICAgQ0hFQ0tfT0ZGU0VUKHB0ciAtIGJhc2VQdHIpOworICAgIH0KKworICAgIHJlc3VsdCA9IHRydWU7CisKK2JhaWw6CisgICAgcmV0dXJuIHJlc3VsdDsKKyN1bmRlZiBDSEVDS19PRkZTRVQKK30KKworCisvKgorICogU2ltcGxlIHN0cmluZyBoYXNoIGZ1bmN0aW9uIGZvciBub24tbnVsbC10ZXJtaW5hdGVkIHN0cmluZ3MuCisgKi8KKy8qc3RhdGljKi8gdW5zaWduZWQgaW50IFppcEZpbGVSTzo6Y29tcHV0ZUhhc2goY29uc3QgY2hhciogc3RyLCBpbnQgbGVuKQoreworICAgIHVuc2lnbmVkIGludCBoYXNoID0gMDsKKworICAgIHdoaWxlIChsZW4tLSkKKyAgICAgICAgaGFzaCA9IGhhc2ggKiAzMSArICpzdHIrKzsKKworICAgIHJldHVybiBoYXNoOworfQorCisvKgorICogQWRkIGEgbmV3IGVudHJ5IHRvIHRoZSBoYXNoIHRhYmxlLgorICovCit2b2lkIFppcEZpbGVSTzo6YWRkVG9IYXNoKGNvbnN0IGNoYXIqIHN0ciwgaW50IHN0ckxlbiwgdW5zaWduZWQgaW50IGhhc2gpCit7CisgICAgaW50IGVudCA9IGhhc2ggJiAobUhhc2hUYWJsZVNpemUtMSk7CisKKyAgICAvKgorICAgICAqIFdlIG92ZXItYWxsb2NhdGUgdGhlIHRhYmxlLCBzbyB3ZSdyZSBndWFyYW50ZWVkIHRvIGZpbmQgYW4gZW1wdHkgc2xvdC4KKyAgICAgKi8KKyAgICB3aGlsZSAobUhhc2hUYWJsZVtlbnRdLm5hbWUgIT0gTlVMTCkKKyAgICAgICAgZW50ID0gKGVudCArIDEpICYgKG1IYXNoVGFibGVTaXplLTEpOworCisgICAgbUhhc2hUYWJsZVtlbnRdLm5hbWUgPSBzdHI7CisgICAgbUhhc2hUYWJsZVtlbnRdLm5hbWVMZW4gPSBzdHJMZW47Cit9CisKKy8qCisgKiBGaW5kIGEgbWF0Y2hpbmcgZW50cnkuCisgKgorICogUmV0dXJucyAwIGlmIG5vdCBmb3VuZC4KKyAqLworWmlwRW50cnlSTyBaaXBGaWxlUk86OmZpbmRFbnRyeUJ5TmFtZShjb25zdCBjaGFyKiBmaWxlTmFtZSkgY29uc3QKK3sKKyAgICBpbnQgbmFtZUxlbiA9IHN0cmxlbihmaWxlTmFtZSk7CisgICAgdW5zaWduZWQgaW50IGhhc2ggPSBjb21wdXRlSGFzaChmaWxlTmFtZSwgbmFtZUxlbik7CisgICAgaW50IGVudCA9IGhhc2ggJiAobUhhc2hUYWJsZVNpemUtMSk7CisKKyAgICB3aGlsZSAobUhhc2hUYWJsZVtlbnRdLm5hbWUgIT0gTlVMTCkgeworICAgICAgICBpZiAobUhhc2hUYWJsZVtlbnRdLm5hbWVMZW4gPT0gbmFtZUxlbiAmJgorICAgICAgICAgICAgbWVtY21wKG1IYXNoVGFibGVbZW50XS5uYW1lLCBmaWxlTmFtZSwgbmFtZUxlbikgPT0gMCkKKyAgICAgICAgeworICAgICAgICAgICAgLyogbWF0Y2ggKi8KKyAgICAgICAgICAgIHJldHVybiAoWmlwRW50cnlSTykgKGVudCArIGtaaXBFbnRyeUFkaik7CisgICAgICAgIH0KKworICAgICAgICBlbnQgPSAoZW50ICsgMSkgJiAobUhhc2hUYWJsZVNpemUtMSk7CisgICAgfQorCisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qCisgKiBGaW5kIHRoZSBOdGggZW50cnkuCisgKgorICogVGhpcyBjdXJyZW50bHkgaW52b2x2ZXMgd2Fsa2luZyB0aHJvdWdoIHRoZSBzcGFyc2UgaGFzaCB0YWJsZSwgY291bnRpbmcKKyAqIG5vbi1lbXB0eSBlbnRyaWVzLiAgSWYgd2UgbmVlZCB0byBzcGVlZCB0aGlzIHVwIHdlIGNhbiBlaXRoZXIgYWxsb2NhdGUKKyAqIGEgcGFyYWxsZWwgbG9va3VwIHRhYmxlIG9yIChwZXJoYXBzIGJldHRlcikgcHJvdmlkZSBhbiBpdGVyYXRvciBpbnRlcmZhY2UuCisgKi8KK1ppcEVudHJ5Uk8gWmlwRmlsZVJPOjpmaW5kRW50cnlCeUluZGV4KGludCBpZHgpIGNvbnN0Cit7CisgICAgaWYgKGlkeCA8IDAgfHwgaWR4ID49IG1OdW1FbnRyaWVzKSB7CisgICAgICAgIExPR1coIkludmFsaWQgaW5kZXggJWRcbiIsIGlkeCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGZvciAoaW50IGVudCA9IDA7IGVudCA8IG1IYXNoVGFibGVTaXplOyBlbnQrKykgeworICAgICAgICBpZiAobUhhc2hUYWJsZVtlbnRdLm5hbWUgIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKGlkeC0tID09IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIChaaXBFbnRyeVJPKSAoZW50ICsga1ppcEVudHJ5QWRqKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBOVUxMOworfQorCisvKgorICogR2V0IHRoZSB1c2VmdWwgZmllbGRzIGZyb20gdGhlIHppcCBlbnRyeS4KKyAqCisgKiBSZXR1cm5zICJmYWxzZSIgaWYgdGhlIG9mZnNldHMgdG8gdGhlIGZpZWxkcyBvciB0aGUgY29udGVudHMgb2YgdGhlIGZpZWxkcworICogYXBwZWFyIHRvIGJlIGJvZ3VzLgorICovCitib29sIFppcEZpbGVSTzo6Z2V0RW50cnlJbmZvKFppcEVudHJ5Uk8gZW50cnksIGludCogcE1ldGhvZCwgbG9uZyogcFVuY29tcExlbiwKKyAgICBsb25nKiBwQ29tcExlbiwgb2ZmX3QqIHBPZmZzZXQsIGxvbmcqIHBNb2RXaGVuLCBsb25nKiBwQ3JjMzIpIGNvbnN0Cit7CisgICAgaW50IGVudCA9IGVudHJ5VG9JbmRleChlbnRyeSk7CisgICAgaWYgKGVudCA8IDApCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgIC8qCisgICAgICogUmVjb3ZlciB0aGUgc3RhcnQgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGVudHJ5IGZyb20gdGhlIGZpbGVuYW1lCisgICAgICogcG9pbnRlci4KKyAgICAgKi8KKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBiYXNlUHRyID0gKGNvbnN0IHVuc2lnbmVkIGNoYXIqKW1GaWxlTWFwLT5nZXREYXRhUHRyKCk7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciogcHRyID0gKGNvbnN0IHVuc2lnbmVkIGNoYXIqKSBtSGFzaFRhYmxlW2VudF0ubmFtZTsKKyAgICBzaXplX3QgemlwTGVuZ3RoID0gbUZpbGVNYXAtPmdldERhdGFMZW5ndGgoKTsKKworICAgIHB0ciAtPSBrQ0RFTGVuOworCisgICAgaW50IG1ldGhvZCA9IGdldDJMRShwdHIgKyBrQ0RFTWV0aG9kKTsKKyAgICBpZiAocE1ldGhvZCAhPSBOVUxMKQorICAgICAgICAqcE1ldGhvZCA9IG1ldGhvZDsKKworICAgIGlmIChwTW9kV2hlbiAhPSBOVUxMKQorICAgICAgICAqcE1vZFdoZW4gPSBnZXQ0TEUocHRyICsga0NERU1vZFdoZW4pOworICAgIGlmIChwQ3JjMzIgIT0gTlVMTCkKKyAgICAgICAgKnBDcmMzMiA9IGdldDRMRShwdHIgKyBrQ0RFQ1JDKTsKKworICAgIC8qCisgICAgICogV2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgbGVuZ3RocyBhcmUgbm90IHNvIGxhcmdlIHRoYXQgc29tZWJvZHkKKyAgICAgKiB0cnlpbmcgdG8gbWFwIHRoZSBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZCBkYXRhIHJ1bnMgb2ZmIHRoZSBlbmQKKyAgICAgKiBvZiB0aGUgbWFwcGVkIHJlZ2lvbi4KKyAgICAgKi8KKyAgICB1bnNpZ25lZCBsb25nIGxvY2FsSGRyT2Zmc2V0ID0gZ2V0NExFKHB0ciArIGtDREVMb2NhbE9mZnNldCk7CisgICAgaWYgKGxvY2FsSGRyT2Zmc2V0ICsga0xGSExlbiA+PSB6aXBMZW5ndGgpIHsKKyAgICAgICAgTE9HRSgiRVJST1I6IGJhZCBsb2NhbCBoZHIgb2Zmc2V0IGluIHppcFxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY29uc3QgdW5zaWduZWQgY2hhciogbG9jYWxIZHIgPSBiYXNlUHRyICsgbG9jYWxIZHJPZmZzZXQ7CisgICAgb2ZmX3QgZGF0YU9mZnNldCA9IGxvY2FsSGRyT2Zmc2V0ICsga0xGSExlbgorICAgICAgICArIGdldDJMRShsb2NhbEhkciArIGtMRkhOYW1lTGVuKSArIGdldDJMRShsb2NhbEhkciArIGtMRkhFeHRyYUxlbik7CisgICAgaWYgKCh1bnNpZ25lZCBsb25nKSBkYXRhT2Zmc2V0ID49IHppcExlbmd0aCkgeworICAgICAgICBMT0dFKCJFUlJPUjogYmFkIGRhdGEgb2Zmc2V0IGluIHppcFxuIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAocENvbXBMZW4gIT0gTlVMTCkgeworICAgICAgICAqcENvbXBMZW4gPSBnZXQ0TEUocHRyICsga0NERUNvbXBMZW4pOworICAgICAgICBpZiAoKnBDb21wTGVuIDwgMCB8fCAoc2l6ZV90KShkYXRhT2Zmc2V0ICsgKnBDb21wTGVuKSA+PSB6aXBMZW5ndGgpIHsKKyAgICAgICAgICAgIExPR0UoIkVSUk9SOiBiYWQgY29tcHJlc3NlZCBsZW5ndGggaW4gemlwXG4iKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAocFVuY29tcExlbiAhPSBOVUxMKSB7CisgICAgICAgICpwVW5jb21wTGVuID0gZ2V0NExFKHB0ciArIGtDREVVbmNvbXBMZW4pOworICAgICAgICBpZiAoKnBVbmNvbXBMZW4gPCAwKSB7CisgICAgICAgICAgICBMT0dFKCJFUlJPUjogbmVnYXRpdmUgdW5jb21wcmVzc2VkIGxlbmd0aCBpbiB6aXBcbiIpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChtZXRob2QgPT0ga0NvbXByZXNzU3RvcmVkICYmCisgICAgICAgICAgICAoc2l6ZV90KShkYXRhT2Zmc2V0ICsgKnBVbmNvbXBMZW4pID49IHppcExlbmd0aCkKKyAgICAgICAgeworICAgICAgICAgICAgTE9HRSgiRVJST1I6IGJhZCB1bmNvbXByZXNzZWQgbGVuZ3RoIGluIHppcFxuIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAocE9mZnNldCAhPSBOVUxMKSB7CisgICAgICAgICpwT2Zmc2V0ID0gZGF0YU9mZnNldDsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7Cit9CisKKy8qCisgKiBDb3B5IHRoZSBlbnRyeSdzIGZpbGVuYW1lIHRvIHRoZSBidWZmZXIuCisgKi8KK2ludCBaaXBGaWxlUk86OmdldEVudHJ5RmlsZU5hbWUoWmlwRW50cnlSTyBlbnRyeSwgY2hhciogYnVmZmVyLCBpbnQgYnVmTGVuKQorICAgIGNvbnN0Cit7CisgICAgaW50IGVudCA9IGVudHJ5VG9JbmRleChlbnRyeSk7CisgICAgaWYgKGVudCA8IDApCisgICAgICAgIHJldHVybiAtMTsKKworICAgIGludCBuYW1lTGVuID0gbUhhc2hUYWJsZVtlbnRdLm5hbWVMZW47CisgICAgaWYgKGJ1ZkxlbiA8IG5hbWVMZW4rMSkKKyAgICAgICAgcmV0dXJuIG5hbWVMZW4rMTsKKworICAgIG1lbWNweShidWZmZXIsIG1IYXNoVGFibGVbZW50XS5uYW1lLCBuYW1lTGVuKTsKKyAgICBidWZmZXJbbmFtZUxlbl0gPSAnXDAnOworICAgIHJldHVybiAwOworfQorCisvKgorICogQ3JlYXRlIGEgbmV3IEZpbGVNYXAgb2JqZWN0IHRoYXQgc3BhbnMgdGhlIGRhdGEgaW4gImVudHJ5Ii4KKyAqLworRmlsZU1hcCogWmlwRmlsZVJPOjpjcmVhdGVFbnRyeUZpbGVNYXAoWmlwRW50cnlSTyBlbnRyeSkgY29uc3QKK3sKKyAgICAvKgorICAgICAqIFRPRE86IHRoZSBlZmZpY2llbnQgd2F5IHRvIGRvIHRoaXMgaXMgdG8gbW9kaWZ5IEZpbGVNYXAgdG8gYWxsb3cKKyAgICAgKiBzdWItcmVnaW9ucyBvZiBhIGZpbGUgdG8gYmUgbWFwcGVkLiAgQSByZWZlcmVuY2UtY291bnRpbmcgc2NoZW1lCisgICAgICogY2FuIG1hbmFnZSB0aGUgYmFzZSBtZW1vcnkgbWFwcGluZy4gIEZvciBub3csIHdlIGp1c3QgY3JlYXRlIGEgYnJhbmQKKyAgICAgKiBuZXcgbWFwcGluZyBvZmYgb2YgdGhlIFppcCBhcmNoaXZlIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKworICAgIEZpbGVNYXAqIG5ld01hcDsKKyAgICBsb25nIGNvbXBMZW47CisgICAgb2ZmX3Qgb2Zmc2V0OworCisgICAgaWYgKCFnZXRFbnRyeUluZm8oZW50cnksIE5VTEwsIE5VTEwsICZjb21wTGVuLCAmb2Zmc2V0LCBOVUxMLCBOVUxMKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBuZXdNYXAgPSBuZXcgRmlsZU1hcCgpOworICAgIGlmICghbmV3TWFwLT5jcmVhdGUobUZpbGVNYXAtPmdldEZpbGVOYW1lKCksIG1GZCwgb2Zmc2V0LCBjb21wTGVuLCB0cnVlKSkgeworICAgICAgICBuZXdNYXAtPnJlbGVhc2UoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgcmV0dXJuIG5ld01hcDsKK30KKworLyoKKyAqIFVuY29tcHJlc3MgYW4gZW50cnksIGluIGl0cyBlbnRpcmV0eSwgaW50byB0aGUgcHJvdmlkZWQgb3V0cHV0IGJ1ZmZlci4KKyAqCisgKiBUaGlzIGRvZXNuJ3QgdmVyaWZ5IHRoZSBkYXRhJ3MgQ1JDLCB3aGljaCBtaWdodCBiZSB1c2VmdWwgZm9yCisgKiB1bmNvbXByZXNzZWQgZGF0YS4gIFRoZSBjYWxsZXIgc2hvdWxkIGJlIGFibGUgdG8gbWFuYWdlIGl0LgorICovCitib29sIFppcEZpbGVSTzo6dW5jb21wcmVzc0VudHJ5KFppcEVudHJ5Uk8gZW50cnksIHZvaWQqIGJ1ZmZlcikgY29uc3QKK3sKKyAgICBjb25zdCBpbnQga1NlcXVlbnRpYWxNaW4gPSAzMjc2ODsKKyAgICBib29sIHJlc3VsdCA9IGZhbHNlOworICAgIGludCBlbnQgPSBlbnRyeVRvSW5kZXgoZW50cnkpOworICAgIGlmIChlbnQgPCAwKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBiYXNlUHRyID0gKGNvbnN0IHVuc2lnbmVkIGNoYXIqKW1GaWxlTWFwLT5nZXREYXRhUHRyKCk7CisgICAgaW50IG1ldGhvZDsKKyAgICBsb25nIHVuY29tcExlbiwgY29tcExlbjsKKyAgICBvZmZfdCBvZmZzZXQ7CisKKyAgICBnZXRFbnRyeUluZm8oZW50cnksICZtZXRob2QsICZ1bmNvbXBMZW4sICZjb21wTGVuLCAmb2Zmc2V0LCBOVUxMLCBOVUxMKTsKKworICAgIC8qCisgICAgICogRXhwZXJpbWVudCB3aXRoIG1hZHZpc2UgaGludC4gIFdoZW4gd2Ugd2FudCB0byB1bmNvbXByZXNzIGEgZmlsZSwKKyAgICAgKiB3ZSBwdWxsIHNvbWUgc3R1ZmYgb3V0IG9mIHRoZSBjZW50cmFsIGRpciBlbnRyeSBhbmQgdGhlbiBoaXQgYQorICAgICAqIGJ1bmNoIG9mIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkIGRhdGEgc2VxdWVudGlhbGx5LiAgVGhlIENERQorICAgICAqIHZpc2l0IHdpbGwgY2F1c2UgYSBsaW1pdGVkIGFtb3VudCBvZiByZWFkLWFoZWFkIGJlY2F1c2UgaXQncyBhdAorICAgICAqIHRoZSBlbmQgb2YgdGhlIGZpbGUuICBXZSBjb3VsZCBlbmQgdXAgZG9pbmcgbG90cyBvZiBleHRyYSBkaXNrCisgICAgICogYWNjZXNzIGlmIHRoZSBmaWxlIHdlJ3JlIHByeWluZyBvcGVuIGlzIHNtYWxsLiAgQm90dG9tIGxpbmUgaXMgd2UKKyAgICAgKiBwcm9iYWJseSBkb24ndCB3YW50IHRvIHR1cm4gTUFEVl9TRVFVRU5USUFMIG9uIGFuZCBsZWF2ZSBpdCBvbi4KKyAgICAgKgorICAgICAqIFNvLCBpZiB0aGUgY29tcHJlc3NlZCBzaXplIG9mIHRoZSBmaWxlIGlzIGFib3ZlIGEgY2VydGFpbiBtaW5pbXVtCisgICAgICogc2l6ZSwgdGVtcG9yYXJpbHkgYm9vc3QgdGhlIHJlYWQtYWhlYWQgaW4gdGhlIGhvcGUgdGhhdCB0aGUgZXh0cmEKKyAgICAgKiBwYWlyIG9mIHN5c3RlbSBjYWxscyBhcmUgbmVnYXRlZCBieSBhIHJlZHVjdGlvbiBpbiBwYWdlIGZhdWx0cy4KKyAgICAgKi8KKyAgICBpZiAoY29tcExlbiA+IGtTZXF1ZW50aWFsTWluKQorICAgICAgICBtRmlsZU1hcC0+YWR2aXNlKEZpbGVNYXA6OlNFUVVFTlRJQUwpOworCisgICAgaWYgKG1ldGhvZCA9PSBrQ29tcHJlc3NTdG9yZWQpIHsKKyAgICAgICAgbWVtY3B5KGJ1ZmZlciwgYmFzZVB0ciArIG9mZnNldCwgdW5jb21wTGVuKTsKKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoIWluZmxhdGVCdWZmZXIoYnVmZmVyLCBiYXNlUHRyICsgb2Zmc2V0LCB1bmNvbXBMZW4sIGNvbXBMZW4pKQorICAgICAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIGlmIChjb21wTGVuID4ga1NlcXVlbnRpYWxNaW4pCisgICAgICAgIG1GaWxlTWFwLT5hZHZpc2UoRmlsZU1hcDo6Tk9STUFMKTsKKworICAgIHJlc3VsdCA9IHRydWU7CisKK2JhaWw6CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAqIFVuY29tcHJlc3MgYW4gZW50cnksIGluIGl0cyBlbnRpcmV0eSwgdG8gYW4gb3BlbiBmaWxlIGRlc2NyaXB0b3IuCisgKgorICogVGhpcyBkb2Vzbid0IHZlcmlmeSB0aGUgZGF0YSdzIENSQywgYnV0IHByb2JhYmx5IHNob3VsZC4KKyAqLworYm9vbCBaaXBGaWxlUk86OnVuY29tcHJlc3NFbnRyeShaaXBFbnRyeVJPIGVudHJ5LCBpbnQgZmQpIGNvbnN0Cit7CisgICAgYm9vbCByZXN1bHQgPSBmYWxzZTsKKyAgICBpbnQgZW50ID0gZW50cnlUb0luZGV4KGVudHJ5KTsKKyAgICBpZiAoZW50IDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgY29uc3QgdW5zaWduZWQgY2hhciogYmFzZVB0ciA9IChjb25zdCB1bnNpZ25lZCBjaGFyKiltRmlsZU1hcC0+Z2V0RGF0YVB0cigpOworICAgIGludCBtZXRob2Q7CisgICAgbG9uZyB1bmNvbXBMZW4sIGNvbXBMZW47CisgICAgb2ZmX3Qgb2Zmc2V0OworCisgICAgZ2V0RW50cnlJbmZvKGVudHJ5LCAmbWV0aG9kLCAmdW5jb21wTGVuLCAmY29tcExlbiwgJm9mZnNldCwgTlVMTCwgTlVMTCk7CisKKyAgICBpZiAobWV0aG9kID09IGtDb21wcmVzc1N0b3JlZCkgeworICAgICAgICBzc2l6ZV90IGFjdHVhbDsKKworICAgICAgICBhY3R1YWwgPSB3cml0ZShmZCwgYmFzZVB0ciArIG9mZnNldCwgdW5jb21wTGVuKTsKKyAgICAgICAgaWYgKGFjdHVhbCA8IDApIHsKKyAgICAgICAgICAgIExPR0UoIldyaXRlIGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgICAgIH0gZWxzZSBpZiAoYWN0dWFsICE9IHVuY29tcExlbikgeworICAgICAgICAgICAgTE9HRSgiUGFydGlhbCB3cml0ZSBkdXJpbmcgdW5jb21wcmVzcyAoJWQgb2YgJWxkKVxuIiwKKyAgICAgICAgICAgICAgICAoaW50KWFjdHVhbCwgdW5jb21wTGVuKTsKKyAgICAgICAgICAgIGdvdG8gYmFpbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0koIisrKyBzdWNjZXNzZnVsIHdyaXRlXG4iKTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIGlmICghaW5mbGF0ZUJ1ZmZlcihmZCwgYmFzZVB0citvZmZzZXQsIHVuY29tcExlbiwgY29tcExlbikpCisgICAgICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgcmVzdWx0ID0gdHJ1ZTsKKworYmFpbDoKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKgorICogVW5jb21wcmVzcyAiZGVmbGF0ZSIgZGF0YSBmcm9tIG9uZSBidWZmZXIgdG8gYW5vdGhlci4KKyAqLworLypzdGF0aWMqLyBib29sIFppcEZpbGVSTzo6aW5mbGF0ZUJ1ZmZlcih2b2lkKiBvdXRCdWYsIGNvbnN0IHZvaWQqIGluQnVmLAorICAgIGxvbmcgdW5jb21wTGVuLCBsb25nIGNvbXBMZW4pCit7CisgICAgYm9vbCByZXN1bHQgPSBmYWxzZTsKKyAgICB6X3N0cmVhbSB6c3RyZWFtOworICAgIGludCB6ZXJyOworCisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHRoZSB6bGliIHN0cmVhbSBzdHJ1Y3QuCisgICAgICovCisJbWVtc2V0KCZ6c3RyZWFtLCAwLCBzaXplb2YoenN0cmVhbSkpOworICAgIHpzdHJlYW0uemFsbG9jID0gWl9OVUxMOworICAgIHpzdHJlYW0uemZyZWUgPSBaX05VTEw7CisgICAgenN0cmVhbS5vcGFxdWUgPSBaX05VTEw7CisgICAgenN0cmVhbS5uZXh0X2luID0gKEJ5dGVmKilpbkJ1ZjsKKyAgICB6c3RyZWFtLmF2YWlsX2luID0gY29tcExlbjsKKyAgICB6c3RyZWFtLm5leHRfb3V0ID0gKEJ5dGVmKikgb3V0QnVmOworICAgIHpzdHJlYW0uYXZhaWxfb3V0ID0gdW5jb21wTGVuOworICAgIHpzdHJlYW0uZGF0YV90eXBlID0gWl9VTktOT1dOOworCisJLyoKKwkgKiBVc2UgdGhlIHVuZG9jdW1lbnRlZCAibmVnYXRpdmUgd2luZG93IGJpdHMiIGZlYXR1cmUgdG8gdGVsbCB6bGliCisJICogdGhhdCB0aGVyZSdzIG5vIHpsaWIgaGVhZGVyIHdhaXRpbmcgZm9yIGl0LgorCSAqLworICAgIHplcnIgPSBpbmZsYXRlSW5pdDIoJnpzdHJlYW0sIC1NQVhfV0JJVFMpOworICAgIGlmICh6ZXJyICE9IFpfT0spIHsKKyAgICAgICAgaWYgKHplcnIgPT0gWl9WRVJTSU9OX0VSUk9SKSB7CisgICAgICAgICAgICBMT0dFKCJJbnN0YWxsZWQgemxpYiBpcyBub3QgY29tcGF0aWJsZSB3aXRoIGxpbmtlZCB2ZXJzaW9uICglcylcbiIsCisgICAgICAgICAgICAgICAgWkxJQl9WRVJTSU9OKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0UoIkNhbGwgdG8gaW5mbGF0ZUluaXQyIGZhaWxlZCAoemVycj0lZClcbiIsIHplcnIpOworICAgICAgICB9CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEV4cGFuZCBkYXRhLgorICAgICAqLworICAgIHplcnIgPSBpbmZsYXRlKCZ6c3RyZWFtLCBaX0ZJTklTSCk7CisgICAgaWYgKHplcnIgIT0gWl9TVFJFQU1fRU5EKSB7CisgICAgICAgIExPR1coIlppcCBpbmZsYXRlIGZhaWxlZCwgemVycj0lZCAobkluPSVwIGFJbj0ldSBuT3V0PSVwIGFPdXQ9JXUpXG4iLAorICAgICAgICAgICAgemVyciwgenN0cmVhbS5uZXh0X2luLCB6c3RyZWFtLmF2YWlsX2luLAorICAgICAgICAgICAgenN0cmVhbS5uZXh0X291dCwgenN0cmVhbS5hdmFpbF9vdXQpOworICAgICAgICBnb3RvIHpfYmFpbDsKKyAgICB9CisKKyAgICAvKiBwYXJhbm9pYSAqLworICAgIGlmICgobG9uZykgenN0cmVhbS50b3RhbF9vdXQgIT0gdW5jb21wTGVuKSB7CisgICAgICAgIExPR1coIlNpemUgbWlzbWF0Y2ggb24gaW5mbGF0ZWQgZmlsZSAoJWxkIHZzICVsZClcbiIsCisgICAgICAgICAgICB6c3RyZWFtLnRvdGFsX291dCwgdW5jb21wTGVuKTsKKyAgICAgICAgZ290byB6X2JhaWw7CisgICAgfQorCisgICAgcmVzdWx0ID0gdHJ1ZTsKKworel9iYWlsOgorICAgIGluZmxhdGVFbmQoJnpzdHJlYW0pOyAgICAgICAgLyogZnJlZSB1cCBhbnkgYWxsb2NhdGVkIHN0cnVjdHVyZXMgKi8KKworYmFpbDoKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKgorICogVW5jb21wcmVzcyAiZGVmbGF0ZSIgZGF0YSBmcm9tIG9uZSBidWZmZXIgdG8gYW4gb3BlbiBmaWxlIGRlc2NyaXB0b3IuCisgKi8KKy8qc3RhdGljKi8gYm9vbCBaaXBGaWxlUk86OmluZmxhdGVCdWZmZXIoaW50IGZkLCBjb25zdCB2b2lkKiBpbkJ1ZiwKKyAgICBsb25nIHVuY29tcExlbiwgbG9uZyBjb21wTGVuKQoreworICAgIGJvb2wgcmVzdWx0ID0gZmFsc2U7CisgICAgY29uc3QgaW50IGtXcml0ZUJ1ZlNpemUgPSAzMjc2ODsKKyAgICB1bnNpZ25lZCBjaGFyIHdyaXRlQnVmW2tXcml0ZUJ1ZlNpemVdOworICAgIHpfc3RyZWFtIHpzdHJlYW07CisgICAgaW50IHplcnI7CisKKyAgICAvKgorICAgICAqIEluaXRpYWxpemUgdGhlIHpsaWIgc3RyZWFtIHN0cnVjdC4KKyAgICAgKi8KKwltZW1zZXQoJnpzdHJlYW0sIDAsIHNpemVvZih6c3RyZWFtKSk7CisgICAgenN0cmVhbS56YWxsb2MgPSBaX05VTEw7CisgICAgenN0cmVhbS56ZnJlZSA9IFpfTlVMTDsKKyAgICB6c3RyZWFtLm9wYXF1ZSA9IFpfTlVMTDsKKyAgICB6c3RyZWFtLm5leHRfaW4gPSAoQnl0ZWYqKWluQnVmOworICAgIHpzdHJlYW0uYXZhaWxfaW4gPSBjb21wTGVuOworICAgIHpzdHJlYW0ubmV4dF9vdXQgPSAoQnl0ZWYqKSB3cml0ZUJ1ZjsKKyAgICB6c3RyZWFtLmF2YWlsX291dCA9IHNpemVvZih3cml0ZUJ1Zik7CisgICAgenN0cmVhbS5kYXRhX3R5cGUgPSBaX1VOS05PV047CisKKwkvKgorCSAqIFVzZSB0aGUgdW5kb2N1bWVudGVkICJuZWdhdGl2ZSB3aW5kb3cgYml0cyIgZmVhdHVyZSB0byB0ZWxsIHpsaWIKKwkgKiB0aGF0IHRoZXJlJ3Mgbm8gemxpYiBoZWFkZXIgd2FpdGluZyBmb3IgaXQuCisJICovCisgICAgemVyciA9IGluZmxhdGVJbml0MigmenN0cmVhbSwgLU1BWF9XQklUUyk7CisgICAgaWYgKHplcnIgIT0gWl9PSykgeworICAgICAgICBpZiAoemVyciA9PSBaX1ZFUlNJT05fRVJST1IpIHsKKyAgICAgICAgICAgIExPR0UoIkluc3RhbGxlZCB6bGliIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggbGlua2VkIHZlcnNpb24gKCVzKVxuIiwKKyAgICAgICAgICAgICAgICBaTElCX1ZFUlNJT04pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HRSgiQ2FsbCB0byBpbmZsYXRlSW5pdDIgZmFpbGVkICh6ZXJyPSVkKVxuIiwgemVycik7CisgICAgICAgIH0KKyAgICAgICAgZ290byBiYWlsOworICAgIH0KKworICAgIC8qCisgICAgICogTG9vcCB3aGlsZSB3ZSBoYXZlIG1vcmUgdG8gZG8uCisgICAgICovCisgICAgZG8geworICAgICAgICAvKgorICAgICAgICAgKiBFeHBhbmQgZGF0YS4KKyAgICAgICAgICovCisgICAgICAgIHplcnIgPSBpbmZsYXRlKCZ6c3RyZWFtLCBaX05PX0ZMVVNIKTsKKyAgICAgICAgaWYgKHplcnIgIT0gWl9PSyAmJiB6ZXJyICE9IFpfU1RSRUFNX0VORCkgeworICAgICAgICAgICAgTE9HVygiemxpYiBpbmZsYXRlOiB6ZXJyPSVkIChuSW49JXAgYUluPSV1IG5PdXQ9JXAgYU91dD0ldSlcbiIsCisgICAgICAgICAgICAgICAgemVyciwgenN0cmVhbS5uZXh0X2luLCB6c3RyZWFtLmF2YWlsX2luLAorICAgICAgICAgICAgICAgIHpzdHJlYW0ubmV4dF9vdXQsIHpzdHJlYW0uYXZhaWxfb3V0KTsKKyAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICB9CisKKyAgICAgICAgLyogd3JpdGUgd2hlbiB3ZSdyZSBmdWxsIG9yIHdoZW4gd2UncmUgZG9uZSAqLworICAgICAgICBpZiAoenN0cmVhbS5hdmFpbF9vdXQgPT0gMCB8fAorICAgICAgICAgICAgKHplcnIgPT0gWl9TVFJFQU1fRU5EICYmIHpzdHJlYW0uYXZhaWxfb3V0ICE9IHNpemVvZih3cml0ZUJ1ZikpKQorICAgICAgICB7CisgICAgICAgICAgICBsb25nIHdyaXRlU2l6ZSA9IHpzdHJlYW0ubmV4dF9vdXQgLSB3cml0ZUJ1ZjsKKyAgICAgICAgICAgIGludCBjYyA9IHdyaXRlKGZkLCB3cml0ZUJ1Ziwgd3JpdGVTaXplKTsKKyAgICAgICAgICAgIGlmIChjYyAhPSAoaW50KSB3cml0ZVNpemUpIHsKKyAgICAgICAgICAgICAgICBMT0dXKCJ3cml0ZSBmYWlsZWQgaW4gaW5mbGF0ZSAoJWQgdnMgJWxkKVxuIiwgY2MsIHdyaXRlU2l6ZSk7CisgICAgICAgICAgICAgICAgZ290byB6X2JhaWw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHpzdHJlYW0ubmV4dF9vdXQgPSB3cml0ZUJ1ZjsKKyAgICAgICAgICAgIHpzdHJlYW0uYXZhaWxfb3V0ID0gc2l6ZW9mKHdyaXRlQnVmKTsKKyAgICAgICAgfQorICAgIH0gd2hpbGUgKHplcnIgPT0gWl9PSyk7CisKKyAgICBhc3NlcnQoemVyciA9PSBaX1NUUkVBTV9FTkQpOyAgICAgICAvKiBvdGhlciBlcnJvcnMgc2hvdWxkJ3ZlIGJlZW4gY2F1Z2h0ICovCisKKyAgICAvKiBwYXJhbm9pYSAqLworICAgIGlmICgobG9uZykgenN0cmVhbS50b3RhbF9vdXQgIT0gdW5jb21wTGVuKSB7CisgICAgICAgIExPR1coIlNpemUgbWlzbWF0Y2ggb24gaW5mbGF0ZWQgZmlsZSAoJWxkIHZzICVsZClcbiIsCisgICAgICAgICAgICB6c3RyZWFtLnRvdGFsX291dCwgdW5jb21wTGVuKTsKKyAgICAgICAgZ290byB6X2JhaWw7CisgICAgfQorCisgICAgcmVzdWx0ID0gdHJ1ZTsKKworel9iYWlsOgorICAgIGluZmxhdGVFbmQoJnpzdHJlYW0pOyAgICAgICAgLyogZnJlZSB1cCBhbnkgYWxsb2NhdGVkIHN0cnVjdHVyZXMgKi8KKworYmFpbDoKKyAgICByZXR1cm4gcmVzdWx0OworfQpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9aaXBVdGlscy5jcHAgYi9saWJzL3V0aWxzL1ppcFV0aWxzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZmJhY2ZlCi0tLSAvZGV2L251bGwKKysrIGIvbGlicy91dGlscy9aaXBVdGlscy5jcHAKQEAgLTAsMCArMSwzNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLworLy8gTWlzYyB6aXAvZ3ppcCB1dGlsaXR5IGZ1bmN0aW9ucy4KKy8vCisKKyNkZWZpbmUgTE9HX1RBRyAiemlwdXRpbCIKKworI2luY2x1ZGUgInV0aWxzL1ppcFV0aWxzLmgiCisjaW5jbHVkZSAidXRpbHMvWmlwRmlsZVJPLmgiCisjaW5jbHVkZSAidXRpbHMvTG9nLmgiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxhc3NlcnQuaD4KKworI2luY2x1ZGUgPHpsaWIuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKy8qCisgKiBVdGlsaXR5IGZ1bmN0aW9uIHRoYXQgZXhwYW5kcyB6aXAvZ3ppcCAiZGVmbGF0ZSIgY29tcHJlc3NlZCBkYXRhCisgKiBpbnRvIGEgYnVmZmVyLgorICoKKyAqICJmZCIgaXMgYW4gb3BlbiBmaWxlIHBvc2l0aW9uZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSAiZGVmbGF0ZSIgZGF0YQorICogImJ1ZiIgbXVzdCBob2xkIGF0IGxlYXN0ICJ1bmNvbXByZXNzZWRMZW4iIGJ5dGVzLgorICovCisvKnN0YXRpYyovIGJvb2wgWmlwVXRpbHM6OmluZmxhdGVUb0J1ZmZlcihpbnQgZmQsIHZvaWQqIGJ1ZiwKKyAgICBsb25nIHVuY29tcHJlc3NlZExlbiwgbG9uZyBjb21wcmVzc2VkTGVuKQoreworICAgIGJvb2wgcmVzdWx0ID0gZmFsc2U7CisJY29uc3QgdW5zaWduZWQgbG9uZyBrUmVhZEJ1ZlNpemUgPSAzMjc2ODsKKwl1bnNpZ25lZCBjaGFyKiByZWFkQnVmID0gTlVMTDsKKyAgICB6X3N0cmVhbSB6c3RyZWFtOworICAgIGludCB6ZXJyOworICAgIHVuc2lnbmVkIGxvbmcgY29tcFJlbWFpbmluZzsKKworICAgIGFzc2VydCh1bmNvbXByZXNzZWRMZW4gPj0gMCk7CisgICAgYXNzZXJ0KGNvbXByZXNzZWRMZW4gPj0gMCk7CisKKwlyZWFkQnVmID0gbmV3IHVuc2lnbmVkIGNoYXJba1JlYWRCdWZTaXplXTsKKwlpZiAocmVhZEJ1ZiA9PSBOVUxMKQorICAgICAgICBnb3RvIGJhaWw7CisgICAgY29tcFJlbWFpbmluZyA9IGNvbXByZXNzZWRMZW47CisKKyAgICAvKgorICAgICAqIEluaXRpYWxpemUgdGhlIHpsaWIgc3RyZWFtLgorICAgICAqLworCW1lbXNldCgmenN0cmVhbSwgMCwgc2l6ZW9mKHpzdHJlYW0pKTsKKyAgICB6c3RyZWFtLnphbGxvYyA9IFpfTlVMTDsKKyAgICB6c3RyZWFtLnpmcmVlID0gWl9OVUxMOworICAgIHpzdHJlYW0ub3BhcXVlID0gWl9OVUxMOworICAgIHpzdHJlYW0ubmV4dF9pbiA9IE5VTEw7CisgICAgenN0cmVhbS5hdmFpbF9pbiA9IDA7CisgICAgenN0cmVhbS5uZXh0X291dCA9IChCeXRlZiopIGJ1ZjsKKyAgICB6c3RyZWFtLmF2YWlsX291dCA9IHVuY29tcHJlc3NlZExlbjsKKyAgICB6c3RyZWFtLmRhdGFfdHlwZSA9IFpfVU5LTk9XTjsKKworCS8qCisJICogVXNlIHRoZSB1bmRvY3VtZW50ZWQgIm5lZ2F0aXZlIHdpbmRvdyBiaXRzIiBmZWF0dXJlIHRvIHRlbGwgemxpYgorCSAqIHRoYXQgdGhlcmUncyBubyB6bGliIGhlYWRlciB3YWl0aW5nIGZvciBpdC4KKwkgKi8KKyAgICB6ZXJyID0gaW5mbGF0ZUluaXQyKCZ6c3RyZWFtLCAtTUFYX1dCSVRTKTsKKyAgICBpZiAoemVyciAhPSBaX09LKSB7CisgICAgICAgIGlmICh6ZXJyID09IFpfVkVSU0lPTl9FUlJPUikgeworICAgICAgICAgICAgTE9HRSgiSW5zdGFsbGVkIHpsaWIgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBsaW5rZWQgdmVyc2lvbiAoJXMpXG4iLAorICAgICAgICAgICAgICAgIFpMSUJfVkVSU0lPTik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJDYWxsIHRvIGluZmxhdGVJbml0MiBmYWlsZWQgKHplcnI9JWQpXG4iLCB6ZXJyKTsKKyAgICAgICAgfQorICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBMb29wIHdoaWxlIHdlIGhhdmUgZGF0YS4KKyAgICAgKi8KKyAgICBkbyB7CisgICAgICAgIHVuc2lnbmVkIGxvbmcgZ2V0U2l6ZTsKKworICAgICAgICAvKiByZWFkIGFzIG11Y2ggYXMgd2UgY2FuICovCisgICAgICAgIGlmICh6c3RyZWFtLmF2YWlsX2luID09IDApIHsKKyAgICAgICAgICAgIGdldFNpemUgPSAoY29tcFJlbWFpbmluZyA+IGtSZWFkQnVmU2l6ZSkgPworICAgICAgICAgICAgICAgICAgICAgICAga1JlYWRCdWZTaXplIDogY29tcFJlbWFpbmluZzsKKyAgICAgICAgICAgIExPR1YoIisrKyByZWFkaW5nICVsZCBieXRlcyAoJWxkIGxlZnQpXG4iLAorICAgICAgICAgICAgICAgIGdldFNpemUsIGNvbXBSZW1haW5pbmcpOworCisgICAgICAgICAgICBpbnQgY2MgPSByZWFkKGZkLCByZWFkQnVmLCBnZXRTaXplKTsKKyAgICAgICAgICAgIGlmIChjYyAhPSAoaW50KSBnZXRTaXplKSB7CisgICAgICAgICAgICAgICAgTE9HRCgiaW5mbGF0ZSByZWFkIGZhaWxlZCAoJWQgdnMgJWxkKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgY2MsIGdldFNpemUpOworICAgICAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjb21wUmVtYWluaW5nIC09IGdldFNpemU7CisKKyAgICAgICAgICAgIHpzdHJlYW0ubmV4dF9pbiA9IHJlYWRCdWY7CisgICAgICAgICAgICB6c3RyZWFtLmF2YWlsX2luID0gZ2V0U2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIHVuY29tcHJlc3MgdGhlIGRhdGEgKi8KKyAgICAgICAgemVyciA9IGluZmxhdGUoJnpzdHJlYW0sIFpfTk9fRkxVU0gpOworICAgICAgICBpZiAoemVyciAhPSBaX09LICYmIHplcnIgIT0gWl9TVFJFQU1fRU5EKSB7CisgICAgICAgICAgICBMT0dEKCJ6bGliIGluZmxhdGUgY2FsbCBmYWlsZWQgKHplcnI9JWQpXG4iLCB6ZXJyKTsKKyAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICB9CisKKwkJLyogb3V0cHV0IGJ1ZmZlciBob2xkcyBhbGwsIHNvIG5vIG5lZWQgdG8gd3JpdGUgdGhlIG91dHB1dCAqLworICAgIH0gd2hpbGUgKHplcnIgPT0gWl9PSyk7CisKKyAgICBhc3NlcnQoemVyciA9PSBaX1NUUkVBTV9FTkQpOyAgICAgICAvKiBvdGhlciBlcnJvcnMgc2hvdWxkJ3ZlIGJlZW4gY2F1Z2h0ICovCisKKyAgICBpZiAoKGxvbmcpIHpzdHJlYW0udG90YWxfb3V0ICE9IHVuY29tcHJlc3NlZExlbikgeworICAgICAgICBMT0dXKCJTaXplIG1pc21hdGNoIG9uIGluZmxhdGVkIGZpbGUgKCVsZCB2cyAlbGQpXG4iLAorICAgICAgICAgICAgenN0cmVhbS50b3RhbF9vdXQsIHVuY29tcHJlc3NlZExlbik7CisgICAgICAgIGdvdG8gel9iYWlsOworICAgIH0KKworICAgIC8vIHN1Y2Nlc3MhCisgICAgcmVzdWx0ID0gdHJ1ZTsKKworel9iYWlsOgorICAgIGluZmxhdGVFbmQoJnpzdHJlYW0pOyAgICAgICAgLyogZnJlZSB1cCBhbnkgYWxsb2NhdGVkIHN0cnVjdHVyZXMgKi8KKworYmFpbDoKKwlkZWxldGVbXSByZWFkQnVmOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBVdGlsaXR5IGZ1bmN0aW9uIHRoYXQgZXhwYW5kcyB6aXAvZ3ppcCAiZGVmbGF0ZSIgY29tcHJlc3NlZCBkYXRhCisgKiBpbnRvIGEgYnVmZmVyLgorICoKKyAqIChUaGlzIGlzIGEgY2xvbmUgb2YgdGhlIHByZXZpb3VzIGZ1bmN0aW9uLCBidXQgaXQgdGFrZXMgYSBGSUxFKiBpbnN0ZWFkCisgKiBvZiBhbiBmZC4gIFdlIGNvdWxkIHBhc3MgZmlsZW5vKGZkKSB0byB0aGUgYWJvdmUsIGJ1dCB3ZSBjYW4gcnVuIGludG8KKyAqIHRyb3VibGUgd2hlbiAiZnAiIGhhcyBhIGRpZmZlcmVudCBub3Rpb24gb2Ygd2hhdCBmZCdzIGZpbGUgcG9zaXRpb24gaXMuKQorICoKKyAqICJmcCIgaXMgYW4gb3BlbiBmaWxlIHBvc2l0aW9uZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSAiZGVmbGF0ZSIgZGF0YQorICogImJ1ZiIgbXVzdCBob2xkIGF0IGxlYXN0ICJ1bmNvbXByZXNzZWRMZW4iIGJ5dGVzLgorICovCisvKnN0YXRpYyovIGJvb2wgWmlwVXRpbHM6OmluZmxhdGVUb0J1ZmZlcihGSUxFKiBmcCwgdm9pZCogYnVmLAorICAgIGxvbmcgdW5jb21wcmVzc2VkTGVuLCBsb25nIGNvbXByZXNzZWRMZW4pCit7CisgICAgYm9vbCByZXN1bHQgPSBmYWxzZTsKKwljb25zdCB1bnNpZ25lZCBsb25nIGtSZWFkQnVmU2l6ZSA9IDMyNzY4OworCXVuc2lnbmVkIGNoYXIqIHJlYWRCdWYgPSBOVUxMOworICAgIHpfc3RyZWFtIHpzdHJlYW07CisgICAgaW50IHplcnI7CisgICAgdW5zaWduZWQgbG9uZyBjb21wUmVtYWluaW5nOworCisgICAgYXNzZXJ0KHVuY29tcHJlc3NlZExlbiA+PSAwKTsKKyAgICBhc3NlcnQoY29tcHJlc3NlZExlbiA+PSAwKTsKKworCXJlYWRCdWYgPSBuZXcgdW5zaWduZWQgY2hhcltrUmVhZEJ1ZlNpemVdOworCWlmIChyZWFkQnVmID09IE5VTEwpCisgICAgICAgIGdvdG8gYmFpbDsKKyAgICBjb21wUmVtYWluaW5nID0gY29tcHJlc3NlZExlbjsKKworICAgIC8qCisgICAgICogSW5pdGlhbGl6ZSB0aGUgemxpYiBzdHJlYW0uCisgICAgICovCisJbWVtc2V0KCZ6c3RyZWFtLCAwLCBzaXplb2YoenN0cmVhbSkpOworICAgIHpzdHJlYW0uemFsbG9jID0gWl9OVUxMOworICAgIHpzdHJlYW0uemZyZWUgPSBaX05VTEw7CisgICAgenN0cmVhbS5vcGFxdWUgPSBaX05VTEw7CisgICAgenN0cmVhbS5uZXh0X2luID0gTlVMTDsKKyAgICB6c3RyZWFtLmF2YWlsX2luID0gMDsKKyAgICB6c3RyZWFtLm5leHRfb3V0ID0gKEJ5dGVmKikgYnVmOworICAgIHpzdHJlYW0uYXZhaWxfb3V0ID0gdW5jb21wcmVzc2VkTGVuOworICAgIHpzdHJlYW0uZGF0YV90eXBlID0gWl9VTktOT1dOOworCisJLyoKKwkgKiBVc2UgdGhlIHVuZG9jdW1lbnRlZCAibmVnYXRpdmUgd2luZG93IGJpdHMiIGZlYXR1cmUgdG8gdGVsbCB6bGliCisJICogdGhhdCB0aGVyZSdzIG5vIHpsaWIgaGVhZGVyIHdhaXRpbmcgZm9yIGl0LgorCSAqLworICAgIHplcnIgPSBpbmZsYXRlSW5pdDIoJnpzdHJlYW0sIC1NQVhfV0JJVFMpOworICAgIGlmICh6ZXJyICE9IFpfT0spIHsKKyAgICAgICAgaWYgKHplcnIgPT0gWl9WRVJTSU9OX0VSUk9SKSB7CisgICAgICAgICAgICBMT0dFKCJJbnN0YWxsZWQgemxpYiBpcyBub3QgY29tcGF0aWJsZSB3aXRoIGxpbmtlZCB2ZXJzaW9uICglcylcbiIsCisgICAgICAgICAgICAgICAgWkxJQl9WRVJTSU9OKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0UoIkNhbGwgdG8gaW5mbGF0ZUluaXQyIGZhaWxlZCAoemVycj0lZClcbiIsIHplcnIpOworICAgICAgICB9CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIExvb3Agd2hpbGUgd2UgaGF2ZSBkYXRhLgorICAgICAqLworICAgIGRvIHsKKyAgICAgICAgdW5zaWduZWQgbG9uZyBnZXRTaXplOworCisgICAgICAgIC8qIHJlYWQgYXMgbXVjaCBhcyB3ZSBjYW4gKi8KKyAgICAgICAgaWYgKHpzdHJlYW0uYXZhaWxfaW4gPT0gMCkgeworICAgICAgICAgICAgZ2V0U2l6ZSA9IChjb21wUmVtYWluaW5nID4ga1JlYWRCdWZTaXplKSA/CisgICAgICAgICAgICAgICAgICAgICAgICBrUmVhZEJ1ZlNpemUgOiBjb21wUmVtYWluaW5nOworICAgICAgICAgICAgTE9HVigiKysrIHJlYWRpbmcgJWxkIGJ5dGVzICglbGQgbGVmdClcbiIsCisgICAgICAgICAgICAgICAgZ2V0U2l6ZSwgY29tcFJlbWFpbmluZyk7CisKKyAgICAgICAgICAgIGludCBjYyA9IGZyZWFkKHJlYWRCdWYsIGdldFNpemUsIDEsIGZwKTsKKyAgICAgICAgICAgIGlmIChjYyAhPSAoaW50KSBnZXRTaXplKSB7CisgICAgICAgICAgICAgICAgTE9HRCgiaW5mbGF0ZSByZWFkIGZhaWxlZCAoJWQgdnMgJWxkKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgY2MsIGdldFNpemUpOworICAgICAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjb21wUmVtYWluaW5nIC09IGdldFNpemU7CisKKyAgICAgICAgICAgIHpzdHJlYW0ubmV4dF9pbiA9IHJlYWRCdWY7CisgICAgICAgICAgICB6c3RyZWFtLmF2YWlsX2luID0gZ2V0U2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIHVuY29tcHJlc3MgdGhlIGRhdGEgKi8KKyAgICAgICAgemVyciA9IGluZmxhdGUoJnpzdHJlYW0sIFpfTk9fRkxVU0gpOworICAgICAgICBpZiAoemVyciAhPSBaX09LICYmIHplcnIgIT0gWl9TVFJFQU1fRU5EKSB7CisgICAgICAgICAgICBMT0dEKCJ6bGliIGluZmxhdGUgY2FsbCBmYWlsZWQgKHplcnI9JWQpXG4iLCB6ZXJyKTsKKyAgICAgICAgICAgIGdvdG8gel9iYWlsOworICAgICAgICB9CisKKwkJLyogb3V0cHV0IGJ1ZmZlciBob2xkcyBhbGwsIHNvIG5vIG5lZWQgdG8gd3JpdGUgdGhlIG91dHB1dCAqLworICAgIH0gd2hpbGUgKHplcnIgPT0gWl9PSyk7CisKKyAgICBhc3NlcnQoemVyciA9PSBaX1NUUkVBTV9FTkQpOyAgICAgICAvKiBvdGhlciBlcnJvcnMgc2hvdWxkJ3ZlIGJlZW4gY2F1Z2h0ICovCisKKyAgICBpZiAoKGxvbmcpIHpzdHJlYW0udG90YWxfb3V0ICE9IHVuY29tcHJlc3NlZExlbikgeworICAgICAgICBMT0dXKCJTaXplIG1pc21hdGNoIG9uIGluZmxhdGVkIGZpbGUgKCVsZCB2cyAlbGQpXG4iLAorICAgICAgICAgICAgenN0cmVhbS50b3RhbF9vdXQsIHVuY29tcHJlc3NlZExlbik7CisgICAgICAgIGdvdG8gel9iYWlsOworICAgIH0KKworICAgIC8vIHN1Y2Nlc3MhCisgICAgcmVzdWx0ID0gdHJ1ZTsKKworel9iYWlsOgorICAgIGluZmxhdGVFbmQoJnpzdHJlYW0pOyAgICAgICAgLyogZnJlZSB1cCBhbnkgYWxsb2NhdGVkIHN0cnVjdHVyZXMgKi8KKworYmFpbDoKKwlkZWxldGVbXSByZWFkQnVmOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBMb29rIGF0IHRoZSBjb250ZW50cyBvZiBhIGd6aXAgYXJjaGl2ZS4gIFdlIHdhbnQgdG8ga25vdyB3aGVyZSB0aGUKKyAqIGRhdGEgc3RhcnRzLCBhbmQgaG93IGxvbmcgaXQgd2lsbCBiZSBhZnRlciBpdCBpcyB1bmNvbXByZXNzZWQuCisgKgorICogV2UgZXhwZWN0IHRvIGZpbmQgdGhlIENSQyBhbmQgbGVuZ3RoIGFzIHRoZSBsYXN0IDggYnl0ZXMgb24gdGhlIGZpbGUuCisgKiBUaGlzIGlzIGEgcHJldHR5IHJlYXNvbmFibGUgdGhpbmcgdG8gZXhwZWN0IGZvciBsb2NhbGx5LWNvbXByZXNzZWQKKyAqIGZpbGVzLCBidXQgdGhlcmUncyBhIHNtYWxsIGNoYW5jZSB0aGF0IHNvbWUgZXh0cmEgcGFkZGluZyBnb3QgdGhyb3duCisgKiBvbiAodGhlIG1hbiBwYWdlIHRhbGtzIGFib3V0IGNvbXByZXNzZWQgZGF0YSB3cml0dGVuIHRvIHRhcGUpLiAgV2UKKyAqIGRvbid0IGN1cnJlbnRseSBkZWFsIHdpdGggdGhhdCBoZXJlLiAgSWYgImd6aXAgLWwiIHdoaW5lcywgd2UncmUgZ29pbmcKKyAqIHRvIGZhaWwgdG9vLgorICoKKyAqIE9uIGV4aXQsICJmcCIgaXMgcG9pbnRpbmcgYXQgdGhlIHN0YXJ0IG9mIHRoZSBjb21wcmVzc2VkIGRhdGEuCisgKi8KKy8qc3RhdGljKi8gYm9vbCBaaXBVdGlsczo6ZXhhbWluZUd6aXAoRklMRSogZnAsIGludCogcENvbXByZXNzaW9uTWV0aG9kLAorICAgIGxvbmcqIHBVbmNvbXByZXNzZWRMZW4sIGxvbmcqIHBDb21wcmVzc2VkTGVuLCB1bnNpZ25lZCBsb25nKiBwQ1JDMzIpCit7CisgICAgZW51bSB7ICAvLyBmbGFncworICAgICAgICBGVEVYVCAgICAgICA9IDB4MDEsCisgICAgICAgIEZIQ1JDICAgICAgID0gMHgwMiwKKyAgICAgICAgRkVYVFJBICAgICAgPSAweDA0LAorICAgICAgICBGTkFNRSAgICAgICA9IDB4MDgsCisgICAgICAgIEZDT01NRU5UICAgID0gMHgxMCwKKyAgICB9OworICAgIGludCBpYzsKKyAgICBpbnQgbWV0aG9kLCBmbGFnczsKKyAgICBpbnQgaTsKKworICAgIGljID0gZ2V0YyhmcCk7CisgICAgaWYgKGljICE9IDB4MWYgfHwgZ2V0YyhmcCkgIT0gMHg4YikKKyAgICAgICAgcmV0dXJuIGZhbHNlOyAgICAgICAvLyBub3QgZ3ppcAorICAgIG1ldGhvZCA9IGdldGMoZnApOworICAgIGZsYWdzID0gZ2V0YyhmcCk7CisKKyAgICAvKiBxdWljayBzYW5pdHkgY2hlY2tzICovCisgICAgaWYgKG1ldGhvZCA9PSBFT0YgfHwgZmxhZ3MgPT0gRU9GKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgaWYgKG1ldGhvZCAhPSBaaXBGaWxlUk86OmtDb21wcmVzc0RlZmxhdGVkKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAvKiBza2lwIG92ZXIgNCBieXRlcyBvZiBtb2QgdGltZSwgMSBieXRlIFhGTCwgMSBieXRlIE9TICovCisgICAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykKKyAgICAgICAgKHZvaWQpIGdldGMoZnApOworICAgIC8qIGNvbnN1bWUgImV4dHJhIiBmaWVsZCwgaWYgcHJlc2VudCAqLworICAgIGlmICgoZmxhZ3MgJiBGRVhUUkEpICE9IDApIHsKKyAgICAgICAgaW50IGxlbjsKKworICAgICAgICBsZW4gPSBnZXRjKGZwKTsKKyAgICAgICAgbGVuIHw9IGdldGMoZnApIDw8IDg7CisgICAgICAgIHdoaWxlIChsZW4tLSAmJiBnZXRjKGZwKSAhPSBFT0YpCisgICAgICAgICAgICA7CisgICAgfQorICAgIC8qIGNvbnN1bWUgZmlsZW5hbWUsIGlmIHByZXNlbnQgKi8KKyAgICBpZiAoKGZsYWdzICYgRk5BTUUpICE9IDApIHsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaWMgPSBnZXRjKGZwKTsKKyAgICAgICAgfSB3aGlsZSAoaWMgIT0gMCAmJiBpYyAhPSBFT0YpOworICAgIH0KKyAgICAvKiBjb25zdW1lIGNvbW1lbnQsIGlmIHByZXNlbnQgKi8KKyAgICBpZiAoKGZsYWdzICYgRkNPTU1FTlQpICE9IDApIHsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaWMgPSBnZXRjKGZwKTsKKyAgICAgICAgfSB3aGlsZSAoaWMgIT0gMCAmJiBpYyAhPSBFT0YpOworICAgIH0KKyAgICAvKiBjb25zdW1lIDE2LWJpdCBoZWFkZXIgQ1JDLCBpZiBwcmVzZW50ICovCisgICAgaWYgKChmbGFncyAmIEZIQ1JDKSAhPSAwKSB7CisgICAgICAgICh2b2lkKSBnZXRjKGZwKTsKKyAgICAgICAgKHZvaWQpIGdldGMoZnApOworICAgIH0KKworICAgIGlmIChmZW9mKGZwKSB8fCBmZXJyb3IoZnApKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAvKiBzZWVrIHRvIHRoZSBlbmQ7IENSQyBhbmQgbGVuZ3RoIGFyZSBpbiB0aGUgbGFzdCA4IGJ5dGVzICovCisgICAgbG9uZyBjdXJQb3NuID0gZnRlbGwoZnApOworICAgIHVuc2lnbmVkIGNoYXIgYnVmWzhdOworICAgIGZzZWVrKGZwLCAtOCwgU0VFS19FTkQpOworICAgICpwQ29tcHJlc3NlZExlbiA9IGZ0ZWxsKGZwKSAtIGN1clBvc247CisKKyAgICBpZiAoZnJlYWQoYnVmLCAxLCA4LCBmcCkgIT0gOCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIC8qIHNlZWsgYmFjayB0byBzdGFydCBvZiBjb21wcmVzc2VkIGRhdGEgKi8KKyAgICBmc2VlayhmcCwgY3VyUG9zbiwgU0VFS19TRVQpOworCisgICAgKnBDb21wcmVzc2lvbk1ldGhvZCA9IG1ldGhvZDsKKyAgICAqcENSQzMyID0gWmlwRmlsZVJPOjpnZXQ0TEUoJmJ1ZlswXSk7CisgICAgKnBVbmNvbXByZXNzZWRMZW4gPSBaaXBGaWxlUk86OmdldDRMRSgmYnVmWzRdKTsKKworICAgIHJldHVybiB0cnVlOworfQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL2NoYXJhY3RlckRhdGEuaCBiL2xpYnMvdXRpbHMvY2hhcmFjdGVyRGF0YS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5MzFkOTkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL2NoYXJhY3RlckRhdGEuaApAQCAtMCwwICsxLDczMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vIEF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG9uIDA3LTExLTIwMDYgYnkgbWFrZS1DaGFyYWN0ZXJEYXRhQworLy8gRE8gTk9UIEVESVQgRElSRUNUTFkKK25hbWVzcGFjZSBDaGFyYWN0ZXJEYXRhIHsKKworICAgIC8vIFN0cnVjdHVyZSBjb250YWluaW5nIGFuIGFycmF5IG9mIHJhbmdlcworICAgIHN0cnVjdCBSYW5nZSB7CisgICAgICAgIGludCBsZW5ndGg7CisgICAgICAgIGNvbnN0IHVpbnQzMl90KiBhcnJheTsKKyAgICB9OworCisgICAgLy8gRm9yIExhdGluMSBjaGFyYWN0ZXJzIGp1c3QgaW5kZXggaW50byB0aGlzIGFycmF5IHRvIGdldCB0aGUgaW5kZXggYW5kIGRlY29tcG9zaXRpb24KKyAgICBzdGF0aWMgY29uc3QgdWludDE2X3QgTEFUSU4xX0RBVEFbXSA9IHsKKyAgICAgICAgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIAorICAgICAgICAweDAwMDEsIDB4MDAwMiwgMHgwMDAzLCAweDAwMDIsIDB4MDAwNCwgMHgwMDAzLCAweDAwMDEsIDB4MDAwMSwgCisgICAgICAgIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAKKyAgICAgICAgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDMsIDB4MDAwMywgMHgwMDAzLCAweDAwMDIsIAorICAgICAgICAweDAwMDUsIDB4MDAwNiwgMHgwMDA2LCAweDAwMDcsIDB4MDAwOCwgMHgwMDA3LCAweDAwMDYsIDB4MDAwNiwgCisgICAgICAgIDB4MDAwOSwgMHgwMDBBLCAweDAwMDYsIDB4MDAwQiwgMHgwMDBDLCAweDAwMEQsIDB4MDAwQywgMHgwMDBDLCAKKyAgICAgICAgMHgwMDBFLCAweDAwMEYsIDB4MDAxMCwgMHgwMDExLCAweDAwMTIsIDB4MDAxMywgMHgwMDE0LCAweDAwMTUsIAorICAgICAgICAweDAwMTYsIDB4MDAxNywgMHgwMDBDLCAweDAwMDYsIDB4MDAxOCwgMHgwMDE5LCAweDAwMUEsIDB4MDAwNiwgCisgICAgICAgIDB4MDAwNiwgMHgwMDFCLCAweDAwMUMsIDB4MDAxRCwgMHgwMDFFLCAweDAwMUYsIDB4MDAyMCwgMHgwMDIxLCAKKyAgICAgICAgMHgwMDIyLCAweDAwMjMsIDB4MDAyNCwgMHgwMDI1LCAweDAwMjYsIDB4MDAyNywgMHgwMDI4LCAweDAwMjksIAorICAgICAgICAweDAwMkEsIDB4MDAyQiwgMHgwMDJDLCAweDAwMkQsIDB4MDAyRSwgMHgwMDJGLCAweDAwMzAsIDB4MDAzMSwgCisgICAgICAgIDB4MDAzMiwgMHgwMDMzLCAweDAwMzQsIDB4MDAzNSwgMHgwMDA2LCAweDAwMzYsIDB4MDAzNywgMHgwMDM4LCAKKyAgICAgICAgMHgwMDM3LCAweDAwMzksIDB4MDAzQSwgMHgwMDNCLCAweDAwM0MsIDB4MDAzRCwgMHgwMDNFLCAweDAwM0YsIAorICAgICAgICAweDAwNDAsIDB4MDA0MSwgMHgwMDQyLCAweDAwNDMsIDB4MDA0NCwgMHgwMDQ1LCAweDAwNDYsIDB4MDA0NywgCisgICAgICAgIDB4MDA0OCwgMHgwMDQ5LCAweDAwNEEsIDB4MDA0QiwgMHgwMDRDLCAweDAwNEQsIDB4MDA0RSwgMHgwMDRGLCAKKyAgICAgICAgMHgwMDUwLCAweDAwNTEsIDB4MDA1MiwgMHgwMDM1LCAweDAwMTksIDB4MDAzNiwgMHgwMDE5LCAweDAwMDEsIAorICAgICAgICAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAzLCAweDAwMDEsIDB4MDAwMSwgCisgICAgICAgIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAKKyAgICAgICAgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIAorICAgICAgICAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgMHgwMDAxLCAweDAwMDEsIDB4MDAwMSwgCisgICAgICAgIDB4NTg1MywgMHgwMDA2LCAweDAwMDgsIDB4MDAwOCwgMHgwMDA4LCAweDAwMDgsIDB4MDA1NCwgMHgwMDU0LCAKKyAgICAgICAgMHgxMDM3LCAweDAwNTQsIDB4Nzg1NSwgMHgwMDU2LCAweDAwMTksIDB4MDA1NywgMHgwMDU0LCAweDEwMzcsIAorICAgICAgICAweDAwNTgsIDB4MDA1OSwgMHg3ODVBLCAweDc4NUIsIDB4MTAzNywgMHgxMDVDLCAweDAwNTQsIDB4MDAwNiwgCisgICAgICAgIDB4MTAzNywgMHg3ODVELCAweDc4NTUsIDB4MDA1RSwgMHgzMDVGLCAweDMwNUYsIDB4MzA1RiwgMHgwMDA2LCAKKyAgICAgICAgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwMDYwLCAweDA4NjAsIAorICAgICAgICAweDA4NjAsIDB4MDg2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgCisgICAgICAgIDB4MDA2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwMDE5LCAKKyAgICAgICAgMHgwMDYwLCAweDA4NjAsIDB4MDg2MCwgMHgwODYwLCAweDA4NjAsIDB4MDg2MCwgMHgwMDYwLCAweDAwNTUsIAorICAgICAgICAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDAwNjEsIDB4MDg2MSwgCisgICAgICAgIDB4MDg2MSwgMHgwODYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAKKyAgICAgICAgMHgwMDYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDAwMTksIAorICAgICAgICAweDAwNjEsIDB4MDg2MSwgMHgwODYxLCAweDA4NjEsIDB4MDg2MSwgMHgwODYxLCAweDAwNjEsIDB4MDg2MgorICAgIH07CisKKyAgICAvLyBFYWNoIG9mIHRoZXNlIGFycmF5cyBpcyBzdHJpcHBlZCBpbnRvIHJhbmdlcy4gSW4gb3JkZXIgdG8gYnVpbGQgdGhlIGFycmF5cywgZWFjaAorICAgIC8vIGNvZGVwb2ludCB3YXMgYml0LXNoaWZ0ZWQgc28gdGhhdCBldmVuIGFuZCBvZGQgY2hhcmFjdGVycyB3ZXJlIHNlcGFyYXRlZCBpbnRvIGRpZmZlcmVudAorICAgIC8vIGFycmF5cy4gVGhlIGlkZW50aWZpZXIgb2YgZWFjaCBhcnJheSBpcyB0aGUgdG9wIGJ5dGUgYWZ0ZXIgYml0LXNoaWZ0aW5nLgorICAgIC8vIFRoZSBudW1iZXJzIHN0b3JlZCBpbiB0aGUgYXJyYXkgYXJlIHRoZSBiaXQtc2hpZnRlZCBjb2RlcG9pbnQsIHRoZSBkZWNvbXBvc2l0aW9uLCBhbmQgYW4KKyAgICAvLyBpbmRleCBpbnRvIGFub3RoZXIgYXJyYXkgb2YgYWxsIHBvc3NpYmxlIHBhY2tlZCBkYXRhIHZhbHVlcy4gVGhlIHRvcCAxNiBiaXRzIGFyZSB0aGUKKyAgICAvLyBjb2RlcG9pbnQgYW5kIHRoZSBib3R0b20gMTYgYXJlIHRoZSBkZWNvbXBvc2l0aW9uIGFuZCBpbmRleC4gVGhlIHRvcCA1IGJpdHMgZm9yIHRoZSBkZWNvbXBvc2l0aW9uCisgICAgLy8gYW5kIHRoZSByZXN0IGZvciB0aGUgaW5kZXguCisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IGEwW10gPSB7CisgICAgICAgIDB4MDA4MDA4NjMsIDB4MDA4ODAwNjMsIDB4MDA4OTA4NjMsIDB4MDA5MzAwNjMsIDB4MDA5NDA4NjMsIDB4MDA5ODA4NjQsIDB4MDA5OTEwNjMsIDB4MDA5QTA4NjMsIAorICAgICAgICAweDAwOUMwMDU1LCAweDAwOUQwODY1LCAweDAwQTAxMDY1LCAweDAwQTEwMDY1LCAweDAwQTIwODY1LCAweDAwQTUwMDYzLCAweDAwQTYwODYzLCAweDAwQTkwMDYzLCAKKyAgICAgICAgMHgwMEFBMDg2MywgMHgwMEIzMDA2MywgMHgwMEI0MDg2MywgMHgwMEJDMDg2NiwgMHgwMEJEMDg2NSwgMHgwMEMwMDA1NSwgMHgwMEMxMDA2MywgMHgwMEMzMDA2NywgCisgICAgICAgIDB4MDBDNDAwNjUsIDB4MDBDNTAwNjgsIDB4MDBDNjAwNjUsIDB4MDBDNzAwNjksIDB4MDBDODAwNkEsIDB4MDBDOTAwNjUsIDB4MDBDQTAwNkIsIDB4MDBDQjAwNkMsIAorICAgICAgICAweDAwQ0MwMDYzLCAweDAwQ0QwMDZELCAweDAwQ0UwMDZDLCAweDAwQ0YwMDZFLCAweDAwRDAwODYzLCAweDAwRDEwMDYzLCAweDAwRDMwMDZGLCAweDAwRDQwMDY1LCAKKyAgICAgICAgMHgwMEQ1MDA1NSwgMHgwMEQ2MDA2MywgMHgwMEQ3MDA2RiwgMHgwMEQ4MDg2NSwgMHgwMEQ5MDA3MCwgMHgwMERBMDA2NSwgMHgwMERDMDA2MywgMHgwMEREMDA1NSwgCisgICAgICAgIDB4MDBERTAwNjMsIDB4MDBERjAwNTUsIDB4MDBFMDAwNzEsIDB4MDBFMjEwNzIsIDB4MDBFMzEwNzMsIDB4MDBFNDEwNzQsIDB4MDBFNTEwNzIsIDB4MDBFNjEwNzMsIAorICAgICAgICAweDAwRTcwODY1LCAweDAwRUYwODYzLCAweDAwRjIwMDYzLCAweDAwRjMwODYzLCAweDAwRjgwODU1LCAweDAwRjkxMDc0LCAweDAwRkEwODYzLCAweDAwRkIwMDc1LCAKKyAgICAgICAgMHgwMEZDMDg2MywgMHgwMTBFMDA2MywgMHgwMTBGMDg2MywgMHgwMTEwMDA3NiwgMHgwMTExMDA2MywgMHgwMTEzMDg2MywgMHgwMTFBMDA1NSwgMHgwMTFEMDA3NywgCisgICAgICAgIDB4MDExRTAwNjUsIDB4MDExRjAwNzcsIDB4MDEyMDAwNTUsIDB4MDEyMTAwNzgsIDB4MDEyODAwNTUsIDB4MDEyQTAwNzksIDB4MDEyQjAwN0EsIDB4MDEyQzAwNTUsIAorICAgICAgICAweDAxMzAwMDdBLCAweDAxMzEwMDU1LCAweDAxMzQwMDdCLCAweDAxMzUwMDU1LCAweDAxMzkwMDdDLCAweDAxM0EwMDU1LCAweDAxNDAwMDdELCAweDAxNDEwMDU1LCAKKyAgICAgICAgMHgwMTQ0MDA3RCwgMHgwMTQ1MDA3RSwgMHgwMTQ2MDA1NSwgMHgwMTQ5MDA3RiwgMHgwMTRBMDA4MCwgMHgwMTRCMDA1NSwgMHgwMTU4Nzg4MSwgMHgwMTVEMDA4MiwgCisgICAgICAgIDB4MDE1RTAwODEsIDB4MDE2MTAwMzcsIDB4MDE2MzAwODIsIDB4MDE2ODAwODEsIDB4MDE2OTAwMzcsIDB4MDE2QzEwMzcsIDB4MDE2RjAwMzcsIDB4MDE3MDc4ODEsIAorICAgICAgICAweDAxNzMwMDM3LCAweDAxNzcwMDgxLCAweDAxNzgwMDM3LCAweDAxODAwMDgzLCAweDAxQTAwODgzLCAweDAxQTEwMDgzLCAweDAxQTIwODgzLCAweDAxQTMwMDgzLCAKKyAgICAgICAgMHgwMUI4MDA3OCwgMHgwMUJBMDgzNywgMHgwMUJCMDA3OCwgMHgwMUJEMTA4MSwgMHgwMUJFMDA3OCwgMHgwMUJGMDgwNiwgMHgwMUMwMDA3OCwgMHgwMUMyMTAzNywgCisgICAgICAgIDB4MDFDMzA4ODQsIDB4MDFDNDA4ODUsIDB4MDFDNjA4ODYsIDB4MDFDNzA4ODcsIDB4MDFDODA4NTUsIDB4MDFDOTAwNjAsIDB4MDFEMTAwNzgsIDB4MDFEMjAwNjAsIAorICAgICAgICAweDAxRDUwODYwLCAweDAxRDYwODg4LCAweDAxRDcwODg5LCAweDAxRDgwODU1LCAweDAxRDkwMDYxLCAweDAxRTEwMDhBLCAweDAxRTIwMDYxLCAweDAxRTUwODYxLCAKKyAgICAgICAgMHgwMUU2MDg4QiwgMHgwMUU3MDg4QywgMHgwMUU4MTA4RCwgMHgwMUU5MTA3NywgMHgwMUVBMDg3NywgMHgwMUVCMTA4RSwgMHgwMUVDMDA2MywgMHgwMUY4MTA4RiwgCisgICAgICAgIDB4MDFGOTEwOTAsIDB4MDFGQTEwOTEsIDB4MDFGQjAwMTksIDB4MDFGQzAwNjUsIDB4MDFGRDAwNjMsIDB4MDFGRTAwNTUsIDB4MDFGRjAwNzcsIDB4MDIwMDA4OTIsIAorICAgICAgICAweDAyMDEwMDkyLCAweDAyMDYwODkyLCAweDAyMDgwMDYwLCAweDAyMTgwMDYxLCAweDAyMjgwODkzLCAweDAyMjkwMDkzLCAweDAyMkUwODkzLCAweDAyMzAwMDYzLCAKKyAgICAgICAgMHgwMjNCMDg2MywgMHgwMjNDMDA2MywgMHgwMjQxMDA5NCwgMHgwMjQyMDA4MywgMHgwMjQ0MDA5NSwgMHgwMjQ1MDA2MywgMHgwMjYwMDA3NywgMHgwMjYxMDg2NSwgCisgICAgICAgIDB4MDI2MjAwNjUsIDB4MDI2ODA4NjMsIDB4MDI2QTAwNjMsIDB4MDI2QjA4NjMsIDB4MDI2QzAwNjMsIDB4MDI2RDA4NjMsIDB4MDI3MDAwNjMsIDB4MDI3MTA4NjMsIAorICAgICAgICAweDAyNzQwMDYzLCAweDAyNzUwODYzLCAweDAyN0IwMDYzLCAweDAyN0MwODYzLCAweDAyN0QwMDc4LCAweDAyODAwMDYzLCAweDAyODgwMDc4LCAweDAyOTkwMDk2LCAKKyAgICAgICAgMHgwMkFDMDA3OCwgMHgwMkFEMDA5NywgMHgwMkIwMDA3OCwgMHgwMkIxMDA5OCwgMHgwMkM0MDA3OCwgMHgwMkM1MDA5OSwgMHgwMkM2MDA3OCwgMHgwMkM5MDA4MywgCisgICAgICAgIDB4MDJERDAwNzgsIDB4MDJERTAwODMsIDB4MDJERjAwOUEsIDB4MDJFMTAwODMsIDB4MDJFMzAwOUEsIDB4MDJFNDAwNzgsIDB4MDJFODAwOUIsIDB4MDJGNjAwNzgsIAorICAgICAgICAweDAyRjgwMDlCLCAweDAyRkEwMDlBLCAweDAyRkIwMDc4LCAweDAzMDAwMDlDLCAweDAzMDIwMDc4LCAweDAzMDYwMDBDLCAweDAzMDcwMDU0LCAweDAzMDgwMDgzLCAKKyAgICAgICAgMHgwMzBCMDA3OCwgMHgwMzBGMDA5RCwgMHgwMzEwMDA3OCwgMHgwMzExMDg5RSwgMHgwMzE0MDA5RSwgMHgwMzFFMDA3OCwgMHgwMzIwMDA5RiwgMHgwMzIxMDA5RSwgCisgICAgICAgIDB4MDMyNjAwODMsIDB4MDMzMDAwQTAsIDB4MDMzMTAwQTEsIDB4MDMzMjAwQTIsIDB4MDMzMzAwQTMsIDB4MDMzNDAwQTQsIDB4MDMzNTAwMDcsIDB4MDMzNjAwQTUsIAorICAgICAgICAweDAzMzcwMDlFLCAweDAzMzgwMDgzLCAweDAzMzkwMDlFLCAweDAzM0IxMDlFLCAweDAzM0QwMDlFLCAweDAzNjAwODlFLCAweDAzNjIwMDlFLCAweDAzNkEwMDlELCAKKyAgICAgICAgMHgwMzZCMDA4MywgMHgwMzZGMDA5NSwgMHgwMzcwMDA4MywgMHgwMzczMDA5RiwgMHgwMzc0MDA4MywgMHgwMzc3MDA5RSwgMHgwMzc4MDAwRSwgMHgwMzc5MDAxMCwgCisgICAgICAgIDB4MDM3QTAwMTIsIDB4MDM3QjAwMTQsIDB4MDM3QzAwMTYsIDB4MDM3RDAwOUUsIDB4MDM3RjAwQTYsIDB4MDM4MDAwOUQsIDB4MDM4NzAwNzgsIDB4MDM4ODAwOUUsIAorICAgICAgICAweDAzOTgwMDgzLCAweDAzQTYwMDc4LCAweDAzQTcwMDlFLCAweDAzQjcwMDc4LCAweDAzQzAwMDlFLCAweDAzRDMwMDgzLCAweDAzRDkwMDc4LCAweDA0ODEwMDgzLCAKKyAgICAgICAgMHgwNDgyMDA3MSwgMHgwNDlBMDg3MSwgMHgwNDlCMDA3MSwgMHgwNDlEMDA3OCwgMHgwNDlFMDA4MywgMHgwNDlGMDBBNywgMHgwNEExMDA4MywgMHgwNEE1MDBBNywgCisgICAgICAgIDB4MDRBNzAwNzgsIDB4MDRBODAwNzEsIDB4MDRBOTAwODMsIDB4MDRBQjAwNzgsIDB4MDRBQzA4NzEsIDB4MDRCMDAwNzEsIDB4MDRCMTAwODMsIDB4MDRCMjAwOTcsIAorICAgICAgICAweDA0QjMwMEE4LCAweDA0QjQwMEE5LCAweDA0QjUwMEFBLCAweDA0QjYwMEFCLCAweDA0QjcwMEFDLCAweDA0QjgwMDk3LCAweDA0QjkwMDc4LCAweDA0QzEwMEE3LCAKKyAgICAgICAgMHgwNEMyMDA3OCwgMHgwNEMzMDA3MSwgMHgwNEM3MDA3OCwgMHgwNEM4MDA3MSwgMHgwNEM5MDA3OCwgMHgwNENBMDA3MSwgMHgwNERBMDA3OCwgMHgwNERCMDA3MSwgCisgICAgICAgIDB4MDRERDAwNzgsIDB4MDRERTAwODMsIDB4MDRERjAwQTcsIDB4MDRFMTAwODMsIDB4MDRFMzAwNzgsIDB4MDRFNDAwQTcsIDB4MDRFNTAwNzgsIDB4MDRFNjA4QTcsIAorICAgICAgICAweDA0RTcwMDcxLCAweDA0RTgwMDc4LCAweDA0RUUwODcxLCAweDA0RUYwMDc4LCAweDA0RjAwMDcxLCAweDA0RjEwMDgzLCAweDA0RjIwMDc4LCAweDA0RjMwMEE4LCAKKyAgICAgICAgMHgwNEY0MDBBOSwgMHgwNEY1MDBBQSwgMHgwNEY2MDBBQiwgMHgwNEY3MDBBQywgMHgwNEY4MDA3MSwgMHgwNEY5MDAwOCwgMHgwNEZBMDBBRCwgMHgwNEZCMDBBRSwgCisgICAgICAgIDB4MDRGQzAwQUYsIDB4MDRGRDAwOTQsIDB4MDRGRTAwNzgsIDB4MDUwMTAwODMsIDB4MDUwMjAwNzgsIDB4MDUwMzAwNzEsIDB4MDUwNjAwNzgsIDB4MDUwODAwNzEsIAorICAgICAgICAweDA1MDkwMDc4LCAweDA1MEEwMDcxLCAweDA1MUEwMDc4LCAweDA1MUIwODcxLCAweDA1MUMwMDcxLCAweDA1MUQwMDc4LCAweDA1MUUwMDgzLCAweDA1MUYwMEE3LCAKKyAgICAgICAgMHgwNTIxMDA4MywgMHgwNTIyMDA3OCwgMHgwNTI0MDA4MywgMHgwNTI1MDA3OCwgMHgwNTI2MDA4MywgMHgwNTI3MDA3OCwgMHgwNTJEMDg3MSwgMHgwNTJFMDA3MSwgCisgICAgICAgIDB4MDUyRjA4NzEsIDB4MDUzMDAwNzgsIDB4MDUzMzAwQTgsIDB4MDUzNDAwQTksIDB4MDUzNTAwQUEsIDB4MDUzNjAwQUIsIDB4MDUzNzAwQUMsIDB4MDUzODAwODMsIAorICAgICAgICAweDA1MzkwMDcxLCAweDA1M0IwMDc4LCAweDA1NDEwMDgzLCAweDA1NDIwMDc4LCAweDA1NDMwMDcxLCAweDA1NDcwMDc4LCAweDA1NDgwMDcxLCAweDA1NDkwMDc4LCAKKyAgICAgICAgMHgwNTRBMDA3MSwgMHgwNTVBMDA3OCwgMHgwNTVCMDA3MSwgMHgwNTVEMDA3OCwgMHgwNTVFMDA4MywgMHgwNTVGMDBBNywgMHgwNTYxMDA4MywgMHgwNTYzMDA3OCwgCisgICAgICAgIDB4MDU2NDAwODMsIDB4MDU2NTAwNzgsIDB4MDU2NjAwQTcsIDB4MDU2NzAwNzgsIDB4MDU2ODAwNzEsIDB4MDU2OTAwNzgsIDB4MDU3MDAwNzEsIDB4MDU3MTAwODMsIAorICAgICAgICAweDA1NzIwMDc4LCAweDA1NzMwMEE4LCAweDA1NzQwMEE5LCAweDA1NzUwMEFBLCAweDA1NzYwMEFCLCAweDA1NzcwMEFDLCAweDA1NzgwMDc4LCAweDA1ODEwMEE3LCAKKyAgICAgICAgMHgwNTgyMDA3OCwgMHgwNTgzMDA3MSwgMHgwNTg3MDA3OCwgMHgwNTg4MDA3MSwgMHgwNTg5MDA3OCwgMHgwNThBMDA3MSwgMHgwNTlBMDA3OCwgMHgwNTlCMDA3MSwgCisgICAgICAgIDB4MDU5RDAwNzgsIDB4MDU5RTAwODMsIDB4MDU5RjAwQTcsIDB4MDVBMTAwODMsIDB4MDVBMjAwNzgsIDB4MDVBNDA4QTcsIDB4MDVBNTAwNzgsIDB4MDVBNjA4QTcsIAorICAgICAgICAweDA1QTcwMDc4LCAweDA1QUIwMDgzLCAweDA1QUMwMDc4LCAweDA1QUUwODcxLCAweDA1QUYwMDc4LCAweDA1QjAwMDcxLCAweDA1QjEwMDc4LCAweDA1QjMwMEE4LCAKKyAgICAgICAgMHgwNUI0MDBBOSwgMHgwNUI1MDBBQSwgMHgwNUI2MDBBQiwgMHgwNUI3MDBBQywgMHgwNUI4MDA5NCwgMHgwNUI5MDA3OCwgMHgwNUMxMDA4MywgMHgwNUMyMDA3OCwgCisgICAgICAgIDB4MDVDMzAwNzEsIDB4MDVDNjAwNzgsIDB4MDVDNzAwNzEsIDB4MDVDQTA4NzEsIDB4MDVDQjAwNzgsIDB4MDVDRDAwNzEsIDB4MDVEMDAwNzgsIDB4MDVEMjAwNzEsIAorICAgICAgICAweDA1RDMwMDc4LCAweDA1RDQwMDcxLCAweDA1RDYwMDc4LCAweDA1RDcwMDcxLCAweDA1REQwMDc4LCAweDA1REYwMEE3LCAweDA1RTAwMDgzLCAweDA1RTEwMEE3LCAKKyAgICAgICAgMHgwNUUyMDA3OCwgMHgwNUUzMDBBNywgMHgwNUU1MDhBNywgMHgwNUU3MDA3OCwgMHgwNUYzMDBBOCwgMHgwNUY0MDBBOSwgMHgwNUY1MDBBQSwgMHgwNUY2MDBBQiwgCisgICAgICAgIDB4MDVGNzAwQUMsIDB4MDVGODAwQjAsIDB4MDVGOTAwQjEsIDB4MDVGQTAwNTQsIDB4MDVGRTAwNzgsIDB4MDYwMTAwQTcsIDB4MDYwMjAwNzgsIDB4MDYwMzAwNzEsIAorICAgICAgICAweDA2MUEwMDc4LCAweDA2MUIwMDcxLCAweDA2MUQwMDc4LCAweDA2MUYwMDgzLCAweDA2MjEwMEE3LCAweDA2MjMwMDgzLCAweDA2MjQwODgzLCAweDA2MjUwMDgzLCAKKyAgICAgICAgMHgwNjI3MDA3OCwgMHgwNjJCMDA4MywgMHgwNjJDMDA3OCwgMHgwNjMwMDA3MSwgMHgwNjMxMDA3OCwgMHgwNjMzMDBBOCwgMHgwNjM0MDBBOSwgMHgwNjM1MDBBQSwgCisgICAgICAgIDB4MDYzNjAwQUIsIDB4MDYzNzAwQUMsIDB4MDYzODAwNzgsIDB4MDY0MTAwQTcsIDB4MDY0MjAwNzgsIDB4MDY0MzAwNzEsIDB4MDY1QTAwNzgsIDB4MDY1QjAwNzEsIAorICAgICAgICAweDA2NUQwMDc4LCAweDA2NUUwMDgzLCAweDA2NUYwMEE3LCAweDA2NjAwOEE3LCAweDA2NjEwMEE3LCAweDA2NjMwMEIyLCAweDA2NjQwOEE3LCAweDA2NjYwMDgzLCAKKyAgICAgICAgMHgwNjY3MDA3OCwgMHgwNjZCMDBBNywgMHgwNjZDMDA3OCwgMHgwNjZGMDA3MSwgMHgwNjcxMDA3OCwgMHgwNjczMDBBOCwgMHgwNjc0MDBBOSwgMHgwNjc1MDBBQSwgCisgICAgICAgIDB4MDY3NjAwQUIsIDB4MDY3NzAwQUMsIDB4MDY3ODAwNzgsIDB4MDY4MTAwQTcsIDB4MDY4MjAwNzgsIDB4MDY4MzAwNzEsIDB4MDY5RDAwNzgsIDB4MDY5RjAwQTcsIAorICAgICAgICAweDA2QTEwMDgzLCAweDA2QTIwMDc4LCAweDA2QTMwMEE3LCAweDA2QTUwOEE3LCAweDA2QTcwMDc4LCAweDA2QjAwMDcxLCAweDA2QjEwMDc4LCAweDA2QjMwMEE4LCAKKyAgICAgICAgMHgwNkI0MDBBOSwgMHgwNkI1MDBBQSwgMHgwNkI2MDBBQiwgMHgwNkI3MDBBQywgMHgwNkI4MDA3OCwgMHgwNkMxMDBBNywgMHgwNkMyMDA3OCwgMHgwNkMzMDA3MSwgCisgICAgICAgIDB4MDZDQzAwNzgsIDB4MDZDRDAwNzEsIDB4MDZEOTAwNzgsIDB4MDZEQTAwNzEsIDB4MDZERTAwNzgsIDB4MDZFMDAwNzEsIDB4MDZFNDAwNzgsIDB4MDZFNTAwODMsIAorICAgICAgICAweDA2RTYwMDc4LCAweDA2RTgwMEE3LCAweDA2RTkwMDgzLCAweDA2RUMwMEE3LCAweDA2RUQwOEE3LCAweDA2RjAwMDc4LCAweDA2RjkwMEE3LCAweDA2RkEwMDk3LCAKKyAgICAgICAgMHgwNkZCMDA3OCwgMHgwNzAxMDA3MSwgMHgwNzFBMDA4MywgMHgwNzFFMDA3OCwgMHgwNzIwMDA3MSwgMHgwNzIzMDA4MSwgMHgwNzI0MDA4MywgMHgwNzI4MDBBOCwgCisgICAgICAgIDB4MDcyOTAwQTksIDB4MDcyQTAwQUEsIDB4MDcyQjAwQUIsIDB4MDcyQzAwQUMsIDB4MDcyRDAwOTcsIDB4MDcyRTAwNzgsIDB4MDc0MTAwNzEsIDB4MDc0MzAwNzgsIAorICAgICAgICAweDA3NDQwMDcxLCAweDA3NDYwMDc4LCAweDA3NEEwMDcxLCAweDA3NEMwMDc4LCAweDA3NEQwMDcxLCAweDA3NTAwMDc4LCAweDA3NTEwMDcxLCAweDA3NTIwMDc4LCAKKyAgICAgICAgMHgwNzU1MDA3MSwgMHgwNzU2MDA3OCwgMHgwNzU3MDA3MSwgMHgwNzVBMDA4MywgMHgwNzVEMDA3OCwgMHgwNzVFMDA4MywgMHgwNzVGMDA3OCwgMHgwNzYwMDA3MSwgCisgICAgICAgIDB4MDc2MzAwODEsIDB4MDc2NDAwODMsIDB4MDc2NzAwNzgsIDB4MDc2ODAwQTgsIDB4MDc2OTAwQTksIDB4MDc2QTAwQUEsIDB4MDc2QjAwQUIsIDB4MDc2QzAwQUMsIAorICAgICAgICAweDA3NkQwMDc4LCAweDA3NkUxMDcxLCAweDA3NkYwMDc4LCAweDA3ODAwMDcxLCAweDA3ODEwMDk0LCAweDA3ODIwMDk3LCAweDA3ODY1ODk3LCAweDA3ODcwMDk3LCAKKyAgICAgICAgMHgwNzhBMDA5NCwgMHgwNzhDMDA4MywgMHgwNzhEMDA5NCwgMHgwNzkwMDBBOCwgMHgwNzkxMDBBOSwgMHgwNzkyMDBBQSwgMHgwNzkzMDBBQiwgMHgwNzk0MDBBQywgCisgICAgICAgIDB4MDc5NTAwQjMsIDB4MDc5QTAwOTQsIDB4MDc5RDAwQjQsIDB4MDc5RjAwQTcsIDB4MDdBMDAwNzEsIDB4MDdBNDAwNzgsIDB4MDdBNTAwNzEsIDB4MDdBOTA4NzEsIAorICAgICAgICAweDA3QUEwMDcxLCAweDA3QUUwODcxLCAweDA3QUYwMDcxLCAweDA3QjYwMDc4LCAweDA3QjkwMDgzLCAweDA3QkIwODgzLCAweDA3QkQwMDgzLCAweDA3QzQwMDcxLCAKKyAgICAgICAgMHgwN0M2MDA3OCwgMHgwN0M4MDA4MywgMHgwN0NDMDA3OCwgMHgwN0NEMDA4MywgMHgwN0QxMDg4MywgMHgwN0QyMDA4MywgMHgwN0Q2MDg4MywgMHgwN0Q3MDA4MywgCisgICAgICAgIDB4MDdERjAwOTQsIDB4MDdFMzAwODMsIDB4MDdFNDAwOTQsIDB4MDdFNzAwNzgsIDB4MDdFODAwOTcsIDB4MDdFOTAwNzgsIDB4MDgwMDAwNzEsIDB4MDgxMTAwNzgsIAorICAgICAgICAweDA4MTIwMDcxLCAweDA4MTMwODcxLCAweDA4MTQwMDc4LCAweDA4MTUwMDcxLCAweDA4MTYwMEE3LCAweDA4MTcwMDgzLCAweDA4MUEwMDc4LCAweDA4MUIwMDgzLCAKKyAgICAgICAgMHgwODFDMDBBNywgMHgwODFEMDA3OCwgMHgwODIwMDBBOCwgMHgwODIxMDBBOSwgMHgwODIyMDBBQSwgMHgwODIzMDBBQiwgMHgwODI0MDBBQywgMHgwODI1MDA5NywgCisgICAgICAgIDB4MDgyODAwNzEsIDB4MDgyQjAwQTcsIDB4MDgyQzAwODMsIDB4MDgyRDAwNzgsIDB4MDg1MDAwQjUsIDB4MDg2MzAwNzgsIDB4MDg2ODAwNzEsIDB4MDg3RTc4ODEsIAorICAgICAgICAweDA4N0YwMDc4LCAweDA4ODAwMDcxLCAweDA4QUQwMDc4LCAweDA4QjAwMDcxLCAweDA4RDIwMDc4LCAweDA4RDQwMDcxLCAweDA4RkQwMDc4LCAweDA5MDAwMDcxLCAKKyAgICAgICAgMHgwOTI3MDA3OCwgMHgwOTI4MDA3MSwgMHgwOTJGMDA3OCwgMHgwOTMwMDA3MSwgMHgwOTQ3MDA3OCwgMHgwOTQ4MDA3MSwgMHgwOTVCMDA3OCwgMHgwOTVDMDA3MSwgCisgICAgICAgIDB4MDk2MzAwNzgsIDB4MDk2NDAwNzEsIDB4MDk4QjAwNzgsIDB4MDk4QzAwNzEsIDB4MDlBRTAwNzgsIDB4MDlCMDAwOTQsIDB4MDlCMTAwOTcsIDB4MDlCNTAwQjYsIAorICAgICAgICAweDA5QjYwMEI3LCAweDA5QjcwMEI4LCAweDA5QjgwMEI5LCAweDA5QjkwMEIwLCAweDA5QkEwMEJBLCAweDA5QkIwMEJCLCAweDA5QkMwMEJDLCAweDA5QkQwMEJELCAKKyAgICAgICAgMHgwOUJFMDBCRSwgMHgwOUJGMDA3OCwgMHgwOUMwMDA3MSwgMHgwOUM4MDA1NCwgMHgwOUNEMDA3OCwgMHgwOUQwMDA3MSwgMHgwOUZCMDA3OCwgMHgwQTAxMDA3MSwgCisgICAgICAgIDB4MEIzNzAwOTcsIDB4MEIzODAwNzEsIDB4MEIzQzAwNzgsIDB4MEI0MDAwMDUsIDB4MEI0MTAwNzEsIDB4MEI0RTAwQkYsIDB4MEI0RjAwNzgsIDB4MEI1MDAwNzEsIAorICAgICAgICAweDBCNzYwMDk3LCAweDBCNzcwMEMwLCAweDBCNzgwMEMxLCAweDBCNzkwMDc4LCAweDBCODAwMDcxLCAweDBCODkwMDgzLCAweDBCOEIwMDc4LCAweDBCOTAwMDcxLCAKKyAgICAgICAgMHgwQjk5MDA4MywgMHgwQjlCMDA5NywgMHgwQjlDMDA3OCwgMHgwQkEwMDA3MSwgMHgwQkE5MDA4MywgMHgwQkFBMDA3OCwgMHgwQkIwMDA3MSwgMHgwQkI5MDA4MywgCisgICAgICAgIDB4MEJCQTAwNzgsIDB4MEJDMDAwNzEsIDB4MEJEQTAwQzIsIDB4MEJEQjAwQTcsIDB4MEJEQzAwODMsIDB4MEJERjAwQTcsIDB4MEJFMzAwODMsIDB4MEJFNDAwQTcsIAorICAgICAgICAweDBCRTUwMDgzLCAweDBCRUEwMDk3LCAweDBCRUUwMDcxLCAweDBCRUYwMDc4LCAweDBCRjAwMEE4LCAweDBCRjEwMEE5LCAweDBCRjIwMEFBLCAweDBCRjMwMEFCLCAKKyAgICAgICAgMHgwQkY0MDBBQywgMHgwQkY1MDA3OCwgMHgwQkY4MDBDMywgMHgwQkY5MDBDNCwgMHgwQkZBMDBDNSwgMHgwQkZCMDBDNiwgMHgwQkZDMDBDNywgMHgwQkZEMDA3OCwgCisgICAgICAgIDB4MEMwMDAwMDYsIDB4MEMwMzAwOTksIDB4MEMwNDAwMDYsIDB4MEMwNjAwODMsIDB4MEMwNzAwMDUsIDB4MEMwODAwQTgsIDB4MEMwOTAwQTksIDB4MEMwQTAwQUEsIAorICAgICAgICAweDBDMEIwMEFCLCAweDBDMEMwMEFDLCAweDBDMEQwMDc4LCAweDBDMTAwMDcxLCAweDBDM0MwMDc4LCAweDBDNDAwMDcxLCAweDBDNTUwMDc4LCAweDBDODAwMDcxLCAKKyAgICAgICAgMHgwQzhGMDA3OCwgMHgwQzkwMDA4MywgMHgwQzkyMDBBNywgMHgwQzk0MDA4MywgMHgwQzk1MDBDOCwgMHgwQzk2MDA3OCwgMHgwQzk4MDBBNywgMHgwQzk5MDA4MywgCisgICAgICAgIDB4MEM5QTAwQTcsIDB4MEM5RDAwODMsIDB4MEM5RTAwNzgsIDB4MENBMDAwNTQsIDB4MENBMTAwNzgsIDB4MENBMjAwMDYsIDB4MENBMzAwQTgsIDB4MENBNDAwQTksIAorICAgICAgICAweDBDQTUwMEFBLCAweDBDQTYwMEFCLCAweDBDQTcwMEFDLCAweDBDQTgwMDcxLCAweDBDQjcwMDc4LCAweDBDQjgwMDcxLCAweDBDQkIwMDc4LCAweDBDQzAwMDcxLCAKKyAgICAgICAgMHgwQ0Q1MDA3OCwgMHgwQ0Q4MDBBNywgMHgwQ0UxMDA3MSwgMHgwQ0U0MDBBNywgMHgwQ0U1MDA3OCwgMHgwQ0U4MDBBOCwgMHgwQ0U5MDBBOSwgMHgwQ0VBMDBBQSwgCisgICAgICAgIDB4MENFQjAwQUIsIDB4MENFQzAwQUMsIDB4MENFRDAwNzgsIDB4MENFRjAwMDYsIDB4MENGMDAwNTQsIDB4MEQwMDAwNzEsIDB4MEQwQzAwODMsIDB4MEQwRDAwQTcsIAorICAgICAgICAweDBEMEUwMDc4LCAweDBEMEYwMDk3LCAweDBEMTAwMDc4LCAweDBFODAwMDU1LCAweDBFOTY3ODgxLCAweDBFQTcwMDgxLCAweDBFQTg3ODgxLCAweDBFQjE3MDU1LCAKKyAgICAgICAgMHgwRUI2MDA1NSwgMHgwRUJDNzg4MSwgMHgwRUJEMDA1NSwgMHgwRUNFNzg4MSwgMHgwRUUwMDA4MywgMHgwRUUyMDA3OCwgMHgwRjAwMDg2MywgMHgwRjRCMDg1NSwgCisgICAgICAgIDB4MEY0RDEwNTUsIDB4MEY0RTAwNzgsIDB4MEY1MDA4NjMsIDB4MEY3RDAwNzgsIDB4MEY4MDA4QzksIDB4MEY4NDA4Q0EsIDB4MEY4ODA4QzksIDB4MEY4QjAwNzgsIAorICAgICAgICAweDBGOEMwOENBLCAweDBGOEYwMDc4LCAweDBGOTAwOEM5LCAweDBGOTQwOENBLCAweDBGOTgwOEM5LCAweDBGOUMwOENBLCAweDBGQTAwOEM5LCAweDBGQTMwMDc4LCAKKyAgICAgICAgMHgwRkE0MDhDQSwgMHgwRkE3MDA3OCwgMHgwRkE4MDg1NSwgMHgwRkFDMDA3OCwgMHgwRkIwMDhDOSwgMHgwRkI0MDhDQSwgMHgwRkI4MDhDQiwgMHgwRkI5MDhDQywgCisgICAgICAgIDB4MEZCQjA4Q0QsIDB4MEZCQzA4Q0UsIDB4MEZCRDA4Q0YsIDB4MEZCRTA4RDAsIDB4MEZCRjAwNzgsIDB4MEZDMDA4QzksIDB4MEZDNDA4RDEsIDB4MEZDODA4QzksIAorICAgICAgICAweDBGQ0MwOEQxLCAweDBGRDAwOEM5LCAweDBGRDQwOEQxLCAweDBGRDgwOEM5LCAweDBGRDkwODU1LCAweDBGREMwOENBLCAweDBGREQwOEQyLCAweDBGREUwOEQzLCAKKyAgICAgICAgMHgwRkRGMDhENCwgMHgwRkUwMTAzNywgMHgwRkUxMDg1NSwgMHgwRkU0MDhENSwgMHgwRkU2MDhEMywgMHgwRkU3MDgzNywgMHgwRkU4MDhDOSwgMHgwRkU5MDg1NSwgCisgICAgICAgIDB4MEZFQTAwNzgsIDB4MEZFQjA4NTUsIDB4MEZFQzA4Q0EsIDB4MEZFRDA4RDYsIDB4MEZFRTAwNzgsIDB4MEZFRjA4MzcsIDB4MEZGMDA4QzksIDB4MEZGMTA4NTUsIAorICAgICAgICAweDBGRjQwOENBLCAweDBGRjUwOEQ3LCAweDBGRjYwOEQ4LCAweDBGRjcwODM3LCAweDBGRjgwMDc4LCAweDBGRjkwODU1LCAweDBGRkMwOEQ5LCAweDBGRkQwOERBLCAKKyAgICAgICAgMHgwRkZFMDhEMywgMHgwRkZGMTAzNywgMHgxMDAwMDgwNSwgMHgxMDAxMTAwNSwgMHgxMDA2MDA1NywgMHgxMDA3MDBDMiwgMHgxMDA4MDA5OSwgMHgxMDBCMDAwNiwgCisgICAgICAgIDB4MTAwQzAwREIsIDB4MTAwRDAwQjQsIDB4MTAwRTAwREIsIDB4MTAwRjAwQjQsIDB4MTAxMDAwMDYsIDB4MTAxMjEwMDYsIDB4MTAxNDAwREMsIDB4MTAxNTAwREQsIAorICAgICAgICAweDEwMTYwMERFLCAweDEwMTcwMERGLCAweDEwMTgwMDA3LCAweDEwMUExMDA3LCAweDEwMUIxMDA2LCAweDEwMUMwMDA2LCAweDEwMUQwMEUwLCAweDEwMUUxMDA2LCAKKyAgICAgICAgMHgxMDIwMDAzOCwgMHgxMDIxMDAwNiwgMHgxMDIyMDBFMSwgMHgxMDIzMDAwQSwgMHgxMDI0MTAwNiwgMHgxMDI1MDAwNiwgMHgxMDI5MDAxOSwgMHgxMDJBMDAzOCwgCisgICAgICAgIDB4MTAyQjAwMDYsIDB4MTAzMDAwNTcsIDB4MTAzMjAwNzgsIDB4MTAzNTAwNTcsIDB4MTAzODc4RTIsIDB4MTAzOTAwNzgsIDB4MTAzQTc4RTMsIDB4MTAzQjc4RTQsIAorICAgICAgICAweDEwM0M3OEU1LCAweDEwM0Q3ODBCLCAweDEwM0U3ODE5LCAweDEwM0Y3ODBBLCAweDEwNDA3MEUyLCAweDEwNDE3MDVBLCAweDEwNDI3MEUzLCAweDEwNDM3MEU0LCAKKyAgICAgICAgMHgxMDQ0NzBFNSwgMHgxMDQ1NzAwQiwgMHgxMDQ2NzAxOSwgMHgxMDQ3NzAwQSwgMHgxMDQ4NzA4MSwgMHgxMDRCMDA3OCwgMHgxMDUwMDAwOCwgMHgxMDU0MTAwOCwgCisgICAgICAgIDB4MTA1NTAwMDgsIDB4MTA1QjAwNzgsIDB4MTA2ODAwODMsIDB4MTA2RjAwOTUsIDB4MTA3MzAwODMsIDB4MTA3NjAwNzgsIDB4MTA4MDEwNTQsIDB4MTA4MTI4NzcsIAorICAgICAgICAweDEwODIwMDU0LCAweDEwODMxMDU0LCAweDEwODQwMDU0LCAweDEwODUyODU1LCAweDEwODYyODc3LCAweDEwODcyODU1LCAweDEwODgyODc3LCAweDEwOEEwMDU0LCAKKyAgICAgICAgMHgxMDhCMTA1NCwgMHgxMDhDMDA1NCwgMHgxMDhEMjg3NywgMHgxMDhGMDA1NCwgMHgxMDkwNzg1NCwgMHgxMDkyMjg3NywgMHgxMDkzMDhFNiwgMHgxMDk0Mjg3NywgCisgICAgICAgIDB4MTA5NTA4RTcsIDB4MTA5NjI4NzcsIDB4MTA5NzAwNTgsIDB4MTA5ODI4NzcsIDB4MTA5OTAwNTQsIDB4MTA5QTI4NTUsIDB4MTA5QjEwNzEsIDB4MTA5RDAwNTQsIAorICAgICAgICAweDEwOUUyODU1LCAweDEwOUYyODc3LCAweDEwQTAyOEU4LCAweDEwQTEwMDE5LCAweDEwQTMyODU1LCAweDEwQTUwMDU0LCAweDEwQTcwMDc4LCAweDEwQUEzMDVGLCAKKyAgICAgICAgMHgxMEIwMTBFOSwgMHgxMEIxMTBFQSwgMHgxMEIyMTBFQiwgMHgxMEIzMTBFQywgMHgxMEI0MTBFRCwgMHgxMEI1MTBFRSwgMHgxMEI2MTBFRiwgMHgxMEI3MTBGMCwgCisgICAgICAgIDB4MTBCODEwRjEsIDB4MTBCOTEwRjIsIDB4MTBCQTEwRjMsIDB4MTBCQjEwRjQsIDB4MTBCQzEwRjUsIDB4MTBCRDEwRjYsIDB4MTBCRTEwRjcsIDB4MTBCRjEwRjgsIAorICAgICAgICAweDEwQzAwMEY5LCAweDEwQzEwMEZBLCAweDEwQzIwMDc4LCAweDEwQzgwMDE5LCAweDEwQ0IwMDU0LCAweDEwQ0QwODE5LCAweDEwQ0UwMDU0LCAweDEwRDAwMDE5LCAKKyAgICAgICAgMHgxMEQxMDA1NCwgMHgxMEQzMDAxOSwgMHgxMEQ0MDA1NCwgMHgxMEQ3MDgxOSwgMHgxMEQ4MDA1NCwgMHgxMEU3MDgxOSwgMHgxMEU4MDA1NCwgMHgxMEU5MDAxOSwgCisgICAgICAgIDB4MTBFQjAwNTQsIDB4MTBGQTAwMTksIDB4MTEwMTAwRTgsIDB4MTEwMjA4RTgsIDB4MTEwMzAwMTksIDB4MTEwNDAwRkIsIDB4MTEwNjA4RkMsIDB4MTEwNzAwMTksIAorICAgICAgICAweDExMDkwMDBCLCAweDExMEEwMDE5LCAweDExMEIwMEU4LCAweDExMEMwMDE5LCAweDExMEQwMEU4LCAweDExMEYwMDE5LCAweDExMTAwMEU4LCAweDExMTIwOEU4LCAKKyAgICAgICAgMHgxMTE0MDAxOSwgMHgxMTE2MTBFOCwgMHgxMTE3MDBFOCwgMHgxMTE4MTBFOCwgMHgxMTE5MDBFOCwgMHgxMTFBMDAxOSwgMHgxMTFFMDBGRCwgMHgxMTFGMDBFOCwgCisgICAgICAgIDB4MTEyMjA4RTgsIDB4MTEyMzAwRTgsIDB4MTEyNzAwMTksIDB4MTEyOTAwRkQsIDB4MTEyQjAwMTksIDB4MTEzMDA4RTgsIDB4MTEzMjAwRkQsIDB4MTEzNjAwMTksIAorICAgICAgICAweDExMzcwOEZELCAweDExMzkwMEZELCAweDExM0EwOEZELCAweDExM0IwMEZELCAweDExM0MwOEZELCAweDExM0QwMEZELCAweDExNDAwOEZELCAweDExNDEwMEZELCAKKyAgICAgICAgMHgxMTQyMDhGRCwgMHgxMTQzMDBGRCwgMHgxMTQ0MDhGRCwgMHgxMTQ1MDBGRCwgMHgxMTQ2MDBFOCwgMHgxMTQ3MDAxOSwgMHgxMTQ4MDBGRSwgMHgxMTRBMDAxOSwgCisgICAgICAgIDB4MTE0QzAwRkYsIDB4MTE0RDAwMTksIDB4MTE1MTAwRkQsIDB4MTE1MjAwMTksIDB4MTE1MzAxMDAsIDB4MTE1NDAxMDEsIDB4MTE1NTAwRTgsIDB4MTE1NjA4RTgsIAorICAgICAgICAweDExNTgwMEZELCAweDExNUMwMEU4LCAweDExNUQwMDE5LCAweDExNUYwMEU4LCAweDExNjAwMDE5LCAweDExNjUwMEZFLCAweDExNjcwMDE5LCAweDExNjgwMEZELCAKKyAgICAgICAgMHgxMTY5MDAxOSwgMHgxMTZCMDBGRCwgMHgxMTcwMDhGRCwgMHgxMTcyMDBGRCwgMHgxMTc1MDhGRCwgMHgxMTc3MDAxOSwgMHgxMTc4MDBGRCwgMHgxMTc5MDEwMiwgCisgICAgICAgIDB4MTE3QjAxMDMsIDB4MTE3QzAwRTgsIDB4MTE3RDAxMDQsIDB4MTE3RjAxMDUsIDB4MTE4MDAwNTQsIDB4MTE4NDAwRkQsIDB4MTE4NjAwNTQsIDB4MTE5MDAwRTgsIAorICAgICAgICAweDExOTEwMDU0LCAweDExOTUwODBBLCAweDExOTYwMDU0LCAweDExOUIwMDk0LCAweDExQkUwMDE5LCAweDExQkYwMDU0LCAweDExQ0UwMDE5LCAweDExREEwMEI0LCAKKyAgICAgICAgMHgxMURCMDAwNiwgMHgxMURDMDA1NCwgMHgxMUVFMDA3OCwgMHgxMjAwMDA1NCwgMHgxMjE0MDA3OCwgMHgxMjIwMDA1NCwgMHgxMjI2MDA3OCwgMHgxMjMwMTkwNiwgCisgICAgICAgIDB4MTIzMTE5MDcsIDB4MTIzMjE5MDgsIDB4MTIzMzE5MDksIDB4MTIzNDE5MEEsIDB4MTIzNTE5MEIsIDB4MTIzNjE5MEMsIDB4MTIzNzE5MEQsIDB4MTIzODE5MEUsIAorICAgICAgICAweDEyMzkxOTBGLCAweDEyM0ExMTA2LCAweDEyM0IxMTA3LCAweDEyM0MxMTA4LCAweDEyM0QxMTA5LCAweDEyM0UxMTBBLCAweDEyM0YxMTBCLCAweDEyNDAxMTBDLCAKKyAgICAgICAgMHgxMjQxMTEwRCwgMHgxMjQyMTEwRSwgMHgxMjQzMTEwRiwgMHgxMjQ0MTA1RCwgMHgxMjQ1MTA1QiwgMHgxMjQ2MTExMCwgMHgxMjQ3MTExMSwgMHgxMjQ4MTExMiwgCisgICAgICAgIDB4MTI0OTExMTMsIDB4MTI0QTExMTQsIDB4MTI0QjExMTUsIDB4MTI0QzExMTYsIDB4MTI0RDExMTcsIDB4MTI0RTEwOTQsIDB4MTI1QjE5MTgsIDB4MTI2ODE5MTksIAorICAgICAgICAweDEyNzUxOEMzLCAweDEyNzYwMTFBLCAweDEyNzcwMTFCLCAweDEyNzgwMTFDLCAweDEyNzkwMTFELCAweDEyN0EwMTFFLCAweDEyN0IwMEM0LCAweDEyN0MwMEM1LCAKKyAgICAgICAgMHgxMjdEMDBDNiwgMHgxMjdFMDBDNywgMHgxMjdGMDExRiwgMHgxMjgwMDA1NCwgMHgxMkZDMDAxOSwgMHgxMzAwMDA1NCwgMHgxMzRGMDA3OCwgMHgxMzUwMDA1NCwgCisgICAgICAgIDB4MTM1NjAwOTQsIDB4MTM1NzAwNTQsIDB4MTM1OTAwNzgsIDB4MTM4MTAwNTQsIDB4MTM4NTAwNzgsIDB4MTM4NjAwNTQsIDB4MTM5NDAwNzgsIDB4MTM5NTAwNTQsIAorICAgICAgICAweDEzQTYwMDc4LCAweDEzQTgwMDU0LCAweDEzQUEwMDc4LCAweDEzQUIwMDU0LCAweDEzQjAwMDc4LCAweDEzQjEwMDU0LCAweDEzQjQwMDA5LCAweDEzQkIwMTA2LCAKKyAgICAgICAgMHgxM0JDMDEwNywgMHgxM0JEMDEwOCwgMHgxM0JFMDEwOSwgMHgxM0JGMDEwQSwgMHgxM0MwMDEwNiwgMHgxM0MxMDEwNywgMHgxM0MyMDEwOCwgMHgxM0MzMDEwOSwgCisgICAgICAgIDB4MTNDNDAxMEEsIDB4MTNDNTAxMDYsIDB4MTNDNjAxMDcsIDB4MTNDNzAxMDgsIDB4MTNDODAxMDksIDB4MTNDOTAxMEEsIDB4MTNDQTAwNTQsIDB4MTNDQjAwNzgsIAorICAgICAgICAweDEzQ0MwMDU0LCAweDEzRDgwMDc4LCAweDEzRDkwMDU0LCAweDEzRTAwMEU4LCAweDEzRTEwMDE5LCAweDEzRTIwMEZFLCAweDEzRTMwMDBBLCAweDEzRTQwMDc4LCAKKyAgICAgICAgMHgxM0U4MDAxOSwgMHgxM0VBMDBFOCwgMHgxM0VCMDBGRSwgMHgxM0VDMDAxOSwgMHgxM0VFMDBFOCwgMHgxM0VGMDBGRSwgMHgxM0YwMDAxOSwgMHgxM0YxMDBGRCwgCisgICAgICAgIDB4MTNGMzAwMDksIDB4MTNGNjAwNzgsIDB4MTNGODAwMTksIDB4MTQwMDAwOTQsIDB4MTQ4MDAwMTksIDB4MTRDMjAwMEEsIDB4MTRDNzAxMjAsIDB4MTRDODAxMjEsIAorICAgICAgICAweDE0QzkwMDBBLCAweDE0Q0QwMDE5LCAweDE0Q0UwMEU4LCAweDE0RDgwMDE5LCAweDE0REMwMTIyLCAweDE0REQwMDE5LCAweDE0RTAwMEZELCAweDE0RTEwMEU4LCAKKyAgICAgICAgMHgxNEUyMDBGRCwgMHgxNEUzMDAxOSwgMHgxNEU3MDBFOCwgMHgxNEU4MDBGRSwgMHgxNEVBMDBGRCwgMHgxNEVCMDAxOSwgMHgxNEVDMDAwOSwgMHgxNEVFMDBFOCwgCisgICAgICAgIDB4MTRFRjAwMTksIDB4MTRGMjAwRTgsIDB4MTRGMzAwMTksIDB4MTRGNDAwRTgsIDB4MTRGNTAwMTksIDB4MTRGQTAwRTgsIDB4MTRGQzAwRkQsIDB4MTRGRDAwMTksIAorICAgICAgICAweDE0RkUwMDA5LCAweDE0RkYwMDE5LCAweDE1MDUwMEU4LCAweDE1MDYxMEU4LCAweDE1MDcwMEU4LCAweDE1MTEwMDE5LCAweDE1MTIwMEU4LCAweDE1MTQwMDE5LCAKKyAgICAgICAgMHgxNTE2MDBGRSwgMHgxNTE4MDAxOSwgMHgxNTFBMDBGRCwgMHgxNTFCMDAxOSwgMHgxNTFFMDBGRCwgMHgxNTFGMDBFOCwgMHgxNTIwMDAxOSwgMHgxNTJDMDBFOCwgCisgICAgICAgIDB4MTUyRDAwMTksIDB4MTUzMjAwRkQsIDB4MTUzMzAwMTksIDB4MTUzNTAwRTgsIDB4MTUzNzAwMTksIDB4MTUzODAwRTgsIDB4MTUzOTAwMTksIDB4MTUzQTEwRTgsIAorICAgICAgICAweDE1M0IxMDE5LCAweDE1M0MwMDE5LCAweDE1M0QwMEZFLCAweDE1M0UwMEU4LCAweDE1M0YwMEZFLCAweDE1NDMwMEU4LCAweDE1NDYwMEZFLCAweDE1NDcwMEU4LCAKKyAgICAgICAgMHgxNTQ5MDBGRSwgMHgxNTRGMDBFOCwgMHgxNTUxMDBGRSwgMHgxNTUyMDAxOSwgMHgxNTUzMDBGRCwgMHgxNTU3MDAxOSwgMHgxNTU4MDBGRSwgMHgxNTU5MDBFOCwgCisgICAgICAgIDB4MTU1QTAwRkUsIDB4MTU1QjAwRTgsIDB4MTU1RTAwRkUsIDB4MTU2NDAwRTgsIDB4MTU2NzAwRkUsIDB4MTU2QzAwMTksIDB4MTU2RTA4RTgsIDB4MTU2RjAxMjMsIAorICAgICAgICAweDE1NzAwMDE5LCAweDE1NzEwMEU4LCAweDE1NzIwMTI0LCAweDE1NzMwMEU4LCAweDE1NzQwMDE5LCAweDE1NzYwMEZELCAweDE1NzcwMEU4LCAweDE1NzgwMDE5LCAKKyAgICAgICAgMHgxNTdDMDBGRSwgMHgxNTdFMDAxOSwgMHgxNTgwMDA1NCwgMHgxNThBMDA3OCwgMHgxNjAwMDA5NiwgMHgxNjE4MDA5OCwgMHgxNjMwMDA3OCwgMHgxNjQwMDA2MywgCisgICAgICAgIDB4MTY3MjAwNTUsIDB4MTY3MzAwNTQsIDB4MTY3NjAwNzgsIDB4MTY3RDAwMDYsIDB4MTY4MDAxMjUsIDB4MTY5MzAwNzgsIDB4MTY5ODAwNzEsIDB4MTZCMzAwNzgsIAorICAgICAgICAweDE2QzAwMDcxLCAweDE2Q0MwMDc4LCAweDE2RDAwMDcxLCAweDE2RjAwMDc4LCAweDE3MDAwMDA2LCAweDE3MDEwMTI2LCAweDE3MDMwMDA2LCAweDE3MDUwMEUwLCAKKyAgICAgICAgMHgxNzA2MDEyNiwgMHgxNzA3MDAwNiwgMHgxNzBDMDA3OCwgMHgxNzBFMDEyNiwgMHgxNzBGMDA3OCwgMHgxNzQwMDA1NCwgMHgxNzREMDA3OCwgMHgxNzRFMDA1NCwgCisgICAgICAgIDB4MTc3QTAwNzgsIDB4MTc4MDEwNTQsIDB4MTdFQjAwNzgsIDB4MTdGODAwNTQsIDB4MTdGRTAwNzgsIDB4MTgwMDg4MDUsIDB4MTgwMTAwMDYsIDB4MTgwMjAwNTQsIAorICAgICAgICAweDE4MDMwMDcxLCAweDE4MDQwMDA5LCAweDE4MDkwMDU0LCAweDE4MEEwMDA5LCAweDE4MEUwMDk5LCAweDE4MEYwMEJGLCAweDE4MTAwMDU0LCAweDE4MTEwMTI3LCAKKyAgICAgICAgMHgxODEyMDEyOCwgMHgxODEzMDEyOSwgMHgxODE0MDEyQSwgMHgxODE1MDA4MywgMHgxODE4MDA5OSwgMHgxODE5MDA4MSwgMHgxODFCMTA1NCwgMHgxODFDMTEyQiwgCisgICAgICAgIDB4MTgxRDExMkMsIDB4MTgxRTAwNzEsIDB4MTgxRjAwNTQsIDB4MTgyMDAwNzgsIDB4MTgyMTAwNzEsIDB4MTgyNjA4NzEsIDB4MTgzMjAwNzEsIDB4MTgzODA4NzEsIAorICAgICAgICAweDE4MzkwMDcxLCAweDE4M0EwODcxLCAweDE4M0MwMDcxLCAweDE4M0QwODcxLCAweDE4M0YwMDcxLCAweDE4NEEwODcxLCAweDE4NEIwMDcxLCAweDE4NEMwMDc4LCAKKyAgICAgICAgMHgxODREMDA4MywgMHgxODRFMTAzNywgMHgxODRGMDg4MSwgMHgxODUwMDA5OSwgMHgxODUxMDA3MSwgMHgxODU2MDg3MSwgMHgxODYyMDA3MSwgMHgxODY4MDg3MSwgCisgICAgICAgIDB4MTg2OTAwNzEsIDB4MTg2QTA4NzEsIDB4MTg2QzAwNzEsIDB4MTg2RDA4NzEsIDB4MTg2RjAwNzEsIDB4MTg3QTA4NzEsIDB4MTg3QjAwNzEsIDB4MTg3QzA4NzEsIAorICAgICAgICAweDE4N0UwMDgxLCAweDE4N0YwODgxLCAweDE4ODAwMDc4LCAweDE4ODMwMDcxLCAweDE4OTcwMDc4LCAweDE4OTkxMDcxLCAweDE4QzgwMDk0LCAweDE4Qzk3OEFELCAKKyAgICAgICAgMHgxOENBNzhBRSwgMHgxOENCNzg5NCwgMHgxOEQwMDA3MSwgMHgxOERDMDA3OCwgMHgxOEUwMDA1NCwgMHgxOEU4MDA3OCwgMHgxOEY4MDA3MSwgMHgxOTAwMTA5NCwgCisgICAgICAgIDB4MTkwRjEwNTQsIDB4MTkxMDEwQUQsIDB4MTkxMTEwQUUsIDB4MTkxMjExMkQsIDB4MTkxMzExMkUsIDB4MTkxNDExMkYsIDB4MTkxNTEwOTQsIDB4MTkyMjAwNzgsIAorICAgICAgICAweDE5Mjg2ODU0LCAweDE5MjkxOTMwLCAweDE5MkExOTMxLCAweDE5MkIxOTMyLCAweDE5MkMxOTMzLCAweDE5MkQxOTM0LCAweDE5MkUxOTM1LCAweDE5MkYxOTM2LCAKKyAgICAgICAgMHgxOTMwMTg5NCwgMHgxOTNFMTg1NCwgMHgxOTQwMThBRCwgMHgxOTQxMThBRSwgMHgxOTQyMTkyRCwgMHgxOTQzMTkyRSwgMHgxOTQ0MTkyRiwgMHgxOTQ1MTg5NCwgCisgICAgICAgIDB4MTk1OTE5MzcsIDB4MTk1QTE5MzgsIDB4MTk1QjE5MzksIDB4MTk1QzE5M0EsIDB4MTk1RDE5M0IsIDB4MTk1RTE5M0MsIDB4MTk1RjE5M0QsIDB4MTk2MDEwOTQsIAorICAgICAgICAweDE5NjY2ODU0LCAweDE5NjgxODk0LCAweDE5ODA2ODk0LCAweDE5QUMxMDk0LCAweDE5Qjk2ODk0LCAweDE5QkM2ODU0LCAweDE5QkU2ODk0LCAweDE5RUY2ODU0LCAKKyAgICAgICAgMHgxOUYwMTA5NCwgMHgxQTAwMDA3MSwgMHgyNkRCMDA3OCwgMHgyNkUwMDA1NCwgMHgyNzAwMDA3MSwgMHg0RkRFMDA3OCwgMHg1MDAwMDA3MSwgMHg1MjQ3MDA3OCwgCisgICAgICAgIDB4NTI0ODAwNTQsIDB4NTI2NDAwNzgsIDB4NTM4MDAwMzcsIDB4NTM4QzAwNzgsIDB4NTQwMDAwNzEsIDB4NTQwMTAwQzgsIDB4NTQwMjAwNzEsIDB4NTQwMzAwODMsIAorICAgICAgICAweDU0MDQwMDcxLCAweDU0MTIwMEE3LCAweDU0MTMwMDgzLCAweDU0MTQwMDU0LCAweDU0MTYwMDc4LCAweDU2MDAwMDcxLCAweDZCRDIwMDc4LCAweDZDMDAwMTNFLCAKKyAgICAgICAgMHg3MDAwMDEzRiwgMHg3QzgwMDg3MSwgMHg3RDA3MDA3MSwgMHg3RDA4MDg3MSwgMHg3RDBBMDA3MSwgMHg3RDBCMDg3MSwgMHg3RDEyMDA3MSwgMHg3RDEzMDg3MSwgCisgICAgICAgIDB4N0QxNDAwNzEsIDB4N0QxNTA4NzEsIDB4N0QxNzAwNzgsIDB4N0QxODA4NzEsIDB4N0QzNjAwNzgsIDB4N0QzODA4NzEsIDB4N0Q2RDAwNzgsIDB4N0Q4MDEwNTUsIAorICAgICAgICAweDdEODQwMDc4LCAweDdEOEExMDU1LCAweDdEOEMwMDc4LCAweDdEOEYwMDgzLCAweDdEOTAyODlCLCAweDdEOTUwODlCLCAweDdEQTEwMDc4LCAweDdEQTIwODlCLCAKKyAgICAgICAgMHg3REE4NDA5RSwgMHg3REFBMzg5RSwgMHg3REFCNDA5RSwgMHg3REFDMzg5RSwgMHg3REFENDA5RSwgMHg3REFFMzg5RSwgMHg3REFGNDA5RSwgMHg3REIwMzg5RSwgCisgICAgICAgIDB4N0RCMTQwOUUsIDB4N0RCMjM4OUUsIDB4N0RCMzQwOUUsIDB4N0RCNDM4OUUsIDB4N0RCNTQwOUUsIDB4N0RCNjM4OUUsIDB4N0RCNzQwOUUsIDB4N0RCODM4OUUsIAorICAgICAgICAweDdEQjk0MDlFLCAweDdEQkEzODlFLCAweDdEQkI0MDlFLCAweDdEQkMzODlFLCAweDdEQkQ0MDlFLCAweDdEQkUzODlFLCAweDdEQkY0MDlFLCAweDdEQzAzODlFLCAKKyAgICAgICAgMHg3REMxNDA5RSwgMHg3REM4Mzg5RSwgMHg3REM5NDA5RSwgMHg3RENBMzg5RSwgMHg3RENCNDA5RSwgMHg3RENDMzg5RSwgMHg3RENENDA5RSwgMHg3RENFMzg5RSwgCisgICAgICAgIDB4N0RDRjQwOUUsIDB4N0REMTM4OUUsIDB4N0REMjQwOUUsIDB4N0RENDM4OUUsIDB4N0RENTQwOUUsIDB4N0RENjM4OUUsIDB4N0RENzQwOUUsIDB4N0REOTAwNzgsIAorICAgICAgICAweDdERUEyMDlFLCAweDdERUI0ODlFLCAweDdERUMyMDlFLCAweDdERUY0MDlFLCAweDdERjMzODlFLCAweDdERjU0MDlFLCAweDdERkMzODlFLCAweDdERkQyMDlFLCAKKyAgICAgICAgMHg3REZFNDA5RSwgMHg3REZGMzg5RSwgMHg3RTAwNDA5RSwgMHg3RTMyMjA5RSwgMHg3RTRDMzg5RSwgMHg3RTcwNDg5RSwgMHg3RTdCNDA5RSwgMHg3RTg5MjA5RSwgCisgICAgICAgIDB4N0U5NzM4OUUsIDB4N0U5QTQ4OUUsIDB4N0U5RTIwOUUsIDB4N0U5RjAwQjQsIDB4N0VBMDAwNzgsIDB4N0VBODM4OUUsIDB4N0VBQzIwOUUsIDB4N0VBRTM4OUUsIAorICAgICAgICAweDdFQUYyMDlFLCAweDdFQjAzODlFLCAweDdFQjEyMDlFLCAweDdFQjQzODlFLCAweDdFQjUyMDlFLCAweDdFQjgzODlFLCAweDdFQkEyMDlFLCAweDdFQzMzODlFLCAKKyAgICAgICAgMHg3RUM4MDA3OCwgMHg3RUM5Mzg5RSwgMHg3RUNCMjA5RSwgMHg3RUNDMzg5RSwgMHg3RUNEMjA5RSwgMHg3RURBMzg5RSwgMHg3RURCMjA5RSwgMHg3RURDMzg5RSwgCisgICAgICAgIDB4N0VERTIwOUUsIDB4N0VFMjM4OUUsIDB4N0VFMzIwOUUsIDB4N0VFNDAwNzgsIDB4N0VGODQwOUUsIDB4N0VGRTQxNDAsIDB4N0VGRjAwNzgsIDB4N0YwMDAwODMsIAorICAgICAgICAweDdGMDg4MDA2LCAweDdGMEM4MEJGLCAweDdGMEQwMDc4LCAweDdGMTAwMDgzLCAweDdGMTIwMDc4LCAweDdGMTg4MDA2LCAweDdGMTk4MDk5LCAweDdGMUE4MDM4LCAKKyAgICAgICAgMHg3RjFCODBCRiwgMHg3RjIzMDAwNiwgMHg3RjI0ODBCRiwgMHg3RjI1MTAwNiwgMHg3RjI3MTAzOCwgMHg3RjI4NjAwQywgMHg3RjJBNjAwNiwgMHg3RjJDNjA5OSwgCisgICAgICAgIDB4N0YyRDYwQkYsIDB4N0YzMDYwMDYsIDB4N0YzMTYwMEIsIDB4N0YzMjYwMTksIDB4N0YzNDYwMDYsIDB4N0YzNTYwMDcsIDB4N0YzNjAwNzgsIDB4N0YzODQwOUUsIAorICAgICAgICAweDdGNDEyMDlFLCAweDdGNDY0ODlFLCAweDdGNDcyMDlFLCAweDdGNDk0ODlFLCAweDdGNEEyMDlFLCAweDdGNEM0ODlFLCAweDdGNEQyMDlFLCAweDdGNEU0ODlFLCAKKyAgICAgICAgMHg3RjRGMjA5RSwgMHg3RjUwNDg5RSwgMHg3RjUxMjA5RSwgMHg3RjUyNDg5RSwgMHg3RjUzMjA5RSwgMHg3RjU0NDg5RSwgMHg3RjU1MjA5RSwgMHg3RjVBNDg5RSwgCisgICAgICAgIDB4N0Y1QjIwOUUsIDB4N0Y1QzQ4OUUsIDB4N0Y1RDIwOUUsIDB4N0Y1RTQ4OUUsIDB4N0Y1RjIwOUUsIDB4N0Y2MDQ4OUUsIDB4N0Y2MTIwOUUsIDB4N0Y2MjQ4OUUsIAorICAgICAgICAweDdGNjMyMDlFLCAweDdGNjQ0ODlFLCAweDdGNjUyMDlFLCAweDdGNjY0ODlFLCAweDdGNjcyMDlFLCAweDdGNjg0ODlFLCAweDdGNjkyMDlFLCAweDdGNkE0ODlFLCAKKyAgICAgICAgMHg3RjZCMjA5RSwgMHg3RjZDNDg5RSwgMHg3RjZEMjA5RSwgMHg3RjZFNDg5RSwgMHg3RjZGMjA5RSwgMHg3RjcwNDg5RSwgMHg3RjcxMjA5RSwgMHg3RjcyNDg5RSwgCisgICAgICAgIDB4N0Y3MzIwOUUsIDB4N0Y3NDQ4OUUsIDB4N0Y3NTIwOUUsIDB4N0Y3NjQ4OUUsIDB4N0Y3NzIwOUUsIDB4N0Y3QTQ4OUUsIDB4N0Y3QjIwOUUsIDB4N0Y3RjAwNzgsIAorICAgICAgICAweDdGODE4ODA2LCAweDdGODI4ODA4LCAweDdGODM4ODA2LCAweDdGODQ4ODA5LCAweDdGODU4ODA2LCAweDdGODY4ODBDLCAweDdGODg4ODBFLCAweDdGODk4ODEwLCAKKyAgICAgICAgMHg3RjhBODgxMiwgMHg3RjhCODgxNCwgMHg3RjhDODgxNiwgMHg3RjhEODgwQywgMHg3RjhFODgxOCwgMHg3RjhGODgxQSwgMHg3RjkwODgwNiwgMHg3RjkxODg2MCwgCisgICAgICAgIDB4N0Y5RTg4MDYsIDB4N0Y5Rjg4MzcsIDB4N0ZBMTg4NjEsIDB4N0ZBRTg4MTksIDB4N0ZCMDg4MEEsIDB4N0ZCMTUwMDksIDB4N0ZCMjUwMDYsIDB4N0ZCMzUwNzEsIAorICAgICAgICAweDdGQjg1MDgxLCAweDdGQjk1MDcxLCAweDdGQ0Y1MDgxLCAweDdGRDA1MDcxLCAweDdGRTAwMDc4LCAweDdGRTE1MDcxLCAweDdGRTQwMDc4LCAweDdGRTU1MDcxLCAKKyAgICAgICAgMHg3RkU4MDA3OCwgMHg3RkU5NTA3MSwgMHg3RkVDMDA3OCwgMHg3RkVENTA3MSwgMHg3RkVGMDA3OCwgMHg3RkYwODgwOCwgMHg3RkYxODgxOSwgMHg3RkYyODg1NCwgCisgICAgICAgIDB4N0ZGMzg4MDgsIDB4N0ZGNDUwNTQsIDB4N0ZGNTUwMTksIDB4N0ZGNzUwNTQsIDB4N0ZGODAwNzgsIDB4N0ZGRDAxNDEsIDB4N0ZGRTAwNTQsIDB4N0ZGRjAwNzgsIAorICAgICAgICAweDgwMDAwMDcxLCAweDgwMDYwMDc4LCAweDgwMDcwMDcxLCAweDgwMUYwMDc4LCAweDgwMjAwMDcxLCAweDgwMjcwMDc4LCAweDgwMjgwMDcxLCAweDgwMkYwMDc4LCAKKyAgICAgICAgMHg4MDQwMDA3MSwgMHg4MDdFMDA3OCwgMHg4MDgwMDA5NywgMHg4MDgxMDA5NCwgMHg4MDgyMDA3OCwgMHg4MDg0MDBCNiwgMHg4MDg1MDBCNywgMHg4MDg2MDBCOCwgCisgICAgICAgIDB4ODA4NzAwQjksIDB4ODA4ODAwQjAsIDB4ODA4OTAwQkEsIDB4ODA4QTAwQkIsIDB4ODA4QjAwQkMsIDB4ODA4QzAwQkQsIDB4ODA4RDAxNDIsIDB4ODA4RTAxNDMsIAorICAgICAgICAweDgwOEYwMTQ0LCAweDgwOTAwMTQ1LCAweDgwOTEwMEIxLCAweDgwOTIwMTQ2LCAweDgwOTMwMTQ3LCAweDgwOTQwMTQ4LCAweDgwOTUwMTQ5LCAweDgwOTYwMTRBLCAKKyAgICAgICAgMHg4MDk3MDE0QiwgMHg4MDk4MDE0QywgMHg4MDk5MDE0RCwgMHg4MDlBMDA3OCwgMHg4MDlDMDA5NCwgMHg4MEEwMDE0RSwgMHg4MEExMDE0RiwgMHg4MEEyMDE1MCwgCisgICAgICAgIDB4ODBBMzAxNTEsIDB4ODBBNDAxNTIsIDB4ODBBNTAxNTAsIDB4ODBBNjAxNTMsIDB4ODBBNzAxNTEsIDB4ODBBODAxNTQsIDB4ODBBOTAxNTUsIDB4ODBBQTAxNTYsIAorICAgICAgICAweDgwQUIwMTU3LCAweDgwQUMwMTRGLCAweDgwQUUwMTU4LCAweDgwQjAwMTU0LCAweDgwQjMwMTUwLCAweDgwQjUwMTU1LCAweDgwQjYwMTUzLCAweDgwQjkwMTUxLCAKKyAgICAgICAgMHg4MEJBMDE1MCwgMHg4MEJCMDA1RiwgMHg4MEJEMDA1NCwgMHg4MEM1MDBDMywgMHg4MEM2MDA3OCwgMHg4MTgwMDA3MSwgMHg4MTkwMDBBRCwgMHg4MTkxMDBCMCwgCisgICAgICAgIDB4ODE5MjAwNzgsIDB4ODE5ODAwNzEsIDB4ODFBNTAxNTksIDB4ODFBNjAwNzgsIDB4ODFDMDAwNzEsIDB4ODFDRjAwNzgsIDB4ODFEMDAwNzEsIDB4ODFFMjAwNzgsIAorICAgICAgICAweDgxRTQwMDcxLCAweDgxRTgwMDk0LCAweDgxRTkwMTU4LCAweDgxRUEwMTVBLCAweDgxRUIwMDc4LCAweDgyMDAwMTVCLCAweDgyMTQwMTVDLCAweDgyMjgwMDcxLCAKKyAgICAgICAgMHg4MjRGMDA3OCwgMHg4MjUwMDBBOCwgMHg4MjUxMDBBOSwgMHg4MjUyMDBBQSwgMHg4MjUzMDBBQiwgMHg4MjU0MDBBQywgMHg4MjU1MDA3OCwgMHg4NDAwMDA5QiwgCisgICAgICAgIDB4ODQwMzAwNzgsIDB4ODQwNDAwOUIsIDB4ODQxQjAwNzgsIDB4ODQxQzAwOUIsIDB4ODQxRDAwNzgsIDB4ODQxRTAwOUIsIDB4ODQxRjAwNzgsIDB4ODUwMDAwOUIsIAorICAgICAgICAweDg1MDEwMDgzLCAweDg1MDIwMDc4LCAweDg1MDMwMDgzLCAweDg1MDQwMDc4LCAweDg1MDYwMDgzLCAweDg1MDgwMDlCLCAweDg1MEEwMDc4LCAweDg1MEIwMDlCLCAKKyAgICAgICAgMHg4NTBDMDA3OCwgMHg4NTBEMDA5QiwgMHg4NTFBMDA3OCwgMHg4NTFDMDA4MywgMHg4NTFFMDA3OCwgMHg4NTIwMDE1RCwgMHg4NTIxMDE1RSwgMHg4NTIyMDE1RiwgCisgICAgICAgIDB4ODUyMzAxNjAsIDB4ODUyNDAwNzgsIDB4ODUyODAwOUEsIDB4ODUyRDAwNzgsIDB4RTgwMDAwOTQsIDB4RTg3QjAwNzgsIDB4RTg4MDAwOTQsIDB4RTg5NDAwNzgsIAorICAgICAgICAweEU4OTUwMDk0LCAweEU4QUYwODk0LCAweEU4QjMwMEE3LCAweEU4QjQwMDgzLCAweEU4QjUwMDk0LCAweEU4QjcwMEE3LCAweEU4QkEwMDU3LCAweEU4QkUwMDgzLCAKKyAgICAgICAgMHhFOEMyMDA5NCwgMHhFOEMzMDA4MywgMHhFOEM2MDA5NCwgMHhFOEQ1MDA4MywgMHhFOEQ3MDA5NCwgMHhFOERFMDg5NCwgMHhFOEUxMDA5NCwgMHhFOEVGMDA3OCwgCisgICAgICAgIDB4RTkwMDAwNTQsIDB4RTkyMTAwODMsIDB4RTkyMzAwNzgsIDB4RTk4MDAwNTQsIDB4RTlBQzAwNzgsIDB4RUEwMDI4NzcsIDB4RUEwRDI4NTUsIDB4RUExQTI4NzcsIAorICAgICAgICAweEVBMjcyODU1LCAweEVBMzQyODc3LCAweEVBNDEyODU1LCAweEVBNEUyODc3LCAweEVBNTAwMDc4LCAweEVBNTEyODc3LCAweEVBNTIwMDc4LCAweEVBNTMyODc3LCAKKyAgICAgICAgMHhFQTU0MDA3OCwgMHhFQTU1Mjg3NywgMHhFQTVCMjg1NSwgMHhFQTVEMDA3OCwgMHhFQTVGMjg1NSwgMHhFQTYyMDA3OCwgMHhFQTYzMjg1NSwgMHhFQTY4Mjg3NywgCisgICAgICAgIDB4RUE3NTI4NTUsIDB4RUE4MjI4NzcsIDB4RUE4MzAwNzgsIDB4RUE4NDI4NzcsIDB4RUE4NjAwNzgsIDB4RUE4NzI4NzcsIDB4RUE4RjI4NTUsIDB4RUE5QzI4NzcsIAorICAgICAgICAweEVBOUQwMDc4LCAweEVBOUUyODc3LCAweEVBQTQwMDc4LCAweEVBQTUyODc3LCAweEVBQTkyODU1LCAweEVBQjYyODc3LCAweEVBQzMyODU1LCAweEVBRDAyODc3LCAKKyAgICAgICAgMHhFQUREMjg1NSwgMHhFQUVBMjg3NywgMHhFQUY3Mjg1NSwgMHhFQjA0Mjg3NywgMHhFQjExMjg1NSwgMHhFQjFFMjg3NywgMHhFQjJCMjg1NSwgMHhFQjM4Mjg3NywgCisgICAgICAgIDB4RUI0NTI4NTUsIDB4RUI1MzAwNzgsIDB4RUI1NDI4NzcsIDB4RUI2MTI4NTUsIDB4RUI3MTI4NzcsIDB4RUI3RTI4NTUsIDB4RUI4RTI4NzcsIDB4RUI5QjI4NTUsIAorICAgICAgICAweEVCQUIyODc3LCAweEVCQjgyODU1LCAweEVCQzgyODc3LCAweEVCRDUyODU1LCAweEVCRTUwMDc4LCAweEVCRTcyODBFLCAweEVCRTgyODEwLCAweEVCRTkyODEyLCAKKyAgICAgICAgMHhFQkVBMjgxNCwgMHhFQkVCMjgxNiwgMHhFQkVDMjgwRSwgMHhFQkVEMjgxMCwgMHhFQkVFMjgxMiwgMHhFQkVGMjgxNCwgMHhFQkYwMjgxNiwgMHhFQkYxMjgwRSwgCisgICAgICAgIDB4RUJGMjI4MTAsIDB4RUJGMzI4MTIsIDB4RUJGNDI4MTQsIDB4RUJGNTI4MTYsIDB4RUJGNjI4MEUsIDB4RUJGNzI4MTAsIDB4RUJGODI4MTIsIDB4RUJGOTI4MTQsIAorICAgICAgICAweEVCRkEyODE2LCAweEVCRkIyODBFLCAweEVCRkMyODEwLCAweEVCRkQyODEyLCAweEVCRkUyODE0LCAweEVCRkYyODE2LCAweEVDMDAwMDc4CisgICAgfTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBhMVtdID0geworICAgICAgICAweDAwMDAwMDcxLCAweDUzNkMwMDc4LCAweDdDMDAwODcxLCAweDdEMEYwMDc4CisgICAgfTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBhN1tdID0geworICAgICAgICAweDAwMTAwMDU3LCAweDAwNDAwMDc4LCAweDAwODAwMDgzLCAweDAwRjgwMDc4LCAweDgwMDAwMTNGLCAweEZGRkYwMDc4CisgICAgfTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBhOFtdID0geworICAgICAgICAweDAwMDAwMTNGLCAweDdGRkYwMDc4CisgICAgfTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBhMTZbXSA9IHsKKyAgICAgICAgMHgwMDgwMDg2NSwgMHgwMDg4MDA2NSwgMHgwMDg5MDg2NSwgMHgwMDkzMDA2NSwgMHgwMDk0MDg2NSwgMHgwMDk4MDE2MSwgMHgwMDk5MTA2NSwgMHgwMDlBMDg2NSwgCisgICAgICAgIDB4MDA5QzA4NjMsIDB4MDA5RjEwNjMsIDB4MDBBMDAwNjMsIDB4MDBBMTA4NjMsIDB4MDBBNDEwNTUsIDB4MDBBNTAwNjUsIDB4MDBBNjA4NjUsIDB4MDBBOTAwNjUsIAorICAgICAgICAweDAwQUEwODY1LCAweDAwQjMwMDY1LCAweDAwQjQwODY1LCAweDAwQkMwODYzLCAweDAwQkYxMTYyLCAweDAwQzAwMTYzLCAweDAwQzEwMDY1LCAweDAwQzMwMDYzLCAKKyAgICAgICAgMHgwMEM0MDA2OCwgMHgwMEM1MDA2MywgMHgwMEM2MDA1NSwgMHgwMEM3MDE2NCwgMHgwMEM4MDA2MywgMHgwMEM5MDA2OCwgMHgwMENBMDE2NSwgMHgwMENCMDE2NiwgCisgICAgICAgIDB4MDBDQzAwNjUsIDB4MDBDRDAwNTUsIDB4MDBDRTAxNjcsIDB4MDBDRjAxNjgsIDB4MDBEMDA4NjUsIDB4MDBEMTAwNjUsIDB4MDBEMzAwNjMsIDB4MDBENDAwNkYsIAorICAgICAgICAweDAwRDUwMDU1LCAweDAwRDYwMDY1LCAweDAwRDcwODYzLCAweDAwRDgwMDcwLCAweDAwRDkwMDYzLCAweDAwREIwMTY5LCAweDAwREMwMDY1LCAweDAwREQwMDcxLCAKKyAgICAgICAgMHgwMERFMDA2NSwgMHgwMERGMDE2QSwgMHgwMEUwMDA3MSwgMHgwMEUyMTA3NCwgMHgwMEUzMTA3MiwgMHgwMEU0MTA3MywgMHgwMEU1MTA3NCwgMHgwMEU2MDg2MywgCisgICAgICAgIDB4MDBFRTAxNkIsIDB4MDBFRjA4NjUsIDB4MDBGMjAwNjUsIDB4MDBGMzA4NjUsIDB4MDBGODEwNzIsIDB4MDBGOTEwNzMsIDB4MDBGQTA4NjUsIDB4MDBGQjAxNkMsIAorICAgICAgICAweDAwRkMwODY1LCAweDAxMEUwMDY1LCAweDAxMEYwODY1LCAweDAxMTAwMDU1LCAweDAxMTEwMDY1LCAweDAxMTMwODY1LCAweDAxMUEwMDU1LCAweDAxMUQwMDYzLCAKKyAgICAgICAgMHgwMTFFMDE2RCwgMHgwMTFGMDA1NSwgMHgwMTIwMDE2RSwgMHgwMTIxMDA3OCwgMHgwMTI4MDA1NSwgMHgwMTI5MDE2RiwgMHgwMTJBMDA1NSwgMHgwMTJCMDA3QSwgCisgICAgICAgIDB4MDEyQzAxNzAsIDB4MDEyRDAxNzEsIDB4MDEyRTAwNTUsIDB4MDEzMTAxNzIsIDB4MDEzMjAwNTUsIDB4MDEzNDAxNzMsIDB4MDEzNTAwNTUsIDB4MDEzNzAxNzMsIAorICAgICAgICAweDAxMzgwMDU1LCAweDAxM0EwMTc0LCAweDAxM0IwMDU1LCAweDAxNDEwMDdELCAweDAxNDIwMDU1LCAweDAxNDUwMDdFLCAweDAxNDYwMDU1LCAweDAxNTg3ODgxLCAKKyAgICAgICAgMHgwMTVDMDA4MiwgMHgwMTVEMDA4MSwgMHgwMTYxMDAzNywgMHgwMTYzMDA4MiwgMHgwMTY4MDA4MSwgMHgwMTY5MDAzNywgMHgwMTZDMTAzNywgMHgwMTZGMDAzNywgCisgICAgICAgIDB4MDE3MDc4ODEsIDB4MDE3MjAwMzcsIDB4MDE4MDAwODMsIDB4MDFBMDA4ODMsIDB4MDFBMjAxNzUsIDB4MDFBMzAwODMsIDB4MDFCODAwNzgsIDB4MDFCQTAwMzcsIAorICAgICAgICAweDAxQkIwMDc4LCAweDAxQzIwODM3LCAweDAxQzMwODA2LCAweDAxQzQwODg1LCAweDAxQzUwMDc4LCAweDAxQzcwODg3LCAweDAxQzgwMDYwLCAweDAxRDUwODYwLCAKKyAgICAgICAgMHgwMUQ2MDg4OSwgMHgwMUQ4MDA2MSwgMHgwMUU1MDg2MSwgMHgwMUU2MDg4QywgMHgwMUU3MDA3OCwgMHgwMUU4MTE3NiwgMHgwMUU5MDg3NywgMHgwMUVBMTE3NywgCisgICAgICAgIDB4MDFFQjAwNTUsIDB4MDFFQzAwNjUsIDB4MDFGODEwOTMsIDB4MDFGOTAwNTUsIDB4MDFGQTExNzgsIDB4MDFGQjAwNjMsIDB4MDFGQzEwRDgsIDB4MDFGRDAwNjUsIAorICAgICAgICAweDAxRkUwMDc3LCAweDAyMDAwODkyLCAweDAyMDIwMDkyLCAweDAyMDMwODkyLCAweDAyMDQwMDkyLCAweDAyMDYwODkyLCAweDAyMDcwMDkyLCAweDAyMDgwMDYwLCAKKyAgICAgICAgMHgwMjBDMDg2MCwgMHgwMjBEMDA2MCwgMHgwMjE4MDA2MSwgMHgwMjFDMDg2MSwgMHgwMjFEMDA2MSwgMHgwMjI4MDg5MywgMHgwMjJBMDA5MywgMHgwMjJCMDg5MywgCisgICAgICAgIDB4MDIyQzAwOTMsIDB4MDIyRTA4OTMsIDB4MDIyRjAwOTMsIDB4MDIzMDAwNjUsIDB4MDIzQjA4NjUsIDB4MDIzQzAwNjUsIDB4MDI0MTAwODMsIDB4MDI0MzAwNzgsIAorICAgICAgICAweDAyNDQwMDk1LCAweDAyNDUwMDY1LCAweDAyNjAwODYzLCAweDAyNjEwMDYzLCAweDAyNjcwMDc4LCAweDAyNjgwODY1LCAweDAyNkEwMDY1LCAweDAyNkIwODY1LCAKKyAgICAgICAgMHgwMjZDMDA2NSwgMHgwMjZEMDg2NSwgMHgwMjcwMDA2NSwgMHgwMjcxMDg2NSwgMHgwMjc0MDA2NSwgMHgwMjc1MDg2NSwgMHgwMjdCMDA2NSwgMHgwMjdDMDg2NSwgCisgICAgICAgIDB4MDI3RDAwNzgsIDB4MDI4MDAwNjUsIDB4MDI4ODAwNzgsIDB4MDI5ODAwOTYsIDB4MDJBQjAwNzgsIDB4MDJBQzAwODEsIDB4MDJBRDAwOTcsIDB4MDJCMDAwOTgsIAorICAgICAgICAweDAyQzMxMDU1LCAweDAyQzQwMDk3LCAweDAyQzUwMDc4LCAweDAyQzgwMDgzLCAweDAyRTEwMDlBLCAweDAyRTIwMDgzLCAweDAyRTQwMDc4LCAweDAyRTgwMDlCLCAKKyAgICAgICAgMHgwMkY1MDA3OCwgMHgwMkY4MDA5QiwgMHgwMkY5MDA5QSwgMHgwMkZBMDA3OCwgMHgwMzAwMDA5QywgMHgwMzAyMDA3OCwgMHgwMzA1MDE0MCwgMHgwMzA2MDA5RCwgCisgICAgICAgIDB4MDMwNzAwNTQsIDB4MDMwODAwODMsIDB4MDMwQjAwNzgsIDB4MDMwRDAwOUQsIDB4MDMwRTAwNzgsIDB4MDMwRjAwOUQsIDB4MDMxMDAwOUUsIDB4MDMxMTA4OUUsIAorICAgICAgICAweDAzMTMwMDlFLCAweDAzMUQwMDc4LCAweDAzMjAwMDlFLCAweDAzMjUwMDgzLCAweDAzMkYwMDc4LCAweDAzMzAwMTc5LCAweDAzMzEwMTdBLCAweDAzMzIwMTdCLCAKKyAgICAgICAgMHgwMzMzMDE3QywgMHgwMzM0MDE3RCwgMHgwMzM1MDBBNSwgMHgwMzM2MDA5RCwgMHgwMzM3MDA5RSwgMHgwMzNBMTA5RSwgMHgwMzNDMDA5RSwgMHgwMzY5MDg5RSwgCisgICAgICAgIDB4MDM2QTAwOUUsIDB4MDM2QjAwODMsIDB4MDM2RTAwOUMsIDB4MDM2RjAwODMsIDB4MDM3MjAwOUYsIDB4MDM3MzAwODMsIDB4MDM3NDAwNTQsIDB4MDM3NTAwODMsIAorICAgICAgICAweDAzNzcwMDlFLCAweDAzNzgwMDBGLCAweDAzNzkwMDExLCAweDAzN0EwMDEzLCAweDAzN0IwMDE1LCAweDAzN0MwMDE3LCAweDAzN0QwMDlFLCAweDAzN0UwMEE2LCAKKyAgICAgICAgMHgwMzdGMDA5RSwgMHgwMzgwMDA5RCwgMHgwMzg3MDA1NywgMHgwMzg4MDA4MywgMHgwMzg5MDA5RSwgMHgwMzk4MDA4MywgMHgwM0E1MDA3OCwgMHgwM0E2MDA5RSwgCisgICAgICAgIDB4MDNCNzAwNzgsIDB4MDNDMDAwOUUsIDB4MDNEMzAwODMsIDB4MDNEODAwOUUsIDB4MDNEOTAwNzgsIDB4MDQ4MDAwODMsIDB4MDQ4MTAwQTcsIDB4MDQ4MjAwNzEsIAorICAgICAgICAweDA0OTQwODcxLCAweDA0OTUwMDcxLCAweDA0OTgwODcxLCAweDA0OTkwMDcxLCAweDA0OUQwMDc4LCAweDA0OUUwMDcxLCAweDA0OUYwMEE3LCAweDA0QTAwMDgzLCAKKyAgICAgICAgMHgwNEE0MDBBNywgMHgwNEE2MDA4MywgMHgwNEE3MDA3OCwgMHgwNEE4MDA4MywgMHgwNEFBMDA3OCwgMHgwNEFDMDg3MSwgMHgwNEIwMDA3MSwgMHgwNEIxMDA4MywgCisgICAgICAgIDB4MDRCMjAwOTcsIDB4MDRCMzAxN0UsIDB4MDRCNDAxN0YsIDB4MDRCNTAxODAsIDB4MDRCNjAxODEsIDB4MDRCNzAxODIsIDB4MDRCODAwNzgsIDB4MDRCRTAwNzEsIAorICAgICAgICAweDA0QkYwMDc4LCAweDA0QzAwMDgzLCAweDA0QzEwMEE3LCAweDA0QzIwMDcxLCAweDA0QzYwMDc4LCAweDA0QzcwMDcxLCAweDA0QzgwMDc4LCAweDA0QzkwMDcxLCAKKyAgICAgICAgMHgwNEQ0MDA3OCwgMHgwNEQ1MDA3MSwgMHgwNEQ4MDA3OCwgMHgwNERCMDA3MSwgMHgwNEREMDA3OCwgMHgwNERFMDA3MSwgMHgwNERGMDBBNywgMHgwNEUwMDA4MywgCisgICAgICAgIDB4MDRFMjAwNzgsIDB4MDRFMzAwQTcsIDB4MDRFNDAwNzgsIDB4MDRFNTA4QTcsIDB4MDRFNjAwODMsIDB4MDRFNzAwNzgsIDB4MDRFQjAwQTcsIDB4MDRFQzAwNzgsIAorICAgICAgICAweDA0RUUwODcxLCAweDA0RjAwMDcxLCAweDA0RjEwMDgzLCAweDA0RjIwMDc4LCAweDA0RjMwMTdFLCAweDA0RjQwMTdGLCAweDA0RjUwMTgwLCAweDA0RjYwMTgxLCAKKyAgICAgICAgMHgwNEY3MDE4MiwgMHgwNEY4MDA3MSwgMHgwNEY5MDAwOCwgMHgwNEZBMDBCNiwgMHgwNEZCMDBCNywgMHgwNEZDMDE4MywgMHgwNEZEMDA3OCwgMHgwNTAwMDA4MywgCisgICAgICAgIDB4MDUwMTAwQTcsIDB4MDUwMjAwNzEsIDB4MDUwNTAwNzgsIDB4MDUwNzAwNzEsIDB4MDUwODAwNzgsIDB4MDUwOTAwNzEsIDB4MDUxNDAwNzgsIDB4MDUxNTAwNzEsIAorICAgICAgICAweDA1MTgwMDc4LCAweDA1MTkwODcxLCAweDA1MUEwMDcxLCAweDA1MUIwMDc4LCAweDA1MUMwMDcxLCAweDA1MUQwMDc4LCAweDA1MUYwMEE3LCAweDA1MjAwMDgzLCAKKyAgICAgICAgMHgwNTIxMDA3OCwgMHgwNTIzMDA4MywgMHgwNTI0MDA3OCwgMHgwNTI1MDA4MywgMHgwNTI3MDA3OCwgMHgwNTJDMDg3MSwgMHgwNTJFMDA3OCwgMHgwNTMzMDE3RSwgCisgICAgICAgIDB4MDUzNDAxN0YsIDB4MDUzNTAxODAsIDB4MDUzNjAxODEsIDB4MDUzNzAxODIsIDB4MDUzODAwODMsIDB4MDUzOTAwNzEsIDB4MDUzQTAwNzgsIDB4MDU0MDAwODMsIAorICAgICAgICAweDA1NDEwMEE3LCAweDA1NDIwMDcxLCAweDA1NTQwMDc4LCAweDA1NTUwMDcxLCAweDA1NTgwMDc4LCAweDA1NTkwMDcxLCAweDA1NUQwMDc4LCAweDA1NUUwMDcxLCAKKyAgICAgICAgMHgwNTVGMDBBNywgMHgwNTYwMDA4MywgMHgwNTY0MDBBNywgMHgwNTY2MDA4MywgMHgwNTY3MDA3OCwgMHgwNTcwMDA3MSwgMHgwNTcxMDA4MywgMHgwNTcyMDA3OCwgCisgICAgICAgIDB4MDU3MzAxN0UsIDB4MDU3NDAxN0YsIDB4MDU3NTAxODAsIDB4MDU3NjAxODEsIDB4MDU3NzAxODIsIDB4MDU3ODAwMDgsIDB4MDU3OTAwNzgsIDB4MDU4MDAwODMsIAorICAgICAgICAweDA1ODEwMEE3LCAweDA1ODIwMDcxLCAweDA1ODYwMDc4LCAweDA1ODcwMDcxLCAweDA1ODgwMDc4LCAweDA1ODkwMDcxLCAweDA1OTQwMDc4LCAweDA1OTUwMDcxLCAKKyAgICAgICAgMHgwNTk4MDA3OCwgMHgwNTk5MDA3MSwgMHgwNTlEMDA3OCwgMHgwNTlFMDA3MSwgMHgwNTlGMDA4MywgMHgwNUEyMDA3OCwgMHgwNUEzMDBBNywgMHgwNUE0MDA3OCwgCisgICAgICAgIDB4MDVBNTA4QTcsIDB4MDVBNjAwODMsIDB4MDVBNzAwNzgsIDB4MDVBQjAwQTcsIDB4MDVBQzAwNzgsIDB4MDVBRTA4NzEsIDB4MDVBRjAwNzEsIDB4MDVCMTAwNzgsIAorICAgICAgICAweDA1QjMwMTdFLCAweDA1QjQwMTdGLCAweDA1QjUwMTgwLCAweDA1QjYwMTgxLCAweDA1QjcwMTgyLCAweDA1QjgwMDcxLCAweDA1QjkwMDc4LCAweDA1QzEwMDcxLCAKKyAgICAgICAgMHgwNUM1MDA3OCwgMHgwNUM3MDA3MSwgMHgwNUM4MDA3OCwgMHgwNUM5MDA3MSwgMHgwNUNCMDA3OCwgMHgwNUNDMDA3MSwgMHgwNUNEMDA3OCwgMHgwNUNGMDA3MSwgCisgICAgICAgIDB4MDVEMDAwNzgsIDB4MDVEMTAwNzEsIDB4MDVEMjAwNzgsIDB4MDVENDAwNzEsIDB4MDVENTAwNzgsIDB4MDVENzAwNzEsIDB4MDVERDAwNzgsIDB4MDVERjAwQTcsIAorICAgICAgICAweDA1RTEwMDc4LCAweDA1RTMwMEE3LCAweDA1RTQwMDc4LCAweDA1RTUwOEE3LCAweDA1RTYwMDgzLCAweDA1RTcwMDc4LCAweDA1RUIwMEE3LCAweDA1RUMwMDc4LCAKKyAgICAgICAgMHgwNUYzMDE3RSwgMHgwNUY0MDE3RiwgMHgwNUY1MDE4MCwgMHgwNUY2MDE4MSwgMHgwNUY3MDE4MiwgMHgwNUY4MDE4NCwgMHgwNUY5MDA1NCwgMHgwNUZDMDAwOCwgCisgICAgICAgIDB4MDVGRDAwNzgsIDB4MDYwMDAwQTcsIDB4MDYwMjAwNzEsIDB4MDYwNjAwNzgsIDB4MDYwNzAwNzEsIDB4MDYwODAwNzgsIDB4MDYwOTAwNzEsIDB4MDYxNDAwNzgsIAorICAgICAgICAweDA2MTUwMDcxLCAweDA2MUQwMDc4LCAweDA2MUYwMDgzLCAweDA2MjAwMEE3LCAweDA2MjIwMDc4LCAweDA2MjMwMDgzLCAweDA2MjQwMDc4LCAweDA2MjUwMDgzLCAKKyAgICAgICAgMHgwNjI3MDA3OCwgMHgwNjJBMDA4MywgMHgwNjJCMDA3OCwgMHgwNjMwMDA3MSwgMHgwNjMxMDA3OCwgMHgwNjMzMDE3RSwgMHgwNjM0MDE3RiwgMHgwNjM1MDE4MCwgCisgICAgICAgIDB4MDYzNjAxODEsIDB4MDYzNzAxODIsIDB4MDYzODAwNzgsIDB4MDY0MTAwQTcsIDB4MDY0MjAwNzEsIDB4MDY0NjAwNzgsIDB4MDY0NzAwNzEsIDB4MDY0ODAwNzgsIAorICAgICAgICAweDA2NDkwMDcxLCAweDA2NTQwMDc4LCAweDA2NTUwMDcxLCAweDA2NUQwMDc4LCAweDA2NUUwMDcxLCAweDA2NUYwMEIyLCAweDA2NjAwMEE3LCAweDA2NjIwMDc4LCAKKyAgICAgICAgMHgwNjYzMDhBNywgMHgwNjY0MDA3OCwgMHgwNjY1MDhBNywgMHgwNjY2MDA4MywgMHgwNjY3MDA3OCwgMHgwNjZBMDBBNywgMHgwNjZCMDA3OCwgMHgwNjcwMDA3MSwgCisgICAgICAgIDB4MDY3MTAwNzgsIDB4MDY3MzAxN0UsIDB4MDY3NDAxN0YsIDB4MDY3NTAxODAsIDB4MDY3NjAxODEsIDB4MDY3NzAxODIsIDB4MDY3ODAwNzgsIDB4MDY4MTAwQTcsIAorICAgICAgICAweDA2ODIwMDcxLCAweDA2ODYwMDc4LCAweDA2ODcwMDcxLCAweDA2ODgwMDc4LCAweDA2ODkwMDcxLCAweDA2OTQwMDc4LCAweDA2OTUwMDcxLCAweDA2OUQwMDc4LCAKKyAgICAgICAgMHgwNjlGMDBBNywgMHgwNkEwMDA4MywgMHgwNkEyMDA3OCwgMHgwNkEzMDBBNywgMHgwNkE0MDA3OCwgMHgwNkE1MDhBNywgMHgwNkE2MDA4MywgMHgwNkE3MDA3OCwgCisgICAgICAgIDB4MDZBQjAwQTcsIDB4MDZBQzAwNzgsIDB4MDZCMDAwNzEsIDB4MDZCMTAwNzgsIDB4MDZCMzAxN0UsIDB4MDZCNDAxN0YsIDB4MDZCNTAxODAsIDB4MDZCNjAxODEsIAorICAgICAgICAweDA2QjcwMTgyLCAweDA2QjgwMDc4LCAweDA2QzEwMEE3LCAweDA2QzIwMDcxLCAweDA2Q0IwMDc4LCAweDA2Q0QwMDcxLCAweDA2REYwMDc4LCAweDA2RTAwMDcxLCAKKyAgICAgICAgMHgwNkUzMDA3OCwgMHgwNkU3MDBBNywgMHgwNkU5MDA4MywgMHgwNkVBMDA3OCwgMHgwNkVDMDBBNywgMHgwNkVFMDhBNywgMHgwNkVGMDBBNywgMHgwNkYwMDA3OCwgCisgICAgICAgIDB4MDZGOTAwQTcsIDB4MDZGQTAwNzgsIDB4MDcwMDAwNzEsIDB4MDcxODAwODMsIDB4MDcxOTEwNzEsIDB4MDcxQTAwODMsIDB4MDcxRDAwNzgsIDB4MDcxRjAwMDgsIAorICAgICAgICAweDA3MjAwMDcxLCAweDA3MjMwMDgzLCAweDA3MjcwMDk3LCAweDA3MjgwMTdFLCAweDA3MjkwMTdGLCAweDA3MkEwMTgwLCAweDA3MkIwMTgxLCAweDA3MkMwMTgyLCAKKyAgICAgICAgMHgwNzJEMDA5NywgMHgwNzJFMDA3OCwgMHgwNzQwMDA3MSwgMHgwNzQxMDA3OCwgMHgwNzQzMDA3MSwgMHgwNzQ0MDA3OCwgMHgwNzQ2MDA3MSwgMHgwNzQ3MDA3OCwgCisgICAgICAgIDB4MDc0QTAwNzEsIDB4MDc1NDAwNzgsIDB4MDc1NTAwNzEsIDB4MDc1ODAwODMsIDB4MDc1OTEwNzEsIDB4MDc1QTAwODMsIDB4MDc1RTAwNzEsIDB4MDc1RjAwNzgsIAorICAgICAgICAweDA3NjAwMDcxLCAweDA3NjIwMDc4LCAweDA3NjQwMDgzLCAweDA3NjcwMDc4LCAweDA3NjgwMTdFLCAweDA3NjkwMTdGLCAweDA3NkEwMTgwLCAweDA3NkIwMTgxLCAKKyAgICAgICAgMHgwNzZDMDE4MiwgMHgwNzZEMDA3OCwgMHgwNzZFMTA3MSwgMHgwNzZGMDA3OCwgMHgwNzgwMDA5NCwgMHgwNzgyMDA5NywgMHgwNzg5MDA5NCwgMHgwNzhDMDA4MywgCisgICAgICAgIDB4MDc4RDAwOTQsIDB4MDc5MDAxN0UsIDB4MDc5MTAxN0YsIDB4MDc5MjAxODAsIDB4MDc5MzAxODEsIDB4MDc5NDAxODIsIDB4MDc5NTAwQjMsIDB4MDc5QTAwODMsIAorICAgICAgICAweDA3OUQwMEJGLCAweDA3OUYwMEE3LCAweDA3QTAwMDcxLCAweDA3QTEwODcxLCAweDA3QTIwMDcxLCAweDA3QTYwODcxLCAweDA3QTcwMDcxLCAweDA3QUIwODcxLCAKKyAgICAgICAgMHgwN0FDMDA3MSwgMHgwN0I0MDg3MSwgMHgwN0I1MDA3OCwgMHgwN0I4MDA4MywgMHgwN0I5MDg4MywgMHgwN0JCMTA4MywgMHgwN0JEMDA4MywgMHgwN0JGMDBBNywgCisgICAgICAgIDB4MDdDMDA4ODMsIDB4MDdDMTAwODMsIDB4MDdDMjAwOTcsIDB4MDdDMzAwODMsIDB4MDdDNDAwNzEsIDB4MDdDNjAwNzgsIDB4MDdDODAwODMsIDB4MDdDOTA4ODMsIAorICAgICAgICAweDA3Q0EwMDgzLCAweDA3Q0UwODgzLCAweDA3Q0YwMDgzLCAweDA3RDMwODgzLCAweDA3RDQwMDgzLCAweDA3REMwODgzLCAweDA3REQwMDgzLCAweDA3REUwMDc4LCAKKyAgICAgICAgMHgwN0RGMDA5NCwgMHgwN0U2MDA3OCwgMHgwN0U3MDA5NCwgMHgwN0U4MDA5NywgMHgwN0U5MDA3OCwgMHgwODAwMDA3MSwgMHgwODE1MDA3OCwgMHgwODE2MDA4MywgCisgICAgICAgIDB4MDgxODAwQTcsIDB4MDgxOTAwNzgsIDB4MDgxQjAwODMsIDB4MDgxRDAwNzgsIDB4MDgyMDAxN0UsIDB4MDgyMTAxN0YsIDB4MDgyMjAxODAsIDB4MDgyMzAxODEsIAorICAgICAgICAweDA4MjQwMTgyLCAweDA4MjUwMDk3LCAweDA4MjgwMDcxLCAweDA4MkIwMEE3LCAweDA4MkMwMDgzLCAweDA4MkQwMDc4LCAweDA4NTAwMEI1LCAweDA4NjMwMDc4LCAKKyAgICAgICAgMHgwODY4MDA3MSwgMHgwODdEMDA5NywgMHgwODdFMDA3OCwgMHgwODgwMDA3MSwgMHgwOEFEMDA3OCwgMHgwOEFGMDA3MSwgMHgwOEQxMDA3OCwgMHgwOEQ0MDA3MSwgCisgICAgICAgIDB4MDhGRDAwNzgsIDB4MDkwMDAwNzEsIDB4MDkyNDAwNzgsIDB4MDkyNTAwNzEsIDB4MDkyNzAwNzgsIDB4MDkyODAwNzEsIDB4MDkyQjAwNzgsIDB4MDkyRDAwNzEsIAorICAgICAgICAweDA5MkYwMDc4LCAweDA5MzAwMDcxLCAweDA5NDQwMDc4LCAweDA5NDUwMDcxLCAweDA5NDcwMDc4LCAweDA5NDgwMDcxLCAweDA5NTgwMDc4LCAweDA5NTkwMDcxLCAKKyAgICAgICAgMHgwOTVCMDA3OCwgMHgwOTVDMDA3MSwgMHgwOTVGMDA3OCwgMHgwOTYxMDA3MSwgMHgwOTYzMDA3OCwgMHgwOTY0MDA3MSwgMHgwOTZCMDA3OCwgMHgwOTZDMDA3MSwgCisgICAgICAgIDB4MDk4ODAwNzgsIDB4MDk4OTAwNzEsIDB4MDk4QjAwNzgsIDB4MDk4QzAwNzEsIDB4MDlBRDAwNzgsIDB4MDlBRjAwODMsIDB4MDlCMDAwOTcsIDB4MDlCNDAwQUQsIAorICAgICAgICAweDA5QjUwMEFFLCAweDA5QjYwMTJELCAweDA5QjcwMTJFLCAweDA5QjgwMTJGLCAweDA5QjkwMTg1LCAweDA5QkEwMTg2LCAweDA5QkIwMTg3LCAweDA5QkMwMTg4LCAKKyAgICAgICAgMHgwOUJEMDE4NCwgMHgwOUJFMDA3OCwgMHgwOUMwMDA3MSwgMHgwOUM4MDA1NCwgMHgwOUNEMDA3OCwgMHgwOUQwMDA3MSwgMHgwOUZBMDA3OCwgMHgwQTAwMDA3MSwgCisgICAgICAgIDB4MEIzNjAwOTcsIDB4MEIzNzAwNzEsIDB4MEIzQjAwNzgsIDB4MEI0MDAwNzEsIDB4MEI0RDAwQjQsIDB4MEI0RTAwNzgsIDB4MEI1MDAwNzEsIDB4MEI3NTAwOTcsIAorICAgICAgICAweDBCNzcwMTg5LCAweDBCNzgwMDc4LCAweDBCODAwMDcxLCAweDBCODYwMDc4LCAweDBCODcwMDcxLCAweDBCODkwMDgzLCAweDBCOEEwMDc4LCAweDBCOTAwMDcxLCAKKyAgICAgICAgMHgwQjk5MDA4MywgMHgwQjlBMDA5NywgMHgwQjlCMDA3OCwgMHgwQkEwMDA3MSwgMHgwQkE5MDA4MywgMHgwQkFBMDA3OCwgMHgwQkIwMDA3MSwgMHgwQkI2MDA3OCwgCisgICAgICAgIDB4MEJCNzAwNzEsIDB4MEJCODAwNzgsIDB4MEJCOTAwODMsIDB4MEJCQTAwNzgsIDB4MEJDMDAwNzEsIDB4MEJEQTAwQzIsIDB4MEJEQjAwODMsIDB4MEJERjAwQTcsIAorICAgICAgICAweDBCRTQwMDgzLCAweDBCRUEwMDk3LCAweDBCRUIwMDgxLCAweDBCRUMwMDk3LCAweDBCRUQwMDA4LCAweDBCRUUwMDgzLCAweDBCRUYwMDc4LCAweDBCRjAwMTdFLCAKKyAgICAgICAgMHgwQkYxMDE3RiwgMHgwQkYyMDE4MCwgMHgwQkYzMDE4MSwgMHgwQkY0MDE4MiwgMHgwQkY1MDA3OCwgMHgwQkY4MDEwNiwgMHgwQkY5MDEwNywgMHgwQkZBMDEwOCwgCisgICAgICAgIDB4MEJGQjAxMDksIDB4MEJGQzAxMEEsIDB4MEJGRDAwNzgsIDB4MEMwMDAwMDYsIDB4MEMwNTAwODMsIDB4MEMwNzAwNzgsIDB4MEMwODAxN0UsIDB4MEMwOTAxN0YsIAorICAgICAgICAweDBDMEEwMTgwLCAweDBDMEIwMTgxLCAweDBDMEMwMTgyLCAweDBDMEQwMDc4LCAweDBDMTAwMDcxLCAweDBDMjEwMDgxLCAweDBDMjIwMDcxLCAweDBDM0MwMDc4LCAKKyAgICAgICAgMHgwQzQwMDA3MSwgMHgwQzU0MDA4MywgMHgwQzU1MDA3OCwgMHgwQzgwMDA3MSwgMHgwQzhFMDA3OCwgMHgwQzkwMDA4MywgMHgwQzkxMDBBNywgMHgwQzkzMDA4MywgCisgICAgICAgIDB4MEM5NDAwQzgsIDB4MEM5NjAwNzgsIDB4MEM5ODAwQTcsIDB4MEM5QzAwODMsIDB4MEM5RTAwNzgsIDB4MENBMjAwMDYsIDB4MENBMzAxN0UsIDB4MENBNDAxN0YsIAorICAgICAgICAweDBDQTUwMTgwLCAweDBDQTYwMTgxLCAweDBDQTcwMTgyLCAweDBDQTgwMDcxLCAweDBDQjcwMDc4LCAweDBDQjgwMDcxLCAweDBDQkEwMDc4LCAweDBDQzAwMDcxLCAKKyAgICAgICAgMHgwQ0Q1MDA3OCwgMHgwQ0Q4MDBBNywgMHgwQ0UwMDA3MSwgMHgwQ0U0MDBBNywgMHgwQ0U1MDA3OCwgMHgwQ0U4MDE3RSwgMHgwQ0U5MDE3RiwgMHgwQ0VBMDE4MCwgCisgICAgICAgIDB4MENFQjAxODEsIDB4MENFQzAxODIsIDB4MENFRDAwNzgsIDB4MENFRjAwMDYsIDB4MENGMDAwNTQsIDB4MEQwMDAwNzEsIDB4MEQwQjAwODMsIDB4MEQwQzAwQTcsIAorICAgICAgICAweDBEMEUwMDc4LCAweDBEMEYwMDk3LCAweDBEMTAwMDc4LCAweDBFODAwMDU1LCAweDBFOTY3ODgxLCAweDBFOTcwMDgxLCAweDBFOTg3ODgxLCAweDBFOUQwMDgxLCAKKyAgICAgICAgMHgwRTlFNzg4MSwgMHgwRUIxNzA1NSwgMHgwRUI1MDA1NSwgMHgwRUNENzg4MSwgMHgwRUUwMDA4MywgMHgwRUUyMDA3OCwgMHgwRjAwMDg2NSwgMHgwRjRCMDg1NSwgCisgICAgICAgIDB4MEY0RDA5OEEsIDB4MEY0RTAwNzgsIDB4MEY1MDA4NjUsIDB4MEY3RDAwNzgsIDB4MEY4MDA4QzksIDB4MEY4NDA4Q0EsIDB4MEY4ODA4QzksIDB4MEY4QjAwNzgsIAorICAgICAgICAweDBGOEMwOENBLCAweDBGOEYwMDc4LCAweDBGOTAwOEM5LCAweDBGOTQwOENBLCAweDBGOTgwOEM5LCAweDBGOUMwOENBLCAweDBGQTAwOEM5LCAweDBGQTMwMDc4LCAKKyAgICAgICAgMHgwRkE0MDhDQSwgMHgwRkE3MDA3OCwgMHgwRkE4MDhDOSwgMHgwRkFDMDhDQSwgMHgwRkIwMDhDOSwgMHgwRkI0MDhDQSwgMHgwRkI4MDhDQiwgMHgwRkI5MDhDQywgCisgICAgICAgIDB4MEZCQjA4Q0QsIDB4MEZCQzA4Q0UsIDB4MEZCRDA4Q0YsIDB4MEZCRTA4RDAsIDB4MEZCRjAwNzgsIDB4MEZDMDA4QzksIDB4MEZDNDA4RDEsIDB4MEZDODA4QzksIAorICAgICAgICAweDBGQ0MwOEQxLCAweDBGRDAwOEM5LCAweDBGRDQwOEQxLCAweDBGRDgwOEM5LCAweDBGRDkwOThCLCAweDBGREEwMDc4LCAweDBGREIwODU1LCAweDBGREMwOENBLCAKKyAgICAgICAgMHgwRkREMDhEMiwgMHgwRkRFMTAzNywgMHgwRkUwMDgzNywgMHgwRkUxMDk4QiwgMHgwRkUyMDA3OCwgMHgwRkUzMDg1NSwgMHgwRkU0MDhENSwgMHgwRkU2MDgzNywgCisgICAgICAgIDB4MEZFODA4QzksIDB4MEZFOTA4NTUsIDB4MEZFQTAwNzgsIDB4MEZFQjA4NTUsIDB4MEZFQzA4Q0EsIDB4MEZFRDA4RDYsIDB4MEZFRTA4MzcsIDB4MEZGMDA4QzksIAorICAgICAgICAweDBGRjEwODU1LCAweDBGRjIwODkwLCAweDBGRjMwODU1LCAweDBGRjQwOENBLCAweDBGRjUwOEQ3LCAweDBGRjYwODM3LCAweDBGRjgwMDc4LCAweDBGRjkwOThCLCAKKyAgICAgICAgMHgwRkZBMDA3OCwgMHgwRkZCMDg1NSwgMHgwRkZDMDhEOSwgMHgwRkZEMDhEQSwgMHgwRkZFMDgzNywgMHgwRkZGMDA3OCwgMHgxMDAwMDgwNSwgMHgxMDAxMTAwNSwgCisgICAgICAgIDB4MTAwMzU4MDUsIDB4MTAwNDEwMDUsIDB4MTAwNTAwNTcsIDB4MTAwNzAxOEMsIDB4MTAwODU4OTksIDB4MTAwOTAwOTksIDB4MTAwQjEwMDYsIDB4MTAwQzAxOEQsIAorICAgICAgICAweDEwMEQwMERCLCAweDEwMEUwMThELCAweDEwMEYwMERCLCAweDEwMTAwMDA2LCAweDEwMTIxMDA2LCAweDEwMTMwMDA2LCAweDEwMTQwMThFLCAweDEwMTUwMThGLCAKKyAgICAgICAgMHgxMDE2MDE5MCwgMHgxMDE3NTg1MywgMHgxMDE4MDAwNywgMHgxMDE5MTAwNywgMHgxMDFBMDAwNiwgMHgxMDFCMTAwNiwgMHgxMDFDMDEyNiwgMHgxMDFEMDAwNiwgCisgICAgICAgIDB4MTAxRjAwMzgsIDB4MTAyMDAwMDYsIDB4MTAyMjAwMDksIDB4MTAyMzEwMDYsIDB4MTAyNTAwMDYsIDB4MTAyQjEwMDYsIDB4MTAyQzAwMDYsIDB4MTAyRjEwMDUsIAorICAgICAgICAweDEwMzAwMDU3LCAweDEwMzIwMDc4LCAweDEwMzUwMDU3LCAweDEwMzg3ODU1LCAweDEwMzkwMDc4LCAweDEwM0E3OTEwLCAweDEwM0I3OTExLCAweDEwM0M3OTEyLCAKKyAgICAgICAgMHgxMDNENzgwQiwgMHgxMDNFNzgwOSwgMHgxMDNGNzg1NSwgMHgxMDQwNzA1RCwgMHgxMDQxNzA1QiwgMHgxMDQyNzExMCwgMHgxMDQzNzExMSwgMHgxMDQ0NzExMiwgCisgICAgICAgIDB4MTA0NTcwMEIsIDB4MTA0NjcwMDksIDB4MTA0NzAwNzgsIDB4MTA0ODcwODEsIDB4MTA0QTAwNzgsIDB4MTA1MDAwMDgsIDB4MTA1QjAwNzgsIDB4MTA2ODAwODMsIAorICAgICAgICAweDEwNkUwMDk1LCAweDEwNzAwMDgzLCAweDEwNzEwMDk1LCAweDEwNzIwMDgzLCAweDEwNzYwMDc4LCAweDEwODAxMDU0LCAweDEwODMxMDc3LCAweDEwODQxMDU0LCAKKyAgICAgICAgMHgxMDg1Mjg3NywgMHgxMDg3Mjg1NSwgMHgxMDg4Mjg3NywgMHgxMDg5Mjg1NSwgMHgxMDhBMjg3NywgMHgxMDhCMDA1NCwgMHgxMDhDMjg3NywgMHgxMDhGMDA1NCwgCisgICAgICAgIDB4MTA5MDEwNTQsIDB4MTA5MTAwNTQsIDB4MTA5NTA5OTEsIDB4MTA5NjI4NzcsIDB4MTA5NzI4NTUsIDB4MTA5ODI4NzcsIDB4MTA5QTEwNzEsIDB4MTA5QzI4NTUsIAorICAgICAgICAweDEwOUQxMDU0LCAweDEwOUUyODU1LCAweDEwOUYyODc3LCAweDEwQTAwMDE5LCAweDEwQTIyODc3LCAweDEwQTMyODU1LCAweDEwQTUwMDE5LCAweDEwQTYwMDc4LCAKKyAgICAgICAgMHgxMEE5MzA1RiwgMHgxMEFGMzEwNiwgMHgxMEIwMTE5MiwgMHgxMEIxMTE5MywgMHgxMEIyMTE5NCwgMHgxMEIzMTE5NSwgMHgxMEI0MTE5NiwgMHgxMEI1MTE5NywgCisgICAgICAgIDB4MTBCNjExOTgsIDB4MTBCNzExOTksIDB4MTBCODExOUEsIDB4MTBCOTExOUIsIDB4MTBCQTExOUMsIDB4MTBCQjExOUQsIDB4MTBCQzExOUUsIDB4MTBCRDExOUYsIAorICAgICAgICAweDEwQkUxMUEwLCAweDEwQkYxMUExLCAweDEwQzAwMUEyLCAweDEwQzEwMUEzLCAweDEwQzIwMDc4LCAweDEwQzgwMDE5LCAweDEwQ0EwMDU0LCAweDEwQ0QwODE5LCAKKyAgICAgICAgMHgxMENFMDA1NCwgMHgxMEQxMDAxOSwgMHgxMEQyMDA1NCwgMHgxMEU2MDg1NCwgMHgxMEU3MDgxOSwgMHgxMEU4MDA1NCwgMHgxMEZBMDAxOSwgMHgxMTAwMDBFOCwgCisgICAgICAgIDB4MTEwMjAwMTksIDB4MTEwNDA4RkIsIDB4MTEwNTAwRkMsIDB4MTEwNzAwMTksIDB4MTEwODAwRTgsIDB4MTEwOTAwNTksIDB4MTEwQTAxQTQsIDB4MTEwQjAwMTksIAorICAgICAgICAweDExMEQwMEU4LCAweDExMTEwMDE5LCAweDExMTUwMEU4LCAweDExMTYxMEU4LCAweDExMTgwMEU4LCAweDExMUEwMDE5LCAweDExMUMwMEU4LCAweDExMUUwMEZFLCAKKyAgICAgICAgMHgxMTFGMDBFOCwgMHgxMTIwMDhFOCwgMHgxMTIxMDFBNSwgMHgxMTIyMDBFOCwgMHgxMTIzMDhFOCwgMHgxMTI1MDBFOCwgMHgxMTI2MDAxOSwgMHgxMTI5MDBGRSwgCisgICAgICAgIDB4MTEyQjAwMTksIDB4MTEyRjAwRTgsIDB4MTEzMDAwMTksIDB4MTEzMjAwRkUsIDB4MTEzNjA4MTksIDB4MTEzNzA4RkUsIDB4MTEzOTAwRkUsIDB4MTEzQTA4RkUsIAorICAgICAgICAweDExM0IwMEZFLCAweDExM0MwOEZFLCAweDExM0QwMEZFLCAweDExNDAwOEZFLCAweDExNDEwMEZFLCAweDExNDIwOEZFLCAweDExNDMwMEZFLCAweDExNDQwOEZFLCAKKyAgICAgICAgMHgxMTQ1MDBGRSwgMHgxMTQ2MDAxOSwgMHgxMTQ3MDBGRCwgMHgxMTQ5MDAxOSwgMHgxMTUxMDBGRSwgMHgxMTUyMDAxOSwgMHgxMTUzMDBFOCwgMHgxMTU0MDFBNiwgCisgICAgICAgIDB4MTE1NjA4RTgsIDB4MTE1ODAwRkUsIDB4MTE1QzAwMTksIDB4MTE1RjAwRTgsIDB4MTE2MDAwMTksIDB4MTE2NDAwRkQsIDB4MTE2NjAxQTcsIDB4MTE2NzAwMTksIAorICAgICAgICAweDExNjgwMEZFLCAweDExNjkwMDE5LCAweDExNkIwMEZFLCAweDExNzAwOEZFLCAweDExNzIwMEZFLCAweDExNzUwOEZFLCAweDExNzcwMDE5LCAweDExNzgwMEZFLCAKKyAgICAgICAgMHgxMTc5MDEwMiwgMHgxMTdBMDBFOCwgMHgxMTdCMDEwMywgMHgxMTdDMDBFOCwgMHgxMTdEMDEwNCwgMHgxMTdFMDEwNSwgMHgxMTdGMDBFOCwgMHgxMTgwMDA1NCwgCisgICAgICAgIDB4MTE4NDAwRkUsIDB4MTE4NjAwNTQsIDB4MTE5MDAwRTgsIDB4MTE5MTAwNTQsIDB4MTE5NDA4MDksIDB4MTE5NTAwNTQsIDB4MTE5QjAwOTQsIDB4MTFCRDAwNTQsIAorICAgICAgICAweDExQ0EwMDk0LCAweDExQ0IwMDU0LCAweDExQ0QwMDE5LCAweDExREEwMEJGLCAweDExREIwMDU0LCAweDExRUUwMDc4LCAweDEyMDAwMDU0LCAweDEyMTMwMDc4LCAKKyAgICAgICAgMHgxMjIwMDA1NCwgMHgxMjI1MDA3OCwgMHgxMjMwMThDNCwgMHgxMjMxMThDNSwgMHgxMjMyMThDNiwgMHgxMjMzMThDNywgMHgxMjM0MTkxRiwgMHgxMjM1MTkxQSwgCisgICAgICAgIDB4MTIzNjE5MUIsIDB4MTIzNzE5MUMsIDB4MTIzODE5MUQsIDB4MTIzOTE5MUUsIDB4MTIzQTEwQzQsIDB4MTIzQjEwQzUsIDB4MTIzQzEwQzYsIDB4MTIzRDEwQzcsIAorICAgICAgICAweDEyM0UxMTFGLCAweDEyM0YxMTFBLCAweDEyNDAxMTFCLCAweDEyNDExMTFDLCAweDEyNDIxMTFELCAweDEyNDMxMTFFLCAweDEyNDQxMDVBLCAweDEyNDUxMEUzLCAKKyAgICAgICAgMHgxMjQ2MTBFNCwgMHgxMjQ3MTBFNSwgMHgxMjQ4MTFBOCwgMHgxMjQ5MTFBOSwgMHgxMjRBMTFBQSwgMHgxMjRCMTFBQiwgMHgxMjRDMTFBQywgMHgxMjREMTFBRCwgCisgICAgICAgIDB4MTI0RTEwOTQsIDB4MTI1QjE5MTgsIDB4MTI2ODE5MTksIDB4MTI3NTAxMEIsIDB4MTI3NjAxMEMsIDB4MTI3NzAxMEQsIDB4MTI3ODAxMEUsIDB4MTI3OTAxMEYsIAorICAgICAgICAweDEyN0EwMTA2LCAweDEyN0IwMTA3LCAweDEyN0MwMTA4LCAweDEyN0QwMTA5LCAweDEyN0UwMTBBLCAweDEyN0YwMEMzLCAweDEyODAwMDU0LCAweDEyREIwMDE5LCAKKyAgICAgICAgMHgxMkRDMDA1NCwgMHgxMkUwMDAxOSwgMHgxMkUxMDA1NCwgMHgxMkZDMDAxOSwgMHgxMzAwMDA1NCwgMHgxMzM3MDAxOSwgMHgxMzM4MDA1NCwgMHgxMzRFMDA3OCwgCisgICAgICAgIDB4MTM1MDAwNTQsIDB4MTM1OTAwNzgsIDB4MTM4MDAwNTQsIDB4MTM4MjAwNzgsIDB4MTM4MzAwNTQsIDB4MTM4NTAwNzgsIDB4MTM4NjAwNTQsIDB4MTNBOTAwNzgsIAorICAgICAgICAweDEzQUMwMDU0LCAweDEzQUYwMDc4LCAweDEzQjAwMDU0LCAweDEzQjQwMDBBLCAweDEzQkIwMEM0LCAweDEzQkMwMEM1LCAweDEzQkQwMEM2LCAweDEzQkUwMEM3LCAKKyAgICAgICAgMHgxM0JGMDExRiwgMHgxM0MwMDBDNCwgMHgxM0MxMDBDNSwgMHgxM0MyMDBDNiwgMHgxM0MzMDBDNywgMHgxM0M0MDExRiwgMHgxM0M1MDBDNCwgMHgxM0M2MDBDNSwgCisgICAgICAgIDB4MTNDNzAwQzYsIDB4MTNDODAwQzcsIDB4MTNDOTAxMUYsIDB4MTNDQTAwNzgsIDB4MTNDQzAwNTQsIDB4MTNERjAwNzgsIDB4MTNFMDAwMTksIDB4MTNFMTAwRkQsIAorICAgICAgICAweDEzRTIwMDA5LCAweDEzRTMwMDc4LCAweDEzRTgwMDE5LCAweDEzRTkwMEU4LCAweDEzRUEwMEZELCAweDEzRUIwMDE5LCAweDEzRUUwMEZELCAweDEzRUYwMDE5LCAKKyAgICAgICAgMHgxM0YxMDBGRSwgMHgxM0YzMDAwQSwgMHgxM0Y2MDA3OCwgMHgxM0Y4MDAxOSwgMHgxNDAwMDA5NCwgMHgxNDgwMDAxOSwgMHgxNEMxMDAwOSwgMHgxNEM2MDFBRSwgCisgICAgICAgIDB4MTRDNzAxQUYsIDB4MTRDODAwMDksIDB4MTRDQzAwMTksIDB4MTRDRDAwRTgsIDB4MTREODAwMTksIDB4MTRFMDAwRkUsIDB4MTRFMTAwRTgsIDB4MTRFMjAwRkUsIAorICAgICAgICAweDE0RTMwMDE5LCAweDE0RTQwMEU4LCAweDE0RTUwMDE5LCAweDE0RTcwMEZELCAweDE0RTkwMDE5LCAweDE0RUEwMEZFLCAweDE0RUIwMDE5LCAweDE0RUMwMDBBLCAKKyAgICAgICAgMHgxNEVFMDAxOSwgMHgxNEYwMDBFOCwgMHgxNEYzMDAxOSwgMHgxNEY0MDBFOCwgMHgxNEY1MDAxOSwgMHgxNEZBMDFCMCwgMHgxNEZCMDBFOCwgMHgxNEZDMDBGRSwgCisgICAgICAgIDB4MTRGRDAwMTksIDB4MTRGRTAwMEEsIDB4MTRGRjAwMTksIDB4MTUwNTAwRTgsIDB4MTUwRTAwMTksIDB4MTUwRjAwRTgsIDB4MTUxMTAwMTksIDB4MTUxNDAwRTgsIAorICAgICAgICAweDE1MTUwMEZELCAweDE1MTcwMDE5LCAweDE1MUEwMEZFLCAweDE1MUIwMDE5LCAweDE1MUUwMEZFLCAweDE1MUYwMDE5LCAweDE1MkIwMEU4LCAweDE1MkMwMDE5LCAKKyAgICAgICAgMHgxNTMyMDBGRSwgMHgxNTMzMDAxOSwgMHgxNTM1MDBFOCwgMHgxNTM4MDAxOSwgMHgxNTM5MDBFOCwgMHgxNTNBMTAxOSwgMHgxNTNCMDAxOSwgMHgxNTNDMDBGRCwgCisgICAgICAgIDB4MTUzRDAwRTgsIDB4MTUzRTAwRkQsIDB4MTU0MjAwRTgsIDB4MTU0NTAwRkQsIDB4MTU0NjAwRTgsIDB4MTU0ODAwRkQsIDB4MTU0RTAwRTgsIDB4MTU1MDAwRkQsIAorICAgICAgICAweDE1NTEwMEU4LCAweDE1NTIwMDE5LCAweDE1NTMwMEZFLCAweDE1NTcwMEZELCAweDE1NTgwMEU4LCAweDE1NTkwMEZELCAweDE1NUEwMEU4LCAweDE1NUQwMEZELCAKKyAgICAgICAgMHgxNTYzMDBFOCwgMHgxNTY2MDBGRCwgMHgxNTZCMDAxOSwgMHgxNTcxMDFCMSwgMHgxNTczMDAxOSwgMHgxNTc2MDBGRSwgMHgxNTc3MDAxOSwgMHgxNTc5MDBFOCwgCisgICAgICAgIDB4MTU3QTAwMTksIDB4MTU3QjAwRkQsIDB4MTU3RDAwRTgsIDB4MTU3RjAwMTksIDB4MTU4MDAwNTQsIDB4MTU4QTAwNzgsIDB4MTYwMDAwOTYsIDB4MTYxNzAwNzgsIAorICAgICAgICAweDE2MTgwMDk4LCAweDE2MkYwMDc4LCAweDE2NDAwMDY1LCAweDE2NzIwMDU0LCAweDE2NzUwMDc4LCAweDE2N0MwMDA2LCAweDE2N0UwMDVGLCAweDE2N0YwMDA2LCAKKyAgICAgICAgMHgxNjgwMDEyNSwgMHgxNjkzMDA3OCwgMHgxNjk4MDA3MSwgMHgxNkIzMDA3OCwgMHgxNkI3Nzg4MSwgMHgxNkI4MDA3OCwgMHgxNkMwMDA3MSwgMHgxNkNCMDA3OCwgCisgICAgICAgIDB4MTZEMDAwNzEsIDB4MTZEMzAwNzgsIDB4MTZENDAwNzEsIDB4MTZENzAwNzgsIDB4MTZEODAwNzEsIDB4MTZEQjAwNzgsIDB4MTZEQzAwNzEsIDB4MTZERjAwNzgsIAorICAgICAgICAweDE2RTAwMDcxLCAweDE2RTMwMDc4LCAweDE2RTQwMDcxLCAweDE2RTcwMDc4LCAweDE2RTgwMDcxLCAweDE2RUIwMDc4LCAweDE2RUMwMDcxLCAweDE2RUYwMDc4LCAKKyAgICAgICAgMHgxNzAwMDAwNiwgMHgxNzAxMDBFMCwgMHgxNzAzMDAwNiwgMHgxNzA0MDEyNiwgMHgxNzA1MDAwNiwgMHgxNzA2MDBFMCwgMHgxNzA3MDAwNiwgMHgxNzBCMDA5OSwgCisgICAgICAgIDB4MTcwQzAwNzgsIDB4MTcwRTAwRTAsIDB4MTcwRjAwNzgsIDB4MTc0MDAwNTQsIDB4MTc0RjEwNTQsIDB4MTc1MDAwNTQsIDB4MTc3OTEwNTQsIDB4MTc3QTAwNzgsIAorICAgICAgICAweDE3ODAxMDU0LCAweDE3RUIwMDc4LCAweDE3RjgwMDU0LCAweDE3RkUwMDc4LCAweDE4MDAwMDA2LCAweDE4MDIwMDgxLCAweDE4MDMwMUIyLCAweDE4MDQwMDBBLCAKKyAgICAgICAgMHgxODA5MDA1NCwgMHgxODBBMDAwQSwgMHgxODBFMDBCNCwgMHgxODBGMDBCRiwgMHgxODEwMDFCMywgMHgxODExMDFCNCwgMHgxODEyMDFCNSwgMHgxODEzMDFCNiwgCisgICAgICAgIDB4MTgxNDAxQjcsIDB4MTgxNTAwODMsIDB4MTgxODAwODEsIDB4MTgxQjAwNTQsIDB4MTgxQzExQjgsIDB4MTgxRDAwODEsIDB4MTgxRTAwMDYsIDB4MTgxRjAwNTQsIAorICAgICAgICAweDE4MjAwMDcxLCAweDE4MzIwODcxLCAweDE4MzUwMDcxLCAweDE4MzgwODcxLCAweDE4M0EwMDcxLCAweDE4M0IwODcxLCAweDE4M0QwMDcxLCAweDE4M0UwODcxLCAKKyAgICAgICAgMHgxODNGMDA3MSwgMHgxODRCMDA3OCwgMHgxODRDMDA4MywgMHgxODREMTAzNywgMHgxODRFMDA4MSwgMHgxODRGODA3MSwgMHgxODUwMDA3MSwgMHgxODYyMDg3MSwgCisgICAgICAgIDB4MTg2NTAwNzEsIDB4MTg2ODA4NzEsIDB4MTg2QTAwNzEsIDB4MTg2QjA4NzEsIDB4MTg2RDAwNzEsIDB4MTg2RTA4NzEsIDB4MTg2RjAwNzEsIDB4MTg3QjA4NzEsIAorICAgICAgICAweDE4N0QwMDA2LCAweDE4N0UwMDgxLCAweDE4N0Y4MDcxLCAweDE4ODAwMDc4LCAweDE4ODIwMDcxLCAweDE4OTYwMDc4LCAweDE4OTgxMDcxLCAweDE4QzcwMDc4LCAKKyAgICAgICAgMHgxOEM4MDA5NCwgMHgxOEM5NzhCNiwgMHgxOENBNzhCNywgMHgxOENCNzg5NCwgMHgxOEQwMDA3MSwgMHgxOERDMDA3OCwgMHgxOEUwMDA1NCwgMHgxOEU4MDA3OCwgCisgICAgICAgIDB4MThGODAwNzEsIDB4MTkwMDEwOTQsIDB4MTkwRTEwNTQsIDB4MTkwRjAwNzgsIDB4MTkxMDEwQjYsIDB4MTkxMTEwQjcsIDB4MTkxMjEwQjgsIDB4MTkxMzEwQjksIAorICAgICAgICAweDE5MTQxMEIwLCAweDE5MTUxMDk0LCAweDE5MjIwMDc4LCAweDE5MjgxOUI5LCAweDE5MjkxOUJBLCAweDE5MkExOUJCLCAweDE5MkIxOUJDLCAweDE5MkMxOUJELCAKKyAgICAgICAgMHgxOTJEMTlCRSwgMHgxOTJFMTlCRiwgMHgxOTJGMTlDMCwgMHgxOTMwMTg5NCwgMHgxOTNFMTg1NCwgMHgxOTNGMDA5NCwgMHgxOTQwMThCNiwgMHgxOTQxMThCNywgCisgICAgICAgIDB4MTk0MjE4QjgsIDB4MTk0MzE4QjksIDB4MTk0NDE4QjAsIDB4MTk0NTE4OTQsIDB4MTk1ODE5QzEsIDB4MTk1OTE5QzIsIDB4MTk1QTE5QzMsIDB4MTk1QjE5QzQsIAorICAgICAgICAweDE5NUMxOUM1LCAweDE5NUQxOUM2LCAweDE5NUUxOUM3LCAweDE5NUYxOUM4LCAweDE5NjAxMDk0LCAweDE5NjY2ODU0LCAweDE5NjgxODk0LCAweDE5N0YwMDc4LCAKKyAgICAgICAgMHgxOTgwNjg5NCwgMHgxOUFDMTA5NCwgMHgxOUI4Njg5NCwgMHgxOUJCNjg1NCwgMHgxOUJENjg5NCwgMHgxOUVGNjg1NCwgMHgxOUYwMTA5NCwgMHgxOUZGNjg1NCwgCisgICAgICAgIDB4MUEwMDAwNzEsIDB4MjZEQjAwNzgsIDB4MjZFMDAwNTQsIDB4MjcwMDAwNzEsIDB4NEZERTAwNzgsIDB4NTAwMDAwNzEsIDB4NTAwQTAwODEsIDB4NTAwQjAwNzEsIAorICAgICAgICAweDUyNDYwMDc4LCAweDUyNDgwMDU0LCAweDUyNjMwMDc4LCAweDUzODAwMDM3LCAweDUzOEIwMDc4LCAweDU0MDAwMDcxLCAweDU0MDUwMDgzLCAweDU0MDYwMDcxLCAKKyAgICAgICAgMHg1NDExMDBBNywgMHg1NDEyMDA4MywgMHg1NDEzMDBBNywgMHg1NDE0MDA1NCwgMHg1NDE2MDA3OCwgMHg1NjAwMDA3MSwgMHg2QkQyMDA3OCwgMHg2QzAwMDEzRSwgCisgICAgICAgIDB4NzAwMDAxM0YsIDB4N0M4MDA4NzEsIDB4N0QwNzAwNzEsIDB4N0QwQTA4NzEsIDB4N0QwRjAwNzEsIDB4N0QxMjA4NzEsIDB4N0QxMzAwNzEsIDB4N0QxNTA4NzEsIAorICAgICAgICAweDdEMTcwMDc4LCAweDdEMTgwODcxLCAweDdEMzUwMDc4LCAweDdEMzgwODcxLCAweDdENkQwMDc4LCAweDdEODAxMDU1LCAweDdEODMwMDc4LCAweDdEODkxMDU1LCAKKyAgICAgICAgMHg3RDhDMDA3OCwgMHg3RDhFMDg5QiwgMHg3RDkwMjg5QiwgMHg3RDk0MjgwQiwgMHg3RDk1MDg5QiwgMHg3RDlCMDA3OCwgMHg3RDlDMDg5QiwgMHg3RDlFMDA3OCwgCisgICAgICAgIDB4N0RBMDA4OUIsIDB4N0RBMjAwNzgsIDB4N0RBMzA4OUIsIDB4N0RBNzEwOUIsIDB4N0RBODIwOUUsIDB4N0RBQTQ4OUUsIDB4N0RBQjIwOUUsIDB4N0RBQzQ4OUUsIAorICAgICAgICAweDdEQUQyMDlFLCAweDdEQUU0ODlFLCAweDdEQUYyMDlFLCAweDdEQjA0ODlFLCAweDdEQjEyMDlFLCAweDdEQjI0ODlFLCAweDdEQjMyMDlFLCAweDdEQjQ0ODlFLCAKKyAgICAgICAgMHg3REI1MjA5RSwgMHg3REI2NDg5RSwgMHg3REI3MjA5RSwgMHg3REI4NDg5RSwgMHg3REI5MjA5RSwgMHg3REJBNDg5RSwgMHg3REJCMjA5RSwgMHg3REJDNDg5RSwgCisgICAgICAgIDB4N0RCRDIwOUUsIDB4N0RCRTQ4OUUsIDB4N0RCRjIwOUUsIDB4N0RDMDQ4OUUsIDB4N0RDMTIwOUUsIDB4N0RDODQ4OUUsIDB4N0RDOTIwOUUsIDB4N0RDQTQ4OUUsIAorICAgICAgICAweDdEQ0IyMDlFLCAweDdEQ0M0ODlFLCAweDdEQ0QyMDlFLCAweDdEQ0U0ODlFLCAweDdEQ0YyMDlFLCAweDdERDE0ODlFLCAweDdERDIyMDlFLCAweDdERDQ0ODlFLCAKKyAgICAgICAgMHg3REQ1MjA5RSwgMHg3REQ2NDg5RSwgMHg3REQ3MjA5RSwgMHg3REQ5MDA3OCwgMHg3REU5NDA5RSwgMHg3REVBMzg5RSwgMHg3REVCNDA5RSwgMHg3REVGMjA5RSwgCisgICAgICAgIDB4N0RGMzQ4OUUsIDB4N0RGNTIwOUUsIDB4N0RGQzQwOUUsIDB4N0RGRDM4OUUsIDB4N0RGRTIwOUUsIDB4N0RGRjQ4OUUsIDB4N0UwMDQwOUUsIDB4N0UzMjIwOUUsIAorICAgICAgICAweDdFNEIzODlFLCAweDdFNkY0ODlFLCAweDdFN0E0MDlFLCAweDdFODgyMDlFLCAweDdFOTYzODlFLCAweDdFOUE0ODlFLCAweDdFOUU0MDlFLCAweDdFOUYwMEJGLCAKKyAgICAgICAgMHg3RUEwMDA3OCwgMHg3RUE4MjA5RSwgMHg3RUE5Mzg5RSwgMHg3RUFEMjA5RSwgMHg3RUFFMzg5RSwgMHg3RUFGMjA5RSwgMHg3RUIwMzg5RSwgMHg3RUIzMjA5RSwgCisgICAgICAgIDB4N0VCNTM4OUUsIDB4N0VCNzIwOUUsIDB4N0VCOTM4OUUsIDB4N0VCQTIwOUUsIDB4N0VCQjM4OUUsIDB4N0VCQzIwOUUsIDB4N0VCRTM4OUUsIDB4N0VCRjIwOUUsIAorICAgICAgICAweDdFQzEzODlFLCAweDdFQzIyMDlFLCAweDdFQzQzODlFLCAweDdFQzUyMDlFLCAweDdFQzYzODlFLCAweDdFQzgwMDc4LCAweDdFQzkzODlFLCAweDdFQ0IyMDlFLCAKKyAgICAgICAgMHg3RUNFMzg5RSwgMHg3RUNGMjA5RSwgMHg3RURBMzg5RSwgMHg3RURCMjA5RSwgMHg3RUUxMzg5RSwgMHg3RUUzMjA5RSwgMHg3RUU0MDA3OCwgMHg3RUY4NDA5RSwgCisgICAgICAgIDB4N0VGRTAwNTQsIDB4N0VGRjAwNzgsIDB4N0YwMDAwODMsIDB4N0YwODgwMDYsIDB4N0YwQjgwQjQsIDB4N0YwQzgwMDYsIDB4N0YwRDAwNzgsIDB4N0YxMDAwODMsIAorICAgICAgICAweDdGMTIwMDc4LCAweDdGMTg4MDk5LCAweDdGMTk4MDM4LCAweDdGMUE4MEI0LCAweDdGMjIwMDA2LCAweDdGMjM4MEI0LCAweDdGMjQxMDA2LCAweDdGMjYxMDM4LCAKKyAgICAgICAgMHg3RjI4NjAwNiwgMHg3RjI5MDA3OCwgMHg3RjJBNjAwQywgMHg3RjJCNjAwNiwgMHg3RjJDNjBCNCwgMHg3RjJGNjAwNywgMHg3RjMwNjAwNiwgMHg3RjMxNjAwRCwgCisgICAgICAgIDB4N0YzMjYwMTksIDB4N0YzMzAwNzgsIDB4N0YzNDYwMDgsIDB4N0YzNTYwMDYsIDB4N0YzNjAwNzgsIDB4N0YzODQ4OUUsIDB4N0YzOTAwOUUsIDB4N0YzQTAwNzgsIAorICAgICAgICAweDdGM0I0ODlFLCAweDdGNDA0MDlFLCAweDdGNDUzODlFLCAweDdGNDY0MDlFLCAweDdGNDgzODlFLCAweDdGNDk0MDlFLCAweDdGNEIzODlFLCAweDdGNEM0MDlFLCAKKyAgICAgICAgMHg3RjREMzg5RSwgMHg3RjRFNDA5RSwgMHg3RjRGMzg5RSwgMHg3RjUwNDA5RSwgMHg3RjUxMzg5RSwgMHg3RjUyNDA5RSwgMHg3RjUzMzg5RSwgMHg3RjU0NDA5RSwgCisgICAgICAgIDB4N0Y1OTM4OUUsIDB4N0Y1QTQwOUUsIDB4N0Y1QjM4OUUsIDB4N0Y1QzQwOUUsIDB4N0Y1RDM4OUUsIDB4N0Y1RTQwOUUsIDB4N0Y1RjM4OUUsIDB4N0Y2MDQwOUUsIAorICAgICAgICAweDdGNjEzODlFLCAweDdGNjI0MDlFLCAweDdGNjMzODlFLCAweDdGNjQ0MDlFLCAweDdGNjUzODlFLCAweDdGNjY0MDlFLCAweDdGNjczODlFLCAweDdGNjg0MDlFLCAKKyAgICAgICAgMHg3RjY5Mzg5RSwgMHg3RjZBNDA5RSwgMHg3RjZCMzg5RSwgMHg3RjZDNDA5RSwgMHg3RjZEMzg5RSwgMHg3RjZFNDA5RSwgMHg3RjZGMzg5RSwgMHg3RjcwNDA5RSwgCisgICAgICAgIDB4N0Y3MTM4OUUsIDB4N0Y3MjQwOUUsIDB4N0Y3MzM4OUUsIDB4N0Y3NDQwOUUsIDB4N0Y3NTM4OUUsIDB4N0Y3NjQwOUUsIDB4N0Y3OTM4OUUsIDB4N0Y3QTQwOUUsIAorICAgICAgICAweDdGN0UwMDc4LCAweDdGN0YwMDU3LCAweDdGODA4ODA2LCAweDdGODE4ODA3LCAweDdGODM4ODA2LCAweDdGODQ4ODBBLCAweDdGODU4ODBCLCAweDdGODY4ODBELCAKKyAgICAgICAgMHg3Rjg3ODgwQywgMHg3Rjg4ODgwRiwgMHg3Rjg5ODgxMSwgMHg3RjhBODgxMywgMHg3RjhCODgxNSwgMHg3RjhDODgxNywgMHg3RjhEODgwNiwgMHg3RjhFODgxOSwgCisgICAgICAgIDB4N0Y4Rjg4MDYsIDB4N0Y5MDg4NjAsIDB4N0Y5RDg4MzUsIDB4N0Y5RTg4MzYsIDB4N0Y5Rjg4MzgsIDB4N0ZBMDg4NjEsIDB4N0ZBRDg4MzUsIDB4N0ZBRTg4MzYsIAorICAgICAgICAweDdGQUY4ODA5LCAweDdGQjA1MDA2LCAweDdGQjE1MDBBLCAweDdGQjI1MDA2LCAweDdGQjM1MDcxLCAweDdGQ0Y1MDgxLCAweDdGRDA1MDcxLCAweDdGREYwMDc4LCAKKyAgICAgICAgMHg3RkUxNTA3MSwgMHg3RkU0MDA3OCwgMHg3RkU1NTA3MSwgMHg3RkU4MDA3OCwgMHg3RkU5NTA3MSwgMHg3RkVDMDA3OCwgMHg3RkVENTA3MSwgMHg3RkVFMDA3OCwgCisgICAgICAgIDB4N0ZGMDg4MDgsIDB4N0ZGMTg4MzcsIDB4N0ZGMjg4MDgsIDB4N0ZGMzAwNzgsIDB4N0ZGNDUwMTksIDB4N0ZGNjUwNTQsIDB4N0ZGNzAwNzgsIDB4N0ZGQzAxNDEsIAorICAgICAgICAweDdGRkUwMDU0LCAweDdGRkYwMDc4LCAweDgwMDAwMDcxLCAweDgwMTMwMDc4LCAweDgwMTQwMDcxLCAweDgwMUQwMDc4LCAweDgwMUUwMDcxLCAweDgwMjcwMDc4LCAKKyAgICAgICAgMHg4MDI4MDA3MSwgMHg4MDJGMDA3OCwgMHg4MDQwMDA3MSwgMHg4MDdEMDA3OCwgMHg4MDgwMDAwNiwgMHg4MDgxMDA3OCwgMHg4MDgzMDBBRCwgMHg4MDg0MDBBRSwgCisgICAgICAgIDB4ODA4NTAxMkQsIDB4ODA4NjAxMkUsIDB4ODA4NzAxMkYsIDB4ODA4ODAxODUsIDB4ODA4OTAxODYsIDB4ODA4QTAxODcsIDB4ODA4QjAxODgsIDB4ODA4QzAxODQsIAorICAgICAgICAweDgwOEQwMUM5LCAweDgwOEUwMUNBLCAweDgwOEYwMUNCLCAweDgwOTAwMUNDLCAweDgwOTEwMUNELCAweDgwOTIwMUNFLCAweDgwOTMwMUNGLCAweDgwOTQwMUQwLCAKKyAgICAgICAgMHg4MDk1MDBCRSwgMHg4MDk2MDFEMSwgMHg4MDk3MDFEMiwgMHg4MDk4MDFEMywgMHg4MDk5MDFENCwgMHg4MDlBMDA3OCwgMHg4MDlCMDA5NCwgMHg4MEEwMDE0RSwgCisgICAgICAgIDB4ODBBMTAxNTIsIDB4ODBBMjAxNTMsIDB4ODBBMzAxNTcsIDB4ODBBNDAxNTQsIDB4ODBBNTAxNTUsIDB4ODBBNjAxNTYsIDB4ODBBNzAxNTIsIDB4ODBBODAxNTAsIAorICAgICAgICAweDgwQTkwMTUzLCAweDgwQUEwMUQ1LCAweDgwQUIwMTU0LCAweDgwQUMwMTRGLCAweDgwQUQwMTU4LCAweDgwQUYwMTUyLCAweDgwQjAwMTU0LCAweDgwQjIwMUQ2LCAKKyAgICAgICAgMHg4MEIzMDE1MCwgMHg4MEI1MDFENywgMHg4MEI2MDE1MywgMHg4MEI4MDE1NiwgMHg4MEI5MDE1MiwgMHg4MEJBMDA1RiwgMHg4MEJDMDA1NCwgMHg4MEM1MDA3OCwgCisgICAgICAgIDB4ODE4MDAwNzEsIDB4ODE4RjAwNzgsIDB4ODE5MDAxMkQsIDB4ODE5MTAwQkIsIDB4ODE5MjAwNzgsIDB4ODE5ODAwNzEsIDB4ODFBNTAwNzgsIDB4ODFDMDAwNzEsIAorICAgICAgICAweDgxQ0YwMDk3LCAweDgxRDAwMDcxLCAweDgxRTIwMDc4LCAweDgxRTQwMDcxLCAweDgxRTgwMTRGLCAweDgxRTkwMTU0LCAweDgxRUEwMTU1LCAweDgxRUIwMDc4LCAKKyAgICAgICAgMHg4MjAwMDE1QiwgMHg4MjE0MDE1QywgMHg4MjI4MDA3MSwgMHg4MjRGMDA3OCwgMHg4MjUwMDE3RSwgMHg4MjUxMDE3RiwgMHg4MjUyMDE4MCwgMHg4MjUzMDE4MSwgCisgICAgICAgIDB4ODI1NDAxODIsIDB4ODI1NTAwNzgsIDB4ODQwMDAwOUIsIDB4ODQwMzAwNzgsIDB4ODQwNTAwOUIsIDB4ODQxQzAwNzgsIDB4ODQxRjAwOUIsIDB4ODQyMDAwNzgsIAorICAgICAgICAweDg1MDAwMDgzLCAweDg1MDMwMDc4LCAweDg1MDYwMDgzLCAweDg1MDgwMDlCLCAweDg1MUEwMDc4LCAweDg1MUMwMDgzLCAweDg1MUQwMDc4LCAweDg1MUYwMDgzLCAKKyAgICAgICAgMHg4NTIwMDFEOCwgMHg4NTIxMDFEOSwgMHg4NTIyMDFEQSwgMHg4NTIzMDFEQiwgMHg4NTI0MDA3OCwgMHg4NTI4MDA5QSwgMHg4NTJDMDA3OCwgMHhFODAwMDA5NCwgCisgICAgICAgIDB4RTg3QjAwNzgsIDB4RTg4MDAwOTQsIDB4RTg5MzAwNzgsIDB4RTg5NTAwOTQsIDB4RThBRjA4OTQsIDB4RThCMjAwQTcsIDB4RThCMzAwODMsIDB4RThCNTAwOTQsIAorICAgICAgICAweEU4QjYwMEE3LCAweEU4QjkwMDU3LCAweEU4QkQwMDgzLCAweEU4QzEwMDk0LCAweEU4QzIwMDgzLCAweEU4QzYwMDk0LCAweEU4RDUwMDgzLCAweEU4RDcwMDk0LCAKKyAgICAgICAgMHhFOEREMDg5NCwgMHhFOEUwMDA5NCwgMHhFOEVGMDA3OCwgMHhFOTAwMDA1NCwgMHhFOTIxMDA4MywgMHhFOTIyMDA1NCwgMHhFOTIzMDA3OCwgMHhFOTgwMDA1NCwgCisgICAgICAgIDB4RTlBQjAwNzgsIDB4RUEwMDI4NzcsIDB4RUEwRDI4NTUsIDB4RUExQTI4NzcsIDB4RUEyNzI4NTUsIDB4RUEyQTAwNzgsIDB4RUEyQjI4NTUsIDB4RUEzNDI4NzcsIAorICAgICAgICAweEVBNDEyODU1LCAweEVBNEUwMDc4LCAweEVBNEYyODc3LCAweEVBNTAwMDc4LCAweEVBNTIyODc3LCAweEVBNTMwMDc4LCAweEVBNTQyODc3LCAweEVBNTYwMDc4LCAKKyAgICAgICAgMHhFQTU3Mjg3NywgMHhFQTVCMjg1NSwgMHhFQTY4Mjg3NywgMHhFQTc1Mjg1NSwgMHhFQTgyMjg3NywgMHhFQTg1MDA3OCwgMHhFQTg2Mjg3NywgMHhFQThBMDA3OCwgCisgICAgICAgIDB4RUE4QjI4NzcsIDB4RUE4RTAwNzgsIDB4RUE4RjI4NTUsIDB4RUE5QzI4NzcsIDB4RUE5RjAwNzgsIDB4RUFBMDI4NzcsIDB4RUFBMjAwNzgsIDB4RUFBNTI4NzcsIAorICAgICAgICAweEVBQTgwMDc4LCAweEVBQTkyODU1LCAweEVBQjYyODc3LCAweEVBQzMyODU1LCAweEVBRDAyODc3LCAweEVBREQyODU1LCAweEVBRUEyODc3LCAweEVBRjcyODU1LCAKKyAgICAgICAgMHhFQjA0Mjg3NywgMHhFQjExMjg1NSwgMHhFQjFFMjg3NywgMHhFQjJCMjg1NSwgMHhFQjM4Mjg3NywgMHhFQjQ1Mjg1NSwgMHhFQjUzMDA3OCwgMHhFQjU0Mjg3NywgCisgICAgICAgIDB4RUI2MDI5REMsIDB4RUI2MTI4NTUsIDB4RUI2RDI5REMsIDB4RUI2RTI4NTUsIDB4RUI3MTI4NzcsIDB4RUI3RDI5REMsIDB4RUI3RTI4NTUsIDB4RUI4QTI5REMsIAorICAgICAgICAweEVCOEIyODU1LCAweEVCOEUyODc3LCAweEVCOUEyOURDLCAweEVCOUIyODU1LCAweEVCQTcyOURDLCAweEVCQTgyODU1LCAweEVCQUIyODc3LCAweEVCQjcyOURDLCAKKyAgICAgICAgMHhFQkI4Mjg1NSwgMHhFQkM0MjlEQywgMHhFQkM1Mjg1NSwgMHhFQkM4Mjg3NywgMHhFQkQ0MjlEQywgMHhFQkQ1Mjg1NSwgMHhFQkUxMjlEQywgMHhFQkUyMjg1NSwgCisgICAgICAgIDB4RUJFNTAwNzgsIDB4RUJFNzI4MEYsIDB4RUJFODI4MTEsIDB4RUJFOTI4MTMsIDB4RUJFQTI4MTUsIDB4RUJFQjI4MTcsIDB4RUJFQzI4MEYsIDB4RUJFRDI4MTEsIAorICAgICAgICAweEVCRUUyODEzLCAweEVCRUYyODE1LCAweEVCRjAyODE3LCAweEVCRjEyODBGLCAweEVCRjIyODExLCAweEVCRjMyODEzLCAweEVCRjQyODE1LCAweEVCRjUyODE3LCAKKyAgICAgICAgMHhFQkY2MjgwRiwgMHhFQkY3MjgxMSwgMHhFQkY4MjgxMywgMHhFQkY5MjgxNSwgMHhFQkZBMjgxNywgMHhFQkZCMjgwRiwgMHhFQkZDMjgxMSwgMHhFQkZEMjgxMywgCisgICAgICAgIDB4RUJGRTI4MTUsIDB4RUJGRjI4MTcsIDB4RUMwMDAwNzgKKyAgICB9OworCisgICAgc3RhdGljIGNvbnN0IHVpbnQzMl90IGExN1tdID0geworICAgICAgICAweDAwMDAwMDcxLCAweDUzNkIwMDc4LCAweDdDMDAwODcxLCAweDdEMEYwMDc4CisgICAgfTsKKworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBhMjNbXSA9IHsKKyAgICAgICAgMHgwMDAwMDA1NywgMHgwMDAxMDA3OCwgMHgwMDEwMDA1NywgMHgwMDQwMDA3OCwgMHgwMDgwMDA4MywgMHgwMEY4MDA3OCwgMHg4MDAwMDEzRiwgMHhGRkZGMDA3OAorICAgIH07CisKKyAgICBzdGF0aWMgY29uc3QgdWludDMyX3QgYTI0W10gPSB7CisgICAgICAgIDB4MDAwMDAxM0YsIDB4N0ZGRjAwNzgKKyAgICB9OworCisKKyAgICAvLyBUaGUgZnVsbCBzZXQgb2YgYWxsIGFycmF5cyB0byBiZSBzZWFyY2hlZC4KKyAgICBzdGF0aWMgY29uc3QgUmFuZ2UgRlVMTF9EQVRBW10gPSB7CisgICAgICAgIHtzaXplb2YoYTApL3NpemVvZih1aW50MzJfdCksIGEwfSwKKyAgICAgICAge3NpemVvZihhMSkvc2l6ZW9mKHVpbnQzMl90KSwgYTF9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAge3NpemVvZihhNykvc2l6ZW9mKHVpbnQzMl90KSwgYTd9LAorICAgICAgICB7c2l6ZW9mKGE4KS9zaXplb2YodWludDMyX3QpLCBhOH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAge3NpemVvZihhMTYpL3NpemVvZih1aW50MzJfdCksIGExNn0sCisgICAgICAgIHtzaXplb2YoYTE3KS9zaXplb2YodWludDMyX3QpLCBhMTd9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAge3NpemVvZihhMjMpL3NpemVvZih1aW50MzJfdCksIGEyM30sCisgICAgICAgIHtzaXplb2YoYTI0KS9zaXplb2YodWludDMyX3QpLCBhMjR9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0sCisgICAgICAgIHswLCAwfSwKKyAgICAgICAgezAsIDB9LAorICAgICAgICB7MCwgMH0KKyAgICB9OworCisgICAgLy8gQXJyYXkgb2YgdXBwZXJjYXNlIGRpZmZlcmVuY2VzCisgICAgc3RhdGljIGNvbnN0IHNob3J0IFVDRElGRltdID0geworICAgICAgICAgICAgMCwgICAtMzIsICAgNzQzLCAgIDEyMSwgICAgLTEsICAtMjMyLCAgLTMwMCwgICAgOTcsIAorICAgICAgICAgIDE2MywgICAxMzAsICAgIDU2LCAgICAtMiwgICAtNzksICAtMjEwLCAgLTIwNiwgIC0yMDUsIAorICAgICAgICAgLTIwMiwgIC0yMDMsICAtMjA3LCAgLTIwOSwgIC0yMTEsICAtMjEzLCAgLTIxNCwgIC0yMTgsIAorICAgICAgICAgLTIxNywgIC0yMTksICAgLTgzLCAgICA4NCwgICAtMzgsICAgLTM3LCAgIC0zMSwgICAtNjQsIAorICAgICAgICAgIC02MywgICAtNjIsICAgLTU3LCAgIC00NywgICAtNTQsICAgLTg2LCAgIC04MCwgICAgIDcsIAorICAgICAgICAgIC05NiwgICAtNDgsICAgLTU5LCAgICAgOCwgICAgNzQsICAgIDg2LCAgIDEwMCwgICAxMjgsIAorICAgICAgICAgIDExMiwgICAxMjYsICAgICA5LCAtNzIwNSwgICAtMTYsICAgLTI2LCAtNzI2NCwgICAtNDAKKyAgICB9OworCisgICAgLy8gQXJyYXkgb2YgbG93ZXJjYXNlIGRpZmZlcmVuY2VzCisgICAgc3RhdGljIGNvbnN0IHNob3J0IExDRElGRltdID0geworICAgICAgICAgICAgMCwgICAgMzIsICAgICAxLCAgLTE5OSwgIC0xMjEsICAgMjEwLCAgIDIwNiwgICAyMDUsIAorICAgICAgICAgICA3OSwgICAyMDIsICAgMjAzLCAgIDIwNywgICAyMTEsICAgMjA5LCAgIDIxMywgICAyMTQsIAorICAgICAgICAgIDIxOCwgICAyMTcsICAgMjE5LCAgICAgMiwgICAtOTcsICAgLTU2LCAgLTEzMCwgIC0xNjMsIAorICAgICAgICAgICA4MywgICAgMzgsICAgIDM3LCAgICA2NCwgICAgNjMsICAgLTYwLCAgICAtNywgICAgODAsIAorICAgICAgICAgICA0OCwgIDcyNjQsICAgIC04LCAgIC03NCwgICAgLTksICAgLTg2LCAgLTEwMCwgIC0xMTIsIAorICAgICAgICAgLTEyOCwgIC0xMjYsIC03NTE3LCAtODM4MywgLTgyNjIsICAgIDE2LCAgICAyNiwgICAgNDAKKyAgICB9OworCisgICAgLy8gQXJyYXkgb2YgdGl0bGVjYXNlIGRpZmZlcmVuY2VzCisgICAgc3RhdGljIGNvbnN0IHNob3J0IFRDRElGRltdID0geworICAgICAgICAgICAgMywgICAgIDEsICAgICAwLCAgICAtMQorICAgIH07CisKKyAgICAvLyBBcnJheSBvZiBtaXJyb3JlZCBjaGFyYWN0ZXIgZGlmZmVyZW5jZXMKKyAgICBzdGF0aWMgY29uc3Qgc2hvcnQgTUlSUk9SX0RJRkZbXSA9IHsKKyAgICAgICAgICAgIDAsICAgICAxLCAgICAtMSwgICAgIDIsICAgIC0yLCAgICAxNiwgICAtMTYsICAgICAzLCAKKyAgICAgICAgICAgLTMsICAyMDE2LCAgIDEzOCwgIDE4MjQsICAyMTA0LCAgMjEwOCwgIDIxMDYsICAtMTM4LCAKKyAgICAgICAgICAgIDgsICAgICA3LCAgICAtOCwgICAgLTcsIC0xODI0LCAtMjAxNiwgLTIxMDQsIC0yMTA2LCAKKyAgICAgICAgLTIxMDgKKyAgICB9OworCisgICAvLyBBcnJheSBvZiBhbGwgcG9zc2libGUgbnVtZXJpYyB2YWx1ZXMKKyAgIHN0YXRpYyBjb25zdCBpbnQgTlVNRVJJQ1NbXSA9IHsKKyAgICAgICAgICAgIC0xLCAgICAgIDAsICAgICAgMSwgICAgICAyLCAgICAgIDMsICAgICAgNCwgICAgICA1LCAgICAgIDYsIAorICAgICAgICAgICAgIDcsICAgICAgOCwgICAgICA5LCAgICAgMTAsICAgICAxMSwgICAgIDEyLCAgICAgMTMsICAgICAxNCwgCisgICAgICAgICAgICAxNSwgICAgIDE2LCAgICAgMTcsICAgICAxOCwgICAgIDE5LCAgICAgMjAsICAgICAyMSwgICAgIDIyLCAKKyAgICAgICAgICAgIDIzLCAgICAgMjQsICAgICAyNSwgICAgIDI2LCAgICAgMjcsICAgICAyOCwgICAgIDI5LCAgICAgMzAsIAorICAgICAgICAgICAgMzEsICAgICAzMiwgICAgIDMzLCAgICAgMzQsICAgICAzNSwgICAgIC0yLCAgICAxMDAsICAgMTAwMCwgCisgICAgICAgICAgICA0MCwgICAgIDUwLCAgICAgNjAsICAgICA3MCwgICAgIDgwLCAgICAgOTAsICAxMDAwMCwgICAgNTAwLCAKKyAgICAgICAgICA1MDAwLCAgICAgMzYsICAgICAzNywgICAgIDM4LCAgICAgMzksICAgICA0MSwgICAgIDQyLCAgICAgNDMsIAorICAgICAgICAgICAgNDQsICAgICA0NSwgICAgIDQ2LCAgICAgNDcsICAgICA0OCwgICAgIDQ5LCAgICAyMDAsICAgIDMwMCwgCisgICAgICAgICAgIDQwMCwgICAgNjAwLCAgICA3MDAsICAgIDgwMCwgICAgOTAwLCAgIDIwMDAsICAgMzAwMCwgICA0MDAwLCAKKyAgICAgICAgICA2MDAwLCAgIDcwMDAsICAgODAwMCwgICA5MDAwLCAgMjAwMDAsICAzMDAwMCwgIDQwMDAwLCAgNTAwMDAsIAorICAgICAgICAgNjAwMDAsICA3MDAwMCwgIDgwMDAwLCAgOTAwMDAKKyAgICB9OworCisgICAgLy8gQWxsIHBvc3NpYmxlIHBhY2tlZCBkYXRhIHZhbHVlcywgbm8gZHVwbGljYXRlcworICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBQQUNLRURfREFUQVtdID0geworICAgICAgICAweDAwMDAwMDAwLCAweDAwMDAwMTJGLCAweDAwMDAwMTZGLCAweDAwMDAwMTRGLCAweDAwMDAwMThGLCAweDAwMDAwMThDLCAweDAwMDAwMUI4LCAweDAwMDAwMEI4LCAKKyAgICAgICAgMHgwMDAwMDBCQSwgMHgwMjAwMDVCNSwgMHgwNDAwMDVCNiwgMHgwMDAwMDA5OSwgMHgwMDAwMDBGOCwgMHgwMDAwMDA5NCwgMHgwMjAwMDA2OSwgMHgwNDAwMDA2OSwgCisgICAgICAgIDB4MDYwMDAwNjksIDB4MDgwMDAwNjksIDB4MEEwMDAwNjksIDB4MEMwMDAwNjksIDB4MEUwMDAwNjksIDB4MTAwMDAwNjksIDB4MTIwMDAwNjksIDB4MTQwMDAwNjksIAorICAgICAgICAweDA2MDAwNUI5LCAweDAwMDAwMUI5LCAweDA4MDAwNUI5LCAweDE2MDIwMDAxLCAweDE4MDIwMDAxLCAweDFBMDIwMDAxLCAweDFDMDIwMDAxLCAweDFFMDIwMDAxLCAKKyAgICAgICAgMHgyMDAyMDAwMSwgMHgyMjAyMDAwMSwgMHgyNDAyMDAwMSwgMHgyNjAyMDAwMSwgMHgyODAyMDAwMSwgMHgyQTAyMDAwMSwgMHgyQzAyMDAwMSwgMHgyRTAyMDAwMSwgCisgICAgICAgIDB4MzAwMjAwMDEsIDB4MzIwMjAwMDEsIDB4MzQwMjAwMDEsIDB4MzYwMjAwMDEsIDB4MzgwMjAwMDEsIDB4M0EwMjAwMDEsIDB4M0MwMjAwMDEsIDB4M0UwMjAwMDEsIAorICAgICAgICAweDQwMDIwMDAxLCAweDQyMDIwMDAxLCAweDQ0MDIwMDAxLCAweDQ2MDIwMDAxLCAweDQ4MDIwMDAxLCAweDA2MDAwNUI1LCAweDA4MDAwNUI2LCAweDAwMDAwMUJCLCAKKyAgICAgICAgMHgwMDAwMDFCNywgMHgxNjAwMDgwMiwgMHgxODAwMDgwMiwgMHgxQTAwMDgwMiwgMHgxQzAwMDgwMiwgMHgxRTAwMDgwMiwgMHgyMDAwMDgwMiwgMHgyMjAwMDgwMiwgCisgICAgICAgIDB4MjQwMDA4MDIsIDB4MjYwMDA4MDIsIDB4MjgwMDA4MDIsIDB4MkEwMDA4MDIsIDB4MkMwMDA4MDIsIDB4MkUwMDA4MDIsIDB4MzAwMDA4MDIsIDB4MzIwMDA4MDIsIAorICAgICAgICAweDM0MDAwODAyLCAweDM2MDAwODAyLCAweDM4MDAwODAyLCAweDNBMDAwODAyLCAweDNDMDAwODAyLCAweDNFMDAwODAyLCAweDQwMDAwODAyLCAweDQyMDAwODAyLCAKKyAgICAgICAgMHg0NDAwMDgwMiwgMHg0NjAwMDgwMiwgMHg0ODAwMDgwMiwgMHgwMDAwMDBFQywgMHgwMDAwMDFCQywgMHgwMDAwMDAwMiwgMHgwQTAwMDVCRCwgMHgwMDAwMDEzMCwgCisgICAgICAgIDB4MDAwMDAwQkMsIDB4MDAwMDAwQjksIDB4MDYwMDAwNkIsIDB4MDgwMDAwNkIsIDB4MDAwMDEwMDIsIDB4MDQwMDAwNkIsIDB4MEMwMDA1QkUsIDB4NEEwMDAxQUIsIAorICAgICAgICAweDAwMDIwMDAxLCAweDAwMDAwODAyLCAweDAwMDAxODAyLCAweDAwMDQwMDAxLCAweDAwMDYwMDAxLCAweDAwMDAyMDAyLCAweDAwMDgwMDAxLCAweDAwMEMwMDAxLCAKKyAgICAgICAgMHgwMDBFMDAwMSwgMHgwMDEwMDAwMSwgMHgwMDE0MDAwMSwgMHgwMDE2MDAwMSwgMHgwMDE4MDAwMSwgMHgwMDAwNDAwMiwgMHgwMDAwNDgwMiwgMHgwMDIwMDAwMSwgCisgICAgICAgIDB4MDAyMjAwMDEsIDB4MDAwMDAwMDUsIDB4MDBBNjAwMDEsIDB4MDE4MDU4MDIsIDB4MDEwNDIwMDMsIDB4MDAyODAwMDEsIDB4MDAyQzAwMDEsIDB4MDAwMDAwMDEsIAorICAgICAgICAweDAwMDAwMDAwLCAweDAwMDA3MDAyLCAweDAwMDA3ODAyLCAweDAwMDA5ODAyLCAweDAwMDBBODAyLCAweDAwMDBCODAyLCAweDAwMDBDMDAyLCAweDAwMDBDODAyLCAKKyAgICAgICAgMHgwMDAwRDAwMiwgMHgwMDAwMDAwNCwgMHgwMDAwMDFBNCwgMHgwMDAwMDEwNiwgMHgwMDMyMDAwMSwgMHgwMDM0MDAwMSwgMHgwMDM2MDAwMSwgMHgwMDM4MDAwMSwgCisgICAgICAgIDB4MDAwMEUwMDIsIDB4MDAwMEU4MDIsIDB4MDAwMEYwMDIsIDB4MDAwMEY4MDIsIDB4MDAwMTAwMDIsIDB4MDAwMTA4MDIsIDB4MDAwMTIwMDIsIDB4MDAwMTI4MDIsIAorICAgICAgICAweDAwMDEzODAyLCAweDAwM0EwMDAxLCAweDAwM0UwMDAxLCAweDAwMDEzMDAyLCAweDAwMDAwMDFDLCAweDAwMDAwMTA3LCAweDAwNDAwMDAxLCAweDAwMDAwMDE4LCAKKyAgICAgICAgMHgwMDAxNDgwMiwgMHgwMDAwMDFCNCwgMHgwMDAwMDAzOCwgMHgwMDAwMDAyNSwgMHgwMDAwMDA1MCwgMHgwMDAwMDA1OCwgMHgwMDAwMDA0NSwgMHgwMDAwMDA0NCwgCisgICAgICAgIDB4MDIwMDAwQzksIDB4MDYwMDAwQzksIDB4MEEwMDAwQzksIDB4MEUwMDAwQzksIDB4MTIwMDAwQzksIDB4MDAwMDAwRDgsIDB4MDAwMDAwNUMsIDB4MDAwMDAwMDgsIAorICAgICAgICAweDAyMDAwMDA5LCAweDA2MDAwMDA5LCAweDBBMDAwMDA5LCAweDBFMDAwMDA5LCAweDEyMDAwMDA5LCAweDA0MDAwMDBCLCAweDA4MDAwMDBCLCAweDAwMDAwMDBCLCAKKyAgICAgICAgMHgxNjAwMDAwQiwgMHg0RTAwMDAwQiwgMHgwMDAwMDAwNiwgMHg0QTAwMDAwQiwgMHgwMDAwMDFCNSwgMHgwMDQyMDAwMSwgMHgwNjAwMDAwQiwgMHgwQTAwMDAwQiwgCisgICAgICAgIDB4MEUwMDAwMEIsIDB4MTIwMDAwMEIsIDB4M0UwMDAwMEIsIDB4NTIwMDAwMEIsIDB4NTYwMDAwMEIsIDB4NUEwMDAwMEIsIDB4NUMwMDAwMEIsIDB4MDAwMDAxQjYsIAorICAgICAgICAweDI0MDAwMDBBLCAweDI4MDAwMDBBLCAweDAwMDAwMDEwLCAweDAyMDAwMUFCLCAweDA2MDAwMUFCLCAweDBBMDAwMUFCLCAweDBFMDAwMUFCLCAweDEyMDAwMUFCLCAKKyAgICAgICAgMHgwMDAwMDEwOCwgMHgwMDAxNTgwMiwgMHgwMDQ0MDAwMSwgMHgwMDAxNjAwMiwgMHgwMDAxNjgwMiwgMHgwMDAxNzAwMiwgMHgwMDAxNzgwMiwgMHgwMDAxODAwMiwgCisgICAgICAgIDB4MDAwMTg4MDIsIDB4MDA0NDAwMDMsIDB4MDA0NjAwMDEsIDB4MDA0ODAwMDMsIDB4MDAwMTk4MDIsIDB4MDA0QTAwMDEsIDB4MDA0QzAwMDEsIDB4MDA0RTAwMDEsIAorICAgICAgICAweDAwM0MwMDAxLCAweDAwNTAwMDAxLCAweDAwNTIwMDAxLCAweDAwMDAwMUJELCAweDAwMDAwMThELCAweDAwMDAwMUQwLCAweDAwMDAwMjUwLCAweDAwMDAwMjMwLCAKKyAgICAgICAgMHgwNDAwMDVCRSwgMHgwMDAwMDBGOSwgMHgwMjAwMDA2QiwgMHgwQTAwMDA2QiwgMHgwRTAwMDA2QiwgMHgxMjAwMDA2QiwgMHgwMDU0MDAwMSwgMHgwMDU2MDAwMSwgCisgICAgICAgIDB4MDAwMDA1QjksIDB4MDQ1QTAwMEEsIDB4MDg1QTAwMEEsIDB4MEM1QTAwMEEsIDB4MTA1QTAwMEEsIDB4MTQ1QTAwMEEsIDB4MTg1QTAwMEEsIDB4NTI1QTAwMEEsIAorICAgICAgICAweDVFNUEwMDBBLCAweDA0MDFBMDBBLCAweDA4MDFBMDBBLCAweDBDMDFBMDBBLCAweDEwMDFBMDBBLCAweDE0MDFBMDBBLCAweDE4MDFBMDBBLCAweDUyMDFBMDBBLCAKKyAgICAgICAgMHg1RTAxQTAwQSwgMHg0RTAwMDAwQSwgMHg1QzAwMDAwQSwgMHgwRTAwMDVCOSwgMHgxMDAwMDVCOSwgMHgwMjAwMDVCOSwgMHgwNDAwMDVCOSwgMHgxNjAwMDVCOSwgCisgICAgICAgIDB4MTgwMDA1QjksIDB4MUEwMDA1QjksIDB4MjAwMDA1QjksIDB4MjIwMDA1QjksIDB4MjQwMDA1QjksIDB4MjYwMDA1QjksIDB4MDQwMDAxQUIsIDB4MDgwMDAxQUIsIAorICAgICAgICAweDBDMDAwMUFCLCAweDEwMDAwMUFCLCAweDE0MDAwMUFCLCAweDE4MDAwMUFCLCAweDFDMDAwMUFCLCAweDIwMDAwMUFCLCAweDI0MDAwMUFCLCAweDI4MDAwMUFCLCAKKyAgICAgICAgMHgwQzAwMDA2QiwgMHgxMDAwMDA2QiwgMHgxNDAwMDA2QiwgMHgxODAwMDA2QiwgMHgxQzAwMDA2QiwgMHgyMDAwMDA2QiwgMHgyNDAwMDA2QiwgMHgyODAwMDA2QiwgCisgICAgICAgIDB4MDA1QzAwMUMsIDB4MDAwMUE4MUMsIDB4MUEwMDAxQUIsIDB4MUUwMDAxQUIsIDB4MjIwMDAxQUIsIDB4MjYwMDAxQUIsIDB4MkEwMDAxQUIsIDB4MTYwMDAxQUIsIAorICAgICAgICAweDAyMDAwNUI2LCAweDEwMDAwNUI2LCAweDI4MDAwNUI5LCAweDJDMDAwNUI5LCAweDMwMDAwNUI5LCAweDAwMDFCMDAyLCAweDAyMDAwNUJELCAweDA2MDAwMDBBLCAKKyAgICAgICAgMHgwQTAwMDAwQSwgMHgwRTAwMDAwQSwgMHgxMjAwMDAwQSwgMHgxNjAwMDAwQSwgMHgzRTAwMDAwQSwgMHgwQzAwMDAwQiwgMHgxMDAwMDAwQiwgMHgxNDAwMDAwQiwgCisgICAgICAgIDB4MkUwMDAxQUIsIDB4MzIwMDAxQUIsIDB4MzYwMDAxQUIsIDB4M0EwMDAxQUIsIDB4M0UwMDAxQUIsIDB4NDIwMDAxQUIsIDB4NDYwMDAxQUIsIDB4NjQwMDAxQUIsIAorICAgICAgICAweDY4MDAwMUFCLCAweDZBMDAwMUFCLCAweDZFMDAwMUFCLCAweDcyMDAwMUFCLCAweDc2MDAwMUFCLCAweDdBMDAwMUFCLCAweDAwMDAwMDEzLCAweDAwMDAwMDEyLCAKKyAgICAgICAgMHgwMDAwMDA1QSwgMHgwMDAwMDFCMCwgMHg3QzAwMDAwQiwgMHg4MDAwMDAwQiwgMHg4MjAwMDAwQiwgMHg4NjAwMDAwQiwgMHg4QzAwMDAwQiwgMHg2MDAwMDAwQiwgCisgICAgICAgIDB4OTIwMDAwMEIsIDB4OTYwMDAwMEIsIDB4OTgwMDAwMEIsIDB4OUMwMDAwMEIsIDB4QTAwMDAwMEIsIDB4QTQwMDAwMEIsIDB4NEEwMDAxQUEsIDB4MDQwMDAxQUEsIAorICAgICAgICAweDUyMDAwMUFBLCAweDYwMDAwMUFBLCAweDBDMDAwMUFBLCAweDVFMDAwMUFBLCAweDE2MDAwMUFBLCAweDRDMDAwMUFBLCAweDRFMDAwMUFBLCAweDlFMDAwMUFBLCAKKyAgICAgICAgMHgwNjAwMDFBQSwgMHg4ODAwMDAwQSwgMHgyQTAwMDFBQSwgMHgwMDVFMDAwMSwgMHgwMDAxQjgwMiwgMHgwNDAwMDAyQiwgMHgwODAwMDAyQiwgMHgxNjAwMDAyQiwgCisgICAgICAgIDB4NEMwMDAwMkIsIDB4MDAwMDI4MDIsIDB4MDAwMDMwMDIsIDB4MDAwQTAwMDEsIDB4MDAxMjAwMDEsIDB4MDAwMDM4MDIsIDB4MDAxQTAwMDEsIDB4MDAxQzAwMDEsIAorICAgICAgICAweDAwMUUwMDAxLCAweDAwMjQwMDAxLCAweDAwMDA1MDAyLCAweDAwMDA2MDAyLCAweDAwMkEwMDAxLCAweDAwMkUwMDAxLCAweDAwMzAwMDAxLCAweDAwMDA2ODAyLCAKKyAgICAgICAgMHgwMDAwODAwMiwgMHgwMDAwODgwMiwgMHgwMDAwOTAwMiwgMHgwMDAwQTAwMiwgMHgwMDAwQjAwMiwgMHgwMDAwRDkwNiwgMHgwMDAxMTAwMiwgMHgwMDAxMTgwMiwgCisgICAgICAgIDB4MDAwMTQwMDIsIDB4MDQwMDAwQzksIDB4MDgwMDAwQzksIDB4MEMwMDAwQzksIDB4MTAwMDAwQzksIDB4MTQwMDAwQzksIDB4MDQwMDAwMDksIDB4MDgwMDAwMDksIAorICAgICAgICAweDBDMDAwMDA5LCAweDEwMDAwMDA5LCAweDE0MDAwMDA5LCAweDIyMDAwMDBCLCAweDRDMDAwMDBCLCAweDJBMDAwMDBCLCAweDUwMDAwMDBCLCAweDU0MDAwMDBCLCAKKyAgICAgICAgMHg1ODAwMDAwQiwgMHgyNjAwMDAwQSwgMHgwMDAxNTAwMiwgMHgwMDAxOTAwMiwgMHgwMDAwMDAzMCwgMHgwMDAwMDFCRSwgMHgwMDAwMDE0RSwgMHgwMDAwMDIxMCwgCisgICAgICAgIDB4MDAwMDAxRjAsIDB4MDA1ODAwMDEsIDB4MDY1QTAwMEEsIDB4MEE1QTAwMEEsIDB4MEU1QTAwMEEsIDB4MTI1QTAwMEEsIDB4MTY1QTAwMEEsIDB4MUE1QTAwMEEsIAorICAgICAgICAweDRDNUEwMDBBLCAweDRFNUEwMDBBLCAweDA2MDFBMDBBLCAweDBBMDFBMDBBLCAweDBFMDFBMDBBLCAweDEyMDFBMDBBLCAweDE2MDFBMDBBLCAweDFBMDFBMDBBLCAKKyAgICAgICAgMHg0QzAxQTAwQSwgMHg0RTAxQTAwQSwgMHg2MDAwMDAwQSwgMHgwMDAwMDAwQSwgMHgxMjAwMDVCOSwgMHgxNDAwMDVCOSwgMHgxQzAwMDVCOSwgMHgxRTAwMDVCOSwgCisgICAgICAgIDB4MTYwMDAwNkIsIDB4MUEwMDAwNkIsIDB4MUUwMDAwNkIsIDB4MjIwMDAwNkIsIDB4MjYwMDAwNkIsIDB4MkEwMDAwNkIsIDB4MEUwMDA1QjUsIDB4MDQwMDA1QjUsIAorICAgICAgICAweDJBMDAwNUI5LCAweDJFMDAwNUI5LCAweDAyMDAwMDBBLCAweDA0MDAwMDBBLCAweDA4MDAwMDBBLCAweDBDMDAwMDBBLCAweDEwMDAwMDBBLCAweDE0MDAwMDBBLCAKKyAgICAgICAgMHgyQTAwMDAwQSwgMHgyQzAwMDFBQiwgMHgzMDAwMDFBQiwgMHgzNDAwMDFBQiwgMHgzODAwMDFBQiwgMHgzQzAwMDFBQiwgMHg0MDAwMDFBQiwgMHg0NDAwMDFBQiwgCisgICAgICAgIDB4NDgwMDAxQUIsIDB4NjIwMDAxQUIsIDB4NjYwMDAxQUIsIDB4NTAwMDAxQUIsIDB4NkMwMDAxQUIsIDB4NzAwMDAxQUIsIDB4NzQwMDAxQUIsIDB4NzgwMDAxQUIsIAorICAgICAgICAweDUyMDAwMUFCLCAweDdFMDAwMDBCLCAweDVFMDAwMDBCLCAweDg0MDAwMDBCLCAweDg4MDAwMDBCLCAweDhBMDAwMDBCLCAweDhFMDAwMDBCLCAweDkwMDAwMDBCLCAKKyAgICAgICAgMHg5NDAwMDAwQiwgMHg5QTAwMDAwQiwgMHg5RTAwMDAwQiwgMHhBMjAwMDAwQiwgMHhBNjAwMDAwQiwgMHg1QzAwMDFBQSwgMHgzRTAwMDFBQSwgMHg3RTAwMDFBQSwgCisgICAgICAgIDB4MDYwMDAwMkIsIDB4MEEwMDAwMkIsIDB4MkEwMDAwMkIsIDB4NEUwMDAwMkIsIDB4MDAwMDAwMTkKKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbGlicy91dGlscy9leGVjdXRhYmxlcGF0aF9kYXJ3aW4uY3BwIGIvbGlicy91dGlscy9leGVjdXRhYmxlcGF0aF9kYXJ3aW4uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlM2MzYTAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL2V4ZWN1dGFibGVwYXRoX2Rhcndpbi5jcHAKQEAgLTAsMCArMSwzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDx1dGlscy9leGVjdXRhYmxlcGF0aC5oPgorI2ltcG9ydCA8Q2FyYm9uL0NhcmJvbi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCit2b2lkIGV4ZWN1dGFibGVwYXRoKGNoYXIgc1tQQVRIX01BWF0pCit7CisgICAgUHJvY2Vzc1NlcmlhbE51bWJlciBwc247CisgICAgR2V0Q3VycmVudFByb2Nlc3MoJnBzbik7CisgICAgQ0ZEaWN0aW9uYXJ5UmVmIGRpY3Q7CisgICAgZGljdCA9IFByb2Nlc3NJbmZvcm1hdGlvbkNvcHlEaWN0aW9uYXJ5KCZwc24sIDB4ZmZmZmZmZmYpOworICAgIENGU3RyaW5nUmVmIHZhbHVlID0gKENGU3RyaW5nUmVmKUNGRGljdGlvbmFyeUdldFZhbHVlKGRpY3QsCisgICAgICAgICAgICAgICAgQ0ZTVFIoIkNGQnVuZGxlRXhlY3V0YWJsZSIpKTsKKyAgICBDRlN0cmluZ0dldENTdHJpbmcodmFsdWUsIHMsIFBBVEhfTUFYKzEsIGtDRlN0cmluZ0VuY29kaW5nVVRGOCk7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvZXhlY3V0YWJsZXBhdGhfbGludXguY3BwIGIvbGlicy91dGlscy9leGVjdXRhYmxlcGF0aF9saW51eC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjhkMmEzZAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvZXhlY3V0YWJsZXBhdGhfbGludXguY3BwCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8dXRpbHMvZXhlY3V0YWJsZXBhdGguaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorCit2b2lkIGV4ZWN1dGFibGVwYXRoKGNoYXIgZXhlW1BBVEhfTUFYXSkKK3sKKyAgICBjaGFyIHByb2NbMTAwXTsKKyAgICBzcHJpbnRmKHByb2MsICIvcHJvYy8lZC9leGUiLCBnZXRwaWQoKSk7CisgICAgCisgICAgaW50IGVyciA9IHJlYWRsaW5rKHByb2MsIGV4ZSwgUEFUSF9NQVgpOworfQorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL2Z1dGV4X3N5bmNocm8uYyBiL2xpYnMvdXRpbHMvZnV0ZXhfc3luY2hyby5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhMTk1MjAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL2Z1dGV4X3N5bmNocm8uYwpAQCAtMCwwICsxLDE3NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorCisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKyNpbmNsdWRlIDxzY2hlZC5oPgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKworI2luY2x1ZGUgPHByaXZhdGUvdXRpbHMvZnV0ZXhfc3luY2hyby5oPgorCisKKy8vIFRoaXMgZnV0ZXggZ2x1ZSBjb2RlIGlzIG5lZWQgb24gZGVza3RvcCBsaW51eCwgYnV0IGlzIGFscmVhZHkgcGFydCBvZiBiaW9uaWMuCisjaWYgIWRlZmluZWQoSEFWRV9GVVRFWF9XUkFQUEVSUykKKworI2luY2x1ZGUgPHN5cy9zeXNjYWxsLmg+Cit0eXBlZGVmIHVuc2lnbmVkIGludCB1MzI7CisjZGVmaW5lIGFzbWxpbmthZ2UKKyNkZWZpbmUgX191c2VyCisjaW5jbHVkZSA8bGludXgvZnV0ZXguaD4KKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKworCitpbnQgZnV0ZXggKGludCAqdWFkZHIsIGludCBvcCwgaW50IHZhbCwgY29uc3Qgc3RydWN0IHRpbWVzcGVjICp0aW1lb3V0LCBpbnQgKnVhZGRyMiwgaW50IHZhbDMpCit7CisgICAgaW50IGVyciA9IHN5c2NhbGwoU1lTX2Z1dGV4LCB1YWRkciwgb3AsIHZhbCwgdGltZW91dCwgdWFkZHIyLCB2YWwzKTsKKyAgICByZXR1cm4gZXJyID09IDAgPyAwIDogLWVycm5vOworfQorCitpbnQgX19mdXRleF93YWl0KHZvbGF0aWxlIHZvaWQgKmZ0eCwgaW50IHZhbCwgY29uc3Qgc3RydWN0IHRpbWVzcGVjICp0aW1lb3V0KQoreworICAgIHJldHVybiBmdXRleCgoaW50KilmdHgsIEZVVEVYX1dBSVQsIHZhbCwgdGltZW91dCwgTlVMTCwgMCk7Cit9CisKK2ludCBfX2Z1dGV4X3dha2Uodm9sYXRpbGUgdm9pZCAqZnR4LCBpbnQgY291bnQpCit7CisgICAgcmV0dXJuIGZ1dGV4KChpbnQqKWZ0eCwgRlVURVhfV0FLRSwgY291bnQsIE5VTEwsIE5VTEwsIDApOworfQorCitpbnQgX19hdG9taWNfY21weGNoZyhpbnQgb2xkLCBpbnQgX25ldywgdm9sYXRpbGUgaW50ICpwdHIpCit7CisgICAgcmV0dXJuIGFuZHJvaWRfYXRvbWljX2NtcHhjaGcob2xkLCBfbmV3LCBwdHIpOworfQorCitpbnQgX19hdG9taWNfc3dhcChpbnQgX25ldywgdm9sYXRpbGUgaW50ICpwdHIpCit7CisgICAgcmV0dXJuIGFuZHJvaWRfYXRvbWljX3N3YXAoX25ldywgcHRyKTsKK30KKworaW50IF9fYXRvbWljX2RlYyh2b2xhdGlsZSBpbnQgKnB0cikKK3sKKyAgICByZXR1cm4gYW5kcm9pZF9hdG9taWNfZGVjKHB0cik7Cit9CisKKyNlbHNlIC8vICFkZWZpbmVkKF9fYXJtX18pCisKK2ludCBfX2Z1dGV4X3dhaXQodm9sYXRpbGUgdm9pZCAqZnR4LCBpbnQgdmFsLCBjb25zdCBzdHJ1Y3QgdGltZXNwZWMgKnRpbWVvdXQpOworaW50IF9fZnV0ZXhfd2FrZSh2b2xhdGlsZSB2b2lkICpmdHgsIGludCBjb3VudCk7CisKK2ludCBfX2F0b21pY19jbXB4Y2hnKGludCBvbGQsIGludCBfbmV3LCB2b2xhdGlsZSBpbnQgKnB0cik7CitpbnQgX19hdG9taWNfc3dhcChpbnQgX25ldywgdm9sYXRpbGUgaW50ICpwdHIpOworaW50IF9fYXRvbWljX2RlYyh2b2xhdGlsZSBpbnQgKnB0cik7CisKKyNlbmRpZiAvLyAhZGVmaW5lZChIQVZFX0ZVVEVYX1dSQVBQRVJTKQorCisKKy8vIGxvY2sgc3RhdGVzCisvLworLy8gMDogdW5sb2NrZWQKKy8vIDE6IGxvY2tlZCwgbm8gd2FpdGVycworLy8gMjogbG9ja2VkLCBtYXliZSB3YWl0ZXJzCisKK3ZvaWQgZnV0ZXhfbXV0ZXhfaW5pdChmdXRleF9tdXRleF90ICptKQoreworICAgIG0tPnZhbHVlID0gMDsKK30KKworaW50IGZ1dGV4X211dGV4X2xvY2soZnV0ZXhfbXV0ZXhfdCAqbSwgdW5zaWduZWQgbXNlYykKK3sKKyAgICBpZihfX2F0b21pY19jbXB4Y2hnKDAsIDEsICZtLT52YWx1ZSkgPT0gMCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYobXNlYyA9PSBGVVRFWF9XQUlUX0lORklOSVRFKSB7CisgICAgICAgIHdoaWxlKF9fYXRvbWljX3N3YXAoMiwgJm0tPnZhbHVlKSAhPSAwKSB7CisgICAgICAgICAgICBfX2Z1dGV4X3dhaXQoJm0tPnZhbHVlLCAyLCAwKTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIHN0cnVjdCB0aW1lc3BlYyB0czsKKyAgICAgICAgdHMudHZfc2VjID0gbXNlYyAvIDEwMDA7CisgICAgICAgIHRzLnR2X25zZWMgPSAobXNlYyAlIDEwMDApICogMTAwMDAwMDsKKyAgICAgICAgd2hpbGUoX19hdG9taWNfc3dhcCgyLCAmbS0+dmFsdWUpICE9IDApIHsKKyAgICAgICAgICAgIGlmKF9fZnV0ZXhfd2FpdCgmbS0+dmFsdWUsIDIsICZ0cykgPT0gLUVUSU1FRE9VVCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworaW50IGZ1dGV4X211dGV4X3RyeWxvY2soZnV0ZXhfbXV0ZXhfdCAqbSkKK3sKKyAgICBpZihfX2F0b21pY19jbXB4Y2hnKDAsIDEsICZtLT52YWx1ZSkgPT0gMCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCit2b2lkIGZ1dGV4X211dGV4X3VubG9jayhmdXRleF9tdXRleF90ICptKQoreworICAgIGlmKF9fYXRvbWljX2RlYygmbS0+dmFsdWUpICE9IDEpIHsKKyAgICAgICAgbS0+dmFsdWUgPSAwOworICAgICAgICBfX2Z1dGV4X3dha2UoJm0tPnZhbHVlLCAxKTsKKyAgICB9Cit9CisKKy8qIFhYWCAqdGVjaG5pY2FsbHkqIHRoZXJlIGlzIGEgcmFjZSBjb25kaXRpb24gdGhhdCBjb3VsZCBhbGxvdworICogWFhYIGEgc2lnbmFsIHRvIGJlIG1pc3NlZC4gIElmIHRocmVhZCBBIGlzIHByZWVtcHRlZCBpbiBfd2FpdCgpCisgKiBYWFggYWZ0ZXIgdW5sb2NraW5nIHRoZSBtdXRleCBhbmQgYmVmb3JlIHdhaXRpbmcsIGFuZCBpZiBvdGhlcgorICogWFhYIHRocmVhZHMgY2FsbCBzaWduYWwgb3IgYnJvYWRjYXN0IFVJTlRfTUFYIHRpbWVzIChleGFjdGx5KSwKKyAqIFhYWCBiZWZvcmUgdGhyZWFkIEEgaXMgc2NoZWR1bGVkIGFnYWluIGFuZCBjYWxscyBmdXRleF93YWl0KCksCisgKiBYWFggdGhlbiB0aGUgc2lnbmFsIHdpbGwgYmUgbG9zdC4KKyAqLworCit2b2lkIGZ1dGV4X2NvbmRfaW5pdChmdXRleF9jb25kX3QgKmMpCit7CisgICAgYy0+dmFsdWUgPSAwOworfQorCitpbnQgZnV0ZXhfY29uZF93YWl0KGZ1dGV4X2NvbmRfdCAqYywgZnV0ZXhfbXV0ZXhfdCAqbSwgdW5zaWduZWQgbXNlYykKK3sKKyAgICBpZihtc2VjID09IEZVVEVYX1dBSVRfSU5GSU5JVEUpeworICAgICAgICBpbnQgb2xkdmFsdWUgPSBjLT52YWx1ZTsKKyAgICAgICAgZnV0ZXhfbXV0ZXhfdW5sb2NrKG0pOworICAgICAgICBfX2Z1dGV4X3dhaXQoJmMtPnZhbHVlLCBvbGR2YWx1ZSwgMCk7CisgICAgICAgIGZ1dGV4X211dGV4X2xvY2sobSwgRlVURVhfV0FJVF9JTkZJTklURSk7CisgICAgICAgIHJldHVybiAwOworICAgIH0gZWxzZSB7CisgICAgICAgIGludCBvbGR2YWx1ZSA9IGMtPnZhbHVlOworICAgICAgICBzdHJ1Y3QgdGltZXNwZWMgdHM7ICAgICAgICAKKyAgICAgICAgdHMudHZfc2VjID0gbXNlYyAvIDEwMDA7CisgICAgICAgIHRzLnR2X25zZWMgPSAobXNlYyAlIDEwMDApICogMTAwMDAwMDsKKyAgICAgICAgZnV0ZXhfbXV0ZXhfdW5sb2NrKG0pOworICAgICAgICBjb25zdCBpbnQgZXJyID0gX19mdXRleF93YWl0KCZjLT52YWx1ZSwgb2xkdmFsdWUsICZ0cyk7CisgICAgICAgIGZ1dGV4X211dGV4X2xvY2sobSwgRlVURVhfV0FJVF9JTkZJTklURSk7CisgICAgICAgIHJldHVybiBlcnI7CisgICAgfQorfQorCit2b2lkIGZ1dGV4X2NvbmRfc2lnbmFsKGZ1dGV4X2NvbmRfdCAqYykKK3sKKyAgICBfX2F0b21pY19kZWMoJmMtPnZhbHVlKTsKKyAgICBfX2Z1dGV4X3dha2UoJmMtPnZhbHVlLCAxKTsKK30KKwordm9pZCBmdXRleF9jb25kX2Jyb2FkY2FzdChmdXRleF9jb25kX3QgKmMpCit7CisgICAgX19hdG9taWNfZGVjKCZjLT52YWx1ZSk7CisgICAgX19mdXRleF93YWtlKCZjLT52YWx1ZSwgSU5UX01BWCk7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnMvdXRpbHMvbWlzYy5jcHAgYi9saWJzL3V0aWxzL21pc2MuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjODlkMTUKLS0tIC9kZXYvbnVsbAorKysgYi9saWJzL3V0aWxzL21pc2MuY3BwCkBAIC0wLDAgKzEsMTg1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA1IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8KKy8vIE1pc2NlbGxhbmVvdXMgdXRpbGl0eSBmdW5jdGlvbnMuCisvLworI2luY2x1ZGUgPHV0aWxzL21pc2MuaD4KKworI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvKgorICogTGlrZSBzdHJkdXAoKSwgYnV0IHVzZXMgQysrICJuZXciIG9wZXJhdG9yIGluc3RlYWQgb2YgbWFsbG9jLgorICovCitjaGFyKiBzdHJkdXBOZXcoY29uc3QgY2hhciogc3RyKQoreworICAgIGNoYXIqIG5ld1N0cjsKKyAgICBpbnQgbGVuOworCisgICAgaWYgKHN0ciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGxlbiA9IHN0cmxlbihzdHIpOworICAgIG5ld1N0ciA9IG5ldyBjaGFyW2xlbisxXTsKKyAgICBtZW1jcHkobmV3U3RyLCBzdHIsIGxlbisxKTsKKworICAgIHJldHVybiBuZXdTdHI7Cit9CisKKy8qCisgKiBDb25jYXRlbmF0ZSBhbiBhcmd1bWVudCB2ZWN0b3IuCisgKi8KK2NoYXIqIGNvbmNhdEFyZ3YoaW50IGFyZ2MsIGNvbnN0IGNoYXIqIGNvbnN0IGFyZ3ZbXSkKK3sKKyAgICBjaGFyKiBuZXdTdHIgPSBOVUxMOworICAgIGludCBsZW4sIHRvdGFsTGVuLCBwb3NuLCBpZHg7CisKKyAgICAvKgorICAgICAqIEZpcnN0LCBmaWd1cmUgb3V0IHRoZSB0b3RhbCBsZW5ndGguCisgICAgICovCisgICAgdG90YWxMZW4gPSBpZHggPSAwOworICAgIHdoaWxlICgxKSB7CisgICAgICAgIGlmIChpZHggPT0gYXJnYyB8fCBhcmd2W2lkeF0gPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBpZiAoaWR4KQorICAgICAgICAgICAgdG90YWxMZW4rKzsgIC8vIGxlYXZlIGEgc3BhY2UgYmV0d2VlbiBhcmdzCisgICAgICAgIHRvdGFsTGVuICs9IHN0cmxlbihhcmd2W2lkeF0pOworICAgICAgICBpZHgrKzsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFsbG9jIHRoZSBzdHJpbmcuCisgICAgICovCisgICAgbmV3U3RyID0gbmV3IGNoYXJbdG90YWxMZW4gKzFdOworICAgIGlmIChuZXdTdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKgorICAgICAqIEZpbmFsbHksIGFsbG9jYXRlIHRoZSBzdHJpbmcgYW5kIGNvcHkgZGF0YSBvdmVyLgorICAgICAqLworICAgIGlkeCA9IHBvc24gPSAwOworICAgIHdoaWxlICgxKSB7CisgICAgICAgIGlmIChpZHggPT0gYXJnYyB8fCBhcmd2W2lkeF0gPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBpZiAoaWR4KQorICAgICAgICAgICAgbmV3U3RyW3Bvc24rK10gPSAnICc7CisKKyAgICAgICAgbGVuID0gc3RybGVuKGFyZ3ZbaWR4XSk7CisgICAgICAgIG1lbWNweSgmbmV3U3RyW3Bvc25dLCBhcmd2W2lkeF0sIGxlbik7CisgICAgICAgIHBvc24gKz0gbGVuOworCisgICAgICAgIGlkeCsrOworICAgIH0KKworICAgIGFzc2VydChwb3NuID09IHRvdGFsTGVuKTsKKyAgICBuZXdTdHJbcG9zbl0gPSAnXDAnOworCisgICAgcmV0dXJuIG5ld1N0cjsKK30KKworLyoKKyAqIENvdW50IHRoZSAjb2YgYXJncyBpbiBhbiBhcmd1bWVudCB2ZWN0b3IuICBEb24ndCBjb3VudCB0aGUgZmluYWwgTlVMTC4KKyAqLworaW50IGNvdW50QXJndihjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pCit7CisgICAgaW50IGNvdW50ID0gMDsKKworICAgIHdoaWxlIChhcmd2W2NvdW50XSAhPSBOVUxMKQorICAgICAgICBjb3VudCsrOworCisgICAgcmV0dXJuIGNvdW50OworfQorCisKKyNpbmNsdWRlIDxzdGRpby5oPgorLyoKKyAqIEdldCBhIGZpbGUncyB0eXBlLgorICovCitGaWxlVHlwZSBnZXRGaWxlVHlwZShjb25zdCBjaGFyKiBmaWxlTmFtZSkKK3sKKyAgICBzdHJ1Y3Qgc3RhdCBzYjsKKworICAgIGlmIChzdGF0KGZpbGVOYW1lLCAmc2IpIDwgMCkgeworICAgICAgICBpZiAoZXJybm8gPT0gRU5PRU5UIHx8IGVycm5vID09IEVOT1RESVIpCisgICAgICAgICAgICByZXR1cm4ga0ZpbGVUeXBlTm9uZXhpc3RlbnQ7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJnZXRGaWxlVHlwZSBnb3QgZXJybm89JWQgb24gJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICBlcnJubywgZmlsZU5hbWUpOworICAgICAgICAgICAgcmV0dXJuIGtGaWxlVHlwZVVua25vd247CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoU19JU1JFRyhzYi5zdF9tb2RlKSkKKyAgICAgICAgICAgIHJldHVybiBrRmlsZVR5cGVSZWd1bGFyOworICAgICAgICBlbHNlIGlmIChTX0lTRElSKHNiLnN0X21vZGUpKQorICAgICAgICAgICAgcmV0dXJuIGtGaWxlVHlwZURpcmVjdG9yeTsKKyAgICAgICAgZWxzZSBpZiAoU19JU0NIUihzYi5zdF9tb2RlKSkKKyAgICAgICAgICAgIHJldHVybiBrRmlsZVR5cGVDaGFyRGV2OworICAgICAgICBlbHNlIGlmIChTX0lTQkxLKHNiLnN0X21vZGUpKQorICAgICAgICAgICAgcmV0dXJuIGtGaWxlVHlwZUJsb2NrRGV2OworICAgICAgICBlbHNlIGlmIChTX0lTRklGTyhzYi5zdF9tb2RlKSkKKyAgICAgICAgICAgIHJldHVybiBrRmlsZVR5cGVGaWZvOworI2lmZGVmIEhBVkVfU1lNTElOS1MgICAgICAgICAgICAKKyAgICAgICAgZWxzZSBpZiAoU19JU0xOSyhzYi5zdF9tb2RlKSkKKyAgICAgICAgICAgIHJldHVybiBrRmlsZVR5cGVTeW1saW5rOworICAgICAgICBlbHNlIGlmIChTX0lTU09DSyhzYi5zdF9tb2RlKSkKKyAgICAgICAgICAgIHJldHVybiBrRmlsZVR5cGVTb2NrZXQ7CisjZW5kaWYgICAgICAgICAgICAKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIGtGaWxlVHlwZVVua25vd247CisgICAgfQorfQorCisvKgorICogR2V0IGEgZmlsZSdzIG1vZGlmaWNhdGlvbiBkYXRlLgorICovCit0aW1lX3QgZ2V0RmlsZU1vZERhdGUoY29uc3QgY2hhciogZmlsZU5hbWUpCit7CisgICAgc3RydWN0IHN0YXQgc2I7CisKKyAgICBpZiAoc3RhdChmaWxlTmFtZSwgJnNiKSA8IDApCisgICAgICAgIHJldHVybiAodGltZV90KSAtMTsKKworICAgIHJldHVybiBzYi5zdF9tdGltZTsKK30KKworLyoKKyAqIFJvdW5kIHVwIHRvIHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMi4KKyAqCisgKiBGb3VuZCBvbiBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWwuCisgKi8KK3Vuc2lnbmVkIGludCByb3VuZFVwUG93ZXIyKHVuc2lnbmVkIGludCB2YWwpCit7CisgICAgdmFsLS07CisgICAgdmFsIHw9IHZhbCA+PiAxOworICAgIHZhbCB8PSB2YWwgPj4gMjsKKyAgICB2YWwgfD0gdmFsID4+IDQ7CisgICAgdmFsIHw9IHZhbCA+PiA4OworICAgIHZhbCB8PSB2YWwgPj4gMTY7CisgICAgdmFsKys7CisKKyAgICByZXR1cm4gdmFsOworfQorCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCmRpZmYgLS1naXQgYS9saWJzL3V0aWxzL3BvcnRlZC5jcHAgYi9saWJzL3V0aWxzL3BvcnRlZC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjU2ZTQ2ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnMvdXRpbHMvcG9ydGVkLmNwcApAQCAtMCwwICsxLDEwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vCisvLyBQb3J0cyBvZiBzdGFuZGFyZCBmdW5jdGlvbnMgdGhhdCBkb24ndCBleGlzdCBvbiBhIHNwZWNpZmljIHBsYXRmb3JtLgorLy8KKy8vIE5vdGUgdGhlc2UgYXJlIE5PVCBpbiB0aGUgImFuZHJvaWQiIG5hbWVzcGFjZS4KKy8vCisjaW5jbHVkZSA8dXRpbHMvcG9ydGVkLmg+CisKKyNpZiBkZWZpbmVkKE5FRURfR0VUVElNRU9GREFZKSB8fCBkZWZpbmVkKE5FRURfVVNMRUVQKQorIyBpbmNsdWRlIDxzeXMvdGltZS5oPgorIyBpbmNsdWRlIDx3aW5kb3dzLmg+CisjZW5kaWYKKworCisjaWYgZGVmaW5lZChORUVEX0dFVFRJTUVPRkRBWSkKKy8qCisgKiBSZXBsYWNlbWVudCBnZXR0aW1lb2ZkYXkoKSBmb3IgV2luZG93cyBlbnZpcm9ubWVudHMgKHByaW1hcmlseSBNaW5HVykuCisgKgorICogSWdub3JlcyAidHoiLgorICovCitpbnQgZ2V0dGltZW9mZGF5KHN0cnVjdCB0aW1ldmFsKiBwdHYsIHN0cnVjdCB0aW1lem9uZSogdHopCit7CisgICAgbG9uZyBsb25nIG5zVGltZTsgICAvLyB0aW1lIGluIDEwMG5zIHVuaXRzIHNpbmNlIEphbiAxIDE2MDEKKyAgICBGSUxFVElNRSBmdDsKKworICAgIGlmICh0eiAhPSBOVUxMKSB7CisgICAgICAgIC8vIG9oIHdlbGwKKyAgICB9CisKKyAgICA6OkdldFN5c3RlbVRpbWVBc0ZpbGVUaW1lKCZmdCk7CisgICAgbnNUaW1lID0gKGxvbmcgbG9uZykgZnQuZHdIaWdoRGF0ZVRpbWUgPDwgMzIgfAorICAgICAgICAgICAgIChsb25nIGxvbmcpIGZ0LmR3TG93RGF0ZVRpbWU7CisgICAgLy8gY29udmVydCB0byB0aW1lIGluIHVzZWMgc2luY2UgSmFuIDEgMTk3MAorICAgIHB0di0+dHZfdXNlYyA9IChsb25nKSAoKG5zVGltZSAvIDEwTEwpICUgMTAwMDAwMExMKTsKKyAgICBwdHYtPnR2X3NlYyA9IChsb25nKSAoKG5zVGltZSAtIDExNjQ0NDczNjAwMDAwMDAwMExMKSAvIDEwMDAwMDAwTEwpOworCisgICAgcmV0dXJuIDA7Cit9CisjZW5kaWYKKworI2lmIGRlZmluZWQoTkVFRF9VU0xFRVApCisvLworLy8gUmVwbGFjZW1lbnQgdXNsZWVwIGZvciBXaW5kb3dzIGVudmlyb25tZW50cyAocHJpbWFyaWx5IE1pbkdXKS4KKy8vCit2b2lkIHVzbGVlcCh1bnNpZ25lZCBsb25nIHVzZWMpCit7CisgICAgLy8gV2luMzIgQVBJIGZ1bmN0aW9uIFNsZWVwKCkgdGFrZXMgbWlsbGlzZWNvbmRzCisgICAgOjpTbGVlcCgodXNlYyArIDUwMCkgLyAxMDAwKTsKK30KKyNlbmRpZgorCisjaWYgMCAvL2RlZmluZWQoTkVFRF9QSVBFKQorLy8KKy8vIFJlcGxhY2VtZW50IHBpcGUoKSBjb21tYW5kIGZvciBNaW5HVworLy8KKy8vIFRoZSBfT19OT0lOSEVSSVQgZmxhZyBzZXRzIGJJbmhlcml0SGFuZGxlIHRvIEZBTFNFIGluIHRoZQorLy8gU2VjdXJpdHlBdHRyaWJ1dGVzIGFyZ3VtZW50IHRvIENyZWF0ZVBpcGUoKS4gIFRoaXMgbWVhbnMgdGhlIGhhbmRsZXMKKy8vIGFyZW4ndCBpbmhlcml0ZWQgd2hlbiBhIG5ldyBwcm9jZXNzIGlzIGNyZWF0ZWQuICBUaGUgZXhhbXBsZXMgSSd2ZSBzZWVuCisvLyB1c2UgaXQsIHBvc3NpYmx5IGJlY2F1c2UgdGhlcmUncyBhIGxvdCBvZiBqdW5rIGdvaW5nIG9uIGJlaGluZCB0aGUKKy8vIHNjZW5lcy4gIChJJ20gYXNzdW1pbmcgInByb2Nlc3MiIGFuZCAidGhyZWFkIiBhcmUgZGlmZmVyZW50IGhlcmUsIHNvCisvLyB3ZSBzaG91bGQgYmUgb2theSBzcGlubmluZyB1cCBhIHRocmVhZC4pICBUaGUgcmVjb21tZW5kZWQgcHJhY3RpY2UgaXMKKy8vIHRvIGR1cCgpIHRoZSBkZXNjcmlwdG9yIHlvdSB3YW50IHRoZSBjaGlsZCB0byBoYXZlLgorLy8KKy8vIEl0IGFwcGVhcnMgdGhhdCB1bm5hbWVkIHBpcGVzIGNhbid0IGRvIG5vbi1ibG9ja2luZyAoIm92ZXJsYXBwZWQiKSBJL08uCisvLyBZb3UgY2FuJ3QgdXNlIHNlbGVjdCgpIGVpdGhlciwgc2luY2UgdGhhdCBvbmx5IHdvcmtzIG9uIHNvY2tldHMuICBUaGUKKy8vIFdpbmRvd3MgQVBJIGNhbGxzIHRoYXQgYXJlIHVzZWZ1bCBoZXJlIGFsbCBvcGVyYXRlIG9uIGEgSEFORExFLCBub3QKKy8vIGFuIGludGVnZXIgZmlsZSBkZXNjcmlwdG9yLCBhbmQgSSBkb24ndCB0aGluayB5b3UgY2FuIGdldCB0aGVyZSBmcm9tCisvLyBoZXJlLiAgVGhlICJuYW1lZCBwaXBlIiBzdHVmZiBpcyBpbnNhbmUuCisvLworaW50IHBpcGUoaW50IGZpbGVkZXNbMl0pCit7CisgICAgcmV0dXJuIF9waXBlKGZpbGVkZXMsIDAsIF9PX0JJTkFSWSB8IF9PX05PSU5IRVJJVCk7Cit9CisjZW5kaWYKKworI2lmIGRlZmluZWQoTkVFRF9TRVRFTlYpCisvKgorICogTWluR1cgbGFja3MgdGhlc2UuICBGb3Igbm93LCBqdXN0IHN0dWIgdGhlbSBvdXQgc28gdGhlIGNvZGUgY29tcGlsZXMuCisgKi8KK2ludCBzZXRlbnYoY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogdmFsdWUsIGludCBvdmVyd3JpdGUpCit7CisgICAgcmV0dXJuIDA7Cit9Cit2b2lkIHVuc2V0ZW52KGNvbnN0IGNoYXIqIG5hbWUpCit7Cit9CitjaGFyKiBnZXRlbnYoY29uc3QgY2hhciogbmFtZSkKK3sKKyAgICByZXR1cm4gTlVMTDsKK30KKyNlbmRpZgpkaWZmIC0tZ2l0IGEvb3BlbmdsL2luY2x1ZGUvRUdML2VnbC5oIGIvb3BlbmdsL2luY2x1ZGUvRUdML2VnbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyNjk5NzYKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvaW5jbHVkZS9FR0wvZWdsLmgKQEAgLTAsMCArMSwzMzAgQEAKKy8qIC0qLSBtb2RlOiBjOyB0YWItd2lkdGg6IDg7IC0qLSAqLworLyogdmk6IHNldCBzdz00IHRzPTg6ICovCisvKiBSZWZlcmVuY2UgdmVyc2lvbiBvZiBlZ2wuaCBmb3IgRUdMIDEuNC4KKyAqICRSZXZpc2lvbjogNzI0NCAkIG9uICREYXRlOiAyMDA5LTAxLTIwIDE3OjA2OjU5IC0wODAwIChUdWUsIDIwIEphbiAyMDA5KSAkCisgKi8KKworLyoKKyoqIENvcHlyaWdodCAoYykgMjAwNy0yMDA5IFRoZSBLaHJvbm9zIEdyb3VwIEluYy4KKyoqCisqKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQorKiogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZC9vciBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQorKiogIk1hdGVyaWFscyIpLCB0byBkZWFsIGluIHRoZSBNYXRlcmlhbHMgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCisqKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCisqKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIE1hdGVyaWFscywgYW5kIHRvCisqKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBNYXRlcmlhbHMgYXJlIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bworKiogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorKioKKyoqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkCisqKiBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBNYXRlcmlhbHMuCisqKgorKiogVEhFIE1BVEVSSUFMUyBBUkUgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKyoqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgorKiogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULgorKiogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkKKyoqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCisqKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQorKiogTUFURVJJQUxTIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIE1BVEVSSUFMUy4KKyovCisKKyNpZm5kZWYgX19lZ2xfaF8KKyNkZWZpbmUgX19lZ2xfaF8KKworLyogQWxsIHBsYXRmb3JtLWRlcGVuZGVudCB0eXBlcyBhbmQgbWFjcm8gYm9pbGVycGxhdGUgKHN1Y2ggYXMgRUdMQVBJCisgKiBhbmQgRUdMQVBJRU5UUlkpIHNob3VsZCBnbyBpbiBlZ2xwbGF0Zm9ybS5oLgorICovCisjaW5jbHVkZSA8RUdML2VnbHBsYXRmb3JtLmg+CisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyogRUdMIFR5cGVzICovCisvKiBFR0xpbnQgaXMgZGVmaW5lZCBpbiBlZ2xwbGF0Zm9ybS5oICovCit0eXBlZGVmIHVuc2lnbmVkIGludCBFR0xCb29sZWFuOwordHlwZWRlZiB1bnNpZ25lZCBpbnQgRUdMZW51bTsKK3R5cGVkZWYgdm9pZCAqRUdMQ29uZmlnOwordHlwZWRlZiB2b2lkICpFR0xDb250ZXh0OwordHlwZWRlZiB2b2lkICpFR0xEaXNwbGF5OwordHlwZWRlZiB2b2lkICpFR0xTdXJmYWNlOwordHlwZWRlZiB2b2lkICpFR0xDbGllbnRCdWZmZXI7CisKKy8qIEVHTCBWZXJzaW9uaW5nICovCisjZGVmaW5lIEVHTF9WRVJTSU9OXzFfMAkJCTEKKyNkZWZpbmUgRUdMX1ZFUlNJT05fMV8xCQkJMQorI2RlZmluZSBFR0xfVkVSU0lPTl8xXzIJCQkxCisjZGVmaW5lIEVHTF9WRVJTSU9OXzFfMwkJCTEKKyNkZWZpbmUgRUdMX1ZFUlNJT05fMV80CQkJMQorCisvKiBFR0wgRW51bWVyYW50cy4gQml0bWFza3MgYW5kIG90aGVyIGV4Y2VwdGlvbmFsIGNhc2VzIGFzaWRlLCBtb3N0CisgKiBlbnVtcyBhcmUgYXNzaWduZWQgdW5pcXVlIHZhbHVlcyBzdGFydGluZyBhdCAweDMwMDAuCisgKi8KKworLyogRUdMIGFsaWFzZXMgKi8KKyNkZWZpbmUgRUdMX0ZBTFNFCQkJMAorI2RlZmluZSBFR0xfVFJVRQkJCTEKKworLyogT3V0LW9mLWJhbmQgaGFuZGxlIHZhbHVlcyAqLworI2RlZmluZSBFR0xfREVGQVVMVF9ESVNQTEFZCQkoKEVHTE5hdGl2ZURpc3BsYXlUeXBlKTApCisjZGVmaW5lIEVHTF9OT19DT05URVhUCQkJKChFR0xDb250ZXh0KTApCisjZGVmaW5lIEVHTF9OT19ESVNQTEFZCQkJKChFR0xEaXNwbGF5KTApCisjZGVmaW5lIEVHTF9OT19TVVJGQUNFCQkJKChFR0xTdXJmYWNlKTApCisKKy8qIE91dC1vZi1iYW5kIGF0dHJpYnV0ZSB2YWx1ZSAqLworI2RlZmluZSBFR0xfRE9OVF9DQVJFCQkJKChFR0xpbnQpLTEpCisKKy8qIEVycm9ycyAvIEdldEVycm9yIHJldHVybiB2YWx1ZXMgKi8KKyNkZWZpbmUgRUdMX1NVQ0NFU1MJCQkweDMwMDAKKyNkZWZpbmUgRUdMX05PVF9JTklUSUFMSVpFRAkJMHgzMDAxCisjZGVmaW5lIEVHTF9CQURfQUNDRVNTCQkJMHgzMDAyCisjZGVmaW5lIEVHTF9CQURfQUxMT0MJCQkweDMwMDMKKyNkZWZpbmUgRUdMX0JBRF9BVFRSSUJVVEUJCTB4MzAwNAorI2RlZmluZSBFR0xfQkFEX0NPTkZJRwkJCTB4MzAwNQorI2RlZmluZSBFR0xfQkFEX0NPTlRFWFQJCQkweDMwMDYKKyNkZWZpbmUgRUdMX0JBRF9DVVJSRU5UX1NVUkZBQ0UJCTB4MzAwNworI2RlZmluZSBFR0xfQkFEX0RJU1BMQVkJCQkweDMwMDgKKyNkZWZpbmUgRUdMX0JBRF9NQVRDSAkJCTB4MzAwOQorI2RlZmluZSBFR0xfQkFEX05BVElWRV9QSVhNQVAJCTB4MzAwQQorI2RlZmluZSBFR0xfQkFEX05BVElWRV9XSU5ET1cJCTB4MzAwQgorI2RlZmluZSBFR0xfQkFEX1BBUkFNRVRFUgkJMHgzMDBDCisjZGVmaW5lIEVHTF9CQURfU1VSRkFDRQkJCTB4MzAwRAorI2RlZmluZSBFR0xfQ09OVEVYVF9MT1NUCQkweDMwMEUJLyogRUdMIDEuMSAtIElNR19wb3dlcl9tYW5hZ2VtZW50ICovCisKKy8qIFJlc2VydmVkIDB4MzAwRi0weDMwMUYgZm9yIGFkZGl0aW9uYWwgZXJyb3JzICovCisKKy8qIENvbmZpZyBhdHRyaWJ1dGVzICovCisjZGVmaW5lIEVHTF9CVUZGRVJfU0laRQkJCTB4MzAyMAorI2RlZmluZSBFR0xfQUxQSEFfU0laRQkJCTB4MzAyMQorI2RlZmluZSBFR0xfQkxVRV9TSVpFCQkJMHgzMDIyCisjZGVmaW5lIEVHTF9HUkVFTl9TSVpFCQkJMHgzMDIzCisjZGVmaW5lIEVHTF9SRURfU0laRQkJCTB4MzAyNAorI2RlZmluZSBFR0xfREVQVEhfU0laRQkJCTB4MzAyNQorI2RlZmluZSBFR0xfU1RFTkNJTF9TSVpFCQkweDMwMjYKKyNkZWZpbmUgRUdMX0NPTkZJR19DQVZFQVQJCTB4MzAyNworI2RlZmluZSBFR0xfQ09ORklHX0lECQkJMHgzMDI4CisjZGVmaW5lIEVHTF9MRVZFTAkJCTB4MzAyOQorI2RlZmluZSBFR0xfTUFYX1BCVUZGRVJfSEVJR0hUCQkweDMwMkEKKyNkZWZpbmUgRUdMX01BWF9QQlVGRkVSX1BJWEVMUwkJMHgzMDJCCisjZGVmaW5lIEVHTF9NQVhfUEJVRkZFUl9XSURUSAkJMHgzMDJDCisjZGVmaW5lIEVHTF9OQVRJVkVfUkVOREVSQUJMRQkJMHgzMDJECisjZGVmaW5lIEVHTF9OQVRJVkVfVklTVUFMX0lECQkweDMwMkUKKyNkZWZpbmUgRUdMX05BVElWRV9WSVNVQUxfVFlQRQkJMHgzMDJGCisjZGVmaW5lIEVHTF9QUkVTRVJWRURfUkVTT1VSQ0VTCQkweDMwMzAKKyNkZWZpbmUgRUdMX1NBTVBMRVMJCQkweDMwMzEKKyNkZWZpbmUgRUdMX1NBTVBMRV9CVUZGRVJTCQkweDMwMzIKKyNkZWZpbmUgRUdMX1NVUkZBQ0VfVFlQRQkJMHgzMDMzCisjZGVmaW5lIEVHTF9UUkFOU1BBUkVOVF9UWVBFCQkweDMwMzQKKyNkZWZpbmUgRUdMX1RSQU5TUEFSRU5UX0JMVUVfVkFMVUUJMHgzMDM1CisjZGVmaW5lIEVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRQkweDMwMzYKKyNkZWZpbmUgRUdMX1RSQU5TUEFSRU5UX1JFRF9WQUxVRQkweDMwMzcKKyNkZWZpbmUgRUdMX05PTkUJCQkweDMwMzgJLyogQXR0cmliIGxpc3QgdGVybWluYXRvciAqLworI2RlZmluZSBFR0xfQklORF9UT19URVhUVVJFX1JHQgkJMHgzMDM5CisjZGVmaW5lIEVHTF9CSU5EX1RPX1RFWFRVUkVfUkdCQQkweDMwM0EKKyNkZWZpbmUgRUdMX01JTl9TV0FQX0lOVEVSVkFMCQkweDMwM0IKKyNkZWZpbmUgRUdMX01BWF9TV0FQX0lOVEVSVkFMCQkweDMwM0MKKyNkZWZpbmUgRUdMX0xVTUlOQU5DRV9TSVpFCQkweDMwM0QKKyNkZWZpbmUgRUdMX0FMUEhBX01BU0tfU0laRQkJMHgzMDNFCisjZGVmaW5lIEVHTF9DT0xPUl9CVUZGRVJfVFlQRQkJMHgzMDNGCisjZGVmaW5lIEVHTF9SRU5ERVJBQkxFX1RZUEUJCTB4MzA0MAorI2RlZmluZSBFR0xfTUFUQ0hfTkFUSVZFX1BJWE1BUAkJMHgzMDQxCS8qIFBzZXVkby1hdHRyaWJ1dGUgKG5vdCBxdWVyeWFibGUpICovCisjZGVmaW5lIEVHTF9DT05GT1JNQU5UCQkJMHgzMDQyCisKKy8qIFJlc2VydmVkIDB4MzA0MS0weDMwNEYgZm9yIGFkZGl0aW9uYWwgY29uZmlnIGF0dHJpYnV0ZXMgKi8KKworLyogQ29uZmlnIGF0dHJpYnV0ZSB2YWx1ZXMgKi8KKyNkZWZpbmUgRUdMX1NMT1dfQ09ORklHCQkJMHgzMDUwCS8qIEVHTF9DT05GSUdfQ0FWRUFUIHZhbHVlICovCisjZGVmaW5lIEVHTF9OT05fQ09ORk9STUFOVF9DT05GSUcJMHgzMDUxCS8qIEVHTF9DT05GSUdfQ0FWRUFUIHZhbHVlICovCisjZGVmaW5lIEVHTF9UUkFOU1BBUkVOVF9SR0IJCTB4MzA1MgkvKiBFR0xfVFJBTlNQQVJFTlRfVFlQRSB2YWx1ZSAqLworI2RlZmluZSBFR0xfUkdCX0JVRkZFUgkJCTB4MzA4RQkvKiBFR0xfQ09MT1JfQlVGRkVSX1RZUEUgdmFsdWUgKi8KKyNkZWZpbmUgRUdMX0xVTUlOQU5DRV9CVUZGRVIJCTB4MzA4RgkvKiBFR0xfQ09MT1JfQlVGRkVSX1RZUEUgdmFsdWUgKi8KKworLyogTW9yZSBjb25maWcgYXR0cmlidXRlIHZhbHVlcywgZm9yIEVHTF9URVhUVVJFX0ZPUk1BVCAqLworI2RlZmluZSBFR0xfTk9fVEVYVFVSRQkJCTB4MzA1QworI2RlZmluZSBFR0xfVEVYVFVSRV9SR0IJCQkweDMwNUQKKyNkZWZpbmUgRUdMX1RFWFRVUkVfUkdCQQkJMHgzMDVFCisjZGVmaW5lIEVHTF9URVhUVVJFXzJECQkJMHgzMDVGCisKKy8qIENvbmZpZyBhdHRyaWJ1dGUgbWFzayBiaXRzICovCisjZGVmaW5lIEVHTF9QQlVGRkVSX0JJVAkJCTB4MDAwMQkvKiBFR0xfU1VSRkFDRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfUElYTUFQX0JJVAkJCTB4MDAwMgkvKiBFR0xfU1VSRkFDRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfV0lORE9XX0JJVAkJCTB4MDAwNAkvKiBFR0xfU1VSRkFDRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfVkdfQ09MT1JTUEFDRV9MSU5FQVJfQklUCTB4MDAyMAkvKiBFR0xfU1VSRkFDRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfVkdfQUxQSEFfRk9STUFUX1BSRV9CSVQJMHgwMDQwCS8qIEVHTF9TVVJGQUNFX1RZUEUgbWFzayBiaXRzICovCisjZGVmaW5lIEVHTF9NVUxUSVNBTVBMRV9SRVNPTFZFX0JPWF9CSVQgMHgwMjAwCS8qIEVHTF9TVVJGQUNFX1RZUEUgbWFzayBiaXRzICovCisjZGVmaW5lIEVHTF9TV0FQX0JFSEFWSU9SX1BSRVNFUlZFRF9CSVQgMHgwNDAwCS8qIEVHTF9TVVJGQUNFX1RZUEUgbWFzayBiaXRzICovCisKKyNkZWZpbmUgRUdMX09QRU5HTF9FU19CSVQJCTB4MDAwMQkvKiBFR0xfUkVOREVSQUJMRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfT1BFTlZHX0JJVAkJCTB4MDAwMgkvKiBFR0xfUkVOREVSQUJMRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfT1BFTkdMX0VTMl9CSVQJCTB4MDAwNAkvKiBFR0xfUkVOREVSQUJMRV9UWVBFIG1hc2sgYml0cyAqLworI2RlZmluZSBFR0xfT1BFTkdMX0JJVAkJCTB4MDAwOAkvKiBFR0xfUkVOREVSQUJMRV9UWVBFIG1hc2sgYml0cyAqLworCisvKiBRdWVyeVN0cmluZyB0YXJnZXRzICovCisjZGVmaW5lIEVHTF9WRU5ET1IJCQkweDMwNTMKKyNkZWZpbmUgRUdMX1ZFUlNJT04JCQkweDMwNTQKKyNkZWZpbmUgRUdMX0VYVEVOU0lPTlMJCQkweDMwNTUKKyNkZWZpbmUgRUdMX0NMSUVOVF9BUElTCQkJMHgzMDhECisKKy8qIFF1ZXJ5U3VyZmFjZSAvIFN1cmZhY2VBdHRyaWIgLyBDcmVhdGVQYnVmZmVyU3VyZmFjZSB0YXJnZXRzICovCisjZGVmaW5lIEVHTF9IRUlHSFQJCQkweDMwNTYKKyNkZWZpbmUgRUdMX1dJRFRICQkJMHgzMDU3CisjZGVmaW5lIEVHTF9MQVJHRVNUX1BCVUZGRVIJCTB4MzA1OAorI2RlZmluZSBFR0xfVEVYVFVSRV9GT1JNQVQJCTB4MzA4MAorI2RlZmluZSBFR0xfVEVYVFVSRV9UQVJHRVQJCTB4MzA4MQorI2RlZmluZSBFR0xfTUlQTUFQX1RFWFRVUkUJCTB4MzA4MgorI2RlZmluZSBFR0xfTUlQTUFQX0xFVkVMCQkweDMwODMKKyNkZWZpbmUgRUdMX1JFTkRFUl9CVUZGRVIJCTB4MzA4NgorI2RlZmluZSBFR0xfVkdfQ09MT1JTUEFDRQkJMHgzMDg3CisjZGVmaW5lIEVHTF9WR19BTFBIQV9GT1JNQVQJCTB4MzA4OAorI2RlZmluZSBFR0xfSE9SSVpPTlRBTF9SRVNPTFVUSU9OCTB4MzA5MAorI2RlZmluZSBFR0xfVkVSVElDQUxfUkVTT0xVVElPTgkJMHgzMDkxCisjZGVmaW5lIEVHTF9QSVhFTF9BU1BFQ1RfUkFUSU8JCTB4MzA5MgorI2RlZmluZSBFR0xfU1dBUF9CRUhBVklPUgkJMHgzMDkzCisjZGVmaW5lIEVHTF9NVUxUSVNBTVBMRV9SRVNPTFZFCQkweDMwOTkKKworLyogRUdMX1JFTkRFUl9CVUZGRVIgdmFsdWVzIC8gQmluZFRleEltYWdlIC8gUmVsZWFzZVRleEltYWdlIGJ1ZmZlciB0YXJnZXRzICovCisjZGVmaW5lIEVHTF9CQUNLX0JVRkZFUgkJCTB4MzA4NAorI2RlZmluZSBFR0xfU0lOR0xFX0JVRkZFUgkJMHgzMDg1CisKKy8qIE9wZW5WRyBjb2xvciBzcGFjZXMgKi8KKyNkZWZpbmUgRUdMX1ZHX0NPTE9SU1BBQ0Vfc1JHQgkJMHgzMDg5CS8qIEVHTF9WR19DT0xPUlNQQUNFIHZhbHVlICovCisjZGVmaW5lIEVHTF9WR19DT0xPUlNQQUNFX0xJTkVBUgkweDMwOEEJLyogRUdMX1ZHX0NPTE9SU1BBQ0UgdmFsdWUgKi8KKworLyogT3BlblZHIGFscGhhIGZvcm1hdHMgKi8KKyNkZWZpbmUgRUdMX1ZHX0FMUEhBX0ZPUk1BVF9OT05QUkUJMHgzMDhCCS8qIEVHTF9BTFBIQV9GT1JNQVQgdmFsdWUgKi8KKyNkZWZpbmUgRUdMX1ZHX0FMUEhBX0ZPUk1BVF9QUkUJCTB4MzA4QwkvKiBFR0xfQUxQSEFfRk9STUFUIHZhbHVlICovCisKKy8qIENvbnN0YW50IHNjYWxlIGZhY3RvciBieSB3aGljaCBmcmFjdGlvbmFsIGRpc3BsYXkgcmVzb2x1dGlvbnMgJgorICogYXNwZWN0IHJhdGlvIGFyZSBzY2FsZWQgd2hlbiBxdWVyaWVkIGFzIGludGVnZXIgdmFsdWVzLgorICovCisjZGVmaW5lIEVHTF9ESVNQTEFZX1NDQUxJTkcJCTEwMDAwCisKKy8qIFVua25vd24gZGlzcGxheSByZXNvbHV0aW9uL2FzcGVjdCByYXRpbyAqLworI2RlZmluZSBFR0xfVU5LTk9XTgkJCSgoRUdMaW50KS0xKQorCisvKiBCYWNrIGJ1ZmZlciBzd2FwIGJlaGF2aW9ycyAqLworI2RlZmluZSBFR0xfQlVGRkVSX1BSRVNFUlZFRAkJMHgzMDk0CS8qIEVHTF9TV0FQX0JFSEFWSU9SIHZhbHVlICovCisjZGVmaW5lIEVHTF9CVUZGRVJfREVTVFJPWUVECQkweDMwOTUJLyogRUdMX1NXQVBfQkVIQVZJT1IgdmFsdWUgKi8KKworLyogQ3JlYXRlUGJ1ZmZlckZyb21DbGllbnRCdWZmZXIgYnVmZmVyIHR5cGVzICovCisjZGVmaW5lIEVHTF9PUEVOVkdfSU1BR0UJCTB4MzA5NgorCisvKiBRdWVyeUNvbnRleHQgdGFyZ2V0cyAqLworI2RlZmluZSBFR0xfQ09OVEVYVF9DTElFTlRfVFlQRQkJMHgzMDk3CisKKy8qIENyZWF0ZUNvbnRleHQgYXR0cmlidXRlcyAqLworI2RlZmluZSBFR0xfQ09OVEVYVF9DTElFTlRfVkVSU0lPTgkweDMwOTgKKworLyogTXVsdGlzYW1wbGUgcmVzb2x1dGlvbiBiZWhhdmlvcnMgKi8KKyNkZWZpbmUgRUdMX01VTFRJU0FNUExFX1JFU09MVkVfREVGQVVMVCAweDMwOUEJLyogRUdMX01VTFRJU0FNUExFX1JFU09MVkUgdmFsdWUgKi8KKyNkZWZpbmUgRUdMX01VTFRJU0FNUExFX1JFU09MVkVfQk9YCTB4MzA5QgkvKiBFR0xfTVVMVElTQU1QTEVfUkVTT0xWRSB2YWx1ZSAqLworCisvKiBCaW5kQVBJL1F1ZXJ5QVBJIHRhcmdldHMgKi8KKyNkZWZpbmUgRUdMX09QRU5HTF9FU19BUEkJCTB4MzBBMAorI2RlZmluZSBFR0xfT1BFTlZHX0FQSQkJCTB4MzBBMQorI2RlZmluZSBFR0xfT1BFTkdMX0FQSQkJCTB4MzBBMgorCisvKiBHZXRDdXJyZW50U3VyZmFjZSB0YXJnZXRzICovCisjZGVmaW5lIEVHTF9EUkFXCQkJMHgzMDU5CisjZGVmaW5lIEVHTF9SRUFECQkJMHgzMDVBCisKKy8qIFdhaXROYXRpdmUgZW5naW5lcyAqLworI2RlZmluZSBFR0xfQ09SRV9OQVRJVkVfRU5HSU5FCQkweDMwNUIKKworLyogRUdMIDEuMiB0b2tlbnMgcmVuYW1lZCBmb3IgY29uc2lzdGVuY3kgaW4gRUdMIDEuMyAqLworI2RlZmluZSBFR0xfQ09MT1JTUEFDRQkJCUVHTF9WR19DT0xPUlNQQUNFCisjZGVmaW5lIEVHTF9BTFBIQV9GT1JNQVQJCUVHTF9WR19BTFBIQV9GT1JNQVQKKyNkZWZpbmUgRUdMX0NPTE9SU1BBQ0Vfc1JHQgkJRUdMX1ZHX0NPTE9SU1BBQ0Vfc1JHQgorI2RlZmluZSBFR0xfQ09MT1JTUEFDRV9MSU5FQVIJCUVHTF9WR19DT0xPUlNQQUNFX0xJTkVBUgorI2RlZmluZSBFR0xfQUxQSEFfRk9STUFUX05PTlBSRQkJRUdMX1ZHX0FMUEhBX0ZPUk1BVF9OT05QUkUKKyNkZWZpbmUgRUdMX0FMUEhBX0ZPUk1BVF9QUkUJCUVHTF9WR19BTFBIQV9GT1JNQVRfUFJFCisKKy8qIEVHTCBleHRlbnNpb25zIG11c3QgcmVxdWVzdCBlbnVtIGJsb2NrcyBmcm9tIHRoZSBLaHJvbm9zCisgKiBBUEkgUmVnaXN0cmFyLCB3aG8gbWFpbnRhaW5zIHRoZSBlbnVtZXJhbnQgcmVnaXN0cnkuIFN1Ym1pdAorICogYSBidWcgaW4gS2hyb25vcyBCdWd6aWxsYSBhZ2FpbnN0IHRhc2sgIlJlZ2lzdHJ5Ii4KKyAqLworCisKKworLyogRUdMIEZ1bmN0aW9ucyAqLworCitFR0xBUEkgRUdMaW50IEVHTEFQSUVOVFJZIGVnbEdldEVycm9yKHZvaWQpOworCitFR0xBUEkgRUdMRGlzcGxheSBFR0xBUElFTlRSWSBlZ2xHZXREaXNwbGF5KEVHTE5hdGl2ZURpc3BsYXlUeXBlIGRpc3BsYXlfaWQpOworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsSW5pdGlhbGl6ZShFR0xEaXNwbGF5IGRweSwgRUdMaW50ICptYWpvciwgRUdMaW50ICptaW5vcik7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xUZXJtaW5hdGUoRUdMRGlzcGxheSBkcHkpOworCitFR0xBUEkgY29uc3QgY2hhciAqIEVHTEFQSUVOVFJZIGVnbFF1ZXJ5U3RyaW5nKEVHTERpc3BsYXkgZHB5LCBFR0xpbnQgbmFtZSk7CisKK0VHTEFQSSBFR0xCb29sZWFuIEVHTEFQSUVOVFJZIGVnbEdldENvbmZpZ3MoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyAqY29uZmlncywKKwkJCSBFR0xpbnQgY29uZmlnX3NpemUsIEVHTGludCAqbnVtX2NvbmZpZyk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xDaG9vc2VDb25maWcoRUdMRGlzcGxheSBkcHksIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QsCisJCQkgICBFR0xDb25maWcgKmNvbmZpZ3MsIEVHTGludCBjb25maWdfc2l6ZSwKKwkJCSAgIEVHTGludCAqbnVtX2NvbmZpZyk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xHZXRDb25maWdBdHRyaWIoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisJCQkgICAgICBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgKnZhbHVlKTsKKworRUdMQVBJIEVHTFN1cmZhY2UgRUdMQVBJRU5UUlkgZWdsQ3JlYXRlV2luZG93U3VyZmFjZShFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKwkJCQkgIEVHTE5hdGl2ZVdpbmRvd1R5cGUgd2luLAorCQkJCSAgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCk7CitFR0xBUEkgRUdMU3VyZmFjZSBFR0xBUElFTlRSWSBlZ2xDcmVhdGVQYnVmZmVyU3VyZmFjZShFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKwkJCQkgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK0VHTEFQSSBFR0xTdXJmYWNlIEVHTEFQSUVOVFJZIGVnbENyZWF0ZVBpeG1hcFN1cmZhY2UoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisJCQkJICBFR0xOYXRpdmVQaXhtYXBUeXBlIHBpeG1hcCwKKwkJCQkgIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QpOworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsRGVzdHJveVN1cmZhY2UoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xRdWVyeVN1cmZhY2UoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwKKwkJCSAgIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpOworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xCaW5kQVBJKEVHTGVudW0gYXBpKTsKK0VHTEFQSSBFR0xlbnVtIEVHTEFQSUVOVFJZIGVnbFF1ZXJ5QVBJKHZvaWQpOworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xXYWl0Q2xpZW50KHZvaWQpOworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xSZWxlYXNlVGhyZWFkKHZvaWQpOworCitFR0xBUEkgRUdMU3VyZmFjZSBFR0xBUElFTlRSWSBlZ2xDcmVhdGVQYnVmZmVyRnJvbUNsaWVudEJ1ZmZlcigKKwkgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMZW51bSBidWZ0eXBlLCBFR0xDbGllbnRCdWZmZXIgYnVmZmVyLAorCSAgICAgIEVHTENvbmZpZyBjb25maWcsIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QpOworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xTdXJmYWNlQXR0cmliKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIHN1cmZhY2UsCisJCQkgICAgRUdMaW50IGF0dHJpYnV0ZSwgRUdMaW50IHZhbHVlKTsKK0VHTEFQSSBFR0xCb29sZWFuIEVHTEFQSUVOVFJZIGVnbEJpbmRUZXhJbWFnZShFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBFR0xpbnQgYnVmZmVyKTsKK0VHTEFQSSBFR0xCb29sZWFuIEVHTEFQSUVOVFJZIGVnbFJlbGVhc2VUZXhJbWFnZShFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBFR0xpbnQgYnVmZmVyKTsKKworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xTd2FwSW50ZXJ2YWwoRUdMRGlzcGxheSBkcHksIEVHTGludCBpbnRlcnZhbCk7CisKKworRUdMQVBJIEVHTENvbnRleHQgRUdMQVBJRU5UUlkgZWdsQ3JlYXRlQ29udGV4dChFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKwkJCSAgICBFR0xDb250ZXh0IHNoYXJlX2NvbnRleHQsCisJCQkgICAgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xEZXN0cm95Q29udGV4dChFR0xEaXNwbGF5IGRweSwgRUdMQ29udGV4dCBjdHgpOworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsTWFrZUN1cnJlbnQoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2UgZHJhdywKKwkJCSAgRUdMU3VyZmFjZSByZWFkLCBFR0xDb250ZXh0IGN0eCk7CisKK0VHTEFQSSBFR0xDb250ZXh0IEVHTEFQSUVOVFJZIGVnbEdldEN1cnJlbnRDb250ZXh0KHZvaWQpOworRUdMQVBJIEVHTFN1cmZhY2UgRUdMQVBJRU5UUlkgZWdsR2V0Q3VycmVudFN1cmZhY2UoRUdMaW50IHJlYWRkcmF3KTsKK0VHTEFQSSBFR0xEaXNwbGF5IEVHTEFQSUVOVFJZIGVnbEdldEN1cnJlbnREaXNwbGF5KHZvaWQpOworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsUXVlcnlDb250ZXh0KEVHTERpc3BsYXkgZHB5LCBFR0xDb250ZXh0IGN0eCwKKwkJCSAgIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpOworCitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xXYWl0R0wodm9pZCk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xXYWl0TmF0aXZlKEVHTGludCBlbmdpbmUpOworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsU3dhcEJ1ZmZlcnMoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xDb3B5QnVmZmVycyhFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLAorCQkJICBFR0xOYXRpdmVQaXhtYXBUeXBlIHRhcmdldCk7CisKKy8qIFRoaXMgaXMgYSBnZW5lcmljIGZ1bmN0aW9uIHBvaW50ZXIgdHlwZSwgd2hvc2UgbmFtZSBpbmRpY2F0ZXMgaXQgbXVzdAorICogYmUgY2FzdCB0byB0aGUgcHJvcGVyIHR5cGUgKmFuZCBjYWxsaW5nIGNvbnZlbnRpb24qIGJlZm9yZSB1c2UuCisgKi8KK3R5cGVkZWYgdm9pZCAoKl9fZWdsTXVzdENhc3RUb1Byb3BlckZ1bmN0aW9uUG9pbnRlclR5cGUpKHZvaWQpOworCisvKiBOb3csIGRlZmluZSBlZ2xHZXRQcm9jQWRkcmVzcyB1c2luZyB0aGUgZ2VuZXJpYyBmdW5jdGlvbiBwdHIuIHR5cGUgKi8KK0VHTEFQSSBfX2VnbE11c3RDYXN0VG9Qcm9wZXJGdW5jdGlvblBvaW50ZXJUeXBlIEVHTEFQSUVOVFJZCisgICAgICAgZWdsR2V0UHJvY0FkZHJlc3MoY29uc3QgY2hhciAqcHJvY25hbWUpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19lZ2xfaF8gKi8KZGlmZiAtLWdpdCBhL29wZW5nbC9pbmNsdWRlL0VHTC9lZ2xleHQuaCBiL29wZW5nbC9pbmNsdWRlL0VHTC9lZ2xleHQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNWNmY2I4Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2luY2x1ZGUvRUdML2VnbGV4dC5oCkBAIC0wLDAgKzEsMTM4IEBACisjaWZuZGVmIF9fZWdsZXh0X2hfCisjZGVmaW5lIF9fZWdsZXh0X2hfCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoKKyoqIENvcHlyaWdodCAoYykgMjAwNy0yMDA5IFRoZSBLaHJvbm9zIEdyb3VwIEluYy4KKyoqCisqKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQorKiogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZC9vciBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQorKiogIk1hdGVyaWFscyIpLCB0byBkZWFsIGluIHRoZSBNYXRlcmlhbHMgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCisqKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCisqKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIE1hdGVyaWFscywgYW5kIHRvCisqKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBNYXRlcmlhbHMgYXJlIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bworKiogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorKioKKyoqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkCisqKiBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBNYXRlcmlhbHMuCisqKgorKiogVEhFIE1BVEVSSUFMUyBBUkUgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKyoqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgorKiogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULgorKiogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkKKyoqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCisqKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQorKiogTUFURVJJQUxTIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIE1BVEVSSUFMUy4KKyovCisKKyNpbmNsdWRlIDxFR0wvZWdscGxhdGZvcm0uaD4KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIEhlYWRlciBmaWxlIHZlcnNpb24gbnVtYmVyICovCisvKiBDdXJyZW50IHZlcnNpb24gYXQgaHR0cDovL3d3dy5raHJvbm9zLm9yZy9yZWdpc3RyeS9lZ2wvICovCisvKiAkUmV2aXNpb246IDcyNDQgJCBvbiAkRGF0ZTogMjAwOS0wMS0yMCAxNzowNjo1OSAtMDgwMCAoVHVlLCAyMCBKYW4gMjAwOSkgJCAqLworI2RlZmluZSBFR0xfRUdMRVhUX1ZFUlNJT04gMworCisjaWZuZGVmIEVHTF9LSFJfY29uZmlnX2F0dHJpYnMKKyNkZWZpbmUgRUdMX0tIUl9jb25maWdfYXR0cmlicyAxCisjZGVmaW5lIEVHTF9DT05GT1JNQU5UX0tIUgkJCTB4MzA0MgkvKiBFR0xDb25maWcgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9WR19DT0xPUlNQQUNFX0xJTkVBUl9CSVRfS0hSCTB4MDAyMAkvKiBFR0xfU1VSRkFDRV9UWVBFIGJpdGZpZWxkICovCisjZGVmaW5lIEVHTF9WR19BTFBIQV9GT1JNQVRfUFJFX0JJVF9LSFIJCTB4MDA0MAkvKiBFR0xfU1VSRkFDRV9UWVBFIGJpdGZpZWxkICovCisjZW5kaWYKKworI2lmbmRlZiBFR0xfS0hSX2xvY2tfc3VyZmFjZQorI2RlZmluZSBFR0xfS0hSX2xvY2tfc3VyZmFjZSAxCisjZGVmaW5lIEVHTF9SRUFEX1NVUkZBQ0VfQklUX0tIUgkJMHgwMDAxCS8qIEVHTF9MT0NLX1VTQUdFX0hJTlRfS0hSIGJpdGZpZWxkICovCisjZGVmaW5lIEVHTF9XUklURV9TVVJGQUNFX0JJVF9LSFIJCTB4MDAwMgkvKiBFR0xfTE9DS19VU0FHRV9ISU5UX0tIUiBiaXRmaWVsZCAqLworI2RlZmluZSBFR0xfTE9DS19TVVJGQUNFX0JJVF9LSFIJCTB4MDA4MAkvKiBFR0xfU1VSRkFDRV9UWVBFIGJpdGZpZWxkICovCisjZGVmaW5lIEVHTF9PUFRJTUFMX0ZPUk1BVF9CSVRfS0hSCQkweDAxMDAJLyogRUdMX1NVUkZBQ0VfVFlQRSBiaXRmaWVsZCAqLworI2RlZmluZSBFR0xfTUFUQ0hfRk9STUFUX0tIUgkJCTB4MzA0MwkvKiBFR0xDb25maWcgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9GT1JNQVRfUkdCXzU2NV9FWEFDVF9LSFIJCTB4MzBDMAkvKiBFR0xfTUFUQ0hfRk9STUFUX0tIUiB2YWx1ZSAqLworI2RlZmluZSBFR0xfRk9STUFUX1JHQl81NjVfS0hSCQkJMHgzMEMxCS8qIEVHTF9NQVRDSF9GT1JNQVRfS0hSIHZhbHVlICovCisjZGVmaW5lIEVHTF9GT1JNQVRfUkdCQV84ODg4X0VYQUNUX0tIUgkJMHgzMEMyCS8qIEVHTF9NQVRDSF9GT1JNQVRfS0hSIHZhbHVlICovCisjZGVmaW5lIEVHTF9GT1JNQVRfUkdCQV84ODg4X0tIUgkJMHgzMEMzCS8qIEVHTF9NQVRDSF9GT1JNQVRfS0hSIHZhbHVlICovCisjZGVmaW5lIEVHTF9NQVBfUFJFU0VSVkVfUElYRUxTX0tIUgkJMHgzMEM0CS8qIGVnbExvY2tTdXJmYWNlS0hSIGF0dHJpYnV0ZSAqLworI2RlZmluZSBFR0xfTE9DS19VU0FHRV9ISU5UX0tIUgkJCTB4MzBDNQkvKiBlZ2xMb2NrU3VyZmFjZUtIUiBhdHRyaWJ1dGUgKi8KKyNkZWZpbmUgRUdMX0JJVE1BUF9QT0lOVEVSX0tIUgkJCTB4MzBDNgkvKiBlZ2xRdWVyeVN1cmZhY2UgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9CSVRNQVBfUElUQ0hfS0hSCQkJMHgzMEM3CS8qIGVnbFF1ZXJ5U3VyZmFjZSBhdHRyaWJ1dGUgKi8KKyNkZWZpbmUgRUdMX0JJVE1BUF9PUklHSU5fS0hSCQkJMHgzMEM4CS8qIGVnbFF1ZXJ5U3VyZmFjZSBhdHRyaWJ1dGUgKi8KKyNkZWZpbmUgRUdMX0JJVE1BUF9QSVhFTF9SRURfT0ZGU0VUX0tIUgkJMHgzMEM5CS8qIGVnbFF1ZXJ5U3VyZmFjZSBhdHRyaWJ1dGUgKi8KKyNkZWZpbmUgRUdMX0JJVE1BUF9QSVhFTF9HUkVFTl9PRkZTRVRfS0hSCTB4MzBDQQkvKiBlZ2xRdWVyeVN1cmZhY2UgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9CSVRNQVBfUElYRUxfQkxVRV9PRkZTRVRfS0hSCTB4MzBDQgkvKiBlZ2xRdWVyeVN1cmZhY2UgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9CSVRNQVBfUElYRUxfQUxQSEFfT0ZGU0VUX0tIUgkweDMwQ0MJLyogZWdsUXVlcnlTdXJmYWNlIGF0dHJpYnV0ZSAqLworI2RlZmluZSBFR0xfQklUTUFQX1BJWEVMX0xVTUlOQU5DRV9PRkZTRVRfS0hSCTB4MzBDRAkvKiBlZ2xRdWVyeVN1cmZhY2UgYXR0cmlidXRlICovCisjZGVmaW5lIEVHTF9MT1dFUl9MRUZUX0tIUgkJCTB4MzBDRQkvKiBFR0xfQklUTUFQX09SSUdJTl9LSFIgdmFsdWUgKi8KKyNkZWZpbmUgRUdMX1VQUEVSX0xFRlRfS0hSCQkJMHgzMENGCS8qIEVHTF9CSVRNQVBfT1JJR0lOX0tIUiB2YWx1ZSAqLworI2lmZGVmIEVHTF9FR0xFWFRfUFJPVE9UWVBFUworRUdMQVBJIEVHTEJvb2xlYW4gRUdMQVBJRU5UUlkgZWdsTG9ja1N1cmZhY2VLSFIgKEVHTERpc3BsYXkgZGlzcGxheSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK0VHTEFQSSBFR0xCb29sZWFuIEVHTEFQSUVOVFJZIGVnbFVubG9ja1N1cmZhY2VLSFIgKEVHTERpc3BsYXkgZGlzcGxheSwgRUdMU3VyZmFjZSBzdXJmYWNlKTsKKyNlbmRpZiAvKiBFR0xfRUdMRVhUX1BST1RPVFlQRVMgKi8KK3R5cGVkZWYgRUdMQm9vbGVhbiAoRUdMQVBJRU5UUllQIFBGTkVHTExPQ0tTVVJGQUNFS0hSUFJPQykgKEVHTERpc3BsYXkgZGlzcGxheSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK3R5cGVkZWYgRUdMQm9vbGVhbiAoRUdMQVBJRU5UUllQIFBGTkVHTFVOTE9DS1NVUkZBQ0VLSFJQUk9DKSAoRUdMRGlzcGxheSBkaXNwbGF5LCBFR0xTdXJmYWNlIHN1cmZhY2UpOworI2VuZGlmCisKKyNpZm5kZWYgRUdMX0tIUl9pbWFnZQorI2RlZmluZSBFR0xfS0hSX2ltYWdlIDEKKyNkZWZpbmUgRUdMX05BVElWRV9QSVhNQVBfS0hSCQkJMHgzMEIwCS8qIGVnbENyZWF0ZUltYWdlS0hSIHRhcmdldCAqLwordHlwZWRlZiB2b2lkICpFR0xJbWFnZUtIUjsKKyNkZWZpbmUgRUdMX05PX0lNQUdFX0tIUgkJCSgoRUdMSW1hZ2VLSFIpMCkKKyNpZmRlZiBFR0xfRUdMRVhUX1BST1RPVFlQRVMKK0VHTEFQSSBFR0xJbWFnZUtIUiBFR0xBUElFTlRSWSBlZ2xDcmVhdGVJbWFnZUtIUiAoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4LCBFR0xlbnVtIHRhcmdldCwgRUdMQ2xpZW50QnVmZmVyIGJ1ZmZlciwgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCk7CitFR0xBUEkgRUdMQm9vbGVhbiBFR0xBUElFTlRSWSBlZ2xEZXN0cm95SW1hZ2VLSFIgKEVHTERpc3BsYXkgZHB5LCBFR0xJbWFnZUtIUiBpbWFnZSk7CisjZW5kaWYgLyogRUdMX0VHTEVYVF9QUk9UT1RZUEVTICovCit0eXBlZGVmIEVHTEltYWdlS0hSIChFR0xBUElFTlRSWVAgUEZORUdMQ1JFQVRFSU1BR0VLSFJQUk9DKSAoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4LCBFR0xlbnVtIHRhcmdldCwgRUdMQ2xpZW50QnVmZmVyIGJ1ZmZlciwgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCk7Cit0eXBlZGVmIEVHTEJvb2xlYW4gKEVHTEFQSUVOVFJZUCBQRk5FR0xERVNUUk9ZSU1BR0VLSFJQUk9DKSAoRUdMRGlzcGxheSBkcHksIEVHTEltYWdlS0hSIGltYWdlKTsKKyNlbmRpZgorCisjaWZuZGVmIEVHTF9LSFJfdmdfcGFyZW50X2ltYWdlCisjZGVmaW5lIEVHTF9LSFJfdmdfcGFyZW50X2ltYWdlIDEKKyNkZWZpbmUgRUdMX1ZHX1BBUkVOVF9JTUFHRV9LSFIJCQkweDMwQkEJLyogZWdsQ3JlYXRlSW1hZ2VLSFIgdGFyZ2V0ICovCisjZW5kaWYKKworI2lmbmRlZiBFR0xfS0hSX2dsX3RleHR1cmVfMkRfaW1hZ2UKKyNkZWZpbmUgRUdMX0tIUl9nbF90ZXh0dXJlXzJEX2ltYWdlIDEKKyNkZWZpbmUgRUdMX0dMX1RFWFRVUkVfMkRfS0hSCQkJMHgzMEIxCS8qIGVnbENyZWF0ZUltYWdlS0hSIHRhcmdldCAqLworI2RlZmluZSBFR0xfR0xfVEVYVFVSRV9MRVZFTF9LSFIJCTB4MzBCQwkvKiBlZ2xDcmVhdGVJbWFnZUtIUiBhdHRyaWJ1dGUgKi8KKyNlbmRpZgorCisjaWZuZGVmIEVHTF9LSFJfZ2xfdGV4dHVyZV9jdWJlbWFwX2ltYWdlCisjZGVmaW5lIEVHTF9LSFJfZ2xfdGV4dHVyZV9jdWJlbWFwX2ltYWdlIDEKKyNkZWZpbmUgRUdMX0dMX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWF9LSFIJMHgzMEIzCS8qIGVnbENyZWF0ZUltYWdlS0hSIHRhcmdldCAqLworI2RlZmluZSBFR0xfR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9YX0tIUgkweDMwQjQJLyogZWdsQ3JlYXRlSW1hZ2VLSFIgdGFyZ2V0ICovCisjZGVmaW5lIEVHTF9HTF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1lfS0hSCTB4MzBCNQkvKiBlZ2xDcmVhdGVJbWFnZUtIUiB0YXJnZXQgKi8KKyNkZWZpbmUgRUdMX0dMX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWV9LSFIJMHgzMEI2CS8qIGVnbENyZWF0ZUltYWdlS0hSIHRhcmdldCAqLworI2RlZmluZSBFR0xfR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9aX0tIUgkweDMwQjcJLyogZWdsQ3JlYXRlSW1hZ2VLSFIgdGFyZ2V0ICovCisjZGVmaW5lIEVHTF9HTF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1pfS0hSCTB4MzBCOAkvKiBlZ2xDcmVhdGVJbWFnZUtIUiB0YXJnZXQgKi8KKyNlbmRpZgorCisjaWZuZGVmIEVHTF9LSFJfZ2xfdGV4dHVyZV8zRF9pbWFnZQorI2RlZmluZSBFR0xfS0hSX2dsX3RleHR1cmVfM0RfaW1hZ2UgMQorI2RlZmluZSBFR0xfR0xfVEVYVFVSRV8zRF9LSFIJCQkweDMwQjIJLyogZWdsQ3JlYXRlSW1hZ2VLSFIgdGFyZ2V0ICovCisjZGVmaW5lIEVHTF9HTF9URVhUVVJFX1pPRkZTRVRfS0hSCQkweDMwQkQJLyogZWdsQ3JlYXRlSW1hZ2VLSFIgYXR0cmlidXRlICovCisjZW5kaWYKKworI2lmbmRlZiBFR0xfS0hSX2dsX3JlbmRlcmJ1ZmZlcl9pbWFnZQorI2RlZmluZSBFR0xfS0hSX2dsX3JlbmRlcmJ1ZmZlcl9pbWFnZSAxCisjZGVmaW5lIEVHTF9HTF9SRU5ERVJCVUZGRVJfS0hSCQkJMHgzMEI5CS8qIGVnbENyZWF0ZUltYWdlS0hSIHRhcmdldCAqLworI2VuZGlmCisKKyNpZm5kZWYgRUdMX0tIUl9pbWFnZV9iYXNlCisjZGVmaW5lIEVHTF9LSFJfaW1hZ2VfYmFzZSAxCisvKiBNb3N0IGludGVyZmFjZXMgZGVmaW5lZCBieSBFR0xfS0hSX2ltYWdlX3BpeG1hcCBhYm92ZSAqLworI2RlZmluZSBFR0xfSU1BR0VfUFJFU0VSVkVEX0tIUgkJCTB4MzBEMgkvKiBlZ2xDcmVhdGVJbWFnZUtIUiBhdHRyaWJ1dGUgKi8KKyNlbmRpZgorCisjaWZuZGVmIEVHTF9LSFJfaW1hZ2VfcGl4bWFwCisjZGVmaW5lIEVHTF9LSFJfaW1hZ2VfcGl4bWFwIDEKKy8qIEludGVyZmFjZXMgZGVmaW5lZCBieSBFR0xfS0hSX2ltYWdlIGFib3ZlICovCisjZW5kaWYKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2VuZGlmCmRpZmYgLS1naXQgYS9vcGVuZ2wvaW5jbHVkZS9FR0wvZWdsbmF0aXZlcy5oIGIvb3BlbmdsL2luY2x1ZGUvRUdML2VnbG5hdGl2ZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTYyMmRjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2luY2x1ZGUvRUdML2VnbG5hdGl2ZXMuaApAQCAtMCwwICsxLDI3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9FR0xOQVRJVkVTX0gKKyNkZWZpbmUgQU5EUk9JRF9FR0xOQVRJVkVTX0gKKworI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyogZmxhZ3MgcmV0dXJuZWQgZnJvbSBzd2FwQnVmZmVyICovCisjZGVmaW5lIEVHTF9OQVRJVkVTX0ZMQUdfU0laRV9DSEFOR0VEICAgICAgIDB4MDAwMDAwMDEKKworLyogc3VyZmFjZSBmbGFncyAqLworI2RlZmluZSBFR0xfTkFUSVZFU19GTEFHX0RFU1RST1lfQkFDS0JVRkZFUiAweDAwMDAwMDAxCisKK2VudW0gbmF0aXZlX3BpeGVsX2Zvcm1hdF90Cit7CisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9SR0JBXzg4ODggICA9IDEsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9SR0JfNTY1ICAgICA9IDQsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9CR1JBXzg4ODggICA9IDUsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9SR0JBXzU1NTEgICA9IDYsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9SR0JBXzQ0NDQgICA9IDcsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9ZQ2JDcl80MjJfU1A9IDB4MTAsCisgICAgTkFUSVZFX1BJWEVMX0ZPUk1BVF9ZQ2JDcl80MjBfU1A9IDB4MTEsCit9OworCitlbnVtIG5hdGl2ZV9tZW1vcnlfdHlwZV90Cit7CisgICAgTkFUSVZFX01FTU9SWV9UWVBFX1BNRU0gICAgICAgICA9IDAsCisgICAgTkFUSVZFX01FTU9SWV9UWVBFX0dQVSAgICAgICAgICA9IDEsCisgICAgTkFUSVZFX01FTU9SWV9UWVBFX0ZCICAgICAgICAgICA9IDIsCisgICAgTkFUSVZFX01FTU9SWV9UWVBFX0hFQVAgICAgICAgICA9IDEyOAorfTsKKworCitzdHJ1Y3QgZWdsX25hdGl2ZV93aW5kb3dfdAoreworICAgIC8qCisgICAgICogbWFnaWMgbXVzdCBiZSBzZXQgdG8gMHg2MDA5MTMKKyAgICAgKi8KKyAgICB1aW50MzJfdCAgICBtYWdpYzsKKyAgICAKKyAgICAvKgorICAgICAqIG11c3QgYmUgc2l6ZW9mKGVnbF9uYXRpdmVfd2luZG93X3QpCisgICAgICovCisgICAgdWludDMyX3QgICAgdmVyc2lvbjsKKworICAgIC8qCisgICAgICogaWRlbnQgaXMgcmVzZXJ2ZWQgZm9yIHRoZSBBbmRyb2lkIHBsYXRmb3JtCisgICAgICovCisgICAgdWludDMyX3QgICAgaWRlbnQ7CisgICAgCisgICAgLyoKKyAgICAgKiB3aWR0aCwgaGVpZ2h0IGFuZCBzdHJpZGUgb2YgdGhlIHdpbmRvdyBpbiBwaXhlbHMKKyAgICAgKiBBbnkgb2YgdGhlc2UgdmFsdWUgY2FuIGJlIG51bCBpbiB3aGljaCBjYXNlIEdMIGNvbW1hbmRzIGFyZQorICAgICAqIGFjY2VwdGVkIGFuZCBwcm9jZXNzZWQgYXMgdXN1YWwsIGJ1dCBub3QgcmVuZGVyaW5nIG9jY3Vycy4KKyAgICAgKi8KKyAgICBpbnQgICAgICAgICB3aWR0aDsgICAgICAvLyB3PWg9MCBpcyBsZWdhbAorICAgIGludCAgICAgICAgIGhlaWdodDsKKyAgICBpbnQgICAgICAgICBzdHJpZGU7CisKKyAgICAvKgorICAgICAqIGZvcm1hdCBvZiB0aGUgbmF0aXZlIHdpbmRvdyAoc2VlIHVpL1BpeGVsRm9ybWF0LmgpCisgICAgICovCisgICAgaW50ICAgICAgICAgZm9ybWF0OworICAgIAorICAgIC8qCisgICAgICogT2Zmc2V0IG9mIHRoZSBiaXRzIGluIHRoZSBWUkFNCisgICAgICovCisgICAgaW50cHRyX3QgICAgb2Zmc2V0OworICAgIAorICAgIC8qCisgICAgICogZmxhZ3MgZGVzY3JpYmluZyBzb21lIGF0dHJpYnV0ZXMgb2YgdGhpcyBzdXJmYWNlCisgICAgICogRUdMX05BVElWRVNfRkxBR19ERVNUUk9ZX0JBQ0tCVUZGRVI6IGJhY2tidWZmZXIgbm90IHByZXNlcnZlZCBhZnRlciAKKyAgICAgKiBlZ2xTd2FwQnVmZmVycworICAgICAqLworICAgIHVpbnQzMl90ICAgIGZsYWdzOworICAgIAorICAgIC8qCisgICAgICogaG9yaXpvbnRhbCBhbmQgdmVydGljYWwgcmVzb2x1dGlvbiBpbiBEUEkKKyAgICAgKi8KKyAgICBmbG9hdCAgICAgICB4ZHBpOworICAgIGZsb2F0ICAgICAgIHlkcGk7CisgICAgCisgICAgLyoKKyAgICAgKiByZWZyZXNoIHJhdGUgaW4gZnJhbWVzIHBlciBzZWNvbmQgKEh6KQorICAgICAqLworICAgIGZsb2F0ICAgICAgIGZwczsKKyAgICAKKyAgICAKKyAgICAvKgorICAgICAqICBCYXNlIG1lbW9yeSB2aXJ0dWFsIGFkZHJlc3Mgb2YgdGhlIHN1cmZhY2UgaW4gdGhlIENQVSBzaWRlCisgICAgICovCisgICAgaW50cHRyX3QgICAgYmFzZTsKKyAgICAKKyAgICAvKgorICAgICAqICBIZWFwIHRoZSBvZmZzZXQgYWJvdmUgaXMgYmFzZWQgZnJvbQorICAgICAqLworICAgIGludCAgICAgICAgIGZkOworICAgIAorICAgIC8qCisgICAgICogIE1lbW9yeSB0eXBlIHRoZSBzdXJmYWNlIHJlc2lkZXMgaW50bworICAgICAqLworICAgIHVpbnQ4X3QgICAgIG1lbW9yeV90eXBlOworICAgIAorICAgIC8qCisgICAgICogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuIE1VU1QgQkUgWkVSTy4KKyAgICAgKi8KKyAgICB1aW50OF90ICAgICByZXNlcnZlZF9wYWRbM107CisgICAgaW50ICAgICAgICAgcmVzZXJ2ZWRbOF07CisgICAgCisgICAgLyoKKyAgICAgKiBWZXJ0aWNhbCBzdHJpZGUgKG9ubHkgcmVsZXZhbnQgd2l0aCBwbGFuYXIgZm9ybWF0cykgCisgICAgICovCisgICAgCisgICAgaW50ICAgICAgICAgdnN0cmlkZTsKKworICAgIC8qCisgICAgICogSG9vayBjYWxsZWQgYnkgRUdMIHRvIGhvbGQgYSByZWZlcmVuY2Ugb24gdGhpcyBzdHJ1Y3R1cmUKKyAgICAgKi8KKyAgICB2b2lkICAgICAgICAoKmluY1JlZikoc3RydWN0IGVnbF9uYXRpdmVfd2luZG93X3QqIHdpbmRvdyk7CisKKyAgICAvKgorICAgICAqIEhvb2sgY2FsbGVkIGJ5IEVHTCB0byByZWxlYXNlIGEgcmVmZXJlbmNlIG9uIHRoaXMgc3RydWN0dXJlCisgICAgICovCisgICAgdm9pZCAgICAgICAgKCpkZWNSZWYpKHN0cnVjdCBlZ2xfbmF0aXZlX3dpbmRvd190KiB3aW5kb3cpOworCisgICAgLyoKKyAgICAgKiBIb29rIGNhbGxlZCBieSBFR0wgdG8gcGVyZm9ybSBhIHBhZ2UgZmxpcC4gVGhpcyBmdW5jdGlvbgorICAgICAqIG1heSB1cGRhdGUgdGhlIHNpemUgYXR0cmlidXRlcyBhYm92ZSwgaW4gd2hpY2ggY2FzZSBpdCByZXR1cm5zCisgICAgICogdGhlIEVHTF9OQVRJVkVTX0ZMQUdfU0laRV9DSEFOR0VEIGJpdCBzZXQuCisgICAgICovCisgICAgdWludDMyX3QgICAgKCpzd2FwQnVmZmVycykoc3RydWN0IGVnbF9uYXRpdmVfd2luZG93X3QqIHdpbmRvdyk7CisgICAgCisgICAgLyoKKyAgICAgKiBSZXNlcnZlZCBmb3IgZnV0dXJlIHVzZS4gTVVTVCBCRSBaRVJPLgorICAgICAqLworICAgIHZvaWQgICAgICAgICgqcmVzZXJ2ZWRfcHJvY18wKSh2b2lkKTsKKworICAgIC8qCisgICAgICogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuIE1VU1QgQkUgWkVSTy4KKyAgICAgKi8KKyAgICB2b2lkICAgICAgICAoKnJlc2VydmVkX3Byb2NfMSkodm9pZCk7CisgICAgCisgICAgLyoKKyAgICAgKiBSZXNlcnZlZCBmb3IgZnV0dXJlIHVzZS4gTVVTVCBCRSBaRVJPLgorICAgICAqLworICAgIHZvaWQgICAgICAgICgqcmVzZXJ2ZWRfcHJvY18yKSh2b2lkKTsKKworICAgIAorICAgIC8qCisgICAgICogSG9vayBjYWxsZWQgYnkgRUdMIHdoZW4gdGhlIG5hdGl2ZSBzdXJmYWNlIGlzIGFzc29jaWF0ZWQgdG8gRUdMCisgICAgICogKGVnbENyZWF0ZVdpbmRvd1N1cmZhY2UpLiBDYW4gYmUgTlVMTC4KKyAgICAgKi8KKyAgICB2b2lkICAgICAgICAoKmNvbm5lY3QpKHN0cnVjdCBlZ2xfbmF0aXZlX3dpbmRvd190KiB3aW5kb3cpOworCisgICAgLyoKKyAgICAgKiBIb29rIGNhbGxlZCBieSBFR0wgd2hlbiBlZ2xEZXN0cm95U3VyZmFjZSBpcyBjYWxsZWQuICBDYW4gYmUgTlVMTC4KKyAgICAgKi8KKyAgICB2b2lkICAgICAgICAoKmRpc2Nvbm5lY3QpKHN0cnVjdCBlZ2xfbmF0aXZlX3dpbmRvd190KiB3aW5kb3cpOworICAgIAorICAgIC8qCisgICAgICogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuIE1VU1QgQkUgWkVSTy4KKyAgICAgKi8KKyAgICB2b2lkICAgICAgICAoKnJlc2VydmVkX3Byb2NbMTFdKSh2b2lkKTsKKyAgICAKKyAgICAvKgorICAgICAqICBTb21lIHN0b3JhZ2UgcmVzZXJ2ZWQgZm9yIHRoZSBvZW0gZHJpdmVyLgorICAgICAqLworICAgIGludHB0cl90ICAgIG9lbVs0XTsKK307CisKKworc3RydWN0IGVnbF9uYXRpdmVfcGl4bWFwX3QKK3sKKyAgICBpbnQzMl90ICAgICB2ZXJzaW9uOyAgICAvKiBtdXN0IGJlIDMyICovCisgICAgaW50MzJfdCAgICAgd2lkdGg7CisgICAgaW50MzJfdCAgICAgaGVpZ2h0OworICAgIGludDMyX3QgICAgIHN0cmlkZTsKKyAgICB1aW50OF90KiAgICBkYXRhOworICAgIHVpbnQ4X3QgICAgIGZvcm1hdDsKKyAgICB1aW50OF90ICAgICByZnVbM107CisgICAgdW5pb24geworICAgICAgICB1aW50MzJfdCAgICBjb21wcmVzc2VkRm9ybWF0OworICAgICAgICBpbnQzMl90ICAgICB2c3RyaWRlOworICAgIH07CisgICAgaW50MzJfdCAgICAgcmVzZXJ2ZWQ7Cit9OworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIAorICogVGhpcyBhIGNvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIE5hdGl2ZVdpbmRvd1R5cGUgc3VyZmFjZQorICogdGhhdCBtYXBzIHRvIHRoZSB3aG9sZSBzY3JlZW4KKyAqIFRoaXMgZnVuY3Rpb24gaXMgYWN0dWFsbHkgaW1wbGVtZW50ZWQgaW4gbGlidWkuc28KKyAqLworCitzdHJ1Y3QgZWdsX25hdGl2ZV93aW5kb3dfdCogYW5kcm9pZF9jcmVhdGVEaXNwbGF5U3VyZmFjZSgpOworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKworLyoKKyAqIE9FTSdzIGVnbCdzIGxpYnJhcnkgKGxpYmhnbC5zbykgbXVzdCBpbWxlbWVudCB0aGVzZSBob29rcyB0byBhbGxvY2F0ZQorICogdGhlIEdQVSBtZW1vcnkgdGhleSBuZWVkICAKKyAqLworCisKK3R5cGVkZWYgc3RydWN0Cit7CisgICAgLy8gZm9yIGludGVybmFsIHVzZQorICAgIHZvaWQqICAgdXNlcjsKKyAgICAvLyB2aXJ0dWFsIGFkZHJlc3Mgb2YgdGhpcyBhcmVhCisgICAgdm9pZCogICBiYXNlOworICAgIC8vIHNpemUgb2YgdGhpcyBhcmVhIGluIGJ5dGVzCisgICAgc2l6ZV90ICBzaXplOworICAgIC8vIHBoeXNpY2FsIGFkZHJlc3Mgb2YgdGhpcyBhcmVhCisgICAgdm9pZCogICBwaHlzOworICAgIC8vIG9mZnNldCBpbiB0aGlzIGFyZWEgYXZhaWxhYmxlIHRvIHRoZSBHUFUKKyAgICBzaXplX3QgIG9mZnNldDsKKyAgICAvLyBmZCBvZiB0aGlzIGFyZWEKKyAgICBpbnQgICAgIGZkOworfSBncHVfYXJlYV90OworCit0eXBlZGVmIHN0cnVjdAoreworICAgIC8vIGFyZWEgd2hlcmUgR1BVIHJlZ2lzdGVycyBhcmUgbWFwcGVkCisgICAgZ3B1X2FyZWFfdCByZWdzOworICAgIC8vIG51bWJlciBvZiBleHRyYSBhcmVhcyAoY3VycmVudGx5IGxpbWl0ZWQgdG8gMikKKyAgICBpbnQzMl90IGNvdW50OworICAgIC8vIGV4dHJhIEdQVSBhcmVhcyAoY3VycmVudGx5IGxpbWl0ZWQgdG8gMikKKyAgICBncHVfYXJlYV90IGdwdVsyXTsKK30gcmVxdWVzdF9ncHVfdDsKKworCit0eXBlZGVmIHJlcXVlc3RfZ3B1X3QqICgqT0VNX0VHTF9hY3F1aXJlX2dwdV90KSh2b2lkKiB1c2VyKTsKK3R5cGVkZWYgaW50ICgqT0VNX0VHTF9yZWxlYXNlX2dwdV90KSh2b2lkKiB1c2VyLCByZXF1ZXN0X2dwdV90KiBoYW5kbGUpOwordHlwZWRlZiB2b2lkICgqcmVnaXN0ZXJfZ3B1X3QpCisgICAgICAgICh2b2lkKiB1c2VyLCBPRU1fRUdMX2FjcXVpcmVfZ3B1X3QsIE9FTV9FR0xfcmVsZWFzZV9ncHVfdCk7CisKK3ZvaWQgb2VtX3JlZ2lzdGVyX2dwdSgKKyAgICAgICAgdm9pZCogdXNlciwKKyAgICAgICAgT0VNX0VHTF9hY3F1aXJlX2dwdV90IGFjcXVpcmUsCisgICAgICAgIE9FTV9FR0xfcmVsZWFzZV9ncHVfdCByZWxlYXNlKTsKKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBBTkRST0lEX0VHTE5BVElWRVNfSCAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2luY2x1ZGUvRUdML2VnbHBsYXRmb3JtLmggYi9vcGVuZ2wvaW5jbHVkZS9FR0wvZWdscGxhdGZvcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYzAwOTAxCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2luY2x1ZGUvRUdML2VnbHBsYXRmb3JtLmgKQEAgLTAsMCArMSwxMTcgQEAKKyNpZm5kZWYgX19lZ2xwbGF0Zm9ybV9oXworI2RlZmluZSBfX2VnbHBsYXRmb3JtX2hfCisKKy8qCisqKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOSBUaGUgS2hyb25vcyBHcm91cCBJbmMuCisqKgorKiogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKKyoqIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQvb3IgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKKyoqICJNYXRlcmlhbHMiKSwgdG8gZGVhbCBpbiB0aGUgTWF0ZXJpYWxzIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZworKiogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAorKiogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBNYXRlcmlhbHMsIGFuZCB0bworKiogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgTWF0ZXJpYWxzIGFyZSBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KKyoqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKyoqCisqKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZAorKiogaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgTWF0ZXJpYWxzLgorKioKKyoqIFRIRSBNQVRFUklBTFMgQVJFIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCisqKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKKyoqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KKyoqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCisqKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAorKiogVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKKyoqIE1BVEVSSUFMUyBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBNQVRFUklBTFMuCisqLworCisvKiBQbGF0Zm9ybS1zcGVjaWZpYyB0eXBlcyBhbmQgZGVmaW5pdGlvbnMgZm9yIGVnbC5oCisgKiAkUmV2aXNpb246IDcyNDQgJCBvbiAkRGF0ZTogMjAwOS0wMS0yMCAxNzowNjo1OSAtMDgwMCAoVHVlLCAyMCBKYW4gMjAwOSkgJAorICoKKyAqIEFkb3B0ZXJzIG1heSBtb2RpZnkga2hycGxhdGZvcm0uaCBhbmQgdGhpcyBmaWxlIHRvIHN1aXQgdGhlaXIgcGxhdGZvcm0uCisgKiBZb3UgYXJlIGVuY291cmFnZWQgdG8gc3VibWl0IGFsbCBtb2RpZmljYXRpb25zIHRvIHRoZSBLaHJvbm9zIGdyb3VwIHNvIHRoYXQKKyAqIHRoZXkgY2FuIGJlIGluY2x1ZGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGlzIGZpbGUuICBQbGVhc2Ugc3VibWl0IGNoYW5nZXMKKyAqIGJ5IHNlbmRpbmcgdGhlbSB0byB0aGUgcHVibGljIEtocm9ub3MgQnVnemlsbGEgKGh0dHA6Ly9raHJvbm9zLm9yZy9idWd6aWxsYSkKKyAqIGJ5IGZpbGluZyBhIGJ1ZyBhZ2FpbnN0IHByb2R1Y3QgIkVHTCIgY29tcG9uZW50ICJSZWdpc3RyeSIuCisgKi8KKworI2luY2x1ZGUgPEtIUi9raHJwbGF0Zm9ybS5oPgorCisvKiBNYWNyb3MgdXNlZCBpbiBFR0wgZnVuY3Rpb24gcHJvdG90eXBlIGRlY2xhcmF0aW9ucy4KKyAqCisgKiBFR0wgZnVuY3Rpb25zIHNob3VsZCBiZSBwcm90b3R5cGVkIGFzOgorICoKKyAqIEVHTEFQSSByZXR1cm4tdHlwZSBFR0xBUElFTlRSWSBlZ2xGdW5jdGlvbihhcmd1bWVudHMpOworICogdHlwZWRlZiByZXR1cm4tdHlwZSAoRVhQQVBJRU5UUllQIFBGTkVHTEZVTkNUSU9OUFJPQykgKGFyZ3VtZW50cyk7CisgKgorICogS0hST05PU19BUElDQUxMIGFuZCBLSFJPTk9TX0FQSUVOVFJZIGFyZSBkZWZpbmVkIGluIEtIUi9raHJwbGF0Zm9ybS5oCisgKi8KKworI2lmbmRlZiBFR0xBUEkKKyNkZWZpbmUgRUdMQVBJIEtIUk9OT1NfQVBJQ0FMTAorI2VuZGlmCisKKyNkZWZpbmUgRUdMQVBJRU5UUlkgIEtIUk9OT1NfQVBJRU5UUlkKKyNkZWZpbmUgRUdMQVBJRU5UUllQIEtIUk9OT1NfQVBJRU5UUlkqCisKKy8qIFRoZSB0eXBlcyBOYXRpdmVEaXNwbGF5VHlwZSwgTmF0aXZlV2luZG93VHlwZSwgYW5kIE5hdGl2ZVBpeG1hcFR5cGUKKyAqIGFyZSBhbGlhc2VzIG9mIHdpbmRvdy1zeXN0ZW0tZGVwZW5kZW50IHR5cGVzLCBzdWNoIGFzIFggRGlzcGxheSAqIG9yCisgKiBXaW5kb3dzIERldmljZSBDb250ZXh0LiBUaGV5IG11c3QgYmUgZGVmaW5lZCBpbiBwbGF0Zm9ybS1zcGVjaWZpYworICogY29kZSBiZWxvdy4gVGhlIEVHTC1wcmVmaXhlZCB2ZXJzaW9ucyBvZiBOYXRpdmUqVHlwZSBhcmUgdGhlIHNhbWUKKyAqIHR5cGVzLCByZW5hbWVkIGluIEVHTCAxLjMgc28gYWxsIHR5cGVzIGluIHRoZSBBUEkgc3RhcnQgd2l0aCAiRUdMIi4KKyAqLworCisjaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX19WQzMyX18pICYmICFkZWZpbmVkKF9fQ1lHV0lOX18pICYmICFkZWZpbmVkKF9fU0NJVEVDSF9TTkFQX18pIC8qIFdpbjMyIGFuZCBXaW5DRSAqLworI2lmbmRlZiBXSU4zMl9MRUFOX0FORF9NRUFOCisjZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4gMQorI2VuZGlmCisjaW5jbHVkZSA8d2luZG93cy5oPgorCit0eXBlZGVmIEhEQyAgICAgRUdMTmF0aXZlRGlzcGxheVR5cGU7Cit0eXBlZGVmIEhCSVRNQVAgRUdMTmF0aXZlUGl4bWFwVHlwZTsKK3R5cGVkZWYgSFdORCAgICBFR0xOYXRpdmVXaW5kb3dUeXBlOworCisjZWxpZiBkZWZpbmVkKF9fV0lOU0NXX18pIHx8IGRlZmluZWQoX19TWU1CSUFOMzJfXykgIC8qIFN5bWJpYW4gKi8KKwordHlwZWRlZiBpbnQgICBFR0xOYXRpdmVEaXNwbGF5VHlwZTsKK3R5cGVkZWYgdm9pZCAqRUdMTmF0aXZlV2luZG93VHlwZTsKK3R5cGVkZWYgdm9pZCAqRUdMTmF0aXZlUGl4bWFwVHlwZTsKKworI2VsaWYgZGVmaW5lZChfX3VuaXhfXykgJiYgIWRlZmluZWQoQU5EUk9JRCkKKworLyogWDExICh0ZW50YXRpdmUpICAqLworI2luY2x1ZGUgPFgxMS9YbGliLmg+CisjaW5jbHVkZSA8WDExL1h1dGlsLmg+CisKK3R5cGVkZWYgRGlzcGxheSAqRUdMTmF0aXZlRGlzcGxheVR5cGU7Cit0eXBlZGVmIFBpeG1hcCAgIEVHTE5hdGl2ZVBpeG1hcFR5cGU7Cit0eXBlZGVmIFdpbmRvdyAgIEVHTE5hdGl2ZVdpbmRvd1R5cGU7CisKKworI2VsaWYgZGVmaW5lZChBTkRST0lEKQorCisjaW5jbHVkZSA8RUdML2VnbG5hdGl2ZXMuaD4KKwordHlwZWRlZiBzdHJ1Y3QgZWdsX25hdGl2ZV93aW5kb3dfdCogICAgIEVHTE5hdGl2ZVdpbmRvd1R5cGU7Cit0eXBlZGVmIHN0cnVjdCBlZ2xfbmF0aXZlX3BpeG1hcF90KiAgICAgRUdMTmF0aXZlUGl4bWFwVHlwZTsKK3R5cGVkZWYgdm9pZCogICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xOYXRpdmVEaXNwbGF5VHlwZTsKKworI2Vsc2UKKyNlcnJvciAiUGxhdGZvcm0gbm90IHJlY29nbml6ZWQiCisjZW5kaWYKKworLyogRUdMIDEuMiB0eXBlcywgcmVuYW1lZCBmb3IgY29uc2lzdGVuY3kgaW4gRUdMIDEuMyAqLwordHlwZWRlZiBFR0xOYXRpdmVEaXNwbGF5VHlwZSBOYXRpdmVEaXNwbGF5VHlwZTsKK3R5cGVkZWYgRUdMTmF0aXZlUGl4bWFwVHlwZSAgTmF0aXZlUGl4bWFwVHlwZTsKK3R5cGVkZWYgRUdMTmF0aXZlV2luZG93VHlwZSAgTmF0aXZlV2luZG93VHlwZTsKKworCisvKiBEZWZpbmUgRUdMaW50LiBUaGlzIG11c3QgYmUgYSBzaWduZWQgaW50ZWdyYWwgdHlwZSBsYXJnZSBlbm91Z2ggdG8gY29udGFpbgorICogYWxsIGxlZ2FsIGF0dHJpYnV0ZSBuYW1lcyBhbmQgdmFsdWVzIHBhc3NlZCBpbnRvIGFuZCBvdXQgb2YgRUdMLCB3aGV0aGVyCisgKiB0aGVpciB0eXBlIGlzIGJvb2xlYW4sIGJpdG1hc2ssIGVudW1lcmFudCAoc3ltYm9saWMgY29uc3RhbnQpLCBpbnRlZ2VyLAorICogaGFuZGxlLCBvciBvdGhlci4gIFdoaWxlIGluIGdlbmVyYWwgYSAzMi1iaXQgaW50ZWdlciB3aWxsIHN1ZmZpY2UsIGlmCisgKiBoYW5kbGVzIGFyZSA2NCBiaXQgdHlwZXMsIHRoZW4gRUdMaW50IHNob3VsZCBiZSBkZWZpbmVkIGFzIGEgc2lnbmVkIDY0LWJpdAorICogaW50ZWdlciB0eXBlLgorICovCit0eXBlZGVmIGtocm9ub3NfaW50MzJfdCBFR0xpbnQ7CisKKyNlbmRpZiAvKiBfX2VnbHBsYXRmb3JtX2ggKi8KZGlmZiAtLWdpdCBhL29wZW5nbC9pbmNsdWRlL0dMRVMvZWdsLmggYi9vcGVuZ2wvaW5jbHVkZS9HTEVTL2VnbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3NzhlMDAKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvaW5jbHVkZS9HTEVTL2VnbC5oCkBAIC0wLDAgKzEsMTUgQEAKKy8qCisgKiBTa2VsZXRvbiBlZ2wuaCB0byBwcm92aWRlIGNvbXBhdGliaWxpdHkgZm9yIGVhcmx5IEdMRVMgMS4wCisgKiBhcHBsaWNhdGlvbnMuIFNldmVyYWwgZWFybHkgaW1wbGVtZW50YXRpb25zIGluY2x1ZGVkIGdsLmgKKyAqIGluIGVnbC5oIGxlYWRpbmcgYXBwbGljYXRpb25zIHRvIGluY2x1ZGUgb25seSBlZ2wuaAorICoKKyAqICRSZXZpc2lvbjogNjI1MiAkIG9uICREYXRlOjogMjAwOC0wOC0wNiAxNjozNTowOCAtMDcwMCAjJAorICovCisKKyNpZm5kZWYgX19sZWdhY3lfZWdsX2hfCisjZGVmaW5lIF9fbGVnYWN5X2VnbF9oXworCisjaW5jbHVkZSA8RUdML2VnbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2VuZGlmIC8qIF9fbGVnYWN5X2VnbF9oXyAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2luY2x1ZGUvR0xFUy9nbC5oIGIvb3BlbmdsL2luY2x1ZGUvR0xFUy9nbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlOGI5NzEKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvaW5jbHVkZS9HTEVTL2dsLmgKQEAgLTAsMCArMSw3NjkgQEAKKyNpZm5kZWYgX19nbF9oXworI2RlZmluZSBfX2dsX2hfCisKKy8qICRSZXZpc2lvbjogNzE3MiAkIG9uICREYXRlOjogMjAwOS0wMS0wOSAxMToxNzo0MSAtMDgwMCAjJCAqLworCisjaW5jbHVkZSA8R0xFUy9nbHBsYXRmb3JtLmg+CisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoKKyAqIFRoaXMgZG9jdW1lbnQgaXMgbGljZW5zZWQgdW5kZXIgdGhlIFNHSSBGcmVlIFNvZnR3YXJlIEIgTGljZW5zZSBWZXJzaW9uCisgKiAyLjAuIEZvciBkZXRhaWxzLCBzZWUgaHR0cDovL29zcy5zZ2kuY29tL3Byb2plY3RzL0ZyZWVCLyAuCisgKi8KKwordHlwZWRlZiB2b2lkICAgICAgICAgICAgIEdMdm9pZDsKK3R5cGVkZWYgdW5zaWduZWQgaW50ICAgICBHTGVudW07Cit0eXBlZGVmIHVuc2lnbmVkIGNoYXIgICAgR0xib29sZWFuOwordHlwZWRlZiB1bnNpZ25lZCBpbnQgICAgIEdMYml0ZmllbGQ7Cit0eXBlZGVmIGtocm9ub3NfaW50OF90ICAgR0xieXRlOwordHlwZWRlZiBzaG9ydCAgICAgICAgICAgIEdMc2hvcnQ7Cit0eXBlZGVmIGludCAgICAgICAgICAgICAgR0xpbnQ7Cit0eXBlZGVmIGludCAgICAgICAgICAgICAgR0xzaXplaTsKK3R5cGVkZWYga2hyb25vc191aW50OF90ICBHTHVieXRlOwordHlwZWRlZiB1bnNpZ25lZCBzaG9ydCAgIEdMdXNob3J0OwordHlwZWRlZiB1bnNpZ25lZCBpbnQgICAgIEdMdWludDsKK3R5cGVkZWYga2hyb25vc19mbG9hdF90ICBHTGZsb2F0OwordHlwZWRlZiBraHJvbm9zX2Zsb2F0X3QgIEdMY2xhbXBmOwordHlwZWRlZiBraHJvbm9zX2ludDMyX3QgIEdMZml4ZWQ7Cit0eXBlZGVmIGtocm9ub3NfaW50MzJfdCAgR0xjbGFtcHg7CisKK3R5cGVkZWYga2hyb25vc19pbnRwdHJfdCBHTGludHB0cjsKK3R5cGVkZWYga2hyb25vc19zc2l6ZV90ICBHTHNpemVpcHRyOworCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBPcGVuR0wgRVMgY29yZSB2ZXJzaW9ucyAqLworI2RlZmluZSBHTF9WRVJTSU9OX0VTX0NNXzFfMCAgICAgICAgICAxCisjZGVmaW5lIEdMX1ZFUlNJT05fRVNfQ0xfMV8wICAgICAgICAgIDEKKyNkZWZpbmUgR0xfVkVSU0lPTl9FU19DTV8xXzEgICAgICAgICAgMQorI2RlZmluZSBHTF9WRVJTSU9OX0VTX0NMXzFfMSAgICAgICAgICAxCisKKy8qIENsZWFyQnVmZmVyTWFzayAqLworI2RlZmluZSBHTF9ERVBUSF9CVUZGRVJfQklUICAgICAgICAgICAgICAgMHgwMDAwMDEwMAorI2RlZmluZSBHTF9TVEVOQ0lMX0JVRkZFUl9CSVQgICAgICAgICAgICAgMHgwMDAwMDQwMAorI2RlZmluZSBHTF9DT0xPUl9CVUZGRVJfQklUICAgICAgICAgICAgICAgMHgwMDAwNDAwMAorCisvKiBCb29sZWFuICovCisjZGVmaW5lIEdMX0ZBTFNFICAgICAgICAgICAgICAgICAgICAgICAgICAwCisjZGVmaW5lIEdMX1RSVUUgICAgICAgICAgICAgICAgICAgICAgICAgICAxCisKKy8qIEJlZ2luTW9kZSAqLworI2RlZmluZSBHTF9QT0lOVFMgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMDAwCisjZGVmaW5lIEdMX0xJTkVTICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwMDEKKyNkZWZpbmUgR0xfTElORV9MT09QICAgICAgICAgICAgICAgICAgICAgIDB4MDAwMgorI2RlZmluZSBHTF9MSU5FX1NUUklQICAgICAgICAgICAgICAgICAgICAgMHgwMDAzCisjZGVmaW5lIEdMX1RSSUFOR0xFUyAgICAgICAgICAgICAgICAgICAgICAweDAwMDQKKyNkZWZpbmUgR0xfVFJJQU5HTEVfU1RSSVAgICAgICAgICAgICAgICAgIDB4MDAwNQorI2RlZmluZSBHTF9UUklBTkdMRV9GQU4gICAgICAgICAgICAgICAgICAgMHgwMDA2CisKKy8qIEFscGhhRnVuY3Rpb24gKi8KKyNkZWZpbmUgR0xfTkVWRVIgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwMAorI2RlZmluZSBHTF9MRVNTICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMjAxCisjZGVmaW5lIEdMX0VRVUFMICAgICAgICAgICAgICAgICAgICAgICAgICAweDAyMDIKKyNkZWZpbmUgR0xfTEVRVUFMICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwMworI2RlZmluZSBHTF9HUkVBVEVSICAgICAgICAgICAgICAgICAgICAgICAgMHgwMjA0CisjZGVmaW5lIEdMX05PVEVRVUFMICAgICAgICAgICAgICAgICAgICAgICAweDAyMDUKKyNkZWZpbmUgR0xfR0VRVUFMICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwNgorI2RlZmluZSBHTF9BTFdBWVMgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMjA3CisKKy8qIEJsZW5kaW5nRmFjdG9yRGVzdCAqLworI2RlZmluZSBHTF9aRVJPICAgICAgICAgICAgICAgICAgICAgICAgICAgMAorI2RlZmluZSBHTF9PTkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgMQorI2RlZmluZSBHTF9TUkNfQ09MT1IgICAgICAgICAgICAgICAgICAgICAgMHgwMzAwCisjZGVmaW5lIEdMX09ORV9NSU5VU19TUkNfQ09MT1IgICAgICAgICAgICAweDAzMDEKKyNkZWZpbmUgR0xfU1JDX0FMUEhBICAgICAgICAgICAgICAgICAgICAgIDB4MDMwMgorI2RlZmluZSBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBICAgICAgICAgICAgMHgwMzAzCisjZGVmaW5lIEdMX0RTVF9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAweDAzMDQKKyNkZWZpbmUgR0xfT05FX01JTlVTX0RTVF9BTFBIQSAgICAgICAgICAgIDB4MDMwNQorCisvKiBCbGVuZGluZ0ZhY3RvclNyYyAqLworLyogICAgICBHTF9aRVJPICovCisvKiAgICAgIEdMX09ORSAqLworI2RlZmluZSBHTF9EU1RfQ09MT1IgICAgICAgICAgICAgICAgICAgICAgMHgwMzA2CisjZGVmaW5lIEdMX09ORV9NSU5VU19EU1RfQ09MT1IgICAgICAgICAgICAweDAzMDcKKyNkZWZpbmUgR0xfU1JDX0FMUEhBX1NBVFVSQVRFICAgICAgICAgICAgIDB4MDMwOAorLyogICAgICBHTF9TUkNfQUxQSEEgKi8KKy8qICAgICAgR0xfT05FX01JTlVTX1NSQ19BTFBIQSAqLworLyogICAgICBHTF9EU1RfQUxQSEEgKi8KKy8qICAgICAgR0xfT05FX01JTlVTX0RTVF9BTFBIQSAqLworCisvKiBDbGlwUGxhbmVOYW1lICovCisjZGVmaW5lIEdMX0NMSVBfUExBTkUwICAgICAgICAgICAgICAgICAgICAweDMwMDAKKyNkZWZpbmUgR0xfQ0xJUF9QTEFORTEgICAgICAgICAgICAgICAgICAgIDB4MzAwMQorI2RlZmluZSBHTF9DTElQX1BMQU5FMiAgICAgICAgICAgICAgICAgICAgMHgzMDAyCisjZGVmaW5lIEdMX0NMSVBfUExBTkUzICAgICAgICAgICAgICAgICAgICAweDMwMDMKKyNkZWZpbmUgR0xfQ0xJUF9QTEFORTQgICAgICAgICAgICAgICAgICAgIDB4MzAwNAorI2RlZmluZSBHTF9DTElQX1BMQU5FNSAgICAgICAgICAgICAgICAgICAgMHgzMDA1CisKKy8qIENvbG9yTWF0ZXJpYWxGYWNlICovCisvKiAgICAgIEdMX0ZST05UX0FORF9CQUNLICovCisKKy8qIENvbG9yTWF0ZXJpYWxQYXJhbWV0ZXIgKi8KKy8qICAgICAgR0xfQU1CSUVOVF9BTkRfRElGRlVTRSAqLworCisvKiBDb2xvclBvaW50ZXJUeXBlICovCisvKiAgICAgIEdMX1VOU0lHTkVEX0JZVEUgKi8KKy8qICAgICAgR0xfRkxPQVQgKi8KKy8qICAgICAgR0xfRklYRUQgKi8KKworLyogQ3VsbEZhY2VNb2RlICovCisjZGVmaW5lIEdMX0ZST05UICAgICAgICAgICAgICAgICAgICAgICAgICAweDA0MDQKKyNkZWZpbmUgR0xfQkFDSyAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDQwNQorI2RlZmluZSBHTF9GUk9OVF9BTkRfQkFDSyAgICAgICAgICAgICAgICAgMHgwNDA4CisKKy8qIERlcHRoRnVuY3Rpb24gKi8KKy8qICAgICAgR0xfTkVWRVIgKi8KKy8qICAgICAgR0xfTEVTUyAqLworLyogICAgICBHTF9FUVVBTCAqLworLyogICAgICBHTF9MRVFVQUwgKi8KKy8qICAgICAgR0xfR1JFQVRFUiAqLworLyogICAgICBHTF9OT1RFUVVBTCAqLworLyogICAgICBHTF9HRVFVQUwgKi8KKy8qICAgICAgR0xfQUxXQVlTICovCisKKy8qIEVuYWJsZUNhcCAqLworI2RlZmluZSBHTF9GT0cgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwQjYwCisjZGVmaW5lIEdMX0xJR0hUSU5HICAgICAgICAgICAgICAgICAgICAgICAweDBCNTAKKyNkZWZpbmUgR0xfVEVYVFVSRV8yRCAgICAgICAgICAgICAgICAgICAgIDB4MERFMQorI2RlZmluZSBHTF9DVUxMX0ZBQ0UgICAgICAgICAgICAgICAgICAgICAgMHgwQjQ0CisjZGVmaW5lIEdMX0FMUEhBX1RFU1QgICAgICAgICAgICAgICAgICAgICAweDBCQzAKKyNkZWZpbmUgR0xfQkxFTkQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MEJFMgorI2RlZmluZSBHTF9DT0xPUl9MT0dJQ19PUCAgICAgICAgICAgICAgICAgMHgwQkYyCisjZGVmaW5lIEdMX0RJVEhFUiAgICAgICAgICAgICAgICAgICAgICAgICAweDBCRDAKKyNkZWZpbmUgR0xfU1RFTkNJTF9URVNUICAgICAgICAgICAgICAgICAgIDB4MEI5MAorI2RlZmluZSBHTF9ERVBUSF9URVNUICAgICAgICAgICAgICAgICAgICAgMHgwQjcxCisvKiAgICAgIEdMX0xJR0hUMCAqLworLyogICAgICBHTF9MSUdIVDEgKi8KKy8qICAgICAgR0xfTElHSFQyICovCisvKiAgICAgIEdMX0xJR0hUMyAqLworLyogICAgICBHTF9MSUdIVDQgKi8KKy8qICAgICAgR0xfTElHSFQ1ICovCisvKiAgICAgIEdMX0xJR0hUNiAqLworLyogICAgICBHTF9MSUdIVDcgKi8KKyNkZWZpbmUgR0xfUE9JTlRfU01PT1RIICAgICAgICAgICAgICAgICAgIDB4MEIxMAorI2RlZmluZSBHTF9MSU5FX1NNT09USCAgICAgICAgICAgICAgICAgICAgMHgwQjIwCisjZGVmaW5lIEdMX1NDSVNTT1JfVEVTVCAgICAgICAgICAgICAgICAgICAweDBDMTEKKyNkZWZpbmUgR0xfQ09MT1JfTUFURVJJQUwgICAgICAgICAgICAgICAgIDB4MEI1NworI2RlZmluZSBHTF9OT1JNQUxJWkUgICAgICAgICAgICAgICAgICAgICAgMHgwQkExCisjZGVmaW5lIEdMX1JFU0NBTEVfTk9STUFMICAgICAgICAgICAgICAgICAweDgwM0EKKyNkZWZpbmUgR0xfUE9MWUdPTl9PRkZTRVRfRklMTCAgICAgICAgICAgIDB4ODAzNworI2RlZmluZSBHTF9WRVJURVhfQVJSQVkgICAgICAgICAgICAgICAgICAgMHg4MDc0CisjZGVmaW5lIEdMX05PUk1BTF9BUlJBWSAgICAgICAgICAgICAgICAgICAweDgwNzUKKyNkZWZpbmUgR0xfQ09MT1JfQVJSQVkgICAgICAgICAgICAgICAgICAgIDB4ODA3NgorI2RlZmluZSBHTF9URVhUVVJFX0NPT1JEX0FSUkFZICAgICAgICAgICAgMHg4MDc4CisjZGVmaW5lIEdMX01VTFRJU0FNUExFICAgICAgICAgICAgICAgICAgICAweDgwOUQKKyNkZWZpbmUgR0xfU0FNUExFX0FMUEhBX1RPX0NPVkVSQUdFICAgICAgIDB4ODA5RQorI2RlZmluZSBHTF9TQU1QTEVfQUxQSEFfVE9fT05FICAgICAgICAgICAgMHg4MDlGCisjZGVmaW5lIEdMX1NBTVBMRV9DT1ZFUkFHRSAgICAgICAgICAgICAgICAweDgwQTAKKworLyogRXJyb3JDb2RlICovCisjZGVmaW5lIEdMX05PX0VSUk9SICAgICAgICAgICAgICAgICAgICAgICAwCisjZGVmaW5lIEdMX0lOVkFMSURfRU5VTSAgICAgICAgICAgICAgICAgICAweDA1MDAKKyNkZWZpbmUgR0xfSU5WQUxJRF9WQUxVRSAgICAgICAgICAgICAgICAgIDB4MDUwMQorI2RlZmluZSBHTF9JTlZBTElEX09QRVJBVElPTiAgICAgICAgICAgICAgMHgwNTAyCisjZGVmaW5lIEdMX1NUQUNLX09WRVJGTE9XICAgICAgICAgICAgICAgICAweDA1MDMKKyNkZWZpbmUgR0xfU1RBQ0tfVU5ERVJGTE9XICAgICAgICAgICAgICAgIDB4MDUwNAorI2RlZmluZSBHTF9PVVRfT0ZfTUVNT1JZICAgICAgICAgICAgICAgICAgMHgwNTA1CisKKy8qIEZvZ01vZGUgKi8KKy8qICAgICAgR0xfTElORUFSICovCisjZGVmaW5lIEdMX0VYUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA4MDAKKyNkZWZpbmUgR0xfRVhQMiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDgwMQorCisvKiBGb2dQYXJhbWV0ZXIgKi8KKyNkZWZpbmUgR0xfRk9HX0RFTlNJVFkgICAgICAgICAgICAgICAgICAgIDB4MEI2MgorI2RlZmluZSBHTF9GT0dfU1RBUlQgICAgICAgICAgICAgICAgICAgICAgMHgwQjYzCisjZGVmaW5lIEdMX0ZPR19FTkQgICAgICAgICAgICAgICAgICAgICAgICAweDBCNjQKKyNkZWZpbmUgR0xfRk9HX01PREUgICAgICAgICAgICAgICAgICAgICAgIDB4MEI2NQorI2RlZmluZSBHTF9GT0dfQ09MT1IgICAgICAgICAgICAgICAgICAgICAgMHgwQjY2CisKKy8qIEZyb250RmFjZURpcmVjdGlvbiAqLworI2RlZmluZSBHTF9DVyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwOTAwCisjZGVmaW5lIEdMX0NDVyAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA5MDEKKworLyogR2V0UE5hbWUgKi8KKyNkZWZpbmUgR0xfQ1VSUkVOVF9DT0xPUiAgICAgICAgICAgICAgICAgIDB4MEIwMAorI2RlZmluZSBHTF9DVVJSRU5UX05PUk1BTCAgICAgICAgICAgICAgICAgMHgwQjAyCisjZGVmaW5lIEdMX0NVUlJFTlRfVEVYVFVSRV9DT09SRFMgICAgICAgICAweDBCMDMKKyNkZWZpbmUgR0xfUE9JTlRfU0laRSAgICAgICAgICAgICAgICAgICAgIDB4MEIxMQorI2RlZmluZSBHTF9QT0lOVF9TSVpFX01JTiAgICAgICAgICAgICAgICAgMHg4MTI2CisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfTUFYICAgICAgICAgICAgICAgICAweDgxMjcKKyNkZWZpbmUgR0xfUE9JTlRfRkFERV9USFJFU0hPTERfU0laRSAgICAgIDB4ODEyOAorI2RlZmluZSBHTF9QT0lOVF9ESVNUQU5DRV9BVFRFTlVBVElPTiAgICAgMHg4MTI5CisjZGVmaW5lIEdMX1NNT09USF9QT0lOVF9TSVpFX1JBTkdFICAgICAgICAweDBCMTIKKyNkZWZpbmUgR0xfTElORV9XSURUSCAgICAgICAgICAgICAgICAgICAgIDB4MEIyMQorI2RlZmluZSBHTF9TTU9PVEhfTElORV9XSURUSF9SQU5HRSAgICAgICAgMHgwQjIyCisjZGVmaW5lIEdMX0FMSUFTRURfUE9JTlRfU0laRV9SQU5HRSAgICAgICAweDg0NkQKKyNkZWZpbmUgR0xfQUxJQVNFRF9MSU5FX1dJRFRIX1JBTkdFICAgICAgIDB4ODQ2RQorI2RlZmluZSBHTF9DVUxMX0ZBQ0VfTU9ERSAgICAgICAgICAgICAgICAgMHgwQjQ1CisjZGVmaW5lIEdMX0ZST05UX0ZBQ0UgICAgICAgICAgICAgICAgICAgICAweDBCNDYKKyNkZWZpbmUgR0xfU0hBREVfTU9ERUwgICAgICAgICAgICAgICAgICAgIDB4MEI1NAorI2RlZmluZSBHTF9ERVBUSF9SQU5HRSAgICAgICAgICAgICAgICAgICAgMHgwQjcwCisjZGVmaW5lIEdMX0RFUFRIX1dSSVRFTUFTSyAgICAgICAgICAgICAgICAweDBCNzIKKyNkZWZpbmUgR0xfREVQVEhfQ0xFQVJfVkFMVUUgICAgICAgICAgICAgIDB4MEI3MworI2RlZmluZSBHTF9ERVBUSF9GVU5DICAgICAgICAgICAgICAgICAgICAgMHgwQjc0CisjZGVmaW5lIEdMX1NURU5DSUxfQ0xFQVJfVkFMVUUgICAgICAgICAgICAweDBCOTEKKyNkZWZpbmUgR0xfU1RFTkNJTF9GVU5DICAgICAgICAgICAgICAgICAgIDB4MEI5MgorI2RlZmluZSBHTF9TVEVOQ0lMX1ZBTFVFX01BU0sgICAgICAgICAgICAgMHgwQjkzCisjZGVmaW5lIEdMX1NURU5DSUxfRkFJTCAgICAgICAgICAgICAgICAgICAweDBCOTQKKyNkZWZpbmUgR0xfU1RFTkNJTF9QQVNTX0RFUFRIX0ZBSUwgICAgICAgIDB4MEI5NQorI2RlZmluZSBHTF9TVEVOQ0lMX1BBU1NfREVQVEhfUEFTUyAgICAgICAgMHgwQjk2CisjZGVmaW5lIEdMX1NURU5DSUxfUkVGICAgICAgICAgICAgICAgICAgICAweDBCOTcKKyNkZWZpbmUgR0xfU1RFTkNJTF9XUklURU1BU0sgICAgICAgICAgICAgIDB4MEI5OAorI2RlZmluZSBHTF9NQVRSSVhfTU9ERSAgICAgICAgICAgICAgICAgICAgMHgwQkEwCisjZGVmaW5lIEdMX1ZJRVdQT1JUICAgICAgICAgICAgICAgICAgICAgICAweDBCQTIKKyNkZWZpbmUgR0xfTU9ERUxWSUVXX1NUQUNLX0RFUFRIICAgICAgICAgIDB4MEJBMworI2RlZmluZSBHTF9QUk9KRUNUSU9OX1NUQUNLX0RFUFRIICAgICAgICAgMHgwQkE0CisjZGVmaW5lIEdMX1RFWFRVUkVfU1RBQ0tfREVQVEggICAgICAgICAgICAweDBCQTUKKyNkZWZpbmUgR0xfTU9ERUxWSUVXX01BVFJJWCAgICAgICAgICAgICAgIDB4MEJBNgorI2RlZmluZSBHTF9QUk9KRUNUSU9OX01BVFJJWCAgICAgICAgICAgICAgMHgwQkE3CisjZGVmaW5lIEdMX1RFWFRVUkVfTUFUUklYICAgICAgICAgICAgICAgICAweDBCQTgKKyNkZWZpbmUgR0xfQUxQSEFfVEVTVF9GVU5DICAgICAgICAgICAgICAgIDB4MEJDMQorI2RlZmluZSBHTF9BTFBIQV9URVNUX1JFRiAgICAgICAgICAgICAgICAgMHgwQkMyCisjZGVmaW5lIEdMX0JMRU5EX0RTVCAgICAgICAgICAgICAgICAgICAgICAweDBCRTAKKyNkZWZpbmUgR0xfQkxFTkRfU1JDICAgICAgICAgICAgICAgICAgICAgIDB4MEJFMQorI2RlZmluZSBHTF9MT0dJQ19PUF9NT0RFICAgICAgICAgICAgICAgICAgMHgwQkYwCisjZGVmaW5lIEdMX1NDSVNTT1JfQk9YICAgICAgICAgICAgICAgICAgICAweDBDMTAKKyNkZWZpbmUgR0xfU0NJU1NPUl9URVNUICAgICAgICAgICAgICAgICAgIDB4MEMxMQorI2RlZmluZSBHTF9DT0xPUl9DTEVBUl9WQUxVRSAgICAgICAgICAgICAgMHgwQzIyCisjZGVmaW5lIEdMX0NPTE9SX1dSSVRFTUFTSyAgICAgICAgICAgICAgICAweDBDMjMKKyNkZWZpbmUgR0xfVU5QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgIDB4MENGNQorI2RlZmluZSBHTF9QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgICAgMHgwRDA1CisjZGVmaW5lIEdMX01BWF9MSUdIVFMgICAgICAgICAgICAgICAgICAgICAweDBEMzEKKyNkZWZpbmUgR0xfTUFYX0NMSVBfUExBTkVTICAgICAgICAgICAgICAgIDB4MEQzMgorI2RlZmluZSBHTF9NQVhfVEVYVFVSRV9TSVpFICAgICAgICAgICAgICAgMHgwRDMzCisjZGVmaW5lIEdMX01BWF9NT0RFTFZJRVdfU1RBQ0tfREVQVEggICAgICAweDBEMzYKKyNkZWZpbmUgR0xfTUFYX1BST0pFQ1RJT05fU1RBQ0tfREVQVEggICAgIDB4MEQzOAorI2RlZmluZSBHTF9NQVhfVEVYVFVSRV9TVEFDS19ERVBUSCAgICAgICAgMHgwRDM5CisjZGVmaW5lIEdMX01BWF9WSUVXUE9SVF9ESU1TICAgICAgICAgICAgICAweDBEM0EKKyNkZWZpbmUgR0xfTUFYX1RFWFRVUkVfVU5JVFMgICAgICAgICAgICAgIDB4ODRFMgorI2RlZmluZSBHTF9TVUJQSVhFTF9CSVRTICAgICAgICAgICAgICAgICAgMHgwRDUwCisjZGVmaW5lIEdMX1JFRF9CSVRTICAgICAgICAgICAgICAgICAgICAgICAweDBENTIKKyNkZWZpbmUgR0xfR1JFRU5fQklUUyAgICAgICAgICAgICAgICAgICAgIDB4MEQ1MworI2RlZmluZSBHTF9CTFVFX0JJVFMgICAgICAgICAgICAgICAgICAgICAgMHgwRDU0CisjZGVmaW5lIEdMX0FMUEhBX0JJVFMgICAgICAgICAgICAgICAgICAgICAweDBENTUKKyNkZWZpbmUgR0xfREVQVEhfQklUUyAgICAgICAgICAgICAgICAgICAgIDB4MEQ1NgorI2RlZmluZSBHTF9TVEVOQ0lMX0JJVFMgICAgICAgICAgICAgICAgICAgMHgwRDU3CisjZGVmaW5lIEdMX1BPTFlHT05fT0ZGU0VUX1VOSVRTICAgICAgICAgICAweDJBMDAKKyNkZWZpbmUgR0xfUE9MWUdPTl9PRkZTRVRfRklMTCAgICAgICAgICAgIDB4ODAzNworI2RlZmluZSBHTF9QT0xZR09OX09GRlNFVF9GQUNUT1IgICAgICAgICAgMHg4MDM4CisjZGVmaW5lIEdMX1RFWFRVUkVfQklORElOR18yRCAgICAgICAgICAgICAweDgwNjkKKyNkZWZpbmUgR0xfVkVSVEVYX0FSUkFZX1NJWkUgICAgICAgICAgICAgIDB4ODA3QQorI2RlZmluZSBHTF9WRVJURVhfQVJSQVlfVFlQRSAgICAgICAgICAgICAgMHg4MDdCCisjZGVmaW5lIEdMX1ZFUlRFWF9BUlJBWV9TVFJJREUgICAgICAgICAgICAweDgwN0MKKyNkZWZpbmUgR0xfTk9STUFMX0FSUkFZX1RZUEUgICAgICAgICAgICAgIDB4ODA3RQorI2RlZmluZSBHTF9OT1JNQUxfQVJSQVlfU1RSSURFICAgICAgICAgICAgMHg4MDdGCisjZGVmaW5lIEdMX0NPTE9SX0FSUkFZX1NJWkUgICAgICAgICAgICAgICAweDgwODEKKyNkZWZpbmUgR0xfQ09MT1JfQVJSQVlfVFlQRSAgICAgICAgICAgICAgIDB4ODA4MgorI2RlZmluZSBHTF9DT0xPUl9BUlJBWV9TVFJJREUgICAgICAgICAgICAgMHg4MDgzCisjZGVmaW5lIEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfU0laRSAgICAgICAweDgwODgKKyNkZWZpbmUgR0xfVEVYVFVSRV9DT09SRF9BUlJBWV9UWVBFICAgICAgIDB4ODA4OQorI2RlZmluZSBHTF9URVhUVVJFX0NPT1JEX0FSUkFZX1NUUklERSAgICAgMHg4MDhBCisjZGVmaW5lIEdMX1ZFUlRFWF9BUlJBWV9QT0lOVEVSICAgICAgICAgICAweDgwOEUKKyNkZWZpbmUgR0xfTk9STUFMX0FSUkFZX1BPSU5URVIgICAgICAgICAgIDB4ODA4RgorI2RlZmluZSBHTF9DT0xPUl9BUlJBWV9QT0lOVEVSICAgICAgICAgICAgMHg4MDkwCisjZGVmaW5lIEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfUE9JTlRFUiAgICAweDgwOTIKKyNkZWZpbmUgR0xfU0FNUExFX0JVRkZFUlMgICAgICAgICAgICAgICAgIDB4ODBBOAorI2RlZmluZSBHTF9TQU1QTEVTICAgICAgICAgICAgICAgICAgICAgICAgMHg4MEE5CisjZGVmaW5lIEdMX1NBTVBMRV9DT1ZFUkFHRV9WQUxVRSAgICAgICAgICAweDgwQUEKKyNkZWZpbmUgR0xfU0FNUExFX0NPVkVSQUdFX0lOVkVSVCAgICAgICAgIDB4ODBBQgorCisvKiBHZXRUZXh0dXJlUGFyYW1ldGVyICovCisvKiAgICAgIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiAqLworLyogICAgICBHTF9URVhUVVJFX01JTl9GSUxURVIgKi8KKy8qICAgICAgR0xfVEVYVFVSRV9XUkFQX1MgKi8KKy8qICAgICAgR0xfVEVYVFVSRV9XUkFQX1QgKi8KKworI2RlZmluZSBHTF9OVU1fQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFMgMHg4NkEyCisjZGVmaW5lIEdMX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTICAgICAweDg2QTMKKworLyogSGludE1vZGUgKi8KKyNkZWZpbmUgR0xfRE9OVF9DQVJFICAgICAgICAgICAgICAgICAgICAgIDB4MTEwMAorI2RlZmluZSBHTF9GQVNURVNUICAgICAgICAgICAgICAgICAgICAgICAgMHgxMTAxCisjZGVmaW5lIEdMX05JQ0VTVCAgICAgICAgICAgICAgICAgICAgICAgICAweDExMDIKKworLyogSGludFRhcmdldCAqLworI2RlZmluZSBHTF9QRVJTUEVDVElWRV9DT1JSRUNUSU9OX0hJTlQgICAgMHgwQzUwCisjZGVmaW5lIEdMX1BPSU5UX1NNT09USF9ISU5UICAgICAgICAgICAgICAweDBDNTEKKyNkZWZpbmUgR0xfTElORV9TTU9PVEhfSElOVCAgICAgICAgICAgICAgIDB4MEM1MgorI2RlZmluZSBHTF9GT0dfSElOVCAgICAgICAgICAgICAgICAgICAgICAgMHgwQzU0CisjZGVmaW5lIEdMX0dFTkVSQVRFX01JUE1BUF9ISU5UICAgICAgICAgICAweDgxOTIKKworLyogTGlnaHRNb2RlbFBhcmFtZXRlciAqLworI2RlZmluZSBHTF9MSUdIVF9NT0RFTF9BTUJJRU5UICAgICAgICAgICAgMHgwQjUzCisjZGVmaW5lIEdMX0xJR0hUX01PREVMX1RXT19TSURFICAgICAgICAgICAweDBCNTIKKworLyogTGlnaHRQYXJhbWV0ZXIgKi8KKyNkZWZpbmUgR0xfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgIDB4MTIwMAorI2RlZmluZSBHTF9ESUZGVVNFICAgICAgICAgICAgICAgICAgICAgICAgMHgxMjAxCisjZGVmaW5lIEdMX1NQRUNVTEFSICAgICAgICAgICAgICAgICAgICAgICAweDEyMDIKKyNkZWZpbmUgR0xfUE9TSVRJT04gICAgICAgICAgICAgICAgICAgICAgIDB4MTIwMworI2RlZmluZSBHTF9TUE9UX0RJUkVDVElPTiAgICAgICAgICAgICAgICAgMHgxMjA0CisjZGVmaW5lIEdMX1NQT1RfRVhQT05FTlQgICAgICAgICAgICAgICAgICAweDEyMDUKKyNkZWZpbmUgR0xfU1BPVF9DVVRPRkYgICAgICAgICAgICAgICAgICAgIDB4MTIwNgorI2RlZmluZSBHTF9DT05TVEFOVF9BVFRFTlVBVElPTiAgICAgICAgICAgMHgxMjA3CisjZGVmaW5lIEdMX0xJTkVBUl9BVFRFTlVBVElPTiAgICAgICAgICAgICAweDEyMDgKKyNkZWZpbmUgR0xfUVVBRFJBVElDX0FUVEVOVUFUSU9OICAgICAgICAgIDB4MTIwOQorCisvKiBEYXRhVHlwZSAqLworI2RlZmluZSBHTF9CWVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNDAwCisjZGVmaW5lIEdMX1VOU0lHTkVEX0JZVEUgICAgICAgICAgICAgICAgICAweDE0MDEKKyNkZWZpbmUgR0xfU0hPUlQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTQwMgorI2RlZmluZSBHTF9VTlNJR05FRF9TSE9SVCAgICAgICAgICAgICAgICAgMHgxNDAzCisjZGVmaW5lIEdMX0ZMT0FUICAgICAgICAgICAgICAgICAgICAgICAgICAweDE0MDYKKyNkZWZpbmUgR0xfRklYRUQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTQwQworCisvKiBMb2dpY09wICovCisjZGVmaW5lIEdMX0NMRUFSICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDAKKyNkZWZpbmUgR0xfQU5EICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwMQorI2RlZmluZSBHTF9BTkRfUkVWRVJTRSAgICAgICAgICAgICAgICAgICAgMHgxNTAyCisjZGVmaW5lIEdMX0NPUFkgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDMKKyNkZWZpbmUgR0xfQU5EX0lOVkVSVEVEICAgICAgICAgICAgICAgICAgIDB4MTUwNAorI2RlZmluZSBHTF9OT09QICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTA1CisjZGVmaW5lIEdMX1hPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDYKKyNkZWZpbmUgR0xfT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwNworI2RlZmluZSBHTF9OT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTA4CisjZGVmaW5lIEdMX0VRVUlWICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDkKKyNkZWZpbmUgR0xfSU5WRVJUICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwQQorI2RlZmluZSBHTF9PUl9SRVZFUlNFICAgICAgICAgICAgICAgICAgICAgMHgxNTBCCisjZGVmaW5lIEdMX0NPUFlfSU5WRVJURUQgICAgICAgICAgICAgICAgICAweDE1MEMKKyNkZWZpbmUgR0xfT1JfSU5WRVJURUQgICAgICAgICAgICAgICAgICAgIDB4MTUwRAorI2RlZmluZSBHTF9OQU5EICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTBFCisjZGVmaW5lIEdMX1NFVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MEYKKworLyogTWF0ZXJpYWxGYWNlICovCisvKiAgICAgIEdMX0ZST05UX0FORF9CQUNLICovCisKKy8qIE1hdGVyaWFsUGFyYW1ldGVyICovCisjZGVmaW5lIEdMX0VNSVNTSU9OICAgICAgICAgICAgICAgICAgICAgICAweDE2MDAKKyNkZWZpbmUgR0xfU0hJTklORVNTICAgICAgICAgICAgICAgICAgICAgIDB4MTYwMQorI2RlZmluZSBHTF9BTUJJRU5UX0FORF9ESUZGVVNFICAgICAgICAgICAgMHgxNjAyCisvKiAgICAgIEdMX0FNQklFTlQgKi8KKy8qICAgICAgR0xfRElGRlVTRSAqLworLyogICAgICBHTF9TUEVDVUxBUiAqLworCisvKiBNYXRyaXhNb2RlICovCisjZGVmaW5lIEdMX01PREVMVklFVyAgICAgICAgICAgICAgICAgICAgICAweDE3MDAKKyNkZWZpbmUgR0xfUFJPSkVDVElPTiAgICAgICAgICAgICAgICAgICAgIDB4MTcwMQorI2RlZmluZSBHTF9URVhUVVJFICAgICAgICAgICAgICAgICAgICAgICAgMHgxNzAyCisKKy8qIE5vcm1hbFBvaW50ZXJUeXBlICovCisvKiAgICAgIEdMX0JZVEUgKi8KKy8qICAgICAgR0xfU0hPUlQgKi8KKy8qICAgICAgR0xfRkxPQVQgKi8KKy8qICAgICAgR0xfRklYRUQgKi8KKworLyogUGl4ZWxGb3JtYXQgKi8KKyNkZWZpbmUgR0xfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTkwNgorI2RlZmluZSBHTF9SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxOTA3CisjZGVmaW5lIEdMX1JHQkEgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE5MDgKKyNkZWZpbmUgR0xfTFVNSU5BTkNFICAgICAgICAgICAgICAgICAgICAgIDB4MTkwOQorI2RlZmluZSBHTF9MVU1JTkFOQ0VfQUxQSEEgICAgICAgICAgICAgICAgMHgxOTBBCisKKy8qIFBpeGVsU3RvcmVQYXJhbWV0ZXIgKi8KKyNkZWZpbmUgR0xfVU5QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgIDB4MENGNQorI2RlZmluZSBHTF9QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgICAgMHgwRDA1CisKKy8qIFBpeGVsVHlwZSAqLworLyogICAgICBHTF9VTlNJR05FRF9CWVRFICovCisjZGVmaW5lIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQgICAgICAgICAweDgwMzMKKyNkZWZpbmUgR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMSAgICAgICAgIDB4ODAzNAorI2RlZmluZSBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSAgICAgICAgICAgMHg4MzYzCisKKy8qIFNoYWRpbmdNb2RlbCAqLworI2RlZmluZSBHTF9GTEFUICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRDAwCisjZGVmaW5lIEdMX1NNT09USCAgICAgICAgICAgICAgICAgICAgICAgICAweDFEMDEKKworLyogU3RlbmNpbEZ1bmN0aW9uICovCisvKiAgICAgIEdMX05FVkVSICovCisvKiAgICAgIEdMX0xFU1MgKi8KKy8qICAgICAgR0xfRVFVQUwgKi8KKy8qICAgICAgR0xfTEVRVUFMICovCisvKiAgICAgIEdMX0dSRUFURVIgKi8KKy8qICAgICAgR0xfTk9URVFVQUwgKi8KKy8qICAgICAgR0xfR0VRVUFMICovCisvKiAgICAgIEdMX0FMV0FZUyAqLworCisvKiBTdGVuY2lsT3AgKi8KKy8qICAgICAgR0xfWkVSTyAqLworI2RlZmluZSBHTF9LRUVQICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRTAwCisjZGVmaW5lIEdMX1JFUExBQ0UgICAgICAgICAgICAgICAgICAgICAgICAweDFFMDEKKyNkZWZpbmUgR0xfSU5DUiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MUUwMgorI2RlZmluZSBHTF9ERUNSICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRTAzCisvKiAgICAgIEdMX0lOVkVSVCAqLworCisvKiBTdHJpbmdOYW1lICovCisjZGVmaW5lIEdMX1ZFTkRPUiAgICAgICAgICAgICAgICAgICAgICAgICAweDFGMDAKKyNkZWZpbmUgR0xfUkVOREVSRVIgICAgICAgICAgICAgICAgICAgICAgIDB4MUYwMQorI2RlZmluZSBHTF9WRVJTSU9OICAgICAgICAgICAgICAgICAgICAgICAgMHgxRjAyCisjZGVmaW5lIEdMX0VYVEVOU0lPTlMgICAgICAgICAgICAgICAgICAgICAweDFGMDMKKworLyogVGV4Q29vcmRQb2ludGVyVHlwZSAqLworLyogICAgICBHTF9TSE9SVCAqLworLyogICAgICBHTF9GTE9BVCAqLworLyogICAgICBHTF9GSVhFRCAqLworLyogICAgICBHTF9CWVRFICovCisKKy8qIFRleHR1cmVFbnZNb2RlICovCisjZGVmaW5lIEdMX01PRFVMQVRFICAgICAgICAgICAgICAgICAgICAgICAweDIxMDAKKyNkZWZpbmUgR0xfREVDQUwgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjEwMQorLyogICAgICBHTF9CTEVORCAqLworI2RlZmluZSBHTF9BREQgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMTA0CisvKiAgICAgIEdMX1JFUExBQ0UgKi8KKworLyogVGV4dHVyZUVudlBhcmFtZXRlciAqLworI2RlZmluZSBHTF9URVhUVVJFX0VOVl9NT0RFICAgICAgICAgICAgICAgMHgyMjAwCisjZGVmaW5lIEdMX1RFWFRVUkVfRU5WX0NPTE9SICAgICAgICAgICAgICAweDIyMDEKKworLyogVGV4dHVyZUVudlRhcmdldCAqLworI2RlZmluZSBHTF9URVhUVVJFX0VOViAgICAgICAgICAgICAgICAgICAgMHgyMzAwCisKKy8qIFRleHR1cmVNYWdGaWx0ZXIgKi8KKyNkZWZpbmUgR0xfTkVBUkVTVCAgICAgICAgICAgICAgICAgICAgICAgIDB4MjYwMAorI2RlZmluZSBHTF9MSU5FQVIgICAgICAgICAgICAgICAgICAgICAgICAgMHgyNjAxCisKKy8qIFRleHR1cmVNaW5GaWx0ZXIgKi8KKy8qICAgICAgR0xfTkVBUkVTVCAqLworLyogICAgICBHTF9MSU5FQVIgKi8KKyNkZWZpbmUgR0xfTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCAgICAgICAgIDB4MjcwMAorI2RlZmluZSBHTF9MSU5FQVJfTUlQTUFQX05FQVJFU1QgICAgICAgICAgMHgyNzAxCisjZGVmaW5lIEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUiAgICAgICAgICAweDI3MDIKKyNkZWZpbmUgR0xfTElORUFSX01JUE1BUF9MSU5FQVIgICAgICAgICAgIDB4MjcwMworCisvKiBUZXh0dXJlUGFyYW1ldGVyTmFtZSAqLworI2RlZmluZSBHTF9URVhUVVJFX01BR19GSUxURVIgICAgICAgICAgICAgMHgyODAwCisjZGVmaW5lIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiAgICAgICAgICAgICAweDI4MDEKKyNkZWZpbmUgR0xfVEVYVFVSRV9XUkFQX1MgICAgICAgICAgICAgICAgIDB4MjgwMgorI2RlZmluZSBHTF9URVhUVVJFX1dSQVBfVCAgICAgICAgICAgICAgICAgMHgyODAzCisjZGVmaW5lIEdMX0dFTkVSQVRFX01JUE1BUCAgICAgICAgICAgICAgICAweDgxOTEKKworLyogVGV4dHVyZVRhcmdldCAqLworLyogICAgICBHTF9URVhUVVJFXzJEICovCisKKy8qIFRleHR1cmVVbml0ICovCisjZGVmaW5lIEdMX1RFWFRVUkUwICAgICAgICAgICAgICAgICAgICAgICAweDg0QzAKKyNkZWZpbmUgR0xfVEVYVFVSRTEgICAgICAgICAgICAgICAgICAgICAgIDB4ODRDMQorI2RlZmluZSBHTF9URVhUVVJFMiAgICAgICAgICAgICAgICAgICAgICAgMHg4NEMyCisjZGVmaW5lIEdMX1RFWFRVUkUzICAgICAgICAgICAgICAgICAgICAgICAweDg0QzMKKyNkZWZpbmUgR0xfVEVYVFVSRTQgICAgICAgICAgICAgICAgICAgICAgIDB4ODRDNAorI2RlZmluZSBHTF9URVhUVVJFNSAgICAgICAgICAgICAgICAgICAgICAgMHg4NEM1CisjZGVmaW5lIEdMX1RFWFRVUkU2ICAgICAgICAgICAgICAgICAgICAgICAweDg0QzYKKyNkZWZpbmUgR0xfVEVYVFVSRTcgICAgICAgICAgICAgICAgICAgICAgIDB4ODRDNworI2RlZmluZSBHTF9URVhUVVJFOCAgICAgICAgICAgICAgICAgICAgICAgMHg4NEM4CisjZGVmaW5lIEdMX1RFWFRVUkU5ICAgICAgICAgICAgICAgICAgICAgICAweDg0QzkKKyNkZWZpbmUgR0xfVEVYVFVSRTEwICAgICAgICAgICAgICAgICAgICAgIDB4ODRDQQorI2RlZmluZSBHTF9URVhUVVJFMTEgICAgICAgICAgICAgICAgICAgICAgMHg4NENCCisjZGVmaW5lIEdMX1RFWFRVUkUxMiAgICAgICAgICAgICAgICAgICAgICAweDg0Q0MKKyNkZWZpbmUgR0xfVEVYVFVSRTEzICAgICAgICAgICAgICAgICAgICAgIDB4ODRDRAorI2RlZmluZSBHTF9URVhUVVJFMTQgICAgICAgICAgICAgICAgICAgICAgMHg4NENFCisjZGVmaW5lIEdMX1RFWFRVUkUxNSAgICAgICAgICAgICAgICAgICAgICAweDg0Q0YKKyNkZWZpbmUgR0xfVEVYVFVSRTE2ICAgICAgICAgICAgICAgICAgICAgIDB4ODREMAorI2RlZmluZSBHTF9URVhUVVJFMTcgICAgICAgICAgICAgICAgICAgICAgMHg4NEQxCisjZGVmaW5lIEdMX1RFWFRVUkUxOCAgICAgICAgICAgICAgICAgICAgICAweDg0RDIKKyNkZWZpbmUgR0xfVEVYVFVSRTE5ICAgICAgICAgICAgICAgICAgICAgIDB4ODREMworI2RlZmluZSBHTF9URVhUVVJFMjAgICAgICAgICAgICAgICAgICAgICAgMHg4NEQ0CisjZGVmaW5lIEdMX1RFWFRVUkUyMSAgICAgICAgICAgICAgICAgICAgICAweDg0RDUKKyNkZWZpbmUgR0xfVEVYVFVSRTIyICAgICAgICAgICAgICAgICAgICAgIDB4ODRENgorI2RlZmluZSBHTF9URVhUVVJFMjMgICAgICAgICAgICAgICAgICAgICAgMHg4NEQ3CisjZGVmaW5lIEdMX1RFWFRVUkUyNCAgICAgICAgICAgICAgICAgICAgICAweDg0RDgKKyNkZWZpbmUgR0xfVEVYVFVSRTI1ICAgICAgICAgICAgICAgICAgICAgIDB4ODREOQorI2RlZmluZSBHTF9URVhUVVJFMjYgICAgICAgICAgICAgICAgICAgICAgMHg4NERBCisjZGVmaW5lIEdMX1RFWFRVUkUyNyAgICAgICAgICAgICAgICAgICAgICAweDg0REIKKyNkZWZpbmUgR0xfVEVYVFVSRTI4ICAgICAgICAgICAgICAgICAgICAgIDB4ODREQworI2RlZmluZSBHTF9URVhUVVJFMjkgICAgICAgICAgICAgICAgICAgICAgMHg4NERECisjZGVmaW5lIEdMX1RFWFRVUkUzMCAgICAgICAgICAgICAgICAgICAgICAweDg0REUKKyNkZWZpbmUgR0xfVEVYVFVSRTMxICAgICAgICAgICAgICAgICAgICAgIDB4ODRERgorI2RlZmluZSBHTF9BQ1RJVkVfVEVYVFVSRSAgICAgICAgICAgICAgICAgMHg4NEUwCisjZGVmaW5lIEdMX0NMSUVOVF9BQ1RJVkVfVEVYVFVSRSAgICAgICAgICAweDg0RTEKKworLyogVGV4dHVyZVdyYXBNb2RlICovCisjZGVmaW5lIEdMX1JFUEVBVCAgICAgICAgICAgICAgICAgICAgICAgICAweDI5MDEKKyNkZWZpbmUgR0xfQ0xBTVBfVE9fRURHRSAgICAgICAgICAgICAgICAgIDB4ODEyRgorCisvKiBWZXJ0ZXhQb2ludGVyVHlwZSAqLworLyogICAgICBHTF9TSE9SVCAqLworLyogICAgICBHTF9GTE9BVCAqLworLyogICAgICBHTF9GSVhFRCAqLworLyogICAgICBHTF9CWVRFICovCisKKy8qIExpZ2h0TmFtZSAqLworI2RlZmluZSBHTF9MSUdIVDAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAwCisjZGVmaW5lIEdMX0xJR0hUMSAgICAgICAgICAgICAgICAgICAgICAgICAweDQwMDEKKyNkZWZpbmUgR0xfTElHSFQyICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAwMgorI2RlZmluZSBHTF9MSUdIVDMgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAzCisjZGVmaW5lIEdMX0xJR0hUNCAgICAgICAgICAgICAgICAgICAgICAgICAweDQwMDQKKyNkZWZpbmUgR0xfTElHSFQ1ICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAwNQorI2RlZmluZSBHTF9MSUdIVDYgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDA2CisjZGVmaW5lIEdMX0xJR0hUNyAgICAgICAgICAgICAgICAgICAgICAgICAweDQwMDcKKworLyogQnVmZmVyIE9iamVjdHMgKi8KKyNkZWZpbmUgR0xfQVJSQVlfQlVGRkVSICAgICAgICAgICAgICAgICAgIDB4ODg5MgorI2RlZmluZSBHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiAgICAgICAgICAgMHg4ODkzCisKKyNkZWZpbmUgR0xfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICAgICAgICAgICAweDg4OTQKKyNkZWZpbmUgR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVJfQklORElORyAgICAgICAweDg4OTUKKyNkZWZpbmUgR0xfVkVSVEVYX0FSUkFZX0JVRkZFUl9CSU5ESU5HICAgICAgICAweDg4OTYKKyNkZWZpbmUgR0xfTk9STUFMX0FSUkFZX0JVRkZFUl9CSU5ESU5HICAgICAgICAweDg4OTcKKyNkZWZpbmUgR0xfQ09MT1JfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICAgICAweDg4OTgKKyNkZWZpbmUgR0xfVEVYVFVSRV9DT09SRF9BUlJBWV9CVUZGRVJfQklORElORyAweDg4OUEKKworI2RlZmluZSBHTF9TVEFUSUNfRFJBVyAgICAgICAgICAgICAgICAgICAgMHg4OEU0CisjZGVmaW5lIEdMX0RZTkFNSUNfRFJBVyAgICAgICAgICAgICAgICAgICAweDg4RTgKKworI2RlZmluZSBHTF9CVUZGRVJfU0laRSAgICAgICAgICAgICAgICAgICAgMHg4NzY0CisjZGVmaW5lIEdMX0JVRkZFUl9VU0FHRSAgICAgICAgICAgICAgICAgICAweDg3NjUKKworLyogVGV4dHVyZSBjb21iaW5lICsgZG90MyAqLworI2RlZmluZSBHTF9TVUJUUkFDVCAgICAgICAgICAgICAgICAgICAgICAgMHg4NEU3CisjZGVmaW5lIEdMX0NPTUJJTkUgICAgICAgICAgICAgICAgICAgICAgICAweDg1NzAKKyNkZWZpbmUgR0xfQ09NQklORV9SR0IgICAgICAgICAgICAgICAgICAgIDB4ODU3MQorI2RlZmluZSBHTF9DT01CSU5FX0FMUEhBICAgICAgICAgICAgICAgICAgMHg4NTcyCisjZGVmaW5lIEdMX1JHQl9TQ0FMRSAgICAgICAgICAgICAgICAgICAgICAweDg1NzMKKyNkZWZpbmUgR0xfQUREX1NJR05FRCAgICAgICAgICAgICAgICAgICAgIDB4ODU3NAorI2RlZmluZSBHTF9JTlRFUlBPTEFURSAgICAgICAgICAgICAgICAgICAgMHg4NTc1CisjZGVmaW5lIEdMX0NPTlNUQU5UICAgICAgICAgICAgICAgICAgICAgICAweDg1NzYKKyNkZWZpbmUgR0xfUFJJTUFSWV9DT0xPUiAgICAgICAgICAgICAgICAgIDB4ODU3NworI2RlZmluZSBHTF9QUkVWSU9VUyAgICAgICAgICAgICAgICAgICAgICAgMHg4NTc4CisjZGVmaW5lIEdMX09QRVJBTkQwX1JHQiAgICAgICAgICAgICAgICAgICAweDg1OTAKKyNkZWZpbmUgR0xfT1BFUkFORDFfUkdCICAgICAgICAgICAgICAgICAgIDB4ODU5MQorI2RlZmluZSBHTF9PUEVSQU5EMl9SR0IgICAgICAgICAgICAgICAgICAgMHg4NTkyCisjZGVmaW5lIEdMX09QRVJBTkQwX0FMUEhBICAgICAgICAgICAgICAgICAweDg1OTgKKyNkZWZpbmUgR0xfT1BFUkFORDFfQUxQSEEgICAgICAgICAgICAgICAgIDB4ODU5OQorI2RlZmluZSBHTF9PUEVSQU5EMl9BTFBIQSAgICAgICAgICAgICAgICAgMHg4NTlBCisKKyNkZWZpbmUgR0xfQUxQSEFfU0NBTEUgICAgICAgICAgICAgICAgICAgIDB4MEQxQworCisjZGVmaW5lIEdMX1NSQzBfUkdCICAgICAgICAgICAgICAgICAgICAgICAweDg1ODAKKyNkZWZpbmUgR0xfU1JDMV9SR0IgICAgICAgICAgICAgICAgICAgICAgIDB4ODU4MQorI2RlZmluZSBHTF9TUkMyX1JHQiAgICAgICAgICAgICAgICAgICAgICAgMHg4NTgyCisjZGVmaW5lIEdMX1NSQzBfQUxQSEEgICAgICAgICAgICAgICAgICAgICAweDg1ODgKKyNkZWZpbmUgR0xfU1JDMV9BTFBIQSAgICAgICAgICAgICAgICAgICAgIDB4ODU4OQorI2RlZmluZSBHTF9TUkMyX0FMUEhBICAgICAgICAgICAgICAgICAgICAgMHg4NThBCisKKyNkZWZpbmUgR0xfRE9UM19SR0IgICAgICAgICAgICAgICAgICAgICAgIDB4ODZBRQorI2RlZmluZSBHTF9ET1QzX1JHQkEgICAgICAgICAgICAgICAgICAgICAgMHg4NkFGCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKgorICogcmVxdWlyZWQgT0VTIGV4dGVuc2lvbiB0b2tlbnMKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworLyogT0VTX3JlYWRfZm9ybWF0ICovCisjaWZuZGVmIEdMX09FU19yZWFkX2Zvcm1hdAorI2RlZmluZSBHTF9JTVBMRU1FTlRBVElPTl9DT0xPUl9SRUFEX1RZUEVfT0VTICAgICAgICAgICAgICAgICAgIDB4OEI5QQorI2RlZmluZSBHTF9JTVBMRU1FTlRBVElPTl9DT0xPUl9SRUFEX0ZPUk1BVF9PRVMgICAgICAgICAgICAgICAgIDB4OEI5QgorI2VuZGlmCisKKy8qIEdMX09FU19jb21wcmVzc2VkX3BhbGV0dGVkX3RleHR1cmUgKi8KKyNpZm5kZWYgR0xfT0VTX2NvbXByZXNzZWRfcGFsZXR0ZWRfdGV4dHVyZQorI2RlZmluZSBHTF9QQUxFVFRFNF9SR0I4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5MAorI2RlZmluZSBHTF9QQUxFVFRFNF9SR0JBOF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5MQorI2RlZmluZSBHTF9QQUxFVFRFNF9SNV9HNl9CNV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5MgorI2RlZmluZSBHTF9QQUxFVFRFNF9SR0JBNF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5MworI2RlZmluZSBHTF9QQUxFVFRFNF9SR0I1X0ExX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5NAorI2RlZmluZSBHTF9QQUxFVFRFOF9SR0I4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5NQorI2RlZmluZSBHTF9QQUxFVFRFOF9SR0JBOF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5NgorI2RlZmluZSBHTF9QQUxFVFRFOF9SNV9HNl9CNV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5NworI2RlZmluZSBHTF9QQUxFVFRFOF9SR0JBNF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5OAorI2RlZmluZSBHTF9QQUxFVFRFOF9SR0I1X0ExX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5OQorI2VuZGlmCisKKy8qIE9FU19wb2ludF9zaXplX2FycmF5ICovCisjaWZuZGVmIEdMX09FU19wb2ludF9zaXplX2FycmF5CisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfQVJSQVlfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4QjlDCisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfQVJSQVlfVFlQRV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OThBCisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfQVJSQVlfU1RSSURFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OThCCisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfQVJSQVlfUE9JTlRFUl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OThDCisjZGVmaW5lIEdMX1BPSU5UX1NJWkVfQVJSQVlfQlVGRkVSX0JJTkRJTkdfT0VTICAgICAgICAgICAgICAgICAgMHg4QjlGCisjZW5kaWYKKworLyogR0xfT0VTX3BvaW50X3Nwcml0ZSAqLworI2lmbmRlZiBHTF9PRVNfcG9pbnRfc3ByaXRlCisjZGVmaW5lIEdMX1BPSU5UX1NQUklURV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODYxCisjZGVmaW5lIEdMX0NPT1JEX1JFUExBQ0VfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODYyCisjZW5kaWYKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIEF2YWlsYWJsZSBvbmx5IGluIENvbW1vbiBwcm9maWxlICovCitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEFscGhhRnVuYyAoR0xlbnVtIGZ1bmMsIEdMY2xhbXBmIHJlZik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyQ29sb3IgKEdMY2xhbXBmIHJlZCwgR0xjbGFtcGYgZ3JlZW4sIEdMY2xhbXBmIGJsdWUsIEdMY2xhbXBmIGFscGhhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ2xlYXJEZXB0aGYgKEdMY2xhbXBmIGRlcHRoKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ2xpcFBsYW5lZiAoR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZsb2F0ICplcXVhdGlvbik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENvbG9yNGYgKEdMZmxvYXQgcmVkLCBHTGZsb2F0IGdyZWVuLCBHTGZsb2F0IGJsdWUsIEdMZmxvYXQgYWxwaGEpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xEZXB0aFJhbmdlZiAoR0xjbGFtcGYgek5lYXIsIEdMY2xhbXBmIHpGYXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGb2dmIChHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGb2dmdiAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGcnVzdHVtZiAoR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LCBHTGZsb2F0IGJvdHRvbSwgR0xmbG9hdCB0b3AsIEdMZmxvYXQgek5lYXIsIEdMZmxvYXQgekZhcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldENsaXBQbGFuZWYgKEdMZW51bSBwbmFtZSwgR0xmbG9hdCBlcW5bNF0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRGbG9hdHYgKEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0TGlnaHRmdiAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldE1hdGVyaWFsZnYgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldFRleEVudmZ2IChHTGVudW0gZW52LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldFRleFBhcmFtZXRlcmZ2IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExpZ2h0TW9kZWxmIChHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaWdodE1vZGVsZnYgKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTGlnaHRmIChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExpZ2h0ZnYgKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaW5lV2lkdGggKEdMZmxvYXQgd2lkdGgpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMb2FkTWF0cml4ZiAoY29uc3QgR0xmbG9hdCAqbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE1hdGVyaWFsZiAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE1hdGVyaWFsZnYgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE11bHRNYXRyaXhmIChjb25zdCBHTGZsb2F0ICptKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTXVsdGlUZXhDb29yZDRmIChHTGVudW0gdGFyZ2V0LCBHTGZsb2F0IHMsIEdMZmxvYXQgdCwgR0xmbG9hdCByLCBHTGZsb2F0IHEpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xOb3JtYWwzZiAoR0xmbG9hdCBueCwgR0xmbG9hdCBueSwgR0xmbG9hdCBueik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE9ydGhvZiAoR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LCBHTGZsb2F0IGJvdHRvbSwgR0xmbG9hdCB0b3AsIEdMZmxvYXQgek5lYXIsIEdMZmxvYXQgekZhcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFBvaW50UGFyYW1ldGVyZiAoR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUG9pbnRQYXJhbWV0ZXJmdiAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQb2ludFNpemUgKEdMZmxvYXQgc2l6ZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFBvbHlnb25PZmZzZXQgKEdMZmxvYXQgZmFjdG9yLCBHTGZsb2F0IHVuaXRzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUm90YXRlZiAoR0xmbG9hdCBhbmdsZSwgR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFNjYWxlZiAoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleEVudmYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleEVudmZ2IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleFBhcmFtZXRlcmYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleFBhcmFtZXRlcmZ2IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRyYW5zbGF0ZWYgKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopOworCisvKiBBdmFpbGFibGUgaW4gYm90aCBDb21tb24gYW5kIENvbW1vbi1MaXRlIHByb2ZpbGVzICovCitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEFjdGl2ZVRleHR1cmUgKEdMZW51bSB0ZXh0dXJlKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQWxwaGFGdW5jeCAoR0xlbnVtIGZ1bmMsIEdMY2xhbXB4IHJlZik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJpbmRCdWZmZXIgKEdMZW51bSB0YXJnZXQsIEdMdWludCBidWZmZXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xCaW5kVGV4dHVyZSAoR0xlbnVtIHRhcmdldCwgR0x1aW50IHRleHR1cmUpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xCbGVuZEZ1bmMgKEdMZW51bSBzZmFjdG9yLCBHTGVudW0gZGZhY3Rvcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJ1ZmZlckRhdGEgKEdMZW51bSB0YXJnZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhLCBHTGVudW0gdXNhZ2UpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xCdWZmZXJTdWJEYXRhIChHTGVudW0gdGFyZ2V0LCBHTGludHB0ciBvZmZzZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ2xlYXIgKEdMYml0ZmllbGQgbWFzayk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyQ29sb3J4IChHTGNsYW1weCByZWQsIEdMY2xhbXB4IGdyZWVuLCBHTGNsYW1weCBibHVlLCBHTGNsYW1weCBhbHBoYSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyRGVwdGh4IChHTGNsYW1weCBkZXB0aCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyU3RlbmNpbCAoR0xpbnQgcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsaWVudEFjdGl2ZVRleHR1cmUgKEdMZW51bSB0ZXh0dXJlKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ2xpcFBsYW5leCAoR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZpeGVkICplcXVhdGlvbik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENvbG9yNHViIChHTHVieXRlIHJlZCwgR0x1Ynl0ZSBncmVlbiwgR0x1Ynl0ZSBibHVlLCBHTHVieXRlIGFscGhhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ29sb3I0eCAoR0xmaXhlZCByZWQsIEdMZml4ZWQgZ3JlZW4sIEdMZml4ZWQgYmx1ZSwgR0xmaXhlZCBhbHBoYSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENvbG9yTWFzayAoR0xib29sZWFuIHJlZCwgR0xib29sZWFuIGdyZWVuLCBHTGJvb2xlYW4gYmx1ZSwgR0xib29sZWFuIGFscGhhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ29sb3JQb2ludGVyIChHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENvbXByZXNzZWRUZXhJbWFnZTJEIChHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyLCBHTHNpemVpIGltYWdlU2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQgKEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xzaXplaSBpbWFnZVNpemUsIGNvbnN0IEdMdm9pZCAqZGF0YSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENvcHlUZXhJbWFnZTJEIChHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ29weVRleFN1YkltYWdlMkQgKEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEN1bGxGYWNlIChHTGVudW0gbW9kZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbERlbGV0ZUJ1ZmZlcnMgKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICpidWZmZXJzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGVsZXRlVGV4dHVyZXMgKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICp0ZXh0dXJlcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbERlcHRoRnVuYyAoR0xlbnVtIGZ1bmMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xEZXB0aE1hc2sgKEdMYm9vbGVhbiBmbGFnKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGVwdGhSYW5nZXggKEdMY2xhbXB4IHpOZWFyLCBHTGNsYW1weCB6RmFyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGlzYWJsZSAoR0xlbnVtIGNhcCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbERpc2FibGVDbGllbnRTdGF0ZSAoR0xlbnVtIGFycmF5KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd0FycmF5cyAoR0xlbnVtIG1vZGUsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd0VsZW1lbnRzIChHTGVudW0gbW9kZSwgR0xzaXplaSBjb3VudCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEVuYWJsZSAoR0xlbnVtIGNhcCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEVuYWJsZUNsaWVudFN0YXRlIChHTGVudW0gYXJyYXkpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGaW5pc2ggKHZvaWQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGbHVzaCAodm9pZCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEZvZ3ggKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEZvZ3h2IChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEZyb250RmFjZSAoR0xlbnVtIG1vZGUpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xGcnVzdHVteCAoR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LCBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsIEdMZml4ZWQgek5lYXIsIEdMZml4ZWQgekZhcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldEJvb2xlYW52IChHTGVudW0gcG5hbWUsIEdMYm9vbGVhbiAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0QnVmZmVyUGFyYW1ldGVyaXYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldENsaXBQbGFuZXggKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBlcW5bNF0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZW5CdWZmZXJzIChHTHNpemVpIG4sIEdMdWludCAqYnVmZmVycyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdlblRleHR1cmVzIChHTHNpemVpIG4sIEdMdWludCAqdGV4dHVyZXMpOworR0xfQVBJIEdMZW51bSBHTF9BUElFTlRSWSBnbEdldEVycm9yICh2b2lkKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0Rml4ZWR2IChHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldEludGVnZXJ2IChHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRMaWdodHh2IChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0TWF0ZXJpYWx4diAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0UG9pbnRlcnYgKEdMZW51bSBwbmFtZSwgdm9pZCAqKnBhcmFtcyk7CitHTF9BUEkgY29uc3QgR0x1Ynl0ZSAqIEdMX0FQSUVOVFJZIGdsR2V0U3RyaW5nIChHTGVudW0gbmFtZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldFRleEVudml2IChHTGVudW0gZW52LCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhFbnZ4diAoR0xlbnVtIGVudiwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhQYXJhbWV0ZXJpdiAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGludCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0VGV4UGFyYW1ldGVyeHYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsSGludCAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIG1vZGUpOworR0xfQVBJIEdMYm9vbGVhbiBHTF9BUElFTlRSWSBnbElzQnVmZmVyIChHTHVpbnQgYnVmZmVyKTsKK0dMX0FQSSBHTGJvb2xlYW4gR0xfQVBJRU5UUlkgZ2xJc0VuYWJsZWQgKEdMZW51bSBjYXApOworR0xfQVBJIEdMYm9vbGVhbiBHTF9BUElFTlRSWSBnbElzVGV4dHVyZSAoR0x1aW50IHRleHR1cmUpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaWdodE1vZGVseCAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTGlnaHRNb2RlbHh2IChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExpZ2h0eCAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaWdodHh2IChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTGluZVdpZHRoeCAoR0xmaXhlZCB3aWR0aCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExvYWRJZGVudGl0eSAodm9pZCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExvYWRNYXRyaXh4IChjb25zdCBHTGZpeGVkICptKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTG9naWNPcCAoR0xlbnVtIG9wY29kZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE1hdGVyaWFseCAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE1hdGVyaWFseHYgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE1hdHJpeE1vZGUgKEdMZW51bSBtb2RlKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTXVsdE1hdHJpeHggKGNvbnN0IEdMZml4ZWQgKm0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xNdWx0aVRleENvb3JkNHggKEdMZW51bSB0YXJnZXQsIEdMZml4ZWQgcywgR0xmaXhlZCB0LCBHTGZpeGVkIHIsIEdMZml4ZWQgcSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE5vcm1hbDN4IChHTGZpeGVkIG54LCBHTGZpeGVkIG55LCBHTGZpeGVkIG56KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTm9ybWFsUG9pbnRlciAoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xPcnRob3ggKEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwgR0xmaXhlZCBib3R0b20sIEdMZml4ZWQgdG9wLCBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQaXhlbFN0b3JlaSAoR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFBvaW50UGFyYW1ldGVyeCAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUG9pbnRQYXJhbWV0ZXJ4diAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQb2ludFNpemV4IChHTGZpeGVkIHNpemUpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQb2x5Z29uT2Zmc2V0eCAoR0xmaXhlZCBmYWN0b3IsIEdMZml4ZWQgdW5pdHMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQb3BNYXRyaXggKHZvaWQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQdXNoTWF0cml4ICh2b2lkKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUmVhZFBpeGVscyAoR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBHTHZvaWQgKnBpeGVscyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFJvdGF0ZXggKEdMZml4ZWQgYW5nbGUsIEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xTYW1wbGVDb3ZlcmFnZSAoR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xTYW1wbGVDb3ZlcmFnZXggKEdMY2xhbXB4IHZhbHVlLCBHTGJvb2xlYW4gaW52ZXJ0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsU2NhbGV4IChHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsU2Npc3NvciAoR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xTaGFkZU1vZGVsIChHTGVudW0gbW9kZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFN0ZW5jaWxGdW5jIChHTGVudW0gZnVuYywgR0xpbnQgcmVmLCBHTHVpbnQgbWFzayk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFN0ZW5jaWxNYXNrIChHTHVpbnQgbWFzayk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFN0ZW5jaWxPcCAoR0xlbnVtIGZhaWwsIEdMZW51bSB6ZmFpbCwgR0xlbnVtIHpwYXNzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4Q29vcmRQb2ludGVyIChHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleEVudmkgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhFbnZ4IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhFbnZpdiAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4RW52eHYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4SW1hZ2UyRCAoR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyLCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpwaXhlbHMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhQYXJhbWV0ZXJpIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4UGFyYW1ldGVyeCAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4UGFyYW1ldGVyaXYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xpbnQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleFBhcmFtZXRlcnh2IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleFN1YkltYWdlMkQgKEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqcGl4ZWxzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVHJhbnNsYXRleCAoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFZlcnRleFBvaW50ZXIgKEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVmlld3BvcnQgKEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0KTsKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qCisgKiBSZXF1aXJlZCBPRVMgZXh0ZW5zaW9uIGZ1bmN0aW9ucworICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisvKiBHTF9PRVNfcmVhZF9mb3JtYXQgKi8KKyNpZm5kZWYgR0xfT0VTX3JlYWRfZm9ybWF0CisjZGVmaW5lIEdMX09FU19yZWFkX2Zvcm1hdCAxCisjZW5kaWYKKworLyogR0xfT0VTX2NvbXByZXNzZWRfcGFsZXR0ZWRfdGV4dHVyZSAqLworI2lmbmRlZiBHTF9PRVNfY29tcHJlc3NlZF9wYWxldHRlZF90ZXh0dXJlCisjZGVmaW5lIEdMX09FU19jb21wcmVzc2VkX3BhbGV0dGVkX3RleHR1cmUgMQorI2VuZGlmCisKKy8qIEdMX09FU19wb2ludF9zaXplX2FycmF5ICovCisjaWZuZGVmIEdMX09FU19wb2ludF9zaXplX2FycmF5CisjZGVmaW5lIEdMX09FU19wb2ludF9zaXplX2FycmF5IDEKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUG9pbnRTaXplUG9pbnRlck9FUyAoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworI2VuZGlmCisKKy8qIEdMX09FU19wb2ludF9zcHJpdGUgKi8KKyNpZm5kZWYgR0xfT0VTX3BvaW50X3Nwcml0ZQorI2RlZmluZSBHTF9PRVNfcG9pbnRfc3ByaXRlIDEKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19nbF9oXyAqLworCmRpZmYgLS1naXQgYS9vcGVuZ2wvaW5jbHVkZS9HTEVTL2dsZXh0LmggYi9vcGVuZ2wvaW5jbHVkZS9HTEVTL2dsZXh0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGMwMTg3MQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9pbmNsdWRlL0dMRVMvZ2xleHQuaApAQCAtMCwwICsxLDYyMiBAQAorI2lmbmRlZiBfX2dsZXh0X2hfCisjZGVmaW5lIF9fZ2xleHRfaF8KKworLyogJFJldmlzaW9uOiA3MTcyICQgb24gJERhdGU6OiAyMDA5LTAxLTA5IDExOjE3OjQxIC0wODAwICMkICovCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoKKyAqIFRoaXMgZG9jdW1lbnQgaXMgbGljZW5zZWQgdW5kZXIgdGhlIFNHSSBGcmVlIFNvZnR3YXJlIEIgTGljZW5zZSBWZXJzaW9uCisgKiAyLjAuIEZvciBkZXRhaWxzLCBzZWUgaHR0cDovL29zcy5zZ2kuY29tL3Byb2plY3RzL0ZyZWVCLyAuCisgKi8KKworI2lmbmRlZiBHTF9BUElFTlRSWVAKKyMgICBkZWZpbmUgR0xfQVBJRU5UUllQIEdMX0FQSUVOVFJZKgorI2VuZGlmCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKgorICogT0VTIGV4dGVuc2lvbiB0b2tlbnMKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworLyogR0xfT0VTX2JsZW5kX2VxdWF0aW9uX3NlcGFyYXRlICovCisjaWZuZGVmIEdMX09FU19ibGVuZF9lcXVhdGlvbl9zZXBhcmF0ZQorLyogQkxFTkRfRVFVQVRJT05fUkdCX09FUyBzYW1lIGFzIEJMRU5EX0VRVUFUSU9OX09FUyAqLworI2RlZmluZSBHTF9CTEVORF9FUVVBVElPTl9SR0JfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAwOQorI2RlZmluZSBHTF9CTEVORF9FUVVBVElPTl9BTFBIQV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODgzRAorI2VuZGlmCisKKy8qIEdMX09FU19ibGVuZF9mdW5jX3NlcGFyYXRlICovCisjaWZuZGVmIEdMX09FU19ibGVuZF9mdW5jX3NlcGFyYXRlCisjZGVmaW5lIEdMX0JMRU5EX0RTVF9SR0JfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MEM4CisjZGVmaW5lIEdMX0JMRU5EX1NSQ19SR0JfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MEM5CisjZGVmaW5lIEdMX0JMRU5EX0RTVF9BTFBIQV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MENBCisjZGVmaW5lIEdMX0JMRU5EX1NSQ19BTFBIQV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MENCCisjZW5kaWYKKworLyogR0xfT0VTX2JsZW5kX3N1YnRyYWN0ICovCisjaWZuZGVmIEdMX09FU19ibGVuZF9zdWJ0cmFjdAorI2RlZmluZSBHTF9CTEVORF9FUVVBVElPTl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAwOQorI2RlZmluZSBHTF9GVU5DX0FERF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAwNgorI2RlZmluZSBHTF9GVU5DX1NVQlRSQUNUX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAwQQorI2RlZmluZSBHTF9GVU5DX1JFVkVSU0VfU1VCVFJBQ1RfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAwQgorI2VuZGlmCisKKy8qIEdMX09FU19jb21wcmVzc2VkX0VUQzFfUkdCOF90ZXh0dXJlICovCisjaWZuZGVmIEdMX09FU19jb21wcmVzc2VkX0VUQzFfUkdCOF90ZXh0dXJlCisjZGVmaW5lIEdMX0VUQzFfUkdCOF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDY0CisjZW5kaWYKKworLyogR0xfT0VTX2RlcHRoMjQgKi8KKyNpZm5kZWYgR0xfT0VTX2RlcHRoMjQKKyNkZWZpbmUgR0xfREVQVEhfQ09NUE9ORU5UMjRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDgxQTYKKyNlbmRpZgorCisvKiBHTF9PRVNfZGVwdGgzMiAqLworI2lmbmRlZiBHTF9PRVNfZGVwdGgzMgorI2RlZmluZSBHTF9ERVBUSF9DT01QT05FTlQzMl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODFBNworI2VuZGlmCisKKy8qIEdMX09FU19kcmF3X3RleHR1cmUgKi8KKyNpZm5kZWYgR0xfT0VTX2RyYXdfdGV4dHVyZQorI2RlZmluZSBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEI5RAorI2VuZGlmCisKKy8qIEdMX09FU19FR0xfaW1hZ2UgKi8KKyNpZm5kZWYgR0xfT0VTX0VHTF9pbWFnZQordHlwZWRlZiB2b2lkKiBHTGVnbEltYWdlT0VTOworI2VuZGlmCisKKy8qIEdMX09FU19maXhlZF9wb2ludCAqLworI2lmbmRlZiBHTF9PRVNfZml4ZWRfcG9pbnQKKyNkZWZpbmUgR0xfRklYRURfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE0MEMKKyNlbmRpZgorCisvKiBHTF9PRVNfZnJhbWVidWZmZXJfb2JqZWN0ICovCisjaWZuZGVmIEdMX09FU19mcmFtZWJ1ZmZlcl9vYmplY3QKKyNkZWZpbmUgR0xfTk9ORV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDQwCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDQxCisjZGVmaW5lIEdMX1JHQkE0X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDU2CisjZGVmaW5lIEdMX1JHQjVfQTFfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDU3CisjZGVmaW5lIEdMX1JHQjU2NV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDYyCisjZGVmaW5lIEdMX0RFUFRIX0NPTVBPTkVOVDE2X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MUE1CisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9XSURUSF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDQyCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9IRUlHSFRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDQzCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9JTlRFUk5BTF9GT1JNQVRfT0VTICAgICAgICAgICAgICAgICAgICAgMHg4RDQ0CisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9SRURfU0laRV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDUwCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9HUkVFTl9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDUxCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9CTFVFX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDUyCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9BTFBIQV9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDUzCisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9ERVBUSF9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDU0CisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9TVEVOQ0lMX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDU1CisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfT0JKRUNUX1RZUEVfT0VTICAgICAgICAgICAgICAgMHg4Q0QwCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfT0JKRUNUX05BTUVfT0VTICAgICAgICAgICAgICAgMHg4Q0QxCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfVEVYVFVSRV9MRVZFTF9PRVMgICAgICAgICAgICAgMHg4Q0QyCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfVEVYVFVSRV9DVUJFX01BUF9GQUNFX09FUyAgICAgMHg4Q0QzCisjZGVmaW5lIEdMX0NPTE9SX0FUVEFDSE1FTlQwX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4Q0UwCisjZGVmaW5lIEdMX0RFUFRIX0FUVEFDSE1FTlRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDAwCisjZGVmaW5lIEdMX1NURU5DSUxfQVRUQUNITUVOVF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDIwCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0NPTVBMRVRFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4Q0Q1CisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfQVRUQUNITUVOVF9PRVMgICAgICAgICAgICAgICAgMHg4Q0Q2CisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfTUlTU0lOR19BVFRBQ0hNRU5UX09FUyAgICAgICAgMHg4Q0Q3CisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfRElNRU5TSU9OU19PRVMgICAgICAgICAgICAgICAgMHg4Q0Q5CisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfRk9STUFUU19PRVMgICAgICAgICAgICAgICAgICAgMHg4Q0RBCisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4Q0RECisjZGVmaW5lIEdMX0ZSQU1FQlVGRkVSX0JJTkRJTkdfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4Q0E2CisjZGVmaW5lIEdMX1JFTkRFUkJVRkZFUl9CSU5ESU5HX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4Q0E3CisjZGVmaW5lIEdMX01BWF9SRU5ERVJCVUZGRVJfU0laRV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NEU4CisjZGVmaW5lIEdMX0lOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OX09FUyAgICAgICAgICAgICAgICAgICAgMHgwNTA2CisjZW5kaWYKKworLyogR0xfT0VTX21hcGJ1ZmZlciAqLworI2lmbmRlZiBHTF9PRVNfbWFwYnVmZmVyCisjZGVmaW5lIEdMX1dSSVRFX09OTFlfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OEI5CisjZGVmaW5lIEdMX0JVRkZFUl9BQ0NFU1NfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OEJCCisjZGVmaW5lIEdMX0JVRkZFUl9NQVBQRURfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OEJDCisjZGVmaW5lIEdMX0JVRkZFUl9NQVBfUE9JTlRFUl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4OEJECisjZW5kaWYKKworLyogR0xfT0VTX21hdHJpeF9nZXQgKi8KKyNpZm5kZWYgR0xfT0VTX21hdHJpeF9nZXQKKyNkZWZpbmUgR0xfTU9ERUxWSUVXX01BVFJJWF9GTE9BVF9BU19JTlRfQklUU19PRVMgICAgICAgICAgICAgICAweDg5OEQKKyNkZWZpbmUgR0xfUFJPSkVDVElPTl9NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTICAgICAgICAgICAgICAweDg5OEUKKyNkZWZpbmUgR0xfVEVYVFVSRV9NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTICAgICAgICAgICAgICAgICAweDg5OEYKKyNlbmRpZgorCisvKiBHTF9PRVNfbWF0cml4X3BhbGV0dGUgKi8KKyNpZm5kZWYgR0xfT0VTX21hdHJpeF9wYWxldHRlCisjZGVmaW5lIEdMX01BWF9WRVJURVhfVU5JVFNfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkE0CisjZGVmaW5lIEdMX01BWF9QQUxFVFRFX01BVFJJQ0VTX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQyCisjZGVmaW5lIEdMX01BVFJJWF9QQUxFVFRFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQwCisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQ0CisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkFECisjZGVmaW5lIEdMX0NVUlJFTlRfUEFMRVRURV9NQVRSSVhfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQzCisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQ2CisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9UWVBFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQ3CisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9TVFJJREVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQ4CisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9QT0lOVEVSX09FUyAgICAgICAgICAgICAgICAgICAgICAgMHg4ODQ5CisjZGVmaW5lIEdMX01BVFJJWF9JTkRFWF9BUlJBWV9CVUZGRVJfQklORElOR19PRVMgICAgICAgICAgICAgICAgMHg4QjlFCisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkFCCisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9UWVBFX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkE5CisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9TVFJJREVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkFBCisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9QT0lOVEVSX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NkFDCisjZGVmaW5lIEdMX1dFSUdIVF9BUlJBWV9CVUZGRVJfQklORElOR19PRVMgICAgICAgICAgICAgICAgICAgICAgMHg4ODlFCisjZW5kaWYKKworLyogR0xfT0VTX3BhY2tlZF9kZXB0aF9zdGVuY2lsICovCisjaWZuZGVmIEdMX09FU19wYWNrZWRfZGVwdGhfc3RlbmNpbAorI2RlZmluZSBHTF9ERVBUSF9TVEVOQ0lMX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODRGOQorI2RlZmluZSBHTF9VTlNJR05FRF9JTlRfMjRfOF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODRGQQorI2RlZmluZSBHTF9ERVBUSDI0X1NURU5DSUw4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODhGMAorI2VuZGlmCisKKy8qIEdMX09FU19yZ2I4X3JnYmE4ICovCisjaWZuZGVmIEdMX09FU19yZ2I4X3JnYmE4CisjZGVmaW5lIEdMX1JHQjhfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDUxCisjZGVmaW5lIEdMX1JHQkE4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDU4CisjZW5kaWYKKworLyogR0xfT0VTX3N0ZW5jaWwxICovCisjaWZuZGVmIEdMX09FU19zdGVuY2lsMQorI2RlZmluZSBHTF9TVEVOQ0lMX0lOREVYMV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OEQ0NgorI2VuZGlmCisKKy8qIEdMX09FU19zdGVuY2lsNCAqLworI2lmbmRlZiBHTF9PRVNfc3RlbmNpbDQKKyNkZWZpbmUgR0xfU1RFTkNJTF9JTkRFWDRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDhENDcKKyNlbmRpZgorCisvKiBHTF9PRVNfc3RlbmNpbDggKi8KKyNpZm5kZWYgR0xfT0VTX3N0ZW5jaWw4CisjZGVmaW5lIEdMX1NURU5DSUxfSU5ERVg4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4RDQ4CisjZW5kaWYKKworLyogR0xfT0VTX3N0ZW5jaWxfd3JhcCAqLworI2lmbmRlZiBHTF9PRVNfc3RlbmNpbF93cmFwCisjZGVmaW5lIEdMX0lOQ1JfV1JBUF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NTA3CisjZGVmaW5lIEdMX0RFQ1JfV1JBUF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NTA4CisjZW5kaWYKKworLyogR0xfT0VTX3RleHR1cmVfY3ViZV9tYXAgKi8KKyNpZm5kZWYgR0xfT0VTX3RleHR1cmVfY3ViZV9tYXAKKyNkZWZpbmUgR0xfTk9STUFMX01BUF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDg1MTEKKyNkZWZpbmUgR0xfUkVGTEVDVElPTl9NQVBfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDg1MTIKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDg1MTMKKyNkZWZpbmUgR0xfVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAweDg1MTQKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MTUKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9YX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MTYKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9ZX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MTcKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9ZX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MTgKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9aX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MTkKKyNkZWZpbmUgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9aX09FUyAgICAgICAgICAgICAgICAgICAgICAweDg1MUEKKyNkZWZpbmUgR0xfTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAweDg1MUMKKyNkZWZpbmUgR0xfVEVYVFVSRV9HRU5fTU9ERV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDI1MDAKKyNkZWZpbmUgR0xfVEVYVFVSRV9HRU5fU1RSX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDhENjAKKyNlbmRpZgorCisvKiBHTF9PRVNfdGV4dHVyZV9taXJyb3JlZF9yZXBlYXQgKi8KKyNpZm5kZWYgR0xfT0VTX3RleHR1cmVfbWlycm9yZWRfcmVwZWF0CisjZGVmaW5lIEdMX01JUlJPUkVEX1JFUEVBVF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MzcwCisjZW5kaWYKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qCisgKiBBTUQgZXh0ZW5zaW9uIHRva2VucworICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisvKiBHTF9BTURfY29tcHJlc3NlZF8zRENfdGV4dHVyZSAqLworI2lmbmRlZiBHTF9BTURfY29tcHJlc3NlZF8zRENfdGV4dHVyZQorI2RlZmluZSBHTF8zRENfWF9BTUQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODdGOQorI2RlZmluZSBHTF8zRENfWFlfQU1EICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODdGQQorI2VuZGlmCisKKy8qIEdMX0FNRF9jb21wcmVzc2VkX0FUQ190ZXh0dXJlICovCisjaWZuZGVmIEdMX0FNRF9jb21wcmVzc2VkX0FUQ190ZXh0dXJlCisjZGVmaW5lIEdMX0FUQ19SR0JfQU1EICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4QzkyCisjZGVmaW5lIEdMX0FUQ19SR0JBX0VYUExJQ0lUX0FMUEhBX0FNRCAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4QzkzCisjZGVmaW5lIEdMX0FUQ19SR0JBX0lOVEVSUE9MQVRFRF9BTFBIQV9BTUQgICAgICAgICAgICAgICAgICAgICAgMHg4N0VFCisjZW5kaWYKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qCisgKiBFWFQgZXh0ZW5zaW9uIHRva2VucworICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisvKiBHTF9FWFRfdGV4dHVyZV9maWx0ZXJfYW5pc290cm9waWMgKi8KKyNpZm5kZWYgR0xfRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljCisjZGVmaW5lIEdMX1RFWFRVUkVfTUFYX0FOSVNPVFJPUFlfRVhUICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NEZFCisjZGVmaW5lIEdMX01BWF9URVhUVVJFX01BWF9BTklTT1RST1BZX0VYVCAgICAgICAgICAgICAgICAgICAgICAgMHg4NEZGCisjZW5kaWYKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qCisgKiBPRVMgZXh0ZW5zaW9uIGZ1bmN0aW9ucworICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisvKiBHTF9PRVNfYmxlbmRfZXF1YXRpb25fc2VwYXJhdGUgKi8KKyNpZm5kZWYgR0xfT0VTX2JsZW5kX2VxdWF0aW9uX3NlcGFyYXRlCisjZGVmaW5lIEdMX09FU19ibGVuZF9lcXVhdGlvbl9zZXBhcmF0ZSAxCisjaWZkZWYgR0xfR0xFWFRfUFJPVE9UWVBFUworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xCbGVuZEVxdWF0aW9uU2VwYXJhdGVPRVMgKEdMZW51bSBtb2RlUkdCLCBHTGVudW0gbW9kZUFscGhhKTsKKyNlbmRpZgordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xCTEVOREVRVUFUSU9OU0VQQVJBVEVPRVNQUk9DKSAoR0xlbnVtIG1vZGVSR0IsIEdMZW51bSBtb2RlQWxwaGEpOworI2VuZGlmCisKKy8qIEdMX09FU19ibGVuZF9mdW5jX3NlcGFyYXRlICovCisjaWZuZGVmIEdMX09FU19ibGVuZF9mdW5jX3NlcGFyYXRlCisjZGVmaW5lIEdMX09FU19ibGVuZF9mdW5jX3NlcGFyYXRlIDEKKyNpZmRlZiBHTF9HTEVYVF9QUk9UT1RZUEVTCitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJsZW5kRnVuY1NlcGFyYXRlT0VTIChHTGVudW0gc3JjUkdCLCBHTGVudW0gZHN0UkdCLCBHTGVudW0gc3JjQWxwaGEsIEdMZW51bSBkc3RBbHBoYSk7CisjZW5kaWYKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMQkxFTkRGVU5DU0VQQVJBVEVPRVNQUk9DKSAoR0xlbnVtIHNyY1JHQiwgR0xlbnVtIGRzdFJHQiwgR0xlbnVtIHNyY0FscGhhLCBHTGVudW0gZHN0QWxwaGEpOworI2VuZGlmCisKKy8qIEdMX09FU19ibGVuZF9zdWJ0cmFjdCAqLworI2lmbmRlZiBHTF9PRVNfYmxlbmRfc3VidHJhY3QKKyNkZWZpbmUgR0xfT0VTX2JsZW5kX3N1YnRyYWN0IDEKKyNpZmRlZiBHTF9HTEVYVF9QUk9UT1RZUEVTCitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJsZW5kRXF1YXRpb25PRVMgKEdMZW51bSBtb2RlKTsKKyNlbmRpZgordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xCTEVOREVRVUFUSU9OT0VTUFJPQykgKEdMZW51bSBtb2RlKTsKKyNlbmRpZgorCisvKiBHTF9PRVNfYnl0ZV9jb29yZGluYXRlcyAqLworI2lmbmRlZiBHTF9PRVNfYnl0ZV9jb29yZGluYXRlcworI2RlZmluZSBHTF9PRVNfYnl0ZV9jb29yZGluYXRlcyAxCisjZW5kaWYKKworLyogR0xfT0VTX2NvbXByZXNzZWRfRVRDMV9SR0I4X3RleHR1cmUgKi8KKyNpZm5kZWYgR0xfT0VTX2NvbXByZXNzZWRfRVRDMV9SR0I4X3RleHR1cmUKKyNkZWZpbmUgR0xfT0VTX2NvbXByZXNzZWRfRVRDMV9SR0I4X3RleHR1cmUgMQorI2VuZGlmCisKKy8qIEdMX09FU19kZXB0aDI0ICovCisjaWZuZGVmIEdMX09FU19kZXB0aDI0CisjZGVmaW5lIEdMX09FU19kZXB0aDI0IDEKKyNlbmRpZgorCisvKiBHTF9PRVNfZGVwdGgzMiAqLworI2lmbmRlZiBHTF9PRVNfZGVwdGgzMgorI2RlZmluZSBHTF9PRVNfZGVwdGgzMiAxCisjZW5kaWYKKworLyogR0xfT0VTX2RyYXdfdGV4dHVyZSAqLworI2lmbmRlZiBHTF9PRVNfZHJhd190ZXh0dXJlCisjZGVmaW5lIEdMX09FU19kcmF3X3RleHR1cmUgMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd1RleHNPRVMgKEdMc2hvcnQgeCwgR0xzaG9ydCB5LCBHTHNob3J0IHosIEdMc2hvcnQgd2lkdGgsIEdMc2hvcnQgaGVpZ2h0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd1RleGlPRVMgKEdMaW50IHgsIEdMaW50IHksIEdMaW50IHosIEdMaW50IHdpZHRoLCBHTGludCBoZWlnaHQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xEcmF3VGV4eE9FUyAoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeiwgR0xmaXhlZCB3aWR0aCwgR0xmaXhlZCBoZWlnaHQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xEcmF3VGV4c3ZPRVMgKGNvbnN0IEdMc2hvcnQgKmNvb3Jkcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbERyYXdUZXhpdk9FUyAoY29uc3QgR0xpbnQgKmNvb3Jkcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbERyYXdUZXh4dk9FUyAoY29uc3QgR0xmaXhlZCAqY29vcmRzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd1RleGZPRVMgKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHosIEdMZmxvYXQgd2lkdGgsIEdMZmxvYXQgaGVpZ2h0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRHJhd1RleGZ2T0VTIChjb25zdCBHTGZsb2F0ICpjb29yZHMpOworI2VuZGlmCit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTERSQVdURVhTT0VTUFJPQykgKEdMc2hvcnQgeCwgR0xzaG9ydCB5LCBHTHNob3J0IHosIEdMc2hvcnQgd2lkdGgsIEdMc2hvcnQgaGVpZ2h0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRFJBV1RFWElPRVNQUk9DKSAoR0xpbnQgeCwgR0xpbnQgeSwgR0xpbnQgeiwgR0xpbnQgd2lkdGgsIEdMaW50IGhlaWdodCk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTERSQVdURVhYT0VTUFJPQykgKEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHosIEdMZml4ZWQgd2lkdGgsIEdMZml4ZWQgaGVpZ2h0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRFJBV1RFWFNWT0VTUFJPQykgKGNvbnN0IEdMc2hvcnQgKmNvb3Jkcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTERSQVdURVhJVk9FU1BST0MpIChjb25zdCBHTGludCAqY29vcmRzKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRFJBV1RFWFhWT0VTUFJPQykgKGNvbnN0IEdMZml4ZWQgKmNvb3Jkcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTERSQVdURVhGT0VTUFJPQykgKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHosIEdMZmxvYXQgd2lkdGgsIEdMZmxvYXQgaGVpZ2h0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRFJBV1RFWEZWT0VTUFJPQykgKGNvbnN0IEdMZmxvYXQgKmNvb3Jkcyk7CisjZW5kaWYKKworLyogR0xfT0VTX0VHTF9pbWFnZSAqLworI2lmbmRlZiBHTF9PRVNfRUdMX2ltYWdlCisjZGVmaW5lIEdMX09FU19FR0xfaW1hZ2UgMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRUdMSW1hZ2VUYXJnZXRUZXh0dXJlMkRPRVMgKEdMZW51bSB0YXJnZXQsIEdMZWdsSW1hZ2VPRVMgaW1hZ2UpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xFR0xJbWFnZVRhcmdldFJlbmRlcmJ1ZmZlclN0b3JhZ2VPRVMgKEdMZW51bSB0YXJnZXQsIEdMZWdsSW1hZ2VPRVMgaW1hZ2UpOworI2VuZGlmCit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTEVHTElNQUdFVEFSR0VUVEVYVFVSRTJET0VTUFJPQykgKEdMZW51bSB0YXJnZXQsIEdMZWdsSW1hZ2VPRVMgaW1hZ2UpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xFR0xJTUFHRVRBUkdFVFJFTkRFUkJVRkZFUlNUT1JBR0VPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlZ2xJbWFnZU9FUyBpbWFnZSk7CisjZW5kaWYKKworLyogR0xfT0VTX2VsZW1lbnRfaW5kZXhfdWludCAqLworI2lmbmRlZiBHTF9PRVNfZWxlbWVudF9pbmRleF91aW50CisjZGVmaW5lIEdMX09FU19lbGVtZW50X2luZGV4X3VpbnQgMQorI2VuZGlmCisKKy8qIEdMX09FU19leHRlbmRlZF9tYXRyaXhfcGFsZXR0ZSAqLworI2lmbmRlZiBHTF9PRVNfZXh0ZW5kZWRfbWF0cml4X3BhbGV0dGUKKyNkZWZpbmUgR0xfT0VTX2V4dGVuZGVkX21hdHJpeF9wYWxldHRlIDEKKyNlbmRpZgorCisvKiBHTF9PRVNfZmJvX3JlbmRlcl9taXBtYXAgKi8KKyNpZm5kZWYgR0xfT0VTX2Zib19yZW5kZXJfbWlwbWFwCisjZGVmaW5lIEdMX09FU19mYm9fcmVuZGVyX21pcG1hcCAxCisjZW5kaWYKKworLyogR0xfT0VTX2ZpeGVkX3BvaW50ICovCisjaWZuZGVmIEdMX09FU19maXhlZF9wb2ludAorI2RlZmluZSBHTF9PRVNfZml4ZWRfcG9pbnQgMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQWxwaGFGdW5jeE9FUyAoR0xlbnVtIGZ1bmMsIEdMY2xhbXB4IHJlZik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyQ29sb3J4T0VTIChHTGNsYW1weCByZWQsIEdMY2xhbXB4IGdyZWVuLCBHTGNsYW1weCBibHVlLCBHTGNsYW1weCBhbHBoYSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyRGVwdGh4T0VTIChHTGNsYW1weCBkZXB0aCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsaXBQbGFuZXhPRVMgKEdMZW51bSBwbGFuZSwgY29uc3QgR0xmaXhlZCAqZXF1YXRpb24pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xDb2xvcjR4T0VTIChHTGZpeGVkIHJlZCwgR0xmaXhlZCBncmVlbiwgR0xmaXhlZCBibHVlLCBHTGZpeGVkIGFscGhhKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGVwdGhSYW5nZXhPRVMgKEdMY2xhbXB4IHpOZWFyLCBHTGNsYW1weCB6RmFyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRm9neE9FUyAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRm9neHZPRVMgKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRnJ1c3R1bXhPRVMgKEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwgR0xmaXhlZCBib3R0b20sIEdMZml4ZWQgdG9wLCBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRDbGlwUGxhbmV4T0VTIChHTGVudW0gcG5hbWUsIEdMZml4ZWQgZXFuWzRdKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0Rml4ZWR2T0VTIChHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldExpZ2h0eHZPRVMgKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRNYXRlcmlhbHh2T0VTIChHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhFbnZ4dk9FUyAoR0xlbnVtIGVudiwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhQYXJhbWV0ZXJ4dk9FUyAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaWdodE1vZGVseE9FUyAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTGlnaHRNb2RlbHh2T0VTIChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExpZ2h0eE9FUyAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMaWdodHh2T0VTIChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTGluZVdpZHRoeE9FUyAoR0xmaXhlZCB3aWR0aCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbExvYWRNYXRyaXh4T0VTIChjb25zdCBHTGZpeGVkICptKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTWF0ZXJpYWx4T0VTIChHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTWF0ZXJpYWx4dk9FUyAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsTXVsdE1hdHJpeHhPRVMgKGNvbnN0IEdMZml4ZWQgKm0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xNdWx0aVRleENvb3JkNHhPRVMgKEdMZW51bSB0YXJnZXQsIEdMZml4ZWQgcywgR0xmaXhlZCB0LCBHTGZpeGVkIHIsIEdMZml4ZWQgcSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbE5vcm1hbDN4T0VTIChHTGZpeGVkIG54LCBHTGZpeGVkIG55LCBHTGZpeGVkIG56KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsT3J0aG94T0VTIChHTGZpeGVkIGxlZnQsIEdMZml4ZWQgcmlnaHQsIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUG9pbnRQYXJhbWV0ZXJ4T0VTIChHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xQb2ludFBhcmFtZXRlcnh2T0VTIChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFBvaW50U2l6ZXhPRVMgKEdMZml4ZWQgc2l6ZSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFBvbHlnb25PZmZzZXR4T0VTIChHTGZpeGVkIGZhY3RvciwgR0xmaXhlZCB1bml0cyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFJvdGF0ZXhPRVMgKEdMZml4ZWQgYW5nbGUsIEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xTYW1wbGVDb3ZlcmFnZXhPRVMgKEdMY2xhbXB4IHZhbHVlLCBHTGJvb2xlYW4gaW52ZXJ0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsU2NhbGV4T0VTIChHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4RW52eE9FUyAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4RW52eHZPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4UGFyYW1ldGVyeE9FUyAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4UGFyYW1ldGVyeHZPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVHJhbnNsYXRleE9FUyAoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeik7CisjZW5kaWYKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMQUxQSEFGVU5DWE9FU1BST0MpIChHTGVudW0gZnVuYywgR0xjbGFtcHggcmVmKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMQ0xFQVJDT0xPUlhPRVNQUk9DKSAoR0xjbGFtcHggcmVkLCBHTGNsYW1weCBncmVlbiwgR0xjbGFtcHggYmx1ZSwgR0xjbGFtcHggYWxwaGEpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xDTEVBUkRFUFRIWE9FU1BST0MpIChHTGNsYW1weCBkZXB0aCk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTENMSVBQTEFORVhPRVNQUk9DKSAoR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZpeGVkICplcXVhdGlvbik7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTENPTE9SNFhPRVNQUk9DKSAoR0xmaXhlZCByZWQsIEdMZml4ZWQgZ3JlZW4sIEdMZml4ZWQgYmx1ZSwgR0xmaXhlZCBhbHBoYSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTERFUFRIUkFOR0VYT0VTUFJPQykgKEdMY2xhbXB4IHpOZWFyLCBHTGNsYW1weCB6RmFyKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRk9HWE9FU1BST0MpIChHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xGT0dYVk9FU1BST0MpIChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTEZSVVNUVU1YT0VTUFJPQykgKEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwgR0xmaXhlZCBib3R0b20sIEdMZml4ZWQgdG9wLCBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRDTElQUExBTkVYT0VTUFJPQykgKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBlcW5bNF0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRGSVhFRFZPRVNQUk9DKSAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRMSUdIVFhWT0VTUFJPQykgKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRNQVRFUklBTFhWT0VTUFJPQykgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTEdFVFRFWEVOVlhWT0VTUFJPQykgKEdMZW51bSBlbnYsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMR0VUVEVYUEFSQU1FVEVSWFZPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMSUdIVE1PREVMWE9FU1BST0MpIChHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMSUdIVE1PREVMWFZPRVNQUk9DKSAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMSUdIVFhPRVNQUk9DKSAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMSUdIVFhWT0VTUFJPQykgKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMSU5FV0lEVEhYT0VTUFJPQykgKEdMZml4ZWQgd2lkdGgpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMT0FETUFUUklYWE9FU1BST0MpIChjb25zdCBHTGZpeGVkICptKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMTUFURVJJQUxYT0VTUFJPQykgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xNQVRFUklBTFhWT0VTUFJPQykgKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTE1VTFRNQVRSSVhYT0VTUFJPQykgKGNvbnN0IEdMZml4ZWQgKm0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xNVUxUSVRFWENPT1JENFhPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xmaXhlZCBzLCBHTGZpeGVkIHQsIEdMZml4ZWQgciwgR0xmaXhlZCBxKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMTk9STUFMM1hPRVNQUk9DKSAoR0xmaXhlZCBueCwgR0xmaXhlZCBueSwgR0xmaXhlZCBueik7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTE9SVEhPWE9FU1BST0MpIChHTGZpeGVkIGxlZnQsIEdMZml4ZWQgcmlnaHQsIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMUE9JTlRQQVJBTUVURVJYT0VTUFJPQykgKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFBPSU5UUEFSQU1FVEVSWFZPRVNQUk9DKSAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xQT0lOVFNJWkVYT0VTUFJPQykgKEdMZml4ZWQgc2l6ZSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFBPTFlHT05PRkZTRVRYT0VTUFJPQykgKEdMZml4ZWQgZmFjdG9yLCBHTGZpeGVkIHVuaXRzKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMUk9UQVRFWE9FU1BST0MpIChHTGZpeGVkIGFuZ2xlLCBHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMU0FNUExFQ09WRVJBR0VYT0VTUFJPQykgKEdMY2xhbXB4IHZhbHVlLCBHTGJvb2xlYW4gaW52ZXJ0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMU0NBTEVYT0VTUFJPQykgKEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xURVhFTlZYT0VTUFJPQykgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFRFWEVOVlhWT0VTUFJPQykgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMVEVYUEFSQU1FVEVSWE9FU1BST0MpIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xURVhQQVJBTUVURVJYVk9FU1BST0MpIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFRSQU5TTEFURVhPRVNQUk9DKSAoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeik7CisjZW5kaWYKKworLyogR0xfT0VTX2ZyYW1lYnVmZmVyX29iamVjdCAqLworI2lmbmRlZiBHTF9PRVNfZnJhbWVidWZmZXJfb2JqZWN0CisjZGVmaW5lIEdMX09FU19mcmFtZWJ1ZmZlcl9vYmplY3QgMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSBHTGJvb2xlYW4gR0xfQVBJRU5UUlkgZ2xJc1JlbmRlcmJ1ZmZlck9FUyAoR0x1aW50IHJlbmRlcmJ1ZmZlcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJpbmRSZW5kZXJidWZmZXJPRVMgKEdMZW51bSB0YXJnZXQsIEdMdWludCByZW5kZXJidWZmZXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xEZWxldGVSZW5kZXJidWZmZXJzT0VTIChHTHNpemVpIG4sIGNvbnN0IEdMdWludCogcmVuZGVyYnVmZmVycyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdlblJlbmRlcmJ1ZmZlcnNPRVMgKEdMc2l6ZWkgbiwgR0x1aW50KiByZW5kZXJidWZmZXJzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsUmVuZGVyYnVmZmVyU3RvcmFnZU9FUyAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdldFJlbmRlcmJ1ZmZlclBhcmFtZXRlcml2T0VTIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50KiBwYXJhbXMpOworR0xfQVBJIEdMYm9vbGVhbiBHTF9BUElFTlRSWSBnbElzRnJhbWVidWZmZXJPRVMgKEdMdWludCBmcmFtZWJ1ZmZlcik7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEJpbmRGcmFtZWJ1ZmZlck9FUyAoR0xlbnVtIHRhcmdldCwgR0x1aW50IGZyYW1lYnVmZmVyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGVsZXRlRnJhbWVidWZmZXJzT0VTIChHTHNpemVpIG4sIGNvbnN0IEdMdWludCogZnJhbWVidWZmZXJzKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2VuRnJhbWVidWZmZXJzT0VTIChHTHNpemVpIG4sIEdMdWludCogZnJhbWVidWZmZXJzKTsKK0dMX0FQSSBHTGVudW0gR0xfQVBJRU5UUlkgZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzT0VTIChHTGVudW0gdGFyZ2V0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRnJhbWVidWZmZXJSZW5kZXJidWZmZXJPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBhdHRhY2htZW50LCBHTGVudW0gcmVuZGVyYnVmZmVydGFyZ2V0LCBHTHVpbnQgcmVuZGVyYnVmZmVyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRnJhbWVidWZmZXJUZXh0dXJlMkRPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBhdHRhY2htZW50LCBHTGVudW0gdGV4dGFyZ2V0LCBHTHVpbnQgdGV4dHVyZSwgR0xpbnQgbGV2ZWwpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRGcmFtZWJ1ZmZlckF0dGFjaG1lbnRQYXJhbWV0ZXJpdk9FUyAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIGF0dGFjaG1lbnQsIEdMZW51bSBwbmFtZSwgR0xpbnQqIHBhcmFtcyk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbEdlbmVyYXRlTWlwbWFwT0VTIChHTGVudW0gdGFyZ2V0KTsKKyNlbmRpZgordHlwZWRlZiBHTGJvb2xlYW4gKEdMX0FQSUVOVFJZUCBQRk5HTElTUkVOREVSQlVGRkVST0VTUFJPQykgKEdMdWludCByZW5kZXJidWZmZXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xCSU5EUkVOREVSQlVGRkVST0VTUFJPQykgKEdMZW51bSB0YXJnZXQsIEdMdWludCByZW5kZXJidWZmZXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xERUxFVEVSRU5ERVJCVUZGRVJTT0VTUFJPQykgKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50KiByZW5kZXJidWZmZXJzKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMR0VOUkVOREVSQlVGRkVSU09FU1BST0MpIChHTHNpemVpIG4sIEdMdWludCogcmVuZGVyYnVmZmVycyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFJFTkRFUkJVRkZFUlNUT1JBR0VPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTEdFVFJFTkRFUkJVRkZFUlBBUkFNRVRFUklWT0VTUFJPQykgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQqIHBhcmFtcyk7Cit0eXBlZGVmIEdMYm9vbGVhbiAoR0xfQVBJRU5UUllQIFBGTkdMSVNGUkFNRUJVRkZFUk9FU1BST0MpIChHTHVpbnQgZnJhbWVidWZmZXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xCSU5ERlJBTUVCVUZGRVJPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0x1aW50IGZyYW1lYnVmZmVyKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMREVMRVRFRlJBTUVCVUZGRVJTT0VTUFJPQykgKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50KiBmcmFtZWJ1ZmZlcnMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRU5GUkFNRUJVRkZFUlNPRVNQUk9DKSAoR0xzaXplaSBuLCBHTHVpbnQqIGZyYW1lYnVmZmVycyk7Cit0eXBlZGVmIEdMZW51bSAoR0xfQVBJRU5UUllQIFBGTkdMQ0hFQ0tGUkFNRUJVRkZFUlNUQVRVU09FU1BST0MpIChHTGVudW0gdGFyZ2V0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMRlJBTUVCVUZGRVJSRU5ERVJCVUZGRVJPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIGF0dGFjaG1lbnQsIEdMZW51bSByZW5kZXJidWZmZXJ0YXJnZXQsIEdMdWludCByZW5kZXJidWZmZXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xGUkFNRUJVRkZFUlRFWFRVUkUyRE9FU1BST0MpIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gYXR0YWNobWVudCwgR0xlbnVtIHRleHRhcmdldCwgR0x1aW50IHRleHR1cmUsIEdMaW50IGxldmVsKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMR0VURlJBTUVCVUZGRVJBVFRBQ0hNRU5UUEFSQU1FVEVSSVZPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIGF0dGFjaG1lbnQsIEdMZW51bSBwbmFtZSwgR0xpbnQqIHBhcmFtcyk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTEdFTkVSQVRFTUlQTUFQT0VTUFJPQykgKEdMZW51bSB0YXJnZXQpOworI2VuZGlmCisKKy8qIEdMX09FU19tYXBidWZmZXIgKi8KKyNpZm5kZWYgR0xfT0VTX21hcGJ1ZmZlcgorI2RlZmluZSBHTF9PRVNfbWFwYnVmZmVyIDEKKyNpZmRlZiBHTF9HTEVYVF9QUk9UT1RZUEVTCitHTF9BUEkgdm9pZCogR0xfQVBJRU5UUlkgZ2xNYXBCdWZmZXJPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBhY2Nlc3MpOworR0xfQVBJIEdMYm9vbGVhbiBHTF9BUElFTlRSWSBnbFVubWFwQnVmZmVyT0VTIChHTGVudW0gdGFyZ2V0KTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0QnVmZmVyUG9pbnRlcnZPRVMgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgdm9pZCoqIHBhcmFtcyk7CisjZW5kaWYKK3R5cGVkZWYgdm9pZCogKEdMX0FQSUVOVFJZUCBQRk5HTE1BUEJVRkZFUk9FU1BST0MpIChHTGVudW0gdGFyZ2V0LCBHTGVudW0gYWNjZXNzKTsKK3R5cGVkZWYgR0xib29sZWFuIChHTF9BUElFTlRSWVAgUEZOR0xVTk1BUEJVRkZFUk9FU1BST0MpIChHTGVudW0gdGFyZ2V0KTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMR0VUQlVGRkVSUE9JTlRFUlZPRVNQUk9DKSAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCB2b2lkKiogcGFyYW1zKTsKKyNlbmRpZgorCisvKiBHTF9PRVNfbWF0cml4X2dldCAqLworI2lmbmRlZiBHTF9PRVNfbWF0cml4X2dldAorI2RlZmluZSBHTF9PRVNfbWF0cml4X2dldCAxCisjZW5kaWYKKworLyogR0xfT0VTX21hdHJpeF9wYWxldHRlICovCisjaWZuZGVmIEdMX09FU19tYXRyaXhfcGFsZXR0ZQorI2RlZmluZSBHTF9PRVNfbWF0cml4X3BhbGV0dGUgMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsQ3VycmVudFBhbGV0dGVNYXRyaXhPRVMgKEdMdWludCBtYXRyaXhwYWxldHRlaW5kZXgpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xMb2FkUGFsZXR0ZUZyb21Nb2RlbFZpZXdNYXRyaXhPRVMgKHZvaWQpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xNYXRyaXhJbmRleFBvaW50ZXJPRVMgKEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsV2VpZ2h0UG9pbnRlck9FUyAoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworI2VuZGlmCit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTENVUlJFTlRQQUxFVFRFTUFUUklYT0VTUFJPQykgKEdMdWludCBtYXRyaXhwYWxldHRlaW5kZXgpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xMT0FEUEFMRVRURUZST01NT0RFTFZJRVdNQVRSSVhPRVNQUk9DKSAodm9pZCk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTE1BVFJJWElOREVYUE9JTlRFUk9FU1BST0MpIChHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcik7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFdFSUdIVFBPSU5URVJPRVNQUk9DKSAoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworI2VuZGlmCisKKy8qIEdMX09FU19wYWNrZWRfZGVwdGhfc3RlbmNpbCAqLworI2lmbmRlZiBHTF9PRVNfcGFja2VkX2RlcHRoX3N0ZW5jaWwKKyNkZWZpbmUgR0xfT0VTX3BhY2tlZF9kZXB0aF9zdGVuY2lsIDEKKyNlbmRpZgorCisvKiBHTF9PRVNfcXVlcnlfbWF0cml4ICovCisjaWZuZGVmIEdMX09FU19xdWVyeV9tYXRyaXgKKyNkZWZpbmUgR0xfT0VTX3F1ZXJ5X21hdHJpeCAxCisjaWZkZWYgR0xfR0xFWFRfUFJPVE9UWVBFUworR0xfQVBJIEdMYml0ZmllbGQgR0xfQVBJRU5UUlkgZ2xRdWVyeU1hdHJpeHhPRVMgKEdMZml4ZWQgbWFudGlzc2FbMTZdLCBHTGludCBleHBvbmVudFsxNl0pOworI2VuZGlmCit0eXBlZGVmIEdMYml0ZmllbGQgKEdMX0FQSUVOVFJZUCBQRk5HTFFVRVJZTUFUUklYWE9FU1BST0MpIChHTGZpeGVkIG1hbnRpc3NhWzE2XSwgR0xpbnQgZXhwb25lbnRbMTZdKTsKKyNlbmRpZgorCisvKiBHTF9PRVNfcmdiOF9yZ2JhOCAqLworI2lmbmRlZiBHTF9PRVNfcmdiOF9yZ2JhOAorI2RlZmluZSBHTF9PRVNfcmdiOF9yZ2JhOCAxCisjZW5kaWYKKworLyogR0xfT0VTX3NpbmdsZV9wcmVjaXNpb24gKi8KKyNpZm5kZWYgR0xfT0VTX3NpbmdsZV9wcmVjaXNpb24KKyNkZWZpbmUgR0xfT0VTX3NpbmdsZV9wcmVjaXNpb24gMQorI2lmZGVmIEdMX0dMRVhUX1BST1RPVFlQRVMKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRGVwdGhSYW5nZWZPRVMgKEdMY2xhbXBmIHpOZWFyLCBHTGNsYW1wZiB6RmFyKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsRnJ1c3R1bWZPRVMgKEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLCBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xPcnRob2ZPRVMgKEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLCBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xDbGlwUGxhbmVmT0VTIChHTGVudW0gcGxhbmUsIGNvbnN0IEdMZmxvYXQgKmVxdWF0aW9uKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0Q2xpcFBsYW5lZk9FUyAoR0xlbnVtIHBuYW1lLCBHTGZsb2F0IGVxbls0XSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbENsZWFyRGVwdGhmT0VTIChHTGNsYW1wZiBkZXB0aCk7CisjZW5kaWYKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMREVQVEhSQU5HRUZPRVNQUk9DKSAoR0xjbGFtcGYgek5lYXIsIEdMY2xhbXBmIHpGYXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xGUlVTVFVNRk9FU1BST0MpIChHTGZsb2F0IGxlZnQsIEdMZmxvYXQgcmlnaHQsIEdMZmxvYXQgYm90dG9tLCBHTGZsb2F0IHRvcCwgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMT1JUSE9GT0VTUFJPQykgKEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLCBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xDTElQUExBTkVGT0VTUFJPQykgKEdMZW51bSBwbGFuZSwgY29uc3QgR0xmbG9hdCAqZXF1YXRpb24pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRDTElQUExBTkVGT0VTUFJPQykgKEdMZW51bSBwbmFtZSwgR0xmbG9hdCBlcW5bNF0pOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xDTEVBUkRFUFRIRk9FU1BST0MpIChHTGNsYW1wZiBkZXB0aCk7CisjZW5kaWYKKworLyogR0xfT0VTX3N0ZW5jaWwxICovCisjaWZuZGVmIEdMX09FU19zdGVuY2lsMQorI2RlZmluZSBHTF9PRVNfc3RlbmNpbDEgMQorI2VuZGlmCisKKy8qIEdMX09FU19zdGVuY2lsNCAqLworI2lmbmRlZiBHTF9PRVNfc3RlbmNpbDQKKyNkZWZpbmUgR0xfT0VTX3N0ZW5jaWw0IDEKKyNlbmRpZgorCisvKiBHTF9PRVNfc3RlbmNpbDggKi8KKyNpZm5kZWYgR0xfT0VTX3N0ZW5jaWw4CisjZGVmaW5lIEdMX09FU19zdGVuY2lsOCAxCisjZW5kaWYKKworLyogR0xfT0VTX3N0ZW5jaWxfd3JhcCAqLworI2lmbmRlZiBHTF9PRVNfc3RlbmNpbF93cmFwCisjZGVmaW5lIEdMX09FU19zdGVuY2lsX3dyYXAgMQorI2VuZGlmCisKKy8qIEdMX09FU190ZXh0dXJlX2N1YmVfbWFwICovCisjaWZuZGVmIEdMX09FU190ZXh0dXJlX2N1YmVfbWFwCisjZGVmaW5lIEdMX09FU190ZXh0dXJlX2N1YmVfbWFwIDEKKyNpZmRlZiBHTF9HTEVYVF9QUk9UT1RZUEVTCitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleEdlbmZPRVMgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsVGV4R2VuZnZPRVMgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhHZW5pT0VTIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xpbnQgcGFyYW0pOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhHZW5pdk9FUyAoR0xlbnVtIGNvb3JkLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMaW50ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xUZXhHZW54T0VTIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTF9BUEkgdm9pZCBHTF9BUElFTlRSWSBnbFRleEdlbnh2T0VTIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMX0FQSSB2b2lkIEdMX0FQSUVOVFJZIGdsR2V0VGV4R2VuZnZPRVMgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhHZW5pdk9FUyAoR0xlbnVtIGNvb3JkLCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpOworR0xfQVBJIHZvaWQgR0xfQVBJRU5UUlkgZ2xHZXRUZXhHZW54dk9FUyAoR0xlbnVtIGNvb3JkLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcyk7CisjZW5kaWYKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMVEVYR0VORk9FU1BST0MpIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFRFWEdFTkZWT0VTUFJPQykgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xURVhHRU5JT0VTUFJPQykgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFRFWEdFTklWT0VTUFJPQykgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCAqcGFyYW1zKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMVEVYR0VOWE9FU1BST0MpIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7Cit0eXBlZGVmIHZvaWQgKEdMX0FQSUVOVFJZUCBQRk5HTFRFWEdFTlhWT0VTUFJPQykgKEdMZW51bSBjb29yZCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRURVhHRU5GVk9FU1BST0MpIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKTsKK3R5cGVkZWYgdm9pZCAoR0xfQVBJRU5UUllQIFBGTkdMR0VUVEVYR0VOSVZPRVNQUk9DKSAoR0xlbnVtIGNvb3JkLCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpOwordHlwZWRlZiB2b2lkIChHTF9BUElFTlRSWVAgUEZOR0xHRVRURVhHRU5YVk9FU1BST0MpIChHTGVudW0gY29vcmQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKTsKKyNlbmRpZgorCisvKiBHTF9PRVNfdGV4dHVyZV9lbnZfY3Jvc3NiYXIgKi8KKyNpZm5kZWYgR0xfT0VTX3RleHR1cmVfZW52X2Nyb3NzYmFyCisjZGVmaW5lIEdMX09FU190ZXh0dXJlX2Vudl9jcm9zc2JhciAxCisjZW5kaWYKKworLyogR0xfT0VTX3RleHR1cmVfbWlycm9yZWRfcmVwZWF0ICovCisjaWZuZGVmIEdMX09FU190ZXh0dXJlX21pcnJvcmVkX3JlcGVhdAorI2RlZmluZSBHTF9PRVNfdGV4dHVyZV9taXJyb3JlZF9yZXBlYXQgMQorI2VuZGlmCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKgorICogQU1EIGV4dGVuc2lvbiBmdW5jdGlvbnMKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworLyogR0xfQU1EX2NvbXByZXNzZWRfM0RDX3RleHR1cmUgKi8KKyNpZm5kZWYgR0xfQU1EX2NvbXByZXNzZWRfM0RDX3RleHR1cmUKKyNkZWZpbmUgR0xfQU1EX2NvbXByZXNzZWRfM0RDX3RleHR1cmUgMQorI2VuZGlmCisKKy8qIEdMX0FNRF9jb21wcmVzc2VkX0FUQ190ZXh0dXJlICovCisjaWZuZGVmIEdMX0FNRF9jb21wcmVzc2VkX0FUQ190ZXh0dXJlCisjZGVmaW5lIEdMX0FNRF9jb21wcmVzc2VkX0FUQ190ZXh0dXJlIDEKKyNlbmRpZgorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSoKKyAqIEVYVCBleHRlbnNpb24gZnVuY3Rpb25zCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKy8qIEdMX0VYVF90ZXh0dXJlX2ZpbHRlcl9hbmlzb3Ryb3BpYyAqLworI2lmbmRlZiBHTF9FWFRfdGV4dHVyZV9maWx0ZXJfYW5pc290cm9waWMKKyNkZWZpbmUgR0xfRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljIDEKKyNlbmRpZgorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSoKKyAqIGRhbHZpayBleHRlbnNpb24gZnVuY3Rpb25zCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisjaWZkZWYgQU5EUk9JRAordm9pZCBnbENvbG9yUG9pbnRlckJvdW5kcyhHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsCisgICAgICAgIGNvbnN0IEdMdm9pZCAqcHRyLCBHTHNpemVpIGNvdW50KTsKK3ZvaWQgZ2xOb3JtYWxQb2ludGVyQm91bmRzKEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwKKyAgICAgICAgY29uc3QgR0x2b2lkICpwb2ludGVyLCBHTHNpemVpIGNvdW50KTsKK3ZvaWQgZ2xUZXhDb29yZFBvaW50ZXJCb3VuZHMoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsCisgICAgICAgIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIsIEdMc2l6ZWkgY291bnQpOwordm9pZCBnbFZlcnRleFBvaW50ZXJCb3VuZHMoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsCisgICAgICAgIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIsIEdMc2l6ZWkgY291bnQpOworI2VuZGlmCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2VuZGlmIC8qIF9fZ2xleHRfaF8gKi8KKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2luY2x1ZGUvR0xFUy9nbHBsYXRmb3JtLmggYi9vcGVuZ2wvaW5jbHVkZS9HTEVTL2dscGxhdGZvcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOTI0Y2FlCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2luY2x1ZGUvR0xFUy9nbHBsYXRmb3JtLmgKQEAgLTAsMCArMSwzOSBAQAorI2lmbmRlZiBfX2dscGxhdGZvcm1faF8KKyNkZWZpbmUgX19nbHBsYXRmb3JtX2hfCisKKy8qICRSZXZpc2lvbjogNzE3MiAkIG9uICREYXRlOjogMjAwOS0wMS0wOSAxMToxNzo0MSAtMDgwMCAjJCAqLworCisvKgorICogVGhpcyBkb2N1bWVudCBpcyBsaWNlbnNlZCB1bmRlciB0aGUgU0dJIEZyZWUgU29mdHdhcmUgQiBMaWNlbnNlIFZlcnNpb24KKyAqIDIuMC4gRm9yIGRldGFpbHMsIHNlZSBodHRwOi8vb3NzLnNnaS5jb20vcHJvamVjdHMvRnJlZUIvIC4KKyAqLworCisvKiBQbGF0Zm9ybS1zcGVjaWZpYyB0eXBlcyBhbmQgZGVmaW5pdGlvbnMgZm9yIE9wZW5HTCBFUyAxLlggIGdsLmgKKyAqIExhc3QgbW9kaWZpZWQgb24gMjAwOC8xMi8xOQorICoKKyAqIEFkb3B0ZXJzIG1heSBtb2RpZnkga2hycGxhdGZvcm0uaCBhbmQgdGhpcyBmaWxlIHRvIHN1aXQgdGhlaXIgcGxhdGZvcm0uCisgKiBZb3UgYXJlIGVuY291cmFnZWQgdG8gc3VibWl0IGFsbCBtb2RpZmljYXRpb25zIHRvIHRoZSBLaHJvbm9zIGdyb3VwIHNvIHRoYXQKKyAqIHRoZXkgY2FuIGJlIGluY2x1ZGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGlzIGZpbGUuICBQbGVhc2Ugc3VibWl0IGNoYW5nZXMKKyAqIGJ5IHNlbmRpbmcgdGhlbSB0byB0aGUgcHVibGljIEtocm9ub3MgQnVnemlsbGEgKGh0dHA6Ly9raHJvbm9zLm9yZy9idWd6aWxsYSkKKyAqIGJ5IGZpbGluZyBhIGJ1ZyBhZ2FpbnN0IHByb2R1Y3QgIk9wZW5HTC1FUyIgY29tcG9uZW50ICJSZWdpc3RyeSIuCisgKi8KKworI2luY2x1ZGUgPEtIUi9raHJwbGF0Zm9ybS5oPgorCisjaWZuZGVmIEdMX0FQSQorI2RlZmluZSBHTF9BUEkgICAgICBLSFJPTk9TX0FQSUNBTEwKKyNlbmRpZgorCisjaWYgZGVmaW5lZChBTkRST0lEKQorCisjZGVmaW5lIEdMX0FQSUVOVFJZIEtIUk9OT1NfQVBJRU5UUlkKKworLy8gWFhYOiB0aGlzIHNob3VsZCBwcm9iYWJseSBub3QgYmUgaGVyZQorI2RlZmluZSBHTF9ESVJFQ1RfVEVYVFVSRV8yRF9RVUFMQ09NTSAgICAgICAgICAgICAgIDB4N0U4MAorCisvLyBYWFg6IG5vdCBzdXJlIGhvdyB0aGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQKKyNkZWZpbmUgR0xfR0xFWFRfUFJPVE9UWVBFUworCisjZW5kaWYKKworI2VuZGlmIC8qIF9fZ2xwbGF0Zm9ybV9oXyAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2luY2x1ZGUvS0hSL2tocnBsYXRmb3JtLmggYi9vcGVuZ2wvaW5jbHVkZS9LSFIva2hycGxhdGZvcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Y2MyN2M1Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2luY2x1ZGUvS0hSL2tocnBsYXRmb3JtLmgKQEAgLTAsMCArMSwyNDEgQEAKKyNpZm5kZWYgX19raHJwbGF0Zm9ybV9oXworI2RlZmluZSBfX2tocnBsYXRmb3JtX2hfCisKKy8qCisqKiBDb3B5cmlnaHQgKGMpIDIwMDgtMjAwOSBUaGUgS2hyb25vcyBHcm91cCBJbmMuCisqKgorKiogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKKyoqIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQvb3IgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKKyoqICJNYXRlcmlhbHMiKSwgdG8gZGVhbCBpbiB0aGUgTWF0ZXJpYWxzIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZworKiogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAorKiogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBNYXRlcmlhbHMsIGFuZCB0bworKiogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgTWF0ZXJpYWxzIGFyZSBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KKyoqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKyoqCisqKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZAorKiogaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgTWF0ZXJpYWxzLgorKioKKyoqIFRIRSBNQVRFUklBTFMgQVJFIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCisqKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKKyoqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KKyoqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCisqKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAorKiogVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKKyoqIE1BVEVSSUFMUyBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBNQVRFUklBTFMuCisqLworCisvKiBQbGF0Zm9ybS1zcGVjaWZpYyB0eXBlcyBhbmQgZGVmaW5pdGlvbnMuCisgKiAkUmV2aXNpb246IDcyNDQgJCBvbiAkRGF0ZTogMjAwOS0wMS0yMCAxNzowNjo1OSAtMDgwMCAoVHVlLCAyMCBKYW4gMjAwOSkgJAorICogCisgKiBBZG9wdGVycyBtYXkgbW9kaWZ5IHRoaXMgZmlsZSB0byBzdWl0IHRoZWlyIHBsYXRmb3JtLiBBZG9wdGVycyBhcmUKKyAqIGVuY291cmFnZWQgdG8gc3VibWl0IHBsYXRmb3JtIHNwZWNpZmljIG1vZGlmaWNhdGlvbnMgdG8gdGhlIEtocm9ub3MKKyAqIGdyb3VwIHNvIHRoYXQgdGhleSBjYW4gYmUgaW5jbHVkZWQgaW4gZnV0dXJlIHZlcnNpb25zIG9mIHRoaXMgZmlsZS4KKyAqIFBsZWFzZSBzdWJtaXQgY2hhbmdlcyBieSBzZW5kaW5nIHRoZW0gdG8gdGhlIHB1YmxpYyBLaHJvbm9zIEJ1Z3ppbGxhCisgKiAoaHR0cDovL2tocm9ub3Mub3JnL2J1Z3ppbGxhKSBieSBmaWxpbmcgYSBidWcgYWdhaW5zdCBwcm9kdWN0CisgKiAiS2hyb25vcyAoZ2VuZXJhbCkiIGNvbXBvbmVudCAiUmVnaXN0cnkiLgorICoKKyAqIEEgcHJlZGVmaW5lZCB0ZW1wbGF0ZSB3aGljaCBmaWxscyBpbiBzb21lIG9mIHRoZSBidWcgZmllbGRzIGNhbiBiZQorICogcmVhY2hlZCB1c2luZyBodHRwOi8vdGlueXVybC5jb20va2hycGxhdGZvcm0taC1idWdyZXBvcnQsIGJ1dCB5b3UKKyAqIG11c3QgY3JlYXRlIGEgQnVnemlsbGEgbG9naW4gZmlyc3QuCisgKiAKKyAqCisgKiBTZWUgdGhlIEltcGxlbWVudGVyJ3MgR3VpZGVsaW5lcyBmb3IgaW5mb3JtYXRpb24gYWJvdXQgd2hlcmUgdGhpcyBmaWxlCisgKiBzaG91bGQgYmUgbG9jYXRlZCBvbiB5b3VyIHN5c3RlbS4KKyAqICAgIGh0dHA6Ly93d3cua2hyb25vcy5vcmcvcmVnaXN0cnkvaW1wbGVtZW50ZXJzX2d1aWRlLnBkZgorICoKKyAqIAorICogVGhpcyBmaWxlIHNob3VsZCBiZSBpbmNsdWRlZCBhcworICogICAgICAgICNpbmNsdWRlIDxLSFIva2hycGxhdGZvcm0uaD4KKyAqIGJ5IHRoZSBLaHJvbm9zIEFQSSBoZWFkZXIgZmlsZSB0aGF0IHVzZXMgaXRzIHR5cGVzIGFuZCBkZWZpbmVzLgorICoKKyAqIFRoZSB0eXBlcyBpbiB0aGlzIGZpbGUgc2hvdWxkIG9ubHkgYmUgdXNlZCB0byBkZWZpbmUgQVBJLXNwZWNpZmljIHR5cGVzLgorICogVHlwZXMgZGVmaW5lZCBpbiB0aGlzIGZpbGU6CisgKiAgICBraHJvbm9zX2ludDhfdCAgICAgICAgICAgICAgc2lnbmVkICAgOCAgYml0CisgKiAgICBraHJvbm9zX3VpbnQ4X3QgICAgICAgICAgICAgdW5zaWduZWQgOCAgYml0CisgKiAgICBraHJvbm9zX2ludDE2X3QgICAgICAgICAgICAgc2lnbmVkICAgMTYgYml0CisgKiAgICBraHJvbm9zX3VpbnQxNl90ICAgICAgICAgICAgdW5zaWduZWQgMTYgYml0CisgKiAgICBraHJvbm9zX2ludDMyX3QgICAgICAgICAgICAgc2lnbmVkICAgMzIgYml0CisgKiAgICBraHJvbm9zX3VpbnQzMl90ICAgICAgICAgICAgdW5zaWduZWQgMzIgYml0CisgKiAgICBraHJvbm9zX2ludDY0X3QgICAgICAgICAgICAgc2lnbmVkICAgNjQgYml0CisgKiAgICBraHJvbm9zX3VpbnQ2NF90ICAgICAgICAgICAgdW5zaWduZWQgNjQgYml0CisgKiAgICBraHJvbm9zX2ludHB0cl90ICAgICAgICAgICAgc2lnbmVkICAgc2FtZSBudW1iZXIgb2YgYml0cyBhcyBhIHBvaW50ZXIKKyAqICAgIGtocm9ub3NfdWludHB0cl90ICAgICAgICAgICB1bnNpZ25lZCBzYW1lIG51bWJlciBvZiBiaXRzIGFzIGEgcG9pbnRlcgorICogICAga2hyb25vc19zc2l6ZV90ICAgICAgICAgICAgIHNpZ25lZCAgIHNpemUKKyAqICAgIGtocm9ub3NfdXNpemVfdCAgICAgICAgICAgICB1bnNpZ25lZCBzaXplCisgKiAgICBraHJvbm9zX2Zsb2F0X3QgICAgICAgICAgICAgc2lnbmVkICAgMzIgYml0IGZsb2F0aW5nIHBvaW50CisgKiAgICBraHJvbm9zX3RpbWVfbnNfdCAgICAgICAgICAgdW5zaWduZWQgNjQgYml0IHRpbWUgaW4gbmFub3NlY29uZHMKKyAqICAgIGtocm9ub3NfdXRpbWVfbmFub3NlY29uZHNfdCB1bnNpZ25lZCB0aW1lIGludGVydmFsIG9yIGFic29sdXRlIHRpbWUgaW4KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW5vc2Vjb25kcworICogICAga2hyb25vc19zdGltZV9uYW5vc2Vjb25kc190IHNpZ25lZCB0aW1lIGludGVydmFsIGluIG5hbm9zZWNvbmRzCisgKgorICogS0hST05PU19TVVBQT1JUX0lOVDY0IGlzIDEgaWYgNjQgYml0IGludGVnZXJzIGFyZSBzdXBwb3J0ZWQ7IG90aGVyd2lzZSAwLgorICogS0hST05PU19TVVBQT1JUX0ZMT0FUIGlzIDEgaWYgZmxvYXRzIGFyZSBzdXBwb3J0ZWQ7IG90aGVyd2lzZSAwLgorICogCisgKgorICogTWFjcm9zIGRlZmluZWQgaW4gdGhpcyBmaWxlOgorICogICAgS0hST05PU19BUElDQUxMCisgKiAgICBLSFJPTk9TX0FQSUVOVFJZCisgKiAgICBLSFJPTk9TX0FQSUFUVFJJQlVURVMKKyAqIFRoZXNlIG1heSBiZSB1c2VkIGluIGZ1bmN0aW9uIHByb3RvdHlwZXMgYXM6CisgKiAgICAgIEtIUk9OT1NfQVBJQ0FMTCB2b2lkIEtIUk9OT1NfQVBJRU5UUlkgZnVuY25hbWUoCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYXJnMSwKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBhcmcyKSBLSFJPTk9TX0FQSUFUVFJJQlVURVM7CisgKi8KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBEZWZpbml0aW9uIG9mIEtIUk9OT1NfQVBJQ0FMTAorICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBUaGlzIHByZWNlZGVzIHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgZnVuY3Rpb24gaW4gdGhlIGZ1bmN0aW9uIHByb3RvdHlwZS4KKyAqLworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX1NDSVRFQ0hfU05BUF9fKQorIyAgIGRlZmluZSBLSFJPTk9TX0FQSUNBTEwgX19kZWNsc3BlYyhkbGxpbXBvcnQpCisjZWxpZiBkZWZpbmVkIChfX1NZTUJJQU4zMl9fKQorIyAgIGRlZmluZSBLSFJPTk9TX0FQSUNBTEwgSU1QT1JUX0MKKyNlbHNlCisjICAgZGVmaW5lIEtIUk9OT1NfQVBJQ0FMTAorI2VuZGlmCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICogRGVmaW5pdGlvbiBvZiBLSFJPTk9TX0FQSUVOVFJZCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIFRoaXMgZm9sbG93cyB0aGUgcmV0dXJuIHR5cGUgb2YgdGhlIGZ1bmN0aW9uICBhbmQgcHJlY2VkZXMgdGhlIGZ1bmN0aW9uCisgKiBuYW1lIGluIHRoZSBmdW5jdGlvbiBwcm90b3R5cGUuCisgKi8KKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX1dJTjMyX1dDRSkgJiYgIWRlZmluZWQoX19TQ0lURUNIX1NOQVBfXykKKyAgICAvKiBXaW4zMiBidXQgbm90IFdpbkNFICovCisjICAgZGVmaW5lIEtIUk9OT1NfQVBJRU5UUlkgX19zdGRjYWxsCisjZWxzZQorIyAgIGRlZmluZSBLSFJPTk9TX0FQSUVOVFJZCisjZW5kaWYKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBEZWZpbml0aW9uIG9mIEtIUk9OT1NfQVBJQVRUUklCVVRFUworICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBUaGlzIGZvbGxvd3MgdGhlIGNsb3NpbmcgcGFyZW50aGVzaXMgb2YgdGhlIGZ1bmN0aW9uIHByb3RvdHlwZSBhcmd1bWVudHMuCisgKi8KKyNpZiBkZWZpbmVkIChfX0FSTUNDXzJfXykKKyNkZWZpbmUgS0hST05PU19BUElBVFRSSUJVVEVTIF9fc29mdGZwCisjZWxzZQorI2RlZmluZSBLSFJPTk9TX0FQSUFUVFJJQlVURVMKKyNlbmRpZgorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIGJhc2ljIHR5cGUgZGVmaW5pdGlvbnMKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworI2lmIChkZWZpbmVkKF9fU1REQ19WRVJTSU9OX18pICYmIF9fU1REQ19WRVJTSU9OX18gPj0gMTk5OTAxTCkgfHwgZGVmaW5lZChfX0dOVUNfXykgfHwgZGVmaW5lZChfX1NDT19fKSB8fCBkZWZpbmVkKF9fVVNMQ19fKQorCisKKy8qCisgKiBVc2luZyA8c3RkaW50Lmg+CisgKi8KKyNpbmNsdWRlIDxzdGRpbnQuaD4KK3R5cGVkZWYgaW50MzJfdCAgICAgICAgICAgICAgICAga2hyb25vc19pbnQzMl90OwordHlwZWRlZiB1aW50MzJfdCAgICAgICAgICAgICAgICBraHJvbm9zX3VpbnQzMl90OwordHlwZWRlZiBpbnQ2NF90ICAgICAgICAgICAgICAgICBraHJvbm9zX2ludDY0X3Q7Cit0eXBlZGVmIHVpbnQ2NF90ICAgICAgICAgICAgICAgIGtocm9ub3NfdWludDY0X3Q7CisjZGVmaW5lIEtIUk9OT1NfU1VQUE9SVF9JTlQ2NCAgIDEKKyNkZWZpbmUgS0hST05PU19TVVBQT1JUX0ZMT0FUICAgMQorCisjZWxpZiBkZWZpbmVkKF9fVk1TICkgfHwgZGVmaW5lZChfX3NnaSkKKworLyoKKyAqIFVzaW5nIDxpbnR0eXBlcy5oPgorICovCisjaW5jbHVkZSA8aW50dHlwZXMuaD4KK3R5cGVkZWYgaW50MzJfdCAgICAgICAgICAgICAgICAga2hyb25vc19pbnQzMl90OwordHlwZWRlZiB1aW50MzJfdCAgICAgICAgICAgICAgICBraHJvbm9zX3VpbnQzMl90OwordHlwZWRlZiBpbnQ2NF90ICAgICAgICAgICAgICAgICBraHJvbm9zX2ludDY0X3Q7Cit0eXBlZGVmIHVpbnQ2NF90ICAgICAgICAgICAgICAgIGtocm9ub3NfdWludDY0X3Q7CisjZGVmaW5lIEtIUk9OT1NfU1VQUE9SVF9JTlQ2NCAgIDEKKyNkZWZpbmUgS0hST05PU19TVVBQT1JUX0ZMT0FUICAgMQorCisjZWxpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX19TQ0lURUNIX1NOQVBfXykKKworLyoKKyAqIFdpbjMyCisgKi8KK3R5cGVkZWYgX19pbnQzMiAgICAgICAgICAgICAgICAga2hyb25vc19pbnQzMl90OwordHlwZWRlZiB1bnNpZ25lZCBfX2ludDMyICAgICAgICBraHJvbm9zX3VpbnQzMl90OwordHlwZWRlZiBfX2ludDY0ICAgICAgICAgICAgICAgICBraHJvbm9zX2ludDY0X3Q7Cit0eXBlZGVmIHVuc2lnbmVkIF9faW50NjQgICAgICAgIGtocm9ub3NfdWludDY0X3Q7CisjZGVmaW5lIEtIUk9OT1NfU1VQUE9SVF9JTlQ2NCAgIDEKKyNkZWZpbmUgS0hST05PU19TVVBQT1JUX0ZMT0FUICAgMQorCisjZWxpZiBkZWZpbmVkKF9fc3VuX18pIHx8IGRlZmluZWQoX19kaWdpdGFsX18pCisKKy8qCisgKiBTdW4gb3IgRGlnaXRhbAorICovCit0eXBlZGVmIGludCAgICAgICAgICAgICAgICAgICAgIGtocm9ub3NfaW50MzJfdDsKK3R5cGVkZWYgdW5zaWduZWQgaW50ICAgICAgICAgICAga2hyb25vc191aW50MzJfdDsKKyNpZiBkZWZpbmVkKF9fYXJjaDY0X18pIHx8IGRlZmluZWQoX0xQNjQpCit0eXBlZGVmIGxvbmcgaW50ICAgICAgICAgICAgICAgIGtocm9ub3NfaW50NjRfdDsKK3R5cGVkZWYgdW5zaWduZWQgbG9uZyBpbnQgICAgICAga2hyb25vc191aW50NjRfdDsKKyNlbHNlCit0eXBlZGVmIGxvbmcgbG9uZyBpbnQgICAgICAgICAgIGtocm9ub3NfaW50NjRfdDsKK3R5cGVkZWYgdW5zaWduZWQgbG9uZyBsb25nIGludCAga2hyb25vc191aW50NjRfdDsKKyNlbmRpZiAvKiBfX2FyY2g2NF9fICovCisjZGVmaW5lIEtIUk9OT1NfU1VQUE9SVF9JTlQ2NCAgIDEKKyNkZWZpbmUgS0hST05PU19TVVBQT1JUX0ZMT0FUICAgMQorCisjZWxpZiAwCisKKy8qCisgKiBIeXBvdGhldGljYWwgcGxhdGZvcm0gd2l0aCBubyBmbG9hdCBvciBpbnQ2NCBzdXBwb3J0CisgKi8KK3R5cGVkZWYgaW50ICAgICAgICAgICAgICAgICAgICAga2hyb25vc19pbnQzMl90OwordHlwZWRlZiB1bnNpZ25lZCBpbnQgICAgICAgICAgICBraHJvbm9zX3VpbnQzMl90OworI2RlZmluZSBLSFJPTk9TX1NVUFBPUlRfSU5UNjQgICAwCisjZGVmaW5lIEtIUk9OT1NfU1VQUE9SVF9GTE9BVCAgIDAKKworI2Vsc2UKKworLyoKKyAqIEdlbmVyaWMgZmFsbGJhY2sKKyAqLworI2luY2x1ZGUgPHN0ZGludC5oPgordHlwZWRlZiBpbnQzMl90ICAgICAgICAgICAgICAgICBraHJvbm9zX2ludDMyX3Q7Cit0eXBlZGVmIHVpbnQzMl90ICAgICAgICAgICAgICAgIGtocm9ub3NfdWludDMyX3Q7Cit0eXBlZGVmIGludDY0X3QgICAgICAgICAgICAgICAgIGtocm9ub3NfaW50NjRfdDsKK3R5cGVkZWYgdWludDY0X3QgICAgICAgICAgICAgICAga2hyb25vc191aW50NjRfdDsKKyNkZWZpbmUgS0hST05PU19TVVBQT1JUX0lOVDY0ICAgMQorI2RlZmluZSBLSFJPTk9TX1NVUFBPUlRfRkxPQVQgICAxCisKKyNlbmRpZgorCisKKy8qCisgKiBUeXBlcyB0aGF0IGFyZSAoc28gZmFyKSB0aGUgc2FtZSBvbiBhbGwgcGxhdGZvcm1zCisgKi8KK3R5cGVkZWYgc2lnbmVkICAgY2hhciAgICAgICAgICBraHJvbm9zX2ludDhfdDsKK3R5cGVkZWYgdW5zaWduZWQgY2hhciAgICAgICAgICBraHJvbm9zX3VpbnQ4X3Q7Cit0eXBlZGVmIHNpZ25lZCAgIHNob3J0IGludCAgICAga2hyb25vc19pbnQxNl90OwordHlwZWRlZiB1bnNpZ25lZCBzaG9ydCBpbnQgICAgIGtocm9ub3NfdWludDE2X3Q7Cit0eXBlZGVmIHNpZ25lZCAgIGxvbmcgIGludCAgICAga2hyb25vc19pbnRwdHJfdDsKK3R5cGVkZWYgdW5zaWduZWQgbG9uZyAgaW50ICAgICBraHJvbm9zX3VpbnRwdHJfdDsKK3R5cGVkZWYgc2lnbmVkICAgbG9uZyAgaW50ICAgICBraHJvbm9zX3NzaXplX3Q7Cit0eXBlZGVmIHVuc2lnbmVkIGxvbmcgIGludCAgICAga2hyb25vc191c2l6ZV90OworCisjaWYgS0hST05PU19TVVBQT1JUX0ZMT0FUCisvKgorICogRmxvYXQgdHlwZQorICovCit0eXBlZGVmICAgICAgICAgIGZsb2F0ICAgICAgICAga2hyb25vc19mbG9hdF90OworI2VuZGlmCisKKyNpZiBLSFJPTk9TX1NVUFBPUlRfSU5UNjQKKy8qIFRpbWUgdHlwZXMKKyAqCisgKiBUaGVzZSB0eXBlcyBjYW4gYmUgdXNlZCB0byByZXByZXNlbnQgYSB0aW1lIGludGVydmFsIGluIG5hbm9zZWNvbmRzIG9yIAorICogYW4gYWJzb2x1dGUgVW5hZGp1c3RlZCBTeXN0ZW0gVGltZS4gIFVuYWRqdXN0ZWQgU3lzdGVtIFRpbWUgaXMgdGhlIG51bWJlciAKKyAqIG9mIG5hbm9zZWNvbmRzIHNpbmNlIHNvbWUgYXJiaXRyYXJ5IHN5c3RlbSBldmVudCAoZS5nLiBzaW5jZSB0aGUgbGFzdCAKKyAqIHRpbWUgdGhlIHN5c3RlbSBib290ZWQpLiAgVGhlIFVuYWRqdXN0ZWQgU3lzdGVtIFRpbWUgaXMgYW4gdW5zaWduZWQgCisgKiA2NCBiaXQgdmFsdWUgdGhhdCB3cmFwcyBiYWNrIHRvIDAgZXZlcnkgNTg0IHllYXJzLiAgVGltZSBpbnRlcnZhbHMgCisgKiBtYXkgYmUgZWl0aGVyIHNpZ25lZCBvciB1bnNpZ25lZC4KKyAqLwordHlwZWRlZiBraHJvbm9zX3VpbnQ2NF90ICAgICAgIGtocm9ub3NfdXRpbWVfbmFub3NlY29uZHNfdDsKK3R5cGVkZWYga2hyb25vc19pbnQ2NF90ICAgICAgICBraHJvbm9zX3N0aW1lX25hbm9zZWNvbmRzX3Q7CisjZW5kaWYKKworCisjZW5kaWYgLyogX19raHJwbGF0Zm9ybV9oXyAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9BbmRyb2lkLm1rIGIvb3BlbmdsL2xpYmFnbC9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5ZWZlNGMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL0FuZHJvaWQubWsKQEAgLTAsMCArMSwzOSBAQAorTE9DQUxfUEFUSDo9ICQoY2FsbCBteS1kaXIpCisKKyMKKyMgQnVpbGQgdGhlIHNvZnR3YXJlIE9wZW5HTCBFUyBsaWJyYXJ5CisjCisKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVM6PSBcCisJZWdsLmNwcCAgICAgICAgICAgICAgICAgICAgIFwKKwlzdGF0ZS5jcHAJCSAgICAgICAgICAgIFwKKwl0ZXh0dXJlLmNwcAkJICAgICAgICAgICAgXAorICAgIFRva2VuaXplci5jcHAgICAgICAgICAgICAgICBcCisgICAgVG9rZW5NYW5hZ2VyLmNwcCAgICAgICAgICAgIFwKKyAgICBUZXh0dXJlT2JqZWN0TWFuYWdlci5jcHAgICAgXAorICAgIEJ1ZmZlck9iamVjdE1hbmFnZXIuY3BwICAgICBcCisJYXJyYXkuY3BwLmFybQkJICAgICAgICBcCisJZnAuY3BwLmFybQkJICAgICAgICAgICAgXAorCWxpZ2h0LmNwcC5hcm0JCSAgICAgICAgXAorCW1hdHJpeC5jcHAuYXJtCQkgICAgICAgIFwKKwltaXBtYXAuY3BwLmFybQkJICAgICAgICBcCisJcHJpbWl0aXZlcy5jcHAuYXJtCSAgICAgICAgXAorCXZlcnRleC5jcHAuYXJtCisKK2lmZXEgKCQoVEFSR0VUX0FSQ0gpLGFybSkKKwlMT0NBTF9TUkNfRklMRVMgKz0gZml4ZWRfYXNtLlMgaXRlcmF0b3JzLlMKKwlMT0NBTF9DRkxBR1MgKz0gLWZzdHJpY3QtYWxpYXNpbmcKK2VuZGlmCisKK2lmbmVxICgkKFRBUkdFVF9TSU1VTEFUT1IpLHRydWUpCisgICAgIyB3ZSBuZWVkIHRvIGFjY2VzcyB0aGUgcHJpdmF0ZSBCaW9uaWMgaGVhZGVyIDxiaW9uaWNfdGxzLmg+CisgICAgTE9DQUxfQ0ZMQUdTICs9IC1JJChMT0NBTF9QQVRIKS8uLi8uLi8uLi8uLi9iaW9uaWMvbGliYy9wcml2YXRlCitlbmRpZgorCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IGxpYmN1dGlscyBsaWJ1dGlscyBsaWJwaXhlbGZsaW5nZXIKK0xPQ0FMX0xETElCUyA6PSAtbHB0aHJlYWQgLWxkbAorTE9DQUxfTU9EVUxFOj0gbGliYWdsCisKK2luY2x1ZGUgJChCVUlMRF9TSEFSRURfTElCUkFSWSkKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvQnVmZmVyT2JqZWN0TWFuYWdlci5jcHAgYi9vcGVuZ2wvbGliYWdsL0J1ZmZlck9iamVjdE1hbmFnZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiZjI4ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL0J1ZmZlck9iamVjdE1hbmFnZXIuY3BwCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICoqIENvcHlyaWdodCAyMDA4LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKioKKyAqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisgKioKKyAqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoqCisgKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisgKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9BdG9taWMuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKworI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2luY2x1ZGUgIkJ1ZmZlck9iamVjdE1hbmFnZXIuaCIKKworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK3VzaW5nIG5hbWVzcGFjZSBnbDsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xCdWZmZXJPYmplY3RNYW5hZ2VyOjpFR0xCdWZmZXJPYmplY3RNYW5hZ2VyKCkgCis6IFRva2VuTWFuYWdlcigpLCBtQ291bnQoMCkKK3sKK30KKworRUdMQnVmZmVyT2JqZWN0TWFuYWdlcjo6fkVHTEJ1ZmZlck9iamVjdE1hbmFnZXIoKQoreworICAgIC8vIGRlc3Ryb3kgYWxsIHRoZSBidWZmZXIgb2JqZWN0cyBhbmQgdGhlaXIgc3RvcmFnZQorICAgIEdMc2l6ZWkgbiA9IG1CdWZmZXJzLnNpemUoKTsKKyAgICBmb3IgKEdMc2l6ZWkgaT0wIDsgaTxuIDsgaSsrKSB7CisgICAgICAgIGJ1ZmZlcl90KiBibyA9IG1CdWZmZXJzLnZhbHVlQXQoaSk7CisgICAgICAgIGZyZWUoYm8tPmRhdGEpOworICAgICAgICBkZWxldGUgYm87CisgICAgfQorfQorCitidWZmZXJfdCBjb25zdCogRUdMQnVmZmVyT2JqZWN0TWFuYWdlcjo6YmluZChHTHVpbnQgYnVmZmVyKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgaW50MzJfdCBpID0gbUJ1ZmZlcnMuaW5kZXhPZktleShidWZmZXIpOworICAgIGlmIChpID49IDApIHsKKyAgICAgICAgcmV0dXJuIG1CdWZmZXJzLnZhbHVlQXQoaSk7CisgICAgfQorICAgIGJ1ZmZlcl90KiBibyA9IG5ldyBidWZmZXJfdDsKKyAgICBiby0+ZGF0YSA9IDA7CisgICAgYm8tPnVzYWdlID0gR0xfU1RBVElDX0RSQVc7CisgICAgYm8tPnNpemUgPSAwOworICAgIGJvLT5uYW1lID0gYnVmZmVyOworICAgIG1CdWZmZXJzLmFkZChidWZmZXIsIGJvKTsKKyAgICByZXR1cm4gYm87Cit9CisKK2ludCBFR0xCdWZmZXJPYmplY3RNYW5hZ2VyOjphbGxvY2F0ZVN0b3JlKGJ1ZmZlcl90KiBibywKKyAgICAgICAgR0xzaXplaXB0ciBzaXplLCBHTGVudW0gdXNhZ2UpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBpZiAoc2l6ZSAhPSBiby0+c2l6ZSkgeworICAgICAgIHVpbnQ4X3QqIGRhdGEgPSAodWludDhfdCopbWFsbG9jKHNpemUpOworICAgICAgICBpZiAoZGF0YSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBmcmVlKGJvLT5kYXRhKTsKKyAgICAgICAgYm8tPmRhdGEgPSBkYXRhOworICAgICAgICBiby0+c2l6ZSA9IHNpemU7CisgICAgfQorICAgIGJvLT51c2FnZSA9IHVzYWdlOworICAgIHJldHVybiAwOworfQorCit2b2lkIEVHTEJ1ZmZlck9iamVjdE1hbmFnZXI6OmRlbGV0ZUJ1ZmZlcnMoR0xzaXplaSBuLCBjb25zdCBHTHVpbnQqIGJ1ZmZlcnMpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICB3aGlsZSAobi0tKSB7CisgICAgICAgIGNvbnN0IEdMdWludCB0ID0gKmJ1ZmZlcnMrKzsKKyAgICAgICAgaWYgKHQpIHsKKyAgICAgICAgICAgIGludDMyX3QgaW5kZXggPSBtQnVmZmVycy5pbmRleE9mS2V5KHQpOworICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgICAgICAgICAgICBidWZmZXJfdCogYm8gPSBtQnVmZmVycy52YWx1ZUF0KGluZGV4KTsKKyAgICAgICAgICAgICAgICBmcmVlKGJvLT5kYXRhKTsKKyAgICAgICAgICAgICAgICBtQnVmZmVycy5yZW1vdmVJdGVtc0F0KGluZGV4KTsKKyAgICAgICAgICAgICAgICBkZWxldGUgYm87CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL0J1ZmZlck9iamVjdE1hbmFnZXIuaCBiL29wZW5nbC9saWJhZ2wvQnVmZmVyT2JqZWN0TWFuYWdlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllOTM0MGEKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL0J1ZmZlck9iamVjdE1hbmFnZXIuaApAQCAtMCwwICsxLDg1IEBACisvKgorICoqCisgKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqKgorICoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqKgorICoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKioKKyAqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19CVUZGRVJfT0JKRUNUX01BTkFHRVJfSAorI2RlZmluZSBBTkRST0lEX09QRU5HTEVTX0JVRkZFUl9PQkpFQ1RfTUFOQUdFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0F0b21pYy5oPgorI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKyNpbmNsdWRlIDx1dGlscy9LZXllZFZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjaW5jbHVkZSAiVG9rZW5pemVyLmgiCisjaW5jbHVkZSAiVG9rZW5NYW5hZ2VyLmgiCisKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBnbCB7CisKK3N0cnVjdCBidWZmZXJfdCB7CisgICAgR0xzaXplaXB0ciAgICAgIHNpemU7CisgICAgR0xlbnVtICAgICAgICAgIHVzYWdlOworICAgIHVpbnQ4X3QqICAgICAgICBkYXRhOworICAgIHVpbnQzMl90ICAgICAgICBuYW1lOworfTsKKworfTsKKworY2xhc3MgRUdMQnVmZmVyT2JqZWN0TWFuYWdlciA6IHB1YmxpYyBUb2tlbk1hbmFnZXIKK3sKK3B1YmxpYzoKKyAgICBFR0xCdWZmZXJPYmplY3RNYW5hZ2VyKCk7CisgICAgfkVHTEJ1ZmZlck9iamVjdE1hbmFnZXIoKTsKKworICAgIC8vIHByb3RvY29sIGZvciBzcDw+CisgICAgaW5saW5lICB2b2lkICAgIGluY1N0cm9uZyhjb25zdCB2b2lkKiBpZCkgY29uc3Q7CisgICAgaW5saW5lICB2b2lkICAgIGRlY1N0cm9uZyhjb25zdCB2b2lkKiBpZCkgY29uc3Q7CisgICAgdHlwZWRlZiB2b2lkICAgIHdlYWtyZWZfdHlwZTsKKworICAgIGdsOjpidWZmZXJfdCBjb25zdCogYmluZChHTHVpbnQgYnVmZmVyKTsKKyAgICBpbnQgICAgICAgICAgICAgICAgIGFsbG9jYXRlU3RvcmUoZ2w6OmJ1ZmZlcl90KiBibywgR0xzaXplaXB0ciBzaXplLCBHTGVudW0gdXNhZ2UpOworICAgIHZvaWQgICAgICAgICAgICAgICAgZGVsZXRlQnVmZmVycyhHTHNpemVpIG4sIGNvbnN0IEdMdWludCogYnVmZmVycyk7CisKK3ByaXZhdGU6CisgICAgbXV0YWJsZSB2b2xhdGlsZSBpbnQzMl90ICAgICAgICAgICAgbUNvdW50OworICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgIG1Mb2NrOworICAgIEtleWVkVmVjdG9yPEdMdWludCwgZ2w6OmJ1ZmZlcl90Kj4gIG1CdWZmZXJzOworfTsKKwordm9pZCBFR0xCdWZmZXJPYmplY3RNYW5hZ2VyOjppbmNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0IHsKKyAgICBhbmRyb2lkX2F0b21pY19pbmMoJm1Db3VudCk7Cit9Cit2b2lkIEVHTEJ1ZmZlck9iamVjdE1hbmFnZXI6OmRlY1N0cm9uZyhjb25zdCB2b2lkKiBpZCkgY29uc3QgeworICAgIGlmIChhbmRyb2lkX2F0b21pY19kZWMoJm1Db3VudCkgPT0gMSkgeworICAgICAgICBkZWxldGUgdGhpczsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09QRU5HTEVTX0JVRkZFUl9PQkpFQ1RfTUFOQUdFUl9ICisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvVGV4dHVyZU9iamVjdE1hbmFnZXIuY3BwIGIvb3BlbmdsL2xpYmFnbC9UZXh0dXJlT2JqZWN0TWFuYWdlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2UzMTg1NAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvVGV4dHVyZU9iamVjdE1hbmFnZXIuY3BwCkBAIC0wLDAgKzEsMzA5IEBACisvKgorICoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKioKKyAqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisgKioKKyAqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoqCisgKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisgKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlICJjb250ZXh0LmgiCisjaW5jbHVkZSAiVGV4dHVyZU9iamVjdE1hbmFnZXIuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xUZXh0dXJlT2JqZWN0OjpFR0xUZXh0dXJlT2JqZWN0KCkKKyAgICA6IG1Db3VudCgwKSwgbVNpemUoMCkKK3sKKyAgICBpbml0KCk7Cit9CisKK0VHTFRleHR1cmVPYmplY3Q6On5FR0xUZXh0dXJlT2JqZWN0KCkKK3sKKyAgICBpZiAoIWRpcmVjdCkgeworICAgICAgICBpZiAobVNpemUgJiYgc3VyZmFjZS5kYXRhKQorICAgICAgICAgICAgZnJlZShzdXJmYWNlLmRhdGEpOworICAgICAgICBpZiAobU1pcG1hcHMpCisgICAgICAgICAgICBmcmVlTWlwbWFwcygpOworICAgIH0KK30KKwordm9pZCBFR0xUZXh0dXJlT2JqZWN0Ojppbml0KCkKK3sKKyAgICBtZW1zZXQoJnN1cmZhY2UsIDAsIHNpemVvZihzdXJmYWNlKSk7CisgICAgc3VyZmFjZS52ZXJzaW9uID0gc2l6ZW9mKHN1cmZhY2UpOworICAgIG1NaXBtYXBzID0gMDsKKyAgICBtTnVtRXh0cmFMb2QgPSAwOworICAgIG1Jc0NvbXBsZXRlID0gZmFsc2U7CisgICAgd3JhcHMgPSBHTF9SRVBFQVQ7CisgICAgd3JhcHQgPSBHTF9SRVBFQVQ7CisgICAgbWluX2ZpbHRlciA9IEdMX0xJTkVBUjsKKyAgICBtYWdfZmlsdGVyID0gR0xfTElORUFSOworICAgIGludGVybmFsZm9ybWF0ID0gMDsKKyAgICBtZW1zZXQoY3JvcF9yZWN0LCAwLCBzaXplb2YoY3JvcF9yZWN0KSk7CisgICAgZ2VuZXJhdGVfbWlwbWFwID0gR0xfRkFMU0U7CisgICAgZGlyZWN0ID0gR0xfRkFMU0U7Cit9CisKK3ZvaWQgRUdMVGV4dHVyZU9iamVjdDo6Y29weVBhcmFtZXRlcnMoY29uc3Qgc3A8RUdMVGV4dHVyZU9iamVjdD4mIG9sZCkKK3sKKyAgICB3cmFwcyA9IG9sZC0+d3JhcHM7CisgICAgd3JhcHQgPSBvbGQtPndyYXB0OworICAgIG1pbl9maWx0ZXIgPSBvbGQtPm1pbl9maWx0ZXI7CisgICAgbWFnX2ZpbHRlciA9IG9sZC0+bWFnX2ZpbHRlcjsKKyAgICBtZW1jcHkoY3JvcF9yZWN0LCBvbGQtPmNyb3BfcmVjdCwgc2l6ZW9mKGNyb3BfcmVjdCkpOworICAgIGdlbmVyYXRlX21pcG1hcCA9IG9sZC0+Z2VuZXJhdGVfbWlwbWFwOworICAgIGRpcmVjdCA9IG9sZC0+ZGlyZWN0OworfQorCitzdGF0dXNfdCBFR0xUZXh0dXJlT2JqZWN0OjphbGxvY2F0ZU1pcG1hcHMoKQoreworICAgIC8vIGhlcmUsIGJ5IGNvbnN0cnVjdGlvbiwgbU1pcG1hcHM9MCAmJiBtTnVtRXh0cmFMb2Q9MAorCisgICAgaWYgKCFzdXJmYWNlLmRhdGEpCisgICAgICAgIHJldHVybiBOT19JTklUOworCisgICAgaW50IHcgPSBzdXJmYWNlLndpZHRoOworICAgIGludCBoID0gc3VyZmFjZS5oZWlnaHQ7CisgICAgY29uc3QgaW50IG51bUxvZHMgPSAzMSAtIGdnbENseihtYXgodyxoKSk7CisgICAgaWYgKG51bUxvZHMgPD0gMCkKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworCisgICAgbU1pcG1hcHMgPSAoR0dMU3VyZmFjZSopbWFsbG9jKG51bUxvZHMgKiBzaXplb2YoR0dMU3VyZmFjZSkpOworICAgIGlmICghbU1pcG1hcHMpCisgICAgICAgIHJldHVybiBOT19NRU1PUlk7CisKKyAgICBtZW1zZXQobU1pcG1hcHMsIDAsIG51bUxvZHMgKiBzaXplb2YoR0dMU3VyZmFjZSkpOworICAgIG1OdW1FeHRyYUxvZCA9IG51bUxvZHM7CisgICAgcmV0dXJuIE5PX0VSUk9SOworfQorCit2b2lkIEVHTFRleHR1cmVPYmplY3Q6OmZyZWVNaXBtYXBzKCkKK3sKKyAgICBpZiAobU1pcG1hcHMpIHsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxtTnVtRXh0cmFMb2QgOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChtTWlwbWFwc1tpXS5kYXRhKSB7CisgICAgICAgICAgICAgICAgZnJlZShtTWlwbWFwc1tpXS5kYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmcmVlKG1NaXBtYXBzKTsKKyAgICAgICAgbU1pcG1hcHMgPSAwOworICAgICAgICBtTnVtRXh0cmFMb2QgPSAwOworICAgIH0KK30KKworY29uc3QgR0dMU3VyZmFjZSYgRUdMVGV4dHVyZU9iamVjdDo6bWlwKGludCBsb2QpIGNvbnN0Cit7CisgICAgaWYgKGxvZDw9MCB8fCAhbU1pcG1hcHMpCisgICAgICAgIHJldHVybiBzdXJmYWNlOworICAgIGxvZCA9IG1pbihsb2QtMSwgbU51bUV4dHJhTG9kLTEpOworICAgIHJldHVybiBtTWlwbWFwc1tsb2RdOworfQorCitHR0xTdXJmYWNlJiBFR0xUZXh0dXJlT2JqZWN0OjplZGl0TWlwKGludCBsb2QpCit7CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8R0dMU3VyZmFjZSY+KG1pcChsb2QpKTsKK30KKworc3RhdHVzX3QgRUdMVGV4dHVyZU9iamVjdDo6c2V0U3VyZmFjZShHR0xTdXJmYWNlIGNvbnN0KiBzKQoreworICAgIC8vIFhYWDogZ2xGbHVzaCgpIG9uICdzJworICAgIGlmIChtU2l6ZSAmJiBzdXJmYWNlLmRhdGEpIHsKKyAgICAgICAgZnJlZShzdXJmYWNlLmRhdGEpOworICAgIH0KKyAgICBzdXJmYWNlID0gKnM7CisgICAgaW50ZXJuYWxmb3JtYXQgPSAwOworCisgICAgLy8gd2Ugc2hvdWxkIGtlZXAgdGhlIGNyb3BfcmVjdCwgYnV0IGl0J3MgZGVsaWNhdGUgYmVjYXVzZQorICAgIC8vIHRoZSBuZXcgc2l6ZSBvZiB0aGUgc3VyZmFjZSBjb3VsZCBtYWtlIGl0IGludmFsaWQuCisgICAgLy8gc28gZm9yIG5vdywgd2UganVzdCBsb29zZSBpdC4KKyAgICBtZW1zZXQoY3JvcF9yZWN0LCAwLCBzaXplb2YoY3JvcF9yZWN0KSk7CisKKyAgICAvLyBpdCB3b3VsZCBiZSBuaWNlIGlmIHdlIGNvdWxkIGtlZXAgdGhlIGdlbmVyYXRlX21pcG1hcCBmbGFnLAorICAgIC8vIHdlIHdvdWxkIGhhdmUgdG8gZ2VuZXJhdGUgdGhlbSByaWdodCBub3cgdGhvdWdoLgorICAgIGdlbmVyYXRlX21pcG1hcCA9IEdMX0ZBTFNFOworCisgICAgZGlyZWN0ID0gR0xfVFJVRTsKKyAgICBtU2l6ZSA9IDA7ICAvLyB3ZSBkb24ndCBvd24gdGhpcyBzdXJmYWNlCisgICAgaWYgKG1NaXBtYXBzKQorICAgICAgICBmcmVlTWlwbWFwcygpOworICAgIG1Jc0NvbXBsZXRlID0gdHJ1ZTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3N0YXR1c190IEVHTFRleHR1cmVPYmplY3Q6OnJlYWxsb2NhdGUoCisgICAgICAgIEdMaW50IGxldmVsLCBpbnQgdywgaW50IGgsIGludCBzLAorICAgICAgICBpbnQgZm9ybWF0LCBpbnQgY29tcHJlc3NlZEZvcm1hdCwgaW50IGJwcikKK3sKKyAgICBjb25zdCBzaXplX3Qgc2l6ZSA9IGggKiBicHI7CisgICAgaWYgKGxldmVsID09IDApIAorICAgIHsKKyAgICAgICAgaWYgKHNpemUhPW1TaXplIHx8ICFzdXJmYWNlLmRhdGEpIHsKKyAgICAgICAgICAgIGlmIChtU2l6ZSAmJiBzdXJmYWNlLmRhdGEpIHsKKyAgICAgICAgICAgICAgICBmcmVlKHN1cmZhY2UuZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdXJmYWNlLmRhdGEgPSAoR0dMdWJ5dGUqKW1hbGxvYyhzaXplKTsKKyAgICAgICAgICAgIGlmICghc3VyZmFjZS5kYXRhKSB7CisgICAgICAgICAgICAgICAgbVNpemUgPSAwOworICAgICAgICAgICAgICAgIG1Jc0NvbXBsZXRlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5PX01FTU9SWTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1TaXplID0gc2l6ZTsKKyAgICAgICAgfQorICAgICAgICBzdXJmYWNlLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgIHN1cmZhY2Uud2lkdGggID0gdzsKKyAgICAgICAgc3VyZmFjZS5oZWlnaHQgPSBoOworICAgICAgICBzdXJmYWNlLnN0cmlkZSA9IHM7CisgICAgICAgIHN1cmZhY2UuZm9ybWF0ID0gZm9ybWF0OworICAgICAgICBzdXJmYWNlLmNvbXByZXNzZWRGb3JtYXQgPSBjb21wcmVzc2VkRm9ybWF0OworICAgICAgICBpZiAobU1pcG1hcHMpCisgICAgICAgICAgICBmcmVlTWlwbWFwcygpOworICAgICAgICBtSXNDb21wbGV0ZSA9IHRydWU7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAgIGlmICghbU1pcG1hcHMpIHsKKyAgICAgICAgICAgIGlmIChhbGxvY2F0ZU1pcG1hcHMoKSAhPSBOT19FUlJPUikKKyAgICAgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICB9CisKKyAgICAgICAgTE9HV19JRihsZXZlbC0xID49IG1OdW1FeHRyYUxvZCwgCisgICAgICAgICAgICAgICAgInNwZWNpZnlpbmcgbWlwbWFwIGxldmVsICVkLCBidXQgIyBvZiBsZXZlbCBpcyAlZCIsCisgICAgICAgICAgICAgICAgbGV2ZWwsIG1OdW1FeHRyYUxvZCsxKTsgICAgICAgIAorCisgICAgICAgIEdHTFN1cmZhY2UmIG1pcG1hcCA9IGVkaXRNaXAobGV2ZWwpOworICAgICAgICBpZiAobWlwbWFwLmRhdGEpCisgICAgICAgICAgICBmcmVlKG1pcG1hcC5kYXRhKTsKKworICAgICAgICBtaXBtYXAuZGF0YSA9IChHR0x1Ynl0ZSopbWFsbG9jKHNpemUpOworICAgICAgICBpZiAoIW1pcG1hcC5kYXRhKSB7CisgICAgICAgICAgICBtZW1zZXQoJm1pcG1hcCwgMCwgc2l6ZW9mKEdHTFN1cmZhY2UpKTsKKyAgICAgICAgICAgIG1Jc0NvbXBsZXRlID0gZmFsc2U7CisgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICB9CisKKyAgICAgICAgbWlwbWFwLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgICAgIG1pcG1hcC53aWR0aCAgPSB3OworICAgICAgICBtaXBtYXAuaGVpZ2h0ID0gaDsKKyAgICAgICAgbWlwbWFwLnN0cmlkZSA9IHM7CisgICAgICAgIG1pcG1hcC5mb3JtYXQgPSBmb3JtYXQ7CisgICAgICAgIG1pcG1hcC5jb21wcmVzc2VkRm9ybWF0ID0gY29tcHJlc3NlZEZvcm1hdDsKKworICAgICAgICAvLyBjaGVjayBpZiB0aGUgdGV4dHVyZSBpcyBjb21wbGV0ZQorICAgICAgICBtSXNDb21wbGV0ZSA9IHRydWU7CisgICAgICAgIGNvbnN0IEdHTFN1cmZhY2UqIHByZXYgPSAmc3VyZmFjZTsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxtTnVtRXh0cmFMb2QgOyBpKyspIHsKKyAgICAgICAgICAgIGNvbnN0IEdHTFN1cmZhY2UqIGN1cnIgPSBtTWlwbWFwcyArIGk7CisgICAgICAgICAgICBpZiAoY3Vyci0+Zm9ybWF0ICE9IHN1cmZhY2UuZm9ybWF0KSB7CisgICAgICAgICAgICAgICAgbUlzQ29tcGxldGUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdWludDMyX3QgdyA9IChwcmV2LT53aWR0aCAgPj4gMSkgPyA6IDE7CisgICAgICAgICAgICB1aW50MzJfdCBoID0gKHByZXYtPmhlaWdodCA+PiAxKSA/IDogMTsKKyAgICAgICAgICAgIGlmICh3ICE9IGN1cnItPndpZHRoIHx8IGggIT0gY3Vyci0+aGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgbUlzQ29tcGxldGUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZXYgPSBjdXJyOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xTdXJmYWNlTWFuYWdlcjo6RUdMU3VyZmFjZU1hbmFnZXIoKQorICAgIDogVG9rZW5NYW5hZ2VyKCksIG1Db3VudCgwKQoreworfQorCitFR0xTdXJmYWNlTWFuYWdlcjo6fkVHTFN1cmZhY2VNYW5hZ2VyKCkKK3sKKyAgICAvLyBldmVyeXRoaW5nIGdldHMgZnJlZWQgYXV0b21hdGljYWxseSBoZXJlLi4uCit9CisKK3NwPEVHTFRleHR1cmVPYmplY3Q+IEVHTFN1cmZhY2VNYW5hZ2VyOjpjcmVhdGVUZXh0dXJlKEdMdWludCBuYW1lKQoreworICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+IHJlc3VsdDsKKworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgaWYgKG1UZXh0dXJlcy5pbmRleE9mS2V5KG5hbWUpID49IDApCisgICAgICAgIHJldHVybiByZXN1bHQ7IC8vIGFscmVhZHkgZXhpc3RzIQorCisgICAgcmVzdWx0ID0gbmV3IEVHTFRleHR1cmVPYmplY3QoKTsKKworICAgIHN0YXR1c190IGVyciA9IG1UZXh0dXJlcy5hZGQobmFtZSwgcmVzdWx0KTsKKyAgICBpZiAoZXJyIDwgMCkKKyAgICAgICAgcmVzdWx0LmNsZWFyKCk7CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzcDxFR0xUZXh0dXJlT2JqZWN0PiBFR0xTdXJmYWNlTWFuYWdlcjo6cmVtb3ZlVGV4dHVyZShHTHVpbnQgbmFtZSkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIGNvbnN0IHNzaXplX3QgaW5kZXggPSBtVGV4dHVyZXMuaW5kZXhPZktleShuYW1lKTsKKyAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICBzcDxFR0xUZXh0dXJlT2JqZWN0PiByZXN1bHQobVRleHR1cmVzLnZhbHVlQXQoaW5kZXgpKTsKKyAgICAgICAgbVRleHR1cmVzLnJlbW92ZUl0ZW1zQXQoaW5kZXgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3A8RUdMVGV4dHVyZU9iamVjdD4gRUdMU3VyZmFjZU1hbmFnZXI6OnJlcGxhY2VUZXh0dXJlKEdMdWludCBuYW1lKQoreworICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+IHRleDsKKyAgICBNdXRleDo6QXV0b2xvY2sgX2wobUxvY2spOworICAgIGNvbnN0IHNzaXplX3QgaW5kZXggPSBtVGV4dHVyZXMuaW5kZXhPZktleShuYW1lKTsKKyAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICBjb25zdCBzcDxFR0xUZXh0dXJlT2JqZWN0PiYgb2xkID0gbVRleHR1cmVzLnZhbHVlQXQoaW5kZXgpOworICAgICAgICBjb25zdCB1aW50MzJfdCByZWZzID0gb2xkLT5nZXRTdHJvbmdDb3VudCgpOworICAgICAgICBpZiAoZ2dsX2xpa2VseShyZWZzID09IDEpKSB7CisgICAgICAgICAgICAvLyB3ZSdyZSB0aGUgb25seSBvd25lcgorICAgICAgICAgICAgdGV4ID0gb2xkOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8ga2VlcCB0aGUgdGV4dHVyZSdzIHBhcmFtZXRlcnMKKyAgICAgICAgICAgIHRleCA9IG5ldyBFR0xUZXh0dXJlT2JqZWN0KCk7CisgICAgICAgICAgICB0ZXgtPmNvcHlQYXJhbWV0ZXJzKG9sZCk7CisgICAgICAgICAgICBtVGV4dHVyZXMucmVtb3ZlSXRlbXNBdChpbmRleCk7CisgICAgICAgICAgICBtVGV4dHVyZXMuYWRkKG5hbWUsIHRleCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRleDsKK30KKwordm9pZCBFR0xTdXJmYWNlTWFuYWdlcjo6ZGVsZXRlVGV4dHVyZXMoR0xzaXplaSBuLCBjb25zdCBHTHVpbnQgKnRva2VucykKK3sKKyAgICAvLyBmcmVlIGFsbCB0ZXh0dXJlcworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgZm9yIChHTHNpemVpIGk9MCA7IGk8biA7IGkrKykgeworICAgICAgICBjb25zdCBHTHVpbnQgdCgqdG9rZW5zKyspOworICAgICAgICBpZiAodCkgeworICAgICAgICAgICAgbVRleHR1cmVzLnJlbW92ZUl0ZW0odCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK3NwPEVHTFRleHR1cmVPYmplY3Q+IEVHTFN1cmZhY2VNYW5hZ2VyOjp0ZXh0dXJlKEdMdWludCBuYW1lKQoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgY29uc3Qgc3NpemVfdCBpbmRleCA9IG1UZXh0dXJlcy5pbmRleE9mS2V5KG5hbWUpOworICAgIGlmIChpbmRleCA+PSAwKQorICAgICAgICByZXR1cm4gbVRleHR1cmVzLnZhbHVlQXQoaW5kZXgpOworICAgIHJldHVybiAwOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZApkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9UZXh0dXJlT2JqZWN0TWFuYWdlci5oIGIvb3BlbmdsL2xpYmFnbC9UZXh0dXJlT2JqZWN0TWFuYWdlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0ZWQxYTQKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL1RleHR1cmVPYmplY3RNYW5hZ2VyLmgKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfT1BFTkdMRVNfU1VSRkFDRV9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfU1VSRkFDRV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL0F0b21pYy5oPgorI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKyNpbmNsdWRlIDx1dGlscy9SZWZCYXNlLmg+CisjaW5jbHVkZSA8dXRpbHMvS2V5ZWRWZWN0b3IuaD4KKyNpbmNsdWRlIDx1dGlscy9FcnJvcnMuaD4KKworI2luY2x1ZGUgPHByaXZhdGUvcGl4ZWxmbGluZ2VyL2dnbF9jb250ZXh0Lmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisKKyNpbmNsdWRlICJUb2tlbml6ZXIuaCIKKyNpbmNsdWRlICJUb2tlbk1hbmFnZXIuaCIKKworCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgRUdMVGV4dHVyZU9iamVjdAoreworcHVibGljOgorICAgICAgICAgICAgICAgICAgICBFR0xUZXh0dXJlT2JqZWN0KCk7CisgICAgICAgICAgICAgICAgICAgfkVHTFRleHR1cmVPYmplY3QoKTsKKworICAgIC8vIHByb3RvY29sIGZvciBzcDw+CisgICAgaW5saW5lICB2b2lkICAgICAgICBpbmNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0OworICAgIGlubGluZSAgdm9pZCAgICAgICAgZGVjU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKyAgICBpbmxpbmUgIHVpbnQzMl90ICAgIGdldFN0cm9uZ0NvdW50KCkgY29uc3Q7CisKKyAgICBzdGF0dXNfdCAgICAgICAgICAgIHNldFN1cmZhY2UoR0dMU3VyZmFjZSBjb25zdCogcyk7CisgICAgc3RhdHVzX3QgICAgICAgICAgICByZWFsbG9jYXRlKEdMaW50IGxldmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB3LCBpbnQgaCwgaW50IHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcm1hdCwgaW50IGNvbXByZXNzZWRGb3JtYXQsIGludCBicHIpOworICAgIGlubGluZSAgc2l6ZV90ICAgICAgc2l6ZSgpIGNvbnN0OworICAgIGNvbnN0IEdHTFN1cmZhY2UmICAgbWlwKGludCBsb2QpIGNvbnN0OworICAgIEdHTFN1cmZhY2UmICAgICAgICAgZWRpdE1pcChpbnQgbG9kKTsKKyAgICBib29sICAgICAgICAgICAgICAgIGhhc01pcG1hcHMoKSBjb25zdCB7IHJldHVybiBtTWlwbWFwcyE9MDsgfQorICAgIGJvb2wgICAgICAgICAgICAgICAgaXNDb21wbGV0ZSgpIGNvbnN0IHsgcmV0dXJuIG1Jc0NvbXBsZXRlOyB9CisgICAgdm9pZCAgICAgICAgICAgICAgICBjb3B5UGFyYW1ldGVycyhjb25zdCBzcDxFR0xUZXh0dXJlT2JqZWN0PiYgb2xkKTsKKworcHJpdmF0ZToKKyAgICAgICAgc3RhdHVzX3QgICAgICAgIGFsbG9jYXRlTWlwbWFwcygpOworICAgICAgICAgICAgdm9pZCAgICAgICAgZnJlZU1pcG1hcHMoKTsKKyAgICAgICAgICAgIHZvaWQgICAgICAgIGluaXQoKTsKKyAgICBtdXRhYmxlIGludDMyX3QgICAgIG1Db3VudDsKKyAgICBzaXplX3QgICAgICAgICAgICAgIG1TaXplOworICAgIEdHTFN1cmZhY2UgICAgICAgICAgKm1NaXBtYXBzOworICAgIGludCAgICAgICAgICAgICAgICAgbU51bUV4dHJhTG9kOworICAgIGJvb2wgICAgICAgICAgICAgICAgbUlzQ29tcGxldGU7CisKK3B1YmxpYzoKKyAgICBHR0xTdXJmYWNlICAgICAgICAgIHN1cmZhY2U7CisgICAgR0xlbnVtICAgICAgICAgICAgICB3cmFwczsKKyAgICBHTGVudW0gICAgICAgICAgICAgIHdyYXB0OworICAgIEdMZW51bSAgICAgICAgICAgICAgbWluX2ZpbHRlcjsKKyAgICBHTGVudW0gICAgICAgICAgICAgIG1hZ19maWx0ZXI7CisgICAgR0xlbnVtICAgICAgICAgICAgICBpbnRlcm5hbGZvcm1hdDsKKyAgICBHTGludCAgICAgICAgICAgICAgIGNyb3BfcmVjdFs0XTsKKyAgICBHTGludCAgICAgICAgICAgICAgIGdlbmVyYXRlX21pcG1hcDsKKyAgICBHTGludCAgICAgICAgICAgICAgIGRpcmVjdDsKK307CisKK3ZvaWQgRUdMVGV4dHVyZU9iamVjdDo6aW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdCB7CisgICAgYW5kcm9pZF9hdG9taWNfaW5jKCZtQ291bnQpOworfQordm9pZCBFR0xUZXh0dXJlT2JqZWN0OjpkZWNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0IHsKKyAgICBpZiAoYW5kcm9pZF9hdG9taWNfZGVjKCZtQ291bnQpID09IDEpIHsKKyAgICAgICAgZGVsZXRlIHRoaXM7CisgICAgfQorfQordWludDMyX3QgRUdMVGV4dHVyZU9iamVjdDo6Z2V0U3Ryb25nQ291bnQoKSBjb25zdCB7CisgICAgcmV0dXJuIG1Db3VudDsKK30KK3NpemVfdCBFR0xUZXh0dXJlT2JqZWN0OjpzaXplKCkgY29uc3QgeworICAgIHJldHVybiBtU2l6ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBFR0xTdXJmYWNlTWFuYWdlciA6IHB1YmxpYyBUb2tlbk1hbmFnZXIKK3sKK3B1YmxpYzoKKyAgICAgICAgICAgICAgICBFR0xTdXJmYWNlTWFuYWdlcigpOworICAgICAgICAgICAgICAgIH5FR0xTdXJmYWNlTWFuYWdlcigpOworCisgICAgLy8gcHJvdG9jb2wgZm9yIHNwPD4KKyAgICBpbmxpbmUgIHZvaWQgICAgaW5jU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKyAgICBpbmxpbmUgIHZvaWQgICAgZGVjU3Ryb25nKGNvbnN0IHZvaWQqIGlkKSBjb25zdDsKKyAgICB0eXBlZGVmIHZvaWQgICAgd2Vha3JlZl90eXBlOworCisgICAgc3A8RUdMVGV4dHVyZU9iamVjdD4gICAgY3JlYXRlVGV4dHVyZShHTHVpbnQgbmFtZSk7CisgICAgc3A8RUdMVGV4dHVyZU9iamVjdD4gICAgcmVtb3ZlVGV4dHVyZShHTHVpbnQgbmFtZSk7CisgICAgc3A8RUdMVGV4dHVyZU9iamVjdD4gICAgcmVwbGFjZVRleHR1cmUoR0x1aW50IG5hbWUpOworICAgIHZvaWQgICAgICAgICAgICAgICAgICAgIGRlbGV0ZVRleHR1cmVzKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICp0b2tlbnMpOworICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+ICAgIHRleHR1cmUoR0x1aW50IG5hbWUpOworCitwcml2YXRlOgorICAgIG11dGFibGUgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUNvdW50OworICAgIG11dGFibGUgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbUxvY2s7CisgICAgS2V5ZWRWZWN0b3I8IEdMdWludCwgc3A8RUdMVGV4dHVyZU9iamVjdD4gPiBtVGV4dHVyZXM7Cit9OworCit2b2lkIEVHTFN1cmZhY2VNYW5hZ2VyOjppbmNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0IHsKKyAgICBhbmRyb2lkX2F0b21pY19pbmMoJm1Db3VudCk7Cit9Cit2b2lkIEVHTFN1cmZhY2VNYW5hZ2VyOjpkZWNTdHJvbmcoY29uc3Qgdm9pZCogaWQpIGNvbnN0IHsKKyAgICBpZiAoYW5kcm9pZF9hdG9taWNfZGVjKCZtQ291bnQpID09IDEpIHsKKyAgICAgICAgZGVsZXRlIHRoaXM7CisgICAgfQorfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09QRU5HTEVTX1NVUkZBQ0VfSAorCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL1Rva2VuTWFuYWdlci5jcHAgYi9vcGVuZ2wvbGliYWdsL1Rva2VuTWFuYWdlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWVhNjAyNQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvVG9rZW5NYW5hZ2VyLmNwcApAQCAtMCwwICsxLDYyIEBACisvKiBsaWJzL29wZW5nbGVzL3N1cmZhY2UuY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSAiVG9rZW5NYW5hZ2VyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVG9rZW5NYW5hZ2VyOjpUb2tlbk1hbmFnZXIoKQoreworICAgIC8vIHRva2VuIDAgaXMgYWx3YXlzIHJlc2VydmVkCisgICAgbVRva2VuaXplci5yZXNlcnZlKDApOworfQorCitUb2tlbk1hbmFnZXI6On5Ub2tlbk1hbmFnZXIoKQoreworfQorCitzdGF0dXNfdCBUb2tlbk1hbmFnZXI6OmdldFRva2VuKEdMc2l6ZWkgbiwgR0x1aW50ICp0b2tlbnMpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBmb3IgKEdMc2l6ZWkgaT0wIDsgaTxuIDsgaSsrKQorICAgICAgICAqdG9rZW5zKysgPSBtVG9rZW5pemVyLmFjcXVpcmUoKTsKKyAgICByZXR1cm4gTk9fRVJST1I7Cit9CisKK3ZvaWQgVG9rZW5NYW5hZ2VyOjpyZWN5Y2xlVG9rZW5zKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICp0b2tlbnMpCit7CisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKG1Mb2NrKTsKKyAgICBmb3IgKGludCBpPTAgOyBpPG4gOyBpKyspIHsKKyAgICAgICAgY29uc3QgR0x1aW50IHRva2VuID0gKnRva2VucysrOworICAgICAgICBpZiAodG9rZW4pIHsKKyAgICAgICAgICAgIG1Ub2tlbml6ZXIucmVsZWFzZSh0b2tlbik7CisgICAgICAgIH0KKyAgICB9Cit9CisKK2Jvb2wgVG9rZW5NYW5hZ2VyOjppc1Rva2VuVmFsaWQoR0x1aW50IHRva2VuKSBjb25zdAoreworICAgIE11dGV4OjpBdXRvbG9jayBfbChtTG9jayk7CisgICAgcmV0dXJuIG1Ub2tlbml6ZXIuaXNBY3F1aXJlZCh0b2tlbik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvVG9rZW5NYW5hZ2VyLmggYi9vcGVuZ2wvbGliYWdsL1Rva2VuTWFuYWdlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5YzE0NjkKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL1Rva2VuTWFuYWdlci5oCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfT1BFTkdMRVNfVE9LRU5fTUFOQUdFUl9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfVE9LRU5fTUFOQUdFUl9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2luY2x1ZGUgIlRva2VuaXplci5oIgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgVG9rZW5NYW5hZ2VyCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgVG9rZW5NYW5hZ2VyKCk7CisgICAgICAgICAgICAgICAgflRva2VuTWFuYWdlcigpOworCisgICAgc3RhdHVzX3QgICAgZ2V0VG9rZW4oR0xzaXplaSBuLCBHTHVpbnQgKnRva2Vucyk7CisgICAgdm9pZCAgICAgICAgcmVjeWNsZVRva2VucyhHTHNpemVpIG4sIGNvbnN0IEdMdWludCAqdG9rZW5zKTsKKyAgICBib29sICAgICAgICBpc1Rva2VuVmFsaWQoR0x1aW50IHRva2VuKSBjb25zdDsKKworcHJpdmF0ZToKKyAgICBtdXRhYmxlIE11dGV4ICAgbUxvY2s7CisgICAgVG9rZW5pemVyICAgICAgIG1Ub2tlbml6ZXI7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9PUEVOR0xFU19UT0tFTl9NQU5BR0VSX0gKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9Ub2tlbml6ZXIuY3BwIGIvb3BlbmdsL2xpYmFnbC9Ub2tlbml6ZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliM2VhMWEKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL1Rva2VuaXplci5jcHAKQEAgLTAsMCArMSwxNzMgQEAKKy8qIGxpYnMvb3BlbmdsZXMvVG9rZW5pemVyLmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorCisjaW5jbHVkZSAiVG9rZW5pemVyLmgiCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitBTkRST0lEX0JBU0lDX1RZUEVTX1RSQUlUUyhUb2tlbml6ZXI6OnJ1bl90KQorCitUb2tlbml6ZXI6OlRva2VuaXplcigpCit7Cit9CisKK1Rva2VuaXplcjo6VG9rZW5pemVyKGNvbnN0IFRva2VuaXplciYgb3RoZXIpCisgICAgOiBtUmFuZ2VzKG90aGVyLm1SYW5nZXMpCit7Cit9CisKK1Rva2VuaXplcjo6flRva2VuaXplcigpCit7Cit9CisKK3VpbnQzMl90IFRva2VuaXplcjo6YWNxdWlyZSgpCit7CisgICAgaWYgKCFtUmFuZ2VzLnNpemUoKSB8fCBtUmFuZ2VzWzBdLmZpcnN0KSB7CisgICAgICAgIF9pbnNlcnRUb2tlbkF0KDAsMCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICAKKyAgICAvLyBqdXN0IGV4dGVuZCB0aGUgZmlyc3QgcnVuCisgICAgY29uc3QgcnVuX3QmIHJ1biA9IG1SYW5nZXNbMF07CisgICAgdWludDMyX3QgdG9rZW4gPSBydW4uZmlyc3QgKyBydW4ubGVuZ3RoOworICAgIF9pbnNlcnRUb2tlbkF0KHRva2VuLCAxKTsKKyAgICByZXR1cm4gdG9rZW47Cit9CisKK2Jvb2wgVG9rZW5pemVyOjppc0FjcXVpcmVkKHVpbnQzMl90IHRva2VuKSBjb25zdAoreworICAgIHJldHVybiAoX2luZGV4T3JkZXJPZih0b2tlbikgPj0gMCk7Cit9CisKK3N0YXR1c190IFRva2VuaXplcjo6cmVzZXJ2ZSh1aW50MzJfdCB0b2tlbikKK3sKKyAgICBzaXplX3QgbzsKKyAgICBjb25zdCBzc2l6ZV90IGkgPSBfaW5kZXhPcmRlck9mKHRva2VuLCAmbyk7CisgICAgaWYgKGkgPj0gMCkgeworICAgICAgICByZXR1cm4gQkFEX1ZBTFVFOyAvLyB0aGlzIHRva2VuIGlzIGFscmVhZHkgdGFrZW4KKyAgICB9CisgICAgc3NpemVfdCBlcnIgPSBfaW5zZXJ0VG9rZW5BdCh0b2tlbiwgbyk7CisgICAgcmV0dXJuIChlcnI8MCkgPyBlcnIgOiBzdGF0dXNfdChOT19FUlJPUik7Cit9CisKK3N0YXR1c190IFRva2VuaXplcjo6cmVsZWFzZSh1aW50MzJfdCB0b2tlbikKK3sKKyAgICBjb25zdCBzc2l6ZV90IGkgPSBfaW5kZXhPcmRlck9mKHRva2VuKTsKKyAgICBpZiAoaSA+PSAwKSB7CisgICAgICAgIGNvbnN0IHJ1bl90JiBydW4gPSBtUmFuZ2VzW2ldOworICAgICAgICBpZiAoKHRva2VuID49IHJ1bi5maXJzdCkgJiYgKHRva2VuIDwgcnVuLmZpcnN0K3J1bi5sZW5ndGgpKSB7CisgICAgICAgICAgICAvLyB0b2tlbiBpbiB0aGlzIHJhbmdlLCB3ZSBuZWVkIHRvIHNwbGl0CisgICAgICAgICAgICBydW5fdCYgcnVuID0gbVJhbmdlcy5lZGl0SXRlbUF0KGkpOworICAgICAgICAgICAgaWYgKCh0b2tlbiA9PSBydW4uZmlyc3QpIHx8ICh0b2tlbiA9PSBydW4uZmlyc3QrcnVuLmxlbmd0aC0xKSkgeworICAgICAgICAgICAgICAgIGlmICh0b2tlbiA9PSBydW4uZmlyc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgcnVuLmZpcnN0ICs9IDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJ1bi5sZW5ndGggLT0gMTsKKyAgICAgICAgICAgICAgICBpZiAocnVuLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFhYWDogc2hvdWxkIHdlIHN5c3RlbWF0aWNhbGx5IHJlbW92ZSBhIHJ1biB0aGF0J3MgZW1wdHk/CisgICAgICAgICAgICAgICAgICAgIG1SYW5nZXMucmVtb3ZlSXRlbXNBdChpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIHNwbGl0IHRoZSBydW4KKyAgICAgICAgICAgICAgICBydW5fdCBuZXdfcnVuOworICAgICAgICAgICAgICAgIG5ld19ydW4uZmlyc3QgPSB0b2tlbisxOworICAgICAgICAgICAgICAgIG5ld19ydW4ubGVuZ3RoID0gcnVuLmZpcnN0K3J1bi5sZW5ndGggLSBuZXdfcnVuLmZpcnN0OworICAgICAgICAgICAgICAgIHJ1bi5sZW5ndGggPSB0b2tlbiAtIHJ1bi5maXJzdDsKKyAgICAgICAgICAgICAgICBtUmFuZ2VzLmluc2VydEF0KG5ld19ydW4sIGkrMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gTk9fRVJST1I7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5BTUVfTk9UX0ZPVU5EOworfQorCitzc2l6ZV90IFRva2VuaXplcjo6X2luZGV4T3JkZXJPZih1aW50MzJfdCB0b2tlbiwgc2l6ZV90KiBvcmRlcikgY29uc3QKK3sKKyAgICAvLyBiaW5hcnkgc2VhcmNoCisgICAgc3NpemVfdCBlcnIgPSBOQU1FX05PVF9GT1VORDsKKyAgICBzc2l6ZV90IGwgPSAwOworICAgIHNzaXplX3QgaCA9IG1SYW5nZXMuc2l6ZSgpLTE7CisgICAgc3NpemVfdCBtaWQ7CisgICAgY29uc3QgcnVuX3QqIGEgPSBtUmFuZ2VzLmFycmF5KCk7CisgICAgd2hpbGUgKGwgPD0gaCkgeworICAgICAgICBtaWQgPSBsICsgKGggLSBsKS8yOworICAgICAgICBjb25zdCBydW5fdCogY29uc3QgY3VyciA9IGEgKyBtaWQ7CisgICAgICAgIGludCBjID0gMDsKKyAgICAgICAgaWYgKHRva2VuIDwgY3Vyci0+Zmlyc3QpICAgICAgICAgICAgICAgICAgICAgICAgYyA9IDE7CisgICAgICAgIGVsc2UgaWYgKHRva2VuID49IGN1cnItPmZpcnN0K2N1cnItPmxlbmd0aCkgICAgIGMgPSAtMTsKKyAgICAgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAgICAgZXJyID0gbCA9IG1pZDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9IGVsc2UgaWYgKGMgPCAwKSB7CisgICAgICAgICAgICBsID0gbWlkICsgMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGggPSBtaWQgLSAxOworICAgICAgICB9CisgICAgfQorICAgIGlmIChvcmRlcikgKm9yZGVyID0gbDsKKyAgICByZXR1cm4gZXJyOworfQorCitzc2l6ZV90IFRva2VuaXplcjo6X2luc2VydFRva2VuQXQodWludDMyX3QgdG9rZW4sIHNpemVfdCBpbmRleCkKK3sKKyAgICBjb25zdCBzaXplX3QgYyA9IG1SYW5nZXMuc2l6ZSgpOworCisgICAgaWYgKGluZGV4ID49IDEpIHsKKyAgICAgICAgLy8gZG8gd2UgbmVlZCB0byBtZXJnZSB3aXRoIHRoZSBwcmV2aW91cyBydW4/CisgICAgICAgIHJ1bl90JiBwID0gbVJhbmdlcy5lZGl0SXRlbUF0KGluZGV4LTEpOworICAgICAgICBpZiAocC5maXJzdCtwLmxlbmd0aCA9PSB0b2tlbikgeworICAgICAgICAgICAgcC5sZW5ndGggKz0gMTsKKyAgICAgICAgICAgIGlmIChpbmRleCA8IGMpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBydW5fdCYgbiA9IG1SYW5nZXNbaW5kZXhdOworICAgICAgICAgICAgICAgIGlmICh0b2tlbisxID09IG4uZmlyc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgcC5sZW5ndGggKz0gbi5sZW5ndGg7CisgICAgICAgICAgICAgICAgICAgIG1SYW5nZXMucmVtb3ZlSXRlbXNBdChpbmRleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisgICAgfQorICAgIAorICAgIGlmIChpbmRleCA8IGMpIHsKKyAgICAgICAgLy8gZG8gd2UgbmVlZCB0byBtZXJnZSB3aXRoIHRoZSBuZXh0IHJ1bj8KKyAgICAgICAgcnVuX3QmIG4gPSBtUmFuZ2VzLmVkaXRJdGVtQXQoaW5kZXgpOworICAgICAgICBpZiAodG9rZW4rMSA9PSBuLmZpcnN0KSB7CisgICAgICAgICAgICBuLmZpcnN0IC09IDE7CisgICAgICAgICAgICBuLmxlbmd0aCArPSAxOworICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIG1SYW5nZXMuaW5zZXJ0QXQocnVuX3QodG9rZW4sMSksIGluZGV4KTsKK30KKwordm9pZCBUb2tlbml6ZXI6OmR1bXAoKSBjb25zdAoreworICAgIGNvbnN0IHJ1bl90KiByYW5nZXMgPSBtUmFuZ2VzLmFycmF5KCk7CisgICAgY29uc3Qgc2l6ZV90IGMgPSBtUmFuZ2VzLnNpemUoKTsKKyAgICBMT0dEKCJUb2tlbml6ZXIgKCVwLCBzaXplID0gJXUpXG4iLCB0aGlzLCBjKTsKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGMgOyBpKyspIHsKKyAgICAgICAgTE9HRCgiJXU6ICgldSwgJXUpXG4iLCBpLCByYW5nZXNbaV0uZmlyc3QsIHJhbmdlc1tpXS5sZW5ndGgpOworICAgIH0KK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9Ub2tlbml6ZXIuaCBiL29wZW5nbC9saWJhZ2wvVG9rZW5pemVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWM1NTVjYgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvVG9rZW5pemVyLmgKQEAgLTAsMCArMSw1OSBAQAorLyogbGlicy9vcGVuZ2xlcy9Ub2tlbml6ZXIuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKworI2lmbmRlZiBBTkRST0lEX09QRU5HTEVTX1RPS0VOSVpFUl9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfVE9LRU5JWkVSX0gKKworI2luY2x1ZGUgPHV0aWxzL1ZlY3Rvci5oPgorI2luY2x1ZGUgPHV0aWxzL0Vycm9ycy5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworY2xhc3MgVG9rZW5pemVyCit7CitwdWJsaWM6CisgICAgICAgICAgICAgICAgVG9rZW5pemVyKCk7CisgICAgICAgICAgICAgICAgVG9rZW5pemVyKGNvbnN0IFRva2VuaXplciYgb3RoZXIpOworICAgICAgICAgICAgICAgIH5Ub2tlbml6ZXIoKTsKKworICAgIHVpbnQzMl90ICAgIGFjcXVpcmUoKTsKKyAgICBzdGF0dXNfdCAgICByZXNlcnZlKHVpbnQzMl90IHRva2VuKTsKKyAgICBzdGF0dXNfdCAgICByZWxlYXNlKHVpbnQzMl90IHRva2VuKTsKKyAgICBib29sICAgICAgICBpc0FjcXVpcmVkKHVpbnQzMl90IHRva2VuKSBjb25zdDsKKworICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgc3RydWN0IHJ1bl90IHsKKyAgICAgICAgcnVuX3QoKSB7fTsKKyAgICAgICAgcnVuX3QodWludDMyX3QgZiwgdWludDMyX3QgbCkgOiBmaXJzdChmKSwgbGVuZ3RoKGwpIHt9CisgICAgICAgIHVpbnQzMl90ICAgIGZpcnN0OworICAgICAgICB1aW50MzJfdCAgICBsZW5ndGg7CisgICAgfTsKK3ByaXZhdGU6CisgICAgc3NpemVfdCBfaW5kZXhPcmRlck9mKHVpbnQzMl90IHRva2VuLCBzaXplX3QqIG9yZGVyPTApIGNvbnN0OworICAgIHNzaXplX3QgX2luc2VydFRva2VuQXQodWludDMyX3QgdG9rZW4sIHNpemVfdCBpbmRleCk7CisgICAgVmVjdG9yPHJ1bl90PiAgIG1SYW5nZXM7Cit9OworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvLyBBTkRST0lEX09QRU5HTEVTX1RPS0VOSVpFUl9ICmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL2FycmF5LmNwcCBiL29wZW5nbC9saWJhZ2wvYXJyYXkuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmYTc1NjYKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL2FycmF5LmNwcApAQCAtMCwwICsxLDE1NTcgQEAKKy8qIAorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpbmNsdWRlICJjb250ZXh0LmgiCisjaW5jbHVkZSAiZnAuaCIKKyNpbmNsdWRlICJzdGF0ZS5oIgorI2luY2x1ZGUgIm1hdHJpeC5oIgorI2luY2x1ZGUgInZlcnRleC5oIgorI2luY2x1ZGUgImxpZ2h0LmgiCisjaW5jbHVkZSAicHJpbWl0aXZlcy5oIgorI2luY2x1ZGUgInRleHR1cmUuaCIKKyNpbmNsdWRlICJCdWZmZXJPYmplY3RNYW5hZ2VyLmgiCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBWQ19DQUNIRV9TVEFUSVNUSUNTICAgICAwCisjZGVmaW5lIFZDX0NBQ0hFX1RZUEVfTk9ORSAgICAgIDAKKyNkZWZpbmUgVkNfQ0FDSEVfVFlQRV9JTkRFWEVEICAgMQorI2RlZmluZSBWQ19DQUNIRV9UWVBFX0xSVSAgICAgICAyCisjZGVmaW5lIFZDX0NBQ0hFX1RZUEUgICAgICAgICAgIFZDX0NBQ0hFX1RZUEVfSU5ERVhFRAorCisjaWYgVkNfQ0FDSEVfU1RBVElTVElDUworI2luY2x1ZGUgPHV0aWxzL1RpbWVycy5oPgorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitzdGF0aWMgdm9pZCB2YWxpZGF0ZV9hcnJheXMob2dsZXNfY29udGV4dF90KiBjLCBHTGVudW0gbW9kZSk7CisKK3N0YXRpYyB2b2lkIGNvbXBpbGVFbGVtZW50c19fZ2VuZXJpYyhvZ2xlc19jb250ZXh0X3QqLAorICAgICAgICB2ZXJ0ZXhfdCosIEdMaW50LCBHTHNpemVpKTsKK3N0YXRpYyB2b2lkIGNvbXBpbGVFbGVtZW50X19nZW5lcmljKG9nbGVzX2NvbnRleHRfdCosCisgICAgICAgIHZlcnRleF90KiwgR0xpbnQpOworCitzdGF0aWMgdm9pZCBkcmF3UHJpbWl0aXZlc1BvaW50cyhvZ2xlc19jb250ZXh0X3QqLCBHTGludCwgR0xzaXplaSk7CitzdGF0aWMgdm9pZCBkcmF3UHJpbWl0aXZlc0xpbmVTdHJpcChvZ2xlc19jb250ZXh0X3QqLCBHTGludCwgR0xzaXplaSk7CitzdGF0aWMgdm9pZCBkcmF3UHJpbWl0aXZlc0xpbmVMb29wKG9nbGVzX2NvbnRleHRfdCosIEdMaW50LCBHTHNpemVpKTsKK3N0YXRpYyB2b2lkIGRyYXdQcmltaXRpdmVzTGluZXMob2dsZXNfY29udGV4dF90KiwgR0xpbnQsIEdMc2l6ZWkpOworc3RhdGljIHZvaWQgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZVN0cmlwKG9nbGVzX2NvbnRleHRfdCosIEdMaW50LCBHTHNpemVpKTsKK3N0YXRpYyB2b2lkIGRyYXdQcmltaXRpdmVzVHJpYW5nbGVGYW4ob2dsZXNfY29udGV4dF90KiwgR0xpbnQsIEdMc2l6ZWkpOworc3RhdGljIHZvaWQgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZXMob2dsZXNfY29udGV4dF90KiwgR0xpbnQsIEdMc2l6ZWkpOworCitzdGF0aWMgdm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNQb2ludHMob2dsZXNfY29udGV4dF90KiwKKyAgICAgICAgR0xzaXplaSwgY29uc3QgR0x2b2lkKik7CitzdGF0aWMgdm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lU3RyaXAob2dsZXNfY29udGV4dF90KiwKKyAgICAgICAgR0xzaXplaSwgY29uc3QgR0x2b2lkKik7CitzdGF0aWMgdm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lTG9vcChvZ2xlc19jb250ZXh0X3QqLAorICAgICAgICBHTHNpemVpLCBjb25zdCBHTHZvaWQqKTsKK3N0YXRpYyB2b2lkIGRyYXdJbmRleGVkUHJpbWl0aXZlc0xpbmVzKG9nbGVzX2NvbnRleHRfdCosCisgICAgICAgIEdMc2l6ZWksIGNvbnN0IEdMdm9pZCopOworc3RhdGljIHZvaWQgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVTdHJpcChvZ2xlc19jb250ZXh0X3QqLAorICAgICAgICBHTHNpemVpLCBjb25zdCBHTHZvaWQqKTsKK3N0YXRpYyB2b2lkIGRyYXdJbmRleGVkUHJpbWl0aXZlc1RyaWFuZ2xlRmFuKG9nbGVzX2NvbnRleHRfdCosCisgICAgICAgIEdMc2l6ZWksIGNvbnN0IEdMdm9pZCopOworc3RhdGljIHZvaWQgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVzKG9nbGVzX2NvbnRleHRfdCosCisgICAgICAgIEdMc2l6ZWksIGNvbnN0IEdMdm9pZCopOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3R5cGVkZWYgdm9pZCAoKmFycmF5c19wcmltc19mY3RfdCkob2dsZXNfY29udGV4dF90KiwgR0xpbnQsIEdMc2l6ZWkpOworc3RhdGljIGNvbnN0IGFycmF5c19wcmltc19mY3RfdCBkcmF3QXJyYXlzUHJpbXNbXSA9IHsKKyAgICBkcmF3UHJpbWl0aXZlc1BvaW50cywKKyAgICBkcmF3UHJpbWl0aXZlc0xpbmVzLAorICAgIGRyYXdQcmltaXRpdmVzTGluZUxvb3AsCisgICAgZHJhd1ByaW1pdGl2ZXNMaW5lU3RyaXAsCisgICAgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZXMsCisgICAgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZVN0cmlwLAorICAgIGRyYXdQcmltaXRpdmVzVHJpYW5nbGVGYW4KK307CisKK3R5cGVkZWYgdm9pZCAoKmVsZW1lbnRzX3ByaW1zX2ZjdF90KShvZ2xlc19jb250ZXh0X3QqLCBHTHNpemVpLCBjb25zdCBHTHZvaWQqKTsKK3N0YXRpYyBjb25zdCBlbGVtZW50c19wcmltc19mY3RfdCBkcmF3RWxlbWVudHNQcmltc1tdID0geworICAgIGRyYXdJbmRleGVkUHJpbWl0aXZlc1BvaW50cywKKyAgICBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lcywKKyAgICBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lTG9vcCwKKyAgICBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lU3RyaXAsCisgICAgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVzLAorICAgIGRyYXdJbmRleGVkUHJpbWl0aXZlc1RyaWFuZ2xlU3RyaXAsCisgICAgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVGYW4KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK3ZvaWQgb2dsZXNfaW5pdF9hcnJheShvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgYy0+YXJyYXlzLnZlcnRleC5zaXplID0gNDsKKyAgICBjLT5hcnJheXMudmVydGV4LnR5cGUgPSBHTF9GTE9BVDsKKyAgICBjLT5hcnJheXMuY29sb3Iuc2l6ZSA9IDQ7CisgICAgYy0+YXJyYXlzLmNvbG9yLnR5cGUgPSBHTF9GTE9BVDsKKyAgICBjLT5hcnJheXMubm9ybWFsLnNpemUgPSA0OworICAgIGMtPmFycmF5cy5ub3JtYWwudHlwZSA9IEdMX0ZMT0FUOworICAgIGZvciAoaW50IGk9MCA7IGk8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IGkrKykgeworICAgICAgICBjLT5hcnJheXMudGV4dHVyZVtpXS5zaXplID0gNDsKKyAgICAgICAgYy0+YXJyYXlzLnRleHR1cmVbaV0udHlwZSA9IEdMX0ZMT0FUOworICAgIH0KKyAgICBjLT52Yy5pbml0KCk7CisKKyAgICBpZiAoIWMtPnZjLnZCdWZmZXIpIHsKKyAgICAgICAgLy8gdGhpcyBjb3VsZCBoYXZlIGZhaWxlZAorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9PVVRfT0ZfTUVNT1JZKTsKKyAgICB9Cit9CisKK3ZvaWQgb2dsZXNfdW5pbml0X2FycmF5KG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBjLT52Yy51bmluaXQoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgQXJyYXkgZmV0Y2hlcnMKKyNlbmRpZgorCitzdGF0aWMgdm9pZCBjdXJyZW50Q29sb3Iob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkKiB2LCBjb25zdCBHTHZvaWQqKSB7CisgICAgbWVtY3B5KHYsIGMtPmN1cnJlbnQuY29sb3Iudiwgc2l6ZW9mKHZlYzRfdCkpOworfQorc3RhdGljIHZvaWQgY3VycmVudENvbG9yX2NsYW1wKG9nbGVzX2NvbnRleHRfdCogYywgR0xmaXhlZCogdiwgY29uc3QgR0x2b2lkKikgeworICAgIG1lbWNweSh2LCBjLT5jdXJyZW50Q29sb3JDbGFtcGVkLnYsIHNpemVvZih2ZWM0X3QpKTsKK30KK3N0YXRpYyB2b2lkIGN1cnJlbnROb3JtYWwob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkKiB2LCBjb25zdCBHTHZvaWQqKSB7CisgICAgbWVtY3B5KHYsIGMtPmN1cnJlbnROb3JtYWwudiwgc2l6ZW9mKHZlYzNfdCkpOworfQorc3RhdGljIHZvaWQgY3VycmVudFRleENvb3JkKG9nbGVzX2NvbnRleHRfdCogYywgR0xmaXhlZCogdiwgY29uc3QgR0x2b2lkKikgeworICAgIG1lbWNweSh2LCBjLT5jdXJyZW50LnRleHR1cmVbYy0+YXJyYXlzLnRtdV0udiwgc2l6ZW9mKHZlYzRfdCkpOworfQorCisKK3N0YXRpYyB2b2lkIGZldGNoTm9wKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqLCBjb25zdCBHTHZvaWQqKSB7Cit9CitzdGF0aWMgdm9pZCBmZXRjaDJiKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMYnl0ZSogcCkgeworICAgIHZbMF0gPSBnZ2xJbnRUb0ZpeGVkKHBbMF0pOworICAgIHZbMV0gPSBnZ2xJbnRUb0ZpeGVkKHBbMV0pOworfQorc3RhdGljIHZvaWQgZmV0Y2gycyhvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTHNob3J0KiBwKSB7CisgICAgdlswXSA9IGdnbEludFRvRml4ZWQocFswXSk7CisgICAgdlsxXSA9IGdnbEludFRvRml4ZWQocFsxXSk7Cit9CitzdGF0aWMgdm9pZCBmZXRjaDJ4KG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMZml4ZWQqIHApIHsKKyAgICBtZW1jcHkodiwgcCwgMipzaXplb2YoR0xmaXhlZCkpOworfQorc3RhdGljIHZvaWQgZmV0Y2gyZihvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTGZsb2F0KiBwKSB7CisgICAgdlswXSA9IGdnbEZsb2F0VG9GaXhlZChwWzBdKTsKKyAgICB2WzFdID0gZ2dsRmxvYXRUb0ZpeGVkKHBbMV0pOworfQorc3RhdGljIHZvaWQgZmV0Y2gzYihvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTGJ5dGUqIHApIHsKKyAgICB2WzBdID0gZ2dsSW50VG9GaXhlZChwWzBdKTsKKyAgICB2WzFdID0gZ2dsSW50VG9GaXhlZChwWzFdKTsKKyAgICB2WzJdID0gZ2dsSW50VG9GaXhlZChwWzJdKTsKK30KK3N0YXRpYyB2b2lkIGZldGNoM3Mob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xzaG9ydCogcCkgeworICAgIHZbMF0gPSBnZ2xJbnRUb0ZpeGVkKHBbMF0pOworICAgIHZbMV0gPSBnZ2xJbnRUb0ZpeGVkKHBbMV0pOworICAgIHZbMl0gPSBnZ2xJbnRUb0ZpeGVkKHBbMl0pOworfQorc3RhdGljIHZvaWQgZmV0Y2gzeChvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTGZpeGVkKiBwKSB7CisgICAgbWVtY3B5KHYsIHAsIDMqc2l6ZW9mKEdMZml4ZWQpKTsKK30KK3N0YXRpYyB2b2lkIGZldGNoM2Yob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xmbG9hdCogcCkgeworICAgIHZbMF0gPSBnZ2xGbG9hdFRvRml4ZWQocFswXSk7CisgICAgdlsxXSA9IGdnbEZsb2F0VG9GaXhlZChwWzFdKTsKKyAgICB2WzJdID0gZ2dsRmxvYXRUb0ZpeGVkKHBbMl0pOworfQorc3RhdGljIHZvaWQgZmV0Y2g0YihvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTGJ5dGUqIHApIHsKKyAgICB2WzBdID0gZ2dsSW50VG9GaXhlZChwWzBdKTsKKyAgICB2WzFdID0gZ2dsSW50VG9GaXhlZChwWzFdKTsKKyAgICB2WzJdID0gZ2dsSW50VG9GaXhlZChwWzJdKTsKKyAgICB2WzNdID0gZ2dsSW50VG9GaXhlZChwWzNdKTsKK30KK3N0YXRpYyB2b2lkIGZldGNoNHMob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xzaG9ydCogcCkgeworICAgIHZbMF0gPSBnZ2xJbnRUb0ZpeGVkKHBbMF0pOworICAgIHZbMV0gPSBnZ2xJbnRUb0ZpeGVkKHBbMV0pOworICAgIHZbMl0gPSBnZ2xJbnRUb0ZpeGVkKHBbMl0pOworICAgIHZbM10gPSBnZ2xJbnRUb0ZpeGVkKHBbM10pOworfQorc3RhdGljIHZvaWQgZmV0Y2g0eChvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTGZpeGVkKiBwKSB7CisgICAgbWVtY3B5KHYsIHAsIDQqc2l6ZW9mKEdMZml4ZWQpKTsKK30KK3N0YXRpYyB2b2lkIGZldGNoNGYob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xmbG9hdCogcCkgeworICAgIHZbMF0gPSBnZ2xGbG9hdFRvRml4ZWQocFswXSk7CisgICAgdlsxXSA9IGdnbEZsb2F0VG9GaXhlZChwWzFdKTsKKyAgICB2WzJdID0gZ2dsRmxvYXRUb0ZpeGVkKHBbMl0pOworICAgIHZbM10gPSBnZ2xGbG9hdFRvRml4ZWQocFszXSk7Cit9CitzdGF0aWMgdm9pZCBmZXRjaEV4cGFuZDR1YihvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTHVieXRlKiBwKSB7CisgICAgdlswXSA9IEdHTF9VQl9UT19YKHBbMF0pOworICAgIHZbMV0gPSBHR0xfVUJfVE9fWChwWzFdKTsKKyAgICB2WzJdID0gR0dMX1VCX1RPX1gocFsyXSk7CisgICAgdlszXSA9IEdHTF9VQl9UT19YKHBbM10pOworfQorc3RhdGljIHZvaWQgZmV0Y2hDbGFtcDR4KG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMZml4ZWQqIHApIHsKKyAgICB2WzBdID0gZ2dsQ2xhbXB4KHBbMF0pOworICAgIHZbMV0gPSBnZ2xDbGFtcHgocFsxXSk7CisgICAgdlsyXSA9IGdnbENsYW1weChwWzJdKTsKKyAgICB2WzNdID0gZ2dsQ2xhbXB4KHBbM10pOworfQorc3RhdGljIHZvaWQgZmV0Y2hDbGFtcDRmKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMZmxvYXQqIHApIHsKKyAgICB2WzBdID0gZ2dsQ2xhbXB4KGdnbEZsb2F0VG9GaXhlZChwWzBdKSk7CisgICAgdlsxXSA9IGdnbENsYW1weChnZ2xGbG9hdFRvRml4ZWQocFsxXSkpOworICAgIHZbMl0gPSBnZ2xDbGFtcHgoZ2dsRmxvYXRUb0ZpeGVkKHBbMl0pKTsKKyAgICB2WzNdID0gZ2dsQ2xhbXB4KGdnbEZsb2F0VG9GaXhlZChwWzNdKSk7Cit9CitzdGF0aWMgdm9pZCBmZXRjaEV4cGFuZDN1YihvZ2xlc19jb250ZXh0X3QqLCBHTGZpeGVkKiB2LCBjb25zdCBHTHVieXRlKiBwKSB7CisgICAgdlswXSA9IEdHTF9VQl9UT19YKHBbMF0pOworICAgIHZbMV0gPSBHR0xfVUJfVE9fWChwWzFdKTsKKyAgICB2WzJdID0gR0dMX1VCX1RPX1gocFsyXSk7CisgICAgdlszXSA9IDB4MTAwMDA7Cit9CitzdGF0aWMgdm9pZCBmZXRjaENsYW1wM3gob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xmaXhlZCogcCkgeworICAgIHZbMF0gPSBnZ2xDbGFtcHgocFswXSk7CisgICAgdlsxXSA9IGdnbENsYW1weChwWzFdKTsKKyAgICB2WzJdID0gZ2dsQ2xhbXB4KHBbMl0pOworICAgIHZbM10gPSAweDEwMDAwOworfQorc3RhdGljIHZvaWQgZmV0Y2hDbGFtcDNmKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMZmxvYXQqIHApIHsKKyAgICB2WzBdID0gZ2dsQ2xhbXB4KGdnbEZsb2F0VG9GaXhlZChwWzBdKSk7CisgICAgdlsxXSA9IGdnbENsYW1weChnZ2xGbG9hdFRvRml4ZWQocFsxXSkpOworICAgIHZbMl0gPSBnZ2xDbGFtcHgoZ2dsRmxvYXRUb0ZpeGVkKHBbMl0pKTsKKyAgICB2WzNdID0gMHgxMDAwMDsKK30KK3N0YXRpYyB2b2lkIGZldGNoRXhwYW5kM2Iob2dsZXNfY29udGV4dF90KiwgR0xmaXhlZCogdiwgY29uc3QgR0xieXRlKiBwKSB7CisgICAgdlswXSA9IEdHTF9CX1RPX1gocFswXSk7CisgICAgdlsxXSA9IEdHTF9CX1RPX1gocFsxXSk7CisgICAgdlsyXSA9IEdHTF9CX1RPX1gocFsyXSk7Cit9CitzdGF0aWMgdm9pZCBmZXRjaEV4cGFuZDNzKG9nbGVzX2NvbnRleHRfdCosIEdMZml4ZWQqIHYsIGNvbnN0IEdMc2hvcnQqIHApIHsKKyAgICB2WzBdID0gR0dMX1NfVE9fWChwWzBdKTsKKyAgICB2WzFdID0gR0dMX1NfVE9fWChwWzFdKTsKKyAgICB2WzJdID0gR0dMX1NfVE9fWChwWzJdKTsKK30KKwordHlwZWRlZiBhcnJheV90OjpmZXRjaGVyX3QgZm5fdDsgCisKK3N0YXRpYyBjb25zdCBmbl90IGNvbG9yX2ZjdFsyXVsxNl0gPSB7IC8vIHNpemU9ezMsNH0sIHR5cGU9e3ViLGYseH0KKyAgICB7IDAsIChmbl90KWZldGNoRXhwYW5kM3ViLCAwLCAwLCAwLCAwLAorICAgICAgICAgKGZuX3QpZmV0Y2gzZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgIChmbl90KWZldGNoM3ggfSwKKyAgICB7IDAsIChmbl90KWZldGNoRXhwYW5kNHViLCAwLCAwLCAwLCAwLAorICAgICAgICAgKGZuX3QpZmV0Y2g0ZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgIChmbl90KWZldGNoNHggfSwKK307CitzdGF0aWMgY29uc3QgZm5fdCBjb2xvcl9jbGFtcF9mY3RbMl1bMTZdID0geyAvLyBzaXplPXszLDR9LCB0eXBlPXt1YixmLHh9CisgICAgeyAwLCAoZm5fdClmZXRjaEV4cGFuZDN1YiwgMCwgMCwgMCwgMCwKKyAgICAgICAgIChmbl90KWZldGNoQ2xhbXAzZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgIChmbl90KWZldGNoQ2xhbXAzeCB9LAorICAgIHsgMCwgKGZuX3QpZmV0Y2hFeHBhbmQ0dWIsIDAsIDAsIDAsIDAsCisgICAgICAgICAoZm5fdClmZXRjaENsYW1wNGYsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAoZm5fdClmZXRjaENsYW1wNHggfSwKK307CitzdGF0aWMgY29uc3QgZm5fdCBub3JtYWxfZmN0WzFdWzE2XSA9IHsgLy8gc2l6ZT17M30sIHR5cGU9e2IscyxmLHh9CisgICAgeyAoZm5fdClmZXRjaEV4cGFuZDNiLCAwLAorICAgICAgKGZuX3QpZmV0Y2hFeHBhbmQzcywgMCwgMCwgMCwKKyAgICAgIChmbl90KWZldGNoM2YsIDAsIDAsIDAsIDAsIDAsCisgICAgICAoZm5fdClmZXRjaDN4IH0sCit9Oworc3RhdGljIGNvbnN0IGZuX3QgdmVydGV4X2ZjdFszXVsxNl0gPSB7IC8vIHNpemU9ezIsMyw0fSwgdHlwZT17YixzLGYseH0KKyAgICB7IChmbl90KWZldGNoMmIsIDAsCisgICAgICAoZm5fdClmZXRjaDJzLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2gyZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgIChmbl90KWZldGNoM3ggfSwKKyAgICB7IChmbl90KWZldGNoM2IsIDAsCisgICAgICAoZm5fdClmZXRjaDNzLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2gzZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgIChmbl90KWZldGNoM3ggfSwKKyAgICB7IChmbl90KWZldGNoNGIsIDAsCisgICAgICAoZm5fdClmZXRjaDRzLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2g0ZiwgMCwgMCwgMCwgMCwgMCwKKyAgICAgIChmbl90KWZldGNoNHggfQorfTsKK3N0YXRpYyBjb25zdCBmbl90IHRleHR1cmVfZmN0WzNdWzE2XSA9IHsgLy8gc2l6ZT17MiwzLDR9LCB0eXBlPXtiLHMsZix4fQorICAgIHsgKGZuX3QpZmV0Y2gyYiwgMCwKKyAgICAgIChmbl90KWZldGNoMnMsIDAsIDAsIDAsCisgICAgICAoZm5fdClmZXRjaDJmLCAwLCAwLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2gyeCB9LAorICAgIHsgKGZuX3QpZmV0Y2gzYiwgMCwKKyAgICAgIChmbl90KWZldGNoM3MsIDAsIDAsIDAsCisgICAgICAoZm5fdClmZXRjaDNmLCAwLCAwLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2gzeCB9LAorICAgIHsgKGZuX3QpZmV0Y2g0YiwgMCwKKyAgICAgIChmbl90KWZldGNoNHMsIDAsIDAsIDAsCisgICAgICAoZm5fdClmZXRjaDRmLCAwLCAwLCAwLCAwLCAwLAorICAgICAgKGZuX3QpZmV0Y2g0eCB9Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBhcnJheV90CisjZW5kaWYKKwordm9pZCBhcnJheV90Ojppbml0KAorICAgICAgICBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsCisgICAgICAgIGNvbnN0IEdMdm9pZCAqcG9pbnRlciwgY29uc3QgYnVmZmVyX3QqIGJvLCBHTHNpemVpIGNvdW50KQoreworICAgIGlmICghc3RyaWRlKSB7CisgICAgICAgIHN0cmlkZSA9IHNpemU7CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICBjYXNlIEdMX1NIT1JUOgorICAgICAgICBjYXNlIEdMX1VOU0lHTkVEX1NIT1JUOgorICAgICAgICAgICAgc3RyaWRlICo9IDI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBHTF9GTE9BVDoKKyAgICAgICAgY2FzZSBHTF9GSVhFRDoKKyAgICAgICAgICAgIHN0cmlkZSAqPSA0OworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgdGhpcy0+c2l6ZSA9IHNpemU7CisgICAgdGhpcy0+dHlwZSA9IHR5cGU7CisgICAgdGhpcy0+c3RyaWRlID0gc3RyaWRlOworICAgIHRoaXMtPnBvaW50ZXIgPSBwb2ludGVyOworICAgIHRoaXMtPmJvID0gYm87CisgICAgdGhpcy0+Ym91bmRzID0gY291bnQ7Cit9CisKK2lubGluZSB2b2lkIGFycmF5X3Q6OnJlc29sdmUoKSAKK3sKKyAgICBwaHlzaWNhbF9wb2ludGVyID0gKGJvKSA/IChiby0+ZGF0YSArIHVpbnRwdHJfdChwb2ludGVyKSkgOiBwb2ludGVyOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayB2ZXJ0ZXhfY2FjaGVfdAorI2VuZGlmCisKK3ZvaWQgdmVydGV4X2NhY2hlX3Q6OmluaXQoKQoreworICAgIC8vIG1ha2Ugc3VyZSB0aGUgc2l6ZSBvZiB2ZXJ0ZXhfdCBhbGxvd3MgY2FjaGUtbGluZSBhbGlnbm1lbnQKKyAgICBDVEE8KHNpemVvZih2ZXJ0ZXhfdCkgJiAweDFGKSA9PSAwPiBhc3NlcnRBbGlnbmVkU2l6ZTsKKworICAgIGNvbnN0IGludCBhbGlnbiA9IDMyOworICAgIGNvbnN0IHNpemVfdCBzID0gVkVSVEVYX0JVRkZFUl9TSVpFICsgVkVSVEVYX0NBQ0hFX1NJWkU7CisgICAgY29uc3Qgc2l6ZV90IHNpemUgPSBzKnNpemVvZih2ZXJ0ZXhfdCkgKyBhbGlnbjsKKyAgICBiYXNlID0gbWFsbG9jKHNpemUpOworICAgIGlmIChiYXNlKSB7CisgICAgICAgIG1lbXNldChiYXNlLCAwLCBzaXplKTsKKyAgICAgICAgdkJ1ZmZlciA9ICh2ZXJ0ZXhfdCopKChzaXplX3QoYmFzZSkgKyBhbGlnbiAtIDEpICYgfihhbGlnbi0xKSk7CisgICAgICAgIHZDYWNoZSA9IHZCdWZmZXIgKyBWRVJURVhfQlVGRkVSX1NJWkU7CisgICAgICAgIHNlcXVlbmNlID0gMDsKKyAgICB9Cit9CisKK3ZvaWQgdmVydGV4X2NhY2hlX3Q6OnVuaW5pdCgpCit7CisgICAgZnJlZShiYXNlKTsKKyAgICBiYXNlID0gdkJ1ZmZlciA9IHZDYWNoZSA9IDA7Cit9CisKK3ZvaWQgdmVydGV4X2NhY2hlX3Q6OmNsZWFyKCkKK3sKKyNpZiBWQ19DQUNIRV9TVEFUSVNUSUNTCisgICAgc3RhcnRUaW1lID0gc3lzdGVtVGltZShTWVNURU1fVElNRV9USFJFQUQpOworICAgIHRvdGFsID0gMDsKKyAgICBtaXNzZXMgPSAwOworI2VuZGlmCisKKyNpZiBWQ19DQUNIRV9UWVBFID09IFZDX0NBQ0hFX1RZUEVfTFJVCisgICAgdmVydGV4X3QqIHYgPSB2QnVmZmVyOworICAgIHNpemVfdCBjb3VudCA9IFZFUlRFWF9CVUZGRVJfU0laRSArIFZFUlRFWF9DQUNIRV9TSVpFOworICAgIGRvIHsKKyAgICAgICAgdi0+bXJ1ID0gMDsKKyAgICAgICAgdisrOworICAgIH0gd2hpbGUgKC0tY291bnQpOworI2VuZGlmCisKKyAgICBzZXF1ZW5jZSArPSBJTkRFWF9TRVE7CisgICAgaWYgKHNlcXVlbmNlID49IDB4ODAwMDAwMDBMVSkgeworICAgICAgICBzZXF1ZW5jZSA9IElOREVYX1NFUTsKKyAgICAgICAgdmVydGV4X3QqIHYgPSB2QnVmZmVyOworICAgICAgICBzaXplX3QgY291bnQgPSBWRVJURVhfQlVGRkVSX1NJWkUgKyBWRVJURVhfQ0FDSEVfU0laRTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgdi0+aW5kZXggPSAwOworICAgICAgICAgICAgdisrOworICAgICAgICB9IHdoaWxlICgtLWNvdW50KTsKKyAgICB9Cit9CisKK3ZvaWQgdmVydGV4X2NhY2hlX3Q6OmR1bXBfc3RhdHMoR0xlbnVtIG1vZGUpCit7CisjaWYgVkNfQ0FDSEVfU1RBVElTVElDUworICAgIG5zZWNzX3QgdGltZSA9IHN5c3RlbVRpbWUoU1lTVEVNX1RJTUVfVEhSRUFEKSAtIHN0YXJ0VGltZTsKKyAgICB1aW50MzJfdCBoaXRzID0gdG90YWwgLSBtaXNzZXM7CisgICAgdWludDMyX3QgcHJpbV9jb3VudDsKKyAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICBjYXNlIEdMX1BPSU5UUzogICAgICAgICAgICAgcHJpbV9jb3VudCA9IHRvdGFsOyAgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTElORV9TVFJJUDogICAgICAgICBwcmltX2NvdW50ID0gdG90YWwgLSAxOyAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9MSU5FX0xPT1A6ICAgICAgICAgIHByaW1fY291bnQgPSB0b3RhbCAtIDE7ICAgICBicmVhazsKKyAgICBjYXNlIEdMX0xJTkVTOiAgICAgICAgICAgICAgcHJpbV9jb3VudCA9IHRvdGFsIC8gMjsgICAgIGJyZWFrOworICAgIGNhc2UgR0xfVFJJQU5HTEVfU1RSSVA6ICAgICBwcmltX2NvdW50ID0gdG90YWwgLSAyOyAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9UUklBTkdMRV9GQU46ICAgICAgIHByaW1fY291bnQgPSB0b3RhbCAtIDI7ICAgICBicmVhazsKKyAgICBjYXNlIEdMX1RSSUFOR0xFUzogICAgICAgICAgcHJpbV9jb3VudCA9IHRvdGFsIC8gMzsgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6ICAgIHJldHVybjsKKyAgICB9CisgICAgcHJpbnRmKCAidG90YWw9JTV1LCBoaXRzPSU1dSwgbWlzcz0lNXUsIGhpdHJhdGU9JTN1JSUsIgorICAgICAgICAgICAgIiBwcmltcz0lNXUsIHRpbWU9JTZ1IHVzLCBwcmltcy9zPSVkLCB2L3Q9JWZcbiIsCisgICAgICAgICAgICB0b3RhbCwgaGl0cywgbWlzc2VzLCAoaGl0cyoxMDApL3RvdGFsLAorICAgICAgICAgICAgcHJpbV9jb3VudCwgaW50KG5zMnVzKHRpbWUpKSwgaW50KHByaW1fY291bnQqZmxvYXQoc2Vjb25kcygxKSkvdGltZSksCisgICAgICAgICAgICBmbG9hdChtaXNzZXMpIC8gcHJpbV9jb3VudCk7CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjZW5kaWYKKworc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK3ZvaWQgZW5hYmxlRGlzYWJsZUNsaWVudFN0YXRlKG9nbGVzX2NvbnRleHRfdCogYywgR0xlbnVtIGFycmF5LCBib29sIGVuYWJsZSkKK3sKKyAgICBjb25zdCBpbnQgdG11ID0gYy0+YXJyYXlzLmFjdGl2ZVRleHR1cmU7CisgICAgYXJyYXlfdCogYTsKKyAgICBzd2l0Y2ggKGFycmF5KSB7CisgICAgY2FzZSBHTF9DT0xPUl9BUlJBWTogICAgICAgICAgICBhID0gJmMtPmFycmF5cy5jb2xvcjsgICAgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTk9STUFMX0FSUkFZOiAgICAgICAgICAgYSA9ICZjLT5hcnJheXMubm9ybWFsOyAgICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1RFWFRVUkVfQ09PUkRfQVJSQVk6ICAgIGEgPSAmYy0+YXJyYXlzLnRleHR1cmVbdG11XTsgICAgYnJlYWs7CisgICAgY2FzZSBHTF9WRVJURVhfQVJSQVk6ICAgICAgICAgICBhID0gJmMtPmFycmF5cy52ZXJ0ZXg7ICAgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYS0+ZW5hYmxlID0gZW5hYmxlID8gR0xfVFJVRSA6IEdMX0ZBTFNFOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBWZXJ0ZXggQ2FjaGUKKyNlbmRpZgorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordmVydGV4X3QqIGNhY2hlX3ZlcnRleChvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2LCB1aW50MzJfdCBpbmRleCkKK3sKKyAgICAjaWYgVkNfQ0FDSEVfU1RBVElTVElDUworICAgICAgICBjLT52Yy5taXNzZXMrKzsKKyAgICAjZW5kaWYKKyAgICBpZiAoZ2dsX3VubGlrZWx5KHYtPmxvY2tlZCkpIHsKKyAgICAgICAgLy8gd2UncmUganVzdCBsb29raW5nIGZvciBhbiBlbnRyeSBpbiB0aGUgY2FjaGUgdGhhdCBpcyBub3QgbG9ja2VkLgorICAgICAgICAvLyBhbmQgd2Uga25vdyB0aGF0IHRoZXJlIGNhbm5vdCBiZSBtb3JlIHRoYW4gMiBsb2NrZWQgZW50cmllcworICAgICAgICAvLyBiZWNhdXNlIGEgdHJpYW5nbGUgbmVlZHMgYXQgbW9zdCAzIHZlcnRpY2VzLgorICAgICAgICAvLyBXZSBuZXZlciB1c2UgdGhlIGZpcnN0IGFuZCBzZWNvbmQgZW50cmllcyBiZWNhdXNlIHRoZXkgbWlnaHQgYmUgaW4KKyAgICAgICAgLy8gdXNlIGJ5IHRoZSBzdHJpcGVyIG9yIGZhbmVyLiBBbnkgb3RoZXIgZW50cnkgd2lsbCBkbyBhcyBsb25nIGFzCisgICAgICAgIC8vIGl0J3Mgbm90IGxvY2tlZC4KKyAgICAgICAgLy8gV2UgY29tcHV0ZSBkaXJlY3RseSB0aGUgaW5kZXggb2YgYSAiZnJlZSIgZW50cnkgZnJvbSB0aGUgbG9ja2VkCisgICAgICAgIC8vIHN0YXRlIG9mIHZbMl0gYW5kIHZbM10uCisgICAgICAgIHYgPSBjLT52Yy52QnVmZmVyICsgMjsKKyAgICAgICAgdiArPSB2WzBdLmxvY2tlZCB8ICh2WzFdLmxvY2tlZDw8MSk7ICAgICAgIAorICAgIH0KKyAgICAvLyBub3RlOiBjb21waWxlRWxlbWVudCBjbGVhcnMgdi0+ZmxhZ3MKKyAgICBjLT5hcnJheXMuY29tcGlsZUVsZW1lbnQoYywgdiwgaW5kZXgpOworICAgIHYtPmxvY2tlZCA9IDE7CisgICAgcmV0dXJuIHY7Cit9CisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCit2ZXJ0ZXhfdCogZmV0Y2hfdmVydGV4KG9nbGVzX2NvbnRleHRfdCogYywgc2l6ZV90IGluZGV4KQoreworICAgIGluZGV4IHw9IGMtPnZjLnNlcXVlbmNlOworCisjaWYgVkNfQ0FDSEVfVFlQRSA9PSBWQ19DQUNIRV9UWVBFX0lOREVYRUQKKworICAgIHZlcnRleF90KiBjb25zdCB2ID0gYy0+dmMudkNhY2hlICsgCisgICAgICAgICAgICAoaW5kZXggJiAodmVydGV4X2NhY2hlX3Q6OlZFUlRFWF9DQUNIRV9TSVpFLTEpKTsKKworICAgIGlmIChnZ2xfbGlrZWx5KHYtPmluZGV4ID09IGluZGV4KSkgeworICAgICAgICB2LT5sb2NrZWQgPSAxOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisgICAgcmV0dXJuIGNhY2hlX3ZlcnRleChjLCB2LCBpbmRleCk7CisKKyNlbGlmIFZDX0NBQ0hFX1RZUEUgPT0gVkNfQ0FDSEVfVFlQRV9MUlUKKworICAgIHZlcnRleF90KiB2ID0gYy0+dmMudkNhY2hlICsgCisgICAgICAgICAgICAoaW5kZXggJiAoKHZlcnRleF9jYWNoZV90OjpWRVJURVhfQ0FDSEVfU0laRS0xKT4+MSkpKjI7CisKKyAgICAvLyBhbHdheXMgcmVjb3JkIExSVSBpbiB2WzBdCisgICAgaWYgKGdnbF9saWtlbHkodlswXS5pbmRleCA9PSBpbmRleCkpIHsKKyAgICAgICAgdlswXS5sb2NrZWQgPSAxOworICAgICAgICB2WzBdLm1ydSA9IDA7CisgICAgICAgIHJldHVybiAmdlswXTsKKyAgICB9CisKKyAgICBpZiAoZ2dsX2xpa2VseSh2WzFdLmluZGV4ID09IGluZGV4KSkgeworICAgICAgICB2WzFdLmxvY2tlZCA9IDE7CisgICAgICAgIHZbMF0ubXJ1ID0gMTsKKyAgICAgICAgcmV0dXJuICZ2WzFdOworICAgIH0KKworICAgIGNvbnN0IGludCBscnUgPSAxIC0gdlswXS5tcnU7CisgICAgdlswXS5tcnUgPSBscnU7CisgICAgcmV0dXJuIGNhY2hlX3ZlcnRleChjLCAmdltscnVdLCBpbmRleCk7CisKKyNlbGlmIFZDX0NBQ0hFX1RZUEUgPT0gVkNfQ0FDSEVfVFlQRV9OT05FCisKKyAgICAvLyBqdXN0IGZvciBkZWJ1Z2dpbmcuLi4KKyAgICB2ZXJ0ZXhfdCogdiA9IGMtPnZjLnZCdWZmZXIgKyAyOworICAgIHJldHVybiBjYWNoZV92ZXJ0ZXgoYywgdiwgaW5kZXgpOworCisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgUHJpbWl0aXZlIEFzc2VtYmx5CisjZW5kaWYKKwordm9pZCBkcmF3UHJpbWl0aXZlc1BvaW50cyhvZ2xlc19jb250ZXh0X3QqIGMsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KQoreworICAgIGlmIChnZ2xfdW5saWtlbHkoY291bnQgPCAxKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgLy8gdmVydGV4IGNhY2hlIHNpemUgbXVzdCBiZSBtdWx0aXBsZSBvZiAxCisgICAgY29uc3QgR0xzaXplaSB2Y3MgPSAKKyAgICAgICAgICAgICh2ZXJ0ZXhfY2FjaGVfdDo6VkVSVEVYX0JVRkZFUl9TSVpFICsKKyAgICAgICAgICAgICB2ZXJ0ZXhfY2FjaGVfdDo6VkVSVEVYX0NBQ0hFX1NJWkUpOworICAgIGRvIHsKKyAgICAgICAgdmVydGV4X3QqIHYgPSBjLT52Yy52QnVmZmVyOworICAgICAgICBHTHNpemVpIG51bSA9IGNvdW50ID4gdmNzID8gdmNzIDogY291bnQ7IAorICAgICAgICBjLT5hcnJheXMuY3VsbCA9IHZlcnRleF90OjpDTElQX0FMTDsKKyAgICAgICAgYy0+YXJyYXlzLmNvbXBpbGVFbGVtZW50cyhjLCB2LCBmaXJzdCwgbnVtKTsKKyAgICAgICAgZmlyc3QgKz0gbnVtOworICAgICAgICBjb3VudCAtPSBudW07CisgICAgICAgIGlmICghYy0+YXJyYXlzLmN1bGwpIHsKKyAgICAgICAgICAgIC8vIHF1aWNrL3RyaXZpYWwgcmVqZWN0IG9mIHRoZSB3aG9sZSBiYXRjaAorICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdlswXS5mbGFnczsKKyAgICAgICAgICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICAgICAgICAgIGMtPnByaW1zLnJlbmRlclBvaW50KGMsIHYpOworICAgICAgICAgICAgICAgIHYrKzsKKyAgICAgICAgICAgICAgICBudW0tLTsKKyAgICAgICAgICAgIH0gd2hpbGUgKG51bSk7CisgICAgICAgIH0KKyAgICB9IHdoaWxlIChjb3VudCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBkcmF3UHJpbWl0aXZlc0xpbmVTdHJpcChvZ2xlc19jb250ZXh0X3QqIGMsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KQoreworICAgIGlmIChnZ2xfdW5saWtlbHkoY291bnQgPCAyKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgdmVydGV4X3QgKnYsICp2MCwgKnYxOworICAgIGMtPmFycmF5cy5jdWxsID0gdmVydGV4X3Q6OkNMSVBfQUxMOworICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudChjLCBjLT52Yy52QnVmZmVyLCBmaXJzdCk7CisgICAgZmlyc3QgKz0gMTsKKyAgICBjb3VudCAtPSAxOworCisgICAgLy8gdmVydGV4IGNhY2hlIHNpemUgbXVzdCBiZSBtdWx0aXBsZSBvZiAxCisgICAgY29uc3QgR0xzaXplaSB2Y3MgPSAKKyAgICAgICAgKHZlcnRleF9jYWNoZV90OjpWRVJURVhfQlVGRkVSX1NJWkUgKworICAgICAgICAgdmVydGV4X2NhY2hlX3Q6OlZFUlRFWF9DQUNIRV9TSVpFIC0gMSk7CisgICAgZG8geworICAgICAgICB2MCA9IGMtPnZjLnZCdWZmZXIgKyAwOyAKKyAgICAgICAgdiAgPSBjLT52Yy52QnVmZmVyICsgMTsKKyAgICAgICAgR0xzaXplaSBudW0gPSBjb3VudCA+IHZjcyA/IHZjcyA6IGNvdW50OyAKKyAgICAgICAgYy0+YXJyYXlzLmNvbXBpbGVFbGVtZW50cyhjLCB2LCBmaXJzdCwgbnVtKTsKKyAgICAgICAgZmlyc3QgKz0gbnVtOworICAgICAgICBjb3VudCAtPSBudW07CisgICAgICAgIGlmICghYy0+YXJyYXlzLmN1bGwpIHsKKyAgICAgICAgICAgIC8vIHF1aWNrL3RyaXZpYWwgcmVqZWN0IG9mIHRoZSB3aG9sZSBiYXRjaAorICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIHYxID0gdisrOworICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdjAtPmZsYWdzICYgdjEtPmZsYWdzOworICAgICAgICAgICAgICAgIGlmIChnZ2xfbGlrZWx5KCEoY2MgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEwpKSkKKyAgICAgICAgICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyTGluZShjLCB2MCwgdjEpOworICAgICAgICAgICAgICAgIHYwID0gdjE7CisgICAgICAgICAgICAgICAgbnVtLS07CisgICAgICAgICAgICB9IHdoaWxlIChudW0pOworICAgICAgICB9CisgICAgICAgIC8vIGNvcHkgYmFjayB0aGUgbGFzdCBwcm9jZXNzZWQgdmVydGV4CisgICAgICAgIGMtPnZjLnZCdWZmZXJbMF0gPSAqdjA7CisgICAgICAgIGMtPmFycmF5cy5jdWxsID0gdjAtPmZsYWdzICYgdmVydGV4X3Q6OkNMSVBfQUxMOworICAgIH0gd2hpbGUgKGNvdW50KTsKK30KKwordm9pZCBkcmF3UHJpbWl0aXZlc0xpbmVMb29wKG9nbGVzX2NvbnRleHRfdCogYywgR0xpbnQgZmlyc3QsIEdMc2l6ZWkgY291bnQpCit7CisgICAgaWYgKGdnbF91bmxpa2VseShjb3VudCA8IDIpKQorICAgICAgICByZXR1cm47CisgICAgZHJhd1ByaW1pdGl2ZXNMaW5lU3RyaXAoYywgZmlyc3QsIGNvdW50KTsKKyAgICBpZiAoZ2dsX2xpa2VseShjb3VudCA+PSAzKSkgeworICAgICAgICB2ZXJ0ZXhfdCogdjAgPSBjLT52Yy52QnVmZmVyOyAKKyAgICAgICAgdmVydGV4X3QqIHYxID0gYy0+dmMudkJ1ZmZlciArIDE7CisgICAgICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudChjLCB2MSwgZmlyc3QpOworICAgICAgICBjb25zdCB1aW50MzJfdCBjYyA9IHYwLT5mbGFncyAmIHYxLT5mbGFnczsKKyAgICAgICAgaWYgKGdnbF9saWtlbHkoIShjYyAmIHZlcnRleF90OjpDTElQX0FMTCkpKQorICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyTGluZShjLCB2MCwgdjEpOworICAgIH0KK30KKwordm9pZCBkcmF3UHJpbWl0aXZlc0xpbmVzKG9nbGVzX2NvbnRleHRfdCogYywgR0xpbnQgZmlyc3QsIEdMc2l6ZWkgY291bnQpCit7CisgICAgaWYgKGdnbF91bmxpa2VseShjb3VudCA8IDIpKQorICAgICAgICByZXR1cm47CisKKyAgICAvLyB2ZXJ0ZXggY2FjaGUgc2l6ZSBtdXN0IGJlIG11bHRpcGxlIG9mIDIKKyAgICBjb25zdCBHTHNpemVpIHZjcyA9IAorICAgICAgICAoKHZlcnRleF9jYWNoZV90OjpWRVJURVhfQlVGRkVSX1NJWkUgKworICAgICAgICB2ZXJ0ZXhfY2FjaGVfdDo6VkVSVEVYX0NBQ0hFX1NJWkUpIC8gMikgKiAyOworICAgIGRvIHsKKyAgICAgICAgdmVydGV4X3QqIHYgPSBjLT52Yy52QnVmZmVyOworICAgICAgICBHTHNpemVpIG51bSA9IGNvdW50ID4gdmNzID8gdmNzIDogY291bnQ7IAorICAgICAgICBjLT5hcnJheXMuY3VsbCA9IHZlcnRleF90OjpDTElQX0FMTDsKKyAgICAgICAgYy0+YXJyYXlzLmNvbXBpbGVFbGVtZW50cyhjLCB2LCBmaXJzdCwgbnVtKTsKKyAgICAgICAgZmlyc3QgKz0gbnVtOworICAgICAgICBjb3VudCAtPSBudW07CisgICAgICAgIGlmICghYy0+YXJyYXlzLmN1bGwpIHsKKyAgICAgICAgICAgIC8vIHF1aWNrL3RyaXZpYWwgcmVqZWN0IG9mIHRoZSB3aG9sZSBiYXRjaAorICAgICAgICAgICAgbnVtIC09IDI7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgY29uc3QgdWludDMyX3QgY2MgPSB2WzBdLmZsYWdzICYgdlsxXS5mbGFnczsKKyAgICAgICAgICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICAgICAgICAgIGMtPnByaW1zLnJlbmRlckxpbmUoYywgdiwgdisxKTsKKyAgICAgICAgICAgICAgICB2ICs9IDI7CisgICAgICAgICAgICAgICAgbnVtIC09IDI7CisgICAgICAgICAgICB9IHdoaWxlIChudW0gPj0gMCk7CisgICAgICAgIH0KKyAgICB9IHdoaWxlIChjb3VudCA+PSAyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBkcmF3UHJpbWl0aXZlc1RyaWFuZ2xlRmFuT3JTdHJpcChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50LCBpbnQgd2luZGluZykKK3sKKyAgICAvLyB3aW5kaW5nID09IDIgOiBmYW4KKyAgICAvLyB3aW5kaW5nID09IDEgOiBzdHJpcAorCisgICAgaWYgKGdnbF91bmxpa2VseShjb3VudCA8IDMpKQorICAgICAgICByZXR1cm47CisKKyAgICB2ZXJ0ZXhfdCAqdiwgKnYwLCAqdjEsICp2MjsKKyAgICBjLT5hcnJheXMuY3VsbCA9IHZlcnRleF90OjpDTElQX0FMTDsKKyAgICBjLT5hcnJheXMuY29tcGlsZUVsZW1lbnRzKGMsIGMtPnZjLnZCdWZmZXIsIGZpcnN0LCAyKTsKKyAgICBmaXJzdCArPSAyOworICAgIGNvdW50IC09IDI7CisKKyAgICAvLyB2ZXJ0ZXggY2FjaGUgc2l6ZSBtdXN0IGJlIG11bHRpcGxlIG9mIDIuIFRoaXMgaXMgZXh0cmVtZWx5IGltcG9ydGFudAorICAgIC8vIGJlY2F1c2UgaXQgYWxsb3dzIHVzIHRvIHByZXNlcnZlIHRoZSBzYW1lIHdpbmRpbmcgd2hlbiB0aGUgd2hvbGUKKyAgICAvLyBiYXRjaCBpcyBjdWxsZWQuIFdlIGFsc28gbmVlZCAyIGV4dHJhIHZlcnRpY2VzIGluIHRoZSBhcnJheSwgYmVjYXVzZQorICAgIC8vIHdlIGFsd2F5cyBrZWVwIHRoZSB0d28gZmlyc3Qgb25lcy4KKyAgICBjb25zdCBHTHNpemVpIHZjcyA9IAorICAgICAgICAoKHZlcnRleF9jYWNoZV90OjpWRVJURVhfQlVGRkVSX1NJWkUgKworICAgICAgICAgIHZlcnRleF9jYWNoZV90OjpWRVJURVhfQ0FDSEVfU0laRSAtIDIpIC8gMikgKiAyOworICAgIGRvIHsKKyAgICAgICAgdjAgPSBjLT52Yy52QnVmZmVyICsgMDsgCisgICAgICAgIHYxID0gYy0+dmMudkJ1ZmZlciArIDE7IAorICAgICAgICB2ICA9IGMtPnZjLnZCdWZmZXIgKyAyOworICAgICAgICBHTHNpemVpIG51bSA9IGNvdW50ID4gdmNzID8gdmNzIDogY291bnQ7IAorICAgICAgICBjLT5hcnJheXMuY29tcGlsZUVsZW1lbnRzKGMsIHYsIGZpcnN0LCBudW0pOworICAgICAgICBmaXJzdCArPSBudW07CisgICAgICAgIGNvdW50IC09IG51bTsKKyAgICAgICAgaWYgKCFjLT5hcnJheXMuY3VsbCkgeworICAgICAgICAgICAgLy8gcXVpY2svdHJpdmlhbCByZWplY3Qgb2YgdGhlIHdob2xlIGJhdGNoCisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgdjIgPSB2Kys7CisgICAgICAgICAgICAgICAgY29uc3QgdWludDMyX3QgY2MgPSB2MC0+ZmxhZ3MgJiB2MS0+ZmxhZ3MgJiB2Mi0+ZmxhZ3M7CisgICAgICAgICAgICAgICAgaWYgKGdnbF9saWtlbHkoIShjYyAmIHZlcnRleF90OjpDTElQX0FMTCkpKQorICAgICAgICAgICAgICAgICAgICBjLT5wcmltcy5yZW5kZXJUcmlhbmdsZShjLCB2MCwgdjEsIHYyKTsKKyAgICAgICAgICAgICAgICBzd2FwKCgod2luZGluZ149MSkgPyB2MSA6IHYwKSwgdjIpOworICAgICAgICAgICAgICAgIG51bS0tOworICAgICAgICAgICAgfSB3aGlsZSAobnVtKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY291bnQpIHsKKyAgICAgICAgICAgIHYwID0gYy0+dmMudkJ1ZmZlciArIDIgKyBudW0gLSAyOworICAgICAgICAgICAgdjEgPSBjLT52Yy52QnVmZmVyICsgMiArIG51bSAtIDE7CisgICAgICAgICAgICBpZiAoKHdpbmRpbmcmMikgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIGZvciBzdHJpcHMgY29weSBiYWNrIHRoZSB0d28gbGFzdCBjb21waWxlZCB2ZXJ0aWNlcworICAgICAgICAgICAgICAgIGMtPnZjLnZCdWZmZXJbMF0gPSAqdjA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjLT52Yy52QnVmZmVyWzFdID0gKnYxOworICAgICAgICAgICAgYy0+YXJyYXlzLmN1bGwgPSB2MC0+ZmxhZ3MgJiB2MS0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEw7CisgICAgICAgIH0KKyAgICB9IHdoaWxlIChjb3VudCA+IDApOworfQorCit2b2lkIGRyYXdQcmltaXRpdmVzVHJpYW5nbGVTdHJpcChvZ2xlc19jb250ZXh0X3QqIGMsIAorICAgICAgICBHTGludCBmaXJzdCwgR0xzaXplaSBjb3VudCkgeworICAgIGRyYXdQcmltaXRpdmVzVHJpYW5nbGVGYW5PclN0cmlwKGMsIGZpcnN0LCBjb3VudCwgMSk7Cit9CisKK3ZvaWQgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZUZhbihvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KSB7CisgICAgZHJhd1ByaW1pdGl2ZXNUcmlhbmdsZUZhbk9yU3RyaXAoYywgZmlyc3QsIGNvdW50LCAyKTsKK30KKwordm9pZCBkcmF3UHJpbWl0aXZlc1RyaWFuZ2xlcyhvZ2xlc19jb250ZXh0X3QqIGMsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KQoreworICAgIGlmIChnZ2xfdW5saWtlbHkoY291bnQgPCAzKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgLy8gdmVydGV4IGNhY2hlIHNpemUgbXVzdCBiZSBtdWx0aXBsZSBvZiAzCisgICAgY29uc3QgR0xzaXplaSB2Y3MgPSAKKyAgICAgICAgKCh2ZXJ0ZXhfY2FjaGVfdDo6VkVSVEVYX0JVRkZFUl9TSVpFICsKKyAgICAgICAgdmVydGV4X2NhY2hlX3Q6OlZFUlRFWF9DQUNIRV9TSVpFKSAvIDMpICogMzsKKyAgICBkbyB7CisgICAgICAgIHZlcnRleF90KiB2ID0gYy0+dmMudkJ1ZmZlcjsKKyAgICAgICAgR0xzaXplaSBudW0gPSBjb3VudCA+IHZjcyA/IHZjcyA6IGNvdW50OyAKKyAgICAgICAgYy0+YXJyYXlzLmN1bGwgPSB2ZXJ0ZXhfdDo6Q0xJUF9BTEw7CisgICAgICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudHMoYywgdiwgZmlyc3QsIG51bSk7CisgICAgICAgIGZpcnN0ICs9IG51bTsKKyAgICAgICAgY291bnQgLT0gbnVtOworICAgICAgICBpZiAoIWMtPmFycmF5cy5jdWxsKSB7CisgICAgICAgICAgICAvLyBxdWljay90cml2aWFsIHJlamVjdCBvZiB0aGUgd2hvbGUgYmF0Y2gKKyAgICAgICAgICAgIG51bSAtPSAzOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdlswXS5mbGFncyAmIHZbMV0uZmxhZ3MgJiB2WzJdLmZsYWdzOworICAgICAgICAgICAgICAgIGlmIChnZ2xfbGlrZWx5KCEoY2MgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEwpKSkKKyAgICAgICAgICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyVHJpYW5nbGUoYywgdiwgdisxLCB2KzIpOworICAgICAgICAgICAgICAgIHYgKz0gMzsKKyAgICAgICAgICAgICAgICBudW0gLT0gMzsKKyAgICAgICAgICAgIH0gd2hpbGUgKG51bSA+PSAwKTsKKyAgICAgICAgfQorICAgIH0gd2hpbGUgKGNvdW50ID49IDMpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCisvLyB0aGlzIGxvb2tzIGdvb2Z5LCBidXQgZ2NjIGRvZXMgYSBncmVhdCBqb2Igd2l0aCB0aGlzLi4uCitzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCByZWFkX2luZGV4KGludCB0eXBlLCBjb25zdCBHTHZvaWQqJiBwKSB7CisgICAgdW5zaWduZWQgaW50IHI7CisgICAgaWYgKHR5cGUpIHsKKyAgICAgICAgciA9ICooY29uc3QgR0x1Ynl0ZSopcDsKKyAgICAgICAgcCA9IChjb25zdCBHTHVieXRlKilwICsgMTsKKyAgICB9IGVsc2UgeworICAgICAgICByID0gKihjb25zdCBHTHVzaG9ydCopcDsKKyAgICAgICAgcCA9IChjb25zdCBHTHVzaG9ydCopcCArIDE7CisgICAgfQorICAgIHJldHVybiByOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgZHJhd0luZGV4ZWRQcmltaXRpdmVzUG9pbnRzKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgR0xzaXplaSBjb3VudCwgY29uc3QgR0x2b2lkICppbmRpY2VzKQoreworICAgIGlmIChnZ2xfdW5saWtlbHkoY291bnQgPCAxKSkKKyAgICAgICAgcmV0dXJuOworICAgIGNvbnN0IGludCB0eXBlID0gKGMtPmFycmF5cy5pbmRpY2VzVHlwZSA9PSBHTF9VTlNJR05FRF9CWVRFKTsKKyAgICBkbyB7CisgICAgICAgIHZlcnRleF90ICogdiA9IGZldGNoX3ZlcnRleChjLCByZWFkX2luZGV4KHR5cGUsIGluZGljZXMpKTsKKyAgICAgICAgaWYgKGdnbF9saWtlbHkoISh2LT5mbGFncyAmIHZlcnRleF90OjpDTElQX0FMTCkpKQorICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyUG9pbnQoYywgdik7CisgICAgICAgIHYtPmxvY2tlZCA9IDA7CisgICAgICAgIGNvdW50LS07CisgICAgfSB3aGlsZShjb3VudCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lU3RyaXAob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICBHTHNpemVpIGNvdW50LCBjb25zdCBHTHZvaWQgKmluZGljZXMpCit7CisgICAgaWYgKGdnbF91bmxpa2VseShjb3VudCA8IDIpKQorICAgICAgICByZXR1cm47CisgICAgCisgICAgdmVydGV4X3QgKiBjb25zdCB2ID0gYy0+dmMudkJ1ZmZlcjsKKyAgICB2ZXJ0ZXhfdCogdjAgPSB2OworICAgIHZlcnRleF90KiB2MTsKKyAgICAKKyAgICBjb25zdCBpbnQgdHlwZSA9IChjLT5hcnJheXMuaW5kaWNlc1R5cGUgPT0gR0xfVU5TSUdORURfQllURSk7CisgICAgYy0+YXJyYXlzLmNvbXBpbGVFbGVtZW50KGMsIHYwLCByZWFkX2luZGV4KHR5cGUsIGluZGljZXMpKTsKKyAgICBjb3VudCAtPSAxOworICAgIGRvIHsKKyAgICAgICAgdjEgPSBmZXRjaF92ZXJ0ZXgoYywgcmVhZF9pbmRleCh0eXBlLCBpbmRpY2VzKSk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdjAtPmZsYWdzICYgdjEtPmZsYWdzOworICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICBjLT5wcmltcy5yZW5kZXJMaW5lKGMsIHYwLCB2MSk7CisgICAgICAgIHYwLT5sb2NrZWQgPSAwOworICAgICAgICB2MCA9IHYxOworICAgICAgICBjb3VudC0tOworICAgIH0gd2hpbGUgKGNvdW50KTsKKyAgICB2MS0+bG9ja2VkID0gMDsKK30KKwordm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lTG9vcChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMc2l6ZWkgY291bnQsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykKK3sKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGNvdW50IDw9IDIpKSB7CisgICAgICAgIGRyYXdJbmRleGVkUHJpbWl0aXZlc0xpbmVzKGMsIGNvdW50LCBpbmRpY2VzKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAKKyAgICB2ZXJ0ZXhfdCAqIGNvbnN0IHYgPSBjLT52Yy52QnVmZmVyOworICAgIHZlcnRleF90KiB2MCA9IHY7CisgICAgdmVydGV4X3QqIHYxOworICAgIAorICAgIGNvbnN0IGludCB0eXBlID0gKGMtPmFycmF5cy5pbmRpY2VzVHlwZSA9PSBHTF9VTlNJR05FRF9CWVRFKTsKKyAgICBjLT5hcnJheXMuY29tcGlsZUVsZW1lbnQoYywgdjAsIHJlYWRfaW5kZXgodHlwZSwgaW5kaWNlcykpOworICAgIGNvdW50IC09IDE7CisgICAgZG8geworICAgICAgICB2MSA9IGZldGNoX3ZlcnRleChjLCByZWFkX2luZGV4KHR5cGUsIGluZGljZXMpKTsKKyAgICAgICAgY29uc3QgdWludDMyX3QgY2MgPSB2MC0+ZmxhZ3MgJiB2MS0+ZmxhZ3M7CisgICAgICAgIGlmIChnZ2xfbGlrZWx5KCEoY2MgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEwpKSkKKyAgICAgICAgICAgIGMtPnByaW1zLnJlbmRlckxpbmUoYywgdjAsIHYxKTsKKyAgICAgICAgdjAtPmxvY2tlZCA9IDA7CisgICAgICAgIHYwID0gdjE7CisgICAgICAgIGNvdW50LS07CisgICAgfSB3aGlsZSAoY291bnQpOworICAgIHYxLT5sb2NrZWQgPSAwOworCisgICAgdjEgPSBjLT52Yy52QnVmZmVyOyAKKyAgICBjb25zdCB1aW50MzJfdCBjYyA9IHYwLT5mbGFncyAmIHYxLT5mbGFnczsKKyAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgIGMtPnByaW1zLnJlbmRlckxpbmUoYywgdjAsIHYxKTsKK30KKwordm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNMaW5lcyhvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMc2l6ZWkgY291bnQsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykKK3sKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGNvdW50IDwgMikpCisgICAgICAgIHJldHVybjsKKworICAgIGNvdW50IC09IDI7CisgICAgY29uc3QgaW50IHR5cGUgPSAoYy0+YXJyYXlzLmluZGljZXNUeXBlID09IEdMX1VOU0lHTkVEX0JZVEUpOworICAgIGRvIHsKKyAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYwID0gZmV0Y2hfdmVydGV4KGMsIHJlYWRfaW5kZXgodHlwZSwgaW5kaWNlcykpOworICAgICAgICB2ZXJ0ZXhfdCogY29uc3QgdjEgPSBmZXRjaF92ZXJ0ZXgoYywgcmVhZF9pbmRleCh0eXBlLCBpbmRpY2VzKSk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdjAtPmZsYWdzICYgdjEtPmZsYWdzOworICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICBjLT5wcmltcy5yZW5kZXJMaW5lKGMsIHYwLCB2MSk7CisgICAgICAgIHYwLT5sb2NrZWQgPSAwOworICAgICAgICB2MS0+bG9ja2VkID0gMDsKKyAgICAgICAgY291bnQgLT0gMjsKKyAgICB9IHdoaWxlIChjb3VudCA+PSAwKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBkcmF3SW5kZXhlZFByaW1pdGl2ZXNUcmlhbmdsZUZhbk9yU3RyaXAob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICBHTHNpemVpIGNvdW50LCBjb25zdCBHTHZvaWQgKmluZGljZXMsIGludCB3aW5kaW5nKQoreworICAgIC8vIHdpbmRpbmcgPT0gMiA6IGZhbgorICAgIC8vIHdpbmRpbmcgPT0gMSA6IHN0cmlwCisKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGNvdW50IDwgMykpCisgICAgICAgIHJldHVybjsKKyAgICAKKyAgICB2ZXJ0ZXhfdCAqIGNvbnN0IHYgPSBjLT52Yy52QnVmZmVyOworICAgIHZlcnRleF90KiB2MCA9IHY7CisgICAgdmVydGV4X3QqIHYxID0gdisxOworICAgIHZlcnRleF90KiB2MjsKKworICAgIGNvbnN0IGludCB0eXBlID0gKGMtPmFycmF5cy5pbmRpY2VzVHlwZSA9PSBHTF9VTlNJR05FRF9CWVRFKTsKKyAgICBjLT5hcnJheXMuY29tcGlsZUVsZW1lbnQoYywgdjAsIHJlYWRfaW5kZXgodHlwZSwgaW5kaWNlcykpOworICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudChjLCB2MSwgcmVhZF9pbmRleCh0eXBlLCBpbmRpY2VzKSk7CisgICAgY291bnQgLT0gMjsKKworICAgIC8vIG5vdGU6IEdDQyA0LjEuMSBoZXJlIG1ha2VzIGEgcHJldHkgaW50ZXJlc3Rpbmcgb3B0aW1pemF0aW9uCisgICAgLy8gd2hlcmUgaXQgZHVwbGljYXRlcyB0aGUgbG9vcCBiZWxvdyBiYXNlZCBvbiBjLT5hcnJheXMuaW5kaWNlc1R5cGUKKworICAgIGRvIHsKKyAgICAgICAgdjIgPSBmZXRjaF92ZXJ0ZXgoYywgcmVhZF9pbmRleCh0eXBlLCBpbmRpY2VzKSk7CisgICAgICAgIGNvbnN0IHVpbnQzMl90IGNjID0gdjAtPmZsYWdzICYgdjEtPmZsYWdzICYgdjItPmZsYWdzOworICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICBjLT5wcmltcy5yZW5kZXJUcmlhbmdsZShjLCB2MCwgdjEsIHYyKTsKKyAgICAgICAgdmVydGV4X3QqICYgY29uc3VtZWQgPSAoKHdpbmRpbmdePTEpID8gdjEgOiB2MCk7CisgICAgICAgIGNvbnN1bWVkLT5sb2NrZWQgPSAwOworICAgICAgICBjb25zdW1lZCA9IHYyOworICAgICAgICBjb3VudC0tOworICAgIH0gd2hpbGUgKGNvdW50KTsKKyAgICB2MC0+bG9ja2VkID0gdjEtPmxvY2tlZCA9IDA7CisgICAgdjItPmxvY2tlZCA9IDA7Cit9CisKK3ZvaWQgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVTdHJpcChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMc2l6ZWkgY291bnQsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykgeworICAgIGRyYXdJbmRleGVkUHJpbWl0aXZlc1RyaWFuZ2xlRmFuT3JTdHJpcChjLCBjb3VudCwgaW5kaWNlcywgMSk7Cit9CisKK3ZvaWQgZHJhd0luZGV4ZWRQcmltaXRpdmVzVHJpYW5nbGVGYW4ob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICBHTHNpemVpIGNvdW50LCBjb25zdCBHTHZvaWQgKmluZGljZXMpIHsKKyAgICBkcmF3SW5kZXhlZFByaW1pdGl2ZXNUcmlhbmdsZUZhbk9yU3RyaXAoYywgY291bnQsIGluZGljZXMsIDIpOworfQorCit2b2lkIGRyYXdJbmRleGVkUHJpbWl0aXZlc1RyaWFuZ2xlcyhvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMc2l6ZWkgY291bnQsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykKK3sKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGNvdW50IDwgMykpCisgICAgICAgIHJldHVybjsKKworICAgIGNvdW50IC09IDM7CisgICAgaWYgKGdnbF9saWtlbHkoYy0+YXJyYXlzLmluZGljZXNUeXBlID09IEdMX1VOU0lHTkVEX1NIT1JUKSkgeworICAgICAgICAvLyBUaGlzIGNhc2UgaXMgcHJvYmFibHkgb3VyIG1vc3QgY29tbW9uIGNhc2UuLi4KKyAgICAgICAgdWludDE2X3QgY29uc3QgKiBwID0gKHVpbnQxNl90IGNvbnN0ICopaW5kaWNlczsKKyAgICAgICAgZG8geworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYwID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYxID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYyID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgY29uc3QgdWludDMyX3QgY2MgPSB2MC0+ZmxhZ3MgJiB2MS0+ZmxhZ3MgJiB2Mi0+ZmxhZ3M7CisgICAgICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyVHJpYW5nbGUoYywgdjAsIHYxLCB2Mik7CisgICAgICAgICAgICB2MC0+bG9ja2VkID0gMDsKKyAgICAgICAgICAgIHYxLT5sb2NrZWQgPSAwOworICAgICAgICAgICAgdjItPmxvY2tlZCA9IDA7CisgICAgICAgICAgICBjb3VudCAtPSAzOworICAgICAgICB9IHdoaWxlIChjb3VudCA+PSAwKTsKKyAgICB9IGVsc2UgeworICAgICAgICB1aW50OF90IGNvbnN0ICogcCA9ICh1aW50OF90IGNvbnN0ICopaW5kaWNlczsKKyAgICAgICAgZG8geworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYwID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYxID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYyID0gZmV0Y2hfdmVydGV4KGMsICpwKyspOworICAgICAgICAgICAgY29uc3QgdWludDMyX3QgY2MgPSB2MC0+ZmxhZ3MgJiB2MS0+ZmxhZ3MgJiB2Mi0+ZmxhZ3M7CisgICAgICAgICAgICBpZiAoZ2dsX2xpa2VseSghKGNjICYgdmVydGV4X3Q6OkNMSVBfQUxMKSkpCisgICAgICAgICAgICAgICAgYy0+cHJpbXMucmVuZGVyVHJpYW5nbGUoYywgdjAsIHYxLCB2Mik7CisgICAgICAgICAgICB2MC0+bG9ja2VkID0gMDsKKyAgICAgICAgICAgIHYxLT5sb2NrZWQgPSAwOworICAgICAgICAgICAgdjItPmxvY2tlZCA9IDA7CisgICAgICAgICAgICBjb3VudCAtPSAzOworICAgICAgICB9IHdoaWxlIChjb3VudCA+PSAwKTsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIEFycmF5IGNvbXBpbGVycworI2VuZGlmCisKK3ZvaWQgY29tcGlsZUVsZW1lbnRfX2dlbmVyaWMob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdiwgR0xpbnQgZmlyc3QpCit7CisgICAgdi0+ZmxhZ3MgPSAwOworICAgIHYtPmluZGV4ID0gZmlyc3Q7CisgICAgZmlyc3QgJj0gdmVydGV4X2NhY2hlX3Q6OklOREVYX01BU0s7CisgICAgY29uc3QgR0x1Ynl0ZSogdnAgPSBjLT5hcnJheXMudmVydGV4LmVsZW1lbnQoZmlyc3QpOworICAgIGMtPmFycmF5cy52ZXJ0ZXguZmV0Y2goYywgdi0+b2JqLnYsIHZwKTsKKyAgICBjLT5hcnJheXMubXZwX3RyYW5zZm9ybSgmYy0+dHJhbnNmb3Jtcy5tdnAsICZ2LT5jbGlwLCAmdi0+b2JqKTsKKyAgICBjLT5hcnJheXMucGVyc3BlY3RpdmUoYywgdik7Cit9CisKK3ZvaWQgY29tcGlsZUVsZW1lbnRzX19nZW5lcmljKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KQoreworICAgIGNvbnN0IEdMdWJ5dGUqIHZwID0gYy0+YXJyYXlzLnZlcnRleC5lbGVtZW50KAorICAgICAgICAgICAgZmlyc3QgJiB2ZXJ0ZXhfY2FjaGVfdDo6SU5ERVhfTUFTSyk7CisgICAgY29uc3Qgc2l6ZV90IHN0cmlkZSA9IGMtPmFycmF5cy52ZXJ0ZXguc3RyaWRlOworICAgIHRyYW5zZm9ybV90IGNvbnN0KiBjb25zdCBtdnAgPSAmYy0+dHJhbnNmb3Jtcy5tdnA7CisgICAgZG8geworICAgICAgICB2LT5mbGFncyA9IDA7CisgICAgICAgIHYtPmluZGV4ID0gZmlyc3QrKzsKKyAgICAgICAgYy0+YXJyYXlzLnZlcnRleC5mZXRjaChjLCB2LT5vYmoudiwgdnApOworICAgICAgICBjLT5hcnJheXMubXZwX3RyYW5zZm9ybShtdnAsICZ2LT5jbGlwLCAmdi0+b2JqKTsKKyAgICAgICAgYy0+YXJyYXlzLnBlcnNwZWN0aXZlKGMsIHYpOworICAgICAgICB2cCArPSBzdHJpZGU7CisgICAgICAgIHYrKzsKKyAgICB9IHdoaWxlICgtLWNvdW50KTsKK30KKworLyoKK3ZvaWQgY29tcGlsZUVsZW1lbnRzX18zeF9mdWxsKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KQoreworICAgIGNvbnN0IEdMZml4ZWQqIHZwID0gKGNvbnN0IEdMZml4ZWQqKWMtPmFycmF5cy52ZXJ0ZXguZWxlbWVudChmaXJzdCk7CisgICAgY29uc3Qgc2l6ZV90IHN0cmlkZSA9IGMtPmFycmF5cy52ZXJ0ZXguc3RyaWRlIC8gNDsKKy8vICAgIGNvbnN0IEdMZml4ZWQqIGNvbnN0JiBtID0gYy0+dHJhbnNmb3Jtcy5tdnAubWF0cml4Lm07CisgICAgCisgICAgR0xmaXhlZCBtWzE2XTsKKyAgICBtZW1jcHkoJm0sIGMtPnRyYW5zZm9ybXMubXZwLm1hdHJpeC5tLCBzaXplb2YobSkpOworICAgIAorICAgIGRvIHsKKyAgICAgICAgY29uc3QgR0xmaXhlZCByeCA9IHZwWzBdOworICAgICAgICBjb25zdCBHTGZpeGVkIHJ5ID0gdnBbMV07CisgICAgICAgIGNvbnN0IEdMZml4ZWQgcnogPSB2cFsyXTsKKyAgICAgICAgdnAgKz0gc3RyaWRlOworICAgICAgICB2LT5pbmRleCA9IGZpcnN0Kys7CisgICAgICAgIHYtPmNsaXAueCA9IG1sYTNhKHJ4LCBtWyAwXSwgcnksIG1bIDRdLCByeiwgbVsgOF0sIG1bMTJdKTsgCisgICAgICAgIHYtPmNsaXAueSA9IG1sYTNhKHJ4LCBtWyAxXSwgcnksIG1bIDVdLCByeiwgbVsgOV0sIG1bMTNdKTsKKyAgICAgICAgdi0+Y2xpcC56ID0gbWxhM2EocngsIG1bIDJdLCByeSwgbVsgNl0sIHJ6LCBtWzEwXSwgbVsxNF0pOworICAgICAgICB2LT5jbGlwLncgPSBtbGEzYShyeCwgbVsgM10sIHJ5LCBtWyA3XSwgcnosIG1bMTFdLCBtWzE1XSk7CisKKyAgICAgICAgY29uc3QgR0xmaXhlZCB3ID0gdi0+Y2xpcC53OworICAgICAgICB1aW50MzJfdCBjbGlwID0gMDsKKyAgICAgICAgaWYgKHYtPmNsaXAueCA8IC13KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfTDsKKyAgICAgICAgaWYgKHYtPmNsaXAueCA+ICB3KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfUjsKKyAgICAgICAgaWYgKHYtPmNsaXAueSA8IC13KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfQjsKKyAgICAgICAgaWYgKHYtPmNsaXAueSA+ICB3KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfVDsKKyAgICAgICAgaWYgKHYtPmNsaXAueiA8IC13KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfTjsKKyAgICAgICAgaWYgKHYtPmNsaXAueiA+ICB3KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfRjsKKyAgICAgICAgdi0+ZmxhZ3MgPSBjbGlwOworICAgICAgICBjLT5hcnJheXMuY3VsbCAmPSBjbGlwOworCisgICAgICAgIC8vYy0+YXJyYXlzLnBlcnNwZWN0aXZlKGMsIHYpOworICAgICAgICB2Kys7CisgICAgfSB3aGlsZSAoLS1jb3VudCk7Cit9CisqLworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBjbGlwcGVycworI2VuZGlmCisKK3N0YXRpYyB2b2lkIGNsaXBWZWM0KHZlYzRfdCYgbnYsIAorICAgICAgICBHTGZpeGVkIHQsIGNvbnN0IHZlYzRfdCYgcywgY29uc3QgdmVjNF90JiBwKQoreworICAgIGZvciAoaW50IGk9MDsgaTw0IDsgaSsrKQorICAgICAgICBudi52W2ldID0gZ2dsTXVsQWRkeCh0LCBzLnZbaV0gLSBwLnZbaV0sIHAudltpXSwgMjgpOworfQorCitzdGF0aWMgdm9pZCBjbGlwVmVydGV4KG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIG52LAorICAgICAgICBHTGZpeGVkIHQsIGNvbnN0IHZlcnRleF90KiBzLCBjb25zdCB2ZXJ0ZXhfdCogcCkKK3sKKyAgICBjbGlwVmVjNChudi0+Y2xpcCwgdCwgcy0+Y2xpcCwgcC0+Y2xpcCk7CisgICAgbnYtPmZvZyA9IGdnbE11bEFkZHgodCwgcy0+Zm9nIC0gcC0+Zm9nLCBwLT5mb2csIDI4KTsKKyAgICBvZ2xlc192ZXJ0ZXhfcHJvamVjdChjLCBudik7CisgICAgbnYtPmZsYWdzIHw9ICB2ZXJ0ZXhfdDo6TElUIHwgdmVydGV4X3Q6OkVZRSB8IHZlcnRleF90OjpUVDsKKyAgICBudi0+ZmxhZ3MgJj0gfnZlcnRleF90OjpDTElQX0FMTDsKK30KKworc3RhdGljIHZvaWQgY2xpcFZlcnRleEMob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogbnYsCisgICAgICAgIEdMZml4ZWQgdCwgY29uc3QgdmVydGV4X3QqIHMsIGNvbnN0IHZlcnRleF90KiBwKQoreworICAgIGNsaXBWZWM0KG52LT5jb2xvciwgdCwgcy0+Y29sb3IsIHAtPmNvbG9yKTsKKyAgICBjbGlwVmVydGV4KGMsIG52LCB0LCBzLCBwKTsKK30KKworc3RhdGljIHZvaWQgY2xpcFZlcnRleFQob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogbnYsCisgICAgICAgIEdMZml4ZWQgdCwgY29uc3QgdmVydGV4X3QqIHMsIGNvbnN0IHZlcnRleF90KiBwKQoreworICAgIGZvciAoaW50IGk9MCA7IGk8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IGkrKykgeworICAgICAgICBpZiAoYy0+cmFzdGVyaXplci5zdGF0ZS50ZXh0dXJlW2ldLmVuYWJsZSkKKyAgICAgICAgICAgIGNsaXBWZWM0KG52LT50ZXh0dXJlW2ldLCB0LCBzLT50ZXh0dXJlW2ldLCBwLT50ZXh0dXJlW2ldKTsKKyAgICB9CisgICAgY2xpcFZlcnRleChjLCBudiwgdCwgcywgcCk7Cit9CisKK3N0YXRpYyB2b2lkIGNsaXBWZXJ0ZXhBbGwob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogbnYsCisgICAgICAgIEdMZml4ZWQgdCwgY29uc3QgdmVydGV4X3QqIHMsIGNvbnN0IHZlcnRleF90KiBwKQoreworICAgIGNsaXBWZWM0KG52LT5jb2xvciwgdCwgcy0+Y29sb3IsIHAtPmNvbG9yKTsKKyAgICBjbGlwVmVydGV4VChjLCBudiwgdCwgcywgcCk7Cit9CisKK3N0YXRpYyB2b2lkIGNsaXBFeWUob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogbnYsCisgICAgICAgIEdMZml4ZWQgdCwgY29uc3QgdmVydGV4X3QqIHMsIGNvbnN0IHZlcnRleF90KiBwKQoreworICAgIG52LT5jbGVhcigpOworICAgIGMtPmFycmF5cy5jbGlwVmVydGV4KGMsIG52LCB0LCBwLCBzKTsKKyAgICBjbGlwVmVjNChudi0+ZXllLCB0LCBzLT5leWUsIHAtPmV5ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK3ZvaWQgdmFsaWRhdGVfYXJyYXlzKG9nbGVzX2NvbnRleHRfdCogYywgR0xlbnVtIG1vZGUpCit7CisgICAgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKworICAgIC8vIFBlcnNwZWN0aXZlIGNvcnJlY3Rpb24gaXMgbm90IG5lZWQgaWYgT3J0aG8gdHJhbnNmb3JtLCBidXQKKyAgICAvLyB0aGUgdXNlciBjYW4gc3RpbGwgcHJvdmlkZSB0aGUgdyBjb29yZGluYXRlIG1hbnVhbGx5LCBzbyB3ZSBjYW4ndAorICAgIC8vIGF1dG9tYXRpY2FsbHkgdHVybiBpdCBvZmYgKGluIGZhY3Qgd2UgY291bGQgd2hlbiB0aGUgNHRoIGNvb3JkaW5hdGUKKyAgICAvLyBpcyBub3Qgc3BjaWZpZWQgaW4gdGhlIHZlcnRleCBhcnJheSkuCisgICAgLy8gVyBpbnRlcnBvbGF0aW9uIGlzIG5ldmVyIG5lZWRlZCBmb3IgcG9pbnRzLgorICAgIEdMYm9vbGVhbiBwZXJzcGVjdGl2ZSA9IAorICAgICAgICBjLT5wZXJzcGVjdGl2ZSAmJiBtb2RlIT1HTF9QT0lOVFMgJiYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX1RNVVMpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZW5hYmxlRGlzYWJsZShjLCBHR0xfV19MRVJQLCBwZXJzcGVjdGl2ZSk7CisgICAgCisgICAgLy8gc2V0IGFudGktYWxpYXNpbmcKKyAgICBHTGJvb2xlYW4gc21vb3RoID0gR0xfRkFMU0U7CisgICAgc3dpdGNoIChtb2RlKSB7CisgICAgY2FzZSBHTF9QT0lOVFM6CisgICAgICAgIHNtb290aCA9IGMtPnBvaW50LnNtb290aDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9MSU5FUzoKKyAgICBjYXNlIEdMX0xJTkVfTE9PUDoKKyAgICBjYXNlIEdMX0xJTkVfU1RSSVA6CisgICAgICAgIHNtb290aCA9IGMtPmxpbmUuc21vb3RoOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgaWYgKCgoZW5hYmxlcyAmIEdHTF9FTkFCTEVfQUEpPzE6MCkgIT0gc21vb3RoKQorICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmVuYWJsZURpc2FibGUoYywgR0dMX0FBLCBzbW9vdGgpOworCisgICAgLy8gc2V0IHRoZSBzaGFkZSBtb2RlbCBmb3IgdGhpcyBwcmltaXRpdmUKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnNoYWRlTW9kZWwoYywKKyAgICAgICAgICAgIChtb2RlID09IEdMX1BPSU5UUykgPyBHTF9GTEFUIDogYy0+bGlnaHRpbmcuc2hhZGVNb2RlbCk7CisKKyAgICAvLyBjb21wdXRlIGFsbCB0aGUgbWF0cmljZXMgd2UnbGwgbmVlZC4uLgorICAgIHVpbnQzMl90IHdhbnQgPQorICAgICAgICAgICAgdHJhbnNmb3JtX3N0YXRlX3Q6Ok1WUCB8CisgICAgICAgICAgICB0cmFuc2Zvcm1fc3RhdGVfdDo6VklFV1BPUlQ7CisgICAgaWYgKGMtPmxpZ2h0aW5nLmVuYWJsZSkgeyAvLyBuZWVkcyBub3JtYWwgdHJhbnNmb3JtcyBhbmQgZXllIGNvb3JkcworICAgICAgICB3YW50IHw9IHRyYW5zZm9ybV9zdGF0ZV90OjpNVlVJOworICAgICAgICB3YW50IHw9IHRyYW5zZm9ybV9zdGF0ZV90OjpNT0RFTFZJRVc7CisgICAgfQorICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKSB7IC8vIG5lZWRzIHRleHR1cmUgdHJhbnNmb3JtcworICAgICAgICB3YW50IHw9IHRyYW5zZm9ybV9zdGF0ZV90OjpURVhUVVJFOworICAgIH0KKyAgICBpZiAoYy0+Y2xpcFBsYW5lcy5lbmFibGUgfHwgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0ZPRykpIHsgCisgICAgICAgIHdhbnQgfD0gdHJhbnNmb3JtX3N0YXRlX3Q6Ok1PREVMVklFVzsgLy8gbmVlZHMgZXllIGNvb3JkcworICAgIH0KKyAgICBvZ2xlc192YWxpZGF0ZV90cmFuc2Zvcm0oYywgd2FudCk7CisKKyAgICAvLyB0ZXh0dXJlcy4uLgorICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKQorICAgICAgICBvZ2xlc192YWxpZGF0ZV90ZXh0dXJlKGMpOworCisgICAgLy8gdmVydGV4IGNvbXBpbGVycworICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudCA9IGNvbXBpbGVFbGVtZW50X19nZW5lcmljOworICAgIGMtPmFycmF5cy5jb21waWxlRWxlbWVudHMgPSBjb21waWxlRWxlbWVudHNfX2dlbmVyaWM7CisKKyAgICAvLyB2ZXJ0ZXggdHJhbnNmb3JtCisgICAgYy0+YXJyYXlzLm12cF90cmFuc2Zvcm0gPQorICAgICAgICBjLT50cmFuc2Zvcm1zLm12cC5wb2ludHZbYy0+YXJyYXlzLnZlcnRleC5zaXplIC0gMl07CisKKyAgICBjLT5hcnJheXMubXZfdHJhbnNmb3JtID0KKyAgICAgICAgYy0+dHJhbnNmb3Jtcy5tb2RlbHZpZXcudHJhbnNmb3JtLnBvaW50dltjLT5hcnJheXMudmVydGV4LnNpemUgLSAyXTsKKyAgICAKKyAgICAvKgorICAgICAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICogIHBpY2sgZmV0Y2hlcnMKKyAgICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqLworICAgIAorICAgIGFycmF5X21hY2hpbmVfdCYgYW0gPSBjLT5hcnJheXM7CisgICAgYW0udmVydGV4LmZldGNoID0gZmV0Y2hOb3A7CisgICAgYW0ubm9ybWFsLmZldGNoID0gY3VycmVudE5vcm1hbDsKKyAgICBhbS5jb2xvci5mZXRjaCA9IGN1cnJlbnRDb2xvcjsKKyAgICAKKyAgICBpZiAoYW0udmVydGV4LmVuYWJsZSkgeworICAgICAgICBhbS52ZXJ0ZXgucmVzb2x2ZSgpOworICAgICAgICBpZiAoYW0udmVydGV4LmJvIHx8IGFtLnZlcnRleC5wb2ludGVyKSB7CisgICAgICAgICAgICBhbS52ZXJ0ZXguZmV0Y2ggPSB2ZXJ0ZXhfZmN0W2FtLnZlcnRleC5zaXplLTJdW2FtLnZlcnRleC50eXBlICYgMHhGXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChhbS5ub3JtYWwuZW5hYmxlKSB7CisgICAgICAgIGFtLm5vcm1hbC5yZXNvbHZlKCk7CisgICAgICAgIGlmIChhbS5ub3JtYWwuYm8gfHwgYW0ubm9ybWFsLnBvaW50ZXIpIHsKKyAgICAgICAgICAgIGFtLm5vcm1hbC5mZXRjaCA9IG5vcm1hbF9mY3RbYW0ubm9ybWFsLnNpemUtM11bYW0ubm9ybWFsLnR5cGUgJiAweEZdOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGFtLmNvbG9yLmVuYWJsZSkgeworICAgICAgICBhbS5jb2xvci5yZXNvbHZlKCk7CisgICAgICAgIGlmIChjLT5saWdodGluZy5lbmFibGUpIHsKKyAgICAgICAgICAgIGlmIChhbS5jb2xvci5ibyB8fCBhbS5jb2xvci5wb2ludGVyKSB7CisgICAgICAgICAgICAgICAgYW0uY29sb3IuZmV0Y2ggPSBjb2xvcl9mY3RbYW0uY29sb3Iuc2l6ZS0zXVthbS5jb2xvci50eXBlICYgMHhGXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChhbS5jb2xvci5ibyB8fCBhbS5jb2xvci5wb2ludGVyKSB7CisgICAgICAgICAgICAgICAgYW0uY29sb3IuZmV0Y2ggPSBjb2xvcl9jbGFtcF9mY3RbYW0uY29sb3Iuc2l6ZS0zXVthbS5jb2xvci50eXBlICYgMHhGXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGludCBhY3RpdmVUbXVDb3VudCA9IDA7CisgICAgZm9yIChpbnQgaT0wIDsgaTxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgaSsrKSB7CisgICAgICAgIGFtLnRleHR1cmVbaV0uZmV0Y2ggPSBjdXJyZW50VGV4Q29vcmQ7CisgICAgICAgIGlmIChjLT5yYXN0ZXJpemVyLnN0YXRlLnRleHR1cmVbaV0uZW5hYmxlKSB7CisKKyAgICAgICAgICAgIC8vIHRleHR1cmUgZmV0Y2hlcnMuLi4KKyAgICAgICAgICAgIGlmIChhbS50ZXh0dXJlW2ldLmVuYWJsZSkgeworICAgICAgICAgICAgICAgIGFtLnRleHR1cmVbaV0ucmVzb2x2ZSgpOworICAgICAgICAgICAgICAgIGlmIChhbS50ZXh0dXJlW2ldLmJvIHx8IGFtLnRleHR1cmVbaV0ucG9pbnRlcikgeworICAgICAgICAgICAgICAgICAgICBhbS50ZXh0dXJlW2ldLmZldGNoID0gdGV4dHVyZV9mY3RbYW0udGV4dHVyZVtpXS5zaXplLTJdW2FtLnRleHR1cmVbaV0udHlwZSAmIDB4Rl07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXh0dXJlIHRyYW5zZm9ybS4uLgorICAgICAgICAgICAgY29uc3QgaW50IGluZGV4ID0gYy0+YXJyYXlzLnRleHR1cmVbaV0uc2l6ZSAtIDI7CisgICAgICAgICAgICBjLT5hcnJheXMudGV4X3RyYW5zZm9ybVtpXSA9CisgICAgICAgICAgICAgICAgYy0+dHJhbnNmb3Jtcy50ZXh0dXJlW2ldLnRyYW5zZm9ybS5wb2ludHZbaW5kZXhdOworCisgICAgICAgICAgICBhbS50bXUgPSBpOworICAgICAgICAgICAgYWN0aXZlVG11Q291bnQrKzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHBpY2sgdGhlIHZlcnRleC1jbGlwcGVyCisgICAgdWludDMyX3QgY2xpcHBlciA9IDA7CisgICAgLy8gd2UgbXVzdCByZWxvYWQgJ2VuYWJsZXMnIGhlcmUKKyAgICBlbmFibGVzID0gYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzOworICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9TTU9PVEgpCisgICAgICAgIGNsaXBwZXIgfD0gMTsgICAvLyB3ZSBuZWVkIHRvIGludGVycG9sYXRlIGNvbG9ycworICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKQorICAgICAgICBjbGlwcGVyIHw9IDI7ICAgLy8gd2UgbmVlZCB0byBpbnRlcnBvbGF0ZSB0ZXh0dXJlcworICAgIHN3aXRjaCAoY2xpcHBlcikgeworICAgIGNhc2UgMDogYy0+YXJyYXlzLmNsaXBWZXJ0ZXggPSBjbGlwVmVydGV4OyAgICAgIGJyZWFrOworICAgIGNhc2UgMTogYy0+YXJyYXlzLmNsaXBWZXJ0ZXggPSBjbGlwVmVydGV4QzsgICAgIGJyZWFrOworICAgIGNhc2UgMjogYy0+YXJyYXlzLmNsaXBWZXJ0ZXggPSBjbGlwVmVydGV4VDsgICAgIGJyZWFrOworICAgIGNhc2UgMzogYy0+YXJyYXlzLmNsaXBWZXJ0ZXggPSBjbGlwVmVydGV4QWxsOyAgIGJyZWFrOworICAgIH0KKyAgICBjLT5hcnJheXMuY2xpcEV5ZSA9IGNsaXBFeWU7CisKKyAgICAvLyBwaWNrIHRoZSBwcmltaXRpdmUgcmFzdGVyaXplcgorICAgIG9nbGVzX3ZhbGlkYXRlX3ByaW1pdGl2ZXMoYyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3VzaW5nIG5hbWVzcGFjZSBhbmRyb2lkOworCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBhcnJheSBBUEkKKyNlbmRpZgorCit2b2lkIGdsVmVydGV4UG9pbnRlcigKKyAgICBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChzaXplPDIgfHwgc2l6ZT40IHx8IHN0cmlkZTwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgR0xfQllURToKKyAgICBjYXNlIEdMX1NIT1JUOgorICAgIGNhc2UgR0xfRklYRUQ6CisgICAgY2FzZSBHTF9GTE9BVDoKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT5hcnJheXMudmVydGV4LmluaXQoc2l6ZSwgdHlwZSwgc3RyaWRlLCBwb2ludGVyLCBjLT5hcnJheXMuYXJyYXlfYnVmZmVyLCAwKTsKK30KKwordm9pZCBnbENvbG9yUG9pbnRlcigKKyAgICBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIC8vIGluIHRoZW9yeSBvZ2xlcyBkb2Vzbid0IGFsbG93IGNvbG9yIGFycmF5cyBvZiBzaXplIDMKKyAgICAvLyBidXQgaXQgaXMgdmVyeSB1c2VmdWwgdG8gJ3Zpc3VhbGl6ZScgdGhlIG5vcm1hbCBhcnJheS4KKyAgICBpZiAoc2l6ZTwzIHx8IHNpemU+NCB8fCBzdHJpZGU8MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEdMX1VOU0lHTkVEX0JZVEU6CisgICAgY2FzZSBHTF9GSVhFRDoKKyAgICBjYXNlIEdMX0ZMT0FUOgorICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPmFycmF5cy5jb2xvci5pbml0KHNpemUsIHR5cGUsIHN0cmlkZSwgcG9pbnRlciwgYy0+YXJyYXlzLmFycmF5X2J1ZmZlciwgMCk7Cit9CisKK3ZvaWQgZ2xOb3JtYWxQb2ludGVyKAorICAgIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHN0cmlkZTwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgR0xfQllURToKKyAgICBjYXNlIEdMX1NIT1JUOgorICAgIGNhc2UgR0xfRklYRUQ6CisgICAgY2FzZSBHTF9GTE9BVDoKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT5hcnJheXMubm9ybWFsLmluaXQoMywgdHlwZSwgc3RyaWRlLCBwb2ludGVyLCBjLT5hcnJheXMuYXJyYXlfYnVmZmVyLCAwKTsKK30KKwordm9pZCBnbFRleENvb3JkUG9pbnRlcigKKyAgICBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChzaXplPDIgfHwgc2l6ZT40IHx8IHN0cmlkZTwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgR0xfQllURToKKyAgICBjYXNlIEdMX1NIT1JUOgorICAgIGNhc2UgR0xfRklYRUQ6CisgICAgY2FzZSBHTF9GTE9BVDoKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBpbnQgdG11ID0gYy0+YXJyYXlzLmFjdGl2ZVRleHR1cmU7CisgICAgYy0+YXJyYXlzLnRleHR1cmVbdG11XS5pbml0KHNpemUsIHR5cGUsIHN0cmlkZSwgcG9pbnRlciwKKyAgICAgICAgICAgIGMtPmFycmF5cy5hcnJheV9idWZmZXIsIDApOworfQorCisKK3ZvaWQgZ2xFbmFibGVDbGllbnRTdGF0ZShHTGVudW0gYXJyYXkpIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGVuYWJsZURpc2FibGVDbGllbnRTdGF0ZShjLCBhcnJheSwgdHJ1ZSk7Cit9CisKK3ZvaWQgZ2xEaXNhYmxlQ2xpZW50U3RhdGUoR0xlbnVtIGFycmF5KSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBlbmFibGVEaXNhYmxlQ2xpZW50U3RhdGUoYywgYXJyYXksIGZhbHNlKTsKK30KKwordm9pZCBnbENsaWVudEFjdGl2ZVRleHR1cmUoR0xlbnVtIHRleHR1cmUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAodGV4dHVyZTxHTF9URVhUVVJFMCB8fCB0ZXh0dXJlPj1HTF9URVhUVVJFMCtHR0xfVEVYVFVSRV9VTklUX0NPVU5UKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYy0+YXJyYXlzLmFjdGl2ZVRleHR1cmUgPSB0ZXh0dXJlIC0gR0xfVEVYVFVSRTA7Cit9CisKK3ZvaWQgZ2xEcmF3QXJyYXlzKEdMZW51bSBtb2RlLCBHTGludCBmaXJzdCwgR0xzaXplaSBjb3VudCkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChjb3VudDwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHN3aXRjaCAobW9kZSkgeworICAgIGNhc2UgR0xfUE9JTlRTOgorICAgIGNhc2UgR0xfTElORV9TVFJJUDoKKyAgICBjYXNlIEdMX0xJTkVfTE9PUDoKKyAgICBjYXNlIEdMX0xJTkVTOgorICAgIGNhc2UgR0xfVFJJQU5HTEVfU1RSSVA6CisgICAgY2FzZSBHTF9UUklBTkdMRV9GQU46CisgICAgY2FzZSBHTF9UUklBTkdMRVM6CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoY291bnQgPT0gMCB8fCAhYy0+YXJyYXlzLnZlcnRleC5lbmFibGUpCisgICAgICAgIHJldHVybjsKKyAgICBpZiAoKGMtPmN1bGwuZW5hYmxlKSAmJiAoYy0+Y3VsbC5jdWxsRmFjZSA9PSBHTF9GUk9OVF9BTkRfQkFDSykpCisgICAgICAgIHJldHVybjsgLy8gYWxsIHRyaWFuZ2xlcyBhcmUgY3VsbGVkCisKKyAgICB2YWxpZGF0ZV9hcnJheXMoYywgbW9kZSk7CisgICAgZHJhd0FycmF5c1ByaW1zW21vZGVdKGMsIGZpcnN0LCBjb3VudCk7CisKKyNpZiBWQ19DQUNIRV9TVEFUSVNUSUNTCisgICAgYy0+dmMudG90YWwgPSBjb3VudDsKKyAgICBjLT52Yy5kdW1wX3N0YXRzKG1vZGUpOworI2VuZGlmCit9CisKK3ZvaWQgZ2xEcmF3RWxlbWVudHMoCisgICAgR0xlbnVtIG1vZGUsIEdMc2l6ZWkgY291bnQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKmluZGljZXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoY291bnQ8MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICBjYXNlIEdMX1BPSU5UUzoKKyAgICBjYXNlIEdMX0xJTkVfU1RSSVA6CisgICAgY2FzZSBHTF9MSU5FX0xPT1A6CisgICAgY2FzZSBHTF9MSU5FUzoKKyAgICBjYXNlIEdMX1RSSUFOR0xFX1NUUklQOgorICAgIGNhc2UgR0xfVFJJQU5HTEVfRkFOOgorICAgIGNhc2UgR0xfVFJJQU5HTEVTOgorICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgR0xfVU5TSUdORURfQllURToKKyAgICBjYXNlIEdMX1VOU0lHTkVEX1NIT1JUOgorICAgICAgICBjLT5hcnJheXMuaW5kaWNlc1R5cGUgPSB0eXBlOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChjb3VudCA9PSAwIHx8ICFjLT5hcnJheXMudmVydGV4LmVuYWJsZSkKKyAgICAgICAgcmV0dXJuOworICAgIGlmICgoYy0+Y3VsbC5lbmFibGUpICYmIChjLT5jdWxsLmN1bGxGYWNlID09IEdMX0ZST05UX0FORF9CQUNLKSkKKyAgICAgICAgcmV0dXJuOyAvLyBhbGwgdHJpYW5nbGVzIGFyZSBjdWxsZWQKKworICAgIC8vIGNsZWFyIHRoZSB2ZXJ0ZXgtY2FjaGUKKyAgICBjLT52Yy5jbGVhcigpOworICAgIHZhbGlkYXRlX2FycmF5cyhjLCBtb2RlKTsKKyAgICAKKyAgICAvLyBpZiBpbmRpY2VzIGFyZSBpbiBhIGJ1ZmZlciBvYmplY3QsIHRoZSBwb2ludGVyIGlzIHRyZWF0ZWQgYXMgYW4KKyAgICAvLyBvZmZzZXQgaW4gdGhhdCBidWZmZXIuCisgICAgaWYgKGMtPmFycmF5cy5lbGVtZW50X2FycmF5X2J1ZmZlcikgeworICAgICAgICBpbmRpY2VzID0gYy0+YXJyYXlzLmVsZW1lbnRfYXJyYXlfYnVmZmVyLT5kYXRhICsgdWludHB0cl90KGluZGljZXMpOworICAgIH0KKworICAgIGRyYXdFbGVtZW50c1ByaW1zW21vZGVdKGMsIGNvdW50LCBpbmRpY2VzKTsKKworI2lmIFZDX0NBQ0hFX1NUQVRJU1RJQ1MKKyAgICBjLT52Yy50b3RhbCA9IGNvdW50OworICAgIGMtPnZjLmR1bXBfc3RhdHMobW9kZSk7CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gYnVmZmVycworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIGdsQmluZEJ1ZmZlcihHTGVudW0gdGFyZ2V0LCBHTHVpbnQgYnVmZmVyKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKCh0YXJnZXQhPUdMX0FSUkFZX0JVRkZFUikgJiYgKHRhcmdldCE9R0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gY3JlYXRlIGEgYnVmZmVyIG9iamVjdCwgb3IgYmluZCBhbiBleGlzdGluZyBvbmUKKyAgICBidWZmZXJfdCBjb25zdCogYm8gPSAwOworICAgIGlmIChidWZmZXIpIHsKKyAgICAgICAgYm8gPSBjLT5idWZmZXJPYmplY3RNYW5hZ2VyLT5iaW5kKGJ1ZmZlcik7CisgICAgICAgIGlmICghYm8pIHsKKyAgICAgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX09VVF9PRl9NRU1PUlkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorICAgICgodGFyZ2V0ID09IEdMX0FSUkFZX0JVRkZFUikgPyAKKyAgICAgICAgICAgIGMtPmFycmF5cy5hcnJheV9idWZmZXIgOiBjLT5hcnJheXMuZWxlbWVudF9hcnJheV9idWZmZXIpID0gYm87Cit9CisKK3ZvaWQgZ2xCdWZmZXJEYXRhKEdMZW51bSB0YXJnZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkKiBkYXRhLCBHTGVudW0gdXNhZ2UpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoKHRhcmdldCE9R0xfQVJSQVlfQlVGRkVSKSAmJiAodGFyZ2V0IT1HTF9FTEVNRU5UX0FSUkFZX0JVRkZFUikpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoc2l6ZTwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmICgodXNhZ2UhPUdMX1NUQVRJQ19EUkFXKSAmJiAodXNhZ2UhPUdMX0RZTkFNSUNfRFJBVykpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBidWZmZXJfdCBjb25zdCogYm8gPSAoKHRhcmdldCA9PSBHTF9BUlJBWV9CVUZGRVIpID8gCisgICAgICAgICAgICBjLT5hcnJheXMuYXJyYXlfYnVmZmVyIDogYy0+YXJyYXlzLmVsZW1lbnRfYXJyYXlfYnVmZmVyKTsKKworICAgIGlmIChibyA9PSAwKSB7CisgICAgICAgIC8vIGNhbid0IG1vZGlmeSBidWZmZXIgMAorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX09QRVJBVElPTik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBidWZmZXJfdCogZWRpdF9ibyA9IGNvbnN0X2Nhc3Q8YnVmZmVyX3QqPihibyk7CisgICAgaWYgKGMtPmJ1ZmZlck9iamVjdE1hbmFnZXItPmFsbG9jYXRlU3RvcmUoZWRpdF9ibywgc2l6ZSwgdXNhZ2UpICE9IDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfT1VUX09GX01FTU9SWSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGRhdGEpIHsKKyAgICAgICAgbWVtY3B5KGJvLT5kYXRhLCBkYXRhLCBzaXplKTsKKyAgICB9Cit9CisKK3ZvaWQgZ2xCdWZmZXJTdWJEYXRhKEdMZW51bSB0YXJnZXQsIEdMaW50cHRyIG9mZnNldCwgR0xzaXplaXB0ciBzaXplLCBjb25zdCBHTHZvaWQqIGRhdGEpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoKHRhcmdldCE9R0xfQVJSQVlfQlVGRkVSKSAmJiAodGFyZ2V0IT1HTF9FTEVNRU5UX0FSUkFZX0JVRkZFUikpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAob2Zmc2V0PDAgfHwgc2l6ZTwwIHx8IGRhdGE9PTApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYnVmZmVyX3QgY29uc3QqIGJvID0gKCh0YXJnZXQgPT0gR0xfQVJSQVlfQlVGRkVSKSA/IAorICAgICAgICAgICAgYy0+YXJyYXlzLmFycmF5X2J1ZmZlciA6IGMtPmFycmF5cy5lbGVtZW50X2FycmF5X2J1ZmZlcik7CisKKyAgICBpZiAoYm8gPT0gMCkgeworICAgICAgICAvLyBjYW4ndCBtb2RpZnkgYnVmZmVyIDAKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9PUEVSQVRJT04pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChvZmZzZXQrc2l6ZSA+IGJvLT5zaXplKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIG1lbWNweShiby0+ZGF0YSArIG9mZnNldCwgZGF0YSwgc2l6ZSk7Cit9CisKK3ZvaWQgZ2xEZWxldGVCdWZmZXJzKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50KiBidWZmZXJzKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKG48MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGZvciAoaW50IGk9MCA7IGk8biA7IGkrKykgeworICAgICAgICBHTHVpbnQgbmFtZSA9IGJ1ZmZlcnNbaV07CisgICAgICAgIGlmIChuYW1lKSB7CisgICAgICAgICAgICAvLyB1bmJpbmQgYm91bmQgZGVsZXRlZCBidWZmZXJzLi4uCisgICAgICAgICAgICBpZiAoYy0+YXJyYXlzLmVsZW1lbnRfYXJyYXlfYnVmZmVyLT5uYW1lID09IG5hbWUpIHsKKyAgICAgICAgICAgICAgICBjLT5hcnJheXMuZWxlbWVudF9hcnJheV9idWZmZXIgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGMtPmFycmF5cy5hcnJheV9idWZmZXItPm5hbWUgPT0gbmFtZSkgeworICAgICAgICAgICAgICAgIGMtPmFycmF5cy5hcnJheV9idWZmZXIgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGMtPmFycmF5cy52ZXJ0ZXguYm8tPm5hbWUgPT0gbmFtZSkgeworICAgICAgICAgICAgICAgIGMtPmFycmF5cy52ZXJ0ZXguYm8gPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGMtPmFycmF5cy5ub3JtYWwuYm8tPm5hbWUgPT0gbmFtZSkgeworICAgICAgICAgICAgICAgIGMtPmFycmF5cy5ub3JtYWwuYm8gPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGMtPmFycmF5cy5jb2xvci5iby0+bmFtZSA9PSBuYW1lKSB7CisgICAgICAgICAgICAgICAgYy0+YXJyYXlzLmNvbG9yLmJvID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaW50IHQ9MCA7IHQ8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IHQrKykgeworICAgICAgICAgICAgICAgIGlmIChjLT5hcnJheXMudGV4dHVyZVt0XS5iby0+bmFtZSA9PSBuYW1lKSB7CisgICAgICAgICAgICAgICAgICAgIGMtPmFycmF5cy50ZXh0dXJlW3RdLmJvID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9ICAgIAorICAgIGMtPmJ1ZmZlck9iamVjdE1hbmFnZXItPmRlbGV0ZUJ1ZmZlcnMobiwgYnVmZmVycyk7CisgICAgYy0+YnVmZmVyT2JqZWN0TWFuYWdlci0+cmVjeWNsZVRva2VucyhuLCBidWZmZXJzKTsKK30KKwordm9pZCBnbEdlbkJ1ZmZlcnMoR0xzaXplaSBuLCBHTHVpbnQqIGJ1ZmZlcnMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAobjwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPmJ1ZmZlck9iamVjdE1hbmFnZXItPmdldFRva2VuKG4sIGJ1ZmZlcnMpOworfQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9hcnJheS5oIGIvb3BlbmdsL2xpYmFnbC9hcnJheS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxNTY5NzgKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL2FycmF5LmgKQEAgLTAsMCArMSwzNyBAQAorLyogbGlicy9vcGVuZ2xlcy9hcnJheS5oCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2lmbmRlZiBBTkRST0lEX09QRU5HTEVTX0FSUkFZX0gKKyNkZWZpbmUgQU5EUk9JRF9PUEVOR0xFU19BUlJBWV9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCituYW1lc3BhY2UgZ2wgeworc3RydWN0IG9nbGVzX2NvbnRleHRfdDsKK307CisKK3ZvaWQgb2dsZXNfaW5pdF9hcnJheShvZ2xlc19jb250ZXh0X3QqIGMpOwordm9pZCBvZ2xlc191bmluaXRfYXJyYXkob2dsZXNfY29udGV4dF90KiBjKTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfT1BFTkdMRVNfQVJSQVlfSAorCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL2NvbnRleHQuaCBiL29wZW5nbC9saWJhZ2wvY29udGV4dC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmMzZiNTYKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL2NvbnRleHQuaApAQCAtMCwwICsxLDIwIEBACisvKiBsaWJzL29wZW5nbGVzL2NvbnRleHQuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxwcml2YXRlL29wZW5nbGVzL2dsX2NvbnRleHQuaD4KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ6OmdsOwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9keHQuY3BwIGIvb3BlbmdsL2xpYmFnbC9keHQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzOGM4MWYKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL2R4dC5jcHAKQEAgLTAsMCArMSw2MzYgQEAKKy8qIGxpYnMvb3BlbmdsZXMvZHh0LmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNkZWZpbmUgVElNSU5HIDAKKworI2lmIFRJTUlORworI2luY2x1ZGUgPHN5cy90aW1lLmg+IC8vIGZvciBvcHRpbWl6YXRpb24gdGltaW5nCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPHV0aWxzL0VuZGlhbi5oPgorCisjaW5jbHVkZSAiY29udGV4dC5oIgorCisjZGVmaW5lIFRJTUlORyAwCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworc3RhdGljIHVpbnQ4X3QgYXZnMjN0YWJbNjQqNjRdOworc3RhdGljIHZvbGF0aWxlIGludCB0YWJsZXNfaW5pdGlhbGl6ZWQgPSAwOworCisvLyBEZWZpbml0aW9ucyBiZWxvdyBhcmUgZXF1aXZhbGVudCB0byB0aGVzZSBvdmVyIHRoZSB2YWxpZCByYW5nZSBvZiBhcmd1bWVudHMKKy8vICAjZGVmaW5lIGRpdjUoeCkgKCh4KS81KQorLy8gICNkZWZpbmUgZGl2Nyh4KSAoKHgpLzcpCisKKy8vIFVzZSBmaXhlZC1wb2ludCB0byBkaXZpZGUgYnkgNSBhbmQgNworLy8gMzI3NyA9IDJeMTQvNSArIDEKKy8vIDIzNDEgPSAyXjE0LzcgKyAxCisjZGVmaW5lIGRpdjUoeCkgKCgoeCkqMzI3NykgPj4gMTQpCisjZGVmaW5lIGRpdjcoeCkgKCgoeCkqMjM0MSkgPj4gMTQpCisKKy8vIFRhYmxlIHdpdGggZW50cnkgW2EgPDwgNiB8IGJdID0gKDIqYSArIGIpLzMgZm9yIDAgPD0gYSxiIDwgNjQKKyNkZWZpbmUgYXZnMjMoeDAseDEpIGF2ZzIzdGFiWygoeDApIDw8IDYpIHwgKHgxKV0KKworLy8gRXh0cmFjdCA1LzYvNSBSR0IKKyNkZWZpbmUgcmVkKHgpICAgKCgoeCkgPj4gMTEpICYgMHgxZikKKyNkZWZpbmUgZ3JlZW4oeCkgKCgoeCkgPj4gIDUpICYgMHgzZikKKyNkZWZpbmUgYmx1ZSh4KSAgKCAoeCkgICAgICAgICYgMHgxZikKKworLyoKKyAqIENvbnZlcnQgNS82LzUgUkdCIChhcyAzIGludHMpIHRvIDgvOC84CisgKgorICogT3BlcmF0aW9uIGNvdW50OiA4IDw8LCAwICYsIDUgfAorICovCitpbmxpbmUgc3RhdGljIGludCByZ2I1NjVTZXBUbzg4OChpbnQgciwgaW50IGcsIGludCBiKQorCit7CisgICAgcmV0dXJuICgoKChyIDw8IDMpIHwgKHIgPj4gMikpIDw8IDE2KSB8CisgICAgICAgICAgICAoKChnIDw8IDIpIHwgKGcgPj4gNCkpIDw8ICA4KSB8CisgICAgICAgICAgICAgKChiIDw8IDMpIHwgKGIgPj4gMikpKTsKK30KKworLyoKKyAqIENvbnZlcnQgNS82LzUgUkdCIChhcyBhIHNpbmdsZSAxNi1iaXQgd29yZCkgdG8gOC84LzgKKyAqCisgKiAgICAgICAgICAgICAgICAgICByNHIzcjJyMSByMGc1ZzRnMyBnMmcxZzBiNCBiM2IyYjFiMCAgIHJnYgorICogICAgICAgICAgICByNHIzcjIgcjFyMGc1ZzQgZzNnMmcxZzAgYjRiM2IyYjEgYjAgMCAwIDAgICByZ2IgPDwgMworICogcjRyM3IycjEgcjByNHIzcjIgZzVnNGczZzIgZzFnMGc1ZzQgYjRiM2IyYjEgYjBiNGIzYjIgICBkZXNpcmVkIHJlc3VsdAorICoKKyAqIENvbnN0cnVjdCB0aGUgMjQtYml0IFJHQiB3b3JkIGFzOgorICoKKyAqIHI0cjNyMnIxIHIwLS0tLS0tIC0tLS0tLS0tIC0tLS0tLS0tIC0tLS0tLS0tIC0tLS0tLS0tICAocmdiIDw8IDgpICYgMHhmODAwMDAKKyAqICAgICAgICAgICAgcjRyM3IyIC0tLS0tLS0tIC0tLS0tLS0tIC0tLS0tLS0tIC0tLS0tLS0tICAocmdiIDw8IDMpICYgMHgwNzAwMDAKKyAqICAgICAgICAgICAgICAgICAgIGc1ZzRnM2cyIGcxZzAtLS0tIC0tLS0tLS0tIC0tLS0tLS0tICAocmdiIDw8IDUpICYgMHgwMGZjMDAKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnNWc0IC0tLS0tLS0tIC0tLS0tLS0tICAocmdiID4+IDEpICYgMHgwMDAzMDAKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGI0YjNiMmIxIGIwLS0tLS0tICAocmdiIDw8IDMpICYgMHgwMDAwZjgKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjRiM2IyICAocmdiID4+IDIpICYgMHgwMDAwMDcKKyAqCisgKiBPcGVyYXRpb24gY291bnQ6IDUgPDwsIDYgJiwgNSB8IChuLmIuIHJnYiA+PiAzIGlzIHVzZWQgdHdpY2UpCisgKi8KK2lubGluZSBzdGF0aWMgaW50IHJnYjU2NVRvODg4KGludCByZ2IpCisKK3sKKyAgICBpbnQgcmdiMyA9IHJnYiA+PiAzOworICAgIHJldHVybiAoKChyZ2IgPDwgOCkgJiAweGY4MDAwMCkgfAorICAgICAgICAgICAgKCByZ2IzICAgICAgJiAweDA3MDAwMCkgfAorICAgICAgICAgICAgKChyZ2IgPDwgNSkgJiAweDAwZmMwMCkgfAorICAgICAgICAgICAgKChyZ2IgPj4gMSkgJiAweDAwMDMwMCkgfAorICAgICAgICAgICAgKCByZ2IzICAgICAgJiAweDAwMDBmOCkgfAorICAgICAgICAgICAgKChyZ2IgPj4gMikgJiAweDAwMDAwNykpOworfQorCisjaWYgX19CWVRFX09SREVSID09IF9fQklHX0VORElBTgorc3RhdGljIHVpbnQzMl90IHN3YXAodWludDMyX3QgeCkgeworICAgIGludCBiMCA9ICh4ID4+IDI0KSAmIDB4ZmY7CisgICAgaW50IGIxID0gKHggPj4gMTYpICYgMHhmZjsKKyAgICBpbnQgYjIgPSAoeCA+PiAgOCkgJiAweGZmOworICAgIGludCBiMyA9ICh4ICAgICAgKSAmIDB4ZmY7CisgICAgCisgICAgcmV0dXJuICh1aW50MzJfdCkoKGIzIDw8IDI0KSB8IChiMiA8PCAxNikgfCAoYjEgPDwgOCkgfCBiMCk7Cit9CisjZW5kaWYKKworc3RhdGljIHZvaWQKK2luaXRfdGFibGVzKCkKK3sKKyAgICBpZiAodGFibGVzX2luaXRpYWxpemVkKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDY0OyBpKyspIHsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCA2NDsgaisrKSB7CisgICAgICAgICAgICBpbnQgYXZnID0gKDIqaSArIGopLzM7CisgICAgICAgICAgICBhdmcyM3RhYlsoaSA8PCA2KSB8IGpdID0gYXZnOworICAgICAgICB9CisgICAgfQorCisgICAgYXNtIHZvbGF0aWxlICgiIiA6IDogOiAibWVtb3J5Iik7CisgICAgdGFibGVzX2luaXRpYWxpemVkID0gMTsKK30KKworLyoKKyAqIFV0aWxpdHkgdG8gc2NhbiBhIERYVDEgY29tcHJlc3NlZCB0ZXh0dXJlIHRvIGRldGVybWluZSB3aGV0aGVyIGl0CisgKiBjb250YWlucyBhIHRyYW5zcGFyZW50IHBpeGVsIChjb2xvcjAgPCBjb2xvcjEsIGNvZGUgPT0gMykuICBUaGlzCisgKiBtYXkgYmUgdXNlZnVsIGlmIHRoZSBhcHBsaWNhdGlvbiBsYWNrcyBpbmZvcm1hdGlvbiBhcyB0byB3aGV0aGVyCisgKiB0aGUgdHJ1ZSBmb3JtYXQgaXMgR0xfQ09NUFJFU1NFRF9SR0JfUzNUQ19EWFQxX0VYVCBvcgorICogR0xfQ09NUFJFU1NFRF9SR0JBX1MzVENfRFhUMV9FWFQuCisgKi8KK2Jvb2wKK0RYVDFIYXNBbHBoYShjb25zdCBHTHZvaWQgKmRhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCkgeyAgICAKKyNpZiBUSU1JTkcKKyAgICBzdHJ1Y3QgdGltZXZhbCBzdGFydF90LCBlbmRfdDsKKyAgICBzdHJ1Y3QgdGltZXpvbmUgdHo7CisgICAgCisgICAgZ2V0dGltZW9mZGF5KCZzdGFydF90LCAmdHopOworI2VuZGlmCisKKyAgICBib29sIGhhc0FscGhhID0gZmFsc2U7CisKKyAgICBpbnQgeGJsb2NrcyA9ICh3aWR0aCArIDMpLzQ7CisgICAgaW50IHlibG9ja3MgPSAoaGVpZ2h0ICsgMykvNDsKKyAgICBpbnQgbnVtYmxvY2tzID0geGJsb2Nrcyp5YmxvY2tzOworCisgICAgdWludDMyX3QgY29uc3QgKmQzMiA9ICh1aW50MzJfdCAqKWRhdGE7CisgICAgZm9yIChpbnQgYiA9IDA7IGIgPCBudW1ibG9ja3M7IGIrKykgeworICAgICAgICB1aW50MzJfdCBjb2xvcnMgPSAqZDMyKys7CisgICAgICAgIAorI2lmIF9fQllURV9PUkRFUiA9PSBfX0JJR19FTkRJQU4KKyAgICAgICAgY29sb3JzID0gc3dhcChjb2xvcnMpOworI2VuZGlmCisgICAgICAgIAorICAgICAgICB1aW50MTZfdCBjb2xvcjAgPSBjb2xvcnMgJiAweGZmZmY7CisgICAgICAgIHVpbnQxNl90IGNvbG9yMSA9IGNvbG9ycyA+PiAxNjsKKyAgICAgICAgCisgICAgICAgIGlmIChjb2xvcjAgPCBjb2xvcjEpIHsKKyAgICAgICAgICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBlbmRpYW4tc3dhcCB3aXRoaW4gJ2JpdHMnCisgICAgICAgICAgICAvLyBzaW5jZSB3ZSBkb24ndCBjYXJlIHdoaWNoIHBpeGVsIGlzIHRoZSB0cmFuc3BhcmVudCBvbmUKKyAgICAgICAgICAgIHVpbnQzMl90IGJpdHMgPSAqZDMyKys7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIERldGVjdCBpZiBhbnkgKG9kZCwgZXZlbikgcGFpciBvZiBiaXRzIGFyZSAnMTEnCisgICAgICAgICAgICAvLyAgICAgIGJpdHM6IGIzMSBiMzAgYjI5IC4uLiBiMyBiMiBiMSBiMAorICAgICAgICAgICAgLy8gYml0cyA+PiAxOiBiMzEgYjMxIGIzMCAuLi4gYjQgYjMgYjIgYjEKKyAgICAgICAgICAgIC8vICAgICAgICAgJjogYjMxIChiMzEgJiBiMzApIChiMjkgJiBiMjgpIC4uLiAoYjIgJiBiMSkgKGIxICYgYjApCisgICAgICAgICAgICAvLyAgJiAweDU1Li46ICAgMCAoYjMxICYgYjMwKSAgICAgICAwICAgICAuLi4gICAgIDAgICAgIChiMSAmIGIwKQorICAgICAgICAgICAgaWYgKCgoYml0cyAmIChiaXRzID4+IDEpKSAmIDB4NTU1NTU1NTUpICE9IDApIHsKKyAgICAgICAgICAgICAgICBoYXNBbHBoYSA9IHRydWU7CisgICAgICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gU2tpcCA0IGJ5dGVzCisgICAgICAgICAgICArK2QzMjsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyBkb25lOgorI2lmIFRJTUlORworICAgIGdldHRpbWVvZmRheSgmZW5kX3QsICZ0eik7CisgICAgbG9uZyB1c2VjID0gKGVuZF90LnR2X3NlYyAtIHN0YXJ0X3QudHZfc2VjKSoxMDAwMDAwICsKKyAgICAgICAgKGVuZF90LnR2X3VzZWMgLSBzdGFydF90LnR2X3VzZWMpOworICAgIAorICAgIHByaW50ZigiU2Nhbm5lZCB3PSVkIGg9JWQgaW4gJWxkIHVzZWNcbiIsIHdpZHRoLCBoZWlnaHQsIHVzZWMpOworI2VuZGlmCisgICAgCisgICAgcmV0dXJuIGhhc0FscGhhOworfQorCitzdGF0aWMgdm9pZAorZGVjb2RlRFhUMShjb25zdCBHTHZvaWQgKmRhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICAgdm9pZCAqc3VyZmFjZSwgaW50IHN0cmlkZSwKKyAgICAgICAgICAgYm9vbCBoYXNBbHBoYSkKKyAgICAKK3sKKyAgICBpbml0X3RhYmxlcygpOworICAgIAorICAgIHVpbnQzMl90IGNvbnN0ICpkMzIgPSAodWludDMyX3QgKilkYXRhOworICAgIAorICAgIC8vIENvbG9yIHRhYmxlIGZvciB0aGUgY3VycmVudCBibG9jaworICAgIHVpbnQxNl90IGNbNF07CisgICAgY1swXSA9IGNbMV0gPSBjWzJdID0gY1szXSA9IDA7CisgICAgCisgICAgLy8gU3BlY2lmaWVkIGNvbG9ycyBmcm9tIHRoZSBwcmV2aW91cyBibG9jaworICAgIHVpbnQxNl90IHByZXZfY29sb3IwID0gMHgwMDAwOworICAgIHVpbnQxNl90IHByZXZfY29sb3IxID0gMHgwMDAwOworICAgIAorICAgIHVpbnQxNl90KiByb3dQdHIgPSAodWludDE2X3QqKXN1cmZhY2U7CisgICAgZm9yIChpbnQgYmFzZV95ID0gMDsgYmFzZV95IDwgaGVpZ2h0OyBiYXNlX3kgKz0gNCwgcm93UHRyICs9IDQqc3RyaWRlKSB7CisgICAgICAgIHVpbnQxNl90ICpibG9ja1B0ciA9IHJvd1B0cjsKKyAgICAgICAgZm9yIChpbnQgYmFzZV94ID0gMDsgYmFzZV94IDwgd2lkdGg7IGJhc2VfeCArPSA0LCBibG9ja1B0ciArPSA0KSB7CisgICAgICAgICAgICB1aW50MzJfdCBjb2xvcnMgPSAqZDMyKys7CisgICAgICAgICAgICB1aW50MzJfdCBiaXRzID0gKmQzMisrOworICAgICAgICAgICAgCisjaWYgX19CWVRFX09SREVSID09IF9fQklHX0VORElBTgorICAgICAgICAgICAgY29sb3JzID0gc3dhcChjb2xvcnMpOworICAgICAgICAgICAgYml0cyA9IHN3YXAoYml0cyk7CisjZW5kaWYKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gUmF3IGNvbG9ycworICAgICAgICAgICAgdWludDE2X3QgY29sb3IwID0gY29sb3JzICYgMHhmZmZmOworICAgICAgICAgICAgdWludDE2X3QgY29sb3IxID0gY29sb3JzID4+IDE2OworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBJZiB0aGUgbmV3IGJsb2NrIGhhcyB0aGUgc2FtZSBiYXNlIGNvbG9ycyBhcyB0aGUKKyAgICAgICAgICAgIC8vIHByZXZpb3VzIG9uZSwgd2UgZG9uJ3QgbmVlZCB0byByZWNvbXB1dGUgdGhlIGNvbG9yCisgICAgICAgICAgICAvLyB0YWJsZSBjW10KKyAgICAgICAgICAgIGlmIChjb2xvcjAgIT0gcHJldl9jb2xvcjAgfHwgY29sb3IxICE9IHByZXZfY29sb3IxKSB7CisgICAgICAgICAgICAgICAgLy8gU3RvcmUgcmF3IGNvbG9ycyBmb3IgY29tcGFyaXNvbiB3aXRoIG5leHQgYmxvY2sKKyAgICAgICAgICAgICAgICBwcmV2X2NvbG9yMCA9IGNvbG9yMDsKKyAgICAgICAgICAgICAgICBwcmV2X2NvbG9yMSA9IGNvbG9yMTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpbnQgcjAgPSAgIHJlZChjb2xvcjApOworICAgICAgICAgICAgICAgIGludCBnMCA9IGdyZWVuKGNvbG9yMCk7CisgICAgICAgICAgICAgICAgaW50IGIwID0gIGJsdWUoY29sb3IwKTsKKworICAgICAgICAgICAgICAgIGludCByMSA9ICAgcmVkKGNvbG9yMSk7CisgICAgICAgICAgICAgICAgaW50IGcxID0gZ3JlZW4oY29sb3IxKTsKKyAgICAgICAgICAgICAgICBpbnQgYjEgPSAgYmx1ZShjb2xvcjEpOyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpZiAoaGFzQWxwaGEpIHsKKyAgICAgICAgICAgICAgICAgICAgY1swXSA9IChyMCA8PCAxMSkgfCAoKGcwID4+IDEpIDw8IDYpIHwgKGIwIDw8IDEpIHwgMHgxOworICAgICAgICAgICAgICAgICAgICBjWzFdID0gKHIxIDw8IDExKSB8ICgoZzEgPj4gMSkgPDwgNikgfCAoYjEgPDwgMSkgfCAweDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY1swXSA9IGNvbG9yMDsKKyAgICAgICAgICAgICAgICAgICAgY1sxXSA9IGNvbG9yMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaW50IHIyLCBnMiwgYjIsIHIzLCBnMywgYjMsIGEzOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGludCBiYml0cyA9IGJpdHMgPj4gMTsKKyAgICAgICAgICAgICAgICBib29sIGhhczIgPSAoKGJiaXRzICYgfmJpdHMpICYgMHg1NTU1NTU1NSkgIT0gMDsKKyAgICAgICAgICAgICAgICBib29sIGhhczMgPSAoKGJiaXRzICYgIGJpdHMpICYgMHg1NTU1NTU1NSkgIT0gMDsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpZiAoaGFzMiB8fCBoYXMzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb2xvcjAgPiBjb2xvcjEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHIyID0gYXZnMjMocjAsIHIxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGcyID0gYXZnMjMoZzAsIGcxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGIyID0gYXZnMjMoYjAsIGIxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgcjMgPSBhdmcyMyhyMSwgcjApOworICAgICAgICAgICAgICAgICAgICAgICAgZzMgPSBhdmcyMyhnMSwgZzApOworICAgICAgICAgICAgICAgICAgICAgICAgYjMgPSBhdmcyMyhiMSwgYjApOworICAgICAgICAgICAgICAgICAgICAgICAgYTMgPSAxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcjIgPSAocjAgKyByMSkgPj4gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGcyID0gKGcwICsgZzEpID4+IDE7CisgICAgICAgICAgICAgICAgICAgICAgICBiMiA9IChiMCArIGIxKSA+PiAxOworICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICByMyA9IGczID0gYjMgPSBhMyA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGhhc0FscGhhKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjWzJdID0gKHIyIDw8IDExKSB8ICgoZzIgPj4gMSkgPDwgNikgfAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChiMiA8PCAxKSB8IDB4MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNbM10gPSAocjMgPDwgMTEpIHwgKChnMyA+PiAxKSA8PCA2KSB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIzIDw8IDEpIHwgYTM7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjWzJdID0gKHIyIDw8IDExKSB8IChnMiA8PCA1KSB8IGIyOworICAgICAgICAgICAgICAgICAgICAgICAgY1szXSA9IChyMyA8PCAxMSkgfCAoZzMgPDwgNSkgfCBiMzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgdWludDE2X3QqIGJsb2NrUm93UHRyID0gYmxvY2tQdHI7CisgICAgICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IDQ7IHkrKywgYmxvY2tSb3dQdHIgKz0gc3RyaWRlKSB7CisgICAgICAgICAgICAgICAgLy8gRG9uJ3QgcHJvY2VzcyByb3dzIHBhc3QgdGhlIGJvdG9tCisgICAgICAgICAgICAgICAgaWYgKGJhc2VfeSArIHkgPj0gaGVpZ2h0KSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpbnQgdyA9IG1pbih3aWR0aCAtIGJhc2VfeCwgNCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeCA9IDA7IHggPCB3OyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGNvZGUgPSBiaXRzICYgMHgzOworICAgICAgICAgICAgICAgICAgICBiaXRzID4+PSAyOworICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgYmxvY2tSb3dQdHJbeF0gPSBjW2NvZGVdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKyAgICAKKy8vIE91dHB1dCBkYXRhIGFzIGludGVybmFsZm9ybWF0PUdMX1JHQkEsIHR5cGU9R0xfVU5TSUdORURfQllURQorc3RhdGljIHZvaWQKK2RlY29kZURYVDMoY29uc3QgR0x2b2lkICpkYXRhLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsCisgICAgICAgICAgIHZvaWQgKnN1cmZhY2UsIGludCBzdHJpZGUpCisKK3sKKyAgICBpbml0X3RhYmxlcygpOworICAgIAorICAgIHVpbnQzMl90IGNvbnN0ICpkMzIgPSAodWludDMyX3QgKilkYXRhOworICAgIAorICAgIC8vIFNwZWNpZmllZCBjb2xvcnMgZnJvbSB0aGUgcHJldmlvdXMgYmxvY2sKKyAgICB1aW50MTZfdCBwcmV2X2NvbG9yMCA9IDB4MDAwMDsKKyAgICB1aW50MTZfdCBwcmV2X2NvbG9yMSA9IDB4MDAwMDsKKworICAgIC8vIENvbG9yIHRhYmxlIGZvciB0aGUgY3VycmVudCBibG9jaworICAgIHVpbnQzMl90IGNbNF07CisgICAgY1swXSA9IGNbMV0gPSBjWzJdID0gY1szXSA9IDA7CisKKyAgICB1aW50MzJfdCogcm93UHRyID0gKHVpbnQzMl90KilzdXJmYWNlOworICAgIGZvciAoaW50IGJhc2VfeSA9IDA7IGJhc2VfeSA8IGhlaWdodDsgYmFzZV95ICs9IDQsIHJvd1B0ciArPSA0KnN0cmlkZSkgeworICAgICAgICB1aW50MzJfdCAqYmxvY2tQdHIgPSByb3dQdHI7CisgICAgICAgIGZvciAoaW50IGJhc2VfeCA9IDA7IGJhc2VfeCA8IHdpZHRoOyBiYXNlX3ggKz0gNCwgYmxvY2tQdHIgKz0gNCkgeworICAgICAgICAgICAgCisjaWYgX19CWVRFX09SREVSID09IF9fQklHX0VORElBTgorICAgICAgICAgICAgdWludDMyX3QgYWxwaGFoaSA9ICpkMzIrKzsKKyAgICAgICAgICAgIHVpbnQzMl90IGFscGhhbG8gPSAqZDMyKys7CisgICAgICAgICAgICBhbHBoYWhpID0gc3dhcChhbHBoYWhpKTsKKyAgICAgICAgICAgIGFscGhhbG8gPSBzd2FwKGFscGhhbG8pOworI2Vsc2UKKyAgICAgICAgICAgIHVpbnQzMl90IGFscGhhbG8gPSAqZDMyKys7CisgICAgICAgICAgICB1aW50MzJfdCBhbHBoYWhpID0gKmQzMisrOworI2VuZGlmCisKKyAgICAgICAgICAgIHVpbnQzMl90IGNvbG9ycyA9ICpkMzIrKzsKKyAgICAgICAgICAgIHVpbnQzMl90IGJpdHMgPSAqZDMyKys7CisgICAgICAgICAgICAKKyNpZiBfX0JZVEVfT1JERVIgPT0gX19CSUdfRU5ESUFOCisgICAgICAgICAgICBjb2xvcnMgPSBzd2FwKGNvbG9ycyk7CisgICAgICAgICAgICBiaXRzID0gc3dhcChiaXRzKTsKKyNlbmRpZgorICAgICAgICAgICAgCisgICAgICAgICAgICB1aW50NjRfdCBhbHBoYSA9ICgodWludDY0X3QpYWxwaGFoaSA8PCAzMikgfCBhbHBoYWxvOworCisgICAgICAgICAgICAvLyBSYXcgY29sb3JzCisgICAgICAgICAgICB1aW50MTZfdCBjb2xvcjAgPSBjb2xvcnMgJiAweGZmZmY7CisgICAgICAgICAgICB1aW50MTZfdCBjb2xvcjEgPSBjb2xvcnMgPj4gMTY7CisKKyAgICAgICAgICAgIC8vIElmIHRoZSBuZXcgYmxvY2sgaGFzIHRoZSBzYW1lIGJhc2UgY29sb3JzIGFzIHRoZQorICAgICAgICAgICAgLy8gcHJldmlvdXMgb25lLCB3ZSBkb24ndCBuZWVkIHRvIHJlY29tcHV0ZSB0aGUgY29sb3IKKyAgICAgICAgICAgIC8vIHRhYmxlIGNbXQorICAgICAgICAgICAgaWYgKGNvbG9yMCAhPSBwcmV2X2NvbG9yMCB8fCBjb2xvcjEgIT0gcHJldl9jb2xvcjEpIHsKKyAgICAgICAgICAgICAgICAvLyBTdG9yZSByYXcgY29sb3JzIGZvciBjb21wYXJpc29uIHdpdGggbmV4dCBibG9jaworICAgICAgICAgICAgICAgIHByZXZfY29sb3IwID0gY29sb3IwOworICAgICAgICAgICAgICAgIHByZXZfY29sb3IxID0gY29sb3IxOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGludCBiYml0cyA9IGJpdHMgPj4gMTsKKyAgICAgICAgICAgICAgICBib29sIGhhczIgPSAoKGJiaXRzICYgfmJpdHMpICYgMHg1NTU1NTU1NSkgIT0gMDsKKyAgICAgICAgICAgICAgICBib29sIGhhczMgPSAoKGJiaXRzICYgIGJpdHMpICYgMHg1NTU1NTU1NSkgIT0gMDsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpZiAoaGFzMiB8fCBoYXMzKSB7CisgICAgICAgICAgICAgICAgICAgIGludCByMCA9ICAgcmVkKGNvbG9yMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBnMCA9IGdyZWVuKGNvbG9yMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBiMCA9ICBibHVlKGNvbG9yMCk7CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBpbnQgcjEgPSAgIHJlZChjb2xvcjEpOworICAgICAgICAgICAgICAgICAgICBpbnQgZzEgPSBncmVlbihjb2xvcjEpOworICAgICAgICAgICAgICAgICAgICBpbnQgYjEgPSAgYmx1ZShjb2xvcjEpOworICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgaW50IHIyID0gYXZnMjMocjAsIHIxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGcyID0gYXZnMjMoZzAsIGcxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGIyID0gYXZnMjMoYjAsIGIxKTsKKyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgIGludCByMyA9IGF2ZzIzKHIxLCByMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBnMyA9IGF2ZzIzKGcxLCBnMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBiMyA9IGF2ZzIzKGIxLCBiMCk7CisKKyAgICAgICAgICAgICAgICAgICAgY1swXSA9IHJnYjU2NVNlcFRvODg4KHIwLCBnMCwgYjApOworICAgICAgICAgICAgICAgICAgICBjWzFdID0gcmdiNTY1U2VwVG84ODgocjEsIGcxLCBiMSk7CisgICAgICAgICAgICAgICAgICAgIGNbMl0gPSByZ2I1NjVTZXBUbzg4OChyMiwgZzIsIGIyKTsKKyAgICAgICAgICAgICAgICAgICAgY1szXSA9IHJnYjU2NVNlcFRvODg4KHIzLCBnMywgYjMpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgdG8gOCBiaXRzCisgICAgICAgICAgICAgICAgICAgIGNbMF0gPSByZ2I1NjVUbzg4OChjb2xvcjApOworICAgICAgICAgICAgICAgICAgICBjWzFdID0gcmdiNTY1VG84ODgoY29sb3IxKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHVpbnQzMl90KiBibG9ja1Jvd1B0ciA9IGJsb2NrUHRyOworICAgICAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCA0OyB5KyssIGJsb2NrUm93UHRyICs9IHN0cmlkZSkgeworICAgICAgICAgICAgICAgIC8vIERvbid0IHByb2Nlc3Mgcm93cyBwYXN0IHRoZSBib3RvbQorICAgICAgICAgICAgICAgIGlmIChiYXNlX3kgKyB5ID49IGhlaWdodCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaW50IHcgPSBtaW4od2lkdGggLSBiYXNlX3gsIDQpOworICAgICAgICAgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgdzsgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBhID0gYWxwaGEgJiAweGY7CisgICAgICAgICAgICAgICAgICAgIGFscGhhID4+PSA0OworCisgICAgICAgICAgICAgICAgICAgIGludCBjb2RlID0gYml0cyAmIDB4MzsKKyAgICAgICAgICAgICAgICAgICAgYml0cyA+Pj0gMjsKKworICAgICAgICAgICAgICAgICAgICBibG9ja1Jvd1B0clt4XSA9IGNbY29kZV0gfCAoYSA8PCAyOCkgfCAoYSA8PCAyNCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorCisvLyBPdXRwdXQgZGF0YSBhcyBpbnRlcm5hbGZvcm1hdD1HTF9SR0JBLCB0eXBlPUdMX1VOU0lHTkVEX0JZVEUKK3N0YXRpYyB2b2lkCitkZWNvZGVEWFQ1KGNvbnN0IEdMdm9pZCAqZGF0YSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICB2b2lkICpzdXJmYWNlLCBpbnQgc3RyaWRlKQorCit7CisgICAgaW5pdF90YWJsZXMoKTsKKyAgICAKKyAgICB1aW50MzJfdCBjb25zdCAqZDMyID0gKHVpbnQzMl90ICopZGF0YTsKKyAgICAKKyAgICAvLyBTcGVjaWZpZWQgYWxwaGFzIGZyb20gdGhlIHByZXZpb3VzIGJsb2NrCisgICAgdWludDhfdCBwcmV2X2FscGhhMCA9IDB4MDA7CisgICAgdWludDhfdCBwcmV2X2FscGhhMSA9IDB4MDA7CisKKyAgICAvLyBTcGVjaWZpZWQgY29sb3JzIGZyb20gdGhlIHByZXZpb3VzIGJsb2NrCisgICAgdWludDE2X3QgcHJldl9jb2xvcjAgPSAweDAwMDA7CisgICAgIHVpbnQxNl90IHByZXZfY29sb3IxID0gMHgwMDAwOworCisgICAgLy8gQWxwaGEgdGFibGUgZm9yIHRoZSBjdXJyZW50IGJsb2NrCisgICAgdWludDhfdCBhWzhdOworICAgIGFbMF0gPSBhWzFdID0gYVsyXSA9IGFbM10gPSBhWzRdID0gYVs1XSA9IGFbNl0gPSBhWzddID0gMDsKKworICAgIC8vIENvbG9yIHRhYmxlIGZvciB0aGUgY3VycmVudCBibG9jaworICAgIHVpbnQzMl90IGNbNF07CisgICAgY1swXSA9IGNbMV0gPSBjWzJdID0gY1szXSA9IDA7CisKKyAgICBpbnQgZ29vZF9hNSA9IDA7CisgICAgaW50IGJhZF9hNSA9IDA7CisgICAgaW50IGdvb2RfYTYgPSAwOworICAgIGludCBiYWRfYTYgPSAwOworICAgIGludCBnb29kX2E3ID0gMDsKKyAgICBpbnQgYmFkX2E3ID0gMDsKKworICAgIHVpbnQzMl90KiByb3dQdHIgPSAodWludDMyX3QqKXN1cmZhY2U7CisgICAgZm9yIChpbnQgYmFzZV95ID0gMDsgYmFzZV95IDwgaGVpZ2h0OyBiYXNlX3kgKz0gNCwgcm93UHRyICs9IDQqc3RyaWRlKSB7CisgICAgICAgIHVpbnQzMl90ICpibG9ja1B0ciA9IHJvd1B0cjsKKyAgICAgICAgZm9yIChpbnQgYmFzZV94ID0gMDsgYmFzZV94IDwgd2lkdGg7IGJhc2VfeCArPSA0LCBibG9ja1B0ciArPSA0KSB7CisgICAgICAgICAgICAKKyNpZiBfX0JZVEVfT1JERVIgPT0gX19CSUdfRU5ESUFOCisgICAgICAgICAgICB1aW50MzJfdCBhbHBoYWhpID0gKmQzMisrOworICAgICAgICAgICAgdWludDMyX3QgYWxwaGFsbyA9ICpkMzIrKzsKKyAgICAgICAgICAgIGFscGhhaGkgPSBzd2FwKGFscGhhaGkpOworICAgICAgICAgICAgYWxwaGFsbyA9IHN3YXAoYWxwaGFsbyk7CisjZWxzZQorICAgICAgICAgICAgIHVpbnQzMl90IGFscGhhbG8gPSAqZDMyKys7CisgICAgICAgICAgICAgdWludDMyX3QgYWxwaGFoaSA9ICpkMzIrKzsKKyNlbmRpZgorCisgICAgICAgICAgICB1aW50MzJfdCBjb2xvcnMgPSAqZDMyKys7CisgICAgICAgICAgICB1aW50MzJfdCBiaXRzID0gKmQzMisrOworICAgICAgICAgICAgCisjaWYgX19CWVRFX09SREVSID09IF9fQklHX0VORElBTngKKyAgICAgICAgICAgIGNvbG9ycyA9IHN3YXAoY29sb3JzKTsKKyAgICAgICAgICAgIGJpdHMgPSBzd2FwKGJpdHMpOworI2VuZGlmCisgICAgICAgICAgICAKKyAgICAgICAgICAgIHVpbnQ2NF90IGFscGhhID0gKCh1aW50NjRfdClhbHBoYWhpIDw8IDMyKSB8IGFscGhhbG87CisgICAgICAgICAgICB1aW50NjRfdCBhbHBoYTAgPSBhbHBoYSAmIDB4ZmY7CisgICAgICAgICAgICBhbHBoYSA+Pj0gODsKKyAgICAgICAgICAgIHVpbnQ2NF90IGFscGhhMSA9IGFscGhhICYgMHhmZjsKKyAgICAgICAgICAgIGFscGhhID4+PSA4OworCisgICAgICAgICAgICBpZiAoYWxwaGEwICE9IHByZXZfYWxwaGEwIHx8IGFscGhhMSAhPSBwcmV2X2FscGhhMSkgeworICAgICAgICAgICAgICAgIHByZXZfYWxwaGEwID0gYWxwaGEwOworICAgICAgICAgICAgICAgIHByZXZfYWxwaGExID0gYWxwaGExOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGFbMF0gPSBhbHBoYTA7CisgICAgICAgICAgICAgICAgYVsxXSA9IGFscGhhMTsKKyAgICAgICAgICAgICAgICBpbnQgYTAxID0gYWxwaGEwICsgYWxwaGExIC0gMTsKKyAgICAgICAgICAgICAgICBpZiAoYWxwaGEwID4gYWxwaGExKSB7CisgICAgICAgICAgICAgICAgICAgIGFbMl0gPSBkaXY3KDYqYWxwaGEwICsgICBhbHBoYTEpOworICAgICAgICAgICAgICAgICAgICBhWzRdID0gZGl2Nyg0KmFscGhhMCArIDMqYWxwaGExKTsKKyAgICAgICAgICAgICAgICAgICAgYVs2XSA9IGRpdjcoMiphbHBoYTAgKyA1KmFscGhhMSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIHN5bW1ldHJ5IHRvIGRlcml2ZSBoYWxmIG9mIHRoZSB2YWx1ZXMKKyAgICAgICAgICAgICAgICAgICAgLy8gQSBmZXcgdmFsdWVzIHdpbGwgYmUgb2ZmIGJ5IDEgKH4uNSUpCisgICAgICAgICAgICAgICAgICAgIC8vIEFsdGVybmF0ZSB3aGljaCB2YWx1ZXMgYXJlIGNvbXB1dGVkIGRpcmVjdGx5CisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3aGljaCBhcmUgZGVyaXZlZCB0byB0cnkgdG8gcmVkdWNlIGJpYXMKKyAgICAgICAgICAgICAgICAgICAgYVszXSA9IGEwMSAtIGFbNl07CisgICAgICAgICAgICAgICAgICAgIGFbNV0gPSBhMDEgLSBhWzRdOworICAgICAgICAgICAgICAgICAgICBhWzddID0gYTAxIC0gYVsyXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhWzJdID0gZGl2NSg0KmFscGhhMCArICAgYWxwaGExKTsKKyAgICAgICAgICAgICAgICAgICAgYVs0XSA9IGRpdjUoMiphbHBoYTAgKyAzKmFscGhhMSk7CisgICAgICAgICAgICAgICAgICAgIGFbM10gPSBhMDEgLSBhWzRdOworICAgICAgICAgICAgICAgICAgICBhWzVdID0gYTAxIC0gYVsyXTsKKyAgICAgICAgICAgICAgICAgICAgYVs2XSA9IDB4MDA7CisgICAgICAgICAgICAgICAgICAgIGFbN10gPSAweGZmOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUmF3IGNvbG9ycworICAgICAgICAgICAgdWludDE2X3QgY29sb3IwID0gY29sb3JzICYgMHhmZmZmOworICAgICAgICAgICAgdWludDE2X3QgY29sb3IxID0gY29sb3JzID4+IDE2OworCisgICAgICAgICAgICAvLyBJZiB0aGUgbmV3IGJsb2NrIGhhcyB0aGUgc2FtZSBiYXNlIGNvbG9ycyBhcyB0aGUKKyAgICAgICAgICAgIC8vIHByZXZpb3VzIG9uZSwgd2UgZG9uJ3QgbmVlZCB0byByZWNvbXB1dGUgdGhlIGNvbG9yCisgICAgICAgICAgICAvLyB0YWJsZSBjW10KKyAgICAgICAgICAgIGlmIChjb2xvcjAgIT0gcHJldl9jb2xvcjAgfHwgY29sb3IxICE9IHByZXZfY29sb3IxKSB7CisgICAgICAgICAgICAgICAgLy8gU3RvcmUgcmF3IGNvbG9ycyBmb3IgY29tcGFyaXNvbiB3aXRoIG5leHQgYmxvY2sKKyAgICAgICAgICAgICAgICBwcmV2X2NvbG9yMCA9IGNvbG9yMDsKKyAgICAgICAgICAgICAgICBwcmV2X2NvbG9yMSA9IGNvbG9yMTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpbnQgYmJpdHMgPSBiaXRzID4+IDE7CisgICAgICAgICAgICAgICAgYm9vbCBoYXMyID0gKChiYml0cyAmIH5iaXRzKSAmIDB4NTU1NTU1NTUpICE9IDA7CisgICAgICAgICAgICAgICAgYm9vbCBoYXMzID0gKChiYml0cyAmICBiaXRzKSAmIDB4NTU1NTU1NTUpICE9IDA7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaWYgKGhhczIgfHwgaGFzMykgeworICAgICAgICAgICAgICAgICAgICBpbnQgcjAgPSAgIHJlZChjb2xvcjApOworICAgICAgICAgICAgICAgICAgICBpbnQgZzAgPSBncmVlbihjb2xvcjApOworICAgICAgICAgICAgICAgICAgICBpbnQgYjAgPSAgYmx1ZShjb2xvcjApOworICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgaW50IHIxID0gICByZWQoY29sb3IxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGcxID0gZ3JlZW4oY29sb3IxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGIxID0gIGJsdWUoY29sb3IxKTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgaW50IHIyID0gYXZnMjMocjAsIHIxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGcyID0gYXZnMjMoZzAsIGcxKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGIyID0gYXZnMjMoYjAsIGIxKTsKKyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgIGludCByMyA9IGF2ZzIzKHIxLCByMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBnMyA9IGF2ZzIzKGcxLCBnMCk7CisgICAgICAgICAgICAgICAgICAgIGludCBiMyA9IGF2ZzIzKGIxLCBiMCk7CisKKyAgICAgICAgICAgICAgICAgICAgY1swXSA9IHJnYjU2NVNlcFRvODg4KHIwLCBnMCwgYjApOworICAgICAgICAgICAgICAgICAgICBjWzFdID0gcmdiNTY1U2VwVG84ODgocjEsIGcxLCBiMSk7CisgICAgICAgICAgICAgICAgICAgIGNbMl0gPSByZ2I1NjVTZXBUbzg4OChyMiwgZzIsIGIyKTsKKyAgICAgICAgICAgICAgICAgICAgY1szXSA9IHJnYjU2NVNlcFRvODg4KHIzLCBnMywgYjMpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgdG8gOCBiaXRzCisgICAgICAgICAgICAgICAgICAgIGNbMF0gPSByZ2I1NjVUbzg4OChjb2xvcjApOworICAgICAgICAgICAgICAgICAgICBjWzFdID0gcmdiNTY1VG84ODgoY29sb3IxKTsKKyAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB1aW50MzJfdCogYmxvY2tSb3dQdHIgPSBibG9ja1B0cjsKKyAgICAgICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgNDsgeSsrLCBibG9ja1Jvd1B0ciArPSBzdHJpZGUpIHsKKyAgICAgICAgICAgICAgICAvLyBEb24ndCBwcm9jZXNzIHJvd3MgcGFzdCB0aGUgYm90b20KKyAgICAgICAgICAgICAgICBpZiAoYmFzZV95ICsgeSA+PSBoZWlnaHQpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGludCB3ID0gbWluKHdpZHRoIC0gYmFzZV94LCA0KTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IHc7IHgrKykgeworICAgICAgICAgICAgICAgICAgICBpbnQgYWNvZGUgPSBhbHBoYSAmIDB4NzsKKyAgICAgICAgICAgICAgICAgICAgYWxwaGEgPj49IDM7CisKKyAgICAgICAgICAgICAgICAgICAgaW50IGNvZGUgPSBiaXRzICYgMHgzOworICAgICAgICAgICAgICAgICAgICBiaXRzID4+PSAyOworCisgICAgICAgICAgICAgICAgICAgIGJsb2NrUm93UHRyW3hdID0gY1tjb2RlXSB8IChhW2Fjb2RlXSA8PCAyNCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQorICAgCisvKgorICogRGVjb2RlIGEgRFhULWNvbXByZXNzZWQgdGV4dHVyZSBpbnRvIG1lbW9yeS4gIERYVCB0ZXh0dXJlcyBjb25zaXN0IG9mCisgKiBhIHNlcmllcyBvZiA0eDQgcGl4ZWwgYmxvY2tzIGluIGxlZnQtdG8tcmlnaHQsIHRvcC1kb3duIG9yZGVyLgorICogVGhlIG51bWJlciBvZiBibG9ja3MgaXMgZ2l2ZW4gYnkgY2VpbCh3aWR0aC80KSpjZWlsKGhlaWdodC80KS4KKyAqCisgKiAnZGF0YScgcG9pbnRzIHRvIHRoZSB0ZXh0dXJlIGRhdGEuICd3aWR0aCcgYW5kICdoZWlnaHQnIGluZGljYXRlIHRoZQorICogZGltZW5zaW9ucyBvZiB0aGUgdGV4dHVyZS4gIFdlIGFzc3VtZSB3aWR0aCBhbmQgaGVpZ2h0IGFyZSA+PSAwIGJ1dAorICogZG8gbm90IHJlcXVpcmUgdGhlbSB0byBiZSBwb3dlcnMgb2YgMiBvciBkaXZpc2libGUgYnkgYW55IGZhY3Rvci4KKyAqCisgKiBUaGUgb3V0cHV0IGlzIHdyaXR0ZW4gdG8gJ3N1cmZhY2UnIHdpdGggZWFjaCBzY2FubGluZSBzZXBhcmF0ZWQgYnkKKyAqICdzdHJpZGUnIDItIG9yIDQtYnl0ZSB3b3Jkcy4KKyAqCisgKiAnZm9ybWF0JyBpbmRpY2F0ZXMgdGhlIHR5cGUgb2YgY29tcHJlc3Npb24gYW5kIG11c3QgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6CisgKgorICogICBHTF9DT01QUkVTU0VEX1JHQl9TM1RDX0RYVDFfRVhUOgorICogICAgICBUaGUgb3V0cHV0IGlzIHdyaXR0ZW4gYXMgNS82LzUgb3BhcXVlIFJHQiAoMTYgYml0IHdvcmRzKS4KKyAqICAgICAgOCBieXRlcyBhcmUgcmVhZCBmcm9tICdkYXRhJyBmb3IgZWFjaCBibG9jay4KKyAqCisgKiAgIEdMX0NPTVBSRVNTRURfUkdCQV9TM1RDX0RYVDFfRVhUCisgKiAgICAgIFRoZSBvdXRwdXQgaXMgd3JpdHRlbiBhcyA1LzUvNS8xIFJHQkEgKDE2IGJpdCB3b3JkcykKKyAqICAgICAgOCBieXRlcyBhcmUgcmVhZCBmcm9tICdkYXRhJyBmb3IgZWFjaCBibG9jay4KKyAqCisgKiAgIEdMX0NPTVBSRVNTRURfUkdCQV9TM1RDX0RYVDNfRVhUCisgKiAgIEdMX0NPTVBSRVNTRURfUkdCQV9TM1RDX0RYVDVfRVhUCisgKiAgICAgIFRoZSBvdXRwdXQgaXMgd3JpdHRlbiBhcyA4LzgvOC84IEFSR0IgKDMyIGJpdCB3b3JkcykKKyAqICAgICAgMTYgYnl0ZXMgYXJlIHJlYWQgZnJvbSAnZGF0YScgZm9yIGVhY2ggYmxvY2suCisgKi8KK3ZvaWQKK2RlY29kZURYVChjb25zdCBHTHZvaWQgKmRhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCwKKyAgICAgICAgICB2b2lkICpzdXJmYWNlLCBpbnQgc3RyaWRlLCBpbnQgZm9ybWF0KQoreworI2lmIFRJTUlORworICAgIHN0cnVjdCB0aW1ldmFsIHN0YXJ0X3QsIGVuZF90OworICAgIHN0cnVjdCB0aW1lem9uZSB0ejsKKyAgICAKKyAgICBnZXR0aW1lb2ZkYXkoJnN0YXJ0X3QsICZ0eik7CisjZW5kaWYKKworICAgIHN3aXRjaCAoZm9ybWF0KSB7CisgICAgY2FzZSBHTF9DT01QUkVTU0VEX1JHQl9TM1RDX0RYVDFfRVhUOgorICAgICAgICBkZWNvZGVEWFQxKGRhdGEsIHdpZHRoLCBoZWlnaHQsIHN1cmZhY2UsIHN0cmlkZSwgZmFsc2UpOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBHTF9DT01QUkVTU0VEX1JHQkFfUzNUQ19EWFQxX0VYVDoKKyAgICAgICAgZGVjb2RlRFhUMShkYXRhLCB3aWR0aCwgaGVpZ2h0LCBzdXJmYWNlLCBzdHJpZGUsIHRydWUpOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBHTF9DT01QUkVTU0VEX1JHQkFfUzNUQ19EWFQzX0VYVDoKKyAgICAgICAgZGVjb2RlRFhUMyhkYXRhLCB3aWR0aCwgaGVpZ2h0LCBzdXJmYWNlLCBzdHJpZGUpOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBHTF9DT01QUkVTU0VEX1JHQkFfUzNUQ19EWFQ1X0VYVDoKKyAgICAgICAgZGVjb2RlRFhUNShkYXRhLCB3aWR0aCwgaGVpZ2h0LCBzdXJmYWNlLCBzdHJpZGUpOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgCisjaWYgVElNSU5HCisgICAgZ2V0dGltZW9mZGF5KCZlbmRfdCwgJnR6KTsKKyAgICBsb25nIHVzZWMgPSAoZW5kX3QudHZfc2VjIC0gc3RhcnRfdC50dl9zZWMpKjEwMDAwMDAgKworICAgICAgICAoZW5kX3QudHZfdXNlYyAtIHN0YXJ0X3QudHZfdXNlYyk7CisgICAgCisgICAgcHJpbnRmKCJMb2FkZWQgdz0lZCBoPSVkIGluICVsZCB1c2VjXG4iLCB3aWR0aCwgaGVpZ2h0LCB1c2VjKTsKKyNlbmRpZgorfQorCit9IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL2R4dC5oIGIvb3BlbmdsL2xpYmFnbC9keHQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTVhMzZjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9keHQuaApAQCAtMCwwICsxLDMzIEBACisvKiBsaWJzL29wZW5nbGVzL2R4dC5oCisqKgorKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2lmbmRlZiBBTkRST0lEX09QRU5HTEVTX1RFWFRVUkVfSAorI2RlZmluZSBBTkRST0lEX09QRU5HTEVTX1RFWFRVUkVfSAorCisjaW5jbHVkZSA8c3RkbGliLmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworICBib29sIERYVDFIYXNBbHBoYShjb25zdCBHTHZvaWQgKmRhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCk7CisgIHZvaWQgZGVjb2RlRFhUKGNvbnN0IEdMdm9pZCAqZGF0YSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgICAgICB2b2lkICpzdXJmYWNlLCBpbnQgc3RyaWRlLCBpbnQgZm9ybWF0KTsKKworfSAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9PUEVOR0xFU19URVhUVVJFX0gKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvZWdsLmNwcCBiL29wZW5nbC9saWJhZ2wvZWdsLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjkwYmYwCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9lZ2wuY3BwCkBAIC0wLDAgKzEsMTU0MyBAQAorLyogCisqKgorKiogQ29weXJpZ2h0IDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUyAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5EIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2RlZmluZSBMT0dfVEFHICJFR0wiCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvbW1hbi5oPgorCisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorI2luY2x1ZGUgPGN1dGlscy9hdG9taWMuaD4KKworI2luY2x1ZGUgPHV0aWxzL3RocmVhZHMuaD4KKworI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKyNpbmNsdWRlIDxFR0wvZWdsZXh0Lmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2xleHQuaD4KKworI2luY2x1ZGUgPHBpeGVsZmxpbmdlci9mb3JtYXQuaD4KKyNpbmNsdWRlIDxwaXhlbGZsaW5nZXIvcGl4ZWxmbGluZ2VyLmg+CisKKyNpbmNsdWRlICJjb250ZXh0LmgiCisjaW5jbHVkZSAic3RhdGUuaCIKKyNpbmNsdWRlICJ0ZXh0dXJlLmgiCisjaW5jbHVkZSAibWF0cml4LmgiCisKKyN1bmRlZiBORUxFTQorI2RlZmluZSBORUxFTSh4KSAoc2l6ZW9mKHgpL3NpemVvZigqKHgpKSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjb25zdCB1bnNpZ25lZCBpbnQgTlVNX0RJU1BMQVlTID0gMTsKKworc3RhdGljIHB0aHJlYWRfbXV0ZXhfdCBnSW5pdE11dGV4ID0gUFRIUkVBRF9NVVRFWF9JTklUSUFMSVpFUjsKK3N0YXRpYyBwdGhyZWFkX211dGV4X3QgZ0Vycm9yS2V5TXV0ZXggPSBQVEhSRUFEX01VVEVYX0lOSVRJQUxJWkVSOworc3RhdGljIHB0aHJlYWRfa2V5X3QgZ0VHTEVycm9yS2V5ID0gLTE7CisjaWZuZGVmIEhBVkVfQU5EUk9JRF9PUworbmFtZXNwYWNlIGdsIHsKK3B0aHJlYWRfa2V5X3QgZ0dMS2V5ID0gLTE7Cit9OyAvLyBuYW1lc3BhY2UgZ2wKKyNlbmRpZgorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RhdGljIFQgc2V0RXJyb3IoR0xpbnQgZXJyb3IsIFQgcmV0dXJuVmFsdWUpIHsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGdFR0xFcnJvcktleSA9PSAtMSkpIHsKKyAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZnRXJyb3JLZXlNdXRleCk7CisgICAgICAgIGlmIChnRUdMRXJyb3JLZXkgPT0gLTEpCisgICAgICAgICAgICBwdGhyZWFkX2tleV9jcmVhdGUoJmdFR0xFcnJvcktleSwgTlVMTCk7CisgICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnRXJyb3JLZXlNdXRleCk7CisgICAgfQorICAgIHB0aHJlYWRfc2V0c3BlY2lmaWMoZ0VHTEVycm9yS2V5LCAodm9pZCopZXJyb3IpOworICAgIHJldHVybiByZXR1cm5WYWx1ZTsKK30KKworc3RhdGljIEdMaW50IGdldEVycm9yKCkgeworICAgIGlmIChnZ2xfdW5saWtlbHkoZ0VHTEVycm9yS2V5ID09IC0xKSkKKyAgICAgICAgcmV0dXJuIEVHTF9TVUNDRVNTOworICAgIEdMaW50IGVycm9yID0gKEdMaW50KXB0aHJlYWRfZ2V0c3BlY2lmaWMoZ0VHTEVycm9yS2V5KTsKKyAgICBwdGhyZWFkX3NldHNwZWNpZmljKGdFR0xFcnJvcktleSwgKHZvaWQqKUVHTF9TVUNDRVNTKTsKKyAgICByZXR1cm4gZXJyb3I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RydWN0IGVnbF9kaXNwbGF5X3QKK3sKKyAgICBlZ2xfZGlzcGxheV90KCkgOiB0eXBlKDApLCBpbml0aWFsaXplZCgwKSB7IH0KKyAgICAKKyAgICBzdGF0aWMgZWdsX2Rpc3BsYXlfdCYgZ2V0X2Rpc3BsYXkoRUdMRGlzcGxheSBkcHkpOworICAgIAorICAgIHN0YXRpYyBFR0xCb29sZWFuIGlzX3ZhbGlkKEVHTERpc3BsYXkgZHB5KSB7CisgICAgICAgIHJldHVybiAoKHVpbnRwdHJfdChkcHkpLTFVKSA+PSBOVU1fRElTUExBWVMpID8gRUdMX0ZBTFNFIDogRUdMX1RSVUU7CisgICAgfQorCisgICAgTmF0aXZlRGlzcGxheVR5cGUgICB0eXBlOworICAgIHZvbGF0aWxlIGludDMyX3QgICAgaW5pdGlhbGl6ZWQ7Cit9OworCitzdGF0aWMgZWdsX2Rpc3BsYXlfdCBnRGlzcGxheXNbTlVNX0RJU1BMQVlTXTsKKworZWdsX2Rpc3BsYXlfdCYgZWdsX2Rpc3BsYXlfdDo6Z2V0X2Rpc3BsYXkoRUdMRGlzcGxheSBkcHkpIHsKKyAgICByZXR1cm4gZ0Rpc3BsYXlzW3VpbnRwdHJfdChkcHkpLTFVXTsKK30KKworc3RydWN0IGVnbF9jb250ZXh0X3QgeworICAgIGVudW0geworICAgICAgICBJU19DVVJSRU5UICAgICAgPSAgIDB4MDAwMTAwMDAsCisgICAgICAgIE5FVkVSX0NVUlJFTlQgICA9ICAgMHgwMDAyMDAwMAorICAgIH07CisgICAgdWludDMyX3QgICAgICAgICAgICBmbGFnczsKKyAgICBFR0xEaXNwbGF5ICAgICAgICAgIGRweTsKKyAgICBFR0xDb25maWcgICAgICAgICAgIGNvbmZpZzsKKyAgICBFR0xTdXJmYWNlICAgICAgICAgIHJlYWQ7CisgICAgRUdMU3VyZmFjZSAgICAgICAgICBkcmF3OworCisgICAgc3RhdGljIGlubGluZSBlZ2xfY29udGV4dF90KiBjb250ZXh0KEVHTENvbnRleHQgY3R4KSB7CisgICAgICAgIG9nbGVzX2NvbnRleHRfdCogY29uc3QgZ2wgPSBzdGF0aWNfY2FzdDxvZ2xlc19jb250ZXh0X3QqPihjdHgpOworICAgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8ZWdsX2NvbnRleHRfdCo+KGdsLT5yYXN0ZXJpemVyLmJhc2UpOworICAgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RydWN0IGVnbF9zdXJmYWNlX3QKK3sKKyAgICBlbnVtIHsKKyAgICAgICAgUEFHRV9GTElQID0gMHgwMDAwMDAwMSwKKyAgICAgICAgTUFHSUMgICAgID0gMHgzMTQxNTI2NQorICAgIH07CisKKyAgICB1aW50MzJfdCAgICAgICAgICAgIG1hZ2ljOworICAgIEVHTERpc3BsYXkgICAgICAgICAgZHB5OworICAgIEVHTENvbmZpZyAgICAgICAgICAgY29uZmlnOworICAgIEVHTENvbnRleHQgICAgICAgICAgY3R4OworCisgICAgICAgICAgICAgICAgZWdsX3N1cmZhY2VfdChFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywgaW50MzJfdCBkZXB0aEZvcm1hdCk7CisgICAgdmlydHVhbCAgICAgfmVnbF9zdXJmYWNlX3QoKTsKKyAgICB2aXJ0dWFsICAgICBib29sICAgIGlzVmFsaWQoKSBjb25zdCA9IDA7CisgICAgCisgICAgdmlydHVhbCAgICAgRUdMQm9vbGVhbiAgYmluZERyYXdTdXJmYWNlKG9nbGVzX2NvbnRleHRfdCogZ2wpID0gMDsKKyAgICB2aXJ0dWFsICAgICBFR0xCb29sZWFuICBiaW5kUmVhZFN1cmZhY2Uob2dsZXNfY29udGV4dF90KiBnbCkgPSAwOworICAgIHZpcnR1YWwgICAgIEVHTGludCAgICAgIGdldFdpZHRoKCkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgICAgIEVHTGludCAgICAgIGdldEhlaWdodCgpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsICAgICB2b2lkKiAgICAgICBnZXRCaXRzKCkgY29uc3QgPSAwOworCisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0SG9yaXpvbnRhbFJlc29sdXRpb24oKSBjb25zdDsKKyAgICB2aXJ0dWFsICAgICBFR0xpbnQgICAgICBnZXRWZXJ0aWNhbFJlc29sdXRpb24oKSBjb25zdDsKKyAgICB2aXJ0dWFsICAgICBFR0xpbnQgICAgICBnZXRSZWZyZXNoUmF0ZSgpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIEVHTGludCAgICAgIGdldFN3YXBCZWhhdmlvcigpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIEVHTEJvb2xlYW4gIHN3YXBCdWZmZXJzKCk7Citwcm90ZWN0ZWQ6CisgICAgR0dMU3VyZmFjZSAgICAgICAgICAgICAgZGVwdGg7Cit9OworCitlZ2xfc3VyZmFjZV90OjplZ2xfc3VyZmFjZV90KEVHTERpc3BsYXkgZHB5LAorICAgICAgICBFR0xDb25maWcgY29uZmlnLAorICAgICAgICBpbnQzMl90IGRlcHRoRm9ybWF0KQorICAgIDogbWFnaWMoTUFHSUMpLCBkcHkoZHB5KSwgY29uZmlnKGNvbmZpZyksIGN0eCgwKQoreworICAgIGRlcHRoLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgZGVwdGguZGF0YSA9IDA7CisgICAgZGVwdGguZm9ybWF0ID0gZGVwdGhGb3JtYXQ7Cit9CitlZ2xfc3VyZmFjZV90Ojp+ZWdsX3N1cmZhY2VfdCgpCit7CisgICAgbWFnaWMgPSAwOworICAgIGZyZWUoZGVwdGguZGF0YSk7Cit9CitFR0xCb29sZWFuIGVnbF9zdXJmYWNlX3Q6OnN3YXBCdWZmZXJzKCkgeworICAgIHJldHVybiBFR0xfRkFMU0U7Cit9CitFR0xpbnQgZWdsX3N1cmZhY2VfdDo6Z2V0SG9yaXpvbnRhbFJlc29sdXRpb24oKSBjb25zdCB7CisgICAgcmV0dXJuICgwICogRUdMX0RJU1BMQVlfU0NBTElORykgKiAoMS4wZiAvIDI1LjRmKTsKK30KK0VHTGludCBlZ2xfc3VyZmFjZV90OjpnZXRWZXJ0aWNhbFJlc29sdXRpb24oKSBjb25zdCB7CisgICAgcmV0dXJuICgwICogRUdMX0RJU1BMQVlfU0NBTElORykgKiAoMS4wZiAvIDI1LjRmKTsKK30KK0VHTGludCBlZ2xfc3VyZmFjZV90OjpnZXRSZWZyZXNoUmF0ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gKDYwICogRUdMX0RJU1BMQVlfU0NBTElORyk7Cit9CitFR0xpbnQgZWdsX3N1cmZhY2VfdDo6Z2V0U3dhcEJlaGF2aW9yKCkgY29uc3QgeworICAgIHJldHVybiBFR0xfQlVGRkVSX1BSRVNFUlZFRDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgZWdsX3dpbmRvd19zdXJmYWNlX3QgOiBwdWJsaWMgZWdsX3N1cmZhY2VfdAoreworICAgIGVnbF93aW5kb3dfc3VyZmFjZV90KAorICAgICAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgICAgICBpbnQzMl90IGRlcHRoRm9ybWF0LAorICAgICAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdCogd2luZG93KTsKKworICAgICB+ZWdsX3dpbmRvd19zdXJmYWNlX3QoKTsKKworICAgIHZpcnR1YWwgICAgIGJvb2wgICAgICAgIGlzVmFsaWQoKSBjb25zdCB7IHJldHVybiBuYXRpdmVXaW5kb3ctPm1hZ2ljID09IDB4NjAwOTEzOyB9ICAgIAorICAgIHZpcnR1YWwgICAgIEVHTEJvb2xlYW4gIHN3YXBCdWZmZXJzKCk7CisgICAgdmlydHVhbCAgICAgRUdMQm9vbGVhbiAgYmluZERyYXdTdXJmYWNlKG9nbGVzX2NvbnRleHRfdCogZ2wpOworICAgIHZpcnR1YWwgICAgIEVHTEJvb2xlYW4gIGJpbmRSZWFkU3VyZmFjZShvZ2xlc19jb250ZXh0X3QqIGdsKTsKKyAgICB2aXJ0dWFsICAgICBFR0xpbnQgICAgICBnZXRXaWR0aCgpIGNvbnN0ICAgIHsgcmV0dXJuIG5hdGl2ZVdpbmRvdy0+d2lkdGg7ICB9CisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0SGVpZ2h0KCkgY29uc3QgICB7IHJldHVybiBuYXRpdmVXaW5kb3ctPmhlaWdodDsgfQorICAgIHZpcnR1YWwgICAgIHZvaWQqICAgICAgIGdldEJpdHMoKSBjb25zdDsKKyAgICB2aXJ0dWFsICAgICBFR0xpbnQgICAgICBnZXRIb3Jpem9udGFsUmVzb2x1dGlvbigpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIEVHTGludCAgICAgIGdldFZlcnRpY2FsUmVzb2x1dGlvbigpIGNvbnN0OworICAgIHZpcnR1YWwgICAgIEVHTGludCAgICAgIGdldFJlZnJlc2hSYXRlKCkgY29uc3Q7CisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0U3dhcEJlaGF2aW9yKCkgY29uc3Q7Citwcml2YXRlOgorICAgIGVnbF9uYXRpdmVfd2luZG93X3QqICAgIG5hdGl2ZVdpbmRvdzsKK307CisKK2VnbF93aW5kb3dfc3VyZmFjZV90OjplZ2xfd2luZG93X3N1cmZhY2VfdChFR0xEaXNwbGF5IGRweSwKKyAgICAgICAgRUdMQ29uZmlnIGNvbmZpZywKKyAgICAgICAgaW50MzJfdCBkZXB0aEZvcm1hdCwKKyAgICAgICAgZWdsX25hdGl2ZV93aW5kb3dfdCogd2luZG93KQorICAgIDogZWdsX3N1cmZhY2VfdChkcHksIGNvbmZpZywgZGVwdGhGb3JtYXQpLCBuYXRpdmVXaW5kb3cod2luZG93KQoreworICAgIGlmIChkZXB0aEZvcm1hdCkgeworICAgICAgICBkZXB0aC53aWR0aCAgID0gd2luZG93LT53aWR0aDsKKyAgICAgICAgZGVwdGguaGVpZ2h0ICA9IHdpbmRvdy0+aGVpZ2h0OworICAgICAgICBkZXB0aC5zdHJpZGUgID0gZGVwdGgud2lkdGg7IC8vIHVzZSB0aGUgd2lkdGggaGVyZQorICAgICAgICBkZXB0aC5kYXRhICAgID0gKEdHTHVieXRlKiltYWxsb2MoZGVwdGguc3RyaWRlKmRlcHRoLmhlaWdodCoyKTsKKyAgICAgICAgaWYgKGRlcHRoLmRhdGEgPT0gMCkgeworICAgICAgICAgICAgc2V0RXJyb3IoRUdMX0JBRF9BTExPQywgRUdMX05PX1NVUkZBQ0UpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorICAgIG5hdGl2ZVdpbmRvdy0+aW5jUmVmKG5hdGl2ZVdpbmRvdyk7Cit9CitlZ2xfd2luZG93X3N1cmZhY2VfdDo6fmVnbF93aW5kb3dfc3VyZmFjZV90KCkgeworICAgIG5hdGl2ZVdpbmRvdy0+ZGVjUmVmKG5hdGl2ZVdpbmRvdyk7Cit9CisKK0VHTEJvb2xlYW4gZWdsX3dpbmRvd19zdXJmYWNlX3Q6OnN3YXBCdWZmZXJzKCkKK3sKKyAgICB1aW50MzJfdCBmbGFncyA9IG5hdGl2ZVdpbmRvdy0+c3dhcEJ1ZmZlcnMobmF0aXZlV2luZG93KTsKKyAgICBpZiAoZmxhZ3MgJiBFR0xfTkFUSVZFU19GTEFHX1NJWkVfQ0hBTkdFRCkgeworICAgICAgICAvLyBUT0RPOiB3ZSBwcm9iYWJseSBzaG91bGQgcmVzZXQgdGhlIHN3YXAgcmVjdCBoZXJlCisgICAgICAgIC8vIGlmIHRoZSB3aW5kb3cgc2l6ZSBoYXMgY2hhbmdlZAorICAgICAgICBpZiAoZGVwdGguZGF0YSkgeworICAgICAgICAgICAgZnJlZShkZXB0aC5kYXRhKTsKKyAgICAgICAgICAgIGRlcHRoLndpZHRoICAgPSBuYXRpdmVXaW5kb3ctPndpZHRoOworICAgICAgICAgICAgZGVwdGguaGVpZ2h0ICA9IG5hdGl2ZVdpbmRvdy0+aGVpZ2h0OworICAgICAgICAgICAgZGVwdGguc3RyaWRlICA9IG5hdGl2ZVdpbmRvdy0+c3RyaWRlOworICAgICAgICAgICAgZGVwdGguZGF0YSAgICA9IChHR0x1Ynl0ZSopbWFsbG9jKGRlcHRoLnN0cmlkZSpkZXB0aC5oZWlnaHQqMik7CisgICAgICAgICAgICBpZiAoZGVwdGguZGF0YSA9PSAwKSB7CisgICAgICAgICAgICAgICAgc2V0RXJyb3IoRUdMX0JBRF9BTExPQywgRUdMX05PX1NVUkZBQ0UpOworICAgICAgICAgICAgICAgIHJldHVybiBFR0xfRkFMU0U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbF93aW5kb3dfc3VyZmFjZV90OjpiaW5kRHJhd1N1cmZhY2Uob2dsZXNfY29udGV4dF90KiBnbCkKK3sKKyAgICBHR0xTdXJmYWNlIGJ1ZmZlcjsKKyAgICBidWZmZXIudmVyc2lvbiA9IHNpemVvZihHR0xTdXJmYWNlKTsKKyAgICBidWZmZXIud2lkdGggICA9IG5hdGl2ZVdpbmRvdy0+d2lkdGg7CisgICAgYnVmZmVyLmhlaWdodCAgPSBuYXRpdmVXaW5kb3ctPmhlaWdodDsKKyAgICBidWZmZXIuc3RyaWRlICA9IG5hdGl2ZVdpbmRvdy0+c3RyaWRlOworICAgIGJ1ZmZlci5kYXRhICAgID0gKEdHTHVieXRlKiluYXRpdmVXaW5kb3ctPmJhc2UgKyBuYXRpdmVXaW5kb3ctPm9mZnNldDsKKyAgICBidWZmZXIuZm9ybWF0ICA9IG5hdGl2ZVdpbmRvdy0+Zm9ybWF0OworICAgIGdsLT5yYXN0ZXJpemVyLnByb2NzLmNvbG9yQnVmZmVyKGdsLCAmYnVmZmVyKTsKKyAgICBpZiAoZGVwdGguZGF0YSAhPSBnbC0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmRlcHRoLmRhdGEpCisgICAgICAgIGdsLT5yYXN0ZXJpemVyLnByb2NzLmRlcHRoQnVmZmVyKGdsLCAmZGVwdGgpOworICAgIHJldHVybiBFR0xfVFJVRTsKK30KK0VHTEJvb2xlYW4gZWdsX3dpbmRvd19zdXJmYWNlX3Q6OmJpbmRSZWFkU3VyZmFjZShvZ2xlc19jb250ZXh0X3QqIGdsKQoreworICAgIEdHTFN1cmZhY2UgYnVmZmVyOworICAgIGJ1ZmZlci52ZXJzaW9uID0gc2l6ZW9mKEdHTFN1cmZhY2UpOworICAgIGJ1ZmZlci53aWR0aCAgID0gbmF0aXZlV2luZG93LT53aWR0aDsKKyAgICBidWZmZXIuaGVpZ2h0ICA9IG5hdGl2ZVdpbmRvdy0+aGVpZ2h0OworICAgIGJ1ZmZlci5zdHJpZGUgID0gbmF0aXZlV2luZG93LT5zdHJpZGU7CisgICAgYnVmZmVyLmRhdGEgICAgPSAoR0dMdWJ5dGUqKW5hdGl2ZVdpbmRvdy0+YmFzZSArIG5hdGl2ZVdpbmRvdy0+b2Zmc2V0OworICAgIGJ1ZmZlci5mb3JtYXQgID0gbmF0aXZlV2luZG93LT5mb3JtYXQ7CisgICAgZ2wtPnJhc3Rlcml6ZXIucHJvY3MucmVhZEJ1ZmZlcihnbCwgJmJ1ZmZlcik7CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQordm9pZCogZWdsX3dpbmRvd19zdXJmYWNlX3Q6OmdldEJpdHMoKSBjb25zdCB7CisgICAgcmV0dXJuIChHR0x1Ynl0ZSopbmF0aXZlV2luZG93LT5iYXNlICsgbmF0aXZlV2luZG93LT5vZmZzZXQ7Cit9CitFR0xpbnQgZWdsX3dpbmRvd19zdXJmYWNlX3Q6OmdldEhvcml6b250YWxSZXNvbHV0aW9uKCkgY29uc3QgeworICAgIHJldHVybiAobmF0aXZlV2luZG93LT54ZHBpICogRUdMX0RJU1BMQVlfU0NBTElORykgKiAoMS4wZiAvIDI1LjRmKTsKK30KK0VHTGludCBlZ2xfd2luZG93X3N1cmZhY2VfdDo6Z2V0VmVydGljYWxSZXNvbHV0aW9uKCkgY29uc3QgeworICAgIHJldHVybiAobmF0aXZlV2luZG93LT55ZHBpICogRUdMX0RJU1BMQVlfU0NBTElORykgKiAoMS4wZiAvIDI1LjRmKTsKK30KK0VHTGludCBlZ2xfd2luZG93X3N1cmZhY2VfdDo6Z2V0UmVmcmVzaFJhdGUoKSBjb25zdCB7CisgICAgcmV0dXJuIChuYXRpdmVXaW5kb3ctPmZwcyAqIEVHTF9ESVNQTEFZX1NDQUxJTkcpOworfQorRUdMaW50IGVnbF93aW5kb3dfc3VyZmFjZV90OjpnZXRTd2FwQmVoYXZpb3IoKSBjb25zdCB7CisgICAgdWludDMyX3QgZmxhZ3MgPSBuYXRpdmVXaW5kb3ctPmZsYWdzOworICAgIGlmIChmbGFncyAmIEVHTF9OQVRJVkVTX0ZMQUdfREVTVFJPWV9CQUNLQlVGRkVSKQorICAgICAgICByZXR1cm4gRUdMX0JVRkZFUl9ERVNUUk9ZRUQ7CisgICAgcmV0dXJuIEVHTF9CVUZGRVJfUFJFU0VSVkVEOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBlZ2xfcGl4bWFwX3N1cmZhY2VfdCA6IHB1YmxpYyBlZ2xfc3VyZmFjZV90Cit7CisgICAgZWdsX3BpeG1hcF9zdXJmYWNlX3QoCisgICAgICAgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKyAgICAgICAgICAgIGludDMyX3QgZGVwdGhGb3JtYXQsCisgICAgICAgICAgICBlZ2xfbmF0aXZlX3BpeG1hcF90IGNvbnN0ICogcGl4bWFwKTsKKworICAgIHZpcnR1YWwgfmVnbF9waXhtYXBfc3VyZmFjZV90KCkgeyB9CisKKyAgICB2aXJ0dWFsICAgICBib29sICAgICAgICBpc1ZhbGlkKCkgY29uc3QgeyByZXR1cm4gbmF0aXZlUGl4bWFwLnZlcnNpb24gPT0gc2l6ZW9mKGVnbF9uYXRpdmVfcGl4bWFwX3QpOyB9ICAgIAorICAgIHZpcnR1YWwgICAgIEVHTEJvb2xlYW4gIGJpbmREcmF3U3VyZmFjZShvZ2xlc19jb250ZXh0X3QqIGdsKTsKKyAgICB2aXJ0dWFsICAgICBFR0xCb29sZWFuICBiaW5kUmVhZFN1cmZhY2Uob2dsZXNfY29udGV4dF90KiBnbCk7CisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0V2lkdGgoKSBjb25zdCAgICB7IHJldHVybiBuYXRpdmVQaXhtYXAud2lkdGg7ICB9CisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0SGVpZ2h0KCkgY29uc3QgICB7IHJldHVybiBuYXRpdmVQaXhtYXAuaGVpZ2h0OyB9CisgICAgdmlydHVhbCAgICAgdm9pZCogICAgICAgZ2V0Qml0cygpIGNvbnN0ICAgICB7IHJldHVybiBuYXRpdmVQaXhtYXAuZGF0YTsgfQorcHJpdmF0ZToKKyAgICBlZ2xfbmF0aXZlX3BpeG1hcF90ICAgICBuYXRpdmVQaXhtYXA7Cit9OworCitlZ2xfcGl4bWFwX3N1cmZhY2VfdDo6ZWdsX3BpeG1hcF9zdXJmYWNlX3QoRUdMRGlzcGxheSBkcHksCisgICAgICAgIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgIGludDMyX3QgZGVwdGhGb3JtYXQsCisgICAgICAgIGVnbF9uYXRpdmVfcGl4bWFwX3QgY29uc3QgKiBwaXhtYXApCisgICAgOiBlZ2xfc3VyZmFjZV90KGRweSwgY29uZmlnLCBkZXB0aEZvcm1hdCksIG5hdGl2ZVBpeG1hcCgqcGl4bWFwKQoreworICAgIGlmIChkZXB0aEZvcm1hdCkgeworICAgICAgICBkZXB0aC53aWR0aCAgID0gcGl4bWFwLT53aWR0aDsKKyAgICAgICAgZGVwdGguaGVpZ2h0ICA9IHBpeG1hcC0+aGVpZ2h0OworICAgICAgICBkZXB0aC5zdHJpZGUgID0gZGVwdGgud2lkdGg7IC8vIHVzZSB0aGUgd2lkdGggaGVyZQorICAgICAgICBkZXB0aC5kYXRhICAgID0gKEdHTHVieXRlKiltYWxsb2MoZGVwdGguc3RyaWRlKmRlcHRoLmhlaWdodCoyKTsKKyAgICAgICAgaWYgKGRlcHRoLmRhdGEgPT0gMCkgeworICAgICAgICAgICAgc2V0RXJyb3IoRUdMX0JBRF9BTExPQywgRUdMX05PX1NVUkZBQ0UpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorfQorRUdMQm9vbGVhbiBlZ2xfcGl4bWFwX3N1cmZhY2VfdDo6YmluZERyYXdTdXJmYWNlKG9nbGVzX2NvbnRleHRfdCogZ2wpCit7CisgICAgR0dMU3VyZmFjZSBidWZmZXI7CisgICAgYnVmZmVyLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgYnVmZmVyLndpZHRoICAgPSBuYXRpdmVQaXhtYXAud2lkdGg7CisgICAgYnVmZmVyLmhlaWdodCAgPSBuYXRpdmVQaXhtYXAuaGVpZ2h0OworICAgIGJ1ZmZlci5zdHJpZGUgID0gbmF0aXZlUGl4bWFwLnN0cmlkZTsKKyAgICBidWZmZXIuZGF0YSAgICA9IG5hdGl2ZVBpeG1hcC5kYXRhOworICAgIGJ1ZmZlci5mb3JtYXQgID0gbmF0aXZlUGl4bWFwLmZvcm1hdDsKKyAgICAKKyAgICBnbC0+cmFzdGVyaXplci5wcm9jcy5jb2xvckJ1ZmZlcihnbCwgJmJ1ZmZlcik7CisgICAgaWYgKGRlcHRoLmRhdGEgIT0gZ2wtPnJhc3Rlcml6ZXIuc3RhdGUuYnVmZmVycy5kZXB0aC5kYXRhKQorICAgICAgICBnbC0+cmFzdGVyaXplci5wcm9jcy5kZXB0aEJ1ZmZlcihnbCwgJmRlcHRoKTsKKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CitFR0xCb29sZWFuIGVnbF9waXhtYXBfc3VyZmFjZV90OjpiaW5kUmVhZFN1cmZhY2Uob2dsZXNfY29udGV4dF90KiBnbCkKK3sKKyAgICBHR0xTdXJmYWNlIGJ1ZmZlcjsKKyAgICBidWZmZXIudmVyc2lvbiA9IHNpemVvZihHR0xTdXJmYWNlKTsKKyAgICBidWZmZXIud2lkdGggICA9IG5hdGl2ZVBpeG1hcC53aWR0aDsKKyAgICBidWZmZXIuaGVpZ2h0ICA9IG5hdGl2ZVBpeG1hcC5oZWlnaHQ7CisgICAgYnVmZmVyLnN0cmlkZSAgPSBuYXRpdmVQaXhtYXAuc3RyaWRlOworICAgIGJ1ZmZlci5kYXRhICAgID0gbmF0aXZlUGl4bWFwLmRhdGE7CisgICAgYnVmZmVyLmZvcm1hdCAgPSBuYXRpdmVQaXhtYXAuZm9ybWF0OworICAgIGdsLT5yYXN0ZXJpemVyLnByb2NzLnJlYWRCdWZmZXIoZ2wsICZidWZmZXIpOworICAgIHJldHVybiBFR0xfVFJVRTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJ1Y3QgZWdsX3BidWZmZXJfc3VyZmFjZV90IDogcHVibGljIGVnbF9zdXJmYWNlX3QKK3sKKyAgICBlZ2xfcGJ1ZmZlcl9zdXJmYWNlX3QoCisgICAgICAgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywgaW50MzJfdCBkZXB0aEZvcm1hdCwKKyAgICAgICAgICAgIGludDMyX3QgdywgaW50MzJfdCBoLCBpbnQzMl90IGYpOworCisgICAgdmlydHVhbCB+ZWdsX3BidWZmZXJfc3VyZmFjZV90KCk7CisKKyAgICB2aXJ0dWFsICAgICBib29sICAgICAgICBpc1ZhbGlkKCkgY29uc3QgeyByZXR1cm4gcGJ1ZmZlci5kYXRhICE9IDA7IH0gICAgCisgICAgdmlydHVhbCAgICAgRUdMQm9vbGVhbiAgYmluZERyYXdTdXJmYWNlKG9nbGVzX2NvbnRleHRfdCogZ2wpOworICAgIHZpcnR1YWwgICAgIEVHTEJvb2xlYW4gIGJpbmRSZWFkU3VyZmFjZShvZ2xlc19jb250ZXh0X3QqIGdsKTsKKyAgICB2aXJ0dWFsICAgICBFR0xpbnQgICAgICBnZXRXaWR0aCgpIGNvbnN0ICAgIHsgcmV0dXJuIHBidWZmZXIud2lkdGg7ICB9CisgICAgdmlydHVhbCAgICAgRUdMaW50ICAgICAgZ2V0SGVpZ2h0KCkgY29uc3QgICB7IHJldHVybiBwYnVmZmVyLmhlaWdodDsgfQorICAgIHZpcnR1YWwgICAgIHZvaWQqICAgICAgIGdldEJpdHMoKSBjb25zdCAgICAgeyByZXR1cm4gcGJ1ZmZlci5kYXRhOyB9Citwcml2YXRlOgorICAgIEdHTFN1cmZhY2UgIHBidWZmZXI7Cit9OworCitlZ2xfcGJ1ZmZlcl9zdXJmYWNlX3Q6OmVnbF9wYnVmZmVyX3N1cmZhY2VfdChFR0xEaXNwbGF5IGRweSwKKyAgICAgICAgRUdMQ29uZmlnIGNvbmZpZywgaW50MzJfdCBkZXB0aEZvcm1hdCwKKyAgICAgICAgaW50MzJfdCB3LCBpbnQzMl90IGgsIGludDMyX3QgZikKKyAgICA6IGVnbF9zdXJmYWNlX3QoZHB5LCBjb25maWcsIGRlcHRoRm9ybWF0KQoreworICAgIHNpemVfdCBzaXplID0gdypoOworICAgIHN3aXRjaCAoZikgeworICAgICAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfQV84OiAgICAgICAgICBzaXplICo9IDE7IGJyZWFrOworICAgICAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NTogICAgICBzaXplICo9IDI7IGJyZWFrOworICAgICAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4OiAgICBzaXplICo9IDQ7IGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgTE9HRSgiaW5jb21wYXRpYmxlIHBpeGVsIGZvcm1hdCBmb3IgcGJ1ZmZlciAoZm9ybWF0PSVkKSIsIGYpOworICAgICAgICAgICAgcGJ1ZmZlci5kYXRhID0gMDsKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKyAgICBwYnVmZmVyLnZlcnNpb24gPSBzaXplb2YoR0dMU3VyZmFjZSk7CisgICAgcGJ1ZmZlci53aWR0aCAgID0gdzsKKyAgICBwYnVmZmVyLmhlaWdodCAgPSBoOworICAgIHBidWZmZXIuc3RyaWRlICA9IHc7CisgICAgcGJ1ZmZlci5kYXRhICAgID0gKEdHTHVieXRlKiltYWxsb2Moc2l6ZSk7CisgICAgcGJ1ZmZlci5mb3JtYXQgID0gZjsKKyAgICAKKyAgICBpZiAoZGVwdGhGb3JtYXQpIHsKKyAgICAgICAgZGVwdGgud2lkdGggICA9IHBidWZmZXIud2lkdGg7CisgICAgICAgIGRlcHRoLmhlaWdodCAgPSBwYnVmZmVyLmhlaWdodDsKKyAgICAgICAgZGVwdGguc3RyaWRlICA9IGRlcHRoLndpZHRoOyAvLyB1c2UgdGhlIHdpZHRoIGhlcmUKKyAgICAgICAgZGVwdGguZGF0YSAgICA9IChHR0x1Ynl0ZSopbWFsbG9jKGRlcHRoLnN0cmlkZSpkZXB0aC5oZWlnaHQqMik7CisgICAgICAgIGlmIChkZXB0aC5kYXRhID09IDApIHsKKyAgICAgICAgICAgIHNldEVycm9yKEVHTF9CQURfQUxMT0MsIEVHTF9OT19TVVJGQUNFKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KK30KK2VnbF9wYnVmZmVyX3N1cmZhY2VfdDo6fmVnbF9wYnVmZmVyX3N1cmZhY2VfdCgpIHsKKyAgICBmcmVlKHBidWZmZXIuZGF0YSk7Cit9CitFR0xCb29sZWFuIGVnbF9wYnVmZmVyX3N1cmZhY2VfdDo6YmluZERyYXdTdXJmYWNlKG9nbGVzX2NvbnRleHRfdCogZ2wpCit7CisgICAgZ2wtPnJhc3Rlcml6ZXIucHJvY3MuY29sb3JCdWZmZXIoZ2wsICZwYnVmZmVyKTsKKyAgICBpZiAoZGVwdGguZGF0YSAhPSBnbC0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmRlcHRoLmRhdGEpCisgICAgICAgIGdsLT5yYXN0ZXJpemVyLnByb2NzLmRlcHRoQnVmZmVyKGdsLCAmZGVwdGgpOworICAgIHJldHVybiBFR0xfVFJVRTsKK30KK0VHTEJvb2xlYW4gZWdsX3BidWZmZXJfc3VyZmFjZV90OjpiaW5kUmVhZFN1cmZhY2Uob2dsZXNfY29udGV4dF90KiBnbCkKK3sKKyAgICBnbC0+cmFzdGVyaXplci5wcm9jcy5yZWFkQnVmZmVyKGdsLCAmcGJ1ZmZlcik7CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBjb25maWdfcGFpcl90IHsKKyAgICBHTGludCBrZXk7CisgICAgR0xpbnQgdmFsdWU7Cit9OworCitzdHJ1Y3QgY29uZmlnc190IHsKKyAgICBjb25zdCBjb25maWdfcGFpcl90KiBhcnJheTsKKyAgICBpbnQgICAgICAgICAgICAgICAgICBzaXplOworfTsKKworc3RydWN0IGNvbmZpZ19tYW5hZ2VtZW50X3QgeworICAgIEdMaW50IGtleTsKKyAgICBib29sICgqbWF0Y2gpKEdMaW50IHJlcVZhbHVlLCBHTGludCBjb25mVmFsdWUpOworICAgIHN0YXRpYyBib29sIGF0TGVhc3QoR0xpbnQgcmVxVmFsdWUsIEdMaW50IGNvbmZWYWx1ZSkgeworICAgICAgICByZXR1cm4gKHJlcVZhbHVlID09IEVHTF9ET05UX0NBUkUpIHx8IChjb25mVmFsdWUgPj0gcmVxVmFsdWUpOworICAgIH0KKyAgICBzdGF0aWMgYm9vbCBleGFjdChHTGludCByZXFWYWx1ZSwgR0xpbnQgY29uZlZhbHVlKSB7CisgICAgICAgIHJldHVybiAocmVxVmFsdWUgPT0gRUdMX0RPTlRfQ0FSRSkgfHwgKGNvbmZWYWx1ZSA9PSByZXFWYWx1ZSk7CisgICAgfQorICAgIHN0YXRpYyBib29sIG1hc2soR0xpbnQgcmVxVmFsdWUsIEdMaW50IGNvbmZWYWx1ZSkgeworICAgICAgICByZXR1cm4gKGNvbmZWYWx1ZSAmIHJlcVZhbHVlKSA9PSByZXFWYWx1ZTsKKyAgICB9Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgVkVSU0lPTl9NQUpPUiAxCisjZGVmaW5lIFZFUlNJT05fTUlOT1IgMgorc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBnVmVuZG9yU3RyaW5nICAgICA9ICJHb29nbGUgSW5jLiI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdWZXJzaW9uU3RyaW5nICAgID0gIjEuMiBBbmRyb2lkIERyaXZlciI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdDbGllbnRBcGlTdHJpbmcgID0gIk9wZW5HTCBFUyI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdFeHRlbnNpb25zU3RyaW5nID0gIiI7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RydWN0IGV4dGVudGlvbl9tYXBfdCB7CisgICAgY29uc3QgY2hhciAqIGNvbnN0IG5hbWU7CisgICAgX19lZ2xNdXN0Q2FzdFRvUHJvcGVyRnVuY3Rpb25Qb2ludGVyVHlwZSBhZGRyZXNzOworfTsKKworc3RhdGljIGNvbnN0IGV4dGVudGlvbl9tYXBfdCBnRXh0ZW50aW9uTWFwW10gPSB7CisgICAgeyAiZ2xEcmF3VGV4c09FUyIsICAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXhzT0VTIH0sCisgICAgeyAiZ2xEcmF3VGV4aU9FUyIsICAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXhpT0VTIH0sCisgICAgeyAiZ2xEcmF3VGV4Zk9FUyIsICAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXhmT0VTIH0sCisgICAgeyAiZ2xEcmF3VGV4eE9FUyIsICAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXh4T0VTIH0sCisgICAgeyAiZ2xEcmF3VGV4c3ZPRVMiLCAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXhzdk9FUyB9LAorICAgIHsgImdsRHJhd1RleGl2T0VTIiwgICAgICAgICAgICAgKHZvaWQoKikoKSkmZ2xEcmF3VGV4aXZPRVMgfSwKKyAgICB7ICJnbERyYXdUZXhmdk9FUyIsICAgICAgICAgICAgICh2b2lkKCopKCkpJmdsRHJhd1RleGZ2T0VTIH0sCisgICAgeyAiZ2xEcmF3VGV4eHZPRVMiLCAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERyYXdUZXh4dk9FUyB9LAorICAgIHsgImdsUXVlcnlNYXRyaXh4T0VTIiwgICAgICAgICAgKHZvaWQoKikoKSkmZ2xRdWVyeU1hdHJpeHhPRVMgfSwKKyAgICB7ICJnbENsaXBQbGFuZWYiLCAgICAgICAgICAgICAgICh2b2lkKCopKCkpJmdsQ2xpcFBsYW5lZiB9LAorICAgIHsgImdsQ2xpcFBsYW5leCIsICAgICAgICAgICAgICAgKHZvaWQoKikoKSkmZ2xDbGlwUGxhbmV4IH0sCisgICAgeyAiZ2xCaW5kQnVmZmVyIiwgICAgICAgICAgICAgICAodm9pZCgqKSgpKSZnbEJpbmRCdWZmZXIgfSwKKyAgICB7ICJnbEJ1ZmZlckRhdGEiLCAgICAgICAgICAgICAgICh2b2lkKCopKCkpJmdsQnVmZmVyRGF0YSB9LAorICAgIHsgImdsQnVmZmVyU3ViRGF0YSIsICAgICAgICAgICAgKHZvaWQoKikoKSkmZ2xCdWZmZXJTdWJEYXRhIH0sCisgICAgeyAiZ2xEZWxldGVCdWZmZXJzIiwgICAgICAgICAgICAodm9pZCgqKSgpKSZnbERlbGV0ZUJ1ZmZlcnMgfSwKKyAgICB7ICJnbEdlbkJ1ZmZlcnMiLCAgICAgICAgICAgICAgICh2b2lkKCopKCkpJmdsR2VuQnVmZmVycyB9LAorfTsKKworLyogCisgKiBJbiB0aGUgbGlzdHMgYmVsb3csIGF0dHJpYnV0ZXMgbmFtZXMgTVVTVCBiZSBzb3J0ZWQuCisgKiBBZGRpdGlvbmFsbHksIGFsbCBjb25maWdzIG11c3QgYmUgc29ydGVkIGFjY29yZGluZyB0bworICogdGhlIEVHTCBzcGVjaWZpY2F0aW9uLgorICovCisKK3N0YXRpYyBjb25maWdfcGFpcl90IGNvbnN0IGNvbmZpZ19iYXNlX2F0dHJpYnV0ZV9saXN0W10gPSB7CisgICAgICAgIHsgRUdMX1NURU5DSUxfU0laRSwgICAgICAgICAgICAgICAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfQ09ORklHX0NBVkVBVCwgICAgICAgICAgICAgIEVHTF9TTE9XX0NPTkZJRyAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICB7IEVHTF9MRVZFTCwgICAgICAgICAgICAgICAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX01BWF9QQlVGRkVSX0hFSUdIVCwgICAgICAgICBHR0xfTUFYX1ZJRVdQT1JUX0RJTVMgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfTUFYX1BCVUZGRVJfUElYRUxTLCAgICAgICAgIAorICAgICAgICAgICAgICAgIEdHTF9NQVhfVklFV1BPUlRfRElNUypHR0xfTUFYX1ZJRVdQT1JUX0RJTVMgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX01BWF9QQlVGRkVSX1dJRFRILCAgICAgICAgICBHR0xfTUFYX1ZJRVdQT1JUX0RJTVMgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfTkFUSVZFX1JFTkRFUkFCTEUsICAgICAgICAgIEVHTF9UUlVFICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICB7IEVHTF9OQVRJVkVfVklTVUFMX0lELCAgICAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX05BVElWRV9WSVNVQUxfVFlQRSwgICAgICAgICBHR0xfUElYRUxfRk9STUFUX1JHQl81NjUgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfU0FNUExFUywgICAgICAgICAgICAgICAgICAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICB7IEVHTF9TQU1QTEVfQlVGRkVSUywgICAgICAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX1RSQU5TUEFSRU5UX1RZUEUsICAgICAgICAgICBFR0xfTk9ORSAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfVFJBTlNQQVJFTlRfQkxVRV9WQUxVRSwgICAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICB7IEVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRSwgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX1RSQU5TUEFSRU5UX1JFRF9WQUxVRSwgICAgICAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfQklORF9UT19URVhUVVJFX1JHQkEsICAgICAgIEVHTF9GQUxTRSAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICB7IEVHTF9CSU5EX1RPX1RFWFRVUkVfUkdCLCAgICAgICAgRUdMX0ZBTFNFICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgIHsgRUdMX01JTl9TV0FQX0lOVEVSVkFMLCAgICAgICAgICAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgeyBFR0xfTUFYX1NXQVBfSU5URVJWQUwsICAgICAgICAgIDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorfTsKKworLy8gVGhlc2UgY29uZmlncyBjYW4gb3ZlcnJpZGUgdGhlIGJhc2UgYXR0cmlidXRlIGxpc3QKKy8vIE5PVEU6IHdoZW4gYWRkaW5nIGEgY29uZmlnIGhlcmUsIGRvbid0IGZvcmdldCB0byB1cGRhdGUgZWdsQ3JlYXRlKlN1cmZhY2UoKQorCitzdGF0aWMgY29uZmlnX3BhaXJfdCBjb25zdCBjb25maWdfMF9hdHRyaWJ1dGVfbGlzdFtdID0geworICAgICAgICB7IEVHTF9CVUZGRVJfU0laRSwgICAgIDE2IH0sCisgICAgICAgIHsgRUdMX0FMUEhBX1NJWkUsICAgICAgIDAgfSwKKyAgICAgICAgeyBFR0xfQkxVRV9TSVpFLCAgICAgICAgNSB9LAorICAgICAgICB7IEVHTF9HUkVFTl9TSVpFLCAgICAgICA2IH0sCisgICAgICAgIHsgRUdMX1JFRF9TSVpFLCAgICAgICAgIDUgfSwKKyAgICAgICAgeyBFR0xfREVQVEhfU0laRSwgICAgICAgMCB9LAorICAgICAgICB7IEVHTF9DT05GSUdfSUQsICAgICAgICAwIH0sCisgICAgICAgIHsgRUdMX1NVUkZBQ0VfVFlQRSwgICAgIEVHTF9XSU5ET1dfQklUfEVHTF9QQlVGRkVSX0JJVHxFR0xfUElYTUFQX0JJVCB9LAorfTsKKworc3RhdGljIGNvbmZpZ19wYWlyX3QgY29uc3QgY29uZmlnXzFfYXR0cmlidXRlX2xpc3RbXSA9IHsKKyAgICAgICAgeyBFR0xfQlVGRkVSX1NJWkUsICAgICAxNiB9LAorICAgICAgICB7IEVHTF9BTFBIQV9TSVpFLCAgICAgICAwIH0sCisgICAgICAgIHsgRUdMX0JMVUVfU0laRSwgICAgICAgIDUgfSwKKyAgICAgICAgeyBFR0xfR1JFRU5fU0laRSwgICAgICAgNiB9LAorICAgICAgICB7IEVHTF9SRURfU0laRSwgICAgICAgICA1IH0sCisgICAgICAgIHsgRUdMX0RFUFRIX1NJWkUsICAgICAgMTYgfSwKKyAgICAgICAgeyBFR0xfQ09ORklHX0lELCAgICAgICAgMSB9LAorICAgICAgICB7IEVHTF9TVVJGQUNFX1RZUEUsICAgICBFR0xfV0lORE9XX0JJVHxFR0xfUEJVRkZFUl9CSVR8RUdMX1BJWE1BUF9CSVQgfSwKK307CisKK3N0YXRpYyBjb25maWdfcGFpcl90IGNvbnN0IGNvbmZpZ18yX2F0dHJpYnV0ZV9saXN0W10gPSB7CisgICAgICAgIHsgRUdMX0JVRkZFUl9TSVpFLCAgICAgMzIgfSwKKyAgICAgICAgeyBFR0xfQUxQSEFfU0laRSwgICAgICAgOCB9LAorICAgICAgICB7IEVHTF9CTFVFX1NJWkUsICAgICAgICA4IH0sCisgICAgICAgIHsgRUdMX0dSRUVOX1NJWkUsICAgICAgIDggfSwKKyAgICAgICAgeyBFR0xfUkVEX1NJWkUsICAgICAgICAgOCB9LAorICAgICAgICB7IEVHTF9ERVBUSF9TSVpFLCAgICAgICAwIH0sCisgICAgICAgIHsgRUdMX0NPTkZJR19JRCwgICAgICAgIDIgfSwKKyAgICAgICAgeyBFR0xfU1VSRkFDRV9UWVBFLCAgICAgRUdMX1dJTkRPV19CSVR8RUdMX1BCVUZGRVJfQklUfEVHTF9QSVhNQVBfQklUIH0sCit9OworCitzdGF0aWMgY29uZmlnX3BhaXJfdCBjb25zdCBjb25maWdfM19hdHRyaWJ1dGVfbGlzdFtdID0geworICAgICAgICB7IEVHTF9CVUZGRVJfU0laRSwgICAgIDMyIH0sCisgICAgICAgIHsgRUdMX0FMUEhBX1NJWkUsICAgICAgIDggfSwKKyAgICAgICAgeyBFR0xfQkxVRV9TSVpFLCAgICAgICAgOCB9LAorICAgICAgICB7IEVHTF9HUkVFTl9TSVpFLCAgICAgICA4IH0sCisgICAgICAgIHsgRUdMX1JFRF9TSVpFLCAgICAgICAgIDggfSwKKyAgICAgICAgeyBFR0xfREVQVEhfU0laRSwgICAgICAxNiB9LAorICAgICAgICB7IEVHTF9DT05GSUdfSUQsICAgICAgICAzIH0sCisgICAgICAgIHsgRUdMX1NVUkZBQ0VfVFlQRSwgICAgIEVHTF9XSU5ET1dfQklUfEVHTF9QQlVGRkVSX0JJVHxFR0xfUElYTUFQX0JJVCB9LAorfTsKKworc3RhdGljIGNvbmZpZ19wYWlyX3QgY29uc3QgY29uZmlnXzRfYXR0cmlidXRlX2xpc3RbXSA9IHsKKyAgICAgICAgeyBFR0xfQlVGRkVSX1NJWkUsICAgICAgOCB9LAorICAgICAgICB7IEVHTF9BTFBIQV9TSVpFLCAgICAgICA4IH0sCisgICAgICAgIHsgRUdMX0JMVUVfU0laRSwgICAgICAgIDAgfSwKKyAgICAgICAgeyBFR0xfR1JFRU5fU0laRSwgICAgICAgMCB9LAorICAgICAgICB7IEVHTF9SRURfU0laRSwgICAgICAgICAwIH0sCisgICAgICAgIHsgRUdMX0RFUFRIX1NJWkUsICAgICAgIDAgfSwKKyAgICAgICAgeyBFR0xfQ09ORklHX0lELCAgICAgICAgNCB9LAorICAgICAgICB7IEVHTF9TVVJGQUNFX1RZUEUsICAgICBFR0xfV0lORE9XX0JJVHxFR0xfUEJVRkZFUl9CSVR8RUdMX1BJWE1BUF9CSVQgfSwKK307CisKK3N0YXRpYyBjb25maWdfcGFpcl90IGNvbnN0IGNvbmZpZ181X2F0dHJpYnV0ZV9saXN0W10gPSB7CisgICAgICAgIHsgRUdMX0JVRkZFUl9TSVpFLCAgICAgIDggfSwKKyAgICAgICAgeyBFR0xfQUxQSEFfU0laRSwgICAgICAgOCB9LAorICAgICAgICB7IEVHTF9CTFVFX1NJWkUsICAgICAgICAwIH0sCisgICAgICAgIHsgRUdMX0dSRUVOX1NJWkUsICAgICAgIDAgfSwKKyAgICAgICAgeyBFR0xfUkVEX1NJWkUsICAgICAgICAgMCB9LAorICAgICAgICB7IEVHTF9ERVBUSF9TSVpFLCAgICAgIDE2IH0sCisgICAgICAgIHsgRUdMX0NPTkZJR19JRCwgICAgICAgIDUgfSwKKyAgICAgICAgeyBFR0xfU1VSRkFDRV9UWVBFLCAgICAgRUdMX1dJTkRPV19CSVR8RUdMX1BCVUZGRVJfQklUfEVHTF9QSVhNQVBfQklUIH0sCit9OworCitzdGF0aWMgY29uZmlnc190IGNvbnN0IGdDb25maWdzW10gPSB7CisgICAgICAgIHsgY29uZmlnXzBfYXR0cmlidXRlX2xpc3QsIE5FTEVNKGNvbmZpZ18wX2F0dHJpYnV0ZV9saXN0KSB9LAorICAgICAgICB7IGNvbmZpZ18xX2F0dHJpYnV0ZV9saXN0LCBORUxFTShjb25maWdfMV9hdHRyaWJ1dGVfbGlzdCkgfSwKKyAgICAgICAgeyBjb25maWdfMl9hdHRyaWJ1dGVfbGlzdCwgTkVMRU0oY29uZmlnXzJfYXR0cmlidXRlX2xpc3QpIH0sCisgICAgICAgIHsgY29uZmlnXzNfYXR0cmlidXRlX2xpc3QsIE5FTEVNKGNvbmZpZ18zX2F0dHJpYnV0ZV9saXN0KSB9LAorICAgICAgICB7IGNvbmZpZ180X2F0dHJpYnV0ZV9saXN0LCBORUxFTShjb25maWdfNF9hdHRyaWJ1dGVfbGlzdCkgfSwKKyAgICAgICAgeyBjb25maWdfNV9hdHRyaWJ1dGVfbGlzdCwgTkVMRU0oY29uZmlnXzVfYXR0cmlidXRlX2xpc3QpIH0sCit9OworCitzdGF0aWMgY29uZmlnX21hbmFnZW1lbnRfdCBjb25zdCBnQ29uZmlnTWFuYWdlbWVudFtdID0geworICAgICAgICB7IEVHTF9CVUZGRVJfU0laRSwgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9BTFBIQV9TSVpFLCAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9CTFVFX1NJWkUsICAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9HUkVFTl9TSVpFLCAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9SRURfU0laRSwgICAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9ERVBUSF9TSVpFLCAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9TVEVOQ0lMX1NJWkUsICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6YXRMZWFzdCB9LAorICAgICAgICB7IEVHTF9DT05GSUdfQ0FWRUFULCAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9DT05GSUdfSUQsICAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9MRVZFTCwgICAgICAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9NQVhfUEJVRkZFUl9IRUlHSFQsICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9NQVhfUEJVRkZFUl9QSVhFTFMsICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9NQVhfUEJVRkZFUl9XSURUSCwgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9OQVRJVkVfUkVOREVSQUJMRSwgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9OQVRJVkVfVklTVUFMX0lELCAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9OQVRJVkVfVklTVUFMX1RZUEUsICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9TQU1QTEVTLCAgICAgICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9TQU1QTEVfQlVGRkVSUywgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9TVVJGQUNFX1RZUEUsICAgICAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6bWFzayAgICB9LAorICAgICAgICB7IEVHTF9UUkFOU1BBUkVOVF9UWVBFLCAgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9UUkFOU1BBUkVOVF9CTFVFX1ZBTFVFLCAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRSwgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9UUkFOU1BBUkVOVF9SRURfVkFMVUUsICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9CSU5EX1RPX1RFWFRVUkVfUkdCQSwgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9CSU5EX1RPX1RFWFRVUkVfUkdCLCAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9NSU5fU1dBUF9JTlRFUlZBTCwgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorICAgICAgICB7IEVHTF9NQVhfU1dBUF9JTlRFUlZBTCwgICAgICAgICAgY29uZmlnX21hbmFnZW1lbnRfdDo6ZXhhY3QgICB9LAorfTsKKworc3RhdGljIGNvbmZpZ19wYWlyX3QgY29uc3QgY29uZmlnX2RlZmF1bHRzW10gPSB7CisgICAgICAgIHsgRUdMX1NVUkZBQ0VfVFlQRSwgICAgICAgIEVHTF9XSU5ET1dfQklUIH0sCit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChUIGNvbnN0IHNvcnRlZEFycmF5W10sIGludCBmaXJzdCwgaW50IGxhc3QsIEVHTGludCBrZXkpCit7CisgICB3aGlsZSAoZmlyc3QgPD0gbGFzdCkgeworICAgICAgIGludCBtaWQgPSAoZmlyc3QgKyBsYXN0KSAvIDI7CisgICAgICAgaWYgKGtleSA+IHNvcnRlZEFycmF5W21pZF0ua2V5KSB7IAorICAgICAgICAgICBmaXJzdCA9IG1pZCArIDE7CisgICAgICAgfSBlbHNlIGlmIChrZXkgPCBzb3J0ZWRBcnJheVttaWRdLmtleSkgeyAKKyAgICAgICAgICAgbGFzdCA9IG1pZCAtIDE7CisgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgcmV0dXJuIG1pZDsKKyAgICAgICB9CisgICB9CisgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBpbnQgaXNBdHRyaWJ1dGVNYXRjaGluZyhpbnQgaSwgRUdMaW50IGF0dHIsIEVHTGludCB2YWwpCit7CisgICAgLy8gbG9vayBmb3IgdGhlIGF0dHJpYnV0ZSBpbiBhbGwgb2Ygb3VyIGNvbmZpZ3MKKyAgICBjb25maWdfcGFpcl90IGNvbnN0KiBjb25maWdGb3VuZCA9IGdDb25maWdzW2ldLmFycmF5OyAKKyAgICBpbnQgaW5kZXggPSBiaW5hcnlTZWFyY2g8Y29uZmlnX3BhaXJfdD4oCisgICAgICAgICAgICBnQ29uZmlnc1tpXS5hcnJheSwKKyAgICAgICAgICAgIDAsIGdDb25maWdzW2ldLnNpemUtMSwKKyAgICAgICAgICAgIGF0dHIpOworICAgIGlmIChpbmRleCA8IDApIHsKKyAgICAgICAgY29uZmlnRm91bmQgPSBjb25maWdfYmFzZV9hdHRyaWJ1dGVfbGlzdDsgCisgICAgICAgIGluZGV4ID0gYmluYXJ5U2VhcmNoPGNvbmZpZ19wYWlyX3Q+KAorICAgICAgICAgICAgICAgIGNvbmZpZ19iYXNlX2F0dHJpYnV0ZV9saXN0LAorICAgICAgICAgICAgICAgIDAsIE5FTEVNKGNvbmZpZ19iYXNlX2F0dHJpYnV0ZV9saXN0KS0xLAorICAgICAgICAgICAgICAgIGF0dHIpOworICAgIH0KKyAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICAvLyBhdHRyaWJ1dGUgZm91bmQsIGNoZWNrIGlmIHRoaXMgY29uZmlnIGNvdWxkIG1hdGNoCisgICAgICAgIGludCBjZmdNZ3RJbmRleCA9IGJpbmFyeVNlYXJjaDxjb25maWdfbWFuYWdlbWVudF90PigKKyAgICAgICAgICAgICAgICBnQ29uZmlnTWFuYWdlbWVudCwKKyAgICAgICAgICAgICAgICAwLCBORUxFTShnQ29uZmlnTWFuYWdlbWVudCktMSwKKyAgICAgICAgICAgICAgICBhdHRyKTsKKyAgICAgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgICAgICAgIGJvb2wgbWF0Y2ggPSBnQ29uZmlnTWFuYWdlbWVudFtjZmdNZ3RJbmRleF0ubWF0Y2goCisgICAgICAgICAgICAgICAgICAgIHZhbCwgY29uZmlnRm91bmRbaW5kZXhdLnZhbHVlKTsKKyAgICAgICAgICAgIGlmIChtYXRjaCkgeworICAgICAgICAgICAgICAgIC8vIHRoaXMgY29uZmlnIG1hdGNoZXMKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSBub3QgZm91bmQuIHRoaXMgc2hvdWxkIE5FVkVSIGhhcHBlbi4KKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8vIGVycm9yLCB0aGlzIGF0dHJpYnV0ZSBkb2Vzbid0IGV4aXN0CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IG1ha2VDdXJyZW50KG9nbGVzX2NvbnRleHRfdCogZ2wpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjdXJyZW50ID0gKG9nbGVzX2NvbnRleHRfdCopZ2V0R2xUaHJlYWRTcGVjaWZpYygpOworICAgIGlmIChnbCkgeworICAgICAgICBlZ2xfY29udGV4dF90KiBjID0gZWdsX2NvbnRleHRfdDo6Y29udGV4dChnbCk7CisgICAgICAgIGlmIChjLT5mbGFncyAmIGVnbF9jb250ZXh0X3Q6OklTX0NVUlJFTlQpIHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50ICE9IGdsKSB7CisgICAgICAgICAgICAgICAgLy8gaXQgaXMgYW4gZXJyb3IgdG8gc2V0IGEgY29udGV4dCBjdXJyZW50LCBpZiBpdCdzIGFscmVhZHkKKyAgICAgICAgICAgICAgICAvLyBjdXJyZW50IHRvIGFub3RoZXIgdGhyZWFkCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGN1cnJlbnQpIHsKKyAgICAgICAgICAgICAgICAvLyBtYXJrIHRoZSBjdXJyZW50IGNvbnRleHQgYXMgbm90IGN1cnJlbnQsIGFuZCBmbHVzaAorICAgICAgICAgICAgICAgIGdsRmx1c2goKTsKKyAgICAgICAgICAgICAgICBlZ2xfY29udGV4dF90Ojpjb250ZXh0KGN1cnJlbnQpLT5mbGFncyAmPSB+ZWdsX2NvbnRleHRfdDo6SVNfQ1VSUkVOVDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoIShjLT5mbGFncyAmIGVnbF9jb250ZXh0X3Q6OklTX0NVUlJFTlQpKSB7CisgICAgICAgICAgICAvLyBUaGUgY29udGV4dCBpcyBub3QgY3VycmVudCwgbWFrZSBpdCBjdXJyZW50IQorICAgICAgICAgICAgc2V0R2xUaHJlYWRTcGVjaWZpYyhnbCk7CisgICAgICAgICAgICBjLT5mbGFncyB8PSBlZ2xfY29udGV4dF90OjpJU19DVVJSRU5UOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGN1cnJlbnQpIHsKKyAgICAgICAgICAgIC8vIG1hcmsgdGhlIGN1cnJlbnQgY29udGV4dCBhcyBub3QgY3VycmVudCwgYW5kIGZsdXNoCisgICAgICAgICAgICBnbEZsdXNoKCk7CisgICAgICAgICAgICBlZ2xfY29udGV4dF90Ojpjb250ZXh0KGN1cnJlbnQpLT5mbGFncyAmPSB+ZWdsX2NvbnRleHRfdDo6SVNfQ1VSUkVOVDsKKyAgICAgICAgfQorICAgICAgICAvLyB0aGlzIHRocmVhZCBoYXMgbm8gY29udGV4dCBhdHRhY2hlZCB0byBpdAorICAgICAgICBzZXRHbFRocmVhZFNwZWNpZmljKDApOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIEVHTEJvb2xlYW4gZ2V0Q29uZmlnQXR0cmliKEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgKnZhbHVlKQoreworICAgIHNpemVfdCBudW1Db25maWdzID0gIE5FTEVNKGdDb25maWdzKTsKKyAgICBpbnQgaW5kZXggPSAoaW50KWNvbmZpZzsKKyAgICBpZiAodWludDMyX3QoaW5kZXgpID49IG51bUNvbmZpZ3MpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTkZJRywgRUdMX0ZBTFNFKTsKKworICAgIGludCBhdHRySW5kZXg7CisgICAgYXR0ckluZGV4ID0gYmluYXJ5U2VhcmNoPGNvbmZpZ19wYWlyX3Q+KAorICAgICAgICAgICAgZ0NvbmZpZ3NbaW5kZXhdLmFycmF5LAorICAgICAgICAgICAgMCwgZ0NvbmZpZ3NbaW5kZXhdLnNpemUtMSwKKyAgICAgICAgICAgIGF0dHJpYnV0ZSk7CisgICAgaWYgKGF0dHJJbmRleD49MCkgeworICAgICAgICAqdmFsdWUgPSBnQ29uZmlnc1tpbmRleF0uYXJyYXlbYXR0ckluZGV4XS52YWx1ZTsKKyAgICAgICAgcmV0dXJuIEVHTF9UUlVFOworICAgIH0KKworICAgIGF0dHJJbmRleCA9IGJpbmFyeVNlYXJjaDxjb25maWdfcGFpcl90PigKKyAgICAgICAgICAgIGNvbmZpZ19iYXNlX2F0dHJpYnV0ZV9saXN0LAorICAgICAgICAgICAgMCwgTkVMRU0oY29uZmlnX2Jhc2VfYXR0cmlidXRlX2xpc3QpLTEsCisgICAgICAgICAgICBhdHRyaWJ1dGUpOworICAgIGlmIChhdHRySW5kZXg+PTApIHsKKyAgICAgICAgKnZhbHVlID0gY29uZmlnX2Jhc2VfYXR0cmlidXRlX2xpc3RbYXR0ckluZGV4XS52YWx1ZTsKKyAgICAgICAgcmV0dXJuIEVHTF9UUlVFOworICAgIH0KKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9BVFRSSUJVVEUsIEVHTF9GQUxTRSk7Cit9CisKK3N0YXRpYyBFR0xTdXJmYWNlIGNyZWF0ZVdpbmRvd1N1cmZhY2UoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgIE5hdGl2ZVdpbmRvd1R5cGUgd2luZG93LCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX05PX1NVUkZBQ0UpOworICAgIGlmICh3aW5kb3cgPT0gMCkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9OT19TVVJGQUNFKTsKKworICAgIEVHTGludCBzdXJmYWNlVHlwZTsKKyAgICBpZiAoZ2V0Q29uZmlnQXR0cmliKGRweSwgY29uZmlnLCBFR0xfU1VSRkFDRV9UWVBFLCAmc3VyZmFjZVR5cGUpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsKKworICAgIGlmICghKHN1cmZhY2VUeXBlICYgRUdMX1dJTkRPV19CSVQpKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9NQVRDSCwgRUdMX05PX1NVUkZBQ0UpOworCisgICAgRUdMaW50IGNvbmZpZ0lEOworICAgIGlmIChnZXRDb25maWdBdHRyaWIoZHB5LCBjb25maWcsIEVHTF9DT05GSUdfSUQsICZjb25maWdJRCkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOworCisgICAgaW50MzJfdCBkZXB0aEZvcm1hdDsKKyAgICBpbnQzMl90IHBpeGVsRm9ybWF0OworICAgIHN3aXRjaChjb25maWdJRCkgeworICAgIGNhc2UgMDogCisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgMjoKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1JHQkFfODg4ODsgCisgICAgICAgIGRlcHRoRm9ybWF0ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAzOgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgNDoKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX0FfODsgCisgICAgICAgIGRlcHRoRm9ybWF0ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSA1OgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfQV84OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfTk9fU1VSRkFDRSk7CisgICAgfQorCisgICAgLy8gRklYTUU6IHdlIGRvbid0IGhhdmUgYWNjZXNzIHRvIHRoZSBwaXhlbEZvcm1hdCBoZXJlIGp1c3QgeWV0LgorICAgIC8vIChpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHN1cmZhY2UgaXMgbm90IGZ1bGx5IGluaXRpYWxpemVkKQorICAgIC8vIG1heWJlIHRoaXMgc2hvdWxkIGJlIGRvbmUgYWZ0ZXIgdGhlIHBhZ2UtZmxpcAorICAgIC8vaWYgKEVHTGludChpbmZvLmZvcm1hdCkgIT0gcGl4ZWxGb3JtYXQpCisgICAgLy8gICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9OT19TVVJGQUNFKTsKKworICAgIGVnbF9zdXJmYWNlX3QqIHN1cmZhY2UgPQorICAgICAgICBuZXcgZWdsX3dpbmRvd19zdXJmYWNlX3QoZHB5LCBjb25maWcsIGRlcHRoRm9ybWF0LAorICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PGVnbF9uYXRpdmVfd2luZG93X3QqPih3aW5kb3cpKTsKKworICAgIGlmICghc3VyZmFjZS0+aXNWYWxpZCgpKSB7CisgICAgICAgIC8vIHRoZXJlIHdhcyBhIHByb2JsZW0gaW4gdGhlIGN0b3IsIHRoZSBlcnJvcgorICAgICAgICAvLyBmbGFnIGhhcyBiZWVuIHNldC4KKyAgICAgICAgZGVsZXRlIHN1cmZhY2U7CisgICAgICAgIHN1cmZhY2UgPSAwOworICAgIH0KKyAgICByZXR1cm4gc3VyZmFjZTsKK30KKworc3RhdGljIEVHTFN1cmZhY2UgY3JlYXRlUGl4bWFwU3VyZmFjZShFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKyAgICAgICAgTmF0aXZlUGl4bWFwVHlwZSBwaXhtYXAsIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfTk9fU1VSRkFDRSk7CisgICAgaWYgKHBpeG1hcCA9PSAwKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9NQVRDSCwgRUdMX05PX1NVUkZBQ0UpOworCisgICAgRUdMaW50IHN1cmZhY2VUeXBlOworICAgIGlmIChnZXRDb25maWdBdHRyaWIoZHB5LCBjb25maWcsIEVHTF9TVVJGQUNFX1RZUEUsICZzdXJmYWNlVHlwZSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOworCisgICAgaWYgKCEoc3VyZmFjZVR5cGUgJiBFR0xfUElYTUFQX0JJVCkpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfTk9fU1VSRkFDRSk7CisKKyAgICBFR0xpbnQgY29uZmlnSUQ7CisgICAgaWYgKGdldENvbmZpZ0F0dHJpYihkcHksIGNvbmZpZywgRUdMX0NPTkZJR19JRCwgJmNvbmZpZ0lEKSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBFR0xfRkFMU0U7CisKKyAgICBpbnQzMl90IGRlcHRoRm9ybWF0OworICAgIGludDMyX3QgcGl4ZWxGb3JtYXQ7CisgICAgc3dpdGNoKGNvbmZpZ0lEKSB7CisgICAgY2FzZSAwOiAKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1JHQl81NjU7IAorICAgICAgICBkZXB0aEZvcm1hdCA9IDA7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgMToKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1JHQl81NjU7IAorICAgICAgICBkZXB0aEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfWl8xNjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAyOgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDM6CisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzg4ODg7IAorICAgICAgICBkZXB0aEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfWl8xNjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSA0OgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfQV84OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDU6CisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9BXzg7IAorICAgICAgICBkZXB0aEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfWl8xNjsKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9OT19TVVJGQUNFKTsKKyAgICB9CisKKyAgICBpZiAocGl4bWFwLT5mb3JtYXQgIT0gcGl4ZWxGb3JtYXQpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfTk9fU1VSRkFDRSk7CisKKyAgICBlZ2xfc3VyZmFjZV90KiBzdXJmYWNlID0KKyAgICAgICAgbmV3IGVnbF9waXhtYXBfc3VyZmFjZV90KGRweSwgY29uZmlnLCBkZXB0aEZvcm1hdCwKKyAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxlZ2xfbmF0aXZlX3BpeG1hcF90Kj4ocGl4bWFwKSk7CisKKyAgICBpZiAoIXN1cmZhY2UtPmlzVmFsaWQoKSkgeworICAgICAgICAvLyB0aGVyZSB3YXMgYSBwcm9ibGVtIGluIHRoZSBjdG9yLCB0aGUgZXJyb3IKKyAgICAgICAgLy8gZmxhZyBoYXMgYmVlbiBzZXQuCisgICAgICAgIGRlbGV0ZSBzdXJmYWNlOworICAgICAgICBzdXJmYWNlID0gMDsKKyAgICB9CisgICAgcmV0dXJuIHN1cmZhY2U7Cit9CisKK3N0YXRpYyBFR0xTdXJmYWNlIGNyZWF0ZVBidWZmZXJTdXJmYWNlKEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX05PX1NVUkZBQ0UpOworCisgICAgRUdMaW50IHN1cmZhY2VUeXBlOworICAgIGlmIChnZXRDb25maWdBdHRyaWIoZHB5LCBjb25maWcsIEVHTF9TVVJGQUNFX1RZUEUsICZzdXJmYWNlVHlwZSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOworICAgIAorICAgIGlmICghKHN1cmZhY2VUeXBlICYgRUdMX1BCVUZGRVJfQklUKSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9OT19TVVJGQUNFKTsKKyAgICAgICAgCisgICAgRUdMaW50IGNvbmZpZ0lEOworICAgIGlmIChnZXRDb25maWdBdHRyaWIoZHB5LCBjb25maWcsIEVHTF9DT05GSUdfSUQsICZjb25maWdJRCkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOworCisgICAgaW50MzJfdCBkZXB0aEZvcm1hdDsKKyAgICBpbnQzMl90IHBpeGVsRm9ybWF0OworICAgIHN3aXRjaChjb25maWdJRCkgeworICAgIGNhc2UgMDogCisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICAgIHBpeGVsRm9ybWF0ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgMjoKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1JHQkFfODg4ODsgCisgICAgICAgIGRlcHRoRm9ybWF0ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAzOgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfUkdCQV84ODg4OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgNDoKKyAgICAgICAgcGl4ZWxGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX0FfODsgCisgICAgICAgIGRlcHRoRm9ybWF0ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSA1OgorICAgICAgICBwaXhlbEZvcm1hdCA9IEdHTF9QSVhFTF9GT1JNQVRfQV84OyAKKyAgICAgICAgZGVwdGhGb3JtYXQgPSBHR0xfUElYRUxfRk9STUFUX1pfMTY7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfTk9fU1VSRkFDRSk7CisgICAgfQorCisgICAgaW50MzJfdCB3ID0gMDsKKyAgICBpbnQzMl90IGggPSAwOworICAgIHdoaWxlIChhdHRyaWJfbGlzdFswXSkgeworICAgICAgICBpZiAoYXR0cmliX2xpc3RbMF0gPT0gRUdMX1dJRFRIKSAgdyA9IGF0dHJpYl9saXN0WzFdOworICAgICAgICBpZiAoYXR0cmliX2xpc3RbMF0gPT0gRUdMX0hFSUdIVCkgaCA9IGF0dHJpYl9saXN0WzFdOworICAgICAgICBhdHRyaWJfbGlzdCs9MjsKKyAgICB9CisKKyAgICBlZ2xfc3VyZmFjZV90KiBzdXJmYWNlID0KKyAgICAgICAgbmV3IGVnbF9wYnVmZmVyX3N1cmZhY2VfdChkcHksIGNvbmZpZywgZGVwdGhGb3JtYXQsIHcsIGgsIHBpeGVsRm9ybWF0KTsKKworICAgIGlmICghc3VyZmFjZS0+aXNWYWxpZCgpKSB7CisgICAgICAgIC8vIHRoZXJlIHdhcyBhIHByb2JsZW0gaW4gdGhlIGN0b3IsIHRoZSBlcnJvcgorICAgICAgICAvLyBmbGFnIGhhcyBiZWVuIHNldC4KKyAgICAgICAgZGVsZXRlIHN1cmZhY2U7CisgICAgICAgIHN1cmZhY2UgPSAwOworICAgIH0KKyAgICByZXR1cm4gc3VyZmFjZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEluaXRpYWxpemF0aW9uCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0VHTERpc3BsYXkgZWdsR2V0RGlzcGxheShOYXRpdmVEaXNwbGF5VHlwZSBkaXNwbGF5KQoreworI2lmbmRlZiBIQVZFX0FORFJPSURfT1MKKyAgICAvLyB0aGlzIGp1c3QgbmVlZHMgdG8gYmUgZG9uZSBvbmNlCisgICAgaWYgKGdHTEtleSA9PSAtMSkgeworICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJmdJbml0TXV0ZXgpOworICAgICAgICBpZiAoZ0dMS2V5ID09IC0xKQorICAgICAgICAgICAgcHRocmVhZF9rZXlfY3JlYXRlKCZnR0xLZXksIE5VTEwpOworICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ0luaXRNdXRleCk7CisgICAgfQorI2VuZGlmCisgICAgaWYgKGRpc3BsYXkgPT0gRUdMX0RFRkFVTFRfRElTUExBWSkgeworICAgICAgICBFR0xEaXNwbGF5IGRweSA9IChFR0xEaXNwbGF5KTE7CisgICAgICAgIGVnbF9kaXNwbGF5X3QmIGQgPSBlZ2xfZGlzcGxheV90OjpnZXRfZGlzcGxheShkcHkpOworICAgICAgICBkLnR5cGUgPSBkaXNwbGF5OworICAgICAgICByZXR1cm4gZHB5OworICAgIH0gICAgCisgICAgcmV0dXJuIEVHTF9OT19ESVNQTEFZOworfQorCitFR0xCb29sZWFuIGVnbEluaXRpYWxpemUoRUdMRGlzcGxheSBkcHksIEVHTGludCAqbWFqb3IsIEVHTGludCAqbWlub3IpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworICAgIAorICAgIEVHTEJvb2xlYW4gcmVzID0gRUdMX1RSVUU7CisgICAgZWdsX2Rpc3BsYXlfdCYgZCA9IGVnbF9kaXNwbGF5X3Q6OmdldF9kaXNwbGF5KGRweSk7CisgICAgCisgICAgaWYgKGFuZHJvaWRfYXRvbWljX2luYygmZC5pbml0aWFsaXplZCkgPT0gMCkgeworICAgICAgICAvLyBpbml0aWFsaXplIHN0dWZmIGhlcmUgaWYgbmVlZGVkCisgICAgICAgIC8vcHRocmVhZF9tdXRleF9sb2NrKCZnSW5pdE11dGV4KTsKKyAgICAgICAgLy9wdGhyZWFkX211dGV4X3VubG9jaygmZ0luaXRNdXRleCk7CisgICAgfQorCisgICAgaWYgKHJlcyA9PSBFR0xfVFJVRSkgeworICAgICAgICBpZiAobWFqb3IgIT0gTlVMTCkgKm1ham9yID0gVkVSU0lPTl9NQUpPUjsKKyAgICAgICAgaWYgKG1pbm9yICE9IE5VTEwpICptaW5vciA9IFZFUlNJT05fTUlOT1I7CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisKK0VHTEJvb2xlYW4gZWdsVGVybWluYXRlKEVHTERpc3BsYXkgZHB5KQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKworICAgIEVHTEJvb2xlYW4gcmVzID0gRUdMX1RSVUU7CisgICAgZWdsX2Rpc3BsYXlfdCYgZCA9IGVnbF9kaXNwbGF5X3Q6OmdldF9kaXNwbGF5KGRweSk7CisgICAgaWYgKGFuZHJvaWRfYXRvbWljX2RlYygmZC5pbml0aWFsaXplZCkgPT0gMSkgeworICAgICAgICAvLyBUT0RPOiBkZXN0cm95IGFsbCByZXNvdXJjZXMgKHN1cmZhY2VzLCBjb250ZXh0cywgZXRjLi4uKQorICAgICAgICAvL3B0aHJlYWRfbXV0ZXhfbG9jaygmZ0luaXRNdXRleCk7CisgICAgICAgIC8vcHRocmVhZF9tdXRleF91bmxvY2soJmdJbml0TXV0ZXgpOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBjb25maWd1cmF0aW9uCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0VHTEJvb2xlYW4gZWdsR2V0Q29uZmlncyggICBFR0xEaXNwbGF5IGRweSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xDb25maWcgKmNvbmZpZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMaW50IGNvbmZpZ19zaXplLCBFR0xpbnQgKm51bV9jb25maWcpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworCisgICAgR0xpbnQgbnVtQ29uZmlncyA9IE5FTEVNKGdDb25maWdzKTsKKyAgICBpZiAoIWNvbmZpZ3MpIHsKKyAgICAgICAgKm51bV9jb25maWcgPSBudW1Db25maWdzOworICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgfQorICAgIEdMaW50IGk7CisgICAgZm9yIChpPTAgOyBpPG51bUNvbmZpZ3MgJiYgaTxjb25maWdfc2l6ZSA7IGkrKykgeworICAgICAgICAqY29uZmlncysrID0gKEVHTENvbmZpZylpOworICAgIH0KKyAgICAqbnVtX2NvbmZpZyA9IGk7CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbENob29zZUNvbmZpZyggRUdMRGlzcGxheSBkcHksIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMQ29uZmlnICpjb25maWdzLCBFR0xpbnQgY29uZmlnX3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMaW50ICpudW1fY29uZmlnKQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKworICAgIGlmIChnZ2xfdW5saWtlbHkoY29uZmlncz09MCB8fCBhdHRyaWJfbGlzdD09MCkpIHsKKyAgICAgICAgKm51bV9jb25maWcgPSAwOworICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgfQorICAgIAorICAgIGludCBudW1BdHRyaWJ1dGVzID0gMDsKKyAgICBpbnQgbnVtQ29uZmlncyA9ICBORUxFTShnQ29uZmlncyk7CisgICAgdWludDMyX3QgcG9zc2libGVNYXRjaCA9ICgxPDxudW1Db25maWdzKS0xOworICAgIHdoaWxlKHBvc3NpYmxlTWF0Y2ggJiYgKmF0dHJpYl9saXN0ICE9IEVHTF9OT05FKSB7CisgICAgICAgIG51bUF0dHJpYnV0ZXMrKzsKKyAgICAgICAgRUdMaW50IGF0dHIgPSAqYXR0cmliX2xpc3QrKzsKKyAgICAgICAgRUdMaW50IHZhbCAgPSAqYXR0cmliX2xpc3QrKzsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxudW1Db25maWdzIDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoIShwb3NzaWJsZU1hdGNoICYgKDE8PGkpKSkKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIGlmIChpc0F0dHJpYnV0ZU1hdGNoaW5nKGksIGF0dHIsIHZhbCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHBvc3NpYmxlTWF0Y2ggJj0gfigxPDxpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIG5vdywgaGFuZGxlIHRoZSBhdHRyaWJ1dGVzIHdoaWNoIGhhdmUgYSB1c2VmdWwgZGVmYXVsdCB2YWx1ZQorICAgIGZvciAoc2l6ZV90IGo9MCA7IGo8TkVMRU0oY29uZmlnX2RlZmF1bHRzKSA7IGorKykgeworICAgICAgICAvLyBzZWUgaWYgdGhpcyBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZCwgaWYgbm90IGFwcGx5IGl0cworICAgICAgICAvLyBkZWZhdWx0IHZhbHVlCisgICAgICAgIGlmIChiaW5hcnlTZWFyY2g8Y29uZmlnX3BhaXJfdD4oCisgICAgICAgICAgICAgICAgKGNvbmZpZ19wYWlyX3QgY29uc3QqKWF0dHJpYl9saXN0LAorICAgICAgICAgICAgICAgIDAsIG51bUF0dHJpYnV0ZXMsCisgICAgICAgICAgICAgICAgY29uZmlnX2RlZmF1bHRzW2pdLmtleSkgPCAwKQorICAgICAgICB7CisgICAgICAgICAgICBmb3IgKGludCBpPTAgOyBpPG51bUNvbmZpZ3MgOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIShwb3NzaWJsZU1hdGNoICYgKDE8PGkpKSkKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgaWYgKGlzQXR0cmlidXRlTWF0Y2hpbmcoaSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ19kZWZhdWx0c1tqXS5rZXksCisgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdfZGVmYXVsdHNbal0udmFsdWUpID09IDApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZU1hdGNoICY9IH4oMTw8aSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gcmV0dXJuIHRoZSBjb25maWd1cmF0aW9ucyBmb3VuZAorICAgIGludCBuPTA7CisgICAgaWYgKHBvc3NpYmxlTWF0Y2gpIHsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgY29uZmlnX3NpemUgJiYgaTxudW1Db25maWdzIDsgaSsrKSB7CisgICAgICAgICAgICBpZiAocG9zc2libGVNYXRjaCAmICgxPDxpKSkgeworICAgICAgICAgICAgICAgKmNvbmZpZ3MrKyA9IChFR0xDb25maWcpaTsKKyAgICAgICAgICAgICAgICBjb25maWdfc2l6ZS0tOworICAgICAgICAgICAgICAgIG4rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAqbnVtX2NvbmZpZyA9IG47CisgICAgIHJldHVybiBFR0xfVFJVRTsKK30KKworRUdMQm9vbGVhbiBlZ2xHZXRDb25maWdBdHRyaWIoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworCisgICAgcmV0dXJuIGdldENvbmZpZ0F0dHJpYihkcHksIGNvbmZpZywgYXR0cmlidXRlLCB2YWx1ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHN1cmZhY2VzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0VHTFN1cmZhY2UgZWdsQ3JlYXRlV2luZG93U3VyZmFjZSggIEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlV2luZG93VHlwZSB3aW5kb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIHJldHVybiBjcmVhdGVXaW5kb3dTdXJmYWNlKGRweSwgY29uZmlnLCB3aW5kb3csIGF0dHJpYl9saXN0KTsKK30KKyAgICAKK0VHTFN1cmZhY2UgZWdsQ3JlYXRlUGl4bWFwU3VyZmFjZSggIEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlUGl4bWFwVHlwZSBwaXhtYXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIHJldHVybiBjcmVhdGVQaXhtYXBTdXJmYWNlKGRweSwgY29uZmlnLCBwaXhtYXAsIGF0dHJpYl9saXN0KTsKK30KKworRUdMU3VyZmFjZSBlZ2xDcmVhdGVQYnVmZmVyU3VyZmFjZSggRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIHJldHVybiBjcmVhdGVQYnVmZmVyU3VyZmFjZShkcHksIGNvbmZpZywgYXR0cmliX2xpc3QpOworfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCitFR0xCb29sZWFuIGVnbERlc3Ryb3lTdXJmYWNlKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGVnbFN1cmZhY2UpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworICAgIGlmIChlZ2xTdXJmYWNlICE9IEVHTF9OT19TVVJGQUNFKSB7CisgICAgICAgIGVnbF9zdXJmYWNlX3QqIHN1cmZhY2UoIHN0YXRpY19jYXN0PGVnbF9zdXJmYWNlX3QqPihlZ2xTdXJmYWNlKSApOworICAgICAgICBpZiAoc3VyZmFjZS0+bWFnaWMgIT0gZWdsX3N1cmZhY2VfdDo6TUFHSUMpCisgICAgICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9TVVJGQUNFLCBFR0xfRkFMU0UpOworICAgICAgICBpZiAoc3VyZmFjZS0+ZHB5ICE9IGRweSkKKyAgICAgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgICAgIGRlbGV0ZSBzdXJmYWNlOworICAgIH0KKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CisKK0VHTEJvb2xlYW4gZWdsUXVlcnlTdXJmYWNlKCBFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBlZ2xTdXJmYWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworICAgIGVnbF9zdXJmYWNlX3QqIHN1cmZhY2UgPSBzdGF0aWNfY2FzdDxlZ2xfc3VyZmFjZV90Kj4oZWdsU3VyZmFjZSk7CisgICAgaWYgKHN1cmZhY2UtPmRweSAhPSBkcHkpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisKKyAgICBFR0xCb29sZWFuIHJldCA9IEVHTF9UUlVFOworICAgIHN3aXRjaCAoYXR0cmlidXRlKSB7CisgICAgICAgIGNhc2UgRUdMX0NPTkZJR19JRDoKKyAgICAgICAgICAgIHJldCA9IGdldENvbmZpZ0F0dHJpYihkcHksIHN1cmZhY2UtPmNvbmZpZywgRUdMX0NPTkZJR19JRCwgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRUdMX1dJRFRIOgorICAgICAgICAgICAgKnZhbHVlID0gc3VyZmFjZS0+Z2V0V2lkdGgoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEVHTF9IRUlHSFQ6CisgICAgICAgICAgICAqdmFsdWUgPSBzdXJmYWNlLT5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEVHTF9MQVJHRVNUX1BCVUZGRVI6CisgICAgICAgICAgICAvLyBub3QgbW9kaWZpZWQgZm9yIGEgd2luZG93IG9yIHBpeG1hcCBzdXJmYWNlCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBFR0xfVEVYVFVSRV9GT1JNQVQ6CisgICAgICAgICAgICAqdmFsdWUgPSBFR0xfTk9fVEVYVFVSRTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEVHTF9URVhUVVJFX1RBUkdFVDoKKyAgICAgICAgICAgICp2YWx1ZSA9IEVHTF9OT19URVhUVVJFOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRUdMX01JUE1BUF9URVhUVVJFOgorICAgICAgICAgICAgKnZhbHVlID0gRUdMX0ZBTFNFOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRUdMX01JUE1BUF9MRVZFTDoKKyAgICAgICAgICAgICp2YWx1ZSA9IDA7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBFR0xfUkVOREVSX0JVRkZFUjoKKyAgICAgICAgICAgIC8vIFRPRE86IHJldHVybiB0aGUgcmVhbCBSRU5ERVJfQlVGRkVSIGhlcmUKKyAgICAgICAgICAgICp2YWx1ZSA9IEVHTF9CQUNLX0JVRkZFUjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEVHTF9IT1JJWk9OVEFMX1JFU09MVVRJT046CisgICAgICAgICAgICAvLyBwaXhlbC9tbSAqIEVHTF9ESVNQTEFZX1NDQUxJTkcKKyAgICAgICAgICAgICp2YWx1ZSA9IHN1cmZhY2UtPmdldEhvcml6b250YWxSZXNvbHV0aW9uKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBFR0xfVkVSVElDQUxfUkVTT0xVVElPTjoKKyAgICAgICAgICAgIC8vIHBpeGVsL21tICogRUdMX0RJU1BMQVlfU0NBTElORworICAgICAgICAgICAgKnZhbHVlID0gc3VyZmFjZS0+Z2V0VmVydGljYWxSZXNvbHV0aW9uKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBFR0xfUElYRUxfQVNQRUNUX1JBVElPOiB7CisgICAgICAgICAgICAvLyB3L2ggKiBFR0xfRElTUExBWV9TQ0FMSU5HCisgICAgICAgICAgICBpbnQgd3IgPSBzdXJmYWNlLT5nZXRIb3Jpem9udGFsUmVzb2x1dGlvbigpOworICAgICAgICAgICAgaW50IGhyID0gc3VyZmFjZS0+Z2V0VmVydGljYWxSZXNvbHV0aW9uKCk7CisgICAgICAgICAgICAqdmFsdWUgPSAod3IgKiBFR0xfRElTUExBWV9TQ0FMSU5HKSAvIGhyOworICAgICAgICB9IGJyZWFrOworICAgICAgICBjYXNlIEVHTF9TV0FQX0JFSEFWSU9SOgorICAgICAgICAgICAgKnZhbHVlID0gc3VyZmFjZS0+Z2V0U3dhcEJlaGF2aW9yKCk7IAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXQgPSBzZXRFcnJvcihFR0xfQkFEX0FUVFJJQlVURSwgRUdMX0ZBTFNFKTsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKK30KKworRUdMQ29udGV4dCBlZ2xDcmVhdGVDb250ZXh0KEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVHTENvbnRleHQgc2hhcmVfbGlzdCwgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9OT19TVVJGQUNFKTsKKworICAgIG9nbGVzX2NvbnRleHRfdCogZ2wgPSBvZ2xlc19pbml0KHNpemVvZihlZ2xfY29udGV4dF90KSk7CisgICAgaWYgKCFnbCkgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQUxMT0MsIEVHTF9OT19DT05URVhUKTsKKworICAgIGVnbF9jb250ZXh0X3QqIGMgPSBzdGF0aWNfY2FzdDxlZ2xfY29udGV4dF90Kj4oZ2wtPnJhc3Rlcml6ZXIuYmFzZSk7CisgICAgYy0+ZmxhZ3MgPSBlZ2xfY29udGV4dF90OjpORVZFUl9DVVJSRU5UOworICAgIGMtPmRweSA9IGRweTsKKyAgICBjLT5jb25maWcgPSBjb25maWc7CisgICAgYy0+cmVhZCA9IDA7CisgICAgYy0+ZHJhdyA9IDA7CisgICAgcmV0dXJuIChFR0xDb250ZXh0KWdsOworfQorCitFR0xCb29sZWFuIGVnbERlc3Ryb3lDb250ZXh0KEVHTERpc3BsYXkgZHB5LCBFR0xDb250ZXh0IGN0eCkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgZWdsX2NvbnRleHRfdCogYyA9IGVnbF9jb250ZXh0X3Q6OmNvbnRleHQoY3R4KTsKKyAgICBpZiAoYy0+ZmxhZ3MgJiBlZ2xfY29udGV4dF90OjpJU19DVVJSRU5UKQorICAgICAgICBzZXRHbFRocmVhZFNwZWNpZmljKDApOworICAgIG9nbGVzX3VuaW5pdCgob2dsZXNfY29udGV4dF90KiljdHgpOworICAgIHJldHVybiBFR0xfVFJVRTsKK30KKworRUdMQm9vbGVhbiBlZ2xNYWtlQ3VycmVudCggIEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGRyYXcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMU3VyZmFjZSByZWFkLCBFR0xDb250ZXh0IGN0eCkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgaWYgKGRyYXcpIHsKKyAgICAgICAgZWdsX3N1cmZhY2VfdCogcyA9IChlZ2xfc3VyZmFjZV90KilkcmF3OworICAgICAgICBpZiAocy0+ZHB5ICE9IGRweSkKKyAgICAgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgICAgIC8vIFRPRE86IGNoZWNrIHRoYXQgZHJhdyBhbmQgcmVhZCBhcmUgY29tcGF0aWJsZSB3aXRoIHRoZSBjb250ZXh0CisgICAgfQorCisgICAgRUdMQ29udGV4dCBjdXJyZW50X2N0eCA9IEVHTF9OT19DT05URVhUOworICAgIAorICAgIGlmICgocmVhZCA9PSBFR0xfTk9fU1VSRkFDRSAmJiBkcmF3ID09IEVHTF9OT19TVVJGQUNFKSAmJiAoY3R4ICE9IEVHTF9OT19DT05URVhUKSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9GQUxTRSk7CisKKyAgICBpZiAoKHJlYWQgIT0gRUdMX05PX1NVUkZBQ0UgfHwgZHJhdyAhPSBFR0xfTk9fU1VSRkFDRSkgJiYgKGN0eCA9PSBFR0xfTk9fQ09OVEVYVCkpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfRkFMU0UpOworCisgICAgaWYgKGN0eCA9PSBFR0xfTk9fQ09OVEVYVCkgeworICAgICAgICAvLyBpZiB3ZSdyZSBkZXRhY2hpbmcsIHdlIG5lZWQgdGhlIGN1cnJlbnQgY29udGV4dAorICAgICAgICBjdXJyZW50X2N0eCA9IChFR0xDb250ZXh0KWdldEdsVGhyZWFkU3BlY2lmaWMoKTsKKyAgICB9IGVsc2UgeworICAgICAgICBlZ2xfY29udGV4dF90KiBjID0gZWdsX2NvbnRleHRfdDo6Y29udGV4dChjdHgpOworICAgICAgICBlZ2xfc3VyZmFjZV90KiBkID0gKGVnbF9zdXJmYWNlX3QqKWRyYXc7CisgICAgICAgIGVnbF9zdXJmYWNlX3QqIHIgPSAoZWdsX3N1cmZhY2VfdCopcmVhZDsKKyAgICAgICAgaWYgKChkICYmIGQtPmN0eCAmJiBkLT5jdHggIT0gY3R4KSB8fAorICAgICAgICAgICAgKHIgJiYgci0+Y3R4ICYmIHItPmN0eCAhPSBjdHgpKSB7CisgICAgICAgICAgICAvLyBvbmNlIG9mIHRoZSBzdXJmYWNlIGlzIGJvdW5kIHRvIGEgY29udGV4dCBpbiBhbm90aGVyIHRocmVhZAorICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQUNDRVNTLCBFR0xfRkFMU0UpOworICAgICAgICB9CisgICAgfQorCisgICAgb2dsZXNfY29udGV4dF90KiBnbCA9IChvZ2xlc19jb250ZXh0X3QqKWN0eDsKKyAgICBpZiAobWFrZUN1cnJlbnQoZ2wpID09IDApIHsKKyAgICAgICAgaWYgKGN0eCkgeworICAgICAgICAgICAgZWdsX2NvbnRleHRfdCogYyA9IGVnbF9jb250ZXh0X3Q6OmNvbnRleHQoY3R4KTsKKyAgICAgICAgICAgIGVnbF9zdXJmYWNlX3QqIGQgPSAoZWdsX3N1cmZhY2VfdCopZHJhdzsKKyAgICAgICAgICAgIGVnbF9zdXJmYWNlX3QqIHIgPSAoZWdsX3N1cmZhY2VfdCopcmVhZDsKKyAgICAgICAgICAgIGMtPnJlYWQgPSByZWFkOworICAgICAgICAgICAgYy0+ZHJhdyA9IGRyYXc7CisgICAgICAgICAgICBpZiAoYy0+ZmxhZ3MgJiBlZ2xfY29udGV4dF90OjpORVZFUl9DVVJSRU5UKSB7CisgICAgICAgICAgICAgICAgYy0+ZmxhZ3MgJj0gfmVnbF9jb250ZXh0X3Q6Ok5FVkVSX0NVUlJFTlQ7CisgICAgICAgICAgICAgICAgR0xpbnQgdyA9IDA7CisgICAgICAgICAgICAgICAgR0xpbnQgaCA9IDA7CisgICAgICAgICAgICAgICAgaWYgKGRyYXcpIHsKKyAgICAgICAgICAgICAgICAgICAgdyA9IGQtPmdldFdpZHRoKCk7CisgICAgICAgICAgICAgICAgICAgIGggPSBkLT5nZXRIZWlnaHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2dsZXNfc3VyZmFjZXBvcnQoZ2wsIDAsIDApOworICAgICAgICAgICAgICAgIG9nbGVzX3ZpZXdwb3J0KGdsLCAwLCAwLCB3LCBoKTsKKyAgICAgICAgICAgICAgICBvZ2xlc19zY2lzc29yKGdsLCAwLCAwLCB3LCBoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChkKSB7CisgICAgICAgICAgICAgICAgZC0+Y3R4ID0gY3R4OworICAgICAgICAgICAgICAgIGQtPmJpbmREcmF3U3VyZmFjZShnbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocikgeworICAgICAgICAgICAgICAgIHItPmN0eCA9IGN0eDsKKyAgICAgICAgICAgICAgICByLT5iaW5kUmVhZFN1cmZhY2UoZ2wpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gaWYgc3VyZmFjZXMgd2VyZSBib3VuZCB0byB0aGUgY29udGV4dCBib3VuZCB0byB0aGlzIHRocmVhZAorICAgICAgICAgICAgLy8gbWFyayB0aGVuIGFzIHVuYm91bmQuCisgICAgICAgICAgICBpZiAoY3VycmVudF9jdHgpIHsKKyAgICAgICAgICAgICAgICBlZ2xfY29udGV4dF90KiBjID0gZWdsX2NvbnRleHRfdDo6Y29udGV4dChjdXJyZW50X2N0eCk7CisgICAgICAgICAgICAgICAgZWdsX3N1cmZhY2VfdCogZCA9IChlZ2xfc3VyZmFjZV90KiljLT5kcmF3OworICAgICAgICAgICAgICAgIGVnbF9zdXJmYWNlX3QqIHIgPSAoZWdsX3N1cmZhY2VfdCopYy0+cmVhZDsKKyAgICAgICAgICAgICAgICBpZiAoZCkgZC0+Y3R4ID0gRUdMX05PX0NPTlRFWFQ7CisgICAgICAgICAgICAgICAgaWYgKHIpIHItPmN0eCA9IEVHTF9OT19DT05URVhUOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBFR0xfVFJVRTsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQUNDRVNTLCBFR0xfRkFMU0UpOworfQorCitFR0xDb250ZXh0IGVnbEdldEN1cnJlbnRDb250ZXh0KHZvaWQpCit7CisgICAgLy8gZWdsR2V0Q3VycmVudENvbnRleHQgcmV0dXJucyB0aGUgY3VycmVudCBFR0wgcmVuZGVyaW5nIGNvbnRleHQsCisgICAgLy8gYXMgc3BlY2lmaWVkIGJ5IGVnbE1ha2VDdXJyZW50LiBJZiBubyBjb250ZXh0IGlzIGN1cnJlbnQsCisgICAgLy8gRUdMX05PX0NPTlRFWFQgaXMgcmV0dXJuZWQuCisgICAgcmV0dXJuIChFR0xDb250ZXh0KWdldEdsVGhyZWFkU3BlY2lmaWMoKTsKK30KKworRUdMU3VyZmFjZSBlZ2xHZXRDdXJyZW50U3VyZmFjZShFR0xpbnQgcmVhZGRyYXcpCit7CisgICAgLy8gZWdsR2V0Q3VycmVudFN1cmZhY2UgcmV0dXJucyB0aGUgcmVhZCBvciBkcmF3IHN1cmZhY2UgYXR0YWNoZWQKKyAgICAvLyB0byB0aGUgY3VycmVudCBFR0wgcmVuZGVyaW5nIGNvbnRleHQsIGFzIHNwZWNpZmllZCBieSBlZ2xNYWtlQ3VycmVudC4KKyAgICAvLyBJZiBubyBjb250ZXh0IGlzIGN1cnJlbnQsIEVHTF9OT19TVVJGQUNFIGlzIHJldHVybmVkLgorICAgIEVHTENvbnRleHQgY3R4ID0gKEVHTENvbnRleHQpZ2V0R2xUaHJlYWRTcGVjaWZpYygpOworICAgIGlmIChjdHggPT0gRUdMX05PX0NPTlRFWFQpIHJldHVybiBFR0xfTk9fU1VSRkFDRTsKKyAgICBlZ2xfY29udGV4dF90KiBjID0gZWdsX2NvbnRleHRfdDo6Y29udGV4dChjdHgpOworICAgIGlmIChyZWFkZHJhdyA9PSBFR0xfUkVBRCkgeworICAgICAgICByZXR1cm4gYy0+cmVhZDsKKyAgICB9IGVsc2UgaWYgKHJlYWRkcmF3ID09IEVHTF9EUkFXKSB7CisgICAgICAgIHJldHVybiBjLT5kcmF3OworICAgIH0KKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9BVFRSSUJVVEUsIEVHTF9OT19TVVJGQUNFKTsKK30KKworRUdMRGlzcGxheSBlZ2xHZXRDdXJyZW50RGlzcGxheSh2b2lkKQoreworICAgIC8vIGVnbEdldEN1cnJlbnREaXNwbGF5IHJldHVybnMgdGhlIGN1cnJlbnQgRUdMIGRpc3BsYXkgY29ubmVjdGlvbgorICAgIC8vIGZvciB0aGUgY3VycmVudCBFR0wgcmVuZGVyaW5nIGNvbnRleHQsIGFzIHNwZWNpZmllZCBieSBlZ2xNYWtlQ3VycmVudC4KKyAgICAvLyBJZiBubyBjb250ZXh0IGlzIGN1cnJlbnQsIEVHTF9OT19ESVNQTEFZIGlzIHJldHVybmVkLgorICAgIEVHTENvbnRleHQgY3R4ID0gKEVHTENvbnRleHQpZ2V0R2xUaHJlYWRTcGVjaWZpYygpOworICAgIGlmIChjdHggPT0gRUdMX05PX0NPTlRFWFQpIHJldHVybiBFR0xfTk9fRElTUExBWTsKKyAgICBlZ2xfY29udGV4dF90KiBjID0gZWdsX2NvbnRleHRfdDo6Y29udGV4dChjdHgpOworICAgIHJldHVybiBjLT5kcHk7Cit9CisKK0VHTEJvb2xlYW4gZWdsUXVlcnlDb250ZXh0KCBFR0xEaXNwbGF5IGRweSwgRUdMQ29udGV4dCBjdHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMaW50IGF0dHJpYnV0ZSwgRUdMaW50ICp2YWx1ZSkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgZWdsX2NvbnRleHRfdCogYyA9IGVnbF9jb250ZXh0X3Q6OmNvbnRleHQoY3R4KTsKKyAgICBzd2l0Y2ggKGF0dHJpYnV0ZSkgeworICAgICAgICBjYXNlIEVHTF9DT05GSUdfSUQ6CisgICAgICAgICAgICAvLyBSZXR1cm5zIHRoZSBJRCBvZiB0aGUgRUdMIGZyYW1lIGJ1ZmZlciBjb25maWd1cmF0aW9uIHdpdGgKKyAgICAgICAgICAgIC8vIHJlc3BlY3QgdG8gd2hpY2ggdGhlIGNvbnRleHQgd2FzIGNyZWF0ZWQKKyAgICAgICAgICAgIHJldHVybiBnZXRDb25maWdBdHRyaWIoZHB5LCBjLT5jb25maWcsIEVHTF9DT05GSUdfSUQsIHZhbHVlKTsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQVRUUklCVVRFLCBFR0xfRkFMU0UpOworfQorCitFR0xCb29sZWFuIGVnbFdhaXRHTCh2b2lkKQoreworICAgIHJldHVybiBFR0xfVFJVRTsKK30KKworRUdMQm9vbGVhbiBlZ2xXYWl0TmF0aXZlKEVHTGludCBlbmdpbmUpCit7CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbFN3YXBCdWZmZXJzKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGRyYXcpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworICAgIAorICAgIGVnbF9zdXJmYWNlX3QqIGQgPSBzdGF0aWNfY2FzdDxlZ2xfc3VyZmFjZV90Kj4oZHJhdyk7CisgICAgaWYgKGQtPmRweSAhPSBkcHkpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisKKyAgICAvLyBwb3N0IHRoZSBzdXJmYWNlCisgICAgZC0+c3dhcEJ1ZmZlcnMoKTsKKworICAgIC8vIGlmIGl0J3MgYm91bmQgdG8gYSBjb250ZXh0LCB1cGRhdGUgdGhlIGJ1ZmZlcgorICAgIGlmIChkLT5jdHggIT0gRUdMX05PX0NPTlRFWFQpIHsKKyAgICAgICAgZC0+YmluZERyYXdTdXJmYWNlKChvZ2xlc19jb250ZXh0X3QqKWQtPmN0eCk7CisgICAgICAgIC8vIGlmIHRoaXMgc3VyZmFjZSBpcyBhbHNvIHRoZSByZWFkIHN1cmZhY2Ugb2YgdGhlIGNvbnRleHQKKyAgICAgICAgLy8gaXQgaXMgYm91bmQgdG8sIG1ha2Ugc3VyZSB0byB1cGRhdGUgdGhlIHJlYWQgYnVmZmVyIGFzIHdlbGwuCisgICAgICAgIC8vIFRoZSBFR0wgc3BlYyBpcyBhIGxpdHRsZSB1bmNsZWFyIGFib3V0IHRoaXMuCisgICAgICAgIGVnbF9jb250ZXh0X3QqIGMgPSBlZ2xfY29udGV4dF90Ojpjb250ZXh0KGQtPmN0eCk7CisgICAgICAgIGlmIChjLT5yZWFkID09IGRyYXcpIHsKKyAgICAgICAgICAgIGQtPmJpbmRSZWFkU3VyZmFjZSgob2dsZXNfY29udGV4dF90KilkLT5jdHgpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbENvcHlCdWZmZXJzKCAgRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVQaXhtYXBUeXBlIHRhcmdldCkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgLy8gVE9ETzogZWdsQ29weUJ1ZmZlcnMoKQorICAgIHJldHVybiBFR0xfRkFMU0U7Cit9CisKK0VHTGludCBlZ2xHZXRFcnJvcih2b2lkKQoreworICAgIHJldHVybiBnZXRFcnJvcigpOworfQorCitjb25zdCBjaGFyKiBlZ2xRdWVyeVN0cmluZyhFR0xEaXNwbGF5IGRweSwgRUdMaW50IG5hbWUpCit7CisgICAgaWYgKGVnbF9kaXNwbGF5X3Q6OmlzX3ZhbGlkKGRweSkgPT0gRUdMX0ZBTFNFKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCAoY29uc3QgY2hhciopMCk7CisKKyAgICBzd2l0Y2ggKG5hbWUpIHsKKyAgICAgICAgY2FzZSBFR0xfVkVORE9SOgorICAgICAgICAgICAgcmV0dXJuIGdWZW5kb3JTdHJpbmc7CisgICAgICAgIGNhc2UgRUdMX1ZFUlNJT046CisgICAgICAgICAgICByZXR1cm4gZ1ZlcnNpb25TdHJpbmc7CisgICAgICAgIGNhc2UgRUdMX0VYVEVOU0lPTlM6CisgICAgICAgICAgICByZXR1cm4gZ0V4dGVuc2lvbnNTdHJpbmc7CisgICAgICAgIGNhc2UgRUdMX0NMSUVOVF9BUElTOgorICAgICAgICAgICAgcmV0dXJuIGdDbGllbnRBcGlTdHJpbmc7CisgICAgfQorICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1BBUkFNRVRFUiwgKGNvbnN0IGNoYXIgKikwKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRUdMIDEuMQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xCb29sZWFuIGVnbFN1cmZhY2VBdHRyaWIoCisgICAgICAgIEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIHN1cmZhY2UsIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCB2YWx1ZSkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgLy8gVE9ETzogZWdsU3VyZmFjZUF0dHJpYigpCisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfUEFSQU1FVEVSLCBFR0xfRkFMU0UpOworfQorCitFR0xCb29sZWFuIGVnbEJpbmRUZXhJbWFnZSgKKyAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwgRUdMaW50IGJ1ZmZlcikKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgLy8gVE9ETzogZWdsQmluZFRleEltYWdlKCkKKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9QQVJBTUVURVIsIEVHTF9GQUxTRSk7Cit9CisKK0VHTEJvb2xlYW4gZWdsUmVsZWFzZVRleEltYWdlKAorICAgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBFR0xpbnQgYnVmZmVyKQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKyAgICAvLyBUT0RPOiBlZ2xSZWxlYXNlVGV4SW1hZ2UoKQorICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1BBUkFNRVRFUiwgRUdMX0ZBTFNFKTsKK30KKworRUdMQm9vbGVhbiBlZ2xTd2FwSW50ZXJ2YWwoRUdMRGlzcGxheSBkcHksIEVHTGludCBpbnRlcnZhbCkKK3sKKyAgICBpZiAoZWdsX2Rpc3BsYXlfdDo6aXNfdmFsaWQoZHB5KSA9PSBFR0xfRkFMU0UpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisgICAgLy8gVE9ETzogZWdsU3dhcEludGVydmFsKCkKKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9QQVJBTUVURVIsIEVHTF9GQUxTRSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEVHTCAxLjIKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRUdMQm9vbGVhbiBlZ2xCaW5kQVBJKEVHTGVudW0gYXBpKQoreworICAgIGlmIChhcGkgIT0gRUdMX09QRU5HTF9FU19BUEkpCisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1BBUkFNRVRFUiwgRUdMX0ZBTFNFKTsKKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CisKK0VHTGVudW0gZWdsUXVlcnlBUEkodm9pZCkKK3sKKyAgICByZXR1cm4gRUdMX09QRU5HTF9FU19BUEk7Cit9CisKK0VHTEJvb2xlYW4gZWdsV2FpdENsaWVudCh2b2lkKQoreworICAgIGdsRmluaXNoKCk7CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbFJlbGVhc2VUaHJlYWQodm9pZCkKK3sKKyAgICAvLyBUT0RPOiBlZ2xSZWxlYXNlVGhyZWFkKCkKKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CisKK0VHTFN1cmZhY2UgZWdsQ3JlYXRlUGJ1ZmZlckZyb21DbGllbnRCdWZmZXIoCisgICAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTGVudW0gYnVmdHlwZSwgRUdMQ2xpZW50QnVmZmVyIGJ1ZmZlciwKKyAgICAgICAgICBFR0xDb25maWcgY29uZmlnLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGlmIChlZ2xfZGlzcGxheV90Ojppc192YWxpZChkcHkpID09IEVHTF9GQUxTRSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX05PX1NVUkZBQ0UpOworICAgIC8vIFRPRE86IGVnbENyZWF0ZVBidWZmZXJGcm9tQ2xpZW50QnVmZmVyKCkKKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9QQVJBTUVURVIsIEVHTF9OT19TVVJGQUNFKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gQW5kcm9pZCBleHRlbnNpb25zCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgKCplZ2xHZXRQcm9jQWRkcmVzcyAoY29uc3QgY2hhciAqcHJvY25hbWUpKSgpCit7CisgICAgZXh0ZW50aW9uX21hcF90IGNvbnN0ICogY29uc3QgbWFwID0gZ0V4dGVudGlvbk1hcDsKKyAgICBmb3IgKHVpbnQzMl90IGk9MCA7IGk8TkVMRU0oZ0V4dGVudGlvbk1hcCkgOyBpKyspIHsKKyAgICAgICAgaWYgKCFzdHJjbXAocHJvY25hbWUsIG1hcFtpXS5uYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIG1hcFtpXS5hZGRyZXNzOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9maXhlZF9hc20uUyBiL29wZW5nbC9saWJhZ2wvZml4ZWRfYXNtLlMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNiYzU2ZgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvZml4ZWRfYXNtLlMKQEAgLTAsMCArMSw2NSBAQAorLyogbGlicy9vcGVuZ2xlcy9maXhlZF9hc20uUworKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKworICAgIC50ZXh0CisgICAgLmFsaWduCisgICAgCisgICAgLmdsb2JhbCBnZ2xGbG9hdFRvRml4ZWQKKyAgICAuZ2xvYmFsIGdnbEZsb2F0VG9GaXhlZEZhc3QKKworCisvKgorICogQ29udmVydHMgYSBmbG9hdCB0byBhIHMxNS4xNiBmaXhlZC1wb2ludCBudW1iZXIuCisgKiB0aGlzIGRvZXNuJ3QgaGFuZGxlIGZsb2F0cyBvdXQgb2YgdGhlIFstMzI3NjgsICszMjc2OFsgcmFuZ2UKKyAqIGFuZCBkb2Vzbid0IHBlcmZvcm1zIHJvdW5kLXRvLW5lYXJlc3QuCisgKiBob3dldmVyLCBpdCdzIHZlcnkgZmFzdCA6LSkKKyAqLworCitnZ2xGbG9hdFRvRml4ZWRGYXN0OgorICAgICAgICBtb3ZzICAgIHIxLCByMCwgbHNsICMxICAgICAgICAgIC8qIHJlbW92ZSBiaXQgc2lnbiAqLworICAgICAgICBtb3YgICAgIHIyLCAjMHg4RSAgICAgICAgICAgICAgIC8qIDEyNyArIDE1ICovCisgICAgICAgIHN1YiAgICAgcjEsIHIyLCByMSwgbHNyICMyNCAgICAgLyogY29tcHV0ZSBzaGlmdCAqLworICAgICAgICBtb3YgICAgIHIyLCByMCwgbHNsICM4ICAgICAgICAgIC8qIG1hbnRpc3NhPDw4ICovCisgICAgICAgIG9yciAgICAgcjIsIHIyLCAjMHg4MDAwMDAwMCAgICAgLyogYWRkIHRoZSBtaXNzaW5nIDEgKi8KKyAgICAgICAgbW92ICAgICByMCwgcjIsIGxzciByMSAgICAgICAgICAvKiBzY2FsZSB0byAxNi4xNiAqLworICAgICAgICByc2JjcyAgIHIwLCByMCwgIzAgICAgICAgICAgICAgIC8qIG5lZ2F0ZSBpZiBuZWVkZWQgKi8KKyAgICAgICAgYnggICAgICBscgorCisvKgorICogdGhpcyB2ZXJzaW9uIHJvdW5kcy10by1uZWFyZXN0IGFuZCBzYXR1cmF0ZXMgbnVtYmVycworICogb3V0c2lkZSB0aGUgcmFuZ2UgKGJ1dCBub3QgTmFOcykuCisgKi8KKworZ2dsRmxvYXRUb0ZpeGVkOgorICAgICAgICBtb3YgICAgIHIxLCByMCwgbHNsICMxICAgICAgICAgIC8qIHJlbW92ZSBiaXQgc2lnbiAqLworICAgICAgICBtb3YgICAgIHIyLCAjMHg4RSAgICAgICAgICAgICAgIC8qIDEyNyArIDE1ICovCisgICAgICAgIHN1YnMgICAgcjEsIHIyLCByMSwgbHNyICMyNCAgICAgLyogY29tcHV0ZSBzaGlmdCAqLworICAgICAgICBibHMgICAgIDBmICAgICAgICAgICAgICAgICAgICAgIC8qIHRvbyBiaWcgKi8KKyAgICAgICAgbW92ICAgICByMiwgcjAsIGxzbCAjOCAgICAgICAgICAvKiBtYW50aXNzYTw8OCAqLworICAgICAgICBvcnIgICAgIHIyLCByMiwgIzB4ODAwMDAwMDAgICAgIC8qIGFkZCB0aGUgbWlzc2luZyAxICovCisgICAgICAgIG1vdiAgICAgcjMsIHIwCisgICAgICAgIG1vdnMgICAgcjAsIHIyLCBsc3IgcjEgICAgICAgICAgLyogc2NhbGUgdG8gMTYuMTYgKi8KKyAgICAgICAgYWRkY3MgICByMCwgcjAsICMxICAgICAgICAgICAgICAvKiByb3VuZC10by1uZWFyZXN0ICovCisgICAgICAgIHRzdCAgICAgcjMsICMweDgwMDAwMDAwICAgICAgICAgLyogbmVnYXRpdmU/ICovCisgICAgICAgIHJzYm5lICAgcjAsIHIwLCAjMCAgICAgICAgICAgICAgLyogbmVnYXRlIGlmIG5lZWRlZCAqLworICAgICAgICBieCAgICAgIGxyIAorIAorMDogICAgICBhbmRzICAgIHIwLCByMCwgIzB4ODAwMDAwMDAgICAgIC8qIGtlZXAgb25seSB0aGUgc2lnbiBiaXQgKi8KKyAgICAgICAgbW92ZXEgICByMCwgIzB4N2ZmZmZmZmYgICAgICAgICAvKiBwb3NpdGl2ZSwgbWF4aW11bSB2YWx1ZSAqLworICAgICAgICBieCAgICAgIGxyCisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvZnAuY3BwIGIvb3BlbmdsL2xpYmFnbC9mcC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU1ZjFmZQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvZnAuY3BwCkBAIC0wLDAgKzEsODcgQEAKKy8qIGxpYnMvb3BlbmdsZXMvZnAuY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgImZwLmgiCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmICFkZWZpbmVkKF9fYXJtX18pCitHR0xmaXhlZCBnZ2xGbG9hdFRvRml4ZWQoZmxvYXQgdikgeyAgIAorICAgIHJldHVybiBHR0xmaXhlZChmbG9vcmYodiAqIDY1NTM2LjBmICsgMC41ZikpOworfQorI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCituYW1lc3BhY2UgZ2wgeworCitHTGZsb2F0IGZpeGVkVG9GbG9hdChHTGZpeGVkIHgpCit7CisjaWYgREVCVUdfVVNFX0ZMT0FUUworICAgIHJldHVybiB4IC8gNjU1MzYuMGY7CisjZWxzZQorICAgIGlmICgheCkgcmV0dXJuIDA7CisgICAgY29uc3QgdWludDMyX3QgcyA9IHggJiAweDgwMDAwMDAwOworICAgIHVuaW9uIHsKKyAgICAgICAgdWludDMyX3QgaTsKKyAgICAgICAgZmxvYXQgZjsKKyAgICB9OworICAgIGkgPSBzID8gLXggOiB4OworICAgIGNvbnN0IGludCBjID0gZ2dsQ2x6KGkpIC0gODsKKyAgICBpID0gKGM+PTApID8gKGk8PGMpIDogKGk+Pi1jKTsKKyAgICBjb25zdCB1aW50MzJfdCBlID0gMTM0IC0gYzsKKyAgICBpICY9IH4weDgwMDAwMDsKKyAgICBpIHw9IGU8PDIzOworICAgIGkgfD0gczsKKyAgICByZXR1cm4gZjsKKyNlbmRpZgorfQorCitmbG9hdCBzaW5lZihmbG9hdCB4KQoreworICAgIGNvbnN0IGZsb2F0IEEgPSAgIDEuMGYgLyAoMi4wZipNX1BJKTsKKyAgICBjb25zdCBmbG9hdCBCID0gLTE2LjBmOworICAgIGNvbnN0IGZsb2F0IEMgPSAgIDguMGY7CisKKyAgICAvLyBzY2FsZSBhbmdsZSBmb3IgZWFzeSBhcmd1bWVudCByZWR1Y3Rpb24KKyAgICB4ICo9IEE7CisgICAgCisgICAgaWYgKGZhYnNmKHgpID49IDAuNWYpIHsKKyAgICAgICAgLy8gQXJndW1lbnQgcmVkdWN0aW9uCisgICAgICAgIHggPSB4IC0gY2VpbGYoeCArIDAuNWYpICsgMS4wZjsgCisgICAgfQorCisgICAgY29uc3QgZmxvYXQgeSA9IEIqeCpmYWJzZih4KSArIEMqeDsKKyAgICByZXR1cm4gMC4yMjE1ZiAqICh5KmZhYnNmKHkpIC0geSkgKyB5OworfQorCitmbG9hdCBjb3NpbmVmKGZsb2F0IHgpCit7CisgICAgcmV0dXJuIHNpbmVmKHggKyBmbG9hdChNX1BJLzIpKTsKK30KKwordm9pZCBzaW5jb3NmKEdMZmxvYXQgYW5nbGUsIEdMZmxvYXQqIHMsIEdMZmxvYXQqIGMpIHsKKyAgICAqcyA9IHNpbmVmKGFuZ2xlKTsKKyAgICAqYyA9IGNvc2luZWYoYW5nbGUpOworfQorCit9OyAvLyBuYW1lc3BhY2UgZnBfdXRpbHMKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvZnAuaCBiL29wZW5nbC9saWJhZ2wvZnAuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZDBjMTgzCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9mcC5oCkBAIC0wLDAgKzEsMjQzIEBACisvKiBsaWJzL29wZW5nbGVzL2ZwLmgKKyoqCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfT1BFTkdMRVNfRlBfSAorI2RlZmluZSBBTkRST0lEX09QRU5HTEVTX0ZQX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPG1hdGguaD4KKworI2luY2x1ZGUgPHByaXZhdGUvcGl4ZWxmbGluZ2VyL2dnbF9jb250ZXh0Lmg+CisKKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisKKyNkZWZpbmUgREVCVUdfVVNFX0ZMT0FUUyAgICAgIDAKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitleHRlcm4gIkMiIEdMZml4ZWQgZ2dsRmxvYXRUb0ZpeGVkKGZsb2F0IGYpIF9fYXR0cmlidXRlX18oKGNvbnN0KSk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKworbmFtZXNwYWNlIGdsIHsKKworICAgICAgICBHTGZsb2F0IGZpeGVkVG9GbG9hdChHTGZpeGVkKSBDT05TVDsKKworICAgICAgICB2b2lkICAgIHNpbmNvc2YoR0xmbG9hdCBhbmdsZSwgR0xmbG9hdCogcywgR0xmbG9hdCogYyk7CisgICAgICAgIGZsb2F0ICAgc2luZWYoR0xmbG9hdCB4KSBDT05TVDsKKyAgICAgICAgZmxvYXQgICBjb3NpbmVmKEdMZmxvYXQgeCkgQ09OU1Q7CisKK2lubGluZSBib29sICAgICBjbXBmKEdMZmxvYXQgYSwgR0xmbG9hdCBiKSBDT05TVDsKK2lubGluZSBib29sICAgICBpc1plcm9mKEdMZmxvYXQpIENPTlNUOworaW5saW5lIGJvb2wgICAgIGlzT25lZihHTGZsb2F0KSBDT05TVDsKKworaW5saW5lIGludCAgICAgIGlzWmVyb09yTmVnYXRpdmVmKEdMZmxvYXQpIENPTlNUOworCitpbmxpbmUgaW50ICAgICAgZXhwb25lbnQoR0xmbG9hdCkgQ09OU1Q7CitpbmxpbmUgaW50MzJfdCAgbWFudGlzc2EoR0xmbG9hdCkgQ09OU1Q7CitpbmxpbmUgR0xmbG9hdCAgY2xhbXBUb1plcm9mKEdMZmxvYXQpIENPTlNUOworaW5saW5lIEdMZmxvYXQgIHJlY2lwcm9jYWxmKEdMZmxvYXQpIENPTlNUOworaW5saW5lIEdMZmxvYXQgIHJzcXJ0ZihHTGZsb2F0KSBDT05TVDsKK2lubGluZSBHTGZsb2F0ICBzcXJmKEdMZmxvYXQpIENPTlNUOworaW5saW5lIEdMZmxvYXQgIGFkZEV4cGYoR0xmbG9hdCB2LCBpbnQgZSkgQ09OU1Q7CitpbmxpbmUgR0xmbG9hdCAgbXVsMmYoR0xmbG9hdCB2KSBDT05TVDsKK2lubGluZSBHTGZsb2F0ICBkaXYyZihHTGZsb2F0IHYpIENPTlNUOworaW5saW5lIEdMZmxvYXQgIGFic2YoR0xmbG9hdCB2KSBDT05TVDsKKworCisvKiAKKyAqIGZsb2F0IGZhc3RleHBmKGZsb2F0KSA6IGEgZmFzdCBhcHByb3hpbWF0aW9uIG9mIGV4cGYoeCkKKyAqCQlnaXZlIHNvbWV3aGF0IGFjY3VyYXRlIHJlc3VsdHMgZm9yIC04OCA8PSB4IDw9IDg4CisgKgorICogZXhwKHgpID0gMl4oeC9sbigyKSkKKyAqIHdlIHVzZSB0aGUgcHJvcGVydGllcyBvZiBmbG9hdCBlbmNvZGluZworICogdG8gZ2V0IGEgZmFzdCAyXiBhbmQgbGluZWFyIGludGVycG9sYXRpb24KKyAqCisgKi8KKworaW5saW5lIGZsb2F0IGZhc3RleHBmKGZsb2F0IHkpIF9fYXR0cmlidXRlX18oKGNvbnN0KSk7CisKK2lubGluZSBmbG9hdCBmYXN0ZXhwZihmbG9hdCB5KQoreworCXVuaW9uIHsKKwkJZmxvYXQJcjsKKwkJaW50MzJfdAlpOworCX0gdTsJCisKKwkvLyAxMjcqbG4oMikgPSA4OAorCWlmICh5IDwgLTg4LjBmKSB7CisJCXUuciA9IDAuMGY7CisJfSBlbHNlIGlmICh5ID4gODguMGYpIHsKKwkJdS5yID0gSU5GSU5JVFk7CisJfSBlbHNlIHsKKwkJY29uc3QgZmxvYXQga09uZU92ZXJMb2dUd28gPSAoMUw8PDIzKSAvIE1fTE4yOworCQljb25zdCBpbnQzMl90IGtFeHBvbmVudEJpYXMgPSAxMjdMPDwyMzsKKwkJY29uc3QgaW50MzJfdCBlID0gaW50MzJfdCh5KmtPbmVPdmVyTG9nVHdvKTsKKwkJdS5pID0gZSArIGtFeHBvbmVudEJpYXM7CisJfQorCQorCXJldHVybiB1LnI7Cit9CisKKworYm9vbCBjbXBmKEdMZmxvYXQgYSwgR0xmbG9hdCBiKSB7CisjaWYgREVCVUdfVVNFX0ZMT0FUUworICAgIHJldHVybiBhID09IGI7CisjZWxzZQorICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgICAgZjsKKyAgICAgICAgdWludDMyX3QgICAgaTsKKyAgICB9IHVhLCB1YjsKKyAgICB1YS5mID0gYTsKKyAgICB1Yi5mID0gYjsKKyAgICByZXR1cm4gdWEuaSA9PSB1Yi5pOworI2VuZGlmCit9IAorCitib29sIGlzWmVyb2YoR0xmbG9hdCB2KSB7CisjaWYgREVCVUdfVVNFX0ZMT0FUUworICAgIHJldHVybiB2ID09IDA7CisjZWxzZQorICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgICAgZjsKKyAgICAgICAgaW50MzJfdCAgICAgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIHJldHVybiAoaTw8MSkgPT0gMDsKKyNlbmRpZgorfQorCitib29sIGlzT25lZihHTGZsb2F0IHYpIHsKKyAgICByZXR1cm4gY21wZih2LCAxLjBmKTsKK30KKworaW50IGlzWmVyb09yTmVnYXRpdmVmKEdMZmxvYXQgdikgeworI2lmIERFQlVHX1VTRV9GTE9BVFMKKyAgICByZXR1cm4gdiA8PSAwOworI2Vsc2UKKyAgICB1bmlvbiB7CisgICAgICAgIGZsb2F0ICAgICAgIGY7CisgICAgICAgIGludDMyX3QgICAgIGk7CisgICAgfTsKKyAgICBmID0gdjsKKyAgICByZXR1cm4gaXNaZXJvZih2KSB8IChpPj4zMSk7CisjZW5kaWYKK30KKworaW50IGV4cG9uZW50KEdMZmxvYXQgdikgeworICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgZjsKKyAgICAgICAgdWludDMyX3QgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIHJldHVybiAoKGkgPDwgMSkgPj4gMjQpIC0gMTI3OworfQorCitpbnQzMl90IG1hbnRpc3NhKEdMZmxvYXQgdikgeworICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgZjsKKyAgICAgICAgdWludDMyX3QgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIGlmICghKGkmMHg3RjgwMDAwMCkpIHJldHVybiAwOworICAgIGNvbnN0IGludCBzID0gaSA+PiAzMTsKKyAgICBpIHw9ICgxTDw8MjMpOworICAgIGkgJj0gfjB4RkYwMDAwMDA7CisgICAgcmV0dXJuIHMgPyAtaSA6IGk7Cit9CisKK0dMZmxvYXQgY2xhbXBUb1plcm9mKEdMZmxvYXQgdikgeworI2lmIERFQlVHX1VTRV9GTE9BVFMKKyAgICByZXR1cm4gdjwwID8gMCA6ICh2PjEgPyAxIDogdik7CisjZWxzZQorICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgICAgZjsKKyAgICAgICAgaW50MzJfdCAgICAgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIGkgJj0gfihpPj4zMSk7CisgICAgcmV0dXJuIGY7CisjZW5kaWYKK30KKworR0xmbG9hdCByZWNpcHJvY2FsZihHTGZsb2F0IHYpIHsKKyAgICAvLyBYWFg6IGRvIGJldHRlcgorICAgIHJldHVybiAxLjBmIC8gdjsKK30KKworR0xmbG9hdCByc3FydGYoR0xmbG9hdCB2KSB7CisgICAgLy8gWFhYOiBkbyBiZXR0ZXIKKyAgICByZXR1cm4gMS4wZiAvIHNxcnRmKHYpOworfQorCitHTGZsb2F0IHNxcmYoR0xmbG9hdCB2KSB7CisgICAgLy8gWFhYOiBkbyBiZXR0ZXIKKyAgICByZXR1cm4gdip2OworfQorCitHTGZsb2F0IGFkZEV4cGYoR0xmbG9hdCB2LCBpbnQgZSkgeworICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgICAgZjsKKyAgICAgICAgaW50MzJfdCAgICAgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIGlmIChpPDwxKSB7IC8vIFhYWDogZGVhbCB3aXRoIG92ZXIvdW5kZXJmbG93CQorICAgICAgICBpICs9IGludDMyX3QoZSk8PDIzOworICAgIH0KKyAgICByZXR1cm4gZjsKK30KKworR0xmbG9hdCBtdWwyZihHTGZsb2F0IHYpIHsKKyNpZiBERUJVR19VU0VfRkxPQVRTCisgICAgcmV0dXJuIHYqMjsKKyNlbHNlCisgICAgcmV0dXJuIGFkZEV4cGYodiwgMSk7CisjZW5kaWYKK30KKworR0xmbG9hdCBkaXYyZihHTGZsb2F0IHYpIHsKKyNpZiBERUJVR19VU0VfRkxPQVRTCisgICAgcmV0dXJuIHYqMC41ZjsKKyNlbHNlCisgICAgcmV0dXJuIGFkZEV4cGYodiwgLTEpOworI2VuZGlmCit9CisKK0dMZmxvYXQgIGFic2YoR0xmbG9hdCB2KSB7CisjaWYgREVCVUdfVVNFX0ZMT0FUUworICAgIHJldHVybiB2PDAgPyAtdiA6IHY7CisjZWxzZQorICAgIHVuaW9uIHsKKyAgICAgICAgZmxvYXQgICAgICAgZjsKKyAgICAgICAgaW50MzJfdCAgICAgaTsKKyAgICB9OworICAgIGYgPSB2OworICAgIGkgJj0gfjB4ODAwMDAwMDA7CisgICAgcmV0dXJuIGY7CisjZW5kaWYKK30KKworfTsgIC8vIG5hbWVzcGFjZSBnbAorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9PUEVOR0xFU19GUF9ICisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvaXRlcmF0b3JzLlMgYi9vcGVuZ2wvbGliYWdsL2l0ZXJhdG9ycy5TCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZjI5MzcKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL2l0ZXJhdG9ycy5TCkBAIC0wLDAgKzEsODggQEAKKy8qIGxpYnMvb3BlbmdsZXMvaXRlcmF0b3JzLlMKKyoqCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisKKyAgICAudGV4dAorICAgIC5hbGlnbgorICAgIC5hcm0KKyAgICAKKyAgICAuZ2xvYmFsIGl0ZXJhdG9yczAwMzIKKworLyoKKyAqIGl0ZXJhdG9yczAwMzIKKyAqCisgKiBNVVNUIEJFIENBTExFRCBGUk9NIEFSTSBDT0RFCisgKgorICogcjA6IGNvbnN0IGNvbXB1dGVfaXRlcmF0b3JzX3QqICh0aGlzKQorICogICAgICByMCArIDA6IG1fZHgwMSAKKyAqICAgICAgcjAgKyA0OiBtX2R5MTAKKyAqICAgICAgcjAgKyA4OiBtX2R4MjAKKyAqICAgICAgcjAgKzEyOiBtX2R5MDIKKyAqICAgICAgcjAgKzE2OiBtX3gwCisgKiAgICAgIHIwICsyMDogbV95MAorICogICAgICByMCArMjQ6IG1fYXJlYQorICoJCXIwICsyODogbV9zY2FsZQorICoJCXIwICsyOTogbV9hcmVhX3NjYWxlOworICogcjE6IGludDMyX3QqIChvdXQpCisgKiAgICAgIHIxICsgMDogYworICogICAgICByMSArIDQ6IGRjZHgKKyAqICAgICAgcjEgKyA4OiBkY2R5CisgKiAgIHIyOiBjMAorICogICByMzogYzEKKyAqIFtzcF06IGMyCisgKi8KKyAKK2l0ZXJhdG9yczAwMzI6CisgICAgICAgIHN0bWZkCXNwISwge3I0LCByNSwgcjYsIHI3LCByOCwgbHJ9CisgICAgICAgIGxkciAgICAgcjQsIFtzcCwgIzQqNl0KKworICAgICAgICBsZHJiICAgIHIxMiwgW3IwLCAjMjldCisgICAgICAgIHN1YiAgICAgcjMsIHIzLCByMgorICAgICAgICBzdWIgICAgIHI0LCByNCwgcjIKKyAgICAgICAgc3ViICAgICByMTIsIHIxMiwgIzE2CisgICAgICAgIG1vdiAgICAgcjMsIHIzLCBhc3IgcjEyCisgICAgICAgIG1vdiAgICAgcjQsIHI0LCBhc3IgcjEyCisgICAgICAgIAorICAgICAgICBsZHIgICAgIHI1LCBbcjAsICMwXQorICAgICAgICBsZHIgICAgIHIxMiwgW3IwLCAjNF0KKyAgICAgICAgc211bGwgICByOCwgbHIsIHI0LCByNQorICAgICAgICBsZHIgICAgIHI1LCBbcjAsICM4XQorICAgICAgICBzbXVsbCAgIHI2LCByNywgcjQsIHIxMgorICAgICAgICBsZHIgICAgIHIxMiwgW3IwLCAjMTJdCisgICAgICAgIHNtbGFsICAgcjgsIGxyLCByMywgcjUKKyAgICAgICAgc21sYWwgICByNiwgcjcsIHIzLCByMTIKKworICAgICAgICBsZHIgICAgIHIzLCBbcjAsICMxNl0gICAgICAgIC8vIG1feDAKKyAgICAgICAgbGRyICAgICByNCwgW3IwLCAjMjBdICAgICAgICAvLyBtX3gxCisgICAgICAgIAorICAgICAgICBzdHIgICAgIHI2LCBbcjEsICM0XQorICAgICAgICBzdHIgICAgIHI4LCBbcjEsICM4XQorCisgICAgICAgIHVtdWxsICAgcjYsIHI1LCByMywgcjYKKyAgICAgICAgdW11bGwgICByOCwgcjAsIHI0LCByOAorICAgICAgICBtbGEgICAgIHI3LCByMywgcjcsIHI1CisgICAgICAgIG1sYSAgICAgbHIsIHI0LCBsciwgcjAKKyAgICAgICAgYWRkcyAgICByNiwgcjYsIHI4CisgICAgICAgIGFkYyAgICAgcjcsIHI3LCBscgorCisgICAgICAgIG1vdnMgICAgcjYsIHI2LCBsc3IgIzQKKyAgICAgICAgYWRjICAgICByNiwgcjYsIHI3LCBsc2wgIzI4CisgICAgICAgIHJzYiAgICAgcjYsIHI2LCByMiwgbHNsICMxNgorICAgICAgICBzdHIgICAgIHI2LCBbcjEsICMwXQorCisgICAgICAgIGxkbWZkCXNwISwge3I0LCByNSwgcjYsIHI3LCByOCwgcGN9CisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvbGlnaHQuY3BwIGIvb3BlbmdsL2xpYmFnbC9saWdodC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjVjNDFkMAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvbGlnaHQuY3BwCkBAIC0wLDAgKzEsODUyIEBACisvKiBsaWJzL29wZW5nbGVzL2xpZ2h0LmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgImNvbnRleHQuaCIKKyNpbmNsdWRlICJmcC5oIgorI2luY2x1ZGUgImxpZ2h0LmgiCisjaW5jbHVkZSAic3RhdGUuaCIKKyNpbmNsdWRlICJtYXRyaXguaCIKKworCisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiBkZWZpbmVkKF9fdGh1bWJfXykKKyN3YXJuaW5nICJsaWdodC5jcHAgc2hvdWxkIG5vdCBiZSBjb21waWxlZCBpbiB0aHVtYiBvbiBBUk0uIgorI2VuZGlmCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgdm9pZCBpbnZhbGlkYXRlX2xpZ2h0aW5nKG9nbGVzX2NvbnRleHRfdCogYyk7CitzdGF0aWMgdm9pZCBsaWdodFZlcnRleFZhbGlkYXRlKG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIHYpOworc3RhdGljIHZvaWQgbGlnaHRWZXJ0ZXhOb3Aob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdik7CitzdGF0aWMgdm9pZCBsaWdodFZlcnRleChvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KTsKK3N0YXRpYyB2b2lkIGxpZ2h0VmVydGV4TWF0ZXJpYWwob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdik7CisKK3N0YXRpYyBpbmxpbmUgdm9pZCB2c2NhbGUzKEdMZml4ZWQqIGQsIGNvbnN0IEdMZml4ZWQqIG0sIEdMZml4ZWQgcyk7CitzdGF0aWMgaW5saW5lIHZvaWQgdnN1YjN3KEdMZml4ZWQqIGQsIGNvbnN0IEdMZml4ZWQqIGEsIGNvbnN0IEdMZml4ZWQqIGIpOworCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCB2bm9ybTMoR0xmaXhlZCogZCwgY29uc3QgR0xmaXhlZCogYSk7CisKK3N0YXRpYyBpbmxpbmUgdm9pZCB2c2EzKEdMZml4ZWQqIGQsCisgICAgY29uc3QgR0xmaXhlZCogbSwgR0xmaXhlZCBzLCBjb25zdCBHTGZpeGVkKiBhKTsKK3N0YXRpYyBpbmxpbmUgdm9pZCB2bWxhMyhHTGZpeGVkKiBkLAorICAgIGNvbnN0IEdMZml4ZWQqIG0wLCBjb25zdCBHTGZpeGVkKiBtMSwgY29uc3QgR0xmaXhlZCogYSk7CitzdGF0aWMgaW5saW5lIHZvaWQgdm11bDMoR0xmaXhlZCogZCwKKyAgICBjb25zdCBHTGZpeGVkKiBtMCwgY29uc3QgR0xmaXhlZCogbTEpOworCitzdGF0aWMgR0xmaXhlZCBmb2dfbGluZWFyKG9nbGVzX2NvbnRleHRfdCogYywgR0xmaXhlZCB6KTsKK3N0YXRpYyBHTGZpeGVkIGZvZ19leHAob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkIHopOworc3RhdGljIEdMZml4ZWQgZm9nX2V4cDIob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkIHopOworCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIHZvaWQgaW5pdF93aGl0ZSh2ZWM0X3QmIGMpIHsKKyAgICBjLnIgPSBjLmcgPSBjLmIgPSBjLmEgPSAweDEwMDAwOworfQorCit2b2lkIG9nbGVzX2luaXRfbGlnaHQob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGZvciAodW5zaWduZWQgaW50IGk9MCA7IGk8T0dMRVNfTUFYX0xJR0hUUyA7IGkrKykgeworICAgICAgICBjLT5saWdodGluZy5saWdodHNbaV0uYW1iaWVudC5hID0gMHgxMDAwMDsKKyAgICAgICAgYy0+bGlnaHRpbmcubGlnaHRzW2ldLnBvc2l0aW9uLnogPSAweDEwMDAwOworICAgICAgICBjLT5saWdodGluZy5saWdodHNbaV0uc3BvdERpci56ID0gLTB4MTAwMDA7CisgICAgICAgIGMtPmxpZ2h0aW5nLmxpZ2h0c1tpXS5zcG90Q3V0b2ZmID0gZ2dsSW50VG9GaXhlZCgxODApOworICAgICAgICBjLT5saWdodGluZy5saWdodHNbaV0uYXR0ZW51YXRpb25bMF0gPSAweDEwMDAwOworICAgIH0KKyAgICBpbml0X3doaXRlKGMtPmxpZ2h0aW5nLmxpZ2h0c1swXS5kaWZmdXNlKTsKKyAgICBpbml0X3doaXRlKGMtPmxpZ2h0aW5nLmxpZ2h0c1swXS5zcGVjdWxhcik7CisKKyAgICBjLT5saWdodGluZy5mcm9udC5hbWJpZW50LnIgPQorICAgIGMtPmxpZ2h0aW5nLmZyb250LmFtYmllbnQuZyA9CisgICAgYy0+bGlnaHRpbmcuZnJvbnQuYW1iaWVudC5iID0gZ2dsRmxvYXRUb0ZpeGVkKDAuMmYpOworICAgIGMtPmxpZ2h0aW5nLmZyb250LmFtYmllbnQuYSA9IDB4MTAwMDA7CisgICAgYy0+bGlnaHRpbmcuZnJvbnQuZGlmZnVzZS5yID0KKyAgICBjLT5saWdodGluZy5mcm9udC5kaWZmdXNlLmcgPQorICAgIGMtPmxpZ2h0aW5nLmZyb250LmRpZmZ1c2UuYiA9IGdnbEZsb2F0VG9GaXhlZCgwLjhmKTsKKyAgICBjLT5saWdodGluZy5mcm9udC5kaWZmdXNlLmEgPSAweDEwMDAwOworICAgIGMtPmxpZ2h0aW5nLmZyb250LnNwZWN1bGFyLmEgPSAweDEwMDAwOworICAgIGMtPmxpZ2h0aW5nLmZyb250LmVtaXNzaW9uLmEgPSAweDEwMDAwOworCisgICAgYy0+bGlnaHRpbmcubGlnaHRNb2RlbC5hbWJpZW50LnIgPQorICAgIGMtPmxpZ2h0aW5nLmxpZ2h0TW9kZWwuYW1iaWVudC5nID0KKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuYiA9IGdnbEZsb2F0VG9GaXhlZCgwLjJmKTsKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuYSA9IDB4MTAwMDA7CisKKyAgICBjLT5saWdodGluZy5jb2xvck1hdGVyaWFsLmZhY2UgPSBHTF9GUk9OVF9BTkRfQkFDSzsKKyAgICBjLT5saWdodGluZy5jb2xvck1hdGVyaWFsLm1vZGUgPSBHTF9BTUJJRU5UX0FORF9ESUZGVVNFOworCisgICAgYy0+Zm9nLm1vZGUgPSBHTF9FWFA7CisgICAgYy0+Zm9nLmZvZyA9IGZvZ19leHA7CisgICAgYy0+Zm9nLmRlbnNpdHkgPSAweDEwMDAwOworICAgIGMtPmZvZy5lbmQgPSAweDEwMDAwOworICAgIGMtPmZvZy5pbnZFbmRNaW51c1N0YXJ0ID0gMHgxMDAwMDsKKworICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7CisgICAgICAgCisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5zaGFkZU1vZGVsKGMsIEdMX1NNT09USCk7CisgICAgYy0+bGlnaHRpbmcuc2hhZGVNb2RlbCA9IEdMX1NNT09USDsKK30KKwordm9pZCBvZ2xlc191bmluaXRfbGlnaHQob2dsZXNfY29udGV4dF90KiBjKQoreworfQorCitzdGF0aWMgaW5saW5lIGludDMyX3QgY2xhbXBGKEdMZml4ZWQgZikgQ09OU1Q7CitpbnQzMl90IGNsYW1wRihHTGZpeGVkIGYpIHsKKyAgICBmID0gKGYgJiB+KGY+PjMxKSk7CisgICAgaWYgKGYgPj0gMHgxMDAwMCkKKyAgICAgICAgZiA9IDB4MTAwMDA7CisgICAgcmV0dXJuIGY7Cit9CisKK3N0YXRpYyBHTGZpeGVkIGZvZ19saW5lYXIob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkIHopIHsKKyAgICByZXR1cm4gY2xhbXBGKGdnbE11bHgoKGMtPmZvZy5lbmQgLSAoKHo8MCk/LXo6eikpLCBjLT5mb2cuaW52RW5kTWludXNTdGFydCkpOworfQorCitzdGF0aWMgR0xmaXhlZCBmb2dfZXhwKG9nbGVzX2NvbnRleHRfdCogYywgR0xmaXhlZCB6KSB7CisgICAgY29uc3QgZmxvYXQgZSA9IGZpeGVkVG9GbG9hdChnZ2xNdWx4KGMtPmZvZy5kZW5zaXR5LCAoKHo8MCk/LXo6eikpKTsKKyAgICByZXR1cm4gY2xhbXBGKGdnbEZsb2F0VG9GaXhlZChmYXN0ZXhwZigtZSkpKTsKK30KKworc3RhdGljIEdMZml4ZWQgZm9nX2V4cDIob2dsZXNfY29udGV4dF90KiBjLCBHTGZpeGVkIHopIHsKKyAgICBjb25zdCBmbG9hdCBlID0gZml4ZWRUb0Zsb2F0KGdnbE11bHgoYy0+Zm9nLmRlbnNpdHksIHopKTsKKyAgICByZXR1cm4gY2xhbXBGKGdnbEZsb2F0VG9GaXhlZChmYXN0ZXhwZigtZSplKSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBtYXRoIGhlbHBlcnMKKyNlbmRpZgorCitzdGF0aWMgaW5saW5lCit2b2lkIHZzY2FsZTMoR0xmaXhlZCogZCwgY29uc3QgR0xmaXhlZCogbSwgR0xmaXhlZCBzKSB7CisgICAgZFswXSA9IGdnbE11bHgobVswXSwgcyk7CisgICAgZFsxXSA9IGdnbE11bHgobVsxXSwgcyk7CisgICAgZFsyXSA9IGdnbE11bHgobVsyXSwgcyk7Cit9CisKK3N0YXRpYyBpbmxpbmUKK3ZvaWQgdnNhMyhHTGZpeGVkKiBkLCBjb25zdCBHTGZpeGVkKiBtLCBHTGZpeGVkIHMsIGNvbnN0IEdMZml4ZWQqIGEpIHsKKyAgICBkWzBdID0gZ2dsTXVsQWRkeChtWzBdLCBzLCBhWzBdKTsKKyAgICBkWzFdID0gZ2dsTXVsQWRkeChtWzFdLCBzLCBhWzFdKTsKKyAgICBkWzJdID0gZ2dsTXVsQWRkeChtWzJdLCBzLCBhWzJdKTsKK30KKworc3RhdGljIGlubGluZQordm9pZCB2c3ViM3coR0xmaXhlZCogZCwgY29uc3QgR0xmaXhlZCogYSwgY29uc3QgR0xmaXhlZCogYikgeworICAgIGNvbnN0IEdMZml4ZWQgd2EgPSBhWzNdOworICAgIGNvbnN0IEdMZml4ZWQgd2IgPSBiWzNdOworICAgIGlmIChnZ2xfbGlrZWx5KHdhID09IHdiKSkgeworICAgICAgICBkWzBdID0gYVswXSAtIGJbMF07CisgICAgICAgIGRbMV0gPSBhWzFdIC0gYlsxXTsKKyAgICAgICAgZFsyXSA9IGFbMl0gLSBiWzJdOworICAgIH0gZWxzZSB7CisgICAgICAgIGRbMF0gPSBnZ2xNdWxTdWJ4KGFbMF0sIHdiLCBnZ2xNdWx4KGJbMF0sIHdhKSk7CisgICAgICAgIGRbMV0gPSBnZ2xNdWxTdWJ4KGFbMV0sIHdiLCBnZ2xNdWx4KGJbMV0sIHdhKSk7CisgICAgICAgIGRbMl0gPSBnZ2xNdWxTdWJ4KGFbMl0sIHdiLCBnZ2xNdWx4KGJbMl0sIHdhKSk7CisgICAgfQorfQorCitzdGF0aWMgaW5saW5lCit2b2lkIHZtbGEzKEdMZml4ZWQqIGQsCisgICAgICAgIGNvbnN0IEdMZml4ZWQqIG0wLCBjb25zdCBHTGZpeGVkKiBtMSwgY29uc3QgR0xmaXhlZCogYSkKK3sKKyAgICBkWzBdID0gZ2dsTXVsQWRkeChtMFswXSwgbTFbMF0sIGFbMF0pOworICAgIGRbMV0gPSBnZ2xNdWxBZGR4KG0wWzFdLCBtMVsxXSwgYVsxXSk7CisgICAgZFsyXSA9IGdnbE11bEFkZHgobTBbMl0sIG0xWzJdLCBhWzJdKTsKK30KKworc3RhdGljIGlubGluZQordm9pZCB2bXVsMyhHTGZpeGVkKiBkLCBjb25zdCBHTGZpeGVkKiBtMCwgY29uc3QgR0xmaXhlZCogbTEpIHsKKyAgICBkWzBdID0gZ2dsTXVseChtMFswXSwgbTFbMF0pOworICAgIGRbMV0gPSBnZ2xNdWx4KG0wWzFdLCBtMVsxXSk7CisgICAgZFsyXSA9IGdnbE11bHgobTBbMl0sIG0xWzJdKTsKK30KKwordm9pZCB2bm9ybTMoR0xmaXhlZCogZCwgY29uc3QgR0xmaXhlZCogYSkKK3sKKyAgICAvLyB3ZSBtdXN0IHRha2UgY2FyZSBvZiBvdmVyZmxvd3Mgd2hlbiBub3JtYWxpemluZyBhIHZlY3RvcgorICAgIEdMZml4ZWQgbjsKKyAgICBpbnQzMl90IHggPSBhWzBdOyAgIHggPSB4Pj0wID8geCA6IC14OworICAgIGludDMyX3QgeSA9IGFbMV07ICAgeSA9IHk+PTAgPyB5IDogLXk7CisgICAgaW50MzJfdCB6ID0gYVsyXTsgICB6ID0gej49MCA/IHogOiAtejsKKyAgICBpZiAoZ2dsX2xpa2VseSh4PD0weDY4MDAgJiYgeTw9MHg2ODAwICYmIHo8PSAweDY4MDApKSB7CisgICAgICAgIC8vIGluIHRoaXMgY2FzZSB0aGlzIHdpbGwgYWxsIGZpdCBvbiAzMiBiaXRzCisgICAgICAgIG4gPSB4KnggKyB5KnkgKyB6Kno7CisgICAgICAgIG4gPSBnZ2xTcXJ0UmVjaXB4KG4pOworICAgICAgICBuIDw8PSA4OworICAgIH0gZWxzZSB7CisgICAgICAgIC8vIGhlcmUgbm9ybV4yIGlzIGF0IGxlYXN0IDB4N0VDMDAwMDAgKD4+MzIgPT0gMC40OTUxMTcpCisgICAgICAgIG4gPSB2c3F1YXJlMyh4LCB5LCB6KTsKKyAgICAgICAgbiA9IGdnbFNxcnRSZWNpcHgobik7CisgICAgfQorICAgIHZzY2FsZTMoZCwgYSwgbik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIGxpZ2h0aW5nIGVxdWF0aW9ucworI2VuZGlmCisKK3N0YXRpYyBpbmxpbmUgdm9pZCBsaWdodF9waWNrZXIob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGlmIChnZ2xfbGlrZWx5KCFjLT5saWdodGluZy5lbmFibGUpKSB7CisgICAgICAgIGMtPmxpZ2h0aW5nLmxpZ2h0VmVydGV4ID0gbGlnaHRWZXJ0ZXhOb3A7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGMtPmxpZ2h0aW5nLmNvbG9yTWF0ZXJpYWwuZW5hYmxlKSB7CisgICAgICAgIGMtPmxpZ2h0aW5nLmxpZ2h0VmVydGV4ID0gbGlnaHRWZXJ0ZXhNYXRlcmlhbDsKKyAgICB9IGVsc2UgeworICAgICAgICBjLT5saWdodGluZy5saWdodFZlcnRleCA9IGxpZ2h0VmVydGV4OworICAgIH0KK30KKworc3RhdGljIGlubGluZSB2b2lkIHZhbGlkYXRlX2xpZ2h0X212aShvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgdWludDMyX3QgZW4gPSBjLT5saWdodGluZy5lbmFibGVkTGlnaHRzOworICAgIHdoaWxlIChlbikgeworICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gZ2dsQ2x6KGVuKTsKKyAgICAgICAgZW4gJj0gfigxPDxpKTsKKyAgICAgICAgbGlnaHRfdCYgbCA9IGMtPmxpZ2h0aW5nLmxpZ2h0c1tpXTsKKyAgICAgICAgYy0+dHJhbnNmb3Jtcy5tdnVpLnBvaW50MygmYy0+dHJhbnNmb3Jtcy5tdnVpLAorICAgICAgICAgICAgICAgICZsLm9ialBvc2l0aW9uLCAmbC5wb3NpdGlvbik7CisgICAgICAgIHZub3JtMyhsLm5vcm1hbGl6ZWRPYmpQb3NpdGlvbi52LCBsLm9ialBvc2l0aW9uLnYpOworICAgIH0KK30KKworc3RhdGljIGlubGluZSB2b2lkIHZhbGlkYXRlX2xpZ2h0KG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICAvLyBpZiBjb2xvck1hdGVyaWFsIGlzIGVuYWJsZWQsIHdlIGdldCB0aGUgY29sb3IgZnJvbSB0aGUgdmVydGV4CisgICAgaWYgKCFjLT5saWdodGluZy5jb2xvck1hdGVyaWFsLmVuYWJsZSkgeworICAgICAgICBtYXRlcmlhbF90JiBtYXRlcmlhbCA9IGMtPmxpZ2h0aW5nLmZyb250OworICAgICAgICB1aW50MzJfdCBlbiA9IGMtPmxpZ2h0aW5nLmVuYWJsZWRMaWdodHM7CisgICAgICAgIHdoaWxlIChlbikgeworICAgICAgICAgICAgY29uc3QgaW50IGkgPSAzMSAtIGdnbENseihlbik7CisgICAgICAgICAgICBlbiAmPSB+KDE8PGkpOworICAgICAgICAgICAgbGlnaHRfdCYgbCA9IGMtPmxpZ2h0aW5nLmxpZ2h0c1tpXTsKKyAgICAgICAgICAgIHZtdWwzKGwuaW1wbGljaXRBbWJpZW50LnYsICBtYXRlcmlhbC5hbWJpZW50LnYsICBsLmFtYmllbnQudik7CisgICAgICAgICAgICB2bXVsMyhsLmltcGxpY2l0RGlmZnVzZS52LCAgbWF0ZXJpYWwuZGlmZnVzZS52LCAgbC5kaWZmdXNlLnYpOworICAgICAgICAgICAgdm11bDMobC5pbXBsaWNpdFNwZWN1bGFyLnYsIG1hdGVyaWFsLnNwZWN1bGFyLnYsIGwuc3BlY3VsYXIudik7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIHRoaXMgaXMganVzdCBhIGZsYWcgdG8gdGVsbCBpZiB3ZSBoYXZlIGEgc3BlY3VsYXIgY29tcG9uZW50CisgICAgICAgICAgICBsLmltcGxpY2l0U3BlY3VsYXIudlszXSA9CisgICAgICAgICAgICAgICAgICAgIGwuaW1wbGljaXRTcGVjdWxhci5yIHwKKyAgICAgICAgICAgICAgICAgICAgbC5pbXBsaWNpdFNwZWN1bGFyLmcgfAorICAgICAgICAgICAgICAgICAgICBsLmltcGxpY2l0U3BlY3VsYXIuYjsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgbC5yQ29uc3RBdHRlbnVhdGlvbiA9IChsLmF0dGVudWF0aW9uWzFdIHwgbC5hdHRlbnVhdGlvblsyXSk9PTA7CisgICAgICAgICAgICBpZiAobC5yQ29uc3RBdHRlbnVhdGlvbikKKyAgICAgICAgICAgICAgICBsLnJDb25zdEF0dGVudWF0aW9uID0gZ2dsUmVjaXBGYXN0KGwuYXR0ZW51YXRpb25bMF0pOworICAgICAgICB9CisgICAgICAgIC8vIGVtaXNzaW9uIGFuZCBhbWJpZW50IGZvciB0aGUgd2hvbGUgc2NlbmUKKyAgICAgICAgdm1sYTMoICBjLT5saWdodGluZy5pbXBsaWNpdFNjZW5lRW1pc3Npb25BbmRBbWJpZW50LnYsCisgICAgICAgICAgICAgICAgYy0+bGlnaHRpbmcubGlnaHRNb2RlbC5hbWJpZW50LnYsCisgICAgICAgICAgICAgICAgbWF0ZXJpYWwuYW1iaWVudC52LCAKKyAgICAgICAgICAgICAgICBtYXRlcmlhbC5lbWlzc2lvbi52KTsKKyAgICAgICAgYy0+bGlnaHRpbmcuaW1wbGljaXRTY2VuZUVtaXNzaW9uQW5kQW1iaWVudC5hID0gbWF0ZXJpYWwuZGlmZnVzZS5hOworICAgIH0KKyAgICB2YWxpZGF0ZV9saWdodF9tdmkoYyk7Cit9CisKK3ZvaWQgaW52YWxpZGF0ZV9saWdodGluZyhvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgLy8gVE9ETzogcGljayBsaWdodFZlcnRleFZhbGlkYXRlIG9yIGxpZ2h0VmVydGV4VmFsaWRhdGVNVkkKKyAgICAvLyBpbnN0ZWFkIG9mIHN5c3RlbWF0aWNhbGx5IHRoZSBoZWF2aWVyIGxpZ2h0VmVydGV4VmFsaWRhdGUoKQorICAgIGMtPmxpZ2h0aW5nLmxpZ2h0VmVydGV4ID0gbGlnaHRWZXJ0ZXhWYWxpZGF0ZTsKK30KKwordm9pZCBvZ2xlc19pbnZhbGlkYXRlX2xpZ2h0aW5nX212dWkob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7Cit9CisKK3ZvaWQgbGlnaHRWZXJ0ZXhOb3Aob2dsZXNfY29udGV4dF90KiwgdmVydGV4X3QqIHYpCit7CisgICAgLy8gd2Ugc2hvdWxkIG5ldmVyIGVuZC11cCBoZXJlCit9CisKK3ZvaWQgbGlnaHRWZXJ0ZXhWYWxpZGF0ZU1WSShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KQoreworICAgIHZhbGlkYXRlX2xpZ2h0X212aShjKTsKKyAgICBsaWdodF9waWNrZXIoYyk7CisgICAgYy0+bGlnaHRpbmcubGlnaHRWZXJ0ZXgoYywgdik7Cit9CisKK3ZvaWQgbGlnaHRWZXJ0ZXhWYWxpZGF0ZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KQoreworICAgIHZhbGlkYXRlX2xpZ2h0KGMpOworICAgIGxpZ2h0X3BpY2tlcihjKTsKKyAgICBjLT5saWdodGluZy5saWdodFZlcnRleChjLCB2KTsKK30KKwordm9pZCBsaWdodFZlcnRleE1hdGVyaWFsKG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIHYpCit7CisgICAgLy8gZmV0Y2ggdGhlIG1hdGVyaWFsIGNvbG9yCisgICAgY29uc3QgR0x2b2lkKiBjcCA9IGMtPmFycmF5cy5jb2xvci5lbGVtZW50KAorICAgICAgICAgICAgdi0+aW5kZXggJiB2ZXJ0ZXhfY2FjaGVfdDo6SU5ERVhfTUFTSyk7CisgICAgYy0+YXJyYXlzLmNvbG9yLmZldGNoKGMsIHYtPmNvbG9yLnYsIGNwKTsKKworICAgIC8vIGFjcXVpcmUgdGhlIGNvbG9yLW1hdGVyaWFsIGZyb20gdGhlIHZlcnRleAorICAgIG1hdGVyaWFsX3QmIG1hdGVyaWFsID0gYy0+bGlnaHRpbmcuZnJvbnQ7CisgICAgbWF0ZXJpYWwuYW1iaWVudCA9CisgICAgbWF0ZXJpYWwuZGlmZnVzZSA9IHYtPmNvbG9yOworICAgIC8vIGltcGxpY2l0IGFyZ3VtZW50cyBuZWVkIHRvIGJlIGNvbXB1dGVkIHBlci92ZXJ0ZXgKKyAgICB1aW50MzJfdCBlbiA9IGMtPmxpZ2h0aW5nLmVuYWJsZWRMaWdodHM7CisgICAgd2hpbGUgKGVuKSB7CisgICAgICAgIGNvbnN0IGludCBpID0gMzEgLSBnZ2xDbHooZW4pOworICAgICAgICBlbiAmPSB+KDE8PGkpOworICAgICAgICBsaWdodF90JiBsID0gYy0+bGlnaHRpbmcubGlnaHRzW2ldOworICAgICAgICB2bXVsMyhsLmltcGxpY2l0QW1iaWVudC52LCAgbWF0ZXJpYWwuYW1iaWVudC52LCAgbC5hbWJpZW50LnYpOworICAgICAgICB2bXVsMyhsLmltcGxpY2l0RGlmZnVzZS52LCAgbWF0ZXJpYWwuZGlmZnVzZS52LCAgbC5kaWZmdXNlLnYpOworICAgICAgICB2bXVsMyhsLmltcGxpY2l0U3BlY3VsYXIudiwgbWF0ZXJpYWwuc3BlY3VsYXIudiwgbC5zcGVjdWxhci52KTsKKyAgICB9CisgICAgLy8gZW1pc3Npb24gYW5kIGFtYmllbnQgZm9yIHRoZSB3aG9sZSBzY2VuZQorICAgIHZtbGEzKCAgYy0+bGlnaHRpbmcuaW1wbGljaXRTY2VuZUVtaXNzaW9uQW5kQW1iaWVudC52LAorICAgICAgICAgICAgYy0+bGlnaHRpbmcubGlnaHRNb2RlbC5hbWJpZW50LnYsCisgICAgICAgICAgICBtYXRlcmlhbC5hbWJpZW50LnYsIAorICAgICAgICAgICAgbWF0ZXJpYWwuZW1pc3Npb24udik7CisgICAgYy0+bGlnaHRpbmcuaW1wbGljaXRTY2VuZUVtaXNzaW9uQW5kQW1iaWVudC5hID0gbWF0ZXJpYWwuZGlmZnVzZS5hOworCisgICAgLy8gbm93IHdlIGNhbiBsaWdodCBvdXIgdmVydGV4IGFzIHVzdWFsCisgICAgbGlnaHRWZXJ0ZXgoYywgdik7Cit9CisKK3ZvaWQgbGlnaHRWZXJ0ZXgob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikKK3sKKyAgICAvLyBlbWlzc2lvbiBhbmQgYW1iaWVudCBmb3IgdGhlIHdob2xlIHNjZW5lCisgICAgdmVjNF90IHIgPSBjLT5saWdodGluZy5pbXBsaWNpdFNjZW5lRW1pc3Npb25BbmRBbWJpZW50OworCisgICAgdWludDMyX3QgZW4gPSBjLT5saWdodGluZy5lbmFibGVkTGlnaHRzOworICAgIGlmIChnZ2xfbGlrZWx5KGVuKSkgeworICAgICAgICAvLyBzaW5jZSB3ZSBkbyB0aGUgbGlnaHRpbmcgaW4gb2JqZWN0LXNwYWNlLCB3ZSBkb24ndCBuZWVkIHRvCisgICAgICAgIC8vIHRyYW5zZm9ybSBlYWNoIG5vcm1hbC4gSG93ZXZlciwgd2UgbWlnaHQgc3RpbGwgaGF2ZSB0byBub3JtYWxpemUKKyAgICAgICAgLy8gaXQgaWYgR0xfTk9STUFMSVpFIGlzIGVuYWJsZWQuCisgICAgICAgIHZlYzRfdCBuOworICAgICAgICBjLT5hcnJheXMubm9ybWFsLmZldGNoKGMsIG4udiwKKyAgICAgICAgICAgIGMtPmFycmF5cy5ub3JtYWwuZWxlbWVudCh2LT5pbmRleCAmIHZlcnRleF9jYWNoZV90OjpJTkRFWF9NQVNLKSk7CisgICAgICAgIGlmIChjLT50cmFuc2Zvcm1zLnJlc2NhbGVOb3JtYWxzID09IEdMX05PUk1BTElaRSkKKyAgICAgICAgICAgIHZub3JtMyhuLnYsIG4udik7CisKKyAgICAgICAgY29uc3QgbWF0ZXJpYWxfdCYgbWF0ZXJpYWwgPSBjLT5saWdodGluZy5mcm9udDsKKyAgICAgICAgY29uc3QgaW50IHR3b1NpZGUgPSBjLT5saWdodGluZy5saWdodE1vZGVsLnR3b1NpZGU7CisKKyAgICAgICAgd2hpbGUgKGVuKSB7CisgICAgICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gZ2dsQ2x6KGVuKTsKKyAgICAgICAgICAgIGVuICY9IH4oMTw8aSk7CisgICAgICAgICAgICBjb25zdCBsaWdodF90JiBsID0gYy0+bGlnaHRpbmcubGlnaHRzW2ldOworICAgICAgICAgICAgCisgICAgICAgICAgICB2ZWM0X3QgZCwgdDsKKyAgICAgICAgICAgIEdMZml4ZWQgczsKKyAgICAgICAgICAgIEdMZml4ZWQgc3FEaXN0ID0gMHgxMDAwMDsKKworICAgICAgICAgICAgLy8gY29tcHV0ZSB2ZXJ0ZXgtdG8tbGlnaHQgdmVjdG9yCisgICAgICAgICAgICBpZiAoZ2dsX3VubGlrZWx5KGwucG9zaXRpb24udykpIHsKKyAgICAgICAgICAgICAgICB2c3ViM3coZC52LCBsLm9ialBvc2l0aW9uLnYsIHYtPm9iai52KTsKKyAgICAgICAgICAgICAgICBzcURpc3QgPSBkb3QzKGQudiwgZC52KTsKKyAgICAgICAgICAgICAgICB2c2NhbGUzKGQudiwgZC52LCBnZ2xTcXJ0UmVjaXB4KHNxRGlzdCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiBhdm9pZCBjb3B5IGhlcmUKKyAgICAgICAgICAgICAgICBkID0gbC5ub3JtYWxpemVkT2JqUG9zaXRpb247CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGFtYmllbnQgJiBkaWZmdXNlCisgICAgICAgICAgICBzID0gZG90MyhuLnYsIGQudik7CisgICAgICAgICAgICBzID0gKHM8MCkgPyAodHdvU2lkZT8oLXMpOjApIDogczsKKyAgICAgICAgICAgIHZzYTModC52LCBsLmltcGxpY2l0RGlmZnVzZS52LCBzLCBsLmltcGxpY2l0QW1iaWVudC52KTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy8gc3BlY3VsYXIKKyAgICAgICAgICAgIGlmIChnZ2xfdW5saWtlbHkocyAmJiBsLmltcGxpY2l0U3BlY3VsYXIudlszXSkpIHsKKyAgICAgICAgICAgICAgICB2ZWM0X3QgaDsKKyAgICAgICAgICAgICAgICBoLnggPSBkLng7CisgICAgICAgICAgICAgICAgaC55ID0gZC55OworICAgICAgICAgICAgICAgIGgueiA9IGQueiArIDB4MTAwMDA7CisgICAgICAgICAgICAgICAgdm5vcm0zKGgudiwgaC52KTsKKyAgICAgICAgICAgICAgICBzID0gZG90MyhuLnYsIGgudik7CisgICAgICAgICAgICAgICAgcyA9IChzPDApID8gKHR3b1NpZGU/KC1zKTowKSA6IHM7CisgICAgICAgICAgICAgICAgaWYgKHMgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHMgPSBnZ2xQb3d4KHMsIG1hdGVyaWFsLnNoaW5pbmVzcyk7CisgICAgICAgICAgICAgICAgICAgIHZzYTModC52LCBsLmltcGxpY2l0U3BlY3VsYXIudiwgcywgdC52KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHNwb3QKKyAgICAgICAgICAgIGlmIChnZ2xfdW5saWtlbHkobC5zcG90Q3V0b2ZmICE9IGdnbEludFRvRml4ZWQoMTgwKSkpIHsKKyAgICAgICAgICAgICAgICBHTGZpeGVkIHNwb3RBdHQgPSAtZG90MyhsLm5vcm1hbGl6ZWRTcG90RGlyLnYsIGQudik7CisgICAgICAgICAgICAgICAgaWYgKHNwb3RBdHQgPj0gbC5zcG90Q3V0b2ZmQ29zaW5lKSB7CisgICAgICAgICAgICAgICAgICAgIHZzY2FsZTModC52LCB0LnYsIGdnbFBvd3goc3BvdEF0dCwgbC5zcG90RXhwKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBhdHRlbnVhdGlvbgorICAgICAgICAgICAgaWYgKGdnbF91bmxpa2VseShsLnBvc2l0aW9uLncpKSB7CisgICAgICAgICAgICAgICAgaWYgKGwuckNvbnN0QXR0ZW51YXRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgcyA9IGwuckNvbnN0QXR0ZW51YXRpb247CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcyA9IGdnbE11bEFkZHgoc3FEaXN0LCBsLmF0dGVudWF0aW9uWzJdLCBsLmF0dGVudWF0aW9uWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGwuYXR0ZW51YXRpb25bMV0pCisgICAgICAgICAgICAgICAgICAgICAgICBzID0gZ2dsTXVsQWRkeChnZ2xTcXJ0eChzcURpc3QpLCBsLmF0dGVudWF0aW9uWzFdLCBzKTsKKyAgICAgICAgICAgICAgICAgICAgcyA9IGdnbFJlY2lwRmFzdChzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdnNjYWxlMyh0LnYsIHQudiwgcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHIuciArPSB0LnI7CisgICAgICAgICAgICByLmcgKz0gdC5nOworICAgICAgICAgICAgci5iICs9IHQuYjsKKyAgICAgICAgfQorICAgIH0KKyAgICB2LT5jb2xvci5yID0gZ2dsQ2xhbXB4KHIucik7CisgICAgdi0+Y29sb3IuZyA9IGdnbENsYW1weChyLmcpOworICAgIHYtPmNvbG9yLmIgPSBnZ2xDbGFtcHgoci5iKTsKKyAgICB2LT5jb2xvci5hID0gZ2dsQ2xhbXB4KHIuYSk7CisgICAgdi0+ZmxhZ3MgfD0gdmVydGV4X3Q6OkxJVDsKK30KKworc3RhdGljIHZvaWQgbGlnaHRNb2RlbHgoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtLCBvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgaWYgKGdnbF91bmxpa2VseShwbmFtZSAhPSBHTF9MSUdIVF9NT0RFTF9UV09fU0lERSkpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLnR3b1NpZGUgPSBwYXJhbSA/IEdMX1RSVUUgOiBHTF9GQUxTRTsKKyAgICBpbnZhbGlkYXRlX2xpZ2h0aW5nKGMpOworfQorCitzdGF0aWMgdm9pZCBsaWdodHgoR0xlbnVtIGksIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSwgb2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGlmIChnZ2xfdW5saWtlbHkodWludDMyX3QoaS1HTF9MSUdIVDApID49IE9HTEVTX01BWF9MSUdIVFMpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBsaWdodF90JiBsaWdodCA9IGMtPmxpZ2h0aW5nLmxpZ2h0c1tpLUdMX0xJR0hUMF07CisgICAgY29uc3QgR0xmaXhlZCBrRGVnVG9SYWQgPSBHTGZpeGVkKChNX1BJICogZ2dsSW50VG9GaXhlZCgxKSkgLyAxODAuMGYpOworICAgIHN3aXRjaCAocG5hbWUpIHsKKyAgICBjYXNlIEdMX1NQT1RfRVhQT05FTlQ6CisgICAgICAgIGlmIChHR0xmaXhlZChwYXJhbSkgPj0gZ2dsSW50VG9GaXhlZCgxMjgpKSB7CisgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBsaWdodC5zcG90RXhwID0gcGFyYW07CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfU1BPVF9DVVRPRkY6CisgICAgICAgIGlmIChwYXJhbSE9Z2dsSW50VG9GaXhlZCgxODApICYmIEdHTGZpeGVkKHBhcmFtKT49Z2dsSW50VG9GaXhlZCg5MCkpIHsKKyAgICAgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGxpZ2h0LnNwb3RDdXRvZmYgPSBwYXJhbTsKKyAgICAgICAgbGlnaHQuc3BvdEN1dG9mZkNvc2luZSA9IAorICAgICAgICAgICAgICAgIGdnbEZsb2F0VG9GaXhlZChjb3NpbmVmKChNX1BJLygxODAuMGYqNjU1MzYuMGYpKSpwYXJhbSkpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0NPTlNUQU5UX0FUVEVOVUFUSU9OOgorICAgICAgICBpZiAocGFyYW0gPCAwKSB7CisgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBsaWdodC5hdHRlbnVhdGlvblswXSA9IHBhcmFtOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0xJTkVBUl9BVFRFTlVBVElPTjoKKyAgICAgICAgaWYgKHBhcmFtIDwgMCkgeworICAgICAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgbGlnaHQuYXR0ZW51YXRpb25bMV0gPSBwYXJhbTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9RVUFEUkFUSUNfQVRURU5VQVRJT046CisgICAgICAgIGlmIChwYXJhbSA8IDApIHsKKyAgICAgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGxpZ2h0LmF0dGVudWF0aW9uWzJdID0gcGFyYW07CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW52YWxpZGF0ZV9saWdodGluZyhjKTsKK30KKworc3RhdGljIHZvaWQgbGlnaHR4dihHTGVudW0gaSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMsIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBpZiAoZ2dsX3VubGlrZWx5KHVpbnQzMl90KGktR0xfTElHSFQwKSA+PSBPR0xFU19NQVhfTElHSFRTKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgR0xmaXhlZCogd2hhdDsKKyAgICBsaWdodF90JiBsaWdodCA9IGMtPmxpZ2h0aW5nLmxpZ2h0c1tpLUdMX0xJR0hUMF07CisgICAgc3dpdGNoIChwbmFtZSkgeworICAgIGNhc2UgR0xfQU1CSUVOVDoKKyAgICAgICAgd2hhdCA9IGxpZ2h0LmFtYmllbnQudjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9ESUZGVVNFOgorICAgICAgICB3aGF0ID0gbGlnaHQuZGlmZnVzZS52OworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1NQRUNVTEFSOgorICAgICAgICB3aGF0ID0gbGlnaHQuc3BlY3VsYXIudjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9QT1NJVElPTjogeworICAgICAgICBvZ2xlc192YWxpZGF0ZV90cmFuc2Zvcm0oYywgdHJhbnNmb3JtX3N0YXRlX3Q6Ok1PREVMVklFVyk7CisgICAgICAgIHRyYW5zZm9ybV90JiBtdiA9IGMtPnRyYW5zZm9ybXMubW9kZWx2aWV3LnRyYW5zZm9ybTsKKyAgICAgICAgbWVtY3B5KGxpZ2h0LnBvc2l0aW9uLnYsIHBhcmFtcywgc2l6ZW9mKGxpZ2h0LnBvc2l0aW9uLnYpKTsKKyAgICAgICAgbXYucG9pbnQ0KCZtdiwgJmxpZ2h0LnBvc2l0aW9uLCAmbGlnaHQucG9zaXRpb24pOworICAgICAgICBpbnZhbGlkYXRlX2xpZ2h0aW5nKGMpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGNhc2UgR0xfU1BPVF9ESVJFQ1RJT046IHsKKyAgICAgICAgb2dsZXNfdmFsaWRhdGVfdHJhbnNmb3JtKGMsIHRyYW5zZm9ybV9zdGF0ZV90OjpNVlVJKTsKKyAgICAgICAgdHJhbnNmb3JtX3QmIG12dWkgPSBjLT50cmFuc2Zvcm1zLm12dWk7CisgICAgICAgIG12dWkucG9pbnQzKCZtdnVpLCAmbGlnaHQuc3BvdERpciwgKHZlYzRfdCopcGFyYW1zKTsKKyAgICAgICAgdm5vcm0zKGxpZ2h0Lm5vcm1hbGl6ZWRTcG90RGlyLnYsIGxpZ2h0LnNwb3REaXIudik7CisgICAgICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgICAgbGlnaHR4KGksIHBuYW1lLCBwYXJhbXNbMF0sIGMpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHdoYXRbMF0gPSBwYXJhbXNbMF07CisgICAgd2hhdFsxXSA9IHBhcmFtc1sxXTsKKyAgICB3aGF0WzJdID0gcGFyYW1zWzJdOworICAgIHdoYXRbM10gPSBwYXJhbXNbM107CisgICAgaW52YWxpZGF0ZV9saWdodGluZyhjKTsKK30KKworc3RhdGljIHZvaWQgbWF0ZXJpYWx4KEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0sIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGZhY2UgIT0gR0xfRlJPTlRfQU5EX0JBQ0spKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGdnbF91bmxpa2VseShwbmFtZSAhPSBHTF9TSElOSU5FU1MpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYy0+bGlnaHRpbmcuZnJvbnQuc2hpbmluZXNzID0gcGFyYW07CisgICAgaW52YWxpZGF0ZV9saWdodGluZyhjKTsKK30KKworc3RhdGljIHZvaWQgZm9neChHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0sIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBzd2l0Y2ggKHBuYW1lKSB7CisgICAgY2FzZSBHTF9GT0dfREVOU0lUWToKKyAgICAgICAgaWYgKHBhcmFtID49IDApIHsKKyAgICAgICAgICAgIGMtPmZvZy5kZW5zaXR5ID0gcGFyYW07CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9GT0dfU1RBUlQ6CisgICAgICAgIGMtPmZvZy5zdGFydCA9IHBhcmFtOworICAgICAgICBjLT5mb2cuaW52RW5kTWludXNTdGFydCA9IGdnbFJlY2lwKGMtPmZvZy5lbmQgLSBjLT5mb2cuc3RhcnQpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0ZPR19FTkQ6CisgICAgICAgIGMtPmZvZy5lbmQgPSBwYXJhbTsKKyAgICAgICAgYy0+Zm9nLmludkVuZE1pbnVzU3RhcnQgPSBnZ2xSZWNpcChjLT5mb2cuZW5kIC0gYy0+Zm9nLnN0YXJ0KTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9GT0dfTU9ERToKKyAgICAgICAgc3dpdGNoIChwYXJhbSkgeworICAgICAgICBjYXNlIEdMX0xJTkVBUjoKKyAgICAgICAgICAgIGMtPmZvZy5tb2RlID0gcGFyYW07CisgICAgICAgICAgICBjLT5mb2cuZm9nID0gZm9nX2xpbmVhcjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEdMX0VYUDoKKyAgICAgICAgICAgIGMtPmZvZy5tb2RlID0gcGFyYW07CisgICAgICAgICAgICBjLT5mb2cuZm9nID0gZm9nX2V4cDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEdMX0VYUDI6CisgICAgICAgICAgICBjLT5mb2cubW9kZSA9IHBhcmFtOworICAgICAgICAgICAgYy0+Zm9nLmZvZyA9IGZvZ19leHAyOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgbGlnaHRpbmcgQVBJcworI2VuZGlmCisKK3ZvaWQgZ2xTaGFkZU1vZGVsKEdMZW51bSBtb2RlKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKGdnbF91bmxpa2VseShtb2RlICE9IEdMX1NNT09USCAmJiBtb2RlICE9IEdMX0ZMQVQpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYy0+bGlnaHRpbmcuc2hhZGVNb2RlbCA9IG1vZGU7Cit9CisKK3ZvaWQgZ2xMaWdodE1vZGVsZihHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBsaWdodE1vZGVseChwbmFtZSwgZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtKSwgYyk7Cit9CisKK3ZvaWQgZ2xMaWdodE1vZGVseChHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBsaWdodE1vZGVseChwbmFtZSwgcGFyYW0sIGMpOworfQorCit2b2lkIGdsTGlnaHRNb2RlbGZ2KEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHBuYW1lID09IEdMX0xJR0hUX01PREVMX1RXT19TSURFKSB7CisgICAgICAgIGxpZ2h0TW9kZWx4KHBuYW1lLCBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzBdKSwgYyk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoZ2dsX3VubGlrZWx5KHBuYW1lICE9IEdMX0xJR0hUX01PREVMX0FNQklFTlQpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuciA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMF0pOworICAgIGMtPmxpZ2h0aW5nLmxpZ2h0TW9kZWwuYW1iaWVudC5nID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1sxXSk7CisgICAgYy0+bGlnaHRpbmcubGlnaHRNb2RlbC5hbWJpZW50LmIgPSBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzJdKTsKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuYSA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbM10pOworICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7Cit9CisKK3ZvaWQgZ2xMaWdodE1vZGVseHYoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAocG5hbWUgPT0gR0xfTElHSFRfTU9ERUxfVFdPX1NJREUpIHsKKyAgICAgICAgbGlnaHRNb2RlbHgocG5hbWUsIHBhcmFtc1swXSwgYyk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoZ2dsX3VubGlrZWx5KHBuYW1lICE9IEdMX0xJR0hUX01PREVMX0FNQklFTlQpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuciA9IHBhcmFtc1swXTsKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuZyA9IHBhcmFtc1sxXTsKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuYiA9IHBhcmFtc1syXTsKKyAgICBjLT5saWdodGluZy5saWdodE1vZGVsLmFtYmllbnQuYSA9IHBhcmFtc1szXTsKKyAgICBpbnZhbGlkYXRlX2xpZ2h0aW5nKGMpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCit2b2lkIGdsTGlnaHRmKEdMZW51bSBpLCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBsaWdodHgoaSwgcG5hbWUsIGdnbEZsb2F0VG9GaXhlZChwYXJhbSksIGMpOworfQorCit2b2lkIGdsTGlnaHR4KEdMZW51bSBpLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBsaWdodHgoaSwgcG5hbWUsIHBhcmFtLCBjKTsKK30KKwordm9pZCBnbExpZ2h0ZnYoR0xlbnVtIGksIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgc3dpdGNoIChwbmFtZSkgeworICAgIGNhc2UgR0xfU1BPVF9FWFBPTkVOVDoKKyAgICBjYXNlIEdMX1NQT1RfQ1VUT0ZGOgorICAgIGNhc2UgR0xfQ09OU1RBTlRfQVRURU5VQVRJT046CisgICAgY2FzZSBHTF9MSU5FQVJfQVRURU5VQVRJT046CisgICAgY2FzZSBHTF9RVUFEUkFUSUNfQVRURU5VQVRJT046CisgICAgICAgIGxpZ2h0eChpLCBwbmFtZSwgZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1swXSksIGMpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgR0xmaXhlZCBwYXJhbXN4WzRdOworICAgIHBhcmFtc3hbMF0gPSBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzBdKTsKKyAgICBwYXJhbXN4WzFdID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1sxXSk7CisgICAgcGFyYW1zeFsyXSA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMl0pOworICAgIGlmIChwbmFtZSAhPSBHTF9TUE9UX0RJUkVDVElPTikKKyAgICAgICAgcGFyYW1zeFszXSA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbM10pOworCisgICAgbGlnaHR4dihpLCBwbmFtZSwgcGFyYW1zeCwgYyk7Cit9CisKK3ZvaWQgZ2xMaWdodHh2KEdMZW51bSBpLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGxpZ2h0eHYoaSwgcG5hbWUsIHBhcmFtcywgYyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK3ZvaWQgZ2xNYXRlcmlhbGYoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIG1hdGVyaWFseChmYWNlLCBwbmFtZSwgZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtKSwgYyk7Cit9CisKK3ZvaWQgZ2xNYXRlcmlhbHgoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIG1hdGVyaWFseChmYWNlLCBwbmFtZSwgcGFyYW0sIGMpOworfQorCit2b2lkIGdsTWF0ZXJpYWxmdigKKyAgICBHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGZhY2UgIT0gR0xfRlJPTlRfQU5EX0JBQ0spKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgR0xmaXhlZCogd2hhdD0wOworICAgIEdMZml4ZWQqIG90aGVyPTA7CisgICAgc3dpdGNoIChwbmFtZSkgeworICAgIGNhc2UgR0xfQU1CSUVOVDogICAgd2hhdCA9IGMtPmxpZ2h0aW5nLmZyb250LmFtYmllbnQudjsgYnJlYWs7CisgICAgY2FzZSBHTF9ESUZGVVNFOiAgICB3aGF0ID0gYy0+bGlnaHRpbmcuZnJvbnQuZGlmZnVzZS52OyBicmVhazsKKyAgICBjYXNlIEdMX1NQRUNVTEFSOiAgIHdoYXQgPSBjLT5saWdodGluZy5mcm9udC5zcGVjdWxhci52OyBicmVhazsKKyAgICBjYXNlIEdMX0VNSVNTSU9OOiAgIHdoYXQgPSBjLT5saWdodGluZy5mcm9udC5lbWlzc2lvbi52OyBicmVhazsKKyAgICBjYXNlIEdMX0FNQklFTlRfQU5EX0RJRkZVU0U6CisgICAgICAgIHdoYXQgID0gYy0+bGlnaHRpbmcuZnJvbnQuYW1iaWVudC52OyBicmVhazsKKyAgICAgICAgb3RoZXIgPSBjLT5saWdodGluZy5mcm9udC5kaWZmdXNlLnY7IGJyZWFrOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1NISU5JTkVTUzoKKyAgICAgICAgYy0+bGlnaHRpbmcuZnJvbnQuc2hpbmluZXNzID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1swXSk7CisgICAgICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7CisgICAgICAgIHJldHVybjsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHdoYXRbMF0gPSBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzBdKTsKKyAgICB3aGF0WzFdID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1sxXSk7CisgICAgd2hhdFsyXSA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMl0pOworICAgIHdoYXRbM10gPSBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzNdKTsKKyAgICBpZiAob3RoZXIpIHsKKyAgICAgICAgb3RoZXJbMF0gPSB3aGF0WzBdOworICAgICAgICBvdGhlclsxXSA9IHdoYXRbMV07CisgICAgICAgIG90aGVyWzJdID0gd2hhdFsyXTsKKyAgICAgICAgb3RoZXJbM10gPSB3aGF0WzNdOworICAgIH0KKyAgICBpbnZhbGlkYXRlX2xpZ2h0aW5nKGMpOworfQorCit2b2lkIGdsTWF0ZXJpYWx4digKKyAgICBHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGZhY2UgIT0gR0xfRlJPTlRfQU5EX0JBQ0spKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgR0xmaXhlZCogd2hhdD0wOworICAgIEdMZml4ZWQqIG90aGVyPTA7CisgICAgc3dpdGNoIChwbmFtZSkgeworICAgIGNhc2UgR0xfQU1CSUVOVDogICAgd2hhdCA9IGMtPmxpZ2h0aW5nLmZyb250LmFtYmllbnQudjsgYnJlYWs7CisgICAgY2FzZSBHTF9ESUZGVVNFOiAgICB3aGF0ID0gYy0+bGlnaHRpbmcuZnJvbnQuZGlmZnVzZS52OyBicmVhazsKKyAgICBjYXNlIEdMX1NQRUNVTEFSOiAgIHdoYXQgPSBjLT5saWdodGluZy5mcm9udC5zcGVjdWxhci52OyBicmVhazsKKyAgICBjYXNlIEdMX0VNSVNTSU9OOiAgIHdoYXQgPSBjLT5saWdodGluZy5mcm9udC5lbWlzc2lvbi52OyBicmVhazsKKyAgICBjYXNlIEdMX0FNQklFTlRfQU5EX0RJRkZVU0U6CisgICAgICAgIHdoYXQgPSBjLT5saWdodGluZy5mcm9udC5hbWJpZW50LnY7IGJyZWFrOworICAgICAgICBvdGhlcj0gYy0+bGlnaHRpbmcuZnJvbnQuZGlmZnVzZS52OyBicmVhazsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9TSElOSU5FU1M6CisgICAgICAgIGMtPmxpZ2h0aW5nLmZyb250LnNoaW5pbmVzcyA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMF0pOworICAgICAgICBpbnZhbGlkYXRlX2xpZ2h0aW5nKGMpOworICAgICAgICByZXR1cm47CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICB3aGF0WzBdID0gcGFyYW1zWzBdOworICAgIHdoYXRbMV0gPSBwYXJhbXNbMV07CisgICAgd2hhdFsyXSA9IHBhcmFtc1syXTsKKyAgICB3aGF0WzNdID0gcGFyYW1zWzNdOworICAgIGlmIChvdGhlcikgeworICAgICAgICBvdGhlclswXSA9IHdoYXRbMF07CisgICAgICAgIG90aGVyWzFdID0gd2hhdFsxXTsKKyAgICAgICAgb3RoZXJbMl0gPSB3aGF0WzJdOworICAgICAgICBvdGhlclszXSA9IHdoYXRbM107CisgICAgfQorICAgIGludmFsaWRhdGVfbGlnaHRpbmcoYyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIGZvZworI2VuZGlmCisKK3ZvaWQgZ2xGb2dmKEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgR0xmaXhlZCBwYXJhbXggPSAoR0xmaXhlZClwYXJhbTsKKyAgICBpZiAocG5hbWUgIT0gR0xfRk9HX01PREUpCisgICAgICAgIHBhcmFteCA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbSk7CisgICAgZm9neChwbmFtZSwgcGFyYW14LCBjKTsKK30KKwordm9pZCBnbEZvZ3goR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBmb2d4KHBuYW1lLCBwYXJhbSwgYyk7Cit9CisKK3ZvaWQgZ2xGb2dmdihHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcykKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChwbmFtZSAhPSBHTF9GT0dfQ09MT1IpIHsKKyAgICAgICAgR0xmaXhlZCBwYXJhbXggPSAoR0xmaXhlZClwYXJhbXNbMF07CisgICAgICAgIGlmIChwbmFtZSAhPSBHTF9GT0dfTU9ERSkKKyAgICAgICAgICAgIHBhcmFteCA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMF0pOworICAgICAgICBmb2d4KHBuYW1lLCBwYXJhbXgsIGMpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIEdMZml4ZWQgcGFyYW1zeFs0XTsKKyAgICBwYXJhbXN4WzBdID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1swXSk7CisgICAgcGFyYW1zeFsxXSA9IGdnbEZsb2F0VG9GaXhlZChwYXJhbXNbMV0pOworICAgIHBhcmFtc3hbMl0gPSBnZ2xGbG9hdFRvRml4ZWQocGFyYW1zWzJdKTsKKyAgICBwYXJhbXN4WzNdID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1szXSk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5mb2dDb2xvcjN4dihjLCBwYXJhbXN4KTsKK30KKwordm9pZCBnbEZvZ3h2KEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHBuYW1lICE9IEdMX0ZPR19DT0xPUikgeworICAgICAgICBmb2d4KHBuYW1lLCBwYXJhbXNbMF0sIGMpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZm9nQ29sb3IzeHYoYywgcGFyYW1zKTsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvbGlnaHQuaCBiL29wZW5nbC9saWJhZ2wvbGlnaHQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGFlMjVmCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9saWdodC5oCkBAIC0wLDAgKzEsMzggQEAKKy8qIGxpYnMvb3BlbmdsZXMvbGlnaHQuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19MSUdIVF9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfTElHSFRfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworbmFtZXNwYWNlIGdsIHsKK3N0cnVjdCBvZ2xlc19jb250ZXh0X3Q7Cit9OworCit2b2lkIG9nbGVzX2luaXRfbGlnaHQob2dsZXNfY29udGV4dF90KiBjKTsKK3ZvaWQgb2dsZXNfdW5pbml0X2xpZ2h0KG9nbGVzX2NvbnRleHRfdCogYyk7Cit2b2lkIG9nbGVzX2ludmFsaWRhdGVfbGlnaHRpbmdfbXZ1aShvZ2xlc19jb250ZXh0X3QqIGMpOworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLy8gQU5EUk9JRF9PUEVOR0xFU19MSUdIVF9ICisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvbWF0cml4LmNwcCBiL29wZW5nbC9saWJhZ2wvbWF0cml4LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTc1Y2RhCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9tYXRyaXguY3BwCkBAIC0wLDAgKzEsMTE0NSBAQAorLyogbGlicy9vcGVuZ2xlcy9tYXRyaXguY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpbmNsdWRlICJjb250ZXh0LmgiCisjaW5jbHVkZSAiZnAuaCIKKyNpbmNsdWRlICJzdGF0ZS5oIgorI2luY2x1ZGUgIm1hdHJpeC5oIgorI2luY2x1ZGUgInZlcnRleC5oIgorI2luY2x1ZGUgImxpZ2h0LmgiCisKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmIGRlZmluZWQoX190aHVtYl9fKQorI3dhcm5pbmcgIm1hdHJpeC5jcHAgc2hvdWxkIG5vdCBiZSBjb21waWxlZCBpbiB0aHVtYiBvbiBBUk0uIgorI2VuZGlmCisKKyNkZWZpbmUgSShfaSwgX2opICgoX2opKyA0KihfaSkpCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0aWMgY29uc3QgR0xmbG9hdCBnSWRlbnRpdHlmWzE2XSA9IHsgMSwwLDAsMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLDEsMCwwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsMCwxLDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwwLDAsMSB9OworCitzdGF0aWMgY29uc3QgbWF0cml4eF90IGdJZGVudGl0eXggPSB7IAorICAgICAgICAgICAgeyAgIDB4MTAwMDAsMCwwLDAsCisgICAgICAgICAgICAgICAgMCwweDEwMDAwLDAsMCwKKyAgICAgICAgICAgICAgICAwLDAsMHgxMDAwMCwwLAorICAgICAgICAgICAgICAgIDAsMCwwLDB4MTAwMDAKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworc3RhdGljIHZvaWQgcG9pbnQyX19ub3AodHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CitzdGF0aWMgdm9pZCBwb2ludDNfX25vcCh0cmFuc2Zvcm1fdCBjb25zdCosIHZlYzRfdCogYywgdmVjNF90IGNvbnN0KiBvKTsKK3N0YXRpYyB2b2lkIHBvaW50NF9fbm9wKHRyYW5zZm9ybV90IGNvbnN0KiwgdmVjNF90KiBjLCB2ZWM0X3QgY29uc3QqIG8pOworc3RhdGljIHZvaWQgbm9ybWFsX19ub3AodHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CitzdGF0aWMgdm9pZCBwb2ludDJfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CitzdGF0aWMgdm9pZCBwb2ludDNfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CitzdGF0aWMgdm9pZCBwb2ludDRfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CitzdGF0aWMgdm9pZCBub3JtYWxfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGMsIHZlYzRfdCBjb25zdCogbyk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI2VuZGlmCisKK3ZvaWQgb2dsZXNfaW5pdF9tYXRyaXgob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGMtPnRyYW5zZm9ybXMubW9kZWx2aWV3LmluaXQoT0dMRVNfTU9ERUxWSUVXX1NUQUNLX0RFUFRIKTsKKyAgICBjLT50cmFuc2Zvcm1zLnByb2plY3Rpb24uaW5pdChPR0xFU19QUk9KRUNUSU9OX1NUQUNLX0RFUFRIKTsKKyAgICBmb3IgKGludCBpPTA7IGk8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IGkrKykKKyAgICAgICAgYy0+dHJhbnNmb3Jtcy50ZXh0dXJlW2ldLmluaXQoT0dMRVNfVEVYVFVSRV9TVEFDS19ERVBUSCk7CisKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQgPSAmYy0+dHJhbnNmb3Jtcy5tb2RlbHZpZXc7CisgICAgYy0+dHJhbnNmb3Jtcy5tYXRyaXhNb2RlID0gR0xfTU9ERUxWSUVXOworICAgIGMtPnRyYW5zZm9ybXMuZGlydHkgPSAgIHRyYW5zZm9ybV9zdGF0ZV90OjpWSUVXUE9SVCB8IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybV9zdGF0ZV90OjpNVlVJIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1fc3RhdGVfdDo6TVZJVCB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtX3N0YXRlX3Q6Ok1WUDsKKyAgICBjLT50cmFuc2Zvcm1zLm12cC5sb2FkSWRlbnRpdHkoKTsKKyAgICBjLT50cmFuc2Zvcm1zLm12cDQubG9hZElkZW50aXR5KCk7CisgICAgYy0+dHJhbnNmb3Jtcy5tdml0NC5sb2FkSWRlbnRpdHkoKTsKKyAgICBjLT50cmFuc2Zvcm1zLm12dWkubG9hZElkZW50aXR5KCk7CisgICAgYy0+dHJhbnNmb3Jtcy52cHQubG9hZElkZW50aXR5KCk7CisgICAgYy0+dHJhbnNmb3Jtcy52cHQuek5lYXIgPSAwLjBmOworICAgIGMtPnRyYW5zZm9ybXMudnB0LnpGYXIgID0gMS4wZjsKK30KKwordm9pZCBvZ2xlc191bmluaXRfbWF0cml4KG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBjLT50cmFuc2Zvcm1zLm1vZGVsdmlldy51bmluaXQoKTsKKyAgICBjLT50cmFuc2Zvcm1zLnByb2plY3Rpb24udW5pbml0KCk7CisgICAgZm9yIChpbnQgaT0wOyBpPEdHTF9URVhUVVJFX1VOSVRfQ09VTlQgOyBpKyspCisgICAgICAgIGMtPnRyYW5zZm9ybXMudGV4dHVyZVtpXS51bmluaXQoKTsKK30KKworc3RhdGljIHZvaWQgdmFsaWRhdGVfcGVyc3BlY3RpdmUob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikKK3sKKyAgICBjb25zdCB1aW50MzJfdCBlbmFibGVzID0gYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzOworICAgIGMtPmFycmF5cy5wZXJzcGVjdGl2ZSA9IChjLT5jbGlwUGxhbmVzLmVuYWJsZSkgPworICAgICAgICBvZ2xlc192ZXJ0ZXhfY2xpcEFsbFBlcnNwZWN0aXZlM0QgOiBvZ2xlc192ZXJ0ZXhfcGVyc3BlY3RpdmUzRDsKKyAgICBpZiAoZW5hYmxlcyAmIChHR0xfRU5BQkxFX0RFUFRIX1RFU1R8R0dMX0VOQUJMRV9GT0cpKSB7CisgICAgICAgIGMtPmFycmF5cy5wZXJzcGVjdGl2ZSA9IG9nbGVzX3ZlcnRleF9wZXJzcGVjdGl2ZTNEWjsKKyAgICAgICAgaWYgKGMtPmNsaXBQbGFuZXMuZW5hYmxlIHx8IChlbmFibGVzJkdHTF9FTkFCTEVfRk9HKSkKKyAgICAgICAgICAgIGMtPmFycmF5cy5wZXJzcGVjdGl2ZSA9IG9nbGVzX3ZlcnRleF9jbGlwQWxsUGVyc3BlY3RpdmUzRFo7CisgICAgfQorICAgIGlmICgoYy0+YXJyYXlzLnZlcnRleC5zaXplICE9IDQpICYmCisgICAgICAgIChjLT50cmFuc2Zvcm1zLm12cDQuZmxhZ3MgJiB0cmFuc2Zvcm1fdDo6RkxBR1NfMkRfUFJPSkVDVElPTikpIHsKKyAgICAgICAgYy0+YXJyYXlzLnBlcnNwZWN0aXZlID0gb2dsZXNfdmVydGV4X3BlcnNwZWN0aXZlMkQ7CisgICAgfQorICAgIGMtPmFycmF5cy5wZXJzcGVjdGl2ZShjLCB2KTsKK30KKwordm9pZCBvZ2xlc19pbnZhbGlkYXRlX3BlcnNwZWN0aXZlKG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBjLT5hcnJheXMucGVyc3BlY3RpdmUgPSB2YWxpZGF0ZV9wZXJzcGVjdGl2ZTsKK30KKwordm9pZCBvZ2xlc192YWxpZGF0ZV90cmFuc2Zvcm1faW1wbChvZ2xlc19jb250ZXh0X3QqIGMsIHVpbnQzMl90IHdhbnQpCit7CisgICAgaW50IGRpcnR5ID0gYy0+dHJhbnNmb3Jtcy5kaXJ0eSAmIHdhbnQ7CisKKyAgICAvLyBWYWxpZGF0ZSB0aGUgbW9kZWx2aWV3CisgICAgaWYgKGRpcnR5ICYgdHJhbnNmb3JtX3N0YXRlX3Q6Ok1PREVMVklFVykgeworICAgICAgICBjLT50cmFuc2Zvcm1zLm1vZGVsdmlldy52YWxpZGF0ZSgpOworICAgIH0KKworICAgIC8vIFZhbGlkYXRlIHRoZSBwcm9qZWN0aW9uIHN0YWNrIChpbiBmYWN0LCBpdCdzIG5ldmVyIG5lZWRlZCkKKyAgICBpZiAoZGlydHkgJiB0cmFuc2Zvcm1fc3RhdGVfdDo6UFJPSkVDVElPTikgeworICAgICAgICBjLT50cmFuc2Zvcm1zLnByb2plY3Rpb24udmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICAvLyBWYWxpZGF0ZSB0aGUgdmlld3BvcnQgdHJhbnNmb3JtYXRpb24KKyAgICBpZiAoZGlydHkgJiB0cmFuc2Zvcm1fc3RhdGVfdDo6VklFV1BPUlQpIHsKKyAgICAgICAgdnBfdHJhbnNmb3JtX3QmIHZwdCA9IGMtPnRyYW5zZm9ybXMudnB0OworICAgICAgICB2cHQudHJhbnNmb3JtLm1hdHJpeC5sb2FkKHZwdC5tYXRyaXgpOworICAgICAgICB2cHQudHJhbnNmb3JtLnBpY2tlcigpOworICAgIH0KKworICAgIC8vIFdlIG5lZWQgdG8gdXBkYXRlIHRoZSBtdnAgKHVzZWQgdG8gdHJhbnNmb3JtIGVhY2ggdmVydGV4KQorICAgIGlmIChkaXJ0eSAmIHRyYW5zZm9ybV9zdGF0ZV90OjpNVlApIHsKKyAgICAgICAgYy0+dHJhbnNmb3Jtcy51cGRhdGVfbXZwKCk7CisgICAgICAgIC8vIGludmFsaWRhdGUgcGVyc3BlY3RpdmUgKGRpdmlkZSBieSBXKSBhbmQgdmlldyB2b2x1bWUgY2xpcHBpbmcKKyAgICAgICAgb2dsZXNfaW52YWxpZGF0ZV9wZXJzcGVjdGl2ZShjKTsKKyAgICB9CisKKyAgICAvLyBWYWxpZGF0ZSB0aGUgbXZ1aSAoZm9yIG5vcm1hbCB0cmFuc2Zvcm1hdGlvbikKKyAgICBpZiAoZGlydHkgJiB0cmFuc2Zvcm1fc3RhdGVfdDo6TVZVSSkgeworICAgICAgICBjLT50cmFuc2Zvcm1zLnVwZGF0ZV9tdnVpKCk7CisgICAgICAgIG9nbGVzX2ludmFsaWRhdGVfbGlnaHRpbmdfbXZ1aShjKTsKKyAgICB9CisKKyAgICAvLyBWYWxpZGF0ZSB0aGUgdGV4dHVyZSBzdGFjaworICAgIGlmIChkaXJ0eSAmIHRyYW5zZm9ybV9zdGF0ZV90OjpURVhUVVJFKSB7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgaSsrKQorICAgICAgICAgICAgYy0+dHJhbnNmb3Jtcy50ZXh0dXJlW2ldLnZhbGlkYXRlKCk7CisgICAgfQorCisgICAgLy8gVmFsaWRhdGUgdGhlIG12aXQ0ICh1c2VyLWNsaXAgcGxhbmVzKQorICAgIGlmIChkaXJ0eSAmIHRyYW5zZm9ybV9zdGF0ZV90OjpNVklUKSB7CisgICAgICAgIGMtPnRyYW5zZm9ybXMudXBkYXRlX212aXQoKTsKKyAgICB9CisKKyAgICBjLT50cmFuc2Zvcm1zLmRpcnR5ICY9IH53YW50OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayB0cmFuc2Zvcm1fdAorI2VuZGlmCisKK3ZvaWQgdHJhbnNmb3JtX3Q6OmxvYWRJZGVudGl0eSgpIHsKKyAgICBtYXRyaXggPSBnSWRlbnRpdHl4OworICAgIGZsYWdzID0gMDsKKyAgICBvcHMgPSBPUF9JREVOVElUWTsKKyAgICBwb2ludDIgPSBwb2ludDJfX25vcDsKKyAgICBwb2ludDMgPSBwb2ludDNfX25vcDsKKyAgICBwb2ludDQgPSBwb2ludDRfX25vcDsKK30KKworCitzdGF0aWMgaW5saW5lCitpbnQgbm90WmVybyhHTGZpeGVkIHYpIHsKKyAgICByZXR1cm4gYWJzKHYpICYgfjB4MzsKK30KKworc3RhdGljIGlubGluZQoraW50IG5vdE9uZShHTGZpeGVkIHYpIHsKKyAgICByZXR1cm4gbm90WmVybyh2IC0gMHgxMDAwMCk7Cit9CisKK3ZvaWQgdHJhbnNmb3JtX3Q6OnBpY2tlcigpCit7CisgICAgY29uc3QgR0xmaXhlZCogY29uc3QgbSA9IG1hdHJpeC5tOworCisgICAgLy8gWFhYOiBwaWNrZXIgbmVlZHMgdG8gYmUgc21hcnRlcgorICAgIGZsYWdzID0gMDsKKyAgICBvcHMgPSBPUF9BTEw7CisgICAgcG9pbnQyID0gcG9pbnQyX19nZW5lcmljOworICAgIHBvaW50MyA9IHBvaW50M19fZ2VuZXJpYzsKKyAgICBwb2ludDQgPSBwb2ludDRfX2dlbmVyaWM7CisgICAgCisgICAgLy8gZmluZCBvdXQgaWYgdGhpcyBpcyBhIDJEIHByb2plY3Rpb24KKyAgICBpZiAoIShub3RaZXJvKG1bM10pIHwgbm90WmVybyhtWzddKSB8IG5vdFplcm8obVsxMV0pIHwgbm90T25lKG1bMTVdKSkpIHsKKyAgICAgICAgZmxhZ3MgfD0gRkxBR1NfMkRfUFJPSkVDVElPTjsKKyAgICB9Cit9CisKK3ZvaWQgbXZ1aV90cmFuc2Zvcm1fdDo6cGlja2VyKCkKK3sKKyAgICBmbGFncyA9IDA7CisgICAgb3BzID0gT1BfQUxMOworICAgIHBvaW50MyA9IG5vcm1hbF9fZ2VuZXJpYzsKK30KKwordm9pZCB0cmFuc2Zvcm1fdDo6ZHVtcChjb25zdCBjaGFyKiB3aGF0KQoreworICAgIEdMZml4ZWQgY29uc3QgKiBjb25zdCBtID0gbWF0cml4Lm07CisgICAgTE9HRCgiJXM6Iiwgd2hhdCk7CisgICAgZm9yIChpbnQgaT0wIDsgaTw0IDsgaSsrKQorICAgICAgICBMT0dEKCJbJTA4eCAlMDh4ICUwOHggJTA4eF0gWyVmICVmICVmICVmXVxuIiwKKyAgICAgICAgICAgIG1bSSgwLGkpXSwgbVtJKDEsaSldLCBtW0koMixpKV0sIG1bSSgzLGkpXSwKKyAgICAgICAgICAgIGZpeGVkVG9GbG9hdChtW0koMCxpKV0pLAorICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KG1bSSgxLGkpXSksIAorICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KG1bSSgyLGkpXSksCisgICAgICAgICAgICBmaXhlZFRvRmxvYXQobVtJKDMsaSldKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIG1hdHJpeHhfdAorI2VuZGlmCisKK3ZvaWQgbWF0cml4eF90Ojpsb2FkKGNvbnN0IG1hdHJpeGZfdCYgcmhzKSB7CisgICAgR0xmaXhlZCogeHAgPSBtOworICAgIEdMZmxvYXQgY29uc3QqIGZwID0gcmhzLmVsZW1lbnRzKCk7CisgICAgdW5zaWduZWQgaW50IGkgPSAxNjsKKyAgICBkbyB7CisgICAgICAgIGNvbnN0IEdMZmxvYXQgZiA9ICpmcCsrOworICAgICAgICAqeHArKyA9IGlzWmVyb2YoZikgPyAwIDogZ2dsRmxvYXRUb0ZpeGVkKGYpOworICAgIH0gd2hpbGUgKC0taSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIG1hdHJpeGZfdAorI2VuZGlmCisKK3ZvaWQgbWF0cml4Zl90OjptdWx0aXBseShtYXRyaXhmX3QmIHIsIGNvbnN0IG1hdHJpeGZfdCYgbGhzLCBjb25zdCBtYXRyaXhmX3QmIHJocykKK3sKKyAgICBHTGZsb2F0IGNvbnN0KiBjb25zdCBtID0gbGhzLm07CisgICAgZm9yIChpbnQgaT0wIDsgaTw0IDsgaSsrKSB7CisgICAgICAgIHJlZ2lzdGVyIGNvbnN0IGZsb2F0IHJoc19pMCA9IHJocy5tWyBJKGksMCkgXTsKKyAgICAgICAgcmVnaXN0ZXIgZmxvYXQgcmkwID0gbVsgSSgwLDApIF0gKiByaHNfaTA7CisgICAgICAgIHJlZ2lzdGVyIGZsb2F0IHJpMSA9IG1bIEkoMCwxKSBdICogcmhzX2kwOworICAgICAgICByZWdpc3RlciBmbG9hdCByaTIgPSBtWyBJKDAsMikgXSAqIHJoc19pMDsKKyAgICAgICAgcmVnaXN0ZXIgZmxvYXQgcmkzID0gbVsgSSgwLDMpIF0gKiByaHNfaTA7CisgICAgICAgIGZvciAoaW50IGo9MSA7IGo8NCA7IGorKykgeworICAgICAgICAgICAgcmVnaXN0ZXIgY29uc3QgZmxvYXQgcmhzX2lqID0gcmhzLm1bIEkoaSxqKSBdOworICAgICAgICAgICAgcmkwICs9IG1bIEkoaiwwKSBdICogcmhzX2lqOworICAgICAgICAgICAgcmkxICs9IG1bIEkoaiwxKSBdICogcmhzX2lqOworICAgICAgICAgICAgcmkyICs9IG1bIEkoaiwyKSBdICogcmhzX2lqOworICAgICAgICAgICAgcmkzICs9IG1bIEkoaiwzKSBdICogcmhzX2lqOworICAgICAgICB9CisgICAgICAgIHIubVsgSShpLDApIF0gPSByaTA7CisgICAgICAgIHIubVsgSShpLDEpIF0gPSByaTE7CisgICAgICAgIHIubVsgSShpLDIpIF0gPSByaTI7CisgICAgICAgIHIubVsgSShpLDMpIF0gPSByaTM7CisgICAgfQorfQorCit2b2lkIG1hdHJpeGZfdDo6ZHVtcChjb25zdCBjaGFyKiB3aGF0KSB7CisgICAgTE9HRCgiJXMiLCB3aGF0KTsKKyAgICBMT0dEKCJbICU5ZiAlOWYgJTlmICU5ZiBdIiwgbVtJKDAsMCldLCBtW0koMSwwKV0sIG1bSSgyLDApXSwgbVtJKDMsMCldKTsKKyAgICBMT0dEKCJbICU5ZiAlOWYgJTlmICU5ZiBdIiwgbVtJKDAsMSldLCBtW0koMSwxKV0sIG1bSSgyLDEpXSwgbVtJKDMsMSldKTsKKyAgICBMT0dEKCJbICU5ZiAlOWYgJTlmICU5ZiBdIiwgbVtJKDAsMildLCBtW0koMSwyKV0sIG1bSSgyLDIpXSwgbVtJKDMsMildKTsKKyAgICBMT0dEKCJbICU5ZiAlOWYgJTlmICU5ZiBdIiwgbVtJKDAsMyldLCBtW0koMSwzKV0sIG1bSSgyLDMpXSwgbVtJKDMsMyldKTsKK30KKwordm9pZCBtYXRyaXhmX3Q6OmxvYWRJZGVudGl0eSgpIHsKKyAgICBtZW1jcHkobSwgZ0lkZW50aXR5Ziwgc2l6ZW9mKG0pKTsKK30KKwordm9pZCBtYXRyaXhmX3Q6OnNldChjb25zdCBHTGZpeGVkKiByaHMpIHsKKyAgICBsb2FkKHJocyk7Cit9CisKK3ZvaWQgbWF0cml4Zl90OjpzZXQoY29uc3QgR0xmbG9hdCogcmhzKSB7CisgICAgbG9hZChyaHMpOworfQorCit2b2lkIG1hdHJpeGZfdDo6bG9hZChjb25zdCBHTGZpeGVkKiByaHMpIHsKKyAgICBHTGZsb2F0KiBmcCA9IG07CisgICAgdW5zaWduZWQgaW50IGkgPSAxNjsKKyAgICBkbyB7CisgICAgICAgICpmcCsrID0gZml4ZWRUb0Zsb2F0KCpyaHMrKyk7CisgICAgfSB3aGlsZSAoLS1pKTsKK30KKwordm9pZCBtYXRyaXhmX3Q6OmxvYWQoY29uc3QgR0xmbG9hdCogcmhzKSB7CisgICAgbWVtY3B5KG0sIHJocywgc2l6ZW9mKG0pKTsKK30KKwordm9pZCBtYXRyaXhmX3Q6OmxvYWQoY29uc3QgbWF0cml4Zl90JiByaHMpIHsKKyAgICBvcGVyYXRvciA9IChyaHMpOworfQorCit2b2lkIG1hdHJpeGZfdDo6bXVsdGlwbHkoY29uc3QgbWF0cml4Zl90JiByaHMpIHsKKyAgICBtYXRyaXhmX3QgcjsKKyAgICBtdWx0aXBseShyLCAqdGhpcywgcmhzKTsKKyAgICBvcGVyYXRvciA9IChyKTsKK30KKwordm9pZCBtYXRyaXhmX3Q6OnRyYW5zbGF0ZShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KSB7CisgICAgZm9yIChpbnQgaT0wIDsgaTw0IDsgaSsrKSB7CisgICAgICAgIG1bMTIraV0gKz0gbVtpXSp4ICsgbVs0K2ldKnkgKyBtWzgraV0qejsKKyAgICB9Cit9CisKK3ZvaWQgbWF0cml4Zl90OjpzY2FsZShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KSB7CisgICAgZm9yIChpbnQgaT0wIDsgaTw0IDsgaSsrKSB7CisgICAgICAgIG1bICBpXSAqPSB4OworICAgICAgICBtWzQraV0gKj0geTsKKyAgICAgICAgbVs4K2ldICo9IHo7CisgICAgfQorfQorCit2b2lkIG1hdHJpeGZfdDo6cm90YXRlKEdMZmxvYXQgYSwgR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeikKK3sKKyAgICBtYXRyaXhmX3Qgcm90YXRpb247CisgICAgR0xmbG9hdCogciA9IHJvdGF0aW9uLm07CisgICAgR0xmbG9hdCBjLCBzOworICAgIHJbM10gPSAwOyAgIHJbN10gPSAwOyAgIHJbMTFdPSAwOworICAgIHJbMTJdPSAwOyAgIHJbMTNdPSAwOyAgIHJbMTRdPSAwOyAgIHJbMTVdPSAxOworICAgIGEgKj0gR0xmbG9hdChNX1BJIC8gMTgwLjBmKTsKKyAgICBzaW5jb3NmKGEsICZzLCAmYyk7CisgICAgaWYgKGlzT25lZih4KSAmJiBpc1plcm9mKHkpICYmIGlzWmVyb2YoeikpIHsKKyAgICAgICAgcls1XSA9IGM7ICAgclsxMF09IGM7CisgICAgICAgIHJbNl0gPSBzOyAgIHJbOV0gPSAtczsKKyAgICAgICAgclsxXSA9IDA7ICAgclsyXSA9IDA7CisgICAgICAgIHJbNF0gPSAwOyAgIHJbOF0gPSAwOworICAgICAgICByWzBdID0gMTsKKyAgICB9IGVsc2UgaWYgKGlzWmVyb2YoeCkgJiYgaXNPbmVmKHkpICYmIGlzWmVyb2YoeikpIHsKKyAgICAgICAgclswXSA9IGM7ICAgclsxMF09IGM7CisgICAgICAgIHJbOF0gPSBzOyAgIHJbMl0gPSAtczsKKyAgICAgICAgclsxXSA9IDA7ICAgcls0XSA9IDA7CisgICAgICAgIHJbNl0gPSAwOyAgIHJbOV0gPSAwOworICAgICAgICByWzVdID0gMTsKKyAgICB9IGVsc2UgaWYgKGlzWmVyb2YoeCkgJiYgaXNaZXJvZih5KSAmJiBpc09uZWYoeikpIHsKKyAgICAgICAgclswXSA9IGM7ICAgcls1XSA9IGM7CisgICAgICAgIHJbMV0gPSBzOyAgIHJbNF0gPSAtczsKKyAgICAgICAgclsyXSA9IDA7ICAgcls2XSA9IDA7CisgICAgICAgIHJbOF0gPSAwOyAgIHJbOV0gPSAwOworICAgICAgICByWzEwXT0gMTsKKyAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBHTGZsb2F0IGxlbiA9IHNxcnRmKHgqeCArIHkqeSArIHoqeik7CisgICAgICAgIGlmICghaXNPbmVmKGxlbikpIHsKKyAgICAgICAgICAgIGNvbnN0IEdMZmxvYXQgcmVjaXBMZW4gPSByZWNpcHJvY2FsZihsZW4pOworICAgICAgICAgICAgeCAqPSByZWNpcExlbjsKKyAgICAgICAgICAgIHkgKj0gcmVjaXBMZW47CisgICAgICAgICAgICB6ICo9IHJlY2lwTGVuOworICAgICAgICB9CisgICAgICAgIGNvbnN0IEdMZmxvYXQgbmMgPSAxLjBmIC0gYzsKKyAgICAgICAgY29uc3QgR0xmbG9hdCB4eSA9IHggKiB5OworICAgICAgICBjb25zdCBHTGZsb2F0IHl6ID0geSAqIHo7CisgICAgICAgIGNvbnN0IEdMZmxvYXQgenggPSB6ICogeDsKKyAgICAgICAgY29uc3QgR0xmbG9hdCB4cyA9IHggKiBzOworICAgICAgICBjb25zdCBHTGZsb2F0IHlzID0geSAqIHM7CisgICAgICAgIGNvbnN0IEdMZmxvYXQgenMgPSB6ICogczsJCQorICAgICAgICByWyAwXSA9IHgqeCpuYyArICBjOyAgICByWyA0XSA9ICB4eSpuYyAtIHpzOyAgICByWyA4XSA9ICB6eCpuYyArIHlzOworICAgICAgICByWyAxXSA9ICB4eSpuYyArIHpzOyAgICByWyA1XSA9IHkqeSpuYyArICBjOyAgICByWyA5XSA9ICB5eipuYyAtIHhzOworICAgICAgICByWyAyXSA9ICB6eCpuYyAtIHlzOyAgICByWyA2XSA9ICB5eipuYyArIHhzOyAgICByWzEwXSA9IHoqeipuYyArICBjOworICAgIH0KKyAgICBtdWx0aXBseShyb3RhdGlvbik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIG1hdHJpeF9zdGFja190CisjZW5kaWYKKwordm9pZCBtYXRyaXhfc3RhY2tfdDo6aW5pdChpbnQgZGVwdGgpIHsKKyAgICBzdGFjayA9IG5ldyBtYXRyaXhmX3RbZGVwdGhdOworICAgIG9wcyA9IG5ldyB1aW50OF90W2RlcHRoXTsKKyAgICBtYXhEZXB0aCA9IGRlcHRoOworICAgIGRlcHRoID0gMDsKKyAgICBkaXJ0eSA9IDA7CisgICAgbG9hZElkZW50aXR5KCk7Cit9CisKK3ZvaWQgbWF0cml4X3N0YWNrX3Q6OnVuaW5pdCgpIHsKKyAgICBkZWxldGUgW10gc3RhY2s7CisgICAgZGVsZXRlIFtdIG9wczsKK30KKwordm9pZCBtYXRyaXhfc3RhY2tfdDo6bG9hZElkZW50aXR5KCkgeworICAgIHRyYW5zZm9ybS5sb2FkSWRlbnRpdHkoKTsKKyAgICBzdGFja1tkZXB0aF0ubG9hZElkZW50aXR5KCk7CisgICAgb3BzW2RlcHRoXSA9IE9QX0lERU5USVRZOworfQorCit2b2lkIG1hdHJpeF9zdGFja190Ojpsb2FkKGNvbnN0IEdMZml4ZWQqIHJocykKK3sgICAKKyAgICBtZW1jcHkodHJhbnNmb3JtLm1hdHJpeC5tLCByaHMsIHNpemVvZih0cmFuc2Zvcm0ubWF0cml4Lm0pKTsKKyAgICBzdGFja1tkZXB0aF0ubG9hZChyaHMpOworICAgIG9wc1tkZXB0aF0gPSBPUF9BTEw7ICAgIC8vIFRPRE86IHdlIHNob3VsZCBsb29rIGF0IHRoZSBtYXRyaXgKK30KKwordm9pZCBtYXRyaXhfc3RhY2tfdDo6bG9hZChjb25zdCBHTGZsb2F0KiByaHMpCit7CisgICAgc3RhY2tbZGVwdGhdLmxvYWQocmhzKTsKKyAgICBvcHNbZGVwdGhdID0gT1BfQUxMOyAgICAvLyBUT0RPOiB3ZSBzaG91bGQgbG9vayBhdCB0aGUgbWF0cml4Cit9CisKK3ZvaWQgbWF0cml4X3N0YWNrX3Q6Om11bHRpcGx5KGNvbnN0IG1hdHJpeGZfdCYgcmhzKQoreyAgICAKKyAgICBzdGFja1tkZXB0aF0ubXVsdGlwbHkocmhzKTsKKyAgICBvcHNbZGVwdGhdID0gT1BfQUxMOyAgICAvLyBUT0RPOiB3ZSBzaG91bGQgbG9vayBhdCB0aGUgbWF0cml4Cit9CisKK3ZvaWQgbWF0cml4X3N0YWNrX3Q6OnRyYW5zbGF0ZShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KQoreworICAgIHN0YWNrW2RlcHRoXS50cmFuc2xhdGUoeCx5LHopOworICAgIG9wc1tkZXB0aF0gfD0gT1BfVFJBTlNMQVRFOworfQorCit2b2lkIG1hdHJpeF9zdGFja190OjpzY2FsZShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KQoreworICAgIHN0YWNrW2RlcHRoXS5zY2FsZSh4LHkseik7CisgICAgaWYgKHg9PXkgJiYgeT09eikgeworICAgICAgICBvcHNbZGVwdGhdIHw9IE9QX1VOSUZPUk1fU0NBTEU7CisgICAgfSBlbHNlIHsKKyAgICAgICAgb3BzW2RlcHRoXSB8PSBPUF9TQ0FMRTsKKyAgICB9Cit9CisKK3ZvaWQgbWF0cml4X3N0YWNrX3Q6OnJvdGF0ZShHTGZsb2F0IGEsIEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopCit7CisgICAgc3RhY2tbZGVwdGhdLnJvdGF0ZShhLHgseSx6KTsKKyAgICBvcHNbZGVwdGhdIHw9IE9QX1JPVEFURTsKK30KKwordm9pZCBtYXRyaXhfc3RhY2tfdDo6dmFsaWRhdGUoKQoreworICAgIGlmIChkaXJ0eSAmIERPX0ZMT0FUX1RPX0ZJWEVEKSB7CisgICAgICAgIHRyYW5zZm9ybS5tYXRyaXgubG9hZCh0b3AoKSk7CisgICAgfQorICAgIGlmIChkaXJ0eSAmIERPX1BJQ0tFUikgeworICAgICAgICB0cmFuc2Zvcm0ucGlja2VyKCk7CisgICAgfQorICAgIGRpcnR5ID0gMDsKK30KKworR0xpbnQgbWF0cml4X3N0YWNrX3Q6OnB1c2goKQoreworICAgIGlmIChkZXB0aCA+PSAobWF4RGVwdGgtMSkpIHsKKyAgICAgICAgcmV0dXJuIEdMX1NUQUNLX09WRVJGTE9XOworICAgIH0KKyAgICBzdGFja1tkZXB0aCsxXSA9IHN0YWNrW2RlcHRoXTsKKyAgICBvcHNbZGVwdGgrMV0gPSBvcHNbZGVwdGhdOworICAgIGRlcHRoKys7CisgICAgcmV0dXJuIDA7Cit9CisKK0dMaW50IG1hdHJpeF9zdGFja190Ojpwb3AoKQoreworICAgIGlmIChkZXB0aCA9PSAwKSB7CisgICAgICAgIHJldHVybiBHTF9TVEFDS19VTkRFUkZMT1c7CisgICAgfQorICAgIGRlcHRoLS07CisgICAgcmV0dXJuIDA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIHZwX3RyYW5zZm9ybV90CisjZW5kaWYKKwordm9pZCB2cF90cmFuc2Zvcm1fdDo6bG9hZElkZW50aXR5KCkgeworICAgIHRyYW5zZm9ybS5sb2FkSWRlbnRpdHkoKTsKKyAgICBtYXRyaXgubG9hZElkZW50aXR5KCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyNpZiAwCisjcHJhZ21hIG1hcmsgLQorI3ByYWdtYSBtYXJrIHRyYW5zZm9ybV9zdGF0ZV90CisjZW5kaWYKKwordm9pZCB0cmFuc2Zvcm1fc3RhdGVfdDo6aW52YWxpZGF0ZSgpCit7CisgICAgc3dpdGNoIChtYXRyaXhNb2RlKSB7CisgICAgY2FzZSBHTF9NT0RFTFZJRVc6ICBkaXJ0eSB8PSBNT0RFTFZJRVcgIHwgTVZQIHwgTVZVSSB8IE1WSVQ7ICAgIGJyZWFrOworICAgIGNhc2UgR0xfUFJPSkVDVElPTjogZGlydHkgfD0gUFJPSkVDVElPTiB8IE1WUDsgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1RFWFRVUkU6ICAgIGRpcnR5IHw9IFRFWFRVUkUgICAgfCBNVlA7ICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGN1cnJlbnQtPmRpcnR5ID0gICAgbWF0cml4X3N0YWNrX3Q6OkRPX1BJQ0tFUiB8CisgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhfc3RhY2tfdDo6RE9fRkxPQVRfVE9fRklYRUQ7Cit9CisKK3ZvaWQgdHJhbnNmb3JtX3N0YXRlX3Q6OnVwZGF0ZV9tdnAoKQoreworICAgIG1hdHJpeGZfdCB0ZW1wX212cDsKKyAgICBtYXRyaXhmX3Q6Om11bHRpcGx5KHRlbXBfbXZwLCBwcm9qZWN0aW9uLnRvcCgpLCBtb2RlbHZpZXcudG9wKCkpOworICAgIG12cDQubWF0cml4LmxvYWQodGVtcF9tdnApOworICAgIG12cDQucGlja2VyKCk7CisKKyAgICBpZiAobXZwNC5mbGFncyAmIHRyYW5zZm9ybV90OjpGTEFHU18yRF9QUk9KRUNUSU9OKSB7CisgICAgICAgIC8vIHRoZSBtdnAgbWF0cml4IGRvZXNuJ3QgdHJhbnNmb3JtIFcsIGluIHRoaXMgY2FzZSB3ZSBjYW4KKyAgICAgICAgLy8gcHJlbXVsdGlwbHkgaXQgd2l0aCB0aGUgdmlld3BvcnQgdHJhbnNmb3JtYXRpb24uIEluIGFkZGl0aW9uIHRvCisgICAgICAgIC8vIGJlaW5nIG1vcmUgZWZmaWNpZW50LCB0aGlzIGlzIGFsc28gbXVjaCBtb3JlIGFjY3VyYXRlIGFuZCBpbiBmYWN0CisgICAgICAgIC8vIGlzIG5lZWRlZCBmb3IgMkQgZHJhd2luZyB3aXRoIGEgcmVzdWx0aW5nIDE6MSBtYXBwaW5nLgorICAgICAgICBtYXRyaXhmX3QgbXZwdjsKKyAgICAgICAgbWF0cml4Zl90OjptdWx0aXBseShtdnB2LCB2cHQubWF0cml4LCB0ZW1wX212cCk7CisgICAgICAgIG12cC5tYXRyaXgubG9hZChtdnB2KTsKKyAgICAgICAgbXZwLnBpY2tlcigpOworICAgIH0gZWxzZSB7CisgICAgICAgIG12cCA9IG12cDQ7CisgICAgfQorfQorCitzdGF0aWMgaW5saW5lIAorR0xmbG9hdCBkZXQyMihHTGZsb2F0IGEsIEdMZmxvYXQgYiwgR0xmbG9hdCBjLCBHTGZsb2F0IGQpIHsKKyAgICByZXR1cm4gYSpkIC0gYipjOworfQorCitzdGF0aWMgaW5saW5lCitHTGZsb2F0IG5kZXQyMihHTGZsb2F0IGEsIEdMZmxvYXQgYiwgR0xmbG9hdCBjLCBHTGZsb2F0IGQpIHsKKyAgICByZXR1cm4gYipjIC0gYSpkOworfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBpbnZlcnQoR0xmbG9hdCogaW52ZXJzZSwgY29uc3QgR0xmbG9hdCogc3JjKQoreworICAgIGRvdWJsZSB0OworICAgIGludCBpLCBqLCBrLCBzd2FwOworICAgIEdMZmxvYXQgdG1wWzRdWzRdOworICAgIAorICAgIG1lbWNweShpbnZlcnNlLCBnSWRlbnRpdHlmLCBzaXplb2YoZ0lkZW50aXR5ZikpOworICAgIG1lbWNweSh0bXAsIHNyYywgc2l6ZW9mKEdMZmxvYXQpKjE2KTsKKyAgICAKKyAgICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgICAgIC8vIGxvb2sgZm9yIGxhcmdlc3QgZWxlbWVudCBpbiBjb2x1bW4KKyAgICAgICAgc3dhcCA9IGk7CisgICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgNDsgaisrKSB7CisgICAgICAgICAgICBpZiAoZmFicyh0bXBbal1baV0pID4gZmFicyh0bXBbaV1baV0pKSB7CisgICAgICAgICAgICAgICAgc3dhcCA9IGo7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGlmIChzd2FwICE9IGkpIHsKKyAgICAgICAgICAgIC8qIHN3YXAgcm93cy4gKi8KKyAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCA0OyBrKyspIHsKKyAgICAgICAgICAgICAgICB0ID0gdG1wW2ldW2tdOworICAgICAgICAgICAgICAgIHRtcFtpXVtrXSA9IHRtcFtzd2FwXVtrXTsKKyAgICAgICAgICAgICAgICB0bXBbc3dhcF1ba10gPSB0OworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIHQgPSBpbnZlcnNlW2kqNCtrXTsKKyAgICAgICAgICAgICAgICBpbnZlcnNlW2kqNCtrXSA9IGludmVyc2Vbc3dhcCo0K2tdOworICAgICAgICAgICAgICAgIGludmVyc2Vbc3dhcCo0K2tdID0gdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgdCA9IDEuMGYgLyB0bXBbaV1baV07CisgICAgICAgIGZvciAoayA9IDA7IGsgPCA0OyBrKyspIHsKKyAgICAgICAgICAgIHRtcFtpXVtrXSAqPSB0OworICAgICAgICAgICAgaW52ZXJzZVtpKjQra10gKj0gdDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGogPSAwOyBqIDwgNDsgaisrKSB7CisgICAgICAgICAgICBpZiAoaiAhPSBpKSB7CisgICAgICAgICAgICAgICAgdCA9IHRtcFtqXVtpXTsKKyAgICAgICAgICAgICAgICBmb3IgKGsgPSAwOyBrIDwgNDsgaysrKSB7CisgICAgICAgICAgICAgICAgICAgIHRtcFtqXVtrXSAtPSB0bXBbaV1ba10qdDsKKyAgICAgICAgICAgICAgICAgICAgaW52ZXJzZVtqKjQra10gLT0gaW52ZXJzZVtpKjQra10qdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgdHJhbnNmb3JtX3N0YXRlX3Q6OnVwZGF0ZV9tdml0KCkKK3sKKyAgICBHTGZsb2F0IHJbMTZdOworICAgIGNvbnN0IEdMZmxvYXQqIGNvbnN0IG12ID0gbW9kZWx2aWV3LnRvcCgpLmVsZW1lbnRzKCk7CisgICAgaW52ZXJ0KHIsIG12KTsKKyAgICAvLyBjb252ZXJ0IHRvIGZpeGVkLXBvaW50IGFuZCB0cmFuc3Bvc2UKKyAgICBHTGZpeGVkKiBjb25zdCB4ID0gbXZpdDQubWF0cml4Lm07CisgICAgZm9yIChpbnQgaT0wIDsgaTw0IDsgaSsrKQorICAgICAgICBmb3IgKGludCBqPTAgOyBqPDQgOyBqKyspCisgICAgICAgICAgICB4W0koaSxqKV0gPSBnZ2xGbG9hdFRvRml4ZWQocltJKGosaSldKTsKKyAgICBtdml0NC5waWNrZXIoKTsKK30KKwordm9pZCB0cmFuc2Zvcm1fc3RhdGVfdDo6dXBkYXRlX212dWkoKQoreworICAgIGNvbnN0IEdMZmxvYXQqIGNvbnN0IG12ID0gbW9kZWx2aWV3LnRvcCgpLmVsZW1lbnRzKCk7CisKKyAgICAvKgorICAgIFdoZW4gdHJhbnNmb3JtaW5nIG5vcm1hbHMsIHdlIGNhbiB1c2UgdGhlIHVwcGVyIDN4MyBtYXRyaXgsIHNlZToKKyAgICBodHRwOi8vd3d3Lm9wZW5nbC5vcmcvZG9jdW1lbnRhdGlvbi9zcGVjcy92ZXJzaW9uMS4xL2dsc3BlYzEuMS9ub2RlMjYuaHRtbAorICAgICovCisgICAgCisgICAgLy8gQWxzbyBub3RlIHRoYXQ6CisgICAgLy8gICAgICBsKG9iaikgPSAgdHIoTSkubChleWUpIGZvciBpbmZpbml0ZSBsaWdodAorICAgIC8vICAgICAgbChvYmopID0gaW52KE0pLmwoZXllKSBmb3IgbG9jYWwgbGlnaHQKKworICAgIGNvbnN0IHVpbnQzMl90IG9wcyA9IG1vZGVsdmlldy50b3Bfb3BzKCkgJiB+T1BfVFJBTlNMQVRFOworICAgIGlmIChnZ2xfbGlrZWx5KCghKG9wcyAmIH5PUF9ST1RBVEUpKSB8fAorICAgICAgICAocmVzY2FsZU5vcm1hbHMgJiYgbW9kZWx2aWV3LmlzUmlnaWRCb2R5KCkpKSkgeworICAgICAgICAvLyBpZiB0aGUgbW9kZWx2aWV3IG1hdHJpeCBpcyBhIHJpZ2lkIGJvZHkgdHJhbnNmb3JtYXRpb24KKyAgICAgICAgLy8gKHRyYW5zbGF0aW9uLCByb3RhdGlvbiwgdW5pZm9ybSBzY2FsaW5nKSwgdGhlbiB3ZSBjYW4gYnlwYXNzCisgICAgICAgIC8vIHRoZSBpbnZlcnNlIGJ5IHRyYW5zcG9zaW5nIHRoZSBtYXRyaXguCisgICAgICAgIEdMZmxvYXQgcmVzY2FsZSA9IDEuMGY7CisgICAgICAgIGlmIChyZXNjYWxlTm9ybWFscyA9PSBHTF9SRVNDQUxFX05PUk1BTCkgeworICAgICAgICAgICAgaWYgKCEob3BzICYgfk9QX1VOSUZPUk1fU0NBTEUpKSB7CisgICAgICAgICAgICAgICAgcmVzY2FsZSA9IHJlY2lwcm9jYWxmKG12W0koMCwwKV0pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXNjYWxlID0gcnNxcnRmKAorICAgICAgICAgICAgICAgICAgICAgICAgc3FyZihtdltJKDIsMCldKSArIHNxcmYobXZbSSgyLDEpXSkgKyBzcXJmKG12W0koMiwyKV0pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBHTGZpeGVkKiBjb25zdCB4ID0gbXZ1aS5tYXRyaXgubTsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTwzIDsgaSsrKSB7CisgICAgICAgICAgICB4W0koaSwwKV0gPSBnZ2xGbG9hdFRvRml4ZWQobXZbSSgwLGkpXSAqIHJlc2NhbGUpOworICAgICAgICAgICAgeFtJKGksMSldID0gZ2dsRmxvYXRUb0ZpeGVkKG12W0koMSxpKV0gKiByZXNjYWxlKTsKKyAgICAgICAgICAgIHhbSShpLDIpXSA9IGdnbEZsb2F0VG9GaXhlZChtdltJKDIsaSldICogcmVzY2FsZSk7CisgICAgICAgIH0KKyAgICAgICAgbXZ1aS5waWNrZXIoKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEdMZmxvYXQgclszXVszXTsKKyAgICByWzBdWzBdID0gZGV0MjIobXZbSSgxLDEpXSwgbXZbSSgyLDEpXSwgbXZbSSgxLDIpXSwgbXZbSSgyLDIpXSk7CisgICAgclswXVsxXSA9bmRldDIyKG12W0koMCwxKV0sIG12W0koMiwxKV0sIG12W0koMCwyKV0sIG12W0koMiwyKV0pOworICAgIHJbMF1bMl0gPSBkZXQyMihtdltJKDAsMSldLCBtdltJKDEsMSldLCBtdltJKDAsMildLCBtdltJKDEsMildKTsKKyAgICByWzFdWzBdID1uZGV0MjIobXZbSSgxLDApXSwgbXZbSSgyLDApXSwgbXZbSSgxLDIpXSwgbXZbSSgyLDIpXSk7CisgICAgclsxXVsxXSA9IGRldDIyKG12W0koMCwwKV0sIG12W0koMiwwKV0sIG12W0koMCwyKV0sIG12W0koMiwyKV0pOworICAgIHJbMV1bMl0gPW5kZXQyMihtdltJKDAsMCldLCBtdltJKDEsMCldLCBtdltJKDAsMildLCBtdltJKDEsMildKTsKKyAgICByWzJdWzBdID0gZGV0MjIobXZbSSgxLDApXSwgbXZbSSgyLDApXSwgbXZbSSgxLDEpXSwgbXZbSSgyLDEpXSk7CisgICAgclsyXVsxXSA9bmRldDIyKG12W0koMCwwKV0sIG12W0koMiwwKV0sIG12W0koMCwxKV0sIG12W0koMiwxKV0pOworICAgIHJbMl1bMl0gPSBkZXQyMihtdltJKDAsMCldLCBtdltJKDEsMCldLCBtdltJKDAsMSldLCBtdltJKDEsMSldKTsgICAgICAgIAorCisgICAgR0xmbG9hdCByZGV0OworICAgIGlmIChyZXNjYWxlTm9ybWFscyA9PSBHTF9SRVNDQUxFX05PUk1BTCkgeworICAgICAgICByZGV0ID0gcnNxcnRmKHNxcmYoclswXVsyXSkgKyBzcXJmKHJbMV1bMl0pICsgc3FyZihyWzJdWzJdKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmRldCA9IHJlY2lwcm9jYWxmKCAKKyAgICAgICAgICAgIHJbMF1bMF0qbXZbSSgwLDApXSArIHJbMF1bMV0qbXZbSSgxLDApXSArIHJbMF1bMl0qbXZbSSgyLDApXSk7CisgICAgfQorCisgICAgR0xmaXhlZCogY29uc3QgeCA9IG12dWkubWF0cml4Lm07CisgICAgZm9yIChpbnQgaT0wIDsgaTwzIDsgaSsrKSB7CisgICAgICAgIHhbSShpLDApXSA9IGdnbEZsb2F0VG9GaXhlZChyW2ldWzBdICogcmRldCk7CisgICAgICAgIHhbSShpLDEpXSA9IGdnbEZsb2F0VG9GaXhlZChyW2ldWzFdICogcmRldCk7CisgICAgICAgIHhbSShpLDIpXSA9IGdnbEZsb2F0VG9GaXhlZChyW2ldWzJdICogcmRldCk7CisgICAgfQorICAgIG12dWkucGlja2VyKCk7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gdHJhbnNmb3JtYXRpb24gYW5kIG1hdHJpY2VzIEFQSQorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgdHJhbnNmb3JtYXRpb24gYW5kIG1hdHJpY2VzIEFQSQorI2VuZGlmCisKK2ludCBvZ2xlc19zdXJmYWNlcG9ydChvZ2xlc19jb250ZXh0X3QqIGMsIEdMaW50IHgsIEdMaW50IHkpCit7CisgICAgYy0+dmlld3BvcnQuc3VyZmFjZXBvcnQueCA9IHg7CisgICAgYy0+dmlld3BvcnQuc3VyZmFjZXBvcnQueSA9IHk7CisKKyAgICBvZ2xlc192aWV3cG9ydChjLCAKKyAgICAgICAgICAgIGMtPnZpZXdwb3J0LngsCisgICAgICAgICAgICBjLT52aWV3cG9ydC55LAorICAgICAgICAgICAgYy0+dmlld3BvcnQudywKKyAgICAgICAgICAgIGMtPnZpZXdwb3J0LmgpOworCisgICAgb2dsZXNfc2Npc3NvcihjLAorICAgICAgICAgICAgYy0+dmlld3BvcnQuc2Npc3Nvci54LAorICAgICAgICAgICAgYy0+dmlld3BvcnQuc2Npc3Nvci55LAorICAgICAgICAgICAgYy0+dmlld3BvcnQuc2Npc3Nvci53LAorICAgICAgICAgICAgYy0+dmlld3BvcnQuc2Npc3Nvci5oKTsKKworICAgIHJldHVybiAwOworfQorCit2b2lkIG9nbGVzX3NjaXNzb3Iob2dsZXNfY29udGV4dF90KiBjLCAKKyAgICAgICAgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3LCBHTHNpemVpIGgpCit7CisgICAgaWYgKCh3fGgpIDwgMCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT52aWV3cG9ydC5zY2lzc29yLnggPSB4OworICAgIGMtPnZpZXdwb3J0LnNjaXNzb3IueSA9IHk7CisgICAgYy0+dmlld3BvcnQuc2Npc3Nvci53ID0gdzsKKyAgICBjLT52aWV3cG9ydC5zY2lzc29yLmggPSBoOworICAgIAorICAgIHggKz0gYy0+dmlld3BvcnQuc3VyZmFjZXBvcnQueDsKKyAgICB5ICs9IGMtPnZpZXdwb3J0LnN1cmZhY2Vwb3J0Lnk7CisKKyAgICB5ID0gYy0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmNvbG9yLmhlaWdodCAtICh5ICsgaCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5zY2lzc29yKGMsIHgsIHksIHcsIGgpOworfQorCit2b2lkIG9nbGVzX3ZpZXdwb3J0KG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3LCBHTHNpemVpIGgpCit7CisgICAgaWYgKCh3fGgpPDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBjLT52aWV3cG9ydC54ID0geDsKKyAgICBjLT52aWV3cG9ydC55ID0geTsKKyAgICBjLT52aWV3cG9ydC53ID0gdzsKKyAgICBjLT52aWV3cG9ydC5oID0gaDsKKworICAgIHggKz0gYy0+dmlld3BvcnQuc3VyZmFjZXBvcnQueDsKKyAgICB5ICs9IGMtPnZpZXdwb3J0LnN1cmZhY2Vwb3J0Lnk7CisKKyAgICBHTGludCBIID0gYy0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmNvbG9yLmhlaWdodDsKKyAgICBHTGZsb2F0IHN4ID0gZGl2MmYodyk7CisgICAgR0xmbG9hdCBveCA9IHN4ICsgeDsKKyAgICBHTGZsb2F0IHN5ID0gZGl2MmYoaCk7CisgICAgR0xmbG9hdCBveSA9IHN5IC0geSArIChIIC0gaCk7CisKKyAgICBHTGZsb2F0IG5lYXIgPSBjLT50cmFuc2Zvcm1zLnZwdC56TmVhcjsKKyAgICBHTGZsb2F0IGZhciAgPSBjLT50cmFuc2Zvcm1zLnZwdC56RmFyOworICAgIEdMZmxvYXQgQSA9IGRpdjJmKGZhciAtIG5lYXIpOworICAgIEdMZmxvYXQgQiA9IGRpdjJmKGZhciArIG5lYXIpOworCisgICAgLy8gY29tcHV0ZSB2aWV3cG9ydCBtYXRyaXgKKyAgICBHTGZsb2F0KiBjb25zdCBmID0gYy0+dHJhbnNmb3Jtcy52cHQubWF0cml4LmVkaXRFbGVtZW50cygpOworICAgIGZbMF0gPSBzeDsgIGZbNF0gPSAwOyAgIGZbIDhdID0gMDsgIGZbMTJdID0gb3g7CisgICAgZlsxXSA9IDA7ICAgZls1XSA9LXN5OyAgZlsgOV0gPSAwOyAgZlsxM10gPSBveTsKKyAgICBmWzJdID0gMDsgICBmWzZdID0gMDsgICBmWzEwXSA9IEE7ICBmWzE0XSA9IEI7CisgICAgZlszXSA9IDA7ICAgZls3XSA9IDA7ICAgZlsxMV0gPSAwOyAgZlsxNV0gPSAxOworICAgIGMtPnRyYW5zZm9ybXMuZGlydHkgfD0gdHJhbnNmb3JtX3N0YXRlX3Q6OlZJRVdQT1JUOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBtYXRyaXggKiB2ZXJ0ZXgKKyNlbmRpZgorCit2b2lkIHBvaW50Ml9fZ2VuZXJpYyh0cmFuc2Zvcm1fdCBjb25zdCogbXgsIHZlYzRfdCogbGhzLCB2ZWM0X3QgY29uc3QqIHJocykgeworICAgIGNvbnN0IEdMZml4ZWQqIGNvbnN0IG0gPSBteC0+bWF0cml4Lm07CisgICAgY29uc3QgR0xmaXhlZCByeCA9IHJocy0+eDsKKyAgICBjb25zdCBHTGZpeGVkIHJ5ID0gcmhzLT55OworICAgIGxocy0+eCA9IG1sYTJhKHJ4LCBtWyAwXSwgcnksIG1bIDRdLCBtWzEyXSk7IAorICAgIGxocy0+eSA9IG1sYTJhKHJ4LCBtWyAxXSwgcnksIG1bIDVdLCBtWzEzXSk7CisgICAgbGhzLT56ID0gbWxhMmEocngsIG1bIDJdLCByeSwgbVsgNl0sIG1bMTRdKTsKKyAgICBsaHMtPncgPSBtbGEyYShyeCwgbVsgM10sIHJ5LCBtWyA3XSwgbVsxNV0pOworfQorCit2b2lkIHBvaW50M19fZ2VuZXJpYyh0cmFuc2Zvcm1fdCBjb25zdCogbXgsIHZlYzRfdCogbGhzLCB2ZWM0X3QgY29uc3QqIHJocykgeworICAgIGNvbnN0IEdMZml4ZWQqIGNvbnN0IG0gPSBteC0+bWF0cml4Lm07CisgICAgY29uc3QgR0xmaXhlZCByeCA9IHJocy0+eDsKKyAgICBjb25zdCBHTGZpeGVkIHJ5ID0gcmhzLT55OworICAgIGNvbnN0IEdMZml4ZWQgcnogPSByaHMtPno7CisgICAgbGhzLT54ID0gbWxhM2EocngsIG1bIDBdLCByeSwgbVsgNF0sIHJ6LCBtWyA4XSwgbVsxMl0pOyAKKyAgICBsaHMtPnkgPSBtbGEzYShyeCwgbVsgMV0sIHJ5LCBtWyA1XSwgcnosIG1bIDldLCBtWzEzXSk7CisgICAgbGhzLT56ID0gbWxhM2EocngsIG1bIDJdLCByeSwgbVsgNl0sIHJ6LCBtWzEwXSwgbVsxNF0pOworICAgIGxocy0+dyA9IG1sYTNhKHJ4LCBtWyAzXSwgcnksIG1bIDddLCByeiwgbVsxMV0sIG1bMTVdKTsKK30KKwordm9pZCBwb2ludDRfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqIG14LCB2ZWM0X3QqIGxocywgdmVjNF90IGNvbnN0KiByaHMpIHsKKyAgICBjb25zdCBHTGZpeGVkKiBjb25zdCBtID0gbXgtPm1hdHJpeC5tOworICAgIGNvbnN0IEdMZml4ZWQgcnggPSByaHMtPng7CisgICAgY29uc3QgR0xmaXhlZCByeSA9IHJocy0+eTsKKyAgICBjb25zdCBHTGZpeGVkIHJ6ID0gcmhzLT56OworICAgIGNvbnN0IEdMZml4ZWQgcncgPSByaHMtPnc7CisgICAgbGhzLT54ID0gbWxhNChyeCwgbVsgMF0sIHJ5LCBtWyA0XSwgcnosIG1bIDhdLCBydywgbVsxMl0pOyAKKyAgICBsaHMtPnkgPSBtbGE0KHJ4LCBtWyAxXSwgcnksIG1bIDVdLCByeiwgbVsgOV0sIHJ3LCBtWzEzXSk7CisgICAgbGhzLT56ID0gbWxhNChyeCwgbVsgMl0sIHJ5LCBtWyA2XSwgcnosIG1bMTBdLCBydywgbVsxNF0pOworICAgIGxocy0+dyA9IG1sYTQocngsIG1bIDNdLCByeSwgbVsgN10sIHJ6LCBtWzExXSwgcncsIG1bMTVdKTsKK30KKwordm9pZCBub3JtYWxfX2dlbmVyaWModHJhbnNmb3JtX3QgY29uc3QqIG14LCB2ZWM0X3QqIGxocywgdmVjNF90IGNvbnN0KiByaHMpIHsKKyAgICBjb25zdCBHTGZpeGVkKiBjb25zdCBtID0gbXgtPm1hdHJpeC5tOworICAgIGNvbnN0IEdMZml4ZWQgcnggPSByaHMtPng7CisgICAgY29uc3QgR0xmaXhlZCByeSA9IHJocy0+eTsKKyAgICBjb25zdCBHTGZpeGVkIHJ6ID0gcmhzLT56OworICAgIGxocy0+eCA9IG1sYTMocngsIG1bIDBdLCByeSwgbVsgNF0sIHJ6LCBtWyA4XSk7IAorICAgIGxocy0+eSA9IG1sYTMocngsIG1bIDFdLCByeSwgbVsgNV0sIHJ6LCBtWyA5XSk7CisgICAgbGhzLT56ID0gbWxhMyhyeCwgbVsgMl0sIHJ5LCBtWyA2XSwgcnosIG1bMTBdKTsKK30KKworCit2b2lkIHBvaW50Ml9fbm9wKHRyYW5zZm9ybV90IGNvbnN0KiwgdmVjNF90KiBsaHMsIHZlYzRfdCBjb25zdCogcmhzKSB7CisgICAgbGhzLT56ID0gMDsKKyAgICBsaHMtPncgPSAweDEwMDAwOworICAgIGlmIChsaHMgIT0gcmhzKSB7CisgICAgICAgIGxocy0+eCA9IHJocy0+eDsKKyAgICAgICAgbGhzLT55ID0gcmhzLT55OworICAgIH0KK30KKwordm9pZCBwb2ludDNfX25vcCh0cmFuc2Zvcm1fdCBjb25zdCosIHZlYzRfdCogbGhzLCB2ZWM0X3QgY29uc3QqIHJocykgeworICAgIGxocy0+dyA9IDB4MTAwMDA7CisgICAgaWYgKGxocyAhPSByaHMpIHsKKyAgICAgICAgbGhzLT54ID0gcmhzLT54OworICAgICAgICBsaHMtPnkgPSByaHMtPnk7CisgICAgICAgIGxocy0+eiA9IHJocy0+ejsKKyAgICB9Cit9CisKK3ZvaWQgcG9pbnQ0X19ub3AodHJhbnNmb3JtX3QgY29uc3QqLCB2ZWM0X3QqIGxocywgdmVjNF90IGNvbnN0KiByaHMpIHsKKyAgICBpZiAobGhzICE9IHJocykKKyAgICAgICAgKmxocyA9ICpyaHM7Cit9CisKKworc3RhdGljIHZvaWQgZnJ1c3R1bWYoCisgICAgICAgICAgICBHTGZsb2F0IGxlZnQsIEdMZmxvYXQgcmlnaHQsIAorICAgICAgICAgICAgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLAorICAgICAgICAgICAgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyLAorICAgICAgICAgICAgb2dsZXNfY29udGV4dF90KiBjKQorICAgIHsKKyAgICBpZiAoY21wZihsZWZ0LHJpZ2h0KSB8fAorICAgICAgICBjbXBmKHRvcCwgYm90dG9tKSB8fAorICAgICAgICBjbXBmKHpOZWFyLCB6RmFyKSB8fAorICAgICAgICBpc1plcm9Pck5lZ2F0aXZlZih6TmVhcikgfHwKKyAgICAgICAgaXNaZXJvT3JOZWdhdGl2ZWYoekZhcikpCisgICAgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBHTGZsb2F0IHJfd2lkdGggID0gcmVjaXByb2NhbGYocmlnaHQgLSBsZWZ0KTsKKyAgICBjb25zdCBHTGZsb2F0IHJfaGVpZ2h0ID0gcmVjaXByb2NhbGYodG9wIC0gYm90dG9tKTsKKyAgICBjb25zdCBHTGZsb2F0IHJfZGVwdGggID0gcmVjaXByb2NhbGYoek5lYXIgLSB6RmFyKTsKKyAgICBjb25zdCBHTGZsb2F0IHggPSBtdWwyZih6TmVhciAqIHJfd2lkdGgpOworICAgIGNvbnN0IEdMZmxvYXQgeSA9IG11bDJmKHpOZWFyICogcl9oZWlnaHQpOworICAgIGNvbnN0IEdMZmxvYXQgQSA9IG11bDJmKChyaWdodCArIGxlZnQpICogcl93aWR0aCk7CisgICAgY29uc3QgR0xmbG9hdCBCID0gKHRvcCArIGJvdHRvbSkgKiByX2hlaWdodDsKKyAgICBjb25zdCBHTGZsb2F0IEMgPSAoekZhciArIHpOZWFyKSAqIHJfZGVwdGg7CisgICAgY29uc3QgR0xmbG9hdCBEID0gbXVsMmYoekZhciAqIHpOZWFyICogcl9kZXB0aCk7CisgICAgR0xmbG9hdCBmWzE2XTsKKyAgICBmWyAwXSA9IHg7CisgICAgZlsgNV0gPSB5OworICAgIGZbIDhdID0gQTsKKyAgICBmWyA5XSA9IEI7CisgICAgZlsxMF0gPSBDOworICAgIGZbMTRdID0gRDsKKyAgICBmWzExXSA9IC0xLjBmOworICAgIGZbIDFdID0gZlsgMl0gPSBmWyAzXSA9CisgICAgZlsgNF0gPSBmWyA2XSA9IGZbIDddID0KKyAgICBmWzEyXSA9IGZbMTNdID0gZlsxNV0gPSAwLjBmOworCisgICAgbWF0cml4Zl90IHJoczsKKyAgICByaHMuc2V0KGYpOworICAgIGMtPnRyYW5zZm9ybXMuY3VycmVudC0+bXVsdGlwbHkocmhzKTsKKyAgICBjLT50cmFuc2Zvcm1zLmludmFsaWRhdGUoKTsKK30KKworc3RhdGljIHZvaWQgb3J0aG9mKCAKKyAgICAgICAgR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LCAKKyAgICAgICAgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLAorICAgICAgICBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIsCisgICAgICAgIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBpZiAoY21wZihsZWZ0LHJpZ2h0KSB8fAorICAgICAgICBjbXBmKHRvcCwgYm90dG9tKSB8fAorICAgICAgICBjbXBmKHpOZWFyLCB6RmFyKSkKKyAgICB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGNvbnN0IEdMZmxvYXQgcl93aWR0aCAgPSByZWNpcHJvY2FsZihyaWdodCAtIGxlZnQpOworICAgIGNvbnN0IEdMZmxvYXQgcl9oZWlnaHQgPSByZWNpcHJvY2FsZih0b3AgLSBib3R0b20pOworICAgIGNvbnN0IEdMZmxvYXQgcl9kZXB0aCAgPSByZWNpcHJvY2FsZih6RmFyIC0gek5lYXIpOworICAgIGNvbnN0IEdMZmxvYXQgeCA9ICBtdWwyZihyX3dpZHRoKTsKKyAgICBjb25zdCBHTGZsb2F0IHkgPSAgbXVsMmYocl9oZWlnaHQpOworICAgIGNvbnN0IEdMZmxvYXQgeiA9IC1tdWwyZihyX2RlcHRoKTsKKyAgICBjb25zdCBHTGZsb2F0IHR4ID0gLShyaWdodCArIGxlZnQpICogcl93aWR0aDsKKyAgICBjb25zdCBHTGZsb2F0IHR5ID0gLSh0b3AgKyBib3R0b20pICogcl9oZWlnaHQ7CisgICAgY29uc3QgR0xmbG9hdCB0eiA9IC0oekZhciArIHpOZWFyKSAqIHJfZGVwdGg7CisgICAgR0xmbG9hdCBmWzE2XTsKKyAgICBmWyAwXSA9IHg7CisgICAgZlsgNV0gPSB5OworICAgIGZbMTBdID0gejsKKyAgICBmWzEyXSA9IHR4OworICAgIGZbMTNdID0gdHk7CisgICAgZlsxNF0gPSB0ejsKKyAgICBmWzE1XSA9IDEuMGY7CisgICAgZlsgMV0gPSBmWyAyXSA9IGZbIDNdID0KKyAgICBmWyA0XSA9IGZbIDZdID0gZlsgN10gPQorICAgIGZbIDhdID0gZlsgOV0gPSBmWzExXSA9IDAuMGY7CisgICAgbWF0cml4Zl90IHJoczsKKyAgICByaHMuc2V0KGYpOworICAgIGMtPnRyYW5zZm9ybXMuY3VycmVudC0+bXVsdGlwbHkocmhzKTsKKyAgICBjLT50cmFuc2Zvcm1zLmludmFsaWRhdGUoKTsKK30KKworc3RhdGljIHZvaWQgZGVwdGhSYW5nZWYoR0xjbGFtcGYgek5lYXIsIEdMY2xhbXBmIHpGYXIsIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICB6TmVhciA9IGNsYW1wVG9aZXJvZih6TmVhciA+IDEgPyAxIDogek5lYXIpOworICAgIHpGYXIgID0gY2xhbXBUb1plcm9mKHpGYXIgID4gMSA/IDEgOiB6RmFyKTsKKyAgICBHTGZsb2F0KiBjb25zdCBmID0gYy0+dHJhbnNmb3Jtcy52cHQubWF0cml4LmVkaXRFbGVtZW50cygpOworICAgIGZbMTBdID0gZGl2MmYoekZhciAtIHpOZWFyKTsKKyAgICBmWzE0XSA9IGRpdjJmKHpGYXIgKyB6TmVhcik7CisgICAgYy0+dHJhbnNmb3Jtcy5kaXJ0eSB8PSB0cmFuc2Zvcm1fc3RhdGVfdDo6VklFV1BPUlQ7CisgICAgYy0+dHJhbnNmb3Jtcy52cHQuek5lYXIgPSB6TmVhcjsKKyAgICBjLT50cmFuc2Zvcm1zLnZwdC56RmFyICA9IHpGYXI7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKK3ZvaWQgZ2xNYXRyaXhNb2RlKEdMZW51bSBtb2RlKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgbWF0cml4X3N0YWNrX3QqIHN0YWNrID0gMDsKKyAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICBjYXNlIEdMX01PREVMVklFVzoKKyAgICAgICAgc3RhY2sgPSAmYy0+dHJhbnNmb3Jtcy5tb2RlbHZpZXc7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfUFJPSkVDVElPTjoKKyAgICAgICAgc3RhY2sgPSAmYy0+dHJhbnNmb3Jtcy5wcm9qZWN0aW9uOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1RFWFRVUkU6CisgICAgICAgIHN0YWNrID0gJmMtPnRyYW5zZm9ybXMudGV4dHVyZVtjLT50ZXh0dXJlcy5hY3RpdmVdOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPnRyYW5zZm9ybXMubWF0cml4TW9kZSA9IG1vZGU7CisgICAgYy0+dHJhbnNmb3Jtcy5jdXJyZW50ID0gc3RhY2s7Cit9CisKK3ZvaWQgZ2xMb2FkSWRlbnRpdHkoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5sb2FkSWRlbnRpdHkoKTsgLy8gYWxzbyBsb2FkcyB0aGUgR0xmaXhlZCB0cmFuc2Zvcm0KKyAgICBjLT50cmFuc2Zvcm1zLmludmFsaWRhdGUoKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPmRpcnR5ID0gMDsKK30KKwordm9pZCBnbExvYWRNYXRyaXhmKGNvbnN0IEdMZmxvYXQqIG0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPmxvYWQobSk7CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xMb2FkTWF0cml4eChjb25zdCBHTGZpeGVkKiBtKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5sb2FkKG0pOyAvLyBhbHNvIGxvYWRzIHRoZSBHTGZpeGVkIHRyYW5zZm9ybQorICAgIGMtPnRyYW5zZm9ybXMuaW52YWxpZGF0ZSgpOworICAgIGMtPnRyYW5zZm9ybXMuY3VycmVudC0+ZGlydHkgJj0gfm1hdHJpeF9zdGFja190OjpET19GTE9BVF9UT19GSVhFRDsKK30KKwordm9pZCBnbE11bHRNYXRyaXhmKGNvbnN0IEdMZmxvYXQqIG0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBtYXRyaXhmX3QgcmhzOworICAgIHJocy5zZXQobSk7CisgICAgYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5tdWx0aXBseShyaHMpOworICAgIGMtPnRyYW5zZm9ybXMuaW52YWxpZGF0ZSgpOworfQorCit2b2lkIGdsTXVsdE1hdHJpeHgoY29uc3QgR0xmaXhlZCogbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIG1hdHJpeGZfdCByaHM7CisgICAgcmhzLnNldChtKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPm11bHRpcGx5KHJocyk7CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xQb3BNYXRyaXgoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgR0xpbnQgZXJyID0gYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5wb3AoKTsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGVycikpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgZXJyKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT50cmFuc2Zvcm1zLmludmFsaWRhdGUoKTsKK30KKwordm9pZCBnbFB1c2hNYXRyaXgoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgR0xpbnQgZXJyID0gYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5wdXNoKCk7CisgICAgaWYgKGdnbF91bmxpa2VseShlcnIpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIGVycik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xGcnVzdHVtZigKKyAgICAgICAgR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LCAKKyAgICAgICAgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLAorICAgICAgICBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBmcnVzdHVtZihsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIHpOZWFyLCB6RmFyLCBjKTsKK30KKwordm9pZCBnbEZydXN0dW14KCAKKyAgICAgICAgR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LAorICAgICAgICBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsCisgICAgICAgIEdMZml4ZWQgek5lYXIsIEdMZml4ZWQgekZhcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGZydXN0dW1mKCBmaXhlZFRvRmxvYXQobGVmdCksIGZpeGVkVG9GbG9hdChyaWdodCksCisgICAgICAgICAgICAgIGZpeGVkVG9GbG9hdChib3R0b20pLCBmaXhlZFRvRmxvYXQodG9wKSwKKyAgICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KHpOZWFyKSwgZml4ZWRUb0Zsb2F0KHpGYXIpLAorICAgICAgICAgICAgICBjKTsKK30KKwordm9pZCBnbE9ydGhvZiggCisgICAgICAgIEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwgCisgICAgICAgIEdMZmxvYXQgYm90dG9tLCBHTGZsb2F0IHRvcCwKKyAgICAgICAgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgb3J0aG9mKGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgek5lYXIsIHpGYXIsIGMpOworfQorCit2b2lkIGdsT3J0aG94KAorICAgICAgICBHTGZpeGVkIGxlZnQsIEdMZml4ZWQgcmlnaHQsCisgICAgICAgIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwKKyAgICAgICAgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgb3J0aG9mKCBmaXhlZFRvRmxvYXQobGVmdCksIGZpeGVkVG9GbG9hdChyaWdodCksCisgICAgICAgICAgICBmaXhlZFRvRmxvYXQoYm90dG9tKSwgZml4ZWRUb0Zsb2F0KHRvcCksCisgICAgICAgICAgICBmaXhlZFRvRmxvYXQoek5lYXIpLCBmaXhlZFRvRmxvYXQoekZhciksCisgICAgICAgICAgICBjKTsKK30KKwordm9pZCBnbFJvdGF0ZWYoR0xmbG9hdCBhLCBHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+dHJhbnNmb3Jtcy5jdXJyZW50LT5yb3RhdGUoYSwgeCwgeSwgeik7CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xSb3RhdGV4KEdMZml4ZWQgYSwgR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnRyYW5zZm9ybXMuY3VycmVudC0+cm90YXRlKCAKKyAgICAgICAgICAgIGZpeGVkVG9GbG9hdChhKSwgZml4ZWRUb0Zsb2F0KHgpLAorICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KHkpLCBmaXhlZFRvRmxvYXQoeikpOworICAgIGMtPnRyYW5zZm9ybXMuaW52YWxpZGF0ZSgpOworfQorCit2b2lkIGdsU2NhbGVmKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPnNjYWxlKHgsIHksIHopOworICAgIGMtPnRyYW5zZm9ybXMuaW52YWxpZGF0ZSgpOworfQorCit2b2lkIGdsU2NhbGV4KEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPnNjYWxlKAorICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KHgpLCBmaXhlZFRvRmxvYXQoeSksIGZpeGVkVG9GbG9hdCh6KSk7CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xUcmFuc2xhdGVmKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT50cmFuc2Zvcm1zLmN1cnJlbnQtPnRyYW5zbGF0ZSh4LCB5LCB6KTsKKyAgICBjLT50cmFuc2Zvcm1zLmludmFsaWRhdGUoKTsKK30KKwordm9pZCBnbFRyYW5zbGF0ZXgoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnRyYW5zZm9ybXMuY3VycmVudC0+dHJhbnNsYXRlKAorICAgICAgICAgICAgZml4ZWRUb0Zsb2F0KHgpLCBmaXhlZFRvRmxvYXQoeSksIGZpeGVkVG9GbG9hdCh6KSk7CisgICAgYy0+dHJhbnNmb3Jtcy5pbnZhbGlkYXRlKCk7Cit9CisKK3ZvaWQgZ2xTY2lzc29yKEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgdywgR0xzaXplaSBoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgb2dsZXNfc2Npc3NvcihjLCB4LCB5LCB3LCBoKTsKK30KKwordm9pZCBnbFZpZXdwb3J0KEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgdywgR0xzaXplaSBoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgb2dsZXNfdmlld3BvcnQoYywgeCwgeSwgdywgaCk7Cit9CisKK3ZvaWQgZ2xEZXB0aFJhbmdlZihHTGNsYW1wZiB6TmVhciwgR0xjbGFtcGYgekZhcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGRlcHRoUmFuZ2VmKHpOZWFyLCB6RmFyLCBjKTsKK30KKwordm9pZCBnbERlcHRoUmFuZ2V4KEdMY2xhbXB4IHpOZWFyLCBHTGNsYW1weCB6RmFyKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZGVwdGhSYW5nZWYoZml4ZWRUb0Zsb2F0KHpOZWFyKSwgZml4ZWRUb0Zsb2F0KHpGYXIpLCBjKTsKK30KKwordm9pZCBnbFBvbHlnb25PZmZzZXR4KEdMZml4ZWQgZmFjdG9yLCBHTGZpeGVkIHVuaXRzKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+cG9seWdvbk9mZnNldC5mYWN0b3IgPSBmYWN0b3I7CisgICAgYy0+cG9seWdvbk9mZnNldC51bml0cyA9IHVuaXRzOworfQorCit2b2lkIGdsUG9seWdvbk9mZnNldChHTGZsb2F0IGZhY3RvciwgR0xmbG9hdCB1bml0cykKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnBvbHlnb25PZmZzZXQuZmFjdG9yID0gZ2dsRmxvYXRUb0ZpeGVkKGZhY3Rvcik7CisgICAgYy0+cG9seWdvbk9mZnNldC51bml0cyA9IGdnbEZsb2F0VG9GaXhlZCh1bml0cyk7Cit9CisKK0dMYml0ZmllbGQgZ2xRdWVyeU1hdHJpeHhPRVMoR0xmaXhlZCogbSwgR0xpbnQqIGUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBHTGJpdGZpZWxkIHN0YXR1cyA9IDA7CisgICAgR0xmbG9hdCBjb25zdCogZiA9IGMtPnRyYW5zZm9ybXMuY3VycmVudC0+dG9wKCkuZWxlbWVudHMoKTsKKyAgICBmb3IgIChpbnQgaT0wIDsgaTwxNiA7IGkrKykgeworICAgICAgICBpZiAoaXNuYW4oZltpXSkgfHwgaXNpbmYoZltpXSkpIHsKKyAgICAgICAgICAgIHN0YXR1cyB8PSAxPDxpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgZVtpXSA9IGV4cG9uZW50KGZbaV0pIC0gNzsKKyAgICAgICAgbVtpXSA9IG1hbnRpc3NhKGZbaV0pOworICAgIH0KKyAgICByZXR1cm4gc3RhdHVzOworfQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9tYXRyaXguaCBiL29wZW5nbC9saWJhZ2wvbWF0cml4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzlhMzhhOQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvbWF0cml4LmgKQEAgLTAsMCArMSwzNTUgQEAKKy8qIGxpYnMvb3BlbmdsZXMvbWF0cml4LmgKKyoqCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIEFORFJPSURfT1BFTkdMRVNfTUFUUklYX0gKKyNkZWZpbmUgQU5EUk9JRF9PUEVOR0xFU19NQVRSSVhfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dXRpbHMvTG9nLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3BpeGVsZmxpbmdlci9nZ2xfY29udGV4dC5oPgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCituYW1lc3BhY2UgYW5kcm9pZCB7CisKK2NvbnN0IGludCBPR0xFU19NT0RFTFZJRVdfU1RBQ0tfREVQVEggICA9IDE2OworY29uc3QgaW50IE9HTEVTX1BST0pFQ1RJT05fU1RBQ0tfREVQVEggID0gIDI7Citjb25zdCBpbnQgT0dMRVNfVEVYVFVSRV9TVEFDS19ERVBUSCAgICAgPSAgMjsKKwordm9pZCBvZ2xlc19pbml0X21hdHJpeChvZ2xlc19jb250ZXh0X3QqKTsKK3ZvaWQgb2dsZXNfdW5pbml0X21hdHJpeChvZ2xlc19jb250ZXh0X3QqKTsKK3ZvaWQgb2dsZXNfaW52YWxpZGF0ZV9wZXJzcGVjdGl2ZShvZ2xlc19jb250ZXh0X3QqIGMpOwordm9pZCBvZ2xlc192YWxpZGF0ZV90cmFuc2Zvcm1faW1wbChvZ2xlc19jb250ZXh0X3QqIGMsIHVpbnQzMl90IHdhbnQpOworCitpbnQgb2dsZXNfc3VyZmFjZXBvcnQob2dsZXNfY29udGV4dF90KiBjLCBHTGludCB4LCBHTGludCB5KTsKKwordm9pZCBvZ2xlc19zY2lzc29yKG9nbGVzX2NvbnRleHRfdCogYywgCisgICAgICAgIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgdywgR0xzaXplaSBoKTsKKwordm9pZCBvZ2xlc192aWV3cG9ydChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgdywgR0xzaXplaSBoKTsKKworaW5saW5lIHZvaWQgb2dsZXNfdmFsaWRhdGVfdHJhbnNmb3JtKAorICAgICAgICBvZ2xlc19jb250ZXh0X3QqIGMsIHVpbnQzMl90IHdhbnQpCit7CisgICAgaWYgKGMtPnRyYW5zZm9ybXMuZGlydHkgJiB3YW50KQorICAgICAgICBvZ2xlc192YWxpZGF0ZV90cmFuc2Zvcm1faW1wbChjLCB3YW50KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUKK0dMZml4ZWQgdnNxdWFyZTMoR0xmaXhlZCBhLCBHTGZpeGVkIGIsIEdMZml4ZWQgYykgCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisKKyAgICBHTGZpeGVkIHI7CisgICAgaW50MzJfdCB0OworICAgIGFzbSgKKyAgICAgICAgInNtdWxsICUwLCAlMSwgJTIsICUyICAgICAgIFxuIgorICAgICAgICAic21sYWwgJTAsICUxLCAlMywgJTMgICAgICAgXG4iCisgICAgICAgICJzbWxhbCAlMCwgJTEsICU0LCAlNCAgICAgICBcbiIKKyAgICAgICAgIm1vdnMgICUwLCAlMCwgbHNyICMxNiAgICAgIFxuIgorICAgICAgICAiYWRjICAgJTAsICUwLCAlMSwgbHNsICMxNiAgXG4iCisgICAgICAgIDogICAiPSZyIihyKSwgIj0mciIodCkgCisgICAgICAgIDogICAiJXIiKGEpLCAiciIoYiksICJyIihjKQorICAgICAgICA6ICAgImNjIgorICAgICAgICApOyAKKyAgICByZXR1cm4gcjsKKworI2Vsc2UKKworICAgIHJldHVybiAoKCAgIGludDY0X3QoYSkqYSArCisgICAgICAgICAgICAgICAgaW50NjRfdChiKSpiICsKKyAgICAgICAgICAgICAgICBpbnQ2NF90KGMpKmMgKyAweDgwMDApPj4xNik7CisKKyNlbmRpZgorfQorCitzdGF0aWMgaW5saW5lIEdMZml4ZWQgbWxhMmEoIEdMZml4ZWQgYTAsIEdMZml4ZWQgYjAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMSwgR0xmaXhlZCBiMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGMpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgR0xmaXhlZCByOworICAgIGludDMyX3QgdDsKKyAgICBhc20oCisgICAgICAgICJzbXVsbCAlMCwgJTEsICUyLCAlMyAgICAgICBcbiIKKyAgICAgICAgInNtbGFsICUwLCAlMSwgJTQsICU1ICAgICAgIFxuIgorICAgICAgICAiYWRkICAgJTAsICU2LCAlMCwgbHNyICMxNiAgXG4iCisgICAgICAgICJhZGQgICAlMCwgJTAsICUxLCBsc2wgIzE2ICBcbiIKKyAgICAgICAgOiAgICI9JnIiKHIpLCAiPSZyIih0KSAKKyAgICAgICAgOiAgICIlciIoYTApLCAiciIoYjApLCAKKyAgICAgICAgICAgICIlciIoYTEpLCAiciIoYjEpLAorICAgICAgICAgICAgInIiKGMpCisgICAgICAgIDoKKyAgICAgICAgKTsgCisgICAgcmV0dXJuIHI7CisgICAgCisjZWxzZQorCisgICAgcmV0dXJuICgoICAgaW50NjRfdChhMCkqYjAgKworICAgICAgICAgICAgICAgIGludDY0X3QoYTEpKmIxKT4+MTYpICsgYzsKKworI2VuZGlmCit9CisKK3N0YXRpYyBpbmxpbmUgR0xmaXhlZCBtbGEzYSggR0xmaXhlZCBhMCwgR0xmaXhlZCBiMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMSwgR0xmaXhlZCBiMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMiwgR0xmaXhlZCBiMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBjKQoreworI2lmIGRlZmluZWQoX19hcm1fXykgJiYgIWRlZmluZWQoX190aHVtYl9fKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgIEdMZml4ZWQgcjsKKyAgICBpbnQzMl90IHQ7CisgICAgYXNtKAorICAgICAgICAic211bGwgJTAsICUxLCAlMiwgJTMgICAgICAgXG4iCisgICAgICAgICJzbWxhbCAlMCwgJTEsICU0LCAlNSAgICAgICBcbiIKKyAgICAgICAgInNtbGFsICUwLCAlMSwgJTYsICU3ICAgICAgIFxuIgorICAgICAgICAiYWRkICAgJTAsICU4LCAlMCwgbHNyICMxNiAgXG4iCisgICAgICAgICJhZGQgICAlMCwgJTAsICUxLCBsc2wgIzE2ICBcbiIKKyAgICAgICAgOiAgICI9JnIiKHIpLCAiPSZyIih0KSAKKyAgICAgICAgOiAgICIlciIoYTApLCAiciIoYjApLAorICAgICAgICAgICAgIiVyIihhMSksICJyIihiMSksCisgICAgICAgICAgICAiJXIiKGEyKSwgInIiKGIyKSwKKyAgICAgICAgICAgICJyIihjKQorICAgICAgICA6CisgICAgICAgICk7IAorICAgIHJldHVybiByOworICAgIAorI2Vsc2UKKworICAgIHJldHVybiAoKCAgIGludDY0X3QoYTApKmIwICsKKyAgICAgICAgICAgICAgICBpbnQ2NF90KGExKSpiMSArCisgICAgICAgICAgICAgICAgaW50NjRfdChhMikqYjIpPj4xNikgKyBjOworCisjZW5kaWYKK30KKworLy8gYjAsIGIxLCBiMiBhcmUgc2lnbmVkIDE2LWJpdCBxdWFuaXRpZXMKKy8vIHRoYXQgaGF2ZSBiZWVuIHNoaWZ0ZWQgcmlnaHQgYnkgJ3NoaWZ0JyBiaXRzIHJlbGF0aXZlIHRvIG5vcm1hbAorLy8gUzE2LjE2IGZpeGVkIHBvaW50CitzdGF0aWMgaW5saW5lIEdMZml4ZWQgbWxhM2ExNiggR0xmaXhlZCBhMCwgaW50MzJfdCBiMWIwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZml4ZWQgYTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMiwgaW50MzJfdCBiMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGludCBzaGlmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGMpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgR0xmaXhlZCByOworICAgIGFzbSgKKyAgICAgICAgInNtdWx3YiAlMCwgJTEsICUyICAgICAgICAgIFxuIgorICAgICAgICAic21sYXd0ICUwLCAlMywgJTIsICUwICAgICAgXG4iIAorICAgICAgICAic21sYXdiICUwLCAlNCwgJTUsICUwICAgICAgXG4iCisgICAgICAgICJhZGQgICAgJTAsICU3LCAlMCwgbHNsICU2ICBcbiIKKyAgICAgICAgOiAgICI9JnIiKHIpCisgICAgICAgIDogICAiciIoYTApLCAiciIoYjFiMCksCisgICAgICAgICAgICAiciIoYTEpLAorICAgICAgICAgICAgInIiKGEyKSwgInIiKGIyKSwKKyAgICAgICAgICAgICJyIihzaGlmdCksCisgICAgICAgICAgICAiciIoYykKKyAgICAgICAgOgorICAgICAgICApOyAKKyAgICByZXR1cm4gcjsKKyAgICAKKyNlbHNlCisKKyAgICBpbnQzMl90IGFjY3VtOworICAgIGludDE2X3QgYjAgPSBiMWIwICYgMHhmZmZmOworICAgIGludDE2X3QgYjEgPSAoYjFiMCA+PiAxNikgJiAweGZmZmY7CisgICAgYWNjdW0gID0gaW50NjRfdChhMCkqaW50MTZfdChiMCkgPj4gMTY7CisgICAgYWNjdW0gKz0gaW50NjRfdChhMSkqaW50MTZfdChiMSkgPj4gMTY7CisgICAgYWNjdW0gKz0gaW50NjRfdChhMikqaW50MTZfdChiMikgPj4gMTY7CisgICAgYWNjdW0gPSAoYWNjdW0gPDwgc2hpZnQpICsgYzsKKyAgICByZXR1cm4gYWNjdW07CisKKyNlbmRpZgorfQorCisKK3N0YXRpYyBpbmxpbmUgR0xmaXhlZCBtbGEzYTE2X2J0YiggR0xmaXhlZCBhMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBiMWIwLCBpbnQzMl90IHh4YjIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMaW50IHNoaWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGMpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgR0xmaXhlZCByOworICAgIGFzbSgKKyAgICAgICAgInNtdWx3YiAlMCwgJTEsICU0ICAgICAgICAgIFxuIgorICAgICAgICAic21sYXd0ICUwLCAlMiwgJTQsICUwICAgICAgXG4iIAorICAgICAgICAic21sYXdiICUwLCAlMywgJTUsICUwICAgICAgXG4iCisgICAgICAgICJhZGQgICAgJTAsICU3LCAlMCwgbHNsICU2ICBcbiIKKyAgICAgICAgOiAgICI9JnIiKHIpCisgICAgICAgIDogICAiciIoYTApLAorICAgICAgICAgICAgInIiKGExKSwKKyAgICAgICAgICAgICJyIihhMiksCisgICAgICAgICAgICAiciIoYjFiMCksICJyIih4eGIyKSwKKyAgICAgICAgICAgICJyIihzaGlmdCksCisgICAgICAgICAgICAiciIoYykKKyAgICAgICAgOgorICAgICAgICApOyAKKyAgICByZXR1cm4gcjsKKyAgICAKKyNlbHNlCisKKyAgICBpbnQzMl90IGFjY3VtOworICAgIGludDE2X3QgYjAgPSAgYjFiMCAgICAgICAgJiAweGZmZmY7CisgICAgaW50MTZfdCBiMSA9IChiMWIwID4+IDE2KSAmIDB4ZmZmZjsKKyAgICBpbnQxNl90IGIyID0gIHh4YjIgICAgICAgICYgMHhmZmZmOworICAgIGFjY3VtICA9IGludDY0X3QoYTApKmludDE2X3QoYjApID4+IDE2OworICAgIGFjY3VtICs9IGludDY0X3QoYTEpKmludDE2X3QoYjEpID4+IDE2OworICAgIGFjY3VtICs9IGludDY0X3QoYTIpKmludDE2X3QoYjIpID4+IDE2OworICAgIGFjY3VtID0gKGFjY3VtIDw8IHNoaWZ0KSArIGM7CisgICAgcmV0dXJuIGFjY3VtOworCisjZW5kaWYKK30KKworc3RhdGljIGlubGluZSBHTGZpeGVkIG1sYTNhMTZfYnR0KCBHTGZpeGVkIGEwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGExLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGIxYjAsIGludDMyX3QgYjJ4eCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xpbnQgc2hpZnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZml4ZWQgYykKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICBHTGZpeGVkIHI7CisgICAgYXNtKAorICAgICAgICAic211bHdiICUwLCAlMSwgJTQgICAgICAgICAgXG4iCisgICAgICAgICJzbWxhd3QgJTAsICUyLCAlNCwgJTAgICAgICBcbiIgCisgICAgICAgICJzbWxhd3QgJTAsICUzLCAlNSwgJTAgICAgICBcbiIKKyAgICAgICAgImFkZCAgICAlMCwgJTcsICUwLCBsc2wgJTYgIFxuIgorICAgICAgICA6ICAgIj0mciIocikKKyAgICAgICAgOiAgICJyIihhMCksCisgICAgICAgICAgICAiciIoYTEpLAorICAgICAgICAgICAgInIiKGEyKSwKKyAgICAgICAgICAgICJyIihiMWIwKSwgInIiKGIyeHgpLAorICAgICAgICAgICAgInIiKHNoaWZ0KSwKKyAgICAgICAgICAgICJyIihjKQorICAgICAgICA6CisgICAgICAgICk7IAorICAgIHJldHVybiByOworICAgIAorI2Vsc2UKKworICAgIGludDMyX3QgYWNjdW07CisgICAgaW50MTZfdCBiMCA9ICBiMWIwICAgICAgICAmIDB4ZmZmZjsKKyAgICBpbnQxNl90IGIxID0gKGIxYjAgPj4gMTYpICYgMHhmZmZmOworICAgIGludDE2X3QgYjIgPSAoYjJ4eCA+PiAxNikgJiAweGZmZmY7CisgICAgYWNjdW0gID0gaW50NjRfdChhMCkqaW50MTZfdChiMCkgPj4gMTY7CisgICAgYWNjdW0gKz0gaW50NjRfdChhMSkqaW50MTZfdChiMSkgPj4gMTY7CisgICAgYWNjdW0gKz0gaW50NjRfdChhMikqaW50MTZfdChiMikgPj4gMTY7CisgICAgYWNjdW0gPSAoYWNjdW0gPDwgc2hpZnQpICsgYzsKKyAgICByZXR1cm4gYWNjdW07CisKKyNlbmRpZgorfQorCitzdGF0aWMgaW5saW5lIEdMZml4ZWQgbWxhMyggR0xmaXhlZCBhMCwgR0xmaXhlZCBiMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGExLCBHTGZpeGVkIGIxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZml4ZWQgYTIsIEdMZml4ZWQgYjIpCit7CisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgR0xmaXhlZCByOworICAgIGludDMyX3QgdDsKKyAgICBhc20oCisgICAgICAgICJzbXVsbCAlMCwgJTEsICUyLCAlMyAgICAgICBcbiIKKyAgICAgICAgInNtbGFsICUwLCAlMSwgJTQsICU1ICAgICAgIFxuIgorICAgICAgICAic21sYWwgJTAsICUxLCAlNiwgJTcgICAgICAgXG4iCisgICAgICAgICJtb3ZzICAlMCwgJTAsIGxzciAjMTYgICAgICBcbiIKKyAgICAgICAgImFkYyAgICUwLCAlMCwgJTEsIGxzbCAjMTYgIFxuIgorICAgICAgICA6ICAgIj0mciIociksICI9JnIiKHQpIAorICAgICAgICA6ICAgIiVyIihhMCksICJyIihiMCksCisgICAgICAgICAgICAiJXIiKGExKSwgInIiKGIxKSwKKyAgICAgICAgICAgICIlciIoYTIpLCAiciIoYjIpCisgICAgICAgIDogICAiY2MiCisgICAgICAgICk7IAorICAgIHJldHVybiByOworICAgIAorI2Vsc2UKKworICAgIHJldHVybiAoKCAgIGludDY0X3QoYTApKmIwICsKKyAgICAgICAgICAgICAgICBpbnQ2NF90KGExKSpiMSArCisgICAgICAgICAgICAgICAgaW50NjRfdChhMikqYjIgKyAweDgwMDApPj4xNik7CisKKyNlbmRpZgorfQorCitzdGF0aWMgaW5saW5lIEdMZml4ZWQgbWxhNCggR0xmaXhlZCBhMCwgR0xmaXhlZCBiMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGZpeGVkIGExLCBHTGZpeGVkIGIxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZml4ZWQgYTIsIEdMZml4ZWQgYjIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xmaXhlZCBhMywgR0xmaXhlZCBiMykKK3sKKyNpZiBkZWZpbmVkKF9fYXJtX18pICYmICFkZWZpbmVkKF9fdGh1bWJfXykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICBHTGZpeGVkIHI7CisgICAgaW50MzJfdCB0OworICAgIGFzbSgKKyAgICAgICAgInNtdWxsICUwLCAlMSwgJTIsICUzICAgICAgIFxuIgorICAgICAgICAic21sYWwgJTAsICUxLCAlNCwgJTUgICAgICAgXG4iCisgICAgICAgICJzbWxhbCAlMCwgJTEsICU2LCAlNyAgICAgICBcbiIKKyAgICAgICAgInNtbGFsICUwLCAlMSwgJTgsICU5ICAgICAgIFxuIgorICAgICAgICAibW92cyAgJTAsICUwLCBsc3IgIzE2ICAgICAgXG4iCisgICAgICAgICJhZGMgICAlMCwgJTAsICUxLCBsc2wgIzE2ICBcbiIKKyAgICAgICAgOiAgICI9JnIiKHIpLCAiPSZyIih0KSAKKyAgICAgICAgOiAgICIlciIoYTApLCAiciIoYjApLAorICAgICAgICAgICAgIiVyIihhMSksICJyIihiMSksCisgICAgICAgICAgICAiJXIiKGEyKSwgInIiKGIyKSwKKyAgICAgICAgICAgICIlciIoYTMpLCAiciIoYjMpCisgICAgICAgIDogICAiY2MiCisgICAgICAgICk7IAorICAgIHJldHVybiByOworICAgIAorI2Vsc2UKKworICAgIHJldHVybiAoKCAgIGludDY0X3QoYTApKmIwICsKKyAgICAgICAgICAgICAgICBpbnQ2NF90KGExKSpiMSArCisgICAgICAgICAgICAgICAgaW50NjRfdChhMikqYjIgKworICAgICAgICAgICAgICAgIGludDY0X3QoYTMpKmIzICsgMHg4MDAwKT4+MTYpOworCisjZW5kaWYKK30KKworaW5saW5lCitHTGZpeGVkIGRvdDQoY29uc3QgR0xmaXhlZCogYSwgY29uc3QgR0xmaXhlZCogYikgCit7CisgICAgcmV0dXJuIG1sYTQoYVswXSwgYlswXSwgYVsxXSwgYlsxXSwgYVsyXSwgYlsyXSwgYVszXSwgYlszXSk7Cit9CisKKworaW5saW5lCitHTGZpeGVkIGRvdDMoY29uc3QgR0xmaXhlZCogYSwgY29uc3QgR0xmaXhlZCogYikgCit7CisgICAgcmV0dXJuIG1sYTMoYVswXSwgYlswXSwgYVsxXSwgYlsxXSwgYVsyXSwgYlsyXSk7Cit9CisKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfT1BFTkdMRVNfTUFUUklYX0gKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC9taXBtYXAuY3BwIGIvb3BlbmdsL2xpYmFnbC9taXBtYXAuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjZDc3YjcKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL21pcG1hcC5jcHAKQEAgLTAsMCArMSwxOTIgQEAKKy8qIGxpYnMvb3BlbmdsZXMvbWlwbWFwLmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorCisjaW5jbHVkZSAiY29udGV4dC5oIgorI2luY2x1ZGUgInN0YXRlLmgiCisjaW5jbHVkZSAidGV4dHVyZS5oIgorI2luY2x1ZGUgIlRleHR1cmVPYmplY3RNYW5hZ2VyLmgiCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdGF0dXNfdCBidWlsZEFQeXJhbWlkKG9nbGVzX2NvbnRleHRfdCogYywgRUdMVGV4dHVyZU9iamVjdCogdGV4KQoreworICAgIGludCBsZXZlbCA9IDA7CisgICAgY29uc3QgR0dMU3VyZmFjZSogYmFzZSA9ICZ0ZXgtPnN1cmZhY2U7ICAgIAorICAgIGNvbnN0IEdHTEZvcm1hdCYgcGl4ZWxGb3JtYXQoYy0+cmFzdGVyaXplci5mb3JtYXRzW2Jhc2UtPmZvcm1hdF0pOworCisgICAgaW50IHcgPSBiYXNlLT53aWR0aDsKKyAgICBpbnQgaCA9IGJhc2UtPmhlaWdodDsKKyAgICBpZiAoKHcmaCkgPT0gMSkKKyAgICAgICAgcmV0dXJuIE5PX0VSUk9SOworCisgICAgdyA9ICh3Pj4xKSA/IDogMTsKKyAgICBoID0gKGg+PjEpID8gOiAxOworCisgICAgd2hpbGUodHJ1ZSkgeworICAgICAgICArK2xldmVsOworICAgICAgICBjb25zdCBpbnQgYnByID0gdyAqIHBpeGVsRm9ybWF0LnNpemU7CisgICAgICAgIGlmICh0ZXgtPnJlYWxsb2NhdGUobGV2ZWwsIHcsIGgsIHcsCisgICAgICAgICAgICAgICAgYmFzZS0+Zm9ybWF0LCBiYXNlLT5jb21wcmVzc2VkRm9ybWF0LCBicHIpICE9IE5PX0VSUk9SKSB7CisgICAgICAgICAgICByZXR1cm4gTk9fTUVNT1JZOworICAgICAgICB9CisgICAgCisgICAgICAgIGludCBzdHJpZGUgPSB3OworICAgICAgICBpbnQgYnMgPSBiYXNlLT5zdHJpZGU7CisgICAgICAgIEdHTFN1cmZhY2UmIGN1ciA9IHRleC0+ZWRpdE1pcChsZXZlbCk7CisKKyAgICAgICAgaWYgKGJhc2UtPmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1JHQl81NjUpCisgICAgICAgIHsKKyAgICAgICAgICAgIHVpbnQxNl90IGNvbnN0ICogc3JjID0gKHVpbnQxNl90IGNvbnN0ICopYmFzZS0+ZGF0YTsKKyAgICAgICAgICAgIHVpbnQxNl90KiBkc3QgPSAodWludDE2X3QqKWN1ci5kYXRhOworICAgICAgICAgICAgY29uc3QgdWludDMyX3QgbWFzayA9IDB4MDdFMEY4MUY7CisgICAgICAgICAgICBmb3IgKGludCB5PTAgOyB5PGggOyB5KyspIHsKKyAgICAgICAgICAgICAgICBzaXplX3Qgb2Zmc2V0ID0gKHkqMikgKiBiczsKKyAgICAgICAgICAgICAgICBmb3IgKGludCB4PTAgOyB4PHcgOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcDAwID0gc3JjW29mZnNldF07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAxMCA9IHNyY1tvZmZzZXQrMV07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAwMSA9IHNyY1tvZmZzZXQrYnNdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMTEgPSBzcmNbb2Zmc2V0K2JzKzFdOworICAgICAgICAgICAgICAgICAgICBwMDAgPSAocDAwIHwgKHAwMCA8PCAxNikpICYgbWFzazsKKyAgICAgICAgICAgICAgICAgICAgcDAxID0gKHAwMSB8IChwMDEgPDwgMTYpKSAmIG1hc2s7CisgICAgICAgICAgICAgICAgICAgIHAxMCA9IChwMTAgfCAocDEwIDw8IDE2KSkgJiBtYXNrOworICAgICAgICAgICAgICAgICAgICBwMTEgPSAocDExIHwgKHAxMSA8PCAxNikpICYgbWFzazsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZ3JiID0gKChwMDAgKyBwMTAgKyBwMDEgKyBwMTEpID4+IDIpICYgbWFzazsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcmdiID0gKGdyYiAmIDB4RkZGRikgfCAoZ3JiID4+IDE2KTsKKyAgICAgICAgICAgICAgICAgICAgZHN0W3ggKyB5KnN0cmlkZV0gPSByZ2I7CisgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChiYXNlLT5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzU1NTEpCisgICAgICAgIHsKKyAgICAgICAgICAgIHVpbnQxNl90IGNvbnN0ICogc3JjID0gKHVpbnQxNl90IGNvbnN0ICopYmFzZS0+ZGF0YTsKKyAgICAgICAgICAgIHVpbnQxNl90KiBkc3QgPSAodWludDE2X3QqKWN1ci5kYXRhOworICAgICAgICAgICAgZm9yIChpbnQgeT0wIDsgeTxoIDsgeSsrKSB7CisgICAgICAgICAgICAgICAgc2l6ZV90IG9mZnNldCA9ICh5KjIpICogYnM7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeD0wIDsgeDx3IDsgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAwMCA9IHNyY1tvZmZzZXRdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMTAgPSBzcmNbb2Zmc2V0KzFdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMDEgPSBzcmNbb2Zmc2V0K2JzXTsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcDExID0gc3JjW29mZnNldCticysxXTsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgciA9ICgocDAwPj4xMSkrKHAxMD4+MTEpKyhwMDE+PjExKSsocDExPj4xMSkrMik+PjI7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGcgPSAoKChwMDA+PjYpKyhwMTA+PjYpKyhwMDE+PjYpKyhwMTE+PjYpKzIpPj4yKSYweDNGOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBiID0gKChwMDAmMHgzRSkrKHAxMCYweDNFKSsocDAxJjB4M0UpKyhwMTEmMHgzRSkrNCk+PjM7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGEgPSAoKHAwMCYxKSsocDEwJjEpKyhwMDEmMSkrKHAxMSYxKSsyKT4+MjsKKyAgICAgICAgICAgICAgICAgICAgZHN0W3ggKyB5KnN0cmlkZV0gPSAocjw8MTEpfChnPDw2KXwoYjw8MSl8YTsKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGJhc2UtPmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1JHQkFfODg4OCkKKyAgICAgICAgeworICAgICAgICAgICAgdWludDMyX3QgY29uc3QgKiBzcmMgPSAodWludDMyX3QgY29uc3QgKiliYXNlLT5kYXRhOworICAgICAgICAgICAgdWludDMyX3QqIGRzdCA9ICh1aW50MzJfdCopY3VyLmRhdGE7CisgICAgICAgICAgICBmb3IgKGludCB5PTAgOyB5PGggOyB5KyspIHsKKyAgICAgICAgICAgICAgICBzaXplX3Qgb2Zmc2V0ID0gKHkqMikgKiBiczsKKyAgICAgICAgICAgICAgICBmb3IgKGludCB4PTAgOyB4PHcgOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcDAwID0gc3JjW29mZnNldF07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAxMCA9IHNyY1tvZmZzZXQrMV07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAwMSA9IHNyY1tvZmZzZXQrYnNdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMTEgPSBzcmNbb2Zmc2V0K2JzKzFdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByYjAwID0gcDAwICYgMHgwMEZGMDBGRjsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcmIwMSA9IHAwMSAmIDB4MDBGRjAwRkY7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHJiMTAgPSBwMTAgJiAweDAwRkYwMEZGOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByYjExID0gcDExICYgMHgwMEZGMDBGRjsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZ2EwMCA9IChwMDAgPj4gOCkgJiAweDAwRkYwMEZGOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBnYTAxID0gKHAwMSA+PiA4KSAmIDB4MDBGRjAwRkY7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGdhMTAgPSAocDEwID4+IDgpICYgMHgwMEZGMDBGRjsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZ2ExMSA9IChwMTEgPj4gOCkgJiAweDAwRkYwMEZGOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByYiA9IChyYjAwICsgcmIwMSArIHJiMTAgKyByYjExKT4+MjsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgZ2EgPSAoZ2EwMCArIGdhMDEgKyBnYTEwICsgZ2ExMSk+PjI7CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHJnYmEgPSAocmIgJiAweDAwRkYwMEZGKSB8ICgoZ2EgJiAweDAwRkYwMEZGKTw8OCk7CisgICAgICAgICAgICAgICAgICAgIGRzdFt4ICsgeSpzdHJpZGVdID0gcmdiYTsKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKChiYXNlLT5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfODg4KSB8fAorICAgICAgICAgICAgICAgICAoYmFzZS0+Zm9ybWF0ID09IEdHTF9QSVhFTF9GT1JNQVRfTEFfODgpIHx8CisgICAgICAgICAgICAgICAgIChiYXNlLT5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9BXzgpIHx8CisgICAgICAgICAgICAgICAgIChiYXNlLT5mb3JtYXQgPT0gR0dMX1BJWEVMX0ZPUk1BVF9MXzgpKQorICAgICAgICB7CisgICAgICAgICAgICBpbnQgc2tpcDsKKyAgICAgICAgICAgIHN3aXRjaCAoYmFzZS0+Zm9ybWF0KSB7CisgICAgICAgICAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCXzg4ODogIHNraXAgPSAzOyAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBHR0xfUElYRUxfRk9STUFUX0xBXzg4OiAgICBza2lwID0gMjsgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDE7ICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1aW50OF90IGNvbnN0ICogc3JjID0gKHVpbnQ4X3QgY29uc3QgKiliYXNlLT5kYXRhOworICAgICAgICAgICAgdWludDhfdCogZHN0ID0gKHVpbnQ4X3QqKWN1ci5kYXRhOyAgICAgICAgICAgIAorICAgICAgICAgICAgYnMgKj0gc2tpcDsKKyAgICAgICAgICAgIHN0cmlkZSAqPSBza2lwOworICAgICAgICAgICAgZm9yIChpbnQgeT0wIDsgeTxoIDsgeSsrKSB7CisgICAgICAgICAgICAgICAgc2l6ZV90IG9mZnNldCA9ICh5KjIpICogYnM7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeD0wIDsgeDx3IDsgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGM9MCA7IGM8c2tpcCA7IGMrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcDAwID0gc3JjW2Mrb2Zmc2V0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAxMCA9IHNyY1tjK29mZnNldCtza2lwXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAwMSA9IHNyY1tjK29mZnNldCtic107CisgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMTEgPSBzcmNbYytvZmZzZXQrYnMrc2tpcF07CisgICAgICAgICAgICAgICAgICAgICAgICBkc3RbeCArIHkqc3RyaWRlICsgY10gPSAocDAwICsgcDEwICsgcDAxICsgcDExKSA+PiAyOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAyKnNraXA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGJhc2UtPmZvcm1hdCA9PSBHR0xfUElYRUxfRk9STUFUX1JHQkFfNDQ0NCkKKyAgICAgICAgeworICAgICAgICAgICAgdWludDE2X3QgY29uc3QgKiBzcmMgPSAodWludDE2X3QgY29uc3QgKiliYXNlLT5kYXRhOworICAgICAgICAgICAgdWludDE2X3QqIGRzdCA9ICh1aW50MTZfdCopY3VyLmRhdGE7CisgICAgICAgICAgICBmb3IgKGludCB5PTAgOyB5PGggOyB5KyspIHsKKyAgICAgICAgICAgICAgICBzaXplX3Qgb2Zmc2V0ID0gKHkqMikgKiBiczsKKyAgICAgICAgICAgICAgICBmb3IgKGludCB4PTAgOyB4PHcgOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcDAwID0gc3JjW29mZnNldF07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAxMCA9IHNyY1tvZmZzZXQrMV07CisgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHAwMSA9IHNyY1tvZmZzZXQrYnNdOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBwMTEgPSBzcmNbb2Zmc2V0K2JzKzFdOworICAgICAgICAgICAgICAgICAgICBwMDAgPSAoKHAwMCA8PCAxMikgJiAweDBGMEYwMDAwKSB8IChwMDAgJiAweDBGMEYpOworICAgICAgICAgICAgICAgICAgICBwMTAgPSAoKHAxMCA8PCAxMikgJiAweDBGMEYwMDAwKSB8IChwMTAgJiAweDBGMEYpOworICAgICAgICAgICAgICAgICAgICBwMDEgPSAoKHAwMSA8PCAxMikgJiAweDBGMEYwMDAwKSB8IChwMDEgJiAweDBGMEYpOworICAgICAgICAgICAgICAgICAgICBwMTEgPSAoKHAxMSA8PCAxMikgJiAweDBGMEYwMDAwKSB8IChwMTEgJiAweDBGMEYpOworICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByYmdhID0gKHAwMCArIHAxMCArIHAwMSArIHAxMSkgPj4gMjsKKyAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgcmdiYSA9IChyYmdhICYgMHgwRjBGKSB8ICgocmJnYT4+MTIpICYgMHhGMEYwKTsKKyAgICAgICAgICAgICAgICAgICAgZHN0W3ggKyB5KnN0cmlkZV0gPSByZ2JhOworICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJVbnN1cHBvcnRlZCBmb3JtYXQgKCVkKSIsIGJhc2UtPmZvcm1hdCk7CisgICAgICAgICAgICByZXR1cm4gQkFEX1RZUEU7CisgICAgICAgIH0KKworICAgICAgICAvLyBleGl0IGNvbmRpdGlvbjogd2UganVzdCBwcm9jZXNzZWQgdGhlIDF4MSBMT0RzCisgICAgICAgIGlmICgodyZoKSA9PSAxKQorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgYmFzZSA9ICZjdXI7CisgICAgICAgIHcgPSAodz4+MSkgPyA6IDE7CisgICAgICAgIGggPSAoaD4+MSkgPyA6IDE7CisgICAgfQorICAgIHJldHVybiBOT19FUlJPUjsKK30KKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvcHJpbWl0aXZlcy5jcHAgYi9vcGVuZ2wvbGliYWdsL3ByaW1pdGl2ZXMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNjRjMDIKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL3ByaW1pdGl2ZXMuY3BwCkBAIC0wLDAgKzEsMTExMSBAQAorLyogbGlicy9vcGVuZ2xlcy9wcmltaXRpdmVzLmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPG1hdGguaD4KKworI2luY2x1ZGUgImNvbnRleHQuaCIKKyNpbmNsdWRlICJwcmltaXRpdmVzLmgiCisjaW5jbHVkZSAibGlnaHQuaCIKKyNpbmNsdWRlICJtYXRyaXguaCIKKyNpbmNsdWRlICJ2ZXJ0ZXguaCIKKyNpbmNsdWRlICJmcC5oIgorI2luY2x1ZGUgIlRleHR1cmVPYmplY3RNYW5hZ2VyLmgiCisKK2V4dGVybiAiQyIgdm9pZCBpdGVyYXRvcnMwMDMyKGNvbnN0IHZvaWQqIHRoYXQsCisgICAgICAgIGludDMyX3QqIGl0LCBpbnQzMl90IGMwLCBpbnQzMl90IGMxLCBpbnQzMl90IGMyKTsKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyB2b2lkIHByaW1pdGl2ZV9wb2ludChvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KTsKK3N0YXRpYyB2b2lkIHByaW1pdGl2ZV9saW5lKG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEpOworc3RhdGljIHZvaWQgcHJpbWl0aXZlX2NsaXBfdHJpYW5nbGUob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdjAsIHZlcnRleF90KiB2MSwgdmVydGV4X3QqIHYyKTsKKworc3RhdGljIHZvaWQgcHJpbWl0aXZlX25vcF9wb2ludChvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KTsKK3N0YXRpYyB2b2lkIHByaW1pdGl2ZV9ub3BfbGluZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxKTsKK3N0YXRpYyB2b2lkIHByaW1pdGl2ZV9ub3BfdHJpYW5nbGUob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdjAsIHZlcnRleF90KiB2MSwgdmVydGV4X3QqIHYyKTsKKworc3RhdGljIGlubGluZSBib29sIGN1bGxfdHJpYW5nbGUob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdjAsIHZlcnRleF90KiB2MSwgdmVydGV4X3QqIHYyKTsKKworc3RhdGljIHZvaWQgbGVycF90cmlhbmdsZShvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpOworCitzdGF0aWMgdm9pZCBsZXJwX3RleGNvb3JkcyhvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpOworCitzdGF0aWMgdm9pZCBsZXJwX3RleGNvb3Jkc193KG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2Mik7CisKK3N0YXRpYyB2b2lkIHRyaWFuZ2xlKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2Mik7CisKK3N0YXRpYyB2b2lkIGNsaXBfdHJpYW5nbGUob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdjAsIHZlcnRleF90KiB2MSwgdmVydGV4X3QqIHYyKTsKKworc3RhdGljIHVuc2lnbmVkIGludCBjbGlwX2xpbmUob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogcywgdmVydGV4X3QqIHApOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCitzdGF0aWMgdm9pZCBsaWdodFRyaWFuZ2xlRGFya1Ntb290aChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgaWYgKCEodjAtPmZsYWdzICYgdmVydGV4X3Q6OkxJVCkpIHsKKyAgICAgICAgdjAtPmZsYWdzIHw9IHZlcnRleF90OjpMSVQ7CisgICAgICAgIGNvbnN0IEdMdm9pZCogY3AgPSBjLT5hcnJheXMuY29sb3IuZWxlbWVudCgKKyAgICAgICAgICAgICAgICB2MC0+aW5kZXggJiB2ZXJ0ZXhfY2FjaGVfdDo6SU5ERVhfTUFTSyk7CisgICAgICAgIGMtPmFycmF5cy5jb2xvci5mZXRjaChjLCB2MC0+Y29sb3IudiwgY3ApOworICAgIH0KKyAgICBpZiAoISh2MS0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6TElUKSkgeworICAgICAgICB2MS0+ZmxhZ3MgfD0gdmVydGV4X3Q6OkxJVDsKKyAgICAgICAgY29uc3QgR0x2b2lkKiBjcCA9IGMtPmFycmF5cy5jb2xvci5lbGVtZW50KAorICAgICAgICAgICAgICAgIHYxLT5pbmRleCAmIHZlcnRleF9jYWNoZV90OjpJTkRFWF9NQVNLKTsKKyAgICAgICAgYy0+YXJyYXlzLmNvbG9yLmZldGNoKGMsIHYxLT5jb2xvci52LCBjcCk7CisgICAgfQorICAgIGlmKCEodjItPmZsYWdzICYgdmVydGV4X3Q6OkxJVCkpIHsKKyAgICAgICAgdjItPmZsYWdzIHw9IHZlcnRleF90OjpMSVQ7CisgICAgICAgIGNvbnN0IEdMdm9pZCogY3AgPSBjLT5hcnJheXMuY29sb3IuZWxlbWVudCgKKyAgICAgICAgICAgICAgICB2Mi0+aW5kZXggJiB2ZXJ0ZXhfY2FjaGVfdDo6SU5ERVhfTUFTSyk7CisgICAgICAgIGMtPmFycmF5cy5jb2xvci5mZXRjaChjLCB2Mi0+Y29sb3IudiwgY3ApOworICAgIH0KK30KKworc3RhdGljIHZvaWQgbGlnaHRUcmlhbmdsZURhcmtGbGF0KG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBpZiAoISh2Mi0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6TElUKSkgeworICAgICAgICB2Mi0+ZmxhZ3MgfD0gdmVydGV4X3Q6OkxJVDsKKyAgICAgICAgY29uc3QgR0x2b2lkKiBjcCA9IGMtPmFycmF5cy5jb2xvci5lbGVtZW50KAorICAgICAgICAgICAgICAgIHYyLT5pbmRleCAmIHZlcnRleF9jYWNoZV90OjpJTkRFWF9NQVNLKTsKKyAgICAgICAgYy0+YXJyYXlzLmNvbG9yLmZldGNoKGMsIHYyLT5jb2xvci52LCBjcCk7CisgICAgfQorICAgIC8vIGNvbmZpZ3VyZSB0aGUgcmFzdGVyaXplciBoZXJlLCBiZWZvcmUgd2UgY2xpcAorICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuY29sb3I0eHYoYywgdjItPmNvbG9yLnYpOworfQorCitzdGF0aWMgdm9pZCBsaWdodFRyaWFuZ2xlU21vb3RoKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBpZiAoISh2MC0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6TElUKSkKKyAgICAgICAgYy0+bGlnaHRpbmcubGlnaHRWZXJ0ZXgoYywgdjApOworICAgIGlmICghKHYxLT5mbGFncyAmIHZlcnRleF90OjpMSVQpKQorICAgICAgICBjLT5saWdodGluZy5saWdodFZlcnRleChjLCB2MSk7CisgICAgaWYoISh2Mi0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6TElUKSkKKyAgICAgICAgYy0+bGlnaHRpbmcubGlnaHRWZXJ0ZXgoYywgdjIpOworfQorCitzdGF0aWMgdm9pZCBsaWdodFRyaWFuZ2xlRmxhdChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgaWYgKCEodjItPmZsYWdzICYgdmVydGV4X3Q6OkxJVCkpCisgICAgICAgIGMtPmxpZ2h0aW5nLmxpZ2h0VmVydGV4KGMsIHYyKTsKKyAgICAvLyBjb25maWd1cmUgdGhlIHJhc3Rlcml6ZXIgaGVyZSwgYmVmb3JlIHdlIGNsaXAKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNvbG9yNHh2KGMsIHYyLT5jb2xvci52KTsKK30KKworLy8gVGhlIGZvZyB2ZXJzaW9ucy4uLgorCitzdGF0aWMgaW5saW5lCit2b2lkIGxpZ2h0VmVydGV4RGFya1Ntb290aEZvZyhvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2KQoreworICAgIGlmICghKHYtPmZsYWdzICYgdmVydGV4X3Q6OkxJVCkpIHsKKyAgICAgICAgdi0+ZmxhZ3MgfD0gdmVydGV4X3Q6OkxJVDsKKyAgICAgICAgdi0+Zm9nID0gYy0+Zm9nLmZvZyhjLCB2LT5leWUueik7CisgICAgICAgIGNvbnN0IEdMdm9pZCogY3AgPSBjLT5hcnJheXMuY29sb3IuZWxlbWVudCgKKyAgICAgICAgICAgICAgICB2LT5pbmRleCAmIHZlcnRleF9jYWNoZV90OjpJTkRFWF9NQVNLKTsKKyAgICAgICAgYy0+YXJyYXlzLmNvbG9yLmZldGNoKGMsIHYtPmNvbG9yLnYsIGNwKTsKKyAgICB9Cit9CitzdGF0aWMgaW5saW5lCit2b2lkIGxpZ2h0VmVydGV4RGFya0ZsYXRGb2cob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikKK3sKKyAgICBpZiAoISh2LT5mbGFncyAmIHZlcnRleF90OjpMSVQpKSB7CisgICAgICAgIHYtPmZsYWdzIHw9IHZlcnRleF90OjpMSVQ7CisgICAgICAgIHYtPmZvZyA9IGMtPmZvZy5mb2coYywgdi0+ZXllLnopOworICAgIH0KK30KK3N0YXRpYyBpbmxpbmUKK3ZvaWQgbGlnaHRWZXJ0ZXhTbW9vdGhGb2cob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikKK3sKKyAgICBpZiAoISh2LT5mbGFncyAmIHZlcnRleF90OjpMSVQpKSB7CisgICAgICAgIHYtPmZvZyA9IGMtPmZvZy5mb2coYywgdi0+ZXllLnopOworICAgICAgICBjLT5saWdodGluZy5saWdodFZlcnRleChjLCB2KTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIGxpZ2h0VHJpYW5nbGVEYXJrU21vb3RoRm9nKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBsaWdodFZlcnRleERhcmtTbW9vdGhGb2coYywgdjApOworICAgIGxpZ2h0VmVydGV4RGFya1Ntb290aEZvZyhjLCB2MSk7CisgICAgbGlnaHRWZXJ0ZXhEYXJrU21vb3RoRm9nKGMsIHYyKTsKK30KKworc3RhdGljIHZvaWQgbGlnaHRUcmlhbmdsZURhcmtGbGF0Rm9nKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBsaWdodFZlcnRleERhcmtGbGF0Rm9nKGMsIHYwKTsKKyAgICBsaWdodFZlcnRleERhcmtGbGF0Rm9nKGMsIHYxKTsKKyAgICBsaWdodFZlcnRleERhcmtTbW9vdGhGb2coYywgdjIpOworICAgIC8vIGNvbmZpZ3VyZSB0aGUgcmFzdGVyaXplciBoZXJlLCBiZWZvcmUgd2UgY2xpcAorICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuY29sb3I0eHYoYywgdjItPmNvbG9yLnYpOworfQorCitzdGF0aWMgdm9pZCBsaWdodFRyaWFuZ2xlU21vb3RoRm9nKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBsaWdodFZlcnRleFNtb290aEZvZyhjLCB2MCk7CisgICAgbGlnaHRWZXJ0ZXhTbW9vdGhGb2coYywgdjEpOworICAgIGxpZ2h0VmVydGV4U21vb3RoRm9nKGMsIHYyKTsKK30KKworc3RhdGljIHZvaWQgbGlnaHRUcmlhbmdsZUZsYXRGb2cob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICB2ZXJ0ZXhfdCogdjAsIHZlcnRleF90KiB2MSwgdmVydGV4X3QqIHYyKQoreworICAgIGxpZ2h0VmVydGV4RGFya0ZsYXRGb2coYywgdjApOworICAgIGxpZ2h0VmVydGV4RGFya0ZsYXRGb2coYywgdjEpOworICAgIGxpZ2h0VmVydGV4U21vb3RoRm9nKGMsIHYyKTsKKyAgICAvLyBjb25maWd1cmUgdGhlIHJhc3Rlcml6ZXIgaGVyZSwgYmVmb3JlIHdlIGNsaXAKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNvbG9yNHh2KGMsIHYyLT5jb2xvci52KTsKK30KKworCisKK3R5cGVkZWYgdm9pZCAoKmxpZ2h0X3ByaW1pdGl2ZV90KShvZ2xlc19jb250ZXh0X3QqLAorICAgICAgICB2ZXJ0ZXhfdCosIHZlcnRleF90KiwgdmVydGV4X3QqKTsKKworLy8gZm9nIDB4NCwgbGlnaHQgMHgyLCBzbW9vdGggMHgxCitzdGF0aWMgY29uc3QgbGlnaHRfcHJpbWl0aXZlX3QgbGlnaHRQcmltaXRpdmVbOF0gPSB7CisgICAgbGlnaHRUcmlhbmdsZURhcmtGbGF0LCAgICAgICAgICAvLyBubyBmb2cgfCBkYXJrICB8IGZsYXQKKyAgICBsaWdodFRyaWFuZ2xlRGFya1Ntb290aCwgICAgICAgIC8vIG5vIGZvZyB8IGRhcmsgIHwgc21vb3RoCisgICAgbGlnaHRUcmlhbmdsZUZsYXQsICAgICAgICAgICAgICAvLyBubyBmb2cgfCBsaWdodCB8IGZsYXQKKyAgICBsaWdodFRyaWFuZ2xlU21vb3RoLCAgICAgICAgICAgIC8vIG5vIGZvZyB8IGxpZ2h0IHwgc21vb3RoCisgICAgbGlnaHRUcmlhbmdsZURhcmtGbGF0Rm9nLCAgICAgICAvLyBmb2cgICAgfCBkYXJrICB8IGZsYXQKKyAgICBsaWdodFRyaWFuZ2xlRGFya1Ntb290aEZvZywgICAgIC8vIGZvZyAgICB8IGRhcmsgIHwgc21vb3RoCisgICAgbGlnaHRUcmlhbmdsZUZsYXRGb2csICAgICAgICAgICAvLyBmb2cgICAgfCBsaWdodCB8IGZsYXQKKyAgICBsaWdodFRyaWFuZ2xlU21vb3RoRm9nICAgICAgICAgIC8vIGZvZyAgICB8IGxpZ2h0IHwgc21vb3RoCit9OworCit2b2lkIG9nbGVzX3ZhbGlkYXRlX3ByaW1pdGl2ZXMob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGNvbnN0IHVpbnQzMl90IGVuYWJsZXMgPSBjLT5yYXN0ZXJpemVyLnN0YXRlLmVuYWJsZXM7CisKKyAgICAvLyBzZXQgdXAgdGhlIGxpZ2h0aW5nL3NoYWRpbmcvc21vb3RoaW5nL2ZvZ2dpbmcgZnVuY3Rpb24KKyAgICBpbnQgaW5kZXggPSBlbmFibGVzICYgR0dMX0VOQUJMRV9TTU9PVEggPyAweDEgOiAwOworICAgIGluZGV4IHw9IGMtPmxpZ2h0aW5nLmVuYWJsZSA/IDB4MiA6IDA7CisgICAgaW5kZXggfD0gZW5hYmxlcyAmIEdHTF9FTkFCTEVfRk9HID8gMHg0IDogMDsKKyAgICBjLT5saWdodGluZy5saWdodFRyaWFuZ2xlID0gbGlnaHRQcmltaXRpdmVbaW5kZXhdOworICAgIAorICAgIC8vIHNldCB1cCB0aGUgcHJpbWl0aXZlIHJlbmRlcmVycworICAgIGlmIChnZ2xfbGlrZWx5KGMtPmFycmF5cy52ZXJ0ZXguZW5hYmxlKSkgeworICAgICAgICBjLT5wcmltcy5yZW5kZXJQb2ludCAgICA9IHByaW1pdGl2ZV9wb2ludDsKKyAgICAgICAgYy0+cHJpbXMucmVuZGVyTGluZSAgICAgPSBwcmltaXRpdmVfbGluZTsKKyAgICAgICAgYy0+cHJpbXMucmVuZGVyVHJpYW5nbGUgPSBwcmltaXRpdmVfY2xpcF90cmlhbmdsZTsKKyAgICB9IGVsc2UgeworICAgICAgICBjLT5wcmltcy5yZW5kZXJQb2ludCAgICA9IHByaW1pdGl2ZV9ub3BfcG9pbnQ7CisgICAgICAgIGMtPnByaW1zLnJlbmRlckxpbmUgICAgID0gcHJpbWl0aXZlX25vcF9saW5lOworICAgICAgICBjLT5wcmltcy5yZW5kZXJUcmlhbmdsZSA9IHByaW1pdGl2ZV9ub3BfdHJpYW5nbGU7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgY29tcHV0ZV9pdGVyYXRvcnNfdDo6aW5pdFRyaWFuZ2xlKAorICAgICAgICB2ZXJ0ZXhfdCBjb25zdCogdjAsIHZlcnRleF90IGNvbnN0KiB2MSwgdmVydGV4X3QgY29uc3QqIHYyKQoreworICAgIG1fZHgwMSA9IHYxLT53aW5kb3cueCAtIHYwLT53aW5kb3cueDsKKyAgICBtX2R5MTAgPSB2MC0+d2luZG93LnkgLSB2MS0+d2luZG93Lnk7CisgICAgbV9keDIwID0gdjAtPndpbmRvdy54IC0gdjItPndpbmRvdy54OworICAgIG1fZHkwMiA9IHYyLT53aW5kb3cueSAtIHYwLT53aW5kb3cueTsKKyAgICBtX2FyZWEgPSBtX2R4MDEqbV9keTAyICsgKC1tX2R5MTApKm1fZHgyMDsKK30KKwordm9pZCBjb21wdXRlX2l0ZXJhdG9yc190Ojppbml0TGluZSgKKyAgICAgICAgdmVydGV4X3QgY29uc3QqIHYwLCB2ZXJ0ZXhfdCBjb25zdCogdjEpCit7CisgICAgbV9keDAxID0gbV9keTAyID0gdjEtPndpbmRvdy54IC0gdjAtPndpbmRvdy54OworICAgIG1fZHkxMCA9IG1fZHgyMCA9IHYwLT53aW5kb3cueSAtIHYxLT53aW5kb3cueTsKKyAgICBtX2FyZWEgPSBtX2R4MDEqbV9keTAyICsgKC1tX2R5MTApKm1fZHgyMDsKK30KKwordm9pZCBjb21wdXRlX2l0ZXJhdG9yc190Ojppbml0TGVycCh2ZXJ0ZXhfdCBjb25zdCogdjAsIHVpbnQzMl90IGVuYWJsZXMpCit7CisgICAgbV94MCA9IHYwLT53aW5kb3cueDsKKyAgICBtX3kwID0gdjAtPndpbmRvdy55OworICAgIGNvbnN0IEdHTGNvb3JkIGFyZWEgPSAobV9hcmVhICsgVFJJX0hBTEYpID4+IFRSSV9GUkFDVElPTl9CSVRTOworICAgIGNvbnN0IEdHTGNvb3JkIG1pbkFyZWEgPSAyOyAvLyBjYW5ub3QgYmUgaW52ZXJ0ZWQKKyAgICAvLyB0cmlhbmdsZXMgd2l0aCBhbiBhcmVhIHNtYWxsZXIgdGhhbiAxLjAgYXJlIG5vdCBzbW9vdGgtc2hhZGVkCisKKyAgICBpbnQgcT0wLCBzPTAsIGQ9MDsKKyAgICBpZiAoYWJzKGFyZWEpID49IG1pbkFyZWEpIHsKKyAgICAgICAgLy8gSGVyZSB3ZSBkbyBzb21lIHZvb2RvbyBtYWdpYywgdG8gY29tcHV0ZSBhIHN1aXRhYmxlIHNjYWxlCisgICAgICAgIC8vIGZhY3RvciBmb3IgZGVsdGFzL2FyZWE6CisKKyAgICAgICAgLy8gRmlyc3QgY29tcHV0ZSB0aGUgMS9hcmVhIHdpdGggZnVsbCAzMi1iaXRzIHByZWNpc2lvbiwKKyAgICAgICAgLy8gZ2dsUmVjaXBRTm9ybWFsaXplZCByZXR1cm5zIGEgbnVtYmVyIFstMC41LCAwLjVbIGFuZCBhbiBleHBvbmVudC4KKyAgICAgICAgZCA9IGdnbFJlY2lwUU5vcm1hbGl6ZWQoYXJlYSwgJnEpOworCisgICAgICAgIC8vIFRoZW4gY29tcHV0ZSB0aGUgbWluaW11bSBsZWZ0LXNoaWZ0IHRvIG5vdCBvdmVyZmxvdyB0aGUgbXVscworICAgICAgICAvLyBiZWxvdy4gCisgICAgICAgIHMgPSAzMiAtIGdnbENseihhYnMobV9keTAyKXxhYnMobV9keTEwKXxhYnMobV9keDAxKXxhYnMobV9keDIwKSk7CisKKyAgICAgICAgLy8gV2UnbGwga2VlcCAxNi1iaXRzIG9mIHByZWNpc2lvbiBmb3IgZGVsdGFzL2FyZWEuIFNvIHdlIG5lZWQKKyAgICAgICAgLy8gdG8gc2hpZnQgZXZlcnl0aGluZyBsZWZ0IGFuIGV4dHJhIDE1IGJpdHMuCisgICAgICAgIHMgKz0gMTU7CisgICAgICAgIAorICAgICAgICAvLyBtYWtlIHN1cmUgYWxsIGZpbmFsIHNoaWZ0cyBhcmUgbm90ID4gMzIsIGJlY2F1c2UgZ2dsTXVseAorICAgICAgICAvLyBjYW4ndCBoYW5kbGUgaXQuCisgICAgICAgIGlmIChzIDwgcSkgcyA9IHE7CisgICAgICAgIGlmIChzID4gMzIpIHsKKyAgICAgICAgICAgIGQgPj49IDMyLXM7CisgICAgICAgICAgICBzID0gMzI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBtX2R4MDEgPSBnZ2xNdWx4KG1fZHgwMSwgZCwgcyk7CisgICAgbV9keTEwID0gZ2dsTXVseChtX2R5MTAsIGQsIHMpOworICAgIG1fZHgyMCA9IGdnbE11bHgobV9keDIwLCBkLCBzKTsKKyAgICBtX2R5MDIgPSBnZ2xNdWx4KG1fZHkwMiwgZCwgcyk7CisgICAgbV9hcmVhX3NjYWxlID0gMzIgKyBxIC0gczsKKyAgICBtX3NjYWxlID0gMDsKKworICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKSB7CisgICAgICAgIGNvbnN0IGludCBBID0gZ2dsQ2x6KGFicyhtX2R5MDIpfGFicyhtX2R5MTApfGFicyhtX2R4MDEpfGFicyhtX2R4MjApKTsKKyAgICAgICAgY29uc3QgaW50IEIgPSBnZ2xDbHooYWJzKG1feDApfGFicyhtX3kwKSk7CisgICAgICAgIG1fc2NhbGUgPSBtYXgoMCwgMzIgLSAoQSArIDE2KSkgKworICAgICAgICAgICAgICAgICAgbWF4KDAsIDMyIC0gKEIgKyBUUklfRlJBQ1RJT05fQklUUykpICsgMTsKKyAgICB9Cit9CisKK2ludCBjb21wdXRlX2l0ZXJhdG9yc190OjppdGVyYXRvcnNTY2FsZShHR0xmaXhlZCogaXQsCisgICAgICAgIGludDMyX3QgYzAsIGludDMyX3QgYzEsIGludDMyX3QgYzIpIGNvbnN0Cit7CisgICAgaW50MzJfdCBkYzAxID0gYzEgLSBjMDsKKyAgICBpbnQzMl90IGRjMDIgPSBjMiAtIGMwOworICAgIGNvbnN0IGludCBBID0gZ2dsQ2x6KGFicyhjMCkpOworICAgIGNvbnN0IGludCBCID0gZ2dsQ2x6KGFicyhkYzAxKXxhYnMoZGMwMikpOworICAgIGNvbnN0IGludCBzY2FsZSA9IG1pbihBLCBCIC0gbV9zY2FsZSkgLSAyOworICAgIGlmIChzY2FsZSA+PSAwKSB7CisgICAgICAgIGMwICAgPDw9IHNjYWxlOworICAgICAgICBkYzAxIDw8PSBzY2FsZTsKKyAgICAgICAgZGMwMiA8PD0gc2NhbGU7CisgICAgfSBlbHNlIHsKKyAgICAgICAgYzAgICA+Pj0gLXNjYWxlOworICAgICAgICBkYzAxID4+PSAtc2NhbGU7CisgICAgICAgIGRjMDIgPj49IC1zY2FsZTsKKyAgICB9CisgICAgY29uc3QgaW50IHMgPSBtX2FyZWFfc2NhbGU7CisgICAgaW50MzJfdCBkY2R4ID0gZ2dsTXVsQWRkeChkYzAxLCBtX2R5MDIsIGdnbE11bHgoZGMwMiwgbV9keTEwLCBzKSwgcyk7CisgICAgaW50MzJfdCBkY2R5ID0gZ2dsTXVsQWRkeChkYzAyLCBtX2R4MDEsIGdnbE11bHgoZGMwMSwgbV9keDIwLCBzKSwgcyk7CisgICAgaW50MzJfdCBjID0gYzAgLSAoZ2dsTXVsQWRkeChkY2R4LCBtX3gwLCAKKyAgICAgICAgICAgIGdnbE11bHgoZGNkeSwgbV95MCwgVFJJX0ZSQUNUSU9OX0JJVFMpLCBUUklfRlJBQ1RJT05fQklUUykpOworICAgIGl0WzBdID0gYzsKKyAgICBpdFsxXSA9IGRjZHg7CisgICAgaXRbMl0gPSBkY2R5OworICAgIHJldHVybiBzY2FsZTsKK30KKwordm9pZCBjb21wdXRlX2l0ZXJhdG9yc190OjppdGVyYXRvcnMxNjE2KEdHTGZpeGVkKiBpdCwKKyAgICAgICAgR0dMZml4ZWQgYzAsIEdHTGZpeGVkIGMxLCBHR0xmaXhlZCBjMikgY29uc3QKK3sKKyAgICBjb25zdCBHR0xmaXhlZCBkYzAxID0gYzEgLSBjMDsKKyAgICBjb25zdCBHR0xmaXhlZCBkYzAyID0gYzIgLSBjMDsKKyAgICAvLyAxNi4xNiB4IDE2LjE2ID09IDMyLjMyIC0tPiAxNi4xNgorICAgIGNvbnN0IGludCBzID0gbV9hcmVhX3NjYWxlOworICAgIGludDMyX3QgZGNkeCA9IGdnbE11bEFkZHgoZGMwMSwgbV9keTAyLCBnZ2xNdWx4KGRjMDIsIG1fZHkxMCwgcyksIHMpOworICAgIGludDMyX3QgZGNkeSA9IGdnbE11bEFkZHgoZGMwMiwgbV9keDAxLCBnZ2xNdWx4KGRjMDEsIG1fZHgyMCwgcyksIHMpOworICAgIGludDMyX3QgYyA9IGMwIC0gKGdnbE11bEFkZHgoZGNkeCwgbV94MCwKKyAgICAgICAgICAgIGdnbE11bHgoZGNkeSwgbV95MCwgVFJJX0ZSQUNUSU9OX0JJVFMpLCBUUklfRlJBQ1RJT05fQklUUykpOworICAgIGl0WzBdID0gYzsKKyAgICBpdFsxXSA9IGRjZHg7CisgICAgaXRbMl0gPSBkY2R5OworfQorCit2b2lkIGNvbXB1dGVfaXRlcmF0b3JzX3Q6Oml0ZXJhdG9yczAwMzIoaW50NjRfdCogaXQsCisgICAgICAgIGludDMyX3QgYzAsIGludDMyX3QgYzEsIGludDMyX3QgYzIpIGNvbnN0Cit7CisgICAgY29uc3QgaW50IHMgPSBtX2FyZWFfc2NhbGUgLSAxNjsKKyAgICBpbnQzMl90IGRjMDEgPSAoYzEgLSBjMCk+PnM7CisgICAgaW50MzJfdCBkYzAyID0gKGMyIC0gYzApPj5zOworICAgIC8vIDE2LjE2IHggMTYuMTYgPT0gMzIuMzIKKyAgICBpbnQ2NF90IGRjZHggPSBnZ2xNdWxpaShkYzAxLCBtX2R5MDIpICsgZ2dsTXVsaWkoZGMwMiwgbV9keTEwKTsKKyAgICBpbnQ2NF90IGRjZHkgPSBnZ2xNdWxpaShkYzAyLCBtX2R4MDEpICsgZ2dsTXVsaWkoZGMwMSwgbV9keDIwKTsKKyAgICBpdFsgMF0gPSAoYzA8PDE2KSAtICgoZGNkeCptX3gwICsgZGNkeSptX3kwKT4+NCk7CisgICAgaXRbIDFdID0gZGNkeDsKKyAgICBpdFsgMl0gPSBkY2R5OworfQorCisjaWYgZGVmaW5lZChfX2FybV9fKSAmJiAhZGVmaW5lZChfX3RodW1iX18pCitpbmxpbmUgdm9pZCBjb21wdXRlX2l0ZXJhdG9yc190OjppdGVyYXRvcnMwMDMyKGludDMyX3QqIGl0LAorICAgICAgICBpbnQzMl90IGMwLCBpbnQzMl90IGMxLCBpbnQzMl90IGMyKSBjb25zdAoreworICAgIDo6aXRlcmF0b3JzMDAzMih0aGlzLCBpdCwgYzAsIGMxLCBjMik7Cit9CisjZWxzZQordm9pZCBjb21wdXRlX2l0ZXJhdG9yc190OjppdGVyYXRvcnMwMDMyKGludDMyX3QqIGl0LAorICAgICAgICBpbnQzMl90IGMwLCBpbnQzMl90IGMxLCBpbnQzMl90IGMyKSBjb25zdAoreworICAgIGludDY0X3QgaXQ2NFszXTsKKyAgICBpdGVyYXRvcnMwMDMyKGl0LCBjMCwgYzEsIGMyKTsKKyAgICBpdFswXSA9IGl0NjRbMF07CisgICAgaXRbMV0gPSBpdDY0WzFdOworICAgIGl0WzJdID0gaXQ2NFsyXTsKK30KKyNlbmRpZgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBpbmxpbmUgaW50MzJfdCBjbGFtcFooR0xmaXhlZCB6KSBDT05TVDsKK2ludDMyX3QgY2xhbXBaKEdMZml4ZWQgeikgeworICAgIHogPSAoeiAmIH4oej4+MzEpKTsKKyAgICBpZiAoeiA+PSAweDEwMDAwKQorICAgICAgICB6ID0gMHhGRkZGOworICAgIHJldHVybiB6OworfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBmZXRjaF90ZXhjb29yZF9pbXBsKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICB2ZXJ0ZXhfdCogY29uc3QgdnR4WzNdID0geyB2MCwgdjEsIHYyIH07CisgICAgYXJyYXlfdCBjb25zdCAqIGNvbnN0IHRleGNvb3JkQXJyYXkgPSBjLT5hcnJheXMudGV4dHVyZTsKKyAgICAKKyAgICBmb3IgKGludCBpPTAgOyBpPEdHTF9URVhUVVJFX1VOSVRfQ09VTlQgOyBpKyspIHsKKyAgICAgICAgaWYgKCEoYy0+cmFzdGVyaXplci5zdGF0ZS50ZXh0dXJlW2ldLmVuYWJsZSkpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgCisgICAgICAgIGZvciAoaW50IGo9MCA7IGo8MyA7IGorKykgeworICAgICAgICAgICAgdmVydGV4X3QqIGNvbnN0IHYgPSB2dHhbal07CisgICAgICAgICAgICBpZiAodi0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6VFQpCisgICAgICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgICAgIC8vIE5PVEU6IGhlcmUgd2UgY291bGQgY29tcHV0ZSBhdXRvbWF0aWMgdGV4Z2VuCisgICAgICAgICAgICAvLyBzdWNoIGFzIHNwaGVyZS9jdWJlIG1hcHMsIGluc3RlYWQgb2YgZmV0Y2hpbmcgdGhlbQorICAgICAgICAgICAgLy8gZnJvbSB0aGUgdGV4dGNvb3JkIGFycmF5LgorCisgICAgICAgICAgICB2ZWM0X3QmIGNvb3JkcyA9IHYtPnRleHR1cmVbaV07CisgICAgICAgICAgICBjb25zdCBHTHVieXRlKiB0cCA9IHRleGNvb3JkQXJyYXlbaV0uZWxlbWVudCgKKyAgICAgICAgICAgICAgICAgICAgdi0+aW5kZXggJiB2ZXJ0ZXhfY2FjaGVfdDo6SU5ERVhfTUFTSyk7CisgICAgICAgICAgICB0ZXhjb29yZEFycmF5W2ldLmZldGNoKGMsIGNvb3Jkcy52LCB0cCk7CisKKyAgICAgICAgICAgIC8vIHRyYW5zZm9ybSB0ZXh0dXJlIGNvb3JkaW5hdGVzLi4uCisgICAgICAgICAgICBjb29yZHMuUSA9IDB4MTAwMDA7CisgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1fdCYgdHIgPSBjLT50cmFuc2Zvcm1zLnRleHR1cmVbaV0udHJhbnNmb3JtOyAKKyAgICAgICAgICAgIGlmIChnZ2xfdW5saWtlbHkodHIub3BzKSkgeworICAgICAgICAgICAgICAgIGMtPmFycmF5cy50ZXhfdHJhbnNmb3JtW2ldKCZ0ciwgJmNvb3JkcywgJmNvb3Jkcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGRpdmlkZSBieSBRCisgICAgICAgICAgICBjb25zdCBHR0xmaXhlZCBxID0gY29vcmRzLlE7CisgICAgICAgICAgICBpZiAoZ2dsX3VubGlrZWx5KHEgIT0gMHgxMDAwMCkpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBpbnQzMl90IHFpbnYgPSBnZ2xSZWNpcDI4KHEpOworICAgICAgICAgICAgICAgIGNvb3Jkcy5TID0gZ2dsTXVseChjb29yZHMuUywgcWludiwgMjgpOworICAgICAgICAgICAgICAgIGNvb3Jkcy5UID0gZ2dsTXVseChjb29yZHMuVCwgcWludiwgMjgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHYwLT5mbGFncyB8PSB2ZXJ0ZXhfdDo6VFQ7CisgICAgdjEtPmZsYWdzIHw9IHZlcnRleF90OjpUVDsKKyAgICB2Mi0+ZmxhZ3MgfD0gdmVydGV4X3Q6OlRUOworfQorCitpbmxpbmUgdm9pZCBmZXRjaF90ZXhjb29yZChvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgY29uc3QgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKyAgICBpZiAoIShlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgLy8gRmV0Y2ggJiB0cmFuc2Zvcm0gdGV4dHVyZSBjb29yZGluYXRlcy4uLgorICAgIGlmIChnZ2xfbGlrZWx5KHYwLT5mbGFncyAmIHYxLT5mbGFncyAmIHYyLT5mbGFncyAmIHZlcnRleF90OjpUVCkpIHsKKyAgICAgICAgLy8gYWxyZWFkeSBkb25lIGZvciBhbGwgdGhyZWUgdmVydGljZXMsIGJhaWwuLi4KKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBmZXRjaF90ZXhjb29yZF9pbXBsKGMsIHYwLCB2MSwgdjIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBQb2ludAorI2VuZGlmCisKK3ZvaWQgcHJpbWl0aXZlX25vcF9wb2ludChvZ2xlc19jb250ZXh0X3QqLCB2ZXJ0ZXhfdCopIHsKK30KKwordm9pZCBwcmltaXRpdmVfcG9pbnQob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikKK3sKKyAgICAvLyBsaWdodGluZyAmIGNsYW1waW5nLi4uCisgICAgY29uc3QgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKworICAgIGlmIChnZ2xfdW5saWtlbHkoISh2LT5mbGFncyAmIHZlcnRleF90OjpMSVQpKSkgeworICAgICAgICBpZiAoYy0+bGlnaHRpbmcuZW5hYmxlKSB7CisgICAgICAgICAgICBjLT5saWdodGluZy5saWdodFZlcnRleChjLCB2KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHYtPmZsYWdzIHw9IHZlcnRleF90OjpMSVQ7CisgICAgICAgICAgICBjb25zdCBHTHZvaWQqIGNwID0gYy0+YXJyYXlzLmNvbG9yLmVsZW1lbnQoCisgICAgICAgICAgICAgICAgICAgIHYtPmluZGV4ICYgdmVydGV4X2NhY2hlX3Q6OklOREVYX01BU0spOworICAgICAgICAgICAgYy0+YXJyYXlzLmNvbG9yLmZldGNoKGMsIHYtPmNvbG9yLnYsIGNwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5hYmxlcyAmIEdHTF9FTkFCTEVfRk9HKSB7CisgICAgICAgICAgICB2LT5mb2cgPSBjLT5mb2cuZm9nKGMsIHYtPmV5ZS56KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFhYWDogd2UgZG9uJ3QgbmVlZCB0byBkbyB0aGF0IGVhY2gtdGltZQorICAgIC8vIGlmIGNvbG9yIGFycmF5IGFuZCBsaWdodGluZyBub3QgZW5hYmxlZCAKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNvbG9yNHh2KGMsIHYtPmNvbG9yLnYpOworCisgICAgLy8gWFhYOiBsb29rIGludG8gRVMgcG9pbnQtc3ByaXRlIGV4dGVuc2lvbgorICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKSB7CisgICAgICAgIGZldGNoX3RleGNvb3JkKGMsIHYsdix2KTsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoIWMtPnJhc3Rlcml6ZXIuc3RhdGUudGV4dHVyZVtpXS5lbmFibGUpIAorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgaW50MzJfdCBpdHRbOF07CisgICAgICAgICAgICBpdHRbMV0gPSBpdHRbMl0gPSBpdHRbNF0gPSBpdHRbNV0gPSAwOworICAgICAgICAgICAgaXR0WzZdID0gaXR0WzddID0gMTY7IC8vIFhYWDogY2hlY2sgdGhhdAorICAgICAgICAgICAgaWYgKGMtPnJhc3Rlcml6ZXIuc3RhdGUudGV4dHVyZVtpXS5zX3dyYXAgPT0gR0dMX0NMQU1QKSB7CisgICAgICAgICAgICAgICAgaW50IHdpZHRoID0gYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUtPnN1cmZhY2Uud2lkdGg7CisgICAgICAgICAgICAgICAgaXR0WzBdID0gdi0+dGV4dHVyZVtpXS5TICogd2lkdGg7CisgICAgICAgICAgICAgICAgaXR0WzZdID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjLT5yYXN0ZXJpemVyLnN0YXRlLnRleHR1cmVbaV0udF93cmFwID09IEdHTF9DTEFNUCkgeworICAgICAgICAgICAgICAgIGludCBoZWlnaHQgPSBjLT50ZXh0dXJlcy50bXVbaV0udGV4dHVyZS0+c3VyZmFjZS5oZWlnaHQ7CisgICAgICAgICAgICAgICAgaXR0WzNdID0gdi0+dGV4dHVyZVtpXS5UICogaGVpZ2h0OworICAgICAgICAgICAgICAgIGl0dFs3XSA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleENvb3JkR3JhZFNjYWxlOHh2KGMsIGksIGl0dCk7CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0RFUFRIX1RFU1QpIHsKKyAgICAgICAgaW50MzJfdCBpdHpbM107CisgICAgICAgIGl0elswXSA9IGNsYW1wWih2LT53aW5kb3cueikgKiAweDAwMDEwMDAxOworICAgICAgICBpdHpbMV0gPSBpdHpbMl0gPSAwOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnpHcmFkM3h2KGMsIGl0eik7CisgICAgfQorCisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0ZPRykgeworICAgICAgICBHTGZpeGVkIGl0ZlszXTsKKyAgICAgICAgaXRmWzBdID0gdi0+Zm9nOworICAgICAgICBpdGZbMV0gPSBpdGZbMl0gPSAwOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmZvZ0dyYWQzeHYoYywgaXRmKTsKKyAgICB9CisKKyAgICAvLyBSZW5kZXIgb3VyIHBvaW50Li4uCisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5wb2ludHgoYywgdi0+d2luZG93LnYsIGMtPnBvaW50LnNpemUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBMaW5lCisjZW5kaWYKKwordm9pZCBwcmltaXRpdmVfbm9wX2xpbmUob2dsZXNfY29udGV4dF90KiwgdmVydGV4X3QqLCB2ZXJ0ZXhfdCopIHsKK30KKwordm9pZCBwcmltaXRpdmVfbGluZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxKQoreworICAgIC8vIGdldCB0ZXh0dXJlIGNvb3JkaW5hdGVzCisgICAgZmV0Y2hfdGV4Y29vcmQoYywgdjAsIHYxLCB2MSk7CisKKyAgICAvLyBsaWdodC9zaGFkZSB0aGUgdmVydGljZXMgZmlyc3QgKHRoZXkncmUgY29waWVkIGJlbG93KQorICAgIGMtPmxpZ2h0aW5nLmxpZ2h0VHJpYW5nbGUoYywgdjAsIHYxLCB2MSk7CisKKyAgICAvLyBjbGlwIHRoZSBsaW5lIGlmIG5lZWRlZAorICAgIGlmIChnZ2xfdW5saWtlbHkoKHYwLT5mbGFncyB8IHYxLT5mbGFncykgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEwpKSB7CisgICAgICAgIHVuc2lnbmVkIGludCBjb3VudCA9IGNsaXBfbGluZShjLCB2MCwgdjEpOworICAgICAgICBpZiAoZ2dsX3VubGlrZWx5KGNvdW50ID09IDApKQorICAgICAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIGNvbXB1dGUgaXRlcmF0b3JzLi4uCisgICAgY29uc3QgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKyAgICBjb25zdCB1aW50MzJfdCBtYXNrID0gICBHR0xfRU5BQkxFX1RNVVMgfAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdHTF9FTkFCTEVfU01PT1RIIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHR0xfRU5BQkxFX1cgfCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHR0xfRU5BQkxFX0ZPRyB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0dMX0VOQUJMRV9ERVBUSF9URVNUOworCisgICAgaWYgKGdnbF91bmxpa2VseShlbmFibGVzICYgbWFzaykpIHsKKyAgICAgICAgYy0+bGVycC5pbml0TGluZSh2MCwgdjEpOworICAgICAgICBsZXJwX3RyaWFuZ2xlKGMsIHYwLCB2MSwgdjApOworICAgIH0KKworICAgIC8vIHJlbmRlciBvdXIgbGluZQorICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MubGluZXgoYywgdjAtPndpbmRvdy52LCB2MS0+d2luZG93LnYsIGMtPmxpbmUud2lkdGgpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBUcmlhbmdsZQorI2VuZGlmCisKK3ZvaWQgcHJpbWl0aXZlX25vcF90cmlhbmdsZShvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpIHsKK30KKwordm9pZCBwcmltaXRpdmVfY2xpcF90cmlhbmdsZShvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgdWludDMyX3QgY2MgPSAodjAtPmZsYWdzIHwgdjEtPmZsYWdzIHwgdjItPmZsYWdzKSAmIHZlcnRleF90OjpDTElQX0FMTDsKKyAgICBpZiAoZ2dsX2xpa2VseSghY2MpKSB7CisgICAgICAgIC8vIGNvZGUgYmVsb3cgbXVzdCBiZSBhcyBvcHRpbWl6ZWQgYXMgcG9zc2libGUsIHRoaXMgaXMgdGhlCisgICAgICAgIC8vIGNvbW1vbiBjb2RlIHBhdGguCisKKyAgICAgICAgLy8gVGhpcyB0cmlhbmdsZSBpcyBub3QgY2xpcHBlZCwgdGVzdCBpZiBpdCdzIGN1bGxlZAorICAgICAgICAvLyB1bmNsaXBwZWQgdHJpYW5nbGUuLi4KKyAgICAgICAgYy0+bGVycC5pbml0VHJpYW5nbGUodjAsIHYxLCB2Mik7CisgICAgICAgIGlmIChjdWxsX3RyaWFuZ2xlKGMsIHYwLCB2MSwgdjIpKQorICAgICAgICAgICAgcmV0dXJuOyAvLyBjdWxsZWQhCisKKyAgICAgICAgLy8gRmV0Y2ggYWxsIHRleHR1cmUgY29vcmRpbmF0ZXMgaWYgbmVlZGVkCisgICAgICAgIGZldGNoX3RleGNvb3JkKGMsIHYwLCB2MSwgdjIpOworCisgICAgICAgIC8vIGxpZ2h0IChvciBzaGFkZSkgb3VyIHRyaWFuZ2xlIQorICAgICAgICBjLT5saWdodGluZy5saWdodFRyaWFuZ2xlKGMsIHYwLCB2MSwgdjIpOworCisgICAgICAgIHRyaWFuZ2xlKGMsIHYwLCB2MSwgdjIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gVGhlIGFzc3VtcHRpb24gaGVyZSBpcyB0aGF0IHdlJ3JlIG5vdCBnb2luZyB0byBjbGlwIHZlcnkgb2Z0ZW4sCisgICAgLy8gYW5kIGV2ZW4gbW9yZSByYXJlbHkgd2lsbCB3ZSBjbGlwIGEgdHJpYW5nbGUgdGhhdCBlbmRzIHVwCisgICAgLy8gYmVpbmcgY3VsbGVkIG91dC4gU28gaXQncyBva2F5IHRvIGxpZ2h0IHRoZSB2ZXJ0aWNlcyBoZXJlLCBldmVuIHRob3VnaAorICAgIC8vIGluIGEgZmV3IGNhc2VzIHdlIHdvbid0IHJlbmRlciB0aGUgdHJpYW5nbGUgKGlmIGN1bGxlZCkuCisKKyAgICAvLyBGZXRjaCB0ZXh0dXJlIGNvb3JkaW5hdGVzLi4uCisgICAgZmV0Y2hfdGV4Y29vcmQoYywgdjAsIHYxLCB2Mik7CisKKyAgICAvLyBsaWdodCAob3Igc2hhZGUpIG91ciB0cmlhbmdsZSEKKyAgICBjLT5saWdodGluZy5saWdodFRyaWFuZ2xlKGMsIHYwLCB2MSwgdjIpOworCisgICAgY2xpcF90cmlhbmdsZShjLCB2MCwgdjEsIHYyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCB0cmlhbmdsZShvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgLy8gY29tcHV0ZSBpdGVyYXRvcnMuLi4KKyAgICBjb25zdCB1aW50MzJfdCBlbmFibGVzID0gYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzOworICAgIGNvbnN0IHVpbnQzMl90IG1hc2sgPSAgIEdHTF9FTkFCTEVfVE1VUyB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0dMX0VOQUJMRV9TTU9PVEggfAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdHTF9FTkFCTEVfVyB8IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdHTF9FTkFCTEVfRk9HIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHR0xfRU5BQkxFX0RFUFRIX1RFU1Q7CisKKyAgICBpZiAoZ2dsX2xpa2VseShlbmFibGVzICYgbWFzaykpCisgICAgICAgIGxlcnBfdHJpYW5nbGUoYywgdjAsIHYxLCB2Mik7CisKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRyaWFuZ2xleChjLCB2MC0+d2luZG93LnYsIHYxLT53aW5kb3cudiwgdjItPndpbmRvdy52KTsKK30KKwordm9pZCBsZXJwX3RyaWFuZ2xlKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBjb25zdCB1aW50MzJfdCBlbmFibGVzID0gYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzOworICAgIGMtPmxlcnAuaW5pdExlcnAodjAsIGVuYWJsZXMpOworCisgICAgLy8gc2V0IHVwIHRleHR1cmUgaXRlcmF0b3JzCisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX1RNVVMpIHsKKyAgICAgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX1cpIHsKKyAgICAgICAgICAgIGxlcnBfdGV4Y29vcmRzX3coYywgdjAsIHYxLCB2Mik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsZXJwX3RleGNvb3JkcyhjLCB2MCwgdjEsIHYyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHNldCB1cCB0aGUgY29sb3IgaXRlcmF0b3JzCisgICAgY29uc3QgY29tcHV0ZV9pdGVyYXRvcnNfdCYgbGVycCA9IGMtPmxlcnA7CisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX1NNT09USCkgeworICAgICAgICBHTGZpeGVkIGl0Y1sxMl07CisgICAgICAgIGZvciAoaW50IGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgICAgY29uc3QgR0dMY29sb3IgYzAgPSB2MC0+Y29sb3IudltpXSAqIDI1NTsKKyAgICAgICAgICAgIGNvbnN0IEdHTGNvbG9yIGMxID0gdjEtPmNvbG9yLnZbaV0gKiAyNTU7CisgICAgICAgICAgICBjb25zdCBHR0xjb2xvciBjMiA9IHYyLT5jb2xvci52W2ldICogMjU1OworICAgICAgICAgICAgbGVycC5pdGVyYXRvcnMxNjE2KCZpdGNbaSozXSwgYzAsIGMxLCBjMik7CisgICAgICAgIH0KKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jb2xvckdyYWQxMnh2KGMsIGl0Yyk7CisgICAgfQorCisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0RFUFRIX1RFU1QpIHsKKyAgICAgICAgaW50MzJfdCBpdHpbM107CisgICAgICAgIGNvbnN0IGludDMyX3QgdjB6ID0gY2xhbXBaKHYwLT53aW5kb3cueik7CisgICAgICAgIGNvbnN0IGludDMyX3QgdjF6ID0gY2xhbXBaKHYxLT53aW5kb3cueik7CisgICAgICAgIGNvbnN0IGludDMyX3QgdjJ6ID0gY2xhbXBaKHYyLT53aW5kb3cueik7CisgICAgICAgIGlmIChnZ2xfdW5saWtlbHkoYy0+cG9seWdvbk9mZnNldC5lbmFibGUpKSB7CisgICAgICAgICAgICBjb25zdCBpbnQzMl90IHVuaXRzID0gKGMtPnBvbHlnb25PZmZzZXQudW5pdHMgPDwgMTYpOworICAgICAgICAgICAgY29uc3QgR0xmaXhlZCBmYWN0b3IgPSBjLT5wb2x5Z29uT2Zmc2V0LmZhY3RvcjsKKyAgICAgICAgICAgIGlmIChmYWN0b3IpIHsKKyAgICAgICAgICAgICAgICBpbnQ2NF90IGl0ejY0WzNdOworICAgICAgICAgICAgICAgIGxlcnAuaXRlcmF0b3JzMDAzMihpdHo2NCwgdjB6LCB2MXosIHYyeik7CisgICAgICAgICAgICAgICAgaW50NjRfdCBtYXhEZXB0aFNsb3BlID0gbWF4KGl0ejY0WzFdLCBpdHo2NFsyXSk7CisgICAgICAgICAgICAgICAgaXR6WzBdID0gdWludDMyX3QoaXR6NjRbMF0pIAorICAgICAgICAgICAgICAgICAgICAgICAgKyB1aW50MzJfdCgobWF4RGVwdGhTbG9wZSpmYWN0b3IpPj4xNikgKyB1bml0czsKKyAgICAgICAgICAgICAgICBpdHpbMV0gPSB1aW50MzJfdChpdHo2NFsxXSk7CisgICAgICAgICAgICAgICAgaXR6WzJdID0gdWludDMyX3QoaXR6NjRbMl0pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBsZXJwLml0ZXJhdG9yczAwMzIoaXR6LCB2MHosIHYxeiwgdjJ6KTsKKyAgICAgICAgICAgICAgICBpdHpbMF0gKz0gdW5pdHM7IAorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbGVycC5pdGVyYXRvcnMwMDMyKGl0eiwgdjB6LCB2MXosIHYyeik7CisgICAgICAgIH0KKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy56R3JhZDN4dihjLCBpdHopOworICAgIH0gICAgCisKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGVuYWJsZXMgJiBHR0xfRU5BQkxFX0ZPRykpIHsKKyAgICAgICAgR0xmaXhlZCBpdGZbM107CisgICAgICAgIGxlcnAuaXRlcmF0b3JzMTYxNihpdGYsIHYwLT5mb2csIHYxLT5mb2csIHYyLT5mb2cpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmZvZ0dyYWQzeHYoYywgaXRmKTsKKyAgICB9Cit9CisKKworc3RhdGljIGlubGluZQoraW50IGNvbXB1dGVfbG9kKG9nbGVzX2NvbnRleHRfdCogYywgaW50IGksCisgICAgICAgIGludDMyX3QgczAsIGludDMyX3QgdDAsIGludDMyX3QgczEsIGludDMyX3QgdDEsIGludDMyX3QgczIsIGludDMyX3QgdDIpCit7CisgICAgLy8gQ29tcHV0ZSBtaXBtYXAgbGV2ZWwgLyBwcmltaXRpdmUKKyAgICAvLyByaG8gPSBzcXJ0KCB0ZXhlbEFyZWEgLyBhcmVhICkKKyAgICAvLyBsb2QgPSBsb2cyKCByaG8gKQorICAgIC8vIGxvZCA9IGxvZzIoIHRleGVsQXJlYSAvIGFyZWEgKSAvIDIKKyAgICAvLyBsb2QgPSAobG9nMiggdGV4ZWxBcmVhICkgLSBsb2cyKCBhcmVhICkpIC8gMgorICAgIGNvbnN0IGNvbXB1dGVfaXRlcmF0b3JzX3QmIGxlcnAgPSBjLT5sZXJwOworICAgIGNvbnN0IEdHTGNvb3JkIGFyZWEgPSBhYnMobGVycC5hcmVhKCkpOworICAgIGNvbnN0IGludCB3ID0gYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUtPnN1cmZhY2Uud2lkdGg7CisgICAgY29uc3QgaW50IGggPSBjLT50ZXh0dXJlcy50bXVbaV0udGV4dHVyZS0+c3VyZmFjZS5oZWlnaHQ7CisgICAgY29uc3QgaW50IHNoaWZ0ID0gMTYgKyAoMTYgLSBUUklfRlJBQ1RJT05fQklUUyk7CisgICAgaW50MzJfdCB0ZXhlbEFyZWEgPSBhYnMoIGdnbE11bHgoczEtczAsIHQyLXQwLCBzaGlmdCkgLQorICAgICAgICAgICAgZ2dsTXVseChzMi1zMCwgdDEtdDAsIHNoaWZ0KSApKncqaDsKKyAgICBpbnQgbG9nMlRBcmVhID0gKDMyLVRSSV9GUkFDVElPTl9CSVRTICAtMSkgLSBnZ2xDbHoodGV4ZWxBcmVhKTsKKyAgICBpbnQgbG9nMkFyZWEgID0gKDMyLVRSSV9GUkFDVElPTl9CSVRTKjItMSkgLSBnZ2xDbHooYXJlYSk7CisgICAgaW50IGxvZCA9IChsb2cyVEFyZWEgLSBsb2cyQXJlYSArIDEpID4+IDE7CisgICAgcmV0dXJuIGxvZDsKK30KKwordm9pZCBsZXJwX3RleGNvb3JkcyhvZ2xlc19jb250ZXh0X3QqIGMsCisgICAgICAgIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgY29uc3QgY29tcHV0ZV9pdGVyYXRvcnNfdCYgbGVycCA9IGMtPmxlcnA7CisgICAgaW50MzJfdCBpdHRbOF0gX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgxNikpKTsKKyAgICBmb3IgKGludCBpPTAgOyBpPEdHTF9URVhUVVJFX1VOSVRfQ09VTlQgOyBpKyspIHsKKyAgICAgICAgY29uc3QgdGV4dHVyZV90JiB0bXUgPSBjLT5yYXN0ZXJpemVyLnN0YXRlLnRleHR1cmVbaV07CisgICAgICAgIGlmICghdG11LmVuYWJsZSkgCisgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAvLyBjb21wdXRlIHRoZSBqYWNvYmlhbnMgdXNpbmcgYmxvY2sgZmxvYXRpbmctcG9pbnQKKyAgICAgICAgaW50MzJfdCBzMCA9IHYwLT50ZXh0dXJlW2ldLlM7CisgICAgICAgIGludDMyX3QgdDAgPSB2MC0+dGV4dHVyZVtpXS5UOworICAgICAgICBpbnQzMl90IHMxID0gdjEtPnRleHR1cmVbaV0uUzsKKyAgICAgICAgaW50MzJfdCB0MSA9IHYxLT50ZXh0dXJlW2ldLlQ7CisgICAgICAgIGludDMyX3QgczIgPSB2Mi0+dGV4dHVyZVtpXS5TOworICAgICAgICBpbnQzMl90IHQyID0gdjItPnRleHR1cmVbaV0uVDsKKworICAgICAgICBjb25zdCBHTGVudW0gbWluX2ZpbHRlciA9IGMtPnRleHR1cmVzLnRtdVtpXS50ZXh0dXJlLT5taW5fZmlsdGVyOworICAgICAgICBpZiAoZ2dsX3VubGlrZWx5KG1pbl9maWx0ZXIgPj0gR0xfTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCkpIHsKKyAgICAgICAgICAgIGludCBsb2QgPSBjb21wdXRlX2xvZChjLCBpLCBzMCwgdDAsIHMxLCB0MSwgczIsIHQyKTsKKyAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuYmluZFRleHR1cmVMb2QoYywgaSwKKyAgICAgICAgICAgICAgICAgICAgJmMtPnRleHR1cmVzLnRtdVtpXS50ZXh0dXJlLT5taXAobG9kKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBwcmVtdWx0aXBseSAocyx0KSB3aGVuIGNsYW1wbGluZworICAgICAgICBpZiAodG11LnNfd3JhcCA9PSBHR0xfQ0xBTVApIHsKKyAgICAgICAgICAgIGNvbnN0IGludCB3aWR0aCA9IHRtdS5zdXJmYWNlLndpZHRoOworICAgICAgICAgICAgczAgKj0gd2lkdGg7CisgICAgICAgICAgICBzMSAqPSB3aWR0aDsKKyAgICAgICAgICAgIHMyICo9IHdpZHRoOworICAgICAgICB9CisgICAgICAgIGlmICh0bXUudF93cmFwID09IEdHTF9DTEFNUCkgeworICAgICAgICAgICAgY29uc3QgaW50IGhlaWdodCA9IHRtdS5zdXJmYWNlLmhlaWdodDsKKyAgICAgICAgICAgIHQwICo9IGhlaWdodDsKKyAgICAgICAgICAgIHQxICo9IGhlaWdodDsKKyAgICAgICAgICAgIHQyICo9IGhlaWdodDsKKyAgICAgICAgfQorICAgICAgICBpdHRbNl0gPSAtbGVycC5pdGVyYXRvcnNTY2FsZShpdHQrMCwgczAsIHMxLCBzMik7CisgICAgICAgIGl0dFs3XSA9IC1sZXJwLml0ZXJhdG9yc1NjYWxlKGl0dCszLCB0MCwgdDEsIHQyKTsKKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy50ZXhDb29yZEdyYWRTY2FsZTh4dihjLCBpLCBpdHQpOworICAgIH0KK30KKwordm9pZCBsZXJwX3RleGNvb3Jkc193KG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICBjb25zdCBjb21wdXRlX2l0ZXJhdG9yc190JiBsZXJwID0gYy0+bGVycDsKKyAgICBpbnQzMl90IGl0dFs4XSBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDE2KSkpOworICAgIGludDMyX3QgaXR3WzNdOworCisgICAgLy8gY29tcHV0ZSBXJ3Mgc2NhbGUgdG8gMi4zMAorICAgIGludDMyX3QgdzAgPSB2MC0+d2luZG93Lnc7CisgICAgaW50MzJfdCB3MSA9IHYxLT53aW5kb3cudzsKKyAgICBpbnQzMl90IHcyID0gdjItPndpbmRvdy53OworICAgIGludCB3c2NhbGUgPSAzMiAtIGdnbENseih3MHx3MXx3Mik7CisKKyAgICAvLyBjb21wdXRlIHRoZSBqYWNvYmlhbiB1c2luZyBibG9jayBmbG9hdGluZy1wb2ludCAgICAKKyAgICBpbnQgc2MgPSBsZXJwLml0ZXJhdG9yc1NjYWxlKGl0dywgdzAsIHcxLCB3Mik7CisgICAgc2MgKz0gIHdzY2FsZSAtIDE2OworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3Mud0dyYWQzeHYoYywgaXR3KTsKKworICAgIGZvciAoaW50IGk9MCA7IGk8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IGkrKykgeworICAgICAgICBjb25zdCB0ZXh0dXJlX3QmIHRtdSA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUudGV4dHVyZVtpXTsKKyAgICAgICAgaWYgKCF0bXUuZW5hYmxlKSAKKyAgICAgICAgICAgIGNvbnRpbnVlOworCisgICAgICAgIC8vIGNvbXB1dGUgdGhlIGphY29iaWFucyB1c2luZyBibG9jayBmbG9hdGluZy1wb2ludAorICAgICAgICBpbnQzMl90IHMwID0gdjAtPnRleHR1cmVbaV0uUzsKKyAgICAgICAgaW50MzJfdCB0MCA9IHYwLT50ZXh0dXJlW2ldLlQ7CisgICAgICAgIGludDMyX3QgczEgPSB2MS0+dGV4dHVyZVtpXS5TOworICAgICAgICBpbnQzMl90IHQxID0gdjEtPnRleHR1cmVbaV0uVDsKKyAgICAgICAgaW50MzJfdCBzMiA9IHYyLT50ZXh0dXJlW2ldLlM7CisgICAgICAgIGludDMyX3QgdDIgPSB2Mi0+dGV4dHVyZVtpXS5UOworCisgICAgICAgIGNvbnN0IEdMZW51bSBtaW5fZmlsdGVyID0gYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUtPm1pbl9maWx0ZXI7CisgICAgICAgIGlmIChnZ2xfdW5saWtlbHkobWluX2ZpbHRlciA+PSBHTF9ORUFSRVNUX01JUE1BUF9ORUFSRVNUKSkgeworICAgICAgICAgICAgaW50IGxvZCA9IGNvbXB1dGVfbG9kKGMsIGksIHMwLCB0MCwgczEsIHQxLCBzMiwgdDIpOworICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5iaW5kVGV4dHVyZUxvZChjLCBpLAorICAgICAgICAgICAgICAgICAgICAmYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUtPm1pcChsb2QpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHByZW11bHRpcGx5IChzLHQpIHdoZW4gY2xhbXBsaW5nCisgICAgICAgIGlmICh0bXUuc193cmFwID09IEdHTF9DTEFNUCkgeworICAgICAgICAgICAgY29uc3QgaW50IHdpZHRoID0gdG11LnN1cmZhY2Uud2lkdGg7CisgICAgICAgICAgICBzMCAqPSB3aWR0aDsKKyAgICAgICAgICAgIHMxICo9IHdpZHRoOworICAgICAgICAgICAgczIgKj0gd2lkdGg7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRtdS50X3dyYXAgPT0gR0dMX0NMQU1QKSB7CisgICAgICAgICAgICBjb25zdCBpbnQgaGVpZ2h0ID0gdG11LnN1cmZhY2UuaGVpZ2h0OworICAgICAgICAgICAgdDAgKj0gaGVpZ2h0OworICAgICAgICAgICAgdDEgKj0gaGVpZ2h0OworICAgICAgICAgICAgdDIgKj0gaGVpZ2h0OworICAgICAgICB9CisKKyAgICAgICAgczAgPSBnZ2xNdWx4KHMwLCB3MCwgd3NjYWxlKTsKKyAgICAgICAgdDAgPSBnZ2xNdWx4KHQwLCB3MCwgd3NjYWxlKTsKKyAgICAgICAgczEgPSBnZ2xNdWx4KHMxLCB3MSwgd3NjYWxlKTsKKyAgICAgICAgdDEgPSBnZ2xNdWx4KHQxLCB3MSwgd3NjYWxlKTsKKyAgICAgICAgczIgPSBnZ2xNdWx4KHMyLCB3Miwgd3NjYWxlKTsKKyAgICAgICAgdDIgPSBnZ2xNdWx4KHQyLCB3Miwgd3NjYWxlKTsKKworICAgICAgICBpdHRbNl0gPSBzYyAtIGxlcnAuaXRlcmF0b3JzU2NhbGUoaXR0KzAsIHMwLCBzMSwgczIpOworICAgICAgICBpdHRbN10gPSBzYyAtIGxlcnAuaXRlcmF0b3JzU2NhbGUoaXR0KzMsIHQwLCB0MSwgdDIpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleENvb3JkR3JhZFNjYWxlOHh2KGMsIGksIGl0dCk7CisgICAgfQorfQorCisKK3N0YXRpYyBpbmxpbmUKK2Jvb2wgY3VsbF90cmlhbmdsZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2MCwgdmVydGV4X3QqIHYxLCB2ZXJ0ZXhfdCogdjIpCit7CisgICAgaWYgKGdnbF9saWtlbHkoYy0+Y3VsbC5lbmFibGUpKSB7CisgICAgICAgIGNvbnN0IEdMZW51bSB3aW5kaW5nID0gKGMtPmxlcnAuYXJlYSgpID4gMCkgPyBHTF9DVyA6IEdMX0NDVzsKKyAgICAgICAgY29uc3QgR0xlbnVtIGZhY2UgPSAod2luZGluZyA9PSBjLT5jdWxsLmZyb250RmFjZSkgPyBHTF9GUk9OVCA6IEdMX0JBQ0s7CisgICAgICAgIGlmIChmYWNlID09IGMtPmN1bGwuY3VsbEZhY2UpCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gY3VsbGVkIQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXRpYyBpbmxpbmUKK0dMZml4ZWQgZnJ1c3R1bVBsYW5lRGlzdChpbnQgcGxhbmUsIGNvbnN0IHZlYzRfdCYgcykKK3sKKyAgICBjb25zdCBHTGZpeGVkIGQgPSBzLnZbIHBsYW5lID4+IDEgXTsKKyAgICByZXR1cm4gICgocGxhbmUgJiAxKSA/IChzLncgLSBkKSA6IChzLncgKyBkKSk7IAorfQorCitzdGF0aWMgaW5saW5lCitpbnQzMl90IGNsaXBEaXZpZGUoR0xmaXhlZCBhLCBHTGZpeGVkIGIpIHsKKyAgICAvLyByZXR1cm5zIGEgNC4yOCBmaXhlZC1wb2ludAorICAgIHJldHVybiBnZ2xNdWxEaXZpKDFMVTw8MjgsIGEsIGIpOworfSAKKwordm9pZCBjbGlwX3RyaWFuZ2xlKG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgdmVydGV4X3QqIHYwLCB2ZXJ0ZXhfdCogdjEsIHZlcnRleF90KiB2MikKK3sKKyAgICB1aW50MzJfdCBhbGxfY2MgPSAodjAtPmZsYWdzIHwgdjEtPmZsYWdzIHwgdjItPmZsYWdzKSAmIHZlcnRleF90OjpDTElQX0FMTDsKKworICAgIHZlcnRleF90ICpwMCwgKnAxLCAqcDI7CisgICAgY29uc3QgaW50IE1BWF9DTElQUElOR19QTEFORVMgPSA2ICsgT0dMRVNfTUFYX0NMSVBfUExBTkVTOworICAgIGNvbnN0IGludCBNQVhfVkVSVElDRVMgPSAzOworCisgICAgLy8gVGVtcG9yYXJ5IGJ1ZmZlciB0byBob2xkIHRoZSBuZXcgdmVydGljZXMuIEVhY2ggcGxhbmUgY2FuIGFkZCB1cCB0byAKKyAgICAvLyB0d28gbmV3IHZlcnRpY2VzIChiZWNhdXNlIHRoZSBwb2x5Z29uIGlzIGNvbnZleCkuCisgICAgLy8gV2UgbmVlZCBvbmUgZXh0cmEgZWxlbWVudCwgdG8gaGFuZGxlIGFuIG92ZXJmbG93IGNhc2Ugd2hlbgorICAgIC8vIHRoZSBwb2x5Z29uIGRlZ2VuZXJhdGVzIGludG8gc29tZXRoaW5nIG5vbiBjb252ZXguCisgICAgdmVydGV4X3QgYnVmZmVyW01BWF9DTElQUElOR19QTEFORVMgKiAyICsgMV07ICAgLy8gfjNLQgorICAgIHZlcnRleF90KiBidWYgPSBidWZmZXI7CisKKyAgICAvLyBvcmlnaW5hbCBsaXN0IG9mIHZlcnRpY2VzIChwb2x5Z29uIHRvIGNsaXAsIGluIGZhY3QgdGhpcworICAgIC8vIGZ1bmN0aW9uIHdvcmtzIHdpdGggYW4gYXJiaXRyYXJ5IHBvbHlnb24pLgorICAgIHZlcnRleF90KiBpblszXSA9IHsgdjAsIHYxLCB2MiB9OworICAgIAorICAgIC8vIG91dHB1dCBsaXN0cyAod2UgbmVlZCAyLCB3aGljaCB3ZSB1c2UgYmFjayBhbmQgZm9ydGgpCisgICAgLy8gKG1heGltdW0gb3V0cG91dCBsaXN0J3Mgc2l6ZSBpcyBNQVhfQ0xJUFBJTkdfUExBTkVTICsgTUFYX1ZFUlRJQ0VTKQorICAgIC8vIDIgbW9yZSBlbGVtZW50cyBmb3Igb3ZlcmZsb3cgd2hlbiBub24gY29udmV4IHBvbHlnb25zLgorICAgIHZlcnRleF90KiBvdXRbMl1bTUFYX0NMSVBQSU5HX1BMQU5FUyArIE1BWF9WRVJUSUNFUyArIDJdOworICAgIHVuc2lnbmVkIGludCBvdXRpID0gMDsKKyAgICAKKyAgICAvLyBjdXJyZW50IGlucHV0IGxpc3QKKyAgICB2ZXJ0ZXhfdCoqIGl2bCA9IGluOworCisgICAgLy8gMyBpbnB1dCB2ZXJ0aWNlcywgMCBpbiB0aGUgb3V0cHV0IGxpc3QsIGZpcnN0IHBsYW5lCisgICAgdW5zaWduZWQgaW50IGljID0gMzsKKworICAgIC8vIFVzZXIgY2xpcC1wbGFuZXMgZmlyc3QsIHRoZSBjbGlwcGluZyBpcyBhbHdheXMgZG9uZSBpbiBleWUtY29vcmRpbmF0ZQorICAgIC8vIHRoaXMgaXMgYmFzaWNhbGx5IHRoZSBzYW1lIGFsZ29yaXRobSB0aGFuIGZvciB0aGUgdmlldy12b2x1bWUKKyAgICAvLyBjbGlwcGluZywgZXhjZXB0IGZvciB0aGUgY29tcHV0YXRpb24gb2YgdGhlIGRpc3RhbmNlICh2ZXJ0ZXgsIHBsYW5lKQorICAgIC8vIGFuZCB0aGUgZmFjdCB0aGF0IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgZXllLWNvb3JkaW5hdGVzIG9mIGVhY2gKKyAgICAvLyBuZXcgdmVydGV4IHdlIGNyZWF0ZS4KKyAgICAKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGFsbF9jYyAmIHZlcnRleF90OjpVU0VSX0NMSVBfQUxMKSkKKyAgICB7CisgICAgICAgIHVuc2lnbmVkIGludCBwbGFuZSA9IDA7CisgICAgICAgIHVpbnQzMl90IGNjID0gKGFsbF9jYyAmIHZlcnRleF90OjpVU0VSX0NMSVBfQUxMKSA+PiA4OworICAgICAgICBkbyB7CisgICAgICAgICAgICBpZiAoY2MgJiAxKSB7ICAgICAgICAKKyAgICAgICAgICAgICAgICAvLyBwb2ludGVycyB0byBvdXIgb3V0cHV0IGxpc3QgKGhlYWQgYW5kIGN1cnJlbnQpCisgICAgICAgICAgICAgICAgdmVydGV4X3QqKiBjb25zdCBvdmwgPSAmb3V0W291dGldWzBdOworICAgICAgICAgICAgICAgIHZlcnRleF90Kiogb3V0cHV0ID0gb3ZsOworICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBvYyA9IDA7CisgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHNlbnRpbmVsID0gMDsKKyAgICAgICAgICAgICAgICAvLyBwcmV2aW91cyB2ZXJ0ZXgsIGNvbXB1dGUgZGlzdGFuY2UgdG8gdGhlIHBsYW5lCisgICAgICAgICAgICAgICAgdmVydGV4X3QqIHMgPSBpdmxbaWMtMV07CisgICAgICAgICAgICAgICAgY29uc3QgdmVjNF90JiBlcXVhdGlvbiA9IGMtPmNsaXBQbGFuZXMucGxhbmVbcGxhbmVdLmVxdWF0aW9uOworICAgICAgICAgICAgICAgIEdMZml4ZWQgc2QgPSBkb3Q0KGVxdWF0aW9uLnYsIHMtPmV5ZS52KTsKKyAgICAgICAgICAgICAgICAvLyBjbGlwIGVhY2ggdmVydGV4IGFnYWluc3QgdGhpcyBwbGFuZS4uLgorICAgICAgICAgICAgICAgIGZvciAodW5zaWduZWQgaW50IGk9MCA7IGk8aWMgOyBpKyspIHsgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgdmVydGV4X3QqIHAgPSBpdmxbaV07CisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgcGQgPSBkb3Q0KGVxdWF0aW9uLnYsIHAtPmV5ZS52KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNkID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBpbnNpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHMgaW5zaWRlLCBwIG91dHNpZGUgKGV4aXRpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCB0ID0gY2xpcERpdmlkZShzZCwgc2QtcGQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMtPmFycmF5cy5jbGlwRXllKGMsIGJ1ZiwgdCwgcCwgcyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm91dHB1dCsrID0gYnVmKys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2MrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKytzZW50aW5lbCA+PSAzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIG5vbi1jb252ZXggcG9seWdvbiEKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcyBvdXRzaWRlIChlbnRlcmluZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCB0ID0gY2xpcERpdmlkZShwZCwgcGQtc2QpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLT5hcnJheXMuY2xpcEV5ZShjLCBidWYsIHQsIHMsIHApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBidWYrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2MrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrc2VudGluZWwgPj0gMykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgLy8gbm9uLWNvbnZleCBwb2x5Z29uIQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBvdXRzaWRlCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcyA9IHA7CisgICAgICAgICAgICAgICAgICAgIHNkID0gcGQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIG91dHB1dCBsaXN0IGJlY29tZSB0aGUgbmV3IGlucHV0IGxpc3QKKyAgICAgICAgICAgICAgICBpZiAob2M8MykKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBsZXNzIHRoYW4gMyB2ZXJ0aWNlcyBsZWZ0PyB3ZSdyZSBkb25lIQorICAgICAgICAgICAgICAgIGl2bCA9IG92bDsKKyAgICAgICAgICAgICAgICBpYyA9IG9jOworICAgICAgICAgICAgICAgIG91dGkgPSAxLW91dGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYyA+Pj0gMTsKKyAgICAgICAgICAgIHBsYW5lKys7CisgICAgICAgIH0gd2hpbGUgKGNjKTsKKyAgICB9CisKKyAgICAvLyBmcnVzdHVtIGNsaXAtcGxhbmVzCisgICAgaWYgKGFsbF9jYyAmIHZlcnRleF90OjpGUlVTVFVNX0NMSVBfQUxMKQorICAgIHsKKyAgICAgICAgdW5zaWduZWQgaW50IHBsYW5lID0gMDsKKyAgICAgICAgdWludDMyX3QgY2MgPSBhbGxfY2MgJiB2ZXJ0ZXhfdDo6RlJVU1RVTV9DTElQX0FMTDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaWYgKGNjICYgMSkgeyAgICAgICAgCisgICAgICAgICAgICAgICAgLy8gcG9pbnRlcnMgdG8gb3VyIG91dHB1dCBsaXN0IChoZWFkIGFuZCBjdXJyZW50KQorICAgICAgICAgICAgICAgIHZlcnRleF90KiogY29uc3Qgb3ZsID0gJm91dFtvdXRpXVswXTsKKyAgICAgICAgICAgICAgICB2ZXJ0ZXhfdCoqIG91dHB1dCA9IG92bDsKKyAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgb2MgPSAwOworICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBzZW50aW5lbCA9IDA7CisgICAgICAgICAgICAgICAgLy8gcHJldmlvdXMgdmVydGV4LCBjb21wdXRlIGRpc3RhbmNlIHRvIHRoZSBwbGFuZQorICAgICAgICAgICAgICAgIHZlcnRleF90KiBzID0gaXZsW2ljLTFdOworICAgICAgICAgICAgICAgIEdMZml4ZWQgc2QgPSBmcnVzdHVtUGxhbmVEaXN0KHBsYW5lLCBzLT5jbGlwKTsKKyAgICAgICAgICAgICAgICAvLyBjbGlwIGVhY2ggdmVydGV4IGFnYWluc3QgdGhpcyBwbGFuZS4uLgorICAgICAgICAgICAgICAgIGZvciAodW5zaWduZWQgaW50IGk9MCA7IGk8aWMgOyBpKyspIHsgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgdmVydGV4X3QqIHAgPSBpdmxbaV07CisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgcGQgPSBmcnVzdHVtUGxhbmVEaXN0KHBsYW5lLCBwLT5jbGlwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNkID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBpbnNpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHMgaW5zaWRlLCBwIG91dHNpZGUgKGV4aXRpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCB0ID0gY2xpcERpdmlkZShzZCwgc2QtcGQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMtPmFycmF5cy5jbGlwVmVydGV4KGMsIGJ1ZiwgdCwgcCwgcyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm91dHB1dCsrID0gYnVmKys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2MrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKytzZW50aW5lbCA+PSAzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIG5vbi1jb252ZXggcG9seWdvbiEKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcyBvdXRzaWRlIChlbnRlcmluZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCB0ID0gY2xpcERpdmlkZShwZCwgcGQtc2QpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLT5hcnJheXMuY2xpcFZlcnRleChjLCBidWYsIHQsIHMsIHApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBidWYrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2MrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrc2VudGluZWwgPj0gMykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgLy8gbm9uLWNvbnZleCBwb2x5Z29uIQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqb3V0cHV0KysgPSBwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBvdXRzaWRlCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcyA9IHA7CisgICAgICAgICAgICAgICAgICAgIHNkID0gcGQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIG91dHB1dCBsaXN0IGJlY29tZSB0aGUgbmV3IGlucHV0IGxpc3QKKyAgICAgICAgICAgICAgICBpZiAob2M8MykKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBsZXNzIHRoYW4gMyB2ZXJ0aWNlcyBsZWZ0PyB3ZSdyZSBkb25lIQorICAgICAgICAgICAgICAgIGl2bCA9IG92bDsKKyAgICAgICAgICAgICAgICBpYyA9IG9jOworICAgICAgICAgICAgICAgIG91dGkgPSAxLW91dGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYyA+Pj0gMTsKKyAgICAgICAgICAgIHBsYW5lKys7CisgICAgICAgIH0gd2hpbGUgKGNjKTsKKyAgICB9CisgICAgCisgICAgLy8gZmluYWxseSB3ZSBjYW4gcmVuZGVyIG91ciB0cmlhbmdsZXMuLi4KKyAgICBwMCA9IGl2bFswXTsKKyAgICBwMSA9IGl2bFsxXTsKKyAgICBmb3IgKHVuc2lnbmVkIGludCBpPTIgOyBpPGljIDsgaSsrKSB7CisgICAgICAgIHAyID0gaXZsW2ldOworICAgICAgICBjLT5sZXJwLmluaXRUcmlhbmdsZShwMCwgcDEsIHAyKTsKKyAgICAgICAgaWYgKGN1bGxfdHJpYW5nbGUoYywgcDAsIHAxLCBwMikpIHsKKyAgICAgICAgICAgIHAxID0gcDI7CisgICAgICAgICAgICBjb250aW51ZTsgLy8gY3VsbGVkIQorICAgICAgICB9CisgICAgICAgIHRyaWFuZ2xlKGMsIHAwLCBwMSwgcDIpOworICAgICAgICBwMSA9IHAyOworICAgIH0KK30KKwordW5zaWduZWQgaW50IGNsaXBfbGluZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiBzLCB2ZXJ0ZXhfdCogcCkKK3sKKyAgICBjb25zdCB1aW50MzJfdCBhbGxfY2MgPSAocy0+ZmxhZ3MgfCBwLT5mbGFncykgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEw7CisKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGFsbF9jYyAmIHZlcnRleF90OjpVU0VSX0NMSVBfQUxMKSkKKyAgICB7CisgICAgICAgIHVuc2lnbmVkIGludCBwbGFuZSA9IDA7CisgICAgICAgIHVpbnQzMl90IGNjID0gKGFsbF9jYyAmIHZlcnRleF90OjpVU0VSX0NMSVBfQUxMKSA+PiA4OworICAgICAgICBkbyB7CisgICAgICAgICAgICBpZiAoY2MgJiAxKSB7CisgICAgICAgICAgICAgICAgY29uc3QgdmVjNF90JiBlcXVhdGlvbiA9IGMtPmNsaXBQbGFuZXMucGxhbmVbcGxhbmVdLmVxdWF0aW9uOworICAgICAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgc2QgPSBkb3Q0KGVxdWF0aW9uLnYsIHMtPmV5ZS52KTsKKyAgICAgICAgICAgICAgICBjb25zdCBHTGZpeGVkIHBkID0gZG90NChlcXVhdGlvbi52LCBwLT5leWUudik7CisgICAgICAgICAgICAgICAgaWYgKHNkID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBkID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJvdGggaW5zaWRlCisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzIGluc2lkZSwgcCBvdXRzaWRlIChleGl0aW5nKQorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCB0ID0gY2xpcERpdmlkZShzZCwgc2QtcGQpOworICAgICAgICAgICAgICAgICAgICAgICAgYy0+YXJyYXlzLmNsaXBFeWUoYywgcCwgdCwgcCwgcyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAocGQgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gcyBvdXRzaWRlIChlbnRlcmluZykKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgdCA9IGNsaXBEaXZpZGUocGQsIHBkLXNkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLT5hcnJheXMuY2xpcEV5ZShjLCBzLCB0LCBzLCBwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBvdXRzaWRlCisgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgY2MgPj49IDE7CisgICAgICAgICAgICBwbGFuZSsrOworICAgICAgICB9IHdoaWxlIChjYyk7CisgICAgfQorCisgICAgLy8gZnJ1c3R1bSBjbGlwLXBsYW5lcworICAgIGlmIChhbGxfY2MgJiB2ZXJ0ZXhfdDo6RlJVU1RVTV9DTElQX0FMTCkKKyAgICB7CisgICAgICAgIHVuc2lnbmVkIGludCBwbGFuZSA9IDA7CisgICAgICAgIHVpbnQzMl90IGNjID0gYWxsX2NjICYgdmVydGV4X3Q6OkZSVVNUVU1fQ0xJUF9BTEw7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGlmIChjYyAmIDEpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBHTGZpeGVkIHNkID0gZnJ1c3R1bVBsYW5lRGlzdChwbGFuZSwgcy0+Y2xpcCk7CisgICAgICAgICAgICAgICAgY29uc3QgR0xmaXhlZCBwZCA9IGZydXN0dW1QbGFuZURpc3QocGxhbmUsIHAtPmNsaXApOworICAgICAgICAgICAgICAgIGlmIChzZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChwZCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBib3RoIGluc2lkZQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gcyBpbnNpZGUsIHAgb3V0c2lkZSAoZXhpdGluZykKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdMZml4ZWQgdCA9IGNsaXBEaXZpZGUoc2QsIHNkLXBkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGMtPmFycmF5cy5jbGlwVmVydGV4KGMsIHAsIHQsIHAsIHMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBkID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHMgb3V0c2lkZSAoZW50ZXJpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBHTGZpeGVkIHQgPSBjbGlwRGl2aWRlKHBkLCBwZC1zZCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy0+YXJyYXlzLmNsaXBWZXJ0ZXgoYywgcywgdCwgcywgcCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgIC8vIGJvdGggb3V0c2lkZQorICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNjID4+PSAxOworICAgICAgICAgICAgcGxhbmUrKzsKKyAgICAgICAgfSB3aGlsZSAoY2MpOworICAgIH0KKworICAgIHJldHVybiAyOworfQorCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL3ByaW1pdGl2ZXMuaCBiL29wZW5nbC9saWJhZ2wvcHJpbWl0aXZlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiZWY2MDQKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL3ByaW1pdGl2ZXMuaApAQCAtMCwwICsxLDM3IEBACisvKiBsaWJzL29wZW5nbGVzL3ByaW1pdGl2ZXMuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19QUklNSVRJVkVTX0gKKyNkZWZpbmUgQU5EUk9JRF9PUEVOR0xFU19QUklNSVRJVkVTX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKworbmFtZXNwYWNlIGdsIHsKK3N0cnVjdCBvZ2xlc19jb250ZXh0X3Q7Cit9OworCit2b2lkIG9nbGVzX3ZhbGlkYXRlX3ByaW1pdGl2ZXMob2dsZXNfY29udGV4dF90KiBjKTsKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfT1BFTkdMRVNfUFJJTUlUSVZFU19ICisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvc3RhdGUuY3BwIGIvb3BlbmdsL2xpYmFnbC9zdGF0ZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWNiYWJlYQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvc3RhdGUuY3BwCkBAIC0wLDAgKzEsNTg2IEBACisvKiBsaWJzL29wZW5nbGVzL3N0YXRlLmNwcAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworI2luY2x1ZGUgImNvbnRleHQuaCIKKyNpbmNsdWRlICJmcC5oIgorI2luY2x1ZGUgInN0YXRlLmgiCisjaW5jbHVkZSAiYXJyYXkuaCIKKyNpbmNsdWRlICJtYXRyaXguaCIKKyNpbmNsdWRlICJ2ZXJ0ZXguaCIKKyNpbmNsdWRlICJsaWdodC5oIgorI2luY2x1ZGUgInRleHR1cmUuaCIKKyNpbmNsdWRlICJCdWZmZXJPYmplY3RNYW5hZ2VyLmgiCisjaW5jbHVkZSAiVGV4dHVyZU9iamVjdE1hbmFnZXIuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBjaGFyIGNvbnN0ICogY29uc3QgZ1ZlbmRvclN0cmluZyAgICAgPSAiQW5kcm9pZCI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdSZW5kZXJlclN0cmluZyAgID0gIkFuZHJvaWQgUGl4ZWxGbGluZ2VyIDEuMCI7CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdWZXJzaW9uU3RyaW5nICAgID0gIk9wZW5HTCBFUy1DTSAxLjAiOworc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBnRXh0ZW5zaW9uc1N0cmluZyA9CisgICAgIkdMX09FU19ieXRlX2Nvb3JkaW5hdGVzICIgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19maXhlZF9wb2ludCAiICAgICAgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19zaW5nbGVfcHJlY2lzaW9uICIgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19yZWFkX2Zvcm1hdCAiICAgICAgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19jb21wcmVzc2VkX3BhbGV0dGVkX3RleHR1cmUgIiAgIC8vIE9LCisgICAgIkdMX09FU19kcmF3X3RleHR1cmUgIiAgICAgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19tYXRyaXhfZ2V0ICIgICAgICAgICAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX09FU19xdWVyeV9tYXRyaXggIiAgICAgICAgICAgICAgICAgIC8vIE9LCisgICAgLy8gICAgICAgICJHTF9PRVNfcG9pbnRfc2l6ZV9hcnJheSAiICAgICAgICAgICAgICAvLyBUT0RPCisgICAgLy8gICAgICAgICJHTF9PRVNfcG9pbnRfc3ByaXRlICIgICAgICAgICAgICAgICAgICAvLyBUT0RPCisgICAgIkdMX0FSQl90ZXh0dXJlX2NvbXByZXNzaW9uICIgICAgICAgICAgIC8vIE9LCisgICAgIkdMX0FSQl90ZXh0dXJlX25vbl9wb3dlcl9vZl90d28gIiAgICAgIC8vIE9LCisgICAgIkdMX0FORFJPSURfZGlyZWN0X3RleHR1cmUgIiAgICAgICAgICAgIC8vIE9LCisgICAgIkdMX0FORFJPSURfdXNlcl9jbGlwX3BsYW5lICIgICAgICAgICAgIC8vIE9LCisgICAgIkdMX0FORFJPSURfdmVydGV4X2J1ZmZlcl9vYmplY3QgIiAgICAgIC8vIE9LCisgICAgIkdMX0FORFJPSURfZ2VuZXJhdGVfbWlwbWFwICIgICAgICAgICAgIC8vIE9LCisgICAgOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCitvZ2xlc19jb250ZXh0X3QgKm9nbGVzX2luaXQoc2l6ZV90IGV4dHJhKQoreworICAgIHZvaWQqIGNvbnN0IGJhc2UgPSBtYWxsb2MoZXh0cmEgKyBzaXplb2Yob2dsZXNfY29udGV4dF90KSArIDMyKTsKKwlpZiAoIWJhc2UpIHJldHVybiAwOworCisgICAgb2dsZXNfY29udGV4dF90ICpjID0KKyAgICAgICAgICAgIChvZ2xlc19jb250ZXh0X3QgKikoKHB0cmRpZmZfdChiYXNlKSArIGV4dHJhICsgMzEpICYgfjB4MUZMKTsKKyAgICBtZW1zZXQoYywgMCwgc2l6ZW9mKG9nbGVzX2NvbnRleHRfdCkpOworICAgIGdnbF9pbml0X2NvbnRleHQoJihjLT5yYXN0ZXJpemVyKSk7CisgICAgCisgICAgLy8gWFhYOiB0aGlzIHNob3VsZCBiZSBwYXNzZWQgYXMgYW4gYXJndW1lbnQKKyAgICBzcDxFR0xTdXJmYWNlTWFuYWdlcj4gc21ncihuZXcgRUdMU3VyZmFjZU1hbmFnZXIoKSk7CisgICAgYy0+c3VyZmFjZU1hbmFnZXIgPSBzbWdyLmdldCgpOworICAgIGMtPnN1cmZhY2VNYW5hZ2VyLT5pbmNTdHJvbmcoYyk7CisKKyAgICBzcDxFR0xCdWZmZXJPYmplY3RNYW5hZ2VyPiBib21ncihuZXcgRUdMQnVmZmVyT2JqZWN0TWFuYWdlcigpKTsKKyAgICBjLT5idWZmZXJPYmplY3RNYW5hZ2VyID0gYm9tZ3IuZ2V0KCk7CisgICAgYy0+YnVmZmVyT2JqZWN0TWFuYWdlci0+aW5jU3Ryb25nKGMpOworCisgICAgb2dsZXNfaW5pdF9hcnJheShjKTsKKyAgICBvZ2xlc19pbml0X21hdHJpeChjKTsKKyAgICBvZ2xlc19pbml0X3ZlcnRleChjKTsKKyAgICBvZ2xlc19pbml0X2xpZ2h0KGMpOworICAgIG9nbGVzX2luaXRfdGV4dHVyZShjKTsKKworICAgIGMtPnJhc3Rlcml6ZXIuYmFzZSA9IGJhc2U7CisgICAgYy0+cG9pbnQuc2l6ZSA9IFRSSV9PTkU7CisgICAgYy0+bGluZS53aWR0aCA9IFRSSV9PTkU7CisgICAgICAgICAgICAKKyAgICAvLyBpbiBPcGVuR0wsIHdyaXRpbmcgdG8gdGhlIGRlcHRoIGJ1ZmZlciBpcyBlbmFibGVkIGJ5IGRlZmF1bHQuCisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5kZXB0aE1hc2soYywgMSk7CisgICAgCisgICAgLy8gT3BlbkdMIGVuYWJsZXMgZGl0aGVyaW5nIGJ5IGRlZmF1bHQKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmVuYWJsZShjLCBHTF9ESVRIRVIpOworCisgICAgcmV0dXJuIGM7Cit9CisKK3ZvaWQgb2dsZXNfdW5pbml0KG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBvZ2xlc191bmluaXRfYXJyYXkoYyk7CisgICAgb2dsZXNfdW5pbml0X21hdHJpeChjKTsKKyAgICBvZ2xlc191bmluaXRfdmVydGV4KGMpOworICAgIG9nbGVzX3VuaW5pdF9saWdodChjKTsKKyAgICBvZ2xlc191bmluaXRfdGV4dHVyZShjKTsKKyAgICBjLT5zdXJmYWNlTWFuYWdlci0+ZGVjU3Ryb25nKGMpOworICAgIGMtPmJ1ZmZlck9iamVjdE1hbmFnZXItPmRlY1N0cm9uZyhjKTsKKyAgICBnZ2xfdW5pbml0X2NvbnRleHQoJihjLT5yYXN0ZXJpemVyKSk7CisJZnJlZShjLT5yYXN0ZXJpemVyLmJhc2UpOworfQorCit2b2lkIF9vZ2xlc19lcnJvcihvZ2xlc19jb250ZXh0X3QqIGMsIEdMZW51bSBlcnJvcikKK3sKKyAgICBpZiAoYy0+ZXJyb3IgPT0gR0xfTk9fRVJST1IpCisgICAgICAgIGMtPmVycm9yID0gZXJyb3I7Cit9CisKK3N0YXRpYyBib29sIHN0ZW5jaWxvcF92YWxpZChHTGVudW0gb3ApIHsKKyAgICBzd2l0Y2ggKG9wKSB7CisgICAgY2FzZSBHTF9LRUVQOgorICAgIGNhc2UgR0xfWkVSTzoKKyAgICBjYXNlIEdMX1JFUExBQ0U6CisgICAgY2FzZSBHTF9JTkNSOgorICAgIGNhc2UgR0xfREVDUjoKKyAgICBjYXNlIEdMX0lOVkVSVDoKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKK30KKworc3RhdGljIHZvaWQgZW5hYmxlX2Rpc2FibGUob2dsZXNfY29udGV4dF90KiBjLCBHTGVudW0gY2FwLCBpbnQgZW5hYmxlZCkKK3sKKyAgICBpZiAoKGNhcCA+PSBHTF9MSUdIVDApICYmIChjYXA8R0xfTElHSFQwK09HTEVTX01BWF9MSUdIVFMpKSB7CisgICAgICAgIGMtPmxpZ2h0aW5nLmxpZ2h0c1tjYXAtR0xfTElHSFQwXS5lbmFibGUgPSBlbmFibGVkOworICAgICAgICBjLT5saWdodGluZy5lbmFibGVkTGlnaHRzICY9IH4oMTw8KGNhcC1HTF9MSUdIVDApKTsKKyAgICAgICAgYy0+bGlnaHRpbmcuZW5hYmxlZExpZ2h0cyB8PSAoZW5hYmxlZDw8KGNhcC1HTF9MSUdIVDApKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHN3aXRjaCAoY2FwKSB7CisgICAgY2FzZSBHTF9QT0lOVF9TTU9PVEg6CisgICAgICAgIGMtPnBvaW50LnNtb290aCA9IGVuYWJsZWQ7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTElORV9TTU9PVEg6CisgICAgICAgIGMtPmxpbmUuc21vb3RoID0gZW5hYmxlZDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9QT0xZR09OX09GRlNFVF9GSUxMOgorICAgICAgICBjLT5wb2x5Z29uT2Zmc2V0LmVuYWJsZSA9IGVuYWJsZWQ7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfQ1VMTF9GQUNFOgorICAgICAgICBjLT5jdWxsLmVuYWJsZSA9IGVuYWJsZWQ7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTElHSFRJTkc6CisgICAgICAgIGMtPmxpZ2h0aW5nLmVuYWJsZSA9IGVuYWJsZWQ7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfQ09MT1JfTUFURVJJQUw6CisgICAgICAgIGMtPmxpZ2h0aW5nLmNvbG9yTWF0ZXJpYWwuZW5hYmxlID0gZW5hYmxlZDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9OT1JNQUxJWkU6CisgICAgY2FzZSBHTF9SRVNDQUxFX05PUk1BTDoKKyAgICAgICAgYy0+dHJhbnNmb3Jtcy5yZXNjYWxlTm9ybWFscyA9IGVuYWJsZWQgPyBjYXAgOiAwOworICAgICAgICAvLyBYWFg6IGludmFsaWRhdGUgbXZpdAorICAgICAgICBicmVhazsKKworICAgIGNhc2UgR0xfQ0xJUF9QTEFORTA6CisgICAgY2FzZSBHTF9DTElQX1BMQU5FMToKKyAgICBjYXNlIEdMX0NMSVBfUExBTkUyOgorICAgIGNhc2UgR0xfQ0xJUF9QTEFORTM6CisgICAgY2FzZSBHTF9DTElQX1BMQU5FNDoKKyAgICBjYXNlIEdMX0NMSVBfUExBTkU1OgorICAgICAgICBjLT5jbGlwUGxhbmVzLmVuYWJsZSAmPSB+KDE8PChjYXAtR0xfQ0xJUF9QTEFORTApKTsKKyAgICAgICAgYy0+Y2xpcFBsYW5lcy5lbmFibGUgfD0gKGVuYWJsZWQ8PChjYXAtR0xfQ0xJUF9QTEFORTApKTsKKyAgICAgICAgb2dsZXNfaW52YWxpZGF0ZV9wZXJzcGVjdGl2ZShjKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEdMX0ZPRzoKKyAgICBjYXNlIEdMX0RFUFRIX1RFU1Q6CisgICAgICAgIG9nbGVzX2ludmFsaWRhdGVfcGVyc3BlY3RpdmUoYyk7CisgICAgICAgIC8vIGZhbGwtdGhyb3VnaC4uLgorICAgIGNhc2UgR0xfQkxFTkQ6CisgICAgY2FzZSBHTF9TQ0lTU09SX1RFU1Q6CisgICAgY2FzZSBHTF9BTFBIQV9URVNUOgorICAgIGNhc2UgR0xfQ09MT1JfTE9HSUNfT1A6CisgICAgY2FzZSBHTF9ESVRIRVI6CisgICAgY2FzZSBHTF9TVEVOQ0lMX1RFU1Q6CisgICAgY2FzZSBHTF9URVhUVVJFXzJEOgorICAgICAgICAvLyB0aGVzZSBuZWVkIHRvIGZhbGwgdGhyb3VnaCBpbnRvIHRoZSByYXN0ZXJpemVyCisgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZW5hYmxlRGlzYWJsZShjLCBjYXAsIGVuYWJsZWQpOworICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgY2FzZSBHTF9NVUxUSVNBTVBMRToKKyAgICBjYXNlIEdMX1NBTVBMRV9BTFBIQV9UT19DT1ZFUkFHRToKKyAgICBjYXNlIEdMX1NBTVBMRV9BTFBIQV9UT19PTkU6CisgICAgY2FzZSBHTF9TQU1QTEVfQ09WRVJBR0U6CisgICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbgorICAgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjZW5kaWYKKworLy8gVGhlc2Ugb25lcyBhcmUgc3VwZXItZWFzeSwgd2UncmUgbm90IHN1cHBvcnRpbmcgdGhvc2UgZmVhdHVyZXMhCit2b2lkIGdsU2FtcGxlQ292ZXJhZ2UoR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpIHsKK30KK3ZvaWQgZ2xTYW1wbGVDb3ZlcmFnZXgoR0xjbGFtcHggdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpIHsKK30KK3ZvaWQgZ2xTdGVuY2lsRnVuYyhHTGVudW0gZnVuYywgR0xpbnQgcmVmLCBHTHVpbnQgbWFzaykgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKGZ1bmMgPCBHTF9ORVZFUiB8fCBmdW5jID4gR0xfQUxXQVlTKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gZnJvbSBPcGVuR0x8RVMgMS4wIHNlcGNpZmljYXRpb246CisgICAgLy8gSWYgdGhlcmUgaXMgbm8gc3RlbmNpbCBidWZmZXIsIG5vIHN0ZW5jaWwgbW9kaWZpY2F0aW9uIGNhbiBvY2N1cgorICAgIC8vIGFuZCBpdCBpcyBhcyBpZiB0aGUgc3RlbmNpbCB0ZXN0IGFsd2F5cyBwYXNzZXMuCit9CisKK3ZvaWQgZ2xTdGVuY2lsT3AoR0xlbnVtIGZhaWwsIEdMZW51bSB6ZmFpbCwgR0xlbnVtIHpwYXNzKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoKHN0ZW5jaWxvcF92YWxpZChmYWlsKSAmCisgICAgICAgICBzdGVuY2lsb3BfdmFsaWQoemZhaWwpICYKKyAgICAgICAgIHN0ZW5jaWxvcF92YWxpZCh6cGFzcykpID09IDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIGdsQWxwaGFGdW5jKEdMZW51bSBmdW5jLCBHTGNsYW1wZiByZWYpCit7CisgICAgZ2xBbHBoYUZ1bmN4KGZ1bmMsIGdnbEZsb2F0VG9GaXhlZChyZWYpKTsKK30KKwordm9pZCBnbEN1bGxGYWNlKEdMZW51bSBtb2RlKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgc3dpdGNoIChtb2RlKSB7CisgICAgY2FzZSBHTF9GUk9OVDoKKyAgICBjYXNlIEdMX0JBQ0s6CisgICAgY2FzZSBHTF9GUk9OVF9BTkRfQkFDSzoKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICB9CisgICAgYy0+Y3VsbC5jdWxsRmFjZSA9IG1vZGU7Cit9CisKK3ZvaWQgZ2xGcm9udEZhY2UoR0xlbnVtIG1vZGUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICBjYXNlIEdMX0NXOgorICAgIGNhc2UgR0xfQ0NXOgorICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPmN1bGwuZnJvbnRGYWNlID0gbW9kZTsKK30KKwordm9pZCBnbEhpbnQoR0xlbnVtIHRhcmdldCwgR0xlbnVtIG1vZGUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBzd2l0Y2ggKHRhcmdldCkgeworICAgIGNhc2UgR0xfRk9HX0hJTlQ6CisgICAgY2FzZSBHTF9HRU5FUkFURV9NSVBNQVBfSElOVDoKKyAgICBjYXNlIEdMX0xJTkVfU01PT1RIX0hJTlQ6CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfUE9JTlRfU01PT1RIX0hJTlQ6CisgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZW5hYmxlRGlzYWJsZShjLCAKKyAgICAgICAgICAgICAgICBHR0xfUE9JTlRfU01PT1RIX05JQ0UsIG1vZGU9PUdMX05JQ0VTVCk7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfUEVSU1BFQ1RJVkVfQ09SUkVDVElPTl9ISU5UOgorICAgICAgICBjLT5wZXJzcGVjdGl2ZSA9IChtb2RlID09IEdMX05JQ0VTVCkgPyAxIDogMDsKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICB9Cit9CisKK3ZvaWQgZ2xFbmFibGUoR0xlbnVtIGNhcCkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZW5hYmxlX2Rpc2FibGUoYywgY2FwLCAxKTsKK30KK3ZvaWQgZ2xEaXNhYmxlKEdMZW51bSBjYXApIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGVuYWJsZV9kaXNhYmxlKGMsIGNhcCwgMCk7Cit9CisKK3ZvaWQgZ2xGaW5pc2goKQoreyAvLyBub3RoaW5nIHRvIGRvIGZvciBvdXIgc29mdHdhcmUgaW1wbGVtZW50YXRpb24KK30KKwordm9pZCBnbEZsdXNoKCkKK3sgLy8gbm90aGluZyB0byBkbyBmb3Igb3VyIHNvZnR3YXJlIGltcGxlbWVudGF0aW9uCit9CisKK0dMZW51bSBnbEdldEVycm9yKCkKK3sKKyAgICAvLyBGcm9tIE9wZW5HTHxFUyAxLjAgc3BlY2lmaWNhdGlvbjoKKyAgICAvLyBJZiBtb3JlIHRoYW4gb25lIGZsYWcgaGFzIHJlY29yZGVkIGFuIGVycm9yLCBnbEdldEVycm9yIHJldHVybnMKKyAgICAvLyBhbmQgY2xlYXJzIGFuIGFyYml0cmFyeSBlcnJvciBmbGFnIHZhbHVlLiBUaHVzLCBnbEdldEVycm9yIHNob3VsZAorICAgIC8vIGFsd2F5cyBiZSBjYWxsZWQgaW4gYSBsb29wLCB1bnRpbCBpdCByZXR1cm5zIEdMX05PX0VSUk9SLAorICAgIC8vIGlmIGFsbCBlcnJvciBmbGFncyBhcmUgdG8gYmUgcmVzZXQuCisKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChjLT5lcnJvcikgeworICAgICAgICBjb25zdCBHTGVudW0gcmV0KGMtPmVycm9yKTsKKyAgICAgICAgYy0+ZXJyb3IgPSAwOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKyAgICAKKyAgICBpZiAoYy0+cmFzdGVyaXplci5lcnJvcikgeworICAgICAgICBjb25zdCBHTGVudW0gcmV0KGMtPnJhc3Rlcml6ZXIuZXJyb3IpOworICAgICAgICBjLT5yYXN0ZXJpemVyLmVycm9yID0gMDsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICByZXR1cm4gR0xfTk9fRVJST1I7Cit9CisKK2NvbnN0IEdMdWJ5dGUqIGdsR2V0U3RyaW5nKEdMZW51bSBzdHJpbmcpCit7CisgICAgc3dpdGNoIChzdHJpbmcpIHsKKyAgICBjYXNlIEdMX1ZFTkRPUjogICAgIHJldHVybiAoY29uc3QgR0x1Ynl0ZSopZ1ZlbmRvclN0cmluZzsKKyAgICBjYXNlIEdMX1JFTkRFUkVSOiAgIHJldHVybiAoY29uc3QgR0x1Ynl0ZSopZ1JlbmRlcmVyU3RyaW5nOworICAgIGNhc2UgR0xfVkVSU0lPTjogICAgcmV0dXJuIChjb25zdCBHTHVieXRlKilnVmVyc2lvblN0cmluZzsKKyAgICBjYXNlIEdMX0VYVEVOU0lPTlM6IHJldHVybiAoY29uc3QgR0x1Ynl0ZSopZ0V4dGVuc2lvbnNTdHJpbmc7CisgICAgfQorICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICByZXR1cm4gMDsKK30KKwordm9pZCBnbEdldEludGVnZXJ2KEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcykKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIHN3aXRjaCAocG5hbWUpIHsKKyAgICBjYXNlIEdMX0FMSUFTRURfUE9JTlRfU0laRV9SQU5HRToKKyAgICAgICAgcGFyYW1zWzBdID0gMDsKKyAgICAgICAgcGFyYW1zWzFdID0gR0dMX01BWF9BTElBU0VEX1BPSU5UX1NJWkU7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfQUxJQVNFRF9MSU5FX1dJRFRIX1JBTkdFOgorICAgICAgICBwYXJhbXNbMF0gPSAwOworICAgICAgICBwYXJhbXNbMV0gPSBHR0xfTUFYX0FMSUFTRURfUE9JTlRfU0laRTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9BTFBIQV9CSVRTOiB7CisgICAgICAgIGludCBpbmRleCA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuYnVmZmVycy5jb2xvci5mb3JtYXQ7CisgICAgICAgIEdHTEZvcm1hdCBjb25zdCAqIGZvcm1hdHMgPSBnZ2xHZXRQaXhlbEZvcm1hdFRhYmxlKCk7CisgICAgICAgIHBhcmFtc1swXSA9IGZvcm1hdHNbaW5kZXhdLmFoIC0gZm9ybWF0c1tpbmRleF0uYWw7CisgICAgICAgIGJyZWFrOyAKKyAgICAgICAgfQorICAgIGNhc2UgR0xfUkVEX0JJVFM6IHsKKyAgICAgICAgaW50IGluZGV4ID0gYy0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmNvbG9yLmZvcm1hdDsKKyAgICAgICAgR0dMRm9ybWF0IGNvbnN0ICogZm9ybWF0cyA9IGdnbEdldFBpeGVsRm9ybWF0VGFibGUoKTsKKyAgICAgICAgcGFyYW1zWzBdID0gZm9ybWF0c1tpbmRleF0ucmggLSBmb3JtYXRzW2luZGV4XS5ybDsKKyAgICAgICAgYnJlYWs7IAorICAgICAgICB9CisgICAgY2FzZSBHTF9HUkVFTl9CSVRTOiB7CisgICAgICAgIGludCBpbmRleCA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuYnVmZmVycy5jb2xvci5mb3JtYXQ7CisgICAgICAgIEdHTEZvcm1hdCBjb25zdCAqIGZvcm1hdHMgPSBnZ2xHZXRQaXhlbEZvcm1hdFRhYmxlKCk7CisgICAgICAgIHBhcmFtc1swXSA9IGZvcm1hdHNbaW5kZXhdLmdoIC0gZm9ybWF0c1tpbmRleF0uZ2w7CisgICAgICAgIGJyZWFrOyAKKyAgICAgICAgfQorICAgIGNhc2UgR0xfQkxVRV9CSVRTOiB7CisgICAgICAgIGludCBpbmRleCA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuYnVmZmVycy5jb2xvci5mb3JtYXQ7CisgICAgICAgIEdHTEZvcm1hdCBjb25zdCAqIGZvcm1hdHMgPSBnZ2xHZXRQaXhlbEZvcm1hdFRhYmxlKCk7CisgICAgICAgIHBhcmFtc1swXSA9IGZvcm1hdHNbaW5kZXhdLmJoIC0gZm9ybWF0c1tpbmRleF0uYmw7CisgICAgICAgIGJyZWFrOyAKKyAgICAgICAgfQorICAgIGNhc2UgR0xfQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFM6CisgICAgICAgIHBhcmFtc1sgMF0gPSBHTF9QQUxFVFRFNF9SR0I4X09FUzsKKyAgICAgICAgcGFyYW1zWyAxXSA9IEdMX1BBTEVUVEU0X1JHQkE4X09FUzsKKyAgICAgICAgcGFyYW1zWyAyXSA9IEdMX1BBTEVUVEU0X1I1X0c2X0I1X09FUzsKKyAgICAgICAgcGFyYW1zWyAzXSA9IEdMX1BBTEVUVEU0X1JHQkE0X09FUzsKKyAgICAgICAgcGFyYW1zWyA0XSA9IEdMX1BBTEVUVEU0X1JHQjVfQTFfT0VTOworICAgICAgICBwYXJhbXNbIDVdID0gR0xfUEFMRVRURThfUkdCOF9PRVM7CisgICAgICAgIHBhcmFtc1sgNl0gPSBHTF9QQUxFVFRFOF9SR0JBOF9PRVM7CisgICAgICAgIHBhcmFtc1sgN10gPSBHTF9QQUxFVFRFOF9SNV9HNl9CNV9PRVM7CisgICAgICAgIHBhcmFtc1sgOF0gPSBHTF9QQUxFVFRFOF9SR0JBNF9PRVM7CisgICAgICAgIHBhcmFtc1sgOV0gPSBHTF9QQUxFVFRFOF9SR0I1X0ExX09FUzsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9ERVBUSF9CSVRTOgorICAgICAgICBwYXJhbXNbMF0gPSBjLT5yYXN0ZXJpemVyLnN0YXRlLmJ1ZmZlcnMuZGVwdGguZm9ybWF0ID8gMCA6IDE2OworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfRk9STUFUX09FUzoKKyAgICAgICAgcGFyYW1zWzBdID0gR0xfUkdCOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfVFlQRV9PRVM6CisgICAgICAgIHBhcmFtc1swXSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81OworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9MSUdIVFM6CisgICAgICAgIHBhcmFtc1swXSA9IE9HTEVTX01BWF9MSUdIVFM7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTUFYX0NMSVBfUExBTkVTOgorICAgICAgICBwYXJhbXNbMF0gPSBPR0xFU19NQVhfQ0xJUF9QTEFORVM7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTUFYX01PREVMVklFV19TVEFDS19ERVBUSDoKKyAgICAgICAgcGFyYW1zWzBdID0gT0dMRVNfTU9ERUxWSUVXX1NUQUNLX0RFUFRIOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9QUk9KRUNUSU9OX1NUQUNLX0RFUFRIOgorICAgICAgICBwYXJhbXNbMF0gPSBPR0xFU19QUk9KRUNUSU9OX1NUQUNLX0RFUFRIOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9URVhUVVJFX1NUQUNLX0RFUFRIOgorICAgICAgICBwYXJhbXNbMF0gPSBPR0xFU19URVhUVVJFX1NUQUNLX0RFUFRIOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9URVhUVVJFX1NJWkU6CisgICAgICAgIHBhcmFtc1swXSA9IEdHTF9NQVhfVEVYVFVSRV9TSVpFOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9URVhUVVJFX1VOSVRTOgorICAgICAgICBwYXJhbXNbMF0gPSBHR0xfVEVYVFVSRV9VTklUX0NPVU5UOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX01BWF9WSUVXUE9SVF9ESU1TOgorICAgICAgICBwYXJhbXNbMF0gPSBHR0xfTUFYX1ZJRVdQT1JUX0RJTVM7CisgICAgICAgIHBhcmFtc1sxXSA9IEdHTF9NQVhfVklFV1BPUlRfRElNUzsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9OVU1fQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFM6CisgICAgICAgIHBhcmFtc1swXSA9IE9HTEVTX05VTV9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUzsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9TTU9PVEhfTElORV9XSURUSF9SQU5HRToKKyAgICAgICAgcGFyYW1zWzBdID0gMDsKKyAgICAgICAgcGFyYW1zWzFdID0gR0dMX01BWF9TTU9PVEhfTElORV9XSURUSDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9TTU9PVEhfUE9JTlRfU0laRV9SQU5HRToKKyAgICAgICAgcGFyYW1zWzBdID0gMDsKKyAgICAgICAgcGFyYW1zWzFdID0gR0dMX01BWF9TTU9PVEhfUE9JTlRfU0laRTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9TVEVOQ0lMX0JJVFM6CisgICAgICAgIHBhcmFtc1swXSA9IDA7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfU1VCUElYRUxfQklUUzoKKyAgICAgICAgcGFyYW1zWzBdID0gR0dMX1NVQlBJWEVMX0JJVFM7CisgICAgICAgIGJyZWFrOworCisgICAgY2FzZSBHTF9NT0RFTFZJRVdfTUFUUklYX0ZMT0FUX0FTX0lOVF9CSVRTX09FUzoKKyAgICAgICAgbWVtY3B5KCBwYXJhbXMsCisgICAgICAgICAgICAgICAgYy0+dHJhbnNmb3Jtcy5tb2RlbHZpZXcudG9wKCkuZWxlbWVudHMoKSwKKyAgICAgICAgICAgICAgICAxNipzaXplb2YoR0xpbnQpKTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9QUk9KRUNUSU9OX01BVFJJWF9GTE9BVF9BU19JTlRfQklUU19PRVM6CisgICAgICAgIG1lbWNweSggcGFyYW1zLAorICAgICAgICAgICAgICAgIGMtPnRyYW5zZm9ybXMucHJvamVjdGlvbi50b3AoKS5lbGVtZW50cygpLAorICAgICAgICAgICAgICAgIDE2KnNpemVvZihHTGludCkpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1RFWFRVUkVfTUFUUklYX0ZMT0FUX0FTX0lOVF9CSVRTX09FUzoKKyAgICAgICAgbWVtY3B5KCBwYXJhbXMsCisgICAgICAgICAgICAgICAgYy0+dHJhbnNmb3Jtcy50ZXh0dXJlW2MtPnRleHR1cmVzLmFjdGl2ZV0udG9wKCkuZWxlbWVudHMoKSwKKyAgICAgICAgICAgICAgICAxNipzaXplb2YoR0xpbnQpKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICBicmVhazsKKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBnbFBvaW50U2l6ZShHTGZsb2F0IHNpemUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgYy0+cG9pbnQuc2l6ZSA9IFRSSV9GUk9NX0ZJWEVEKGdnbEZsb2F0VG9GaXhlZChzaXplKSk7Cit9CisKK3ZvaWQgZ2xQb2ludFNpemV4KEdMZml4ZWQgc2l6ZSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmIChzaXplIDw9IDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT5wb2ludC5zaXplID0gVFJJX0ZST01fRklYRUQoc2l6ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBnbExpbmVXaWR0aChHTGZsb2F0IHdpZHRoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHdpZHRoIDw9IDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT5saW5lLndpZHRoID0gVFJJX0ZST01fRklYRUQoZ2dsRmxvYXRUb0ZpeGVkKHdpZHRoKSk7Cit9CisKK3ZvaWQgZ2xMaW5lV2lkdGh4KEdMZml4ZWQgd2lkdGgpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAod2lkdGggPD0gMCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGMtPmxpbmUud2lkdGggPSBUUklfRlJPTV9GSVhFRCh3aWR0aCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBnbENvbG9yTWFzayhHTGJvb2xlYW4gciwgR0xib29sZWFuIGcsIEdMYm9vbGVhbiBiLCBHTGJvb2xlYW4gYSkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jb2xvck1hc2soYywgciwgZywgYiwgYSk7Cit9CisKK3ZvaWQgZ2xEZXB0aE1hc2soR0xib29sZWFuIGZsYWcpIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZGVwdGhNYXNrKGMsIGZsYWcpOworfQorCit2b2lkIGdsU3RlbmNpbE1hc2soR0x1aW50IG1hc2spIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3Muc3RlbmNpbE1hc2soYywgbWFzayk7Cit9CisKK3ZvaWQgZ2xEZXB0aEZ1bmMoR0xlbnVtIGZ1bmMpIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZGVwdGhGdW5jKGMsIGZ1bmMpOworfQorCit2b2lkIGdsTG9naWNPcChHTGVudW0gb3Bjb2RlKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmxvZ2ljT3AoYywgb3Bjb2RlKTsKK30KKwordm9pZCBnbEFscGhhRnVuY3goR0xlbnVtIGZ1bmMsIEdMY2xhbXB4IHJlZikgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5hbHBoYUZ1bmN4KGMsIGZ1bmMsIHJlZik7Cit9CisKK3ZvaWQgZ2xCbGVuZEZ1bmMoR0xlbnVtIHNmYWN0b3IsIEdMZW51bSBkZmFjdG9yKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmJsZW5kRnVuYyhjLCBzZmFjdG9yLCBkZmFjdG9yKTsKK30KKwordm9pZCBnbENsZWFyKEdMYml0ZmllbGQgbWFzaykgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jbGVhcihjLCBtYXNrKTsKK30KKwordm9pZCBnbENsZWFyQ29sb3J4KEdMY2xhbXB4IHJlZCwgR0xjbGFtcHggZ3JlZW4sIEdMY2xhbXB4IGJsdWUsIEdMY2xhbXB4IGFscGhhKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNsZWFyQ29sb3J4KGMsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKK30KKwordm9pZCBnbENsZWFyQ29sb3IoR0xjbGFtcGYgciwgR0xjbGFtcGYgZywgR0xjbGFtcGYgYiwgR0xjbGFtcGYgYSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuY2xlYXJDb2xvcngoYywKKyAgICAgICAgICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKHIpLAorICAgICAgICAgICAgICAgICAgICBnZ2xGbG9hdFRvRml4ZWQoZyksCisgICAgICAgICAgICAgICAgICAgIGdnbEZsb2F0VG9GaXhlZChiKSwKKyAgICAgICAgICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKGEpKTsKK30KKwordm9pZCBnbENsZWFyRGVwdGh4KEdMY2xhbXB4IGRlcHRoKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNsZWFyRGVwdGh4KGMsIGRlcHRoKTsKK30KKwordm9pZCBnbENsZWFyRGVwdGhmKEdMY2xhbXBmIGRlcHRoKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jbGVhckRlcHRoeChjLCBnZ2xGbG9hdFRvRml4ZWQoZGVwdGgpKTsKK30KKwordm9pZCBnbENsZWFyU3RlbmNpbChHTGludCBzKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmNsZWFyU3RlbmNpbChjLCBzKTsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC9saWJhZ2wvc3RhdGUuaCBiL29wZW5nbC9saWJhZ2wvc3RhdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWE1Y2NiCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYmFnbC9zdGF0ZS5oCkBAIC0wLDAgKzEsNTQgQEAKKy8qIGxpYnMvb3BlbmdsZXMvc3RhdGUuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19TVEFURV9ICisjZGVmaW5lIEFORFJPSURfT1BFTkdMRVNfU1RBVEVfSAorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisKKyNpbmNsdWRlIDxwcml2YXRlL3BpeGVsZmxpbmdlci9nZ2xfY29udGV4dC5oPgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjaW5jbHVkZSA8c3RkaW8uaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCitvZ2xlc19jb250ZXh0X3QgKm9nbGVzX2luaXQoc2l6ZV90IGV4dHJhKTsKK3ZvaWQgb2dsZXNfdW5pbml0KG9nbGVzX2NvbnRleHRfdCogYyk7Cit2b2lkIF9vZ2xlc19lcnJvcihvZ2xlc19jb250ZXh0X3QqIGMsIEdMZW51bSBlcnJvcik7CisKKyNpZm5kZWYgVFJBQ0VfR0xfRVJST1JTCisjZGVmaW5lIFRSQUNFX0dMX0VSUk9SUyAwCisjZW5kaWYKKworI2lmIFRSQUNFX0dMX0VSUk9SUworI2RlZmluZSBvZ2xlc19lcnJvcihjLCBlcnJvcikgXAorZG8geyBcCisgIHByaW50Zigib2dsZXNfZXJyb3IgYXQgZmlsZSAlcyBsaW5lICVkXG4iLCBfX0ZJTEVfXywgX19MSU5FX18pOyBcCisgIF9vZ2xlc19lcnJvcihjLCBlcnJvcik7IFwKK30gd2hpbGUgKDApCisjZWxzZSAvKiAhVFJBQ0VfR0xfRVJST1JTICovCisjZGVmaW5lIG9nbGVzX2Vycm9yKGMsIGVycm9yKSBfb2dsZXNfZXJyb3IoKGMpLCAoZXJyb3IpKQorI2VuZGlmCisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09QRU5HTEVTX1NUQVRFX0gKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC90ZXh0dXJlLmNwcCBiL29wZW5nbC9saWJhZ2wvdGV4dHVyZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjZmNTM0YgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvdGV4dHVyZS5jcHAKQEAgLTAsMCArMSwxNDIxIEBACisvKiBsaWJzL29wZW5nbGVzL3RleHR1cmUuY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSAiY29udGV4dC5oIgorI2luY2x1ZGUgImZwLmgiCisjaW5jbHVkZSAic3RhdGUuaCIKKyNpbmNsdWRlICJ0ZXh0dXJlLmgiCisjaW5jbHVkZSAiVGV4dHVyZU9iamVjdE1hbmFnZXIuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyB2b2lkIGJpbmRUZXh0dXJlVG11KAorICAgIG9nbGVzX2NvbnRleHRfdCogYywgaW50IHRtdSwgR0x1aW50IHRleHR1cmUsIGNvbnN0IHNwPEVHTFRleHR1cmVPYmplY3Q+JiB0ZXgpOworCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBnZW5lcmF0ZU1pcG1hcChvZ2xlc19jb250ZXh0X3QqIGMsIEdMaW50IGxldmVsKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBJbml0CisjZW5kaWYKKwordm9pZCBvZ2xlc19pbml0X3RleHR1cmUob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGMtPnRleHR1cmVzLnBhY2tBbGlnbm1lbnQgICA9IDQ7CisgICAgYy0+dGV4dHVyZXMudW5wYWNrQWxpZ25tZW50ID0gNDsKKworICAgIC8vIGVhY2ggY29udGV4dCBoYXMgYSBkZWZhdWx0IG5hbWVkICgwKSB0ZXh0dXJlIChub3Qgc2hhcmVkKQorICAgIGMtPnRleHR1cmVzLmRlZmF1bHRUZXh0dXJlID0gbmV3IEVHTFRleHR1cmVPYmplY3QoKTsKKyAgICBjLT50ZXh0dXJlcy5kZWZhdWx0VGV4dHVyZS0+aW5jU3Ryb25nKGMpOworICAgIAorICAgIC8vIGJpbmQgdGhlIGRlZmF1bHQgdGV4dHVyZSB0byBlYWNoIHRleHR1cmUgdW5pdAorICAgIGZvciAoaW50IGk9MDsgaTxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgaSsrKSB7CisgICAgICAgIGJpbmRUZXh0dXJlVG11KGMsIGksIDAsIGMtPnRleHR1cmVzLmRlZmF1bHRUZXh0dXJlKTsKKyAgICAgICAgbWVtc2V0KGMtPmN1cnJlbnQudGV4dHVyZVtpXS52LCAwLCBzaXplb2YodmVjNF90KSk7CisgICAgICAgIGMtPmN1cnJlbnQudGV4dHVyZVtpXS5RID0gMHgxMDAwMDsKKyAgICB9Cit9CisKK3ZvaWQgb2dsZXNfdW5pbml0X3RleHR1cmUob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGlmIChjLT50ZXh0dXJlcy5nZ2wpCisgICAgICAgIGdnbFVuaW5pdChjLT50ZXh0dXJlcy5nZ2wpOworICAgIGMtPnRleHR1cmVzLmRlZmF1bHRUZXh0dXJlLT5kZWNTdHJvbmcoYyk7CisgICAgZm9yIChpbnQgaT0wOyBpPEdHTF9URVhUVVJFX1VOSVRfQ09VTlQgOyBpKyspIHsKKyAgICAgICAgaWYgKGMtPnRleHR1cmVzLnRtdVtpXS50ZXh0dXJlKQorICAgICAgICAgICAgYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUtPmRlY1N0cm9uZyhjKTsKKyAgICB9Cit9CisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCit2b2lkIHZhbGlkYXRlX3RtdShvZ2xlc19jb250ZXh0X3QqIGMsIGludCBpKQoreworICAgIHRleHR1cmVfdW5pdF90JiB1KGMtPnRleHR1cmVzLnRtdVtpXSk7CisgICAgaWYgKHUuZGlydHkpIHsKKyAgICAgICAgdS5kaXJ0eSA9IDA7CisgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuYWN0aXZlVGV4dHVyZShjLCBpKTsKKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5iaW5kVGV4dHVyZShjLCAmKHUudGV4dHVyZS0+c3VyZmFjZSkpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleEdlbmkoYywgR0dMX1MsCisgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfR0VOX01PREUsIEdHTF9BVVRPTUFUSUMpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleEdlbmkoYywgR0dMX1QsCisgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfR0VOX01PREUsIEdHTF9BVVRPTUFUSUMpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleFBhcmFtZXRlcmkoYywgR0dMX1RFWFRVUkVfMkQsCisgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfV1JBUF9TLCB1LnRleHR1cmUtPndyYXBzKTsKKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy50ZXhQYXJhbWV0ZXJpKGMsIEdHTF9URVhUVVJFXzJELAorICAgICAgICAgICAgICAgIEdHTF9URVhUVVJFX1dSQVBfVCwgdS50ZXh0dXJlLT53cmFwdCk7CisgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4UGFyYW1ldGVyaShjLCBHR0xfVEVYVFVSRV8yRCwKKyAgICAgICAgICAgICAgICBHR0xfVEVYVFVSRV9NSU5fRklMVEVSLCB1LnRleHR1cmUtPm1pbl9maWx0ZXIpOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleFBhcmFtZXRlcmkoYywgR0dMX1RFWFRVUkVfMkQsCisgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgdS50ZXh0dXJlLT5tYWdfZmlsdGVyKTsKKworICAgICAgICAvLyBkaXNhYmxlIHRoaXMgdGV4dHVyZSB1bml0IGlmIGl0J3Mgbm90IGNvbXBsZXRlCisgICAgICAgIGlmICghdS50ZXh0dXJlLT5pc0NvbXBsZXRlKCkpIHsKKyAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZGlzYWJsZShjLCBHR0xfVEVYVFVSRV8yRCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKK3ZvaWQgb2dsZXNfdmFsaWRhdGVfdGV4dHVyZV9pbXBsKG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBmb3IgKGludCBpPTAgOyBpPEdHTF9URVhUVVJFX1VOSVRfQ09VTlQgOyBpKyspIHsKKyAgICAgICAgaWYgKGMtPnJhc3Rlcml6ZXIuc3RhdGUudGV4dHVyZVtpXS5lbmFibGUpCisgICAgICAgICAgICB2YWxpZGF0ZV90bXUoYywgaSk7CisgICAgfQorICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuYWN0aXZlVGV4dHVyZShjLCBjLT50ZXh0dXJlcy5hY3RpdmUpOworfQorCitzdGF0aWMKK3ZvaWQgaW52YWxpZGF0ZV90ZXh0dXJlKG9nbGVzX2NvbnRleHRfdCogYywgaW50IHRtdSwgdWludDhfdCBmbGFncyA9IDB4RkYpIHsKKyAgICBjLT50ZXh0dXJlcy50bXVbdG11XS5kaXJ0eSA9IGZsYWdzOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBGb3JtYXQgY29udmVyc2lvbgorI2VuZGlmCisKK3N0YXRpYyB1aW50MzJfdCBnbDJmb3JtYXRfdGFibGVbNl1bNF0gPSB7CisgICAgLy8gQllURSwgNTY1LCA0NDQ0LCA1NTUxCisgICAgeyBHR0xfUElYRUxfRk9STUFUX0FfOCwKKyAgICAgIDAsIDAsIDAgfSwgICAgICAgICAgICAgICAgICAgICAgICAvLyBHTF9BTFBIQQorICAgIHsgR0dMX1BJWEVMX0ZPUk1BVF9SR0JfODg4LAorICAgICAgR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1LAorICAgICAgMCwgMCB9LCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdMX1JHQgorICAgIHsgR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzg4ODgsCisgICAgICAwLAorICAgICAgR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzQ0NDQsCisgICAgICBHR0xfUElYRUxfRk9STUFUX1JHQkFfNTU1MSB9LCAgICAgLy8gR0xfUkdCQQorICAgIHsgR0dMX1BJWEVMX0ZPUk1BVF9MXzgsCisgICAgICAwLCAwLCAwIH0sICAgICAgICAgICAgICAgICAgICAgICAgLy8gR0xfTFVNSU5BTkNFCisgICAgeyBHR0xfUElYRUxfRk9STUFUX0xBXzg4LAorICAgICAgMCwgMCwgMCB9LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdMX0xVTUlOQU5DRV9BTFBIQQorfTsKKworc3RhdGljIGludDMyX3QgY29udmVydEdMUGl4ZWxGb3JtYXQoR0xpbnQgZm9ybWF0LCBHTGVudW0gdHlwZSkKK3sKKyAgICBpbnQzMl90IGZpID0gLTE7CisgICAgaW50MzJfdCB0aSA9IC0xOworICAgIHN3aXRjaCAoZm9ybWF0KSB7CisgICAgY2FzZSBHTF9BTFBIQTogICAgICAgICAgICAgIGZpID0gMDsgICAgIGJyZWFrOworICAgIGNhc2UgR0xfUkdCOiAgICAgICAgICAgICAgICBmaSA9IDE7ICAgICBicmVhazsKKyAgICBjYXNlIEdMX1JHQkE6ICAgICAgICAgICAgICAgZmkgPSAyOyAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9MVU1JTkFOQ0U6ICAgICAgICAgIGZpID0gMzsgICAgIGJyZWFrOworICAgIGNhc2UgR0xfTFVNSU5BTkNFX0FMUEhBOiAgICBmaSA9IDQ7ICAgICBicmVhazsKKyAgICB9CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBHTF9VTlNJR05FRF9CWVRFOiAgICAgICAgICB0aSA9IDA7IGJyZWFrOworICAgIGNhc2UgR0xfVU5TSUdORURfU0hPUlRfNV82XzU6ICAgdGkgPSAxOyBicmVhazsKKyAgICBjYXNlIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQ6IHRpID0gMjsgYnJlYWs7CisgICAgY2FzZSBHTF9VTlNJR05FRF9TSE9SVF81XzVfNV8xOiB0aSA9IDM7IGJyZWFrOworICAgIH0KKyAgICBpZiAoZmk9PS0xIHx8IHRpPT0tMSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIGdsMmZvcm1hdF90YWJsZVtmaV1bdGldOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBHTGVudW0gdmFsaWRGb3JtYXRUeXBlKG9nbGVzX2NvbnRleHRfdCogYywgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUpCit7CisgICAgR0xlbnVtIGVycm9yID0gMDsKKyAgICBpZiAoZm9ybWF0PEdMX0FMUEhBIHx8IGZvcm1hdD5HTF9MVU1JTkFOQ0VfQUxQSEEpIHsKKyAgICAgICAgZXJyb3IgPSBHTF9JTlZBTElEX0VOVU07CisgICAgfQorICAgIGlmICh0eXBlICE9IEdMX1VOU0lHTkVEX0JZVEUgJiYgdHlwZSAhPSBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80ICYmCisgICAgICAgIHR5cGUgIT0gR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMSAmJiB0eXBlICE9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81KSB7CisgICAgICAgIGVycm9yID0gR0xfSU5WQUxJRF9FTlVNOworICAgIH0KKyAgICBpZiAodHlwZSA9PSBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSAmJiBmb3JtYXQgIT0gR0xfUkdCKSB7CisgICAgICAgIGVycm9yID0gR0xfSU5WQUxJRF9PUEVSQVRJT047CisgICAgfQorICAgIGlmICgodHlwZSA9PSBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80IHx8CisgICAgICAgICB0eXBlID09IEdMX1VOU0lHTkVEX1NIT1JUXzVfNV81XzEpICAmJiBmb3JtYXQgIT0gR0xfUkdCQSkgeworICAgICAgICBlcnJvciA9IEdMX0lOVkFMSURfT1BFUkFUSU9OOworICAgIH0KKyAgICBpZiAoZXJyb3IpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgZXJyb3IpOworICAgIH0KKyAgICByZXR1cm4gZXJyb3I7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworR0dMQ29udGV4dCogZ2V0UmFzdGVyaXplcihvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgR0dMQ29udGV4dCogZ2dsID0gYy0+dGV4dHVyZXMuZ2dsOworICAgIGlmIChnZ2xfdW5saWtlbHkoIWdnbCkpIHsKKyAgICAgICAgLy8gdGhpcyBpcyBxdWl0ZSBoZWF2eSB0aGUgZmlyc3QgdGltZS4uLgorICAgICAgICBnZ2xJbml0KCZnZ2wpOworICAgICAgICBpZiAoIWdnbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgR0dMZml4ZWQgY29sb3JzWzRdID0geyAwLCAwLCAwLCAweDEwMDAwIH07CisgICAgICAgIGMtPnRleHR1cmVzLmdnbCA9IGdnbDsKKyAgICAgICAgZ2dsLT5hY3RpdmVUZXh0dXJlKGdnbCwgMCk7CisgICAgICAgIGdnbC0+ZW5hYmxlKGdnbCwgR0dMX1RFWFRVUkVfMkQpOworICAgICAgICBnZ2wtPnRleEVudmkoZ2dsLCBHR0xfVEVYVFVSRV9FTlYsIEdHTF9URVhUVVJFX0VOVl9NT0RFLCBHR0xfUkVQTEFDRSk7CisgICAgICAgIGdnbC0+ZGlzYWJsZShnZ2wsIEdHTF9ESVRIRVIpOworICAgICAgICBnZ2wtPnNoYWRlTW9kZWwoZ2dsLCBHR0xfRkxBVCk7CisgICAgICAgIGdnbC0+Y29sb3I0eHYoZ2dsLCBjb2xvcnMpOworICAgIH0KKyAgICByZXR1cm4gZ2dsOworfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQoraW50IGNvcHlQaXhlbHMoCisgICAgICAgIG9nbGVzX2NvbnRleHRfdCogYywKKyAgICAgICAgY29uc3QgR0dMU3VyZmFjZSYgZHN0LAorICAgICAgICBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LAorICAgICAgICBjb25zdCBHR0xTdXJmYWNlJiBzcmMsCisgICAgICAgIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgdywgR0xzaXplaSBoKQoreworICAgIGlmICgoZHN0LmZvcm1hdCA9PSBzcmMuZm9ybWF0KSAmJgorICAgICAgICAoZHN0LnN0cmlkZSA9PSBzcmMuc3RyaWRlKSAmJgorICAgICAgICAoZHN0LndpZHRoID09IHNyYy53aWR0aCkgJiYKKyAgICAgICAgKGRzdC5oZWlnaHQgPT0gc3JjLmhlaWdodCkgJiYKKyAgICAgICAgKGRzdC5zdHJpZGUgPiAwKSAmJgorICAgICAgICAoKHh8eSkgPT0gMCkgJiYKKyAgICAgICAgKCh4b2Zmc2V0fHlvZmZzZXQpID09IDApKQorICAgIHsKKyAgICAgICAgLy8gdGhpcyBpcyBhIGNvbW1vbiBjYXNlLi4uCisgICAgICAgIGNvbnN0IEdHTEZvcm1hdCYgcGl4ZWxGb3JtYXQoYy0+cmFzdGVyaXplci5mb3JtYXRzW3NyYy5mb3JtYXRdKTsKKyAgICAgICAgY29uc3Qgc2l6ZV90IHNpemUgPSBzcmMuaGVpZ2h0ICogc3JjLnN0cmlkZSAqIHBpeGVsRm9ybWF0LnNpemU7CisgICAgICAgIG1lbWNweShkc3QuZGF0YSwgc3JjLmRhdGEsIHNpemUpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyB1c2UgcGl4ZWwtZmxpbmdlciB0byBoYW5kbGUgYWxsIHRoZSBjb252ZXJzaW9ucworICAgIEdHTENvbnRleHQqIGdnbCA9IGdldFJhc3Rlcml6ZXIoYyk7CisgICAgaWYgKCFnZ2wpIHsKKyAgICAgICAgLy8gdGhlIG9ubHkgcmVhc29uIHRoaXMgd291bGQgZmFpbCBpcyBiZWNhdXNlIHdlIHJhbiBvdXQgb2YgbWVtb3J5CisgICAgICAgIHJldHVybiBHTF9PVVRfT0ZfTUVNT1JZOworICAgIH0KKworICAgIGdnbC0+Y29sb3JCdWZmZXIoZ2dsLCAmZHN0KTsKKyAgICBnZ2wtPmJpbmRUZXh0dXJlKGdnbCwgJnNyYyk7CisgICAgZ2dsLT50ZXhDb29yZDJpKGdnbCwgeC14b2Zmc2V0LCB5LXlvZmZzZXQpOworICAgIGdnbC0+cmVjdGkoZ2dsLCB4b2Zmc2V0LCB5b2Zmc2V0LCB4b2Zmc2V0K3csIHlvZmZzZXQraCk7CisgICAgcmV0dXJuIDA7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK3NwPEVHTFRleHR1cmVPYmplY3Q+IGdldEFuZEJpbmRBY3RpdmVUZXh0dXJlT2JqZWN0KG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICBzcDxFR0xUZXh0dXJlT2JqZWN0PiB0ZXg7CisgICAgY29uc3QgaW50IGFjdGl2ZSA9IGMtPnRleHR1cmVzLmFjdGl2ZTsKKyAgICBjb25zdCBHTHVpbnQgbmFtZSA9IGMtPnRleHR1cmVzLnRtdVthY3RpdmVdLm5hbWU7CisKKyAgICAvLyBmcmVlIHRoZSByZWZlcmVuY2UgdG8gdGhlIHByZXZpb3VzbHkgYm91bmQgb2JqZWN0CisgICAgdGV4dHVyZV91bml0X3QmIHUoYy0+dGV4dHVyZXMudG11W2FjdGl2ZV0pOworICAgIGlmICh1LnRleHR1cmUpCisgICAgICAgIHUudGV4dHVyZS0+ZGVjU3Ryb25nKGMpOworCisgICAgaWYgKG5hbWUgPT0gMCkgeworICAgICAgICAvLyAwIGlzIG91ciBsb2NhbCB0ZXh0dXJlIG9iamVjdCwgbm90IHNoYXJlZCB3aXRoIGFueW9uZS4gCisgICAgICAgIC8vIEJ1dCBpdCBhZmZlY3RzIGFsbCBib3VuZCBUTVVzIGltbWVkaWF0ZWx5LgorICAgICAgICAvLyAod2UgbmVlZCB0byBpbnZhbGlkYXRlIGFsbCB1bml0cyBib3VuZCB0byB0aGlzIHRleHR1cmUgb2JqZWN0KQorICAgICAgICB0ZXggPSBjLT50ZXh0dXJlcy5kZWZhdWx0VGV4dHVyZTsKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYy0+dGV4dHVyZXMudG11W2ldLnRleHR1cmUgPT0gdGV4LmdldCgpKQorICAgICAgICAgICAgICAgIGludmFsaWRhdGVfdGV4dHVyZShjLCBpKTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8vIGdldCBhIG5ldyB0ZXh0dXJlIG9iamVjdCBmb3IgdGhhdCBuYW1lCisgICAgICAgIHRleCA9IGMtPnN1cmZhY2VNYW5hZ2VyLT5yZXBsYWNlVGV4dHVyZShuYW1lKTsKKyAgICB9CisKKyAgICAvLyBiaW5kIHRoaXMgdGV4dHVyZSB0byB0aGUgY3VycmVudCBhY3RpdmUgdGV4dHVyZSB1bml0CisgICAgLy8gYW5kIGFkZCBhIHJlZmVyZW5jZSB0byB0aGlzIHRleHR1cmUgb2JqZWN0CisgICAgdS50ZXh0dXJlID0gdGV4LmdldCgpOworICAgIHUudGV4dHVyZS0+aW5jU3Ryb25nKGMpOworICAgIHUubmFtZSA9IG5hbWU7CisgICAgaW52YWxpZGF0ZV90ZXh0dXJlKGMsIGFjdGl2ZSk7ICAgIAorICAgIHJldHVybiB0ZXg7Cit9CisKK3ZvaWQgYmluZFRleHR1cmVUbXUoCisgICAgb2dsZXNfY29udGV4dF90KiBjLCBpbnQgdG11LCBHTHVpbnQgdGV4dHVyZSwgY29uc3Qgc3A8RUdMVGV4dHVyZU9iamVjdD4mIHRleCkKK3sKKyAgICBpZiAodGV4LmdldCgpID09IGMtPnRleHR1cmVzLnRtdVt0bXVdLnRleHR1cmUpCisgICAgICAgIHJldHVybjsKKyAgICAKKyAgICAvLyBmcmVlIHRoZSByZWZlcmVuY2UgdG8gdGhlIHByZXZpb3VzbHkgYm91bmQgb2JqZWN0CisgICAgdGV4dHVyZV91bml0X3QmIHUoYy0+dGV4dHVyZXMudG11W3RtdV0pOworICAgIGlmICh1LnRleHR1cmUpCisgICAgICAgIHUudGV4dHVyZS0+ZGVjU3Ryb25nKGMpOworCisgICAgLy8gYmluZCB0aGlzIHRleHR1cmUgdG8gdGhlIGN1cnJlbnQgYWN0aXZlIHRleHR1cmUgdW5pdAorICAgIC8vIGFuZCBhZGQgYSByZWZlcmVuY2UgdG8gdGhpcyB0ZXh0dXJlIG9iamVjdAorICAgIHUudGV4dHVyZSA9IHRleC5nZXQoKTsKKyAgICB1LnRleHR1cmUtPmluY1N0cm9uZyhjKTsKKyAgICB1Lm5hbWUgPSB0ZXh0dXJlOworICAgIGludmFsaWRhdGVfdGV4dHVyZShjLCB0bXUpOworfQorCitpbnQgY3JlYXRlVGV4dHVyZVN1cmZhY2Uob2dsZXNfY29udGV4dF90KiBjLAorICAgICAgICBHR0xTdXJmYWNlKiogb3V0U3VyZmFjZSwgaW50MzJfdCogb3V0U2l6ZSwgR0xpbnQgbGV2ZWwsCisgICAgICAgIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwKKyAgICAgICAgR0xlbnVtIGNvbXByZXNzZWRGb3JtYXQgPSAwKQoreworICAgIC8vIGZpbmQgb3V0IHdoaWNoIHRleHR1cmUgaXMgYm91bmQgdG8gdGhlIGN1cnJlbnQgdW5pdAorICAgIGNvbnN0IGludCBhY3RpdmUgPSBjLT50ZXh0dXJlcy5hY3RpdmU7CisgICAgY29uc3QgR0x1aW50IG5hbWUgPSBjLT50ZXh0dXJlcy50bXVbYWN0aXZlXS5uYW1lOworCisgICAgLy8gY29udmVydCB0aGUgcGl4ZWxmb3JtYXQgdG8gb25lIHdlIGNhbiBoYW5kbGUKKyAgICBjb25zdCBpbnQzMl90IGZvcm1hdElkeCA9IGNvbnZlcnRHTFBpeGVsRm9ybWF0KGZvcm1hdCwgdHlwZSk7CisgICAgaWYgKGZvcm1hdElkeCA9PSAwKSB7IC8vIHdlIGRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIHRoaXMKKyAgICAgICAgcmV0dXJuIEdMX0lOVkFMSURfT1BFUkFUSU9OOworICAgIH0KKyAgICAKKyAgICAvLyBmaWd1cmUgb3V0IHRoZSBzaXplIHdlIG5lZWQgYXMgd2VsbCBhcyB0aGUgc3RyaWRlCisgICAgY29uc3QgR0dMRm9ybWF0JiBwaXhlbEZvcm1hdChjLT5yYXN0ZXJpemVyLmZvcm1hdHNbZm9ybWF0SWR4XSk7CisgICAgY29uc3QgaW50MzJfdCBhbGlnbiA9IGMtPnRleHR1cmVzLnVucGFja0FsaWdubWVudC0xOworICAgIGNvbnN0IGludDMyX3QgYnByID0gKCh3aWR0aCAqIHBpeGVsRm9ybWF0LnNpemUpICsgYWxpZ24pICYgfmFsaWduOworICAgIGNvbnN0IHNpemVfdCBzaXplID0gYnByICogaGVpZ2h0OworICAgIGNvbnN0IGludDMyX3Qgc3RyaWRlID0gYnByIC8gcGl4ZWxGb3JtYXQuc2l6ZTsKKworICAgIGlmIChsZXZlbCA+IDApIHsKKyAgICAgICAgY29uc3QgaW50IGFjdGl2ZSA9IGMtPnRleHR1cmVzLmFjdGl2ZTsKKyAgICAgICAgRUdMVGV4dHVyZU9iamVjdCogdGV4ID0gYy0+dGV4dHVyZXMudG11W2FjdGl2ZV0udGV4dHVyZTsKKyAgICAgICAgc3RhdHVzX3QgZXJyID0gdGV4LT5yZWFsbG9jYXRlKGxldmVsLAorICAgICAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIHN0cmlkZSwgZm9ybWF0SWR4LCBjb21wcmVzc2VkRm9ybWF0LCBicHIpOworICAgICAgICBpZiAoZXJyICE9IE5PX0VSUk9SKQorICAgICAgICAgICAgcmV0dXJuIEdMX09VVF9PRl9NRU1PUlk7CisgICAgICAgIEdHTFN1cmZhY2UmIHN1cmZhY2UgPSB0ZXgtPmVkaXRNaXAobGV2ZWwpOworICAgICAgICAqb3V0U3VyZmFjZSA9ICZzdXJmYWNlOworICAgICAgICAqb3V0U2l6ZSA9IHNpemU7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+IHRleCA9IGdldEFuZEJpbmRBY3RpdmVUZXh0dXJlT2JqZWN0KGMpOworICAgIHN0YXR1c190IGVyciA9IHRleC0+cmVhbGxvY2F0ZShsZXZlbCwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIHN0cmlkZSwgZm9ybWF0SWR4LCBjb21wcmVzc2VkRm9ybWF0LCBicHIpOworICAgIGlmIChlcnIgIT0gTk9fRVJST1IpCisgICAgICAgIHJldHVybiBHTF9PVVRfT0ZfTUVNT1JZOworCisgICAgdGV4LT5pbnRlcm5hbGZvcm1hdCA9IGZvcm1hdDsKKyAgICAqb3V0U3VyZmFjZSA9ICZ0ZXgtPnN1cmZhY2U7CisgICAgKm91dFNpemUgPSBzaXplOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBkZWNvZGVQYWxldHRlNChjb25zdCBHTHZvaWQgKmRhdGEsIGludCBsZXZlbCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqc3VyZmFjZSwgaW50IHN0cmlkZSwgaW50IGZvcm1hdCkKKworeworICAgIGludCBpbmRleEJpdHMgPSA4OworICAgIGludCBlbnRyeVNpemUgPSAwOworICAgIHN3aXRjaCAoZm9ybWF0KSB7CisgICAgY2FzZSBHTF9QQUxFVFRFNF9SR0I4X09FUzoKKyAgICAgICAgaW5kZXhCaXRzID0gNDsKKyAgICAgICAgLyogRkFMTFRIUk9VR0ggKi8KKyAgICBjYXNlIEdMX1BBTEVUVEU4X1JHQjhfT0VTOgorICAgICAgICBlbnRyeVNpemUgPSAzOworICAgICAgICBicmVhazsKKworICAgIGNhc2UgR0xfUEFMRVRURTRfUkdCQThfT0VTOgorICAgICAgICBpbmRleEJpdHMgPSA0OworICAgICAgICAvKiBGQUxMVEhST1VHSCAqLworICAgIGNhc2UgR0xfUEFMRVRURThfUkdCQThfT0VTOgorICAgICAgICBlbnRyeVNpemUgPSA0OworICAgICAgICBicmVhazsKKworICAgIGNhc2UgR0xfUEFMRVRURTRfUjVfRzZfQjVfT0VTOgorICAgIGNhc2UgR0xfUEFMRVRURTRfUkdCQTRfT0VTOgorICAgIGNhc2UgR0xfUEFMRVRURTRfUkdCNV9BMV9PRVM6CisgICAgICAgIGluZGV4Qml0cyA9IDQ7CisgICAgICAgIC8qIEZBTExUSFJPVUdIICovCisgICAgY2FzZSBHTF9QQUxFVFRFOF9SNV9HNl9CNV9PRVM6CisgICAgY2FzZSBHTF9QQUxFVFRFOF9SR0JBNF9PRVM6CisgICAgY2FzZSBHTF9QQUxFVFRFOF9SR0I1X0ExX09FUzoKKyAgICAgICAgZW50cnlTaXplID0gMjsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY29uc3QgaW50IHBhbGV0dGVTaXplID0gKDEgPDwgaW5kZXhCaXRzKSAqIGVudHJ5U2l6ZTsKKyAgICB1aW50OF90IGNvbnN0KiBwaXhlbHMgPSAodWludDhfdCAqKWRhdGEgKyBwYWxldHRlU2l6ZTsKKyAgICBmb3IgKGludCBpPTAgOyBpPGxldmVsIDsgaSsrKSB7CisgICAgICAgIGludCB3ID0gKHdpZHRoICA+PiBpKSA/IDogMTsKKyAgICAgICAgaW50IGggPSAoaGVpZ2h0ID4+IGkpID8gOiAxOworICAgICAgICBwaXhlbHMgKz0gaCAqICgodyAqIGluZGV4Qml0cykgLyA4KTsKKyAgICB9CisgICAgd2lkdGggID0gKHdpZHRoICA+PiBsZXZlbCkgPyA6IDE7CisgICAgaGVpZ2h0ID0gKGhlaWdodCA+PiBsZXZlbCkgPyA6IDE7CisKKyAgICBpZiAoZW50cnlTaXplID09IDIpIHsKKyAgICAgICAgdWludDhfdCBjb25zdCogY29uc3QgcGFsZXR0ZSA9ICh1aW50OF90KilkYXRhOworICAgICAgICBmb3IgKGludCB5PTAgOyB5PGhlaWdodCA7IHkrKykgeworICAgICAgICAgICAgdWludDhfdCogcCA9ICh1aW50OF90KilzdXJmYWNlICsgeSpzdHJpZGUqMjsKKyAgICAgICAgICAgIGlmIChpbmRleEJpdHMgPT0gOCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IHg9MCA7IHg8d2lkdGggOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMiAqICgqcGl4ZWxzKyspOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDBdOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDFdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeD0wIDsgeDx3aWR0aCA7IHgrPTIpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHYgPSAqcGl4ZWxzKys7CisgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9IDIgKiAodiA+PiA0KTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHgrMSA8IHdpZHRoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDIgKiAodiAmIDB4Rik7CisgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDBdOworICAgICAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0gZWxzZSBpZiAoZW50cnlTaXplID09IDMpIHsKKyAgICAgICAgdWludDhfdCBjb25zdCogY29uc3QgcGFsZXR0ZSA9ICh1aW50OF90KilkYXRhOworICAgICAgICBmb3IgKGludCB5PTAgOyB5PGhlaWdodCA7IHkrKykgeworICAgICAgICAgICAgdWludDhfdCogcCA9ICh1aW50OF90KilzdXJmYWNlICsgeSpzdHJpZGUqMzsKKyAgICAgICAgICAgIGlmIChpbmRleEJpdHMgPT0gOCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IHg9MCA7IHg8d2lkdGggOyB4KyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMyAqICgqcGl4ZWxzKyspOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDBdOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDFdOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDJdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgeD0wIDsgeDx3aWR0aCA7IHgrPTIpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHYgPSAqcGl4ZWxzKys7CisgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9IDMgKiAodiA+PiA0KTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAyXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHgrMSA8IHdpZHRoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDMgKiAodiAmIDB4Rik7CisgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDBdOworICAgICAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgMl07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGVudHJ5U2l6ZSA9PSA0KSB7CisgICAgICAgIHVpbnQ4X3QgY29uc3QqIGNvbnN0IHBhbGV0dGUgPSAodWludDhfdCopZGF0YTsKKyAgICAgICAgZm9yIChpbnQgeT0wIDsgeTxoZWlnaHQgOyB5KyspIHsKKyAgICAgICAgICAgIHVpbnQ4X3QqIHAgPSAodWludDhfdCopc3VyZmFjZSArIHkqc3RyaWRlKjQ7CisgICAgICAgICAgICBpZiAoaW5kZXhCaXRzID09IDgpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCB4PTAgOyB4PHdpZHRoIDsgeCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9IDQgKiAoKnBpeGVscysrKTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAyXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAzXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IHg9MCA7IHg8d2lkdGggOyB4Kz0yKSB7CisgICAgICAgICAgICAgICAgICAgIGludCB2ID0gKnBpeGVscysrOworICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSA0ICogKHYgPj4gNCk7CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgMF07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgMV07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgMl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgM107CisgICAgICAgICAgICAgICAgICAgIGlmICh4KzEgPCB3aWR0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSA0ICogKHYgJiAweEYpOworICAgICAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAwXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICpwKysgPSBwYWxldHRlW2luZGV4ICsgMV07CisgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gcGFsZXR0ZVtpbmRleCArIDJdOworICAgICAgICAgICAgICAgICAgICAgICAgKnArKyA9IHBhbGV0dGVbaW5kZXggKyAzXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KKworCisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCit2b2lkIHNldF9kZXB0aF9hbmRfZm9nKG9nbGVzX2NvbnRleHRfdCogYywgR0xpbnQgeikKK3sKKyAgICBjb25zdCB1aW50MzJfdCBlbmFibGVzID0gYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzOworICAgIC8vIHdlIG5lZWQgdG8gY29tcHV0ZSBadworICAgIGludDMyX3QgaXRlcmF0b3JzWzNdOworICAgIGl0ZXJhdG9yc1sxXSA9IGl0ZXJhdG9yc1syXSA9IDA7CisgICAgR0dMZml4ZWQgWnc7CisgICAgR0dMZml4ZWQgbiA9IGdnbEZsb2F0VG9GaXhlZChjLT50cmFuc2Zvcm1zLnZwdC56TmVhcik7CisgICAgR0dMZml4ZWQgZiA9IGdnbEZsb2F0VG9GaXhlZChjLT50cmFuc2Zvcm1zLnZwdC56RmFyKTsKKyAgICBpZiAoejw9MCkgICAgICAgWncgPSBuOworICAgIGVsc2UgaWYgKHo+PTEpICBadyA9IGY7CisgICAgZWxzZSAgICAgICAgICAgIFp3ID0gZ2dsTXVsQWRkeCh6LCAoZi1uKSwgbik7CisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0ZPRykgeworICAgICAgICAvLyBzZXQgdXAgZm9nIGlmIG5lZWRlZC4uLgorICAgICAgICBpdGVyYXRvcnNbMF0gPSBjLT5mb2cuZm9nKGMsIFp3KTsKKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5mb2dHcmFkM3h2KGMsIGl0ZXJhdG9ycyk7CisgICAgfQorICAgIGlmIChlbmFibGVzICYgR0dMX0VOQUJMRV9ERVBUSF9URVNUKSB7CisgICAgICAgIC8vIHNldCB1cCB6LXRlc3QgaWYgbmVlZGVkLi4uCisgICAgICAgIGludDMyX3QgeiA9IChadyAmIH4oWnc+PjMxKSk7CisgICAgICAgIGlmICh6ID49IDB4MTAwMDApCisgICAgICAgICAgICB6ID0gMHhGRkZGOworICAgICAgICBpdGVyYXRvcnNbMF0gPSAoeiA8PCAxNikgfCB6OworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnpHcmFkM3h2KGMsIGl0ZXJhdG9ycyk7CisgICAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBHZW5lcmF0ZSBtaW1hcHMKKyNlbmRpZgorCitleHRlcm4gc3RhdHVzX3QgYnVpbGRBUHlyYW1pZChvZ2xlc19jb250ZXh0X3QqIGMsIEVHTFRleHR1cmVPYmplY3QqIHRleCk7CisKK3ZvaWQgZ2VuZXJhdGVNaXBtYXAob2dsZXNfY29udGV4dF90KiBjLCBHTGludCBsZXZlbCkKK3sKKyAgICBpZiAobGV2ZWwgPT0gMCkgeworICAgICAgICBjb25zdCBpbnQgYWN0aXZlID0gYy0+dGV4dHVyZXMuYWN0aXZlOworICAgICAgICBFR0xUZXh0dXJlT2JqZWN0KiB0ZXggPSBjLT50ZXh0dXJlcy50bXVbYWN0aXZlXS50ZXh0dXJlOworICAgICAgICBpZiAodGV4LT5nZW5lcmF0ZV9taXBtYXApIHsKKyAgICAgICAgICAgIGlmIChidWlsZEFQeXJhbWlkKGMsIHRleCkgIT0gTk9fRVJST1IpIHsKKyAgICAgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9PVVRfT0ZfTUVNT1JZKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKKworc3RhdGljIHZvaWQgdGV4UGFyYW1ldGVyeCgKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtLCBvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgaWYgKHRhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgCisgICAgRUdMVGV4dHVyZU9iamVjdCogdGV4dHVyZU9iamVjdCA9IGMtPnRleHR1cmVzLnRtdVtjLT50ZXh0dXJlcy5hY3RpdmVdLnRleHR1cmU7ICAgIAorICAgIHN3aXRjaCAocG5hbWUpIHsKKyAgICBjYXNlIEdMX1RFWFRVUkVfV1JBUF9TOgorICAgICAgICBpZiAoKHBhcmFtID09IEdMX1JFUEVBVCkgfHwKKyAgICAgICAgICAgIChwYXJhbSA9PSBHTF9DTEFNUF9UT19FREdFKSkgeworICAgICAgICAgICAgdGV4dHVyZU9iamVjdC0+d3JhcHMgPSBwYXJhbTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdvdG8gaW52YWxpZF9lbnVtOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfVEVYVFVSRV9XUkFQX1Q6CisgICAgICAgIGlmICgocGFyYW0gPT0gR0xfUkVQRUFUKSB8fAorICAgICAgICAgICAgKHBhcmFtID09IEdMX0NMQU1QX1RPX0VER0UpKSB7CisgICAgICAgICAgICB0ZXh0dXJlT2JqZWN0LT53cmFwdCA9IHBhcmFtOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZ290byBpbnZhbGlkX2VudW07CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9URVhUVVJFX01JTl9GSUxURVI6CisgICAgICAgIGlmICgocGFyYW0gPT0gR0xfTkVBUkVTVCkgfHwKKyAgICAgICAgICAgIChwYXJhbSA9PSBHTF9MSU5FQVIpIHx8CisgICAgICAgICAgICAocGFyYW0gPT0gR0xfTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCkgfHwKKyAgICAgICAgICAgIChwYXJhbSA9PSBHTF9MSU5FQVJfTUlQTUFQX05FQVJFU1QpIHx8CisgICAgICAgICAgICAocGFyYW0gPT0gR0xfTkVBUkVTVF9NSVBNQVBfTElORUFSKSB8fAorICAgICAgICAgICAgKHBhcmFtID09IEdMX0xJTkVBUl9NSVBNQVBfTElORUFSKSkgeworICAgICAgICAgICAgdGV4dHVyZU9iamVjdC0+bWluX2ZpbHRlciA9IHBhcmFtOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZ290byBpbnZhbGlkX2VudW07CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9URVhUVVJFX01BR19GSUxURVI6CisgICAgICAgIGlmICgocGFyYW0gPT0gR0xfTkVBUkVTVCkgfHwKKyAgICAgICAgICAgIChwYXJhbSA9PSBHTF9MSU5FQVIpKSB7CisgICAgICAgICAgICB0ZXh0dXJlT2JqZWN0LT5tYWdfZmlsdGVyID0gcGFyYW07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnb3RvIGludmFsaWRfZW51bTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX0dFTkVSQVRFX01JUE1BUDoKKyAgICAgICAgdGV4dHVyZU9iamVjdC0+Z2VuZXJhdGVfbWlwbWFwID0gcGFyYW07CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CitpbnZhbGlkX2VudW06CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW52YWxpZGF0ZV90ZXh0dXJlKGMsIGMtPnRleHR1cmVzLmFjdGl2ZSk7Cit9CisKKworc3RhdGljIHZvaWQgZHJhd1RleHhPRVMoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeiwgR0xmaXhlZCB3LCBHTGZpeGVkIGgsCisgICAgICAgIG9nbGVzX2NvbnRleHRfdCogYykKK3sKKyAgICAvLyBxdWlja2x5IHJlamVjdCBlbXB0eSByZWN0cworICAgIGlmICgod3xoKSA8PSAwKQorICAgICAgICByZXR1cm47ICAgICAgICAgICAgICAgIAorCisgICAgY29uc3QgR0dMU3VyZmFjZSYgY2JTdXJmYWNlID0gYy0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLmNvbG9yLnM7CisgICAgeSA9IGdnbEludFRvRml4ZWQoY2JTdXJmYWNlLmhlaWdodCkgLSAoeSArIGgpOworICAgIHcgPj49IEZJWEVEX0JJVFM7CisgICAgaCA+Pj0gRklYRURfQklUUzsKKworICAgIC8vIHNldCB1cCBhbGwgdGV4dHVyZSB1bml0cworICAgIGZvciAoaW50IGk9MCA7IGk8R0dMX1RFWFRVUkVfVU5JVF9DT1VOVCA7IGkrKykgeworICAgICAgICBpZiAoIWMtPnJhc3Rlcml6ZXIuc3RhdGUudGV4dHVyZVtpXS5lbmFibGUpCisgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICBpbnQzMl90IHRleGNvb3Jkc1s4XTsKKyAgICAgICAgdGV4dHVyZV91bml0X3QmIHUoYy0+dGV4dHVyZXMudG11W2ldKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGlzIHRtdSAoYmluZCwgd3JhcCwgZmlsdGVyKQorICAgICAgICB2YWxpZGF0ZV90bXUoYywgaSk7CisgICAgICAgIC8vIHdlIENMQU1QIGhlcmUsIHdoaWNoIHdvcmtzIHdpdGggcHJlbXVsdGlwbGllZCAocyx0KQorICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleFBhcmFtZXRlcmkoYywKKyAgICAgICAgICAgICAgICBHR0xfVEVYVFVSRV8yRCwgR0dMX1RFWFRVUkVfV1JBUF9TLCBHR0xfQ0xBTVApOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleFBhcmFtZXRlcmkoYywKKyAgICAgICAgICAgICAgICBHR0xfVEVYVFVSRV8yRCwgR0dMX1RFWFRVUkVfV1JBUF9ULCBHR0xfQ0xBTVApOworICAgICAgICB1LmRpcnR5ID0gMHhGRjsgLy8gWFhYOiBzaG91bGQgYmUgbW9yZSBzdWJ0bGUKKworICAgICAgICBFR0xUZXh0dXJlT2JqZWN0KiB0ZXh0dXJlT2JqZWN0ID0gdS50ZXh0dXJlOyAgCisgICAgICAgIGNvbnN0IEdMaW50IFVjciA9IHRleHR1cmVPYmplY3QtPmNyb3BfcmVjdFswXSA8PCAxNjsKKyAgICAgICAgY29uc3QgR0xpbnQgVmNyID0gdGV4dHVyZU9iamVjdC0+Y3JvcF9yZWN0WzFdIDw8IDE2OworICAgICAgICBjb25zdCBHTGludCBXY3IgPSB0ZXh0dXJlT2JqZWN0LT5jcm9wX3JlY3RbMl0gPDwgMTY7CisgICAgICAgIGNvbnN0IEdMaW50IEhjciA9IHRleHR1cmVPYmplY3QtPmNyb3BfcmVjdFszXSA8PCAxNjsKKworICAgICAgICAvLyBjb21wdXRlcyB0ZXh0dXJlIGNvb3JkaW5hdGVzIChwcmUtbXVsdGlwbGllZCkKKyAgICAgICAgaW50MzJfdCBkc2R4ID0gV2NyIC8gdzsgICAvLyBkc2R4ID0gICgoV2NyL3cpL1d0KSpXdAorICAgICAgICBpbnQzMl90IGR0ZHkgPS1IY3IgLyBoOyAgIC8vIGR0ZHkgPSAtKChIY3IvaCkvSHQpKkh0CisgICAgICAgIGludDMyX3QgczAgICA9IFVjciAgICAgICAtIGdnbE11bHgoZHNkeCwgeCk7IC8vIHMwID0gVWNyIC0geCAqIGRzZHgKKyAgICAgICAgaW50MzJfdCB0MCAgID0gKFZjcitIY3IpIC0gZ2dsTXVseChkdGR5LCB5KTsgLy8gdDAgPSAoVmNyK0hjcikgLSB5KmR0ZHkKKyAgICAgICAgdGV4Y29vcmRzWzBdID0gczA7CisgICAgICAgIHRleGNvb3Jkc1sxXSA9IGRzZHg7CisgICAgICAgIHRleGNvb3Jkc1syXSA9IDA7CisgICAgICAgIHRleGNvb3Jkc1szXSA9IHQwOworICAgICAgICB0ZXhjb29yZHNbNF0gPSAwOworICAgICAgICB0ZXhjb29yZHNbNV0gPSBkdGR5OworICAgICAgICB0ZXhjb29yZHNbNl0gPSAwOworICAgICAgICB0ZXhjb29yZHNbN10gPSAwOworICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleENvb3JkR3JhZFNjYWxlOHh2KGMsIGksIHRleGNvb3Jkcyk7CisgICAgfQorCisgICAgY29uc3QgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KGVuYWJsZXMgJiAoR0dMX0VOQUJMRV9ERVBUSF9URVNUfEdHTF9FTkFCTEVfRk9HKSkpCisgICAgICAgIHNldF9kZXB0aF9hbmRfZm9nKGMsIHopOworCisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5hY3RpdmVUZXh0dXJlKGMsIGMtPnRleHR1cmVzLmFjdGl2ZSk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jb2xvcjR4dihjLCBjLT5jdXJyZW50Q29sb3JDbGFtcGVkLnYpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MuZGlzYWJsZShjLCBHR0xfV19MRVJQKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLmRpc2FibGUoYywgR0dMX0FBKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnNoYWRlTW9kZWwoYywgR0xfRkxBVCk7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5yZWN0aShjLCAKKyAgICAgICAgICAgIGdnbEZpeGVkVG9JbnRSb3VuZCh4KSwKKyAgICAgICAgICAgIGdnbEZpeGVkVG9JbnRSb3VuZCh5KSwKKyAgICAgICAgICAgIGdnbEZpeGVkVG9JbnRSb3VuZCh4KSt3LAorICAgICAgICAgICAgZ2dsRml4ZWRUb0ludFJvdW5kKHkpK2gpOworfQorCitzdGF0aWMgdm9pZCBkcmF3VGV4aU9FUyhHTGludCB4LCBHTGludCB5LCBHTGludCB6LCBHTGludCB3LCBHTGludCBoLCBvZ2xlc19jb250ZXh0X3QqIGMpCit7CisgICAgLy8gQWxsIGNvb3JkaW5hdGVzIGFyZSBpbnRlZ2VyLCBzbyBpZiB3ZSBoYXZlIG9ubHkgb25lCisgICAgLy8gdGV4dHVyZSB1bml0IGFjdGl2ZSBhbmQgbm8gc2NhbGluZyBpcyByZXF1aXJlZAorICAgIC8vIFRIRU4sIHdlIGNhbiB1c2Ugb3VyIHNwZWNpYWwgMToxIG1hcHBpbmcKKyAgICAvLyB3aGljaCBpcyBhIGxvdCBmYXN0ZXIuCisKKyAgICBpZiAoZ2dsX2xpa2VseShjLT5yYXN0ZXJpemVyLnN0YXRlLmVuYWJsZWRfdG11ID09IDEpKSB7CisgICAgICAgIGNvbnN0IGludCB0bXUgPSAwOworICAgICAgICB0ZXh0dXJlX3VuaXRfdCYgdShjLT50ZXh0dXJlcy50bXVbdG11XSk7CisgICAgICAgIEVHTFRleHR1cmVPYmplY3QqIHRleHR1cmVPYmplY3QgPSB1LnRleHR1cmU7ICAKKyAgICAgICAgY29uc3QgR0xpbnQgV2NyID0gdGV4dHVyZU9iamVjdC0+Y3JvcF9yZWN0WzJdOworICAgICAgICBjb25zdCBHTGludCBIY3IgPSB0ZXh0dXJlT2JqZWN0LT5jcm9wX3JlY3RbM107CisKKyAgICAgICAgaWYgKCh3ID09IFdjcikgJiYgKGggPT0gLUhjcikpIHsKKyAgICAgICAgICAgIGlmICgod3xoKSA8PSAwKSByZXR1cm47IC8vIHF1aWNrbHkgcmVqZWN0IGVtcHR5IHJlY3RzCisKKyAgICAgICAgICAgIGlmICh1LmRpcnR5KSB7CisgICAgICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5hY3RpdmVUZXh0dXJlKGMsIHRtdSk7CisgICAgICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5iaW5kVGV4dHVyZShjLCAmKHUudGV4dHVyZS0+c3VyZmFjZSkpOworICAgICAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4UGFyYW1ldGVyaShjLCBHR0xfVEVYVFVSRV8yRCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdHTF9URVhUVVJFX01JTl9GSUxURVIsIHUudGV4dHVyZS0+bWluX2ZpbHRlcik7CisgICAgICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy50ZXhQYXJhbWV0ZXJpKGMsIEdHTF9URVhUVVJFXzJELAorICAgICAgICAgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgdS50ZXh0dXJlLT5tYWdfZmlsdGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4R2VuaShjLCBHR0xfUywKKyAgICAgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfR0VOX01PREUsIEdHTF9PTkVfVE9fT05FKTsKKyAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4R2VuaShjLCBHR0xfVCwKKyAgICAgICAgICAgICAgICAgICAgR0dMX1RFWFRVUkVfR0VOX01PREUsIEdHTF9PTkVfVE9fT05FKTsKKyAgICAgICAgICAgIHUuZGlydHkgPSAweEZGOyAvLyBYWFg6IHNob3VsZCBiZSBtb3JlIHN1YnRsZQorICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5hY3RpdmVUZXh0dXJlKGMsIGMtPnRleHR1cmVzLmFjdGl2ZSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGNvbnN0IEdHTFN1cmZhY2UmIGNiU3VyZmFjZSA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuYnVmZmVycy5jb2xvci5zOworICAgICAgICAgICAgeSA9IGNiU3VyZmFjZS5oZWlnaHQgLSAoeSArIGgpOworICAgICAgICAgICAgY29uc3QgR0xpbnQgVWNyID0gdGV4dHVyZU9iamVjdC0+Y3JvcF9yZWN0WzBdOworICAgICAgICAgICAgY29uc3QgR0xpbnQgVmNyID0gdGV4dHVyZU9iamVjdC0+Y3JvcF9yZWN0WzFdOworICAgICAgICAgICAgY29uc3QgR0xpbnQgczAgID0gVWNyIC0geDsKKyAgICAgICAgICAgIGNvbnN0IEdMaW50IHQwICA9IChWY3IgKyBIY3IpIC0geTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgY29uc3QgR0x1aW50IHR3ID0gdGV4dHVyZU9iamVjdC0+c3VyZmFjZS53aWR0aDsKKyAgICAgICAgICAgIGNvbnN0IEdMdWludCB0aCA9IHRleHR1cmVPYmplY3QtPnN1cmZhY2UuaGVpZ2h0OworICAgICAgICAgICAgaWYgKCh1aW50MzJfdChzMCt4K3cpID4gdHcpIHx8ICh1aW50MzJfdCh0MCt5K2gpID4gdGgpKSB7CisgICAgICAgICAgICAgICAgLy8gVGhlIEdMIHNwZWMgaXMgdW5jbGVhciBhYm91dCB3aGF0IHNob3VsZCBoYXBwZW4KKyAgICAgICAgICAgICAgICAvLyBpbiB0aGlzIGNhc2UsIHNvIHdlIGp1c3QgdXNlIHRoZSBzbG93IGNhc2UsIHdoaWNoCisgICAgICAgICAgICAgICAgLy8gYXQgbGVhc3Qgd29uJ3QgY3Jhc2gKKyAgICAgICAgICAgICAgICBnb3RvIHNsb3dfY2FzZTsKKyAgICAgICAgICAgIH0gCisKKyAgICAgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4Q29vcmQyaShjLCBzMCwgdDApOworICAgICAgICAgICAgY29uc3QgdWludDMyX3QgZW5hYmxlcyA9IGMtPnJhc3Rlcml6ZXIuc3RhdGUuZW5hYmxlczsKKyAgICAgICAgICAgIGlmIChnZ2xfdW5saWtlbHkoZW5hYmxlcyAmIChHR0xfRU5BQkxFX0RFUFRIX1RFU1R8R0dMX0VOQUJMRV9GT0cpKSkKKyAgICAgICAgICAgICAgICBzZXRfZGVwdGhfYW5kX2ZvZyhjLCB6KTsKKworICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5jb2xvcjR4dihjLCBjLT5jdXJyZW50Q29sb3JDbGFtcGVkLnYpOworICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5kaXNhYmxlKGMsIEdHTF9XX0xFUlApOworICAgICAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy5kaXNhYmxlKGMsIEdHTF9BQSk7CisgICAgICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnNoYWRlTW9kZWwoYywgR0xfRkxBVCk7CisgICAgICAgICAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnJlY3RpKGMsIHgsIHksIHgrdywgeStoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworc2xvd19jYXNlOgorICAgIGRyYXdUZXh4T0VTKAorICAgICAgICAgICAgZ2dsSW50VG9GaXhlZCh4KSwgZ2dsSW50VG9GaXhlZCh5KSwgZ2dsSW50VG9GaXhlZCh6KSwKKyAgICAgICAgICAgIGdnbEludFRvRml4ZWQodyksIGdnbEludFRvRml4ZWQoaCksCisgICAgICAgICAgICBjKTsKK30KKworCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit1c2luZyBuYW1lc3BhY2UgYW5kcm9pZDsKKworCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNwcmFnbWEgbWFyayBUZXh0dXJlIEFQSQorI2VuZGlmCisKK3ZvaWQgZ2xBY3RpdmVUZXh0dXJlKEdMZW51bSB0ZXh0dXJlKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHVpbnQzMl90KHRleHR1cmUtR0xfVEVYVFVSRTApID4gdWludDMyX3QoR0dMX1RFWFRVUkVfVU5JVF9DT1VOVCkpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjLT50ZXh0dXJlcy5hY3RpdmUgPSB0ZXh0dXJlIC0gR0xfVEVYVFVSRTA7CisgICAgYy0+cmFzdGVyaXplci5wcm9jcy5hY3RpdmVUZXh0dXJlKGMsIGMtPnRleHR1cmVzLmFjdGl2ZSk7Cit9CisKK3ZvaWQgZ2xCaW5kVGV4dHVyZShHTGVudW0gdGFyZ2V0LCBHTHVpbnQgdGV4dHVyZSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmICh0YXJnZXQgIT0gR0xfVEVYVFVSRV8yRCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gQmluZCBvciBjcmVhdGUgYSB0ZXh0dXJlCisgICAgc3A8RUdMVGV4dHVyZU9iamVjdD4gdGV4OyAgICAKKyAgICBpZiAodGV4dHVyZSA9PSAwKSB7CisgICAgICAgIC8vIDAgaXMgb3VyIGxvY2FsIHRleHR1cmUgb2JqZWN0CisgICAgICAgIHRleCA9IGMtPnRleHR1cmVzLmRlZmF1bHRUZXh0dXJlOworICAgIH0gZWxzZSB7CisgICAgICAgIHRleCA9IGMtPnN1cmZhY2VNYW5hZ2VyLT50ZXh0dXJlKHRleHR1cmUpOworICAgICAgICBpZiAoZ2dsX3VubGlrZWx5KHRleCA9PSAwKSkgeworICAgICAgICAgICAgdGV4ID0gYy0+c3VyZmFjZU1hbmFnZXItPmNyZWF0ZVRleHR1cmUodGV4dHVyZSk7CisgICAgICAgICAgICBpZiAodGV4ID09IDApIHsKKyAgICAgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9PVVRfT0ZfTUVNT1JZKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgYmluZFRleHR1cmVUbXUoYywgYy0+dGV4dHVyZXMuYWN0aXZlLCB0ZXh0dXJlLCB0ZXgpOworfQorCit2b2lkIGdsR2VuVGV4dHVyZXMoR0xzaXplaSBuLCBHTHVpbnQgKnRleHR1cmVzKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKG48MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBnZW5lcmF0ZSB1bmlxdWUgKHNoYXJlZCkgdGV4dHVyZSBuYW1lcworICAgIGMtPnN1cmZhY2VNYW5hZ2VyLT5nZXRUb2tlbihuLCB0ZXh0dXJlcyk7Cit9CisKK3ZvaWQgZ2xEZWxldGVUZXh0dXJlcyhHTHNpemVpIG4sIGNvbnN0IEdMdWludCAqdGV4dHVyZXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAobjwwKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gSWYgZGVsZXRpbmcgYSBib3VuZCB0ZXh0dXJlLCBiaW5kIHRoaXMgdW5pdCB0byAwCisgICAgZm9yIChpbnQgdD0wIDsgdDxHR0xfVEVYVFVSRV9VTklUX0NPVU5UIDsgdCsrKSB7CisgICAgICAgIGlmIChjLT50ZXh0dXJlcy50bXVbdF0ubmFtZSA9PSAwKQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIGZvciAoaW50IGk9MCA7IGk8biA7IGkrKykgeworICAgICAgICAgICAgaWYgKHRleHR1cmVzW2ldICYmICh0ZXh0dXJlc1tpXSA9PSBjLT50ZXh0dXJlcy50bXVbdF0ubmFtZSkpIHsKKyAgICAgICAgICAgICAgICAvLyBiaW5kIHRoaXMgdG11IHRvIHRleHR1cmUgMAorICAgICAgICAgICAgICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+IHRleChjLT50ZXh0dXJlcy5kZWZhdWx0VGV4dHVyZSk7CisgICAgICAgICAgICAgICAgYmluZFRleHR1cmVUbXUoYywgdCwgMCwgdGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBjLT5zdXJmYWNlTWFuYWdlci0+ZGVsZXRlVGV4dHVyZXMobiwgdGV4dHVyZXMpOworICAgIGMtPnN1cmZhY2VNYW5hZ2VyLT5yZWN5Y2xlVG9rZW5zKG4sIHRleHR1cmVzKTsKK30KKwordm9pZCBnbE11bHRpVGV4Q29vcmQ0ZigKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xmbG9hdCBzLCBHTGZsb2F0IHQsIEdMZmxvYXQgciwgR0xmbG9hdCBxKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHVpbnQzMl90KHRhcmdldC1HTF9URVhUVVJFMCkgPiB1aW50MzJfdChHR0xfVEVYVFVSRV9VTklUX0NPVU5UKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGNvbnN0IGludCB0bXUgPSB0YXJnZXQtR0xfVEVYVFVSRTA7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uUyA9IGdnbEZsb2F0VG9GaXhlZChzKTsKKyAgICBjLT5jdXJyZW50LnRleHR1cmVbdG11XS5UID0gZ2dsRmxvYXRUb0ZpeGVkKHQpOworICAgIGMtPmN1cnJlbnQudGV4dHVyZVt0bXVdLlIgPSBnZ2xGbG9hdFRvRml4ZWQocik7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uUSA9IGdnbEZsb2F0VG9GaXhlZChxKTsKK30KKwordm9pZCBnbE11bHRpVGV4Q29vcmQ0eCgKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xmaXhlZCBzLCBHTGZpeGVkIHQsIEdMZml4ZWQgciwgR0xmaXhlZCBxKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHVpbnQzMl90KHRhcmdldC1HTF9URVhUVVJFMCkgPiB1aW50MzJfdChHR0xfVEVYVFVSRV9VTklUX0NPVU5UKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGNvbnN0IGludCB0bXUgPSB0YXJnZXQtR0xfVEVYVFVSRTA7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uUyA9IHM7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uVCA9IHQ7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uUiA9IHI7CisgICAgYy0+Y3VycmVudC50ZXh0dXJlW3RtdV0uUSA9IHE7Cit9CisKK3ZvaWQgZ2xQaXhlbFN0b3JlaShHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKChwbmFtZSAhPSBHTF9QQUNLX0FMSUdOTUVOVCkgJiYgKHBuYW1lICE9IEdMX1VOUEFDS19BTElHTk1FTlQpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9ICAgIAorICAgIGlmICgocGFyYW08PTAgfHwgcGFyYW0+OCkgfHwgKHBhcmFtICYgKHBhcmFtLTEpKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAocG5hbWUgPT0gR0xfUEFDS19BTElHTk1FTlQpCisgICAgICAgIGMtPnRleHR1cmVzLnBhY2tBbGlnbm1lbnQgPSBwYXJhbTsKKyAgICBpZiAocG5hbWUgPT0gR0xfVU5QQUNLX0FMSUdOTUVOVCkKKyAgICAgICAgYy0+dGV4dHVyZXMudW5wYWNrQWxpZ25tZW50ID0gcGFyYW07Cit9CisKK3ZvaWQgZ2xUZXhFbnZmKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4RW52aShjLCB0YXJnZXQsIHBuYW1lLCBHTGludChwYXJhbSkpOworfQorCit2b2lkIGdsVGV4RW52ZnYoCisgICAgICAgIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHBuYW1lID09IEdMX1RFWFRVUkVfRU5WX01PREUpIHsKKyAgICAgICAgYy0+cmFzdGVyaXplci5wcm9jcy50ZXhFbnZpKGMsIHRhcmdldCwgcG5hbWUsIEdMaW50KCpwYXJhbXMpKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAocG5hbWUgPT0gR0xfVEVYVFVSRV9FTlZfQ09MT1IpIHsKKyAgICAgICAgR0dMZml4ZWQgZml4ZWRbNF07CisgICAgICAgIGZvciAoaW50IGk9MCA7IGk8NCA7IGkrKykKKyAgICAgICAgICAgIGZpeGVkW2ldID0gZ2dsRmxvYXRUb0ZpeGVkKHBhcmFtc1tpXSk7CisgICAgICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4RW52eHYoYywgdGFyZ2V0LCBwbmFtZSwgZml4ZWQpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7Cit9CisKK3ZvaWQgZ2xUZXhFbnZ4KEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGMtPnJhc3Rlcml6ZXIucHJvY3MudGV4RW52aShjLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgZ2xUZXhFbnZ4digKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5yYXN0ZXJpemVyLnByb2NzLnRleEVudnh2KGMsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7Cit9CisKK3ZvaWQgZ2xUZXhQYXJhbWV0ZXJpdigKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCogcGFyYW1zKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHRhcmdldCAhPSBHR0xfVEVYVFVSRV8yRCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgRUdMVGV4dHVyZU9iamVjdCogdGV4dHVyZU9iamVjdCA9IGMtPnRleHR1cmVzLnRtdVtjLT50ZXh0dXJlcy5hY3RpdmVdLnRleHR1cmU7CisgICAgc3dpdGNoIChwbmFtZSkgeworICAgIGNhc2UgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTOgorICAgICAgICBtZW1jcHkodGV4dHVyZU9iamVjdC0+Y3JvcF9yZWN0LCBwYXJhbXMsIDQqc2l6ZW9mKEdMaW50KSk7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9Cit9CisKK3ZvaWQgZ2xUZXhQYXJhbWV0ZXJmKAorICAgICAgICBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICB0ZXhQYXJhbWV0ZXJ4KHRhcmdldCwgcG5hbWUsIEdMZml4ZWQocGFyYW0pLCBjKTsKK30KKwordm9pZCBnbFRleFBhcmFtZXRlcngoCisgICAgICAgIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIHRleFBhcmFtZXRlcngodGFyZ2V0LCBwbmFtZSwgcGFyYW0sIGMpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjaWYgMAorI3ByYWdtYSBtYXJrIC0KKyNlbmRpZgorCit2b2lkIGdsQ29tcHJlc3NlZFRleEltYWdlMkQoCisgICAgICAgIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGVudW0gaW50ZXJuYWxmb3JtYXQsCisgICAgICAgIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGludCBib3JkZXIsCisgICAgICAgIEdMc2l6ZWkgaW1hZ2VTaXplLCBjb25zdCBHTHZvaWQgKmRhdGEpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAodGFyZ2V0ICE9IEdMX1RFWFRVUkVfMkQpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoKGludGVybmFsZm9ybWF0IDwgR0xfUEFMRVRURTRfUkdCOF9PRVMgfHwKKyAgICAgICAgIGludGVybmFsZm9ybWF0ID4gR0xfUEFMRVRURThfUkdCNV9BMV9PRVMpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHdpZHRoPDAgfHwgaGVpZ2h0PDAgfHwgYm9yZGVyIT0wKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfVkFMVUUpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gInVuY29tcHJlc3MiIHRoZSB0ZXh0dXJlIHNpbmNlIHBpeGVsZmxpbmdlciBkb2Vzbid0IHN1cHBvcnQKKyAgICAvLyBhbnkgY29tcHJlc3NlZCB0ZXh0dXJlIGZvcm1hdCBuYXRpdmVseS4gCisgICAgR0xlbnVtIGZvcm1hdDsKKyAgICBHTGVudW0gdHlwZTsKKyAgICBzd2l0Y2ggKGludGVybmFsZm9ybWF0KSB7CisgICAgY2FzZSBHTF9QQUxFVFRFOF9SR0I4X09FUzoKKyAgICBjYXNlIEdMX1BBTEVUVEU0X1JHQjhfT0VTOgorICAgICAgICBmb3JtYXQgICAgICA9IEdMX1JHQjsKKyAgICAgICAgdHlwZSAgICAgICAgPSBHTF9VTlNJR05FRF9CWVRFOworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1BBTEVUVEU4X1JHQkE4X09FUzoKKyAgICBjYXNlIEdMX1BBTEVUVEU0X1JHQkE4X09FUzoKKyAgICAgICAgZm9ybWF0ICAgICAgPSBHTF9SR0JBOworICAgICAgICB0eXBlICAgICAgICA9IEdMX1VOU0lHTkVEX0JZVEU7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgR0xfUEFMRVRURThfUjVfRzZfQjVfT0VTOgorICAgIGNhc2UgR0xfUEFMRVRURTRfUjVfRzZfQjVfT0VTOgorICAgICAgICBmb3JtYXQgICAgICA9IEdMX1JHQjsKKyAgICAgICAgdHlwZSAgICAgICAgPSBHTF9VTlNJR05FRF9TSE9SVF81XzZfNTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHTF9QQUxFVFRFOF9SR0JBNF9PRVM6CisgICAgY2FzZSBHTF9QQUxFVFRFNF9SR0JBNF9PRVM6CisgICAgICAgIGZvcm1hdCAgICAgID0gR0xfUkdCQTsKKyAgICAgICAgdHlwZSAgICAgICAgPSBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80OworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdMX1BBTEVUVEU4X1JHQjVfQTFfT0VTOgorICAgIGNhc2UgR0xfUEFMRVRURTRfUkdCNV9BMV9PRVM6CisgICAgICAgIGZvcm1hdCAgICAgID0gR0xfUkdCQTsKKyAgICAgICAgdHlwZSAgICAgICAgPSBHTF9VTlNJR05FRF9TSE9SVF81XzVfNV8xOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKCFkYXRhIHx8ICF3aWR0aCB8fCAhaGVpZ2h0KSB7CisgICAgICAgIC8vIHVuY2xlYXIgaWYgdGhpcyBpcyBhbiBlcnJvciBvciBub3QuLi4KKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGludDMyX3Qgc2l6ZTsKKyAgICBHR0xTdXJmYWNlKiBzdXJmYWNlOworICAgIC8vIGFsbCBtaXBtYXAgbGV2ZWxzIGFyZSBzcGVjaWZpZWQgYXQgb25jZS4KKyAgICBjb25zdCBpbnQgbnVtTGV2ZWxzID0gbGV2ZWw8MCA/IC1sZXZlbCA6IDE7CisgICAgZm9yIChpbnQgaT0wIDsgaTxudW1MZXZlbHMgOyBpKyspIHsKKyAgICAgICAgaW50IGxvZF93ID0gKHdpZHRoICA+PiBpKSA/IDogMTsKKyAgICAgICAgaW50IGxvZF9oID0gKGhlaWdodCA+PiBpKSA/IDogMTsKKyAgICAgICAgaW50IGVycm9yID0gY3JlYXRlVGV4dHVyZVN1cmZhY2UoYywgJnN1cmZhY2UsICZzaXplLAorICAgICAgICAgICAgICAgIGksIGZvcm1hdCwgdHlwZSwgbG9kX3csIGxvZF9oKTsKKyAgICAgICAgaWYgKGVycm9yKSB7CisgICAgICAgICAgICBvZ2xlc19lcnJvcihjLCBlcnJvcik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZGVjb2RlUGFsZXR0ZTQoZGF0YSwgaSwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgICAgICBzdXJmYWNlLT5kYXRhLCBzdXJmYWNlLT5zdHJpZGUsIGludGVybmFsZm9ybWF0KTsKKyAgICB9Cit9CisKKwordm9pZCBnbFRleEltYWdlMkQoCisgICAgICAgIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCBpbnRlcm5hbGZvcm1hdCwKKyAgICAgICAgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMaW50IGJvcmRlciwKKyAgICAgICAgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqcGl4ZWxzKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgaWYgKHRhcmdldCAhPSBHTF9URVhUVVJFXzJEICYmIHRhcmdldCAhPSBHTF9ESVJFQ1RfVEVYVFVSRV8yRF9RVUFMQ09NTSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmICh3aWR0aDwwIHx8IGhlaWdodDwwIHx8IGJvcmRlciE9MCB8fCBsZXZlbCA8IDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGZvcm1hdCAhPSBpbnRlcm5hbGZvcm1hdCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX09QRVJBVElPTik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHZhbGlkRm9ybWF0VHlwZShjLCBmb3JtYXQsIHR5cGUpKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbnQzMl90IHNpemUgPSAwOworICAgIEdHTFN1cmZhY2UqIHN1cmZhY2UgPSAwOworICAgIGlmICh0YXJnZXQgIT0gR0xfRElSRUNUX1RFWFRVUkVfMkRfUVVBTENPTU0pIHsKKyAgICAgICAgaW50IGVycm9yID0gY3JlYXRlVGV4dHVyZVN1cmZhY2UoYywgJnN1cmZhY2UsICZzaXplLAorICAgICAgICAgICAgICAgIGxldmVsLCBmb3JtYXQsIHR5cGUsIHdpZHRoLCBoZWlnaHQpOworICAgICAgICBpZiAoZXJyb3IpIHsKKyAgICAgICAgICAgIG9nbGVzX2Vycm9yKGMsIGVycm9yKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0gZWxzZSBpZiAocGl4ZWxzID09IDAgfHwgbGV2ZWwgIT0gMCkgeworICAgICAgICAvLyBwaXhlbCBjYW4ndCBiZSBudWxsIGZvciBkaXJlY3QgdGV4dHVyZQorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX09QRVJBVElPTik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAocGl4ZWxzKSB7CisgICAgICAgIGNvbnN0IGludDMyX3QgZm9ybWF0SWR4ID0gY29udmVydEdMUGl4ZWxGb3JtYXQoZm9ybWF0LCB0eXBlKTsKKyAgICAgICAgY29uc3QgR0dMRm9ybWF0JiBwaXhlbEZvcm1hdChjLT5yYXN0ZXJpemVyLmZvcm1hdHNbZm9ybWF0SWR4XSk7CisgICAgICAgIGNvbnN0IGludDMyX3QgYWxpZ24gPSBjLT50ZXh0dXJlcy51bnBhY2tBbGlnbm1lbnQtMTsKKyAgICAgICAgY29uc3QgaW50MzJfdCBicHIgPSAoKHdpZHRoICogcGl4ZWxGb3JtYXQuc2l6ZSkgKyBhbGlnbikgJiB+YWxpZ247CisgICAgICAgIGNvbnN0IHNpemVfdCBzaXplID0gYnByICogaGVpZ2h0OworICAgICAgICBjb25zdCBpbnQzMl90IHN0cmlkZSA9IGJwciAvIHBpeGVsRm9ybWF0LnNpemU7CisKKyAgICAgICAgR0dMU3VyZmFjZSB1c2VyU3VyZmFjZTsKKyAgICAgICAgdXNlclN1cmZhY2UudmVyc2lvbiA9IHNpemVvZih1c2VyU3VyZmFjZSk7CisgICAgICAgIHVzZXJTdXJmYWNlLndpZHRoICA9IHdpZHRoOworICAgICAgICB1c2VyU3VyZmFjZS5oZWlnaHQgPSBoZWlnaHQ7CisgICAgICAgIHVzZXJTdXJmYWNlLnN0cmlkZSA9IHN0cmlkZTsKKyAgICAgICAgdXNlclN1cmZhY2UuZm9ybWF0ID0gZm9ybWF0SWR4OworICAgICAgICB1c2VyU3VyZmFjZS5jb21wcmVzc2VkRm9ybWF0ID0gMDsKKyAgICAgICAgdXNlclN1cmZhY2UuZGF0YSA9IChHTHVieXRlKilwaXhlbHM7CisKKyAgICAgICAgaWYgKHRhcmdldCAhPSBHTF9ESVJFQ1RfVEVYVFVSRV8yRF9RVUFMQ09NTSkgeworICAgICAgICAgICAgaW50IGVyciA9IGNvcHlQaXhlbHMoYywgKnN1cmZhY2UsIDAsIDAsIHVzZXJTdXJmYWNlLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTsgCisgICAgICAgICAgICBpZiAoZXJyKSB7CisgICAgICAgICAgICAgICAgb2dsZXNfZXJyb3IoYywgZXJyKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBnZW5lcmF0ZU1pcG1hcChjLCBsZXZlbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBiaW5kIGl0IHRvIHRoZSB0ZXh0dXJlIHVuaXQKKyAgICAgICAgICAgIHNwPEVHTFRleHR1cmVPYmplY3Q+IHRleCA9IGdldEFuZEJpbmRBY3RpdmVUZXh0dXJlT2JqZWN0KGMpOworICAgICAgICAgICAgdGV4LT5zZXRTdXJmYWNlKCZ1c2VyU3VyZmFjZSk7CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEKAorICAgICAgICBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xpbnQgeG9mZnNldCwKKyAgICAgICAgR0xpbnQgeW9mZnNldCwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsCisgICAgICAgIEdMZW51bSBmb3JtYXQsIEdMc2l6ZWkgaW1hZ2VTaXplLAorICAgICAgICBjb25zdCBHTHZvaWQgKmRhdGEpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworfQorCit2b2lkIGdsVGV4U3ViSW1hZ2UyRCgKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsCisgICAgICAgIEdMaW50IHlvZmZzZXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LAorICAgICAgICBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpwaXhlbHMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAodGFyZ2V0ICE9IEdMX1RFWFRVUkVfMkQpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoeG9mZnNldDwwIHx8IHlvZmZzZXQ8MCB8fCB3aWR0aDwwIHx8IGhlaWdodDwwIHx8IGxldmVsPDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHZhbGlkRm9ybWF0VHlwZShjLCBmb3JtYXQsIHR5cGUpKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBmaW5kIG91dCB3aGljaCB0ZXh0dXJlIGlzIGJvdW5kIHRvIHRoZSBjdXJyZW50IHVuaXQKKyAgICBjb25zdCBpbnQgYWN0aXZlID0gYy0+dGV4dHVyZXMuYWN0aXZlOworICAgIEVHTFRleHR1cmVPYmplY3QqIHRleCA9IGMtPnRleHR1cmVzLnRtdVthY3RpdmVdLnRleHR1cmU7CisgICAgY29uc3QgR0dMU3VyZmFjZSYgc3VyZmFjZSh0ZXgtPm1pcChsZXZlbCkpOworCisgICAgaWYgKCF0ZXgtPmludGVybmFsZm9ybWF0IHx8IHRleC0+ZGlyZWN0KSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfT1BFUkFUSU9OKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoKHhvZmZzZXQgKyB3aWR0aCAgPiBHTHNpemVpKHN1cmZhY2Uud2lkdGgpKSB8fAorICAgICAgICAoeW9mZnNldCArIGhlaWdodCA+IEdMc2l6ZWkoc3VyZmFjZS5oZWlnaHQpKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoIXdpZHRoIHx8ICFoZWlnaHQpIHsKKyAgICAgICAgcmV0dXJuOyAvLyBva2F5LCBidXQgbm8tb3AuCisgICAgfQorCisgICAgLy8gZmlndXJlIG91dCB0aGUgc2l6ZSB3ZSBuZWVkIGFzIHdlbGwgYXMgdGhlIHN0cmlkZQorICAgIGNvbnN0IGludDMyX3QgZm9ybWF0SWR4ID0gY29udmVydEdMUGl4ZWxGb3JtYXQoZm9ybWF0LCB0eXBlKTsKKyAgICBpZiAoZm9ybWF0SWR4ID09IDApIHsgLy8gd2UgZG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggdGhpcworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX09QRVJBVElPTik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBjb25zdCBHR0xGb3JtYXQmIHBpeGVsRm9ybWF0KGMtPnJhc3Rlcml6ZXIuZm9ybWF0c1tmb3JtYXRJZHhdKTsKKyAgICBjb25zdCBpbnQzMl90IGFsaWduID0gYy0+dGV4dHVyZXMudW5wYWNrQWxpZ25tZW50LTE7CisgICAgY29uc3QgaW50MzJfdCBicHIgPSAoKHdpZHRoICogcGl4ZWxGb3JtYXQuc2l6ZSkgKyBhbGlnbikgJiB+YWxpZ247CisgICAgY29uc3Qgc2l6ZV90IHNpemUgPSBicHIgKiBoZWlnaHQ7CisgICAgY29uc3QgaW50MzJfdCBzdHJpZGUgPSBicHIgLyBwaXhlbEZvcm1hdC5zaXplOworICAgIEdHTFN1cmZhY2UgdXNlclN1cmZhY2U7CisgICAgdXNlclN1cmZhY2UudmVyc2lvbiA9IHNpemVvZih1c2VyU3VyZmFjZSk7CisgICAgdXNlclN1cmZhY2Uud2lkdGggID0gd2lkdGg7CisgICAgdXNlclN1cmZhY2UuaGVpZ2h0ID0gaGVpZ2h0OworICAgIHVzZXJTdXJmYWNlLnN0cmlkZSA9IHN0cmlkZTsKKyAgICB1c2VyU3VyZmFjZS5mb3JtYXQgPSBmb3JtYXRJZHg7CisgICAgdXNlclN1cmZhY2UuY29tcHJlc3NlZEZvcm1hdCA9IDA7CisgICAgdXNlclN1cmZhY2UuZGF0YSA9IChHTHVieXRlKilwaXhlbHM7CisKKyAgICBpbnQgZXJyID0gY29weVBpeGVscyhjLAorICAgICAgICAgICAgc3VyZmFjZSwgeG9mZnNldCwgeW9mZnNldCwKKyAgICAgICAgICAgIHVzZXJTdXJmYWNlLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTsgCisgICAgaWYgKGVycikgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBlcnIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgZ2VuZXJhdGVNaXBtYXAoYywgbGV2ZWwpOworCisgICAgLy8gc2luY2Ugd2Ugb25seSBjaGFuZ2VkIHRoZSBjb250ZW50IG9mIHRoZSB0ZXh0dXJlLCB3ZSBkb24ndCBuZWVkCisgICAgLy8gdG8gY2FsbCBiaW5kVGV4dHVyZSBvbiB0aGUgbWFpbiByYXN0ZXJpemVyLgorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgZ2xDb3B5VGV4SW1hZ2UyRCgKKyAgICAgICAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMZW51bSBpbnRlcm5hbGZvcm1hdCwKKyAgICAgICAgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsCisgICAgICAgIEdMaW50IGJvcmRlcikKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmICh0YXJnZXQgIT0gR0xfVEVYVFVSRV8yRCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChpbnRlcm5hbGZvcm1hdDxHTF9BTFBIQSB8fCBpbnRlcm5hbGZvcm1hdD5HTF9MVU1JTkFOQ0VfQUxQSEEpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAod2lkdGg8MCB8fCBoZWlnaHQ8MCB8fCBib3JkZXIhPTAgfHwgbGV2ZWw8MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEdMZW51bSBmb3JtYXQgPSAwOworICAgIEdMZW51bSB0eXBlID0gR0xfVU5TSUdORURfQllURTsKKyAgICBjb25zdCBHR0xTdXJmYWNlJiBjYlN1cmZhY2UgPSBjLT5yYXN0ZXJpemVyLnN0YXRlLmJ1ZmZlcnMuY29sb3IuczsKKyAgICBjb25zdCBpbnQgY2JGb3JtYXRJZHggPSBjYlN1cmZhY2UuZm9ybWF0OworICAgIHN3aXRjaCAoY2JGb3JtYXRJZHgpIHsKKyAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCXzU2NToKKyAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81OworICAgICAgICBicmVhazsKKyAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCQV81NTUxOgorICAgICAgICB0eXBlID0gR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBHR0xfUElYRUxfRk9STUFUX1JHQkFfNDQ0NDoKKyAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQ7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICBzd2l0Y2ggKGludGVybmFsZm9ybWF0KSB7CisgICAgY2FzZSBHTF9BTFBIQToKKyAgICBjYXNlIEdMX0xVTUlOQU5DRV9BTFBIQToKKyAgICBjYXNlIEdMX0xVTUlOQU5DRToKKyAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CisgICAgICAgIGJyZWFrOyAgICAKKyAgICB9CisKKyAgICAvLyBmaWd1cmUgb3V0IHRoZSBmb3JtYXQgdG8gdXNlIGZvciB0aGUgbmV3IHRleHR1cmUKKyAgICBzd2l0Y2ggKGNiRm9ybWF0SWR4KSB7CisgICAgY2FzZSBHR0xfUElYRUxfRk9STUFUX1JHQkFfODg4ODoKKyAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfQV84OgorICAgIGNhc2UgR0dMX1BJWEVMX0ZPUk1BVF9SR0JBXzU1NTE6CisgICAgY2FzZSBHR0xfUElYRUxfRk9STUFUX1JHQkFfNDQ0NDoKKyAgICAgICAgZm9ybWF0ID0gaW50ZXJuYWxmb3JtYXQ7CisgICAgICAgIGJyZWFrOyAgICAKKyAgICBjYXNlIEdHTF9QSVhFTF9GT1JNQVRfUkdCWF84ODg4OgorICAgIGNhc2UgR0dMX1BJWEVMX0ZPUk1BVF9SR0JfODg4OgorICAgIGNhc2UgR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OgorICAgIGNhc2UgR0dMX1BJWEVMX0ZPUk1BVF9MXzg6CisgICAgICAgIHN3aXRjaCAoaW50ZXJuYWxmb3JtYXQpIHsKKyAgICAgICAgY2FzZSBHTF9MVU1JTkFOQ0U6CisgICAgICAgIGNhc2UgR0xfUkdCOgorICAgICAgICAgICAgZm9ybWF0ID0gaW50ZXJuYWxmb3JtYXQ7CisgICAgICAgICAgICBicmVhazsgICAgCisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgaWYgKGZvcm1hdCA9PSAwKSB7CisgICAgICAgIC8vIGludmFsaWQgY29tYmluYXRpb24KKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIGNyZWF0ZSB0aGUgbmV3IHRleHR1cmUuLi4KKyAgICBpbnQzMl90IHNpemU7CisgICAgR0dMU3VyZmFjZSogc3VyZmFjZTsKKyAgICBpbnQgZXJyb3IgPSBjcmVhdGVUZXh0dXJlU3VyZmFjZShjLCAmc3VyZmFjZSwgJnNpemUsCisgICAgICAgICAgICBsZXZlbCwgZm9ybWF0LCB0eXBlLCB3aWR0aCwgaGVpZ2h0KTsKKyAgICBpZiAoZXJyb3IpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgZXJyb3IpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIC8vIFRoZSBib3R0b20gcm93IGlzIHN0b3JlZCBmaXJzdCBpbiB0ZXh0dXJlcworICAgIEdHTFN1cmZhY2UgdHhTdXJmYWNlKCpzdXJmYWNlKTsKKyAgICB0eFN1cmZhY2Uuc3RyaWRlID0gLXR4U3VyZmFjZS5zdHJpZGU7CisKKyAgICAvLyAoeCx5KSBpcyB0aGUgbG93ZXItbGVmdCBjb3JuZXIgb2YgY29sb3JCdWZmZXIKKyAgICB5ID0gY2JTdXJmYWNlLmhlaWdodCAtICh5ICsgaGVpZ2h0KTsKKworICAgIGludCBlcnIgPSBjb3B5UGl4ZWxzKGMsCisgICAgICAgICAgICB0eFN1cmZhY2UsIDAsIDAsCisgICAgICAgICAgICBjYlN1cmZhY2UsIHgsIHksIGNiU3VyZmFjZS53aWR0aCwgY2JTdXJmYWNlLmhlaWdodCk7ICAKKyAgICBpZiAoZXJyKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIGVycik7CisgICAgfQorCisgICAgZ2VuZXJhdGVNaXBtYXAoYywgbGV2ZWwpOworfQorCit2b2lkIGdsQ29weVRleFN1YkltYWdlMkQoCisgICAgICAgIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LAorICAgICAgICBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCkKK3sKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGlmICh0YXJnZXQgIT0gR0xfVEVYVFVSRV8yRCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmICh4b2Zmc2V0PDAgfHwgeW9mZnNldDwwIHx8IHdpZHRoPDAgfHwgaGVpZ2h0PDAgfHwgbGV2ZWw8MCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoIXdpZHRoIHx8ICFoZWlnaHQpIHsKKyAgICAgICAgcmV0dXJuOyAvLyBva2F5LCBidXQgbm8tb3AuCisgICAgfQorCisgICAgLy8gZmluZCBvdXQgd2hpY2ggdGV4dHVyZSBpcyBib3VuZCB0byB0aGUgY3VycmVudCB1bml0CisgICAgY29uc3QgaW50IGFjdGl2ZSA9IGMtPnRleHR1cmVzLmFjdGl2ZTsKKyAgICBFR0xUZXh0dXJlT2JqZWN0KiB0ZXggPSBjLT50ZXh0dXJlcy50bXVbYWN0aXZlXS50ZXh0dXJlOworICAgIGNvbnN0IEdHTFN1cmZhY2UmIHN1cmZhY2UodGV4LT5taXAobGV2ZWwpKTsKKworICAgIGlmICghdGV4LT5pbnRlcm5hbGZvcm1hdCkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX09QRVJBVElPTik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKCh4b2Zmc2V0ICsgd2lkdGggID4gR0xzaXplaShzdXJmYWNlLndpZHRoKSkgfHwKKyAgICAgICAgKHlvZmZzZXQgKyBoZWlnaHQgPiBHTHNpemVpKHN1cmZhY2UuaGVpZ2h0KSkpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBUaGUgYm90dG9tIHJvdyBpcyBzdG9yZWQgZmlyc3QgaW4gdGV4dHVyZXMKKyAgICBHR0xTdXJmYWNlIHR4U3VyZmFjZShzdXJmYWNlKTsKKyAgICB0eFN1cmZhY2Uuc3RyaWRlID0gLXR4U3VyZmFjZS5zdHJpZGU7CisKKyAgICAvLyAoeCx5KSBpcyB0aGUgbG93ZXItbGVmdCBjb3JuZXIgb2YgY29sb3JCdWZmZXIKKyAgICBjb25zdCBHR0xTdXJmYWNlJiBjYlN1cmZhY2UgPSBjLT5yYXN0ZXJpemVyLnN0YXRlLmJ1ZmZlcnMuY29sb3IuczsKKyAgICB5ID0gY2JTdXJmYWNlLmhlaWdodCAtICh5ICsgaGVpZ2h0KTsKKworICAgIGludCBlcnIgPSBjb3B5UGl4ZWxzKGMsCisgICAgICAgICAgICBzdXJmYWNlLCB4b2Zmc2V0LCB5b2Zmc2V0LAorICAgICAgICAgICAgY2JTdXJmYWNlLCB4LCB5LCB3aWR0aCwgaGVpZ2h0KTsgIAorICAgIGlmIChlcnIpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgZXJyKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGdlbmVyYXRlTWlwbWFwKGMsIGxldmVsKTsKK30KKwordm9pZCBnbFJlYWRQaXhlbHMoCisgICAgICAgIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LAorICAgICAgICBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgR0x2b2lkICpwaXhlbHMpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBpZiAoKGZvcm1hdCAhPSBHTF9SR0JBKSAmJiAoZm9ybWF0ICE9IEdMX1JHQikpIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9FTlVNKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoKHR5cGUgIT0gR0xfVU5TSUdORURfQllURSkgJiYgKHR5cGUgIT0gR0xfVU5TSUdORURfU0hPUlRfNV82XzUpKSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfRU5VTSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHdpZHRoPDAgfHwgaGVpZ2h0PDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHg8MCB8fCB4PDApIHsKKyAgICAgICAgb2dsZXNfZXJyb3IoYywgR0xfSU5WQUxJRF9WQUxVRSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbnQzMl90IGZvcm1hdElkeCA9IEdHTF9QSVhFTF9GT1JNQVRfTk9ORTsKKyAgICBpZiAoKGZvcm1hdCA9PSBHTF9SR0JBKSAmJiAodHlwZSA9PSBHTF9VTlNJR05FRF9CWVRFKSkgeworICAgICAgICBmb3JtYXRJZHggPSBHR0xfUElYRUxfRk9STUFUX1JHQkFfODg4ODsKKyAgICB9IGVsc2UgaWYgKChmb3JtYXQgPT0gR0xfUkdCKSAmJiAodHlwZSA9PSBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSkpIHsKKyAgICAgICAgZm9ybWF0SWR4ID0gR0dMX1BJWEVMX0ZPUk1BVF9SR0JfNTY1OworICAgIH0gZWxzZSB7CisgICAgICAgIG9nbGVzX2Vycm9yKGMsIEdMX0lOVkFMSURfT1BFUkFUSU9OKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNvbnN0IEdHTFN1cmZhY2UmIHJlYWRTdXJmYWNlID0gYy0+cmFzdGVyaXplci5zdGF0ZS5idWZmZXJzLnJlYWQuczsKKyAgICBpZiAoKHgrd2lkdGggPiBHTGludChyZWFkU3VyZmFjZS53aWR0aCkpIHx8CisgICAgICAgICAgICAoeStoZWlnaHQgPiBHTGludChyZWFkU3VyZmFjZS5oZWlnaHQpKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX1ZBTFVFKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNvbnN0IEdHTEZvcm1hdCYgcGl4ZWxGb3JtYXQoYy0+cmFzdGVyaXplci5mb3JtYXRzW2Zvcm1hdElkeF0pOworICAgIGNvbnN0IGludDMyX3QgYWxpZ24gPSBjLT50ZXh0dXJlcy5wYWNrQWxpZ25tZW50LTE7CisgICAgY29uc3QgaW50MzJfdCBicHIgPSAoKHdpZHRoICogcGl4ZWxGb3JtYXQuc2l6ZSkgKyBhbGlnbikgJiB+YWxpZ247CisgICAgY29uc3QgaW50MzJfdCBzdHJpZGUgPSBicHIgLyBwaXhlbEZvcm1hdC5zaXplOworCisgICAgR0dMU3VyZmFjZSB1c2VyU3VyZmFjZTsKKyAgICB1c2VyU3VyZmFjZS52ZXJzaW9uID0gc2l6ZW9mKHVzZXJTdXJmYWNlKTsKKyAgICB1c2VyU3VyZmFjZS53aWR0aCAgPSB3aWR0aDsKKyAgICB1c2VyU3VyZmFjZS5oZWlnaHQgPSBoZWlnaHQ7CisgICAgdXNlclN1cmZhY2Uuc3RyaWRlID0gLXN0cmlkZTsgLy8gYm90dG9tIHJvdyBpcyB0cmFuc2ZlcmVkIGZpcnN0CisgICAgdXNlclN1cmZhY2UuZm9ybWF0ID0gZm9ybWF0SWR4OworICAgIHVzZXJTdXJmYWNlLmNvbXByZXNzZWRGb3JtYXQgPSAwOworICAgIHVzZXJTdXJmYWNlLmRhdGEgPSAoR0x1Ynl0ZSopcGl4ZWxzOworCisgICAgLy8gdXNlIHBpeGVsLWZsaW5nZXIgdG8gaGFuZGxlIGFsbCB0aGUgY29udmVyc2lvbnMKKyAgICBHR0xDb250ZXh0KiBnZ2wgPSBnZXRSYXN0ZXJpemVyKGMpOworICAgIGlmICghZ2dsKSB7CisgICAgICAgIC8vIHRoZSBvbmx5IHJlYXNvbiB0aGlzIHdvdWxkIGZhaWwgaXMgYmVjYXVzZSB3ZSByYW4gb3V0IG9mIG1lbW9yeQorICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9PVVRfT0ZfTUVNT1JZKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGdnbC0+Y29sb3JCdWZmZXIoZ2dsLCAmdXNlclN1cmZhY2UpOyAgLy8gZGVzdGluYXRpb24gaXMgdXNlciBidWZmZXIgCisgICAgZ2dsLT5iaW5kVGV4dHVyZShnZ2wsICZyZWFkU3VyZmFjZSk7ICAvLyBzb3VyY2UgaXMgcmVhZC1idWZmZXIKKyAgICBnZ2wtPnRleENvb3JkMmkoZ2dsLCB4LCByZWFkU3VyZmFjZS5oZWlnaHQgLSAoeSArIGhlaWdodCkpOworICAgIGdnbC0+cmVjdGkoZ2dsLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2lmIDAKKyNwcmFnbWEgbWFyayAtCisjcHJhZ21hIG1hcmsgRHJhd1RleHR1cmUgRXh0ZW5zaW9uCisjZW5kaWYKKwordm9pZCBnbERyYXdUZXhzdk9FUyhjb25zdCBHTHNob3J0KiBjb29yZHMpIHsKKyAgICBvZ2xlc19jb250ZXh0X3QqIGMgPSBvZ2xlc19jb250ZXh0X3Q6OmdldCgpOworICAgIGRyYXdUZXhpT0VTKGNvb3Jkc1swXSwgY29vcmRzWzFdLCBjb29yZHNbMl0sIGNvb3Jkc1szXSwgY29vcmRzWzRdLCBjKTsKK30KK3ZvaWQgZ2xEcmF3VGV4aXZPRVMoY29uc3QgR0xpbnQqIGNvb3JkcykgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZHJhd1RleGlPRVMoY29vcmRzWzBdLCBjb29yZHNbMV0sIGNvb3Jkc1syXSwgY29vcmRzWzNdLCBjb29yZHNbNF0sIGMpOworfQordm9pZCBnbERyYXdUZXhzT0VTKEdMc2hvcnQgeCAsIEdMc2hvcnQgeSwgR0xzaG9ydCB6LCBHTHNob3J0IHcsIEdMc2hvcnQgaCkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZHJhd1RleGlPRVMoeCwgeSwgeiwgdywgaCwgYyk7Cit9Cit2b2lkIGdsRHJhd1RleGlPRVMoR0xpbnQgeCwgR0xpbnQgeSwgR0xpbnQgeiwgR0xpbnQgdywgR0xpbnQgaCkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZHJhd1RleGlPRVMoeCwgeSwgeiwgdywgaCwgYyk7Cit9CisKK3ZvaWQgZ2xEcmF3VGV4ZnZPRVMoY29uc3QgR0xmbG9hdCogY29vcmRzKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBkcmF3VGV4eE9FUygKKyAgICAgICAgICAgIGdnbEZsb2F0VG9GaXhlZChjb29yZHNbMF0pLAorICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKGNvb3Jkc1sxXSksCisgICAgICAgICAgICBnZ2xGbG9hdFRvRml4ZWQoY29vcmRzWzJdKSwKKyAgICAgICAgICAgIGdnbEZsb2F0VG9GaXhlZChjb29yZHNbM10pLAorICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKGNvb3Jkc1s0XSksCisgICAgICAgICAgICBjKTsKK30KK3ZvaWQgZ2xEcmF3VGV4eHZPRVMoY29uc3QgR0xmaXhlZCogY29vcmRzKSB7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBkcmF3VGV4eE9FUyhjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10sIGNvb3Jkc1s0XSwgYyk7Cit9Cit2b2lkIGdsRHJhd1RleGZPRVMoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeiwgR0xmbG9hdCB3LCBHTGZsb2F0IGgpeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZHJhd1RleHhPRVMoCisgICAgICAgICAgICBnZ2xGbG9hdFRvRml4ZWQoeCksIGdnbEZsb2F0VG9GaXhlZCh5KSwgZ2dsRmxvYXRUb0ZpeGVkKHopLAorICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKHcpLCBnZ2xGbG9hdFRvRml4ZWQoaCksCisgICAgICAgICAgICBjKTsKK30KK3ZvaWQgZ2xEcmF3VGV4eE9FUyhHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6LCBHTGZpeGVkIHcsIEdMZml4ZWQgaCkgeworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgZHJhd1RleHhPRVMoeCwgeSwgeiwgdywgaCwgYyk7Cit9CmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL3RleHR1cmUuaCBiL29wZW5nbC9saWJhZ2wvdGV4dHVyZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNTc5NDgKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGliYWdsL3RleHR1cmUuaApAQCAtMCwwICsxLDQ1IEBACisvKiBsaWJzL29wZW5nbGVzL3RleHR1cmUuaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19URVhUVVJFX0gKKyNkZWZpbmUgQU5EUk9JRF9PUEVOR0xFU19URVhUVVJFX0gKKworI2luY2x1ZGUgPHN0ZGludC5oPgorI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS9waXhlbGZsaW5nZXIvZ2dsX2NvbnRleHQuaD4KKworI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2luY2x1ZGUgImNvbnRleHQuaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCit2b2lkIG9nbGVzX2luaXRfdGV4dHVyZShvZ2xlc19jb250ZXh0X3QqIGMpOwordm9pZCBvZ2xlc191bmluaXRfdGV4dHVyZShvZ2xlc19jb250ZXh0X3QqIGMpOwordm9pZCBvZ2xlc192YWxpZGF0ZV90ZXh0dXJlX2ltcGwob2dsZXNfY29udGV4dF90KiBjKTsKKworaW5saW5lIHZvaWQgb2dsZXNfdmFsaWRhdGVfdGV4dHVyZShvZ2xlc19jb250ZXh0X3QqIGMpIHsKKyAgICBpZiAoYy0+cmFzdGVyaXplci5zdGF0ZS5lbmFibGVzICYgR0dMX0VOQUJMRV9UTVVTKQorICAgICAgICBvZ2xlc192YWxpZGF0ZV90ZXh0dXJlX2ltcGwoYyk7Cit9CisKKworfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKworI2VuZGlmIC8vIEFORFJPSURfT1BFTkdMRVNfVEVYVFVSRV9ICmRpZmYgLS1naXQgYS9vcGVuZ2wvbGliYWdsL3ZlcnRleC5jcHAgYi9vcGVuZ2wvbGliYWdsL3ZlcnRleC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFkMDRkNgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvdmVydGV4LmNwcApAQCAtMCwwICsxLDI0NyBAQAorLyogbGlicy9vcGVuZ2xlcy92ZXJ0ZXguY3BwCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSAiY29udGV4dC5oIgorI2luY2x1ZGUgImZwLmgiCisjaW5jbHVkZSAidmVydGV4LmgiCisjaW5jbHVkZSAic3RhdGUuaCIKKyNpbmNsdWRlICJtYXRyaXguaCIKKworbmFtZXNwYWNlIGFuZHJvaWQgeworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgb2dsZXNfaW5pdF92ZXJ0ZXgob2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGMtPmN1bGwuZW5hYmxlID0gR0xfRkFMU0U7CisgICAgYy0+Y3VsbC5jdWxsRmFjZSA9IEdMX0JBQ0s7CisgICAgYy0+Y3VsbC5mcm9udEZhY2UgPSBHTF9DQ1c7CisKKyAgICBjLT5jdXJyZW50LmNvbG9yLnIgPSAweDEwMDAwOworICAgIGMtPmN1cnJlbnQuY29sb3IuZyA9IDB4MTAwMDA7CisgICAgYy0+Y3VycmVudC5jb2xvci5iID0gMHgxMDAwMDsKKyAgICBjLT5jdXJyZW50LmNvbG9yLmEgPSAweDEwMDAwOworCisgICAgYy0+Y3VycmVudE5vcm1hbC56ID0gMHgxMDAwMDsKK30KKwordm9pZCBvZ2xlc191bmluaXRfdmVydGV4KG9nbGVzX2NvbnRleHRfdCogYykKK3sKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gdmVydGV4IHByb2Nlc3NpbmcKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRGl2aWRlcyBhIHZlcnRleCBjbGlwIGNvb3JkaW5hdGVzIGJ5IFcKK3N0YXRpYyBpbmxpbmUKK3ZvaWQgcGVyc3BlY3RpdmUob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdiwgdWludDMyX3QgZW5hYmxlcykKK3sKKyAgICAvLyBbeCx5LHpdd2luZG93ID0gdnB0ICogKFt4LHksel1jbGlwIC8gY2xpcC53KQorICAgIC8vIFt3XXdpbmRvdyA9IDEvdworCisgICAgLy8gV2l0aCBhIHJlZ3VsYXIgcHJvamVjdGlvbiBnZW5lcmF0ZWQgYnkgZ2xGcnVzdHVtKCksCisgICAgLy8gd2UgaGF2ZSB3PS16LCB0aGVyZWZvcmUsIHcgaXMgaW4gW3pOZWFyLCB6RmFyXS4KKyAgICAvLyBBbHNvLCB6TmVhciBhbmQgekZhciBhcmUgc3RyaWNseSBwb3NpdGl2ZSwKKyAgICAvLyBhbmQgMS93ICh3aW5kb3cudykgaXMgaW4gWzEvekZhciwgMS96TmVhcl0sIHVzdWFsbHkgdGhpcworICAgIC8vIG1lYW5zIF0wLCAraW5mWyAtLSBob3dldmVyLCBpdCBpcyBhbHdheXMgcmVjb21tZW5kZWQKKyAgICAvLyB0byB1c2UgYXMgbGFyZ2UgdmFsdWVzIGFzIHBvc3NpYmxlIGZvciB6TmVhci4KKyAgICAvLyBBbGwgaW4gYWxsLCB3IGlzIHVzdWFsbHkgc21hbGxlciB0aGFuIDEuMCAoYXNzdW1pbmcKKyAgICAvLyB6TmVhciBpcyBhdCBsZWFzdCAxLjApOyBhbmQgZXZlbiBpZiB6TmVhciBpcyBzbWFsbGVyIHRoYW4gMS4wCisgICAgLy8gdmFsdWVzIG9mIHcgd29uJ3QgYmUgdG9vIGJpZy4KKworICAgIGNvbnN0IGludDMyX3QgcncgPSBnZ2xSZWNpcDI4KHYtPmNsaXAudyk7CisgICAgY29uc3QgR0xmaXhlZCogY29uc3QgbSA9IGMtPnRyYW5zZm9ybXMudnB0LnRyYW5zZm9ybS5tYXRyaXgubTsKKyAgICB2LT53aW5kb3cudyA9IHJ3OworICAgIHYtPndpbmRvdy54ID0gZ2dsTXVsQWRkeChnZ2xNdWx4KHYtPmNsaXAueCwgcncsIDE2KSwgbVsgMF0sIG1bMTJdLCAyOCk7IAorICAgIHYtPndpbmRvdy55ID0gZ2dsTXVsQWRkeChnZ2xNdWx4KHYtPmNsaXAueSwgcncsIDE2KSwgbVsgNV0sIG1bMTNdLCAyOCk7CisgICAgdi0+d2luZG93LnggPSBUUklfRlJPTV9GSVhFRCh2LT53aW5kb3cueCk7CisgICAgdi0+d2luZG93LnkgPSBUUklfRlJPTV9GSVhFRCh2LT53aW5kb3cueSk7CisgICAgaWYgKGVuYWJsZXMgJiBHR0xfRU5BQkxFX0RFUFRIX1RFU1QpIHsKKyAgICAgICAgdi0+d2luZG93LnogPSBnZ2xNdWxBZGR4KGdnbE11bHgodi0+Y2xpcC56LCBydywgMTYpLCBtWzEwXSwgbVsxNF0sIDI4KTsKKyAgICB9Cit9CisKKy8vIGZydXN0dW0gY2xpcHBpbmcgYW5kIFctZGl2aWRlCitzdGF0aWMgaW5saW5lCit2b2lkIGNsaXBGcnVzdHVtUGVyc3BlY3RpdmUob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdiwgdWludDMyX3QgZW5hYmxlcykKK3sKKyAgICAvLyBuZGMgPSBjbGlwIC8gVworICAgIC8vIHdpbmRvdyA9IG5jZCAqIHZpZXdwb3J0CisgICAgCisgICAgLy8gY2xpcCB0byB0aGUgdmlldy12b2x1bWUKKyAgICB1aW50MzJfdCBjbGlwID0gdi0+ZmxhZ3MgJiB2ZXJ0ZXhfdDo6Q0xJUF9BTEw7CisgICAgY29uc3QgR0xmaXhlZCB3ID0gdi0+Y2xpcC53OworICAgIGlmICh2LT5jbGlwLnggPCAtdykgICBjbGlwIHw9IHZlcnRleF90OjpDTElQX0w7CisgICAgaWYgKHYtPmNsaXAueCA+ICB3KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfUjsKKyAgICBpZiAodi0+Y2xpcC55IDwgLXcpICAgY2xpcCB8PSB2ZXJ0ZXhfdDo6Q0xJUF9COworICAgIGlmICh2LT5jbGlwLnkgPiAgdykgICBjbGlwIHw9IHZlcnRleF90OjpDTElQX1Q7CisgICAgaWYgKHYtPmNsaXAueiA8IC13KSAgIGNsaXAgfD0gdmVydGV4X3Q6OkNMSVBfTjsKKyAgICBpZiAodi0+Y2xpcC56ID4gIHcpICAgY2xpcCB8PSB2ZXJ0ZXhfdDo6Q0xJUF9GOworCisgICAgdi0+ZmxhZ3MgfD0gY2xpcDsKKyAgICBjLT5hcnJheXMuY3VsbCAmPSBjbGlwOworCisgICAgaWYgKGdnbF9saWtlbHkoIWNsaXApKSB7CisgICAgICAgIC8vIGlmIHRoZSB2ZXJ0ZXggaXMgY2xpcHBlZCwgd2UgZG9uJ3QgZG8gdGhlIHBlcnNwZWN0aXZlCisgICAgICAgIC8vIGRpdmlkZSwgc2luY2Ugd2UgZG9uJ3QgbmVlZCBpdHMgd2luZG93IGNvb3JkaW5hdGVzLgorICAgICAgICBwZXJzcGVjdGl2ZShjLCB2LCBlbmFibGVzKTsKKyAgICB9Cit9CisKKy8vIGZydXN0dW0gY2xpcHBpbmcsIHVzZXIgY2xpcHBpbmcgYW5kIFctZGl2aWRlCitzdGF0aWMgaW5saW5lCit2b2lkIGNsaXBBbGxQZXJzcGVjdGl2ZShvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90KiB2LCB1aW50MzJfdCBlbmFibGVzKQoreworICAgIC8vIGNvbXB1dGUgZXllIGNvb3JkaW5hdGVzCisgICAgYy0+YXJyYXlzLm12X3RyYW5zZm9ybSgKKyAgICAgICAgICAgICZjLT50cmFuc2Zvcm1zLm1vZGVsdmlldy50cmFuc2Zvcm0sICZ2LT5leWUsICZ2LT5vYmopOworICAgIHYtPmZsYWdzIHw9IHZlcnRleF90OjpFWUU7CisKKyAgICAvLyBjbGlwIHRoaXMgdmVydGV4IGFnYWluc3QgZWFjaCB1c2VyIGNsaXAgcGxhbmUKKyAgICB1aW50MzJfdCBjbGlwID0gMDsKKyAgICBpbnQgcGxhbmVzID0gYy0+Y2xpcFBsYW5lcy5lbmFibGU7CisgICAgd2hpbGUgKHBsYW5lcykgeworICAgICAgICBjb25zdCBpbnQgaSA9IDMxIC0gZ2dsQ2x6KHBsYW5lcyk7CisgICAgICAgIHBsYW5lcyAmPSB+KDE8PGkpOworICAgICAgICAvLyBYWFg6IHdlIHNob3VsZCBoYXZlIGEgc3BlY2lhbCBkb3QoKSBmb3IgMiwzLDQgY29vcmRzIHZlcnRpY2VzCisgICAgICAgIEdMZml4ZWQgZCA9IGRvdDQoYy0+Y2xpcFBsYW5lcy5wbGFuZVtpXS5lcXVhdGlvbi52LCB2LT5leWUudik7CisgICAgICAgIGlmIChkIDwgMCkgeworICAgICAgICAgICAgY2xpcCB8PSAweDEwMDw8aTsKKyAgICAgICAgfQorICAgIH0KKyAgICB2LT5mbGFncyB8PSBjbGlwOworCisgICAgY2xpcEZydXN0dW1QZXJzcGVjdGl2ZShjLCB2LCBlbmFibGVzKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIG9nbGVzX3ZlcnRleF9wcm9qZWN0KG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIHYpIHsKKyAgICBwZXJzcGVjdGl2ZShjLCB2LCBjLT5yYXN0ZXJpemVyLnN0YXRlLmVuYWJsZXMpOworfQorCit2b2lkIG9nbGVzX3ZlcnRleF9wZXJzcGVjdGl2ZTJEKG9nbGVzX2NvbnRleHRfdCogYywgdmVydGV4X3QqIHYpCit7CisgICAgLy8gaGVyZSB3ZSBhc3N1bWUgdz0xLjAgYW5kIHRoZSB2aWV3cG9ydCB0cmFuc2Zvcm1hdGlvbgorICAgIC8vIGhhcyBiZWVuIGFwcGxpZWQgYWxyZWFkeS4KKyAgICBjLT5hcnJheXMuY3VsbCA9IDA7CisgICAgdi0+d2luZG93LnggPSBUUklfRlJPTV9GSVhFRCh2LT5jbGlwLngpOworICAgIHYtPndpbmRvdy55ID0gVFJJX0ZST01fRklYRUQodi0+Y2xpcC55KTsKKyAgICB2LT53aW5kb3cueiA9IHYtPmNsaXAuejsKKyAgICB2LT53aW5kb3cudyA9IHYtPmNsaXAudyA8PCAxMjsKK30KKwordm9pZCBvZ2xlc192ZXJ0ZXhfcGVyc3BlY3RpdmUzRFoob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikgeworICAgIGNsaXBGcnVzdHVtUGVyc3BlY3RpdmUoYywgdiwgR0dMX0VOQUJMRV9ERVBUSF9URVNUKTsKK30KK3ZvaWQgb2dsZXNfdmVydGV4X3BlcnNwZWN0aXZlM0Qob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikgeworICAgIGNsaXBGcnVzdHVtUGVyc3BlY3RpdmUoYywgdiwgMCk7Cit9Cit2b2lkIG9nbGVzX3ZlcnRleF9jbGlwQWxsUGVyc3BlY3RpdmUzRFoob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikgeworICAgIGNsaXBBbGxQZXJzcGVjdGl2ZShjLCB2LCBHR0xfRU5BQkxFX0RFUFRIX1RFU1QpOworfQordm9pZCBvZ2xlc192ZXJ0ZXhfY2xpcEFsbFBlcnNwZWN0aXZlM0Qob2dsZXNfY29udGV4dF90KiBjLCB2ZXJ0ZXhfdCogdikgeworICAgIGNsaXBBbGxQZXJzcGVjdGl2ZShjLCB2LCAwKTsKK30KKworc3RhdGljIHZvaWQgY2xpcFBsYW5leChHTGVudW0gcGxhbmUsIGNvbnN0IEdMZml4ZWQqIGVxdSwgb2dsZXNfY29udGV4dF90KiBjKQoreworICAgIGNvbnN0IGludCBwID0gcGxhbmUgLSBHTF9DTElQX1BMQU5FMDsKKyAgICBpZiAoZ2dsX3VubGlrZWx5KHVpbnQzMl90KHApID4gKEdMX0NMSVBfUExBTkU1IC0gR0xfQ0xJUF9QTEFORTApKSkgeworICAgICAgICBvZ2xlc19lcnJvcihjLCBHTF9JTlZBTElEX0VOVU0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgdmVjNF90JiBlcXVhdGlvbiA9IGMtPmNsaXBQbGFuZXMucGxhbmVbcF0uZXF1YXRpb247CisgICAgbWVtY3B5KGVxdWF0aW9uLnYsIGVxdSwgc2l6ZW9mKHZlYzRfdCkpOworCisgICAgb2dsZXNfdmFsaWRhdGVfdHJhbnNmb3JtKGMsIHRyYW5zZm9ybV9zdGF0ZV90OjpNVklUKTsKKyAgICB0cmFuc2Zvcm1fdCYgbXZpdCA9IGMtPnRyYW5zZm9ybXMubXZpdDQ7CisgICAgbXZpdC5wb2ludDQoJm12aXQsICZlcXVhdGlvbiwgJmVxdWF0aW9uKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKwordm9pZCBnbENvbG9yNGYoR0xmbG9hdCByLCBHTGZsb2F0IGcsIEdMZmxvYXQgYiwgR0xmbG9hdCBhKQoreworICAgIG9nbGVzX2NvbnRleHRfdCogYyA9IG9nbGVzX2NvbnRleHRfdDo6Z2V0KCk7CisgICAgYy0+Y3VycmVudC5jb2xvci5yICAgICAgID0gZ2dsRmxvYXRUb0ZpeGVkKHIpOworICAgIGMtPmN1cnJlbnRDb2xvckNsYW1wZWQuciA9IGdnbENsYW1weChjLT5jdXJyZW50LmNvbG9yLnIpOworICAgIGMtPmN1cnJlbnQuY29sb3IuZyAgICAgICA9IGdnbEZsb2F0VG9GaXhlZChnKTsKKyAgICBjLT5jdXJyZW50Q29sb3JDbGFtcGVkLmcgPSBnZ2xDbGFtcHgoYy0+Y3VycmVudC5jb2xvci5nKTsKKyAgICBjLT5jdXJyZW50LmNvbG9yLmIgICAgICAgPSBnZ2xGbG9hdFRvRml4ZWQoYik7CisgICAgYy0+Y3VycmVudENvbG9yQ2xhbXBlZC5iID0gZ2dsQ2xhbXB4KGMtPmN1cnJlbnQuY29sb3IuYik7CisgICAgYy0+Y3VycmVudC5jb2xvci5hICAgICAgID0gZ2dsRmxvYXRUb0ZpeGVkKGEpOworICAgIGMtPmN1cnJlbnRDb2xvckNsYW1wZWQuYSA9IGdnbENsYW1weChjLT5jdXJyZW50LmNvbG9yLmEpOworfQorCit2b2lkIGdsQ29sb3I0eChHTGZpeGVkIHIsIEdMZml4ZWQgZywgR0xmaXhlZCBiLCBHTGZpeGVkIGEpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5jdXJyZW50LmNvbG9yLnIgPSByOworICAgIGMtPmN1cnJlbnQuY29sb3IuZyA9IGc7CisgICAgYy0+Y3VycmVudC5jb2xvci5iID0gYjsKKyAgICBjLT5jdXJyZW50LmNvbG9yLmEgPSBhOworICAgIGMtPmN1cnJlbnRDb2xvckNsYW1wZWQuciA9IGdnbENsYW1weChyKTsKKyAgICBjLT5jdXJyZW50Q29sb3JDbGFtcGVkLmcgPSBnZ2xDbGFtcHgoZyk7CisgICAgYy0+Y3VycmVudENvbG9yQ2xhbXBlZC5iID0gZ2dsQ2xhbXB4KGIpOworICAgIGMtPmN1cnJlbnRDb2xvckNsYW1wZWQuYSA9IGdnbENsYW1weChhKTsKK30KKwordm9pZCBnbE5vcm1hbDNmKEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5jdXJyZW50Tm9ybWFsLnggPSBnZ2xGbG9hdFRvRml4ZWQoeCk7CisgICAgYy0+Y3VycmVudE5vcm1hbC55ID0gZ2dsRmxvYXRUb0ZpeGVkKHkpOworICAgIGMtPmN1cnJlbnROb3JtYWwueiA9IGdnbEZsb2F0VG9GaXhlZCh6KTsKK30KKwordm9pZCBnbE5vcm1hbDN4KEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjLT5jdXJyZW50Tm9ybWFsLnggPSB4OworICAgIGMtPmN1cnJlbnROb3JtYWwueSA9IHk7CisgICAgYy0+Y3VycmVudE5vcm1hbC56ID0gejsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIGdsQ2xpcFBsYW5lZihHTGVudW0gcGxhbmUsIGNvbnN0IEdMZmxvYXQqIGVxdSkKK3sKKyAgICBjb25zdCBHTGZpeGVkIGVxdXhbNF0gPSB7CisgICAgICAgICAgICBnZ2xGbG9hdFRvRml4ZWQoZXF1WzBdKSwKKyAgICAgICAgICAgIGdnbEZsb2F0VG9GaXhlZChlcXVbMV0pLAorICAgICAgICAgICAgZ2dsRmxvYXRUb0ZpeGVkKGVxdVsyXSksCisgICAgICAgICAgICBnZ2xGbG9hdFRvRml4ZWQoZXF1WzNdKQorICAgIH07CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjbGlwUGxhbmV4KHBsYW5lLCBlcXV4LCBjKTsKK30KKwordm9pZCBnbENsaXBQbGFuZXgoR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZpeGVkKiBlcXUpCit7CisgICAgb2dsZXNfY29udGV4dF90KiBjID0gb2dsZXNfY29udGV4dF90OjpnZXQoKTsKKyAgICBjbGlwUGxhbmV4KHBsYW5lLCBlcXUsIGMpOworfQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYmFnbC92ZXJ0ZXguaCBiL29wZW5nbC9saWJhZ2wvdmVydGV4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTVlNjIxMwotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJhZ2wvdmVydGV4LmgKQEAgLTAsMCArMSw0OCBAQAorLyogbGlicy9vcGVuZ2xlcy92ZXJ0ZXguaAorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgQU5EUk9JRF9PUEVOR0xFU19WRVJURVhfSAorI2RlZmluZSBBTkRST0lEX09QRU5HTEVTX1ZFUlRFWF9ICisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKworbmFtZXNwYWNlIGFuZHJvaWQgeworCituYW1lc3BhY2UgZ2wgeworc3RydWN0IHZlcnRleF90Oworc3RydWN0IG9nbGVzX2NvbnRleHRfdDsKK307CisKK3ZvaWQgb2dsZXNfaW5pdF92ZXJ0ZXgob2dsZXNfY29udGV4dF90KiBjKTsKK3ZvaWQgb2dsZXNfdW5pbml0X3ZlcnRleChvZ2xlc19jb250ZXh0X3QqIGMpOworCit2b2lkIG9nbGVzX3ZlcnRleF9wZXJzcGVjdGl2ZTJEKG9nbGVzX2NvbnRleHRfdCosIHZlcnRleF90Kik7CisKK3ZvaWQgb2dsZXNfdmVydGV4X3BlcnNwZWN0aXZlM0Qob2dsZXNfY29udGV4dF90KiwgdmVydGV4X3QqKTsKK3ZvaWQgb2dsZXNfdmVydGV4X3BlcnNwZWN0aXZlM0RaKG9nbGVzX2NvbnRleHRfdCosIHZlcnRleF90Kik7Cit2b2lkIG9nbGVzX3ZlcnRleF9jbGlwQWxsUGVyc3BlY3RpdmUzRChvZ2xlc19jb250ZXh0X3QqLCB2ZXJ0ZXhfdCopOwordm9pZCBvZ2xlc192ZXJ0ZXhfY2xpcEFsbFBlcnNwZWN0aXZlM0RaKG9nbGVzX2NvbnRleHRfdCosIHZlcnRleF90Kik7CisKKwordm9pZCBvZ2xlc192ZXJ0ZXhfcHJvamVjdChvZ2xlc19jb250ZXh0X3QqIGMsIHZlcnRleF90Kik7CisKK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisKKyNlbmRpZiAvLyBBTkRST0lEX09QRU5HTEVTX1ZFUlRFWF9ICisKZGlmZiAtLWdpdCBhL29wZW5nbC9saWJzL0FuZHJvaWQubWsgYi9vcGVuZ2wvbGlicy9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlY2M3NzYKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsNTMgQEAKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQorCisjCisjIEJ1aWxkIE1FVEEgRUdMIGxpYnJhcnkKKyMKKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IAlcCisJRUdML2VnbC5jcHAgCQlcCisJRUdML2dwdS5jcHAJCQlcCisjCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgKz0gbGliY3V0aWxzIGxpYnV0aWxzIGxpYnVpCitMT0NBTF9MRExJQlMgOj0gLWxwdGhyZWFkIC1sZGwKK0xPQ0FMX01PRFVMRTo9IGxpYkVHTAorCisjIG5lZWRlZCBvbiBzaW0gYnVpbGQgYmVjYXVzZSBvZiB3ZWlyZCBsb2dnaW5nIGlzc3VlcworaWZlcSAoJChUQVJHRVRfU0lNVUxBVE9SKSx0cnVlKQorZWxzZQorICAgIExPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgKz0gbGliZGwKKyAgICAjIHdlIG5lZWQgdG8gYWNjZXNzIHRoZSBCaW9uaWMgcHJpdmF0ZSBoZWFkZXIgPGJpb25pY190bHMuaD4KKyAgICBMT0NBTF9DRkxBR1MgKz0gLUkkKExPQ0FMX1BBVEgpLy4uLy4uLy4uLy4uL2Jpb25pYy9saWJjL3ByaXZhdGUKK2VuZGlmCisKK2luY2x1ZGUgJChCVUlMRF9TSEFSRURfTElCUkFSWSkKKworCisKKyMKKyMgQnVpbGQgdGhlIHdyYXBwZXIgT3BlbkdMIEVTIGxpYnJhcnkKKyMKKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IAlcCisJR0xFU19DTS9nbC5jcHAuYXJtIAkJXAorCUdMRVNfQ00vZ2xfbG9nZ2VyLmNwcCAJXAorIworCitMT0NBTF9TSEFSRURfTElCUkFSSUVTICs9IGxpYmN1dGlscyBsaWJ1dGlscyBsaWJ1aSBsaWJFR0wKK0xPQ0FMX0xETElCUyA6PSAtbHB0aHJlYWQgLWxkbAorTE9DQUxfTU9EVUxFOj0gbGliR0xFU3YxX0NNCisKKyMgbmVlZGVkIG9uIHNpbSBidWlsZCBiZWNhdXNlIG9mIHdlaXJkIGxvZ2dpbmcgaXNzdWVzCitpZmVxICgkKFRBUkdFVF9TSU1VTEFUT1IpLHRydWUpCitlbHNlCisgICAgTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBsaWJkbAorICAgICMgd2UgbmVlZCB0byBhY2Nlc3MgdGhlIEJpb25pYyBwcml2YXRlIGhlYWRlciA8YmlvbmljX3Rscy5oPgorICAgIExPQ0FMX0NGTEFHUyArPSAtSSQoTE9DQUxfUEFUSCkvLi4vLi4vLi4vLi4vYmlvbmljL2xpYmMvcHJpdmF0ZQorZW5kaWYKKworaW5jbHVkZSAkKEJVSUxEX1NIQVJFRF9MSUJSQVJZKQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYnMvRUdML2VnbC5jcHAgYi9vcGVuZ2wvbGlicy9FR0wvZWdsLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODdjOGJjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYnMvRUdML2VnbC5jcHAKQEAgLTAsMCArMSwxMzYzIEBACisvKiAKKyAqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoqCisgKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisgKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorICoqCisgKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyAqKgorICoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisgKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorICoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJHTExvZ2dlciIKKworI2luY2x1ZGUgPGN0eXBlLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxkbGZjbi5oPgorCisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyNpbmNsdWRlIDxsaW51eC9hbmRyb2lkX3BtZW0uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8RUdML2VnbC5oPgorI2luY2x1ZGUgPEVHTC9lZ2xleHQuaD4KKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8R0xFUy9nbGV4dC5oPgorCisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorI2luY2x1ZGUgPGN1dGlscy9hdG9taWMuaD4KKyNpbmNsdWRlIDxjdXRpbHMvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGN1dGlscy9tZW1vcnkuaD4KKworI2luY2x1ZGUgPHV0aWxzL1JlZkJhc2UuaD4KKworI2luY2x1ZGUgImhvb2tzLmgiCisjaW5jbHVkZSAiZWdsX2ltcGwuaCIKKworCisjZGVmaW5lIE1BS0VfQ09ORklHKF9pbXBsLCBfaW5kZXgpICAoKEVHTENvbmZpZykoKChfaW1wbCk8PDI0KSB8IChfaW5kZXgpKSkKKyNkZWZpbmUgc2V0RXJyb3IoX2UsIF9yKSBzZXRFcnJvckV0YyhfX0ZVTkNUSU9OX18sIF9fTElORV9fLCBfZSwgX3IpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBWRVJTSU9OX01BSk9SIDEKKyNkZWZpbmUgVkVSU0lPTl9NSU5PUiA0CitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGdWZW5kb3JTdHJpbmcgICAgID0gIkFuZHJvaWQiOworc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBnVmVyc2lvblN0cmluZyAgICA9ICIxLjMxIEFuZHJvaWQgTUVUQS1FR0wiOworc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBnQ2xpZW50QXBpU3RyaW5nICA9ICJPcGVuR0wgRVMiOworc3RhdGljIGNoYXIgY29uc3QgKiBjb25zdCBnRXh0ZW5zaW9uU3RyaW5nICA9ICIiOworCit0ZW1wbGF0ZSA8aW50IE1BR0lDPgorc3RydWN0IGVnbF9vYmplY3RfdAoreworICAgIGVnbF9vYmplY3RfdCgpIDogbWFnaWMoTUFHSUMpIHsgfQorICAgIH5lZ2xfb2JqZWN0X3QoKSB7IG1hZ2ljID0gMDsgfQorICAgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIG1hZ2ljID09IE1BR0lDOyB9Citwcml2YXRlOgorICAgIHVpbnQzMl90ICAgIG1hZ2ljOworfTsKKworc3RydWN0IGVnbF9kaXNwbGF5X3QgOiBwdWJsaWMgZWdsX29iamVjdF90PCdfZHB5Jz4KK3sKKyAgICBFR0xEaXNwbGF5ICBkcHlzWzJdOworICAgIEVHTENvbmZpZyogIGNvbmZpZ3NbMl07CisgICAgRUdMaW50ICAgICAgbnVtQ29uZmlnc1syXTsKKyAgICBFR0xpbnQgICAgICBudW1Ub3RhbENvbmZpZ3M7CisgICAgY2hhciBjb25zdCogZXh0ZW5zaW9uc1N0cmluZzsKKyAgICB2b2xhdGlsZSBpbnQzMl90IHJlZnM7CisgICAgc3RydWN0IHN0cmluZ3NfdCB7CisgICAgICAgIGNoYXIgY29uc3QgKiB2ZW5kb3I7CisgICAgICAgIGNoYXIgY29uc3QgKiB2ZXJzaW9uOworICAgICAgICBjaGFyIGNvbnN0ICogY2xpZW50QXBpOworICAgICAgICBjaGFyIGNvbnN0ICogZXh0ZW5zaW9uczsKKyAgICB9OworICAgIHN0cmluZ3NfdCAgIHF1ZXJ5U3RyaW5nWzJdOworfTsKKworc3RydWN0IGVnbF9zdXJmYWNlX3QgOiBwdWJsaWMgZWdsX29iamVjdF90PCdfc3JmJz4KK3sKKyAgICBlZ2xfc3VyZmFjZV90KEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIHN1cmZhY2UsCisgICAgICAgICAgICBOYXRpdmVXaW5kb3dUeXBlIHdpbmRvdywgaW50IGltcGwsIGVnbF9jb25uZWN0aW9uX3QgY29uc3QqIGNueCkgCisgICAgOiBkcHkoZHB5KSwgc3VyZmFjZShzdXJmYWNlKSwgd2luZG93KHdpbmRvdyksIGltcGwoaW1wbCksIGNueChjbngpCisgICAgeworICAgICAgICAvLyBOT1RFOiB3aW5kb3cgbXVzdCBiZSBpbmNSZWYnZWQgYW5kIGNvbm5lY3RlZCBhbHJlYWR5CisgICAgfQorICAgIH5lZ2xfc3VyZmFjZV90KCkgeworICAgICAgICBpZiAod2luZG93KSB7CisgICAgICAgICAgICBpZiAod2luZG93LT5kaXNjb25uZWN0KQorICAgICAgICAgICAgICAgIHdpbmRvdy0+ZGlzY29ubmVjdCh3aW5kb3cpOworICAgICAgICAgICAgd2luZG93LT5kZWNSZWYod2luZG93KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBFR0xEaXNwbGF5ICAgICAgICAgICAgICAgICAgZHB5OworICAgIEVHTFN1cmZhY2UgICAgICAgICAgICAgICAgICBzdXJmYWNlOworICAgIE5hdGl2ZVdpbmRvd1R5cGUgICAgICAgICAgICB3aW5kb3c7CisgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgIGltcGw7CisgICAgZWdsX2Nvbm5lY3Rpb25fdCBjb25zdCogICAgIGNueDsKK307CisKK3N0cnVjdCBlZ2xfY29udGV4dF90IDogcHVibGljIGVnbF9vYmplY3RfdDwnX2N0eCc+Cit7CisgICAgZWdsX2NvbnRleHRfdChFR0xEaXNwbGF5IGRweSwgRUdMQ29udGV4dCBjb250ZXh0LAorICAgICAgICAgICAgaW50IGltcGwsIGVnbF9jb25uZWN0aW9uX3QgY29uc3QqIGNueCkgCisgICAgOiBkcHkoZHB5KSwgY29udGV4dChjb250ZXh0KSwgcmVhZCgwKSwgZHJhdygwKSwgaW1wbChpbXBsKSwgY254KGNueCkKKyAgICB7CisgICAgfQorICAgIEVHTERpc3BsYXkgICAgICAgICAgICAgICAgICBkcHk7CisgICAgRUdMQ29udGV4dCAgICAgICAgICAgICAgICAgIGNvbnRleHQ7CisgICAgRUdMU3VyZmFjZSAgICAgICAgICAgICAgICAgIHJlYWQ7CisgICAgRUdMU3VyZmFjZSAgICAgICAgICAgICAgICAgIGRyYXc7CisgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgIGltcGw7CisgICAgZWdsX2Nvbm5lY3Rpb25fdCBjb25zdCogICAgIGNueDsKK307CisKK3N0cnVjdCB0bHNfdAoreworICAgIHRsc190KCkgOiBlcnJvcihFR0xfU1VDQ0VTUyksIGN0eCgwKSB7IH0KKyAgICBFR0xpbnQgICAgICBlcnJvcjsKKyAgICBFR0xDb250ZXh0ICBjdHg7Cit9OworCitzdGF0aWMgdm9pZCBnbF91bmltcGxlbWVudGVkKCkgeworICAgIExPR0UoImNhbGxlZCB1bmltcGxlbWVudGVkIE9wZW5HTCBFUyBBUEkiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gR0wgLyBFR0wgaG9va3MKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI3VuZGVmIEdMX0VOVFJZCisjdW5kZWYgRUdMX0VOVFJZCisjZGVmaW5lIEdMX0VOVFJZKF9yLCBfYXBpLCAuLi4pICNfYXBpLAorI2RlZmluZSBFR0xfRU5UUlkoX3IsIF9hcGksIC4uLikgI19hcGksCisKK3N0YXRpYyBjaGFyIGNvbnN0ICogY29uc3QgZ2xfbmFtZXNbXSA9IHsKKyAgICAjaW5jbHVkZSAiZ2xfZW50cmllcy5pbiIKKyAgICBOVUxMCit9OworCitzdGF0aWMgY2hhciBjb25zdCAqIGNvbnN0IGVnbF9uYW1lc1tdID0geworICAgICNpbmNsdWRlICJlZ2xfZW50cmllcy5pbiIKKyAgICBOVUxMCit9OworCisjdW5kZWYgR0xfRU5UUlkKKyN1bmRlZiBFR0xfRU5UUlkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitlZ2xfY29ubmVjdGlvbl90IGdFR0xJbXBsWzJdOworc3RhdGljIGVnbF9kaXNwbGF5X3QgZ0Rpc3BsYXlbTlVNX0RJU1BMQVlTXTsKK3N0YXRpYyBwdGhyZWFkX211dGV4X3QgZ1RocmVhZExvY2FsU3RvcmFnZUtleU11dGV4ID0gUFRIUkVBRF9NVVRFWF9JTklUSUFMSVpFUjsKK3N0YXRpYyBwdGhyZWFkX2tleV90IGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkgPSAtMTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitnbF9ob29rc190IGdIb29rc1tJTVBMX05VTV9JTVBMRU1FTlRBVElPTlNdOworcHRocmVhZF9rZXlfdCBnR0xXcmFwcGVyS2V5ID0gLTE7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK2NvbnN0IGNoYXIgKmVnbF9zdHJlcnJvcihFR0xpbnQgZXJyKQoreworICAgIHN3aXRjaCAoZXJyKXsKKyAgICAgICAgY2FzZSBFR0xfU1VDQ0VTUzogICAgICAgICAgICAgICByZXR1cm4gIkVHTF9TVUNDRVNTIjsKKyAgICAgICAgY2FzZSBFR0xfTk9UX0lOSVRJQUxJWkVEOiAgICAgICByZXR1cm4gIkVHTF9OT1RfSU5JVElBTElaRUQiOworICAgICAgICBjYXNlIEVHTF9CQURfQUNDRVNTOiAgICAgICAgICAgIHJldHVybiAiRUdMX0JBRF9BQ0NFU1MiOworICAgICAgICBjYXNlIEVHTF9CQURfQUxMT0M6ICAgICAgICAgICAgIHJldHVybiAiRUdMX0JBRF9BTExPQyI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9BVFRSSUJVVEU6ICAgICAgICAgcmV0dXJuICJFR0xfQkFEX0FUVFJJQlVURSI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9DT05GSUc6ICAgICAgICAgICAgcmV0dXJuICJFR0xfQkFEX0NPTkZJRyI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9DT05URVhUOiAgICAgICAgICAgcmV0dXJuICJFR0xfQkFEX0NPTlRFWFQiOworICAgICAgICBjYXNlIEVHTF9CQURfQ1VSUkVOVF9TVVJGQUNFOiAgIHJldHVybiAiRUdMX0JBRF9DVVJSRU5UX1NVUkZBQ0UiOworICAgICAgICBjYXNlIEVHTF9CQURfRElTUExBWTogICAgICAgICAgIHJldHVybiAiRUdMX0JBRF9ESVNQTEFZIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX01BVENIOiAgICAgICAgICAgICByZXR1cm4gIkVHTF9CQURfTUFUQ0giOworICAgICAgICBjYXNlIEVHTF9CQURfTkFUSVZFX1BJWE1BUDogICAgIHJldHVybiAiRUdMX0JBRF9OQVRJVkVfUElYTUFQIjsKKyAgICAgICAgY2FzZSBFR0xfQkFEX05BVElWRV9XSU5ET1c6ICAgICByZXR1cm4gIkVHTF9CQURfTkFUSVZFX1dJTkRPVyI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9QQVJBTUVURVI6ICAgICAgICAgcmV0dXJuICJFR0xfQkFEX1BBUkFNRVRFUiI7CisgICAgICAgIGNhc2UgRUdMX0JBRF9TVVJGQUNFOiAgICAgICAgICAgcmV0dXJuICJFR0xfQkFEX1NVUkZBQ0UiOworICAgICAgICBjYXNlIEVHTF9DT05URVhUX0xPU1Q6ICAgICAgICAgIHJldHVybiAiRUdMX0NPTlRFWFRfTE9TVCI7CisgICAgICAgIGRlZmF1bHQ6IHJldHVybiAiVU5LTk9XTiI7CisgICAgfQorfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBjbGVhclRMUygpIHsKKyAgICBpZiAoZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSAhPSAtMSkgeworICAgICAgICB0bHNfdCogdGxzID0gKHRsc190KilwdGhyZWFkX2dldHNwZWNpZmljKGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkpOworICAgICAgICBpZiAodGxzKSB7CisgICAgICAgICAgICBkZWxldGUgdGxzOworICAgICAgICAgICAgcHRocmVhZF9zZXRzcGVjaWZpYyhnRUdMVGhyZWFkTG9jYWxTdG9yYWdlS2V5LCAwKTsKKyAgICAgICAgfQorICAgIH0KK30KKworc3RhdGljIHRsc190KiBnZXRUTFMoKQoreworICAgIHRsc190KiB0bHMgPSAodGxzX3QqKXB0aHJlYWRfZ2V0c3BlY2lmaWMoZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSk7CisgICAgaWYgKHRscyA9PSAwKSB7CisgICAgICAgIHRscyA9IG5ldyB0bHNfdDsKKyAgICAgICAgcHRocmVhZF9zZXRzcGVjaWZpYyhnRUdMVGhyZWFkTG9jYWxTdG9yYWdlS2V5LCB0bHMpOworICAgIH0KKyAgICByZXR1cm4gdGxzOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK1Qgc2V0RXJyb3JFdGMoY29uc3QgY2hhciogY2FsbGVyLCBpbnQgbGluZSwgRUdMaW50IGVycm9yLCBUIHJldHVyblZhbHVlKSB7CisgICAgaWYgKGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkgPT0gLTEpIHsKKyAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZnVGhyZWFkTG9jYWxTdG9yYWdlS2V5TXV0ZXgpOworICAgICAgICBpZiAoZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSA9PSAtMSkKKyAgICAgICAgICAgIHB0aHJlYWRfa2V5X2NyZWF0ZSgmZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSwgTlVMTCk7CisgICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnVGhyZWFkTG9jYWxTdG9yYWdlS2V5TXV0ZXgpOworICAgIH0KKyAgICB0bHNfdCogdGxzID0gZ2V0VExTKCk7CisgICAgaWYgKHRscy0+ZXJyb3IgIT0gZXJyb3IpIHsKKyAgICAgICAgTE9HRSgiJXM6JWQgZXJyb3IgJXggKCVzKSIsIGNhbGxlciwgbGluZSwgZXJyb3IsIGVnbF9zdHJlcnJvcihlcnJvcikpOworICAgICAgICB0bHMtPmVycm9yID0gZXJyb3I7CisgICAgfQorICAgIHJldHVybiByZXR1cm5WYWx1ZTsKK30KKworc3RhdGljIF9fYXR0cmlidXRlX18oKG5vaW5saW5lKSkKK0dMaW50IGdldEVycm9yKCkgeworICAgIGlmIChnRUdMVGhyZWFkTG9jYWxTdG9yYWdlS2V5ID09IC0xKQorICAgICAgICByZXR1cm4gRUdMX1NVQ0NFU1M7CisgICAgdGxzX3QqIHRscyA9ICh0bHNfdCopcHRocmVhZF9nZXRzcGVjaWZpYyhnRUdMVGhyZWFkTG9jYWxTdG9yYWdlS2V5KTsKKyAgICBpZiAoIXRscykgcmV0dXJuIEVHTF9TVUNDRVNTOworICAgIEdMaW50IGVycm9yID0gdGxzLT5lcnJvcjsKKyAgICB0bHMtPmVycm9yID0gRUdMX1NVQ0NFU1M7CisgICAgcmV0dXJuIGVycm9yOworfQorCitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQordm9pZCBzZXRDb250ZXh0KEVHTENvbnRleHQgY3R4KSB7CisgICAgaWYgKGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkgPT0gLTEpIHsKKyAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZnVGhyZWFkTG9jYWxTdG9yYWdlS2V5TXV0ZXgpOworICAgICAgICBpZiAoZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSA9PSAtMSkKKyAgICAgICAgICAgIHB0aHJlYWRfa2V5X2NyZWF0ZSgmZ0VHTFRocmVhZExvY2FsU3RvcmFnZUtleSwgTlVMTCk7CisgICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnVGhyZWFkTG9jYWxTdG9yYWdlS2V5TXV0ZXgpOworICAgIH0KKyAgICB0bHNfdCogdGxzID0gZ2V0VExTKCk7CisgICAgdGxzLT5jdHggPSBjdHg7Cit9CisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCitFR0xDb250ZXh0IGdldENvbnRleHQoKSB7CisgICAgaWYgKGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkgPT0gLTEpCisgICAgICAgIHJldHVybiBFR0xfTk9fQ09OVEVYVDsKKyAgICB0bHNfdCogdGxzID0gKHRsc190KilwdGhyZWFkX2dldHNwZWNpZmljKGdFR0xUaHJlYWRMb2NhbFN0b3JhZ2VLZXkpOworICAgIGlmICghdGxzKSByZXR1cm4gRUdMX05PX0NPTlRFWFQ7CisgICAgcmV0dXJuIHRscy0+Y3R4OworfQorCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworY2xhc3MgSVN1cmZhY2VDb21wb3NlcjsKK2NvbnN0IHNwPElTdXJmYWNlQ29tcG9zZXI+JiBnZXRTdXJmYWNlRmxpbmdlcigpOworcmVxdWVzdF9ncHVfdCogZ3B1X2FjcXVpcmUodm9pZCogdXNlcik7CitpbnQgZ3B1X3JlbGVhc2Uodm9pZCosIHJlcXVlc3RfZ3B1X3QqIGdwdSk7CisKK3N0YXRpYyBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCit2b2lkICpsb2FkX2RyaXZlcihjb25zdCBjaGFyKiBkcml2ZXIsIGdsX2hvb2tzX3QqIGhvb2tzKQoreworICAgIHZvaWQqIGRzbyA9IGRsb3Blbihkcml2ZXIsIFJUTERfTk9XIHwgUlRMRF9MT0NBTCk7CisgICAgTE9HRV9JRighZHNvLAorICAgICAgICAgICAgImNvdWxkbid0IGxvYWQgPCVzPiBsaWJyYXJ5ICglcykiLAorICAgICAgICAgICAgZHJpdmVyLCBkbGVycm9yKCkpOworCisgICAgaWYgKGRzbykgeworICAgICAgICB2b2lkKiogY3VycjsKKyAgICAgICAgY2hhciBjb25zdCAqIGNvbnN0ICogYXBpOworICAgICAgICBnbF9ob29rc190OjpnbF90KiBnbCA9ICZob29rcy0+Z2w7CisgICAgICAgIGN1cnIgPSAodm9pZCoqKWdsOworICAgICAgICBhcGkgPSBnbF9uYW1lczsKKyAgICAgICAgd2hpbGUgKCphcGkpIHsKKyAgICAgICAgICAgIHZvaWQqIGYgPSBkbHN5bShkc28sICphcGkpOworICAgICAgICAgICAgLy9MT0dEKCI8JXM+IEAgMHglcCIsICphcGksIGYpOworICAgICAgICAgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIC8vTE9HVygiPCVzPiBub3QgZm91bmQgaW4gJXMiLCAqYXBpLCBkcml2ZXIpOworICAgICAgICAgICAgICAgIGYgPSAodm9pZCopZ2xfdW5pbXBsZW1lbnRlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICpjdXJyKysgPSBmOworICAgICAgICAgICAgYXBpKys7CisgICAgICAgIH0KKyAgICAgICAgZ2xfaG9va3NfdDo6ZWdsX3QqIGVnbCA9ICZob29rcy0+ZWdsOworICAgICAgICBjdXJyID0gKHZvaWQqKillZ2w7CisgICAgICAgIGFwaSA9IGVnbF9uYW1lczsKKyAgICAgICAgd2hpbGUgKCphcGkpIHsKKyAgICAgICAgICAgIHZvaWQqIGYgPSBkbHN5bShkc28sICphcGkpOworICAgICAgICAgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIC8vTE9HVygiPCVzPiBub3QgZm91bmQgaW4gJXMiLCAqYXBpLCBkcml2ZXIpOworICAgICAgICAgICAgICAgIGYgPSAodm9pZCopMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICpjdXJyKysgPSBmOworICAgICAgICAgICAgYXBpKys7CisgICAgICAgIH0KKworICAgICAgICAvLyBob29rIHRoaXMgZHJpdmVyIHVwIHdpdGggc3VyZmFjZWZsaW5nZXIgaWYgbmVlZGVkCisgICAgICAgIHJlZ2lzdGVyX2dwdV90IHJlZ2lzdGVyX2dwdSA9IAorICAgICAgICAgICAgKHJlZ2lzdGVyX2dwdV90KWRsc3ltKGRzbywgIm9lbV9yZWdpc3Rlcl9ncHUiKTsKKworICAgICAgICBpZiAocmVnaXN0ZXJfZ3B1ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChnZXRTdXJmYWNlRmxpbmdlcigpICE9IDApIHsKKyAgICAgICAgICAgICAgICByZWdpc3Rlcl9ncHUoZHNvLCBncHVfYWNxdWlyZSwgZ3B1X3JlbGVhc2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBkc287Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdGF0aWMgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKQoraW50IGJpbmFyeVNlYXJjaCgKKyAgICAgICAgVCBjb25zdCBzb3J0ZWRBcnJheVtdLCBpbnQgZmlyc3QsIGludCBsYXN0LCBUIGtleSkKK3sKKyAgICB3aGlsZSAoZmlyc3QgPD0gbGFzdCkgeworICAgICAgICBpbnQgbWlkID0gKGZpcnN0ICsgbGFzdCkgLyAyOworICAgICAgICBpZiAoa2V5ID4gc29ydGVkQXJyYXlbbWlkXSkgeyAKKyAgICAgICAgICAgIGZpcnN0ID0gbWlkICsgMTsKKyAgICAgICAgfSBlbHNlIGlmIChrZXkgPCBzb3J0ZWRBcnJheVttaWRdKSB7IAorICAgICAgICAgICAgbGFzdCA9IG1pZCAtIDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbWlkOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAtMTsKK30KKworc3RhdGljIEVHTGludCBjb25maWdUb1VuaXF1ZUlkKGVnbF9kaXNwbGF5X3QgY29uc3QqIGRwLCBpbnQgaSwgaW50IGluZGV4KSAKK3sKKyAgICAvLyBOT1RFOiB0aGlzIG1hcHBpbmcgd29ya3Mgb25seSBpZiB3ZSBoYXZlIG5vIG1vcmUgdGhhbiB0d28gRUdMaW1wbAorICAgIHJldHVybiAoaT4wID8gZHAtPm51bUNvbmZpZ3NbMF0gOiAwKSArIGluZGV4OworfQorCitzdGF0aWMgdm9pZCB1bmlxdWVJZFRvQ29uZmlnKGVnbF9kaXNwbGF5X3QgY29uc3QqIGRwLCBFR0xpbnQgY29uZmlnSWQsCisgICAgICAgIGludCYgaSwgaW50JiBpbmRleCkgCit7CisgICAgLy8gTk9URTogdGhpcyBtYXBwaW5nIHdvcmtzIG9ubHkgaWYgd2UgaGF2ZSBubyBtb3JlIHRoYW4gdHdvIEVHTGltcGwKKyAgICBzaXplX3QgbnVtQ29uZmlncyA9IGRwLT5udW1Db25maWdzWzBdOworICAgIGkgPSBjb25maWdJZCAvIG51bUNvbmZpZ3M7CisgICAgaW5kZXggPSBjb25maWdJZCAlIG51bUNvbmZpZ3M7Cit9CisKK3N0YXRpYyBpbnQgY21wX2NvbmZpZ3MoY29uc3Qgdm9pZCogYSwgY29uc3Qgdm9pZCAqYikKK3sKKyAgICBFR0xDb25maWcgYzAgPSAqKEVHTENvbmZpZyBjb25zdCAqKWE7CisgICAgRUdMQ29uZmlnIGMxID0gKihFR0xDb25maWcgY29uc3QgKiliOworICAgIHJldHVybiBjMDxjMSA/IC0xIDogKGMwPmMxID8gMSA6IDApOworfQorCitzdHJ1Y3QgZXh0ZW50aW9uX21hcF90IHsKKyAgICBjb25zdCBjaGFyKiBuYW1lOworICAgIF9fZWdsTXVzdENhc3RUb1Byb3BlckZ1bmN0aW9uUG9pbnRlclR5cGUgYWRkcmVzczsKK307CisKK3N0YXRpYyBjb25zdCBleHRlbnRpb25fbWFwX3QgZ0V4dGVudGlvbk1hcFtdID0geworfTsKKworc3RhdGljIGV4dGVudGlvbl9tYXBfdCBnR0xFeHRlbnRpb25NYXBbTUFYX05VTUJFUl9PRl9HTF9FWFRFTlNJT05TXTsKKworc3RhdGljIHZvaWQoKmZpbmRQcm9jQWRkcmVzcyhjb25zdCBjaGFyKiBuYW1lLAorICAgICAgICBjb25zdCBleHRlbnRpb25fbWFwX3QqIG1hcCwgc2l6ZV90IG4pKSgpIAoreworICAgIGZvciAodWludDMyX3QgaT0wIDsgaTxuIDsgaSsrKSB7CisgICAgICAgIGlmICghc3RyY21wKG5hbWUsIG1hcFtpXS5uYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIG1hcFtpXS5hZGRyZXNzOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBpbnQgZ2xfY29udGV4dF9sb3N0KCkgeworICAgIHNldEdsVGhyZWFkU3BlY2lmaWMoJmdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF0pOworICAgIHJldHVybiAwOworfQorc3RhdGljIGludCBlZ2xfY29udGV4dF9sb3N0KCkgeworICAgIHNldEdsVGhyZWFkU3BlY2lmaWMoJmdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF0pOworICAgIHJldHVybiBFR0xfRkFMU0U7Cit9CitzdGF0aWMgRUdMQm9vbGVhbiBlZ2xfY29udGV4dF9sb3N0X3N3YXBfYnVmZmVycyh2b2lkKiwgdm9pZCopIHsKKyAgICB1c2xlZXAoMTAwMDAwKTsgLy8gZG9uJ3QgdXNlIGFsbCB0aGUgQ1BVCisgICAgc2V0R2xUaHJlYWRTcGVjaWZpYygmZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXSk7CisgICAgcmV0dXJuIEVHTF9GQUxTRTsKK30KK3N0YXRpYyBHTGludCBlZ2xfY29udGV4dF9sb3N0X2dldF9lcnJvcigpIHsKKyAgICByZXR1cm4gRUdMX0NPTlRFWFRfTE9TVDsKK30KK3N0YXRpYyBpbnQgZXh0X2NvbnRleHRfbG9zdCgpIHsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgZ2xfbm9fY29udGV4dCgpIHsKKyAgICBMT0dFKCJjYWxsIHRvIE9wZW5HTCBFUyBBUEkgd2l0aCBubyBjdXJyZW50IGNvbnRleHQiKTsKK30KK3N0YXRpYyB2b2lkIGVhcmx5X2VnbF9pbml0KHZvaWQpIAoreworI2lmICFVU0VfRkFTVF9UTFNfS0VZCisgICAgcHRocmVhZF9rZXlfY3JlYXRlKCZnR0xXcmFwcGVyS2V5LCBOVUxMKTsKKyNlbmRpZgorICAgIHVpbnQzMl90IGFkZHIgPSAodWludDMyX3QpKCh2b2lkKilnbF9ub19jb250ZXh0KTsKKyAgICBhbmRyb2lkX21lbXNldDMyKAorICAgICAgICAgICAgKHVpbnQzMl90Kikodm9pZCopJmdIb29rc1tJTVBMX05PX0NPTlRFWFRdLCAKKyAgICAgICAgICAgIGFkZHIsIAorICAgICAgICAgICAgc2l6ZW9mKGdIb29rc1tJTVBMX05PX0NPTlRFWFRdKSk7CisgICAgc2V0R2xUaHJlYWRTcGVjaWZpYygmZ0hvb2tzW0lNUExfTk9fQ09OVEVYVF0pOworfQorCitzdGF0aWMgcHRocmVhZF9vbmNlX3Qgb25jZV9jb250cm9sID0gUFRIUkVBRF9PTkNFX0lOSVQ7CitzdGF0aWMgaW50IHNFYXJseUluaXRTdGF0ZSA9IHB0aHJlYWRfb25jZSgmb25jZV9jb250cm9sLCAmZWFybHlfZWdsX2luaXQpOworCisKK3N0YXRpYyBpbmxpbmUKK2VnbF9kaXNwbGF5X3QqIGdldF9kaXNwbGF5KEVHTERpc3BsYXkgZHB5KQoreworICAgIHVpbnRwdHJfdCBpbmRleCA9IHVpbnRwdHJfdChkcHkpLTFVOworICAgIHJldHVybiAoaW5kZXggPj0gTlVNX0RJU1BMQVlTKSA/IE5VTEwgOiAmZ0Rpc3BsYXlbaW5kZXhdOworfQorCitzdGF0aWMgaW5saW5lCitlZ2xfc3VyZmFjZV90KiBnZXRfc3VyZmFjZShFR0xTdXJmYWNlIHN1cmZhY2UpCit7CisgICAgZWdsX3N1cmZhY2VfdCogcyA9IChlZ2xfc3VyZmFjZV90ICopc3VyZmFjZTsKKyAgICByZXR1cm4gczsKK30KKworc3RhdGljIGlubGluZQorZWdsX2NvbnRleHRfdCogZ2V0X2NvbnRleHQoRUdMQ29udGV4dCBjb250ZXh0KQoreworICAgIGVnbF9jb250ZXh0X3QqIGMgPSAoZWdsX2NvbnRleHRfdCAqKWNvbnRleHQ7CisgICAgcmV0dXJuIGM7Cit9CisKK3N0YXRpYyBlZ2xfY29ubmVjdGlvbl90KiB2YWxpZGF0ZV9kaXNwbGF5X2NvbmZpZygKKyAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgIGVnbF9kaXNwbGF5X3QgY29uc3QqJiBkcCwgaW50JiBpbXBsLCBpbnQmIGluZGV4KQoreworICAgIGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBpZiAoIWRwKSByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCAoZWdsX2Nvbm5lY3Rpb25fdCopTlVMTCk7CisKKyAgICBpbXBsID0gdWludHB0cl90KGNvbmZpZyk+PjI0OworICAgIGlmICh1aW50MzJfdChpbXBsKSA+PSAyKSB7CisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTkZJRywgKGVnbF9jb25uZWN0aW9uX3QqKU5VTEwpOworICAgIH0gCisgICAgaW5kZXggPSB1aW50cHRyX3QoY29uZmlnKSAmIDB4RkZGRkZGOworICAgIGlmIChpbmRleCA+PSBkcC0+bnVtQ29uZmlnc1tpbXBsXSkgeworICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9DT05GSUcsIChlZ2xfY29ubmVjdGlvbl90KilOVUxMKTsKKyAgICB9CisgICAgZWdsX2Nvbm5lY3Rpb25fdCogY29uc3QgY254ID0gJmdFR0xJbXBsW2ltcGxdOworICAgIGlmIChjbngtPmRzbyA9PSAwKSB7CisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTkZJRywgKGVnbF9jb25uZWN0aW9uX3QqKU5VTEwpOworICAgIH0KKyAgICByZXR1cm4gY254OworfQorCitzdGF0aWMgRUdMQm9vbGVhbiB2YWxpZGF0ZV9kaXNwbGF5X2NvbnRleHQoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4KQoreworICAgIGlmICgodWludHB0cl90KGRweSktMVUpID49IE5VTV9ESVNQTEFZUykKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKyAgICBpZiAoIWdldF9kaXNwbGF5KGRweSktPmlzVmFsaWQoKSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKyAgICBpZiAoIWN0eCkgLy8gVE9ETzogbWFrZSBzdXJlIGNvbnRleHQgaXMgYSB2YWxpZCBvYmplY3QKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09OVEVYVCwgRUdMX0ZBTFNFKTsKKyAgICBpZiAoIWdldF9jb250ZXh0KGN0eCktPmlzVmFsaWQoKSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09OVEVYVCwgRUdMX0ZBTFNFKTsKKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CisKK3N0YXRpYyBFR0xCb29sZWFuIHZhbGlkYXRlX2Rpc3BsYXlfc3VyZmFjZShFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlKQoreworICAgIGlmICgodWludHB0cl90KGRweSktMVUpID49IE5VTV9ESVNQTEFZUykKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKyAgICBpZiAoIWdldF9kaXNwbGF5KGRweSktPmlzVmFsaWQoKSkKKyAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKyAgICBpZiAoIXN1cmZhY2UpIC8vIFRPRE86IG1ha2Ugc3VyZSBzdXJmYWNlIGlzIGEgdmFsaWQgb2JqZWN0CisgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1NVUkZBQ0UsIEVHTF9GQUxTRSk7CisgICAgaWYgKCFnZXRfc3VyZmFjZShzdXJmYWNlKS0+aXNWYWxpZCgpKQorICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9TVVJGQUNFLCBFR0xfRkFMU0UpOworICAgIHJldHVybiBFR0xfVFJVRTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorfTsgLy8gbmFtZXNwYWNlIGFuZHJvaWQKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKK0VHTERpc3BsYXkgZWdsR2V0RGlzcGxheShOYXRpdmVEaXNwbGF5VHlwZSBkaXNwbGF5KQoreworICAgIGlmIChzRWFybHlJbml0U3RhdGUpIHsKKyAgICAgICAgcmV0dXJuIEVHTF9OT19ESVNQTEFZOworICAgIH0KKworICAgIHVpbnQzMl90IGluZGV4ID0gdWludDMyX3QoZGlzcGxheSk7CisgICAgaWYgKGluZGV4ID49IE5VTV9ESVNQTEFZUykgeworICAgICAgICByZXR1cm4gRUdMX05PX0RJU1BMQVk7CisgICAgfQorICAgIAorICAgIEVHTERpc3BsYXkgZHB5ID0gRUdMRGlzcGxheSh1aW50cHRyX3QoZGlzcGxheSkgKyAxTFUpOworICAgIGVnbF9kaXNwbGF5X3QqIGQgPSAmZ0Rpc3BsYXlbaW5kZXhdOworICAgICAgICAKKyAgICAvLyBkeW5hbWljYWxseSBsb2FkIGFsbCBvdXIgRUdMIGltcGxlbWVudGF0aW9ucyBmb3IgdGhhdCBkaXNwbGF5CisgICAgLy8gYW5kIGNhbGwgaW50byB0aGUgcmVhbCBlZ2xHZXRHaXNwbGF5KCkKKyAgICBlZ2xfY29ubmVjdGlvbl90KiBjbnggPSAmZ0VHTEltcGxbSU1QTF9TT0ZUV0FSRV07CisgICAgaWYgKGNueC0+ZHNvID09IDApIHsKKyAgICAgICAgY254LT5ob29rcyA9ICZnSG9va3NbSU1QTF9TT0ZUV0FSRV07CisgICAgICAgIGNueC0+ZHNvID0gbG9hZF9kcml2ZXIoImxpYmFnbC5zbyIsIGNueC0+aG9va3MpOworICAgIH0KKyAgICBpZiAoY254LT5kc28gJiYgZC0+ZHB5c1tJTVBMX1NPRlRXQVJFXT09RUdMX05PX0RJU1BMQVkpIHsKKyAgICAgICAgZC0+ZHB5c1tJTVBMX1NPRlRXQVJFXSA9IGNueC0+aG9va3MtPmVnbC5lZ2xHZXREaXNwbGF5KGRpc3BsYXkpOworICAgICAgICBMT0dFX0lGKGQtPmRweXNbSU1QTF9TT0ZUV0FSRV09PUVHTF9OT19ESVNQTEFZLAorICAgICAgICAgICAgICAgICJObyBFR0xEaXNwbGF5IGZvciBzb2Z0d2FyZSBFR0whIik7CisgICAgfQorCisgICAgY254ID0gJmdFR0xJbXBsW0lNUExfSEFSRFdBUkVdOworICAgIGlmIChjbngtPmRzbyA9PSAwICYmIGNueC0+dW5hdmFpbGFibGUgPT0gMCkgeworICAgICAgICBjaGFyIHZhbHVlW1BST1BFUlRZX1ZBTFVFX01BWF07CisgICAgICAgIHByb3BlcnR5X2dldCgiZGVidWcuZWdsLmh3IiwgdmFsdWUsICIxIik7CisgICAgICAgIGlmIChhdG9pKHZhbHVlKSAhPSAwKSB7CisgICAgICAgICAgICBjbngtPmhvb2tzID0gJmdIb29rc1tJTVBMX0hBUkRXQVJFXTsKKyAgICAgICAgICAgIGNueC0+ZHNvID0gbG9hZF9kcml2ZXIoImxpYmhnbC5zbyIsIGNueC0+aG9va3MpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HRCgiM0QgaGFyZHdhcmUgYWNjZWxlcmF0aW9uIGlzIGRpc2FibGVkIik7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGNueC0+ZHNvICYmIGQtPmRweXNbSU1QTF9IQVJEV0FSRV09PUVHTF9OT19ESVNQTEFZKSB7CisgICAgICAgIGFuZHJvaWRfbWVtc2V0MzIoCisgICAgICAgICAgICAgICAgKHVpbnQzMl90Kikodm9pZCopJmdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF0uZ2wsCisgICAgICAgICAgICAgICAgKHVpbnQzMl90KSgodm9pZCopZ2xfY29udGV4dF9sb3N0KSwKKyAgICAgICAgICAgICAgICBzaXplb2YoZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXS5nbCkpOworICAgICAgICBhbmRyb2lkX21lbXNldDMyKAorICAgICAgICAgICAgICAgICh1aW50MzJfdCopKHZvaWQqKSZnSG9va3NbSU1QTF9DT05URVhUX0xPU1RdLmVnbCwKKyAgICAgICAgICAgICAgICAodWludDMyX3QpKCh2b2lkKillZ2xfY29udGV4dF9sb3N0KSwKKyAgICAgICAgICAgICAgICBzaXplb2YoZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXS5lZ2wpKTsKKyAgICAgICAgYW5kcm9pZF9tZW1zZXQzMigKKyAgICAgICAgICAgICAgICAodWludDMyX3QqKSh2b2lkKikmZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXS5leHQsCisgICAgICAgICAgICAgICAgKHVpbnQzMl90KSgodm9pZCopZXh0X2NvbnRleHRfbG9zdCksCisgICAgICAgICAgICAgICAgc2l6ZW9mKGdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF0uZXh0KSk7CisKKyAgICAgICAgZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXS5lZ2wuZWdsU3dhcEJ1ZmZlcnMgPQorICAgICAgICAgICAgICAgIGVnbF9jb250ZXh0X2xvc3Rfc3dhcF9idWZmZXJzOworICAgICAgICAKKyAgICAgICAgZ0hvb2tzW0lNUExfQ09OVEVYVF9MT1NUXS5lZ2wuZWdsR2V0RXJyb3IgPQorICAgICAgICAgICAgICAgIGVnbF9jb250ZXh0X2xvc3RfZ2V0X2Vycm9yOworCisgICAgICAgIGdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF0uZWdsLmVnbFRlcm1pbmF0ZSA9CisgICAgICAgICAgICAgICAgZ0hvb2tzW0lNUExfSEFSRFdBUkVdLmVnbC5lZ2xUZXJtaW5hdGU7CisgICAgICAgIAorICAgICAgICBkLT5kcHlzW0lNUExfSEFSRFdBUkVdID0gY254LT5ob29rcy0+ZWdsLmVnbEdldERpc3BsYXkoZGlzcGxheSk7CisgICAgICAgIGlmIChkLT5kcHlzW0lNUExfSEFSRFdBUkVdID09IEVHTF9OT19ESVNQTEFZKSB7CisgICAgICAgICAgICBMT0dFKCJoL3cgYWNjZWxlcmF0ZWQgZWdsR2V0RGlzcGxheSgpIGZhaWxlZCAoJXMpIiwKKyAgICAgICAgICAgICAgICAgICAgZWdsX3N0cmVycm9yKGNueC0+aG9va3MtPmVnbC5lZ2xHZXRFcnJvcigpKSk7CisgICAgICAgICAgICBkbGNsb3NlKCh2b2lkKiljbngtPmRzbyk7CisgICAgICAgICAgICBjbngtPmRzbyA9IDA7CisgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIGZhaWx1cmUsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IHRyeSBhZ2FpbgorICAgICAgICAgICAgLy8gYXMgaXQncyBleHBlbnNpdmUuCisgICAgICAgICAgICBjbngtPnVuYXZhaWxhYmxlID0gMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBkcHk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEluaXRpYWxpemF0aW9uCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0VHTEJvb2xlYW4gZWdsSW5pdGlhbGl6ZShFR0xEaXNwbGF5IGRweSwgRUdMaW50ICptYWpvciwgRUdMaW50ICptaW5vcikKK3sKKyAgICBlZ2xfZGlzcGxheV90ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGlmICghZHApIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisKKyAgICBpZiAoYW5kcm9pZF9hdG9taWNfaW5jKCZkcC0+cmVmcykgPiAwKSB7CisgICAgICAgIGlmIChtYWpvciAhPSBOVUxMKSAqbWFqb3IgPSBWRVJTSU9OX01BSk9SOworICAgICAgICBpZiAobWlub3IgIT0gTlVMTCkgKm1pbm9yID0gVkVSU0lPTl9NSU5PUjsKKyAgICAgICAgcmV0dXJuIEVHTF9UUlVFOworICAgIH0KKyAgICAKKyAgICBzZXRHbFRocmVhZFNwZWNpZmljKCZnSG9va3NbSU1QTF9OT19DT05URVhUXSk7CisgICAgCisgICAgLy8gaW5pdGlhbGl6ZSBlYWNoIEVHTCBhbmQKKyAgICAvLyBidWlsZCBvdXIgb3duIGV4dGVuc2lvbiBzdHJpbmcgZmlyc3QsIGJhc2VkIG9uIHRoZSBleHRlbnNpb24gd2Uga25vdworICAgIC8vIGFuZCB0aGUgZXh0ZW5zaW9uIHN1cHBvcnRlZCBieSBvdXIgY2xpZW50IGltcGxlbWVudGF0aW9uCisgICAgZHAtPmV4dGVuc2lvbnNTdHJpbmcgPSBzdHJkdXAoZ0V4dGVuc2lvblN0cmluZyk7CisgICAgZm9yIChpbnQgaT0wIDsgaTwyIDsgaSsrKSB7CisgICAgICAgIGVnbF9jb25uZWN0aW9uX3QqIGNvbnN0IGNueCA9ICZnRUdMSW1wbFtpXTsKKyAgICAgICAgY254LT5tYWpvciA9IC0xOworICAgICAgICBjbngtPm1pbm9yID0gLTE7CisgICAgICAgIGlmICghY254LT5kc28pIAorICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xJbml0aWFsaXplKAorICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCAmY254LT5tYWpvciwgJmNueC0+bWlub3IpKSB7CisKKyAgICAgICAgICAgIC8vTE9HRCgiaW5pdGlhbGl6ZWQgJWQgZHB5PSVwLCB2ZXI9JWQuJWQsIGNueD0lcCIsCisgICAgICAgICAgICAvLyAgICAgICAgaSwgZHAtPmRweXNbaV0sIGNueC0+bWFqb3IsIGNueC0+bWlub3IsIGNueCk7CisKKyAgICAgICAgICAgIC8vIGdldCB0aGUgcXVlcnktc3RyaW5ncyBmb3IgdGhpcyBkaXNwbGF5IGZvciBlYWNoIGltcGxlbWVudGF0aW9uCisgICAgICAgICAgICBkcC0+cXVlcnlTdHJpbmdbaV0udmVuZG9yID0KKyAgICAgICAgICAgICAgICBjbngtPmhvb2tzLT5lZ2wuZWdsUXVlcnlTdHJpbmcoZHAtPmRweXNbaV0sIEVHTF9WRU5ET1IpOworICAgICAgICAgICAgZHAtPnF1ZXJ5U3RyaW5nW2ldLnZlcnNpb24gPQorICAgICAgICAgICAgICAgIGNueC0+aG9va3MtPmVnbC5lZ2xRdWVyeVN0cmluZyhkcC0+ZHB5c1tpXSwgRUdMX1ZFUlNJT04pOworICAgICAgICAgICAgZHAtPnF1ZXJ5U3RyaW5nW2ldLmV4dGVuc2lvbnMgPSBzdHJkdXAoCisgICAgICAgICAgICAgICAgICAgIGNueC0+aG9va3MtPmVnbC5lZ2xRdWVyeVN0cmluZyhkcC0+ZHB5c1tpXSwgRUdMX0VYVEVOU0lPTlMpKTsKKyAgICAgICAgICAgIGRwLT5xdWVyeVN0cmluZ1tpXS5jbGllbnRBcGkgPQorICAgICAgICAgICAgICAgIGNueC0+aG9va3MtPmVnbC5lZ2xRdWVyeVN0cmluZyhkcC0+ZHB5c1tpXSwgRUdMX0NMSUVOVF9BUElTKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HRCgiJWQ6IGVnbEluaXRpYWxpemUoKSBmYWlsZWQgKCVzKSIsIAorICAgICAgICAgICAgICAgICAgICBpLCBlZ2xfc3RyZXJyb3IoY254LT5ob29rcy0+ZWdsLmVnbEdldEVycm9yKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEVHTEJvb2xlYW4gcmVzID0gRUdMX0ZBTFNFOworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbyAmJiBjbngtPm1ham9yPj0wICYmIGNueC0+bWlub3I+PTApIHsKKyAgICAgICAgICAgIEVHTGludCBuOworICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xHZXRDb25maWdzKGRwLT5kcHlzW2ldLCAwLCAwLCAmbikpIHsKKyAgICAgICAgICAgICAgICBkcC0+Y29uZmlnc1tpXSA9IChFR0xDb25maWcqKW1hbGxvYyhzaXplb2YoRUdMQ29uZmlnKSpuKTsKKyAgICAgICAgICAgICAgICBpZiAoZHAtPmNvbmZpZ3NbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xHZXRDb25maWdzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBkcC0+Y29uZmlnc1tpXSwgbiwgJmRwLT5udW1Db25maWdzW2ldKSkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29ydCB0aGUgY29uZmlndXJhdGlvbnMgc28gd2UgY2FuIGRvIGJpbmFyeSBzZWFyY2hlcworICAgICAgICAgICAgICAgICAgICAgICAgcXNvcnQoICBkcC0+Y29uZmlnc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHAtPm51bUNvbmZpZ3NbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihFR0xDb25maWcpLCBjbXBfY29uZmlncyk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGRwLT5udW1Ub3RhbENvbmZpZ3MgKz0gbjsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IEVHTF9UUlVFOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKHJlcyA9PSBFR0xfVFJVRSkgeworICAgICAgICBpZiAobWFqb3IgIT0gTlVMTCkgKm1ham9yID0gVkVSU0lPTl9NQUpPUjsKKyAgICAgICAgaWYgKG1pbm9yICE9IE5VTEwpICptaW5vciA9IFZFUlNJT05fTUlOT1I7CisgICAgICAgIHJldHVybiBFR0xfVFJVRTsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9OT1RfSU5JVElBTElaRUQsIEVHTF9GQUxTRSk7Cit9CisKK0VHTEJvb2xlYW4gZWdsVGVybWluYXRlKEVHTERpc3BsYXkgZHB5KQoreworICAgIGVnbF9kaXNwbGF5X3QqIGNvbnN0IGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBpZiAoIWRwKSByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9ESVNQTEFZLCBFR0xfRkFMU0UpOworICAgIGlmIChhbmRyb2lkX2F0b21pY19kZWMoJmRwLT5yZWZzKSAhPSAxKQorICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgICAgIAorICAgIEVHTEJvb2xlYW4gcmVzID0gRUdMX0ZBTFNFOworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbykgeworICAgICAgICAgICAgY254LT5ob29rcy0+ZWdsLmVnbFRlcm1pbmF0ZShkcC0+ZHB5c1tpXSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8qIFJFVklTSVQ6IGl0J3MgdW5jbGVhciB3aGF0IHRvIGRvIGlmIGVnbFRlcm1pbmF0ZSgpIGZhaWxzLAorICAgICAgICAgICAgICogb24gb25lIGVuZCB3ZSBzaG91bGRuJ3QgY2FyZSwgb24gdGhlIG90aGVyIGVuZCBpZiBpdCBmYWlscworICAgICAgICAgICAgICogaXQgbWlnaHQgbm90IGJlIHNhZmUgdG8gY2FsbCBkbGNsb3NlKCkgKHRoZXJlIGNvdWxkIGJlIHNvbWUKKyAgICAgICAgICAgICAqIHRocmVhZHMgYXJvdW5kKS4gKi8KKyAgICAgICAgICAgIAorICAgICAgICAgICAgZnJlZShkcC0+Y29uZmlnc1tpXSk7CisgICAgICAgICAgICBmcmVlKCh2b2lkKilkcC0+cXVlcnlTdHJpbmdbaV0uZXh0ZW5zaW9ucyk7CisgICAgICAgICAgICBkcC0+bnVtQ29uZmlnc1tpXSA9IDA7CisgICAgICAgICAgICBkcC0+ZHB5c1tpXSA9IEVHTF9OT19ESVNQTEFZOworICAgICAgICAgICAgZGxjbG9zZSgodm9pZCopY254LT5kc28pOworICAgICAgICAgICAgY254LT5kc28gPSAwOworICAgICAgICAgICAgcmVzID0gRUdMX1RSVUU7CisgICAgICAgIH0KKyAgICB9CisgICAgZnJlZSgodm9pZCopZHAtPmV4dGVuc2lvbnNTdHJpbmcpOworICAgIGRwLT5leHRlbnNpb25zU3RyaW5nID0gMDsKKyAgICBkcC0+bnVtVG90YWxDb25maWdzID0gMDsKKyAgICBjbGVhclRMUygpOworICAgIHJldHVybiByZXM7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGNvbmZpZ3VyYXRpb24KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRUdMQm9vbGVhbiBlZ2xHZXRDb25maWdzKCAgIEVHTERpc3BsYXkgZHB5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVHTENvbmZpZyAqY29uZmlncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xpbnQgY29uZmlnX3NpemUsIEVHTGludCAqbnVtX2NvbmZpZykKK3sKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGlmICghZHApIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisKKyAgICBHTGludCBudW1Db25maWdzID0gZHAtPm51bVRvdGFsQ29uZmlnczsKKyAgICBpZiAoIWNvbmZpZ3MpIHsKKyAgICAgICAgKm51bV9jb25maWcgPSBudW1Db25maWdzOworICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgfQorICAgIEdMaW50IG4gPSAwOworICAgIGZvciAoaW50IGo9MCA7IGo8MiA7IGorKykgeworICAgICAgICBmb3IgKGludCBpPTAgOyBpPGRwLT5udW1Db25maWdzW2pdICYmIGNvbmZpZ19zaXplIDsgaSsrKSB7CisgICAgICAgICAgICAqY29uZmlncysrID0gTUFLRV9DT05GSUcoaiwgaSk7CisgICAgICAgICAgICBjb25maWdfc2l6ZS0tOworICAgICAgICAgICAgbisrOworICAgICAgICB9CisgICAgfSAgICAKKyAgICAKKyAgICAqbnVtX2NvbmZpZyA9IG47CisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCitFR0xCb29sZWFuIGVnbENob29zZUNvbmZpZyggRUdMRGlzcGxheSBkcHksIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMQ29uZmlnICpjb25maWdzLCBFR0xpbnQgY29uZmlnX3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMaW50ICpudW1fY29uZmlnKQoreworICAgIGVnbF9kaXNwbGF5X3QgY29uc3QgKiBjb25zdCBkcCA9IGdldF9kaXNwbGF5KGRweSk7CisgICAgaWYgKCFkcCkgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKworICAgIGlmIChjb25maWdzID09IDApIHsKKyAgICAgICAgKm51bV9jb25maWcgPSAwOworICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgfQorCisgICAgRUdMaW50IG47CisgICAgRUdMQm9vbGVhbiByZXMgPSBFR0xfRkFMU0U7CisgICAgKm51bV9jb25maWcgPSAwOworCisgICAgCisgICAgLy8gSXQgaXMgdW5mb3J0dW5hdGUsIGJ1dCB3ZSBuZWVkIHRvIHJlbWFwIHRoZSBFR0xfQ09ORklHX0lEcywgCisgICAgLy8gdG8gZG8gIHRoaXMsIHdlIGhhdmUgdG8gZ28gdGhyb3VnaCB0aGUgYXR0cmliX2xpc3QgYXJyYXkgb25jZQorICAgIC8vIHRvIGZpZ3VyZSBvdXQgYm90aCBpdHMgc2l6ZSBhbmQgaWYgaXQgY29udGFpbnMgYW4gRUdMX0NPTkZJR19JRAorICAgIC8vIGtleS4gSWYgc28sIHRoZSBmdWxsIGFycmF5IGlzIGNvcGllZCBhbmQgcGF0Y2hlZC4KKyAgICAvLyBOT1RFOiB3ZSBhc3N1bWUgdGhhdCB0aGVyZSBjYW4gYmUgb25seSBvbmUgb2NjdXJyZW5jZQorICAgIC8vIG9mIEVHTF9DT05GSUdfSUQuCisgICAgCisgICAgRUdMaW50IHBhdGNoX2luZGV4ID0gLTE7CisgICAgR0xpbnQgYXR0cjsKKyAgICBzaXplX3Qgc2l6ZSA9IDA7CisgICAgd2hpbGUgKChhdHRyPWF0dHJpYl9saXN0W3NpemVdKSkgeworICAgICAgICBpZiAoYXR0ciA9PSBFR0xfQ09ORklHX0lEKQorICAgICAgICAgICAgcGF0Y2hfaW5kZXggPSBzaXplOworICAgICAgICBzaXplICs9IDI7CisgICAgfQorICAgIGlmIChwYXRjaF9pbmRleCA+PSAwKSB7CisgICAgICAgIHNpemUgKz0gMjsgLy8gd2UgbmVlZCBjb3B5IHRoZSBzZW50aW5lbCBhcyB3ZWxsCisgICAgICAgIEVHTGludCogbmV3X2xpc3QgPSAoRUdMaW50KiltYWxsb2Moc2l6ZSpzaXplb2YoRUdMaW50KSk7CisgICAgICAgIGlmIChuZXdfbGlzdCA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQUxMT0MsIEVHTF9GQUxTRSk7CisgICAgICAgIG1lbWNweShuZXdfbGlzdCwgYXR0cmliX2xpc3QsIHNpemUqc2l6ZW9mKEVHTGludCkpOworCisgICAgICAgIC8vIHBhdGNoIHRoZSByZXF1ZXN0ZWQgRUdMX0NPTkZJR19JRAorICAgICAgICBpbnQgaSwgaW5kZXg7CisgICAgICAgIEVHTGludCYgY29uZmlnSWQobmV3X2xpc3RbcGF0Y2hfaW5kZXgrMV0pOworICAgICAgICB1bmlxdWVJZFRvQ29uZmlnKGRwLCBjb25maWdJZCwgaSwgaW5kZXgpOworICAgICAgICAKKyAgICAgICAgZWdsX2Nvbm5lY3Rpb25fdCogY29uc3QgY254ID0gJmdFR0xJbXBsW2ldOworICAgICAgICBpZiAoY254LT5kc28pIHsKKyAgICAgICAgICAgIGNueC0+aG9va3MtPmVnbC5lZ2xHZXRDb25maWdBdHRyaWIoCisgICAgICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBkcC0+Y29uZmlnc1tpXVtpbmRleF0sIAorICAgICAgICAgICAgICAgICAgICBFR0xfQ09ORklHX0lELCAmY29uZmlnSWQpOworCisgICAgICAgICAgICAvLyBhbmQgc3dpdGNoIHRvIHRoZSBuZXcgbGlzdAorICAgICAgICAgICAgYXR0cmliX2xpc3QgPSBjb25zdF9jYXN0PGNvbnN0IEVHTGludCAqPihuZXdfbGlzdCk7CisKKyAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSBvbmx5IGNvbmZpZ3VyYXRpb24gdGhhdCBjYW4gbWF0Y2ggaXMKKyAgICAgICAgICAgIC8vIGRwLT5jb25maWdzW2ldW2luZGV4XSwgaG93ZXZlciwgd2UgZG9uJ3Qga25vdyBpZiBpdCB3b3VsZCBiZQorICAgICAgICAgICAgLy8gcmVqZWN0ZWQgYmVjYXVzZSBvZiB0aGUgb3RoZXIgYXR0cmlidXRlcywgc28gd2UgZG8gaGF2ZSB0byBjYWxsCisgICAgICAgICAgICAvLyBjbngtPmhvb2tzLT5lZ2wuZWdsQ2hvb3NlQ29uZmlnKCkgLS0gYnV0IHdlIGRvbid0IGhhdmUgdG8gbG9vcAorICAgICAgICAgICAgLy8gdGhyb3VnaCBhbGwgdGhlIEVHTGltcGxbXS4KKyAgICAgICAgICAgIC8vIFdlIGFsc28ga25vdyB3ZSBjYW4gb25seSBnZXQgYSBzaW5nbGUgY29uZmlnIGJhY2ssIGFuZCB3ZSBrbm93CisgICAgICAgICAgICAvLyB3aGljaCBvbmUuCisKKyAgICAgICAgICAgIHJlcyA9IGNueC0+aG9va3MtPmVnbC5lZ2xDaG9vc2VDb25maWcoCisgICAgICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBhdHRyaWJfbGlzdCwgY29uZmlncywgY29uZmlnX3NpemUsICZuKTsKKyAgICAgICAgICAgIGlmIChyZXMgJiYgbj4wKSB7CisgICAgICAgICAgICAgICAgLy8gbiBoYXMgdG8gYmUgMCBvciAxLCBieSBjb25zdHJ1Y3Rpb24sIGFuZCB3ZSBhbHJlYWR5IGtub3cKKyAgICAgICAgICAgICAgICAvLyB3aGljaCBjb25maWcgaXQgd2lsbCByZXR1cm4gKHNpbmNlIHRoZXJlIGNhbiBiZSBvbmx5IG9uZSkuCisgICAgICAgICAgICAgICAgY29uZmlnc1swXSA9IE1BS0VfQ09ORklHKGksIGluZGV4KTsKKyAgICAgICAgICAgICAgICAqbnVtX2NvbmZpZyA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmcmVlKGNvbnN0X2Nhc3Q8RUdMaW50ICo+KGF0dHJpYl9saXN0KSk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgZm9yIChpbnQgaT0wIDsgaTwyIDsgaSsrKSB7CisgICAgICAgIGVnbF9jb25uZWN0aW9uX3QqIGNvbnN0IGNueCA9ICZnRUdMSW1wbFtpXTsKKyAgICAgICAgaWYgKGNueC0+ZHNvKSB7CisgICAgICAgICAgICBpZiAoY254LT5ob29rcy0+ZWdsLmVnbENob29zZUNvbmZpZygKKyAgICAgICAgICAgICAgICAgICAgZHAtPmRweXNbaV0sIGF0dHJpYl9saXN0LCBjb25maWdzLCBjb25maWdfc2l6ZSwgJm4pKSB7CisgICAgICAgICAgICAgICAgLy8gbm93IHdlIG5lZWQgdG8gY29udmVydCB0aGVzZSBjbGllbnQgRUdMQ29uZmlnIHRvIG91cgorICAgICAgICAgICAgICAgIC8vIGludGVybmFsIEVHTENvbmZpZyBmb3JtYXQuIFRoaXMgaXMgZG9uZSBpbiBPKG4gbG9nIG4pLgorICAgICAgICAgICAgICAgIGZvciAoaW50IGo9MCA7IGo8biA7IGorKykgeworICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBiaW5hcnlTZWFyY2g8RUdMQ29uZmlnPigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcC0+Y29uZmlnc1tpXSwgMCwgZHAtPm51bUNvbmZpZ3NbaV0tMSwgY29uZmlnc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdzW2pdID0gTUFLRV9DT05GSUcoaSwgaW5kZXgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09ORklHLCBFR0xfRkFMU0UpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbmZpZ3MgKz0gbjsKKyAgICAgICAgICAgICAgICBjb25maWdfc2l6ZSAtPSBuOworICAgICAgICAgICAgICAgICpudW1fY29uZmlnICs9IG47CisgICAgICAgICAgICAgICAgcmVzID0gRUdMX1RSVUU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworRUdMQm9vbGVhbiBlZ2xHZXRDb25maWdBdHRyaWIoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpCit7CisgICAgZWdsX2Rpc3BsYXlfdCBjb25zdCogZHAgPSAwOworICAgIGludCBpPTAsIGluZGV4PTA7CisgICAgZWdsX2Nvbm5lY3Rpb25fdCogY254ID0gdmFsaWRhdGVfZGlzcGxheV9jb25maWcoZHB5LCBjb25maWcsIGRwLCBpLCBpbmRleCk7CisgICAgaWYgKCFjbngpIHJldHVybiBFR0xfRkFMU0U7CisgICAgCisgICAgaWYgKGF0dHJpYnV0ZSA9PSBFR0xfQ09ORklHX0lEKSB7CisgICAgICAgIC8vIEVHTF9DT05GSUdfSURzIG11c3QgYmUgdW5pcXVlLCBqdXN0IHVzZSB0aGUgb3JkZXIgb2YgdGhlIHNlbGVjdGVkCisgICAgICAgIC8vIEVHTENvbmZpZy4KKyAgICAgICAgKnZhbHVlID0gY29uZmlnVG9VbmlxdWVJZChkcCwgaSwgaW5kZXgpOworICAgICAgICByZXR1cm4gRUdMX1RSVUU7CisgICAgfQorICAgIHJldHVybiBjbngtPmhvb2tzLT5lZ2wuZWdsR2V0Q29uZmlnQXR0cmliKAorICAgICAgICAgICAgZHAtPmRweXNbaV0sIGRwLT5jb25maWdzW2ldW2luZGV4XSwgYXR0cmlidXRlLCB2YWx1ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHN1cmZhY2VzCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0VHTFN1cmZhY2UgZWdsQ3JlYXRlV2luZG93U3VyZmFjZSggIEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlV2luZG93VHlwZSB3aW5kb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGVnbF9kaXNwbGF5X3QgY29uc3QqIGRwID0gMDsKKyAgICBpbnQgaT0wLCBpbmRleD0wOworICAgIGVnbF9jb25uZWN0aW9uX3QqIGNueCA9IHZhbGlkYXRlX2Rpc3BsYXlfY29uZmlnKGRweSwgY29uZmlnLCBkcCwgaSwgaW5kZXgpOworICAgIGlmIChjbngpIHsKKyAgICAgICAgLy8gd2luZG93IG11c3QgYmUgY29ubmVjdGVkIHVwb24gY2FsbGluZyB1bmRlcmx5aW5nCisgICAgICAgIC8vIGVnbENyZWF0ZVdpbmRvd1N1cmZhY2UKKyAgICAgICAgaWYgKHdpbmRvdykgeworICAgICAgICAgICAgd2luZG93LT5pbmNSZWYod2luZG93KTsKKyAgICAgICAgICAgIGlmICh3aW5kb3ctPmNvbm5lY3QpCisgICAgICAgICAgICAgICAgd2luZG93LT5jb25uZWN0KHdpbmRvdyk7CisgICAgICAgIH0KKworICAgICAgICBFR0xTdXJmYWNlIHN1cmZhY2UgPSBjbngtPmhvb2tzLT5lZ2wuZWdsQ3JlYXRlV2luZG93U3VyZmFjZSgKKyAgICAgICAgICAgICAgICBkcC0+ZHB5c1tpXSwgZHAtPmNvbmZpZ3NbaV1baW5kZXhdLCB3aW5kb3csIGF0dHJpYl9saXN0KTsgICAgICAgCisgICAgICAgIGlmIChzdXJmYWNlICE9IEVHTF9OT19TVVJGQUNFKSB7CisgICAgICAgICAgICBlZ2xfc3VyZmFjZV90KiBzID0gbmV3IGVnbF9zdXJmYWNlX3QoZHB5LCBzdXJmYWNlLCB3aW5kb3csIGksIGNueCk7CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmcsIGRpc2Nvbm5lY3QgYW5kIGZyZWUgd2luZG93CisgICAgICAgIC8vICh3aWxsIGRpc2Nvbm5lY3QoKSBhdXRvbWF0aWNhbGx5KQorICAgICAgICBpZiAod2luZG93KSB7CisgICAgICAgICAgICB3aW5kb3ctPmRlY1JlZih3aW5kb3cpOworICAgICAgICB9ICAgICAgICAKKyAgICB9CisgICAgcmV0dXJuIEVHTF9OT19TVVJGQUNFOworfQorCitFR0xTdXJmYWNlIGVnbENyZWF0ZVBpeG1hcFN1cmZhY2UoICBFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hdGl2ZVBpeG1hcFR5cGUgcGl4bWFwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCkKK3sKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0KiBkcCA9IDA7CisgICAgaW50IGk9MCwgaW5kZXg9MDsKKyAgICBlZ2xfY29ubmVjdGlvbl90KiBjbnggPSB2YWxpZGF0ZV9kaXNwbGF5X2NvbmZpZyhkcHksIGNvbmZpZywgZHAsIGksIGluZGV4KTsKKyAgICBpZiAoY254KSB7CisgICAgICAgIEVHTFN1cmZhY2Ugc3VyZmFjZSA9IGNueC0+aG9va3MtPmVnbC5lZ2xDcmVhdGVQaXhtYXBTdXJmYWNlKAorICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBkcC0+Y29uZmlnc1tpXVtpbmRleF0sIHBpeG1hcCwgYXR0cmliX2xpc3QpOworICAgICAgICBpZiAoc3VyZmFjZSAhPSBFR0xfTk9fU1VSRkFDRSkgeworICAgICAgICAgICAgZWdsX3N1cmZhY2VfdCogcyA9IG5ldyBlZ2xfc3VyZmFjZV90KGRweSwgc3VyZmFjZSwgTlVMTCwgaSwgY254KTsKKyAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBFR0xfTk9fU1VSRkFDRTsKK30KKworRUdMU3VyZmFjZSBlZ2xDcmVhdGVQYnVmZmVyU3VyZmFjZSggRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGVnbF9kaXNwbGF5X3QgY29uc3QqIGRwID0gMDsKKyAgICBpbnQgaT0wLCBpbmRleD0wOworICAgIGVnbF9jb25uZWN0aW9uX3QqIGNueCA9IHZhbGlkYXRlX2Rpc3BsYXlfY29uZmlnKGRweSwgY29uZmlnLCBkcCwgaSwgaW5kZXgpOworICAgIGlmIChjbngpIHsKKyAgICAgICAgRUdMU3VyZmFjZSBzdXJmYWNlID0gY254LT5ob29rcy0+ZWdsLmVnbENyZWF0ZVBidWZmZXJTdXJmYWNlKAorICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBkcC0+Y29uZmlnc1tpXVtpbmRleF0sIGF0dHJpYl9saXN0KTsKKyAgICAgICAgaWYgKHN1cmZhY2UgIT0gRUdMX05PX1NVUkZBQ0UpIHsKKyAgICAgICAgICAgIGVnbF9zdXJmYWNlX3QqIHMgPSBuZXcgZWdsX3N1cmZhY2VfdChkcHksIHN1cmZhY2UsIE5VTEwsIGksIGNueCk7CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gRUdMX05PX1NVUkZBQ0U7Cit9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKK0VHTEJvb2xlYW4gZWdsRGVzdHJveVN1cmZhY2UoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSkKK3sKKyAgICBpZiAoIXZhbGlkYXRlX2Rpc3BsYXlfc3VyZmFjZShkcHksIHN1cmZhY2UpKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOyAgICAKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGVnbF9zdXJmYWNlX3QgY29uc3QgKiBjb25zdCBzID0gZ2V0X3N1cmZhY2Uoc3VyZmFjZSk7CisKKyAgICBFR0xCb29sZWFuIHJlc3VsdCA9IHMtPmNueC0+aG9va3MtPmVnbC5lZ2xEZXN0cm95U3VyZmFjZSgKKyAgICAgICAgICAgIGRwLT5kcHlzW3MtPmltcGxdLCBzLT5zdXJmYWNlKTsKKyAgICAKKyAgICBkZWxldGUgczsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitFR0xCb29sZWFuIGVnbFF1ZXJ5U3VyZmFjZSggRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgKnZhbHVlKQoreworICAgIGlmICghdmFsaWRhdGVfZGlzcGxheV9zdXJmYWNlKGRweSwgc3VyZmFjZSkpCisgICAgICAgIHJldHVybiBFR0xfRkFMU0U7ICAgIAorICAgIGVnbF9kaXNwbGF5X3QgY29uc3QgKiBjb25zdCBkcCA9IGdldF9kaXNwbGF5KGRweSk7CisgICAgZWdsX3N1cmZhY2VfdCBjb25zdCAqIGNvbnN0IHMgPSBnZXRfc3VyZmFjZShzdXJmYWNlKTsKKworICAgIHJldHVybiBzLT5jbngtPmhvb2tzLT5lZ2wuZWdsUXVlcnlTdXJmYWNlKAorICAgICAgICAgICAgZHAtPmRweXNbcy0+aW1wbF0sIHMtPnN1cmZhY2UsIGF0dHJpYnV0ZSwgdmFsdWUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBjb250ZXh0ZXMKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRUdMQ29udGV4dCBlZ2xDcmVhdGVDb250ZXh0KEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVHTENvbnRleHQgc2hhcmVfbGlzdCwgY29uc3QgRUdMaW50ICphdHRyaWJfbGlzdCkKK3sKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0KiBkcCA9IDA7CisgICAgaW50IGk9MCwgaW5kZXg9MDsKKyAgICBlZ2xfY29ubmVjdGlvbl90KiBjbnggPSB2YWxpZGF0ZV9kaXNwbGF5X2NvbmZpZyhkcHksIGNvbmZpZywgZHAsIGksIGluZGV4KTsKKyAgICBpZiAoY254KSB7CisgICAgICAgIEVHTENvbnRleHQgY29udGV4dCA9IGNueC0+aG9va3MtPmVnbC5lZ2xDcmVhdGVDb250ZXh0KAorICAgICAgICAgICAgICAgIGRwLT5kcHlzW2ldLCBkcC0+Y29uZmlnc1tpXVtpbmRleF0sIHNoYXJlX2xpc3QsIGF0dHJpYl9saXN0KTsKKyAgICAgICAgaWYgKGNvbnRleHQgIT0gRUdMX05PX0NPTlRFWFQpIHsKKyAgICAgICAgICAgIGVnbF9jb250ZXh0X3QqIGMgPSBuZXcgZWdsX2NvbnRleHRfdChkcHksIGNvbnRleHQsIGksIGNueCk7CisgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gRUdMX05PX0NPTlRFWFQ7Cit9CisKK0VHTEJvb2xlYW4gZWdsRGVzdHJveUNvbnRleHQoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4KQoreworICAgIGlmICghdmFsaWRhdGVfZGlzcGxheV9jb250ZXh0KGRweSwgY3R4KSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGVnbF9jb250ZXh0X3QgKiBjb25zdCBjID0gZ2V0X2NvbnRleHQoY3R4KTsKKyAgICBFR0xCb29sZWFuIHJlc3VsdCA9IGMtPmNueC0+aG9va3MtPmVnbC5lZ2xEZXN0cm95Q29udGV4dCgKKyAgICAgICAgICAgIGRwLT5kcHlzW2MtPmltcGxdLCBjLT5jb250ZXh0KTsKKyAgICBkZWxldGUgYzsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitFR0xCb29sZWFuIGVnbE1ha2VDdXJyZW50KCAgRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2UgZHJhdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xTdXJmYWNlIHJlYWQsIEVHTENvbnRleHQgY3R4KQoreworICAgIGVnbF9kaXNwbGF5X3QgY29uc3QgKiBjb25zdCBkcCA9IGdldF9kaXNwbGF5KGRweSk7CisgICAgaWYgKCFkcCkgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfRElTUExBWSwgRUdMX0ZBTFNFKTsKKworICAgIGlmIChyZWFkID09IEVHTF9OT19TVVJGQUNFICYmIGRyYXcgID09IEVHTF9OT19TVVJGQUNFICYmCisgICAgICAgICAgICBjdHggPT0gRUdMX05PX0NPTlRFWFQpIAorICAgIHsKKyAgICAgICAgRUdMQm9vbGVhbiByZXN1bHQgPSBFR0xfVFJVRTsKKyAgICAgICAgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgICAgICBpZiAoY3R4KSB7CisgICAgICAgICAgICBlZ2xfY29udGV4dF90ICogY29uc3QgYyA9IGdldF9jb250ZXh0KGN0eCk7CisgICAgICAgICAgICByZXN1bHQgPSBjLT5jbngtPmhvb2tzLT5lZ2wuZWdsTWFrZUN1cnJlbnQoZHAtPmRweXNbYy0+aW1wbF0sIDAsIDAsIDApOworICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBFR0xfVFJVRSkgeworICAgICAgICAgICAgICAgIHNldEdsVGhyZWFkU3BlY2lmaWMoJmdIb29rc1tJTVBMX05PX0NPTlRFWFRdKTsKKyAgICAgICAgICAgICAgICBzZXRDb250ZXh0KEVHTF9OT19DT05URVhUKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIGlmICghdmFsaWRhdGVfZGlzcGxheV9jb250ZXh0KGRweSwgY3R4KSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsgICAgCisgICAgCisgICAgZWdsX2NvbnRleHRfdCAqIGNvbnN0IGMgPSBnZXRfY29udGV4dChjdHgpOworICAgIGlmIChkcmF3ICE9IEVHTF9OT19TVVJGQUNFKSB7CisgICAgICAgIGVnbF9zdXJmYWNlX3QgY29uc3QgKiBkID0gZ2V0X3N1cmZhY2UoZHJhdyk7CisgICAgICAgIGlmICghZCkgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfU1VSRkFDRSwgRUdMX0ZBTFNFKTsKKyAgICAgICAgaWYgKGQtPmltcGwgIT0gYy0+aW1wbCkKKyAgICAgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX01BVENILCBFR0xfRkFMU0UpOworICAgICAgICBkcmF3ID0gZC0+c3VyZmFjZTsKKyAgICB9CisgICAgaWYgKHJlYWQgIT0gRUdMX05PX1NVUkZBQ0UpIHsKKyAgICAgICAgZWdsX3N1cmZhY2VfdCBjb25zdCAqIHIgPSBnZXRfc3VyZmFjZShyZWFkKTsKKyAgICAgICAgaWYgKCFyKSByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9TVVJGQUNFLCBFR0xfRkFMU0UpOworICAgICAgICBpZiAoci0+aW1wbCAhPSBjLT5pbXBsKQorICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfTUFUQ0gsIEVHTF9GQUxTRSk7CisgICAgICAgIHJlYWQgPSByLT5zdXJmYWNlOworICAgIH0KKyAgICBFR0xCb29sZWFuIHJlc3VsdCA9IGMtPmNueC0+aG9va3MtPmVnbC5lZ2xNYWtlQ3VycmVudCgKKyAgICAgICAgICAgIGRwLT5kcHlzW2MtPmltcGxdLCBkcmF3LCByZWFkLCBjLT5jb250ZXh0KTsKKworICAgIGlmIChyZXN1bHQgPT0gRUdMX1RSVUUpIHsKKyAgICAgICAgc2V0R2xUaHJlYWRTcGVjaWZpYyhjLT5jbngtPmhvb2tzKTsKKyAgICAgICAgc2V0Q29udGV4dChjdHgpOworICAgICAgICBjLT5yZWFkID0gcmVhZDsKKyAgICAgICAgYy0+ZHJhdyA9IGRyYXc7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworRUdMQm9vbGVhbiBlZ2xRdWVyeUNvbnRleHQoIEVHTERpc3BsYXkgZHB5LCBFR0xDb250ZXh0IGN0eCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgKnZhbHVlKQoreworICAgIGlmICghdmFsaWRhdGVfZGlzcGxheV9jb250ZXh0KGRweSwgY3R4KSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsgICAgCisgICAgCisgICAgZWdsX2Rpc3BsYXlfdCBjb25zdCAqIGNvbnN0IGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBlZ2xfY29udGV4dF90ICogY29uc3QgYyA9IGdldF9jb250ZXh0KGN0eCk7CisKKyAgICByZXR1cm4gYy0+Y254LT5ob29rcy0+ZWdsLmVnbFF1ZXJ5Q29udGV4dCgKKyAgICAgICAgICAgIGRwLT5kcHlzW2MtPmltcGxdLCBjLT5jb250ZXh0LCBhdHRyaWJ1dGUsIHZhbHVlKTsKK30KKworRUdMQ29udGV4dCBlZ2xHZXRDdXJyZW50Q29udGV4dCh2b2lkKQoreworICAgIEVHTENvbnRleHQgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgIHJldHVybiBjdHg7Cit9CisKK0VHTFN1cmZhY2UgZWdsR2V0Q3VycmVudFN1cmZhY2UoRUdMaW50IHJlYWRkcmF3KQoreworICAgIEVHTENvbnRleHQgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgIGlmIChjdHgpIHsKKyAgICAgICAgZWdsX2NvbnRleHRfdCBjb25zdCAqIGNvbnN0IGMgPSBnZXRfY29udGV4dChjdHgpOworICAgICAgICBpZiAoIWMpIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTlRFWFQsIEVHTF9OT19TVVJGQUNFKTsKKyAgICAgICAgc3dpdGNoIChyZWFkZHJhdykgeworICAgICAgICAgICAgY2FzZSBFR0xfUkVBRDogcmV0dXJuIGMtPnJlYWQ7CisgICAgICAgICAgICBjYXNlIEVHTF9EUkFXOiByZXR1cm4gYy0+ZHJhdzsgICAgICAgICAgICAKKyAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1BBUkFNRVRFUiwgRUdMX05PX1NVUkZBQ0UpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBFR0xfTk9fU1VSRkFDRTsKK30KKworRUdMRGlzcGxheSBlZ2xHZXRDdXJyZW50RGlzcGxheSh2b2lkKQoreworICAgIEVHTENvbnRleHQgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgIGlmIChjdHgpIHsKKyAgICAgICAgZWdsX2NvbnRleHRfdCBjb25zdCAqIGNvbnN0IGMgPSBnZXRfY29udGV4dChjdHgpOworICAgICAgICBpZiAoIWMpIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTlRFWFQsIEVHTF9OT19TVVJGQUNFKTsKKyAgICAgICAgcmV0dXJuIGMtPmRweTsKKyAgICB9CisgICAgcmV0dXJuIEVHTF9OT19ESVNQTEFZOworfQorCitFR0xCb29sZWFuIGVnbFdhaXRHTCh2b2lkKQoreworICAgIEVHTEJvb2xlYW4gcmVzID0gRUdMX1RSVUU7CisgICAgRUdMQ29udGV4dCBjdHggPSBnZXRDb250ZXh0KCk7CisgICAgaWYgKGN0eCkgeworICAgICAgICBlZ2xfY29udGV4dF90IGNvbnN0ICogY29uc3QgYyA9IGdldF9jb250ZXh0KGN0eCk7CisgICAgICAgIGlmICghYykgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09OVEVYVCwgRUdMX0ZBTFNFKTsKKyAgICAgICAgaWYgKHVpbnQzMl90KGMtPmltcGwpPj0yKQorICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09OVEVYVCwgRUdMX0ZBTFNFKTsKKyAgICAgICAgZWdsX2Nvbm5lY3Rpb25fdCogY29uc3QgY254ID0gJmdFR0xJbXBsW2MtPmltcGxdOworICAgICAgICBpZiAoIWNueC0+ZHNvKSAKKyAgICAgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTlRFWFQsIEVHTF9GQUxTRSk7CisgICAgICAgIHJlcyA9IGNueC0+aG9va3MtPmVnbC5lZ2xXYWl0R0woKTsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworRUdMQm9vbGVhbiBlZ2xXYWl0TmF0aXZlKEVHTGludCBlbmdpbmUpCit7CisgICAgRUdMQm9vbGVhbiByZXMgPSBFR0xfVFJVRTsKKyAgICBFR0xDb250ZXh0IGN0eCA9IGdldENvbnRleHQoKTsKKyAgICBpZiAoY3R4KSB7CisgICAgICAgIGVnbF9jb250ZXh0X3QgY29uc3QgKiBjb25zdCBjID0gZ2V0X2NvbnRleHQoY3R4KTsKKyAgICAgICAgaWYgKCFjKSByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9DT05URVhULCBFR0xfRkFMU0UpOworICAgICAgICBpZiAodWludDMyX3QoYy0+aW1wbCk+PTIpCisgICAgICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9DT05URVhULCBFR0xfRkFMU0UpOworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbYy0+aW1wbF07CisgICAgICAgIGlmICghY254LT5kc28pIAorICAgICAgICAgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09OVEVYVCwgRUdMX0ZBTFNFKTsKKyAgICAgICAgcmVzID0gY254LT5ob29rcy0+ZWdsLmVnbFdhaXROYXRpdmUoZW5naW5lKTsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworRUdMaW50IGVnbEdldEVycm9yKHZvaWQpCit7CisgICAgRUdMaW50IHJlc3VsdCA9IEVHTF9TVUNDRVNTOworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBFR0xpbnQgZXJyID0gRUdMX1NVQ0NFU1M7CisgICAgICAgIGVnbF9jb25uZWN0aW9uX3QqIGNvbnN0IGNueCA9ICZnRUdMSW1wbFtpXTsKKyAgICAgICAgaWYgKGNueC0+ZHNvKQorICAgICAgICAgICAgZXJyID0gY254LT5ob29rcy0+ZWdsLmVnbEdldEVycm9yKCk7CisgICAgICAgIGlmIChlcnIhPUVHTF9TVUNDRVNTICYmIHJlc3VsdD09RUdMX1NVQ0NFU1MpCisgICAgICAgICAgICByZXN1bHQgPSBlcnI7CisgICAgfQorICAgIGlmIChyZXN1bHQgPT0gRUdMX1NVQ0NFU1MpCisgICAgICAgIHJlc3VsdCA9IGdldEVycm9yKCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCAoKmVnbEdldFByb2NBZGRyZXNzKGNvbnN0IGNoYXIgKnByb2NuYW1lKSkoKQoreworICAgIF9fZWdsTXVzdENhc3RUb1Byb3BlckZ1bmN0aW9uUG9pbnRlclR5cGUgYWRkcjsKKyAgICBhZGRyID0gZmluZFByb2NBZGRyZXNzKHByb2NuYW1lLCBnRXh0ZW50aW9uTWFwLCBORUxFTShnRXh0ZW50aW9uTWFwKSk7CisgICAgaWYgKGFkZHIpIHJldHVybiBhZGRyOworCisgICAgcmV0dXJuIE5VTEw7IC8vIFRPRE86IGZpbmlzaCBpbXBsZW1lbnRhdGlvbiBiZWxvdworCisgICAgYWRkciA9IGZpbmRQcm9jQWRkcmVzcyhwcm9jbmFtZSwgZ0dMRXh0ZW50aW9uTWFwLCBORUxFTShnR0xFeHRlbnRpb25NYXApKTsKKyAgICBpZiAoYWRkcikgcmV0dXJuIGFkZHI7CisgICAgCisgICAgYWRkciA9IDA7CisgICAgaW50IHNsb3QgPSAtMTsKKyAgICBmb3IgKGludCBpPTAgOyBpPDIgOyBpKyspIHsKKyAgICAgICAgZWdsX2Nvbm5lY3Rpb25fdCogY29uc3QgY254ID0gJmdFR0xJbXBsW2ldOworICAgICAgICBpZiAoY254LT5kc28pIHsKKyAgICAgICAgICAgIGlmIChjbngtPmhvb2tzLT5lZ2wuZWdsR2V0UHJvY0FkZHJlc3MpIHsKKyAgICAgICAgICAgICAgICBhZGRyID0gY254LT5ob29rcy0+ZWdsLmVnbEdldFByb2NBZGRyZXNzKHByb2NuYW1lKTsKKyAgICAgICAgICAgICAgICBpZiAoYWRkcikgeworICAgICAgICAgICAgICAgICAgICBpZiAoc2xvdCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCA9IDA7IC8vIFhYWDogZmluZCBmcmVlIHNsb3QKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbG90ID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkciA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY254LT5ob29rcy0+ZXh0LmV4dGVuc2lvbnNbc2xvdF0gPSBhZGRyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICBpZiAoc2xvdCA+PSAwKSB7CisgICAgICAgIGFkZHIgPSAwOyAvLyBYWFg6IGFkZHJlc3Mgb2Ygc3R1YiAnc2xvdCcKKyAgICAgICAgZ0dMRXh0ZW50aW9uTWFwW3Nsb3RdLm5hbWUgPSBzdHJkdXAocHJvY25hbWUpOworICAgICAgICBnR0xFeHRlbnRpb25NYXBbc2xvdF0uYWRkcmVzcyA9IGFkZHI7CisgICAgfQorICAgIAorICAgIHJldHVybiBhZGRyOworCisgICAgCisgICAgLyoKKyAgICAgKiAgVE9ETzogRm9yIE9wZW5HTCBFUyBleHRlbnNpb25zLCB3ZSBtdXN0IGdlbmVyYXRlIGEgc3R1YgorICAgICAqICB0aGF0IGxvb2tzIGxpa2UKKyAgICAgKiAgICAgIG1vdiAgICAgcjEyLCAjMHhGRkZGMEZGRgorICAgICAqICAgICAgbGRyICAgICByMTIsIFtyMTIsICMtMTVdCisgICAgICogICAgICBsZHIgICAgIHIxMiwgW3IxMiwgI1RMU19TTE9UX09QRU5HTF9BUEkqNF0KKyAgICAgKiAgICAgIG1vdiAgICAgcjEyLCBbcjEyLCAjYXBpX29mZnNldF0KKyAgICAgKiAgICAgIGxkcm5lICAgcGMsIHIxMgorICAgICAqICAgICAgbW92ICAgICBwYywgI3Vuc3VwcG9ydGVkX2V4dGVuc2lvbgorICAgICAqIAorICAgICAqICBhbmQgd3JpdGUgdGhlIGFkZHJlc3Mgb2YgdGhlIGV4dGVuc2lvbiBpbiAqYWxsKgorICAgICAqICBnbF9ob29rc190OjpnbF9leHRfdCBhdCBvZmZzZXQgImFwaV9vZmZzZXQiIGZyb20gZ2xfaG9va3NfdAorICAgICAqIAorICAgICAqLworfQorCitFR0xCb29sZWFuIGVnbFN3YXBCdWZmZXJzKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGRyYXcpCit7CisgICAgaWYgKCF2YWxpZGF0ZV9kaXNwbGF5X3N1cmZhY2UoZHB5LCBkcmF3KSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsgICAgCisgICAgZWdsX2Rpc3BsYXlfdCBjb25zdCAqIGNvbnN0IGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBlZ2xfc3VyZmFjZV90IGNvbnN0ICogY29uc3QgcyA9IGdldF9zdXJmYWNlKGRyYXcpOworICAgIHJldHVybiBzLT5jbngtPmhvb2tzLT5lZ2wuZWdsU3dhcEJ1ZmZlcnMoZHAtPmRweXNbcy0+aW1wbF0sIHMtPnN1cmZhY2UpOworfQorCitFR0xCb29sZWFuIGVnbENvcHlCdWZmZXJzKCAgRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVQaXhtYXBUeXBlIHRhcmdldCkKK3sKKyAgICBpZiAoIXZhbGlkYXRlX2Rpc3BsYXlfc3VyZmFjZShkcHksIHN1cmZhY2UpKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOyAgICAKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGVnbF9zdXJmYWNlX3QgY29uc3QgKiBjb25zdCBzID0gZ2V0X3N1cmZhY2Uoc3VyZmFjZSk7CisgICAgcmV0dXJuIHMtPmNueC0+aG9va3MtPmVnbC5lZ2xDb3B5QnVmZmVycygKKyAgICAgICAgICAgIGRwLT5kcHlzW3MtPmltcGxdLCBzLT5zdXJmYWNlLCB0YXJnZXQpOworfQorCitjb25zdCBjaGFyKiBlZ2xRdWVyeVN0cmluZyhFR0xEaXNwbGF5IGRweSwgRUdMaW50IG5hbWUpCit7CisgICAgZWdsX2Rpc3BsYXlfdCBjb25zdCAqIGNvbnN0IGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBzd2l0Y2ggKG5hbWUpIHsKKyAgICAgICAgY2FzZSBFR0xfVkVORE9SOgorICAgICAgICAgICAgcmV0dXJuIGdWZW5kb3JTdHJpbmc7CisgICAgICAgIGNhc2UgRUdMX1ZFUlNJT046CisgICAgICAgICAgICByZXR1cm4gZ1ZlcnNpb25TdHJpbmc7CisgICAgICAgIGNhc2UgRUdMX0VYVEVOU0lPTlM6CisgICAgICAgICAgICByZXR1cm4gZ0V4dGVuc2lvblN0cmluZzsKKyAgICAgICAgY2FzZSBFR0xfQ0xJRU5UX0FQSVM6CisgICAgICAgICAgICByZXR1cm4gZ0NsaWVudEFwaVN0cmluZzsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfUEFSQU1FVEVSLCAoY29uc3QgY2hhciAqKTApOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEVHTCAxLjEKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworRUdMQm9vbGVhbiBlZ2xTdXJmYWNlQXR0cmliKAorICAgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgdmFsdWUpCit7CisgICAgaWYgKCF2YWxpZGF0ZV9kaXNwbGF5X3N1cmZhY2UoZHB5LCBzdXJmYWNlKSkKKyAgICAgICAgcmV0dXJuIEVHTF9GQUxTRTsgICAgCisgICAgZWdsX2Rpc3BsYXlfdCBjb25zdCAqIGNvbnN0IGRwID0gZ2V0X2Rpc3BsYXkoZHB5KTsKKyAgICBlZ2xfc3VyZmFjZV90IGNvbnN0ICogY29uc3QgcyA9IGdldF9zdXJmYWNlKHN1cmZhY2UpOworICAgIGlmIChzLT5jbngtPmhvb2tzLT5lZ2wuZWdsU3VyZmFjZUF0dHJpYikgeworICAgICAgICByZXR1cm4gcy0+Y254LT5ob29rcy0+ZWdsLmVnbFN1cmZhY2VBdHRyaWIoCisgICAgICAgICAgICAgICAgZHAtPmRweXNbcy0+aW1wbF0sIHMtPnN1cmZhY2UsIGF0dHJpYnV0ZSwgdmFsdWUpOworICAgIH0KKyAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9TVVJGQUNFLCBFR0xfRkFMU0UpOworfQorCitFR0xCb29sZWFuIGVnbEJpbmRUZXhJbWFnZSgKKyAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwgRUdMaW50IGJ1ZmZlcikKK3sKKyAgICBpZiAoIXZhbGlkYXRlX2Rpc3BsYXlfc3VyZmFjZShkcHksIHN1cmZhY2UpKQorICAgICAgICByZXR1cm4gRUdMX0ZBTFNFOyAgICAKKyAgICBlZ2xfZGlzcGxheV90IGNvbnN0ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGVnbF9zdXJmYWNlX3QgY29uc3QgKiBjb25zdCBzID0gZ2V0X3N1cmZhY2Uoc3VyZmFjZSk7CisgICAgaWYgKHMtPmNueC0+aG9va3MtPmVnbC5lZ2xCaW5kVGV4SW1hZ2UpIHsKKyAgICAgICAgcmV0dXJuIHMtPmNueC0+aG9va3MtPmVnbC5lZ2xCaW5kVGV4SW1hZ2UoCisgICAgICAgICAgICAgICAgZHAtPmRweXNbcy0+aW1wbF0sIHMtPnN1cmZhY2UsIGJ1ZmZlcik7CisgICAgfQorICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX1NVUkZBQ0UsIEVHTF9GQUxTRSk7Cit9CisKK0VHTEJvb2xlYW4gZWdsUmVsZWFzZVRleEltYWdlKAorICAgICAgICBFR0xEaXNwbGF5IGRweSwgRUdMU3VyZmFjZSBzdXJmYWNlLCBFR0xpbnQgYnVmZmVyKQoreworICAgIGlmICghdmFsaWRhdGVfZGlzcGxheV9zdXJmYWNlKGRweSwgc3VyZmFjZSkpCisgICAgICAgIHJldHVybiBFR0xfRkFMU0U7ICAgIAorICAgIGVnbF9kaXNwbGF5X3QgY29uc3QgKiBjb25zdCBkcCA9IGdldF9kaXNwbGF5KGRweSk7CisgICAgZWdsX3N1cmZhY2VfdCBjb25zdCAqIGNvbnN0IHMgPSBnZXRfc3VyZmFjZShzdXJmYWNlKTsKKyAgICBpZiAocy0+Y254LT5ob29rcy0+ZWdsLmVnbFJlbGVhc2VUZXhJbWFnZSkgeworICAgICAgICByZXR1cm4gcy0+Y254LT5ob29rcy0+ZWdsLmVnbFJlbGVhc2VUZXhJbWFnZSgKKyAgICAgICAgICAgICAgICBkcC0+ZHB5c1tzLT5pbXBsXSwgcy0+c3VyZmFjZSwgYnVmZmVyKTsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfU1VSRkFDRSwgRUdMX0ZBTFNFKTsKK30KKworRUdMQm9vbGVhbiBlZ2xTd2FwSW50ZXJ2YWwoRUdMRGlzcGxheSBkcHksIEVHTGludCBpbnRlcnZhbCkKK3sKKyAgICBlZ2xfZGlzcGxheV90ICogY29uc3QgZHAgPSBnZXRfZGlzcGxheShkcHkpOworICAgIGlmICghZHApIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0RJU1BMQVksIEVHTF9GQUxTRSk7CisKKyAgICBFR0xCb29sZWFuIHJlcyA9IEVHTF9UUlVFOworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbykgeworICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xTd2FwSW50ZXJ2YWwpIHsKKyAgICAgICAgICAgICAgICBpZiAoY254LT5ob29rcy0+ZWdsLmVnbFN3YXBJbnRlcnZhbChkcC0+ZHB5c1tpXSwgaW50ZXJ2YWwpID09IEVHTF9GQUxTRSkgeworICAgICAgICAgICAgICAgICAgICByZXMgPSBFR0xfRkFMU0U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRUdMIDEuMgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFR0xCb29sZWFuIGVnbFdhaXRDbGllbnQodm9pZCkKK3sKKyAgICBFR0xCb29sZWFuIHJlcyA9IEVHTF9UUlVFOworICAgIEVHTENvbnRleHQgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgIGlmIChjdHgpIHsKKyAgICAgICAgZWdsX2NvbnRleHRfdCBjb25zdCAqIGNvbnN0IGMgPSBnZXRfY29udGV4dChjdHgpOworICAgICAgICBpZiAoIWMpIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTlRFWFQsIEVHTF9GQUxTRSk7CisgICAgICAgIGlmICh1aW50MzJfdChjLT5pbXBsKT49MikKKyAgICAgICAgICAgIHJldHVybiBzZXRFcnJvcihFR0xfQkFEX0NPTlRFWFQsIEVHTF9GQUxTRSk7CisgICAgICAgIGVnbF9jb25uZWN0aW9uX3QqIGNvbnN0IGNueCA9ICZnRUdMSW1wbFtjLT5pbXBsXTsKKyAgICAgICAgaWYgKCFjbngtPmRzbykgCisgICAgICAgICAgICByZXR1cm4gc2V0RXJyb3IoRUdMX0JBRF9DT05URVhULCBFR0xfRkFMU0UpOworICAgICAgICBpZiAoY254LT5ob29rcy0+ZWdsLmVnbFdhaXRDbGllbnQpIHsKKyAgICAgICAgICAgIHJlcyA9IGNueC0+aG9va3MtPmVnbC5lZ2xXYWl0Q2xpZW50KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXMgPSBjbngtPmhvb2tzLT5lZ2wuZWdsV2FpdEdMKCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworRUdMQm9vbGVhbiBlZ2xCaW5kQVBJKEVHTGVudW0gYXBpKQoreworICAgIC8vIGJpbmQgdGhpcyBBUEkgb24gYWxsIEVHTHMKKyAgICBFR0xCb29sZWFuIHJlcyA9IEVHTF9UUlVFOworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbykgeworICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xCaW5kQVBJKSB7CisgICAgICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xCaW5kQVBJKGFwaSkgPT0gRUdMX0ZBTFNFKSB7CisgICAgICAgICAgICAgICAgICAgIHJlcyA9IEVHTF9GQUxTRTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworRUdMZW51bSBlZ2xRdWVyeUFQSSh2b2lkKQoreworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbykgeworICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xRdWVyeUFQSSkgeworICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBvbmUgd2UgZmluZCBpcyBva2F5LCBiZWNhdXNlIHRoZXkgYWxsCisgICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIHRoZSBzYW1lCisgICAgICAgICAgICAgICAgcmV0dXJuIGNueC0+aG9va3MtPmVnbC5lZ2xRdWVyeUFQSSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8vIG9yLCBpdCBjYW4gb25seSBiZSBPcGVuR0wgRVMKKyAgICByZXR1cm4gRUdMX09QRU5HTF9FU19BUEk7Cit9CisKK0VHTEJvb2xlYW4gZWdsUmVsZWFzZVRocmVhZCh2b2lkKQoreworICAgIGZvciAoaW50IGk9MCA7IGk8MiA7IGkrKykgeworICAgICAgICBlZ2xfY29ubmVjdGlvbl90KiBjb25zdCBjbnggPSAmZ0VHTEltcGxbaV07CisgICAgICAgIGlmIChjbngtPmRzbykgeworICAgICAgICAgICAgaWYgKGNueC0+aG9va3MtPmVnbC5lZ2xSZWxlYXNlVGhyZWFkKSB7CisgICAgICAgICAgICAgICAgY254LT5ob29rcy0+ZWdsLmVnbFJlbGVhc2VUaHJlYWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBjbGVhclRMUygpOyAgICAKKyAgICByZXR1cm4gRUdMX1RSVUU7Cit9CisKK0VHTFN1cmZhY2UgZWdsQ3JlYXRlUGJ1ZmZlckZyb21DbGllbnRCdWZmZXIoCisgICAgICAgICAgRUdMRGlzcGxheSBkcHksIEVHTGVudW0gYnVmdHlwZSwgRUdMQ2xpZW50QnVmZmVyIGJ1ZmZlciwKKyAgICAgICAgICBFR0xDb25maWcgY29uZmlnLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KQoreworICAgIGVnbF9kaXNwbGF5X3QgY29uc3QqIGRwID0gMDsKKyAgICBpbnQgaT0wLCBpbmRleD0wOworICAgIGVnbF9jb25uZWN0aW9uX3QqIGNueCA9IHZhbGlkYXRlX2Rpc3BsYXlfY29uZmlnKGRweSwgY29uZmlnLCBkcCwgaSwgaW5kZXgpOworICAgIGlmICghY254KSByZXR1cm4gRUdMX0ZBTFNFOworICAgIGlmIChjbngtPmhvb2tzLT5lZ2wuZWdsQ3JlYXRlUGJ1ZmZlckZyb21DbGllbnRCdWZmZXIpIHsKKyAgICAgICAgcmV0dXJuIGNueC0+aG9va3MtPmVnbC5lZ2xDcmVhdGVQYnVmZmVyRnJvbUNsaWVudEJ1ZmZlcigKKyAgICAgICAgICAgICAgICBkcC0+ZHB5c1tpXSwgYnVmdHlwZSwgYnVmZmVyLCBkcC0+Y29uZmlnc1tpXVtpbmRleF0sIGF0dHJpYl9saXN0KTsKKyAgICB9CisgICAgcmV0dXJuIHNldEVycm9yKEVHTF9CQURfQ09ORklHLCBFR0xfTk9fU1VSRkFDRSk7Cit9CmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9FR0wvZ3B1LmNwcCBiL29wZW5nbC9saWJzL0VHTC9ncHUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmOWZkNjMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9FR0wvZ3B1LmNwcApAQCAtMCwwICsxLDIxMiBAQAorLyogCisgKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqKgorICoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqKgorICoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKioKKyAqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiRUdMIgorCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorCisjaW5jbHVkZSA8c3lzL2lvY3RsLmg+CisKKyNpZiBIQVZFX0FORFJPSURfT1MKKyNpbmNsdWRlIDxsaW51eC9hbmRyb2lkX3BtZW0uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Y3V0aWxzL2xvZy5oPgorI2luY2x1ZGUgPGN1dGlscy9wcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDx1dGlscy9JTWVtb3J5Lmg+CisjaW5jbHVkZSA8dXRpbHMvdGhyZWFkcy5oPgorI2luY2x1ZGUgPHV0aWxzL0lTZXJ2aWNlTWFuYWdlci5oPgorI2luY2x1ZGUgPHV0aWxzL0lQQ1RocmVhZFN0YXRlLmg+CisjaW5jbHVkZSA8dXRpbHMvUGFyY2VsLmg+CisKKyNpbmNsdWRlIDx1aS9FR0xEaXNwbGF5U3VyZmFjZS5oPgorI2luY2x1ZGUgPHVpL0lTdXJmYWNlQ29tcG9zZXIuaD4KKworI2luY2x1ZGUgImhvb2tzLmgiCisjaW5jbHVkZSAiZWdsX2ltcGwuaCIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorbmFtZXNwYWNlIGFuZHJvaWQgeworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvKgorICogd2UgcHJvdmlkZSBvdXIgb3duIGFsbG9jYXRvcnMgZm9yIHRoZSBHUFUgcmVnaW9ucywgdGhlc2UKKyAqIGFsbG9jYXRvcnMgZ28gdGhyb3VnaCBzdXJmYWNlZmxpbmdlciAKKyAqLworCitzdGF0aWMgTXV0ZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgZ1JlZ2lvbnNMb2NrOworc3RhdGljIHJlcXVlc3RfZ3B1X3QgICAgICAgICAgICAgICAgICAgIGdSZWdpb25zOworc3RhdGljIHNwPElTdXJmYWNlQ29tcG9zZXI+ICAgICAgICAgICAgIGdTdXJmYWNlTWFuYWdlcjsKK0lTdXJmYWNlQ29tcG9zZXIqICAgICAgICAgICAgICAgICAgICAgICBHTEVTX2xvY2FsU3VyZmFjZU1hbmFnZXIgPSAwOworCitleHRlcm4gZWdsX2Nvbm5lY3Rpb25fdCBnRUdMSW1wbFsyXTsKKworY29uc3Qgc3A8SVN1cmZhY2VDb21wb3Nlcj4mIGdldFN1cmZhY2VGbGluZ2VyKCkKK3sKKyAgICBNdXRleDo6QXV0b2xvY2sgX2woZ1JlZ2lvbnNMb2NrKTsKKworICAgIC8qCisgICAgICogVGhlcmUgaXMgYSBsaXR0bGUgYml0IG9mIHZvb2RvbyBtYWdpYyBoZXJlLiBXZSB3YW50IHRvIGFjY2VzcworICAgICAqIHN1cmZhY2VmbGluZ2VyIGZvciBhbGxvY2F0aW5nIEdQVSByZWdpb25zLCBob3dldmVyLCB3aGVuIHdlIGFyZQorICAgICAqIHJ1bm5pbmcgYXMgcGFydCBvZiBzdXJmYWNlZmxpbmdlciwgd2Ugd2FudCB0byBieXBhc3MgdGhlCisgICAgICogc2VydmljZSBtYW5hZ2VyIGJlY2F1c2Ugc3VyZmFjZWZsaW5nZXIgbWlnaHQgbm90IGJlIHJlZ2lzdGVyZWQgeWV0LgorICAgICAqIFN1cmZhY2VGbGluZ2VyIHdpbGwgcG9wdWxhdGUgIkdMRVNfbG9jYWxTdXJmYWNlTWFuYWdlciIgd2l0aCBpdHMKKyAgICAgKiBvd24gYWRkcmVzcywgc28gd2UgY2FuIGp1c3QgdXNlIHRoYXQuCisgICAgICovCisgICAgaWYgKGdTdXJmYWNlTWFuYWdlciA9PSAwKSB7CisgICAgICAgIGlmIChHTEVTX2xvY2FsU3VyZmFjZU1hbmFnZXIpIHsKKyAgICAgICAgICAgIC8vIHdlJ3JlIHJ1bm5pbmcgaW4gU3VyZmFjZUZsaW5nZXIncyBjb250ZXh0CisgICAgICAgICAgICBnU3VyZmFjZU1hbmFnZXIgPSAgR0xFU19sb2NhbFN1cmZhY2VNYW5hZ2VyOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gd2UncmUgYSByZW1vdGUgcHJvY2VzcyBvciBub3QgcGFydCBvZiBzdXJmYWNlZmxpbmdlciwKKyAgICAgICAgICAgIC8vIGdvIHRocm91Z2ggdGhlIHNlcnZpY2UgbWFuYWdlcgorICAgICAgICAgICAgc3A8SVNlcnZpY2VNYW5hZ2VyPiBzbSA9IGRlZmF1bHRTZXJ2aWNlTWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNtICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBzcDxJQmluZGVyPiBiaW5kZXIgPSBzbS0+Z2V0U2VydmljZShTdHJpbmcxNigiU3VyZmFjZUZsaW5nZXIiKSk7CisgICAgICAgICAgICAgICAgZ1N1cmZhY2VNYW5hZ2VyID0gaW50ZXJmYWNlX2Nhc3Q8SVN1cmZhY2VDb21wb3Nlcj4oYmluZGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZ1N1cmZhY2VNYW5hZ2VyOworfQorCitjbGFzcyBHUFVSZXZva2VSZXF1ZXN0ZXIgOiBwdWJsaWMgQm5HUFVDYWxsYmFjaworeworcHVibGljOgorICAgIHZpcnR1YWwgdm9pZCBncHVMb3N0KCkgeworICAgICAgICBMT0dEKCJDT05URVhUX0xPU1Q6IFJlbGVhc2luZyBHUFUgdXBvbiByZXF1ZXN0IGZyb20gU3VyZmFjZUZsaW5nZXIuIik7CisgICAgICAgIGdFR0xJbXBsW0lNUExfSEFSRFdBUkVdLmhvb2tzID0gJmdIb29rc1tJTVBMX0NPTlRFWFRfTE9TVF07CisgICAgfQorfTsKKworc3RhdGljIHNwPEdQVVJldm9rZVJlcXVlc3Rlcj4gZ1Jldm9rZXJDYWxsYmFjazsKKworCityZXF1ZXN0X2dwdV90KiBncHVfYWNxdWlyZSh2b2lkKiB1c2VyKQoreworICAgIHNwPElTdXJmYWNlQ29tcG9zZXI+IHNlcnZlciggZ2V0U3VyZmFjZUZsaW5nZXIoKSApOworCisgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKGdSZWdpb25zTG9jayk7CisgICAgaWYgKHNlcnZlciA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICAKKyAgICBJU3VyZmFjZUNvbXBvc2VyOjpncHVfaW5mb190IGluZm87CisgICAgCisgICAgaWYgKGdSZXZva2VyQ2FsbGJhY2sgPT0gMCkKKyAgICAgICAgZ1Jldm9rZXJDYWxsYmFjayA9IG5ldyBHUFVSZXZva2VSZXF1ZXN0ZXIoKTsKKworICAgIHN0YXR1c190IGVyciA9IHNlcnZlci0+cmVxdWVzdEdQVShnUmV2b2tlckNhbGxiYWNrLCAmaW5mbyk7CisgICAgaWYgKGVyciAhPSBOT19FUlJPUikgeworICAgICAgICBMT0dEKCJyZXF1ZXN0R1BVIHJldHVybmVkICVkIiwgZXJyKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgYm9vbCBmYWlsZWQgPSBmYWxzZTsKKyAgICByZXF1ZXN0X2dwdV90KiBncHUgPSAmZ1JlZ2lvbnM7CisgICAgbWVtc2V0KGdwdSwgMCwgc2l6ZW9mKCpncHUpKTsKKyAgICAKKyAgICBpZiAoaW5mby5yZWdzICE9IDApIHsKKyAgICAgICAgc3A8SU1lbW9yeUhlYXA+IGhlYXAoaW5mby5yZWdzLT5nZXRNZW1vcnkoKSk7CisgICAgICAgIGlmIChoZWFwICE9IDApIHsKKyAgICAgICAgICAgIGludCBmZCA9IGhlYXAtPmhlYXBJRCgpOworICAgICAgICAgICAgZ3B1LT5yZWdzLmZkID0gZmQ7CisgICAgICAgICAgICBncHUtPnJlZ3MuYmFzZSA9IGluZm8ucmVncy0+cG9pbnRlcigpOyAKKyAgICAgICAgICAgIGdwdS0+cmVncy5zaXplID0gaW5mby5yZWdzLT5zaXplKCk7IAorICAgICAgICAgICAgZ3B1LT5yZWdzLnVzZXIgPSBpbmZvLnJlZ3MuZ2V0KCk7CisjaWYgSEFWRV9BTkRST0lEX09TCisgICAgICAgICAgICBzdHJ1Y3QgcG1lbV9yZWdpb24gcmVnaW9uOworICAgICAgICAgICAgaWYgKGlvY3RsKGZkLCBQTUVNX0dFVF9QSFlTLCAmcmVnaW9uKSA+PSAwKQorICAgICAgICAgICAgICAgIGdwdS0+cmVncy5waHlzID0gKHZvaWQqKXJlZ2lvbi5vZmZzZXQ7CisjZW5kaWYKKyAgICAgICAgICAgIGluZm8ucmVncy0+aW5jU3Ryb25nKGdwdSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dFKCJHUFUgcmVnaXN0ZXIgaGFuZGxlICVwIGlzIGludmFsaWQhIiwgaW5mby5yZWdzLmdldCgpKTsKKyAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmb3IgKHNpemVfdCBpPTAgOyBpPGluZm8uY291bnQgJiYgIWZhaWxlZCA7IGkrKykgeworICAgICAgICBzcDxJTWVtb3J5PiYgcmVnaW9uKGluZm8ucmVnaW9uc1tpXS5yZWdpb24pOworICAgICAgICBpZiAocmVnaW9uICE9IDApIHsKKyAgICAgICAgICAgIHNwPElNZW1vcnlIZWFwPiBoZWFwKHJlZ2lvbi0+Z2V0TWVtb3J5KCkpOworICAgICAgICAgICAgaWYgKGhlYXAgIT0gMCkgeworICAgICAgICAgICAgICAgIGNvbnN0IGludCBmZCA9IGhlYXAtPmhlYXBJRCgpOworICAgICAgICAgICAgICAgIGdwdS0+Z3B1W2ldLmZkID0gZmQ7CisgICAgICAgICAgICAgICAgZ3B1LT5ncHVbaV0uYmFzZSA9IHJlZ2lvbi0+cG9pbnRlcigpOyAKKyAgICAgICAgICAgICAgICBncHUtPmdwdVtpXS5zaXplID0gcmVnaW9uLT5zaXplKCk7IAorICAgICAgICAgICAgICAgIGdwdS0+Z3B1W2ldLnVzZXIgPSByZWdpb24uZ2V0KCk7CisgICAgICAgICAgICAgICAgZ3B1LT5ncHVbaV0ub2Zmc2V0ID0gaW5mby5yZWdpb25zW2ldLnJlc2VydmVkOworI2lmIEhBVkVfQU5EUk9JRF9PUworICAgICAgICAgICAgICAgIHN0cnVjdCBwbWVtX3JlZ2lvbiByZWc7CisgICAgICAgICAgICAgICAgaWYgKGlvY3RsKGZkLCBQTUVNX0dFVF9QSFlTLCAmcmVnKSA+PSAwKQorICAgICAgICAgICAgICAgICAgICBncHUtPmdwdVtpXS5waHlzID0gKHZvaWQqKXJlZy5vZmZzZXQ7CisjZW5kaWYKKyAgICAgICAgICAgICAgICByZWdpb24tPmluY1N0cm9uZyhncHUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dFKCJHUFUgcmVnaW9uIGhhbmRsZSBbJWQsICVwXSBpcyBpbnZhbGlkISIsIGksIHJlZ2lvbi5nZXQoKSk7CisgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICBpZiAoZmFpbGVkKSB7CisgICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nLCBjbGVhbiB1cCBldmVyeXRoaW5nIQorICAgICAgICBpZiAoZ3B1LT5yZWdzLnVzZXIpIHsKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PElNZW1vcnkqPihncHUtPnJlZ3MudXNlciktPmRlY1N0cm9uZyhncHUpOworICAgICAgICAgICAgZm9yIChzaXplX3QgaT0wIDsgaTxpbmZvLmNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGdwdS0+Z3B1W2ldLnVzZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8SU1lbW9yeSo+KGdwdS0+Z3B1W2ldLnVzZXIpLT5kZWNTdHJvbmcoZ3B1KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgCisgICAgZ3B1LT5jb3VudCA9IGluZm8uY291bnQ7CisgICAgcmV0dXJuIGdwdTsKK30KKworaW50IGdwdV9yZWxlYXNlKHZvaWQqLCByZXF1ZXN0X2dwdV90KiBncHUpCit7CisgICAgc3A8SU1lbW9yeT4gcmVnczsKKworICAgIHsgLy8gc2NvcGUgZm9yIGxvY2sKKyAgICAgICAgTXV0ZXg6OkF1dG9sb2NrIF9sKGdSZWdpb25zTG9jayk7CisgICAgICAgIHJlZ3MgPSBzdGF0aWNfY2FzdDxJTWVtb3J5Kj4oZ3B1LT5yZWdzLnVzZXIpOyAgIAorICAgICAgICBncHUtPnJlZ3MudXNlciA9IDA7CisgICAgICAgIGlmIChyZWdzICE9IDApIHJlZ3MtPmRlY1N0cm9uZyhncHUpOworICAgICAgICAKKyAgICAgICAgZm9yIChpbnQgaT0wIDsgaTxncHUtPmNvdW50IDsgaSsrKSB7CisgICAgICAgICAgICBzcDxJTWVtb3J5PiByKHN0YXRpY19jYXN0PElNZW1vcnkqPihncHUtPmdwdVtpXS51c2VyKSk7CisgICAgICAgICAgICBncHUtPmdwdVtpXS51c2VyID0gMDsKKyAgICAgICAgICAgIGlmIChyICE9IDApIHItPmRlY1N0cm9uZyhncHUpOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIC8vIHRoZXJlIGlzIGEgc3BlY2lhbCB0cmFuc2FjdGlvbiB0byByZWxpbnF1aXNoIHRoZSBHUFUKKyAgICAvLyAoaXQgd2lsbCBoYXBwZW4gYXV0b21hdGljYWxseSBhbnl3YXkgaWYgd2UgZG9uJ3QgZG8gdGhpcykKKyAgICBQYXJjZWwgZGF0YSwgcmVwbHk7CisgICAgLy8gTk9URTogdGhpcyB0cmFuc2FjdGlvbiBkb2VzIG5vdCByZXF1aXJlIGFuIGludGVyZmFjZSB0b2tlbgorICAgIHJlZ3MtPmFzQmluZGVyKCktPnRyYW5zYWN0KDEwMDAsIGRhdGEsICZyZXBseSk7CisgICAgcmV0dXJuIDE7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsLmNwcCBiL29wZW5nbC9saWJzL0dMRVNfQ00vZ2wuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2NWNmNDQKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsLmNwcApAQCAtMCwwICsxLDExNiBAQAorLyogCisgKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqKgorICoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqKgorICoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKioKKyAqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiR0xFU19DTSIKKworI2luY2x1ZGUgPGN0eXBlLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKworI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2xleHQuaD4KKworI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKyNpbmNsdWRlIDxjdXRpbHMvcHJvcGVydGllcy5oPgorCisjaW5jbHVkZSAiaG9va3MuaCIKKwordXNpbmcgbmFtZXNwYWNlIGFuZHJvaWQ7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGV4dGVuc2lvbnMgZm9yIHRoZSBmcmFtZXdvcmsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBnbENvbG9yUG9pbnRlckJvdW5kcyhHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsCisgICAgICAgIGNvbnN0IEdMdm9pZCAqcHRyLCBHTHNpemVpIGNvdW50KSB7CisgICAgZ2xDb2xvclBvaW50ZXIoc2l6ZSwgdHlwZSwgc3RyaWRlLCBwdHIpOworfQordm9pZCBnbE5vcm1hbFBvaW50ZXJCb3VuZHMoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLAorICAgICAgICBjb25zdCBHTHZvaWQgKnBvaW50ZXIsIEdMc2l6ZWkgY291bnQpIHsKKyAgICBnbE5vcm1hbFBvaW50ZXIodHlwZSwgc3RyaWRlLCBwb2ludGVyKTsKK30KK3ZvaWQgZ2xUZXhDb29yZFBvaW50ZXJCb3VuZHMoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsCisgICAgICAgIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIsIEdMc2l6ZWkgY291bnQpIHsKKyAgICBnbFRleENvb3JkUG9pbnRlcihzaXplLCB0eXBlLCBzdHJpZGUsIHBvaW50ZXIpOworfQordm9pZCBnbFZlcnRleFBvaW50ZXJCb3VuZHMoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsCisgICAgICAgIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIsIEdMc2l6ZWkgY291bnQpIHsKKyAgICBnbFZlcnRleFBvaW50ZXIoc2l6ZSwgdHlwZSwgc3RyaWRlLCBwb2ludGVyKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gQWN0dWFsIEdMIGVudHJ5LXBvaW50cworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWYgR0xfTE9HR0VSCisjICAgaW5jbHVkZSAiZ2xfbG9nZ2VyLmgiCisjICAgZGVmaW5lIEdMX0xPR0dFUl9JTVBMKF94KSBfeAorI2Vsc2UKKyMgICBkZWZpbmUgR0xfTE9HR0VSX0lNUEwoX3gpCisjZW5kaWYKKworI3VuZGVmIEFQSV9FTlRSWQorI3VuZGVmIENBTExfR0xfQVBJCisjdW5kZWYgQ0FMTF9HTF9BUElfUkVUVVJOCisKKyNpZiBVU0VfRkFTVF9UTFNfS0VZCisKKyAgICAjZGVmaW5lIEFQSV9FTlRSWShfYXBpKSBfX2F0dHJpYnV0ZV9fKChuYWtlZCkpIF9hcGkKKworICAgICNkZWZpbmUgQ0FMTF9HTF9BUEkoX2FwaSwgLi4uKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgIGFzbSB2b2xhdGlsZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAibW92ICAgcjEyLCAjMHhGRkZGMEZGRiAgIFxuIiAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgImxkciAgIHIxMiwgW3IxMiwgIy0xNV0gICBcbiIgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICJsZHIgICByMTIsIFtyMTIsICVbdGxzXV0gXG4iICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAiY21wICAgcjEyLCAjMCAgICAgICAgICAgIFxuIiAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgImxkcm5lIHBjLCAgW3IxMiwgJVthcGldXSBcbiIgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICJieCAgICBsciAgICAgICAgICAgICAgICAgXG4iICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOiBbdGxzXSAiSiIoVExTX1NMT1RfT1BFTkdMX0FQSSo0KSwgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgW2FwaV0gIkoiKF9fYnVpbHRpbl9vZmZzZXRvZihnbF9ob29rc190LCBnbC5fYXBpKSkgICAgXAorICAgICAgICAgICAgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICk7CisgICAgCisgICAgI2RlZmluZSBDQUxMX0dMX0FQSV9SRVRVUk4oX2FwaSwgLi4uKSBcCisgICAgICAgIENBTExfR0xfQVBJKF9hcGksIF9fVkFfQVJHU19fKSBcCisgICAgICAgIHJldHVybiAwOyAvLyBwbGFjYXRlIGdjYydzIHdhcm5pbmdzLiBuZXZlciByZWFjaGVkLgorCisjZWxzZQorCisgICAgI2RlZmluZSBBUElfRU5UUlkoX2FwaSkgX2FwaQorCisgICAgI2RlZmluZSBDQUxMX0dMX0FQSShfYXBpLCAuLi4pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGdsX2hvb2tzX3Q6OmdsX3QgY29uc3QgKiBjb25zdCBfYyA9ICZnZXRHbFRocmVhZFNwZWNpZmljKCktPmdsOyBcCisgICAgICAgIEdMX0xPR0dFUl9JTVBMKCBsb2dfIyNfYXBpKF9fVkFfQVJHU19fKTsgKSAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIF9jLT5fYXBpKF9fVkFfQVJHU19fKQorICAgIAorICAgICNkZWZpbmUgQ0FMTF9HTF9BUElfUkVUVVJOKF9hcGksIC4uLikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBnbF9ob29rc190OjpnbF90IGNvbnN0ICogY29uc3QgX2MgPSAmZ2V0R2xUaHJlYWRTcGVjaWZpYygpLT5nbDsgXAorICAgICAgICBHTF9MT0dHRVJfSU1QTCggbG9nXyMjX2FwaShfX1ZBX0FSR1NfXyk7ICkgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICByZXR1cm4gX2MtPl9hcGkoX19WQV9BUkdTX18pCisKKyNlbmRpZgorCitleHRlcm4gIkMiIHsKKyNpbmNsdWRlICJnbF9hcGkuaW4iCit9CisKKyN1bmRlZiBBUElfRU5UUlkKKyN1bmRlZiBDQUxMX0dMX0FQSQorI3VuZGVmIENBTExfR0xfQVBJX1JFVFVSTgorCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsX2FwaS5pbiBiL29wZW5nbC9saWJzL0dMRVNfQ00vZ2xfYXBpLmluCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyMzRlZjIKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsX2FwaS5pbgpAQCAtMCwwICsxLDYwNiBAQAordm9pZCBBUElfRU5UUlkoZ2xBY3RpdmVUZXh0dXJlKShHTGVudW0gdGV4dHVyZSkgeworICAgIENBTExfR0xfQVBJKGdsQWN0aXZlVGV4dHVyZSwgdGV4dHVyZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQWxwaGFGdW5jKShHTGVudW0gZnVuYywgR0xjbGFtcGYgcmVmKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xBbHBoYUZ1bmMsIGZ1bmMsIHJlZik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQWxwaGFGdW5jeCkoR0xlbnVtIGZ1bmMsIEdMY2xhbXB4IHJlZikgeworICAgIENBTExfR0xfQVBJKGdsQWxwaGFGdW5jeCwgZnVuYywgcmVmKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xCaW5kVGV4dHVyZSkoR0xlbnVtIHRhcmdldCwgR0x1aW50IHRleHR1cmUpIHsKKyAgICBDQUxMX0dMX0FQSShnbEJpbmRUZXh0dXJlLCB0YXJnZXQsIHRleHR1cmUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEJsZW5kRnVuYykoR0xlbnVtIHNmYWN0b3IsIEdMZW51bSBkZmFjdG9yKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xCbGVuZEZ1bmMsIHNmYWN0b3IsIGRmYWN0b3IpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyKShHTGJpdGZpZWxkIG1hc2spIHsKKyAgICBDQUxMX0dMX0FQSShnbENsZWFyLCBtYXNrKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDbGVhckNvbG9yKShHTGNsYW1wZiByZWQsIEdMY2xhbXBmIGdyZWVuLCBHTGNsYW1wZiBibHVlLCBHTGNsYW1wZiBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJDb2xvciwgcmVkLCBncmVlbiwgYmx1ZSwgYWxwaGEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyQ29sb3J4KShHTGNsYW1weCByZWQsIEdMY2xhbXB4IGdyZWVuLCBHTGNsYW1weCBibHVlLCBHTGNsYW1weCBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJDb2xvcngsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDbGVhckRlcHRoZikoR0xjbGFtcGYgZGVwdGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbENsZWFyRGVwdGhmLCBkZXB0aCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ2xlYXJEZXB0aHgpKEdMY2xhbXB4IGRlcHRoKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDbGVhckRlcHRoeCwgZGVwdGgpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyU3RlbmNpbCkoR0xpbnQgcykgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJTdGVuY2lsLCBzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDbGllbnRBY3RpdmVUZXh0dXJlKShHTGVudW0gdGV4dHVyZSkgeworICAgIENBTExfR0xfQVBJKGdsQ2xpZW50QWN0aXZlVGV4dHVyZSwgdGV4dHVyZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ29sb3I0ZikoR0xmbG9hdCByZWQsIEdMZmxvYXQgZ3JlZW4sIEdMZmxvYXQgYmx1ZSwgR0xmbG9hdCBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ29sb3I0ZiwgcmVkLCBncmVlbiwgYmx1ZSwgYWxwaGEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbG9yNHgpKEdMZml4ZWQgcmVkLCBHTGZpeGVkIGdyZWVuLCBHTGZpeGVkIGJsdWUsIEdMZml4ZWQgYWxwaGEpIHsKKyAgICBDQUxMX0dMX0FQSShnbENvbG9yNHgsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDb2xvck1hc2spKEdMYm9vbGVhbiByLCBHTGJvb2xlYW4gZywgR0xib29sZWFuIGIsIEdMYm9vbGVhbiBhKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb2xvck1hc2ssIHIsIGcsIGIsIGEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbG9yUG9pbnRlcikoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnB0cikKK3sKKyAgICBDQUxMX0dMX0FQSShnbENvbG9yUG9pbnRlciwgc2l6ZSwgdHlwZSwgc3RyaWRlLCBwdHIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbXByZXNzZWRUZXhJbWFnZTJEKShHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGludCBib3JkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xzaXplaSBpbWFnZVNpemUsIGNvbnN0IEdMdm9pZCAqZGF0YSkgeworICAgIENBTExfR0xfQVBJKGdsQ29tcHJlc3NlZFRleEltYWdlMkQsIHRhcmdldCwgbGV2ZWwsIGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgYm9yZGVyLCBpbWFnZVNpemUsIGRhdGEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEKSggR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMaW50IHlvZmZzZXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGVudW0gZm9ybWF0LCBHTHNpemVpIGltYWdlU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR0x2b2lkICpkYXRhKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgeW9mZnNldCwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgaW1hZ2VTaXplLCBkYXRhKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDb3B5VGV4SW1hZ2UyRCkoICBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICBHTGludCBib3JkZXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbENvcHlUZXhJbWFnZTJELCB0YXJnZXQsIGxldmVsLCBpbnRlcm5hbGZvcm1hdCwgeCwgeSwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIGJvcmRlcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ29weVRleFN1YkltYWdlMkQpKCAgIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMaW50IHlvZmZzZXQsIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xzaXplaSBoZWlnaHQpIHsKKyAgICBDQUxMX0dMX0FQSShnbENvcHlUZXhTdWJJbWFnZTJELCB0YXJnZXQsIGxldmVsLCB4b2Zmc2V0LCB5b2Zmc2V0LCB4LCB5LAorICAgICAgICAgICAgd2lkdGgsIGhlaWdodCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ3VsbEZhY2UpKEdMZW51bSBtb2RlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDdWxsRmFjZSwgbW9kZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRGVsZXRlVGV4dHVyZXMpKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICp0ZXh0dXJlcykgeworICAgIENBTExfR0xfQVBJKGdsRGVsZXRlVGV4dHVyZXMsIG4sIHRleHR1cmVzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEZXB0aEZ1bmMpKEdMZW51bSBmdW5jKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZXB0aEZ1bmMsIGZ1bmMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbERlcHRoTWFzaykoR0xib29sZWFuIGZsYWcpIHsKKyAgICBDQUxMX0dMX0FQSShnbERlcHRoTWFzaywgZmxhZyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRGVwdGhSYW5nZWYpKEdMY2xhbXBmIHpOZWFyLCBHTGNsYW1wZiB6RmFyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZXB0aFJhbmdlZiwgek5lYXIsIHpGYXIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbERlcHRoUmFuZ2V4KShHTGNsYW1weCB6TmVhciwgR0xjbGFtcHggekZhcikgeworICAgIENBTExfR0xfQVBJKGdsRGVwdGhSYW5nZXgsIHpOZWFyLCB6RmFyKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEaXNhYmxlKShHTGVudW0gY2FwKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEaXNhYmxlLCBjYXApOworfQorCit2b2lkIEFQSV9FTlRSWShnbERpc2FibGVDbGllbnRTdGF0ZSkoR0xlbnVtIGFycmF5KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEaXNhYmxlQ2xpZW50U3RhdGUsIGFycmF5KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEcmF3QXJyYXlzKShHTGVudW0gbW9kZSwgR0xpbnQgZmlyc3QsIEdMc2l6ZWkgY291bnQpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdBcnJheXMsIG1vZGUsIGZpcnN0LCBjb3VudCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd0VsZW1lbnRzKShHTGVudW0gbW9kZSwgR0xzaXplaSBjb3VudCwKKyAgICAgICAgICAgICAgICAgICAgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd0VsZW1lbnRzLCBtb2RlLCBjb3VudCwgdHlwZSwgaW5kaWNlcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRW5hYmxlKShHTGVudW0gY2FwKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xFbmFibGUsIGNhcCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRW5hYmxlQ2xpZW50U3RhdGUpKEdMZW51bSBhcnJheSkgeworICAgIENBTExfR0xfQVBJKGdsRW5hYmxlQ2xpZW50U3RhdGUsIGFycmF5KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGaW5pc2gpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbEZpbmlzaCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRmx1c2gpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbEZsdXNoKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGb2dmKShHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbEZvZ2YsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRm9nZnYpKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGb2dmdiwgcG5hbWUsIHBhcmFtcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRm9neCkoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGb2d4LCBwbmFtZSwgcGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbEZvZ3h2KShHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsRm9neHYsIHBuYW1lLCBwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEZyb250RmFjZSkoR0xlbnVtIG1vZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbEZyb250RmFjZSwgbW9kZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRnJ1c3R1bWYpKEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwKKyAgICAgICAgICAgICAgICBHTGZsb2F0IGJvdHRvbSwgR0xmbG9hdCB0b3AsCisgICAgICAgICAgICAgICAgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGcnVzdHVtZiwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCB6TmVhciwgekZhcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRnJ1c3R1bXgpKEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwKKyAgICAgICAgICAgICAgICBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsCisgICAgICAgICAgICAgICAgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGcnVzdHVteCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCB6TmVhciwgekZhcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsR2VuVGV4dHVyZXMpKEdMc2l6ZWkgbiwgR0x1aW50ICp0ZXh0dXJlcykgeworICAgIENBTExfR0xfQVBJKGdsR2VuVGV4dHVyZXMsIG4sIHRleHR1cmVzKTsKK30KKworR0xlbnVtIEFQSV9FTlRSWShnbEdldEVycm9yKSh2b2lkKSB7CisgICAgQ0FMTF9HTF9BUElfUkVUVVJOKGdsR2V0RXJyb3IpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEdldEludGVnZXJ2KShHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldEludGVnZXJ2LCBwbmFtZSwgcGFyYW1zKTsKK30KKworY29uc3QgR0x1Ynl0ZSAqIEFQSV9FTlRSWShnbEdldFN0cmluZykoR0xlbnVtIG5hbWUpIHsKKyAgICBDQUxMX0dMX0FQSV9SRVRVUk4oZ2xHZXRTdHJpbmcsIG5hbWUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEhpbnQpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBtb2RlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xIaW50LCB0YXJnZXQsIG1vZGUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpZ2h0TW9kZWxmKShHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbExpZ2h0TW9kZWxmLCBwbmFtZSwgcGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpZ2h0TW9kZWxmdikoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpZ2h0TW9kZWxmdiwgcG5hbWUsIHBhcmFtcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTGlnaHRNb2RlbHgpKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsTGlnaHRNb2RlbHgsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTGlnaHRNb2RlbHh2KShHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsTGlnaHRNb2RlbHh2LCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodGYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodGYsIGxpZ2h0LCBwbmFtZSwgcGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpZ2h0ZnYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpZ2h0ZnYsIGxpZ2h0LCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodHgpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodHgsIGxpZ2h0LCBwbmFtZSwgcGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpZ2h0eHYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpZ2h0eHYsIGxpZ2h0LCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaW5lV2lkdGgpKEdMZmxvYXQgd2lkdGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpbmVXaWR0aCwgd2lkdGgpOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpbmVXaWR0aHgpKEdMZml4ZWQgd2lkdGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpbmVXaWR0aHgsIHdpZHRoKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMb2FkSWRlbnRpdHkpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbExvYWRJZGVudGl0eSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTG9hZE1hdHJpeGYpKGNvbnN0IEdMZmxvYXQgKm0pIHsKKyAgICBDQUxMX0dMX0FQSShnbExvYWRNYXRyaXhmLCBtKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMb2FkTWF0cml4eCkoY29uc3QgR0xmaXhlZCAqbSkgeworICAgIENBTExfR0xfQVBJKGdsTG9hZE1hdHJpeHgsIG0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbExvZ2ljT3ApKEdMZW51bSBvcGNvZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbExvZ2ljT3AsIG9wY29kZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTWF0ZXJpYWxmKShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xNYXRlcmlhbGYsIGZhY2UsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTWF0ZXJpYWxmdikoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xNYXRlcmlhbGZ2LCBmYWNlLCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNYXRlcmlhbHgpKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbE1hdGVyaWFseCwgZmFjZSwgcG5hbWUsIHBhcmFtKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNYXRlcmlhbHh2KShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbE1hdGVyaWFseHYsIGZhY2UsIHBuYW1lLCBwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbE1hdHJpeE1vZGUpKEdMZW51bSBtb2RlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xNYXRyaXhNb2RlLCBtb2RlKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNdWx0TWF0cml4ZikoY29uc3QgR0xmbG9hdCAqbSkgeworICAgIENBTExfR0xfQVBJKGdsTXVsdE1hdHJpeGYsIG0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbE11bHRNYXRyaXh4KShjb25zdCBHTGZpeGVkICptKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xNdWx0TWF0cml4eCwgbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTXVsdGlUZXhDb29yZDRmKShHTGVudW0gdGFyZ2V0LCBHTGZsb2F0IHMsIEdMZmxvYXQgdCwgR0xmbG9hdCByLCBHTGZsb2F0IHEpIHsKKyAgICBDQUxMX0dMX0FQSShnbE11bHRpVGV4Q29vcmQ0ZiwgdGFyZ2V0LCBzLCB0LCByLCBxKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNdWx0aVRleENvb3JkNHgpKEdMZW51bSB0YXJnZXQsIEdMZml4ZWQgcywgR0xmaXhlZCB0LCBHTGZpeGVkIHIsIEdMZml4ZWQgcSkgeworICAgIENBTExfR0xfQVBJKGdsTXVsdGlUZXhDb29yZDR4LCB0YXJnZXQsIHMsIHQsIHIsIHEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbE5vcm1hbDNmKShHTGZsb2F0IG54LCBHTGZsb2F0IG55LCBHTGZsb2F0IG56KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xOb3JtYWwzZiwgbngsIG55LCBueik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTm9ybWFsM3gpKEdMZml4ZWQgbngsIEdMZml4ZWQgbnksIEdMZml4ZWQgbnopIHsKKyAgICBDQUxMX0dMX0FQSShnbE5vcm1hbDN4LCBueCwgbnksIG56KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xOb3JtYWxQb2ludGVyKShHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikgeworICAgIENBTExfR0xfQVBJKGdsTm9ybWFsUG9pbnRlciwgdHlwZSwgc3RyaWRlLCBwb2ludGVyKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xPcnRob2YpKCAgR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LAorICAgICAgICAgICAgICAgIEdMZmxvYXQgYm90dG9tLCBHTGZsb2F0IHRvcCwKKyAgICAgICAgICAgICAgICBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbE9ydGhvZiwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCB6TmVhciwgekZhcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsT3J0aG94KSggIEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwKKyAgICAgICAgICAgICAgICBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsCisgICAgICAgICAgICAgICAgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xPcnRob3gsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgek5lYXIsIHpGYXIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFBpeGVsU3RvcmVpKShHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQaXhlbFN0b3JlaSwgcG5hbWUsIHBhcmFtKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb2ludFNpemUpKEdMZmxvYXQgc2l6ZSkgeworICAgIENBTExfR0xfQVBJKGdsUG9pbnRTaXplLCBzaXplKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb2ludFNpemV4KShHTGZpeGVkIHNpemUpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50U2l6ZXgsIHNpemUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFBvbHlnb25PZmZzZXQpKEdMZmxvYXQgZmFjdG9yLCBHTGZsb2F0IHVuaXRzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2x5Z29uT2Zmc2V0LCBmYWN0b3IsIHVuaXRzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb2x5Z29uT2Zmc2V0eCkoR0xmaXhlZCBmYWN0b3IsIEdMZml4ZWQgdW5pdHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvbHlnb25PZmZzZXR4LCBmYWN0b3IsIHVuaXRzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb3BNYXRyaXgpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvcE1hdHJpeCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUHVzaE1hdHJpeCkodm9pZCkgeworICAgIENBTExfR0xfQVBJKGdsUHVzaE1hdHJpeCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUmVhZFBpeGVscykoICBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIEdMdm9pZCAqcGl4ZWxzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xSZWFkUGl4ZWxzLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUsIHBpeGVscyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUm90YXRlZikoR0xmbG9hdCBhbmdsZSwgR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeikgeworICAgIENBTExfR0xfQVBJKGdsUm90YXRlZiwgYW5nbGUsIHgsIHksIHopOworfQorCit2b2lkIEFQSV9FTlRSWShnbFJvdGF0ZXgpKEdMZml4ZWQgYW5nbGUsIEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopIHsKKyAgICBDQUxMX0dMX0FQSShnbFJvdGF0ZXgsIGFuZ2xlLCB4LCB5LCB6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTYW1wbGVDb3ZlcmFnZSkoR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFNhbXBsZUNvdmVyYWdlLCB2YWx1ZSwgaW52ZXJ0KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTYW1wbGVDb3ZlcmFnZXgpKEdMY2xhbXB4IHZhbHVlLCBHTGJvb2xlYW4gaW52ZXJ0KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xTYW1wbGVDb3ZlcmFnZXgsIHZhbHVlLCBpbnZlcnQpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFNjYWxlZikoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeikgeworICAgIENBTExfR0xfQVBJKGdsU2NhbGVmLCB4LCB5LCB6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTY2FsZXgpKEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHopIHsKKyAgICBDQUxMX0dMX0FQSShnbFNjYWxleCwgeCwgeSwgeik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsU2Npc3NvcikoR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFNjaXNzb3IsIHgsIHksIHdpZHRoLCBoZWlnaHQpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFNoYWRlTW9kZWwpKEdMZW51bSBtb2RlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xTaGFkZU1vZGVsLCBtb2RlKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTdGVuY2lsRnVuYykoR0xlbnVtIGZ1bmMsIEdMaW50IHJlZiwgR0x1aW50IG1hc2spIHsKKyAgICBDQUxMX0dMX0FQSShnbFN0ZW5jaWxGdW5jLCBmdW5jLCByZWYsIG1hc2spOworfQorCit2b2lkIEFQSV9FTlRSWShnbFN0ZW5jaWxNYXNrKShHTHVpbnQgbWFzaykgeworICAgIENBTExfR0xfQVBJKGdsU3RlbmNpbE1hc2ssIG1hc2spOworfQorCit2b2lkIEFQSV9FTlRSWShnbFN0ZW5jaWxPcCkoR0xlbnVtIGZhaWwsIEdMZW51bSB6ZmFpbCwgR0xlbnVtIHpwYXNzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xTdGVuY2lsT3AsIGZhaWwsIHpmYWlsLCB6cGFzcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4Q29vcmRQb2ludGVyKSggR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhDb29yZFBvaW50ZXIsIHNpemUsIHR5cGUsIHN0cmlkZSwgcG9pbnRlcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4RW52ZikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhFbnZmLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4RW52ZnYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhFbnZmdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhFbnZ4KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleEVudngsIHRhcmdldCwgcG5hbWUsIHBhcmFtKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhFbnZ4dikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleEVudnh2LCB0YXJnZXQsIHBuYW1lLCBwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleEltYWdlMkQpKCAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyLCBHTGVudW0gZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpwaXhlbHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleEltYWdlMkQsIHRhcmdldCwgbGV2ZWwsIGludGVybmFsZm9ybWF0LCB3aWR0aCwgaGVpZ2h0LAorICAgICAgICAgICAgYm9yZGVyLCBmb3JtYXQsIHR5cGUsIHBpeGVscyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4UGFyYW1ldGVyZikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJmLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4UGFyYW1ldGVyeCkoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJ4LCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4U3ViSW1hZ2UyRCkoICAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKnBpeGVscykgeworICAgIENBTExfR0xfQVBJKGdsVGV4U3ViSW1hZ2UyRCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgeW9mZnNldCwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgcGl4ZWxzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUcmFuc2xhdGVmKShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUcmFuc2xhdGVmLCB4LCB5LCB6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUcmFuc2xhdGV4KShHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUcmFuc2xhdGV4LCB4LCB5LCB6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xWZXJ0ZXhQb2ludGVyKSggICBHTGludCBzaXplLCBHTGVudW0gdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbFZlcnRleFBvaW50ZXIsIHNpemUsIHR5cGUsIHN0cmlkZSwgcG9pbnRlcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVmlld3BvcnQpKEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xWaWV3cG9ydCwgeCwgeSwgd2lkdGgsIGhlaWdodCk7Cit9CisKKy8vIEVTIDEuMQordm9pZCBBUElfRU5UUlkoZ2xDbGlwUGxhbmVmKShHTGVudW0gcGxhbmUsIGNvbnN0IEdMZmxvYXQgKmVxdWF0aW9uKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDbGlwUGxhbmVmLCBwbGFuZSwgZXF1YXRpb24pOworfQordm9pZCBBUElfRU5UUlkoZ2xDbGlwUGxhbmV4KShHTGVudW0gcGxhbmUsIGNvbnN0IEdMZml4ZWQgKmVxdWF0aW9uKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDbGlwUGxhbmV4LCBwbGFuZSwgZXF1YXRpb24pOworfQordm9pZCBBUElfRU5UUlkoZ2xCaW5kQnVmZmVyKShHTGVudW0gdGFyZ2V0LCBHTHVpbnQgYnVmZmVyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xCaW5kQnVmZmVyLCB0YXJnZXQsIGJ1ZmZlcik7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEJ1ZmZlckRhdGEpKEdMZW51bSB0YXJnZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkKiBkYXRhLCBHTGVudW0gdXNhZ2UpIHsKKyAgICBDQUxMX0dMX0FQSShnbEJ1ZmZlckRhdGEsIHRhcmdldCwgc2l6ZSwgZGF0YSwgdXNhZ2UpOworfQordm9pZCBBUElfRU5UUlkoZ2xCdWZmZXJTdWJEYXRhKShHTGVudW0gdGFyZ2V0LCBHTGludHB0ciBvZmZzZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkKiBkYXRhKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xCdWZmZXJTdWJEYXRhLCB0YXJnZXQsIG9mZnNldCwgc2l6ZSwgZGF0YSk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbERlbGV0ZUJ1ZmZlcnMpKEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50KiBidWZmZXJzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZWxldGVCdWZmZXJzLCBuLCBidWZmZXJzKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2VuQnVmZmVycykoR0xzaXplaSBuLCBHTHVpbnQqIGJ1ZmZlcnMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdlbkJ1ZmZlcnMsIG4sIGJ1ZmZlcnMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRCb29sZWFudikoR0xlbnVtIHBuYW1lLCBHTGJvb2xlYW4gKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0Qm9vbGVhbnYsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRGaXhlZHYpKEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRGaXhlZHYsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRGbG9hdHYpKEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRGbG9hdHYsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRQb2ludGVydikoR0xlbnVtIHBuYW1lLCB2b2lkICoqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRQb2ludGVydiwgcG5hbWUsIHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldEJ1ZmZlclBhcmFtZXRlcml2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldEJ1ZmZlclBhcmFtZXRlcml2LCB0YXJnZXQsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRDbGlwUGxhbmVmKShHTGVudW0gcG5hbWUsIEdMZmxvYXQgZXFuWzRdKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRDbGlwUGxhbmVmLCBwbmFtZSwgZXFuKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0Q2xpcFBsYW5leCkoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIGVxbls0XSkgeworICAgIENBTExfR0xfQVBJKGdsR2V0Q2xpcFBsYW5leCwgcG5hbWUsIGVxbik7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldExpZ2h0eHYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldExpZ2h0eHYsIGxpZ2h0LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0TGlnaHRmdikoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0TGlnaHRmdiwgbGlnaHQsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRNYXRlcmlhbHh2KShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldE1hdGVyaWFseHYsIGZhY2UsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRNYXRlcmlhbGZ2KShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldE1hdGVyaWFsZnYsIGZhY2UsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRUZXhFbnZmdikoR0xlbnVtIGVudiwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldFRleEVudmZ2LCBlbnYsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRUZXhFbnZpdikoR0xlbnVtIGVudiwgR0xlbnVtIHBuYW1lLCBHTGludCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhFbnZpdiwgZW52LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4RW52eHYpKEdMZW51bSBlbnYsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhFbnZ4diwgZW52LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4UGFyYW1ldGVyZnYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhQYXJhbWV0ZXJmdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4UGFyYW1ldGVyaXYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0VGV4UGFyYW1ldGVyaXYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldFRleFBhcmFtZXRlcnh2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0VGV4UGFyYW1ldGVyeHYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7Cit9CitHTGJvb2xlYW4gQVBJX0VOVFJZKGdsSXNCdWZmZXIpKEdMdWludCBidWZmZXIpIHsKKyAgICBDQUxMX0dMX0FQSV9SRVRVUk4oZ2xJc0J1ZmZlciwgYnVmZmVyKTsKK30KK0dMYm9vbGVhbiBBUElfRU5UUlkoZ2xJc0VuYWJsZWQpKEdMZW51bSBjYXApIHsKKyAgICBDQUxMX0dMX0FQSV9SRVRVUk4oZ2xJc0VuYWJsZWQsIGNhcCk7Cit9CitHTGJvb2xlYW4gQVBJX0VOVFJZKGdsSXNUZXh0dXJlKShHTHVpbnQgdGV4dHVyZSkgeworICAgIENBTExfR0xfQVBJX1JFVFVSTihnbElzVGV4dHVyZSwgdGV4dHVyZSk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbFBvaW50UGFyYW1ldGVyZikoR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2ludFBhcmFtZXRlcmYsIHBuYW1lLCBwYXJhbSk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbFBvaW50UGFyYW1ldGVyZnYpKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2ludFBhcmFtZXRlcmZ2LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRQYXJhbWV0ZXJ4KShHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50UGFyYW1ldGVyeCwgcG5hbWUsIHBhcmFtKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRQYXJhbWV0ZXJ4dikoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50UGFyYW1ldGVyeHYsIHBuYW1lLCBwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xDb2xvcjR1YikoR0x1Ynl0ZSByZWQsIEdMdWJ5dGUgZ3JlZW4sIEdMdWJ5dGUgYmx1ZSwgR0x1Ynl0ZSBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ29sb3I0dWIsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsVGV4RW52aSkoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsVGV4RW52aSwgdGFyZ2V0LCBwbmFtZSwgcGFyYW0pOworfQordm9pZCBBUElfRU5UUlkoZ2xUZXhFbnZpdikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhFbnZpdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhQYXJhbWV0ZXJmdikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleFBhcmFtZXRlcmZ2LCB0YXJnZXQsIHBuYW1lLCBwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleFBhcmFtZXRlcml2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMaW50ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleFBhcmFtZXRlcml2LCB0YXJnZXQsIHBuYW1lLCBwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleFBhcmFtZXRlcmkpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleFBhcmFtZXRlcmksIHRhcmdldCwgcG5hbWUsIHBhcmFtKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsVGV4UGFyYW1ldGVyeHYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJ4diwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRTaXplUG9pbnRlck9FUykoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50U2l6ZVBvaW50ZXJPRVMsIHR5cGUsIHN0cmlkZSwgcG9pbnRlcik7Cit9CisKKy8vIEV4dGVuc2lvbnMKK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd1RleHNPRVMpKEdMc2hvcnQgeCAsIEdMc2hvcnQgeSwgR0xzaG9ydCB6LCBHTHNob3J0IHcsIEdMc2hvcnQgaCkgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleHNPRVMsIHgsIHksIHosIHcsIGgpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4aU9FUykoR0xpbnQgeCwgR0xpbnQgeSwgR0xpbnQgeiwgR0xpbnQgdywgR0xpbnQgaCkgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleGlPRVMsIHgsIHksIHosIHcsIGgpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4Zk9FUykoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeiwgR0xmbG9hdCB3LCBHTGZsb2F0IGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdUZXhmT0VTLCB4LCB5LCB6LCB3LCBoKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd1RleHhPRVMpKEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHosIEdMZml4ZWQgdywgR0xmaXhlZCBoKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEcmF3VGV4eE9FUywgeCwgeSwgeiwgdywgaCk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbERyYXdUZXhzdk9FUykoY29uc3QgR0xzaG9ydCogY29vcmRzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEcmF3VGV4c3ZPRVMsIGNvb3Jkcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbERyYXdUZXhpdk9FUykoY29uc3QgR0xpbnQqIGNvb3JkcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleGl2T0VTLCBjb29yZHMpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4ZnZPRVMpKGNvbnN0IEdMZmxvYXQqIGNvb3JkcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleGZ2T0VTLCBjb29yZHMpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4eHZPRVMpKGNvbnN0IEdMZml4ZWQqIGNvb3JkcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleHh2T0VTLCBjb29yZHMpOworfQorR0xiaXRmaWVsZCBBUElfRU5UUlkoZ2xRdWVyeU1hdHJpeHhPRVMpKEdMZml4ZWQqIG1hbnRpc3NhLCBHTGludCogZXhwb25lbnQpIHsKKyAgICBDQUxMX0dMX0FQSV9SRVRVUk4oZ2xRdWVyeU1hdHJpeHhPRVMsIG1hbnRpc3NhLCBleHBvbmVudCk7Cit9CmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsX2xvZ2dlci5jcHAgYi9vcGVuZ2wvbGlicy9HTEVTX0NNL2dsX2xvZ2dlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdiZTVjOQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJzL0dMRVNfQ00vZ2xfbG9nZ2VyLmNwcApAQCAtMCwwICsxLDEwNjAgQEAKKy8qCisgKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqKgorICoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqKgorICoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqKgorICoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkdMTG9nZ2VyIgorCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGRsZmNuLmg+CisKKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKworI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKyNpbmNsdWRlIDxFR0wvZWdsZXh0Lmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2xleHQuaD4KKworI2luY2x1ZGUgPGN1dGlscy9sb2cuaD4KKyNpbmNsdWRlIDxjdXRpbHMvYXRvbWljLmg+CisjaW5jbHVkZSA8Y3V0aWxzL3Byb3BlcnRpZXMuaD4KKworI2luY2x1ZGUgPHV0aWxzL1N0cmluZzguaD4KKworI2luY2x1ZGUgImdsX2xvZ2dlci5oIgorCisjdW5kZWYgTkVMRU0KKyNkZWZpbmUgTkVMRU0oeCkgKHNpemVvZih4KS9zaXplb2YoKih4KSkpCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKFQgY29uc3Qgc29ydGVkQXJyYXlbXSwgaW50IGZpcnN0LCBpbnQgbGFzdCwgRUdMaW50IGtleSkKK3sKKyAgIHdoaWxlIChmaXJzdCA8PSBsYXN0KSB7CisgICAgICAgaW50IG1pZCA9IChmaXJzdCArIGxhc3QpIC8gMjsKKyAgICAgICBpZiAoa2V5ID4gc29ydGVkQXJyYXlbbWlkXS5rZXkpIHsKKyAgICAgICAgICAgZmlyc3QgPSBtaWQgKyAxOworICAgICAgIH0gZWxzZSBpZiAoa2V5IDwgc29ydGVkQXJyYXlbbWlkXS5rZXkpIHsKKyAgICAgICAgICAgbGFzdCA9IG1pZCAtIDE7CisgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgcmV0dXJuIG1pZDsKKyAgICAgICB9CisgICB9CisgICByZXR1cm4gLTE7Cit9CisKK3N0cnVjdCBwYWlyX3QgeworICAgIGNvbnN0IGNoYXIqIG5hbWU7CisgICAgaW50ICAgICAgICAga2V5OworfTsKKworc3RhdGljIGNvbnN0IHBhaXJfdCBnRW51bU1hcFtdID0geworICAgICNkZWZpbmUgR0xFTlVNKE5BTUUsIFZBTFVFKSB7ICNOQU1FLCBWQUxVRSB9LAorICAgICNpbmNsdWRlICJnbF9lbnVtcy5pbiIKKyAgICAjdW5kZWYgR0xFTlVNCit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIFRZUEU+CitjbGFzcyBHTExvZ1ZhbHVlIHsKK3B1YmxpYzoKKyAgICBHTExvZ1ZhbHVlKFRZUEUgdmFsdWUpIDogbVZhbHVlKHZhbHVlKSB7IH0KKyAgICBjb25zdCBUWVBFJiBnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIG1WYWx1ZTsgfQorICAgIFN0cmluZzggdG9TdHJpbmcoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBjb252ZXJ0VG9TdHJpbmcobVZhbHVlKTsKKyAgICB9Citwcml2YXRlOgorICAgIGNvbnN0IFRZUEUmIG1WYWx1ZTsKKyAgICBTdHJpbmc4IGNvbnZlcnRUb1N0cmluZyh1bnNpZ25lZCBpbnQgdikgY29uc3QgeworICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgIHNucHJpbnRmKGJ1ZiwgMTYsICIldSIsIHYpOworICAgICAgICByZXR1cm4gU3RyaW5nOChidWYpOworICAgIH0KKyAgICBTdHJpbmc4IGNvbnZlcnRUb1N0cmluZyh1bnNpZ25lZCBsb25nIHYpIGNvbnN0IHsKKyAgICAgICAgY2hhciBidWZbMTZdOworICAgICAgICBzbnByaW50ZihidWYsIDE2LCAiJWx1Iiwgdik7CisgICAgICAgIHJldHVybiBTdHJpbmc4KGJ1Zik7CisgICAgfQorICAgIFN0cmluZzggY29udmVydFRvU3RyaW5nKGludCB2KSBjb25zdCB7CisgICAgICAgIGNoYXIgYnVmWzE2XTsKKyAgICAgICAgc25wcmludGYoYnVmLCAxNiwgIiVkIiwgdik7CisgICAgICAgIHJldHVybiBTdHJpbmc4KGJ1Zik7CisgICAgfQorICAgIFN0cmluZzggY29udmVydFRvU3RyaW5nKGxvbmcgdikgY29uc3QgeworICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgIHNucHJpbnRmKGJ1ZiwgMTYsICIlbGQiLCB2KTsKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoYnVmKTsKKyAgICB9CisgICAgU3RyaW5nOCBjb252ZXJ0VG9TdHJpbmcoZmxvYXQgdikgY29uc3QgeworICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgIHNucHJpbnRmKGJ1ZiwgMTYsICIlZiIsIHYpOworICAgICAgICByZXR1cm4gU3RyaW5nOChidWYpOworICAgIH0KKyAgICBTdHJpbmc4IGNvbnZlcnRUb1N0cmluZyh2b2lkIGNvbnN0KiB2KSBjb25zdCB7CisgICAgICAgIGNoYXIgYnVmWzE2XTsKKyAgICAgICAgc25wcmludGYoYnVmLCAxNiwgIiVwIiwgdik7CisgICAgICAgIHJldHVybiBTdHJpbmc4KGJ1Zik7CisgICAgfQorfTsKKworY2xhc3MgR0xMb2dFbnVtIDogcHVibGljIEdMTG9nVmFsdWU8R0xlbnVtPiB7CitwdWJsaWM6CisgICAgR0xMb2dFbnVtKEdMZW51bSB2KSA6IEdMTG9nVmFsdWU8R0xlbnVtPih2KSB7IH0KKyAgICBTdHJpbmc4IHRvU3RyaW5nKCkgY29uc3QgeworICAgICAgICBHTGVudW0gdiA9IGdldFZhbHVlKCk7CisgICAgICAgIGludCBpID0gYmluYXJ5U2VhcmNoPHBhaXJfdD4oZ0VudW1NYXAsIDAsIE5FTEVNKGdFbnVtTWFwKS0xLCB2KTsKKyAgICAgICAgaWYgKGkgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIFN0cmluZzgoZ0VudW1NYXBbaV0ubmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgICAgICBzbnByaW50ZihidWYsIDE2LCAiMHglMDR4Iiwgdik7CisgICAgICAgICAgICByZXR1cm4gU3RyaW5nOChidWYpOworICAgICAgICB9CisgICAgfQorfTsKKworY2xhc3MgR0xMb2dDbGVhckJpdGZpZWxkIDogcHVibGljIEdMTG9nVmFsdWU8R0xiaXRmaWVsZD4geworcHVibGljOgorICAgIEdMTG9nQ2xlYXJCaXRmaWVsZChHTGJpdGZpZWxkIHYpIDogR0xMb2dWYWx1ZTxHTGJpdGZpZWxkPih2KSB7IH0KKyAgICBTdHJpbmc4IHRvU3RyaW5nKCkgY29uc3QgeworICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgIHNucHJpbnRmKGJ1ZiwgMTYsICIweCUwOHgiLCBnZXRWYWx1ZSgpKTsKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoYnVmKTsKKyAgICB9Cit9OworCitjbGFzcyBHTExvZ0Jvb2wgOiBwdWJsaWMgR0xMb2dWYWx1ZTxHTGJvb2xlYW4+IHsKK3B1YmxpYzoKKyAgICBHTExvZ0Jvb2woR0xib29sZWFuIHYpIDogR0xMb2dWYWx1ZTxHTGJvb2xlYW4+KHYpIHsgfQorICAgIFN0cmluZzggdG9TdHJpbmcoKSBjb25zdCB7CisgICAgICAgIEdMYm9vbGVhbiB2ID0gZ2V0VmFsdWUoKTsKKyAgICAgICAgaWYgKHYgPT0gR0xfVFJVRSkgICByZXR1cm4gU3RyaW5nOCgiR0xfVFJVRSIpOworICAgICAgICBpZiAodiA9PSBHTF9GQUxTRSkgIHJldHVybiBTdHJpbmc4KCJHTF9GQUxTRSIpOworICAgICAgICByZXR1cm4gR0xMb2dWYWx1ZTxHTGJvb2xlYW4+Ojp0b1N0cmluZygpOworICAgIH0KK307CisKK2NsYXNzIEdMTG9nRml4ZWQgOiBwdWJsaWMgR0xMb2dWYWx1ZTxHTGZpeGVkPiB7CitwdWJsaWM6CisgICAgR0xMb2dGaXhlZChHTGZpeGVkIHYpIDogR0xMb2dWYWx1ZTxHTGZpeGVkPih2KSB7IH0KKyAgICBTdHJpbmc4IHRvU3RyaW5nKCkgY29uc3QgeworICAgICAgICBjaGFyIGJ1ZlsxNl07CisgICAgICAgIHNucHJpbnRmKGJ1ZiwgMTYsICIweCUwOHgiLCBnZXRWYWx1ZSgpKTsKKyAgICAgICAgcmV0dXJuIFN0cmluZzgoYnVmKTsKKyAgICB9Cit9OworCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUWVBFPgorY2xhc3MgR0xMb2dCdWZmZXIgOiBwdWJsaWMgR0xMb2dWYWx1ZTxUWVBFICo+IHsKK3B1YmxpYzoKKyAgICBHTExvZ0J1ZmZlcihUWVBFKiBidWZmZXIsIHNpemVfdCBjb3VudCA9IC0xKQorICAgICAgICA6IEdMTG9nVmFsdWU8VFlQRSo+KGJ1ZmZlcikKKyAgICB7IC8vIG91dHB1dCBidWZmZXIKKyAgICB9CisgICAgR0xMb2dCdWZmZXIoVFlQRSBjb25zdCogYnVmZmVyLCBzaXplX3QgY291bnQgPSAtMSkKKyAgICA6IEdMTG9nVmFsdWU8VFlQRSo+KGNvbnN0X2Nhc3Q8VFlQRSo+KGJ1ZmZlcikpCisgICAgeyAvLyBpbnB1dCBidWZmZXIKKyAgICB9Cit9OworCitjbGFzcyBHTExvZworeworcHVibGljOgorICAgIEdMTG9nKGNvbnN0IGNoYXIqIG5hbWUpIDogbU51bVBhcmFtcygwKSB7CisgICAgICAgIG1TdHJpbmcuYXBwZW5kKG5hbWUpOworICAgICAgICBtU3RyaW5nLmFwcGVuZCgiKCIpOworICAgIH0KKworICAgIH5HTExvZygpIHsKKyAgICAgICAgTE9HRCgiJXMpOyIsIG1TdHJpbmcuc3RyaW5nKCkpOworICAgIH0KKworICAgIEdMTG9nJiBvcGVyYXRvciA8PCAodW5zaWduZWQgY2hhciB2KSB7CisgICAgICAgIHJldHVybiAqdGhpcyA8PCBHTExvZ1ZhbHVlPHVuc2lnbmVkIGludD4odik7CisgICAgfQorICAgIEdMTG9nJiBvcGVyYXRvciA8PCAoc2hvcnQgdikgeworICAgICAgICByZXR1cm4gKnRoaXMgPDwgR0xMb2dWYWx1ZTx1bnNpZ25lZCBpbnQ+KHYpOworICAgIH0KKyAgICBHTExvZyYgb3BlcmF0b3IgPDwgKHVuc2lnbmVkIGludCB2KSB7CisgICAgICAgIHJldHVybiAqdGhpcyA8PCBHTExvZ1ZhbHVlPHVuc2lnbmVkIGludD4odik7CisgICAgfQorICAgIEdMTG9nJiBvcGVyYXRvciA8PCAoaW50IHYpIHsKKyAgICAgICAgcmV0dXJuICp0aGlzIDw8IEdMTG9nVmFsdWU8aW50Pih2KTsKKyAgICB9CisgICAgR0xMb2cmIG9wZXJhdG9yIDw8IChsb25nIHYpIHsKKyAgICAgICAgcmV0dXJuICp0aGlzIDw8IEdMTG9nVmFsdWU8bG9uZz4odik7CisgICAgfQorICAgIEdMTG9nJiBvcGVyYXRvciA8PCAodW5zaWduZWQgbG9uZyB2KSB7CisgICAgICAgIHJldHVybiAqdGhpcyA8PCBHTExvZ1ZhbHVlPHVuc2lnbmVkIGxvbmc+KHYpOworICAgIH0KKyAgICBHTExvZyYgb3BlcmF0b3IgPDwgKGZsb2F0IHYpIHsKKyAgICAgICAgcmV0dXJuICp0aGlzIDw8IEdMTG9nVmFsdWU8ZmxvYXQ+KHYpOworICAgIH0KKyAgICBHTExvZyYgb3BlcmF0b3IgPDwgKGNvbnN0IHZvaWQqIHYpIHsKKyAgICAgICAgcmV0dXJuICp0aGlzIDw8IEdMTG9nVmFsdWU8Y29uc3Qgdm9pZCogPih2KTsKKyAgICB9CisKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVFlQRT4KKyAgICBHTExvZyYgb3BlcmF0b3IgPDwgKGNvbnN0IFRZUEUmIHJocykgeworICAgICAgICBpZiAobU51bVBhcmFtcyA+IDApCisgICAgICAgICAgICBtU3RyaW5nLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgbVN0cmluZy5hcHBlbmQocmhzLnRvU3RyaW5nKCkpOworICAgICAgICBtTnVtUGFyYW1zKys7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBjb25zdCBTdHJpbmc4JiBzdHJpbmcoKSBjb25zdCB7IHJldHVybiBtU3RyaW5nOyB9Citwcml2YXRlOgorICAgIEdMTG9nKGNvbnN0IEdMTG9nJik7CisKKyAgICBTdHJpbmc4IG1TdHJpbmc7CisgICAgaW50IG1OdW1QYXJhbXM7Cit9OworCisjZGVmaW5lIEFQSV9FTlRSWShhcGkpICAgICAgICAgICAgICAgICAgICAgIGxvZ18jI2FwaQorI2RlZmluZSBDQUxMX0dMX0FQSShfeCwgLi4uKQorI2RlZmluZSBDQUxMX0dMX0FQSV9SRVRVUk4oX3gsIC4uLikgICAgICAgICByZXR1cm4oMCk7CisKK3ZvaWQgQVBJX0VOVFJZKGdsQWN0aXZlVGV4dHVyZSkoR0xlbnVtIHRleHR1cmUpIHsKKyAgICBDQUxMX0dMX0FQSShnbEFjdGl2ZVRleHR1cmUsIHRleHR1cmUpOworICAgIEdMTG9nKCJnbEFjdGl2ZVRleHR1cmUiKSA8PCBHTExvZ0VudW0odGV4dHVyZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQWxwaGFGdW5jKShHTGVudW0gZnVuYywgR0xjbGFtcGYgcmVmKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xBbHBoYUZ1bmMsIGZ1bmMsIHJlZik7CisgICAgR0xMb2coImdsQWxwaGFGdW5jIikgPDwgR0xMb2dFbnVtKGZ1bmMpIDw8IHJlZjsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xBbHBoYUZ1bmN4KShHTGVudW0gZnVuYywgR0xjbGFtcHggcmVmKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xBbHBoYUZ1bmN4LCBmdW5jLCByZWYpOworICAgIEdMTG9nKCJnbEFscGhhRnVuY3giKSA8PCBHTExvZ0VudW0oZnVuYykgPDwgR0xMb2dGaXhlZChyZWYpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEJpbmRUZXh0dXJlKShHTGVudW0gdGFyZ2V0LCBHTHVpbnQgdGV4dHVyZSkgeworICAgIENBTExfR0xfQVBJKGdsQmluZFRleHR1cmUsIHRhcmdldCwgdGV4dHVyZSk7CisgICAgR0xMb2coImdsQmluZFRleHR1cmUiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCB0ZXh0dXJlOworfQorCit2b2lkIEFQSV9FTlRSWShnbEJsZW5kRnVuYykoR0xlbnVtIHNmYWN0b3IsIEdMZW51bSBkZmFjdG9yKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xCbGVuZEZ1bmMsIHNmYWN0b3IsIGRmYWN0b3IpOworICAgIEdMTG9nKCJnbEJsZW5kRnVuYyIpIDw8IEdMTG9nRW51bShzZmFjdG9yKSA8PCBHTExvZ0VudW0oZGZhY3Rvcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ2xlYXIpKEdMYml0ZmllbGQgbWFzaykgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXIsIG1hc2spOworICAgIEdMTG9nKCJnbENsZWFyIikgPDwgR0xMb2dDbGVhckJpdGZpZWxkKG1hc2spOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyQ29sb3IpKEdMY2xhbXBmIHJlZCwgR0xjbGFtcGYgZ3JlZW4sIEdMY2xhbXBmIGJsdWUsIEdMY2xhbXBmIGFscGhhKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDbGVhckNvbG9yLCByZWQsIGdyZWVuLCBibHVlLCBhbHBoYSk7CisgICAgR0xMb2coImdsQ2xlYXJDb2xvciIpIDw8IHJlZCA8PCBncmVlbiA8PCBibHVlIDw8IGFscGhhOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyQ29sb3J4KShHTGNsYW1weCByZWQsIEdMY2xhbXB4IGdyZWVuLCBHTGNsYW1weCBibHVlLCBHTGNsYW1weCBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJDb2xvcngsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKKyAgICBHTExvZygiZ2xDbGVhckNvbG9yeCIpIDw8IEdMTG9nRml4ZWQocmVkKSA8PCBHTExvZ0ZpeGVkKGdyZWVuKSA8PCBHTExvZ0ZpeGVkKGJsdWUpIDw8IEdMTG9nRml4ZWQoYWxwaGEpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyRGVwdGhmKShHTGNsYW1wZiBkZXB0aCkgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJEZXB0aGYsIGRlcHRoKTsKKyAgICBHTExvZygiZ2xDbGVhckRlcHRoZiIpIDw8IGRlcHRoOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyRGVwdGh4KShHTGNsYW1weCBkZXB0aCkgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJEZXB0aHgsIGRlcHRoKTsKKyAgICBHTExvZygiZ2xDbGVhckRlcHRoeCIpIDw8IEdMTG9nRml4ZWQoZGVwdGgpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsZWFyU3RlbmNpbCkoR0xpbnQgcykgeworICAgIENBTExfR0xfQVBJKGdsQ2xlYXJTdGVuY2lsLCBzKTsKKyAgICBHTExvZygiZ2xDbGVhclN0ZW5jaWwiKSA8PCBzOworfQorCit2b2lkIEFQSV9FTlRSWShnbENsaWVudEFjdGl2ZVRleHR1cmUpKEdMZW51bSB0ZXh0dXJlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDbGllbnRBY3RpdmVUZXh0dXJlLCB0ZXh0dXJlKTsKKyAgICBHTExvZygiZ2xDbGllbnRBY3RpdmVUZXh0dXJlIikgPDwgR0xMb2dFbnVtKHRleHR1cmUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbG9yNGYpKEdMZmxvYXQgcmVkLCBHTGZsb2F0IGdyZWVuLCBHTGZsb2F0IGJsdWUsIEdMZmxvYXQgYWxwaGEpIHsKKyAgICBDQUxMX0dMX0FQSShnbENvbG9yNGYsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKKyAgICBHTExvZygiZ2xDb2xvcjRmIikgPDwgcmVkIDw8IGdyZWVuIDw8IGJsdWUgPDwgYWxwaGE7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ29sb3I0eCkoR0xmaXhlZCByZWQsIEdMZml4ZWQgZ3JlZW4sIEdMZml4ZWQgYmx1ZSwgR0xmaXhlZCBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ29sb3I0eCwgcmVkLCBncmVlbiwgYmx1ZSwgYWxwaGEpOworICAgIEdMTG9nKCJnbENvbG9yNHgiKSA8PCBHTExvZ0ZpeGVkKHJlZCkgPDwgR0xMb2dGaXhlZChncmVlbikgPDwgR0xMb2dGaXhlZChibHVlKSA8PCBHTExvZ0ZpeGVkKGFscGhhKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDb2xvck1hc2spKEdMYm9vbGVhbiByLCBHTGJvb2xlYW4gZywgR0xib29sZWFuIGIsIEdMYm9vbGVhbiBhKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb2xvck1hc2ssIHIsIGcsIGIsIGEpOworICAgIEdMTG9nKCJnbENvbG9yTWFzayIpIDw8IEdMTG9nQm9vbChyKSA8PCBHTExvZ0Jvb2woZykgPDwgR0xMb2dCb29sKGIpIDw8IEdMTG9nQm9vbChhKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDb2xvclBvaW50ZXIpKEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwdHIpCit7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb2xvclBvaW50ZXIsIHNpemUsIHR5cGUsIHN0cmlkZSwgcHRyKTsKKyAgICBHTExvZygiZ2xDb2xvclBvaW50ZXIiKSA8PCBzaXplIDw8IEdMTG9nRW51bSh0eXBlKSA8PCBzdHJpZGUgPDwgcHRyOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvbXByZXNzZWRUZXhJbWFnZTJEKShHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGludCBib3JkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xzaXplaSBpbWFnZVNpemUsIGNvbnN0IEdMdm9pZCAqZGF0YSkgeworICAgIENBTExfR0xfQVBJKGdsQ29tcHJlc3NlZFRleEltYWdlMkQsIHRhcmdldCwgbGV2ZWwsIGludGVybmFsZm9ybWF0LAorICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgYm9yZGVyLCBpbWFnZVNpemUsIGRhdGEpOworICAgIEdMTG9nKCJnbENvbXByZXNzZWRUZXhJbWFnZTJEIikKKyAgICAgICAgICAgICAgICA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBsZXZlbCA8PCBHTExvZ0VudW0oaW50ZXJuYWxmb3JtYXQpCisgICAgICAgICAgICAgICAgPDwgd2lkdGggPDwgaGVpZ2h0IDw8IGJvcmRlciA8PCBpbWFnZVNpemUgPDwgZGF0YTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCkoIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xlbnVtIGZvcm1hdCwgR0xzaXplaSBpbWFnZVNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdMdm9pZCAqZGF0YSkgeworICAgIENBTExfR0xfQVBJKGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQsIHRhcmdldCwgbGV2ZWwsIHhvZmZzZXQsIHlvZmZzZXQsCisgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIGltYWdlU2l6ZSwgZGF0YSk7CisgICAgR0xMb2coImdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQiKQorICAgICAgICAgICAgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgbGV2ZWwgPDwgeG9mZnNldCA8PCB5b2Zmc2V0CisgICAgICAgICAgICA8PCB3aWR0aCA8PCBoZWlnaHQgPDwgR0xMb2dFbnVtKGZvcm1hdCkgPDwgaW1hZ2VTaXplIDw8IGRhdGE7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsQ29weVRleEltYWdlMkQpKCAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMZW51bSBpbnRlcm5hbGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgICAgR0xpbnQgYm9yZGVyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb3B5VGV4SW1hZ2UyRCwgdGFyZ2V0LCBsZXZlbCwgaW50ZXJuYWxmb3JtYXQsIHgsIHksCisgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCBib3JkZXIpOworICAgIEdMTG9nKCJnbENvcHlUZXhJbWFnZTJEIikKKyAgICAgICAgICAgIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IGxldmVsIDw8IEdMTG9nRW51bShpbnRlcm5hbGZvcm1hdCkKKyAgICAgICAgICAgIDw8IHggPDwgeSA8PCB3aWR0aCA8PCBoZWlnaHQgPDwgYm9yZGVyOworfQorCit2b2lkIEFQSV9FTlRSWShnbENvcHlUZXhTdWJJbWFnZTJEKSggICBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xpbnQgeG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTGludCB5b2Zmc2V0LCBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMc2l6ZWkgaGVpZ2h0KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xDb3B5VGV4U3ViSW1hZ2UyRCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgeW9mZnNldCwgeCwgeSwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQpOworICAgIEdMTG9nKCJnbENvcHlUZXhTdWJJbWFnZTJEIikKKyAgICAgICAgICAgIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IGxldmVsIDw8IHhvZmZzZXQgPDwgeW9mZnNldAorICAgICAgICAgICAgPDwgeCA8PCB5IDw8IHdpZHRoIDw8IGhlaWdodDsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xDdWxsRmFjZSkoR0xlbnVtIG1vZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbEN1bGxGYWNlLCBtb2RlKTsKKyAgICBHTExvZygiZ2xDdWxsRmFjZSIpIDw8IEdMTG9nRW51bShtb2RlKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEZWxldGVUZXh0dXJlcykoR0xzaXplaSBuLCBjb25zdCBHTHVpbnQgKnRleHR1cmVzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZWxldGVUZXh0dXJlcywgbiwgdGV4dHVyZXMpOworICAgIEdMTG9nKCJnbERlbGV0ZVRleHR1cmVzIikgPDwgbiA8PCBHTExvZ0J1ZmZlcjxHTHVpbnQ+KHRleHR1cmVzLCBuKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEZXB0aEZ1bmMpKEdMZW51bSBmdW5jKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZXB0aEZ1bmMsIGZ1bmMpOworICAgIEdMTG9nKCJnbERlcHRoRnVuYyIpIDw8IEdMTG9nRW51bShmdW5jKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEZXB0aE1hc2spKEdMYm9vbGVhbiBmbGFnKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEZXB0aE1hc2ssIGZsYWcpOworICAgIEdMTG9nKCJnbERlcHRoTWFzayIpIDw8IEdMTG9nQm9vbChmbGFnKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xEZXB0aFJhbmdlZikoR0xjbGFtcGYgek5lYXIsIEdMY2xhbXBmIHpGYXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbERlcHRoUmFuZ2VmLCB6TmVhciwgekZhcik7CisgICAgR0xMb2coImdsRGVwdGhSYW5nZWYiKSA8PCB6TmVhciA8PCB6RmFyOworfQorCit2b2lkIEFQSV9FTlRSWShnbERlcHRoUmFuZ2V4KShHTGNsYW1weCB6TmVhciwgR0xjbGFtcHggekZhcikgeworICAgIENBTExfR0xfQVBJKGdsRGVwdGhSYW5nZXgsIHpOZWFyLCB6RmFyKTsKKyAgICBHTExvZygiZ2xEZXB0aFJhbmdleCIpIDw8IEdMTG9nRml4ZWQoek5lYXIpIDw8IEdMTG9nRml4ZWQoekZhcik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRGlzYWJsZSkoR0xlbnVtIGNhcCkgeworICAgIENBTExfR0xfQVBJKGdsRGlzYWJsZSwgY2FwKTsKKyAgICBHTExvZygiZ2xEaXNhYmxlIikgPDwgR0xMb2dFbnVtKGNhcCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRGlzYWJsZUNsaWVudFN0YXRlKShHTGVudW0gYXJyYXkpIHsKKyAgICBDQUxMX0dMX0FQSShnbERpc2FibGVDbGllbnRTdGF0ZSwgYXJyYXkpOworICAgIEdMTG9nKCJnbERpc2FibGVDbGllbnRTdGF0ZSIpIDw8IEdMTG9nRW51bShhcnJheSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd0FycmF5cykoR0xlbnVtIG1vZGUsIEdMaW50IGZpcnN0LCBHTHNpemVpIGNvdW50KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEcmF3QXJyYXlzLCBtb2RlLCBmaXJzdCwgY291bnQpOworICAgIEdMTG9nKCJnbERyYXdBcnJheXMiKSA8PCBHTExvZ0VudW0obW9kZSkgPDwgZmlyc3QgPDwgY291bnQ7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd0VsZW1lbnRzKShHTGVudW0gbW9kZSwgR0xzaXplaSBjb3VudCwKKyAgICAgICAgICAgICAgICAgICAgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd0VsZW1lbnRzLCBtb2RlLCBjb3VudCwgdHlwZSwgaW5kaWNlcyk7CisgICAgR0xMb2cgbG9nKCJnbERyYXdFbGVtZW50cyIpOworICAgIGxvZyA8PCBHTExvZ0VudW0obW9kZSkgPDwgY291bnQgPDwgR0xMb2dFbnVtKHR5cGUpOworICAgIGlmICh0eXBlID09IEdMX1VOU0lHTkVEX0JZVEUpIHsKKyAgICAgICAgbG9nIDw8IEdMTG9nQnVmZmVyPEdMdWJ5dGU+KHN0YXRpY19jYXN0PGNvbnN0IEdMdWJ5dGUqPihpbmRpY2VzKSwgY291bnQpOworICAgIH0gZWxzZSB7CisgICAgICAgIGxvZyA8PCBHTExvZ0J1ZmZlcjxHTHVzaG9ydD4oc3RhdGljX2Nhc3Q8Y29uc3QgR0x1c2hvcnQqPihpbmRpY2VzKSwgY291bnQpOworICAgIH0KKyAgICBsb2c7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRW5hYmxlKShHTGVudW0gY2FwKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xFbmFibGUsIGNhcCk7CisgICAgR0xMb2coImdsRW5hYmxlIikgPDwgR0xMb2dFbnVtKGNhcCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRW5hYmxlQ2xpZW50U3RhdGUpKEdMZW51bSBhcnJheSkgeworICAgIENBTExfR0xfQVBJKGdsRW5hYmxlQ2xpZW50U3RhdGUsIGFycmF5KTsKKyAgICBHTExvZygiZ2xFbmFibGVDbGllbnRTdGF0ZSIpIDw8IEdMTG9nRW51bShhcnJheSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRmluaXNoKSh2b2lkKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGaW5pc2gpOworICAgIEdMTG9nKCJnbEZpbmlzaCIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEZsdXNoKSh2b2lkKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGbHVzaCk7CisgICAgR0xMb2coImdsRmx1c2giKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGb2dmKShHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbEZvZ2YsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsRm9nZiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgcGFyYW07Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRm9nZnYpKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGb2dmdiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xGb2dmdiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGb2d4KShHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbEZvZ3gsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsRm9neCIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dGaXhlZChwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRm9neHYpKEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGb2d4diwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xGb2dmeCIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGcm9udEZhY2UpKEdMZW51bSBtb2RlKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGcm9udEZhY2UsIG1vZGUpOworICAgIEdMTG9nKCJnbEZyb250RmFjZSIpIDw8IEdMTG9nRW51bShtb2RlKTsKKyB9CisKK3ZvaWQgQVBJX0VOVFJZKGdsRnJ1c3R1bWYpKEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwKKyAgICAgICAgICAgICAgICBHTGZsb2F0IGJvdHRvbSwgR0xmbG9hdCB0b3AsCisgICAgICAgICAgICAgICAgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xGcnVzdHVtZiwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCB6TmVhciwgekZhcik7CisgICAgR0xMb2coImdsRnJ1c3R1bWYiKSA8PCBsZWZ0IDw8IHJpZ2h0IDw8IGJvdHRvbSA8PCB0b3AgPDwgek5lYXIgPDwgekZhcjsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xGcnVzdHVteCkoR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LAorICAgICAgICAgICAgICAgIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwKKyAgICAgICAgICAgICAgICBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbEZydXN0dW14LCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIHpOZWFyLCB6RmFyKTsKKyAgICBHTExvZygiZ2xGcnVzdHVteCIpCisgICAgICAgICAgICA8PCBHTExvZ0ZpeGVkKGxlZnQpIDw8IEdMTG9nRml4ZWQocmlnaHQpCisgICAgICAgICAgICA8PCBHTExvZ0ZpeGVkKGJvdHRvbSkgPDwgR0xMb2dGaXhlZCh0b3ApCisgICAgICAgICAgICA8PCBHTExvZ0ZpeGVkKHpOZWFyKSA8PCBHTExvZ0ZpeGVkKHpGYXIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbEdlblRleHR1cmVzKShHTHNpemVpIG4sIEdMdWludCAqdGV4dHVyZXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdlblRleHR1cmVzLCBuLCB0ZXh0dXJlcyk7CisgICAgR0xMb2coImdsR2VuVGV4dHVyZXMiKSA8PCBuIDw8IEdMTG9nQnVmZmVyPEdMdWludD4odGV4dHVyZXMsIG4pOworfQorCitHTGVudW0gQVBJX0VOVFJZKGdsR2V0RXJyb3IpKHZvaWQpIHsKKyAgICBHTExvZygiZ2xHZXRFcnJvciIpOworICAgIENBTExfR0xfQVBJX1JFVFVSTihnbEdldEVycm9yKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xHZXRJbnRlZ2VydikoR0xlbnVtIHBuYW1lLCBHTGludCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRJbnRlZ2VydiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRJbnRlZ2VydiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xpbnQ+KHBhcmFtcyk7Cit9CisKK2NvbnN0IEdMdWJ5dGUgKiBBUElfRU5UUlkoZ2xHZXRTdHJpbmcpKEdMZW51bSBuYW1lKSB7CisgICAgR0xMb2coImdsR2V0U3RyaW5nIikgPDwgR0xMb2dFbnVtKG5hbWUpOworICAgIENBTExfR0xfQVBJX1JFVFVSTihnbEdldFN0cmluZywgbmFtZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsSGludCkoR0xlbnVtIHRhcmdldCwgR0xlbnVtIG1vZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbEhpbnQsIHRhcmdldCwgbW9kZSk7CisgICAgR0xMb2coIkdMZW51bSIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShtb2RlKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodE1vZGVsZikoR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodE1vZGVsZiwgcG5hbWUsIHBhcmFtKTsKKyAgICBHTExvZygiZ2xMaWdodE1vZGVsZiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgcGFyYW07Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTGlnaHRNb2RlbGZ2KShHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsTGlnaHRNb2RlbGZ2LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbExpZ2h0TW9kZWxmdiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodE1vZGVseCkoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodE1vZGVseCwgcG5hbWUsIHBhcmFtKTsKKyAgICBHTExvZygiZ2xMaWdodE1vZGVseCIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dGaXhlZChwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTGlnaHRNb2RlbHh2KShHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsTGlnaHRNb2RlbHh2LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbExpZ2h0TW9kZWx4diIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodGYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodGYsIGxpZ2h0LCBwbmFtZSwgcGFyYW0pOworICAgIEdMTG9nKCJnbExpZ2h0ZiIpIDw8IEdMTG9nRW51bShsaWdodCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBwYXJhbTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaWdodGZ2KShHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xMaWdodGZ2LCBsaWdodCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xMaWdodGZ2IikgPDwgR0xMb2dFbnVtKGxpZ2h0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMZmxvYXQ+KHBhcmFtcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTGlnaHR4KShHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkgeworICAgQ0FMTF9HTF9BUEkoZ2xMaWdodHgsIGxpZ2h0LCBwbmFtZSwgcGFyYW0pOworICAgR0xMb2coImdsTGlnaHR4IikgPDwgR0xMb2dFbnVtKGxpZ2h0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nRml4ZWQocGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpZ2h0eHYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpZ2h0eHYsIGxpZ2h0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbExpZ2h0eHYiKSA8PCBHTExvZ0VudW0obGlnaHQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMaW5lV2lkdGgpKEdMZmxvYXQgd2lkdGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpbmVXaWR0aCwgd2lkdGgpOworICAgIEdMTG9nKCJnbExpbmVXaWR0aCIpIDw8IHdpZHRoOworfQorCit2b2lkIEFQSV9FTlRSWShnbExpbmVXaWR0aHgpKEdMZml4ZWQgd2lkdGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbExpbmVXaWR0aHgsIHdpZHRoKTsKKyAgICBHTExvZygiZ2xMaW5lV2lkdGgiKSA8PCBHTExvZ0ZpeGVkKHdpZHRoKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMb2FkSWRlbnRpdHkpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbExvYWRJZGVudGl0eSk7CisgICAgR0xMb2coImdsTG9hZElkZW50aXR5Iik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTG9hZE1hdHJpeGYpKGNvbnN0IEdMZmxvYXQgKm0pIHsKKyAgICBDQUxMX0dMX0FQSShnbExvYWRNYXRyaXhmLCBtKTsKKyAgICBHTExvZygiZ2xMb2FkTWF0cml4ZiIpIDw8IEdMTG9nQnVmZmVyPEdMZmxvYXQ+KG0sIDE2KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xMb2FkTWF0cml4eCkoY29uc3QgR0xmaXhlZCAqbSkgeworICAgIENBTExfR0xfQVBJKGdsTG9hZE1hdHJpeHgsIG0pOworICAgIEdMTG9nKCJnbExvYWRNYXRyaXh4IikgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4obSwgMTYpOworfQorCit2b2lkIEFQSV9FTlRSWShnbExvZ2ljT3ApKEdMZW51bSBvcGNvZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbExvZ2ljT3AsIG9wY29kZSk7CisgICAgR0xMb2coImdsTG9naWNPcCIpIDw8IEdMTG9nRW51bShvcGNvZGUpOworfQorCit2b2lkIEFQSV9FTlRSWShnbE1hdGVyaWFsZikoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsTWF0ZXJpYWxmLCBmYWNlLCBwbmFtZSwgcGFyYW0pOworICAgIEdMTG9nKCJnbE1hdGVyaWFsZiIpIDw8IEdMTG9nRW51bShmYWNlKSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IHBhcmFtOworfQorCit2b2lkIEFQSV9FTlRSWShnbE1hdGVyaWFsZnYpKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsTWF0ZXJpYWxmdiwgZmFjZSwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xNYXRlcmlhbGZ2IikgPDwgR0xMb2dFbnVtKGZhY2UpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNYXRlcmlhbHgpKEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbE1hdGVyaWFseCwgZmFjZSwgcG5hbWUsIHBhcmFtKTsKKyAgICBHTExvZygiZ2xNYXRlcmlhbHgiKSA8PCBHTExvZ0VudW0oZmFjZSkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0ZpeGVkKHBhcmFtKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNYXRlcmlhbHh2KShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbE1hdGVyaWFseHYsIGZhY2UsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsTWF0ZXJpYWx4diIpIDw8IEdMTG9nRW51bShmYWNlKSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMZml4ZWQ+KHBhcmFtcyk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTWF0cml4TW9kZSkoR0xlbnVtIG1vZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbE1hdHJpeE1vZGUsIG1vZGUpOworICAgIEdMTG9nKCJnbE1hdHJpeE1vZGUiKSA8PCBHTExvZ0VudW0obW9kZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTXVsdE1hdHJpeGYpKGNvbnN0IEdMZmxvYXQgKm0pIHsKKyAgICBDQUxMX0dMX0FQSShnbE11bHRNYXRyaXhmLCBtKTsKKyAgICBHTExvZygiZ2xNdWx0TWF0cml4ZiIpIDw8IEdMTG9nQnVmZmVyPEdMZmxvYXQ+KG0sIDE2KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNdWx0TWF0cml4eCkoY29uc3QgR0xmaXhlZCAqbSkgeworICAgIENBTExfR0xfQVBJKGdsTXVsdE1hdHJpeHgsIG0pOworICAgIEdMTG9nKCJnbE11bHRNYXRyaXh4IikgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4obSwgMTYpOworfQorCit2b2lkIEFQSV9FTlRSWShnbE11bHRpVGV4Q29vcmQ0ZikoR0xlbnVtIHRhcmdldCwgR0xmbG9hdCBzLCBHTGZsb2F0IHQsIEdMZmxvYXQgciwgR0xmbG9hdCBxKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xNdWx0aVRleENvb3JkNGYsIHRhcmdldCwgcywgdCwgciwgcSk7CisgICAgR0xMb2coImdsTXVsdGlUZXhDb29yZDRmIikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgcyA8PCB0IDw8IHIgPDwgcTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xNdWx0aVRleENvb3JkNHgpKEdMZW51bSB0YXJnZXQsIEdMZml4ZWQgcywgR0xmaXhlZCB0LCBHTGZpeGVkIHIsIEdMZml4ZWQgcSkgeworICAgIENBTExfR0xfQVBJKGdsTXVsdGlUZXhDb29yZDR4LCB0YXJnZXQsIHMsIHQsIHIsIHEpOworICAgIEdMTG9nKCJnbE11bHRpVGV4Q29vcmQ0eCIpIDw8IEdMTG9nRW51bSh0YXJnZXQpCisgICAgICAgIDw8IEdMTG9nRml4ZWQocykgPDwgR0xMb2dGaXhlZCh0KSA8PCBHTExvZ0ZpeGVkKHIpIDw8IEdMTG9nRml4ZWQocSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsTm9ybWFsM2YpKEdMZmxvYXQgbngsIEdMZmxvYXQgbnksIEdMZmxvYXQgbnopIHsKKyAgICBDQUxMX0dMX0FQSShnbE5vcm1hbDNmLCBueCwgbnksIG56KTsKKyAgICBHTExvZygiZ2xOb3JtYWwzZiIpIDw8IG54IDw8IG55IDw8IG56OworfQorCit2b2lkIEFQSV9FTlRSWShnbE5vcm1hbDN4KShHTGZpeGVkIG54LCBHTGZpeGVkIG55LCBHTGZpeGVkIG56KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xOb3JtYWwzeCwgbngsIG55LCBueik7CisgICAgR0xMb2coImdsTm9ybWFsM3giKSA8PCBHTExvZ0ZpeGVkKG54KSA8PCBHTExvZ0ZpeGVkKG55KSA8PCBHTExvZ0ZpeGVkKG56KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xOb3JtYWxQb2ludGVyKShHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikgeworICAgIENBTExfR0xfQVBJKGdsTm9ybWFsUG9pbnRlciwgdHlwZSwgc3RyaWRlLCBwb2ludGVyKTsKKyAgICBHTExvZygiZ2xOb3JtYWxQb2ludGVyIikgPDwgR0xMb2dFbnVtKHR5cGUpIDw8IHN0cmlkZSA8PCBwb2ludGVyOworfQorCit2b2lkIEFQSV9FTlRSWShnbE9ydGhvZikoICBHTGZsb2F0IGxlZnQsIEdMZmxvYXQgcmlnaHQsCisgICAgICAgICAgICAgICAgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLAorICAgICAgICAgICAgICAgIEdMZmxvYXQgek5lYXIsIEdMZmxvYXQgekZhcikgeworICAgIENBTExfR0xfQVBJKGdsT3J0aG9mLCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIHpOZWFyLCB6RmFyKTsKKyAgICBHTExvZygiZ2xPcnRob2YiKSA8PCBsZWZ0IDw8IHJpZ2h0IDw8IGJvdHRvbSA8PCB0b3AgPDwgek5lYXIgPDwgekZhcjsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xPcnRob3gpKCAgR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LAorICAgICAgICAgICAgICAgIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwKKyAgICAgICAgICAgICAgICBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbE9ydGhveCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCB6TmVhciwgekZhcik7CisgICAgR0xMb2coImdsT3J0aG94IikgPDwgR0xMb2dGaXhlZChsZWZ0KSA8PCBHTExvZ0ZpeGVkKHJpZ2h0KQorICAgICAgICAgICAgPDwgR0xMb2dGaXhlZChib3R0b20pIDw8IEdMTG9nRml4ZWQodG9wKQorICAgICAgICAgICAgPDwgR0xMb2dGaXhlZCh6TmVhcikgPDwgR0xMb2dGaXhlZCh6RmFyKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQaXhlbFN0b3JlaSkoR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsUGl4ZWxTdG9yZWksIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsUGl4ZWxTdG9yZWkiKSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IHBhcmFtOworfQorCit2b2lkIEFQSV9FTlRSWShnbFBvaW50U2l6ZSkoR0xmbG9hdCBzaXplKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2ludFNpemUsIHNpemUpOworICAgIEdMTG9nKCJnbFBvaW50U2l6ZSIpIDw8IHNpemU7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRTaXpleCkoR0xmaXhlZCBzaXplKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2ludFNpemV4LCBzaXplKTsKKyAgICBHTExvZygiZ2xQb2ludFNpemV4IikgPDwgR0xMb2dGaXhlZChzaXplKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb2x5Z29uT2Zmc2V0KShHTGZsb2F0IGZhY3RvciwgR0xmbG9hdCB1bml0cykgeworICAgIENBTExfR0xfQVBJKGdsUG9seWdvbk9mZnNldCwgZmFjdG9yLCB1bml0cyk7CisgICAgR0xMb2coImdsUG9seWdvbk9mZnNldCIpIDw8IGZhY3RvciA8PCB1bml0czsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb2x5Z29uT2Zmc2V0eCkoR0xmaXhlZCBmYWN0b3IsIEdMZml4ZWQgdW5pdHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvbHlnb25PZmZzZXR4LCBmYWN0b3IsIHVuaXRzKTsKKyAgICBHTExvZygiZ2xQb2x5Z29uT2Zmc2V0eCIpIDw8IEdMTG9nRml4ZWQoZmFjdG9yKSA8PCBHTExvZ0ZpeGVkKHVuaXRzKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xQb3BNYXRyaXgpKHZvaWQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvcE1hdHJpeCk7CisgICAgR0xMb2coImdsUG9wTWF0cml4Iik7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUHVzaE1hdHJpeCkodm9pZCkgeworICAgIENBTExfR0xfQVBJKGdsUHVzaE1hdHJpeCk7CisgICAgR0xMb2coImdsUHVzaE1hdHJpeCIpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFJlYWRQaXhlbHMpKCAgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsCisgICAgICAgICAgICAgICAgICAgIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBHTHZvaWQgKnBpeGVscykgeworICAgIENBTExfR0xfQVBJKGdsUmVhZFBpeGVscywgeCwgeSwgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCB0eXBlLCBwaXhlbHMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsUmVhZFBpeGVscyIpIDw8IHggPDwgeSA8PCB3aWR0aCA8PCBoZWlnaHQgPDwgR0xMb2dFbnVtKGZvcm1hdCkgPDwgR0xMb2dFbnVtKHR5cGUpCisgICAgICAgICAgICA8PCBHTExvZ0J1ZmZlcjx1bnNpZ25lZCBjaGFyPihzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyICo+KHBpeGVscykpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFJvdGF0ZWYpKEdMZmxvYXQgYW5nbGUsIEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHopIHsKKyAgICBDQUxMX0dMX0FQSShnbFJvdGF0ZWYsIGFuZ2xlLCB4LCB5LCB6KTsKKyAgICBHTExvZygiZ2xSb3RhdGVmIikgPDwgYW5nbGUgPDwgeCA8PCB5IDw8IHo7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsUm90YXRleCkoR0xmaXhlZCBhbmdsZSwgR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeikgeworICAgIENBTExfR0xfQVBJKGdsUm90YXRleCwgYW5nbGUsIHgsIHksIHopOworICAgIEdMTG9nKCJnbFJvdGF0ZXgiKSA8PCBHTExvZ0ZpeGVkKGFuZ2xlKSA8PCBHTExvZ0ZpeGVkKHgpIDw8IEdMTG9nRml4ZWQoeSkgPDwgR0xMb2dGaXhlZCh6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTYW1wbGVDb3ZlcmFnZSkoR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFNhbXBsZUNvdmVyYWdlLCB2YWx1ZSwgaW52ZXJ0KTsKKyAgICBHTExvZygiZ2xTYW1wbGVDb3ZlcmFnZSIpIDw8IHZhbHVlIDw8IEdMTG9nQm9vbChpbnZlcnQpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFNhbXBsZUNvdmVyYWdleCkoR0xjbGFtcHggdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpIHsKKyAgICBDQUxMX0dMX0FQSShnbFNhbXBsZUNvdmVyYWdleCwgdmFsdWUsIGludmVydCk7CisgICAgR0xMb2coImdsU2FtcGxlQ292ZXJhZ2V4IikgPDwgR0xMb2dGaXhlZCh2YWx1ZSkgPDwgR0xMb2dCb29sKGludmVydCk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsU2NhbGVmKShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xTY2FsZWYsIHgsIHksIHopOworICAgIEdMTG9nKCJnbFNjYWxlZiIpIDw8IHggPDwgeSA8PCB6OworfQorCit2b2lkIEFQSV9FTlRSWShnbFNjYWxleCkoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeikgeworICAgIENBTExfR0xfQVBJKGdsU2NhbGV4LCB4LCB5LCB6KTsKKyAgICBHTExvZygiZ2xTY2FsZXgiKSA8PCBHTExvZ0ZpeGVkKHgpIDw8IEdMTG9nRml4ZWQoeSkgPDwgR0xMb2dGaXhlZCh6KTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTY2lzc29yKShHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCkgeworICAgIENBTExfR0xfQVBJKGdsU2Npc3NvciwgeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgR0xMb2coImdsU2Npc3NvciIpIDw8IHggPDwgeSA8PCB3aWR0aCA8PCBoZWlnaHQ7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsU2hhZGVNb2RlbCkoR0xlbnVtIG1vZGUpIHsKKyAgICBDQUxMX0dMX0FQSShnbFNoYWRlTW9kZWwsIG1vZGUpOworICAgIEdMTG9nKCJnbFNoYWRlTW9kZWwiKSA8PCBHTExvZ0VudW0obW9kZSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsU3RlbmNpbEZ1bmMpKEdMZW51bSBmdW5jLCBHTGludCByZWYsIEdMdWludCBtYXNrKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xTdGVuY2lsRnVuYywgZnVuYywgcmVmLCBtYXNrKTsKKyAgICBHTExvZygiZ2xTdGVuY2lsRnVuYyIpIDw8IEdMTG9nRW51bShmdW5jKSA8PCByZWYgPDwgbWFzazsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xTdGVuY2lsTWFzaykoR0x1aW50IG1hc2spIHsKKyAgICBDQUxMX0dMX0FQSShnbFN0ZW5jaWxNYXNrLCBtYXNrKTsKKyAgICBHTExvZygiZ2xTdGVuY2lsTWFzayIpIDw8IG1hc2s7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsU3RlbmNpbE9wKShHTGVudW0gZmFpbCwgR0xlbnVtIHpmYWlsLCBHTGVudW0genBhc3MpIHsKKyAgICBDQUxMX0dMX0FQSShnbFN0ZW5jaWxPcCwgZmFpbCwgemZhaWwsIHpwYXNzKTsKKyAgICBHTExvZygiZ2xTdGVuY2lsT3AiKSA8PCBHTExvZ0VudW0oZmFpbCkgPDwgR0xMb2dFbnVtKHpmYWlsKSA8PCBHTExvZ0VudW0oenBhc3MpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleENvb3JkUG9pbnRlcikoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikgeworICAgIENBTExfR0xfQVBJKGdsVGV4Q29vcmRQb2ludGVyLCBzaXplLCB0eXBlLCBzdHJpZGUsIHBvaW50ZXIpOworICAgIEdMTG9nKCJnbFRleENvb3JkUG9pbnRlciIpIDw8IHNpemUgPDwgR0xMb2dFbnVtKHR5cGUpIDw8IHN0cmlkZSA8PCBwb2ludGVyOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleEVudmYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsVGV4RW52ZiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW0pOworICAgIEdMTG9nKCJnbFRleEVudmYiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IHBhcmFtOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleEVudmZ2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsVGV4RW52ZnYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xUZXhFbnZ4IikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0PihwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleEVudngpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSkgeworICAgIENBTExfR0xfQVBJKGdsVGV4RW52eCwgdGFyZ2V0LCBwbmFtZSwgcGFyYW0pOworICAgIEdMTG9nKCJnbFRleEVudngiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nRml4ZWQocGFyYW0pOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleEVudnh2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsVGV4RW52eHYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xUZXhFbnZ4diIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhJbWFnZTJEKSggIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCBpbnRlcm5hbGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMaW50IGJvcmRlciwgR0xlbnVtIGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqcGl4ZWxzKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhJbWFnZTJELCB0YXJnZXQsIGxldmVsLCBpbnRlcm5hbGZvcm1hdCwgd2lkdGgsIGhlaWdodCwKKyAgICAgICAgICAgIGJvcmRlciwgZm9ybWF0LCB0eXBlLCBwaXhlbHMpOworICAgIEdMTG9nKCJnbFRleEltYWdlMkQiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBsZXZlbCA8PCBHTExvZ0VudW0oaW50ZXJuYWxmb3JtYXQpCisgICAgICAgICAgICA8PCB3aWR0aCA8PCBoZWlnaHQgPDwgYm9yZGVyIDw8IEdMTG9nRW51bShmb3JtYXQpIDw8IEdMTG9nRW51bSh0eXBlKQorICAgICAgICAgICAgPDwgR0xMb2dCdWZmZXI8dW5zaWduZWQgY2hhcj4oIHN0YXRpY19jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIgKj4ocGl4ZWxzKSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4UGFyYW1ldGVyZikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJmLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsVGV4UGFyYW1ldGVyZiIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgcGFyYW07Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4UGFyYW1ldGVyeCkoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJ4LCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsVGV4UGFyYW1ldGVyeCIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dGaXhlZChwYXJhbSk7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVGV4U3ViSW1hZ2UyRCkoICAgR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKnBpeGVscykgeworICAgIENBTExfR0xfQVBJKGdsVGV4U3ViSW1hZ2UyRCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgeW9mZnNldCwKKyAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgcGl4ZWxzKTsKKyAgICBHTExvZygiZ2xUZXhTdWJJbWFnZTJEIikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgbGV2ZWwgPDwgeG9mZnNldCA8PCB5b2Zmc2V0CisgICAgICAgICAgICA8PCB3aWR0aCA8PCBoZWlnaHQgPDwgR0xMb2dFbnVtKGZvcm1hdCkgPDwgR0xMb2dFbnVtKHR5cGUpCisgICAgICAgICAgICA8PCBHTExvZ0J1ZmZlcjx1bnNpZ25lZCBjaGFyPiggc3RhdGljX2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhciAqPihwaXhlbHMpKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUcmFuc2xhdGVmKShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUcmFuc2xhdGVmLCB4LCB5LCB6KTsKKyAgICBHTExvZygiZ2xUcmFuc2xhdGVmIikgPDwgeCA8PCB5IDw8IHo7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVHJhbnNsYXRleCkoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeikgeworICAgIENBTExfR0xfQVBJKGdsVHJhbnNsYXRleCwgeCwgeSwgeik7CisgICAgR0xMb2coImdsVHJhbnNsYXRleCIpIDw8IEdMTG9nRml4ZWQoeCkgPDwgR0xMb2dGaXhlZCh5KSA8PCBHTExvZ0ZpeGVkKHopOworfQorCit2b2lkIEFQSV9FTlRSWShnbFZlcnRleFBvaW50ZXIpKCAgIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcikgeworICAgIENBTExfR0xfQVBJKGdsVmVydGV4UG9pbnRlciwgc2l6ZSwgdHlwZSwgc3RyaWRlLCBwb2ludGVyKTsKKyAgICBHTExvZygiZ2xWZXJ0ZXhQb2ludGVyIikgPDwgc2l6ZSA8PCBHTExvZ0VudW0odHlwZSkgPDwgc3RyaWRlIDw8IHBvaW50ZXI7Cit9CisKK3ZvaWQgQVBJX0VOVFJZKGdsVmlld3BvcnQpKEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0KSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xWaWV3cG9ydCwgeCwgeSwgd2lkdGgsIGhlaWdodCk7CisgICAgR0xMb2coImdsVmlld3BvcnQiKSA8PCB4IDw8IHkgPDwgd2lkdGggPDwgaGVpZ2h0OworfQorCisvLyBFUyAxLjEKK3ZvaWQgQVBJX0VOVFJZKGdsQ2xpcFBsYW5lZikoR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZsb2F0ICplcXVhdGlvbikgeworICAgIENBTExfR0xfQVBJKGdsQ2xpcFBsYW5lZiwgcGxhbmUsIGVxdWF0aW9uKTsKKyAgICBHTExvZygiZ2xDbGlwUGxhbmVmIikgPDwgR0xMb2dFbnVtKHBsYW5lKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0PihlcXVhdGlvbiwgNCk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbENsaXBQbGFuZXgpKEdMZW51bSBwbGFuZSwgY29uc3QgR0xmaXhlZCAqZXF1YXRpb24pIHsKKyAgICBDQUxMX0dMX0FQSShnbENsaXBQbGFuZXgsIHBsYW5lLCBlcXVhdGlvbik7CisgICAgR0xMb2coImdsQ2xpcFBsYW5leCIpIDw8IEdMTG9nRW51bShwbGFuZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4oZXF1YXRpb24sIDQpOworfQordm9pZCBBUElfRU5UUlkoZ2xCaW5kQnVmZmVyKShHTGVudW0gdGFyZ2V0LCBHTHVpbnQgYnVmZmVyKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xCaW5kQnVmZmVyLCB0YXJnZXQsIGJ1ZmZlcik7CisgICAgR0xMb2coImdsQmluZEJ1ZmZlciIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IGJ1ZmZlcjsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsQnVmZmVyRGF0YSkoR0xlbnVtIHRhcmdldCwgR0xzaXplaXB0ciBzaXplLCBjb25zdCBHTHZvaWQqIGRhdGEsIEdMZW51bSB1c2FnZSkgeworICAgIENBTExfR0xfQVBJKGdsQnVmZmVyRGF0YSwgdGFyZ2V0LCBzaXplLCBkYXRhLCB1c2FnZSk7CisgICAgR0xMb2coImdsQnVmZmVyRGF0YSIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IHNpemUKKyAgICAgICAgPDwgR0xMb2dCdWZmZXI8dW5zaWduZWQgY2hhcj4oc3RhdGljX2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGRhdGEpLCBzaXplKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsQnVmZmVyU3ViRGF0YSkoR0xlbnVtIHRhcmdldCwgR0xpbnRwdHIgb2Zmc2V0LCBHTHNpemVpcHRyIHNpemUsIGNvbnN0IEdMdm9pZCogZGF0YSkgeworICAgIENBTExfR0xfQVBJKGdsQnVmZmVyU3ViRGF0YSwgdGFyZ2V0LCBvZmZzZXQsIHNpemUsIGRhdGEpOworICAgIEdMTG9nKCJnbEJ1ZmZlclN1YkRhdGEiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBvZmZzZXQgPDwgc2l6ZQorICAgICAgICA8PCBHTExvZ0J1ZmZlcjx1bnNpZ25lZCBjaGFyPihzdGF0aWNfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oZGF0YSksIHNpemUpOworfQordm9pZCBBUElfRU5UUlkoZ2xEZWxldGVCdWZmZXJzKShHTHNpemVpIG4sIGNvbnN0IEdMdWludCogYnVmZmVycykgeworICAgIENBTExfR0xfQVBJKGdsRGVsZXRlQnVmZmVycywgbiwgYnVmZmVycyk7CisgICAgR0xMb2coImdsRGVsZXRlQnVmZmVycyIpIDw8IG4gPDwgR0xMb2dCdWZmZXI8R0x1aW50PihidWZmZXJzLCBuKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2VuQnVmZmVycykoR0xzaXplaSBuLCBHTHVpbnQqIGJ1ZmZlcnMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdlbkJ1ZmZlcnMsIG4sIGJ1ZmZlcnMpOworICAgIEdMTG9nKCJnbEdlbkJ1ZmZlcnMiKSA8PCBuIDw8IEdMTG9nQnVmZmVyPEdMdWludD4oYnVmZmVycywgbik7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldEJvb2xlYW52KShHTGVudW0gcG5hbWUsIEdMYm9vbGVhbiAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRCb29sZWFudiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRCb29sZWFudiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xib29sZWFuPihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRGaXhlZHYpKEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRGaXhlZHYsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsR2V0Rml4ZWR2IikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZpeGVkPihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRGbG9hdHYpKEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRGbG9hdHYsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsR2V0RmxvYXR2IikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0PihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRQb2ludGVydikoR0xlbnVtIHBuYW1lLCB2b2lkICoqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRQb2ludGVydiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRQb2ludGVydiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8dm9pZCo+KHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldEJ1ZmZlclBhcmFtZXRlcml2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMpIHsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIENBTExfR0xfQVBJKGdsR2V0QnVmZmVyUGFyYW1ldGVyaXYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7CisgICAgR0xMb2coImdsR2V0QnVmZmVyUGFyYW1ldGVyaXYiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMaW50PihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRDbGlwUGxhbmVmKShHTGVudW0gcG5hbWUsIEdMZmxvYXQgZXFuWzRdKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRDbGlwUGxhbmVmLCBwbmFtZSwgZXFuKTsKKyAgICBHTExvZygiZ2xHZXRDbGlwUGxhbmVmIikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0PihlcW4sIDQpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRDbGlwUGxhbmV4KShHTGVudW0gcG5hbWUsIEdMZml4ZWQgZXFuWzRdKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRDbGlwUGxhbmV4LCBwbmFtZSwgZXFuKTsKKyAgICBHTExvZygiZ2xHZXRDbGlwUGxhbmV4IikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZpeGVkPihlcW4sIDQpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRMaWdodHh2KShHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRMaWdodHh2LCBsaWdodCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRMaWdodHh2IikgPDwgR0xMb2dFbnVtKGxpZ2h0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMZml4ZWQ+KHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldExpZ2h0ZnYpKEdMZW51bSBsaWdodCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldExpZ2h0ZnYsIGxpZ2h0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbEdldExpZ2h0ZnYiKSA8PCBHTExvZ0VudW0obGlnaHQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0TWF0ZXJpYWx4dikoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRNYXRlcmlhbHh2LCBmYWNlLCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbEdldE1hdGVyaWFseHYiKSA8PCBHTExvZ0VudW0oZmFjZSkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZpeGVkPihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRNYXRlcmlhbGZ2KShHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbEdldE1hdGVyaWFsZnYsIGZhY2UsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsR2V0TWF0ZXJpYWxmdiIpIDw8IEdMTG9nRW51bShmYWNlKSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMZmxvYXQ+KHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldFRleEVudmZ2KShHTGVudW0gZW52LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0VGV4RW52ZnYsIGVudiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRUZXhFbnZmdiIpIDw8IEdMTG9nRW51bShlbnYpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4RW52aXYpKEdMZW51bSBlbnYsIEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0VGV4RW52aXYsIGVudiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRUZXhFbnZpdiIpIDw8IEdMTG9nRW51bShlbnYpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xpbnQ+KHBhcmFtcyk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbEdldFRleEVudnh2KShHTGVudW0gZW52LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsR2V0VGV4RW52eHYsIGVudiwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xHZXRUZXhFbnZ4diIpIDw8IEdMTG9nRW51bShlbnYpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4UGFyYW1ldGVyZnYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhQYXJhbWV0ZXJmdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbEdldFRleFBhcmFtZXRlcmZ2IikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0PihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xHZXRUZXhQYXJhbWV0ZXJpdikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGludCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhQYXJhbWV0ZXJpdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbEdldFRleFBhcmFtZXRlcml2IikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGludD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsR2V0VGV4UGFyYW1ldGVyeHYpKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xHZXRUZXhQYXJhbWV0ZXJ4diwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbEdldFRleFBhcmFtZXRlcnh2IikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZpeGVkPihwYXJhbXMpOworfQorR0xib29sZWFuIEFQSV9FTlRSWShnbElzQnVmZmVyKShHTHVpbnQgYnVmZmVyKSB7CisgICAgR0xMb2coImdsSXNCdWZmZXIiKSA8PCBidWZmZXI7CisgICAgQ0FMTF9HTF9BUElfUkVUVVJOKGdsSXNCdWZmZXIsIGJ1ZmZlcik7Cit9CitHTGJvb2xlYW4gQVBJX0VOVFJZKGdsSXNFbmFibGVkKShHTGVudW0gY2FwKSB7CisgICAgR0xMb2coImdsSXNFbmFibGVkIikgPDwgR0xMb2dFbnVtKGNhcCk7CisgICAgQ0FMTF9HTF9BUElfUkVUVVJOKGdsSXNFbmFibGVkLCBjYXApOworfQorR0xib29sZWFuIEFQSV9FTlRSWShnbElzVGV4dHVyZSkoR0x1aW50IHRleHR1cmUpIHsKKyAgICBHTExvZygiZ2xJc1RleHR1cmUiKSA8PCB0ZXh0dXJlOworICAgIENBTExfR0xfQVBJX1JFVFVSTihnbElzVGV4dHVyZSwgdGV4dHVyZSk7Cit9Cit2b2lkIEFQSV9FTlRSWShnbFBvaW50UGFyYW1ldGVyZikoR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xQb2ludFBhcmFtZXRlcmYsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsUG9pbnRQYXJhbWV0ZXJmIikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBwYXJhbTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRQYXJhbWV0ZXJmdikoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50UGFyYW1ldGVyZnYsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsUG9pbnRQYXJhbWV0ZXJmdiIpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRQYXJhbWV0ZXJ4KShHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50UGFyYW1ldGVyeCwgcG5hbWUsIHBhcmFtKTsKKyAgICBHTExvZygiZ2xQb2ludFBhcmFtZXRlcngiKSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nRml4ZWQocGFyYW0pOworfQordm9pZCBBUElfRU5UUlkoZ2xQb2ludFBhcmFtZXRlcnh2KShHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsUG9pbnRQYXJhbWV0ZXJ4diwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xQb2ludFBhcmFtZXRlcnh2IikgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGZpeGVkPihwYXJhbXMpOworfQordm9pZCBBUElfRU5UUlkoZ2xDb2xvcjR1YikoR0x1Ynl0ZSByZWQsIEdMdWJ5dGUgZ3JlZW4sIEdMdWJ5dGUgYmx1ZSwgR0x1Ynl0ZSBhbHBoYSkgeworICAgIENBTExfR0xfQVBJKGdsQ29sb3I0dWIsIHJlZCwgZ3JlZW4sIGJsdWUsIGFscGhhKTsKKyAgICBHTExvZygiZ2xDb2xvcjR1YiIpIDw8IHJlZCA8PCBncmVlbiA8PCBibHVlIDw8IGFscGhhOworfQordm9pZCBBUElfRU5UUlkoZ2xUZXhFbnZpKShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhFbnZpLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsVGV4RW52aSIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgcGFyYW07Cit9Cit2b2lkIEFQSV9FTlRSWShnbFRleEVudml2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMaW50ICpwYXJhbXMpIHsKKyAgICBDQUxMX0dMX0FQSShnbFRleEVudml2LCB0YXJnZXQsIHBuYW1lLCBwYXJhbXMpOworICAgIC8vIFhYWDogd2UgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoaXMgYnVmZmVyCisgICAgR0xMb2coImdsVGV4RW52aXYiKSA8PCBHTExvZ0VudW0odGFyZ2V0KSA8PCBHTExvZ0VudW0ocG5hbWUpIDw8IEdMTG9nQnVmZmVyPEdMaW50PihwYXJhbXMpOworfQorCit2b2lkIEFQSV9FTlRSWShnbFRleFBhcmFtZXRlcmZ2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsVGV4UGFyYW1ldGVyZnYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xUZXhQYXJhbWV0ZXJmdiIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmbG9hdD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhQYXJhbWV0ZXJpdikoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCAqcGFyYW1zKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJpdiwgdGFyZ2V0LCBwbmFtZSwgcGFyYW1zKTsKKyAgICAvLyBYWFg6IHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGlzIGJ1ZmZlcgorICAgIEdMTG9nKCJnbFRleFBhcmFtZXRlcml2IikgPDwgR0xMb2dFbnVtKHRhcmdldCkgPDwgR0xMb2dFbnVtKHBuYW1lKSA8PCBHTExvZ0J1ZmZlcjxHTGludD4ocGFyYW1zKTsKK30KKwordm9pZCBBUElfRU5UUlkoZ2xUZXhQYXJhbWV0ZXJpKShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xUZXhQYXJhbWV0ZXJpLCB0YXJnZXQsIHBuYW1lLCBwYXJhbSk7CisgICAgR0xMb2coImdsVGV4UGFyYW1ldGVyaSIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgcGFyYW07Cit9Cit2b2lkIEFQSV9FTlRSWShnbFRleFBhcmFtZXRlcnh2KShHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcykgeworICAgIENBTExfR0xfQVBJKGdsVGV4UGFyYW1ldGVyeHYsIHRhcmdldCwgcG5hbWUsIHBhcmFtcyk7CisgICAgLy8gWFhYOiB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgdGhpcyBidWZmZXIKKyAgICBHTExvZygiZ2xUZXhQYXJhbWV0ZXJ4diIpIDw8IEdMTG9nRW51bSh0YXJnZXQpIDw8IEdMTG9nRW51bShwbmFtZSkgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4ocGFyYW1zKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsUG9pbnRTaXplUG9pbnRlck9FUykoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpIHsKKyAgICBDQUxMX0dMX0FQSShnbFBvaW50U2l6ZVBvaW50ZXJPRVMsIHR5cGUsIHN0cmlkZSwgcG9pbnRlcik7CisgICAgR0xMb2coImdsUG9pbnRTaXplUG9pbnRlck9FUyIpIDw8IEdMTG9nRW51bSh0eXBlKSA8PCBzdHJpZGUgPDwgcG9pbnRlcjsKK30KKworLy8gRXh0ZW5zaW9ucwordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4c09FUykoR0xzaG9ydCB4ICwgR0xzaG9ydCB5LCBHTHNob3J0IHosIEdMc2hvcnQgdywgR0xzaG9ydCBoKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEcmF3VGV4c09FUywgeCwgeSwgeiwgdywgaCk7CisgICAgR0xMb2coImdsRHJhd1RleHNPRVMiKSA8PCB4IDw8IHkgPDwgeiA8PCB3IDw8IGg7Cit9Cit2b2lkIEFQSV9FTlRSWShnbERyYXdUZXhpT0VTKShHTGludCB4LCBHTGludCB5LCBHTGludCB6LCBHTGludCB3LCBHTGludCBoKSB7CisgICAgQ0FMTF9HTF9BUEkoZ2xEcmF3VGV4aU9FUywgeCwgeSwgeiwgdywgaCk7CisgICAgR0xMb2coImdsRHJhd1RleGlPRVMiKSA8PCB4IDw8IHkgPDwgeiA8PCB3IDw8IGg7Cit9Cit2b2lkIEFQSV9FTlRSWShnbERyYXdUZXhmT0VTKShHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6LCBHTGZsb2F0IHcsIEdMZmxvYXQgaCkgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleGZPRVMsIHgsIHksIHosIHcsIGgpOworICAgIEdMTG9nKCJnbERyYXdUZXhmT0VTIikgPDwgeCA8PCB5IDw8IHogPDwgdyA8PCBoOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4eE9FUykoR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeiwgR0xmaXhlZCB3LCBHTGZpeGVkIGgpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdUZXh4T0VTLCB4LCB5LCB6LCB3LCBoKTsKKyAgICBHTExvZygiZ2xEcmF3VGV4Zk9FUyIpIDw8IEdMTG9nRml4ZWQoeCkgPDwgR0xMb2dGaXhlZCh5KSA8PCBHTExvZ0ZpeGVkKHopIDw8IEdMTG9nRml4ZWQodykgPDwgR0xMb2dGaXhlZChoKTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd1RleHN2T0VTKShjb25zdCBHTHNob3J0KiBjb29yZHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdUZXhzdk9FUywgY29vcmRzKTsKKyAgICBHTExvZygiZ2xEcmF3VGV4c3ZPRVMiKSA8PCBHTExvZ0J1ZmZlcjxHTHNob3J0Pihjb29yZHMsIDUpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4aXZPRVMpKGNvbnN0IEdMaW50KiBjb29yZHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdUZXhpdk9FUywgY29vcmRzKTsKKyAgICBHTExvZygiZ2xEcmF3VGV4aXZPRVMiKSA8PCBHTExvZ0J1ZmZlcjxHTGludD4oY29vcmRzLCA1KTsKK30KK3ZvaWQgQVBJX0VOVFJZKGdsRHJhd1RleGZ2T0VTKShjb25zdCBHTGZsb2F0KiBjb29yZHMpIHsKKyAgICBDQUxMX0dMX0FQSShnbERyYXdUZXhmdk9FUywgY29vcmRzKTsKKyAgICBHTExvZygiZ2xEcmF3VGV4ZnZPRVMiKSA8PCBHTExvZ0J1ZmZlcjxHTGZsb2F0Pihjb29yZHMsIDUpOworfQordm9pZCBBUElfRU5UUlkoZ2xEcmF3VGV4eHZPRVMpKGNvbnN0IEdMZml4ZWQqIGNvb3JkcykgeworICAgIENBTExfR0xfQVBJKGdsRHJhd1RleHh2T0VTLCBjb29yZHMpOworICAgIEdMTG9nKCJnbERyYXdUZXh4dk9FUyIpIDw8IEdMTG9nQnVmZmVyPEdMZml4ZWQ+KGNvb3JkcywgNSk7Cit9CitHTGJpdGZpZWxkIEFQSV9FTlRSWShnbFF1ZXJ5TWF0cml4eE9FUykoR0xmaXhlZCogbWFudGlzc2EsIEdMaW50KiBleHBvbmVudCkgeworICAgIEdMTG9nKCJnbFF1ZXJ5TWF0cml4eE9FUyIpIDw8IEdMTG9nQnVmZmVyPEdMZml4ZWQ+KG1hbnRpc3NhLCAxNikgPDwgR0xMb2dCdWZmZXI8R0xmaXhlZD4oZXhwb25lbnQsIDE2KTsKKyAgICBDQUxMX0dMX0FQSV9SRVRVUk4oZ2xRdWVyeU1hdHJpeHhPRVMsIG1hbnRpc3NhLCBleHBvbmVudCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9lZ2xfZW50cmllcy5pbiBiL29wZW5nbC9saWJzL2VnbF9lbnRyaWVzLmluCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzYjRjNjUKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9lZ2xfZW50cmllcy5pbgpAQCAtMCwwICsxLDQ1IEBACitFR0xfRU5UUlkoRUdMRGlzcGxheSwgZWdsR2V0RGlzcGxheSwgTmF0aXZlRGlzcGxheVR5cGUpCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsSW5pdGlhbGl6ZSwgRUdMRGlzcGxheSwgRUdMaW50KiwgRUdMaW50KikKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xUZXJtaW5hdGUsIEVHTERpc3BsYXkpCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsR2V0Q29uZmlncywgRUdMRGlzcGxheSwgRUdMQ29uZmlnKiwgRUdMaW50LCBFR0xpbnQqKQorRUdMX0VOVFJZKEVHTEJvb2xlYW4sIGVnbENob29zZUNvbmZpZywgRUdMRGlzcGxheSwgY29uc3QgRUdMaW50ICosIEVHTENvbmZpZyAqLCBFR0xpbnQsIEVHTGludCAqKQorCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsR2V0Q29uZmlnQXR0cmliLCBFR0xEaXNwbGF5LCBFR0xDb25maWcsIEVHTGludCwgRUdMaW50ICopCitFR0xfRU5UUlkoRUdMU3VyZmFjZSwgZWdsQ3JlYXRlV2luZG93U3VyZmFjZSwgRUdMRGlzcGxheSwgRUdMQ29uZmlnLCBOYXRpdmVXaW5kb3dUeXBlLCBjb25zdCBFR0xpbnQgKikKK0VHTF9FTlRSWShFR0xTdXJmYWNlLCBlZ2xDcmVhdGVQaXhtYXBTdXJmYWNlLCBFR0xEaXNwbGF5LCBFR0xDb25maWcsIE5hdGl2ZVBpeG1hcFR5cGUsIGNvbnN0IEVHTGludCAqKQorRUdMX0VOVFJZKEVHTFN1cmZhY2UsIGVnbENyZWF0ZVBidWZmZXJTdXJmYWNlLCAgRUdMRGlzcGxheSwgRUdMQ29uZmlnLCBjb25zdCBFR0xpbnQgKikKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xEZXN0cm95U3VyZmFjZSwgRUdMRGlzcGxheSwgRUdMU3VyZmFjZSkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xRdWVyeVN1cmZhY2UsICBFR0xEaXNwbGF5LCBFR0xTdXJmYWNlLCBFR0xpbnQsIEVHTGludCAqKQorRUdMX0VOVFJZKEVHTENvbnRleHQsIGVnbENyZWF0ZUNvbnRleHQsIEVHTERpc3BsYXksIEVHTENvbmZpZywgRUdMQ29udGV4dCwgY29uc3QgRUdMaW50ICopCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsRGVzdHJveUNvbnRleHQsIEVHTERpc3BsYXksIEVHTENvbnRleHQpCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsTWFrZUN1cnJlbnQsIEVHTERpc3BsYXksIEVHTFN1cmZhY2UsIEVHTFN1cmZhY2UsIEVHTENvbnRleHQpCitFR0xfRU5UUlkoRUdMQ29udGV4dCwgZWdsR2V0Q3VycmVudENvbnRleHQsIHZvaWQpCitFR0xfRU5UUlkoRUdMU3VyZmFjZSwgZWdsR2V0Q3VycmVudFN1cmZhY2UsIEVHTGludCkKK0VHTF9FTlRSWShFR0xEaXNwbGF5LCBlZ2xHZXRDdXJyZW50RGlzcGxheSwgdm9pZCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xRdWVyeUNvbnRleHQsICBFR0xEaXNwbGF5LCBFR0xDb250ZXh0LCBFR0xpbnQsIEVHTGludCAqKQorRUdMX0VOVFJZKEVHTEJvb2xlYW4sIGVnbFdhaXRHTCwgdm9pZCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xXYWl0TmF0aXZlLCBFR0xpbnQpCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsU3dhcEJ1ZmZlcnMsIEVHTERpc3BsYXksIEVHTFN1cmZhY2UpCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsQ29weUJ1ZmZlcnMsIEVHTERpc3BsYXksIEVHTFN1cmZhY2UsIE5hdGl2ZVBpeG1hcFR5cGUpCitFR0xfRU5UUlkoRUdMaW50LCBlZ2xHZXRFcnJvciwgdm9pZCkKK0VHTF9FTlRSWShjb25zdCBjaGFyKiwgZWdsUXVlcnlTdHJpbmcsIEVHTERpc3BsYXksIEVHTGludCkKK0VHTF9FTlRSWShfX2VnbE11c3RDYXN0VG9Qcm9wZXJGdW5jdGlvblBvaW50ZXJUeXBlLCBlZ2xHZXRQcm9jQWRkcmVzcywgY29uc3QgY2hhciAqKQorCisvKiBFR0wgMS4xICovCisKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xTdXJmYWNlQXR0cmliLCBFR0xEaXNwbGF5LCBFR0xTdXJmYWNlLCBFR0xpbnQsIEVHTGludCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xCaW5kVGV4SW1hZ2UsIEVHTERpc3BsYXksIEVHTFN1cmZhY2UsIEVHTGludCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xSZWxlYXNlVGV4SW1hZ2UsIEVHTERpc3BsYXksIEVHTFN1cmZhY2UsIEVHTGludCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xTd2FwSW50ZXJ2YWwsIEVHTERpc3BsYXksIEVHTGludCkKKworLyogRUdMIDEuMiAqLworCitFR0xfRU5UUlkoRUdMQm9vbGVhbiwgZWdsQmluZEFQSSwgRUdMZW51bSkKK0VHTF9FTlRSWShFR0xlbnVtLCBlZ2xRdWVyeUFQSSwgdm9pZCkKK0VHTF9FTlRSWShFR0xCb29sZWFuLCBlZ2xXYWl0Q2xpZW50LCB2b2lkKQorRUdMX0VOVFJZKEVHTEJvb2xlYW4sIGVnbFJlbGVhc2VUaHJlYWQsIHZvaWQpCitFR0xfRU5UUlkoRUdMU3VyZmFjZSwgZWdsQ3JlYXRlUGJ1ZmZlckZyb21DbGllbnRCdWZmZXIsIEVHTERpc3BsYXksIEVHTGVudW0sIEVHTENsaWVudEJ1ZmZlciwgRUdMQ29uZmlnLCBjb25zdCBFR0xpbnQgKikKKworLyogRUdMIDEuMyAqLworCisvKiBFR0wgMS40ICovCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9lZ2xfaW1wbC5oIGIvb3BlbmdsL2xpYnMvZWdsX2ltcGwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmNlM2ZjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYnMvZWdsX2ltcGwuaApAQCAtMCwwICsxLDQzIEBACisvKiAKKyAqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoqCisgKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorICoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisgKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorICoqCisgKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyAqKgorICoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisgKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisgKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorICoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisgKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBTkRST0lEX0VHTF9JTVBMX0gKKyNkZWZpbmUgQU5EUk9JRF9FR0xfSU1QTF9ICisKKyNpbmNsdWRlIDxjdHlwZS5oPgorCisjaW5jbHVkZSA8RUdML2VnbC5oPgorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCituYW1lc3BhY2UgYW5kcm9pZCB7CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cnVjdCBnbF9ob29rc190OworCitzdHJ1Y3QgZWdsX2Nvbm5lY3Rpb25fdAoreworICAgIHZvaWQgdm9sYXRpbGUgKiAgICAgZHNvOworICAgIGdsX2hvb2tzX3QgKiAgICAgICAgaG9va3M7CisgICAgRUdMaW50ICAgICAgICAgICAgICBtYWpvcjsKKyAgICBFR0xpbnQgICAgICAgICAgICAgIG1pbm9yOworICAgIGludCAgICAgICAgICAgICAgICAgdW5hdmFpbGFibGU7Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjZW5kaWYgLyogQU5EUk9JRF9FR0xfSU1QTF9IICovCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9nbF9lbnRyaWVzLmluIGIvb3BlbmdsL2xpYnMvZ2xfZW50cmllcy5pbgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTdlOGZlCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYnMvZ2xfZW50cmllcy5pbgpAQCAtMCwwICsxLDE1OSBAQAorR0xfRU5UUlkodm9pZCwgZ2xDb2xvcjRmLCBHTGZsb2F0LCBHTGZsb2F0LCBHTGZsb2F0LCBHTGZsb2F0KQorR0xfRU5UUlkodm9pZCwgZ2xDb2xvcjR4LCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xOb3JtYWwzZiwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsTm9ybWFsM3gsIEdMZml4ZWQsIEdMZml4ZWQsIEdMZml4ZWQpCitHTF9FTlRSWSh2b2lkLCBnbEN1bGxGYWNlLCBHTGVudW0pCitHTF9FTlRSWSh2b2lkLCBnbEZyb250RmFjZSwgR0xlbnVtKQorR0xfRU5UUlkodm9pZCwgZ2xEaXNhYmxlLCBHTGVudW0pCitHTF9FTlRSWSh2b2lkLCBnbEVuYWJsZSwgR0xlbnVtKQorR0xfRU5UUlkodm9pZCwgZ2xGaW5pc2gsIHZvaWQpCitHTF9FTlRSWSh2b2lkLCBnbEZsdXNoLCB2b2lkKQorR0xfRU5UUlkoR0xlbnVtLCBnbEdldEVycm9yLCB2b2lkKQorR0xfRU5UUlkoY29uc3QgR0x1Ynl0ZSosIGdsR2V0U3RyaW5nLCBHTGVudW0pCitHTF9FTlRSWSh2b2lkLCBnbEdldEludGVnZXJ2LCBHTGVudW0sIEdMaW50ICopCitHTF9FTlRSWSh2b2lkLCBnbENvbG9yTWFzaywgR0xib29sZWFuLCBHTGJvb2xlYW4sIEdMYm9vbGVhbiwgR0xib29sZWFuKQorR0xfRU5UUlkodm9pZCwgZ2xEZXB0aE1hc2ssIEdMYm9vbGVhbikKK0dMX0VOVFJZKHZvaWQsIGdsU3RlbmNpbE1hc2ssIEdMdWludCkKK0dMX0VOVFJZKHZvaWQsIGdsRGVwdGhGdW5jLCBHTGVudW0pCitHTF9FTlRSWSh2b2lkLCBnbERlcHRoUmFuZ2VmLCBHTGNsYW1wZiB6TmVhciwgR0xjbGFtcGYgekZhcikKK0dMX0VOVFJZKHZvaWQsIGdsRGVwdGhSYW5nZXgsIEdMY2xhbXB4IHpOZWFyLCBHTGNsYW1weCB6RmFyKQorR0xfRU5UUlkodm9pZCwgZ2xQb2x5Z29uT2Zmc2V0LCBHTGZsb2F0IGZhY3RvciwgR0xmbG9hdCB1bml0cykKK0dMX0VOVFJZKHZvaWQsIGdsUG9seWdvbk9mZnNldHgsIEdMZml4ZWQgZmFjdG9yLCBHTGZpeGVkIHVuaXRzKQorR0xfRU5UUlkodm9pZCwgZ2xMb2dpY09wLCBHTGVudW0gb3Bjb2RlKQorR0xfRU5UUlkodm9pZCwgZ2xBbHBoYUZ1bmN4LCBHTGVudW0gZnVuYywgR0xjbGFtcHggcmVmKQorR0xfRU5UUlkodm9pZCwgZ2xBbHBoYUZ1bmMsIEdMZW51bSBmdW5jLCBHTGNsYW1wZiByZWYpCitHTF9FTlRSWSh2b2lkLCBnbEJsZW5kRnVuYywgR0xlbnVtIHNmYWN0b3IsIEdMZW51bSBkZmFjdG9yKQorR0xfRU5UUlkodm9pZCwgZ2xDbGVhciwgR0xiaXRmaWVsZCBtYXNrKQorR0xfRU5UUlkodm9pZCwgZ2xDbGVhckNvbG9yLCBHTGNsYW1wZiByLCBHTGNsYW1wZiBnLCBHTGNsYW1wZiBiLCBHTGNsYW1wZiBhKQorR0xfRU5UUlkodm9pZCwgZ2xDbGVhckNvbG9yeCwgR0xjbGFtcHggciwgR0xjbGFtcHggZywgR0xjbGFtcHggYiwgR0xjbGFtcHggYSkKK0dMX0VOVFJZKHZvaWQsIGdsQ2xlYXJEZXB0aGYsIEdMY2xhbXBmIGRlcHRoKQorR0xfRU5UUlkodm9pZCwgZ2xDbGVhckRlcHRoeCwgR0xjbGFtcHggZGVwdGgpCitHTF9FTlRSWSh2b2lkLCBnbENsZWFyU3RlbmNpbCwgR0xpbnQgcykKK0dMX0VOVFJZKHZvaWQsIGdsUG9pbnRTaXplLCBHTGZsb2F0KQorR0xfRU5UUlkodm9pZCwgZ2xQb2ludFNpemV4LCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xTYW1wbGVDb3ZlcmFnZSwgR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpCitHTF9FTlRSWSh2b2lkLCBnbFNhbXBsZUNvdmVyYWdleCwgR0xjbGFtcHggdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpCitHTF9FTlRSWSh2b2lkLCBnbFN0ZW5jaWxGdW5jLCBHTGVudW0gZnVuYywgR0xpbnQgcmVmLCBHTHVpbnQgbWFzaykKK0dMX0VOVFJZKHZvaWQsIGdsU3RlbmNpbE9wLCBHTGVudW0gZmFpbCwgR0xlbnVtIHpmYWlsLCBHTGVudW0genBhc3MpCitHTF9FTlRSWSh2b2lkLCBnbFNjaXNzb3IsIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0KQorR0xfRU5UUlkodm9pZCwgZ2xIaW50LCBHTGVudW0sIEdMZW51bSBtb2RlKQorR0xfRU5UUlkodm9pZCwgZ2xMaW5lV2lkdGgsIEdMZmxvYXQgd2lkdGgpCitHTF9FTlRSWSh2b2lkLCBnbExpbmVXaWR0aHgsIEdMZml4ZWQgd2lkdGgpCitHTF9FTlRSWSh2b2lkLCBnbFNoYWRlTW9kZWwsIEdMZW51bSkKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRNb2RlbGYsIEdMZW51bSwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRNb2RlbGZ2LCBHTGVudW0sIGNvbnN0IEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRNb2RlbHgsIEdMZW51bSwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRNb2RlbHh2LCBHTGVudW0sIGNvbnN0IEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRmLCBHTGVudW0sIEdMZW51bSwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHRmdiwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHR4LCBHTGVudW0sIEdMZW51bSwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsTGlnaHR4diwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTWF0ZXJpYWxmLCBHTGVudW0sIEdMZW51bSwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsTWF0ZXJpYWxmdiwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTWF0ZXJpYWx4LCBHTGVudW0sIEdMZW51bSwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsTWF0ZXJpYWx4diwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsRm9nZiwgR0xlbnVtLCBHTGZsb2F0KQorR0xfRU5UUlkodm9pZCwgZ2xGb2dmdiwgR0xlbnVtLCBjb25zdCBHTGZsb2F0ICopCitHTF9FTlRSWSh2b2lkLCBnbEZvZ3gsIEdMZW51bSwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsRm9neHYsIEdMZW51bSwgY29uc3QgR0xmaXhlZCAqKQorR0xfRU5UUlkodm9pZCwgZ2xWZXJ0ZXhQb2ludGVyLCBHTGludCwgR0xlbnVtLCBHTHNpemVpLCBjb25zdCBHTHZvaWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsQ29sb3JQb2ludGVyLCBHTGludCwgR0xlbnVtLCBHTHNpemVpLCBjb25zdCBHTHZvaWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTm9ybWFsUG9pbnRlciwgR0xlbnVtLCBHTHNpemVpLCBjb25zdCBHTHZvaWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsVGV4Q29vcmRQb2ludGVyLCBHTGludCwgR0xlbnVtLCBHTHNpemVpLCBjb25zdCBHTHZvaWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsRW5hYmxlQ2xpZW50U3RhdGUsIEdMZW51bSkKK0dMX0VOVFJZKHZvaWQsIGdsRGlzYWJsZUNsaWVudFN0YXRlLCBHTGVudW0pCitHTF9FTlRSWSh2b2lkLCBnbENsaWVudEFjdGl2ZVRleHR1cmUsIEdMZW51bSkKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd0FycmF5cywgR0xlbnVtLCBHTGludCBmaXJzdCwgR0xzaXplaSkKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd0VsZW1lbnRzLCBHTGVudW0sIEdMc2l6ZWksIEdMZW51bSwgY29uc3QgR0x2b2lkICopCitHTF9FTlRSWSh2b2lkLCBnbExvYWRJZGVudGl0eSwgdm9pZCkKK0dMX0VOVFJZKHZvaWQsIGdsTG9hZE1hdHJpeGYsIGNvbnN0IEdMZmxvYXQqKQorR0xfRU5UUlkodm9pZCwgZ2xMb2FkTWF0cml4eCwgY29uc3QgR0xmaXhlZCopCitHTF9FTlRSWSh2b2lkLCBnbE1hdHJpeE1vZGUsIEdMZW51bSBtb2RlKQorR0xfRU5UUlkodm9pZCwgZ2xNdWx0TWF0cml4ZiwgY29uc3QgR0xmbG9hdCopCitHTF9FTlRSWSh2b2lkLCBnbE11bHRNYXRyaXh4LCBjb25zdCBHTGZpeGVkKikKK0dMX0VOVFJZKHZvaWQsIGdsUG9wTWF0cml4LCB2b2lkKQorR0xfRU5UUlkodm9pZCwgZ2xQdXNoTWF0cml4LCB2b2lkKQorR0xfRU5UUlkodm9pZCwgZ2xGcnVzdHVtZiwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsRnJ1c3R1bXgsIEdMZml4ZWQsIEdMZml4ZWQsIEdMZml4ZWQsIEdMZml4ZWQsIEdMZml4ZWQsIEdMZml4ZWQpCitHTF9FTlRSWSh2b2lkLCBnbE9ydGhvZiwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsT3J0aG94LCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xSb3RhdGVmLCBHTGZsb2F0LCBHTGZsb2F0LCBHTGZsb2F0LCBHTGZsb2F0KQorR0xfRU5UUlkodm9pZCwgZ2xSb3RhdGV4LCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xTY2FsZWYsIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQpCitHTF9FTlRSWSh2b2lkLCBnbFNjYWxleCwgR0xmaXhlZCwgR0xmaXhlZCwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsVHJhbnNsYXRlZiwgR0xmbG9hdCwgR0xmbG9hdCwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsVHJhbnNsYXRleCwgR0xmaXhlZCwgR0xmaXhlZCwgR0xmaXhlZCkKK0dMX0VOVFJZKHZvaWQsIGdsVmlld3BvcnQsIEdMaW50LCBHTGludCwgR0xzaXplaSwgR0xzaXplaSkKK0dMX0VOVFJZKHZvaWQsIGdsQWN0aXZlVGV4dHVyZSwgR0xlbnVtKQorR0xfRU5UUlkodm9pZCwgZ2xCaW5kVGV4dHVyZSwgR0xlbnVtLCBHTHVpbnQpCitHTF9FTlRSWSh2b2lkLCBnbEdlblRleHR1cmVzLCBHTHNpemVpLCBHTHVpbnQqKQorR0xfRU5UUlkodm9pZCwgZ2xEZWxldGVUZXh0dXJlcywgR0xzaXplaSBuLCBjb25zdCBHTHVpbnQgKikKK0dMX0VOVFJZKHZvaWQsIGdsTXVsdGlUZXhDb29yZDRmLCBHTGVudW0sIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQpCitHTF9FTlRSWSh2b2lkLCBnbE11bHRpVGV4Q29vcmQ0eCwgR0xlbnVtLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xQaXhlbFN0b3JlaSwgR0xlbnVtLCBHTGludCkKK0dMX0VOVFJZKHZvaWQsIGdsVGV4RW52ZiwgR0xlbnVtLCBHTGVudW0sIEdMZmxvYXQpCitHTF9FTlRSWSh2b2lkLCBnbFRleEVudmZ2LCBHTGVudW0sIEdMZW51bSwgY29uc3QgR0xmbG9hdCopCitHTF9FTlRSWSh2b2lkLCBnbFRleEVudngsIEdMZW51bSwgR0xlbnVtLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xUZXhFbnZ4diwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMZml4ZWQqKQorR0xfRU5UUlkodm9pZCwgZ2xUZXhQYXJhbWV0ZXJmLCBHTGVudW0sIEdMZW51bSwgR0xmbG9hdCkKK0dMX0VOVFJZKHZvaWQsIGdsVGV4UGFyYW1ldGVyeCwgR0xlbnVtLCBHTGVudW0sIEdMZml4ZWQpCitHTF9FTlRSWSh2b2lkLCBnbENvbXByZXNzZWRUZXhJbWFnZTJELCAgICBHTGVudW0sIEdMaW50LCBHTGVudW0sIEdMc2l6ZWksIEdMc2l6ZWksIEdMaW50LCBHTHNpemVpLCBjb25zdCBHTHZvaWQqKQorR0xfRU5UUlkodm9pZCwgZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCwgR0xlbnVtLCBHTGludCwgR0xpbnQsIEdMaW50LCBHTHNpemVpLCBHTHNpemVpLCBHTGVudW0sIEdMc2l6ZWksIGNvbnN0IEdMdm9pZCopCitHTF9FTlRSWSh2b2lkLCBnbENvcHlUZXhJbWFnZTJELCBHTGVudW0sIEdMaW50LCBHTGVudW0sIEdMaW50LCBHTGludCwgR0xzaXplaSwgR0xzaXplaSwgR0xpbnQpCitHTF9FTlRSWSh2b2lkLCBnbENvcHlUZXhTdWJJbWFnZTJELCBHTGVudW0sIEdMaW50LCBHTGludCwgR0xpbnQsIEdMaW50LCBHTGludCwgR0xzaXplaSwgR0xzaXplaSkKK0dMX0VOVFJZKHZvaWQsIGdsVGV4SW1hZ2UyRCwgR0xlbnVtLCBHTGludCwgR0xpbnQsIEdMc2l6ZWksIEdMc2l6ZWksIEdMaW50LCBHTGVudW0sIEdMZW51bSwgY29uc3QgR0x2b2lkKikKK0dMX0VOVFJZKHZvaWQsIGdsVGV4U3ViSW1hZ2UyRCwgR0xlbnVtLCBHTGludCwgR0xpbnQsIEdMaW50LCBHTHNpemVpLCBHTHNpemVpLCBHTGVudW0sIEdMZW51bSwgY29uc3QgR0x2b2lkKikKK0dMX0VOVFJZKHZvaWQsIGdsUmVhZFBpeGVscywgR0xpbnQsIEdMaW50LCBHTHNpemVpLCBHTHNpemVpLCBHTGVudW0sIEdMZW51bSwgR0x2b2lkICopCisKKy8vIDEuMSBhZGRpdGlvbnMKK0dMX0VOVFJZKHZvaWQsIGdsQ2xpcFBsYW5lZiwgR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZsb2F0KikKK0dMX0VOVFJZKHZvaWQsIGdsQ2xpcFBsYW5leCwgR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZpeGVkKikKK0dMX0VOVFJZKHZvaWQsIGdsQmluZEJ1ZmZlciwgR0xlbnVtLCBHTHVpbnQpCitHTF9FTlRSWSh2b2lkLCBnbEJ1ZmZlckRhdGEsIEdMZW51bSwgR0xzaXplaXB0ciwgY29uc3QgR0x2b2lkKiwgR0xlbnVtKQorR0xfRU5UUlkodm9pZCwgZ2xCdWZmZXJTdWJEYXRhLCBHTGVudW0sIEdMaW50cHRyLCBHTHNpemVpcHRyLCBjb25zdCBHTHZvaWQqKQorR0xfRU5UUlkodm9pZCwgZ2xEZWxldGVCdWZmZXJzLCBHTHNpemVpLCBjb25zdCBHTHVpbnQqKQorR0xfRU5UUlkodm9pZCwgZ2xHZW5CdWZmZXJzLCBHTHNpemVpLCBHTHVpbnQqKQorR0xfRU5UUlkodm9pZCwgZ2xHZXRCb29sZWFudiwgR0xlbnVtLCBHTGJvb2xlYW4gKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0Rml4ZWR2LCBHTGVudW0sIEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0RmxvYXR2LCBHTGVudW0sIEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0UG9pbnRlcnYsIEdMZW51bSwgdm9pZCAqKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0QnVmZmVyUGFyYW1ldGVyaXYsIEdMZW51bSwgR0xlbnVtLCBHTGludCAqKQorR0xfRU5UUlkodm9pZCwgZ2xHZXRDbGlwUGxhbmVmLCBHTGVudW0sIEdMZmxvYXRbNF0pCitHTF9FTlRSWSh2b2lkLCBnbEdldENsaXBQbGFuZXgsIEdMZW51bSwgR0xmaXhlZFs0XSkKK0dMX0VOVFJZKHZvaWQsIGdsR2V0TGlnaHR4diwgR0xlbnVtLCBHTGVudW0sIEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0TGlnaHRmdiwgR0xlbnVtLCBHTGVudW0sIEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0TWF0ZXJpYWx4diwgR0xlbnVtLCBHTGVudW0sIEdMZml4ZWQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0TWF0ZXJpYWxmdiwgR0xlbnVtLCBHTGVudW0sIEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0VGV4RW52ZnYsIEdMZW51bSwgR0xlbnVtLCBHTGZsb2F0ICopCitHTF9FTlRSWSh2b2lkLCBnbEdldFRleEVudml2LCBHTGVudW0sIEdMZW51bSwgR0xpbnQgKikKK0dMX0VOVFJZKHZvaWQsIGdsR2V0VGV4RW52eHYsIEdMZW51bSwgR0xlbnVtLCBHTGZpeGVkICopCitHTF9FTlRSWSh2b2lkLCBnbEdldFRleFBhcmFtZXRlcmZ2LCBHTGVudW0sIEdMZW51bSwgR0xmbG9hdCAqKQorR0xfRU5UUlkodm9pZCwgZ2xHZXRUZXhQYXJhbWV0ZXJpdiwgR0xlbnVtLCBHTGVudW0sIEdMaW50ICopCitHTF9FTlRSWSh2b2lkLCBnbEdldFRleFBhcmFtZXRlcnh2LCBHTGVudW0sIEdMZW51bSwgR0xmaXhlZCAqKQorR0xfRU5UUlkoR0xib29sZWFuLCBnbElzQnVmZmVyLCBHTHVpbnQpCitHTF9FTlRSWShHTGJvb2xlYW4sIGdsSXNFbmFibGVkLCBHTGVudW0pCitHTF9FTlRSWShHTGJvb2xlYW4sIGdsSXNUZXh0dXJlLCBHTHVpbnQpCitHTF9FTlRSWSh2b2lkLCBnbFBvaW50UGFyYW1ldGVyZiwgR0xlbnVtLCBHTGZsb2F0KQorR0xfRU5UUlkodm9pZCwgZ2xQb2ludFBhcmFtZXRlcmZ2LCBHTGVudW0sIGNvbnN0IEdMZmxvYXQgKikKK0dMX0VOVFJZKHZvaWQsIGdsUG9pbnRQYXJhbWV0ZXJ4LCBHTGVudW0sIEdMZml4ZWQpCitHTF9FTlRSWSh2b2lkLCBnbFBvaW50UGFyYW1ldGVyeHYsIEdMZW51bSwgY29uc3QgR0xmaXhlZCAqKQorR0xfRU5UUlkodm9pZCwgZ2xDb2xvcjR1YiwgR0x1Ynl0ZSwgR0x1Ynl0ZSwgR0x1Ynl0ZSwgR0x1Ynl0ZSkKK0dMX0VOVFJZKHZvaWQsIGdsVGV4RW52aSwgR0xlbnVtLCBHTGVudW0sIEdMaW50KQorR0xfRU5UUlkodm9pZCwgZ2xUZXhFbnZpdiwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMaW50ICopCitHTF9FTlRSWSh2b2lkLCBnbFRleFBhcmFtZXRlcmZ2LCBHTGVudW0sIEdMZW51bSwgY29uc3QgR0xmbG9hdCAqKQorR0xfRU5UUlkodm9pZCwgZ2xUZXhQYXJhbWV0ZXJpdiwgR0xlbnVtLCBHTGVudW0sIGNvbnN0IEdMaW50ICopCitHTF9FTlRSWSh2b2lkLCBnbFRleFBhcmFtZXRlcmksIEdMZW51bSwgR0xlbnVtLCBHTGludCkKK0dMX0VOVFJZKHZvaWQsIGdsVGV4UGFyYW1ldGVyeHYsIEdMZW51bSwgR0xlbnVtLCBjb25zdCBHTGZpeGVkICopCitHTF9FTlRSWSh2b2lkLCBnbFBvaW50U2l6ZVBvaW50ZXJPRVMsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkKikKKworLy8gRXh0ZW5zaW9ucworR0xfRU5UUlkodm9pZCwgZ2xEcmF3VGV4c09FUywgR0xzaG9ydCwgR0xzaG9ydCwgR0xzaG9ydCwgR0xzaG9ydCwgR0xzaG9ydCkKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd1RleGlPRVMsIEdMaW50LCBHTGludCwgR0xpbnQsIEdMaW50LCBHTGludCkKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd1RleGZPRVMsIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQsIEdMZmxvYXQpCitHTF9FTlRSWSh2b2lkLCBnbERyYXdUZXh4T0VTLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkLCBHTGZpeGVkKQorR0xfRU5UUlkodm9pZCwgZ2xEcmF3VGV4c3ZPRVMsIGNvbnN0IEdMc2hvcnQqKQorR0xfRU5UUlkodm9pZCwgZ2xEcmF3VGV4aXZPRVMsIGNvbnN0IEdMaW50KikKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd1RleGZ2T0VTLCBjb25zdCBHTGZsb2F0KikKK0dMX0VOVFJZKHZvaWQsIGdsRHJhd1RleHh2T0VTLCBjb25zdCBHTGZpeGVkKikKK0dMX0VOVFJZKEdMYml0ZmllbGQsIGdsUXVlcnlNYXRyaXh4T0VTLCBHTGZpeGVkKiBtYW50aXNzYSwgR0xpbnQqIGV4cG9uZW50KQorCmRpZmYgLS1naXQgYS9vcGVuZ2wvbGlicy9nbF9lbnVtcy5pbiBiL29wZW5nbC9saWJzL2dsX2VudW1zLmluCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmYzJmYWQKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvbGlicy9nbF9lbnVtcy5pbgpAQCAtMCwwICsxLDI2MSBAQAorR0xFTlVNKEdMX1BPSU5UUywgMHgwMDAwKQorR0xFTlVNKEdMX0xJTkVTLCAweDAwMDEpCitHTEVOVU0oR0xfTElORV9MT09QLCAweDAwMDIpCitHTEVOVU0oR0xfTElORV9TVFJJUCwgMHgwMDAzKQorR0xFTlVNKEdMX1RSSUFOR0xFUywgMHgwMDA0KQorR0xFTlVNKEdMX1RSSUFOR0xFX1NUUklQLCAweDAwMDUpCitHTEVOVU0oR0xfVFJJQU5HTEVfRkFOLCAweDAwMDYpCitHTEVOVU0oR0xfQURELCAweDAxMDQpCitHTEVOVU0oR0xfTkVWRVIsIDB4MDIwMCkKK0dMRU5VTShHTF9MRVNTLCAweDAyMDEpCitHTEVOVU0oR0xfRVFVQUwsIDB4MDIwMikKK0dMRU5VTShHTF9MRVFVQUwsIDB4MDIwMykKK0dMRU5VTShHTF9HUkVBVEVSLCAweDAyMDQpCitHTEVOVU0oR0xfTk9URVFVQUwsIDB4MDIwNSkKK0dMRU5VTShHTF9HRVFVQUwsIDB4MDIwNikKK0dMRU5VTShHTF9BTFdBWVMsIDB4MDIwNykKK0dMRU5VTShHTF9TUkNfQ09MT1IsIDB4MDMwMCkKK0dMRU5VTShHTF9PTkVfTUlOVVNfU1JDX0NPTE9SLCAweDAzMDEpCitHTEVOVU0oR0xfU1JDX0FMUEhBLCAweDAzMDIpCitHTEVOVU0oR0xfT05FX01JTlVTX1NSQ19BTFBIQSwgMHgwMzAzKQorR0xFTlVNKEdMX0RTVF9BTFBIQSwgMHgwMzA0KQorR0xFTlVNKEdMX09ORV9NSU5VU19EU1RfQUxQSEEsIDB4MDMwNSkKK0dMRU5VTShHTF9EU1RfQ09MT1IsIDB4MDMwNikKK0dMRU5VTShHTF9PTkVfTUlOVVNfRFNUX0NPTE9SLCAweDAzMDcpCitHTEVOVU0oR0xfU1JDX0FMUEhBX1NBVFVSQVRFLCAweDAzMDgpCitHTEVOVU0oR0xfRlJPTlQsIDB4MDQwNCkKK0dMRU5VTShHTF9CQUNLLCAweDA0MDUpCitHTEVOVU0oR0xfRlJPTlRfQU5EX0JBQ0ssIDB4MDQwOCkKK0dMRU5VTShHTF9JTlZBTElEX0VOVU0sIDB4MDUwMCkKK0dMRU5VTShHTF9JTlZBTElEX1ZBTFVFLCAweDA1MDEpCitHTEVOVU0oR0xfSU5WQUxJRF9PUEVSQVRJT04sIDB4MDUwMikKK0dMRU5VTShHTF9TVEFDS19PVkVSRkxPVywgMHgwNTAzKQorR0xFTlVNKEdMX1NUQUNLX1VOREVSRkxPVywgMHgwNTA0KQorR0xFTlVNKEdMX09VVF9PRl9NRU1PUlksIDB4MDUwNSkKK0dMRU5VTShHTF9FWFAsIDB4MDgwMCkKK0dMRU5VTShHTF9FWFAyLCAweDA4MDEpCitHTEVOVU0oR0xfQ1csIDB4MDkwMCkKK0dMRU5VTShHTF9DQ1csIDB4MDkwMSkKK0dMRU5VTShHTF9QT0lOVF9TTU9PVEgsIDB4MEIxMCkKK0dMRU5VTShHTF9TTU9PVEhfUE9JTlRfU0laRV9SQU5HRSwgMHgwQjEyKQorR0xFTlVNKEdMX0xJTkVfU01PT1RILCAweDBCMjApCitHTEVOVU0oR0xfU01PT1RIX0xJTkVfV0lEVEhfUkFOR0UsIDB4MEIyMikKK0dMRU5VTShHTF9DVUxMX0ZBQ0UsIDB4MEI0NCkKK0dMRU5VTShHTF9MSUdIVElORywgMHgwQjUwKQorR0xFTlVNKEdMX0xJR0hUX01PREVMX1RXT19TSURFLCAweDBCNTIpCitHTEVOVU0oR0xfTElHSFRfTU9ERUxfQU1CSUVOVCwgMHgwQjUzKQorR0xFTlVNKEdMX0NPTE9SX01BVEVSSUFMLCAweDBCNTcpCitHTEVOVU0oR0xfRk9HLCAweDBCNjApCitHTEVOVU0oR0xfRk9HX0RFTlNJVFksIDB4MEI2MikKK0dMRU5VTShHTF9GT0dfU1RBUlQsIDB4MEI2MykKK0dMRU5VTShHTF9GT0dfRU5ELCAweDBCNjQpCitHTEVOVU0oR0xfRk9HX01PREUsIDB4MEI2NSkKK0dMRU5VTShHTF9GT0dfQ09MT1IsIDB4MEI2NikKK0dMRU5VTShHTF9ERVBUSF9URVNULCAweDBCNzEpCitHTEVOVU0oR0xfU1RFTkNJTF9URVNULCAweDBCOTApCitHTEVOVU0oR0xfTk9STUFMSVpFLCAweDBCQTEpCitHTEVOVU0oR0xfQUxQSEFfVEVTVCwgMHgwQkMwKQorR0xFTlVNKEdMX0RJVEhFUiwgMHgwQkQwKQorR0xFTlVNKEdMX0JMRU5ELCAweDBCRTIpCitHTEVOVU0oR0xfQ09MT1JfTE9HSUNfT1AsIDB4MEJGMikKK0dMRU5VTShHTF9TQ0lTU09SX1RFU1QsIDB4MEMxMSkKK0dMRU5VTShHTF9QRVJTUEVDVElWRV9DT1JSRUNUSU9OX0hJTlQsIDB4MEM1MCkKK0dMRU5VTShHTF9QT0lOVF9TTU9PVEhfSElOVCwgMHgwQzUxKQorR0xFTlVNKEdMX0xJTkVfU01PT1RIX0hJTlQsIDB4MEM1MikKK0dMRU5VTShHTF9QT0xZR09OX1NNT09USF9ISU5ULCAweDBDNTMpCitHTEVOVU0oR0xfRk9HX0hJTlQsIDB4MEM1NCkKK0dMRU5VTShHTF9VTlBBQ0tfQUxJR05NRU5ULCAweDBDRjUpCitHTEVOVU0oR0xfUEFDS19BTElHTk1FTlQsIDB4MEQwNSkKK0dMRU5VTShHTF9NQVhfTElHSFRTLCAweDBEMzEpCitHTEVOVU0oR0xfTUFYX0NMSVBfUExBTkVTLCAweDBEMzIpCitHTEVOVU0oR0xfTUFYX1RFWFRVUkVfU0laRSwgMHgwRDMzKQorR0xFTlVNKEdMX01BWF9NT0RFTFZJRVdfU1RBQ0tfREVQVEgsIDB4MEQzNikKK0dMRU5VTShHTF9NQVhfUFJPSkVDVElPTl9TVEFDS19ERVBUSCwgMHgwRDM4KQorR0xFTlVNKEdMX01BWF9URVhUVVJFX1NUQUNLX0RFUFRILCAweDBEMzkpCitHTEVOVU0oR0xfTUFYX1ZJRVdQT1JUX0RJTVMsIDB4MEQzQSkKK0dMRU5VTShHTF9SRURfQklUUywgMHgwRDUyKQorR0xFTlVNKEdMX0dSRUVOX0JJVFMsIDB4MEQ1MykKK0dMRU5VTShHTF9CTFVFX0JJVFMsIDB4MEQ1NCkKK0dMRU5VTShHTF9BTFBIQV9CSVRTLCAweDBENTUpCitHTEVOVU0oR0xfREVQVEhfQklUUywgMHgwRDU2KQorR0xFTlVNKEdMX1NURU5DSUxfQklUUywgMHgwRDU3KQorR0xFTlVNKEdMX1RFWFRVUkVfMkQsIDB4MERFMSkKK0dMRU5VTShHTF9ET05UX0NBUkUsIDB4MTEwMCkKK0dMRU5VTShHTF9GQVNURVNULCAweDExMDEpCitHTEVOVU0oR0xfTklDRVNULCAweDExMDIpCitHTEVOVU0oR0xfQU1CSUVOVCwgMHgxMjAwKQorR0xFTlVNKEdMX0RJRkZVU0UsIDB4MTIwMSkKK0dMRU5VTShHTF9TUEVDVUxBUiwgMHgxMjAyKQorR0xFTlVNKEdMX1BPU0lUSU9OLCAweDEyMDMpCitHTEVOVU0oR0xfU1BPVF9ESVJFQ1RJT04sIDB4MTIwNCkKK0dMRU5VTShHTF9TUE9UX0VYUE9ORU5ULCAweDEyMDUpCitHTEVOVU0oR0xfU1BPVF9DVVRPRkYsIDB4MTIwNikKK0dMRU5VTShHTF9DT05TVEFOVF9BVFRFTlVBVElPTiwgMHgxMjA3KQorR0xFTlVNKEdMX0xJTkVBUl9BVFRFTlVBVElPTiwgMHgxMjA4KQorR0xFTlVNKEdMX1FVQURSQVRJQ19BVFRFTlVBVElPTiwgMHgxMjA5KQorR0xFTlVNKEdMX0JZVEUsIDB4MTQwMCkKK0dMRU5VTShHTF9VTlNJR05FRF9CWVRFLCAweDE0MDEpCitHTEVOVU0oR0xfU0hPUlQsIDB4MTQwMikKK0dMRU5VTShHTF9VTlNJR05FRF9TSE9SVCwgMHgxNDAzKQorR0xFTlVNKEdMX0ZMT0FULCAweDE0MDYpCitHTEVOVU0oR0xfRklYRUQsIDB4MTQwQykKK0dMRU5VTShHTF9DTEVBUiwgMHgxNTAwKQorR0xFTlVNKEdMX0FORCwgMHgxNTAxKQorR0xFTlVNKEdMX0FORF9SRVZFUlNFLCAweDE1MDIpCitHTEVOVU0oR0xfQ09QWSwgMHgxNTAzKQorR0xFTlVNKEdMX0FORF9JTlZFUlRFRCwgMHgxNTA0KQorR0xFTlVNKEdMX05PT1AsIDB4MTUwNSkKK0dMRU5VTShHTF9YT1IsIDB4MTUwNikKK0dMRU5VTShHTF9PUiwgMHgxNTA3KQorR0xFTlVNKEdMX05PUiwgMHgxNTA4KQorR0xFTlVNKEdMX0VRVUlWLCAweDE1MDkpCitHTEVOVU0oR0xfSU5WRVJULCAweDE1MEEpCitHTEVOVU0oR0xfT1JfUkVWRVJTRSwgMHgxNTBCKQorR0xFTlVNKEdMX0NPUFlfSU5WRVJURUQsIDB4MTUwQykKK0dMRU5VTShHTF9PUl9JTlZFUlRFRCwgMHgxNTBEKQorR0xFTlVNKEdMX05BTkQsIDB4MTUwRSkKK0dMRU5VTShHTF9TRVQsIDB4MTUwRikKK0dMRU5VTShHTF9FTUlTU0lPTiwgMHgxNjAwKQorR0xFTlVNKEdMX1NISU5JTkVTUywgMHgxNjAxKQorR0xFTlVNKEdMX0FNQklFTlRfQU5EX0RJRkZVU0UsIDB4MTYwMikKK0dMRU5VTShHTF9NT0RFTFZJRVcsIDB4MTcwMCkKK0dMRU5VTShHTF9QUk9KRUNUSU9OLCAweDE3MDEpCitHTEVOVU0oR0xfVEVYVFVSRSwgMHgxNzAyKQorR0xFTlVNKEdMX0FMUEhBLCAweDE5MDYpCitHTEVOVU0oR0xfUkdCLCAweDE5MDcpCitHTEVOVU0oR0xfUkdCQSwgMHgxOTA4KQorR0xFTlVNKEdMX0xVTUlOQU5DRSwgMHgxOTA5KQorR0xFTlVNKEdMX0xVTUlOQU5DRV9BTFBIQSwgMHgxOTBBKQorR0xFTlVNKEdMX0ZMQVQsIDB4MUQwMCkKK0dMRU5VTShHTF9TTU9PVEgsIDB4MUQwMSkKK0dMRU5VTShHTF9LRUVQLCAweDFFMDApCitHTEVOVU0oR0xfUkVQTEFDRSwgMHgxRTAxKQorR0xFTlVNKEdMX1JFUExBQ0UsIDB4MUUwMSkKK0dMRU5VTShHTF9JTkNSLCAweDFFMDIpCitHTEVOVU0oR0xfREVDUiwgMHgxRTAzKQorR0xFTlVNKEdMX1ZFTkRPUiwgMHgxRjAwKQorR0xFTlVNKEdMX1JFTkRFUkVSLCAweDFGMDEpCitHTEVOVU0oR0xfVkVSU0lPTiwgMHgxRjAyKQorR0xFTlVNKEdMX0VYVEVOU0lPTlMsIDB4MUYwMykKK0dMRU5VTShHTF9NT0RVTEFURSwgMHgyMTAwKQorR0xFTlVNKEdMX0RFQ0FMLCAweDIxMDEpCitHTEVOVU0oR0xfVEVYVFVSRV9FTlZfTU9ERSwgMHgyMjAwKQorR0xFTlVNKEdMX1RFWFRVUkVfRU5WX0NPTE9SLCAweDIyMDEpCitHTEVOVU0oR0xfVEVYVFVSRV9FTlYsIDB4MjMwMCkKK0dMRU5VTShHTF9ORUFSRVNULCAweDI2MDApCitHTEVOVU0oR0xfTElORUFSLCAweDI2MDEpCitHTEVOVU0oR0xfTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCwgMHgyNzAwKQorR0xFTlVNKEdMX0xJTkVBUl9NSVBNQVBfTkVBUkVTVCwgMHgyNzAxKQorR0xFTlVNKEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUiwgMHgyNzAyKQorR0xFTlVNKEdMX0xJTkVBUl9NSVBNQVBfTElORUFSLCAweDI3MDMpCitHTEVOVU0oR0xfVEVYVFVSRV9NQUdfRklMVEVSLCAweDI4MDApCitHTEVOVU0oR0xfVEVYVFVSRV9NSU5fRklMVEVSLCAweDI4MDEpCitHTEVOVU0oR0xfVEVYVFVSRV9XUkFQX1MsIDB4MjgwMikKK0dMRU5VTShHTF9URVhUVVJFX1dSQVBfVCwgMHgyODAzKQorR0xFTlVNKEdMX0NMQU1QLCAweDI5MDApCitHTEVOVU0oR0xfUkVQRUFULCAweDI5MDEpCitHTEVOVU0oR0xfQ0xJUF9QTEFORTAsIDB4MzAwMCkKK0dMRU5VTShHTF9DTElQX1BMQU5FMSwgMHgzMDAxKQorR0xFTlVNKEdMX0NMSVBfUExBTkUyLCAweDMwMDIpCitHTEVOVU0oR0xfQ0xJUF9QTEFORTMsIDB4MzAwMykKK0dMRU5VTShHTF9DTElQX1BMQU5FNCwgMHgzMDA0KQorR0xFTlVNKEdMX0NMSVBfUExBTkU1LCAweDMwMDUpCitHTEVOVU0oR0xfTElHSFQwLCAweDQwMDApCitHTEVOVU0oR0xfTElHSFQxLCAweDQwMDEpCitHTEVOVU0oR0xfTElHSFQyLCAweDQwMDIpCitHTEVOVU0oR0xfTElHSFQzLCAweDQwMDMpCitHTEVOVU0oR0xfTElHSFQ0LCAweDQwMDQpCitHTEVOVU0oR0xfTElHSFQ1LCAweDQwMDUpCitHTEVOVU0oR0xfTElHSFQ2LCAweDQwMDYpCitHTEVOVU0oR0xfTElHSFQ3LCAweDQwMDcpCitHTEVOVU0oR0xfRElSRUNUX1RFWFRVUkVfMkRfUVVBTENPTU0sIDB4N0U4MCkKK0dMRU5VTShHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80LCAweDgwMzMpCitHTEVOVU0oR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMSwgMHg4MDM0KQorR0xFTlVNKEdMX1BPTFlHT05fT0ZGU0VUX0ZJTEwsIDB4ODAzNykKK0dMRU5VTShHTF9SRVNDQUxFX05PUk1BTCwgMHg4MDNBKQorR0xFTlVNKEdMX1ZFUlRFWF9BUlJBWSwgMHg4MDc0KQorR0xFTlVNKEdMX05PUk1BTF9BUlJBWSwgMHg4MDc1KQorR0xFTlVNKEdMX0NPTE9SX0FSUkFZLCAweDgwNzYpCitHTEVOVU0oR0xfVEVYVFVSRV9DT09SRF9BUlJBWSwgMHg4MDc4KQorR0xFTlVNKEdMX01VTFRJU0FNUExFLCAweDgwOUQpCitHTEVOVU0oR0xfU0FNUExFX0FMUEhBX1RPX0NPVkVSQUdFLCAweDgwOUUpCitHTEVOVU0oR0xfU0FNUExFX0FMUEhBX1RPX09ORSwgMHg4MDlGKQorR0xFTlVNKEdMX1NBTVBMRV9DT1ZFUkFHRSwgMHg4MEEwKQorR0xFTlVNKEdMX01BWF9FTEVNRU5UU19WRVJUSUNFUywgMHg4MEU4KQorR0xFTlVNKEdMX01BWF9FTEVNRU5UU19JTkRJQ0VTLCAweDgwRTkpCitHTEVOVU0oR0xfQ0xBTVBfVE9fRURHRSwgMHg4MTJGKQorR0xFTlVNKEdMX0dFTkVSQVRFX01JUE1BUCwgMHg4MTkxKQorR0xFTlVNKEdMX0dFTkVSQVRFX01JUE1BUF9ISU5ULCAweDgxOTIpCitHTEVOVU0oR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIDB4ODM2MykKK0dMRU5VTShHTF9BTElBU0VEX1BPSU5UX1NJWkVfUkFOR0UsIDB4ODQ2RCkKK0dMRU5VTShHTF9BTElBU0VEX0xJTkVfV0lEVEhfUkFOR0UsIDB4ODQ2RSkKK0dMRU5VTShHTF9URVhUVVJFMCwgMHg4NEMwKQorR0xFTlVNKEdMX1RFWFRVUkUxLCAweDg0QzEpCitHTEVOVU0oR0xfVEVYVFVSRTIsIDB4ODRDMikKK0dMRU5VTShHTF9URVhUVVJFMywgMHg4NEMzKQorR0xFTlVNKEdMX1RFWFRVUkU0LCAweDg0QzQpCitHTEVOVU0oR0xfVEVYVFVSRTUsIDB4ODRDNSkKK0dMRU5VTShHTF9URVhUVVJFNiwgMHg4NEM2KQorR0xFTlVNKEdMX1RFWFRVUkU3LCAweDg0QzcpCitHTEVOVU0oR0xfVEVYVFVSRTgsIDB4ODRDOCkKK0dMRU5VTShHTF9URVhUVVJFOSwgMHg4NEM5KQorR0xFTlVNKEdMX1RFWFRVUkUxMCwgMHg4NENBKQorR0xFTlVNKEdMX1RFWFRVUkUxMSwgMHg4NENCKQorR0xFTlVNKEdMX1RFWFRVUkUxMiwgMHg4NENDKQorR0xFTlVNKEdMX1RFWFRVUkUxMywgMHg4NENEKQorR0xFTlVNKEdMX1RFWFRVUkUxNCwgMHg4NENFKQorR0xFTlVNKEdMX1RFWFRVUkUxNSwgMHg4NENGKQorR0xFTlVNKEdMX1RFWFRVUkUxNiwgMHg4NEQwKQorR0xFTlVNKEdMX1RFWFRVUkUxNywgMHg4NEQxKQorR0xFTlVNKEdMX1RFWFRVUkUxOCwgMHg4NEQyKQorR0xFTlVNKEdMX1RFWFRVUkUxOSwgMHg4NEQzKQorR0xFTlVNKEdMX1RFWFRVUkUyMCwgMHg4NEQ0KQorR0xFTlVNKEdMX1RFWFRVUkUyMSwgMHg4NEQ1KQorR0xFTlVNKEdMX1RFWFRVUkUyMiwgMHg4NEQ2KQorR0xFTlVNKEdMX1RFWFRVUkUyMywgMHg4NEQ3KQorR0xFTlVNKEdMX1RFWFRVUkUyNCwgMHg4NEQ4KQorR0xFTlVNKEdMX1RFWFRVUkUyNSwgMHg4NEQ5KQorR0xFTlVNKEdMX1RFWFRVUkUyNiwgMHg4NERBKQorR0xFTlVNKEdMX1RFWFRVUkUyNywgMHg4NERCKQorR0xFTlVNKEdMX1RFWFRVUkUyOCwgMHg4NERDKQorR0xFTlVNKEdMX1RFWFRVUkUyOSwgMHg4NEREKQorR0xFTlVNKEdMX1RFWFRVUkUzMCwgMHg4NERFKQorR0xFTlVNKEdMX1RFWFRVUkUzMSwgMHg4NERGKQorR0xFTlVNKEdMX01BWF9URVhUVVJFX1VOSVRTLCAweDg0RTIpCitHTEVOVU0oR0xfTlVNX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTLCAweDg2QTIpCitHTEVOVU0oR0xfQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFMsIDB4ODZBMykKK0dMRU5VTShHTF9CVUZGRVJfU0laRSwgMHg4NzY0KQorR0xFTlVNKEdMX0JVRkZFUl9VU0FHRSwgMHg4NzY1KQorR0xFTlVNKEdMX1BPSU5UX1NQUklURV9PRVMsIDB4ODg2MSkKK0dMRU5VTShHTF9DT09SRF9SRVBMQUNFX09FUywgMHg4ODYyKQorR0xFTlVNKEdMX0FSUkFZX0JVRkZFUiwgMHg4ODkyKQorR0xFTlVNKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAweDg4OTMpCitHTEVOVU0oR0xfQVJSQVlfQlVGRkVSX0JJTkRJTkcsIDB4ODg5NCkKK0dMRU5VTShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9CSU5ESU5HLCAweDg4OTUpCitHTEVOVU0oR0xfVkVSVEVYX0FSUkFZX0JVRkZFUl9CSU5ESU5HLCAweDg4OTYpCitHTEVOVU0oR0xfTk9STUFMX0FSUkFZX0JVRkZFUl9CSU5ESU5HLCAweDg4OTcpCitHTEVOVU0oR0xfQ09MT1JfQVJSQVlfQlVGRkVSX0JJTkRJTkcsIDB4ODg5OCkKK0dMRU5VTShHTF9URVhUVVJFX0NPT1JEX0FSUkFZX0JVRkZFUl9CSU5ESU5HLCAweDg4OUEpCitHTEVOVU0oR0xfU1RBVElDX0RSQVcsIDB4ODhFNCkKK0dMRU5VTShHTF9EWU5BTUlDX0RSQVcsIDB4ODhFOCkKK0dMRU5VTShHTF9QT0lOVF9TSVpFX0FSUkFZX1RZUEVfT0VTLCAweDg5OEEpCitHTEVOVU0oR0xfUE9JTlRfU0laRV9BUlJBWV9TVFJJREVfT0VTLCAweDg5OEIpCitHTEVOVU0oR0xfUE9JTlRfU0laRV9BUlJBWV9QT0lOVEVSX09FUywgMHg4OThDKQorR0xFTlVNKEdMX01PREVMVklFV19NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTLCAweDg5OEQpCitHTEVOVU0oR0xfUFJPSkVDVElPTl9NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTLCAweDg5OEUpCitHTEVOVU0oR0xfVEVYVFVSRV9NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTLCAweDg5OEYpCitHTEVOVU0oR0xfUEFMRVRURTRfUkdCOF9PRVMsIDB4OEI5MCkKK0dMRU5VTShHTF9QQUxFVFRFNF9SR0JBOF9PRVMsIDB4OEI5MSkKK0dMRU5VTShHTF9QQUxFVFRFNF9SNV9HNl9CNV9PRVMsIDB4OEI5MikKK0dMRU5VTShHTF9QQUxFVFRFNF9SR0JBNF9PRVMsIDB4OEI5MykKK0dMRU5VTShHTF9QQUxFVFRFNF9SR0I1X0ExX09FUywgMHg4Qjk0KQorR0xFTlVNKEdMX1BBTEVUVEU4X1JHQjhfT0VTLCAweDhCOTUpCitHTEVOVU0oR0xfUEFMRVRURThfUkdCQThfT0VTLCAweDhCOTYpCitHTEVOVU0oR0xfUEFMRVRURThfUjVfRzZfQjVfT0VTLCAweDhCOTcpCitHTEVOVU0oR0xfUEFMRVRURThfUkdCQTRfT0VTLCAweDhCOTgpCitHTEVOVU0oR0xfUEFMRVRURThfUkdCNV9BMV9PRVMsIDB4OEI5OSkKK0dMRU5VTShHTF9JTVBMRU1FTlRBVElPTl9DT0xPUl9SRUFEX1RZUEVfT0VTLCAweDhCOUEpCitHTEVOVU0oR0xfSU1QTEVNRU5UQVRJT05fQ09MT1JfUkVBRF9GT1JNQVRfT0VTLCAweDhCOUIpCitHTEVOVU0oR0xfUE9JTlRfU0laRV9BUlJBWV9PRVMsIDB4OEI5QykKK0dMRU5VTShHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIDB4OEI5RCkKK0dMRU5VTShHTF9QT0lOVF9TSVpFX0FSUkFZX0JVRkZFUl9CSU5ESU5HX09FUywgMHg4QjlGKQpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYnMvZ2xfbG9nZ2VyLmggYi9vcGVuZ2wvbGlicy9nbF9sb2dnZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTg1ZGQxCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYnMvZ2xfbG9nZ2VyLmgKQEAgLTAsMCArMSwyNiBAQAorLyogCisgKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqKgorICoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyAqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorICoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyAqKgorICoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisgKioKKyAqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorICoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorICoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyAqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorICoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgQU5EUk9JRF9HTF9MT0dHRVJfSAorI2RlZmluZSBBTkRST0lEX0dMX0xPR0dFUl9ICisKK25hbWVzcGFjZSBhbmRyb2lkIHsKKyNkZWZpbmUgR0xfRU5UUlkociwgYXBpLCAuLi4pIHIgbG9nXyMjYXBpKF9fVkFfQVJHU19fKTsKKyNpbmNsdWRlICJnbF9lbnRyaWVzLmluIgorI3VuZGVmIEdMX0VOVFJZCit9OyAvLyBuYW1lc3BhY2UgYW5kcm9pZAorCisjZW5kaWYgLyogQU5EUk9JRF9HTF9MT0dHRVJfSCAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYnMvaG9va3MuaCBiL29wZW5nbC9saWJzL2hvb2tzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjNmYjAxNwotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC9saWJzL2hvb2tzLmgKQEAgLTAsMCArMSwxMzQgQEAKKy8qIAorICoqIENvcHlyaWdodCAyMDA3LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKioKKyAqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisgKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyAqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisgKioKKyAqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorICoqCisgKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyAqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyAqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisgKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyAqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEFORFJPSURfR0xFU19DTV9IT09LU19ICisjZGVmaW5lIEFORFJPSURfR0xFU19DTV9IT09LU19ICisKKyNpbmNsdWRlIDxjdHlwZS5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjZGVmaW5lIEdMX0xPR0dFUiAgICAgICAgICAgICAgICAgICAwCisjaWYgIWRlZmluZWQoX19hcm1fXykKKyNkZWZpbmUgVVNFX1NMT1dfQklORElORyAgICAgICAgICAgIDEKKyNlbHNlCisjZGVmaW5lIFVTRV9TTE9XX0JJTkRJTkcgICAgICAgICAgICAwCisjZW5kaWYKKyN1bmRlZiBORUxFTQorI2RlZmluZSBORUxFTSh4KSAgICAgICAgICAgICAgICAgICAgKHNpemVvZih4KS9zaXplb2YoKih4KSkpCisjZGVmaW5lIE1BWF9OVU1CRVJfT0ZfR0xfRVhURU5TSU9OUyAzMgorCisKKyNpZiBkZWZpbmVkKEhBVkVfQU5EUk9JRF9PUykgJiYgIVVTRV9TTE9XX0JJTkRJTkcgJiYgIUdMX0xPR0dFUiAmJiBfX09QVElNSVpFX18KKyNkZWZpbmUgVVNFX0ZBU1RfVExTX0tFWSAgICAgICAgICAgIDEKKyNlbHNlCisjZGVmaW5lIFVTRV9GQVNUX1RMU19LRVkgICAgICAgICAgICAwCisjZW5kaWYKKworI2lmIFVTRV9GQVNUX1RMU19LRVkKKyMgICBpbmNsdWRlIDxiaW9uaWNfdGxzLmg+ICAvKiBzcGVjaWFsIHByaXZhdGUgQyBsaWJyYXJ5IGhlYWRlciAqLworI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK25hbWVzcGFjZSBhbmRyb2lkIHsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gIEVHTERpc3BsYXkgYXJlIGdsb2JhbCwgbm90IGF0dGFjaGVkIHRvIGEgZ2l2ZW4gdGhyZWFkCitjb25zdCB1bnNpZ25lZCBpbnQgTlVNX0RJU1BMQVlTID0gMTsKKworZW51bSB7CisgICAgSU1QTF9IQVJEV0FSRSA9IDAsCisgICAgSU1QTF9TT0ZUV0FSRSwKKyAgICBJTVBMX0NPTlRFWFRfTE9TVCwKKyAgICBJTVBMX05PX0NPTlRFWFQsCisgICAgCisgICAgSU1QTF9OVU1fSU1QTEVNRU5UQVRJT05TCit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEdMIC8gRUdMIGhvb2tzCisKKyN1bmRlZiBHTF9FTlRSWQorI3VuZGVmIEVHTF9FTlRSWQorI2RlZmluZSBHTF9FTlRSWShfciwgX2FwaSwgLi4uKSBfciAoKl9hcGkpKF9fVkFfQVJHU19fKTsKKyNkZWZpbmUgRUdMX0VOVFJZKF9yLCBfYXBpLCAuLi4pIF9yICgqX2FwaSkoX19WQV9BUkdTX18pOworCitzdHJ1Y3QgZ2xfaG9va3NfdCB7CisgICAgc3RydWN0IGdsX3QgeworICAgICAgICAjaW5jbHVkZSAiZ2xfZW50cmllcy5pbiIKKyAgICB9IGdsOworICAgIHN0cnVjdCBlZ2xfdCB7CisgICAgICAgICNpbmNsdWRlICJlZ2xfZW50cmllcy5pbiIKKyAgICB9IGVnbDsKKyAgICBzdHJ1Y3QgZ2xfZXh0X3QgeworICAgICAgICB2b2lkICgqZXh0ZW5zaW9uc1tNQVhfTlVNQkVSX09GX0dMX0VYVEVOU0lPTlNdKSh2b2lkKTsKKyAgICB9IGV4dDsKK307CisjdW5kZWYgR0xfRU5UUlkKKyN1bmRlZiBFR0xfRU5UUlkKKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2V4dGVybiBnbF9ob29rc190IGdIb29rc1tJTVBMX05VTV9JTVBMRU1FTlRBVElPTlNdOworZXh0ZXJuIHB0aHJlYWRfa2V5X3QgZ0dMV3JhcHBlcktleTsKKworI2lmIFVTRV9GQVNUX1RMU19LRVkKKworLy8gV2UgaGF2ZSBhIGRlZGljYXRlZCBUTFMgc2xvdCBpbiBiaW9uaWMKK3N0YXRpYyBpbmxpbmUgZ2xfaG9va3NfdCBjb25zdCAqIHZvbGF0aWxlICogZ2V0X3Rsc19ob29rcygpIHsKKyAgICB2b2xhdGlsZSB2b2lkICp0bHNfYmFzZSA9IF9fZ2V0X3RscygpOworICAgIGdsX2hvb2tzX3QgY29uc3QgKiB2b2xhdGlsZSAqIHRsc19ob29rcyA9IAorICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxnbF9ob29rc190IGNvbnN0ICogdm9sYXRpbGUgKj4odGxzX2Jhc2UpOworICAgIHJldHVybiB0bHNfaG9va3M7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCBzZXRHbFRocmVhZFNwZWNpZmljKGdsX2hvb2tzX3QgY29uc3QgKnZhbHVlKSB7CisgICAgZ2xfaG9va3NfdCBjb25zdCAqIHZvbGF0aWxlICogdGxzX2hvb2tzID0gZ2V0X3Rsc19ob29rcygpOworICAgIHRsc19ob29rc1tUTFNfU0xPVF9PUEVOR0xfQVBJXSA9IHZhbHVlOworfQorCitzdGF0aWMgZ2xfaG9va3NfdCBjb25zdCogZ2V0R2xUaHJlYWRTcGVjaWZpYygpIHsKKyAgICBnbF9ob29rc190IGNvbnN0ICogdm9sYXRpbGUgKiB0bHNfaG9va3MgPSBnZXRfdGxzX2hvb2tzKCk7CisgICAgZ2xfaG9va3NfdCBjb25zdCogaG9va3MgPSB0bHNfaG9va3NbVExTX1NMT1RfT1BFTkdMX0FQSV07CisgICAgaWYgKGhvb2tzKSByZXR1cm4gaG9va3M7CisgICAgcmV0dXJuICZnSG9va3NbSU1QTF9OT19DT05URVhUXTsKK30KKworI2Vsc2UKKworc3RhdGljIGlubGluZSB2b2lkIHNldEdsVGhyZWFkU3BlY2lmaWMoZ2xfaG9va3NfdCBjb25zdCAqdmFsdWUpIHsKKyAgICBwdGhyZWFkX3NldHNwZWNpZmljKGdHTFdyYXBwZXJLZXksIHZhbHVlKTsKK30KKworc3RhdGljIGdsX2hvb2tzX3QgY29uc3QqIGdldEdsVGhyZWFkU3BlY2lmaWMoKSB7CisgICAgZ2xfaG9va3NfdCBjb25zdCogaG9va3MgPSAgc3RhdGljX2Nhc3Q8Z2xfaG9va3NfdCo+KHB0aHJlYWRfZ2V0c3BlY2lmaWMoZ0dMV3JhcHBlcktleSkpOworICAgIGlmIChob29rcykgcmV0dXJuIGhvb2tzOworICAgIHJldHVybiAmZ0hvb2tzW0lNUExfTk9fQ09OVEVYVF07Cit9CisKKyNlbmRpZgorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK307IC8vIG5hbWVzcGFjZSBhbmRyb2lkCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNlbmRpZiAvKiBBTkRST0lEX0dMRVNfQ01fSE9PS1NfSCAqLwpkaWZmIC0tZ2l0IGEvb3BlbmdsL2xpYnMvdG9vbHMvZW51bWV4dHJhY3Quc2ggYi9vcGVuZ2wvbGlicy90b29scy9lbnVtZXh0cmFjdC5zaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzA3MzAyCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL2xpYnMvdG9vbHMvZW51bWV4dHJhY3Quc2gKQEAgLTAsMCArMSwzMiBAQAorIyEvYmluL3NoCisKK2F3ayAnCisvXiNkZWZpbmUgR0xfLyB7CisgICAgbmFtZXNbY291bnRdID0gJDI7CisgICAgdmFsdWVzW2NvdW50XSA9ICQzOworICAgIHNvcnRbY291bnRdID0gJDMgKyAwOworICAgIGNvdW50Kys7Cit9CitFTkQgeworICAgIGZvciAoaSA9IDE7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChzb3J0W2ldIDwgc29ydFtqXSkgeworICAgICAgICAgICAgICAgIHRuID0gbmFtZXNbaV07CisgICAgICAgICAgICAgICAgdHYgPSB2YWx1ZXNbaV07CisgICAgICAgICAgICAgICAgdHMgPSBzb3J0W2ldOworICAgICAgICAgICAgICAgIG5hbWVzW2ldID0gbmFtZXNbal07CisgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gdmFsdWVzW2pdOworICAgICAgICAgICAgICAgIHNvcnRbaV0gPSBzb3J0W2pdOworICAgICAgICAgICAgICAgIG5hbWVzW2pdID0gdG47CisgICAgICAgICAgICAgICAgdmFsdWVzW2pdID0gdHY7CisgICAgICAgICAgICAgICAgc29ydFtqXSA9IHRzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorIAorICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgIHByaW50ZigiR0xFTlVNKCVzLCAlcylcbiIsIG5hbWVzW2ldLCB2YWx1ZXNbaV0pOworICAgIH0KK30KKycgPCAkMQorCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvQW5kcm9pZC5tayBiL29wZW5nbC90ZXN0cy9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwNTNlN2QKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvQW5kcm9pZC5tawpAQCAtMCwwICsxIEBACitpbmNsdWRlICQoY2FsbCBhbGwtc3ViZGlyLW1ha2VmaWxlcykKZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL0FuZHJvaWQubWsgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2OTU4ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsMTcgQEAKKyMgQ29weXJpZ2h0IDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorCitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorTE9DQUxfU1JDX0ZJTEVTOj0gYXBwLWxpbnV4LmMgZGVtby5jLmFybQorTE9DQUxfU0hBUkVEX0xJQlJBUklFUyA6PSBsaWJFR0wgbGliR0xFU3YxX0NNIGxpYnVpCitMT0NBTF9NT0RVTEU6PSBhbmdlbGVzCitMT0NBTF9NT0RVTEVfVEFHUyA6PSB0ZXN0cworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCisKKworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCitMT0NBTF9TUkNfRklMRVM6PSBncHVzdGF0ZS5jCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IGxpYkVHTCBsaWJHTEVTdjFfQ00KK0xPQ0FMX01PRFVMRTo9IGdwdXN0YXRlCitMT0NBTF9NT0RVTEVfVEFHUyA6PSB0ZXN0cworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9NT0RVTEVfTElDRU5TRV9CU0RfT1JfTEdQTCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL01PRFVMRV9MSUNFTlNFX0JTRF9PUl9MR1BMCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9NT0RVTEVfTElDRU5TRV9CU0RfT1JfTEdQTApkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvUkVBRE1FLnR4dCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzhiOGE0YQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL1JFQURNRS50eHQKQEAgLTAsMCArMSw3NyBAQAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQorU2FuIEFuZ2VsZXMgT2JzZXJ2YXRpb24gT3BlbkdMIEVTIHZlcnNpb24gZXhhbXBsZQ0KK0NvcHlyaWdodCAyMDA0LTIwMDUgSmV0cm8gTGF1aGENCitXZWI6IGh0dHA6Ly9pa2kuZmkvamV0cm8vDQorU2VlIGZpbGUgbGljZW5zZS50eHQgZm9yIGxpY2Vuc2luZyBpbmZvcm1hdGlvbi4NCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCisNCitUaGlzIGlzIGFuIE9wZW5HTCBFUyBwb3J0IG9mIHRoZSBzbWFsbCBzZWxmLXJ1bm5pbmcgZGVtb25zdHJhdGlvbg0KK2NhbGxlZCAiU2FuIEFuZ2VsZXMgT2JzZXJ2YXRpb24iLCB3aGljaCB3YXMgZmlyc3QgcHJlc2VudGVkIGluIHRoZQ0KK0Fzc2VtYmx5JzIwMDQgZXZlbnQuIEl0IHdvbiB0aGUgZmlyc3QgcGxhY2UgaW4gdGhlIDQgS0IgaW50cm8NCitjb21wZXRpdGlvbiBjYXRlZ29yeS4NCisNCitUaGUgZGVtb25zdHJhdGlvbiBmZWF0dXJlcyBhIHNpZ2h0c2VlaW5nIG9mIGEgZnV0dXJpc3RpYyBjaXR5DQoraGF2aW5nIG1hbnkgZGlmZmVyZW50IGtpbmQgb2YgYnVpbGRpbmdzIGFuZCBpdGVtcy4gRXZlcnl0aGluZyBpcw0KK2ZsYXQgc2hhZGVkIHdpdGggdGhyZWUgZGlmZmVyZW50IGxpZ2h0cy4NCisNCitUaGUgb3JpZ2luYWwgdmVyc2lvbiB3YXMgbWFkZSBmb3IgZGVza3RvcCB3aXRoIE9wZW5HTC4gSXQgd2FzDQorbmF0dXJhbGx5IGhlYXZpbHkgc2l6ZSBvcHRpbWl6ZWQgaW4gb3JkZXIgdG8gZml0IGl0IGluIHRoZSBzaXplDQorbGltaXQuIEZvciB0aGlzIE9wZW5HTCBFUyB2ZXJzaW9uIGV4YW1wbGUgbXVjaCBvZiB0aGUgY29kZSBpcw0KK2NsZWFuZWQgdXAgYW5kIHRoZSBzb3VuZCBpcyByZW1vdmVkLiBBbHNvIGRldGFpbCBsZXZlbCBpcyBsb3dlcmVkLA0KK2FsdGhvdWdoIGl0IHN0aWxsIGNvbnRhaW5zIG92ZXIgNjAwMDAgZmFjZXMuDQorDQorVGhlIFdpbjMyICgyMDAwL1hQKSBiaW5hcnkgcGFja2FnZSBvZiBvcmlnaW5hbCB2ZXJzaW9uIGlzDQorYXZhaWxhYmxlIGZyb20gdGhpcyBhZGRyZXNzOiBodHRwOi8vamV0LnJvL2ZpbGVzL2FuZ2VsZXMuemlwDQorDQorRmlyc3QgdmVyc2lvbiBvZiB0aGlzIE9wZW5HTCBFUyBwb3J0IHdhcyBzdWJtaXR0ZWQgdG8gdGhlIEtocm9ub3MNCitPcGVuR0wgRVMgQ29kaW5nIENoYWxsZW5nZSBoZWxkIGluIDIwMDQtMjAwNS4NCisNCitBcyBhIGNvZGUgZXhhbXBsZSwgdGhpcyBzb3VyY2Ugc2hvd3MgdGhlIGZvbGxvd2luZzoNCisgICogSG93IHRvIGNyZWF0ZSBhIG1pbmltYWwgYW5kIHBvcnRhYmxlIGFkIGhvYyBmcmFtZXdvcmsNCisgICAgZm9yIHNtYWxsIHRlc3RpbmcvZGVtb25zdHJhdGlvbiBwcm9ncmFtcy4gVGhpcyBmcmFtZXdvcmsNCisgICAgY29tcGlsZXMgZm9yIGJvdGggZGVza3RvcCBhbmQgUG9ja2V0UEMgV2luMzIgZW52aXJvbm1lbnQsDQorICAgIGFuZCBhIHNlcGFyYXRlIHNvdXJjZSBpcyBpbmNsdWRlZCBmb3IgTGludXggd2l0aCBYMTEuDQorICAqIEhvdyB0byBkeW5hbWljYWxseSBmaW5kIGFuZCB1c2UgdGhlIE9wZW5HTCBFUyBETEwgb3INCisgICAgc2hhcmVkIG9iamVjdCwgc28gdGhhdCB0aGUgbGlicmFyeSBpcyBub3QgbmVlZGVkIGF0DQorICAgIHRoZSBjb21waWxlL2xpbmsgc3RhZ2UuDQorICAqIEhvdyB0byB1c2UgdGhlIGJhc2ljIGZlYXR1cmVzIG9mIE9wZW5HTCBFUyAxLjAvMS4xDQorICAgIENvbW1vbiBMaXRlLCBzdWNoIGFzIHZlcnRleCBhcnJheXMsIGNvbG9yIGFycmF5cyBhbmQNCisgICAgbGlnaHRpbmcuDQorICAqIEhvdyB0byBjcmVhdGUgYSBzZWxmIGNvbnRhaW5lZCBzbWFsbCBkZW1vbnN0cmF0aW9uDQorICAgIGFwcGxpY2F0aW9uIHdpdGggb2JqZWN0cyBnZW5lcmF0ZWQgdXNpbmcgcHJvY2VkdXJhbA0KKyAgICBhbGdvcml0aG1zLg0KKw0KK0FzIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIHdhcyBvcHRpbWl6ZWQgZm9yIHNpemUgaW5zdGVhZCBvZg0KK3BlcmZvcm1hbmNlLCB0aGF0IGhvbGRzIHRydWUgZm9yIHRoaXMgT3BlbkdMIEVTIHZlcnNpb24gYXMNCit3ZWxsLiBUaHVzIHRoZSBwZXJmb3JtYW5jZSBjb3VsZCBiZSBzaWduaWZpY2FudGx5IGluY3JlYXNlZCwNCitmb3IgZXhhbXBsZSBieSBjaGFuZ2luZyB0aGUgY29kZSB0byB1c2UgZ2xEcmF3RWxlbWVudHMNCitpbnN0ZWFkIG9mIGdsRHJhd0FycmF5cy4gVGhlIGNvZGUgdXNlcyBvbmx5IE9wZW5HTCBFUyAxLjANCitDb21tb24gTGl0ZSAtbGV2ZWwgZnVuY3Rpb24gY2FsbHMgd2l0aG91dCBhbnkgZXh0ZW5zaW9ucy4NCisNCitUaGUgcmVmZXJlbmNlIE9wZW5HTCBFUyBpbXBsZW1lbnRhdGlvbnMgdXNlZCBmb3IgdGhpcyBhcHBsaWNhdGlvbjoNCisgICogSHlicmlkJ3MgT3BlbkdMIEVTIEFQSSBJbXBsZW1lbnRhdGlvbiAoR2VyYmVyYSkgdmVyc2lvbiAyLjAuNA0KKyAgICBQcmVidWlsdCBXaW4zMiBQQyBleGVjdXRhYmxlOiBTYW5PR0xFUy1HZXJiZXJhLmV4ZQ0KKyAgKiBQb3dlclZSIE1CWCBTREssIE9wZW5HTCBFUyBXaW5kb3dzIFBDIEVtdWxhdGlvbiB2ZXJzaW9uIDEuMDQuMTQuMDE3MA0KKyAgICBQcmVidWlsdCBXaW4zMiBQQyBleGVjdXRhYmxlOiBTYW5PR0xFUy1QVlJTREsuZXhlDQorDQorTm90ZSB0aGF0IERJU0FCTEVfSU1QT1JUR0wgcHJlcHJvY2Vzc29yIG1hY3JvIGNhbiBiZSB1c2VkDQordG8gc3BlY2lmeSBub3QgdG8gdXNlIGR5bmFtaWMgcnVudGltZSBiaW5kaW5nIG9mIHRoZSBsaWJyYXJ5Lg0KK1lvdSBhbHNvIG5lZWQgdG8gZGVmaW5lIHByZXByb2Nlc3NvciBtYWNybyBQVlJTREsgdG8gY29tcGlsZQ0KK3RoZSBzb3VyY2Ugd2l0aCBQb3dlclZSIE9wZW5HTCBFUyBTREsuDQorDQorVGhlIGRlbW8gYXBwbGljYXRpb24gaXMgYnJpZWZseSB0ZXN0ZWQgd2l0aCBhIGZldyBvdGhlciBPcGVuR0wgRVMNCitpbXBsZW1lbnRhdGlvbnMgYXMgd2VsbCAoZS5nLiBWaW5jZW50LCBHTEVTb25HTCBvbiBMaW51eCwgRGVsbA0KK0F4aW0gWDUwdikuIE1vc3Qgb2YgdGhlc2Ugb3RoZXIgaW1wbGVtZW50YXRpb25zIHJlbmRlcmVkIHRoZSBkZW1vDQorZXJyb25lb3VzbHkgaW4gc29tZSBhc3BlY3QuIFRoaXMgbWF5IGluZGljYXRlIHRoYXQgdGhlIGRlbW8gc291cmNlDQorY291bGQgc3RpbGwgaGF2ZSBzb21lIHdvcmsgdG8gZG8gd2l0aCBjb21wYXRpYmlsaXR5IGFuZCBjb3JyZWN0DQorQVBJIHVzYWdlLCBhbHRob3VnaCB0aGUgbm9uLWNvbmZvcm1pbmcgaW1wbGVtZW50YXRpb25zIGFyZSBtb3N0DQorcHJvYmFibHkgdW5maW5pc2hlZCBhcyB3ZWxsLg0KKw0KK1RoYW5rcyBhbmQgQWNrbm93bGVkZ2VtZW50czoNCisNCisqIFRvbmkgTPZubmJlcmcgKCFDdWJlKSBjcmVhdGVkIHRoZSBtdXNpYyBmb3Igb3JpZ2luYWwgdmVyc2lvbiwgd2hpY2gNCisgIGlzIG5vdCBmZWF0dXJlZCBpbiB0aGlzIE9wZW5HTCBFUyBwb3J0Lg0KKyogU2FyYSBLYXBsaSAoc3QgUmFuYSkgZm9yIGFkZGl0aW9uYWwgY2FtZXJhIHdvcmsuDQorKiBQYXVsIEJvdXJrZSBmb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN1cGVyc2hhcGVzLg0KKw0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL2FwcC1saW51eC5jIGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvYXBwLWxpbnV4LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QwZDMyMAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2FwcC1saW51eC5jCkBAIC0wLDAgKzEsMjIzIEBACisvKiBTYW4gQW5nZWxlcyBPYnNlcnZhdGlvbiBPcGVuR0wgRVMgdmVyc2lvbiBleGFtcGxlCisgKiBDb3B5cmlnaHQgMjAwNC0yMDA1IEpldHJvIExhdWhhCisgKiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogV2ViOiBodHRwOi8vaWtpLmZpL2pldHJvLworICoKKyAqIFRoaXMgc291cmNlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiBFSVRIRVI6CisgKiAgICgxKSBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZQorICogICAgICAgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQKKyAqICAgICAgIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4gVGhlIHRleHQgb2YgdGhlIEdOVSBMZXNzZXIKKyAqICAgICAgIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIHNvdXJjZSBpbiB0aGUKKyAqICAgICAgIGZpbGUgTElDRU5TRS1MR1BMLnR4dC4KKyAqICAgKDIpIFRoZSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4KKyAqICAgICAgIHRoZSBmaWxlIExJQ0VOU0UtQlNELnR4dC4KKyAqCisgKiBUaGlzIHNvdXJjZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBmaWxlcworICogTElDRU5TRS1MR1BMLnR4dCBhbmQgTElDRU5TRS1CU0QudHh0IGZvciBtb3JlIGRldGFpbHMuCisgKgorICogJElkOiBhcHAtbGludXguYyx2IDEuNCAyMDA1LzAyLzA4IDE4OjQyOjQ4IHRvbmljIEV4cCAkCisgKiAkUmV2aXNpb246IDEuNCAkCisgKgorICogUGFydHMgb2YgdGhpcyBzb3VyY2UgZmlsZSBpcyBiYXNlZCBvbiB0ZXN0L2V4YW1wbGUgY29kZSBmcm9tCisgKiBHTEVTb25HTCBpbXBsZW1lbnRhdGlvbiBieSBEYXZpZCBCbHl0aGUuIEhlcmUgaXMgY29weSBvZiB0aGUKKyAqIGxpY2Vuc2Ugbm90aWNlIGZyb20gdGhhdCBzb3VyY2U6CisgKgorICogQ29weXJpZ2h0IChDKSAyMDAzICBEYXZpZCBCbHl0aGUgICBBbGwgUmlnaHRzIFJlc2VydmVkLgorICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCisgKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAorICogdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgorICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCisgKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKKyAqIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgKgorICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQKKyAqIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorICoKKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTCisgKiBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTAorICogREFWSUQgQkxZVEhFIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTgorICogQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4KKyAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCisgKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3lzL3RpbWUuaD4KKworI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisKKyNpbmNsdWRlICJhcHAuaCIKKworCitpbnQgZ0FwcEFsaXZlID0gMTsKKworc3RhdGljIGNvbnN0IGNoYXIgc0FwcE5hbWVbXSA9CisgICAgIlNhbiBBbmdlbGVzIE9ic2VydmF0aW9uIE9wZW5HTCBFUyB2ZXJzaW9uIGV4YW1wbGUgKExpbnV4KSI7CisKK3N0YXRpYyBpbnQgc1dpbmRvd1dpZHRoID0gV0lORE9XX0RFRkFVTFRfV0lEVEg7CitzdGF0aWMgaW50IHNXaW5kb3dIZWlnaHQgPSBXSU5ET1dfREVGQVVMVF9IRUlHSFQ7CitzdGF0aWMgRUdMRGlzcGxheSBzRWdsRGlzcGxheSA9IEVHTF9OT19ESVNQTEFZOworc3RhdGljIEVHTENvbnRleHQgc0VnbENvbnRleHQgPSBFR0xfTk9fQ09OVEVYVDsKK3N0YXRpYyBFR0xTdXJmYWNlIHNFZ2xTdXJmYWNlID0gRUdMX05PX1NVUkZBQ0U7CisKK2NvbnN0IGNoYXIgKmVnbF9zdHJlcnJvcih1bnNpZ25lZCBlcnIpCit7CisgICAgc3dpdGNoKGVycil7CisgICAgY2FzZSBFR0xfU1VDQ0VTUzogcmV0dXJuICJTVUNDRVNTIjsKKyAgICBjYXNlIEVHTF9OT1RfSU5JVElBTElaRUQ6IHJldHVybiAiTk9UIElOSVRJQUxJWkVEIjsKKyAgICBjYXNlIEVHTF9CQURfQUNDRVNTOiByZXR1cm4gIkJBRCBBQ0NFU1MiOworICAgIGNhc2UgRUdMX0JBRF9BTExPQzogcmV0dXJuICJCQUQgQUxMT0MiOworICAgIGNhc2UgRUdMX0JBRF9BVFRSSUJVVEU6IHJldHVybiAiQkFEX0FUVFJJQlVURSI7CisgICAgY2FzZSBFR0xfQkFEX0NPTkZJRzogcmV0dXJuICJCQUQgQ09ORklHIjsKKyAgICBjYXNlIEVHTF9CQURfQ09OVEVYVDogcmV0dXJuICJCQUQgQ09OVEVYVCI7CisgICAgY2FzZSBFR0xfQkFEX0NVUlJFTlRfU1VSRkFDRTogcmV0dXJuICJCQUQgQ1VSUkVOVCBTVVJGQUNFIjsKKyAgICBjYXNlIEVHTF9CQURfRElTUExBWTogcmV0dXJuICJCQUQgRElTUExBWSI7CisgICAgY2FzZSBFR0xfQkFEX01BVENIOiByZXR1cm4gIkJBRCBNQVRDSCI7CisgICAgY2FzZSBFR0xfQkFEX05BVElWRV9QSVhNQVA6IHJldHVybiAiQkFEIE5BVElWRSBQSVhNQVAiOworICAgIGNhc2UgRUdMX0JBRF9OQVRJVkVfV0lORE9XOiByZXR1cm4gIkJBRCBOQVRJVkUgV0lORE9XIjsKKyAgICBjYXNlIEVHTF9CQURfUEFSQU1FVEVSOiByZXR1cm4gIkJBRCBQQVJBTUVURVIiOworICAgIGNhc2UgRUdMX0JBRF9TVVJGQUNFOiByZXR1cm4gIkJBRF9TVVJGQUNFIjsKKy8vICAgIGNhc2UgRUdMX0NPTlRFWFRfTE9TVDogcmV0dXJuICJDT05URVhUIExPU1QiOworICAgIGRlZmF1bHQ6IHJldHVybiAiVU5LTk9XTiI7CisgICAgfQorfQorCit2b2lkIGVnbF9lcnJvcihjb25zdCBjaGFyICpuYW1lKQoreworICAgIHVuc2lnbmVkIGVyciA9IGVnbEdldEVycm9yKCk7CisgICAgaWYoZXJyICE9IEVHTF9TVUNDRVNTKSB7CisgICAgICAgIGZwcmludGYoc3RkZXJyLCIlcygpOiBlZ2wgZXJyb3IgMHgleCAoJXMpXG4iLCAKKyAgICAgICAgICAgICAgICBuYW1lLCBlcnIsIGVnbF9zdHJlcnJvcihlcnIpKTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIGNoZWNrR0xFcnJvcnMoKQoreworICAgIEdMZW51bSBlcnJvciA9IGdsR2V0RXJyb3IoKTsKKyAgICBpZiAoZXJyb3IgIT0gR0xfTk9fRVJST1IpCisgICAgICAgIGZwcmludGYoc3RkZXJyLCAiR0wgRXJyb3I6IDB4JTA0eFxuIiwgKGludCllcnJvcik7Cit9CisKKworc3RhdGljIHZvaWQgY2hlY2tFR0xFcnJvcnMoKQoreworICAgIEVHTGludCBlcnJvciA9IGVnbEdldEVycm9yKCk7CisgICAgLy8gR0xFU29uR0wgc2VlbXMgdG8gYmUgcmV0dXJuaW5nIDAgd2hlbiB0aGVyZSBpcyBubyBlcnJvcnM/CisgICAgaWYgKGVycm9yICYmIGVycm9yICE9IEVHTF9TVUNDRVNTKQorICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkVHTCBFcnJvcjogMHglMDR4XG4iLCAoaW50KWVycm9yKTsKK30KKworc3RhdGljIGludCBpbml0R3JhcGhpY3MoKQoreworICAgIEVHTGludCBzX2NvbmZpZ0F0dHJpYnNbXSA9IHsKKyAgICAgICAgIEVHTF9SRURfU0laRSwgICAgICAgNSwKKyAgICAgICAgIEVHTF9HUkVFTl9TSVpFLCAgICAgNiwKKyAgICAgICAgIEVHTF9CTFVFX1NJWkUsICAgICAgNSwKKyAjaWYgMQorICAgICAgICAgRUdMX0RFUFRIX1NJWkUsICAgICAxNiwKKyAgICAgICAgIEVHTF9TVEVOQ0lMX1NJWkUsICAgMCwKKyAjZWxzZQorICAgICAgICAgRUdMX0FMUEhBX1NJWkUsICAgICBFR0xfRE9OVF9DQVJFLAorICAgICAgICAgRUdMX0RFUFRIX1NJWkUsICAgICBFR0xfRE9OVF9DQVJFLAorICAgICAgICAgRUdMX1NURU5DSUxfU0laRSwgICBFR0xfRE9OVF9DQVJFLAorICAgICAgICAgRUdMX1NVUkZBQ0VfVFlQRSwgICBFR0xfRE9OVF9DQVJFLAorICNlbmRpZgorICAgICAgICAgRUdMX05PTkUKKyAgICAgfTsKKyAgICAgCisgICAgIEVHTGludCBudW1Db25maWdzID0gLTE7CisgICAgIEVHTGludCBtYWpvclZlcnNpb247CisgICAgIEVHTGludCBtaW5vclZlcnNpb247CisgICAgIEVHTENvbmZpZyBjb25maWc7CisgICAgIEVHTENvbnRleHQgY29udGV4dDsKKyAgICAgRUdMU3VyZmFjZSBzdXJmYWNlOworICAgICAKKyAgICAgRUdMRGlzcGxheSBkcHk7CisKKyAgICAgZHB5ID0gZWdsR2V0RGlzcGxheShFR0xfREVGQVVMVF9ESVNQTEFZKTsKKyAgICAgZWdsX2Vycm9yKCJlZ2xHZXREaXNwbGF5Iik7CisgICAgIGZwcmludGYoc3RkZXJyLCJkcHkgPSAweCUwOHhcbiIsICh1bnNpZ25lZCkgZHB5KTsKKyAgICAgCisgICAgIGVnbEluaXRpYWxpemUoZHB5LCAmbWFqb3JWZXJzaW9uLCAmbWlub3JWZXJzaW9uKTsKKyAgICAgZWdsX2Vycm9yKCJlZ2xJbml0aWFsaXplIik7CisKKyAgICAgZWdsR2V0Q29uZmlncyhkcHksIE5VTEwsIDAsICZudW1Db25maWdzKTsKKyAgICAgZWdsX2Vycm9yKCJlZ2xHZXRDb25maWdzIik7CisgICAgIGZwcmludGYoc3RkZXJyLCJudW0gY29uZmlncyAlZFxuIiwgbnVtQ29uZmlncyk7CisgICAgIAorICAgICBlZ2xDaG9vc2VDb25maWcoZHB5LCBzX2NvbmZpZ0F0dHJpYnMsICZjb25maWcsIDEsICZudW1Db25maWdzKTsKKyAgICAgZWdsX2Vycm9yKCJlZ2xDaG9vc2VDb25maWciKTsKKworICAgICBzdXJmYWNlID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShkcHksIGNvbmZpZywKKyAgICAgICAgICAgICBhbmRyb2lkX2NyZWF0ZURpc3BsYXlTdXJmYWNlKCksIE5VTEwpOworICAgICBlZ2xfZXJyb3IoImVnbE1hcFdpbmRvd1N1cmZhY2UiKTsKKworICAgICBmcHJpbnRmKHN0ZGVyciwic3VyZmFjZSA9ICVwXG4iLCBzdXJmYWNlKTsKKworICAgICBjb250ZXh0ID0gZWdsQ3JlYXRlQ29udGV4dChkcHksIGNvbmZpZywgTlVMTCwgTlVMTCk7CisgICAgIGVnbF9lcnJvcigiZWdsQ3JlYXRlQ29udGV4dCIpOworICAgICBmcHJpbnRmKHN0ZGVyciwiY29udGV4dCA9ICVwXG4iLCBjb250ZXh0KTsKKyAgICAgCisgICAgIGVnbE1ha2VDdXJyZW50KGRweSwgc3VyZmFjZSwgc3VyZmFjZSwgY29udGV4dCk7ICAgCisgICAgIGVnbF9lcnJvcigiZWdsTWFrZUN1cnJlbnQiKTsKKworICAgICBlZ2xRdWVyeVN1cmZhY2UoZHB5LCBzdXJmYWNlLCBFR0xfV0lEVEgsICZzV2luZG93V2lkdGgpOworICAgICBlZ2xRdWVyeVN1cmZhY2UoZHB5LCBzdXJmYWNlLCBFR0xfSEVJR0hULCAmc1dpbmRvd0hlaWdodCk7CisKKyAgICBzRWdsRGlzcGxheSA9IGRweTsKKyAgICBzRWdsU3VyZmFjZSA9IHN1cmZhY2U7CisgICAgc0VnbENvbnRleHQgPSBjb250ZXh0OworCisgICAgcmV0dXJuIEVHTF9UUlVFOworfQorCisKK3N0YXRpYyB2b2lkIGRlaW5pdEdyYXBoaWNzKCkKK3sKKyAgICBlZ2xNYWtlQ3VycmVudChzRWdsRGlzcGxheSwgTlVMTCwgTlVMTCwgTlVMTCk7CisgICAgZWdsRGVzdHJveUNvbnRleHQoc0VnbERpc3BsYXksIHNFZ2xDb250ZXh0KTsKKyAgICBlZ2xEZXN0cm95U3VyZmFjZShzRWdsRGlzcGxheSwgc0VnbFN1cmZhY2UpOworICAgIGVnbFRlcm1pbmF0ZShzRWdsRGlzcGxheSk7Cit9CisKKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgICAvLyBub3QgcmVmZXJlbmNlZDoKKyAgICBhcmdjID0gYXJnYzsKKyAgICBhcmd2ID0gYXJndjsKKworICAgIGlmICghaW5pdEdyYXBoaWNzKCkpCisgICAgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkdyYXBoaWNzIGluaXRpYWxpemF0aW9uIGZhaWxlZC5cbiIpOworICAgICAgICByZXR1cm4gRVhJVF9GQUlMVVJFOworICAgIH0KKworICAgIGFwcEluaXQoKTsKKyAgICAKKyAgICB3aGlsZSAoZ0FwcEFsaXZlKQorICAgIHsKKyAgICAgICAgc3RydWN0IHRpbWV2YWwgdGltZU5vdzsKKworICAgICAgICBpZiAoZ0FwcEFsaXZlKQorICAgICAgICB7CisgICAgICAgICAgICBnZXR0aW1lb2ZkYXkoJnRpbWVOb3csIE5VTEwpOworICAgICAgICAgICAgYXBwUmVuZGVyKHRpbWVOb3cudHZfc2VjICogMTAwMCArIHRpbWVOb3cudHZfdXNlYyAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgc1dpbmRvd1dpZHRoLCBzV2luZG93SGVpZ2h0KTsKKyAgICAgICAgICAgIGNoZWNrR0xFcnJvcnMoKTsKKyAgICAgICAgICAgIGVnbFN3YXBCdWZmZXJzKHNFZ2xEaXNwbGF5LCBzRWdsU3VyZmFjZSk7CisgICAgICAgICAgICBjaGVja0VHTEVycm9ycygpOworICAgICAgICB9CisgICAgfQorCisgICAgYXBwRGVpbml0KCk7CisgICAgZGVpbml0R3JhcGhpY3MoKTsKKworICAgIHJldHVybiBFWElUX1NVQ0NFU1M7Cit9CmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9hcHAuaCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2FwcC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwZWJkMzUKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9hcHAuaApAQCAtMCwwICsxLDU2IEBACisvKiBTYW4gQW5nZWxlcyBPYnNlcnZhdGlvbiBPcGVuR0wgRVMgdmVyc2lvbiBleGFtcGxlCisgKiBDb3B5cmlnaHQgMjAwNC0yMDA1IEpldHJvIExhdWhhCisgKiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogV2ViOiBodHRwOi8vaWtpLmZpL2pldHJvLworICoKKyAqIFRoaXMgc291cmNlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiBFSVRIRVI6CisgKiAgICgxKSBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZQorICogICAgICAgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQKKyAqICAgICAgIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4gVGhlIHRleHQgb2YgdGhlIEdOVSBMZXNzZXIKKyAqICAgICAgIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIHNvdXJjZSBpbiB0aGUKKyAqICAgICAgIGZpbGUgTElDRU5TRS1MR1BMLnR4dC4KKyAqICAgKDIpIFRoZSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4KKyAqICAgICAgIHRoZSBmaWxlIExJQ0VOU0UtQlNELnR4dC4KKyAqCisgKiBUaGlzIHNvdXJjZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBmaWxlcworICogTElDRU5TRS1MR1BMLnR4dCBhbmQgTElDRU5TRS1CU0QudHh0IGZvciBtb3JlIGRldGFpbHMuCisgKgorICogJElkOiBhcHAuaCx2IDEuMTQgMjAwNS8wMi8wNiAyMToxMzo1NCB0b25pYyBFeHAgJAorICogJFJldmlzaW9uOiAxLjE0ICQKKyAqLworCisjaWZuZGVmIEFQUF9IX0lOQ0xVREVECisjZGVmaW5lIEFQUF9IX0lOQ0xVREVECisKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisKKyNkZWZpbmUgV0lORE9XX0RFRkFVTFRfV0lEVEggICAgNjQwCisjZGVmaW5lIFdJTkRPV19ERUZBVUxUX0hFSUdIVCAgIDQ4MAorCisjZGVmaW5lIFdJTkRPV19CUFAgICAgICAgICAgICAgIDE2CisKKworLy8gVGhlIHNpbXBsZSBmcmFtZXdvcmsgZXhwZWN0cyB0aGUgYXBwbGljYXRpb24gY29kZSB0byBkZWZpbmUgdGhlc2UgZnVuY3Rpb25zLgorZXh0ZXJuIHZvaWQgYXBwSW5pdCgpOworZXh0ZXJuIHZvaWQgYXBwRGVpbml0KCk7CitleHRlcm4gdm9pZCBhcHBSZW5kZXIobG9uZyB0aWNrLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpOworCisvKiBWYWx1ZSBpcyBub24temVybyB3aGVuIGFwcGxpY2F0aW9uIGlzIGFsaXZlLCBhbmQgMCB3aGVuIGl0IGlzIGNsb3NpbmcuCisgKiBEZWZpbmVkIGJ5IHRoZSBhcHBsaWNhdGlvbiBmcmFtZXdvcmsuCisgKi8KK2V4dGVybiBpbnQgZ0FwcEFsaXZlOworCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKworI2VuZGlmIC8vICFBUFBfSF9JTkNMVURFRApkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvY2Ftcy5oIGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvY2Ftcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMWFjYjMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9jYW1zLmgKQEAgLTAsMCArMSw2NSBAQAorLyogU2FuIEFuZ2VsZXMgT2JzZXJ2YXRpb24gT3BlbkdMIEVTIHZlcnNpb24gZXhhbXBsZQorICogQ29weXJpZ2h0IDIwMDQtMjAwNSBKZXRybyBMYXVoYQorICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFdlYjogaHR0cDovL2lraS5maS9qZXRyby8KKyAqCisgKiBUaGlzIHNvdXJjZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKKyAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgRUlUSEVSOgorICogICAoMSkgVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUKKyAqICAgICAgIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0CisgKiAgICAgICB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uIFRoZSB0ZXh0IG9mIHRoZSBHTlUgTGVzc2VyCisgKiAgICAgICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4gdGhlCisgKiAgICAgICBmaWxlIExJQ0VOU0UtTEdQTC50eHQuCisgKiAgICgyKSBUaGUgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBpcyBpbmNsdWRlZCB3aXRoIHRoaXMgc291cmNlIGluCisgKiAgICAgICB0aGUgZmlsZSBMSUNFTlNFLUJTRC50eHQuCisgKgorICogVGhpcyBzb3VyY2UgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgZmlsZXMKKyAqIExJQ0VOU0UtTEdQTC50eHQgYW5kIExJQ0VOU0UtQlNELnR4dCBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqICRJZDogY2Ftcy5oLHYgMS43IDIwMDUvMDEvMzEgMjI6MTU6MTUgdG9uaWMgRXhwICQKKyAqICRSZXZpc2lvbjogMS43ICQKKyAqLworCisjaWZuZGVmIENBTVNfSF9JTkNMVURFRAorI2RlZmluZSBDQU1TX0hfSU5DTFVERUQKKworCisvKiBMZW5ndGggaW4gbWlsbGlzZWNvbmRzIG9mIG9uZSBjYW1lcmEgdHJhY2sgYmFzZSB1bml0LgorICogVGhlIHZhbHVlIG9yaWdpbmF0ZXMgZnJvbSB0aGUgbXVzaWMgc3luY2hyb25pemF0aW9uLgorICovCisjZGVmaW5lIENBTVRSQUNLX0xFTiAgICA1NDQyCisKKworLy8gQ2FtZXJhIHRyYWNrIGRlZmluaXRpb24gZm9yIG9uZSBjYW1lcmEgdHJ1Y2tpbmcgc2hvdC4KK3R5cGVkZWYgc3RydWN0Cit7CisgICAgLyogRml2ZSBwYXJhbWV0ZXJzIG9mIHNyY1s1XSBhbmQgZGVzdFs1XToKKyAgICAgKiBleWVYLCBleWVZLCBleWVaLCB2aWV3QW5nbGUsIHZpZXdIZWlnaHRPZmZzCisgICAgICovCisgICAgc2hvcnQgc3JjWzVdLCBkZXN0WzVdOworICAgIHVuc2lnbmVkIGNoYXIgZGlzdDsgICAgIC8vIGlmID4wLCBjYW0gcm90YXRlcyBhcm91bmQgZXllIHh5IG9uIGRpc3QgKiAwLjEKKyAgICB1bnNpZ25lZCBjaGFyIGxlbjsgICAgICAvLyBsZW5ndGggbXVsdGlwbGllcgorfSBDQU1UUkFDSzsKKworc3RhdGljIENBTVRSQUNLIHNDYW1UcmFja3NbXSA9Cit7CisgICAgeyB7IDQ1MDAsIDI3MDAsIDEwMCwgNzAsIC0zMCB9LCB7IDUwLCA1MCwgLTkwLCAtMTAwLCAwIH0sIDIwLCAxIH0sCisgICAgeyB7IC0xNDQ4LCA0Mjk0LCAyNSwgMzYzLCAwIH0sIHsgLTEzNiwgMjAyLCAxMjUsIC05OCwgMTAwIH0sIDAsIDEgfSwKKyAgICB7IHsgMTQzNywgNDkzMCwgMjAwLCAtMjc1LCAtMjAgfSwgeyAxNjg0LCAwLCAwLCA5LCAwIH0sIDAsIDEgfSwKKyAgICB7IHsgMTgwMCwgMzYwOSwgMjAwLCAwLCA2NzUgfSwgeyAwLCAwLCAwLCAzMDAsIDAgfSwgMCwgMSB9LAorICAgIHsgeyA5MjMsIDk5NiwgNTAsIDIzMzYsIC04MCB9LCB7IDAsIC0yMCwgLTUwLCAwLCAxNzAgfSwgMCwgMSB9LAorICAgIHsgeyAtMTY2MywgLTQzLCA2MDAsIDIxNzAsIDAgfSwgeyAyMCwgMCwgLTYwMCwgMCwgMTAwIH0sIDAsIDEgfSwKKyAgICB7IHsgMTA0OSwgLTE0MjAsIDE3NSwgMjExMSwgLTE3IH0sIHsgMCwgMCwgMCwgLTMzNCwgMCB9LCAwLCAyIH0sCisgICAgeyB7IDAsIDAsIDUwLCAzMDAsIDI1IH0sIHsgMCwgMCwgMCwgMzAwLCAwIH0sIDcwLCAyIH0sCisgICAgeyB7IC00NzMsIC05NTMsIDM1MDAsIC0zNTMsIC0zNTAgfSwgeyAwLCAwLCAtMjgwMCwgMCwgMCB9LCAwLCAyIH0sCisgICAgeyB7IDE5MSwgMTkzOCwgMzUsIDExMzksIC0xNyB9LCB7IDEyMDUsIC0yOTA5LCAwLCAwLCAwIH0sIDAsIDIgfSwKKyAgICB7IHsgLTE0NDksIC0yNzAwLCAxNTAsIDAsIDAgfSwgeyAwLCAyMDAwLCAwLCAwLCAwIH0sIDAsIDIgfSwKKyAgICB7IHsgNTI3MywgNDk5MiwgNjUwLCAzNzMsIC01MCB9LCB7IC00NTk4LCAtMzA3MiwgMCwgMCwgMCB9LCAwLCAyIH0sCisgICAgeyB7IDMyMjMsIC0zMjgyLCAxMDc1LCAtMzkzLCAtMjUgfSwgeyAxNjQ5LCAtMTY0OSwgMCwgMCwgMCB9LCAwLCAyIH0KK307CisjZGVmaW5lIENBTVRSQUNLX0NPVU5UIChzaXplb2YoY2FtVHJhY2tzKSAvIHNpemVvZihjYW1UcmFja3NbMF0pKQorCisKKyNlbmRpZiAvLyAhQ0FNU19IX0lOQ0xVREVECmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9kZW1vLmMgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9kZW1vLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODAyZjM5OAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2RlbW8uYwpAQCAtMCwwICsxLDc5MiBAQAorLyogU2FuIEFuZ2VsZXMgT2JzZXJ2YXRpb24gT3BlbkdMIEVTIHZlcnNpb24gZXhhbXBsZQorICogQ29weXJpZ2h0IDIwMDQtMjAwNSBKZXRybyBMYXVoYQorICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFdlYjogaHR0cDovL2lraS5maS9qZXRyby8KKyAqCisgKiBUaGlzIHNvdXJjZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKKyAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgRUlUSEVSOgorICogICAoMSkgVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUKKyAqICAgICAgIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0CisgKiAgICAgICB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uIFRoZSB0ZXh0IG9mIHRoZSBHTlUgTGVzc2VyCisgKiAgICAgICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4gdGhlCisgKiAgICAgICBmaWxlIExJQ0VOU0UtTEdQTC50eHQuCisgKiAgICgyKSBUaGUgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBpcyBpbmNsdWRlZCB3aXRoIHRoaXMgc291cmNlIGluCisgKiAgICAgICB0aGUgZmlsZSBMSUNFTlNFLUJTRC50eHQuCisgKgorICogVGhpcyBzb3VyY2UgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgZmlsZXMKKyAqIExJQ0VOU0UtTEdQTC50eHQgYW5kIExJQ0VOU0UtQlNELnR4dCBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqICRJZDogZGVtby5jLHYgMS4xMCAyMDA1LzAyLzA4IDIwOjU0OjM5IHRvbmljIEV4cCAkCisgKiAkUmV2aXNpb246IDEuMTAgJAorICovCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8ZmxvYXQuaD4KKyNpbmNsdWRlIDxhc3NlcnQuaD4KKworI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2luY2x1ZGUgImFwcC5oIgorI2luY2x1ZGUgInNoYXBlcy5oIgorI2luY2x1ZGUgImNhbXMuaCIKKworCisvLyBUb3RhbCBydW4gbGVuZ3RoIGlzIDIwICogY2FtZXJhIHRyYWNrIGJhc2UgdW5pdCBsZW5ndGggKHNlZSBjYW1zLmgpLgorI2RlZmluZSBSVU5fTEVOR1RIICAoMjAgKiBDQU1UUkFDS19MRU4pCisjdW5kZWYgUEkKKyNkZWZpbmUgUEkgMy4xNDE1OTI2NTM1ODk3OTMyZgorI2RlZmluZSBSQU5ET01fVUlOVF9NQVggNjU1MzUKKworCitzdGF0aWMgdW5zaWduZWQgbG9uZyBzUmFuZG9tU2VlZCA9IDA7CisKK3N0YXRpYyB2b2lkIHNlZWRSYW5kb20odW5zaWduZWQgbG9uZyBzZWVkKQoreworICAgIHNSYW5kb21TZWVkID0gc2VlZDsKK30KKworc3RhdGljIHVuc2lnbmVkIGxvbmcgcmFuZG9tVUludCgpCit7CisgICAgc1JhbmRvbVNlZWQgPSBzUmFuZG9tU2VlZCAqIDB4MzQzZmQgKyAweDI2OWVjMzsKKyAgICByZXR1cm4gc1JhbmRvbVNlZWQgPj4gMTY7Cit9CisKKworLy8gQ2FwcGVkIGNvbnZlcnNpb24gZnJvbSBmbG9hdCB0byBmaXhlZC4KK3N0YXRpYyBsb25nIGZsb2F0VG9GaXhlZChmbG9hdCB2YWx1ZSkKK3sKKyAgICBpZiAodmFsdWUgPCAtMzI3NjgpIHZhbHVlID0gLTMyNzY4OworICAgIGlmICh2YWx1ZSA+IDMyNzY3KSB2YWx1ZSA9IDMyNzY3OworICAgIHJldHVybiAobG9uZykodmFsdWUgKiA2NTUzNik7Cit9CisKKyNkZWZpbmUgRklYRUQodmFsdWUpIGZsb2F0VG9GaXhlZCh2YWx1ZSkKKworCisvLyBEZWZpbml0aW9uIG9mIG9uZSBHTCBvYmplY3QgaW4gdGhpcyBkZW1vLgordHlwZWRlZiBzdHJ1Y3QgeworICAgIC8qIFZlcnRleCBhcnJheSBhbmQgY29sb3IgYXJyYXkgYXJlIGVuYWJsZWQgZm9yIGFsbCBvYmplY3RzLCBzbyB0aGVpcgorICAgICAqIHBvaW50ZXJzIG11c3QgYWx3YXlzIGJlIHZhbGlkIGFuZCBub24tTlVMTC4gTm9ybWFsIGFycmF5IGlzIG5vdAorICAgICAqIHVzZWQgYnkgdGhlIGdyb3VuZCBwbGFuZSwgc28gd2hlbiBpdHMgcG9pbnRlciBpcyBOVUxMIHRoZW4gbm9ybWFsCisgICAgICogYXJyYXkgdXNhZ2UgaXMgZGlzYWJsZWQuCisgICAgICoKKyAgICAgKiBWZXJ0ZXggYXJyYXkgaXMgc3VwcG9zZWQgdG8gdXNlIEdMX0ZJWEVEIGRhdGF0eXBlIGFuZCBzdHJpZGUgMAorICAgICAqIChpLmUuIHRpZ2h0bHkgcGFja2VkIGFycmF5KS4gQ29sb3IgYXJyYXkgaXMgc3VwcG9zZWQgdG8gaGF2ZSA0CisgICAgICogY29tcG9uZW50cyBwZXIgY29sb3Igd2l0aCBHTF9VTlNJR05FRF9CWVRFIGRhdGF0eXBlIGFuZCBzdHJpZGUgMC4KKyAgICAgKiBOb3JtYWwgYXJyYXkgaXMgc3VwcG9zZWQgdG8gdXNlIEdMX0ZJWEVEIGRhdGF0eXBlIGFuZCBzdHJpZGUgMC4KKyAgICAgKi8KKyAgICBHTGZpeGVkICp2ZXJ0ZXhBcnJheTsKKyAgICBHTHVieXRlICpjb2xvckFycmF5OworICAgIEdMZml4ZWQgKm5vcm1hbEFycmF5OworICAgIEdMaW50IHZlcnRleENvbXBvbmVudHM7CisgICAgR0xzaXplaSBjb3VudDsKK30gR0xPQkpFQ1Q7CisKKworc3RhdGljIGxvbmcgc1N0YXJ0VGljayA9IDA7CitzdGF0aWMgbG9uZyBzVGljayA9IDA7CisKK3N0YXRpYyBpbnQgc0N1cnJlbnRDYW1UcmFjayA9IDA7CitzdGF0aWMgbG9uZyBzQ3VycmVudENhbVRyYWNrU3RhcnRUaWNrID0gMDsKK3N0YXRpYyBsb25nIHNOZXh0Q2FtVHJhY2tTdGFydFRpY2sgPSAweDdmZmZmZmZmOworCitzdGF0aWMgR0xPQkpFQ1QgKnNTdXBlclNoYXBlT2JqZWN0c1tTVVBFUlNIQVBFX0NPVU5UXSA9IHsgTlVMTCB9Oworc3RhdGljIEdMT0JKRUNUICpzR3JvdW5kUGxhbmUgPSBOVUxMOworCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBmbG9hdCB4LCB5LCB6OworfSBWRUNUT1IzOworCisKK3N0YXRpYyB2b2lkIGZyZWVHTE9iamVjdChHTE9CSkVDVCAqb2JqZWN0KQoreworICAgIGlmIChvYmplY3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIGZyZWUob2JqZWN0LT5ub3JtYWxBcnJheSk7CisgICAgZnJlZShvYmplY3QtPmNvbG9yQXJyYXkpOworICAgIGZyZWUob2JqZWN0LT52ZXJ0ZXhBcnJheSk7CisgICAgZnJlZShvYmplY3QpOworfQorCisKK3N0YXRpYyBHTE9CSkVDVCAqIG5ld0dMT2JqZWN0KGxvbmcgdmVydGljZXMsIGludCB2ZXJ0ZXhDb21wb25lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHVzZU5vcm1hbEFycmF5KQoreworICAgIEdMT0JKRUNUICpyZXN1bHQ7CisgICAgcmVzdWx0ID0gKEdMT0JKRUNUICopbWFsbG9jKHNpemVvZihHTE9CSkVDVCkpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0LT5jb3VudCA9IHZlcnRpY2VzOworICAgIHJlc3VsdC0+dmVydGV4Q29tcG9uZW50cyA9IHZlcnRleENvbXBvbmVudHM7CisgICAgcmVzdWx0LT52ZXJ0ZXhBcnJheSA9IChHTGZpeGVkICopbWFsbG9jKHZlcnRpY2VzICogdmVydGV4Q29tcG9uZW50cyAqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihHTGZpeGVkKSk7CisgICAgcmVzdWx0LT5jb2xvckFycmF5ID0gKEdMdWJ5dGUgKiltYWxsb2ModmVydGljZXMgKiA0ICogc2l6ZW9mKEdMdWJ5dGUpKTsKKyAgICBpZiAodXNlTm9ybWFsQXJyYXkpCisgICAgeworICAgICAgICByZXN1bHQtPm5vcm1hbEFycmF5ID0gKEdMZml4ZWQgKiltYWxsb2ModmVydGljZXMgKiAzICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihHTGZpeGVkKSk7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmVzdWx0LT5ub3JtYWxBcnJheSA9IE5VTEw7CisgICAgaWYgKHJlc3VsdC0+dmVydGV4QXJyYXkgPT0gTlVMTCB8fAorICAgICAgICByZXN1bHQtPmNvbG9yQXJyYXkgPT0gTlVMTCB8fAorICAgICAgICAodXNlTm9ybWFsQXJyYXkgJiYgcmVzdWx0LT5ub3JtYWxBcnJheSA9PSBOVUxMKSkKKyAgICB7CisgICAgICAgIGZyZWVHTE9iamVjdChyZXN1bHQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCitzdGF0aWMgdm9pZCBkcmF3R0xPYmplY3QoR0xPQkpFQ1QgKm9iamVjdCkKK3sKKyAgICBhc3NlcnQob2JqZWN0ICE9IE5VTEwpOworCisgICAgZ2xWZXJ0ZXhQb2ludGVyKG9iamVjdC0+dmVydGV4Q29tcG9uZW50cywgR0xfRklYRUQsCisgICAgICAgICAgICAgICAgICAgIDAsIG9iamVjdC0+dmVydGV4QXJyYXkpOworICAgIGdsQ29sb3JQb2ludGVyKDQsIEdMX1VOU0lHTkVEX0JZVEUsIDAsIG9iamVjdC0+Y29sb3JBcnJheSk7CisKKyAgICAvLyBBbHJlYWR5IGRvbmUgaW4gaW5pdGlhbGl6YXRpb246CisgICAgLy9nbEVuYWJsZUNsaWVudFN0YXRlKEdMX1ZFUlRFWF9BUlJBWSk7CisgICAgLy9nbEVuYWJsZUNsaWVudFN0YXRlKEdMX0NPTE9SX0FSUkFZKTsKKworICAgIGlmIChvYmplY3QtPm5vcm1hbEFycmF5KQorICAgIHsKKyAgICAgICAgZ2xOb3JtYWxQb2ludGVyKEdMX0ZJWEVELCAwLCBvYmplY3QtPm5vcm1hbEFycmF5KTsKKyAgICAgICAgZ2xFbmFibGVDbGllbnRTdGF0ZShHTF9OT1JNQUxfQVJSQVkpOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGdsRGlzYWJsZUNsaWVudFN0YXRlKEdMX05PUk1BTF9BUlJBWSk7CisgICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgb2JqZWN0LT5jb3VudCk7Cit9CisKKworc3RhdGljIHZvaWQgdmVjdG9yM1N1YihWRUNUT1IzICpkZXN0LCBWRUNUT1IzICp2MSwgVkVDVE9SMyAqdjIpCit7CisgICAgZGVzdC0+eCA9IHYxLT54IC0gdjItPng7CisgICAgZGVzdC0+eSA9IHYxLT55IC0gdjItPnk7CisgICAgZGVzdC0+eiA9IHYxLT56IC0gdjItPno7Cit9CisKKworc3RhdGljIHZvaWQgc3VwZXJTaGFwZU1hcChWRUNUT1IzICpwb2ludCwgZmxvYXQgcjEsIGZsb2F0IHIyLCBmbG9hdCB0LCBmbG9hdCBwKQoreworICAgIC8vIHNwaGVyZS1tYXBwaW5nIG9mIHN1cGVyc2hhcGUgcGFyYW1ldGVycworICAgIHBvaW50LT54ID0gKGZsb2F0KShjb3ModCkgKiBjb3MocCkgLyByMSAvIHIyKTsKKyAgICBwb2ludC0+eSA9IChmbG9hdCkoc2luKHQpICogY29zKHApIC8gcjEgLyByMik7CisgICAgcG9pbnQtPnogPSAoZmxvYXQpKHNpbihwKSAvIHIyKTsKK30KKworCitzdGF0aWMgZmxvYXQgc3NGdW5jKGNvbnN0IGZsb2F0IHQsIGNvbnN0IGZsb2F0ICpwKQoreworICAgIHJldHVybiAoZmxvYXQpKHBvdyhwb3coZmFicyhjb3MocFswXSAqIHQgLyA0KSkgLyBwWzFdLCBwWzRdKSArCisgICAgICAgICAgICAgICAgICAgICAgIHBvdyhmYWJzKHNpbihwWzBdICogdCAvIDQpKSAvIHBbMl0sIHBbNV0pLCAxIC8gcFszXSkpOworfQorCisKKy8vIENyZWF0ZXMgYW5kIHJldHVybnMgYSBzdXBlcnNoYXBlIG9iamVjdC4KKy8vIEJhc2VkIG9uIFBhdWwgQm91cmtlJ3MgUE9WLVJheSBpbXBsZW1lbnRhdGlvbi4KKy8vIGh0dHA6Ly9hc3Ryb25vbXkuc3dpbi5lZHUuYXUvfnBib3Vya2UvcG92cmF5L3N1cGVyc2hhcGUvCitzdGF0aWMgR0xPQkpFQ1QgKiBjcmVhdGVTdXBlclNoYXBlKGNvbnN0IGZsb2F0ICpwYXJhbXMpCit7CisgICAgY29uc3QgaW50IHJlc29sMSA9IChpbnQpcGFyYW1zW1NVUEVSU0hBUEVfUEFSQU1TIC0gM107CisgICAgY29uc3QgaW50IHJlc29sMiA9IChpbnQpcGFyYW1zW1NVUEVSU0hBUEVfUEFSQU1TIC0gMl07CisgICAgLy8gbGF0aXR1ZGUgMCB0byBwaS8yIGZvciBubyBtaXJyb3JlZCBib3R0b20KKyAgICAvLyAobGF0aXR1ZGVCZWdpbj09MCBmb3IgLXBpLzIgdG8gcGkvMiBvcmlnaW5hbGx5KQorICAgIGNvbnN0IGludCBsYXRpdHVkZUJlZ2luID0gcmVzb2wyIC8gNDsKKyAgICBjb25zdCBpbnQgbGF0aXR1ZGVFbmQgPSByZXNvbDIgLyAyOyAgICAvLyBub24taW5jbHVzaXZlCisgICAgY29uc3QgaW50IGxvbmdpdHVkZUNvdW50ID0gcmVzb2wxOworICAgIGNvbnN0IGludCBsYXRpdHVkZUNvdW50ID0gbGF0aXR1ZGVFbmQgLSBsYXRpdHVkZUJlZ2luOworICAgIGNvbnN0IGxvbmcgdHJpYW5nbGVDb3VudCA9IGxvbmdpdHVkZUNvdW50ICogbGF0aXR1ZGVDb3VudCAqIDI7CisgICAgY29uc3QgbG9uZyB2ZXJ0aWNlcyA9IHRyaWFuZ2xlQ291bnQgKiAzOworICAgIEdMT0JKRUNUICpyZXN1bHQ7CisgICAgZmxvYXQgYmFzZUNvbG9yWzNdOworICAgIGludCBhLCBsb25naXR1ZGUsIGxhdGl0dWRlOworICAgIGxvbmcgY3VycmVudFZlcnRleCwgY3VycmVudFF1YWQ7CisKKyAgICByZXN1bHQgPSBuZXdHTE9iamVjdCh2ZXJ0aWNlcywgMywgMSk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGZvciAoYSA9IDA7IGEgPCAzOyArK2EpCisgICAgICAgIGJhc2VDb2xvclthXSA9ICgocmFuZG9tVUludCgpICUgMTU1KSArIDEwMCkgLyAyNTUuZjsKKworICAgIGN1cnJlbnRRdWFkID0gMDsKKyAgICBjdXJyZW50VmVydGV4ID0gMDsKKworICAgIC8vIGxvbmdpdHVkZSAtcGkgdG8gcGkKKyAgICBmb3IgKGxvbmdpdHVkZSA9IDA7IGxvbmdpdHVkZSA8IGxvbmdpdHVkZUNvdW50OyArK2xvbmdpdHVkZSkKKyAgICB7CisKKyAgICAgICAgLy8gbGF0aXR1ZGUgMCB0byBwaS8yCisgICAgICAgIGZvciAobGF0aXR1ZGUgPSBsYXRpdHVkZUJlZ2luOyBsYXRpdHVkZSA8IGxhdGl0dWRlRW5kOyArK2xhdGl0dWRlKQorICAgICAgICB7CisgICAgICAgICAgICBmbG9hdCB0MSA9IC1QSSArIGxvbmdpdHVkZSAqIDIgKiBQSSAvIHJlc29sMTsKKyAgICAgICAgICAgIGZsb2F0IHQyID0gLVBJICsgKGxvbmdpdHVkZSArIDEpICogMiAqIFBJIC8gcmVzb2wxOworICAgICAgICAgICAgZmxvYXQgcDEgPSAtUEkgLyAyICsgbGF0aXR1ZGUgKiAyICogUEkgLyByZXNvbDI7CisgICAgICAgICAgICBmbG9hdCBwMiA9IC1QSSAvIDIgKyAobGF0aXR1ZGUgKyAxKSAqIDIgKiBQSSAvIHJlc29sMjsKKyAgICAgICAgICAgIGZsb2F0IHIwLCByMSwgcjIsIHIzOworCisgICAgICAgICAgICByMCA9IHNzRnVuYyh0MSwgcGFyYW1zKTsKKyAgICAgICAgICAgIHIxID0gc3NGdW5jKHAxLCAmcGFyYW1zWzZdKTsKKyAgICAgICAgICAgIHIyID0gc3NGdW5jKHQyLCBwYXJhbXMpOworICAgICAgICAgICAgcjMgPSBzc0Z1bmMocDIsICZwYXJhbXNbNl0pOworCisgICAgICAgICAgICBpZiAocjAgIT0gMCAmJiByMSAhPSAwICYmIHIyICE9IDAgJiYgcjMgIT0gMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBWRUNUT1IzIHBhLCBwYiwgcGMsIHBkOworICAgICAgICAgICAgICAgIFZFQ1RPUjMgdjEsIHYyLCBuOworICAgICAgICAgICAgICAgIGZsb2F0IGNhOworICAgICAgICAgICAgICAgIGludCBpOworICAgICAgICAgICAgICAgIC8vZmxvYXQgbGVuU3EsIGludkxlblNxOworCisgICAgICAgICAgICAgICAgc3VwZXJTaGFwZU1hcCgmcGEsIHIwLCByMSwgdDEsIHAxKTsKKyAgICAgICAgICAgICAgICBzdXBlclNoYXBlTWFwKCZwYiwgcjIsIHIxLCB0MiwgcDEpOworICAgICAgICAgICAgICAgIHN1cGVyU2hhcGVNYXAoJnBjLCByMiwgcjMsIHQyLCBwMik7CisgICAgICAgICAgICAgICAgc3VwZXJTaGFwZU1hcCgmcGQsIHIwLCByMywgdDEsIHAyKTsKKworICAgICAgICAgICAgICAgIC8vIGtsdWRnZSB0byBzZXQgbG93ZXIgZWRnZSBvZiB0aGUgb2JqZWN0IHRvIGZpeGVkIGxldmVsCisgICAgICAgICAgICAgICAgaWYgKGxhdGl0dWRlID09IGxhdGl0dWRlQmVnaW4gKyAxKQorICAgICAgICAgICAgICAgICAgICBwYS56ID0gcGIueiA9IDA7CisKKyAgICAgICAgICAgICAgICB2ZWN0b3IzU3ViKCZ2MSwgJnBiLCAmcGEpOworICAgICAgICAgICAgICAgIHZlY3RvcjNTdWIoJnYyLCAmcGQsICZwYSk7CisKKyAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgbm9ybWFsIHdpdGggY3Jvc3MgcHJvZHVjdC4KKyAgICAgICAgICAgICAgICAvKiAgIGkgICAgaiAgICBrICAgICAgaSAgICBqCisgICAgICAgICAgICAgICAgICogdjEueCB2MS55IHYxLnogfCB2MS54IHYxLnkKKyAgICAgICAgICAgICAgICAgKiB2Mi54IHYyLnkgdjIueiB8IHYyLnggdjIueQorICAgICAgICAgICAgICAgICAqLworCisgICAgICAgICAgICAgICAgbi54ID0gdjEueSAqIHYyLnogLSB2MS56ICogdjIueTsKKyAgICAgICAgICAgICAgICBuLnkgPSB2MS56ICogdjIueCAtIHYxLnggKiB2Mi56OworICAgICAgICAgICAgICAgIG4ueiA9IHYxLnggKiB2Mi55IC0gdjEueSAqIHYyLng7CisKKyAgICAgICAgICAgICAgICAvKiBQcmUtbm9ybWFsaXphdGlvbiBvZiB0aGUgbm9ybWFscyBpcyBkaXNhYmxlZCBoZXJlIGJlY2F1c2UKKyAgICAgICAgICAgICAgICAgKiB0aGV5IHdpbGwgYmUgbm9ybWFsaXplZCBhbnl3YXkgbGF0ZXIgZHVlIHRvIGF1dG9tYXRpYworICAgICAgICAgICAgICAgICAqIG5vcm1hbGl6YXRpb24gKEdMX05PUk1BTElaRSkuIEl0IGlzIGVuYWJsZWQgYmVjYXVzZSB0aGUKKyAgICAgICAgICAgICAgICAgKiBvYmplY3RzIGFyZSBzY2FsZWQgd2l0aCBnbFNjYWxlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgbGVuU3EgPSBuLnggKiBuLnggKyBuLnkgKiBuLnkgKyBuLnogKiBuLno7CisgICAgICAgICAgICAgICAgaW52TGVuU3EgPSAoZmxvYXQpKDEgLyBzcXJ0KGxlblNxKSk7CisgICAgICAgICAgICAgICAgbi54ICo9IGludkxlblNxOworICAgICAgICAgICAgICAgIG4ueSAqPSBpbnZMZW5TcTsKKyAgICAgICAgICAgICAgICBuLnogKj0gaW52TGVuU3E7CisgICAgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgICAgIGNhID0gcGEueiArIDAuNWY7CisKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSBjdXJyZW50VmVydGV4ICogMzsKKyAgICAgICAgICAgICAgICAgICAgIGkgPCAoY3VycmVudFZlcnRleCArIDYpICogMzsKKyAgICAgICAgICAgICAgICAgICAgIGkgKz0gMykKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC0+bm9ybWFsQXJyYXlbaV0gPSBGSVhFRChuLngpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQtPm5vcm1hbEFycmF5W2kgKyAxXSA9IEZJWEVEKG4ueSk7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC0+bm9ybWFsQXJyYXlbaSArIDJdID0gRklYRUQobi56KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpID0gY3VycmVudFZlcnRleCAqIDQ7CisgICAgICAgICAgICAgICAgICAgICBpIDwgKGN1cnJlbnRWZXJ0ZXggKyA2KSAqIDQ7CisgICAgICAgICAgICAgICAgICAgICBpICs9IDQpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBpbnQgYSwgY29sb3JbM107CisgICAgICAgICAgICAgICAgICAgIGZvciAoYSA9IDA7IGEgPCAzOyArK2EpCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yW2FdID0gKGludCkoY2EgKiBiYXNlQ29sb3JbYV0gKiAyNTUpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbG9yW2FdID4gMjU1KSBjb2xvclthXSA9IDI1NTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXN1bHQtPmNvbG9yQXJyYXlbaV0gPSAoR0x1Ynl0ZSljb2xvclswXTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LT5jb2xvckFycmF5W2kgKyAxXSA9IChHTHVieXRlKWNvbG9yWzFdOworICAgICAgICAgICAgICAgICAgICByZXN1bHQtPmNvbG9yQXJyYXlbaSArIDJdID0gKEdMdWJ5dGUpY29sb3JbMl07CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC0+Y29sb3JBcnJheVtpICsgM10gPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBhLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBhLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBhLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBiLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBiLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBiLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBkLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBkLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBkLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBiLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBiLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBiLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBjLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBjLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBjLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgICAgICByZXN1bHQtPnZlcnRleEFycmF5W2N1cnJlbnRWZXJ0ZXggKiAzXSA9IEZJWEVEKHBkLngpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAxXSA9IEZJWEVEKHBkLnkpOworICAgICAgICAgICAgICAgIHJlc3VsdC0+dmVydGV4QXJyYXlbY3VycmVudFZlcnRleCAqIDMgKyAyXSA9IEZJWEVEKHBkLnopOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgIH0gLy8gcjAgJiYgcjEgJiYgcjIgJiYgcjMKKyAgICAgICAgICAgICsrY3VycmVudFF1YWQ7CisgICAgICAgIH0gLy8gbGF0aXR1ZGUKKyAgICB9IC8vIGxvbmdpdHVkZQorCisgICAgLy8gU2V0IG51bWJlciBvZiB2ZXJ0aWNlcyBpbiBvYmplY3QgdG8gdGhlIGFjdHVhbCBhbW91bnQgY3JlYXRlZC4KKyAgICByZXN1bHQtPmNvdW50ID0gY3VycmVudFZlcnRleDsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworc3RhdGljIEdMT0JKRUNUICogY3JlYXRlR3JvdW5kUGxhbmUoKQoreworICAgIGNvbnN0IGludCBzY2FsZSA9IDQ7CisgICAgY29uc3QgaW50IHlCZWdpbiA9IC0xNSwgeUVuZCA9IDE1OyAgICAvLyBlbmRzIGFyZSBub24taW5jbHVzaXZlCisgICAgY29uc3QgaW50IHhCZWdpbiA9IC0xNSwgeEVuZCA9IDE1OworICAgIGNvbnN0IGxvbmcgdHJpYW5nbGVDb3VudCA9ICh5RW5kIC0geUJlZ2luKSAqICh4RW5kIC0geEJlZ2luKSAqIDI7CisgICAgY29uc3QgbG9uZyB2ZXJ0aWNlcyA9IHRyaWFuZ2xlQ291bnQgKiAzOworICAgIEdMT0JKRUNUICpyZXN1bHQ7CisgICAgaW50IHgsIHk7CisgICAgbG9uZyBjdXJyZW50VmVydGV4LCBjdXJyZW50UXVhZDsKKworICAgIHJlc3VsdCA9IG5ld0dMT2JqZWN0KHZlcnRpY2VzLCAyLCAwKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgY3VycmVudFF1YWQgPSAwOworICAgIGN1cnJlbnRWZXJ0ZXggPSAwOworCisgICAgZm9yICh5ID0geUJlZ2luOyB5IDwgeUVuZDsgKyt5KQorICAgIHsKKyAgICAgICAgZm9yICh4ID0geEJlZ2luOyB4IDwgeEVuZDsgKyt4KQorICAgICAgICB7CisgICAgICAgICAgICBHTHVieXRlIGNvbG9yOworICAgICAgICAgICAgaW50IGksIGE7CisgICAgICAgICAgICBjb2xvciA9IChHTHVieXRlKSgocmFuZG9tVUludCgpICYgMHg1ZikgKyA4MSk7ICAvLyAxMDEgMTExMQorICAgICAgICAgICAgZm9yIChpID0gY3VycmVudFZlcnRleCAqIDQ7IGkgPCAoY3VycmVudFZlcnRleCArIDYpICogNDsgaSArPSA0KQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHJlc3VsdC0+Y29sb3JBcnJheVtpXSA9IGNvbG9yOworICAgICAgICAgICAgICAgIHJlc3VsdC0+Y29sb3JBcnJheVtpICsgMV0gPSBjb2xvcjsKKyAgICAgICAgICAgICAgICByZXN1bHQtPmNvbG9yQXJyYXlbaSArIDJdID0gY29sb3I7CisgICAgICAgICAgICAgICAgcmVzdWx0LT5jb2xvckFycmF5W2kgKyAzXSA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEF4aXMgYml0cyBmb3IgcXVhZCB0cmlhbmdsZXM6CisgICAgICAgICAgICAvLyB4OiAwMTExMDAgKDB4MWMpLCB5OiAxMTAwMDEgKDB4MzEpICAoY2xvY2t3aXNlKQorICAgICAgICAgICAgLy8geDogMDAxMTEwICgweDBlKSwgeTogMTAwMDExICgweDIzKSAgKGNvdW50ZXItY2xvY2t3aXNlKQorICAgICAgICAgICAgZm9yIChhID0gMDsgYSA8IDY7ICsrYSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjb25zdCBpbnQgeG0gPSB4ICsgKCgweDFjID4+IGEpICYgMSk7CisgICAgICAgICAgICAgICAgY29uc3QgaW50IHltID0geSArICgoMHgzMSA+PiBhKSAmIDEpOworICAgICAgICAgICAgICAgIGNvbnN0IGZsb2F0IG0gPSAoZmxvYXQpKGNvcyh4bSAqIDIpICogc2luKHltICogNCkgKiAwLjc1Zik7CisgICAgICAgICAgICAgICAgcmVzdWx0LT52ZXJ0ZXhBcnJheVtjdXJyZW50VmVydGV4ICogMl0gPQorICAgICAgICAgICAgICAgICAgICBGSVhFRCh4bSAqIHNjYWxlICsgbSk7CisgICAgICAgICAgICAgICAgcmVzdWx0LT52ZXJ0ZXhBcnJheVtjdXJyZW50VmVydGV4ICogMiArIDFdID0KKyAgICAgICAgICAgICAgICAgICAgRklYRUQoeW0gKiBzY2FsZSArIG0pOworICAgICAgICAgICAgICAgICsrY3VycmVudFZlcnRleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICsrY3VycmVudFF1YWQ7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCitzdGF0aWMgdm9pZCBkcmF3R3JvdW5kUGxhbmUoKQoreworICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOworICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsKKyAgICBnbEVuYWJsZShHTF9CTEVORCk7CisgICAgZ2xCbGVuZEZ1bmMoR0xfWkVSTywgR0xfU1JDX0NPTE9SKTsKKyAgICBnbERpc2FibGUoR0xfTElHSFRJTkcpOworCisgICAgZHJhd0dMT2JqZWN0KHNHcm91bmRQbGFuZSk7CisKKyAgICBnbEVuYWJsZShHTF9MSUdIVElORyk7CisgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKKyAgICBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKK30KKworCitzdGF0aWMgdm9pZCBkcmF3RmFkZVF1YWQoKQoreworICAgIHN0YXRpYyBjb25zdCBHTGZpeGVkIHF1YWRWZXJ0aWNlc1tdID0geworICAgICAgICAtMHgxMDAwMCwgLTB4MTAwMDAsCisgICAgICAgICAweDEwMDAwLCAtMHgxMDAwMCwKKyAgICAgICAgLTB4MTAwMDAsICAweDEwMDAwLAorICAgICAgICAgMHgxMDAwMCwgLTB4MTAwMDAsCisgICAgICAgICAweDEwMDAwLCAgMHgxMDAwMCwKKyAgICAgICAgLTB4MTAwMDAsICAweDEwMDAwCisgICAgfTsKKworICAgIGNvbnN0IGludCBiZWdpbkZhZGUgPSBzVGljayAtIHNDdXJyZW50Q2FtVHJhY2tTdGFydFRpY2s7CisgICAgY29uc3QgaW50IGVuZEZhZGUgPSBzTmV4dENhbVRyYWNrU3RhcnRUaWNrIC0gc1RpY2s7CisgICAgY29uc3QgaW50IG1pbkZhZGUgPSBiZWdpbkZhZGUgPCBlbmRGYWRlID8gYmVnaW5GYWRlIDogZW5kRmFkZTsKKworICAgIGlmIChtaW5GYWRlIDwgMTAyNCkKKyAgICB7CisgICAgICAgIGNvbnN0IEdMZml4ZWQgZmFkZUNvbG9yID0gbWluRmFkZSA8PCA2OworICAgICAgICBnbENvbG9yNHgoZmFkZUNvbG9yLCBmYWRlQ29sb3IsIGZhZGVDb2xvciwgMCk7CisKKyAgICAgICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOworICAgICAgICBnbEVuYWJsZShHTF9CTEVORCk7CisgICAgICAgIGdsQmxlbmRGdW5jKEdMX1pFUk8sIEdMX1NSQ19DT0xPUik7CisgICAgICAgIGdsRGlzYWJsZShHTF9MSUdIVElORyk7CisKKyAgICAgICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7CisgICAgICAgIGdsTG9hZElkZW50aXR5KCk7CisKKyAgICAgICAgZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pOworICAgICAgICBnbExvYWRJZGVudGl0eSgpOworCisgICAgICAgIGdsRGlzYWJsZUNsaWVudFN0YXRlKEdMX0NPTE9SX0FSUkFZKTsKKyAgICAgICAgZ2xEaXNhYmxlQ2xpZW50U3RhdGUoR0xfTk9STUFMX0FSUkFZKTsKKyAgICAgICAgZ2xWZXJ0ZXhQb2ludGVyKDIsIEdMX0ZJWEVELCAwLCBxdWFkVmVydGljZXMpOworICAgICAgICBnbERyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCA2KTsKKworICAgICAgICBnbEVuYWJsZUNsaWVudFN0YXRlKEdMX0NPTE9SX0FSUkFZKTsKKworICAgICAgICBnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKKworICAgICAgICBnbEVuYWJsZShHTF9MSUdIVElORyk7CisgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CisgICAgICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOworICAgIH0KK30KKworCisvLyBDYWxsZWQgZnJvbSB0aGUgYXBwIGZyYW1ld29yay4KK3ZvaWQgYXBwSW5pdCgpCit7CisgICAgaW50IGE7CisKKyAgICBnbEVuYWJsZShHTF9OT1JNQUxJWkUpOworICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOworICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOworICAgIGdsU2hhZGVNb2RlbChHTF9GTEFUKTsKKworICAgIGdsRW5hYmxlKEdMX0xJR0hUSU5HKTsKKyAgICBnbEVuYWJsZShHTF9MSUdIVDApOworICAgIGdsRW5hYmxlKEdMX0xJR0hUMSk7CisgICAgZ2xFbmFibGUoR0xfTElHSFQyKTsKKworICAgIGdsRW5hYmxlQ2xpZW50U3RhdGUoR0xfVkVSVEVYX0FSUkFZKTsKKyAgICBnbEVuYWJsZUNsaWVudFN0YXRlKEdMX0NPTE9SX0FSUkFZKTsKKworICAgIHNlZWRSYW5kb20oMTUpOworCisgICAgZm9yIChhID0gMDsgYSA8IFNVUEVSU0hBUEVfQ09VTlQ7ICsrYSkKKyAgICB7CisgICAgICAgIHNTdXBlclNoYXBlT2JqZWN0c1thXSA9IGNyZWF0ZVN1cGVyU2hhcGUoc1N1cGVyU2hhcGVQYXJhbXNbYV0pOworICAgICAgICBhc3NlcnQoc1N1cGVyU2hhcGVPYmplY3RzW2FdICE9IE5VTEwpOworICAgIH0KKyAgICBzR3JvdW5kUGxhbmUgPSBjcmVhdGVHcm91bmRQbGFuZSgpOworICAgIGFzc2VydChzR3JvdW5kUGxhbmUgIT0gTlVMTCk7Cit9CisKKworLy8gQ2FsbGVkIGZyb20gdGhlIGFwcCBmcmFtZXdvcmsuCit2b2lkIGFwcERlaW5pdCgpCit7CisgICAgaW50IGE7CisgICAgZm9yIChhID0gMDsgYSA8IFNVUEVSU0hBUEVfQ09VTlQ7ICsrYSkKKyAgICAgICAgZnJlZUdMT2JqZWN0KHNTdXBlclNoYXBlT2JqZWN0c1thXSk7CisgICAgZnJlZUdMT2JqZWN0KHNHcm91bmRQbGFuZSk7Cit9CisKKworc3RhdGljIHZvaWQgZ2x1UGVyc3BlY3RpdmUoR0xmbG9hdCBmb3Z5LCBHTGZsb2F0IGFzcGVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZmxvYXQgek5lYXIsIEdMZmxvYXQgekZhcikKK3sKKyAgICBHTGZsb2F0IHhtaW4sIHhtYXgsIHltaW4sIHltYXg7CisKKyAgICB5bWF4ID0gek5lYXIgKiAoR0xmbG9hdCl0YW4oZm92eSAqIFBJIC8gMzYwKTsKKyAgICB5bWluID0gLXltYXg7CisgICAgeG1pbiA9IHltaW4gKiBhc3BlY3Q7CisgICAgeG1heCA9IHltYXggKiBhc3BlY3Q7CisKKyAgICBnbEZydXN0dW14KChHTGZpeGVkKSh4bWluICogNjU1MzYpLCAoR0xmaXhlZCkoeG1heCAqIDY1NTM2KSwKKyAgICAgICAgICAgICAgIChHTGZpeGVkKSh5bWluICogNjU1MzYpLCAoR0xmaXhlZCkoeW1heCAqIDY1NTM2KSwKKyAgICAgICAgICAgICAgIChHTGZpeGVkKSh6TmVhciAqIDY1NTM2KSwgKEdMZml4ZWQpKHpGYXIgKiA2NTUzNikpOworfQorCisKK3N0YXRpYyB2b2lkIHByZXBhcmVGcmFtZShpbnQgd2lkdGgsIGludCBoZWlnaHQpCit7CisgICAgZ2xWaWV3cG9ydCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKKworICAgIGdsQ2xlYXJDb2xvcngoKEdMZml4ZWQpKDAuMWYgKiA2NTUzNiksCisgICAgICAgICAgICAgICAgICAoR0xmaXhlZCkoMC4yZiAqIDY1NTM2KSwKKyAgICAgICAgICAgICAgICAgIChHTGZpeGVkKSgwLjNmICogNjU1MzYpLCAweDEwMDAwKTsKKyAgICBnbENsZWFyKEdMX0RFUFRIX0JVRkZFUl9CSVQgfCBHTF9DT0xPUl9CVUZGRVJfQklUKTsKKworICAgIGdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKTsKKyAgICBnbExvYWRJZGVudGl0eSgpOworICAgIGdsdVBlcnNwZWN0aXZlKDQ1LCAoZmxvYXQpd2lkdGggLyBoZWlnaHQsIDAuNWYsIDE1MCk7CisKKyAgICBnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKKworICAgIGdsTG9hZElkZW50aXR5KCk7Cit9CisKKworc3RhdGljIHZvaWQgY29uZmlndXJlTGlnaHRBbmRNYXRlcmlhbCgpCit7CisgICAgc3RhdGljIEdMZml4ZWQgbGlnaHQwUG9zaXRpb25bXSA9IHsgLTB4NDAwMDAsIDB4MTAwMDAsIDB4MTAwMDAsIDAgfTsKKyAgICBzdGF0aWMgR0xmaXhlZCBsaWdodDBEaWZmdXNlW10gPSB7IDB4MTAwMDAsIDB4NjY2NiwgMCwgMHgxMDAwMCB9OworICAgIHN0YXRpYyBHTGZpeGVkIGxpZ2h0MVBvc2l0aW9uW10gPSB7IDB4MTAwMDAsIC0weDIwMDAwLCAtMHgxMDAwMCwgMCB9OworICAgIHN0YXRpYyBHTGZpeGVkIGxpZ2h0MURpZmZ1c2VbXSA9IHsgMHgxMWViLCAweDIzZDcsIDB4NTk5OSwgMHgxMDAwMCB9OworICAgIHN0YXRpYyBHTGZpeGVkIGxpZ2h0MlBvc2l0aW9uW10gPSB7IC0weDEwMDAwLCAwLCAtMHg0MDAwMCwgMCB9OworICAgIHN0YXRpYyBHTGZpeGVkIGxpZ2h0MkRpZmZ1c2VbXSA9IHsgMHgxMWViLCAweDJiODUsIDB4MjNkNywgMHgxMDAwMCB9OworICAgIHN0YXRpYyBHTGZpeGVkIG1hdGVyaWFsU3BlY3VsYXJbXSA9IHsgMHgxMDAwMCwgMHgxMDAwMCwgMHgxMDAwMCwgMHgxMDAwMCB9OworCisgICAgZ2xMaWdodHh2KEdMX0xJR0hUMCwgR0xfUE9TSVRJT04sIGxpZ2h0MFBvc2l0aW9uKTsKKyAgICBnbExpZ2h0eHYoR0xfTElHSFQwLCBHTF9ESUZGVVNFLCBsaWdodDBEaWZmdXNlKTsKKyAgICBnbExpZ2h0eHYoR0xfTElHSFQxLCBHTF9QT1NJVElPTiwgbGlnaHQxUG9zaXRpb24pOworICAgIGdsTGlnaHR4dihHTF9MSUdIVDEsIEdMX0RJRkZVU0UsIGxpZ2h0MURpZmZ1c2UpOworICAgIGdsTGlnaHR4dihHTF9MSUdIVDIsIEdMX1BPU0lUSU9OLCBsaWdodDJQb3NpdGlvbik7CisgICAgZ2xMaWdodHh2KEdMX0xJR0hUMiwgR0xfRElGRlVTRSwgbGlnaHQyRGlmZnVzZSk7CisgICAgZ2xNYXRlcmlhbHh2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9TUEVDVUxBUiwgbWF0ZXJpYWxTcGVjdWxhcik7CisKKyAgICBnbE1hdGVyaWFseChHTF9GUk9OVF9BTkRfQkFDSywgR0xfU0hJTklORVNTLCA2MCA8PCAxNik7CisgICAgZ2xFbmFibGUoR0xfQ09MT1JfTUFURVJJQUwpOworfQorCisKK3N0YXRpYyB2b2lkIGRyYXdNb2RlbHMoZmxvYXQgelNjYWxlKQoreworICAgIGNvbnN0IGludCB0cmFuc2xhdGlvblNjYWxlID0gOTsKKyAgICBpbnQgeCwgeTsKKworICAgIHNlZWRSYW5kb20oOSk7CisKKyAgICBnbFNjYWxleCgxIDw8IDE2LCAxIDw8IDE2LCAoR0xmaXhlZCkoelNjYWxlICogNjU1MzYpKTsKKworICAgIGZvciAoeSA9IC01OyB5IDw9IDU7ICsreSkKKyAgICB7CisgICAgICAgIGZvciAoeCA9IC01OyB4IDw9IDU7ICsreCkKKyAgICAgICAgeworICAgICAgICAgICAgZmxvYXQgYnVpbGRpbmdTY2FsZTsKKyAgICAgICAgICAgIEdMZml4ZWQgZml4ZWRTY2FsZTsKKworICAgICAgICAgICAgaW50IGN1clNoYXBlID0gcmFuZG9tVUludCgpICUgU1VQRVJTSEFQRV9DT1VOVDsKKyAgICAgICAgICAgIGJ1aWxkaW5nU2NhbGUgPSBzU3VwZXJTaGFwZVBhcmFtc1tjdXJTaGFwZV1bU1VQRVJTSEFQRV9QQVJBTVMgLSAxXTsKKyAgICAgICAgICAgIGZpeGVkU2NhbGUgPSAoR0xmaXhlZCkoYnVpbGRpbmdTY2FsZSAqIDY1NTM2KTsKKworICAgICAgICAgICAgZ2xQdXNoTWF0cml4KCk7CisgICAgICAgICAgICBnbFRyYW5zbGF0ZXgoKHggKiB0cmFuc2xhdGlvblNjYWxlKSAqIDY1NTM2LAorICAgICAgICAgICAgICAgICAgICAgICAgICh5ICogdHJhbnNsYXRpb25TY2FsZSkgKiA2NTUzNiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgICAgIGdsUm90YXRleCgoR0xmaXhlZCkoKHJhbmRvbVVJbnQoKSAlIDM2MCkgPDwgMTYpLCAwLCAwLCAxIDw8IDE2KTsKKyAgICAgICAgICAgIGdsU2NhbGV4KGZpeGVkU2NhbGUsIGZpeGVkU2NhbGUsIGZpeGVkU2NhbGUpOworCisgICAgICAgICAgICBkcmF3R0xPYmplY3Qoc1N1cGVyU2hhcGVPYmplY3RzW2N1clNoYXBlXSk7CisgICAgICAgICAgICBnbFBvcE1hdHJpeCgpOworICAgICAgICB9CisgICAgfQorCisgICAgZm9yICh4ID0gLTI7IHggPD0gMjsgKyt4KQorICAgIHsKKyAgICAgICAgY29uc3QgaW50IHNoaXBTY2FsZTEwMCA9IHRyYW5zbGF0aW9uU2NhbGUgKiA1MDA7CisgICAgICAgIGNvbnN0IGludCBvZmZzMTAwID0geCAqIHNoaXBTY2FsZTEwMCArIChzVGljayAlIHNoaXBTY2FsZTEwMCk7CisgICAgICAgIGZsb2F0IG9mZnMgPSBvZmZzMTAwICogMC4wMWY7CisgICAgICAgIEdMZml4ZWQgZml4ZWRPZmZzID0gKEdMZml4ZWQpKG9mZnMgKiA2NTUzNik7CisgICAgICAgIGdsUHVzaE1hdHJpeCgpOworICAgICAgICBnbFRyYW5zbGF0ZXgoZml4ZWRPZmZzLCAtNCAqIDY1NTM2LCAyIDw8IDE2KTsKKyAgICAgICAgZHJhd0dMT2JqZWN0KHNTdXBlclNoYXBlT2JqZWN0c1tTVVBFUlNIQVBFX0NPVU5UIC0gMV0pOworICAgICAgICBnbFBvcE1hdHJpeCgpOworICAgICAgICBnbFB1c2hNYXRyaXgoKTsKKyAgICAgICAgZ2xUcmFuc2xhdGV4KC00ICogNjU1MzYsIGZpeGVkT2ZmcywgNCA8PCAxNik7CisgICAgICAgIGdsUm90YXRleCg5MCA8PCAxNiwgMCwgMCwgMSA8PCAxNik7CisgICAgICAgIGRyYXdHTE9iamVjdChzU3VwZXJTaGFwZU9iamVjdHNbU1VQRVJTSEFQRV9DT1VOVCAtIDFdKTsKKyAgICAgICAgZ2xQb3BNYXRyaXgoKTsKKyAgICB9Cit9CisKKworLyogRm9sbG93aW5nIGdsdUxvb2tBdCBpbXBsZW1lbnRhdGlvbiBpcyBhZGFwdGVkIGZyb20gdGhlCisgKiBNZXNhIDNEIEdyYXBoaWNzIGxpYnJhcnkuIGh0dHA6Ly93d3cubWVzYTNkLm9yZworICovCitzdGF0aWMgdm9pZCBnbHVMb29rQXQoR0xmbG9hdCBleWV4LCBHTGZsb2F0IGV5ZXksIEdMZmxvYXQgZXlleiwKKwkgICAgICAgICAgICAgIEdMZmxvYXQgY2VudGVyeCwgR0xmbG9hdCBjZW50ZXJ5LCBHTGZsb2F0IGNlbnRlcnosCisJICAgICAgICAgICAgICBHTGZsb2F0IHVweCwgR0xmbG9hdCB1cHksIEdMZmxvYXQgdXB6KQoreworICAgIEdMZmxvYXQgbVsxNl07CisgICAgR0xmbG9hdCB4WzNdLCB5WzNdLCB6WzNdOworICAgIEdMZmxvYXQgbWFnOworCisgICAgLyogTWFrZSByb3RhdGlvbiBtYXRyaXggKi8KKworICAgIC8qIFogdmVjdG9yICovCisgICAgelswXSA9IGV5ZXggLSBjZW50ZXJ4OworICAgIHpbMV0gPSBleWV5IC0gY2VudGVyeTsKKyAgICB6WzJdID0gZXlleiAtIGNlbnRlcno7CisgICAgbWFnID0gKGZsb2F0KXNxcnQoelswXSAqIHpbMF0gKyB6WzFdICogelsxXSArIHpbMl0gKiB6WzJdKTsKKyAgICBpZiAobWFnKSB7CQkJLyogbXBpY2hsZXIsIDE5OTUwNTE1ICovCisgICAgICAgIHpbMF0gLz0gbWFnOworICAgICAgICB6WzFdIC89IG1hZzsKKyAgICAgICAgelsyXSAvPSBtYWc7CisgICAgfQorCisgICAgLyogWSB2ZWN0b3IgKi8KKyAgICB5WzBdID0gdXB4OworICAgIHlbMV0gPSB1cHk7CisgICAgeVsyXSA9IHVwejsKKworICAgIC8qIFggdmVjdG9yID0gWSBjcm9zcyBaICovCisgICAgeFswXSA9IHlbMV0gKiB6WzJdIC0geVsyXSAqIHpbMV07CisgICAgeFsxXSA9IC15WzBdICogelsyXSArIHlbMl0gKiB6WzBdOworICAgIHhbMl0gPSB5WzBdICogelsxXSAtIHlbMV0gKiB6WzBdOworCisgICAgLyogUmVjb21wdXRlIFkgPSBaIGNyb3NzIFggKi8KKyAgICB5WzBdID0gelsxXSAqIHhbMl0gLSB6WzJdICogeFsxXTsKKyAgICB5WzFdID0gLXpbMF0gKiB4WzJdICsgelsyXSAqIHhbMF07CisgICAgeVsyXSA9IHpbMF0gKiB4WzFdIC0gelsxXSAqIHhbMF07CisKKyAgICAvKiBtcGljaGxlciwgMTk5NTA1MTUgKi8KKyAgICAvKiBjcm9zcyBwcm9kdWN0IGdpdmVzIGFyZWEgb2YgcGFyYWxsZWxvZ3JhbSwgd2hpY2ggaXMgPCAxLjAgZm9yCisgICAgICogbm9uLXBlcnBlbmRpY3VsYXIgdW5pdC1sZW5ndGggdmVjdG9yczsgc28gbm9ybWFsaXplIHgsIHkgaGVyZQorICAgICAqLworCisgICAgbWFnID0gKGZsb2F0KXNxcnQoeFswXSAqIHhbMF0gKyB4WzFdICogeFsxXSArIHhbMl0gKiB4WzJdKTsKKyAgICBpZiAobWFnKSB7CisgICAgICAgIHhbMF0gLz0gbWFnOworICAgICAgICB4WzFdIC89IG1hZzsKKyAgICAgICAgeFsyXSAvPSBtYWc7CisgICAgfQorCisgICAgbWFnID0gKGZsb2F0KXNxcnQoeVswXSAqIHlbMF0gKyB5WzFdICogeVsxXSArIHlbMl0gKiB5WzJdKTsKKyAgICBpZiAobWFnKSB7CisgICAgICAgIHlbMF0gLz0gbWFnOworICAgICAgICB5WzFdIC89IG1hZzsKKyAgICAgICAgeVsyXSAvPSBtYWc7CisgICAgfQorCisjZGVmaW5lIE0ocm93LGNvbCkgIG1bY29sKjQrcm93XQorICAgIE0oMCwgMCkgPSB4WzBdOworICAgIE0oMCwgMSkgPSB4WzFdOworICAgIE0oMCwgMikgPSB4WzJdOworICAgIE0oMCwgMykgPSAwLjA7CisgICAgTSgxLCAwKSA9IHlbMF07CisgICAgTSgxLCAxKSA9IHlbMV07CisgICAgTSgxLCAyKSA9IHlbMl07CisgICAgTSgxLCAzKSA9IDAuMDsKKyAgICBNKDIsIDApID0gelswXTsKKyAgICBNKDIsIDEpID0gelsxXTsKKyAgICBNKDIsIDIpID0gelsyXTsKKyAgICBNKDIsIDMpID0gMC4wOworICAgIE0oMywgMCkgPSAwLjA7CisgICAgTSgzLCAxKSA9IDAuMDsKKyAgICBNKDMsIDIpID0gMC4wOworICAgIE0oMywgMykgPSAxLjA7CisjdW5kZWYgTQorICAgIHsKKyAgICAgICAgaW50IGE7CisgICAgICAgIEdMZml4ZWQgZml4ZWRNWzE2XTsKKyAgICAgICAgZm9yIChhID0gMDsgYSA8IDE2OyArK2EpCisgICAgICAgICAgICBmaXhlZE1bYV0gPSAoR0xmaXhlZCkobVthXSAqIDY1NTM2KTsKKyAgICAgICAgZ2xNdWx0TWF0cml4eChmaXhlZE0pOworICAgIH0KKworICAgIC8qIFRyYW5zbGF0ZSBFeWUgdG8gT3JpZ2luICovCisgICAgZ2xUcmFuc2xhdGV4KChHTGZpeGVkKSgtZXlleCAqIDY1NTM2KSwKKyAgICAgICAgICAgICAgICAgKEdMZml4ZWQpKC1leWV5ICogNjU1MzYpLAorICAgICAgICAgICAgICAgICAoR0xmaXhlZCkoLWV5ZXogKiA2NTUzNikpOworfQorCisKK3N0YXRpYyB2b2lkIGNhbVRyYWNrKCkKK3sKKyAgICBmbG9hdCBsZXJwWzVdOworICAgIGZsb2F0IGVYLCBlWSwgZVosIGNYLCBjWSwgY1o7CisgICAgZmxvYXQgdHJhY2tQb3M7CisgICAgQ0FNVFJBQ0sgKmNhbTsKKyAgICBsb25nIGN1cnJlbnRDYW1UaWNrOworICAgIGludCBhOworCisgICAgaWYgKHNOZXh0Q2FtVHJhY2tTdGFydFRpY2sgPD0gc1RpY2spCisgICAgeworICAgICAgICArK3NDdXJyZW50Q2FtVHJhY2s7CisgICAgICAgIHNDdXJyZW50Q2FtVHJhY2tTdGFydFRpY2sgPSBzTmV4dENhbVRyYWNrU3RhcnRUaWNrOworICAgIH0KKyAgICBzTmV4dENhbVRyYWNrU3RhcnRUaWNrID0gc0N1cnJlbnRDYW1UcmFja1N0YXJ0VGljayArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNDYW1UcmFja3Nbc0N1cnJlbnRDYW1UcmFja10ubGVuICogQ0FNVFJBQ0tfTEVOOworCisgICAgY2FtID0gJnNDYW1UcmFja3Nbc0N1cnJlbnRDYW1UcmFja107CisgICAgY3VycmVudENhbVRpY2sgPSBzVGljayAtIHNDdXJyZW50Q2FtVHJhY2tTdGFydFRpY2s7CisgICAgdHJhY2tQb3MgPSAoZmxvYXQpY3VycmVudENhbVRpY2sgLyAoQ0FNVFJBQ0tfTEVOICogY2FtLT5sZW4pOworCisgICAgZm9yIChhID0gMDsgYSA8IDU7ICsrYSkKKyAgICAgICAgbGVycFthXSA9IChjYW0tPnNyY1thXSArIGNhbS0+ZGVzdFthXSAqIHRyYWNrUG9zKSAqIDAuMDFmOworCisgICAgaWYgKGNhbS0+ZGlzdCkKKyAgICB7CisgICAgICAgIGZsb2F0IGRpc3QgPSBjYW0tPmRpc3QgKiAwLjFmOworICAgICAgICBjWCA9IGxlcnBbMF07CisgICAgICAgIGNZID0gbGVycFsxXTsKKyAgICAgICAgY1ogPSBsZXJwWzJdOworICAgICAgICBlWCA9IGNYIC0gKGZsb2F0KWNvcyhsZXJwWzNdKSAqIGRpc3Q7CisgICAgICAgIGVZID0gY1kgLSAoZmxvYXQpc2luKGxlcnBbM10pICogZGlzdDsKKyAgICAgICAgZVogPSBjWiAtIGxlcnBbNF07CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAgIGVYID0gbGVycFswXTsKKyAgICAgICAgZVkgPSBsZXJwWzFdOworICAgICAgICBlWiA9IGxlcnBbMl07CisgICAgICAgIGNYID0gZVggKyAoZmxvYXQpY29zKGxlcnBbM10pOworICAgICAgICBjWSA9IGVZICsgKGZsb2F0KXNpbihsZXJwWzNdKTsKKyAgICAgICAgY1ogPSBlWiArIGxlcnBbNF07CisgICAgfQorICAgIGdsdUxvb2tBdChlWCwgZVksIGVaLCBjWCwgY1ksIGNaLCAwLCAwLCAxKTsKK30KKworCisvLyBDYWxsZWQgZnJvbSB0aGUgYXBwIGZyYW1ld29yay4KKy8qIFRoZSB0aWNrIGlzIGN1cnJlbnQgdGltZSBpbiBtaWxsaXNlY29uZHMsIHdpZHRoIGFuZCBoZWlnaHQKKyAqIGFyZSB0aGUgaW1hZ2UgZGltZW5zaW9ucyB0byBiZSByZW5kZXJlZC4KKyAqLwordm9pZCBhcHBSZW5kZXIobG9uZyB0aWNrLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpCit7CisgICAgaWYgKHNTdGFydFRpY2sgPT0gMCkKKyAgICAgICAgc1N0YXJ0VGljayA9IHRpY2s7CisgICAgaWYgKCFnQXBwQWxpdmUpCisgICAgICAgIHJldHVybjsKKworICAgIC8vIEFjdHVhbCB0aWNrIHZhbHVlIGlzICJibHVycmVkIiBhIGxpdHRsZSBiaXQuCisgICAgc1RpY2sgPSAoc1RpY2sgKyB0aWNrIC0gc1N0YXJ0VGljaykgPj4gMTsKKworICAgIC8vIFRlcm1pbmF0ZSBhcHBsaWNhdGlvbiBhZnRlciBydW5uaW5nIHRocm91Z2ggdGhlIGRlbW9uc3RyYXRpb24gb25jZS4KKyAgICBpZiAoc1RpY2sgPj0gUlVOX0xFTkdUSCkKKyAgICB7CisgICAgICAgIGdBcHBBbGl2ZSA9IDA7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAvLyBQcmVwYXJlIE9wZW5HTCBFUyBmb3IgcmVuZGVyaW5nIG9mIHRoZSBmcmFtZS4KKyAgICBwcmVwYXJlRnJhbWUod2lkdGgsIGhlaWdodCk7CisKKyAgICAvLyBVcGRhdGUgdGhlIGNhbWVyYSBwb3NpdGlvbiBhbmQgc2V0IHRoZSBsb29rYXQuCisgICAgY2FtVHJhY2soKTsKKworICAgIC8vIENvbmZpZ3VyZSBlbnZpcm9ubWVudC4KKyAgICBjb25maWd1cmVMaWdodEFuZE1hdGVyaWFsKCk7CisKKyAgICAvLyBEcmF3IHRoZSByZWZsZWN0aW9uIGJ5IGRyYXdpbmcgbW9kZWxzIHdpdGggbmVnYXRlZCBaLWF4aXMuCisgICAgZ2xQdXNoTWF0cml4KCk7CisgICAgZHJhd01vZGVscygtMSk7CisgICAgZ2xQb3BNYXRyaXgoKTsKKworICAgIC8vIEJsZW5kIHRoZSBncm91bmQgcGxhbmUgdG8gdGhlIHdpbmRvdy4KKyAgICBkcmF3R3JvdW5kUGxhbmUoKTsKKworICAgIC8vIERyYXcgYWxsIHRoZSBtb2RlbHMgbm9ybWFsbHkuCisgICAgZHJhd01vZGVscygxKTsKKworICAgIC8vIERyYXcgZmFkZSBxdWFkIG92ZXIgd2hvbGUgd2luZG93ICh3aGVuIGNoYW5naW5nIGNhbWVyYXMpLgorICAgIGRyYXdGYWRlUXVhZCgpOworfQpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvZ3B1c3RhdGUuYyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2dwdXN0YXRlLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M1NDBjOQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2dwdXN0YXRlLmMKQEAgLTAsMCArMSwzOSBAQAorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzeXMvbW1hbi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisKK3N0YXRpYyB2b2lkICptYXBfbWVtb3J5KGNvbnN0IGNoYXIgKmZuLCB1bnNpZ25lZCBiYXNlLCB1bnNpZ25lZCBzaXplKQoreworICAgIGludCBmZDsKKyAgICB2b2lkICpwdHI7CisgICAgCisgICAgZmQgPSBvcGVuKGZuLCBPX1JEV1IgfCBPX1NZTkMpOworICAgIGlmKGZkIDwgMCkgeworICAgICAgICBwZXJyb3IoImNhbm5vdCBvcGVuICVzIGZvciBtYXBwaW5nIik7CisgICAgICAgIHJldHVybiBNQVBfRkFJTEVEOworICAgIH0KKworICAgIHB0ciA9IG1tYXAoMCwgc2l6ZSwgUFJPVF9SRUFEIHwgUFJPVF9XUklURSwKKyAgICAgICAgICAgICAgIE1BUF9TSEFSRUQsIGZkLCBiYXNlKTsKKyAgICBjbG9zZShmZCk7CisgICAgCisgICAgaWYocHRyID09IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgZnByaW50ZihzdGRlcnIsImNhbm5vdCBtYXAgJXMgKEAlMDh4LCUwOHgpXG4iLCBmbiwgYmFzZSwgc2l6ZSk7CisgICAgfQorICAgIHJldHVybiBwdHI7ICAgIAorfQorCisKK2ludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikKK3sKKyAgICB2b2lkICpncnBfcmVncyA9IG1hcF9tZW1vcnkoIi9kZXYvaHczZCIsIDAsIDEwMjQgKiAxMDI0KTsKKyAgICBwcmludGYoIkdQVSBiYXNlIG1hcHBlZCBhdCAlcFxuIiwgZ3JwX3JlZ3MpOworICAgIGludCBzdGF0ZV9vZmZzZXQgPSAweDEwMTQwOworICAgIHByaW50ZigiR1BVIHN0YXRlID0gJTA4bHhcbiIsCisgICAgICAgICAgICAqKChsb25nKikoKGNoYXIqKWdycF9yZWdzICsgc3RhdGVfb2Zmc2V0KSkgICk7CisKKyAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL2luY2x1ZGUvR0xFUy9lZ2wuaCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2luY2x1ZGUvR0xFUy9lZ2wuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZGY4NDEwCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvaW5jbHVkZS9HTEVTL2VnbC5oCkBAIC0wLDAgKzEsMjI5IEBACisjaWZuZGVmIF9fZWdsX2hfCisjZGVmaW5lIF9fZWdsX2hfCisKKy8qCisqKiBMaWNlbnNlIEFwcGxpY2FiaWxpdHkuIEV4Y2VwdCB0byB0aGUgZXh0ZW50IHBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUKKyoqIG1hZGUgc3ViamVjdCB0byBhbiBhbHRlcm5hdGl2ZSBsaWNlbnNlIGFzIHBlcm1pdHRlZCBpbiB0aGUgU0dJIEZyZWUKKyoqIFNvZnR3YXJlIExpY2Vuc2UgQiwgVmVyc2lvbiAxLjAgKHRoZSAiTGljZW5zZSIpLCB0aGUgY29udGVudHMgb2YgdGhpcworKiogZmlsZSBhcmUgc3ViamVjdCBvbmx5IHRvIHRoZSBwcm92aXNpb25zIG9mIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG5vdCB1c2UKKyoqIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkKKyoqIG9mIHRoZSBMaWNlbnNlIGF0IFNpbGljb24gR3JhcGhpY3MsIEluYy4sIGF0dG46IExlZ2FsIFNlcnZpY2VzLCAxNjAwCisqKiBBbXBoaXRoZWF0cmUgUGFya3dheSwgTW91bnRhaW4gVmlldywgQ0EgOTQwNDMtMTM1MSwgb3IgYXQ6CisqKgorKiogaHR0cDovL29zcy5zZ2kuY29tL3Byb2plY3RzL0ZyZWVCCisqKgorKiogTm90ZSB0aGF0LCBhcyBwcm92aWRlZCBpbiB0aGUgTGljZW5zZSwgdGhlIFNvZnR3YXJlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisqKiAiQVMgSVMiIGJhc2lzLCB3aXRoIEFMTCBFWFBSRVNTIEFORCBJTVBMSUVEIFdBUlJBTlRJRVMgQU5EIENPTkRJVElPTlMKKyoqIERJU0NMQUlNRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgSU1QTElFRCBXQVJSQU5USUVTIEFORAorKiogQ09ORElUSU9OUyBPRiBNRVJDSEFOVEFCSUxJVFksIFNBVElTRkFDVE9SWSBRVUFMSVRZLCBGSVRORVNTIEZPUiBBCisqKiBQQVJUSUNVTEFSIFBVUlBPU0UsIEFORCBOT04tSU5GUklOR0VNRU5ULgorKioKKyoqIE9yaWdpbmFsIENvZGUuIFRoZSBPcmlnaW5hbCBDb2RlIGlzOiBPcGVuR0wgU2FtcGxlIEltcGxlbWVudGF0aW9uLAorKiogVmVyc2lvbiAxLjIuMSwgcmVsZWFzZWQgSmFudWFyeSAyNiwgMjAwMCwgZGV2ZWxvcGVkIGJ5IFNpbGljb24gR3JhcGhpY3MsCisqKiBJbmMuIFRoZSBPcmlnaW5hbCBDb2RlIGlzIENvcHlyaWdodCAoYykgMTk5MS0yMDA0IFNpbGljb24gR3JhcGhpY3MsIEluYy4KKyoqIENvcHlyaWdodCBpbiBhbnkgcG9ydGlvbnMgY3JlYXRlZCBieSB0aGlyZCBwYXJ0aWVzIGlzIGFzIGluZGljYXRlZAorKiogZWxzZXdoZXJlIGhlcmVpbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyoqCisqKiBBZGRpdGlvbmFsIE5vdGljZSBQcm92aXNpb25zOiBUaGUgYXBwbGljYXRpb24gcHJvZ3JhbW1pbmcgaW50ZXJmYWNlcworKiogZXN0YWJsaXNoZWQgYnkgU0dJIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIE9yaWdpbmFsIENvZGUgYXJlIFRoZQorKiogT3BlbkdMKFIpIEdyYXBoaWNzIFN5c3RlbTogQSBTcGVjaWZpY2F0aW9uIChWZXJzaW9uIDEuMi4xKSwgcmVsZWFzZWQKKyoqIEFwcmlsIDEsIDE5OTk7IFRoZSBPcGVuR0woUikgR3JhcGhpY3MgU3lzdGVtIFV0aWxpdHkgTGlicmFyeSAoVmVyc2lvbgorKiogMS4zKSwgcmVsZWFzZWQgTm92ZW1iZXIgNCwgMTk5ODsgYW5kIE9wZW5HTChSKSBHcmFwaGljcyB3aXRoIHRoZSBYCisqKiBXaW5kb3cgU3lzdGVtKFIpIChWZXJzaW9uIDEuMyksIHJlbGVhc2VkIE9jdG9iZXIgMTksIDE5OTguIFRoaXMgc29mdHdhcmUKKyoqIHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBPcGVuR0woUikgdmVyc2lvbiAxLjIuMSBTYW1wbGUgSW1wbGVtZW50YXRpb24KKyoqIHB1Ymxpc2hlZCBieSBTR0ksIGJ1dCBoYXMgbm90IGJlZW4gaW5kZXBlbmRlbnRseSB2ZXJpZmllZCBhcyBiZWluZworKiogY29tcGxpYW50IHdpdGggdGhlIE9wZW5HTChSKSB2ZXJzaW9uIDEuMi4xIFNwZWNpZmljYXRpb24uCisqLworCisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZWdsdHlwZXMuaD4KKworLyoKKyoqIGVnbHR5cGVzLmggaXMgcGxhdGZvcm0gZGVwZW5kZW50LiBJdCBkZWZpbmVzOgorKioKKyoqICAgICAtIEVHTCB0eXBlcyBhbmQgcmVzb3VyY2VzCisqKiAgICAgLSBOYXRpdmUgdHlwZXMKKyoqICAgICAtIEVHTCBhbmQgbmF0aXZlIGhhbmRsZSB2YWx1ZXMKKyoqCisqKiBFR0wgdHlwZXMgYW5kIHJlc291cmNlcyBhcmUgdG8gYmUgdHlwZWRlZidlZCB3aXRoIGFwcHJvcHJpYXRlIHBsYXRmb3JtCisqKiBkZXBlbmRlbnQgcmVzb3VyY2UgaGFuZGxlIHR5cGVzLiBFR0xpbnQgbXVzdCBiZSBhbiBpbnRlZ2VyIG9mIGF0IGxlYXN0CisqKiAzMi1iaXQuCisqKgorKiogTmF0aXZlRGlzcGxheVR5cGUsIE5hdGl2ZVdpbmRvd1R5cGUgYW5kIE5hdGl2ZVBpeG1hcFR5cGUgYXJlIHRvIGJlCisqKiByZXBsYWNlZCB3aXRoIGNvcnJlc3BvbmRpbmcgdHlwZXMgb2YgdGhlIG5hdGl2ZSB3aW5kb3cgc3lzdGVtIGluIGVnbC5oLgorKioKKyoqIEVHTCBhbmQgbmF0aXZlIGhhbmRsZSB2YWx1ZXMgbXVzdCBtYXRjaCB0aGVpciB0eXBlcy4KKyoqCisqKiBFeGFtcGxlIGVnbHR5cGVzLmg6CisqLworCisjaWYgMAorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8bmF0aXZlX3dpbmRvd19zeXN0ZW0uaD4KKworLyoKKyoqIFR5cGVzIGFuZCByZXNvdXJjZXMKKyovCit0eXBlZGVmIGludCBFR0xCb29sZWFuOwordHlwZWRlZiBpbnQzMl90IEVHTGludDsKK3R5cGVkZWYgdm9pZCAqRUdMRGlzcGxheTsKK3R5cGVkZWYgdm9pZCAqRUdMQ29uZmlnOwordHlwZWRlZiB2b2lkICpFR0xTdXJmYWNlOwordHlwZWRlZiB2b2lkICpFR0xDb250ZXh0OworCisvKgorKiogRUdMIGFuZCBuYXRpdmUgaGFuZGxlIHZhbHVlcworKi8KKyNkZWZpbmUgRUdMX0RFRkFVTFRfRElTUExBWSAoKE5hdGl2ZURpc3BsYXlUeXBlKTApCisjZGVmaW5lIEVHTF9OT19DT05URVhUICgoRUdMQ29udGV4dCkwKQorI2RlZmluZSBFR0xfTk9fRElTUExBWSAoKEVHTERpc3BsYXkpMCkKKyNkZWZpbmUgRUdMX05PX1NVUkZBQ0UgKChFR0xTdXJmYWNlKTApCisKKyNlbmRpZgorCisvKgorKiogVmVyc2lvbmluZyBhbmQgZXh0ZW5zaW9ucworKi8KKyNkZWZpbmUgRUdMX1ZFUlNJT05fMV8wCQkgICAgICAgMQorCisvKgorKiogQm9vbGVhbgorKi8KKyNkZWZpbmUgRUdMX0ZBTFNFCQkgICAgICAgMAorI2RlZmluZSBFR0xfVFJVRQkJICAgICAgIDEKKworLyoKKyoqIEVycm9ycworKi8KKyNkZWZpbmUgRUdMX1NVQ0NFU1MJCSAgICAgICAweDMwMDAKKyNkZWZpbmUgRUdMX05PVF9JTklUSUFMSVpFRAkgICAgICAgMHgzMDAxCisjZGVmaW5lIEVHTF9CQURfQUNDRVNTCQkgICAgICAgMHgzMDAyCisjZGVmaW5lIEVHTF9CQURfQUxMT0MJCSAgICAgICAweDMwMDMKKyNkZWZpbmUgRUdMX0JBRF9BVFRSSUJVVEUJICAgICAgIDB4MzAwNAorI2RlZmluZSBFR0xfQkFEX0NPTkZJRwkJICAgICAgIDB4MzAwNQorI2RlZmluZSBFR0xfQkFEX0NPTlRFWFQJCSAgICAgICAweDMwMDYKKyNkZWZpbmUgRUdMX0JBRF9DVVJSRU5UX1NVUkZBQ0UgICAgICAgIDB4MzAwNworI2RlZmluZSBFR0xfQkFEX0RJU1BMQVkJCSAgICAgICAweDMwMDgKKyNkZWZpbmUgRUdMX0JBRF9NQVRDSAkJICAgICAgIDB4MzAwOQorI2RlZmluZSBFR0xfQkFEX05BVElWRV9QSVhNQVAJICAgICAgIDB4MzAwQQorI2RlZmluZSBFR0xfQkFEX05BVElWRV9XSU5ET1cJICAgICAgIDB4MzAwQgorI2RlZmluZSBFR0xfQkFEX1BBUkFNRVRFUgkgICAgICAgMHgzMDBDCisjZGVmaW5lIEVHTF9CQURfU1VSRkFDRQkJICAgICAgIDB4MzAwRAorLyogMHgzMDBFIC0gMHgzMDFGIHJlc2VydmVkIGZvciBhZGRpdGlvbmFsIGVycm9ycy4gKi8KKworLyoKKyoqIENvbmZpZyBhdHRyaWJ1dGVzCisqLworI2RlZmluZSBFR0xfQlVGRkVSX1NJWkUJCSAgICAgICAweDMwMjAKKyNkZWZpbmUgRUdMX0FMUEhBX1NJWkUJCSAgICAgICAweDMwMjEKKyNkZWZpbmUgRUdMX0JMVUVfU0laRQkJICAgICAgIDB4MzAyMgorI2RlZmluZSBFR0xfR1JFRU5fU0laRQkJICAgICAgIDB4MzAyMworI2RlZmluZSBFR0xfUkVEX1NJWkUJCSAgICAgICAweDMwMjQKKyNkZWZpbmUgRUdMX0RFUFRIX1NJWkUJCSAgICAgICAweDMwMjUKKyNkZWZpbmUgRUdMX1NURU5DSUxfU0laRQkgICAgICAgMHgzMDI2CisjZGVmaW5lIEVHTF9DT05GSUdfQ0FWRUFUCSAgICAgICAweDMwMjcKKyNkZWZpbmUgRUdMX0NPTkZJR19JRAkJICAgICAgIDB4MzAyOAorI2RlZmluZSBFR0xfTEVWRUwJCSAgICAgICAweDMwMjkKKyNkZWZpbmUgRUdMX01BWF9QQlVGRkVSX0hFSUdIVAkgICAgICAgMHgzMDJBCisjZGVmaW5lIEVHTF9NQVhfUEJVRkZFUl9QSVhFTFMJICAgICAgIDB4MzAyQgorI2RlZmluZSBFR0xfTUFYX1BCVUZGRVJfV0lEVEgJICAgICAgIDB4MzAyQworI2RlZmluZSBFR0xfTkFUSVZFX1JFTkRFUkFCTEUJICAgICAgIDB4MzAyRAorI2RlZmluZSBFR0xfTkFUSVZFX1ZJU1VBTF9JRAkgICAgICAgMHgzMDJFCisjZGVmaW5lIEVHTF9OQVRJVkVfVklTVUFMX1RZUEUJICAgICAgIDB4MzAyRgorLyojZGVmaW5lIEVHTF9QUkVTRVJWRURfUkVTT1VSQ0VTCSAweDMwMzAqLworI2RlZmluZSBFR0xfU0FNUExFUwkJICAgICAgIDB4MzAzMQorI2RlZmluZSBFR0xfU0FNUExFX0JVRkZFUlMJICAgICAgIDB4MzAzMgorI2RlZmluZSBFR0xfU1VSRkFDRV9UWVBFCSAgICAgICAweDMwMzMKKyNkZWZpbmUgRUdMX1RSQU5TUEFSRU5UX1RZUEUJICAgICAgIDB4MzAzNAorI2RlZmluZSBFR0xfVFJBTlNQQVJFTlRfQkxVRV9WQUxVRSAgICAgMHgzMDM1CisjZGVmaW5lIEVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRSAgICAweDMwMzYKKyNkZWZpbmUgRUdMX1RSQU5TUEFSRU5UX1JFRF9WQUxVRSAgICAgIDB4MzAzNworCisvKgorKiogQ29uZmlnIGF0dHJpYnV0ZSBhbmQgdmFsdWUKKyovCisjZGVmaW5lIEVHTF9OT05FCQkgICAgICAgMHgzMDM4CisvKiAweDMwMzkgLSAweDMwNEYgcmVzZXJ2ZWQgZm9yIGFkZGl0aW9uYWwgY29uZmlnIGF0dHJpYnV0ZXMuICovCisKKy8qCisqKiBDb25maWcgdmFsdWVzCisqLworI2RlZmluZSBFR0xfRE9OVF9DQVJFCQkgICAgICAgKChFR0xpbnQpIC0xKQorI2RlZmluZSBFR0xfUEJVRkZFUl9CSVQJCSAgICAgICAweDAxCisjZGVmaW5lIEVHTF9QSVhNQVBfQklUCQkgICAgICAgMHgwMgorI2RlZmluZSBFR0xfV0lORE9XX0JJVAkJICAgICAgIDB4MDQKKyNkZWZpbmUgRUdMX1NMT1dfQ09ORklHCQkgICAgICAgMHgzMDUwCisjZGVmaW5lIEVHTF9OT05fQ09ORk9STUFOVF9DT05GSUcgICAgICAweDMwNTEKKyNkZWZpbmUgRUdMX1RSQU5TUEFSRU5UX1JHQgkgICAgICAgMHgzMDUyCisKKy8qCisqKiBTdHJpbmcgbmFtZXMKKyovCisjZGVmaW5lIEVHTF9WRU5ET1IJCSAgICAgICAweDMwNTMKKyNkZWZpbmUgRUdMX1ZFUlNJT04JCSAgICAgICAweDMwNTQKKyNkZWZpbmUgRUdMX0VYVEVOU0lPTlMJCSAgICAgICAweDMwNTUKKworLyoKKyoqIFN1cmZhY2UgYXR0cmlidXRlcworKi8KKyNkZWZpbmUgRUdMX0hFSUdIVAkJICAgICAgIDB4MzA1NgorI2RlZmluZSBFR0xfV0lEVEgJCSAgICAgICAweDMwNTcKKyNkZWZpbmUgRUdMX0xBUkdFU1RfUEJVRkZFUgkgICAgICAgMHgzMDU4CisKKy8qCisqKiBDdXJyZW50IHN1cmZhY2VzCisqLworI2RlZmluZSBFR0xfRFJBVwkJICAgICAgIDB4MzA1OQorI2RlZmluZSBFR0xfUkVBRAkJICAgICAgIDB4MzA1QQorCisvKgorKiogRW5naW5lcworKi8KKyNkZWZpbmUgRUdMX0NPUkVfTkFUSVZFX0VOR0lORQkgICAgICAgMHgzMDVCCisKKy8qIDB4MzA1Qy0weDNGRkZGIHJlc2VydmVkIGZvciBmdXR1cmUgdXNlICovCisKKy8qCisqKiBGdW5jdGlvbnMKKyovCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKK0dMQVBJIEVHTGludCBBUElFTlRSWSBlZ2xHZXRFcnJvciAodm9pZCk7CisKK0dMQVBJIEVHTERpc3BsYXkgQVBJRU5UUlkgZWdsR2V0RGlzcGxheSAoTmF0aXZlRGlzcGxheVR5cGUgZGlzcGxheSk7CitHTEFQSSBFR0xCb29sZWFuIEFQSUVOVFJZIGVnbEluaXRpYWxpemUgKEVHTERpc3BsYXkgZHB5LCBFR0xpbnQgKm1ham9yLCBFR0xpbnQgKm1pbm9yKTsKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsVGVybWluYXRlIChFR0xEaXNwbGF5IGRweSk7CitHTEFQSSBjb25zdCBjaGFyICogQVBJRU5UUlkgZWdsUXVlcnlTdHJpbmcgKEVHTERpc3BsYXkgZHB5LCBFR0xpbnQgbmFtZSk7CitHTEFQSSB2b2lkICgqIEFQSUVOVFJZIGVnbEdldFByb2NBZGRyZXNzIChjb25zdCBjaGFyICpwcm9jbmFtZSkpKCk7CisKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsR2V0Q29uZmlncyAoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyAqY29uZmlncywgRUdMaW50IGNvbmZpZ19zaXplLCBFR0xpbnQgKm51bV9jb25maWcpOworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xDaG9vc2VDb25maWcgKEVHTERpc3BsYXkgZHB5LCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0LCBFR0xDb25maWcgKmNvbmZpZ3MsIEVHTGludCBjb25maWdfc2l6ZSwgRUdMaW50ICpudW1fY29uZmlnKTsKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsR2V0Q29uZmlnQXR0cmliIChFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZywgRUdMaW50IGF0dHJpYnV0ZSwgRUdMaW50ICp2YWx1ZSk7CisKK0dMQVBJIEVHTFN1cmZhY2UgQVBJRU5UUlkgZWdsQ3JlYXRlV2luZG93U3VyZmFjZSAoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsIE5hdGl2ZVdpbmRvd1R5cGUgd2luZG93LCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK0dMQVBJIEVHTFN1cmZhY2UgQVBJRU5UUlkgZWdsQ3JlYXRlUGl4bWFwU3VyZmFjZSAoRUdMRGlzcGxheSBkcHksIEVHTENvbmZpZyBjb25maWcsIE5hdGl2ZVBpeG1hcFR5cGUgcGl4bWFwLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK0dMQVBJIEVHTFN1cmZhY2UgQVBJRU5UUlkgZWdsQ3JlYXRlUGJ1ZmZlclN1cmZhY2UgKEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLCBjb25zdCBFR0xpbnQgKmF0dHJpYl9saXN0KTsKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsRGVzdHJveVN1cmZhY2UgKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIHN1cmZhY2UpOworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xRdWVyeVN1cmZhY2UgKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIHN1cmZhY2UsIEVHTGludCBhdHRyaWJ1dGUsIEVHTGludCAqdmFsdWUpOworCitHTEFQSSBFR0xDb250ZXh0IEFQSUVOVFJZIGVnbENyZWF0ZUNvbnRleHQgKEVHTERpc3BsYXkgZHB5LCBFR0xDb25maWcgY29uZmlnLCBFR0xDb250ZXh0IHNoYXJlX2xpc3QsIGNvbnN0IEVHTGludCAqYXR0cmliX2xpc3QpOworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xEZXN0cm95Q29udGV4dCAoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4KTsKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsTWFrZUN1cnJlbnQgKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGRyYXcsIEVHTFN1cmZhY2UgcmVhZCwgRUdMQ29udGV4dCBjdHgpOworR0xBUEkgRUdMQ29udGV4dCBBUElFTlRSWSBlZ2xHZXRDdXJyZW50Q29udGV4dCAodm9pZCk7CitHTEFQSSBFR0xTdXJmYWNlIEFQSUVOVFJZIGVnbEdldEN1cnJlbnRTdXJmYWNlIChFR0xpbnQgcmVhZGRyYXcpOworR0xBUEkgRUdMRGlzcGxheSBBUElFTlRSWSBlZ2xHZXRDdXJyZW50RGlzcGxheSAodm9pZCk7CitHTEFQSSBFR0xCb29sZWFuIEFQSUVOVFJZIGVnbFF1ZXJ5Q29udGV4dCAoRUdMRGlzcGxheSBkcHksIEVHTENvbnRleHQgY3R4LCBFR0xpbnQgYXR0cmlidXRlLCBFR0xpbnQgKnZhbHVlKTsKKworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xXYWl0R0wgKHZvaWQpOworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xXYWl0TmF0aXZlIChFR0xpbnQgZW5naW5lKTsKK0dMQVBJIEVHTEJvb2xlYW4gQVBJRU5UUlkgZWdsU3dhcEJ1ZmZlcnMgKEVHTERpc3BsYXkgZHB5LCBFR0xTdXJmYWNlIGRyYXcpOworR0xBUEkgRUdMQm9vbGVhbiBBUElFTlRSWSBlZ2xDb3B5QnVmZmVycyAoRUdMRGlzcGxheSBkcHksIEVHTFN1cmZhY2Ugc3VyZmFjZSwgTmF0aXZlUGl4bWFwVHlwZSB0YXJnZXQpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19fZWdsX2hfICovCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9pbmNsdWRlL0dMRVMvZWdsdHlwZXMuaCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2luY2x1ZGUvR0xFUy9lZ2x0eXBlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkYjM2YzkKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9pbmNsdWRlL0dMRVMvZWdsdHlwZXMuaApAQCAtMCwwICsxLDIwIEBACisvKgorKiogVHlwZXMgYW5kIHJlc291cmNlcworKi8KK3R5cGVkZWYgaW50IEVHTEJvb2xlYW47Cit0eXBlZGVmIGxvbmcgRUdMaW50OwordHlwZWRlZiB2b2lkICpFR0xEaXNwbGF5OwordHlwZWRlZiB2b2lkICpFR0xDb25maWc7Cit0eXBlZGVmIHZvaWQgKkVHTFN1cmZhY2U7Cit0eXBlZGVmIHZvaWQgKkVHTENvbnRleHQ7Cit0eXBlZGVmIHZvaWQgKk5hdGl2ZURpc3BsYXlUeXBlOwordHlwZWRlZiB2b2lkICpOYXRpdmVXaW5kb3dUeXBlOwordHlwZWRlZiB2b2lkICpOYXRpdmVQaXhtYXBUeXBlOworCisvKgorKiogRUdMIGFuZCBuYXRpdmUgaGFuZGxlIHZhbHVlcworKi8KKyNkZWZpbmUgRUdMX0RFRkFVTFRfRElTUExBWSAoKE5hdGl2ZURpc3BsYXlUeXBlKTApCisjZGVmaW5lIEVHTF9OT19DT05URVhUICgoRUdMQ29udGV4dCkwKQorI2RlZmluZSBFR0xfTk9fRElTUExBWSAoKEVHTERpc3BsYXkpMCkKKyNkZWZpbmUgRUdMX05PX1NVUkZBQ0UgKChFR0xTdXJmYWNlKTApCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9pbmNsdWRlL0dMRVMvZ2wuaCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2luY2x1ZGUvR0xFUy9nbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxNTQ4MjIKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvYW5nZWxlcy9pbmNsdWRlL0dMRVMvZ2wuaApAQCAtMCwwICsxLDU4NCBAQAorI2lmbmRlZiBfX2dsX2hfCisjZGVmaW5lIF9fZ2xfaF8KKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKgorKiogTGljZW5zZSBBcHBsaWNhYmlsaXR5LiBFeGNlcHQgdG8gdGhlIGV4dGVudCBwb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlCisqKiBtYWRlIHN1YmplY3QgdG8gYW4gYWx0ZXJuYXRpdmUgbGljZW5zZSBhcyBwZXJtaXR0ZWQgaW4gdGhlIFNHSSBGcmVlCisqKiBTb2Z0d2FyZSBMaWNlbnNlIEIsIFZlcnNpb24gMS4wICh0aGUgIkxpY2Vuc2UiKSwgdGhlIGNvbnRlbnRzIG9mIHRoaXMKKyoqIGZpbGUgYXJlIHN1YmplY3Qgb25seSB0byB0aGUgcHJvdmlzaW9ucyBvZiB0aGUgTGljZW5zZS4gWW91IG1heSBub3QgdXNlCisqKiB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5CisqKiBvZiB0aGUgTGljZW5zZSBhdCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuLCBhdHRuOiBMZWdhbCBTZXJ2aWNlcywgMTYwMAorKiogQW1waGl0aGVhdHJlIFBhcmt3YXksIE1vdW50YWluIFZpZXcsIENBIDk0MDQzLTEzNTEsIG9yIGF0OgorKiogCisqKiBodHRwOi8vb3NzLnNnaS5jb20vcHJvamVjdHMvRnJlZUIKKyoqIAorKiogTm90ZSB0aGF0LCBhcyBwcm92aWRlZCBpbiB0aGUgTGljZW5zZSwgdGhlIFNvZnR3YXJlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisqKiAiQVMgSVMiIGJhc2lzLCB3aXRoIEFMTCBFWFBSRVNTIEFORCBJTVBMSUVEIFdBUlJBTlRJRVMgQU5EIENPTkRJVElPTlMKKyoqIERJU0NMQUlNRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgSU1QTElFRCBXQVJSQU5USUVTIEFORAorKiogQ09ORElUSU9OUyBPRiBNRVJDSEFOVEFCSUxJVFksIFNBVElTRkFDVE9SWSBRVUFMSVRZLCBGSVRORVNTIEZPUiBBCisqKiBQQVJUSUNVTEFSIFBVUlBPU0UsIEFORCBOT04tSU5GUklOR0VNRU5ULgorKiogCisqKiBPcmlnaW5hbCBDb2RlLiBUaGUgT3JpZ2luYWwgQ29kZSBpczogT3BlbkdMIFNhbXBsZSBJbXBsZW1lbnRhdGlvbiwKKyoqIFZlcnNpb24gMS4yLjEsIHJlbGVhc2VkIEphbnVhcnkgMjYsIDIwMDAsIGRldmVsb3BlZCBieSBTaWxpY29uIEdyYXBoaWNzLAorKiogSW5jLiBUaGUgT3JpZ2luYWwgQ29kZSBpcyBDb3B5cmlnaHQgKGMpIDE5OTEtMjAwMCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCisqKiBDb3B5cmlnaHQgaW4gYW55IHBvcnRpb25zIGNyZWF0ZWQgYnkgdGhpcmQgcGFydGllcyBpcyBhcyBpbmRpY2F0ZWQKKyoqIGVsc2V3aGVyZSBoZXJlaW4uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisqKiAKKyoqIEFkZGl0aW9uYWwgTm90aWNlIFByb3Zpc2lvbnM6IFRoZSBhcHBsaWNhdGlvbiBwcm9ncmFtbWluZyBpbnRlcmZhY2VzCisqKiBlc3RhYmxpc2hlZCBieSBTR0kgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgT3JpZ2luYWwgQ29kZSBhcmUgVGhlCisqKiBPcGVuR0woUikgR3JhcGhpY3MgU3lzdGVtOiBBIFNwZWNpZmljYXRpb24gKFZlcnNpb24gMS4yLjEpLCByZWxlYXNlZAorKiogQXByaWwgMSwgMTk5OTsgVGhlIE9wZW5HTChSKSBHcmFwaGljcyBTeXN0ZW0gVXRpbGl0eSBMaWJyYXJ5IChWZXJzaW9uCisqKiAxLjMpLCByZWxlYXNlZCBOb3ZlbWJlciA0LCAxOTk4OyBhbmQgT3BlbkdMKFIpIEdyYXBoaWNzIHdpdGggdGhlIFgKKyoqIFdpbmRvdyBTeXN0ZW0oUikgKFZlcnNpb24gMS4zKSwgcmVsZWFzZWQgT2N0b2JlciAxOSwgMTk5OC4gVGhpcyBzb2Z0d2FyZQorKiogd2FzIGNyZWF0ZWQgdXNpbmcgdGhlIE9wZW5HTChSKSB2ZXJzaW9uIDEuMi4xIFNhbXBsZSBJbXBsZW1lbnRhdGlvbgorKiogcHVibGlzaGVkIGJ5IFNHSSwgYnV0IGhhcyBub3QgYmVlbiBpbmRlcGVuZGVudGx5IHZlcmlmaWVkIGFzIGJlaW5nCisqKiBjb21wbGlhbnQgd2l0aCB0aGUgT3BlbkdMKFIpIHZlcnNpb24gMS4yLjEgU3BlY2lmaWNhdGlvbi4KKyovCisKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoQVBJRU5UUlkpICYmICFkZWZpbmVkKF9fQ1lHV0lOX18pCisjZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4gMQorI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCisjaWZuZGVmIEFQSUVOVFJZCisjZGVmaW5lIEFQSUVOVFJZCisjZW5kaWYKKyNpZm5kZWYgR0xBUEkKKyNkZWZpbmUgR0xBUEkgZXh0ZXJuCisjZW5kaWYKKwordHlwZWRlZiB1bnNpZ25lZCBpbnQgR0xlbnVtOwordHlwZWRlZiB1bnNpZ25lZCBjaGFyIEdMYm9vbGVhbjsKK3R5cGVkZWYgdW5zaWduZWQgaW50IEdMYml0ZmllbGQ7Cit0eXBlZGVmIHNpZ25lZCBjaGFyIEdMYnl0ZTsKK3R5cGVkZWYgc2hvcnQgR0xzaG9ydDsKK3R5cGVkZWYgaW50IEdMaW50OwordHlwZWRlZiBpbnQgR0xzaXplaTsKK3R5cGVkZWYgdW5zaWduZWQgY2hhciBHTHVieXRlOwordHlwZWRlZiB1bnNpZ25lZCBzaG9ydCBHTHVzaG9ydDsKK3R5cGVkZWYgdW5zaWduZWQgaW50IEdMdWludDsKK3R5cGVkZWYgZmxvYXQgR0xmbG9hdDsKK3R5cGVkZWYgZmxvYXQgR0xjbGFtcGY7Cit0eXBlZGVmIHZvaWQgR0x2b2lkOwordHlwZWRlZiBpbnQgR0xpbnRwdHJBUkI7Cit0eXBlZGVmIGludCBHTHNpemVpcHRyQVJCOwordHlwZWRlZiBpbnQgR0xmaXhlZDsKK3R5cGVkZWYgaW50IEdMY2xhbXB4OworLyogSW50ZXJuYWwgY29udmVuaWVuY2UgdHlwZWRlZnMgKi8KK3R5cGVkZWYgdm9pZCAoKl9HTGZ1bmNwdHIpKCk7CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBFeHRlbnNpb25zICovCisjZGVmaW5lIEdMX09FU19WRVJTSU9OXzFfMCAgICAgICAgICAgICAgICAxCisjZGVmaW5lIEdMX09FU19yZWFkX2Zvcm1hdCAgICAgICAgICAgICAgICAxCisjZGVmaW5lIEdMX09FU19jb21wcmVzc2VkX3BhbGV0dGVkX3RleHR1cmUgMQorCisvKiBDbGVhckJ1ZmZlck1hc2sgKi8KKyNkZWZpbmUgR0xfREVQVEhfQlVGRkVSX0JJVCAgICAgICAgICAgICAgIDB4MDAwMDAxMDAKKyNkZWZpbmUgR0xfU1RFTkNJTF9CVUZGRVJfQklUICAgICAgICAgICAgIDB4MDAwMDA0MDAKKyNkZWZpbmUgR0xfQ09MT1JfQlVGRkVSX0JJVCAgICAgICAgICAgICAgIDB4MDAwMDQwMDAKKworLyogQm9vbGVhbiAqLworI2RlZmluZSBHTF9GQUxTRSAgICAgICAgICAgICAgICAgICAgICAgICAgMAorI2RlZmluZSBHTF9UUlVFICAgICAgICAgICAgICAgICAgICAgICAgICAgMQorCisvKiBCZWdpbk1vZGUgKi8KKyNkZWZpbmUgR0xfUE9JTlRTICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDAwMAorI2RlZmluZSBHTF9MSU5FUyAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMDAxCisjZGVmaW5lIEdMX0xJTkVfTE9PUCAgICAgICAgICAgICAgICAgICAgICAweDAwMDIKKyNkZWZpbmUgR0xfTElORV9TVFJJUCAgICAgICAgICAgICAgICAgICAgIDB4MDAwMworI2RlZmluZSBHTF9UUklBTkdMRVMgICAgICAgICAgICAgICAgICAgICAgMHgwMDA0CisjZGVmaW5lIEdMX1RSSUFOR0xFX1NUUklQICAgICAgICAgICAgICAgICAweDAwMDUKKyNkZWZpbmUgR0xfVFJJQU5HTEVfRkFOICAgICAgICAgICAgICAgICAgIDB4MDAwNgorCisvKiBBbHBoYUZ1bmN0aW9uICovCisjZGVmaW5lIEdMX05FVkVSICAgICAgICAgICAgICAgICAgICAgICAgICAweDAyMDAKKyNkZWZpbmUgR0xfTEVTUyAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwMQorI2RlZmluZSBHTF9FUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMjAyCisjZGVmaW5lIEdMX0xFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAweDAyMDMKKyNkZWZpbmUgR0xfR1JFQVRFUiAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwNAorI2RlZmluZSBHTF9OT1RFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgMHgwMjA1CisjZGVmaW5lIEdMX0dFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAweDAyMDYKKyNkZWZpbmUgR0xfQUxXQVlTICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDIwNworCisvKiBCbGVuZGluZ0ZhY3RvckRlc3QgKi8KKyNkZWZpbmUgR0xfWkVSTyAgICAgICAgICAgICAgICAgICAgICAgICAgIDAKKyNkZWZpbmUgR0xfT05FICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEKKyNkZWZpbmUgR0xfU1JDX0NPTE9SICAgICAgICAgICAgICAgICAgICAgIDB4MDMwMAorI2RlZmluZSBHTF9PTkVfTUlOVVNfU1JDX0NPTE9SICAgICAgICAgICAgMHgwMzAxCisjZGVmaW5lIEdMX1NSQ19BTFBIQSAgICAgICAgICAgICAgICAgICAgICAweDAzMDIKKyNkZWZpbmUgR0xfT05FX01JTlVTX1NSQ19BTFBIQSAgICAgICAgICAgIDB4MDMwMworI2RlZmluZSBHTF9EU1RfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgMHgwMzA0CisjZGVmaW5lIEdMX09ORV9NSU5VU19EU1RfQUxQSEEgICAgICAgICAgICAweDAzMDUKKworLyogQmxlbmRpbmdGYWN0b3JTcmMgKi8KKy8qICAgICAgR0xfWkVSTyAqLworLyogICAgICBHTF9PTkUgKi8KKyNkZWZpbmUgR0xfRFNUX0NPTE9SICAgICAgICAgICAgICAgICAgICAgIDB4MDMwNgorI2RlZmluZSBHTF9PTkVfTUlOVVNfRFNUX0NPTE9SICAgICAgICAgICAgMHgwMzA3CisjZGVmaW5lIEdMX1NSQ19BTFBIQV9TQVRVUkFURSAgICAgICAgICAgICAweDAzMDgKKy8qICAgICAgR0xfU1JDX0FMUEhBICovCisvKiAgICAgIEdMX09ORV9NSU5VU19TUkNfQUxQSEEgKi8KKy8qICAgICAgR0xfRFNUX0FMUEhBICovCisvKiAgICAgIEdMX09ORV9NSU5VU19EU1RfQUxQSEEgKi8KKworLyogQ29sb3JNYXRlcmlhbEZhY2UgKi8KKy8qICAgICAgR0xfRlJPTlRfQU5EX0JBQ0sgKi8KKworLyogQ29sb3JNYXRlcmlhbFBhcmFtZXRlciAqLworLyogICAgICBHTF9BTUJJRU5UX0FORF9ESUZGVVNFICovCisKKy8qIENvbG9yUG9pbnRlclR5cGUgKi8KKy8qICAgICAgR0xfVU5TSUdORURfQllURSAqLworLyogICAgICBHTF9GTE9BVCAqLworLyogICAgICBHTF9GSVhFRCAqLworCisvKiBDdWxsRmFjZU1vZGUgKi8KKyNkZWZpbmUgR0xfRlJPTlQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDQwNAorI2RlZmluZSBHTF9CQUNLICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwNDA1CisjZGVmaW5lIEdMX0ZST05UX0FORF9CQUNLICAgICAgICAgICAgICAgICAweDA0MDgKKworLyogRGVwdGhGdW5jdGlvbiAqLworLyogICAgICBHTF9ORVZFUiAqLworLyogICAgICBHTF9MRVNTICovCisvKiAgICAgIEdMX0VRVUFMICovCisvKiAgICAgIEdMX0xFUVVBTCAqLworLyogICAgICBHTF9HUkVBVEVSICovCisvKiAgICAgIEdMX05PVEVRVUFMICovCisvKiAgICAgIEdMX0dFUVVBTCAqLworLyogICAgICBHTF9BTFdBWVMgKi8KKworLyogRW5hYmxlQ2FwICovCisjZGVmaW5lIEdMX0ZPRyAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDBCNjAKKyNkZWZpbmUgR0xfTElHSFRJTkcgICAgICAgICAgICAgICAgICAgICAgIDB4MEI1MAorI2RlZmluZSBHTF9URVhUVVJFXzJEICAgICAgICAgICAgICAgICAgICAgMHgwREUxCisjZGVmaW5lIEdMX0NVTExfRkFDRSAgICAgICAgICAgICAgICAgICAgICAweDBCNDQKKyNkZWZpbmUgR0xfQUxQSEFfVEVTVCAgICAgICAgICAgICAgICAgICAgIDB4MEJDMAorI2RlZmluZSBHTF9CTEVORCAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwQkUyCisjZGVmaW5lIEdMX0NPTE9SX0xPR0lDX09QICAgICAgICAgICAgICAgICAweDBCRjIKKyNkZWZpbmUgR0xfRElUSEVSICAgICAgICAgICAgICAgICAgICAgICAgIDB4MEJEMAorI2RlZmluZSBHTF9TVEVOQ0lMX1RFU1QgICAgICAgICAgICAgICAgICAgMHgwQjkwCisjZGVmaW5lIEdMX0RFUFRIX1RFU1QgICAgICAgICAgICAgICAgICAgICAweDBCNzEKKy8qICAgICAgR0xfTElHSFQwICovCisvKiAgICAgIEdMX0xJR0hUMSAqLworLyogICAgICBHTF9MSUdIVDIgKi8KKy8qICAgICAgR0xfTElHSFQzICovCisvKiAgICAgIEdMX0xJR0hUNCAqLworLyogICAgICBHTF9MSUdIVDUgKi8KKy8qICAgICAgR0xfTElHSFQ2ICovCisvKiAgICAgIEdMX0xJR0hUNyAqLworI2RlZmluZSBHTF9QT0lOVF9TTU9PVEggICAgICAgICAgICAgICAgICAgMHgwQjEwCisjZGVmaW5lIEdMX0xJTkVfU01PT1RIICAgICAgICAgICAgICAgICAgICAweDBCMjAKKyNkZWZpbmUgR0xfU0NJU1NPUl9URVNUICAgICAgICAgICAgICAgICAgIDB4MEMxMQorI2RlZmluZSBHTF9DT0xPUl9NQVRFUklBTCAgICAgICAgICAgICAgICAgMHgwQjU3CisjZGVmaW5lIEdMX05PUk1BTElaRSAgICAgICAgICAgICAgICAgICAgICAweDBCQTEKKyNkZWZpbmUgR0xfUkVTQ0FMRV9OT1JNQUwgICAgICAgICAgICAgICAgIDB4ODAzQQorI2RlZmluZSBHTF9QT0xZR09OX09GRlNFVF9GSUxMICAgICAgICAgICAgMHg4MDM3CisjZGVmaW5lIEdMX1ZFUlRFWF9BUlJBWSAgICAgICAgICAgICAgICAgICAweDgwNzQKKyNkZWZpbmUgR0xfTk9STUFMX0FSUkFZICAgICAgICAgICAgICAgICAgIDB4ODA3NQorI2RlZmluZSBHTF9DT0xPUl9BUlJBWSAgICAgICAgICAgICAgICAgICAgMHg4MDc2CisjZGVmaW5lIEdMX1RFWFRVUkVfQ09PUkRfQVJSQVkgICAgICAgICAgICAweDgwNzgKKyNkZWZpbmUgR0xfTVVMVElTQU1QTEUgICAgICAgICAgICAgICAgICAgIDB4ODA5RAorI2RlZmluZSBHTF9TQU1QTEVfQUxQSEFfVE9fQ09WRVJBR0UgICAgICAgMHg4MDlFCisjZGVmaW5lIEdMX1NBTVBMRV9BTFBIQV9UT19PTkUgICAgICAgICAgICAweDgwOUYKKyNkZWZpbmUgR0xfU0FNUExFX0NPVkVSQUdFICAgICAgICAgICAgICAgIDB4ODBBMAorCisvKiBFcnJvckNvZGUgKi8KKyNkZWZpbmUgR0xfTk9fRVJST1IgICAgICAgICAgICAgICAgICAgICAgIDAKKyNkZWZpbmUgR0xfSU5WQUxJRF9FTlVNICAgICAgICAgICAgICAgICAgIDB4MDUwMAorI2RlZmluZSBHTF9JTlZBTElEX1ZBTFVFICAgICAgICAgICAgICAgICAgMHgwNTAxCisjZGVmaW5lIEdMX0lOVkFMSURfT1BFUkFUSU9OICAgICAgICAgICAgICAweDA1MDIKKyNkZWZpbmUgR0xfU1RBQ0tfT1ZFUkZMT1cgICAgICAgICAgICAgICAgIDB4MDUwMworI2RlZmluZSBHTF9TVEFDS19VTkRFUkZMT1cgICAgICAgICAgICAgICAgMHgwNTA0CisjZGVmaW5lIEdMX09VVF9PRl9NRU1PUlkgICAgICAgICAgICAgICAgICAweDA1MDUKKworLyogRm9nTW9kZSAqLworLyogICAgICBHTF9MSU5FQVIgKi8KKyNkZWZpbmUgR0xfRVhQICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDgwMAorI2RlZmluZSBHTF9FWFAyICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwODAxCisKKy8qIEZvZ1BhcmFtZXRlciAqLworI2RlZmluZSBHTF9GT0dfREVOU0lUWSAgICAgICAgICAgICAgICAgICAgMHgwQjYyCisjZGVmaW5lIEdMX0ZPR19TVEFSVCAgICAgICAgICAgICAgICAgICAgICAweDBCNjMKKyNkZWZpbmUgR0xfRk9HX0VORCAgICAgICAgICAgICAgICAgICAgICAgIDB4MEI2NAorI2RlZmluZSBHTF9GT0dfTU9ERSAgICAgICAgICAgICAgICAgICAgICAgMHgwQjY1CisjZGVmaW5lIEdMX0ZPR19DT0xPUiAgICAgICAgICAgICAgICAgICAgICAweDBCNjYKKworLyogRnJvbnRGYWNlRGlyZWN0aW9uICovCisjZGVmaW5lIEdMX0NXICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA5MDAKKyNkZWZpbmUgR0xfQ0NXICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDkwMQorCisvKiBHZXRQTmFtZSAqLworI2RlZmluZSBHTF9TTU9PVEhfUE9JTlRfU0laRV9SQU5HRSAgICAgICAgMHgwQjEyCisjZGVmaW5lIEdMX1NNT09USF9MSU5FX1dJRFRIX1JBTkdFICAgICAgICAweDBCMjIKKyNkZWZpbmUgR0xfQUxJQVNFRF9QT0lOVF9TSVpFX1JBTkdFICAgICAgIDB4ODQ2RAorI2RlZmluZSBHTF9BTElBU0VEX0xJTkVfV0lEVEhfUkFOR0UgICAgICAgMHg4NDZFCisjZGVmaW5lIEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfVFlQRV9PRVMgMHg4QjlBCisjZGVmaW5lIEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfRk9STUFUX09FUyAweDhCOUIKKyNkZWZpbmUgR0xfTUFYX0xJR0hUUyAgICAgICAgICAgICAgICAgICAgIDB4MEQzMQorI2RlZmluZSBHTF9NQVhfVEVYVFVSRV9TSVpFICAgICAgICAgICAgICAgMHgwRDMzCisjZGVmaW5lIEdMX01BWF9NT0RFTFZJRVdfU1RBQ0tfREVQVEggICAgICAweDBEMzYKKyNkZWZpbmUgR0xfTUFYX1BST0pFQ1RJT05fU1RBQ0tfREVQVEggICAgIDB4MEQzOAorI2RlZmluZSBHTF9NQVhfVEVYVFVSRV9TVEFDS19ERVBUSCAgICAgICAgMHgwRDM5CisjZGVmaW5lIEdMX01BWF9WSUVXUE9SVF9ESU1TICAgICAgICAgICAgICAweDBEM0EKKyNkZWZpbmUgR0xfTUFYX0VMRU1FTlRTX1ZFUlRJQ0VTICAgICAgICAgIDB4ODBFOAorI2RlZmluZSBHTF9NQVhfRUxFTUVOVFNfSU5ESUNFUyAgICAgICAgICAgMHg4MEU5CisjZGVmaW5lIEdMX01BWF9URVhUVVJFX1VOSVRTICAgICAgICAgICAgICAweDg0RTIKKyNkZWZpbmUgR0xfTlVNX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTIDB4ODZBMgorI2RlZmluZSBHTF9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUyAgICAgMHg4NkEzCisjZGVmaW5lIEdMX1NVQlBJWEVMX0JJVFMgICAgICAgICAgICAgICAgICAweDBENTAKKyNkZWZpbmUgR0xfUkVEX0JJVFMgICAgICAgICAgICAgICAgICAgICAgIDB4MEQ1MgorI2RlZmluZSBHTF9HUkVFTl9CSVRTICAgICAgICAgICAgICAgICAgICAgMHgwRDUzCisjZGVmaW5lIEdMX0JMVUVfQklUUyAgICAgICAgICAgICAgICAgICAgICAweDBENTQKKyNkZWZpbmUgR0xfQUxQSEFfQklUUyAgICAgICAgICAgICAgICAgICAgIDB4MEQ1NQorI2RlZmluZSBHTF9ERVBUSF9CSVRTICAgICAgICAgICAgICAgICAgICAgMHgwRDU2CisjZGVmaW5lIEdMX1NURU5DSUxfQklUUyAgICAgICAgICAgICAgICAgICAweDBENTcKKworLyogSGludE1vZGUgKi8KKyNkZWZpbmUgR0xfRE9OVF9DQVJFICAgICAgICAgICAgICAgICAgICAgIDB4MTEwMAorI2RlZmluZSBHTF9GQVNURVNUICAgICAgICAgICAgICAgICAgICAgICAgMHgxMTAxCisjZGVmaW5lIEdMX05JQ0VTVCAgICAgICAgICAgICAgICAgICAgICAgICAweDExMDIKKworLyogSGludFRhcmdldCAqLworI2RlZmluZSBHTF9QRVJTUEVDVElWRV9DT1JSRUNUSU9OX0hJTlQgICAgMHgwQzUwCisjZGVmaW5lIEdMX1BPSU5UX1NNT09USF9ISU5UICAgICAgICAgICAgICAweDBDNTEKKyNkZWZpbmUgR0xfTElORV9TTU9PVEhfSElOVCAgICAgICAgICAgICAgIDB4MEM1MgorI2RlZmluZSBHTF9QT0xZR09OX1NNT09USF9ISU5UICAgICAgICAgICAgMHgwQzUzCisjZGVmaW5lIEdMX0ZPR19ISU5UICAgICAgICAgICAgICAgICAgICAgICAweDBDNTQKKworLyogTGlnaHRNb2RlbFBhcmFtZXRlciAqLworI2RlZmluZSBHTF9MSUdIVF9NT0RFTF9BTUJJRU5UICAgICAgICAgICAgMHgwQjUzCisjZGVmaW5lIEdMX0xJR0hUX01PREVMX1RXT19TSURFICAgICAgICAgICAweDBCNTIKKworLyogTGlnaHRQYXJhbWV0ZXIgKi8KKyNkZWZpbmUgR0xfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgIDB4MTIwMAorI2RlZmluZSBHTF9ESUZGVVNFICAgICAgICAgICAgICAgICAgICAgICAgMHgxMjAxCisjZGVmaW5lIEdMX1NQRUNVTEFSICAgICAgICAgICAgICAgICAgICAgICAweDEyMDIKKyNkZWZpbmUgR0xfUE9TSVRJT04gICAgICAgICAgICAgICAgICAgICAgIDB4MTIwMworI2RlZmluZSBHTF9TUE9UX0RJUkVDVElPTiAgICAgICAgICAgICAgICAgMHgxMjA0CisjZGVmaW5lIEdMX1NQT1RfRVhQT05FTlQgICAgICAgICAgICAgICAgICAweDEyMDUKKyNkZWZpbmUgR0xfU1BPVF9DVVRPRkYgICAgICAgICAgICAgICAgICAgIDB4MTIwNgorI2RlZmluZSBHTF9DT05TVEFOVF9BVFRFTlVBVElPTiAgICAgICAgICAgMHgxMjA3CisjZGVmaW5lIEdMX0xJTkVBUl9BVFRFTlVBVElPTiAgICAgICAgICAgICAweDEyMDgKKyNkZWZpbmUgR0xfUVVBRFJBVElDX0FUVEVOVUFUSU9OICAgICAgICAgIDB4MTIwOQorCisvKiBEYXRhVHlwZSAqLworI2RlZmluZSBHTF9CWVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNDAwCisjZGVmaW5lIEdMX1VOU0lHTkVEX0JZVEUgICAgICAgICAgICAgICAgICAweDE0MDEKKyNkZWZpbmUgR0xfU0hPUlQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTQwMgorI2RlZmluZSBHTF9VTlNJR05FRF9TSE9SVCAgICAgICAgICAgICAgICAgMHgxNDAzCisjZGVmaW5lIEdMX0ZMT0FUICAgICAgICAgICAgICAgICAgICAgICAgICAweDE0MDYKKyNkZWZpbmUgR0xfRklYRUQgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTQwQworCisvKiBMb2dpY09wICovCisjZGVmaW5lIEdMX0NMRUFSICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDAKKyNkZWZpbmUgR0xfQU5EICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwMQorI2RlZmluZSBHTF9BTkRfUkVWRVJTRSAgICAgICAgICAgICAgICAgICAgMHgxNTAyCisjZGVmaW5lIEdMX0NPUFkgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDMKKyNkZWZpbmUgR0xfQU5EX0lOVkVSVEVEICAgICAgICAgICAgICAgICAgIDB4MTUwNAorI2RlZmluZSBHTF9OT09QICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTA1CisjZGVmaW5lIEdMX1hPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDYKKyNkZWZpbmUgR0xfT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwNworI2RlZmluZSBHTF9OT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTA4CisjZGVmaW5lIEdMX0VRVUlWICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MDkKKyNkZWZpbmUgR0xfSU5WRVJUICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUwQQorI2RlZmluZSBHTF9PUl9SRVZFUlNFICAgICAgICAgICAgICAgICAgICAgMHgxNTBCCisjZGVmaW5lIEdMX0NPUFlfSU5WRVJURUQgICAgICAgICAgICAgICAgICAweDE1MEMKKyNkZWZpbmUgR0xfT1JfSU5WRVJURUQgICAgICAgICAgICAgICAgICAgIDB4MTUwRAorI2RlZmluZSBHTF9OQU5EICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNTBFCisjZGVmaW5lIEdMX1NFVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1MEYKKworLyogTWF0ZXJpYWxGYWNlICovCisvKiAgICAgIEdMX0ZST05UX0FORF9CQUNLICovCisKKy8qIE1hdGVyaWFsUGFyYW1ldGVyICovCisjZGVmaW5lIEdMX0VNSVNTSU9OICAgICAgICAgICAgICAgICAgICAgICAweDE2MDAKKyNkZWZpbmUgR0xfU0hJTklORVNTICAgICAgICAgICAgICAgICAgICAgIDB4MTYwMQorI2RlZmluZSBHTF9BTUJJRU5UX0FORF9ESUZGVVNFICAgICAgICAgICAgMHgxNjAyCisvKiAgICAgIEdMX0FNQklFTlQgKi8KKy8qICAgICAgR0xfRElGRlVTRSAqLworLyogICAgICBHTF9TUEVDVUxBUiAqLworCisvKiBNYXRyaXhNb2RlICovCisjZGVmaW5lIEdMX01PREVMVklFVyAgICAgICAgICAgICAgICAgICAgICAweDE3MDAKKyNkZWZpbmUgR0xfUFJPSkVDVElPTiAgICAgICAgICAgICAgICAgICAgIDB4MTcwMQorI2RlZmluZSBHTF9URVhUVVJFICAgICAgICAgICAgICAgICAgICAgICAgMHgxNzAyCisKKy8qIE5vcm1hbFBvaW50ZXJUeXBlICovCisvKiAgICAgIEdMX0JZVEUgKi8KKy8qICAgICAgR0xfU0hPUlQgKi8KKy8qICAgICAgR0xfRkxPQVQgKi8KKy8qICAgICAgR0xfRklYRUQgKi8KKworLyogUGl4ZWxGb3JtYXQgKi8KKyNkZWZpbmUgR0xfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTkwNgorI2RlZmluZSBHTF9SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxOTA3CisjZGVmaW5lIEdMX1JHQkEgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE5MDgKKyNkZWZpbmUgR0xfTFVNSU5BTkNFICAgICAgICAgICAgICAgICAgICAgIDB4MTkwOQorI2RlZmluZSBHTF9MVU1JTkFOQ0VfQUxQSEEgICAgICAgICAgICAgICAgMHgxOTBBCisKKy8qIFBpeGVsU3RvcmVQYXJhbWV0ZXIgKi8KKyNkZWZpbmUgR0xfVU5QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgIDB4MENGNQorI2RlZmluZSBHTF9QQUNLX0FMSUdOTUVOVCAgICAgICAgICAgICAgICAgMHgwRDA1CisKKy8qIFBpeGVsVHlwZSAqLworLyogICAgICBHTF9VTlNJR05FRF9CWVRFICovCisjZGVmaW5lIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQgICAgICAgICAweDgwMzMKKyNkZWZpbmUgR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMSAgICAgICAgIDB4ODAzNAorI2RlZmluZSBHTF9VTlNJR05FRF9TSE9SVF81XzZfNSAgICAgICAgICAgMHg4MzYzCisKKy8qIFNoYWRpbmdNb2RlbCAqLworI2RlZmluZSBHTF9GTEFUICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRDAwCisjZGVmaW5lIEdMX1NNT09USCAgICAgICAgICAgICAgICAgICAgICAgICAweDFEMDEKKworLyogU3RlbmNpbEZ1bmN0aW9uICovCisvKiAgICAgIEdMX05FVkVSICovCisvKiAgICAgIEdMX0xFU1MgKi8KKy8qICAgICAgR0xfRVFVQUwgKi8KKy8qICAgICAgR0xfTEVRVUFMICovCisvKiAgICAgIEdMX0dSRUFURVIgKi8KKy8qICAgICAgR0xfTk9URVFVQUwgKi8KKy8qICAgICAgR0xfR0VRVUFMICovCisvKiAgICAgIEdMX0FMV0FZUyAqLworCisvKiBTdGVuY2lsT3AgKi8KKy8qICAgICAgR0xfWkVSTyAqLworI2RlZmluZSBHTF9LRUVQICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRTAwCisjZGVmaW5lIEdMX1JFUExBQ0UgICAgICAgICAgICAgICAgICAgICAgICAweDFFMDEKKyNkZWZpbmUgR0xfSU5DUiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MUUwMgorI2RlZmluZSBHTF9ERUNSICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxRTAzCisvKiAgICAgIEdMX0lOVkVSVCAqLworCisvKiBTdHJpbmdOYW1lICovCisjZGVmaW5lIEdMX1ZFTkRPUiAgICAgICAgICAgICAgICAgICAgICAgICAweDFGMDAKKyNkZWZpbmUgR0xfUkVOREVSRVIgICAgICAgICAgICAgICAgICAgICAgIDB4MUYwMQorI2RlZmluZSBHTF9WRVJTSU9OICAgICAgICAgICAgICAgICAgICAgICAgMHgxRjAyCisjZGVmaW5lIEdMX0VYVEVOU0lPTlMgICAgICAgICAgICAgICAgICAgICAweDFGMDMKKworLyogVGV4Q29vcmRQb2ludGVyVHlwZSAqLworLyogICAgICBHTF9TSE9SVCAqLworLyogICAgICBHTF9GTE9BVCAqLworLyogICAgICBHTF9GSVhFRCAqLworLyogICAgICBHTF9CWVRFICovCisKKy8qIFRleHR1cmVFbnZNb2RlICovCisjZGVmaW5lIEdMX01PRFVMQVRFICAgICAgICAgICAgICAgICAgICAgICAweDIxMDAKKyNkZWZpbmUgR0xfREVDQUwgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjEwMQorLyogICAgICBHTF9CTEVORCAqLworI2RlZmluZSBHTF9BREQgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMTA0CisvKiAgICAgIEdMX1JFUExBQ0UgKi8KKworLyogVGV4dHVyZUVudlBhcmFtZXRlciAqLworI2RlZmluZSBHTF9URVhUVVJFX0VOVl9NT0RFICAgICAgICAgICAgICAgMHgyMjAwCisjZGVmaW5lIEdMX1RFWFRVUkVfRU5WX0NPTE9SICAgICAgICAgICAgICAweDIyMDEKKworLyogVGV4dHVyZUVudlRhcmdldCAqLworI2RlZmluZSBHTF9URVhUVVJFX0VOViAgICAgICAgICAgICAgICAgICAgMHgyMzAwCisKKy8qIFRleHR1cmVNYWdGaWx0ZXIgKi8KKyNkZWZpbmUgR0xfTkVBUkVTVCAgICAgICAgICAgICAgICAgICAgICAgIDB4MjYwMAorI2RlZmluZSBHTF9MSU5FQVIgICAgICAgICAgICAgICAgICAgICAgICAgMHgyNjAxCisKKy8qIFRleHR1cmVNaW5GaWx0ZXIgKi8KKy8qICAgICAgR0xfTkVBUkVTVCAqLworLyogICAgICBHTF9MSU5FQVIgKi8KKyNkZWZpbmUgR0xfTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCAgICAgICAgIDB4MjcwMAorI2RlZmluZSBHTF9MSU5FQVJfTUlQTUFQX05FQVJFU1QgICAgICAgICAgMHgyNzAxCisjZGVmaW5lIEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUiAgICAgICAgICAweDI3MDIKKyNkZWZpbmUgR0xfTElORUFSX01JUE1BUF9MSU5FQVIgICAgICAgICAgIDB4MjcwMworCisvKiBUZXh0dXJlUGFyYW1ldGVyTmFtZSAqLworI2RlZmluZSBHTF9URVhUVVJFX01BR19GSUxURVIgICAgICAgICAgICAgMHgyODAwCisjZGVmaW5lIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiAgICAgICAgICAgICAweDI4MDEKKyNkZWZpbmUgR0xfVEVYVFVSRV9XUkFQX1MgICAgICAgICAgICAgICAgIDB4MjgwMgorI2RlZmluZSBHTF9URVhUVVJFX1dSQVBfVCAgICAgICAgICAgICAgICAgMHgyODAzCisKKy8qIFRleHR1cmVUYXJnZXQgKi8KKy8qICAgICAgR0xfVEVYVFVSRV8yRCAqLworCisvKiBUZXh0dXJlVW5pdCAqLworI2RlZmluZSBHTF9URVhUVVJFMCAgICAgICAgICAgICAgICAgICAgICAgMHg4NEMwCisjZGVmaW5lIEdMX1RFWFRVUkUxICAgICAgICAgICAgICAgICAgICAgICAweDg0QzEKKyNkZWZpbmUgR0xfVEVYVFVSRTIgICAgICAgICAgICAgICAgICAgICAgIDB4ODRDMgorI2RlZmluZSBHTF9URVhUVVJFMyAgICAgICAgICAgICAgICAgICAgICAgMHg4NEMzCisjZGVmaW5lIEdMX1RFWFRVUkU0ICAgICAgICAgICAgICAgICAgICAgICAweDg0QzQKKyNkZWZpbmUgR0xfVEVYVFVSRTUgICAgICAgICAgICAgICAgICAgICAgIDB4ODRDNQorI2RlZmluZSBHTF9URVhUVVJFNiAgICAgICAgICAgICAgICAgICAgICAgMHg4NEM2CisjZGVmaW5lIEdMX1RFWFRVUkU3ICAgICAgICAgICAgICAgICAgICAgICAweDg0QzcKKyNkZWZpbmUgR0xfVEVYVFVSRTggICAgICAgICAgICAgICAgICAgICAgIDB4ODRDOAorI2RlZmluZSBHTF9URVhUVVJFOSAgICAgICAgICAgICAgICAgICAgICAgMHg4NEM5CisjZGVmaW5lIEdMX1RFWFRVUkUxMCAgICAgICAgICAgICAgICAgICAgICAweDg0Q0EKKyNkZWZpbmUgR0xfVEVYVFVSRTExICAgICAgICAgICAgICAgICAgICAgIDB4ODRDQgorI2RlZmluZSBHTF9URVhUVVJFMTIgICAgICAgICAgICAgICAgICAgICAgMHg4NENDCisjZGVmaW5lIEdMX1RFWFRVUkUxMyAgICAgICAgICAgICAgICAgICAgICAweDg0Q0QKKyNkZWZpbmUgR0xfVEVYVFVSRTE0ICAgICAgICAgICAgICAgICAgICAgIDB4ODRDRQorI2RlZmluZSBHTF9URVhUVVJFMTUgICAgICAgICAgICAgICAgICAgICAgMHg4NENGCisjZGVmaW5lIEdMX1RFWFRVUkUxNiAgICAgICAgICAgICAgICAgICAgICAweDg0RDAKKyNkZWZpbmUgR0xfVEVYVFVSRTE3ICAgICAgICAgICAgICAgICAgICAgIDB4ODREMQorI2RlZmluZSBHTF9URVhUVVJFMTggICAgICAgICAgICAgICAgICAgICAgMHg4NEQyCisjZGVmaW5lIEdMX1RFWFRVUkUxOSAgICAgICAgICAgICAgICAgICAgICAweDg0RDMKKyNkZWZpbmUgR0xfVEVYVFVSRTIwICAgICAgICAgICAgICAgICAgICAgIDB4ODRENAorI2RlZmluZSBHTF9URVhUVVJFMjEgICAgICAgICAgICAgICAgICAgICAgMHg4NEQ1CisjZGVmaW5lIEdMX1RFWFRVUkUyMiAgICAgICAgICAgICAgICAgICAgICAweDg0RDYKKyNkZWZpbmUgR0xfVEVYVFVSRTIzICAgICAgICAgICAgICAgICAgICAgIDB4ODRENworI2RlZmluZSBHTF9URVhUVVJFMjQgICAgICAgICAgICAgICAgICAgICAgMHg4NEQ4CisjZGVmaW5lIEdMX1RFWFRVUkUyNSAgICAgICAgICAgICAgICAgICAgICAweDg0RDkKKyNkZWZpbmUgR0xfVEVYVFVSRTI2ICAgICAgICAgICAgICAgICAgICAgIDB4ODREQQorI2RlZmluZSBHTF9URVhUVVJFMjcgICAgICAgICAgICAgICAgICAgICAgMHg4NERCCisjZGVmaW5lIEdMX1RFWFRVUkUyOCAgICAgICAgICAgICAgICAgICAgICAweDg0REMKKyNkZWZpbmUgR0xfVEVYVFVSRTI5ICAgICAgICAgICAgICAgICAgICAgIDB4ODRERAorI2RlZmluZSBHTF9URVhUVVJFMzAgICAgICAgICAgICAgICAgICAgICAgMHg4NERFCisjZGVmaW5lIEdMX1RFWFRVUkUzMSAgICAgICAgICAgICAgICAgICAgICAweDg0REYKKworLyogVGV4dHVyZVdyYXBNb2RlICovCisjZGVmaW5lIEdMX1JFUEVBVCAgICAgICAgICAgICAgICAgICAgICAgICAweDI5MDEKKyNkZWZpbmUgR0xfQ0xBTVBfVE9fRURHRSAgICAgICAgICAgICAgICAgIDB4ODEyRgorCisvKiBQaXhlbEludGVybmFsRm9ybWF0ICovCisjZGVmaW5lIEdMX1BBTEVUVEU0X1JHQjhfT0VTICAgICAgICAgICAgICAweDhCOTAKKyNkZWZpbmUgR0xfUEFMRVRURTRfUkdCQThfT0VTICAgICAgICAgICAgIDB4OEI5MQorI2RlZmluZSBHTF9QQUxFVFRFNF9SNV9HNl9CNV9PRVMgICAgICAgICAgMHg4QjkyCisjZGVmaW5lIEdMX1BBTEVUVEU0X1JHQkE0X09FUyAgICAgICAgICAgICAweDhCOTMKKyNkZWZpbmUgR0xfUEFMRVRURTRfUkdCNV9BMV9PRVMgICAgICAgICAgIDB4OEI5NAorI2RlZmluZSBHTF9QQUxFVFRFOF9SR0I4X09FUyAgICAgICAgICAgICAgMHg4Qjk1CisjZGVmaW5lIEdMX1BBTEVUVEU4X1JHQkE4X09FUyAgICAgICAgICAgICAweDhCOTYKKyNkZWZpbmUgR0xfUEFMRVRURThfUjVfRzZfQjVfT0VTICAgICAgICAgIDB4OEI5NworI2RlZmluZSBHTF9QQUxFVFRFOF9SR0JBNF9PRVMgICAgICAgICAgICAgMHg4Qjk4CisjZGVmaW5lIEdMX1BBTEVUVEU4X1JHQjVfQTFfT0VTICAgICAgICAgICAweDhCOTkKKworLyogVmVydGV4UG9pbnRlclR5cGUgKi8KKy8qICAgICAgR0xfU0hPUlQgKi8KKy8qICAgICAgR0xfRkxPQVQgKi8KKy8qICAgICAgR0xfRklYRUQgKi8KKy8qICAgICAgR0xfQllURSAqLworCisvKiBMaWdodE5hbWUgKi8KKyNkZWZpbmUgR0xfTElHSFQwICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAwMAorI2RlZmluZSBHTF9MSUdIVDEgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAxCisjZGVmaW5lIEdMX0xJR0hUMiAgICAgICAgICAgICAgICAgICAgICAgICAweDQwMDIKKyNkZWZpbmUgR0xfTElHSFQzICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAwMworI2RlZmluZSBHTF9MSUdIVDQgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDA0CisjZGVmaW5lIEdMX0xJR0hUNSAgICAgICAgICAgICAgICAgICAgICAgICAweDQwMDUKKyNkZWZpbmUgR0xfTElHSFQ2ICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAwNgorI2RlZmluZSBHTF9MSUdIVDcgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDA3CisKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xBY3RpdmVUZXh0dXJlIChHTGVudW0gdGV4dHVyZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQWxwaGFGdW5jIChHTGVudW0gZnVuYywgR0xjbGFtcGYgcmVmKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xBbHBoYUZ1bmN4IChHTGVudW0gZnVuYywgR0xjbGFtcHggcmVmKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xCaW5kVGV4dHVyZSAoR0xlbnVtIHRhcmdldCwgR0x1aW50IHRleHR1cmUpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbEJsZW5kRnVuYyAoR0xlbnVtIHNmYWN0b3IsIEdMZW51bSBkZmFjdG9yKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDbGVhciAoR0xiaXRmaWVsZCBtYXNrKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDbGVhckNvbG9yIChHTGNsYW1wZiByZWQsIEdMY2xhbXBmIGdyZWVuLCBHTGNsYW1wZiBibHVlLCBHTGNsYW1wZiBhbHBoYSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ2xlYXJDb2xvcnggKEdMY2xhbXB4IHJlZCwgR0xjbGFtcHggZ3JlZW4sIEdMY2xhbXB4IGJsdWUsIEdMY2xhbXB4IGFscGhhKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDbGVhckRlcHRoZiAoR0xjbGFtcGYgZGVwdGgpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbENsZWFyRGVwdGh4IChHTGNsYW1weCBkZXB0aCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ2xlYXJTdGVuY2lsIChHTGludCBzKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDbGllbnRBY3RpdmVUZXh0dXJlIChHTGVudW0gdGV4dHVyZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ29sb3I0ZiAoR0xmbG9hdCByZWQsIEdMZmxvYXQgZ3JlZW4sIEdMZmxvYXQgYmx1ZSwgR0xmbG9hdCBhbHBoYSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ29sb3I0eCAoR0xmaXhlZCByZWQsIEdMZml4ZWQgZ3JlZW4sIEdMZml4ZWQgYmx1ZSwgR0xmaXhlZCBhbHBoYSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ29sb3JNYXNrIChHTGJvb2xlYW4gcmVkLCBHTGJvb2xlYW4gZ3JlZW4sIEdMYm9vbGVhbiBibHVlLCBHTGJvb2xlYW4gYWxwaGEpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbENvbG9yUG9pbnRlciAoR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbENvbXByZXNzZWRUZXhJbWFnZTJEIChHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyLCBHTHNpemVpIGltYWdlU2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCAoR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsIEdMaW50IHlvZmZzZXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTHNpemVpIGltYWdlU2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xDb3B5VGV4SW1hZ2UyRCAoR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMZW51bSBpbnRlcm5hbGZvcm1hdCwgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMaW50IGJvcmRlcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ29weVRleFN1YkltYWdlMkQgKEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsQ3VsbEZhY2UgKEdMZW51bSBtb2RlKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xEZWxldGVUZXh0dXJlcyAoR0xzaXplaSBuLCBjb25zdCBHTHVpbnQgKnRleHR1cmVzKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xEZXB0aEZ1bmMgKEdMZW51bSBmdW5jKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xEZXB0aE1hc2sgKEdMYm9vbGVhbiBmbGFnKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xEZXB0aFJhbmdlZiAoR0xjbGFtcGYgek5lYXIsIEdMY2xhbXBmIHpGYXIpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbERlcHRoUmFuZ2V4IChHTGNsYW1weCB6TmVhciwgR0xjbGFtcHggekZhcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsRGlzYWJsZSAoR0xlbnVtIGNhcCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsRGlzYWJsZUNsaWVudFN0YXRlIChHTGVudW0gYXJyYXkpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbERyYXdBcnJheXMgKEdMZW51bSBtb2RlLCBHTGludCBmaXJzdCwgR0xzaXplaSBjb3VudCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsRHJhd0VsZW1lbnRzIChHTGVudW0gbW9kZSwgR0xzaXplaSBjb3VudCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsRW5hYmxlIChHTGVudW0gY2FwKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xFbmFibGVDbGllbnRTdGF0ZSAoR0xlbnVtIGFycmF5KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xGaW5pc2ggKHZvaWQpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbEZsdXNoICh2b2lkKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xGb2dmIChHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0pOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbEZvZ2Z2IChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsRm9neCAoR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xGb2d4diAoR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbEZyb250RmFjZSAoR0xlbnVtIG1vZGUpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbEZydXN0dW1mIChHTGZsb2F0IGxlZnQsIEdMZmxvYXQgcmlnaHQsIEdMZmxvYXQgYm90dG9tLCBHTGZsb2F0IHRvcCwgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xGcnVzdHVteCAoR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LCBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsIEdMZml4ZWQgek5lYXIsIEdMZml4ZWQgekZhcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsR2VuVGV4dHVyZXMgKEdMc2l6ZWkgbiwgR0x1aW50ICp0ZXh0dXJlcyk7CitHTEFQSSBHTGVudW0gQVBJRU5UUlkgZ2xHZXRFcnJvciAodm9pZCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsR2V0SW50ZWdlcnYgKEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcyk7CitHTEFQSSBjb25zdCBHTHVieXRlICogQVBJRU5UUlkgZ2xHZXRTdHJpbmcgKEdMZW51bSBuYW1lKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xIaW50IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gbW9kZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRNb2RlbGYgKEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRNb2RlbGZ2IChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRNb2RlbHggKEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRNb2RlbHh2IChHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRmIChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHRmdiAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHR4IChHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGlnaHR4diAoR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTGluZVdpZHRoIChHTGZsb2F0IHdpZHRoKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xMaW5lV2lkdGh4IChHTGZpeGVkIHdpZHRoKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xMb2FkSWRlbnRpdHkgKHZvaWQpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbExvYWRNYXRyaXhmIChjb25zdCBHTGZsb2F0ICptKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xMb2FkTWF0cml4eCAoY29uc3QgR0xmaXhlZCAqbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTG9naWNPcCAoR0xlbnVtIG9wY29kZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTWF0ZXJpYWxmIChHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xNYXRlcmlhbGZ2IChHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbE1hdGVyaWFseCAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTWF0ZXJpYWx4diAoR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xNYXRyaXhNb2RlIChHTGVudW0gbW9kZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTXVsdE1hdHJpeGYgKGNvbnN0IEdMZmxvYXQgKm0pOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbE11bHRNYXRyaXh4IChjb25zdCBHTGZpeGVkICptKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xNdWx0aVRleENvb3JkNGYgKEdMZW51bSB0YXJnZXQsIEdMZmxvYXQgcywgR0xmbG9hdCB0LCBHTGZsb2F0IHIsIEdMZmxvYXQgcSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTXVsdGlUZXhDb29yZDR4IChHTGVudW0gdGFyZ2V0LCBHTGZpeGVkIHMsIEdMZml4ZWQgdCwgR0xmaXhlZCByLCBHTGZpeGVkIHEpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbE5vcm1hbDNmIChHTGZsb2F0IG54LCBHTGZsb2F0IG55LCBHTGZsb2F0IG56KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xOb3JtYWwzeCAoR0xmaXhlZCBueCwgR0xmaXhlZCBueSwgR0xmaXhlZCBueik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsTm9ybWFsUG9pbnRlciAoR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbE9ydGhvZiAoR0xmbG9hdCBsZWZ0LCBHTGZsb2F0IHJpZ2h0LCBHTGZsb2F0IGJvdHRvbSwgR0xmbG9hdCB0b3AsIEdMZmxvYXQgek5lYXIsIEdMZmxvYXQgekZhcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsT3J0aG94IChHTGZpeGVkIGxlZnQsIEdMZml4ZWQgcmlnaHQsIEdMZml4ZWQgYm90dG9tLCBHTGZpeGVkIHRvcCwgR0xmaXhlZCB6TmVhciwgR0xmaXhlZCB6RmFyKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xQaXhlbFN0b3JlaSAoR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsUG9pbnRTaXplIChHTGZsb2F0IHNpemUpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFBvaW50U2l6ZXggKEdMZml4ZWQgc2l6ZSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsUG9seWdvbk9mZnNldCAoR0xmbG9hdCBmYWN0b3IsIEdMZmxvYXQgdW5pdHMpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFBvbHlnb25PZmZzZXR4IChHTGZpeGVkIGZhY3RvciwgR0xmaXhlZCB1bml0cyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsUG9wTWF0cml4ICh2b2lkKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xQdXNoTWF0cml4ICh2b2lkKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xSZWFkUGl4ZWxzIChHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIEdMdm9pZCAqcGl4ZWxzKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xSb3RhdGVmIChHTGZsb2F0IGFuZ2xlLCBHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xSb3RhdGV4IChHTGZpeGVkIGFuZ2xlLCBHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xTYW1wbGVDb3ZlcmFnZSAoR0xjbGFtcGYgdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFNhbXBsZUNvdmVyYWdleCAoR0xjbGFtcHggdmFsdWUsIEdMYm9vbGVhbiBpbnZlcnQpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFNjYWxlZiAoR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsU2NhbGV4IChHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xTY2lzc29yIChHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsU2hhZGVNb2RlbCAoR0xlbnVtIG1vZGUpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFN0ZW5jaWxGdW5jIChHTGVudW0gZnVuYywgR0xpbnQgcmVmLCBHTHVpbnQgbWFzayk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsU3RlbmNpbE1hc2sgKEdMdWludCBtYXNrKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xTdGVuY2lsT3AgKEdMZW51bSBmYWlsLCBHTGVudW0gemZhaWwsIEdMZW51bSB6cGFzcyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsVGV4Q29vcmRQb2ludGVyIChHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsVGV4RW52ZiAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xUZXhFbnZmdiAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMpOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFRleEVudnggKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsVGV4RW52eHYgKEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xUZXhJbWFnZTJEIChHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xpbnQgaW50ZXJuYWxmb3JtYXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGludCBib3JkZXIsIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKnBpeGVscyk7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsVGV4UGFyYW1ldGVyZiAoR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xUZXhQYXJhbWV0ZXJ4IChHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0pOworR0xBUEkgdm9pZCBBUElFTlRSWSBnbFRleFN1YkltYWdlMkQgKEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqcGl4ZWxzKTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xUcmFuc2xhdGVmIChHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xUcmFuc2xhdGV4IChHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6KTsKK0dMQVBJIHZvaWQgQVBJRU5UUlkgZ2xWZXJ0ZXhQb2ludGVyIChHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlcik7CitHTEFQSSB2b2lkIEFQSUVOVFJZIGdsVmlld3BvcnQgKEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0KTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2VuZGlmIC8qIF9fZ2xfaF8gKi8KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UtQlNELnR4dCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UtQlNELnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTI0ZTNjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvbGljZW5zZS1CU0QudHh0CkBAIC0wLDAgKzEsMzQgQEAKK1RoaXMgaXMgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvciB0aGUgIlNhbiBBbmdlbGVzIE9ic2VydmF0aW9uIg0KK09wZW5HTCBFUyB2ZXJzaW9uIGV4YW1wbGUgc291cmNlIGNvZGUNCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCisNCitTYW4gQW5nZWxlcyBPYnNlcnZhdGlvbiBPcGVuR0wgRVMgdmVyc2lvbiBleGFtcGxlDQorQ29weXJpZ2h0IChjKSAyMDA0LTIwMDUsIEpldHJvIExhdWhhDQorQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisNCitSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQNCittb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMNCithcmUgbWV0Og0KKw0KKyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0DQorICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLg0KKyAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0DQorICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluDQorICAgICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQ0KKyAgICAgIGRpc3RyaWJ1dGlvbi4NCisgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBzb2Z0d2FyZSBwcm9kdWN0J3MgY29weXJpZ2h0IG93bmVyIG5vcg0KKyAgICAgIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZQ0KKyAgICAgIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbg0KKyAgICAgIHBlcm1pc3Npb24uDQorDQorVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUw0KKyJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UDQorTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SDQorQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQNCitPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwNCitTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQNCitUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SDQorUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRg0KK0xJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HDQorTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTDQorU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuDQpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvbGljZW5zZS1MR1BMLnR4dCBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UtTEdQTC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFlM2Y1YQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UtTEdQTC50eHQKQEAgLTAsMCArMSw1MDQgQEAKKwkJICBHTlUgTEVTU0VSIEdFTkVSQUwgUFVCTElDIExJQ0VOU0UKKwkJICAgICAgIFZlcnNpb24gMi4xLCBGZWJydWFyeSAxOTk5CisKKyBDb3B5cmlnaHQgKEMpIDE5OTEsIDE5OTkgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCisgICAgIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKKyBFdmVyeW9uZSBpcyBwZXJtaXR0ZWQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB2ZXJiYXRpbSBjb3BpZXMKKyBvZiB0aGlzIGxpY2Vuc2UgZG9jdW1lbnQsIGJ1dCBjaGFuZ2luZyBpdCBpcyBub3QgYWxsb3dlZC4KKworW1RoaXMgaXMgdGhlIGZpcnN0IHJlbGVhc2VkIHZlcnNpb24gb2YgdGhlIExlc3NlciBHUEwuICBJdCBhbHNvIGNvdW50cworIGFzIHRoZSBzdWNjZXNzb3Igb2YgdGhlIEdOVSBMaWJyYXJ5IFB1YmxpYyBMaWNlbnNlLCB2ZXJzaW9uIDIsIGhlbmNlCisgdGhlIHZlcnNpb24gbnVtYmVyIDIuMS5dCisKKwkJCSAgICBQcmVhbWJsZQorCisgIFRoZSBsaWNlbnNlcyBmb3IgbW9zdCBzb2Z0d2FyZSBhcmUgZGVzaWduZWQgdG8gdGFrZSBhd2F5IHlvdXIKK2ZyZWVkb20gdG8gc2hhcmUgYW5kIGNoYW5nZSBpdC4gIEJ5IGNvbnRyYXN0LCB0aGUgR05VIEdlbmVyYWwgUHVibGljCitMaWNlbnNlcyBhcmUgaW50ZW5kZWQgdG8gZ3VhcmFudGVlIHlvdXIgZnJlZWRvbSB0byBzaGFyZSBhbmQgY2hhbmdlCitmcmVlIHNvZnR3YXJlLS10byBtYWtlIHN1cmUgdGhlIHNvZnR3YXJlIGlzIGZyZWUgZm9yIGFsbCBpdHMgdXNlcnMuCisKKyAgVGhpcyBsaWNlbnNlLCB0aGUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIGFwcGxpZXMgdG8gc29tZQorc3BlY2lhbGx5IGRlc2lnbmF0ZWQgc29mdHdhcmUgcGFja2FnZXMtLXR5cGljYWxseSBsaWJyYXJpZXMtLW9mIHRoZQorRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCBvdGhlciBhdXRob3JzIHdobyBkZWNpZGUgdG8gdXNlIGl0LiAgWW91CitjYW4gdXNlIGl0IHRvbywgYnV0IHdlIHN1Z2dlc3QgeW91IGZpcnN0IHRoaW5rIGNhcmVmdWxseSBhYm91dCB3aGV0aGVyCit0aGlzIGxpY2Vuc2Ugb3IgdGhlIG9yZGluYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMgdGhlIGJldHRlcgorc3RyYXRlZ3kgdG8gdXNlIGluIGFueSBwYXJ0aWN1bGFyIGNhc2UsIGJhc2VkIG9uIHRoZSBleHBsYW5hdGlvbnMgYmVsb3cuCisKKyAgV2hlbiB3ZSBzcGVhayBvZiBmcmVlIHNvZnR3YXJlLCB3ZSBhcmUgcmVmZXJyaW5nIHRvIGZyZWVkb20gb2YgdXNlLAorbm90IHByaWNlLiAgT3VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VzIGFyZSBkZXNpZ25lZCB0byBtYWtlIHN1cmUgdGhhdAoreW91IGhhdmUgdGhlIGZyZWVkb20gdG8gZGlzdHJpYnV0ZSBjb3BpZXMgb2YgZnJlZSBzb2Z0d2FyZSAoYW5kIGNoYXJnZQorZm9yIHRoaXMgc2VydmljZSBpZiB5b3Ugd2lzaCk7IHRoYXQgeW91IHJlY2VpdmUgc291cmNlIGNvZGUgb3IgY2FuIGdldAoraXQgaWYgeW91IHdhbnQgaXQ7IHRoYXQgeW91IGNhbiBjaGFuZ2UgdGhlIHNvZnR3YXJlIGFuZCB1c2UgcGllY2VzIG9mCitpdCBpbiBuZXcgZnJlZSBwcm9ncmFtczsgYW5kIHRoYXQgeW91IGFyZSBpbmZvcm1lZCB0aGF0IHlvdSBjYW4gZG8KK3RoZXNlIHRoaW5ncy4KKworICBUbyBwcm90ZWN0IHlvdXIgcmlnaHRzLCB3ZSBuZWVkIHRvIG1ha2UgcmVzdHJpY3Rpb25zIHRoYXQgZm9yYmlkCitkaXN0cmlidXRvcnMgdG8gZGVueSB5b3UgdGhlc2UgcmlnaHRzIG9yIHRvIGFzayB5b3UgdG8gc3VycmVuZGVyIHRoZXNlCityaWdodHMuICBUaGVzZSByZXN0cmljdGlvbnMgdHJhbnNsYXRlIHRvIGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcyBmb3IKK3lvdSBpZiB5b3UgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlIGxpYnJhcnkgb3IgaWYgeW91IG1vZGlmeSBpdC4KKworICBGb3IgZXhhbXBsZSwgaWYgeW91IGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZSBsaWJyYXJ5LCB3aGV0aGVyIGdyYXRpcworb3IgZm9yIGEgZmVlLCB5b3UgbXVzdCBnaXZlIHRoZSByZWNpcGllbnRzIGFsbCB0aGUgcmlnaHRzIHRoYXQgd2UgZ2F2ZQoreW91LiAgWW91IG11c3QgbWFrZSBzdXJlIHRoYXQgdGhleSwgdG9vLCByZWNlaXZlIG9yIGNhbiBnZXQgdGhlIHNvdXJjZQorY29kZS4gIElmIHlvdSBsaW5rIG90aGVyIGNvZGUgd2l0aCB0aGUgbGlicmFyeSwgeW91IG11c3QgcHJvdmlkZQorY29tcGxldGUgb2JqZWN0IGZpbGVzIHRvIHRoZSByZWNpcGllbnRzLCBzbyB0aGF0IHRoZXkgY2FuIHJlbGluayB0aGVtCit3aXRoIHRoZSBsaWJyYXJ5IGFmdGVyIG1ha2luZyBjaGFuZ2VzIHRvIHRoZSBsaWJyYXJ5IGFuZCByZWNvbXBpbGluZworaXQuICBBbmQgeW91IG11c3Qgc2hvdyB0aGVtIHRoZXNlIHRlcm1zIHNvIHRoZXkga25vdyB0aGVpciByaWdodHMuCisKKyAgV2UgcHJvdGVjdCB5b3VyIHJpZ2h0cyB3aXRoIGEgdHdvLXN0ZXAgbWV0aG9kOiAoMSkgd2UgY29weXJpZ2h0IHRoZQorbGlicmFyeSwgYW5kICgyKSB3ZSBvZmZlciB5b3UgdGhpcyBsaWNlbnNlLCB3aGljaCBnaXZlcyB5b3UgbGVnYWwKK3Blcm1pc3Npb24gdG8gY29weSwgZGlzdHJpYnV0ZSBhbmQvb3IgbW9kaWZ5IHRoZSBsaWJyYXJ5LgorCisgIFRvIHByb3RlY3QgZWFjaCBkaXN0cmlidXRvciwgd2Ugd2FudCB0byBtYWtlIGl0IHZlcnkgY2xlYXIgdGhhdAordGhlcmUgaXMgbm8gd2FycmFudHkgZm9yIHRoZSBmcmVlIGxpYnJhcnkuICBBbHNvLCBpZiB0aGUgbGlicmFyeSBpcworbW9kaWZpZWQgYnkgc29tZW9uZSBlbHNlIGFuZCBwYXNzZWQgb24sIHRoZSByZWNpcGllbnRzIHNob3VsZCBrbm93Cit0aGF0IHdoYXQgdGhleSBoYXZlIGlzIG5vdCB0aGUgb3JpZ2luYWwgdmVyc2lvbiwgc28gdGhhdCB0aGUgb3JpZ2luYWwKK2F1dGhvcidzIHJlcHV0YXRpb24gd2lsbCBub3QgYmUgYWZmZWN0ZWQgYnkgcHJvYmxlbXMgdGhhdCBtaWdodCBiZQoraW50cm9kdWNlZCBieSBvdGhlcnMuCisMCisgIEZpbmFsbHksIHNvZnR3YXJlIHBhdGVudHMgcG9zZSBhIGNvbnN0YW50IHRocmVhdCB0byB0aGUgZXhpc3RlbmNlIG9mCithbnkgZnJlZSBwcm9ncmFtLiAgV2Ugd2lzaCB0byBtYWtlIHN1cmUgdGhhdCBhIGNvbXBhbnkgY2Fubm90CitlZmZlY3RpdmVseSByZXN0cmljdCB0aGUgdXNlcnMgb2YgYSBmcmVlIHByb2dyYW0gYnkgb2J0YWluaW5nIGEKK3Jlc3RyaWN0aXZlIGxpY2Vuc2UgZnJvbSBhIHBhdGVudCBob2xkZXIuICBUaGVyZWZvcmUsIHdlIGluc2lzdCB0aGF0CithbnkgcGF0ZW50IGxpY2Vuc2Ugb2J0YWluZWQgZm9yIGEgdmVyc2lvbiBvZiB0aGUgbGlicmFyeSBtdXN0IGJlCitjb25zaXN0ZW50IHdpdGggdGhlIGZ1bGwgZnJlZWRvbSBvZiB1c2Ugc3BlY2lmaWVkIGluIHRoaXMgbGljZW5zZS4KKworICBNb3N0IEdOVSBzb2Z0d2FyZSwgaW5jbHVkaW5nIHNvbWUgbGlicmFyaWVzLCBpcyBjb3ZlcmVkIGJ5IHRoZQorb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuICBUaGlzIGxpY2Vuc2UsIHRoZSBHTlUgTGVzc2VyCitHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBhcHBsaWVzIHRvIGNlcnRhaW4gZGVzaWduYXRlZCBsaWJyYXJpZXMsIGFuZAoraXMgcXVpdGUgZGlmZmVyZW50IGZyb20gdGhlIG9yZGluYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UuICBXZSB1c2UKK3RoaXMgbGljZW5zZSBmb3IgY2VydGFpbiBsaWJyYXJpZXMgaW4gb3JkZXIgdG8gcGVybWl0IGxpbmtpbmcgdGhvc2UKK2xpYnJhcmllcyBpbnRvIG5vbi1mcmVlIHByb2dyYW1zLgorCisgIFdoZW4gYSBwcm9ncmFtIGlzIGxpbmtlZCB3aXRoIGEgbGlicmFyeSwgd2hldGhlciBzdGF0aWNhbGx5IG9yIHVzaW5nCithIHNoYXJlZCBsaWJyYXJ5LCB0aGUgY29tYmluYXRpb24gb2YgdGhlIHR3byBpcyBsZWdhbGx5IHNwZWFraW5nIGEKK2NvbWJpbmVkIHdvcmssIGEgZGVyaXZhdGl2ZSBvZiB0aGUgb3JpZ2luYWwgbGlicmFyeS4gIFRoZSBvcmRpbmFyeQorR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB0aGVyZWZvcmUgcGVybWl0cyBzdWNoIGxpbmtpbmcgb25seSBpZiB0aGUKK2VudGlyZSBjb21iaW5hdGlvbiBmaXRzIGl0cyBjcml0ZXJpYSBvZiBmcmVlZG9tLiAgVGhlIExlc3NlciBHZW5lcmFsCitQdWJsaWMgTGljZW5zZSBwZXJtaXRzIG1vcmUgbGF4IGNyaXRlcmlhIGZvciBsaW5raW5nIG90aGVyIGNvZGUgd2l0aAordGhlIGxpYnJhcnkuCisKKyAgV2UgY2FsbCB0aGlzIGxpY2Vuc2UgdGhlICJMZXNzZXIiIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYmVjYXVzZSBpdAorZG9lcyBMZXNzIHRvIHByb3RlY3QgdGhlIHVzZXIncyBmcmVlZG9tIHRoYW4gdGhlIG9yZGluYXJ5IEdlbmVyYWwKK1B1YmxpYyBMaWNlbnNlLiAgSXQgYWxzbyBwcm92aWRlcyBvdGhlciBmcmVlIHNvZnR3YXJlIGRldmVsb3BlcnMgTGVzcworb2YgYW4gYWR2YW50YWdlIG92ZXIgY29tcGV0aW5nIG5vbi1mcmVlIHByb2dyYW1zLiAgVGhlc2UgZGlzYWR2YW50YWdlcworYXJlIHRoZSByZWFzb24gd2UgdXNlIHRoZSBvcmRpbmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtYW55CitsaWJyYXJpZXMuICBIb3dldmVyLCB0aGUgTGVzc2VyIGxpY2Vuc2UgcHJvdmlkZXMgYWR2YW50YWdlcyBpbiBjZXJ0YWluCitzcGVjaWFsIGNpcmN1bXN0YW5jZXMuCisKKyAgRm9yIGV4YW1wbGUsIG9uIHJhcmUgb2NjYXNpb25zLCB0aGVyZSBtYXkgYmUgYSBzcGVjaWFsIG5lZWQgdG8KK2VuY291cmFnZSB0aGUgd2lkZXN0IHBvc3NpYmxlIHVzZSBvZiBhIGNlcnRhaW4gbGlicmFyeSwgc28gdGhhdCBpdCBiZWNvbWVzCithIGRlLWZhY3RvIHN0YW5kYXJkLiAgVG8gYWNoaWV2ZSB0aGlzLCBub24tZnJlZSBwcm9ncmFtcyBtdXN0IGJlCithbGxvd2VkIHRvIHVzZSB0aGUgbGlicmFyeS4gIEEgbW9yZSBmcmVxdWVudCBjYXNlIGlzIHRoYXQgYSBmcmVlCitsaWJyYXJ5IGRvZXMgdGhlIHNhbWUgam9iIGFzIHdpZGVseSB1c2VkIG5vbi1mcmVlIGxpYnJhcmllcy4gIEluIHRoaXMKK2Nhc2UsIHRoZXJlIGlzIGxpdHRsZSB0byBnYWluIGJ5IGxpbWl0aW5nIHRoZSBmcmVlIGxpYnJhcnkgdG8gZnJlZQorc29mdHdhcmUgb25seSwgc28gd2UgdXNlIHRoZSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZS4KKworICBJbiBvdGhlciBjYXNlcywgcGVybWlzc2lvbiB0byB1c2UgYSBwYXJ0aWN1bGFyIGxpYnJhcnkgaW4gbm9uLWZyZWUKK3Byb2dyYW1zIGVuYWJsZXMgYSBncmVhdGVyIG51bWJlciBvZiBwZW9wbGUgdG8gdXNlIGEgbGFyZ2UgYm9keSBvZgorZnJlZSBzb2Z0d2FyZS4gIEZvciBleGFtcGxlLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgR05VIEMgTGlicmFyeSBpbgorbm9uLWZyZWUgcHJvZ3JhbXMgZW5hYmxlcyBtYW55IG1vcmUgcGVvcGxlIHRvIHVzZSB0aGUgd2hvbGUgR05VCitvcGVyYXRpbmcgc3lzdGVtLCBhcyB3ZWxsIGFzIGl0cyB2YXJpYW50LCB0aGUgR05VL0xpbnV4IG9wZXJhdGluZworc3lzdGVtLgorCisgIEFsdGhvdWdoIHRoZSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBpcyBMZXNzIHByb3RlY3RpdmUgb2YgdGhlCit1c2VycycgZnJlZWRvbSwgaXQgZG9lcyBlbnN1cmUgdGhhdCB0aGUgdXNlciBvZiBhIHByb2dyYW0gdGhhdCBpcworbGlua2VkIHdpdGggdGhlIExpYnJhcnkgaGFzIHRoZSBmcmVlZG9tIGFuZCB0aGUgd2hlcmV3aXRoYWwgdG8gcnVuCit0aGF0IHByb2dyYW0gdXNpbmcgYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBMaWJyYXJ5LgorCisgIFRoZSBwcmVjaXNlIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciBjb3B5aW5nLCBkaXN0cmlidXRpb24gYW5kCittb2RpZmljYXRpb24gZm9sbG93LiAgUGF5IGNsb3NlIGF0dGVudGlvbiB0byB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGEKKyJ3b3JrIGJhc2VkIG9uIHRoZSBsaWJyYXJ5IiBhbmQgYSAid29yayB0aGF0IHVzZXMgdGhlIGxpYnJhcnkiLiAgVGhlCitmb3JtZXIgY29udGFpbnMgY29kZSBkZXJpdmVkIGZyb20gdGhlIGxpYnJhcnksIHdoZXJlYXMgdGhlIGxhdHRlciBtdXN0CitiZSBjb21iaW5lZCB3aXRoIHRoZSBsaWJyYXJ5IGluIG9yZGVyIHRvIHJ1bi4KKwwKKwkJICBHTlUgTEVTU0VSIEdFTkVSQUwgUFVCTElDIExJQ0VOU0UKKyAgIFRFUk1TIEFORCBDT05ESVRJT05TIEZPUiBDT1BZSU5HLCBESVNUUklCVVRJT04gQU5EIE1PRElGSUNBVElPTgorCisgIDAuIFRoaXMgTGljZW5zZSBBZ3JlZW1lbnQgYXBwbGllcyB0byBhbnkgc29mdHdhcmUgbGlicmFyeSBvciBvdGhlcgorcHJvZ3JhbSB3aGljaCBjb250YWlucyBhIG5vdGljZSBwbGFjZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXIgb3IKK290aGVyIGF1dGhvcml6ZWQgcGFydHkgc2F5aW5nIGl0IG1heSBiZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YKK3RoaXMgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKGFsc28gY2FsbGVkICJ0aGlzIExpY2Vuc2UiKS4KK0VhY2ggbGljZW5zZWUgaXMgYWRkcmVzc2VkIGFzICJ5b3UiLgorCisgIEEgImxpYnJhcnkiIG1lYW5zIGEgY29sbGVjdGlvbiBvZiBzb2Z0d2FyZSBmdW5jdGlvbnMgYW5kL29yIGRhdGEKK3ByZXBhcmVkIHNvIGFzIHRvIGJlIGNvbnZlbmllbnRseSBsaW5rZWQgd2l0aCBhcHBsaWNhdGlvbiBwcm9ncmFtcworKHdoaWNoIHVzZSBzb21lIG9mIHRob3NlIGZ1bmN0aW9ucyBhbmQgZGF0YSkgdG8gZm9ybSBleGVjdXRhYmxlcy4KKworICBUaGUgIkxpYnJhcnkiLCBiZWxvdywgcmVmZXJzIHRvIGFueSBzdWNoIHNvZnR3YXJlIGxpYnJhcnkgb3Igd29yaword2hpY2ggaGFzIGJlZW4gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlc2UgdGVybXMuICBBICJ3b3JrIGJhc2VkIG9uIHRoZQorTGlicmFyeSIgbWVhbnMgZWl0aGVyIHRoZSBMaWJyYXJ5IG9yIGFueSBkZXJpdmF0aXZlIHdvcmsgdW5kZXIKK2NvcHlyaWdodCBsYXc6IHRoYXQgaXMgdG8gc2F5LCBhIHdvcmsgY29udGFpbmluZyB0aGUgTGlicmFyeSBvciBhCitwb3J0aW9uIG9mIGl0LCBlaXRoZXIgdmVyYmF0aW0gb3Igd2l0aCBtb2RpZmljYXRpb25zIGFuZC9vciB0cmFuc2xhdGVkCitzdHJhaWdodGZvcndhcmRseSBpbnRvIGFub3RoZXIgbGFuZ3VhZ2UuICAoSGVyZWluYWZ0ZXIsIHRyYW5zbGF0aW9uIGlzCitpbmNsdWRlZCB3aXRob3V0IGxpbWl0YXRpb24gaW4gdGhlIHRlcm0gIm1vZGlmaWNhdGlvbiIuKQorCisgICJTb3VyY2UgY29kZSIgZm9yIGEgd29yayBtZWFucyB0aGUgcHJlZmVycmVkIGZvcm0gb2YgdGhlIHdvcmsgZm9yCittYWtpbmcgbW9kaWZpY2F0aW9ucyB0byBpdC4gIEZvciBhIGxpYnJhcnksIGNvbXBsZXRlIHNvdXJjZSBjb2RlIG1lYW5zCithbGwgdGhlIHNvdXJjZSBjb2RlIGZvciBhbGwgbW9kdWxlcyBpdCBjb250YWlucywgcGx1cyBhbnkgYXNzb2NpYXRlZAoraW50ZXJmYWNlIGRlZmluaXRpb24gZmlsZXMsIHBsdXMgdGhlIHNjcmlwdHMgdXNlZCB0byBjb250cm9sIGNvbXBpbGF0aW9uCithbmQgaW5zdGFsbGF0aW9uIG9mIHRoZSBsaWJyYXJ5LgorCisgIEFjdGl2aXRpZXMgb3RoZXIgdGhhbiBjb3B5aW5nLCBkaXN0cmlidXRpb24gYW5kIG1vZGlmaWNhdGlvbiBhcmUgbm90Citjb3ZlcmVkIGJ5IHRoaXMgTGljZW5zZTsgdGhleSBhcmUgb3V0c2lkZSBpdHMgc2NvcGUuICBUaGUgYWN0IG9mCitydW5uaW5nIGEgcHJvZ3JhbSB1c2luZyB0aGUgTGlicmFyeSBpcyBub3QgcmVzdHJpY3RlZCwgYW5kIG91dHB1dCBmcm9tCitzdWNoIGEgcHJvZ3JhbSBpcyBjb3ZlcmVkIG9ubHkgaWYgaXRzIGNvbnRlbnRzIGNvbnN0aXR1dGUgYSB3b3JrIGJhc2VkCitvbiB0aGUgTGlicmFyeSAoaW5kZXBlbmRlbnQgb2YgdGhlIHVzZSBvZiB0aGUgTGlicmFyeSBpbiBhIHRvb2wgZm9yCit3cml0aW5nIGl0KS4gIFdoZXRoZXIgdGhhdCBpcyB0cnVlIGRlcGVuZHMgb24gd2hhdCB0aGUgTGlicmFyeSBkb2VzCithbmQgd2hhdCB0aGUgcHJvZ3JhbSB0aGF0IHVzZXMgdGhlIExpYnJhcnkgZG9lcy4KKyAgCisgIDEuIFlvdSBtYXkgY29weSBhbmQgZGlzdHJpYnV0ZSB2ZXJiYXRpbSBjb3BpZXMgb2YgdGhlIExpYnJhcnkncworY29tcGxldGUgc291cmNlIGNvZGUgYXMgeW91IHJlY2VpdmUgaXQsIGluIGFueSBtZWRpdW0sIHByb3ZpZGVkIHRoYXQKK3lvdSBjb25zcGljdW91c2x5IGFuZCBhcHByb3ByaWF0ZWx5IHB1Ymxpc2ggb24gZWFjaCBjb3B5IGFuCithcHByb3ByaWF0ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCBkaXNjbGFpbWVyIG9mIHdhcnJhbnR5OyBrZWVwIGludGFjdAorYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8gdGhpcyBMaWNlbnNlIGFuZCB0byB0aGUgYWJzZW5jZSBvZiBhbnkKK3dhcnJhbnR5OyBhbmQgZGlzdHJpYnV0ZSBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlIGFsb25nIHdpdGggdGhlCitMaWJyYXJ5LgorCisgIFlvdSBtYXkgY2hhcmdlIGEgZmVlIGZvciB0aGUgcGh5c2ljYWwgYWN0IG9mIHRyYW5zZmVycmluZyBhIGNvcHksCithbmQgeW91IG1heSBhdCB5b3VyIG9wdGlvbiBvZmZlciB3YXJyYW50eSBwcm90ZWN0aW9uIGluIGV4Y2hhbmdlIGZvciBhCitmZWUuCisMCisgIDIuIFlvdSBtYXkgbW9kaWZ5IHlvdXIgY29weSBvciBjb3BpZXMgb2YgdGhlIExpYnJhcnkgb3IgYW55IHBvcnRpb24KK29mIGl0LCB0aHVzIGZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBMaWJyYXJ5LCBhbmQgY29weSBhbmQKK2Rpc3RyaWJ1dGUgc3VjaCBtb2RpZmljYXRpb25zIG9yIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gMQorYWJvdmUsIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gbWVldCBhbGwgb2YgdGhlc2UgY29uZGl0aW9uczoKKworICAgIGEpIFRoZSBtb2RpZmllZCB3b3JrIG11c3QgaXRzZWxmIGJlIGEgc29mdHdhcmUgbGlicmFyeS4KKworICAgIGIpIFlvdSBtdXN0IGNhdXNlIHRoZSBmaWxlcyBtb2RpZmllZCB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcworICAgIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgZmlsZXMgYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuCisKKyAgICBjKSBZb3UgbXVzdCBjYXVzZSB0aGUgd2hvbGUgb2YgdGhlIHdvcmsgdG8gYmUgbGljZW5zZWQgYXQgbm8KKyAgICBjaGFyZ2UgdG8gYWxsIHRoaXJkIHBhcnRpZXMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZS4KKworICAgIGQpIElmIGEgZmFjaWxpdHkgaW4gdGhlIG1vZGlmaWVkIExpYnJhcnkgcmVmZXJzIHRvIGEgZnVuY3Rpb24gb3IgYQorICAgIHRhYmxlIG9mIGRhdGEgdG8gYmUgc3VwcGxpZWQgYnkgYW4gYXBwbGljYXRpb24gcHJvZ3JhbSB0aGF0IHVzZXMKKyAgICB0aGUgZmFjaWxpdHksIG90aGVyIHRoYW4gYXMgYW4gYXJndW1lbnQgcGFzc2VkIHdoZW4gdGhlIGZhY2lsaXR5CisgICAgaXMgaW52b2tlZCwgdGhlbiB5b3UgbXVzdCBtYWtlIGEgZ29vZCBmYWl0aCBlZmZvcnQgdG8gZW5zdXJlIHRoYXQsCisgICAgaW4gdGhlIGV2ZW50IGFuIGFwcGxpY2F0aW9uIGRvZXMgbm90IHN1cHBseSBzdWNoIGZ1bmN0aW9uIG9yCisgICAgdGFibGUsIHRoZSBmYWNpbGl0eSBzdGlsbCBvcGVyYXRlcywgYW5kIHBlcmZvcm1zIHdoYXRldmVyIHBhcnQgb2YKKyAgICBpdHMgcHVycG9zZSByZW1haW5zIG1lYW5pbmdmdWwuCisKKyAgICAoRm9yIGV4YW1wbGUsIGEgZnVuY3Rpb24gaW4gYSBsaWJyYXJ5IHRvIGNvbXB1dGUgc3F1YXJlIHJvb3RzIGhhcworICAgIGEgcHVycG9zZSB0aGF0IGlzIGVudGlyZWx5IHdlbGwtZGVmaW5lZCBpbmRlcGVuZGVudCBvZiB0aGUKKyAgICBhcHBsaWNhdGlvbi4gIFRoZXJlZm9yZSwgU3Vic2VjdGlvbiAyZCByZXF1aXJlcyB0aGF0IGFueQorICAgIGFwcGxpY2F0aW9uLXN1cHBsaWVkIGZ1bmN0aW9uIG9yIHRhYmxlIHVzZWQgYnkgdGhpcyBmdW5jdGlvbiBtdXN0CisgICAgYmUgb3B0aW9uYWw6IGlmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCBzdXBwbHkgaXQsIHRoZSBzcXVhcmUKKyAgICByb290IGZ1bmN0aW9uIG11c3Qgc3RpbGwgY29tcHV0ZSBzcXVhcmUgcm9vdHMuKQorCitUaGVzZSByZXF1aXJlbWVudHMgYXBwbHkgdG8gdGhlIG1vZGlmaWVkIHdvcmsgYXMgYSB3aG9sZS4gIElmCitpZGVudGlmaWFibGUgc2VjdGlvbnMgb2YgdGhhdCB3b3JrIGFyZSBub3QgZGVyaXZlZCBmcm9tIHRoZSBMaWJyYXJ5LAorYW5kIGNhbiBiZSByZWFzb25hYmx5IGNvbnNpZGVyZWQgaW5kZXBlbmRlbnQgYW5kIHNlcGFyYXRlIHdvcmtzIGluCit0aGVtc2VsdmVzLCB0aGVuIHRoaXMgTGljZW5zZSwgYW5kIGl0cyB0ZXJtcywgZG8gbm90IGFwcGx5IHRvIHRob3NlCitzZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUgd29ya3MuICBCdXQgd2hlbiB5b3UKK2Rpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEgd29yayBiYXNlZAorb24gdGhlIExpYnJhcnksIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHdob2xlIG11c3QgYmUgb24gdGhlIHRlcm1zIG9mCit0aGlzIExpY2Vuc2UsIHdob3NlIHBlcm1pc3Npb25zIGZvciBvdGhlciBsaWNlbnNlZXMgZXh0ZW5kIHRvIHRoZQorZW50aXJlIHdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlCitpdC4KKworVGh1cywgaXQgaXMgbm90IHRoZSBpbnRlbnQgb2YgdGhpcyBzZWN0aW9uIHRvIGNsYWltIHJpZ2h0cyBvciBjb250ZXN0Cit5b3VyIHJpZ2h0cyB0byB3b3JrIHdyaXR0ZW4gZW50aXJlbHkgYnkgeW91OyByYXRoZXIsIHRoZSBpbnRlbnQgaXMgdG8KK2V4ZXJjaXNlIHRoZSByaWdodCB0byBjb250cm9sIHRoZSBkaXN0cmlidXRpb24gb2YgZGVyaXZhdGl2ZSBvcgorY29sbGVjdGl2ZSB3b3JrcyBiYXNlZCBvbiB0aGUgTGlicmFyeS4KKworSW4gYWRkaXRpb24sIG1lcmUgYWdncmVnYXRpb24gb2YgYW5vdGhlciB3b3JrIG5vdCBiYXNlZCBvbiB0aGUgTGlicmFyeQord2l0aCB0aGUgTGlicmFyeSAob3Igd2l0aCBhIHdvcmsgYmFzZWQgb24gdGhlIExpYnJhcnkpIG9uIGEgdm9sdW1lIG9mCithIHN0b3JhZ2Ugb3IgZGlzdHJpYnV0aW9uIG1lZGl1bSBkb2VzIG5vdCBicmluZyB0aGUgb3RoZXIgd29yayB1bmRlcgordGhlIHNjb3BlIG9mIHRoaXMgTGljZW5zZS4KKworICAzLiBZb3UgbWF5IG9wdCB0byBhcHBseSB0aGUgdGVybXMgb2YgdGhlIG9yZGluYXJ5IEdOVSBHZW5lcmFsIFB1YmxpYworTGljZW5zZSBpbnN0ZWFkIG9mIHRoaXMgTGljZW5zZSB0byBhIGdpdmVuIGNvcHkgb2YgdGhlIExpYnJhcnkuICBUbyBkbwordGhpcywgeW91IG11c3QgYWx0ZXIgYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8gdGhpcyBMaWNlbnNlLCBzbwordGhhdCB0aGV5IHJlZmVyIHRvIHRoZSBvcmRpbmFyeSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgdmVyc2lvbiAyLAoraW5zdGVhZCBvZiB0byB0aGlzIExpY2Vuc2UuICAoSWYgYSBuZXdlciB2ZXJzaW9uIHRoYW4gdmVyc2lvbiAyIG9mIHRoZQorb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaGFzIGFwcGVhcmVkLCB0aGVuIHlvdSBjYW4gc3BlY2lmeQordGhhdCB2ZXJzaW9uIGluc3RlYWQgaWYgeW91IHdpc2guKSAgRG8gbm90IG1ha2UgYW55IG90aGVyIGNoYW5nZSBpbgordGhlc2Ugbm90aWNlcy4KKwwKKyAgT25jZSB0aGlzIGNoYW5nZSBpcyBtYWRlIGluIGEgZ2l2ZW4gY29weSwgaXQgaXMgaXJyZXZlcnNpYmxlIGZvcgordGhhdCBjb3B5LCBzbyB0aGUgb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXBwbGllcyB0byBhbGwKK3N1YnNlcXVlbnQgY29waWVzIGFuZCBkZXJpdmF0aXZlIHdvcmtzIG1hZGUgZnJvbSB0aGF0IGNvcHkuCisKKyAgVGhpcyBvcHRpb24gaXMgdXNlZnVsIHdoZW4geW91IHdpc2ggdG8gY29weSBwYXJ0IG9mIHRoZSBjb2RlIG9mCit0aGUgTGlicmFyeSBpbnRvIGEgcHJvZ3JhbSB0aGF0IGlzIG5vdCBhIGxpYnJhcnkuCisKKyAgNC4gWW91IG1heSBjb3B5IGFuZCBkaXN0cmlidXRlIHRoZSBMaWJyYXJ5IChvciBhIHBvcnRpb24gb3IKK2Rlcml2YXRpdmUgb2YgaXQsIHVuZGVyIFNlY3Rpb24gMikgaW4gb2JqZWN0IGNvZGUgb3IgZXhlY3V0YWJsZSBmb3JtCit1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbnMgMSBhbmQgMiBhYm92ZSBwcm92aWRlZCB0aGF0IHlvdSBhY2NvbXBhbnkKK2l0IHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcgbWFjaGluZS1yZWFkYWJsZSBzb3VyY2UgY29kZSwgd2hpY2gKK211c3QgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb25zIDEgYW5kIDIgYWJvdmUgb24gYQorbWVkaXVtIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGludGVyY2hhbmdlLgorCisgIElmIGRpc3RyaWJ1dGlvbiBvZiBvYmplY3QgY29kZSBpcyBtYWRlIGJ5IG9mZmVyaW5nIGFjY2VzcyB0byBjb3B5Citmcm9tIGEgZGVzaWduYXRlZCBwbGFjZSwgdGhlbiBvZmZlcmluZyBlcXVpdmFsZW50IGFjY2VzcyB0byBjb3B5IHRoZQorc291cmNlIGNvZGUgZnJvbSB0aGUgc2FtZSBwbGFjZSBzYXRpc2ZpZXMgdGhlIHJlcXVpcmVtZW50IHRvCitkaXN0cmlidXRlIHRoZSBzb3VyY2UgY29kZSwgZXZlbiB0aG91Z2ggdGhpcmQgcGFydGllcyBhcmUgbm90Citjb21wZWxsZWQgdG8gY29weSB0aGUgc291cmNlIGFsb25nIHdpdGggdGhlIG9iamVjdCBjb2RlLgorCisgIDUuIEEgcHJvZ3JhbSB0aGF0IGNvbnRhaW5zIG5vIGRlcml2YXRpdmUgb2YgYW55IHBvcnRpb24gb2YgdGhlCitMaWJyYXJ5LCBidXQgaXMgZGVzaWduZWQgdG8gd29yayB3aXRoIHRoZSBMaWJyYXJ5IGJ5IGJlaW5nIGNvbXBpbGVkIG9yCitsaW5rZWQgd2l0aCBpdCwgaXMgY2FsbGVkIGEgIndvcmsgdGhhdCB1c2VzIHRoZSBMaWJyYXJ5Ii4gIFN1Y2ggYQord29yaywgaW4gaXNvbGF0aW9uLCBpcyBub3QgYSBkZXJpdmF0aXZlIHdvcmsgb2YgdGhlIExpYnJhcnksIGFuZAordGhlcmVmb3JlIGZhbGxzIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoaXMgTGljZW5zZS4KKworICBIb3dldmVyLCBsaW5raW5nIGEgIndvcmsgdGhhdCB1c2VzIHRoZSBMaWJyYXJ5IiB3aXRoIHRoZSBMaWJyYXJ5CitjcmVhdGVzIGFuIGV4ZWN1dGFibGUgdGhhdCBpcyBhIGRlcml2YXRpdmUgb2YgdGhlIExpYnJhcnkgKGJlY2F1c2UgaXQKK2NvbnRhaW5zIHBvcnRpb25zIG9mIHRoZSBMaWJyYXJ5KSwgcmF0aGVyIHRoYW4gYSAid29yayB0aGF0IHVzZXMgdGhlCitsaWJyYXJ5Ii4gIFRoZSBleGVjdXRhYmxlIGlzIHRoZXJlZm9yZSBjb3ZlcmVkIGJ5IHRoaXMgTGljZW5zZS4KK1NlY3Rpb24gNiBzdGF0ZXMgdGVybXMgZm9yIGRpc3RyaWJ1dGlvbiBvZiBzdWNoIGV4ZWN1dGFibGVzLgorCisgIFdoZW4gYSAid29yayB0aGF0IHVzZXMgdGhlIExpYnJhcnkiIHVzZXMgbWF0ZXJpYWwgZnJvbSBhIGhlYWRlciBmaWxlCit0aGF0IGlzIHBhcnQgb2YgdGhlIExpYnJhcnksIHRoZSBvYmplY3QgY29kZSBmb3IgdGhlIHdvcmsgbWF5IGJlIGEKK2Rlcml2YXRpdmUgd29yayBvZiB0aGUgTGlicmFyeSBldmVuIHRob3VnaCB0aGUgc291cmNlIGNvZGUgaXMgbm90LgorV2hldGhlciB0aGlzIGlzIHRydWUgaXMgZXNwZWNpYWxseSBzaWduaWZpY2FudCBpZiB0aGUgd29yayBjYW4gYmUKK2xpbmtlZCB3aXRob3V0IHRoZSBMaWJyYXJ5LCBvciBpZiB0aGUgd29yayBpcyBpdHNlbGYgYSBsaWJyYXJ5LiAgVGhlCit0aHJlc2hvbGQgZm9yIHRoaXMgdG8gYmUgdHJ1ZSBpcyBub3QgcHJlY2lzZWx5IGRlZmluZWQgYnkgbGF3LgorCisgIElmIHN1Y2ggYW4gb2JqZWN0IGZpbGUgdXNlcyBvbmx5IG51bWVyaWNhbCBwYXJhbWV0ZXJzLCBkYXRhCitzdHJ1Y3R1cmUgbGF5b3V0cyBhbmQgYWNjZXNzb3JzLCBhbmQgc21hbGwgbWFjcm9zIGFuZCBzbWFsbCBpbmxpbmUKK2Z1bmN0aW9ucyAodGVuIGxpbmVzIG9yIGxlc3MgaW4gbGVuZ3RoKSwgdGhlbiB0aGUgdXNlIG9mIHRoZSBvYmplY3QKK2ZpbGUgaXMgdW5yZXN0cmljdGVkLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgaXQgaXMgbGVnYWxseSBhIGRlcml2YXRpdmUKK3dvcmsuICAoRXhlY3V0YWJsZXMgY29udGFpbmluZyB0aGlzIG9iamVjdCBjb2RlIHBsdXMgcG9ydGlvbnMgb2YgdGhlCitMaWJyYXJ5IHdpbGwgc3RpbGwgZmFsbCB1bmRlciBTZWN0aW9uIDYuKQorCisgIE90aGVyd2lzZSwgaWYgdGhlIHdvcmsgaXMgYSBkZXJpdmF0aXZlIG9mIHRoZSBMaWJyYXJ5LCB5b3UgbWF5CitkaXN0cmlidXRlIHRoZSBvYmplY3QgY29kZSBmb3IgdGhlIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gNi4KK0FueSBleGVjdXRhYmxlcyBjb250YWluaW5nIHRoYXQgd29yayBhbHNvIGZhbGwgdW5kZXIgU2VjdGlvbiA2LAord2hldGhlciBvciBub3QgdGhleSBhcmUgbGlua2VkIGRpcmVjdGx5IHdpdGggdGhlIExpYnJhcnkgaXRzZWxmLgorDAorICA2LiBBcyBhbiBleGNlcHRpb24gdG8gdGhlIFNlY3Rpb25zIGFib3ZlLCB5b3UgbWF5IGFsc28gY29tYmluZSBvcgorbGluayBhICJ3b3JrIHRoYXQgdXNlcyB0aGUgTGlicmFyeSIgd2l0aCB0aGUgTGlicmFyeSB0byBwcm9kdWNlIGEKK3dvcmsgY29udGFpbmluZyBwb3J0aW9ucyBvZiB0aGUgTGlicmFyeSwgYW5kIGRpc3RyaWJ1dGUgdGhhdCB3b3JrCit1bmRlciB0ZXJtcyBvZiB5b3VyIGNob2ljZSwgcHJvdmlkZWQgdGhhdCB0aGUgdGVybXMgcGVybWl0Cittb2RpZmljYXRpb24gb2YgdGhlIHdvcmsgZm9yIHRoZSBjdXN0b21lcidzIG93biB1c2UgYW5kIHJldmVyc2UKK2VuZ2luZWVyaW5nIGZvciBkZWJ1Z2dpbmcgc3VjaCBtb2RpZmljYXRpb25zLgorCisgIFlvdSBtdXN0IGdpdmUgcHJvbWluZW50IG5vdGljZSB3aXRoIGVhY2ggY29weSBvZiB0aGUgd29yayB0aGF0IHRoZQorTGlicmFyeSBpcyB1c2VkIGluIGl0IGFuZCB0aGF0IHRoZSBMaWJyYXJ5IGFuZCBpdHMgdXNlIGFyZSBjb3ZlcmVkIGJ5Cit0aGlzIExpY2Vuc2UuICBZb3UgbXVzdCBzdXBwbHkgYSBjb3B5IG9mIHRoaXMgTGljZW5zZS4gIElmIHRoZSB3b3JrCitkdXJpbmcgZXhlY3V0aW9uIGRpc3BsYXlzIGNvcHlyaWdodCBub3RpY2VzLCB5b3UgbXVzdCBpbmNsdWRlIHRoZQorY29weXJpZ2h0IG5vdGljZSBmb3IgdGhlIExpYnJhcnkgYW1vbmcgdGhlbSwgYXMgd2VsbCBhcyBhIHJlZmVyZW5jZQorZGlyZWN0aW5nIHRoZSB1c2VyIHRvIHRoZSBjb3B5IG9mIHRoaXMgTGljZW5zZS4gIEFsc28sIHlvdSBtdXN0IGRvIG9uZQorb2YgdGhlc2UgdGhpbmdzOgorCisgICAgYSkgQWNjb21wYW55IHRoZSB3b3JrIHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcKKyAgICBtYWNoaW5lLXJlYWRhYmxlIHNvdXJjZSBjb2RlIGZvciB0aGUgTGlicmFyeSBpbmNsdWRpbmcgd2hhdGV2ZXIKKyAgICBjaGFuZ2VzIHdlcmUgdXNlZCBpbiB0aGUgd29yayAod2hpY2ggbXVzdCBiZSBkaXN0cmlidXRlZCB1bmRlcgorICAgIFNlY3Rpb25zIDEgYW5kIDIgYWJvdmUpOyBhbmQsIGlmIHRoZSB3b3JrIGlzIGFuIGV4ZWN1dGFibGUgbGlua2VkCisgICAgd2l0aCB0aGUgTGlicmFyeSwgd2l0aCB0aGUgY29tcGxldGUgbWFjaGluZS1yZWFkYWJsZSAid29yayB0aGF0CisgICAgdXNlcyB0aGUgTGlicmFyeSIsIGFzIG9iamVjdCBjb2RlIGFuZC9vciBzb3VyY2UgY29kZSwgc28gdGhhdCB0aGUKKyAgICB1c2VyIGNhbiBtb2RpZnkgdGhlIExpYnJhcnkgYW5kIHRoZW4gcmVsaW5rIHRvIHByb2R1Y2UgYSBtb2RpZmllZAorICAgIGV4ZWN1dGFibGUgY29udGFpbmluZyB0aGUgbW9kaWZpZWQgTGlicmFyeS4gIChJdCBpcyB1bmRlcnN0b29kCisgICAgdGhhdCB0aGUgdXNlciB3aG8gY2hhbmdlcyB0aGUgY29udGVudHMgb2YgZGVmaW5pdGlvbnMgZmlsZXMgaW4gdGhlCisgICAgTGlicmFyeSB3aWxsIG5vdCBuZWNlc3NhcmlseSBiZSBhYmxlIHRvIHJlY29tcGlsZSB0aGUgYXBwbGljYXRpb24KKyAgICB0byB1c2UgdGhlIG1vZGlmaWVkIGRlZmluaXRpb25zLikKKworICAgIGIpIFVzZSBhIHN1aXRhYmxlIHNoYXJlZCBsaWJyYXJ5IG1lY2hhbmlzbSBmb3IgbGlua2luZyB3aXRoIHRoZQorICAgIExpYnJhcnkuICBBIHN1aXRhYmxlIG1lY2hhbmlzbSBpcyBvbmUgdGhhdCAoMSkgdXNlcyBhdCBydW4gdGltZSBhCisgICAgY29weSBvZiB0aGUgbGlicmFyeSBhbHJlYWR5IHByZXNlbnQgb24gdGhlIHVzZXIncyBjb21wdXRlciBzeXN0ZW0sCisgICAgcmF0aGVyIHRoYW4gY29weWluZyBsaWJyYXJ5IGZ1bmN0aW9ucyBpbnRvIHRoZSBleGVjdXRhYmxlLCBhbmQgKDIpCisgICAgd2lsbCBvcGVyYXRlIHByb3Blcmx5IHdpdGggYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBsaWJyYXJ5LCBpZgorICAgIHRoZSB1c2VyIGluc3RhbGxzIG9uZSwgYXMgbG9uZyBhcyB0aGUgbW9kaWZpZWQgdmVyc2lvbiBpcworICAgIGludGVyZmFjZS1jb21wYXRpYmxlIHdpdGggdGhlIHZlcnNpb24gdGhhdCB0aGUgd29yayB3YXMgbWFkZSB3aXRoLgorCisgICAgYykgQWNjb21wYW55IHRoZSB3b3JrIHdpdGggYSB3cml0dGVuIG9mZmVyLCB2YWxpZCBmb3IgYXQKKyAgICBsZWFzdCB0aHJlZSB5ZWFycywgdG8gZ2l2ZSB0aGUgc2FtZSB1c2VyIHRoZSBtYXRlcmlhbHMKKyAgICBzcGVjaWZpZWQgaW4gU3Vic2VjdGlvbiA2YSwgYWJvdmUsIGZvciBhIGNoYXJnZSBubyBtb3JlCisgICAgdGhhbiB0aGUgY29zdCBvZiBwZXJmb3JtaW5nIHRoaXMgZGlzdHJpYnV0aW9uLgorCisgICAgZCkgSWYgZGlzdHJpYnV0aW9uIG9mIHRoZSB3b3JrIGlzIG1hZGUgYnkgb2ZmZXJpbmcgYWNjZXNzIHRvIGNvcHkKKyAgICBmcm9tIGEgZGVzaWduYXRlZCBwbGFjZSwgb2ZmZXIgZXF1aXZhbGVudCBhY2Nlc3MgdG8gY29weSB0aGUgYWJvdmUKKyAgICBzcGVjaWZpZWQgbWF0ZXJpYWxzIGZyb20gdGhlIHNhbWUgcGxhY2UuCisKKyAgICBlKSBWZXJpZnkgdGhhdCB0aGUgdXNlciBoYXMgYWxyZWFkeSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlc2UKKyAgICBtYXRlcmlhbHMgb3IgdGhhdCB5b3UgaGF2ZSBhbHJlYWR5IHNlbnQgdGhpcyB1c2VyIGEgY29weS4KKworICBGb3IgYW4gZXhlY3V0YWJsZSwgdGhlIHJlcXVpcmVkIGZvcm0gb2YgdGhlICJ3b3JrIHRoYXQgdXNlcyB0aGUKK0xpYnJhcnkiIG11c3QgaW5jbHVkZSBhbnkgZGF0YSBhbmQgdXRpbGl0eSBwcm9ncmFtcyBuZWVkZWQgZm9yCityZXByb2R1Y2luZyB0aGUgZXhlY3V0YWJsZSBmcm9tIGl0LiAgSG93ZXZlciwgYXMgYSBzcGVjaWFsIGV4Y2VwdGlvbiwKK3RoZSBtYXRlcmlhbHMgdG8gYmUgZGlzdHJpYnV0ZWQgbmVlZCBub3QgaW5jbHVkZSBhbnl0aGluZyB0aGF0IGlzCitub3JtYWxseSBkaXN0cmlidXRlZCAoaW4gZWl0aGVyIHNvdXJjZSBvciBiaW5hcnkgZm9ybSkgd2l0aCB0aGUgbWFqb3IKK2NvbXBvbmVudHMgKGNvbXBpbGVyLCBrZXJuZWwsIGFuZCBzbyBvbikgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gb24KK3doaWNoIHRoZSBleGVjdXRhYmxlIHJ1bnMsIHVubGVzcyB0aGF0IGNvbXBvbmVudCBpdHNlbGYgYWNjb21wYW5pZXMKK3RoZSBleGVjdXRhYmxlLgorCisgIEl0IG1heSBoYXBwZW4gdGhhdCB0aGlzIHJlcXVpcmVtZW50IGNvbnRyYWRpY3RzIHRoZSBsaWNlbnNlCityZXN0cmljdGlvbnMgb2Ygb3RoZXIgcHJvcHJpZXRhcnkgbGlicmFyaWVzIHRoYXQgZG8gbm90IG5vcm1hbGx5CithY2NvbXBhbnkgdGhlIG9wZXJhdGluZyBzeXN0ZW0uICBTdWNoIGEgY29udHJhZGljdGlvbiBtZWFucyB5b3UgY2Fubm90Cit1c2UgYm90aCB0aGVtIGFuZCB0aGUgTGlicmFyeSB0b2dldGhlciBpbiBhbiBleGVjdXRhYmxlIHRoYXQgeW91CitkaXN0cmlidXRlLgorDAorICA3LiBZb3UgbWF5IHBsYWNlIGxpYnJhcnkgZmFjaWxpdGllcyB0aGF0IGFyZSBhIHdvcmsgYmFzZWQgb24gdGhlCitMaWJyYXJ5IHNpZGUtYnktc2lkZSBpbiBhIHNpbmdsZSBsaWJyYXJ5IHRvZ2V0aGVyIHdpdGggb3RoZXIgbGlicmFyeQorZmFjaWxpdGllcyBub3QgY292ZXJlZCBieSB0aGlzIExpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHN1Y2ggYSBjb21iaW5lZAorbGlicmFyeSwgcHJvdmlkZWQgdGhhdCB0aGUgc2VwYXJhdGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB3b3JrIGJhc2VkIG9uCit0aGUgTGlicmFyeSBhbmQgb2YgdGhlIG90aGVyIGxpYnJhcnkgZmFjaWxpdGllcyBpcyBvdGhlcndpc2UKK3Blcm1pdHRlZCwgYW5kIHByb3ZpZGVkIHRoYXQgeW91IGRvIHRoZXNlIHR3byB0aGluZ3M6CisKKyAgICBhKSBBY2NvbXBhbnkgdGhlIGNvbWJpbmVkIGxpYnJhcnkgd2l0aCBhIGNvcHkgb2YgdGhlIHNhbWUgd29yaworICAgIGJhc2VkIG9uIHRoZSBMaWJyYXJ5LCB1bmNvbWJpbmVkIHdpdGggYW55IG90aGVyIGxpYnJhcnkKKyAgICBmYWNpbGl0aWVzLiAgVGhpcyBtdXN0IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUKKyAgICBTZWN0aW9ucyBhYm92ZS4KKworICAgIGIpIEdpdmUgcHJvbWluZW50IG5vdGljZSB3aXRoIHRoZSBjb21iaW5lZCBsaWJyYXJ5IG9mIHRoZSBmYWN0CisgICAgdGhhdCBwYXJ0IG9mIGl0IGlzIGEgd29yayBiYXNlZCBvbiB0aGUgTGlicmFyeSwgYW5kIGV4cGxhaW5pbmcKKyAgICB3aGVyZSB0byBmaW5kIHRoZSBhY2NvbXBhbnlpbmcgdW5jb21iaW5lZCBmb3JtIG9mIHRoZSBzYW1lIHdvcmsuCisKKyAgOC4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBzdWJsaWNlbnNlLCBsaW5rIHdpdGgsIG9yIGRpc3RyaWJ1dGUKK3RoZSBMaWJyYXJ5IGV4Y2VwdCBhcyBleHByZXNzbHkgcHJvdmlkZWQgdW5kZXIgdGhpcyBMaWNlbnNlLiAgQW55CithdHRlbXB0IG90aGVyd2lzZSB0byBjb3B5LCBtb2RpZnksIHN1YmxpY2Vuc2UsIGxpbmsgd2l0aCwgb3IKK2Rpc3RyaWJ1dGUgdGhlIExpYnJhcnkgaXMgdm9pZCwgYW5kIHdpbGwgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUgeW91cgorcmlnaHRzIHVuZGVyIHRoaXMgTGljZW5zZS4gIEhvd2V2ZXIsIHBhcnRpZXMgd2hvIGhhdmUgcmVjZWl2ZWQgY29waWVzLAorb3IgcmlnaHRzLCBmcm9tIHlvdSB1bmRlciB0aGlzIExpY2Vuc2Ugd2lsbCBub3QgaGF2ZSB0aGVpciBsaWNlbnNlcwordGVybWluYXRlZCBzbyBsb25nIGFzIHN1Y2ggcGFydGllcyByZW1haW4gaW4gZnVsbCBjb21wbGlhbmNlLgorCisgIDkuIFlvdSBhcmUgbm90IHJlcXVpcmVkIHRvIGFjY2VwdCB0aGlzIExpY2Vuc2UsIHNpbmNlIHlvdSBoYXZlIG5vdAorc2lnbmVkIGl0LiAgSG93ZXZlciwgbm90aGluZyBlbHNlIGdyYW50cyB5b3UgcGVybWlzc2lvbiB0byBtb2RpZnkgb3IKK2Rpc3RyaWJ1dGUgdGhlIExpYnJhcnkgb3IgaXRzIGRlcml2YXRpdmUgd29ya3MuICBUaGVzZSBhY3Rpb25zIGFyZQorcHJvaGliaXRlZCBieSBsYXcgaWYgeW91IGRvIG5vdCBhY2NlcHQgdGhpcyBMaWNlbnNlLiAgVGhlcmVmb3JlLCBieQorbW9kaWZ5aW5nIG9yIGRpc3RyaWJ1dGluZyB0aGUgTGlicmFyeSAob3IgYW55IHdvcmsgYmFzZWQgb24gdGhlCitMaWJyYXJ5KSwgeW91IGluZGljYXRlIHlvdXIgYWNjZXB0YW5jZSBvZiB0aGlzIExpY2Vuc2UgdG8gZG8gc28sIGFuZAorYWxsIGl0cyB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgY29weWluZywgZGlzdHJpYnV0aW5nIG9yIG1vZGlmeWluZwordGhlIExpYnJhcnkgb3Igd29ya3MgYmFzZWQgb24gaXQuCisKKyAgMTAuIEVhY2ggdGltZSB5b3UgcmVkaXN0cmlidXRlIHRoZSBMaWJyYXJ5IChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKK0xpYnJhcnkpLCB0aGUgcmVjaXBpZW50IGF1dG9tYXRpY2FsbHkgcmVjZWl2ZXMgYSBsaWNlbnNlIGZyb20gdGhlCitvcmlnaW5hbCBsaWNlbnNvciB0byBjb3B5LCBkaXN0cmlidXRlLCBsaW5rIHdpdGggb3IgbW9kaWZ5IHRoZSBMaWJyYXJ5CitzdWJqZWN0IHRvIHRoZXNlIHRlcm1zIGFuZCBjb25kaXRpb25zLiAgWW91IG1heSBub3QgaW1wb3NlIGFueSBmdXJ0aGVyCityZXN0cmljdGlvbnMgb24gdGhlIHJlY2lwaWVudHMnIGV4ZXJjaXNlIG9mIHRoZSByaWdodHMgZ3JhbnRlZCBoZXJlaW4uCitZb3UgYXJlIG5vdCByZXNwb25zaWJsZSBmb3IgZW5mb3JjaW5nIGNvbXBsaWFuY2UgYnkgdGhpcmQgcGFydGllcyB3aXRoCit0aGlzIExpY2Vuc2UuCisMCisgIDExLiBJZiwgYXMgYSBjb25zZXF1ZW5jZSBvZiBhIGNvdXJ0IGp1ZGdtZW50IG9yIGFsbGVnYXRpb24gb2YgcGF0ZW50CitpbmZyaW5nZW1lbnQgb3IgZm9yIGFueSBvdGhlciByZWFzb24gKG5vdCBsaW1pdGVkIHRvIHBhdGVudCBpc3N1ZXMpLAorY29uZGl0aW9ucyBhcmUgaW1wb3NlZCBvbiB5b3UgKHdoZXRoZXIgYnkgY291cnQgb3JkZXIsIGFncmVlbWVudCBvcgorb3RoZXJ3aXNlKSB0aGF0IGNvbnRyYWRpY3QgdGhlIGNvbmRpdGlvbnMgb2YgdGhpcyBMaWNlbnNlLCB0aGV5IGRvIG5vdAorZXhjdXNlIHlvdSBmcm9tIHRoZSBjb25kaXRpb25zIG9mIHRoaXMgTGljZW5zZS4gIElmIHlvdSBjYW5ub3QKK2Rpc3RyaWJ1dGUgc28gYXMgdG8gc2F0aXNmeSBzaW11bHRhbmVvdXNseSB5b3VyIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMKK0xpY2Vuc2UgYW5kIGFueSBvdGhlciBwZXJ0aW5lbnQgb2JsaWdhdGlvbnMsIHRoZW4gYXMgYSBjb25zZXF1ZW5jZSB5b3UKK21heSBub3QgZGlzdHJpYnV0ZSB0aGUgTGlicmFyeSBhdCBhbGwuICBGb3IgZXhhbXBsZSwgaWYgYSBwYXRlbnQKK2xpY2Vuc2Ugd291bGQgbm90IHBlcm1pdCByb3lhbHR5LWZyZWUgcmVkaXN0cmlidXRpb24gb2YgdGhlIExpYnJhcnkgYnkKK2FsbCB0aG9zZSB3aG8gcmVjZWl2ZSBjb3BpZXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSB0aHJvdWdoIHlvdSwgdGhlbgordGhlIG9ubHkgd2F5IHlvdSBjb3VsZCBzYXRpc2Z5IGJvdGggaXQgYW5kIHRoaXMgTGljZW5zZSB3b3VsZCBiZSB0bworcmVmcmFpbiBlbnRpcmVseSBmcm9tIGRpc3RyaWJ1dGlvbiBvZiB0aGUgTGlicmFyeS4KKworSWYgYW55IHBvcnRpb24gb2YgdGhpcyBzZWN0aW9uIGlzIGhlbGQgaW52YWxpZCBvciB1bmVuZm9yY2VhYmxlIHVuZGVyIGFueQorcGFydGljdWxhciBjaXJjdW1zdGFuY2UsIHRoZSBiYWxhbmNlIG9mIHRoZSBzZWN0aW9uIGlzIGludGVuZGVkIHRvIGFwcGx5LAorYW5kIHRoZSBzZWN0aW9uIGFzIGEgd2hvbGUgaXMgaW50ZW5kZWQgdG8gYXBwbHkgaW4gb3RoZXIgY2lyY3Vtc3RhbmNlcy4KKworSXQgaXMgbm90IHRoZSBwdXJwb3NlIG9mIHRoaXMgc2VjdGlvbiB0byBpbmR1Y2UgeW91IHRvIGluZnJpbmdlIGFueQorcGF0ZW50cyBvciBvdGhlciBwcm9wZXJ0eSByaWdodCBjbGFpbXMgb3IgdG8gY29udGVzdCB2YWxpZGl0eSBvZiBhbnkKK3N1Y2ggY2xhaW1zOyB0aGlzIHNlY3Rpb24gaGFzIHRoZSBzb2xlIHB1cnBvc2Ugb2YgcHJvdGVjdGluZyB0aGUKK2ludGVncml0eSBvZiB0aGUgZnJlZSBzb2Z0d2FyZSBkaXN0cmlidXRpb24gc3lzdGVtIHdoaWNoIGlzCitpbXBsZW1lbnRlZCBieSBwdWJsaWMgbGljZW5zZSBwcmFjdGljZXMuICBNYW55IHBlb3BsZSBoYXZlIG1hZGUKK2dlbmVyb3VzIGNvbnRyaWJ1dGlvbnMgdG8gdGhlIHdpZGUgcmFuZ2Ugb2Ygc29mdHdhcmUgZGlzdHJpYnV0ZWQKK3Rocm91Z2ggdGhhdCBzeXN0ZW0gaW4gcmVsaWFuY2Ugb24gY29uc2lzdGVudCBhcHBsaWNhdGlvbiBvZiB0aGF0CitzeXN0ZW07IGl0IGlzIHVwIHRvIHRoZSBhdXRob3IvZG9ub3IgdG8gZGVjaWRlIGlmIGhlIG9yIHNoZSBpcyB3aWxsaW5nCit0byBkaXN0cmlidXRlIHNvZnR3YXJlIHRocm91Z2ggYW55IG90aGVyIHN5c3RlbSBhbmQgYSBsaWNlbnNlZSBjYW5ub3QKK2ltcG9zZSB0aGF0IGNob2ljZS4KKworVGhpcyBzZWN0aW9uIGlzIGludGVuZGVkIHRvIG1ha2UgdGhvcm91Z2hseSBjbGVhciB3aGF0IGlzIGJlbGlldmVkIHRvCitiZSBhIGNvbnNlcXVlbmNlIG9mIHRoZSByZXN0IG9mIHRoaXMgTGljZW5zZS4KKworICAxMi4gSWYgdGhlIGRpc3RyaWJ1dGlvbiBhbmQvb3IgdXNlIG9mIHRoZSBMaWJyYXJ5IGlzIHJlc3RyaWN0ZWQgaW4KK2NlcnRhaW4gY291bnRyaWVzIGVpdGhlciBieSBwYXRlbnRzIG9yIGJ5IGNvcHlyaWdodGVkIGludGVyZmFjZXMsIHRoZQorb3JpZ2luYWwgY29weXJpZ2h0IGhvbGRlciB3aG8gcGxhY2VzIHRoZSBMaWJyYXJ5IHVuZGVyIHRoaXMgTGljZW5zZSBtYXkgYWRkCithbiBleHBsaWNpdCBnZW9ncmFwaGljYWwgZGlzdHJpYnV0aW9uIGxpbWl0YXRpb24gZXhjbHVkaW5nIHRob3NlIGNvdW50cmllcywKK3NvIHRoYXQgZGlzdHJpYnV0aW9uIGlzIHBlcm1pdHRlZCBvbmx5IGluIG9yIGFtb25nIGNvdW50cmllcyBub3QgdGh1cworZXhjbHVkZWQuICBJbiBzdWNoIGNhc2UsIHRoaXMgTGljZW5zZSBpbmNvcnBvcmF0ZXMgdGhlIGxpbWl0YXRpb24gYXMgaWYKK3dyaXR0ZW4gaW4gdGhlIGJvZHkgb2YgdGhpcyBMaWNlbnNlLgorCisgIDEzLiBUaGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG1heSBwdWJsaXNoIHJldmlzZWQgYW5kL29yIG5ldwordmVyc2lvbnMgb2YgdGhlIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZyb20gdGltZSB0byB0aW1lLgorU3VjaCBuZXcgdmVyc2lvbnMgd2lsbCBiZSBzaW1pbGFyIGluIHNwaXJpdCB0byB0aGUgcHJlc2VudCB2ZXJzaW9uLAorYnV0IG1heSBkaWZmZXIgaW4gZGV0YWlsIHRvIGFkZHJlc3MgbmV3IHByb2JsZW1zIG9yIGNvbmNlcm5zLgorCitFYWNoIHZlcnNpb24gaXMgZ2l2ZW4gYSBkaXN0aW5ndWlzaGluZyB2ZXJzaW9uIG51bWJlci4gIElmIHRoZSBMaWJyYXJ5CitzcGVjaWZpZXMgYSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIExpY2Vuc2Ugd2hpY2ggYXBwbGllcyB0byBpdCBhbmQKKyJhbnkgbGF0ZXIgdmVyc2lvbiIsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgZm9sbG93aW5nIHRoZSB0ZXJtcyBhbmQKK2NvbmRpdGlvbnMgZWl0aGVyIG9mIHRoYXQgdmVyc2lvbiBvciBvZiBhbnkgbGF0ZXIgdmVyc2lvbiBwdWJsaXNoZWQgYnkKK3RoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBJZiB0aGUgTGlicmFyeSBkb2VzIG5vdCBzcGVjaWZ5IGEKK2xpY2Vuc2UgdmVyc2lvbiBudW1iZXIsIHlvdSBtYXkgY2hvb3NlIGFueSB2ZXJzaW9uIGV2ZXIgcHVibGlzaGVkIGJ5Cit0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgorDAorICAxNC4gSWYgeW91IHdpc2ggdG8gaW5jb3Jwb3JhdGUgcGFydHMgb2YgdGhlIExpYnJhcnkgaW50byBvdGhlciBmcmVlCitwcm9ncmFtcyB3aG9zZSBkaXN0cmlidXRpb24gY29uZGl0aW9ucyBhcmUgaW5jb21wYXRpYmxlIHdpdGggdGhlc2UsCit3cml0ZSB0byB0aGUgYXV0aG9yIHRvIGFzayBmb3IgcGVybWlzc2lvbi4gIEZvciBzb2Z0d2FyZSB3aGljaCBpcworY29weXJpZ2h0ZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd3JpdGUgdG8gdGhlIEZyZWUKK1NvZnR3YXJlIEZvdW5kYXRpb247IHdlIHNvbWV0aW1lcyBtYWtlIGV4Y2VwdGlvbnMgZm9yIHRoaXMuICBPdXIKK2RlY2lzaW9uIHdpbGwgYmUgZ3VpZGVkIGJ5IHRoZSB0d28gZ29hbHMgb2YgcHJlc2VydmluZyB0aGUgZnJlZSBzdGF0dXMKK29mIGFsbCBkZXJpdmF0aXZlcyBvZiBvdXIgZnJlZSBzb2Z0d2FyZSBhbmQgb2YgcHJvbW90aW5nIHRoZSBzaGFyaW5nCithbmQgcmV1c2Ugb2Ygc29mdHdhcmUgZ2VuZXJhbGx5LgorCisJCQkgICAgTk8gV0FSUkFOVFkKKworICAxNS4gQkVDQVVTRSBUSEUgTElCUkFSWSBJUyBMSUNFTlNFRCBGUkVFIE9GIENIQVJHRSwgVEhFUkUgSVMgTk8KK1dBUlJBTlRZIEZPUiBUSEUgTElCUkFSWSwgVE8gVEhFIEVYVEVOVCBQRVJNSVRURUQgQlkgQVBQTElDQUJMRSBMQVcuCitFWENFUFQgV0hFTiBPVEhFUldJU0UgU1RBVEVEIElOIFdSSVRJTkcgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORC9PUgorT1RIRVIgUEFSVElFUyBQUk9WSURFIFRIRSBMSUJSQVJZICJBUyBJUyIgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkKK0tJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQorSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLiAgVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUKK0xJQlJBUlkgSVMgV0lUSCBZT1UuICBTSE9VTEQgVEhFIExJQlJBUlkgUFJPVkUgREVGRUNUSVZFLCBZT1UgQVNTVU1FCitUSEUgQ09TVCBPRiBBTEwgTkVDRVNTQVJZIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uCisKKyAgMTYuIElOIE5PIEVWRU5UIFVOTEVTUyBSRVFVSVJFRCBCWSBBUFBMSUNBQkxFIExBVyBPUiBBR1JFRUQgVE8gSU4KK1dSSVRJTkcgV0lMTCBBTlkgQ09QWVJJR0hUIEhPTERFUiwgT1IgQU5ZIE9USEVSIFBBUlRZIFdITyBNQVkgTU9ESUZZCitBTkQvT1IgUkVESVNUUklCVVRFIFRIRSBMSUJSQVJZIEFTIFBFUk1JVFRFRCBBQk9WRSwgQkUgTElBQkxFIFRPIFlPVQorRk9SIERBTUFHRVMsIElOQ0xVRElORyBBTlkgR0VORVJBTCwgU1BFQ0lBTCwgSU5DSURFTlRBTCBPUgorQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT1IgSU5BQklMSVRZIFRPIFVTRSBUSEUKK0xJQlJBUlkgKElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gTE9TUyBPRiBEQVRBIE9SIERBVEEgQkVJTkcKK1JFTkRFUkVEIElOQUNDVVJBVEUgT1IgTE9TU0VTIFNVU1RBSU5FRCBCWSBZT1UgT1IgVEhJUkQgUEFSVElFUyBPUiBBCitGQUlMVVJFIE9GIFRIRSBMSUJSQVJZIFRPIE9QRVJBVEUgV0lUSCBBTlkgT1RIRVIgU09GVFdBUkUpLCBFVkVOIElGCitTVUNIIEhPTERFUiBPUiBPVEhFUiBQQVJUWSBIQVMgQkVFTiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICitEQU1BR0VTLgorCisJCSAgICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCisMCisgICAgICAgICAgIEhvdyB0byBBcHBseSBUaGVzZSBUZXJtcyB0byBZb3VyIE5ldyBMaWJyYXJpZXMKKworICBJZiB5b3UgZGV2ZWxvcCBhIG5ldyBsaWJyYXJ5LCBhbmQgeW91IHdhbnQgaXQgdG8gYmUgb2YgdGhlIGdyZWF0ZXN0Citwb3NzaWJsZSB1c2UgdG8gdGhlIHB1YmxpYywgd2UgcmVjb21tZW5kIG1ha2luZyBpdCBmcmVlIHNvZnR3YXJlIHRoYXQKK2V2ZXJ5b25lIGNhbiByZWRpc3RyaWJ1dGUgYW5kIGNoYW5nZS4gIFlvdSBjYW4gZG8gc28gYnkgcGVybWl0dGluZworcmVkaXN0cmlidXRpb24gdW5kZXIgdGhlc2UgdGVybXMgKG9yLCBhbHRlcm5hdGl2ZWx5LCB1bmRlciB0aGUgdGVybXMgb2YgdGhlCitvcmRpbmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlKS4KKworICBUbyBhcHBseSB0aGVzZSB0ZXJtcywgYXR0YWNoIHRoZSBmb2xsb3dpbmcgbm90aWNlcyB0byB0aGUgbGlicmFyeS4gIEl0IGlzCitzYWZlc3QgdG8gYXR0YWNoIHRoZW0gdG8gdGhlIHN0YXJ0IG9mIGVhY2ggc291cmNlIGZpbGUgdG8gbW9zdCBlZmZlY3RpdmVseQorY29udmV5IHRoZSBleGNsdXNpb24gb2Ygd2FycmFudHk7IGFuZCBlYWNoIGZpbGUgc2hvdWxkIGhhdmUgYXQgbGVhc3QgdGhlCisiY29weXJpZ2h0IiBsaW5lIGFuZCBhIHBvaW50ZXIgdG8gd2hlcmUgdGhlIGZ1bGwgbm90aWNlIGlzIGZvdW5kLgorCisgICAgPG9uZSBsaW5lIHRvIGdpdmUgdGhlIGxpYnJhcnkncyBuYW1lIGFuZCBhIGJyaWVmIGlkZWEgb2Ygd2hhdCBpdCBkb2VzLj4KKyAgICBDb3B5cmlnaHQgKEMpIDx5ZWFyPiAgPG5hbWUgb2YgYXV0aG9yPgorCisgICAgVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKKyAgICBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKKyAgICB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KKworICAgIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKKyAgICBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorCisgICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYworICAgIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKKyAgICBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCisKK0Fsc28gYWRkIGluZm9ybWF0aW9uIG9uIGhvdyB0byBjb250YWN0IHlvdSBieSBlbGVjdHJvbmljIGFuZCBwYXBlciBtYWlsLgorCitZb3Ugc2hvdWxkIGFsc28gZ2V0IHlvdXIgZW1wbG95ZXIgKGlmIHlvdSB3b3JrIGFzIGEgcHJvZ3JhbW1lcikgb3IgeW91cgorc2Nob29sLCBpZiBhbnksIHRvIHNpZ24gYSAiY29weXJpZ2h0IGRpc2NsYWltZXIiIGZvciB0aGUgbGlicmFyeSwgaWYKK25lY2Vzc2FyeS4gIEhlcmUgaXMgYSBzYW1wbGU7IGFsdGVyIHRoZSBuYW1lczoKKworICBZb3lvZHluZSwgSW5jLiwgaGVyZWJ5IGRpc2NsYWltcyBhbGwgY29weXJpZ2h0IGludGVyZXN0IGluIHRoZQorICBsaWJyYXJ5IGBGcm9iJyAoYSBsaWJyYXJ5IGZvciB0d2Vha2luZyBrbm9icykgd3JpdHRlbiBieSBKYW1lcyBSYW5kb20gSGFja2VyLgorCisgIDxzaWduYXR1cmUgb2YgVHkgQ29vbj4sIDEgQXByaWwgMTk5MAorICBUeSBDb29uLCBQcmVzaWRlbnQgb2YgVmljZQorCitUaGF0J3MgYWxsIHRoZXJlIGlzIHRvIGl0IQorCisKZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UudHh0IGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvbGljZW5zZS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIwODQxZQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL2xpY2Vuc2UudHh0CkBAIC0wLDAgKzEsMTkgQEAKK1NhbiBBbmdlbGVzIE9ic2VydmF0aW9uIE9wZW5HTCBFUyB2ZXJzaW9uIGV4YW1wbGUNCitDb3B5cmlnaHQgMjAwNC0yMDA1IEpldHJvIExhdWhhDQorQWxsIHJpZ2h0cyByZXNlcnZlZC4NCitXZWI6IGh0dHA6Ly9pa2kuZmkvamV0cm8vDQorDQorVGhpcyBzb3VyY2UgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQorbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiBFSVRIRVI6DQorICAoMSkgVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUNCisgICAgICBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdA0KKyAgICAgIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4gVGhlIHRleHQgb2YgdGhlIEdOVSBMZXNzZXINCisgICAgICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4gdGhlDQorICAgICAgZmlsZSBMSUNFTlNFLUxHUEwudHh0Lg0KKyAgKDIpIFRoZSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGlzIGluY2x1ZGVkIHdpdGggdGhpcyBzb3VyY2UgaW4NCisgICAgICB0aGUgZmlsZSBMSUNFTlNFLUJTRC50eHQuDQorDQorVGhpcyBzb3VyY2UgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCitidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KK01FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBmaWxlcw0KK0xJQ0VOU0UtTEdQTC50eHQgYW5kIExJQ0VOU0UtQlNELnR4dCBmb3IgbW9yZSBkZXRhaWxzLg0KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9hbmdlbGVzL3NoYXBlcy5oIGIvb3BlbmdsL3Rlc3RzL2FuZ2VsZXMvc2hhcGVzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjVmZmFlOAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy9hbmdlbGVzL3NoYXBlcy5oCkBAIC0wLDAgKzEsNTkgQEAKKy8qIFNhbiBBbmdlbGVzIE9ic2VydmF0aW9uIE9wZW5HTCBFUyB2ZXJzaW9uIGV4YW1wbGUKKyAqIENvcHlyaWdodCAyMDA0LTIwMDUgSmV0cm8gTGF1aGEKKyAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBXZWI6IGh0dHA6Ly9pa2kuZmkvamV0cm8vCisgKgorICogVGhpcyBzb3VyY2UgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCisgKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIEVJVEhFUjoKKyAqICAgKDEpIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCisgKiAgICAgICBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdAorICogICAgICAgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLiBUaGUgdGV4dCBvZiB0aGUgR05VIExlc3NlcgorICogICAgICAgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBpcyBpbmNsdWRlZCB3aXRoIHRoaXMgc291cmNlIGluIHRoZQorICogICAgICAgZmlsZSBMSUNFTlNFLUxHUEwudHh0LgorICogICAoMikgVGhlIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIHNvdXJjZSBpbgorICogICAgICAgdGhlIGZpbGUgTElDRU5TRS1CU0QudHh0LgorICoKKyAqIFRoaXMgc291cmNlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCisgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgorICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIGZpbGVzCisgKiBMSUNFTlNFLUxHUEwudHh0IGFuZCBMSUNFTlNFLUJTRC50eHQgZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiAkSWQ6IHNoYXBlcy5oLHYgMS42IDIwMDUvMDEvMzEgMjI6MTU6MzAgdG9uaWMgRXhwICQKKyAqICRSZXZpc2lvbjogMS42ICQKKyAqLworCisjaWZuZGVmIFNIQVBFU19IX0lOQ0xVREVECisjZGVmaW5lIFNIQVBFU19IX0lOQ0xVREVECisKKworI2RlZmluZSBTVVBFUlNIQVBFX1BBUkFNUyAxNQorCitzdGF0aWMgY29uc3QgZmxvYXQgc1N1cGVyU2hhcGVQYXJhbXNbXVtTVVBFUlNIQVBFX1BBUkFNU10gPQoreworICAgIC8vIG0gIGEgICAgIGIgICAgIG4xICAgICAgbjIgICAgIG4zICAgICBtICAgICBhICAgICBiICAgICBuMSAgICAgbjIgICAgICBuMyAgIHJlczEgcmVzMiBzY2FsZSAgKG9yZy5yZXMxLHJlczIpCisgICAgeyAxMCwgMSwgICAgMiwgICAgOTAsICAgICAgMSwgICAtNDUsICAgIDgsICAgIDEsICAgIDEsICAgIC0xLCAgICAgMSwgIC0wLjRmLCAgIDIwLCAgMzAsIDIgfSwgLy8gNDAsIDYwCisgICAgeyAxMCwgMSwgICAgMiwgICAgOTAsICAgICAgMSwgICAtNDUsICAgIDQsICAgIDEsICAgIDEsICAgIDEwLCAgICAgMSwgIC0wLjRmLCAgIDIwLCAgMjAsIDQgfSwgLy8gNDAsIDQwCisgICAgeyAxMCwgMSwgICAgMiwgICAgNjAsICAgICAgMSwgICAtMTAsICAgIDQsICAgIDEsICAgIDEsICAgIC0xLCAgICAtMiwgIC0wLjRmLCAgIDQxLCAgNDEsIDEgfSwgLy8gODIsIDgyCisgICAgeyAgNiwgMSwgICAgMSwgICAgNjAsICAgICAgMSwgICAtNzAsICAgIDgsICAgIDEsICAgIDEsICAwLjRmLCAgICAgMywgIDAuMjVmLCAgIDIwLCAgMjAsIDEgfSwgLy8gNDAsIDQwCisgICAgeyAgNCwgMSwgICAgMSwgICAgMzAsICAgICAgMSwgICAgMjAsICAgMTIsICAgIDEsICAgIDEsICAwLjRmLCAgICAgMywgIDAuMjVmLCAgIDEwLCAgMzAsIDEgfSwgLy8gMjAsIDYwCisgICAgeyAgOCwgMSwgICAgMSwgICAgMzAsICAgICAgMSwgICAgLTQsICAgIDgsICAgIDIsICAgIDEsICAgIC0xLCAgICAgNSwgICAwLjVmLCAgIDI1LCAgMjYsIDEgfSwgLy8gNjAsIDYwCisgICAgeyAxMywgMSwgICAgMSwgICAgMzAsICAgICAgMSwgICAgLTQsICAgMTMsICAgIDEsICAgIDEsICAgICAxLCAgICAgNSwgICAgICAxLCAgIDMwLCAgMzAsIDYgfSwgLy8gNjAsIDYwCisgICAgeyAxMCwgMSwgMS4xZiwgLTAuNWYsICAgMC4xZiwgICAgNzAsICAgNjAsICAgIDEsICAgIDEsICAgLTkwLCAgICAgMCwgLTAuMjVmLCAgIDIwLCAgNjAsIDggfSwgLy8gNjAsIDE4MAorICAgIHsgIDcsIDEsICAgIDEsICAgIDIwLCAgLTAuM2YsIC0zLjVmLCAgICA2LCAgICAxLCAgICAxLCAgICAtMSwgIDQuNWYsICAgMC41ZiwgICAxMCwgIDIwLCA0IH0sIC8vIDYwLCA4MAorICAgIHsgIDQsIDEsICAgIDEsICAgIDEwLCAgICAgMTAsICAgIDEwLCAgICA0LCAgICAxLCAgICAxLCAgICAxMCwgICAgMTAsICAgICAxMCwgICAxMCwgIDIwLCAxIH0sIC8vIDIwLCA0MAorICAgIHsgIDQsIDEsICAgIDEsICAgICAxLCAgICAgIDEsICAgICAxLCAgICA0LCAgICAxLCAgICAxLCAgICAgMSwgICAgIDEsICAgICAgMSwgICAxMCwgIDEwLCAyIH0sIC8vIDEwLCAxMAorICAgIHsgIDEsIDEsICAgIDEsICAgIDM4LCAtMC4yNWYsICAgIDE5LCAgICA0LCAgICAxLCAgICAxLCAgICAxMCwgICAgMTAsICAgICAxMCwgICAxMCwgIDE1LCAyIH0sIC8vIDIwLCA0MAorICAgIHsgIDIsIDEsICAgIDEsICAwLjdmLCAgIDAuM2YsICAwLjJmLCAgICAzLCAgICAxLCAgICAxLCAgIDEwMCwgICAxMDAsICAgIDEwMCwgICAxMCwgIDI1LCAyIH0sIC8vIDIwLCA1MAorICAgIHsgIDYsIDEsICAgIDEsICAgICAxLCAgICAgIDEsICAgICAxLCAgICAzLCAgICAxLCAgICAxLCAgICAgMSwgICAgIDEsICAgICAgMSwgICAzMCwgIDMwLCAyIH0sIC8vIDYwLCA2MAorICAgIHsgIDMsIDEsICAgIDEsICAgICAxLCAgICAgIDEsICAgICAxLCAgICA2LCAgICAxLCAgICAxLCAgICAgMiwgICAgIDEsICAgICAgMSwgICAxMCwgIDIwLCAyIH0sIC8vIDIwLCA0MAorICAgIHsgIDYsIDEsICAgIDEsICAgICA2LCAgIDUuNWYsICAgMTAwLCAgICA2LCAgICAxLCAgICAxLCAgICAyNSwgICAgMTAsICAgICAxMCwgICAzMCwgIDIwLCAyIH0sIC8vIDYwLCA0MAorICAgIHsgIDMsIDEsICAgIDEsICAwLjVmLCAgIDEuN2YsICAxLjdmLCAgICAyLCAgICAxLCAgICAxLCAgICAxMCwgICAgMTAsICAgICAxMCwgICAyMCwgIDIwLCAyIH0sIC8vIDQwLCA0MAorICAgIHsgIDUsIDEsICAgIDEsICAwLjFmLCAgIDEuN2YsICAxLjdmLCAgICAxLCAgICAxLCAgICAxLCAgMC4zZiwgIDAuNWYsICAgMC41ZiwgICAyMCwgIDIwLCA0IH0sIC8vIDQwLCA0MAorICAgIHsgIDIsIDEsICAgIDEsICAgICA2LCAgIDUuNWYsICAgMTAwLCAgICA2LCAgICAxLCAgICAxLCAgICAgNCwgICAgMTAsICAgICAxMCwgICAxMCwgIDIyLCAxIH0sIC8vIDQwLCA0MAorICAgIHsgIDYsIDEsICAgIDEsICAgIC0xLCAgICAgNzAsICAwLjFmLCAgICA5LCAgICAxLCAwLjVmLCAgIC05OCwgMC4wNWYsICAgIC00NSwgICAyMCwgIDMwLCA0IH0sIC8vIDYwLCA5MQorICAgIHsgIDYsIDEsICAgIDEsICAgIC0xLCAgICAgOTAsIC0wLjFmLCAgICA3LCAgICAxLCAgICAxLCAgICA5MCwgIDEuM2YsICAgICAzNCwgICAxMywgIDE2LCAxIH0sIC8vIDMyLCA2MAorfTsKKyNkZWZpbmUgU1VQRVJTSEFQRV9DT1VOVCAoc2l6ZW9mKHNTdXBlclNoYXBlUGFyYW1zKSAvIHNpemVvZihzU3VwZXJTaGFwZVBhcmFtc1swXSkpCisKKworI2VuZGlmIC8vICFTSEFQRVNfSF9JTkNMVURFRApkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL2ZpbHRlci9BbmRyb2lkLm1rIGIvb3BlbmdsL3Rlc3RzL2ZpbHRlci9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0NDhmMGQKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvZmlsdGVyL0FuZHJvaWQubWsKQEAgLTAsMCArMSwxNyBAQAorTE9DQUxfUEFUSDo9ICQoY2FsbCBteS1kaXIpCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfU1JDX0ZJTEVTOj0gXAorCWZpbHRlci5jCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgOj0gXAorCWxpYmN1dGlscyBcCisgICAgbGliRUdMIFwKKyAgICBsaWJHTEVTdjFfQ00gXAorICAgIGxpYnVpCisKK0xPQ0FMX01PRFVMRTo9IHRlc3Qtb3BlbmdsLWZpbHRlcgorCitMT0NBTF9NT0RVTEVfVEFHUyA6PSB0ZXN0cworCitpbmNsdWRlICQoQlVJTERfRVhFQ1VUQUJMRSkKZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9maWx0ZXIvZmlsdGVyLmMgYi9vcGVuZ2wvdGVzdHMvZmlsdGVyL2ZpbHRlci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlOTcxMTkKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdGVzdHMvZmlsdGVyL2ZpbHRlci5jCkBAIC0wLDAgKzEsMTMwIEBACisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKworI2luY2x1ZGUgPEVHTC9lZ2wuaD4KKyNpbmNsdWRlIDxHTEVTL2dsLmg+CisjaW5jbHVkZSA8R0xFUy9nbGV4dC5oPgorCitpbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpCit7CisgICAgaWYgKGFyZ2MhPTIgJiYgYXJnYyE9MykgeworICAgICAgICBwcmludGYoInVzYWdlOiAlcyA8MC02PiBbcGJ1ZmZlcl1cbiIsIGFyZ3ZbMF0pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgCisgICAgY29uc3QgaW50IHRlc3QgPSBhdG9pKGFyZ3ZbMV0pOworICAgIGludCB1c2VQYnVmZmVyID0gYXJnYz09MyAmJiAhc3RyY21wKGFyZ3ZbMl0sICJwYnVmZmVyIik7CisgICAgRUdMaW50IHNfY29uZmlnQXR0cmlic1tdID0geworICAgICAgICAgRUdMX1NVUkZBQ0VfVFlQRSwgRUdMX1BCVUZGRVJfQklUfEVHTF9XSU5ET1dfQklULAorICAgICAgICAgRUdMX1JFRF9TSVpFLCAgICAgICA1LAorICAgICAgICAgRUdMX0dSRUVOX1NJWkUsICAgICA2LAorICAgICAgICAgRUdMX0JMVUVfU0laRSwgICAgICA1LAorICAgICAgICAgRUdMX05PTkUKKyAgICAgfTsKKyAgICAgCisgICAgIEVHTGludCBudW1Db25maWdzID0gLTE7CisgICAgIEVHTGludCBtYWpvclZlcnNpb247CisgICAgIEVHTGludCBtaW5vclZlcnNpb247CisgICAgIEVHTENvbmZpZyBjb25maWc7CisgICAgIEVHTENvbnRleHQgY29udGV4dDsKKyAgICAgRUdMU3VyZmFjZSBzdXJmYWNlOworICAgICBFR0xpbnQgdywgaDsKKyAgICAgCisgICAgIEVHTERpc3BsYXkgZHB5OworCisgICAgIGRweSA9IGVnbEdldERpc3BsYXkoRUdMX0RFRkFVTFRfRElTUExBWSk7CisgICAgIGVnbEluaXRpYWxpemUoZHB5LCAmbWFqb3JWZXJzaW9uLCAmbWlub3JWZXJzaW9uKTsKKyAgICAgZWdsQ2hvb3NlQ29uZmlnKGRweSwgc19jb25maWdBdHRyaWJzLCAmY29uZmlnLCAxLCAmbnVtQ29uZmlncyk7CisgICAgIGlmICghdXNlUGJ1ZmZlcikgeworICAgICAgICAgc3VyZmFjZSA9IGVnbENyZWF0ZVdpbmRvd1N1cmZhY2UoZHB5LCBjb25maWcsCisgICAgICAgICAgICAgICAgIGFuZHJvaWRfY3JlYXRlRGlzcGxheVN1cmZhY2UoKSwgTlVMTCk7CisgICAgIH0gZWxzZSB7CisgICAgICAgICBwcmludGYoInVzaW5nIHBidWZmZXJcbiIpOworICAgICAgICAgRUdMaW50IGF0dHJpYnNbXSA9IHsgRUdMX1dJRFRILCAzMjAsIEVHTF9IRUlHSFQsIDQ4MCwgRUdMX05PTkUgfTsKKyAgICAgICAgIHN1cmZhY2UgPSBlZ2xDcmVhdGVQYnVmZmVyU3VyZmFjZShkcHksIGNvbmZpZywgYXR0cmlicyk7CisgICAgICAgICBpZiAoc3VyZmFjZSA9PSBFR0xfTk9fU1VSRkFDRSkgeworICAgICAgICAgICAgIHByaW50ZigiZWdsQ3JlYXRlUGJ1ZmZlclN1cmZhY2UgZXJyb3IgJXhcbiIsIGVnbEdldEVycm9yKCkpOworICAgICAgICAgfQorICAgICB9CisgICAgIGNvbnRleHQgPSBlZ2xDcmVhdGVDb250ZXh0KGRweSwgY29uZmlnLCBOVUxMLCBOVUxMKTsKKyAgICAgZWdsTWFrZUN1cnJlbnQoZHB5LCBzdXJmYWNlLCBzdXJmYWNlLCBjb250ZXh0KTsgICAKKyAgICAgZWdsUXVlcnlTdXJmYWNlKGRweSwgc3VyZmFjZSwgRUdMX1dJRFRILCAmdyk7CisgICAgIGVnbFF1ZXJ5U3VyZmFjZShkcHksIHN1cmZhY2UsIEVHTF9IRUlHSFQsICZoKTsKKyAgICAgR0xpbnQgZGltID0gdzxoID8gdyA6IGg7CisKKyAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKworICAgICBHTGludCBjcm9wWzRdID0geyAwLCA0LCA0LCAtNCB9OworICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOworICAgICBnbFRleFBhcmFtZXRlcml2KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfQ1JPUF9SRUNUX09FUywgY3JvcCk7CisgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX0xJTkVBUik7CisgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX0xJTkVBUik7CisgICAgIGdsVGV4RW52eChHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CisgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOworICAgICBnbENvbG9yNGYoMSwxLDEsMSk7CisKKyAgICAgLy8gcGFja2luZyBpcyBhbHdheXMgNAorICAgICB1aW50OF90IHQ4W10gID0geyAKKyAgICAgICAgICAgICAweDAwLCAweDU1LCAweDAwLCAweDU1LCAKKyAgICAgICAgICAgICAweEFBLCAweEZGLCAweEFBLCAweEZGLAorICAgICAgICAgICAgIDB4MDAsIDB4NTUsIDB4MDAsIDB4NTUsIAorICAgICAgICAgICAgIDB4QUEsIDB4RkYsIDB4QUEsIDB4RkYgIH07CisKKyAgICAgdWludDE2X3QgdDE2W10gID0geyAKKyAgICAgICAgICAgICAweDAwMDAsIDB4NTU1NSwgMHgwMDAwLCAweDU1NTUsIAorICAgICAgICAgICAgIDB4QUFBQSwgMHhGRkZGLCAweEFBQUEsIDB4RkZGRiwKKyAgICAgICAgICAgICAweDAwMDAsIDB4NTU1NSwgMHgwMDAwLCAweDU1NTUsIAorICAgICAgICAgICAgIDB4QUFBQSwgMHhGRkZGLCAweEFBQUEsIDB4RkZGRiAgfTsKKworICAgICB1aW50MTZfdCB0NTU1MVtdICA9IHsgCisgICAgICAgICAgICAgMHgwMDAwLCAweEZGRkYsIDB4MDAwMCwgMHhGRkZGLCAKKyAgICAgICAgICAgICAweEZGRkYsIDB4MDAwMCwgMHhGRkZGLCAweDAwMDAsCisgICAgICAgICAgICAgMHgwMDAwLCAweEZGRkYsIDB4MDAwMCwgMHhGRkZGLCAKKyAgICAgICAgICAgICAweEZGRkYsIDB4MDAwMCwgMHhGRkZGLCAweDAwMDAgIH07CisKKyAgICAgdWludDMyX3QgdDMyW10gID0geyAKKyAgICAgICAgICAgICAweEZGMDAwMDAwLCAweEZGMDAwMEZGLCAweEZGMDBGRjAwLCAweEZGRkYwMDAwLCAKKyAgICAgICAgICAgICAweEZGMDBGRjAwLCAweEZGRkYwMDAwLCAweEZGMDAwMDAwLCAweEZGMDAwMEZGLCAKKyAgICAgICAgICAgICAweEZGMDBGRkZGLCAweEZGMDBGRjAwLCAweDAwRkYwMEZGLCAweEZGRkZGRjAwLCAKKyAgICAgICAgICAgICAweEZGMDAwMDAwLCAweEZGRkYwMEZGLCAweEZGMDBGRkZGLCAweEZGRkZGRkZGCisgICAgIH07CisKKyAgICAgc3dpdGNoKHRlc3QpIAorICAgICB7CisgICAgIGNhc2UgMToKKyAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9MVU1JTkFOQ0UsCisgICAgICAgICAgICAgICAgIDQsIDQsIDAsIEdMX0xVTUlOQU5DRSwgR0xfVU5TSUdORURfQllURSwgdDgpOworICAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgMjoKKyAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0IsCisgICAgICAgICAgICAgICAgIDQsIDQsIDAsIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsIHQxNik7CisgICAgICAgICBicmVhazsKKyAgICAgY2FzZSAzOgorICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsCisgICAgICAgICAgICAgICAgIDQsIDQsIDAsIEdMX1JHQkEsIEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQsIHQxNik7CisgICAgICAgICBicmVhazsKKyAgICAgY2FzZSA0OgorICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX0xVTUlOQU5DRV9BTFBIQSwKKyAgICAgICAgICAgICAgICAgNCwgNCwgMCwgR0xfTFVNSU5BTkNFX0FMUEhBLCBHTF9VTlNJR05FRF9CWVRFLCB0MTYpOworICAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgNToKKyAgICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLAorICAgICAgICAgICAgICAgICA0LCA0LCAwLCBHTF9SR0JBLCBHTF9VTlNJR05FRF9TSE9SVF81XzVfNV8xLCB0NTU1MSk7CisgICAgICAgICBicmVhazsKKyAgICAgY2FzZSA2OgorICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsCisgICAgICAgICAgICAgICAgIDQsIDQsIDAsIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIHQzMik7CisgICAgICAgICBicmVhazsKKyAgICAgfQorCisgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgZGltLCBkaW0pOworCisgICAgIGlmICghdXNlUGJ1ZmZlcikgeworICAgICAgICAgZWdsU3dhcEJ1ZmZlcnMoZHB5LCBzdXJmYWNlKTsKKyAgICAgfSBlbHNlIHsKKyAgICAgICAgIGdsRmluaXNoKCk7CisgICAgIH0KKyAgICAgCisgICAgIGVnbFRlcm1pbmF0ZShkcHkpOworICAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy9maW5pc2gvQW5kcm9pZC5tayBiL29wZW5nbC90ZXN0cy9maW5pc2gvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjgzNmMxCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL2ZpbmlzaC9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsMTcgQEAKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKwlmaW5pc2guYworCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJjdXRpbHMgXAorICAgIGxpYkVHTCBcCisgICAgbGliR0xFU3YxX0NNIFwKKyAgICBsaWJ1aQorCitMT0NBTF9NT0RVTEU6PSB0ZXN0LW9wZW5nbC1maW5pc2gKKworTE9DQUxfTU9EVUxFX1RBR1MgOj0gdGVzdHMKKworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvZmluaXNoL2ZpbmlzaC5jIGIvb3BlbmdsL3Rlc3RzL2ZpbmlzaC9maW5pc2guYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWZjNzU4Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL2ZpbmlzaC9maW5pc2guYwpAQCAtMCwwICsxLDIyNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHRpbWUuaD4KKyNpbmNsdWRlIDxzY2hlZC5oPgorI2luY2x1ZGUgPHN5cy9yZXNvdXJjZS5oPgorCisjaW5jbHVkZSA8RUdML2VnbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKyNpbmNsdWRlIDxHTEVTL2dsZXh0Lmg+CisKKworbG9uZyBsb25nIHN5c3RlbVRpbWUoKQoreworICAgIHN0cnVjdCB0aW1lc3BlYyB0OworICAgIHQudHZfc2VjID0gdC50dl9uc2VjID0gMDsKKyAgICBjbG9ja19nZXR0aW1lKENMT0NLX01PTk9UT05JQywgJnQpOworICAgIHJldHVybiAobG9uZyBsb25nKSh0LnR2X3NlYykqMTAwMDAwMDAwMExMICsgdC50dl9uc2VjOworfQorCitpbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpCit7CisgICAgRUdMaW50IHNfY29uZmlnQXR0cmlic1tdID0geworICAgICAgICAgRUdMX1JFRF9TSVpFLCAgICAgICA1LAorICAgICAgICAgRUdMX0dSRUVOX1NJWkUsICAgICA2LAorICAgICAgICAgRUdMX0JMVUVfU0laRSwgICAgICA1LAorICAgICAgICAgRUdMX05PTkUKKyAgICAgfTsKKyAgICAgCisgICAgIEVHTGludCBudW1Db25maWdzID0gLTE7CisgICAgIEVHTGludCBtYWpvclZlcnNpb247CisgICAgIEVHTGludCBtaW5vclZlcnNpb247CisgICAgIEVHTENvbmZpZyBjb25maWc7CisgICAgIEVHTENvbnRleHQgY29udGV4dDsKKyAgICAgRUdMU3VyZmFjZSBzdXJmYWNlOworICAgICBFR0xpbnQgdywgaDsKKyAgICAgCisgICAgIEVHTERpc3BsYXkgZHB5OworCisgICAgIGRweSA9IGVnbEdldERpc3BsYXkoRUdMX0RFRkFVTFRfRElTUExBWSk7CisgICAgIGVnbEluaXRpYWxpemUoZHB5LCAmbWFqb3JWZXJzaW9uLCAmbWlub3JWZXJzaW9uKTsKKyAgICAgZWdsQ2hvb3NlQ29uZmlnKGRweSwgc19jb25maWdBdHRyaWJzLCAmY29uZmlnLCAxLCAmbnVtQ29uZmlncyk7CisgICAgIHN1cmZhY2UgPSBlZ2xDcmVhdGVXaW5kb3dTdXJmYWNlKGRweSwgY29uZmlnLCAKKyAgICAgICAgICAgICBhbmRyb2lkX2NyZWF0ZURpc3BsYXlTdXJmYWNlKCksIE5VTEwpOworICAgICBjb250ZXh0ID0gZWdsQ3JlYXRlQ29udGV4dChkcHksIGNvbmZpZywgTlVMTCwgTlVMTCk7CisgICAgIGVnbE1ha2VDdXJyZW50KGRweSwgc3VyZmFjZSwgc3VyZmFjZSwgY29udGV4dCk7ICAgCisgICAgIGVnbFF1ZXJ5U3VyZmFjZShkcHksIHN1cmZhY2UsIEVHTF9XSURUSCwgJncpOworICAgICBlZ2xRdWVyeVN1cmZhY2UoZHB5LCBzdXJmYWNlLCBFR0xfSEVJR0hULCAmaCk7CisgICAgIEdMaW50IGRpbSA9IHc8aCA/IHcgOiBoOworCisgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CisgICAgIGdsVGV4UGFyYW1ldGVyeChHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOworICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKKyAgICAgZ2xUZXhFbnZ4KEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKKyAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CisgICAgIGdsQ29sb3I0ZigxLDEsMSwxKTsKKyAgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgIGdsU2hhZGVNb2RlbChHTF9GTEFUKTsKKworICAgICBsb25nIGxvbmcgbm93LCB0OworICAgICBpbnQgaTsKKworICAgICBjaGFyKiB0ZXhlbHMgPSBtYWxsb2MoNTEyKjUxMioyKTsKKyAgICAgbWVtc2V0KHRleGVscywweEZGLDUxMio1MTIqMik7CisgICAgIAorICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCLAorICAgICAgICAgICAgIDUxMiwgNTEyLCAwLCBHTF9SR0IsIEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81LCB0ZXhlbHMpOworCisgICAgIGNoYXIqIGRzdCA9IG1hbGxvYygzMjAqNDgwKjIpOworICAgICBtZW1zZXQoZHN0LCAwLCAzMjAqNDgwKjIpOworICAgICBwcmludGYoIjMwNzIwMCBieXRlcyBtZW1jcHlcbiIpOworICAgICBmb3IgKGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgbm93ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgbWVtY3B5KGRzdCwgdGV4ZWxzLCAzMjAqNDgwKjIpOworICAgICAgICAgdCA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIHByaW50ZigibWVtY3B5KCkgdGltZSA9ICVsbHUgdXNcbiIsICh0LW5vdykvMTAwMCk7CisgICAgICAgICBmZmx1c2goc3Rkb3V0KTsKKyAgICAgfQorICAgICBmcmVlKGRzdCk7CisKKyAgICAgZnJlZSh0ZXhlbHMpOworCisgICAgIHNldHByaW9yaXR5KFBSSU9fUFJPQ0VTUywgMCwgLTIwKTsKKyAgICAgCisgICAgIHByaW50ZigiNTEyeDUxMiB1bm1vZGlmaWVkIHRleHR1cmUsIDUxMng1MTIgYmxpdDpcbiIpOworICAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgICBmb3IgKGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgNTEyLCA1MTIsIC01MTIgfTsKKyAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgIG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgNTEyLCA1MTIpOworICAgICAgICAgZ2xGaW5pc2goKTsKKyAgICAgICAgIHQgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBwcmludGYoImdsRmluaXNoKCkgdGltZSA9ICVsbHUgdXNcbiIsICh0LW5vdykvMTAwMCk7CisgICAgICAgICBmZmx1c2goc3Rkb3V0KTsKKyAgICAgICAgIGVnbFN3YXBCdWZmZXJzKGRweSwgc3VyZmFjZSk7CisgICAgIH0KKyAgICAgCisgICAgIHByaW50ZigiNTEyeDUxMiB1bm1vZGlmaWVkIHRleHR1cmUsIDF4MSBibGl0OlxuIik7CisgICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CisgICAgIGZvciAoaT0wIDsgaTw0IDsgaSsrKSB7CisgICAgICAgICBHTGludCBjcm9wWzRdID0geyAwLCAxLCAxLCAtMSB9OworICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpdihHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIGNyb3ApOworICAgICAgICAgbm93ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgZ2xEcmF3VGV4aU9FUygwLCAwLCAwLCAxLCAxKTsKKyAgICAgICAgIGdsRmluaXNoKCk7CisgICAgICAgICB0ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgcHJpbnRmKCJnbEZpbmlzaCgpIHRpbWUgPSAlbGx1IHVzXG4iLCAodC1ub3cpLzEwMDApOworICAgICAgICAgZmZsdXNoKHN0ZG91dCk7CisgICAgICAgICBlZ2xTd2FwQnVmZmVycyhkcHksIHN1cmZhY2UpOworICAgICB9CisgICAgIAorICAgICBwcmludGYoIjUxMng1MTIgdW5tb2RpZmllZCB0ZXh0dXJlLCA1MTJ4NTEyIGJsaXQgKHgyKTpcbiIpOworICAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgICBmb3IgKGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgNTEyLCA1MTIsIC01MTIgfTsKKyAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgIG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgNTEyLCA1MTIpOworICAgICAgICAgZ2xEcmF3VGV4aU9FUygwLCAwLCAwLCA1MTIsIDUxMik7CisgICAgICAgICBnbEZpbmlzaCgpOworICAgICAgICAgdCA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIHByaW50ZigiZ2xGaW5pc2goKSB0aW1lID0gJWxsdSB1c1xuIiwgKHQtbm93KS8xMDAwKTsKKyAgICAgICAgIGZmbHVzaChzdGRvdXQpOworICAgICAgICAgZWdsU3dhcEJ1ZmZlcnMoZHB5LCBzdXJmYWNlKTsKKyAgICAgfQorCisgICAgIHByaW50ZigiNTEyeDUxMiB1bm1vZGlmaWVkIHRleHR1cmUsIDF4MSBibGl0ICh4Mik6XG4iKTsKKyAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKyAgICAgZm9yIChpPTAgOyBpPDQgOyBpKyspIHsKKyAgICAgICAgIEdMaW50IGNyb3BbNF0gPSB7IDAsIDEsIDEsIC0xIH07CisgICAgICAgICBnbFRleFBhcmFtZXRlcml2KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfQ1JPUF9SRUNUX09FUywgY3JvcCk7CisgICAgICAgICBub3cgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBnbERyYXdUZXhpT0VTKDAsIDAsIDAsIDEsIDEpOworICAgICAgICAgZ2xEcmF3VGV4aU9FUygwLCAwLCAwLCAxLCAxKTsKKyAgICAgICAgIGdsRmluaXNoKCk7CisgICAgICAgICB0ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgcHJpbnRmKCJnbEZpbmlzaCgpIHRpbWUgPSAlbGx1IHVzXG4iLCAodC1ub3cpLzEwMDApOworICAgICAgICAgZmZsdXNoKHN0ZG91dCk7CisgICAgICAgICBlZ2xTd2FwQnVmZmVycyhkcHksIHN1cmZhY2UpOworICAgICB9CisKKyAgICAgCisgICAgIHByaW50ZigiNTEyeDUxMiAoMXgxIHRleGVsIE1PRElGSUVEIHRleHR1cmUpLCA1MTJ4NTEyIGJsaXQ6XG4iKTsKKyAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKyAgICAgZm9yIChpPTAgOyBpPDQgOyBpKyspIHsKKyAgICAgICAgIHVpbnQxNl90IGdyZWVuID0gMHg3RTA7CisgICAgICAgICBHTGludCBjcm9wWzRdID0geyAwLCA1MTIsIDUxMiwgLTUxMiB9OworICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpdihHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIGNyb3ApOworICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIDAsIDAsIDEsIDEsIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsICZncmVlbik7CisgICAgICAgICBub3cgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBnbERyYXdUZXhpT0VTKDAsIDAsIDAsIDUxMiwgNTEyKTsKKyAgICAgICAgIGdsRmluaXNoKCk7CisgICAgICAgICB0ID0gc3lzdGVtVGltZSgpOworICAgICAgICAgcHJpbnRmKCJnbEZpbmlzaCgpIHRpbWUgPSAlbGx1IHVzXG4iLCAodC1ub3cpLzEwMDApOworICAgICAgICAgZmZsdXNoKHN0ZG91dCk7CisgICAgICAgICBlZ2xTd2FwQnVmZmVycyhkcHksIHN1cmZhY2UpOworICAgICB9CisKKworICAgICBpbnQxNl90IHRleGVsID0gMHhGODAwOworICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCLAorICAgICAgICAgICAgIDEsIDEsIDAsIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsICZ0ZXhlbCk7CisKKyAgICAgcHJpbnRmKCIxeDEgdW5tb2RpZmllZCB0ZXh0dXJlLCAxeDEgYmxpdDpcbiIpOworICAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgICBmb3IgKGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgMSwgMSwgLTEgfTsKKyAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgIG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgMSwgMSk7CisgICAgICAgICBnbEZpbmlzaCgpOworICAgICAgICAgdCA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIHByaW50ZigiZ2xGaW5pc2goKSB0aW1lID0gJWxsdSB1c1xuIiwgKHQtbm93KS8xMDAwKTsKKyAgICAgICAgIGVnbFN3YXBCdWZmZXJzKGRweSwgc3VyZmFjZSk7CisgICAgIH0KKworICAgICBwcmludGYoIjF4MSB1bm1vZGlmaWVkIHRleHR1cmUsIDUxMng1MTIgYmxpdDpcbiIpOworICAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgICBmb3IgKGk9MCA7IGk8NCA7IGkrKykgeworICAgICAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgMSwgMSwgLTEgfTsKKyAgICAgICAgIGdsVGV4UGFyYW1ldGVyaXYoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9DUk9QX1JFQ1RfT0VTLCBjcm9wKTsKKyAgICAgICAgIG5vdyA9IHN5c3RlbVRpbWUoKTsKKyAgICAgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgNTEyLCA1MTIpOworICAgICAgICAgZ2xGaW5pc2goKTsKKyAgICAgICAgIHQgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBwcmludGYoImdsRmluaXNoKCkgdGltZSA9ICVsbHUgdXNcbiIsICh0LW5vdykvMTAwMCk7CisgICAgICAgICBmZmx1c2goc3Rkb3V0KTsKKyAgICAgICAgIGVnbFN3YXBCdWZmZXJzKGRweSwgc3VyZmFjZSk7CisgICAgIH0KKworICAgICBwcmludGYoIjF4MSAoMXgxIHRleGVsIE1PRElGSUVEIHRleHR1cmUpLCA1MTJ4NTEyIGJsaXQ6XG4iKTsKKyAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKyAgICAgZm9yIChpPTAgOyBpPDQgOyBpKyspIHsKKyAgICAgICAgIHVpbnQxNl90IGdyZWVuID0gMHg3RTA7CisgICAgICAgICBHTGludCBjcm9wWzRdID0geyAwLCAxLCAxLCAtMSB9OworICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpdihHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIGNyb3ApOworICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIDAsIDAsIDEsIDEsIEdMX1JHQiwgR0xfVU5TSUdORURfU0hPUlRfNV82XzUsICZncmVlbik7CisgICAgICAgICBub3cgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBnbERyYXdUZXhpT0VTKDAsIDAsIDAsIDEsIDEpOworICAgICAgICAgZ2xGaW5pc2goKTsKKyAgICAgICAgIHQgPSBzeXN0ZW1UaW1lKCk7CisgICAgICAgICBwcmludGYoImdsRmluaXNoKCkgdGltZSA9ICVsbHUgdXNcbiIsICh0LW5vdykvMTAwMCk7CisgICAgICAgICBmZmx1c2goc3Rkb3V0KTsKKyAgICAgICAgIGVnbFN3YXBCdWZmZXJzKGRweSwgc3VyZmFjZSk7CisgICAgIH0KKworICAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy90ZXh0dXJlcy9BbmRyb2lkLm1rIGIvb3BlbmdsL3Rlc3RzL3RleHR1cmVzL0FuZHJvaWQubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThjNjIyMAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90ZXN0cy90ZXh0dXJlcy9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsMTcgQEAKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKwl0ZXh0dXJlcy5jCisKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgOj0gXAorCWxpYmN1dGlscyBcCisgICAgbGliRUdMIFwKKyAgICBsaWJHTEVTdjFfQ00gXAorICAgIGxpYnVpCisKK0xPQ0FMX01PRFVMRTo9IHRlc3Qtb3BlbmdsLXRleHR1cmVzCisKK0xPQ0FMX01PRFVMRV9UQUdTIDo9IHRlc3RzCisKK2luY2x1ZGUgJChCVUlMRF9FWEVDVVRBQkxFKQpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rlc3RzL3RleHR1cmVzL3RleHR1cmVzLmMgYi9vcGVuZ2wvdGVzdHMvdGV4dHVyZXMvdGV4dHVyZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTQyOTFiCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL3RleHR1cmVzL3RleHR1cmVzLmMKQEAgLTAsMCArMSwxMDkgQEAKKy8qCisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorI2luY2x1ZGUgPEdMRVMvZ2xleHQuaD4KKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KQoreworICAgIEVHTGludCBzX2NvbmZpZ0F0dHJpYnNbXSA9IHsKKyAgICAgICAgIEVHTF9SRURfU0laRSwgICAgICAgNSwKKyAgICAgICAgIEVHTF9HUkVFTl9TSVpFLCAgICAgNiwKKyAgICAgICAgIEVHTF9CTFVFX1NJWkUsICAgICAgNSwKKyAgICAgICAgIEVHTF9OT05FCisgICAgIH07CisgICAgIAorICAgICBFR0xpbnQgbnVtQ29uZmlncyA9IC0xOworICAgICBFR0xpbnQgbWFqb3JWZXJzaW9uOworICAgICBFR0xpbnQgbWlub3JWZXJzaW9uOworICAgICBFR0xDb25maWcgY29uZmlnOworICAgICBFR0xDb250ZXh0IGNvbnRleHQ7CisgICAgIEVHTFN1cmZhY2Ugc3VyZmFjZTsKKyAgICAgRUdMaW50IHcsIGg7CisgICAgIAorICAgICBFR0xEaXNwbGF5IGRweTsKKworICAgICBkcHkgPSBlZ2xHZXREaXNwbGF5KEVHTF9ERUZBVUxUX0RJU1BMQVkpOworICAgICBlZ2xJbml0aWFsaXplKGRweSwgJm1ham9yVmVyc2lvbiwgJm1pbm9yVmVyc2lvbik7CisgICAgIGVnbENob29zZUNvbmZpZyhkcHksIHNfY29uZmlnQXR0cmlicywgJmNvbmZpZywgMSwgJm51bUNvbmZpZ3MpOworICAgICBzdXJmYWNlID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShkcHksIGNvbmZpZywKKyAgICAgICAgICAgICBhbmRyb2lkX2NyZWF0ZURpc3BsYXlTdXJmYWNlKCksIE5VTEwpOworICAgICBjb250ZXh0ID0gZWdsQ3JlYXRlQ29udGV4dChkcHksIGNvbmZpZywgTlVMTCwgTlVMTCk7CisgICAgIGVnbE1ha2VDdXJyZW50KGRweSwgc3VyZmFjZSwgc3VyZmFjZSwgY29udGV4dCk7ICAgCisgICAgIGVnbFF1ZXJ5U3VyZmFjZShkcHksIHN1cmZhY2UsIEVHTF9XSURUSCwgJncpOworICAgICBlZ2xRdWVyeVN1cmZhY2UoZHB5LCBzdXJmYWNlLCBFR0xfSEVJR0hULCAmaCk7CisgICAgIEdMaW50IGRpbSA9IHc8aCA/IHcgOiBoOworCisKKyAgICAgR0xpbnQgY3JvcFs0XSA9IHsgMCwgNCwgNCwgLTQgfTsKKyAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKKyAgICAgZ2xUZXhQYXJhbWV0ZXJpdihHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX0NST1BfUkVDVF9PRVMsIGNyb3ApOworICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9MSU5FQVIpOworICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9MSU5FQVIpOworICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QX1RPX0VER0UpOworICAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QX1RPX0VER0UpOworICAgICBnbFRleEVudngoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOworICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKKyAgICAgZ2xDb2xvcjRmKDEsMSwxLDEpOworCisgICAgIC8vIHBhY2tpbmcgaXMgYWx3YXlzIDQKKyAgICAgdWludDhfdCB0OFtdICA9IHsgCisgICAgICAgICAgICAgMHgwMCwgMHg1NSwgMHgwMCwgMHg1NSwgCisgICAgICAgICAgICAgMHhBQSwgMHhGRiwgMHhBQSwgMHhGRiwKKyAgICAgICAgICAgICAweDAwLCAweDU1LCAweDAwLCAweDU1LCAKKyAgICAgICAgICAgICAweEFBLCAweEZGLCAweEFBLCAweEZGICB9OworCisgICAgIHVpbnQxNl90IHQxNltdICA9IHsgCisgICAgICAgICAgICAgMHgwMDAwLCAweDU1NTUsIDB4MDAwMCwgMHg1NTU1LCAKKyAgICAgICAgICAgICAweEFBQUEsIDB4RkZGRiwgMHhBQUFBLCAweEZGRkYsCisgICAgICAgICAgICAgMHgwMDAwLCAweDU1NTUsIDB4MDAwMCwgMHg1NTU1LCAKKyAgICAgICAgICAgICAweEFBQUEsIDB4RkZGRiwgMHhBQUFBLCAweEZGRkYgIH07CisKKyAgICAgdWludDE2X3QgdDU1NTFbXSAgPSB7IAorICAgICAgICAgICAgIDB4MDAwMCwgMHhGRkZGLCAweDAwMDAsIDB4RkZGRiwgCisgICAgICAgICAgICAgMHhGRkZGLCAweDAwMDAsIDB4RkZGRiwgMHgwMDAwLAorICAgICAgICAgICAgIDB4MDAwMCwgMHhGRkZGLCAweDAwMDAsIDB4RkZGRiwgCisgICAgICAgICAgICAgMHhGRkZGLCAweDAwMDAsIDB4RkZGRiwgMHgwMDAwICB9OworCisgICAgIHVpbnQzMl90IHQzMltdICA9IHsgCisgICAgICAgICAgICAgMHhGRjAwMDAwMCwgMHhGRjAwMDBGRiwgMHhGRjAwRkYwMCwgMHhGRkZGMDAwMCwgCisgICAgICAgICAgICAgMHhGRjAwRkYwMCwgMHhGRkZGMDAwMCwgMHhGRjAwMDAwMCwgMHhGRjAwMDBGRiwgCisgICAgICAgICAgICAgMHhGRjAwRkZGRiwgMHhGRjAwRkYwMCwgMHgwMEZGMDBGRiwgMHhGRkZGRkYwMCwgCisgICAgICAgICAgICAgMHhGRjAwMDAwMCwgMHhGRkZGMDBGRiwgMHhGRjAwRkZGRiwgMHhGRkZGRkZGRgorICAgICB9OworCisKKyAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKKyAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX0xVTUlOQU5DRSwgNCwgNCwgMCwgR0xfTFVNSU5BTkNFLCBHTF9VTlNJR05FRF9CWVRFLCB0OCk7CisgICAgIGdsRHJhd1RleGlPRVMoMCwgMCwgMCwgZGltLzIsIGRpbS8yKTsKKworICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCLCA0LCA0LCAwLCBHTF9SR0IsIEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81LCB0MTYpOworICAgICBnbERyYXdUZXhpT0VTKGRpbS8yLCAwLCAwLCBkaW0vMiwgZGltLzIpOworCisgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCA0LCA0LCAwLCBHTF9SR0JBLCBHTF9VTlNJR05FRF9TSE9SVF80XzRfNF80LCB0MTYpOworICAgICBnbERyYXdUZXhpT0VTKDAsIGRpbS8yLCAwLCBkaW0vMiwgZGltLzIpOworCisgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCA0LCA0LCAwLCBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLCB0MzIpOworICAgICBnbERyYXdUZXhpT0VTKGRpbS8yLCBkaW0vMiwgMCwgZGltLzIsIGRpbS8yKTsKKworICAgICBlZ2xTd2FwQnVmZmVycyhkcHksIHN1cmZhY2UpOworICAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL29wZW5nbC90ZXN0cy90cml0ZXgvQW5kcm9pZC5tayBiL29wZW5nbC90ZXN0cy90cml0ZXgvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2QxZjA0Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL3RyaXRleC9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsMTcgQEAKK0xPQ0FMX1BBVEg6PSAkKGNhbGwgbXktZGlyKQoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKK0xPQ0FMX1NSQ19GSUxFUzo9IFwKKwl0cml0ZXguYworCitMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9IFwKKwlsaWJjdXRpbHMgXAorICAgIGxpYkVHTCBcCisgICAgbGliR0xFU3YxX0NNIFwKKyAgICBsaWJ1aQorCitMT0NBTF9NT0RVTEU6PSB0ZXN0LW9wZW5nbC10cml0ZXgKKworTE9DQUxfTU9EVUxFX1RBR1MgOj0gdGVzdHMKKworaW5jbHVkZSAkKEJVSUxEX0VYRUNVVEFCTEUpCmRpZmYgLS1naXQgYS9vcGVuZ2wvdGVzdHMvdHJpdGV4L3RyaXRleC5jIGIvb3BlbmdsL3Rlc3RzL3RyaXRleC90cml0ZXguYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGE3ZmViCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rlc3RzL3RyaXRleC90cml0ZXguYwpAQCAtMCwwICsxLDI3MyBAQAorLy8gQ2FsbHMgZ2xEcmF3RWxlbWVudHMoKSB0aGUgbnVtYmVyIG9mIHRpbWVzIHNwZWNpZmllZCBieQorLy8gSVRFUkFUSU9OUy4gU2hvdWxkIGRyYXcgYSBjaGVja2VyYm9hcmQgb24gdGhlIHNjcmVlbiBhZnRlcgorLy8gYSBmZXcgc2Vjb25kcy4KKy8vCisvLyBQb3J0ZWQgZnJvbSBhIEphdmEgdmVyc2lvbiBieSBHb29nbGUuCisKKyNpbmNsdWRlIDxFR0wvZWdsLmg+DQorI2luY2x1ZGUgPEdMRVMvZ2wuaD4KKworI2luY2x1ZGUgPHN0ZGlvLmg+DQorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPG1hdGguaD4KKw0KK0VHTERpc3BsYXkgZWdsRGlzcGxheTsNCitFR0xTdXJmYWNlIGVnbFN1cmZhY2U7DQorRUdMQ29udGV4dCBlZ2xDb250ZXh0Ow0KK0dMdWludCB0ZXh0dXJlOw0KKw0KKyNkZWZpbmUgRklYRURfT05FIDB4MTAwMDAKKyNkZWZpbmUgSVRFUkFUSU9OUyA1MA0KKw0KK2ludCBpbml0X2dsX3N1cmZhY2Uodm9pZCk7DQordm9pZCBmcmVlX2dsX3N1cmZhY2Uodm9pZCk7DQordm9pZCBpbml0X3NjZW5lKHZvaWQpOw0KK3ZvaWQgcmVuZGVyKGludCBxdWFkcyk7DQordm9pZCBjcmVhdGVfdGV4dHVyZSh2b2lkKTsKK2ludCByZWFkVGltZXIodm9pZCk7DQorCitzdGF0aWMgdm9pZCBnbHVMb29rQXQoZmxvYXQgZXllWCwgZmxvYXQgZXllWSwgZmxvYXQgZXllWiwKKyAgICAgICAgZmxvYXQgY2VudGVyWCwgZmxvYXQgY2VudGVyWSwgZmxvYXQgY2VudGVyWiwgZmxvYXQgdXBYLCBmbG9hdCB1cFksCisgICAgICAgIGZsb2F0IHVwWikKK3sKKyAgICAvLyBTZWUgdGhlIE9wZW5HTCBHTFVUIGRvY3VtZW50YXRpb24gZm9yIGdsdUxvb2tBdCBmb3IgYSBkZXNjcmlwdGlvbgorICAgIC8vIG9mIHRoZSBhbGdvcml0aG0uIFdlIGltcGxlbWVudCBpdCBpbiBhIHN0cmFpZ2h0Zm9yd2FyZCB3YXk6CisKKyAgICBmbG9hdCBmeCA9IGNlbnRlclggLSBleWVYOworICAgIGZsb2F0IGZ5ID0gY2VudGVyWSAtIGV5ZVk7CisgICAgZmxvYXQgZnogPSBjZW50ZXJaIC0gZXllWjsKKworICAgIC8vIE5vcm1hbGl6ZSBmCisgICAgZmxvYXQgcmxmID0gMS4wZiAvIHNxcnRmKGZ4KmZ4ICsgZnkqZnkgKyBmeipmeik7CisgICAgZnggKj0gcmxmOworICAgIGZ5ICo9IHJsZjsKKyAgICBmeiAqPSBybGY7CisKKyAgICAvLyBOb3JtYWxpemUgdXAKKyAgICBmbG9hdCBybHVwID0gMS4wZiAvIHNxcnRmKHVwWCp1cFggKyB1cFkqdXBZICsgdXBaKnVwWik7CisgICAgdXBYICo9IHJsdXA7CisgICAgdXBZICo9IHJsdXA7CisgICAgdXBaICo9IHJsdXA7CisKKyAgICAvLyBjb21wdXRlIHMgPSBmIHggdXAgKHggbWVhbnMgImNyb3NzIHByb2R1Y3QiKQorCisgICAgZmxvYXQgc3ggPSBmeSAqIHVwWiAtIGZ6ICogdXBZOworICAgIGZsb2F0IHN5ID0gZnogKiB1cFggLSBmeCAqIHVwWjsKKyAgICBmbG9hdCBzeiA9IGZ4ICogdXBZIC0gZnkgKiB1cFg7CisKKyAgICAvLyBjb21wdXRlIHUgPSBzIHggZgorICAgIGZsb2F0IHV4ID0gc3kgKiBmeiAtIHN6ICogZnk7CisgICAgZmxvYXQgdXkgPSBzeiAqIGZ4IC0gc3ggKiBmejsKKyAgICBmbG9hdCB1eiA9IHN4ICogZnkgLSBzeSAqIGZ4OworCisgICAgZmxvYXQgbVsxNl0gOworICAgIG1bMF0gPSBzeDsKKyAgICBtWzFdID0gdXg7CisgICAgbVsyXSA9IC1meDsKKyAgICBtWzNdID0gMC4wZjsKKworICAgIG1bNF0gPSBzeTsKKyAgICBtWzVdID0gdXk7CisgICAgbVs2XSA9IC1meTsKKyAgICBtWzddID0gMC4wZjsKKworICAgIG1bOF0gPSBzejsKKyAgICBtWzldID0gdXo7CisgICAgbVsxMF0gPSAtZno7CisgICAgbVsxMV0gPSAwLjBmOworCisgICAgbVsxMl0gPSAwLjBmOworICAgIG1bMTNdID0gMC4wZjsKKyAgICBtWzE0XSA9IDAuMGY7CisgICAgbVsxNV0gPSAxLjBmOworCisgICAgZ2xNdWx0TWF0cml4ZihtKTsKKyAgICBnbFRyYW5zbGF0ZWYoLWV5ZVgsIC1leWVZLCAtZXllWik7Cit9CisNCitpbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpDQorew0KKyAgICBpbnQgcTsKKyAgICBpbnQgc3RhcnQsIGVuZDsNCisKKyAgICBwcmludGYoIkluaXRpYWxpemluZyBFR0wuLi5cbiIpOworDQorICAgIGlmKCFpbml0X2dsX3N1cmZhY2UoKSkNCisgICAgew0KKyAgICAgICAgcHJpbnRmKCJHTCBpbml0aWFsaXNhdGlvbiBmYWlsZWQgLSBleGl0aW5nXG4iKTsNCisgICAgICAgIHJldHVybiAwOw0KKyAgICB9DQorDQorICAgIGluaXRfc2NlbmUoKTsNCisNCisgICAgY3JlYXRlX3RleHR1cmUoKTsNCisNCisgICAgcHJpbnRmKCJTdGFydCB0ZXN0Li4uXG4iKTsKKworICAgIHJlbmRlcihhcmdjPT0yID8gYXRvaShhcmd2WzFdKSA6IElURVJBVElPTlMpOw0KKw0KKyAgICBmcmVlX2dsX3N1cmZhY2UoKTsNCisNCisgICAgcmV0dXJuIDA7DQorfQ0KKw0KK2ludCBpbml0X2dsX3N1cmZhY2Uodm9pZCkNCit7DQorICAgIEVHTGludCBudW1Db25maWdzID0gMTsNCisgICAgRUdMQ29uZmlnIG15Q29uZmlnID0gezB9Ow0KKyAgICBFR0xpbnQgYXR0cmliW10gPQ0KKyAgICB7DQorICAgICAgICAgICAgRUdMX0RFUFRIX1NJWkUsICAgICAxNiwNCisgICAgICAgICAgICBFR0xfTk9ORQ0KKyAgICB9Ow0KKw0KKyAgICBpZiAoIChlZ2xEaXNwbGF5ID0gZWdsR2V0RGlzcGxheShFR0xfREVGQVVMVF9ESVNQTEFZKSkgPT0gRUdMX05PX0RJU1BMQVkgKQ0KKyAgICB7DQorICAgICAgICBwcmludGYoImVnbEdldERpc3BsYXkgZmFpbGVkXG4iKTsNCisgICAgICAgIHJldHVybiAwOw0KKyAgICB9DQorDQorICAgIGlmICggZWdsSW5pdGlhbGl6ZShlZ2xEaXNwbGF5LCBOVUxMLCBOVUxMKSAhPSBFR0xfVFJVRSApDQorICAgIHsNCisgICAgICAgIHByaW50ZigiZWdsSW5pdGlhbGl6ZSBmYWlsZWRcbiIpOw0KKyAgICAgICAgcmV0dXJuIDA7DQorICAgIH0NCisNCisgICAgaWYgKCBlZ2xDaG9vc2VDb25maWcoZWdsRGlzcGxheSwgYXR0cmliLCAmbXlDb25maWcsIDEsICZudW1Db25maWdzKSAhPSBFR0xfVFJVRSApDQorICAgIHsNCisgICAgICAgIHByaW50ZigiZWdsQ2hvb3NlQ29uZmlnIGZhaWxlZFxuIik7DQorICAgICAgICByZXR1cm4gMDsNCisgICAgfQ0KKw0KKyAgICBpZiAoIChlZ2xTdXJmYWNlID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShlZ2xEaXNwbGF5LCBteUNvbmZpZywKKyAgICAgICAgICAgIGFuZHJvaWRfY3JlYXRlRGlzcGxheVN1cmZhY2UoKSwgMCkpID09IEVHTF9OT19TVVJGQUNFICkNCisgICAgew0KKyAgICAgICAgcHJpbnRmKCJlZ2xDcmVhdGVXaW5kb3dTdXJmYWNlIGZhaWxlZFxuIik7DQorICAgICAgICByZXR1cm4gMDsNCisgICAgfQ0KKw0KKyAgICBpZiAoIChlZ2xDb250ZXh0ID0gZWdsQ3JlYXRlQ29udGV4dChlZ2xEaXNwbGF5LCBteUNvbmZpZywgMCwgMCkpID09IEVHTF9OT19DT05URVhUICkNCisgICAgew0KKyAgICAgICAgcHJpbnRmKCJlZ2xDcmVhdGVDb250ZXh0IGZhaWxlZFxuIik7DQorICAgICAgICByZXR1cm4gMDsNCisgICAgfQ0KKw0KKyAgICBpZiAoIGVnbE1ha2VDdXJyZW50KGVnbERpc3BsYXksIGVnbFN1cmZhY2UsIGVnbFN1cmZhY2UsIGVnbENvbnRleHQpICE9IEVHTF9UUlVFICkNCisgICAgew0KKyAgICAgICAgcHJpbnRmKCJlZ2xNYWtlQ3VycmVudCBmYWlsZWRcbiIpOw0KKyAgICAgICAgcmV0dXJuIDA7DQorICAgIH0NCisNCisgICAgcmV0dXJuIDE7DQorfQ0KKw0KK3ZvaWQgZnJlZV9nbF9zdXJmYWNlKHZvaWQpDQorew0KKyAgICBpZiAoZWdsRGlzcGxheSAhPSBFR0xfTk9fRElTUExBWSkNCisgICAgew0KKyAgICAgICAgZWdsTWFrZUN1cnJlbnQoIEVHTF9OT19ESVNQTEFZLCBFR0xfTk9fU1VSRkFDRSwNCisgICAgICAgICAgICAgICAgRUdMX05PX1NVUkZBQ0UsIEVHTF9OT19DT05URVhUICk7DQorICAgICAgICBlZ2xEZXN0cm95Q29udGV4dCggZWdsRGlzcGxheSwgZWdsQ29udGV4dCApOw0KKyAgICAgICAgZWdsRGVzdHJveVN1cmZhY2UoIGVnbERpc3BsYXksIGVnbFN1cmZhY2UgKTsNCisgICAgICAgIGVnbFRlcm1pbmF0ZSggZWdsRGlzcGxheSApOw0KKyAgICAgICAgZWdsRGlzcGxheSA9IEVHTF9OT19ESVNQTEFZOw0KKyAgICB9DQorfQ0KKw0KK3ZvaWQgaW5pdF9zY2VuZSh2b2lkKQ0KK3sNCisgICAgZ2xEaXNhYmxlKEdMX0RJVEhFUik7CisgICAgZ2xFbmFibGUoR0xfQ1VMTF9GQUNFKTsKKworICAgIGZsb2F0IHJhdGlvID0gMzIwLjBmIC8gNDgwLjBmOworICAgIGdsVmlld3BvcnQoMCwgMCwgMzIwLCA0ODApOworCisgICAgZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pOworICAgIGdsTG9hZElkZW50aXR5KCk7CisgICAgZ2xGcnVzdHVtZigtcmF0aW8sIHJhdGlvLCAtMSwgMSwgMSwgMTApOworCisgICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7DQorICAgIGdsTG9hZElkZW50aXR5KCk7CisgICAgZ2x1TG9va0F0KAorICAgICAgICAgICAgMCwgMCwgMywgIC8vIGV5ZQorICAgICAgICAgICAgMCwgMCwgMCwgIC8vIGNlbnRlcgorICAgICAgICAgICAgMCwgMSwgMCk7IC8vIHVwCisNCisgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7DQorICAgIGdsRW5hYmxlQ2xpZW50U3RhdGUoR0xfVkVSVEVYX0FSUkFZKTsNCisgICAgZ2xFbmFibGVDbGllbnRTdGF0ZShHTF9URVhUVVJFX0NPT1JEX0FSUkFZKTsKK30NCisNCit2b2lkIGNyZWF0ZV90ZXh0dXJlKHZvaWQpDQorew0KKyAgICBjb25zdCB1bnNpZ25lZCBpbnQgb24gPSAweGZmMDAwMGZmOworICAgIGNvbnN0IHVuc2lnbmVkIGludCBvZmYgPSAweGZmZmZmZmZmOworICAgIGNvbnN0IHVuc2lnbmVkIGludCBwaXhlbHNbXSA9CisgICAgeworICAgICAgICAgICAgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwKKyAgICAgICAgICAgIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sCisgICAgICAgICAgICBvbiwgb2ZmLCBvbiwgb2ZmLCBvbiwgb2ZmLCBvbiwgb2ZmLAorICAgICAgICAgICAgb2ZmLCBvbiwgb2ZmLCBvbiwgb2ZmLCBvbiwgb2ZmLCBvbiwKKyAgICAgICAgICAgIG9uLCBvZmYsIG9uLCBvZmYsIG9uLCBvZmYsIG9uLCBvZmYsCisgICAgICAgICAgICBvZmYsIG9uLCBvZmYsIG9uLCBvZmYsIG9uLCBvZmYsIG9uLAorICAgICAgICAgICAgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwKKyAgICAgICAgICAgIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sIG9mZiwgb24sCisgICAgfTsNCisgICAgZ2xHZW5UZXh0dXJlcygxLCAmdGV4dHVyZSk7DQorICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4dHVyZSk7DQorICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCA4LCA4LCAwLCBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLCBwaXhlbHMpOw0KKyAgICBnbFRleFBhcmFtZXRlcngoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsNCisgICAgZ2xUZXhQYXJhbWV0ZXJ4KEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7DQorICAgIGdsVGV4RW52eChHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7DQorfQ0KKw0KK3ZvaWQgcmVuZGVyKGludCBxdWFkcykNCit7DQorICAgIGludCBpLCBqOw0KKw0KKyAgICBjb25zdCBHTGZsb2F0IHZlcnRpY2VzW10gPSB7DQorICAgICAgICAgICAgLTEsICAtMSwgIDAsDQorICAgICAgICAgICAgIDEsICAtMSwgIDAsDQorICAgICAgICAgICAgIDEsICAgMSwgIDAsDQorICAgICAgICAgICAgLTEsICAgMSwgIDANCisgICAgfTsNCisNCisgICAgY29uc3QgR0xmaXhlZCB0ZXhDb29yZHNbXSA9IHsNCisgICAgICAgICAgICAwLCAgICAgICAgICAgIDAsDQorICAgICAgICAgICAgRklYRURfT05FLCAgICAwLA0KKyAgICAgICAgICAgIEZJWEVEX09ORSwgICAgRklYRURfT05FLA0KKyAgICAgICAgICAgIDAsICAgICAgICAgICAgRklYRURfT05FDQorICAgIH07DQorDQorICAgIGNvbnN0IEdMdXNob3J0IHRlbXBsYXRlW10gPSB7IDAsIDEsIDIsICAwLCAyLCAzIH07CisKKworICAgIEdMdXNob3J0KiBpbmRpY2VzID0gKEdMdXNob3J0KiltYWxsb2MocXVhZHMqc2l6ZW9mKHRlbXBsYXRlKSk7CisgICAgZm9yIChpPTAgOyBpPHF1YWRzIDsgaSsrKQorICAgICAgICBtZW1jcHkoaW5kaWNlcysoc2l6ZW9mKHRlbXBsYXRlKS9zaXplb2YoaW5kaWNlc1swXSkpKmksIHRlbXBsYXRlLCBzaXplb2YodGVtcGxhdGUpKTsKKw0KKyAgICBnbFZlcnRleFBvaW50ZXIoMywgR0xfRkxPQVQsIDAsIHZlcnRpY2VzKTsNCisgICAgZ2xUZXhDb29yZFBvaW50ZXIoMiwgR0xfRklYRUQsIDAsIHRleENvb3Jkcyk7CisKKyAgICAvLyBtYWtlIHN1cmUgdG8gZG8gYSBjb3VwbGUgZWdsU3dhcEJ1ZmZlcnMgdG8gbWFrZSBzdXJlIHRoZXJlIGFyZQorICAgIC8vIG5vIHByb2JsZW1zIHdpdGggdGhlIHZlcnkgZmlyc3Qgb25lcyAod2hvIGtub3dzKQorICAgIGdsQ2xlYXJDb2xvcigwLjQsIDAuNCwgMC40LCAwLjQpOworICAgIGdsQ2xlYXIoR0xfREVQVEhfQlVGRkVSX0JJVCB8IEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgIGVnbFN3YXBCdWZmZXJzKGVnbERpc3BsYXksIGVnbFN1cmZhY2UpOworICAgIGdsQ2xlYXJDb2xvcigwLjYsIDAuNiwgMC42LCAwLjYpOworICAgIGdsQ2xlYXIoR0xfREVQVEhfQlVGRkVSX0JJVCB8IEdMX0NPTE9SX0JVRkZFUl9CSVQpOworICAgIGVnbFN3YXBCdWZmZXJzKGVnbERpc3BsYXksIGVnbFN1cmZhY2UpOworICAgIGdsQ2xlYXJDb2xvcigxLjAsIDEuMCwgMS4wLCAxLjApOworCisgICAgZm9yIChqPTAgOyBqPDEwIDsgaisrKSB7CisgICAgICAgIHByaW50ZigibG9vcCAlZCAvIDEwICglZCBxdWFkcyAvIGxvb3ApXG4iLCBqLCBxdWFkcyk7CisKKyAgICAgICAgaW50IG5lbGVtID0gc2l6ZW9mKHRlbXBsYXRlKS9zaXplb2YodGVtcGxhdGVbMF0pOworICAgICAgICBnbENsZWFyKEdMX0RFUFRIX0JVRkZFUl9CSVQgfCBHTF9DT0xPUl9CVUZGRVJfQklUKTsKKyAgICAgICAgZ2xEcmF3RWxlbWVudHMoR0xfVFJJQU5HTEVTLCBuZWxlbSpxdWFkcywgR0xfVU5TSUdORURfU0hPUlQsIGluZGljZXMpOworICAgICAgICBlZ2xTd2FwQnVmZmVycyhlZ2xEaXNwbGF5LCBlZ2xTdXJmYWNlKTsKKyAgICB9CisKKyAgICBmcmVlKGluZGljZXMpOw0KK30NCisKZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9nZW4gYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2VuCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjFjNDk4NjEKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2VuCkBAIC0wLDAgKzEsOTkgQEAKKyMhL2Jpbi9zaAorcm0gLXJmIG91dCBnZW5lcmF0ZWQKKworbWtkaXIgb3V0Citta2RpciAtcCBvdXQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMKK21rZGlyIC1wIG91dC9jb20vZ29vZ2xlL2FuZHJvaWQvZ2xlc19qbmkKK21rZGlyIC1wIG91dC9hbmRyb2lkL2dyYXBoaWNzCisKK2VjaG8gInBhY2thZ2UgYW5kcm9pZC5ncmFwaGljczsiID4gb3V0L2FuZHJvaWQvZ3JhcGhpY3MvQ2FudmFzLmphdmEKK2VjaG8gInB1YmxpYyBpbnRlcmZhY2UgQ2FudmFzIHt9IiA+PiBvdXQvYW5kcm9pZC9ncmFwaGljcy9DYW52YXMuamF2YQorCitHTEZJTEU9b3V0L2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMLmphdmEKK2NwIHN0dWJzL0dMSGVhZGVyLmphdmEtaWYgJEdMRklMRQorCitHTEdFTl9GSUxFUz0iQ0Z1bmMuamF2YSBDVHlwZS5qYXZhIENvZGVFbWl0dGVyLmphdmEgR2VuZXJhdGVHTC5qYXZhIEpGdW5jLmphdmEgSlR5cGUuamF2YSBKbmlDb2RlRW1pdHRlci5qYXZhIFBhcmFtZXRlckNoZWNrZXIuamF2YSIKKworcHVzaGQgc3JjID4gL2Rldi9udWxsCitqYXZhYyAke0dMR0VOX0ZJTEVTfQorcG9wZCA+IC9kZXYvbnVsbAoramF2YSAtY2xhc3NwYXRoIHNyYyBHZW5lcmF0ZUdMIC1jIGdsc3BlYy0xLjAgZ2xzcGVjLTEuMGV4dCBnbHNwZWMtMS4xIGdsc3BlYy0xLjFleHQgZ2xzcGVjLTEuMWV4dHBhY2sgZ2xzcGVjLWNoZWNrcworCitwdXNoZCBvdXQgPiAvZGV2L251bGwKK21rZGlyIGNsYXNzZXMKK2phdmFjIC1kIGNsYXNzZXMgY29tL2dvb2dsZS9hbmRyb2lkL2dsZXNfam5pL0dMSW1wbC5qYXZhIGphdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTAuamF2YSBqYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwRXh0LmphdmEgamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMS5qYXZhIGphdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTFFeHQuamF2YSBqYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0ZW5zaW9uUGFjay5qYXZhCitwb3BkID4gL2Rldi9udWxsCisKK3JtIC1yZiBnZW5lcmF0ZWQKK21rZGlyIC1wIGdlbmVyYXRlZC9DCitjcCBvdXQvY29tX2dvb2dsZV9hbmRyb2lkX2dsZXNfam5pX0dMSW1wbC5jcHAgZ2VuZXJhdGVkL0MKK2NwIC1yIG91dC9jb20gZ2VuZXJhdGVkCitjcCAtciBvdXQvamF2YXggZ2VuZXJhdGVkCisKK3JtIC1yZiBvdXQKKworIyBjb21fZ29vZ2xlX2FuZHJvaWRfZ2xlc19qbmlfR0xJbXBsLmNwcAoraWYgY21wIC4uLy4uLy4uL2ZyYW1ld29ya3MvYmFzZS9jb3JlL2puaS9jb21fZ29vZ2xlX2FuZHJvaWRfZ2xlc19qbmlfR0xJbXBsLmNwcCBnZW5lcmF0ZWQvQy9jb21fZ29vZ2xlX2FuZHJvaWRfZ2xlc19qbmlfR0xJbXBsLmNwcCA7IHRoZW4KK2VjaG8gY29tX2dvb2dsZV9hbmRyb2lkX2dsZXNfam5pX0dMSW1wbC5jcHAgdW5jaGFuZ2VkCitlbHNlCitlY2hvIFBsZWFzZSBlZGl0IC4uLy4uLy4uL2ZyYW1ld29ya3MvYmFzZS9jb3JlL2puaS9jb21fZ29vZ2xlX2FuZHJvaWRfZ2xlc19qbmlfR0xJbXBsLmNwcAorZWNobyBQbGVhc2UgY3AgZ2VuZXJhdGVkL0MvY29tX2dvb2dsZV9hbmRyb2lkX2dsZXNfam5pX0dMSW1wbC5jcHAgLi4vLi4vLi4vZnJhbWV3b3Jrcy9iYXNlL2NvcmUvam5pCitmaQorCisjIEdMSW1wbC5qYXZhCitpZiBjbXAgLi4vLi4vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvZ2xlc19qbmkvR0xJbXBsLmphdmEgZ2VuZXJhdGVkL2NvbS9nb29nbGUvYW5kcm9pZC9nbGVzX2puaS9HTEltcGwuamF2YSA7IHRoZW4KK2VjaG8gR0xJbXBsLmphdmEgdW5jaGFuZ2VkCitlbHNlCitlY2hvIFBsZWFzZSBlZGl0IC4uLy4uL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2dsZXNfam5pL0dMSW1wbC5qYXZhCitlY2hvIFBsZWFzZSBjcCBnZW5lcmF0ZWQvY29tL2dvb2dsZS9hbmRyb2lkL2dsZXNfam5pL0dMSW1wbC5qYXZhIC4uLy4uL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2dsZXNfam5pCitmaQorCisjIEdMLmphdmEKK2lmIGNtcCAuLi8uLi9qYXZhL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMLmphdmEgZ2VuZXJhdGVkL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMLmphdmEgOyB0aGVuCitlY2hvIEdMLmphdmEgdW5jaGFuZ2VkCitlbHNlCitlY2hvIFBsZWFzZSBlZGl0IC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wuamF2YQorZWNobyBQbGVhc2UgY3AgZ2VuZXJhdGVkL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMLmphdmEgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTC5qYXZhCitmaQorCisjIEdMMTAuamF2YQoraWYgY21wIC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMC5qYXZhIGdlbmVyYXRlZC9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwLmphdmEgOyB0aGVuCitlY2hvIEdMMTAuamF2YSB1bmNoYW5nZWQKK2Vsc2UKK2VjaG8gUGxlYXNlIGVkaXQgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwLmphdmEKK2VjaG8gUGxlYXNlIGNwIGdlbmVyYXRlZC9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwLmphdmEgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwLmphdmEKK2ZpCisKKyMgR0wxMEV4dC5qYXZhCitpZiBjbXAgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwRXh0LmphdmEgZ2VuZXJhdGVkL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTBFeHQuamF2YSA7IHRoZW4KK2VjaG8gR0wxMEV4dC5qYXZhIHVuY2hhbmdlZAorZWxzZQorZWNobyBQbGVhc2UgZWRpdCAuLi8uLi9qYXZhL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTBFeHQuamF2YQorZWNobyBQbGVhc2UgY3AgZ2VuZXJhdGVkL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTBFeHQuamF2YSAuLi8uLi9qYXZhL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTBFeHQuamF2YQorZmkKKworIyBHTDExLmphdmEKK2lmIGNtcCAuLi8uLi9qYXZhL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTEuamF2YSBnZW5lcmF0ZWQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMS5qYXZhIDsgdGhlbgorZWNobyBHTDExLmphdmEgdW5jaGFuZ2VkCitlbHNlCitlY2hvIFBsZWFzZSBlZGl0IC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMS5qYXZhCitlY2hvIFBsZWFzZSBjcCBnZW5lcmF0ZWQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMS5qYXZhIC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMS5qYXZhCitmaQorCisjIEdMMTFFeHQuamF2YQoraWYgY21wIC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dC5qYXZhIGdlbmVyYXRlZC9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0LmphdmEgOyB0aGVuCitlY2hvIEdMMTFFeHQuamF2YSB1bmNoYW5nZWQKK2Vsc2UKK2VjaG8gUGxlYXNlIGVkaXQgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0LmphdmEKK2VjaG8gUGxlYXNlIGNwIGdlbmVyYXRlZC9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0LmphdmEgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0LmphdmEKK2ZpCisKKyMgR0wxMUV4dGVuc2lvblBhY2suamF2YQoraWYgY21wIC4uLy4uL2phdmEvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dGVuc2lvblBhY2suamF2YSBnZW5lcmF0ZWQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dGVuc2lvblBhY2suamF2YSA7IHRoZW4KK2VjaG8gR0wxMUV4dGVuc2lvblBhY2suamF2YSB1bmNoYW5nZWQKK2Vsc2UKK2VjaG8gUGxlYXNlIGVkaXQgLi4vLi4vamF2YS9qYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDExRXh0ZW5zaW9uUGFjay5qYXZhCitlY2hvIFBsZWFzZSBjcCBnZW5lcmF0ZWQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dGVuc2lvblBhY2suamF2YSAuLi8uLi9qYXZhL2phdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTFFeHRlbnNpb25QYWNrLmphdmEKK2ZpCisKK3JtIC1yZiBnZW5lcmF0ZWQKZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4wIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL2dsc3BlYy0xLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQ0MjMyMAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4wCkBAIC0wLDAgKzEsMTA2IEBACit2b2lkIGdsQWN0aXZlVGV4dHVyZSAoIEdMZW51bSB0ZXh0dXJlICkNCit2b2lkIGdsQWxwaGFGdW5jICggR0xlbnVtIGZ1bmMsIEdMY2xhbXBmIHJlZiApDQordm9pZCBnbEFscGhhRnVuY3ggKCBHTGVudW0gZnVuYywgR0xjbGFtcHggcmVmICkNCit2b2lkIGdsQmluZFRleHR1cmUgKCBHTGVudW0gdGFyZ2V0LCBHTHVpbnQgdGV4dHVyZSApDQordm9pZCBnbEJsZW5kRnVuYyAoIEdMZW51bSBzZmFjdG9yLCBHTGVudW0gZGZhY3RvciApDQordm9pZCBnbENsZWFyICggR0xiaXRmaWVsZCBtYXNrICkNCit2b2lkIGdsQ2xlYXJDb2xvciAoIEdMY2xhbXBmIHJlZCwgR0xjbGFtcGYgZ3JlZW4sIEdMY2xhbXBmIGJsdWUsIEdMY2xhbXBmIGFscGhhICkNCit2b2lkIGdsQ2xlYXJDb2xvcnggKCBHTGNsYW1weCByZWQsIEdMY2xhbXB4IGdyZWVuLCBHTGNsYW1weCBibHVlLCBHTGNsYW1weCBhbHBoYSApDQordm9pZCBnbENsZWFyRGVwdGhmICggR0xjbGFtcGYgZGVwdGggKQ0KK3ZvaWQgZ2xDbGVhckRlcHRoeCAoIEdMY2xhbXB4IGRlcHRoICkNCit2b2lkIGdsQ2xlYXJTdGVuY2lsICggR0xpbnQgcyApDQordm9pZCBnbENsaWVudEFjdGl2ZVRleHR1cmUgKCBHTGVudW0gdGV4dHVyZSApDQordm9pZCBnbENvbG9yNGYgKCBHTGZsb2F0IHJlZCwgR0xmbG9hdCBncmVlbiwgR0xmbG9hdCBibHVlLCBHTGZsb2F0IGFscGhhICkNCit2b2lkIGdsQ29sb3I0eCAoIEdMZml4ZWQgcmVkLCBHTGZpeGVkIGdyZWVuLCBHTGZpeGVkIGJsdWUsIEdMZml4ZWQgYWxwaGEgKQ0KK3ZvaWQgZ2xDb2xvck1hc2sgKCBHTGJvb2xlYW4gcmVkLCBHTGJvb2xlYW4gZ3JlZW4sIEdMYm9vbGVhbiBibHVlLCBHTGJvb2xlYW4gYWxwaGEgKQ0KK3ZvaWQgZ2xDb2xvclBvaW50ZXIgKCBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlciApDQordm9pZCBnbENvbXByZXNzZWRUZXhJbWFnZTJEICggR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMZW51bSBpbnRlcm5hbGZvcm1hdCwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMaW50IGJvcmRlciwgR0xzaXplaSBpbWFnZVNpemUsIGNvbnN0IEdMdm9pZCAqZGF0YSApDQordm9pZCBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEICggR0xlbnVtIHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IHhvZmZzZXQsIEdMaW50IHlvZmZzZXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTHNpemVpIGltYWdlU2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhICkNCit2b2lkIGdsQ29weVRleEltYWdlMkQgKCBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTGludCB4LCBHTGludCB5LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyICkNCit2b2lkIGdsQ29weVRleFN1YkltYWdlMkQgKCBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xpbnQgeG9mZnNldCwgR0xpbnQgeW9mZnNldCwgR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQgKQ0KK3ZvaWQgZ2xDdWxsRmFjZSAoIEdMZW51bSBtb2RlICkNCit2b2lkIGdsRGVsZXRlVGV4dHVyZXMgKCBHTHNpemVpIG4sIGNvbnN0IEdMdWludCAqdGV4dHVyZXMgKQ0KK3ZvaWQgZ2xEZXB0aEZ1bmMgKCBHTGVudW0gZnVuYyApDQordm9pZCBnbERlcHRoTWFzayAoIEdMYm9vbGVhbiBmbGFnICkNCit2b2lkIGdsRGVwdGhSYW5nZWYgKCBHTGNsYW1wZiB6TmVhciwgR0xjbGFtcGYgekZhciApDQordm9pZCBnbERlcHRoUmFuZ2V4ICggR0xjbGFtcHggek5lYXIsIEdMY2xhbXB4IHpGYXIgKQ0KK3ZvaWQgZ2xEaXNhYmxlICggR0xlbnVtIGNhcCApDQordm9pZCBnbERpc2FibGVDbGllbnRTdGF0ZSAoIEdMZW51bSBhcnJheSApDQordm9pZCBnbERyYXdBcnJheXMgKCBHTGVudW0gbW9kZSwgR0xpbnQgZmlyc3QsIEdMc2l6ZWkgY291bnQgKQ0KK3ZvaWQgZ2xEcmF3RWxlbWVudHMgKCBHTGVudW0gbW9kZSwgR0xzaXplaSBjb3VudCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqaW5kaWNlcyApDQordm9pZCBnbEVuYWJsZSAoIEdMZW51bSBjYXAgKQ0KK3ZvaWQgZ2xFbmFibGVDbGllbnRTdGF0ZSAoIEdMZW51bSBhcnJheSApDQordm9pZCBnbEZpbmlzaCAoIHZvaWQgKQ0KK3ZvaWQgZ2xGbHVzaCAoIHZvaWQgKQ0KK3ZvaWQgZ2xGb2dmICggR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtICkNCit2b2lkIGdsRm9nZnYgKCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyApDQordm9pZCBnbEZvZ3ggKCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0gKQ0KK3ZvaWQgZ2xGb2d4diAoIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zICkNCit2b2lkIGdsRnJvbnRGYWNlICggR0xlbnVtIG1vZGUgKQ0KK3ZvaWQgZ2xGcnVzdHVtZiAoIEdMZmxvYXQgbGVmdCwgR0xmbG9hdCByaWdodCwgR0xmbG9hdCBib3R0b20sIEdMZmxvYXQgdG9wLCBHTGZsb2F0IHpOZWFyLCBHTGZsb2F0IHpGYXIgKQ0KK3ZvaWQgZ2xGcnVzdHVteCAoIEdMZml4ZWQgbGVmdCwgR0xmaXhlZCByaWdodCwgR0xmaXhlZCBib3R0b20sIEdMZml4ZWQgdG9wLCBHTGZpeGVkIHpOZWFyLCBHTGZpeGVkIHpGYXIgKQ0KK3ZvaWQgZ2xHZW5UZXh0dXJlcyAoIEdMc2l6ZWkgbiwgR0x1aW50ICp0ZXh0dXJlcyApDQorR0xlbnVtIGdsR2V0RXJyb3IgKCB2b2lkICkNCit2b2lkIGdsR2V0SW50ZWdlcnYgKCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMgKQ0KK2NvbnN0IEdMdWJ5dGUgKiBnbEdldFN0cmluZyAoIEdMZW51bSBuYW1lICkNCit2b2lkIGdsSGludCAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBtb2RlICkNCit2b2lkIGdsTGlnaHRNb2RlbGYgKCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0gKQ0KK3ZvaWQgZ2xMaWdodE1vZGVsZnYgKCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyApDQordm9pZCBnbExpZ2h0TW9kZWx4ICggR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtICkNCit2b2lkIGdsTGlnaHRNb2RlbHh2ICggR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMgKQ0KK3ZvaWQgZ2xMaWdodGYgKCBHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSApDQordm9pZCBnbExpZ2h0ZnYgKCBHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zICkNCit2b2lkIGdsTGlnaHR4ICggR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgcGFyYW0gKQ0KK3ZvaWQgZ2xMaWdodHh2ICggR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyApDQordm9pZCBnbExpbmVXaWR0aCAoIEdMZmxvYXQgd2lkdGggKQ0KK3ZvaWQgZ2xMaW5lV2lkdGh4ICggR0xmaXhlZCB3aWR0aCApDQordm9pZCBnbExvYWRJZGVudGl0eSAoIHZvaWQgKQ0KK3ZvaWQgZ2xMb2FkTWF0cml4ZiAoIGNvbnN0IEdMZmxvYXQgKm0gKQ0KK3ZvaWQgZ2xMb2FkTWF0cml4eCAoIGNvbnN0IEdMZml4ZWQgKm0gKQ0KK3ZvaWQgZ2xMb2dpY09wICggR0xlbnVtIG9wY29kZSApDQordm9pZCBnbE1hdGVyaWFsZiAoIEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0gKQ0KK3ZvaWQgZ2xNYXRlcmlhbGZ2ICggR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zICkNCit2b2lkIGdsTWF0ZXJpYWx4ICggR0xlbnVtIGZhY2UsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCBwYXJhbSApDQordm9pZCBnbE1hdGVyaWFseHYgKCBHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZpeGVkICpwYXJhbXMgKQ0KK3ZvaWQgZ2xNYXRyaXhNb2RlICggR0xlbnVtIG1vZGUgKQ0KK3ZvaWQgZ2xNdWx0TWF0cml4ZiAoIGNvbnN0IEdMZmxvYXQgKm0gKQ0KK3ZvaWQgZ2xNdWx0TWF0cml4eCAoIGNvbnN0IEdMZml4ZWQgKm0gKQ0KK3ZvaWQgZ2xNdWx0aVRleENvb3JkNGYgKCBHTGVudW0gdGFyZ2V0LCBHTGZsb2F0IHMsIEdMZmxvYXQgdCwgR0xmbG9hdCByLCBHTGZsb2F0IHEgKQ0KK3ZvaWQgZ2xNdWx0aVRleENvb3JkNHggKCBHTGVudW0gdGFyZ2V0LCBHTGZpeGVkIHMsIEdMZml4ZWQgdCwgR0xmaXhlZCByLCBHTGZpeGVkIHEgKQ0KK3ZvaWQgZ2xOb3JtYWwzZiAoIEdMZmxvYXQgbngsIEdMZmxvYXQgbnksIEdMZmxvYXQgbnogKQ0KK3ZvaWQgZ2xOb3JtYWwzeCAoIEdMZml4ZWQgbngsIEdMZml4ZWQgbnksIEdMZml4ZWQgbnogKQ0KK3ZvaWQgZ2xOb3JtYWxQb2ludGVyICggR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBjb25zdCBHTHZvaWQgKnBvaW50ZXIgKQ0KK3ZvaWQgZ2xPcnRob2YgKCBHTGZsb2F0IGxlZnQsIEdMZmxvYXQgcmlnaHQsIEdMZmxvYXQgYm90dG9tLCBHTGZsb2F0IHRvcCwgR0xmbG9hdCB6TmVhciwgR0xmbG9hdCB6RmFyICkNCit2b2lkIGdsT3J0aG94ICggR0xmaXhlZCBsZWZ0LCBHTGZpeGVkIHJpZ2h0LCBHTGZpeGVkIGJvdHRvbSwgR0xmaXhlZCB0b3AsIEdMZml4ZWQgek5lYXIsIEdMZml4ZWQgekZhciApDQordm9pZCBnbFBpeGVsU3RvcmVpICggR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSApDQordm9pZCBnbFBvaW50U2l6ZSAoIEdMZmxvYXQgc2l6ZSApDQordm9pZCBnbFBvaW50U2l6ZXggKCBHTGZpeGVkIHNpemUgKQ0KK3ZvaWQgZ2xQb2x5Z29uT2Zmc2V0ICggR0xmbG9hdCBmYWN0b3IsIEdMZmxvYXQgdW5pdHMgKQ0KK3ZvaWQgZ2xQb2x5Z29uT2Zmc2V0eCAoIEdMZml4ZWQgZmFjdG9yLCBHTGZpeGVkIHVuaXRzICkNCit2b2lkIGdsUG9wTWF0cml4ICggdm9pZCApDQordm9pZCBnbFB1c2hNYXRyaXggKCB2b2lkICkNCit2b2lkIGdsUmVhZFBpeGVscyAoIEdMaW50IHgsIEdMaW50IHksIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgR0x2b2lkICpwaXhlbHMgKQ0KK3ZvaWQgZ2xSb3RhdGVmICggR0xmbG9hdCBhbmdsZSwgR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeiApDQordm9pZCBnbFJvdGF0ZXggKCBHTGZpeGVkIGFuZ2xlLCBHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6ICkNCit2b2lkIGdsU2FtcGxlQ292ZXJhZ2UgKCBHTGNsYW1wZiB2YWx1ZSwgR0xib29sZWFuIGludmVydCApDQordm9pZCBnbFNhbXBsZUNvdmVyYWdleCAoIEdMY2xhbXB4IHZhbHVlLCBHTGJvb2xlYW4gaW52ZXJ0ICkNCit2b2lkIGdsU2NhbGVmICggR0xmbG9hdCB4LCBHTGZsb2F0IHksIEdMZmxvYXQgeiApDQordm9pZCBnbFNjYWxleCAoIEdMZml4ZWQgeCwgR0xmaXhlZCB5LCBHTGZpeGVkIHogKQ0KK3ZvaWQgZ2xTY2lzc29yICggR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQgKQ0KK3ZvaWQgZ2xTaGFkZU1vZGVsICggR0xlbnVtIG1vZGUgKQ0KK3ZvaWQgZ2xTdGVuY2lsRnVuYyAoIEdMZW51bSBmdW5jLCBHTGludCByZWYsIEdMdWludCBtYXNrICkNCit2b2lkIGdsU3RlbmNpbE1hc2sgKCBHTHVpbnQgbWFzayApDQordm9pZCBnbFN0ZW5jaWxPcCAoIEdMZW51bSBmYWlsLCBHTGVudW0gemZhaWwsIEdMZW51bSB6cGFzcyApDQordm9pZCBnbFRleENvb3JkUG9pbnRlciAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyICkNCit2b2lkIGdsVGV4RW52ZiAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCBwYXJhbSApDQordm9pZCBnbFRleEVudmZ2ICggR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbXMgKQ0KK3ZvaWQgZ2xUZXhFbnZ4ICggR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtICkNCit2b2lkIGdsVGV4RW52eHYgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZml4ZWQgKnBhcmFtcyApDQordm9pZCBnbFRleEltYWdlMkQgKCBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xpbnQgaW50ZXJuYWxmb3JtYXQsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGludCBib3JkZXIsIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKnBpeGVscyApDQordm9pZCBnbFRleFBhcmFtZXRlcmYgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgcGFyYW0gKQ0KK3ZvaWQgZ2xUZXhQYXJhbWV0ZXJ4ICggR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtICkNCit2b2lkIGdsVGV4U3ViSW1hZ2UyRCAoIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLCBHTGludCB4b2Zmc2V0LCBHTGludCB5b2Zmc2V0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqcGl4ZWxzICkNCit2b2lkIGdsVHJhbnNsYXRlZiAoIEdMZmxvYXQgeCwgR0xmbG9hdCB5LCBHTGZsb2F0IHogKQ0KK3ZvaWQgZ2xUcmFuc2xhdGV4ICggR0xmaXhlZCB4LCBHTGZpeGVkIHksIEdMZml4ZWQgeiApDQordm9pZCBnbFZlcnRleFBvaW50ZXIgKCBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlciApDQordm9pZCBnbFZpZXdwb3J0ICggR0xpbnQgeCwgR0xpbnQgeSwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQgKQ0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4wZXh0IGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL2dsc3BlYy0xLjBleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QxOTc1OAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4wZXh0CkBAIC0wLDAgKzEgQEAKK0dMYml0ZmllbGQgZ2xRdWVyeU1hdHJpeHhPRVMgKCBHTGZpeGVkICptYW50aXNzYSwgR0xpbnQgKmV4cG9uZW50ICkNCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMSBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4xCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxNDlhN2YKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMQpAQCAtMCwwICsxLDQyIEBACit2b2lkIGdsQmluZEJ1ZmZlciAoIEdMZW51bSB0YXJnZXQsIEdMdWludCBidWZmZXIgKQ0KK3ZvaWQgZ2xCdWZmZXJEYXRhICggR0xlbnVtIHRhcmdldCwgR0xzaXplaXB0ciBzaXplLCBjb25zdCBHTHZvaWQgKmRhdGEsIEdMZW51bSB1c2FnZSApDQordm9pZCBnbEJ1ZmZlclN1YkRhdGEgKCBHTGVudW0gdGFyZ2V0LCBHTGludHB0ciBvZmZzZXQsIEdMc2l6ZWlwdHIgc2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhICkNCit2b2lkIGdsQ2xpcFBsYW5lZiAoIEdMZW51bSBwbGFuZSwgY29uc3QgR0xmbG9hdCAqZXF1YXRpb24gKQ0KK3ZvaWQgZ2xDbGlwUGxhbmV4ICggR0xlbnVtIHBsYW5lLCBjb25zdCBHTGZpeGVkICplcXVhdGlvbiApDQordm9pZCBnbENvbG9yNHViICggR0x1Ynl0ZSByZWQsIEdMdWJ5dGUgZ3JlZW4sIEdMdWJ5dGUgYmx1ZSwgR0x1Ynl0ZSBhbHBoYSApDQordm9pZCBnbENvbG9yUG9pbnRlciAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgR0xpbnQgb2Zmc2V0ICkNCit2b2lkIGdsRGVsZXRlQnVmZmVycyAoIEdMc2l6ZWkgbiwgY29uc3QgR0x1aW50ICpidWZmZXJzICkNCit2b2lkIGdsRHJhd0VsZW1lbnRzICggR0xlbnVtIG1vZGUsIEdMc2l6ZWkgY291bnQsIEdMZW51bSB0eXBlLCBHTGludCBvZmZzZXQgKQ0KK3ZvaWQgZ2xHZW5CdWZmZXJzICggR0xzaXplaSBuLCBHTHVpbnQgKmJ1ZmZlcnMgKQ0KK3ZvaWQgZ2xHZXRCb29sZWFudiAoIEdMZW51bSBwbmFtZSwgR0xib29sZWFuICpwYXJhbXMgKQ0KK3ZvaWQgZ2xHZXRCdWZmZXJQYXJhbWV0ZXJpdiAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcyApDQordm9pZCBnbEdldENsaXBQbGFuZWYgKCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKmVxbiApDQordm9pZCBnbEdldENsaXBQbGFuZXggKCBHTGVudW0gcG5hbWUsIEdMZml4ZWQgKmVxbiApDQordm9pZCBnbEdldEZpeGVkdiAoIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zICkNCit2b2lkIGdsR2V0RmxvYXR2ICggR0xlbnVtIHBuYW1lLCBHTGZsb2F0ICpwYXJhbXMgKQ0KK3ZvaWQgZ2xHZXRMaWdodGZ2ICggR0xlbnVtIGxpZ2h0LCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyApDQordm9pZCBnbEdldExpZ2h0eHYgKCBHTGVudW0gbGlnaHQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zICkNCit2b2lkIGdsR2V0TWF0ZXJpYWxmdiAoIEdMZW51bSBmYWNlLCBHTGVudW0gcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyApDQordm9pZCBnbEdldE1hdGVyaWFseHYgKCBHTGVudW0gZmFjZSwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMgKQ0KK3ZvaWQgZ2xHZXRUZXhFbnZpdiAoIEdMZW51bSBlbnYsIEdMZW51bSBwbmFtZSwgR0xpbnQgKnBhcmFtcyApDQordm9pZCBnbEdldFRleEVudnh2ICggR0xlbnVtIGVudiwgR0xlbnVtIHBuYW1lLCBHTGZpeGVkICpwYXJhbXMgKQ0KK3ZvaWQgZ2xHZXRUZXhQYXJhbWV0ZXJmdiAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zICkNCit2b2lkIGdsR2V0VGV4UGFyYW1ldGVyaXYgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50ICpwYXJhbXMgKQ0KK3ZvaWQgZ2xHZXRUZXhQYXJhbWV0ZXJ4diAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgR0xmaXhlZCAqcGFyYW1zICkNCitHTGJvb2xlYW4gZ2xJc0J1ZmZlciAoIEdMdWludCBidWZmZXIgKQ0KK0dMYm9vbGVhbiBnbElzRW5hYmxlZCAoIEdMZW51bSBjYXAgKQ0KK0dMYm9vbGVhbiBnbElzVGV4dHVyZSAoIEdMdWludCB0ZXh0dXJlICkNCit2b2lkIGdsTm9ybWFsUG9pbnRlciAoIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgR0xpbnQgb2Zmc2V0ICkNCit2b2lkIGdsUG9pbnRQYXJhbWV0ZXJmICggR0xlbnVtIHBuYW1lLCBHTGZsb2F0IHBhcmFtICkNCit2b2lkIGdsUG9pbnRQYXJhbWV0ZXJmdiAoIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmbG9hdCAqcGFyYW1zICkNCit2b2lkIGdsUG9pbnRQYXJhbWV0ZXJ4ICggR0xlbnVtIHBuYW1lLCBHTGZpeGVkIHBhcmFtICkNCit2b2lkIGdsUG9pbnRQYXJhbWV0ZXJ4diAoIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zICkNCit2b2lkIGdsUG9pbnRTaXplUG9pbnRlck9FUyAoIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyICkNCit2b2lkIGdsVGV4Q29vcmRQb2ludGVyICggR0xpbnQgc2l6ZSwgR0xlbnVtIHR5cGUsIEdMc2l6ZWkgc3RyaWRlLCBHTGludCBvZmZzZXQgKQ0KK3ZvaWQgZ2xUZXhFbnZpICggR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBHTGludCBwYXJhbSApDQordm9pZCBnbFRleEVudml2ICggR0xlbnVtIHRhcmdldCwgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGludCAqcGFyYW1zICkNCit2b2lkIGdsVGV4UGFyYW1ldGVyZnYgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyApDQordm9pZCBnbFRleFBhcmFtZXRlcmkgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIEdMaW50IHBhcmFtICkNCit2b2lkIGdsVGV4UGFyYW1ldGVyaXYgKCBHTGVudW0gdGFyZ2V0LCBHTGVudW0gcG5hbWUsIGNvbnN0IEdMaW50ICpwYXJhbXMgKQ0KK3ZvaWQgZ2xUZXhQYXJhbWV0ZXJ4diAoIEdMZW51bSB0YXJnZXQsIEdMZW51bSBwbmFtZSwgY29uc3QgR0xmaXhlZCAqcGFyYW1zICkNCit2b2lkIGdsVmVydGV4UG9pbnRlciAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgR0xpbnQgb2Zmc2V0ICkNCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMWV4dCBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4xZXh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjMDhjNzMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMWV4dApAQCAtMCwwICsxLDE2IEBACit2b2lkIGdsQ3VycmVudFBhbGV0dGVNYXRyaXhPRVMgKCBHTHVpbnQgbWF0cml4cGFsZXR0ZWluZGV4ICkNCit2b2lkIGdsRHJhd1RleGZPRVMgKCBHTGZsb2F0IHgsIEdMZmxvYXQgeSwgR0xmbG9hdCB6LCBHTGZsb2F0IHdpZHRoLCBHTGZsb2F0IGhlaWdodCApDQordm9pZCBnbERyYXdUZXhmdk9FUyAoIGNvbnN0IEdMZmxvYXQgKmNvb3JkcyApDQordm9pZCBnbERyYXdUZXhpT0VTICggR0xpbnQgeCwgR0xpbnQgeSwgR0xpbnQgeiwgR0xpbnQgd2lkdGgsIEdMaW50IGhlaWdodCApDQordm9pZCBnbERyYXdUZXhpdk9FUyAoIGNvbnN0IEdMaW50ICpjb29yZHMgKQ0KK3ZvaWQgZ2xEcmF3VGV4c09FUyAoIEdMc2hvcnQgeCwgR0xzaG9ydCB5LCBHTHNob3J0IHosIEdMc2hvcnQgd2lkdGgsIEdMc2hvcnQgaGVpZ2h0ICkNCit2b2lkIGdsRHJhd1RleHN2T0VTICggY29uc3QgR0xzaG9ydCAqY29vcmRzICkNCit2b2lkIGdsRHJhd1RleHhPRVMgKCBHTGZpeGVkIHgsIEdMZml4ZWQgeSwgR0xmaXhlZCB6LCBHTGZpeGVkIHdpZHRoLCBHTGZpeGVkIGhlaWdodCApDQordm9pZCBnbERyYXdUZXh4dk9FUyAoIGNvbnN0IEdMZml4ZWQgKmNvb3JkcyApDQordm9pZCBnbEVuYWJsZSAoIEdMZW51bSBjYXAgKQ0KK3ZvaWQgZ2xFbmFibGVDbGllbnRTdGF0ZSAoIEdMZW51bSBhcnJheSApDQordm9pZCBnbExvYWRQYWxldHRlRnJvbU1vZGVsVmlld01hdHJpeE9FUyAoIHZvaWQgKQ0KK3ZvaWQgZ2xNYXRyaXhJbmRleFBvaW50ZXJPRVMgKCBHTGludCBzaXplLCBHTGVudW0gdHlwZSwgR0xzaXplaSBzdHJpZGUsIGNvbnN0IEdMdm9pZCAqcG9pbnRlciApDQordm9pZCBnbE1hdHJpeEluZGV4UG9pbnRlck9FUyAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgR0xpbnQgb2Zmc2V0ICkNCit2b2lkIGdsV2VpZ2h0UG9pbnRlck9FUyAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgY29uc3QgR0x2b2lkICpwb2ludGVyICkNCit2b2lkIGdsV2VpZ2h0UG9pbnRlck9FUyAoIEdMaW50IHNpemUsIEdMZW51bSB0eXBlLCBHTHNpemVpIHN0cmlkZSwgR0xpbnQgb2Zmc2V0ICkNCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMWV4dHBhY2sgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vZ2xzcGVjLTEuMWV4dHBhY2sKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E5ZTZkMgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtMS4xZXh0cGFjawpAQCAtMCwwICsxLDM4IEBACit2b2lkIGdsQmluZEZyYW1lYnVmZmVyT0VTICggR0xpbnQgdGFyZ2V0LCBHTGludCBmcmFtZWJ1ZmZlciApCit2b2lkIGdsQmluZFJlbmRlcmJ1ZmZlck9FUyAoIEdMaW50IHRhcmdldCwgR0xpbnQgcmVuZGVyYnVmZmVyICkKK3ZvaWQgZ2xCaW5kVGV4dHVyZSAoIEdMaW50IHRhcmdldCwgR0xpbnQgdGV4dHVyZSApCit2b2lkIGdsQmxlbmRFcXVhdGlvbiAoIEdMaW50IG1vZGUgKQordm9pZCBnbEJsZW5kRXF1YXRpb25TZXBhcmF0ZSAoIEdMaW50IG1vZGVSR0IsIEdMaW50IG1vZGVBbHBoYSApCit2b2lkIGdsQmxlbmRGdW5jU2VwYXJhdGUgKCBHTGludCBzcmNSR0IsIEdMaW50IGRzdFJHQiwgR0xpbnQgc3JjQWxwaGEsIEdMaW50IGRzdEFscGhhICkKK0dMaW50IGdsQ2hlY2tGcmFtZWJ1ZmZlclN0YXR1c09FUyAoIEdMaW50IHRhcmdldCApCit2b2lkIGdsQ29tcHJlc3NlZFRleEltYWdlMkQgKCBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwgR0xlbnVtIGludGVybmFsZm9ybWF0LCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xpbnQgYm9yZGVyLCBHTHNpemVpIGltYWdlU2l6ZSwgY29uc3QgR0x2b2lkICpkYXRhICkKK3ZvaWQgZ2xDb3B5VGV4SW1hZ2UyRCAoIEdMaW50IHRhcmdldCwgR0xpbnQgbGV2ZWwsIEdMaW50IGludGVybmFsZm9ybWF0LCBHTGludCB4LCBHTGludCB5LCBHTGludCB3aWR0aCwgR0xpbnQgaGVpZ2h0LCBHTGludCBib3JkZXIgKQordm9pZCBnbERlbGV0ZUZyYW1lYnVmZmVyc09FUyAoIEdMaW50IG4sIEdMaW50ICpmcmFtZWJ1ZmZlcnMgKQordm9pZCBnbERlbGV0ZVJlbmRlcmJ1ZmZlcnNPRVMgKCBHTGludCBuLCBHTGludCAqcmVuZGVyYnVmZmVycyApCit2b2lkIGdsRW5hYmxlICggR0xpbnQgY2FwICkKK3ZvaWQgZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlck9FUyAoIEdMaW50IHRhcmdldCwgR0xpbnQgYXR0YWNobWVudCwgR0xpbnQgcmVuZGVyYnVmZmVydGFyZ2V0LCBHTGludCByZW5kZXJidWZmZXIgKQordm9pZCBnbEZyYW1lYnVmZmVyVGV4dHVyZTJET0VTICggR0xpbnQgdGFyZ2V0LCBHTGludCBhdHRhY2htZW50LCBHTGludCB0ZXh0YXJnZXQsIEdMaW50IHRleHR1cmUsIEdMaW50IGxldmVsICkKK3ZvaWQgZ2xHZW5lcmF0ZU1pcG1hcE9FUyAoIEdMaW50IHRhcmdldCApCit2b2lkIGdsR2VuRnJhbWVidWZmZXJzT0VTICggR0xpbnQgbiwgR0xpbnQgKmZyYW1lYnVmZmVycyApCit2b2lkIGdsR2VuUmVuZGVyYnVmZmVyc09FUyAoIEdMaW50IG4sIEdMaW50ICpyZW5kZXJidWZmZXJzICkKK3ZvaWQgZ2xHZXRGcmFtZWJ1ZmZlckF0dGFjaG1lbnRQYXJhbWV0ZXJpdk9FUyAoIEdMaW50IHRhcmdldCwgR0xpbnQgYXR0YWNobWVudCwgR0xpbnQgcG5hbWUsIEdMaW50ICpwYXJhbXMgKQordm9pZCBnbEdldEludGVnZXJ2ICggR0xpbnQgcG5hbWUsIEdMaW50ICpwYXJhbXMgKQordm9pZCBnbEdldFJlbmRlcmJ1ZmZlclBhcmFtZXRlcml2T0VTICggR0xpbnQgdGFyZ2V0LCBHTGludCBwbmFtZSwgR0xpbnQgKnBhcmFtcyApCit2b2lkIGdsR2V0VGV4R2VuZnYgKCBHTGludCBjb29yZCwgR0xpbnQgcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyApCit2b2lkIGdsR2V0VGV4R2VuaXYgKCBHTGludCBjb29yZCwgR0xpbnQgcG5hbWUsIEdMaW50ICpwYXJhbXMgKQordm9pZCBnbEdldFRleEdlbnh2ICggR0xpbnQgY29vcmQsIEdMaW50IHBuYW1lLCBHTGludCAqcGFyYW1zICkKK0dMYm9vbGVhbiBnbElzRnJhbWVidWZmZXJPRVMgKCBHTGludCBmcmFtZWJ1ZmZlciApCitHTGJvb2xlYW4gZ2xJc1JlbmRlcmJ1ZmZlck9FUyAoIEdMaW50IHJlbmRlcmJ1ZmZlciApCit2b2lkIGdsUmVuZGVyYnVmZmVyU3RvcmFnZU9FUyAoIEdMaW50IHRhcmdldCwgR0xpbnQgaW50ZXJuYWxmb3JtYXQsIEdMaW50IHdpZHRoLCBHTGludCBoZWlnaHQgKQordm9pZCBnbFN0ZW5jaWxPcCAoIEdMaW50IGZhaWwsIEdMaW50IHpmYWlsLCBHTGludCB6cGFzcyApCit2b2lkIGdsVGV4RW52ZiAoIEdMaW50IHRhcmdldCwgR0xpbnQgcG5hbWUsIEdMZmxvYXQgcGFyYW0gKQordm9pZCBnbFRleEVudmZ2ICggR0xpbnQgdGFyZ2V0LCBHTGludCBwbmFtZSwgR0xmbG9hdCAqcGFyYW1zICkKK3ZvaWQgZ2xUZXhFbnZ4ICggR0xpbnQgdGFyZ2V0LCBHTGludCBwbmFtZSwgR0xpbnQgcGFyYW0gKQordm9pZCBnbFRleEVudnh2ICggR0xpbnQgdGFyZ2V0LCBHTGludCBwbmFtZSwgR0xpbnQgKnBhcmFtcyApCit2b2lkIGdsVGV4R2VuZiAoIEdMaW50IGNvb3JkLCBHTGludCBwbmFtZSwgR0xmbG9hdCBwYXJhbSApCit2b2lkIGdsVGV4R2VuZnYgKCBHTGludCBjb29yZCwgR0xpbnQgcG5hbWUsIEdMZmxvYXQgKnBhcmFtcyApCit2b2lkIGdsVGV4R2VuaSAoIEdMaW50IGNvb3JkLCBHTGludCBwbmFtZSwgR0xpbnQgcGFyYW0gKQordm9pZCBnbFRleEdlbml2ICggR0xpbnQgY29vcmQsIEdMaW50IHBuYW1lLCBHTGludCAqcGFyYW1zICkKK3ZvaWQgZ2xUZXhHZW54ICggR0xpbnQgY29vcmQsIEdMaW50IHBuYW1lLCBHTGludCBwYXJhbSApCit2b2lkIGdsVGV4R2VueHYgKCBHTGludCBjb29yZCwgR0xpbnQgcG5hbWUsIEdMaW50ICpwYXJhbXMgKQordm9pZCBnbFRleFBhcmFtZXRlcmYgKCBHTGludCB0YXJnZXQsIEdMaW50IHBuYW1lLCBHTGZsb2F0IHBhcmFtICkKZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtY2hlY2tzIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL2dsc3BlYy1jaGVja3MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTg0ZWQ2NQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9nbHNwZWMtY2hlY2tzCkBAIC0wLDAgKzEsNTkgQEAKK2dsQ2xpcFBsYW5lZiBjaGVjayBlcXVhdGlvbiA0DQorZ2xDbGlwUGxhbmV4IGNoZWNrIGVxdWF0aW9uIDQNCitnbERlbGV0ZUJ1ZmZlcnMgY2hlY2sgYnVmZmVycyBuIA0KK2dsRGVsZXRlVGV4dHVyZXMgY2hlY2sgdGV4dHVyZXMgbg0KK2dsRHJhd0VsZW1lbnRzIGNoZWNrX0FJT09CRSBpbmRpY2VzIGNvdW50DQorZ2xGb2cgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9GT0dfTU9ERSxHTF9GT0dfREVOU0lUWSxHTF9GT0dfU1RBUlQsR0xfRk9HX0VORCBpZmNoZWNrIHBhcmFtcyA0IHBuYW1lIEdMX0ZPR19DT0xPUg0KK2dsR2VuQnVmZmVycyBjaGVjayBidWZmZXJzIG4NCitnbEdlblRleHR1cmVzIGNoZWNrIHRleHR1cmVzIG4NCitnbEdldENsaXBQbGFuZSBjaGVjayBlcW4gNA0KK2dsR2V0SW50ZWdlcnYgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9BTFBIQV9CSVRTLEdMX0FMUEhBX1RFU1RfRlVOQyxHTF9BTFBIQV9URVNUX1JFRixHTF9CTEVORF9EU1QsR0xfQkxVRV9CSVRTLEdMX0NPTE9SX0FSUkFZX0JVRkZFUl9CSU5ESU5HLEdMX0NPTE9SX0FSUkFZX1NJWkUsR0xfQ09MT1JfQVJSQVlfU1RSSURFLEdMX0NPTE9SX0FSUkFZX1RZUEUsR0xfQ1VMTF9GQUNFLEdMX0RFUFRIX0JJVFMsR0xfREVQVEhfQ0xFQVJfVkFMVUUsR0xfREVQVEhfRlVOQyxHTF9ERVBUSF9XUklURU1BU0ssR0xfRk9HX0RFTlNJVFksR0xfRk9HX0VORCxHTF9GT0dfTU9ERSxHTF9GT0dfU1RBUlQsR0xfRlJPTlRfRkFDRSxHTF9HUkVFTl9CSVRTLEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfRk9STUFUX09FUyxHTF9JTVBMRU1FTlRBVElPTl9DT0xPUl9SRUFEX1RZUEVfT0VTLEdMX0xJR0hUX01PREVMX1RXT19TSURFLEdMX0xJTkVfU01PT1RIX0hJTlQsR0xfTElORV9XSURUSCxHTF9MT0dJQ19PUF9NT0RFLEdMX01BVFJJWF9JTkRFWF9BUlJBWV9CVUZGRVJfQklORElOR19PRVMsR0xfTUFUUklYX0lOREVYX0FSUkFZX1NJWkVfT0VTLEdMX01BVFJJWF9JTkRFWF9BUlJBWV9TVFJJREVfT0VTLEdMX01BVFJJWF9JTkRFWF9BUlJBWV9UWVBFX09FUyxHTF9NQVRSSVhfTU9ERSxHTF9NQVhfQ0xJUF9QTEFORVMsR0xfTUFYX0VMRU1FTlRTX0lORElDRVMsR0xfTUFYX0VMRU1FTlRTX1ZFUlRJQ0VTLEdMX01BWF9MSUdIVFMsR0xfTUFYX01PREVMVklFV19TVEFDS19ERVBUSCxHTF9NQVhfUEFMRVRURV9NQVRSSUNFU19PRVMsR0xfTUFYX1BST0pFQ1RJT05fU1RBQ0tfREVQVEgsR0xfTUFYX1RFWFRVUkVfU0laRSxHTF9NQVhfVEVYVFVSRV9TVEFDS19ERVBUSCxHTF9NQVhfVEVYVFVSRV9VTklUUyxHTF9NQVhfVkVSVEVYX1VOSVRTX09FUyxHTF9NT0RFTFZJRVdfU1RBQ0tfREVQVEgsR0xfTk9STUFMX0FSUkFZX0JVRkZFUl9CSU5ESU5HLEdMX05PUk1BTF9BUlJBWV9TVFJJREUsR0xfTk9STUFMX0FSUkFZX1RZUEUsR0xfTlVNX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTLEdMX1BBQ0tfQUxJR05NRU5ULEdMX1BFUlNQRUNUSVZFX0NPUlJFQ1RJT05fSElOVCxHTF9QT0lOVF9TSVpFLEdMX1BPSU5UX1NJWkVfQVJSQVlfQlVGRkVSX0JJTkRJTkdfT0VTLEdMX1BPSU5UX1NJWkVfQVJSQVlfU1RSSURFX09FUyxHTF9QT0lOVF9TSVpFX0FSUkFZX1RZUEVfT0VTLEdMX1BPSU5UX1NNT09USF9ISU5ULEdMX1BPTFlHT05fT0ZGU0VUX0ZBQ1RPUixHTF9QT0xZR09OX09GRlNFVF9VTklUUyxHTF9QUk9KRUNUSU9OX1NUQUNLX0RFUFRILEdMX1JFRF9CSVRTLEdMX1NIQURFX01PREVMLEdMX1NURU5DSUxfQklUUyxHTF9TVEVOQ0lMX0NMRUFSX1ZBTFVFLEdMX1NURU5DSUxfRkFJTCxHTF9TVEVOQ0lMX0ZVTkMsR0xfU1RFTkNJTF9QQVNTX0RFUFRIX0ZBSUwsR0xfU1RFTkNJTF9QQVNTX0RFUFRIX1BBU1MsR0xfU1RFTkNJTF9SRUYsR0xfU1RFTkNJTF9WQUxVRV9NQVNLLEdMX1NURU5DSUxfV1JJVEVNQVNLLEdMX1NVQlBJWEVMX0JJVFMsR0xfVEVYVFVSRV9CSU5ESU5HXzJELEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfQlVGRkVSX0JJTkRJTkcsR0xfVEVYVFVSRV9DT09SRF9BUlJBWV9TSVpFLEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfU1RSSURFLEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfVFlQRSxHTF9URVhUVVJFX1NUQUNLX0RFUFRILEdMX1VOUEFDS19BTElHTk1FTlQsR0xfVkVSVEVYX0FSUkFZX0JVRkZFUl9CSU5ESU5HLEdMX1ZFUlRFWF9BUlJBWV9TSVpFLEdMX1ZFUlRFWF9BUlJBWV9TVFJJREUsR0xfVkVSVEVYX0FSUkFZX1RZUEUsR0xfV0VJR0hUX0FSUkFZX0JVRkZFUl9CSU5ESU5HX09FUyxHTF9XRUlHSFRfQVJSQVlfU0laRV9PRVMsR0xfV0VJR0hUX0FSUkFZX1NUUklERV9PRVMsR0xfV0VJR0hUX0FSUkFZX1RZUEVfT0VTIGlmY2hlY2sgcGFyYW1zIDIgcG5hbWUgR0xfQUxJQVNFRF9QT0lOVF9TSVpFX1JBTkdFLEdMX0FMSUFTRURfTElORV9XSURUSF9SQU5HRSxHTF9ERVBUSF9SQU5HRSxHTF9NQVhfVklFV1BPUlRfRElNUyxHTF9TTU9PVEhfTElORV9XSURUSF9SQU5HRSxHTF9TTU9PVEhfUE9JTlRfU0laRV9SQU5HRSBpZmNoZWNrIHBhcmFtcyA0IHBuYW1lIEdMX0NPTE9SX0NMRUFSX1ZBTFVFLEdMX0NPTE9SX1dSSVRFTUFTSyxHTF9TQ0lTU09SX0JPWCxHTF9WSUVXUE9SVCBpZmNoZWNrIHBhcmFtcyAxNiBwbmFtZSBHTF9NT0RFTFZJRVdfTUFUUklYLEdMX01PREVMVklFV19NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTLEdMX1BST0pFQ1RJT05fTUFUUklYLEdMX1BST0pFQ1RJT05fTUFUUklYX0ZMT0FUX0FTX0lOVF9CSVRTX09FUyxHTF9URVhUVVJFX01BVFJJWCxHTF9URVhUVVJFX01BVFJJWF9GTE9BVF9BU19JTlRfQklUU19PRVMgaWZjaGVjayBwYXJhbXMgX05VTV9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUyBwbmFtZSBHTF9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUyxHTF9GT0dfQ09MT1IsR0xfTElHSFRfTU9ERUxfQU1CSUVOVA0KK2dsR2V0TGlnaHQgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9TUE9UX0VYUE9ORU5ULEdMX1NQT1RfQ1VUT0ZGLEdMX0NPTlNUQU5UX0FUVEVOVUFUSU9OLEdMX0xJTkVBUl9BVFRFTlVBVElPTixHTF9RVUFEUkFUSUNfQVRURU5VQVRJT04gaWZjaGVjayBwYXJhbXMgMyBwbmFtZSBHTF9TUE9UX0RJUkVDVElPTiBpZmNoZWNrIHBhcmFtcyA0IHBuYW1lIEdMX0FNQklFTlQsR0xfRElGRlVTRSxHTF9TUEVDVUxBUixHTF9FTUlTU0lPTg0KK2dsR2V0TWF0ZXJpYWwgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9TSElOSU5FU1MgaWZjaGVjayBwYXJhbXMgNCBwbmFtZSBHTF9BTUJJRU5ULEdMX0RJRkZVU0UsR0xfU1BFQ1VMQVIsR0xfRU1JU1NJT04sR0xfQU1CSUVOVF9BTkRfRElGRlVTRQ0KK2dsR2V0VGV4RW52IGlmY2hlY2sgcGFyYW1zIDEgcG5hbWUgR0xfVEVYVFVSRV9FTlZfTU9ERSxHTF9DT01CSU5FX1JHQixHTF9DT01CSU5FX0FMUEhBIGlmY2hlY2sgcGFyYW1zIDQgcG5hbWUgR0xfVEVYVFVSRV9FTlZfQ09MT1INCitnbEdldFRleFBhcmFtZXRlciBjaGVjayBwYXJhbXMgMQ0KK2dsTGlnaHRNb2RlbCBpZmNoZWNrIHBhcmFtcyAxIHBuYW1lIEdMX0xJR0hUX01PREVMX1RXT19TSURFIGlmY2hlY2sgcGFyYW1zIDQgcG5hbWUgR0xfTElHSFRfTU9ERUxfQU1CSUVOVA0KK2dsTGlnaHQgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9TUE9UX0VYUE9ORU5ULEdMX1NQT1RfQ1VUT0ZGLEdMX0NPTlNUQU5UX0FUVEVOVUFUSU9OLEdMX0xJTkVBUl9BVFRFTlVBVElPTixHTF9RVUFEUkFUSUNfQVRURU5VQVRJT04gaWZjaGVjayBwYXJhbXMgMyBwbmFtZSBHTF9TUE9UX0RJUkVDVElPTiBpZmNoZWNrIHBhcmFtcyA0IHBuYW1lIEdMX0FNQklFTlQsR0xfRElGRlVTRSxHTF9TUEVDVUxBUixHTF9FTUlTU0lPTg0KK2dsTG9hZE1hdHJpeCBjaGVjayBtIDE2DQorZ2xNYXRlcmlhbCBpZmNoZWNrIHBhcmFtcyAxIHBuYW1lIEdMX1NISU5JTkVTUyBpZmNoZWNrIHBhcmFtcyA0IHBuYW1lIEdMX0FNQklFTlQsR0xfRElGRlVTRSxHTF9TUEVDVUxBUixHTF9FTUlTU0lPTixHTF9BTUJJRU5UX0FORF9ESUZGVVNFDQorZ2xNdWx0TWF0cml4IGNoZWNrIG0gMTYNCitnbFBvaW50UGFyYW1ldGVyIGNoZWNrIHBhcmFtcyAxDQorZ2xUZXhFbnYgaWZjaGVjayBwYXJhbXMgMSBwbmFtZSBHTF9URVhUVVJFX0VOVl9NT0RFLEdMX0NPTUJJTkVfUkdCLEdMX0NPTUJJTkVfQUxQSEEgaWZjaGVjayBwYXJhbXMgNCBwbmFtZSBHTF9URVhUVVJFX0VOVl9DT0xPUg0KK2dsVGV4SW1hZ2UyRCBudWxsQWxsb3dlZA0KK2dsVGV4U3ViSW1hZ2UyRCBudWxsQWxsb3dlZA0KK2dsQnVmZmVyRGF0YSBudWxsQWxsb3dlZA0KK2dsVGV4UGFyYW1ldGVyIGNoZWNrIHBhcmFtcyAxDQorZ2xRdWVyeU1hdHJpeHhPRVMgY2hlY2sgbWFudGlzc2EgMTYgY2hlY2sgZXhwb25lbnQgMTYgcmV0dXJuIC0xDQorZ2xEcmF3VGV4ZnZPRVMgY2hlY2sgY29vcmRzIDUNCitnbERyYXdUZXhpdk9FUyBjaGVjayBjb29yZHMgNQ0KK2dsRHJhd1RleHN2T0VTIGNoZWNrIGNvb3JkcyA1DQorZ2xEcmF3VGV4eHZPRVMgY2hlY2sgY29vcmRzIDUNCitnbEJpbmRGcmFtZWJ1ZmZlck9FUyB1bnN1cHBvcnRlZA0KK2dsQmluZFJlbmRlcmJ1ZmZlck9FUyB1bnN1cHBvcnRlZA0KK2dsQmxlbmRFcXVhdGlvbiB1bnN1cHBvcnRlZA0KK2dsQmxlbmRFcXVhdGlvblNlcGFyYXRlIHVuc3VwcG9ydGVkDQorZ2xCbGVuZEZ1bmNTZXBhcmF0ZSB1bnN1cHBvcnRlZA0KK2dsQ2hlY2tGcmFtZWJ1ZmZlclN0YXR1c09FUyB1bnN1cHBvcnRlZCByZXR1cm4gMA0KK2dsQ3VycmVudFBhbGV0dGVNYXRyaXhPRVMgdW5zdXBwb3J0ZWQNCitnbERlbGV0ZUZyYW1lYnVmZmVyc09FUyB1bnN1cHBvcnRlZA0KK2dsRGVsZXRlUmVuZGVyYnVmZmVyc09FUyB1bnN1cHBvcnRlZA0KK2dsRnJhbWVidWZmZXJSZW5kZXJidWZmZXJPRVMgdW5zdXBwb3J0ZWQNCitnbEZyYW1lYnVmZmVyU3RvcmFnZU9FUyB1bnN1cHBvcnRlZA0KK2dsRnJhbWVidWZmZXJUZXh0dXJlMkRPRVMgdW5zdXBwb3J0ZWQNCitnbEdlbkZyYW1lYnVmZmVyc09FUyB1bnN1cHBvcnRlZA0KK2dsR2VuUmVuZGVyYnVmZmVyc09FUyB1bnN1cHBvcnRlZA0KK2dsR2VuZXJhdGVNaXBtYXBPRVMgdW5zdXBwb3J0ZWQNCitnbEdldEJ1ZmZlclBhcmFtZXRlciB1bnN1cHBvcnRlZA0KK2dsR2V0RnJhbWVidWZmZXJBdHRhY2htZW50UGFyYW1ldGVyaXZPRVMgdW5zdXBwb3J0ZWQNCitnbEdldFJlbmRlcmJ1ZmZlclBhcmFtZXRlcml2T0VTIHVuc3VwcG9ydGVkDQorZ2xHZXRUZXhHZW4gdW5zdXBwb3J0ZWQNCitnbElzRnJhbWVidWZmZXJPRVMgdW5zdXBwb3J0ZWQgcmV0dXJuIEpOSV9GQUxTRQ0KK2dsSXNSZW5kZXJidWZmZXJPRVMgdW5zdXBwb3J0ZWQgcmV0dXJuIEpOSV9GQUxTRQ0KK2dsTG9hZFBhbGV0dGVGcm9tTW9kZWxWaWV3TWF0cml4T0VTIHVuc3VwcG9ydGVkDQorZ2xNYXRyaXhJbmRleFBvaW50ZXJPRVMgdW5zdXBwb3J0ZWQNCitnbFJlbmRlcmJ1ZmZlclN0b3JhZ2VPRVMgdW5zdXBwb3J0ZWQgcmV0dXJuIGZhbHNlDQorZ2xUZXhHZW4gdW5zdXBwb3J0ZWQNCitnbFRleEdlbmYgdW5zdXBwb3J0ZWQNCitnbFRleEdlbmkgdW5zdXBwb3J0ZWQNCitnbFRleEdlbnggdW5zdXBwb3J0ZWQNCitnbFdlaWdodFBvaW50ZXJPRVMgdW5zdXBwb3J0ZWQNCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0NGdW5jLmphdmEgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0NGdW5jLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc5NGY0MQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvQ0Z1bmMuamF2YQpAQCAtMCwwICsxLDE1NSBAQAorDQoraW1wb3J0IGphdmEudXRpbC4qOw0KKw0KK3B1YmxpYyBjbGFzcyBDRnVuYyB7DQorDQorICAgIFN0cmluZyBvcmlnaW5hbDsNCisNCisgICAgQ1R5cGUgZnR5cGU7DQorICAgIFN0cmluZyBmbmFtZTsNCisNCisgICAgTGlzdDxTdHJpbmc+IGFyZ05hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7DQorICAgIExpc3Q8Q1R5cGU+IGFyZ1R5cGVzID0gbmV3IEFycmF5TGlzdDxDVHlwZT4oKTsNCisNCisgICAgYm9vbGVhbiBoYXNQb2ludGVyQXJnID0gZmFsc2U7DQorICAgIGJvb2xlYW4gaGFzVHlwZWRQb2ludGVyQXJnID0gZmFsc2U7DQorDQorICAgIHB1YmxpYyBDRnVuYyhTdHJpbmcgb3JpZ2luYWwpIHsNCisgICAgICAgIHRoaXMub3JpZ2luYWwgPSBvcmlnaW5hbDsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldE9yaWdpbmFsKCkgew0KKyAgICAgICAgcmV0dXJuIG9yaWdpbmFsOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIGZuYW1lKSB7DQorICAgICAgICB0aGlzLmZuYW1lID0gZm5hbWU7DQorICAgIH0NCisNCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgew0KKyAgICAgICAgcmV0dXJuIGZuYW1lOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoQ1R5cGUgZnR5cGUpIHsNCisgICAgICAgIHRoaXMuZnR5cGUgPSBmdHlwZTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgQ1R5cGUgZ2V0VHlwZSgpIHsNCisgICAgICAgIHJldHVybiBmdHlwZTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgdm9pZCBhZGRBcmd1bWVudChTdHJpbmcgYXJnTmFtZSwgQ1R5cGUgYXJnVHlwZSkgew0KKyAgICAgICAgYXJnTmFtZXMuYWRkKGFyZ05hbWUpOw0KKyAgICAgICAgYXJnVHlwZXMuYWRkKGFyZ1R5cGUpOw0KKw0KKyAgICAgICAgaWYgKGFyZ1R5cGUuaXNQb2ludGVyKCkpIHsNCisgICAgICAgICAgICBoYXNQb2ludGVyQXJnID0gdHJ1ZTsNCisgICAgICAgIH0NCisgICAgICAgIGlmIChhcmdUeXBlLmlzVHlwZWRQb2ludGVyKCkpIHsNCisgICAgICAgICAgICBoYXNUeXBlZFBvaW50ZXJBcmcgPSB0cnVlOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHB1YmxpYyBpbnQgZ2V0TnVtQXJncygpIHsNCisgICAgICAgIHJldHVybiBhcmdOYW1lcy5zaXplKCk7DQorICAgIH0NCisNCisgICAgcHVibGljIGludCBnZXRBcmdJbmRleChTdHJpbmcgbmFtZSkgew0KKyAgICAgICAgaW50IGxlbiA9IGFyZ05hbWVzLnNpemUoKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsNCisgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoYXJnTmFtZXMuZ2V0KGkpKSkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gaTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gLTE7DQorICAgIH0NCisNCisgICAgcHVibGljIFN0cmluZyBnZXRBcmdOYW1lKGludCBpbmRleCkgew0KKyAgICAgICAgcmV0dXJuIGFyZ05hbWVzLmdldChpbmRleCk7DQorICAgIH0NCisNCisgICAgcHVibGljIENUeXBlIGdldEFyZ1R5cGUoaW50IGluZGV4KSB7DQorICAgICAgICByZXR1cm4gYXJnVHlwZXMuZ2V0KGluZGV4KTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNQb2ludGVyQXJnKCkgew0KKyAgICAgICAgcmV0dXJuIGhhc1BvaW50ZXJBcmc7DQorICAgIH0NCisNCisgICAgcHVibGljIGJvb2xlYW4gaGFzVHlwZWRQb2ludGVyQXJnKCkgew0KKyAgICAgICAgcmV0dXJuIGhhc1R5cGVkUG9pbnRlckFyZzsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KKyAgICAgICAgU3RyaW5nIHMgPSAgIkZ1bmN0aW9uICIgKyBmbmFtZSArICIgcmV0dXJucyAiICsgZnR5cGUgKyAiOiAiOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdOYW1lcy5zaXplKCk7IGkrKykgew0KKyAgICAgICAgICAgIGlmIChpID4gMCkgew0KKyAgICAgICAgICAgICAgICBzICs9ICIsICI7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIHMgKz0gYXJnVHlwZXMuZ2V0KGkpICsgIiAiICsgYXJnTmFtZXMuZ2V0KGkpOw0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIHM7DQorICAgIH0NCisNCisgICAgcHVibGljIHN0YXRpYyBDRnVuYyBwYXJzZUNGdW5jKFN0cmluZyBzKSB7DQorICAgICAgICBDRnVuYyBjZnVuYyA9IG5ldyBDRnVuYyhzKTsNCisgICAgICAgIFN0cmluZ1tdIHRva2VucyA9IHMuc3BsaXQoIlxccyIpOw0KKw0KKyAgICAgICAgaW50IGkgPSAwOw0KKyAgICAgICAgQ1R5cGUgZnR5cGUgPSBuZXcgQ1R5cGUoKTsNCisgICAgICAgIFN0cmluZyBmdHlwZU5hbWUgPSB0b2tlbnNbaSsrXTsNCisgICAgICAgIGlmIChmdHlwZU5hbWUuZXF1YWxzKCJjb25zdCIpKSB7DQorICAgICAgICAgICAgZnR5cGUuc2V0SXNDb25zdCh0cnVlKTsNCisgICAgICAgICAgICBmdHlwZU5hbWUgPSB0b2tlbnNbaSsrXTsNCisgICAgICAgIH0NCisgICAgICAgIGZ0eXBlLnNldEJhc2VUeXBlKGZ0eXBlTmFtZSk7DQorDQorICAgICAgICBTdHJpbmcgZm5hbWUgPSB0b2tlbnNbaSsrXTsNCisgICAgICAgIGlmIChmbmFtZS5lcXVhbHMoIioiKSkgew0KKyAgICAgICAgICAgIGZ0eXBlLnNldElzUG9pbnRlcih0cnVlKTsNCisgICAgICAgICAgICBmbmFtZSA9IHRva2Vuc1tpKytdOw0KKyAgICAgICAgfQ0KKwkNCisgICAgICAgIGNmdW5jLnNldE5hbWUoZm5hbWUpOw0KKyAgICAgICAgY2Z1bmMuc2V0VHlwZShmdHlwZSk7DQorCQ0KKyAgICAgICAgd2hpbGUgKGkgPCB0b2tlbnMubGVuZ3RoKSB7DQorICAgICAgICAgICAgU3RyaW5nIHRvayA9IHRva2Vuc1tpKytdOw0KKwkgICAgDQorICAgICAgICAgICAgaWYgKHRvay5lcXVhbHMoIigiKSkgew0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgaWYgKHRvay5lcXVhbHMoIikiKSkgew0KKyAgICAgICAgICAgICAgICBicmVhazsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgQ1R5cGUgYXJnVHlwZSA9IG5ldyBDVHlwZSgpOw0KKwkgICAgDQorICAgICAgICAgICAgU3RyaW5nIGFyZ1R5cGVOYW1lID0gdG9rOw0KKyAgICAgICAgICAgIFN0cmluZyBhcmdOYW1lID0gIiI7DQorCSAgICANCisgICAgICAgICAgICBpZiAoYXJnVHlwZU5hbWUuZXF1YWxzKCJjb25zdCIpKSB7DQorICAgICAgICAgICAgICAgIGFyZ1R5cGUuc2V0SXNDb25zdCh0cnVlKTsNCisgICAgICAgICAgICAgICAgYXJnVHlwZU5hbWUgPSB0b2tlbnNbaSsrXTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgYXJnVHlwZS5zZXRCYXNlVHlwZShhcmdUeXBlTmFtZSk7DQorDQorICAgICAgICAgICAgaWYgKGFyZ1R5cGVOYW1lLmVxdWFscygidm9pZCIpKSB7DQorICAgICAgICAgICAgICAgIGJyZWFrOw0KKyAgICAgICAgICAgIH0NCisJICAgIA0KKyAgICAgICAgICAgIGFyZ05hbWUgPSB0b2tlbnNbaSsrXTsNCisgICAgICAgICAgICBpZiAoYXJnTmFtZS5zdGFydHNXaXRoKCIqIikpIHsNCisgICAgICAgICAgICAgICAgYXJnVHlwZS5zZXRJc1BvaW50ZXIodHJ1ZSk7DQorICAgICAgICAgICAgICAgIGFyZ05hbWUgPSBhcmdOYW1lLnN1YnN0cmluZygxLCBhcmdOYW1lLmxlbmd0aCgpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgaWYgKGFyZ05hbWUuZW5kc1dpdGgoIiwiKSkgew0KKyAgICAgICAgICAgICAgICBhcmdOYW1lID0gYXJnTmFtZS5zdWJzdHJpbmcoMCwgYXJnTmFtZS5sZW5ndGgoKSAtIDEpOw0KKyAgICAgICAgICAgIH0NCisJICAgIA0KKyAgICAgICAgICAgIGNmdW5jLmFkZEFyZ3VtZW50KGFyZ05hbWUsIGFyZ1R5cGUpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgcmV0dXJuIGNmdW5jOw0KKyAgICB9DQorfQ0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zcmMvQ1R5cGUuamF2YSBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvQ1R5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzFlYzYyCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3NyYy9DVHlwZS5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKw0KK3B1YmxpYyBjbGFzcyBDVHlwZSB7DQorDQorICAgIFN0cmluZyBiYXNlVHlwZTsNCisgICAgYm9vbGVhbiBpc0NvbnN0Ow0KKyAgICBib29sZWFuIGlzUG9pbnRlcjsNCisNCisgICAgcHVibGljIENUeXBlKCkgew0KKyAgICB9DQorDQorICAgIHB1YmxpYyBDVHlwZShTdHJpbmcgYmFzZVR5cGUpIHsNCisJc2V0QmFzZVR5cGUoYmFzZVR5cGUpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBDVHlwZShTdHJpbmcgYmFzZVR5cGUsIGJvb2xlYW4gaXNDb25zdCwgYm9vbGVhbiBpc1BvaW50ZXIpIHsNCisJc2V0QmFzZVR5cGUoYmFzZVR5cGUpOw0KKwlzZXRJc0NvbnN0KGlzQ29uc3QpOw0KKwlzZXRJc1BvaW50ZXIoaXNQb2ludGVyKTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldERlY2xhcmF0aW9uKCkgew0KKwlyZXR1cm4gYmFzZVR5cGUgKyAoaXNQb2ludGVyID8gIiAqIiA6ICIiKTsNCisgICAgfQ0KKyAgICANCisgICAgcHVibGljIHZvaWQgc2V0SXNDb25zdChib29sZWFuIGlzQ29uc3QpIHsNCisJdGhpcy5pc0NvbnN0ID0gaXNDb25zdDsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnN0KCkgew0KKwlyZXR1cm4gaXNDb25zdDsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgdm9pZCBzZXRJc1BvaW50ZXIoYm9vbGVhbiBpc1BvaW50ZXIpIHsNCisJdGhpcy5pc1BvaW50ZXIgPSBpc1BvaW50ZXI7DQorICAgIH0NCisNCisgICAgcHVibGljIGJvb2xlYW4gaXNQb2ludGVyKCkgew0KKwlyZXR1cm4gaXNQb2ludGVyOw0KKyAgICB9DQorDQorICAgIGJvb2xlYW4gaXNWb2lkKCkgew0KKwlTdHJpbmcgYmFzZVR5cGUgPSBnZXRCYXNlVHlwZSgpOw0KKwlyZXR1cm4gYmFzZVR5cGUuZXF1YWxzKCJHTHZvaWQiKSB8fA0KKwkgICAgYmFzZVR5cGUuZXF1YWxzKCJ2b2lkIik7DQorICAgIH0NCisNCisgICAgcHVibGljIGJvb2xlYW4gaXNUeXBlZFBvaW50ZXIoKSB7DQorCXJldHVybiBpc1BvaW50ZXIoKSAmJiAhaXNWb2lkKCk7DQorICAgIH0NCisNCisgICAgcHVibGljIHZvaWQgc2V0QmFzZVR5cGUoU3RyaW5nIGJhc2VUeXBlKSB7DQorCXRoaXMuYmFzZVR5cGUgPSBiYXNlVHlwZTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlKCkgew0KKwlyZXR1cm4gYmFzZVR5cGU7DQorICAgIH0NCisNCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCisJU3RyaW5nIHMgPSAiIjsNCisJaWYgKGlzQ29uc3QoKSkgew0KKwkgICAgcyArPSAiY29uc3QgIjsNCisJfQ0KKwlzICs9IGJhc2VUeXBlOw0KKwlpZiAoaXNQb2ludGVyKCkpIHsNCisJICAgIHMgKz0gIioiOw0KKwl9DQorDQorCXJldHVybiBzOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7DQorCXJldHVybiBiYXNlVHlwZS5oYXNoQ29kZSgpIF4gKGlzUG9pbnRlciA/IDIgOiAwKSBeIChpc0NvbnN0ID8gMSA6IDApOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgbykgew0KKwlpZiAobyAhPSBudWxsICYmIG8gaW5zdGFuY2VvZiBDVHlwZSkgew0KKwkgICAgQ1R5cGUgYyA9IChDVHlwZSlvOw0KKwkgICAgcmV0dXJuIGJhc2VUeXBlLmVxdWFscyhjLmJhc2VUeXBlKSAmJg0KKwkJaXNQb2ludGVyKCkgPT0gYy5pc1BvaW50ZXIoKSAmJg0KKwkJaXNDb25zdCgpID09IGMuaXNDb25zdCgpOw0KKwl9DQorCXJldHVybiBmYWxzZTsNCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0NvZGVFbWl0dGVyLmphdmEgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0NvZGVFbWl0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U5YjkwYQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvQ29kZUVtaXR0ZXIuamF2YQpAQCAtMCwwICsxLDggQEAKKw0KK3B1YmxpYyBpbnRlcmZhY2UgQ29kZUVtaXR0ZXIgew0KKw0KKyAgICB2b2lkIHNldFZlcnNpb24oaW50IHZlcnNpb24sIGJvb2xlYW4gZXh0LCBib29sZWFuIHBhY2spOw0KKyAgICB2b2lkIGVtaXRDb2RlKENGdW5jIGNmdW5jLCBTdHJpbmcgb3JpZ2luYWwpOw0KKyAgICB2b2lkIGFkZE5hdGl2ZVJlZ2lzdHJhdGlvbihTdHJpbmcgZm5hbWUpOw0KKyAgICB2b2lkIGVtaXROYXRpdmVSZWdpc3RyYXRpb24oKTsNCit9DQpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rvb2xzL2dsZ2VuL3NyYy9HZW5lcmF0ZUdMLmphdmEgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0dlbmVyYXRlR0wuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTdlZTZlCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3NyYy9HZW5lcmF0ZUdMLmphdmEKQEAgLTAsMCArMSwxNjQgQEAKKw0KK2ltcG9ydCBqYXZhLmlvLio7DQoraW1wb3J0IGphdmEudXRpbC4qOw0KKw0KK3B1YmxpYyBjbGFzcyBHZW5lcmF0ZUdMIHsNCisNCisgICAgc3RhdGljIHZvaWQgY29weShTdHJpbmcgZmlsZW5hbWUsIFByaW50U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsNCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGZpbGVuYW1lKSk7DQorICAgICAgICBTdHJpbmcgczsNCisgICAgICAgIHdoaWxlICgocyA9IGJyLnJlYWRMaW5lKCkpICE9IG51bGwpIHsNCisgICAgICAgICAgICBvdXQucHJpbnRsbihzKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGVtaXQoaW50IHZlcnNpb24sIGJvb2xlYW4gZXh0LCBib29sZWFuIHBhY2ssDQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlRW1pdHRlciBlbWl0dGVyLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnVmZmVyZWRSZWFkZXIgc3BlY1JlYWRlciwNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW50U3RyZWFtIGdsU3RyZWFtLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gZ2xJbXBsU3RyZWFtLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gY1N0cmVhbSkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBTdHJpbmcgcyA9IG51bGw7DQorICAgICAgICBpbnQgY291bnRlciA9IDA7DQorICAgICAgICB3aGlsZSAoKHMgPSBzcGVjUmVhZGVyLnJlYWRMaW5lKCkpICE9IG51bGwpIHsNCisgICAgICAgICAgICBpZiAocy50cmltKCkuc3RhcnRzV2l0aCgiLy8iKSkgew0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgQ0Z1bmMgY2Z1bmMgPSBDRnVuYy5wYXJzZUNGdW5jKHMpOw0KKw0KKyAgICAgICAgICAgIFN0cmluZyBmbmFtZSA9IGNmdW5jLmdldE5hbWUoKTsNCisgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZSgic3R1YnMvIiArIGZuYW1lICsNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLmphdmEtMSIgKyB2ZXJzaW9uICsgIi1pZiIpOw0KKyAgICAgICAgICAgIGlmIChmLmV4aXN0cygpKSB7DQorICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3BlY2lhbC1jYXNpbmcgZnVuY3Rpb24gIiArIGZuYW1lKTsNCisgICAgICAgICAgICAgICAgY29weSgic3R1YnMvIiArIGZuYW1lICsNCisgICAgICAgICAgICAgICAgICAgICAiLmphdmEtMSIgKyB2ZXJzaW9uICsgIi1pZiIsIGdsU3RyZWFtKTsNCisgICAgICAgICAgICAgICAgY29weSgic3R1YnMvIiArIGZuYW1lICsgIi5qYXZhLWltcGwiLCBnbEltcGxTdHJlYW0pOw0KKyAgICAgICAgICAgICAgICBjb3B5KCJzdHVicy8iICsgZm5hbWUgKyAiLmNwcCIsIGNTdHJlYW0pOw0KKw0KKyAgICAgICAgICAgICAgICAvLyBSZWdpc3RlciBuYXRpdmUgZnVuY3Rpb24gbmFtZXMNCisgICAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgYmUgaW1wcm92ZWQgdG8gcmVxdWlyZSBmZXdlciBkaXNjcmV0ZSBmaWxlcw0KKyAgICAgICAgICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSAic3R1YnMvIiArIGZuYW1lICsgIi5uYXRpdmVSZWciOw0KKyAgICAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiciA9DQorICAgICAgICAgICAgICAgICAgICBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoZmlsZW5hbWUpKTsNCisgICAgICAgICAgICAgICAgU3RyaW5nIG5mdW5jOw0KKyAgICAgICAgICAgICAgICB3aGlsZSAoKG5mdW5jID0gYnIucmVhZExpbmUoKSkgIT0gbnVsbCkgew0KKyAgICAgICAgICAgICAgICAgICAgZW1pdHRlci5hZGROYXRpdmVSZWdpc3RyYXRpb24obmZ1bmMpOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgZW1pdHRlci5zZXRWZXJzaW9uKHZlcnNpb24sIGV4dCwgcGFjayk7DQorICAgICAgICAgICAgICAgIGVtaXR0ZXIuZW1pdENvZGUoY2Z1bmMsIHMpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBjbGFzc1BhdGhOYW1lID0gImNvbS9nb29nbGUvYW5kcm9pZC9nbGVzX2puaS9HTEltcGwiOw0KKyAgICAgICAgYm9vbGVhbiB1c2VDb250ZXh0UG9pbnRlciA9IHRydWU7DQorDQorICAgICAgICBpbnQgYWlkeCA9IDA7DQorICAgICAgICB3aGlsZSAoYXJnc1thaWR4XS5jaGFyQXQoMCkgPT0gJy0nKSB7DQorICAgICAgICAgICAgc3dpdGNoIChhcmdzW2FpZHhdLmNoYXJBdCgxKSkgew0KKyAgICAgICAgICAgIGNhc2UgJ2MnOg0KKyAgICAgICAgICAgICAgICB1c2VDb250ZXh0UG9pbnRlciA9IGZhbHNlOw0KKyAgICAgICAgICAgICAgICBicmVhazsNCisNCisgICAgICAgICAgICBkZWZhdWx0Og0KKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVua25vd24gZmxhZzogIiArIGFyZ3NbYWlkeF0pOw0KKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXhpdCgxKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgYWlkeCsrOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ1c2VDb250ZXh0UG9pbnRlciA9ICIgKyB1c2VDb250ZXh0UG9pbnRlcik7DQorDQorICAgICAgICBCdWZmZXJlZFJlYWRlciBzcGVjMTBSZWFkZXIgPQ0KKyAgICAgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihhcmdzW2FpZHgrK10pKTsNCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHNwZWMxMEV4dFJlYWRlciA9DQorICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGFyZ3NbYWlkeCsrXSkpOw0KKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgc3BlYzExUmVhZGVyID0NCisgICAgICAgICAgICBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoYXJnc1thaWR4KytdKSk7DQorICAgICAgICBCdWZmZXJlZFJlYWRlciBzcGVjMTFFeHRSZWFkZXIgPQ0KKyAgICAgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihhcmdzW2FpZHgrK10pKTsNCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHNwZWMxMUV4dFBhY2tSZWFkZXIgPQ0KKyAgICAgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihhcmdzW2FpZHgrK10pKTsNCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGNoZWNrc1JlYWRlciA9DQorICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGFyZ3NbYWlkeCsrXSkpOw0KKw0KKyAgICAgICAgU3RyaW5nIGdsMTBGaWxlbmFtZSA9ICJqYXZheC9taWNyb2VkaXRpb24va2hyb25vcy9vcGVuZ2xlcy9HTDEwLmphdmEiOw0KKyAgICAgICAgU3RyaW5nIGdsMTBFeHRGaWxlbmFtZSA9DQorICAgICAgICAgICAgImphdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTBFeHQuamF2YSI7DQorICAgICAgICBTdHJpbmcgZ2wxMUZpbGVuYW1lID0gImphdmF4L21pY3JvZWRpdGlvbi9raHJvbm9zL29wZW5nbGVzL0dMMTEuamF2YSI7DQorICAgICAgICBTdHJpbmcgZ2wxMUV4dEZpbGVuYW1lID0NCisgICAgICAgICAgICAiamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dC5qYXZhIjsNCisgICAgICAgIFN0cmluZyBnbDExRXh0UGFja0ZpbGVuYW1lID0NCisgICAgICAgICAgICAiamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wxMUV4dGVuc2lvblBhY2suamF2YSI7DQorICAgICAgICBTdHJpbmcgZ2xJbXBsRmlsZW5hbWUgPSAiY29tL2dvb2dsZS9hbmRyb2lkL2dsZXNfam5pL0dMSW1wbC5qYXZhIjsNCisgICAgICAgIFN0cmluZyBjRmlsZW5hbWUgPSAiY29tX2dvb2dsZV9hbmRyb2lkX2dsZXNfam5pX0dMSW1wbC5jcHAiOw0KKw0KKyAgICAgICAgUHJpbnRTdHJlYW0gZ2wxMFN0cmVhbSA9DQorICAgICAgICAgICAgbmV3IFByaW50U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCJvdXQvIiArIGdsMTBGaWxlbmFtZSkpOw0KKyAgICAgICAgUHJpbnRTdHJlYW0gZ2wxMEV4dFN0cmVhbSA9DQorICAgICAgICAgICAgbmV3IFByaW50U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCJvdXQvIiArIGdsMTBFeHRGaWxlbmFtZSkpOw0KKyAgICAgICAgUHJpbnRTdHJlYW0gZ2wxMVN0cmVhbSA9DQorICAgICAgICAgICAgbmV3IFByaW50U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCJvdXQvIiArIGdsMTFGaWxlbmFtZSkpOw0KKyAgICAgICAgUHJpbnRTdHJlYW0gZ2wxMUV4dFN0cmVhbSA9DQorICAgICAgICAgICAgbmV3IFByaW50U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCJvdXQvIiArIGdsMTFFeHRGaWxlbmFtZSkpOw0KKyAgICAgICAgUHJpbnRTdHJlYW0gZ2wxMUV4dFBhY2tTdHJlYW0gPQ0KKyAgICAgICAgICAgIG5ldyBQcmludFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSgib3V0LyIgKyBnbDExRXh0UGFja0ZpbGVuYW1lKSk7DQorICAgICAgICBQcmludFN0cmVhbSBnbEltcGxTdHJlYW0gPQ0KKyAgICAgICAgICAgIG5ldyBQcmludFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSgib3V0LyIgKyBnbEltcGxGaWxlbmFtZSkpOw0KKyAgICAgICAgUHJpbnRTdHJlYW0gY1N0cmVhbSA9DQorICAgICAgICAgICAgbmV3IFByaW50U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCJvdXQvIiArIGNGaWxlbmFtZSkpOw0KKw0KKyAgICAgICAgUGFyYW1ldGVyQ2hlY2tlciBjaGVja2VyID0gbmV3IFBhcmFtZXRlckNoZWNrZXIoY2hlY2tzUmVhZGVyKTsNCisNCisgICAgICAgIENvZGVFbWl0dGVyIGVtaXR0ZXIgPQ0KKyAgICAgICAgICAgIG5ldyBKbmlDb2RlRW1pdHRlcihjbGFzc1BhdGhOYW1lLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja2VyLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbDEwU3RyZWFtLCBnbDEwRXh0U3RyZWFtLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbDExU3RyZWFtLCBnbDExRXh0U3RyZWFtLCBnbDExRXh0UGFja1N0cmVhbSwNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xJbXBsU3RyZWFtLCBjU3RyZWFtLA0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VDb250ZXh0UG9pbnRlcik7DQorDQorICAgICAgICBnbDEwU3RyZWFtLnByaW50bG4oIi8qIC8vZGV2aWNlL2phdmEvYW5kcm9pZC8iICsgZ2wxMEZpbGVuYW1lKTsNCisgICAgICAgIGdsMTBFeHRTdHJlYW0ucHJpbnRsbigiLyogLy9kZXZpY2UvamF2YS9hbmRyb2lkLyIgKyBnbDEwRXh0RmlsZW5hbWUpOw0KKyAgICAgICAgZ2wxMVN0cmVhbS5wcmludGxuKCIvKiAvL2RldmljZS9qYXZhL2FuZHJvaWQvIiArIGdsMTFGaWxlbmFtZSk7DQorICAgICAgICBnbDExRXh0U3RyZWFtLnByaW50bG4oIi8qIC8vZGV2aWNlL2phdmEvYW5kcm9pZC8iICsgZ2wxMUV4dEZpbGVuYW1lKTsNCisgICAgICAgIGdsMTFFeHRQYWNrU3RyZWFtLnByaW50bG4oIi8qIC8vZGV2aWNlL2phdmEvYW5kcm9pZC8iICsNCisgICAgICAgICAgICBnbDExRXh0UGFja0ZpbGVuYW1lKTsNCisgICAgICAgIGdsSW1wbFN0cmVhbS5wcmludGxuKCIvKiAvL2RldmljZS9qYXZhL2FuZHJvaWQvIiArIGdsSW1wbEZpbGVuYW1lKTsNCisgICAgICAgIGNTdHJlYW0ucHJpbnRsbigiLyogLy9kZXZpY2UvbGlicy9hbmRyb2lkX3J1bnRpbWUvIiArIGNGaWxlbmFtZSk7DQorDQorICAgICAgICBjb3B5KCJzdHVicy9HTDEwSGVhZGVyLmphdmEtaWYiLCBnbDEwU3RyZWFtKTsNCisgICAgICAgIGNvcHkoInN0dWJzL0dMMTBFeHRIZWFkZXIuamF2YS1pZiIsIGdsMTBFeHRTdHJlYW0pOw0KKyAgICAgICAgY29weSgic3R1YnMvR0wxMUhlYWRlci5qYXZhLWlmIiwgZ2wxMVN0cmVhbSk7DQorICAgICAgICBjb3B5KCJzdHVicy9HTDExRXh0SGVhZGVyLmphdmEtaWYiLCBnbDExRXh0U3RyZWFtKTsNCisgICAgICAgIGNvcHkoInN0dWJzL0dMMTFFeHRlbnNpb25QYWNrSGVhZGVyLmphdmEtaWYiLCBnbDExRXh0UGFja1N0cmVhbSk7DQorICAgICAgICBjb3B5KCJzdHVicy9HTEltcGxIZWFkZXIuamF2YS1pbXBsIiwgZ2xJbXBsU3RyZWFtKTsNCisgICAgICAgIGNvcHkoInN0dWJzL0dMQ0hlYWRlci5jcHAiLCBjU3RyZWFtKTsNCisNCisgICAgICAgIGVtaXQoMCwgZmFsc2UsIGZhbHNlLA0KKyAgICAgICAgICAgICBlbWl0dGVyLCBzcGVjMTBSZWFkZXIsIGdsMTBTdHJlYW0sIGdsSW1wbFN0cmVhbSwgY1N0cmVhbSk7DQorICAgICAgICBlbWl0KDAsIHRydWUsIGZhbHNlLA0KKyAgICAgICAgICAgICBlbWl0dGVyLCBzcGVjMTBFeHRSZWFkZXIsIGdsMTBFeHRTdHJlYW0sIGdsSW1wbFN0cmVhbSwgY1N0cmVhbSk7DQorICAgICAgICBlbWl0KDEsIGZhbHNlLCBmYWxzZSwNCisgICAgICAgICAgICAgZW1pdHRlciwgc3BlYzExUmVhZGVyLCBnbDExU3RyZWFtLCBnbEltcGxTdHJlYW0sIGNTdHJlYW0pOw0KKyAgICAgICAgZW1pdCgxLCB0cnVlLCBmYWxzZSwNCisgICAgICAgICAgICAgZW1pdHRlciwgc3BlYzExRXh0UmVhZGVyLCBnbDExRXh0U3RyZWFtLCBnbEltcGxTdHJlYW0sIGNTdHJlYW0pOw0KKyAgICAgICAgZW1pdCgxLCB0cnVlLCB0cnVlLA0KKyAgICAgICAgICAgICBlbWl0dGVyLCBzcGVjMTFFeHRQYWNrUmVhZGVyLCBnbDExRXh0UGFja1N0cmVhbSwgZ2xJbXBsU3RyZWFtLA0KKyAgICAgICAgICAgICBjU3RyZWFtKTsNCisNCisgICAgICAgIGVtaXR0ZXIuZW1pdE5hdGl2ZVJlZ2lzdHJhdGlvbigpOw0KKw0KKyAgICAgICAgZ2wxMFN0cmVhbS5wcmludGxuKCJ9Iik7DQorICAgICAgICBnbDEwRXh0U3RyZWFtLnByaW50bG4oIn0iKTsNCisgICAgICAgIGdsMTFTdHJlYW0ucHJpbnRsbigifSIpOw0KKyAgICAgICAgZ2wxMUV4dFN0cmVhbS5wcmludGxuKCJ9Iik7DQorICAgICAgICBnbDExRXh0UGFja1N0cmVhbS5wcmludGxuKCJ9Iik7DQorICAgICAgICBnbEltcGxTdHJlYW0ucHJpbnRsbigifSIpOw0KKyAgICB9DQorfQ0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zcmMvSkZ1bmMuamF2YSBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvSkZ1bmMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MmQ0NjZjCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3NyYy9KRnVuYy5qYXZhCkBAIC0wLDAgKzEsMTQ4IEBACisNCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsNCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7DQorDQorcHVibGljIGNsYXNzIEpGdW5jIHsNCisNCisgICAgU3RyaW5nIGNsYXNzTmFtZSA9ICJjb20uZ29vZ2xlLmFuZHJvaWQuZ2xlc19qbmkuR0wxMUltcGwiOw0KKw0KKyAgICBDRnVuYyBjZnVuYzsNCisgICAgSlR5cGUgZnR5cGU7DQorICAgIFN0cmluZyBmbmFtZTsNCisNCisgICAgTGlzdDxTdHJpbmc+IGFyZ05hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7DQorICAgIExpc3Q8SlR5cGU+IGFyZ1R5cGVzID0gbmV3IEFycmF5TGlzdDxKVHlwZT4oKTsNCisgICAgTGlzdDxJbnRlZ2VyPiBhcmdDSW5kaWNlcyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsNCisNCisgICAgYm9vbGVhbiBoYXNCdWZmZXJBcmcgPSBmYWxzZTsNCisgICAgYm9vbGVhbiBoYXNUeXBlZEJ1ZmZlckFyZyA9IGZhbHNlOw0KKyAgICBBcnJheUxpc3Q8U3RyaW5nPiBidWZmZXJBcmdOYW1lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOw0KKw0KKyAgICBwdWJsaWMgSkZ1bmMoQ0Z1bmMgY2Z1bmMpIHsNCisgICAgICAgIHRoaXMuY2Z1bmMgPSBjZnVuYzsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgQ0Z1bmMgZ2V0Q0Z1bmMoKSB7DQorICAgICAgICByZXR1cm4gY2Z1bmM7DQorICAgIH0NCisNCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgZm5hbWUpIHsNCisgICAgICAgIHRoaXMuZm5hbWUgPSBmbmFtZTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7DQorICAgICAgICByZXR1cm4gZm5hbWU7DQorICAgIH0NCisNCisgICAgcHVibGljIHZvaWQgc2V0VHlwZShKVHlwZSBmdHlwZSkgew0KKyAgICAgICAgdGhpcy5mdHlwZSA9IGZ0eXBlOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBKVHlwZSBnZXRUeXBlKCkgew0KKyAgICAgICAgcmV0dXJuIGZ0eXBlOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyB2b2lkIHNldENsYXNzTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB7DQorICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsNCisgICAgICAgIHJldHVybiBjbGFzc05hbWU7DQorICAgIH0NCisgICAgDQorICAgIHB1YmxpYyBib29sZWFuIGhhc0J1ZmZlckFyZygpIHsNCisgICAgICAgIHJldHVybiBoYXNCdWZmZXJBcmc7DQorICAgIH0NCisNCisgICAgcHVibGljIGJvb2xlYW4gaGFzVHlwZWRCdWZmZXJBcmcoKSB7DQorICAgICAgICByZXR1cm4gaGFzVHlwZWRCdWZmZXJBcmc7DQorICAgIH0NCisNCisgICAgcHVibGljIFN0cmluZyBnZXRCdWZmZXJBcmdOYW1lKGludCBpbmRleCkgew0KKyAgICAgICAgcmV0dXJuIGJ1ZmZlckFyZ05hbWVzLmdldChpbmRleCk7DQorICAgIH0NCisNCisgICAgcHVibGljIHZvaWQgYWRkQXJndW1lbnQoU3RyaW5nIGFyZ05hbWUsIEpUeXBlIGFyZ1R5cGUsIGludCBjaW5kZXgpIHsNCisgICAgICAgIGFyZ05hbWVzLmFkZChhcmdOYW1lKTsNCisgICAgICAgIGFyZ1R5cGVzLmFkZChhcmdUeXBlKTsNCisgICAgICAgIGFyZ0NJbmRpY2VzLmFkZChuZXcgSW50ZWdlcihjaW5kZXgpKTsNCisNCisgICAgICAgIGlmIChhcmdUeXBlLmlzQnVmZmVyKCkpIHsNCisgICAgICAgICAgICBoYXNCdWZmZXJBcmcgPSB0cnVlOw0KKyAgICAgICAgICAgIGJ1ZmZlckFyZ05hbWVzLmFkZChhcmdOYW1lKTsNCisgICAgICAgIH0NCisgICAgICAgIGlmIChhcmdUeXBlLmlzVHlwZWRCdWZmZXIoKSkgew0KKyAgICAgICAgICAgIGhhc1R5cGVkQnVmZmVyQXJnID0gdHJ1ZTsNCisgICAgICAgICAgICBidWZmZXJBcmdOYW1lcy5hZGQoYXJnTmFtZSk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgcHVibGljIGludCBnZXROdW1BcmdzKCkgew0KKyAgICAgICAgcmV0dXJuIGFyZ05hbWVzLnNpemUoKTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgaW50IGdldEFyZ0luZGV4KFN0cmluZyBuYW1lKSB7DQorICAgICAgICBpbnQgbGVuID0gYXJnTmFtZXMuc2l6ZSgpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgew0KKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhhcmdOYW1lcy5nZXQoaSkpKSB7DQorICAgICAgICAgICAgICAgIHJldHVybiBpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiAtMTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFyZ05hbWUoaW50IGluZGV4KSB7DQorICAgICAgICByZXR1cm4gYXJnTmFtZXMuZ2V0KGluZGV4KTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgSlR5cGUgZ2V0QXJnVHlwZShpbnQgaW5kZXgpIHsNCisgICAgICAgIHJldHVybiBhcmdUeXBlcy5nZXQoaW5kZXgpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBpbnQgZ2V0QXJnQ0luZGV4KGludCBpbmRleCkgew0KKyAgICAgICAgcmV0dXJuIGFyZ0NJbmRpY2VzLmdldChpbmRleCkuaW50VmFsdWUoKTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgc3RhdGljIEpGdW5jIGNvbnZlcnQoQ0Z1bmMgY2Z1bmMsIGJvb2xlYW4gdXNlQXJyYXkpIHsNCisgICAgICAgIEpGdW5jIGpmdW5jID0gbmV3IEpGdW5jKGNmdW5jKTsNCisgICAgICAgIGpmdW5jLnNldE5hbWUoY2Z1bmMuZ2V0TmFtZSgpKTsNCisgICAgICAgIGpmdW5jLnNldFR5cGUoSlR5cGUuY29udmVydChjZnVuYy5nZXRUeXBlKCksIGZhbHNlKSk7DQorCQ0KKyAgICAgICAgaW50IG51bUFyZ3MgPSBjZnVuYy5nZXROdW1BcmdzKCk7DQorICAgICAgICBpbnQgbnVtT2Zmc2V0cyA9IDA7DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUFyZ3M7IGkrKykgew0KKyAgICAgICAgICAgIENUeXBlIGNBcmdUeXBlID0gY2Z1bmMuZ2V0QXJnVHlwZShpKTsNCisgICAgICAgICAgICBpZiAoY0FyZ1R5cGUuaXNUeXBlZFBvaW50ZXIoKSAmJiB1c2VBcnJheSkgew0KKyAgICAgICAgICAgICAgICArK251bU9mZnNldHM7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1BcmdzOyBpKyspIHsNCisgICAgICAgICAgICBTdHJpbmcgY0FyZ05hbWUgPSBjZnVuYy5nZXRBcmdOYW1lKGkpOw0KKyAgICAgICAgICAgIENUeXBlIGNBcmdUeXBlID0gY2Z1bmMuZ2V0QXJnVHlwZShpKTsNCisNCisgICAgICAgICAgICBqZnVuYy5hZGRBcmd1bWVudChjQXJnTmFtZSwgSlR5cGUuY29udmVydChjQXJnVHlwZSwgdXNlQXJyYXkpLCBpKTsNCisgICAgICAgICAgICBpZiAoY0FyZ1R5cGUuaXNUeXBlZFBvaW50ZXIoKSAmJiB1c2VBcnJheSkgew0KKyAgICAgICAgICAgICAgICBpZiAobnVtT2Zmc2V0cyA+IDEpIHsNCisgICAgICAgICAgICAgICAgICAgIGpmdW5jLmFkZEFyZ3VtZW50KGNBcmdOYW1lICsgIk9mZnNldCIsIG5ldyBKVHlwZSgiaW50IiksIGkpOw0KKyAgICAgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAgICAgamZ1bmMuYWRkQXJndW1lbnQoIm9mZnNldCIsIG5ldyBKVHlwZSgiaW50IiksIGkpOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgcmV0dXJuIGpmdW5jOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7DQorICAgICAgICBTdHJpbmcgcyA9ICAiRnVuY3Rpb24gIiArIGZuYW1lICsgIiByZXR1cm5zICIgKyBmdHlwZSArICI6ICI7DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ05hbWVzLnNpemUoKTsgaSsrKSB7DQorICAgICAgICAgICAgaWYgKGkgPiAwKSB7DQorICAgICAgICAgICAgICAgIHMgKz0gIiwgIjsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgcyArPSBhcmdUeXBlcy5nZXQoaSkgKyAiICIgKyBhcmdOYW1lcy5nZXQoaSk7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gczsNCisgICAgfQ0KKw0KK30NCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0pUeXBlLmphdmEgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0pUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTE2ZDQ0MAotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvSlR5cGUuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorDQoraW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOw0KKw0KK3B1YmxpYyBjbGFzcyBKVHlwZSB7DQorICAgIA0KKyAgICBTdHJpbmcgYmFzZVR5cGU7DQorICAgIGJvb2xlYW4gaXNBcnJheTsNCisgICAgYm9vbGVhbiBpc0NsYXNzOw0KKw0KKyAgICBzdGF0aWMgSGFzaE1hcDxDVHlwZSxKVHlwZT4gdHlwZU1hcHBpbmcgPSBuZXcgSGFzaE1hcDxDVHlwZSxKVHlwZT4oKTsNCisgICAgc3RhdGljIEhhc2hNYXA8Q1R5cGUsSlR5cGU+IGFycmF5VHlwZU1hcHBpbmcgPSBuZXcgSGFzaE1hcDxDVHlwZSxKVHlwZT4oKTsNCisNCisgICAgc3RhdGljIHsNCisJLy8gUHJpbWl0aXZlIHR5cGVzDQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMYml0ZmllbGQiKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMYm9vbGVhbiIpLCBuZXcgSlR5cGUoImJvb2xlYW4iKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMY2xhbXBmIiksIG5ldyBKVHlwZSgiZmxvYXQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMY2xhbXB4IiksIG5ldyBKVHlwZSgiaW50IikpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTGVudW0iKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMZmxvYXQiKSwgbmV3IEpUeXBlKCJmbG9hdCIpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xmaXhlZCIpLCBuZXcgSlR5cGUoImludCIpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xpbnQiKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMaW50cHRyIiksIG5ldyBKVHlwZSgiaW50IikpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHNob3J0IiksIG5ldyBKVHlwZSgic2hvcnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMc2l6ZWkiKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMc2l6ZWlwdHIiKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMdWJ5dGUiKSwgbmV3IEpUeXBlKCJieXRlIikpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHVpbnQiKSwgbmV3IEpUeXBlKCJpbnQiKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoInZvaWQiKSwgbmV3IEpUeXBlKCJ2b2lkIikpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHVieXRlIiwgdHJ1ZSwgdHJ1ZSksIG5ldyBKVHlwZSgiU3RyaW5nIikpOw0KKw0KKwkvLyBVbnR5cGVkIHBvaW50ZXJzIG1hcCB0byB1bnR5cGVkIEJ1ZmZlcnMNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0x2b2lkIiwgdHJ1ZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5CdWZmZXIiLCB0cnVlLCBmYWxzZSkpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHZvaWQiLCBmYWxzZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5CdWZmZXIiLCB0cnVlLCBmYWxzZSkpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJ2b2lkIiwgZmFsc2UsIHRydWUpLA0KKwkJCW5ldyBKVHlwZSgiamF2YS5uaW8uQnVmZmVyIiwgdHJ1ZSwgZmFsc2UpKTsNCisNCisJLy8gVHlwZWQgcG9pbnRlcnMgbWFwIHRvIHR5cGVkIEJ1ZmZlcnMNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xib29sZWFuIiwgZmFsc2UsIHRydWUpLA0KKwkJCW5ldyBKVHlwZSgiamF2YS5uaW8uSW50QnVmZmVyIiwgdHJ1ZSwgZmFsc2UpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xmaXhlZCIsIGZhbHNlLCB0cnVlKSwNCisJCQluZXcgSlR5cGUoImphdmEubmlvLkludEJ1ZmZlciIsIHRydWUsIGZhbHNlKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMZml4ZWQiLCB0cnVlLCB0cnVlKSwNCisJCQluZXcgSlR5cGUoImphdmEubmlvLkludEJ1ZmZlciIsIHRydWUsIGZhbHNlKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMZmxvYXQiLCBmYWxzZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5GbG9hdEJ1ZmZlciIsIHRydWUsIGZhbHNlKSk7DQorCXR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMZmxvYXQiLCB0cnVlLCB0cnVlKSwNCisJCQluZXcgSlR5cGUoImphdmEubmlvLkZsb2F0QnVmZmVyIiwgdHJ1ZSwgZmFsc2UpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xpbnQiLCBmYWxzZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5JbnRCdWZmZXIiLCB0cnVlLCBmYWxzZSkpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTGludCIsIHRydWUsIHRydWUpLA0KKwkJCW5ldyBKVHlwZSgiamF2YS5uaW8uSW50QnVmZmVyIiwgdHJ1ZSwgZmFsc2UpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0x1aW50IiwgZmFsc2UsIHRydWUpLA0KKwkJCW5ldyBKVHlwZSgiamF2YS5uaW8uSW50QnVmZmVyIiwgdHJ1ZSwgZmFsc2UpKTsNCisJdHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0x1aW50IiwgdHJ1ZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5JbnRCdWZmZXIiLCB0cnVlLCBmYWxzZSkpOw0KKwl0eXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHNob3J0IiwgdHJ1ZSwgdHJ1ZSksDQorCQkJbmV3IEpUeXBlKCJqYXZhLm5pby5TaG9ydEJ1ZmZlciIsIHRydWUsIGZhbHNlKSk7DQorDQorCS8vIFR5cGVkIHBvaW50ZXJzIG1hcCB0byBhcnJheXMgKyBvZmZzZXRzDQorCWFycmF5VHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xib29sZWFuIiwgZmFsc2UsIHRydWUpLA0KKwkJCSAgICAgbmV3IEpUeXBlKCJib29sZWFuIiwgZmFsc2UsIHRydWUpKTsNCisJYXJyYXlUeXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTGZpeGVkIiwgdHJ1ZSwgdHJ1ZSksIG5ldyBKVHlwZSgiaW50IiwgZmFsc2UsIHRydWUpKTsNCisJYXJyYXlUeXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTGZpeGVkIiwgZmFsc2UsIHRydWUpLCBuZXcgSlR5cGUoImludCIsIGZhbHNlLCB0cnVlKSk7DQorCWFycmF5VHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xmbG9hdCIsIGZhbHNlLCB0cnVlKSwgbmV3IEpUeXBlKCJmbG9hdCIsIGZhbHNlLCB0cnVlKSk7DQorCWFycmF5VHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xmbG9hdCIsIHRydWUsIHRydWUpLCBuZXcgSlR5cGUoImZsb2F0IiwgZmFsc2UsIHRydWUpKTsNCisJYXJyYXlUeXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTGludCIsIGZhbHNlLCB0cnVlKSwgbmV3IEpUeXBlKCJpbnQiLCBmYWxzZSwgdHJ1ZSkpOw0KKwlhcnJheVR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMaW50IiwgdHJ1ZSwgdHJ1ZSksIG5ldyBKVHlwZSgiaW50IiwgZmFsc2UsIHRydWUpKTsNCisJYXJyYXlUeXBlTWFwcGluZy5wdXQobmV3IENUeXBlKCJHTHNob3J0IiwgdHJ1ZSwgdHJ1ZSksIG5ldyBKVHlwZSgic2hvcnQiLCBmYWxzZSwgdHJ1ZSkpOw0KKwlhcnJheVR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMdWludCIsIGZhbHNlLCB0cnVlKSwgbmV3IEpUeXBlKCJpbnQiLCBmYWxzZSwgdHJ1ZSkpOw0KKwlhcnJheVR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMdWludCIsIHRydWUsIHRydWUpLCBuZXcgSlR5cGUoImludCIsIGZhbHNlLCB0cnVlKSk7DQorCWFycmF5VHlwZU1hcHBpbmcucHV0KG5ldyBDVHlwZSgiR0xpbnRwdHIiKSwgbmV3IEpUeXBlKCJpbnQiLCBmYWxzZSwgdHJ1ZSkpOw0KKwlhcnJheVR5cGVNYXBwaW5nLnB1dChuZXcgQ1R5cGUoIkdMc2l6ZWlwdHIiKSwgbmV3IEpUeXBlKCJpbnQiLCBmYWxzZSwgdHJ1ZSkpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBKVHlwZSgpIHsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgSlR5cGUoU3RyaW5nIHByaW1pdGl2ZVR5cGVOYW1lKSB7DQorCXRoaXMuYmFzZVR5cGUgPSBwcmltaXRpdmVUeXBlTmFtZTsNCisJdGhpcy5pc0NsYXNzID0gZmFsc2U7DQorCXRoaXMuaXNBcnJheSA9IGZhbHNlOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBKVHlwZShTdHJpbmcgcHJpbWl0aXZlVHlwZU5hbWUsIGJvb2xlYW4gaXNDbGFzcywgYm9vbGVhbiBpc0FycmF5KSB7DQorCXRoaXMuYmFzZVR5cGUgPSBwcmltaXRpdmVUeXBlTmFtZTsNCisJdGhpcy5pc0NsYXNzID0gaXNDbGFzczsNCisJdGhpcy5pc0FycmF5ID0gaXNBcnJheTsNCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlKCkgew0KKwlyZXR1cm4gYmFzZVR5cGU7DQorICAgIH0NCisNCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCisJcmV0dXJuIGJhc2VUeXBlICsgKGlzQXJyYXkgPyAiW10iIDogIiIpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGlzQXJyYXkoKSB7DQorCXJldHVybiBpc0FycmF5Ow0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGlzQ2xhc3MoKSB7DQorCXJldHVybiBpc0NsYXNzOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlKCkgew0KKwlyZXR1cm4gIWlzQ2xhc3MoKSAmJiAhaXNBcnJheSgpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGlzVm9pZCgpIHsNCisJcmV0dXJuIGJhc2VUeXBlLmVxdWFscygidm9pZCIpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBib29sZWFuIGlzQnVmZmVyKCkgew0KKwlyZXR1cm4gYmFzZVR5cGUuaW5kZXhPZigiQnVmZmVyIikgIT0gLTE7DQorICAgIH0NCisNCisgICAgcHVibGljIGJvb2xlYW4gaXNUeXBlZEJ1ZmZlcigpIHsNCisJcmV0dXJuICFiYXNlVHlwZS5lcXVhbHMoImphdmEubmlvLkJ1ZmZlciIpICYmDQorCSAgICAoYmFzZVR5cGUuaW5kZXhPZigiQnVmZmVyIikgIT0gLTEpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyBzdGF0aWMgSlR5cGUgY29udmVydChDVHlwZSBjdHlwZSwgYm9vbGVhbiB1c2VBcnJheSkgew0KKyAJSlR5cGUgamF2YVR5cGUgPSBudWxsOw0KKyAJaWYgKHVzZUFycmF5KSB7DQorIAkgICAgamF2YVR5cGUgPSBhcnJheVR5cGVNYXBwaW5nLmdldChjdHlwZSk7DQorIAl9DQorIAlpZiAoamF2YVR5cGUgPT0gbnVsbCkgew0KKyAJICAgIGphdmFUeXBlID0gdHlwZU1hcHBpbmcuZ2V0KGN0eXBlKTsNCisgCX0NCisgCWlmIChqYXZhVHlwZSA9PSBudWxsKSB7DQorIAkgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuc3VwcG9ydGVkIEMgdHlwZTogIiArIGN0eXBlKTsNCisgCX0NCisgCXJldHVybiBqYXZhVHlwZTsNCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0puaUNvZGVFbWl0dGVyLmphdmEgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL0puaUNvZGVFbWl0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzNiOWEzZQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvSm5pQ29kZUVtaXR0ZXIuamF2YQpAQCAtMCwwICsxLDEwODYgQEAKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBFbWl0cyBhIEphdmEgaW50ZXJmYWNlIGFuZCBKYXZhICYgQyBpbXBsZW1lbnRhdGlvbiBmb3IgYSBDIGZ1bmN0aW9uLgorICoKKyAqIDxwPiBUaGUgSmF2YSBpbnRlcmZhY2Ugd2lsbCBoYXZlIEJ1ZmZlciBhbmQgYXJyYXkgdmFyaWFudHMgZm9yIGZ1bmN0aW9ucyB0aGF0CisgKiBoYXZlIGEgdHlwZWQgcG9pbnRlciBhcmd1bWVudC4gIFRoZSBhcnJheSB2YXJpYW50IHdpbGwgY29udmVydCBhIHNpbmdsZSAiPHR5cGU+ICpkYXRhIgorICogYXJndW1lbnQgdG8gYSBwYWlyIG9mIGFyZ3VtZW50cyAiPHR5cGU+W10gZGF0YSwgaW50IG9mZnNldCIuCisgKi8KK3B1YmxpYyBjbGFzcyBKbmlDb2RlRW1pdHRlciBpbXBsZW1lbnRzIENvZGVFbWl0dGVyIHsKKworICAgIC8vIElmIHRydWUsIHVzZSBDKysgc3R5bGUgZm9yIGNhbGxpbmcgdGhyb3VnaCBhIEpOSUVudiAqOgorICAgIC8vIGVudi0+RnVuYyguLi4pCisgICAgLy8gSWYgZmFsc2UsIHVzZSBDIHN0eWxlOgorICAgIC8vICgqZW52KS0+RnVuYyhlbnYsIC4uLikKKyAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBtVXNlQ1BsdXNQbHVzID0gdHJ1ZTsKKworICAgIGJvb2xlYW4gbVVzZUNvbnRleHRQb2ludGVyID0gdHJ1ZTsKKworICAgIFN0cmluZyBtQ2xhc3NQYXRoTmFtZTsKKyAgICAKKyAgICBQYXJhbWV0ZXJDaGVja2VyIG1DaGVja2VyOworICAgIFByaW50U3RyZWFtIG1KYXZhMTBJbnRlcmZhY2VTdHJlYW07CisgICAgUHJpbnRTdHJlYW0gbUphdmExMEV4dEludGVyZmFjZVN0cmVhbTsKKyAgICBQcmludFN0cmVhbSBtSmF2YTExSW50ZXJmYWNlU3RyZWFtOworICAgIFByaW50U3RyZWFtIG1KYXZhMTFFeHRJbnRlcmZhY2VTdHJlYW07CisgICAgUHJpbnRTdHJlYW0gbUphdmExMUV4dFBhY2tJbnRlcmZhY2VTdHJlYW07CisgICAgUHJpbnRTdHJlYW0gbUphdmFJbXBsU3RyZWFtOworICAgIFByaW50U3RyZWFtIG1DU3RyZWFtOworCisgICAgUHJpbnRTdHJlYW0gbUphdmFJbnRlcmZhY2VTdHJlYW07CisKKyAgICBMaXN0PFN0cmluZz4gbmF0aXZlUmVnaXN0cmF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgYm9vbGVhbiBuZWVkc0V4aXQ7CisKKyAgICBzdGF0aWMgU3RyaW5nIGluZGVudCA9ICIgICAgIjsKKworICAgIEhhc2hTZXQ8U3RyaW5nPiBtRnVuY3Rpb25zRW1pdHRlZCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBqYXZhMTBJbnRlcmZhY2VTdHJlYW0gdGhlIFByaW50U3RyZWFtIHRvIHdoaWNoIHRvIGVtaXQgdGhlIEphdmEgaW50ZXJmYWNlIGZvciBHTCAxLjAgZnVuY3Rpb25zCisgICAgICogQHBhcmFtIGphdmExMEV4dEludGVyZmFjZVN0cmVhbSB0aGUgUHJpbnRTdHJlYW0gdG8gd2hpY2ggdG8gZW1pdCB0aGUgSmF2YSBpbnRlcmZhY2UgZm9yIEdMIDEuMCBleHRlbnNpb24gZnVuY3Rpb25zCisgICAgICogQHBhcmFtIGphdmExMUludGVyZmFjZVN0cmVhbSB0aGUgUHJpbnRTdHJlYW0gdG8gd2hpY2ggdG8gZW1pdCB0aGUgSmF2YSBpbnRlcmZhY2UgZm9yIEdMIDEuMSBmdW5jdGlvbnMgCisgICAgICogQHBhcmFtIGphdmExMUV4dEludGVyZmFjZVN0cmVhbSB0aGUgUHJpbnRTdHJlYW0gdG8gd2hpY2ggdG8gZW1pdCB0aGUgSmF2YSBpbnRlcmZhY2UgZm9yIEdMIDEuMSBFeHRlbnNpb24gZnVuY3Rpb25zCisgICAgICogQHBhcmFtIGphdmExMUV4dFBhY2tJbnRlcmZhY2VTdHJlYW0gdGhlIFByaW50U3RyZWFtIHRvIHdoaWNoIHRvIGVtaXQgdGhlIEphdmEgaW50ZXJmYWNlIGZvciBHTCAxLjEgRXh0ZW5zaW9uIFBhY2sgZnVuY3Rpb25zCisgICAgICogQHBhcmFtIGphdmFJbXBsU3RyZWFtIHRoZSBQcmludFN0cmVhbSB0byB3aGljaCB0byBlbWl0IHRoZSBKYXZhIGltcGxlbWVudGF0aW9uCisgICAgICogQHBhcmFtIGNTdHJlYW0gdGhlIFByaW50U3RyZWFtIHRvIHdoaWNoIHRvIGVtaXQgdGhlIEMgaW1wbGVtZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgSm5pQ29kZUVtaXR0ZXIoU3RyaW5nIGNsYXNzUGF0aE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmFtZXRlckNoZWNrZXIgY2hlY2tlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gamF2YTEwSW50ZXJmYWNlU3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQcmludFN0cmVhbSBqYXZhMTBFeHRJbnRlcmZhY2VTdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW50U3RyZWFtIGphdmExMUludGVyZmFjZVN0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gamF2YTExRXh0SW50ZXJmYWNlU3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQcmludFN0cmVhbSBqYXZhMTFFeHRQYWNrSW50ZXJmYWNlU3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQcmludFN0cmVhbSBqYXZhSW1wbFN0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRTdHJlYW0gY1N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VDb250ZXh0UG9pbnRlcikgeworICAgICAgICBtQ2xhc3NQYXRoTmFtZSA9IGNsYXNzUGF0aE5hbWU7CisgICAgICAgIG1DaGVja2VyID0gY2hlY2tlcjsKKyAgICAgICAgbUphdmExMEludGVyZmFjZVN0cmVhbSA9IGphdmExMEludGVyZmFjZVN0cmVhbTsKKyAgICAgICAgbUphdmExMEV4dEludGVyZmFjZVN0cmVhbSA9IGphdmExMEV4dEludGVyZmFjZVN0cmVhbTsKKyAgICAgICAgbUphdmExMUludGVyZmFjZVN0cmVhbSA9IGphdmExMUludGVyZmFjZVN0cmVhbTsKKyAgICAgICAgbUphdmExMUV4dEludGVyZmFjZVN0cmVhbSA9IGphdmExMUV4dEludGVyZmFjZVN0cmVhbTsKKyAgICAgICAgbUphdmExMUV4dFBhY2tJbnRlcmZhY2VTdHJlYW0gPSBqYXZhMTFFeHRQYWNrSW50ZXJmYWNlU3RyZWFtOworICAgICAgICBtSmF2YUltcGxTdHJlYW0gPSBqYXZhSW1wbFN0cmVhbTsKKyAgICAgICAgbUNTdHJlYW0gPSBjU3RyZWFtOworICAgICAgICBtVXNlQ29udGV4dFBvaW50ZXIgPSB1c2VDb250ZXh0UG9pbnRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKGludCB2ZXJzaW9uLCBib29sZWFuIGV4dCwgYm9vbGVhbiBwYWNrKSB7CisgICAgICAgIGlmICh2ZXJzaW9uID09IDApIHsKKyAgICAgICAgICAgIG1KYXZhSW50ZXJmYWNlU3RyZWFtID0gZXh0ID8gbUphdmExMEV4dEludGVyZmFjZVN0cmVhbSA6CisgICAgICAgICAgICAgICAgbUphdmExMEludGVyZmFjZVN0cmVhbTsKKyAgICAgICAgfSBlbHNlIGlmICh2ZXJzaW9uID09IDEpIHsKKyAgICAgICAgICAgIG1KYXZhSW50ZXJmYWNlU3RyZWFtID0gZXh0ID8KKyAgICAgICAgICAgICAgICAocGFjayA/IG1KYXZhMTFFeHRQYWNrSW50ZXJmYWNlU3RyZWFtIDoKKyAgICAgICAgICAgICAgICAgbUphdmExMUV4dEludGVyZmFjZVN0cmVhbSkgOgorICAgICAgICAgICAgICAgIG1KYXZhMTFJbnRlcmZhY2VTdHJlYW07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQmFkIHZlcnNpb246ICIgKyB2ZXJzaW9uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVtaXRDb2RlKENGdW5jIGNmdW5jLCBTdHJpbmcgb3JpZ2luYWwpIHsKKyAgICAgICAgSkZ1bmMgamZ1bmM7CisgICAgICAgIFN0cmluZyBzaWduYXR1cmU7CisgICAgICAgIGJvb2xlYW4gZHVwbGljYXRlOworICAgICAgICAKKyAgICAgICAgaWYgKGNmdW5jLmhhc1R5cGVkUG9pbnRlckFyZygpKSB7CisgICAgICAgICAgICBqZnVuYyA9IEpGdW5jLmNvbnZlcnQoY2Z1bmMsIHRydWUpOworCisgICAgICAgICAgICAvLyBEb24ndCBlbWl0IGR1cGxpY2F0ZSBmdW5jdGlvbnMKKyAgICAgICAgICAgIC8vIFRoZXNlIG1heSBhcHBlYXIgYmVjYXVzZSB0aGV5IGFyZSBkZWZpbmVkIGluIG11bHRpcGxlCisgICAgICAgICAgICAvLyBKYXZhIGludGVyZmFjZXMgKGUuZy4sIEdMMTEvR0wxMUV4dGVuc2lvblBhY2spCisgICAgICAgICAgICBzaWduYXR1cmUgPSBqZnVuYy50b1N0cmluZygpOworICAgICAgICAgICAgZHVwbGljYXRlID0gZmFsc2U7CisgICAgICAgICAgICBpZiAobUZ1bmN0aW9uc0VtaXR0ZWQuY29udGFpbnMoc2lnbmF0dXJlKSkgeworICAgICAgICAgICAgICAgIGR1cGxpY2F0ZSA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG1GdW5jdGlvbnNFbWl0dGVkLmFkZChzaWduYXR1cmUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIWR1cGxpY2F0ZSkgeworICAgICAgICAgICAgICAgIGVtaXROYXRpdmVEZWNsYXJhdGlvbihqZnVuYywgbUphdmFJbXBsU3RyZWFtKTsKKyAgICAgICAgICAgICAgICBlbWl0SmF2YUNvZGUoamZ1bmMsIG1KYXZhSW1wbFN0cmVhbSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbWl0SmF2YUludGVyZmFjZUNvZGUoamZ1bmMsIG1KYXZhSW50ZXJmYWNlU3RyZWFtKTsKKyAgICAgICAgICAgIGlmICghZHVwbGljYXRlKSB7CisgICAgICAgICAgICAgICAgZW1pdEpuaUNvZGUoamZ1bmMsIG1DU3RyZWFtKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGpmdW5jID0gSkZ1bmMuY29udmVydChjZnVuYywgZmFsc2UpOworCisgICAgICAgIHNpZ25hdHVyZSA9IGpmdW5jLnRvU3RyaW5nKCk7CisgICAgICAgIGR1cGxpY2F0ZSA9IGZhbHNlOworICAgICAgICBpZiAobUZ1bmN0aW9uc0VtaXR0ZWQuY29udGFpbnMoc2lnbmF0dXJlKSkgeworICAgICAgICAgICAgZHVwbGljYXRlID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1GdW5jdGlvbnNFbWl0dGVkLmFkZChzaWduYXR1cmUpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFkdXBsaWNhdGUpIHsKKyAgICAgICAgICAgIGVtaXROYXRpdmVEZWNsYXJhdGlvbihqZnVuYywgbUphdmFJbXBsU3RyZWFtKTsKKyAgICAgICAgfQorICAgICAgICBlbWl0SmF2YUludGVyZmFjZUNvZGUoamZ1bmMsIG1KYXZhSW50ZXJmYWNlU3RyZWFtKTsKKyAgICAgICAgaWYgKCFkdXBsaWNhdGUpIHsKKyAgICAgICAgICAgIGVtaXRKYXZhQ29kZShqZnVuYywgbUphdmFJbXBsU3RyZWFtKTsKKyAgICAgICAgICAgIGVtaXRKbmlDb2RlKGpmdW5jLCBtQ1N0cmVhbSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbWl0TmF0aXZlRGVjbGFyYXRpb24oSkZ1bmMgamZ1bmMsIFByaW50U3RyZWFtIG91dCkgeworICAgICAgICBvdXQucHJpbnRsbigiICAgIC8vIEMgZnVuY3Rpb24gIiArIGpmdW5jLmdldENGdW5jKCkuZ2V0T3JpZ2luYWwoKSk7CisgICAgICAgIG91dC5wcmludGxuKCk7CisKKyAgICAgICAgZW1pdEZ1bmN0aW9uKGpmdW5jLCBvdXQsIHRydWUsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbWl0SmF2YUludGVyZmFjZUNvZGUoSkZ1bmMgamZ1bmMsIFByaW50U3RyZWFtIG91dCkgeworICAgICAgICBlbWl0RnVuY3Rpb24oamZ1bmMsIG91dCwgZmFsc2UsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVtaXRKYXZhQ29kZShKRnVuYyBqZnVuYywgUHJpbnRTdHJlYW0gb3V0KSB7CisgICAgICAgIGVtaXRGdW5jdGlvbihqZnVuYywgb3V0LCBmYWxzZSwgZmFsc2UpOworICAgIH0KKyAgICAKKyAgICB2b2lkIGVtaXRGdW5jdGlvbkNhbGwoSkZ1bmMgamZ1bmMsIFByaW50U3RyZWFtIG91dCwgU3RyaW5nIGlpaSwgYm9vbGVhbiBncmFiQXJyYXkgKSB7CisgICAgICAgIGJvb2xlYW4gaXNWb2lkID0gamZ1bmMuZ2V0VHlwZSgpLmlzVm9pZCgpOworICAgICAgICBib29sZWFuIGlzUG9pbnRlckZ1bmMgPSBqZnVuYy5nZXROYW1lKCkuZW5kc1dpdGgoIlBvaW50ZXIiKSAmJgorICAgICAgICAgICAgamZ1bmMuZ2V0Q0Z1bmMoKS5oYXNQb2ludGVyQXJnKCk7CisKKyAgICAgICAgaWYgKCFpc1ZvaWQpIHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArCisgICAgICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXRUeXBlKCkgKyAiIF9yZXR1cm5WYWx1ZTsiKTsKKyAgICAgICAgfQorICAgICAgICBvdXQucHJpbnRsbihpaWkgKworICAgICAgICAgICAgICAgICAgICAoaXNWb2lkID8gIiIgOiAiX3JldHVyblZhbHVlID0gIikgKworICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAoaXNQb2ludGVyRnVuYyA/ICJCb3VuZHMiIDogIiIgKSArCisgICAgICAgICAgICAgICAgICAgICIoIik7CisJCisgICAgICAgIGludCBudW1BcmdzID0gamZ1bmMuZ2V0TnVtQXJncygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUFyZ3M7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGFyZ05hbWUgPSBqZnVuYy5nZXRBcmdOYW1lKGkpOworICAgICAgICAgICAgSlR5cGUgYXJnVHlwZSA9IGpmdW5jLmdldEFyZ1R5cGUoaSk7CisKKyAgICAgICAgICAgIGlmIChncmFiQXJyYXkgJiYgYXJnVHlwZS5pc1R5cGVkQnVmZmVyKCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZU5hbWUgPSBhcmdUeXBlLmdldEJhc2VUeXBlKCk7CisgICAgICAgICAgICAgICAgdHlwZU5hbWUgPSB0eXBlTmFtZS5zdWJzdHJpbmcoOSwgdHlwZU5hbWUubGVuZ3RoKCkgLSA2KTsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyBpbmRlbnQgKyAiZ2V0IiArIHR5cGVOYW1lICsgIkFycmF5KCIgKyBhcmdOYW1lICsgIiksIik7CisgICAgICAgICAgICAgICAgb3V0LnByaW50KGlpaSArIGluZGVudCArICJnZXRPZmZzZXQoIiArIGFyZ05hbWUgKyAiKSIpOyAKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50KGlpaSArIGluZGVudCArIGFyZ05hbWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gbnVtQXJncyAtIDEpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNQb2ludGVyRnVuYykgeworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiLCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyBpbmRlbnQgKyBhcmdOYW1lICsgIi5yZW1haW5pbmcoKSIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiLCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisJCisgICAgICAgIG91dC5wcmludGxuKGlpaSArICIpOyIpOworICAgIH0KKworICAgIHZvaWQgcHJpbnRJZmNoZWNrUG9zdGFtYmxlKFByaW50U3RyZWFtIG91dCwgYm9vbGVhbiBpc0J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVtaXRFeGNlcHRpb25DaGVjaywgU3RyaW5nIGlpaSkgeworICAgICAgICBwcmludElmY2hlY2tQb3N0YW1ibGUob3V0LCBpc0J1ZmZlciwgZW1pdEV4Y2VwdGlvbkNoZWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9mZnNldCIsICJfcmVtYWluaW5nIiwgaWlpKTsKKyAgICB9CisKKyAgICB2b2lkIHByaW50SWZjaGVja1Bvc3RhbWJsZShQcmludFN0cmVhbSBvdXQsIGJvb2xlYW4gaXNCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbWl0RXhjZXB0aW9uQ2hlY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG9mZnNldCwgU3RyaW5nIHJlbWFpbmluZywgU3RyaW5nIGlpaSkgeworICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgIGRlZmF1bHQ6Iik7CisgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgICAgIF9uZWVkZWQgPSAwOyIpOworICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAgICBicmVhazsiKTsKKyAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIn0iKTsKKworICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiaWYgKCIgKyByZW1haW5pbmcgKyAiIDwgX25lZWRlZCkgeyIpOworICAgICAgICBpZiAoZW1pdEV4Y2VwdGlvbkNoZWNrKSB7CisgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyBpbmRlbnQgKyAiX2V4Y2VwdGlvbiA9IDE7Iik7CisgICAgICAgIH0KKyAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgKG1Vc2VDUGx1c1BsdXMgPyAiX2VudiIgOiAiKCpfZW52KSIpICsKKyAgICAgICAgICAgICAgICAgICAgIi0+VGhyb3dOZXcoIiArCisgICAgICAgICAgICAgICAgICAgIChtVXNlQ1BsdXNQbHVzID8gIiIgOiAiX2VudiwgIikgKworICAgICAgICAgICAgICAgICAgICAiSUFFQ2xhc3MsICIgKworICAgICAgICAgICAgICAgICAgICAiXCIiICsKKyAgICAgICAgICAgICAgICAgICAgKGlzQnVmZmVyID8gCisgICAgICAgICAgICAgICAgICAgICAicmVtYWluaW5nKCkiIDogImxlbmd0aCAtICIgKyBvZmZzZXQpICsKKyAgICAgICAgICAgICAgICAgICAgIiA8IG5lZWRlZFwiKTsiKTsKKyAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsgImdvdG8gZXhpdDsiKTsKKyAgICAgICAgbmVlZHNFeGl0ID0gdHJ1ZTsKKyAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIn0iKTsKKyAgICB9CisKKyAgICBib29sZWFuIGlzTnVsbEFsbG93ZWQoQ0Z1bmMgY2Z1bmMpIHsKKyAgICAgICAgU3RyaW5nW10gY2hlY2tzID0gbUNoZWNrZXIuZ2V0Q2hlY2tzKGNmdW5jLmdldE5hbWUoKSk7CisgICAgICAgIGludCBpbmRleCA9IDE7CisgICAgICAgIGlmIChjaGVja3MgIT0gbnVsbCkgeworICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgY2hlY2tzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGlmIChjaGVja3NbaW5kZXhdLmVxdWFscygicmV0dXJuIikpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uc3RhcnRzV2l0aCgiY2hlY2siKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAzOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoImlmY2hlY2siKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSA1OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoInVuc3VwcG9ydGVkIikpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJudWxsQWxsb3dlZCIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXJyb3I6IHVua25vd24ga2V5d29yZCBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tzW2luZGV4XSArICJcIiIpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXhpdCgwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIFN0cmluZyBnZXRFcnJvclJldHVyblZhbHVlKENGdW5jIGNmdW5jKSB7CisgICAgICAgIENUeXBlIHJldHVyblR5cGUgPSBjZnVuYy5nZXRUeXBlKCk7CisgICAgICAgIGJvb2xlYW4gaXNWb2lkID0gcmV0dXJuVHlwZS5pc1ZvaWQoKTsKKyAgICAgICAgaWYgKGlzVm9pZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBjaGVja3MgPSBtQ2hlY2tlci5nZXRDaGVja3MoY2Z1bmMuZ2V0TmFtZSgpKTsKKworICAgICAgICBpbnQgaW5kZXggPSAxOworICAgICAgICBpZiAoY2hlY2tzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChpbmRleCA8IGNoZWNrcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoInJldHVybiIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGVja3NbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uc3RhcnRzV2l0aCgiY2hlY2siKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAzOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoImlmY2hlY2siKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSA1OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoInVuc3VwcG9ydGVkIikpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJudWxsQWxsb3dlZCIpKSB7CisgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvcjogdW5rbm93biBrZXl3b3JkIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja3NbaW5kZXhdICsgIlwiIik7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5leGl0KDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIGJvb2xlYW4gaXNVbnN1cHBvcnRlZEZ1bmMoQ0Z1bmMgY2Z1bmMpIHsKKyAgICAgICAgU3RyaW5nW10gY2hlY2tzID0gbUNoZWNrZXIuZ2V0Q2hlY2tzKGNmdW5jLmdldE5hbWUoKSk7CisgICAgICAgIGludCBpbmRleCA9IDE7CisgICAgICAgIGlmIChjaGVja3MgIT0gbnVsbCkgeworICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgY2hlY2tzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGlmIChjaGVja3NbaW5kZXhdLmVxdWFscygidW5zdXBwb3J0ZWQiKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJyZXR1cm4iKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5zdGFydHNXaXRoKCJjaGVjayIpKSB7CisgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDM7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVja3NbaW5kZXhdLmVxdWFscygiaWZjaGVjayIpKSB7CisgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVja3NbaW5kZXhdLmVxdWFscygibnVsbEFsbG93ZWQiKSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAxOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXJyb3I6IHVua25vd24ga2V5d29yZCBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tzW2luZGV4XSArICJcIiIpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXhpdCgwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHZvaWQgZW1pdE5hdGl2ZUJvdW5kc0NoZWNrcyhDRnVuYyBjZnVuYywgU3RyaW5nIGNuYW1lLCBQcmludFN0cmVhbSBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNCdWZmZXIsIGJvb2xlYW4gZW1pdEV4Y2VwdGlvbkNoZWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgb2Zmc2V0LCBTdHJpbmcgcmVtYWluaW5nLCBTdHJpbmcgaWlpKSB7CisgICAgICAgIENUeXBlIHJldHVyblR5cGUgPSBjZnVuYy5nZXRUeXBlKCk7CisgICAgICAgIGJvb2xlYW4gaXNWb2lkID0gcmV0dXJuVHlwZS5pc1ZvaWQoKTsKKworICAgICAgICBTdHJpbmdbXSBjaGVja3MgPSBtQ2hlY2tlci5nZXRDaGVja3MoY2Z1bmMuZ2V0TmFtZSgpKTsKKyAgICAgICAgU3RyaW5nIGNoZWNrVmFyOworICAgICAgICBTdHJpbmcgcmV0dmFsID0gZ2V0RXJyb3JSZXR1cm5WYWx1ZShjZnVuYyk7CisKKyAgICAgICAgYm9vbGVhbiBsYXN0V2FzSWZjaGVjayA9IGZhbHNlOworCisgICAgICAgIGludCBpbmRleCA9IDE7CisgICAgICAgIGlmIChjaGVja3MgIT0gbnVsbCkgeworICAgICAgICAgICAgYm9vbGVhbiByZW1haW5pbmdEZWNsYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgYm9vbGVhbiBudWxsQ2hlY2tEZWNsYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgYm9vbGVhbiBvZmZzZXRDaGVja2VkID0gZmFsc2U7CisgICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBjaGVja3MubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoZWNrc1tpbmRleF0uc3RhcnRzV2l0aCgiY2hlY2siKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAobGFzdFdhc0lmY2hlY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByaW50SWZjaGVja1Bvc3RhbWJsZShvdXQsIGlzQnVmZmVyLCBlbWl0RXhjZXB0aW9uQ2hlY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LCByZW1haW5pbmcsIGlpaSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGFzdFdhc0lmY2hlY2sgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNuYW1lICE9IG51bGwgJiYgIWNuYW1lLmVxdWFscyhjaGVja3NbaW5kZXggKyAxXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDM7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiaWYgKCIgKyByZW1haW5pbmcgKyAiIDwgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrc1tpbmRleCArIDJdICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIikgeyIpOworICAgICAgICAgICAgICAgICAgICBpZiAoZW1pdEV4Y2VwdGlvbkNoZWNrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyBpbmRlbnQgKyAiX2V4Y2VwdGlvbiA9IDE7Iik7CisgICAgICAgICAgICAgICAgICAgIH0KKwkJICAgIFN0cmluZyBleGNlcHRpb25DbGFzc05hbWUgPSAiSUFFQ2xhc3MiOworCQkgICAgLy8gSWYgdGhlICJjaGVjayIga2V5d29yZCB3YXMgb2YgdGhlIGZvcm0KKwkJICAgIC8vICJjaGVja188Y2xhc3MgbmFtZT4iLCB1c2UgdGhlIGNsYXNzIG5hbWUgaW4gdGhlCisJCSAgICAvLyBleGNlcHRpb24gdG8gYmUgdGhyb3duCisJCSAgICBpbnQgdW5kZXJzY29yZSA9IGNoZWNrc1tpbmRleF0uaW5kZXhPZignXycpOworCQkgICAgaWYgKHVuZGVyc2NvcmUgPj0gMCkgeworCQkJZXhjZXB0aW9uQ2xhc3NOYW1lID0gY2hlY2tzW2luZGV4XS5zdWJzdHJpbmcodW5kZXJzY29yZSArIDEpICsgIkNsYXNzIjsKKwkJICAgIH0KKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1Vc2VDUGx1c1BsdXMgPyAiX2VudiIgOiAiKCpfZW52KSIpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi0+VGhyb3dOZXcoIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtVXNlQ1BsdXNQbHVzID8gIiIgOiAiX2VudiwgIikgKworCQkJCWV4Y2VwdGlvbkNsYXNzTmFtZSArICIsICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlzQnVmZmVyID8gCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVtYWluaW5nKCkiIDogImxlbmd0aCAtICIgKyBvZmZzZXQpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiA8ICIgKyBjaGVja3NbaW5kZXggKyAyXSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIik7Iik7CisKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsgImdvdG8gZXhpdDsiKTsKKyAgICAgICAgICAgICAgICAgICAgbmVlZHNFeGl0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIn0iKTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJpZmNoZWNrIikpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nW10gbWF0Y2hlcyA9IGNoZWNrc1tpbmRleCArIDRdLnNwbGl0KCIsIik7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFsYXN0V2FzSWZjaGVjaykgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgImludCBfbmVlZGVkOyIpOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzd2l0Y2ggKCIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tzW2luZGV4ICsgM10gKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIikgeyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hdGNoZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIjaWYgZGVmaW5lZCgiICsgbWF0Y2hlc1tpXSArICIpIik7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBjYXNlICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlc1tpXSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOiIpOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIiNlbmRpZiAvLyBkZWZpbmVkKCIgKyBtYXRjaGVzW2ldICsgIikiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICAgICBfbmVlZGVkID0gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrc1tpbmRleCArIDJdICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjsiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAgICAgYnJlYWs7Iik7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgIGxhc3RXYXNJZmNoZWNrID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gNTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJyZXR1cm4iKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrc1tpbmRleF0uZXF1YWxzKCJ1bnN1cHBvcnRlZCIpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAxOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tzW2luZGV4XS5lcXVhbHMoIm51bGxBbGxvd2VkIikpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvcjogdW5rbm93biBrZXl3b3JkIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja3NbaW5kZXhdICsgIlwiIik7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5leGl0KDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChsYXN0V2FzSWZjaGVjaykgeworICAgICAgICAgICAgcHJpbnRJZmNoZWNrUG9zdGFtYmxlKG91dCwgaXNCdWZmZXIsIGVtaXRFeGNlcHRpb25DaGVjaywgaWlpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGJvb2xlYW4gaGFzTm9uQ29uc3RBcmcoSkZ1bmMgamZ1bmMsIENGdW5jIGNmdW5jLAorICAgICAgICBMaXN0PEludGVnZXI+IG5vblByaW1pdGl2ZUFyZ3MpIHsKKyAgICAgICAgaWYgKG5vblByaW1pdGl2ZUFyZ3Muc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IG5vblByaW1pdGl2ZUFyZ3Muc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpbnQgaWR4ID0gbm9uUHJpbWl0aXZlQXJncy5nZXQoaSkuaW50VmFsdWUoKTsKKyAgICAgICAgICAgICAgICBpbnQgY0luZGV4ID0gamZ1bmMuZ2V0QXJnQ0luZGV4KGlkeCk7CisgICAgICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaWR4KS5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjZnVuYy5nZXRBcmdUeXBlKGNJbmRleCkuaXNDb25zdCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoamZ1bmMuZ2V0QXJnVHlwZShpZHgpLmlzQnVmZmVyKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjZnVuYy5nZXRBcmdUeXBlKGNJbmRleCkuaXNDb25zdCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogRW1pdCBhIGZ1bmN0aW9uIGluIHNldmVyYWwgdmFyaWFudHM6CisgICAgICoKKyAgICAgKiBpZiBuYXRpdmVEZWNsOiBwdWJsaWMgbmF0aXZlIDxyZXR1cm50eXBlPiBmdW5jKGFyZ3MpOworICAgICAqCisgICAgICogaWYgIW5hdGl2ZURlY2w6CisgICAgICogICBpZiBpbnRlcmZhY2VEZWNsOiAgcHVibGljIDxyZXR1cm50eXBlPiBmdW5jKGFyZ3MpOworICAgICAqICAgaWYgIWludGVyZmFjZURlY2w6IHB1YmxpYyA8cmV0dXJudHlwZT4gZnVuYyhhcmdzKSB7IGJvZHkgfQorICAgICAqLworICAgIHZvaWQgZW1pdEZ1bmN0aW9uKEpGdW5jIGpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgIFByaW50U3RyZWFtIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG5hdGl2ZURlY2wsIGJvb2xlYW4gaW50ZXJmYWNlRGVjbCkgeworICAgICAgICBib29sZWFuIGlzUG9pbnRlckZ1bmMgPQorICAgICAgICAgICAgamZ1bmMuZ2V0TmFtZSgpLmVuZHNXaXRoKCJQb2ludGVyIikgJiYKKyAgICAgICAgICAgIGpmdW5jLmdldENGdW5jKCkuaGFzUG9pbnRlckFyZygpOworCisgICAgICAgIGlmICghbmF0aXZlRGVjbCAmJiAhaW50ZXJmYWNlRGVjbCAmJiAhaXNQb2ludGVyRnVuYykgeworICAgICAgICAgICAgLy8gSWYgaXQncyBub3QgYSBwb2ludGVyIGZ1bmN0aW9uLCB3ZSd2ZSBhbHJlYWR5IGVtaXR0ZWQgaXQKKyAgICAgICAgICAgIC8vIHdpdGggbmF0aXZlRGVjbCA9PSB0cnVlCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoaXNQb2ludGVyRnVuYykgeworICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgIChuYXRpdmVEZWNsID8gInByaXZhdGUgbmF0aXZlICIgOgorICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRlcmZhY2VEZWNsID8gIiIgOiAicHVibGljICIpKSArCisgICAgICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXRUeXBlKCkgKyAiICIgKworICAgICAgICAgICAgICAgICAgICAgICAgamZ1bmMuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAgIChuYXRpdmVEZWNsID8gIkJvdW5kcyIgOiAiIikgKworICAgICAgICAgICAgICAgICAgICAgICAgIigiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArCisgICAgICAgICAgICAgICAgICAgICAgICAobmF0aXZlRGVjbCA/ICJwdWJsaWMgbmF0aXZlICIgOgorICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRlcmZhY2VEZWNsID8gIiIgOiAicHVibGljICIpKSArCisgICAgICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXRUeXBlKCkgKyAiICIgKworICAgICAgICAgICAgICAgICAgICAgICAgamZ1bmMuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICIoIik7CisgICAgICAgIH0KKwkKKyAgICAgICAgaW50IG51bUFyZ3MgPSBqZnVuYy5nZXROdW1BcmdzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQXJnczsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgYXJnTmFtZSA9IGpmdW5jLmdldEFyZ05hbWUoaSk7CisgICAgICAgICAgICBKVHlwZSBhcmdUeXBlID0gamZ1bmMuZ2V0QXJnVHlwZShpKTsKKwkgICAgCisgICAgICAgICAgICBvdXQucHJpbnQoaW5kZW50ICsgaW5kZW50ICsgYXJnVHlwZSArICIgIiArIGFyZ05hbWUpOworICAgICAgICAgICAgaWYgKGkgPT0gbnVtQXJncyAtIDEpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNQb2ludGVyRnVuYyAmJiBuYXRpdmVEZWNsKSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIsIik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArIGluZGVudCArICJpbnQgcmVtYWluaW5nIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIsIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAobmF0aXZlRGVjbCB8fCBpbnRlcmZhY2VEZWNsKSB7CisgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAiKTsiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICIpIHsiKTsKKworICAgICAgICAgICAgU3RyaW5nIGlpaSA9IGluZGVudCArIGluZGVudDsKKworICAgICAgICAgICAgU3RyaW5nIGZuYW1lID0gamZ1bmMuZ2V0TmFtZSgpOworICAgICAgICAgICAgaWYgKGlzUG9pbnRlckZ1bmMpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPIC0gZGVhbCB3aXRoIFZCTyB2YXJpYW50cworICAgICAgICAgICAgICAgIGlmIChmbmFtZS5lcXVhbHMoImdsQ29sb3JQb2ludGVyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgImlmICgoc2l6ZSA9PSA0KSAmJiIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICgodHlwZSA9PSBHTF9GTE9BVCkgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHR5cGUgPT0gR0xfVU5TSUdORURfQllURSkgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHR5cGUgPT0gR0xfRklYRUQpKSAmJiIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgIChzdHJpZGUgPj0gMCkpIHsiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsgIl9jb2xvclBvaW50ZXIgPSBwb2ludGVyOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAifSIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm5hbWUuZXF1YWxzKCJnbE5vcm1hbFBvaW50ZXIiKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiaWYgKCgodHlwZSA9PSBHTF9GTE9BVCkgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHR5cGUgPT0gR0xfQllURSkgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHR5cGUgPT0gR0xfU0hPUlQpIHx8Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgICh0eXBlID09IEdMX0ZJWEVEKSkgJiYiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAoc3RyaWRlID49IDApKSB7Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArIGluZGVudCArICJfbm9ybWFsUG9pbnRlciA9IHBvaW50ZXI7Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICJ9Iik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmbmFtZS5lcXVhbHMoImdsVGV4Q29vcmRQb2ludGVyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgImlmICgoKHNpemUgPT0gMikgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHNpemUgPT0gMykgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHNpemUgPT0gNCkpICYmIik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgKCh0eXBlID09IEdMX0ZMT0FUKSB8fCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAodHlwZSA9PSBHTF9CWVRFKSB8fCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAodHlwZSA9PSBHTF9TSE9SVCkgfHwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAgKHR5cGUgPT0gR0xfRklYRUQpKSAmJiIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgIChzdHJpZGUgPj0gMCkpIHsiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgaW5kZW50ICsgIl90ZXhDb29yZFBvaW50ZXIgPSBwb2ludGVyOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAifSIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm5hbWUuZXF1YWxzKCJnbFZlcnRleFBvaW50ZXIiKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiaWYgKCgoc2l6ZSA9PSAyKSB8fCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAoc2l6ZSA9PSAzKSB8fCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAoc2l6ZSA9PSA0KSkgJiYiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaWlpICsgIiAgICAoKHR5cGUgPT0gR0xfRkxPQVQpIHx8Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgICh0eXBlID09IEdMX0JZVEUpIHx8Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgICh0eXBlID09IEdMX1NIT1JUKSB8fCIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAiICAgICAodHlwZSA9PSBHTF9GSVhFRCkpICYmIik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGlpaSArICIgICAgKHN0cmlkZSA+PSAwKSkgeyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyBpbmRlbnQgKyAiX3ZlcnRleFBvaW50ZXIgPSBwb2ludGVyOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpaWkgKyAifSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gZW1pdEJvdW5kc0NoZWNrcyhqZnVuYywgb3V0LCBpaWkpOworICAgICAgICAgICAgZW1pdEZ1bmN0aW9uQ2FsbChqZnVuYywgb3V0LCBpaWksIGZhbHNlKTsKKworICAgICAgICAgICAgYm9vbGVhbiBpc1ZvaWQgPSBqZnVuYy5nZXRUeXBlKCkuaXNWb2lkKCk7CisKKyAgICAgICAgICAgIGlmICghaXNWb2lkKSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgaW5kZW50ICsgInJldHVybiBfcmV0dXJuVmFsdWU7Iik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAifSIpOworICAgICAgICB9CisgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0Sm5pTmFtZShKVHlwZSBqVHlwZSkgeworICAgICAgICBTdHJpbmcgam5pTmFtZSA9ICIiOworICAgICAgICBpZiAoalR5cGUuaXNDbGFzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gIkwiICsgalR5cGUuZ2V0QmFzZVR5cGUoKSArICI7IjsKKyAgICAgICAgfSBlbHNlIGlmIChqVHlwZS5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgIGpuaU5hbWUgPSAiWyI7CisgICAgICAgIH0KKwkKKyAgICAgICAgU3RyaW5nIGJhc2VUeXBlID0galR5cGUuZ2V0QmFzZVR5cGUoKTsKKyAgICAgICAgaWYgKGJhc2VUeXBlLmVxdWFscygiaW50IikpIHsKKyAgICAgICAgICAgIGpuaU5hbWUgKz0gIkkiOworICAgICAgICB9IGVsc2UgaWYgKGJhc2VUeXBlLmVxdWFscygiZmxvYXQiKSkgeworICAgICAgICAgICAgam5pTmFtZSArPSAiRiI7CisgICAgICAgIH0gZWxzZSBpZiAoYmFzZVR5cGUuZXF1YWxzKCJib29sZWFuIikpIHsKKyAgICAgICAgICAgIGpuaU5hbWUgKz0gIloiOworICAgICAgICB9IGVsc2UgaWYgKGJhc2VUeXBlLmVxdWFscygic2hvcnQiKSkgeworICAgICAgICAgICAgam5pTmFtZSArPSAiUyI7CisgICAgICAgIH0gZWxzZSBpZiAoYmFzZVR5cGUuZXF1YWxzKCJsb25nIikpIHsKKyAgICAgICAgICAgIGpuaU5hbWUgKz0gIkwiOworICAgICAgICB9IGVsc2UgaWYgKGJhc2VUeXBlLmVxdWFscygiYnl0ZSIpKSB7CisgICAgICAgICAgICBqbmlOYW1lICs9ICJCIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gam5pTmFtZTsKKyAgICB9CisKKyAgICBTdHJpbmcgZ2V0Sm5pVHlwZShKVHlwZSBqVHlwZSkgeworICAgICAgICBpZiAoalR5cGUuaXNWb2lkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAidm9pZCI7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgYmFzZVR5cGUgPSBqVHlwZS5nZXRCYXNlVHlwZSgpOworICAgICAgICBpZiAoalR5cGUuaXNQcmltaXRpdmUoKSkgeworICAgICAgICAgICAgaWYgKGJhc2VUeXBlLmVxdWFscygiU3RyaW5nIikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gImpzdHJpbmciOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gImoiICsgYmFzZVR5cGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoalR5cGUuaXNBcnJheSgpKSB7CisgICAgICAgICAgICByZXR1cm4gImoiICsgYmFzZVR5cGUgKyAiQXJyYXkiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuICJqb2JqZWN0IjsKKyAgICAgICAgfQorICAgIH0KKyAgICAKKyAgICBTdHJpbmcgZ2V0Sm5pTWFuZ2xlZE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZUFsbCgiXyIsICJfMSIpOworICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlQWxsKCI7IiwgIl8yIik7CisgICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2VBbGwoIlxcWyIsICJfMyIpOworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbWl0Sm5pQ29kZShKRnVuYyBqZnVuYywgUHJpbnRTdHJlYW0gb3V0KSB7CisgICAgICAgIENGdW5jIGNmdW5jID0gamZ1bmMuZ2V0Q0Z1bmMoKTsKKwkKKyAgICAgICAgLy8gRW1pdCBjb21tZW50IGlkZW50aWZ5aW5nIG9yaWdpbmFsIEMgZnVuY3Rpb24KKyAgICAgICAgLy8KKyAgICAgICAgLy8gRXhhbXBsZToKKyAgICAgICAgLy8KKyAgICAgICAgLy8gLyogdm9pZCBnbENsaXBQbGFuZWYgKCBHTGVudW0gcGxhbmUsIGNvbnN0IEdMZmxvYXQgKmVxdWF0aW9uICkgKi8KKyAgICAgICAgLy8KKyAgICAgICAgb3V0LnByaW50bG4oIi8qICIgKyBjZnVuYy5nZXRPcmlnaW5hbCgpICsgIiAqLyIpOworCisgICAgICAgIC8vIEVtaXQgSk5JIHNpZ25hdHVyZSAobmFtZSkKKyAgICAgICAgLy8KKyAgICAgICAgLy8gRXhhbXBsZToKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdm9pZAorICAgICAgICAvLyBhbmRyb2lkX2dsQ2xpcFBsYW5lZl9fSV8zRkkKKyAgICAgICAgLy8KKworICAgICAgICBTdHJpbmcgb3V0TmFtZSA9ICJhbmRyb2lkXyIgKyBqZnVuYy5nZXROYW1lKCk7CisgICAgICAgIGJvb2xlYW4gaXNQb2ludGVyRnVuYyA9IG91dE5hbWUuZW5kc1dpdGgoIlBvaW50ZXIiKSAmJgorICAgICAgICAgICAgamZ1bmMuZ2V0Q0Z1bmMoKS5oYXNQb2ludGVyQXJnKCk7CisgICAgICAgIGJvb2xlYW4gaXNWQk9Qb2ludGVyRnVuYyA9IChvdXROYW1lLmVuZHNXaXRoKCJQb2ludGVyIikgfHwKKyAgICAgICAgICAgIG91dE5hbWUuZW5kc1dpdGgoIkRyYXdFbGVtZW50cyIpKSAmJgorICAgICAgICAgICAgIWpmdW5jLmdldENGdW5jKCkuaGFzUG9pbnRlckFyZygpOworICAgICAgICBpZiAoaXNQb2ludGVyRnVuYykgeworICAgICAgICAgICAgb3V0TmFtZSArPSAiQm91bmRzIjsKKyAgICAgICAgfQorCisgICAgICAgIG91dC5wcmludCgic3RhdGljICIpOworICAgICAgICBvdXQucHJpbnRsbihnZXRKbmlUeXBlKGpmdW5jLmdldFR5cGUoKSkpOworICAgICAgICBvdXQucHJpbnQob3V0TmFtZSk7CisKKyAgICAgICAgU3RyaW5nIHJzaWduYXR1cmUgPSBnZXRKbmlOYW1lKGpmdW5jLmdldFR5cGUoKSk7CisKKyAgICAgICAgU3RyaW5nIHNpZ25hdHVyZSA9ICIiOworICAgICAgICBpbnQgbnVtQXJncyA9IGpmdW5jLmdldE51bUFyZ3MoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1BcmdzOyBpKyspIHsKKyAgICAgICAgICAgIEpUeXBlIGFyZ1R5cGUgPSBqZnVuYy5nZXRBcmdUeXBlKGkpOworICAgICAgICAgICAgc2lnbmF0dXJlICs9IGdldEpuaU5hbWUoYXJnVHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzUG9pbnRlckZ1bmMpIHsKKyAgICAgICAgICAgIHNpZ25hdHVyZSArPSAiSSI7CisgICAgICAgIH0KKworICAgICAgICAvLyBBcHBlbmQgc2lnbmF0dXJlIHRvIGZ1bmN0aW9uIG5hbWUKKyAgICAgICAgU3RyaW5nIHNpZyA9IGdldEpuaU1hbmdsZWROYW1lKHNpZ25hdHVyZSkucmVwbGFjZSgnLicsICdfJyk7ICAgICAgICAKKyAgICAgICAgb3V0LnByaW50KCJfXyIgKyBzaWcpOworICAgICAgICBvdXROYW1lICs9ICJfXyIgKyBzaWc7CisJCisgICAgICAgIHNpZ25hdHVyZSA9IHNpZ25hdHVyZS5yZXBsYWNlKCcuJywgJy8nKTsKKyAgICAgICAgcnNpZ25hdHVyZSA9IHJzaWduYXR1cmUucmVwbGFjZSgnLicsICcvJyk7CisJCisgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgICAgIGlmIChyc2lnbmF0dXJlLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJzaWduYXR1cmUgPSAiViI7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcyA9ICJ7XCIiICsKKyAgICAgICAgICAgIGpmdW5jLmdldE5hbWUoKSArCisgICAgICAgICAgICAoaXNQb2ludGVyRnVuYyA/ICJCb3VuZHMiIDogIiIpICsKKyAgICAgICAgICAgICJcIiwgXCIoIiArIHNpZ25hdHVyZSArIikiICsKKyAgICAgICAgICAgIHJzaWduYXR1cmUgKworICAgICAgICAgICAgIlwiLCAodm9pZCAqKSAiICsKKyAgICAgICAgICAgIG91dE5hbWUgKworICAgICAgICAgICAgIiB9LCI7CisgICAgICAgIG5hdGl2ZVJlZ2lzdHJhdGlvbnMuYWRkKHMpOworCisgICAgICAgIExpc3Q8SW50ZWdlcj4gbm9uUHJpbWl0aXZlQXJncyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKKyAgICAgICAgaW50IG51bUJ1ZmZlckFyZ3MgPSAwOworICAgICAgICBMaXN0PFN0cmluZz4gYnVmZmVyQXJnTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICAvLyBFbWl0IEpOSSBzaWduYXR1cmUgKGFyZ3VtZW50cykKKyAgICAgICAgLy8KKyAgICAgICAgLy8gRXhhbXBsZToKKyAgICAgICAgLy8KKyAgICAgICAgLy8gKEpOSUVudiAqX2Vudiwgam9iamVjdCB0aGlzLCBqaW50IHBsYW5lLCBqZmxvYXRBcnJheSBlcXVhdGlvbl9yZWYsIGppbnQgb2Zmc2V0KSB7CisgICAgICAgIC8vCisgICAgICAgIG91dC5wcmludCgiICAoSk5JRW52ICpfZW52LCBqb2JqZWN0IF90aGlzIik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQXJnczsgaSsrKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoIiwgIik7CisgICAgICAgICAgICBKVHlwZSBhcmdUeXBlID0gamZ1bmMuZ2V0QXJnVHlwZShpKTsKKyAgICAgICAgICAgIFN0cmluZyBzdWZmaXg7CisgICAgICAgICAgICBpZiAoIWFyZ1R5cGUuaXNQcmltaXRpdmUoKSkgeworICAgICAgICAgICAgICAgIGlmIChhcmdUeXBlLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgICAgICAgICBzdWZmaXggPSAiX3JlZiI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc3VmZml4ID0gIl9idWYiOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBub25QcmltaXRpdmVBcmdzLmFkZChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaSkuaXNCdWZmZXIoKSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgY0luZGV4ID0gamZ1bmMuZ2V0QXJnQ0luZGV4KGkpOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBjZnVuYy5nZXRBcmdOYW1lKGNJbmRleCk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlckFyZ05hbWVzLmFkZChjbmFtZSk7CisgICAgICAgICAgICAgICAgICAgIG51bUJ1ZmZlckFyZ3MrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN1ZmZpeCA9ICIiOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBvdXQucHJpbnQoZ2V0Sm5pVHlwZShhcmdUeXBlKSArICIgIiArIGpmdW5jLmdldEFyZ05hbWUoaSkgKyBzdWZmaXgpOworICAgICAgICB9CisgICAgICAgIGlmIChpc1BvaW50ZXJGdW5jKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoIiwgamludCByZW1haW5pbmciKTsKKyAgICAgICAgfQorICAgICAgICBvdXQucHJpbnRsbigiKSB7Iik7CisJCisgICAgICAgIGludCBudW1BcnJheXMgPSAwOworICAgICAgICBpbnQgbnVtQnVmZmVycyA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9uUHJpbWl0aXZlQXJncy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgaW50IGlkeCA9IG5vblByaW1pdGl2ZUFyZ3MuZ2V0KGkpLmludFZhbHVlKCk7CisgICAgICAgICAgICBpbnQgY0luZGV4ID0gamZ1bmMuZ2V0QXJnQ0luZGV4KGlkeCk7CisgICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBjZnVuYy5nZXRBcmdOYW1lKGNJbmRleCk7CisgICAgICAgICAgICBpZiAoamZ1bmMuZ2V0QXJnVHlwZShpZHgpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgICAgICsrbnVtQXJyYXlzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaWR4KS5pc0J1ZmZlcigpKSB7CisgICAgICAgICAgICAgICAgKytudW1CdWZmZXJzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gRW1pdCBtZXRob2QgYm9keQorCisgICAgICAgIC8vIEVtaXQgbG9jYWwgdmFyaWFibGUgZGVjbGFyYXRpb25zIGZvciBfZXhjZXB0aW9uIGFuZCBfcmV0dXJuVmFsdWUKKyAgICAgICAgLy8KKyAgICAgICAgLy8gRXhhbXBsZToKKyAgICAgICAgLy8KKyAgICAgICAgLy8gYW5kcm9pZDo6Z2w6Om9nbGVzX2NvbnRleHRfdCAqY3R4OworICAgICAgICAvLyAKKyAgICAgICAgLy8gamludCBfZXhjZXB0aW9uOworICAgICAgICAvLyBHTGVudW0gX3JldHVyblZhbHVlOworICAgICAgICAvLworICAgICAgICBDVHlwZSByZXR1cm5UeXBlID0gY2Z1bmMuZ2V0VHlwZSgpOworICAgICAgICBib29sZWFuIGlzVm9pZCA9IHJldHVyblR5cGUuaXNWb2lkKCk7CisKKyAgICAgICAgYm9vbGVhbiBpc1Vuc3VwcG9ydGVkID0gaXNVbnN1cHBvcnRlZEZ1bmMoY2Z1bmMpOworICAgICAgICBpZiAoaXNVbnN1cHBvcnRlZCkgeworICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJfZW52LT5UaHJvd05ldyhVT0VDbGFzcywiKTsKKyAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArCisgICAgICAgICAgICAgICAgICAgICAgICAiICAgIFwiIiArIGNmdW5jLmdldE5hbWUoKSArICJcIik7Iik7CisgICAgICAgICAgICBpZiAoIWlzVm9pZCkgeworICAgICAgICAgICAgICAgIFN0cmluZyByZXR2YWwgPSBnZXRFcnJvclJldHVyblZhbHVlKGNmdW5jKTsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAicmV0dXJuICIgKyByZXR2YWwgKyAiOyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb3V0LnByaW50bG4oIn0iKTsKKyAgICAgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAobVVzZUNvbnRleHRQb2ludGVyKSB7CisgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICJhbmRyb2lkOjpnbDo6b2dsZXNfY29udGV4dF90ICpjdHggPSBnZXRDb250ZXh0KF9lbnYsIF90aGlzKTsiKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZW1pdEV4Y2VwdGlvbkNoZWNrID0gKG51bUFycmF5cyA+IDAgfHwgbnVtQnVmZmVycyA+IDApICYmCisgICAgICAgICAgICBoYXNOb25Db25zdEFyZyhqZnVuYywgY2Z1bmMsIG5vblByaW1pdGl2ZUFyZ3MpOworICAgICAgICAvLyBtQ2hlY2tlci5nZXRDaGVja3MoY2Z1bmMuZ2V0TmFtZSgpKSAhPSBudWxsCisKKyAgICAgICAgLy8gRW1pdCBhbiBfZXhlcHRpb24gdmFyaWFibGUgaWYgdGhlcmUgd2lsbCBiZSBlcnJvciBjaGVja3MKKyAgICAgICAgaWYgKGVtaXRFeGNlcHRpb25DaGVjaykgeworICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgImppbnQgX2V4Y2VwdGlvbiA9IDA7Iik7CisgICAgICAgIH0KKworICAgICAgICAvLyBFbWl0IGEgc2luZ2xlIF9hcnJheSBvciBtdWx0aXBsZSBfWFhYQXJyYXkgdmFyaWFibGVzCisgICAgICAgIGlmIChudW1CdWZmZXJBcmdzID09IDEpIHsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAiamFycmF5IF9hcnJheSA9IChqYXJyYXkpIDA7Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUJ1ZmZlckFyZ3M7IGkrKykgeworICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICJqYXJyYXkgXyIgKyBidWZmZXJBcmdOYW1lcy5nZXQoaSkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcnJheSA9IChqYXJyYXkpIDA7Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFpc1ZvaWQpIHsKKyAgICAgICAgICAgIFN0cmluZyByZXR2YWwgPSBnZXRFcnJvclJldHVyblZhbHVlKGNmdW5jKTsKKyAgICAgICAgICAgIGlmIChyZXR2YWwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArIHJldHVyblR5cGUuZ2V0RGVjbGFyYXRpb24oKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBfcmV0dXJuVmFsdWUgPSAiICsgcmV0dmFsICsgIjsiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgcmV0dXJuVHlwZS5nZXREZWNsYXJhdGlvbigpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIF9yZXR1cm5WYWx1ZTsiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEVtaXQgbG9jYWwgdmFyaWFibGUgZGVjbGFyYXRpb25zIGZvciBwb2ludGVyIGFyZ3VtZW50cworICAgICAgICAvLworICAgICAgICAvLyBFeGFtcGxlOgorICAgICAgICAvLworICAgICAgICAvLyBHTGZpeGVkICplcW5fYmFzZTsKKyAgICAgICAgLy8gR0xmaXhlZCAqZXFuOworICAgICAgICAvLworICAgICAgICBTdHJpbmcgb2Zmc2V0ID0gIm9mZnNldCI7CisgICAgICAgIFN0cmluZyByZW1haW5pbmcgPSAiX3JlbWFpbmluZyI7CisgICAgICAgIGlmIChub25QcmltaXRpdmVBcmdzLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9uUHJpbWl0aXZlQXJncy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGludCBpZHggPSBub25QcmltaXRpdmVBcmdzLmdldChpKS5pbnRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGludCBjSW5kZXggPSBqZnVuYy5nZXRBcmdDSW5kZXgoaWR4KTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBjZnVuYy5nZXRBcmdOYW1lKGNJbmRleCk7CisKKyAgICAgICAgICAgICAgICBDVHlwZSB0eXBlID0gY2Z1bmMuZ2V0QXJnVHlwZShqZnVuYy5nZXRBcmdDSW5kZXgoaWR4KSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRlY2wgPSB0eXBlLmdldERlY2xhcmF0aW9uKCk7CisgICAgICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaWR4KS5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjbCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNsLmVuZHNXaXRoKCIqIikgPyAiIiA6ICIgIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXRBcmdOYW1lKGlkeCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX2Jhc2UgPSAoIiArIGRlY2wgKyAiKSAwOyIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZW1haW5pbmcgPSAobnVtQXJyYXlzIDw9IDEgJiYgbnVtQnVmZmVycyA8PSAxKSA/ICJfcmVtYWluaW5nIiA6CisgICAgICAgICAgICAgICAgICAgICJfIiArIGNuYW1lICsgIlJlbWFpbmluZyI7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamludCAiICsgcmVtYWluaW5nICsgIjsiKTsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2wgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNsLmVuZHNXaXRoKCIqIikgPyAiIiA6ICIgIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpmdW5jLmdldEFyZ05hbWUoaWR4KSArIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgPSAoIiArIGRlY2wgKyAiKSAwOyIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBvdXQucHJpbnRsbigpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJldHZhbCA9IGlzVm9pZCA/ICIiIDogIiBfcmV0dXJuVmFsdWUiOworCisgICAgICAgIC8vIEVtaXQgJ0dldFByaW1pdGl2ZUFycmF5Q3JpdGljYWwnIGZvciBhcnJheXMKKyAgICAgICAgLy8gRW1pdCAnR2V0UG9pbnRlcicgY2FsbHMgZm9yIEJ1ZmZlciBwb2ludGVycworICAgICAgICBpbnQgYnVmQXJnSWR4ID0gMDsKKyAgICAgICAgaWYgKG5vblByaW1pdGl2ZUFyZ3Muc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBub25QcmltaXRpdmVBcmdzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGlkeCA9IG5vblByaW1pdGl2ZUFyZ3MuZ2V0KGkpLmludFZhbHVlKCk7CisgICAgICAgICAgICAgICAgaW50IGNJbmRleCA9IGpmdW5jLmdldEFyZ0NJbmRleChpZHgpOworCQkKKyAgICAgICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBjZnVuYy5nZXRBcmdOYW1lKGNJbmRleCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnVtQXJyYXlzIDw9IDEgPyAib2Zmc2V0IiA6CisgICAgICAgICAgICAgICAgICAgIGNuYW1lICsgIk9mZnNldCI7CisgICAgICAgICAgICAgICAgcmVtYWluaW5nID0gKG51bUFycmF5cyA8PSAxICYmIG51bUJ1ZmZlcnMgPD0gMSkgPyAiX3JlbWFpbmluZyIgOgorICAgICAgICAgICAgICAgICAgICAiXyIgKyBjbmFtZSArICJSZW1haW5pbmciOworCisgICAgICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaWR4KS5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlmICghIiArIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfcmVmKSB7Iik7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbWl0RXhjZXB0aW9uQ2hlY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArIGluZGVudCArICJfZXhjZXB0aW9uID0gMTsiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAiICAgICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICJfZW52IiA6ICIoKl9lbnYpIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLT5UaHJvd05ldygiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1Vc2VDUGx1c1BsdXMgPyAiIiA6ICJfZW52LCAiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJQUVDbGFzcywgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiIgKyBjbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgPT0gbnVsbFwiKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgIiAgICBnb3RvIGV4aXQ7Iik7CisgICAgICAgICAgICAgICAgICAgIG5lZWRzRXhpdCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICJ9Iik7CisKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgImlmICgiICsgb2Zmc2V0ICsgIiA8IDApIHsiKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVtaXRFeGNlcHRpb25DaGVjaykgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgaW5kZW50ICsgIl9leGNlcHRpb24gPSAxOyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICIgICAgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtVXNlQ1BsdXNQbHVzID8gIl9lbnYiIDogIigqX2VudikiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItPlRocm93TmV3KCIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICIiIDogIl9lbnYsICIpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklBRUNsYXNzLCAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIiArIG9mZnNldCArICIgPCAwXCIpOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAiICAgIGdvdG8gZXhpdDsiKTsKKyAgICAgICAgICAgICAgICAgICAgbmVlZHNFeGl0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgIn0iKTsKKworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyByZW1haW5pbmcgKyAiID0gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICJfZW52IiA6ICIoKl9lbnYpIikgKyAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItPkdldEFycmF5TGVuZ3RoKCIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1Vc2VDUGx1c1BsdXMgPyAiIiA6ICJfZW52LCAiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbmFtZSArICJfcmVmKSAtICIgKyBvZmZzZXQgKyAiOyIpOworCisgICAgICAgICAgICAgICAgICAgIGVtaXROYXRpdmVCb3VuZHNDaGVja3MoY2Z1bmMsIGNuYW1lLCBvdXQsIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRFeGNlcHRpb25DaGVjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQsIHJlbWFpbmluZywgIiAgICAiKTsKKworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfYmFzZSA9ICgiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2Z1bmMuZ2V0QXJnVHlwZShjSW5kZXgpLmdldERlY2xhcmF0aW9uKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKSIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAiICAgICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICJfZW52IiA6ICIoKl9lbnYpIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLT5HZXRQcmltaXRpdmVBcnJheUNyaXRpY2FsKCIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICIiIDogIl9lbnYsICIpICsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpmdW5jLmdldEFyZ05hbWUoaWR4KSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfcmVmLCAoamJvb2xlYW4gKikwKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY25hbWUgKyAiID0gIiArIGNuYW1lICsgIl9iYXNlICsgIiArIG9mZnNldCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7Iik7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFycmF5ID0gbnVtQnVmZmVyQXJncyA8PSAxID8gIl9hcnJheSIgOgorICAgICAgICAgICAgICAgICAgICAgICAgIl8iICsgYnVmZmVyQXJnTmFtZXMuZ2V0KGJ1ZkFyZ0lkeCsrKSArICJBcnJheSI7CisKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBudWxsQWxsb3dlZCA9IGlzTnVsbEFsbG93ZWQoY2Z1bmMpOworICAgICAgICAgICAgICAgICAgICBpZiAobnVsbEFsbG93ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICJpZiAoIiArIGNuYW1lICsgIl9idWYpIHsiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludChpbmRlbnQpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgPSAoIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmdW5jLmdldEFyZ1R5cGUoY0luZGV4KS5nZXREZWNsYXJhdGlvbigpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIilnZXRQb2ludGVyKF9lbnYsICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfYnVmLCAmIiArIGFycmF5ICsgIiwgJiIgKyByZW1haW5pbmcgKyAiKTsiKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAobnVsbEFsbG93ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICJ9Iik7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBlbWl0TmF0aXZlQm91bmRzQ2hlY2tzKGNmdW5jLCBjbmFtZSwgb3V0LCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRFeGNlcHRpb25DaGVjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQsIHJlbWFpbmluZywgIiAgICAiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzVm9pZCkgeworICAgICAgICAgICAgb3V0LnByaW50KGluZGVudCArICJfcmV0dXJuVmFsdWUgPSAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dC5wcmludChpbmRlbnQpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBuYW1lID0gY2Z1bmMuZ2V0TmFtZSgpOworCisgICAgICAgIGlmIChtVXNlQ29udGV4dFBvaW50ZXIpIHsKKyAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygyLCBuYW1lLmxlbmd0aCgpKTsgLy8gU3RyaXAgb2ZmICdnbCcgcHJlZml4CisgICAgICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMCwgMSkudG9Mb3dlckNhc2UoKSArCisgICAgICAgICAgICAgICAgbmFtZS5zdWJzdHJpbmcoMSwgbmFtZS5sZW5ndGgoKSk7CisgICAgICAgICAgICBvdXQucHJpbnQoImN0eC0+cHJvY3MuIik7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIG91dC5wcmludChuYW1lICsgKGlzUG9pbnRlckZ1bmMgPyAiQm91bmRzIiA6ICIiKSArICIoIik7CisKKyAgICAgICAgbnVtQXJncyA9IGNmdW5jLmdldE51bUFyZ3MoKTsgICAgCisgICAgICAgIGlmIChudW1BcmdzID09IDApIHsKKyAgICAgICAgICAgIGlmIChtVXNlQ29udGV4dFBvaW50ZXIpIHsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiY3R4KTsiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIik7Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAobVVzZUNvbnRleHRQb2ludGVyKSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oImN0eCwiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQXJnczsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGVjYXN0OworICAgICAgICAgICAgICAgIGlmIChpID09IG51bUFyZ3MgLSAxICYmIGlzVkJPUG9pbnRlckZ1bmMpIHsKKyAgICAgICAgICAgICAgICAgICAgdHlwZWNhc3QgPSAiY29uc3QgR0x2b2lkICoiOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHR5cGVjYXN0ID0gY2Z1bmMuZ2V0QXJnVHlwZShpKS5nZXREZWNsYXJhdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvdXQucHJpbnQoaW5kZW50ICsgaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWNhc3QgKworICAgICAgICAgICAgICAgICAgICAgICAgICAiKSIgKworICAgICAgICAgICAgICAgICAgICAgICAgICBjZnVuYy5nZXRBcmdOYW1lKGkpKTsKKworICAgICAgICAgICAgICAgIGlmIChpID09IG51bUFyZ3MgLSAxKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc1BvaW50ZXJGdW5jKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiLCIpOworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgaW5kZW50ICsgIihHTHNpemVpKXJlbWFpbmluZyIpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIsIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgIik7Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmVlZHNFeGl0KSB7CisgICAgICAgICAgICBvdXQucHJpbnRsbigpOworICAgICAgICAgICAgb3V0LnByaW50bG4oImV4aXQ6Iik7CisgICAgICAgICAgICBuZWVkc0V4aXQgPSBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJ1ZkFyZ0lkeCA9IDA7CisgICAgICAgIGlmIChub25QcmltaXRpdmVBcmdzLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBub25QcmltaXRpdmVBcmdzLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgaW50IGlkeCA9IG5vblByaW1pdGl2ZUFyZ3MuZ2V0KGkpLmludFZhbHVlKCk7CisKKyAgICAgICAgICAgICAgICBpbnQgY0luZGV4ID0gamZ1bmMuZ2V0QXJnQ0luZGV4KGlkeCk7CisgICAgICAgICAgICAgICAgaWYgKGpmdW5jLmdldEFyZ1R5cGUoaWR4KS5pc0FycmF5KCkpIHsKKwkJICAgIAorICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgYXJndW1lbnQgaXMgJ2NvbnN0JywgR0wgd2lsbCBub3Qgd3JpdGUgdG8gaXQuCisgICAgICAgICAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgd2UgY2FuIHVzZSB0aGUgJ0pOSV9BQk9SVCcgZmxhZyB0byBhdm9pZAorICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbmVlZCB0byB3cml0ZSBiYWNrIHRvIHRoZSBKYXZhIGFycmF5CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpZiAoIiArIGpmdW5jLmdldEFyZ05hbWUoaWR4KSArICJfYmFzZSkgeyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyBpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobVVzZUNQbHVzUGx1cyA/ICJfZW52IiA6ICIoKl9lbnYpIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLT5SZWxlYXNlUHJpbWl0aXZlQXJyYXlDcml0aWNhbCgiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1Vc2VDUGx1c1BsdXMgPyAiIiA6ICJfZW52LCAiKSArIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqZnVuYy5nZXRBcmdOYW1lKGlkeCkgKyAiX3JlZiwgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmdW5jLmdldEFyZ05hbWUoY0luZGV4KSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfYmFzZSwiKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oaW5kZW50ICsgaW5kZW50ICsgaW5kZW50ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNmdW5jLmdldEFyZ1R5cGUoY0luZGV4KS5pc0NvbnN0KCkgPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkpOSV9BQk9SVCIgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl9leGNlcHRpb24gPyBKTklfQUJPUlQ6IDAiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIpOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAifSIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoamZ1bmMuZ2V0QXJnVHlwZShpZHgpLmlzQnVmZmVyKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFycmF5ID0gbnVtQnVmZmVyQXJncyA8PSAxID8gIl9hcnJheSIgOgorICAgICAgICAgICAgICAgICAgICAgICAgIl8iICsgYnVmZmVyQXJnTmFtZXMuZ2V0KGJ1ZkFyZ0lkeCsrKSArICJBcnJheSI7CisgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGluZGVudCArICJpZiAoIiArIGFycmF5ICsgIikgeyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyBpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVsZWFzZVBvaW50ZXIoX2VudiwgIiArIGFycmF5ICsgIiwgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmdW5jLmdldEFyZ05hbWUoY0luZGV4KSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2Z1bmMuZ2V0QXJnVHlwZShjSW5kZXgpLmlzQ29uc3QoKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSk5JX0ZBTFNFIiA6ICJfZXhjZXB0aW9uID8gSk5JX0ZBTFNFIDogSk5JX1RSVUUiKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIpOyIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAifSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICghaXNWb2lkKSB7CisgICAgICAgICAgICBvdXQucHJpbnRsbihpbmRlbnQgKyAicmV0dXJuIF9yZXR1cm5WYWx1ZTsiKTsKKyAgICAgICAgfQorCisgICAgICAgIG91dC5wcmludGxuKCJ9Iik7CisgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkTmF0aXZlUmVnaXN0cmF0aW9uKFN0cmluZyBzKSB7CisgICAgICAgIG5hdGl2ZVJlZ2lzdHJhdGlvbnMuYWRkKHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVtaXROYXRpdmVSZWdpc3RyYXRpb24oKSB7CisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oInN0YXRpYyBjb25zdCBjaGFyICpjbGFzc1BhdGhOYW1lID0gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1DbGFzc1BhdGhOYW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJcIjsiKTsKKyAgICAgICAgbUNTdHJlYW0ucHJpbnRsbigpOworCisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oInN0YXRpYyBKTklOYXRpdmVNZXRob2QgbWV0aG9kc1tdID0geyIpOworCisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oIntcIl9uYXRpdmVDbGFzc0luaXRcIiwgXCIoKVZcIiwgKHZvaWQqKW5hdGl2ZUNsYXNzSW5pdCB9LCIpOworCisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaSA9IG5hdGl2ZVJlZ2lzdHJhdGlvbnMuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBtQ1N0cmVhbS5wcmludGxuKGkubmV4dCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oIn07Iik7CisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oKTsKKyAgICAKKworICAgICAgICBtQ1N0cmVhbS5wcmludGxuKCJpbnQgcmVnaXN0ZXJfY29tX2dvb2dsZV9hbmRyb2lkX2dsZXNfam5pX0dMSW1wbChKTklFbnYgKl9lbnYpIik7CisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oInsiKTsKKyAgICAgICAgbUNTdHJlYW0ucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgImludCBlcnI7Iik7CisKKyAgICAgICAgbUNTdHJlYW0ucHJpbnRsbihpbmRlbnQgKworICAgICAgICAgICAgICAgICAgICAgICAgImVyciA9IGFuZHJvaWQ6OkFuZHJvaWRSdW50aW1lOjpyZWdpc3Rlck5hdGl2ZU1ldGhvZHMoX2VudiwgY2xhc3NQYXRoTmFtZSwgbWV0aG9kcywgTkVMRU0obWV0aG9kcykpOyIpOworCisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oaW5kZW50ICsgInJldHVybiBlcnI7Iik7CisgICAgICAgIG1DU3RyZWFtLnByaW50bG4oIn0iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL1BhcmFtZXRlckNoZWNrZXIuamF2YSBiL29wZW5nbC90b29scy9nbGdlbi9zcmMvUGFyYW1ldGVyQ2hlY2tlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmMjZhY2QKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3JjL1BhcmFtZXRlckNoZWNrZXIuamF2YQpAQCAtMCwwICsxLDI4IEBACisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworCitwdWJsaWMgY2xhc3MgUGFyYW1ldGVyQ2hlY2tlciB7CisKKyAgICBIYXNoTWFwPFN0cmluZyxTdHJpbmdbXT4gbWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLFN0cmluZ1tdPigpOworCisgICAgcHVibGljIFBhcmFtZXRlckNoZWNrZXIoQnVmZmVyZWRSZWFkZXIgcmVhZGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHM7CisgICAgICAgIHdoaWxlICgocyA9IHJlYWRlci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmdbXSB0b2tlbnMgPSBzLnNwbGl0KCJcXHMiKTsKKyAgICAgICAgICAgIG1hcC5wdXQodG9rZW5zWzBdLCB0b2tlbnMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldENoZWNrcyhTdHJpbmcgZnVuY3Rpb25OYW1lKSB7CisgICAgICAgIFN0cmluZ1tdIGNoZWNrcyA9IG1hcC5nZXQoZnVuY3Rpb25OYW1lKTsKKyAgICAgICAgaWYgKGNoZWNrcyA9PSBudWxsICYmCisgICAgICAgICAgICAoZnVuY3Rpb25OYW1lLmVuZHNXaXRoKCJmdiIpIHx8CisgICAgICAgICAgICAgZnVuY3Rpb25OYW1lLmVuZHNXaXRoKCJ4diIpIHx8CisgICAgICAgICAgICAgZnVuY3Rpb25OYW1lLmVuZHNXaXRoKCJpdiIpKSkgeworICAgICAgICAgICAgZnVuY3Rpb25OYW1lID0gZnVuY3Rpb25OYW1lLnN1YnN0cmluZygwLCBmdW5jdGlvbk5hbWUubGVuZ3RoKCkgLSAyKTsKKyAgICAgICAgICAgIGNoZWNrcyA9IG1hcC5nZXQoZnVuY3Rpb25OYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2hlY2tzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDEwRXh0SGVhZGVyLmphdmEtaWYgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMEV4dEhlYWRlci5qYXZhLWlmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwOTk5YzIKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMEV4dEhlYWRlci5qYXZhLWlmCkBAIC0wLDAgKzEsMjIgQEAKKyoqCisqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisvLyBUaGlzIHNvdXJjZSBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkCisKK3BhY2thZ2UgamF2YXgubWljcm9lZGl0aW9uLmtocm9ub3Mub3BlbmdsZXM7CisKK3B1YmxpYyBpbnRlcmZhY2UgR0wxMEV4dCBleHRlbmRzIEdMIHsKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTBIZWFkZXIuamF2YS1pZiBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDEwSGVhZGVyLmphdmEtaWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM5MjgyMQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDEwSGVhZGVyLmphdmEtaWYKQEAgLTAsMCArMSwyNTkgQEAKKyoqCisqKiBDb3B5cmlnaHQgMjAwNiwgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisvLyBUaGlzIHNvdXJjZSBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkCisKK3BhY2thZ2UgamF2YXgubWljcm9lZGl0aW9uLmtocm9ub3Mub3BlbmdsZXM7CisKK3B1YmxpYyBpbnRlcmZhY2UgR0wxMCBleHRlbmRzIEdMIHsKKyAgICBpbnQgR0xfQUREICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDEwNDsKKyAgICBpbnQgR0xfQUxJQVNFRF9MSU5FX1dJRFRIX1JBTkdFICAgICAgICAgICAgICA9IDB4ODQ2RTsKKyAgICBpbnQgR0xfQUxJQVNFRF9QT0lOVF9TSVpFX1JBTkdFICAgICAgICAgICAgICA9IDB4ODQ2RDsKKyAgICBpbnQgR0xfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTkwNjsKKyAgICBpbnQgR0xfQUxQSEFfQklUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1NTsKKyAgICBpbnQgR0xfQUxQSEFfVEVTVCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJDMDsKKyAgICBpbnQgR0xfQUxXQVlTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDIwNzsKKyAgICBpbnQgR0xfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwMDsKKyAgICBpbnQgR0xfQU1CSUVOVF9BTkRfRElGRlVTRSAgICAgICAgICAgICAgICAgICA9IDB4MTYwMjsKKyAgICBpbnQgR0xfQU5EICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwMTsKKyAgICBpbnQgR0xfQU5EX0lOVkVSVEVEICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwNDsKKyAgICBpbnQgR0xfQU5EX1JFVkVSU0UgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwMjsKKyAgICBpbnQgR0xfQkFDSyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDQwNTsKKyAgICBpbnQgR0xfQkxFTkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJFMjsKKyAgICBpbnQgR0xfQkxVRV9CSVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1NDsKKyAgICBpbnQgR0xfQllURSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTQwMDsKKyAgICBpbnQgR0xfQ0NXICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDkwMTsKKyAgICBpbnQgR0xfQ0xBTVBfVE9fRURHRSAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODEyRjsKKyAgICBpbnQgR0xfQ0xFQVIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwMDsKKyAgICBpbnQgR0xfQ09MT1JfQVJSQVkgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODA3NjsKKyAgICBpbnQgR0xfQ09MT1JfQlVGRkVSX0JJVCAgICAgICAgICAgICAgICAgICAgICA9IDB4NDAwMDsKKyAgICBpbnQgR0xfQ09MT1JfTE9HSUNfT1AgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJGMjsKKyAgICBpbnQgR0xfQ09MT1JfTUFURVJJQUwgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI1NzsKKyAgICBpbnQgR0xfQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFMgICAgICAgICAgICA9IDB4ODZBMzsKKyAgICBpbnQgR0xfQ09OU1RBTlRfQVRURU5VQVRJT04gICAgICAgICAgICAgICAgICA9IDB4MTIwNzsKKyAgICBpbnQgR0xfQ09QWSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwMzsKKyAgICBpbnQgR0xfQ09QWV9JTlZFUlRFRCAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwQzsKKyAgICBpbnQgR0xfQ1VMTF9GQUNFICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI0NDsKKyAgICBpbnQgR0xfQ1cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDkwMDsKKyAgICBpbnQgR0xfREVDQUwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MjEwMTsKKyAgICBpbnQgR0xfREVDUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MUUwMzsKKyAgICBpbnQgR0xfREVQVEhfQklUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1NjsKKyAgICBpbnQgR0xfREVQVEhfQlVGRkVSX0JJVCAgICAgICAgICAgICAgICAgICAgICA9IDB4MDEwMDsKKyAgICBpbnQgR0xfREVQVEhfVEVTVCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI3MTsKKyAgICBpbnQgR0xfRElGRlVTRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwMTsKKyAgICBpbnQgR0xfRElUSEVSICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJEMDsKKyAgICBpbnQgR0xfRE9OVF9DQVJFICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTEwMDsKKyAgICBpbnQgR0xfRFNUX0FMUEhBICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDMwNDsKKyAgICBpbnQgR0xfRFNUX0NPTE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDMwNjsKKyAgICBpbnQgR0xfRU1JU1NJT04gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTYwMDsKKyAgICBpbnQgR0xfRVFVQUwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDIwMjsKKyAgICBpbnQgR0xfRVFVSVYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwOTsKKyAgICBpbnQgR0xfRVhQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDgwMDsKKyAgICBpbnQgR0xfRVhQMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDgwMTsKKyAgICBpbnQgR0xfRVhURU5TSU9OUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MUYwMzsKKyAgICBpbnQgR0xfRkFMU0UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDA7CisgICAgaW50IEdMX0ZBU1RFU1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDExMDE7CisgICAgaW50IEdMX0ZJWEVEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE0MEM7CisgICAgaW50IEdMX0ZMQVQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDFEMDA7CisgICAgaW50IEdMX0ZMT0FUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE0MDY7CisgICAgaW50IEdMX0ZPRyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjA7CisgICAgaW50IEdMX0ZPR19DT0xPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjY7CisgICAgaW50IEdMX0ZPR19ERU5TSVRZICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjI7CisgICAgaW50IEdMX0ZPR19FTkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjQ7CisgICAgaW50IEdMX0ZPR19ISU5UICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBDNTQ7CisgICAgaW50IEdMX0ZPR19NT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjU7CisgICAgaW50IEdMX0ZPR19TVEFSVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNjM7CisgICAgaW50IEdMX0ZST05UICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA0MDQ7CisgICAgaW50IEdMX0ZST05UX0FORF9CQUNLICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA0MDg7CisgICAgaW50IEdMX0dFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAyMDY7CisgICAgaW50IEdMX0dSRUFURVIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAyMDQ7CisgICAgaW50IEdMX0dSRUVOX0JJVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBENTM7CisgICAgaW50IEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfRk9STUFUX09FUyAgPSAweDhCOUI7CisgICAgaW50IEdMX0lNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfVFlQRV9PRVMgICAgPSAweDhCOUE7CisgICAgaW50IEdMX0lOQ1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDFFMDI7CisgICAgaW50IEdMX0lOVkFMSURfRU5VTSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA1MDA7CisgICAgaW50IEdMX0lOVkFMSURfT1BFUkFUSU9OICAgICAgICAgICAgICAgICAgICAgPSAweDA1MDI7CisgICAgaW50IEdMX0lOVkFMSURfVkFMVUUgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA1MDE7CisgICAgaW50IEdMX0lOVkVSVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE1MEE7CisgICAgaW50IEdMX0tFRVAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDFFMDA7CisgICAgaW50IEdMX0xFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAyMDM7CisgICAgaW50IEdMX0xFU1MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAyMDE7CisgICAgaW50IEdMX0xJR0hUX01PREVMX0FNQklFTlQgICAgICAgICAgICAgICAgICAgPSAweDBCNTM7CisgICAgaW50IEdMX0xJR0hUX01PREVMX1RXT19TSURFICAgICAgICAgICAgICAgICAgPSAweDBCNTI7CisgICAgaW50IEdMX0xJR0hUMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDA7CisgICAgaW50IEdMX0xJR0hUMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDE7CisgICAgaW50IEdMX0xJR0hUMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDI7CisgICAgaW50IEdMX0xJR0hUMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDM7CisgICAgaW50IEdMX0xJR0hUNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDQ7CisgICAgaW50IEdMX0xJR0hUNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDU7CisgICAgaW50IEdMX0xJR0hUNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDY7CisgICAgaW50IEdMX0xJR0hUNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDQwMDc7CisgICAgaW50IEdMX0xJR0hUSU5HICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNTA7CisgICAgaW50IEdMX0xJTkVfTE9PUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAwMDI7CisgICAgaW50IEdMX0xJTkVfU01PT1RIICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCMjA7CisgICAgaW50IEdMX0xJTkVfU01PT1RIX0hJTlQgICAgICAgICAgICAgICAgICAgICAgPSAweDBDNTI7CisgICAgaW50IEdMX0xJTkVfU1RSSVAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAwMDM7CisgICAgaW50IEdMX0xJTkVBUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDI2MDE7CisgICAgaW50IEdMX0xJTkVBUl9BVFRFTlVBVElPTiAgICAgICAgICAgICAgICAgICAgPSAweDEyMDg7CisgICAgaW50IEdMX0xJTkVBUl9NSVBNQVBfTElORUFSICAgICAgICAgICAgICAgICAgPSAweDI3MDM7CisgICAgaW50IEdMX0xJTkVBUl9NSVBNQVBfTkVBUkVTVCAgICAgICAgICAgICAgICAgPSAweDI3MDE7CisgICAgaW50IEdMX0xJTkVTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAwMDE7CisgICAgaW50IEdMX0xVTUlOQU5DRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE5MDk7CisgICAgaW50IEdMX0xVTUlOQU5DRV9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAgPSAweDE5MEE7CisgICAgaW50IEdMX01BWF9FTEVNRU5UU19JTkRJQ0VTICAgICAgICAgICAgICAgICAgPSAweDgwRTk7CisgICAgaW50IEdMX01BWF9FTEVNRU5UU19WRVJUSUNFUyAgICAgICAgICAgICAgICAgPSAweDgwRTg7CisgICAgaW50IEdMX01BWF9MSUdIVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBEMzE7CisgICAgaW50IEdMX01BWF9NT0RFTFZJRVdfU1RBQ0tfREVQVEggICAgICAgICAgICAgPSAweDBEMzY7CisgICAgaW50IEdMX01BWF9QUk9KRUNUSU9OX1NUQUNLX0RFUFRIICAgICAgICAgICAgPSAweDBEMzg7CisgICAgaW50IEdMX01BWF9URVhUVVJFX1NJWkUgICAgICAgICAgICAgICAgICAgICAgPSAweDBEMzM7CisgICAgaW50IEdMX01BWF9URVhUVVJFX1NUQUNLX0RFUFRIICAgICAgICAgICAgICAgPSAweDBEMzk7CisgICAgaW50IEdMX01BWF9URVhUVVJFX1VOSVRTICAgICAgICAgICAgICAgICAgICAgPSAweDg0RTI7CisgICAgaW50IEdMX01BWF9WSUVXUE9SVF9ESU1TICAgICAgICAgICAgICAgICAgICAgPSAweDBEM0E7CisgICAgaW50IEdMX01PREVMVklFVyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE3MDA7CisgICAgaW50IEdMX01PRFVMQVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDIxMDA7CisgICAgaW50IEdMX01VTFRJU0FNUExFICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwOUQ7CisgICAgaW50IEdMX05BTkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE1MEU7CisgICAgaW50IEdMX05FQVJFU1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDI2MDA7CisgICAgaW50IEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUiAgICAgICAgICAgICAgICAgPSAweDI3MDI7CisgICAgaW50IEdMX05FQVJFU1RfTUlQTUFQX05FQVJFU1QgICAgICAgICAgICAgICAgPSAweDI3MDA7CisgICAgaW50IEdMX05FVkVSICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAyMDA7CisgICAgaW50IEdMX05JQ0VTVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDExMDI7CisgICAgaW50IEdMX05PX0VSUk9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAwOworICAgIGludCBHTF9OT09QICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgxNTA1OworICAgIGludCBHTF9OT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgxNTA4OworICAgIGludCBHTF9OT1JNQUxfQVJSQVkgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDc1OworICAgIGludCBHTF9OT1JNQUxJWkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQkExOworICAgIGludCBHTF9OT1RFUVVBTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMjA1OworICAgIGludCBHTF9OVU1fQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFMgICAgICAgID0gMHg4NkEyOworICAgIGludCBHTF9PTkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMTsKKyAgICBpbnQgR0xfT05FX01JTlVTX0RTVF9BTFBIQSAgICAgICAgICAgICAgICAgICA9IDB4MDMwNTsKKyAgICBpbnQgR0xfT05FX01JTlVTX0RTVF9DT0xPUiAgICAgICAgICAgICAgICAgICA9IDB4MDMwNzsKKyAgICBpbnQgR0xfT05FX01JTlVTX1NSQ19BTFBIQSAgICAgICAgICAgICAgICAgICA9IDB4MDMwMzsKKyAgICBpbnQgR0xfT05FX01JTlVTX1NSQ19DT0xPUiAgICAgICAgICAgICAgICAgICA9IDB4MDMwMTsKKyAgICBpbnQgR0xfT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwNzsKKyAgICBpbnQgR0xfT1JfSU5WRVJURUQgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwRDsKKyAgICBpbnQgR0xfT1JfUkVWRVJTRSAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwQjsKKyAgICBpbnQgR0xfT1VUX09GX01FTU9SWSAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDUwNTsKKyAgICBpbnQgR0xfUEFDS19BTElHTk1FTlQgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQwNTsKKyAgICBpbnQgR0xfUEFMRVRURTRfUjVfRzZfQjVfT0VTICAgICAgICAgICAgICAgICA9IDB4OEI5MjsKKyAgICBpbnQgR0xfUEFMRVRURTRfUkdCNV9BMV9PRVMgICAgICAgICAgICAgICAgICA9IDB4OEI5NDsKKyAgICBpbnQgR0xfUEFMRVRURTRfUkdCOF9PRVMgICAgICAgICAgICAgICAgICAgICA9IDB4OEI5MDsKKyAgICBpbnQgR0xfUEFMRVRURTRfUkdCQTRfT0VTICAgICAgICAgICAgICAgICAgICA9IDB4OEI5MzsKKyAgICBpbnQgR0xfUEFMRVRURTRfUkdCQThfT0VTICAgICAgICAgICAgICAgICAgICA9IDB4OEI5MTsKKyAgICBpbnQgR0xfUEFMRVRURThfUjVfRzZfQjVfT0VTICAgICAgICAgICAgICAgICA9IDB4OEI5NzsKKyAgICBpbnQgR0xfUEFMRVRURThfUkdCNV9BMV9PRVMgICAgICAgICAgICAgICAgICA9IDB4OEI5OTsKKyAgICBpbnQgR0xfUEFMRVRURThfUkdCOF9PRVMgICAgICAgICAgICAgICAgICAgICA9IDB4OEI5NTsKKyAgICBpbnQgR0xfUEFMRVRURThfUkdCQTRfT0VTICAgICAgICAgICAgICAgICAgICA9IDB4OEI5ODsKKyAgICBpbnQgR0xfUEFMRVRURThfUkdCQThfT0VTICAgICAgICAgICAgICAgICAgICA9IDB4OEI5NjsKKyAgICBpbnQgR0xfUEVSU1BFQ1RJVkVfQ09SUkVDVElPTl9ISU5UICAgICAgICAgICA9IDB4MEM1MDsKKyAgICBpbnQgR0xfUE9JTlRfU01PT1RIICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEIxMDsKKyAgICBpbnQgR0xfUE9JTlRfU01PT1RIX0hJTlQgICAgICAgICAgICAgICAgICAgICA9IDB4MEM1MTsKKyAgICBpbnQgR0xfUE9JTlRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDAwMDsKKyAgICBpbnQgR0xfUE9JTlRfRkFERV9USFJFU0hPTERfU0laRSAgICAgICAgICAgICA9IDB4ODEyODsKKyAgICBpbnQgR0xfUE9JTlRfU0laRSAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEIxMTsKKyAgICBpbnQgR0xfUE9MWUdPTl9PRkZTRVRfRklMTCAgICAgICAgICAgICAgICAgICA9IDB4ODAzNzsKKyAgICBpbnQgR0xfUE9MWUdPTl9TTU9PVEhfSElOVCAgICAgICAgICAgICAgICAgICA9IDB4MEM1MzsKKyAgICBpbnQgR0xfUE9TSVRJT04gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwMzsKKyAgICBpbnQgR0xfUFJPSkVDVElPTiAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTcwMTsKKyAgICBpbnQgR0xfUVVBRFJBVElDX0FUVEVOVUFUSU9OICAgICAgICAgICAgICAgICA9IDB4MTIwOTsKKyAgICBpbnQgR0xfUkVEX0JJVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1MjsKKyAgICBpbnQgR0xfUkVOREVSRVIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MUYwMTsKKyAgICBpbnQgR0xfUkVQRUFUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MjkwMTsKKyAgICBpbnQgR0xfUkVQTEFDRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MUUwMTsKKyAgICBpbnQgR0xfUkVTQ0FMRV9OT1JNQUwgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODAzQTsKKyAgICBpbnQgR0xfUkdCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTkwNzsKKyAgICBpbnQgR0xfUkdCQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTkwODsKKyAgICBpbnQgR0xfU0FNUExFX0FMUEhBX1RPX0NPVkVSQUdFICAgICAgICAgICAgICA9IDB4ODA5RTsKKyAgICBpbnQgR0xfU0FNUExFX0FMUEhBX1RPX09ORSAgICAgICAgICAgICAgICAgICA9IDB4ODA5RjsKKyAgICBpbnQgR0xfU0FNUExFX0NPVkVSQUdFICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODBBMDsKKyAgICBpbnQgR0xfU0NJU1NPUl9URVNUICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEMxMTsKKyAgICBpbnQgR0xfU0VUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTUwRjsKKyAgICBpbnQgR0xfU0hJTklORVNTICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTYwMTsKKyAgICBpbnQgR0xfU0hPUlQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTQwMjsKKyAgICBpbnQgR0xfU01PT1RIICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MUQwMTsKKyAgICBpbnQgR0xfU01PT1RIX0xJTkVfV0lEVEhfUkFOR0UgICAgICAgICAgICAgICA9IDB4MEIyMjsKKyAgICBpbnQgR0xfU01PT1RIX1BPSU5UX1NJWkVfUkFOR0UgICAgICAgICAgICAgICA9IDB4MEIxMjsKKyAgICBpbnQgR0xfU1BFQ1VMQVIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwMjsKKyAgICBpbnQgR0xfU1BPVF9DVVRPRkYgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwNjsKKyAgICBpbnQgR0xfU1BPVF9ESVJFQ1RJT04gICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwNDsKKyAgICBpbnQgR0xfU1BPVF9FWFBPTkVOVCAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTIwNTsKKyAgICBpbnQgR0xfU1JDX0FMUEhBICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDMwMjsKKyAgICBpbnQgR0xfU1JDX0FMUEhBX1NBVFVSQVRFICAgICAgICAgICAgICAgICAgICA9IDB4MDMwODsKKyAgICBpbnQgR0xfU1JDX0NPTE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDMwMDsKKyAgICBpbnQgR0xfU1RBQ0tfT1ZFUkZMT1cgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDUwMzsKKyAgICBpbnQgR0xfU1RBQ0tfVU5ERVJGTE9XICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDUwNDsKKyAgICBpbnQgR0xfU1RFTkNJTF9CSVRTICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1NzsKKyAgICBpbnQgR0xfU1RFTkNJTF9CVUZGRVJfQklUICAgICAgICAgICAgICAgICAgICA9IDB4MDQwMDsKKyAgICBpbnQgR0xfU1RFTkNJTF9URVNUICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI5MDsKKyAgICBpbnQgR0xfU1VCUElYRUxfQklUUyAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ1MDsKKyAgICBpbnQgR0xfVEVYVFVSRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MTcwMjsKKyAgICBpbnQgR0xfVEVYVFVSRV8yRCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MERFMTsKKyAgICBpbnQgR0xfVEVYVFVSRV9DT09SRF9BUlJBWSAgICAgICAgICAgICAgICAgICA9IDB4ODA3ODsKKyAgICBpbnQgR0xfVEVYVFVSRV9FTlYgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MjMwMDsKKyAgICBpbnQgR0xfVEVYVFVSRV9FTlZfQ09MT1IgICAgICAgICAgICAgICAgICAgICA9IDB4MjIwMTsKKyAgICBpbnQgR0xfVEVYVFVSRV9FTlZfTU9ERSAgICAgICAgICAgICAgICAgICAgICA9IDB4MjIwMDsKKyAgICBpbnQgR0xfVEVYVFVSRV9NQUdfRklMVEVSICAgICAgICAgICAgICAgICAgICA9IDB4MjgwMDsKKyAgICBpbnQgR0xfVEVYVFVSRV9NSU5fRklMVEVSICAgICAgICAgICAgICAgICAgICA9IDB4MjgwMTsKKyAgICBpbnQgR0xfVEVYVFVSRV9XUkFQX1MgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MjgwMjsKKyAgICBpbnQgR0xfVEVYVFVSRV9XUkFQX1QgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MjgwMzsKKyAgICBpbnQgR0xfVEVYVFVSRTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDMDsKKyAgICBpbnQgR0xfVEVYVFVSRTEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDMTsKKyAgICBpbnQgR0xfVEVYVFVSRTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDMjsKKyAgICBpbnQgR0xfVEVYVFVSRTMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDMzsKKyAgICBpbnQgR0xfVEVYVFVSRTQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDNDsKKyAgICBpbnQgR0xfVEVYVFVSRTUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDNTsKKyAgICBpbnQgR0xfVEVYVFVSRTYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDNjsKKyAgICBpbnQgR0xfVEVYVFVSRTcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDNzsKKyAgICBpbnQgR0xfVEVYVFVSRTggICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDODsKKyAgICBpbnQgR0xfVEVYVFVSRTkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDOTsKKyAgICBpbnQgR0xfVEVYVFVSRTEwICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDQTsKKyAgICBpbnQgR0xfVEVYVFVSRTExICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDQjsKKyAgICBpbnQgR0xfVEVYVFVSRTEyICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDQzsKKyAgICBpbnQgR0xfVEVYVFVSRTEzICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDRDsKKyAgICBpbnQgR0xfVEVYVFVSRTE0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDRTsKKyAgICBpbnQgR0xfVEVYVFVSRTE1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRDRjsKKyAgICBpbnQgR0xfVEVYVFVSRTE2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREMDsKKyAgICBpbnQgR0xfVEVYVFVSRTE3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREMTsKKyAgICBpbnQgR0xfVEVYVFVSRTE4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREMjsKKyAgICBpbnQgR0xfVEVYVFVSRTE5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREMzsKKyAgICBpbnQgR0xfVEVYVFVSRTIwICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRENDsKKyAgICBpbnQgR0xfVEVYVFVSRTIxICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRENTsKKyAgICBpbnQgR0xfVEVYVFVSRTIyICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRENjsKKyAgICBpbnQgR0xfVEVYVFVSRTIzICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRENzsKKyAgICBpbnQgR0xfVEVYVFVSRTI0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREODsKKyAgICBpbnQgR0xfVEVYVFVSRTI1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREOTsKKyAgICBpbnQgR0xfVEVYVFVSRTI2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREQTsKKyAgICBpbnQgR0xfVEVYVFVSRTI3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREQjsKKyAgICBpbnQgR0xfVEVYVFVSRTI4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODREQzsKKyAgICBpbnQgR0xfVEVYVFVSRTI5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRERDsKKyAgICBpbnQgR0xfVEVYVFVSRTMwICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRERTsKKyAgICBpbnQgR0xfVEVYVFVSRTMxICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODRERjsKKyAgICBpbnQgR0xfVFJJQU5HTEVfRkFOICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDAwNjsKKyAgICBpbnQgR0xfVFJJQU5HTEVfU1RSSVAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDAwNTsKKyAgICBpbnQgR0xfVFJJQU5HTEVTICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDAwNDsKKyAgICBpbnQgR0xfVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDE7CisgICAgaW50IEdMX1VOUEFDS19BTElHTk1FTlQgICAgICAgICAgICAgICAgICAgICAgPSAweDBDRjU7CisgICAgaW50IEdMX1VOU0lHTkVEX0JZVEUgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE0MDE7CisgICAgaW50IEdMX1VOU0lHTkVEX1NIT1JUICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE0MDM7CisgICAgaW50IEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQgICAgICAgICAgICAgICAgPSAweDgwMzM7CisgICAgaW50IEdMX1VOU0lHTkVEX1NIT1JUXzVfNV81XzEgICAgICAgICAgICAgICAgPSAweDgwMzQ7CisgICAgaW50IEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81ICAgICAgICAgICAgICAgICAgPSAweDgzNjM7CisgICAgaW50IEdMX1ZFTkRPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDFGMDA7CisgICAgaW50IEdMX1ZFUlNJT04gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDFGMDI7CisgICAgaW50IEdMX1ZFUlRFWF9BUlJBWSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwNzQ7CisgICAgaW50IEdMX1hPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE1MDY7CisgICAgaW50IEdMX1pFUk8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAwOworCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMUV4dEhlYWRlci5qYXZhLWlmIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTFFeHRIZWFkZXIuamF2YS1pZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmUyMTY0Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTFFeHRIZWFkZXIuamF2YS1pZgpAQCAtMCwwICsxLDQwIEBACisqKgorKiogQ29weXJpZ2h0IDIwMDcsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8gVGhpcyBzb3VyY2UgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZAorCitwYWNrYWdlIGphdmF4Lm1pY3JvZWRpdGlvbi5raHJvbm9zLm9wZW5nbGVzOworCitwdWJsaWMgaW50ZXJmYWNlIEdMMTFFeHQgZXh0ZW5kcyBHTCB7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9CVUZGRVJfQklORElOR19PRVMgPSAweDhCOUU7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9PRVMgICAgICAgICAgICAgICAgPSAweDg4NDQ7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9QT0lOVEVSX09FUyAgICAgICAgPSAweDg4NDk7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9TSVpFX09FUyAgICAgICAgICAgPSAweDg4NDY7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9TVFJJREVfT0VTICAgICAgICAgPSAweDg4NDg7CisgICAgaW50IEdMX01BVFJJWF9JTkRFWF9BUlJBWV9UWVBFX09FUyAgICAgICAgICAgPSAweDg4NDc7CisgICAgaW50IEdMX01BVFJJWF9QQUxFVFRFX09FUyAgICAgICAgICAgICAgICAgICAgPSAweDg4NDA7CisgICAgaW50IEdMX01BWF9QQUxFVFRFX01BVFJJQ0VTX09FUyAgICAgICAgICAgICAgPSAweDg4NDI7CisgICAgaW50IEdMX01BWF9WRVJURVhfVU5JVFNfT0VTICAgICAgICAgICAgICAgICAgPSAweDg2QTQ7CisgICAgaW50IEdMX1RFWFRVUkVfQ1JPUF9SRUNUX09FUyAgICAgICAgICAgICAgICAgPSAweDhCOUQ7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9CVUZGRVJfQklORElOR19PRVMgICAgICAgPSAweDg4OUU7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9PRVMgICAgICAgICAgICAgICAgICAgICAgPSAweDg2QUQ7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9QT0lOVEVSX09FUyAgICAgICAgICAgICAgPSAweDg2QUM7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9TSVpFX09FUyAgICAgICAgICAgICAgICAgPSAweDg2QUI7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9TVFJJREVfT0VTICAgICAgICAgICAgICAgPSAweDg2QUE7CisgICAgaW50IEdMX1dFSUdIVF9BUlJBWV9UWVBFX09FUyAgICAgICAgICAgICAgICAgPSAweDg2QTk7CisKKyAgICB2b2lkIGdsVGV4UGFyYW1ldGVyZnYoaW50IHRhcmdldCwgaW50IHBuYW1lLCBmbG9hdFtdIHBhcmFtLCBpbnQgb2Zmc2V0KTsKKwpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTFFeHRlbnNpb25QYWNrSGVhZGVyLmphdmEtaWYgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMUV4dGVuc2lvblBhY2tIZWFkZXIuamF2YS1pZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODAwMTkxCi0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTFFeHRlbnNpb25QYWNrSGVhZGVyLmphdmEtaWYKQEAgLTAsMCArMSwxMDggQEAKKyoqCisqKiBDb3B5cmlnaHQgMjAwNywgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorKioKKyoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyAKKyoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gCisqKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgCisqKgorKiogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAKKyoqCisqKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIAorKiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgCisqKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCisqKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIAorKiogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisvLyBUaGlzIHNvdXJjZSBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkCisKK3BhY2thZ2UgamF2YXgubWljcm9lZGl0aW9uLmtocm9ub3Mub3BlbmdsZXM7CisKK3B1YmxpYyBpbnRlcmZhY2UgR0wxMUV4dGVuc2lvblBhY2sgZXh0ZW5kcyBHTCB7CisgICAgaW50IEdMX0JMRU5EX0RTVF9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODBDQTsKKyAgICBpbnQgR0xfQkxFTkRfRFNUX1JHQiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MEM4OworICAgIGludCBHTF9CTEVORF9FUVVBVElPTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwMDk7CisgICAgaW50IEdMX0JMRU5EX0VRVUFUSU9OX0FMUEhBICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODgzRDsKKyAgICBpbnQgR0xfQkxFTkRfRVFVQVRJT05fUkdCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDA5OworICAgIGludCBHTF9CTEVORF9TUkNfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwQ0I7CisgICAgaW50IEdMX0JMRU5EX1NSQ19SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODBDOTsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDBfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0UwOworICAgIGludCBHTF9DT0xPUl9BVFRBQ0hNRU5UMV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhDRTE7CisgICAgaW50IEdMX0NPTE9SX0FUVEFDSE1FTlQyX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENFMjsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDNfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0UzOworICAgIGludCBHTF9DT0xPUl9BVFRBQ0hNRU5UNF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhDRTQ7CisgICAgaW50IEdMX0NPTE9SX0FUVEFDSE1FTlQ1X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENFNTsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDZfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0U2OworICAgIGludCBHTF9DT0xPUl9BVFRBQ0hNRU5UN19PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhDRTc7CisgICAgaW50IEdMX0NPTE9SX0FUVEFDSE1FTlQ4X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENFODsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDlfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0U5OworICAgIGludCBHTF9DT0xPUl9BVFRBQ0hNRU5UMTBfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhDRUE7CisgICAgaW50IEdMX0NPTE9SX0FUVEFDSE1FTlQxMV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENFQjsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDEyX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0VDOworICAgIGludCBHTF9DT0xPUl9BVFRBQ0hNRU5UMTNfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhDRUQ7CisgICAgaW50IEdMX0NPTE9SX0FUVEFDSE1FTlQxNF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENFRTsKKyAgICBpbnQgR0xfQ09MT1JfQVRUQUNITUVOVDE1X09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0VGOworICAgIGludCBHTF9ERUNSX1dSQVAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1MDg7CisgICAgaW50IEdMX0RFUFRIX0FUVEFDSE1FTlRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OEQwMDsKKyAgICBpbnQgR0xfREVQVEhfQ09NUE9ORU5UICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgxOTAyOworICAgIGludCBHTF9ERVBUSF9DT01QT05FTlQxNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgxQTU7CisgICAgaW50IEdMX0RFUFRIX0NPTVBPTkVOVDI0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODFBNjsKKyAgICBpbnQgR0xfREVQVEhfQ09NUE9ORU5UMzIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MUE3OworICAgIGludCBHTF9GUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX09CSkVDVF9OQU1FX09FUyAgICAgICAgICAgPSAweDhDRDE7CisgICAgaW50IEdMX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfT0JKRUNUX1RZUEVfT0VTICAgICAgICAgICA9IDB4OENEMDsKKyAgICBpbnQgR0xfRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9URVhUVVJFX0NVQkVfTUFQX0ZBQ0VfT0VTID0gMHg4Q0QzOworICAgIGludCBHTF9GUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX1RFWFRVUkVfTEVWRUxfT0VTICAgICAgICAgPSAweDhDRDI7CisgICAgaW50IEdMX0ZSQU1FQlVGRkVSX0JJTkRJTkdfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENBNjsKKyAgICBpbnQgR0xfRlJBTUVCVUZGRVJfQ09NUExFVEVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0Q1OworICAgIGludCBHTF9GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0FUVEFDSE1FTlRfT0VTICAgICAgICAgICAgPSAweDhDRDY7CisgICAgaW50IEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfRElNRU5TSU9OU19PRVMgICAgICAgICAgICA9IDB4OENEOTsKKyAgICBpbnQgR0xfRlJBTUVCVUZGRVJfSU5DT01QTEVURV9EUkFXX0JVRkZFUl9PRVMgICAgICAgICAgID0gMHg4Q0RCOworICAgIGludCBHTF9GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0ZPUk1BVFNfT0VTICAgICAgICAgICAgICAgPSAweDhDREE7CisgICAgaW50IEdMX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfTUlTU0lOR19BVFRBQ0hNRU5UX09FUyAgICA9IDB4OENENzsKKyAgICBpbnQgR0xfRlJBTUVCVUZGRVJfSU5DT01QTEVURV9SRUFEX0JVRkZFUl9PRVMgICAgICAgICAgID0gMHg4Q0RDOworICAgIGludCBHTF9GUkFNRUJVRkZFUl9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENDA7CisgICAgaW50IEdMX0ZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEX09FUyAgICAgICAgICAgICAgICAgICAgICA9IDB4OENERDsKKyAgICBpbnQgR0xfRlVOQ19BREQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDA2OworICAgIGludCBHTF9GVU5DX1JFVkVSU0VfU1VCVFJBQ1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwMEI7CisgICAgaW50IEdMX0ZVTkNfU1VCVFJBQ1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODAwQTsKKyAgICBpbnQgR0xfSU5DUl9XUkFQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTA3OworICAgIGludCBHTF9JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTl9PRVMgICAgICAgICAgICAgICAgPSAweDA1MDY7CisgICAgaW50IEdMX01BWF9DT0xPUl9BVFRBQ0hNRU5UU19PRVMgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OENERjsKKyAgICBpbnQgR0xfTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRSAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTFDOworICAgIGludCBHTF9NQVhfUkVOREVSQlVGRkVSX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg0RTg7CisgICAgaW50IEdMX01JUlJPUkVEX1JFUEVBVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODM3MDsKKyAgICBpbnQgR0xfTk9STUFMX01BUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTExOworICAgIGludCBHTF9SRUZMRUNUSU9OX01BUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1MTI7CisgICAgaW50IEdMX1JFTkRFUkJVRkZFUl9BTFBIQV9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICA9IDB4OEQ1MzsKKyAgICBpbnQgR0xfUkVOREVSQlVGRkVSX0JJTkRJTkdfT0VTICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4Q0E3OworICAgIGludCBHTF9SRU5ERVJCVUZGRVJfQkxVRV9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENTI7CisgICAgaW50IEdMX1JFTkRFUkJVRkZFUl9ERVBUSF9TSVpFX09FUyAgICAgICAgICAgICAgICAgICAgICA9IDB4OEQ1NDsKKyAgICBpbnQgR0xfUkVOREVSQlVGRkVSX0dSRUVOX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICAgID0gMHg4RDUxOworICAgIGludCBHTF9SRU5ERVJCVUZGRVJfSEVJR0hUX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENDM7CisgICAgaW50IEdMX1JFTkRFUkJVRkZFUl9JTlRFUk5BTF9GT1JNQVRfT0VTICAgICAgICAgICAgICAgICA9IDB4OEQ0NDsKKyAgICBpbnQgR0xfUkVOREVSQlVGRkVSX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4RDQxOworICAgIGludCBHTF9SRU5ERVJCVUZGRVJfUkVEX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENTA7CisgICAgaW50IEdMX1JFTkRFUkJVRkZFUl9TVEVOQ0lMX1NJWkVfT0VTICAgICAgICAgICAgICAgICAgICA9IDB4OEQ1NTsKKyAgICBpbnQgR0xfUkVOREVSQlVGRkVSX1dJRFRIX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4RDQyOworICAgIGludCBHTF9SR0I1X0ExICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwNTc7CisgICAgaW50IEdMX1JHQjU2NV9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OEQ2MjsKKyAgICBpbnQgR0xfUkdCOCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDUxOworICAgIGludCBHTF9SR0JBNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwNTY7CisgICAgaW50IEdMX1JHQkE4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODA1ODsKKyAgICBpbnQgR0xfU1RFTkNJTF9BVFRBQ0hNRU5UX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4RDIwOworICAgIGludCBHTF9TVEVOQ0lMX0lOREVYICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDE5MDE7CisgICAgaW50IEdMX1NURU5DSUxfSU5ERVgxX09FUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4OEQ0NjsKKyAgICBpbnQgR0xfU1RFTkNJTF9JTkRFWDRfT0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4RDQ3OworICAgIGludCBHTF9TVEVOQ0lMX0lOREVYOF9PRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENDg7CisgICAgaW50IEdMX1NUUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IC0xOworICAgIGludCBHTF9URVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1MTQ7CisgICAgaW50IEdMX1RFWFRVUkVfQ1VCRV9NQVAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODUxMzsKKyAgICBpbnQgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9YICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTE2OworICAgIGludCBHTF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1kgICAgICAgICAgICAgICAgICAgICAgPSAweDg1MTg7CisgICAgaW50IEdMX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWiAgICAgICAgICAgICAgICAgICAgICA9IDB4ODUxQTsKKyAgICBpbnQgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTE1OworICAgIGludCBHTF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1kgICAgICAgICAgICAgICAgICAgICAgPSAweDg1MTc7CisgICAgaW50IEdMX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWiAgICAgICAgICAgICAgICAgICAgICA9IDB4ODUxOTsKKyAgICBpbnQgR0xfVEVYVFVSRV9HRU5fTU9ERSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgyNTAwOworICAgIGludCBHTF9URVhUVVJFX0dFTl9TVFIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDhENjA7CisKZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDExSGVhZGVyLmphdmEtaWYgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMUhlYWRlci5qYXZhLWlmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwZTVhNmIKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0wxMUhlYWRlci5qYXZhLWlmCkBAIC0wLDAgKzEsMTQ1IEBACisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8gVGhpcyBzb3VyY2UgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZAorCitwYWNrYWdlIGphdmF4Lm1pY3JvZWRpdGlvbi5raHJvbm9zLm9wZW5nbGVzOworCitwdWJsaWMgaW50ZXJmYWNlIEdMMTEgZXh0ZW5kcyBHTDEwIHsKKyAgICBpbnQgR0xfQUNUSVZFX1RFWFRVUkUgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NEUwOworICAgIGludCBHTF9BRERfU0lHTkVEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1NzQ7CisgICAgaW50IEdMX0FMUEhBX1NDQUxFICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQxQzsKKyAgICBpbnQgR0xfQUxQSEFfVEVTVF9GVU5DICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQkMxOworICAgIGludCBHTF9BTFBIQV9URVNUX1JFRiAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCQzI7CisgICAgaW50IEdMX0FSUkFZX0JVRkZFUiAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODg5MjsKKyAgICBpbnQgR0xfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICAgICAgICAgICAgICAgID0gMHg4ODk0OworICAgIGludCBHTF9CTEVORF9EU1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCRTA7CisgICAgaW50IEdMX0JMRU5EX1NSQyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJFMTsKKyAgICBpbnQgR0xfQlVGRkVSX0FDQ0VTUyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4OEJCOworICAgIGludCBHTF9CVUZGRVJfU0laRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg3NjQ7CisgICAgaW50IEdMX0JVRkZFUl9VU0FHRSAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODc2NTsKKyAgICBpbnQgR0xfQ0xJRU5UX0FDVElWRV9URVhUVVJFICAgICAgICAgICAgICAgICAgID0gMHg4NEUxOworICAgIGludCBHTF9DTElQX1BMQU5FMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDMwMDA7CisgICAgaW50IEdMX0NMSVBfUExBTkUxICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MzAwMTsKKyAgICBpbnQgR0xfQ0xJUF9QTEFORTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgzMDAyOworICAgIGludCBHTF9DTElQX1BMQU5FMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDMwMDM7CisgICAgaW50IEdMX0NMSVBfUExBTkU0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MzAwNDsKKyAgICBpbnQgR0xfQ0xJUF9QTEFORTUgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgzMDA1OworICAgIGludCBHTF9DT0xPUl9BUlJBWV9CVUZGRVJfQklORElORyAgICAgICAgICAgICAgPSAweDg4OTg7CisgICAgaW50IEdMX0NPTE9SX0FSUkFZX1BPSU5URVIgICAgICAgICAgICAgICAgICAgICA9IDB4ODA5MDsKKyAgICBpbnQgR0xfQ09MT1JfQVJSQVlfU0laRSAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDgxOworICAgIGludCBHTF9DT0xPUl9BUlJBWV9TVFJJREUgICAgICAgICAgICAgICAgICAgICAgPSAweDgwODM7CisgICAgaW50IEdMX0NPTE9SX0FSUkFZX1RZUEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODA4MjsKKyAgICBpbnQgR0xfQ09MT1JfQ0xFQVJfVkFMVUUgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQzIyOworICAgIGludCBHTF9DT0xPUl9XUklURU1BU0sgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBDMjM7CisgICAgaW50IEdMX0NPTUJJTkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU3MDsKKyAgICBpbnQgR0xfQ09NQklORV9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTcyOworICAgIGludCBHTF9DT01CSU5FX1JHQiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1NzE7CisgICAgaW50IEdMX0NPTlNUQU5UICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU3NjsKKyAgICBpbnQgR0xfQ09PUkRfUkVQTEFDRV9PRVMgICAgICAgICAgICAgICAgICAgICAgID0gMHg4ODYyOworICAgIGludCBHTF9DVUxMX0ZBQ0VfTU9ERSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNDU7CisgICAgaW50IEdMX0NVUlJFTlRfQ09MT1IgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEIwMDsKKyAgICBpbnQgR0xfQ1VSUkVOVF9OT1JNQUwgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjAyOworICAgIGludCBHTF9DVVJSRU5UX1RFWFRVUkVfQ09PUkRTICAgICAgICAgICAgICAgICAgPSAweDBCMDM7CisgICAgaW50IEdMX0RFUFRIX0NMRUFSX1ZBTFVFICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI3MzsKKyAgICBpbnQgR0xfREVQVEhfRlVOQyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjc0OworICAgIGludCBHTF9ERVBUSF9SQU5HRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCNzA7CisgICAgaW50IEdMX0RFUFRIX1dSSVRFTUFTSyAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI3MjsKKyAgICBpbnQgR0xfRE9UM19SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NkFFOworICAgIGludCBHTF9ET1QzX1JHQkEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg2QUY7CisgICAgaW50IEdMX0RZTkFNSUNfRFJBVyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODhFODsKKyAgICBpbnQgR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIgICAgICAgICAgICAgICAgICAgID0gMHg4ODkzOworICAgIGludCBHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9CSU5ESU5HICAgICAgICAgICAgPSAweDg4OTU7CisgICAgaW50IEdMX0ZST05UX0ZBQ0UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI0NjsKKyAgICBpbnQgR0xfR0VORVJBVEVfTUlQTUFQICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MTkxOworICAgIGludCBHTF9HRU5FUkFURV9NSVBNQVBfSElOVCAgICAgICAgICAgICAgICAgICAgPSAweDgxOTI7CisgICAgaW50IEdMX0lOVEVSUE9MQVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU3NTsKKyAgICBpbnQgR0xfTElORV9XSURUSCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjIxOworICAgIGludCBHTF9MT0dJQ19PUF9NT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCRjA7CisgICAgaW50IEdMX01BVFJJWF9NT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJBMDsKKyAgICBpbnQgR0xfTUFYX0NMSVBfUExBTkVTICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwRDMyOworICAgIGludCBHTF9NT0RFTFZJRVdfTUFUUklYICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCQTY7CisgICAgaW50IEdMX01PREVMVklFV19NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTICA9IDB4ODk4RDsKKyAgICBpbnQgR0xfTU9ERUxWSUVXX1NUQUNLX0RFUFRIICAgICAgICAgICAgICAgICAgID0gMHgwQkEzOworICAgIGludCBHTF9OT1JNQUxfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICAgICAgICAgPSAweDg4OTc7CisgICAgaW50IEdMX05PUk1BTF9BUlJBWV9QT0lOVEVSICAgICAgICAgICAgICAgICAgICA9IDB4ODA4RjsKKyAgICBpbnQgR0xfTk9STUFMX0FSUkFZX1NUUklERSAgICAgICAgICAgICAgICAgICAgID0gMHg4MDdGOworICAgIGludCBHTF9OT1JNQUxfQVJSQVlfVFlQRSAgICAgICAgICAgICAgICAgICAgICAgPSAweDgwN0U7CisgICAgaW50IEdMX09QRVJBTkQwX0FMUEhBICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU5ODsKKyAgICBpbnQgR0xfT1BFUkFORDBfUkdCICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTkwOworICAgIGludCBHTF9PUEVSQU5EMV9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1OTk7CisgICAgaW50IEdMX09QRVJBTkQxX1JHQiAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU5MTsKKyAgICBpbnQgR0xfT1BFUkFORDJfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTlBOworICAgIGludCBHTF9PUEVSQU5EMl9SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1OTI7CisgICAgaW50IEdMX1BPSU5UX0RJU1RBTkNFX0FUVEVOVUFUSU9OICAgICAgICAgICAgICA9IDB4ODEyOTsKKyAgICBpbnQgR0xfUE9JTlRfRkFERV9USFJFU0hPTERfU0laRSAgICAgICAgICAgICAgID0gMHg4MTI4OworICAgIGludCBHTF9QT0lOVF9TSVpFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCMTE7CisgICAgaW50IEdMX1BPSU5UX1NJWkVfQVJSQVlfQlVGRkVSX0JJTkRJTkdfT0VTICAgICA9IDB4OEI5RjsKKyAgICBpbnQgR0xfUE9JTlRfU0laRV9BUlJBWV9PRVMgICAgICAgICAgICAgICAgICAgID0gMHg4QjlDOworICAgIGludCBHTF9QT0lOVF9TSVpFX0FSUkFZX1BPSU5URVJfT0VTICAgICAgICAgICAgPSAweDg5OEM7CisgICAgaW50IEdMX1BPSU5UX1NJWkVfQVJSQVlfU1RSSURFX09FUyAgICAgICAgICAgICA9IDB4ODk4QjsKKyAgICBpbnQgR0xfUE9JTlRfU0laRV9BUlJBWV9UWVBFX09FUyAgICAgICAgICAgICAgID0gMHg4OThBOworICAgIGludCBHTF9QT0lOVF9TSVpFX01BWCAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDgxMjc7CisgICAgaW50IEdMX1BPSU5UX1NJWkVfTUlOICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODEyNjsKKyAgICBpbnQgR0xfUE9JTlRfU1BSSVRFX09FUyAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4ODYxOworICAgIGludCBHTF9QT0xZR09OX09GRlNFVF9GQUNUT1IgICAgICAgICAgICAgICAgICAgPSAweDgwMzg7CisgICAgaW50IEdMX1BPTFlHT05fT0ZGU0VUX1VOSVRTICAgICAgICAgICAgICAgICAgICA9IDB4MkEwMDsKKyAgICBpbnQgR0xfUFJFVklPVVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTc4OworICAgIGludCBHTF9QUklNQVJZX0NPTE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1Nzc7CisgICAgaW50IEdMX1BST0pFQ1RJT05fTUFUUklYICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEJBNzsKKyAgICBpbnQgR0xfUFJPSkVDVElPTl9NQVRSSVhfRkxPQVRfQVNfSU5UX0JJVFNfT0VTID0gMHg4OThFOworICAgIGludCBHTF9QUk9KRUNUSU9OX1NUQUNLX0RFUFRIICAgICAgICAgICAgICAgICAgPSAweDBCQTQ7CisgICAgaW50IEdMX1JHQl9TQ0FMRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU3MzsKKyAgICBpbnQgR0xfU0FNUExFX0JVRkZFUlMgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MEE4OworICAgIGludCBHTF9TQU1QTEVfQ09WRVJBR0VfSU5WRVJUICAgICAgICAgICAgICAgICAgPSAweDgwQUI7CisgICAgaW50IEdMX1NBTVBMRV9DT1ZFUkFHRV9WQUxVRSAgICAgICAgICAgICAgICAgICA9IDB4ODBBQTsKKyAgICBpbnQgR0xfU0FNUExFUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MEE5OworICAgIGludCBHTF9TQ0lTU09SX0JPWCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBDMTA7CisgICAgaW50IEdMX1NIQURFX01PREVMICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI1NDsKKyAgICBpbnQgR0xfU1JDMF9BTFBIQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTg4OworICAgIGludCBHTF9TUkMwX1JHQiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1ODA7CisgICAgaW50IEdMX1NSQzFfQUxQSEEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU4OTsKKyAgICBpbnQgR0xfU1JDMV9SR0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NTgxOworICAgIGludCBHTF9TUkMyX0FMUEhBICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg1OEE7CisgICAgaW50IEdMX1NSQzJfUkdCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODU4MjsKKyAgICBpbnQgR0xfU1RBVElDX0RSQVcgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4OEU0OworICAgIGludCBHTF9TVEVOQ0lMX0NMRUFSX1ZBTFVFICAgICAgICAgICAgICAgICAgICAgPSAweDBCOTE7CisgICAgaW50IEdMX1NURU5DSUxfRkFJTCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI5NDsKKyAgICBpbnQgR0xfU1RFTkNJTF9GVU5DICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjkyOworICAgIGludCBHTF9TVEVOQ0lMX1BBU1NfREVQVEhfRkFJTCAgICAgICAgICAgICAgICAgPSAweDBCOTU7CisgICAgaW50IEdMX1NURU5DSUxfUEFTU19ERVBUSF9QQVNTICAgICAgICAgICAgICAgICA9IDB4MEI5NjsKKyAgICBpbnQgR0xfU1RFTkNJTF9SRUYgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjk3OworICAgIGludCBHTF9TVEVOQ0lMX1ZBTFVFX01BU0sgICAgICAgICAgICAgICAgICAgICAgPSAweDBCOTM7CisgICAgaW50IEdMX1NURU5DSUxfV1JJVEVNQVNLICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI5ODsKKyAgICBpbnQgR0xfU1VCVFJBQ1QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHg4NEU3OworICAgIGludCBHTF9URVhUVVJFX0JJTkRJTkdfMkQgICAgICAgICAgICAgICAgICAgICAgPSAweDgwNjk7CisgICAgaW50IEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICA9IDB4ODg5QTsKKyAgICBpbnQgR0xfVEVYVFVSRV9DT09SRF9BUlJBWV9QT0lOVEVSICAgICAgICAgICAgID0gMHg4MDkyOworICAgIGludCBHTF9URVhUVVJFX0NPT1JEX0FSUkFZX1NJWkUgICAgICAgICAgICAgICAgPSAweDgwODg7CisgICAgaW50IEdMX1RFWFRVUkVfQ09PUkRfQVJSQVlfU1RSSURFICAgICAgICAgICAgICA9IDB4ODA4QTsKKyAgICBpbnQgR0xfVEVYVFVSRV9DT09SRF9BUlJBWV9UWVBFICAgICAgICAgICAgICAgID0gMHg4MDg5OworICAgIGludCBHTF9URVhUVVJFX01BVFJJWCAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBCQTg7CisgICAgaW50IEdMX1RFWFRVUkVfTUFUUklYX0ZMT0FUX0FTX0lOVF9CSVRTX09FUyAgICA9IDB4ODk4RjsKKyAgICBpbnQgR0xfVEVYVFVSRV9TVEFDS19ERVBUSCAgICAgICAgICAgICAgICAgICAgID0gMHgwQkE1OworICAgIGludCBHTF9WRVJURVhfQVJSQVlfQlVGRkVSX0JJTkRJTkcgICAgICAgICAgICAgPSAweDg4OTY7CisgICAgaW50IEdMX1ZFUlRFWF9BUlJBWV9QT0lOVEVSICAgICAgICAgICAgICAgICAgICA9IDB4ODA4RTsKKyAgICBpbnQgR0xfVkVSVEVYX0FSUkFZX1NJWkUgICAgICAgICAgICAgICAgICAgICAgID0gMHg4MDdBOworICAgIGludCBHTF9WRVJURVhfQVJSQVlfU1RSSURFICAgICAgICAgICAgICAgICAgICAgPSAweDgwN0M7CisgICAgaW50IEdMX1ZFUlRFWF9BUlJBWV9UWVBFICAgICAgICAgICAgICAgICAgICAgICA9IDB4ODA3QjsKKyAgICBpbnQgR0xfVklFV1BPUlQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQkEyOworICAgIGludCBHTF9XUklURV9PTkxZICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDg4Qjk7CisKKyAgICB2b2lkIGdsR2V0UG9pbnRlcnYoaW50IHBuYW1lLCBqYXZhLm5pby5CdWZmZXJbXSBwYXJhbXMpOwpkaWZmIC0tZ2l0IGEvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMMTFJbXBsSGVhZGVyLmphdmEtaW1wbCBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDExSW1wbEhlYWRlci5qYXZhLWltcGwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTAxYmU2NQotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTDExSW1wbEhlYWRlci5qYXZhLWltcGwKQEAgLTAsMCArMSwzMCBAQAorLy8gQ29weXJpZ2h0IDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorCisvLyBBbGwgUmlnaHRzIFJlc2VydmVkLgorCisvLyBUaGlzIHNvdXJjZSBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkCisKK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmdsZXNfam5pOworCitpbXBvcnQgamF2YS5uaW8uQnVmZmVyOworaW1wb3J0IGphdmF4Lm1pY3JvZWRpdGlvbi5raHJvbm9zLm9wZW5nbGVzLkdMMTE7CitpbXBvcnQgYW5kcm9pZC5ncmFwaGljcy5DYW52YXM7CisKK3B1YmxpYyBjbGFzcyBHTDExSW1wbCBpbXBsZW1lbnRzIEdMMTEgeworCisgICAgLy8gUHJpdmF0ZSBhY2Nlc3NvcnMgZm9yIG5hdGl2ZSBjb2RlCisKKyAgICBuYXRpdmUgcHJpdmF0ZSBzdGF0aWMgdm9pZCBfbmF0aXZlQ2xhc3NJbml0KCk7CisgICAgc3RhdGljIHsKKwlfbmF0aXZlQ2xhc3NJbml0KCk7CisgICAgfQorCisgICAgQnVmZmVyIF9jb2xvclBvaW50ZXIgPSBudWxsOworICAgIEJ1ZmZlciBfbm9ybWFsUG9pbnRlciA9IG51bGw7CisgICAgQnVmZmVyIF90ZXhDb29yZFBvaW50ZXIgPSBudWxsOworICAgIEJ1ZmZlciBfdmVydGV4UG9pbnRlciA9IG51bGw7CisKKyAgICBwdWJsaWMgR0wxMUltcGwoKSB7CisgICAgfQorCisKZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTENIZWFkZXIuY3BwIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL0dMQ0hlYWRlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQ5NTY4NgotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTENIZWFkZXIuY3BwCkBAIC0wLDAgKzEsMTI5IEBACisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8gVGhpcyBzb3VyY2UgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZAorCisjaW5jbHVkZSA8YW5kcm9pZF9ydW50aW1lL0FuZHJvaWRSdW50aW1lLmg+CisjaW5jbHVkZSA8dXRpbHMvbWlzYy5oPgorCisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisjaW5jbHVkZSA8R0xFUy9nbC5oPgorCisjaW5jbHVkZSA8cHJpdmF0ZS9vcGVuZ2xlcy9nbF9jb250ZXh0Lmg+CisKKyNkZWZpbmUgX05VTV9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUyBcCisgICAgICAgICg6OmFuZHJvaWQ6Ok9HTEVTX05VTV9DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUykKKworc3RhdGljIGludCBpbml0aWFsaXplZCA9IDA7CisKK3N0YXRpYyBqY2xhc3MgbmlvQWNjZXNzQ2xhc3M7CitzdGF0aWMgamNsYXNzIGJ1ZmZlckNsYXNzOworc3RhdGljIGpjbGFzcyBPT01FQ2xhc3M7CitzdGF0aWMgamNsYXNzIFVPRUNsYXNzOworc3RhdGljIGpjbGFzcyBJQUVDbGFzczsKK3N0YXRpYyBqY2xhc3MgQUlPT0JFQ2xhc3M7CitzdGF0aWMgam1ldGhvZElEIGdldEJhc2VQb2ludGVySUQ7CitzdGF0aWMgam1ldGhvZElEIGdldEJhc2VBcnJheUlEOworc3RhdGljIGptZXRob2RJRCBnZXRCYXNlQXJyYXlPZmZzZXRJRDsKK3N0YXRpYyBqZmllbGRJRCBwb3NpdGlvbklEOworc3RhdGljIGpmaWVsZElEIGxpbWl0SUQ7CitzdGF0aWMgamZpZWxkSUQgZWxlbWVudFNpemVTaGlmdElEOworCisvKiBDYWNoZSBtZXRob2QgSURzIGVhY2ggdGltZSB0aGUgY2xhc3MgaXMgbG9hZGVkLiAqLworCit2b2lkCituYXRpdmVDbGFzc0luaXRCdWZmZXIoSk5JRW52ICpfZW52KQoreworICAgIGpjbGFzcyBuaW9BY2Nlc3NDbGFzc0xvY2FsID0gX2Vudi0+RmluZENsYXNzKCJqYXZhL25pby9OSU9BY2Nlc3MiKTsKKyAgICBuaW9BY2Nlc3NDbGFzcyA9IChqY2xhc3MpIF9lbnYtPk5ld0dsb2JhbFJlZihuaW9BY2Nlc3NDbGFzc0xvY2FsKTsKKworICAgIGpjbGFzcyBidWZmZXJDbGFzc0xvY2FsID0gX2Vudi0+RmluZENsYXNzKCJqYXZhL25pby9CdWZmZXIiKTsKKyAgICBidWZmZXJDbGFzcyA9IChqY2xhc3MpIF9lbnYtPk5ld0dsb2JhbFJlZihidWZmZXJDbGFzc0xvY2FsKTsKKworICAgIGdldEJhc2VQb2ludGVySUQgPSBfZW52LT5HZXRTdGF0aWNNZXRob2RJRChuaW9BY2Nlc3NDbGFzcywKKyAgICAgICAgICAgICJnZXRCYXNlUG9pbnRlciIsICIoTGphdmEvbmlvL0J1ZmZlcjspSiIpOworICAgIGdldEJhc2VBcnJheUlEID0gX2Vudi0+R2V0U3RhdGljTWV0aG9kSUQobmlvQWNjZXNzQ2xhc3MsCisgICAgICAgICAgICAiZ2V0QmFzZUFycmF5IiwgIihMamF2YS9uaW8vQnVmZmVyOylMamF2YS9sYW5nL09iamVjdDsiKTsKKyAgICBnZXRCYXNlQXJyYXlPZmZzZXRJRCA9IF9lbnYtPkdldFN0YXRpY01ldGhvZElEKG5pb0FjY2Vzc0NsYXNzLAorICAgICAgICAgICAgImdldEJhc2VBcnJheU9mZnNldCIsICIoTGphdmEvbmlvL0J1ZmZlcjspSSIpOworCisgICAgcG9zaXRpb25JRCA9IF9lbnYtPkdldEZpZWxkSUQoYnVmZmVyQ2xhc3MsICJwb3NpdGlvbiIsICJJIik7CisgICAgbGltaXRJRCA9IF9lbnYtPkdldEZpZWxkSUQoYnVmZmVyQ2xhc3MsICJsaW1pdCIsICJJIik7CisgICAgZWxlbWVudFNpemVTaGlmdElEID0KKyAgICAgICAgX2Vudi0+R2V0RmllbGRJRChidWZmZXJDbGFzcywgIl9lbGVtZW50U2l6ZVNoaWZ0IiwgIkkiKTsKK30KKworCitzdGF0aWMgdm9pZAorbmF0aXZlQ2xhc3NJbml0KEpOSUVudiAqX2VudiwgamNsYXNzIGdsSW1wbENsYXNzKQoreworICAgIG5hdGl2ZUNsYXNzSW5pdEJ1ZmZlcihfZW52KTsKKworICAgIGpjbGFzcyBJQUVDbGFzc0xvY2FsID0KKyAgICAgICAgX2Vudi0+RmluZENsYXNzKCJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgamNsYXNzIE9PTUVDbGFzc0xvY2FsID0KKyAgICAgICAgIF9lbnYtPkZpbmRDbGFzcygiamF2YS9sYW5nL091dE9mTWVtb3J5RXJyb3IiKTsKKyAgICBqY2xhc3MgVU9FQ2xhc3NMb2NhbCA9CisgICAgICAgICBfZW52LT5GaW5kQ2xhc3MoImphdmEvbGFuZy9VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgIGpjbGFzcyBBSU9PQkVDbGFzc0xvY2FsID0KKyAgICAgICAgIF9lbnYtPkZpbmRDbGFzcygiamF2YS9sYW5nL0FycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworCisgICAgSUFFQ2xhc3MgPSAoamNsYXNzKSBfZW52LT5OZXdHbG9iYWxSZWYoSUFFQ2xhc3NMb2NhbCk7CisgICAgT09NRUNsYXNzID0gKGpjbGFzcykgX2Vudi0+TmV3R2xvYmFsUmVmKE9PTUVDbGFzc0xvY2FsKTsKKyAgICBVT0VDbGFzcyA9IChqY2xhc3MpIF9lbnYtPk5ld0dsb2JhbFJlZihVT0VDbGFzc0xvY2FsKTsKKyAgICBBSU9PQkVDbGFzcyA9IChqY2xhc3MpIF9lbnYtPk5ld0dsb2JhbFJlZihBSU9PQkVDbGFzc0xvY2FsKTsKK30KKworc3RhdGljIHZvaWQgKgorZ2V0UG9pbnRlcihKTklFbnYgKl9lbnYsIGpvYmplY3QgYnVmZmVyLCBqYXJyYXkgKmFycmF5LCBqaW50ICpyZW1haW5pbmcpCit7CisgICAgamludCBwb3NpdGlvbjsKKyAgICBqaW50IGxpbWl0OworICAgIGppbnQgZWxlbWVudFNpemVTaGlmdDsKKyAgICBqbG9uZyBwb2ludGVyOworICAgIGppbnQgb2Zmc2V0OworICAgIHZvaWQgKmRhdGE7CisKKyAgICBwb3NpdGlvbiA9IF9lbnYtPkdldEludEZpZWxkKGJ1ZmZlciwgcG9zaXRpb25JRCk7CisgICAgbGltaXQgPSBfZW52LT5HZXRJbnRGaWVsZChidWZmZXIsIGxpbWl0SUQpOworICAgIGVsZW1lbnRTaXplU2hpZnQgPSBfZW52LT5HZXRJbnRGaWVsZChidWZmZXIsIGVsZW1lbnRTaXplU2hpZnRJRCk7CisgICAgKnJlbWFpbmluZyA9IChsaW1pdCAtIHBvc2l0aW9uKSA8PCBlbGVtZW50U2l6ZVNoaWZ0OworICAgIHBvaW50ZXIgPSBfZW52LT5DYWxsU3RhdGljTG9uZ01ldGhvZChuaW9BY2Nlc3NDbGFzcywKKyAgICAgICAgICAgIGdldEJhc2VQb2ludGVySUQsIGJ1ZmZlcik7CisgICAgaWYgKHBvaW50ZXIgIT0gMEwpIHsKKyAgICAgICAgKmFycmF5ID0gTlVMTDsKKyAgICAgICAgcmV0dXJuICh2b2lkICopIChqaW50KSBwb2ludGVyOworICAgIH0KKyAgICAKKyAgICAqYXJyYXkgPSAoamFycmF5KSBfZW52LT5DYWxsU3RhdGljT2JqZWN0TWV0aG9kKG5pb0FjY2Vzc0NsYXNzLAorICAgICAgICAgICAgZ2V0QmFzZUFycmF5SUQsIGJ1ZmZlcik7CisgICAgb2Zmc2V0ID0gX2Vudi0+Q2FsbFN0YXRpY0ludE1ldGhvZChuaW9BY2Nlc3NDbGFzcywKKyAgICAgICAgICAgIGdldEJhc2VBcnJheU9mZnNldElELCBidWZmZXIpOworICAgIGRhdGEgPSBfZW52LT5HZXRQcmltaXRpdmVBcnJheUNyaXRpY2FsKCphcnJheSwgKGpib29sZWFuICopIDApOworICAgIAorICAgIHJldHVybiAodm9pZCAqKSAoKGNoYXIgKikgZGF0YSArIG9mZnNldCk7Cit9CisKKworc3RhdGljIHZvaWQKK3JlbGVhc2VQb2ludGVyKEpOSUVudiAqX2VudiwgamFycmF5IGFycmF5LCB2b2lkICpkYXRhLCBqYm9vbGVhbiBjb21taXQpCit7CisgICAgX2Vudi0+UmVsZWFzZVByaW1pdGl2ZUFycmF5Q3JpdGljYWwoYXJyYXksIGRhdGEsCisJCQkJCSAgIGNvbW1pdCA/IDAgOiBKTklfQUJPUlQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0xIZWFkZXIuamF2YS1pZiBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTEhlYWRlci5qYXZhLWlmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiNzhmM2QKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0xIZWFkZXIuamF2YS1pZgpAQCAtMCwwICsxLDIyIEBACisvKiAvL2RldmljZS9qYXZhL2FuZHJvaWQvamF2YXgvbWljcm9lZGl0aW9uL2tocm9ub3Mvb3BlbmdsZXMvR0wuamF2YQorKioKKyoqIENvcHlyaWdodCAyMDA2LCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisqKgorKiogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IAorKiogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAKKyoqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAKKyoqCisqKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIAorKioKKyoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgCisqKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCAKKyoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKKyoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgCisqKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKK3BhY2thZ2UgamF2YXgubWljcm9lZGl0aW9uLmtocm9ub3Mub3BlbmdsZXM7CisKK3B1YmxpYyBpbnRlcmZhY2UgR0wgeworfQorCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0xJbXBsSGVhZGVyLmphdmEtaW1wbCBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9HTEltcGxIZWFkZXIuamF2YS1pbXBsCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiM2E0MWMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvR0xJbXBsSGVhZGVyLmphdmEtaW1wbApAQCAtMCwwICsxLDQ4IEBACisqKgorKiogQ29weXJpZ2h0IDIwMDYsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoqCisqKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgCisqKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIAorKiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IAorKioKKyoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgCisqKgorKiogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSAKKyoqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIAorKiogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAorKiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCAKKyoqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworLy8gVGhpcyBzb3VyY2UgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZAorCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5nbGVzX2puaTsKKworaW1wb3J0IGphdmEubmlvLkJ1ZmZlcjsKK2ltcG9ydCBqYXZheC5taWNyb2VkaXRpb24ua2hyb25vcy5vcGVuZ2xlcy5HTDEwOworaW1wb3J0IGphdmF4Lm1pY3JvZWRpdGlvbi5raHJvbm9zLm9wZW5nbGVzLkdMMTBFeHQ7CitpbXBvcnQgamF2YXgubWljcm9lZGl0aW9uLmtocm9ub3Mub3BlbmdsZXMuR0wxMTsKK2ltcG9ydCBqYXZheC5taWNyb2VkaXRpb24ua2hyb25vcy5vcGVuZ2xlcy5HTDExRXh0OworaW1wb3J0IGphdmF4Lm1pY3JvZWRpdGlvbi5raHJvbm9zLm9wZW5nbGVzLkdMMTFFeHRlbnNpb25QYWNrOworCitwdWJsaWMgY2xhc3MgR0xJbXBsIGltcGxlbWVudHMgR0wxMCwgR0wxMEV4dCwgR0wxMSwgR0wxMUV4dCwgR0wxMUV4dGVuc2lvblBhY2sgeworCisgICAgLy8gUHJpdmF0ZSBhY2Nlc3NvcnMgZm9yIG5hdGl2ZSBjb2RlCisKKyAgICBuYXRpdmUgcHJpdmF0ZSBzdGF0aWMgdm9pZCBfbmF0aXZlQ2xhc3NJbml0KCk7CisgICAgc3RhdGljIHsKKwlfbmF0aXZlQ2xhc3NJbml0KCk7CisgICAgfQorCisgICAgQnVmZmVyIF9jb2xvclBvaW50ZXIgPSBudWxsOworICAgIEJ1ZmZlciBfbm9ybWFsUG9pbnRlciA9IG51bGw7CisgICAgQnVmZmVyIF90ZXhDb29yZFBvaW50ZXIgPSBudWxsOworICAgIEJ1ZmZlciBfdmVydGV4UG9pbnRlciA9IG51bGw7CisKKyAgICBwdWJsaWMgR0xJbXBsKCkgeworICAgIH0KKworICAgICBwdWJsaWMgdm9pZCBnbEdldFBvaW50ZXJ2KGludCBwbmFtZSwgamF2YS5uaW8uQnVmZmVyW10gcGFyYW1zKSB7CisgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oImdsR2V0UG9pbnRlcnYiKTsKKyAgICAgfQorCmRpZmYgLS1naXQgYS9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvZ2xHZXRTdHJpbmcuY3BwIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL2dsR2V0U3RyaW5nLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmUxMjk3Ci0tLSAvZGV2L251bGwKKysrIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL2dsR2V0U3RyaW5nLmNwcApAQCAtMCwwICsxLDEwIEBACisjaW5jbHVkZSA8c3RyaW5nLmg+DQorDQorLyogY29uc3QgR0x1Ynl0ZSAqIGdsR2V0U3RyaW5nICggR0xlbnVtIG5hbWUgKSAqLw0KK2pzdHJpbmcNCithbmRyb2lkX2dsR2V0U3RyaW5nDQorICAoSk5JRW52ICpfZW52LCBqb2JqZWN0IF90aGlzLCBqaW50IG5hbWUpIHsNCisgICAgY29uc3QgY2hhciAqIGNoYXJzID0gKGNvbnN0IGNoYXIgKilnbEdldFN0cmluZygoR0xlbnVtKW5hbWUpOw0KKyAgICBqc3RyaW5nIG91dHB1dCA9IF9lbnYtPk5ld1N0cmluZ1VURihjaGFycyk7DQorICAgIHJldHVybiBvdXRwdXQ7DQorfQ0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5qYXZhLTEwLWlmIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL2dsR2V0U3RyaW5nLmphdmEtMTAtaWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODk4ZmFiYwotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5qYXZhLTEwLWlmCkBAIC0wLDAgKzEsNCBAQAorICAgIHB1YmxpYyBTdHJpbmcgZ2xHZXRTdHJpbmcoDQorICAgICAgICBpbnQgbmFtZQ0KKyAgICApOw0KKw0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5qYXZhLWlmIGIvb3BlbmdsL3Rvb2xzL2dsZ2VuL3N0dWJzL2dsR2V0U3RyaW5nLmphdmEtaWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODk4ZmFiYwotLS0gL2Rldi9udWxsCisrKyBiL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5qYXZhLWlmCkBAIC0wLDAgKzEsNCBAQAorICAgIHB1YmxpYyBTdHJpbmcgZ2xHZXRTdHJpbmcoDQorICAgICAgICBpbnQgbmFtZQ0KKyAgICApOw0KKw0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5qYXZhLWltcGwgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvZ2xHZXRTdHJpbmcuamF2YS1pbXBsCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjNzg4MWMKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvZ2xHZXRTdHJpbmcuamF2YS1pbXBsCkBAIC0wLDAgKzEsMTYgQEAKKyAgICAvLyBDIGZ1bmN0aW9uIGNvbnN0IEdMdWJ5dGUgKiBnbEdldFN0cmluZyAoIEdMZW51bSBuYW1lICkNCisNCisgICAgcHVibGljIG5hdGl2ZSBTdHJpbmcgX2dsR2V0U3RyaW5nKA0KKyAgICAgICAgaW50IG5hbWUNCisgICAgKTsNCisNCisgICAgcHVibGljIFN0cmluZyBnbEdldFN0cmluZygNCisgICAgICAgIGludCBuYW1lDQorICAgICkgew0KKyAgICAgICAgU3RyaW5nIHJldHVyblZhbHVlOw0KKyAgICAgICAgcmV0dXJuVmFsdWUgPSBfZ2xHZXRTdHJpbmcoDQorICAgICAgICAgICAgbmFtZQ0KKyAgICAgICAgKTsNCisgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsNCisgICAgfQ0KKw0KZGlmZiAtLWdpdCBhL29wZW5nbC90b29scy9nbGdlbi9zdHVicy9nbEdldFN0cmluZy5uYXRpdmVSZWcgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvZ2xHZXRTdHJpbmcubmF0aXZlUmVnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2NDE4N2MKLS0tIC9kZXYvbnVsbAorKysgYi9vcGVuZ2wvdG9vbHMvZ2xnZW4vc3R1YnMvZ2xHZXRTdHJpbmcubmF0aXZlUmVnCkBAIC0wLDAgKzEgQEAKK3siX2dsR2V0U3RyaW5nIiwgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIsICh2b2lkICopIGFuZHJvaWRfZ2xHZXRTdHJpbmcgfSwNCmRpZmYgLS1naXQgYS9zZXJ2aWNlcy9BbmRyb2lkLm1rIGIvc2VydmljZXMvQW5kcm9pZC5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTkxMmQ2Ci0tLSAvZGV2L251bGwKKysrIGIvc2VydmljZXMvQW5kcm9pZC5tawpAQCAtMCwwICsxLDE3IEBACitMT0NBTF9QQVRIOj0gJChjYWxsIG15LWRpcikKKworIyB0aGUgbGlicmFyeQorIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVMgOj0gXAorICAgICAgICAgICAgJChjYWxsIGFsbC1zdWJkaXItamF2YS1maWxlcykKKworTE9DQUxfTU9EVUxFOj0gc2VydmljZXMKKworTE9DQUxfSkFWQV9MSUJSQVJJRVMgOj0gYW5kcm9pZC5wb2xpY3kKKworaW5jbHVkZSAkKEJVSUxEX0pBVkFfTElCUkFSWSkKKworaW5jbHVkZSAkKEJVSUxEX0RST0lERE9DKQorCg==